././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9891026 tomwer-1.6.17/0000755000175000017500000000000015153325403012222 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/LICENSE0000644000175000017500000000352414757047403013245 0ustar00paynopayno The Tomwer library goal is to provide some useful process for acquisition/reconstruction automation. Tomwer is distributed under the MIT license. Tomwer is using the Qt library. A word of caution is to be provided. If users develop and distribute software using modules accessing Qt by means of Riverbank Computing Qt bindings PyQt4 or PyQt5, those users will be conditioned by the license of their PyQt4/5 software (GPL or commercial). If the end user does not own a commercial license of PyQt4 or PyQt5 and wishes to be free of any distribution condition, (s)he should be able to use PySide because it uses the LGPL license. It can also be used as an Orange3 add-on. If you wan't to distribute Orange you must stick to there license (GNU [GPL-3.0]+ license) The MIT license follows: Copyright (c) European Synchrotron Radiation Facility (ESRF) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/MANIFEST.in0000644000175000017500000000000015153325210013742 0ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9891026 tomwer-1.6.17/PKG-INFO0000644000175000017500000001621115153325403013320 0ustar00paynopaynoMetadata-Version: 2.4 Name: tomwer Version: 1.6.17 Summary: Tomography workflow tools Author-email: Henri Payno , Pierre Paleo , Pierre-Olivier Autran , Jérôme Lesaint , Alessandro Mirone License: MIT Project-URL: Homepage, https://gitlab.esrf.fr/tomotools/tomwer Project-URL: Documentation, https://tomotools.gitlab-pages.esrf.fr/tomwer/ Project-URL: Repository, https://gitlab.esrf.fr/tomotools/tomwer Project-URL: Issues, https://gitlab.esrf.fr/tomotools/tomwer/-/issues Project-URL: Changelog, https://gitlab.esrf.fr/tomotools/tomwer/-/blob/main/CHANGELOG.rst?ref_type=heads Keywords: orange3 add-on,ewoks Classifier: Intended Audience :: Education Classifier: Intended Audience :: Science/Research Classifier: License :: OSI Approved :: MIT License Classifier: Programming Language :: Python :: 3 Classifier: Environment :: Console Classifier: Environment :: X11 Applications :: Qt Classifier: Operating System :: POSIX Classifier: Natural Language :: English Classifier: Topic :: Scientific/Engineering :: Physics Classifier: Topic :: Software Development :: Libraries :: Python Modules Requires-Python: >=3.10 Description-Content-Type: text/x-rst License-File: LICENSE Requires-Dist: numpy Requires-Dist: setuptools<81 Requires-Dist: psutil Requires-Dist: silx[full]>=2.1.1 Requires-Dist: tomoscan>=2.2.0a6 Requires-Dist: nxtomo>2.0.0dev2 Requires-Dist: nxtomomill>=2.0.0dev0 Requires-Dist: processview>=1.5.0 Requires-Dist: ewoks>=0.1.1 Requires-Dist: ewokscore<2.0,>=1.5 Requires-Dist: sluurp>=0.4.1 Requires-Dist: packaging Requires-Dist: pint Requires-Dist: tqdm Requires-Dist: eval_type_backport; python_version < "3.10" Requires-Dist: platformdirs Provides-Extra: full-base Requires-Dist: orange-canvas-core; extra == "full-base" Requires-Dist: orange-widget-base; extra == "full-base" Requires-Dist: ewoks[orange]>=0.1.1; extra == "full-base" Requires-Dist: ewoksorange<2.0,>=0.7.0rc0; extra == "full-base" Requires-Dist: fabio; extra == "full-base" Requires-Dist: h5py>=3; extra == "full-base" Requires-Dist: lxml; extra == "full-base" Requires-Dist: werkzeug; extra == "full-base" Requires-Dist: json-rpc; extra == "full-base" Requires-Dist: scipy; extra == "full-base" Requires-Dist: Pillow; extra == "full-base" Requires-Dist: resource; extra == "full-base" Requires-Dist: tifffile; extra == "full-base" Requires-Dist: hdf5plugin; extra == "full-base" Requires-Dist: pyicat_plus; extra == "full-base" Requires-Dist: ewoksnotify[full]<0.2; extra == "full-base" Requires-Dist: pyicat_plus; extra == "full-base" Requires-Dist: rsyncmanager; extra == "full-base" Requires-Dist: blissdata; extra == "full-base" Provides-Extra: full-no-cuda Requires-Dist: tomwer[full_base]; extra == "full-no-cuda" Requires-Dist: nabu>=2024.2.0; extra == "full-no-cuda" Provides-Extra: full Requires-Dist: tomwer[full_base]; extra == "full" Requires-Dist: nabu[full]>=2024.2.0; extra == "full" Requires-Dist: pycuda<2024.1.1; extra == "full" Requires-Dist: scikit-cuda; extra == "full" Provides-Extra: doc Requires-Dist: tomwer[full_no_cuda]; extra == "doc" Requires-Dist: Sphinx>=4.0.0; extra == "doc" Requires-Dist: nbsphinx; extra == "doc" Requires-Dist: pandoc; extra == "doc" Requires-Dist: jupyterlab; extra == "doc" Requires-Dist: pydata_sphinx_theme; extra == "doc" Requires-Dist: sphinx-design; extra == "doc" Requires-Dist: sphinx-autodoc-typehints; extra == "doc" Requires-Dist: sphinxcontrib-programoutput; extra == "doc" Requires-Dist: sphinxcontrib-youtube; extra == "doc" Requires-Dist: myst-parser; extra == "doc" Requires-Dist: nb_extension_tagstyler; extra == "doc" Provides-Extra: dev-spec Requires-Dist: black; extra == "dev-spec" Requires-Dist: flake8; extra == "dev-spec" Requires-Dist: timeout-decorator; extra == "dev-spec" Requires-Dist: pyopencl; extra == "dev-spec" Provides-Extra: dev Requires-Dist: tomwer[full]; extra == "dev" Requires-Dist: tomwer[dev_spec]; extra == "dev" Provides-Extra: dev-no-cuda Requires-Dist: tomwer[full_no_cuda]; extra == "dev-no-cuda" Requires-Dist: tomwer[dev_spec]; extra == "dev-no-cuda" Provides-Extra: test Requires-Dist: tomwer[full_no_cuda]; extra == "test" Requires-Dist: pytest-asyncio; extra == "test" Requires-Dist: tomoscan[test]>=2.2.0a6; extra == "test" Dynamic: license-file .. image:: doc/img/tomwer.png :alt: Tomwer Logo :align: left :width: 400px Introduction ------------ **Tomwer** provides tools to automate acquisition and reconstruction processes for tomography. The package includes: - A library to individually access each acquisition process. - Graphical User Interface (GUI) applications to control key processes such as reconstruction and data transfer, which can be executed as standalone applications. - An Orange add-on to help users define custom workflows (`Orange3 `_). Tomwer relies on `Nabu `_ for tomographic reconstruction. **Note**: Currently, the software is only compatible with Linux. Documentation ------------- The latest version of the documentation is available `here `_. Installation ------------ Step 1: Installing Tomwer ''''''''''''''''''''''''' To install Tomwer with all features: .. code-block:: bash pip install tomwer[full] Alternatively, you can install the latest development branch from the repository: .. code-block:: bash pip install git+https://gitlab.esrf.fr/tomotools/tomwer/#egg=tomwer[full] Step 2: (Optional) Update Orange-CANVAS-CORE and Orange-WIDGET-BASE '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' If you need access to additional 'processing' wheels and 'reprocess action,' you may want to update these Orange forks. This is optional, as the project works with the native Orange libraries. .. code-block:: bash pip install git+https://github.com/payno/orange-canvas-core --no-deps --upgrade pip install git+https://github.com/payno/orange-widget-base --no-deps --upgrade Launching Applications ----------------------- After installation, Tomwer includes several applications. You can launch an application by running: .. code-block:: bash tomwer [options] - If you run `tomwer` without arguments, a manual page will be displayed. - For application-specific help, run: .. code-block:: bash tomwer --help Tomwer Canvas - Orange Canvas ----------------------------- You can launch the Orange canvas to create workflows using the available building blocks: .. code-block:: bash tomwer canvas - Alternatively, you can use `orange-canvas`. - If you're using a virtual environment, remember to activate it: .. code-block:: bash source myvirtualenv/bin/activate Building Documentation ----------------------- To build the documentation: .. code-block:: bash sphinx-build doc build/html The documentation will be generated in `doc/build/html`, and the entry point is `index.html`. To view the documentation in a browser: .. code-block:: bash firefox build/html/index.html **Note**: Building the documentation requires `sphinx` to be installed, which is not a hard dependency of Tomwer. If needed, install it separately. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/README.rst0000644000175000017500000000557715153325210013723 0ustar00paynopayno.. image:: doc/img/tomwer.png :alt: Tomwer Logo :align: left :width: 400px Introduction ------------ **Tomwer** provides tools to automate acquisition and reconstruction processes for tomography. The package includes: - A library to individually access each acquisition process. - Graphical User Interface (GUI) applications to control key processes such as reconstruction and data transfer, which can be executed as standalone applications. - An Orange add-on to help users define custom workflows (`Orange3 `_). Tomwer relies on `Nabu `_ for tomographic reconstruction. **Note**: Currently, the software is only compatible with Linux. Documentation ------------- The latest version of the documentation is available `here `_. Installation ------------ Step 1: Installing Tomwer ''''''''''''''''''''''''' To install Tomwer with all features: .. code-block:: bash pip install tomwer[full] Alternatively, you can install the latest development branch from the repository: .. code-block:: bash pip install git+https://gitlab.esrf.fr/tomotools/tomwer/#egg=tomwer[full] Step 2: (Optional) Update Orange-CANVAS-CORE and Orange-WIDGET-BASE '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' If you need access to additional 'processing' wheels and 'reprocess action,' you may want to update these Orange forks. This is optional, as the project works with the native Orange libraries. .. code-block:: bash pip install git+https://github.com/payno/orange-canvas-core --no-deps --upgrade pip install git+https://github.com/payno/orange-widget-base --no-deps --upgrade Launching Applications ----------------------- After installation, Tomwer includes several applications. You can launch an application by running: .. code-block:: bash tomwer [options] - If you run `tomwer` without arguments, a manual page will be displayed. - For application-specific help, run: .. code-block:: bash tomwer --help Tomwer Canvas - Orange Canvas ----------------------------- You can launch the Orange canvas to create workflows using the available building blocks: .. code-block:: bash tomwer canvas - Alternatively, you can use `orange-canvas`. - If you're using a virtual environment, remember to activate it: .. code-block:: bash source myvirtualenv/bin/activate Building Documentation ----------------------- To build the documentation: .. code-block:: bash sphinx-build doc build/html The documentation will be generated in `doc/build/html`, and the entry point is `index.html`. To view the documentation in a browser: .. code-block:: bash firefox build/html/index.html **Note**: Building the documentation requires `sphinx` to be installed, which is not a hard dependency of Tomwer. If needed, install it separately. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989076.0 tomwer-1.6.17/pyproject.toml0000644000175000017500000001146015153325224015141 0ustar00paynopayno[project] name = "tomwer" dynamic = ["version"] authors = [ { name = "Henri Payno", email = "henri.payno@esrf.fr" }, { name = "Pierre Paleo", email = "pierre.paleo@esrf.fr" }, { name = "Pierre-Olivier Autran", email = "pierre-olivier.autran@esrf.fr" }, { name = "Jérôme Lesaint", email = "jerome.lesaint@esrf.fr" }, { name = "Alessandro Mirone", email = "mirone@esrf.fr" } ] description = "Tomography workflow tools" readme = { file = "README.rst", content-type = "text/x-rst" } license = { text = "MIT" } requires-python = ">=3.10" keywords = ["orange3 add-on", "ewoks"] classifiers = [ "Intended Audience :: Education", "Intended Audience :: Science/Research", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", "Environment :: Console", "Environment :: X11 Applications :: Qt", "Operating System :: POSIX", "Natural Language :: English", "Topic :: Scientific/Engineering :: Physics", "Topic :: Software Development :: Libraries :: Python Modules" ] dependencies = [ "numpy", "setuptools<81", "psutil", "silx[full]>=2.1.1", "tomoscan>=2.2.0a6", "nxtomo>2.0.0dev2", "nxtomomill>=2.0.0dev0", "processview>=1.5.0", "ewoks>=0.1.1", "ewokscore>=1.5,<2.0", "sluurp>=0.4.1", "packaging", "pint", "tqdm", "eval_type_backport; python_version < '3.10'", "platformdirs", ] [project.optional-dependencies] full_base = [ "orange-canvas-core", "orange-widget-base", "ewoks[orange]>=0.1.1", "ewoksorange>=0.7.0rc0,<2.0", "fabio", "h5py>=3", "lxml", "werkzeug", "json-rpc", "scipy", "Pillow", "resource", "tifffile", "hdf5plugin", "pyicat_plus", "ewoksnotify[full]<0.2", "pyicat_plus", "rsyncmanager", "blissdata", ] full_no_cuda = [ "tomwer[full_base]", "nabu>=2024.2.0" ] full = [ "tomwer[full_base]", "nabu[full]>=2024.2.0", "pycuda<2024.1.1", "scikit-cuda" ] doc = [ "tomwer[full_no_cuda]", "Sphinx>=4.0.0", "nbsphinx", "pandoc", "jupyterlab", "pydata_sphinx_theme", "sphinx-design", "sphinx-autodoc-typehints", "sphinxcontrib-programoutput", "sphinxcontrib-youtube", "myst-parser", "nb_extension_tagstyler", ] dev_spec = [ "black", "flake8", "timeout-decorator", "pyopencl" ] dev = [ "tomwer[full]", "tomwer[dev_spec]" ] dev_no_cuda = [ "tomwer[full_no_cuda]", "tomwer[dev_spec]" ] test = [ "tomwer[full_no_cuda]", "pytest-asyncio", "tomoscan[test]>=2.2.0a6", ] [project.urls] Homepage = "https://gitlab.esrf.fr/tomotools/tomwer" Documentation = "https://tomotools.gitlab-pages.esrf.fr/tomwer/" Repository = "https://gitlab.esrf.fr/tomotools/tomwer" Issues = "https://gitlab.esrf.fr/tomotools/tomwer/-/issues" Changelog = "https://gitlab.esrf.fr/tomotools/tomwer/-/blob/main/CHANGELOG.rst?ref_type=heads" [build-system] requires = ["setuptools>=61.0,<81.0", "wheel", "numpy>=1.12"] build-backend = "setuptools.build_meta" [tool.setuptools.dynamic] version = { attr = "tomwer.__version__" } [tool.setuptools.packages.find] where = ["src"] [project.scripts] tomwer = "tomwer.__main__:main" [project.entry-points."orange3.addon"] tomwer-add-on = "orangecontrib.tomwer:addon" [project.entry-points."orange.widgets"] tomwer = "orangecontrib.tomwer.widgets" [project.entry-points."orangecanvas.examples"] tomo_examples = "orangecontrib.tomwer.examples" [project.entry-points."orange.widgets.tutorials"] tomo_tutorials = "orangecontrib.tomwer.tutorials" tomo_tutorials_id16b = "orangecontrib.tomwer.tutorials.id16b" [project.entry-points."orange.canvas.help"] html-index = "orangecontrib.tomwer.widgets:WIDGET_HELP_PATH" [project.entry-points."ewoks.tasks.class"] "tomwer.tasks.*.*" = "tomwer" [tool.setuptools.package-data] "tomwer.resources" = [ "gui/icons/*.png", "gui/icons/*.svg", "gui/icons/*.npy", "gui/illustrations/*.svg", "gui/illustrations/*.png" ] "orangecontrib.tomwer" = [ "tutorials/*.ows", "tutorials/id16b/*.ows", "widgets/icons/*.png", "widgets/icons/*.svg", "widgets/cluster/icons/*.png", "widgets/cluster/icons/*.svg", "widgets/control/icons/*.png", "widgets/control/icons/*.svg", "widgets/deprecated/icons/*.png", "widgets/deprecated/icons/*.svg", "widgets/debugtools/icons/*.png", "widgets/debugtools/icons/*.svg", "widgets/edit/icons/*.png", "widgets/edit/icons/*.svg", "widgets/dataportal/icons/*.png", "widgets/dataportal/icons/*.svg", "widgets/reconstruction/icons/*.png", "widgets/reconstruction/icons/*.svg", "widgets/visualization/icons/*.png", "widgets/visualization/icons/*.svg", "widgets/other/icons/*.png", "widgets/other/icons/*.svg" ] [tool.sphinx] source-dir = "./doc" [tool.coverage.run] omit = ["setup.py", "*/test/*"] ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9891026 tomwer-1.6.17/setup.cfg0000644000175000017500000000004615153325403014043 0ustar00paynopayno[egg_info] tag_build = tag_date = 0 ././@PaxHeader0000000000000000000000000000003100000000000010207 xustar0025 mtime=1772989186.8731 tomwer-1.6.17/src/0000755000175000017500000000000015153325403013011 5ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8690999 tomwer-1.6.17/src/orangecontrib/0000755000175000017500000000000015153325403015645 5ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8811002 tomwer-1.6.17/src/orangecontrib/tomwer/0000755000175000017500000000000015153325403017162 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/orangecontrib/tomwer/__init__.py0000644000175000017500000000027214764622416021307 0ustar00paynopayno""" Orange add-on for tomography """ import logging from . import state_summary # noqa F401 fabio_logger = logging.getLogger("fabio.edfimage") fabio_logger.setLevel(logging.WARNING) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8811002 tomwer-1.6.17/src/orangecontrib/tomwer/orange/0000755000175000017500000000000015153325403020435 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/orange/__init__.py0000644000175000017500000000000014757047403022546 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/orange/managedprocess.py0000644000175000017500000000735715153325210024012 0ustar00paynopaynofrom __future__ import annotations import functools import logging from ewoksorange.bindings import ( OWEwoksWidgetWithTaskStack, OWEwoksWidgetOneThreadPerRun, ) from ewoksorange.bindings.owwidgets import invalid_data from orangewidget.widget import OWBaseWidget from processview.core.manager import DatasetState, ProcessManager from processview.core.superviseprocess import SuperviseProcess from orangecontrib.tomwer.widgets.utils import WidgetLongProcessing _logger = logging.getLogger(__name__) class _SuperviseMixIn(SuperviseProcess): def __init__(self, process_id=None): SuperviseProcess.__init__(self, process_id=process_id) self.destroyed.connect(functools.partial(ProcessManager().unregister, self)) def setCaption(self, caption): self.name = caption try: ProcessManager().process_renamed(process=self) except Exception as e: _logger.warning(f"Fail to update process name. Error is {e}") def notify_skip(self, scan, details=None): ProcessManager().notify_dataset_state( dataset=scan, process=self, state=DatasetState.SKIPPED, details=details ) def notify_pending(self, scan, details=None): ProcessManager().notify_dataset_state( dataset=scan, process=self, state=DatasetState.PENDING, details=details ) def notify_succeed(self, scan, details=None): ProcessManager().notify_dataset_state( dataset=scan, process=self, state=DatasetState.SUCCEED, details=details ) def notify_failed(self, scan, details=None): ProcessManager().notify_dataset_state( dataset=scan, process=self, state=DatasetState.FAILED, details=details ) def notify_on_going(self, scan, details=None): ProcessManager().notify_dataset_state( dataset=scan, process=self, state=DatasetState.ON_GOING, details=details ) class SuperviseOW(OWBaseWidget, _SuperviseMixIn, openclass=True): """ A basic OWWidget but registered on the process manager """ want_control_area = False def __init__(self, parent, process_id=None): OWBaseWidget.__init__(self, parent, process_id=process_id) _SuperviseMixIn.__init__(self, process_id=process_id) def setCaption(self, caption): OWBaseWidget.setCaption(self, caption) _SuperviseMixIn.setCaption(self, caption=caption) class TomwerWithStackStack( OWEwoksWidgetWithTaskStack, _SuperviseMixIn, WidgetLongProcessing, openclass=True ): def __init__(self, parent, process_id=None, *args, **kwargs): OWEwoksWidgetWithTaskStack.__init__(self, parent, args, kwargs) _SuperviseMixIn.__init__(self, process_id=process_id) WidgetLongProcessing.__init__(self) self.task_executor_queue.sigComputationStarted.connect(self._startProcessing) self.task_executor_queue.sigComputationEnded.connect(self._endProcessing) def setCaption(self, caption): OWBaseWidget.setCaption(self, caption) _SuperviseMixIn.setCaption(self, caption=caption) def trigger_downstream(self) -> None: # for now ewoksorange send ewoks variable. This will work only if # all task are implemented using ewokwidget which is not the case today for ewoksname, var in self.get_task_outputs().items(): channel = self._get_output_signal(ewoksname) if invalid_data.is_invalid_data(var.value): channel.send(None) # or channel.invalidate? else: channel.send(var.value) class TomwerUnsupervisedOneThreadPerRun( OWEwoksWidgetOneThreadPerRun, WidgetLongProcessing, openclass=True ): """EwoksOrange OWEwoksWidgetOneThreadPerRun with API to provide dataset state information""" pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/orange/settings.py0000644000175000017500000000132014757047403022655 0ustar00paynopaynofrom __future__ import annotations from orangewidget import settings class CallbackSettingsHandler(settings.SettingsHandler): """ Settings handler used to call some callback before packing data (so before) saving orange :class:`Setting` """ def __init__(self): super(CallbackSettingsHandler, self).__init__() self.__callbacks = [] def addCallback(self, _callback): self.__callbacks.append(_callback) def removeCallback(self, callback): self.__callbacks.remove(callback) def pack_data(self, widget): """""" for callback in self.__callbacks: callback() return super(CallbackSettingsHandler, self).pack_data(widget) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/state_summary.py0000644000175000017500000000325715153325210022434 0ustar00paynopaynofrom orangewidget.utils.signals import PartialSummary, summarize from tomwer.core.cluster import SlurmClusterConfiguration from tomwer.core.futureobject import FutureTomwerObject from tomwer.core.scan.blissscan import BlissScan from tomwer.core.scan.scanbase import TomwerScanBase @summarize.register(object) # noqa F811 def summarize_(Object: object): # noqa F811 return PartialSummary("any object", "an oject of any type") @summarize.register(dict) # noqa F811 def summarize_(configuration: dict): # noqa F811 return PartialSummary( "any configuration", "any configuration that can be provided to a process" ) @summarize.register(SlurmClusterConfiguration) # noqa F811 def summarize_(cluster_config: SlurmClusterConfiguration): # noqa F811 return PartialSummary( "cluster configuration", "cluster configuration to launch some remote processing", ) @summarize.register(TomwerScanBase) # noqa F811 def summarize_(data: TomwerScanBase): # noqa F811 return PartialSummary( "dataset with processing history", "core object used to ship dataset and history of processing done on this dataset", ) @summarize.register(FutureTomwerObject) # noqa F811 def summarize_(future_data: FutureTomwerObject): # noqa F811 return PartialSummary( "dataset with pending processing", "object used when there is some pending processing (asyncio.future). Can be convert back to `data`", ) @summarize.register(BlissScan) # noqa F811 def summarize_(bliss_scan: BlissScan): # noqa F811 return PartialSummary( "raw dataset from bliss", "object used when debug some processing relative to bliss", ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8811002 tomwer-1.6.17/src/orangecontrib/tomwer/tests/0000755000175000017500000000000015153325403020324 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/tests/TestAcquisition.py0000644000175000017500000001714415153325210024031 0ustar00paynopayno"""Full tomwer test suite.""" from __future__ import annotations import logging import os import shutil from silx.gui import qt from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.tests.datasets import TomwerCIDatasets logger = logging.getLogger(__name__) class Simulation(qt.QThread): """Simulation is a simple class able to simulate an acquisition by copying files on a targetted directory. :param targetdir: the folder where the acquisition is stored :param manipulationId: the id of the simulation we want to simulate :param finalState: when launched, the state to reach before stopping :warning: the targetted directory won't be removed or cleaned during class destruction. This is to be managed by callers. """ advancement = { "not started": -1, "starting-s0": 0, "starting-s1": 1, "acquisitionRunning": 2, "acquisitionDone": 3, "reconstructionLaunched": 4, } sigAdvancementChanged = qt.Signal(int) __definedDataset = ["test01", "test10"] def __init__(self, targetdir, manipulationId, finalState=4): assert type(manipulationId) is str assert type(targetdir) is str assert manipulationId in self.__definedDataset super(Simulation, self).__init__() self.targetdir = targetdir self.outputFolder = os.path.sep.join((targetdir, manipulationId)) self.finalState = finalState self.currentState = "not started" self._createFinalXML = False ( self.originalFolder, self.nbSlices, self.manipulationId, ) = self.__getOriginalDataSet(manipulationId) self.stopFileCreationForRunningState = int(self.nbSlices / 2) self.srcPattern = None self.destPattern = None def __getOriginalDataSet(self, dataSetID): """Return paths to the requested scan""" assert dataSetID in self.__definedDataset dataDir = TomwerCIDatasets.get_dataset(os.path.join("edf_datasets", dataSetID)) assert os.path.isdir(dataDir) assert os.path.isfile(os.path.join(dataDir, dataSetID + ".info")) slices = EDFTomoScan(dataDir).projections nbSlices = len(slices) manipulationID = dataSetID return dataDir, nbSlices, manipulationID def advanceTo(self, state): """Reset the new advancement targetted :param state: the new state to reach when run will be executed """ assert state in Simulation.advancement assert type(state) is str self.finalState = Simulation.advancement[state] def setSrcDestPatterns(self, srcPattern, destPattern): """ If setted, will set the .info and .xml files into a different folder """ self.srcPattern = srcPattern self.destPattern = destPattern if srcPattern is not None or destPattern is not None: assert os.path.isdir(srcPattern) assert os.path.isdir(destPattern) targettedFolder = self.outputFolder.replace( self.srcPattern, self.destPattern, 1 ) if not os.path.isdir(targettedFolder): os.makedirs(targettedFolder) def __shouldExecStep(self, step): """Return True if the thread should exec this step to advance taking into consideration is current state and his final state """ return self.finalState >= self.advancement[step] and ( Simulation.advancement[self.currentState] + 1 == self.advancement[step] ) def run(self): """Main function, run the acquisition through all states until finalState is reached """ if self.__shouldExecStep("starting-s0") is True: logger.info("starting-s0") self._startAcquisition() self.currentState = "starting-s0" self.signalCurrentState() if self.__shouldExecStep("starting-s1") is True: self.copyInitialFiles() logger.info("starting-s1") self.currentState = "starting-s1" self.signalCurrentState() if self.__shouldExecStep("acquisitionRunning") is True: self._copyScans((0, self.stopFileCreationForRunningState)) logger.info("acquisitionRunning") self.currentState = "acquisitionRunning" self.signalCurrentState() if self.__shouldExecStep("acquisitionDone") is True: self._copyScans((self.stopFileCreationForRunningState, self.nbSlices)) if self._createFinalXML is True: inputXMLFile = os.path.join( self.originalFolder, self.manipulationId + ".xml" ) assert os.path.isfile(inputXMLFile) ouputXMLFile = os.path.join( self.outputFolder, self.manipulationId + ".xml" ) shutil.copyfile(inputXMLFile, ouputXMLFile) logger.info("acquisitionDone") self.currentState = "acquisitionDone" self.signalCurrentState() def signalCurrentState(self): """Signal the actual state of the simulation""" self.sigAdvancementChanged.emit(self.currentState) def _startAcquisition(self): """create needed data dir""" for newFolder in (self.targetdir, self.outputFolder): if not os.path.exists(self.outputFolder): os.makedirs(self.outputFolder) def _copyScans(self, _slicesRange): """copy the .edf file from the original directory to the outputFolder :_slicesRange tuple: the _range of slices data we want to copy """ logger.info("copying files from %s to %s" % (_slicesRange[0], _slicesRange[1])) for iSlice in list(range(_slicesRange[0], _slicesRange[1])): filename = "".join((self.manipulationId, format(iSlice, "04d"), ".edf")) srcFile = os.path.join(self.originalFolder, filename) outputFile = os.path.join(self.outputFolder, filename) assert os.path.isfile(srcFile) assert os.path.isdir(self.outputFolder) shutil.copyfile(srcFile, outputFile) def copyInitialFiles(self): """copy the .info file""" assert os.path.isdir(self.originalFolder) logger.info( "copying initial files (.info, .xml...) from %s to %s" % (self.originalFolder, self.manipulationId) ) for extension in (".info", ".db", ".cfg"): filename = "".join((self.manipulationId, extension)) srcFile = os.path.join(self.originalFolder, filename) targettedFolder = self.outputFolder if self.srcPattern is not None or self.destPattern is not None: targettedFolder = self.outputFolder.replace( self.srcPattern, self.destPattern, 1 ) assert os.path.isfile(srcFile) assert os.path.isdir(targettedFolder) assert os.path.isdir(self.originalFolder) shutil.copy2(srcFile, targettedFolder) def createFinalXML(self, val): """If activated, once all the file will be copied, this will create an .xml file into the output directory """ self._createFinalXML = val def createParFile(self): pass def createReconstructedFile(self): pass def createOARJob(self): pass def createDark(self): pass def createJPG(self): pass def createVolfloat(self): pass def createVolraw(self): pass def __createFileTo(self, filePath): assert type(filePath) is str open(filePath, "a").close() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/tests/__init__.py0000644000175000017500000000000014757047403022435 0ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8811002 tomwer-1.6.17/src/orangecontrib/tomwer/tutorials/0000755000175000017500000000000015153325403021210 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/tutorials/EBS_tomo_listener.ows0000644000175000017500000001123515153325210025314 0ustar00paynopayno wait for bliss scan and create NXtomo compute reduced darks and flats compute COR compute slice browse dataset and reconstructed slice(s) {'_blissConfiguration': {}, '_nxtomo_cfg_file': '', '_static_input': {'nxtomomill_cfg_file': ''}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'dark_ref_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'axis_params': {'MODE': 'sino-sliding-window', 'POSITION_VALUE': None, 'CALC_INPUT_TYPE': 'transmission_nopag', 'ANGLE_MODE': '0-180', 'USE_SINOGRAM': True, 'SINOGRAM_LINE': 'middle', 'SINOGRAM_SUBSAMPLING': 10, 'AXIS_URL_1': '', 'AXIS_URL_2': '', 'LOOK_AT_STDMAX': False, 'NEAR_WX': 5, 'FINE_STEP_X': 0.1, 'SCALE_IMG2_TO_IMG1': False, 'NEAR_POSITION': 0.0, 'PADDING_MODE': 'edge', 'FLIP_LR': True, 'COMPOSITE_OPTS': {'theta': 10, 'oversampling': 4, 'n_subsampling_y': 10, 'take_log': True, 'near_pos': 0.0, 'near_width': 20}, 'SIDE': 'left', 'COR_OPTIONS': ''}, 'gui': {'mode_is_lock': True, 'value_is_lock': False, 'auto_update_estimated_cor': True}}, 'controlAreaVisible': True, 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\x01k\x00\x00\x00\xac\x00\x00\x06\x01\x00\x00\x03\x8e\x00\x00\x01k\x00\x00\x00\xd1\x00\x00\x06\x01\x00\x00\x03\x8e\x00\x00\x00\x00\x00\x00\x00\x00\x07\x80\x00\x00\x01k\x00\x00\x00\xd1\x00\x00\x06\x01\x00\x00\x03\x8e', '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'nabu_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_viewer_config': {}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/tutorials/__init__.py0000644000175000017500000000000014757047403023321 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/tutorials/append_raw_darks_and_flats_frames_to_NXtomos.ows0000644000175000017500000001255315153325210033011 0ustar00paynopayno Context: we want to modify a NXtomo in order to append some (raw) darks / flats to it. Then those raw darks and flats will be used for reduced darks / flats calculation. warning: reduced darks and flats are usually mean / median of a serie of darks / flats. when raw darks and flats are raw frame before mean / median 'reduction' NXtomo to be patched Step 3 : process NXtomo step1: define frame series to be ignored (here darks and flats series to avoid conflict with the one added by the dark / flat patch) result: NXtomo with patched frame (step 2) and reduced darks and flats to be used for reconstruction standard darks / flats reduction (but taking into account patched darks / flats frames) step2: provide series of darks / flats from other(s) NXtomo to be added to the `NXtomo to be patched` {'_ewoks_default_inputs': {'operations': {}}, '_ewoks_execinfo': {}, '_ewoks_varinfo': {}, 'controlAreaVisible': True, 'default_inputs': {}, 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\x07\xe6\x00\x00\x01\x18\x00\x00\n/\x00\x00\x03-\x00\x00\x07\xeb\x00\x00\x015\x00\x00\n*\x00\x00\x03(\x00\x00\x00\x01\x00\x00\x00\x00\x07\x7f\x00\x00\x07\xeb\x00\x00\x015\x00\x00\n*\x00\x00\x03(', '__version__': 1} {'_urlsSetting': {}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'dark_ref_params': {'DOWHEN': 'before', 'DARKCAL': 'mean', 'DARKOVE': 0, 'DARKRMV': 0, 'DKFILE': 'darkend[0-9]{3,4}', 'REFSCAL': 'median', 'REFSOVE': 0, 'REFSRMV': 0, 'RFFILE': 'ref*.*[0-9]{3,4}_[0-9]{3,4}'}}, 'controlAreaVisible': True, 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\x06\x9b\x00\x00\x02K\x00\x00\n\x95\x00\x00\x04\x8f\x00\x00\x06\xa0\x00\x00\x02h\x00\x00\n\x90\x00\x00\x04\x8a\x00\x00\x00\x01\x00\x00\x00\x00\x07\x7f\x00\x00\x06\xa0\x00\x00\x02h\x00\x00\n\x90\x00\x00\x04\x8a', '__version__': 1} {'_scanIDs': [], 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_scanIDs': [], 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/tutorials/cast_volume.ows0000644000175000017500000000554615153325210024271 0ustar00paynopayno define volume volume casting display original volume display volume casted {'_scanIDs': [], 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'cast_volume_params': {}}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/tutorials/copy_reduced_darks_and_flats_meth1.ows0000644000175000017500000001407715153325210030711 0ustar00paynopayno step2: provide scans for which we need to copy reduced darks and flats invalid any existing darks or flats frames (else reduced darks and flats will use them instead of making the copy) will copy reduced darks / flats to `dataset_{darks|flats}.hdf5` to be used for reconstruction step1: provide scan with already computed darks and flats result: scans with copied reduced darks / flats Context: on this workflow we want to copy reduced flats / darks from a dataset to others. This one of the various way to do this. Note: You can also replace the two upper widgets (providing reduced darks and flats) by a python script providing a python dictionary. * Key should be position of the flat / dark in the sequence (so 0 if at the beginning for example) * Value is the 2D numpy array with mean / median /xxx of the darks and flats serie {'_scanIDs': [], 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} gASVLwEAAAAAAAB9lCiMFV9ld29rc19kZWZhdWx0X2lucHV0c5R9lIwKb3BlcmF0aW9uc5R9lCiM G3RvbW9zY2FuLmVzcmYuc2Nhbi5oZGY1c2NhbpSMCEltYWdlS2V5lJOUSwKFlFKUaAdLA4WUUpRo B0sBhZRSlGgLdXOMD19ld29rc19leGVjaW5mb5R9lIwOX2V3b2tzX3ZhcmluZm+UfZSMEmNvbnRy b2xBcmVhVmlzaWJsZZSIjA5kZWZhdWx0X2lucHV0c5R9lIwTc2F2ZWRXaWRnZXRHZW9tZXRyeZRD QgHZ0MsAAwAAAAAH5gAAARgAAAovAAADLQAAB+sAAAE1AAAKKgAAAygAAAABAAAAAAd/AAAH6wAA ATUAAAoqAAADKJSMC19fdmVyc2lvbl9flEsBdS4= {'_ewoks_default_inputs': {'data': None, 'dark_ref_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\x07\x0e\x00\x00\x015\x00\x00\x0b\x08\x00\x00\x03\x10\x00\x00\x07\x13\x00\x00\x01R\x00\x00\x0b\x03\x00\x00\x03\x0b\x00\x00\x00\x01\x00\x00\x00\x00\x07\x7f\x00\x00\x07\x13\x00\x00\x01R\x00\x00\x0b\x03\x00\x00\x03\x0b', '__version__': 1} {'_tomo_obj_setting': '', 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_tomo_obj_setting': '', 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_scanIDs': [], 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/tutorials/copy_reduced_darks_and_flats_meth2.ows0000644000175000017500000001212415153325210030701 0ustar00paynopayno step2: provide scans for which we need to copy reduced darks and flats invalid any existing darks or flats frames (else reduced darks and flats will use them instead of making the copy) will copy reduced darks / flats to `dataset_{darks|flats}.hdf5` to be used for reconstruction step1: provide reduced darks and flats from the 'copy' tab, unselecting auto and setting them through `select darks url` and `select flats url` result: scans with copied reduced darks / flats Context: on this workflow we want to copy reduced flats / darks from a dataset to others. This one of the various way to do this. Note: reduced darks / flats can be saved to disk from another python script using the `silx.io.dictdump` dicttoh5 function. Reduced darks and flats are dictionary with index in the sequence as key (so index==0 if the dark / flat serie is done at the beginning) and the reduced darks / flats as value (2D numpy array) {'_scanIDs': [], 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} gASVLwEAAAAAAAB9lCiMFV9ld29rc19kZWZhdWx0X2lucHV0c5R9lIwKb3BlcmF0aW9uc5R9lCiM G3RvbW9zY2FuLmVzcmYuc2Nhbi5oZGY1c2NhbpSMCEltYWdlS2V5lJOUSwKFlFKUaAdLA4WUUpRo B0sBhZRSlGgLdXOMD19ld29rc19leGVjaW5mb5R9lIwOX2V3b2tzX3ZhcmluZm+UfZSMEmNvbnRy b2xBcmVhVmlzaWJsZZSIjA5kZWZhdWx0X2lucHV0c5R9lIwTc2F2ZWRXaWRnZXRHZW9tZXRyeZRD QgHZ0MsAAwAAAAAH5gAAARgAAAovAAADLQAAB+sAAAE1AAAKKgAAAygAAAABAAAAAAd/AAAH6wAA ATUAAAoqAAADKJSMC19fdmVyc2lvbl9flEsBdS4= {'_ewoks_default_inputs': {'data': None, 'dark_ref_params': {'DOWHEN': 'before', 'DARKCAL': 'mean', 'DARKOVE': 0, 'DARKRMV': 0, 'DKFILE': 'darkend[0-9]{3,4}', 'REFSCAL': 'median', 'REFSOVE': 0, 'REFSRMV': 0, 'RFFILE': 'ref*.*[0-9]{3,4}_[0-9]{3,4}'}}, 'controlAreaVisible': True, 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\x06\x9b\x00\x00\x02K\x00\x00\n\x95\x00\x00\x04\x8f\x00\x00\x06\xa0\x00\x00\x02h\x00\x00\n\x90\x00\x00\x04\x8a\x00\x00\x00\x01\x00\x00\x00\x00\x07\x7f\x00\x00\x06\xa0\x00\x00\x02h\x00\x00\n\x90\x00\x00\x04\x8a', '__version__': 1} {'_scanIDs': [], 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/tutorials/default_cor_search.ows0000644000175000017500000001113315153325210025551 0ustar00paynopayno provide dataset compute reduced darks and flats compute center of rotation manually or using one of the numerous existing algorithms reconstruct one or several slices browse reconstructed slices and browse dataset {'_scanIDs': [], 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'dark_ref_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'axis_params': {'MODE': 'manual', 'POSITION_VALUE': None, 'CALC_INPUT_TYPE': 'transmission_nopag', 'ANGLE_MODE': '0-180', 'USE_SINOGRAM': False, 'SINOGRAM_LINE': '', 'SINOGRAM_SUBSAMPLING': 10, 'AXIS_URL_1': '', 'AXIS_URL_2': '', 'LOOK_AT_STDMAX': False, 'NEAR_WX': 5, 'FINE_STEP_X': 0.1, 'SCALE_IMG2_TO_IMG1': False, 'NEAR_POSITION': 0.0, 'PADDING_MODE': 'edge', 'FLIP_LR': True, 'COMPOSITE_OPTS': {'theta': 10, 'n_subsampling_y': 10, 'oversampling': 4, 'take_log': True, 'near_pos': 0, 'near_width': 20}, 'SIDE': 'all', 'COR_OPTIONS': ''}, 'gui': {'mode_is_lock': False, 'value_is_lock': False, 'auto_update_estimated_cor': True}}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'nabu_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_viewer_config': {}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/tutorials/drac_publication.ows0000644000175000017500000001377515153325210025255 0ustar00paynopayno provide dataset publish reconstructed volume to icat reconstruct the volume {'_scanIDs': [], 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'dark_ref_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'axis_params': {'MODE': 'manual', 'POSITION_VALUE': None, 'CALC_INPUT_TYPE': 'transmission_nopag', 'ANGLE_MODE': '0-180', 'USE_SINOGRAM': False, 'SINOGRAM_LINE': '', 'SINOGRAM_SUBSAMPLING': 10, 'AXIS_URL_1': '', 'AXIS_URL_2': '', 'LOOK_AT_STDMAX': False, 'NEAR_WX': 5, 'FINE_STEP_X': 0.1, 'SCALE_IMG2_TO_IMG1': False, 'NEAR_POSITION': 0.0, 'PADDING_MODE': 'edge', 'FLIP_LR': True, 'COMPOSITE_OPTS': {'theta': 10, 'n_subsampling_y': 10, 'oversampling': 4, 'take_log': True, 'near_pos': 0, 'near_width': 20}, 'SIDE': 'all', 'COR_OPTIONS': ''}, 'gui': {'mode_is_lock': False, 'value_is_lock': False, 'auto_update_estimated_cor': True}}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'nabu_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_viewer_config': {}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'nabu_volume_params': None, 'nabu_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {}, '_ewoks_execinfo': {}, '_ewoks_varinfo': {}, 'controlAreaVisible': True, 'default_inputs': {}, 'savedWidgetGeometry': None, '__version__': 1} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/tutorials/hello_world_python_script.ows0000644000175000017500000000712614757047403027261 0ustar00paynopayno 1: provide a scan either by: * using the 'select button' * copy-paste a file containing a NXtomo to the interface 2: print some information about this scan {'_tomo_obj_setting': '', 'controlAreaVisible': True, 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\x08C\x00\x00\x02=\x00\x00\r\xb3\x00\x00\x02\xd8\x00\x00\x08C\x00\x00\x02b\x00\x00\r\xb3\x00\x00\x02\xd8\x00\x00\x00\x01\x00\x00\x00\x00\x07\x80\x00\x00\x08C\x00\x00\x02b\x00\x00\r\xb3\x00\x00\x02\xd8', '__version__': 1} gASVKQUAAAAAAAB9lCiMEmNvbnRyb2xBcmVhVmlzaWJsZZSIjBJjdXJyZW50U2NyaXB0SW5kZXiU SwCMEWxpYnJhcnlMaXN0U291cmNllF2UjDFvcmFuZ2Vjb250cmliLnRvbXdlci53aWRnZXRzLm90 aGVyLlB5dGhvblNjcmlwdE9XlIwGU2NyaXB0lJOUKYGUfZQojARuYW1llIwLSGVsbG8gd29ybGSU jAZzY3JpcHSUWOgBAABmcm9tIHRvbXdlci5jb3JlLnNjYW4uaGRmNXNjYW4gaW1wb3J0IEhERjVU b21vU2Nhbgpmcm9tIHRvbXdlci5jb3JlLnNjYW4uZWRmc2NhbiBpbXBvcnQgRURGVG9tb1NjYW4K c2NhbiA9IGluX2RhdGEKaWYgaXNpbnN0YW5jZShzY2FuLCBIREY1VG9tb1NjYW4pOgogICAgcHJp bnQoInNjYW4gbWFzdGVyIGZpbGUgaXMiLCBzY2FuLm1hc3Rlcl9maWxlKQplbHNlOgogICAgcHJp bnQoInNjYW4gZGlyZWN0b3J5IGlzIiwgc2Nhbi5wYXRoKQoKcHJpbnQoZiJzY2FuIGhhcyB7bGVu KHNjYW4ucHJvamVjdGlvbnMpfSBwcm9qZWN0aW9ucywge2xlbihzY2FuLmRhcmtzKX0gZGFya3Mg YW5kIHtsZW4oc2Nhbi5mbGF0cyl9IGZsYXRzIikKCnByaW50KGYic2NhbiBlbmVyZ3kgaXMge3Nj YW4uZW5lcmd5fSwgcm90YXRpb24gYW5nbGUgZ29lcyBmcm9tIHttaW4oc2Nhbi5yb3RhdGlvbl9h bmdsZSl9IHRvIHttYXgoc2Nhbi5yb3RhdGlvbl9hbmdsZSl9IGRlZ3JlZXMiKZSMBWZsYWdzlEsA jAhmaWxlbmFtZZROdWJhjBNzYXZlZFdpZGdldEdlb21ldHJ5lENCAdnQywADAAAAAAhKAAAA0wAA DWYAAARRAAAISgAAAPgAAA1mAAAEUQAAAAEAAAAAB4AAAAhKAAAA+AAADWYAAARRlIwKc2NyaXB0 VGV4dJRY6AEAAGZyb20gdG9td2VyLmNvcmUuc2Nhbi5oZGY1c2NhbiBpbXBvcnQgSERGNVRvbW9T Y2FuCmZyb20gdG9td2VyLmNvcmUuc2Nhbi5lZGZzY2FuIGltcG9ydCBFREZUb21vU2NhbgpzY2Fu ID0gaW5fZGF0YQppZiBpc2luc3RhbmNlKHNjYW4sIEhERjVUb21vU2Nhbik6CiAgICBwcmludCgi c2NhbiBtYXN0ZXIgZmlsZSBpcyIsIHNjYW4ubWFzdGVyX2ZpbGUpCmVsc2U6CiAgICBwcmludCgi c2NhbiBkaXJlY3RvcnkgaXMiLCBzY2FuLnBhdGgpCgpwcmludChmInNjYW4gaGFzIHtsZW4oc2Nh bi5wcm9qZWN0aW9ucyl9IHByb2plY3Rpb25zLCB7bGVuKHNjYW4uZGFya3MpfSBkYXJrcyBhbmQg e2xlbihzY2FuLmZsYXRzKX0gZmxhdHMiKQoKcHJpbnQoZiJzY2FuIGVuZXJneSBpcyB7c2Nhbi5l bmVyZ3l9LCByb3RhdGlvbiBhbmdsZSBnb2VzIGZyb20ge21pbihzY2FuLnJvdGF0aW9uX2FuZ2xl KX0gdG8ge21heChzY2FuLnJvdGF0aW9uX2FuZ2xlKX0gZGVncmVlcyIplIwNc3BsaXR0ZXJTdGF0 ZZROjAtfX3ZlcnNpb25fX5RLAXUu ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8811002 tomwer-1.6.17/src/orangecontrib/tomwer/tutorials/id16b/0000755000175000017500000000000015153325403022115 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/tutorials/id16b/ID16b_full_volume.ows0000644000175000017500000000327715153325210026072 0ustar00paynopayno {'_scanIDs': [], 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_rpSetting': {}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, 'static_input': {'data': None, 'nabu_params': None}, '__version__': 1} {'_rpSetting': {}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, 'static_input': {'data': None, 'nabu_volume_params': None, 'nabu_params': None}, '__version__': 1} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989076.0 tomwer-1.6.17/src/orangecontrib/tomwer/tutorials/id16b/ID16b_insitu.ows0000644000175000017500000007160215153325224025056 0ustar00paynopayno {'_muted': False, 'controlAreaVisible': False, 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\x04n\x00\x00\x01\xfe\x00\x00\x05\xc1\x00\x00\x03-\x00\x00\x04n\x00\x00\x02#\x00\x00\x05\xc1\x00\x00\x03-\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x04n\x00\x00\x02#\x00\x00\x05\xc1\x00\x00\x03-', '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'nabu_params': {'preproc': {'flatfield': 1, 'double_flatfield': 0, 'dff_sigma': 0.0, 'ccd_filter_enabled': 0, 'ccd_filter_threshold': 0.04, 'take_logarithm': True, 'log_min_clip': 1e-06, 'log_max_clip': 10.0, 'sino_rings_correction': 'None', 'sino_rings_options': 'sigma=1.0 ; levels=10 ; padding=False', 'tilt_correction': '', 'autotilt_options': '', 'normalize_srcurrent': 1}, 'reconstruction': {'method': 'FBP', 'slice_plane': 'XY', 'angles_file': '', 'axis_correction_file': '', 'angle_offset': 0.0, 'fbp_filter_type': 'ramlak', 'padding_type': 'edges', 'iterations': 200, 'optim_algorithm': 'chambolle-pock', 'regularization_weight': 0.01, 'preconditioning_filter': 1, 'positivity_constraint': 1, 'rotation_axis_position': '', 'translation_movements_file': '', 'clip_outer_circle': 1, 'centered_axis': 1, 'start_x': 0, 'end_x': -1, 'start_y': 0, 'end_y': -1, 'start_z': 0, 'end_z': -1, 'enable_halftomo': 0}, 'dataset': {'binning': 1, 'binning_z': 1, 'projections_subsampling': 1}, 'tomwer_slices': 'middle', 'output': {'file_format': 'vol', 'location': '', 'output_dir_mode': 'same folder as scan'}, 'phase': {'method': 'Paganin', 'delta_beta': '180', 'padding_type': 'edge', 'unsharp_coeff': 3.0, 'unsharp_sigma': 0.8, 'ctf_geometry': ' z1_v=None; z1_h=None; detec_pixel_size=None; magnification=True', 'beam_shape': 'parallel', 'ctf_advanced_params': ' length_scale=1e-05; lim1=1e-05; lim2=0.2; normalize_by_mean=True', 'ctf_translations_file': ''}, 'configuration_level': 'optional', 'mode_locked': True, 'cluster_config': None}}, 'controlAreaVisible': True, 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\x02\xaa\x00\x00\x00\xb4\x00\x00\x083\x00\x00\x04\x12\x00\x00\x02\xaa\x00\x00\x00\xb4\x00\x00\x083\x00\x00\x04\x12\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x02\xaa\x00\x00\x00\xb4\x00\x00\x083\x00\x00\x04\x12', '__version__': 1} gASVPgEAAAAAAAB9lCiMDl92aWV3ZXJfY29uZmlnlH2UKIwEbW9kZZSMI3RvbXdlci5ndWkudmlz dWFsaXphdGlvbi5kYXRhdmlld2VylIwMX0Rpc3BsYXlNb2RllJOUjAZzbGljZXOUhZRSlIwJc2xp Y2Vfb3B0lGgEjApfU2xpY2VNb2RllJOUjAZsYXRlc3SUhZRSlIwJcmFkaW9fb3B0lGgEjApfUmFk aW9Nb2RllJOUjApub3JtYWxpemVklIWUUpR1jBJjb250cm9sQXJlYVZpc2libGWUiIwTc2F2ZWRX aWRnZXRHZW9tZXRyeZRDQgHZ0MsAAwAAAAAASAAAAIIAAAeRAAAEpAAAAEgAAACnAAAHkQAABKQA AAAAAAAAAAoAAAAASAAAAKcAAAeRAAAEpJSMC19fdmVyc2lvbl9flEsBdS4= {'_ewoks_default_inputs': {'data': None, 'axis_params': {'MODE': 'centered', 'POSITION_VALUE': -27.7489905564438, 'CALC_INPUT_TYPE': 'transmission_nopag', 'ANGLE_MODE': '0-180', 'USE_SINOGRAM': False, 'SINOGRAM_LINE': '', 'SINOGRAM_SUBSAMPLING': 10, 'AXIS_URL_1': '', 'AXIS_URL_2': '', 'LOOK_AT_STDMAX': False, 'NEAR_WX': 5, 'FINE_STEP_X': 0.1, 'SCALE_IMG2_TO_IMG1': False, 'NEAR_POSITION': 0.0, 'PADDING_MODE': 'edge', 'FLIP_LR': True, 'COMPOSITE_OPTS': {'theta': 10, 'n_subsampling_y': 10, 'oversampling': 4, 'take_log': True, 'near_pos': 0, 'near_width': 20}, 'SIDE': 'center', 'COR_OPTIONS': ''}, 'gui': {'mode_is_lock': True, 'value_is_lock': False, 'auto_update_estimated_cor': False}}, 'controlAreaVisible': True, 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\x02\xda\x00\x00\x00Y\x00\x00\x08\xac\x00\x00\x03U\x00\x00\x02\xda\x00\x00\x00~\x00\x00\x08\xac\x00\x00\x03U\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x02\xda\x00\x00\x00~\x00\x00\x08\xac\x00\x00\x03U', '__version__': 1} gASVwwUAAAAAAAB9lCiMEmNvbnRyb2xBcmVhVmlzaWJsZZSIjBJjdXJyZW50U2NyaXB0SW5kZXiU SwCMEWxpYnJhcnlMaXN0U291cmNllF2UjDFvcmFuZ2Vjb250cmliLnRvbXdlci53aWRnZXRzLm90 aGVyLlB5dGhvblNjcmlwdE9XlIwGU2NyaXB0lJOUKYGUfZQojARuYW1llIwLSGVsbG8gd29ybGSU jAZzY3JpcHSUWDUCAABpbXBvcnQgb3MKc2NhbiA9IGluX2RhdGEKCnZvbF9mbG9hdF9wYXRoID0g b3MucGF0aC5qb2luKAogICAgb3MucGF0aC5kaXJuYW1lKHNjYW4ucGF0aCksCiAgICAiLnZvbGZs b2F0X25vYmFja3VwIiwKKQoKdm9sX2Zsb2F0X3N5bV9saW5rX3BhdGggPSBvcy5wYXRoLmpvaW4o CiAgICBvcy5wYXRoLmRpcm5hbWUoc2Nhbi5wYXRoKSwKICAgICJ2b2xmbG9hdCIsCikKCmlmIG5v dCBvcy5wYXRoLmV4aXN0cyh2b2xfZmxvYXRfcGF0aCk6CiAgICBwcmludChmImNyZWF0ZXMge3Zv bF9mbG9hdF9wYXRofSIpCiAgICBvcy5tYWtlZGlycyh2b2xfZmxvYXRfcGF0aCwgbW9kZT0wbzc3 NCkKICAgICMgZG9uJ3Qga25vdyB3aHkgYnV0IGZpcnN0IGNyZWF0aW9uIHdpdGggMG83NzQgZmFp bHMuLi4KICAgIG9zLmNobW9kKHZvbF9mbG9hdF9wYXRoLCAwbzc3NCkKICAgIAogICAgIyBjcmVh dGUgc3ltbGluayBmcm9tIHZvbGZsb2F0IHRvICIudm9sZmxvYXRfbm9iYWNrdXAiCiAgICBvcy5z eW1saW5rKHZvbF9mbG9hdF9wYXRoLCB2b2xfZmxvYXRfc3ltX2xpbmtfcGF0aCkKCgpvdXRfZGF0 YSA9IHNjYW4KlIwFZmxhZ3OUSwCMCGZpbGVuYW1llE51YmGME3NhdmVkV2lkZ2V0R2VvbWV0cnmU Q0IB2dDLAAMAAAAAAEgAAABAAAAGBwAAA3YAAABIAAAAQAAABgcAAAN2AAAAAAAAAAAKAAAAAEgA AABAAAAGBwAAA3aUjApzY3JpcHRUZXh0lFg1AgAAaW1wb3J0IG9zCnNjYW4gPSBpbl9kYXRhCgp2 b2xfZmxvYXRfcGF0aCA9IG9zLnBhdGguam9pbigKICAgIG9zLnBhdGguZGlybmFtZShzY2FuLnBh dGgpLAogICAgIi52b2xmbG9hdF9ub2JhY2t1cCIsCikKCnZvbF9mbG9hdF9zeW1fbGlua19wYXRo ID0gb3MucGF0aC5qb2luKAogICAgb3MucGF0aC5kaXJuYW1lKHNjYW4ucGF0aCksCiAgICAidm9s ZmxvYXQiLAopCgppZiBub3Qgb3MucGF0aC5leGlzdHModm9sX2Zsb2F0X3BhdGgpOgogICAgcHJp bnQoZiJjcmVhdGVzIHt2b2xfZmxvYXRfcGF0aH0iKQogICAgb3MubWFrZWRpcnModm9sX2Zsb2F0 X3BhdGgsIG1vZGU9MG83NzQpCiAgICAjIGRvbid0IGtub3cgd2h5IGJ1dCBmaXJzdCBjcmVhdGlv biB3aXRoIDBvNzc0IGZhaWxzLi4uCiAgICBvcy5jaG1vZCh2b2xfZmxvYXRfcGF0aCwgMG83NzQp CiAgICAKICAgICMgY3JlYXRlIHN5bWxpbmsgZnJvbSB2b2xmbG9hdCB0byAiLnZvbGZsb2F0X25v YmFja3VwIgogICAgb3Muc3ltbGluayh2b2xfZmxvYXRfcGF0aCwgdm9sX2Zsb2F0X3N5bV9saW5r X3BhdGgpCgoKb3V0X2RhdGEgPSBzY2FuCpSMDXNwbGl0dGVyU3RhdGWUTowLX192ZXJzaW9uX1+U SwF1Lg== gASVKQ8AAAAAAAB9lCiMEmNvbnRyb2xBcmVhVmlzaWJsZZSIjBJjdXJyZW50U2NyaXB0SW5kZXiU SwCMEWxpYnJhcnlMaXN0U291cmNllF2UjDFvcmFuZ2Vjb250cmliLnRvbXdlci53aWRnZXRzLm90 aGVyLlB5dGhvblNjcmlwdE9XlIwGU2NyaXB0lJOUKYGUfZQojARuYW1llIwLSGVsbG8gd29ybGSU jAZzY3JpcHSUWOgGAABpbXBvcnQgc2h1dGlsCmltcG9ydCBvcwpmcm9tIHRvbXdlci5jb3JlLnNj YW4uZWRmc2NhbiBpbXBvcnQgRURGVG9tb1NjYW4KZnJvbSBzaWx4LmlvLmRpY3RkdW1wIGltcG9y dCBkaWN0dG9pbmksIGxvYWQgYXMgbG9hZF9pbmkKCmRlZiBnZXRfa2V5KGxpbmUpOgogICAgIiIi InJldHVybiBrZXkgbmFtZSBvZiBhIC5pbmZvIGZpbGUiIiIKICAgIHJldHVybiBsaW5lLnNwbGl0 KCI9IilbMF0ucmVwbGFjZSgiICIsICIiKQoKCmRlZiBnZXRfcmF3X2RpY3QoZmlsZV9wYXRoKToK ICAgICIiInJldHVybiB0aGUgaW5mbyBmaWxlIG1ldGFkYXRhIGFzIGEgZGljdGlvbmFyeSB3aXRo IG1ldGFkYXRhIG5hbWUgYXMga2V5IGFuZCByYXcgbGluZSBhcyB2YWx1ZSIiIgogICAgbWV0YWRh dGEgPSB7fQogICAgd2l0aCBvcGVuKGZpbGVfcGF0aCwgbW9kZT0iciIpIGFzIGY6CiAgICAgICAg bGluZSA9IGYucmVhZGxpbmUoKQogICAgICAgIHdoaWxlIGxpbmU6CiAgICAgICAgICAgIGtleSA9 IGdldF9rZXkobGluZSkKICAgICAgICAgICAgbWV0YWRhdGFba2V5XSA9IGxpbmUKICAgICAgICAg ICAgbGluZSA9IGYucmVhZGxpbmUoKQogICAgcmV0dXJuIG1ldGFkYXRhCgpzY2FuID0gaW5fZGF0 YQpwcmludCgidHJlYXQiLCBpbl9kYXRhKQoKaWYgaXNpbnN0YW5jZShzY2FuLCBFREZUb21vU2Nh bik6CiAgICAjIGNvcHkgdGhlIC5pbmZvIGZpbGUKICAgIGluZm9fZmlsZSA9IHNjYW4uZ2V0X2lu Zm9fZmlsZShzY2FuLnBhdGgpCiAgICBwcmludChmIlxuXG5UcnlpbmcgdG8gcmVhZCBpbmZvX2Zp bGU6IHtpbmZvX2ZpbGV9IikKICAgICNpbmZvX2ZpbGUgPSBpbmZvX2ZpbGVbNzpdCiAgICBwcmlu dChmIlxuRm9yY2UgdG8gcmVhZCAqdGhpcyogaW5mb19maWxlOiB7aW5mb19maWxlfSIpCiAgICBw cmludChmIlxuSW5pdGlhbCBkaXN0YW5jZSBpbiBpbnB1dCBmaWxlOiBcdHtnZXRfcmF3X2RpY3Qo aW5mb19maWxlKVsnRGlzdGFuY2UnXX0iKQogICAgcmF3X2luZm9fZmlsZSA9IGluZm9fZmlsZVs6 LTVdICsgIl9yYXcuaW5mbyIKICAgIGlmIG5vdCBvcy5wYXRoLmV4aXN0cyhyYXdfaW5mb19maWxl KToKICAgICAgICAjIGNvcHkgdGhlIG9yaWdpbmFsIGZpbGUgb25seSB0aGUgZmlyc3QgdGltZS4g T3RoZXJ3aXNlIHdlIHdpbGwgb3ZlcndyaXRlIHdpdGggYW4gdXBkYXRlZCBmaWxlLgogICAgICAg IHNodXRpbC5jb3B5ZmlsZSgKICAgICAgICAgICAgaW5mb19maWxlLAogICAgICAgICAgICByYXdf aW5mb19maWxlLAogICAgICAgICkKICAgIG1ldGFkYXRhID0gZ2V0X3Jhd19kaWN0KGluZm9fZmls ZSkKICAgICMgb3ZlcndyaXRlIGRpc3RhbmNlIGtleQogICAgbmV3X2Rpc3RhbmNlID0gMC4xMzIx MzY5NyoxMDAwICMgMjgwbm0gcGNvMQogICAgI25ld19kaXN0YW5jZSA9IDAuMTM5OSAqMTAwMCAj IDI4MG5tIHBjbzIKICAgICNuZXdfZGlzdGFuY2UgPSAwLjEyODczNjkzICoxMDAwICMgMjVubSBw Y28xCiAgICAjbmV3X2Rpc3RhbmNlID0gIDAuMDUwMDA2MDUgKiAxMDAwICMgNTBubQogICAgbWV0 YWRhdGFbIkRpc3RhbmNlIl0gPSAiRGlzdGFuY2U9IFx0XHQiICsgc3RyKG5ld19kaXN0YW5jZSkg KyAiXG4iCiAgICB3aXRoIG9wZW4oaW5mb19maWxlLCBtb2RlPSJ3IikgYXMgZjoKICAgICAgICBm b3IgXywgbGluZSBpbiBtZXRhZGF0YS5pdGVtcygpOgogICAgICAgICAgICBmLndyaXRlKGxpbmUp CiAgICAjIHJlc2V0IGtleSBmb3IgY29oZXJlbmNlCiAgICBzY2FuLl9kaXN0YW5jZSA9IE5vbmUK b3V0X2RhdGEgPSBzY2FulIwFZmxhZ3OUSwCMCGZpbGVuYW1llE51YmGME3NhdmVkV2lkZ2V0R2Vv bWV0cnmUQ0IB2dDLAAMAAAAAAfoAAAJ5AAAHgQAABpsAAAH6AAACngAAB4EAAAabAAAAAAAAAAAK AAAAAfoAAAKeAAAHgQAABpuUjApzY3JpcHRUZXh0lFjoBgAAaW1wb3J0IHNodXRpbAppbXBvcnQg b3MKZnJvbSB0b213ZXIuY29yZS5zY2FuLmVkZnNjYW4gaW1wb3J0IEVERlRvbW9TY2FuCmZyb20g c2lseC5pby5kaWN0ZHVtcCBpbXBvcnQgZGljdHRvaW5pLCBsb2FkIGFzIGxvYWRfaW5pCgpkZWYg Z2V0X2tleShsaW5lKToKICAgICIiIiJyZXR1cm4ga2V5IG5hbWUgb2YgYSAuaW5mbyBmaWxlIiIi CiAgICByZXR1cm4gbGluZS5zcGxpdCgiPSIpWzBdLnJlcGxhY2UoIiAiLCAiIikKCgpkZWYgZ2V0 X3Jhd19kaWN0KGZpbGVfcGF0aCk6CiAgICAiIiJyZXR1cm4gdGhlIGluZm8gZmlsZSBtZXRhZGF0 YSBhcyBhIGRpY3Rpb25hcnkgd2l0aCBtZXRhZGF0YSBuYW1lIGFzIGtleSBhbmQgcmF3IGxpbmUg YXMgdmFsdWUiIiIKICAgIG1ldGFkYXRhID0ge30KICAgIHdpdGggb3BlbihmaWxlX3BhdGgsIG1v ZGU9InIiKSBhcyBmOgogICAgICAgIGxpbmUgPSBmLnJlYWRsaW5lKCkKICAgICAgICB3aGlsZSBs aW5lOgogICAgICAgICAgICBrZXkgPSBnZXRfa2V5KGxpbmUpCiAgICAgICAgICAgIG1ldGFkYXRh W2tleV0gPSBsaW5lCiAgICAgICAgICAgIGxpbmUgPSBmLnJlYWRsaW5lKCkKICAgIHJldHVybiBt ZXRhZGF0YQoKc2NhbiA9IGluX2RhdGEKcHJpbnQoInRyZWF0IiwgaW5fZGF0YSkKCmlmIGlzaW5z dGFuY2Uoc2NhbiwgRURGVG9tb1NjYW4pOgogICAgIyBjb3B5IHRoZSAuaW5mbyBmaWxlCiAgICBp bmZvX2ZpbGUgPSBzY2FuLmdldF9pbmZvX2ZpbGUoc2Nhbi5wYXRoKQogICAgcHJpbnQoZiJcblxu VHJ5aW5nIHRvIHJlYWQgaW5mb19maWxlOiB7aW5mb19maWxlfSIpCiAgICAjaW5mb19maWxlID0g aW5mb19maWxlWzc6XQogICAgcHJpbnQoZiJcbkZvcmNlIHRvIHJlYWQgKnRoaXMqIGluZm9fZmls ZToge2luZm9fZmlsZX0iKQogICAgcHJpbnQoZiJcbkluaXRpYWwgZGlzdGFuY2UgaW4gaW5wdXQg ZmlsZTogXHR7Z2V0X3Jhd19kaWN0KGluZm9fZmlsZSlbJ0Rpc3RhbmNlJ119IikKICAgIHJhd19p bmZvX2ZpbGUgPSBpbmZvX2ZpbGVbOi01XSArICJfcmF3LmluZm8iCiAgICBpZiBub3Qgb3MucGF0 aC5leGlzdHMocmF3X2luZm9fZmlsZSk6CiAgICAgICAgIyBjb3B5IHRoZSBvcmlnaW5hbCBmaWxl IG9ubHkgdGhlIGZpcnN0IHRpbWUuIE90aGVyd2lzZSB3ZSB3aWxsIG92ZXJ3cml0ZSB3aXRoIGFu IHVwZGF0ZWQgZmlsZS4KICAgICAgICBzaHV0aWwuY29weWZpbGUoCiAgICAgICAgICAgIGluZm9f ZmlsZSwKICAgICAgICAgICAgcmF3X2luZm9fZmlsZSwKICAgICAgICApCiAgICBtZXRhZGF0YSA9 IGdldF9yYXdfZGljdChpbmZvX2ZpbGUpCiAgICAjIG92ZXJ3cml0ZSBkaXN0YW5jZSBrZXkKICAg IG5ld19kaXN0YW5jZSA9IDAuMTMyMTM2OTcqMTAwMCAjIDI4MG5tIHBjbzEKICAgICNuZXdfZGlz dGFuY2UgPSAwLjEzOTkgKjEwMDAgIyAyODBubSBwY28yCiAgICAjbmV3X2Rpc3RhbmNlID0gMC4x Mjg3MzY5MyAqMTAwMCAjIDI1bm0gcGNvMQogICAgI25ld19kaXN0YW5jZSA9ICAwLjA1MDAwNjA1 ICogMTAwMCAjIDUwbm0KICAgIG1ldGFkYXRhWyJEaXN0YW5jZSJdID0gIkRpc3RhbmNlPSBcdFx0 IiArIHN0cihuZXdfZGlzdGFuY2UpICsgIlxuIgogICAgd2l0aCBvcGVuKGluZm9fZmlsZSwgbW9k ZT0idyIpIGFzIGY6CiAgICAgICAgZm9yIF8sIGxpbmUgaW4gbWV0YWRhdGEuaXRlbXMoKToKICAg ICAgICAgICAgZi53cml0ZShsaW5lKQogICAgIyByZXNldCBrZXkgZm9yIGNvaGVyZW5jZQogICAg c2Nhbi5fZGlzdGFuY2UgPSBOb25lCm91dF9kYXRhID0gc2NhbpSMDXNwbGl0dGVyU3RhdGWUTowL X192ZXJzaW9uX1+USwF1Lg== gASVyw4AAAAAAAB9lCiMEmNvbnRyb2xBcmVhVmlzaWJsZZSIjBJjdXJyZW50U2NyaXB0SW5kZXiU SwCMEWxpYnJhcnlMaXN0U291cmNllF2UjDFvcmFuZ2Vjb250cmliLnRvbXdlci53aWRnZXRzLm90 aGVyLlB5dGhvblNjcmlwdE9XlIwGU2NyaXB0lJOUKYGUfZQojARuYW1llIwLSGVsbG8gd29ybGSU jAZzY3JpcHSUWLkGAABpbXBvcnQgb3MKaW1wb3J0IG51bXB5CmZyb20gdG9tb3NjYW4uZmFjdG9y eSBpbXBvcnQgRmFjdG9yeQpmcm9tIG5hYnUubWlzYy51dGlscyBpbXBvcnQgcmVzY2FsZV9kYXRh CgppZiBpbl9kYXRhIGlzIG5vdCBOb25lOgogICAgc2NhbiA9IGluX2RhdGEKICAgIAogICAgIyB3 YXJuaW5nOiBzY2FuLmxhdGVzdF9yZWNvbnN0cnVjdGlvbnMgaXMgZGVmaW5lZCBieSB0aGUgJ25h YnUgc2xpY2UgcmVjb25zdHJ1Y3Rpb24nLiBTbyBpZiBhIHNjYW4gaXMgbG9hZGVkIGFuZCBub3Qg Z28gdHJob3VnaCB0aGlzIHdpZGdldAogICAgIyBoZSB3b24ndCBiZSBhd2FyZSBhYm91dCBzbGlj ZSByZWNvbnN0cnVjdGlvbnMKICAgIHByaW50KCJjaGVjayIsIHNjYW4sICIgLSBsYXRlc3RfcmVj b25zdHJ1Y3Rpb25zIiwgc2Nhbi5sYXRlc3RfcmVjb25zdHJ1Y3Rpb25zKQogICAgaW5fdm9sdW1l cyA9IFsKICAgICAgICBGYWN0b3J5LmNyZWF0ZV90b21vX29iamVjdF9mcm9tX2lkZW50aWZpZXIo aWRlbnRpZmllcikgZm9yIGlkZW50aWZpZXIgaW4gc2Nhbi5sYXRlc3RfcmVjb25zdHJ1Y3Rpb25z CiAgICBdCgogICAgIyBsb29rcyBsaWtlIHRoZXJlIGlzIHNvbWUgZXh0cmEgdm9sdW1lIGV4aXN0 aW5nOiBmaWx0ZXIgdGhlbQogICAgcmVzID0gW10KICAgIGZvciB2b2wgaW4gaW5fdm9sdW1lczoK ICAgICAgICBpZiBvcy5wYXRoLmV4aXN0cyh2b2wuZmlsZV9wYXRoKToKICAgICAgICAgICAgcmVz LmFwcGVuZCh2b2wpCiAgICAKICAgIGluX3ZvbHVtZXMgPSByZXMKICAgIHByaW50KCJzbGljZXMg dG8gYmUgaGFuZGxlZCIsIGluX3ZvbHVtZXMpCgogICAgW3ByaW50KHZvbC5nZXRfaWRlbnRpZmll cigpLnRvX3N0cigpKSBmb3Igdm9sIGluIGluX3ZvbHVtZXNdCiAgICAKICAgICMgcmV0cmlldmUg dGhlIG1pbiAvIG1heCBmcm9tIHRoZSBmaXJzdCBhY3F1aXNpdGlvbgogICAgaWYgc2Nhbi5wYXRo LmVuZHN3aXRoKCJfMV8iKToKICAgICAgICBmb3Igdm9sIGluIGluX3ZvbHVtZXM6CiAgICAgICAg ICAgIHByaW50KCJyZWNvbXB1dGUgbWluIGFuZCBtYXggZnJvbSIsIHZvbC5maWxlX3BhdGgpCiAg ICAgICAgICAgIGRhdGEgPSB2b2wubG9hZF9kYXRhKCkKICAgICAgICAgICAgbmV3X21pbiwgbmV3 X21heCA9IG51bXB5LnBlcmNlbnRpbGUoZGF0YVswXSwgKDUsIDk1KSkKCiAgICAjIGFwcGx5IGNh c3QgLyByZWNsYW1pbmcgZGF0YQogICAgaWYgIm5ld19taW4iIGluIGdsb2JhbHMoKSBhbmQgIm5l d19tYXgiIGluIGdsb2JhbHMoKToKICAgICAgICBmb3Igdm9sIGluIGluX3ZvbHVtZXM6CiAgICAg ICAgICAgIHByaW50KCJub3JtYWxpemUiLCB2b2wuZmlsZV9wYXRoKQogICAgICAgICAgICB2b2wu bG9hZF9kYXRhKCkKICAgICAgICAgICAgZGF0YSA9IHZvbC5kYXRhCiAgICAgICAgICAgIGRhdGEg PSByZXNjYWxlX2RhdGEoCiAgICAgICAgICAgICAgICBkYXRhPWRhdGEsCiAgICAgICAgICAgICAg ICBuZXdfbWluPW5ld19taW4sCiAgICAgICAgICAgICAgICBuZXdfbWF4PW5ld19tYXgsCiAgICAg ICAgICAgICAgICBkYXRhX21pbj1kYXRhLm1pbigpLAogICAgICAgICAgICAgICAgZGF0YV9tYXg9 ZGF0YS5tYXgoKSwKICAgICAgICAgICAgKQogICAgICAgICAgICB2b2wuZGF0YSA9IGRhdGEKICAg ICAgICAgICAgdm9sLnNhdmVfZGF0YSgpCiAgICAgICAgCiAgICBvdXRfZGF0YSA9IHNjYW4KZWxz ZToKICAgIG91dF9kYXRhID0gaW5fZGF0YZSMBWZsYWdzlEsAjAhmaWxlbmFtZZROdWJhjBNzYXZl ZFdpZGdldEdlb21ldHJ5lENCAdnQywADAAAAAAHKAAAA5wAACf8AAAWfAAABygAAAOcAAAn/AAAF nwAAAAAAAAAACgAAAAHKAAAA5wAACf8AAAWflIwKc2NyaXB0VGV4dJRYuQYAAGltcG9ydCBvcwpp bXBvcnQgbnVtcHkKZnJvbSB0b21vc2Nhbi5mYWN0b3J5IGltcG9ydCBGYWN0b3J5CmZyb20gbmFi dS5taXNjLnV0aWxzIGltcG9ydCByZXNjYWxlX2RhdGEKCmlmIGluX2RhdGEgaXMgbm90IE5vbmU6 CiAgICBzY2FuID0gaW5fZGF0YQogICAgCiAgICAjIHdhcm5pbmc6IHNjYW4ubGF0ZXN0X3JlY29u c3RydWN0aW9ucyBpcyBkZWZpbmVkIGJ5IHRoZSAnbmFidSBzbGljZSByZWNvbnN0cnVjdGlvbicu IFNvIGlmIGEgc2NhbiBpcyBsb2FkZWQgYW5kIG5vdCBnbyB0cmhvdWdoIHRoaXMgd2lkZ2V0CiAg ICAjIGhlIHdvbid0IGJlIGF3YXJlIGFib3V0IHNsaWNlIHJlY29uc3RydWN0aW9ucwogICAgcHJp bnQoImNoZWNrIiwgc2NhbiwgIiAtIGxhdGVzdF9yZWNvbnN0cnVjdGlvbnMiLCBzY2FuLmxhdGVz dF9yZWNvbnN0cnVjdGlvbnMpCiAgICBpbl92b2x1bWVzID0gWwogICAgICAgIEZhY3RvcnkuY3Jl YXRlX3RvbW9fb2JqZWN0X2Zyb21faWRlbnRpZmllcihpZGVudGlmaWVyKSBmb3IgaWRlbnRpZmll ciBpbiBzY2FuLmxhdGVzdF9yZWNvbnN0cnVjdGlvbnMKICAgIF0KCiAgICAjIGxvb2tzIGxpa2Ug dGhlcmUgaXMgc29tZSBleHRyYSB2b2x1bWUgZXhpc3Rpbmc6IGZpbHRlciB0aGVtCiAgICByZXMg PSBbXQogICAgZm9yIHZvbCBpbiBpbl92b2x1bWVzOgogICAgICAgIGlmIG9zLnBhdGguZXhpc3Rz KHZvbC5maWxlX3BhdGgpOgogICAgICAgICAgICByZXMuYXBwZW5kKHZvbCkKICAgIAogICAgaW5f dm9sdW1lcyA9IHJlcwogICAgcHJpbnQoInNsaWNlcyB0byBiZSBoYW5kbGVkIiwgaW5fdm9sdW1l cykKCiAgICBbcHJpbnQodm9sLmdldF9pZGVudGlmaWVyKCkudG9fc3RyKCkpIGZvciB2b2wgaW4g aW5fdm9sdW1lc10KICAgIAogICAgIyByZXRyaWV2ZSB0aGUgbWluIC8gbWF4IGZyb20gdGhlIGZp cnN0IGFjcXVpc2l0aW9uCiAgICBpZiBzY2FuLnBhdGguZW5kc3dpdGgoIl8xXyIpOgogICAgICAg IGZvciB2b2wgaW4gaW5fdm9sdW1lczoKICAgICAgICAgICAgcHJpbnQoInJlY29tcHV0ZSBtaW4g YW5kIG1heCBmcm9tIiwgdm9sLmZpbGVfcGF0aCkKICAgICAgICAgICAgZGF0YSA9IHZvbC5sb2Fk X2RhdGEoKQogICAgICAgICAgICBuZXdfbWluLCBuZXdfbWF4ID0gbnVtcHkucGVyY2VudGlsZShk YXRhWzBdLCAoNSwgOTUpKQoKICAgICMgYXBwbHkgY2FzdCAvIHJlY2xhbWluZyBkYXRhCiAgICBp ZiAibmV3X21pbiIgaW4gZ2xvYmFscygpIGFuZCAibmV3X21heCIgaW4gZ2xvYmFscygpOgogICAg ICAgIGZvciB2b2wgaW4gaW5fdm9sdW1lczoKICAgICAgICAgICAgcHJpbnQoIm5vcm1hbGl6ZSIs IHZvbC5maWxlX3BhdGgpCiAgICAgICAgICAgIHZvbC5sb2FkX2RhdGEoKQogICAgICAgICAgICBk YXRhID0gdm9sLmRhdGEKICAgICAgICAgICAgZGF0YSA9IHJlc2NhbGVfZGF0YSgKICAgICAgICAg ICAgICAgIGRhdGE9ZGF0YSwKICAgICAgICAgICAgICAgIG5ld19taW49bmV3X21pbiwKICAgICAg ICAgICAgICAgIG5ld19tYXg9bmV3X21heCwKICAgICAgICAgICAgICAgIGRhdGFfbWluPWRhdGEu bWluKCksCiAgICAgICAgICAgICAgICBkYXRhX21heD1kYXRhLm1heCgpLAogICAgICAgICAgICAp CiAgICAgICAgICAgIHZvbC5kYXRhID0gZGF0YQogICAgICAgICAgICB2b2wuc2F2ZV9kYXRhKCkK ICAgICAgICAKICAgIG91dF9kYXRhID0gc2NhbgplbHNlOgogICAgb3V0X2RhdGEgPSBpbl9kYXRh lIwNc3BsaXR0ZXJTdGF0ZZROjAtfX3ZlcnNpb25fX5RLAXUu {'controlAreaVisible': True, 'dest_dir_settings': None, 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\x04>\x00\x00\x02h\x00\x00\x05\xad\x00\x00\x02\xe8\x00\x00\x04>\x00\x00\x02h\x00\x00\x05\xad\x00\x00\x02\xe8\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x04>\x00\x00\x02h\x00\x00\x05\xad\x00\x00\x02\xe8', '__version__': 1} gASVPgEAAAAAAAB9lCiMDl92aWV3ZXJfY29uZmlnlH2UKIwEbW9kZZSMI3RvbXdlci5ndWkudmlz dWFsaXphdGlvbi5kYXRhdmlld2VylIwMX0Rpc3BsYXlNb2RllJOUjAZzbGljZXOUhZRSlIwJc2xp Y2Vfb3B0lGgEjApfU2xpY2VNb2RllJOUjAZsYXRlc3SUhZRSlIwJcmFkaW9fb3B0lGgEjApfUmFk aW9Nb2RllJOUjApub3JtYWxpemVklIWUUpR1jBJjb250cm9sQXJlYVZpc2libGWUiIwTc2F2ZWRX aWRnZXRHZW9tZXRyeZRDQgHZ0MsAAwAAAAABBgAAAJgAAAhPAAAEugAAAQYAAAC9AAAITwAABLoA AAAAAAAAAAoAAAABBgAAAL0AAAhPAAAEupSMC19fdmVyc2lvbl9flEsBdS4= gASV8hAAAAAAAAB9lCiMEmNvbnRyb2xBcmVhVmlzaWJsZZSIjBJjdXJyZW50U2NyaXB0SW5kZXiU SwCMEWxpYnJhcnlMaXN0U291cmNllF2UjDFvcmFuZ2Vjb250cmliLnRvbXdlci53aWRnZXRzLm90 aGVyLlB5dGhvblNjcmlwdE9XlIwGU2NyaXB0lJOUKYGUfZQojARuYW1llIwLSGVsbG8gd29ybGSU jAZzY3JpcHSUWLwHAABmcm9tIHRvbXdlci5jb3JlLnNjYW4uZWRmc2NhbiBpbXBvcnQgRURGVG9t b1NjYW4KaW1wb3J0IG9zCmltcG9ydCBzaHV0aWwKaW1wb3J0IHNpbHguaW8KCmRlZiBnZXRfa2V5 KGxpbmUpOgogICAgIiIiInJldHVybiBrZXkgbmFtZSBvZiBhIC5pbmZvIGZpbGUiIiIKICAgIHJl dHVybiBsaW5lLnNwbGl0KCI9IilbMF0ucmVwbGFjZSgiICIsICIiKQoKZGVmIGdldF9yYXdfZGlj dChmaWxlX3BhdGgpOgogICAgIiIicmV0dXJuIHRoZSBpbmZvIGZpbGUgbWV0YWRhdGEgYXMgYSBk aWN0aW9uYXJ5IHdpdGggbWV0YWRhdGEgbmFtZSBhcyBrZXkgYW5kIHJhdyBsaW5lIGFzIHZhbHVl IiIiCiAgICBtZXRhZGF0YSA9IHt9CiAgICB3aXRoIG9wZW4oZmlsZV9wYXRoLCBtb2RlPSJyIikg YXMgZjoKICAgICAgICBsaW5lID0gZi5yZWFkbGluZSgpCiAgICAgICAgd2hpbGUgbGluZToKICAg ICAgICAgICAga2V5ID0gZ2V0X2tleShsaW5lKQogICAgICAgICAgICBtZXRhZGF0YVtrZXldID0g bGluZQogICAgICAgICAgICBsaW5lID0gZi5yZWFkbGluZSgpCiAgICByZXR1cm4gbWV0YWRhdGEK CiMgUmVhZCB0aGUgZGF0YQpzY2FuID0gaW5fZGF0YQpwcmludCgiV29ya2luZyBvbjogIiwgaW5f ZGF0YSkKaWYgaXNpbnN0YW5jZShzY2FuLCBFREZUb21vU2Nhbik6CiAgICBpbmZvX2ZpbGUgPSBz Y2FuLmdldF9pbmZvX2ZpbGUoc2Nhbi5wYXRoKQogICAgcHJpbnQoZiJcblJlYWRpbmcgKnRoaXMq IGluZm9fZmlsZToge2luZm9fZmlsZX0iKQogICAgcmF3X2luZm9fZmlsZSA9IGluZm9fZmlsZVs6 LTVdICsgIl9yYXcuaW5mbyIKICAgIGlmIG5vdCBvcy5wYXRoLmV4aXN0cyhyYXdfaW5mb19maWxl KToKICAgICAgICAjIGNvcHkgdGhlIG9yaWdpbmFsIGZpbGUgb25seSB0aGUgZmlyc3QgdGltZS4g T3RoZXJ3aXNlIHdlIHdpbGwgb3ZlcndyaXRlIHdpdGggYW4gdXBkYXRlZCBmaWxlLgogICAgICAg IHNodXRpbC5jb3B5ZmlsZSgKICAgICAgICAgICAgaW5mb19maWxlLAogICAgICAgICAgICByYXdf aW5mb19maWxlLAogICAgICAgICkKICAgIG1ldGFkYXRhID0gZ2V0X3Jhd19kaWN0KGluZm9fZmls ZSkKICAgIAogICAgIyBSZWFkIHRoZSBpbWFnZXMKICAgIGVkZk5hbWUgPSBpbmZvX2ZpbGVbOi01 XSsiMDA1MC5lZGYiCiAgICBlZGYgPSBzaWx4LmlvLm9wZW4oZWRmTmFtZSkKICAgICMgUmVhZCB0 aGUgcGFyYW1ldGVycyBmcm9tIHRoZSBpbWFnZQogICAgY3gxID0gZWRmWyJzY2FuXzAvaW5zdHJ1 bWVudC9wb3NpdGlvbmVycy9jeCJdWzBdICNtbQogICAgc3gxID0gZWRmWyJzY2FuXzAvaW5zdHJ1 bWVudC9wb3NpdGlvbmVycy9zeCJdWzBdICNtbQogICAgcHhfbWFnbmlmaWVkX2VkZiA9IGVkZlsi c2Nhbl8wL2luc3RydW1lbnQvZGV0ZWN0b3JfMC9vdGhlcnMvcGl4ZWxfc2l6ZSJdWzBdIC8gMWU2 CiAgICBweDEgPSBlZGZbInNjYW5fMC9pbnN0cnVtZW50L2RldGVjdG9yXzAvb3RoZXJzL29wdGlj X3VzZWQiXVswXSAvIDFlNgogICAgbWFnID0gcHgxIC8gcHhfbWFnbmlmaWVkX2VkZgogICAgc3gw ID0gc3gxIC0gY3gxIC8gbWFnICMgbW0KICAgIHoxID0gKHN4MSAtIHN4MCkgIyBtbQogICAgejIg PSAoY3gxIC0gc3gxICsgc3gwKSAjIG1tCiAgICBtYWduaWZpY2F0aW9uID0gKHoxICsgejIpIC8g ejEKICAgIGRpc3RhbmNlID0gejIgLyBtYWduaWZpY2F0aW9uICMgbW0KICAgIHByaW50KCJDb21w dXRlZCBkaXN0YW5jZSBpbiBbbW1dOiAiLCBkaXN0YW5jZSkKICAgIG1ldGFkYXRhWyJEaXN0YW5j ZSJdID0gIkRpc3RhbmNlPSBcdFx0ICIgKyBzdHIoZGlzdGFuY2UpICsgIlxuIgoKICAgIHdpdGgg b3BlbihpbmZvX2ZpbGUsIG1vZGU9InciKSBhcyBmOgogICAgICAgIGZvciBfLCBsaW5lIGluIG1l dGFkYXRhLml0ZW1zKCk6CiAgICAgICAgICAgIGYud3JpdGUobGluZSkKICAgICMgcmVzZXQga2V5 IGZvciBjb2hlcmVuY2UKICAgIHNjYW4uX2Rpc3RhbmNlID0gTm9uZQpvdXRfZGF0YSA9IHNjYW6U jAVmbGFnc5RLAIwIZmlsZW5hbWWUTnViYYwTc2F2ZWRXaWRnZXRHZW9tZXRyeZRDQgHZ0MsAAwAA AAAMQAAAATEAABCdAAAEwQAADEAAAAFWAAAQnQAABMEAAAABAAAAAAoAAAAMQAAAAVYAABCdAAAE wZSMCnNjcmlwdFRleHSUWLwHAABmcm9tIHRvbXdlci5jb3JlLnNjYW4uZWRmc2NhbiBpbXBvcnQg RURGVG9tb1NjYW4KaW1wb3J0IG9zCmltcG9ydCBzaHV0aWwKaW1wb3J0IHNpbHguaW8KCmRlZiBn ZXRfa2V5KGxpbmUpOgogICAgIiIiInJldHVybiBrZXkgbmFtZSBvZiBhIC5pbmZvIGZpbGUiIiIK ICAgIHJldHVybiBsaW5lLnNwbGl0KCI9IilbMF0ucmVwbGFjZSgiICIsICIiKQoKZGVmIGdldF9y YXdfZGljdChmaWxlX3BhdGgpOgogICAgIiIicmV0dXJuIHRoZSBpbmZvIGZpbGUgbWV0YWRhdGEg YXMgYSBkaWN0aW9uYXJ5IHdpdGggbWV0YWRhdGEgbmFtZSBhcyBrZXkgYW5kIHJhdyBsaW5lIGFz IHZhbHVlIiIiCiAgICBtZXRhZGF0YSA9IHt9CiAgICB3aXRoIG9wZW4oZmlsZV9wYXRoLCBtb2Rl PSJyIikgYXMgZjoKICAgICAgICBsaW5lID0gZi5yZWFkbGluZSgpCiAgICAgICAgd2hpbGUgbGlu ZToKICAgICAgICAgICAga2V5ID0gZ2V0X2tleShsaW5lKQogICAgICAgICAgICBtZXRhZGF0YVtr ZXldID0gbGluZQogICAgICAgICAgICBsaW5lID0gZi5yZWFkbGluZSgpCiAgICByZXR1cm4gbWV0 YWRhdGEKCiMgUmVhZCB0aGUgZGF0YQpzY2FuID0gaW5fZGF0YQpwcmludCgiV29ya2luZyBvbjog IiwgaW5fZGF0YSkKaWYgaXNpbnN0YW5jZShzY2FuLCBFREZUb21vU2Nhbik6CiAgICBpbmZvX2Zp bGUgPSBzY2FuLmdldF9pbmZvX2ZpbGUoc2Nhbi5wYXRoKQogICAgcHJpbnQoZiJcblJlYWRpbmcg KnRoaXMqIGluZm9fZmlsZToge2luZm9fZmlsZX0iKQogICAgcmF3X2luZm9fZmlsZSA9IGluZm9f ZmlsZVs6LTVdICsgIl9yYXcuaW5mbyIKICAgIGlmIG5vdCBvcy5wYXRoLmV4aXN0cyhyYXdfaW5m b19maWxlKToKICAgICAgICAjIGNvcHkgdGhlIG9yaWdpbmFsIGZpbGUgb25seSB0aGUgZmlyc3Qg dGltZS4gT3RoZXJ3aXNlIHdlIHdpbGwgb3ZlcndyaXRlIHdpdGggYW4gdXBkYXRlZCBmaWxlLgog ICAgICAgIHNodXRpbC5jb3B5ZmlsZSgKICAgICAgICAgICAgaW5mb19maWxlLAogICAgICAgICAg ICByYXdfaW5mb19maWxlLAogICAgICAgICkKICAgIG1ldGFkYXRhID0gZ2V0X3Jhd19kaWN0KGlu Zm9fZmlsZSkKICAgIAogICAgIyBSZWFkIHRoZSBpbWFnZXMKICAgIGVkZk5hbWUgPSBpbmZvX2Zp bGVbOi01XSsiMDA1MC5lZGYiCiAgICBlZGYgPSBzaWx4LmlvLm9wZW4oZWRmTmFtZSkKICAgICMg UmVhZCB0aGUgcGFyYW1ldGVycyBmcm9tIHRoZSBpbWFnZQogICAgY3gxID0gZWRmWyJzY2FuXzAv aW5zdHJ1bWVudC9wb3NpdGlvbmVycy9jeCJdWzBdICNtbQogICAgc3gxID0gZWRmWyJzY2FuXzAv aW5zdHJ1bWVudC9wb3NpdGlvbmVycy9zeCJdWzBdICNtbQogICAgcHhfbWFnbmlmaWVkX2VkZiA9 IGVkZlsic2Nhbl8wL2luc3RydW1lbnQvZGV0ZWN0b3JfMC9vdGhlcnMvcGl4ZWxfc2l6ZSJdWzBd IC8gMWU2CiAgICBweDEgPSBlZGZbInNjYW5fMC9pbnN0cnVtZW50L2RldGVjdG9yXzAvb3RoZXJz L29wdGljX3VzZWQiXVswXSAvIDFlNgogICAgbWFnID0gcHgxIC8gcHhfbWFnbmlmaWVkX2VkZgog ICAgc3gwID0gc3gxIC0gY3gxIC8gbWFnICMgbW0KICAgIHoxID0gKHN4MSAtIHN4MCkgIyBtbQog ICAgejIgPSAoY3gxIC0gc3gxICsgc3gwKSAjIG1tCiAgICBtYWduaWZpY2F0aW9uID0gKHoxICsg ejIpIC8gejEKICAgIGRpc3RhbmNlID0gejIgLyBtYWduaWZpY2F0aW9uICMgbW0KICAgIHByaW50 KCJDb21wdXRlZCBkaXN0YW5jZSBpbiBbbW1dOiAiLCBkaXN0YW5jZSkKICAgIG1ldGFkYXRhWyJE aXN0YW5jZSJdID0gIkRpc3RhbmNlPSBcdFx0ICIgKyBzdHIoZGlzdGFuY2UpICsgIlxuIgoKICAg IHdpdGggb3BlbihpbmZvX2ZpbGUsIG1vZGU9InciKSBhcyBmOgogICAgICAgIGZvciBfLCBsaW5l IGluIG1ldGFkYXRhLml0ZW1zKCk6CiAgICAgICAgICAgIGYud3JpdGUobGluZSkKICAgICMgcmVz ZXQga2V5IGZvciBjb2hlcmVuY2UKICAgIHNjYW4uX2Rpc3RhbmNlID0gTm9uZQpvdXRfZGF0YSA9 IHNjYW6UjA1zcGxpdHRlclN0YXRllEMfAAAA/wAAAAEAAAACAAACdgAAAM8B/////wEAAAACAJSM C19fdmVyc2lvbl9flEsBdS4= {'_scanIDs': [], 'controlAreaVisible': True, 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\x02\xac\x00\x00\x03:\x00\x00\x06\x17\x00\x00\x04\xe8\x00\x00\x02\xac\x00\x00\x03_\x00\x00\x06\x17\x00\x00\x04\xe8\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x02\xac\x00\x00\x03_\x00\x00\x06\x17\x00\x00\x04\xe8', '__version__': 1} {'acquisitionMethod': ('[scan].xml',), 'controlAreaVisible': True, 'folderObserved': '/lbsram/data', 'linuxFilePatternSetting': None, 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\x0c\xf3\x00\x00\x00|\x00\x00\x13\x7f\x00\x00\x02n\x00\x00\x0c\xf3\x00\x00\x00\xa1\x00\x00\x13\x7f\x00\x00\x02n\x00\x00\x00\x01\x00\x00\x00\x00\n\x00\x00\x00\x0c\xf3\x00\x00\x00\xa1\x00\x00\x13\x7f\x00\x00\x02n', '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'dark_ref_params': {'DOWHEN': 'before', 'DARKCAL': 'mean', 'DARKOVE': 0, 'DARKRMV': 0, 'DKFILE': 'darkend[0-9]{3,4}', 'REFSCAL': 'median', 'REFSOVE': 0, 'REFSRMV': 0, 'RFFILE': 'ref*.*[0-9]{3,4}_[0-9]{3,4}'}}, 'controlAreaVisible': True, 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\x01+\x00\x00\x01\x99\x00\x00\x08\xd4\x00\x00\x04\x06\x00\x00\x01+\x00\x00\x01\x99\x00\x00\x08\xd4\x00\x00\x04\x06\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x01+\x00\x00\x01\x99\x00\x00\x08\xd4\x00\x00\x04\x06', '__version__': 1} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989076.0 tomwer-1.6.17/src/orangecontrib/tomwer/tutorials/id16b/ID16b_normalization.ows0000644000175000017500000005411615153325224026432 0ustar00paynopayno {'acquisitionMethod': ('[scan].xml',), 'controlAreaVisible': True, 'folderObserved': '/lbsram/data/', 'linuxFilePatternSetting': '', 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\x02I\x00\x00\x01h\x00\x00\x056\x00\x00\x03G\x00\x00\x02I\x00\x00\x01h\x00\x00\x056\x00\x00\x03G\x00\x00\x00\x00\x00\x00\x00\x00\x07\x80\x00\x00\x02I\x00\x00\x01h\x00\x00\x056\x00\x00\x03G', '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'dark_ref_params': {'DOWHEN': 'before', 'DARKCAL': 'Average', 'DARKOVE': 1, 'DARKRMV': 0, 'DKFILE': 'darkend[0-9]{3,4}', 'REFSCAL': 'Median', 'REFSOVE': 1, 'REFSRMV': 0, 'RFFILE': 'ref*.*[0-9]{3,4}_[0-9]{3,4}'}}, 'controlAreaVisible': True, 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\x00H\x00\x00\x00\x1b\x00\x00\x03\xef\x00\x00\x02\x1f\x00\x00\x00H\x00\x00\x00@\x00\x00\x03\xef\x00\x00\x02\x1f\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00H\x00\x00\x00@\x00\x00\x03\xef\x00\x00\x02\x1f', '__version__': 1} {'_scanIDs': [], 'controlAreaVisible': True, 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\x02\x80\x00\x00\x01C\x00\x00\x04\xff\x00\x00\x03G\x00\x00\x02\x80\x00\x00\x01h\x00\x00\x04\xff\x00\x00\x03G\x00\x00\x00\x00\x00\x00\x00\x00\x07\x80\x00\x00\x02\x80\x00\x00\x01h\x00\x00\x04\xff\x00\x00\x03G', '__version__': 1} {'_muted': False, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'nabu_params': {'preproc': {'flatfield': 1, 'double_flatfield': 0, 'dff_sigma': 0.0, 'ccd_filter_enabled': 0, 'ccd_filter_threshold': 0.04, 'take_logarithm': True, 'log_min_clip': 1e-06, 'log_max_clip': 10.0, 'sino_rings_correction': 'None', 'sino_rings_options': 'sigma=1.0 ; levels=10', 'tilt_correction': '', 'autotilt_options': ''}, 'reconstruction': {'method': 'FBP', 'angles_file': '', 'axis_correction_file': '', 'angle_offset': 0.0, 'fbp_filter_type': 'ramlak', 'padding_type': 'edges', 'iterations': 200, 'optim_algorithm': 'chambolle-pock', 'regularization_weight': 0.01, 'preconditioning_filter': 1, 'positivity_constraint': 1, 'rotation_axis_position': '', 'translation_movements_file': '', 'clip_outer_circle': 1, 'start_x': 0, 'end_x': -1, 'start_y': 0, 'end_y': -1, 'start_z': 0, 'end_z': -1, 'enable_halftomo': 0}, 'dataset': {'binning': 1, 'binning_z': 1, 'projections_subsampling': 1}, 'tomwer_slices': 'middle', 'output': {'file_format': 'vol', 'location': ''}, 'phase': {'method': 'Paganin', 'delta_beta': '500', 'padding_type': 'edge', 'unsharp_coeff': 3.0, 'unsharp_sigma': 0.65}, 'configuration_level': 'optional', 'mode_locked': False, 'cluster_config': None}}, 'controlAreaVisible': True, 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\x00H\x00\x00\x00@\x00\x00\x05\xd1\x00\x00\x03\x9e\x00\x00\x00H\x00\x00\x00@\x00\x00\x05\xd1\x00\x00\x03\x9e\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00H\x00\x00\x00@\x00\x00\x05\xd1\x00\x00\x03\x9e', '__version__': 1} gASVWQEAAAAAAAB9lCiMDl92aWV3ZXJfY29uZmlnlH2UKIwEbW9kZZSMCGJ1aWx0aW5zlIwHZ2V0 YXR0cpSTlIwjdG9td2VyLmd1aS52aXN1YWxpemF0aW9uLmRhdGF2aWV3ZXKUjAxfRGlzcGxheU1v ZGWUk5SMBlNMSUNFU5SGlFKUjAlzbGljZV9vcHSUaAZoB4wKX1NsaWNlTW9kZZSTlIwGTEFURVNU lIaUUpSMCXJhZGlvX29wdJRoBmgHjApfUmFkaW9Nb2RllJOUjApOT1JNQUxJWkVElIaUUpR1jBJj b250cm9sQXJlYVZpc2libGWUiIwTc2F2ZWRXaWRnZXRHZW9tZXRyeZRDQgHZ0MsAAwAAAAAASAAA AIIAAAeRAAAEpAAAAEgAAACnAAAHkQAABKQAAAAAAAAAAAoAAAAASAAAAKcAAAeRAAAEpJSMC19f dmVyc2lvbl9flEsBdS4= {'_ewoks_default_inputs': {'data': None, 'axis_params': {'MODE': 'centered', 'POSITION_VALUE': -11.37684057962989, 'CALC_INPUT_TYPE': 'transmission_nopag', 'ANGLE_MODE': '0-180', 'USE_SINOGRAM': False, 'SINOGRAM_LINE': '', 'SINOGRAM_SUBSAMPLING': 10, 'AXIS_URL_1': '', 'AXIS_URL_2': '', 'LOOK_AT_STDMAX': False, 'NEAR_WX': 10, 'FINE_STEP_X': 0.1, 'SCALE_IMG2_TO_IMG1': False, 'NEAR_POSITION': 0.0, 'PADDING_MODE': 'edge', 'FLIP_LR': True, 'COMPOSITE_OPTS': {'theta': 10, 'oversampling': 4, 'n_subsampling_y': 10, 'take_log': True, 'near_pos': 0.0, 'near_width': 20}, 'SIDE': 'left', 'COR_OPTIONS': ''}, 'gui': {'mode_is_lock': True, 'value_is_lock': False, 'auto_update_estimated_cor': True}}, 'controlAreaVisible': True, 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\x00H\x00\x00\x00\x1b\x00\x00\x05]\x00\x00\x03\x17\x00\x00\x00H\x00\x00\x00@\x00\x00\x05]\x00\x00\x03\x17\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x00H\x00\x00\x00@\x00\x00\x05]\x00\x00\x03\x17', '__version__': 1} gASVwwUAAAAAAAB9lCiMEmNvbnRyb2xBcmVhVmlzaWJsZZSIjBJjdXJyZW50U2NyaXB0SW5kZXiU SwCMEWxpYnJhcnlMaXN0U291cmNllF2UjDFvcmFuZ2Vjb250cmliLnRvbXdlci53aWRnZXRzLm90 aGVyLlB5dGhvblNjcmlwdE9XlIwGU2NyaXB0lJOUKYGUfZQojARuYW1llIwLSGVsbG8gd29ybGSU jAZzY3JpcHSUWDUCAABpbXBvcnQgb3MKc2NhbiA9IGluX2RhdGEKCnZvbF9mbG9hdF9wYXRoID0g b3MucGF0aC5qb2luKAogICAgb3MucGF0aC5kaXJuYW1lKHNjYW4ucGF0aCksCiAgICAiLnZvbGZs b2F0X25vYmFja3VwIiwKKQoKdm9sX2Zsb2F0X3N5bV9saW5rX3BhdGggPSBvcy5wYXRoLmpvaW4o CiAgICBvcy5wYXRoLmRpcm5hbWUoc2Nhbi5wYXRoKSwKICAgICJ2b2xmbG9hdCIsCikKCmlmIG5v dCBvcy5wYXRoLmV4aXN0cyh2b2xfZmxvYXRfcGF0aCk6CiAgICBwcmludChmImNyZWF0ZXMge3Zv bF9mbG9hdF9wYXRofSIpCiAgICBvcy5tYWtlZGlycyh2b2xfZmxvYXRfcGF0aCwgbW9kZT0wbzc3 NCkKICAgICMgZG9uJ3Qga25vdyB3aHkgYnV0IGZpcnN0IGNyZWF0aW9uIHdpdGggMG83NzQgZmFp bHMuLi4KICAgIG9zLmNobW9kKHZvbF9mbG9hdF9wYXRoLCAwbzc3NCkKICAgIAogICAgIyBjcmVh dGUgc3ltbGluayBmcm9tIHZvbGZsb2F0IHRvICIudm9sZmxvYXRfbm9iYWNrdXAiCiAgICBvcy5z eW1saW5rKHZvbF9mbG9hdF9wYXRoLCB2b2xfZmxvYXRfc3ltX2xpbmtfcGF0aCkKCgpvdXRfZGF0 YSA9IHNjYW4KlIwFZmxhZ3OUSwCMCGZpbGVuYW1llE51YmGME3NhdmVkV2lkZ2V0R2VvbWV0cnmU Q0IB2dDLAAMAAAAAAEgAAAAbAAAGBwAAA3YAAABIAAAAQAAABgcAAAN2AAAAAAAAAAAKAAAAAEgA AABAAAAGBwAAA3aUjApzY3JpcHRUZXh0lFg1AgAAaW1wb3J0IG9zCnNjYW4gPSBpbl9kYXRhCgp2 b2xfZmxvYXRfcGF0aCA9IG9zLnBhdGguam9pbigKICAgIG9zLnBhdGguZGlybmFtZShzY2FuLnBh dGgpLAogICAgIi52b2xmbG9hdF9ub2JhY2t1cCIsCikKCnZvbF9mbG9hdF9zeW1fbGlua19wYXRo ID0gb3MucGF0aC5qb2luKAogICAgb3MucGF0aC5kaXJuYW1lKHNjYW4ucGF0aCksCiAgICAidm9s ZmxvYXQiLAopCgppZiBub3Qgb3MucGF0aC5leGlzdHModm9sX2Zsb2F0X3BhdGgpOgogICAgcHJp bnQoZiJjcmVhdGVzIHt2b2xfZmxvYXRfcGF0aH0iKQogICAgb3MubWFrZWRpcnModm9sX2Zsb2F0 X3BhdGgsIG1vZGU9MG83NzQpCiAgICAjIGRvbid0IGtub3cgd2h5IGJ1dCBmaXJzdCBjcmVhdGlv biB3aXRoIDBvNzc0IGZhaWxzLi4uCiAgICBvcy5jaG1vZCh2b2xfZmxvYXRfcGF0aCwgMG83NzQp CiAgICAKICAgICMgY3JlYXRlIHN5bWxpbmsgZnJvbSB2b2xmbG9hdCB0byAiLnZvbGZsb2F0X25v YmFja3VwIgogICAgb3Muc3ltbGluayh2b2xfZmxvYXRfcGF0aCwgdm9sX2Zsb2F0X3N5bV9saW5r X3BhdGgpCgoKb3V0X2RhdGEgPSBzY2FuCpSMDXNwbGl0dGVyU3RhdGWUTowLX192ZXJzaW9uX1+U SwF1Lg== gASVMw8AAAAAAAB9lCiMEmNvbnRyb2xBcmVhVmlzaWJsZZSIjBJjdXJyZW50U2NyaXB0SW5kZXiU SwCMEWxpYnJhcnlMaXN0U291cmNllF2UjDFvcmFuZ2Vjb250cmliLnRvbXdlci53aWRnZXRzLm90 aGVyLlB5dGhvblNjcmlwdE9XlIwGU2NyaXB0lJOUKYGUfZQojARuYW1llIwLSGVsbG8gd29ybGSU jAZzY3JpcHSUWO0GAABpbXBvcnQgc2h1dGlsCmltcG9ydCBvcwpmcm9tIHRvbXdlci5jb3JlLnNj YW4uZWRmc2NhbiBpbXBvcnQgRURGVG9tb1NjYW4KZnJvbSBzaWx4LmlvLmRpY3RkdW1wIGltcG9y dCBkaWN0dG9pbmksIGxvYWQgYXMgbG9hZF9pbmkKCmRlZiBnZXRfa2V5KGxpbmUpOgogICAgIiIi InJldHVybiBrZXkgbmFtZSBvZiBhIC5pbmZvIGZpbGUiIiIKICAgIHJldHVybiBsaW5lLnNwbGl0 KCI9IilbMF0ucmVwbGFjZSgiICIsICIiKQoKCmRlZiBnZXRfcmF3X2RpY3QoZmlsZV9wYXRoKToK ICAgICIiInJldHVybiB0aGUgaW5mbyBmaWxlIG1ldGFkYXRhIGFzIGEgZGljdGlvbmFyeSB3aXRo IG1ldGFkYXRhIG5hbWUgYXMga2V5IGFuZCByYXcgbGluZSBhcyB2YWx1ZSIiIgogICAgbWV0YWRh dGEgPSB7fQogICAgd2l0aCBvcGVuKGZpbGVfcGF0aCwgbW9kZT0iciIpIGFzIGY6CiAgICAgICAg bGluZSA9IGYucmVhZGxpbmUoKQogICAgICAgIHdoaWxlIGxpbmU6CiAgICAgICAgICAgIGtleSA9 IGdldF9rZXkobGluZSkKICAgICAgICAgICAgbWV0YWRhdGFba2V5XSA9IGxpbmUKICAgICAgICAg ICAgbGluZSA9IGYucmVhZGxpbmUoKQogICAgcmV0dXJuIG1ldGFkYXRhCgpzY2FuID0gaW5fZGF0 YQpwcmludCgidHJlYXQiLCBpbl9kYXRhKQoKaWYgaXNpbnN0YW5jZShzY2FuLCBFREZUb21vU2Nh bik6CiAgICAjIGNvcHkgdGhlIC5pbmZvIGZpbGUKICAgIGluZm9fZmlsZSA9IHNjYW4uZ2V0X2lu Zm9fZmlsZShzY2FuLnBhdGgpCiAgICBwcmludChmIlxuXG5UcnlpbmcgdG8gcmVhZCBpbmZvX2Zp bGU6IHtpbmZvX2ZpbGV9IikKICAgICNpbmZvX2ZpbGUgPSBpbmZvX2ZpbGVbNzpdCiAgICBwcmlu dChmIlxuRm9yY2UgdG8gcmVhZCAqdGhpcyogaW5mb19maWxlOiB7aW5mb19maWxlfSIpCiAgICBw cmludChmIlxuSW5pdGlhbCBkaXN0YW5jZSBpbiBpbnB1dCBmaWxlOiBcdHtnZXRfcmF3X2RpY3Qo aW5mb19maWxlKVsnRGlzdGFuY2UnXX0iKQogICAgcmF3X2luZm9fZmlsZSA9IGluZm9fZmlsZVs6 LTVdICsgIl9yYXcuaW5mbyIKICAgIGlmIG5vdCBvcy5wYXRoLmV4aXN0cyhyYXdfaW5mb19maWxl KToKICAgICAgICAjIGNvcHkgdGhlIG9yaWdpbmFsIGZpbGUgb25seSB0aGUgZmlyc3QgdGltZS4g T3RoZXJ3aXNlIHdlIHdpbGwgb3ZlcndyaXRlIHdpdGggYW4gdXBkYXRlZCBmaWxlLgogICAgICAg IHNodXRpbC5jb3B5ZmlsZSgKICAgICAgICAgICAgaW5mb19maWxlLAogICAgICAgICAgICByYXdf aW5mb19maWxlLAogICAgICAgICkKICAgIG1ldGFkYXRhID0gZ2V0X3Jhd19kaWN0KGluZm9fZmls ZSkKICAgICMgb3ZlcndyaXRlIGRpc3RhbmNlIGtleQogICAgbmV3X2Rpc3RhbmNlID0gMC4xNjg1 ICoxMDAwICMgMjgwbm0KICAgICNuZXdfZGlzdGFuY2UgPSAwLjA5MTcgIzEwMG5tCiAgICAjbmV3 X2Rpc3RhbmNlID0gMC4xMjUgIzE1MG5tCiAgICAjbmV3X2Rpc3RhbmNlID0gIDAuMDUwMDA2MDUg IyAqIDEwMDAgIzUwbm0KICAgICNuZXdfZGlzdGFuY2UgPSAwLjA5OSAqIDEwMDAgIzE1MG5tCiAg ICBtZXRhZGF0YVsiRGlzdGFuY2UiXSA9ICJEaXN0YW5jZT0gXHRcdCIgKyBzdHIobmV3X2Rpc3Rh bmNlKSArICJcbiIKICAgIHdpdGggb3BlbihpbmZvX2ZpbGUsIG1vZGU9InciKSBhcyBmOgogICAg ICAgIGZvciBfLCBsaW5lIGluIG1ldGFkYXRhLml0ZW1zKCk6CiAgICAgICAgICAgIGYud3JpdGUo bGluZSkKICAgICMgcmVzZXQga2V5IGZvciBjb2hlcmVuY2UKICAgIHNjYW4uX2Rpc3RhbmNlID0g Tm9uZQpvdXRfZGF0YSA9IHNjYW6UjAVmbGFnc5RLAIwIZmlsZW5hbWWUTnViYYwTc2F2ZWRXaWRn ZXRHZW9tZXRyeZRDQgHZ0MsAAwAAAAABfwAAAJAAAAjIAAAEsgAAAX8AAAC1AAAIyAAABLIAAAAA AAAAAAoAAAABfwAAALUAAAjIAAAEspSMCnNjcmlwdFRleHSUWO0GAABpbXBvcnQgc2h1dGlsCmlt cG9ydCBvcwpmcm9tIHRvbXdlci5jb3JlLnNjYW4uZWRmc2NhbiBpbXBvcnQgRURGVG9tb1NjYW4K ZnJvbSBzaWx4LmlvLmRpY3RkdW1wIGltcG9ydCBkaWN0dG9pbmksIGxvYWQgYXMgbG9hZF9pbmkK CmRlZiBnZXRfa2V5KGxpbmUpOgogICAgIiIiInJldHVybiBrZXkgbmFtZSBvZiBhIC5pbmZvIGZp bGUiIiIKICAgIHJldHVybiBsaW5lLnNwbGl0KCI9IilbMF0ucmVwbGFjZSgiICIsICIiKQoKCmRl ZiBnZXRfcmF3X2RpY3QoZmlsZV9wYXRoKToKICAgICIiInJldHVybiB0aGUgaW5mbyBmaWxlIG1l dGFkYXRhIGFzIGEgZGljdGlvbmFyeSB3aXRoIG1ldGFkYXRhIG5hbWUgYXMga2V5IGFuZCByYXcg bGluZSBhcyB2YWx1ZSIiIgogICAgbWV0YWRhdGEgPSB7fQogICAgd2l0aCBvcGVuKGZpbGVfcGF0 aCwgbW9kZT0iciIpIGFzIGY6CiAgICAgICAgbGluZSA9IGYucmVhZGxpbmUoKQogICAgICAgIHdo aWxlIGxpbmU6CiAgICAgICAgICAgIGtleSA9IGdldF9rZXkobGluZSkKICAgICAgICAgICAgbWV0 YWRhdGFba2V5XSA9IGxpbmUKICAgICAgICAgICAgbGluZSA9IGYucmVhZGxpbmUoKQogICAgcmV0 dXJuIG1ldGFkYXRhCgpzY2FuID0gaW5fZGF0YQpwcmludCgidHJlYXQiLCBpbl9kYXRhKQoKaWYg aXNpbnN0YW5jZShzY2FuLCBFREZUb21vU2Nhbik6CiAgICAjIGNvcHkgdGhlIC5pbmZvIGZpbGUK ICAgIGluZm9fZmlsZSA9IHNjYW4uZ2V0X2luZm9fZmlsZShzY2FuLnBhdGgpCiAgICBwcmludChm IlxuXG5UcnlpbmcgdG8gcmVhZCBpbmZvX2ZpbGU6IHtpbmZvX2ZpbGV9IikKICAgICNpbmZvX2Zp bGUgPSBpbmZvX2ZpbGVbNzpdCiAgICBwcmludChmIlxuRm9yY2UgdG8gcmVhZCAqdGhpcyogaW5m b19maWxlOiB7aW5mb19maWxlfSIpCiAgICBwcmludChmIlxuSW5pdGlhbCBkaXN0YW5jZSBpbiBp bnB1dCBmaWxlOiBcdHtnZXRfcmF3X2RpY3QoaW5mb19maWxlKVsnRGlzdGFuY2UnXX0iKQogICAg cmF3X2luZm9fZmlsZSA9IGluZm9fZmlsZVs6LTVdICsgIl9yYXcuaW5mbyIKICAgIGlmIG5vdCBv cy5wYXRoLmV4aXN0cyhyYXdfaW5mb19maWxlKToKICAgICAgICAjIGNvcHkgdGhlIG9yaWdpbmFs IGZpbGUgb25seSB0aGUgZmlyc3QgdGltZS4gT3RoZXJ3aXNlIHdlIHdpbGwgb3ZlcndyaXRlIHdp dGggYW4gdXBkYXRlZCBmaWxlLgogICAgICAgIHNodXRpbC5jb3B5ZmlsZSgKICAgICAgICAgICAg aW5mb19maWxlLAogICAgICAgICAgICByYXdfaW5mb19maWxlLAogICAgICAgICkKICAgIG1ldGFk YXRhID0gZ2V0X3Jhd19kaWN0KGluZm9fZmlsZSkKICAgICMgb3ZlcndyaXRlIGRpc3RhbmNlIGtl eQogICAgbmV3X2Rpc3RhbmNlID0gMC4xNjg1ICoxMDAwICMgMjgwbm0KICAgICNuZXdfZGlzdGFu Y2UgPSAwLjA5MTcgIzEwMG5tCiAgICAjbmV3X2Rpc3RhbmNlID0gMC4xMjUgIzE1MG5tCiAgICAj bmV3X2Rpc3RhbmNlID0gIDAuMDUwMDA2MDUgIyAqIDEwMDAgIzUwbm0KICAgICNuZXdfZGlzdGFu Y2UgPSAwLjA5OSAqIDEwMDAgIzE1MG5tCiAgICBtZXRhZGF0YVsiRGlzdGFuY2UiXSA9ICJEaXN0 YW5jZT0gXHRcdCIgKyBzdHIobmV3X2Rpc3RhbmNlKSArICJcbiIKICAgIHdpdGggb3BlbihpbmZv X2ZpbGUsIG1vZGU9InciKSBhcyBmOgogICAgICAgIGZvciBfLCBsaW5lIGluIG1ldGFkYXRhLml0 ZW1zKCk6CiAgICAgICAgICAgIGYud3JpdGUobGluZSkKICAgICMgcmVzZXQga2V5IGZvciBjb2hl cmVuY2UKICAgIHNjYW4uX2Rpc3RhbmNlID0gTm9uZQpvdXRfZGF0YSA9IHNjYW6UjA1zcGxpdHRl clN0YXRllE6MC19fdmVyc2lvbl9flEsBdS4= gASVyw4AAAAAAAB9lCiMEmNvbnRyb2xBcmVhVmlzaWJsZZSIjBJjdXJyZW50U2NyaXB0SW5kZXiU SwCMEWxpYnJhcnlMaXN0U291cmNllF2UjDFvcmFuZ2Vjb250cmliLnRvbXdlci53aWRnZXRzLm90 aGVyLlB5dGhvblNjcmlwdE9XlIwGU2NyaXB0lJOUKYGUfZQojARuYW1llIwLSGVsbG8gd29ybGSU jAZzY3JpcHSUWLkGAABpbXBvcnQgb3MKaW1wb3J0IG51bXB5CmZyb20gdG9tb3NjYW4uZmFjdG9y eSBpbXBvcnQgRmFjdG9yeQpmcm9tIG5hYnUubWlzYy51dGlscyBpbXBvcnQgcmVzY2FsZV9kYXRh CgppZiBpbl9kYXRhIGlzIG5vdCBOb25lOgogICAgc2NhbiA9IGluX2RhdGEKICAgIAogICAgIyB3 YXJuaW5nOiBzY2FuLmxhdGVzdF9yZWNvbnN0cnVjdGlvbnMgaXMgZGVmaW5lZCBieSB0aGUgJ25h YnUgc2xpY2UgcmVjb25zdHJ1Y3Rpb24nLiBTbyBpZiBhIHNjYW4gaXMgbG9hZGVkIGFuZCBub3Qg Z28gdHJob3VnaCB0aGlzIHdpZGdldAogICAgIyBoZSB3b24ndCBiZSBhd2FyZSBhYm91dCBzbGlj ZSByZWNvbnN0cnVjdGlvbnMKICAgIHByaW50KCJjaGVjayIsIHNjYW4sICIgLSBsYXRlc3RfcmVj b25zdHJ1Y3Rpb25zIiwgc2Nhbi5sYXRlc3RfcmVjb25zdHJ1Y3Rpb25zKQogICAgaW5fdm9sdW1l cyA9IFsKICAgICAgICBGYWN0b3J5LmNyZWF0ZV90b21vX29iamVjdF9mcm9tX2lkZW50aWZpZXIo aWRlbnRpZmllcikgZm9yIGlkZW50aWZpZXIgaW4gc2Nhbi5sYXRlc3RfcmVjb25zdHJ1Y3Rpb25z CiAgICBdCgogICAgIyBsb29rcyBsaWtlIHRoZXJlIGlzIHNvbWUgZXh0cmEgdm9sdW1lIGV4aXN0 aW5nOiBmaWx0ZXIgdGhlbQogICAgcmVzID0gW10KICAgIGZvciB2b2wgaW4gaW5fdm9sdW1lczoK ICAgICAgICBpZiBvcy5wYXRoLmV4aXN0cyh2b2wuZmlsZV9wYXRoKToKICAgICAgICAgICAgcmVz LmFwcGVuZCh2b2wpCiAgICAKICAgIGluX3ZvbHVtZXMgPSByZXMKICAgIHByaW50KCJzbGljZXMg dG8gYmUgaGFuZGxlZCIsIGluX3ZvbHVtZXMpCgogICAgW3ByaW50KHZvbC5nZXRfaWRlbnRpZmll cigpLnRvX3N0cigpKSBmb3Igdm9sIGluIGluX3ZvbHVtZXNdCiAgICAKICAgICMgcmV0cmlldmUg dGhlIG1pbiAvIG1heCBmcm9tIHRoZSBmaXJzdCBhY3F1aXNpdGlvbgogICAgaWYgc2Nhbi5wYXRo LmVuZHN3aXRoKCJfMV8iKToKICAgICAgICBmb3Igdm9sIGluIGluX3ZvbHVtZXM6CiAgICAgICAg ICAgIHByaW50KCJyZWNvbXB1dGUgbWluIGFuZCBtYXggZnJvbSIsIHZvbC5maWxlX3BhdGgpCiAg ICAgICAgICAgIGRhdGEgPSB2b2wubG9hZF9kYXRhKCkKICAgICAgICAgICAgbmV3X21pbiwgbmV3 X21heCA9IG51bXB5LnBlcmNlbnRpbGUoZGF0YVswXSwgKDUsIDk1KSkKCiAgICAjIGFwcGx5IGNh c3QgLyByZWNsYW1pbmcgZGF0YQogICAgaWYgIm5ld19taW4iIGluIGdsb2JhbHMoKSBhbmQgIm5l d19tYXgiIGluIGdsb2JhbHMoKToKICAgICAgICBmb3Igdm9sIGluIGluX3ZvbHVtZXM6CiAgICAg ICAgICAgIHByaW50KCJub3JtYWxpemUiLCB2b2wuZmlsZV9wYXRoKQogICAgICAgICAgICB2b2wu bG9hZF9kYXRhKCkKICAgICAgICAgICAgZGF0YSA9IHZvbC5kYXRhCiAgICAgICAgICAgIGRhdGEg PSByZXNjYWxlX2RhdGEoCiAgICAgICAgICAgICAgICBkYXRhPWRhdGEsCiAgICAgICAgICAgICAg ICBuZXdfbWluPW5ld19taW4sCiAgICAgICAgICAgICAgICBuZXdfbWF4PW5ld19tYXgsCiAgICAg ICAgICAgICAgICBkYXRhX21pbj1kYXRhLm1pbigpLAogICAgICAgICAgICAgICAgZGF0YV9tYXg9 ZGF0YS5tYXgoKSwKICAgICAgICAgICAgKQogICAgICAgICAgICB2b2wuZGF0YSA9IGRhdGEKICAg ICAgICAgICAgdm9sLnNhdmVfZGF0YSgpCiAgICAgICAgCiAgICBvdXRfZGF0YSA9IHNjYW4KZWxz ZToKICAgIG91dF9kYXRhID0gaW5fZGF0YZSMBWZsYWdzlEsAjAhmaWxlbmFtZZROdWJhjBNzYXZl ZFdpZGdldEdlb21ldHJ5lENCAdnQywADAAAAAAHKAAAA5wAACf8AAAWfAAABygAAAOcAAAn/AAAF nwAAAAAAAAAACgAAAAHKAAAA5wAACf8AAAWflIwKc2NyaXB0VGV4dJRYuQYAAGltcG9ydCBvcwpp bXBvcnQgbnVtcHkKZnJvbSB0b21vc2Nhbi5mYWN0b3J5IGltcG9ydCBGYWN0b3J5CmZyb20gbmFi dS5taXNjLnV0aWxzIGltcG9ydCByZXNjYWxlX2RhdGEKCmlmIGluX2RhdGEgaXMgbm90IE5vbmU6 CiAgICBzY2FuID0gaW5fZGF0YQogICAgCiAgICAjIHdhcm5pbmc6IHNjYW4ubGF0ZXN0X3JlY29u c3RydWN0aW9ucyBpcyBkZWZpbmVkIGJ5IHRoZSAnbmFidSBzbGljZSByZWNvbnN0cnVjdGlvbicu IFNvIGlmIGEgc2NhbiBpcyBsb2FkZWQgYW5kIG5vdCBnbyB0cmhvdWdoIHRoaXMgd2lkZ2V0CiAg ICAjIGhlIHdvbid0IGJlIGF3YXJlIGFib3V0IHNsaWNlIHJlY29uc3RydWN0aW9ucwogICAgcHJp bnQoImNoZWNrIiwgc2NhbiwgIiAtIGxhdGVzdF9yZWNvbnN0cnVjdGlvbnMiLCBzY2FuLmxhdGVz dF9yZWNvbnN0cnVjdGlvbnMpCiAgICBpbl92b2x1bWVzID0gWwogICAgICAgIEZhY3RvcnkuY3Jl YXRlX3RvbW9fb2JqZWN0X2Zyb21faWRlbnRpZmllcihpZGVudGlmaWVyKSBmb3IgaWRlbnRpZmll ciBpbiBzY2FuLmxhdGVzdF9yZWNvbnN0cnVjdGlvbnMKICAgIF0KCiAgICAjIGxvb2tzIGxpa2Ug dGhlcmUgaXMgc29tZSBleHRyYSB2b2x1bWUgZXhpc3Rpbmc6IGZpbHRlciB0aGVtCiAgICByZXMg PSBbXQogICAgZm9yIHZvbCBpbiBpbl92b2x1bWVzOgogICAgICAgIGlmIG9zLnBhdGguZXhpc3Rz KHZvbC5maWxlX3BhdGgpOgogICAgICAgICAgICByZXMuYXBwZW5kKHZvbCkKICAgIAogICAgaW5f dm9sdW1lcyA9IHJlcwogICAgcHJpbnQoInNsaWNlcyB0byBiZSBoYW5kbGVkIiwgaW5fdm9sdW1l cykKCiAgICBbcHJpbnQodm9sLmdldF9pZGVudGlmaWVyKCkudG9fc3RyKCkpIGZvciB2b2wgaW4g aW5fdm9sdW1lc10KICAgIAogICAgIyByZXRyaWV2ZSB0aGUgbWluIC8gbWF4IGZyb20gdGhlIGZp cnN0IGFjcXVpc2l0aW9uCiAgICBpZiBzY2FuLnBhdGguZW5kc3dpdGgoIl8xXyIpOgogICAgICAg IGZvciB2b2wgaW4gaW5fdm9sdW1lczoKICAgICAgICAgICAgcHJpbnQoInJlY29tcHV0ZSBtaW4g YW5kIG1heCBmcm9tIiwgdm9sLmZpbGVfcGF0aCkKICAgICAgICAgICAgZGF0YSA9IHZvbC5sb2Fk X2RhdGEoKQogICAgICAgICAgICBuZXdfbWluLCBuZXdfbWF4ID0gbnVtcHkucGVyY2VudGlsZShk YXRhWzBdLCAoNSwgOTUpKQoKICAgICMgYXBwbHkgY2FzdCAvIHJlY2xhbWluZyBkYXRhCiAgICBp ZiAibmV3X21pbiIgaW4gZ2xvYmFscygpIGFuZCAibmV3X21heCIgaW4gZ2xvYmFscygpOgogICAg ICAgIGZvciB2b2wgaW4gaW5fdm9sdW1lczoKICAgICAgICAgICAgcHJpbnQoIm5vcm1hbGl6ZSIs IHZvbC5maWxlX3BhdGgpCiAgICAgICAgICAgIHZvbC5sb2FkX2RhdGEoKQogICAgICAgICAgICBk YXRhID0gdm9sLmRhdGEKICAgICAgICAgICAgZGF0YSA9IHJlc2NhbGVfZGF0YSgKICAgICAgICAg ICAgICAgIGRhdGE9ZGF0YSwKICAgICAgICAgICAgICAgIG5ld19taW49bmV3X21pbiwKICAgICAg ICAgICAgICAgIG5ld19tYXg9bmV3X21heCwKICAgICAgICAgICAgICAgIGRhdGFfbWluPWRhdGEu bWluKCksCiAgICAgICAgICAgICAgICBkYXRhX21heD1kYXRhLm1heCgpLAogICAgICAgICAgICAp CiAgICAgICAgICAgIHZvbC5kYXRhID0gZGF0YQogICAgICAgICAgICB2b2wuc2F2ZV9kYXRhKCkK ICAgICAgICAKICAgIG91dF9kYXRhID0gc2NhbgplbHNlOgogICAgb3V0X2RhdGEgPSBpbl9kYXRh lIwNc3BsaXR0ZXJTdGF0ZZROjAtfX3ZlcnNpb25fX5RLAXUu {'controlAreaVisible': True, 'dest_dir_settings': None, 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\x04>\x00\x00\x02h\x00\x00\x05\xad\x00\x00\x02\xe8\x00\x00\x04>\x00\x00\x02h\x00\x00\x05\xad\x00\x00\x02\xe8\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x04>\x00\x00\x02h\x00\x00\x05\xad\x00\x00\x02\xe8', '__version__': 1} {'controlAreaVisible': True, 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\x01\xaa\x00\x00\x00\x8b\x00\x00\x08\xbc\x00\x00\x04\x90\x00\x00\x01\xaa\x00\x00\x00\xb0\x00\x00\x08\xbc\x00\x00\x04\x90\x00\x00\x00\x00\x00\x00\x00\x00\n\x00\x00\x00\x01\xaa\x00\x00\x00\xb0\x00\x00\x08\xbc\x00\x00\x04\x90', '__version__': 1} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/tutorials/id16b/__init__.py0000644000175000017500000000000014757047403024226 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/tutorials/simple_slice_reconstruction.ows0000644000175000017500000001052315153325210027550 0ustar00paynopayno provide dataset compute reduced darks and flats compute center of rotation define one or several slice to be reconstructed display reconstructed slices and browse dataset {'_scanIDs': [], 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'dark_ref_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'axis_params': {'MODE': 'manual', 'POSITION_VALUE': None, 'CALC_INPUT_TYPE': 'transmission_nopag', 'ANGLE_MODE': '0-180', 'USE_SINOGRAM': False, 'SINOGRAM_LINE': '', 'SINOGRAM_SUBSAMPLING': 10, 'AXIS_URL_1': '', 'AXIS_URL_2': '', 'LOOK_AT_STDMAX': False, 'NEAR_WX': 5, 'FINE_STEP_X': 0.1, 'SCALE_IMG2_TO_IMG1': False, 'NEAR_POSITION': 0.0, 'PADDING_MODE': 'edge', 'FLIP_LR': True, 'COMPOSITE_OPTS': {'theta': 10, 'n_subsampling_y': 10, 'oversampling': 4, 'take_log': True, 'near_pos': 0, 'near_width': 20}, 'SIDE': 'all', 'COR_OPTIONS': ''}, 'gui': {'mode_is_lock': False, 'value_is_lock': False, 'auto_update_estimated_cor': True}}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'nabu_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_viewer_config': {}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/tutorials/simple_slice_reconstruction_on_slurm.ows0000644000175000017500000001467015153325210031475 0ustar00paynopayno provide dataset compute reduced darks and flats compute center of rotation slice reconstruction will be done on slurm as it has a 'slurm cluster' input display reconstructed slices and browse dataset Define the slurm partition to be used for the reconstruction. Warning: you must ask for one GPU wait for reconstruction to be done over slurm {'_scanIDs': [], 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'dark_ref_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'axis_params': {'MODE': 'manual', 'POSITION_VALUE': None, 'CALC_INPUT_TYPE': 'transmission_nopag', 'ANGLE_MODE': '0-180', 'USE_SINOGRAM': False, 'SINOGRAM_LINE': '', 'SINOGRAM_SUBSAMPLING': 10, 'AXIS_URL_1': '', 'AXIS_URL_2': '', 'LOOK_AT_STDMAX': False, 'NEAR_WX': 5, 'FINE_STEP_X': 0.1, 'SCALE_IMG2_TO_IMG1': False, 'NEAR_POSITION': 0.0, 'PADDING_MODE': 'edge', 'FLIP_LR': True, 'COMPOSITE_OPTS': {'theta': 10, 'n_subsampling_y': 10, 'oversampling': 4, 'take_log': True, 'near_pos': 0, 'near_width': 20}, 'SIDE': 'all', 'COR_OPTIONS': ''}, 'gui': {'mode_is_lock': False, 'value_is_lock': False, 'auto_update_estimated_cor': True}}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'nabu_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_viewer_config': {}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {}, 'controlAreaVisible': True, 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\nH\x00\x00\x01l\x00\x00\x0c#\x00\x00\x02\xce\x00\x00\nH\x00\x00\x01\x91\x00\x00\x0c#\x00\x00\x02\xce\x00\x00\x00\x01\x00\x00\x00\x00\x07\x80\x00\x00\nH\x00\x00\x01\x91\x00\x00\x0c#\x00\x00\x02\xce', '__version__': 1} {'_ewoks_default_inputs': {}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/tutorials/simple_volume_local_reconstruction.ows0000644000175000017500000001557115153325210031142 0ustar00paynopayno provide dataset compute reduced darks and flats compute center of rotation define one or several slice to be reconstructed display reconstructed slices and browse dataset browse reconstructed volume reconstruct volume {'_scanIDs': [], 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'dark_ref_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'axis_params': {'MODE': 'manual', 'POSITION_VALUE': None, 'CALC_INPUT_TYPE': 'transmission_nopag', 'ANGLE_MODE': '0-180', 'SINOGRAM_LINE': '', 'SINOGRAM_SUBSAMPLING': 10, 'AXIS_URL_1': '', 'AXIS_URL_2': '', 'LOOK_AT_STDMAX': False, 'NEAR_WX': 5, 'FINE_STEP_X': 0.1, 'SCALE_IMG2_TO_IMG1': False, 'NEAR_POSITION': 0.0, 'PADDING_MODE': 'edge', 'FLIP_LR': True, 'COMPOSITE_OPTS': {'theta': 10, 'oversampling': 4, 'n_subsampling_y': 10, 'take_log': True, 'near_width': 20}, 'COR_OPTIONS': '', 'MOTOR_OFFSET': 0.0, 'X_ROTATION_AXIS_PIXEL_POSITION': None}, 'gui': {'mode_is_lock': False, 'value_is_lock': False, 'auto_update_estimated_cor': True, 'y_axis_inverted': False}}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'nabu_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_viewer_config': {}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'nabu_volume_params': None, 'nabu_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {}, '_ewoks_execinfo': {}, '_ewoks_task_options': {}, '_ewoks_varinfo': {}, 'controlAreaVisible': True, 'default_inputs': {}, 'savedWidgetGeometry': None, '__version__': 1} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/tutorials/simple_volume_to_slurm_reconstruction.ows0000644000175000017500000002315615153325210031712 0ustar00paynopayno provide dataset compute reduced darks and flats compute center of rotation define one or several slice to be reconstructed display reconstructed slices and browse dataset browse reconstructed volume reconstruct volume wait for the slurm job to be finished define slurm node to be used {'_scanIDs': [], 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'dark_ref_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'axis_params': {'MODE': 'manual', 'POSITION_VALUE': None, 'CALC_INPUT_TYPE': 'transmission_nopag', 'ANGLE_MODE': '0-180', 'SINOGRAM_LINE': '', 'SINOGRAM_SUBSAMPLING': 10, 'AXIS_URL_1': '', 'AXIS_URL_2': '', 'LOOK_AT_STDMAX': False, 'NEAR_WX': 5, 'FINE_STEP_X': 0.1, 'SCALE_IMG2_TO_IMG1': False, 'NEAR_POSITION': 0.0, 'PADDING_MODE': 'edge', 'FLIP_LR': True, 'COMPOSITE_OPTS': {'theta': 10, 'oversampling': 4, 'n_subsampling_y': 10, 'take_log': True, 'near_width': 20}, 'COR_OPTIONS': '', 'MOTOR_OFFSET': 0.0, 'X_ROTATION_AXIS_PIXEL_POSITION': None}, 'gui': {'mode_is_lock': False, 'value_is_lock': False, 'auto_update_estimated_cor': True, 'y_axis_inverted': False}}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'nabu_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_viewer_config': {}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'nabu_volume_params': None, 'nabu_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, 'slurm_mode_name': 'GENERIC', '__version__': 1} {'_ewoks_default_inputs': {}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {}, '_ewoks_execinfo': {}, '_ewoks_task_options': {}, '_ewoks_varinfo': {}, 'controlAreaVisible': True, 'default_inputs': {}, 'savedWidgetGeometry': None, '__version__': 1} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/tutorials/using_saaxis_to_find_cor.ows0000644000175000017500000001211015153325210026773 0ustar00paynopayno provide dataset compute reduced darks and flats compute center of rotation refine COR reconstruct one or several slices browse reconstructed slices and browse dataset {'_scanIDs': [], 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'dark_ref_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'axis_params': {'MODE': 'manual', 'POSITION_VALUE': None, 'CALC_INPUT_TYPE': 'transmission_nopag', 'ANGLE_MODE': '0-180', 'USE_SINOGRAM': False, 'SINOGRAM_LINE': '', 'SINOGRAM_SUBSAMPLING': 10, 'AXIS_URL_1': '', 'AXIS_URL_2': '', 'LOOK_AT_STDMAX': False, 'NEAR_WX': 5, 'FINE_STEP_X': 0.1, 'SCALE_IMG2_TO_IMG1': False, 'NEAR_POSITION': 0.0, 'PADDING_MODE': 'edge', 'FLIP_LR': True, 'COMPOSITE_OPTS': {'theta': 10, 'n_subsampling_y': 10, 'oversampling': 4, 'take_log': True, 'near_pos': 0, 'near_width': 20}, 'SIDE': 'all', 'COR_OPTIONS': ''}, 'gui': {'mode_is_lock': False, 'value_is_lock': False, 'auto_update_estimated_cor': True}}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'sa_axis_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'nabu_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_viewer_config': {}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/tutorials/volume_casting_on_slurm.ows0000644000175000017500000001662015153325210026700 0ustar00paynopayno cast a volume remotly (using slurm) Do the volume casting remotly Define the node configuration to do the casting. WARNING: casting is a pure IO operation. No need any GPU here. Wait for casting to be done. Needed if you want to resume processing once casting is done Alternative input to the cast volume. If you want to launch it in post-processing {'_scanIDs': [], 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'dark_ref_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'axis_params': {'MODE': 'manual', 'POSITION_VALUE': None, 'CALC_INPUT_TYPE': 'transmission_nopag', 'ANGLE_MODE': '0-180', 'USE_SINOGRAM': False, 'SINOGRAM_LINE': '', 'SINOGRAM_SUBSAMPLING': 10, 'AXIS_URL_1': '', 'AXIS_URL_2': '', 'LOOK_AT_STDMAX': False, 'NEAR_WX': 5, 'FINE_STEP_X': 0.1, 'SCALE_IMG2_TO_IMG1': False, 'NEAR_POSITION': 0.0, 'PADDING_MODE': 'edge', 'FLIP_LR': True, 'COMPOSITE_OPTS': {'theta': 10, 'n_subsampling_y': 10, 'oversampling': 4, 'take_log': True, 'near_pos': 0, 'near_width': 20}, 'SIDE': 'all', 'COR_OPTIONS': ''}, 'gui': {'mode_is_lock': False, 'value_is_lock': False, 'auto_update_estimated_cor': True}}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'nabu_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'nabu_volume_params': None, 'nabu_params': None}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {'data': None, 'cast_volume_params': {}}, 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} {'_ewoks_default_inputs': {}, 'controlAreaVisible': True, 'savedWidgetGeometry': b'\x01\xd9\xd0\xcb\x00\x03\x00\x00\x00\x00\x02\xea\x00\x00\x01W\x00\x00\x04\x81\x00\x00\x03\x08\x00\x00\x02\xea\x00\x00\x01W\x00\x00\x04\x81\x00\x00\x03\x08\x00\x00\x00\x00\x00\x00\x00\x00\x07\x80\x00\x00\x02\xea\x00\x00\x01W\x00\x00\x04\x81\x00\x00\x03\x08', '__version__': 1} {'_ewoks_default_inputs': {}, '_ewoks_execinfo': {}, '_ewoks_task_options': {}, '_ewoks_varinfo': {}, 'controlAreaVisible': True, 'default_inputs': {}, 'savedWidgetGeometry': None, '__version__': 1} {'_scanIDs': [], 'controlAreaVisible': True, 'savedWidgetGeometry': None, '__version__': 1} ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8811002 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/0000755000175000017500000000000015153325403020630 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/__init__.py0000644000175000017500000000236015143647637022761 0ustar00paynopayno""" (Ewoks)Orange Widgets dedicated for tomography """ from ewoksorange.pkg_meta import get_distribution ICON = "../widgets/icons/tomwer.png" BACKGROUND = "#C0CCFF" # Entry point for main Orange categories/widgets discovery def widget_discovery(discovery): dist = get_distribution("tomwer") pkgs = [ "orangecontrib.tomwer.widgets.cluster", "orangecontrib.tomwer.widgets.control", "orangecontrib.tomwer.widgets.deprecated", "orangecontrib.tomwer.widgets.debugtools", "orangecontrib.tomwer.widgets.edit", "orangecontrib.tomwer.widgets.dataportal", "orangecontrib.tomwer.widgets.reconstruction", # "orangecontrib.tomwer.widgets.stitching", "orangecontrib.tomwer.widgets.visualization", "orangecontrib.tomwer.widgets.other", ] for pkg in pkgs: discovery.process_category_package(pkg, distribution=dist) WIDGET_HELP_PATH = ( # Used for development. # You still need to build help pages using # make htmlhelp # inside doc folder # ( # "/home/payno/Documents/dev/tomography/tomwer/build/html/canvas/widgets/widgets.html", # None, # ), ("https://tomwer.readthedocs.io/en/latest/canvas/widgets/widgets.html", None), ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8811002 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/cluster/0000755000175000017500000000000015153325403022311 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/cluster/FutureSupervisorOW.py0000644000175000017500000002440515153325210026506 0ustar00paynopayno# coding: utf-8 # /*########################################################################## # # Copyright (c) 2016-2017 European Synchrotron Radiation Facility # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # # ###########################################################################*/ __authors__ = ["H. Payno"] __license__ = "MIT" __date__ = "14/10/2021" import time from orangewidget import gui from orangewidget.settings import Setting from orangewidget.widget import Input, Output, OWBaseWidget from processview.core.manager import DatasetState, ProcessManager from processview.core.superviseprocess import SuperviseProcess from silx.gui import qt from silx.gui.utils.concurrent import submitToQtMainThread from tomwer.core.futureobject import FutureTomwerObject from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.volume.volumebase import TomwerVolumeBase from tomwer.gui.cluster.supervisor import ( FutureTomwerScanObserverWidget as _FutureTomwerScanObserverWidget, ) from tomwer.core.process.drac.processeddataset import DracReconstructedVolumeDataset from tomwer.core.volume.volumefactory import VolumeFactory class FutureSupervisorOW(OWBaseWidget, openclass=True): """ Orange widget to define a slurm cluster as input of other widgets (based on nabu for now) """ name = "future supervisor" id = "orange.widgets.tomwer.cluster.FutureSupervisorOW.FutureSupervisorOW" description = "Observe slurm job registered." icon = "icons/slurmobserver.svg" priority = 22 keywords = [ "tomography", "tomwer", "slurm", "observer", "cluster", "job", "sbatch", "supervisor", "future", ] want_main_area = True want_control_area = False resizing_enabled = True _ewoks_default_inputs = Setting(dict()) class Inputs: future_in = Input( name="future_tomo_obj", type=FutureTomwerObject, doc="data with some remote processing", multiple=True, default=True, ) class Outputs: data = Output(name="data", type=TomwerScanBase) volume = Output(name="volume", type=TomwerVolumeBase) data_portal_processed_datasets = Output( name="data_portal_processed_datasets", type=tuple, doc="data portal processed data to be saved", ) def __init__(self, parent=None): super().__init__(parent) # gui layout = gui.vBox(self.mainArea, self.name).layout() self._widget = FutureTomwerObjectObserverWidget( parent=self, name=self.windowTitle() ) layout.addWidget(self._widget) # connect signal / slot self._widget.observationTable.model().sigStatusUpdated.connect( self._convertBackAutomatically ) self._widget.sigConversionRequested.connect(self._convertBack) def convertWhenFinished(self): return self._widget.convertWhenFinished() def _convertBackAutomatically(self, future_tomo_obj, status): if not isinstance(future_tomo_obj, FutureTomwerObject): raise TypeError( f"future_tomo_obj is expected to be an instance of {FutureTomwerObject} and not {type(future_tomo_obj)}" ) if status in ("finished", "completed") and self.convertWhenFinished(): self._convertBack(future_tomo_obj) def _convertBack(self, future_tomo_obj): if not isinstance(future_tomo_obj, FutureTomwerObject): raise TypeError( f"future_tomo_obj is expected to be an instance of {FutureTomwerObject} and not {type(future_tomo_obj)}" ) self._futureHasBeenConverted(future_tomo_obj, future_tomo_obj.tomo_obj) @Inputs.future_in def add(self, future_tomo_obj, signal_id=None): if future_tomo_obj is not None: self._widget.addFutureTomoObj(future_tomo_obj=future_tomo_obj) def _futureHasBeenConverted(self, future_tomo_obj, tomo_obj): # clean client to free resources self._widget.removeFutureTomoObj(future_tomo_obj=future_tomo_obj) if tomo_obj is not None: if isinstance(tomo_obj, TomwerScanBase): self.Outputs.data.send(tomo_obj) def build_drac_dataset(vol_id): volume = VolumeFactory.create_tomo_object_from_identifier(vol_id) return DracReconstructedVolumeDataset( tomo_obj=volume, source_scan=tomo_obj, ) self.Outputs.data_portal_processed_datasets.send( tuple( [ build_drac_dataset(vol_id=vol_id) for vol_id in tomo_obj.latest_vol_reconstructions ] ) ) if len(tomo_obj.latest_vol_reconstructions) > 0: rec_volume = VolumeFactory.create_tomo_object_from_identifier( tomo_obj.latest_vol_reconstructions[0] ) self.Outputs.volume.send(rec_volume) elif isinstance(tomo_obj, TomwerVolumeBase): self.Outputs.volume.send(tomo_obj) class FutureTomwerObjectObserverWidget( _FutureTomwerScanObserverWidget, SuperviseProcess ): """add dataset state notification (ProcessManager) to the original FutureTomwerScanObserverWidget""" REFRESH_FREQUENCE = 10 """time between call to updateView""" def __init__(self, name, parent=None): super().__init__(parent=parent) self.name = name self._updateThread = _RefreshThread( callback=self.updateView, refresh_frequence=self.REFRESH_FREQUENCE ) self.destroyed.connect(self.stopRefresh) self._updateThread.start() def stopRefresh(self): if self._updateThread is not None: self._updateThread.stop() self._updateThread.wait(self.REFRESH_FREQUENCE + 1) self._updateThread = None def close(self): self.stopRefresh() super().close() def addFutureTomoObj(self, future_tomo_obj: FutureTomwerObject): super().addFutureTomoObj(future_tomo_obj) self._updateTomoObjSupervisor(future_tomo_obj) def removeFutureTomoObj(self, future_tomo_obj: FutureTomwerObject): self._updateTomoObjSupervisor(future_tomo_obj) super().removeFutureTomoObj(future_tomo_obj) def _updateTomoObjSupervisor(self, future_tomo_obj): r_id = future_tomo_obj.process_requester_id if r_id is not None: requester_name = ProcessManager().get_process(r_id).name else: requester_name = "unknow" details = f"job spawn by {requester_name}" if future_tomo_obj is None: return elif future_tomo_obj.status == "error": state = DatasetState.FAILED if future_tomo_obj.job_id is None: details = "Job submission to Slurm has failed. This is likely due to an invalid configuration request, such as requesting a GPU on a partition that does not support GPUs. Please review your configuration and try again." elif future_tomo_obj.status == "pending": details = "\n".join([details, "pending"]) state = DatasetState.PENDING elif future_tomo_obj.status in ("finished", "completed"): details = future_tomo_obj.logs or "no log found" state = DatasetState.SUCCEED elif future_tomo_obj.status == "running": details = "\n".join([details, "running"]) state = DatasetState.ON_GOING elif future_tomo_obj.status == "cancelled": details = "\n".join([details, "job cancelled"]) state = DatasetState.SKIPPED elif future_tomo_obj.status is None: return else: raise ValueError( f"future scan status '{future_tomo_obj.status}' is not managed, {type(future_tomo_obj.status)}" ) ProcessManager().notify_dataset_state( dataset=future_tomo_obj.tomo_obj, process=self, state=state, details=details, ) def _updateStatus(self, future_tomo_obj): self._updateTomoObjSupervisor(future_tomo_obj) super()._updateStatus(future_tomo_obj) class _RefreshThread(qt.QThread): """Simple thread to call a refresh callback each refresh_frequence (seconds)""" TIME_BETWEEN_LOOP = 1.0 def __init__(self, callback, refresh_frequence) -> None: super().__init__() self._callback = callback self._refresh_frequence = refresh_frequence self._stop = False def stop(self): self._stop = True self._callback = None def run(self): w_t = self._refresh_frequence + self.TIME_BETWEEN_LOOP while not self._stop: if w_t <= 0: if self._callback is not None: try: submitToQtMainThread(self._callback) except AttributeError: # can happen when closing pass w_t = self._refresh_frequence + self.TIME_BETWEEN_LOOP w_t -= self.TIME_BETWEEN_LOOP time.sleep(self.TIME_BETWEEN_LOOP) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/cluster/SlurmClusterOW.py0000644000175000017500000000567315153325210025604 0ustar00paynopaynofrom __future__ import annotations import logging from silx.gui import qt from orangewidget import gui from orangewidget.settings import Setting from orangewidget.widget import Output, OWBaseWidget from tomwer.core.cluster import SlurmClusterConfiguration from tomwer.gui.cluster.slurm import SlurmSettingsWindow from tomwer.core.settings import SlurmSettingsMode _logger = logging.getLogger(__name__) class SlurmClusterOW(OWBaseWidget, openclass=True): """ Orange widget to define a slurm cluster as input of other widgets (based on nabu for now) """ name = "slurm cluster" id = "orange.widgets.tomwer.cluster.SlurmClusterOW.SlurmClusterOW" description = "Let the user configure the cluster to be used." icon = "icons/slurm.svg" priority = 20 keywords = ["tomography", "tomwer", "slurm", "cluster", "configuration"] want_main_area = True want_control_area = False resizing_enabled = True _ewoks_default_inputs = Setting(dict()) slurm_mode_name = Setting(SlurmSettingsMode.GENERIC.name) class Outputs: config_out = Output(name="cluster_config", type=SlurmClusterConfiguration) def __init__(self, parent=None) -> None: super().__init__(parent) layout = gui.vBox(self.mainArea, self.name).layout() self._widget = SlurmSettingsWindow(parent=self) self._widget.setWindowFlags(qt.Qt.Widget) layout.addWidget(self._widget) if self._ewoks_default_inputs != {}: self._widget.setConfiguration(self._ewoks_default_inputs) try: mode = SlurmSettingsMode[self.slurm_mode_name] self._widget.setMode(mode) except Exception: _logger.exception( f"Could not restore saved SlurmSettingsMode {self.slurm_mode_name!r}" ) # trigger the signal to avoid any user request self.Outputs.config_out.send(self.getConfiguration()) # connect signal / slot self._widget.sigConfigChanged.connect(self._configurationChanged) def __new__(cls, *args, **kwargs): # ensure backward compatibility with 'static_input' static_input = kwargs.get("stored_settings", {}).get("_static_input", None) if static_input not in (None, {}): _logger.warning( "static_input has been deprecated. Will be replaced by _ewoks_default_inputs in the workflow file. Please save the workflow to apply modifications" ) kwargs["stored_settings"]["_ewoks_default_inputs"] = static_input return super().__new__(cls, *args, **kwargs) def _configurationChanged(self): slurmClusterconfiguration = self.getConfiguration() self.Outputs.config_out.send(slurmClusterconfiguration) self._ewoks_default_inputs = slurmClusterconfiguration.to_dict() self.slurm_mode_name = self._widget.mode().name def getConfiguration(self): return self._widget.getSlurmClusterConfiguration() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/cluster/__init__.py0000644000175000017500000000060114764622416024432 0ustar00paynopayno""" (Ewoks)Orange Widgets for remote processing through slurm """ NAME = "compute cluster" ID = "orangecontrib.tomwer.widgets.cluster" DESCRIPTION = "widgets to submit jobs to cluster" LONG_DESCRIPTION = ( "widgets to submit slurm job, observe job and convert them back to tomwer object" ) ICON = "../../widgets/icons/tomwer_cluster.png" BACKGROUND = "#C0CCFF" PRIORITY = 5 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8851004 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/cluster/icons/0000755000175000017500000000000015153325403023424 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/cluster/icons/slurm.png0000644000175000017500000000371314757047403025312 0ustar00paynopayno‰PNG  IHDR- †„ñDsBIT|dˆ pHYsÄÄ•+tEXtSoftwarewww.inkscape.org›î<HIDATX…½—klT×€¿¹û2Æ‹)xi!-QÁà&àD²+Æ`ÒXÄ™–GãÝHѪÈPT�Š’F¨J«†¤„R( Ô¤TˆìJÈ5nØØZb”(ŽÍ£t¡†]ïz÷NìƒõÚ ìÌŸ{Μ™3ß½ç1s…>–©5º˜Ÿ  JaýLùg_Å0új¢•Ôw„ቾ ÐÐý.ÖGuœú7}á(ªÂ¦ÆR9“Ê~F�:|°J!=êÓy×ä7'ËÄ÷¥A#¼ ˆ¶>Îï«r;n&mpÊo2F Ö$ø3ÀàðÑ—�BÂ]l u±¾i¡³¡D.O«Öñ}£Ï¡-6þ ÌŠ+L(ªÑY˜\ì«„.ø»3ºâ{÷ÆÑ2ùw¤ÉO¾Õ«*5N´û ƒ6.v†ù#àŒª}Ö çŠèBUžPálã ÙùXÐÖ0ïbÄ¿Üy ' w''j×èÎN!LÇ7¥–:#vMºL'€©,(0L>:É&Þe0@º/ðF¯3(:­–'MeW|L?-À‘/ÀðpÐÁx %˜ÊΈ~iÞå_ À�¶‡IYÁ0#yB I$r™pìñ¡°Äô³ÀbáóÙ!|jÐg6v‚O``J¥Þ/€!÷|ZýüV`€ir ø&€À…o騘ŽBþ ˜ó«�  ‡;ÃìW�ìiºÄˆ¬HVGrØûxЊ=áˆ9†®ö¨M8dr=ªïQ˜Š‘y›ÎÎ * ƒ4‚7:â>%= §Ðç "ÂÇõ%r!œ0Š¿ ¼M4# mÀïSºšAŽÀ{»q€,'§�ˆpšh¡¥p*Êñ‚([€�Bac©ÜH -Êû CTÙ ¼b ðj ’0+­© Tâëáï1§à7L 3i Â÷â!…öèÛÄñðø‹˜8�ÔÐÉv°Áß°(g�§îgoÀ0¢{Pù�¦ißæéT>f$QHäž®B¹(ÂIUºi÷j™TÐK\åh4¨=>"÷Ú ¿“è¡L„€úRi…^Vä¯Ú*ªM�ìi‚¦5uj7 L3ŒW„`çÝîWmoÐï 2… DöW(a,Þn,•U©ö&õ³åPÖÛ˜(Í#¢Ý�Pž‰Ü(6™…Õ:Ö0(VðY§Öh+�.ÂÏ�Ì�MDO¿JäiëbqÀÂ/ìÂô‹JÃLùq²Î4¹)‘,Ûe±ã™¬"_ú S#)a%Ê`5©8ô]¹\ëØûIãL©*cý©ÔŒÖ:a« »DIá$@à Ùv¿É¶lÙ²Í0 _yyùOú:YÒ 6øºØe5ZgÈKãÜÜÜ<6--­£¿àRÉ/È]ˆ¤øûþتꀾ®ªé½è½èìɺ˜ôZoß¾}ùñãÇ_öz½_³X,]#G޼²|ùr÷È‘#?+//¯KKKëØ¸q㬛7o>½zõê=³gÏ~³¸¸ø=€æææI›6múƒÛí^_TTô—ŠŠŠ_wttLµÙl655Í3fŒ}Þ¼y+Þzë­×=Ï±ŠŠŠ‚«W¯~5;;ûBiié+—.]šÛØØøâ�;wÒòóóO,^¼øe—ËÕme{\y---9‹-Z»`Á‚ÚÜÜÜÍ>Ÿo`kkëDéQ¥�´šššÜ’’’Á1](X]]ýÌÂ… ¿ÐÖÖ6èðáÃÏæææ:§OŸ^ár¹2ü~úþýûŸ;vlÖĉwfffú6oÞü£¡C‡îñz½�²²²Yëׯ_š••õðê}¡ÛÛÛÇ·¶¶:óòòŽM™2e‡ˆ(ðö’%KR­Ö¥¥¥ÅºfÍše………uG�}Ñï÷3dÈ�?y<žŸ¬]»öÉ­[·zöîÝ;³    ¼¼|ÂéÓ§Ç%Ï×cOÔ¸Ýî�Ün÷�çäºuëvÔÖÖ>÷ÈÄ@^^ÞõÉ“'7$êÙÙÙgc}§ÓykܸqÞI“&5%ØÜ™Éóõ,˜Düªú\~~þâS§NM8qâÄwªªªæVVV¾4wîÜýÝœ­VSDPÕøÙéÁ`÷‡ÃÑ%"‰Õ"‹«ÕÚÍÐn·‡IȺÑUî!= UÕ*"~"¥'mmmY�çÌùó矺A»\®Ï‡þ¿öövWLwîܹ‰^¯··X}&= ëêê–®ZµjæèÑ£Odeeýwß¾}ã/_¾ì5jԧɶ"rcÙ²eÍUUUßß¹sgèÖ­[ƒÚÚÚæ¹\®dÓþ……BŸ�ↆ†9ªšž‘‘q}åÊ•ëæÏŸÿ.@nnn«awcö¥¥¥+l6Û/<øÃÌÌÌkn·û�+W®”Øl¶«#FŒ¸æt:?Û½{w<†Ýn¿9gΜc6›-^Ë 6ìZQQÑYÀŒérrrÚÂáp�DöIò½‹ëp¨2IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/cluster/icons/slurm.svg0000644000175000017500000002307614757047403025331 0ustar00paynopayno image/svg+xml slurm ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/cluster/icons/slurmobserver.png0000644000175000017500000000621414757047403027061 0ustar00paynopayno‰PNG  IHDR,+�j¹sBIT|dˆ pHYsÄÄ•+tEXtSoftwarewww.inkscape.org›î< IDATX…Í™{pTU¶Æûô#éîФCçIÞ@% �f$ˆ0$* R": ÌP…2sÅ{uf,uªftÐ Ê&è E¯f)P0$€B �GçI’îsöý£Ch1-!:uïª:Ugï³öw¾½ÎzìÕ-è½9ÀD`pçØ¸\Š€À@û ïùɼ ´²×)`& þ/ÈN®vGLáP„¨Ú»{ll?•À�ìz&�(7&ôzý {@À'aaaß9Žp¡Ó¹úúù]iik3^®¬ÓÜÚ:UJiõÀ8Œj{KX×C½ `# B´þ92<ü_---CU)ûEöï_c6›•¦¦¦Ø‡#Éf³• IJZ^U]®ªjT'N 0XK/ýZ¹½ >À ÀÐ9n��ŠzÑb25)#ÓÒÒ¾T�ÎUʨŒ´4GssóP›Íæìg³é«¯\™óÀòõõÝæ�÷ `aoÈBÏ\b!î  _@ÀÛýƒƒ+5E ÌÉÌ,þxË–GΜ=›m0šCƒ‚Î\¼ti8 3{ö"³År­©©©¥êÊ•ö­;v¼«iZd'L#´Ü)ážXxf—²¢Te¤§ÔÔ×§DEF6ì;p`¼€¾N§Ó¯“,Š¢¨¥gÏ/عó!E§ëÓÏnׇ„„üÝÓ dß)Y¸½[�ÿ¦óKX,–-VëÕöŽŽ�Ò3g²Îž;7¡¶®. Àl6·D†‡W765ùiš¦¿pñâ�kµµƒ]ªZq¾�ÉtñLYÙÃÜt­`ó�¾�…#ñp›>Ë…“%%“]šfŽŠŠ*ÖëõíV«µic~þçïýcÙ§_}·ËA“˜’Ö¤ªª¯ÕjUu:]…v½�Û¶xtCÛ½£FmÎÊÌÜ=)#ãH?¿»ÍÖØ?4T3ú˜ý"Äué‡Ý=‚°AIíoÞ<¿¶¡ÁOÑê×§7„õ·y~Ùspýúu»Ín?f4¬ËßAcSS€²òòþ/þñ�ññÃGë·l/èÒÿfs•¥#…¢´777ûªªìwéßE¸žÎ ÕÔÔ”âìè(hs:�á‰#+*NŸ´KMÕ5;êLÛvîLÙ¶sg×°»Rhi¨#zððÒæúZ{GòäñÚÁƒaØßö†ðí‚Nƒ€áªª†êtºÂ@»½¹ÏäÜéñYO[ú.~½ï{‹„¢�õJ>øãå#³ç»ÊK¾ùeãù“žj q—y ˆÁí××§7B=Ik˹Y•ôÅ%%Ï^»zÕÙŽN»xâ.aÀ`²ÚÿÛÜgžyÁh4:|}|ªØ½ìùÓKŸ^*;šËÕ•–K{×wúÇžN À0`4PLÆñ#õ¡'¥¹ FhšZ^Q:þq«Dô»Vz„A“~ɘ¤Kœ– %xJî¨à §/Veú$ŽORÚE§vn˜«©NwY׈võêkEëwwÕË€çp[z/P 4õ–0� Y�ÄQU5¦ê«]>Ö¸{\ýG?ÜÞRsùúW—5–U\ÒØÜ:ĉÞÜoÄDãÕo¿´œÝõQº¦ºŒAüs« LŸ±ªüƒW,>þÁw©í­Š®Nçcþµt9s€c¸¿@ï$þ·ÿت3ù9鿨¨3.øYûnð÷ÿkĨ ˜ž+S2¥Îäw«n‡¾oÐïÆm’þ�°Æïô ‰‘~±Cå½ëkëq—í±À¬Þò}ZèôZwd{zéL~Cÿ²¿aì6Y×y=0|Ù‰#A³¤Ð<õÿ <�—ÂòcA§ÞVIÕuk||ß“—ŒýºYæ¡è°Þ=ÛÐŒ—Fÿ³æ ëÝ£­¸Ó£ ˆð‹NºõØË˜Ã;ã x ¨Ã„?oyØøxðÒ•¸¤ùüñ—ã­-Bпåü Z.œäºWþÔVu¶ÃoàpÅÝš½àxàˆûªöM¥ÂèóÙý{^r6×¥Ž{,´æÈ–ý€£sC[½¢;Âá¸%Ã<'ƒOkô¬WVÏxá­/' îTg‰IÆ“Œ}ìãïI=&�d­è�YšJÛ¸ÏåêD �o$ÜŸ¡0©oBjfß„T§¿X¸²(ôFÔáTàSÜp—øE;_-0›#žG²جI^Ð) Рu6c·3¸Gz˜Sê‰ [QYÜ5§ò €”ŒRtpóÒCÂ�kÓ-:û‡½õe„Á 5wR�¡id(GÊ×|äõ-.üÄv�|{BÎaüø=·TŸàèÍíW. #bϯù/€à =À¸2Auñœ"hþ"KLáföpŸ°`‚ ªÎ—=!Ù)Êý`z£ª·ôÕ+¾~gkmZWsh¦� ׫ÏUWÝÄ4B„à~Ù™$BÒOŽ|‘% nþw‰^%Z-‘ZGë˜>Sæš"úÚ+.}º´8æ&,iëÔoøW–øð·îwïÞ=¦­­mlvvv�ÜáNeOޏ„»5óñ‹Òh0$¥µ¼ô¯Ó霵µµÆs.—ë{g]!DOþðÒAõ�°”ÒGJé›��pzΜ9ÿ1{öì¿”––FvO½ÄÄÄ2!DÇáLJG–——Çv‡ùs‰·,ºdÉ’K—.Ýa³Ùê·oß>nذa§�+žJ&“©2))éø‡~˜»bÅŠ‘«W¯N·Z­^ ñæ!Ä©ãÇ�ß·gÏž' ƒ+''çy!„ «ÉÌ̬BÈœœœ—ýýýåáÇ§ÄÆÆ�>}ú¾¸¸¸€„„„š´´´jOàñãÇ_ŽŽŽî*±ÉÉɵ£F�ºvcl·Ûë²²²ºmñþV|–£µÂVIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/cluster/icons/slurmobserver.svg0000644000175000017500000015723014757047403027101 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8851004 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/cluster/tests/0000755000175000017500000000000015153325403023453 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/cluster/tests/__init__.py0000644000175000017500000000000014757047403025564 0ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8851004 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/0000755000175000017500000000000015153325403022310 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/AdvancementOW.py0000644000175000017500000000212414757047403025366 0ustar00paynopaynofrom __future__ import annotations import logging from orangewidget import gui, widget from processview.gui.processmanager import ProcessManagerWindow logger = logging.getLogger(__name__) class AdvancementOW(widget.OWBaseWidget, openclass=True): """ A simple widget managing the copy of an incoming folder to an other one :param parent: the parent widget """ # note of this widget should be the one registred on the documentation name = "advancement" id = "orangecontrib.widgets.tomwer.control.AdvancementOW.AdvancementOW" description = "This widget can display advancement of processes and scans" icon = "icons/advancement.svg" priority = 5 keywords = ["tomography", "process", "advancement"] want_main_area = True want_control_area = False resizing_enabled = True def __init__(self, parent=None): widget.OWBaseWidget.__init__(self, parent) self._widget = ProcessManagerWindow(parent=self) self._box = gui.vBox(self.mainArea, self.name) layout = self._box.layout() layout.addWidget(self._widget) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/BlissDataListenerOW.py0000644000175000017500000000521615153325210026504 0ustar00paynopaynofrom __future__ import annotations import logging from ._DataListenerBaseClass import DataListenerBaseClass from tomwer.core.process.control.datalistener import DataListener from tomwer.synctools.bliss_sync.blissdata_listener import BlissDataListenerQThread _logger = logging.getLogger(__name__) class BlissDataListenerOW(DataListenerBaseClass): """ This widget is used to listen to blissdata at a specific BEACON_HOST """ name = "Blissdata Listener" id = "orangecontrib.widgets.tomwer.control.BlissDataListenerOW.BlissDataListenerOW" description = ( "The widget will listen to bliss data in order to retrieve on-going (tomo) bliss-sequence.\n" "It must ne started **before** the bliss scan starts.\n" "Once the bliss sequence is finished it will be converted to NXtomo(s)" ) icon = "icons/blissdata_listener.svg" priority = 10 keywords = [ "bliss data", "blissdata", "tomography", "tomwer", "listener", "datalistener", "hdf5", "NXtomo", ] def __init__(self, host_discovery="BEACON_HOST", parent=None): super().__init__(host_discovery=host_discovery, parent=parent, uses_rpc=False) self._widget.setHostAndPortToolTip( "Host and port must be defined from the 'BEACON_HOST' environment before launching the canvas.\nLike for example: `export BEACON_HOST=id00:25000`" ) def delete_listening_thread(self): if self._listening_thread is not None: self._listening_thread.sigAcquisitionStarted.disconnect( self._widget._acquisitionStarted ) self._listening_thread.sigAcquisitionEnded.disconnect( self._widget._acquisitionEnded ) DataListener.delete_listening_thread(self) def create_listening_thread(self): try: thread = BlissDataListenerQThread( host=self.getHost(), port=self.getPort(), acquisitions=None ) except ConnectionRefusedError: _logger.error(self._getErrorMsg(ConnectionRefusedError)) return None except TimeoutError: _logger.error(self._getErrorMsg(TimeoutError)) return None # connect thread thread.sigAcquisitionStarted.connect(self._widget._acquisitionStarted) thread.sigAcquisitionEnded.connect(self._widget._acquisitionEnded) return thread def _getErrorMsg(self, exception_type): return f"Unable to create Blissdata Listener widget. - {exception_type}. Please check that the host and the port are correct from the BEACON_HOST environment variable" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/DataDiscoveryOW.py0000644000175000017500000001753415153325210025677 0ustar00paynopaynofrom __future__ import annotations import fnmatch import logging import os import h5py from orangewidget import gui, widget from orangewidget.widget import Output from silx.gui import qt from orangewidget.settings import Setting import tomwer.core.process.control.datadiscovery from orangecontrib.tomwer.widgets.utils import WidgetLongProcessing from tomwer.core.scan.blissscan import BlissScan from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.scan.scantype import ScanType from tomwer.gui.control.datadiscovery import DataDiscoveryWidget logger = logging.getLogger(__name__) class DataDiscoveryOW(widget.OWBaseWidget, WidgetLongProcessing, openclass=True): """ This widget will browse a folder and sub folder to find valid tomo scan project. Contrary to the scan watcher it will parse all folder / sub folders then stop. """ name = "scan discovery" id = "orangecontrib.widgets.tomwer.control.DataDiscoveryOW.DataDiscoveryOW" description = ( "This widget will browse a folder and sub folder to find valid tomo scan project. \n" "Contrary to the scan watcher it will parse all folder / sub folders then stop." ) icon = "icons/datadiscover.svg" priority = 11 keywords = [ "tomography", "tomwer", "datadiscovery", "data", "discovery", "search", "research", "hdf5", "NXtomo", ] want_main_area = True want_control_area = False resizing_enabled = True ewokstaskclass = tomwer.core.process.control.datadiscovery._DataDiscoveryPlaceHolder class Outputs: data = Output(name="data", type=TomwerScanBase, doc="one scan to be process") settings = Setting(dict()) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._widget = DataDiscoveryWidget(parent=self) self._box = gui.vBox(self.mainArea, self.name) layout = self._box.layout() layout.addWidget(self._widget) self._widget.setConfiguration(self.settings) # getting ready for processing self._processingThread = _DiscoverThread() # connect signal / slot self._processingThread.sigDataFound.connect(self._sendData) self._processingThread.finished.connect(self._endProcessing) self._widget.widget.controlWidget._qpbstartstop.released.connect( self._switchObservation ) # dedicated one for settings self._widget.widget.controlWidget._filterQLE.editingFinished.connect( self._updatesettings ) self._widget.widget.controlWidget._qteFolderSelected.editingFinished.connect( self._updatesettings ) self._widget.widget.configWidget.sigScanTypeChanged.connect( self._updatesettings ) def _updatesettings(self): self.settings = self.getConfiguration() # expose some API def getConfiguration(self) -> dict: return self._widget.getConfiguration() def setConfiguration(self, config: dict): self._widget.setConfiguration(config) def getProcessingThread(self) -> qt.QThread: return self._processingThread def setFolderObserved(self, dir_: str): self._widget.widget.setFolderObserved(dir_) def setSearchScanType(self, scan_type): self._widget.widget.setSearchScanType(scan_type) def setFilePattern(self, pattern: str | None): self._widget.widget.setLinuxFilePattern(pattern) def _switchObservation(self, *args, **kwargs): """stop or start the disceovery according to the thread state""" thread = self.getProcessingThread() if thread.isRunning(): thread.quit() self._endProcessing() else: self.start_discovery() def start_discovery(self, wait: int | None = None): """start the discovery of scans :param wait: optional waiting time in second """ thread = self.getProcessingThread() if thread.isRunning(): logger.warning("Discovery is already running") return self._startProcessing() thread.setConfiguration(self.getConfiguration()) thread.start() if wait is not None: thread.wait(wait) def _sendData(self, data): if data is not None: self.Outputs.data.send(data) def _startProcessing(self, *args, **kwargs): self._widget.widget.controlWidget._qpbstartstop.setText("stop discovery") return super()._startProcessing(*args, **kwargs) def _endProcessing(self, *args, **kwargs): self._widget.widget.controlWidget._qpbstartstop.setText("start discovery") return super()._endProcessing(*args, **kwargs) class _DiscoverThread(qt.QThread): """ Thread to browse folder and sub folder and looking for some scan """ sigDataFound = qt.Signal(object) """emit each time a new dataset is found""" def __init__(self, **kwargs) -> None: super().__init__(**kwargs) self._root_dir = None self._research_type = None self._file_filter = None self._look_for_hdf5 = False def setConfiguration(self, config: dict): self._root_dir = config.get("start_folder", None) self._research_type = ScanType(config["scan_type_searched"]) self._file_filter = config.get("file_filter", None) self._look_for_hdf5 = self._research_type in ( ScanType.BLISS, ScanType.NX_TOMO, ) def run(self): if self._research_type is None: logger.error("No reserach type defined. Cannot research scan") elif not os.path.isdir(self._root_dir): logger.error(f"{self._root_dir} is not a directory") else: self.discover_scan(file_path=self._root_dir) def discover_scan(self, file_path): if ( os.path.isfile(file_path) and self._look_for_hdf5 and h5py.is_hdf5(file_path) ) or (os.path.isdir(file_path) and not self._look_for_hdf5): try: name_match = self._file_filter is None or fnmatch.fnmatch( os.path.basename(file_path), self._file_filter ) except Exception as e: logger.error(f"fnmatch fail. Error is {e}") name_match = True if name_match: self._treat_path(file_path) if os.path.isdir(file_path): [ self.discover_scan(file_path=os.path.join(file_path, file_)) for file_ in os.listdir(file_path) ] def _treat_path(self, folder_path: str): """treat file / folder at a specific location""" try: scan_objs = ScanFactory.create_scan_objects( scan_path=folder_path, accept_bliss_scan=(self._research_type == ScanType.BLISS), ) except Exception as e: logger.info(f"Fail to treat {folder_path}. Error is {e}") else: for scan in scan_objs: if ( isinstance(scan, BlissScan) and self._research_type is ScanType.BLISS ): self.sigDataFound.emit(scan) elif ( isinstance(scan, NXtomoScan) and self._research_type is ScanType.NX_TOMO ): self.sigDataFound.emit(scan) elif ( isinstance(scan, EDFTomoScan) and self._research_type is ScanType.SPEC ): self.sigDataFound.emit(scan) else: raise NotImplementedError("case not handled", self._research_type) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/DataSelectorOW.py0000644000175000017500000000775615153325210025515 0ustar00paynopaynofrom __future__ import annotations import logging from orangewidget import gui from orangewidget.settings import Setting from orangewidget.widget import Input, Output, OWBaseWidget from silx.gui import qt import tomwer.core.process.control.scanselector from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui.control.scanselectorwidget import ScanSelectorWidget logger = logging.getLogger(__name__) class DataSelectorOW(OWBaseWidget, openclass=True): name = "scan selector" id = "orange.widgets.tomwer.scanselector" description = ( "List all received scan. Then user can select a specific" "scan to be passed to the next widget." ) icon = "icons/scanselector.svg" priority = 42 keywords = ["tomography", "selection", "tomwer", "scan", "data"] ewokstaskclass = tomwer.core.process.control.scanselector._ScanSelectorPlaceHolder want_main_area = True want_control_area = False resizing_enabled = True _scanIDs = Setting(list()) class Inputs: data = Input(name="data", type=TomwerScanBase, multiple=True) class Outputs: data = Output(name="data", type=TomwerScanBase) def __init__(self, parent=None): """ """ super().__init__(parent) self.widget = ScanSelectorWidget(parent=self) self.widget.setWindowFlags(qt.Qt.Widget) self._loadSettings() self.widget.sigUpdated.connect(self._updateSettings) self.widget.sigSelectionChanged.connect(self.changeSelection) layout = gui.vBox(self.mainArea, self.name).layout() layout.addWidget(self.widget) @Inputs.data def addScan(self, scan, *args, **kwargs): self.add(scan) def add(self, scan): if scan is not None: self.widget.add(scan=scan) def changeSelection(self, list_objs): if list_objs is None: return for obj_id in list_objs: item = self.widget.dataList._myitems.get(obj_id, None) if item: tomo_obj = item.data(qt.Qt.UserRole) assert isinstance(tomo_obj, TomwerScanBase) self.Outputs.data.send(tomo_obj) else: logger.error("%s not found in scan ids" % obj_id) def send(self): """send output signals for each selected items""" sItem = self.widget.dataList.selectedItems() if sItem and len(sItem) >= 1: selection = [ _item.data(qt.Qt.UserRole).get_identifier().to_str() for _item in sItem ] self.changeSelection(list_objs=selection) def _loadSettings(self): for scan in self._scanIDs: assert isinstance(scan, str) # kept for backward compatibility since 0.11. To be removed on the future version. if "@" in scan: entry, file_path = scan.split("@") nxtomo_scan = NXtomoScan(entry=entry, scan=file_path) self.addScan(nxtomo_scan) else: self.addScan(scan) def _updateSettings(self): self._scanIDs = [] for scan in self.widget.dataList._myitems: self._scanIDs.append(scan) def keyPressEvent(self, event): """ Forward: * delete key (shortcut orange and make sure the `delete` key will be interpreted we need to overwrite this function) * Ctrl + A to select all the scan """ modifiers = event.modifiers() key = event.key() if key == qt.Qt.Key_A and modifiers == qt.Qt.KeyboardModifier.ControlModifier: self.widget.dataList.keyPressEvent(event) if key == qt.Qt.Key_Delete: self.widget.removeSelectedDatasets() else: super().keyPressEvent(event) # expose API def setActiveScan(self, data): self.widget.setActiveData(data=data) def selectAll(self): return self.widget.selectAll() def n_scan(self): return self.widget.n_scan() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/DataTransfertOW.py0000644000175000017500000001346515153325210025677 0ustar00paynopaynofrom __future__ import annotations import functools import logging from orangewidget import gui, settings from orangewidget.widget import Input, Output from processview.core.manager import DatasetState, ProcessManager from silx.gui import qt import tomwer.core.process.control.scantransfer from orangecontrib.tomwer.orange.managedprocess import SuperviseOW from orangecontrib.tomwer.orange.settings import CallbackSettingsHandler from tomwer.core.process.control.scantransfer import ScanTransferTask from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui.control.datatransfert import DataTransfertSelector from tomwer.utils import docstring logger = logging.getLogger(__name__) class DataTransfertOW(SuperviseOW): """ A simple widget managing the copy of an incoming folder to an other one :param parent: the parent widget """ name = "data transfer" id = "orange.widgets.tomwer.foldertransfert" description = "This widget insure data transfer of the received data " description += "to the given directory" icon = "icons/folder-transfert.svg" priority = 30 keywords = [ "tomography", "transfert", "cp", "copy", "move", "file", "tomwer", "folder", ] ewokstaskclass = tomwer.core.process.control.scantransfer.ScanTransferTask settingsHandler = CallbackSettingsHandler() want_main_area = True resizing_enabled = True dest_dir_settings = settings.Setting(str()) """Parameters directly editabled from the TOFU interface""" scanready = qt.Signal(TomwerScanBase) """emit when scan ready""" class Inputs: data = Input(name="data", type=TomwerScanBase) class Outputs: data = Output(name="data", type=TomwerScanBase) def __init__(self, parent=None): super().__init__(parent) self._destDir = None self._forceSync = False self._threads = [] # define GUI self._widget = DataTransfertSelector( parent=self, rnice_option=True, default_root_folder=ScanTransferTask.getDefaultOutputDir(), ) self._layout = gui.vBox(self.mainArea, self.name).layout() self._layout.addWidget(self._widget) # signal / SLOT connection self.settingsHandler.addCallback(self._updateSettingsVals) self._widget.sigSelectionChanged.connect(self._updateDestDir) # setting configuration if self.dest_dir_settings != "": self._widget.setFolder(self.dest_dir_settings) def _requestFolder(self): # pragma: no cover """Launch a QFileDialog to ask the user the output directory""" dialog = qt.QFileDialog(self) dialog.setWindowTitle("Destination folder") dialog.setModal(1) dialog.setFileMode(qt.QFileDialog.DirectoryOnly) if not dialog.exec(): dialog.close() return None return dialog.selectedFiles()[0] def transfertDoneCallback(self, output_scan): if output_scan is None: return self.Outputs.data.send(output_scan) self.scanready.emit(output_scan) def _updateDestDir(self): self._destDir = self._widget.getFolder() def _updateSettingsVals(self): """function used to update the settings values""" self.dest_dir_settings = self._destDir @Inputs.data def process(self, scan): self._process(data=scan) def _process(self, data, move=False, force=True, noRsync=False): if data is None: return elif not isinstance(data, TomwerScanBase): raise TypeError("data is expected to be an instance of TomwerScanBase") inputs = { "data": data, "move": move, "overwrite": force, "noRsync": noRsync, "dest_dir": self._destDir, "block": self._forceSync, "serialize_output_data": False, } thread = ThreadDataTransfer( inputs=inputs, data=data, process=self, ) try: process = ScanTransferTask(inputs=inputs) except Exception as e: logger.error(e) else: dest_dir = process.getDestinationDir(data.path, ask_for_output=False) if dest_dir is not None: thread.finished.connect( functools.partial( self.transfertDoneCallback, data._deduce_transfert_scan( process.getDestinationDir(data.path) ), ) ) thread.start() self._threads.append(thread) @docstring(SuperviseOW) def reprocess(self, dataset): self.process(dataset) def setDestDir(self, dest_dir): self._destDir = dest_dir def setForceSync(self, sync): self._forceSync = sync def isCopying(self): # for now only move file is handled return False class ThreadDataTransfer(qt.QThread): def __init__(self, data, inputs, process) -> None: super().__init__() self._inputs = inputs self._data = data self._process = process def run(self): try: process = ScanTransferTask(inputs=self._inputs) process.run() except Exception as e: logger.error(f"data transfer failed. Reason is {e}") ProcessManager().notify_dataset_state( dataset=self._data, process=self._process, state=DatasetState.FAILED, details=str(e), ) else: ProcessManager().notify_dataset_state( dataset=self._data, process=self._process, state=DatasetState.SUCCEED, ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/DataValidatorOW.py0000644000175000017500000001321615153325210025646 0ustar00paynopaynofrom __future__ import annotations import logging from orangewidget import gui, settings from orangewidget.widget import Input, Output from processview.core.manager import DatasetState, ProcessManager from silx.gui import qt import tomwer.core.process.control.scanvalidator from orangecontrib.tomwer.orange.managedprocess import SuperviseOW from tomwer.core.scan.scanbase import TomwerScanBase, _TomwerBaseDock from tomwer.gui.control.datavalidator import DataValidator from tomwer.utils import docstring _logger = logging.getLogger(__name__) class DataValidatorOW(SuperviseOW): """a data viewer able to: - display slices (latest reconstructed if any) - display radios with or without normalization :param parent: the parent widget """ name = "scan validator" id = "orange.widgets.tomwer.datavalidator" description = """Widget displaying results of a reconstruction and asking to the user if he want to validate or not the reconstruction. User can also ask for some modification on the reconstruction parameters""" icon = "icons/validator.png" priority = 23 keywords = ["tomography", "file", "tomwer", "acquisition", "validation"] want_main_area = True resizing_enabled = True ewokstaskclass = tomwer.core.process.control.scanvalidator._ScanValidatorPlaceHolder _viewer_config = settings.Setting(dict()) _warnValManualShow = False """ used to know if the message to inform user about `validate manually` has already been displayed. This informative message will be show under the following conditions: * the scanValidator contains at least `_NB_SCAN_BF_WARN` * this dialog have never been showed in the current session. """ _NB_SCAN_BF_WARN = 10 """ Limit of stored scans before displaying the informative message about `validate manually` checkbox """ class Inputs: data = Input(name="data", type=TomwerScanBase) class Outputs: data = Output(name="data", type=TomwerScanBase) recons_params_changed = Output( name="change recons params", type=_TomwerBaseDock, ) def __init__(self, parent=None): SuperviseOW.__init__(self, parent) self._layout = gui.vBox(self.mainArea, self.name).layout() self._widget = DataValidator(parent=self) self._layout.addWidget(self._widget) self._setSettings(settings=self._viewer_config) # connect signal / slots self._widget.sigChangeReconsParams.connect(self._changeReconsParamsEmited) self._widget.sigScanReady.connect(self._scanReadyEmitted) self._widget._centralWidget.sigConfigChanged.connect(self._updateSettings) def close(self): if self._widget is not None: self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None super().close() @Inputs.data def addScan(self, scan): if scan is None: return assert isinstance(scan, TomwerScanBase) self._widget.addScan(scan) ProcessManager().notify_dataset_state( dataset=scan, process=self, state=DatasetState.WAIT_USER_VALIDATION ) # in the case the memory is full, the scan can have been already # validated and so not accessible if ( self._warnValManualShow is False and len(self._widget._scans) >= self._NB_SCAN_BF_WARN ): mess = ( "Please note that the scanValidator is actually storing %s " "scan(s). \n" "Scan need to be validated manually in order to continue " "the workflow processing. \n" "you can either validate scan manually or uncheck the " "`validate manually` check box." % self._NB_SCAN_BF_WARN ) mess = qt.QMessageBox(self, qt.QMessageBox.Information, mess) mess.setModal(False) mess.show() self._warnValManualShow = True if self.isValidationManual(): self.show() self.activateWindow() self.raise_() @docstring def reprocess(self, dataset): self.addScan(dataset) def isValidationManual(self): return self._widget.isValidationManual() def _changeReconsParamsEmited(self, scan): self.Outputs.recons_params_changed.send(scan) def _scanReadyEmitted(self, scan): ProcessManager().notify_dataset_state( dataset=scan, process=self, state=DatasetState.SUCCEED ) self.Outputs.data.send(scan) def _updateSettings(self): viewer = self._widget._centralWidget self._viewer_config["mode"] = viewer.getDisplayMode() # pylint: disable=E1137 self._viewer_config["slice_opt"] = ( # pylint: disable=E1137 viewer.getSliceOption() ) self._viewer_config["radio_opt"] = ( # pylint: disable=E1137 viewer.getRadioOption() ) def _setSettings(self, settings): viewer = self._widget._centralWidget old_state = viewer.blockSignals(True) if "mode" in settings: viewer.setDisplayMode(settings["mode"]) if "slice_opt" in settings: viewer.setSliceOption(settings["slice_opt"]) if "radio_opt" in settings: viewer.setRadioOption(settings["radio_opt"]) viewer.blockSignals(old_state) def getNScanToValidate(self): return len(self._widget._scans) def _validateScan(self, scan): self._widget._validateScan(scan=scan) def setAutomaticValidation(self, auto): self._widget.setAutomaticValidation(auto) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/DataWatcherOW.py0000644000175000017500000001364415153325210025323 0ustar00paynopaynofrom __future__ import annotations import functools import logging from orangewidget import gui, widget from orangewidget.settings import Setting from orangewidget.widget import Output import tomwer.core.process.control.datawatcher.datawatcher from tomwer.core.scan.blissscan import BlissScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui.control.datawatcher import DataWatcherWidget from ..utils import WidgetLongProcessing logger = logging.getLogger(__name__) class DataWatcherOW(widget.OWBaseWidget, WidgetLongProcessing, openclass=True): """ This widget is used to observe a selected folder and his sub-folders to detect if they are containing valid-finished acquisitions. """ name = "scan watcher" id = "orangecontrib.widgets.tomwer.datawatcherwidget.DataWatcherOW" description = ( "The widget will observe folder and sub folders of a given" " path and waiting for acquisition to be ended." " The widget will infinitely wait until an acquisition is " "ended. If an acquisition is ended then a signal " "containing the folder path is emitted." ) icon = "icons/datawatcher.svg" priority = 12 keywords = ["tomography", "file", "tomwer", "observer", "datawatcher"] want_main_area = True want_control_area = False resizing_enabled = True folderObserved = Setting(str()) acquisitionMethod = Setting(tuple()) linuxFilePatternSetting = Setting(str()) DEFAULT_DIRECTORY = "/lbsram/data/visitor" ewokstaskclass = ( tomwer.core.process.control.datawatcher.datawatcher.DataWatcherEwoksTask ) class Outputs: data = Output(name="data", type=TomwerScanBase) bliss_scan = Output( name="bliss data", type=BlissScan, doc="bliss scan to be process" ) def __init__(self, parent=None, displayAdvancement=True): """Simple class which will check advancement state of the acquisition for a specific folder :param parent: the parent widget """ widget.OWBaseWidget.__init__(self, parent) WidgetLongProcessing.__init__(self) self._widget = DataWatcherWidget(parent=self) self._widget.setFolderObserved(self.folderObserved) self._box = gui.vBox(self.mainArea, self.name) layout = self._box.layout() layout.addWidget(self._widget) # signal / slot connection self._widget.sigFolderObservedChanged.connect(self._updateSettings) self._widget.sigObservationModeChanged.connect(self._updateSettings) self._widget.sigObservationModeChanged.connect(self._setObsMethod) self._widget.sigFilterFileNamePatternChanged.connect( self._saveFilterLinuxPattern ) self._widget.sigFilterFileNamePatternChanged.connect( self._widget.setLinuxFilePattern ) self._widget.sigScanReady.connect(self._sendSignal) callback_start = functools.partial(self.processing_state, True, "watching on") self._widget.sigObservationStart.connect(callback_start) callback_end = functools.partial(self.processing_state, False, "watching off") self._widget.sigObservationEnd.connect(callback_end) self._loadSettings() def _loadSettings(self): if self.acquisitionMethod != tuple(): self.widget.getConfigWindow().setMode(self.acquisitionMethod) if self.folderObserved != str(): self.widget.setFolderObserved(self.folderObserved) if self.linuxFilePatternSetting != str(): # for the GUI self.widget._filterQLE.setText(self.linuxFilePatternSetting) # for providing it to the processing thread. Bad design but this widget shouldn't be used that # much and modifying internals is not the priority. self.widget.setLinuxFilePattern(self.linuxFilePatternSetting) def _updateSettings(self): self.folderObserved = self.widget.getFolderObserved() mode = self.widget.getConfigWindow().getMode() if mode is not None: self.acquisitionMethod = mode self.linuxFilePatternSetting = self.widget.getLinuxFilePattern() def _saveFilterLinuxPattern(self, *args, **kwargs): linuxFilePattern = self.widget.getFilterLinuxFileNamePattern() if linuxFilePattern is None: self.linuxFilePatternSetting = "" else: self.linuxFilePatternSetting = linuxFilePattern def _setObsMethod(self, mode): self.widget.setObsMethod(mode) @property def widget(self): return self._widget @property def currentStatus(self): return self._widget.currentStatus @property def sigTMStatusChanged(self): return self._widget.sigTMStatusChanged def resetStatus(self): self._widget.resetStatus() def _sendSignal(self, scan): if scan is None: pass elif isinstance(scan, TomwerScanBase): self.Outputs.data.send(scan) elif isinstance(scan, BlissScan): self.Outputs.bliss_scan.send(scan) else: raise TypeError( f"output is expected to be a {TomwerScanBase} or a {BlissScan}" ) def setFolderObserved(self, path): self.widget.setFolderObserved(path) def setObservation(self, b): self._widget.setObservation(b) def setTimeBreak(self, val): """ Set the time break between two loop observation :param val: time (in sec) """ self._widget.setWaitTimeBtwLoop(val) def startObservation(self): try: self.processing_info("processing") except Exception: pass self._widget.start() def stopObservation(self, succes=False): self.widget.stop(succes) try: self.Processing.clear() except Exception: pass def close(self): self.widget.close() super().close() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/EDF2NXTomomillOW.py0000644000175000017500000002262315153325210025574 0ustar00paynopaynofrom __future__ import annotations import logging from copy import copy from nxtomomill.models.edf2nx import EDF2nxModel from orangewidget import gui from silx.gui import qt from silx.gui.utils import blockSignals from orangecontrib.tomwer.orange.managedprocess import TomwerWithStackStack from orangecontrib.tomwer.widgets.control.NXTomomillMixIn import NXTomomillMixIn from tomwer.core.process.control.nxtomomill import EDFToNxProcess from tomwer.core.process.output import ProcessDataOutputDirMode from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.gui.control.datalist import EDFDataListMainWindow logger = logging.getLogger(__name__) class EDF2NXOW( TomwerWithStackStack, NXTomomillMixIn, ewokstaskclass=EDFToNxProcess, ): """ Widget to allow user to pick some bliss files and that will convert them to HDF5scan. """ name = "nxtomomill - edf2nx (Spec-EDF)" id = "orange.widgets.tomwer.control.NXTomomillOW.EDF2NXOW" description = "Convert folders with .edf to .nx" icon = "icons/edf2nx.svg" priority = 121 keywords = [ "edf", "nexus", "tomwer", "file", "convert", "NXTomo", "tomography", "edf2nx", "nxtomomill", ] want_main_area = True want_control_area = False resizing_enabled = True CONFIG_CLS = EDF2nxModel LOGGER = logger _ewoks_inputs_to_hide_from_orange = ( "edf_to_nx_configuration", "progress", "serialize_output_data", ) def __init__(self, parent=None): self.__configuration_cache = None # cache updated for each folder in order to match `_execute_ewoks_task` design TomwerWithStackStack.__init__(self, parent=parent) NXTomomillMixIn.__init__(self) _layout = gui.vBox(self.mainArea, self.name).layout() self.widget = EDFDataListMainWindow(parent=self) _layout.addWidget(self.widget) # for edf default output path is still the 'near to input file' self.widget._dialog._nxTomomillOutputWidget._inScanFolder.setChecked(True) # add 'convert auto' check box self._convertAutoCB = qt.QCheckBox( "convert automatically when edf scan send through 'edf scan' channel", self ) self._convertAutoCB.setChecked(True) _layout.addWidget(self._convertAutoCB) # connect signal / slot self.widget._sendSelectedButton.clicked.connect(self._sendSelected) self.widget.sigNXTomoCFGFileChanged.connect(self._saveNXTomoCfgFile) self.widget.sigUpdated.connect(self._updateSettings) self._convertAutoCB.toggled.connect(self._updateSettings) # set default configuration is no existing configuration file defined in the settings self.update_default_inputs( edf_to_nx_configuration=EDF2nxModel().to_nested_model().model_dump(), ) if isinstance(self.task_output_changed_callbacks, set): self.task_output_changed_callbacks.add(self._notify_state) elif isinstance(self.task_output_changed_callbacks, list): self.task_output_changed_callbacks.append(self._notify_state) else: raise NotImplementedError # handle settings self._loadSettings() def _updateSettings(self): # keep auto conversion setting self._ewoks_default_inputs[ # pylint: disable=E1137 "convert_auto_edfscan_channel" ] = self.convertAutoEDFScanReceivedFromChannel() # store scans self._scans = [] for scan in self.widget.datalist._myitems: self._scans.append(scan) # store output folder output_dir = self.widget.getOutputFolder() if isinstance(output_dir, ProcessDataOutputDirMode): output_dir = output_dir.value self._ewoks_default_inputs["output_dir"] = output_dir # pylint: disable=E1137 def convertAutoEDFScanReceivedFromChannel(self) -> bool: return self._convertAutoCB.isChecked() def setConvertAutoEDFScanReceivedFromChannel(self, checked: bool): self._convertAutoCB.setChecked(checked) def _loadSettings(self): with blockSignals(self.widget): for scan in self._scans: # pylint: disable=E1133 self.widget.add(scan) if ( "nxtomomill_cfg_file" in self._ewoks_default_inputs ): # pylint: disable=E1135 self._nxtomo_cfg_file = ( self._ewoks_default_inputs[ # pylint: disable=E1136 "nxtomomill_cfg_file" ] ) self.widget.setCFGFilePath(self._nxtomo_cfg_file) if "output_dir" in self._ewoks_default_inputs: # pylint: disable=E1135 self.widget.setOutputFolder( self._ewoks_default_inputs["output_dir"] # pylint: disable=E1136 ) if ( "convert_auto_edfscan_channel" in self._ewoks_default_inputs # pylint: disable=E1135 ): self.setConvertAutoEDFScanReceivedFromChannel( self._ewoks_default_inputs[ # pylint: disable=E1136 "convert_auto_edfscan_channel" ] ) def _convertAndSend(self, edf_scan: EDFTomoScan): # cache updated for each folder in order to match `_execute_ewoks_task` design # for edf2nx we need to update input dir from the DataList and output_dir from # the one requested by the user if not isinstance(edf_scan, EDFTomoScan): raise TypeError( f"edf_scan is expected to be a {EDFTomoScan} not {type(edf_scan)}" ) self.__configuration_cache = EDF2nxModel.from_dict( copy(self.get_default_input_values()["edf_to_nx_configuration"]) ) self.__configuration_cache.input_folder = edf_scan.path self.__configuration_cache.dataset_basename = edf_scan.dataset_basename output_file = EDFToNxProcess.deduce_output_file_path( folder_path=edf_scan.path, output_dir=self.widget.getOutputFolder(), scan=edf_scan, ) output_entry = "entry" self.__configuration_cache.output_file = output_file # keep 'edf_to_nx_configuration' up to date according to input folder and output_file updates self.update_default_inputs( edf_to_nx_configuration=self.__configuration_cache.to_dict() ) self.notify_on_going(scan=NXtomoScan(output_file, output_entry)) try: self._execute_ewoks_task( # pylint: disable=E1123 propagate=True, log_missing_inputs=False, ) except Exception: self._execute_ewoks_task(propagate=True) # pylint: disable=E1123, E1120 def get_task_inputs(self): return { "edf_to_nx_configuration": self.__configuration_cache.to_dict(), "serialize_output_data": False, } def handleNewSignals(self) -> None: """Invoked by the workflow signal propagation manager after all signals handlers have been called. """ # for now we want to avoid propagation any processing. # task will be executed only when the user validates the dialog edf_scan = super().get_task_inputs().get("edf_scan", None) if edf_scan is not None: if not isinstance(edf_scan, EDFTomoScan): raise TypeError("edf_scan is expected to be an instance of EDFTomoScan") self.add(edf_scan.path) if self.convertAutoEDFScanReceivedFromChannel(): self._convertAndSend(edf_scan) def _notify_state(self): try: task_executor = self.sender() task_suceeded = task_executor.succeeded config = task_executor.current_task.inputs.edf_to_nx_configuration config = EDF2nxModel.from_dict(config) scan = NXtomoScan( config.output_file, "entry", ) if task_suceeded: self.notify_succeed(scan=scan) else: self.notify_failed(scan=scan) except Exception as e: logger.error(f"failed to handle task finished callback. Reason is {e}") def _saveNXTomoCfgFile(self, cfg_file): super()._saveNXTomoCfgFile(cfg_file, keyword="edf_to_nx_configuration") def _sendSelected(self): """send all selected items to be converted""" self._canOverwriteOutputs = False for scan_id in self.widget.datalist._myitems: tomo_obj = self.widget.datalist.getEDFTomoScan(scan_id, None) if tomo_obj: self._convertAndSend(tomo_obj) def _sendAll(self): """send all items to be converted""" self._canOverwriteOutputs = False for scan_id in self.widget.datalist._myitems: tomo_obj = self.widget.datalist.getEDFTomoScan(scan_id, None) if tomo_obj: self._convertAndSend(tomo_obj) def keyPressEvent(self, event): # forward Ctrl+A to the list as the shift ease selection of all modifiers = event.modifiers() key = event.key() if key == qt.Qt.Key_A and modifiers == qt.Qt.KeyboardModifier.ControlModifier: self.widget._widget.datalist.keyPressEvent(event) super().keyPressEvent(event) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/EmailOW.py0000644000175000017500000000527515153325210024164 0ustar00paynopaynofrom orangewidget import gui from orangewidget.settings import Setting from silx.gui import qt from ewoksorange.bindings.owwidgets import OWEwoksWidgetNoThread import tomwer.core.process.control.emailnotifier from tomwer.core.utils.dictutils import concatenate_dict try: from ewoksnotify.gui.email import EmailWidget except ImportError: has_ewoksnotify = False else: has_ewoksnotify = True class EmailOW( OWEwoksWidgetNoThread, ewokstaskclass=tomwer.core.process.control.emailnotifier.TomoEmailTask, ): """ This widget will browse a folder and sub folder to find valid tomo scan project. Contrary to the scan watcher it will parse all folder / sub folders then stop. """ name = "email notifier" id = "orangecontrib.widgets.tomwer.control.EmailOW.EmailOW" description = ( "This widget will send an email to receivers when the input is provided. \n" ) icon = "icons/email.svg" priority = 146 keywords = [ "tomography", "tomwer", "tomo_obj", "email", "notifier", "notification", ] want_main_area = True want_control_area = False resizing_enabled = True _ewoks_default_inputs = Setting({"configuration": {}, "tomo_obj": None}) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if not has_ewoksnotify: raise ImportError( "ewoksnotify not install but required. Please run 'pip install ewoksnotify[full]'" ) self._widget = EmailWidget(parent=self) self._box = gui.vBox(self.mainArea, self.name) layout = self._box.layout() layout.addWidget(self._widget) # load settings self._widget.setConfiguration(self._ewoks_default_inputs) # connect signal / slot self._widget.sigChanged.connect(self._updateSettings) def _updateSettings(self): self._ewoks_default_inputs = { "configuration": self.getConfiguration(), "tomo_obj": None, } # expose some API def getConfiguration(self) -> dict: return self._widget.getConfiguration() def setConfiguration(self, config: dict): self._widget.setConfiguration(config.get("configuration", {})) def get_task_inputs(self): return concatenate_dict( super().get_task_inputs(), {"configuration": self.getConfiguration()}, ) def sizeHint(self): return qt.QSize(500, 200) def _execute_ewoks_task(self, *args, **kwargs): arguments = self._get_task_arguments() if arguments.get("inputs", {}).get("tomo_obj", None) is not None: super()._execute_ewoks_task(*args, **kwargs) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/FilterOW.py0000644000175000017500000000637015153325210024357 0ustar00paynopaynofrom __future__ import annotations import logging from orangewidget import gui from orangewidget.widget import Input, Output from processview.core.manager import DatasetState from silx.gui import qt import tomwer.core.process.conditions.filters from orangecontrib.tomwer.orange.managedprocess import SuperviseOW from tomwer.core.process.conditions import filters from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui.conditions.filter import FileNameFilterWidget from tomwer.utils import docstring logger = logging.getLogger(__name__) class NameFilterOW(SuperviseOW): name = "scan filter" id = "orange.widgets.tomwer.filterow" description = ( "Simple widget which filter some data directory if the name" "doesn't match with the pattern defined." ) icon = "icons/namefilter.svg" priority = 106 keywords = ["tomography", "selection", "tomwer", "folder", "filter"] want_main_area = True resizing_enabled = True ewokstaskclass = tomwer.core.process.conditions.filters.FileNameFilterTask class Inputs: data = Input(name="data", type=TomwerScanBase, multiple=True) class Outputs: data = Output(name="data", type=TomwerScanBase) def __init__(self, parent=None): """ """ super().__init__(parent) self.widget = FileNameFilterWidget(parent=self) self.widget.setContentsMargins(0, 0, 0, 0) layout = gui.vBox(self.mainArea, self.name).layout() layout.addWidget(self.widget) spacer = qt.QWidget(parent=self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) layout.addWidget(spacer) @Inputs.data def applyfilter(self, scan, *args, **kwargs): if scan is None: return if not isinstance(scan, TomwerScanBase): raise TypeError(f"{scan} is expected to be an instance of {TomwerScanBase}") process = filters.FileNameFilterTask( inputs={ "data": scan, "pattern": self.getPattern(), "filter_type": self.getActiveFilter(), "invert_result": self.invertFilterAction(), "serialize_output_data": False, # avoid spending time on scan serialization / deserialization when use orange } ) process.run() out = process.outputs.data if out is not None: self.set_dataset_state(dataset=scan, state=DatasetState.SUCCEED) logger.processSucceed(f"{scan} pass through filter") self._signalScanReady(scan) else: self.set_dataset_state(dataset=scan, state=DatasetState.FAILED) logger.processFailed(f"{scan} NOT pass through filter") @docstring(SuperviseOW) def reprocess(self, dataset): self.applyfilter(dataset) def _signalScanReady(self, scan): self.Outputs.data.send(scan) def getPattern(self): return self.widget.getPattern() def setPattern(self, pattern): self.widget.setPattern(pattern) def getActiveFilter(self): return self.widget.getActiveFilter() def setActiveFilter(self, filter): self.widget.setActiveFilter(filter) def invertFilterAction(self): return self.widget.invertFilterAction() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/NXTomomillMixIn.py0000644000175000017500000000664615153325210025701 0ustar00paynopaynoimport logging import os from orangewidget.settings import Setting _logger = logging.getLogger(__name__) class NXTomomillMixIn: """ MixIn class for nxtomomill + ewoks """ _scans = Setting(list()) _ewoks_default_inputs = Setting(dict()) CONFIG_CLS = None # logger to be used. Expected to be redefine by child class LOGGER = None # logger to be used. Expected to be redefine by child class def __init__(self, *args, **kwargs) -> None: self.__configuration_cache = None # cache updated for each folder in order to match `_execute_ewoks_task` design def add(self, *args, **kwargs): self.widget.add(*args, **kwargs) def _updateSettings(self): raise NotImplementedError("Base class") def _saveNXTomoCfgFile(self, cfg_file, keyword: str): """save the nxtomofile to the setttings""" assert ( self.CONFIG_CLS is not None ), "inheriting classes are expected to redefine CONFIG_CLS" self._ewoks_default_inputs["nxtomomill_cfg_file"] = ( cfg_file # pylint: disable=E1137 ) if os.path.exists(cfg_file): try: configuration = ( self.CONFIG_CLS.from_cfg_file(cfg_file) .to_nested_model() .model_dump() ) # pylint: disable=E1102 except Exception as e: self._logger.error( f"Fail to use configuration file {cfg_file}. Error is {e}. No conversion will be done." ) configuration = {} else: configuration = ( self.CONFIG_CLS().to_nested_model().model_dump() ) # pylint: disable=E1102 # make sure section name are upper case configuration = {key.upper(): value for key, value in configuration.items()} # hack: try to upgrade sample|detector_x|y_pixel_keys # otherwise has they have the same values and are tuples they have the same id and orange raises an # dump_literals raise a ValueError - check_relaxed - is a recursive structure for _, section_value in configuration.items(): elments_having_tuple_as_value = { key: value for key, value in section_value.items() if isinstance(value, tuple) } for key in elments_having_tuple_as_value: try: section_value[key] = list(section_value[key]) except KeyError: pass self.update_default_inputs( **{ keyword: configuration, } ) def _get_task_arguments(self): adict = super()._get_task_arguments() # pop progress as does not fully exists on the orange-widget-base adict.pop("progress", None) return adict def __new__(cls, *args, **kwargs): # ensure backward compatibility with 'static_input' static_input = kwargs.get("stored_settings", {}).get("static_input", None) if static_input not in (None, {}): _logger.warning( "static_input has been deprecated. Will be replaced by _ewoks_default_inputs in the workflow file. Please save the workflow to apply modifications" ) kwargs["stored_settings"]["_ewoks_default_inputs"] = static_input return super().__new__(cls, *args, **kwargs) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/NXTomomillOW.py0000644000175000017500000003202715153325210025172 0ustar00paynopaynofrom __future__ import annotations import logging import os from copy import copy from nxtomomill.models.h52nx import H52nxModel from orangewidget import gui from orangewidget.settings import Setting from silx.gui import qt from silx.gui.utils import blockSignals from orangecontrib.tomwer.orange.managedprocess import TomwerWithStackStack from orangecontrib.tomwer.widgets.control.NXTomomillMixIn import NXTomomillMixIn from tomwer.core.process.control.nxtomomill import H5ToNxProcess from tomwer.core.scan.blissscan import BlissScan from tomwer.core.scan.nxtomoscan import NXtomoScan, NXtomoScanIdentifier from tomwer.gui.control.datalist import BlissHDF5DataListMainWindow from tomwer.gui.control.nxtomomill import NXTomomillInput, OverwriteMessage from tomwer.core.process.output import ProcessDataOutputDirMode from ewoksorange.bindings.owwidgets import invalid_data logger = logging.getLogger(__name__) class NXTomomillOW( TomwerWithStackStack, NXTomomillMixIn, ewokstaskclass=H5ToNxProcess, ): """ Widget to allow user to pick some bliss files and that will convert them to HDF5scan. """ name = "nxtomomill h52nx (bliss-HDF5)" id = "orange.widgets.tomwer.control.NXTomomillOW.NXTomomillOW" description = ( "Read a bliss .h5 file and extract from it all possible" "NxTomo. When validated create a TomwerBaseScan for each " "file and entry" ) icon = "icons/nxtomomill.svg" priority = 120 keywords = [ "hdf5", "nexus", "tomwer", "file", "convert", "NXTomo", "tomography", "nxtomomill", "h52nx", ] want_main_area = True want_control_area = False resizing_enabled = True CONFIG_CLS = H52nxModel LOGGER = logger _ewoks_inputs_to_hide_from_orange = ( "h5_to_nx_configuration", "progress", "serialize_output_data", ) _detector_mechanical_flips = Setting(tuple([False, False])) def __init__(self, parent=None): TomwerWithStackStack.__init__(self, parent=parent) NXTomomillMixIn.__init__(self) _layout = gui.vBox(self.mainArea, self.name).layout() self.widget = BlissHDF5DataListMainWindow(parent=self) _layout.addWidget(self.widget) self.__request_input = True # do we ask the user for input if missing self._inputGUI = None """Gui with cache for missing field in files to be converted""" self._canOverwriteOutputs = False """Cache to know if we have to ask user permission for overwriting""" # expose API self.n_scan = self.widget.n_scan # alias used for the 'simple workflow' for now self.start = self._sendAll # connect signal / slot self.widget._sendSelectedButton.clicked.connect(self._sendSelected) self.widget.sigNXTomoCFGFileChanged.connect(self._saveNXTomoCfgFile) self.widget.sigUpdated.connect(self._updateSettings) # set default configuration is no existing configuration file defined in the settings # note: historically the model was a 'nested one'. Let's keep it as it is for now # to avoid any breaking modification default_config = H52nxModel().to_nested_model() default_config = { key.upper(): value for key, value in default_config.model_dump().items() } self.update_default_inputs( h5_to_nx_configuration=default_config, ) if isinstance(self.task_output_changed_callbacks, set): self.task_output_changed_callbacks.add(self._notify_state) elif isinstance(self.task_output_changed_callbacks, list): self.task_output_changed_callbacks.append(self._notify_state) else: raise NotImplementedError # handle settings self._loadSettings() def _updateSettings(self): self._scans = [] for scan in self.widget.datalist._myitems: # kept for backward compatibility since 0.11. To be removed on the future version. if "@" in scan: entry, file_path = scan.split("@") nxtomo_scan = NXtomoScan(entry=entry, scan=file_path) self.add(nxtomo_scan) else: self._scans.append(scan) output_dir = self.widget.getOutputFolder() if isinstance(output_dir, ProcessDataOutputDirMode): output_dir = output_dir.value self._ewoks_default_inputs["output_dir"] = output_dir # pylint: disable=E1137 self._detector_mechanical_flips = self.widget._dialog.getMechanicalFlips() @property def request_input(self): return self.__request_input @request_input.setter def request_input(self, request): self.__request_input = request def get_task_inputs(self): return { "h5_to_nx_configuration": self.__configuration_cache.to_dict(), "serialize_output_data": False, } def handleNewSignals(self) -> None: """Invoked by the workflow signal propagation manager after all signals handlers have been called. """ # for now we want to avoid propagation any processing. # task will be executed only when the user validates the dialog bliss_scan = super().get_task_inputs().get("bliss_scan", None) if bliss_scan is not None: if not isinstance(bliss_scan, BlissScan): raise TypeError("bliss_scan is expected to be an instance of BlissScan") self.add(bliss_scan.master_file) def _convertAndSend(self, bliss_url: str): """ :param bliss_url: string at entry@file format """ logger.processStarted(f"Start translate {bliss_url} to NXTomo") self.__configuration_cache = H52nxModel.from_dict( copy(self.get_default_input_values()["h5_to_nx_configuration"]) ) identifier = NXtomoScanIdentifier.from_str(bliss_url) bliss_scan = BlissScan( master_file=identifier.file_path, entry=identifier.data_path, proposal_file=None, ) output_file_path = H5ToNxProcess.deduce_output_file_path( bliss_scan.master_file, output_dir=self.widget.getOutputFolder(), scan=bliss_scan, ) self.__configuration_cache.input_file = bliss_scan.master_file self.__configuration_cache.output_file = output_file_path self.__configuration_cache.entries = (bliss_scan.entry,) self.__configuration_cache.single_file = False self.__configuration_cache.overwrite = True self.__configuration_cache.request_input = self.request_input self.__configuration_cache.file_extension = ".nx" ( self.__configuration_cache.mechanical_lr_flip, self.__configuration_cache.mechanical_ud_flip, ) = self.widget._dialog.getMechanicalFlips() self._processBlissScan(bliss_scan) def _userAgreeForOverwrite(self, file_path): if self._canOverwriteOutputs: return True else: msg = OverwriteMessage(self) text = "NXtomomill will overwrite \n %s. Do you agree ?" % file_path msg.setText(text) if msg.exec(): self._canOverwriteOutputs = msg.canOverwriteAll() return True else: return False def _processBlissScan(self, bliss_scan): if bliss_scan is None: return output_file_path = H5ToNxProcess.deduce_output_file_path( bliss_scan.master_file, output_dir=self.widget.getOutputFolder(), scan=bliss_scan, ) # check user has rights to write on the folder dirname = os.path.dirname(output_file_path) if os.path.exists(dirname) and not os.access(dirname, os.W_OK): msg = qt.QMessageBox(self) msg.setIcon(qt.QMessageBox.Warning) text = f"You don't have write rights on '{dirname}'. Unable to generate the nexus file associated to {str(bliss_scan)}" msg.setWindowTitle("No rights to write") msg.setText(text) msg.show() return # check if need to overwrite the file elif os.path.exists(output_file_path): if not self._userAgreeForOverwrite(output_file_path): return # keep 'h5_to_nx_configuration' up to date according to input folder and output_file updates self.update_default_inputs( h5_to_nx_configuration=self.__configuration_cache.to_dict() ) try: self._execute_ewoks_task( # pylint: disable=E1123 propagate=True, log_missing_inputs=False, ) except Exception: self._execute_ewoks_task(propagate=True) # pylint: disable=E1123, E1120 def _loadSettings(self): with blockSignals(self.widget): for scan in self._scans: assert isinstance(scan, str) try: self.widget.add(scan) except Exception as e: logger.error(f"Fail to add {scan}. Error is {e}") else: logger.warning(f"{scan} is an invalid link to a file") if ( "nxtomomill_cfg_file" in self._ewoks_default_inputs ): # pylint: disable=E1135 nxtomo_cfg_file = self._ewoks_default_inputs[ # pylint: disable=E1136 "nxtomomill_cfg_file" ] self.widget.setCFGFilePath(nxtomo_cfg_file) if "output_dir" in self._ewoks_default_inputs: # pylint: disable=E1135 self.widget.setOutputFolder( self._ewoks_default_inputs["output_dir"] # pylint: disable=E1136 ) if len(self._detector_mechanical_flips) == 2: self.widget._dialog.setMechanicalFlips(*self._detector_mechanical_flips) def _saveNXTomoCfgFile(self, cfg_file): super()._saveNXTomoCfgFile(cfg_file, keyword="h5_to_nx_configuration") def _sendSelected(self): """Send a signal for selected scans found to the next widget""" self._inputGUI = NXTomomillInput() # reset the GUI for input (reset all the cache for answers) self._canOverwriteOutputs = False for bliss_url in self.widget.datalist.selectedItems(): data = bliss_url.data(qt.Qt.UserRole) assert isinstance(data, NXtomoScan) identifier = data.get_identifier() self._inputGUI.setBlissScan( entry=identifier.data_path, file_path=identifier.file_path ) self._convertAndSend(identifier.to_str()) def _sendAll(self): """Send a signal for each scan found to the next widget""" self._inputGUI = NXTomomillInput() # reset the GUI for input (reset all the cache for answers) self._canOverwriteOutputs = False for bliss_url in self.widget.datalist._myitems.values(): data = bliss_url.data(qt.Qt.UserRole) identifier = data.get_identifier() assert isinstance(data, NXtomoScan) self._inputGUI.setBlissScan( entry=identifier.data_path, file_path=identifier.file_path ) self._convertAndSend(identifier.to_str()) def _notify_state(self): try: task_executor = self.sender() task_suceeded = task_executor.succeeded config = task_executor.current_task.inputs.h5_to_nx_configuration config = H52nxModel.from_dict(config) scan = task_executor.current_task.outputs.data if task_suceeded: self.notify_succeed(scan=scan) else: self.notify_failed(scan=scan) except Exception as e: logger.error(f"failed to handle task finished callback. Reason is {e}") def trigger_downstream(self) -> None: for ewoksname, var in self.get_task_outputs().items(): # note: for now we want to trigger 'data' for each items of 'datas' if ewoksname == "series" and not ( invalid_data.is_invalid_data(var.value) or var.value is None ): for data in var.value: data_channel = self._get_output_signal("data") data_channel.send(data) serie_channel = self._get_output_signal("series") # then send the list of value / series (also know as datas) serie_channel.send(var.value) elif ewoksname == "data" and not ( invalid_data.is_invalid_data(var.value) or var.value is None ): pass # handle by 'series' in this case def keyPressEvent(self, event): # forward Ctrl+A to the list as the shift ease selection of all modifiers = event.modifiers() key = event.key() if key == qt.Qt.Key_A and modifiers == qt.Qt.KeyboardModifier.ControlModifier: self.widget._widget.datalist.keyPressEvent(event) super().keyPressEvent(event) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/NXtomoConcatenate.py0000644000175000017500000001445615153325210026261 0ustar00paynopaynofrom __future__ import annotations import logging from tomoscan.series import Series from orangewidget import gui from orangewidget.settings import Setting from orangewidget.widget import Input, Output from orangecontrib.tomwer.orange.managedprocess import TomwerWithStackStack from silx.gui import qt from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.process.control.nxtomoconcatenate import ( ConcatenateNXtomoTask, format_output_location, ) from tomwer.gui.control.series.nxtomoconcatenate import NXtomoConcatenateWidget _logger = logging.getLogger(__name__) class NXtomoConcatenateOW( TomwerWithStackStack, ewokstaskclass=ConcatenateNXtomoTask, ): """ widget used to call do a concatenation of a serie (of NXtomo) into a single Nxtomo :param parent: the parent widget """ # note of this widget should be the one registered on the documentation name = "NXtomo concatenation" id = "orangecontrib.tomwer.widgets.control.NXtomoConcatenate.NXtomoConcatenate" description = "concatenate a serie (of NXtomo / NXtomoScan) into a single Nxtomo" icon = "icons/concatenate_nxtomos.svg" priority = 200 keywords = [ "tomography", "nabu", "reconstruction", "concatenate", "NXtomo", "data", "NXtomoScan", ] want_main_area = True want_control_area = False resizing_enabled = True _ewoks_default_inputs = Setting( { "series": None, "output_file": "{common_path}/concatenate.nx", "output_entry": "entry0000", "overwrite": False, } ) _ewoks_inputs_to_hide_from_orange = ( "output_entry", "serialize_output_data", "progress", "output_file", "overwrite", ) TIMEOUT = 30 class Inputs: series = Input( name="series", type=Series, doc="series to concatenate", default=True, multiple=False, ) class Outputs: data = Output(name="data", type=TomwerScanBase, doc="concatenated scan") LOGGER = _logger def __init__(self, parent=None): super().__init__(parent) self.__series = None # gui definition _layout = gui.vBox(self.mainArea, self.name).layout() self.widget = NXtomoConcatenateWidget(parent=self) _layout.addWidget(self.widget) ## connect signal / slot self.widget.sigConfigChanged.connect(self._updateSettings) if isinstance(self.task_output_changed_callbacks, set): self.task_output_changed_callbacks.add(self._notify_state) elif isinstance(self.task_output_changed_callbacks, list): self.task_output_changed_callbacks.append(self._notify_state) else: raise NotImplementedError ## handle settings self._loadSettings() self.task_executor_queue.sigComputationStarted.connect(self._newTaskStarted) def _updateSettings(self): config = self.widget.getConfiguration() for key in ("output_file", "output_entry", "overwrite"): self._ewoks_default_inputs[key] = config[key] # pylint: disable=E1137 @property def request_input(self): return self.__request_input @request_input.setter def request_input(self, request): self.__request_input = request def get_task_inputs(self): assert self.__series is not None return { "series": self.__series, "output_file": self.widget.getConfiguration()["output_file"], "output_entry": self.widget.getConfiguration()["output_entry"], "overwrite": self.widget.getConfiguration()["overwrite"], } def handleNewSignals(self) -> None: """Invoked by the workflow signal propagation manager after all signals handlers have been called. """ # for now we want to avoid propagation any processing. # task will be executed only when the user validates the dialog data = super().get_task_inputs().get("data", None) if data is not None: if not isinstance(data, NXtomoScan): raise TypeError( f"data is expected to be an instance of NXtomoScan. {type(data)} are not handled" ) self.add(data.path) def _loadSettings(self): self.widget.setConfiguration(self._ewoks_default_inputs) def _newTaskStarted(self): try: task_executor = self.sender() scan_about_to_be_created = NXtomoScan( scan=format_output_location( file_path=task_executor.current_task.inputs.output_file_path, series=task_executor.current_task.inputs.series, ), entry=task_executor.current_task.inputs.output_entry, ) self.notify_on_going(scan_about_to_be_created) except Exception: pass def _notify_state(self): try: task_executor = self.sender() task_suceeded = task_executor.succeeded scan = task_executor.current_task.outputs.data if task_suceeded: self.notify_succeed(scan=scan) else: self.notify_failed(scan=scan) except Exception as e: _logger.error(f"failed to handle task finished callback. Reason is {e}") @Inputs.series def process_series(self, series: Series | None): self._process_series(series=series) def _process_series(self, series: Series | None): if series is None: return else: self.__series = series scan_about_to_be_created = NXtomoScan( scan=format_output_location( file_path=self.getOutputFilePath(), series=series, ), entry=self.getOutputEntry(), ) self.notify_pending(scan=scan_about_to_be_created) self.execute_ewoks_task() def sizeHint(self) -> qt.QSize: return qt.QSize(500, 200) # expose API def getOutputFilePath(self) -> str: return self.widget.getOutputFilePath() def getOutputEntry(self) -> str: return self.widget.getOutputEntry() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/NotifierOW.py0000644000175000017500000000633515153325210024712 0ustar00paynopaynofrom __future__ import annotations from orangewidget import gui, settings, widget from orangewidget.widget import Input, Output from silx.gui import qt from tomwer.core.tomwer_object import TomwerObject from tomwer.core.utils.deprecation import deprecated_warning class NotifierWidgetOW(widget.OWBaseWidget): """ simple widget which pop up and closes when recive a new object """ name = "notifier" id = "orangecontrib.tomwer.widgets.control.NotifierOW" description = "Simple widget which pop up for 2 second when recives a new object" icon = "icons/notification.png" priority = 145 keywords = ["control", "notifier", "notification"] want_main_area = True want_control_area = False resizing_enabled = False _muted = settings.Setting(False) class Inputs: tomo_obj = Input(name="tomo_obj", type=TomwerObject, multiple=True) class Outputs: tomo_obj = Output(name="tomo_obj", type=TomwerObject) def __init__(self, parent=None): super().__init__(parent) deprecated_warning( type_="class", name="orangecontrib.tomwer.widgets.control.NotifierOW", replacement="orangecontrib.ewoksnotify.ToneNotifierOW", reason="moved to ewoksnotify (pip install ewoksnotify[full] to get the orange widget)", since_version="1.4", ) self.pop_up = None layout = gui.vBox(self.mainArea, self.name).layout() self._soundButton = qt.QPushButton(parent=self) self._soundButton.setMinimumSize(150, 100) self._soundButton.setCheckable(True) layout.addWidget(self._soundButton) self._updateButtonIcon() # connect signal / slot self._soundButton.toggled.connect(self._switchMute) def _switchMute(self): self._muted = not self._muted self._updateButtonIcon() @Inputs.tomo_obj def process(self, tomo_obj, *args, **kwargs): self.notify(tomo_obj) self.Outputs.tomo_obj.send(tomo_obj) def _updateButtonIcon(self): style = qt.QApplication.style() if self._muted: icon = style.standardIcon(qt.QStyle.SP_MediaVolumeMuted) else: icon = style.standardIcon(qt.QStyle.SP_MediaVolume) self._soundButton.setIcon(icon) def notify(self, tomo_obj): if self.pop_up is not None: self.pop_up.close() if not self._muted: # emit sound when requested try: qt.QApplication.beep() except Exception: pass self.pop_up = NotificationMessage() text = f"Object {tomo_obj} received." self.pop_up.setText(text) self.pop_up.show() class NotificationMessage(qt.QMessageBox): EXPOSITION_TIME = 3000 # in ms def __init__(self) -> None: super().__init__() self.setModal(False) self.setIcon(qt.QMessageBox.Information) self.addButton( f"Ok - will close automatically after {self.EXPOSITION_TIME / 1000}s", qt.QMessageBox.YesRole, ) def show(self): super().show() timer = qt.QTimer(self) timer.singleShot( self.EXPOSITION_TIME, self.close, ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/ReduceDarkFlatSelectorOW.py0000644000175000017500000000543115153325210027450 0ustar00paynopaynofrom __future__ import annotations import logging from orangewidget import gui from orangewidget.settings import Setting from orangewidget.widget import Input, Output, OWBaseWidget from tomwer.gui.control.reducedarkflatselector import ReduceDarkFlatSelectorDialog logger = logging.getLogger(__name__) class ReduceDarkFlatSelectorOW(OWBaseWidget, openclass=True): name = "reduce dark-flat selector" id = "orangecontrib.widgets.tomwer.control.ReduceDarkFlatSelectorOW.ReduceDarkFlatSelectorOW" description = "Allow user to select one or several reduced dark / flat" icon = "icons/reduced_darkflat_selector.svg" priority = 242 keywords = [ "tomography", "selection", "tomwer", "scan", "data", "reduce", "dark", "flat", "reduced", ] want_main_area = True want_control_area = False resizing_enabled = True _configuration = Setting(tuple()) class Inputs: in_reduced_frames = Input( name="reduced frames", type=dict, doc="dict of containing reduced frames (either dark or flat)", multiple=True, ) class Outputs: out_reduced_darks = Output( name="reduced dark(s)", doc="dict of containing reduced darks(s)", type=dict, ) out_reduced_flats = Output( name="reduced flat(s)", type=dict, doc="dict of containing reduced flat(s)", ) def __init__(self, parent=None): """ """ super().__init__(parent) self._dialog = ReduceDarkFlatSelectorDialog(parent=self) self._layout = gui.vBox(self.mainArea, self.name).layout() self._layout.addWidget(self._dialog) self._dialog.setConfiguration(self._configuration) # connect signal / slot self._dialog.sigSelectActiveAsDarks.connect(self._sendDarks) self._dialog.sigSelectActiveAsFlats.connect(self._sendFlats) self._dialog.sigUpdated.connect(self._updateConfiguration) def _updateConfiguration(self): self._configuration = self.getConfiguration() def _sendDarks(self, darks: dict): self.Outputs.out_reduced_darks.send(darks) def _sendFlats(self, flats: dict): self.Outputs.out_reduced_flats.send(flats) @Inputs.in_reduced_frames def addReduceFrames(self, reduce_frames: dict | None, *args, **kwargs): if reduce_frames is not None: self._dialog.addReduceFrames(reduce_frames) # expose API def getConfiguration(self) -> tuple: return self._dialog.getConfiguration() def setConfiguration(self, configuration: tuple) -> None: if configuration is None: return return self._dialog.setConfiguration(configuration) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/SingleTomoObjOW.py0000644000175000017500000001251715153325210025645 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging import tomoscan.esrf.scan.utils from orangewidget import gui from orangewidget.settings import Setting from orangewidget.widget import Input, Output, OWBaseWidget import tomwer.core.process.control.singletomoobj from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.tomwer_object import TomwerObject from tomwer.core.volume.volumefactory import VolumeFactory from tomwer.gui.control.singletomoobj import SingleTomoObj _logger = logging.getLogger(__name__) class SingleTomoObjOW(OWBaseWidget, openclass=True): name = "single tomo obj" id = "orange.widgets.tomwer.control.SingleScanOW.SingleScanOW" description = "Definition of a single dataset" icon = "icons/single_tomo_obj.svg" priority = 51 keywords = ["tomography", "NXtomo", "tomwer", "folder", "scan"] want_main_area = True want_control_area = False resizing_enabled = True ewokstaskclass = tomwer.core.process.control.singletomoobj.SingleTomoObjProcess _tomo_obj_setting = Setting(str()) class Inputs: tomo_obj = Input(name="tomo_obj", type=TomwerObject) class Outputs: tomo_obj = Output( name="tomo_obj", type=TomwerObject, doc="one object to be process" ) reduced_darks = Output( name="reduced dark(s)", type=dict, doc="Reduced darks as a dict", ) reduced_flats = Output( name="reduced flat(s)", type=dict, doc="Reduced flats as a dict", ) relative_reduced_darks = Output( name="relative reduced dark(s)", type=dict, doc="Reduced darks as a dict. Indexes are provided as relative so in [0.0, 1.0[", ) relative_reduced_flats = Output( name="relative reduced flat(s)", type=dict, doc="Reduced flats as a dict. Indexes are provided as relative so in [0.0, 1.0[", ) def __init__(self, parent=None): super().__init__(parent) self._latest_received_scan = None # small work around to keep in scan processing cache and avoid recomputing it if not necessary self.widget = SingleTomoObj(parent=self) self.widget.sigTomoObjChanged.connect(self._updateSettings) self.widget.sigTomoObjChanged.connect(self._triggerObjDownstream) self._loadSettings() layout = gui.vBox(self.mainArea, self.name).layout() layout.addWidget(self.widget) @Inputs.tomo_obj def add(self, tomo_obj): if tomo_obj is None: return self.widget.setTomoObject(tomo_obj) def _loadSettings(self): if self._tomo_obj_setting != str(): self.widget.setTomoObject(self._tomo_obj_setting) def _updateSettings(self): self._tomo_obj_setting = self.widget.getTomoObjIdentifier() def _triggerObjDownstream(self): obj_identifier = self.widget.getTomoObjIdentifier() if ( self._latest_received_scan is not None and self._latest_received_scan.get_identifier() == obj_identifier ): data = self._latest_received_scan else: try: data = VolumeFactory.create_tomo_object_from_identifier(obj_identifier) except: # noqa E722 try: data = ScanFactory.create_tomo_object_from_identifier( obj_identifier ) except: # noqa E722 _logger.warning( f"Unable to find an obj with {obj_identifier} as identifier" ) return self.Outputs.tomo_obj.send(data) # if the data is a scan then provide also access to the reduced frames. Can be convenient if isinstance(data, TomwerScanBase): if data.reduced_darks not in (None, {}): reduced_darks = data.reduced_darks self.Outputs.reduced_darks.send(reduced_darks) # we want to send those in relative position to have something generic. This is a convention for now reduced_darks = ( tomoscan.esrf.scan.utils.from_absolute_reduced_frames_to_relative( reduced_frames=data.reduced_darks, scan=data ) ) reduced_darks["reduce_frames_name"] = ( f"darks from {data.get_identifier().short_description()}" ) self.Outputs.relative_reduced_darks.send(reduced_darks) if data.reduced_flats not in (None, {}): reduced_flats = data.reduced_flats self.Outputs.reduced_flats.send(reduced_flats) # we want to send those in relative position to have something generic. This is a convention for now reduced_flats = ( tomoscan.esrf.scan.utils.from_absolute_reduced_frames_to_relative( reduced_frames=data.reduced_flats, scan=data ) ) reduced_flats["reduce_frames_name"] = ( f"flats from {data.get_identifier().short_description()}" ) self.Outputs.relative_reduced_flats.send(reduced_flats) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/TimerOW.py0000644000175000017500000000656215153325210024215 0ustar00paynopaynofrom __future__ import annotations import functools import logging from orangewidget import gui from orangewidget.settings import Setting from orangewidget.widget import Input, Output from processview.core.manager import DatasetState, ProcessManager from silx.gui import qt import tomwer.core.process.control.timer from orangecontrib.tomwer.orange.managedprocess import SuperviseOW from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.utils import docstring from tomwer.core.utils.deprecation import deprecated_warning _logger = logging.getLogger(__name__) class _TimerWidget(qt.QWidget): def __init__(self, parent, _time=None): if _time is not None: assert type(_time) is int qt.QWidget.__init__(self, parent) self.setLayout(qt.QGridLayout()) self.layout().addWidget(qt.QLabel("time to wait (in sec):", parent=self), 0, 0) self._timeLE = qt.QSpinBox(parent=self) self._timeLE.setMinimum(0) self._timeLE.setValue(_time or 1) self.layout().addWidget(self._timeLE, 0, 1) spacer = qt.QWidget(parent=self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer, 1, 0) # expose API self.timeChanged = self._timeLE.valueChanged class TimerOW(SuperviseOW): name = "timer" id = "orange.widgets.tomwer.filterow" description = ( "Simple widget which wait for a defined amont of time and" "release the data" ) icon = "icons/time.png" priority = 200 keywords = ["control", "timer", "wait", "data"] want_main_area = True resizing_enabled = True _waiting_time = Setting(int(1)) ewokstaskclass = tomwer.core.process.control.timer.TimerTask class Inputs: data = Input(name="data", type=TomwerScanBase, multiple=True) class Outputs: data = Output(name="data", type=TomwerScanBase) def __init__(self, parent=None): """ """ SuperviseOW.__init__(self, parent) deprecated_warning( type_="class", name="orangecontrib.tomwer.widgets.control.TimerOW", replacement="orangecontrib.ewoksnotify.WaiterOW", reason="moved to ewoksnotify (pip install ewoksnotify[full] to get the orange widget)", since_version="1.4", ) self._widget = _TimerWidget(parent=self, _time=self._waiting_time) self._widget.setContentsMargins(0, 0, 0, 0) layout = gui.vBox(self.mainArea, self.name).layout() layout.addWidget(self._widget) self._widget.timeChanged.connect(self._updateTime) @Inputs.data def process(self, scan, *args, **kwargs): if scan is None: return ProcessManager().notify_dataset_state( dataset=scan, process=self, state=DatasetState.ON_GOING, ) callback = functools.partial(self._get_out, scan) _timer = qt.QTimer(self) _timer.singleShot(self._waiting_time * 1000, callback) def _updateTime(self, newTime): self._waiting_time = newTime def _get_out(self, scan): ProcessManager().notify_dataset_state( dataset=scan, process=self, state=DatasetState.SUCCEED, ) self.Outputs.data.send(scan) @docstring(SuperviseOW) def reprocess(self, dataset): self.process(dataset) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/TomoObjSeriesOW.py0000644000175000017500000000356115153325210025655 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging from orangewidget import gui from orangewidget.widget import Input, Output, OWBaseWidget from tomoscan.series import Series import tomwer.core.process.control.tomoobjseries from tomwer.core.tomwer_object import TomwerObject from tomwer.gui.control.series.seriescreator import SeriesWidgetDialog logger = logging.getLogger(__name__) class TomoObjSeriesOW(OWBaseWidget, openclass=True): name = "series of objects" id = "orange.widgets.tomwer.tomoobjseriesow" description = "Allow user define a series of object that will be defined as a Series (grouped together and can be used within a purpose like stitching)" icon = "icons/tomoobjseries.svg" priority = 55 keywords = ["tomography", "selection", "tomwer", "series", "group"] ewokstaskclass = tomwer.core.process.control.tomoobjseries._TomoobjseriesPlaceHolder want_main_area = True want_control_area = False resizing_enabled = True class Inputs: tomo_obj = Input(name="tomo obj", type=TomwerObject, multiple=True) class Outputs: series = Output(name="series", type=Series) def __init__(self, parent=None): """ """ super().__init__(parent) layout = gui.vBox(self.mainArea, self.name).layout() self._widget = SeriesWidgetDialog(self) layout.addWidget(self._widget) # connect signal / slot self._widget.sigSeriesSelected.connect(self._send_series) @Inputs.tomo_obj def addTomoObj(self, tomo_obj, *args, **kwargs): if tomo_obj is not None: self._widget.add(tomo_obj) def _send_series(self, series: Series): if not isinstance(series, Series): raise TypeError( f"series is expected to be an instance of {Series}. Not {type(series)}" ) self.Outputs.series.send(series) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/VolumeSelector.py0000644000175000017500000000765515153325210025643 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging from orangewidget import gui from orangewidget.settings import Setting from orangewidget.widget import Input, Output, OWBaseWidget from silx.gui import qt import tomwer.core.process.control.volumeselector from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.volume.volumebase import TomwerVolumeBase from tomwer.gui.control.volumeselectorwidget import VolumeSelectorWidget logger = logging.getLogger(__name__) class VolumeSelectorOW(OWBaseWidget, openclass=True): name = "volume selector" id = "orange.widgets.tomwer.volumeselector" description = ( "List all received volumes. Then user can select a specific" "volume to be passed to the next widget." ) icon = "icons/volumeselector.svg" priority = 62 keywords = ["tomography", "selection", "tomwer", "volume"] ewokstaskclass = ( tomwer.core.process.control.volumeselector._VolumeSelectorPlaceHolder ) want_main_area = True want_control_area = False resizing_enabled = True _scanIDs = Setting(list()) class Inputs: volume = Input(name="volume", type=TomwerVolumeBase, multiple=True) class Outputs: volume = Output(name="volume", type=TomwerVolumeBase) def __init__(self, parent=None): """ """ super().__init__(parent) self.widget = VolumeSelectorWidget(parent=self) self._loadSettings() self.widget.sigUpdated.connect(self._updateSettings) self.widget.sigSelectionChanged.connect(self.changeSelection) layout = gui.vBox(self.mainArea, self.name).layout() layout.addWidget(self.widget) # expose API self.setActiveScan = self.widget.setActiveData self.selectAll = self.widget.selectAll self.add = self.widget.add @Inputs.volume def _volumeReceived(self, volume, *args, **kwargs): self.addVolume(volume) def addVolume(self, volume): if volume is not None: self.widget.add(volume) def removeVolume(self, volume): if volume is not None: self.widget.remove(volume) def changeSelection(self, list_volume): if list_volume: for volume_id in list_volume: volume = self.widget.dataList.getVolume(volume_id, None) if volume is not None: assert isinstance(volume, TomwerVolumeBase) self.Outputs.volume.send(volume) else: logger.error(f"{volume_id} not found the list") def send(self): """send output signals for each selected items""" sItem = self.widget.dataList.selectedItems() if sItem and len(sItem) >= 1: selection = [_item.text() for _item in sItem] self.changeSelection(list_volume=selection) def _loadSettings(self): for scan in self._scanIDs: assert isinstance(scan, str) # kept for backward compatibility since 0.11. To be removed on the future version. if "@" in scan: entry, file_path = scan.split("@") nxtomo_scan = NXtomoScan(entry=entry, scan=file_path) self.addVolume(nxtomo_scan) else: self.addVolume(scan) def _updateSettings(self): self._scanIDs = [] for scan in self.widget.dataList._myitems: self._scanIDs.append(scan) def keyPressEvent(self, event): """ To shortcut orange and make sure the `delete` key will be interpreted we need to overwrite this function """ modifiers = event.modifiers() key = event.key() if key == qt.Qt.Key_A and modifiers == qt.Qt.KeyboardModifier.ControlModifier: self.widget.dataList.keyPressEvent(event) if key == qt.Qt.Key_Delete: self.widget._callbackRemoveSelectedDatasets() else: super().keyPressEvent(event) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/_DataListenerBaseClass.py0000644000175000017500000002131015153325210027152 0ustar00paynopaynofrom __future__ import annotations from orangewidget import gui, settings, widget from orangewidget.widget import Output from silx.gui import qt import os from orangecontrib.tomwer.widgets.utils import WidgetLongProcessing from tomwer.core.process.control.datalistener import DataListener from tomwer.core.process.control.nxtomomill import H5ToNxProcess from tomwer.core.scan.blissscan import BlissScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui.control.datalistener import DataListenerWidget from tomwer.gui.utils.qt_utils import block_signals from tomwer.synctools.stacks.control.datalistener import DataListenerProcessStack from tomwer.utils import docstring from nxtomomill.models.h52nx import H52nxModel import logging import signal from typing import Iterable logger = logging.getLogger(__name__) class DataListenerBaseClass( widget.OWBaseWidget, WidgetLongProcessing, DataListener, openclass=True, ): """ This widget is a mix-in class for widgets listening a scan. Scan decovery can come from `bliss-tomo tomoSync` or from `bliss data ` """ want_main_area = True want_control_area = False resizing_enabled = True _blissConfiguration = settings.Setting(dict()) # to keep backward compatibility _nxtomo_cfg_file = settings.Setting(str()) # to keep backward compatibility _static_input = settings.Setting(dict()) class Outputs: data = Output(name="data", type=TomwerScanBase, doc="one scan to be process") def __init__(self, host_discovery: str | None, parent=None, uses_rpc: bool = False): widget.OWBaseWidget.__init__(self, parent) WidgetLongProcessing.__init__(self) DataListener.__init__(self) self._processingStack = DataListenerProcessStack() self._processingStack.sigComputationEnded.connect(self._signal_scan_ready) self._widget = DataListenerWidget(parent=self, host_discovery=host_discovery) self._mock = False self._is_using_rpc = uses_rpc self._box = gui.vBox(self.mainArea, self.name) layout = self._box.layout() layout.addWidget(self._widget) # signal / slot connection self._widget.sigActivate.connect(self._activated) self._widget.sigDeactivate.connect(self._deactivated) self._widget.sigConfigurationChanged.connect(self._jsonRPCConfigChanged) self._widget.sigCFGFileChanged.connect(self._nxtomoFileChanged) self._widget.sigAcquisitionEnded.connect(self._process_bliss_file_frm_tuple) self._widget.sigServerStopped.connect(self._serverStopped) self._widget.sigMechanicalFlipsChanged.connect(self._mechanicalFlipHaveChanged) # set up self._loadSettings() # for convenience start the listener when create it. # ONLY if 'BEACON_HOST' is defined or using json-rpc if self._is_using_rpc or bool(os.environ.get("BEACON_HOST", "")): self.activate(True, is_using_rpc=self._is_using_rpc) def _loadSettings(self): if "bliss_server_configuration" in self._static_input: # pylint: disable=E1135 bliss_configuration = self._static_input[ # pylint: disable=E1136 "bliss_server_configuration" ] else: bliss_configuration = self._blissConfiguration if bliss_configuration != {}: self._widget.setBlissServerConfiguration(bliss_configuration) if "nxtomomill_cfg_file" in self._static_input: # pylint: disable=E1135 nxtomo_cfg_file = self._static_input[ # pylint: disable=E1136 "nxtomomill_cfg_file" ] else: nxtomo_cfg_file = self._nxtomo_cfg_file self._widget.setCFGFilePath(nxtomo_cfg_file) if "output_dir" in self._static_input: # pylint: disable=E1135 self._widget.setOutputFolder( self._static_input["output_dir"] # pylint: disable=E1136 ) mechanical_flips = self._static_input.get("mechanical_flips") if mechanical_flips is not None: # pylint: disable=E1135 lr_flip, ud_flip = mechanical_flips with block_signals(self._widget): self._widget.setMechanicalFlips( left_right_flip=lr_flip, up_down_flip=ud_flip ) def getNXTomomillConfiguration(self): cfg_file = self._widget.getCFGFilePath() def create_default_config(): configuration = H52nxModel() configuration.bam_single_file = True configuration.no_master_file = True return configuration if cfg_file in (None, ""): config = create_default_config() else: try: config = H52nxModel.from_cfg_file(cfg_file) except Exception as e: logger.warning(f"Fail to load configuration file. Error is {e}") config = create_default_config() # apply mechanical flip config.mechanical_lr_flip, config.mechanical_ud_flip = ( self._widget.getMechanicalFlips() ) return config def _process_bliss_file_frm_tuple(self, t): master_file, entry, proposal_file, saving_file, success = t bliss_scan = BlissScan( master_file=master_file, entry=str(entry) + ".1", proposal_file=proposal_file, saving_file=saving_file, ) configuration = self.getNXTomomillConfiguration() # overwrite output file configuration.output_file = H5ToNxProcess.deduce_output_file_path( bliss_scan.master_file, output_dir=self._widget.getOutputFolder(), scan=bliss_scan, ) if success: self._processingStack.add(data=bliss_scan, configuration=configuration) else: pass def activate(self, activate=True, is_using_rpc: bool = False): with block_signals(self._widget): self.set_configuration(self._widget.getBlissServerConfiguration()) self._widget.activate(activate=activate) super().activate(activate=activate, is_using_rpc=is_using_rpc) self.processing_state(activate, info="listener active") def _activated(self): self.activate(True, is_using_rpc=self._is_using_rpc) def _deactivated(self): self.activate(False, is_using_rpc=self._is_using_rpc) def _mechanicalFlipHaveChanged(self): self._static_input["mechanical_flips"] = self._widget.getMechanicalFlips() def _serverStopped(self): """ Callback when the server is stopped """ self.activate(False, is_using_rpc=self._is_using_rpc) def _signal_scan_ready(self, scan, future_tomo_obj): if scan is None: return assert isinstance(scan, Iterable) for s in scan: assert isinstance(s, TomwerScanBase) self.Outputs.data.send(s) def _ask_user_for_overwritting(self, file_path): msg = qt.QMessageBox(self) msg.setIcon(qt.QMessageBox.Question) types = qt.QMessageBox.Ok | qt.QMessageBox.Cancel msg.setStandardButtons(types) text = "NXtomomill will overwrite: \n %s. Do you agree ?" % file_path msg.setText(text) return msg.exec() == qt.QMessageBox.Ok def _jsonRPCConfigChanged(self): self._blissConfiguration = self._widget.getBlissServerConfiguration() self._static_input["bliss_server_configuration"] = ( # pylint: disable=E1137 self._widget.getBlissServerConfiguration() ) self._static_input["output_dir"] = ( # pylint: disable=E1137 self._widget.getOutputFolder() ) if self.is_active(): self.activate(False, is_using_rpc=True) self.activate(True, is_using_rpc=True) def _nxtomoFileChanged(self, cfg_file): self._nxtomo_cfg_file = cfg_file self._static_input["nxtomomill_cfg_file"] = cfg_file # pylint: disable=E1137 def setMock(self, mock, acquisitions): self._mock = mock self._mock_acquisitions = acquisitions @docstring(DataListenerWidget.getHost) def getHost(self): return self._widget.getHost() @docstring(DataListenerWidget.getPort) def getPort(self): return self._widget.getPort() def close(self): signal.signal(signal.SIGINT, signal.SIG_DFL) self.activate(False) super().close() def _get_n_scan_observe(self): return self._widget._observationWidget.observationTable.model().rowCount() def _get_n_scan_finished(self): return self._widget._historyWindow.scanHistory.model().rowCount() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771010129.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/__init__.py0000644000175000017500000000062615143674121024430 0ustar00paynopayno""" (Ewoks)Orange Widgets to 'control' the flow. Like defining input / output, stacking scans... Those widget are not doing any 'core' processing. """ NAME = "control" ID = "orangecontrib.tomwer.widgets.control" DESCRIPTION = "widgets for data control" LONG_DESCRIPTION = "Contains widget to control the scan flow" ICON = "../../widgets/icons/tomwer_control.png" BACKGROUND = "#C0CCFF" PRIORITY = 1 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8931005 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/0000755000175000017500000000000015153325403023423 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/advancement.png0000644000175000017500000000133114757047403026426 0ustar00paynopayno‰PNG  IHDR/Ä<ðsBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î<VIDAT8��’KkQ†ŸÉmrÕ´ÍE£h1RÚjD°‹JAP›‚Њˆ¸Ð�…Øm7Rð¸v¡ˆJÁ­Òb�‚¥‚ Vk5ŶÔXMÓ&“™Éd&.œBÒ›¾pç{¿ï9ïáØZ6 ¼JÀ ð è7½u€€{ÏÜ:ìvû{·Ë•¡$•J‡4M;b‚Ïù:àönQjèÕµ´ì=Å]/‹{.åH,l�²»:�]×ôJei$™ŒÎ/,\žgë®$F­6ï1G]ªéþ�ûÎïtá›Ê„ÖhQ’\=ñøÂýááÛ¹\nh>­ÎZô¼QÕ2Ærí’§+£TŽ˩ÚWœ¥mjƒÒìi¶µ·µí‡B�~�Ç×ÖÒòÚdtÔ'žˆ/�`mÑnT-tª•¼uººl‰TZD«›ŠEQÊe]¯”dY4Û•:à@oK÷à…Öu/Ö74ÁØÛŸáD<‡ü¼˜ZÔ'§¦ÒŠ,ç3ÙìïT*uÅ„=¯ P] ¸™8ÌÑ«c\º1F¢÷ ²î0Ò_*_S³³MŸgfªªž†©vNèŠR±¨?¸´ i–ñÉ_žÅŒl_cIÀ 0Üâï’„“ßÒ9§ß²YR€†fMªï„& �y 8|îïlû­ñ”ÃëÝ ¶ª�Ŷ<¡I€o€HA Ä�,�¶ª†‘3ô"[$ø®Wœ5=e`"Àió G‚;𯄀<ŒšZ#Ð Eಠxö°Í”F€½æ~îÙî9æÇò�IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/advancement.svg0000644000175000017500000001322514757047403026446 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/blissdata_listener.png0000644000175000017500000001352115115744275030020 0ustar00paynopayno‰PNG  IHDRTTkÁ pHYs¯¯£¦ÈtEXtSoftwarewww.inkscape.org›î<ÞIDATxœí\itŵþnuϪí›eÉò&[Æ’¬cÌbÇ„ðÞ3äHà�íœ<– <{p &@HØ—¬vLˆ11`³˜}ó¾Ë²åEËh±v�¤Ñ¬Ý}ß�É’fF�Æ6¼ãïœ>s¦«êVÕ×ÕU·î½ÕÄÌ8ƒøAœîüÃBãŒ3„Æg�3Îgœ!4Î8Chœq†Ð8ã ¡qÆBãŒ3„Æg�3äá ¢lsÈÞö(ð3ïnß$P,Ö&"’\à³Ð ÙË<àÏÌì�¥‘ß$œ0¡Dt€'LÀ6xÀnõ4I&ø€‹˜TXÌÌ_Ä«ñ_K0sT;€UÐIôx@Aå2üú4 ¸3Ú:¿‰W´dް'Hæ'ÆŸpEÀ4‚2>Ý?m„ ú«ü se@2€MARvº;Ê � 2øª^— õ©c€€¹§›€x_%"2øÀy1ó+Û­ûÉ`;ôyu23wÅKöiÇ #éaè¯æƒ1ŒB9Š<—å?sºGÕI¡D4 À6¸„# ãÐrW¸@ ô]Ø&O0ó›ò¯ð=ÅÌ|àÆA &ýâ;™é¶KÂ¥ut¸ªÚ‡Q£Ò¬ßž?q´¦jF‚P pwº¼ímm®–šÚŽú#å ûe™�––ꘗjÑ´#¡˜  ˆ™C ѧ‡.ðô©B@×AïðO?eæÀ€ryXÃÌ×EÓàH˜7ÿ7/Ì›[¸PÓ LÛº­B=r´Yxÿ¢ '~vë|3°þ¶ô¢¹¹K¹÷þ7šÚZ]è ðv‰Å§ªê{çàÁÇ#NQ![O"š àÛ~%™àyÐ@cŸäÍD´ÀÛVÑ¢¾£�™kˆèe?&¢‡˜ùÐPõEBzºí[ªÆF‹ÙØ4€Lœ0"pøHsÇÀ2™‰)²AdöÞ`}Ç×ÖÞ­>ôÐÛMm­Ý@"1²ˆiœJÚw!o�XôàJ»¹qåöí¿ ”Î8r'€'£ìËíŠ|g™z™ëÌð-w…)ÿ(tnŒ²¾L]–›’b!"ÖˆÐïÊʲKIIV ö½’’¬÷^Dš«ÛXöÐÛ•uõím·¨ãÇ!ƒy1îêvgþ1¯hYêÀ¶ô#4hèXàåhV^"š à®dæÎHù˜¹ú\y/M�V àקކ¤*Eé6‹"dÄèíÆ�K7 ¼o·›ú½¡>o@{xùzGEE³/Œ¯ÔT\œ×|í53³}ôŠ+–\5ý­Â»í}3 |å�¬Œ²/O¸�™÷•‘™Ñ2/ÑùºÁº/ðV”u‡ÆSœCB‚É)ËØqæ�;î¾÷-½óm  òc�¿[SVVïí›GH…³Í3fäÛ¦�L°XŒ@ÀïS¬³f��ÒÒâzÀõ=ùz €jfÞ=Tˆèréþ8TÞ>xÀ¸úBÕƒõ®þž8ˆ¦~ôÉAQrv~GqQNÈH€$»YÊÊJ”;•ž{v»YUÑðôÓk·ï¨ê%<7/Õ8kÖÛŒéù¶ž|}a4Én¿_M˜7¯ð²sæüºdËwmB � àÓ(»ñ_îgfeÈœA0³BD÷XNDkzFipõ_­œ¾˜=û (¡XS4uëÖÊNg»Ûtî¹ãì²L!&Å YæÆÆNWÏ»Ý$±ÆøËË_5 Ð÷¯.N™™a‘™hHL²i+–eá3› Ö)ge?}J;N(%B_©‡�A,„¾}þ¤ÄüÑ)–ZŠòE$nb€Ðg„2s7€:Sbé\ø¶�Ý3zw¼dö…,Ó´œI&BMII�­VÕ¬ÑOoš>fÉ’93gŽI0™„¤ªYcEtwû´õë÷vTWµ{Æš&‡KÂ!MÊQ›š»"j3¬s¨à „ΗŸ˜4xÄ“4Çè1 ÆgͲ�A€¦¦zM�5†éÓFÙ-<7óŽÛÏ˘R’ÍÆ¤d«¤(¯[·Û™êë3,ƒÊÏM…– Ù¥©‘-wHLÐt¡„¾Ýíq^ìÝì‡Mq’Õsç.3�™:•@L‚4hii”l6;×ÔVöÎ�íÎ RÓ,¦å]>ê¾{ÿmäåß›žòîGã•Y?õ%maåg[rp�ù÷k/ï¼ýƒ`xÚ1 t§´À³ÐuÅxøÏ ‰Hbæ¨^±hÑØˆ³.ÍMµ ¢Þ�ZSsƒ˜6õœ@mÍqB›õQðû‰ˆ�““lÌÉI6^üíIÉ]]^eaÎÿ¢6P.pí�\J'RåLL°Ìðw;ºŸyrsãà:(†™ÁªÊÌ]Dôw×퓇Óif®&¢:?ðçáÈUŠóòRÍB"\®Nò¸»éì³~øvï~¾¥¥Q Föù¼!2,£hv�»µ:×à½�m²J- ~ÿнUnŸ7¥—V:4a÷òð8€ÅЃþ=†¾ÄmÞ'"'3¿~"‰È‚ã–¯D ×Ÿl±¤ä?ðÀëV%Ð~ýÄŸNg%$ظ°pвjå Ö­-�"+{¤æv»Èá8*UW7(G«¯²ªÙç¨i÷i ifˈÁÒˆ „� Gʤ@B™¹’ˆž‚n»¼ž™WÄTÙqy›‰èZ¯ÑÕcæQ@w§@{ðWÐ1{΢çÍ+N]½ê9þôÓw�ÙÙ¹Zzz¶–Ÿ?Nu¹:Éél£ääT®«¯£´Ô|ÏÁƒÛÌ7ÜpuXhè£k˲͟?fIyL}RAÔ.H{£ÇçÉ¢²ºWò9"ÚÆÃŒ cæ·ˆ¨ºQä+"rXÈÌ›‡(§øÃÀû§=2rö¹Åö©SÆ(µ}WùòË�sæÌ÷gff«ª*+6[²ºjÕzW›3¹m÷î²ñÉ)3šF�½=Þ[j“ŒLÜ$Á°¦çfXí6¸-ìÙko$¢‰Ã­�™̼@.€_hŽU)Þâ¼Q)VI�rάùÞý¥;å�>üL­?æëº÷þ7ÅêÞ²e‡ÖÒÜ¥¨ŠË`0$Æ9ê�Ù j’˜^*-]Úû°"Úü˜y?]` €w‰èbf>2ܦ0s3€¿ Kˆ†â öiMM®æ¶öîvYN7——o±¥¤Î¬·Ù5�©^Ÿ¿Õ ªê6 I±˜çs‡|r°L^Ó7eP#*3¿ID‹¬†îÁ¼‚™£5@Ÿ<O=PÞ ƒÙlö‚ö֖ƃ!ÙFcª×ãvØJ§�Y£Þû&•ÌiËo·H!Ž9ÜÞÍŸ;:»»}QùÜuïFìa{HñÝÏüp¿²CZ¥™ùDÔ àoÐWë%̼ú)ˆ¢©” Ý+ºŽ™·DÊ7wî23˜Š¡ëµHLœÜÞÚòE®ÁØC\º·Ã¹7Cñw$É¢�füpñYYIc|¶2ÏfÃ6O%ÔrÎÎÅâó/J¯Þ&ÚÖÿ«|Ð9– ˆ³hgÂN¤[ÊËCýóQY˜ù-s4XEDOQR4eOF÷˜>X¦Ú&uôUºWÕ1š2|éÖX,#Ý`2ex¥Ãä´›Œ&{àöe%£÷§¾‘úFߌeMEã¦$ƒ·TÝU�5¬0$–Ë(ž’c S�(� yDH#P³›åëËË—¶„k_Ô1ö̼‡ˆÎƒne¿À�D´z¸M5€èªÍafoµÍЃÇòË$H›B!å´ôó{cŒÆ4@,Ð�4~RžüÏæçÌ>EWìYP»Œ‚!±µý1ÿª«rf_6Y�× t´¨þCû;�ö#�Ûç! DÛ ´ì[¾}°ö�С…`¤G €[¡+ì?^}ÑID #Å3 "›‰¨CJ,t =ÐÙ‚C0™Rü,Õ§´'@KWŽï×å?'_TÕÏ&ëS<ØåùØ0Ê4Q¤›GIyI)«Õh®s´¹=ž@“V!iòóeû–îª'| $h þ ýzTr €èqõ ï®7ãDF-tµ*"4æA$sè^2YTX\@»·o’ÆL=¨ ¡8¹D+ðÏí>¸«Íµ¹´Å][S®«XºÿËÎÄ9¤Q&“ö×ÂÉn ÍòØ�÷¶F’³»ƒuìbæ?2ó2f¾À?‚É¥1Š Ö¦‰Ó)@9Ðm�a÷Ú&³�n½oVž?£C€SŠ)âžœ¡Ø4×÷üã›k?xç�³¶¦í¸¾Êsi¨f¢vfÎdæk ¹WŸuÖ/ "ÉŒ·ÿh"tRÇXÞ ¢NŠ·` ˆÃ¬Òm”äoô¬HÐÒu#¦)Ù‘Ð\[>îìŒBÔ[/³à*"(¬aªFü\AÁ}áòƛб*bq11(¡ÐP " ˜B-˜˜a¾áž³òÿÕþ¢¥ÍÛŒ„l«ædsDB ÌSÕÝÛ¢_@Í @C�d’ï —%Þ„ÊÐWêX‘ˆ>êPˆ§‚`8B/Y0>å¢EÖ¼¿5¶`Ù,ó¹Ëg¹…q°Ï¬²å&é8˜4t�,ÃoúbØg=@ƒ® Ç‚Â`Ù½ák›ÔIR…>''ÙpÝÍ…¹ïwþÕÜäl8áÊL²n'ŸǧN"ÎeæYSâ=B«Œ‰1ÎóÜàïžp‰‚Õâ ÁÙsþ¼1‰ÿyKVþ«-O››<'N&LH*æ}ÛZC¢š£3ƒ$ic‹ïÏê×ÎØFÄèç:'ÇPvtí ¬†@$“`Ëu?™b͸ .û�c2ÔØ�H…æ’ÀŽíµÝ1 `@À(soL€ø¿ò=–øK슶P0Tg6ôðȰ«rZZ¬k~<ɺ�Þ”­G†åæÎ±æ¢õˆìòû¢ó…‘ Öä`dL/â:BƒáÝŸ¸9i-ž‚®¿® —øûŸ”,¾cÂÔõîß‘Ã5<2Iæ%]í{ueé°ÜÛÁSIKý|OÆž0á(„€ˆ®ð]�3sm¸J—ÃÆ#7J÷üú×–GÈfu8«r5 @3¡$—ç\Øôª§¾¬¬16/gfVèwBƒ WC�YKD�Q¿•�ˆò‚ç—VC7ˆ,$*Ï­uÀ$ˆ8&B³¬9¸:óç¾�VuÔíÙ},ö…¨È@EQD?5#Þ‹€™ˆèB¯Bõï ¢]Ѓyó Ç<ô´ßgæˆQÓåõGÏ«tJ�žv 9 £0Ã6/à«Mt=ûäîÆá¾æý ˜5¦î#GmÑ}Ž:N ¡À̇‰h6ôè»ÅÐ~ú× ¾ð;gŽ<ê¼ðŽ9ê<üð––� L¬E³ÙŒ‰˜‘t�š®ŽõWîóv®~¯Â½Ï(Jd0©¤Ÿ˜é÷�N¡ÀºÍòÏ•ýÎh‚nÛü g•µì_þìÎGFk, Òwaa!I¦%ÏÒF‹é~g ¹?ü{U[}ý®8{:û€a±�)ô|ÖI%´_t TÈÑÅphèløÖîÖ-¿xf×ò¿ÙBLB 9¾c6XpAê%Á=ÒûÕ›�moíܧùqHØîb-4æ”-j]µmküüÎ?ì}2Kƒö‹0ÄÜcw!A8'm¾–ã)ò¼ú\y}sãö¨ÏJÅ‚™ˆ‰×¿V„:º*þã‹ú�o^Yú¢n¼U„šΟzˆ·Ý˜ˆËÒ–ø6®©o\»sû©‘ÇA”p7ïoß¾4äàÅ׆Ð:Wå•«Ö/yíÐËé=÷4E¶èê’ncËMËç›®ôüîW»jº\Þø.4Q�ÄɤÁ! 9llÂׂÐÊŽC?^wôµ¾SùFrßûìV0 RÎN�£¥7Mïxê[ Ñ>© dAC›F¼ö@éÒ°aI§�ЊŽ#7½Z¾òªOjÞ 9Îʰ€IœŸqiÀ³/§åå5»"zO:ˆR Ð4Áež�”í´êp½aí¡ÕW†# H– 2h-[R?ØpÐyš¨ƒ(“ôï=”›„áν{—FôC�6B+;Ê—¼~è•lt¬O ›A•- ²Ä›×z:÷ìsª M<ì:¼ì…=Od…K̲�Ôî.yèÀ(ã¸ÿ9°ÿý×A�‰‘ ¢ØŒÌÒ-jLЈAÐHc‚ ŠÍNf­Se�°MfùƒÒ²ð+ù`8¥„u¾í©måkaì!EiÓ}7MûŸ­ã“'ÝS\ü@AØ4†~/ºïp�H'Pë=å#À|$~Í'˜:4F+ v‚¨™4Ô æ²¢¢©¯½vÕ°ÎS�RB=jwN»¿\« �…“olž5bîÛcǾ€÷í[^=퇘>+j:*Jš½�?ù¤fã¸÷ª×%åÚóµ[¦Ýs4ß:ê‘T[ö�_Öù&à”ÚƒZWÕÒòöýSóí㾟\ø<‹gú†á´ ýû&-ˆí#0_küUÝú>(E$IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/blissdata_listener.svg0000644000175000017500000001561415115744275030040 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/concatenate_nxtomos.png0000644000175000017500000000140014757047403030211 0ustar00paynopayno‰PNG  IHDR¯ÓsBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î<}IDATH‰½ÖKhUWàï^HcŒ¨˜¡Pƒ :ÖAh(´‚P´(¨¨8RÁI¬ )v"¢Ö¢‚Ðø€"Hœ¨T(UE�ñ�¥4>k)XÛZÁWŒÞÖ¹ —˜8œËY‹ûïõø×Ú9œÁ ´ã_\@+Nà�AÂ0Táž` ².”a5þÁ3en( '`/Þà$&õáû%ƽ+a-þÀSl@¾„ÏÜÂüw%�ƒ¢v­¨ëE¸2ÙþÂŒ ò]ƒÑ?õ«Ä߸ŒÇ›Èá5îàsø5�`(Ÿßr¨×]¼‚héþ`*–c2^ Mh®³zE”©^eØ‘þä–¨IY‘}…îíÂð,$5âäØŒ‘%|¤Ô•°½åØŠN\Âô>|×Ë £‘X&´Ó�FSQ `6¶ˆ<pJßQô _¡?ኘäQìãAá„`[E«>ÇC!¼±�~ ’÷ŠaBdyœMßÖb.Îaƈék°D¤yÀèêíŒ ø:ý®ÆMÑi£pS²� µ¹�Oñs/û/¸ŽEB§q&"hªDð ~m?/ Ýé:*ÆþÄ>—ñÅøÉ„®ˆ:pKKøTbšH]^¬ój¡³k%‚ïqDÜ ŠÑ€Ýb ~�Ãø3ñ�èÄÛ¢këñ2æžÐã:\-^Ám"EŸ}› Úy§èÄÆU›¨Ûl)/’‘ü+±QÕûrѤçÈiÀ~qÝjIïù"mù”‘ŽA.ÙÛÓ“K>¯QÈë¹Q›ñ§hù ,À·EöM)U7Äv=Ÿ¢ìL„�bÛJïcØŽGÿ[Ѷ2–kOIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/concatenate_nxtomos.svg0000644000175000017500000003375614757047403030247 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/datadiscover.png0000644000175000017500000000112614757047403026613 0ustar00paynopayno‰PNG  IHDR”yýˆsBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î<ÓIDAT8�Õ“MH“aÇûx÷f:§‰‚®jø¹K^!E4ŒJ¼øu(‚ (J$„îP]6Pœ±œˆq´Å%b¦œÒCõ)sa¡’ÖöR6¿Bì‡q°æ*l"qYÊ¡ªY”Ÿ2ù|UÍ I 6ÊÊÿÒ¸ÖIäÅršLî;)e•Dú=9ó&ÏžÆépƒÕЫ/¾|�pj[eìÖ>¬FÙØZ#øp�—ËY&üÆ¡ ý ¢ ò\Éà¶;ø”�©L%‡Ù¸ÐÍœçk{A$‰ä�a– � @ÈC»�¨-ÎS °¨Àè~@ú ìB' ¿Œ»úϲ"Z†»:ßæ¾IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/datadiscover.svg0000644000175000017500000000727414757047403026640 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/datalistener.png0000644000175000017500000000406414757047403026626 0ustar00paynopayno‰PNG  IHDRNG©¥qÕsBIT|dˆ pHYs°°œÔtEXtSoftwarewww.inkscape.org›î<±IDATxœíœy¬_CÇ?¿§^7´E¨.¨×ªªµRK„ªgoª‚Z±)B„Š-–ZKÄ[m-�’ *ÄVÄÒPÄÞåÕZªj©–ö)ïýüñ�1¿×þ–{çν¿ßïñM~™ûÞ�9ç̹3gæœ3÷æèo¢^רø uèÌ”y�@f <–2¯TÑÌE™–ÏѸuvF<ƒãÔ�¥dkw&¾Ã3äýpûÔõ‡!/âàVà8´çóAxÞð~hð¤SÜ„ŸCyÁ7FC;²OsÐôn¾Žôä¿%rÏòÀ‰ž42G´£Ï‡–©7˜üŒFeáv(0ÃиÞSŽ‹Mû/‘½­y\ŠþM›bè | ,¶*Cë<4¯ñ�£'°ÄÈršGûLÑí8±D�Fà-ää÷�@s"RÞ1òØ…â#�¶™â`$è/”6îW¢o×tA6p`Ly6V™v�Ù6SLEBÞUâþöHiWƤÛ…•žN Óm3AOܤ”?ú"ð9~[�£*Ð.…ÃL»o~¬´8Ø'Y,ÓÝÅ«…“+6^C9ˆ“�1ð³Á„%Iׄ�¡¤òÄhOv]¼šL¹0ªâŠ…m†˜2n¤! \‡ÿ´#Ûš²¥’âl4µk/ýC îU{»ò 2Øû¦ÌÇÒ+êˆkD+l!¬âÖ6 $˜/ÚQ´¤©RňúܼUq°¶�Ì+ ÚÙa÷²s€_’*n–¹®ö±.Úc-H‘Çɦ|*;ËÖÆµÓQq=Ђ1í¢«­¸ñ@/ü"»QÐŒÌJàQPR¤º£õ2:®¬Mh±X€BÑvªæ ‹•¦=(Õ׆Ë}‚vþÅïGônž>KH«r¸­Î¤ º  Žy¶s£ÐˆúžŽ#Î. VqvÄ�žŒ!T3Z}±5emÀ è”Ãx`$“ì?»"­v£¸Ï÷>Å· �çX„óCyP›@î…Jƒ¹­Ð=ÍõÇž�霅’ÅßûCccœ»y³�»�w þž ¼c®¯¾B{¹¥ètcZ8xMõVÔ©že[$Ãtä›¶à̸=Y‹×QŽ`°Më< m§…шžl–"€sPV£©ê…S�¿q‹Ébà s=Ö0˜ ü@ºaí¬ÂGãqg‚/JBhŒ!Ò¥ÉÚ�ãÍ=jiEïÔ;öÃ¥'“0ʼ³!4r�k�µÇÝË�*ªŽ;ê0“ÊÛµŠØ—¶™ð„Éh¹NÆn$€°ž87=g($߀Œätâqé÷ç¡£ôIq,Ú0O @+lž6�ÌMŇõé¶£¡òÖô Ï'Ì™ŠÁd{x¯z3çó÷UhQ1ÙgZØMðÖV\ˆÑ.,Ôˆ^14";}J0[=��„¸Šë�÷\Œvq`½“£·+:”¸?Y}Ð1¯(šb1É!Ï¢¸ u(�ß©Æ(xßЀÖdJ¿¯ºù¸ÇâiâŽ8™ïÃ,64åÏhÙ ë\=ùÕü ‘ÝöFź\ “0-ÿ«˜)�€MÙH y×8î‘� ,!B&ÛVž¶²µ¢áSSnIG›>ŠK3¨µ©ÚŽ‚ˆàÿr®…}åèݲµ:šqÓ5ɶľ~Y¡ê9t”!OAæ<&â¾â0,�\u�cp£Îgkrî#ÿ)äP§óè-è8Љm‡­ö1÷1ƒDÛýÀ[ŸHO´ÚÇA(»f¿u4¸LÝ=pJ[€ Šþgqî�éÕèÐÍáèÓÑ=œ�ˉ¶Îe«{ Æ}7®Üokòþèܽè„y«ù}ÜN8ÿ6þP‰Ô¢{pdIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/datawatcher.svg0000644000175000017500000000642715153325210026440 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/edf2nx.png0000644000175000017500000000243214757047403025332 0ustar00paynopayno‰PNG  IHDR,*ÈݹsBIT|dˆ pHYs j juÿc-tEXtSoftwarewww.inkscape.org›î<—IDATX…Õ˜kL›UÇïÛB[ ƒn\&»!��("·Ä8g¦[œÊ¦�Ì-Æ…e.1&.|ÑúÙK”DG"Sc$fG–ÌêæbRtŠD\¢ŒÉ}eʸ”K¯oýpº®¥ÚžÜÿKû>ç9Ïù÷és;/ÜfP’Ø£ÖÄ©«3IœúD7kÕ¿²s�Ú�®}Öçþ¬�Ý]�nkâÔ"#QÂêý Jce­§‡ÆGµ—»:y&afQ-úq°Ew0£ro,eÇ¢O?ÔOq"ø@+½Gé˜õõv´y;’bêGÀÃUõjþ&õ°Œ±åðå§žöŽ6:dl¨)â²b‰áoNçò›5+L©ùØ(›œíÌ ¬›2¼ä滨¬›¥¢z%¨Þ´½Yˆ}:4=vîû˜L-áÙé4<…âÒ…%ƒA`Þ®GU¡¤lÍ«06dࣷ6QÓ0Ã�#£ÒÿÚ ¬Ís‘“ç ØÈÌrK“ # °¥d�ý/ŽEݰ¹d‘§�žº�MçÉ Ü]i§ªþVÉ­ßqƒê†ÐÜû‹;Ã&|¾TX‹�°�ùûNwÜ"ÛÛlC§‹Î&{­§Cea^‡9à @÷ Wÿ4tž:4m{¼Ø #Ðx"¬(pmÄȵcˆRÎzg€ðØ ‰±AF£—œ�5^gÛ#“!eOU}(jøe¦°„>à‹%â±'°D0Ôï‹À&À$�™@9P4!ºØƒ„þ•Éà.¿Íràaà Äô6.ãásþÏ>ൠy ðµ„]IâÚà@LxS�š*á&Fg’„Šx"�ÅmGØCü�'�ŧþª{xPâÔױʄO"*ÀòÓ¾Àª{8Q¬z ' •%ó¨ÌA'€l¿Ñ`¿•° ⢊߶qï–étÇýßç+P�¸£¥?uÜúñuˆ®—4z‘›öÅ) RæÀnDH­À;K@ÌÇ{ÿe 8á,“žòIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/edf2nx.svg0000644000175000017500000001557714757047403025363 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/email.png0000644000175000017500000000136314757047403025235 0ustar00paynopayno‰PNG  IHDR00Wù‡ pHYsÃÃÇo¨dtEXtSoftwarewww.inkscape.org›î<€IDATh�í×O¨UUÇñÏÏ.„FH"A`FAeQÒ? ±Y�ÄAá qê°á…áH�D� k‘!¼”^AA“,J´ h¢¬ç={Ýwß}î}.œ/œÁÙg­}ÖoŸµö^'Ue–ÙÐu“Ò èš^@×ôº¦Ð5ƒå7I6á8~Å¥N"Ïfœ¨ªO—Cñ~Ç»¸píbË{°›pE€ªºra Îã5ü�–?ïâÂXÀûØ�·—?YUu ÏàÍ$sI:©•$Ïã”&èñϰͪ�UÕY<€ûq2ÉÖõ t˜$ƒ$s8Œçªê­ÕlÇ®lU�ÇÓø g’<8ÕHG�ä6ͪß�{«j~œýš©QU—«êà£$¯N%Ò$ygpBS×tUÄc êN|‹w°qŠ…:Àø;ÇØíu5ELróZ>InÁÇxL“2ŸMÃÄTU�ÃøóIîYÍ6ÉãšSu»ªê·Iß?Q �øÄ¯hZ‘}CãÁAMÊìž`þ)4ÜÌMºï%YÀIÒœ›5Ûî Ø±øÅ¦ÆÔ{œªú^³ÕnÃøßhŠuªÁ³²�ž Uõ×b#ö:~¬ªOÖã=¬“¨&i�¬×üKÌü/e/ kz]Ó èš^@× ŸÄ—pS’³]slÁÿþ²Ø¦þ7�Ü…¯aPmù©ªþ\ºY!`Ö˜ùètM/ kz]3óþ(ìi•¾¡ÑÌIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/email.svg0000644000175000017500000000345414757047403025253 0ustar00paynopayno ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/esrf.png0000644000175000017500000031660614757047403025116 0ustar00paynopayno‰PNG  IHDRú,êü®» cHRMz&€„ú€èu0ê`:˜pœºQ<bKGDÿÿÿ ½§“ pHYs.#.#x¥?vtIMEà 93Xgc€IDATxÚìý}|\gyç�¿Ïó<�$?'-UJJ+(¤Ð"(MëÖ¥ÛîoØv»ì¦´«–P.&á±:)�!à•¦!Pz\©Aà˜@‚›Ð Y‡Ž1(A ²cE’e=kæœÏ÷�ûœ±ìþº/¶14>¯×yÙ²G3ç̹¯û¾îëú@ºŠ Ô>pÀrj5ÅXÎój<„üí´¿•?wüÇ=ÎÍìÿ¡Ë.€];ÖQ°-°ŽÖ�Vöªâvóÿœ{þ�›ãÜŠþ~܇U‰AO³X’t7–—ëBÔÂêÄxgOnYX€%qnEçfôÿPGЖÝ«òNtÀ²×ÜÖíÓëÜ,ÿ89ÎúOø1Ë °bVsh÷ðéÃÍåp³×IøÅãbã ØÐÞ¹Šûãç8—ºÿÄ– ¦ªÐ@&È-‹e!ë¡ +ÈåpsÉ-‚µånféWël_ý¹ã±9έè?ñ‡Ú€­[ÈꃤÜp¿7O^Ⱥ’Ûì¾@k'7E«%«qê+˜þÜalî¶¼³}õçŽÇæ8èÿQŽ—„:�n¼�¤Úî+p%C”­$MÄ¢g&µÖÎçãÞwòÜó¼çôOüa¹�úñ V¸ÆV·l —�*tï}¦}%/pjDª=ûO­ëÀÏiå©¿©µ³}õçŽÇæ8èÿ1Ž„(´à%éÊ>dñS|é;@Üû0ÖÐÀm<뙡^Äq¥õ£}ì¹ã'å8WŒûI?,ì¼ÄzÁÔ�ÀÆ�´ õ’—¤ˆ7ÁöV®w­·÷âýÒZ¡�Ëšåö]LÜäܪþx8έè?áÇ�uˆ·S±j5QdÙýþƒØ›±_»ˆKt´À¡ý:z Ÿíë?w<6‡û£¿Å¹ã¬‘E­¦¬ÅMH\i?’•«‚mýw¸ô£ãñ×^»m`ŠàùO6Âmm.½íî;..ógûÎÿþǹÔý'þ°lP²ËîÀm„¼ ×­W"aýÕž~ö-àZÂA¬èT÷-CÌÜø^ÁÒÙ¾ƒsÇcpHzœŸ”$rMá£Ð¦&‡†<ÔïíÁ!Q”$숚#B;Dn„Ñð¾ÿýȰ¥éÏMƒH³Âk ¿!< ·ó:ä Ù’8Hhƒ!§|ç@FR¹â� ¿ ¹5±R°´ É*h­v‹ï”wš´ÿÑÇw�ô§ßÖ÷èÏËîÏbH;ØÑ¬ÞÍ$ýà°{§ÅÝX?Î{gñØÁ;êÁ–‡a ›ø#õп¸°Hë6pÃDz,+;èÔŒ”dmèv&[±7–ÿ_t ?„ž³=ÓœõÙJW5Üc¢|HG„G(;›ýKN¶"MMQž=éÊð\Yj—Q2±/+4+¸"?B=<¥õKX}çâwàé9ìU‘Æ;«Œ &s�+ó§!'d ³z›{m5LÆ@ºÚ�íÉû¬¾5Ï·[¤%J $²ù—eÊ'ßñèÕ 7ŠÌêmÞG mBÙ kÝkíôsì>OO$òÜz5‡vè²"­·Äß»MØ«b–-„!n=Är/e<×Y±›øjà�ù>)ÏŠ.Ú +»_s_ʘw?Šþø:Ïúœõ3 !›4Å<"Š ƒ老œA�YŒ‹®u󇺨ÙI×m�-BÛ¤ÿnˆ|v¼ë8ož¸ME¾Òv¸ê¹!4å›ß‘kÎÐ6×[s²-Az–ià§ï_3›ñÀE¸/ñ‘ éËáë«\ _^èYÚ¿þ~}?gî5›$JûÇé¢_OÁ}Ó×|ê+._^´¹yÉã£GyúMOGr£&þ�‡(JØjâ ·—Ñ ¢öƒ�NhÏŠ®iQÉ®#ÛRDNvž ôs�þqš•,¼Ùž:«–• î(Âé¬(¡lþƒ\aˆ¦“é¾r“…9Oåægà¶D>‰qÎ\b£V™XüüÊ‹P³d² Js¢'Í ÊÀ=³w=3™ ©9ÙÞÕ]ùT^~e‘Ë9¢•"Ñj™O.ãþÙ›QÃËî/[1;{üô3«~ŒB6��“—•ºÑW<æe1'¬µe˜Mr,Æ_û(½cA 9û"ò'NP”È}H”O�_?Ѧ{ñÂÄùY3‰–׺¹.Y€]Ž©¬ŸhØy¶Ç×�Çyn�nöiÉ�XQ„]«!Z5KfPe‡ ð§„1\i1„ Cëö”?ì°ì¡!’€(ýýmÎylk}�ëíGøÈo`¹b¹eáäAÄжc,øîÇŸÍW7[ô½Äzøa²%Öž‹wŸé�¿ËI¯ˆÒ3;b øû㫞Äÿïw\jW;Ô®þY~ï?ñÙpÿÔﯿÚüºžü™[¸Ò>pÀrÀº;ûÿÙ뮄ù¿sØ4Cò<�o%èTÎ+Av˾í¹oΉD pß}Ø<‚75ûè±·°};N׺ÚIa¨ÁKj¡¨aS“õ"°0pÙ÷o=ÎöLs¶ÏlÚI‘©æ¦©äúªï1QŽ"³’ ³ý?d ¶„;.r{ö‘œZö^Ⱦ”ñ\•K^‡µ$Pl¡ØA1Ö|R`&aóÞ73Ô(0PwÓÏÏI”¥ÿi¥} Ž[Svíašæ‡v§º¯—K•CòÛ0ÚDN„òÙ½±.sÉVõ¦ð›2ßAöó÷¯æBöþqºL-ਠ¬´ÓW+i{¬Éæ½35”òDòG‡ 8±¥ÈØp '¢æL‹Ê¬èʶõÐd-j¦]…&¾ÖocD!=íÛyöÇÚÙç?qV¿€P&г��<5ðÖúœèY¿gü?¿ï™=ïð(A îrá\Šrrz¹åçq“Ä¢%‡$ñhÇ>+*² ~AÏAÊQ3ƒÆÉIä”n²@ìËÚ‚Y»)ýŒ40=$“¾KéÙŸÖ °Õiš÷Ì®»äé=¤×Ÿýig­5![Â{Æ8]IF , á)†5Häpç?ôÑô¯æDQD¾$Æ/%·CäÆÍýÙ³¢Ëº:ïŸÕ"ÆEn<½÷�×´5M»íßäî¹@?èì„Ïðh0€Ü'(ª‰?6J Ýãf%í™]f‡Äv3ñµ›@#gŠ_ü�ýl$9­+ÈI& Ï8åO¿Áâse¾®Ž´Š|d©Àè_26DéÄS£éKôè~ªB^DÍIûèþˆðÆÉIBÈU¯nzÔ)6 îÒñ~]ô„¢ë l¹Eœ'd×�sH'E!¢ædŸ$²¾øÄy¥º(2™LCx·ÞOu\äÒ€žˆ~Æâ=ßÀþÌ<ÖÍKðñÓØû-.ßζ¡‚y]h a;Ÿ†<#^Cx³¢ë¡ÓlXär¦¦(kšŠHWtñ„oLs�fÍê†Y/¾S$L{ô¦>¢s+û¹@—DïAŸð¨»Böx�®‰}äâ+Ä×(ÁèWØ$ñ„e±#ļ®±‹Âè0�ÖÚÖz–OL�t w*å&Ð[A¿p>ñ¾Äï}ËÏïG…K÷“ë~6‘g0è�õ­Îç‡vHÝm¯OøŒí 8qQ‘‘™*:X@òyé%ÞÄ`®yÃwRMùìVPÛG>Ë ¢'E‘HÁ;‡'Èåq‘l$—Â}í"‹‰G,�5¹¬$óÊ1{Ü»Ræð/AäP“Ó'S„%ÈjÙ96Jpx‚ü�‡(Ò?âÑ'B—GŠH4‘gXÁ¬èºî:ºGÇ$Jä3 ‹)Zž©²SlP§]—4)K”!r�‹ú=TÏù¼ï pW;àÎeü·,rÞÇB!;CÙIf¿nVøìyœ ôs�¾n`¤ˆ­‚„kX“.¼ýyy³¶a*�xÅe%)“$ôêùìWNiëg=|ôûßÿ‡µã:)–UÀ~å(ióÄoèAŸ¨�Dˆ_w§ž²�‰|/c˜`“ÈORW×!ô\³ºËàÜ÷ªhóµ+󴓀Ĵ½œD¸«Â™Ž¬¶¶1þŽíLäQhïùãbÓq±)Û÷³ãÒà�›¿+Î{ûØ€)¨yÏFO…Õ7Úèc=´£Ÿ¡uùnæû„Jb"Rw§e¶&#�ƈêð² àѧìè$¥P”8¦2ÛNÿr…ÕvžXEâ¶Íª°W[¸SÚÈ%ýBö #È2fò=+î� ôÿ�žõO×­ é¿ÿ@o;­$gÿ¥­(í1-0�“»”ñŠ|Ž©Ì×¼5àTì±,­Ù¬*@qŽ9Q½ë�H¹aQy»Ø�±¬¢“”FÇÒXЉO‹k) ,BŽ"eÕæ�Ú¶�γ*˜9ÅX§…ÛÄkU4Ï3´ƒ†¼1±iB¦ÝtÏ Ûd�Ž|å8›nÝèD‘M·¼Ý'‘Åšð²=~[°$‹Åvá_¦{úõ°„&òÈtÂÓûØ0-*c¢2H¿‡&òì×S!žÁRÙ´…ÕZ„Gd‘Ä%’9Þ¢'a84^CRœ~�DÎLF¡mVùmNl)ÒI™x5xx‚üIQ":Y¢úæ×˜U€Zf‚j +NÌýüáë hÈuÓ p×·Ø2àMS†_oxõ}RÆÓìl\).a]úÿ}ÅT7›¬ÏþøÜúº þ¾@W:»g(;×Ïô5G5òÍÈzHÝeŸòHž½ü‚€Y¬¬Ârb¯z´Ta¥ÍF=ŸC*�“»Z Ü~äÕÇé£ÒÌh¨¡ì�:n–bgm°šۅ ð¦?-0�”h¯, æ„·hråi‰M7¾‚HþwØ¢Yº†ÿ�ŠRdÛ( „ìq‘›š¢ÍPE*ÑÛºÄf-1$ô5“®»IbÄ'âU¬Óº½d£‹ó¨žCÊ¥�î6…?5Eù_¯e«¦(ÊG“úÿó«,Lêo£5X3”½ÜrIV<Ú¢÷Õ¯æÎé ª»i'`czæÒ6œ ¶±�Á‘#’O­ÏÔ Lk³\¯Ó…”£W?_fZ>KrP KÂU GòøÚ³�\úäg$£áQ‚ýCäÖ­äîú@ïPo¥N �§…Ìõ�že3’X_LmOŽ~ÈVíÇõ<ëð£žû ÖÛìWgE×q±)ƒ®ª‘>œ´èÓypÈ‘;:L YºN‹�ŸŸbÛ]œT‰žOý¥Íû—þi!Ïç–mÞ6 W]ñù9S5¾t¿ÙŸg ƒçnx…±1*c2+l¦Ô’õ׳‚C'Šw�™Kæ Ï‹Í ìI6+‰ÇÃKø_½‰K•«‰ü¤(À Ç`¿7:F�¡ÔL›Ê´ÇúB|&”'8p½Ë§×r,&yZ*�ÈðÑ?¾Lî“ ¯IŠR“\#’wèűQ‚&ò3‘rA6‡NÉ}å&­8Ć?æ¬ÿtŒ½°32)ö×ßÏ>åk"MÉå yYöaVõºKMyúB¿£Ø³›`üRrŠp¨É¡w4`T¼ÿÍo>ísÛ²Ç?/ì[å‰7¼§OøÃ"¹•êºIßY�®™<›e¡°M@¯OëÍ¿…)cQ?¬ÛîìÇÀã"Ð3ž²àiÏ7™•9Ñ3›a¨ëé—g„ šη�€1‰{E÷KO°EyBUv°öì*«ïrY½ºÀâ3Ùqiîƒb˽¢{8k™Ú;ÌDþjN�‰ršònjÌP�Ò@_OI¯»àp× ENÉ¢�`ʼnE"X9%°çxHpÇ~ÓÎp_÷:º«V3“Ÿȩ�ךH°½f*÷;UñY¹ª‹d!ÏZR$Ñ’ŀֻةŠ�3ÄÁˆðˆjNèÙê7ÊpRw/BEÀ¢¡•¯~Z²PÛ"i°§3rˆ•c1�»¯çuv2©4Ðk�ɶ&ˆœ,ˉ�³þ>@59ìSžKT¤¬‹«ÄWçÑ_óÔµg3¦MÃ"¸êC”³•Ö@bÕ¡_�w‚u]�ÄZ¿r_pXë€O�¢èvA~ bàñè"o‚m½8Ä™ªnÆ„R§‡k&ƒaD"¿œ®c¢|DO�ÚêC>ãCÛ ›"J¨ß#”}ëýTeXd.DN´�¼RàÒÜrUËZ_"¤îê‡1ÂÎààm4Yà‰¯zmžµÄgEÐná- o¥'äÑÖf$žòüË©×s¼üöîtÏÐ//ý»‘#B{êÊš¢<ˆ¼Ý(8q‚¢é}Ëç)·ôòÔß{2ÊPo ïdHIWSTÚ¦’pûGÎd:ƒŒxJ'B.ÚR¤¡[_wE‘•UŸ%Y,ÈFkqb-N%÷·ÙúîËÑž<5e�b —Ùj˜áÒHœ7ÊXÐDþ‰S¥C¼v=Ľd¯QZ4­]F)1 šIÄæ ÙLvá€û}㢳}ëœY ¤cc}«ïûTuÜñ4½—(uØv?1ð¸ôC¢8,‚hñ"Jhë{ýE8Ã"™¤0**·Šê½¢{Rú‘WOWÀÁ°�<ö+W§KG(¦PÙ ™öžÍꦃ-¦ t³kÊVÞõäó& ¼éÔ“Jħ ,%K¦gkfb%Hy�.ÀìŸ}úåe¢‹YÊÝ�”MTsè@z×-ëT~2˜³:ÅÜu×ÖÙƒŸÜh 2¨œ]¦ÀxöcàqèÙÃ|”ÄP#e•�™�m­C§u´ÖÒßGø¤óŽ;(«ß@Q…‚�ºû¡—QÖŠž¢;K=w§ÿG(Ÿ§h3C“jyÔEC^ÿHŠtK9ëé£Îja΋çè¹BTÙ¸Ø�õ¶‡<îX-qתËUâplñŠq6ÖŸ‰L�ö…ø#*kEÈYWq¶EÍÊ5‘?'z ÃK^ˆì›î¤’®ªåãclrDÔázwøßYo»‰ßlR’¨NM,{ D)mŸ Ï“÷?+ÇŸ?ðõ¶Ëaܹìó¥U‡×=ÄSÔ™(½â lˆÒ-Ji�ͶRëžWM8—OQÞ% |èX™P^¤*(H»>59Ïå–rˆìfd®WûÉM‹Êi±±Ñ 0´Ÿ¡Œ’¯i3þ�ÔÚds¢ç´Ø˜ñú3ͽõ<ü Í×AKòèâœÉÎÎ~ <Ž{<ÝSfMâ,]é;¯�7¾®}B(ŸÆˆÍPÍ`¤B–a©E¾í±Q‚{Ò?…f" ;µ‰Âå—á¼r{÷èþËW0ðÐvÔo„Lu×Rgw¦òX7ÏÒõËGÙÆ� V¤ý‘­è/)<°�èd‰�ºk �°Ò­’�j~ºöÆQNÈ»/])#jNˆÜ°‰,\<.6)-Œ5…ߌð�på€ ¡¡}š(ß›²ÝÌ÷Úõ“”FE…Þ±àt^ñ_i¤ˆ>¾ ýOÑ4Tø½Û&eÈ/2»âž8AqjêÌžú`ÃpÊG„ÇïÿôylûýArÿóz‚p„üg_ɫ޶E> e5{t˜@ <¤ÐœH‹­)7…¦ÿÊ&j>*K ¼už³Lc}�gci½Ÿ¾/ÕïÔF~ bàñèÙÀŒpö™j­šø)aw Ž›µŠ$qèE¥E¹~äe¨²=2 ³‡áLŠÂÉ�Ò¸ÈÕ•µÉäsÙÉ,>³€æ]–•c1 8¥ ª¢E6äR.[ÑΈCÊʘ_“¢0RY È�f¨vØr—*7’R]wgÀ¶ýãt ö�kÈõœ�‡d™ýùžÖŸß¯‡ÿã~žõ ø‘Ï´ØV»Ø<”ÑÞ´‡ÚÀS?žL�÷…øûö�oï¥{)†i�n�à ÕÙ—ÚÍÈ€.$r:B±^§kh„’KCvÎo²xŸG[I;Çœr,Å>§UbE¸ïþ6;—¶£(ŸµñÖ{²¢ÎDjÚ�Ñ*£“”F&)0ªÕÝ�qrÍÈðÁ3pÌ^®.Þqå‰ òûDÏ5¢+¬SY�*LIê/ð¬Ò¯Pxû^ÿYœ7~çº÷óôg=)#¢@Y¶gùoŠ ™œuX´¾]Ehk7Á.Qx‘¨^>EyLlš›$65‘o2"3¹e�žfgûR¯çøÂC\þaÒçÁÄA-�X.혓͸r|áö©)÷Î[©Jiû Y™PÈúVZ–Ée6„W»–Ò°öï —’^œ&†GÀðh�mMPh_|±©DÍLi—(âýÛ”†~|γ~?úŠŽ}í¥�ô(´Ãô¡ŠÂÀ8¹AQè~Ô4âQ„Öð�°¥¨´ £´=§”l15E9û¿K÷“K5Ö W\ÕntQqº<à[J�(1V;±h [²h)Ǹò´^óìUÖ‘cîÔ  §¾Ÿœ“¿U›†ë y ÈÝûRŠ·ˆóŽŠmu\òjMJõ“™Nü w…¨Þ9M…ШÍ4#üHäÙ­€ÞùM=( ˜—a¯% Hä±&‡i9Ä71¤­4T@ý^˜ÖÌj7âf"?ôuÎ3œ~�¦J½¢ŠRS†Jz*öeà °ê!îµf ÓâÛ£ÕjU·�*œÿ•ך^"˜Nðæ„3ŸPLHV}ÖD¹ñ4Y@õ}M_¡ª4T;�ŒL¨³?ßA=7xÐh ŠÂ !y©Jnžqr½cfÒRo`€;rÙÄ<) ³�âÕÎÄò#9Å<¶çO¼ ¬°/»ŒåQþ[+´žoõ‘Tkä¾ñÏèìþãðgw‘;ч¥Û¾œð’CÂö·ø••ÛB+Sqm‰+-"ËãJŠŒ‹ÇþKY»0Ä!²àðÎÙ¹dÓÔ½Ö*ß½ÈÅka¹1ÂÆ±‘ç€Úwu +n³|Ñw¦ÌûÜö™Ôñ$�E#t@ B_†‡.€"÷¶›ïâ™Ö}ü�]«[zðFVž ±ýÖmËrøÖB­ïÌ`�g…i¤õBh­4ÄÚ j]xa³Ðæ°øÎþ×µ9Yƒ6m,35â.6Gÿ #¯|#ó·%Ð ü›Q`â5.q.æáöËžÌòºñx¸áÓw[ûgÁÞN$/á÷FG[/�ä(·Y€5Ї.ÛA{û_°Viâ¬Wwý¡ÇÃÄ,ßûäÑ&AÎÂÊ›$ky ü¼;û¸{Ü=`Óìk}Ä%—¤®9}¨ÄQ´”*û‚e[wã�k`åU»hßê‡V×#8€8°Ù润Ø�¶ôâ_ñoöc×ë¬é¶ñµìÒ·¥�@’dÎ.}¸µ³=ðÿ¯åÇ`¶ùÑRw3£ÿùç]t#E$ŸUQ³Ä§´�»´©ÂÍ÷te©ß¥¯e+¦ªÞ©^kÖTƒ§+�¾kh7‘/a‡È™¤ÀäHa+­U¾×šoáÌ{1Æ[,&6Zõx()¢�£ºY]2èmZ$U‘5PÙšsZlüàMl¿UT�”JžëqXü�úXÝU¡uW‰öÇ@;‘zh46š¢V˜�@†öç�rôâß”Ã#ksÂU«e2W-‹ÅÄb©•çXR¦ýâ½¢šu9-–ÙýÈãã§7rZºÐ²ÑM ÛºÑWŠÄ7<ý·ªÊ^‘\úG¼«¯f³šøäµ›àÄ cˆAŠûY‡'9&‚O~ÀK$ÂKaº)¦Ý¦¥"K1¹O�ýÊ1n e»Sدicâ›N‹�²“I¤ããw_φ‹n¤ÈØÎ€©©2j–Q•+TeŸòÜz¼q‰óßñIž<’¶•m·ÒçÖ9Ï!ãóÔÝ:Ìá|JVðyÇóºÑd�¾¹gsÞkÿ’Í{ßÌ3–~ M䩽³ºC&?ÌD¾³�£Ö ôHäû3;&dÓžQ‘‘,š–Á“ˆß\`L6'…?ŸàM {Þ�FXRŽïª]�d0×Y!'Má3¬uV°ºõ O˜=ƒÿÈF´­ÀÌL•ž—^žÍq×Z‘ã­®|Mÿ°Â¶ÿñA4VL¹×Fê)Ý—Ÿ8R,ÿmžo¯z|Ïôå­UaņÁfµ…Õ–Çiù|{¥‹µ·ˆâÕ¦ëPºgÜA t™Pž-ôA›Û–<¾®€oÉçÛkßX-px…îßþû&òìÙ—g{-/QfÓè0A3Â?"Šã"GTsˆŒbÌ™Š5†¹m‘D†)Ø–™�‘��¤0/xèÕ4ä…Mük#³u1ôZCºOl>nê†<³NM½aj»{+L(Ï“nøE /{›÷¾™ kÏBÊ|œ�7ÏÒuÿ ÕZ“’:’ZáRË:éés�þØ®èöð(¦�Õ�—*¼­H¢"meôV^v¬lˆu×´”°Bä†È�š2è8$™v”?”Uqo¾‡®z= €aœ×Ÿ×>`´ËÕ²Xˆ-[-³×ì~ý8¯˜}¢±UZñL+¶}Âïê7ýö†<ƒzS©«„X”…ÌÞßjª©/ÃjËKØúûC¦yß§Ø ™š:Tì!¹3ϲ¬l•tæJ "gè©XÉšËJR`&éBw09R 4¸~¶EþVZŸ)ÐjYœÁâ2î# Ì&8–VóÌiЏcªÌ ÿä¶H”ÔÄïy¦–°£0“Láp�ºrŒžpøVŒ7Õš´—±ð½¤Ì¿ÎР ÿ꽦šõå d7´;û;�†§ÖÜhPÇ€�^¬r]ÕêºQReUÝœJªè�;P,ŒŽ �¥�õݘLÕw2Eøq®÷Ø®è2Õ|ÎÓ/9¼o¾L’ø¬&>«I‰vì2²ÀùºE~JMo /¤îNMsÅŒ¾8P7�Ǻpwï$˜…1¥ÖÀrÙ{¤kÏÊÓ> KJƒ/±HbÍóÜÖ¯!™­DZ¤Z¯¡n”Sðê¸ìVÀ¾”:£*/xîo–˜YõYL,’«-r‰°Ú‚– mFple+¯|�$¦E%[‰� ]$·{Ì'&¨["˜I°I`5ÁJb‹–\–Ÿ©¤›äv¤<½£A¶ƒ,~ºï…›X•Çiáϵáaá>, «±Áã·”cJ]|s•m_úušõÒá ò·ÞOuÏaò¹ƒäÔMÛŠ¬»‘)äÊ 7ÐúÕ€‡¦ð¾'œÓ‚Y,·+¬�î¥u ©¦šF�× áäÒ0@¢,Ð;Ú:£‡c¢¼S4F¼ kÏ)ð¡¥�HÖTa9ÙÊ’r\¿ÓÏ1Ϭæïø>$ßúLd|�¾þÙÿ�›@7�:àÜeZ_%ôVŸo¯aµÜXxËÂ^Y+ÓL6 ·§ÐHãO®Ù6 ·Wc¢2‚¼†ðHO %ÉôÓ›:ãBxz#›^󪀿¼>àõ7ؼçOŸ†6Ð/O½ñÅC¢HM¦?/ʺšb–I4‰üT{Îì‰÷+‡ý¥Q‹ÜÃ1ö„pNǸ©€íVÖo.2ú‘&òw œ„ûM±á´Ø¸�ù�wñ`+O,ü81øù¥wÆø¼ù‰,W×´ÿ¿Šn3Iôüü° ÷P☠  JðŽÇ¸±GœQb¨¯«bÃÜ8R<.6=xŠî±Q±/ dY:QL{æ9¢š3%Ê:L�D¡n¶S%~ñW7œÇþ¸Ä«?ˆýšáïy/;Vfh��±�A/£Á™VY 'mbpàî9µDÊd™3�r&>ßȪì=RÜÅd¡—Ñ`ûÍž´ÖçK”LPwAö¡ŽŠìþœ˜,(Ýëí@9“¾?Ø :TF±Ù¯Nµp'…3—à·eVâŒ9¶¦ùGŒå‘=:FpË×9ï¾y6_„þsÊgÅì{YMÈ­ŠüŒl¦‹¶,mâ{zzñÀ8¹—‰r#sw©©ç#Ÿ±�èF˼¾%ìÉ5ì�5I„µdXvÿáË„ªhžMzˆ ·šÖW“ÈO-¡Rk¨Èï3E:‰B½Nפ(ȤÖVêŠPiÊu£*»dÀCœ1ÁLIJ™hžW†i÷ÇDåˆ(6'è1ʳÊ+å$ ~Ï'þ+‡cF´‚aÇf[ä~)Æm½‘?¼³’µZG ²~}ØL]q2+íøtÖÇÿã%Ð'&È_~‹ È}ö,‡<Úq€”G*‘¬æ¹qáIè¢&‘¿UÖ±ªr¹/¡82ˆ·‡íùËùé²�]#ôÕIµ z‡È¡šÏ8¹íéNÈ4ÕØ¯ŠÍ�fÃD&ðx‘Š\¡*Í/�ßLxz#R ©ÀäHajв&)ž ÏÕ/-räPÑáÓŸ/°*h­Ù,§"턜Œójªã±ç¸ù¶Æ»R?¸Î Ä%*Òý;ÃU¾Ýò8-­bµdÑRžöZŽyU]¿ú× ¨k÷¨!ù„¢tx‚<û”wùÌ?(ñQb¤›ÔÆMÖp…«8žXÅš¹Ï†^U”òÖMú\3Û)ÝXDêâ“‹Û(kϽ£|!'K—3U6✡bˆ9DMŸ�¹±Q‚C©…µÒô;eÚ!u7³Íª7بƒº©n'ʇÈfhÒˆf¦Ï.¤înc¨À€Ü"ºÈçãóZk–�ùÄaaÅæc‹.º˜Ý DhOßDÅ%)K3TGEe$…Å®w­ýI8Ïúü¨gSøáÍtÁ ™á‡ï¬Ø¬¾Å€ÀY´d³’leí}wpKyÜ`Á]Úì©åÇÆ¨ÌÞLWºJø@ rÃZÆ‹îð–Ý="¿SŒí AHÓÀ1pu„¢æÙ$Ñ5ñ¹BU.üÊs)ì!xë!œ¿ü ÝòVþø78¦2Ú[üÇo±ñÄ Š�ª4û|&”·ùÖµAªÚJ°œà'-#×´dVUG"XœÒFZïéÅ[ñz .áÆ"59„ê© ¿w˜•…Û øR$ß¼6 ›¾³BJþ¹KE×ë¿Éj*AóŸ5Y(ÆQ‚ÓÖ)ÁŒl´j¡®Ú6-Ü-½c��7€\�ˆÞ ý§.žýÛßö.ü¿þ¼ó36W\‡7ñl$¹ô§{í~ݽ,4$£´ÕW˜šÊn�•T–6ß[¢”z†rÌŠ�g{ü?n�½‡ŠHVæPÂaòŒ*àÂãÏbÛ¼� öFžpo¿šø³¢ë¨Ø65ÅyH>à ¸sºÂ�Ójꡦ<—�,±o"ÏA š¥KbëÂÃl‰�RwGÏ0±:XîwRÕ¬!‹Ü'6_>E¹—ã›¶°öq�V’§�äiÅ& n'yÖXþרKÈ(­ì4È>¢f‰Ÿ=ôkf•gAó1Ì+Y³HL:O²l kÿ²ÀSžÿ‚íùÁ42fÞ;r¨aþEóB¼�ŽàïÅ o�·ü5ÝÍ_f@nïAÿ­&Í®¡|(lÇŸ'½þ—«œJ\Z‚x Vܵ{͈3º-ùL%e¾&~vï’'Ü�·.r4F<.U—‡þΦÃr‚5+�ŵ‰Š¬©Ý¢Qè#™{þS刚“[GmwDxõ”à ¹aˆ;‚ DMí-ò¡ce^=ÛÅU*s•Êõg„Æ1Û#°Øtó3ÈýùëØ´ûm©¡e¡¶�¼Æ¨¤Ÿ™Ù‹)wÄJÒBªÂ[Z/òñ“pžõ øÑoÀ´VÆ31‚qrì›È3£*jTù˜ºš,ÐìóSF×ö¥%.@¡Í/k¼élø³¼êZ ä…KçS“3PÇMYQ[5ÏæNº–R3Üyøl*:BqNôœždãÔå÷ϳ¹Äç?Xக<‰å⧆îNàl?ÖçÁZ0õÚs.3I@¢.¤€hyÑ�DÍ£ ê!n&2n ŒfUMfaÓœ¦%9’KÍÄôg?w>÷ Rý‹à]q=¥ƒÆ<¼…†¼H¿ØDM¿y\(#'}¯º™š*3Nîæ{Rtª¸ÛÁP¤�žn%ÊjÖßÙÿ�Ÿ@¿ú¥EùÛ*(µÕ�P~tžMŸ=ÉVBÙ½» >œàŠwREø}è…9™Ã™K %›¶lV•c~z#0쮃ˆœ0u)=q‚â¬è’èi"rEÊ2C‘OÔ¨R]þÕ‰°—…½c©e$£We³*—V˳”ô¢_§&gç¨À›n=\¥2Þ»>hñöù_Z.1½–ã» hÄ7NS¹b?'ŽïJÉ'©ù£ÛŒðu˜|&�%cÅšpU0œÊ/E¡¨µ7ÊX�¶¥òBùÅE¶IlECœk>hñ±iŸ;Úy¾­€—þeÑâïW(þÏ1 —í¦Âž5Ò/Ï|³Â:mzùV;ë´d‘´-’8 QµyÁÿúu¤Bc†êßÝÂyMê%1ÔC:˜‡ŽÎœÒ¶Z¦s§‰üVZ/¨0? ‹òˆ‹8qˆððl=‡ÉÁÂë�³Iól¾™'ì#Ê‹šÑ¤SÝý¬xâ ±Y¢úÜŸ¦ XÛ)�:¾d-¼Ñ1‚´íæžÌ<–7Ð�Çd£`zâ¦wQsêbã‘y6íÉK¦-3x�ÂØ(Ñöžnn?åó`‚s:•?Nä£$àx;à ó·v>’g½î*44+º¦E¥£ˆBÃcȤ‡H¦¦Ê”Gö•XQ@KKf�K»…µ*-a�V@¬R‰·€~£yþö16Ý*ªæºO–¸P%ÜÖ¯èÚ.’¯•IîØB|ÃÚ¿Ã_/laBùoŠ †_ÚBÞè‡Ù¤#M叿ÃéDÊ6ÅÈš3ž O˜�<��t¼ñŽŒ±ÁdØøôçrâ6ûðUùz/E¥Á¡K(;¥#¢5M›Ê Òú½Z ÍÔ]EhïåÆ"»X|êŸr¬ÖZä&EîDÒ r75ÆpÚòˆEõ _¤®ÒÀ8¹f¾ÑÀSA4¼ƒ4 YeÞZ1°Ðe‘ÃûØ{¤È‹UÎ4é)?"¼¡qr �çR ‹7x�'TÄhºU¨|üv—•5,µqæM€çãÆ²Y´ä£Äã´6òÅ/íb²PKQ_£ÆzÉ™]ßx˜-4ûÒ>tÝÈ$ +èe,P-­$§ä›´ˆ†wÓŒc�Z©¡i¦…¦Rö»Jx˜Þ ¤îNÝB9õus×kî 6¨†¢Ò§t<Øï]|˜|ïîT—ЈKf@¢]�‚Ë-ÿä1ŸØ¬ �õ=Þ±âÄ¢�à%²HT@1¹/ÕŸíBÛóMá7‰|s‘SÝ€”3�µ“Ñ`‡óìU‘ÂÞïv¶­üµ˜ÜªpÛ‰Eœ‰ =ýò¶\b6ªí‚&ò›©ó:m»ù}j3JM ³vß¹@¬o å7g¸âŽ�å4EõjÂéeÔîU‘ÜM×ÛœöŠ v?QÆì* U‰cü¿ÿ‘|åkûÈgíúBŸ¡Ks¤8õTèÁ•ðv Q`¿rô¼aÄ£�v ¡ÄY3À•ò\Lqi Öä vž¾k“œùÁ]f‰ÐÞ?D®&#†A8àÖDÖ~r¾)6ü磃BUhÊïþ‘yCîXçÅ^иû¤…D7BN¦p#yåÙ¦y63PÏ`¥%$ŸáÑÊá òâüñev(4UñTáÅHýÎ#jÎÎ�âüñT*rÿ5Hdä —-cK ÄÔ/–ËI@’P½ýZ¤ÊŸ=ÂùšgÓ\“žÆ.£)@TsÞ ‚Ñ1‚iQYü.çižMìSžÜW÷8½š=-ZÂ_î’ɤ¬vBá×sól‘üÔÍ÷šf7'NPœV§ÚþCœ~ÎhŸqkÉþýìÇÀ¿åü‰ç£‡`Ã�çy`Vïf’ Ä­ÉQ°¼¤ÏùyýfÛÒ�Ë»JØúÂo‚�à .X1ØwE(>Í’E0Ф‰ Äìam#ù,‡&móIýÉîv_Éõƒ–~ç·CZôàÑõ†¨„ƒGÐÂ.,Áš°¼¶,Ä‚Íʪ $ ±]äÒÏ}†ë×ˆŽºD8ø™þVmÀ²Žö…î/^HYÒõ_Àf¨ó5hE,îëç·±Â�eõ Y+ô`;x_·°ÛßðÏ8ýG±Žì á%f_ëoú°ÚÜ*Qä²Í6ý$D´y‡_Ú¹|`VÁ.-°Æ±ûŽ*x è²Tò¶¦(¾àsýI¬Ùàù´yÂ?®’`“OÀ]kq* ic·IÖÀε!hµ aËó>Ã#_Õ%h}±‰ý¥óHúÒºmÇ@›Z”0ý?P|~/î—¿ˆWè¦�H˜;nÑ~NsÉš÷-bÉs×À²Ü`­r ÿ¢{¹µÕ¦ú°7®¬å^Kˆ¶lÁ²Á¶7b�Ë2žù–”€ÚË »Áë'+vÎöL󣞇3ùߌe”¦îc©² ¦H—¿z¯�®Ž�?:¯ÄÑG`<Á›“ÅŠl´êÓVŽqå8t|kĦh†*„f¯6Ïæƒßâü‘I ½chÐÃ8Ĉ«B«UÃcꎲç÷8ÔÎq\KrYISð[ɱ&ì›OQ¹éÆË§(ß9Må²Ð¤ÓY�á )úŒÈ5¨äÐl¯V×V4°…Õ7n@ÎÓþЇö•ˆß¶•Ö èU…WßÓ…9¡¢¡ÛžÁm+íÿg`”Wˆ {�n®Q/R·õ\Ð_UÐû ´ÿÙ§ý!ŸÖ;˜؉*ìR¡J �¿Ùþúü„œK8R¬ÉÔ<>±?Ï¡Ùk*£Äf%ñI”'V޶l>½‚ã�Lüz�I�£ÌKÎ6®¶a E%t�Užp/Ý;Eº¯ž, Ðæã¿½±È×.qŸl¦Û9V×G•ãÐq^»c+QÍ‘°/ ))42Qéøx´u¶Z?J>ª£õžÊt[§³=þ7©{Ø4ÒIë]È=&ÊÇD™]*H¢Ù4iýˆð¸ùž®'³ü«yô°)Ú,ÈB-‹$®°4óó´žÿ<Ñ}�èÂ`Š[%6Þt'•~áíLuá%]’¶©"†Æ ÇËè£9Iò´×Ú ¬&6í” ²ö1®¸¿zHï•Ý£F);pëûÉML��dtáÐEEžùÌã¾ûfŸ›Vþe¡Ä�k‡—]nm»|eÎçà"Îû>ÍSŽüÍz °�Mñ:W×ô{KSÕkD×3DÅæ¯b}øÓ8øÊ,ÜŸø<°–ç­:|~>à-‡ý7³ñ=»0� ¥d�Ì2š”I"?ÛV]ÎT¹Ìê'}Vc%•ˆÛÔ. h„«Œ† ŒöVÌïa]‘"µ‰<“ƒN^fj¤§nïFç£&þëx°[ ˜^½ÂÒÓÐó{˜?å2­+-ì9ù,ÅyŽ? 0Që¡1b\`FÍD}p…uºÿ�’s–Ä™Éq}°›ºÅHÊ 8ÛãÿqèFÜðÑüwNS¹sšŠñ)ÃM�ƒFº'åÄ–"¯þõm”ÿ|û5Ã>¯¿ñ¾zÏ~Ö +d×Çéºgœ®‡{.Dÿy#kŸ¨ÐjäÐí>ŠžÆÊ®~Tí»�Ã/'@ èÆ"S*sþì p?þv‡«?ëóÎQ›Ëþ:ÇuÏïh¨÷í²¦Œøb¦O'uÐ_9î˜*oEï.°¼³‰ÅBÛ"NL?ÚN°ÚrˆeóˆJœZ†•=ì˜íblg�¡å0Å·²R¢�í*ê®Òº¼‹öª1ŽXI`F8§„·Ò6ŸÑ–�T@I‰¹E½©ŠT1ˆ¶ÔìÁ¬„%e&…à¾s†êe¢ÄÏ_ÿ|òá»àï?‹õ¡/±ã÷¯ãw†~“kÔ…B»1CU¢‰|ê[z*ú­ èS]èö<­)¢�è·^„ª©Œu'‹`lgÀÛ~f¾þJòo¹‰-WÞÀyW]FxÕvš*…©8çQÔ•Ô„1×ÁЇF­f4Í;F©`èzygÀ#Ôqöcàqèu\SXÉlu̪uL”S�L¡FŸß ß ÂgS‘pÑ%EÆÆö)²K…~† 5ç0¤ ãPÒôOŠÒ¢Zá×õðU9ÞÊ3!ŸZ.GWK¼¯Uå×bØQ…>á�“clØ´Ü f¼Ô‹*—sGy7 RL¸¡¥Öäô§žaõT Öø†ãùl~m7�(Çt ³m8%¬¤�¥V;§X1ê©kk“±Çu ä¾c=eÔL mM’yº»BvÀôž·,çi)@íÔ©t oY¸ó©h…Ú-$ª0£ÿ¼Ê/ÿ #âùHF:¬u�U; qoݻǨp¯ºù㹞T¡¿QeV]Hd”X33Lã"Óð*¼ï}ö­V¸/)ò­–ËÑ–ÇØªÅ[ó\ý7™„v˜VÌQ-Ï89.;Yâåêæfuqx®‡” XïDÕt¢+�ömøc¢�¤D*8r«¨Ž‹®Ž¢LŠ2ïØ1¥œ÷ªÃ¢r¶ÇÿON Ú!u7j†Ž¥Î€RçË´š~’R&ݦ8c£ÌZÏè«FtÃm‰ó>xRI(0YÍ€+M•¨~°žñÒ�–ܪpÚ2AÝN’AWÓÿ�X[Åš[Àþ†(|ûÐˤûPšÂ¢Ð®é�+F‚:lâÓìóͳ1Í™âL3J½ëjrРǺgÿšC,XM,RÀ «‰Å餀‖È_×âçÚ»í¤ž ô”“`@?2žù¢§*7ÍÿäרªÓlEבc¨Q@Ê�¨s·�;ÆÎ`RÞy+UjÀ48D!“¯ ÷r¦Êû©ç$Q»Ì0—ábŒ/ÊÒÿ&¾A"Ö?�>4nÌ"‘QD¢ñTÏ…>5•ØÕ(Ð;Ð;|\l¼Aô ³¢_ŠrƒƒFægLf_^§+:3{ºë‹Qœé�f)ì£úENã¦�äoD+pª�ÈfUXZ5{âÅU¬GR1ÈvËçÔêôaöïÈeˆ+¡@Ê_ën*aeuj£Z`«ÄV¡`ˆƒ…{ÆéúªØÌÇìæB=×e)Á:-Xia/Çx w¶m¥xnœ¶0œñ4ÐS�EwIÓ²¹·åÒú%³‚ÔS “Ç“O?çöŽ „¹§Õ¬ïlÛigZuFXÒPVÛXJq±(èàDñRÆs5B?bO¾ákþŒë™BiÍ™•iQ1ì?c„9:œjþ©YÊÓ¾ÑenÅØ1+±XžÚq É*–¡ÚZœ\!ߘÖr)©œ¥Ö:S)·£g\FîÁStëAºÓ 'ò›Dþö òŸQD†Çp"™@1B™Šª†bÜ,q§*4F¼ýurGDñ˜(ïêOc%FR·”šn¦*9á’Gù·ÿô(mQÅZ¥ e3zgÝX¤0÷,‚·ìñ¹êÍ”uqmŽžÃsô ­sK5>Ö‡'È“I›ÇSJãzÿ¬Î^†{­l¯zfpdžc —ƈ×�¾’ãdÊãV ÈPb±ØÆ™O@ nûLª}•fŸ¿gy3�^'CЀáÀ§«IDÍ™˜ ?&6�[G ö3ž“Ìj@C6}è–åÓnÙÌÈe^¸'ìSkIb(«Š±â4ЕzbVfoVxÿcëµBî>çk(OMåÖåx_mgA~&à“4èãÄZœJ/kͦm2–ɪG[t¿m”[çGh”@ÇÙ$±ñLkïŒ$×Ôå‚1C¤5û|•r¬Ô-¾g²w¶©H¦…Ú&¥?ÞÆ:ý%Bc÷4›­ÀÙÀ>óyÆ+½‰x‚üœèÑ<›”Âi³`'g¶rQ=U°ix5¥rRQÓçÄ‘"?¿ü+l{Õ[8ïwöòŒËžE´'Ö)E¦˜XNƒÊe8׃oÂŽ4ug žYt�ÞþKOPÌôÉ;ÚÛÑÉ’‹Þê¡UXN\I\èõ ¨D$dˆ‚šôè>6ëÌ@sS×�tÍD eÉ�´:©»=•àO`19#t©+NìlÅ'‘Q»]n %øÚþä +eu‰ŽsŠx™Œv6ÑNÊ‹Ìó2~èFÏ�5K9Ú_r8ž a*Á_îZ‚cp°Ô6+úÃkXó_0Þzf‚Ξi(ì1³Â—²çݘ¡:&*ë&¯!<Ãv¬9¡Áÿ—cÃ�ñb‹œk£Tqç§U½ÁbRqËIž¸Ufùíý¨€jþöˆ¼šøƒƒ¤ˆÉОNÙ‚�­b'б׻úþ‡ôýõl& íÔs&¿C䨍~Ü÷Îc�–G[s²91�ýÞ9<=—ÓÙ{èJí�ÝŒ’íÓÔ?óç¶•¶SŽÉгÙ6û¿‰ òf²h¬wTsžD|S…¹Õ"Ë‚iážZÃzD«mìeá(ÁŠã€ã«Uâë¯5ýöîÆ™r«3بÉ8ðRŸ2ïÐ!ŠWï¥Èe'KøŸ=hÓ2Ò¢ZxF¾ÙCêB*x§½’8Ärˆe1c�2€ÕN,¾³_û"}ò{QÀÎÞÀL"3w8œnCbÒuçø ô–,Ûh-káY,ÄX­%ìeùHeܲ�(¿åÅ}QjJ˜Âb%#Þ1+º2°É¤(œùže4õf¨¦ôÓRýmŽÓ+vJ8²˜AJ€q“Äéb9ÌÌãé†t2·Æ;˜t3®Ò:I!ËðÖ¨@Vd|œ~ä…ÔÝ]¢p…¨bÔkMº^“£ÔF‹²~ÉãÆy›Ù%cª)9¬)Çû«¨Ÿ¨é_t#Å]CFL© ÎljñÕÞ÷ºCíYô~äíb²³¯Q„ÃK÷ Ä•çh‚­e‹Ì½cM>ãIzÏþ:¹h†êÄ„\»G1>áOV•'ÏTéU…¡q#BÑy”7ºIá#³ê§¦õ”ݮÂ_!ª.³;Ÿ'V�¥²v,üS"¿ ‹¶\Ve±™rë¹ìW._@ê¾Ú�áª+òw‰Â°¨tRÅÝ "dŠ:¡!‡„Ô]¢¦O×?Öµ„²pf�>»µØîB©8cœ&XœXF±Õ®�m&pŸâw19R0b˜cÚ[tÑ;\þ5ÉRtcð°.uO'ƒÙOVaµmj§ÒŽÃ²,’ø¾sí(cA¦¿WO÷†Nª”RšrÇ;üñTë=Õw?<‘ªI9ª­Â—”JSÇ-›Ó`Qyâ8ÇbBîºezuÉ:3ˆGÉ/ŸÑt3RPößÔ^"m+0…!,q¨H8ÑÃëÔÍ i¨�1ØnÝc¢ÒE¼¯È„™ph¥®7Éb‰ïè<âwñ"UQ=מ&) SIÑ�\�døúÙùXÆÙYÇëÞÍ�ä ׯüÿÃ?`áÜ]Ãî¿ñÝk`·Û8±•È—•€e�%,òkÉòì=žÕÍêöûp¾¸ñ�í[xàk¿Ï¸š‡ö^Íuײy»Gõ…ögŽbå1§y³—Q³8én`sæ«Å 8•oµ/êú—ßý Y£e.B ØNBk-‘%|<,^ú1v¸G¹”Ä€3,¢Zâ*¨5û_Àú_©_¼[ô<`]NßÅ÷Ìá i ñå„—Tø™׳XYvNØŽ…,g-{»e‘ؘ{Š­d¾¨Ø° â<¶ë[ôŠÞ{E90 ¹Ä\jla­Ëè +!¦VìB˱$Ä$Ë®�ø‰¬Ä.ñÄïÞÅ1àŸÀ¹a~;6Dð7XP¶èO¯uïm‚+ÓïyHÈüsu;1cq.»þ¾áñ_þ>!¶||PËM,7�‡‚ViÛ6Ø/Žxÿwîê;šBù-I’°°±ÒÏgŽÒ’¾£æSŠ£5à¸]]Âå�7þOœ¼šk>ðn>ýW>ø•Íô›gÿ¹¿ÁùYÐ�Ï$°þ*´pG.ÐʃØ1o¼m¦’“�ÿðçpv¿2\`­3#Ý`ãŸ\Ã~rí,ÄÝÙ^Ñ¿ðŽ¥nc£ûÈ�LR {õéð®‹ÄˆÚñ¢±^* _ˆ�3hªš>R×3ÐouϹœ–C,ß ¹’ §æž‚^𪶞3m:jr.ÝOÎìÑêiU^vMÿˆ(¦ ÏàËåÓñr|ô†"Ÿ8]àŽÄåÛË6“Ëð@l󉕟üŠòÑ Õ»Ä=H÷.Q &‡ÉF�>õxè9%Vß\E×çÐçËèoôZ6é—ù»ÅóR/õ¼¦Óªt„ÃO…¿XfF�Q§IpŒ˜‚1O8%˜[!w\”ç³"aÛTÅO ÖVóLËâÆy<=û’3ŠªåÛE÷SÐs»øâZZèji¨¶°Úm˜N°Ö–qæµMµÝø áœVêvÊr{#¯éG²vŠà`ƒ†ª[bû\Ï6ô+›Ð¶Ðþh™ögtí&ZorÑż~3R`� ¦imcÄÕkDÞU׺\¿\åÁ¸À7Tâ»+>ÍÄá}§Þ{ÑHu§ KQ×ÑQsö3žëS „‚z�ÒØ(AŒ-²<ÆÆ*?Íò ª,Ï{¨�£­€Eù<œx<üH/úu& Máßhä¹mÐÏÛì[ 8­ÉR@,¾xïçëçhž,eæ ™ÄÔ82>ð)¬YÈíd0FHãñSŒ“(M‹JcˆÂ‰)fé¡z\ôFX‹-–„sZK‚øõr²$#ydõ�UÆgs<,—•5X‹óÄ-�5WŽO>ü2qÞ]bÃ¥YeøÅiË+Ÿ펈âÇn§û`ƒB'ín¨ÀÔ]¦ýÛyôÞ<ºÓEÿb³vM…öoý1=Hþ%¢8"ª×,²mPÌ–k^äð¦Oº¼w.Ï—Ûš±Çå¸{럖p?´J÷ñäë^„”£ò±éN+À~úZŽ5ÓÚ Z«Xm³Wµây˜ÁÞù8ïQ ˜—ÍT‚uä p¢8,‚h†j4CuZT†™®t1;,')ÈX?±$ü¤…õ�pfÌÏv²€›4zÉ"Ö#ÂZˆqÚw ù„²ohÒó‡ÓT� <õ㿆õws|ºUæ_âw-ç¹M9þiÅçÓË6#sTöä7_¿ëâÃä›ÂO}Ô¬‡îbC(JÐ,mB¿¹�ö»Ð]=èö*qÑ%S$Û³�¼d°ò¯Z` ’ÏU*#S‰È�Ž¡ ;ùד (´ûŒ¢�-܃‡9VtÝrÌ`¹V%¼©WYŠ-æ;{&ÖZ§dÓŠSuÚ×�1 2⩆"—+óÄé‹Ùòú×±å’×óì7\ħ~qÚ“ß!r‘È÷2„o?‰BVÌZ¼GÒ‚l3ƒ%?^}�O‡ÉŸ8Aq¼N—¨9»Éd“ê9tz#³õ.öžØŒîéâþUM¿½æŒ â5K”>÷AŸIÁbB »#@à«Éãý×õÑô/Fy¢šÓ¦EBÃÄJU?%#ç;@½D*YRw£LÈaÕœÌñÃÓ\p\l•„ìÆ Õ·eùOý…ËOåù¦ hÑô½ Ö&^µ³*²Ǹk‰ËIå¹'&ÿ[¯6YÊˆÇØp@m"ŸGW”Pj¹šÀª‘§²Úmìc·ÄbbÓN\V’Kq‰9=™øJ2YkdeRL¦ý9€å¢×;Ì(@±gZm±άŰ Ü™6îtb¶­O‹jë�ÑæÑÔ…š6ýåyn_s™J<ÔÎËá‘5¬ï) içIÚ°˜ “ÓmøØ|•#¯ewo% {'= ÷²¥O=Ć+D•† Œ Œ*S¿ä"“Vׄ³œ®Q%4‚^Æ¡à´Ø¨´ÓÁи�Kó±÷ûL+ŸNœ6máEX‹‹,+Ç�#Mä#£8ƒŒgÍ“%þèø&©È!›©qr' ¤/ý~Ã÷`ÃHp˰­L¡&s˜}\z$ü(%d ‹&‘qÚ4>åtSMsç4•ýur!ucPè¼÷Ú ©Ä¶éŸÖéÄ!V•$qxïûèñú� ›þ/ŠpÞö0[†ÄV Sezµ‰WÏvqHEFPS>lâkšÊ'GØvF)µæy3 ª'Óª.½£{AÏ+ò=åXJ§%Üá-¦Þik2ºì31ÁZË´ëå±øÞÂvô»|jïf$—=ûòD5'Ï-¯*³¦Ì Yn»ÌÉc^Ô¡ú¬&EXp¹~Þ壯EʽsÆ\߸ȹcÓGNqÚ6ªù<é%opxÏ© ÷/æYUÅy“ÒÆíÄ#NòÌ$y‰Í;Obø•—‰Ò³EÕsüö䯧±ú{&ó<”àÌ·a6ÁÕš1tÌTfVcÓÛO̶ 0Á泘pAëW¸JåL*Š ¥˜ˆ¢(�ú½oŠ ‡çèIr\4ÛÅÔeÏõ°÷Äf^¯MH4T E]§®/ï8E7Êã}êƒAFâ±–Ìá­¦Û%V…sóuý©ÖÞ‰)>tš ÷ÏP%í(…nß.ºïöïÈv Âq3¯ãbÓq±i}€7”y¬?vºðg=г½J/cAF8ØÁþœ:dˆF#t¸äP1ÐÏí})Å9ìV€û…×Y�C’R73SÁöZ@Q‚÷•Wñ~ôŠ".Þž•½b3Õú‹pÞù>üw$~ŽÒŸ¼ŸóÞökHîî1*ű1*“l+ 2âEÔœÑt pìò´O…fõÌ}¤žã;‰Åœ”…™•UüãUŽœ¥e‡iYœ–™”Ûóm‡cI�ï0)ü€‹dõ!ÿ¹+ŸÇÊooFwç9�8,´}–äÒV>%zt£v7ºg Úu*r­J£cf[ETS_5k'»ƒ(·óCÎgå·¶ÿ/c_ÕN2ȯO¢"R‘õк3@;Ù9]ù݇Ø`°ÜHn•é;=ŽÊcr g>Á9§.³ÂŽ—-æ‹Ó2�¯U›“2™Âb’c^põç̵Ùêìÿö lÐ4•´5—«‹�c)Œ¶¾ŸoÕùG×,jaiO ž’3Ì·µÄJ‰'6Z5B‘ÉjEÍÔayÞ7ˆN–‘76J0+SxŠ„ÏOý×_¤ûÞW°åÃû†›ñ÷¿ƒ�±—ç†ÏDç9H�ú@N©hcÆq§/ôkûREäZ„œ&ò¯úPÊ´ºðsÏâIïy#ÝûßEå5éy÷_ó„‘WÒ{úâL·–ÂWé÷š,ð¼ot!åig°Ü„ÂrŒJ¸6 sÂ^I;k© ¬ÚøjÁÈÿµJN¿Ü?Cõ¡Ólò&P>Å«;ˆ`ÏaòDÆ}~›åç�Nm>-™?[ò‘zX˜íGÏCrÙ¶«�ºÏXL(χ?}�ÅçŽ[< ‹Óò‰×`M8Š-¾—X9Éi6ÞiÐu¹‘!C¤êe,0ÛÍ~¯)|í&D^È€;:F�¦é�1~Ý0õ¡C¡=œÒ…IÅ9”šD>~=Ú“ï`Œ_zcE~Sø×F†Í&pÇ/5ÕŒð'&È:”zmõI£&òŸÆÊ%ægXÏÄBqÀÜìFô|Dñ`#5°�Û?’‚gÊŸúþæ M-#è�ÄJ<Úòùä Î'?@J¯$pûQ!&(©‰ùËRˆã~åŠèµÍUƒ2[0”O?6Ü•Ù÷¢¥,° KK‰…Ö`EÆT�'¿e’O$¿)üz�.‰ªYE•ãwµ™pºÂÅ= 4KœP‘[UE» ¨¿­Ã—àWKKG„·{” Öè4<Úu‘ë>/V™;¦ÊD�*¯×&î!ÔFŽÉ0ìBÙ»wš­pUÀþêÕe ©«•n�æ¼Yq>»Œ5g²®c±ÒaÅÙ4Wð´çšT7ÿŽ•�´sÍH> ßHxVß3˜{V7W·XŠMÛшpØ´b³�y@UnŸfkOŸ‘Å픂Z@³]°öl›ÙY‹¥Ø�•bSĵ[3E.ÙxŒ²Æ¨œ¸Ñ¬Â»Q�vë CÜf3³e’»ƒº‘Ò£Ñ ÀkÆ~çº@϶}aæ'"ÐùAXŸ›‘ö;*�>]¥šÙ ‘ꃯë)¦”ÃtÖëP×íÛ\¥4Ï9ãJQQ°ws77xãõ6W\‡ýÁWðÎ[«4ž\ E×­i±Æ¬b‘ÿS<ô«^ºŠb­ÊA:ƒ©NbíZP…ï´Ù²ò"nR%ÕwékúMäLsè"�« [×㜈 æÓ¾tF Éè -ul�ÜÕ”i–$sÂZlQì²’`O¿ …�)_Þ|7™K©Ñmç1$EüoŸÿÈL•êíK«XiM"Ÿ~�î#žI:l;«mF�·˜à-±ßV™ÉöÏ ¿54Ú—)vt59)dÖ¹t?9–(êNüù¤È¢Š(ñSÃ<%vÚÍ0‘_¯SSéâÃäSIl7 >þihC�×]æñ_¯s¨]ç°÷�@[0¦ š•»#B‘2!×#î$Ü< ©…³B¨mFƒ6 Wºš‡ø�¥Iã¿G ÛY§û”ôGÁQ#^ækeÞ“G dçØ ®š†å– ØD5§¶ÏèÆ]�ª—3U~3Õ^ÆêQ ä.Å»dÚ/¦ ùݼ|8�0Až¶}ð�bƒDEîoSzÿ_36PÊÑoR®ÃÎ+¥£¦¢ ‡ö­¸$8'LËæ}Õü»—Š;äeZlÞ²r,Å+Úˆ„õéÏóRÆÉ©,Ó��2²L*VxÖ]ÍÅá[}Ú«°`”o¼ôžr2°]û‘$cÆ� ô%³ê[Æ|²È¸žÆT=ý>]T7zpý#ž)~5 c ŸóÏþæVì{¬YU‘¨ÿÿ¿~XÃ"¨‹\'�³ßO«î�Ô�%ÕiÏ,qlÀÚ% ¨ß‹D~XŸ¹—îÔ6Ç&2šbȽKl›2|y/cÁÝeÓv{­“{8§[Ø'SMv%…´ïò¹CôŽl)l¹š¢Œaãy ãl•ÈõŽЬ—lùŸo&”bã�Jвœ¡„ÂrbRƶ°cYLÊfºU0©{‚ý±¿Fò?”’pÒ{Ïu„:+ÊÙ ôù¾õ¾“"mSeUøk1œ’)Â-&™Ž“Ñh­–ÙË{Š ¤<ßÓôaúG¼HäÆÉ=[T¨É©ÑL餑ß$ò)y¡­$+±ÁãÛ§×ÈÏ&X'E¾•à()¢¶ÏḂ~sýbQsÂ:¥¨‰o‰‘�ê®Ù‚U]änºÇ:õóû /•ïÞ.±=Ë 2!’Ç0óúÑS÷ïgâðCRôK ŸoSd3U˰ó:Î(¹š"TЀE¿¼h]Š;ÊXp¿Ñð*�‰ŠÆ¨¹£|3Â'ª9¦ðÚ¼\Ý9ÚWJ¡¤§c‹¥–…!ôÐÇØ9]IÝR=P jŽféš=4d|ºkrŒ…ÐDžUŠøÊóžIèíäQ�nÐY«°¦€–ò¬ìåÅ*…éý¬3¦HÑV…¬cq¶ÝØ(_œçæ{º(ÇWX¬gQø±gðVÓÉ-¸hŸŰâÄeVÝè ÆÈAÖƒ§è6è€Ë€ÙŽ¥F–^DÍ™kÒs¯0›–¥€ (¶˜•ÃÂJ�ç*ÌÍ=…å ƒö)X5”7UïšÃŽzîÌX ݇óëÇîè0AÁö¨@?3AV¸?Xék )J^èOÈŠ{©ývþ'&е®Â¾~Æ[w³nÇÕ3­˜ßt'•¬ZÙùÒúš>`¿ôÅaP›È“Ù×^kü¨›È¯Ñô%ñq±åô$gE—êæÿGS¯ë04Úè�ÏÞOnÿ�Á7ûð•â¾ëûÉÉØû”~c€Âû«×|1Ͼ@þ5ïàÉïýÕg‹Ê q{±²v^æJ ²GñL 6¼q”Sª‰†j>Û~í/n™Çºï¸pÕ‚%Y(ñi¯æ˜S�“ÊqLûg)6^…ŒœVâF™jkªt*‘«§ÿ~¶<;ë"g@<µR…ž[÷�¿æ4Η˜iÙ´ŸxÍe^0£"ŠMÏ{l ç¦ÓxûöP“s\lš]©£Ž±·Â´±Nœ ¨ÌÁy!²GDõe¢Ìe—n¥úß^žãÝŸp G]ö| û=ÊkŸµuhÜ€€vžiOºš¦2u å(µ¨6ãf8˜š¢Üœ 'ìx¥wœgìrêÂíÝmÜb5Ŷ™U¥ÈÑÁ3®.‘ðG&)Ü)¶?°h¸£F ØV?^?òTKí™ÃË¿{ ‡i 4) õ“Fÿ˜(�›�ëÖ�3h\T,ÀºZ/%ä^Šr©Þ»{�FÁ€)LAã.±áãb‹¾ÅF¡¨u¢�;R}í�ôjàeðC&?6šÂ?C|ÝBy_DÞà¨ë.5å/D¥ŸæX™èd‰kÔŠÒͳ)CWlP0ýشׯT[ åCä~}”M’ÑC'Š”—~×BuœÉ4ГU#?•¬8Ì*Ï\«Lòý5•8qQ±/Ó>3+Ùêu@¡3ßýÙ ô#©z¯‘KV‘úäFž°TÃJ¾�c±•ŠH¶N ku%�Z.‹²h×ÙÖþ]>t¬, ͳéä8[�.¼üZjK•Ž“ÜþäFRÁEÝwœ¢{@”�ò|èXùŽaª\a¢‡©ÊØp°­A�fŸo ©Ø/Fåt+WØûRŠ„² ¢æŒ~…Mž¢;+œ5„G¿<êÆ+]¡OŠ­ÇŽñ¤YÑ54H¡Ñ PqÙ¯59O{ŸÁµ1í×�a¦4â×ȼõìÌÙæ?D K¦Ÿ˜i^g�nú�5€ÌÁd²@¨î˜*3Ⱦ,¤d8éʪy&£ºßÈ*6—*§Ý[®-( ÿÃbSs‚$Ÿ�ªÜ:ÃŽŠm)U÷¸Ø´ð0[ê!ç2öäÀ89& {YÙLÖõœ]á¸}4}ˆœ�FÁƲˆš~ŠðôØ{¤Èð�FÇ*\¥ò5¢ë¤(u´S¹ïT¹&÷X=§ÿ�Þ)Äe/›ýÒ³tL”3Tïœ6zëRÊC'´9r¨ÈϾü"J{ßHù5¯£äÙ¨ž#Üß²›È¯‡¸æõÆø°³ž, e�ÄMS!ª9ô‘ö+'L+*Mû!+¬¥ ¢|2~)¹[ŽQnfƒ4ÚïEÁ‰Fõ¦A¿¦à›T’ÈE‘/³÷ÚªaCp*Ž2»ÁÐ~ÓÎ;¡"¯V—œ(^ÈÉÒ”c{”GÊ£(¿KÞ>ƦÝ(©»—p¤¨uÖi —;™Dª ¶}åÆPEÈ@îÈ­T;Ü…z=‡A›Ø6R`G=w )ýWõÜ@êy–Ž£\8Lde&“ë\vìZ p¦Dùð=)³ÌV G—’Û�!êP Ü˧8ïÑCMyÔïÝ!Î[\dÛ~†ru”;.6é[lܽÓXn×Q.¢æÔEŽqŒ„˜ä3Ù( ¹»G F ÐÅ®Ñô Í7tá¢"ê7ÏþÞ9}ù9ïÚ? |z㢬º±SDzªá�‹œ!fýdúú½¹-a7›”$òã)ò "CãK ~[À#²XiITfA[X»MÐ%ÅéLªw”`¹ü´Êôê)­×æi(¡Ø€®à¿¬þ ‡çzŒ›†ü,À_ñ 6Hxa�Í>?5.,pêÁnt¢ˆTbXÆuDUjrt˜ü½¢[¢{Ôð£íiQ¹?ÕE‰ÉÁBúY%hx‚ºû˜ëá"Ù§<2RRFÁ&›°ÒÁ›a§s€µ…½E¥…�}¾�µ°ÊÓgÅÏKôhİÌRø«­Þtj{|¶ýŽ;(kœœ¨9 TÐ,]¥«¹¨˜z›å4I¡VËŒåf‘ÑaÔÕÅÉkKÔ£¡*ü¶6ò»Ú@¨ :T4ˆÃ>ŸÔqhœÜÁ…&òOp¤!§)üÛE·féBòÙs8Ͻîù s=9Tä3¯3<]RÜ6rºšýÍP½DÙ_ï¢_O�ø5úDEEâײYOfd¦ŠöäêgdÈjÂaBùnž^å¡ïPË'VñÃüÌ©_`l8èÝmì¥k„¾�;5Eùžqº~b}=yåÑ{ŽÎŠÔORÚ‘WŠc7Ô>¹;y6|5ɳ¼ì°¦"jå˜W…1ñ¢?yNŸðo9fàŸ Q|¶Ì<öŽÙÜÙÆú_-�{Û%¢°ç»üòÄEé ì 9}4M…3ô„M|îØXæÄ‘";‡ŸÂÅöël}É ø�ú®P•¨ésËåå[E5[Ç�U’©œ¦æ#·R}ÅØÐ+Ìãü/\ ùc›Ï¾þr÷}ïdË»vÓ{ÑsLê'"§7Mõ†�ÚICxO¾‚ê²³"B{ð …Ôʺ˜íùYñs«âgS…”TB:å4ñ\]ãä¦n¡,T5GÒ=ÿu6ÕCÜË¡üß_Á†¦ðG„·‹ÉBˆìíLäÃÔà�“×–øýÜ/ó„ð•ø#Wá¾õŸ(z;Û^3ÈÓÿàâ>ásâ¢"¯ží¢6‘OÇ”;Êp &òBÞ˜Ñ (¿}”Mg §*ò”·üçßùžtÛ¯!Qd„z�ýâ«(æ3tGû –}DTÿ“èâ)'~oïw¾Ü¶¸}ÅáŽU�/·ñ®ø.üº8ŸÕPšÈ§6‘g¿r‡>UáÈ¢�0<£ƒðá¿eh<'‰f_–Iʾgܰô~"ýûVz;C í¯“KS¯ŽP^�Ãù�ì}-®‘}ÂNV`:±ˆã‰(~ù5¼ìX9³/®Ñô)kÃ6´`$•–¼öù$Æ[,¨BkŽë´?sÐ0+’a )†Èíb0ÄŠclùbgmÙ¦�x,ŠÒ?¾•èd‰�ºÛáõÿýOK¬) –�V�bÉiQŒc¬ù$ϬØ4òJ4àî‹Èk7�)ŽÉì§z_qa‘›Où®Œ‚J;$)iå_øø—¼ó—²ô?Šp4EÙðˆ/6ª³59¸ð>2_åÓö“˜`JxKcdÚg+ÏðÒ¾ò ±!µ 2�pvÔÉ ²­ N�Üô¥ûBÓëgh²ŠÒ` %3ìë8Ãòc˜yny‹(^!£Â"‘Ë 0CT p›Â¿L”î•KDñÑÓÅ­»»¸~ÕáDâ¦z’ͪåi· $*ómÙÜ0ƒÿ‘ËiŒx÷‰ÍŸ<Âöq‘ o€aÄE*|äº<Y.3­"§dh¬ ª0£.îùÁë2«.ãÆ+—õMù<á-¯Êñ°,N' eŒYƒ<´–cAy¾'ž°û•4å÷!ÿjQ%N=½»J¬¼!ëÄØËúÿØû÷0¹ÎòÌý­óªcŸt°|Ä!"qB:@Œ iNJD&dOe“ù<Ÿ‡™é$& ŒíU6vÒ`‡¶1c)ä4(†`£( 2´MÛ´h7Ýên©Ï]UkÝû�÷]Õm‡Ù³¯ÍÄ6C¸®ué`!u¯ZÏzß÷yîûwãt ](ºy�Z£ æ+¡MZ­o’`~L ýùü0…›ù±ìÆ»·å1mY]J`.íå» ¿õ[¿À¡ësPóÆÇˆÎg2Wæ‹·•iµ]Z&éÓK·(Í’¤�$ øúûاÂÝÝ€ûJȰòÛXÙsÿbH˰Â2õ–sV.ó†Hã,(àþ³—£ÝB9Ù\.H`Œ´�¼þÈááNÈJ겞âYõ[¦úÊ„!Þr’…0ºtD¨«ù¸zß"v~Kìšœ|ìÄÿ¶—áºÉŽ�¦Ä¶ûÄÀÖú*uÙ$�ÃSy]iâ�eTrNÇ ˆë[ï¤Æ`C,ÃŽ¦Své�èÔRÌPÝ·ÿ¦Ç näÉë-8K)~ÚÉ(³ÐÚ€ÓÆ$ê)ñXÔNÚ×/Šmµã†=WE>W¨àòOï5Ž7 ll´“Xq¸{5àïgÿøvdrøNÈCM‚Íc'xzL ýÑÒÁ¬à�<¾® Xn é†bÖÛçÑú+n}ǹ4dŒ.5ÂLå8ù79–,ŠÈ"ˆr±‰Ê‘(ÇøM\ªø˜(LOS¨™¬ñ|Èò•1ßÜðÙΪÒ³¢Ÿéൗqæs 9¹>@û*ѺÈá2sc‘ýÏýMü{—<¦Sèlø¬˜"÷Φ�(t'1Ì4û †h�à½g8wñ7þh…]cKlo4ÈW«�ÿŠü¿¡ÐM6™™Ü+úL¡Û<òªûh0`j8Ï9ßÞ�ÿŽù’¶1·t¶H‚3œW’ŽÛ¢Ý1uüÉ”üçWØ÷Ë¿iè«ò c–öÊKÕïøîjê²aVS§-ܳÂYkÙ8èÔg£ÝËìFcžžE±mr’\ y +ïòåwF™�ÖOüÄìUmˆED"ܯ¼ƒÊd. 9Œ�D/bîYýÌž* 4@�¬>Ò»˜�-Ùó¶?ÎHôøê�\讲0 {¤ØìàÞvŒB­IHU®éN§wÁ¤p >º›ÇÎFêt=ûv·å®M|˜¤>‰ÁF?<¶•kT<öVÆöŒáëE'V2,5œáºpWLk� O©K'íEâ‚O=Çê8œÁQLâOÿï¿®Àh§Ú.k2”ØÎFÀ¢Bæ:ô¾æuH^…jXá_Œ³]¢Ä¥ŠÙ7½ƒ'�üλúÏxêðïò% 0©Cò+¶Ï4Ìh žîü8ÍÑÿ*ôîø ðÀ¢†ÁC¿ÓljK TçÊ\®^4•g~¾§Ö$l6)S‡¼ÿvˆ~îø©¾>ÚsÒ¶c Iä,¥ÔÙNr–½êï¦G+œ{b•óM–:Å^ô�‡¡6~š­¦D«Æpá)1<·Î†Ï)õÒ¹äh” fm‡äõ‹8GV´á’ wMn÷¥!c·dÝHÐJ6 ÝðâB´ò@Ê Gž�LÀÀc ø7*t³Ð7�i[F¬FÎÚ Ø{ÃÏçh*‡– ³•š„ÖŽ…ešívÎaøs†3ï,¥Ëë[ÛAû¢*òk¶qyÅuˆ:¯ðøÆºáѵEÐiáÎ ·Õ�µ”¼g �€–øó—îÍnÂåyãeª‹ÛzÑ™�V@K.Iⳑ$*�¶KtæøÃņzÍ3�¯zõ}H†¨{»ÊÜ3WF*ÓT?R&sCȯ"ÿq…Õ&áI=vSÿ12ɹŽcRð€Ä±¿pÇ“S\þmFýZÓi¿ë ½¿çhÑÁY« 9¡ÀÁi×.âì­ï{ˆ…ÜÚËY»ö/î¥Ýö=’Ôa5Yqî>»¢·๬.œ«ÖrÞ gWp H°!g}ƒ…˜Žg”ˆ®‰—Bâà´œV˜ÈY^áþuŽ<#r Í>Ò¡‰þ*/ú>¿œO™Ç£DšÆ’éžrœ4µ6]‘’:‹à¦Ž¼‚hµ@弸À ¾pð—ÛÏúVSzV�ïâ‚Î>FŸÁ¿Éÿ>âHÐSäx á>ˆãEf ¸nQ )ª²Çv'ùÎÅ Ð!‰!pÒÈ�ö‚„‹£‚ãàZkâÈ[¤ ’Aê)$a=ŒtzqŸ`ÞùÖ“Ò»¾OøÜÿ‡ þÚûA2óMÑzš~›öFàÒ›¦Ž›ÂšÇFœà”RÔ]æv·“o}UªVœ€¯¢ê=O[®žRtæ“G�ùx)9´=¥å�—z„éb|ý<ÏØ÷|ƱÔÂAþW|`ýÉï%•œÔIÔaüañÌ]m¾øÌxüâowÎ�Bq�k@ûw—6»ðví%I`ã1û £Ýã‘«úÖ3»§Þû>Ã@CF)ÄÈX$äXµSp%³&Ngä`Ç ÃGó=$ï™ZÇ=k`’¾:NÖP²«’gÙs.�w>Å?�­Êa)ÅWR I‰îºªþ±cf?ñ˜ƒÿˆWâÙì¬»ÐØ;‡‡íù}H>¼ç¯ûH�˜lù(îB‚s&u,†*~6ü’q»ùJÔŽHÔÏlç:·Ö¾Æö{æ(ß%úŽ £: >öµLó¬e¶ý¬ Gí /mÆž+L,ô22VnŠðâgP¢jÇlcãeöiÇzS?úÐ6:µ]èMìÓ®U‰†òá ]No­†§1"!3:-±½)BŽìŽ-Œ1�‘�†Ã zöŒ5DÞ lòbÈä³Uö†¼|ùâ7M—Ìêžâœn9œ’Ç‚p–Ú0§2Ë)ñL1¬mˆ°6OÏ;x·è/Ñ y8u餆h2'¢v ?±h©º”Þ•˜Ó€IDATçï—×OÀïÿ!{ Ï`÷¥dYêñ„ÍCëe,Í'Sv>¢Ñh/»&¬�Ö¦´%ãÐÔÿGæQÈÐöòKBÐãÿ la·o-ô Ÿ$—ÅÌn}!lúV}=]ö{·Øí‡FU.×]RàöƒeT R±Œžv>zåO¡ÿøLôôó™Ì1T÷«MBŽ“ËU£Säw‹xí_.ñí6,˜€€@©É?mçèëÐÙ0c"Ùq*â³"g;’”ÿ°ú|¤p„{Ê›¾òçËx6þ¶ãžz ïYȨŽáØ`v·§fìec°Œ¢p]í6á†ÉxÞ)áÍ´ÒÄgM¾»ÞGûH4™Ëv Ø('0Øèa›Î=½ „”ÐE0^fp4`pÔ$­ ×.$ù uÕ›AÄÙØôHd Höó­H¯-áÅ-W^[É@[žo²AkÒù‰)ô“¢Ô�Ý­Èë¦sH> TÕ …�å¹[cI¢”ñ³³ »˜åE±M§9oe…]™Ý³V£ÿã_§—††ç|ù Š®A=Ä eª¾�[.j\«’ǵÿ`xíiÇ<„óM ´ºÌr#úH;Xµ—Iu}pÉãËŸâÌC}UQÔ8åûÄÀã}ÿÔË®dù­/Xó’µöaA¹Æ�¶+s籈‡V7-’’Ž:°nÒVœŽ�0VÇ¥-Ÿ5œMC¦Ÿ±äâ»K¿.ú>}–þ¯Á` !|&®Úøj¤�©á<ãã£/íAÆA˜Q[mîý£Pe8ÕMÐG–IJ%G Sûéa%µnh¢‘þfÌ€Œ�5)OŠRMäF3eÜc¸¢?îÑÓÀô£~¯BÕ�?MüSC�E-³KÍœgœ]�îú*í-\yªU’~S}�éZùÿiWþeÎ4< œÔòä:�„¡6tpR‡§ãÉïøláÞÅý?µqã,|·þU9×ür�]±gÔgøÏZ|õfÿ#]’°Ã—ø”gŸ—Ô<5r„œ*ÈÁæÏ>Š<ìlý…ë8Ýç~»*8LÔ%ÇòÛ8TÅ^Ò‡1Ï:Àg …¡>ÿØqùï!KÐ0+·ý½-b‹ÑGÇ;!× …´Åȯ@¢xB@f«nƒç+sÆÊÞ²™¿Ý¢�b&•cR9›kMXÁ Qå;0Á†‹íãb{Ž»…|pç´"CMÒĬÜôè$I`ö–*ð  ŒuÞ3Œ*ë#T‡|¨ýøoÝ­å–ª½ïvG–}Ž›ç^ ò¬*$þËáˆ�´r|Cy±"Ÿ%™tÙÁzâ’´C”ú´òpòÑõß:Dc4µ÷°"¯ZÅhÞô¨I¿2î�†b¦/,ü…ÌÔä�c a�eq�Ї†ü±"»3,vA$Õ¸ &éB9ÝGö€Ì6=ÛÑȜՃìÿow Af=Þz²d—,³í'bëžÙ/‘¶6 F7#ln%Íf{^·Ån }F»GãK6Å~9Y’è'¾Áηž¡ULøÃ¤rLËÒ\UQØDáØ{Ø>#ŠÇ'ÉUjôOȞɩ�^ôº�ÖF`ÎÝ&EÔfk›Ñ]ÚÁY”‰s:ݺ€�7•¸o€šÂ+®£ á²OjÍÇìƒþ·»ÌÃÝ=nÙ衬ÐkÈ»£m`oÓäÇïU]UàÁõ˜•¶Ã¬|V;>ë)´;Ytµƒ’�µ´ŸµN½~o7.¾ZŠkMBÏ�_#§zçôÜ{}cUÊèPMæ*⼊�§<Ú}é4ò€wp¬[è[€6dË6={aeÄ›,û|v–RvÙB�µ)æK˜žO殳 Šî1T?V„™ñ ° -ûVÌw Ø�Jú›v ±õjˆà„L‹õûÝ7®ÍÏÎF#»ëÄY3È¥¦UÂ]4òW¢•;{¸]åZ olƒ€Ê0A¸çWÈU…[¥î7Q¨%¶ç|žußoP8òüwÎÃ'×p¿uïkÂù— ¼F‡òÍó䪟å§~í%53Js'P, ±Üû? çûñ»lnKÆXµI˜q�çÞ$¡ª�Y�U ¹õd‰§ÿùK‰oýîÑøäªË—7|¾!ŸÉeÂ�¬“»a‰Â;?ƒ¿ü2þpq@MÂæéÉØƒuÇì9Ü{}�Y\´Ï�Š0[BÛ.ædé먷ÆLQb»•¬Æ¨ªÛ(3ö߬œQZ³Dœ¬é¶µá+Û/zä™\]]Á‚è=&C5fò`_~Ýçü'¥ÐE—ù–u+ÝòΊ~‰³ZlIȵ\l³U§‹ÛíRd²Y¨já!‘«"×’<]*“9vz©Ë57á_ýIâ«î ÿ–[!÷‚Ì–jr¹ÍÝ çC>y_;FÄvšêç¿�í·lñ?!—܄߹›br;’?ãõrª*ÛÝ‚7Å�-“ƒJx|’.©äÇûÚZèõGºùc”œ5*^½Š¯*E6ÇjþÆ£»Dßóô€ÛŽˆè±$ýo,ôÍùÑWÆvoŠðhƒüñIrÇ'É©O0�3��ÊfìÖ!{Æ#*ò $‚ÙYJã¢\›¡xëIJhÐ*–&sÈ›ÔBȯ…5*Þì'(u ]*R~û‘<ßQÌY…–0б� +iÌd›þß9ÂøHt÷µ”tØ !Ž“Cµ�ññhh‚x¿ 94›ƒƒÜo5Ø5-vÂ,Y¤JÝÏ$–ŒÒóÐú 'ŒmžÊ›3ú£ ]&ý&+t%Úi<Þ+yVè¶ú(÷š} ¸~õ73>ýLÄMjáØÑ„ˆº‹¾ã5úeqÚcãDÇ'ÉÕdrŇ²†ko˜Á Ê�oôó8Yw¯EDó’o\ñÕ˜\Ãý~oÁ8Ù­ãœÕIêñî‡ ´~žªÜ½UBš{C�0/óÙY«y?|i|B®œ¥ôñz¯…=‰ìK½({¾1dØ™€ïTuÇFˆt)±¸>'5)“0S«á Žf���]3öÛÖíÿÛ5ôÏ9æóCŲº2K_ AÛ¦{ζ{P}Xäo¿Ç|€YPÌè‚Ü*fe¾¾FÎ#î)³oº£HÞŠ«¿öHïvIn&ÔÕÄí!vOôr­Jµ¦-Ö;éyôKQÙ|ÕŽ³fQög²#Ðã^àÙÕ4†¤Ùí¹Õ,l¾Ìåì­�‘sÙL‘W.ÄèW $o؉ní£óùô7Ûhÿñ¹èùìU?+3¦ˆúáx7õ¸)±1Êü$ÛduÑq ÒéFÊô2r�5Yl´pçS%8®¶qNË¡­"Úx6í_áR“•76NÄÕ7õqXçô ¹µ£rL<”zH!Zï!™ã°Îáêô…ɬAgšv1Ržûî@ ½ÌÏ÷p¯úö‰Â•¯2¤$1äëR“Ÿ—uàÿ(ôÍ&]¶]ÏšslÚT]Ô,òsß~.åÿþÇô ¿‘§üñshŒ€sä0ñœ(��S¦¡÷S‡ò¬§>«)n»mf­†çqZ9¾™ýék‘|†Í9®©�†òÛèÔ‹ÌÚˆ›là,'ø«†Ú(%PJBN'=¤Ÿß>cfjXQ†-ôͦ_ÅC~µŠÏ¡JŽóþÓ‹ /ÿxÈÇWî=_•Ë}kðåœ;>¼áð±¿çÉø ³ã'=ª¿Ñ-ä†_t%™OÌBoŠÐš8JY¡o>À¸†'ÿ¢ãäö|ÑMŸôxÿ™ˆºJ|«SäÞV�/§1Ÿî¸|ô þMŸæâg¼È7Næ`ºP©˜—_Ö«CÑ(Ê‹FÐD!ýÚGx—±µæÒfg ¶qžN)%P¡ô©Ü»äÔD8d’Yb¶½úu1§Sœ³Âétº´Gmœå9-Î=ô¤¸"rÁ•¯¢„äpD1o>}O½ñpîUžñ»¿Ç½êCGóÇŽQCÑn9lƒ=‡ÛÈëó"ï&alj¡]IT�·“c½g}#f­“cIý,ëgHn♋j{Æ"¼±wäH s;4®'"YxD'ͱ¡˜“³Å[ÝmP¾ýM�É4GÚ�¶p—SÂT„mówqF.í¶Ë½ŠXº©h¿cx°çé9QÖl7)`÷B/¾^_$Ý€uy$‚•Œ!×6JGêD¤iíµsIÞ†Td|<ÚzÏ"Øpp³­q¶;É ]O ù{ExYTµ4±%EÕB¦Oø¯ÚŽ«+bV;.3rétŒòmV«m%‰bV—3 YдßÈÇÕKCù½6%·)Â+_EI"W¯bÔm4Ðr·.úpÛ¶ÑjLn{§c?‡Å´Ìwžù¥§Û(>>IŽ=ãÜûÎ�UðËËðÖÈM¾Ïš<¾q#åº:ŽCu?D{Kœz÷ûm£ìë´Êh޽3Ï®cù€MBÍQžž¦pi�Þì¾ýØúæêóÈØ¦*rŸÂ�=;xÛSq§Z0/Ÿ%õ�(fVÛ8›°ãï.äúÉœ1ºÈ犼�ÜZ$éx(…�.òÙ±Lð>’ï‹Gv£ õ#Ä{m2çSÙxe‰I$­â,а%— álÈ4jZ��“­<�W0>8lKM¬Q6'ÊZ pš(ÄýÖkÞ¿œ£­J=Öå’®ã¯ÊÅî,ѤxœQã)Ozõ�â-’ÊÍB—m`ýÏ ý C�Ýo|ûQ¶Ýòý˜Î²&s&Uö«oÀ}ÏÙs HÛ™ȧµŽ3£�Ty$‡E9¬¶–:&ÅÞ—¿†;Õƒ²°ÅE5 �&ÞÏž,s-OßW>oÀ�êxÈÒ~Ú6ìCÂSŠFè+TV‘oû 1—Õ‹ðÏGr$m—Ž¥Ü(ÅSêØä•<�üó.«'l/p†êøw~<â«ð]Á¼r¤Ê“Šø GöØlºZ O ôž¥"?"38è¿y¡__#—­®€³…{l7=ägÞHé¤ðÎ$°¬mäI•g#ÁÿðŸRS84A\iRD�€'xµyP–R“ì²ni¡É†ÇºÙZõ½áÕ gõçŸZdà�yz¬1¢ø�F|¾²¸æ³¤�tÃÄ|tÔÃr«‡ï¤rRØûqzí–ÔW ïÔ—ÐåšÈí±ÙaìøÁ¾Lp—최â®È!IèÒgÒ6œ‘Ï|ï[+Xƒ}Î Ýlßm3(5_ã†\:-ŸåܯˆÂ7Žu)) öÊ�A�O’ƒÚ#ü÷�¾·O¤BïnAm“q|ÌÌÈíH2O¡:æÒIs˜ÏÊ¡#ÂåÎXæ^bøpîjšÝ+XI}N§y¾Û)ò½:šÊsÓOõm¹~w�"c=•¿ýZ‰ÕµˆTmy$g¦U U/ZÄ×Ï–0ù|ŽP0†"v×c^¡�½$gZ¦ ó\š¸¥^t–Wh'(³é­Æ@SË•Y1¬@/�äÒJ:Šùûö ¸·OÄYRO yÜzwɤñþØú#3?¬ØM¡oŽ‘L,�œTýýŒE»97DpÉŽ0›»5CØ1Ú¹èâ˜{SüÄ £ƒ5á­ÛÔYž{G8ˉÇbj¸tg;kÂouæÛXùÅ Q�z=¦:ä×¾Æv+íÝ,ò­ :{oŸ0…n¥¢[Óa»‘Ñ  çúœH£ŒÓî¬tpg-t"í‚9MðE§›xãÐIM≳.^zðÙÌΖ¨U¼!ë%¯bvû9i‘�c÷sÁ}b€þÆ6zþéJòÕ¿'~ã�äÿì#lÿ£ƒüWmªã9êdŽÊeÅÉëÉM‰ü¨8¨ˆ_øÁ…Äÿã»!÷t\¾²áóåVÈñ„ø|—§NÿŒíÔ»““äf?A‰£ä96]Èñ��øÊ2î}-�³‰ÏzZ@)ñ»oãð‘xDD‡2  rˆüð�—©…G=„�üo#æ Ôm�ܽ(Ì~NAow9�@¢%eæt.É_šØdÅ5;G5†”fÈï?ÔÇN=¹€®,¢�hým]¡§@³xx‚x|œ²š„U†üQC!5«Ë Õ^š3Eîž-qƒzÙ§œßìçZ• æU�I=­áQ»(wñ«(™‡J‘hä•A ^õ‰R™ä`Ì7ÛÝB÷7„×ÚB”MmPß’–E°ÖÁ9“âÌ›¼8G-¼T7þ· F8*ל7+Uµ+4Ñ–>ÇéÊ\‚Ùü|Ë‹ eV/Ïñí–O«ƒ»!ÂE.š-¼›˜Ý�tí�i’Å4™<¶4-�¤<û—^ƒSò3–àVBϧ¿Å.‰í—L³ Å ÕŠ¼\çp•z¸|¡—ÚL‘+NöŠpO•rf��¥4!b*ò’ÏUôð =¹@ûÊ��”ÐGrèJž£§pÕ=Œ(ª oBf…¶£µBúوęX Y�ÏF² Íò³äˆâjÝqL=ˆ=ãDû¼Îè][Þ}ÍhÊèØ‡‡·ü°9·«V¤òÔAòïx#îÛ¯âç>ð\FÆ"^u²¸×׌\¶Z76T‰ÜèyD„Æ#¤’Oc4¨ËœG“&ËìzŸ8o\lÿÚ çÞ°Â.Év‰ P-üÏM7T'(4F�i¢Ö$Ü/¢áa í¹{i†fä“Üã`è&æ86uÄéXÛªA»t„»•xjh*x©bne¨î3¦ˆªÜ±q¢f“¢•Ñ>Ò¶û¨&ÜaUµžk[à]FÀ¤8ïý+ìê%¹-Ç| órІuÉvÀÛæˆã¤”ÉY;•�ûžÉZsΤ‰Ê¬‹èÆÇ#Õðn;fc4´ß«DϘ(ï'zÊUôÈJ�…Õð¨Èž2jÑÛ—¦ÙUß,$fš‘©Õ�|Ô ÒxªYßé� f4è¶= ‘ƒ/þ­'åø«7Ñ÷¿Ãÿ­]¦0 Ëd²ß3G¹Z§(ºþ±Ëßû‘ÿ‚Í.ð/ô¬SZ­â>b |vÔfbµ"º­Ànõîa<âõfúuûÉl¦A­fÎÍwЦ/,05lÈN·ž,¡ZXkQÅ„ˆ³•ùSùòîù;¿-Ð+ä_ÊD,Õ+D!ù{Ɖ†ŽÐKEÞ¾ )¹M¾J”Ð`þY̫ȿŽé‚h42|4ÿ±]s”…r2Ž4©„§÷‡<¼˜³xše†u³Äº/€uá¶7—�*Ï™I]N·lüP'DZë-8FUwD¦ñWµ¾õ-´�Ìéõ„*ôì3žåìUEþPMæ\ÖÞãòý ÜdÃ¥“~Wx߳߿‰GrYÛ²…ou·ñf¬•È%i×o¦¡üˆ%Iäu…ᬙv©bƒ|6δÆaò:NNLåE%¼ú^ú®™§Ç,•pÅÃ(`øhÉgø@~ Õ5µÎCK¥ ´…Ëá]y$�C×ç2Yî0£A¥Bøïa»Æ»šÿbc\5tšðø$9 ¿i'?Ö…þè"Ïì§ö&ºfËbòº2Lî„ͤzXl?µÈ€��ºþ§¼D<û J{i†UáeÖVÉÉxðwÜKß0£A�Š7z˜|C É߃¢a‘ªãg”ïÍP¼Zô‰ª{~ê.núåÞôb^¦s9¢øNÑs—è3—F0Ìh€¦òDº&RC™é؇u-}—œÔòÝ×…³ Ü33Jœîj'dž Ì^£¾ê^2MA2€ÊFÝ÷D/tY}Á‚ÌøÈ(†¦å'¯ƒSë61eï;›H³�‹�Uù,Ùüµ¬Ð7ÝVˆRº±~ˆi†&ˆ�6È�Üc^,¦áÚ¸àÐ>v½ù…œ÷ß^Bc48^!§䳂Û®;�ÝÖŠÖFl¸‡/�GDt}�Ü¡ãäêGˆeÍL£(h¢PÇÉÕ®'wÛ1 £"àÐõ6 •XGÉ+DÚ—Á»?m"™ YG!’S‘ñ}HÄ2¡?î‚™ÿÿW†Gÿzëˆ)S\Ù¯+áfvW3j1þ~Æ¢ad™â'%L¢œeÆm—2¤ód®ÄêEet<ÏzŠÛ¬*@í<é=äôFÆ¢* ÷‹hBôÞ+ú~™ÖsËŒ®ãžJ Û)Á²Ew:m¨å³"—Å5ø��Îæ¶|ÖÓ§çîU·Y#Æœ+%Ž6ìôÀŽ$÷¢0»'• ¶™Yó"˜ž¦�5§²{8.Ê'Dá˜(T›„Õ*~5kìY\vw…zä½¶çìª55‹H1‡'b$ovÖ�wE-ãž2�Ñàðv2¡àkc†àrR”.:NŽ@¿Poã$Ë8‹iD'5A‹IÌrÇܵMÑ'ö>­tð6ÖqΤ‹ £óÙq!xƒ„Ïåêå*AòX_1"up–…£3Äí?g¿ÊL5òBNs/a�½áÃæ³ßNÍX[e±Ï—Üf Ø€Kª.˜ ö㓆Ÿ°ù¬šmf.úŸéÕýƒrff¤ýû‰¦7ø™Iñ´Z ۨ¹ø”PÕ=tÜt�Ç�ª,ôNd¤Õ¡Ý1S�<¿rñ‹Š|-1÷ImÓuWÛüí3Â]h{¶3o$É…–„÷®EJ:ÀAE†7W÷Q%ÜAr]ÈCih¢–œ¶ ³�?+µUØP¥yôÇì3,@ªî±+(hÔú줠JݯVëG0çvpkóô¼õŒÙ™H›Rè­zþL¨'àØó‰XèÖ¤ñà }Ê&iLˆØ€ï7 £Ù*•y¶Ç~0¥ì��ñ Q0ÖX¼CÇÉÕDŽA|î58 g1ÅYn§E¬ÏlÎZ@’ráŸféá휸¤€.2¨hŸCòÇ1§ÚTÕÍ+MŒ¢jÍ+ü¬#ßI ,«@ûêLåG-BiTÇDaV”7•³»Ž ö>šåS‹ Hô¯¬°K"|‡®oÆ#eÂ{O7‹<–6©?vß;)ú'ìv>{ ì­šUë¬xÚYñ4»ƒp÷ì¡\«™Nõžq"»u��P¤ ™µ7¦¡üôg1‹©Cj‹²-üN‡x¹ƒsZ.g”c# ŒN=ñP‚»!"½�ÛU6Ê7·àèK{b™Ióæ›àL–1-üGë¦orã÷ٽР8×Tè©Wñ�]Aal‹3G•fÍ챻Ǚ�rŽÕ KÒÙD”ócQì�ÿð¨ÆÝÿïæaÍ{£öAœñŠM7¼t ^r¨È£Ö k2̯ŒÓ~Häv׉QÔË�Ÿ l›Ü•1£0%œÕ–é�/%°¸§DþóŸæv•‘é”C…¬Q}]Ì-KE¾¿æÐ–Q�}/�©U—Vꑨ@;õ8“Â;¦)¼íµªá]ÈxÙ‡…VÔc^¹8ÀSÔÓ�Ê ÇÏ ÖíûË»ä©ÈÛK3ò›(¼Wô5æéÉVò­Ûo{èfÒeñ­£»­÷¾Vë‰Üá b£à‘(½§ÆvYËéîK‰ŽaT†×+GSEnT‘ý*³Gež¡µZŽW\[¹KÀeH>Û_øê€Ñ¥˜‰Ä¡“âJ>KÂ]SH»•£­”ø, çöYÎÿç+ÑxÕŠ5ÖElÿ�‹B–²‘º´“ve’úR‡›ç¦vÀýí§²zñ –é'äíC….-vKØ”Èß+ú:CŸlCî/R+ÞÚ ‰|45éñ®§'p¡ËùŸû#É+[Gu]gœížŠ �›ñ³ªûCÄÃ.pÏåÿøYÜ–ñ»‰LSh­ƒ³(‡µ hmþ÷ŶO�Ã:Î×�gšÅë˜.DÑÓЯçIÿÅÄõªã2‘8À�Š•ëÉ��UÎÒoh+#Ï|åE ¼ù2òz Á ÿHø…ëØù¶C<ÿ+?c”‚‡r ðzj9Qñ¢è>1И§§&r›(as­Qñ²‡Ó®^n:)‹%Þ ˆä9óâ1/Í9Q66΃QFD¹î4ñäÚséûÓß§|õ�„W|$à†·¼éw¹àºŸa¨îgÁG¨ÇH> ½äõò�»ÔrPŠsV>­VŽD!ëIžTeÒ/Et^Îõêg^=ˆè?4\v è?ùkIj2Ô�VâtÏçk©�dN:òyhý\ô×Ì[r¬%µfÑdž�`0Ïw>`PÒ'E)›Ø¨+CÞ,ôîKuK[¶ƒú××ã_äOˆBÏnF÷Ì]£+/<µÈ@²¨G‡Øeg¥ ]¯Çh2Çå ½¼U}¼õLÓ*0­S�<ûT "ï�ÈU›„P‘7„|.›)öÒye/é ¬t\Öä²!�嬮˜ÉÂFšCõè7S´—fxœÉ\÷<¢ˆ§?ç9<í%¯eûçÿšâ�Ÿ¡ð×ÕÿÎÏ<óù42>bb‹kͰVÃ4!…üÌŸï+±ºa:íëÂI[JÖSâï‹ø‚XéÀ߬ö2ól†ê>�›å“¢dPT vÑÈ÷cw"—/ô¢ñˆúP|H›xç,tQ65uv–Rv´ÙRä?¤×ôï…¾µÐ7»î2žï ?t†¾i±#»±ÓӦ͌Ù<À[V( —†þà‚sÉ¿˜ü¡›é}ý­ì~ý!þpi;“Ê™„�Áà%c`Xä9¨è|Ößà Ô%µ>èΚ)ð¶B’VˆÒQmêJ®Wî¬è_žà÷RQ#DwËÐBo½Üz²ÄÝ'K¼õLûµ�O¨Äß,í0‹�ÊH1ÍgÍ�è�C·�)ð°ò¬wb–”£Ó1¹Þg‘Ú•ëÛ©Ï{gà¶C4œXbǸØþ°Ø~|ÒŽ 7 =–ÈÏäÒ–B—{VôŸZd`Á$Ϙsg»õÈBoŠplÜ„Z080$Ÿè£=nœ�Oó¬ÉA-h g)5Ç�4qè(Çt«@m÷W�ÁÑL»`@š#cM…HeÞ¢�¼óÔ—Õ‹ì�� «ýöýeTËѰÑÒUBU œq*¿�tÕ8ÄŒ^ÁhWSr3"ÿƒÔaQ> üí÷^�JQ\mNO„såzøOõmDÿô‚·½‹èð-ßý»ü—Cç1¾?:”a²B·È-‹M–Êò?»þ½Ðq5 ›MŠwßMé�yz$Š““äª#”«–´R¯âD‘yX‡ü#LtOl@}ᩬï/ÑZˆ8­€5¹¤Šè¤Eæšö ­¬v3õeÿžˆß¬öºÜ9ë2‘àvŒ¨Ão'›&‹…4æ{Šùì,¯\@ƒÁ­')Ýù={e¤±f'bfµG˜ˆk"WžÙÞæ,ß03ë=]½5ÍbDr…áÊwäÒ2ÛNwÍh¿=kúpkîP곞FL¦ÛИŸïaR9L(@Ô=Ú BakÊ2é$g/&jãQÍÊE…rãŒD²È¯áa‚=‰ê¶ùYለvr]¡‡ö•>ófô&ÝÞô“+[Z«�§­ˆÓº€äMÏ@¥z߈Qð³ãÏå ôV ‡Šùõ™užªÓœwâó±ŽsZ�´Ì6½-œåNȬzXP/k_ø+®ÊÕæéA‡rL«°�µ”XY »|ÿD!Ë*²8?@û¥Ý—² �wŒñH(�ÀüÜc"¸¬jï¯YݼõxGÂn¡¯Û¦àªõe')®Åf¹¤Ê‘ªÈ:y>¹ÁKÿÛ¯££y S½ŠÜ]˜þÁ¥('ÒñóôŒ‹²¨ºÃ](§œŠ+Â*ò�3™S ï×RÊFoÙŠÎôÎÂøÑí—º|t.ÇRâ°hxaG.ök\M ÖS‚T„-án$F8´”öó`ßza¦fe Ã*C¾•BþÔ·¾Å“Æ�­œr™nö´ eôÏÆÑeé4Þ¼ðL#Éo›ìu/œAËÂ5ÚŠ,Àîý—Í»Hjm2Ûj5<êC1�Qƒ©¾\æHqY½*rÙLј‡Ôû;¢ï>1pR”ìq(TÕt–§„Ñ��ç·£/;¬ ç¬ð–:x©ðåI‘ ÎvðÎl®èÑ\‚?›ßùYQø§Ï26^F×›(*ä £€Á]yj¯~„Ø8's¢Yœž6˜ä#LÄW¢R•º*ˆª»ûRb“·®"ç½ã/ˆ¯}>uÆåkðÞu‡ëÆÙvNÕ4ÓŒo]æòù @òÚ<2*Å|«CpVËÂY´H«T¾~%šÌíáí÷P®P5Áã”'Dï®Qòv7•·»©îgP­âW«Fâýï…n¯¦Ýe3JÓªYQ‚™SƒD·Sêã#Vãtëù»›#Ù¹·™ÕºËrXV@;-!å¹ûÈ ¬%Ñ9B=c ¥¹7| ôðì•sØø-vé7)é¼à¡>nT‘ZÅÓ ÁmûljÍZUÇÇÌöî  Ëº‰+œ£%¶›ÝÇ�/EU.¿ôÇ{œìÀÊê# ýlŠ»‘o»-ôܲ”E1G$*¡çC3ìѾl»¸U†ü, \¸³€óì?øEzß~9þ-†÷‡ŸÂýà_²ãí¯c߇žw…ØQŃ_`ûá â¬Éy|ÒL�BžýÝH“<éºË¼WD 7Q)OjÆdÎ’q$":�Ìt •¸h�ÜÈ2çêùèYÅŠ«Ôý¬/PžŽ˜¦` '˜ˆ­è©çS–ôj¦+ÙjIí¢:V`éáí /nÃׯxt^ çõ2ÑËìÝ% ¿ÆÞð0»ãjzš£ó=¸_¼9 �BÒ"œá‘;+ÜõŽIÇ•(½kMæ.E3Ý1=†‡Î˜H¦ý2¹oæ9Þœ¿ËžÏkVvüDÙ¾?î…nüq¶å4E޳ï 5R;”£"o·ˆˆ|cžžê»é?h {â½ó¦ˆÓòYO ;2b—�^KYK=ÞwsÅJKgD±†rFVZ÷'P<=M¡ùiú‡êf,u¾]Y&'ÉÝÿ{¦)8>fAˆãû#¦U@õ˜æö" ¨Y~5oãQ]l³q=ñÜí”u€¼0]^\ý>îéÖE×c-¬ÞBŠ?»iŒq:“"³Þ†NÛD3¯ËczƒPW ¹âÒ8ÃCsòU%Ô,ò% ÀÚ‹ è+9ÖÓôâØ8Q?*g2×D³<~Û�œ#ë§·¾æ<“ÊqßKv‰|¿Ó'¨�wR”ÆDy¾AÏômÆÇˆjÈÛ�bÜ7àžNp×�š.+öle÷Owm›†ZÛjã,'8K‰1¤."Òh yÍaM„ŒŒ¨UCt4ÏÀíWÂÛÖcÎnø,È%í˜÷I…ÌuŒµ¶•L&×â§~÷µ†Á^uAîÉ+í,Y*Püð;rØ#…»–˜ãÄJfþÑfŸ¡m©:[¬ºV¸âò=$71±Ð‹ê±„{x”üLÖõ:´CÇÉÕš„œ_ÉY¹flâ~‰Ž6Œ×l±«>þ‘Ï$kÅÖ*:öçmkwMR­H[°‘ºÌ&¸ó� ^á0·Dt곚3þì]0xµÝ ½1É›bæ;žÙ(Á]ILW|øì<¥T“\ºsF{Ñ_Ž3Îóô,Šm³uǧMèÅ¢\ÒÞºò¶(â³"^°¬8ntáLÄ—2~÷m°$|cÏtȶ¹«ÙÞ°…žf/‚gnwVj‡Ý©½º5óó7k„L«€¿øË¸·¬D,µLGÀþ¹2Rh¹ýF¯ozžæl¢ŽÈe®GdšŒæßSxêq9ú.Wߘ窛K¼ó¿ÿÁŸóäÉI3ai¢ð¤Ýªo£ý¢�ï¬ú¬wpEqUxKi™oê)´_€TäH½É£"oåUÛž¦0ó¨øëLM·IYú (ôqF¢!‹º4?Ierko…û6pÔ1çîÅÿ{ižf²ƒ�k_eãh³ŽèÞª x)ó=WrwéyÜSCQu‚^‹ï‰2Ø&¤¡káôÏŠ~-2 ã亡ŠM…œßþ5 ·´’G¼…”`Π‹ýĤ€°’úÜ´ÎÚ'«·oˆ .3-r¸l{qh‚˜ÙÙ¿©AcÇ”)ŽÀæ{±f­®ö¥â¦ë°,|™¦‘³¨¬ˆáËk\Ü~Yö½üÔïÓÇ+ν8ÏFb^JÍße Ý][ìIjh¬gÔÕ‰;IN ç]§aéWØs02_-dç??Ï„SHY3. MÒ$�—Vê³aWÅ$�Vöou"Rõ!•øBû©èùÛg(ªŠË%WêU|�0a…£Ã5*=í—¼·•1øÔ1 6R�Ô4üÜ­·‡L¡uC ³û1'Êš34à†…>"9S"Ÿ½Xs4Ïîzü Tz*íC…,ë/óœ¥ç‰rHûÏó|3õ8Ó!\4’h=)3žœƒþ’“*¡FÀÈX´ûÒ®)ÈÏÔœ�ôr£QlòQè÷ÞAŸ�Û-JÄÇDQ€ï½)âkë¡}ƒG¨å0™–øNk€ä̓"8¼‹|…5ä-Šm÷‰ì؃ªÅCËFÓÚU|v–Òø¸MB‘@5£T’_µæu�r‡r½¬Ý3o¼•nBŒ‹Z&à1‘”#i_€>ú�9.˜;†�¯Þ¾+(  “ û#4™ó©2à¤U•¥Ù¢me«Â1Üw‚ÕÔaɦ½¤iÌ’"&Öé»åÓÜ«>kê ¨U<žtÍ«#ÒÔ¥-ܳmÜ™-äÙ•4Ã]ÁJ—ºê –ÑŒ§‚œêäH^;x”|}†â³n¤HUnÄxÝe"­š3ÿô΄�nøjãÛT“(1¹el¤¶1·æÒñácfR±+•è©Õð*–ˆS­ÿzÝ/¡÷Ãä ñTj:ágí®§mMG‹"˜“ÃC+yô®jVÈÖ'‘¹É¦,uU™¼×R`­�Ù0j„ûDÕ½"�2˜íMÈ…†T¤1”QµÌ7Z8?P€6Ì1%IB>¼TäkoBÍ¢yé v½ü0üëBߌÊ~,·ñ�{¡7EQuŠ�ù“¢td‚^4˜'n¿0¤±e‚ çlâsv#O³½½8Ûº EbÈ_½Ÿ>K¿ÝÆ™~PC]ÿz6Í´ó[[¶Ðë¾ÕÍû¾A ]”+2÷ùˆï§Ž-4C�餶0;øY¼îí¤ý¥š8ï[b—ì±ÀºÃº¨,‡ûôBN­:$ ΆŒÆ^-8#ÇlÕSÃ~_²&—Nˬ(à[bÏÆ`^=ÊÔnC*²û¿ý¬Z¬ò´Õ¹ëV¦ºÔ¥Þà,vÙv&ñ¦-‡$5Ûø‡Û.z÷Å¢T›§§"¼ ÊmG//pʼDHäð ¦RÂ¥Ô¼(ÚVÚJí4! íË£€Ö9ÿìËÑTþy2±V6ÜÁÍôCȧ2™Ë‘~¾#r§ÌñÂ]M³—¡ñ°·ü¹çdZàôg*«YƒÉ£*Ý̼šU6D0³Åe"�/Ê1¾?¶ŠFÀ¶t£ñ¨ºHÁSÑ‹r|­]`µí°*«ZLŠ|t}2ëڡ܈ˆš5ÂaCqm¡çÿu¡ÿ„�Ñí9ªÇXp&'É 02á_vµÏ+yþa-âVòüÃ*çÿÖaN+ìãD!Û†«†76NÔùš 2ÙêäýÌ”�õìî¡”ýûÙœ´)ÂŒBb¶ô&óº‡ôŸ#³ótbH2‰9ëz2àG. xHÛÑ]{eHŸ]N¯.üÚÛ¾No�Šw#µ¢P@ÿe‡\XN\ÒŽK[ë+mÓ$kÉ¡­œ�yXTž±•ö¾©À˜"ÆÇ#3z2È,4˜á¿=OÄ9ô9‡E~J„óƨҵ ¶D°šͧ0‘öÐùœ ·èRZ·‘¹[’|�lg•‘‡ll”aÓg/‰&á´ØñÝevÞ%ú^rHyòö¦�-ç8¶òÙõ�úªKýM{‹†&L*«êøÇ+&ýEVÖ-›`³EPã?Ö<¹Ç½Ðo¿ÇÀ ÌKîõ‡È]r…õ;_¢B?Ë/+¡¿,Ó~sícR9Fe[ö ÇsCÈW“ð„( MŸoC2›¡-r_È·…Þ“mχêdú÷@�-ñÎ’�&sÛH>\`½mšoëf›š5ÑX5é,ñ™4bfý|:·w³à OÜÝÏžH—{£NP˜@v"ŸCÇsä×{,¦²ºñ•4dÙ¬ð´[ õ<&´—5í@:ÄLqøAvÝ+úêuzEÕe¨V,2ñ7w:kÝÐc6Yó‰íè›N?Áj‚³Ü2vÏNŠ?ÕÆíÜ‚dˆ³¯ÏúßûIþ$Ç‚ZÜ;mÆkaËÜ ÷ì:œ–Ã)ÅÌŠ¾¥72ª“^ ‘ÂáaŒÀyh80rV³ræèÜæpz™h6!X–¹Ç¶‰èËäµ…g0½Ú‹nÝ ÝŠÛdXÅU×r]!צ¨v�yƒ(°GwJäï|yŽ §Øf�à M×ú¾ôæˆöÛ ,ïãyãå òö�™`†Z O ‚ú Å3F›ofÀEVè�e±?î…nH£/CùÉh#¨°7<ÀÑüPŸOWúÑ`pþ$9_S*¢Áàº+ºvUsãöŒjT¼ªåeïç`T³ÑL¶Ð]«CÏŸ¥»LüQqb mv–Ò‚ òÑë£}ŸZ y8u™ëÀlŠ»œÚxÞıús¸n…â}Cf±´é wo9ªIx·DÅ»ðB ¦‰ôÖ>~ý§_JôGc7��ùÂbÌ=Êsr=G3ÉóÅÞèÑÛ>ÅÀé£ÉUÇ»tˆ8MpLv¾÷5&ß{QfœΛ-°ÅOÅZ6¶K…sZÄgR“˜ÒN<îßhdZ»Í=Wâ£4”çi|Ñu�û®µˆû“ˆZ'Tä~õq�z¨­•x×Q¸ûEU‹d§\7n9pFÎ׫øæxeÇ`5<|½ï#¦'âlÈa£å°’zÈ&”Jiâò¡Õ^^´Õ+>¡- stÛ/ΠMir^"oŸ‰à Š$Üû—LžÀ¥LÄPóªU[ŒW¨€ì©RÞ5Jž©FžZ5,M±­>C‘!Ùkâ´d—ž�Ò6‹ew[ }SR[ýÉ9£wý¾T¼Zµ7+ž rw5,fiª‘ß+BTËŽÚíUË[ÜDù ›¼¹%7ÀläqÏå»DßfçÞPT%SèÙX…=*{èˆÇÃmÜY.&xgLwÙMⳞ·neÏxU¿ 1¬Ê=8nùãuŠ:b&¦8l¶Ûªûh¼ÌìÝ%^ú@¬þÒ¹è­Ûi½£}¶—ä=}$oôi¿„ßQC*f $ªV�ݳ†<ª*óÓg~!fÉ(éXÞŠé+ê†vÓd¬½Ô�ï-Ù-òJpÿú6Ú/B“9‰’fÙ5#ÎÑ�ôØ)EÈêã*õ°½ýÂ"zSŽÎm½¤wî$y÷“ÑŸ Ñz=Ú¶‡ñèjÀâ»Eÿì,¥ª}™g(nÓ o{«„Õ !/U^ò~Ã�OlG=õ�Âî$McZ؇̋ÞzÈÈb¶ÌU íäíRϺàùlAArjMÂÆƒìzXl¯ZßÀðp–ï>äg^vÛè ‰ÆD¹Oô Ót­‰\£A^Y4•9’Æ�^Á'²ßûI,ôîy¹‹b[¶ªNX ¼,$üìÏh g;WØí³�LO\JlW—ýÕ²)°šÑ=£Â>{Ms¢PÅdn]tœÜu'(Xk™è曎,÷1½îs0Þñ¸{#à£K!„šÙIT‘_G±HÖc¤<'Uâ°Y)v£˜Š¼W‹�Ëèm4È��X¤°e¾U1çF&•c|´O®=×ÌÓS¾�cLC¾,½õÎèaZ…˜ücÄ÷SŸ X)°»–à§›©¥�d^V‹ÜDøJZʱ,�«�‚ ·ÜÂU“9[ÆÙVwDDdÕx5…UQ´ŸG\^“Z8�ÌÙô ¢Šð�ï¡¡€K#P-<Ú ?%òõ#Äõ*>S�<šÊÓ{óûpßs¶Ì·:%šIÄÝòøÜ<Ü|–Ò»ÞmÔŒo�‘› †Z3äŠ**r­J\¥t(wxÂBÿð� ˜æ_ÅÓ·Ù¶ z³­ü‚è�Óæ8n¨Žo�ÌÆsÙó'»Sérîkd¡˜f÷ø¯è3fŽ?±ÙKxL…3OˆBïžU¨º‹bÛYÑ?'£–ê&Š>âÆànÒ^ÍïmåvmÅ)Iä'.%¶9Ú&omDǦ üÖÜù.vyÝ;\^û¾"ïÿ]ž¼¼äìQMäгŠH¹g¢�t^¹ �æéü³OúÐ;ÏG//1µ�ƒŠQ”5þ¸çye“ 2•ç°Î¡ï†‹ñ¯~1Lž‡êþÛÄ9ï\d ~ÄP^jæçí¥aǃõzÌøHtþ$¹W‰Rõ‘Nª@(8+úW¾Ç¹Õ z‘ò!ú�9nwsÍ¢µgÑÎý;)ž<%øË"Z5n3kþéEòÑ>¨yµÞ�AòÆMh´j­BV臄M˜Q8"ÊÍIú›MŠ2C_ÔB˜¨…4òÂ×]@ÿç¾ñùTÞ³=cò_ýúš"lÖ0+ð´ ¼YçQXÿµ]èæ2�/Äè 94âÑù ®œ=Éf0hR �3™CuŸ+¯<—Ÿ¼Œøuï§|åß0ð·¯æÊmç"ŠÙÊ4+Þ·§Ø&QÌž¯Ñ» z³BÏÂ#3r›�-LÇ'É�¥¹,ê‡zÖóÉž]$§¾¹Êÿdú£ßz›7Ìt¿»[p Ûýa�ŒŒ7g ¼$Q:Îñ\ yÓÓö Óõ=¤þ§Ð~A™ÙiÓT P'¤£"Kó/@C\6S¤¹7ü†ØyÛüôIQšE¶€S‡XÈ3Ù]u_â)gÖyêÃb;—Õ‹VžÒÜóËèK9;9ÖÓgÕÏ¢Pƒ½z1SÚfü×ÊÕ¨xà EGMÂÆ<=÷‰�»D_öà�f†i9L<6N4#Š#¢Œj!ùÛ^rOR`}ÃÀ)%‡õ¶ÃŠa²nÍ'ë6)Už;Ö·±ð:{lò¯¸„‚*¦BE^MFY˜u²3@…5˜xÇ3~þ j^s'=CÄÌÏ÷ðSzA€î Yë8†–£€ÕvLû‹;X¼˜ÝõøKc@"¿ÇÒ[‰Ü+î6ÛßáÃäßõ߃¥¾(~ ßÝ 8ãbûbÇÓY|A?gÎäØPR¦È+±òƒ]è…FE7äKf%¹×s<×]H6ãžóS6·<+ìG‹Ø£R¾™á 7ÿžnÒÍÖ�hö¢¨uƒÛÛ¯Ð7oºy º…ž�iþç…nWûØ^yÙæÈ( ƪ”‡&ˆi*ä²Õ ¼kÒå_¬¾¼-—´e¤–÷+æSS\ªsÐ�ÿà »–Äv-Ð{Û1 ‡�t9kΈñkGÔ+ŵ3�“¢tB¶ÎH7w6ªÈœ1£ë˜.ÔDnD”9óPÅ—•H *8^L)¶¬á£µžCmܳ"zà‡§ò\«RÕ4ó¢ƒ�D¤:E›c�Bû Jº^§—ZÅ£¤�"éYµñSCcayf䲡€NbK6–ضr®„{øˆÑ×�7�Ì9ÎÒO»ßŸº/:ëzE˃«ÕðvS�QÝç¼Ã¿ö÷>ùÄFÄ”ç^•øN+fL>7/‘ó§yÒ'^dWäµÂi]›¡X9{Ün—ßæŒ›P�ºò Oþ¶8¯JÝCcŠø=%�Ö<”™!̋⺠¸pÓõ˜µv�S§yæâ€iÒ)W¥îŸ…†È EMj!,ù*Qz�èÓ ªÒÏ¥Š‰Æ/YUµq6VðÎÈCmœ¤]@�‹Šùî0(βÔ8TÉuyí[®ìûËŒ,b*[Œº©±ÝÔ 6?“Ííû&"Ú>ßžb¦1›/‘Ç.$óq/òî7¼…lrBÆ–ÝȆN-2`üfK|’Üè”MLÝÊ…Ï>´-”Ø*uÿ�_bÀU¦ôŽ›}Ö A4\4" ç¬`UmP‚û®QÆ ‘4{ÐDū۸'Ñj5¼ †ðÀ<=wÝKGã¾ý÷CÖ­Ú­%hËc)ñXìdæ £a_Ü øÿ®±:š·ü°ÅN)› ײ¬œÍ7{¨p4Ÿ¥§°Ç`«—Z-Çe3EPq€õ—ö“\Þ�nÞIZßIòží$oòY{/Uy‰¸1JϨ5[Tšiî «ö|ÛÍ®C¾¨˜Ý·�,0$ÿûâ‚ûÅf•lQÌùo8³ÑrXŽQ¬ˆÜ¼«ð8“ú4¢+ïR&âÍËŒ¼ò×ÜI�‘ø‰+È3^{Â"æúê36»ðž[{‘ FA)œ˜��4d#õ9�âÝô7ìm†Œí‰®¸Žªûd»Æ-�ZÙ³#`v�ýMÁÕæ¹Û~&þÖcgVèA§Ú$Ìš{fçj�¦?)…žhÆÊ®`Ü?YÃ#^Ý­�‰Úúß•avíÙÕž!ݪ×ùH_¿´—“*±óC·ú¬wBZÂI¬{+m…t6pÎ(æÁ”â§ofT=Ôë1¯¸¸dwÑբόZ,E©¦�Šrš0sr˜Ì¸çÎȸî6ˆ+®9c:ÝA²«ÂI—|6ò•��ý`~Ï8‘y‰dÍ,E™Vz3 àßo�5îê"¾ÿ;Ίþ{Æ9_Ù÷mωªäÐPL½Z�Y]êq†t>ÂáXT¼ÛŽQxÖ�Q­È½ê�2š“\ÒdÑ_f"0n,¾¶XÆFˆ²3þQ—õ¯³§DnyƒP[ô÷ÙŽG©Ç�ÇØÛ /:n"µ/¹‚‚&€�ÇÇ)3¾?b|$Ž&P̾éÅOßlÄF©(t:‰)ËD.I’gCxÿt3×Oæ>šÏVc7µ9ëζ߶ÐKÊb�­Ãñ»GÓ…ÏÒ]³ÃftSÖg²…>"K'ªê'»Ð%Š32 Ã`7#“͇zëmGªû›[ 2)d^Ýs“r+ì ùÄ­2­OýÞ.³i@bÔmŽ�J†H>«�§D®uÈÐJ”Ûk·²æ¼8˜GåhÖ‹¢0Hbø0ùQ¼õÜs'NÇÌ­ýÄ8Ò¼ÅoI°–ú¤ë¸k"Håñ™O³Wá�èÝ-âëkä×ê |Y·Õ#_›+;òQtÛ1 ¢÷[b—ÄöÌìÒ g¨5ÃK�W›„•šM=¨h|ŒÈÎ šº†W1_èEŠ«2É%:NN¦Q5‘k4•ͨ}!nîµ/× á |n+‘�}´`ô÷N§ë¤3:c†q¨¦ ûET½Œ¢D�Ñnš(üú½÷ˆ²IµÙWÓÍQDÏú"›¥N°"üYsFi@' X‘^Ãá©,�&¢¦,`2ËXó3¸¦¬TzN”3}z6¾íªíª™b³Ð»™LcÏæ‚5’MqQè?Aʸù‰PÍà”/%¶Š§¨ZÅŸœ$×DfÛ=Ki⛜#3´Ð[à‹ Eæ„cžÕ“÷sZýÔOsIu�Ñ c,dã#Ÿ-niÈx“ p¸l¦ˆ÷áè.¦äeè®N+%7oÜï�Ñ ïâÃÝÃX4c ê/ël;¦l~?•gZ._è…f‘ÿ|O™kUb|0p o91G„Ì¿ÿPÇãŽÆþëv$ßÎݽ Ñ[_æœæé™;¦§ × #ÙM—×M;Ž�N‘7c×jw¡ùq¸÷/àGþî¬ô 対š¾jÚ˜]Šõ*¾öQ¨!¯ÎPüÐú´ÈÀÁÿlF4Ϥ=ÔÃê¢I=m)¢“$é6VÎ^ˆ^Lc4‘uÈY1È–b/næw™~Àá âAp¸‘Ç?se�Ô€#âÄ §#»×(¯ Î$¸ív@’î¥õš1YºhqL”ÇDÎ3>qÞ^BT½ïmÿ„7ò)J¯y;ç¾ýùH³ó©˜�ˆ&sh*?4A|ø±�' ùÖwïù�&È!èú!Sä÷ÌQ¾X”ÐѼaºÍßù=}€>UqÇPD|߯üÕ�ø×ßApý�ôº™g¾ãW‘æzÝŸ©RT�^¡¨]n’T´fv8‰ñ¾ûiJ0�â/tp:ŠPŠÿÅ×3r0b~¾Må³]�l—{Ó„¢)lÖLÿÂl�Ð bfæáŒÕ÷·ê,.”X½˜†FGó€S¡ž;î}ßœáœ9Q®~œ^š)¿Jµ¬&á­›³8àŒŠ Ú4†©c¢�é ïçÿ'¦Ð%ܱqc ¼ˆós®Á/«‡é>¦š*ÒPþhƒü‰%v|C줩�—ëÎùz.¿…ÜÝHôÉßåÙ+çR‘w§]¹» {mÍ3oˆ`‚‰Ls¬FÅ;¿Bކò·�‰ùÎ ,t\Úòi·]’6¬¥!�vÄTs×ÔÓYÜ6ˆ‚ cVçZ-÷³¨oúP�ŽJ¤imå‘ ´”gMeÒ¿gHE‰žÏ¼��ìüh·ü.˜„$Ÿ¹÷¡>>¦ª“ý¼»ÙϽ÷öQSx”F> ĨR÷G‡ œãÄ*ç�‹íûQy;úˆ1ÖtRÜ9á.´]:2²¸•÷ñL  Ãùš³—ËØåm7°Ëåý“>'Mt“Ó‘‹ÉI‹HäÒNb¦×bþî,#£�×S6)wŸ(¨j :K�µÆ˜ kRiŒ�arÚž§ó¹àæË(½m”øí·F|ë²ß¹ƒ§œZd >cvaCÈÄKÕj9ªse&&z©×{™¶/N&M7^bN”ÏŠþ…l¼iÅ2™^£{<ü1¸÷/àG½*7R1ëe Þ—P@òøÕÚsÙyé[8÷õÂs/¢¡ *Š®°ë±“†fT¤©~>¾ÐË.p­JTçÊL*7Ü0i1�îæg+¤l„Q y'¹µ¤*¡³Lòɾ.ÊsjÞgqÍa%Å1QOiÇg=Í1·º�ö‹²‡*Ké¤Z-R›)F|å]%îêäQbðÃêä ­%)²®<ÇÏâ~ô=jŽ[&��{˜Ñ| y²Ó ¶ªC>?ýú—Ñû'ï¥ç�ÿ‘Bõ¥�pá]¿Æˆl®y#_C»ë1V$ò°Ø>!Î)ò··”ùòFÞ £V]f„³”˜„ØŽn[$ºåݨB6 ”[k¢ >í‹ ü`G†Ž³*µŒí6U�¹ù>ƒbò*Â;Ú0>ñ‹®§lœHU¬)g¤Á£AVè5*ž‡GÉïE!—Õ‹Œ�—ùY-þų¥oˆ�÷‰�±q¢®F V yößý"}—¼‘�ox+¿ _BSy®ŸÌQ«xCvlzÇ[éË”š�ž§wÁO€ø‰(ô &âæÊuÇ çSy½ÙPI égCä4Ê ¹Íš ÛkŒÒcÃ"\ÙheYÕÈc<ꦼfóUäV«øÙ™ºÑ Ç†:YùK^É#c»Þü‹>¯ý‡�7/D|"Éó饀kç=~ïÓ¼ðÒŸ¥¡àGó€3ˆûç9ï³/Î3›æY6VP–E î’`%ui'.ÊqVø¾¸‰Âavå©Ú�Ç ±�òmЇ<ÎÊpÜÓ4 M\:)ÎÃ"§p¥ÎŠŽ0gqW�ä’Oßúþ &˜ÁSš‘j Ó6îjŠ¿!èl¸´R.ºãWiZEà�õ ÉGŠyÁ­?‡ÿºO¹¼ýLÌkE>¦×�-ò‡ŸaàËÏDÁ;s®MyíΨ³#�hZ´°Jé&™¯Xú®]m–¡üê: “ד[e—ôh_ŒE#Ì•s诋§ŽHбÞÊ»Ïö3©ÜoŠÞÜ£cÖ£³ä·úÛŸ5ðQèB¹YTR6FÊ­>nY"°Ì4O)®Öàæ³œ?¡Y‘É[?rwü4|ØÌä«Uzýwè9Y¡KF•ù™³9þñIrw>`¶øƒ(øÏTËjØÌ2jM…0™{&‹OßC{ß^ôÛÏEOß�b&•ãÎzd3Å$Ñ;Üùÿ¼£‡µ¥Œ6cXl–«î'm’pFEZm—×¼¹Ê�ß…"¢¨V³’Âð_ùA²ng÷ë¶Ã½Ñ™N‰¾Ü¦|éˆ�ÝMd,½™Ÿ>zËM9æKfDè«M ƒŒ2Ùk ´”Gk<ù’w£©<4‹5*Þ^LÜ1—¨À�ôPQŒžt+ž†ôÒúù+¹»DM!CÊ\e¥Ã7rÎÑùZ �½ÍÐâ½-YL·u§ÕjxMj�|½Šÿ,fŠ˜ÊŸý÷Ÿ`GS&}Uѧ/°ýÎAzšÔÂ>6.tùð¢OgÝÈžSù´ÛDXç§ -øÊYJ·ˆ�_;d�l[ýí›ó'NZêÿù…~‡Ù^M‹Ÿ`÷9´ÿ,â{ò2ʪ»&‚éÔãÛɹèÚl<Õ¼‘âĥĪ�‡H£fö>�bQñî–IMÕêˆ,µ³VÃ;! 'Eé¢ãä˜Û¿•FêÕñ_ýn¿‡òÎ}�±àŽÊ¤† 9;¹®`_T¾¨…s¢üûÑGm¦÷0mȪ��fͤÐ8-ƒ�ŠeR_Kïÿ,W«ÏvàCn3Yéú x0qPÇµÜø¥9’ÄŒ·Rcµu¿!žÙù-T)ªI¨!£Îã²™"¹÷}Ρ“ºhÍ ªmº‰:>k‚�ŽƒZ¸g…sÏ1>sjÇÚ;¿dÎÅ'DáÎèAuŸë®+Pk†5FpèúÜA]ÉlI»JÚ­ùÏOлg|ËÜÙÞŒfÜ“Œ|úà8åQì!GÉ[å™o^^�ÀŒk¡…‰äct |Sä¿+“–sF>+rùz‚Ÿ¼‰QõÔš„ßžbÛ'¿Í¶¬Ð%·Ú]]÷¹x¼ŸÿŸ”BŸù¥ivÜ3ÎùZbÇ“HÞ^dÖ̰½Të)¥³ ¹¯3@ûÚ!äwƒ�›\´J8#Š%ÊÕ�÷‰“†#{ïd¸íÇD¡6Cñ€ÈS¯ÇH!#cªº=eBÄ ·jÓ[kדÃâ€3}Ö<»ã^ú‹s˜V>ü™<í Cgíˆ0Iq’„\*‹€Šd0Ð…÷ÿ#Ǧ T¬ƒ T cns™\7[Tµ l²“šJ±('áwZ”þå6Îüzߨ8Q…cŒGS�ü‡ï´ÝëwCøiDZ° h¯ã,ZL²Lø¹/RU™©FþÀaw�(Ú¦fÞXZk!ªûV½"9]AŒ—0d,ºDþ’i =…3¡L�dÐÞ²2g£Á%ÓªUüÃÄÝ‘× �Pl2ÞjF¶«C¹í¿toQž”u®(`Q1÷¶C’?C*ïj�?+úµÄöL»žiû·á6e°Oüëqÿ~ÔkÐâ¬ Õ zAž÷­,·–R�ù4d¶róÊ³Ñ¯Èæ¬™-9+–(e\m†âèùÚŒiòQ‘w)ñì¬q¯U„Lj¢�ç�—ù=É¥ý‡eô·ÛI?9@rå6Vv¡Á<Æ›ýÞ‚áÇŸ¥šͬۄGîE!cŠè½òÓ•N‡$1„Õ�´«½b-µc)qþÕÅí*—*¾dÚ¼€">ç0mÙs‰[ˆ£Gj²Øýeá�íäÑݨV”ÌX®&r\«=o»Îv6eÚëê¦ûªB–峤�9qÞ›þŠIå¸ê�Ài<È.-±]Ÿ°þë†�bÞò{qMä~µÁ.ÆñÒµŸÚ�ªE’Û{IÞ{úNŸÇµ*È\eÈŸ`"~Xl×;l•Š>vÆž½P2‹éá âk 貇gµ_€Ãr�41räNj`ì7-AëyÔ*„¤ûcÅ{TÑdLÁŸ£?fU÷Ðõ†9gÆ'3Å]ã±”äYVŽ9ø� $×^ÉlI6\ñö{ bzzÚpÅeÏa£Sä‡ d2Wmb‰ŒB­pí‡8 Udò¿Š{)_;çpl-bf½—IE|ü,\>ÎóKíQ–nªÌä0GyÁ@5z'¬q¥VÃÛEÃx¿k3EžþðËûP; 阇VB˜&¸kæ|œK³�o‹ §~ )ÞM=æ€òUJÀCÇỆ,t³Ý6Ôrè¤øJðΦ. :Ç‘â}¢p÷Ý”æn§Œj9~VÿwNfû¯ulÐbdÓSÖZ!«I?-~n}·Ëaίä¾!vJlËŠ;ÛúvwFF¢ÿæ×é½r–Ž?—üåÓîjùçõ�ϨÄ݉ˡÙ}ö—2$•h…‚qÎÃbûIYé´lä’¾ê> FDùšyzгŠL,ôê/bVeÃ’IfÔ5\6S¤¡`¨Žß`0&è £¶¸ÙªÂzÔ‡þ½ÐÃo ¤VËi‰ígDß…ì+P«xœô¹ô½ê�øƒ7ò¤SQ‘w%³%-ÐûÀ<=7ˆ^£�m¬˜ØÛ†‚}¢`Xßve‡A{n†Úïá>Îv˨ê Ų±Ì¶#õ²xkÌwa¢cFZu“ZHËÂ[J{ype7ïûÍKé1 µb2gæÙ»ò |â}ð…—Ó‚µU�³‰Ç™ŽÛõ±ëôò÷·!¢êPæÅ®ºÆí·ùYe½ £Ü³Ýl©À »s´#£Oq:* –‰uZMÊ,žÙÎÌ94Fƒf�pâRâ C¯q³žB6öÌ\~™LzDD7Ö,´9/½ŠTuŸBë9=¼æjJ¯¼Š§\ý¤`'Ç Íš‰pš¸Ô¼„75ëÆOn^(U7;º=ÞÏÿOP¡WŠðþ¼Æ“k_c»„{>µšÊsƒz¹üë½4”gw=òî?ÁŽ›>ÀSj3÷ŒYs�›usw[¡†)t“ð*ä�ŠàYÏ2L¥BØÇòJÜÕ1Œ÷45òtÅ¡£JBêë CH&T0sHÙUÁ$y�´=Ófö|ØèPÎoö÷¡ä­Û-"M=Ò4Çšb¾›âu>È[ÕW«á5÷*Ó WåJ;è¼2Ï7„{ªå°˜سµÓ¡‰T"ZOrܧ—¢ÿׄˆ5„?jõñÕ z/™¦@õx¿‹nXLÎÊg%ñXi;$i@K%’Û@f~-c]…š7Ìè#]…öûÞZèî™§=çŠk hYF¾ÒêÀ¼<Ó2ó-xßë¨5Ã{žG¹^ů"·I-4c3m)öÌég~<>I®!‚§0ß³E Ü~åÊ_Áuj3E£‡'b$glÑ¡_¥?Šf™¬Ð«–|R”îÞB8z¢_�ûð£^�yz¬uÔ+šu£rÛž >I.{©<ÞÏÿOL¡×æéyí2;-1Äi6M‡Õ�{5Ûð×'è­aškܾ¿¼wËC‘�)öÊø†GDÔ�îgÇÃb»}@¼+îgGÏCô]€j!?0¡$-�–פˆ4�™IËèƒHy4LŠþE±M�ô;Ç÷ÌQžù}LyR”®º†Ó`ªûL¨—ŠrÏb¦¸›¯÷îålÿÆ¢ÁQN\Rо.%n04k0y!*dzúxæ½wiu\6’�ŽBN'ÛЇëLô ù¢‚ýºÜƒVX•{†£�šEnÔ9¼~j—/ôrƒz[ÚŽ Ç)_b-µŸü6ÛÀZ„Uè¹Ã(ØK3$:6�&f6Ÿt$Ó,sHÒí6|í}\ª8C8eÞû¬k?>f²õ2^{4ð„ÜKPaú6ã,«2dhÀÖ[OEC¦S?lçõßäœ÷½��ìEaŸ�pT"žù-}â^�ûð#ö¼+T¹Ã �ä«Â¥Ö _%J69¥h¢�å_ÇtáÖ“”.3жŒýåo†ñuQI‘‹šÌ-Ø©6 ™¹¬HÏúB¾ºjV›´ƒ“¶ÌY8•‡R�Ù ·|ÅÅÎoˆ�›‚ÓÅí6yjJ &áñ 9ÉRlëf�é×î'ºKôMˆ^�¥¿ÆLQ4‚áa‚“¢ôA±í*a(«ã#Ñð(=&r¨òÜß{1¥ßMoõ3ôTÿ1ftôÉüí «ÈŸñU×ЃfKœ8f\cG,áfÔä¯�½žþS‹ ̉ò0 Ø[Í&n£A~ÂŒM¶Üˆ¢Êõäî5_k¼i!6ßWÓ®ŠöE—?ŸZ÷­¿‡³,HW“Ô°ó„³¶�;'¼¥”§îuh2wêK ÌÎRú¯5¶�Š Û¦OÙ®ü¸…ŠZ&½å¹ÉáüZd|ƒ N,±£±È6«ÞóÞ-úÇdÂs4OEÞÝ¢tb‰÷‰jϋ̵Eèôãp=î_À�zí¥Ò°T”«Wñ5Š!œHá°È·DÙ*¡¬‰ãÑûÖ3ôÉÚ •EåXW’-ôø±Ìv?Ò>ã{Êè%^¶r.|õlˆÖMÒiÛdž¹mE( øîûtÁg–Ùùmqž6yb]x`4è6‹dÐÔ5ë†S“°JݦÑcµð½_^6ÝfYˆ£cc”�Ÿ¥ÿšyzاÒæ¶*—©Fž÷h;7Lôr¤ÞËSÔ#ŽÄ5 Ô±!jåÐ5= sNG�^³”>NïCgèûÌ)�a±_Îå½°u¾­®f`¿ˆŽ‰Âô4…ê–U1+ò¦³È"$‡mÚå¡y‡$�yákÍø¢ s>�çuëOGÊÉæ¶ŸšÏ*bµùYQOO8¥,æÎL #ÈaІQªîß"v~PìDÆÓ~BÆEùq“ZHUnmžžKì7@ߺyV¬’ðñ~þb ýG½Ì9RXŸ±ÉO—@Cþð°�ûVð&+äÄî¸)B{Öóмògàog]>¿ó¥N‰YÏ1¶îñÇSµ—é�…«œÿMñSv+fJ-M™3ú×o WŒ�ê‡cdM6GÔË·Q?g�Þ Û‹/ü2K�‘µinºÏª„MjÆ‹nòÓÜ›17.Êzˆ¾ƒ(š`"–Øöí)¶Mlæƒy["¬¢¦ ÿöÞ<¾®«<÷ÿ®µ‡3hôljÆ8 È  C ù’†: t<¢%ÐÖ�pM’–:êe 5·¦Ð+êhÏé…BR§ ie ˜4‰¤2±ƒ�íXže 眽×óûcí}¤Zè 4Íï²ýÙÉ’Î9{¯½Öz§ç}ž<þýÔ µà�ð*:7Êo.¨“5#åªè­ŠÞÍ¢àAAygŸ÷NË{>;>f ·+YÙü1ÌÛ¾]äÎfÄç–=g;Ù“¼yã—f´J¸åVÊý#D7� ç~Ñ•7ÁìËB‚=(íõuûüÙ>:)˜Yåð‰Ô”ò£…þ:·‹Â®) [P[¼‚G�`lŒ²÷*qÎÌ:µ‹Âe¬-� ÿíä“Cô‡E’�®$ùØ9hèéèÉTTBkKSs¬= ÎU;’aÊå9âÊ£;)f}ІÊ�ó¹èßÀÊ×}ŒeoaÕ?þwþò²ó¹®’Ó›�£Þ3ÚIQôsõÍtl`W¡F%È®5#lÑhØÇD¼YªÄÇåëøÓLwM±½�/<ïx^º *]Á½»˜*Ô&|÷Ø�m”T!Ècâ-·R¾ì:Χøg¿Eámï#zë‡ L¼înåÂ<Íòu£KD –�Jž½Ïx!¤ht½c'èáÆoö°òÌEèw ¤ï/ O®B¿_DOêË’p#[¼æ|m‚¸*:_+ºªU¿`o£ü¡;¼êNÖœôHV¢-ôÇÿ"Ï3'ãÏ�rQ®ÛFÍ£¡�B†Æ<ÂÔT�Š®ÛãûÞkñ‹Ä²›D;ßÝ‹ùVljÉÜ:Öά—•%¥ÚÊ4¹j+²lSi3Ú¼œä4æ["˜oú~o§e,L? ½Ä'Ø2„Ö@f©6l-dýÙž{Ý[Íh'£Å|AùÒP´vË«¢]Wâ½t*£‘Ϊf;‹YøÝ:FùdV%ØÉP0ûæY÷Íyžô{b׊Ÿ@W,ca:âp N¨‹T1r%NŸ¸ýR7R9 =šÙ/t_÷o7 Uäyä�•«¢së. µœ wî‚$®È’†ÜpC‰F¾€+/²¸¸Øÿ­ç΢ þ_`þh¡ÿ'œ[wy9¤œï«Ê€ç«ôÅý#DÞ2�Eh¨Èý/ì¢�¼RÈNŸ/º9²Ú×ÝïžîbLW©Ì•ÖÖ2Qƒ‰E¹¨%ÍKü Óî[¶’3gŠL Žøì½9+Lê < î:o÷ñ±O>ÅhKT­fÂYÖ¸†‚¨$æj7žyt[i�(®žµ¦V 2F›•9μŠ,l‰$ì>ï÷~C¬PD™O=9Ϻ�ˆe¼õï/èæÞé(à€"Ψ€ZETä!Ùu˜ê»VúšúÂÅ%TÈ9„tÛ bm; ‰òŠ×vm…í÷ÐíAM²£xM4äûÒ¥0ãËúÇ=�—Ú– ÿý‰Õ”ò£…þXÀc›Í®íyÅ„GF1°Î7ªÜwß2Öêy鶘ôO(ê%\ë‰!«Y„F霘 slŒò½¯ò ¯Û¨•D›ÜÒfYà®ão½�­GCÿþ߾Ѱ_!�J° ×Ijvq\–ôõWqk¹OÄ£žÈ°G"äÐHõG}"¾n¥ ˜cX3Rf›Jp t1:ïI¤Ü…û».Üß=…ô�(ï_úѢU<×y–À‹%±e Q…¾Éìd_ezi‡´’‚þ{�“.&ie×™R<-‚ù9‹kZæEéÈu\¯ßÀ#£Ea�qÏ@(5W«„PiJb�×Ïz~ï>–¡Ñ�«T~*ú©sQõɤ7ŸGër6¨d×1Z̳ï’Ï»€gú÷Ÿÿ�úÿ3g•Ý™±wŠp3[ mJçÕoy;ñïÍc>wÖòÏ ßz‚âÿúc&F;7gbÅw~À—ñTõ­®UÂ6$™\�ozš®)ѽ]ÚD½ûAÃÑ9Ìl‚=ë<Ñ„4Ó�9qÐEüÝW©Œ*ÁÍ×Ó¡Ìr!Ÿ!Í,YF åkß*²¾y)öO*ò/®“‰ùå|£Qâ«)ö�÷³JÏÉH´/Kd©­‚“U!r¦Ý{ªÝh,bÏéåtÜñ��iÙ¬Ú@ ‡yXÉæ\J)~èýlU�Z%X"zÙ å]hï¥Sïc_qš»»2eÝxl„•Ó¢kJ¸ûâ.øË?êàžìà.uñùf‰Îaï~Kް`gqçe�ÿ_ŠÁ´Ð¿ÇY[ú£Ñ�Ûì Ç"r�^\&iZÔ‚†ó~å‚[Fêèm>‡«UÑÕ>:�<%°dFwRÔNo%Û½ÌK˜I*"ã¯?ÞÍ9##1‰, Ž¢R"ùF“º©‰B}µ‰xå KĆv/ÛC‰Z%Ø5å‰,Éä¦SÄÀáu+P³„[€yy6çÑ{šï@�•LŸGU¶š (ŒúdW­FPEá|IêÈ:úϰ©›òÇF<?õ-´E‰Î†°ÉÌË2/¢ÛÞÇõêhk�å|ûK„�Ì Ó^Ry×6o(øä¤B¡€í*ð�–ñ²Ö‹#RYÔ 8í0'ePjih ¯½TÈz¨ò¢F_¥’éÄ-*©ü?c½´Ð¿ëT-ý^)e´J˜ƒjؾ«@÷ª! Îài”œ"æÕI’¶?¦$:Zõ5p�7Ï9åj�¶f™ßLQs$ç)¯f 1³3Í›v|‚/¬mŽ#ú˜õ:Ê q»¡ù>3áž}‚³}ã¨V3½£GéཎSÏ{v´‘ Ó ÅÈRÄÊ8Q,)¡iŠüÒ øuÆ1«&&ã¯ßŽýçwc.½’•/«Ð#ßÙŸx¾f£ùêqÓbë�ÿŸÿp´È×Màfe4¯ mQJ[Ä<üó¡Ö_~ôïXsÛBŸ©&_½R‰Ù¨–ÙH pã^À1ì;©5ßÅ�™KÀæ&ªj?õš1Œï€“'!y.-R�u¤Ev¥2iàp�÷ôxâ�÷NóxŸßËu/àd3öRŒ1‰zi¥té2®V1Ϩ³”AVB˰Ñ�ŒÛúí�]}"¦r tG^ºœ¹oÃ1u0¯Næ]Ȭz8rf%ÚÄ‘{;2áÙ¥j«Õœ2©j3¼âW÷Ñ{¯èàÝê%úø_™öí³¦åw9'BOQÕÍ'v²Q�¨?ºBtŒˆèÈ:‹U‡Åª‰L‚É3ñT-º¢ƒ©©ÂÅÌoêæÀ©ˆ¹VÀs\!GUæÐ±s99€Ô‰<Ð�i¦q–åÈTXQF¶!ypM–à¬/ä¨ÓËù)½Ì’fŒ;òÌ6&mä~亿žë�‹xÜ]÷/wþ;þˆðƳ†š ù§yâ?ž¡óÄjñ†) ›3Ä™/cõçšfYùg1ëÞþ¼GÑGçBŠk+”x½–E|ü oû ¢?x¯å½×ñÒ³«™š* äÚn늹(åÈ�çH#úh·kV®­uÒù—×øfRàL&:˜Pd�†3î\¾z-ëF‹Ÿ=7�ðXù<— d§Ø^‚]Lîæþ® è‰Ø¾µÀ–êJ £¿ñöÞö?)äõ–•`Ò” Aëì3ÑúÚqí=ÛåëÖTe²Å™³žîCÅ _Å¡r[x— ¨ó*n-óòC+Ù|¼Û+Æ(ôcáŪ™7 Q>î›Nz•N(ç =ߤrBFe‚…Ô&:¹^eN?·@ú®t+Õ�´òGåµ-ôïëüž€™«ä;¬T‰=:n{yqA4V…­æª-¢˜+ätÐ9uR~æ:Ûª¨FÀ¯V£TP°†±2’¹ä:úD|·èÒ4]YIÍþï{èžè#Þ‚¢«ÙWdjªÀ˜"¯,ë9鳞rŸy_¦K°òP_T�/·b>Ó(ó©ñï<ÄÚÆ%m+Ø?yŠ$/XÅËE‹�pb‚Ι¯xWÉT˜ˆsuY2TÝfQØ"ÊÛEÁW&b 8x†Ïø–Ïœ|#‰ôŸãe­ÛòV9ãnF•wùùÍ¢æ¡ÂRø2±|ý zø`æG ýû9¿¬Ac^\¡v]‰ë¶•¨Ê²SEÆÔF»-]è‡ä[7÷eñùwYè¶½ÐåG6°«PÍúÁ}‡•ÌÐNŠccô|àþ\Ô€ü{än:[UÈÙj;Qóðϱ}W�u²âØù«Ð[:ÐG:Ї—¡xòþ5\q¤£†W&ÈÚpÙâ=’ ¶f{ÓŸô›ÍçïåœÜš×Žú¶_jÊšgúËÛwQ¨ŠNîùÕnOÃU ¿!V콋´L�êáÎr"‡6_»è<.ºÅX´3˦�2T¬z ìp‹( cxáGØ-ôï÷ü·šZö]MñŽ+r޳±hb‚Κˆ70UXBa´xV‚GüçrI�83 wFNô •Ù®•¥LªÙìòªŸÑô4]£ûè­m£ôZ_C+ôÅÖ/°%¤¸v”ÎOÞïã]‰bî #…ÔªñQX7J±Rñ «ÊYV®&/I%ʶRÈ“~¨j÷ tH”ï~§ÿìêvº_~¬z+=ÑG\a"FU»�ãÝ™új@ßD '/¯±„VË[pÏ�Åì¨3µ½à%™GÃ)±J_çÜL¶9» 5¬¾ƒŽ¡}ÔÔò£…þ}�ßW›j?Ñ­WQU[%�ÒYÍøÄ´ØÒ)[øz”Õª-�Øù™AA‰XÿGÏ¥ôÒ°—¿žwÑ–-¹$” ÓÓtZ„ŽÚj5XÈ颤"»T¨ŽÒ™!ÛŠ^ï<çd˘Q·ï*Tä+@FàX ä|fjŠî29àZ­„FÃ\ „»¦üF8 ‘œ cÀóÈgtN¶—Ÿí-ñÁWùƒ·°â'¯f½z2<ºÑ„oï]ŠwWjÔj‹aÃe%¯A¯):-–Ÿ9ÄÊoŽÐSCÁm£VÚs€R®Yÿ£6Õï}y¬3Ïâeñ_ëÎf ÓPY¥³Æ#I`,`'Áö�£Ž¬ †€áÇ»Bø�![gP0T&&¹q/…K/C/]…]~ ˧™a0Ÿ-FHÀ …-ã[Pÿ5÷Úi-cŒ•äŒ1„„꘸s/`ó5¨›`xPæ*.5ýŒaÎuïæTë7Y €‰T¦þçòU  ´dpL˜�»ÑäL„ 90¡1¤¢j U!± ÓUšÆ-_….�FLR·NE#Ô 'Ëô’n»†…‘µëè™ñk·Ä<�§'ÏÜšÝkAÖ¤ã6~báJ>ÓñÀW1åòn‹6 œšdÔöÉ$—câ1]ä!ž`0�äZ3D—�~8dŒ€aCÔÁ ‚«ÕŒÝX!èƒðØ1‚•«ª³�ïü{lǪv\ ~®$û�¹:nã ZòxlÂÛÙkï厅{ÿšâÞ0=«ƒªÆ˜z` ÷;"Œû¯u&L=ÿÙø¨ó¦hPU­Nr{Œyõ+h\² ó¿>NÇÞ^\¾Èa!#ÔÃc)ý‡ÓG½�ü"‡öÐL“7 ³_%1Æ3(‡àAÆÜSùȳ™½÷»p*&ôjÇŽ”Üï00ФùgçÇ2¯XŠ1LÕ�Ú¿«`ìù�._…Nø×ºáª¡Î*÷û Sq{¿ÀüÅ{1;v(öøc;f–X}XÌ}~(æØ Ò–5)©PKصLüù0WRì.º„¦aÔÕ!63Écýø>Ó µx¨“1\šr«)Üy½)û±�:CíyZcÐV€øvÌÃ?ñç.ÀÅ S�Ã�eú{擄 }Üfn�ë :ÈÌ‹u÷%8~1šÙ´Û„»?#G!ëÑÀŒÑª�%³ Øê«û�¬Œ>¡lÃ7{·W[ .#æô¸a²¿±g›‰{Ö’n¤šÔêUS©PxøaÌêã´˜GõKå*2fÑ¢c–î}™72‰�ìƒ÷¿›`ÛušÏ6ÛÁOþî¬ÝõNã–̡(Pi.¢XޱœYù·Ã\ýë7só¦†Ì¨£f ƒUݧjéI-Ö™ZŸ1/ªPXP§a=T¬VÃVª‚!qß»Ê\²©ù;¦¿c7°X n¯HØO¬uœz,ãW¯›`°õÌîÞ_ýòñZf�‚ƒY¡‰éİk®—𜇯ºBý/7­±-9E@/óï¶¢Æcùüáý¦÷ �¤÷ƒ]>@ë�ô;Xo¯ v[–¼bôï �q0Éè^÷æf�›ã· „ì?l©®i°woX¹ó¨z-Í>£ üÜ4ÑSVá¾ú¢§]†aX0Š…KcÚ=>br+00s�ªUQA ÁøF»w»šŒ²‘”34¨ÎX ~ë}Û6`yYµóð‘ºYý0ðív¼÷}Lo1''€¾ì'Æ cLÕÀg0Î:CSƒ+9lþÖ)Ï›lÁ€ÿœÁª dã=4Ì Uí9XÕšµ¨>X¡v’š�C/  n¹äú—?ã¢Þðûóæ_®@�™ãwpyëfîÜ kñ\,€IDATÓøÝu–‘¸ÑúÕÄXb !¤ägPI±—+íÇYø› °Ó “�~y/œûU*�íù½®Dë½g‰èGÚ�;w»Žq³ÿ–ãpµ‡öúÅžý;ùãOhCÅ/íh2¸EÔH\QŸ ¨ô¥7n 8ùy d^“á§–ñ×ŧ /  ’4Â… q¡ó—€3‚ñè*ÈçÛcö½ï£ÜÄ{ö“Ð9d[4š®·}öî•9ð\еžé*PÜSŒÉI°Ô¢K‹î»„¹}/Ñ9pÖq• ºÐLE¿ÆÁtˆ·Ž·?ûoOHHIÓ‚ á[8î;;ÿ¬‰ÍüËEãw0h¯c ³B‹©:Sò´nœäÓuM…�W5¸”~à'BÖo;'Øwð®”sž‘ỄÿÊ/œûÓªuï},Ã7Œ±ÕÃ[Š�çýÆSÌ/¤<C1I8XRÓ îüô3¯¿h…0`Þ¥\MÌ-4¥ÇX7¿Ê“ù$¿B8¿ŒùRGLâR °eâþ]SÔ|‚æ .ÂbiyŽGØ´‰HH¯=ñq®{u äîžó9¼õ‹Ÿè°ll´p�MŠΞpœê2 iÀfc–æáÚ C:‘„sØkiÍÙP.fH–¦³4ä[7åòŸ?QO¯6Ú”!Q€1£�æ‚áÛ®›cÏ}VÂ3¬„¨j=+kqý÷V1·}mÕ’l¦™* =`F�\þó/ ë-ofÙ�7ð‚?}!Ûwu£ÑbÿQ5§‡–åÜ/O^á¡¶9­•—•ª¡ ïûöm±×•BÒjÀ7„qI®»fQ+âYÒêc.ÝäM=º¾ƒ«v~ìjÎæ)ñ› éÜŠ®{ŽÓ-OqUÊÇý`”N(éË×qd.äÌ‚o½u ÔÏÙÄåóÖ’8¯ÿÿ“ù‹4„™kYšIDSEÒ¹�/¹�oå€JP)äœà •ŽÇ$k �4pFB:š ó±Ú\¤™)K ="íûDãè½ÄI‰tƒÅÒA@A©Il ‹Ÿ«Þª k„‘ï7‡žÐó×bSYÔ $8 %¹ô)]Ÿa­w= RÄùÏZßuèê«RNw7‰‰5¥o�"HVrö¢9°àJ`[HÖ!¸Ù'ô@AÃb‡ CèhbOZ’³˜eò”ÿq{Í1Õ°õA›Æ-ôg÷Q8ÁF Æí03êc@•1c)a†7Žº!>ãö«oónj)Tœ Á²Ó„¬Äòr-ÔÁ þ&+ùèoÜQœ«>˦óÖrÖÌð¡¯ê¢w]¡8öXF¯n*`‡Ù­>Þ§Ijª ËøCÿ-cŒ©2 1`�)àwºX‡Ë盿~ ‹×h3Éþ§ãVÏuщ…8!n%—pB0¶‰Ï(…àb,]@`OðùÛ5aH2÷Ì&¡M`¶L7(îÿòÀÂ>7*ãïz¯åSoxpÕ¥—¿ßâ`{Ï«[~ãWăëN>jÇ-!8¬…y ÷ï}BÇ8÷nˆ& ËB^D“/á6NNÇ/ÜKc�ÕÒ³¹d‘·ý_'t$cHýÜ7œ�à¼cØd˜š`÷â÷aûH Ús°jž²« ;Ì�m_Ó±% ¦·3Ë�í¯ÖÅ·þi‘(æ’ÛÕùöߥ‹Ó?ˆ1^b•'À0ˆ¨v€Í6:õ1 ÌÿNLâæú~þ¬‹h¾í¶øøAö—:èHЬr-0÷mØ›ÀÔ£^t!nïƽOì…þ«¡a|�eáÁÛ‘ðàW’ {¡gá�ÜnLJžD«�È4º2Øæ>QüԬ̉þÛZÓ€ÝsÀ3†²D ÷‰|V˜ˆ«xA{Fü,oB!ëÏu³5F”(d<­�1Æ­äm ³”ÿ<ïU÷ÒL G2’ Iä²FwˆŽû廼„"MÓ塦™Ú.¨f䇯Ê7� çàVìËÚNóõOÑ­{}›éD�ø°X5#VȤžrˆ«Æˆ–¶¢fm¨�¹©$'ÜÌÉ-Ú½ïÈö£ï Ø~t>åñž�ùSäÃ�J0�⭨Пõ1äôf¢jme Ý ¶°#¸Æ>ˆyòEÌOƒŽ=ºV\‘8|0óû�1~B=qÏ}n‚÷ZcLÈègý¨^¯wƒ&ê^ZgÂôAʃ¸ñ~¨‡ÁîÏà…ÿ÷‡±¬Çnœ€ÁAœ6o…ªô�ë[�˜G°›Ã jU&ìˬh×A\Ü$_|ëš±0gC»-ÝÇbNöÛS˰{ºˆ~ÒÓ|Œ×w‘;K­N_V’q�®=CºJ˜JE)â*l̬gí±~lûX¹’Öñ•@®t%·GWòÆèF�1cŒ©×1ãÔë˜zÝ&;ïù÷XO.5Év„ÃÔ̤/f0¹Ü hãä"ÄÙ ªeÓK,£Ÿq[o¯Fÿ´]ô/”“gÓ¼�Ñ& d¾ÿý°ß†‡`h÷º¾6}lSéÐJÜ·!xìØ ÜG–³‚MÄŒšžZ_™äÔûŽâvOWÄúË톞kì^6£ »þ]d×£cp)Oþ´c÷�UÆa¡Òû àcõaÿUí)èìÕ뜔Feì8Æý¢b£@È&ÁmD­þ&ÙýF)Ʋ[nwÕØ� –>5y,‡¶†!Iˆº ØH@ö0ØóŒæsl�ƒ^u0„Áhq<þ/?~S½“wUô㨬_#Ø·‘2„øž›ñîÇtû�÷1Á&;q’ÒÑ�ðïŽ3»{ÝhÂø€áÖý­ãÈM¾ª28d¸Ký }¼§r«ëcÜü·g3p[{0ü9Œc*TMÝäpðu¡&pÔ8‰ŠG¯ZNxƒ ×ÖšÎ/BÖv »».ÀÞ •Hl7 ¦Ï�a°̃uÜ¥•*÷Re ˜ð’¨àM¸{˜œÄP�p 7Þo‚~°†C>6s7á…×ì²—^se³ ÁñÝ Þ3°›«D¼®·î±Þ@­j�ˆ¨:Aœ'ýØä÷~S¼_tÝ//>Q¶&J5ù…ÿØNlþ™™,tÎð³´ßü‘ãï_³TPã‰zæ$"ÚIqjÊ'ОaÅ�”|4[èïËï퉆G€]¶ÇsžÝt‚žO‹ž1ùùÉ^8°�R­maü„ávQ¨És¥e$ž"È‹õðƒL­xšß,«Ÿ?„ÅDƒãË~žSí{E“–8@IStŸ£GŒEÕœ·ml$bh¬L¿"jUÏz3æ¡£9 S•—-_ ¥*Á"U“b‰Â+^K×òd“ì¡ÄÔöÂ:Q¼aš.¤°"‚{D÷}bÙž,™°>œ[œØÆ›�Q¾ r¾¼öf#:³Åµè±P ¡H¢„hô(�‡äUq&PìU`Ç"UT!Ðñô´÷þqË�ñãG!ö›LÆF»äzi{YdFrFQÝéçÌȧéYw5ETµ½'é]-q³XÔŒ´w¯Œ(“ò¡¦˜í*äX^t¨Œ•_+ºØG]Wbj{a»èþ‹/²e`h_‘ª¬¦èþÐtdsÑ‚?ê<.º?ó5.¨¡à*T®Õj¢4z–sç¿Pte2Êeþúð*ÔËsfÏ£K?ÞEòò�ôí¤ïè!½)F7[o+¡ èÅü™.à5ZEí+«�º9¢îùÕnFŠßÑ»ž=]œ½šâ7Þ²u9âg+"¨ ;¢Œþ*㨿uä“miØ„}LÄK,nv„ê'R®yK!ªv´J¸k;…]Û)äšæ[‰ª9QåÒç��Wqk9�úÉ,ðînqÞ¨Xé­ÏhȆ]Ö�½uÁ“h …ö”j5‚} ç–z½Ð—.IlE…*a®êºæ*Ê>TR„äq {¼÷ ÌÒêý,ß7Jov�¡‹t/eU‰UÍXƒ�Ó-QöFQTQ|óõtLí¢ðÕ}ôJ™’KqeùÚ]5Þ`la$Ê�LM”ªþÙ�»O¬ËŒÕâs˜áœ#âœl£(÷ž¤÷WÄ2ÍpÎ×Å“ªÕ̘öMÄ í+¶=f¡pûŠcôGµ¬è^e4d`ÔÓ��Dl˜* ZÌ;ÕµaŠBUt3µ½à“ ž–7w¡'´$N“ â‰ %‰Z¶Ø'ü`It�”�|¡çI£²k;…\�C9Ϙ°5/°`�Šž ñP •W‹´¦Œj%ÆF¢kEçØ z¨xkÙW� ï]K\ÍE�U—ÄÛØ“¢wzš®­Luç®ò=Çé¾w޵ç­e¤2¯|åSYù+×þÅ톑£˜¿h`?~&äÍ�;!ߘkÜí0_8Eá–„âÍóßsçÿÕï²õEÏâˆ:ÐhSbÕ>Ñ›ïè�b™²â¨+àÕÃë¦ù�ÓË�ñ›ÕÒ]~IXŠª­0o¡?Ú’…-KÝð¶åϦ*m’KU‰5@˜‡yî&_èíŸ/±¢�޳Ÿçw†ª,[ú£ª°Ÿç|T¬^'ŠH™ ï7õLÝ€!ܺ™Bû¾3×xq¡/ ÁÄ¢Ç)ÏI7¦ˆj¥Õb* 4A<2Dù¡Ï±,›Ç]ú&=‡DY[½÷VCA6O yÞêh>ï§èÖNŠ~“©Nø±¿ß+ÁvK‹À ïZXUeö‰âfQ¨Nß?Íy_™çÉ~¡Ws2Ò «ža…DYÄD÷rÑ}öaVK¬ÊŸ‹�øÐO ½$‘jñ_‹U-V…´^Và½÷òM×ÉuÒT‰V«DC1óΰÐÂ.xi_šj«˜ä»œ-�Lâ`^° 8-ÃLj˜q˜328y©�†0-’ö™½o‚�M½Šæ1aOçïë@i©@K1ÎoÑ$Š˜W�T8ur¯[ÉìO£[ËLm.øû­Úí¢°u³pù&ƒªv—èÞ%ºÛ“t«W ©‰˜‰¾]Vâäh/R'¿?³ŠMÚHQ¡ÄpF1MÅ4Õ�²kP#"ULâu‡HšpZ0ëfRLKrg\ÝÙ…®•¹v´“«U¼äCtÜsœîŠè¹Qôl yU�=Mâ�ÍóÑ3+sëík%8)zï݈R¾rS�:ÕÉq9­€Ó)œödŠ9¶øüp~LMÓaÿÕÎË�sØY¦^Ò)LE�“º�y…Ìfç¼BŠhf]b¾C f„9-‚Æ1bý %}‘ròy–%Ÿê@7õк~5zy�…§²îd//¼»‹¡C~³> Ûw¼«.Õ0WuÙEFu­ª­M´©´‹ÊBïÚS»®DECcå L–Q¿ã\öj5ÇTæ¬BfTB-ßÕ–:pþþ–üX¤Ž°•ý?õÿ·gfÆÎ Óœy�Lœ .ÁÎ4¼”ô’µñȵâ0 Î Mÿ¹-?ÆÆ¥ÐL júõ!ç;ð’¶à§!u˜D%œzHÜ Ò·_Å¡rnGDÄõ«ÛU�°~… OL;WÐ<&èT‰ îï`ý>¡$%½p�³@“€² '‰¨…±¹2(Þs{Ôa˜ÄwÓ8ˆškš‘Hp*7� ¦ýú¼¬j|eÖ´²_ÎÛØÈ P¤-PÀ´{“ C�E.ÒrÊ�cû_îØÐïj¦ªK Þ¨‰Dïªl¬¦ýø^òaª&ò/óï&‰7úÿ¹£s&Ý¥;HÆ_´1àÏVò�;ÞÈü�­$Ï /¥D¹!ZÌdz`:ˆZ³œŽ ôpMZ8…„XJ�¦9S4²Î�‰�åøÀ,»|‰NŒð™ý›?,áö.'x*Ø]{ˆŽü˜„4 XÓÅÝ ù 3^§ÆOb˜YrŸó¯váøWRz{ìù)�î”ù&J   ¸c�Á`0™€ª1¾YQA꟱3¾ÜŸ=òÔÿ6¡!ƒ5†ÈØì©9Bd|ç£u˜ÎÓ �zqgºqIˆK É‚ZÙì8f8ÙL9¹À�³Ç9:7É× ·S3w3Ê>¶^èv¿ìH�×¼&E;3lÞÀûJïåZß3ĵ„-7�ÒxéÚ�qä} RƒMC\ Xù'—LbP`¬‡C°ƒN€•‘gÁL ŒeŽkY“NÖ /;HpÁüH2ÚyMÃds!KÑ˾̨H0Xaªxø­~¾ƒþÿ¶Ûï4«ПB”ÜŽ6l¦…¯aw÷-×/oñ÷O¿8Ü}0 fž�éÆ@«iŠˆqp>åó¸Žoþ3ñÏ}œ|ýÈ�»n8¶ôÅÝCM^÷ßÖ°ïžgu5 ?>ŸùiÒõO)§Ï)…lHæPàˆTÀ6[œ%éêüŽ»éJçƒ#Á+‹èÌ n�M~õ)ç×~法 ÂT�!ÎÈôÎC˜Ì�¶ºHŸBmŽŸ©ø³½M6lp@ÀSþøù|«÷•e×ûê9®°Ë"(`q8/ J⪉œ‘ËP|V22Æ»¡‚VÀ7�cNbÑ”ðÈør«n«4vP³×<•K8ü{w±ðëèÉ`:"ãRDàbRÐ<µšRõû?xê½ëúv'|æ’ø¦7®0·.Ã} x…µLþ…)óßW_ÚIð[âì/Xºh"Z´\ÄŒmD÷6ýX.PWXàYAfž¿=“<ç•—ðUó-I9ÄÔœ’éî�!à$Žnd.™åÆÃ†Ê�¥>rY_Ê×p¼‘ÂÓ÷6^ô§ÿ& §a ‡Í8Ò<¹•ùVFÙ™A^Íèl„ùë—7Ñ;°)`"’¢%ŒFÏ Ä…Ž¹5¢ C(HCáÀ&‚i Hw~ #;K) Y9Säd«É?…�®[>Ìó~ümÜõþ×q�w-TÙ i7 Äcj5l¥Bù˜å�£y_ê"Ø!Ä5—š7ŒŒwo€ôº^›røU­Ol*„m×t"ì¾½÷Õ Ì¼«Eg¬À‚ËvµÜ koÉŠŒœ5D�2 HvÁÂB‹ÎÞ¿ à 4Ýæ­¥éd±À…Ùð™‡Ô »ÇSAeƒérèbAd %ÒHÌ:ƒ±Ð8d2¯6ö†M¡¢ÔÑ*ßý'Ì>üÎ3_,ó\t×bý=O6UD°]jGé¼aš.¶¼eM‰¿ýÃ{?ÕÍ-gºø\ºœ£>æ·òqi˜*n—d1o#bV§Ô�Ž•Ð/³î蹿"–m«¾&VŸË••·rpl‰”K(“×ñy×_.kíe¡kñ˜ˆ.ÛC‰}ûzYyóŽ�ã©Á¥í=̧ҀTQ›©&Q�TÝÌ*âoçY¯Þ©.¤ø‘‰Bå%J›'�ÛÉʉ¾�E¨ÚÉ�<ƒÒo(òÖîà–Æ ¾‘ö°O�̩Ȍ ¤©Å‰0Mý5%Žó?ûvÆTΓÖ[�O˜fóÞf¼Ï€oâ<ü0f¿ÿ‘óqÅPîKxÖ̉ Õ÷%C¬)´¡Í†K�¹9‹A¢ßëÓ|kLB1qÐyr}ÿîKÃú¥MÆ ŽÜÉߦÀ3¾‚ÕŸÛBç_ÅÛžÊ+¯åi‹M nyÊ�4ÄÌ`È`0 ™5ÇŽy ½zbÁÚ3¤½�L•ð®¼owëîôë·c ТvÕku&ùø�=Ì[>�`J¡BØ$I18RZA�§}CÏúåA^±¦1s’`|Šh¸Zm) Í xÐ�iÖ¥æW»š„†|ü“ŸO¯¸þâ'vˆ…À(ÖXï %9¸ ±.ÈrÙx«ÂFù÷¢’=ÏEîývǘ›¨“ypý޵iͦÖŽxÖ F´LúR¸Áúx¯)K¨Lƒ¬ç=bpp±ÿ¡q?]¿¶’�‘·�šç©·¿œku?wE�}J$�ÑNX&%° ceR �bE³+·|�éå—‡`-4F¡Ã ‹ÝÔõF†¢ËÁU«;r ½©ù/v‚ò’Ã~Ôš`0…Š]ÁzúRJgZ,{áxD$‘ÊÏOgp9Þ 6‹�-†ÔÈx¦¥‘’øûxÊ´ß!††©ø Ž †q|�ÉÀ¶µÅAL@_Ilš“CMÎýW½ù=ëÙú‹OæÕ/èb}-¢'�cVœuF2‰,Æš6Ta5¢f,5cÎMW×wˆŽ»EW–Š�QÍ«†j´]Ú€ZP�EôÍV~êÝ~GK2KÚȲçN0ï`ÞaZ~g¶©$C¢"3¢çkoåȽŸ=Ÿ˲²\± LÈK$¾–XÖ±WµWµô+ºé=¿ÿ Vðûo_Å9¿ù§1ÿÔ²õYz£†A͹2{Óº’ÚD¯ß®�¢ð¸è>,V)SÍPûPìë㵩c-ºß0“Ɯ氈SGès$íâ3âµÿãbäÕ>=öø@)—^šqD‘!ÝrµUIÜÌ‘Ž1QÞåË1!•%VÝy5Á¶S˜} ÑŒÁÉÒJ-.1œÁZ\ W´Ki@åј€¬iª¾rPºaš®kE§/gQ൜pg£Ìtf©”=ÏÄÈ-VPRgð_RÁ‰”Ð}î¸èÎK•�¨iK¦"‚~ ì£ø+·±lBÄP‰]*p£zèþ­W>7o9{Ö{e-afqS„NJ1s¤)v^Zê$Q'i“Î…ÿNUÝä˜��Ñ�~E9l9÷¤x™ªrîyÍÀUYæÞfȼÒÔ. µôp@%^û%]H–ÔW‡˜mg»áXj9–F$Šq>ûm%Câ«(á-óܨî}UÇu¢tî!çe¿¥tä`1Ñ�¢-(ZD0^WB•¸º�Þ_+yÝŸCù÷Äœj„ÌŠ0M ­¬ú‘8.øç·#Å'Eïqy5“ä2HƦL€¥K¶-T,ýýÀ˜!ÕÀÖ¨°ìùZh Wž´û”iŽÅf¶l7ñ½‰‹v‡V_¢ô ÁJ°÷�ö·Í¹ÿg¨j²7}éð°  x‰åÆISX†Ùð4š¼ý÷gøø;þG‘�7YŒƒÎÆ2IÔ4’<=µ¨d©éš1žéÄ3ÅÜųÀ ¨B…ÏŸð²S瀣8å–ŠåÜŸ¼îg..¦"�° ZcÎÆ¼èC|àpåK‹o„6Aem3sƒìAˆ÷<ëã; ÀÁµþÜaˆÞ\ÛºÐæ|H/4 èX+~òSôl´Zs8aºS¡i�±ŽfP pD‚µ-Tß#ÆÒöØ*Æ\Õ‡V�žÚ"Mò‡´w3Ü4"Ù0ép*ÓmcFÞl›ô{5vµÝ2æ¡RãÓV5ÐC7R\µŽVë§™­|€NÖ"6ãXŽã£®ý¡3§;®� %H#HMŠœ% HlàŠ4�sÎ2Ñüà;áÙTH†Ùmk»40Žê5c®Ü Y{†E–`¸uã¤j¸ì8—&Î'ìYFÂÚ:\ýSßN�ÏvgÞ‹Ëî×âÉ»_—ú£c��é—Lê2`Å#Ækè;F°êÛåmèrÝå 9ÄÞûTx`á<$üåÏ>ÄoÿìO7Mçm« ±ö®ðBäÏêÞ{¤â¡â¤èõÐ:ß„à;¹*A•Ñp ý‘ÖPV?QÞðÑ�¢"ÿ “£Š™Ë,y¢œQ3gÙ„…Ô[ö¦�op*#Qû“ Öi€0³æ�m°‚(ç»YL xh åÑ*á¶m,ŸÚåkÛ¯}]>.+£Ñ"Ï~ö«áë IçKYý:àι�³/Cj[¼,v EÕ®=@i‹({¼°�£'P|H”·<ÀÊUè9lF¨…9#¢³¢0—ÕQϦw�ñuz¯‚ª�vRô˜ã±è¤è½[teØõ¢Ç±çL²2+ï7ÝD�¶zÐìúzvͰŠè�ßÄ|äX€sE$Ììst|Éñtýl^GΠªíÆ£#GèнtLLÐéE3h0*´“¢¶Rà>-£ü™°VÈ‚ pÎãšYM=u.‹�ý÷†Ôœ…äs¹ü󢷴ؕťA?kÊ[¶dÇÅf— E¨ÖÉÊßüÛNu WFÙü9%Š' ÞS,H––œó˜…9u¢tiÕ‰B¤¨Äcì •äµ÷(.¹åŸšòM0|9FêàÔ©e%œ<"«å=�6„jÁ?û`ÆÏr-E$ê ©ˆ�̓:Ø©âÒç‘�Δ«Ê>tŠeêÎjŒèº=”®ÛFiË¢©x3ê¸n˯�H=¬|ý_õ0“Æ8M&utßÿ?¨)­ªF�ƒ»r/ÒZ°ìîju‰E¨ÑÇû4Ò?¿HjÆq+ˆJž¥#mr<ô»[°$# ‹1M~ØÅÍ4�élhè2up·ÿAþv%æDO®÷?«dnàC`ª;ÔèC¿t ï»ßK}à“š]C‹÷ ˆ¯~õï1}»E#˜7iì/,% #·3°Ó,(1Tuðá‘änHèCÝM‚­q[X€ðÑóV(ŠªÖ3iøŸ•.ž÷W�RƳñ H…bGXhÊ šMŸéÁ‘€…âÜ<ÉZ;S¹†¯ï^à–ý!\Êñ‹ »7µ=ŒÉö$÷³Š~`Öc;6xšÓÃákBzl`1òD~‹^Kn¶ÿ­ü’% À˜�`X·@u†L…­gêÏݪ2ƒ¸'M“R&˜¬ri5}Úe$Û~‚ddÝŒWBëêËhty7¢Åo¼ïzCç7!máð¥ëDŽ÷áÀ²[aÚ>BUd�ŠÆ]+:«¢ó^yÌn;c<ê»Î²MusÁÃ7û¸;uDÇEt:‹áœr$¦é|üàRou Ñyç0[Uð°Ê±(ɇ�8«Ê[ã�ûè�Êâ«ß©ÒÛ—7Ž\-�Yçî®}¨(±ü½â\Þ»÷J{ëy¯cÆÂ,ëžñÝõzHl�T­Äè@j�Pxt€ÎJÕ*!?§�¸yCâˆ)Ѭ�#9“¡ñ,?Ëú=èCÏ¿ÇÇF(>½�åy]Qµd]H†=¾slõÍtìò–6•Î)(xßPõ—ËÓ¬¡óô?Zö»ˆW¢•FÜ×díé+ÝÍ7&¢ýçŸéH䵯kÙy].K\FêäÓßì!ýçÔèÍ~hi‰ð¬°sí¸|1Fwi;FG»óì~†Jóý6ÚÐÇêUFà oØJab‚Î]S>ø/œŸX†Ï_ÄOB×Ã~×ÍBp2 8å< ²ácа•ZÂjÖÐÌ)àŒëåSÇÎCOâ u ÅÛE÷ö{èF2}(Τ¤óÇbÛóPöó LE‡¶”9roÒrï‚9yljà¤#8µˆ ÌÏlÞG¤*ãóÑ98Ò�úË ÙC`3ˆqÞø•ÍûynÀj•p #Ѧ ·^Eù°X%±| Šö¡bm‚¸¿Ÿ2SÛ H]�Ÿ�øëYïM;Ñù•áêdî¡ûþ„ÌK‰ídÎÄY7âz40 ÷¡ù› &Ùm&©ßJIÊ)-Ø’*Éös_7Wò]XBò®TgÀHFÞ08OxQß-.uôïÎ^»Æw†½õBn=è²u¤ÇOÀÝ +~•ùÉá»UÙiCÃìç…­u4·L7 É«+ŸŠœó¶H @ü0¦éŠe™ç�ó²<ÇP©0 ¬ÚMcm} U­)ðOïx¾wuM‹ñèÀh±¾à˜]¶œÃwks 0H¸îë˜ß÷~ÊàY\jÈÔ|Öv/º:–½¯¶+®§u%´†6Î}•J²…[�0!'Âpnå g »Ï¢Ä`LŠlJ�t›9psàæA9�Üå`}.˃w9úr‹|YŸ5pŸyX|> Ðh1Ï1Ÿ™j#“ᄯ‚š,ýîs³¾º‚1À`¥ªÁJUý‹‰Æû—3l†´ÉÕͨ›ÚN롘օ(üú³˜æ ö’1T縂4% ,Ʀ&Lp)Ä1„�Á9œuàea.òÀžÎ9?Ã%Þ¨þéAZ·?Ÿï¹=žÔnwa±�”³ÓÖkU“Y:2¬j°6µa±æj±ú’p é#Í5f±Ú`˜ÔäyëÍ|û-ÁËùôM.U}óÖõè^l­è÷©òêd5|pœ°Z•;�‹ôöÚ…ÉUï$I =Œd<€•�•t|œy6œk9}º“™øÎ€g~¡í¬$Òî,÷2;Cýª3±ä4z˨GÔöò8ÒwåŒf¢ñ™š*Ðù•a�aþNo;ûžÇx(ÏJú½üÏÃP›i$W™Ý:î-¢P¨)º5EwÖˆPF;9з\Ubm¥0²ÅãÓ+Tã¼ójûvº%–?k ³®Œ„ùZ“'ëç�ï<ËcÄJÖ¹•[¤U2"¾Bt°í@‰pæ–ÛJ’aÁ½…ÉñÆ1©½}q‡FÊÕ}ôVEgY¨äýòżE0S¢{ŸèýÒYÎ�Ý»¦|½Þo 2�$üP_ônüãU4�!M ¿<Ï ôÊÇÌ3t¨ ·ÿcDêqé&Ç[·ä±ß™ÅðõZ(ÃkŸrEôÙÇüùY�ÛT2Ü|"ÎÇ»0ßœʬ§Ï äײˆ÷NI+BßDê–°ÚIqì*ÊÚGqI_1ï]Ïsíï3Vß¼¤FųùÊÃwör<êÿ‹Ùxy|AáC nTSÛ aþslÁÀ(aÿ’Æ#T+!uúnAÅo+®½ÚI±†‚âü³³zS…•`b‚N�Á�RßxuŒSHKÄC¹·cì='DÏ*ç¼ c"ú/@ìè÷¼Är2MkoöÜ>Мx’eíEŽ'cyO%ñûœ¡ÂPŠŒ»ÌÖ7n™ß ɲßâxDñ>G+ëh¦À‡MÅó™q;l…¾ô.vØÁA¹JEéµ5£ZÍØ‰I¸Z|ý+!Éž§·ËÐí„r†lòU,PL ¾ ž×bÍ7ƒ]‡ÂCˆ�É$4?ÕŠL}0ؼ™x4»Á]ÜAs Ø»깪¨ðµöy­»«† µÐl;ÓëÈ%¬%¢@gãìãýôëQ‘±µzÕx­€sö«]­I¬Óò°ê6^#OäN‘ Eº‚×Y¾ÉÈò®ÿ)¤ÆT*ÕÔsöf/ªÊ†qßçÈtå²ç˜Ï½u9êGìÝé€tÿø¾àaˆJ�¾ìÁ“˜Ê ¦üm0‡ÏÁÝÎ*ÔT>Jx÷§ék�p€ÒF¢ËØæY9D´s”âwP?I1'{>r(fÖïÔ92ÊžuØZþ>mK$¢G>®sò¬úÐÊbméÌYqxŠUû®¦¸%ãÛ®2^�ŠÂ×8‘2"ßZ¹”M'gtG:W [înÜݤ¬?yÂ[ô~ßÏNm¢“øÃ.øñ™ÿ �…óÊNnÑ[‚Y‡™q˜Ó‚câBý$kk%ïŽEw\ï9ö<�B-Ϋd&íVäˆEw™E׋>UðØ�Å–kkUë)À2ÏBžßï굘ÑÑ"ºµ,*ñD-‹å+ 6d]Tí‰1ÏÍ?%º èë–oŠŽ‡~ß³ „aæé¶Û‡øÝ|¯Zìå®`ˆ˜˜ çä[÷ÇÏ\z¾ãÎß¶<üóu`Å�ýM^¾%¥Žcï•Í!‘\x%M^ƒé!Ü”ÝÜ]ŽrÃØ€Fú³ŒÇ{ ;¸&¹Ž/4+}¸M?GGÇ98cŒ­OšØc¨Êp;†’s) YÛÒ’LknI|5öº¼)37ý%ÿkî^t(äš±buDs;¶Lº."=7&Y÷fܤ“™‹ð0·«žµ$Áð#ÂÁÁAsÏ�«T”b¯ùMºXÕH |^ÌÆD¥A–ðx"ãËÜ@Ï áÖ?´¨‘–yLœÕ°ÛÝZÛÀaÌÝöT^FÌîê¥Úß‘YLÔ© S«W�À0X•ñååìRìÈ’cjy£Ñw«Ÿ/þ¼¢á›W…«oNR�äI¸ŠájÝõíÊÖç�ؽÒÉjÝÔ™0§ûi|iŽàîýXƒ»/&v¸ãÝ|°¨0T˜H_Îmm‹þ_Àuß gÐ×ab(–¡|ìÉû æaÆŸòÌˆç• «ËwQ³2æ6™¨:a¢í¢ëc·š•÷§ëš˜ô·A _µ0·­|¿cô@Èì¦Ðú{*s$‘0ÏÙU†åõ \¥σÔjX††á™X–ËDßýÁ.~mÒb�4(¸7ôÄwÞÿ™è¼‘KÖ쨂¶;vˆáeÉä“k³lp€㶸Êîôº2XµÏtƔǨCÈ#ãc‚ë¸>¯§Ôj$¼lö$Ç6ó·bê!Ç¢âŒm}ïñý¯}hb0@úV;ly>h/æP¸¥ HÆ÷ƶ$›øæ%×®hЊ'ן»Ž½Úá@Ú²‘@urÜl¦nþ¢J…Â"$xØÔëæ1 Xô(¸wv<ì\³ø™ßyüÃt}ù™÷NÇÇ.�úÀ¬üÉuØaÆO°Z¿Œ[ƼÜÙ×…¾>´ì›õÎã�nÿ'^sƒföÁ{3§vW¨î�vlÙm*ªÛ['^ž€éÓù¸.t�ÿŒ«°»½�‡Ùæ³re&ã:*¢1³.!:›"{9¸ ›Ìí =}DÏ;¿ürΟ£õËç¡k®é‡‰ƒ…Þ7Q0<ù_"Bg¡—Ý}vç(I½Ž)>{ú0®4Ctû^" 3¸‘tpG}°ö œÀÊ7Ñk1ýš7på1#`,*¤¤Ö†w×Z/7Tõ®ªÑõ9¨°ƒÑxœKÍ­\µ°}ñ4˜3 Ò5�ö�go„15M�J–O�ÛÆ\ªnKùûé`ÍRôü=¡° ‹bõOècxøNEÊU{ƒŒkM¯@›~.?ònº\)µïgSr˜ƒÏ<Ü2C°û(î5 u�u Áð�ÇŽ=æÃ÷—û+{ôrú7^3Ðþî‚U4¾~7sÍÛÙËöRC¬yŽ·ADÿÁ�£DŒï0•ŠÒe'i1N4:�TGÉÝçp§ãgB@}ÎmÙQq¼‰ðp_»âðø[ô ªá�`sÅ�9˜›ƒ9  :Ë�Ío\â8RšÃhUÕ˜÷ìÚŒ€ÜKò‚:k5ÿ… Ô|MugøîÍãª] Sºt6}úÛ«Žóêˆb‰ ¢º*Ô”Yw³{è–�1’Útµ|ÏÏ>Çñ�‹„w¾‘v?ÁÅ3è#ü©­”¹p/4×F�b�Ç^Ù¼”•ýqÖ®Ðÿ.H Š0OÏ .cm †0mRò®Ìsy&y5 CÃPyð‡>ÿ+ «­´Ó>vãËmÜéònZŸº‚èÀ– ]ý)ϰ�\Ï×.mÀXóR“¾¿ÿš®0]ýК¹�¦•m²³áÝ-ýÒ Æ¿ã•2±&6Ú‡�Ô‹ü*É¿˜íiÝh¾n4ÿ8.tß×Üaÿɰ‰ìOcAÇ2‘|ù'Rl#1šÿ×C˜7^I³öB/ˆ)Ø<—«ÍÅÏ`·~d¼Ää�}½\ø¥u ð¾:…¡±Ý¦6A5;@Åà»� `¿ú)|-¸²Q|a: x¾ƒ5ûÚ–›õ6îY²¹‰Q+F%Bµp¤HóÜñëÇxÛ?qåΟarcxr5ºï.Ì©˜)-´°¤_Ø�p%%¤êÕ µº±_üÅ{ið) \üÚO†üö[-|åñ{~?°Ã†ûrSݰž>ͤçÛãuÈ,‰‰eÀ˜T¤`—ÏîÞ°7Àwcš Þk‡ÚÞŽ9ÛJUð’ÐÜÿ^{í£¬úð0€Ïþ±ÜÙ“Øm—Ñú󧻚¤�b!èaukpPb÷dðsýXó­&„ô“nªÊ�÷ƒawJM�‰€¿½�&;°«Wcv�`3[—Èmý§gÝw{2GŸuÌEwy*é~ÝÌ‘M�Š"kÏ>ÓðÙFȾf‰ä³ðÔÌB†�Ñpzš.ß­Si«‚´OϪ™%~Hµ•jT#¨Vˆ3FN˘Ê,zwçûÝ‘#VžmO -YÔj#¤Âc"8åO;Ó�È×Ûàœc?Ç´©L­ô£²ï…®Ú]áQˆ#zÅÝtÕÚ*®�ìYÎû©}6ÙóðÿWϺ“»>‹ÿ$¥w­T¨Æ\¥rȮϕQâçЬ#lÈrBgä™xä|ïúÉö€ JCÏ×O¢Œ@1ÃDlEmÚñœ&›¼»nl$BýÑcͺCÃù>þ,ë´Áfu³]…|~Ýz•ÇÒ8@i»(Œòÿßv%6l- ��¾‰öÿ<æÛ"8Öèá3ÿM(ò Ì£aMþµ{PÒÈbßÀÀ(a®ê“¯‹ŒRÚ÷ŽdÝr�»ëþÌÏa†pûwø0bÒ7×¶.¼¡N<0‰ãPÇË 1Š@õÝÒˆaØh÷€[¹Ò¿n�úwl­f·�PZ̰[¡šuêùWÞ2AÄzìP w9w9¨œ¶tþÒ?%@Šm@ÃÐ$U`hYÎ;“†>#¿´cÏ�|Xop´XÒ 8ùé�ì¸ùcüXå2Ö×ìËÙÝ<ÍÃ�žµ6<ý}@Ç^ˆ«€ÝÀTlú&Û1–1�›̓ü=ì~¼ß÷<$¥øf:cLÆN³ø5¨ ÖèàÕ–¢”cç,�Z©ÂÐàZrA˜àZ±Öƒ†%1¨e°gcL(Ѱbà ÷~êØ+ycÆa8lÞC=™_’Àöè{„ÆýçøäfÓqÕ;IúÀþ�]Äç‚>ÖÀõ�»n í]Ñb|ÔÐ_è�øè¦³Az*>‡�³¯aP¬‰a¯÷c\ lïñ®Ìå`ëdÄ@B“ý˜ýœ‚`vöq·èªl[KI¢0=M×õ{9ç#bR±ÅEô@ç0GQòÝÚ&¾÷VbŒè�(W”©bä$þcDG=*í\yŽìÞ¼.½ôï²T[ðhFv®+úúý?.ð-PbHÓ%—Àl­åYi3 t�äl©¾§::+‚‡vÚÅœš/ñ°V£/<““?û´ŒŠJž²Zåu£Ÿ/º@ÕLß;ë×_BÍ 9N¿jÿ«[ô%Výb ù÷¢]ÝKáÔúßšµÌûþˆÂ Gð°#œ,(@΢†÷¨šó—:ñð\_ÿìó³¾x {5ûŠ9ítÞ½Öžß`”p`”ð±×Ñ[²´þM‹®L¡çÝŸðóohÅ]S¶0m㺒g»Uçr¦ÖFŒ;:œ£(õpçB…\0ïͨf ¯9kÐ>Ñ;-º–êÜ-éÚk{0ÿ ]ßs×¼î`µÁ§ˆO­Ä<é©,ÜõUBê“n2üÄ‹RÒ‹¤(L!°Ãq7 AÝÐOp’:£†!,ÕŒ¥³„Yµ@¥ H¿ n°’+“ûš*>~n…hv‘/… Â^m¡’®¬ƒu �HL+R Ò€ ,‹Íîn‰3ái^Ä�wŠ0 .t´hpäùìÿ~+ù7üóM—Á» ãïŒöG+£S 7n¦ÁFÂñ©÷X¾KXC±åõ_üÈÈ^É ØßÇÁך4x­c¡QtV©ç|ˆ:S\ˆ¡�ÆÑˆeC,Q,RKŠ g‹†‹>¶?«@LB¸Ÿu }“Ñ`¥*CÕÕë>n¯3h(aú'1»ªmnÀê1‰v隸ášß†Èü Åë7 ‘±kX˶&/¿µõfƒu×&”f˜5˜…T>]“³†|qyæÏÁ¬ªS¡Æ:HW‚rä]½n‚¬µ25FU#ªæ?Á¢ûžÙï´èžIfd‹ßa«£tnÔyNu½lP÷94¿ÞîG¶'›tº/<ÊÃbÔÀLOÓuäˆWÍz¼Cªj÷Öç’9çUÙ—W—at¨˜c�«UB߯\ ¦D÷7Ä Öèé†÷|3ä_ç ³‰¿×fÆ×5ãN;‚“‹L,v^ØYåž 4=[K|Òÿ­IS�…9¡"É|LªåèópúJvª—ûZ†&:¹ûþ.–2îPµ™FYòrF?5Òÿ$‹¾ÔšxJf�:z÷¾^¶œYÙÁÌ·#f2œ»DᔈÏh‘/}NpV5¡)LÓ\±ã¡‹ÑyŸ¼Ÿ.ÝKG/€‘Í�,«U‚GKWe9óöè¶QÒÎL´D„\²ºUíNöÇP™;ÔÁJýØrÒÓÐÅQœV™7öáÞŽœÃ>¥ôž£¡äD”‰m,z{´‘–"Ιu÷ýŠ‚Û  }ãÞÍôŸ<Û¸}®´—ߘå+-…¤`[!Æ„çwvÏJ•”ªLšâZ-ܹ :£†ñ†«* >Þ'¨ÉPU»S-ûºdWb˜6îr°«Þ‡ÂÍóNÁFõC§OÐbËá‡T|Mݰ(c¢Ã„)ɼ}D[×¥³2.öÙyÉ’5Æ6ŒMçŒUb Å,“ÁC,ó4œp×'¸ömç5Á³ùØE^xqÂ�ÉÒ»«Uwú Á`¾æô4?ôót(‹Ë3J‰$Ÿ>ÿ�uMnýøï]eSð w’ ¥Ù„ 5"±‘,±Œ°–°eHËkþâ� o<Þ] àLµ:ઙŸ5½K?¢r­©dœz‹—4$ñ÷èk¯®†zÁ¦ÝÀ½G¢jOòeÓ ³õÞ„F78GC«A“ñqhU¸ÑtîÅ‘O¸áw˜Ÿ'€šñ|€ƒþ+tP¥úèGðøZô�\˜nÅ>ó;ê�ÐÊœÕ2Ô"tÞ ÚiGw뤀Ñ�b®a5FÖ×íwº¦éÚ./¦(/2XÜ'Š÷›ßá«‹Œ©¾7»oÙB¤ �Ï„+Шo¤¢€ë÷žñÍ/ù,¯óýÚ…f ;·„}Åïî'\Àé4W�1¤©Íº›(©å™cOˆr"¢YÓŽ)@ILª˜³:wWºˆõ'zÈcÚG?ŸŒƒî¿ºEçQ1ù’ï-P>—ÖKJ|;Åœ4qšx {"JÎGš&M-I2+h*µ¿ Îùô] *{«çY\Àk†ïšaÕM'èaBžŒj5â¥rß?ì¬û® Ž|ˆŽ-ŒDUa©ú ûŠ·0»æ)¨s,-qÒó¿r”œžËg_*TP?QÎoç½�þ¨½6‘É=S‰®{EG¦h.Î Ÿ£xÜ-úî*ŽÚ&Sý ÉëÀðþÚoÃo*QÒ,Í€´e3>ø†ð½È²1 ÛÏØÄÓËìÜÉÏlã�F�íXòý ‹½gÍȈZ“õZÐÇ&Øý>x’€ÚÁ˜›Ÿ:Ûêìx­u眲 g 4Ï„D�¶¨9>Êæê²£œwl! IH¡¤ŒÉØ`cÅfê%Qˆhrü¥3üÞ—ùÖ›~rá0à™IPÕç#2þ¹ÿêG—g_ókîÎ9Ã?~¢E+‰ÕåÙ‰4P,°ÎΧ�¶„µÆÙFqâ €ž\sùu<Mz×FõœåVU³Žu:Õ‰Ü2Búy-ùÏõ‚J¿Fú•S$ÏÐ5¶Š„v†4có¾ù¤ÿÃË?r–û+)©M°:ƒàÍ/pÐ2. –±ù Þ¥ USGÆ`pǼgzÊ3Ü¥� ‹ñsãcѳ#9¯d�]>í9É™w5X¾ð§ é<*ZÎïZIU+¹(¹’ît¡;@Q)vÎó†sº™[À™´íѽtxéa_Wβæy�9Ü—±­ä 'Êu·}ŒÔ•ëLgÿQYJÿž’Øs€R.Ûûv±‚û_ØÅÅ÷\R›îàp«Ãk©ùx2ïU÷1yêuÕÎ$§‘("Q€rJNŸ©·'vz1coÚL.)Èóuã„™ßG·®äˆ:˜PçfQ˜¨‹±Œ®j/»ŒRÎçî»GCßEG|2ã̵Օ‰fzs6·è…¥}÷�œ•eÁÙŒÍ?㬖m\§TFwïʼnZ¦„ú*/y�(ýÁÎ×C,Ë*!l.0¦ˆûÕEU+±�·4NP<)l#ÍÆÀùÚ™K1J09oyÓAS1­$ä_]�O¿ëi?ˆªÃcµèžõæ¬ Yhbna?s–§œ]Í'Nö2¢Þ½¯—#ê ªn^¡Õõâú›ˆ¦b”P8á(u©<oÓœÑ:¾<�³ÄH"¯£/Å€,·ü^gøÚž¾ïcEf$+B01NgbãƒüÙ‰ç C¶QÄ-üé éFc“'•]Ú…E ‰I°Vx½«Ô9çHÅ,®t�”~ÀT©ÈØ:8c0î8¤y\­†­"Ìû‚SCF†îñÐílpvÁ9Á]¸a-ÁJà0„�_¤Åó?ßàOŸ¿ï‚ŸyÖ/œ¤qk×bM#5X §†f ¬0κ”f`ˆRÛF»="y® Þ)# 8�³[”ÉÊ4-öÐZf>ûwüØ?¿�oè�wAÊ.BèOa“`€={4_7od(šÔ‡£J¥šž…Ð�sÇÐtµ"€ý�x@ßÏ!¥˜6Ÿ»œñX„M‡‚ävt°BÄàÀµÝ ~ý…w¨¿9ö´ñ³'–¡Ó{±ox7E´k�g-\À±?®pºó7�{ù“œ±Ä=Ð2 L£`T ýÍ ¤!ÅHŒ°%.ü†Xó‹�'}næJÐÐ÷+?„ÃÏ‘ãDTT1Y0ów¼Ž-ÿ§Hsr†Î‡,ï°],~ŒÙ'=wÑêÛ�§±`š$ZÒ[Ÿ½©u°”ñYç¶=× ¢¡ÿú±Zôð˜|6¹•YôFfѳݯÐHg„I�E §Ó2Gµ‚DeæÕA"Ë‚+�ú¬j)uJ±ÇR8Õ¥žŸn&-¢»« øŒmÖÇ�Ç~™Å.,±Ð~ç[Òœõ!{ÄPv¿9¢(ïÿÎ�©-2›†Œ)zË$kÞ,ÎEêä)Íç|hª‡o("ue”ÂéÄ0“œ"”x/¦åYCMÓ-ÖÚó<Æ£z«ƒS"8á­úoÉ’¦eœ Ìj5Ú» �ÛîÅÕc‡xÒýÓœ·E#(ªV éW´O+Ûù2ã òõñ ŸvħD¨{rB¿ŠF2a¿Z� ¨ |TóD^¢R^ÈÅò¿[$cÌ^–è„Z.mR•]¾�nOO4ZäêåÚ£�]̽pÉݽÌ;_¦J±špzø6|Ù*§¤ ÎsÆåTDíäepÆ7ÅØùÌ�u©%m(�H]L#)1/ºÞqˆËo}Ñ”èù+¯¿Ùƒgª „Bvû. »¦(,& sš® åå%ý®»s²4´’¹Åbâ0i Ž*æÔ\�ÓIóŠ™u˜9_"C)Ñ‚óðßìù§Ìå÷÷Y<™ 4ÌgPâÔÓBE _áIÚÈ+´šõøRl-¿Þb•ѰÊ"õØãîºG³"Ò|ÈIyб}st=—ë�œÃù_\Áe–Ó£Ë#š[KèC!î,¸†åˆ£p¼MA ã2‰¥Ôùð‹Av •¶]B ú¨f§ÿ ×]‘?� ÿ)rYL´Šl�@xÐqn….t/ÖÚVŸ–·Þ<ѹû¸ì5 ÿ‡§Ñý™áWÏ„$&¡­nh•}³HíW5¦Ÿè,„×d„ø•ŠÒåÐ\Íœt`?ć1å%,"†9Å}´)vêuÌ$&¾¯�èáµÄ¾Œ5DݨQ7š¿_ƒåÙ�¦ë¶¯™®ŸÝoºÿ×+³{Ì¶à ›:u¹‰ß÷ºs¢™�¥ñ“ ®8Å'~]üéјÑYÓüvT¦ ÓèÄ4;1I,ëGÝ´ðž©�q~)yw>íôÌ) =1"órL‡)˜¶éH‚yl‹³¿³’Ï\µã™F˯ù°N>íJ Ó˜Î>Fµ»jì·>F¸ù4®ž©#N‚-eO8y[ð=¬�VL‘oèµ.]´` ÄôhôüÙËfÏçK›OÿÈl¼ï ÊŸ½&“¨UHhnYJ«lPK†TÁ‚ÅÉ.tRXèSLdlK¤:Eòг9Ì�³ƒ³LÝ™`.hŽ:m¤c¢fÜKª›øÕ]&ØòYV? j�óaZ ¦5[´ôÐá: ¹;aíªÙçß|î»>?åº7�æ•Õ=¯Qü�Wɼ.yëÛ/æÜ·½®ÌžÃ]�ý Ñ×$ûmd#ëÁmPäb Fë+�LÀIƒ‘§­þþ�ÀB„‹WÜl�‚C6d s!-Œm’Ó“w“| Ü�V'&<õÎÏ3ÇMÏ}£m½øÀ˜ˆX´×iKxœž?‰¨¯wy[“K]rXá°KŠ gÃvÈâ3¶¹~Yä›w9 Òq�dófZ?ýLZŸØIã�Ôì�sAó(Ø9KðÊg’2s»˜$áºuÿ§‡_ë/pù_ÇœwdžyåŸì}Š$cCI—ìvñkÎ�濉Åt¦žœ>)8 -hE îá§wrçoóâÛÃ/õ±p/“ T¸ùå,@[µõ»OÒ%Ziÿæã¥i.‹ÓÃŒù%±ÐÀ’åcÃwóËC_äï~뾶⋜÷’7ЧZ”e”(hb"'ŒIi � 3vx«4€™˜ rV¤ØR‚ùÈŸòöÝOáæ84°Ÿðào�ö•ê7<›àê§pê+,‘“}œCÑB0N8 AÈãé°§ö³Àúše¤:¿ƒ+ÌIˆøÍ?8Åß½îïžÎ•/.ð¬�ƒŒqy²!mÏ…Bô�C¾AW*jcBÖW°è?²Ø¿‡ëÎ¥ ‰"»”¹î9.QÎÒékÞ  ^é1GTeîi™yQÜû'l;PbQ+ºóøÿθÍEŒ^ÑÅ©g.‹Ù_[É7ÕV á¨(ësTªV uœnµk´>Kž%±Œä5åt’ÞZ�€ [ TŒ‰è³Ó¬Ù+Α}ñ'ï§kŸ(RU ²¹2©�‡ÞæUW–+ÕO™L‘u*ÒïÑXïøˆW Ý. Œ�D¬üÖyÝüù{;Ø>×ÉD£ÈŒºP¦VêäëÄ-œM±³>üépyW7jµ¾Ã]Äeõ÷.ÿÿ2ö%}4ŸÍ‘ÕCûÚJ$¡ÕŸõ-·1¢ÝŸ�#ÕÞ©®€;ïXtÝ[YÖ}A–œ¿¾ÕVkñòÆ {•Ñç•é²o«á“5º®ÄÓ/þ�(æäfºÇ…Õ¼WKUR@)vV%rý÷D>¼óúëœ ™þúë9µl`”Pû(J�¡C(ºŒm%4²SÅÇÛuÏUZ ¤ê¤åb>²0ÀÑNÆF¢}>8é=)z—bÑÛŸMÕò¬Ñ×Qøóù¤^ä[ÂÌé<ô"j•`_Žì̪Aùóó�yßÿ}þ³îòXß<ÓÎ2§>b&gÖ:#–­Uµj,¦ê&ïûU’§oÀܰËá±=»,«oL)ÏZ‚Ô¿m©I oç=®ZUÊAÒcÇÚØiU2—Ý''²L|/vprcIoO¢:îÍÎàÅ+i…sæ=ª“ç^Lºí#Ä Ñ“ Þÿ‚jËÐnkú‡aÌu/¥ñõ£D@ŒÐÚÉþÆÍ—¡Å¸'œ\¾‰Fø:—L^óŒo}2oüÃ'ñºyÚÿ±ÎrÖ8ܼ‘IÑ|€ A�Å9¯€7»`(v§´I -²qm Ý&óÁ1z«×»Ãë°†!ÕTýZTï3ÿV‡bfÍ¿‹Eø�&²ÇƒË*õøº -&ú"v÷LÞV·¬Ý�ЊQ+ èh7_ÌÕú&±W$!N±.@òÉücdäHŒã¡uåô »˜Ã;F´:"¨ƒÛ£ëæy×X�í}Ü»÷ Óî•§¬n1벿ñzóƒÙ*©̰õ/‚ÿ9ðw¸7þ¥EJ�!I!µÀÑ2ÕZ›q(ïBë›\´ðÿ±ã±Zôðaa�eVfv‰‚Fnísnî³*q\t|˜ÚDœ!´Êò*+E¡Â*×D<0JÈК2¥ >Ã'–F =bk!ï7¯M,²‡äØõ¬~Þ+:$:F}_n?e$3&¢Ê6JU¿ÉEš ~ßûXÖF–mé�<ž¸# [n¥œãè'P®ºÑ Q $1�£ï„}èËŽ‹n�Z«»˜* …!¯æYCÁwZô¼ŽÞ\‚uOÜ#-ú¼-úX´«xµÚm5Jϼ�eTµn¹ÏëÓ5DÔj`Έ¢Rh8:O:÷DpPŽ%3"Tjüý§–yõâšôS\GÇjÑ¡1¢ ì*@- :>Ùø8%ãŸl f–裳‡é»»².3«±¼ܳMÔˆõË”ø¹».ZÆ÷÷°O3Â×9´.ÛÌ®ÂÒç•%‰‹š þÎþóºEÏß±ȴò¨·}·{K¬ïÀÁƒh˜ÝLRw·1ôCs�+¢ÝX6¾¨Áßÿë]D³18Ç‚M‚I¶+¯ín|ŽÙc�ëuÿ»Ùƒ¸û@luÇ×÷%{ÀrÍê¦Q¿‰¯=sïó ®-ó´¿û7#‡ëávàW‘ò{¦L�Ý®ÞOX©° ªf?µhÓnîÆ¤•šáÎ;)=©·ü[oæÃñ$µ`3oIØ8l¹¥ÿ0¯{õ›‹\{Y'ýQê¹Å›Å”$‚x¢T&5¨�’œ-øÛ“°D{¾ýÕ‚;ˬøô_B}ØÑñã!@�Am5–>lβbÀä 5íaëDßI&û] F;£%×ÐÏ!éc0½ò×è¼®_{fƒ_¢Å9¿öÇ&qÆ´fcL(‰ 2ÌÏK…˜‚ÃyÔ«�ý ƧåÕ �`çŸñÑu¥?€äÃlj{Øì¨UGS³î–Ç=FÇe„ÿƘ¶>:ë�`|ÀÔëúµH˽;_Aƒ AŒ˜\ðñ—XÅE#)S†°Ë%¤�·seó;ž䘑ÿàñ-zna`6CLå¥"eV i+Nvà|÷ÚvÚÝczàƒÇ€j†U'Nð¤éiºn`º«@úÃç {�|VY6£a®h¢Lë0y )›­fLD9F¸V#¸‚{;¶¢B¥B¼òºvŽR¼ûnºrÄRdoàî®ËQÏÕ¨Hm"¾é=÷‰eŸ=̪C¢<�S‘J¦6A<5E÷Ø=^�¥´¯ÓcñÉ1«:ùä ]¨¿Lÿ7ž ù¿BþúDÈ×Z1rßåÇ15(ÁÎ9�®[DÌ-¢êÚè¹ñž¿§6ÖƒjñöçÓ-d« „Å1å %•Œû†¬LCíhgÀíw|gy-·è-oÑÛ¿K|¿½=æÊèówg]S—p}’ÙÆž’P0Z%Dµ¥#ï°|!Ÿ&Æ%X-*°˜´å½˜yG|F˜Ù„àŒ"\ËfÝÇ’üg´©›]*°kCA3¬ú†Xñ¸[ôÜË1‰ 9ëw.p£z�:ÑhØ?’ÅÓ‹*®á˜ˆ¨(¨ˆ &J}"~>ZÝÇŽf¶Ñ(zθУ?YÔžÏböÿè}þ€bô% ddL��°âÊØ;3K1“Ô ÒWõ/¬1h„:qž¡µë^âKY9ç°±P�±‰Oùš†Äè0•ŠÒ>pã`rð€G|-%0A�H ¹÷ îŒFèNW0ÕQzì�£óWw‘¾ð…´d†ô,óæêuËáGyá wÿí½{|ee}ïÿ~žuÛ—Ü&“¹a€aŒE3­¡Z¼†SJD‹þºÓVk‹—†ØŽµÇ›•žþj~ÄsB«cñÚ½[­šé6Q0a030qî“É=Ù{¯õ|ßËçó¡ÿàçÙù Fºó§ÖŒ~�øµ›YÝr%-àŠTMßDÝ}7NOÕÛQQEA�—^fÃIå bþê6Tèî¬ÀxÄ/~ì�øý?†¾ßpøù{5U¡”K¬PލˆÆ©3žÖ(§¥‘ÕF‹ ÐæáWPê©ì Ou}�²BÉ0 ¦±OJ¶:Τišç`Âh´èw@üÈ÷p.–O¬nU�ÜRä[~ÁÐSþ¸â—îÓRõÀ8h:¶hD‰TU¡D¡=”ıAa0ÄÄ nYó“7pÍ~�Sßv dÇTùÑÇp7Âó/`¡´ZS™iáá™Z¢åCë0…ÂÚ#ÒÇÀP°>{_©Pù}Pßã»ËšËî³ä¯ºç­¨úà'?Ϧ®ÿßÄ¢›Ä¢¯˜5;b­‘^5è%ɱjhùjbÑ-ãÇÍBþða²× 9!Ô[É„‚f¢Û—ëÈðÀéò_ܯ9»Èw /ø©p>Òã%zen…L#’‚_@œqÿø‹¬;|˜laY âìCò¯AÖ%z\~}Î cŸé;º›ØøbfÞ”çsKm|õ'×q°­¦g=Rh*ì"+‚[L˜<-ë¦Pœw#¿C,{g¨ñ�~o˹bÑê–ïÜEö3Ÿ±ÚéÉ ¯nfÃ7 0t¨‰Ù²Ë’hL–]î3ÉɨÁ²ú‡ì¥— ÞŠ(þy•Ù‚ìÌÚÞH˜ð¥‰e¾EšU¯�|žµE¯$=§L¹w˹‘$*<�X�÷@N[uÜÝBÀ‹ÿºÇçŸÃã&KH„šU«ý–Èff*bkÝMR÷žž£ïè奛„üûÈ âîçÍÍÏ·E×DâQ‘#­Ä’åÊoFšÙ=$\�IÝGOçèA!sDÈÉÞ}Îö"®Ãß÷¡æÅ#Ž6òù_¡®ZQç#˜X‹Éøw³èõ­*±ê�¥°¶ÞBáH²99jM™"K ¾Ò‰¾ V¡|¼xE5T NêÒÕTyÂóq_{ŸaU&Ò¶LÄàXNv»€é�8åÌ›ßΨêùèÛ¨îïÄ/í쉸ÿ÷·]ËÛžz˜�|ŽË ÂÀ`t‹zV„ʈûyÇ›`ëÄÃq*Ìly��±0šgüv¡÷Cåp'ñEïÄ-Œ#;wQï�{UpåõèÏofyoŸDܹàt¸]¯ë!꼿çöÐÙõ~)_ ÆÁܳ�S§à–_هݛ…æ'<Q(•�ëýjùíæœ"�´�wq„TÝSl‡oGWÿ6¹s2”§;ÔI¯K á÷lGùéíhO§·'µ;}Ê‹Nº1”ì:'OÒ<%´XcÌ£W\šþv h,Û¬åÒ›ºŸnwî,±ÀBhÙ7ðNž¤ù Ð6'´‹ÕE„=™Ä*h±xó,};;X’ÍÈÞ#lú¬°¡�D¹ó‰‹]Ì";k,³¡�>ûp8Ksôô¾ 9ùóÞ4 ±VVD¸sŒÜÁ:MŽ\ôF—Ñå&©nFBxe‹îÁëÈì*’9AÓ�Ð* —K-d±ˆ#cX¾ðÔ/³¾•7!ø÷&{Bh² 1½®¹™1Ze™qÙz¦ÍáO?ÕÊ£’aNPs‚”Tp�±þq,š²eeIgÕ� lZ}Ó°ÐrFh$kñÌVQ³ 8Ý)|¶bOox|ã™­–pÓÇ©þ;µX@œ ðp}Òd‰¾�dO¬…‘P‰-OÜ„…µI¦h¹ >òß›¨ˆeÑ�²«Im€Y…ã‚:]Õ”ESµï¦W , :^rY[Š+»¹Mš^#¬;y’f¹‘@lÔß²žZö"‘<2¤ ª©ÊªPôCF\$ÔE!+BsÒ_ZD˜ZŠB¶^šœÔht,>Fü;�Š�—XtMÅ cüÏ­Ò+M쑌$¬³VÏÜöÏN!Û{� �ðŠ+„zHè¸IØx²Ú†ç˯rd(‡ØSg�óÎr¶»Cb×è³¶è–O+Ù<ž°V`LGÒvêéÕU X˜_¼æ˜¬ù,ù�ÅW7~,qŒ‰Àœ€¨L‚¢—I�}j&G¼c‚E¥ÚÒu,ý~ѶZÈæŠ…Þˆ{ .Jðº!Üâ}ŽCz‚ÎX-üÍ •¨|tÊ/ã÷õ‰QJ©õ›Òý˜p…ƒ28*Bœy¯ü^ù(ø[?€y]�èï?�Ÿ¼ éyZlÀöaݧš•�ïD­uJ¯™û'‚u=‰ ÊÅJÜû¬yñ·-� F¡V=t ÊÁ8(­%kkªPÚe60Öº�€Ù{¤‘Ë|ã(DDDõÕžW­�±¬�·<³nZ'ᤓA[¸'9Aô‚éëÃ0 tQ½ªå ÌâýT¨8äóF­”AÅ(8Ê üÈ¢†EÕN-Ú« –³† îòz>½begº‡[û QF) ˜ìŒ9Ž¥*d4*L²4} ² “©Þš ¥sÚΓ<³RJÅõ «¤qþÖú¦ñtc?³ÿ&9Í®Ô ÖÖRj™÷ƒyëÖúRe�S]@\¨*Ì£† †‰~/Ñwÿ7hI46õÍ_ÜK±Þ2a&ÖXtw<±èqÝwTUA•“ëŠõãœy©q»c,gœ?r£‚¨‘ЪLÔv&B-½6‚.Bîˆ�C$ÇÅrq†âJS£œ¼¸¹kŠd§Ý´Â+õ�¾v†¶¯�¡�T$9¼…•×k¾VÁûú,YyË«bã5BÎZþ„ËÔ�à!;³l’k\ÆÊ>Ëâ²$¼N^ÄaÉ!^É ¢úÏ‚,F\’¿Á ˆÑÔU3d�¨´’,¬©†„.à^·‡ŒµH¡FÄçÊ• >1XËY ³Ë‡Â>Yy)Ö|¿ì²ò:dÄ éu¥€eµ'%}Ph{@h©�kb£@2ß¾;KœŒgYÐ+q R²¹ûêÓ,ºô)“E¾�úŽéûïòû„|Ã�e(|†»²Õ×àܱªˆ—5e³du¢ð²* +–Ŧ"ŠyÁ­ îâ ”&kñè‘2,Á”Ð2ÒÉØ�'" ´Üý¯šû…Oóo„ G… µñIXaS€SÊûŸf4jœyŽežõ¨ˆGÕ¤õ!G'ìA‘ÁýÊ*KsÍ¢§'[¡i¤—©© ;Í*%jBÉ)I§'ñggÑ쮟îÊkÚ rÿ|C¢u!µéu7P×ýǧå[Uºšyx9Š6yru˜A”F £6Âxü8jÞšŒˆëæNø¼å“pшÓ9MŒ …­ºJ)%bÅó6„J½° Õц*­ÙI€ÝÎwñSãÆ˜J†|yR¶}xž ¼^—Š žQ=@7·ÄTb#h<2‘‹‚Go|'�`ú‹Êé«”@ŸÓM¯„X%�'J˜È# /È *­ÙÑ•Ýå)2À ­’* H¢ö\GåÖ½xœß@ ~yj÷�þ›õcQ O0"H¤´µºF™(‘ùv"Mì8¨ŸÂI}„U* 0®þÖ“hyÔ ™$©½ö8¢]]³ä'üÉ?Kã-q×Ä[„��y ¢Ç jˆôË=*(€âB_¸À}(¿ý£Â\Ö(¿Œªæ ªAQÚ( ê+ žM Ý˜x.ã°©\A‚eVš˜üìãE·òøý¸;þ�E.»>Rã·{ƒßŸ0÷OãÿÊ$åk×çô ãÝÈÜfþ(R*¡„A5Þ�Œw#¥b¨J%T_rÒI’ãÉ{PQít#5”oúÿi'€Ÿ¸&Í ÛÐdíñçµà> 2Ñ]_O!}q7D/;I”™¥âüPøÅ»ÙØÑÖæ×ºwº¤*»ÏÍ¢KXS°¨Õz'¾M²èZ%Õn ðôˆ_¼œ\O«É®Yú´Ö=69DhúrÈÔî@Äj�¥~cÊôBÊc.4�Z®r]SÜ"m Kð¡9a½ÔC:§Ã÷Ø1òÇŽ‘·‘mQ©ERsdä‚rÆcÎà~jžÛ7‡‰e%eË´š]Z„¦‡„<9¹Úe¢KF#+S3l’‹xàt‹ˆ@×T¨BÓ~±yxBÑÄ¡�ÀZEjºX PY5â¦Ì�;…ìV!³[zo  upcW rM®‰‰)Ÿ£u¦ë·Ç¾­±6š²¸,G¸_šá•Ã-ˆdj5ûØØ‹ zNh?(´5ÂvÅ5c9—‘oü gœJ|t5'¨ù$—_œÔgŸ59ä;5žô3mÒÉXNPô'WѲ£P<Ñ„H3Îß û|ÃZke*Öz›Ì ,¦‡×X *¢‘ªƒˆ&2. åvd‘Gr„¢¸37%´û.S‹™VNL¸&{ßa²ieªÐ“ÂAkïÑ0—‘àÍ Î‚qY—T[OŒ&2šj�§´J—´X‹n×ÕÔ0ÁA!S²aÃÚ*"N!‰MMMѲCø‚´ðfiFF2Ëí™ÀŸ¶<iL)íççu_o™$ŸfÕSM§F€¿'*e6ý_6•޵Jl½²VÛ�¢g­zh²“*,ϼ*%Îú££öOë)pg;P¥êzˆCFuJì8èM›Ð…mèšùééW@U¯Þrƒa±ÅÅ1ø[㢣ËyÈNrCJÒ–Z& ¨KAˈ!T¬ 3™ˆÙfŽW~›W>\Qj:Ë�®ÊP?î ¨2˜¡JOF�­D(¥R!½‡J·Ý�šÕ Îâ‡ðfÀÛp+¨0s ¤Êï~`…ïþžcè¾;áÔP  ʉÁ!¢ŠAãàŠ‹qTtñ�É^h(�t郄N%Ióå.èÚ�¤îš„èi1˜ÆîH¦ÑwO-ÙÓb7�ï/¡A¶ÓÝ îëîÀ]¾!¦tRX÷î?ªÒ|Œ8Íå»XžvqÁQNŒ(M9 ߉�Š]Aª Gb–ýYîç—ëe„[ªÂ,ÞQn6½Šåa¦üB’Y(G§mŒ$êD¶tÖN5Q¡ q#*¬XDÓÝW‡õ¥~ºQöƒ$û*Ù-m¼Â4„Mkûæè´íÔº5·w(‚7 ’ÉP�:|ÃGO ·¿4`KO”þû® ‘5Y’Ág›S¯ixÙŠ›´Š§‘m’—¢ø4Ýú�Ñõ´{MޱÚÀp�òº7í 9,Ùú}F\Dœ°Æñ–D©¿¹À„_Dœž![Û^¹‘@j¾V«™‰Äב„Ûûn¡õZ¡-ÃÂr8PFŸ40-·ÝÍ×δ%Üsª(dwÁAf ý®&—ê¯âÜ_&ˆm\Y™ØC*ô®leL<Úm´6%°¢všûni b�ª+¡>vÌÖØ(�wo½þ6†§Q¼úd³Oôë.{bñ-IAd3–À"ÀH3"l¹íÙ#ŽŒåÄF“3éÉ'¹2ÃSi�4ieÜÀXõõ^ƒ^K²$k,ºª¤9v;Öάd0ß9#´¥÷Iã= sÊž,î$—Œ‹{ßí§m¬ÀÅ)½÷'eÔ~Á9ºdñQÄqñ'å—ÓbÑ‘úIƒ{ÈhŒíçñy÷\;'O6Ó;âÚÿÓ-é}S+H±PÓ/«½-cC-ư_hZÖf”ÊgÁÔ-új-îä'J-É:ð¿TfÇé¦viŽ~$Ä�übšõH-q=^ãîê$î¦å¡e:� {î¦éuÓ,ÎÓQkÏÍGoØúúÝ51VÅ‹¸`´‘gÚ3jp¨uZûÿ±88 )ENê÷z@8( DJô¥�IFtÇ÷€n¾ gè>„Çïb~²€ä >uªŽCï®MàP= Òf>n0ÚR�eª¨7ÜÇϵE¿ËWzp·CB|ÄF®;ñÚ«ë?�wÀ±ŒÀ…R(”` ÙùUê«ajãâØ¼FCì!9qÔ¨üQ¸jM¿¤]œr l9)t=¢Ç{€¾PzÃЬ€œi\k ¤À_ÝôÉÎi)wof)“Ežš!¿’•þëGí}ž¨Ï›ÚúT¡<;í½„ÜVPÕ+x†…–‡„¼jƬ/\öIž Ÿúp=[¯Øjd7EÍÅx‹ vy)®ñƒû÷ÿ »gq Løµ“Ã~êg‹�)Rp^G¦˜ø»‡ «Y%ˆ+¡õ ÷ ÍCGȘð««Ö'¹¿DZóÄ_BÍ ¾­ÑVˆá‚=7²ÛêfO 'ØqWF,nX„Œ ª¹ÆáÑ ÁŠÕLóÏX\ñ8��ìLýB.8!lN”B\[êB?­)eÓØš|§�Â'ëö3ä ÿ!!/÷‘M|¶¬ Šc—æs¬îÈòc£X2°(0[E\©¢bÓÄ㦉ñ¿G¶7 !÷.±\ô²“laïEÒì„Þi«ú<€(&FšhúÚ75gÊè•ÄŽd·*ÊÆ(*VWN’¨x9BùV˜ úî;LöŽ}vì>³Ÿfzí=çÄZð}uØúÇË3ÏÇä<‚¿ýAÀS’Çj×¹DMdì½´ôªA/Üe‹_·eUŸE!�k¬ÿßkç]AÊço-鈋ˆÚ!½#¸‚ÃHPœ°È¾NŠYá)á…/RHµ5˜R€yöd%õSìªhâ²Õ¬Á—y™´ý�Ð>=ÏúZ?©e  ź\‚†làR —Ö&4d.ôH˜f£jó¨Võøì|ôqãk÷€•šËTJ‘˜«¨bfó¢´¤U×u3Ö0XIlŒ¦lÀh·£ z>Ãû;Õ›¸Ë/IwµW èÁAôý-8§O£6}a¯ÕÉÚú¶‡ÑHˆÓü=»Ë>É¡0“EàfôW¦ñÖeð „ñ;9ä¯uå5Dÿ�ŸÜ°Ì¿¼×*Nl øõê'¸ÑZ¯®(zúFaÞž�‚V(*”%&†¨ªp”Bgª¨™Œ�¯æøáŸð©Ží  YdµiOQ’Ïó� \ã\9Äò_]oïs™"ªw3Œ[¿QJ F¿?È æR¨LŸúø,¸ïìU›nB¼®L,¹·Œk\üæ³êZ:û²Êòò¿a¦Io ÎË òÍÂÛ‰D ª’Âiâ¨ýõÊAïÚIˆ?r5Zá½.h± NŒr¬Ã®â@EnR�©„cWpÁqœd¸u ‡øÑ%ÜŽmDö"Û.¦Ú; }}Ê_ÇÔê0èL38¥äwï BÛo|PÈ.£ˆq´aU)³&Ô'¨•dD®C.¦|ëçž§š7\1ša¿]�dT±=ŒJ3Øk´s¨w#ˆ䊸Ð-•üŽÊOKaUÝjkÁ»jÍÍŸ¹ˆTò¯bðªh“וe2ùfbaP¥XôBšŸ,Ú‡ï¶yË‚ÔÀœ3dm‰«ôv?“þÀ³i©NSš§K*pÖ=luÊ•Œáõ&„|Èá,¹±ÿŠÇVqdÙX"êülý{²#‹Ãœ¸ž$ÜéD&ƒ\Hïˆ;QÄß=L�Ö¥K¢E}°¶“®¾&Êxkª¢9%pF²”ã,eÉpt9OõJ°H¼0ÑÆJO$2�/#¸iÔ;ÝYk5ÎÉÿï¶*°Ýø7ßD>ÝÑÉ13ÓÚŒLjªqÂÜ#èX&r‘—Ó¢ùÐ.(: ‹UB‘7õG‹Eœ„,R%' oLðö�¹éfò-³N ù‘{4'"¨Ä5-¹†(·�Ç$y|Çî¢À\%ƒ|—Pt¿­» L,OrzHÇ2=Õ$u9r5ôâD·�Îâžú¯YF¢ÖšÅ4MYjõiVÇÆ L-òàVE³">«ñzÌÇ$ϰo¾—f‘:9fŠëî±µ‰€·gÄf<èžðAÔCB>š çú3Xt�8Í* ¬ÆYA-ˆÊ¸ß©ðÊ©–]‰EO¹ �FBÝhÑë\Ël¥ù÷ÚI°· ušG¯áÔÿ•½~tO‚céB¿[,,3-L)&F\%yÖ}ë£bXN R¦¨áJ©�Dp£HcV5‡„ìç¾Å.iÿ� ¢5Q£�ªè§¿;"äN›O›wmZ$L�b=âÑ5pì¡Ò‘㮡ö-eX”bðŒàÆ¢ˆL¦ ’e¢Û§Xp&?–· ]\2¶ aõ ¨—í3‚¿² ³§¤‰²q9¶ß9²Ž?¸”ÔQ»iS^„ÌÍ‘³Åk. ƒöhVsYï"+ÉŒ„¸3c´¾ãyDzþå�YNV³T’¢‰qlËq@eŽ9�^+2aÝ�¢/"t3á ¡.p_6%< ø{Flš) mj‰w}½™àB­¢W,ÈÄ5U‰bñ�¨Æê«âØ rœ®æ‘G‘‚Oˆû©w4º€i°+�˜Sâ„Dî—©r8ËËFÚZ‘oæ“úUÅ|„[–Fñ »ð*u" ÍŠ æM3§…‹þä&º9_²#éÑ6%l‚tÁI:îEœ~!g J„¿fƒ-Q-Üô~Qm¡'iM©‰±b R…J½ øßŒÙ6Óú®ýœ7/t¤)ε =)¤J6›g\è�GóZ)µÔ¶·g½ÐÓšÙš�|aQÈ>$Vw|w’ÃëA¼‹Ù߬8úOŠ9Á±MuŒtŠ“n\èÆ.o5ÊðTDöÑq�&DZ�—‚8Å4}IØô7B{ºñt ~—Ð�( ¦—ØZöcyDZ8y²™OË:2ò®€Õ§²œ˜�5U[Í”9#äËâ0kÎÃü4­â²¬'‰bâ âç´ÐÒ/ää�°¿¢:bTÙj­U]V�JüÇ ËóPùÞ"ëi¿IØ8q˜vvK�œL2µÝÛÞG§÷yr–uÉàN pÝumLMH±•_\>ßC~hµÀMÖ²ÓŠÎǹ¨òŠ1Á“‡Ès£6ßã±gkÆfIªó†Èí°ÏrBh:(d¶2’áYç1±¨¨ZÍw]¶TÍ*ñÕUlR¦‹]¨œŠXíµJ…âDCâÑ#ên&ü"§Ÿ/eÝ©-.±ÔÜcvcU)¡—Mû„<›}�fßiÍ“U�‰På5¹ì5ó*EHê•Ø2‰q‰ÄãÔ¼Ãê›iâØCyzÅ ÷ð.²6új)â;F¾x‚&™À¿¦'a8’£ Îzª¿Œ#ó‘Ù`°ã#ÉBO³MKbsÿ«‚’*ªä©^…\ž-iJ×Tzº©eaRÚÜ:Ý¸èÆ“ˆÝ“ Ã:ý³ûlxã¨t40°ÿE!{瘅ÒÙ`˜èr²}ï„b1ÙíÒ D9Xl”NNJu¼gDsdõµerK;øÄcLØ‚ý#BnlžŽ¯�!…ƒº;„éI¬”xÈ‘_—fzGž#c9D2LH/yï{X÷çû`ïlž§â ÒĪ-G̈àÎÄägÅå´lÃ|»@·_D¬%ªÁ[…±ÚBÇ1òòFÅTµa "Œ&Ÿrdᣡ¤ê3·êñ­˜öÛnF¦Zn^`ã‡'Ù‚ˆß�¤)µÌÔ°-|H2å¡Ô®�dCl*…©©€c’§åëóã%Ed,¿»¬j"É#†`õz>&Í{ÈôŽà¦Ó®†ZmÒŒá õÛ£»Là¿Ãº. |º5c«V©áÖe¤ê8)�#°£ª1,K†Uáòñ®ÄýSôޏ)þ0S�ÔƒL:µì GøÄŠI¦Ÿ!¯÷M]BKy›Çt5/¾-�•FpÉϸ†zÕ(âÅ2j<ÇŠÿy‚¿øÑÏ%ÏeÏ2‡w‘M… �¹‡„|8� :™wNâ]€¼Ã–o›¨¾ÐŸfÑÓÊBe*0+踬ˆŒæÉØCÞ•Â…S·4ÝìvKB‚šü>]µOdÜöYƧÅI ØÜ†þûWãj*� ÖÜæWœú”Ð"Bî¦EDxå·å9u¢•5x]–’ÈðŠA-X9÷”µ*””5eÉ!ÒNuaò¶!­Àìº÷e{o+#™íHS’£k* p8Û…´t3×~)’¿Ƀœ×‚üv3寵!ó9,gZja]*©àbhZ1䎉ϓå—}jJh™ÚÉ ‡³i5àHh'þ¡íCB+¹Õk«xD1zÕdX–,«F<ò'oÚØh«”•r9µ¹šß™^�H¦¿?Ù¹bé‰"(ËM—Ô<´/ß…loFî´J¦+‚ž³Ñe½hà”àí9ƒóã÷ E¿†?àXþ!!ò$ÍŸ8BÇA¡­�äl� |‚ÍéIâæ›È ÙA’k¥zs†™Š=ªÆ‰€Äi‹UP+[ùU÷�ó >½RÎ!¦‰x€L¯Gz¼!Á»-µb‰�Ú(@ I}y­‚NDmýÃ4ë7 ö”Öõ©Oéý>»°ç ÌÄ:å$T©PˆD°h­©kŸU!eŸ¹Ÿ¼¹�{;š‡wØÚÿ^7ÝÐIsbûŽå…ˆË‹ß»>Dš.`ÿ¿�_Šq\ÇFþS´Z]ývQ`µšå=V*ÍÈ×ù£3m!–)ÝðD„ýBó½ Úv3²¨¿#Ñ$BS¢ö«Ï$,²©{˜n�©ð¯]èîˆf&m>8 žÛêq$Õyˆn¿‡Ì•7b.SoÊ�âƒ7UhmC7ŧÎLªb…B){ì ?-8â;±-3ãºHv…‘ÿ±›ÉŸ:äï®°<q×¢ÑJió¤ ÄšŽyjÑ;Æ•A™ý/€SV9ºÍáâu«\Ьù91lsyY!Rà࢖ qNáÆ"ÊÁ7 ªŠÕÀÓ.Ή.0Ãa3F<°2EßÂÖ£@™ò,¬lZ Ê7ZÅTQx‘à¸D1¸ÊàfFÛX#Umˆ[Oê¯}�;Žì㮿ýÚ™Óܱ 4Jb;0–×®XD+Bcó }ZJ¡RqyÍ» �sì}y~á¥/QetKD¼âà(å˜u³±zÇ{ùåS_g¼ E�«\aº²²¦ý»§(õtéJQ¡Õ"HÇL T�Aùô+P¿^ V/Ú¬ãàËcºoŒ¸ÄqpUlÖ{£c%ƱE.1àZ)”«ˆV•"çV18ÜÚŸýéyß\¹õUß¿çÆñˆiâÂÐå)${Q’÷5µšsI«ç^¯a”"ê\-̱ðÆ|–Ô ¾w—~»ôF¨n•ÔÓ×õü¬¬«UŸuDŽ&_6R ˆ<ˆDžÈôù�sïßñw§~ý‹˜_Ü[ˆ (,×½ˆˆbP ›–Ô‘þn�ytÙÛ¿[áþ×±´^á<%]#ã�´FI€ˆ(XÅÁ¸U~3ŸýÀBÞS+ ™DIR ¿x]SIÄB`@ÝCh.™F¼ ª£¡/”¨W-à,-&ð|Pã(Õ“üŸ^™ø¿kÃBËÈ š¶Ž�aL¼÷eÛ‘>ôx+ýÒÁG^ÇeÙx§O¼ßeE|Ähâ²Nu³Ÿ×kÞ êG)]ŽíÑÓ$:ã‘�âê¿_`½üÃ05„|A±U]MÖÂKÎr}�up™¼]ZÖD&�‰}Åß­à}tï“÷hþË„ÃÎÓä÷Ç0kqáé3yK°Õ*ÃIDATI´Ö“E<ù;ÖÇï£EÞÈ›¤ƒËz˜j9�Óço¥òJ.‘~Úd¾<Ž:!Æ8Ä$h¿,?‰¾°äò±{A¶q�duZh9,´'Ui¹Ú‰!ñ놅–}B¾“ÃY:‹Yº¤…mÒJ—l yå5ÑçNŸõø¹¬š«&KTÄ­¾šni§[ÚùYÇ@$ñɰ[‚Ô5¼ë.Ö‰ÐôÀiZ†È‹M°ÿ&G÷ò+È~ø°ËDÅcV4‘­ywíaÖ7‰ÄÕ’½^B›×^�Hbɱ"-˜l"*Ð~ú|†%à:É<€´| é`—´ó'žÏ/Èëq¢/øœL�¥\?MÔù­Õ]›X…e±u¦¬XŸê*Žì£cå BigÛLëÏ1ßq)’§k*(ž én¡uÍQý9\õ µÌUã•~¦DÈÝ?�ÜR‚ÒÎBŒúâK]þb0r}…ã³Ûð‚vV^ÙâÆ/Ñè*U¥ð”†jUEÞ¿zWù?Д,# ”älY½ª&»­“|Âß­ÊE¯xO\tˆqL¡G™ï¿ïàÔ?þˆà-/+.Ãåt:€Ï%\ÆcÿðO¹ê[]kõÕƒYø‹å·o„ï½’Þ³úÚÖ­n6à WSŽ.ÄUŽR‘A”-±ïq�ã«ÈS Î@—Ç¡¹¢�–js·GeÄ…Y)Óâ8塪âe9:¯9 ÏÊßÿtà†S¼iOf•è&¿ôºã¬nÚ„*©Â )0(H˜=‰ÊįÚú߯Vñäï‹Ú`PMp·Q½(ðxe¤Ù”-«œsÝOVÜHXv"«jž æØJÌÊã8‹GP�h² _cþ÷áŠQúGoRCŒÅ‹Ê^š@ÃöÞŠþ1æúq�W¡Ù=­ùrgžwò›nyÿͺ6 ±>éà5�øö¥4¢EIFY(A5Éíy¸8Ê'ÆaUæÙ³$™÷¼™©Ì¼ðŠ�öʵ/¯àËb«?u å®&¢m¸òó.4Ç<•°¶ƒA”µ¶9¢’{âqcaÎE¾ â8,鈙9²wåPÇ«TÏû.Ñü¢+3yCæÁ÷� ?éGÄÛ KÿgV†=9¥ º–= ¿G34&PÒ�ºêõŠ?ÿbßrÊPQèÀ ÐF£—p«ÒàúºDgó8gÛÊ(\%d•IÄ|„c‚B|\É)G cåKøÜ—ô*s|´K®eÊégpÕ~Ë€�%Ù�7ï+e¸ 𕼿4ÿt¬7[ž:õÛ^ÇksËô°Lv»’îÉH½»#/ÿùTùÖ2ï{ÍŸö8Qåmšìë�ç.t4ÛhÁh‹\ÌÇc‘OJ´C`01íà‰C…*?1U~°€ÿð 6U?Ï»×�÷¾÷4Ov¬òéÏf¸àó+—†—¯û'œÝ_`Q " ¥”zh� ^ކÅ+Yjâ«!<þ‡ŠM•–›"æ«x(¢¬:ÖR9«ñ3ÎiÁ‰=$9Õ âÐ(Œbá©Öý?Ñu¼õâ—(ï±Ê¢ Ôà : ‹RP¢òÇÀß g®W¢>0¬ôÍ1Îí×H•+fóùѸ=fî CµCÑ´Pf:ÂÅ%n‹‘|woÿ壷�FGQCl—æm¥(µ ¾Á—ìÊÛ¸ðêÝŸgŽ*>;Ÿ¡sÂЭ Ÿ9¹x=*;4Éêû¢ß{à­~à.ÏMÿŠƒS(#—N^$D‚ÄÄ¢qÐ&¦ê N¸>J Áðâ»éxÉWøðï>ÌNbÃÐALÿåï+|xDF-ÿeˆ_*¡U`É×DP?à (Š}êµ}ÅO´Ám`ùD³/fÐtBËäZ(ú³m³×ÍküáQäüÑClÄs.æÎFÌ«AÞúææ {F£ø²å+ET,"ðio€ÉÊñû6_ŠÐ,æZx]1=çáp+š…¶¥_ã×O±-p‰+³2C›šì4fi?´ÕÌ\ŒÃú åÍ\'\>ó-°¡u~´â^²¸¹ú£M“š/¨ò†o~îÛ¿yÕ;�êóØ’ËA´È�ƒVüx‰óô2Óñ¼ØðŽp¨rhkè¶Ä>€1JµæÔì <‡9Gó²[^£˜Ãea31«h3ó þ埾Â8œÊ.ÑQþ&¬Pš4j¨ÆçÜæ’Ÿí‰¿~XP‡‘l'·€¼_&?C®{šÅäñÞyÕn¤¢^´7è¿åjgèÌ ø3À‹J…%úŠfLÔÙk¬ŸEë)aè E1( þ!à'GÑGÏ…Ý=ÂàX,¥TFoôΧ?Нd‘¾1�ôTAå¹ áMR†qýó¼èÂÇx÷ÿµ9ûyä+ßØÝ©ÌǧÑÓLJ"zúÍž‹”wÝA*(ñÙ j‡=ÇEI‰bu+__jã¾}]¨';ˆŽ_‚›–ÈU  ¥íËš“{¾Ûuà ç¶.ËÓõ«×÷TÂÛÇԃчxoþ÷ør¥‹÷™éî|�ØïÛ­ºˆ4cï�È¢JÛí¹2%š(1¡ lû³¨úÀ+Š*ß<ÌÆ—¿)æYžFþ±“³Ú¨¯íÃíº�ê[{ɵ}ƒøÎ«X-"±R()*M¹æµ´Þuo8êEo+%Ûd’'ÔyÒ—;æ‡%–¦ïÇLJq;¨Fð›ï'Þô;²2Èz@FMŸº/¸!|UõŠPâ^p@�1àa”¾e�П…LÛ,Œ·±ô‘«Ñ×~§¼…xf�ødzÃÂÊ0÷ö°5d”�^c…£z7£¹'ÇñzX¾ä˜™I¤Ø “ôHï踼µ'8ŠÓ¿…Ì¡ üÓ«¬ÐÃò%L_Ÿ=8Œ�¡Ü'J˜Rß}þ:‰ Ÿ+Áǫ̂&€m׳x6ý¯JVxFÑÌô3·Ì8_4=ãOº¨îw³ ¨wBõ¯T�Ü.(¦vÄ=`únÁ½öq^õ„¾¢ô¬!�{žZAâ]*á,ƒÙ1ê|…¯ÒK¾ö­°õ:àsrÆÃ)ö3àn=±D~7f~ΉP©¯†¢'zx2/ÝÞœOußwhÛÕÎR_ÏÑøÒ—ªìuYQ/ºÑö;Ô6~͇¯W`ÐŒì =E(lžˆø¯�åÃ7>Äfª`„WŒG\°êðT&&×ã°wt…‘¿JzSŒÿ¨�£+w_©Ì‹ú†½¯ÓQþ!7Æ6;v÷Éu%bx•¥òéÁ#‘hµ5ÕÛ±‘Ü>¡ #Þ^ «JÁÈ"¬äYi„à—4P—>Ƕ«H xc§�©˜¨4(¢Âë½N>âöõI¥8¦œ›®d¡tï„úÎŽ’ûþ½‡¸ŸË�V:ã >·.à´7c ¼Iˆ;¬Š»š¡ Fôêsî——é¶Ì0›¹<8ί.'¡gÕÍ€À§íûOb膙6Ì�ŸÃ9ÿ|⣷ @x!îm—P&,Ê$£Ñ^îtº¹1çƒîÃa¼Êïì¡zê2Ç.ayfÒ>Sß$Œž— ½Hæ’ͪ};•�™½èBJ¯´2¡zG·;ëÅ H——ûyÄ©pȹƒÀë¶­ƒ”Âî¹6)ŠÔN*‹jûÙ¦’ wzÕÙi­^mÈMpÛJ‘÷€þCP'BeCá¯Eå*ûp}ƒÓÕÆbi:ÉC=Oí♥iŒßI”M$‡² ã²-Y’Ë%æNÆUÄvÉÓÍJwQ9“·t:ì|O™[¼p«jn•—ƒQ…å¾Â.Ÿ«;¥ÿìx!ê%mÄÿp‚ÜŸü¹ÌòÚ¾h¤·”m߀¼ô³÷jÞõê•J6ïÅ=¶ƒhœÉÛ{\úÇVR¤n‘>µ�¢3±Me ¢úäKh½ðˆi–™A&3”–™]šÈsÑ�½T~ó#8cã² ƒ\Á€îŠJîê ¶p}õ ÆLAHÈ1-Ée±ˆîëCŠÅTj«ÿÿþ#þµ×²º*j{èÒ7»ÿÿ¥“ÿw­µO2WA¥DŸ�"ÛÁ¡`i·‹¯Áûà¯P¾egç®Dpa}ê½óhµMV(MÝP¸ÌNÒ+Ædà·”ß×O´0Cf};t�¹÷¼ÍYâ®.ª3àµO²:¸]Œµäî<ȨtóiÙ^,9Ý«B¯FMI‰ Á™,öÅô•Ì;n"÷Ç7SÝNÙñ ݉Cèõ[‘÷)̘ÔÀHŠôRP£”„BŠƒ2Dèüø-£xM?O|Û†‘èÕéº]%M�¹üŸ>/x•ÉåîB�}óÀÜ®.™?»°æDý nXÁ!'w’»ï0Ù�÷‘µäŒ6lßoé•‚�^wñnD‚Ó¶€&óø ­2EK±ÁórL(‚j4XI]uZù”ÔÓ[rÆî —Ý —g»Ÿ]‡³lš­x‚¦ÞV˜‘°× “RàkHÛØ­§…Š>Å‚s��Û/4S‡-9¤ÇÒbÝFS*J!I…ZȈ+ˆs�ƒ ñŽXŠë9¡}ØR[{;éÌ»ƒüþDâ¨ø!Z“V¿íÅFÀH�n?…¾&PÇZucR3í ¡ž&¢õˆ�Û3BfÈ‚‚ÈEÎâB‚"Ĥï¶¢#{,™ÉDx·¥±$˜î”Ðrò$Íì;–GF\z†<Š¡Ÿ„˜a(!‚øÞ£¬¡éäIš§¦ì¿“ºH§•‰N`Âui⤰׋Úo"þ†ôž2–JÔ„Xá Á¯XIl]+?MjÖS˜è!'‘¡Móì8÷ºBÑ—^Ü©)ZŽ žœeÝÄMÇŽ‘O+$ÇÆ,aÊY P$¥³ ¥´ÏHF‡%‹HŽc—æ‘-¹«„üÖ2ÈHÆr¤ý„ëÜEÄel(-K={%˃Ë*Ÿ¦—­ºj¨!Î$•FÍ�H*AôQaÃô<ëëx|ËÚ!BÇQaƒÅ•�yb7;÷äIËÿ�ô¼Ð1'´×úclÈ«-vÁ·o–_¾Vùf1Ñk®!Á æœÚçcâu[F’lïA2–­vÌ«�ÅÔŽàKBÇÂ&›ÿÉ$꯵«[ðwØrËìN!‹ôº�ÏÐ�zζÿòi)ilq±ï’¢é’ûí�þßOø×3 Gr�ՔƼðÏLÖúgéçLˆ�ôxw ­÷ Íû|‰ný爛r¤œîû„üÆ™µ (ÙÈÖæ£æjÓ±!qû…\(4…BÝ~ZÖ�nbH¨»“1zú|x¶W?âu3aÇ‘^7a�õFö�aM¾Ý˜Ý"ä~ál@®Êó@h‰k`’d b)yjpÒçy¡� y…z‡)+F!)ÅnºÐ›juü ˜ VZ˜Ò]×kˆÛ§çY?�ø ™…2âžÃ‚[[òY›¸ÖÐØïéñB¡)-²8‰‘5ï»ö§ÅRØ¿û_¬hÒ(SöŒ ýé‹Ï¾kºÐ»?탴¬Ü’dœúÆóܯô”ÑßoC’“I«$ȼt£RBÁù÷¾ÏÝÛ¤TžžÆ�éD?¦ «Ã|Üû\ak5Ü®ÔФAŸØËÒ¯.D¶8c\†—= :›û¶‹ÃWGãÞÑ^F@QcϸI¸qÔáåÖW�|gÑäøEm)£®ˆ Gõ©÷¬®u†Éiâî>1£¡¢÷½dg;pÚ`˜ÆL^!€îzÙ¡IØ£4?@¸ÃøXòQ�@ŸÐ[RÇ¿B­ŽòôiÔÊ &ûÑD_!î£(2¬<ÚÐäÑ,aø2†[{c¸A R00J÷ÄúX7jf¡„ CK^0<Õç¶eÐç�¬b+È=…\y»˜B-u3žüì¡Þ?=0ž•‹Î@hi¥'éQÝ ô(xŠ·àqš+¥QY3Gìs�'ta=ª›q /“ÎWàd.Awf1<ˆ”ÂB E&AmµÎÖ;°½XržüÔÕ¿73ÚkŽSYÇAëÔI�+– ¨„‚}ÁPiF1Œ„Þ’*�dCXR+oǹð‡H÷$Œ‚9¤ÐSÒ¼ Í‘ÁØ1?ÞL¼ð¢é‰O†ûNÅ}}öó^D�‚�’žês+ÛÓçU4+;5‹8 -<ç¦n(M?t�ì8à9ƒç¯Cs%T?ùer½¿•dàRx¦º€Ü ¡é‹ßa ,ìуS ¸VjHžWÿ\¬d“Ý%‹§†�îÅ Ø_î qS±…�·˜HûJB)B&… ¦(¶9¡=õS¢„Ú=*¨y@cŸ¬%îÏÖNBÓ!—Ƭ5±è$I)„’gMïQ+m�°øã!I!,‰YŠŽ“„ܳN?ÔˆF\K¸Y#Ãø·¿ä;m¿J½ß‚‰:L³áxœB¡û³.�mû#é×¹ãšãµEÁMH�:9u!Ž$©¯JBP’5J db¿/…�¦cX?5„)‡@SÕK}yRlyƒ"u’P- PÒÆ¿I¥¡BzR’Ÿ-[}6ׄàwÉrŸ~˜uG… ‡…vIäΤžZ`ã—oå¼"âLPô0Ì9Hf_eL�ïsB{ºš“ üšv×Y=Îö Å¿êÇã¢O±àìØ*ž )œHüÃÚ6ÔõãóÈš#æÓ�{)1EïH]ï õHÂøš^uæ×µJ(5Xf]#»¾I$zaõ¿oôEe­Šf–.┸¡6yíw«µ‹0LшõÉ›ðŒ§ ñlû¿î5l(5˜ìÚßMˆÅÂ?$äÓÏ)ˆSwŸÉ j¸_ꢬ¹´äÄWm!$êµ’mk›OM�TÔw„uc3´Žœ Éúö½îÚ¸ÊÓŽÿ鳦nTº€“÷«m阈ðôøP:5>ü³¹,># ú I+2â2ü@ aØÔ#xéHbµÚÊ âžI"Ì"dúéñÒNœÚ„ '„¦ú®&êßsQ?Óõõý4ßw8E'>»3t„\ñM÷ ͵@�RŸ¹>`5zb+Ã\;!$”nÁß™ˆÕ§PÌô¤Óèß­ÝÕë>Þ„$Ö¢Á_jŒâ>£Øp:¨/˜pͯ¡ªMðt¡Ûû׬Yb='˜¹c–Éælº=‰¬ÁQS›à’nHÉ)'¼¨ýMm[†œÆEnýÛÆøF}#Ø!»K¶±¦_6ÆÔBÛþh<9¥Ñz}·ÐúÀiK„º[,­Wݤó{díBO�:"™TxdLð†§,AK#±FíjŒˆ'›ÂÁùãç¾Ð“ ægö7'‹ÞgX†% ÜÞ”žp]Ò‚‹×±ÿÌ/¹dòKd—+,ci™c‰ˆ\„„Ó/ê§Œäβ„ïl[ Ë9¢äÅ—­Ç8y®˜XµLl Œ%ßpD² ×Gf‰£Ô.±*hÊ‘!H\ì2&`YgÉ%µÃgÄ¡EÍÅà<�=°Ü!Œƒ¤�üZ˜CC,ø(f£$÷™Ü§‚P&yÖ†ßc©ˆí;¥ß]NÿB9:½o pÊBܳLïm›JªTsùY@Ÿ¡-4—“¾D;‚ƒåœwËå R›”ö>NYpPvN• ¤ý§Pq2Ï JRélKçÙ2˜ä¿•úp.¶¹ùeGrà@¬lßÛqŽSÑ�ÀÑkïo)›s Ž8öûIæNã|NpÖNMC)×8°ðY§ì˜ä>"åè 6–õ2¹ ¿œ|o ˆ�, X>»ä DßÁQ>²ZÆd3øËÕ“¿ÇØ£ï/\^±^X~_ÿÍû›*¿³© U¡"€T©j0ÊáBG¨ŠP£ªà$z[ƒwV�yöÍáŒØ~mÕ WEZâ¤àKѬ…HìU[æˆÂÕ¢Q9“q@±ÊѲ©À*n©&+JêÍÚ÷�=ƒ1F‹¯=´*¢Ñªl¹Ü”B«Æ§ª3(i£D'šeªbûPEv™è¤hÅÄ‚A0bRJ’·hl’Š›¤ßâŠ&ïX 5#¢c�ªÔðÛ– }U,”[ÙiZ Öâ±|Vý_õľ¾8–]¯u�2*Œ=ºêäÝç�Ø*Ý;¢ˆª±UÖòQ¸ª®è#Äx´$bf1BEcZ)|­ñÕŠÿSCì·*'e"V1U«�JFŒ‘àÄÇ€R “µ4¶U- �ˆ… ¤ªBÿžŽc:ÍÙ"D…2¨¸œü�1–.8§4y ˆB눑(£pPh­±ú˜Kõ¬6Z·ºb2dtDk*TV–œŽŸöùÓk— Þ�l?¬�ÞÂÒ¾ä®þš£É{U¼Тg ʱCWÕük,¸‚’³B9žkçÚ¹vM¨ ª` EÕ:ƒˆa\ —ýÙ²Lÿ%€&眢êűgT–Aªˆ“”ê‰Jhb|T£©y^OíçÚ¹v®”ã U ¢< LE)2««˜#é_¹¼ëÐ÷ùco¯ÿÁ»|6›a¶=fz#¼˜$‡="Gï«Ë *H%ó<Þϵsí?p \-‰*ÆÄ²ì¬d(g+Ò<ÎûÍà]€²ÒB±ô¨NÕ MÂÊcÍø¼ãd™“ Œ¢Š‚ûåíS°ðJkÙÿgƒvú¹v®�kÿ¾m.Ïj´æÉ–˜× |¡Šæ‰Ò"ò1<–ÿ|^ö¶Î¼‰ƒ§ûP¦qYP‹\¥écEYHq®Å"z[ÁJŤòÊ[‘Õçû]ϵsí?jSJ9¼²W_5*g èÿ´ý½7¼ý…:ÈN&,§ú¡921D#½‡¢íØ|ìFöêÂ.2û |VB_Ÿ˜ËQª <-¥t®�kçÚ¿oDÂ6,áõcKˆ7m@Ñ{÷¢sØ @¥è:‹Y°š]ô÷x`µŸx†b�:‰üó�`;w�»þ£^ݶ ϪòZY±‘÷iZ Zõ#Þí¨ˆ‚h^»×-ÜxuTDl•€R¦€è’Õˆ®EÛÇ,Y=–�ÿ\0î\;מ§&—…Ni\L�q=È‚ ÐëÀ¸)q™[(R¡/µÔjúTï J½µg3èÎihí$îFö˜„Á$ɧ H©¤œ¾> r.‘~®�kÏW;‚ò·(Yµ"¢B…H¢oíÂë5Û1€Ú ìC'ú�íÉÂíUKš+P…]bôù~×sí\ûÛ¶$zê%úR% �3 ¬]³()¢g ä5èèqG•˜# ¿WO¢„P¢J_(–xpÆB'ùüyÅ£ŸkçÚäv¨~àzD`”#\á,Aü"¤" g¡+"¢”2§ ˜ŽŽ$/~Æ{ ›DØ»Ÿ~‡s ü\;מ÷ö¦IÔQ€îQ�o™-`ìE*;iéü¼B&£m(«‰IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/folder-transfert.svg0000644000175000017500000001301515153325210027421 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/image_key_upgrader.png0000644000175000017500000000206514757047403027771 0ustar00paynopayno‰PNG  IHDR;0®¢sBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î<²IDATH‰í–ßO›UÆ?ô mi)¬um¶±Á¬ë %•UY†™&¸è¶,dñZÿ„ýzã½áÚ-±&&“ù#™]×7˜šÁ2�AÃêJ ¼­çûŽu�ŒîFŸä$ï9oÏyžóýñô…ÿ:‚‡½Þ/€†çƨiÚù÷/\È$†‡õ�þþ߀åä3N»½>l~7>n�ÅÜ Œ�R’?�Ãf;÷f8œ¹:8XHF"…�.]Z±X,o—‚K+žä66¦f¾Ýߨx¦ãÈk³×[}¬µõôèÍ›éõl6V2b€|>?=ûJ×õw‚>ŸÕÝÐ` wuõŒ%õkéôHɈËñ[·>M­­�íéì´×9–¾P¨}bròèÃTêK ° Ž2¶ u}§›œ§B¡dlhh=‰¢—/§>ß5 jÄõ@7p|{0¿ê÷_»råq2)L ezƒÁàØáþv”/›±¨É0•ò¼ØÒÚ¹ÅÅH4?ÐÛÝí­±Zm§Oœp-­¬\œ¾{÷3 ýÒ à ð‹œmRqµ¨¯j�,Ð&ÈÜô0•úþ‡7*ƒ>_G]mmõÉ`БÍåÞKLOωðý€hšeÞ.g6.à%ÀèðpT^:Q…`u.‰Ä>À™zôhbdtÔüJ[[K“ËUòûm–ªª¾±DâÊ%R‹À‚œ· ,ÉM·€$0¯É¢1âÀ0 ÌIge”·×s¹ÛßD£?òx·»rxd$?=3ã%J›À}캌 ‰ÀïF¸Í€¥(7•¢ùá¾¢y €¦io¹œÎà ªb?AQ�ü®ERU è¾gBð1ð!ºŠÞyùç¶k*÷Ìpý¨[îe{Åü/8„J¨? (¿¥Ä(çʈ€>Te/”?m×a—çeÀÄŒ+êöV™W ŒT�4¢*¶«ÛÄÎ"V.gÔ \l‰¢�'�?€³¨¢Ü' ¼ŒêíQù9%Ê{P&aEµâ¦ˆÝ’ ”su>TÅÛ�¯�ŒAÜl(‘—&T¯½\Å”´È¸Šj�VTUëBð8†2 v¹ÈçÀ�r�w�‰'ß\‚Êo§d¾,óET‘ S@'ª�·€U‰Ø*Ð Lþ-à ³r1›‘¯_Qö¸üT´veìÇ�yYŸî  Baf /‚<üõ«e�"vHïuwˆXƒøu‚[a;äÿãùàO Ãã ±Õ¶IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/namefilter.png0000644000175000017500000000403014757047403026266 0ustar00paynopayno‰PNG  IHDRJ>Œc�¦sBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î<•IDATxœíš}pTÕ‡Ÿw÷f³É&„`Ð4!1d¨E�ãX•PZ�¡#�¶3¢" ƒZ´E,…b±Ôb±ÓH™6Ø”©iÐÇŠX‡Je„ ED(>†„l²É~Ý·ìnÀ°�åc÷^;>3;sîÍ{Îýí/ç¼{ïy¯¨*veáÂWGõ®œ9sô-Vk1¬pååe«KKóûX-Àaµ€ QS³«ªÿ‚Üœœl[h´…ˆî,_^ß?//gJYYaŽÕZâØréååe¾^\ÜÛp8ìó´�’ÕÕ;ïÍÏ÷Ü\\OM*– Ša7£99YU%%¶ÈߟÃVFÕÕ}RuÍ5¹9¹]çDl1¡ì•£ŠŠ®ýNV–­$u‘´ª'ŸÉXRX¤¹=Åo�†%óB‹¯L–ýHʨ©�çýƘ“í¡ÇuÐÔ¨ÁûfdlûÛŠÐ?¯\Ðó%Ó‚qÿ¬ŒÛóò寋u´1ú¹…á�ÉèàG�Íw}%dâxChÝöíz&É®šÊ”4k®kÚÈ»dn2±¼g®~vAhQüظcŒLû=ÇÌ‹w»¬œ_ÑÚõ[¹øàr€h2Ĩrù¦""Ï®0*.•�ÉÄ·ù˜5|„üuû=6Kæ‰P`àdº¢‘Dq?ûuÆ+¥ƒp^hœª5'ŽáÝðšùV²×žò ±ì…W3Ì#ûùÔfF‰vÏI¿-œï¦Å×kõ~§ãŽÛ¾)…©PõÞ;ú–ÍŒú<Ïy±ÊóÇøºÿ½¢ MJ¶¸áÄ)Ȳú¼w3ãç^Èzžg= ã‡ÕÀã]ñ"Ù"Ò7�ma°xxþM“¯=šy�:w rg0¶u¢3º%ò¾ÀayZDÜéh£~|æ3š�3ÊÇñX¯i(Ê·XÒPQÔìÚ€ŸD¤"Õµ)7Ê4qˆÈ�"Ò@D†ˆH¿X{˜ˆ”)zŒ_òw0Ûlt5!ÂàSC©n}™O?Þ#"òÃXü`™¸ˆf}7P<ÿÈ}¡‚m›»ûyõH¹QgZèìfÄN힌µ×Ïð?.x 0’¡.ò÷õÁ{{#™êfݺZjcñw+�qÎezyÕ9»"ÌÑé™Z)ÿÕóxhÞ��š 싵gÞXû‰9Ã+_ÿ·­è«§ •Ñ/\Q1Ë\½ºêÎXL Ñ[„& ÈðNœäÌZZmä)úF)7Ê•IHUÿ?VÕ—Îi¿qN{ëæÍÍO‹Aqi.”FÏ÷ëWŒªn‹Åxol»€ÓÀ6àþ{¦9ë ƒ”mÛ%™_*aà0QUÇ«ê‰T_ÐV7œ"œ—`Dnø€›T?Τ[•,­Ú¦Í$ø,=Ûlïù�=‘°Y—ŠÁ;;Ôq:ùbÛú¾±ôÁJ 2Uxtò¥ö°Ç êÎ2G%bÍÊÈÏß\›šŠi[»yâÿƨº•ῤr|[%sÓTºçn»$s[eg¾4*IleT¢;slò3h+£€+(H¥ÛÕ�/“yBÎ'[̱¤î£F�•²IÓ3js{]¸Àç“ÝæžšžzåÒ¢ˆá«5Ö•�¤QÎÇG|Ë1<™Ø’2|ïÔŒº—V†Ö_™´(MMííeƒóÇ&��IWy¯62g‘ãé’�Îþ :x@¯ ‡Ô•ì ½{Ë™¾…ÒÚpÄäWO„{~Ú)Z7ojÚäñ¸Ê‹‹ÏnTª]·÷Ö¹÷\¸Qý�ÀkÉ긚_æ¼mÌǘT ¾k;M=‰ 6­™§ŽxtýÉyü(ÃM¿ÈàrmM…Îd°C2/zƒ†<úÝë]§_+yÉh÷e#r�ÏwÊ*‘Ö¥º ˜øÝǹ·ãøQòœ„±÷#@ˆÜMgç¾FJ)iÙ=‘[€` à†'Uõ ˆÜ4Ÿ�»s\î îCû$sô0¤Ý"`šøï¦CçÅH׌Z¼C´7ø7óm1PŸ{w/^uTÝYQ“€†ï?à#HÉî륒®ý¨W€ÝDߢ/eÄ ¢ˆ4[]M'�®Ç½H„>o¯u"($ 娞H‹Qªzî¬èälIU}x‘¬¬ºl^!ª„†Çøp'Y� ÙÀFDFYm–õÉÀí.ÖI8(å7ÓR»ž–Ú7Q‡³DԬ묔h½Q¹¹}� Ú'˜ß7¼i-êÉ¡ýëßÀÌt�'º\½@»•2­7 @õ$ÐúÑ¢UŸ… ¢¯az½>¿Óïÿ0‡j›uí`”ÏwŠ`p4¦9ÒW>$¯í57û� ºÃj“ÀF¨ëcGAŸ¯óc �‡=Œ:‹ªðûƒ–=×%ÂnFumÝuv,ÛRI„íŒ ‡Mg{{@§LºÓj-çblyÛ¬Þµƒ7z½tZ[`\RÛ}qTM3âòzÛΔ”döžFŒ?W†ÿnµˆ8á°œN--‡­ÖÒ[-½PÈTŸ¯s—ÕZºc+£üþ`PüþÀf«µtÇVF�<Ùüp81�N}Ýj-硪¶úÔÔì]nµ†DŸÿ^ `N˜ÊÝâIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/namefilter.svg0000644000175000017500000000725514757047403026315 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/notification.png0000644000175000017500000000505014757047403026631 0ustar00paynopayno‰PNG  IHDR€€Ã>aËsBIT|dˆ pHYs'_'_†ºjtEXtSoftwarewww.inkscape.org›î< ¥IDATxœí�{ŒUÇ?w·Û'}éVŠ ¶TÑÚ?PÐjEL DkLÄßÁ˜Æh4Ë’X£¢`Ä(I �ÏØ€bÄ€V(ÆG„hKwi·•¶Û²¶ûð�ß½¹3¿™ûì�ù�;÷÷I&7gæÜ¹ß9çwÏ9ó;/pÇqÇqÇqÇqÇqÇq KÉZ@†ô«�×”�3€þÈõÀ À³ùKs²fð$0Óàø�•@'[n¦qæÏÇ­†BŸµ€Œxq“ñŽfª¢ ˜e- #ÆRÂ>7EN®|–xQEùüRu~—‰º€(j°O…_RþNú€/Rͬ§�Μf(!r1Rr| ˜$iû�½À(ð8ð° ¸x30ÐàwÖ!™?ƒT ¯nRŸÓ€yÀÏ�„�nÖ‰? )ê‡�À8Íõ4:Æ�;�ó©ý¦t2â]œA<�¯lýq�(H½:ƒ±—׉»øò¾ß‰ ¯w<\ZCÇÄðf€Ç€Å­>´#”€" yxc�xƒÀ7‘^¼¬3^÷’ô$‚¸—ÿYŽs7]öšÊ«Ì`+Ò8»¸/%Îû�nÞ¥MÞóHÿ,Òésqý)ãåx‹‘âüLàµÀIuîyø0ðcu~5°)> |¹I�Òèªü£7¥\ï¾Jýçaà.à3À…¤ÿS›a ¬çf¤¡˜ö[SÀ§R¾{ Õ7Œ5mþ~Ï1©;g�LÖ ¿ =#&‘6ÃF·ÚÛa.°q¥ýþPÊw¶•¯í¤Ëª+†¨6 æ¨k%à6Òÿ×T;x²f)òÓt\­â.¦ê»øhNúº–A¤èž6¤\¿žd‚OÈK b3Rüëêàm*Þ&ª¾†fG&õ$_AJ7¨@ÞtbïÎÉM]:ï!éXÚ ¼LÅ»¯|íkyŠë&– ­ði`­º6é§�&òì3¿ÂGÝQ}÷¨8kC™NËS\·ðq$áîJ¹6D²è¿,7eÍ‘öVò^§Ò Ü–¯´î`’8—¨óK‘�›Ñ„ 1€‰ë|ޏ'ð4¤˜¢ù¾Œž`’`#$G%_GÃ:g6ÙtZu=ćrMÒÞ(`kî níŒ:îIÎ!žp±•Ó6Žº`æUÏSáûMTœ8÷_nf92)hÜ:ÇðSuN»º�¢#n¦ ×õÛ ˆW�ÛÊ Ÿ“‰'Ø“¶rN˜~’CÈ‚ž9d]è5Ý>_ ™?å| !Íš)å÷BâßÈþÃGE �ëIe~œøqA+™Ð,YtoÊàžNFÓç²0€§3¸g¯rÉøÏ‘Ñ^ Y´VßCZ¯iëþ'}Qè£ÈvìšCHB”iÒ•:†¼v~2åÚ$ð‚:*›=F™AÚ Ñì£À5¤×ÁãÈ3ižO¹÷$é‹aL”õ8Bïåû†¿ƒúþ�UçdέÄ3p[ ß]@Ò={Q§:Ù¢wñœ¢ù½{nQߥx XžÒáÍÈ1w²l!ùúu]v2�,Ñ¥À ÒÐ&¹>Á:ÄC©ã?EºÏén$Ý©2‰¼Výx¦Fœ)zkÄr!™üœÖ½n“Àû ô:Ð|�äxüZÇp™‰R'SÞ„lçV+ãÇ�ïèÎYÑ‹;ZžŽ¼×ŸŠLÑÞƒLOûâutÇqÇqÇqÇqÇqÇqÇqœnçÿZ\“]Ç7eBIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/notification.svg0000644000175000017500000001075314757047403026652 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/nxtomomill.png0000644000175000017500000020245714757047403026357 0ustar00paynopayno‰PNG  IHDR´8'Zi#±sBIT|dˆ pHYs°°œÔtEXtSoftwarewww.inkscape.org›î< IDATxœìÁ€�þ¯î €Ùƒ ÿ×FPUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU&ìùM IDATUUUUUUUUUUUUUUUUUUUUUUUUUUUa€ü_AUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU…=8òmUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUµ³ IDATUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUöà@ÈÿµTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU؃ ÿ×FPUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUª3< IDATUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUa€ü_AUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU…=8òmUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU/rôß IDATUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUöà@ÈÿµTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU؃ ÿ×FPUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUÙ!$I IDATUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUa€ü_AUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU…=8òmUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUÇbã— IDATUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUöà@ÈÿµTUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU؃ ÿ×FPUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU*zUT IDATUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUa€ü_AUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU…=8òmUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU ›#hLIDATUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUU•öà€@Ðÿ×ý`+‘玱OIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/nxtomomill.svg0000644000175000017500000003553114757047403026367 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/progress.svg0000644000175000017500000000472414757047403026031 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/reduced_darkflat_selector.png0000644000175000017500000012456214757047403031340 0ustar00paynopayno ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/reduced_darkflat_selector.svg0000644000175000017500000010715614757047403031353 0ustar00paynopayno ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/scanlist.svg0000644000175000017500000000547114757047403026005 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/scanselector.png0000644000175000017500000000266714757047403026643 0ustar00paynopayno‰PNG  IHDRK8µø…sBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î<4IDATxœí›[lU€¿v[Zh1•åV¨X.¶(K€B€A�òP‚}P$†ÔcÄ7C"1CZ^E$¢FKDÀ ‚´„"ÔK¹‰ôBh»m·;óû`‹´ì¶Ýv¦;[÷{›sæüóÏ—sΞ�3#ªJ4¸ßçy(!‘»ãš&u§JÍãvÇð:´;2ï•ñÛŠ½ .ó ²;ö—̦I“äRe¥^±;¶awÀž��ãÉsBÀêÇ=ÉS}ž¥NÄîwY£ÆÊ˜G $ÃÉklxÁȘšã�nwÜ~†)©ä–~¯µ¥?½N0hÍÊíŒ)=™à\`L˜•k+~?Þ#%æá†½Ö›ö=êYói/¾êÖ› ¸‰3§”cGÍÀ9YýMC¹¦\ÙmÞgwÜújØ\G5ðVoÚ»RÖ…-Á…þßuÖ�,±ìŒ›¤� Ë÷Š[¯z2Òö®“ÕP®)7ŽX¾N$z†LÛã_Ø4/™ÅÀüHÛºnÖ®Ü̶ÂP'DL|Ùë³öˆ¬Š´­«zVÓy\û�5ûî|ÃóësA[‡à-Mž ‰z^‹Žˆ|½HµÇk˜>Ëúc»9¥ú Óô¹+þ&ÕjÆ[]baG¼n˜xy0G÷“Úö5±ÌzŠ U¿ ՠϲÏhš˜œ¾Þãék¬(ÐaÞºXlšëõàŒ,€ÁÙb�}>&euàúgVkseøEºë&x7㪠¾'ÔÕ( õöÇ5zÐmbJ–iÂÙÓJV¶ý¢®VùËÂHê✘’UQ¦ÌÈ5Hjì´táä]‰]ü ÇÌœeYÐP¯Žˆj''ß�²tÉ W3=ë\¹ÒÒ §vnÏàb™òg"ãD$AU[;×;*«¢Lñ7Úss–ÉÉÐÒ윬›•jÝcP›·ÄX¾`iÇ•PM�uÎQYþFÅ77fF:Oa,AÆð•Fnçº5óZ%vîÄÄeE@\VÄeE@\VÄeE@\VÄeE@\VØ*«¥îsfŸÁ Ø"+hÁÞ·Mò²œ-¸²úôß0DVè¨=¿X Mû-D`ýƘ–^ËÚ¹ÍÌ~¿ØÌ¯¾¦iíe3|¸L§w°¢GIJÞ}ÓœüÎ3ÿê%ݹ®`ÃÀíU�¬�ß3ǽf.©úMÇ…ªO)¬{ú.KDf§eSýM¦tu^á&±¿sØ5a Edºˆ| ”v'Ê#°nÃÀ_²ÝѳDd8°( ‡K‹¹cÄ9Zx¿ !CUk€­À³ÀW@·½WeáìÛ´.!dÏQÕ*UÝ¥ª«�E@U¸)PíK·÷ =·Ò“aV4…«Ì�ãweÕ‘.e‰È nMð×;�Òü0œp"17vé " À`N[Q)ð(ðоkûI:ø[ob4VÜ9µµ\…@ut>¤ê Péêº�²DD€€mE瀕ªZ-"…Àm廀9µ‡-óxNàŽ¡zy²xF­óÄÔ(43\]È/,Dd'°¹íð20_U«n«? T5§« ?ñŒ·pûnïÄ^eí2ÖÌk=j�õ ÿ‰ª–ß.ª�½@�Ãù¹Ž²Dd#°­íЬVÕ3!Ú}Üp87×qK–ˆ<Æ¿s@X«ª?…j¤ªû!7×aˆÈb`_Û±OªjI4s#†ˆø€Ï�ö/K·¨êGQÌɵÀ@jÛñ몺#Šù¸/°8”«êKQÎÇÕˆª"")@“ª†]�õ†i3=¹IIŒ°3f´ðû­Š¸ý®ƒ·|½IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/scanselector.svg0000644000175000017500000000412114757047403026641 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/single_tomo_obj.png0000644000175000017500000000053714757047403027321 0ustar00paynopayno‰PNG  IHDR')BuþsBIT|dˆ pHYs°°œÔtEXtSoftwarewww.inkscape.org›î<ÜIDATX…c`äFJ ˆMgÍ0´øïCª¾ß?7®þÓrl/Ãq\jX(s«�3C–w(³.9šß½e`<¶÷�.yŠgjÃTþéãñµ‹ÿ¾$G?Ëc#æ˜+çþ.Á&�­ÉùÌ˵ yɱˆàê…ÿŸçNü 㣄œ±“–_“ý�›Vü»4wâ_8Ÿi B u¹`Ôqä‚QÇ‘ FG.u¹`Ôqä‚QÇ‘ FG.u¹¥qöÄ¿k?~ü image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/time.png0000644000175000017500000000707114757047403025106 0ustar00paynopayno‰PNG  IHDRŽŽçý0sBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î< ¶IDATxœí�{tÕ‡3’ðL@yˆòDDAyˆDÀ‚Ç£H�l *§D,Q"¶€‰z äh5Á#%€šêQÞ V¬Øè‰‚yí.y�l o’ÝìÎÜþ±›t%ÉÎìdvçÞå~‘áÎ�ß�|™Ç�¹wB8�Àa.G\Ž&¸8Mpq8šàâp4ÁÅáh‚‹Ãч£ .G\Ž&¸8Mpq8šàâp4ÁÅáh‚‹Ãч£ .G\Ž&¸8Mpq8šàâp4ÁÅáh‚‹Ãч£‰0£´EÝ�‰½DICÒÛè,F ¡L6™Îw¹gµÍè,­!P7øçMá �‘¯�ÕàGDY€�Ø1Üþ2F¼Òhto¨ûÅÔ;"’ÈP˜ÍD²¦Þ‘dt�ë¡êˆS÷ý¶;EQþ €`tÊ ²,ÞÕå¾5ŒÒUÕ¢ M—¦5Ͼ¡ªÄÄp£Ð ]û†.qùÖèÔBÙ¾¡JœÇW}ñCIyí)£sÐFIyí©ÇW}ñƒÑ9¼¡J«ÕzÓò„/ß)*­ùÊè,´PTZóÕò„/ß±Z­7�Ūîªî0`° a#`ÉÌ{n;²ï°¨®áÑÞe¢zÝ>¡CÇnƒŒIœ 5æj[Þ7Þ˪k«¾Ë.Éyïð�y×Ï¿X­Æ$l U=ÇN“éš ¹ÿýÞáóšvš7›ÿº¹Wï>½CJœ²Ò°‚ ùdŸ¯2N“éZ°ò¨�ªSÕ€®°�ƒBìž}C T‰sâÄ W˜Ëž%’ÔV—äêÌLÁÀW›A’Â\ö¬'N¸‚™I ªNUðKqñ•>}úœî9ŒÑ„ïÿ7‰‚f2*^@0‰‚(ˆò¯Å Ä!Uµv{Nii)U§)€²‹c5TWUˆŠŽšmt=©®ªÎˆŠŽšct êTÅa.G\Ž&¸8MPwW¥‘•Êüt1UµÁˆ£H�许køŸeÔ´‰6˜G’¤¥2ÇÎ|‡ãgþŒ8ŠL�4NQ5m¢ æNUõõõEJeúöéŒ(ª¸õå,jÚD̉c++ËW*ÓÿVzF ¸íÅ2jÚD̉“õ߬>¯gôÝw s§ŽÁˆã“.�;bÔÈ¡ŠåÔ´‰6˜g׎äK’$Õù*Þ! “¸7X‘Ú$fühtó})IRݮɗ‚I7˜§¦¶Öi+³U*÷䣓aÜkº‘áxò±ÉŠåle¶£5µµÎ DÒæÄì§OŸÊT*wKï›û̬`Dj•¥ÏÌTu‘~úô©L�°÷* sâÈDhX¿.Ëáp(Þ‰L›<S&ÞŒX¿bÊÄûððäñŠåGÑúøuY2øíx éhïh«ÅªxÔ€¸Øyˆ?*°¡¼ˆ¹âbç©*ÛÔ†¦6±sâdÛ²eu{÷ìùD–eÅ¿T“É„UË`êƒcžmêƒc±ê…0™”ß’e¹aïž=Ÿ¨ó´‰)˜@„«32l/\HQS\E¬ˆ�‡G§n0ä£Ó&bEì<ˆ¢º]zñÂ…”ƒ6�ªWBÕ¤8$L¨ /Z¸0½¡¡AUˆ x~ñS˜9ý!ÝóÌœþž_üAÝè円†¼E ¦�=ma&ÅÉÏÏ—TUUVIo&&­v¹\ªwþ’ù30Ö#ºe™?ë,™?Cuy—ËUùfbÒêªÊ* @•§-ÌÁ¤8 {ñ簾íKK_)˲ê Ìù³Áb?~Ùm±ØO eY¶ïKK_ùnjjðÿ6°sï{3tР¡„ ü}ÇöûŸ1#IÅHµëvô,R>8 ÷� X¶hóãšI–eû¿23W½÷â9w¨É5›sýÚ0E0{ÄÙ%^@ॸÏ

ÅX2ÿ·èÔIÝuwccciâ¶7b“·o÷š]‚\Í·Z,,ߌxâ!„ä[­h>ʤ¦¤nNHˆUó@Æß;]:wj±<2"ÆŒT•ÃápmNHˆMMI)l^(àJ¾Õj!¡b BHÀ}äÉ3›­Aó5ľ´ôËëã×ÅÚív³Òú&“ Œ»»Åò1£îDx¸ò\v»Ý¼>~]ì¾´ôËMË[žÙl !g„˜8MäZÍ…€Ð|Š:|èPùÊqËêëës|­CÞÖbÙà�·*n³¾¾>g劸e‡*ÿÿR¡Ô�%ôIq ÏRP �’¦Ÿ�9RùêËWJ’äsæ‡ÑÝT-óF’¤k¯¾¼qåÑ#G¼}�w†Ð$dÅ€<‹å2Ðü0#ÃVR\ò©¯uztoEœîQ>·SR\òéÁŒŒæÓ#P˜g±\öµë„´8�o6Û  ¹—V–%Ÿï÷FFF´\¦ðîò¯êp)ßlf¾ŸF‰�òÌær�–Ùsæôì׿¿îsëôëßöì9sz D°ä™ÍåÊk°sC€µ’k-].W¢(Š-ï·½Ñp÷#Šb§×·ü-qkâ¿Ñš�5nˆ#€¾N‡……Ý¥TPë]³§îÓžm…<7‚8œ0<ÛîÙÖÀ lËPB]œap«]� Ýuƒ=ÛÖÞŠh&”Å ÷/°Ÿ_kéÓÁÛϳmuÏ)$TÅà$#§­èíÉ0ÆÀ #ʼnp €¦�fèüLé&O–=+¥�Pg€/øîêõAEFÁ�išþUG(‰3@&€ÎFi…Îpg›bt½q†8 @õ‡6 Üë‘pgô=! #„‚8&i¢• ª!ÀoÍDÃ�•ù�Q„‚8L0:„L€;3Ó°.ÎèüKÒ›zÀøm:ëâl€Îjƒô†g?ê°,ÎêÇ«ÐÇ`øB™eq^D@òí¥rî60 «âDx6y4³hGg¥‘°*ÎR]QqeUMËeÕ-—éD¸Û¬Š�k›k1’S>j±|Wê?Q` Ø€&¯ÓXœ§€jºÎ¹Ÿ•�ƒ­;þ�{ë“HtŒŒÀÚ¸Å=R÷×là>]15I6‹âLðo=+Ð¥MÁ䆧±Ñ‰¤wÒqî|¶rá6øüØ×¨¨ªÁª¨š�@æÄaîT%IR»>Ww­·în—4Mœ;Ÿ��[w£îšêi[¥½m2æÄq6:5¿sc»R�ø„�¸˜kÑ-ÏÅ\ âvÂv¥B¹p´§MFÁœ8’,iÊ\`-ÆÚMÉ(º¬ÿ°î¢Ë6¬Ý”¬¹¯Gk›Œ„¹À²,û�9+;ë_•Õ�û¤teu-Ö¿þ6²²§ài�–6 s�‰Lüº�9yö<^KJm³cOOì¼–”Š“gÏûµž¿m¢æîªQ¿“32�ãƒýŸ2N šúz®VVcöŒ©ªÖñ§M´Àœ8jhO�^ ¯‡*BN=úhôB羪`îÇzöÑè…^}=´AíCÎú¬-cŒÇuã¿å®#æFtîÑê³�³YÅ()Ü�S{èÛ³+bF·>{©ãZűöçý×-.ðm§Ññþ]i êÄ©ÏÚ`€¹Fg¡„ý–u_mtoh¼ÆáÒüš¦}¡îÓÂA‚ª#Žçôô�Ñ9(e,M§-Ú.Ž•¿ò~ãBÕ¾¡MœF£P Uû†6q¾F61�{ßPUâŒz:5·¤¼¶å0ƒœ’òÚ�F=�JÕ‡_©Gv:».Žÿx»µ¤ú}²Ñy(@¶–T¿¿8þãí²ÓÙÕè0ÞPuW5tàÀÞÂm0m �Mº}x�¨HMsù±NEµýêçgò.ûÆ\HQ®ÅR¦´^° KœÁƒ»™ 5:�¢�›[P°!¥þBÕ©ÊEH�Ø�ÎA`wRgto¨Çl6Ë1ƒ±Q�Æ ³{ßÐU§ª&úõëa2õ"Dè, ­÷T"8�\sH’­°°Ðetžë¡RýPuªâ°‡£ .G\Ž&¸8Mpq8šàâp4ÁÅáh‚‹Ãч£ .G\Ž&¸8Mpq8šàâp4ÁÅáh‚‹Ãч£ .G\Ž&¸8MüçY÷¤„ÂfdIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/tomoobjseries.png0000644000175000017500000000605414757047403027034 0ustar00paynopayno‰PNG  IHDRABc»ësBIT|dˆ pHYs°°œÔtEXtSoftwarewww.inkscape.org›î< ©IDATxœíœ{pœUÀç~›4}ÙB)Ø×ØViK“&ÙGB�µƒ00T�*"ã �A�q@AQfPF›‘‡<ä�l6É&iµ£¢S¤M ¥TÒ´Mö»Ç?î.Ùlw“ÝìnË8üf:ÉÞ{¿sÏžï>Î=ç¦Â! ÑаÄs'"“¦+ ²{EGÇɇBŸ@%„FÃáé5"Ç÷OAdS],öÓÌzëyVàÈôg�iªšÌ%«'ºOTð¼gö©>éèx»Üú–Õ½Áà Šê*TkAa60ʞțÖÚ§UdPaP` °7[ÞŸ—-›™Y¬=µ®î ŸòDn[‹½\.½ËjQ]ˆ1§§?«ê^Ùµ¡¥Å;§µÕO—/ïèØ\2®À™3g24C¤ÕÉ@�ˆ¬Ú½ÿ�eÕ»œÂ6´´x‹wìxLákísá‰��¼ábÙ N~ >拜mDþ¾¢££¬F˜ZZ¼x8|¶‚É®‹ƒ“+Ù·æxqñææñPè¢\úBÑ#¡»¾~–©ªºETƒsU]4Ú:‘ŽËI<ú…�“€ŽÉª—ßÙùf1Ïe¹x(´ÌxÞƒ¢Pk/Èõf&}MM³Q=.õ1¼WäÁÞ`ð„bdl„¾Hd©¨Þ#"GX‘˜M&/Ðb:,7ËÛÛ_ß34t¦Št¦ŠŽR‘{Ÿ­­=¢Pa¶ï¿ü@Eî\Ñѱ¶!ßYœÊ•áäDâ�—æÎ]k�¹ @Dî89‘x£"�ýyÙ²™]¡Ð™^&‘Hm±Ï3Ÿ/¾[leæçÀ�Ê-4¯³´ñ´Ó¦.™1cŸd89À€Ê­D�|˜3‘{"‘ŲwïκDbw®úœFP�ž��›{ŽŒƒßuvnOU훈"eà&àt…Bgªµ×Q]¾š«MN¡‰Hä\«–D®*¶ãw ÆÀ¹¦ˆÈiñpøS¹Ú0ÚNލNç¹ÿ+öûþÕ;vî|¡'ì6¤�Šf“ßm¨ˆ{éÆ €·€9ªZpîn æáB‡ ¼ä¼ú“‰€;(ª¾Pw€Y "{Ê Ä×pÑ¢CÉ€û h·@T_ÌQ½²·I2x/L_)i½)9l¿ê4T±ž÷R Ì·Ðn+³ÌB¿ ,‰FwmniY’ܱc‘¯úvE®ðåa&.â´ ¨LÚ¼Žom"uÕà`a2—“88—oØ•jÓŒ ÄDpÉ–m¸LÖBàFbiθ˜Ä¿€u¸HVilhiñâ¡Póæ`ððĬnÍø,¸,Ó9Yíšq‘êꌲY¸pÚû3Ê»90‘f;�y_âRq‚b0àR× ûûÛ Ü½GõŒb…ŒÁy¸ÈÒ†¬ò6\åÒŒ²t<139² h'nB)2¹±¹yѳ+WÖd–€º9s^FÄ¥äDÊi„/‘?Øò8.Q;Gá¹ea(™¼uÚÐP¬'þVºÌE›[[}T0"�È•— Ø’§~ °˜ÑÃ?›‹qŽÏMeЇž`°^àXqñtT{$!k\ˆÍð­ýrúœ�›óù¶àtüpvVùçp#è;¸µc# hiˆ¤GžŸôýûÓÅïìuÑèÖx(ô'YbDž-C—¸ù=-OýûR?³¯ÐÜÇÈð÷p;ÃG€–¢L_$²ÔZÛ ª�»ºþ�®•šŸªzÝ@UÕêºhô~Jgwã˜<õǯ1¶cåãŒò½l]‹Å3濈ÄUÄVó³Rd�GöùuàïyÚ>ƒêiÇ­ôGfµû"nêTáüˆõu;€Of|s‹T�x(´,»¼$ëÀOqÃý¼¬ò“p>@¦rE¾«qÛã¯q#+’!k*n=ù[¡Êh},–}=hl�qsKKõ¾íÛ?³|Þ¼{³®òÊ0î:Î�¸7ý$ЀË:�ÂH 5îÒÀ͸älø ÐÁÈ­—ûR2�À%nnÀyŒ%‘×½MMsöô÷ßaD>šèï?£ßZ1¼ |—‚ÿ0.soV›'IÙ�ÅvÜ…ÎF\&ûűÇ?Ÿy2ã bNò�„ÁÁA©©9 U¹0 ½Z‹ý²E§2’TÍd°)õ{®úbH¯3ÙrÞÙûû‚ÁµVäÊ*øJ"¾¬¶££=Ÿ°¼F¨K$vo ‡¿<÷ L‘ïôƒ»ê:;Ǻ̵7ߟ.à‹TŠÁD$r–¯úmQ�¤Èkc=0n®+n4ªw¨¶ÖÞXßÕõ«1š×p ósP‰†ÃÍ“àQ C¢ºvEg瘉æ‚r‘}��«’�ÀñõÑèmåQµrôE"K}ß¿WE¼€µ—.ïêzêPëtHˆ‡B͉p¸ñ t–…>Û¯9(�åáÙ•+ó¹å3á‹”ñPh™¸E3 Ð^\¿´­í¥R*”žHd±X{µ‚W‹•ôgHö�1G‹È0€@Óp2ùho(´~¼çJ¥«¹ùèž`ð–ÔÑ?,ÐØ×Øxú¸ŽÁ„�P�¶Y»ÆBúÄéiI�R1Éä�EätQuº«>-žWèM˜œ”hMyb÷F" Võ<ï®ì6= «1fñ0Ä­1ÿ*ä¾£áðtc퇦Šl_‹�Š*‰êÈ|CE:±öŽñ¶¿B¨øåêx(t—�wþK«úºëj;;Él—‡?£°ÆZ»ÐˆÌN)·®6ËKíjh8JE滺J�.§¨hÈ]AzE>ŒŽ¬YFd¶µö€Ã˜ªÎVy/¾»g8Ê�Ýݯáâe£¢FÐ sç®ZÜßžw‚µv±À¢dŽ/¡ª¯¨Èq‡¤-³Åo¬¤~iþÑסz x,IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/tomoobjseries.svg0000644000175000017500000001341614757047403027047 0ustar00paynopayno image/svg+xml OBJ OBJ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/tomwer.png0000644000175000017500000002144014757047403025461 0ustar00paynopayno‰PNG  IHDR––<qâbKGDÿÿÿ ½§“ pHYsÄÄ•+tIMEá 5J’“” IDATxÚí�y˜ÕÕÆ§ºgcØ÷Mv•hÔ¸G#w£F Ìô5nÄ}‰FqIBw“b™îÁ8ƨŸ{45jâŠ(1( È.ËÀ00k÷ùþ¨šî®îêîêa†n Þç™gz©ÛUuï[çžsî¹ç€{�¸ëè´«u�á±' 1¦°å”M@%ƒù×N;y„™À„/nòFÃ<“*¢• Ñj ÷´{÷¦ÂŽ"U%CñÂrX£•œ¼G©{Ä Ï£zæ™Ìgm J_|@ïÊê\Xuó€‰qm`0d,-™¤U| Ø&åü· ×YŠp7ÊÞø¸]ʘïI¬ŽB ¿D9ef=XAÊVáUùL«ØÛE³}Þ÷æ‹8KÏé<óñâY”wPi%w¶ATL.@K„Jo*ìX¹ì‹{W”©æãˆs; âÂJSÞJøä ¾Êà$]ň›2…«´’oeé"‰SŸG¬Ž•X3€�€Ï€k³jûÝ IÒ�±]37"ü ˆ �3e‘ ¤éðPì›ÕõúÏ[®ŠK<+Ÿu´ ÇàRáη¤s(–©4¸:ÖôÔ¿÷Q=ûIË=«p÷´�<ƒò?à>йÍõ“ë’TõÔ_| ¼ühW$Õ-±´Š½‰pJ#Ê_drjýGgÓƒ^Ò‹�ˆP„�XK>`Ð ¥„”í–d«Pj€�øÙDëåBëûö¸�‡éCÀÀGP&±Î#V®H5›})äß`CXEYˆò†TðUV?SMOyUÿ[#SÙ쫽ƪ�ôú¢ ú" Dè‡ÒôÑÊâM-°±6l5ÿ74ÃVkr«k€æ0D¶8È î�Àïƒ^�Í¿ž�¡_WèÝ%åéž.”k\ê~HÑ2)g^®Ç#¯£´’R|ôFé ô&Bo z¡ôAh}n’¨‘~Q�QlÒ! _ךk6ÃÚ-°n ¬®‰‘gƒE¤õµ1µ'J aH/ÖGŽ‚3C8 8@çp¨+©£¢¡`·Ÿ ut¦3�‰P tJQŠQº#ôŽN;z[ïûZŸõŠÝžk{¬Ýl’åëZXUcþ_]ëjíß5‡óï!*;BE ó7©àl—úÕÇ@?ë£ øØO&±!çÄÒ ×!qŠ(t±I2¡Ä6ÀJ7•(ÕUÌÿE@©E¢6;èZ¦äh�†6l5IÑ*UÖZR¦•<!Yv6ž»N>ÈêUe¤Tð… wÆ0ü\„1x0[+RCÜŒr=ð!>Îh/RŠÝG5fƒ†f¨o‚ÍÛÍ×Û¡¶Þ|]×[ëaÓ6sºY¿ÕN õ[¡fÛžgTœp¼r}ô�ž.å<Ð᪆P§BL“rnëÆÇ!�m�¦¢ ɃZ×Í- ¤i޽GLÒÔ7™ß퉤h¬Ûb{Û£ÃO¸�¬`3bEÆFXÛnÊû/ÿÏÐ|Á˜Á¶·‹¬ÞÎ4rð `Ê/¥‚¯whºK‹VrÊ¥¼I9/´!„:¥ò®{ê@ú èÖÉt ´þuëÝJ {)ù¡Ð¥Ö²u§B(²l®n%`Ä­[lÞfïÈÆfÓ ¨­‡ÆsêßÚ`Î Û¡f{ìu}ì;fŸûô7' " kuÚj5…4òà›q§XN‡È6¹Ô¥&¡ŒCYF˜;³YØíÜ mE‘ö£À^½``wèÛ úwƒÝc$ê\œ——ß„ðcÛJ@H0”F¦3\èRSPæDE‰�#€Ó#˜�0ÖFÊpfRé†ác(J %,’ ¸r¿j%ÃQú㣎Bþ›¶�P�r0Ô&máO.»ö`Pb½¿GÊ-ÉÛA�÷nC}†I0‰ä÷¥”Ù ¥a³Õ µ–þ°Å2m7#(ÊV P~ ÙÚ}/6¥X&üý:s j)¢¿L ^çr ßÃàýlâ½u6](ävàÛÀ:„û¤œ¿§Q†÷G™e}6€[)ç�©v=kˆcP~dSÄár ðT"Áà”1ÀR|ü\&ñ?×÷WÅ"œ|$[ÌWÇ+�ƒ´a ʰþL}ÄüL¬Ï” ¶a ~¶ ÔÒÌ© +o–å¾`ÿëàÓÕé�ïÓÖü.ªK…$@À…”‚ð= –&^�ilmÓÌb"¼õÿ$ãN p�ÃàŽ%Âó8/U)p�øs›®IBŒö'Â;2™·s9{û1¬pX¡%LÛdBÇο)ô…V±Â…}ä¨8]2K& r:ðXtP Y¦�ð=™ÂÒ6 `0 ©®ÒOI9oFÛÍ¢ªH½þ)ÀýZÅËY/ËTSHˆÇ�Ó-íä.©àê\Ë�2–IËd¤Œšœ�Ê$Ö~+7™á(™p؈¸7ÞÉ aºÁ„A�Á½Y_g�c€C2ÚaÊOlŸ”rfèN:”aZÖ×ÔÈQRÅ®à* rlΈ•î���˜&õ'.“õÛvPG1Ÿ¦=8Ì0ÌEñÄá?^5ËáH—G–ðàܦvî®ilЇõ;1^¿ŸLÏn†ç¼~“sÿå‡ko†1#&­r×ä[ã/ßÏh‰ùhI¡IÖe“ZȬb—TlkÔiöf“i9‰�ºŽ®KæÆ¼ýÇÝáÜù±™"˜֗n$Ö f4¦õ´~äbˆƒc^«ym�nwQ'JÑÅ;ä³J?ï8ÝÇ6"<Ýî³KˆS5Ä[´«?ù®�Úù²K'+b�hˆŒ&·L ŒrD•é`.EÎ[¸ô~Š´šnŽ?ÖÄ à";ŸP• 5Ÿ–²ðx Y±Îq–fRÎ?®ˆûýuD(sÏÕ]ø1”£€ŸjˆI­ÿñU»äÊb©¹4¢ð¿Õ.ˆeW�G¹4|%¾M])¢TL‘ Ô'XŽÇk�WèA-�lÖ Ë5È-ñ*ÓØŠrE†Ó½F!�ÙÎ?‰u(¿ÈÐî©D“VrŽy?ÛðS¯AÞ× SÈu/EôÁ`ƒ,“³“VäB òŒ¹<å1÷'…=äµòŽ˜kÙ׿Š&ì;ÀFÊqY�j[�,_ r!ðà„8ýh0?¯ëìØz TD˜Ž/cp¦“Þ'ü ¸-ïG)ŠIëšîB¨¶¬ÐÖ±:xXƒ„ ™@½”±îˆóõï†í–˜ûâ€AÈ¢U1I¥Š¤òÓýv"rÍ£y°�P+¹Cƒ¨ÑÑQHÿ7ªŸy¬Q­L/…šÿÒ*Û6±Œþ„‚xRÎKbMa ¸Êº&g¦¸Á¾1dÆY ƒ'›“ÔÎE$©?‡kŸVý*âÂÞÞ'5±d"+€Ë2üÌ2Ͻ+. ¸³»LP­d6Â�ý?[~­b£‘Ëm÷.|I!wµ¾=�ž—ÎåÃKçò¡Y�p ð)�c»–Bê}9‘X–%1à󶸌6†¯ æ�ÀiŽØ†ÁEym3“ô[ÉÖÓ•6L ÉÚÔz3Âã¿Âà°øl€7ÿ ¦“I€û¤œ ©HåÎxÍV3¼u^^ìRqÒË&íÚT¸HÆÒ¢³9…B*!)ðï  \Êx?Ÿy%¨Ó c1×X¿›ðõ™šüàYi‹nwúÍQýØ{ÒÒ/Ng‹ÜèXñ®—k`÷8ÖDûúR Ì4¶J€318áàB„Ó¨a¿ÄXð¼%W€5à”#Q*€ ‰0ž"ÏTî÷¡iÉc~ݩퟡ97KÖjw-[ï®É XPðj§5= 23Ö}°˜î–©©])c¤xË{‚Uðà?®º|.û üa¯�e=ÂÍRÆ;ƒ{²ßù³Ó'UÙuˆe0¤•Ë]fÁ#VÒ– �Go¼ Œ»³h%g›§kwDÔAÚêË2ãEŽÕyzïst¾¢ª#†87k/0­Á5.  øL?–Õv•ÃÔz¥�T&ö¶ƒR9H›¹àŠ*Þu�þGk�«Ý,éä—IJ2¯Ýì.ªa@÷¸$k†Ã¶(MQ£YL§äw5>˜‚0Ó£½ å%Â<˜5ÿR^·C¸Lº¼TR$9S´†˜Š2Ëû®•\*ü~×�X˜þ•K|P‰öÕG“³$EÓ¯Ó�ª�¼Šðgà{˜9 ¾ƒðKü¼«U®–Nvú”¦!žÀtlÎC¨h�7™—&‡Ej‡ïR‡c/#Ã’N|ƧEèœK«ñae¶[¹É]›�=’¦¾‚„÷w[ŽúœÂd¯qœmù p\ŠoGá™TÙ]rBª,ÃetFì˜uÛy6¥ _ÅŽqü‰EBmK::ü:!«˜�«‰­>,·«oWÛõv?–LfŽþŠY¤ûO4sŒLpNpZ'Ì ±Œ˜~´bcˆ•ZŸÊÚ*uq\¯¼˜Íh‚lÂe¢^ô࿲+Äe%¹Ïús>&Ã:an¦Â8KÍíTØ+>À¸†Míp]^ëú¼�U](¥-á2Àï'“ê�[Û^ù6­B�ùSÖnqפgL}¬“é4º:M�Qâ�Ë ¼êòZóÂ3o¹>²—Y4ß‚åÉÄ:ü»±ˆM/]Ö…ˆ:GÅ]µ* òàs”W0øBCÜl(s»}¦E× øy(| Ìvq”-\fÿŒLŒswÚ;¸»«˜Å!·»Ì„ЭS´s3Ê8+Lö"›Õ¢ÜªAŽNÐFÎ…” ¶uLȇjðQd.“*ÎýîÀΉçÏ™ÄÚ˜E›â‚¨ÄÚîâðT»pN´I­‰¬¦ˆ#€_s¤ÖUâTàI¦�wÞ±Âi�t.½tFl|,×ÉXpœÆ?@8Þ.“bÇG*_´É;’ U³ŒmÖÄRWú•/…"žÔÖ¬ë�ëõ~Šœô7 Ñ•w €îô ¬!æá&+º ýäx„_¢ #ؤ•Ê@Zx±™ú>”qÇk%“¤Â9/{ÖÝâ|”Y6ÿšYêF 9Q«/eÔ€»p™–0ŸøûÿsHNî¡óM„:)ge{ÜO.Ü E`ãvM¬X޾­ädY, ‘ÅZÛícùXª~ƒ™?  å2)O^Åψ*Óø�üs²ÝuìHªJÆ X… .„Œˆ«VÀ »è #ùF©â¯åÜ4�ý5pO†_^H s㬻¾ˆ«êgÅ;?ñs°*Ãy‹ãÆ�ŽP±0›ÃFìÀ8Gx-î\/äóT¸ {§¸ ð®=·Ìm8giŠÏÓOȃ¹ M¹^ø §'ø¿öqÙ§�3BdˆprÊÊL©àþjªxö¨#ô€Am_” !Âx„sØ”Pç:ϬÂU¨iåõ,…�.ŠËþ{‰­ý‘À#YjuSÈH*òAÚK5c“.Ð*%Ì�­*_^ ˆ9IIG|ÔG½g™Ðl�n•É,Ô9LÓ¬RyÀR„9HR°ãI÷±#mâ*µî?h‡l2¯ä¿»!n_à v‹™êhSà�˺c¦±ÕÚ}ò(­eD„/ s©«öæºáüŒnäz°2ZoKœvYŸÝeý¹ƒ‹„ Þùi™vþT‰éƒ³(yô|,2jd[ò„J9Oæ„2”S€ƒd²ëúÎîÎ1�F+WW&Ü×nçLp„64sW¢#ô»ûsÒŽî̉e°¢ÕðÖÇ}³çÀå'FÅüÉ8„�h5>ùf²ŒÅø¸)>ôE¦°§-OD›ï´i5ð+ ¸ªg“8ÅÝBÇZ»XœðKm%YÜY¶q[䑨y롉:B_¾žïŽŸiÞóÀô\z7‹ý<Àî̉Uȇ–QÌ!ÃÜ7{cqܵèŸ “T·Ç毮­šB"¼leS…¹-ìY­blÖd* lcœeQÆOô5ÀÍ æ™áZ³»rˆ&;~¦V³h&þÕ5l*ö3 7©wubY"ús€ïŒvß®±6ņ©oŠÃNIxÿ­r‘I¥�qHR�>ÊumºÇ Ù.®¤ˆ¾VV›ÙN? p{¶õšÝºqÀõÑótvi!ïâS¡‰g�+Gõƒo….²]õéý»G;ziŠÃ×·Rà")ˆ$­?¶N¹Cvð!ª§=2Ú¸p)¤iû$j“Rsv_b…yWrÓðÃû379,5žIqØ­Ö4Ö3læW¥à >tœœ$9e¤ÎÀ`'a(‡í‘SË*¿r:Ð@KŠ@páRHc´\ç&õcû{•r+—æyw¿×<š:éÁCáÍ›£ YÊÁ©ô�G?Œޓ@Úq{» óÀ¶óy+ÊÑñùHµ’R„— NÇî—r~ºýpÂcĪȯ¾íZM!�¼íàR8Ôq7s —Ä*µ:ô€7?ƒªá_Ÿ�ÆìÄ!tQtÓjaŽ”),Ò‡éC§áÍöpXƒw©å€]C˜ß'þ®Vrâ°›ØàˆV -zì£ $ÌL«�ù„[‹qêŠñ³ÜAgü§솃†èŠòS„oK0¸»=6{h%¥Ài(´§û%·õ «ñÑÄí(W¶:.×l†OVBm½Y¦wLL»Ø@„Óe2o[$øsý¯?c¬¬É{½!^Dù¾C/Þ åÌŒ7‹Ntâ#ì±N�D8J&óaœ”<(…ÖÂv:9úl÷{ ò&p4f8Ó‘;ZA,wî»r–r~†²ÊÀòÝaü8û°(©6#üå™l•¡mf(±Eå®´dïh#jS(ùu v×9$Ða$ElKi§®éøM¥ÖŽ£Öø°â¸×»6±¢«à ©`º†Ÿ!GY ŸRD?)ç"[Qí–Å=é5(ÿlÓzµùRƒ,²bŽ\42«Á& ’’îH1?ØããËYŠózå<·¾. 2Uƒ|©•|ª•î‰!º�¤u©ªMS7{Wš ÛAG;ÅÒ±VeIªS°Wx¯ÇÏ(§ú†Óáå(·a®.¦HÀNl‡ßoŃàbÛ±U %B3ì8üå<7¹Su.bðaœ€Pààl¦3­¦„&N¤™�Òxïj~¬ö�rÛpÿ�âq:.!ž²„0Ç�¹0ßïÕÙ̦€R‘"òs)/0’±o’]‹‘¼FÊXŽYq¬/aš²JQip\¬#ÖtæšX–¯íÉÝÃ�•kDø"IV‹{ׄLc+�r/·Ì ¢ÕœE?ÁàÛ(ËñsO:Ã6Õ»@–:/ a%¸¡IDATÏ‹Oä•VSB#Ïc®)*Êï¤"eˆrþÞ‡"„‚•Zx„2ΡÚÖ{$±¢ƒRÅÂlr££é\!Œ¢ž·:Ú  !¾A3[Ýê<­›vÛR Ú#V.Id"03ªó+"ŒoïX.K’úhà +ŠAد~.ax´É8Ø…Àˆ%q‚/厖Ķ=5Ä™úHŠ<ô‰häG©Ì‡^™Þ–Ð�|À¡¼ëŠñqÅ„ù�­–_&ÔÑ�‚„Bæš9¨Vq8�üè†ÕJ.Ë`§ IšC")"/ÒI½&.†#ÜmY�žÄêø¸áf”k1Üoº�óX ›Ü8d#\Kló† üÚEn­Ä]ÞMY–{kb2Ê=(Ó‰ð´7v¬&9:îuöÙaüL^DY�òõöÔ“)�x]JÿôAvRÁ«ÀÅÀg(ÿ&e-q졇{Sa‡Î…<€03mä̬yiúŸNʲÙKÄW¾Pæ» qq“ê:ƒ¨á ´OJ"Ï*LÇ­ùøYO�åiÞJ¿�&®G9 áS ®·2àì,ƒ£0UevaíÃC¦§¿3MA˜YY“íqP(¼·«õ›çÇJ7°³( ‘·­|ñ霷CGž;Ä$  ¼«¡Œ™haË cHRMz&€„ú€èu0ê`:˜pœºQ<bKGDÿÿÿ ½§“ pHYs  šœtIMEà 3’,äù#ïIDATxÚí�w�÷uç?¿N“Ó&,°HŒ A€" ÂŒ&!‘’)Q¢E['˲hËÖ9©ÊáÎuvùäs¸;—]¶ì:�\¶,Ÿ}–£hK<‘²$ Vƒ L" .€�3³3;3ÝÓý ÷GÏ‹EŽ»XÌ·êW;ÛÛÛÓ3ïû{ïýÞï½×ÐC=ôÐC=ôÐC=ôÐC=ôÐC=ôÐC=ôÐC=ôÐC=ôÐC=ôÐC=,Ø }§€Ë€[�a 8�ã0 }s*œ3¿ÄyÃ[€ÿX@L»�—�íÀ‹À�Îßz8I\Hp��èü¾Ø h`Ø << <Œ/ô ÷pvñaâÙmŽ340EL‚«ú¦{8{8Ìub"üPXè›_¬¸�œÀõÀ&@ ØÄqÎO—w#Ä>Ã�…þ‹ Þ¾ |ø6ðP&v “€wŒÿK7oZÀ+Ä$êá‡E¼¼ø)àŸ€×9¤!Ž6Þþ+зÐ7¿Xp!i€ù0@›Øé{ø ðàƒ@‘#MD�xå�žš ý!âÌ/±è�n~¸Èåœ&ðIà�É…¾á“Áå/ß"v=ö\)‡ÂÆñªŽ›ž•?£¸Ç…¬ŽI ú±�p Ð?︖X‹l'Ö$‹úÝI/¨·6 ø)„õƒX¶Ân%vpVþãŒ>Ýë.EtÑ$î`%qàh®Æó€ sÎ;í/ñœã/�L03{¹—)ü`>ßÿîd*{U¤T¨Z³mÙôé· 6£GgOëþ—2 êNbÏñ²p. R�c»;ç-N¼ƒ•(ýÎ\qèî k¯YןïÏ—gÊé¨^Nb9�ɹ~ú§‡êá§gNyOd© ‹QàUb-pù¼¿õÄZ`z¡oô0| ‡{ËIæ79©ì-ë[výå#—äÓùTµ³¡e'"m”j6dØj5“w–šžtM´çäÝ‚‹…û�}ÀÕÄ&a.Ö b¿aac·&£2~ývч¶Þ–JÞºjhå5+úG†ûó}é\:ç“ùt.9]�η«å$ÂLÎ ôõvK?Ü’'ûv öf�›8<“H¤*„7±9_迦¿Ð¿¦˜+ÓÉŒ+#)‚ @J‰’ŠvØ6M¿áWgÊ3•™Êív°�H>MËß{ªÂ‡ö›�ùaÔ ÄÙÇçÞçV¸h³©îJ¸‰»Ö._³fÕ²•)×ví0 i·ÛD2¶û‘Œt­Qó+µÊL­^›l5;u}­ãQuZ;›³ €Ø[z ¨qh±ð¯â\‡‡?æf½åK,/}£—J\ß—í»¢/×—Ë&³^FV—Zk„¦ÑL­Ò¬5jc¾ï?KlGË—øˆŽíþ›“‚Nip&èÎ� =ûö%`ŒÃ �#Ž>|JWúdIðsÕ“€2Chý¶D*ñƒ+‡V­,¦²nÖÓ¡¶kõZ��Ö£µÑFE¾ßòËÕéF³ÕÜ#µ|Á“ätíàõNQøpúXünçõïraçÚM/ ×Ï9f‡‡�€ó©Á¤ô[Y‚°ÂÆM4¬D¢á哳Á{÷�ÜŽÜ'Mk¶}BܘIf6 æJ…d!¡Ó šTë3a€F+EaÛZSÍfãÙj>�%žá7ÃÑ3ýð§C€ðËÀ:¿W€? V£"|âT±ù˜¿_@úK+�öD0‚°®Å¶ïÄ�Bˆ0æDOÑ-Jùó¢àÃóvæntÛ#ÓyÇ"Š»„ëÞžN§/+d‹ùR²”±´•�Ú'*³¤’c°-[+%¥ßjúaØÞ«”úˆÇ±˜8þT �~ø9â­T:¯ËÀÿf¡C¨§‡6±S?,‰$õÇË�Ö땤~““Íßž/.»mRõF½(ý¦Ð�5ãüùÀ«òÃÓÁ ÿ“y´½[lÎ$Ò×­(­XÞ—íÏ(¥³í†¨6ªÔ[ulÛF t…¡Œ¢jàû{e>‹`;Æ}‰ßhœ•@Õ©¬,àýÀ¯p¸½,k„÷Ÿâõê>Ët_¤ÿeµ£ÕH½ ?¸+í¦nÛxÙ†Õ/ß8”N¤® å߈RoÖBorþz0yð Y|¢p(ÿàã‰4Žu Xwã:늙Òк¡+‹+rÃé‰ÙI±»ü:� p<Ûs–PQ;lE~{T+ým´ùÂìá·ÎŽðáÔ4À½À¯qÕØ9ökÄûéŸ?‡‚:W8r8™~kQè·yvkrz©¯ÉôÍéÂÀ¦¡¾¡+³ÉlNC}ËVJ)µï·„nùèÀª;ÿ«ÿUù«å€ŸŸ£ ~?› ­®Ä˜ÍI/µ©¿8°z¨0Xr'¨@Tƒ*3ílËÁ²…Á¥¥š•Qt Ã�Zë§Ðæ9´<é�ž“ÁÉàVà׉S°�…k:甉—V<ÂsF©|u-~û®Lq`ÓµëÞtY>�/4fc¸tå¥}Å~ñüKÏÓ¬Ì@2…Nè¼óƒOË_œŠ}‚�fS ®G‹›êº|*Ɇ‘õË’ÉTv_ã€UnUhʶkcÛF-í¦ôÃ1F/j©w Ìsìö÷ò7g·údp5±`o;‰soëœû›ÄË« IŽÜ÷¥ßÌb¬79©Üí©âÐæ¡þeWäSù‚k¹¢âÇ1ŸËÛùL¡´l`™×ß÷Ñ~€ÄŒý{ù×hEkf“›Lo.d‹W •†–%’‰\dEV9(3T°„Àr,Ðh-U+ ²ôÃ=J©íHõ4¶Þw¶…'&À bÕþNN.…\tÎ�~‡8Òv!`n¿�.Zí"–}G®4x÷ú˯Y�Kçr­f‹î¦ ÀtyÏóìKV]Ú?P°^|ùû4fj /ê4k´ õjd´)[ºúÚÕ–§²™Üx8iU‚²‰e „°@­BÙR­¨"ƒh, ¢—°ø&³êyþ$<'»“'"À}Äêîz3C\x1{9Ô¨á¶Îÿþ- ±­zjð€å©ÊacD mRh#0­5ZÇË}Ý™ñÈd²v6›-•úK:Tmúmi‚ö Œn[‰ôp.?¸n¨4´"™M”§ÝŠ_¥Ü®`0`ƒ0 •n«f؈ÑÕ–;ˆäv´~…?‰âïð—2‚�7Ï« xøÒ¼c÷TÌ-¸#VýOÎ9²ø…qíàÑ‚>£¸‰ˆfgë…ç¾ÿ̺Á�e#—¬¾´?—ËYÕj• °, ©$•jlì¡•Ãý©|ŠÑWöH¿<;„Á¤3©âÆ5FÒÅlnÊ”�Z«Æ¬l`,ƒ°(Œ u¨ÙëA-š _3Â<ŠÅSŒ«Ùƒwt–…'&ÀØQŽm'Ϋ›K€±Ý{®¥u0HÜ~f.ð†å$óŒlµ˜�®„J)Õ_ìù\¾ä8Ž�H$âýy-iM„'H¤¶“óúÒ}Ù5<ኡÒP*]Ì”LŠÄŒ?cUÂ4ê Î1‘–ª!Y§d+zÉ´¢íó�ÎyÕÒéDÇ:cÅœcà:àŸ�è\ßôYÆÕÄ&`.f�—í½bÖ\fo×mQ%‘­VK¼øâó .ÓkÖ\ÒŸNgìz½†ßöñ-ŸÐ„˜†Á–�[YY½²oÈÀ¶m«JÍ©…ukV6bá; ´0B¡u ÂpªÕŠªá^­Ô£Ã9?)ê§C€2qaå¦9Çq¦í2âÔë qrèü½ÿ1l^Ž>ZÖ€ïüqa—ö(è  Y©£µ¡Tì³rySÂÆIA¤#|í#¥Äu<á¦=ÏMxx^©µÖ,U5ƒDblƒ°„F«† e-¬Èzøº®µwO £_1ªN>¯ë p:YÁñŒ¹›Ã ”&îͳx+lŽÄjâUÎêyÇ¿‰áŸè„¶õWÚÒ~gzJG²ŽeyJ¯^�qƒÐwÓ}Ù¤�³­Y3K›Ë¶6H#i«6 ÕdFÎ0Í™è Ý¶…i*޶ZáxðšöÕ׈ô·0æþ\�RZ×™àLÒˆÃëìSÄuv_ãÂ1ï~šC�§ ú'‰Cá£9ÁÖý¥@:weê86¦š¨Zó´—ʦÆ5‰¶Ý¶ŒcÀƒA¡ˆLD›6¾n#;ÂÇ4Æ4¥”å°ð÷Ééö3„úëý,5Uæùó×öît P'¶ù×Î9&ˆUéw9úîÚbà ð�Ï1»€?…ÎnÛÖðàô×ÚÒ~GzJ·UayJáµ* ·¶ÝÔP:™È%-©%ʨx–[cÂ`D,|˳0¾ÒÑžV#õGUMî0�zø.ŸPûΧðáô {ýoåðÙS$Ž«ƒÅ¯î~‘Øtua€ÿü#ó7‡þ +øZˆþr í;Su\‚ÈÈrË0^2›JXŽ•ÐŽ¶p‰5�0±ð-ci­U9j†{Z“Ñxð² ô· õÓ„j7ÏžB>÷Y™˜€*±#8w %ˆýƒ�,n_à2à·€�óŽþˆ¸ùäáøÚ!M`¾Jûé)Ó’užŽŒ×žð]ÙŽÜäP*éæ=Ki�AƒÂO`ÚF«Ñ �Sr¢½G×å÷Ðf+eýÿBÈàLP'ÖoáðMyâ¸À“Ä$YlH·œû‡;±ø±ý?v^Ãïe߈0_ ¤u³Sǵ )�šô]‰ñ¼\"i¹VÂ8ÆÂÝ rƒ4èjD¯3rðº®Ë§iª'ié|náfgZ8AœJµnÞñµÄ&àIXfï!¶ýóE½NœÙôâqÿû‡,›yLIëG““fFÕAxFâ…c¾«éyÃɤSt-ƒAJë²l«ízôº?%'ÃçÍ#4õ“죾� ugJ€Yâpïí^\a“¢ì`ñt߸“XõÏßÖ–Ä3ÿSœlyø�Žà€Æ|9TbØnˆœeS—BïJiÏ-y ‘°’&�0¡6r�߈öcrøò)˜Çø Â, æ¼>g½œÎFuð(qúÔÌ»^š8ÊV!.»^hl~›¸èc>þ�xãä2œ3B0®-±àvj[hQCjEÚDÆ““�¥#å:«�í³Õè…æËæ€þ ¯ò]vQ!B 4‹Ø$Y�ï±+x‹# qÖp6«ÏË9Ò‰‹,Ä8 Õ|á6à¿÷päøð?ˆ«„NöÇ·p±I¡±Ó“r–G m=-meé„=àfͬ ¢g𝍢ìâ»ìå " ±ïäË¡;, ½›b·¨5ÄÎÞ$±°çÇÕû€ë;¯_æüî:ÄÁžß&®œÿEV‰×üÿÀ©i¨îlu1xÄA° 5`Ñ&�¤T9ÌD»üi½+ú¦Ùc¾Ç4DH ßáHÌ7sqVãg³AÄâ¶í×q¤ƒU Þ+ N9+)Í'ÀqÇð�—�Ïÿ"›ÀÇ�?#n!{*èªip8\"Z„Fê@WdC�É]fÔ<ɼ†OƒCšðd_Ïg g»CÈNbu¿�Ã3‡!^2v{öB¼æ>�:»Å�¿Iœ²¾â(ç´€¿þ„ØG9UÌ'“F  34!FTÙ‹ÏóÔy†)öÒ`ƒO¼2š;¢Î��ŸªóZw†™ósÑÃ>H¬î�Åà*ðð^b� —#î þ1âpn÷ ›?fˆ¾3)þÄ“Ç%&\È"(`S$ö}òÄÛäÉÎÈkÂ"‚‡â%ÙÎy©ÎHtF×q’É+Àó�Ÿ£ÄŽeƒXM:�k”ˆë.%65뉟 ’=Ú…`ÌzØ�‡½Þq>þÛRžÓÐËîÛ?E7(Xž‚'Gúú^¿£RYl1àü¨“Äa×—\Ÿè= ñ†’Ï¡‚ Å¡™æ!ÅIT"­„ê[aç» …aWÊïÎ6›kÁãï‹MÁYǧ¡¨á–l&óAÛu7úµÚ_…Æ<êäó/¿·^_t6ü|´‰›% ?G,ÈaâÙz,"b3�b®Ýä ÝÌ“àDDj\ÛïƒoK¥†Þöã?~©ãyC»÷î-ØPýP"1ýOJ�Õ'Œ}ÁóJ¾R·ðÀµ7ÝtçúÛo_1ºsçÐL™lMÿÇ|¾ü÷íÅU>y¾újâ„Ño«ø�C=›õ„¨8ð�Mðé÷ÃØÛV¯^¿þ曯- §©T.ŸL¦÷íKŽ+|Èó&pæM·]¹yóªv ©ƒeY¸®‹_«5øáï—ƒàs%Ëú\.“ÙùöÙÙ÷ šó‘&¶ûybb”:Ç<âÀH‹xU0I¼„lûú ¥Rb¢Z½Ô‡¾zÍšw\²aæ�µkÓ¡”4êu,ËŠ.Ø6…R‰f¥bÆ^}uôÅ'ŸüjYîyßzÏ)’à_]·4Ew”à¾+n¸áîáË.[•ÍÙY”R!0Æ�L§±€ñ]»Zûvî|zïØØðp)ŸßýÃõú‚:‹­IT«3&ˆÛ»Ÿ4ÊÕꚤ÷äS©û×\s͆µ×^›Þ?:J»Ýƶ탵|Zk&ÆÆ\¶L\¹yóªéññ{ôÞ½4Â0ü<þS'¹:ø;(¶¢èæÜ׿rå=—^ýrGT¦§±¬ÃÝšæì,¶m³rýú´6fS½RIDaØ®×ë_ 6] †%Ó,ún¸·¿Xü•»ß÷¾«S}}©ûö!eœb×­çëc ~«E$¥¸|ãÆ¬b`Ïþý%ª?éyÓÿrÇð³®[ ´¾Õ‡Ö_wÝ–kn»m¤éû¢ÕlbæÔÎ}?¥¾ï“íës‡Ö¬˜Þ¿ÿÒzîù·óÙ�ò(X2¸†¶½Òñ¼!7™Ìer9šÍ&Qgð̈”2.âH$„›Hä ©T¡26–œP*ø ëN~F룒àÓ®[šˆ¢;RpÿU7nZ»v•�J‰V³‰ìôñ�O€®öq=�V­Æô¾}SµÉɧB)¿õùnO¿dð€çÕjA0µkïÞB1�. ¯Z•‚@H)QJ!˜î¬¬×ëäúúÄÀŠùêÔÔ°ª×í@ëúÃô#óVÅPë[’pßòå÷\uÓM#V"!ªå2Ƙ£ ¿[I ´6û^yeôû/¼ðm%åßå\wûg´^ÐÚ%C€Ï(忦¨Líߟ,OL _¹qcÖq]1S­U@Ýc~«E†â’«®Ê Ëxc|¼dAõ'\wú³MðϵÀW^sÍ–+7mi´ZÇTûsg¿—L‚RæÅ'žß»w«Ÿ¶àñ´^ð¤Ù%C€G ø1Ï+O(¨ZͶ,kÀK$òùRI4�šÇó„ãºù\2Y¨MM%§•j¾Ïq*ÿÁ²Ò“RÞš‚¹üª«¶ô�Œ¬² Ñꘘ©ýfµjÆ÷ì�xã�­³ðHÎu·}Pë™…þ¾`‰à!¥‚zÞdS©Ù×(ÓéÂЊyÿæ@kM½^'“Ï‹¾eËòµééaÕlšHkj½& ÷‡†î½üMo®+ª•ʉվ‰»|ŽïÙ3ºëµ×¶ x°à8Û�rÁg~KŽ“à]0eC¥<>ž¬LM _ºn]Öq]Q«Åý,»Â›?âDZ„bä’K²Â² û§§×FpÃåëÖmºtÆ5�VKø­Öa&dþÐZãzZ)³ëÙgǦØjwÔþÏ,’™ßÅ’$À¿AðÏ+O*¨ÙYÛ¶¬ÇuóÙ\Nø¾TÕmŒAu´„ãºBXV6›J ô÷¯Ìõ÷Yžç´Z-¤”ÇœùÆ×¥U¯›©ýûG§Çƶ6ᑌãlûÙE&|XÂxX©à®;ék=ûÆÄD)—Lú‡†òA¥ÔÑg1±�Ðl6ñ’Ig`ùòt¾¯/-µvêµÚ1g½™ó¬£µ™Þ¿ô�ÑÑmÀƒ9ÇÙö¡E¤öçbIàa­ƒwtÌÁÌôtr¦\^¹fMÖq]ÑlÆ)‰Ç¦R ?â QGco8ŽƒRÊìݹs¬29yÐÛÿùE8ó»Xòø÷»n¹¬T šM[XÖ€ã8ùt&#¢(:l­>ÝXAWS BÇ¡Õh˜òÄÄhuzz«�¤m{Û‡�™YèÏ<\ø7­ƒ÷9Τ¯õì�r¹”ö¼B±¯//£HèWqÜ¿()Mybbtßøø6fm{Û/(µ(Õþ\\4ø¼ÖÁ=0eA¥^­&ëµÚðÐðpÖõ<†á1Ý%AwX–uðµã8È(2{_{m¬R.Tû¿´Èg~¾ Á;§\Óº¥|ßËÊ !²®çÜí b3 •"Š"º�p ‚ààó³íz­¶»:=ýå|>eÛ�ýê"|¸ ð%­ƒuœ²¯µš˜™Y“K&‡‡†Ò]@k�î<Ÿ/š+tß'hµð;#ð}*•Jmzfæ9ŸÉÚöw~E©³ÚÍû\c±åœW(â|ôL.G?¾ïãû~,ô Ã8¤Û]t–‰@œíÓ1 ô¢Iõ;i\”ࣶ]Sê¶Œe½ýÚuë6òù¡f£áT+Z�aµÛ¨(BK á‹î`Nµ‡eÙ¶v[J» Á;„˜úÊæžO\tøïP �¹%?Ò_*Ý{õ•W® ƒÀÝ»¿Ñ@A,t­±„À"nå>wp¨tǵmDZí¾H©FkGBý.˜þúB‚‹ŠµíR`Ì­!D¡&e²Ü1ß\„$X²øOPlÇÞþýÉä=ëûûGRJ‰f£«õc©üÎOiŒ‚Ý/ûþóe)÷§cô9BˆcùÝ�±m‘µí|C©a¥µíCýV˜~|‘‘`Ià·„(ùpk ¸:Ÿßrm¡0bÚm¡¢è˜‚HcÌ3ÍæØþ0|Ô†ÏØ°£*¥5«ÔÈr×ͦ,KNl!ÄPÇì»…XT>Á’#À¯ Q5æŽ4Üm6»eu"±*+„ÐQÆwæ§„ "¥y½Ý=†[ëðHZˆmŽ{«à+­]  !òEÛp|Ø@Ò²„'D>-D¡,er‚{„˜Ü¶HH°¤ð P à– Ü?ìy÷Ü�Ï�ä…a»}(¨Ã±Õ~hŒy­ÝÝÛÛλ'i ¶- ¶�¯*5,µ¶[Pß ÓÛ – þ³ý>ÜÜ„®Ëd¶ü@.7â*%´R' ê$… 4Æ|§Ù{= né~lN�àcü@g+yZÊdU©áÕ®›M[–М˜Žb•ëf ì–²dCe‹ÕÇøÉjK†—Àí%Ëú™›’É;/÷¼•EÛZ)Ä1Ô¾ ööSB0!¥y±Ý}= ·Và‘’Ûþì(E¢OAp»åI¤Ö¶‚�¤ù¾Ž9èv‚:êòHY–H Q賬�­û&Œ{~�KÖÌn „å6l\ãy}}–…–2f÷±’<:?}­Íka8º-¶¥á³ÃB<þ1cŽ™Éó1cª¿,Ä·êÆDÛ‚ eÁmEËZåuÌÁñ þµ1ôÛ6@ßKíöFydWÕóŽ%£6ƒ/�™}5ŠÓB”Ö8Žk8öš=%mcÌ—šÍ±�ax0oÿ/O¢<üI®‡)*R&§”¾Âu³™ã˜H Á aØÚÚl>ïów6üû3ñSØ K†wÛv£lLyÚ#ŒÉ*\fÛnRæ Å!nö½_J³£Ý݆['á‘!¶ýÕ)t{‚[…(˜cRBä‡l[Ì'^ªsφaëûíöÓ»´þ<ð…aËÚó˜1 Õ@XBxÌuƒe•³ÆLïÒÚ®JÙ·Öu‹i!<—Ãí³oŒù^»=ºµãí ±íÇQûÇÂvÞ"Ädf_–²T¢0ïÏš�%C€g�áVË*GÆ”ø;ÃpYÞ²ú.sWÏDßóP³9öüµÿ·gÐ3ði6vÌÁ˜”É ¥†¯rÝl¶,ÊÁŽ0l=Ül¾Ð2æŸmøbѲvþ­¼?,1ÿu!^yX)9â\´I?,%X œö¡V²Ù1ÐøDû¢hùËR¾¸¾¼öŒÅBì úPÒqgïn·n�C»�¿¥:çæ:ÿ[ê\g¨ Ùhš¾R¹�QÄnc>·¾ýbÜQVçá‹¢CÛ’‰Ì�€m 5&Änǘ°¥õDÕqxe&~ä�&B·ÿ ž7àø�ÎÍœsUçZj¦møžgÌlÒ˜Ò4pNv�å烺=ûú:Ž�?™ö´zÔE…ªî¿þiáü”˜Z(µ�6[‹ü”YfR>Œøúy%–çýÓ©çïo·�/§2Çüú³Ý÷õÊùúõ†^Þç×·çCßïqÆ{ ÷_Ìþäć÷uã=PN¯óòþ;Ì÷}Z>-çý›û3ÄÇÅßÿ]:Á8•“9…t³äȻߘòëWùí¼§,\$¹>gï5çÇ.||ü.xŸ¾‹]Ô÷ùüm(Blï Úw1zŸ—úãØ=ú<#ùúäo¾ f7~þù;³3ÌîkuZ‘jὨ/Ky>qá"”¯h4^�ßÊçþ¼&¯Á7A?dsñÚA¦$¢mR䈊É}Ž[6S,é¦Î1¥MÜýÜÈ=Í´³§ øK,õ<ó y�›MÖ2§ÓÇ\äyî|ž·eðä#\™„Á„;þò ?:ù;¯��̺"q|ÄŠy% ÓðÌù;W‘±wLëßç>á&~Jl&ƒõ ó`�×kˆUå+¶ò“çÌu5–_p—~Þ"ž]™Œd2À–&±§ÔEˆã ?ÊÌS.i‘©5 Fnrn$g$6÷ty®M5½NC-$¢R"�Ô̬$«” ~z`Hk®%ÔZ[íuÔYµåVZm­õæ¥=÷Òko½÷ÑgבGu´ÑÇsèL3Cau¶ÙÃsNUª ­Ü­\¡ºÒÊ«¬ºÚêk¬¹tŸ]vÝm÷=öÜzÒɇò?íôpÆ™G¯\ tË­·Ý~Ç�W ¬Y¶bÕšu6M?²öÎê·Y“ï2÷ó¬É;kž±ò\׿f�Ó½BœNªçŒŒ¥"d¼{tòœÅ!¥$Ïœç,ÎDQÔDÖ¤zrŽxÆÈ`¹’ªÉGî¾fî§y µüWyK—¹à©û_d.xêÞ™ûkÞ~�µ£�¢ä'A^…Ó˜ b³º4 þA‹¿ :ÀÿÏ@ªÕ¶6=i·mR§.)ë˜9ÃØ…òe­R[Ù]W4–,ÿºªÚνK9Öë";X‡8¯�®n ~á~õŸõôÕÂn·¥3âÍu�™Ë˜§ß»Z§z˜w=Ð%«�ù×�ÕÝoJ, Ü(ru#4ÒîzsÜ”ä’^åÄ–ç)«dK«ƒM�ÙFL«Ž»臭=@é6Ñ O¡í¯y p^½­t¨Æ)-Ú¡ïÇõâL*£g™v²s°\ݨÛ·®Œd3ƒ[„Úû¥,O½v)f+’˜U#Ÿå ÑSRbï\ jR™ QlíL±‚s&ñc½ _OhZcz5ü•Àiq¥x=|`’&©K‹%Y+ù.zQ—@ ;AÜóÞŒ@ã_½�½cókÓÝè«ÕFuËŠ­œ,«C1ÁÑÌÒ Ê¸ün´˜¬ø€G¬VÐU­ý€)8ŒA«ÈkòG Dp�gÕœ³1 ÌhÙ„§Óp—À@`h|Böy’ð—bˆ+@‘0[àÊÒÊûz®>xóy‹e•š¯•IFks`@™ìZŸ§@æ‹@¡1wx7(ÅBÜ"ˆSÓV‡Q£GÖÜûŒ0N<7jú¢3ôÉ›Î嶆ñJJÞ‘àë1àâôøºÄ™ïü \G¹¡=T†92ìÆ”½(%oɥ췕ës*KxبåPÑÝŸQiŸócØ¢æá‰Å4µØ}z…þd¯Ì5£AmÛÃÃp<°Á{8€ ƒ(gŽ௣L©brŠï€yú‘o�Û|Ǭ _P´àûègŒH·ªNM ÏâÅǰ˜VL=oÕ«73�N§´mŒ…|¡ý©b0©\Çö Óaˆ"~\ÁWäJç[ÜZÁvj” (’·1|çÊvàÚ9¡Ë½Få"ü«­‡v+ÚŽ3$|¬å¯Aþ»oiü:6¨± Ëêw·ì–µ"^L‹6IÇ6• ƒQ?̈ Ïþx/)nh uVßàò1JÙû�ª—Çx“8EïõòZ´ºpÖm«dìÉ—37uEêi¯#º ÜDG¶É?Ô“¸<ô°F¢ÖønAUœËa4œ4¬›0lÍ߉Ÿ+†ƒN)Ë7+èû t¦Î—LßrL�¨j<%‰'o'Çl¹ÔôsžüàK�rSÙOÜ8"öƒ0iÌ+ÒJáé#jEý@mðû8wvŠp)Œ—À쀷¤-Z+ãຉ6u?è#|yQij­ã.�ì1# K0ù„MÜ„.:jh°p `bØŽ?Ðæ’P¼õB/²9O¾û2Å.¬ÿ¤6Ýæ>u„'©8¤7¼u(�$Ð ɘ›i¾})sî2.ß3 ïGŠËGdžà Q-äÀeà¸õ£ÉAç¡)zT<�Äb÷Å<íÝEí¨ìUsà\‘~ ›—›}t@¡§±ÝíaJ‘°Ç±aàqáÙ÷ª ÷Ä@‹$�ÜJî€hŒ,�bÒ·û¬§ˆÔíR,3¸ë_sÓ¥¹²³z,c鎂Ÿ_*¡kVߣ¡ùÄÿd Y^îTdÚ°«)Rk÷m¤§ÝßîÜ×ûUŽÉíÍ}¹d �ÎëvÊd.ãÙ07®’ðSH1Y"¤ÁÈЛHc±Tʵ†ÑÈoñ˜<èÖF|ý$7R5�Ñ<à¸y?B÷×-à|°Fh0½}¦]�Z yoͶÖKc½½mHOw¢…+šÓ I)nW;)ÇÖ`D½Í÷Д/i¢ÂúÓ8RxöHâPÅ�÷ œÐ¸ ›F×qò¾èúª~}:h˜&�0'Þg¬dp ^›öÆ½ÏØ„«˜ȽÛLÌè&,q)%¸ß‰ ê¾y1š÷ÃX©Eá¬&þÂ¥Sj®H´M€5ѧe韘3üwð«Gj 6ŠÇ[=`ÍÃq.cNØØwEžP;é"¾Þý`òK·D^>O¶AD!34ràKÈ,•%í! •Ïšw…R0£‡D豎4ct)ùDÒ6]?iâhæ%<}8fO§…ò¥»OØL¡ÅÅÁ(ši´èåï”ÕW|ÃǼ]ÞI§­ÚõD‘!}‚¨û·â~íByöwÊx¸w4ŒòÀÂzP‚“éyï›/ #>x~øü6˜S]‚C§Ð„Uš�€l¤´sÑß@¦¼;ÂsEß�ŽÜg‡ôÂw;³`­E])Äâ1zŒá³«Õ¡dÔqv*xá€Fzv@ßé’¼¸±õ+¹@Q‚K^‡z¿ÞÝçD ü)c¡H0tn ™ö-÷ÇÇÌ <—Ñ`h‰ý2ÖÄ#$ŠMAèõàqè§2­ßÌÛ+s£ÞòF£ov!ð¸ÓFûŽ3$c¨ÝÀ˜Þ„�8\ Äè“ ¶�tnX´2 ‘GÒI\§BÉûž,mèzêÆ;])¯0^g¦Ó ø& ã!9nœÞ±cg«¾uDßðuŽÎ²"UåÎY�¹ÃCñÔ)8„ ƒ æð-ÓÑhçKqM ·|{eÒIA;¾ë•¨rÿ�Ç|ç3Fe(Ì£³-QÛtµR©áî{#ÎÎ!z»F+uNï½;ƒ.ÿ”,»Ò¾ùFšýÂlßîAÿñ@pÌ ÿ˜#‚îâ•1 pHYs  šœtIMEä 6Þ)ųIDATxÚí][�iZþ¾ªr•«\>´íö¡�d“žY%“Lv4ƒv@«Õ®´‡]®�¸à!¸Cü.¸á? !.‘à �@€�˜ÌjÙ•F“%³É$=éö©}(W¹ÎG.žîok«;wO·ÝÎø»ˆËmW½Ï{>}úô)ÙœÕnC‚ 6gÀ€ÍÙ°`s6lØœ 6gÀ€ÍÙ°`s6lØœ oôVûóI’°×”Ò Ë¦~E¾ïSJ¹ÔùZá±b pg6›ÅqL)åy^„\.'Šb.—�ã¸7††¡ëºq§ßäy>—ËåóyEQ$I®äÄq†!&!×uMÓäy>ŸÏ‹EUUEQ|#¥aõF8 Ã(Š2™Û¶ ÃPekk«X,ær¹7 †«Ç1D! {`¨T*õz]UUJéÊS‡aµãº®mÛžçA�‘ ß÷-Ë2 £ÝnW«UAÞ V ¥TUUAë8Žá•š¦9›Í ÃpÚ H’Äu]˲vvvÚí¶$Io+–FA„<Ï‹¢X(ªÕªiš£Ñh2™˜¦Ç1 „xžgY–ïû7oÞ”eyÝ1 ×³9´ö}_×õ^¯7 <ÏKRGÅÝÝÝÛ·o+вZ Nž]À8 ×”/(%„ˆ¢«[,_¼x1�Ná°&IâyÞ“'O!»»»ù|~U$Iâû¾ëº„I’r¹ÜyƒGáZ‹'¥”RY–oÞ¼™ÏçŸ>}Úív£(‚Áð<ïñãÇ<Ïïî¸’ &Ïó<ÏK[µsap­`w%Šb³ÙÌår„�/^„a˜Ä!DsíÇ�+ŠÒétxž_~ã8t#ÇqA€î‚ ,~1kÀÑ… B­V»ÿ~ÏŸ>!‘OI¢`t`ý¼P€Ý^š"õ=σŸ&\=>oÈÕjµضÝþ˜ÄaG$‰÷ž|S±œt¬®eYŽã„a˜¦8²[L‘rºk–äây¾Ñh¼ûî»JíFâ[$°ߊçƒÇ�f’zWG}ÇqlÛΤAkD3,¿òú\ÀÚ9Î<ÏïììÜ¿ŸæäÄ·ßJ¼¹õâ'OŸ>…:¾Ò_�¢È¶mÓ4]׉)¥@`࿾ïA°ÈŬ”Ò|>çÎ�ö7ßO¢€vz±3{úäñh4ºR!€ëeš¦eYa‚¾pÉØ¿çΆ­eôHi¹\~ç�wøê�$ô Á‹ÿzþüù‚|w1ê#bYD�çyð>‹Ò‘U¤”¢ ´ˆAZ×BÏóívûÆ7¿! ¡;³gÏžÍf³+Rýàýù|îy¨ г<SAÇ-+ÐÞ~ûí#!=Øþ‹�†Ãá‚Öï¼á®mÛº®Ïçó8Ž9ŽËð>;Fýñ5.õÁ#*ßù5ù0Åáèûûû—kŠáò#nš¦ïû 2ãzvIP><Ï/è¯1”ÒB¡pûöm"ªIà@õ^Z–u¹ìï8Îd2Ñ4- C(øšƒÞGGÁâáÈz»Ah6›Bã‰Ã$ ’Ð ‡?7 ã²|!\º®†aYT?sóÓ*¼¿¸í½iY»&‡ã¸r¹,4ïGaäúÄó¢°ÿ©¦i'UP:•}.Ã;™LF£‘çy +¨$€¹žè¸@�HXœú®ë&I"IÒâ n G–åúvÃâ!Ät §õu]Ï0 ¨õ�Ö£×Þªoº®kšfŒ*¸äÆ¿HÉ¢x±\ô¢€|ßì²,#ÑqÌ@.—+—ËaDlŒB ÃH³9¢']×G£QEår¹R©”J¥3nnÏt:E= Xã õ !¹\N–å|>±2µ°õXCâÇ!„(вäôï¾�ªªb±Ê9Ó8!qB ¬Ó‚«iÚx<îõzA8ŽƒªP(œŠA’$A˜¦9�N5MCdÒGQ7Ÿý´$I’$åóù ç…Eœ0P 4Š"Ó4 !…Báš4¬I’DóeÛ›†1‰cÂÜP80º®ƒÉdâû~’$º®3m^*•2º÷«ëúd2ÑuÝu]ð5þ‡Ä'Çq¹\NQEQ¾J‹†ðÚÌßÉà>Š"Ã0®<ÏS±Àq„Ä„ùã}]×Çãñd2™ÍfPÐà\6ä€aÀòÌP>¶m³l3$„F/“(в,˲ £xqGîµdrL¬D×uŽãV^•ûˆ¶ß~¿?�N]×å8…CI’|ߟL&p"™à¯æóùd2™L&óù´†ë´XÙ�Qÿªÿõ¤›Óo²¶mÃ/^yoH†‰o1LJe�r4�Çc0 !^�(ŠA°€”U…âº.xß0 Ïór¹ˆ›‘Ö<², EQ¾z«¤p6ïgüèÌ Ó49ŽÛÞÞ^mç¬ïû‰=‰DDEß÷G£Q¯×s]—Rêyc&˲¯BàGâc¶m�Çcô^àÍL¿ ¨/I’,˪ª^J7Æ+€ÍÁ¯žìׄÌâ*qK«rŠàš«ÉB¡@)e¾Cšiâ8†9Íår¾ï#¼â8β,Žã`±Ç¾_š÷ñII’Э�Ïç/e|Ax•  —žÑEðüòù<>°Âþ}¸Œ³Ùlj’ñœBD�”J¥\.W©T<Ï›N§–e‰¢(Š¢ã8Ð<¨jÁ¥qg:�Bã£1’çyÏó X¥]{p{*•Šªª—�¾ö\�1”R„Ýà¬êÇqÆÃžBˆÀ“�¦R.—EQ¬T*L^Ç@�¥BŸpÔN†pl0¥Ç/Š"6/źÄJ¥R©T* —¨r_ˆ�ªˆ Ý+ÏIÄq<›ÍÂÞ'aD!"O„Î[[[`yhBÈt:õ}Í[ŽãÄQ˜Ä =7 (ŸC£#˜ÌuÝ´¸³{‡¿W«Õðå—x× e €éwp¡+†Ã0 Á—?vƒ# :”Ëe\š…ÈqÝÊu]ÈÇ Qè%Q@“8Ibß?º;0|ÿ4ûçr¹b±ˆÆ¥»|‹¦t2ÌŽ–¼Õ:?pþøâ‹/,°š'­Î­B¡Âñ<ÏÀà8Áð‘" Ê…„!qè».×#ÙÀT?t¬,ËÛÛÛµZ nÏ €Mæy!xʲ,d„V…AEÃáÐ|òo¦{d~;oݹuëË UUA\D”Žã¸®K9>áE’Ä„�$Ž¢0€?šQ¼*•JµZUUõ*¤•”{X*îÄqŒW¬„ýmÛ~òäI÷ÓŸÀ+"‘îý°Õj¥cF(¥ãñ8 ÃDÊDZ>0 ”ƒs�pH€÷ëõ:¨Eâ¾(P…ÌóE~Ê0 Y–W"Qõz½þ'ÿ25IœŽ’[Ûd÷Jåä•g䦨qB9Êñˆx˜·ƒ‘é,‹µZ­\._Ý4Î9@)Ó[8–eÍçór¹¼d�Ôüä“O~ö0¿jž¨ïÿþ[o½u*Ÿ¦åä�F¸„l_ÙžR©T­VÁþW蜣®¦À0Tdš¦!4_fg²ëºŸþùáG=ž±ÿí¹ýÞ÷šÍæ«(õ*9À¢r<¯‰ÛD–Ê'�.]1à I’Òž²iš“ɤÑh,Í# ÃðË/¿üß�þù‹ÿ{ö¯(¤øëtïÞ½³“3§ÊØQ3¼²,W*•f³¹µµuÕã˜ç«,ââ�Û‚=H’d:� ‚P¯×—0:†a¯×{ôèÑËÿüÛ™}äü¼õÖöƒo¿Õj½VQ€¾ˆÐÎ�‚%ÜS|@’¤­­­jµZ,»eÊ!«‰ØoCá ©ÂÑp8¤”Öëõ+•Ö0 ‡Ãá£G�^þÃ_ö´#å³³Ejßÿ³»wï¾67ÉèH)-‹»’$AÃ2 ”RUU[­F‘3!1‹ .Œs×ÖÑåû>"FÏóz½^Çõzýж è}ôèÑðÿ|otDýz‘t~ðÇ~øákÇcÒͳ„AdY.—Ë }Ežç ‚P,±!ŸÏ#'Ÿ™¿H¿`_{%™³Ý!UU�Ë•;޳¿¿A£Ñ¸Ü±Ed†÷÷÷?þøãÑ?ýÅgûGÔ¯(d÷7~ðíïýö­[·IФ›È b¢(šL&’$5›ÍZ­&Šb†úLAeâäe« †Ø¹x–Jtgooϲ¬v»],¿º:¥LÓ|öìÙO?ú÷ýý«ƒéõÕ<ùæï¿÷[x÷îÝóÚƶ’$±Œ:rœÛÛÛ¥Ri™3—lï�"† ˲XÖ0‚ýýýÙlÖétêõú…«l1Áp8üì³Ï^þøïŸÿìcæt–dr÷ƒ÷üèO>|ˆòË‚Á<Ëà"ñ�$ ŠºÅb.,r¨ìvÒÑÙ©*heà~TUe5z¦‹’$Aa¯^¯c±†,Ë N‘ƒ7¡‘'“ɳgÏ~ñé»?û›þ$BÏGIU%oøÝoýΟ<|ø°T*-HFt`�îQL Ы ì«è¾#œñJ‹Å".µï´YÞÛÛ;88¨V«P¬…BA’$¦¯Nò;Ÿß¸q£Ñh\iÚçª`E£ÑPe8‡CÖ‰Æq\Z’Dñæ±¶—N8Iè‘Ðe/Ñ1“öy2?Á¯[­Ö�7*•Ê2›Ž¯ûÖD`°µµÅ=�1ªŸÞë�¶É 26€§ý%6«t*ï …V«µ³³³dê“5ZÜ ]aÁ©ËCÐ5ŒÑBÐïê‚FåB¡°½½}ãÆ�ejžu £‹xžïv»(®±!Þ“é6@EN{0GzþPÅ���UQŸ¬ÑâÖŒ.‡A ™sꎲ“=ÙA¡"Žcì<ît:«¢>Y¯Í¹'uüúSÙ¢-MÓÀû¢(¢i'ñ¦ÿ û‚`lÙ£¥Î@�0h‰¸”áª7€4õmÛfù†ôˆK†ô¬I K#t]‡†Y¤éܶm*/ áúS_×uÏó˜£yªæÝ!5ÅÖ ô¡ Hf¼Š²lË4!di×™úx`”ã8ÌÕIÓ=ó‚m„õñyöømTäiʳm›í([µ¥¾ã8pöÓžÉI¢3æM’DUU (0ÂŽãð†Ìò»Wýºçy†a`÷ª1¸¦€G±}†§–Ùkh,SͬÖGÃ�,ËäxË)¦‚Ou^™vBÃ�išøÚ¯£ Âð^ziꩌ�O¢—Ô?5(AQX‘ôÒâWö�¤K ÓÚ�Ïçñ¬xý'¹>ýN>ŸWåì-æxÄ2qi“~êAßµ¢(XNûµz<ËžšvR¡?ÏOÀHþÙ_‹…S`pÈÁ©€EQ„Ç2@›}}{C¡»1ó�Q,@O®(Š Î–Øh™¯Åg°�þk톒ã¦A°6[OÄ(…¹"L5�k²—ÙìqeÐ"ŒÀ“B±HwÓz„’ (x±X,w|.@&ôcáÛz„ô*Zê6©ˆ,äW×Bùœô&ܘ…ƒL*ó£Ø“Ø–¼…óºç‚ÏÂBK¤ã4éyH[:”ƒx¡uÁc+[7pФ¥áÂ;œÓ+÷Y—²u+i˜¸î6 #‹ÿÕÊ'ý�“žè¦ C.�"×ð9O¿ôÈælذ96l΀ ›³ôóÿ¼Zô½<¡IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/volumeselector.png0000644000175000017500000000276514757047403027225 0ustar00paynopayno‰PNG  IHDR0$ÏE¹ sBIT|dˆ pHYs°°œÔtEXtSoftwarewww.inkscape.org›î<rIDATX…Õ˜klTeÇïûžËœ¹Ð0­$¥j14¢"n7ênHº»1&J‰ 1q㊄àºn4ÊÙ„(â†,° ÂÇ]ü`LÄx‰~ã…€àeÕE•¢ÝÒ2ÒéÌtNçÜÞýЂeèÌ8Pö÷eæ¼×ÿÿÌyžç=#}ô…ÇMSè‹/žn%“I„PÂ4¥ˆÅ,!¥ÔŽc¶­†,Kö™¦uÈqš>Ÿ=[x\ˆuëÞ~ ŠÀusHÑÜœ¦½½ �§ 6 )Á¶Mí8ªdÛÎ`<®ú¤tv^q…ÈO†ãÄ)!‘˜@±±oßg,\ø[¦LI‡J¡Êæ ¿TŒ÷÷í´,Ìêù÷^óÏ îé1"a‚J(tB  ”6u"ž´£;îì>æ+¹¿siwoà ”#¥dêÔô¨– |¹gOsïëÛftŒ Ô—Ï0#Ï ˆNl‚cþð¡¯L`Ù¾õ[J*™Ê(;vDÅâ ‘zÖÝ7dj ,Ò¢@ðK>ÄU‚&Û"®Î¼tTrí¨ä¶ùÐÌîûhã¶¢‘LýWÆœoµ©¾8œ3öv¯è.žSã‘hÒ¸ºP„Al\'i9Ä S¨HÄã 5ˆB „„è("(äãÞñ;4ºƒÀ[ÐúÑÇ[·¿øË?ÞûÜy1PNŠ©¨D!ÔtN���ûð½Z–�NÛeMª[áÂÿ¿ß/U,HJ%ôùS2›Íý-“)�ʲŸÖBLޤÚ�›6-u7n¼ek~§çé IüÂæd lÙrë;ù¼Ø’Ï—&åHP/§¤Ñ nÈëzè•ÛÓéd'c=/`xØ ‹Å’_(Œ¸Aà88ì‹3…þdˆ‡3Ô�Í›½¼ví›{wíúºE)ïèòåsúËÇÜ÷«ÛçÎqFæNv¤Ÿ±�­^}c/аC×¹¢î:`VYÃfꜾ7Ôm õƒ_ì0;vŸá°z’eÕ»G5Ôm` k¢§wþó¯=æìME‘)ªR¬VÞ²rjËÈñõé oZyŸŸÁµM§?E¡�F Œ„’ !…ÐB‹òû™üÍ­=~ǯ÷Ú¶ì7MÙ388ôåüù3‡nà«,`Zé››Á„¡¬HYÉ×:!A)‰�£Fâ]ÝßgZ®þÏøy–e…Éd,gâX:�þ®‘$ œÿ`çôðÈ*'ÌÚµ(Ç4 .ºié»sÞ�‰6ý¹à6à%@?óÆ3ûd.ÿÀÑ~¸ÚX.1ý#MÁbš{H¶g‡ftõéÖY}Õlþs˜< Lþ¬ßùȼûßjû‹æ¤<5‚kÛuC+룲#ÊÑ~K{k”¼(&›rB'�ç¹ë®›«P¯�yÀ:àú±k Ì–\³d‰µfÇŽÓž¡eËþqõÌ™×,ª´x-j}„º€]Àü$`ÄTßHª5м¼ ü®BÿƆ)ª‘j œ84ìrú?ö4LQ�Tc Þc4ÛeýÛêÙ8 ­BÅ?ÁÇIU]Ùk‰�àyÀ>kk«™íÛWîízaxØ+¿!„¡8ûkÕhc4p›�%@7Pþ5öY[·.þúرÃ2™Â‘zרÆi £ÜÜÏhÆÉíÀfàx½›ìßÿz´{÷óŸ^uÕ�yÛ–JI’+¯¼´ªùÕ�£â¯þ>®¯˜°RÖªU¯¦Âк§¹9™^¼¸ëd»çärn˜Ë¹¾ç•Ü‘‘ ïûaÖ¶­ãg3`¯ €ÕÀS�{6žxb×õ—\ÒsÝ‘¥Ž®X1hâY§"€—­°“–ã«ál1�€?�'-uñ?ší˜K´u#IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/volumeselector.svg0000644000175000017500000002527014757047403027234 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/volumesymlink.png0000644000175000017500000000354714757047403027072 0ustar00paynopayno‰PNG  IHDR77¨ÛÒFsBIT|dˆ pHYs°°œÔtEXtSoftwarewww.inkscape.org›î<äIDATh�ÍšklTEÇçî.–Š(ˆ¢"åmEMÔ(F‘ÄøLô“Æ’ ö&WéÚî6H|%†D?#&F¢¢ñ�  ò°"ñU©ZÚÝ㇙Õ˺ÛÞׂÿ¤:�9�{fΜóŸ  ª’ɤgIBæ«r08 èÚ€­ˆ¾ÒÕÙ»ÎuÝ® ² p]wÐÀ�®©«k|5Ìz/ÄïÄL&=[…f ÆÇôÐgNHõ6/ZäþáW‡ëºUUÕ©µ ŸÕ×.mð»® µdÒ/ªðþ RÛÝ“ÚÑ’Mß§ªý~ÄU«V¥N¨N½\íSG¿èÓ¹lvÙØªêÔ§·…”? x*Óúèk+V¸§”›äº®sàà¾çæ‡ÔSe�kZÞ4*‡óp~ znèîM}–nMO*þƒªJUuj%pGaLD|—¾PÒ¹Çs‡&sò¶Àè8” ŒK(š—7O÷gZÓYàÞØôxPÒ¹#=©§�ó* oˆäòo"˜iM?²¸zH´´>zª·TJ!0,¡¬oÉ6=¯Jm© ~�¹æææ!¨¶Ä!¸ )逈hJŽŠœ$r� C‹æ^Ù¨ä÷9ʦ¡\�Èt*€¸"÷�séé3éa¡W°2ß+766¶­{ ¥¥éRD–"̉ØâÊ–ÿ8—è‘{@«ì¯‡äÖÚÚÆµ}-®¯_ú0·9Ût» �cJ±ÿ €5kÖ$½ÛŽu‹2¯?Ǽh¨]ú"ùÄE ›+beH8»ÚvÍV "÷ÕÕ-y7¨ úúú=Ž&/GXÕ¨x³¥èõ‚¼\÷`ãê°ÂêêêþìêìY²>ã¢ÂÕ¹@GoJï�*ÐuÝ®„¤|VF²§7Õ'›]68tå’EK~ŽCèâÅ‹åEw‡]?ì·ö³®P8#ŠN¹èÊ¥ä‰(‚¼È´¦³¢rgØõ¿Ž8k7°8Oá:…1ê£=+F•©ÏƵL¦i¡ÆP/ üü¢0LVøøN Û� G„Iù'£�mIߥ}¨þ{‰ tlÞŽ×*ÌR(Û�h¯­}hGTƒV?°ð¦}¢«!žê¢=Àv…ÀH`¦-@¿~SQ…¤ÂQ”* Xã¼Û¾8}ø*ùO—7òÀ`�ÂPLk6Ea7°Ã~’šs6„U¤0æ«™5ó¾¼ôâGTœªþWø„ø»Äö+ Æsöß t&Ú‚êVÌøùœ‘κ›ܬâìÇ(*LˆÁY=d¶Àa`‹Â6L$ç+´:j íÌžÿH – Φ�ÀÁ@gD Wá,L�7Y!!fW(œ\„ùøïc€d˜Ð|‰¹k&(LÆd¬ìa?fPC*�&_ ìôŒkçr˜|s˜aöùD›¦wŠ™SQØ{îbÌ|SÀKß ” ˆ| $9.¹ˆ†P3VØ¢¦IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/icons/volumesymlink.svg0000644000175000017500000001323214757047403027075 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8931005 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/tests/0000755000175000017500000000000015153325403023452 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/control/tests/__init__.py0000644000175000017500000000000014757047403025563 0ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8931005 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/dataportal/0000755000175000017500000000000015153325403022763 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/dataportal/PublishProcessedDataOW.py0000644000175000017500000001313515153325210027652 0ustar00paynopaynofrom __future__ import annotations import weakref from silx.gui import qt from ewoksorange.bindings.owwidgets import OWEwoksWidgetOneThreadPerRun from ewoksorange.gui.orange_imports import Input from orangewidget import gui from orangewidget.settings import Setting from orangecontrib.tomwer.widgets.utils import WidgetLongProcessing from tomwer.core.settings import TOMO_BEAMLINES import tomwer.core.process.drac.publish from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui.dataportal.publish import PublishProcessedDataWindow, has_ewoksnotify from processview.core.superviseprocess import SuperviseProcess class PublishProcessedDataOW( OWEwoksWidgetOneThreadPerRun, SuperviseProcess, WidgetLongProcessing, ewokstaskclass=tomwer.core.process.drac.publish.PublishICatDatasetTask, ): """ This widget can receive 'data' (scan) and but some screenshot to be pushed on GALLERY. """ name = "Data Portal Publishing" id = "orangecontrib.widgets.tomwer.dataportal.PublishProcessedDataOW.PublishProcessedDataOW" description = "Publish processed data to the (ESRF) data portal. \n To execute this you need to be inside the ESRF network" icon = "icons/publish_processed_data.svg" priority = 64 keywords = [ "tomography", "tomwer", "tomo_obj", "processed data", "PROCESSED_DATA", "publish", "icat", "icatplus", "pyicatplus", "pyicat-plus", "drac", "data portal", "dataportal", "portal", ] want_main_area = True want_control_area = False resizing_enabled = True _ewoks_default_inputs = Setting({}) _ewoks_inputs_to_hide_from_orange = ( "__process__", "beamline", "proposal", "dataset", "dry_run", "path", ) class Inputs: # redefine the input to allow multiple and default data_portal_processed_datasets = Input( name="data_portal_processed_datasets", type=tuple, doc="data portal processed data to be saved", multiple=True, default=True, ) def __init__(self, parent=None): super().__init__(parent) SuperviseProcess.__init__(self) WidgetLongProcessing.__init__(self) if not has_ewoksnotify: raise RuntimeError( "ewoksnotify not installed. Cannot define the PublishProcessedDataOW" ) self.__on_going_task: int = 0 """used to know how many tasks are on-going (as they are processed in parallel). Used to display processing wheel and processing""" self._window = PublishProcessedDataWindow( parent=self, beamlines=TOMO_BEAMLINES, ) layout = gui.vBox(self.mainArea, self.name).layout() layout.addWidget(self._window) self._scan = None # load settings self._window.setConfiguration(self._ewoks_default_inputs) # connect signal / slot self._window.centralWidget().sigConfigChanged.connect(self._updateSettings) def _updateSettings(self): self._ewoks_default_inputs = self._window.getConfiguration() def setScan(self, scan: TomwerScanBase): self._scan = weakref.ref(scan) self._window.setScan(scan=scan) def getScan(self) -> TomwerScanBase | None: if self._scan is None: return None else: return self._scan() def _getScanFromIcatProcessedData(self) -> TomwerScanBase: """Return the associated scan to the latest set 'data_portal_processed_datasets'""" data_portal_processed_datasets = self.get_task_input_value( "data_portal_processed_datasets", None ) if ( data_portal_processed_datasets is None or len(data_portal_processed_datasets) == 0 ): return None else: return data_portal_processed_datasets[0].source_scan def handleNewSignals(self) -> None: """Invoked by the workflow signal propagation manager after all signals handlers have been called. """ # update the widget when receive the scan (proposal, dataset...) scan = self._getScanFromIcatProcessedData() if scan is None: return # update processing wheel if necessary if self.__on_going_task == 0: self._startProcessing() self.__on_going_task += 1 if scan != self.getScan(): self._window.setScan(scan) super().handleNewSignals() @Inputs.data_portal_processed_datasets def add(self, data_portal_processed_datasets, signal_id=None): # required because today ewoksorange is not handling multiple inputs self.set_dynamic_input( "data_portal_processed_datasets", data_portal_processed_datasets ) def task_output_changed(self): # update processing wheel if necessary # task_output_changed is called when the ewoks task is finished from __ewoks_task_finished # call once even if there is 0..n outputs self.__on_going_task -= 1 if self.__on_going_task == 0: self._endProcessing() return super().task_output_changed() def get_task_inputs(self): task_inputs = super().get_task_inputs() configuration = self._window.getConfiguration() task_inputs["beamline"] = configuration["beamline"] task_inputs["proposal"] = configuration["proposal"] task_inputs["__process__"] = weakref.ref(self) return task_inputs def sizeHint(self): return qt.QSize(500, 200) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/dataportal/__init__.py0000644000175000017500000000067414764622416025116 0ustar00paynopayno""" (Ewoks)Orange Widgets to 'control' the flow. Like defining input / output, stacking scans... Those widget are not doing any 'core' processing. """ NAME = "data portal" ID = "orangecontrib.tomwer.widgets.dataportal" DESCRIPTION = "widgets for data portal publication" LONG_DESCRIPTION = "Contains widget to publish data to the esrf data portal" ICON = "../../widgets/icons/tomwer_data_portal.png" BACKGROUND = "#C0CCFF" PRIORITY = 13 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8931005 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/dataportal/icons/0000755000175000017500000000000015153325403024076 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/dataportal/icons/publish_processed_data.png0000644000175000017500000000546214757047403031333 0ustar00paynopayno‰PNG  IHDR+´€£•sBITÛáOà pHYsÃÃÇo¨dtEXtSoftwarewww.inkscape.org›î< °IDATX…í˜_l[ÕÇ?çÜkÇq» Iœ&¤¤%@3þetB õf“ö0 �®'ö€TE ”'¦=úz{ah“*±iLš*]3!¤!$¤â›Ieª”Vˆ�R…¦ i\'qÒÚÆ±}ïÙÃáâ”²Š±N{éOòý{îï÷=¿ÿ?J)å8Žã8J¹®¾W ”²,Û¶mÛÖwú ¸®RP( Î6‚W_Ujjêðá¹¹�ËvÞŽá½R–U( >ÓçÎÑq:w_ýô£íL;:¸nT s]Û†ÎÙqàé§ß|~ðƒ¿þ~ØuáW¿š››šzõÕÇmÛýŠôWJY–e –eYŽsø°ÞºëjNŽ£¥v¶*N J�eårŽ“Ë9d³úçºB<û¬mÃȈZ#pð ã8Ι3ËËSS¯¼22ò³ŸÍÏ¿ÿþ½÷¬¬@OO*ûö=òT*¦ ñx_ Ÿ:•J*++Ÿ==É$¼ðÂì¬mW«/¼�N‹áÖ³Y­,MB(%Â…x€eMOë§¹\&£Ôäd>ïy¶ ÇŽýñ�02rç�ðöÛ»wC$bkkpÏ=ããpúôæ&4AJ@«ccÝÝP./,ÀƆR D_(ÕhÀO´Z…ÂÁƒÓÓ³³ÓÓŽ“Í*•Í‚ç ÓÓJ™¿¢·×²4þ\òùÉI8{vÇøýï�‡åå�(wí‚F£Ý¥¶¶ ^_X€¹¹ÕUh·ûû¡«+�¥„€f³VƒsçΞ…ññ±1¨×K%h6ÛmX_ÿøcË:xpb¢····cÏ\.—ÓW_iµoÛ™ŒöL!¶›^B>¹œŽcY³³àºù|>_(8ÎÌÌøx*•JÁþý?ÿ9LMYÜu×ý÷C$"D(¸TÚØ€¥¥ÕUøì³•h·ƒFGS)xüñþ~X_ÿè#XZºxÞy§T‚­­+Wà©§þñ�|¾XL§‹ÅLÆqr9è@ÌåÂ+iYƒƒ¹Üä$LNær T&cÛ®;=mY¶}îÜü|£KK‹‹páÂâ"\¼X*A»]¯Äã e*±ØØÄãû÷ƒ”ƒƒpîÜÚ|ø¡”�Ž�C_ßÝwC$21gΔJðÚk##¦/M.¡M¯ÈBÁ²l;Ÿ×‹óyÛ¶mÏ{è¡/¾€­-¥ ¿ÿ~¨TFGÁ÷ÇÆúûÁ÷MÚmÃ¥ ¤4 0Œxâñ�;¡RÙÜ¥b±ðm$ÒÓ¦98…B_ŸNH¡wvȶóy  !„pœrùèÑ¡!ϳ,€—_^X€••Z Ö×ML³§¤ŒÅ Ñ"¤Ôg€ è$i!‚‚À÷Á0”‚­­J`` ¤Ù„®®K—<ï™g>û,�ö¼ññrfgÁq<¯ÝN§áôi!„�Z‹a¢½pab>ýta‰D„ØØ€žž”VË0 ´'i@AB7M€v[ˆh­æû¡“øþâ"´ÛËËàû››‰ŒŽ¦ÓÙìóÏ‹�Ëe³09 ¹œãh§Èf³YÇ1]×qæç+•lž}¶ZM&º»aß¾d‰xΟ�Fáòå­-ˆFµá4!Bpš4( Z©fn¹åË/áŽ;à“O¡Z]_‡ÁÁ�˪Õ&&3™ÉI­0m‘ЄKªÔÉàØ1€‰‰¡¡R©·Wˆ}ûàÝwËeøç?[-¸r¥TÃð}�Ò÷¡ÕR*ÔœÖëÕÇjL3 ‘èî†bq~êõzî»ï'?�_¼|YÃÉçÁuçðá¹¹\,KûfHss_çQ×"Ÿ·m°íéétº\ö<Ó¬T@Ê]» ][!êuðýT |çNð}ÀXLï»^‡F£ÕØÜ„®.߇v[{y4 ­V³ [[¥üò—>ÇŽ�:¾B´ZðØc°gÏ@&cÛŽ£”Ò¶óy!4D]ë=oïÞóçA�Æc1‚h‰;À÷WV  ‚zZ­j|ÿÊbi âñFÚmXÃÃ`š©D£ÃáO¿ñƧŸÂÒ’iB«5: �F"û›a8N&cÛÚ ´SétXŠÅ£Gô£½{Á²N�‚ãÇ'& ÝnµÀ÷Ûmèëëî†��dÚí+W@J! oµ`x¸Õ‚………� €[o¥"‘p¥Rõ:H¹¶õz³ ÑèØD"ƒƒ­áû33ËËÇ�çóB¼þz:=;kYF±èºJe2¯¿^,zži>ñ¼õÖ-·@¹\©tXû>øþ—_ÂÊÊæfF­–6hµ ýýµxÞŸþ]]=‘H2B ‚všÍ àöÛ X[k6u‡&µjµ\†={ººà7¿Y^žŸŸ™yî9Ëšž.¤®©Ù¬îXŠÅ\Þ{¯^‡ÕÕj†‡»»á¾ûöï‡ryuLstb±Ý»AÊ�"•‚3g–– TúóŸáòåãÇè¢Ù„ øüsèí­ÕààÁ={`xxhjµsç Ñ8{úû‡†à�ÓiÛ>z4 &¥„�aùË–ã€ï'“ ÄÈ|òI¹ .œ= ¦©T¨ïºÑaT©œ>¶mkk¿û¬¬üá°¹yþ<$“ÝÝ09¹k—RëëBLM=úè¯ ?üám·Ám·íÚ·Þ:8è80=­[¼°Ö ¡”оî®Ag°C‡––àĉ¥%)á¿8p.]*—áý÷«U¨×ƒêõ‹¡Z=qjµ·ß†jõäI�òµwJ †qèСCwÝU©T*{÷j-•Ë33ù¼çi£—Ëù¼ã‹™Œ~›ÍêL*Ķ:løu"Û¶m×…™™K—&&^yåÈ‘p†q]×qœ¹9ؽûÉ'¡»ûöÛ!™|ðA|ôQH&ücˆÅFF„BÃBÊhTJÝ|è‰*lD:W¶­ãüê!äë™J_ê�-|ÎIáü>×M&µ[¡ã]î·¿…ÉÉBî¸ãï‡TêùçÁ0ºº„�RJ!4\�R)ûk U6ïWƒÓc’>r5òpJÜ>îuæÄH$‘R']6‰`bâµ×àî»Oœ�9"¥”]]¦©{&½^!¢ÑXLϬߔÞÁp-ÜoYªGáíc³.‚:xtº1 =+I�C*õÔS°{÷K/ÁððÓOÃŽccRš¦ijÍëcØæI)¥Þj¨ˆ«!^K_)[ûHÇg:ó}Xü¢Q °#V›Ñ0¤„{îùË_ I$À0b1!@÷�‘h¸a¥3Œ��ng4Üo×é7 jwþ€Ðª6ÍînÓÔp4ÛP‹Z„”ðÓŸê@sœ°3Õ`«xÜ0GÿÑ�Löôh±X,Bh¾ZÏR†@Ã,ôMè\»‡«Û¶ëÑ6³|+é�…ítÈ9„w=ž×’Ø.,4Èñú_]»™ï"åÚ¯äñûÑwáp-ùï–~?ÿ;nòúŸ]“"n0}wÎW…ÍÿÐõé»ÈýLÿÿ¥›@o4Ýz£é&ÐM7�Þhº ôFÓ¿ZC•’®Õ IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/dataportal/icons/publish_processed_data.svg0000644000175000017500000005373114757047403031350 0ustar00paynopayno ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8931005 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/debugtools/0000755000175000017500000000000015153325403022777 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/debugtools/DatasetGeneratorOW.py0000644000175000017500000001166514757047403027076 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import threading import uuid from orangewidget import gui, widget from orangewidget.settings import Setting from orangewidget.widget import Output from silx.gui import qt from silx.gui.utils import concurrent from tomwer.core.scan.blissscan import BlissScan from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.utils.scanutils import MockBlissAcquisition, MockEDF, MockNXtomo from tomwer.gui.debugtools.datasetgenerator import DatasetGeneratorDialog class DatasetGeneratorOW(widget.OWBaseWidget, openclass=True): """ A simple widget to generate on the fly and 'continuously' datasets """ name = "random data generator" id = "orangecontrib.tomwer.widgets.debugtools.datasetgeneratorow" description = "create on the fly dataset" icon = "icons/hammer.png" priority = 250 keywords = ["tomography", "file", "tomwer", "dataset", "debug"] want_main_area = True want_control_area = False resizing_enabled = True _settings = Setting(dict()) class Outputs: data = Output(name="data", type=object) def __init__(self, parent=None): widget.OWBaseWidget.__init__(self, parent=parent) self._layout = gui.vBox(self.mainArea, self.name).layout() self.generatorGUI = DatasetGeneratorDialog(parent=self) self._layout.addWidget(self.generatorGUI) self._displayTimer = qt.QTimer() self._loadSettings() # connect signal / slot self.generatorGUI.sigGenerationStopped.connect(self._stop) self.generatorGUI.sigGenerationStarted.connect(self._start) self.generatorGUI.sigConfigChanged.connect(self._reset) self.generatorGUI.sigCreateOne.connect(self._generate) # connection with the interface to update settings self.generatorGUI.sigConfigChanged.connect(self._saveSettings) def _start(self): self._displayTimer.timeout.connect(self._generateAndRestart) self._displayTimer.start(self.generatorGUI.getTimeout()) def _stop(self): self._displayTimer.timeout.disconnect(self._generateAndRestart) self._displayTimer.stop() def _reset(self): if self._displayTimer.isActive(): self._stop() self._start() def _generateAndRestart(self): self._generate() self._displayTimer.start(self.generatorGUI.getTimeout()) def _generate(self): scan_path = os.path.join( self.generatorGUI.getRootDir(), str(uuid.uuid4()).split("-")[0], ) thread = _DatasetGeneratorThread() thread.init( type_to_generate=self.generatorGUI.getTypeToGenerate(), scan_path=scan_path, callback=self.Outputs.data.send, n_proj=self.generatorGUI.getNProj(), create_ini_dark=self.generatorGUI.isDarkNeededAtBeginning(), create_ini_flat=self.generatorGUI.isFlatNeededAtBeginning(), dims=self.generatorGUI.getFrameDims(), ) thread.start() return thread def _loadSettings(self): self.generatorGUI.setConfiguration(self._settings) def _saveSettings(self): self._settings = self.generatorGUI.getConfiguration() class _DatasetGeneratorThread(threading.Thread): def init( self, type_to_generate, scan_path, callback, n_proj, create_ini_dark, create_ini_flat, dims, ): self.type_to_generate = type_to_generate self.callback = callback self.scan_path = scan_path self.n_proj = n_proj self.create_ini_dark = create_ini_dark self.create_ini_flat = create_ini_flat self.dims = dims def run(self): if self.type_to_generate == EDFTomoScan.__name__: scan = MockEDF.mockScan( scanID=self.scan_path, nRadio=self.n_proj, dim=self.dims[0] ) elif self.type_to_generate == NXtomoScan.__name__: scan = MockNXtomo( scan_path=self.scan_path, n_proj=self.n_proj, n_ini_proj=self.n_proj, create_ini_dark=self.create_ini_dark, create_ini_flat=self.create_ini_flat, dim=self.dims[0], ).scan elif self.type_to_generate == BlissScan.__name__: n_darks = 10 if self.create_ini_dark else 0 n_flats = 10 if self.create_ini_flat else 0 mock = MockBlissAcquisition( n_sample=1, n_sequence=1, n_scan_per_sequence=1, n_darks=n_darks, n_flats=n_flats, output_dir=self.scan_path, ) scan = mock.create_bliss_scan() else: raise ValueError(f"type to generate {self.type_to_generate} not recognized") concurrent.submitToQtMainThread(self.callback, scan) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/debugtools/ObjectInspectorOW.py0000644000175000017500000000212214757047403026723 0ustar00paynopayno# coding: utf-8 from __future__ import annotations from orangewidget import gui, widget from orangewidget.widget import Input from tomwer.gui.debugtools.objectinspector import ObjectInspector class ObjectInspectorOW(widget.OWBaseWidget, openclass=True): """ A simple widget to browse a TomwerScanBase object """ name = "tomwer object browser" id = "orangecontrib.tomwer.widgets.debugtools.tomwerscanbasebrowser" description = "create on the fly dataset" icon = "icons/inspector.png" priority = 255 keywords = ["tomography", "file", "tomwer", "dataset", "debug"] want_main_area = True want_control_area = False resizing_enabled = True class Inputs: data = Input(name="object", type=object) def __init__(self, parent=None): widget.OWBaseWidget.__init__(self, parent=parent) self._layout = gui.vBox(self.mainArea, self.name).layout() self.inspector = ObjectInspector(parent=self) self._layout.addWidget(self.inspector) @Inputs.data def setObject(self, obj): self.inspector.setObject(obj) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/debugtools/__init__.py0000644000175000017500000000053214764622416025123 0ustar00paynopayno""" (Ewoks)Orange Widgets for debugging. To be used at your own risk and peril """ NAME = "debug tools" ID = "orangecontrib.tomwer.widgets.debugtools" DESCRIPTION = "some widgets to help debugging" LONG_DESCRIPTION = "some widgets to help debugging" ICON = "../../widgets/icons/tomwer_debug_tools.png" BACKGROUND = "#C0CCFF" PRIORITY = 20 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8931005 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/debugtools/icons/0000755000175000017500000000000015153325403024112 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/debugtools/icons/hammer.png0000644000175000017500000000376214757047403026113 0ustar00paynopayno‰PNG  IHDR=;È;‚ôsBIT|dˆ pHYs°°œÔtEXtSoftwarewww.inkscape.org›î<oIDATh�í›ml[WÇ××/qb'v¿ÄN;éØP+¥íèš².mÙº±�¡ÑÀŠHËËG>𤠴!ñuŸ!Ä·nP m¡¶uëD;6UíT'vÒ8׎ã¸I;~¹—·iÉ‹í;ëÔŸäñ=çyžîsÎsÏ9×Pdà`ø ÕÉoÍèþ ü¸o�6ÏZwg§f”e xpÖ)>á´ɲ¬y\. Xž¾­Í75à÷k'‡†´'µ»]Æ€ûë/ §]µ4•$éþ�þ~¾ÐׇQ–ÍJ"ñàÞv¯·Øíæ‡zY–±64Ð ±°¸èLÏÏIàƒ­K)ŸjE€3Àà¾Ý»¹'ÀÝÞŽ×ífJQö‹Å/§LF£çèáÃ456þÏ©Á@°«‹F«ÕS”Ç4Mëþ¶&§<ªýKàä®{ï¥oçÎ[.Øššè I¥Ó¾ÅLÆ9Ðß�×åZÓH›ÓI§×K,ïË Oo³UÆT6ÕÌ¢?~ èï_·‘¦iL'ø<žM .//sþâEbв|x¹Š¸Ê¦š;ýŒÅbùüÑC‡�åõ»K’„Ýf+Ë Ñh¤'@’$K<™<´¡Ï ¥*âÛ”jD_)•JOÆÅÖáñ`1›…"I^·�ËELQö‹Å£èeð†«¨Ftx1›Ëõ…ÇÇ{mMM8[Z„dkj"�L¥:3KKÃÀeàš0T?‘-¿SU5½~ýÈb&cð{½ !A™L&vƒ”Tµ1‘Lž¬À9@a+u`xo.�œªAºû<ÚiJQ–TuxXÜªí­Šˆ/es¹=×"‘»Í†C`º·47ÓÝÕE|f&˜Ëåž.“[±)B4@ø½ªªZôúõ�l6+ù½^$I̺Âb6³#$»¼Üœš›òÀ?ªµ'J4èãí`dvnnpJQl>�³ t7 tù|Øm6CLQQ5m7pÈUjK¤èÆ�3Ùlv8 4Ûí8š›…ou8èôù˜ŽÇïËçóOï¢W”²©…h€yàÅ’ªj‘ÉÉ�|>/ux<ÂÒÝÚÐÀŽ`�ùÅŶóóßÀ‡åö¯•h=Ýÿ�L¥cŠbõy½˜M&!ÆeY&ØÕ…Ål6N'�ß\´¼A‹–ZŠ^ácàÌR6{`,ít:4—ùxZ®¶6¼.±x¼¯P,~ýñ5µQŸzˆýQò…R©d‹FÌçó’Oàì¾²²›K§½ ™Ì) |´^ûz‰=Ý—€o%S)M™™‘ý˜ŒF!Æ�F#=ÝÝ+‹–¯£ïê¼uÓï-ÔStð&ÐÈ™¥¥\81¶:e¯Æ6ceÑÒÖÚ*Åe©T:‚>ÎV·«—h'úA÷jßÅR©4�J¥n·°to¶Û ÌÌΖ²Ùa`=åuÇB¼lŒ øðÀm߯(”Éd>žLÊ~¯WXº›M&z‚A …BS2•:�¾ÅuÐê!ú7Àñu®­—3™¥±hÔ$2Ý ’„¿£ƒf»ÝS”êªîÎÖZôO�—ÙÖT,gÆ&&šdYÆÝÞ.,gK ¿%¿g9Ÿÿb-Eø5•íÃ=œžŽÇM$“&ŸÀtWU•�Ãaò…‚¥VÇ+ûПÆ7i·š—ÑÿQúIÉ­Ö]‡Øò]/ œ=wŽT:]«Å�¡ÏÔŽ ú\¾oþ�NŠEO8Ù àq¹ªšÝUUåÜȉÙY øðªhÑ-è›y¡ úŒGÑ)«)Æ•™™ÁT:mòy½7Ø�]‹‘÷ßgbj à'èÃMhÉ2¡Ì­¿þÿ¤€/´^›_X82>1árµµÝrZ²ŒŽr5ø-ðÌÊ÷"EoTšÖ¢|øWmg€— …B(�î’ †MÇùÕp˜/_ø 0̪MEQ¢ŸE?w. ø.ðZ}òÀ+š¦�OÇãÇæÒi“¿£c͇ÉXŒ —.\–W_!ú8•—¦Ÿ¿¨Òß(pöÆÂÂ#‘‰ §»½�F«õ“‹ÉÙYÞ¾pUU¯SƒÃ‚�,ú�+÷s1o"8€WeƒA{`ÏíäÐ�öä±cšÅlÖ€i*›LË&„¾7U‰à÷‹À$à‡Àr°«K³56jèU`¯@ŸÐ \¡2Áa`í3Û­³øúAÀ£µp`B_W"xø\-‚Y#6áHÀi*œŽÔ"˜zñ• V�ooK¤‚BQ‰èŸmK¤‚8Èö•¦m¡šÒt±¥©®|ÚJSÍ1¡ïW"8I}JSM�€¨Lð2wKÓ�E5¥é¹m‰TÑOö+üîàÒÔÃÝÒ´éçwKÓ�Åi*œCûw4a*+M'¶'L±t¢ÿð¤ÑÏnSŒ5Á‚¾;©¡¿cý™+Mq }ÌÞ.ü@Ì«ŸRö¢¿äº"ø zIûÌÓŠþÊÄ$лͱç¿ìŸS‘4÷�jIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/debugtools/icons/hammer.svg0000644000175000017500000000616714757047403026130 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/debugtools/icons/inspector.png0000644000175000017500000000177414757047403026651 0ustar00paynopayno‰PNG  IHDRàw=øsBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î<yIDATH‰­–KhUÇ3wî�¹Ï¹w’´‰‘‚¥�BKéC¬¨Pº¢©vcñ±hÁ�K܈nEéÊ¥ThÅ� ….b%Pj‹ä­A#µ¡I.ä>Î<79y­R­–Çq ™�LSø~Ôít‚o¦§Ï6›Í·²úyàx®�Áyà Û¶¿;?5õ©×h¸ Ï«yõz­îº•J¥R²Ƕ-+‡aŽŽÞ¾³´4&Óô!`°ØÏà]zÍebbâòÄáÉ纮çyµ!ÏsëõzµV©” ù|Þ0MS�NÓ4AðëÚúús[«�Á)è5õä‘#ËEÛnTªU§æºe¯Ñ¨Õ]·¬µ6ºB­µŽ¢( ŠÅðØÑ£wç›ZëaàT?ƒQÓ4×-Ë2ó–•³,Ër …|©Tr¼FÃŒÍ4MmÇ ,˲,ÓÌYù¼™ËåÖ¤”ÃÀX?ƒP×Z—•RZi­•RJJ©¤”ÒÃ@J)S) d/G+¥*£ÝÏ` 8 ”Ú÷Þ½jÃó’(Šb_ˆ°eYù$I$¦IàûQWˆ0ˆ¢8–2YYY))¥Æ·ýš< < ­N§uèàÁ#—3µÖ†JÓ4ŽãÄ"lw»�BtZ-ÑnµÄ·33“Q=–1>êgð ðàÄIòHªÔõ¡z½�j­’ÍMEQ,|?ìt»þÆÆ†ßöýîÏssîoËËo6½9õj?ƒ ‹g€üÚúúãAÎzµÚZœ$I±"ì´ÛA·Ó³·ní›[Xx_k=”Õ¿\4*?Õì]‹Å¯÷�ŒL?06öÀÊêêøêêêÙ0 Ïñ×gÿ9p‘ÞüW�î3x‚n�x�Þ˜é«3@kGñà Àÿ°|Ivóéyzg¿ðÁ¶õ"ððp!{.í p ØÜVÀ›»-¤×3à<^Ü °\æïG"è]²=Ñg;àkÀ£{¸¾ ¾ <¼—p€½ßŽy`|@îÖŸk°­3‚/§zIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/debugtools/icons/inspector.svg0000644000175000017500000000754714757047403026670 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8931005 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/debugtools/tests/0000755000175000017500000000000015153325403024141 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/debugtools/tests/__init__.py0000644000175000017500000000000014757047403026252 0ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8931005 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/deprecated/0000755000175000017500000000000015153325403022730 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/deprecated/DataListenerOW.py0000644000175000017500000001014215153325210026121 0ustar00paynopaynofrom __future__ import annotations import sys from silx.gui import qt import functools import signal from ..control._DataListenerBaseClass import DataListenerBaseClass from tomwer.core.process.control.datalistener import DataListener from tomwer.synctools.bliss_sync.datalistener import ( DataListenerQThread, MockDataListenerQThread, ) from tomwer.gui.dialog._PortOccupyDialog import PortOccupyDialog from tomwer.gui.utils.qt_utils import block_signals class DataListenerOW(DataListenerBaseClass): """ This widget is used to listen to a server notifying the widget when an acquisition is finished. Then the bliss file will be converted to .nx file, NXtomo compliant. """ name = "Old scan listener" id = "orangecontrib.widgets.tomwer.deprecated.DataListenerOW.DataListenerOW" description = ( "The widget will receive information from bliss acquisition " "and wait for acquisition to be finished. Once finished it " "will call nxtomomill to convert from bliss .hdf5 to " "NXtomo compliant .nx file" ) icon = "icons/datalistener.svg" priority = 10 keywords = [ "tomography", "file", "tomwer", "listener", "datalistener", "hdf5", "NXtomo", ] def __init__(self, host_discovery=None, parent=None): super().__init__(host_discovery=host_discovery, parent=parent, uses_rpc=True) # manage server stop when delete directly the widget or stop by Ctr+C signal.signal(signal.SIGINT, self.handleSigTerm) onDestroy = functools.partial(self._stopServerBeforeClosing) self.destroyed.connect(onDestroy) def delete_listening_thread(self): if self._listening_thread is not None: self._listening_thread.sigAcquisitionStarted.disconnect( self._widget._acquisitionStarted ) self._listening_thread.sigAcquisitionEnded.disconnect( self._widget._acquisitionEnded ) self._listening_thread.sigScanAdded.disconnect( self._widget._acquisitionUpdated ) self._listening_thread.sigServerStop.disconnect(self._widget._serverStopped) DataListener.delete_listening_thread(self) def create_listening_thread(self): if self._mock is True: thread = MockDataListenerQThread( host=self.getHost(), port=self.getPort(), acquisitions=None, mock_acquisitions=self._mock_acquisitions, ) else: thread = DataListenerQThread( host=self.getHost(), port=self.getPort(), acquisitions=None ) # connect thread thread.sigAcquisitionStarted.connect( self._widget._acquisitionStarted, qt.Qt.DirectConnection ) thread.sigAcquisitionEnded.connect( self._widget._acquisitionEnded, qt.Qt.DirectConnection ) thread.sigScanAdded.connect( self._widget._acquisitionUpdated, qt.Qt.DirectConnection ) thread.sigServerStop.connect( self._widget._serverStopped, qt.Qt.DirectConnection ) return thread def _stopServerBeforeClosing(self): self.activate(False) def handleSigTerm(self, signo, *args, **kwargs): if signo == signal.SIGINT: self._stopServerBeforeClosing() sys.exit() def activate(self, activate=True, is_using_rpc=True): """Overwrite the activate to notify the user in case the port is occupy""" if activate and not self.is_port_available(): with block_signals(self._widget): self._widget.activate(activate=False) dialog = PortOccupyDialog(parent=self, port=self.port, host=self.host) dialog.setModal(False) if dialog.exec() == qt.QDialog.Accepted: if dialog.retry_connection: return self.activate(activate=True, is_using_rpc=is_using_rpc) else: return super().activate(activate=activate, is_using_rpc=is_using_rpc) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/deprecated/VolumeViewerOW.py0000644000175000017500000000347415153325210026205 0ustar00paynopaynoimport pytest from orangewidget import gui, widget from orangewidget.widget import Input from silx.gui import qt import tomwer.core.process.visualization.volumeviewer from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.volume.volumebase import TomwerVolumeBase from ._volume_viewer import VolumeViewer @pytest.mark.skip("Fail on CI") class VolumeViewerOW(widget.OWBaseWidget, openclass=True): """a viewer to display the last volume reconstructed using silx plot3d viewer. :param parent: the parent widget """ name = "volume viewer" id = "orange.widgets.tomwer.deprecated.VolumeViewerOW.VolumeViewerOW" description = "display the last volume reconstructed" icon = "icons/deprecated_volume_viewer.svg" priority = 80 keywords = ["tomography", "file", "tomwer", "acquisition", "validation"] ewokstaskclass = ( tomwer.core.process.visualization.volumeviewer._VolumeViewerPlaceHolder ) want_main_area = True want_control_area = False resizing_enabled = True class Inputs: data = Input(name="data", type=TomwerScanBase) volume = Input(name="volume", type=TomwerVolumeBase, multiple=True) def __init__(self, parent=None): super().__init__(parent) self._layout = gui.vBox(self.mainArea, self.name).layout() self.viewer = VolumeViewer(parent=self) self._layout.addWidget(self.viewer) @Inputs.data def addScan(self, scan, *args, **kwargs): if scan is None: return self.viewer.setScan(scan) @Inputs.volume def _volumeReceived(self, volume, *args, **kwargs): self.addVolume(volume) def addVolume(self, volume): if volume is None: return self.viewer.setVolume(volume) def sizeHint(self): return qt.QSize(400, 500) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/deprecated/__init__.py0000644000175000017500000000044315143647637025061 0ustar00paynopayno""" Deprecated tomwer widgets """ NAME = "Deprecated tools" ID = "orangecontrib.tomwer.widgets.deprecated" DESCRIPTION = "Some deprecated widgets that will disappear soon" LONG_DESCRIPTION = DESCRIPTION ICON = "../../widgets/icons/deprecated.png" BACKGROUND = "#C0CCFF" PRIORITY = 99 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/deprecated/_volume_viewer.py0000644000175000017500000004233115143647637026353 0ustar00paynopaynofrom __future__ import annotations import logging import weakref import h5py import numpy import os import silx from silx.gui import qt from silx.gui.colors import Colormap from silx.gui.data.DataViewerFrame import DataViewerFrame from silx.gui.data.DataViews import IMAGE_MODE, DataViewHooks from silx.gui.dialog.ColormapDialog import ColormapDialog from tomwer.core.volume.volumebase import TomwerVolumeBase from tomwer.core.volume.volumefactory import VolumeFactory from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui.visualization.reconstructionparameters import ReconstructionParameters from tomwer.core.volume.hdf5volume import HDF5Volume from tomwer.core.resourcemanager import BaseResourceObserver, HDF5VolumeManager from tomoscan.identifier import VolumeIdentifier from silx.gui.widgets.WaitingOverlay import WaitingOverlay _logger = logging.getLogger(__name__) class _ScanInfo(qt.QWidget): """Display information about the reconstruction currently displayed""" def __init__(self, parent=None): qt.QWidget.__init__(self, parent) self.setLayout(qt.QFormLayout()) self._scanQLE = qt.QLineEdit("", self) self._scanQLE.setReadOnly(True) self.layout().addRow("scan", self._scanQLE) self._volumeQLE = qt.QLineEdit("", self) self._volumeQLE.setReadOnly(True) self.layout().addRow("volume", self._volumeQLE) def setScan(self, scan: None | TomwerScanBase): if scan is None: self._scanQLE.clear() else: assert isinstance( scan, TomwerScanBase ), f"scan should be an instance of {TomwerScanBase}. Got {type(scan)}" self._scanQLE.setText(str(scan)) self.setVolumes(volumes=scan.latest_vol_reconstructions) def setVolumes(self, volumes: tuple[str | VolumeIdentifier | TomwerVolumeBase]): """ Display volume metadata. At the moment only display the identifier of the first reconstructed volume """ self._volumeQLE.clear() if len(volumes) > 0: volume = volumes[0] if not isinstance(volume, TomwerVolumeBase): volume = VolumeFactory.create_tomo_object_from_identifier(volume) self._volumeQLE.setText(str(volume)) self._volumeQLE.setToolTip(volume.data_url.file_path()) def clear(self): self.setScan(None) class _TomoApplicationContext(DataViewHooks): """ Store the context of the application It overwrites the DataViewHooks to custom the use of the DataViewer for the silx view application. - Create a single colormap shared with all the views - Create a single colormap dialog shared with all the views """ def __init__(self, parent, settings=None): self.__parent = weakref.ref(parent) self.__defaultColormap = Colormap(name="gray") self.__defaultColormapDialog = None self.__settings = settings self.__recentFiles = [] def getSettings(self) -> qt.QSettings: """Returns actual application settings.""" return self.__settings def restoreLibrarySettings(self): """Restore the library settings, which must be done early""" settings = self.__settings if settings is None: return settings.beginGroup("library") plotBackend = settings.value("plot.backend", "") plotImageYAxisOrientation = settings.value("plot-image.y-axis-orientation", "") settings.endGroup() if plotBackend != "": silx.config.DEFAULT_PLOT_BACKEND = plotBackend if plotImageYAxisOrientation != "": silx.config.DEFAULT_PLOT_IMAGE_Y_AXIS_ORIENTATION = ( plotImageYAxisOrientation ) def restoreSettings(self): """Restore the settings of all the application""" settings = self.__settings if settings is None: return parent = self.__parent() parent.restoreSettings(settings) settings.beginGroup("colormap") byteArray = settings.value("default", None) if byteArray is not None: try: colormap = Colormap() colormap.restoreState(byteArray) self.__defaultColormap = colormap except Exception: _logger.debug("Backtrace", exc_info=True) settings.endGroup() self.__recentFiles = [] settings.beginGroup("recent-files") for index in range(1, 10 + 1): if not settings.contains("path%d" % index): break filePath = settings.value("path%d" % index) self.__recentFiles.append(filePath) settings.endGroup() def saveSettings(self): """Save the settings of all the application""" settings = self.__settings if settings is None: return parent = self.__parent() parent.saveSettings(settings) if self.__defaultColormap is not None: settings.beginGroup("colormap") settings.setValue("default", self.__defaultColormap.saveState()) settings.endGroup() settings.beginGroup("library") settings.setValue("plot.backend", silx.config.DEFAULT_PLOT_BACKEND) settings.setValue( "plot-image.y-axis-orientation", silx.config.DEFAULT_PLOT_IMAGE_Y_AXIS_ORIENTATION, ) settings.endGroup() settings.beginGroup("recent-files") for index in range(0, 11): key = "path%d" % (index + 1) if index < len(self.__recentFiles): filePath = self.__recentFiles[index] settings.setValue(key, filePath) else: settings.remove(key) settings.endGroup() def getRecentFiles(self) -> list[str]: """Returns the list of recently opened files. The list is limited to the last 10 entries. The newest file path is in first. """ return self.__recentFiles def pushRecentFile(self, filePath: str): """Push a new recent file to the list. If the file is duplicated in the list, all duplications are removed before inserting the new filePath. If the list becan bigger than 10 items, oldest paths are removed. :param filePath: File path to push """ # Remove old occurencies self.__recentFiles[:] = (f for f in self.__recentFiles if f != filePath) self.__recentFiles.insert(0, filePath) while len(self.__recentFiles) > 10: self.__recentFiles.pop() def clearRencentFiles(self): """Clear the history of the recent files.""" self.__recentFiles[:] = [] def getColormap(self, view) -> Colormap: """Returns a default colormap. Override from DataViewHooks """ if self.__defaultColormap is None: self.__defaultColormap = Colormap(name="viridis") return self.__defaultColormap def getColormapDialog(self, view) -> ColormapDialog: """Returns a shared color dialog as default for all the views. Override from DataViewHooks """ if self.__defaultColormapDialog is None: parent = self.__parent() if parent is None: return None dialog = ColormapDialog(parent=parent) dialog.setModal(False) self.__defaultColormapDialog = dialog return self.__defaultColormapDialog class VolumeViewer(qt.QMainWindow, BaseResourceObserver): def __init__(self, parent): super().__init__(parent) self._volume_loaded_in_background = (None, None) # store the volume loaded in the background and the thread used for it as (volume_identifier, thread) self._centralWidget = DataViewerFrame(parent=self) self.__context = _TomoApplicationContext(self) self._centralWidget.setGlobalHooks(self.__context) self._centralWidget.setSizePolicy( qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding ) self.setCentralWidget(self._centralWidget) # waiter overlay to notify user loading is on-going self._waitingOverlay = WaitingOverlay(self._centralWidget) self._waitingOverlay.setIconSize(qt.QSize(30, 30)) self._waitingOverlay.hide() # display scan information when possible self._infoWidget = _ScanInfo(parent=self) # top level dock widget to display information regarding the scan # and volume self._dockInfoWidget = qt.QDockWidget(parent=self) self._dockInfoWidget.layout().setContentsMargins(0, 0, 0, 0) self._dockInfoWidget.setFeatures(qt.QDockWidget.DockWidgetMovable) self._dockInfoWidget.setWidget(self._infoWidget) self.addDockWidget(qt.Qt.TopDockWidgetArea, self._dockInfoWidget) # add dock widget for reconstruction parameters self._reconsInfoDockWidget = qt.QDockWidget(parent=self) self._reconsWidgetScrollArea = qt.QScrollArea(self) self._reconsWidgetScrollArea.setWidgetResizable(True) self._reconsWidget = ReconstructionParameters(self) self._reconsWidgetScrollArea.setWidget(self._reconsWidget) self._reconsInfoDockWidget.setWidget(self._reconsWidgetScrollArea) self._reconsInfoDockWidget.setFeatures(qt.QDockWidget.DockWidgetMovable) self.addDockWidget(qt.Qt.RightDockWidgetArea, self._reconsInfoDockWidget) self._h5_file = None """pointer to the hdf5 file since we want to set the HDF5Dataset for loading data on the fly and avoid loading everything into memory for hdf5.""" self.__last_mode = None # register the viewer as observer of the HDF5 volume (handle resource conflict) HDF5VolumeManager.register(self) def _close_h5_file(self): if self._h5_file is not None: self._h5_file.close() self._h5_file = None def close(self): HDF5VolumeManager.unregister(self) self._close_h5_file() super().close() def release_resource(self, resource: str): if self._h5_file is not None and resource in ( self._h5_file.filename, os.path.abspath(self._h5_file.filename), ): _logger.warning( f"{resource} about to be overwrite. Closing resource and cleaning plot." ) self._close_h5_file() self.clear() def setScan(self, scan): self.clear() if scan is None: return elif len(scan.latest_vol_reconstructions) == 0: _logger.warning(f"No reconstructed volume for {scan}") self._infoWidget.setScan(scan) else: self._set_volumes(volumes=scan.latest_vol_reconstructions) self._infoWidget.setScan(scan) def setVolume(self, volume): self.clear(clear_infos=False) if volume is None: return self._set_volumes(volumes=(volume,)) self._infoWidget.setVolumes((volume,)) def _get_data_volume(self, volume: TomwerVolumeBase): """ load the data of the requested volume. :return: (data: str | None, state: str) state can be "loaded", "loading" or "failed" """ if not isinstance(volume, TomwerVolumeBase): raise TypeError( f"volume is expected to be an instance of {TomwerVolumeBase}. Not {type(volume)}" ) self._close_h5_file() if isinstance(volume, HDF5Volume): try: self._h5_file = h5py.File(volume.data_url.file_path(), mode="r") except OSError: self._h5_file = h5py.File( volume.data_url.file_path(), mode="r", libver="latest", swmr=True, ) if volume.data_url.data_path() in self._h5_file: data = self._h5_file[volume.data_url.data_path()] state = "loaded" else: data = None state = "failed" elif volume.data is not None: data = volume.data state = "loaded" else: volume_id, _ = self._volume_loaded_in_background if volume_id == volume.get_identifier().to_str(): # special case if the user send several time the volume which is currently loading # in this case we just want to ignore the request to avoid reloading the volume # can happen in the case of a large volume that take some time to be loaded. pass else: _logger.warning( "Attempt to set a non HDF5 volume to the viewer. This requires to load all the data in memory. This can take a while" ) self._stopExistingLoaderThread() self._loadAndDisplay(volume) state = "loading" data = None return data, state def _loaderThreadFinished(self): """Callback activated when a VolumeLoader thread is finished""" sender = self.sender() if not isinstance(sender, VolumeLoader): raise TypeError("sender is expected to be a VolumeLoader") self._stopExistingLoaderThread() if sender.volume.data is None: _logger.error(f"Failed to load volume {sender.volume.get_identifier()}") elif sender.volume is not None: self.setVolume(sender.volume) def _loadAndDisplay(self, volume): """Load a thread and add a callback when loading is done""" loader_thread = VolumeLoader(volume=volume) self._volume_loaded_in_background = ( volume.get_identifier().to_str(), loader_thread, ) loader_thread.finished.connect(self._loaderThreadFinished) loader_thread.start() def _stopExistingLoaderThread(self): """Will stop any existing loader thread. Make sure we load one volume at most at the time""" _, loader_thread = self._volume_loaded_in_background if loader_thread is not None: loader_thread.finished.disconnect(self._loaderThreadFinished) if loader_thread.isRunning(): loader_thread.quit() self._volume_loaded_in_background = (None, None) def _set_volumes(self, volumes: tuple): self.clear() # for now handle a single volume if len(volumes) == 0: pass else: if len(volumes) > 1: _logger.warning( "Only one volume can be displayed. Will display the first one" ) volume = volumes[0] if isinstance(volume, (str, VolumeIdentifier)): volume = VolumeFactory.create_tomo_object_from_identifier(volume) elif isinstance(volume, TomwerVolumeBase): pass else: raise TypeError( f"Volume should be an instance of a Volume, a VolumeIdentifier or a string refering to a VolumeIdentifier. {type(volume)} provided" ) # warning: load metadata before data because can get some conflict with the HDF5 reader flag if done after try: # warning: limitation expected for .vol as it gets two configuration file. The default one is vol.info and does not contains # any of the metadata 'distance', 'pixel size'... but it is here for backward compatiblity self._reconsWidget.setVolumeMetadata( volume.metadata or volume.load_metadata() ) except Exception as e: _logger.info( f"Unable to set reconstruction parameters from {volume.data_url}. Not handled for pyhst reconstructions. Error is {e}" ) data, state = self._get_data_volume(volume) # set volume dataset if state == "loading": self._waitingOverlay.show() elif state == "loaded": self._waitingOverlay.hide() if data is not None: self._set_volume(data) elif state == "failed": _logger.warning( f"Failed to load data from {volume.get_identifier().to_str()}" ) return def _set_volume(self, volume: numpy.ndarray | h5py.Dataset): self._centralWidget.setData(volume) self._centralWidget.setDisplayMode(self.__last_mode or IMAGE_MODE) def clear(self, clear_infos=True): if self._centralWidget.displayMode(): self.__last_mode = self._centralWidget.displayMode() self._close_h5_file() if clear_infos: self._infoWidget.clear() self._centralWidget.setData(None) # if clear stop loading any volume self._stopExistingLoaderThread() def sizeHint(self): return qt.QSize(600, 600) class VolumeLoader(qt.QThread): """ simple thread that load a volume in memory """ def __init__(self, volume: TomwerVolumeBase) -> None: super().__init__() if not isinstance(volume, TomwerVolumeBase): raise TypeError() self.__volume = volume def run(self): self.__volume.load_data(store=True) @property def volume(self): return self.__volume ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8931005 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/deprecated/icons/0000755000175000017500000000000015153325403024043 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/deprecated/icons/datalistener.svg0000644000175000017500000000546515143647637027274 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/deprecated/icons/deprecated_volume_viewer.png0000644000175000017500000001224415143647637031643 0ustar00paynopayno‰PNG  IHDRCCÇʸs pHYs¯¯£¦ÈtEXtSoftwarewww.inkscape.org›î<1IDATxœí[k”Õµþö9õèÇtÏf˜y �ᔌÊõ1jÔ«1…LV‚Ä«( ¢ÁH ËÜ$J¢W1*ºâ+Y11×hÄn%ˆ0<D`˜3 =Ý]]]uöýQ5L3tã æ‡ßZ³¦»êT�]ßÙ{Ÿ½wí&fÆgð >mþ�ðøŒŒ |FF>##Ÿ‘‘�ÏÈÈ >ÓÁÑýì°ÌêŒÎŸO;øŒB”àlÅö(àØ`˜­Ó.CNш€ÀåÓ¹:D€a†8à]0ÇA$ôóÏEì°̇N›,YÅ# € Àaf÷4ÍT `œÿm#˜÷ä× Àgh°ÀÞ3aBä-Š$!63;§x†<Êà™Á&0§»q]@5€AðLè;Àœ:¥ò3% ˆ°¸;‚vïΙ&ÑÏ$ÚNâ>@_5¾Œ{á™ÐáS"ç1S‘ €|If¶OÁ];L‚ü3§Iôü¾™&tÀ6ûO• ‘·€:(�àO¢†DyðH胞˜ÄÉÍ3Èÿ³á™Ðø„ é“a€"xdô|[óÔ«ÆÿkÆÉšDÏçÕáíBCáù¼l?Ù¹}2LP ½Çdx&Q /N9u&Ñ3@)<ª€· ÛàrÝŽ›È#÷$ÈðTµ^ÀtúL¢§ðv¯Á°Ðê9ÞöS `4€뺣–D$***FQ9E‰(@D:3 !„ðÿKf–ð/‘ë8Nš™�hqçP2™likk«gæøÇLØcêDeð¤`ÉL‚ˆd$)ˆF£AMÓôt:m¸LJ9@)å‘@Â31@÷ ’Þ-Èeæ3fæ:fÞë8ÎGBˆ öÅb±x,k;alt¬ •hôIÙrd|^RÕ-“ˆF£Åápø2]×GûÚ`*¥@šˆl¥”/®±‰(Í̹ÀÌ€å ! ÉKèÊÈ3‡™w(¥6¦ÓéµBˆW8Ð|"Y2ž# O«H¢3rNHÑ‹€¸ê#¤¯skî¹H”––ž­iÚ`!D_xñ@žÚ'˜9ÁÌR"Ïç˜L_/Ò´‰ÈRJY¾)$|/ODdQ  `æ&"Úì8ÎûJ© uuuksi ufåD&€s]/*NHàU0§s’ÑLT^ÔJÀ8lÌvåÊh u]ï Ë\×/„BD½¤™9ADéæ™9O…·•ç‘vfVDdHˆ1s 373ó!ölÝ""�ˆÁ3µ0õQJíWJ½#„ø“ëºûÛÚÚêb±Xc&ŸÂ3õ °Hh̯gj†Ö…F½ÐK±ÃZ\/°!"3³ÃwL  Õ4í‹Ì|¾”Ò†çÅPD”P(„øõó>+2d>*;)f®Т”ÚjYÖ*Çqš�@©®ëßBŒ”Reæ)®ë¾™——÷"ZOn ö¾ q�Q¾–¿&;Çcp,ÌiI”t€dh(Ƴ·{ìÑÁ@4Í…BJ)G !*‰(®”²„ 1³íºn³¾½k]'þ0€€MJ©íÌLRÊ‹‚Áà”RÛlÛ^cYÖ Ó4+t].¥ü‚¦iWJ)UTT ³mû¹¦¦¦Æ:O k j¯v¾ÈìúìÊgÒ ó€Í lPå#l`T;°ã’Þ½Û?Ô´‘Æ !z‘ÆÌ ¶RªE)Õìºnšˆt)e"*€·sdpλ™ùCxÞ0€ˆªà™O‡öI"ª`æM©Tj›¦i!]× !Êt]¿ˆˆö¸®»Ÿ™ë èBœKDcˆ(–2:'m©K$d/ÇyOþ`z޳C�SÅ\d0:j£Þαý~¢]_J)ÇÍ�ÅF¿WþÝ0ìvf›=ÇšdfÇqœ=©TjG<�—””œGD}àùø~A1sL)µÎuÝÕ¶m¿ODņaLB\ „É̦oë€6¦R©?·¶¶>S\\<Æ0Œ‰š¦�—RrgM*•ZcÛö¦p8¬I)Ï­PjÔËjiÚÎ…ùù¿Ùdš»êêê”oæ™dtO34¯.ztðboûÛY^R2¶Æu#c\·pV{»»GÓŽ¼m?J§7¤ÓiËu]GJi¥Óé­š¦]BD½ÙK¹5" 2s’™W[–µ&�¿�Ç·‡B¡aš¦%�@}(ª$¢xÕ7 )åYáp¸ß‘#G~‹Å�@ ! nÖuý›º®_'¥¬iooÄliymŠ”2ŒIÛ £`K8<"Í®k–——?`{Æ3‘¿è=Ð xATqqqYiii- Ñ‹”‡·ÿ¨¶mçÂT*ïöx<Ú xW©Õ/Æ¿b–B¥ÔAo9ŽcK){ ! ˜ù#!ÄÖx<¾€•H$ö„ÃáDähfæ¨ïÝ;VÑ�RìD"±KaQJñœ”òbMˆšñ†qÛE¶½'é8 /Æs‡u}…ý\+¥ü?x•³£�Õ]2T† ÈËË+BTQ5±ëº•Rm[ˆ’ïû®‚¯pÝËÒéQO¦Ó%¶€Yõë×O#¢¸mÛ›ãñx‹iše�@`E¤”Iî �[óóó‹4M 2³ÌÜ}¤áïÌÜFDìNV›f¯QŽS¡µ«òòÜ[“©ÔŽ�ãhRÊõ'¢BtjZ×EÿX2\d8<)e_¥T?!D›mÛíJ©Öd2Ù@!v?›H4x'#Q:DmãÊÊŠÖF@©®ëI!„æQKD«ÊÊÊ nee%…Ãá.$¢rtú˜Ž‡nw§Å_$0ó‘ûˆ>,7ŒQ¡dÒz;Z»*ùrŠh¼®\æC­­­«"‘H£iš£•R:0f}_”ËLŽ®ŽRªÝqœFÇq€]×=˜L&÷ú§;Cxæ€õ ú€êKÛÛµA†‘¿Ù0®Ù ms…(#¢a~²6Ç4ÍsÊËË÷)¥‚º®�B|žˆò˜ùèÜDä0s³mÛuèXI¢Ê…ÀÙûlS4­q_2YQ ²®ëB Ó\×}4•Jm³mûCdYV]—gì¶UÈÐ "jL¥RIý|cÙ˜õI±l^VRòòp!Âç²ÁŽS±Ó0̺^àxN} €³t]?ÄÌõ!¢ÒL3ñó–÷¬³,kO#Ñ8}RÀö)ÕÕ?¾õ¶ÛÎoooG}}=V®\‰`0!¢��@`´eYlooß–eµä”·d]�¶¶¶-DD�@ Ÿ®ë…¥¥¥¥ÉdÒ‰Åbí¹Ê…%;G£kB�ÀȳgPu:�Wå8´WÓð�a[Bw½&Ã]¤4:Žó-�^O$¢¾/‚üß]¿ñ—‹ŸÓM7ÁI[¸òªk0a¬_¿žˆÈB ƒo655åÊ®³:Ðl¶£r‡ÂB p¥®ëÿQPPÐ'ÇdH&“Òéôëí‰Ä{5mË[¡�µÞ4Q¬.N$06•BžÊ^ÏeæF¥Ô_‡Åb»žon`$€�Þ$ 8gΜ­X±Ë-¼ô ðòË/ãòË/‡ëvûÕO�Ì$+ŽãÄ ÃhP`F"*,//or]·!�Nÿ«¥¥åhŲš‚ÁàÛš¦­ÐuýüƒRŽ­×´AE®«W§Ó˜”H QÓ°Ã0Ð*„ÃÌqf~_wœ�W´µ5^ŸHDz+µÀ_ÁlåççWW•”üjàÀ�ÁŸÿü¬y˜8¸òàž{îÁ-·Ü‚eË–mÔ4íuÇqNT†ì¶ÍJ3s0<(¥Ôo+Лˆ*„í¦iæWTT4¸®{¸¡¡á#fv˜9EDuÌüF~~~L×õV)åžf¢ÂC¦ê%e &�6'ÇbÜ(eì})ôJ§w|5‘H�•JÕ§”zmtAÁMÓú½˜ùÆ ÔΟ?³¯òˆ€Ÿß »föíÛ‡šššêM›6ýÍqœãŠ8]©ë�ã‹;D#Œð|¶÷¡P¨BÓ´þŽã8‘Hd°”r°¢ù¹É6fþ3Ç…ÜÐР°iš•DtV P�@ Ÿ¦iåÌà–ÛvbrbĈg‰hBŽÂT·Ãñ—,á…Â9áGv­~l ¤”J)†aô‘R– !Š…yB€©”аWfs¸¡5�–ãD5¥L"RJ©Vfnµm{wuuõO¨¾n7ÞüIçü«ß4“Æ}J€‘ƒ€ïM–,Y‚åË—~ÆŒS<÷IÈè”U3r�ÂD´×¿&‰DL?÷`[Ë`dliZÑñu@*Õ\ÈnsÝ·;ÆÛ¶=eîܹf̘�¿ (÷NÌú>ðäï¼Ï‘ðçÇ€ÚaÀ½s€_¿•À /¼€iÓ¦ý‚ˆ^gæ®…ãkF�ú½:Òc"ŠØêkË1¡}62ó²s•Ê‹Q"z,˪œ;wî­�<òj¤ñÝë¼qõ‡:‰€XÂs OÝ M`ùÀ”ïþO<ñDdõêÕ?ðõ®Óf“åDšqRÍo~ r�7DmèÈ‘#‡ ¦¦æùÞ½{›ëþñÖ> h¾Že‹­œŒc“¿\?X¸p!,X0•ˆV0ó[]Eíz�\h®s§Gc"úêüùó/zà�0÷kž t w‘ç03QÖ%¸ÿÙí€cÕcË–-¸ôÒKŸ&¢@Æi�n’qRfrŠÀðªñÑ©S§þâ·¿ý-òƒmøþÍÇÒ5 0rì±Ò¢c¿—K¿<þøã¸á†*óóófœÎ™›t=ø‰Ìä€JKK2iÒ¤¢W^yÏòBÇêª ¥Ç¥}À¬¯Ô*Üÿý˜;wîD4ìøQ�è #“�OÕL~ ¹óÎ;¿qß}÷áš �+ÎË>°ëÃw%ˆ52êí­‰¿·sçN:Òº?ù¯Üc�ÓŒ¢ìã†öîü°téRÌ›7¯öl!ù§ŽsÃÂ?˜M3Ã{çqÆðÓœvã·¾UúØc�áÁ¹@EïÜc»>|YIî±wͪÊSxâ‰'0væÌ»ör·vÆÞÃw’ÁÜÔ¬:ìK_Ñ%­D}‰Èô_ðäy8)�"¢êKn½uÖC=„qÃ\̾êÄã3ÍD Ïaæ‚¡�.Ö¬Y�QcÆ?îßÿ{]:{€Ò886*$‡¼ÛP 08LܠآٸŽËá‘Øã.¼ššš_š�€Ü¼iÞ]yüÖÙ™fRRàr"œ7˜q¹W÷X²dÉUDt3¿êŸ>JFW31ýï‰/ª\¿‡hs0¨È«~Ñnx=™ Ÿ<‰Î–ëADÓW®\9ñæ›oÆüéÀèÁMÿòìŸO„eó€Wÿzï¼ó®¾úêDTå·?0ut%;²;òz"˜³µO{&P ¯E¨~¯7­|’=™DTû,æÍ›÷ßMMM·vì0'ÿ ¢"x-BýÑÙ¨Ú£.;¨¬¬|þî»ï¾îÛßþ6ÞX\<¾Ç’ô—Ͷ×ÂôéÓÕ¢E‹Æ1ó†¬ÎŽˆD–·Zǃ¹Ìoø=¼·éã\¢!~ËôÇ‚ˆÎ_°`Áu÷Þ{/¦}¹çD¼· øý åHÏ®{d>pðÀH$b„ +Éëg�ŒRd…W-ª‚×7nØ߯dNæäÉ“wTTTô}å×ObËK^ÎÑ]Ì]æeªPþò?^=£»øáSÀ¢G5<õÔS˜5kÖ-–eýìÔ‘ÑO«*àu wüÈfºÔ¢ÑèÒåË—ß9}útür1cúeÝŸ¢±(½äØc3®ž¼§û÷p\àì³p<Î9çëᇮ>õQ&3ƒy?˜ßð:¼ÝêbMÑxf8äöÛo¿}éÒ¥8o cÚ—{6E(Œc�E³�ÍM�Ý ¼»n-ªªªC† yüô†Ü�~åwêÔÚÀåŸ=ú7¶mËÝ»¶âÑ»|7Þä…€'~æ:ip×Ìž‹wÎp`΋/Æm·Ý6åԛɉ@¤O¾9çé§—Ïž= g¦°pÖÉßÎU@< Ds¶Î}<ŽÄ�šk� .þz�Ï>˜Ó' Þ˜H •JáOk�ÕëϨY!°nݺS¸›tDÔwêÔ©[ÆŽnjj:£sç‚”UUUgž ¢þ†aÌìÕ«Wߎc³V¬T4Ê­¢©Mˆ7ÌŸB¤R)«¹¹ùoŸ '„¯¸ŸÆÿýÈøñÿŽw¹§0IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/deprecated/icons/deprecated_volume_viewer.svg0000644000175000017500000001646315143647637031665 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8971007 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/edit/0000755000175000017500000000000015153325403021555 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/edit/DarkFlatPatchOW.py0000644000175000017500000001231715153325210025045 0ustar00paynopaynofrom __future__ import annotations import logging from orangewidget import gui from orangewidget.settings import Setting from silx.io.url import DataUrl import tomwer.core.process.edit.darkflatpatch from tomwer.gui.edit.dkrfpatch import DarkRefPatchWidget from ...orange.managedprocess import TomwerWithStackStack _logger = logging.getLogger(__name__) class DarkFlatPatchOW( TomwerWithStackStack, ewokstaskclass=tomwer.core.process.edit.darkflatpatch.DarkFlatPatchTask, ): """ Widget to define on the fly the image_key of a NXtomoScan """ name = "dark-flat-patch" id = "orange.widgets.tomwer.edit.DarkFlatPatchOW.DarkFlatPatchOW" description = "Interface to patch dark and flat to an existing NXTomo" "entry" icon = "icons/patch_dark_flat.svg" priority = 25 keywords = [ "hdf5", "nexus", "tomwer", "file", "edition", "NXTomo", "editor", "dark", "patch", "ref", "flat", ] want_main_area = True resizing_enabled = True _urlsSetting = Setting(dict()) _ewoks_inputs_to_hide_from_orange = ("configuration", "serialize_output_data") def __init__(self, parent=None): super().__init__(parent=parent) layout = gui.vBox(self.mainArea, self.name).layout() self.widget = DarkRefPatchWidget(parent=self) layout.addWidget(self.widget) self.setConfiguration(self._urlsSetting) # connect signal / slot self.task_executor_queue.sigComputationStarted.connect(self._startProcessing) self.task_executor_queue.sigComputationEnded.connect(self._endProcessing) self.widget.sigConfigurationChanged.connect(self._updateSettings) if isinstance(self.task_output_changed_callbacks, set): self.task_output_changed_callbacks.add(self._notify_state) elif isinstance(self.task_output_changed_callbacks, list): self.task_output_changed_callbacks.append(self._notify_state) else: raise NotImplementedError def reprocess(self, dataset): self.set_default_input( "data", dataset, ) def get_task_inputs(self) -> dict: task_inputs = super().get_task_inputs() task_inputs.update( { "configuration": self.getConfiguration(), "serialize_output_data": False, # avoid serializing when using orange } ) return task_inputs def getConfiguration(self): def cast_url_to_str(url: DataUrl | None): if url is None: return None elif not isinstance(url, DataUrl): raise TypeError( f"url is expected to be an optional DataUrl. {type(url)} provided instead" ) else: return url.path() return { "darks_start": cast_url_to_str(self.widget.getStartDarkUrl()), "flats_start": cast_url_to_str(self.widget.getStartFlatUrl()), "darks_end": cast_url_to_str(self.widget.getEndDarkUrl()), "flats_end": cast_url_to_str(self.widget.getEndFlatUrl()), } def setConfiguration(self, config): if config is None: return self.widget.clear() url_keys = ("darks_start", "flats_start", "darks_end", "flats_end") url_index_keys = ( "darks_start_index", "flats_start_index", "darks_end_index", "flats_end_index", ) setters = ( self.widget.setStartDarkUrl, self.widget.setStartFlatUrl, self.widget.setEndDarkUrl, self.widget.setEndFlatUrl, ) for url_key, url_idx_key, setter in zip(url_keys, url_index_keys, setters): if url_key in config: index = config.get(url_idx_key, 0) url = config[url_key] if isinstance(url, str): url = DataUrl(path=url) if url not in (None, ""): assert isinstance( url, DataUrl ), "url is expected to be an url. Either as a str or as an instance of DataUrl" try: setter(url=url, series_index=index) except Exception as e: _logger.error(e) def _updateSettings(self): self._urlsSetting = self.getConfiguration() self._urlsSetting.update( { "darks_start_index": self.widget.getStartDarkIndex(), "flats_start_index": self.widget.getStartFlatIndex(), "darks_end_index": self.widget.getEndDarkIndex(), "flats_end_index": self.widget.getEndFlatIndex(), } ) def _notify_state(self): try: task_executor = self.sender() task_suceeded = task_executor.succeeded scan = task_executor.current_task.inputs.data if task_suceeded: self.notify_succeed(scan=scan) else: self.notify_failed(scan=scan) except Exception as e: _logger.error(f"failed to handle task finished callback. Reason is {e}") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/edit/ImageKeyEditorOW.py0000644000175000017500000000666215153325210025245 0ustar00paynopaynoimport logging from orangewidget import gui import tomwer.core.process.edit.imagekeyeditor from tomwer.gui.edit.imagekeyeditor import ImageKeyDialog from ewokscore.missing_data import MissingData from ...orange.managedprocess import TomwerWithStackStack _logger = logging.getLogger(__name__) class ImageKeyEditorOW( TomwerWithStackStack, ewokstaskclass=tomwer.core.process.edit.imagekeyeditor.ImageKeyEditorTask, ): """ Widget to define on the fly the image_key of a NXtomoScan """ name = "image-key-editor" id = "orange.widgets.tomwer.control.ImageKeyEditorOW.ImageKeyEditorOW" description = "Interface to edit `image_key` of nexus files" icon = "icons/image_key_editor.svg" priority = 24 keywords = [ "hdf5", "nexus", "tomwer", "file", "edition", "NXTomo", "editor", "image key editor", "image-key-editor", "image_key", "image_key_control", ] want_main_area = True resizing_enabled = True _ewoks_inputs_to_hide_from_orange = ("configuration", "serialize_output_data") def __init__(self, parent=None): super().__init__(parent=parent) self._scan = None layout = gui.vBox(self.mainArea, self.name).layout() self.widget = ImageKeyDialog(parent=self) layout.addWidget(self.widget) # connect signal / slot self.widget.sigValidated.connect(self._validateCallback) self.task_executor_queue.sigComputationStarted.connect(self._startProcessing) self.task_executor_queue.sigComputationEnded.connect(self._endProcessing) if isinstance(self.task_output_changed_callbacks, set): self.task_output_changed_callbacks.add(self._notify_state) elif isinstance(self.task_output_changed_callbacks, list): self.task_output_changed_callbacks.append(self._notify_state) else: raise NotImplementedError def handleNewSignals(self) -> None: scan = self.get_task_input_value("data", MissingData) if scan not in (None, MissingData): if scan is not self._scan: self._scan = scan self.widget.setScan(scan) self.notify_pending(scan=scan) self.activateWindow() self.raise_() self.show() # warning: avoid calling "handleNewSignals" else this will trigger the processing. # here we want for the user to explicitly click on 'validate' to modify the image keys def reprocess(self, scan): self.set_default_input( "data", scan, ) def getConfiguration(self): return { "modifications": self.widget.getModifications(), } def _validateCallback(self): self.update_default_inputs(configuration=self.getConfiguration()) self.update_default_inputs( serialize_output_data=False ) # avoid serializing when using orange self.execute_ewoks_task() def _notify_state(self): try: task_executor = self.sender() task_suceeded = task_executor.succeeded scan = task_executor.current_task.inputs.data if task_suceeded: self.notify_succeed(scan=scan) else: self.notify_failed(scan=scan) except Exception as e: _logger.error(f"failed to handle task finished callback. Reason is {e}") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/edit/ImageKeyUpgraderOW.py0000644000175000017500000000713015153325210025557 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging from orangewidget import gui import tomwer.core.process.edit.imagekeyeditor from tomwer.gui.edit.imagekeyeditor import ImageKeyUpgraderWidget from ...orange.managedprocess import TomwerWithStackStack _logger = logging.getLogger(__name__) class ImageKeyUpgraderOW( TomwerWithStackStack, ewokstaskclass=tomwer.core.process.edit.imagekeyeditor.ImageKeyUpgraderTask, ): """ Widget to define upgrade all frames with some specific values of 'image_key' others values """ name = "image-key-upgrader" id = "orange.widgets.tomwer.control.ImageKeyUpgraderOW.ImageKeyUpgraderOW" description = "Interface to upgrade all values of one or several specific `image_key` to a different value" icon = "icons/image_key_upgrader.svg" priority = 60 keywords = [ "hdf5", "nexus", "tomwer", "file", "edition", "NXTomo", "editor", "image key upgrader", "image-key-upgrader", "image_key", "image_key_control", ] want_main_area = True resizing_enabled = True _ewoks_inputs_to_hide_from_orange = ("operations", "serialize_output_data") def __init__(self, parent=None, *args, **kwargs): super().__init__(parent=parent, *args, **kwargs) _layout = gui.vBox(self.mainArea, self.name).layout() self.widget = ImageKeyUpgraderWidget(parent=self) _layout.addWidget(self.widget) # connect signal / slot if isinstance(self.task_output_changed_callbacks, set): self.task_output_changed_callbacks.add(self._notify_state) elif isinstance(self.task_output_changed_callbacks, list): self.task_output_changed_callbacks.append(self._notify_state) else: raise NotImplementedError self.widget.sigOperationsChanged.connect(self._update_operations_to_ewoks) self._updateGUIFromDefaultValues() # in case there is information registered and the GUI is not synchronized with the default values self._update_operations_to_ewoks() def _update_operations_to_ewoks(self): self.update_default_inputs(operations=self.widget.getOperations()) def _updateGUIFromDefaultValues(self): try: operations = self.get_default_input_values()["operations"] except Exception: operations = {} self.widget.setOperations(operations) def get_task_inputs(self): task_inputs = super().get_task_inputs() task_inputs["serialize_output_data"] = False try: scan = task_inputs["data"] except Exception: pass else: self.notify_pending(scan=scan) return task_inputs def _execute_ewoks_task(self, propagate, log_missing_inputs=False): task_arguments = self._get_task_arguments() scan = task_arguments.get("inputs", {}).get("data", None) if scan is not None: self.notify_pending(scan=scan) super()._execute_ewoks_task( # pylint: disable=E1123 propagate=propagate, log_missing_inputs=log_missing_inputs ) def _notify_state(self): try: task_executor = self.sender() task_suceeded = task_executor.succeeded scan = task_executor.current_task.inputs.data if task_suceeded: self.notify_succeed(scan=scan) else: self.notify_failed(scan=scan) except Exception as e: _logger.error(f"failed to handle task finished callback. Reason is {e}") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/edit/NXtomoEditorOW.py0000644000175000017500000000724015153325210024767 0ustar00paynopaynofrom __future__ import annotations import logging from orangewidget import gui from orangewidget.settings import Setting from silx.gui import qt from ewokscore.missing_data import MISSING_DATA from ...orange.managedprocess import TomwerWithStackStack from tomwer.core.scan.nxtomoscan import NXtomoScan import tomwer.core.process.edit.nxtomoeditor from tomwer.gui.edit.nxtomoeditor import NXtomoEditorDialog as _NXtomoEditorDialog from ...orange.managedprocess import _SuperviseMixIn _logger = logging.getLogger(__name__) class NXtomoEditorDialog(_NXtomoEditorDialog): def __init__(self, parent, *args, **kwargs) -> None: assert isinstance(parent, _SuperviseMixIn) super().__init__(parent, *args, **kwargs) class NXtomoEditorOW( TomwerWithStackStack, ewokstaskclass=tomwer.core.process.edit.nxtomoeditor.NXtomoEditorTask, ): """ Widget to edit manually a NXtomo """ name = "nxtomo-editor" id = "orange.widgets.tomwer.edit.NXtomoEditorOW.NXtomoEditorOW" description = "Interface to edit manually a NXtomo" icon = "icons/nx_tomo_editor.svg" priority = 10 keywords = [ "hdf5", "nexus", "tomwer", "file", "edition", "NXTomo", "editor", "energy", "distance", "pixel size", ] _ewoks_inputs_to_hide_from_orange = ("configuration",) want_main_area = True want_control_area = False resizing_enabled = True sigScanReady = qt.Signal(str) """emit when scan ready. Used for test only""" settings = Setting(dict()) def __init__(self, parent=None, *args, **kwargs): super().__init__(parent=parent, *args, **kwargs) _layout = gui.vBox(self.mainArea, self.name).layout() self.widget = NXtomoEditorDialog(parent=self, hide_lockers=False) _layout.addWidget(self.widget) self.widget.mainWidget.sigEditingFinished.connect(self._updateSettings) # load settings self.widget.setConfiguration(self.settings) # connect signal / slot self.widget._buttons.button(qt.QDialogButtonBox.Ok).released.connect( self.execute_ewoks_task ) def _updateSettings(self): self.settings = self.getConfiguration() def handleNewSignals(self) -> None: scan = self.get_task_input_value("data", MISSING_DATA) if scan not in (MISSING_DATA, None): self._setScan(scan=scan) # return super().handleNewSignals() do not call to make sure the processing is not triggered def setScan(self, scan: NXtomoScan | None): self.set_dynamic_input("data", scan) self._setScan(scan=scan) def _setScan(self, scan: NXtomoScan | None): if not isinstance(scan, NXtomoScan): raise TypeError( f"expect to have an instance of {NXtomoScan}. {type(scan)} provided." ) self.widget.setScan(scan) if self.widget.hasLockField(): super().execute_ewoks_task() else: self.show() self.raise_() def task_output_changed(self) -> None: self.sigScanReady.emit(str(self.get_task_output_value("data"))) super().task_output_changed() def get_task_inputs(self): task_inputs = super().get_task_inputs() task_inputs.update( { "configuration": self.widget.getConfigurationForTask(), } ) return task_inputs def sizeHint(self): return qt.QSize(400, 500) # expose API def getConfiguration(self) -> dict: return self.widget.getConfiguration() def setConfiguration(self, config: dict): self.widget.setConfiguration(config) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/edit/__init__.py0000644000175000017500000000047214764622416023704 0ustar00paynopayno""" (Ewoks)Orange Widgets for NXtomo edition """ NAME = "edit HDF5 - NXTomo" ID = "orangecontrib.tomwer.widgets.edit" DESCRIPTION = "widgets for editing NXTomo" LONG_DESCRIPTION = "Contains widgets for editing NXtomo entries" ICON = "../../widgets/icons/tomwer_edit.png" BACKGROUND = "#C0CCFF" PRIORITY = 8 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8971007 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/edit/icons/0000755000175000017500000000000015153325403022670 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/edit/icons/image_key_editor.png0000644000175000017500000000155614757047403026717 0ustar00paynopayno‰PNG  IHDR¤T<‰sBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î<ëIDATH‰½–[HTAÇí%m·T¶²ËFB±›mvÙì­Hø`šÙdÉ1|é¾õÑKw‚À çnôëT¢˜¦'µ -ÁÅÔÔîêZm§‡éTk´ÑéÃùfÎÇüæÌ|ß7þƒf¹Ý»½ééO—é°É.WÉÙC‡ÞÔݸ1œéñ´ØÌ„%8�9ûJKOW\¾œ”àp ~¨2 f·ÛWœ z4!ô`EÅТÔÔ»À³x)GËË_jBè Áà°Ïë­LÛM÷ž’’M½QˆÏ¹>_=olâŽÂšº&ÄW^^+�dÌQ��­i••M}WQQ;05šãRõ´ÀdûhcN5¶X$öìU«î7ƒŸ4!ôƒee!`N4˜X¯ìq@–j#Zø€Ùªïü€<Â@þꌌ›Ç÷î]b±Xì·««{Ž_¼¸h hÔ5–¨ú‹�§†÷9À Íž´´¬3�@¦Ýf‹ØÔÔ{äüùm@c4X4 À#` 0è† ¾É@‡ê�Ÿžœ|éÜáÛÇÅÅMhikë?pêTY8þmrG>æ+€zø®šUõÓ»z{gÖ>~lkïì|·ÿĉ@ÿÛ·ÁßÁFPÏ`§²×ÅÊöË•½ð(ûgµZk§NštòO@0zöרö³nj^@D"‘šî¾¾c „ï!oåÇðÑd*5Ø‚ 2(@n]2ÃfG‚f �� Š�óó�¯À+ತ -Êg ÐÉ(U%š,È`)‚Ø4`p¸†,{)@+�©|Æ"+Qˆd"jõ¹jòA`r‹7)?'2O[�×À,dÕi¾Ä ¨Cn•_}Õ{ ùÕ?ë°yÏ]‰f4!ƒÅ\Gæ×F ù{W�<¯.Àôc¯7²SMòÖpókâoGž³ér!w ço'øð˸Åû•IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/edit/icons/image_key_editor.svg0000644000175000017500000001634414757047403026733 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/edit/icons/image_key_upgrader.png0000644000175000017500000000174614757047403027243 0ustar00paynopayno‰PNG  IHDR^ö¼sBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î<cIDATH‰Í–ßo“eÇ?l+ý1ßZJêì˜ÃNl![-®eac3.FÛ… ƈ$^pÃ…—pW^Œ„\¦YR ‹ÄIg”Ž6°FFÃ�‰­u¬³v[¡-o½xÎ Y¦ÀJø&Í{ž÷}žó=çûžsÞ˜\NçÈ»}}7�­< t´µ}îôéåéñq}è¬W½aŠÅ¥WÝî}ÇGFÌ[[Z6z*¿T*•®×ГɴûÃâáp%W>=vlÁ¡i¯7O}õB×õÛ—gg¿(—Jﻺln—ËÜ»k×ÀT,æÈåóßÕ„T°8�HœMe2ÃÁ Í¡i–Ážž¿ÎÌl¿“Í~ TÖ‹|5X{� ¿Œ�-ÅÃáJdt4ììœ6=¦Ÿv ØhÜX-SŹtúL4‘ð¿ µÚ,Ûþþþ–¹tz8yëÖ(p÷n^þLr]“@OÏÏ�MF£Ž=�€Okn¶¾ÝÓãÌær$’ÉqÃÉp ”¹‰Ê8e�j@àt ìþ¶ÍÙ\îç‰HdÉïõ\›7[övwk榦ÃS±Ø9 ³é6`X\ÀŠAÚ´m�xYìí@3à^.2_ONÎokmõ·»Ý�~¯×â´ÛE¢ÑF½RÑŸ�ø%ŸHk^Ò@3äýÈsÕ0 ä€KÀ2p»\.Ÿÿ!¹ú¢Ý>àóxÌ>�§ñâ•+{þÈd>΋Ÿ À}Ô»/ˆÿ<Aä5K¶ˆÔ†½xIÖVÀ&ûCGÌ .ŸËûÛ 4ÈÙ7eo5vˆ¿'Fp8�( �DB«œqo< ©�à$ðªEžOÔ22 øU˜õ¨vŒ?6¬ujp8%¶8 \««1i5 ¨Á³¡%q7ð7ªì§PÅq(¯Èu¸€«€¸øDu¨–° eÈkÇ/ÈC Ð$Ž¿‘çºìí�õO¨©cF}Aî ¨ ¶Ü“3Uï‰Gå�†$¢jX�½b…¤5öVä~R‚lçáyœ–ß,p è42]D�¨pUy�@Ø-Qÿ.{S¨* ¡ä6£¾6:P²¬Ž�¨™üÛz¶Œ è. þ]T·Lªv’À·ÿé[?šÅ²~IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/edit/icons/image_key_upgrader.svg0000644000175000017500000003233314757047403027252 0ustar00paynopayno image/svg+xml B A ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/edit/icons/nx_tomo_editor.png0000644000175000017500000000200214757047403026433 0ustar00paynopayno‰PNG  IHDRíiM¿sBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î<IDATH‰½•H•WÇ?^_+odÉÔ-¹Åf´beîGJ�e°$¯³ –³?ö—†ƒÉB&²2$Ü$‚1‚†T(Σ¹jkd°Š²Ù«“Bh[³ÍfÓ™ÎëìÞxûãœ7Ï=Ü›-È^Î9ÏyÞç{žïó<çÀ JšÏW™•žÞ $Î褤�_TU�\mjš\“‘ÑcÍè<¯wóžÒÒšú††ùs½ÞÀøÄDÇs�·¬µGöíûËÂi¬¯,OKûˆyÞ¸+÷ïÞ=` áüÔÜ<¹!3ó<ð˜å2 Ûø¡Xªæ~à-c?Ø: è¢Ê²²;¶Îu!‚ù99�ÀÝÀÎ?�ÞWóO€ÓÆþ à³'€&ï(*ºe áØB<,òû{�y¦‘ügœF~˜ÔzpØ4¡8?ÿ¦-ÄC[§¼¸ø6ðb$CG9^àWà=5φÐr¥Iü¦ììk]--A[§¢¤äwàåH 5vÀ¦´…j^œB†MìºÕ«[VT¬ðÄÄXíwëŽÍ~‹æÔg5�ñF`Is?ð®á#&sÕª¦+��ã¶N}uõ`¼e™ØŒ+Ç‘€ã€a Ya…òŠÏ÷õ�Ç��ÙB8Çjkï%x½þé@]ª»� àÍ(vAdeW?cÚ^FÿÀ@bO_¿ô÷�TÖÕí ¾�dÄ©@ °Wé̈¶+Û2Cÿ%gYVKjJÊGOS\àÉæFù³¦[�¬Ú¯B¡Ð§zVàl 6Š­[Õ¹šÎz€Rà]ü:pòòΈbW|lÖô¨Ïm­m/HF’¤éSÜ».™î,`ð!Ð ø€;À6àcdîgå l°hJT@žpÿQó\ˆìóÈ(PúF yo/^Õö:€ÃH –\ x#pá)Ø5„ÓíÊßÈ– ¨u7pèSã À(ð6®"‹×4Ý`9Ю֭ÀÛ„_"qÈ^×åäàŽzZøp™ð"ÙªtwÕº¸‡¤ÍA²dêu3}êâvLl$£ ƺ�)šQ`mHºÿEæ5Y¹‹ˆÞŽ¨Ã¥‰àá4�Qº!À‹¬Öo '�—��bu˜KÀ1äƒ2ŽÌé˜:à²Â¯Í�Rqù]³IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/edit/icons/nx_tomo_editor.svg0000644000175000017500000002001414757047403026451 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/edit/icons/patch_dark_flat.png0000644000175000017500000000276214757047403026525 0ustar00paynopayno‰PNG  IHDR1Jç‹sBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î<oIDATH‰¥–[lT׆¿}f4Ìà±l»*†`a«/ib¥–Û˜ ¨)-R©@mžXÊC‰U©ª Q¹Ø®�娢žI\©¥Ue@`ùrÆT‚ì( ©¶¨ˆ¹©8¾ »Ôı™<žË9{õ¥M, ½|�û_ûÿ÷ZÚÒÞ°„ i¾û¦i>½týaMóãP Pú¨:ã¿1ýq·oÙ²"á÷w(X¯•C¤ +†vìè‘ÕÀJ%n‡[‚¦y8<«”jZLÓãSê÷{{O. 3~ÿN%k°¬g‘à[_ªÉäk�–õ\9|G”zé-Ó\ÿoe�ˆ\n´¬ï6ôöžpDü+ O‹|ü  ¥jÃ8 pÀ²¦>ÉŠÚãùiÐ4߃ ÌùFVKùý§¿b¤u?p²É²þ¸Ü `Ñ%²2»   µ¶öÛJ©ÊáÅFËÚ ‹a¸³u-ÇŽ%s�Bü¢í•WŠ— ‘Sv‡�ÒàË/ož0l[€üIÛ~,dš›�MK7>½fÍšï.×»"òkÛ¶ß˹™^¯×û<à0š,k@‰üIç�‚õˆìO»\_4ôõ}¢à¤ãv¿£•ªRJ½.JÝp sÿþý'§¦¦>ûËÝ¢"CÇã‹�áp¿À>­um^^Þ×Ïœ93455õþñãÇ/øýþ’å:~(Û¶mkÐZ§.]º$‰DBnܸ‘Ù³gϱœ÷¡C‡†ÇÇÇeddDlÛ––––^šG200ðÁåË—%�Êôô´¤Óiqg¡¾¾¾`÷îÝ™LÆŽÅb211!/^”ëׯ_ÿŸÂΞ={naaA¢Ñ¨$ É’ÉdâÛ·oH¥R÷DD´Ö299)ÑhTÚÚÚN?ÚùìÚµ«mff&377'¹ŒŒŒÈíÛ·�L&“{±,k(v„jkk´È †Ö^QªµÑ²¢Ë…>|xŸßïüàÁƒ?\÷îÝãþýûø|>crr’²²2Ün7±XìŸmmm?f�·^}5O´î1DµR–(õ’rœü‡u4Ík­­­uÁ`°Ð"Âùóç),,¤¼¼œŠŠ FGGI&“É�;wþvxxø€['“¯) ëµÛý©Ë¶²¦!ÓÜ,"Ï TÜeÛ]û"‘»¿Ù±c#"«[MóµÔÐPg{{»¯¸¸øû6l`ݺu(¥p�ÇCww·Äãñ鬟�Rq ƒÈ¼J&í¯´ R \¥â¶Ûý~‹iz”ã$Ad~…Ç3‰DŽmݺÕv¹\¸\.nݺŵkר««óuww¿¹qãÆ å8ýŸ7…ÃÖ¯"‘/r³´ÇóàAÄ­@VÂM}}›ÂaëíááÏ:::Þ(((pû|>b±£££8ŽCMM �­õÚÎÎ竪ªž[ö= ¥*“¹ ”z‘y`Ñ)Ì)ñ677ŸÒZ—”””�N§ñz½8ŽCII óóóضÍÚµkËš››ßXþñtœj”ú¨Á²Ž�¾–£Ú[·lùy}}ý7ý~?ãããäççÇ,˺SYYI&“annŽÒÒR¦¦¦H§Ó©eà ÛBäù�iþan~þÏÀlŽ~bõꆡ¡!U\\ŒÏçcffÆÙ»woO{{û¦+W®üýæÍ›TTTpçÎ|>ýýýŸ‰§žúÌH¥~˜uQ©Ô++ÿ±/¹›L&«0Œß­Zõ#—×»)5;ûW€FËÚ382òËêêjçêÕ«pâĉ�Ž9ò³‰‰‰›�@ ÕZ§ggg?ïééùàèÑ£-ËNñ?À}àÀ�®ÁÁÁÑ®®®a`Õý1ààË�п ÎÆŸ¬bgúIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/edit/icons/patch_dark_flat.svg0000644000175000017500000007206514757047403026543 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8971007 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/edit/tests/0000755000175000017500000000000015153325403022717 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/edit/tests/__init__.py0000644000175000017500000000000014757047403025030 0ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9011006 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/icons/0000755000175000017500000000000015153325403021743 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/icons/deprecated.png0000644000175000017500000003720215143647637024574 0ustar00paynopayno‰PNG  IHDR––<qâÅzTXtRaw profile type exifxÚmP[à ûç;B^ÐpºuÒn°ãÏ@ZµÛ,aBŒŒIÚÞ¯gºu[²¼x©¥`Õª4Nm0“ ¨%4¾öÓ!ZŠ]çÑ£Ï{Ÿƒ¹5Tùdä÷Ö«P-üýË(ÒžHP<öDa¤2ƒ6¿E¥úrþºÑ>Wê´†ëHD¿g[0½GÆ;*²)+�UmоrÒ�Á¤Á¨qiô%’` ÿæ´#}]àYàt¼¿„iCCPICC profilexœ}‘=HÃ@Å_[ký¨8ØAD!Cu²‹Š8Ö*¡B¨Zu0¹ôChÒ�¤¸8 ®?«.κ:¸ ‚àˆ»à¤è"%þ/)´ˆñà¸ïî=îÞþz™©fGP5ËH'B6·"„^Ñ‹N1‚n‰™ú¬(¦à9¾îáãë]ŒgyŸûsô)y“>�8ÎtÃ"^'žÞ´tÎûÄV’âsâqƒ.HüÈuÙå7ÎE‡ý<3bdÒsÄb¡ØÆr³’¡OGU£|Öe…ógµ\eÍ{ò†óÚò×i#‰,B„Ul  1Z5RL¤i?áárü"¹drm€‘c¨�?øüîÖ,LN¸Iá|±í�Q ´ 4j¶ý}lÛ� ð \i-¥Ì|’^kiÑ# ¸¸niòp¹ >é’!9R€¦¿PÞÏè›rÀÀ-гêöÖÜÇé�¡®R7ÀÁ!0V¤ì5�wwµ÷öï™f?6HrŽþ© xiTXtXML:com.adobe.xmp  ¼ïDÍÞ$‡›€¯± ÿSbÎEↆI"�Ó.‰õ¿Bª•D¢áoÀ�D2ûœ¸¾#Æ!ù…D¦ �t‚ÐïÃŒ‡D"Ý\ë†Y”7‘ @C€S½6™mÀ6’œ~z‹rxßoU§q±§b<Í$‹�\Rˆâû{öp3�£Ž#xÉÕ.¸àB1�¤!S¨$× +kïî ‹‹T)T"•½N�Á9™B×2¥F”‰Fþ�P ,*�Ãp‘ÌáB%-õpçWGº «îC ŸÅW—‰"\Ä’íHʱŠfÀM‘Àÿ¢œ>ÞBR-¯‰x¶»$Vq!›×‘<…¤#Þuº±ôÄ#8��oÈä°\EM—ÕÊsÄß–ž­çlÇ�T¾Dò ’2…9…€!b1�â ‹W.k-Ž<œ"ÕvÜ€En‡p *¬4É�y¾ù›“œ¤gˆ‹!S0N¦ÐÌI‰e›j]Ä*^‰5 Ø &:uíIü!Ÿ¤©çðº,¦ X€}@/1 ƒRT·Ñ)j;U^-z`£ÑU1Ü¥c•fMÏï@c ÌIê|Kr9žbªÎU<õ[-¾º�†:"ž.«ðÓv~øÉA`žLWÝsU’ LžúÑÀŸÀ. ïýHª2-±ä*jb ;’L$ÿÉöõù~hDG ¼1à�aœò ÞH<�À É-£d» d IþÁ�+¤sI 5þ^ﱌ`ÜI4hÑ‹þ\p«¤HõµÑñ_0CpXa$J0?APÄNɧ�þD²Éw"‰“NÝf dò+PͤþgS_ ઋXEÕVkÐ’I‚$A� I„‘䆲¨À�lø'.ßPþfdÁ ãà–žY9`�p͆ *ï nZôU>¾Z‚üì>î `¨HäœJÝï9`qž� |XÒíQª£d >h Ba  �H‚D¿WH”I¨IgVÒ!.^W>ç®ÂùkpáœM3“粑H—®›IT”ðÒA¥@¨�*A‹г)hÝ�zr9MUI‰Æ†hpÿŸ åÜñÅ ¾ðÊ>H<‘”Gdv �CŒßžjŸu뜿ª�åâu8“¦ü=›®[ÿ–•Sú:Q|+H}ÎD˜u"‰'TêWû�PãW—ÑRGôçr‰KꙄ°PDÁÏJ’ ¼¬X⎰J$¤«(=#‰ í ËÎQ$Gî0tù†BŠ\©rÞ(erÉS’å^cÃxèÚÈX«’ê"‰¿U¸3ªàÆp  ï:kEÊT¦"yØ�–žEEJ!õê£�AFܾWo)ÿßʄ뷕ÿÓ3áÆm¸rSn.ݰ&Ð¥�v³ìêÁ¶Lz”H`Q±«‚ë*Ä ‘À²"ѱ¦¬…ÜÌTUÈߨé™�•�‡4YæãƒBšÛw”ßÊ")Š®YV(öV$“S\E#c œ/2åýõÏ] ZZP?ÊêðP«×—L& €cH^I\¼«á*–l™BO$#Ðð l*Dµ]å]–Õ†ÔjÀß[q ä~ü½Áß Êû€‡èÜÀÇ8mí­£Íåï‹y‹«7­+23K1(®ß†Ìleè¿‘¡Œ ·2!í–ùÿÛw v8|0j…)ƒªä:måtdò3cñˆxÐDÄqE¥.ÕIG$ÇÈaŽ33ÿsî†ÂÂà j…Ct8T „ˆòâaþ^ÞL"_ÏRYü;ž±š ¸C¿<¤¨L&£€i*t©§‘,7‰-Í�î.b9€¯'tª¯XTm£¡Zˆ"�Tà*‚«ÆP“J6~¿¼\5Zj9ÀucebàÜ�äwyjð3Nó”Câ�ÀÃh5û>ü�ø�ÝœÀÀhxßF€_];寥r\ê“縛ü� âtK+±tnPÎË<´xºƒ—;¸»�¯‡2”ø{) ÿ™4øî�Ù€P‹q]á•^àg[úä x8‡ä,‚KdsÉ?–H™J¤q™–uì Ì*ñž#9bç{µ®…¬¼Þ Ü)‰¥оQÁ'�î‘û¿q8±$Ž¿—ù¼r^ЇÙY«(y lÞ¯îü~-aŽ9øw?ð’d„Ñ|–̉¼âðFGÙN5¶#ˆµ"eŽcRÉåTAKe$ixq@Ä¡Êý*S¨Š$ -éèø¿¯¬AòPÙJÚÂR•U»èx�牣ä-&ˆß¦#µ… ÉMkW8ƒl$×\5VÂu£þpÍhÚ^E ‘Ü@ƒ;’Ç�J72 d˜"ÅaË$e®ãA˜ˆã¶\IC4tFÃ.gâ½åø¡ã5  pÁ‘À–”áºH–Ï7õ àUxÏÞªg™Jk$ï�¬q-Y_+¡á_Hê¡åeÑŸƒªßoÕ0ÐØ+­b¾Š‡X8HÓ\Cr ŒEQ¾Æï$ih¸†�k¸q Áu²¸&’pÊ›eô¿ Pwüy¶àóƒýàÜÛ&]*U$’¨BJTBиÎ6‰AÜ(ÔÈ”J] |gòÿäÇ‘È�‹��Øžª’À‘È¿ U&‰ •Ž@] ü"’ù©$Go74ÆpXÁu$9¸sSÄïøkG_¨f¬ N©0 [Ô°PÐ…cÉ$õôV›UÇ1¹‚Îâiþ*Dê À8™Êz‘À¦ë–à��UØŸÿÀB¹Š­NOˬAG*k�FÙÂ\‘Äø’"–FÄsLÄsLô粈'­DH¥«Àé+J8Š#¨„çì|Évý•?VMª`P"&œQwI³ª¦w9´Ä´dÛÑ$Ó�I-dl,O•T,lÔ©óf“bÙéÅÑ\ÃWš½ýÿËvý•ŽÅêçþ«FbEVP¢1�½u¯Š&>6óZ}Xé vu^)zè®|V�;¶Þã&>+òÑ%•n2•¥ÞZ�x¶½5µKË*§ˆaÕMnG’î`R¦³�•xØ^Â%â!×àoófwØ*²ó V呚Ÿ� KY°ÖŽ¿ÌS.·-ÍD_#cqÿ ˆWÏU]x5’–Àó2•þ¹_¿÷�µä*Ä’ÊPƒ„ƒgUËZ®¡JÐ$qR$Ò†;”ÑÈÓ"ŽÛy,ÇvRÏ6*p�L®J='¤žW,T â’1÷-:V[=¿?�ÌppÝú¼>&™ÂSRÏ.ܸ‰·¥ž]RÏäš�Áh¨BQ"Ù9i%õ •z¾�zFÛ=ga¾°g÷R­¼#‰uì¢2ãïµÃ­HÙÑ©G â†-ËWê | t°Ð�*Ópc§üÀ<(’Ð#6#¶¢¡—-½O$ñð*Ø´¼?ÂÃ,Œeš‹`�Ñ Ím«&À2©'5¯á!â¸-â9á(ñˆ�áíà= 0O¦Xw ÓýG‘ŒŽkб&ï9c»(e*ñU:r;nœ&ðX¿ z©pXxܾ‰´ËwßÜì0‰~œuÐ[¿Ô‘,IÖ®¹œ0Üè� 2’tßÏVG�ÑQÛIp-_‹xk—Iö â¤âwÃÍ~€÷8‘È[*ün�ÑàË~±.#õÜÂ<Ý�- ¿(ãÄ|´%O¬ê ”Ùü}/ìøšS *Àè-’t‰lÈSQ3€ÉÆŽ“…`¢H°ï³’©¤ zîsp£’#’‰ü†öKžfÍõÛdå(¡?­kCÕà|çž%ŠÊö$”qÝág˜§�N}D¢u©çNžN%E¢ãÑ쥞ˆ}–¿=ý¢4 …&Ùs@…âîë©X…F)ò¥ R=¼h!�ݑ̓+iY€4jª¢œZ²‹Ç/d?àßÕªUÛúWÈÄÏ6‹ð�}‡?ÊO¢Ë»ÕùôWëq ‚ÓT±{·;ÌÅz.3 X+×XI'üžçÊßÔÖ©V|‡,yb sæ5>¬èpÂtí�6Néa‡�pÛ`•FF@1Ö„ðfË–-¬[·NL�:•&MšÐ°aC¦N�ÊÖ|ÌÜ_[°a�2íe¡%ûPÞž6¾�à¶uРH ð)‚Ó¾‰<¨¶Ð»^³­N•‰••‡T¬ÿUájÐ٩䂆ý*;Áñb¬‡ÖÀйsç ___ZµjEëÖ­y衇hÙ²%¾¾¾Ì[°�¤Åpê«úT÷¼cÇdËW"‘Þ"�Š"Aé˜S·t¯éË¥×AZàðyuA~V¡Ö±_Ù!EAæ÷×*¤Õ<Š-ÜÄO±xáÂ…¢~ýúL˜0�}ûÌþÜ}ûö1a¢££ycÞÛÌÛ(rëj—ƒ_Úøî<·ØSPaÌÄëÍ ÖVmTšËïª7öJ”Xr! DWüqJÝ5>¬,n؈LˆgÖù r�¼hi`c˜œ³´Ì)Æ úþµk×®Õ«W/>ÿüs>ýôÓü®õëY·n={öäÇ Ñì;�AŒ&!¬Âg.!yÊQ¶›)ù]%Ã+è¹ûdá�\EŒÔ#¥ùòãHpüùc¦r¾L)xâYê©-Sh+רӋä*”zÎæ–'Ïç=9­Ø:ayàÜÊ•+å±cÇdLLŒé]§ —Ó‡›Žcbbä±cÇäŠ+dó*\Ǽ½@wƒLå™B[K_œ=¤>—ßÍ0µ>ÜO�zâs¯w3ǤÒj�ËM�ýi‘—g%�2•©RÏO2…Ÿe*Ëe �³káý¾}ûÊ7nȹsçšÞµu�<»)Fžýª±lÕ@gú~Μ92==]öïß_ïõ¨æo˜P/Òzø+(dv¿R’½H¦ð¯\bEG8&V�P )’ÂÜÿh¬Óé®lÙ²E33“ &P¾|y† Bê÷¦UM­0ð½\eµLÌ!ôÏâþÓQkKpQ’µ®%¦©·‡w,É)�Uæ”�‡Ï9M¬L,2£hfÃBªŒ}­¾9Í@ S�ðGýZ½»A¿5j4NNNfÙ²eüüóϦ^Tw��4}:Á”gª˜Žþùg–/_Nrr2«ÿ¬Æ^³‹7™bZ®¤–La½Ô³K¦ò•\eö®¿¸Ö:³Múû<Ü­1ä>ÿä~¾ûnÏ…<¦KIË`^~Dežßj!&iuÝ3&&†U«V‘™©„Ë&?æO¯ö�ê2•IèÝ>��Ý•òÎ�;èõz6lHܰñÞVÈ1�CŽÅ¢ ;ï#°^2­7U„†Oòœ¶<ßu*"IKÌO!õjí;�^t|~Ÿðóhÿ¤HÌWjž9æõüÕ™°'_¯^½åëÖ­s?yò$�:)6„Î 6-ЦýƒþNÝì›_®ÑuäA2�rióæÍT©R…�}{3ó±¿=ô/óúDcâ¶Ÿ°\h+8ŽŽ¦¹‰Û¢#8xVù_êyAkàg‘Àܼl‰H,£%QàHa\ šB†¯Dñð]gÜDÃsÅðÊ^ÀK p÷óócüxóÊ÷§»Ñ®Y9§oØ®™?ÉÝMÇ&L \¹rôŠÀÐ¥TÀ"ÔXÄqǸ¨u*‚µÞ@Ö٧>nÖÉD" Dq…%UÉ …g©š;.R©¸W ´’³…Ú¸HÄ’Í›Y]þ:‹xvÃOi×®]ôСCÙ´i“)$&º’–W†D¨°ÛWäaÚ�ŠDWVùýû÷³aÞ}öYÂt¨ŽEk©.\‰¼f$Ì‹–I×j„R³ÿb¾/Ê.bYºTJ¬ˆò>¬~*ÖõÙ#× nˆDz¡¡1‚!ÀPÝI£NÞXð"B]ooï!cÇŽåÚµkŒ;i }¦W(aA…¾qh�ƒ{…­^É„ HKKcôèÑx{{…ün“÷åoóIÝŠ>CsÉ,±—TÉÕîŽ]RwI¤9øå¬­U0RO¸±—V‘Í[b€ýôÒ"ž=PpÀ[aô#�<Ü®];F�͵kJz°Ú•ÜÐ3Ü*Ana¤Ö€ža,ùø"‡Og‘––Æ´iÓ˜7o�;w^¿~ýxP|wr%µ¼‰ â3±\B0UÄóKTuPpR•Âý%Á«Tf!ÿH•1pBE&Ìso+Éi�ïD"[ÝïC‚Èa/XÍAÒØÙ<]EŒX`ë‘#G´iiiôèуóçÏ£ÑÀ7‹£iû€m…Ý`€ìIv¶AÉEë¦ÁM+ì’pç®k´z� ¡¡¡|þùçP³fÍ £\É~4ü‘Ç—u -MçoÀoÌ*~-ê×”�ĪŠ3 ÐܵŠËxíCëØ<¤¨it –ü€×§OŸ® gæÌ™œ?¯Ð>ühZÏ×f7ÿçj6ËÖŸ£ÁS»ñióÞm~£QÜn–­?Ï•kÙ6EA“:¾ÄuR*èÂ… Ìš5‹°°0¦OŸ®fÞÈd MiCl‘Jêi%õŒW3¥SºˆeÌP|þªº8÷ðòIÖ46â�¤�=š…B`»ü^ƒV¦0HêÙ,õ‘zvÈ&ËåŽ#3UàÑÈÈÈY½z5ëÖ­3ýð|ÿŠøúä_«pæÂžžú'ƒgœäð)s®Ìƒ'³<ãOOý“³óGGûúh“`Nú¼nÝ:Ö¬YCRRüvÌj ˜eýT²1š ¾ÇÁ”Ni%VE€“*UðÈ V$ª-?ÊG˜£v.½X©üÉäÿ:£ä€h‹àuÜøU®¢Ú]¼_0oîܹ///RRRL?¼1<‚øås†æ$óSOóåöÃÑ¿øþ V�!Ç ó9M›ÕõeÖ󂀕+WâééÉüùó5SVóÐmÛÑúÙè¤#q0¥c™qÆÖ$t‰K®A‹1³Ýé+ꮉ¨�oèsÏsüp-ÏYGÐå÷[ؖ®f�øÂ^v�õ¥ž={FvìØ‘uëÖñí·ßРšOt 6¯‹´�žÈ`Î*Ç–Ì›ú‹üu*Ê! W‡TSÚyçÎ�¬]»–öíÛÒ°g…Ï~ã¢ÕzDÁq�§Í¬ÐyÇhŸ|>H‹yBÎW:$ÖÂs}Xj%VH9«uwk?–Hæ >FÙ¤{)Y´q¶�£ú:ràF¿B¼ae yðàÁœ>}šaÆ™~x¦w85+Ùæê†ïÓT?`ã÷WmêZ5+{òL/³Ô9r$§OŸfðàÁ ù70/×Az-ƒ–6·KùÖXwÎýùâØÜK‡»!‡Š¹t>¥RbúZ½ø363¹$³xJ¥L銺Pä®P€Ô³me¿5xðà€:0eÊÓ�ôdhï0»^¹®~eÙå«™öŒ"†>Ʀ.óÕo›†Ä×_�øAÏV¨4ú½*À“€Á¾ÞÁNs6wJ‡HX½à(2¥žñÀXàw[ó„%C,�Y?:õO!ˆe_ŸrÚ*Uq^ “wîQ½zõÇF�Åþýûyë-%ÞÎÇCð|ÿŠètö_õ™%+øÙ?W§Ó0²_ßí>ÊÍLɼyóèÓ§#FŒ`ëÖ­Ýþúë¯î`ñ®1ÁÈãÇö9‰¼ ¼[º”w KMíPh©›Æ•"(Å?*Ëzɉ{zû÷ïï^±bE†j{müèØ¼|~ÝÊr¸PŸ5¨ s…€ŽÍ+Ð¥�¹Ò† Fdd$ýû÷w^Õ±ø× Þ{bI³?åü5•&–¹ÒÅ(2U=FO ™J¹’H„ùFeY�ñÌ k5fÌ6nÜh àxsTUN1N镘Äúlj]l<ÝMMxKÅéöVáÌŠ+ðpƒ·ÆVuÊm�·áC;>ƒÜ ¥ÇdÉIDATEÜ\—Æ[c«¢3Ú))):tˆY³f1åÓŽ_æ<‚D1À¼¼N¦Ò ø?4üH*o«}Ö½Ÿ„–d"ÀÉ 5Ž^€†Ê cU*rDÄÒÜ©GNCCŸ€iíœHÆ‹ëÀ(;—m4v“É6Àº_ KŸAÔ®]›'žxÂnÜñAo:µ¨PèFpsh5�c'öÀM«œSh-D@Çèô 7~¼Å¹sç˜4iŸ|ò �' ¦ê˜Yû�Ïó\ö„…zÂèX-•:VF‚CXìæÎ©B$«N RY–¥�Ýb*i®çYü<ÌùFŒÁæÍ›Ù¼y³é·×†UÅÏW{WU£Õ ¼tö‰ãå.p»Ë]j|}´ÌnvšnÞ¼™M›61|øpŒÆJ« |kQ_›JóPx  ¼7ª{÷¯Ö¹ešâ™>N9SÍïKHe¾0# f~¦aúüexzzZéVS„P¯†w›¬Zç¦ÅÇÓ~¥x{ tîwG^$Ô©îÔ¡¦¯–.]Ч§'Ë–-ÓhµÚ…`Ö/E+0Ð ÁS\ɳÏu)“Xg¼tVQ â¿G­®oáô3ï°lÎ3þ^`QcÉI 1:|¹‹}ç¼céÞ½;z½žmÛ¶ ˆïŠÎýî§Ý<=4x{Ù¿��—ÀSw÷M¦s$v %"P¹×Ö­[ÑëõôèÑƒØØØpãpgz�Hf›Hàcµ‘%%%±Lé†"UúÏ_³JuÔÑi.â‚`Q1‚ã¡jˆJàèSï9lÄH®\¹Â¬Yfâ £¨SÝ»H*ÆÇKS ÄòñøxM“Õ®êÅä�fÛÌ™3¹|ù2#GŽÔõÎÈ»¹ÿ½'–Á¼.0ʉ-�6š#£ª&O¨HàSr¨‡ Éc@#‘¬zçEƒ Œ��%%%…K—”ø¿ͼé×%˜¢Ú¯ÁÏ[‹�WÁC¡Ÿ·¶h&¡ï£Áth¦ä¹téz½žØØX„ã¬<¥Ì*Ôp*·!ª«¿lÃý¨©Rºbcón¹-™¼´¡å%ËÐñ4akÉ“bV—ÃÀcV–³À"‘¯€�† ÆÁƒ™1üûîsO…T޽Ȫ¦¼¯¶@‰äã¥Áß·èš,¨¼;Ï=Á׿)U2cÆ zôèÁÈ‘#Ù¼ys§3gδ•A‘%.±tìÆØÇ›TQÙw‡,<ðÂŽW\!Õt 0”>VÕy× ÃÀVc6å(˾¼½œNÀËO=õ”W­ZµxåóÖ5�¶ðæñØÀ¢­O-X…:�γh›ìñö�<ÖÚ<”¿òÊ+Ô¨Qƒ'Ÿ|Òx ·Óê='–qÉÑ€¶Ñê¯Ë̶HƒˆuŠC <–縭\¥"“Jù’­i<Ìü:uê´�8q"Û¶m3͆”×ðƨjh‹aƒZ/ûÉÇ»è­F0cD5‚ý*ìØ±ƒ-[¶0iÒ$¢££Ûƒï‰¥àK€¡£2@6ØÂÊ›$Ö_vNË›ùî*’‚ˆü› ¤gÀÊšš“'OÆËË‹#F�‘¡Ì- êD½"RØó"Àßþ´N@9]±<³^5o÷R2gddðÜsÏáááÁ”)SÐh4ãÁöf ¥�X9,Ë_ê©î’Á±`ÊOfà ;§½ ¦Ig0AÕVpvçsq�߯G»÷ìÙ“E‹™øFö�tn\H�:<È~LVD°ÃÎnnn‚}ÌFàÅ‹yûí·éÑ£õêÕ« ½/ˆ%žæRYúÄ0·¿il qe+îã˜ÍŒ|ˆD~GK4�Ô‰,QU%‹ßG¹Çÿ¤ÃX=¼³ø]NŸ>MjjªRYпZ•°àâ‘HèÖÆþÈÝ­MyŠkÇÀ°`)¯V5%_Yµj§OŸÎ ^œŒ­™‹R8bô•lÛv¾ÕÎï�´!l}Aq¨éäÐ_Là —,õ �+ÍÙÁ.“È*‘˜ßj,< ŒË2ðÉ‚Mk÷<Íš5cáÂ…9¢D*wlæÉ£mîj>бEûðú°pÓD1( pßNÃÚ>ÅF,! k›:> HÌdz`Áš4i˜1cÜ�7p"Œ¹Dww’kÐr‡×�ŒÍ-ô¹«ðÇi%>¨v8Ô7Ë^Æ@‘ÌOÆ,À»�½è:nÔý8UDÅj lÞ³g�Ç¥K—LÙ�6ίE—‡+PÜûŒfÞ1ðÕ�iüyLQëTóáÑV®M¼{vÁ¦ïÒèú¼Ù½÷ÕW_FLLÌà`Gi—Xˆ8rD/"©ƒdp"¼²`R=†õï·w¦yÛ×ø|É’%UºuëFÓ¦MM±VãB˜=¦*e çýÍìTe¹eXX¿þú+7ndèСÇ�¡à¼šûõÅE7E"kœ%•±;åM¸æõÕïÌíÚµk•¾}û²råJ©T×1>)ª„^²äºþøä(êWS,¦óçϳråJúöíK×®]«3ðI»g�;pæ ´�z{ÕÇŸyQ£F ¥× H�^…¾]B‹Ï´�ké9\ú'“Ÿö+S -øè�¿¯öÞÕ‘„Õ_] þåã¹;ŠqäÈ®\¹B�=n^¸p¡uÞÿ%‰uWðde®uc�È¥Û8Ö²]'¯ 0yòdÓiõ«»Ñ£]н#•€í¿^cà+©Ù{?I¯üMÒ+S³÷~M;ÄŽß®Ý3Q toLÃf¿Ç‹/¾H½zõèܹ³0�‚ʤÄ2öHÁ*ê¿ôMæïðY±wï^}¸yó& øþƒhZÇ”»gâ‡=׉›xˆsWl½GhXýfmZÇ”»gdÿïÞ´ø' ñññaõêÕÔ©S‡zõê‘‘‘ñ8v’¸iÊ*±„@Šξ±I3yÞ¼y„††òÖ[oIcûÒ´î½³³²%/,øË.©Î^10yá1²²å=+Wã:>Œ�WÜ7oÞdöìÙ„„„°hÑ"4Í›`;ëa™%–ñµjÕªÙ­[7V¬XÁ7ߘC�ô/’0`g†Àö;žÖü~_æ==t’{˜æ~ûí·¬X±‚Ç{ŒZµjÕ@™>+›Ä’Ëñ”)¼*S™%WšzX(0ýõ×_×ܸqƒ¥KÍ{ŒÏW‘z5¼ïi9 >¯Ó/ܸ§e«_Ý›ùcÍi[—.]Ê�7˜5k–%þ-¬lJ,-“LE2 o•Î9ôïܹ3k×®eÿ~eÒ¶1ôétO­@ƒAýð–c�÷¶pú>DlÅé¾ÿ~Ö¬YC‡xæ™gÊsò*òeƒX‚h‹ÿ+�´ZmÏÄÄD<ÈK/½dú9©{DñE/€FµÔës1µîý @h�Ž„næ°¬—_~™�››[O°ÞЦlK™‡LÒ‘ÌæŽ=Ú/&&†9sÌÉjzµ+Gÿ.A÷d>0OùèØÜŸš:º²ŽÍýK¤Œñ]‚x¼­9ó¼yóhܸ1£F�ò5J-QæÜ r;n\Â]ÄѯAƒÿÞ´i“8|ø0íÛ· ¼‚àóùÑ4«_®dÊ'aǯWybüaÒnÚfM€¯à“9µhÛ¬ü=ªs±ëÀ º?ÿ'çÒ”2~ýõ×DGGÓ¥K¹oß¾gP6\�eÆ*±d‹8<�±ÉÉÉÂËË+wY9�[•#¦Ž_Iº?x¨©?ëçÕ&È_XG#”8ûõoÕ¦Mÿ#@£Ú¾<ÚÚ¼Ïâˆ#Ðét$%% `ÆÌ‡eÍA:±qãÆ³¶mÛÆ²e˘0aå}4ìùOC*Gx”ŠBž¿œÅÎ߯‘~Sq?øùêx¨±?aA|§ÎgRÿ©}\¿¥øÜfϞ͠AƒèС»wïž Ì,KÄ nß¾½BÍš5iß¾=‡F#àß/U&¹Gh¡6ý.‹0$ú/.0ðµ$Ô¨QƒíÛ·sôèQbccÓ€ÚeÉAÚ¢Y³f¾ÕªUcÉ’%>¬DI6ªéF·‡Ñh…9šÀõ)ð£Ñ º>HãZЇáèÑ£¼ÿþûT­Z•¦M›úÍÝʱ*k|}}ٲŜ@¹Ve?6ýp)]’ÈY�°F%?vR¶ÃÛºu+Ï?ÿ<ÁÁÁ  ,ëüåË— 7oÞÔ6kÖŒŸV2N®ÞšÆê­i.¦Ü%xàÒÓÓ¹|ùrp®,½{y!Äå;vÈ¿ÿþ[6jÔH*Þ×çn?111òøñãòÛo¿•�æ2P¾¬i«ÏÇÄÄÌÿè£�ðòòB¯×óÃ?�™™é9…€§§'­[·&!!�[·nѯ_?öîÝû<°°¬ËøwLLL¿ùóçS³fMÜÝÝÂe RJ²²²8|ø0£G�fïÞ½ÿ·Êb�zÀ—4hà.\Ä*<±Îž=+ÿøã�tà5”]WoBŽ ü�–Fÿ–‹Y…äJ"–ŸPvNsÁ\pÁ\pÁî7ü?Dìâôz´ÆIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/icons/tomwer.png0000644000175000017500000002144014757047403024001 0ustar00paynopayno‰PNG  IHDR––<qâbKGDÿÿÿ ½§“ pHYsÄÄ•+tIMEá 5J’“” IDATxÚí�y˜ÕÕÆ§ºgcØ÷Mv•hÔ¸G#w£F Ìô5nÄ}‰FqIBw“b™îÁ8ƨŸ{45jâŠ(1( È.ËÀ00k÷ùþ¨šî®îêîêa†n Þç™gz©ÛUuï[çžsî¹ç€{�¸ëè´«u�á±' 1¦°å”M@%ƒù×N;y„™À„/nòFÃ<“*¢• Ñj ÷´{÷¦ÂŽ"U%CñÂrX£•œ¼G©{Ä Ï£zæ™Ìgm J_|@ïÊê\Xuó€‰qm`0d,-™¤U| Ø&åü· ×YŠp7ÊÞø¸]ʘïI¬ŽB ¿D9ef=XAÊVáUùL«ØÛE³}Þ÷æ‹8KÏé<óñâY”wPi%w¶ATL.@K„Jo*ìX¹ì‹{W”©æãˆs; âÂJSÞJøä ¾Êà$]ň›2…«´’oeé"‰SŸG¬Ž•X3€�€Ï€k³jûÝ IÒ�±]37"ü ˆ �3e‘ ¤éðPì›ÕõúÏ[®ŠK<+Ÿu´ ÇàRáη¤s(–©4¸:ÖôÔ¿÷Q=ûIË=«p÷´�<ƒò?à>йÍõ“ë’TõÔ_| ¼ühW$Õ-±´Š½‰pJ#Ê_drjýGgÓƒ^Ò‹�ˆP„�XK>`Ð ¥„”í–d«Pj€�øÙDëåBëûö¸�‡éCÀÀGP&±Î#V®H5›})äß`CXEYˆò†TðUV?SMOyUÿ[#SÙ쫽ƪ�ôú¢ ú" Dè‡ÒôÑÊâM-°±6l5ÿ74ÃVkr«k€æ0D¶8È î�Àïƒ^�Í¿ž�¡_WèÝ%åéž.”k\ê~HÑ2)g^®Ç#¯£´’R|ôFé ô&Bo z¡ôAh}n’¨‘~Q�QlÒ! _ךk6ÃÚ-°n ¬®‰‘gƒE¤õµ1µ'J aH/ÖGŽ‚3C8 8@çp¨+©£¢¡`·Ÿ ut¦3�‰P tJQŠQº#ôŽN;z[ïûZŸõŠÝžk{¬Ýl’åëZXUcþ_]ëjíß5‡óï!*;BE ó7©àl—úÕÇ@?ë£ øØO&±!çÄÒ ×!qŠ(t±I2¡Ä6ÀJ7•(ÕUÌÿE@©E¢6;èZ¦äh�†6l5IÑ*UÖZR¦•<!Yv6ž»N>ÈêUe¤Tð… wÆ0ü\„1x0[+RCÜŒr=ð!>Îh/RŠÝG5fƒ†f¨o‚ÍÛÍ×Û¡¶Þ|]×[ëaÓ6sºY¿ÕN õ[¡fÛžgTœp¼r}ô�ž.å<Ð᪆P§BL“rnëÆÇ!�m�¦¢ ɃZ×Í- ¤i޽GLÒÔ7™ß퉤h¬Ûb{Û£ÃO¸�¬`3bEÆFXÛnÊû/ÿÏÐ|Á˜Á¶·‹¬ÞÎ4rð `Ê/¥‚¯whºK‹VrÊ¥¼I9/´!„:¥ò®{ê@ú èÖÉt ´þuëÝJ {)ù¡Ð¥Ö²u§B(²l®n%`Ä­[lÞfïÈÆfÓ ¨­‡ÆsêßÚ`Î Û¡f{ìu}ì;fŸûô7' " kuÚj5…4òà›q§XN‡È6¹Ô¥&¡ŒCYF˜;³YØíÜ mE‘ö£À^½``wèÛ úwƒÝc$ê\œ——ß„ðcÛJ@H0”F¦3\èRSPæDE‰�#€Ó#˜�0ÖFÊpfRé†ác(J %,’ ¸r¿j%ÃQú㣎Bþ›¶�P�r0Ô&máO.»ö`Pb½¿GÊ-ÉÛA�÷nC}†I0‰ä÷¥”Ù ¥a³Õ µ–þ°Å2m7#(ÊV P~ ÙÚ}/6¥X&üý:s j)¢¿L ^çr ßÃàýlâ½u6](ävàÛÀ:„û¤œ¿§Q†÷G™e}6€[)ç�©v=kˆcP~dSÄár ðT"Áà”1ÀR|ü\&ñ?×÷WÅ"œ|$[ÌWÇ+�ƒ´a ʰþL}ÄüL¬Ï” ¶a ~¶ ÔÒÌ© +o–å¾`ÿëàÓÕé�ïÓÖü.ªK…$@À…”‚ð= –&^�ilmÓÌb"¼õÿ$ãN p�ÃàŽ%Âó8/U)p�øs›®IBŒö'Â;2™·s9{û1¬pX¡%LÛdBÇο)ô…V±Â…}ä¨8]2K& r:ðXtP Y¦�ð=™ÂÒ6 `0 ©®ÒOI9oFÛÍ¢ªH½þ)ÀýZÅËY/ËTSHˆÇ�Ó-íä.©àê\Ë�2–IËd¤Œšœ�Ê$Ö~+7™á(™p؈¸7ÞÉ aºÁ„A�Á½Y_g�c€C2ÚaÊOlŸ”rfèN:”aZÖ×ÔÈQRÅ®à* rlΈ•î���˜&õ'.“õÛvPG1Ÿ¦=8Ì0ÌEñÄá?^5ËáH—G–ðàܦvî®ilЇõ;1^¿ŸLÏn†ç¼~“sÿå‡ko†1#&­r×ä[ã/ßÏh‰ùhI¡IÖe“ZȬb—TlkÔiöf“i9‰�ºŽ®KæÆ¼ýÇÝáÜù±™"˜֗n$Ö f4¦õ´~äbˆƒc^«ym�nwQ'JÑÅ;ä³J?ï8ÝÇ6"<Ýî³KˆS5Ä[´«?ù®�Úù²K'+b�hˆŒ&·L ŒrD•é`.EÎ[¸ô~Š´šnŽ?ÖÄ à";ŸP• 5Ÿ–²ðx Y±Îq–fRÎ?®ˆûýuD(sÏÕ]ø1”£€ŸjˆI­ÿñU»äÊb©¹4¢ð¿Õ.ˆeW�G¹4|%¾M])¢TL‘ Ô'XŽÇk�WèA-�lÖ Ë5È-ñ*ÓØŠrE†Ó½F!�ÙÎ?‰u(¿ÈÐî©D“VrŽy?ÛðS¯AÞ× SÈu/EôÁ`ƒ,“³“VäB òŒ¹<å1÷'…=äµòŽ˜kÙ׿Š&ì;ÀFÊqY�j[�,_ r!ðà„8ýh0?¯ëìØz TD˜Ž/cp¦“Þ'ü ¸-ïG)ŠIëšîB¨¶¬ÐÖ±:xXƒ„ ™@½”±îˆóõï†í–˜ûâ€AÈ¢U1I¥Š¤òÓýv"rÍ£y°�P+¹Cƒ¨ÑÑQHÿ7ªŸy¬Q­L/…šÿÒ*Û6±Œþ„‚xRÎKbMa ¸Êº&g¦¸Á¾1dÆY ƒ'›“ÔÎE$©?‡kŸVý*âÂÞÞ'5±d"+€Ë2üÌ2Ͻ+. ¸³»LP­d6Â�ý?[~­b£‘Ëm÷.|I!wµ¾=�ž—ÎåÃKçò¡Y�p ð)�c»–Bê}9‘X–%1à󶸌6†¯ æ�ÀiŽØ†ÁEym3“ô[ÉÖÓ•6L ÉÚÔz3Âã¿Âà°øl€7ÿ ¦“I€û¤œ ©HåÎxÍV3¼u^^ìRqÒË&íÚT¸HÆÒ¢³9…B*!)ðï  \Êx?Ÿy%¨Ó c1×X¿›ðõ™šüàYi‹nwúÍQýØ{ÒÒ/Ng‹ÜèXñ®—k`÷8ÖDûúR Ì4¶J€318áàB„Ó¨a¿ÄXð¼%W€5à”#Q*€ ‰0ž"ÏTî÷¡iÉc~ݩퟡ97KÖjw-[ï®É XPðj§5= 23Ö}°˜î–©©])c¤xË{‚Uðà?®º|.û üa¯�e=ÂÍRÆ;ƒ{²ßù³Ó'UÙuˆe0¤•Ë]fÁ#VÒ– �Go¼ Œ»³h%g›§kwDÔAÚêË2ãEŽÕyzïst¾¢ª#†87k/0­Á5.  øL?–Õv•ÃÔz¥�T&ö¶ƒR9H›¹àŠ*Þu�þGk�«Ý,éä—IJ2¯Ýì.ªa@÷¸$k†Ã¶(MQ£YL§äw5>˜‚0Ó£½ å%Â<˜5ÿR^·C¸Lº¼TR$9S´†˜Š2Ëû®•\*ü~×�X˜þ•K|P‰öÕG“³$EÓ¯Ó�ª�¼Šðgà{˜9 ¾ƒðKü¼«U®–Nvú”¦!žÀtlÎC¨h�7™—&‡Ej‡ïR‡c/#Ã’N|ƧEèœK«ñae¶[¹É]›�=’¦¾‚„÷w[ŽúœÂd¯qœmù p\ŠoGá™TÙ]rBª,ÃetFì˜uÛy6¥ _ÅŽqü‰EBmK::ü:!«˜�«‰­>,·«oWÛõv?–LfŽþŠY¤ûO4sŒLpNpZ'Ì ±Œ˜~´bcˆ•ZŸÊÚ*uq\¯¼˜Íh‚lÂe¢^ô࿲+Äe%¹Ïús>&Ã:an¦Â8KÍíTØ+>À¸†Míp]^ëú¼�U](¥-á2Àï'“ê�[Û^ù6­B�ùSÖnqפgL}¬“é4º:M�Qâ�Ë ¼êòZóÂ3o¹>²—Y4ß‚åÉÄ:ü»±ˆM/]Ö…ˆ:GÅ]µ* òàs”W0øBCÜl(s»}¦E× øy(| Ìvq”-\fÿŒLŒswÚ;¸»«˜Å!·»Ì„ЭS´s3Ê8+Lö"›Õ¢ÜªAŽNÐFÎ…” ¶uLȇjðQd.“*ÎýîÀΉçÏ™ÄÚ˜E›â‚¨ÄÚîâðT»pN´I­‰¬¦ˆ#€_s¤ÖUâTàI¦�wÞ±Âi�t.½tFl|,×ÉXpœÆ?@8Þ.“bÇG*_´É;’ U³ŒmÖÄRWú•/…"žÔÖ¬ë�ëõ~Šœô7 Ñ•w €îô ¬!æá&+º ýäx„_¢ #ؤ•Ê@Zx±™ú>”qÇk%“¤Â9/{ÖÝâ|”Y6ÿšYêF 9Q«/eÔ€»p™–0ŸøûÿsHNî¡óM„:)ge{ÜO.Ü E`ãvM¬X޾­ädY, ‘ÅZÛícùXª~ƒ™?  å2)O^Åψ*Óø�üs²ÝuìHªJÆ X… .„Œˆ«VÀ »è #ùF©â¯åÜ4�ý5pO†_^H s㬻¾ˆ«êgÅ;?ñs°*Ãy‹ãÆ�ŽP±0›ÃFìÀ8Gx-î\/äóT¸ {§¸ ð®=·Ìm8giŠÏÓOȃ¹ M¹^ø §'ø¿öqÙ§�3BdˆprÊÊL©àþjªxö¨#ô€Am_” !Âx„sØ”Pç:ϬÂU¨iåõ,…�.ŠËþ{‰­ý‘À#YjuSÈH*òAÚK5c“.Ð*%Ì�­*_^ ˆ9IIG|ÔG½g™Ðl�n•É,Ô9LÓ¬RyÀR„9HR°ãI÷±#mâ*µî?h‡l2¯ä¿»!n_à v‹™êhSà�˺c¦±ÕÚ}ò(­eD„/ s©«öæºáüŒnäz°2ZoKœvYŸÝeý¹ƒ‹„ Þùi™vþT‰éƒ³(yô|,2jd[ò„J9Oæ„2”S€ƒd²ëúÎîÎ1�F+WW&Ü×nçLp„64sW¢#ô»ûsÒŽî̉e°¢ÕðÖÇ}³çÀå'FÅüÉ8„�h5>ùf²ŒÅø¸)>ôE¦°§-OD›ï´i5ð+ ¸ªg“8ÅÝBÇZ»XœðKm%YÜY¶q[䑨y롉:B_¾žïŽŸiÞóÀô\z7‹ý<Àî̉Uȇ–QÌ!ÃÜ7{cqܵèŸ “T·Ç毮­šB"¼leS…¹-ìY­blÖd* lcœeQÆOô5ÀÍ æ™áZ³»rˆ&;~¦V³h&þÕ5l*ö3 7©wubY"ús€ïŒvß®±6ņ©oŠÃNIxÿ­r‘I¥�qHR�>ÊumºÇ Ù.®¤ˆ¾VV›ÙN? p{¶õšÝºqÀõÑótvi!ïâS¡‰g�+Gõƒo….²]õéý»G;ziŠÃ×·Rà")ˆ$­?¶N¹Cvð!ª§=2Ú¸p)¤iû$j“Rsv_b…yWrÓðÃû379,5žIqØ­Ö4Ö3læW¥à >tœœ$9e¤ÎÀ`'a(‡í‘SË*¿r:Ð@KŠ@páRHc´\ç&õcû{•r+—æyw¿×<š:éÁCáÍ›£ YÊÁ©ô�G?Œޓ@Úq{» óÀ¶óy+ÊÑñùHµ’R„— NÇî—r~ºýpÂcĪȯ¾íZM!�¼íàR8Ôq7s —Ä*µ:ô€7?ƒªá_Ÿ�ÆìÄ!tQtÓjaŽ”),Ò‡éC§áÍöpXƒw©å€]C˜ß'þ®Vrâ°›ØàˆV -zì£ $ÌL«�ù„[‹qêŠñ³ÜAgü§솃†èŠòS„oK0¸»=6{h%¥Ài(´§û%·õ «ñÑÄí(W¶:.×l†OVBm½Y¦wLL»Ø@„Óe2o[$øsý¯?c¬¬É{½!^Dù¾C/Þ åÌŒ7‹Ntâ#ì±N�D8J&óaœ”<(…ÖÂv:9úl÷{ ò&p4f8Ó‘;ZA,wî»r–r~†²ÊÀòÝaü8û°(©6#üå™l•¡mf(±Eå®´dïh#jS(ùu v×9$Ða$ElKi§®éøM¥ÖŽ£Öø°â¸×»6±¢«à ©`º†Ÿ!GY ŸRD?)ç"[Qí–Å=é5(ÿlÓzµùRƒ,²bŽ\42«Á& ’’îH1?ØããËYŠózå<·¾. 2Uƒ|©•|ª•î‰!º�¤u©ªMS7{Wš ÛAG;ÅÒ±VeIªS°Wx¯ÇÏ(§ú†Óáå(·a®.¦HÀNl‡ßoŃàbÛ±U %B3ì8üå<7¹Su.bðaœ€Pààl¦3­¦„&N¤™�Òxïj~¬ö�rÛpÿ�âq:.!ž²„0Ç�¹0ßïÕÙ̦€R‘"òs)/0’±o’]‹‘¼FÊXŽYq¬/aš²JQip\¬#ÖtæšX–¯íÉÝÃ�•kDø"IV‹{ׄLc+�r/·Ì ¢ÕœE?ÁàÛ(ËñsO:Ã6Õ»@–:/ a%¸¡IDATÏ‹Oä•VSB#Ïc®)*Êï¤"eˆrþÞ‡"„‚•Zx„2ΡÚÖ{$±¢ƒRÅÂlr££é\!Œ¢ž·:Ú  !¾A3[Ýê<­›vÛR Ú#V.Id"03ªó+"ŒoïX.K’úhà +ŠAد~.ax´É8Ø…Àˆ%q‚/厖Ķ=5Ä™úHŠ<ô‰häG©Ì‡^™Þ–Ð�|À¡¼ëŠñqÅ„ù�­–_&ÔÑ�‚„Bæš9¨Vq8�üè†ÕJ.Ë`§ IšC")"/ÒI½&.†#ÜmY�žÄêø¸áf”k1Üoº�óX ›Ü8d#\Kló† üÚEn­Ä]ÞMY–{kb2Ê=(Ó‰ð´7v¬&9:îuöÙaüL^DY�òõöÔ“)�x]JÿôAvRÁ«ÀÅÀg(ÿ&e-q졇{Sa‡Î…<€03mä̬yiúŸNʲÙKÄW¾Pæ» qq“ê:ƒ¨á ´OJ"Ï*LÇ­ùøYO�åiÞJ¿�&®G9 áS ®·2àì,ƒ£0UevaíÃC¦§¿3MA˜YY“íqP(¼·«õ›çÇJ7°³( ‘·­|ñ霷CGž;Ä$  ¼«¡Œ™h-:Rð ¾ÿòN~/þô¿I£YÖ WðlÕÂ{mÇÍöUÒªè&§ì×C<Óÿ¿fäÁÈßqpM*®�8Òírj=(÷[÷ny[Ô[¨1„žü;®R+çÓ‚e¢™fi8M©O F©#œ©­ßq¢à³$êLóHµ~öÉPt2d˜å%ß”¸V«éýU‹7˜`‹ÏŠ6Xã }*Ô)8ó=id•>^£ÍÛ})®wH¿sºÞ$9ÿ$Xo«#öse}ppñø‚’’ˆ(×Ï�‰?ÃÿD^Њ{{”ç5)û1–â횪ôqÎQr/¾Su¬ÊÚ”PÖ>Àœ‰ƒkÇ?j‹`©¼s<Ýo½Ô ¢'±ÿÙ»8,Ð"ñ·8Y�eáUzy�x^°¥ß±æ{—ŠÎRëƒ[Pÿ8¨x|wÄ9%G*Ëû��aÅ^Þuxƒ²cp¿ÔAQN�T^"J•D-R»l÷¸=ÝÅʸÊXyoÂN5î ´÷ÿp¬:†ö õúþ¨„�Qp›:;ŒT2RÎHŒ�’8Fð·‚Dm8Êeã›;[Ú%¥2å(”ËB©,ÄHŠ\ X�ÖÄú¢tD�=!xZð˜Ô¯q‡Í­&ãÇL�¸'áûj\4ÔÄ? £à*Á+ ´IŒ´KŒ“èP�š 8Dj¢àÁ$L±Æ¡åhl�L™–ŒJS#c4jw›Ú­»„gw²u—3žßÅ‹M¼ÐÈŽ&šÛ³W©L9¥”R.“Vä›$PÈSW`D cê�™>ÁÔ£§:éMGYòv�‚ÓÃ"ö.� 괯ζÞü¿[�œ6·á4‰³ÂB?Ú×ñóïü’©åì‘m/e„HcF1{„K.Ø^ÊÖÒñÇ#ØP¡)S™‚$c·q…¼YÞ&ÈÙáö°@ H;0_j�û$jT± „ªV»ÿjäÆÖg¯úFÖf¼¹¶À¨:ÆÔ1nDö>ªŽšÅ\VžËeuCÈ6FGE×më`O[öDîn¡¹�]•÷º"w¶8m¼_ëÍZ”´º\ð!Ñ·ÔúD…ø]ˆ+Œp–èlÜkˆ+Ô)Z¬¹·=èp !ûåBE6 •b̼�P[à¨)¼ýÕ¼êp&�eÜ#k¤£ë¤õE±¶¨=I4Š& ¾Ò´·`‡¨]¢]Ô&¢¨œMut�=£+íGcÚD?Ç7Ã;4Ç“%N�¨,ätí&ÐK—¨u¨èr‹Óâ*·V·KG»>„/äQK}1{�¨ÉvH×{‘ºš¬lt£*u‹ùl'Öä³ÃóÖ_qï#Ù.ì�CF±öð–£5æM˜,x –zRÁV¶‡%šâj#_§kiÿ&qiXhG÷>ãJcÔ©±Ø¶j;/FÁã4I�oWèþ¤7jRô¤àu2£Ú„*Ún¦Y7U„ð�Úû·%½ÂM-Ö2¢ÕÅÚ‚r1§”Ï)òJ…ìs¹&§#ŸS.æ•j :òAkvHì5 Ú¤Zm‘×nÝåä3>ÏC½t½€óßÀ7–i+æ]&ú¹àÏ%~¡èça�rlP§QÞö„ ÆÕfJ\�œÔ×lö`§üŒÔê"Áy¢:Á/”}1,³±‹è«ÍÄrÁí¢ÛÿØéøˆkÌ|¼b¬ø‚%~‚Xé?†%š*‡é«pº²{Ã2¿ÜoÂǵ>'Õ�v´Êvà4‰•÷²fA#š¤š´kêG Ϻ֥¢¯žö÷ÜÓK¡¯+²ò|Ÿb“²sº¨B¤é‚OVDÕoû�;ûud ®ñ?ñ¿õ|zï7ÒÛÃ9vv“<ÎÐMaܼÕçO¼ÂÍ/6k”™ö`WW¿ë¼Vj9ÊÊ>Ó{®‚¼¢OxXt¥8˜Ãa@¤ŽÚÑœ‰–½1¶ž£¦‚§Ôû}÷²Ø ¨ÕUXZ™É±æ9/T&ÞhŠ’%ú²Ì×hôV|G»×áÍ*DO#¿‰/Þî²rê²*ÝîFc>Ñ2÷™tüL£>p†xâ,…¸Ò{Ã%{œ}AÃ|¹¤z 1IX VH‡Šèq•ZÁ¬§·gÊRoŒ®cÎ$°©Š^Ä¡]S•ú¬lÆöù>(¦Tþ: ¹Î¢­åóÿ2àá?SË©9�… 4ÉùŽl×µ‰Ö¨±³³86Èņn‹(z̢۪Uê±Êç‡ÉØâÃ[øÊO¿¤Ž2_k^ý2'ªáwÌ�1Û�Þ4Û±A]÷¢¡·Ç—MÄ!O½Ø¥¤ôÀ¼É•±ïî ÄXp“v�()  ´Ä¨·ÃùÚœ…\\£Ap£ù^°Æ·GSqv%Ñ}êÜŠÕæŸ1ÿ·O)î¯â—F¹–v7âÜÞù}\!o¦S%Þ"ï–ðÿÖ�“ñj4jQÏ^½`è L*¥&>öÜ^�·;Ž<¬ëãœn“OÌ3Q^S…ýt©ðñj5vZ.q•½þÓSDóB°<6X£U“à<Ûù¿ò¾ÑÉÆ*RÒ‡´{hêºšÜ2ªèìÝmî¯p¸’õ˜¬ä\Ìîª=Ò¯íò^9›-²ÝÒÊš¢0ô¬&˜ÛQRûHÿ9ÁÁ*6‘Ùþ^ê7ÚÜ×{}�FcÍÅùz:­‹x\ã°°@»Ån²Ûyš½C“+Ã{<Õcܶ)úâ)óüEmÁÚY^ŒjÚR·½õXïíŠã Œë1îYÃÂB¿ì~††ðrìøè¨RÊã[û�©cÒhD¿+<¾Å1‹D“0IÙ…ø×®Fyc•Lªâ9¨Íó•E h¶­8ÎwãÙúß÷o�´uÈýt£ëñŒ=~i´oÎ}}»ˆ/‡Ïõ¸�Í!“jÿ©¹bñËIÄn‡|o\Ö(Øn¯É %™ûn°èÀ||oß�öÙàeEÜ.õ—XŽåq…Ä>Ú¿†”ÕÄEÌ~䙽‰î˜2޵¢èIWìÛE¿¬mý«Ä5=µÛ,º�nJTv€ÞjqO–2´ã]¹°ïfÜ~0?Âkáª{$*D_y±BÀÃ7´<¾dê7öã¦>|<£k5‹~ßÉóÂ-Š>¡Ã‰¦ysXäçÝÛ„ 5ªõ1|›ð¾®äƒ¨{´•£wÖä«x ‡1ø1NpO׿?Ý! ìü¡e5eó�ø™¾EI`æDò9MƒX*ü·G«×#§h‡¦ù°*‡XÉîpAO¯Ñ~¢¹­älËê{3ŒÅWp™YaÆ� hCKøÄŒÖ6¹§^ì[”K2åIÐ,͈W;T´Hðœ²ïvºàâ ‰µÞ-o™¨^½ßzƕ὞ÒùfÒÑuŒè�˜ˆ»p:þã¥*«‰+$Êælk”ÛVÅó˜K˜5©&‡x&®v¨àF‰/ V˹2Þ-£`ŽK± o¼­FC\oÒPÍWfFXƒw aŸ‡æ÷LçU½ zÅp¡ÿJõ‚);ödŽìÞÈ%�ÇÖp¦6Áaö*9Á«=¥Æ·äEë+ÅœªÜKÆßäq# Q](§&4·ºWŠ"F!®u©5>WvÙ�âоÉHÑ”öðb‰º¶�y™„Šo²d+~‡LJá7Z´›&Á‘UF(ê¦ír¸^&R¾,hl1W@e#ý£à2µŽê¬3t„Ï)˜òìÎêVÉé‡�Ï„­ŒðËl•x>'µ\›Ï‡KtxJ*z¼ÊöOnïŽ×`áö³/8<«Œ¿|K�M�…Cw¸¦FILÚü|u~FgÞÓÈK àj\<؆…œÖŽòàìð2óŧª0”;~g¢²Ú-;ª³šºbŒŠ�>Ð7ä¹tt¨hwXÒ:ןè¸]{¿<þ|y°ÓÜqçGmÊçÌ­bÈ-£ aï6Ø£o÷6K‡¶éõ–z}̆CÃjÊÆ °}OõðíJf*±£·�:®R«ÝU¢û%~×u9£ïÂCzÖoÁÍž®ºÛ—áÛŸ^ôãÈ9#ëÝ&ö‰—, n7_“ufÆ5¾Wû^ÇjgØp`´Â#K©BckuË1O1/VB{:V´L0CôeçƒÍž®ËîE‡ì®�Ïme§TÔU¬~ d¦€A­'w~ô- UÑ�¢¯Úë»mÇ®u•œèƒ¸DpV>ñÙ�òp÷CÃjÊF”ÊòÍUó&Èçºì4mq¥‚¢\—hU’“t#XåSEŽ 68C££”Ðn´×8_°\›«.ölfÆØ7Zk ¼b²gü¤ãFÕùýg—úž6Ÿ¶ÙåŽt�s¥¶ª³1,Öc«Y!tÍsBåõÄfááeˆ÷¡É`&Û/…´CÒÑçÍ%ä³?Q�o ÆÇu. m2Þoìr–ˆ~¯Ô3ü¢’ÓNE<[ëíø‚hÂ÷~É%×™3Ø ¥Ù‡zæÁO™<ª¶‹�‹£á¼p®ßés;ñ°4ÎôÃ�x}Œê?—ËêÄëL³Ýg!®ò©p¾GöeCe�LÒ(T“hÈÜ~•¤…· –âleï‡ðÍ·\ê(%'‡eø@Wª�‡ w<Ĺ_Ý›²¯Qã¡û4݈N&²ž­Æ¼ª�V('uVŠÎî([ªÍ…]ñùyï�':Oaß­žC¥¹väi¡Ÿ‡½½D{I¨-Ø);áG{3²+låyº’‡�Õê°1œ¿7vRQQ4ñ'9çKYRÛ ñï7ȇÆÖí ÁëB¤&ËôL)¼Ñ¡ÊÆ6¦^½À‹ø?_{¿‘Ûí¦D%~/Ú% \a=ë"u* ‹ªg¨ÍŽ�JI"Í÷CøÆV[%‚�‚ q�’ÕU+·9WêÑ]r>Ý#Øs’–›ÐrΗ²ÌÁÁ`ê8Ûð–·íi±jRYG—¯n0KÙzÜ=*çÚxm¦´�tœ¶+Wt“!:Ü.Z,Xª”EÇ)["ú®Ø¿¹bhv|ЖK”kú ¨~~7[w GšŠ»»Éê=×-:×ÞÔ%ø´J°g8ÓñIâôjÚñ@xÅaÜù1íSkív¸]žö%|Nϼª¯jîf²NÌœ& ¢·)úKüó —(é&¼U„„ô\ˆ�²h¸~ýCu¸îÊÑ1¶>‹ ì}Ø=·‹-;xÕáf ÆQ�ðÆkóbec›R—²ô:Ü‘¦}|±bîdîþ‡�•׬NÓW¹FQ‹Ô;QݦÝÚ&‹ ¥‹¼Qt Dû (Ôú©’wX_Å©Ce2Øh�26;H˽¿§•çŒc¼R4]ïlº ™ÚâjWr2‚¬ò˜íx�ÌòR6š˜3©‹èD†K2Þ\Ù¥×V^ý¡¯½ZpŸwÄ­æEžKú5©Ä U‰Ý‹¡!|‡mŠZ¦MÈDÇjfƒ;âò³Õ†Äp?•l�7‹Î•¸Ï7†Ó<ཞ—«$Ÿ›w¦±g$îKaÚxñ'¦Ž“â7‚è¯n$XïÊ>&Hÿh“‡Ìñþçv8|{«íK.v½‹k<×x_X\Õ7¼OÂÿÁ³æØzÜt³ò‰ªùç·dɾõ5ŽíúòvEÑçp¼h¾?¸ [Â;*RÃ…æ†ý zžþêRŸ›1ÁT씺%,íÊ鋵F)ù¤Ä»+<}¢Ã- ‹l—e”t^»x¦áPÑQü‘ V(ŵþeÖ¡^Òî~¸o�#&P[¤GøÞQ&^F©Ýêúüfߊ™Sa0x&F§�õO� ræ÷ÌïêJ‚(‰6{!¬�êP/çð®ü`šÄ2W$Kã·âh™yû€2‡.¼£Ã­I°ùïÎâ“3^߉±õ|ð­$Á©Ä¹¸Bb�\&¸\â|Ý*‹Ä}ã gñ¼ÌM÷x%սƆ^Ék3�©ìfÁM•Ë>i´Cfjµ‰îÕQå`¬±ZêÁÅaa&zÆ(ôÈËÚG ÙEA1 Ö;Uê›OowäÊ»…‡·d,úsþÛ«5çËß}PâaS­àV» ás?Bùìã�yÝ}~\K¿ Ëm}Pââ°ÐŽø5#�v?Ž©4û­EŽ A¬ÜSp†(QãŽþnìè³îuÞ©ìTeŸ ç{n_ç;d>×Êã|_\ãœÃ'x÷Šw:kO‹ñ!0ºÎï$®Qð}%Ç+û€èWžu‡~NÿØ`gíBÛ:ýRc�ÉíñÔ‰sÁér~"“¼ö Cž{4,ò™\­SÆ�2ºÎ©jœÚh—÷¨àŸ°RcÖÒ-Ž¿ëãFÕŽ�]'ýÑG´Ÿ8Ó*S*‘fA�X!pf a�]²èàÝØ‰««Þ{°Ú5®< uE\U=®&¬�J|Spµr•ôÑð²]XyTû\¨Qê¯D§Û\� •°ñe¸Nêo:£}û`¾&9*9ÇÎÊÅBÃØDB\ãì¸Æãqµ‹Öÿ eÃÆ0†1Œa !þdDncFóbKIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/icons/tomwer_build.svg0000644000175000017500000003714114757047403025200 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/icons/tomwer_cluster.png0000644000175000017500000001650314757047403025546 0ustar00paynopayno‰PNG  IHDR^^ªÒ£nsBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î<ÀIDATxœíÝy˜\U™?ðϹU]½eé$„„,�„eXPÁÜXT•T"kPù騌Ž\P@ÜQ"’N”wƒŽ *‹ˆ kX“²§Ó�^ªêÌ÷vwUwu³ØŒøüò}žJݾçÜ{ÏyëÜ÷¼Ë÷œ°Û±Û±Û±Û±Û±Û±Û±Û±Û±Û±ÛñÏ�HˆW8*.ö×x…SbþÑmˆü?ºÏ1 {«h¢. ”WÂb{ˆf öv®��­®¶@bW‡c7Á’p’-ÏRüÓ ÞR-ø²`šÝý+V AŒßv™ëñ‡š?L×,øŒhOÁ*üàùm|?þùÿ€6³,LSgõPÕÂ;mÀµÃÞ«¨SÁÕØ_É#ÜÒÿ/6ê…¨ßñÂjT\ ±§ÝtËip˜­4dÝåòVjr¢¶ªõw¼\ƒœÏæ‰~fº¹áPÅA÷Xf”Qz›t ùœ(¸Â,‰FÓÝ[ë>ÏÉHÜdÄ0Ë.о%q™N;U-^a‚•>/ºF«× ªPo”àhLë£jÜãź´ÚàËq©†lÓwM’ó%ÁRkìò{6/,_§¨("Ê 1!Bâ%øä�øMUy^»’Ÿc.nÔ­½Æ=NÃÑ"Š~ƒ«j>«YI—"Jº‡iÓ³Ä kÄßg¥`®¼ãÔybÈzeëD�`+þ6°8̶Mâã8X½yá =5îò0Úð”`å�Ï:Ö:œ):JƒÇž]‡†Æ JÇW".“S´§’¼‡ÜôëÖ¸LA�×(Ù7+Û*(È©W–—ˆÊŠ¢mʶ¨³Áƒ¶Vš•ñr-òÁ&õn³uW=ÿ °ŸF ³méþýC£àGm4JÑ(9£Ð,-±¯àã‚?ˆº°&”JÆwô(lë–K”¢P* Å’#eä…:å†:±© Ü\okžܯìüÔ ÷Õ²ñã&H\‹—ãê�6ÒÂÿ»t|Œ‚s{ îì$è’-è–'Ñ£NÙÁÊ& vL­v,E-åhT™Qå¢Ñå²Q1½¥KÚÍÂêM¬Ù숧6³¾�umll§£;ýK”ÊË”J”3û& Ôåi¬£¹ž±MÆî<ÁÔ}¦zù!{9yÆDsÍp&nÔ±²)‚]�ØÝVãYÁ‡¸ÄŠ y‰¼’€:‰DY�S§, 'ªCƒ >ûn5J4+kŒÅeã;ˆÆw•ŒÙ²M²µ“M´mK¿7¶³±ƒ5›Sa®ÙÌš-éñ“›ÙÖUÃÇ!ì<�›ÎaÚ8w(98Ì×YYªÓdÞ(ºÂ ߨTuUu—8@Ù>º]NÕöLÛV~Í¥²\Œ’R9�lI9 ‘£$"FI¹,)GùbY®«G®­“mÝlí¤½‹-ÛxjK623!nÙFW‘î]=téìÉŽKÄçKºOƒ ŽãCoÖ&8<œäOËã2�¶¯ÑÚ�ú¿¢NN—áP‰£Â‰~öLŸŸë—Mí)¥¯lw1D9¦BÓW¸˜iÁîb*°m=ÿ8��ÚS—)HRuÈ›åß9ý$̶�a¬8VY«ßJÔ«35£vÿ×È%´4¥Ÿ¦zF5¤º¹¡ŽÑ�Œmd\sú=º‘ú: ¹´<—Kë†�ŒžÌ×íêakWúFnÙFG›³ïÆŸ8Zœ>Þµ8Ì6E�Î|At‰˄߇¸P�fG‰ŽÆõádËâBuœ¬c =þ®É5„ô— ™m²bL'¼áÐPÇ^Sxó‹ø×iLna\³žQõÊc•› bCAw’hM@Svi'®ÃFQ·D·¨KDõ�ÍM�ôÍ=c²ëÇ ]¢[ð­p¤Ž¸Ìd‰ÃEÍYG×m|‰;ŠÎÆ~84^îúl~è1çÙÉn�àër47ÐTH?Íõééû.ÐXŸ–�idtV·�OGb}>�<¯¿�ßÜ›ŽÂ�Øa4‹ßÍëöÑ–K´c²àq|PÙ#ê¬ÑcC˜£=.Ò,ø}]»UâÌp¢�•÷Œ �Õ¨ÞÉÖÖy1 ®1N»²ù6‡Ê7½M»‚G¯�Õjx»©gÝžá›tKz:„«ÿŸØP— ­© 6Ô)rŠùœb]^±.=.ÕçôäsJ…¼b}�ž|Ђ�[D‚.e�‚®ÈK×lvðð—¾^Àü×ðÍyº yÝ"x¥ÄÜf+ÅeµÉ;ÅÖĸÈL‰s�Sv±þÔkÇeFétšàQ£à�J. óÜÝ'ôEfâ,ÁkÝ¢ ¾Ø›øˆ­ö|4 V\hŽ»B³ûÇ0G{6™þ+Wò›0ÏmÏYðq±ó•õ �Ò¸íbö]Ò!hC»²vÝÚ‡pÃÓŽ.v¦è뇞Ç�úÆ çsò«< ä˜JeBÚYð©ÌT½ÔC~5d"±Õà ªßÞ›�òæpŒM–Ç*ƲsuúìPýˆK¼TÙY()ùìÀ¶þ=È+ø˜{DŸŸÍä0,ÊöÚØ‘š–ÑÒÄ^SÁãš,2Qôy*ˆrêâBï gØ!u+0Fb ”�¢ÃoF£4jùF|ÃV«ŒñMÁ1¢o<�tzŸ�œëþ›:x¤Æ”·ó„ÔªüMGñËIÄŠIm mUÒ&Ø zTBQš¾{6x~%Óõý<ýì=•¿œ—ÆŒ2lU�DIÙ ²H8ÓVœ…³²ÉùÅ¿FTÕÄe ØõÞUý ‰JLGsƒ(zÄéÙDUp§ U´Rô{‰oW]Ôm…è'T8Qéz½“«UÊ3À+õO°}¸gešÈPüD÷€hc·_Kü·4bùc=nxŸso”È„¾ðtuq˜ ßÈêø¢Yhº{ˆ4õ´ñŒiÐ!z´Wç…Ù¶)ø˜/3Ýaá$·T^NÕ¦ÁGð-<€ûñ Eï¾Ç�‚è.º?»ÿåÊ>�1Ñú/<ÅZíæéq��f‡ùtïûGøåFå0ÌÈYUS²ò÷¬\”fN$ŸÓžÄú�éߪ«b|×X9m4Ý­Ë&±¢-á”ê¬Ñß‹óhö·æ[­A›‰zâR;ˆJN°©o�¤–Ì�oÙ‚Š·òšk† �¬à3:»ä¯áfä’Ôyt(§BŽ‹ì(:Ið¤’ï÷¦àâ‰ÅÞ.ož¨I“»¬òÉðNO�h{+°p¹õ —{*.4V—Oâ¥(jue¼Á•ñÍTëõ„¡cK½1ÁÇ%»­m“[[#ó˜K˜5eív°*.²£àJÁa(ÉÙ7.w¶C”,qf'iÊ”ÃkÕÛ+.ub8A {i„úp¹u.½½ïdp˜õfᜬNƒÄArêÜfë8à¹ÛnÓ³ñr-�e“ê÷·"Xí-Ç(T¨Æ0r#~oMºLÙ¸5MdD.Iu<Ö„7銭vÒïlä/ò¸z—èÖätƒ­˜W+9ÿ=L+&àsªã7á<ƒØyÞ‹n¾ÏþçþþSI�ÛK�9ßt]÷nÁG�×má­Ÿwþ�±µ½ÕN Ñ’œ—¸××HMËK¼G«†¸ÐW3u5‚æd»Qr¦¬ÛÊúuC]še2k¡h�¼‡°Kf¥Üi›nÓ%ÖÛ³Æ *¼Ý!ðvœVãü÷p+ÃNKJv:þÆ<6@UÞò ‰ß{Ÿ=®]ð6ì(yëÓ}›Û6Û»aŒŒÍ— Þ%òš|Q°Iƒ_à/Œ¤U“7J0eõ¦ÚQÉ�w Ÿ[©àçY#ñ.œ¯ì,].gèñ¸²èÁOèñôvû SqÀùâ>lð¹O*X×Ö9ØÙÔ¡ˆ§$:OÈôy`µnHžÜ¤- nÆj\ßwñj%œ'¸D£zO�܈/-1iÅSµmø½|Ü$�Ágúî|¤ªâ銖ºDôY±*¢÷ù �ö¹á>j¾M)zÜ^,)RŠ^³ÙÊ0'MÆ+œ/§ Ÿq’5_¾ÉŽÿýK·ï?Ç;5˜f´;{¯Í’8ç|ÔÈ >o¦²†¿Õ0%é|¤:ù1!ˆq¹¯Ye NÌØà£áø¡W€ŒÂ\ëC°Õ€˜Ë}Oö;Sa®;âo%꿵ªoÙ¦tå�Š nô¸aÌÍJŒœª)§ñ�‡kEDZS:ݵӟçŒKì[}2.rf\f|oÝp¨¢\.1o·Ö»ÃÉ#"ôÝèS•ŸßÉFyŒƒUM±Ô?1Ç+L-ÏtžÝ\—ؽûq-íûÌd½¹ì#�ÖHÒL�`�˜Å¤™¨äÛ‚× JºÌˆ }¬7Üš½¢5S~ÃÔç_)ýQQ¾+‘1ÎK8YD{^ðvï=`Ajâf ã©6»/¼oX»í¼©�¶þdc�ñ͈ZÔõqWvÂîY•œ`_� *²Eñ2Sœ†Wc¥h©~5�Ñ@LŠ"}oËà`?’¸ÌØæ“õt Yo$§³ô†¢/Ù=c;¤IúK±¿ßÀ§²óÍò¦ëòH%GsDŸÙªSVoªMdÕ�òoТÛdÜ©Ç*uUæäŸmëç(ÆeÆêò£_`oX5Áu¬êéW¥ïºëpUKoVzQÌæf‰.üöãÆþêÊeå ín½Ië“›ÒÀÝ#%[¾óíWþ>5 Ú»LkÛæ8;ã#8ŸŠ)Eð]JÞ«àC¤9FjÄ/Õ"jybåáŸ\jR…S¬�W˜#˜'±RÁÕáä o¯Ëkñ6•�­`ò1_ö�žÔQêÅ5˜]ñwU�í™âë'x=æ0SမHç¿]/8ÎXY0s¾Î|NG±ß•µñuV(ºˆ¾‹Þ…Σ³zÏCεlVoªmJ6Ö¥ê·XßO s­ÄgkÞ3ÚGMÜØnô€SÓ*ŽgàûT±ÖàÍT3Ïbêû êZÇâ›úPG·¹«7ù=®ÉÜþšp8Þª¸Ìût›¨˜ZA!ˆñ _“óS�Õœœ‘|ÎD% +7ÖV5�…”ŒŠMÞ7˜òœ‘Žvméµ—©mÅ”Êúþ¯Å‹œ›…ñ‹áº2 oÁ÷YQŠŸÏù�ȵaÈ rv�ÙÖÀzs­g0;adÌÉ’±¨Û°µ6};ãa–%6ŒQÇË5èv®èf‰â/ËŠ~-u¯+ëokÛ6ì~Cõ§÷ü�QÃûÖø­¨½Xãg-–KÌŒ­.>t/óügŒ‘|0ªXV×ÖY;ò_ÈSÈ‹%p@¡ýDó3D¯Q2¬ð„ètéRÊé^¬ß:¼Êxüý<� Üý³¿X*úz-;>¤Ôí÷ãŒéúˆR½èx. USÒ\,ÉwÔ\7A>×§éŠ Õ)Èõ™VE9IÅÈŽ2;þq™#´©7ZÝ1�“÷¹ýG¾Ä׿ߛ¬ðó°ài[zvüܱv9éÕþ«©ÎÑ(´ŒrkÂ9{õfs Ü@,›‚äSoc÷É6}ÿOßñ¨'pS¼!¥‡?M̾Z&Ï´â°HÔ•{$=CX×¹„|:â'jô-Áø¸Ä‡Ã‰0Þ�6»sD�*Z\ym¶ ¦›ÔÛݰХëÚœ„4ô»Ë&šéÍϤ©Çnü!ûøpw�Sº{$I˜F'%ycìâ„,VS�HŒn‰ƒvÞAÓ釹±«ËïxÔ¦G.Ôbƒï@¼Ü§Ãü!¸˜0RTRŽB-‹†4í—-Zø7¼9%�àáHq�³Ìò9%[.«ÂB�+Ö8åÖGúãí‡îÅî“M“s¢!<Ï1õò[Ò±xðU¿¶üÊ_UG1÷�.wÇg�«¯æÒô"“F u¹ë x÷/ïr<ކ—}Úê5KiZuVàì!Û_�‘|O.Q®Â/ì.Ò]êl’ÎðÍB¿�2µò}‹‡÷5èqw˜_¡“ §Ç«n{¤ÿޯ܃ß��h*–JãAͽåãš•o:ÛI{Íòç0Û«c:¾ëqžÜ$Lo²t-SÕ> ÍOdyáÿ©Ë9£²lm›±Y@)uÔâR;({5þNª½B}d“D9?„àÛ:ië”4Ü�¯Šš+bÖ•èr.FAÎ¥q™õ­EšdÛÆŽjUÐû�îÆ�}Ñ!c,Ë%f¨I]α:=f[>¦+ÁWàHxÄ>v~çá>0®ÉôƒöÐØ�§j+ÅjË(FQt²D¢è× d.Â7ñžZÏÁ]¹D©~BõS[X³Y˜8ÊT,¯°Õ«#:N?u>##{†7éÕ`-&xþï•-B¸ö�N�¹ƒ½®×.xÙ®r‚ã y—ÔZëÛ]6­Ñ£ÒðĦy¯õ¶™íßP'4ä!x¾W.6IÃ?¬îˆ»¥l¸!ó#5¹nÎÑÓÒ”òÚòOnfåFþuš]ã¨-xãuY_ål¬U¬á[;«Í· íÖ‰æ›c•¹Žý¯«¼«ªi�û.d·Iêó‰dÃËE?öõÖ›õHý‡W_AÆ{ÿå¾t¢O¿A‚±{}Ô­»Ð1ÃѺGÆŽ/[èœÒ’vt ¶vò‡4™··8ô>4áMºDçàJ\ûèZÿ9í ‘¡'<±Áªp²û²ŒÖ¤AM‹ÙÊ”èOÝC/j½¹o.Ù{`Ùò{¬Rï§q™º�øJÖÃeØpïJë Þ6ܦB##økÛ¦O¨âVá§!F BÿÆ>1 q±Ãc«Kã'Çåòaއµxç‹?áK3>èê•mÖr¾[µî5ÅŸUçKQ颣Ûý‚Ï WçK'Ù-¶úns}ÿÄÜ‹ûV{èÀÙbW‡Óî=ßëð~·±Ÿ¹x½4Ñ‹ÉCÂȨšÇ¬¶›5ûïlV>QsýùÝ+ÓžMõöë;ùÑùÒˆÞ±ók¬ GêÀhÙH‰2†Á=çû�¢YUÖÎÓà’�óúÏ»Yšð¨‰·ì·Ô× Ttöèº5*Z숇7˜ö·Õ&w÷8Lj¾ñä3mK/FdÄg‰‰ÏÚ‘—AÀØe ªè{[E©y•mÑX{Ï€P¡[¿ðûÕŸæ7RºÆŸ¦µxolµSŒC÷åš[úžù#<˜›C°IöÖ4×»a×IvÌ®hCªÊ®ÿ¯«lýÈÕòËÿf.>/U‹Ï#—síq}¬øÄQüËäj]ßÒÄûßHlTöøL..�˜­œ-1Ÿj¢h/²ˆd·¨ë«?º‹öÃ8pÜhŸÂu–8!Ižvòû[¼ÂJ‹ÜU^äϱÕ;0~ë…ÞÒ˜P rGê-ºñÞA–JSź¬Û¤?æzf(Œ\êož¿Zjþa{ûÖ/?jÏ…Ë…{V¦Cõ¤Wò–é}Lð�NçÙÍ=–[u'ýtˆ <*}…ë‹%w˹@IX¹Ñù*˜b£êµàå¢1{L¶èÞ,‡Wì¦p˃ċ�’8ûfEb´ºâBçhvÓÖ.‹´°D_ø¢j¹e>'¯ÓâåÎó�#µßËë Ĉ >{[3m‚·/x«£¶n3>Æ4zHâÛêü@ÑJÞ'ºÝj?¥62.óÀò[òx›úõë<Nè[¸5Ô$™\x¢Ÿy¡ ûL³ïÁ»{} ™1Qüð[ÌÈÏÁD9]U}î[—%Ù„O㸺D]]^¾»¤£Xz¥G!¯ xŸœ_àDœ�Í'ËDÕÀˆ¯ '»Ÿ�Ë\8¶d¼¼ ÞS½{HÆeîSö%ѽÚj«øÏï8é+¿py±$´4{€Úq”bº*½$Zú–7ù‹ Ýþ×Ï{‡èˆÞ&‰éfÛ[}GO)ã«58öÅE¾%X(z3.Sò«0¿v;»‹º—(ºª(šVûŠÏÛö‡Ùk9h¶³mˆË�ã7ÊÃ-•Ýì5Åt·(Ý=U�¨š€ïzÜ­òÞ!gMŸÝ\òK‰ëJÝW÷]Ðá+\)QÖ1$}dg¼ZÐ"8DÑDýD¥ë°¿,_.ù©©>4ŒÍ>_ú”°@–þ‡ì;Y£‘¯ Û+&M^_ó×Çúƒh=¥*ÇçƒÒ} $„Î× Zå7×úx…Ó3++ÉP™JYIæGœ‘:ÛÚó˜à÷¢‰¢åBU:oiöAúÚ„C‡íîñx]v|‹ç˜Œ¾pž~ºÆ�²sÿ^q®jdÆeãÇÅVg÷-{|–ˆ­vŠ­>›8ˆ..—�‹ìø,÷&þ¢Ô2['¥¥ÀÏ+ú± ·â k§Uòò]ß5¦p’ÇzÒ%”£°kFÑ‹D‹Z”íl5;ãùL(qw8±Ÿ¥[�ÓñqQ·MÖáÇ•…Ù[ù”9ÄËŒ6ZâX[žfÝÕ³ÏÓâ…µÓ*ö�n/|¥{‘URï5HÙý(*ˆê‰Z›H\£Y’ý¾²ïůf;7Uc¬Ô3n†¤w‹×iQ糺]jñða€!PIZï ð½PF|Ÿ“>qŒ±¢ƒ²�5j¯yjðG]Þ/z‘¤¦©WÍ�n:Óxõ•ÏÑ×%ÁzíY½ÚŒ¼L43³Žž-yö]øšTÕôé÷Šà¿‚¿67*Ì;XQÙ:õCÓ¹³ÄÈ·‡*·Q›&_�*¸ÞƒƒÙ aއU›µ±Â*»ú�t{çg» ™ô‡z^éåÿgˆ 5Å…Ãî5óÌïu¹†xy uõ<ã§ãŸÙ.¨ 5ùQ¼l�ïÙÝë«êå}ZÞµqq_áÿ/UóÌ‘× ÝlyuÆQ{Q@¶1óá‚›‡J8›¬N—ƒ{*›‚»ž·vÀ?݈§jSöÑáVÔhŒ‚`¾£ì½U;/UâXírNUtŒMýûÒlÇsD$ÄVGÇVÆEN{¡þ-Û±Û±Û±Û1‚ø_b¦w6¥ÚIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/icons/tomwer_cluster.svg0000644000175000017500000005303714757047403025564 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/icons/tomwer_control.png0000644000175000017500000001562114757047403025545 0ustar00paynopayno‰PNG  IHDR^^ªÒ£nsBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î<IDATxœíÝy˜\U�7ðϹU]½e!�–° ˆ, Š (‹Ï ¨/è «3Œ 2¢¢B㨣Œ‚#cÒI�FE}YÙ]@d3¬!„„l�Þ«îyÿ¸·;½T‡ÅçíïóÜTõ=û¯Îù�ßvNÅ(F1ŠQŒb£Å(F1ŠQŒb£Å(F1ŠQŒâo‘8*.ò¿q�“bþÚ}Œâ_»[Š‹|H4ÅR—‡&éÐLXd7ÑLÁ\ äofk’ØÙáØE°8oýk?‚ s„·Ä|S°�]ýKg AŒW¸R�'õ¸·ê�34 ¾$Ú]ð<~úÚv~#þöÿ¸V3-l§Æòá²…S¬Æ7YWY§’«±�Šß�pOÿÿEü¶1¯GþŽ×W§b“ÄîvÑ­ Îca–ʰyoS´Lƒã´†0�Çùê|Ip¢èf8!ª<¤ŽcŒÑŽÔ5l;Q°ÀL‰z3FÁ‚7l+è’+è–˜(Ñ£Fj²`+©)‚­S1M³­+Ñ„4“2&-›¦ÆÄhìú.u+Ö Ëײb�#^\ÇKm¬jeMíÝÙS®PI)§T*¤¹|“jŠÔ×ÐXËøã·ŸlúžÓpÈfï8Å vtî2°Ô4Á΂zìjƒ‰Œ,áC\l?e%‰¢DQE@�D"ÔHD5¨ÔæŸ ¢z‰F©zÁxL–š(ØJ4©«bÜúɆNÖ¶ÓÚ‘}®icM;+ÖeÄ\±Žë³ï/¬££«ŠŽ?BØ~2wžÇvý^Å;Â\�ýÓã<54á=¢–º´?«�w±ý¤öÔíÚp²ÖÍíCXö-ÏUR…%•4ÛlI…HˆQ£$M%iT,§ ]= ­�tt³¡“¶.Öwðâú|fæD\ßAW™î ]=t—éìÉ¿Wˆ¯u_˧ާUpx8ÞýƒÓc‹z&©·r0ÿï—§ Ëõ8Tâ¨pœ_lnûÅ}ÓôžJ¶d»Ë!Ò˜EÌ–p9ç‚ÝåŒ`==‚�Ú2•)H2v›Íô^AÁ7†Y:Ø„´ÇH5û•D­*6£M¡ªÕî/�B„†ìi¨eL]Æ›ëj[Ïøz&6fŸcë©­¡TÈÒ …,oÙÄèÉuÝ®6te+r}í]¬Ë?ëK|þhqÆ$÷™à0Ê:}Ap‚èruÎ͉߇8O�FG‰ŽÆua¶–8O�z%³µÖ 7…Wµ¹†�ýr!—�BþOŒÙ†·)ÔÕ°Ç4Þ·/oÜŽm&0±QϘZé¸ziCI¬+éN­¢ÉhÈ‹vâZ¬uKt‹ºAT ùÞTOßÞ3./?�è݃Ë´ÇÛH.jÌr¸n“¤KÔÙZôì�Cã|×åûC�9[F»!„¯)ÐXGC){k³Ò÷Y¢¾6KWÏØß'z¨�è 턳ït‹®üW¯ã#4ÛMðYQaÖ%þçšû…#P¨/¹°£Û§c‹ÂÚõöÞë?ynµíÑ�ëð¶Ì¬â"_“êÉ+é”ÍÀ hóÏŠvA+Ú¤ÚtkF ϺȢÿ>ô+Ü>H¡¯/1o.³ò¸Šö'PN¤í_ÌEÕïú³[†ud 6û¾nàê½Ëï ´¶Ÿäq„þ cê�¾\eE;+ô¾($âœw8nþ¯]…³óöúã¼{¸>VCQɹ�/nÉæ°I¤öXÓž‰–ƒ1¡�=¦ƒg5xºZlQÒéœ�÷do»9«ª5¯2MÙCYæ›´z~ ÛÛp˜ÁZzðOJ~€G•-ãqìÞû¢’ ?ü­ùÅÄ9åtãû~\GZŽQ˜u�Ô !& ³TB“t¤ˆç«Ì|nu¦, Ƹzv™ ¯¢†—°uß_Át5Ã6V1†¼jÓò¿¶ÕoööË3IÁøaj¾cð‹ÖµåÔ¾¨«’ÿ®j•DÂ[öTs[ÓÐöGÞ:Y2Û<¹2ãcÇ)Ù¬Çï†$ÎÒ¦àX/“<šÕZÛ›[bK¿A”¼€•UzÑ)õXþýaª²ÅR«d+áØbÑßo?ÞD™ô³ëfŒ´?C-öÃÇô ?°ëŽ;ûÅ!;;/¶¨ï_`äíñS°Õ³/õ))°Û6ù—8tæb¬qµn�(+  ³tÄŸi°Æ\]ŽB!6k\å«4û®`OrgGPýJ½ÛAÉ£ºüÇÈVt ®Òå™ æ®mwe¹Ì³ëź�=}¢ëæâäBbn¯æŸã E™TÔªCõ‚‘'|0µœšòØ 5ÞþØ}Û¾¯»ô~‰M»™¢¨-g?}*|¼D­µÎ–¸ÀFÿéA¢ÝBpvlѬS›à#2¶ókEßéec¹”t–n!hÇ/•Ìó„ØX«im{ÞV^ÑÁ ¢Ã9Ƙm�S,u¼ÕNØØÎˆ›…ã"gvt¹èèoòË?L �›?Ãa{Ú :2Ìö?±E½.ççþÑg|<|ÄÝ}õ-ôFÁuØiPS�˜f[£àR�Š h¯&qÅÝ­“úí!HÚÝ!¿~Äm›1¬ÅoÝÙçÍuÚÊVoÿÌT~÷´É/S&Ŭ®’F~ÆG{”SžX14i|=SÇ!ú­˜óø{I/šŠ©*Nf#áMP6µŠç N´–ç‚Á&Ͷ¹ã<“³ÎÈÞ�x u==ÜûçMŽè||ñÞó}Dpêßýï*oú¼û|Æ[†)Óƒ¯ªNtˆ¯…ëoŸµíœT•P[Šb˜å\œDUEmj’øXšºòM»·ï_c lžã­¸÷škÌÇ?«®CŒ0á;vv)<ûÒФB’)O‚viFä¸ÐÖ¢ã/¨øq¯ .6I,ò�ŠN5hðGÏ;?œâÅí/o–Ù^†GtQMÑÌž²ÿÆ3Ø ŸÂìM”Jp2¾˜—©šaD›$*vYÙª°²Šç±�0s Rm¶ò|\hkÁUß,Tp~¼M1FÁ.ÎÀ|¼Wð.ü«Z-q‰©[Ð¥[Ƀ£²§‡Êó<±©JÒ(é)û„ŒÍuá�2ÍôåDñ;ô#ú Î0r<þ ÓÖlÈÙƒQH2�áH]‚m±so²`_Ϫu¹¢è4†(2«xûföf¢¡D®Çû½KqÑfÖùr¬.^LFð¸Èš}2Îëcg#(N¶#š¶j/U‘¨ëj2/“�û&ËV “ ƒ2Ô¡Û U-€%ý´Ý3±W•¼{ÓË}«¼["¿øÙ÷ûêÿ~5óˆm!nºýs޾ÿí—ŸÄ…Çz?�|"ý—àuöè-0r„/#˜¶|mu«äö[QLsŸh…ÄGñ5©³u¹0œ®Ç³R±êòï1Pn?Dæ|xó˜úÆaz¹Ï ¿ß&SÖÀ�'êî=§[?뀗ëPÜ<¡ÞŠýgúõ©‡Zþ©÷¹R¯D³\_\®Þã½FnsM�•˜ºôÅê2ü޽ñ¸IfƒÏEÁÇñ™OS¶Äå¢/‹¤†{û4Ú£eA¦µ}¥2GÄðv|d˜^NÆí2Y{oœe£Éøð½?­ñ¹KÜ}çcލR¶ŒÖŒ�q ÝjŠÞó“›]¼Ï§¨³�±ìMË�8 ÓŸW�¸Ø‡b³øá·ØÐúž³Þ#Æfi\äÀ—­ë6ŸØÉq‘[c³;c³ïÇf½æµ½e³¿j;¯ö©+¹iL�ö*i§äí78-ØrikäXMjGx²šuÛfîŠ66ú9ãb;ÄfçDžΈ-&õæ ‡*{Ü|‰YøG+ýs˜ÝçT^Î@G÷H¢³ÛiÅÙ…d@œÌÏÉ4ê¸ÀíûïäѾ¾Ô•||KÛ9Vì#OWqÒLŸ„`•˜Û¤š¢â Á»]vŒóœÛkYÌ—h5—ßJYÜûÏ�|Ðí}8¯½G·LS>H¶—\ yÄÃWnù¬ÝæÿŠ7ïèÎÆ¢÷kÊö¤<Âxºu þ” #Iøhûµm´VÑ'ëKLjD4AM_ìʶ6zz ‚½Ô+é§éÅ+MSr*Æ2ÑKݚ܈ÿÄ9#ÖÖ¾çÍN½ñ“‘ÚKâñk³ýºŸê߈™ãê…O�hrïŠÜIÿ]ìc‚KeÊSöcÍÐå©þ1š#Âjbz%šj�Lcê²øLÐ-óAõx^q2z Ïb‰Øb¼’‹eæá2¥åûvöîÜøtóËt+•‰‰ eP›äÃ�‡n<ËR× ¾.X‚En´Ç�~#æÎëÄïľU¹½LJš*øyØHâ£*nRÊÞõbdxüDž[MºiÂ?ª�‰Tá$+¥æˆ>/8U­ 80º¼ ÿ ¿£:ØŸ|ê"ãñÉMôè™Ìþ6[ú�,8éS†±�D¼o©¹BŸâVÄa‚ÏĦŒN;ÍÕ™T|ÇU¢“Vuùhß¡äKe�O�‹¾ß[©h¬LÔ} |®©É¨[¾¶º(Y_“±Üã¥�� áËðåªuF{ ¯¤\øs~³”‡–y×cË­°Ñ:KeÎçÁp·,f¾S­àç«™>‘¿Û6{N<˜·îìMÞ`,ÖÅ(„ìÌÕ�óRáÞ�->®ÛålcAŒ |KÁM:Æ� á ¦¨¨[¶¦:«©/eÁ¨XëãCCžó £­Eëܾƒb}¡q¿šs[ú²Gð^|ɦ¥žy8W-qÙšì¹õa{�›?£‚J$ôw”æ?€ifYiPÔC8ÁKb6VS15«7TßÎã0S‰5ƒmÔq¾:Ý.Ý%qC\ì­yÒ­øbϰ§]«bHLÌ ÄÍȺˢàFÇh³ØN±Ù·ãB?éYè×¼:Ú� áƒ1åTMkguË©H©(æ!�ƒí-:Q°£è�*æ‚¥žË�ewĸE‡z7GÄܬq¯m³J�+]  :§ Ž*&¾º©s¸›ƒ‘šñ�åŠb{Õs }vš®8OMœß/¦¦¬0 ù·Ð$ sܫ֧]á�-èÍá/“ž’Í‹s|x™Ã\k½AS3ûõsrþ€xƒÚxCŸùb³02„OÔ¤©¤g˜yYH(f3~Šz—)º*.ÎeøI\�;´¯lQÿ²a–w·Leÿî”±þ4±q“.¿Ïë8�%ÿVɵì*(Ë\‹×â?*Ù,çaiŒn¬ŽYXÉ= ™(¿g†Õ¾gµïÅùU­ªU1R T’F¡šDCæöË-¼Wæõ)¨x g…h�MÎ6Ó¨X?ø XŽWÆy®Òà ìñþ‹ŸUŒž�;þ~oçüâßtKmÐå¾pº|º­Ûç†ÄÙï÷áo\_åÆ�&•¤Å<]þØS±m©âƾƒfEÿ æF¹L¤üÂpõ÷ÇH¾§�Hk†††";œÐ]êj¬•íð�ÂÆÙ¹yàEôÞKT§ÇCaîÆØI%%Ñ�3ß3,áa÷_þÁu»ZeשÊÏ®¶*ãcz§A/Þµ;_?Öúo\Ÿý£à*[«˜ÐšZ5n–—ð?ßþcVn­½¯`âiÑ:•Ìl—ØJê`Üޝ~B}dXMTNiq·vÒÚ)<$8')[X5s—c¥nݪàK‚=§ê�Ûä<äœÞP<º\áúÔ>øŒé›":üö)Θß� ÌT±·�-¸2^i,°�®ó›ú±º7Šf NPv ¨˜#ú±èÜáÚ™t•Úaª_\ÏŠu”1¦ã¶~²úÄEÆ‰Žµ1uŽL.ï€p¤®¸Ø¼ïßî}ß¾¹/ {D°¡“ïÜâb¼ë%Ž* ¢÷*ù{ühÿÓ•õÞrÖø³�ñ�ÌÁr·a02„O¬+Ð3¡!‹²,Ë¿°.SJÞ¸��©Nx“tyi€²±Ry (Yœ—z’*1ñ#€˜E\„“}ä�¢ !Ú yµÎÍʰíPÅ©#e2Xèœ6!ÛH+ƒ¿¡“{Ÿàˆ½¼A´½Á§ér„#uÅ…ÎP#šï±�á{�Œ—¾¦×½ôЉ-x‹h_Á¯Ôº)¶¨Ñi·È‹aÎðF· image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/icons/tomwer_data_portal.png0000644000175000017500000004433314757047403026361 0ustar00paynopayno‰PNG  IHDR^^úB-sBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î< IDATxœí½{pוþu÷¼ó0x E@”,B–lÉ6¡]Yñ:ÒVv�a­ãlœÄ‰TqåQNmÖ›T%þ“­ZW­k“Z¥Äue+[ÞIÊ[¦í8¶W %ëA‰¤Dà Aâ�f€yO?óÇWç×3)RN~6eòV‘�î™éÇísÏ=ç;ß9WqÇqÜo÷Û=ÑÔ_ö Üo÷Û/²Ýøûížj÷þ~»§Ú}�¿ßî©v_àï·{ªÝøûížj÷þ~»§Ú}�¿ßî©v_àï·{ªÝøûížj÷þ~»§Ú}�¿ßî©v_àï·{ªÝøûížj÷þ~»§Ú}�¿çš¢(Š¢ü²ïâ—Õî ü=×îítÏ/ûî½v+ û‹Ë=»—sÜ”û)~?o›œT�˜›<àü V»½àNL(ŠÏÇ¿e«ëÀô4`šî÷††€› ŒTŠZúèÑÆãcc¢½ï¿Ñ[·ûÿ�ÛÄ„¢ƒîßÿ} p?N¡[Zâñ@€[Ÿ�Ÿû|€ms€€¦q«ªüWß§ñŸª6îÛ6Ï©ª<Ÿ¢~?�k�—JÜf2L33Àì,0?Œ�9Ný»7Ú¯€À‹‰ðÒK|ñÍã¡€©*·Žã ` @ ¹M$øyG?ïìäñ¶6ïêâ¶½Ý4èìÔuÓöí«V ðz+•Z (+ÃÊåZÍ4E©Õ P~OQÖ× À¶³ÙR °íb±Zl›ç3ÍJE×Óäï ƒ¿·mêzÇQŒPˆƒ¨µ5|¾––HhjêìŒÅ€¦¦XŒÏÖÔµZ2�ù|$ 'Oòùþà€/|¸víiRý2Û/Eà) ßü&5’ªá0…2rÑ4�XŒ¿�liá¶¹™Ç[Zø}Ù�F¹‹ñ{‘�Ë6‘à6·mÛâñ\®\üþµµ|VW·¶ “áþÊ ·²O�r¹R 67Ëåúý­­J nóynK¥Z lûf½½ýØíöwö¨lUUQE‰ÇC!èèˆÇàŸ€ûoë·ÇéîŽÇ�ï}�æÔ¿|éKŽ“Í¾ÿu>üͼü²¢üþïSð|��ë÷ócшҡ^/ÿözù=v®û}M㔪ª®àõ[˲, ©I×ù=]×u@Qt½XÅ0, Pj:UÍX,Öj€ªò¸¢”Ëüœ¥ªÔ˜;S¶++äÕUìÍM fuѲí`˲íúý› ìÿmÛn«ÿü°¡ÜŸô‡l/^¤™�Róík¿ó;Àg?KEóä“üõw¿ûó^÷ÃÒ<ög?ý)ðÙφa‡‹p* ƒ/\´ §ì�Q­6Úƒržr™šM4Øýœîî›&÷9¥p÷÷²O�wÏw¿½“�ðÚk—/óˆØÿðÀÜÞÿüóßøÆ/û&>�pœp˜³œlC!Ù'ãõÒAå÷M£°y<š8�‹I¢ªPE1ŒFEbšT0¢�dÀoßÞJ!<õÔ�î3ˆã{éÒÿ›þ¹ûÛ=‹Ã^/ÐéZZšš ¿¿­ z{[[ËêìŒÇ]§¯TJ&# \¦SX­úý^/ ë>Ÿ× ضÏGÄ…û®`kš¢å2¬Z¥`›¦û¹ª��™p˜~NS} MãSάªJÓKÓ8#z<œi5�[wŸ¿÷xdˆîÚ•H4�ïŸBÿ³Ÿý"ûþ—Ù~á/A—`�A›© ý~j@Hœj•ëÊ•ÕUÀ5m>h{øáÝ»àŸÿógž€Gíï€}ûÚÛÝûÐu ÈÉ“4°Þ|ÓqT¸~]U- X]Õ4Ãðû‹E@U¥R<à ªã8b²YV­¦ª~ÿ©SËË>_gçÒ’ãø|Šâ8¦©(�e)J­¶¾®(á°®;Ž¢´¶:N©¶]«©ª J~©Tsš&àñ4Oü~ËrM …ŶM3ä¼p@ɰY\Î�{üñwÞþè�^{­R¡ã*péö™Ìq&&ÆÇEUS©éiO§ëg:Eq£·ž:¥(££ÀïýžãŒ�““Àè¨übr’ÛL†èÓ‘#|îYoæÉ¤Óüdl¬þ¨{åÆcî‘£G9z>õ)ÚoO½¦q§`ÄXŒ^¿xÿ²OMÄãá0à °û=îË6 …Ëâõt�š®Zå@0 ne7 >4ŇgfVW�dòùçÿóTõí·ggwvËÎÖ×—LÀ7¾ñ�þ<úho/pö,»õ?`çÈ똞^_ýþ?üÃÿú_»ºjµ……7ÞˆÅxÃÀe��Õj}§Ó}}>Ðܼ¾‰”Ë^o±¨(¶íõ¦yúôÂB¥’Ï?õpõªmï ,%“““õû'NŒŽÚ606¦(Ž“Nó• MMŠ2==18N: †Ü»¦ƒƒ<ïÈÈ©Sðío?î8@294ä8ÀÄÄô476Ær�}–JÕïɧÃÃõGëïXþvœ›‰*üر˗E\^'“ºÙûºUãýÞ|H=ÊýtºPižï|ç+_ÊeN¹…‚Ø”"ð^¯Çáòyž@ö‰tð¸¢p_>—}Eiü½m…¿GG¨Vù=bÎõÏ-§màС‡Þ³øã?þÌgzH$N�ºv ¸=z"šýÁ»»y>U¾ñ cþÓªTÚÛ�ööjµ¥%‘(ÛÚ>÷¹—^*àÈ‘ígã+U”zÍ’N_»V«¥ÓÄœD��QºšM^S:Ío ñÈô4??|¸þZòRùí‰ ÞÄ„yå ú™3DÏòyî//�Œ¨*ðÛ¿=2}}ì×/Ðõtú©§Ëâýãã@*å Ðô4ÿÉÀH§‡‡©é9På^¥?㻎LNŽŒ““¸_þòÔÔ䤢 rÀœ8!^¾/w"ÿ»‘ãÆ~pŸÿæŸÉo�v?÷$==ÀïüŽkוJÄ/~QòîH|ë[ŠÒ×Ç;Ñ4Á¿ï&|â‰}û1• ƒfÁä$5­ãüÑMOËËéô?ù'Ù,_5ÆØØøx½tÑq2½Öw7�É ”#î,G§¦¦¦ÒiE™˜˜š¢&M¥R)>K&³ýîÅx9ÿK/��ið¿þשS¡påŠiF"@.×Ò‹~¿ª†B@<^­ª*0?¯(Ù,Ðׯ¯ãã»w—J<£e½øâððÄ„¢$“SSìáa>§Üy#•áðátPUÞ•m§ÓG�òcccc޼ø"¿9116Æ«P—sfŽqgÕtúða*¡zÕLMIŸ‹ åšRccŽsô¨«ÙëïöVíCi•Hêù/À?ý§ù|­|ýë_üâK/šö�ïpâ¾]ûë¿þ7ÿ”bu•±ƒ¾>NÜâ8Ž¢ˆc(­ÞNu<�g´cgkì[E™˜H¥ê¿+†‚kNP ø[±¹ùI:MÁSU ™dœäå—ÿôO�lVÓÓ …ººŸOU£QÀï¯Õ4 Lsvèïïë{ã àïü�gž¹qèìû¬ãp¦`Ûãã¼>01AÍ Q1LOsàº{gk<~äˆãŒŽ:¨êÓO³–—''Ç™š¢­?>Þhëoxö“̬Àö!ð!@idÊ^\ …jд766îä×âü uuñˆ¢çÎ=:=íšTÀN2–èU±�9•¿øb£ÀNNòóí“úöóÈÙÅbM¥D¯Ëy¦§E9q‚46Fñ–)9�¦¦äº°°ÀA›Í–Ëûöå²mìc€ã˜fW`YôÇt½Z­TÃðû·¶€Rɶ}>€;`míùçU¨Õ~ðž=T ºm»¼ `hˆ¦Œã8ÎÄÄÄ·þYØDà¯^å}ZgÕr™¢Ú×Çþà�¯~Õ4''O�¢762rê”ãHL\ÞZ}_6¾ŸÆ+º6~½ »¿úðá37²{à€„îçæÖ×ïä×3ŠóÍóÌÏÓ‚¦óÆm:]?ÛÉvlŒSm*5< hÚç?ÜLs5jn�U”£GE3K£.?uª¿PUÙF"äïÐ~WUjPU]Zá€ÿ�ß(‰¢d2°±!d´r¹¥…÷ÜÒ¨ªÇÃï…ÃÙ,`ÛmmSS@(ôØcï½´µ=öX6 ÌÎæršœ;ÇóhÚ£�R9ì߯ªÀ[oñ9Ü4•#°ñÊ+ÜR´ê]^U®^={–‚¾¼ÜÚ Ôj™Lo/à÷çrÝÝ@OO> ÁàȈϬ­ýå_ò|Ï?;FÍžN�ŽŠFg{¿™£þ“›çC áu�B ØÜdÈüv�xº‹:Éô[ÿ��zùf�E[ŸŒÇ¡ËõþÆ`½õ+šh|œzpvvv°m× �˜H§%•¦¦gbbttxXQ€çž£S;2Ò߯i€¦QsÏÌÐ ½zµ«ëí·���ÖV‚‘ˆß„ö�É�€ÏG¥10P«ׯ‡ÃÀÅ‹››½½€i®¬p€ðËŠÇu�@B¡@"Ýæ&ðÿ!·ùßIGÇè¨ã¹\=>z––úû�jõòåÇ'þG8¨Õ€‹›š.\ÚÛûú¦§�G˜Ÿöìùÿ¢RFGs9 úð0±¥tZà ~½Žßù·–�'É‹�°gÏÙ³óóþq@Ó¢Ñ]»Umj" çóµ·++ËËÑ(ð£•˪ œ=ÛÑ17ü­¿5>^©„/E††††ÒiEI&“Iš€<žN×Ã41é<×ë|Eù¼ª’ëÁãôôââ�üJâ ¢á‰ûg2Ôcög‚°¸¨J}«× à‰‰±1Ç9rDºÐqR)^#™TUúðâ‹ìèDâ…TÈåÆÇm8|xzZQCª*0=ýÑ�òžh¢l¯ws³£ƒTÞ]»];:€jµ\ŽÅÓÌåtX\Ìd._t½¹ùÂà‰'ººÖ×�ééµµ@¸x8xØØ°ígžL“¶¾mSÐëyóT‚Ÿ×j¿×uÀ0t½R,KUÃX_?}дJåäI`n®­íúužÃ0‹67“êLCKË®]€ÇÓÝMvl4–U*=ðP,f2Ñ(`YÕªmÙl¥’ÏkkÍÍ‹‹.Óµ½‰D"‘F _»•Éã8�·m`xXezÚu¢Þ¯‘/ìÞMû–�°²Âˆå•+·úÝö®r5…´ñññq z?·Ä»{{ùkqj¯_ÿÜçTX]%˾XüÄ'ˆÅlËdB¡@Èç·¶ví*•ÍÍ�'—<žµµ®.@Q‚A „aø|@­¶¼\©ÙììlK  ¶·/,mm_øÂÆ09ùÎ;íítZ‡‡É‰äÀïïí Ç ëù<MPUz02wÚ¶ã�.¡ëÁ }…p¨T66B!`nnqѲ€þж·¶€Ï~¶£#“¢Q]g\%*•Çñx¨ÑU•áPˆ.¾;s¹D¨TfgjµjõìY þÈG––€çž3thÈÕì±X,æ’ßÜØþ¾Û],ðG¾ü2pðàÚšÐ{%ˆõþ�‰@O�¼ªëë››Ñ(p3‡w{�ƒ¸òNŒ=•'´©IU�åååeMÞ}·³Óç&&®_O$€k×VV’IÀëµ,ÃTÕï_]B¡ýûàÂ…¥¥Þ^ VËåâU) áp_mõ¦&@Q4MÓ˪T9Ôõ\Ž×¶�õuË2M`jjaÁq€J¥VcTÛ4››ŸÏ¶i /‡'¤îúhd½  (Uµ,5�QòlvÏjð�`a!Ÿ§cK�‡#‘BдææË—DZí]»ÇÉçûúÛæyÇë¥àW*%*•PˆLÌ£�íòeÑì$Û>ܦ»�¡{ ü·¾Å„ؽ{~žÉ ̺}Ö"ÉRGÿÒÒÒR[P.ßÜ”Qº�bzÔFÍLOOM©*P©<û¬¦ãã³³ñ8pþü™3]]ÀÒ’ãôõ…B¹ÜÙ „B†±¼Lxβ€R‰6k&“Ë=ñ³™<žp¸½ZZ‚A×ëpfY)Šm“|�߸ñø™3$s @"Áhy4 V«Ìš"ïÈë]XDzâqÀqÊeö�e‘_ÓˆlXu¼K §æw�‡9�m|¿ß¶yÿЬ®òj‰D{{©$û÷OM¦9; ¦IŠ·mÛvg'g‚¦Y©ŠÌÍ^o0x{¥ÖÝmš€ãœ9CßJPp3á¿‹Þ¶™r§i@[ÛÜÝEÉ$º]öc{»dMÑn^[j„¹Ü 4mu²U€d’(‰ÛhENM1ùÆÁ` ¼öÚÔÔÐ�Íf2‡µZ¥ÒßÏ)ýúu ¥%ºt (•öì‰F�ÅÅÓ§{ ¨TŠÅ'žüþÁÁhðzÛÚ|>ÀãñzùÚt�"_©Ø6 &“ËËÀ®]--¯¿ŒŒèú¹s@ssssµ ´¶êºªÍÙØÞyÇãyûm`~žjck+t}k«·°¬õuÚǪ*Q1iÈg’}2š8�'œŸ¢Ñ®®‹��UÍf�={ ÛZ[Ù£mm±Øò2P­vw¿ö°ºª(ׯkkápO°±áó57^o{{¡45mnž= Äb[[KKŒÔ‹ìôôô´ã &“œå‚ÁÛëó�í.x¯—)|¶ 47/,Pà Ïûvm`€ìGÚËü �ä`;b+ÌCÉd&&‡ŒÇ¦¦„bÀ¶¸¸¹I<|i©½¨ÕJ%¢ÍÍ««¤¿ý6mäÙY`eåüù}û€Zm}½¯�ç$™OdÛ¦I¡òù,K¢¾€m‹f u°¬`0¦¦Tup�Сap&Ðu K&M“QXMzzLóòe 0Œ\ØÚÒ´d(—½ÞdÐõZ-™ ck+wïÃq¢Qr¡¼Þl–Ôãµ5 ¡&nk‹Dff{qøæf™š´¶ÆãŽ|ìcñx¥:ÄÜÙS§hRÎÏókµ––jhiééY]eÖ]¹LegÛ.{ˆè Éf®Í>=-¡0× Pa§™zW£4–´¶r:on–@Ó�‘{÷RàÝfÛÀÌÌèè­tFR%ôå/³Á‰ I££ÓÓŠ’NONÒ)êèxõUÇ¡�΄m�gm ˆF÷ìyç ooë- «+‘Èç�éék×úûÛ¦M¯iMM[[¢_Ç1 MLÓ0¨“™º­ªtú ƒw.W,îßllÔj»w³G8½;Nµ ll˜fµJªp¡D"¥Òú:‰¨*}ˆööÅE \¦Ÿ³¼<7×Öèz©DD‹ñg¯7ÍdŸ¯·wi ho�ááR)ŸÖ×/_öz�3gòùîn X …’I@Ó<¿Ÿô ÃVVL3—àùîï__>ñ jq":Œ+X°µuê”mK¤h i‰ø“écÛBÎk üÝLFxì.xâîL= ¯^][û ¿îï'+ƒ­Zeg.-'Nl7iØØ‘…—¿L¼�$ª±1†Ô'&ùplrò�ZZ* Ryúé (`¹°{wSÓõë€ãtw‹@>ßÜlÛÀîÝ>ßÌ ™£�9/««€Ç‰D£tæ’IÚФ;ŽPŒkµŽ &£Çôf‡É¶í8†X–idÁòr­V*~¿Ï—Í2Ã`eˆÇ cnhnnjšŸZZ::Ο<žr¹RB¡H¤V<Û®Õ¨t˜™Ù؈ŀ÷Þ[[òùbqd„”o:§LŠ©TTU×9£d³ P]¼¬­­¯Ÿ=Ë@Ùü<ÀߺþZ0xü8—>Ôð°`tÀÄã|¾Ÿú&p3÷êùð„ îb�w`ï^É™½~ýΨÒöì¡¶b[Z"Ç0¶'.¸�8:ê’·êé§©�J‡g2M¾ÈÍMbü�µV$Bslcƒ‘JËZZ²Y‡ÎŸçý0°cCC@¡P­’^`Y^/ €&‚eñˆ¢0óÀM�ç¬'ÙMœC˜8BR›iÒ4T”Ž›½½ÀææÊÊÞ½€eE"SS€Ï78xò$ðk¿V*]¿ôôÄb†AMì8ÀÕ«Åb8 LN^¹24Ĥ–§ž¼ÞH„³¢ä:øý4…¦¹=¥’®wt.ÌÏ·´Ùl(tâ°² ]»|üãss¥‰,-Ù6�L šðÑ£îûh|?ò6݈¶ã¤ÓDù„,26Æ¡q <8 Éܳ³w¦á%Ñ„)ymáë×�hthˆüúóçùÉ­ÂÒ‘Ôì.)ŠèM*•Jipúô¥KÍÍ@±X* Å¢®µšeƒÀúº¢x½ÀOô÷ÏÌ¿õ[Õ*ð—¹¼l@¥’Ïûý@µêñ7�F[[UÕ4ÖÓ‘4Òq8ކÛçL“Ñ4fg œhYÜ×4Ë¢]¯ë‰`ÛÌ¨Õ #67 k~÷»Ôð##Åâü<ð¹ÏíÚU­ßú–Ï×ÚJÛÿÁy>É$aÆövËj51Ò$Ú«ë¼óB!jµB!ff*àµ×š›k5šxssÀ¯ÿº›ðÓøV¶ t‘‰��&�d=}— ÅâÊJ,d³†1< ”J…Âè(`šùüÁƒ€m“î8Á e~.œ8�nmo½•Ï KKùü“ORó>òàõú|Ñ(‰dtxþï8^/AÄܶ¥â¿E\[Q\ ‘š_Ó$áEQ8ЮV5 Ðõõu„�=äó†¡ëÀü¼¦U*ÀÂB.·²ÌÎ2òkY±Xw7M�Hðx:;‰æÄbr§õ£\WQÂaâùŽÓÖÔjóóO> ¬­Ñ÷¹pÁïÏd€ƒ|P×�ßø Úö·fB ¢ˆ‰Õò�í4�»Pà'&…�"ÐÕuùòòòùµÀ�®À;©´¥ÒÁƒ¦Y¯%ÆÇ‰á$“ÌùÉdˆÊLOKWº­µõÑG×׃ÁõõãÇÃáÁA X\\üÔ§x­‡üþx\pn:³Og'P«Åã--À_ý•¦QÐýþO|Ðu¯÷àAÀã‰Åø¼á0M¿Ÿ/LÓl›S ”«9)ØÔôª*.[¢;ª*ÁM7 Ä}Mã1Ÿ/óù€`P×;;ÓÌd67-ki 8sÆçÛÜJ%�‡f(ÄâNô-…¨’ÇÃs:Žªš&µ4ïSŠCƒ|ŽD‚ìÌJ¥³“…_VW3™éiàäÉçžÛÜNžd"Žp‘[½Ã÷å&Ö;¹BEw |¥Ð&¼Þ+WVV>ȯ'ž6¬m¯¬Ç޽ôRcÉ áÂ%ÀM:£pP£󛀦­¯ÿô§ªJRÔÂÂC€×;4x½±X"x½¡ÏÇ\,EQÕdXXhjúÈG€­­ry÷nÀ²�4­­-‘àTÎFü]"�†Q_« 1$-)oì‰zªrcÝJ)ÜÇÿ}>FŒÛ®V …]»ÃÈåöïVVÂásçÓdÉËbHLÓÄwp¡_¹¯ú:˜ò) +@Ó8ƒy<É$95kk}}Àꪪöôo¼Ñܼ²üð‡cclëSqJEsß*Ãiû¼ Šî.äÃk°kÿVÕê¬67Ó¥ È;a§ßª„\£�D""èªÊªÀšæfG-.FW ëÙ,uI ÐÖx½$�y<±ÉX±Ñ•¦¦¶6 —SUjtÃxôQ†ö[[Ÿ�¦€ÇÃë*ŠÏW/ˆõ1ÃÆ×çâÌ4MD¸$ ¥ñ¹d_Jò=9�ª’Sãó…Ã|Žp¸© 0ŒB¡·XZªV%œÏ¡¥(’{ÌkËù8@é î@M¯i$}x<‰¿ëñ´´•Šiö÷¹\.‹QDëRýöçow¡†w`÷n¢3ªº°�ËÝɯ$ý®­�6< ­Ð4²PÛÑ£¼ÖáÃÜF"##Šâ–˜lfæÚµ@˜ŸÏdöïgˆ½¹ðû™$:Œ%Eñû-‹ÜšWºÞÔD8Ðïg ‡¿²,:s"À"�"°"^"ø¢ñëŸÚí3ׄ�»’}9/Q÷® Ä}Þ�ªú|4wB¡X XYI$ÚÛ�HIJJ%Ò~좠R L“WÃËu8³¸Å¦h\) ˇ«êÖÓkµ¦&à±ÇöìJ·´›ÁÉÔòÀ‘#,öQÿŒ�0å]©á ³SjFnmÑ@¸]“‰Slxî±8«ãìߟN�Ž=ªi·Î˜‘J¡…E꾯¯omqªÏdzzØé ,o$\Û.—)øºÎK´EQ|¾PÐ4ÖÜÑ4�G^¸˜õfÇͶԌ‚¾È pyŽõÏ!‚&@¸1®ƒîŠM½‹'Kú’]8 IDATUV …èòzÛÛ�hÔq(+•VWÉ�aåãJ…×aq(1¿DóדÓxÛvŸ�žO`šá0ë‰úýÌ�PUæ?¹[lòúò"ãá.§Öm.LÉí]¤á'&Ä�:;)èR,õöm»À³9Žm;Žmë:™0¶MgTQ€§Ÿ>uJU�?ù“½{Ãa`só§?mmb1Çñù€'žxæ™|ˆÇ+ÒZ³YÑ"¦Ö±.�a( Ñ˪V¯7�¾À@ Þmt§xqFŶnl;MḈõ.š³ñwÛ�¹¶´ (2ƒð×n gÉRIU#¸­-n¯]c`le0 FZ½^1ÍHbsÑ¥í÷&LL0¸~?mvMcÿ-,@WW>OòÇð°¢(Jc*æ­zË}úÆkße^´lkëæfc¹éÛ5:J® Ïv㋵þ�ÿ‘N E€\àâÅ‘�‡=»v±¾ðSO×®mm}úÓÀÕ«ùü®]@{»àÉ¥’ß8sKu}cÃãL3›•Yˆl¿PèÊj2r\øêM“boYD_ ƒUÌH wQ43P/x¢5iæYëKÚ6g–ív» /�8þ2+¸6<Ï#וúÉòÏÅù #Íç½Þr°¬þþK—Ç!)βDÓóyiÐ÷'lJ�.ͽ¾;óð­­€×ÛÙY*��33Ž|ñ‹_ûšªÒp¸V¢®îYÝ¢RüÆÍz¸ëlxaÀµ´äó¢ªá¥[©4?_,2ª™N»ÉÔ4UŠÅHX]ýÑ�l{ssdðxZZj5`cCU¯\öîmmÍç�h4™¼t Èç‡+m(J(ø|~ÿ¥K@k«×;7躦uw“”µ?mz^Wøß2åSO¹ºÈµq�zƒß“BÞ·jõŽ]½Vs}A{x×ÉåTUaE’<¦(´Î½^F’™æØv$’Ë^o­öÖ[€ã”Jñ8`ׯ?ô�Ü¿aPp†TÇYZ"KôÊF˜77�rùÄ Vh››SUÿT•f‹mOO+Ê‘#„g;Z³}¶sM·»Hà«Õú9òy2Eî”ÿ.OXR¦¼��}û::¨E¤†8qbs366¼^®ì¡ë¬‹ï8¬J¦ªss€”îniI&Ëe ™Ü³çÌ¢4¬œF½«+›™!™!—¦¦jµH„¡wÓ¤¦“W-b½PŠÜS§^ÛrÛˆY¸¶°àÝ�/Üu E£ò ŠBAw¿+Î'gÀ0Êe ¬V3 \ŽF+àäÉp¸P>õ)•ÅâÕ«‘`š««œñ ׄü@wØõ¤ä:“ÎC¡Ó§�pØë�™ÚÛ;: `mmrÒ¶‡‡‡†K­3êu7pè>�«ÐxÿRÖÄ� î*Þç£61 –ȪÔ�¿]1`¾¤¼ÔÅÅçŸ'¦ìØÈ“¿ÿ}à çEÓöì%f¢7ÍUµíùy *—�ŽŽP(Ÿ>ýéPèÂàüyM»v ‡‰_ 1!âôi:ZR Ú4eq²ÅÔp…LØ�® "86?'Õ…å·ÔÐ�ΪœGZ=ý`»s{3´C`KÛ–Å*jµ­- ©É0ÖÖ¨áYJ�IÓ’#ÜÜÜÜüÆ@±¨(œ†‡ÃØØ ¼lYDÎGøô€ß‹ÍÎmmšvú4àóù|KKŒ{˜&ðÍoNNÚ6ëa:N*Å@à‘#·âBI€ŠåM\Ó•=G7ײî"�×u·*nS“”áxÿiÜmòhRý—¯ôÆ�\nd„ŸÎÍ]¾L›VІܧVã–YùªšH\ºtv’]80‹™¦ËM rgV%Çaja92܇«�Ô£ ”‹¤³�¶ .�Sñ­4yã§ÛÛÍ¡;·¹ϵ­i»³×Ç0Èm ––€Ý» csS–J§§¦(Pƒƒôºº‰l¸qÃ®_ÏdÖÖ€Z-ˆF¹¤F0ècòzýþBˆÇ�ÍM`ß¾`p}¸zµµUè#|†tšPF:½³¼¡ü-„1·ÒØáÀ¢LO·µÕqRElû.xÀ]ÕÎç»ÓD·±ˆ,‹<×ÂÂððÜ õö2´‰x½Õ*mÆùyÚ˜o¿M4ek H$zz.]âñDÂ0€—_ÞÜlnNŸ¾qƒ¼oR%7 ‘ˆDVV€@ ®Õ¨‡K%W³»&ÌvSÆEàÝoÕ»Z܃h;\)MœÏ÷ë—F|È…9i2‰Óʪ€inn�@4zí04ÔÚZ*¹åÓŸva9¦iÀ£�†B• P.?þøõë¬Qª(d“ª*×ײm&‚?·m*9Ó}ôQÀ¥_‹:1AÓD`G–ã�íÎAêƒdÁ`c‚&Íš»ŠZ h§÷;5e¤‰°ë.—‰dln>ùäÌ µËÜ\¥R*{÷Æb¥pút&sõ*P*íÛ—ÏSóè:ððÃ]]…°¸X($ÀÌL±øàƒ@&cšO_>„ý½…04ÔÒR,û÷s—€ AGÚæ–%´f1uÀq¦¦h¤¸¬UÆQê 2ñïz ï8üný€ ÈßEOâ‘ Œ¸Ó&n*Šã°c½Þ®®\Žç>rdrRD�EA“IËúó?’É¥%)Ü13#pÞÔÔ©S@&S©°´t ððà y½ ´XP(°®Ê�üÝ£�öõ]ºlnj�ÛZ�&ŽÇC“ÍëVI½s*°d}”²Å©gF6j¶F²°—µÝ¶Ðqˆ’˜&‰¶]«e2@kkkë{ïû÷ÓT¹zÕçkkfgóùªÕ��Þ^ؘ¿jÛ4WˆêÔj´Å5-™žVVZZΟ§é·¶FðÀ¶)èn,SUiU ™L¥lÛ­ßÜü…/( à÷omÙ6ëÓÔzñEÇFG'&l[—´S”S§R©»Ì¤¡vàC™¦¬…t§Mìdbâ¡PG‡Ï´·ÓÁ4ŒññT*•RUYH@8îÜÚö /pfæìYD*�în"êï¼ÞD‚¦Œ”â‚o–¥ë»wÓÉûÈGÃÖ×�p8Èd€B!—cY ÓdE°XL�j ÍÐ •0Ù†’Ì(+_—2 �¶¸ãH¤Sš=h¤ˆÃÌü%°¼º®/.�@0xæ ÐÔ�g³À¹s¹ÜC¹\&³w/±{7à8--¬à`Û$êÑ}vÎªŽ£ª, µ±ÑÑ,.NM…BÀw¾³k×;ïO<�/-CCBëå;xå•Ç…•ÖT•ü'¯—É;RX*Tu`@U�={HÓknæöé§GGiON²âåË<ÿ·¿Íž|å•»JÃsZ¤àÓÄî¼IfÔµk™ ‰tuÅbª:2²ÿ… ïïÆþýþç�f‚¬¸ÑÖ¦(~?>€J¥Zmj*†Ô'ˆÅEI&‰^ø|Ôœ|Ášfá0mô� ›uœë×�¦&ŸoeÈçs¹l–¨ _˜ßOû—Oè8¬;#M@2Siš óÂ’ÜŽ³»Ö>¿%à'ÿ’UU8'¶]*Q0YÂã §§�PˆðêÖÖÚZs3�ÏÛö'>AçöÀ@UÃaR$9vûA $ñ˜PR«­¬0Á¤XT–%Éd€ÙÙx|m èïO¥L˜�%+5“YXÐ4`zš0çêj¥ÒҋŸùl[ÓX5™<+Ód5ÃÈd€ÁÁÞÞrèîfíË……矷,Îw• /®ªÄ|Iâ’—u»*ö²üåô4ËH?ùäÀ€m �=vüøž=„»ÜŠc2å�Ž•ŠãÌÌðj@­–ÏKn‘˜ ² Ž$™�<ž¦& ë±onærÃÃ@k«¦MN’465Ų�`™ ‹CÉ“1Tæ8 *Þ]=¯ªü[4½ÇãzÔø_Rð,‹!;Ça,Õ0¸ä¨¢èúÖ 55�?øýL±«ÕVVzz€RikëÐ!V_ص ðùzzhNUWUÆRÅÄR�lØ’YÅ4—–X¾{v¶§8}º¯ïÜ9ÚðL6—LªÕxx÷ÝÍ̓9P~˜3cOQ5amòzºN“Ñq._66B¡·ÞÞ|SU/\~˜š_È€ô î"�÷ûÉ…×u —“5¢$‘ãvO¾ûî�ŒÚ6ÐÓãñD"¹Üƒò[ø£G™Ê Øö‰ÀáêÊÚè¬ÿ"±…ñ–²b{³�‘[Á‹ •J&³kP(´´ø|@[ &-/³<µa ‡µšm3Ë¿£ƒ‚ãõÖãìõÔØz2V½y"ߨgAZV­Fhk‹ÛR‰‘¿ÿÆ fVMM‰DSÓ•+@µÊòÕº^©°4w0ØÛKMÎZ�1•9×­Ã,h�Ä8#¾Uæ8�@ð¬æfÚñÁ ÐÓC´æõ×YÈ*›ýèG™røÄDZX߇™`š&>�˜PLR¯ÕòùD(•è„ÿä'Í͹¯37ÇUÙÝ\æ»Hàóy ¼ßllˆÀ‹¦¿�ÀËë>yòêUàRòÑhGG,æ8¿ök?üá?ûgŸýìñãŸýìü�ßÿ>m=×Y¢S4:ªª@SSµZ«¥Ë\èºãT*„ï¨ÕL“f…¸œ�…�,IÓ¬T‚A X´,®2ÒÙ97Ç;Ôu “ÙÜt¾Øh �”V­Ò䡱#�'јâÜ:ÊuùÄœcùÛ&Ž˜æÖàñT«KK€ßLMÍÍäú˜f&ÃZ‘…Âà à8ÁàÞ½ôU8Ãñ 8Ž„ÂÑ$×”ªŸg\ÿÂqÜDúôY<YÐaqÑï._^[ëïÊe ºª†B’ “ŸO_…@†ëÓ”JÜÚ6kذ˜ùÆF©45œ9S©Ìϧӓ“É$!ΣGï*“&%~®ëÀÒÒöõS——eµ÷o.0ž*5(»ºâqÛ~ôѶ¶ßüMVÕýÿ�“þÑ£’:F@Kªž8ÑÛ[*¹œi.-Q3e2¤ÁƒÌ¥@ÐqY�n]ZºNî_©üÍ¿�Ÿ;¼új4šÏ‹‹^ïÒ’cq¡J¥»›ũ۶5¦ÍjÛÔ`ŽÃUû]§yÃR&€¢°¦cSëÏtt\¹´´´¶NMƒƒÏÒ°ºZ,†BÀÙ³ËËÿ8Mª�¦ú‘$‹5¢&¯Ï�¢¹%¦Ù55… $dÑô\äÍãñxÊeŸ2 ›-¸æm¡pð g¸}ûŸ¯¥%ü~¦^ª*éÔ2ë¹_>M«J…Üœr™”Ž|>*EQÕ¡!×W»Ë4|*å8ºüÅ_(ÊÛo³êïþî�]]€¦�?/¸íû7©rà®@ÍÈíòrµÚÕ%“²h¬úìøLæ©§xæ™×_¯Õ€·ÞXY*•Jef¨ÕVWy/’¿I½,/ÂÕ³|˲í� À4½ÞJŠÇK%Ú•×®±ÊîÖ�ÉØö•+@¥bYÌ�U”®. E"Af‹8ôpÎ8>_¥Âub-«Xtëâø|ªº¾$“‘ÈÚ00àóår‚p°bY?à8¡ÐÞ½D�¨TX·Ý¶™yå¤lSÚnR¹kQIÒ5¿ÃÕn5�÷çñ(ÊÖ– íÀô´ªJ}¸h4�¦&šJ\ä¹þ}ÉõÙèKÉ\«ªd8lš@{{¡°Óﻋ^šmÇ�3€ôïþÝ—¾4: ´·ÿèG,®!«÷mo2†eµ¾ÞÞd’æ¼úê©Sýý##ïOD#<ÖÙÉÔ»ÁÁdrc(—77ß{0 ®˜lm1D*„qÊ7Œj•ç�Dæç�p8\[ã ¨Vé5¨*0;»±áõ««,Óp!Ó”ÕH„Î¥ßO·“ÅQ}>¿¿\f¶n&CÚò� ÍMæonÒ6f1S¾._fŸž?_©47ÓÖåÀmjbíÆ€@€Àu¸ËΧ“*Uém×g�¿eB�ÀçS”åe �DVWyo„ýþÖVúDÍÍ@0È2Þš&(çLÛÞ™º(p0g¢r™�U•›šÈÕ‰ÅHŽklw¡Àÿîï:Î�ÀË/+Ê×¾öôÓCCÀØØŸþéßÿû@$òïÿý_ýLM5.Œ k9ýá2É‹KÆÏÎrx;FÿÀ¶¿ò•7Þøú×=ž¯«×ðýýÏ>«ªÀÛo‡ÃCà ƒgÏ'OîÚE <7ÇJ`,o!µãhÚÚà÷?ðÀéÓ@G‡×»¶Æe¹x÷Ý••DX\Ìç÷î¥8pQèr¹»›60ëÒ¯WUI!dÍHÀq¸ÂM%Û¦/ ‘»“HøýÕ*5¤aßûä¿ÿw ÈÁƒ,R©°.  fäzÝÛþ$5OX–õ´eÞ�ü¦ÔÈÌç93T*…}‡ÙY`ïÞ½{—–ˆ¯«* ë�ÍV�  Oì(ø¾pž¦5M²Xu�F®® Å"àõÆ�@k+«5ïÝ[©X–0%%îr ¼´žàOþDÓæç�Ë—?ÿù�} øƒ?xî¹Gd­ÉHDèÀa0ä­·è üë}òäü·®˜èôÆ"n�Éú—•šÈ˯Õ66ÚÚ(–ÀÖ–Ïwö,ð{¿G>Ê‹/F£†Aèwm (—WV(ºb+ÝÂaÑø4­dEó,kk‹ƒ�%²¥TÊf™ù³Ÿ{÷†Ã?ù 0:/,o½ÕÚZ­Ò�ª§¹}å+áp>two¿ ,.ªj&CjÃÀP­æó¬ßCÓÉëí윟víŠD®^’ÉDbm èèðûóy`a¡»[×ë î¹êOQ¸Râ]…Ãÿbš,-99éú‘¢zO>Iš9«BðùÂt ÀÚšeõôããW¯ž?ÏÀ]c:mÃÃCC¶Í‚ÿºÎng2·àèD¸Ý #®�)}n“A÷XU) .éBjNÒ0M�'ªUjHB—ÀO0 Ÿg¢ÆÊ ´eU«�<T«‹‹\Ø8 :"3«�ÑhºyOœ{k‹ìÄb¤¢XYáŒF¢5“6êk@²Ç''™‚—H\¾Ì\ãÁÁãÇIµ Zöê«üS Wúf/»3†DÊ·+´�‚.}èþÖå4Ùvê~á@q •š�µm ·÷À�µ5àòeæÙT«ÄÇ c~¾·°¬b‘ø7S¥»›©�?^ßá\™�ÿóy Z�ÅNŸÖ× ’¨¼Þ�~”¨Fw7/\®‘[êָȈ 3,£!boYœ t�Á8©ã÷‡BÓÓ@4JçõþO>gK ÿðáK—,‹|r’å:;k5àÍ7[ZX�@U½^ Z¥-¿µÅYDדI®Â÷ƒ˜æèèg>sò$W%¤(ï{Åq|œ9¨©”»T<×DT”\ލØü|­&&%süþgŸµmàÁGFø.† ŒŒÔ÷ïÔT}Ý‚›/=ï8²â‡(<ùäC/ðR®áý¿%BνƅkÅö{é¥åeÚ’L6Ðu�'ãÒ1[[ü“Kâñ €Dâ‘G67H±m7´AìH¥ªUàé§ææ€?þcbËkk++¥`Ùì¾}ð¶6>“ž-‹@J7IÁ%€D¾Ë …x­Z�0`só{ï»w \ºÄÀY±ü«åÎdÜ’)::zø°iƒƒ'NX�Ë V*t I›"€ãLLäóGŽ©ÔêêÄðå/³_#®Zrüøè(à8éôää‘#¶=1јszäK¥ØßkkO?ÍO2™ÉIÇž~v–ï…5>�=~††x\ʘK(ixx§¨o×ì�Íq~Lšúv+±ßnæÜjÂëì4 à3Ÿ©T––€W_�Ç_{ÍãY\4Ík׸–hµÊ ›ë×�îîcÇj5`jjyÙq€áaÎ5’† P£NOÓ¦ýä'çæfg�™¿cX_oo?žö}W�˱¬…mg³äÒÐÖ·mI³¦s¬(ªÊ¤j®ØÜœHÌÍ{öp™ÈŽjå7hª‘êËg4wÀ;pìëâ'N°g††˜L-&“©S)Y…ßåP áÎq¦¦‰[½�úœÓáa*®†[‘õqS)A»hïOLp;<̼V®tÎ*Ž#9®““““;ó}?Ô‚ÞvvóÍGzãl ‡ì½ðñáññS§*ààÁ§žZ]5ÍXŒ+xD"„Ç�ÿößjµ‘‘gŸ}á ¿ÿé§é„Éò–î Â�6555ÅE»fgK%àðá¯~•¸}*•Ë‘þ°°,.†Bá0°²Â¥æËeF^u�ø¹ª«-PPz{ÉB|à–·ØØàB¿KK4_²YÞOg'5ýC1ÊÉ…Ñ\gbbzÚ¶¥ÀÔJ–øVê¼d2ôÉIØL¥qŸ_|*WÿŽ�É0§Ušm#c}wµjtîI�ŽÆ&&Rã¾+ ;Û¯€ÀïÔעѥòTýgÃzîöö3LLŒ�[�H\¿^­2EúmÊÁÁ^p.¯^ÿ¢ëïÇÕŒrdt”Sþääç?äˆiÙìè¨a÷ï¾òJ¥¼þz(Äú.ÝÝg…z$žYRt#`v–vøë¯_¿ÞÑAžhk+yö4�8/˜&yý…iÎ7ntt¬¬ûöùýׯéôØX.—N§Ó‡ëWIú]@IDATúø8ðÔSŽ#âF`�šwtÔͨS''i ¹Ej]xP¼¤±1®•ÕØËò×ð°Ì<¸ƒÆå*‡ë³~°öÿ­rv; ønnRĈ‚pPÿp Ú @MFgÆý…œIU0’FSHUÜ«GnÖrYƒ(•J¥Žr¹§ŸTõÛßþö·9&'ÛN¥€ñqNÕÓÓŽ“N�Œpiû®®‘¯ææ¢QæÌîÛärÑè§>EË»¡/@üš–>#ÆÂ0]_4-fà&þéO�ŽŸ�¸|±˜ÍÉd_Ÿa4  ¦ÃÃÄ´‡†ã;F°¼L“.�N§Ýò¨nŸºk0ñon�‘¥j\çófKÛÔŸçö¾šÛ¥Ú½þ¯€†oltŠex˜/¬q uÍšF�ß9Ô;Dé´Øªª::Úèõó×�ûŽ#×¥§R2àå«_%18Hz„,” ¸àVXqÚÞ>0=½¸¸oP*•Jão�¬62x½d=rí$Çaf�$q{<†‘ÏsÙÊL&aæ@صPþå¿|è¡õuŠ"�C×ö6M ™œžVU`m�º5‘˜šr`yYB÷¸Õá"4nßLOË€æç7ÃXv¶ÿw*ùC/ð�º¦‰áv2ëËÊësõ•ë$5.N)…÷ݳ‹`Gç´qÑs·I!!ù[lJ�Ú9„¤¹/_lÓR‰˜þ»ïÒœÑõhôÀfï8Àr±SàÈ#g*œ�kÝ0>©Sm›¬IÓÌçûú€jU×[ZXšÄ�#ÇÇ¥'ÒéT 8r$•:r„ýä:�®…í–ºs›ø2.F¦ª|êú%ä·›„r×w&æîü¾ý¸'qÛžœ¤óZ�E¹çÚ>óãã|¾TjxPÕîn&bG"€ms†sB“²lÐ�7ǹs£\Q~4¼´[!5·ŠÁ¥Ó�¦ õØ­»Ûýæ‘#ÂÆïÍZýФÙy7ccDEd¾qWú>uŠ‘[Ò2Ç]˜Òqj5Fu¹¶’�½l›Ü·0—â±í|žû[[†Á™aq‡c1Y!\L/ëBÁ­õ(÷;:º´D�Ï#ó\}O5F98O SµÈb¢ÄØe¦üÅx‘Žã8¨œÝÝÞ™w¾m´'ÓéíE:o�.‹¥úþ/¬þ:çÁ8„Ü亊Ç�_º¤ëŒr®®ºžÏ_¸Àå$oÜÊåÙYEt}q‘ çrŒÄ’ÍhYëë4]˜ lÛ++ù<ÐsçXâÍ7�žžhtq8|xr’γ<½ë´×³YS?“á~}$ÛÝssQ'&hüðÙ-‹©õn L@…tº=ûÿ¯ýJ üÏÛļ —clllŒn—»ª^=†³sÛØ¶k~×1¦M{ôèø¸Ë¡sëjRÑô@:Í0~òòILs}�î¢a¼þ:à8•ʹs€ãƵkd=f2´Í ™–Ë««L¢¾xðzuýí·�hÔç{í5`p0ŠM~§V~cû•€%oÇ–¼9@u³£·ŠÔ¹NéÍÎÏOÆÇù{ÑÑ4#êJã÷]ûþf0i}šgœ��/|Áëúúüþ– V£\«ù|ä�¯®öõŽS(D£\ÿ•E�::.\vï®T.]Ôu5e"H¥òÚk¦ üøÇ¹œã¤Ó]]/¼`Y.V$÷JAt�ÖÇOë£òÛ}'1!]w²þSÑð.3êV3çÿ�ÄþÊ ¼¼_ò"v²)Ý%ellr²QàY›p«}Ýì¤RÌ�wïLlïúWOQØySq¢S)jPŠ¿?>®ªÀsÏ¥R~?Q•H(jµh(•²Ùh”d2âö‘©ÝÝ››@"‘ËmmÅâÆFµ ¬­±ú® Gýý‰„mGŽÔ4÷aÄ��� )¦Y}ÍûF�-Î&g�í¦ÌÎ(ÈÎæ ©¦y'íWÀiÝ ²Ý�‘nj|]ŒŠ€=ÊóÑN½u �­þÓzÜc'›o»ÎjœcøÚiî(ÊÄÄØXãs¥ÓÄé¿û]FaÓiI9!õ¨ÕThnfÊ^6ûÆü>E?þñì,Ë„À‹/ÓÓt>¹¬ÌsÏñüÃÃ7[h`{î„m{¦þ]ѽü(¢¾ÿnÆ‚ý`ÎM› ^}8·€ã¤R,3![7]NR)¤H·\Ÿ¨¾ixðøöóÕë©í+‹ª*gIÓóx^y…[9N1q·õ×­?¯§Àkšl©ù'÷/Ûññú²n&—PFG=¹þø8�JqMïÆó¤ÓÜŽ�ó|ãã|þTÊ¥8Üúþ©ýyþñqž_®Ã,²tšýÂçºÙ{äûº“m}Zä”—_¶Àþßn)¨à8|Q�r3�ç ¢`'Ö´TŠ/‚¿¯ß6¾`WàÝS¿•ó:·r½Û ¼¸ üÆ™Lli.ç˜Jiš»O%wÇãáðxäúõ÷MO¥(Ø/½ôüó^/ðÊ+££Ïèè+¯ðú¼WàÝ�ÁÄ•tÚ]^ÍجÀ¯iŽóÎ;¬65Å: ŽCš´Û_.8p§ïn·÷û­¶òýÿÜØ�7´ñIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/icons/tomwer_data_portal.svg0000644000175000017500000007443614757047403026403 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/icons/tomwer_debug_tools.png0000644000175000017500000001621214757047403026370 0ustar00paynopayno‰PNG  IHDR^^ªÒ£nsBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î<IDATxœíÝyœ\U™7ðï¹µô’}#$!!„EY}TÀ÷Ea–‘ ��°:úê¨|ôuÁà #ÎŒ#*hŒd;Œ2‚3hÀQ‘à2 ˆ„l�NoUuÞ?îíJuwU¤ñ}û÷ùTªúžsï}îsÏyγž0‚Œ`#ÁF0‚Œ`#ÁF0‚Œ`#ÁŸ6"!^ÒÅë�£ðǦi òl^(b¬tºhŠõ¾–¨ ͼÒåBv´·%û;V…ùv¼ôO�âOŽñV�Ï öq Çú�]Bãµ®Óì1½î­ûr`¦Q‚+D 6â–—–øÝøÓcü£ÚͱR°�‚§u çÛ‚›†¼VI—¢¯ãe 3¥ÿÿ"^môËQ¾ãåET\"q°ôÈiöë0W¹aßµò6h5O{ýåw\¦Y΂sDß1Ó¢pœÒ k´m´Þp’î†÷‰‚ëÍ‘h1ÓÃõ®ó‡ Ž‹ æØWÉ—$®ÓeV£nñz“lð)Ñ+¼iP‡&£§b’à �]ç¯Öm…->W›Ü�¦¯™*ç_«m²ïødƒðò’ñ%%Q®Á‚‰×ào�táî~íyÊþ‹p—u®qNQr7n¬{¯Qʺ•PÖ3M//¯ÿˆ ‚EòÎTðdÃ~›E�c'~5°9ÌÕ)ñwx£&ç„‹ôÖ¹ÊchÇ3‚ ïu†Íx�èÍ~ÿ¨1^V2¾±MNÉÁÊò~ëÁ°d·l�mŠz½IÙa¸GÅNAQN“мDTQuªØ¡`‹ßØY«VÆeÆË{ ¶irO˜«§ßý¯7 ‡kq_˜kçp?ß•ñ1 nÓb«ÑJFË�Q¢1‡ þAp¯¨“1©\6qW¯bg�¤T¦…rY(•…© (Tš bkQeT“�!xRðkàë=ROÇ�×›$q^�[4¹`¸™ÿ¢d|Œ‚˯<$˜&è–#葘 Ñ« b’`²Š)‚É‚©˜n…½ÊÑøJ4ºÂèJɘJÅè�ÙÑ­yÓvá©mlÚîÄg¶ó\›ÛÙÚÁ®žôS*S®PªP.SÉô›$PÈÓR`TãZ�›5ÉŒCgxý[±`ö‹ÌöüpЃULì/hÁ�všÀð2>ÄUŽRR”ÈKä•$ANAE@NT@³ )ûnµHŒRÑ"‡I*&&‹&v—�ÝÑ)ÙÙŶ]´w¦ß[;غ‹MÛSfnÚΦéï§·ÓÙ]ÇÆ&ÌšÄ/cŸ PöưXWm{\ª Õ¼Mt½õ®©uýú®r”ŠCõ¸9œ§}Oi>ïÉrE.FI¹’.¶�¤…HˆQ£¤R‘T¢|©"×Ý+×ÞEg;»èèfG'ÏìÈFfÆÄ�t—è)ÓÝKO‰®Þìw™øRq÷yðé3ùÐÉÚ'„ùîØÛ´è4Q‹gÊÿš>9ÝnÃq§„y¾³§÷ÏŸþY3zËé”í)¥Œ¨Ä”)b:…K™ì)¥ ëìýã1l¸Ð‘šLA’ŠÛ¸DÞoälu{˜«“!´8CÅ ß—hRÇg4êzíþ»‘Kßš~Z›ÝœÊææcZׄQé÷˜š si{.—ö !½™­ÛÝËÎîtFîèdW7Û³ï–"=Uœ9ÑOŒw¼N%].|AôeÍ.ɘ_E\ª`”SD§âÖ°@[\ª EÑ»ZÐCáE-®!¤o.dºQÈþ‰1]ð†Bs�C¦sò‘¼jöÏ„QzG7©ŒmQi-ŠÍE=I¢]4 ­Ù©]¸[E==¢nA5A¶6µP]{Æfç�Å(t‹~Œ/…wØÛì-q‚hTö 'è1‰¶D³½D—âp—¹5[z-|a¼ÄøBŽQÍ´ÓϨ¦t„T¿‹´4¥mc[“õ-æÓ‘Ø”OÏ[×q÷Ãé(ˆÉcXù×¼õPí¹Dö<�ªx\Á&½¶„…:âr£×P}´ŸJ¼'̳µöšq©qZ4YàÙz#/FÁt¨Xl{¨�éí:=.xƒÔ©ö{¡Žµ›ZÖ™¾MOc_Òó!|ý‹Í…”i­E±¹ \Ì)åsJ…¼R!ý]nÊéÍ甋y¥¦‚Þ|Ђ­;D»Ý*ºÝ‘×mÚî�'~š_ °õ¿‰/ž£»˜÷aÑ�&ñE?s•c›íòε31.·ŸÄeÈ©¸Úz÷õéß±Íh].œ-jüDÙ?‡sÑè9"Á*¯Sq1ÊÊ>1�Öƒ¼¢K<$ú˜øB‡!QqÈÖ]©j9ã[9dxB«ßÕ¶Å6E].Ç¢Œ’Ãäl®w›xƒéJ,2_­ÝÛp£oÀñZéÁ_)º×}†å¦ˆ>…ãQN!.u~¸Èö!Ÿ}ÚÎ�›»FÅ%& s•Õábz\¦Y0çÉ-©±4c[8`*x´Ž^Ä^Õ¿‚Ê oV6 ã ‚éÙ_Ó�Øeá—íû™7t÷§-h¥”¦rª1šÒR‘ðºCÖ.|ÿá÷NMÅÞ�=›ªq1{J:ê±nPã\rnÄ©æ±B“m}ͱM.¶Õ Ç/D' v­¹ÏCåŠ×#ÿì7:J»+âr—dZÏ]UZRcišNOUåWØGÉjì­äLì_½ØhØî|9ëÍ·Å¢ì:Q~QØ[Òüp�ø<ÁNÁ2ŸÈþ>©â纭�«Ýï¤ñÄbýƒÖE¼;®0-ÌÕc�¯Ûál»¼C‡�…³<Ñï¾s=«èŸ§Ùî¬EK«bhŽš-�#:¨öx\mªV«?Õêæ¸ÊУ˜9aB¿ûž¢=,´&ÌsíÂK1â£CJ~³ipÓ¸¦ŽEt¿˜ÉøN‡IÌϲ©ÊÎÃ�ª'å�W2µNä 9cÎSÙC é¶Íç}zÖ‘uûŽH#½c%¦S“òQr‚àdéÂû6ÑÛp��6ë‹‚ÓD× EC âKs=bÛ.¯³äÍš”j5‚_Ù•yür±f‘¨[•µ ¶Øí2èCI¾ûCðêzÚ;£�NQÿ¡“(«”,Þc'.ÆÅq‰Äú¿†UÔÄ6EìÿðÆÝ‰ZLŸÀ¨fQô¸ ³…ªèç‚¢ ¢I\Ûï¤ëE·ScD¥ è­ô)Ò©þ¼ÄYôÒg>¢ýG¦9Áízx{|Oâ›R�å¿éõí�ç_~—DÆô¥*Ä!"|Ã;âKæ õÁaê}&2¶Ù.Ñïúd^˜«3¶¹D»«Ì±%×?(ÎÓÛ|D·^üOéƒÝ¡äŸjäæ�ø{œ&Ó\àn¼Kj,Èàt8xšÍ¸EÅdzL´ÝtœëÙ¸Ô9 ö¶Ó3á}ƒrq‚»ªƒ#ܹUå¢!Fþð2¾ì äÚ8¸) ì7…|NGæ«"“¿ýΊQð5ãämµÕL´9[ÄJv„s«/h¾ 33¼÷âÏ1£Q§[î÷î%g¹Í½qµÉ¢²³m«’T“8˪XR3+׬Ú�6¼ŒOÌîê–{¢Ž™‘KRãI°K%er\n/Ñ|ÁÓʾÑ‚‹K$Vz§¼sD­ZýÒF ç{fÀe?�Kö�º±¸ÿÞ¨ÃÏ~ï{¶*êö1¼%+ܿ톡²Íô—ë �}K}6ÆÇ%e<Û.÷l�Èc.aÎTt˜lc\n/Á ‚ãQ–sX\ëRoQ¶Ê{2?Ik&%߬É!qµyáìê¢wž=gzf`qƒ¶Çã2e׊ÞY=ï9sp™K$q´œ‚¢{Â\»Ž:Jîþûõn]f|KÅÔ¦#¬¯ío-Ç(ÔˆÆaÔã_©U0}ëÎ4�=¹$•ñØNÒ-˜f·±‘é M¾,/ºÐ`-æX媎¾45ëñQ©µú×jŒ !ð3yGª8~Àñ<Î�Ë�ŠkååüµÄ�¸A�K~ú)cî¿_¥c…ics®n*ø¦‡]ÐwrŒB\é=Vø`\Zµ–ãð1¾ÃhÑôÍ;y®ŽFÝ\H£LB¦-”lÂo‘j)ü\§3%8¸ÎŠRk7Á5ÏÖ•x•T Ý$}AÇãkÏóë”MLÔMÀ^ž0Qð—ØK41F§5Ó$”Û·{%þBp°X3«Ò�ôÁ‡5;¤ïðð1>o´`úSÛê{%gM&Ÿ*[)ãϱIâ]¸RÅź}:\¤×*¢ßÔ¹C¯To? ÿ£k¥¢d Ñó‹¥uŠ6S§*$± ÏHt žÌ®'ð”»�<½M{܃§pkõܧ”ñIÁ—µx´ïðð-®c$¦®¦¾?»/7I}ð™¼{é×ñB%«}Yô ±ŸGï^y?Âõ (蕊•FiÔOáµnçþx@¯n‰ÿÄÉÕ£AIŲ°0 Æë])§ÍW˜oÓgh¯oÞiÝ �¯Ù>Æøyõô4ˆsùÀ› ãóöSÑü«:ª$UÆGú?"1®õyíÀ¼,€ý(þ6œNhpêwðÈóPÙH3yÃ"âjç(»\t¸ "ºQçî—y .q:)Sß¾BÓøNåîRZr—' ¡nÖb8Gülx¬žwÓÒpE5qÎUf©8G´Y³ÂÜÔh Ç)Å%–9È-Ê žµ-|P'æjl îIýÒà IŠjl œmsló%”Dëmî—ìz½Þ›ä4ÅU®yë?Øqôq¶Ýp×ܽÃÇø`ßù]� ]ÀŒ‰6‹™ü]nвko”u›—º¤ÏÝš=ìÀ«½~ ž/ð<c´õ«Ê2ǹù²Œ‡O&,ÑÁŸ~§÷µ$í›eϰÝ#u,Û~>ÆG³¶uÐÞ5¸©¥ÈÄQˆÆ+TsW¦IÍwRuò0-Šj¢Eñ:Ó]€c±aÎÍj4£h\ˆ–áè!ÚÖAl3N�׫8Lšâñ <]“ 2 sôͺhök̲Ò ýWp„ñ®Ádzã£äÍÔíñÚÍaÑjbú4šz‰L£›ÓüŒ×#�AõÚ¨V�Œ~¦swŽbl3NÑU¸T*×Ξ<$óê¼ò~8sˆ¶uY6§UÜ,ø'Áj¬´Ü”¾N�—í¨D?³àub�X�•³ðL¼ƒLœ&Þ¥ìÅôX†G�\m¼hü“[¨ ÍøGäR•*œëY E\ ÉåýR-º½©&PÝ\Ì2Å꣡Fšùujƒ¶­ø�.§ã¡j¸åq¼à#™»×~‹u%e‹yåèÜÍÝÞU-J.X�oãQ1³Òðù©é%ˆ¹VLBóSÛê«’-…TÜàÇžÛ�Ù 5t#:Tè¿�NÊ –æÍÔË{ƒêddXÓJð7 uü‰¯öJc°=3û»Ô©— gÙÛ¼O�)J©­‚¯÷y9wèêOÛð0>gвæ [닚–bšŒŠmÞ78å9›æ{‰vôéËêÈì£f³rpA.‘ºj³“êý‡Aý:— æHèKe”#!Ô´ð½ 1Èz‹<Çàì„á5eãPز³~úv–‡Y‘ØÚ/gQætêq¹è‰oÇUU«ô{ø…šþo;\uÆdŠIÒ ù/ð-ü,û]7ÚTƒÂ‰ÛÅAù’eÁíÎÐa•ýâ WÇå¾Ù»Ü‰Ö¼8Þ ãƒÑ¥ŠB{W}®óób–8 Ñá¢s³EoRÎüë=™9ËîF¯`ãÁÓ]YÌ»cJé(ÿsý£LÛêwgÎÿ•Ññ]ÑìŽÝö`�^×¹\Nô~\$8%ŸøÔPu¸{‚á5e£Jeù]uë&Èçª~šî¸TAQ®ªZ•ä$5 û•éñ÷Æ6'j×dŒz¦O6óéçü²«wÈÀG-–£ 5°at³øèUþ3 ¾©ÛÖ»ÔÁ®Õë@›´x0,ÐÛc—9!T霔}ƒøítÑŸ}žìiÇ!‘(Tz%½ ¼$¹„|:â§hñ%ÁĸʇÃ<�šèç¶û:Š~§deí¹™1ÓCªž=¶Ò«~ñ{¥¿øL}c­½Òpà'Õ©……#g Išš1_0Ö¾Îgú­>5·©Äý|;$ŽŽQkàÇriŸøU3mñ)ˆËü}XÜ s†Ë€J*Q¨§Ñ�†ý²¢…·ã5È){ï°+.q±9þAÙŽ�…`ý°T‹èìÃgÿЕ\ý´Ý˺ÇûiSðÍ3ÞèmïRضßM~Ÿ»ÊkaïqÆŸx¸“›òFóŠê99œªÉAÒu¡?–('m–êöËÞ²iŲ۫…fy):}*å¥{°áb|o.Q)4PØzJô”„æ‚mÒ~”°{fbåªÅljšõz0,®‘ÏEEÑ!]°?trú©D6nuÓÌ¿1?¶)ér ®L?NoéknÓì²0׆§¾à5ø‹ADFAÅÞ2ÆÇ(¸Á^ÊÆ·Wl;×søÏ«ßmô³{ÙU=/ñ;ÑvåLô¬6Yű¸/̯_¡><‹kTJ•|Æ·wÑÞ%<(8ç*Y^·s·3UÜ%úžœ+ú%{NÕ©N.MØg‚uèVr(>-8˜,€,Òå}Y÷bÝ¢²Þj¬®7GÙj¬“s]¼.õó¼þÝ[R£Côº]´@°H)ÍŽS¶Pô ±q `¸´šî\¢ÜÔ ¡ú™lÚ.¨˜¡bmX ­žH‰+�•šö£Q,¤š—.^9KõwÿV?³Yvœ�¥×íFNpf\ª`� >KͨMÝ WÙUã²Nœ!8ÓDoWô¿àµ)ÕªÄa±®°Ð·Â<·TÅOô èGbMFÜ ×âº=GïøÖ4 n .ÿôv6låUûØ_0�:õE0Q·çúÏ* l̳Îrç ÎÅA‚ûE×Xh£EFÎ÷BªÙÂqvÅe®UÔ©âtD·é±²ŸË"謲7Š‚^„hö!hv§’Ÿ •Ö=\.ƒg]ÓǧӾ<€ñ;»¸÷7œx˜WŠfXM—!œ¤;.w™ 'eÈ2¿�XD´Ððƒ~'/¨þZ'ÕÛûûÞ£ûÂEé(ÏfÛuÙ§Úð:Ñ‘‚ïkrGlSÐå È3aá T“Ý4¦yBu²GwcxßëYE�3'¥ªc=·Á¿àÒS5‡Ä›pÙ¶Êñ¢3%¾oºÂq‹ßr¾gäªÅgËÌ–·DZÖ•ý³oû¡âû‚¯âB©Èªàç‚hD~$XíÊ>"HŸñ¨_8À»ŸÞjŸ-]¶,ü°øÃ¯¹°)ñ¿Ž+¼+,¨Þ# ãï)ØtÄ,sò‰ºõçnH‹}[›jü&·+Š®ÄQ¢3üÞ÷°!¼#“¿çeU}Ý®À<Ìô5§j`�fÕyÕí^Ñ«ÛTÜ5NͶÒ%—xgà˜bóÂ|[¤%}Û.žˆ™Ò,ƒCø#3>,QŠ+ýÛœ½ýúXûÐà>ûN¢¹H¿ô½�¢T½Œ*vh©óκ´ fî¾™9ì®&ɶ8)šoSiP"«Èn‹mþÕý뻪Eµa½^­rö©® ÁL‰Qìs!ˆq…[q¨Ô½ý¢*‡/½£×­I°þ£§ðнSY߇ñ­¼ÿm$ÁVߊmrq‰Ä\½ø°àR‰Åô—ç`¦-¢ï’UpGwêÉâ¶Ë#±7[åìÚ÷²ê�&k”Üìç$e7 ¾žmöI»­RŸPWv�»õÖY›,WqšàÂ0/U=cúÕeí!†m£ ««âKOnqðÒµÂCÒÌÿ3þüH»ò‰‹·ˆÞ/ñ�VíÉ®vÙnM') ¢ïVS-Vø.Õ̯_)9),öx\i¬è¥>úû$. ól�Wm¬{¤Ž4ø¥ùŽAÌö)8Q”hrG£;ѶÊéÊŽUveXìé=å×°Å\³éüý¸ÂiûLòÎ%§;eg§‰!0¶Åo%®Up‹’£”½O´ÎSîÐ`õ�mrºÌ�lµ1\ä[uºÕŽæD1û;z‹à\Q^0Kt®7ENw¿g®Š¬L•¼­zÿkMT0YÎÓ�¶¾�K$*Þ%8AÎ08g¾†½*,ðH˜ï¹fÇŒ+:fl‹c59)̳&ÌÕ#ïÁ¿`©ö:¢¥�ŽÜ©âN£×€úk¤91]¢Õ¦gVmÐ"f N] ̵_•¦˜lÃçêî{°Ü(M>'¸WÅeqYýúÖÌ�ÿ%Áç”ë”��—lûÃlªšza®-q­ËÜ­2T©¼Ä1ú²¢ãÕK¯.X£ÛÝòòr6UÅVÙ�7 ^+u1|½zÎ.WivƒDÅ®úãÒÀõ±‚ñ‚·(™¢Q¢Ò£¾éÍn}¡�þQö�Ü#"£â‰lNÞ=¸Yð�– †Ež‹×»@°Ÿ`CX°»O&R6�-Œ¥Æö€Kü>sCL­ê1§×KÏ Þ�òe»ý!™ï¦[¸×WlÓ¢×)*”XÕ§a¼ k¯0 g ž3ΚªíÐ×¾VÞ&6Ú†åÅâåµÓªª£ŒùÚîç^r¤èjÑx³Ø��NÕ"ž!z­ÄƒaÞî,Ý\ˆ¿õØf3þ­¶1›•ÏXH¼Îc$ΰc¸^ÂËj§Õ¬îèqUm"Ñ ”EMÒPÜà|È5Fá‹ø†Š�Ÿ«›�3Nªµ u ÖRšn6^Á'ôøŠ•önÔï…âå5â{M”8ZT”3Žލf?Ñíý¢#3Íf Š¢Ù‚ýLÔd`¦pôyAYðœßkHS»±‚ÿ!ÚO4Þó§ î^^Œoñ¸.ïÍŒ˜†éÜ™KàÚFí¶j×êó¢ó·úÍà솰ÐcøÐóÒ´ÞFûû�t{ç?´ ùÿ Ä¥ZãÒÝ’u­ešã²†éÛ/^V2~O�킺T«ÛúÂqðµ>§IÞßË»)®¬ºþ[ðò5{‚¼fižü¾ &P[ÙÌky‚àžFg{+èöFÁÁ*¦ã—/Ýð'7âÃyÚUü•èëë34K?_UñÞ¾lßA8C‡œó”œfÛ•dŽ`(DB\áÔ¸Âoâr¼\ÿƒ–Œ`#ÁF0Œø¿·gmH¦Š>IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/icons/tomwer_debug_tools.svg0000644000175000017500000003554214757047403026412 0ustar00paynopayno image/svg+xml d ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/icons/tomwer_edit.png0000644000175000017500000001775414757047403025023 0ustar00paynopayno‰PNG  IHDR^^ªÒ£nsBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î<iIDATxœíÝyœ\EÕ7ðoÝîéÙ²/–Y^àd}EPICªPÁ•%L" ¨¬B * ¨HpAÙQA Ù&³ww½ÜžÉ,=èðˆŸ7?>“î¾unݪs«N�­ 6`6`6`6`6`6`6`6`6`6`6`þ³ qžÃâB�ó£ðïnSOdÿÝ x»ˆQ°Ð‘¢Ñ–ø^¨SìM„…¶Mì`–PºÚ�¬Nb+bkÁ�áXkßù¤ø�c¼E†áÛ‚ÍmãçXÒ“$1~ßuª<¯ÝCe_ŒU+¸P´�àüä�müzüç1þ &X(Ø\…Wû" 'Z‰ô[W^‹œ[°³‚Ǹ¥ÿÿ"^mÐÿ²|ÏbÛ·Bø®Ztb�Äv¶Ö&£ÊßÃ$…>iËZªÆd !t—ßq®* ŽýÌXÓÂþò½ê¨7È íáP­}>' æ™ Qm¬§ÊÕSÂhü;cާ‡¤¯‚ &ØBÞw%®Ób\_dqž‘–ºXt«>Ø‹ Ò Áá)˜èƒÊÔ±«V ¬ôí¸È¨>Ûtƒ�e|K°È2[ôA5w�5jç]¶ß¦ázýð÷ÝÅø y±ô_¦ïÑ"ñ_ø >$8³WyV#~Ž&üB›Æ2uœ„ÃEŸ’wPŸÏªU@meÛT…2d·ïÌšeÎìÙvßi'Ræ_§¿»ÿ´¥‚i²ŽVáå>éŠVˆ^À:ü­gq˜¤Yâ¼_¥ãÂ)ÚËÔò<ðº`iŸÏšhfˆSåÅ¥YÜ\[]½ÿ5uu&Œ«ª²ÒUç�×Áüãð}eøü®’ñ]ëeäm§ ë9O„ºõ²5ÖËi÷A;áwŠÖ r2*e%¢¢¼¨YÑZVzÖº®jeœk˜¬ý°Z¥ß…IÚº=ž‘x¯j�„IÖ•ibÀµÙì Wžwž½vݵ[asK‹Ó.¸À£ù Ü€t‘ùÿVÆÇ(¸SµUÉ$cjEƒ%vœƒ xHÔŠQY(ÑÔ.×Ü&É(D¡Pò!Æ´w™@®B±ªB¬É)ÖVZ‚—Wôî±ÄÓåtü8ÏH‰à}ø‰J'•aþ7“$ù܇÷ÙÇÌ3TWUõê_sK‹ÓfÏöè_ÿ ³q~GÙ¿Äø³;žl"h•,h“.Ñ®BÑHÁ(E££cSE¢aÅhP±hP1\,£Ák[U-[#¼ºšekx} o4²¢�U�4µ¥ù…"ù"…Å’~“*²TWP[ÉÐÆ�dÇÍØo{¶íq3ÂqèÕ¯¹v’ñSÁXüA»#Âñ^êBrNáÂ=wÞÙïÿô'»î°ƒ«gÎT[SÓ‹G«z≛›oŤNÆÇí&/'‘•È*¨�HŠ2¢ T *KŸ5¢j‰ZEÕ‚¡©h¸`”hDkÁ�µÍ’u-¬n¢¡9ý\ÕȪ¦”©+ÒÏekÓﯭ¡¹µŒ�?@7’f²ùp�)x˜®¥kyœ£B�:|X4Ï×tuŸÆ5“?ö1‹î¼SŒi+wÚv[ß™5ËàÚÚÎzŠ1úÊ7¾ážßü¦ Ä:¿ôJ/Š21J Åt$Å(DBŒ’ˆ%Å¢¤eóE™Öv™†šÛX×Bc+k›y}mid–˜¸¶™Öø�›Ño™„a5é_M%ƒªRÙ\UÁàj†V3¼6ý\Me¹LZžÉ¤´!¤£½dë¶¶³®5�‘k›ijeMé³:ǹ‡‹cGxØ0h–×â<ÁçDßSåìóaOÜ{à^{Õ~ãK_’$ݵß?ð€¯|ãò…‚‚Ã:Èm¿ø|——ëó¿ä$ !}s¡´D‡Ò?1¦ ^¨ª`ûMùÈ.üŸÍ3ŒáµÚU*©V¬É‰U9mI¢A4+W nÃ*Q›D›¨UD•PZ›ªé\{†”î‚Z´ŠÄwÃÇ4Åzc$Õ–:r 6#ñ2vÂO÷ÜyçÚ‹?ÿù^L‡}àª++�uñÅØsO?¾÷^8GL§ ã+2ÔVQ“Kÿj+ÓÒù™£º2-RÍàm.›ŽÄÊlºxÞþG~õT: {bÔ`~šƒvÔ�I4bŒà%œ©è–i·2LÕç«\#�²ð¨ÄŒ0Ùª®uÆ9†ªViŠå=}7”4°[ רhº5¡ëLoÐ(çÁžR§Ú‹‚Fl…Ÿ½÷=ïñ­sΑ«¨è‹�öÙ}wŸ?ñDÏ™#Æx%.ê“á–ÓÄªŠ”i59±ªB!—‘Ïfä+²òé÷BeF{6£�ËÊWVhÏ-!X%±VÔ$hUÔ"h�ì±l�÷|)îaëLÿ ß9Nk.ë‹¢�xX΃a’B¬W­AÖñÖ… ÆùÆKÌDFÑÕ–x¤CÿŽõiq’à“¢jÁà . Çy¢“éó�ÇY‚ ÚDw ¾Ùøˆ l+øJÉYñõšOy£¹Ùo¶Ùb‹ñ×]t‘¡ƒ÷ÇG�üå/fÌš¥µ­m�Ô]Яq¡Kµ£ -Ò¸�bé³ IЀFE�Ú4öa†§]h†èªý/âþ}uŽ9Ó™²·gÑ•A%&�Ì.©ª×zÎ/û d .ð|C÷Ùû;ƒ|$au¬—ÑêN¬«ÝR4K‹¯öÑ�¡¸ì˜1»ÜpÉ%F Þ×ãÁÏ<ã¤sÏÕØÜ|;>NŸÌNdåœíIÑùb¹)úO¡hûUM©jÙÃjØ~3ð’ÿèZëå´˜…i¥–¼×¶öÆŠr�‰7ÙTÞT½Eæ®|7k³'ÐÓX >!çf<ÕãÞÜ9zĈ]æ\pÁ›2ýÅW^qúhln^ŒOèÁôú‰2“nUÔc$a’B¨S(¦Ç¹ª^^™K=1¤š­7Ï”1ÃsبóW°™‚¾kÁH ëu=¨lZúµ 2ehFÈÚãj~0¨¦fï«gÎ´ÙÆ÷ùhX¶b…“gÎôÆêÕ�Kuüî†a�U,®ëýü�÷NælŒ1Ï/OÕ¸žØrt:êñÇ^…“4ʸk¥šÇ•VwÇz™Xߥ9¯ay™V´(ú{éû“”'Ë×ϤºýdVUVrÕÌ™Þ3aB¿Ý\½v­SfÎôêë¯?#c«{Ýl›-·ò³ý¶23Ö«îZ4ð1ׂÑõÒ�FJ7l;¦ô%êåU ÄXámž’—<&iŽw¨±Êt­C&.P/¸ÉD+,p­`GJÁŽ /úµj÷ƒœ§µú!&Jg´nÒêÅX¯ºÐdâ'®öÕ$“Ùü²/Ù®;ìÐo›š|º®Îó/¿üòØ¡yñ ;Hœ!ë¶pŒG»ðb vAƒf5tÚïãƒ�óE£ÿþÚz‹·+¶Û¤óëÖ_b�ĶFËj,‰ŸN>^¡ÒjgI̲>~º·hÛœë-ТQðI©Øù­¬ïtˆ±’–ô9mþ,:XЄŸË™ãYQ­S¿\ïk·=*.þü™öÞm·~»×ÚÖæŒ /ôä³Ï®Àÿ}ñ» òaŒ¼£¥*hŠA³Æ‰2–8ÖJÓJ}ŠÂÀ‹š`›ö¼ª§ÊÄÿC`»M¬ÜJÉ'²•‹=®Õâ¸È^ÝnfL×=h�éq�MÂ$m¦¸ÅZŸÔäc�ŽéæI&Y.ç2ÁÖ8ÆdW‡IÚŒ7ôëw:ï²»CÅ9§žêà}öé·kÅbÑW.»Ì“ÿkþè8Oi“+9¡ÛJÓ¦º5Lö‡®khïĈ�¶ÏyvYÕl<ÑÄ’Œo¶“ı¢�±±‚ðûΛ²†ÉÛ¸Œ»J´-^-uª\°¢¥ÀyªgÍH¯½÷\Óþú²¡gL™â¨ƒî¿[1šuÕUxô÷îù‚dßl~óXçC|Gp„èš~+éRÝ;‘W³óê&^(³ä�™j5‚¿i*yü2±Ë"ßS·*h¬´ÞeÐ�¼4|÷Ïâ°¿¼ä’c>úQÇuÔ›_6w®;î»×-§±ïö]Fï ëpΊuoÑÿ5 ¢&ÖËa«§^Y�èŠM‡S[%Š^prIßÍy\°@´Tô{‰ïw»©ÍÑݺ¦J¤ èí¦t)oûãæ�p@öK'�ô¦Äsn¾Ù‚ÿ8ž„‡>¾‡¥ø©vwõ¤›u¿D‰ésNVû 4 ¬ŒÏ›€š'úSo>‚!UšDÿè�ya’f9gk÷߯: ëÁ®÷„4¨òe|Ïàï¸FÞgÿIÛcüdÿ÷½¯jÖé§ ¡ÿ Ü-wÝåšE‹àóç}È>Úíe•Iaºz�÷wŽpï*ÅÐÏÈXQS°-²O¾Ò»( ŒM6£±äëDIþv»+FÁ †ÊÈYe•±Î´¢´ˆå­ Çw7VÞ"¶Å�{ì´ÓàK¾ð™Lo»ª+îúÕ¯\Ž�D#btänc�D¡a�ð?‚íDÓ;+MÒ7_TeûŽËÇø¬A‚M_]]Þ+9nÙTÙJœeŸÂ%ŠÎÒêÒpŠv/)Šž-ó„voOoÏ`amMÍ¿SWgüæ›÷K¼|åJ§œwž�kVïú|qëDb5^—h¼¬$ϯjÓ„äµÕ’àwx·wÞûª.|Oµg:.ÜâZ4Xbã%¯—×á·ìÈÇMR|I|_îFx²¼E¾'úªØÍ£÷�l‹¶\[™ËyåyçÙ~«­ú%nhl4cÖ,¯-_öÂo¾áÙáµ]’Xƒ¼¢¹ajšøç¹DFª$.t¬eß~ÀF?¾×wžêDU67Øã�·§AœY=Ÿ9pŒÏ¯¨êoeTI:éüè‰ĸؕ^±“Kìgð•pLß;@zà²$I¦í¬³ì¶ãŽý¶´¶:mölO?ÿü+8`ü f‰Þ+(ŠnÖl^gû¦y,Ö9’”©‡,P9¬Yá¦ûåëî÷’~Ôͮȿ%<_Î;ŽMÒpE#]âœ7§è8Ñ Un “¬„°¿|¬3×¶~¢ Âr«Ã™Ê°²¨ !|îüÓNsà^ý¯Åíù¼3¿ö5úÛßVãP<>I¬÷9yÃåEK¬è–ì:ÏfENO2*ã�®9èkÖÕ7Ýÿ[WÂÀ1>Ø"FþQ&H°Ù+Äç­àû‚ƒ­¶ŒsœÝ-u¶lȯœŠóÏš>Ýáõ�òNêi<û›ßôÀÿØ„�ÒE<¤™c½Ü|¥Œ‡‹¦ˆ‚h»K�rúnu)m)Ãx3k<Îè{— ÉøhÜêFÊØ“Õ9FÔ"¦¢3welS"ÉvR-§K´(^gS9'a,-²Ä/»¦lwÁ'qå§�9Æ”Ãï¿©1ºðšküü·¿m“§€Xo¨6ïS´“4Åã·¦x­‹é_‹ :|0Ñ–ÿµM)Û! Ò_‹� s�ÔÚM_VÖX­^蚣9 ZMŒB‡FS.‘iPUšƒaÚ¤1¨v¯èªNFÒ¼>G=Ö*çrœ‡¥y57ØÊAeœOÅ Ÿ8ôÐäSÇó¦í½|ÞFIœ&>¥à¹ôZF�\d˜hØË+)öÏø§eR•*o¹¢©¢s'©4«[ªE«}¥£q½C%ƒ3-Ô5Ée/Ü|è¾ûV|ù”SÞ´©×ÿð‡æþèGQšõ[ßYÐâH'tnY ørÉÝküt-IÁW0¹¿¢Õ§:7%WX‚»ðŒè¤ó$, K¾1×¢‘¨zuuyU²º"7xÐëAÃ4KñÕ²uF; eݪ[*ª’.ÒïÅO÷Úe—ÚÙŸùŒäM<�·ßwŸ+æÏ'Ua¯í|Tº[|OAEâ®v0kbBЂ›{…c¼ë�¡ÍhùÔV AŒó\)ã-Ýó‡†ñ£T-]U^ÔTçÒdT¬vF÷-/tNó�Dk;ôeúTWj“—Z±?Ûy»í†ëì³UdûïÊ}>¨îÊ+ůÀ¥Ý g &HúðžPˆº{�K/¡Ûk “,×#ë!Lóz¹ FÔ EÅÊuåÓ·Ky˜E‰U=}Ôq®*mf‰~'qW¼Ñ—Šîßu§oÆ&|Þ`Ü·Í[Œ¹jæÌ²Û`ºâá?ÿÙ—¾þu…Bá:io7„:E‰»Å^» ‚»MÔèFããWÇù~Ü>ßÁný×x70Œå‹*ZÊ{þsYrY±”Ø£Ð{EÇ ¶}P¡äçXâå’³ìWh—ž5pé‰sÝúüj`ì ÚÚ~Iá¯ÿ»Ï\x¡¶ööâ]š稈W”2Œs~)ºÊúØmnÕî:³dDŸÅ)‚ò‰‹ûÛ‡ûV0P#¾6_�mê%DRd3�~šÖ8GEœÛ%§&/Ó­¥o¡N1Lõ�Jk3RÎÖ*]0ï×NÆfðØ“O:ý‚ ´´–W™Ÿ{ñE3fÍÒÔÒr/&Kņ¸È¨¸ÐUª-5ܲ¸À Z�·Äy*ì‚Cí©Ò´0Ýj;HbÑ„.íYúñ.•ñ.•=Ÿß†ñ‰ŠbQÒÞGªf&!›ŽøÑª}WÖMñÆ’?Âã‚[JíÇä-ìzo˜¤-œ !LÒ\=ÉNƒ±cÇ"#g\x¡Ö¶îoýµ+̘5Ëꆆ‡q©AëU+ø’èÓ‚ÑÒÕc—ÚB6í¹0Å=ašÇ:·à<©£»+cš¦÷ Lª Çë�µÒõVº>Î-ëUíƒeƒ¤…r iد´iáÁ4®àTÓäYg)Ú^ÞûËíÂ+!ä3®oÍ2qâD�?þ¸<<ôøãθà‚Næ¯Z³Æ)ç�§±aù‹÷}Á¬8§‹ÙbK£{ß38\e@Ô)$Õæˆo/˜¦Õ �ùùY}RôI&¿f¥· Ú3‰bE!̶þ¸OŸ¾K¿øE§Íž-ß´´ý¯—:v„¹¢;c½™a’¥‚j]ÄD'¢ hŒtAOUÌ›l¤`XCÑŠ!“¼�ß\}ªAË7ÒÔy_â¢5 ©Û:.2JÑ>x$[~‡úÀŒø(Ÿ$ŠÙ>ßÐBC‹Dð„à/o~YâVG+º_tŸŒ KÉžÃñuøÖ·¾eh)ŠTYYiÑ¢E8àð‡'žpÄŒ–¿þ\á¾³UŒa(6LÓâŒÒÖŠe·Ð·wÆ `ž añàŒëâu©Ñö¾�µž_×E‡hw·hŠ`š|š§`ªèG¢³ûbÙ@i5­™D¡²ãõµ,[#(ÚLÑâ0E}Ͻ¥‚£¥–^N0U*ƒOÃèƒ:ÈGÑížêêjçž{nçïÆ¦uù_|Y²Í˜ndÁÑqŽ ›{AðmºŒÚTn_®©‹Ë:1Q°?6"çC°û)ò]Uâ0]K˜êŽ0ÙO Òhsô„è÷bßñƒ�5‰5Ú‡Õ¤y�=uù×Ö°tÿgs[ †Sæ4 ¡ÕÝŒ�å7߯§Ã—¾ô¥^·<òÈ#>þñ�wü|îæÓܳ˸Ž$½n¨DEØ_Sœëûrš‰ Ñ�Ú,ìæ²š;ÙEA;Bô¶ÃW¹WÞŸlÒÛpêÀ@¹ –Z6–.¤…Œ_×ÂCÏrðNv�£¼Ü ‡j�óÍd¤ ™;ù»þ£÷ØcûtI*�1ºþúë�yæ™ZSur>¦õßMÖsÃBôH8%å¥Ùv]é¯/ÔcÑ.‚_«tO¬W¡Å¶‘×ÃÔ¾SMJyBe²G×c`DM»å‚æ±#SÕ±îù31ªÖìSŠÀ¸6ÞhJ\,¦zÞ0'js¼)î.§žzjg]�>ú¨C9ÄŒ3:˜~…Ž‘Š~-=¤§Ã*â1Á×új~$ÄE¶‹ Üšo´‹ç,œúÚj“ž|ÕìÝ'‰­MNÂ]‚EqÁÛ¼wÃÀŒø½jkËvgB6ÑÛƒ'–¦›}k*½·óâÝr¢K°›h¢݇¥ác%ù{‚ Ø=—Ë?~¼«®ºJ}}½‡~¸£†•RùSÇ…0Uc¬w®V‰v¬Vt[˜Ö¹C¤7,o¶ÄQ¥Çh››޵Rº£¤Ã‘v°41j#Ñö” Ê¿% ãC�|\è§6²×û¶fñ“½i¶IUŽné{ëD©z­UÝë�M„¶¶6ûí·ßúç‘�©wqvœ§]bÇZB”(íÈ®�õ~hb÷ý]�› º†õÚÕÈØ¼3?+Q+}±é¥ ÆnÇŽR÷v7oãÛÅÀ¥w´»= –œ{ï“Êú «á³& V)º#ÖËÄ:‰IÚñEÁyÓuéh �b) 캅xÊþpà¶ÞƒSã|[K,ÄmnôÉ®ÙZqŽ Õ*ÝÚ#«k¼Cü@pKé°O¬’ú„ZD­¢_i/³0Vš¯èÁÉarªzÆ(tÛ—õ1`Å(XdEß}y¥íæ,ž\š>àØðÑ]4eg ~"ú¬Ä“6sc?§Ú‘žh·kU•üöl›ì6Þ:Ñ/;S-ø¥t+%üMÞ¡aºâBCD_—n {Dâä0ÙªxµA†ø�t›<üűvAŒsT¨u°(Qéžž'6õÙï©`—„é^{«ü°˜ki:ÿ:.pÄæ#Uw¤ÃÖ5Cª='ñ}~"o7gˆþèU÷ècõ�õ2Z¬’±Ø:¯ô±¸ëhNäJ¿£ýÇ‹²‚q¢;1Ïh­ÝúÜé¬+Õgçó¿o„ £d¼Ö×Ñ·±N¢èS‚eü‚Þ9ó}aÀ÷@…)žÇúj¦ÊÞCsöRm• “Ý&i“õ´à[˜£¡—hY�f» îUt¯Zû÷ÑúkðšTD,²i)Ó,¨K N]Ã!L²Fªñ¬•n�¼¢ì¹óÕªt…à!E3»yS»ö5õãWp…B™í£ýà;â¶4U{M½0ÉʸØL¿Rìo«¼ÄÞ:²¢¤ÇvG…[µú•¬¬Œe�b«à^‰Û»KÓþné¼§ÉåªÜ$QÔÔgúÈ8ì#&ØOÞh}%*=ãÇöuû›ˆÌ^ø·œ-ü–=€—JsòW½‹OŠ¡®wˆ0LóFœç$ÁxÁÒ0e=MI¤,¥´0ž’Û=ªxQð{ÑhÑb¡ì&æ´¾tð¼i>|¯ûÞî ÿ›ˆ Ñ*vú@:®×«Öî0EÛHÜØ¡a¼­ºØÇÞ0Ô­�¶CGùbY/Ñ×1,ÿ*Þu§i—e«¡ÏóÜóv]-¦hëóÑ)iX7ÚL´»Äaòú,Ý.8çˆÚ¬¶?íZX𕝛J¼Î`ƒ%&Z;P/á]uÒj\dTI ¼¼k"Q/äåD•‚D¹C$nU‹ïàGŠ~ØW펡R­¨FÐ羜x›a*|U›k-4¦/º·‹w׈o7Bb/Q®t²FyGT•‡µú¬h—’fÓ9Ñ–‚ñF¨¤G.ct¥  xC£ûúlSƒ!‚ÿ� ÓwÚÉÛ»‹ñÕ^Ðâô’Óg:wÉ%ðý¾Ê­Ò Æ•¢·{¶wvC˜êy|áMÛ´Ä+¶òéñÎÿʆæÿ|Ä9jâœ^gÍüsuÍUç–Wï0ÞU2þ­ t ê5îìÇýÓu]¡RÖ²~vºþWðî5oYUÒÖ·Pa8ÊlîÔq0ó�‚ßõp6F…Vïl§hSüåkwüÇ�øp‚EŸhIy†–ÒÆ�ÃõŠNïÈöí…‰eœ ï«K mÀ?�Hˆ x6ÎwÒ»ñÀµ°°°ŒÿFõ¬B§:raIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/icons/tomwer_edit.svg0000644000175000017500000004137614757047403025033 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/icons/tomwer_other.png0000644000175000017500000001603214757047403025203 0ustar00paynopayno‰PNG  IHDR^^ªÒ£nsBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î<—IDATxœíÝy”]U�/ðÏ>w¨!•™0$$Ì4ƒŠs øDñÙ JZÉ@*­­²´» žÚŠ­­(h I%*Ø(Ò8´ øE[}̃ ©$•šï=ûýqN*·ªnAŠ'®Wßµnî©söø»ûüöoÜa˜À&0� L`˜À&0� L`˜À&0�¿nDB\ᤸÊÿ‰+œ£ð—ÓpÿÒx¶ˆQ°Ê©¢Yò�Ð*Y«(ÚWpˆ „üîÐb­û9û V‡…¶>ÿ3ÈðWGxkL×{:À�ðÐð"!ˆñrßÔè�ÜZ÷Ç�¹& >%:Hð8¾ûü~þú¿NûZ%ØSÉ£ gÛ„kÆl«¢WÙÕ8\ÕoÇy¤ÿÿ"^¢å…ÈßñÂTl•8Èþú4º/ÌWµì�ŠÖi¶@gCùw\®QÁ§KD?4×áX•m´kÑb œ¨oÔ~¢`…}%šÌuO½vþ$ãÑȸa_{©øºÄ7õš7Z±¸ÂLë|V´V›cFhÐ"83§yXK�6^¢O›M¾רeÔ1]a7ÿ.Xc½½þÌ™�À ‹Ç—TTDD…Q6DH¼ÿˆ¢ 7y^Ô¥êG87é×U§�wâd7㪺}MRÕ§‚ªþ1Æô,ñÂZñ÷Z'8CÑÛ•<6j¹ÔFÑÃØ†»‡?óõH|¯Ñ`I8×@�VþˆN<%X7j_§ÙˆóD'iôȳ›ÐèxAñøZÄv©*zÐ�¡uo�íÊ£ê0Ü"µMPVÐ U”ˆRQ�ÔV%›<`[­X—›¦èuجÁ-a¾þ!ý¯0/Öä¶0ß¶ñžß_”ð1 ®×¤C‹Š-˜$š,q˜à£‚[E}Ø3«U3º”{ú%•*Õ(T«B¥*ÄHŠB \’6–Äæ²tRƒm!xLpŸÔoñ¹·žŒW˜)q ^‰ïjðÎñ&þsâñ1 ."¸K°‡ Ob² _bºÄ€’ÔLÁ.R³»vÃlmv­FÓÒ¨%¥%­˜œ¦Zb4ykŸÆõ[„'6³~‹žÚÂÓ]l줣‹îþìS©RM©¤T«¤¹|“JEšJLj`j³©ófšsè¯|ÝÁí=Ëöv~1bb©Ù‚ýM8À6Ó_‡¸Ú‘*ÊE‰¢ª€’D"”¤ ¢ ùw³¨Ib’T“`*fJMì"šÑW5ek�d[/›»éìɾ;ºèèfý–Œ˜ë·°~kvýäzúêèøã„y3ùÅ'ØsºßªzMXª·öy\¦¤Y+Þ(Zá!—Ö²º!eW;RêPý® géÜÙ1„u_ñX5UˆQRM³Í6�¤Qˆ„%1JÒT’FÅJªÐ7 ÐÙKO?ÛzéêckOmÍWfNÄ­=ôUè¯Ò7@…Þ�üºJ|¾¨û ¸èí|èÍ:LJ…nþ<¶kÒc†&†óÿš2}®Ç±'…~¸³ýOý’9Õì•í¯d„HcF1{…+9ì¯dëøËl¼Ð•©LA’±Ûتh_otø~˜¯‡1¤8MªÍÏ$Ô±�…ºV»ÿ×($LkÎ>Í ´4f¼¹±Ää&¦61}Rö=¹‰†åBö¼PÈʆ�-Œ�\×í`[_öFní¡»�-ùwS™��,Î�áצ9N�Š^|Aô �>’q™’IN�ŒëÂ"íq™’&e‹t× ÇÂsÚ\CÈ~¹�ËF!ÿ'Ælà �%žÍ›�àE{²û4¦O2ÐÒ �Ò$m.‹�eýI¢S4ÍyÕ^\‹Q¿D¿¨OD �ïMM î=SòúS0 }¢_áëá-ºc»Ý%ŽMÊ'r¼~3¦K4ÚUôq¼ÇÆå®Ë÷‡‹ŸíF¾T`R#Íåì3©![!ƒßeš²gSš˜œ—-³•ØPÌ6Ïëîàæ{²U8»LfÕ»yý¡: ‰.ì.x”zXÉz6…źâJ“—28µßHœè¨m3.3U“‹l¨·òb¬5]—ÔR[Bí›Þ©KÙÂWÉŒj�u´ÝL³îÊ…ðÍúG·%=ÂÕÿ 6–2¢5—ÅÆ’j¹ R,¨”Š*¥ìºÚP0P,¨–‹* %Å 7[EÝ‚>©^A_äåë·xÍ ñûaº^ÀÒcøÚ}墋~%ø[‰_+ûU˜¯Û5éTt¦m!ˆq¥}$>�‚Ô%rÛvù;¶kÑë�‚ÓEM‚_«úBXâÎA¢¯´Î#è]/øâvÇG$hs à_rcÅç-ö‡ļýëÊ7ÓáxU7‡%nÿ³ WùœÔúÑ+[�ÛÐ%æßUÝ‚NtIué×5ŠžMt•óD_=ö3Ü4L¡o*³l)‹Žr¿ªSj ”ižàÂ\T½Ìƒ~2ª#±Í?âß }{oÑâÍá›k$�Ô*Œ© ôúôh󈫽\ê|TU}zøXŸ ŠÊ>â.Ñ'Åg³9Œ‰ÔÁÝ™h9Óš9xxT³?Õ>‹íÊz]€3ò‘¼Ø�ŽÂÆzÝÄ+ÍV±ØH–ù�Þˆ«ô{Ž3\Kþ^ÙU¸§îVš%ú,ŽD¥¸ÌÙá\[Æœû0´Ÿ¦0­Ô0!& óUC«t¼ˆ—kìûئLYŽ)M쿸¿Ž^Æ®ƒsT•Fí¬j&¦�¸”³ó¿ö@¡N™ ¦Ž1•FQ6ÒŒïïf²Æ1Ê�@$¼üP¥ö?þÖɲݰû7dbÜpì=+[õ¸cÄÃùº\…­2É£MƒÍÛÇv…Ø^3‰²'±¡Î(z¥î˯ï¢.;Y/Ýñ&ÅVIl­¡GÕS¢kЇnÑ5öðôhÓ®‹«°÷~~øºý|"¶kª}4þöøªYØåѧ•”!8p÷ü"Ž\=�K®ÖïeÁ=a¾žø=Í:,Õç$b›vÁ•N³Q›Ë‡’;;‚ŠègšÜÊîÕçÛ8MöFA¯àJ}‰íšôzŠ±Í ¦¸,œ¤3®òÑ�¨šîöº^¬VEû8ZâõŠ® ïð›ZìŽ#ЩG3;ô‚ñ'|°[%5ë¾'wh¼µ8h�ÁËýkŸ8Ð,E]9ûTáãÅlv¾ÄvøO�‚óc»6½º§ËØÎÏ}m;Ë¥¤è÷{Ñ ‚nüHÙ2ˆ&y�àB;ô„×é´W\é#¹ÔsÓàX2ei=žÜ”ÿÆž*Ö`woÇ~ƒ3lñ[[œ­à! mrFÞNÆŸÕ T4ÞSÇÿÍF°M°–Ü&²ŸÏHýNŸã¯Riš°ÔP§uï‰möóõ[äj[�®Û[tùdx‡G‡ô;ße_œb‹wXà’0_¿}L}À¢“—ˆ¬m#®±›fk¿ÑìÚ¸Ú¾ _97Âô!ýž¤3,¶6,p{íÂó±â£ƒ+)¬ùhj»MAt»˜óø‡I,Ì7²ÝT�…_V*š¦b·:žƒÆœ8Oä“Ól›;Î39ë¼üfj²Äœ:ŧH̦&ä£âxÁ›Ñ$³Z¾—ÚæqS|MpŠèÒ±ÆPƒø|ø\ßÜÍÃu¶¼y33©Fp·îÜâW�ˆ5›ÚpÙªªS°ÉÐU ™ûîÏGÔ…§1sØ“ÑÐ¥“¨J� çÙ†óq~¾9ï”ýk\YMlWÆ~÷<¾Ã!Q‹ÙÓ™Ô(ŠvN¾Q•ýNÐ&Z'ú¥ÄåC*õ{Hô}j”¨l½Î¢¡,åY£Å¬`ˆÙ7|_ÿ0kc¿ŸJ|Gf±üOnÞÜ7IäD_vŽRÃÃ7¾<¾b_4ß9Š›zÏLiÔ-úÓvžæëQö^a®ãÂB¿ª­ÎÒ©Ñ?ãë¸÷áR﮺G˜¯_ƒOãßwæí/—ú@‰¶£ì™6è²Ä€Wë0?,õððæÜ4¸8Â�;¤aŒ•?¾¬¦ê@ïz|ä£$°Ï,Š]¹Al9ÿR+FÁ¦*(ëÐa®Ú˜ob[ÙC½F.Â|›b» ló%EA£N³ Ä5vU�nóà"É$™Qß²Öš·ríÚ± hãKøÄÞ½} �ÖQ3 I¦< º¥‘ãJ»Š žTõÛ]p±Ub•·)Z"jÖì÷Ép¶§Æu¼9rÓr+gŸOâå¨hse¼Á•cE›Ê×F·-mǸ>¶JTí¿¡SaCÏc!aßYHuÙÅãq¥]W ŽCUÁañF÷:U«�—ÛIšs.ùZ Žk,§«#/�Ó–›¦ä2ÑÛoÇyÚ¾øD^¦QâÕ JÊn óuy¤Âí·èXnZSj·†Ã=^6T[ŽQ¨a�ã(Ç¢Y0»c[æÈŽB’ñx¬'êìa‡²QáQ ¾¡(:ÇH)æhÕa2þx£è©ãFÜå̸Ҥx£¢‚wK\…+õûÈo>kòí·K»Úì1¥à’†’ï¸Ç;·WŽQˆ«œ§Íã²A»S?ÂwiÍÞ¸�§ëHÔ�¥ÌË$äÒBÅz<ˆLJáwzô›+ÁAuz(«ÑvŸTí!˜1â~4»zÔ Á[±«hFŒN=r®™¨vnqþNp�hé`Ýl!}Qða�Þ~{ü_Ô"˜ýÄæúVÉy»PÌ„­ŒðK¬—x>'u¾>…s xT*z Nž«ÜþL(ÛH�¬�Äf<%Ñ+xLÎÏOè×�äÉÍ:“à<�ëë>¡ŠÏ¾¡ÉýÛo�ßæši�»=ôT}~ïíñ¸IfƒÏùÝýøç!ÏQ±Æ7DŸ‡XônU¬ÑhŸ ¸Câã̓÷‚ŠÔò°8sÆ>§ �Ÿ²Ðú/ý®ßù±;_ìl�ö4Ùï«gNœ †w5~„/ÚGªñî:¢$ƒ„� u~ Gb¼ÑWׯhŽ ác¬Î$šz�L-�Yü ¦é·;~gÀãJÄ^¹Ñë¿õì0VÅvSõùòOïvê¹ß”lì$ Nëìõµ„KR>ƘùH‹ñ9;¼N´âkuç�E#\$ZøÛG4_ñ3éí븫E»m¾Š»®Ú:¯à7 ¯‰;ÄÁ·r^…)‚·à˜…¾KÕ{•}ˆÌÁx­ø5¦‰¦=¶‰tlÂß«�‰TáLâ ‹K$Ö)»:,ªÑöú¼ö?nóÖ³.6wÞMÐx¯,výxõÕóO⃲ȱZ|‡âFÔèuª`É{Û”Wý‚-=’Í Á»ð\ºÏR�Ëý‹‚[«QcG¿oÏÚ!\ò�Šp¤è lOtž,sK6�èó¹"¶Ù?¶ùÓ爥‚˜w9ø9tŽxßçÅØæŠxqf÷ xâ+>¹Ëä‘mÕ|¶âÌ:UDÇõ:ð²!ã�Bló…‹I§4�ZoK¡P£Õ£C»Yq•Câòþä¸Â̸ʫâ7M®-;>+¾`–ªÆuõYMS9 FÅfïòœ¿æ»Š¶n——?ó]»õŽ2&Ëо5ìþÙF®ôZL“ù vña`/… ¿#Ô‹ŒÈ1¥Zõi,g„í¹‹qXÔC8ÃÓŒŒN͵j*J›¶ÕßÎã0S‰Žá6ê¸\£~ˆn‘¸!®ö Xû•mÏlø�]çÞK<ó¼^TûGh•~ý§îŒqlû~K£éwÖV:ÁÚçF»ñ!|ÐRI•:{ë[þËEÊE1 öЋEK{‹ŽQÍVâS[ý1„±mÚ!è«“¹½3±/dQÛYß?]ã=cÛø›Jo(&>;VîÎ`¼Vü¤JU±»nÞÅ �¦/.Sªå�* CÆ‘_¥©ïÇ8z¸\!Ï<ÆnV¹5®tbld›kÕ³·ìÀ¶93ÜWùª&ëL·>¶¹âªwëëOç6S�Ÿ6Þ !Þ°s{×vŒá¥4• Œ"ÜŠÙŠŸ¥É×]Wç2ü ¿\�;´«bU^íü”úëôIÂ…oUÄËËìã�üѵ2µ½ÞhÒl¼û"óDïÌÂT,ü»—úx¡àW£Ô“$ªÿãEúËE½ø•BfY�ß2×&߲ɷâòºVÕº/ëd’F¡žqŒÌí—'-¼IpNVõoÑíçK¬â5aÉ�,¼Eø/kH¡±¤²Ç4~øáÌyžcO òë´…ãÊ%÷– CXÛfÜ÷Å–Nn0ßйpò•ïóY™uqø¶ÞSúÐ[œ4Pu†>g Æç½Utºèt¥Á1<#ÆKs($ÒÒÈÐPdÉ ý¡±d³ŒOvddçæ�§L>LÔhÀ�a©“ðRü]K“]>7ß1g¾Öa�ÃCYcÛô:*F…ÿºKüát?±ÉƒltÑmXóþad8Q8íH 8\ö}JŠIË®éêõ�W|ÜÖKÞ£eîj5‹?‰¶¨ffë¸Æ.RGã¶°°~†úø>ª$‰´8 á;{éì•4–݉‹EÍ*56ëZôy;.AYÁe±Ý‡Â|wàŽÎok°ÑW‡ÕC»^q(. ‰ýÞð"Þ�É/‡ˆ ‹¥Ø*Z'Ô„ÚeÈ}8+^á3\V*8H0SŸÎ╇ë;ò\±uG­ï+X$‘¨ø)¨ZŒ/È´ä÷Ô›æxI5}…Dµa”€ê§¶²~‹ 5GêÆ°HûðÜRˆ«LÁÛeš^Y°˜¡ÔáD} –áÞšj©à—¢• êX!¯Û�‚àíq™’==,ø5«6Ë«ú²î“uâ´R–r¿‡èMÊÞ/;W¥V$Kõ†Å¾øî`žkt§è—âèþƒñYñ‰-¦5gq�Ãeù'·°®ƒíi?ÁtêäÁ }ž"nP¶Ù-p‡•Μ‰·‹.µØãÎ@Ð22Þ 4 ŽÕ—»\Y�Ô©(‰®×oÕ�ì� g�¼Q D;qA£«øï±ÂºÇ‡ð© �ÞÙÓ²�´:ŒðÛz¹õN8Ì!¢y†gÓå'ê‹+}BP�d¹û†-ösü|HåEƒWwÈ6Ò¡ ÑmáÜl•çoÛ7óÏhhÇËEG~¦Áb»’^Fž ‹G5Éã„ÆŒ†ÂØ ¬gîÌLt¬g6øÁïùøÉCâÜ Uó8ÑÛ%~f¶+ñþ¿çlO) &Ÿ-··¢VY$ï—-};©Ÿ ¾…sd,+Åïÿ:Úð#Á£êŸ‰à‹î÷{û{Ï“öÜÔkÓâ‹¿¸Â9 ‰ÜÛ¼+,ªëÞ)Œáñ„ý­?|ž}‹‰ºùçw®Ë’}›¼xðæ÷•EŸ“YôNóˆŸb]xKÎÏʳúú|Š\T æºÂÉìÈ©Ež�÷1}n½D°YêÚpÆ`†ÈH¬2YÅ…o˳ìiAXh“,£dû±‹'`®,Êà`þ„­*q•ÿÜwW¯~åþÜx×È2{ͤ±Ì�ð½m¢L¼ŒR[5ÕùÍz5 æîè̾ µþI”-´>„LÖÏ3²Ûc»o;mh~×`D­[o@³‚=÷†`®Ä$v°¹ÄØæ:™Yù^…ç–8~á®K‚‡>v³{Æë·cZ3ï#IÐ!õ½Ø®[%æÀ‡—XÊP~æÚ$ú ywôcý¹ßv¥£$VáZ«�^k·É³7¬–¼¶�U]#¸:?ì“N²ãµzó>n6Pgcl°RêÁ9aA¦£0$/k'1nÅ(Xãh©¯?¶ÉAËnîZ—u°ðoùŸGè.&Î|Wô~‰»Ì±zgNµËOk:QUýd0Ô¢ÍOŒüº[ʼna©‡ã*SDŸ—å¶Þ&qNX #^¢Å·0¨üÁB‡‡ æçœ J4øÁh'vŒÛj§ª:ZÕçÂROî,½ÆÍçš¿Î?‹mNÙs¦·µžê¤m=f„À”&J\®ä»*ŽTõ>Ñžð£ìþ¹:GAÐáñp®ïÕ)V»šåüïèu‚3EEÁ<ÑõXa–‚¾!sdY¹(yý`ÿ—›¡dOŽvôml•H½Kp¼‚ÿbdÌüh÷¨°È½a¡O5µì¨)MŽÖàİÀÚ0_¿¢{ÿŽe:ë°–íèq¤àÇR?6ɱ£ŒþR<)ckÌÎ#Í‚&1'p¤YnR˜o‹Ìq²U¶9_\÷܃•&ip±àV©O ±¦ÖεU*ñuÁŪuÒGÇÀóvüaþªŽxõÂ|›â�>áféX©òGÙ…‡�(S²VŸ›¬d[U?–¸Vð2YØßÕƒuº}Y£+%RÝ£†�ÌÃÑ‚i‚ש˜e´@¥û}Çk]÷lý‹œ;¹SƒŒ~�Gówòæ‘�w‰¡udtY8ÃÓq…w ö¬ ‹v”ÉYÊ:ò�ñÜLÙÖÄ#¹b–èF¡nsÖ^¶xžõy”/ØãÉm7™qjHÄ}l×dÀIRH¬Þ.a<«¶Ûì�wž6ÕÚAÝaûó=jÆhǰË/,Â7yX¯÷æJ̨áܹIàòÑžëЩÙWDg ®óÀÈ膰Øñ¡gÓC·ŸÉŽw~~#^èˆË4Çecž5³óm-×—×aWÏ3^P<~g�Ÿ‚ºL³ë‡‡Å=ë¶.Ö è)º&®ªãN|ñÂb5;ƒ¢FYÀê^J¦SÿXÙÜjy¼à–ÑÎvWÒç5‚ƒ¤fãÏÛ¸‡á¯nŇ³tJý½èxÕ'hŒ‚` ¾%õÞ!'/Õâ4] ÎRqŠÍ;Î¥™ÀŸ‰HˆmNŽmˆ+½ó…ú´L`˜À&0�qÄÿÎqãT!lŠIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/icons/tomwer_other.svg0000644000175000017500000004057314757047403025225 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/icons/tomwer_stitching.png0000644000175000017500000001760214757047403026062 0ustar00paynopayno‰PNG  IHDR^^ªÒ£nsBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î<ÿIDATxœíÝy˜]E�7ðO�»tw:ûBH€Â2€² ¢": < ‚–,„ÕEF–†€ ˆ2ÊBÒI€„A\^Y”U@A‰ !  dOïÝ÷Þzÿ8·;½Ü Í+>o¾ÏsrOŸªS§êwêüê·VØ„MØ„MØ„MØ„MØ„MØ„MØ„MØ„MØ„MØ„MØ„MøçF$Äy‹ ü)ÎsBŒÂ?ºO}‘ýGwàí"FÁGˆÆYêšP§Ô¿ØA4E°³ó„òÕÞÕê$¶u¶, Ó¬÷G�⟎ð‰Ë[ÚÞ/°´o•Äx­ëT{Q§G+¾ØJ­àÑŽ‚Wñ¿ïnç7àŸ�ðÏk4ÅÁ–r^¨Z8ÉjܺѶ ÚäÝŒÝý~�{úÿ/↾ù;Þ[�Šu;ÚN‡Œj S¬{¯¬e†8Nc½ùwœ«ZÆ‚ãE?·•™a…~m4j¨Îp°öŸóL‘¨±•g+µó÷ ŒF Sl­àj‰ë´™4Pµ8ÏË|Gt‹zïW¡ÊPÁá#8ÊK†Vhcíê­vY\dì€}ºÁxß,²ÜÖçÈúá½Åãs "¢Ì "$>€/#+hÃý½Ê³šý3qŸÍÚ8‡‹(¸7U|V­¢vul¤Ooï­ÿœe‚™²Ž–óÊ€õJVŠ^BþÜ·8LÕ*ñߨG•ãé:+´ò"ñ†`Ù€Ï:ÊJ|At˜j{{ï)ß±AFÁŽŠ²^ðL¨ÛÀ[cƒ¼NW´ RÒ$È˨R’•ˆJ ¢V%ë嬶DSO±2Î5RÖ~X«ÊCaªŽ^ÏŸg vUãwaª¦Áß?”ð1 ~ªÆC •1µ¢a»þAð¨¨c1¦X4º¥S¾µCR(RŒB±(ŠBŒ”� äsJÕ9qH^©¶JS^üEÉïq�¥ž«$ãÇyÆHÜŠáU9y°‰ÿŽx|Œ‚ó;  &Ú%† :$FItÊ)#«dœ`¬`<&ª·Y1YІ–Z*V*£aëÛU/_'¼¶–åëôÆ:V5³²‘5Í´t¤G¡H±D¡D±H©,ß$�\–šµUŒbĤ1¶xß>´ßN¦Og¦É¾€û ¬d¢`[A ¶×dƒKøÚSA^"+‘U�“H”9%QÕ‚ªòïQ�D­’ÁŒQ2J0V4º½høúVISk[hlM×4³¦…åëRb._Çòõéùëëhm¯ ã&�áÁsØr”ß+Ú'ÌÒÖ³<Α3D>)šg©+{²º^uÚSÉût¸=œ¨ñ­ö!,û¡WŠ%™%ÅRºØ’R"!FIDŒ’RIRв…’L{§Lc­4µÑÜÎúVÞX_ž™e"®o¥½@G‘öN: ´u–Ï‹Äw‹ºo‚‹�æk‡h¦ù]ßòØ F«Ñj¬èËÿ{ÔÉh÷Sì/qX8ÎÏßêó³G\f‹ÎbúÉvRB”bJ1ý„ e.ØQH ÖÚù�#Ø`¡9U™‚$e·±NÖÿ&ÈXãî0U+‘và(%õ�¨RÁf´1T´Úý¿F&aä�ôRÅÐê”7WçVÈFÕ¦¿Ãj¨Ê‘Ϥå™LZ7„tbt–uÝöNšÚÓ/r}+-í¬+ÿÖä9ëpq«Ñ3Ò'´*hs¶àtÑ5ª�Y&~7â9µŽ;Ãt qŽœyÓµôÕ 7†w´¸†�¾¹P–�BùŸÓoc¨Î±ÓDÙ�÷oÉæ#U«sh•Òð¥!y±:¯#I4ŠÆ`HùÖ6ÜŽ5¢‰Q» ˆª ¼6Õнö /ß?µh=‚«Ã¡ZbƒÍ%Õ–r€cè£KTÛLt6vÅþq®;ËëC§o�výŸËP[Í�|zÔV¥3¤û7OMUZ6¼†aåºùl:«²éâyç“Üÿl: ûbì0|Žß§1“hÆæ‚—ñU%/ÉY®Óê0Csœ¯Vp%ÝC{\â á8kz¶ç¡F•éVTšy1 n1J³’YÖ…ž_z£fy/ >,5ªýM¨ í¦šusY_«c`[Ò›!ÜüE±:—mH^¬Î)æ3 ÙŒB.«�KÏ‹U�ÙŒb>«P•Ó™ ÚB°Fb½¨EЮ¤MÐùàòuö9èbžî£ëÌú8W¯=ŸõuÑ#‚�J<&ï‘0U16¨Ñ(ëM!ˆq¾m$ÎAFÉ–ú]—ü ÕædÁ±¢ÁcŠ. Ç{¦›èómƒ3tˆ~*ø^—ã#ÔÛAðͲ±â3ü1±Ü~ 34—Ó÷ãE÷‡ã=ñw>.p‘’Nt M:›Ð,–‹Z�hVÒ¬Cójx:о º|ÿoq_…¾&ÏœYLß×óŠ>Ý“@e"Mœ_Uäÿg@Gb½/ã»z½ê�ðik{Hé©0–œ§Í…�#,ôA%g ¨è¾}}'ÈÊ;ÓbѹâÛY6Š’�Ö´¤¢e_ŒÂN[€— ñמe±A^›ó0³Ü“]í`_¬¬ô˜x£‰ fèÏ2÷Ð蓸I‡ãújéÁÈ» ÏVÃ|ãDßÁþ‚(#ç8)œjÝFÇÞ GÉL½EI!& SC�Ò`=ÎU-˜òÊêTYê‹á5l7<_A Ïc³î¿‚-å|XÑŒìw=È &–ÿš€L…:£eŒØÈPªEiOS¾?Þ0Õ©ß‘ðÁ÷ÉÝ[×ÿùƒo�Ì�Í_\‘Šq}1y\:ëñd¿Â©šeÜ„õRÉ£^•µ]űA&6ôDÞëXQ¡mJþR>_LEv²\i×ë$±®=ŠÞÝŠv´ˆn5Áª�†]7Ù~ò¶~¾ß¶Î‰ jz ¾=¾hƾ¼ª[Ié…6/ŸÄþ³'cÎÍ:<« /x6LÕbˆ5fiw2±^ƒàFGY©Þ�ï£ìì ¢Ô¸ä=§Ým8JúEA›àFíþÔhs$Ždc½» ÷£p˜Æ¸À¥¢{Q4ʽXu²¶ñ1‰eÝŽñxZlŽÝѨÕ6èƒOø`|¡dÜ_^ß ñöÄŽºO·ëÑùÄÆÉj.³Ÿn>þ@•µÎ�8Ïÿé¾¢BpFlP¯M³àX)Ûù­¬«ºØXYJ:]‡§E Zð ys,Õú¼à|ô„ý4Ú:ÎwfY깯»/©²4A«×ºå±¥‚EØ\ÁÑØ¶{„CýÞ:'ÉXjšÕf–Û‰Â೚`û΂êg+øÿC`ljš·P¶‰lë[JžÒîÞ¸ÈGzÝ4Òö˜¥·Ó:�ÏÇzÂT¦»ÙzÇjq¨fç†c¼Üë¹S­�w©àÓÖ9Æq®SuØÆÑé6�Ôx¼h‡žmÄEÆb‘àqCÜš:äËÆAÕ빇i 3ÜŽóDÏ54„wcÆG;J,YÞ¿hD ã‡#zB,óøV»HL+/dã�ˆ‡»oÊ©`|ÏAu™8¯•µQ³mÙqžÊY_(_,&±E…êÃ%&Ò#ä£àÁ!¨‘Z-?‰+5yÕpW >-ºrc}è�ønø\w[ÛÂK–¼IcR©Fðg-e‹_F"öXÔúÊVE�‚ÕzÏJ(HÝw?¢f¬Â˜>%­¢ÞS'QTÒ/X$|AÎÀåÅù-Ù¿•ÕÄylûì«=1qµÕ¢è%§”ª¼§õ¢e¢‡%®íuS‡¥¢»é¡D¥ è�¦÷f)oC­Ã¦y¤ç=áD�ªý®Æóø ®Tð•wª{„©:T¹ßóÁr¾¦»cÐúÜÅùöÝ&”")ZÂt5ÙD"ãs‚ÿBV‡9�ÇE{ý—¦æzª£ï&𬒊–1 ú¼zÕqŽ”ÙU¼ÅµÙPÑÄ•M¬ª QWçR/“P– –ã…òÐ xJ«[I°c…'äõÐvßMŒîw=‚0¬Zµà3ØL4:FG칕1(6®³3>%ØQ4«ûÞkdEß|]µ�º.᳆ &¾¶¶²UrÒX²©°•þxË%>‹‹”œ¡ÝÅáT�^V-©ð„NïTn3ä­¤BVHbmŒbGQAðŠ2?¼¦C ’××jL‚‡ðîì¾÷5E|Kp�Ïw]+u¦ï޵268]Á(ÑR+{»Î³E‰/%Uq¡+ü¶õÙßÚï{ ½è�Á#|°uŒüµ‚“.`‹ÑVŠe›ô|ã]+8PPÔnrœãÌ.skKg:Øg^±Fjš­Âø:¾"õ,=Þïa0Ed´NÀž©û#©½e:æ•#ÇJR©ë�®J599‰o%LÑŽéK{Ö¥v�r„ñÖy.œ6p– ƒÉj¢Ik›i¬ OÖä]‹h¤\wìÊÁöå*Á.jºÝ8ÿ3¦Æz?»ÿ,/e_ªÎ˜†:œB…ŒÀÊ¿—á*ÄÑ÷@+ÎJ‚oÿúLS�ØËݹŒ¿«ñõžö–ꜜô…†ò˜'`ûr´Ã|“$IüÂHßè&Ë|µq‘ãÜÞŽŸA!|ŒB—DS)�ihuƒ‘:¤>¨N¯ê)NFкÁXõ�mR�Ò¤±Ž\Óì€]¶ô©³Sè(¹?—ÎöQ/Jm;÷â_py…:[H‰8SÆ õøÈ!†ÿû¥nþý_}òÒãT=xŽÍ§íc¯rM:JÑãbÙy�xRìvN‡1^p(ev𸬢{äÓk]V³ÈHÑÈWVSÚ8៓IEªp‚qž‚ã%–É»9Lß íMßÇžO¾È=OIþ¼,u¼ð†¡ˆIb—RÉ)oÒ«f©í<â$Tr»±]K»#µNÚ�ª¬äáç}dÂ(ßJ·–JBgA!):[ƣŨzM‡ÛÆuEç,UpöÝ€®DçaR·ä»às-ƒê×ÖV%kr)»Á#Vm 3-Ã…•šÜbTªÕ¹wª¹®jb§¯séqVœ±Ð()ï�»‘^]Žß ˆý¤q5}ùî(Ü��Žú�?^9Ë>3¯–,çÌOu×É^2ÓMaªË lOê—/ŽñjlpšãR]%1ÎóC÷hë“38<>cª—­©Ìjjòi0*Ö:­Èsl�‰õ&ÄùTõÆ–Þ±4_®g¯)|å /Nçtü�2 ¨€]0 _Ä‘Rß ¿}|-îØ¬ÖóNñ»Úª4|û¦Gx|ƒªV,½û\!6Lµ"L³¸g¼}˜iU˜æ‘¾±óƒCø¢È­nª¾]ŽÃ,I¬ék£ŽsUëpžè!‰»âB{ÃÝO{,­ ¶v¤ÒÒUé€n}áón–fý½>@�ò8Kº ®Ç¡M/LÚ:ßy£Ùr‰»EÍS6ãóòÀ³å‘w;Js‘{;0ÎwGç|¹å�ÑnpXM0´P”kl«lùÏgÉgÅrH`ŸB»*9^°…h²’Yxì®§R1nM‹Å5y;üæ+D?2ÜœrvÆÜØ ÆQ½¬~]x¢|táoRVÓ qŽœvI8M»¼ÿ£Íå‚/^|´¡IÐ�ët�ód²‰ìÖcí&Ø=l­ÍÞ� c°f|m¡(ÛR1o‚l¦ÛNÓçÈõ­ 2½úQ>ë’ãO_d¶cäm§ÊlõÆz³âÒn…�óëÞú$Š‹Œ� \®Æ2£,�õnÐnK�-g÷$ø7%Vef˜e­�%!tG¥“úh»ý´ñ.Uñ®^æ�7ÅàÌøD®Ô)é Ù<“�Mgü85®ŒŽ }=çy£=e�›1CôW zÞÛÔªÐÅ#Á‡à’rÌ<|P0Ç6ÁÓoÖÕØ F»oàsB÷ Ÿ&nkdž£½ KÌíÂb¥bI±³¨#"ðˆLZ'^o+«}â\³Ã¬b1û`°4פ…J ©Û¯œ´ðoR¥&£è%œÕëœaŠo+Zß7¬æ¨«TÀ–2ŽS&|$h0Q›÷+iÒî±î¤6“Çèýµgp¸*;¨ôòê‹õ'wtÝž/º»{±ÌúL¹O©HÉÙ¡S7‹ð�™D)×?4irBGA¨ÎY+ §¨6h’e[Èt'ïrî­v=ÿö> ååEã*úîcd´9L› ãetªñÓØàœ0Õ2i eß—¦–l®ëåEÁ�6S4²13l•c=³Ì+×>æ®›õ0‚%þ*Z' ˜òü¸ÈX%Ãï´ÊêƒÃã£B’(e |c�mÁ3‚q‚‚ù+·;ZÉ}‡}ÀUÛÃŒ0^«�´X–“ Þ‡‹;JÅÈÍ3µ9­\s½X1©¬³ÛWóLQ´¨=Vßwë+ÇüiĈ>´›ösëz,æ�îMÌTH£ãÍýXtfeŠ žTÓžI«¨~c=Ë× ã†Ú÷†•m,q�ᢣ1´+¯jóQ†t¹ÃÁÚãBs”|\j �ƒyT©ü"‹öúÉ÷ÁÑq޳lé%¯¸ é�Wu¹–&ëÄQ‚ý«´…CÇÜÞùà‘ŸÉ.[öê®{�zOAá­ÌÒ{ ž‘Fà è?œŸX—It޲!­'^_Dz5¶•ôŽ/ì…ÑÚé ÝQ裼çIÑIR­õAÁå¢Yf”mõÁPi~n/Ä41-öWPp­Äi¸ ¿}C»o÷Ê Z»È;6·¢4oÞ �Æ :{öìëêêú»{¢Ú¯d}zÿïù‰ ¤Ëd°"Ð6qdº�û º©�G—pÐ.vMÒ7›®Œp°ö8ß9‚Ìê&ãpàK+ºeÿ�±8Íð[ü¶×ÍӻϞ¼õwšo}LíMåÉŽ{Ÿ+÷ÔßL³åYz]ù¨„,ðAÑî‚ …Ò¬;n¿åÑiûžx¦y·»Ï;ZsÏ=÷îŠãHã„–K·æjÁõzD3X3¾Ó AëVcRѱîyšU 6ö‰Qˆ ëý(.4=Þ+fxÑH'}y¾:(ÅEŸ³kuή=ѯã|{%‰³ðµŠ*y`·-Õß»Xœû@zå› ^a¹µHÎpäGwpz¬wê«-ª­òLí 6|þõµ¦.~ÍùðÑííú©1·û+[\Ô:,Û2ã‚ .˜SWW×7¦³ ïÇq²Ôt1øˆu²q�‡žÿ®8$/Ýè§Ï1¼Fl¾VŒõußw—ªXïñX/ÆÖÆy½"w÷@Ül¸ãb½ל Ž&^{²?I-�û ØŸ5ÿy°oå³Ú¿{ŒëBØxý #M¯Îé|î»JÓ?*î6Éê§êz¤¥h�±¯%±^ŒõÚâ|‡^pÁŸ™={öçŸþš=…îIv¾>®ÇAa5¡N!.ð³)›ùȇ¶ãÞÅýël=†ê<½Â÷šD)O�JÖ«éo@U£ [�¼?w?ÍççÚyâH³_]ë!º·8É›fy©¶[ÎÈ>3IŒûÏ-e)iý®$ˆn½W¿ï—S¯²ú ïØl]+��gÅv£ûk¢/­´Dª’<'㙳Î:ki]]݃I’\={öì?d2™+0îÌ3Ï\,e�]q=Ž—~)ÍÞ&�DœkYwüz±)ŸŸËóË7˜ˆGáÒc9á_­}Jµ‡-Õ‰êí*øw<"ï¾Àí�'Cð³ƒÞoô¿L´÷OH^Y- .=¶ÓD[ìµ�½sYÕ^æ/Ù dI >P,ú¨4ßê7°Ç$Sv›l¯Å߿豧_ñ×\Vfïm|â¡%Þ?eœ¸ëVž¾ëi´wv§ÞdñÙ\Öå×¹AÆê.ùû?šf·T…àÑíÇ[ñÂöRíèÆ–~k�¸­'ñ .t„¢�)ºhöËçBhÍf³M+W®\8vìØ¾ùÍov­+WHµÚÕ ¢Ï51ç|zË1ή;Âï®?É ×Ÿì…Ã÷ô‹lÎñª]/c²à4Ñ)^« A–1dHÚ·='÷µkUßÿgnéô©×Ö¹ ßÁüÎb/m"_NÍŒöûÆÍŽ;x7É%ÇØõàÝ݉úÿü™1z³×.cÝcÔþ—×\,ùjc‹9'}ÜNqžâÃËu ØK�t›X'QòYÁi2>0~üø98zÉ’%M·ÝvÛO …¼K.¹¤Ëý¸÷AÏ� Ó=¦¹0Smßyû¯ñ1Uǹ%LÕ!ë9Á÷1Gcïôžøò~v†¯|Ò¹—ÌðQéÆ •‹/Às9WHmòm¢E&¦Zí#K�ÿËkÂeÓ…ÛOó0æ\z—7¤¢Ýz©äe“òp˜4täÊšœE§ì²bvNkê¸J™n¡NIâjÁ=yê©§vf2™c›šš.=zô \ÚÞÞ~zùÞ'¥v*¼‹Û–C$ú9*ÂT«ã½Îq¿ÒÆRåwÙÆîP“·¹èøE�â"~!'£Ýý²²2–w±­Oöã§¿åàlÖžx1—såíp[ü�j7J”lðrut—£å:×îÁHÁ~ Æ•‹VIµÔÙøoð¼;ü«;»ž}æ™g®Èår÷œtÒI“0;Æø§ò½KôÈü‡ì;ùVv+ýãßüÚ V ýƒ–"Áb1Ôõß_8Ì´*Îs’’mËÂô uÊÚé2ÊzÄ©B…Ì�¿ �Ý+ôJb¾;àKøayòôš@���“¯ºêª#êêê&åóù.óH³7Ûëø=‚=' 7­oAlP::Ö;»;íñm"Ö›ë}5.03þ¤_b›x¯lœo³¾ÕV\Ò£Êl©û±/öÃé®÷Â{kÃO©¡,.0 image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/icons/tomwer_visu.png0000644000175000017500000002107014757047403025046 0ustar00paynopayno‰PNG  IHDR^^ªÒ£nsBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î< IDATxœí�yœÕµï¿kWÕºO7MO4 43BPÐ�Pï5ÑçEs•DÇÜx3¨/šx£iobnb†›gžF4 2kc®Æ‡DƒgAƒ( s7MO§‡3TÕzTuÓÃiDm�ù¼þ}>Í©Sµk×ÚëìZ{�Ä 1ˆA bƒÄ 1ˆA bƒÄ 1ˆA â ¢K˜¥ËyU—p¡*ò÷¦©7ì¿7ïªËù"J›¹]ªñû6–3 e§¸ ÏölV�a<§VÈ\Z>úø‡c<+)~�0’‰ü ØÜ»‰ª¿æ7ÄØB–çrþ8£ÈGøÊd„]Àï?Zâ÷ã�ñ›H2Žå#qØÝ_3¹˜àžöå’"ÂÝÀáx¼4À”þÿ ½…Ä'Q¾Ÿ,¢´Ãd&�Á"Æ[2¯ß¶k°ÙIsHŠô”ߺ˜?@X€ò£¸@fâö飆 ²r:é~Ÿ£K‡!Î(ÞÈÕÏ�ˆN ã�Ëm~CŠªþšéJØÉ�PV³Œ“ú4ˆ’@8 (A8—­$rôq$i–ÑÀ/t%¥ýÒt'ðøo„•Ô2úެ>Y2ÞÁÅEÅêgA0|°RÀÚ×mÚðøpð8Úrôq p ¸¬îÊù¬|<Ò¸€Gæ4½O|²fü›ìD¸›/ã°£ßv>õ([�VàõÞ—e6þ8ž( ä2²9zÙ$�:„�ý>ë\ê�ËQfcÛûPÿøDÉøîÐ,\&ãaó¯Iõ~Ùª5DÈr‡OãÓŠÁ"Š��AñqQ:ðiÁ¡�·ií®Vêbа™4åi™M¦Çó—PL#Î 2›Ö�ßß•ñª§‘. ,@>J†Ãþ„çPÒ@)Pây·g‰td0®ž"ž‡¸¢ >` Dü˜ƒæEðó£´Š°á-|^f3oæÒñu %îŽ~O”KšùJÆ«"Ü€ð)„�ÃÒ 2†bÈâàS‚PŠOB)Â0 ’e”{J‘¯$|Hø.¾OB•‚–4±ÚfdwÔ6sZ]3ìkƒú$4¶A{&øs=ð|p}ð<ðCýÆ86ÄÈ�Â�<†T•0bêŽ�1…ycʸ€1\<Õg`>•ãâÀDZ ËxÑLÇ%‚ÁÆ`ã!€ƒÁà#X8ø`¡8@ !~æ¡Ä1äãG”à3¡¥8íQØÒ�iMAS;$;‚ÏÆ6hl‡Ú怙µÍPÛïi†Žt€PUO]#‡òÇËBRݯë"ò¨>�²„ÍÜÚ]Ôõh»‚éøL%ýrɃ¥Avþ’ž�¥Šñü`±0¾" ¢ŠQ@ãû_±]+�ÅJ¦ #­)hKCKÔµ„33dbK¤]Èx�ÎBÆ…T6<ö@?*î¾nú2|ë ’§È\^è}]kˆÓA1qöö–ÿÝÚX¤y˜‰a–Ìᑃ}¾ýÅ_0"ë¯lÆ ákÀ4x…ÝP fÜ€aÙ¿Ã m�É$˜@Üj56ãø‚E#Él:àÚÀ¹ø,ã QrøŒ„œ^»�–�¢¼à// ‰X ›cÄaH†æŸqˆ:±‚ë–´ &F6´uÓYhModK´§¡9üŒGà»g¡£Šyž"N¦—×!\Êíĸ6d~tùÌB9 ¸_æQ£‹pˆaí½-èáC-®"Á/'¡n$á?ªÁ‚w ĘR g‡Ž„Š"šO6Å/ŒãçEÐX„Œ1$QJ€¼ðÖp/Ј’Á�AI#J \›âеö†÷ù@åYà69“v­¡Ã)(ùá@N!C ô²%b”£\Lfêbîׇ,óßïú0Þ± ?y‘à/?Ì�®ÏÄ£ÁµÂ8„m#v0£v°xÞÿ"¬}#˜…½QZËÿ N�JÒ2´Û�+ñÙŠC-Yd>mº”|„[¡khë0\.shìÞ§.bq¢Ìco®™§Š°š¡´á³�féþ¦'i#ÂV„Ï8Õ¶!9¬ÝÀ²n •ð&2ýû’Þ r÷¿£1'`Z^�9x ×¶p× Ž½¨EÖ¶ð"6nÔ!k )1´ ´#¤ñI!¤Ž©mæøÓn‚—{Ùz,< ~µ€tÄæj”g>‹áy"<+³ñ´†8Il.¤UÕ¥ŒÅp=`ás ›y¡SÿÖ¤¸á|”8ÂóxüLðZÓ—2¸ á$„ Ê?ï |(˘„ð�ÐYñæóŠö¯2Ÿ¶p1=8�µ²€õ˜ñºœã“2@Š`¶mhøéÑŽ�Úði#C[?fx0Ðå\ŽògþïeÐÇ#°h!Ì;�MxœÝ�A!“ªþ3TUïàë7�è2¾ü”žoïÓ$8CΦ©›æqÝ FŸHqcãPVp >W7ö¦õÃÀ&µlDùú~‡ÂgJc{ ZöFQLÀvòx·û5­!BŠ€ BJ¦1‰€ú\�ÑUTâ2Ÿ¾"óH’|¸‹ ŸN¦·•.|‰woäÃRÊP~ÌDP,]ÄÅrÍ{/Ôœ‹5{5>½”#³ñ¤ ˜®‹‰!ŒÛÑK½Q‡ ÃØ”à �å]ß„x8ý>Ì£(ês^p*ÃoÃ+G›b,†`(1”€Ò@ØÚ÷�‚3gMußç¼w2Â0 bËÞ@�ë�1eÁ¬^ìsq6mXÜ´hˈÒÔyYk°´¦Û "ìöæ "…Ï[áñFÈ)Njñ÷¿IZ�Ñênüð¨C¹Hí(÷0œ}ý ;'îbâ˜ñ<2c<×k ñî—ÞïQ”nß×e¤ôÀ¤Šð@ûÎU‡»Éð.„7d6úòhd!if–.£açRÏ2î@˜ a°CpQž ÎãDx“4¿Î%x£R«H³Mkˆ“â`‚­Ëx�Bî�Y$u9?CYx e}Î(V56c9éØÜ+ç±®/*€#€$äÁ~»`à/ s}ÊÞÚ³ßâíŽÉû't#Þ0‰2lÚBñÓeÂëÍDiâ* 7°?~zÊ$®Ò–‘¢ á|±ó$6¿êc¡–t^F9 ¡øñ6J>_EøOöÛ 3H2Z—rm¨õ<ÞEK`, §ƒÝ]‹ò!ŒÄe%P�Ë—�ñ]#LðÍ\ŒÅfæÒÀa?Š ¼¨&f]boäˆÿ‹ÀäJ@hEX ¡OdÉ"r9­ÀUÀUáâ|Pþ¯5ZCÿÆ®ý‰î¨ ù1e+—† U„ ËPv¢<ƒá×=nʰå!èfD èýÌë)RÞ74K ‡Û×GxˆL/oc†¿`¸�ÀcùG²<Ø»»Ç2}Ñ¥8z€ßÀÊx—q@Þký„©G …Âí(ïvÊ<™M®%˧ÅÉ2—g»ß#‘$Æ·�Û€MÀ[À­¸|óÃÚ2› Qn~ŠðZØÿb|®3Ñö·½�½´±€,ÇÑÈlYÈÖÞÝñ8>³Í£�ør€™?°¢Æc`oÜÕ÷’] ¶E[èÛOq {Ü¥Šp'C°ˆÐH#£¸’úpsi‘ {F�>(d6 Zà ´ò l„IÊÈêJJQ<Χ©k’šL¿oYuîX½úÀ´�e¼aL*�µ=‡™a¨*„vü€Éº”r”¹{ðøŸÎœVcXÎ9Ø,@É#�WØÅ÷äbê”Þa„i/„^Î4ߎ\–±JdÕ�²Íè)×-xo¯å€1^«1xLØ›ÄÚ›#òh]ø´QÊ.]J9Â*„“‹Ãt ×1�\úIòB)ù9¢Lѕ̑óÉ¡/ ÐS„Ã(çt�Nfã€ëÃ61 Çaáái™MûôéXëדm\LQ}##žlá�…Õ=™¯Št�¨ÇŠ<„ÊÆÖ �Ý– W VN'�0œýƆ…pÛ‰r;6Ê¥ôÕbNÄë¥ã4lŽÀçä>gáB]J¾®ÁÆâß0ܬ"õë~DÁúõømË^hqKU¿ûRwÞ¬Šèr.gWê¢.¿“ãÛH Tַ¾uÌ�²B@BmÁ¥x´Ø@Fa€É9ž¡›µû‘Àc8BqŸóÊP œí#ü+PŽR¬Ê§�¢ð’Í| ø„C,aA×½ÁDú9ÂÕĘÒyzào“@¨ÜÝ”Û+9ª$H2BCÆ/ ÃW€ãsin’ËȲåíOÈòaõö÷B„zÈQbhê0¤vÊs�ÝdhÌž&’FxZa�ëò@×½»ñ€"ÜNœM�§nq ¬Àa›ërëðc:óqMàƒåÝ&àÛ=^ŠËJnG¹íáÑ{»›E»Ö°aÃbÙlÖRU2dˆø¾ß¥?w?0Æhkk«ç8ŽW[[ëB˜� �åE ÎèºApñY,óƒP .áÇXÄ€†0—Ú_?^ùvStñ›{£—?·%zx}«uÔ” wfU±WH0{ëT5ßs´1æsƘé"2QD*ÃYŸ‘<)‘2-"S�1ÇU"RjŒ-"ªºÇ˦Ö9²53®432™¶Ž~}OôÒ¼<ëŽ)GUœ[^^> �5;Iª²ÅWE1¼ˆROðfTŸ(·�`qÖ Eð+x›°•ªàߨk¿ƒ ¢ ŒÃq¸[æá2tèЄHfÎSï8§ìj lŽüˆsüØôªÔ„ÚÆèË-)­wg2ô¬oRÕ& ‘@¼Ø@�lïŒÕz"R—ÉdþbYÖXcÌɶmOŸX–Ý:c|ëXÛ6fó¾(/lË“§¶$**‡dþ+/ωWTT¬=ÿgmµ-7'¿ƒÅs)ŸøŽ&~7ñë¡úé°—U9:ë±”�ó,§ ¤ñ#ˆ¹ú”±ÝM¹Uɸˆ›ŒË ìÛŸšw ;�Ù/K#•••¶1æÈç·Ù³†xäE| l£”æ»2,emØl=šLaŒä«j§W0£ªÏd³Ù‡\×} (‹ÅbóDd:P,�€ˆ‹ÈéÀ3õõõˆÇãë‰ÄÌÝ-ñóî}Õ¶N�”äÔC’12ÅÍkK©mqÊ�ï;Žót"¯)¿:vßÞ½{ïî=F9�]ZÃ×wÕQ¹æµÀVAu ¿ÄâaR=sr†ñexÄv6æ5ñ0íχf¾ÞÃ÷­Ð•î\ŽÒ2üj0£©ÍdžÁS_š¡<‘ű”¬'-ÿ~Jú¥+ï�œ ¨jƒ1&ªª ß÷ïèèøcssó_2™Ì®‚‚‚immmÿ]\\ü ˲f@W€]lÛ>¼¤¤äÙ�;w>êyéÆK>k�^³©à”åëŠÙTßÎÙÓš¸æä�üö¹òæ×öÄ,Û¶¿`YÖ!Æd«ŠŠŠnmlljîí––Ùìšé¶(Ë샾٠Ãx�!€ÓК;};ÌÃô3M½}Ôº˜˜Ÿá»™ sÿJ¬õÐî__ßm¨Oòlq^v|ÕPwDÌñeäPŸE~Gkš;^¦^U-U}2“ɼâyžÄãñiªZoÛöË™Lf3�M&“/RZZz�·1ÆþàDçâ»·¥¥ýÙ¬xî1�'<´±0ú»qÛ-ΚÖäO.kþó†ŽD3SD& +–k¯››ÚÆjVq^Èþ00.!áú8ÉTnË!bCÄF}?G"h„ií)®ßf�ö<™zâ„ôÔl6ûÆ–½é§_Ü¢?=dxöÙi£¼låPw~Œ›†�â—GßNˆ:â[¾ï6¹®»Õ÷ýƘёH¤€@‹ñ�öòòòÃ�1ô’±@KaÄÏêÍØ@ãª';–D²5Ç�mËL(Ëðfm”ß3ºuÏÔái3ºÄÍ?r”ûíÕá jÆç»v{κ °-° ø>i]„C«Kµr±|Å´¥…¢¸Çð!~k*%oe³Ù�ËŸæÅ£Çë—‹E.�¡Ñe,¼ñá–³·ÖÛÅŽÅ[ë�µ¯ï±Ê1¦JU[GŽY¬ª�@ܲ¬³r[bªª"â�qhë¡_›Ñò? ÅÒeÜüàèï:×L¨Ò›;˜—rÍéÛ�"Åþ¼ãtÜwܘfWŒ�m”<Ç+"ˆÓnЃôð÷ðÙ÷äÉåu?‹ÉöSln°mÔJ‰sB±®àj™Ã&ŠÙ`×±zL‰7?ãêο¾¹ß÷ý–ŽŽŽ—ÝüA¨ž-ç à'ÓGu”lo(àµÝ±2f‰1FÁˆÈ™–e¡ªû€¸1æ0 @$p�‹ˆ[Q�i8}jêÈŠ!]~œ¹…ëªÛÏ/ûVé[ñ¸³Ý¶AD‘ã|+²­¡Ýzþœ£ÚÇZ±xDŸÅ Taý-£hàGº˜ï˃« (ÊøŠäÒh û �ñO‡[�+äLÚµšoNçÿ�–_­�MuSZRR2"�NgZ[[蔥‹ˆ£œ”L©Èðúî4o×Gy·Áq€Ðª¡LDÊú¡3cï9G& ެÊHq~ÁpÖò¿åŸ‹Å&‹È‚t‘DЭ™xçs%·^÷¿¶/Ïx �x<$sÂB3› i TJøþÁ0l Ÿµ ¾Ó75Š2.âû4¬ðùÈþŠìÐ=P0©ÊÄ' ×6Fïì‰lÜ-yжí¦ÚÚÚ "(eŒ.QÎ9ª•DÔgéóEÔµÚnÆÅtÎìžP2ªl+ÍËþ혪öYÑà·ôü .å©y!žeY‡…¾ïo°,3 U+b“NgIÉ<þzËWIì-§½«kû(Íà¢gÝ�”NÍg€dnî õ�a¼âƒo÷Ãød ’)Œ¯#ü%—ûsµýÑ9ÉÏF,ùßõm¶ýìæØË�¼›Ô‘ö7———?Ͱº7¨ßï“9T9sZ;e —[Ÿ,~kS]t8½²¹ ¢¾”dw¿±Ë,¯ß=}´;=/d‚Õ¶kÞŒrÿ+Côµ=ñQõ_H§ÓKÞ–=rŒ3*ã™Òq%©ü‡_æµíÛáØÃIO¿ ­îì<ËCXÌÃ`pù Àä æ¢Üü øj®q ã…´eð¢ý$T×µ@]32¢ˆJ|Ötú¶{C—S˜J»3w5›Ø–zå_¦¹Sž{7ò`:kM¶mû�‘—ŒØ{Ò„ö-wÌk|+?Ê$(+PÿÓc3/þô‘ÖEíí^zÖ‘î—†êYÁ2JYÂchŽwçãΆÆgÙK„ŽQ%�ê˜ËmðÈËpÅç‰!œ< ¡Ws'£|ÃT²Jf²EÿÀÅÔaYÒºuA›êbÆìnmÿZm‹ÄÛè¬øÑ#ù[DìRcL¡eYq­D]·ÕÙ<®Ô}vL©w¼%D}mMË®·9�ú¾_F¡Z²Ùì«¡ÆdŠb1·ùöT<"\ƒ`~Î&^f_ÝÓÈȆ ó¯FŸº“K£†kÞÒe|EæåŒ †ñÛØÍj¯bœmÈY¾q¤20$�i]'"‚òc`:ʹlã/ÀN93Ô. «úÒü`xç /R¦ŽÈ?üŠuͳ›­­a/Ýß|¿øÓËþ£W�–™1lˆNɸҲi£õØ“¯³Ò�‰GÒÚÚú.a†ñžß¤ ñù5Â9a€£Œ‘Ì‘¹4T”tn»x0Š Ë` ü�/Õ¸ºœ?Ž+ç¸c'Àš�}ÛT•@4=Ò÷ZQõRñi!žã7K‘‡0ªó«c3öÏWtl•…ì�®-N"Ì¥V$J¬Î›µ‹sñ¿ ®•]E.yl¦]ªñÉ’‡ÅÈ®\`a†|ØŸ?)‚ê2î¦ob}¸ À�KïÈr¿6wRÈúNåÁ7þDhÂçZƒ¥Õf“®F¸ÃBè™( À(Pƒ°‚[y”L·]Ê –÷²‚ó»ï¸VoDYÝ«xm,§ãqÂÝáfŸ�¤‘`{­TøŒµds,ŒQ–âs6Â¥2'°PU‘uY‰Û(Ha%'âsÛŽ&/ZƒlÜ<`îgáóÓhßÓÈŒ)çn”obØÈVÌ®vánM§ã!(�u¥Z,ã1èÊüz—Óe![u9…(?!¨m}Ã¥2‡F½……< Þó s9\ ÷)8 ÅåáþvìèCÛ ¾ˆÇ‰xü8| #âì㉹†¾é'tg�,áœê/2«µƒb(ŒóNkšÅWÞÍŸÿç›LÂãë(/²›‡!÷ê¯5X¤�…ÐÈ.¹¬‡®Ü‰î³Ù ¿+3.D±ªP–P†EºÇ˜» à {W"’þšbJ±ØÓßÖ·Z�Áç+§`ñgè›3ß¼Jæñ¦ÌåF+Æ C"œPçD¢œ^p1÷Üû×ëâÜõ­R��á6„›ñr”�Ùö‡á«º§Û) P™Mƒ®ázÖâ¨Tà ÀD”“�?õiã°š4k±±±¨í[�b¸áh×íþP];ÿ‡«0ø´ç®'\ŸˆP„0—2úË‹ßÄ}|Žû»‰LåcMh:8x$,…ß;߸ÎÀ�}”§€ía‹îûJ �q,lD¥ºov™\À>]Â%cvʼýmB‘² PUD/ Œí^]lCxF}ÊÖ =Š˜{Ô8…“§÷zOÆœ»ð‚Yß¹è„ûËЕoÒ=Ê@à»!�vÛëK[k°É2 Ÿ‰Vtjí7”æEø2Â>†°ºËv±n޽—òû\vWW÷`dgáAg½So¦we3ˆˆ�sÆ÷&2aTi?’ºœB Æ\’Ý5«ÛýY\ŽF¹¥Ÿ*à’ ,â(GcxMæteéÚy÷©˜Í¥Àµ(š¨8�胩IDATþؽ�£ƒ7c'ÀoRæbþ´‹úÕ«qÙ?‰ú›íŸ(QÓ›ñô|¯¤�",åöûCzΞ Ü>Š`ȵ‰Äjò \²gàóªÞÌ1òuÒ?tPc($Њl¤«Ô¾/Ñ÷Rä'¹N +ß�ÕìÇÑŸºyPq·Œ?0QYŠ1‡ wÖÈ툊ñ image/svg+xml ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9011006 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/other/0000755000175000017500000000000015153325403021751 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/other/PythonScriptOW.py0000644000175000017500000007010415153325210025235 0ustar00paynopayno"""This is almost the original orange3 PythonScript widget except that the icon change (to difference them) and here the input is not a Table but a TomwerScanBase (use silx.gui.qt instead of AnyQt too)""" import code import itertools import keyword import os import sys import unicodedata from unittest.mock import patch from orangewidget import gui, widget from orangewidget.settings import Setting, SettingsHandler from orangewidget.utils import itemmodels from orangewidget.widget import Input, Output, OWBaseWidget from silx.gui import qt from tomoscan.series import Series import tomwer.tasks.script.python from tomwer.core.cluster.cluster import SlurmClusterConfiguration from tomwer.core.futureobject import FutureTomwerObject from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.volume.volumebase import TomwerVolumeBase from tomwer.core.tomwer_object import TomwerObject __all__ = ["OWPythonScript"] def text_format(foreground=qt.Qt.black, weight=qt.QFont.Normal): fmt = qt.QTextCharFormat() fmt.setForeground(qt.QBrush(foreground)) fmt.setFontWeight(weight) return fmt class PythonSyntaxHighlighter(qt.QSyntaxHighlighter): def __init__(self, parent=None): self.keywordFormat = text_format(qt.Qt.blue, qt.QFont.Bold) self.stringFormat = text_format(qt.Qt.darkGreen) self.defFormat = text_format(qt.Qt.black, qt.QFont.Bold) self.commentFormat = text_format(qt.Qt.lightGray) self.decoratorFormat = text_format(qt.Qt.darkGray) self.keywords = list(keyword.kwlist) self.rules = [ (qt.QRegularExpression(r"\b%s\b" % kwd), self.keywordFormat) for kwd in self.keywords ] + [ ( qt.QRegularExpression(r"\bdef\s+([A-Za-z_]+[A-Za-z0-9_]+)\s*\("), self.defFormat, ), ( qt.QRegularExpression(r"\bclass\s+([A-Za-z_]+[A-Za-z0-9_]+)\s*\("), self.defFormat, ), (qt.QRegularExpression(r"'.*'"), self.stringFormat), (qt.QRegularExpression(r'".*"'), self.stringFormat), (qt.QRegularExpression(r"#.*"), self.commentFormat), (qt.QRegularExpression(r"@[A-Za-z_]+[A-Za-z0-9_]+"), self.decoratorFormat), ] self.multilineStart = qt.QRegularExpression(r"(''')|" + r'(""")') self.multilineEnd = qt.QRegularExpression(r"(''')|" + r'(""")') super().__init__(parent) def highlightBlock(self, text): for pattern, format in self.rules: exp = qt.QRegularExpression(pattern) index = exp.match(text).capturedStart() while index >= 0: match = exp.match(text) length = match.capturedLength() if exp.captureCount() > 0: nth = 1 else: nth = 0 capture_text = exp.match(text).capturedTexts()[nth] self.setFormat(match.capturedStart(nth=nth), len(capture_text), format) index = exp.match(text, index + length).capturedStart() # Multi line strings start = self.multilineStart end = self.multilineEnd self.setCurrentBlockState(0) startIndex, skip = 0, 0 if self.previousBlockState() != 1: startIndex, skip = start.match(text).capturedStart(), 3 while startIndex >= 0: endIndex = end.match(text).capturedStart(startIndex + skip) if endIndex == -1: self.setCurrentBlockState(1) commentLen = len(text) - startIndex else: commentLen = endIndex - startIndex + 3 self.setFormat(startIndex, commentLen, self.stringFormat) startIndex, skip = ( start.match(text).capturedStart(startIndex + commentLen + 3), 3, ) class PythonScriptEditor(qt.QPlainTextEdit): INDENT = 4 def __init__(self, widget): super().__init__() self.widget = widget def lastLine(self): text = str(self.toPlainText()) pos = self.textCursor().position() index = text.rfind("\n", 0, pos) text = text[index:pos].lstrip("\n") return text def keyPressEvent(self, event): if event.key() == qt.Qt.Key_Return: if event.modifiers() & ( qt.Qt.ShiftModifier | qt.Qt.ControlModifier | qt.Qt.MetaModifier ): self.widget.commit() return text = self.lastLine() indent = len(text) - len(text.lstrip()) if text.strip() == "pass" or text.strip().startswith("return "): indent = max(0, indent - self.INDENT) elif text.strip().endswith(":"): indent += self.INDENT super().keyPressEvent(event) self.insertPlainText(" " * indent) elif event.key() == qt.Qt.Key_Tab: self.insertPlainText(" " * self.INDENT) elif event.key() == qt.Qt.Key_Backspace: text = self.lastLine() if text and not text.strip(): cursor = self.textCursor() for _ in range(min(self.INDENT, len(text))): cursor.deletePreviousChar() else: super().keyPressEvent(event) else: super().keyPressEvent(event) class PythonConsole(qt.QPlainTextEdit, code.InteractiveConsole): def __init__(self, locals=None, parent=None): qt.QPlainTextEdit.__init__(self, parent) code.InteractiveConsole.__init__(self, locals) self.history, self.historyInd = [""], 0 self.loop = self.interact() next(self.loop) def setLocals(self, locals): self.locals = locals def updateLocals(self, locals): self.locals.update(locals) def interact(self, banner=None): try: sys.ps1 except AttributeError: sys.ps1 = ">>> " try: sys.ps2 except AttributeError: sys.ps2 = "... " cprt = ( 'Type "help", "copyright", "credits" or "license" ' "for more information." ) if banner is None: self.write( "Python %s on %s\n%s\n(%s)\n" % (sys.version, sys.platform, cprt, self.__class__.__name__) ) else: self.write("%s\n" % str(banner)) more = 0 while 1: try: if more: prompt = sys.ps2 else: prompt = sys.ps1 self.new_prompt(prompt) yield try: line = self.raw_input(prompt) except EOFError: self.write("\n") break else: more = self.push(line) except KeyboardInterrupt: self.write("\nKeyboardInterrupt\n") self.resetbuffer() more = 0 def raw_input(self, prompt): input = str(self.document().lastBlock().previous().text()) return input[len(prompt) :] def new_prompt(self, prompt): self.write(prompt) self.newPromptPos = self.textCursor().position() self.repaint() def write(self, data): cursor = qt.QTextCursor(self.document()) cursor.movePosition(qt.QTextCursor.End, qt.QTextCursor.MoveAnchor) cursor.insertText(data) self.setTextCursor(cursor) self.ensureCursorVisible() def writelines(self, lines): for line in lines: self.write(line) def flush(self): pass def push(self, line): if self.history[0] != line: self.history.insert(0, line) self.historyInd = 0 # prevent console errors to trigger error reporting & patch stdout, stderr with ( patch("sys.excepthook", sys.__excepthook__), patch("sys.stdout", self), patch("sys.stderr", self), ): return code.InteractiveConsole.push(self, line) def setLine(self, line): cursor = qt.QTextCursor(self.document()) cursor.movePosition(qt.QTextCursor.End) cursor.setPosition(self.newPromptPos, qt.QTextCursor.KeepAnchor) cursor.removeSelectedText() cursor.insertText(line) self.setTextCursor(cursor) def keyPressEvent(self, event): if event.key() == qt.Qt.Key_Return: self.write("\n") next(self.loop) elif event.key() == qt.Qt.Key_Up: self.historyUp() elif event.key() == qt.Qt.Key_Down: self.historyDown() elif event.key() == qt.Qt.Key_Tab: self.complete() elif event.key() in [qt.Qt.Key_Left, qt.Qt.Key_Backspace]: if self.textCursor().position() > self.newPromptPos: qt.QPlainTextEdit.keyPressEvent(self, event) else: qt.QPlainTextEdit.keyPressEvent(self, event) def historyUp(self): self.setLine(self.history[self.historyInd]) self.historyInd = min(self.historyInd + 1, len(self.history) - 1) def historyDown(self): self.setLine(self.history[self.historyInd]) self.historyInd = max(self.historyInd - 1, 0) def complete(self): pass def _moveCursorToInputLine(self): """ Move the cursor to the input line if not already there. If the cursor if already in the input line (at position greater or equal to `newPromptPos`) it is left unchanged, otherwise it is moved at the end. """ cursor = self.textCursor() pos = cursor.position() if pos < self.newPromptPos: cursor.movePosition(qt.QTextCursor.End) self.setTextCursor(cursor) def pasteCode(self, source): """ Paste source code into the console. """ self._moveCursorToInputLine() for line in interleave(source.splitlines(), itertools.repeat("\n")): if line != "\n": self.insertPlainText(line) else: self.write("\n") next(self.loop) def insertFromMimeData(self, source): """ Reimplemented from QPlainTextEdit.insertFromMimeData. """ if source.hasText(): self.pasteCode(str(source.text())) return def interleave(seq1, seq2): """ Interleave elements of `seq2` between consecutive elements of `seq1`. >>> list(interleave([1, 3, 5], [2, 4])) [1, 2, 3, 4, 5] """ iterator1, iterator2 = iter(seq1), iter(seq2) leading = next(iterator1) for element in iterator1: yield leading yield next(iterator2) leading = element yield leading class Script(object): Modified = 1 MissingFromFilesystem = 2 def __init__(self, name, script, flags=0, filename=None): self.name = name self.script = script self.flags = flags self.filename = filename class ScriptItemDelegate(qt.QStyledItemDelegate): def __init__(self, parent): super().__init__(parent) def displayText(self, script, locale): if script.flags & Script.Modified: return "*" + script.name else: return script.name def paint(self, painter, option, index): script = index.data(qt.Qt.DisplayRole) if script.flags & Script.Modified: option = qt.QStyleOptionViewItem(option) option.palette.setColor(qt.QPalette.Text, qt.QColor(qt.Qt.red)) option.palette.setColor(qt.QPalette.Highlight, qt.QColor(qt.Qt.darkRed)) super().paint(painter, option, index) def createEditor(self, parent, option, index): return qt.QLineEdit(parent) def setEditorData(self, editor, index): script = index.data(qt.Qt.DisplayRole) editor.setText(script.name) def setModelData(self, editor, model, index): model[index.row()].name = str(editor.text()) def select_row(view, row): """ Select a `row` in an item view """ selmodel = view.selectionModel() selmodel.select(view.model().index(row, 0), qt.QItemSelectionModel.ClearAndSelect) class PrepareSavingSettingsHandler(SettingsHandler): """Calls storeSpecificSettings, which is currently not called from non-context handlers.""" def pack_data(self, widget): """ Pack the settings for the given widget. This method is used when saving schema, so that when the schema is reloaded the widget is initialized with its proper data and not the class-based defaults. See :obj:`SettingsHandler.initialize` for detailed explanation of its use. Inherited classes add other data, in particular widget-specific local contexts. :param OWBaseWidget widget: """ widget.storeSpecificSettings() return super().pack_data(widget) class OWPythonScript(widget.OWBaseWidget, openclass=True): name = "Python Script" description = "Write a Python script and run it on input data or models." icon = "icons/PythonScript.svg" priority = 3150 keywords = ["file", "program"] class Inputs: tomo_obj = Input( "tomo_obj", TomwerObject, replaces=["in_tomo_obj"], default=True, multiple=True, ) tomo_objs = Input( "tomo_objs", TomwerObject, replaces=["in_tomo_objs"], default=True, multiple=True, ) data = Input( "data", TomwerScanBase, replaces=["in_data"], default=True, multiple=True ) volume = Input( "volume", TomwerVolumeBase, replaces=["in_volume"], default=True, multiple=True, ) future_tomo_obj = Input( "future_tomo_obj", FutureTomwerObject, replaces=["in_future_tomo_obj"], default=True, multiple=True, ) cluster_config = Input( "cluster_config", SlurmClusterConfiguration, replaces=["in_cluster_config"], default=True, multiple=True, ) object = Input( "Object", object, replaces=["in_object"], default=False, multiple=True, auto_summary=False, ) configuration = Input( "configuration", TomwerScanBase, replaces=["in_configuration"], default=True, multiple=True, ) series = Input( "series", Series, replaces=["in_series"], default=True, multiple=True, ) class Outputs: data = Output("data", TomwerScanBase, replaces=["out_data"]) tomo_obj = Output("tomo_obj", TomwerObject, replaces=["out_tomo_obj"]) tomo_objs = Output("tomo_objs", tuple, replaces=["out_tomo_objs"]) volume = Output("volume", TomwerVolumeBase, replaces=["out_volume"]) object = Output("Object", object, replaces=["out_object"], auto_summary=False) configuration = Output("configuration", dict, replaces=["out_configuration"]) future_tomo_obj = Output( "future_tomo_obj", FutureTomwerObject, replaces=["out_future_tomo_obj"] ) cluster_config = Output( "cluster_config", SlurmClusterConfiguration, replaces=["out_cluster_config"], ) series = Output("series", dict, replaces=["out_series"]) signal_names = ( "data", "volume", "future_tomo_obj", "object", "configuration", "cluster_config", "series", "tomo_obj", "tomo_objs", ) settingsHandler = PrepareSavingSettingsHandler() libraryListSource = Setting([Script("Hello world", "print('Hello world')\n")]) currentScriptIndex = Setting(0) scriptText = Setting(None, schema_only=True) splitterState = Setting(None) ewokstaskclass = tomwer.tasks.script.python.PythonScript class Error(OWBaseWidget.Error): pass def __init__(self): super().__init__() for name in self.signal_names: setattr(self, name, {}) for s in self.libraryListSource: # pylint: disable=E1133 s.flags = 0 self._cachedDocuments = {} self.infoBox = gui.vBox(self.controlArea, "Info") gui.label( self.infoBox, self, "

Execute python script.

Input variables:

  • " + "
  • ".join(map("in_{0}, in_{0}s".format, self.signal_names)) + "

Output variables:

  • " + "
  • ".join(map("out_{0}".format, self.signal_names)) + "

", ) self.libraryList = itemmodels.PyListModel( [], self, flags=qt.Qt.ItemIsSelectable | qt.Qt.ItemIsEnabled | qt.Qt.ItemIsEditable, ) self.libraryList.wrap(self.libraryListSource) self.controlBox = gui.vBox(self.controlArea, "Library") self.controlBox.layout().setSpacing(1) self.libraryView = qt.QListView( editTriggers=qt.QListView.DoubleClicked | qt.QListView.EditKeyPressed, sizePolicy=qt.QSizePolicy(qt.QSizePolicy.Ignored, qt.QSizePolicy.Preferred), ) self.libraryView.setItemDelegate(ScriptItemDelegate(self)) self.libraryView.setModel(self.libraryList) self.libraryView.selectionModel().selectionChanged.connect( self.onSelectedScriptChanged ) self.controlBox.layout().addWidget(self.libraryView) w = itemmodels.ModelActionsWidget() self.addNewScriptAction = action = qt.QAction("+", self) action.setToolTip("Add a new script to the library") action.triggered.connect(self.onAddScript) w.addAction(action) action = qt.QAction(unicodedata.lookup("MINUS SIGN"), self) action.setToolTip("Remove script from library") action.triggered.connect(self.onRemoveScript) w.addAction(action) action = qt.QAction("Update", self) action.setToolTip("Save changes in the editor to library") action.setShortcut(qt.QKeySequence(qt.QKeySequence.Save)) action.triggered.connect(self.commitChangesToLibrary) w.addAction(action) action = qt.QAction("More", self, toolTip="More actions") new_from_file = qt.QAction("Import Script from File", self) save_to_file = qt.QAction("Save Selected Script to File", self) restore_saved = qt.QAction("Undo Changes to Selected Script", self) save_to_file.setShortcut(qt.QKeySequence(qt.QKeySequence.SaveAs)) new_from_file.triggered.connect(self.onAddScriptFromFile) save_to_file.triggered.connect(self.saveScript) restore_saved.triggered.connect(self.restoreSaved) menu = qt.QMenu(w) menu.addAction(new_from_file) menu.addAction(save_to_file) menu.addAction(restore_saved) action.setMenu(menu) button = w.addAction(action) button.setPopupMode(qt.QToolButton.InstantPopup) w.layout().setSpacing(1) self.controlBox.layout().addWidget(w) self.execute_button = gui.button( self.controlArea, self, "Run", callback=self.commit ) self.splitCanvas = qt.QSplitter(qt.Qt.Vertical, self.mainArea) self.mainArea.layout().addWidget(self.splitCanvas) self.defaultFont = defaultFont = ( "Monaco" if sys.platform == "darwin" else "Courier" ) self.textBox = gui.vBox(self, "Python Script") self.splitCanvas.addWidget(self.textBox) self.text = PythonScriptEditor(self) self.textBox.layout().addWidget(self.text) self.textBox.setAlignment(qt.Qt.AlignVCenter) self.text.setTabStopWidth(4) self.text.modificationChanged[bool].connect(self.onModificationChanged) self.saveAction = action = qt.QAction("&Save", self.text) action.setToolTip("Save script to file") action.setShortcut(qt.QKeySequence(qt.QKeySequence.Save)) action.setShortcutContext(qt.Qt.WidgetWithChildrenShortcut) action.triggered.connect(self.saveScript) self.consoleBox = gui.vBox(self, "Console") self.splitCanvas.addWidget(self.consoleBox) self.console = PythonConsole({}, self) self.consoleBox.layout().addWidget(self.console) self.console.document().setDefaultFont(qt.QFont(defaultFont)) self.consoleBox.setAlignment(qt.Qt.AlignBottom) self.console.setTabStopWidth(4) select_row(self.libraryView, self.currentScriptIndex) self.restoreScriptText() self.splitCanvas.setSizes([2, 1]) if self.splitterState is not None: self.splitCanvas.restoreState(qt.QByteArray(self.splitterState)) self.splitCanvas.splitterMoved[int, int].connect(self.onSpliterMoved) self.controlArea.layout().addStretch(1) self.resize(800, 600) def storeSpecificSettings(self): self.saveScriptText() def restoreScriptText(self): if self.scriptText is not None: current = self.text.toPlainText() # do not mark scripts as modified if self.scriptText != current: self.text.document().setPlainText(self.scriptText) def saveScriptText(self): self.scriptText = self.text.toPlainText() def handle_input(self, obj, id, signal): id = id[0] dic = getattr(self, signal) if obj is None: if id in dic.keys(): del dic[id] else: dic[id] = obj @Inputs.data # noqa F811 def set_data(self, data, id): self.handle_input(data, id, "data") @Inputs.volume # noqa F811 def set_volume(self, volume, id): self.handle_input(volume, id, "volume") @Inputs.object # noqa F811 def set_object(self, data, id): # noqa F811 self.handle_input(data, id, "object") @Inputs.configuration # noqa F811 def set_configuration(self, data, id): self.handle_input(data, id, "configuration") @Inputs.future_tomo_obj # noqa F811 def set_future_tomo_object(self, data, id): # noqa F811 pylint: disable=E0102 self.handle_input(data, id, "future_tomo_obj") @Inputs.cluster_config # noqa F811 def set_cluster_config(self, data, id): # noqa F811 pylint: disable=E0102 self.handle_input(data, id, "cluster_config") @Inputs.series # noqa F811 def set_series(self, data, id): self.handle_input(data, id, "series") @Inputs.tomo_obj # noqa F811 def set_tomo_obj(self, tomo_obj, id): self.handle_input(tomo_obj, id, "tomo_obj") @Inputs.tomo_objs # noqa F811 def set_tomo_objs(self, tomo_objs, id): self.handle_input(tomo_objs, id, "tomo_objs") def handleNewSignals(self): self.commit() def selectedScriptIndex(self): rows = self.libraryView.selectionModel().selectedRows() if rows: return [i.row() for i in rows][0] else: return None def setSelectedScript(self, index): select_row(self.libraryView, index) def onAddScript(self, *args): self.libraryList.append(Script("New script", self.text.toPlainText(), 0)) self.setSelectedScript(len(self.libraryList) - 1) def onAddScriptFromFile(self, *args): # pragma: no cover filename, _ = qt.QFileDialog.getOpenFileName( self, "Open Python Script", os.path.expanduser("~/"), "Python files (*.py)\nAll files(*.*)", ) if filename: name = os.path.basename(filename) # TODO: use `tokenize.detect_encoding` with open(filename, encoding="utf-8") as f: contents = f.read() self.libraryList.append(Script(name, contents, 0, filename)) self.setSelectedScript(len(self.libraryList) - 1) def onRemoveScript(self, *args): index = self.selectedScriptIndex() if index is not None: del self.libraryList[index] select_row(self.libraryView, max(index - 1, 0)) def onSaveScriptToFile(self, *args): index = self.selectedScriptIndex() if index is not None: self.saveScript() def onSelectedScriptChanged(self, selected, deselected): index = [i.row() for i in selected.indexes()] if index: current = index[0] if current >= len(self.libraryList): self.addNewScriptAction.trigger() return self.text.setDocument(self.documentForScript(current)) self.currentScriptIndex = current def documentForScript(self, script=0): if type(script) is not Script: script = self.libraryList[script] if script not in self._cachedDocuments: doc = qt.QTextDocument(self) doc.setDocumentLayout(qt.QPlainTextDocumentLayout(doc)) doc.setPlainText(script.script) doc.setDefaultFont(qt.QFont(self.defaultFont)) doc.highlighter = PythonSyntaxHighlighter(doc) doc.modificationChanged[bool].connect(self.onModificationChanged) doc.setModified(False) self._cachedDocuments[script] = doc return self._cachedDocuments[script] def commitChangesToLibrary(self, *args): index = self.selectedScriptIndex() if index is not None: self.libraryList[index].script = self.text.toPlainText() self.text.document().setModified(False) self.libraryList.emitDataChanged(index) def onModificationChanged(self, modified): index = self.selectedScriptIndex() if index is not None: self.libraryList[index].flags = Script.Modified if modified else 0 self.libraryList.emitDataChanged(index) def onSpliterMoved(self, pos, ind): self.splitterState = bytes(self.splitCanvas.saveState()) def restoreSaved(self): index = self.selectedScriptIndex() if index is not None: self.text.document().setPlainText(self.libraryList[index].script) self.text.document().setModified(False) def saveScript(self): # pragma: no cover index = self.selectedScriptIndex() if index is not None: script = self.libraryList[index] filename = script.filename else: filename = os.path.expanduser("~/") filename, _ = qt.QFileDialog.getSaveFileName( self, "Save Python Script", filename, "Python files (*.py)\nAll files(*.*)" ) if filename: fn = "" head, tail = os.path.splitext(filename) if not tail: fn = head + ".py" else: fn = filename f = open(fn, "w") f.write(self.text.toPlainText()) f.close() def initial_locals_state(self): d = {} for name in self.signal_names: value = getattr(self, name) all_values = list(value.values()) one_value = all_values[0] if len(all_values) == 1 else None d["in_" + name + "s"] = all_values d["in_" + name] = one_value return d def commit(self): self.Error.clear() self._script = str(self.text.toPlainText()) lcls = self.initial_locals_state() lcls["_script"] = str(self.text.toPlainText()) self.console.updateLocals(lcls) self.console.write("\nRunning script:\n") self.console.push("exec(_script)") self.console.new_prompt(sys.ps1) for signal in self.signal_names: out_var = self.console.locals.get("out_" + signal) signal_type = getattr(self.Outputs, signal).type if not isinstance(out_var, signal_type) and out_var is not None: self.Error.add_message( signal, f"'{signal}' has to be an instance of '{signal_type.__name__}'", ) getattr(self.Error, signal)() out_var = None getattr(self.Outputs, signal).send(out_var) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/other/TomoObjsHub.py0000644000175000017500000000156614757047403024540 0ustar00paynopaynofrom orangewidget import widget from tomwer.core.tomwer_object import TomwerObject from orangewidget.widget import Input, Output class TomoObjsHubOW(widget.OWBaseWidget, openclass=True): name = "Tomo objs hub" description = "takes a list of tomo_obj in entry and trigger a tomo_obj scalar for each element in downstream" icon = "icons/hub.svg" priority = 4000 keywords = ["hub", "tomo-obj", "tomobj"] want_basic_layout = False want_control_area = False want_main_area = False class Inputs: tomo_objs = Input("tomo_objs", tuple, default=True, multiple=True) class Outputs: tomo_objs = Output("tomo_obj", TomwerObject) @Inputs.tomo_objs def execute(self, tomo_objs, *args, **kwargs): if tomo_objs is None: return for tomo_obj in tomo_objs: self.Outputs.tomo_objs.send(tomo_obj) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/other/__init__.py0000644000175000017500000000045314764622416024077 0ustar00paynopayno""" (Ewoks)Orange Widgets for tomography not matching any other category """ NAME = "other" ID = "orangecontrib.tomwer.widgets.other" DESCRIPTION = "some utils widgets" LONG_DESCRIPTION = "some utils widgets" ICON = "../../widgets/icons/tomwer_other.png" BACKGROUND = "#C0CCFF" PRIORITY = 20 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9011006 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/other/icons/0000755000175000017500000000000015153325403023064 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/other/icons/PythonScript.svg0000644000175000017500000001257514757047403026277 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/other/icons/hub.png0000644000175000017500000000214214757047403024361 0ustar00paynopayno‰PNG  IHDR00Wù‡ pHYsÃÃÇo¨dtEXtSoftwarewww.inkscape.org›î<ïIDATh�ÕÚ]ˆUUðßuÌJíE„"†p")*R¢ • ê!*B ª'CˆŒ ƒ è)(¨ „¢‡žì¡ ˆ¢ú„¦¯‡Ê¢ ICS3uRWûwfî=÷œ;çzñwß}Öÿ¿?ÖZ{Ý›"™Œ¡A˜-†«~1¥´Ëqã1Ñ7V5�ºm¡”Ò•xçálLbÛ°)"Ž÷›d)"¢cÃ*ìB´ixK1 ƒjeä‡ðcò§Ú߸k�ÊñJ,é²€çàÁ¾1” ¸Dw°¸!.=¡LÀ!T9 'âÒÊ|„½ÞñUC\zBG±K1Y2~7išT-tq£#øÿ˜é�N`ã =PDT dsp/îùñ¯ñ=Ö⺈8Ñ—Ù­€®:Liïa[D<Ó(«:=‚ÿ�E� À Ø3ÍØv¬¨�rüU�|ëJ<[aRÎÇH%¸ û:üÃ%†ÖÉ—ýªN]Içw°®à´C¥¹PJés\Õá¨Lb}D¼Ú®3¥ôní0¶ãq9§ZÐòùæÏ+ òG±DÄ»Sl·ø£%ÀÅsà@KßÝXZS@/8 ÞÛ™Zú·Ëàø¢xNXÔÒw:K+ÃZn�­v`¬Ã ½x8"¾i×™RºH±Ok9�qù®û§õÄX#OØnl‰ˆ­SÞÒr`Æð›™‡mRN™ËÛZõñ]jJr@<‚çpV7zµ|ÇýS®ùüŠ­J<ïôuVk ±ÊÜ pÆÿÙãŒð&i/[/Ù IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/other/icons/hub.svg0000644000175000017500000000722714757047403024405 0ustar00paynopayno ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9011006 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/other/tests/0000755000175000017500000000000015153325403023113 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/other/tests/__init__.py0000644000175000017500000000000014757047403025224 0ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9011006 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/0000755000175000017500000000000015153325403023711 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/AxisOW.py0000644000175000017500000004714215153325210025441 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import copy import functools import logging from orangewidget import gui from orangewidget.settings import Setting from orangewidget.widget import Input, Output from processview.core import helpers as pv_helpers from processview.core.manager import DatasetState from processview.gui.processmanager import ProcessManager from silx.gui import qt import tomwer.core.process.reconstruction.axis from orangecontrib.tomwer.orange.managedprocess import SuperviseOW from orangecontrib.tomwer.orange.settings import CallbackSettingsHandler from tomwer.core import settings from tomwer.core.utils.lbsram import is_low_on_memory from tomwer.core.process.reconstruction.axis import AxisTask from tomwer.core.process.reconstruction.axis.mode import AxisMode from tomwer.core.process.reconstruction.params_cache import ( save_reconstruction_parameters_to_cache, ) from tomwer.core.scan.scanbase import TomwerScanBase, _TomwerBaseDock from tomwer.gui.reconstruction.axis import AxisMainWindow from tomwer.synctools.axis import QAxisRP from tomwer.synctools.stacks.reconstruction.axis import AxisProcessStack from ..utils import WidgetLongProcessing logger = logging.getLogger(__name__) class AxisOW(SuperviseOW, WidgetLongProcessing): """ Widget used to defined the center of rotation axis to be used for a reconstruction. :param _connect_handler: True if we want to store the modifications on the setting. Need for unit test since keep alive qt widgets. """ name = "center of rotation finder" id = "orange.widgets.tomwer.axis" description = "use to compute the center of rotation" icon = "icons/axis.png" priority = 14 keywords = [ "tomography", "axis", "tomwer", "reconstruction", "rotation", "position", "center of position", ] ewokstaskclass = tomwer.core.process.reconstruction.axis.AxisTask want_main_area = True resizing_enabled = True settingsHandler = CallbackSettingsHandler() sigScanReady = qt.Signal(TomwerScanBase) """Signal emitted when a scan is ready""" _ewoks_default_inputs = Setting({"data": None, "axis_params": None, "gui": None}) class Inputs: data = Input( name="data", type=TomwerScanBase, doc="one scan to be process", multiple=True, ) data_recompute_axis = Input( name="change recons params", type=_TomwerBaseDock, doc="recompute delta / beta", ) class Outputs: data = Output(name="data", type=TomwerScanBase, doc="one scan to be process") def __init__(self, parent=None, axis_params: QAxisRP | None = None): """ :param parent: QWidget parent or None :param _connect_handler: used for CI, because if connected fails CI :param axis_params: reconstruction parameters """ if axis_params is not None: if not isinstance(axis_params, QAxisRP): raise TypeError( f"axis_params should be an instance of QAxisRP. Not {type(axis_params)}" ) self._axis_params = axis_params or QAxisRP() # handle settings # axis params settings axis_params_settings = self._ewoks_default_inputs.get("axis_params", None) if axis_params_settings not in (None, dict()): try: self._axis_params.load_from_dict(axis_params_settings) except Exception as e: logger.error(f"fail to load reconstruction settings: {e}") # gui settings gui_settings = self._ewoks_default_inputs.get("gui", {}) if gui_settings is None: gui_settings = {} original_mode = self._axis_params.mode if original_mode is AxisMode.manual: original_cor = self._axis_params.relative_cor_value else: original_cor = None self.__lastAxisProcessParamsCache = None # used to memorize the last (reconstruction parameters, scan) self.__scan = None self.__skip_exec = False self._n_skip = 0 self._patches = [] """patches for processing""" WidgetLongProcessing.__init__(self) SuperviseOW.__init__(self, parent) self._processingStack = AxisProcessStack( axis_params=self._axis_params, process_id=self.process_id ) self._widget = AxisMainWindow(parent=self, axis_params=self._axis_params) self._layout = gui.vBox(self.mainArea, self.name).layout() self._layout.setContentsMargins(0, 0, 0, 0) self._layout.addWidget(self._widget) # load settings try: if "mode_is_lock" in gui_settings: mode_lock = gui_settings["mode_is_lock"] # if the mode is manual or read ignore lock if not ( mode_lock is True and self.getMode() in (AxisMode.manual, AxisMode.read) ): self._setModeLockFrmSettings(mode_lock) if "value_is_lock" in gui_settings: if gui_settings["value_is_lock"] is True: self._setValueLockFrmSettings(bool(gui_settings["value_is_lock"])) auto_update_estimated_cor = gui_settings.get( "auto_update_estimated_cor", True ) self._widget.setAutoUpdateEstimatedCor(auto_update_estimated_cor) self._widget.setYAxisInverted(gui_settings.get("y_axis_inverted", False)) except Exception as e: logger.warning(f"Fail to load settings. Error is {str(e)}") # expose API self._applyBut = self._widget._controlWidget._applyBut # connect Signal / Slot self._widget.sigComputationRequested.connect(self.__compute) self._widget.sigApply.connect(self.__validate) self._widget.sigAxisEditionLocked.connect(self.__lockReconsParams) self._processingStack.sigComputationStarted.connect(self._processingStart) self._processingStack.sigComputationEnded.connect(self._scanProcessed) self._axis_params.sigChanged.connect(self._updateSettingsVals) self._widget._axisWidget._settingsWidget._mainWidget._calculationWidget.sigUpdateXRotAxisPixelPosOnNewScan.connect( self._updateSettingsVals ) self._widget.sigAxisEditionLocked.connect(self._updateSettingsVals) self._widget.sigModeChanged.connect(self._updateSettingsVals) self._widget.sigLockModeChanged.connect(self._updateSettingsVals) self._widget._axisWidget._settingsWidget._mainWidget._calculationWidget._estimatedCorWidget.sigValueChanged.connect( self._updateSettingsVals ) # handle special case of the manual mode # force axis to manual because not handled by the widget setup directly if original_mode in ( AxisMode.manual, AxisMode.read, ): self._axis_params.mode = original_mode if original_cor is not None: self._axis_params.set_relative_value(original_cor) self.setMode(original_mode) # force gui update self._widget.sigModeChanged.emit("manual") # hard fix, but this widget has to be redone and rework anyway self._widget._axisWidget._settingsWidget._mainWidget._calculationWidget._modeChanged() if original_cor is not None: self._widget._controlWidget._positionInfo.setPosition( relative_cor=original_cor, abs_cor=None ) def __new__(cls, *args, **kwargs): # ensure backward compatibility with 'static_input' static_input = kwargs.get("stored_settings", {}).get("static_input", None) if static_input not in (None, {}): logger.warning( "static_input has been deprecated. Will be replaced by _ewoks_default_inputs in the workflow file. Please save the workflow to apply modifications" ) kwargs["stored_settings"]["_ewoks_default_inputs"] = static_input return super().__new__(cls, *args, **kwargs) def _processingStart(self, *args, **kwargs): WidgetLongProcessing._startProcessing(self) def _scanProcessed(self, scan, future_tomo_obj): assert isinstance(scan, TomwerScanBase) WidgetLongProcessing._endProcessing(self, scan) if self.isValueLock() or self.isModeLocked(): self.__scan = scan self.__validate() else: pm = ProcessManager() # handle previous scan if not validated yey: skip it if ( self.__scan is not None and pm.get_dataset_state(dataset=self.__scan, process=self) != DatasetState.SUCCEED ): pm.notify_dataset_state( dataset=self.__scan, process=self, state=DatasetState.SKIPPED, details="Scan was waiting for validation. Has been replaced by another scan. No scan stack on Axis process", ) # handle the new scan # retrieve details to keep them in `memory` self.__scan = scan details = pm.get_dataset_details(dataset=self.__scan, process=self) details = "Wait for user validation. " + details pm.notify_dataset_state( dataset=self.__scan, process=self, state=DatasetState.WAIT_USER_VALIDATION, details=details, ) self.activateWindow() self.raise_() self.show() def __compute(self): if self.__scan: dict_for_cache = self._axis_params.to_dict().copy() dict_for_cache.pop("POSITION_VALUE") params_cache = ( dict_for_cache, str(self.__scan), ) # check mode is not locked or manual and value is still here if ( params_cache == self.__lastAxisProcessParamsCache ) and self._processingStack.is_computing(): logger.error( "Parameters and scan are the same as last request. Please wait until the processing is done." ) else: self.__lastAxisProcessParamsCache = params_cache callback = functools.partial(self._updatePosition, self.__scan) self._processingStack.add( data=self.__scan, configuration=self._axis_params.to_dict(), callback=callback, ) def __validate(self): """Validate the current scan and move the scan to the next process. The Axis will process the next scan in the stack. """ if self.__scan: if self.getMode() is AxisMode.manual: # when value is set from manual mode we need to retrieve it from the GUI `_axis_param`. Else it has already been set # to the scan `_axis_params` if ( self.__scan._axis_params.frame_width is None and self.__scan.dim_1 is not None ): self.__scan._axis_params.frame_width = self.__scan.dim_1 self.__scan._axis_params.set_relative_value( self._axis_params.relative_cor_value ) relative_cor_value = self.__scan.axis_params.relative_cor_value save_reconstruction_parameters_to_cache(scan=self.__scan) pv_helpers.notify_succeed( process=self, dataset=self.__scan, details=f"axis calculation defined for {self.__scan.path}: {relative_cor_value} (using manual)", ) # validate the center of rotation pm = ProcessManager() # retrieve details to keep them in memory details = pm.get_dataset_details(dataset=self.__scan, process=self) state = pm.get_dataset_state(dataset=self.__scan, process=self) if state in (DatasetState.ON_GOING, DatasetState.WAIT_USER_VALIDATION): # update the state to SUCCEED ProcessManager().notify_dataset_state( dataset=self.__scan, process=self, state=DatasetState.SUCCEED, details=details, ) self.accept() self.scan_ready(scan=self.__scan) self.hide() def __lockReconsParams(self, lock): self.lock_position_value(lock) def scan_ready(self, scan): assert isinstance(scan, TomwerScanBase) self.Outputs.data.send(scan) self.sigScanReady.emit(scan) def _informNoProjFound(self, scan): msg = qt.QMessageBox(self) msg.setIcon(qt.QMessageBox.Warning) text = ( "Unable to find url to compute the axis of `%s`" % scan.path or "no path given" ) text += ", please select them from the `axis input` tab" msg.setText(text) msg.exec() def _updateSettingsVals(self): # remove rp setting to the advantage of 'static_input' self._ewoks_default_inputs = { "data": None, "axis_params": self._axis_params.to_dict(), "gui": { "mode_is_lock": self.isModeLocked(), "value_is_lock": self.isValueLock(), "auto_update_estimated_cor": self._widget.getAutoUpdateEstimatedCor(), "y_axis_inverted": self._widget.isYAxisInverted(), }, } def _skip_exec(self, b): """util function used for unit test. If activate, skip the call to self.exec() in process""" self.__skip_exec = b @property def recons_params(self): return self._axis_params def _lock_axis_controls(self, lock): """ :param lock: lock the axis controls to avoid modification of the requested options, method... of the axis calculation when this value is under calculation. """ self._widget.setLocked(lock) def isValueLock(self): """ Check if the cor value has been lock. If so we simply copy the cor value and move to the next scan """ return self._widget.isValueLock() def isModeLocked(self): """ Check if the mode has been lock or not. If lock then call the algorithm and does not wait for any user feedback """ return self._widget.isModeLock() @Inputs.data def new_data_in(self, scan, *args, **kwargs): if scan is None: return scan_ = copy.copy(scan) if not ( settings.isOnLbsram(scan) and is_low_on_memory(settings.get_lbsram_path()) ): set_position = False # avoid shift reset self._widget.setScan(scan=scan_, set_position=set_position) elif scan_.axis_params is None: scan_.axis_params = QAxisRP() self.process(scan=scan_) def process(self, scan): if scan is None: return self.__scan = scan self._axis_params.frame_width = scan.dim_1 if ( settings.isOnLbsram(scan) and is_low_on_memory(settings.get_lbsram_path()) is True ): self._updatePosition(scan=scan) self.scan_ready(scan=scan) elif self.__skip_exec: self._n_skip += 1 if self.isValueLock(): scan._axis_params.set_relative_value( self._axis_params.relative_cor_value ) cor = scan._axis_params.relative_cor_value save_reconstruction_parameters_to_cache(scan=scan) ap = AxisTask( process_id=self.process_id, inputs={ "data": None, }, ) ProcessManager().notify_dataset_state( dataset=scan, process=ap, state=DatasetState.SUCCEED, ) else: processing_class = AxisTask( inputs={ "axis_params": self._axis_params, "data": self.__scan, "serialize_output_data": False, } ) processing_class.run() self._updatePosition(scan=self.__scan) if self.isModeLocked() or self.isValueLock(): self.scan_ready(scan=scan) elif self.isValueLock(): cor = self._axis_params.relative_cor_value scan.axis_params.set_relative_value(cor) save_reconstruction_parameters_to_cache(scan=scan) scan._axis_params.mode = "manual" ProcessManager().notify_dataset_state( dataset=scan, process=AxisTask( process_id=self.process_id, inputs={ "data": None, "serialize_output_data": False, }, ), state=DatasetState.SUCCEED, ) self.scan_ready(scan=scan) elif self.isModeLocked(): callback = functools.partial(self._updatePosition, scan) self._processingStack.add( data=scan, configuration=self._axis_params.to_dict(), callback=callback ) else: self.activateWindow() self.raise_() self.show() def _updatePosition(self, scan): if scan.axis_params is not None: self._widget.setPosition(relative_value=scan.axis_params.relative_cor_value) @Inputs.data_recompute_axis def reprocess(self, scan): """Recompute the axis for scan""" if scan is not None: # for now The behavior for reprocessing is the sama as for processing if hasattr(scan, "instance"): self.process(scan.instance) else: self.process(scan) def close(self): self._processingStack.stop() self._processingStack.wait_computation_finished() self._widget = None self._processingStack = None super().close() def patch_calc_method(self, mode, function): self._patches.append((mode, function)) def keyPressEvent(self, event): """The event has to be filtered since we have some children that can be edited using the 'enter' key as defining the cor manually (see #481)). As we are in a dialog this automatically trigger 'accepted'. See https://forum.qt.io/topic/5080/preventing-enter-key-from-triggering-ok-in-qbuttonbox-in-particular-qlineedit-qbuttonbox/5 """ if event.key() != qt.Qt.Key_Enter: super().keyPressEvent(event) # expose API def setMode(self, mode): self._widget.setMode(mode=mode) def getMode(self): return self._widget.getMode() def getEstimatedCor(self): return self._widget.getEstimatedCor() def setEstimatedCor(self, value): self._widget.setEstimatedCor(value=value) def getAxisParams(self): return self._widget.getAxisParams() def setValueLock(self, lock: bool): self._widget.setValueLock(lock=lock) def _setModeLockFrmSettings(self, lock: bool): self._widget._setModeLockFrmSettings(lock=lock) def _setValueLockFrmSettings(self, lock: bool): self._widget._setValueLockFrmSettings(lock=lock) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/CastNabuVolumeOW.py0000644000175000017500000002073415153325210027423 0ustar00paynopaynofrom __future__ import annotations import logging from orangewidget import gui from orangewidget.settings import Setting from orangewidget.widget import Input, Output from silx.gui import qt import tomwer.core.process.reconstruction.nabu.castvolume from orangecontrib.tomwer.widgets.utils import WidgetLongProcessing from tomwer.core.cluster.cluster import SlurmClusterConfiguration from tomwer.core.futureobject import FutureTomwerObject from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.volume.volumebase import TomwerVolumeBase from tomwer.core.process.drac.processeddataset import ( DracReconstructedVolumeDataset, ) from tomwer.gui.reconstruction.nabu.castvolume import CastVolumeWidget from tomwer.gui.utils.qt_utils import block_signals from tomwer.synctools.stacks.reconstruction.castvolume import CastVolumeProcessStack from tomwer.utils import docstring from ...orange.managedprocess import SuperviseOW _logger = logging.getLogger(__name__) class CastNabuVolumeOW(WidgetLongProcessing, SuperviseOW): """ widget used to cast from 32 bits tiff to 16 bits tiff. This is done in a separate process because: * this is done in cpu when nabu reconstruct on GPU and this should free sooner GPU resources with the current architecture. * this is not included in nabu but also done as post processing. * limitation is that not having computed the histogram during volume construction will slow down the cast :param parent: the parent widget """ # note of this widget should be the one registered on the documentation name = "cast volume" id = "orange.widgets.tomwer.reconstruction.CastNabuVolumeOW.CastNabuVolumeOW" description = "This widget will allow to cast a nabu volume data type / format to another one." icon = "icons/nabu_cast.svg" priority = 60 keywords = [ "tomography", "nabu", "reconstruction", "volume", "cast", "tiff", "32 bits", "16 bits", "tif", ] ewokstaskclass = tomwer.core.process.reconstruction.nabu.castvolume.CastVolumeTask want_main_area = True resizing_enabled = True _ewoks_default_inputs = Setting({"data": None, "cast_volume_params": {}}) sigScanReady = qt.Signal(TomwerScanBase) "Signal emitted when a scan is ended" TIMEOUT = 30 class Inputs: data = Input( name="data", type=TomwerScanBase, doc="one scan to be process", default=True, multiple=False, ) volume = Input( name="volume", type=TomwerVolumeBase, doc="volume to be process", default=False, multiple=False, ) cluster_in = Input( name="cluster_config", type=SlurmClusterConfiguration, doc="slurm cluster to be used", multiple=False, ) class Outputs: data = Output(name="data", type=TomwerScanBase, doc="one scan to be process") volume = Output(name="volume", type=TomwerVolumeBase, doc="raw volume") cast_volume = Output( name="cast volume", type=TomwerVolumeBase, doc="cast volume" ) future_tomo_obj = Output( name="future_tomo_obj", type=FutureTomwerObject, doc="future object (process remotely)", ) data_portal_processed_datasets = Output( name="data_portal_processed_datasets", type=tuple, doc="data portal processed data to be saved", ) def __init__(self, parent=None): """ """ SuperviseOW.__init__(self, parent) WidgetLongProcessing.__init__(self) self._slurmCluster = None # processing tool self._processingStack = CastVolumeProcessStack(process_id=self.process_id) self._window = CastVolumeWidget(parent=self) self._layout = gui.vBox(self.mainArea, self.name).layout() self._layout.setContentsMargins(0, 0, 0, 0) self._layout.addWidget(self._window) cast_volume_params = self._ewoks_default_inputs.get("cast_volume_params", {}) self.setConfiguration(cast_volume_params) # connect signal / slot self._window.sigConfigChanged.connect(self._updateConfig) self._processingStack.sigComputationStarted.connect(self._startProcessing) self._processingStack.sigComputationEnded.connect(self._endProcessing) def __new__(cls, *args, **kwargs): # ensure backward compatibility with 'static_input' static_input = kwargs.get("stored_settings", {}).get("static_input", None) if static_input not in (None, {}): _logger.warning( "static_input has been deprecated. Will be replaced by _ewoks_default_inputs in the workflow file. Please save the workflow to apply modifications" ) kwargs["stored_settings"]["_ewoks_default_inputs"] = static_input return super().__new__(cls, *args, **kwargs) @Inputs.data def process_data(self, scan: TomwerScanBase | None): self._process(scan=scan, volume=None) def _process(self, scan: TomwerScanBase | None, volume: TomwerVolumeBase | None): if scan is None and volume is None: return # check types if scan is not None and not isinstance(scan, TomwerScanBase): raise TypeError( f"scan is expected to be an instance of {TomwerScanBase} not {type(scan)}" ) if volume is not None and not isinstance(volume, TomwerVolumeBase): raise TypeError( f"volume is expected to be an instance of {TomwerVolumeBase} not {type(volume)}" ) self._processingStack.add(scan or volume, configuration=self.getConfiguration()) @docstring def reprocess(self, dataset): if isinstance(dataset, TomwerScanBase): self._process(scan=dataset, volume=None) elif isinstance(dataset, TomwerVolumeBase): self._process(scan=None, volume=dataset) else: raise TypeError("dataset is expected to be an instance of ''") @Inputs.cluster_in def setCluster(self, slurm_cluster: SlurmClusterConfiguration | None): assert isinstance( slurm_cluster, (type(None), SlurmClusterConfiguration) ), f"Expect None of SlurmClusterConfiguration. Not {type(slurm_cluster)}" self._slurmCluster = slurm_cluster @Inputs.volume def process_volume(self, volume: TomwerVolumeBase | None): self._process(scan=None, volume=volume) def getConfiguration(self) -> dict: config = self._window.getConfiguration() config["cluster_config"] = self._slurmCluster return config def setConfiguration(self, configuration: dict) -> None: with block_signals(self._window): self._window.setConfiguration(configuration) def _updateConfig(self): self._ewoks_default_inputs = { "data": None, "cast_volume_params": self.getConfiguration(), } def _endProcessing(self, obj, future_tomo_obj): WidgetLongProcessing._endProcessing(self, obj) if future_tomo_obj is not None: self.Outputs.future_tomo_obj.send(future_tomo_obj) if obj is not None: scan = None if isinstance(obj, TomwerScanBase): # case the input object was a scan (expected) self.Outputs.data.send(obj) scan = obj elif isinstance(obj, TomwerVolumeBase): # case the input object was a volume self.Outputs.volume.send(obj) # for now we store a cast_volume to the object but this is not very well design. # I guess this will be removed once we move to ewoks or we need to redesign the stack approach if obj.cast_volume is not None: assert isinstance(obj.cast_volume, TomwerVolumeBase) self.Outputs.cast_volume.send(obj.cast_volume) if scan is not None: # case the input object was a scan and we have succeeded to cast the volume # then we can publish to the data portal icatReconstructedDataset = DracReconstructedVolumeDataset( tomo_obj=obj.cast_volume, source_scan=scan, ) self.Outputs.data_portal_processed_datasets.send( (icatReconstructedDataset,) ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/DarkRefAndCopyOW.py0000644000175000017500000002274015153325210027326 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import copy import logging import tomoscan.esrf.scan.utils from orangewidget import gui from orangewidget.settings import Setting from orangewidget.widget import Input, Output from processview.core.manager import DatasetState, ProcessManager from silx.gui import qt import tomwer.core.process.reconstruction.darkref.darkrefscopy from orangecontrib.tomwer.orange.managedprocess import SuperviseOW from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui.reconstruction.darkref.darkrefcopywidget import DarkRefAndCopyWidget from tomwer.synctools.darkref import QDKRFRP from tomwer.synctools.stacks.reconstruction.dkrefcopy import DarkRefCopyProcessStack from tomwer.utils import docstring from ..utils import WidgetLongProcessing _logger = logging.getLogger(__name__) class DarkRefAndCopyOW(SuperviseOW, WidgetLongProcessing): """ A simple widget managing the copy of an incoming folder to an other one :param parent: the parent widget """ # note of this widget should be the one registered on the documentation name = "reduced darks and flats" id = "orange.widgets.tomwer.darkrefs" description = ( "This widget will generate reduced darks and flats for a received scan " ) icon = "icons/darkref.svg" priority = 15 keywords = ["tomography", "dark", "darks", "ref", "refs", "flat", "flats"] want_main_area = True resizing_enabled = True _ewoks_default_inputs = Setting({"data": None, "dark_ref_params": None}) sigScanReady = qt.Signal(TomwerScanBase) """Signal emitted when a scan is ready""" ewokstaskclass = ( tomwer.core.process.reconstruction.darkref.darkrefscopy.DarkRefsCopy ) class Inputs: data = Input( name="data", type=TomwerScanBase, doc="one scan to be process", multiple=True, ) reduced_darks = Input( name="reduced dark(s)", type=dict, doc="dict containing reduced dark(s)", multiple=False, ) reduced_flats = Input( name="reduced flat(s)", type=dict, doc="dict of containing reduced flat(s)", multiple=False, ) class Outputs: data = Output(name="data", type=TomwerScanBase, doc="one scan to be process") reduced_darks = Output( name="reduced dark(s)", type=dict, doc="DataUrl of the reduced dark. Key is the relative position, value is the reduced dark", ) reduced_flats = Output( name="reduced flat(s)", type=dict, doc="DataUrl of the reduced flat. Key is the relative position, value is the reduced flat", ) def __init__(self, parent=None, reconsparams: QDKRFRP | None = None): """ :param reconsparams: reconstruction parameters """ SuperviseOW.__init__(self, parent) WidgetLongProcessing.__init__(self) recons_params = reconsparams or QDKRFRP() self._processing_stack = DarkRefCopyProcessStack(process_id=self.process_id) dark_ref_params = self._ewoks_default_inputs.get("dark_ref_params", None) if dark_ref_params not in ({}, None): try: recons_params.dkrf.load_from_dict(dark_ref_params) except Exception: _logger.warning("fail to load reconstruction settings") self.widget = DarkRefAndCopyWidget( save_dir=self._processing_stack._save_dir, parent=self, reconsparams=recons_params, process_id=self.process_id, ) self._layout = gui.vBox(self.mainArea, self.name).layout() self._layout.addWidget(self.widget) self.setForceSync = self.widget.setForceSync # expose API self.setModeAuto = self.widget.set_mode_auto self.setRefsFromScan = self.widget.setRefsFromScan self.setCopyActive = self.widget.setCopyActive # connect signal / slot self.widget.sigProcessingStart.connect(self._startProcessing) self.widget.sigProcessingEnd.connect(self._endProcessing) self.widget.sigScanReady.connect(self.signalReady) self.widget.recons_params.sigChanged.connect(self._updateSettingsVals) self.widget.sigModeAutoChanged.connect(self._updateSettingsVals) self.widget.sigCopyActivationChanged.connect(self._updateSettingsVals) self.widget.sigClearCache.connect(self._processing_stack.clear_cache) self._processing_stack.sigComputationStarted.connect(self._startProcessing) self._processing_stack.sigComputationEnded.connect(self._endProcessing) self._processing_stack.sigRefSetted.connect(self.widget.setRefSetBy) # load some other copy parameters if dark_ref_params not in ({}, None): try: if "activate" in dark_ref_params: self.widget.setCopyActive(dark_ref_params.pop("activate")) if "auto" in dark_ref_params: auto_mode = dark_ref_params.pop("auto") # insure backward compatibility. Has beem saved as a tuple (this was a typo) if isinstance(auto_mode, tuple) and isinstance(auto_mode[0], bool): auto_mode = auto_mode[0] self.widget.setModeAuto(auto_mode) except Exception: _logger.warning("fail to load reconstruction settings") def __new__(cls, *args, **kwargs): # ensure backward compatibility with 'static_input' static_input = kwargs.get("stored_settings", {}).get("static_input", None) if static_input not in (None, {}): _logger.warning( "static_input has been deprecated. Will be replaced by _ewoks_default_inputs in the workflow file. Please save the workflow to apply modifications" ) kwargs["stored_settings"]["_ewoks_default_inputs"] = static_input return super().__new__(cls, *args, **kwargs) @Inputs.data def process(self, scanID, *args, **kwargs): if scanID is None: return assert isinstance(scanID, TomwerScanBase) ProcessManager().notify_dataset_state( dataset=scanID, process=self, state=DatasetState.PENDING ) configuration = self.widget.recons_params.to_dict() configuration["process_only_copy"] = False # we never only do copy from the gui configuration["process_only_dkrf"] = not self.widget.isCopyActive() configuration["mode_auto"] = self.widget.isOnModeAuto() self._processing_stack.add(copy.copy(scanID), configuration=configuration) @Inputs.reduced_darks def received_reduced_darks(self, reduced_darks: dict): # we consider if the darks are provided then the user want to use those and don't copy them manually self.setModeAuto(False) reduced_darks.pop("reduce_frames_name", None) self.setReducedDarks(reduced_darks) @Inputs.reduced_flats def received_reduced_flats(self, reduced_flats: dict): # we consider if the darks are provided then the user want to use those and don't copy them manually self.setModeAuto(False) reduced_flats.pop("reduce_frames_name", None) self.setReducedFlats(reduced_flats) @docstring(SuperviseOW) def reprocess(self, dataset): self.process(dataset) def signalReady(self, scanID): assert isinstance(scanID, TomwerScanBase) self.Outputs.data.send(scanID) self.sigScanReady.emit(scanID) def _updateSettingsVals(self): self._ewoks_default_inputs = { "data": None, "dark_ref_params": self.widget.recons_params.to_dict(), } self._ewoks_default_inputs["dark_ref_params"][ "auto" ] = self.widget.isOnModeAuto() self._ewoks_default_inputs["dark_ref_params"][ "activate" ] = self.widget.isCopyActive() @property def recons_params(self): return self.widget.recons_params def close(self): self.widget.close() super(DarkRefAndCopyOW, self).close() def _endProcessing(self, scan): WidgetLongProcessing._endProcessing(self, scan) self.Outputs.data.send(scan) self.sigScanReady.emit(scan) if scan.reduced_darks not in (None, {}): # we want to send those in relative position to have something generic. This is a convention for now reduced_darks = scan.reduced_darks reduced_darks.pop("reduce_frames_name", None) self.Outputs.reduced_darks.send( tomoscan.esrf.scan.utils.from_absolute_reduced_frames_to_relative( reduced_frames=reduced_darks, scan=scan ) ) if scan.reduced_flats not in (None, {}): # we want to send those in relative position to have something generic. This is a convention for now reduced_flats = scan.reduced_flats reduced_flats.pop("reduce_frames_name", None) self.Outputs.reduced_flats.send( tomoscan.esrf.scan.utils.from_absolute_reduced_frames_to_relative( reduced_frames=reduced_flats, scan=scan ) ) _logger.info(f"{scan} ended") def setReducedDarks(self, darks: dict): self.widget._refCopyWidget.save_darks_to_be_copied(darks) def setReducedFlats(self, flats: dict): self.widget._refCopyWidget.save_flats_to_be_copied(flats) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/NabuHelicalPrepareWeightsDoubleOW.py0000644000175000017500000001413115153325210032701 0ustar00paynopayno# from __future__ import annotations # import logging # from orangewidget import gui # from orangewidget.settings import Setting # from orangewidget.widget import Input, Output # from orangecontrib.tomwer.orange.managedprocess import TomwerWithStackStack # from silx.gui import qt # from typing import Optional # from tomwer.core.futureobject import FutureTomwerObject # from tomwer.core.scan.scanbase import TomwerScanBase # from tomwer.gui.reconstruction.nabu.helical import HelicalPrepareWeightsDouble # from tomwer.core.process.reconstruction.nabu.helical import ( # NabuHelicalPrepareWeightsDouble, # ) # from tomwer.core.scan.nxtomoscan import NXtomoScan # _logger = logging.getLogger(__name__) # class NabuHelicalPrepareWeightsDoubleOW( # TomwerWithStackStack, # ewokstaskclass=NabuHelicalPrepareWeightsDouble, # ): # """ # widget used to call the `nabu-helical-prepare-weights-double` application on a dedicated thread. It define weights map and double flat field. # :param parent: the parent widget # """ # # note of this widget should be the one registered on the documentation # name = "helical prerate weights double" # id = "orangecontrib.tomwer.widgets.reconstruction.NabuHelicalPrepareWeightsDoubleOW.NabuHelicalPrepareWeightsDoubleOW" # description = "compute map of weights requested for nabu helical reconstruction" # icon = "icons/nabu_prepare_weights_double.svg" # priority = 199 # keywords = [ # "tomography", # "nabu", # "reconstruction", # "nabu-helical", # "helical", # "weights", # "prepare", # ] # want_main_area = True # want_control_area = False # resizing_enabled = True # _ewoks_default_inputs = Setting( # { # "data": None, # "transition_width_vertical": 50, # "transition_width_horizontal": 50, # "processes_file": "", # "rotation_axis_position": 0, # } # ) # _ewoks_inputs_to_hide_from_orange = ( # "progress", # "processes_file", # "transition_width_vertical", # "transition_width_horizontal", # "rotation_axis_position", # ) # sigScanReady = qt.Signal(TomwerScanBase) # "Signal emitted when a scan is ended" # TIMEOUT = 30 # class Inputs: # data = Input( # name="data", # type=TomwerScanBase, # doc="one scan to be process", # default=True, # multiple=False, # ) # class Outputs: # data = Output(name="data", type=TomwerScanBase, doc="one scan to be process") # future_tomo_obj = Output( # name="future_tomo_obj", # type=FutureTomwerObject, # doc="future object (process remotely)", # ) # LOGGER = _logger # def __init__(self, parent=None): # super().__init__(parent) # self.__scan = None # # gui definition # _layout = gui.vBox(self.mainArea, self.name).layout() # self.widget = HelicalPrepareWeightsDouble(parent=self) # _layout.addWidget(self.widget) # ## connect signal / slot # self.widget.sigConfigChanged.connect(self._updateSettings) # if isinstance(self.task_output_changed_callbacks, set): # self.task_output_changed_callbacks.add(self._notify_state) # elif isinstance(self.task_output_changed_callbacks, list): # self.task_output_changed_callbacks.append(self._notify_state) # else: # raise NotImplementedError # ## handle settings # self._loadSettings() # self.task_executor_queue.sigComputationStarted.connect(self._newTaskStarted) # def _updateSettings(self): # config = self.widget.getConfiguration() # for key in ("transition_width", "processes_file"): # self._ewoks_default_inputs[key] = config[key] # pylint: disable=E1137 # @property # def request_input(self): # return self.__request_input # @request_input.setter # def request_input(self, request): # self.__request_input = request # def get_task_inputs(self): # assert self.__scan is not None # return { # "data": self.__scan, # "transition_width": self.widget.getConfiguration()["transition_width"], # "processes_file": self.widget.getConfiguration()["processes_file"], # } # def handleNewSignals(self) -> None: # """Invoked by the workflow signal propagation manager after all # signals handlers have been called. # """ # # for now we want to avoid propagation any processing. # # task will be executed only when the user validates the dialog # data = super().get_task_inputs().get("data", None) # if data is not None: # if not isinstance(data, NXtomoScan): # raise TypeError( # f"data is expected to be an instance of NXtomoScan. {type(data)} are not handled" # ) # self.add(data.path) # def _loadSettings(self): # self.widget.setConfiguration(self._ewoks_default_inputs) # def _newTaskStarted(self): # try: # task_executor = self.sender() # scan = task_executor.current_task.inputs.data # self.notify_on_going(scan) # except Exception: # pass # def _notify_state(self): # try: # task_executor = self.sender() # task_suceeded = task_executor.succeeded # scan = task_executor.current_task.outputs.data # if task_suceeded: # self.notify_succeed(scan=scan) # else: # self.notify_failed(scan=scan) # except Exception as e: # _logger.error(f"failed to handle task finished callback. Reason is {e}") # @Inputs.data # def process_data(self, scan: TomwerScanBase | None): # if scan is None: # return # else: # self.__scan = scan # self.notify_pending(scan=scan) # self.execute_ewoks_task() # def sizeHint(self) -> qt.QSize: # return qt.QSize(650, 60) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/NabuOW.py0000644000175000017500000002333115153325210025414 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import copy import logging from contextlib import AbstractContextManager from orangewidget import gui from orangewidget.settings import Setting from orangewidget.widget import Input, Output from silx.gui import qt from tomwer.core.process.reconstruction.params_cache import ( load_reconstruction_parameters_from_cache, save_reconstruction_parameters_to_cache, ) import tomwer.core.process.reconstruction.nabu.nabuslices from tomwer.core.cluster import SlurmClusterConfiguration from tomwer.core.futureobject import FutureTomwerObject from tomwer.core.scan.scanbase import TomwerScanBase, _TomwerBaseDock from tomwer.core.volume.volumefactory import VolumeFactory from tomwer.gui.reconstruction.nabu.slices import NabuWindow from tomwer.synctools.stacks.reconstruction.nabu import NabuSliceProcessStack from ...orange.managedprocess import SuperviseOW from ..utils import WidgetLongProcessing _logger = logging.getLogger(__name__) class NabuOW(WidgetLongProcessing, SuperviseOW): """ A simple widget managing the copy of an incoming folder to an other one :param parent: the parent widget """ # note of this widget should be the one registered on the documentation name = "nabu slice reconstruction" id = "orange.widgets.tomwer.reconstruction.NabuOW.NabuOW" description = "This widget will call nabu for running a reconstruction " icon = "icons/nabu_2d.svg" priority = 12 keywords = ["tomography", "nabu", "reconstruction", "FBP", "filter"] want_main_area = True resizing_enabled = True _ewoks_default_inputs = Setting({"data": None, "nabu_params": None}) ewokstaskclass = tomwer.core.process.reconstruction.nabu.nabuslices.NabuSlicesTask sigScanReady = qt.Signal(TomwerScanBase) "Signal emitted when a scan is ended" class Inputs: reprocess = Input( name="change recons params", type=_TomwerBaseDock, doc="reconpute slice with different parameters", ) data = Input( name="data", type=TomwerScanBase, doc="one scan to be process", default=True, multiple=True, ) cluster_in = Input( name="cluster_config", type=SlurmClusterConfiguration, doc="slurm cluster to be used", multiple=False, ) class Outputs: data = Output(name="data", type=TomwerScanBase, doc="one scan to be process") future_out = Output( name="future_tomo_obj", type=FutureTomwerObject, doc="data with some remote processing", ) slice_urls = Output(name="slice urls", type=tuple, doc="tuple of urls created") class DialogCM(AbstractContextManager): """Simple context manager to hide / show button dialogs""" def __init__(self, dialogButtonsBox): self._dialogButtonsBox = dialogButtonsBox def __enter__(self): self._dialogButtonsBox.show() def __exit__(self, exc_type, exc_val, exc_tb): self._dialogButtonsBox.hide() def __init__(self, parent=None): SuperviseOW.__init__(self, parent) WidgetLongProcessing.__init__(self) self._slurmCluster = None self.__exec_for_ci = False # processing tool self._processingStack = NabuSliceProcessStack(self, process_id=self.process_id) _layout = gui.vBox(self.mainArea, self.name).layout() # main widget self._nabuWidget = NabuWindow(parent=self) _layout.addWidget(self._nabuWidget) # add button to validate when change reconstruction parameters is # called types = qt.QDialogButtonBox.Ok self._buttons = qt.QDialogButtonBox(self) self._buttons.setStandardButtons(types) _layout.addWidget(self._buttons) # set up self._buttons.hide() # load settings nabu_params = self._ewoks_default_inputs.get("nabu_params", None) if nabu_params not in (dict(), None): try: self._nabuWidget.setConfiguration(nabu_params) except Exception: _logger.warning("fail to load reconstruction settings") # expose API self.getMode = self._nabuWidget.getMode self.setMode = self._nabuWidget.setMode # connect signal / slot self._processingStack.sigComputationStarted.connect(self._startProcessing) self._processingStack.sigComputationEnded.connect(self._endProcessing) self._buttons.button(qt.QDialogButtonBox.Ok).clicked.connect(self.accept) self._nabuWidget.sigConfigChanged.connect(self._updateSettingsVals) def __new__(cls, *args, **kwargs): # ensure backward compatibility with 'static_input' static_input = kwargs.get("stored_settings", {}).get("static_input", None) if static_input not in (None, {}): _logger.warning( "static_input has been deprecated. Will be replaced by _ewoks_default_inputs in the workflow file. Please save the workflow to apply modifications" ) kwargs["stored_settings"]["_ewoks_default_inputs"] = static_input return super().__new__(cls, *args, **kwargs) @Inputs.data def process(self, scan, *args, **kwargs): assert isinstance(scan, (TomwerScanBase, type(None))) if scan is None: return scan_ = copy.copy(scan) scan_.clear_latest_reconstructions() _logger.info(f"add {scan} to the stack") # update the reconstruction mode if possible self._nabuWidget.setScan(scan_) self._processingStack.add(scan_, self.getConfiguration()) @Inputs.reprocess def reprocess(self, scan): """Recompute nabu with different parameters""" # wait for user to tune the reconstruction if scan is None: return self._nabuWidget.setScan(scan) if scan.axis_params is None or scan.axis_params.relative_cor_value is None: # try to retrieve last computed cor value from nabu process if scan.axis_params is None: from tomwer.synctools.axis import QAxisRP scan.axis_params = QAxisRP() load_reconstruction_parameters_from_cache(scan=scan) self.show() with NabuOW.DialogCM(self._buttons): if self.__exec_for_ci is True: self._ciExec() else: if self.exec(): # for now The behavior for reprocessing is the sama as for processing if hasattr(scan, "instance"): self.process(scan.instance) else: self.process(scan) def cancel(self, scan): if scan is None: return if scan in self._processingStack: self._processingStack.remove(scan) if ( self._processingStack._data_currently_computed.get_identifier().to_str() == scan.get_identifier().to_str() ): # stop current processing self._processingStack.cancel() # if possible process next if self._processingStack.can_process_next(): self._processingStack._process_next() @Inputs.cluster_in def setCluster(self, slurm_cluster: SlurmClusterConfiguration | None): assert isinstance( slurm_cluster, (type(None), SlurmClusterConfiguration) ), f"Expect None of SlurmClusterConfiguration. Not {type(slurm_cluster)}" self._slurmCluster = slurm_cluster def _endProcessing(self, scan, future_tomo_obj): WidgetLongProcessing._endProcessing(self, scan) if scan is not None: save_reconstruction_parameters_to_cache(scan=scan) # send scan self.Outputs.data.send(scan) # send slice urls slice_urls = [] for rec_identifier in scan.latest_reconstructions: slice_urls.extend( VolumeFactory.from_identifier_to_vol_urls(rec_identifier) ) if len(slice_urls) > 0: slice_urls = tuple(slice_urls) # provide list of reconstructed slices self.Outputs.slice_urls.send(slice_urls) self.sigScanReady.emit(scan) if future_tomo_obj is not None: # send future scan self.Outputs.future_out.send(future_tomo_obj) def setDryRun(self, dry_run): self._processingStack.setDryRun(dry_run) def _ciExec(self): self.activateWindow() self.raise_() self.show() def _replaceExec_(self): """used for CI, replace the exec_ call ny""" self.__exec_for_ci = True def _updateSettingsVals(self): self._ewoks_default_inputs = { "data": None, "nabu_params": self.getConfiguration(), } def getConfiguration(self): config = self._nabuWidget.getConfiguration() config["cluster_config"] = self._slurmCluster return config def setConfiguration(self, config): # ignore slurm cluster. Defined by the upper widget config.pop("cluster_config", None) self._nabuWidget.setConfiguration(config=config) def keyPressEvent(self, event): """The event has to be filtered since we have some children that can be edited using the 'enter' key as defining the cor manually (see #481)). As we are in a dialog this automatically trigger 'accepted'. See https://forum.qt.io/topic/5080/preventing-enter-key-from-triggering-ok-in-qbuttonbox-in-particular-qlineedit-qbuttonbox/5 """ if event.key() not in (qt.Qt.Key_Enter, qt.Qt.Key_Return): super().keyPressEvent(event) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/NabuVolumeOW.py0000644000175000017500000004150115153325210026603 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import copy import functools import logging from typing import Iterable from contextlib import AbstractContextManager from orangewidget import gui from orangewidget.settings import Setting from orangewidget.widget import Input, Output from silx.gui import qt from tomoscan.identifier import VolumeIdentifier import tomwer.core.process.reconstruction.nabu.nabuvolume from orangecontrib.tomwer.widgets.utils import WidgetLongProcessing from tomwer.core.process.reconstruction.params_cache import ( load_reconstruction_parameters_from_cache, ) from tomwer.core import settings from tomwer.core.cluster import SlurmClusterConfiguration from tomwer.core.futureobject import FutureTomwerObject from tomwer.core.process.drac.processeddataset import ( DracReconstructedVolumeDataset, ) from tomwer.core.process.reconstruction.nabu import utils as nabu_utils from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.utils.char import BETA_CHAR, DELTA_CHAR from tomwer.core.utils.scanutils import format_output_location from tomwer.core.process.reconstruction.nabu.utils import update_nabu_config_for_tiff_3d from tomwer.core.volume.volumebase import TomwerVolumeBase from tomwer.core.volume.volumefactory import VolumeFactory from tomwer.gui.reconstruction.nabu.volume import NabuVolumeWindow from tomwer.synctools.stacks.reconstruction.nabu import NabuVolumeProcessStack from tomwer.utils import docstring from ...orange.managedprocess import SuperviseOW _logger = logging.getLogger(__name__) class NabuVolumeOW(WidgetLongProcessing, SuperviseOW): """ A simple widget managing the copy of an incoming folder to an other one :param parent: the parent widget """ # note of this widget should be the one registered on the documentation name = "nabu volume reconstruction" id = "orange.widgets.tomwer.reconstruction.NabuVolumeOW.NabuVolumeOW" description = ( "This widget will call nabu for running a reconstruction " "on a volume" ) icon = "icons/nabu_3d.svg" priority = 15 keywords = ["tomography", "nabu", "reconstruction", "volume"] ewokstaskclass = tomwer.core.process.reconstruction.nabu.nabuvolume.NabuVolumeTask want_main_area = True resizing_enabled = True _ewoks_default_inputs = Setting( {"data": None, "nabu_volume_params": None, "nabu_params": None} ) sigScanReady = qt.Signal(TomwerScanBase) "Signal emitted when a scan is ended" TIMEOUT = 30 class Inputs: data = Input( name="data", type=TomwerScanBase, doc="one scan to be process", default=True, multiple=False, ) cluster_in = Input( name="cluster_config", type=SlurmClusterConfiguration, doc="slurm cluster to be used", multiple=False, ) class Outputs: data = Output(name="data", type=TomwerScanBase, doc="one scan to be process") future_out = Output( name="future_tomo_obj", type=FutureTomwerObject, doc="data with some remote processing", ) volume = Output( name="volume", type=TomwerVolumeBase, doc="volume(s) created", ) volume_urls = Output( name="volume urls", type=tuple, doc="url of the volume(s) reconstructed" ) data_portal_processed_datasets = Output( name="data_portal_processed_datasets", type=tuple, doc="data portal processed data to be saved", ) class DialogCM(AbstractContextManager): """Simple context manager to hide / show button dialogs""" def __init__(self, dialogButtonsBox): self._dialogButtonsBox = dialogButtonsBox def __enter__(self): self._dialogButtonsBox.show() def __exit__(self, exc_type, exc_val, exc_tb): self._dialogButtonsBox.hide() def __init__(self, parent=None, *args, **kwargs): SuperviseOW.__init__(self, parent) WidgetLongProcessing.__init__(self) self._slurmCluster = None # processing tool self._processingStack = NabuVolumeProcessStack(self, process_id=self.process_id) _layout = gui.vBox(self.mainArea, self.name).layout() # main widget self._nabuWidget = NabuVolumeWindow(parent=self) _layout.addWidget(self._nabuWidget) # add button to validate when change reconstruction parameters is called types = qt.QDialogButtonBox.Ok self._buttons = qt.QDialogButtonBox(self) self._buttons.setStandardButtons(types) _layout.addWidget(self._buttons) # set up self._buttons.hide() # load settings nabu_volume_params = self._ewoks_default_inputs.get("nabu_volume_params", None) if nabu_volume_params not in (dict(), None): try: self.setConfiguration(nabu_volume_params) except Exception: _logger.warning("fail to load reconstruction settings") # connect signal / slot self._processingStack.sigComputationStarted.connect(self._startProcessing) self._processingStack.sigComputationEnded.connect(self._endProcessing) self._buttons.button(qt.QDialogButtonBox.Ok).clicked.connect(self.accept) self._nabuWidget.sigConfigChanged.connect(self._updateSettingsVals) def __new__(cls, *args, **kwargs): # ensure backward compatibility with 'static_input' static_input = kwargs.get("stored_settings", {}).get("static_input", None) if static_input not in (None, {}): _logger.warning( "static_input has been deprecated. Will be replaced by _ewoks_default_inputs in the workflow file. Please save the workflow to apply modifications" ) kwargs["stored_settings"]["_ewoks_default_inputs"] = static_input return super().__new__(cls, *args, **kwargs) @Inputs.data def process(self, scan: TomwerScanBase): assert isinstance(scan, (TomwerScanBase, type(None))) if scan is None: return scan_ = copy.copy(scan) scan_.clear_latest_vol_reconstructions() # insure we are able to reconstruct if scan.nabu_recons_params in ({}, None): _logger.error( f"No reconstruction parameters found from nabu slices for {scan}. " "You should first run slice reconstruction prior to volume reconstruction" ) self.Outputs.data.send(scan) self.sigScanReady.emit(scan) return config = scan.nabu_recons_params # update output format if requested nabuSettingsWidget = self._nabuWidget._mainWidget._nabuSettingsWidget if nabuSettingsWidget.redefineNabuFileFormat(): config["output"]["file_format"] = nabuSettingsWidget.getNabuFileFormat() update_nabu_config_for_tiff_3d(config) # update output location if requested if nabuSettingsWidget.redefineOutputLocation(): location = nabuSettingsWidget.getNabuOutputLocation() if location is not None: location = format_output_location(location=location, scan=scan) config["output"]["location"] = location config["output"][ "output_dir_mode" ] = nabuSettingsWidget._outputLocationWidget.getOutputDirMode().value if "phase" in config and "delta_beta" in config["phase"]: pag_dbs = config["phase"]["delta_beta"] if isinstance(pag_dbs, str): try: pag_dbs = nabu_utils.retrieve_lst_of_value_from_str( config["phase"]["delta_beta"], type_=float ) except Exception: pass if len(pag_dbs) > 1: _logger.warning( f"Several value found for {DELTA_CHAR} / {BETA_CHAR}. Volume reconstruction take one at most." ) timeout = NabuVolumeOW.TIMEOUT if settings.isOnLbsram(scan) else None self._dialogDB = _DeltaBetaSelectorDialog( values=pag_dbs, parent=None, timeout=timeout ) self._dialogDB.setModal(False) self._callbackDB = functools.partial( self._updateDB, scan, self._dialogDB ) self._dialogDB.accepted.connect(self._callbackDB) self._callbackTimeout = functools.partial(self._skipProcessing, scan) self._dialogDB.timeoutReached.connect(self._callbackTimeout) self._dialogDB.show() return self._processingStack.add(scan_, self.getConfiguration()) @docstring(SuperviseOW) def reprocess(self, dataset): if ( dataset.axis_params is None or dataset.axis_params.relative_cor_value is None ): # try to retrieve last computed cor value from nabu process if dataset.axis_params is None: from tomwer.synctools.axis import QAxisRP dataset.axis_params = QAxisRP() load_reconstruction_parameters_from_cache(scan=dataset) self.process(dataset) def cancel(self, scan): if scan is None: return if scan in self._processingStack: self._processingStack.remove(scan) if ( self._processingStack._data_currently_computed.get_identifier().to_str() == scan.get_identifier().to_str() ): # stop current processing self._processingStack.cancel() # if possible process next if self._processingStack.can_process_next(): self._processingStack._process_next() @Inputs.cluster_in def setCluster(self, cluster): self._slurmCluster = cluster def _updateDB(self, scan, dialog): db = dialog.getSelectedValue() if db is not None: try: scan.nabu_recons_params["phase"]["delta_beta"] = (db,) except Exception as e: logging.error(e) else: self.process(scan=scan) def _endProcessing(self, scan, future_tomo_obj): WidgetLongProcessing._endProcessing(self, scan) if scan is not None: # send scan self.Outputs.data.send(scan) self.sigScanReady.emit(scan) # send volume urls volume_urls = [] for volume_id in scan.latest_vol_reconstructions: assert isinstance(volume_id, VolumeIdentifier) volume_urls.extend(VolumeFactory.from_identifier_to_vol_urls(volume_id)) if len(volume_urls) > 0: self.Outputs.volume_urls.send(tuple(volume_urls)) # send volume identifier(s) and associated IcatDataBase objects n_rec_volumes = len(scan.latest_vol_reconstructions) drac_processed_datasets = [] if n_rec_volumes > 0: if n_rec_volumes > 1: _logger.warning( f"{n_rec_volumes} volume reconstructed when at most one expected" ) try: volume = VolumeFactory.create_tomo_object_from_identifier( scan.latest_vol_reconstructions[0] ) except Exception as e: _logger.error( f"Failed to retrieve volume from {volume_id}. Error is {e}" ) else: self.Outputs.volume.send(volume) icatReconstructedDataset = DracReconstructedVolumeDataset( tomo_obj=volume, source_scan=scan, ) drac_processed_datasets.append(icatReconstructedDataset) if len(drac_processed_datasets) > 0: self.Outputs.data_portal_processed_datasets.send( drac_processed_datasets ) if future_tomo_obj is not None: self.Outputs.future_out.send(future_tomo_obj) def setDryRun(self, dry_run): self._processingStack.setDryRun(dry_run) def _ciExec(self): self.activateWindow() self.raise_() self.show() def _updateSettingsVals(self): self._ewoks_default_inputs = { "data": None, "nabu_volume_params": self.getConfiguration(), "nabu_params": None, } def _skipProcessing(self, scan): self.Outputs.data.send(scan) self.sigScanReady.emit(scan) def getConfiguration(self): config = self._nabuWidget.getConfiguration() config["cluster_config"] = self._slurmCluster return config def setConfiguration(self, config): # ignore slurm cluster. Defined by the upper widget config.pop("cluster_config", None) self._nabuWidget.setConfiguration(config=config) class _DeltaBetaSelectorDialog(qt.QDialog): timeoutReached = qt.Signal() def __init__(self, values, parent=None, timeout=None): """ :param values: :param parent: :param timeout: if a timeout is provided once reach this will automatically reject the delta / beta selection. This is needed when on lbsram to avoid 'locking' a reconstruction. In sec. """ qt.QDialog.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) self.mainWidget = _DeltaBetaSelector(parent=self, values=values) self.layout().addWidget(self.mainWidget) types = qt.QDialogButtonBox.Ok | qt.QDialogButtonBox.Cancel self._buttons = qt.QDialogButtonBox(parent=self) self._buttons.setStandardButtons(types) self.layout().addWidget(self._buttons) self._timeout = timeout if self._timeout is None: self.setWindowTitle(f"Select one value for {DELTA_CHAR} / {BETA_CHAR}") else: self.setWindowTitle( f"Select one value for {DELTA_CHAR} / {BETA_CHAR}. (close automatically in {self._timeout} sec.)" ) # connect signal / slot self._buttons.accepted.connect(self.accept) self._buttons.rejected.connect(self.reject) # expose API self.getSelectedValue = self.mainWidget.getSelectedValue # add timers if timeout is not None: self._timer = qt.QTimer() self._timer.timeout.connect(self.reject) self._timer.start(timeout * 1000) self._displayTimer = qt.QTimer() self._displayTimer.timeout.connect(self._updateTitle) self._displayTimer.start(1000) else: self._timer = None def reject(self): if self._timer: self._timer.stop() self._timer.timeout.disconnect(self.reject) self._displayTimer.stop() self._displayTimer.timeout.disconnect(self._updateTitle) self._timer = None qt.QDialog.reject(self) def _updateTitle(self): self._timeout = self._timeout - 1 if self._timeout <= 0: self.timeoutReached.emit() self.reject() else: self.setWindowTitle( f"Select one value for {DELTA_CHAR} / {BETA_CHAR}. (close automatically in {self._timeout} sec.)" ) self._displayTimer.start(1000) class _DeltaBetaSelector(qt.QTableWidget): """Widget used to select a value of delta beta if several provided""" def __init__(self, values, parent=None): qt.QTableWidget.__init__(self, parent) self.setSelectionMode(qt.QAbstractItemView.SingleSelection) self.setHorizontalHeaderLabels([DELTA_CHAR + " / " + BETA_CHAR]) self.setRowCount(0) self.setColumnCount(1) self.verticalHeader().hide() if hasattr(self.horizontalHeader(), "setSectionResizeMode"): # Qt5 self.horizontalHeader().setSectionResizeMode(0, qt.QHeaderView.Stretch) else: # Qt4 self.horizontalHeader().setResizeMode(0, qt.QHeaderView.Stretch) self.setAcceptDrops(False) # set up self.setValues(values=values) def setValues(self, values: Iterable): self.setHorizontalHeaderLabels([DELTA_CHAR + " / " + BETA_CHAR]) self.setRowCount(len(values)) self.setColumnCount(1) for i_value, value in enumerate(values): _item = qt.QTableWidgetItem() _item.setText(str(value)) _item.setFlags(qt.Qt.ItemIsEnabled | qt.Qt.ItemIsSelectable) self.setItem(i_value, 0, _item) _item.setSelected(i_value == 0) def getSelectedValue(self): sel = None for item in self.selectedItems(): sel = item.text() return sel ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py0000644000175000017500000004244715153325210025670 0ustar00paynopaynofrom __future__ import annotations import functools import logging from orangewidget import gui from orangewidget.settings import Setting from orangewidget.widget import Input, Output from processview.core import helpers as pv_helpers from processview.core.manager import DatasetState, ProcessManager from silx.gui import qt import tomwer.core.process.reconstruction.saaxis.saaxis from orangecontrib.tomwer.orange.managedprocess import SuperviseOW from orangecontrib.tomwer.orange.settings import CallbackSettingsHandler from tomwer.core import settings from tomwer.core.utils.lbsram import is_low_on_memory from tomwer.core.cluster import SlurmClusterConfiguration from tomwer.core.process.reconstruction.axis import AxisTask from tomwer.core.process.reconstruction.params_cache import ( save_reconstruction_parameters_to_cache, ) from tomwer.core.scan.scanbase import TomwerScanBase, _TomwerBaseDock from tomwer.gui.reconstruction.saaxis.saaxis import SAAxisWindow as _SAAxisWindow from tomwer.synctools.axis import QAxisRP from tomwer.synctools.saaxis import QSAAxisParams from tomwer.synctools.stacks.reconstruction.saaxis import SAAxisProcessStack from ..utils import WidgetLongProcessing _logger = logging.getLogger(__name__) class SAAxisWindow(_SAAxisWindow): sigResultsToBeShow = qt.Signal() """signal emit when some results are ready to be display""" def __init__(self, Outputs, parent=None, process_id=None): _SAAxisWindow.__init__(self, parent=parent) self.Outputs = Outputs self._saaxis_params = QSAAxisParams() self._processing_stack = SAAxisProcessStack( saaxis_params=self._saaxis_params, process_id=process_id ) if process_id is not None: assert self._processing_stack.process_id == process_id # connect signal / slot self.sigValidated.connect(self.validateCurrentScan) self._clusterConfig = None def setClusterConfig(self, cluster_config: dict): if not isinstance( cluster_config, (dict, type(None), SlurmClusterConfiguration) ): raise TypeError( f"cluster config is expected to be None, dict, {SlurmClusterConfiguration} not {type(cluster_config)}" ) self._clusterConfig = cluster_config def _computeEstimatedCor(self) -> float | None: """callback when calculation of a estimated cor is requested""" # TODO: check but should not be needed anymore scan = self.getScan() if scan is None: text = ( "No scan is set on the widget currently. No automatic center " "of rotation to be computed" ) _logger.warning(text) msg = qt.QMessageBox(self) msg.setIcon(qt.QMessageBox.Warning) msg.setText(text) msg.show() return else: axis_params_info = self.getQAxisRP().get_simple_str() text = f"start automatic cor for {scan} with {axis_params_info}" _logger.inform(text) cor_estimation_process = AxisTask( inputs={ "axis_params": self.getQAxisRP(), "data": scan, "wait": True, "serialize_output_data": False, }, process_id=-1, ) try: cor_estimation_process.run() except Exception as e: text = f"Unable to run automatic cor calculation. Reason is {e}" _logger.error(text) msg = qt.QMessageBox(self) msg.setIcon(qt.QMessageBox.Critical) msg.setText(text) msg.show() return None else: cor = scan.axis_params.relative_cor_value text = f"automatic cor computed for {scan}: {cor} ({axis_params_info})" _logger.inform(text) self.setEstimatedCorPosition(value=cor) self.getAutomaticCorWindow().hide() return cor def _launchReconstructions(self): """callback when we want to launch the reconstruction of the slice for n cor value""" scan = self.getScan() if scan is None: return if self._checkCancelProcessingForMargins(): _logger.info( "Multi-cor reconstruction cancelled by the user because of phasing / margins warning" ) return # step1: if isAutoFocus: validate automatically the scan # step2: update the interface if the current scan is the one displayed # else skip it callback = functools.partial( self._mightUpdateResult, scan, self.isAutoFocusLock() ) self._processing_stack.add( data=scan, configuration=self.getConfiguration(), callback=callback ) def _validate(self): # TODO: check but should not be needed anymore pass def _mightUpdateResult(self, scan: TomwerScanBase, validate: bool): if not isinstance(scan, TomwerScanBase): raise TypeError("scan is expected to be an instance of TomwerScanBase") if not isinstance(validate, bool): raise TypeError("validate is expected to be a boolean") if scan == self.getScan(): self.setCorScores( scan.saaxis_params.scores, score_method=scan.saaxis_params.score_method, img_width=scan.saaxis_params.image_width, ) if scan.saaxis_params.autofocus is not None: self.setCurrentCorValue(scan.saaxis_params.autofocus) pm = ProcessManager() details = pm.get_dataset_details( dataset_id=scan.get_identifier(), process=self._processing_stack ) current_state = pm.get_dataset_state( dataset_id=scan.get_identifier(), process=self._processing_stack ) if current_state not in ( DatasetState.CANCELLED, DatasetState.FAILED, DatasetState.SKIPPED, ): ProcessManager().notify_dataset_state( dataset=scan, process=self._processing_stack, details=details, state=DatasetState.WAIT_USER_VALIDATION, ) self.sigResultsToBeShow.emit() if validate: _logger.processSucceed( f"saaxis processing succeeded with {scan.axis_params.relative_cor_value} as cor value" ) self.validateScan(scan) def wait_processing(self, wait_time): self._processing_stack._computationThread.wait(wait_time) def validateCurrentScan(self): return self.validateScan(self.getScan()) def validateScan(self, scan): if scan is None: return assert isinstance(scan, TomwerScanBase) selected_cor_value = self.getCurrentCorValue() or scan.saaxis_params.autofocus # if validate is done manually then pick current cor value; else we are in 'auto mode' and get it from the autofocus. details = ProcessManager().get_dataset_details( dataset_id=scan.get_identifier(), process=self._processing_stack ) if details is None: details = "" if selected_cor_value is None: infos = f"no selected cor value. {scan} skip SAAXIS" infos = "\n".join((infos, details)) _logger.warning(infos) scan.axis_params.set_relative_value(None) pv_helpers.notify_skip( process=self._processing_stack, dataset=scan, details=infos ) else: scan.axis_params.set_relative_value(selected_cor_value) save_reconstruction_parameters_to_cache(scan=scan) if scan.nabu_recons_params is not None: if "reconstruction" not in scan.nabu_recons_params: scan.nabu_recons_params["reconstruction"] = {} scan.nabu_recons_params["reconstruction"][ "rotation_axis_position" ] = scan.axis_params.absolute_cor_value r_cor = scan.axis_params.relative_cor_value a_cor = scan.axis_params.absolute_cor_value infos = f"cor selected for {scan}: relative: {r_cor}, absolute: {a_cor}" infos = "\n".join((infos, details)) pv_helpers.notify_succeed( process=self._processing_stack, dataset=scan, details=infos ) self.Outputs.data.send(scan) def getConfiguration(self) -> dict: config = super().getConfiguration() config["cluster_config"] = self._clusterConfig return config def setConfiguration(self, config: dict): # ignore slurm cluster. Defined by the upper widget config.pop("cluster_config", None) return super().setConfiguration(config) class SAAxisOW(SuperviseOW, WidgetLongProcessing): """ Widget for semi-automatic center of rotation calculation behavior within a workflow: * when a scan arrived: * if he already has a center of rotation defined (if the axis widget has been defined for example) it will be used as 'estimated center of rotation' * if no cor has been computed yet and if the .nx entry contains information regarding an "x_rotation_axis_pixel_position" this value will be set * if autofocus option is lock: * launch the series of reconstruction (with research width defined) and the estimated center of rotation if defined. Once the reconstruction is ended and if the autofocus button is still lock it will select the cor with the highest value and mode to workflow downstream. * hint: you can define a "multi-step" half-automatic center of rotation research by creating several "saaxis" widget and reducing the research width. Details about :ref:`saaxis score calculation` """ name = "multi-cor (sa-axis)" id = "orange.widgets.tomwer.sa_axis" description = "Reconstruct a slice with different center of rotation (cor) values" icon = "icons/saaxis.png" priority = 21 keywords = [ "multi", "multi-cor", "tomography", "semi automatic", "half automatic", "axis", "tomwer", "reconstruction", "rotation", "position", "center of rotation", "saaxis", ] ewokstaskclass = tomwer.core.process.reconstruction.saaxis.saaxis.SAAxisTask want_main_area = True resizing_enabled = True settingsHandler = CallbackSettingsHandler() sigScanReady = qt.Signal(TomwerScanBase) """Signal emitted when a scan is ready""" _ewoks_default_inputs = Setting({"data": None, "sa_axis_params": None}) class Inputs: data = Input( name="data", type=TomwerScanBase, doc="one scan to be process", default=True, multiple=False, ) data_recompute = Input( name="change recons params", type=_TomwerBaseDock, ) cluster_in = Input( name="cluster_config", type=SlurmClusterConfiguration, doc="slurm cluster to be used", multiple=False, ) class Outputs: data = Output(name="data", type=TomwerScanBase, doc="one scan to be process") def __init__(self, parent=None): """ :param parent: QWidget parent or None """ SuperviseOW.__init__(self, parent) WidgetLongProcessing.__init__(self) self._layout = gui.vBox(self.mainArea, self.name).layout() self._layout.setContentsMargins(0, 0, 0, 0) self._widget = SAAxisWindow( Outputs=self.Outputs, parent=self, process_id=self.process_id ) self._layout.addWidget(self._widget) sa_axis_params = self._ewoks_default_inputs.get("sa_axis_params", None) self.setConfiguration(sa_axis_params or {}) # connect signal / slot self._widget.sigConfigurationChanged.connect(self._updateSettings) self._widget._processing_stack.sigComputationStarted.connect( self._startProcessing ) self._widget._processing_stack.sigComputationEnded.connect(self._endProcessing) self._widget.sigValidated.connect(self.accept) self._widget.sigResultsToBeShow.connect(self._raiseResults) # expose API self.wait_processing = self._widget.wait_processing def getWaitingOverlay(self): return self._widget._tabWidget._resultsViewer._plot.getWaiterOverlay() def _startProcessing(self, *args, **kwargs): self.getWaitingOverlay().show() super()._startProcessing() def _endProcessing(self, *args, **kwargs): self.getWaitingOverlay().hide() super()._endProcessing() def __new__(cls, *args, **kwargs): # ensure backward compatibility with 'static_input' static_input = kwargs.get("stored_settings", {}).get("static_input", None) if static_input not in (None, {}): _logger.warning( "static_input has been deprecated. Will be replaced by _ewoks_default_inputs in the workflow file. Please save the workflow to apply modifications" ) kwargs["stored_settings"]["_ewoks_default_inputs"] = static_input return super().__new__(cls, *args, **kwargs) def setConfiguration(self, configuration): if "workflow" in configuration: autofocus_lock = configuration["workflow"].get("autofocus_lock", None) if autofocus_lock is not None: self._widget.lockAutofocus(autofocus_lock) del configuration["workflow"] self._widget.setConfiguration(configuration) def getCurrentCorValue(self): return self._widget.getCurrentCorValue() def setEstimatedCorPosition(self, value): self._widget.setEstimatedCorPosition(value=value) def load_sinogram(self): self._widget.loadSinogram() def compute(self): self._widget.compute() def lockAutofocus(self, lock): self._widget.lockAutofocus(lock=lock) def isAutoFocusLock(self): return self._widget.isAutoFocusLock() @Inputs.data def process(self, scan): if scan is None: return if scan.axis_params is None: scan.axis_params = QAxisRP() if scan.saaxis_params is None: scan.saaxis_params = QSAAxisParams() self._skipCurrentScan(new_scan=scan) if settings.isOnLbsram(scan) and is_low_on_memory(settings.get_lbsram_path()): self.notify_skip( scan=scan, details=f"saaxis has been skiped for {scan} because of low space in lbsram", ) self.Outputs.data.send(scan) else: self._widget.setScan(scan=scan) self.notify_pending(scan) self.activateWindow() if self.isAutoFocusLock(): self.compute() else: self.raise_() self.show() @Inputs.cluster_in def setCluster(self, cluster): self._widget.setClusterConfig(cluster_config=cluster) def _skipCurrentScan(self, new_scan): scan = self._widget.getScan() # if the same scan has been run several scan if scan is None or str(scan) == str(new_scan): return current_scan_state = ProcessManager().get_dataset_state( dataset_id=scan.get_identifier(), process=self ) if current_scan_state in ( DatasetState.PENDING, DatasetState.WAIT_USER_VALIDATION, DatasetState.CANCELLED, ): details = "Was pending and has been replaced by another scan." self.notify_skip(scan=scan, details=details) self.Outputs.data.send(scan) @Inputs.data_recompute def reprocess(self, dataset): self.lockAutofocus(False) self.process(dataset) def cancel(self, scan): if scan is None: return if scan in self._widget._processing_stack: self._widget._processing_stack.remove(scan) if ( self._widget._processing_stack._data_currently_computed.get_identifier().to_str() == scan.get_identifier().to_str() ): # stop current processing self._widget._processing_stack.cancel() # if possible process next if self._widget._processing_stack.can_process_next(): self._widget._processing_stack._process_next() def validateCurrentScan(self): self._widget.validateCurrentScan() def _updateSettings(self): config = self._widget.getConfiguration() config.pop("cluster_config", None) self._ewoks_default_inputs = { "data": None, "sa_axis_params": self._widget.getConfiguration(), } self._ewoks_default_inputs["sa_axis_params"]["workflow"] = { "autofocus_lock": self._widget.isAutoFocusLock(), } def _raiseResults(self): if not self.isAutoFocusLock(): self.raise_() self.show() self._widget.showResults() def getConfiguration(self): return self._widget.getConfiguration() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py0000644000175000017500000003326515153325210026607 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import functools import logging from orangewidget import gui from orangewidget.settings import Setting from orangewidget.widget import Input, Output from processview.core import helpers as pv_helpers from processview.core.manager import DatasetState, ProcessManager from silx.gui import qt import tomwer.core.process.reconstruction.sadeltabeta.sadeltabeta from orangecontrib.tomwer.orange.managedprocess import SuperviseOW from orangecontrib.tomwer.orange.settings import CallbackSettingsHandler from tomwer.core import settings from tomwer.core.utils.lbsram import is_low_on_memory from tomwer.core.cluster import SlurmClusterConfiguration from tomwer.core.scan.scanbase import TomwerScanBase, _TomwerBaseDock from tomwer.gui.reconstruction.sadeltabeta import ( SADeltaBetaWindow as _SADeltaBetaWindow, ) from tomwer.synctools.axis import QAxisRP from tomwer.synctools.sadeltabeta import QSADeltaBetaParams from tomwer.synctools.stacks.reconstruction.sadeltabeta import SADeltaBetaProcessStack from ..utils import WidgetLongProcessing _logger = logging.getLogger(__name__) class SADeltaBetaWindow(_SADeltaBetaWindow): def __init__(self, Outputs, parent=None, process_id=None): _SADeltaBetaWindow.__init__(self, parent=parent) self.Outputs = Outputs self._sa_delta_beta_params = QSADeltaBetaParams() self._processing_stack = SADeltaBetaProcessStack( sa_delta_beta_params=self._sa_delta_beta_params, process_id=process_id ) self._clusterConfig = None def setClusterConfig(self, cluster_config: dict): if not isinstance( cluster_config, (dict, type(None), SlurmClusterConfiguration) ): raise TypeError( f"cluster config is expected to be None, dict, {SlurmClusterConfiguration} not {type(cluster_config)}" ) self._clusterConfig = cluster_config def _launchReconstructions(self): """callback when we want to launch the reconstruction of the slice for n cor value""" scan = self.getScan() if scan is None: return # step1: if isAutoFocus: validate automatically the scan # step2: update the interface if the current scan is the one displayed # else skip it callback = functools.partial( self._mightUpdateResult, scan, self.isAutoFocusLock() ) self._processing_stack.add( data=scan, configuration=self.getConfiguration(), callback=callback ) def _validate(self): self.validateCurrentScan() def _mightUpdateResult(self, scan: TomwerScanBase, validate: bool): if not isinstance(scan, TomwerScanBase): raise TypeError("scan is expected to be an instance of TomwerScanBase") if not isinstance(validate, bool): raise TypeError("validate is expected to be a boolean") if scan == self.getScan(): self.setDBScores( scan.sa_delta_beta_params.scores, score_method=scan.sa_delta_beta_params.score_method, ) if scan.sa_delta_beta_params.autofocus is not None: self.setCurrentDeltaBetaValue(scan.sa_delta_beta_params.autofocus) pm = ProcessManager() details = pm.get_dataset_details( dataset_id=scan.get_identifier(), process=self._processing_stack ) current_state = ProcessManager().get_dataset_state( dataset_id=scan.get_identifier(), process=self._processing_stack ) if current_state not in ( DatasetState.CANCELLED, DatasetState.FAILED, DatasetState.SKIPPED, ): ProcessManager().notify_dataset_state( dataset=scan, process=self._processing_stack, details=details, state=DatasetState.WAIT_USER_VALIDATION, ) if validate: self.validateScan(scan) def wait_processing(self, wait_time): self._processing_stack._computationThread.wait(wait_time) def validateCurrentScan(self): return self.validateScan(self.getScan()) def validateScan(self, scan): if scan is None: return assert isinstance(scan, TomwerScanBase) selected_db_value = ( self.getCurrentDeltaBetaValue() or scan.sa_delta_beta_params.autofocus ) if selected_db_value is None: infos = f"no selected delta / beta value. {scan} skip SADeltaBetaParams" _logger.warning(infos) scan.sa_delta_beta_params.set_db_selected_value(None) pv_helpers.notify_skip( process=self._processing_stack, dataset=scan, details=infos ) else: scan.sa_delta_beta_params.set_db_selected_value(selected_db_value) if scan.nabu_recons_params is not None: if "phase" not in scan.nabu_recons_params: scan.nabu_recons_params["phase"] = {} scan.nabu_recons_params["phase"]["delta_beta"] = (selected_db_value,) _db_value = scan.sa_delta_beta_params.value infos = f"delta / beta selected for {scan}: {_db_value}" pv_helpers.notify_succeed( process=self._processing_stack, dataset=scan, details=infos ) self.Outputs.data.send(scan) def getConfiguration(self) -> dict: config = super().getConfiguration() config["cluster_config"] = self._clusterConfig return config def setConfiguration(self, config: dict): # ignore slurm cluster. Defined by the upper widget config.pop("cluster_config", None) return super().setConfiguration(config) class SADeltaBetaOW(SuperviseOW, WidgetLongProcessing): """ Widget for semi-automatic delta / beta calculation behavior within a workflow: * no delta / beta value will be loaded even if an "axis" window exists on the upper stream. * if autofocus option is lock: * launch the series of reconstruction (with research width defined) and the estimated center of rotation if defined. Once the reconstruction is ended and if the autofocus button is still lock it will select the cor with the highest value and mode to workflow downstream. * hint: you can define a "multi-step" half-automatic center of rotation research by creating several "sa_delta_beta" widget and reducing the research width. Details about :ref:`sadeltabeta score calculation` """ name = "multi-pag (sa-delta/beta calculation)" id = "orange.widgets.tomwer.sa_delta_beta" description = "Reconstruct a slice with several delta / beta values." icon = "icons/delta_beta_range.png" priority = 22 keywords = [ "multi", "multi-pag", "tomography", "semi automatic", "half automatic", "axis", "delta-beta", "delta/beta", "delta", "beta", "tomwer", "reconstruction", "position", "center of rotation", "sadeltabetaaxis", "sa_delta_beta_axis", "sa_delta_beta", "sadeltabeta", ] ewokstaskclass = ( tomwer.core.process.reconstruction.sadeltabeta.sadeltabeta.SADeltaBetaTask ) want_main_area = True resizing_enabled = True settingsHandler = CallbackSettingsHandler() sigScanReady = qt.Signal(TomwerScanBase) """Signal emitted when a scan is ready""" _ewoks_default_inputs = Setting({"data": None, "sa_delta_beta_params": None}) class Inputs: data = Input(name="data", type=TomwerScanBase, default=True, multiple=False) data_recompute = Input( name="change recons params", type=_TomwerBaseDock, doc="recompute delta / beta", ) cluster_in = Input( name="cluster_config", type=SlurmClusterConfiguration, doc="slurm cluster to be used", multiple=False, ) class Outputs: data = Output(name="data", type=TomwerScanBase) def __init__(self, parent=None): """ :param parent: QWidget parent or None """ SuperviseOW.__init__(self, parent) WidgetLongProcessing.__init__(self) self._layout = gui.vBox(self.mainArea, self.name).layout() self._layout.setContentsMargins(0, 0, 0, 0) self._widget = SADeltaBetaWindow( Outputs=self.Outputs, parent=self, process_id=self.process_id ) self._layout.addWidget(self._widget) sa_delta_beta_params = self._ewoks_default_inputs.get( "sa_delta_beta_params", None ) self.setConfiguration(sa_delta_beta_params or {}) # connect signal / slot self._widget.sigConfigurationChanged.connect(self._updateSettings) self._widget._processing_stack.sigComputationStarted.connect( self._startProcessing ) self._widget._processing_stack.sigComputationEnded.connect(self._endProcessing) # expose API self.wait_processing = self._widget.wait_processing def __new__(cls, *args, **kwargs): # ensure backward compatibility with 'static_input' static_input = kwargs.get("stored_settings", {}).get("static_input", None) if static_input not in (None, {}): _logger.warning( "static_input has been deprecated. Will be replaced by _ewoks_default_inputs in the workflow file. Please save the workflow to apply modifications" ) kwargs["stored_settings"]["_ewoks_default_inputs"] = static_input return super().__new__(cls, *args, **kwargs) def setConfiguration(self, configuration): if "workflow" in configuration: autofocus_lock = configuration["workflow"].get("autofocus_lock", None) if autofocus_lock is not None: self._widget.lockAutofocus(autofocus_lock) del configuration["workflow"] self._widget.setConfiguration(configuration) def getCurrentCorValue(self): return self._widget.getCurrentCorValue() def load_sinogram(self): self._widget.loadSinogram() def compute(self): self._widget.compute() def lockAutofocus(self, lock): self._widget.lockAutofocus(lock=lock) def isAutoFocusLock(self): return self._widget.isAutoFocusLock() @Inputs.data def process(self, scan): if scan is None: return if scan.axis_params is None: scan.axis_params = QAxisRP() if scan.sa_delta_beta_params is None: scan.sa_delta_beta_params = QSADeltaBetaParams() self._skipCurrentScan(new_scan=scan) if settings.isOnLbsram(scan) and is_low_on_memory(settings.get_lbsram_path()): self.notify_skip( scan=scan, details=f"sa-delta-beta has been skiped for {scan} because of low space in lbsram", ) self.Outputs.data.send(scan) else: self._widget.setScan(scan=scan) self.notify_pending(scan) self.activateWindow() if self.isAutoFocusLock(): self.compute() else: self.raise_() self.show() def _skipCurrentScan(self, new_scan): scan = self._widget.getScan() # if the same scan has been run several scan if scan is None or str(scan) == str(new_scan): return current_scan_state = ProcessManager().get_dataset_state( dataset_id=scan.get_identifier(), process=self ) if current_scan_state in ( DatasetState.PENDING, DatasetState.WAIT_USER_VALIDATION, ): details = "Was pending and has been replaced by another scan." self.notify_skip(scan=scan, details=details) self.Outputs.data.send(scan) @Inputs.data_recompute def reprocess(self, dataset): self.lockAutofocus(False) self.process(dataset) @Inputs.cluster_in def setCluster(self, cluster): self._widget.setClusterConfig(cluster_config=cluster) def validateCurrentScan(self): self._widget.validateCurrentScan() def _updateSettings(self): config = self._widget.getConfiguration() config.pop("cluster_config", None) self._ewoks_default_inputs = { "data": None, "sa_delta_beta_params": self._widget.getConfiguration(), } self._ewoks_default_inputs["sa_delta_beta_params"]["workflow"] = { "autofocus_lock": self._widget.isAutoFocusLock(), } def getConfiguration(self): return self._widget.getConfiguration() def cancel(self, scan): if scan is None: return if scan in self._widget._processing_stack: self._widget._processing_stack.remove(scan) if ( self._widget._processing_stack._data_currently_computed.get_identifier().to_str() == scan.get_identifier().to_str() ): # stop current processing self._widget._processing_stack.cancel() # if possible process next if self._widget._processing_stack.can_process_next(): self._widget._processing_stack._process_next() def getWaitingOverlay(self): return self._widget._tabWidget._resultsViewer._plot.getWaiterOverlay() def _startProcessing(self, *args, **kwargs): self.getWaitingOverlay().show() super()._startProcessing() def _endProcessing(self, *args, **kwargs): self.getWaitingOverlay().hide() super()._endProcessing() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py0000644000175000017500000002121315153325210026270 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import functools import logging from orangewidget import gui from orangewidget.settings import Setting from orangewidget.widget import Input, Output from processview.core.manager import DatasetState, ProcessManager from silx.gui import qt from tomoscan.normalization import Method as NormMethod from orangecontrib.tomwer.widgets.utils import WidgetLongProcessing from tomwer.core import settings from tomwer.core.utils.lbsram import is_low_on_memory from tomwer.core.process.reconstruction.normalization.params import _ValueSource from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui.reconstruction.normalization.intensity import ( SinoNormWindow as _SinoNormWindow, ) from tomwer.synctools.stacks.reconstruction.normalization import ( INormalizationProcessStack, ) from ...orange.managedprocess import SuperviseOW _logger = logging.getLogger(__name__) class SinoNormWindow(_SinoNormWindow): """ implementation of NormIntensityWindow for orange. Add a lock processing and a processing stack """ sigValidate = qt.Signal() """emit when the sino normalization is validated""" def __init__(self, parent, process_id=None): assert isinstance(parent, SinoNormOW) _SinoNormWindow.__init__(self, parent) self._parentValidate = self.parent()._validate self._processing_stack = INormalizationProcessStack(process_id=process_id) # connect signal / slot self._optsWidget.sigProcessingRequested.connect(self._processCurrentScan) def _validated(self): scan = self.getScan() self._parentValidate(scan) def _processCurrentScan(self): scan = self.getScan() if scan is None: return self._processScan(scan) def _processScan(self, scan): self._processing_stack.add( data=scan, configuration=self.getConfiguration(), callback=functools.partial( self._mightUpdateResult, scan, self.isLocked(), ), ) def _mightUpdateResult(self, scan, validate): extra_info = scan.intensity_normalization.get_extra_infos() if "value" in extra_info: self.setResult(result=extra_info["value"]) else: self.setResult(None) if validate is True: self._parentValidate(scan) class SinoNormOW(WidgetLongProcessing, SuperviseOW): """ A simple widget managing the copy of an incoming folder to an other one :param parent: the parent widget """ # note of this widget should be the one registered on the documentation name = "sino normalization" id = "orange.widgets.tomwer.reconstruction.SinoNormOW.SinoNormOW" description = "Define normalization on intensity to be applied on projections" icon = "icons/norm_I.svg" priority = 28 keywords = [ "tomography", "normalization", "norm", "I", "intensity", "projections", "radios", ] want_main_area = True resizing_enabled = True _ewoks_default_inputs = Setting(dict()) sigScanReady = qt.Signal(TomwerScanBase) "Signal emitted when a scan is ended" class Inputs: data_in = Input(name="data", type=TomwerScanBase) class Outputs: data_out = Output(name="data", type=TomwerScanBase) def __init__(self, parent=None): """ Widget allowing the user to define the normalization to be applied on projections. This can be a scalar or an array. """ SuperviseOW.__init__(self, parent) WidgetLongProcessing.__init__(self) self._window = SinoNormWindow(self, process_id=self.process_id) self._layout = gui.vBox(self.mainArea, self.name).layout() self._layout.setContentsMargins(0, 0, 0, 0) self._layout.addWidget(self._window) try: self.loadSettings() except Exception as e: _logger.warning(f"Failed to load settings: {e}") # connect signal / slot self._window.sigConfigurationChanged.connect(self._updateSettings) self._window._processing_stack.sigComputationStarted.connect( self._startProcessing ) self._window._processing_stack.sigComputationEnded.connect(self._endProcessing) def isLocked(self): return self._window.isLocked() def setLocked(self, locked): self._window.setLocked(locked) def setCurrentMethod(self, mode): self._window.setCurrentMethod(mode) def getCurrentMethod(self): return self._window.getCurrentMethod() def setCurrentSource(self, source): self._window.setCurrentSource(source) def getCurrentSource(self): return self._window.getCurrentSource() @Inputs.data_in def process(self, scan: TomwerScanBase): if not isinstance(scan, (TomwerScanBase, type(None))): raise TypeError( f"scan should be None or an instance of TomwerScanBase. Not {(type(scan))}", ) if scan is None: return self._skipCurrentScan(new_scan=scan) if settings.isOnLbsram(scan) and is_low_on_memory(settings.get_lbsram_path()): details = f"skip {scan} because low memory on lbsram" self.notify_skip(scan=scan, details=details) self.Outputs.data_out.send(scan) else: self._window.setScan(scan=scan) if self.isLocked(): self._window._processScan(scan=scan) def _validate(self, scan): if scan is None: return # save processing result for the one with interaction. Otherwise # this will be saved in the processing thread extra_infos = scan.intensity_normalization.get_extra_infos() tomwer_processing_res_code = extra_infos.pop( "tomwer_processing_res_code", "unprocessed" ) if tomwer_processing_res_code is True: # if defined by manual scalar we need to set the value if extra_infos.get("source", None) == _ValueSource.MANUAL_SCALAR.value: extra_infos["value"] = self.getCurrentlyDefinedValues() self.notify_succeed(scan=scan) elif tomwer_processing_res_code is False: self.notify_failed(scan=scan) elif tomwer_processing_res_code is None: self.notify_skip(scan=scan) elif tomwer_processing_res_code == "unprocessed": # if validate manually we must set current method + value scan.intensity_normalization = self.getCurrentMethod() if self.getCurrentMethod() in ( NormMethod.NONE, NormMethod.CHEBYSHEV, NormMethod.LSQR_SPLINE, ): extra_infos = {} elif self.getCurrentSource() is _ValueSource.DATASET: extra_infos = { "dataset_url": self._window._optsWidget._datasetWidget.getDatasetUrl().path(), } else: extra_infos = { "value": self.getCurrentlyDefinedValues(), "source": self.getCurrentSource(), } self.notify_succeed(scan=scan) # clear flag scan.intensity_normalization.set_extra_infos(extra_infos) self.Outputs.data_out.send(scan) def _skipCurrentScan(self, new_scan): scan = self._window.getScan() # if the same scan has been run several scan if scan is None or str(scan) == str(new_scan): return current_scan_state = ProcessManager().get_dataset_state( dataset_id=scan.get_identifier(), process=self ) if current_scan_state in ( DatasetState.PENDING, DatasetState.WAIT_USER_VALIDATION, ): details = "Was pending and has been replaced by another scan." self.notify_skip(scan=scan, details=details) self.Outputs.data_out.send(scan) def getCurrentlyDefinedValues(self): return self._window._crtWidget.getResult() def validateCurrentScan(self): scan = self._window.getScan() self._validate(scan) def clear(self): self._window.clear() def getConfiguration(self): return self._window.getConfiguration() def _updateSettings(self): self._ewoks_default_inputs = self._window.getConfiguration() self._ewoks_default_inputs["__lock__"] = self.isLocked() def loadSettings(self): self._window.setConfiguration(self._ewoks_default_inputs) if "__lock__" in self._ewoks_default_inputs: self.setLocked(self._ewoks_default_inputs["__lock__"]) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/__init__.py0000644000175000017500000000056414764622416026042 0ustar00paynopayno""" (Ewoks)Orange Widgets for tomography core processing """ NAME = "reconstruction" ID = "orangecontrib.tomwer.widgets.reconstruction" DESCRIPTION = "widgets for data reconstruction" LONG_DESCRIPTION = ( "Contains widgets for scan reconstruction (mabu slice, nabu volume...)" ) ICON = "../../widgets/icons/tomwer_build.png" BACKGROUND = "#C0CCFF" PRIORITY = 2 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9051008 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/0000755000175000017500000000000015153325403025024 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/axis.png0000644000175000017500000000240614757047403026512 0ustar00paynopayno‰PNG  IHDRNFbù¢psBIT|dˆ pHYs77±d£tEXtSoftwarewww.inkscape.org›î<ƒIDATxœíœOHlUÇ?êçi<}OMÇ|Õ¼‰ðÏB°â¡IÏŠ6F‹@Wºi�®BAÆ? ¹1ÛÂ@ÐbÂ…´5‘Ò`TD¬0‹p ¤ªwZ\Ç73÷ÜëÌE=gò|à€÷üÎ�ûõ;¿ß½gî=3 '�rÕ"Ü(T-À�w€7T‹pCWã:€·T‹È7žþ~ kÉ+>ÄY{I±Gt,Õ7Sþ6åš%…Ào<ɸµrò‡—ybšþ*•*r@·R}?c»ˆôÒÕÝŒ{]ÒgÎsPüMz© àw¬Ì38ð.vÓ’íU…º¤èTª.1S®.ìáœqß*Ô¥5 8›&€Ç@@™: º”ª[™‚õ™U«iI¾æ-—³êfœ c\–<ÎØÖQ£–¢2ËÕd\–ãR%Ä`Ї¬õŸïa=ì58s | |ðÞשÝÔ6^€õ äªp8LKK‹Íâááa677imm¥§§ÇŸ™™ajjŠšš¦§§Ïû÷÷÷ ‡Ã”••144dÛooo���FFF¨®®¶�™��ell ¿ßO,³Å“looÓßßOee%‘H$-vpp@ww7Ô××Ûö'‹ÑÜÜÌèè¨ãqÖ××éëëË3ËÅx<.dttt@tuuIッƒÁ`0­eeE"H÷[^^>www¥c"‘ˆDII‰4ždiiI¢®®ÎÛÙÙ9?ÎêêªtÿÞÞ^ˆööv×ãÄãñó×Òq:r©ø|>B!ë™¶ß/_¬^UUE(¢¶¶6§×v͸ùùy�Fß­ÃÃC±¶¶&666Òú/ʸ££#�FE4'''Ò1§§§"‘Hˆããc×Lp˸Ë$§Œkkks��Ü¿¼\QQAgg§ë¿ßï˜%ª¹²R ƒLNNRZzõ‹&›šš˜››»V““‹\ˆÇã44܈SžÙÚÚ¢±ÑZlu kRwoqq‘ââb¥Âtgaáü7²ÔO(ó­}Ö�ˆV橤{Kœyuç?ò{<#‡w½IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/axis.svg0000644000175000017500000001246214757047403026530 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/bricks.png0000644000175000017500000001767114757047403027035 0ustar00paynopayno‰PNG  IHDRrrê'å cHRMz&€„ú€èu0ê`:˜pœºQ<bKGDÿ‡�Ì¿ pHYs  šœtIMEá,›/ÊIDATxÚíÝM¨,é]Çñßÿ©êsî�Ìäe&“`‚DÁ,„¸ *¸AÁ¥ qçF÷®7âV²Žî\7Á•…0.‚ˆ:!ï1™dæöéªú»¨êóÒçÜ[ïU]ÿþ~†y¹ÓÝÕUõtýú_UO?�¹0†™äìÄ3C«lÁR­”ÖÞP˜! 4B@h„€Ð9¡rB#ä„ft&Â\¶Û[m»kŽ‡Ì¤|í•€¹¸sº 8B@hœ®ËŒJ@pTrÂâÆ€ðè'ô`v¿ÿÜÃ?áüpM@x\“×ä„GÈ��! 4B@hô“•€Ð9¡rB#ä„FÈ��! 4BÀf˜™½úñÇ"ä„FÈ��! 4B@h„€Ð9¡1ž€Ð¨ä„FÈ��Z¾ö À\̨äG%àÖé û! ,wúÉ“2‹QýDÂ59¡rB#ä„FÈ��! 4B@hô“›XÄã˨÷û S£’Ù Þ0*9œ3¢S#䄯é*€Ð9¬êôF 05B+#æ0/B«#æ0'n<œ‘¥Ç"»œ±ÏÆni÷×?¼?Üÿnñ2m²Ý–²æTrB#ä„FÈ��! 4B@h„€Ðè'‡M9÷ñúÆö“;7羿»¬?•€ÐòµWèck•ÄÖm}»SÉŽ�! 4B@h„€Ðè' “­ŽBG% 4B@h„€Ð9¡rB#ä„FÈÍôåµWáâÊdr½§¯è«^õ}¹}\¦ç2™\•²µ7'<“+©R’ôý¹Ç2/ol?Î^ó÷í7õ{z®\® ö3Ûº\¿µö*\˜\¥’\•¾¥w”Ô;äô¦¾¨O(—KJ*ÖÞ ðL.S¥L®è/î=ÐmH̽%ý¼¾¨· ¹uäz{íU¸0•޵�éuQ¥~FoI*e2Ù€% o‚NÊ´3«ƒÊ:íùºê³ëSz³YÆ5¹¥%¥Ûzf½O6-S¡�\RvoI˜Óý½œ$y׈“šJ½R¡r@ÕŽ ä”Ï‹3II®ƒöw×v:«´W¥²Ó¹"æfwÿtµ’7§¨&u¹žê.YjÚÜ$Ž·åå$‹«šÓÌ�v÷/aw”t¥\™¤J‰ÓÕEÔ'ª’)Ý ©ŽqeÇh3I%7Š–G%·´ú@)•©RÕ¿’óÒL{=o7£ýfw¬äêÛE·ºŽÇá.7k. %ÚkyTrK+•5õ—) š².—+“n«9ÌÍnÿN²æ®jÇ›–¼²Ô|±q uÌÖµ´LÞ„œ¼]Þ 6"nY•t¿†;ýŠzü•å•$W©úK‰»«+à ! 4B@h„€Ð9¡rB#ä„FÈ}øqþÑÎ?ÑÇÊ9¡rB#ä„FÈ��! 4B@h„ÐÇÉXr{ËÑwîrB#ä„FÈ}pBº9„€Ð9 /ª¹M!ä€Á¸›º„€Ð˜wè«Ç¼«÷^sœo £’! 4B@h„€Ð9¡rB#ä„Fȃðk‡­ ä„FÈ��! 4B@h„€Ð9¡rÀê±ä|ôrÐ! 4B@h„€Ð9¡rB#ä„FÈ��ú2©žcµÇ˜r.?¾Ë"ä„FÈ��! 4B@h„€Ð9¡rK+år™¤+U>d|1¿ímU2>ÙbJIÍxp^Y&YöÔÓì„dæ.S.ãÉ­‚�[Z¦$©ÔA¥’õÞÿ–«P’«””ѹt1u¤YsÄT’¼îüj¶S’äÍíµ‚üÑwËi3ô}¯æJ2eJ*å^ x½$™2I• íz¾~lû]Zû»L®¤ê8²¯e^>¹'ê§Ÿî�ƒd¦ì¶þf/.oýnû82*u-“7§2½xioè§úˆ¤ƒr]M°>ë¾þÜYów]É]ëÅí�¹:µœíü \…J%I7£[,úþž�é××^… s%ÉUéF®ÿÖÿô 9Û)é ªOU�ïõÙ™¬ (WÒ }ÝÚsÉ+ûŒ~N.S¦þµ;F²Gg£'W‰NO¨ÚGW–«¶÷,yU×€–ú.alû]^û×ûØÌÝ’W}÷¸eJ~�,÷bØ»?üsüý==;-O+ ëù8^ÍÝ’2¹õ¾PÉ•^Õ)yÕwÿ�m¿Kk÷úœe^ÖíeæÞlµu‹Kòz¿YïJîÒö÷Wr#CÝ þvßùáXYô~íÈö»¼öo*¹ãí†ÛÊN�Bîø:Kê°ËÛßÓ³±ûŒFpÎè' ´Ñ•œ3*9¡rB#ä„FÈ��! 4B@h„€Ð9¡rB#ä„FÈ��Z¾ö Lïn¼Ý{c¸b!ÍžO²ã “=°ÈÝ”ÉëÑw±$of 0”þ€‘­ûûfCî8Ún3hõ€±s1F=Ôw½×_u§¯ñÊ]…Ä «Ë3S=�¬õŸ;nÂŽ'w;ì4•Á¢Ü»FÛ}–ÉTõŸ±£Ùqþ‰/Ý@%'… 9Ë”ûÞ’\Ù°90ŽÙq"æöhÔêa+š+š™ãúÍ:BÈ­èxàXÆÌ¤‹K½«¸ÛÊÏr%ÖÞ€ËÒÌ>víû»©zº"äVÒÜlØ©ìÛd˜Š™2I.ï~âjII%UÝòŽ×­m§JêsÔr«©cÎÝ®u~½CY.óÎõ˜íî?—“×¥YòÊ®Tô¿ŽJÈ­Èžù É^Ó/ë NVW�é‡úO}G�O]Íê«§öiý‚ž­½ú&Ó{úˆöºÑ×üƒ~/%äVÒœ®&¹þ]RFÌ­àGúÿçcEÝöä{ý¿ /éCk¯ü…)u¥R¥r}NóÌ'\?¹¦‘LÒgôLtIXžëÛúh}»Ë!s츭LoèúôÚ«�*•ºÑsÿÉÚ+2�p?ë²d™ä…ʈ¸U˜r¹—’™e­OnÚÈ]•2길L»ú2AÌ~ŠáBΫ%7ýä–VH²æ"A—‹Ù&5§¬•âŽøÒJ•*%q;ï„;]•šråÍ?^c8k¹$“If=ö}2©R’h¯…km�Wð… ¹ÛKÝ¥n”ׇT)éÐÔsÖ¹2«¿˜ŒöZ\¡\uŸÆ,æÉjÀ�«™)i÷»éŒ%IÙí�ÓîÞ�¿Ì9]]\�¦óΪñšœ7]Žõ–UÉUÕ#Zt½·jɬùÅk¸Ïã&ÜŽÔc!÷ÿæ+¹ºÄ¾8Ýž®fªÔzwKê?²ÅݳƒÖgÍ•äJªn¯g"¹£–ÙÆ rD€—Û|Èq^eó!¯,ä¢öô0T¨�#✠rD€Ç6ßOî· Î ãüâªäà1B@h„€Ð9¡rB tw2£’•fC/9¬Í�J@p„€Ð9¡rB#ä„¶úÝÕÓ’¸#`JTrB[½’›§rkêC†Ñ\ãÉáPÉ��! 4B@h„€Ð9¡rB#ä0zÉárB#ä„FÈ��! 4B@h„€Ð93[`”·¦‡ý´VµDKm¨ä„FÈ��! 4B@h„€Ð9¡-rîŒ2v)héM¸×›1fÏF*9¡rB#ä„FÈ��! 4B@háBβ¦·�+‰å–w�$e’™åíO·¬þ§™»LÅÚ«� I¦RÛ­½*ór^JÊÌtP¥±ˆ�*I…äî…µ¾*Ë”yé.)W‡XÄÄr’r=óCÌîÛ?TVfÏ´WRÀ?s•*™’%¯$¯Úžî®R’,÷B7Úk¿ö\˜$W¡¹>�êV‹fs!wúÓÓïËT¸KfúŠ>¤Ä ëÂ’ ýHïze¦äeÛÓí™öušéûúª>¶ö\˜ƒ®”ë…\¹™‡¼\`[Ë€Ö�K^Iví{{®1Ëïsfæn¹–dònuAý|¯šz‹²kß›Iî–©ŠxÄl.ä:oXî…e핦eæ.õ;\š×\«òÃÚëiš/—�îjêhÂ…œ™®|/™)ɼˆ9®Âùr·�Jå~#Y®²í°±� eòúëÈ2¼&tÖÌ«ú*¶—ǯ›hÂ…\s”¼²�lGm°¬ã g÷KØM×é ¦fæ^1R—E[0äà,„FÈ��! 4B@h„€Ð9¡rB#ä„FÈ��! 4B@h„€Ð9¡M>‘MÛ cŸ¿öúNøÎiØ …–ɽ:5q$×^{£eäç±ûçtýf¸ðf¿· z|}Ój!gÃc‰ã�A3{{P™I2Ùñ£ß4ÜzÔc™Jå¾rù#Ìš}÷ß$û»Çò?ÞŒ[¬û_*Ç?wÚâ¤\‡»×õÓwLmî÷Ÿºýž\Ó/÷Ó·Qiù¶ü8¯A?ͼJÍt1^NýM8÷A4ue?64»=þ¸b6“u©Êî¾Æ† ðýLgêö{ò=¨äú™ ²0yÿzàöõÉ+»òÛÉŸš¾�JîÕ¯zuí]Zýß^Ÿ²vÙ[Í×Qî…df¦’¿>ÓWr§Ëkk־ϟZÏ÷Ÿ¦²°L:ÇåƒZ.×Impq•\Ë­³ÓjklèݯáºIY&y9èâDôJî´ýN–O%·‚ѕŕLjªç»ì½W~óòyMϾ’ëJ=‚¶ý1øôµ.ªã ‡ºïrãÇžûÇmñêQû´|ɶV.c‹„±ïßwù§o×vã&½úùÝ*¹×{®ô¥ë[™ž:¨¾i %ß8hcÉ+û°JUÊ”TN^ Ï}:4ueß¶¾ÞòüöÇ­ùÿ¦R™nÜ�Õ\§�ÛùÁ®ô†ÞWÒN}¿Ô6v¦3zù§ú¶ß“oñÎä»%¶¾�òøñ�JUÚé]ý�yÀ |F­�è™öªôüÑA36¤Î½´ŸúrHûòLÞs˜ö[_*¹nK¬§È<Î#KÀ³p¿±L’Üí™Ý´Í¦Ôö¡á*Q?u`Ù3^ÔÓ·¼ZS?ÔSü]û‹µ×?ºG¡ŸäÇ3)bĬäši—¯ë­Ö^›Kd™ÌëéSû,£Íå…\ò¢ž8{íõ¿4–)ùÁr/ì¹ç… rRS}]éËzM¹ú6Úéé[Éõ}ýÜï7öñ¾®´×·õ%}]ê2u¶å^4Agú%ý±>ÞóýÆîß±ÀØå�mï±Ëw¹LÒ�þ êõ뀧«–¼2S©ßÕAד/~êÐû|µ¼~é�sUzOÛõ›’’*˼´�ê·õÑžïGÈ�[¾+ÓAI®"êÐ^C®9¼råº}ÈbˆŸÔý/;߯+%/Í”+›ák mr¹ å~ˆyzÓ�e  ! 4B@h„€Ð9¡rB#ä„FÈa6;–t¯•b¶! 4B@h„€Ð9¡rB#ä„FÈm¥�3‹9rî£�q¨ä„FÈ��! 4B@h„€Ð9¡­rÞanõ6fô¶;o1G' çÞ1´þñôp ¦YŸ WrBÚm8äˆ9í6rÄ€69xµÍ…Üú—FlÉæBŽ˜ÐÇCŽ˜Ð]¾ö ôÅ­†í0£µÐÏÃO̽i7ZÉ@W›«ä +w*9ÁrB#ä„FÈ��!\¶{}Ñbök$ä„FÈ��! 4B@h„€Ð9¡M> IÛ€–S÷Ä9}¿˜=}¶‰¶À9 ’Úä•ÜÒßÞT ^…J@h„€Ð9¡rB#ä„¶¹Ùºè·Ì»Šs@% ´ÍUrÔú ’! 4B@h„€Ð9¡ 9333É’%w%åâNìò\R¦$™ÉÚŸnIR2³ä®jí•¿H¦J&SaYÛh�Û´¹.$/çÞ4QR))Ó×ô–*œ…å:è[úÀ’ä]ö½Krw¹™Jý‡Þ^{.L¦ƒL;ýX¯û×^™yX¬b§Ž9wKÊõkºÖÚ­½N&©R©ñÿ³L®äE—™)yiÓ¯([{.ŒË$•rý£–wk¯m r’e^ÖaG·áµXòêøÏŽÏ5YýoZmiuÍm¦Ü„ÜFX’yi&i§J嫟}zPM=GÅÖkÛwý-—¼°\•¼Û¶šIMÄíT¬½έ½æž3¥) 2Ukoé|6r�¿û-Õ'ITk«¿n:=3ëö«L{¥Ù?ïc÷Ïøý5ïú ØžŽ—O1!—ËdzW©¿êëÁ>«Ò'›%M28å·û¸Ôûúœ¿Ûœzvš‹ÎÌÝ®ôGúS}JR±üŽà¦öÒ*™’ I¹Ò€ˆ»Ö�õ†˜2{ •z~üC·SVwIåºR¥’ˆ[!·´$W}WÛäý¯xù^ÏõBÏ$qEuõ>vI;¹ ɬ¾¢Úë¦O%Ó ýÑŽ�! 4B@h„€Ð9¡rB#ä„FȃôìãX÷iä÷E+ ä„FÈ��! 4B@h„€Ð9¡rÀ L!´„€Ð9¡rB#ä„FÈ��! 4B¤ÿœ¹X! 4B@h„€Ð9¡rB#ä„FÈ��! 4B@h„€Ð9¡rB#ä„FÈ��! 4B@h„€Ð9¡rB#ä„FÈ��! 4B@h„€Ð9¡rB#ä„FÈ��q_{ Ð ! 4B@h„€Ð9¡rB#ä„FÈ-×÷Nþ��üylo ky¼mùS¯Oßõõž�·/?é éJßÔ~Àê™nô=IårÙìûc¬¥Ûož-p™¤½Þ—ÛΖ¼’Ì:÷•{¡ïÊ”i¯¼eÿ´Y{ÿ�m϶ãi†÷Ïõw³ï–ËvÚ(•’\I¹¾©oôïPêný½Þ’ËTöþˆŒÿÒ™z¬}Ðv[ãJI¦ƒözOÅíV$•­/®Ï•¾¡ЛکX{c.‘ 8LN—ðPߤ^º’›ºRë¹<¯î=”IÞz˜œ,.÷Â2/ëÃÇ+;}ÿ±íyªïöO½ü±Æ~’Ü+3%Uî¶óCÝ ’eªÚ¿¦,yeI™${¼·¶ö¥3öù+lŸ�ÿi,õ)ŽÙðŸÕ‡ÖsürªOZ[ž›äu[÷8¹Å¤r;½õ0¶›º’˜ÚÔ•Ißnf¥»»%3™ÌûŸÀTÇÃËr©ý„iesŸžÎ¼|w3™üÁ¿¥ªó{Ùm^YùDk�=¾–ÞŸÛ»Ü@%7µÓ’§¾½-WUôû»7§ªY}ËÁË.ï·ôöESoóqK�U¸%y·­ÓÞ��›Ù£«0W*¼”Ìêk=ƒ–™”¼¨—Ñ÷š†¹»Àp{ÁÁº´Þñ”Ö2™Lå°Ç¹�<½<ýfêûMßöþmË»¾m¦®\|\êÐx²ä•eÍÁ6{Ä�{å6÷ú=Q{ÕÝv:Eœä•å^˜ nížÇÇøí�wùk¬•Ü`Obœ3~ñ0ñl•Ü(\HÎ! 4NW„FÈõ4öî.€er½sÀ–rsÀvpãáÜ;Ï‚�§«B#ä„FÈ��Z>~pžÌ9`º�œ¿3éB2fb—ù×ì\× @;®Éu@ÄÛEȵ"â€-#äZqÀ¶rB#äzaü`k6×…dÍ[öD°=Tr�qÀ�I?9˜•€Ð9¡rB#ä„FÈ��! ´³9³ÇpOÿß«þÔ¾t:øÑ�uÈÍ‹ñE€KpÁ!GÌ—à¢CŽ˜â»ð�ÝÅ…·€Ërq!GÌ—åCŽ˜. ãÉí"+9—ƒ�! 4B@h„€Ð9¡rBË×^�í¨»ó“~à<˜u;©ä:#Þ€-"äz æ€í!äz!怭!ä„Fȵ`Ä`Û¹Vİe„\İ]­ãÉ�àc/½O½¼s񵧾CoFœ¢’C8DîkýÅÃÔ>€˜Ÿ0Ü1ãg]†ˆÃ}Ž�C`Ü!‡Àˆ8H\“CXDêOó®>‰o@œ®��! 4B@h„€Ð9¡rB£Ÿ€Ð¨ä„FÈ��! 4B@h„€Ð9¡= ¹ãPƒfõÿ=ÄË^{÷ÿOß­ýýìV—wzùû¾ìù¯zÆ�}1Íþ³”qï<Õ¶ ÝîñkÝï™]>Kî�¥½úsßk+ú~>¨ä„öÿ<4Æ+‹:IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/darkref.png0000644000175000017500000006041515153325210027152 0ustar00paynopayno‰PNG  IHDRxe†,'—sBIT|dˆ pHYsÄÄ•+tEXtSoftwarewww.inkscape.org›î< IDATxœì½ixTUº6|ן>Ÿ��.—ËcÈ9r—Ë�ö›ËåÂårA 0ã‘FÎs8p¹\�LJùm¤/ý7p8¸Ýn�‹t¹\L_§Ó ‡—Ë—Ë·Û §Ó ·ÛÍô#×°?¤�Óé„Ãá€Ãá˜v ™�ô#}Èq£Ñ£Ñ‡¥RÉŒét:™û8ŽiÇèoz\‡Ã»Ý‡Ã«Õ ›Í‹Å“É„òòò)€ÿ³F€âñx … ˆôo6°4èäZ9Îáp¦§�#çÙ’¾ôorŽ46Èw:Gƒ@o,ù&ý=�Ãá€Ífc6š¬À4à P‡ƒ!p»Ý�@©T ‘H‰DÂÌ�ÌÃáp€Çã1¿Éý9ìv;Ó×f³1 c³Ù˜9Ûívf>Ó& ãp8àóù …àóùÌ7ùMs9ͱ|>pä89F€¥9™ 4û8 2 >M47‘FîEÎÑßž¸˜n@²7äo²'4�ß<oÚ9šëÜn7œP(„H$b¤ 9OÀåóù À4±Ðý¹\.3?²'¤Ÿ@ ¸`.— ¡PÈÜœÕä8áV67ÒÏŒ ͉l=q=ßaZ°`�îþûï‰ŠŠ²ÒœKoô­þ·Už|Z‡ƒo¾ù&¨¨¨ÈŸ>g4ù«W¯ót-íf�qèÍëêê±Çûwš···mÕªUûvíê“H$.šûh½L7§Ó‰ÖÖVYyy9s¿äädÃܹs§]GKºY­Vî¾}ûâÛÚÚ|©}q/]º´ÍÏÏÏ<99 »Ý£Ñ€2²Øã� ¦·9n{{»¢½½]qøðáðÅ‹�<ÿüóÝ!!!6v_¢Øâ†&B¼ÂÂÂÛÀ¨®®öîììEFFZ�_@õ¼ 9Šþ'mllLxìØ±°‚‚‚€×_½!66ÖâéÞtóšÓéÄäää´@ ‘6´‹e6›yüqBww·7µw®+V´$$$ŒZ­V8˜L&èõz·¦Åç�Ü"ÒÒÓÓµ2™ÌA»&‡ƒk6›ù‹…×××'3™LÓük—ËŹ|ù²ª¬¬Ìïå—_n¹ï¾ûtÀ/¶aFÛ´•ÌápðÝwßùY,–éŽ/¦À:räˆêÅ_ì¥õ3mý»-((È’””d`1f³™?44$îë듹\.†FFFÄÏ?ÿ|òßþö·___†Zîdõ³çb·Ûa³Ùß™››Û>6999-\I¤cAÓ>0ùfsò¯~õ«ž3fXˆŸLb”öövIAA�ÏéÓ§ƒ†††$äZ‹ÅÂ{ùå—ÍfsËÖ­[GˆA$mØñù|fCÈFóx<|÷Ýw�d<¹\îP*•Ž��1œ>}Zõûßÿ¾—J :‚D§³[bbâøk¯½ÖNU„#�N'DŸ|òIDYYY¹fllL´ÿþ°½{÷v‚~ ‰þW ߘí;�NhµZÁgŸ}–¬Õjeä¡PèX·n]ƒZ­6NNNNó™o�ŸÚS`ÊM’J¥�Éd�ÉdÌo¹\~K¥R( Èd2Æ­"B,ñ¤¤$ËîÝ»~þùçÊgžy¦](2+r»Ýxë­·â*++åž)l©A@cc£¸®®NIέ\¹R›——7Lþ_ºtÉ‹(!Ú;ÝçNRŠvmˆ�H‡hÃÃío¼ñFËÂ… 5ôuW¯^ t8\¶AJÁ£ö�v:�ýýïO¡Á•H$ö‡z¨.""ÂÈŽ)�k ƒ0K$ÈårH$Èd2曽xB ô‡o’8­H$‚T*Å®]»†¾úê«›b±˜‘K‡ƒóÒK/ÅŠÅb¹ž®xŠŽñx<8p �憇zH³eË–zÃŽ9HƒBƒDˆ…€P(d2htãr¹ ÁÒ’�-Ýž~úé..—ËLÈn·skkk4AÐñ|Zê±ïçÉCéïï—|òÉ')z½ž‘‚r¹Üú«_ýêfHHˆ‰ìqo‰�BÖÊL§I�,ˆ 0Íž6L"‘@"‘0€K$,Y²dâ/ùK+=Ngg§ìèÑ£~ô´¨'�2¶8ùùù*r<44Ô²dÉc\\œ5--Í@Ž_¾|ÙO¯×óh=F«šé„ {ÃÙ’‰ý[(",,Ìi¢¯‹Åb†ihÉFß“n<�Ÿ|zzzdÿûßSŒF£ˆôóññ±ìÚµëfhh¨ÅS±S¼ À¤±•¿'+� 8½yt@ƒlYضmÛFgÍše ¯ýöÛoƒØbèÑÏãñpæÌo­V+$×Þ{ï½¢ï¿ÿ~FTZ­VîÁƒÀì¹ß)òF7Ât�þÐÉ??¿i^�ÉdÐçiB!`xbBb±­­­Š¿ýío3Íf3#ZMO?ýôMµZm%c“ùÜŠGL &1k¦;çt0ÝSú�$—ib ýfvø‘=¿þõ¯è±jjj”:�ŽïIϱÅÚ·ß~Ëp/‡ÃÁÃ?<6› ëׯ¥UÀñãÇ™¾ž O¿=�L[ù´è¤E¾ÝnŸ†–P(tÓ\D8‹V]ž˜„p}mm­×û￟<99Ɉ•ððpã /¼P§V«íD°9ÞÓ1`Ú¬&�j›Í»Ý~Ç)½)žŒvLòòòô´Áåt:9W®\Q°E';Ù¡ÑhøEEEŒcŸ‘‘aˆŽŽ¶"“Ëåά¬¬Qr¾©©IQSS#¥ •&`»Ý>-qÎ^#¦ó±žZWW—”þ;44t’­Øz˜ 0ŸÏ‡H$BQQ‘ï;3d³Ù>cÆŒ±×^{­ÞßßßÁ–D%ÊårÆ8&*’d“€‰ÿD¶ÛíLN‘ ­ßh‰Èd‡ ˆÅbw||ü=ÞÍ›7¥tЧ�íß¿?€æ”õë×kè�'lܸqšE{ðàA &!ÚÉÉIX­VæCÖ̘M´•K>gΜñcÔ—ËuÏ™3ÇHK2úö¨©ëðã�?¼÷Þ{ ‡ƒYgzzúèŸþô§F™LædÛ;Ĉ¥í6'·üàÉÉÉÛ,Xâ�²)—æÒ�î“ß´©N/jÆŒæ›7o2®ŽN§ÐÂNj˜æûŠÅbç¦M›FÉÆ–-[fð÷÷·jµZüüóÏ/½ôR7�Çs“±è¨�˜ð0;[CÖN޵´´HÞzë­Xúüܹsu���6z<“&÷¡cꤴµµ)éã ,ÐüŸÿóÚø|¾›H:+GæÃŽC…BØl¶éɆÉÉÉi);BqžD´Õj�&Þè m�z²].”J¥ƒ>®×ëùôf¿ä4ù|>ŠŠŠä­­­Œ˜��=êååå¤ÓyŒœœœ‘C‡…SaÄ3gÎø¬]»Vç X²Aô7µF®F£á³×>11Ámoo—\¹rÅ÷Â… �V«•Y¤B¡°ïÝ»·“VOtÉ 0› Z[[•ôßK—.|úé§;huÈÎ\Ñ1kv6‹6Ž€i‹•p“'j#U{Ä•r»ÝŒn!\Kë’ !D£P(¦­N§Ó űs³n·PÑý|ðÁzn·›ùÁÔ€àäÉ“ªµk×êðŸ4Ok,** ÈÉÉ ¸Ã%·5???ëÿøÇÆàà`+‰kÓ"ž–´ô»S3›Í<›ÍÆq»Ýn:BEMÔQCtˆò¶P%©B E$¡ 6u“’L‘Ht[†® ±Ùl·äq¹ÜÛô:—Ëu“{D¾M&7??ŸÙhÛêÕ«ÇØ!D`Š“SRR,ñññÆææfTTTø ‚‚‚ì´(öd;üOš———-77wࡇ’ÉdNn$cÒãÒÜ̾ŸŸŸßäè記ü}ýúuÕÛo¿�§žzª €›€H[ÿtÙ¬Ífcì(âå�{q0T@S¹È“ÁÕÃÅb±0@>‹f³&“ f³:�nZTA.—;ÈÄhcÈn·ãСC¾F£‘韛›«ñ.m7Ü{l±åt:9ß}÷�Š–Jô7[�üw›Ñh ˆ].—›ì Û0£E6� ¡[NNNÿ’%Kécåååª>ø –ì $9FöŸì}Ïiùà;8žüCÒõ�Í%\H[Á´n&:666 `•JegÀ”Î>räH Ý÷¡‡Ò°Ódά͛7kÿú׿F«;??_õÌ3Ïô“1H"Ÿp‚§`ÇìÙ³u�>úh/}£ÑÈݼySYRR`·Û¹·²dA�Füæ›o6…B7Ùz~ô=î”ÕúÍo~Ó—/_V“c•••ª�>úO<ñD+›`h ë Øi_�øc´CΦ6¢«ÙQ!6@ìä7¼­­mZñ@HHˆÝíþ¥D•ŒÑÑÑ!ª¬¬ô"ý¬½½½¢¾¾>Ù8OQ(—Ë…¨¨(sKK‹zzz¤åååòyóæMеO„=å‚•J¥}Ö¬YlÃÌåraݺuš¶¶¶þ—^z)I«ÕŠ ±±ÑûÓO?�سgOp{¥)»:„- �ïÚµ«Ãår¡¨¨ˆ¹ººZõùçŸcÇŽ­´Ä!î¨'ƒ‹VLM1šèú¬;Æé84;�Ìž4‡“ÉÄëíí�P«Õ&bÅ8<¨bå\EO<ñDòmÿíÈ‘#� .œ  Ò†Y{�„¸=I²¸¸8Ë믿ÞðÔSO¥Ûl6.üüóÏ!YYYºùóç�{â$²žTÙG·Û�'Ÿ|²Ãív£¸¸xÈû÷ïÇŽ;Zi[‚ìmÓ½.€iŽ2  …·ì)EÈŽ�’ “PIdäççû9�Nf@¡PèZ°`�‘΄�M¥ ÿÛváÂ…«ÕÊegƒ$ “ c7öStDФDï»ï¾>Òßívã³Ï>‹öve{ž¤"�8ؽ{wÇâÅ‹§é䪪*Õ?ÿùÏ8¶ A¤-¹™#c°¿d3è'î¤iN§Ó|ž>tFŠÇãáèÑ£Ó ÛfÏž­W*•.vÂâÊ•+^ƒƒƒb�ø4³ÙÌ;qâ„=g:8Ïæ(:áA¯ƒD�È^=ùä“ý*•Šq zzzdùùùìp+íExÊ?“Mÿ ȱtR‡ŽqÓÉ�ie³ì2N:àÁnl‹”½:ýF§ê>ýôÓàîîn=Ö¶mÛIÕ=æ±cǦqï믿ÞúÀ0e>dSØ)­+kjj$6lH%çþõ¯©vìØ1BÆ E¯§ ‰DÓž  ¿IÐF$¹¶oßÞóæ›oÎ ×:t(lݺuZ’'fÛ&žªHèøÁ\.{öì¹M\WUU8p;vìh#Ò€m+9F*ÝöðÑ·j­à©Ñ:ŠÝØÆŸÏÇ�?þè»oß¾Hº_FFÆØÚµk ì¸õøø8ïòåË~¤ŸD"q>úè£Z¥Ré¢û±ƒ"4òw`` 1**ÊÜÙÙ)€ÊÊJïöövQLLŒ•Ý×ÓúˆÚ F"ŠvÍ\.6nܨýúë¯Ã$088(9qâ„ÿúõëG<�y'׌MdĈzê©§:L¹¢¢"{ì±6š$Ï0‘à´|0; Áޱ›'ߎ}˜�¯¾újä /¼�Hë^¹\îøë_ÿÚNëlòûðáÃþ“““Ì.,]ºtÔÇÇÇÅ?lu@K"YòòòFè5íß¿_Åžû�•^›hi—„Ãá¸~øá^úºC‡…9�N-eî”h çç©�-Z4D¯¨¨üâ‹/bÙýo3ŠÉà4÷Ò¾Ö�&BG�hý¢×ëù/^ôþýï½lÙ²¹ÿú׿BèqÄb±ó³Ï>kLLLœd×J ;vlšï»yóæÚP¡ƒë´îö´y[·n�VÎsêÔ©@zî”TÀH¶‰vC茚ÓéÄ}÷ݧU«ÕríÐÐ�äĉ´›õ_í)»š’ Øo~ó›ö x9†¨<å·™ÂwzÐ;¹:ðÁĉÅb'�È·ÛíLÙ,©¶÷ÔÔjõä'Ÿ|Ò¼pá öc,\.µµµ’ºº:¦,ÔÇÇǾ~ýz§foŒ§cdCãâ⬩©©ã555J�={Ö+''Ç@ƒÆ6(IÊ”MÌ$¤Ë¶ºù|¾{Ë–-½ï¾û.£‹¿ýöÛÐ{î¹g„sëɇÿlÞ4°´J`?¼sçÎv—Ë…²²² rmeee�ÃáÀ† Úi‚œ–l`‡ðØ¿éÖÙÙ©À³)•Jû¦M›_xá…~™Læ"É Â�ä~ÿüç?§qïÚµkµb±øŽ�bZ�ƒˆž¿ËåB^^Þ:¸råJ›#Ù�&`ÒˆñC+¨ˆöàÁƒa¤LxxxXròäÉ€uëÖiØseLσŽ7Ó “ò#�<Òîp8PYYÉ€\[[ät:q÷Ýw3 [­V”›Dë.OyàÿNãp8¶,]ºtä�7Þh.++«xíµ×z …‹Ïç3Õš,)À9qâÄ´ Î#�<ÂÄ•=î=U[ÐξËå–-[´|>ŸéPXXè§×ëyì1Ù�v¡è\+]�IƒÆápÜ›7ož¦‹�=æp8 ¹Srƒ�ÒE ìØ3)lß²eK{jjê4q]__têÔ©ú€‹&ú�X`<™™™£Ñ8Æ®P œ"‰Ür¹ÜéãããðòòrªT*ÛìÙ³M¾¾¾Nvޙ܋Ÿ€îîn!¡vgªúcñâÅtú�ín�o:œÈ~,ÅßßßñÜsÏuöõõ IŸŽŽQjjª™ÁŒ3Ì>ø`355u‚ ˆ'}JÇ„àÞ{ïÕvuuIhPûúúD“ô8·ª@Ýd¼¨¨(“Íf›Æ¹4÷ÒùwrìþûïoW*•‹Å" UM¿ÌËËËDö� øw¿ûd2 Ùa—Ï’ßìô4ðdü0ØÔ5´BýDA£Eä�’!ôFÓ®ÍV‹…g2� ¬fŸÃå¹B±C$‘ÚܸÝk`JÇwÙ ÒºóÚצE0=�j%c±ãÊ´ˆ&6€Ó9õ,“Åbaž]¦³K&“ F£ùùù·'ØV-Í…lî£ÝZ�Ó`ÐÁº‘Ð!d“Há€'pÙÁöut¶fL7"j­.ìéð³L%`5—ç’Èf¥¯¿ÑWª÷S‡Àá¸ØãÒ[Ó3D4`ì9Þ)!@s [ÓàÒÄKCt�ö�fd.¥ë˜ÙœJƒË.Vgftš ¾'k˜æjZ�¾äámh`‹ÎÛŒ$— Õ× C[j*ÂÜ.§gw€Ûåäš�cr³qL>ÔݦVú©ô –5ÐxÁÓ¿ï ¼§kØÀzúx*Ù¡¥;~Á<|FWƳ�sOº—ÇãA*•2\H¸žD`Ø„áÉ*§Ç&Q#8ÝH”†-¢=õu»Ý¸vátTWÓÍiqop8�Hd“B‰ÌÊåñœvû¤Ðd0Hip9�öæÝ `º�§ólk™îK«¶.§¯ñ*ûÞ4qxjL¨’Þ(zÓïĽÀT-Ñ™J¥R©###·Ý„L€6Þ<�ÎÎw’¹Ðn ½Bdî.— ½m�ÞlpB"FSîÊî’)¼'Éæðx<˜ÍfŽn¸_®éíôíï  ˆ¸Y侞\#¶Xes3½6€4ÈìZ-ZÓãÒsbCè ­*ùôM0‹§�‘ͤõ&=8hµÚiœNÞEAç‰ ’ÞHºq¹Sµ[N§2™ì¶s.—‹ÙB dÑMÕåjºHTÜÈ¢5÷·8)C‡è}¡Pè7ú…™ÝzÍ€L,{|½Y'!(O®›(< .[4{:çÉ•£ PzÏi¦$�`Z]Ün·O‹õº\®Û*% xôÙ4!6·±N'úI#ýé`z¡ô9>ŸƒV3­b$eþâ>.ŸÎ-c�=§[z·*$b‚¬Íívƒ¸.äCÖFæJ;1As!éK®%ß´t ë¸Á“}a»˜lIÇ&>0U)I¨’d'<óiëš¼ÈÌ“ÛDo„§ÒY:˜B¿u†l %½H¶qA)•{OŽëyXz «CŸ6GËÞ8²&ZŒ²Å$-YhÙaNú8I^�ýØ ™#ûC‡ViõÅ&.2\¶}ÄöR¦=Ù@ðÔ +ÈB˜¤²±M‹(À�H$Œ¤p¹\LÉ!Z,Ó¢’6"ØV&M±.— a1ñÚúŠ_®-)Œ�žaKev¶n¤³}x6Wéy¤-oúÁ<²6Q°-bšh" �ö­Ùz—Ûìˆ!ðlŸ9sæƒèì  uÛ'e7² ‹ÅÂLšˆnú¥šl¿Ð“ÏIs5Í)l£ÄG¥6u4Ô8ìv>ØmVþ@W»2,6a”ÃáºhÑÊÞ`öziIK+rž�ƒ¦¥Û§'ƒý›¾–†\K¦ä8-mØ®½?MMMS¡ÊÛ�ù¼ÅG…)vm^—J‹«áQ½éï�׌¦ÿÙ;“þm<Ûy<bbbðÒK/áæÍ›‡D"ÁÌ™3‘’’‡Ã�±±1¼òÊ+Åèè(ÒÓÓ±jÕ*ÄÇÇC.—#)) :�Ë–-CGG‚ƒƒ±nÝ:˜L&<öØcèèè@VV“É¥R‰]»v!,, þþþÀøø8ãS;�Nøøø`éÒ¥�ËåÈÎΆL&ƒÉd‚ÛíFbb"Äb1yäTWWC$aãúûy³â#"¼òiå¹r©D8/-É/8*v¬¾¡Éáv»‘‘‘�””øúú",, �?þ8æÍ›‡ÞÞ^8�N|üñÇ(((€P(DTTV¯^�èèh( øúúbbbIIIˆŽŽÆƒ>ˆ´´4,^¼ÈÎΆÍfƒD"ÁC=Ädxþð‡?`bbééé°Z­xòÉ'a2™099‰´´4„††B¯×C.—#44:�ÙÙÙ„ŸŸd2fΜ‰åË—C«Õ‚Çã!11III�H$ˆŽŽFRR¸\.t:ÝÀ^^^ˆˆˆ@gg'…Å‹£  ƒÉÉÉ0›ÍGTTZ[[±hÑ"ŒŽŽ"%%qqq8{ö,Ö¯_Ï<„<<<Œµk×"::ü1l6æÍ›ƒÁ€øøxh4LNN¢®®ÙÙÙèîîFRRFFF�››‹ÆÆF æÓÑÑ�œœDGGcbbÙÙÙ0›Í(,,„¿¿?Ò“ãå‹’cRü¼Lþ×ív»9·XY(àóý¤BžX6¾:w­�¬588f³999¸víšššàç燓'O"{ÉŽHÀç{)ÜkW¯r�NgëÖ­î��Ì�;— îH¥Rœ:u ¯¾ú*är9Ìf3ÚÛÛñòË/ã/ù 6oÞŒÖÖV¸\.\¼xÙÙÙÀåË—‘ššŠ��hµZ„‡‡C­VcéÒ¥‰D DTTBCCát:1cÆ Œ��£ªª YYY¨­­…Ùl†P(Ä}÷݇ÂÂBddd §§ç€ ð Î IDATÅb1}ôQ`ûöíèééÁùóçˆU«Va``=ôΞ=‹ôôtFµµµ¡½½===HIIA{{;†‡‡QYY h4\¿~ …Äðð0>ýôS|øá‡˜?>FGG¡R©099 ½^�ÑÑQäää ®®ëÖ­C]]îºë.lÙ²§OŸÆO<�÷ßpýúuøùMÕç 9.Ń«—ÌðyL¶¡³¯¯ ¼®#1:—Ë!‰/&40 º¶ÎÂJ,/^D]]¬V+d2Š‹‹ñÅ_ ¤¤`�S>zߪYÉÑ¡¡Ùó3Bý½’Ó.k322ÐÙÙ‰ÔÔTÔ××£¼¼‡jµÅÅÅèèèÀðð0�œœŒ .`öìÙ¸qã–/_�N‡úúz( TWWc×®](..Fnn.!¬¯¯Ç�7044�Fƒ––hµZˆD"ðù|´··#,, J¥n·gΜAdd$ôz=l6FGG§þO=õ***0gΜ9s---�ËåP(x饗ÐÕÕ///Øív( 455Ájµâᇆ^¯Gll, QÎãñ T*¡P(˜ÐöìÙ0›Í8zô(\.ªªª V«! Ñh�˜˜ˆææf¢²²€X,ÆÕ«WÑßß§Ó‰ÆÆF,Z´k×®E||<ŒF#Tþ~‚Gî_�Àãq¸¤ª¡ëhþÅî¾!�ùóýX«Ÿ`Þ†Ã¸Ëæ¦$Ü•š ÎÎÎÆ¬Y³p×]wáøñãÃ?þñÔÖÖNI¡Õ«¦Õg�[¬*• V«)))�J¥ÈÍÍEBB–,Y‚?ýéO‡J¥Â¢E‹ÐÑÑ�€€„„„Àårapp×®]„„„@£Ñ ..n·���(**Bss3~øa�F|úé§‹ÅàóùHJJB||<†‡‡Ž�� !11]]]X¸p!RRR`4þ‹cžP°Z­xöÙgqýúu(•J?~›6m‚Ñh„Ãá@yyùÇ…¨¯¯G__¤R)BBBÐÔÔ„¬¬,p¹\lݺ‡†Z­†ÃáÀ‘#GððÃÃá`Ö¬YŒ.�ŒŒ„¿¿?.\¸€ááalܸ ƒN§CPPrssqìØ1Èd2fózè!¼÷Þ{ DfrLl�¿/#–{†F´ÍƒúÎÀÀ@ðx<´¶µ;Ç­®‘pu€\,ˆ�)kT)ú¸6þéócááá + øùù¡«« «/ñ9Lt¬µ_Ûksº­ÅÅÅhkkCgg':;;QWW‡Å‹cîܹèîîFJJ &&&ÐÕÕ…ùóç#$$?üð$ ìv;&&&pòäI|õÕW°Ûí@~~>úûûŒÃ‡C"‘`pp�±WT* V¯^ .wê5Ä™™™8tèóžèëׯ#""���0™LSËd2tvvbÍš5HJJ‚Ùl�Çc=sæ ._¾ ��N‡}ûö¡»»F£ÑÑÑhjjÂØØ´Z-jjj0cÆ áçŸFRRÔj5vïÞ�Ï>û 6lÀ¾}û�žžŽ+V ¶¶n·©©©ƒÁ`À�7�‘‘Á¡Ò€€DEE¡¥¥_|ñÄb18n‡hí’±DϺ\.÷€ �+V®r¶¶¶B*•B§ÓÁf·»Ï_¹¦� ú*å `þÞJņ¼µR+øúë×ËÜ7nÄ�7PSS!Ÿ�%sfÆŠ„Œ›Ì“�]Õ55ÈÎÎFkk+bbbàv»122‚ëׯ#;;¥¥¥Ahh(²²²àt:QUU£Ñˆ?þñ� Dpp0^|ñE<ñÄ(//GXXBCCÑÞÞDFF¢¦¦|>X´höîÝ‹Ï>û YYY˜˜˜€¯¯/D">øà\¼x÷Üs¢¢¢0wî\˜L&tuuMìãボœðù|477£¸¸¾¾¾øùçŸ H¥RøùùÁ`0àðáÃFzz:FGG‘””„7nàž{îAOO233qáÂ<öØc@EE$ ²²²P__¥R‰¢¢"Œ��C­Vc``^^^àñxÐëõ8yò$fÍš…‹/2aÓááa„††"22 …aaaˆ��E°�< B­bÞÀÓ3¨;xüÇ¡��Èår\¹r"‘‹Û¶mÃȸEç¥P@ȃq¢l“TÄqy•U×éÊ+n¸ƒÄ˜pß´ø¦¸ÍÊ|ûÝ÷ãR©õõõX½z5Äb1ÆÇDZbÅ Ô××£»»áááCff&f̘�7ß|###¸ë®»†ýû÷C"‘`Á‚ðõõÅìÙ³1sæL:tr¹œ©ÿ&¼páBLNNâ�wÞ�ÉdBqq1L&fÏž�O>ù§N�‚X,ÆùóçÑÜÜ §sê6´¶¶N<þ|tvvâÚµkÈÍÍEii)&&&„ŒŒ &U__�×^{ EEEèèèÀš5kpôèQÔ×׃Ëåâ±ÇCEE¶lÙ‚ªª*´··cÍš5(--…ËåBpp0êëëÑÛÛ‹ŒŒ TVV¢²²ƒƒƒÐëõàp8X³f ^|ñE|ùå—P*•0™LèííÅØØ***`2™�••…cÇŽaÞ¼yàÚÍ�¾ÞL¥§ÝÍÓ»…ұ˗/Ãáp`éÒ¥P«Õ‰Dèèè@DD>Ú÷ŸD*µ†úû26Ÿ+š“’èg´Úõº±qǸÁ€G×çÆ ø<LZmö¿~y¸eëÖ_¹‡‡‡144„¸¸8ÔÕÕaÓ¦MŒÎž={6ª««!‹áãミþ&“ wß}7êêêÐÛÛ‹Ç�G�e<�?ÿùÏØµkÊÊÊŠââbÜ}÷ÝhjjÂ<€‚‚DGGÃÛÛ?ü0cØñù|dffÂÏÏ™™™Ðjµ¨­­…ËåúÅŠöööÆàà /^Œ'N`pp£££A{{;RRRÐÝÝ�™3g¢¼¼R©Z­eeexùå—QUU…ääd9r7nÄ� ±XŒááa¤¦¦¢··½½½¨ªªBXXš››áç燄„ttt ((qqq¸víÂÃÃÁårÑÙÙ oooÜ{x˜˜€Z­Fkk+t:6n܈ÊÊJøÊD>*_/àöî>ã…¢kcb±IIIÐëõ°ÛíèêêBnn.ã‡WÕ5š&¬vctH ‡Ã™z¥#Ÿ'˜Ð38lH‹�ñ�� e¸·K;Þ9f²�N'|}}‘””„ÆÆFØl6´¶¶bppv»ƒƒƒðòòbÒ�F£111¸xñ" &&&pñâEøøø@(â›o¾�ÝnG||<ššš ˆññqôõõáÅ_„F£ÁÍ›71>>Žëׯ#((J¥6lÀÁƒ±hÑ"TWWÃÛÛÛ·oGAAÁTÀv›Í†ÈÈH´··Ãív#//»wï €ÔÕÕÁd2A*•bÑ¢EÈÏÏÇ3Ï<“É„ÆÆFô÷÷Ã××!!!¸qãär9ÆÇÇ!“É`³Ù044„>øçÏŸÇÄÄ/ݳgÒÓÓ1<< “É„   ƪŒ��…V«…¿¿?ÆÆÆàv»§ô¢Poooô÷÷£­­ é3eÞ21ó‚lny@°F©TB,£¸¸›6m•+W¢ííí…X,F@Pðdþ¹‹úô¤8_þ­$—Ãá¥ÄEDysoM´oxtì‹£ßw’ W*•èìì„Z­†T*…��\. ÆÇÇ¡ÕjñꫯbÍš58uêBCCÑÑÑ�¤¤$ìÞ½•••ÐëõHOOGXX***Àãñ0>>ŽÍ›7ãìÙ³X¶l’’’0>>ŽÚÚZètSï’éîîÆÄÄ/^Œ‹/âÆ�xä‘GpôèQ„……áž{îÁÍ›7ÑÜÜ<õ:%Û³²²ÐÙÙ‰+V //ï¼ó, ._¾Œèèh¨T*üú׿FHH<ˆ7ß|Ÿ|ò 4 x<""" T*a0ÐÜÜ ¡Pˆ­[·B$A£Ñ`Ù²e¸ví~úé'äåå!..­­­Ø¶mÞxã 455añâÅÈÌÌDxx8Nž<‰9sæà§Ÿ~ÂØØ:;;ñÚk¯¡«« >>>ˆŠŠÂùóç!—ËaGrlS0/“JD—KÊôcãF[jj*ÑÜÜŒûï¿v»:� .DQQ|}}ß•�2j›󖈄àÞjÀáñm-}õcãã®§žz :�|>óæÍC}}=6mÚ„––Fí˜L&dgg£¦¦�­­­˜1cz{{qéÒ%lÞ¼F£ãããxï½÷ðÎ;ï 00³gφ@ ` ®úúzTUU!((n·���P©TLßËË ‰‰‰p:�ˆ‰‰�Á`Àää$jkk‘——‡³gÏN%Žl÷óóCxx8xà444 77'Nœ€Ëå‚Á`@dd$ ‘HpöìYTWWÃËË ™™™˜˜˜€Éd²eËpüøqÌ›7ƒƒƒhoog‚'7nÜ@^^úúúàåå…ššlß¾o¿ý6ó¿d2ÊÊÊPXXˆ¨¨(üøã�HHH€ÓéÄÊ•+ñÍ7ßÀb±`îܹhkkƒT*EJJ ¶üj›MÓÛ NU¤sÄ„+¯UÝ•Je.â²,[¶ ÅÅÅhjj‚^¯g8åµ×^õÒëÎÂkåÚ¸ð`o±hús)|‰\wæRш\¡@gg'nÞ¼ «ÕŠžž A«ÕÂÇÇ .ĦM›ðæ›obþüùhiiŸÏ‡¯¯/žþy,_¾­­­ˆˆˆ—ËÅŽ; V«qèÐ!DEEaxx!!!p:�Ðh4˜1cär9RRRpéÒ%Œ��1Þ‡\.Gww7ªªª�šš •J…ÊÊJÔ××cåÊ•¨««›877?üðæÏŸ�®®.”””`îܹp»Ý¸ï¾ûpâÄ p¹\œ9s«V­Âðð0S›† 6à•W^�Ýn‡Édb\žƒbùò刉‰Áo¼½^�††¬^½ééé(((À¼yóÐØØˆ+V ¡¡V«\.óçÏGYYV®\‰††¦â¤»»ÑÑÑhiiÁ�7àv»1n2›ƒý½UÄ* ‚YÉñ¾�Á¨Õ�Ù¢££qàÀ ,[¶ r¹õõõÐétÐh4ðöRò3Sf„û{É£‹4—Ý*óUȤ™Ù+ôCÃÃ xyy1"Òáp@*•bÅŠøóŸÿŒsçÎá÷¿ÿ=:„––DGGÃl6ãå—_ÆáÇa·Û‘““ƒÎÎNèt:Èd2twwÃ`0 ""UUUðöö†ÓéDTTŠ‹‹‰ùóçã§Ÿ~BNN„B!î¿ÿ~LNNB$Á××hll„R©DXXÆÆÆÐßß?0±ò ÑÒÒ‡ƒ‚‚¬Zµ ~ø!$ vïÞ�ÁÁALLLÀßßiii8{ö,qþüyìÙ³©©©p:�èèè@^^fΜ‰³gÏ¢¹¹›7oF@@¤R)Ìf3&&&P^^¥RÉÔ]UWW#** £££xûí·QZZŠ5kÖ °°‹~~~ B[[æÎ�‹   $$$àZÙ kÂŒ.!ÇÅèb�+ˆ ô Œ–%''»ì—ãf]�+==çÎ�Ã}÷Þ#X•µÈ[ä¶Ï��ˆSJEJ®Ãérq¹¿íë¥�šÇF½®×Ôé._¾âBcc#fÏž ½^�E‹Áív£µµÁÁÁ�^¯‡ÕjETTüüüð¯ý |>«W¯ÆÀÀnܸ�ÌÌLœ;wYYYøé§Ÿ0gÎôõõ!<<¿ùÍo044›Í£Ñˆ’’`Þ¼y0™Løç?ÿ ¡Pȃ’’’`±Xàp8°dÉŒŽŽ¢··w à””X­VÔ××ã£�>B\\,X€}ûöÁÛÛhhh@tt4jkk‘™™‰Ã‡C,ã™gžANNÊÊÊPWW‡úúz<ú裸~ý:Šþþ~Ô××cÁ‚hooÇÐМN'FFF°~ýz”––B©T"!!F£V«§N�BPP¾ùæˆÅbÜu×]L`` ÚÚÚàp8pñâEdffâbQ‰Ñj³ÙC¼9p8 ©Xʵ[bƒýCr/ TˆBr³æG*Å¡2‚ü}åÄŠ€Ñq³þøÅ↨˜8³˜ãô! Z±�/Jމð5šuº1ƒÓÏÏ�©b9{ö,ø|>4 †††`µZ¡V«‘žžŽêêjÈårôööB&“¡½½Û·oG? ÚÛÛ¡T*‘œœŒ~ø«V­ÂÄÄZ[[qíÚ5¨T* @  ³³3gÎD`` „B!†‡‡1:: µZ�³gÏ""";wî„D"A]]†††¦òÁYYY�J¥¨©©ÁÚµkñõ×_3œ¶páBÌ™3û÷ïŸöâê9sæ`ÅŠ!3gÎ ¦Ï$N«Ý2Z˜oR BçÙÙÙ7‚‚‚�˜˜‹ÅƒÁ—Ë…gŸ}69""‚ù‡\ûöí«ÎÏÏw@BB)3 ÈËËÃ’%KðÚk¯aNzª8ÔGâËárÿ­ÿ ä Ux�U6¶d.]韖–¦‰DÐöwskŠÏ �Ô&ˤ­¼©»±º¡yB¯×Ãßߟ{òäÉ R•BöÁjµþRøv«â…Ïç3¯�´Ûí�J¥0™LÌÿ&U3äå°f³^^^¨¨¨hûꫯ íííð÷÷G||<ÑÕÕ…GyGŽÁ /¼€/¿ü’ñ`‚‚‚ðÃ?LeXfÏž�ï¿ÿ:�ƒ›6mBFF>úè#TUUáòåËØ»w/®^½Š¡¡! `Þ¼yàp8ü   ÿÕËR„B!¤R)ñÚ³g>üðCýýý™±KKK!•J‘˜˜ˆ’’ÔÔÔ@­V#>>jµ—.]BZZ"cã&óóó›Ê:„‹æ¤ùúy+Ý6«\$äóy·¨Ênw8�n·}Ô`4-¶ñ^�^_ÛÐd‰ˆˆ�¼üúr!H/¯Tø¨pêØ·†Qíˆ1@¥B{o’ã"}Î^,4?ÿ»ß¹Îœ9??¿ÿñ(•ÊÛŽI¥ÒiçŠŠŠ¸ƒjµ>>>(,,ÄìÙ³ŠÚÚZlܸB¡###ذa>üðCܼyÀ­dCww7¶mÛ†ëׯ£±±7oÞDYYâââÐÔÔ‰D‚’’¼÷Þ{øþûœŒØØXèt:ïôôôÛgøßh………½<*• óæÍÃwß}.—‹�;wª% “ú;räHŸR©t[,¬Y³óæÍƒ\.G]]Š‹‹¡Óé044·Û ¥R í¨ÎYZYc›tjkÛºtVw_cÏPßáSg{­:�Îæëë+///Ñ+¯¼âÛÝÝ=‡ÊÊJœ:u Z­6lpíÙ³çj__jjjàãã¹\ŽŽŽÄÇÇ#..‹çÏŸGEEEF`` Siòå—_–½òÊ+v???(•JÌŸ?ýýýˆŒŒDhh(Þÿ}xyy!-- ;wî„ÙlÆ—_~‰ÐÐP $$jµ<¥¥¥�Éd˜3gΟ?•jj)L$+77%%%ˆ‹‹C[[bccQXX¡PˆÞÞ^xyyatt”ÉÛΞ={ëõzÝ7ß|c*--ŸÏGpp0 ø|þ´êƒÁ€ÞÞ^tww#** F£hooGbb"FGGñè£�ªe2ÃÁõõõ}ýýýn�N‘H„½{÷¢¬¬ ÅÅÅxüñÇÑ×ׇÞÞ^¼øâ‹8}ú4Î�;‡¼¼<øøøà믿†¿¿?¸\.ÚÛÛ¡PL1iKK Ö¯_�}ûöá­·ÞRÇÅÅ1I‹_|±qÁ‚>b±˜QQQ‚¿ýíoš’’lݺF£IIIøüóÏqóæMÄÆÆB(Âl6#!!� õôô -- þþþÈÊÊR{yy1kz÷ÝwûÕjµ+''?ýôóÀACCŠŠŠËäáqîÜ9”••!,, ###LŸÏ磵µn·‹|>���S ƒÁ€²²28�N:t………LÃét"-- IIIX¹r%¶lÙÂ,dþüùÓ¸Ì`0`ûöí¸ë®»PUU9rJ¥<»wïÆ?ü€µk×¢¤¤IIIèêêBRRbcc1kÖ,¤¥¥A©TÞöÚá��¬\¹’!ÀO>ùùùù0 ¨®®ÆÊ•+‘’’‚çž{N§<ðÞ}÷]ÄÇÇC¥Rá¯ý+Söj·Û1>>�‡ßþö·xúé§‘––Æ<ò¢ÑhLåå冟~ú‰yŠÞÛÛÛ+00P6gÎ<ýôÓhjjÂñãÇ€•+W¢´´uuuàr¹(--E}}=V¬X‰D‚ŠŠ „……1¯Ù'mhhÞÞÞ(--E||<æÍ›‡®®.ôôô`éÒ¥ˆ��ÇÂ… ár¹‡mÛ¶aÖ¬Yزe V¯^�¬¬,<ùä“èïï‡ÙlÆúõ뉎ŽýÂÁ�kÖ¬A}}=î½÷^ÄÄÄ@.—ã…^€ÛíFII ¼¼¼péÒ% ¢¨¨n·‹-òŽ��e8¸²²RWPP`êìì„@ @?QYY‰˜˜cÁ‚‰DP«Õ¸víø|>bbb°`Á˜Íf†›—,Y¢V*• µ_½zµïäÉ“n·Û�ááa¨Õj( ,_¾•••¸v톆†°jÕ*¬X±‡ÆsÏ=‡Ó§OcÍš5¸rå .^¼È”•’jOOÔjµonn.ðO?ýÔ# M.\°lÚ´)˜{Ë_½z5·¸¸X799‰ÆÆF$''#44{öìÁ·ß~‹x555HJJBmm-ªªªÐÜÜÌXÑÙÙÙjuŸþ®®.×ÄÄÔ¿±‹Åàp8�ÉdX³f Z[[QSSƒ»ï¾ßÿ=êêê`³ÙÐ×׃Á€Ë—/C£Ñ`Íš5(..F||<“½">5Àvâ0“Š€îînâóÏ?‡^¯ÇòåËa0088…B�={öÀjµ"22Ò{æÌ™ ÀR©T§ÕjMK–,A?ôz=\.ÆÆÆ�žž³Ù ???X,œ>}±±±Øºu+~øá£¥¥ÁÁÁ¸zõ*vìØ1MD¯Y³¦¯¹¹Ù]QQ�ääd´¶¶b``}}}ÌæÉÒÖÖ†žž1"òÀ�HJJ‚ÝnG^^BBBPZZ .—‹çŸ>&00P v»Ý±}ûö¶ððpw__Ÿ366V.‡#9}úôpMM�K.—cåÊ•˜œœÄ¹sçÕ%066†ââbÌœ9z½sæÌÁðð0î¹çžiëtºþááaWBBº»»™Ú*•J‘HÄäÙÇÇDZwï^twwC¥RaçÎ�8uê@"‘àèÑ£HJJ0å’‘¶k4š)=11�ªª*èt:ÄÇÇãî»ïFEE£´õz=jkka2™°páB¼÷Þ{ Bj*ó¦@À™3gPQQ�¯¾ú &“ �ƒYYYð÷÷Gxx8Ün7 aµZ™ô¤··7Þÿ}…B\¼xIII·½e/77‡ÂÂ… ÑÚÚ ³ÙÌÔ4Ùívtvvâ±ÇCWW¸\.¶mÛ†””ìÚµ Ÿ}öºººðñÇãÀ�L[BB‚4%%…ymñÉ“'5þþþιsçbrrGŽaÞÉãñ¸¯¾új‰;/\¸ÕÕÕHMM…X,F~~>àž{îABB*++!‰066†ŽŽŽÛ+©¨¨€H$¹sç�‘‘�ÒÒR´´´ «« ßÿ=ÐÝÝ —Ë…;vÀßß---øñÇ™ê­V‹ÜÜ\€··7bcc‘””„ŽŽ·Þ²Ãår‘‘‘Áôë|||püøq|ôÑGÌ£&O>ù$êêêÐÒÒ2m‘‘‘Ld``ë֭óÏ>ˈ*ƒÁ€+W® !!/¼ðŽ?Žùóçc``ÿûß±jÕ*¦Š�ý¤D[[¶lÙ‚ŠŠ ddd €y”&::iii8sæ 233a6›ñùçŸC$áàÁƒHJJœ9s‚íÛ·#//‰‰‰àr¹Ø½{w0ý:ˆ…: IDATxÊ•+W†ìv;Ž= µZ�êêjCOO�™šJ�F£áœ={O?ý4ÒÓÓqêÔ)LNNÂ××~~~øú믙ªR«ÕŠÞÞ^üãÿ€��Ï´5©T*tuuÁh4ÂÏÏÏ=÷|||0>>ƒÁ…B�uëÖ¡¨¨R©ÕÕÕ€Ó§O#55»wï†^¯GSSª««qìØ1&{F8š`»ÛíÆªU«ÐÜÜŒ¹sçâüùóÌs/½½½ÈÏÏÇoû[¦ø-00>>>HOO÷ŽŒŒdD´\.ç®\¹Rš““ã½zõjשּׁ,o‡Ãá½páBï3fxggg{/X°À;++Ë{xxXRRR2Q__�™3g¢··3fÌ`¬À�7ª #Ϊ««ûL&“›Ë墻»�ˆ‰‰ak)++ƒV«Åàà d2BBB˜2ŸÜÜ\øøø ¤¤���Ðëõàñx‚çŸ>ŽèØêêê±�>úh€üÏ(‡Ã¥R‰±±1,Z´È$ Ïh4Z*++Í›6mByy9’““¡P(Ð×ׇ°°0¦8099mmm0�ÁâÅ‹§YÑ\.·ÿæÍ›.�FƒøøxôôôÀb±`É’%0™LL.\¯×cïÞ½€X,Æàà „{ï½—.]ÂòåËa4±mÛ62éC>,^¼½½½X½z5ŒF#&&&°sçNˆÅbœ={Ë—/Çœ9spùòeLLLàСC€M›6M£È°°0Ÿ°°°idš˜˜O-22r|ß¾}CøÃðöÛo#22%%%HMMÅâÅ‹o{5ƒ��:;;Ñ××___|üñÇØ·oóÏAúûû!•J™·Í|ñÅøòË/QSSƒ˜˜Øl6TTT`ïÞ½¸víñ»ßý.�Ïç37*))T©TX½z5Ž=ŠÖÖV¬[·nÄd2EÊd2lÞ¼9X¡PŒ8p�•••ÈÍÍ…ŸŸ*** V«QSS�@•J…G}ÅÅÅÓž�€÷ߣ££ÈËËCWWÌf3är9ÊÊÊÐÓÓƒ%K–àÚµkˆ‰‰Ayy9Ün7&''™â |öÙgxà� ×ëát:qúôiÄÅÅ!..ÇŽ›ÑB¡ 8uêSŠyþüyüøã�P(ˆ��‡Á`ÀÈÈ.\>Ÿ�eË–A«Õzïßi|>¸rå üüü°víZ&sBÊ@évóæM,[¶ 6lÀ³Ï> £ÑˆK—.¡µµ!!!°Z­˜7o¼½½‘ŸŸ�ùóçÃl6Ãn·ãĉصkΜ9ƒ��LLLp–.]ÊX΋ÅúÖ[oéCCCñî»ï2eÂÙÙÙxå•Wœ%%%ÌKÙ"##å�@!‹ñòË/#** ÇŽÃÏ?ÿŒÑÑQ´··ãñÇÇòå˱víZÈd2lÙ²å6LâÊ ¨¯¯‡��c<æææâüùóÐh4hnnÆÿmï̃š<׿ÿ‘�B!€Ê¦²‚YTPë.P—©µê´N—±gzzj{~vj[�sôt:õh«µØS[�ÊQëFEQ*(RÃ¾ï » !a‘÷›çÔ×ÿ~¾óÞ3™��É$Ïõ<×}]×w¹srrÙ<+*¯\¹ÂìÙ³9uê*•Š€€\\\„aüž¢5 F£‘5kÖ0kÖ,îÝ»Grr² šœœÄßßfÏž�½½=F£‘   ihh¨�¢oݺեÑh:oܸ¡½ÿ¾V§Ói‹ŠŠ´¿þú«633S[VV¦mmmÕ^½zU{íÚµ•Jež6m���‚šÎBõY¹råséìèÑ£íÃÃÓ– °hÑ"ÆÆÆhoo'""‚àà`lllÐh4LNNÒÞÞŽ¯¯/ååå‚êÚµk,\¸�ññq’““å±±±äÒ¥KŽŽŽCZ­;;;*++Y±b*•ŠE‹a6›Mqqq^– I¥R«S§Ni-¥¾¾žÐÐPìíí©­­ÅÞÞÞ|óMª««iiiyà¿þõ¯888P\\Lee%sçÎåßÿþ·€/J$FFFhll¤ªªŠ¨¨(~ýõWV¯^-�={¶àÇ�wŸ$55•¶¶6Ìf3ÕÕÕüùϦµµ•   ²²²^˜dY………lݺggg¬¬¬puuE*•¢V«©®®fêÔ©B [[[KXX·o߯ÙÙ™ììlAYh¡………¡R©€ßþíííyôèQœ��ijjâðá䥥akkKbb"<Ä_Ë–-£·÷¹?‰‹‹ã?ÿùþþþܼy…B�»»;K–,áæÍ› ZZZ�Éd³gÏvìØÁþýûñòòÂh4’‘‘Appð ãñãÇtvþ÷øá‘‘JJJHKKãã�?¦¯¯�—_~™«W¯222B__ëÖ­£´´”„„ÒÒÒØ½{7z½‰DòœÍRdd¤,88xÞïÖJ¤¦¦ ~ Áí÷Êú¹M455Õ³®®®½  à©�� ƒ'''$ Û·oçøñãèõz¡pµ„þñ�P©TÌ�;—üü|†††X´h—/_fþüùIþÞ½{455MVVr¹x6ÖëõÄÇÇÓÓÓ#¼o[[Û³@£Ñ°aÃ.^¼ˆÑhÄßߟ«W¯røða,X€L&Ã`0`ggÇ·ß~KLL ÷îÝ{ÁâH£ÑPZZJqq1&“‰ŽŽ�ž’’’ÂÄÄr¹œææfÆÆÆ ¨¨{{{ÜÜÜpuuÅÃÃC¨„ÿ¸Ôj5<}ú”ãÇ�Ïûï¾û¥RÉÌ™3B«Õ�¯¯/ƒA�hÆÅÅqîÜ9233íÂÃÃå|o;;;[‰Dâàäääàîîî —ËÜÝÝd2™ƒB¡p°··w‹År¹ü¹»ÎÙÙÙV*•Ê¥R)ñññäççãïï/p¿ILL$22’ØØØ†7¾¾¾DEE!‘H`Ñ¢E|÷ÝwüÏÿü]]]Œ��#•JILL$<<œM›6a4ñöö¦··???¼½Ÿ!•çÎ�cÞ¼yèt:�t/ØÅÅ… .pùòe’’’‰D¤¤¤àåå%< óæÍÿÆÆF†‡‡_€ô¦OŸN\\!!!X[[£Óéððð 00�ºº:Aþ²hÑ"Ö¬Y#¤}³ÙŒ‹‹ ÑÑÑxyy Õò×Ô©Sñññ!99+++ž666n4…×ä¦0{÷î�:þ|A2»yófÌf3_}õnnnôöö ê@ �oYÍÍÍØÚÚ†B¡àÂ… $''³oß>¼¼¼¸~ý:r¹\�äfffrÿþ}vïÞ�¯¯/ŽŽŽÌž=›êêjÞÿ} Ñét¨ÕjfΜ üž¢ÝÜÜ'##©Tн½=QQQ<}ú”ööv´Zí3:ŒR)èv-¼ä?®ÆÆF²²²°±±!,,L€¾Ôj5£££$&&òË/¿‰ÉdbóæÍÜ¿…B!ì*•Šââb6nÜøÜ{O™2…ëׯ322Âûï¿OZZ_ý5;wîD§Óaee…Ùl~‹�ˆˆàÌ™3(•J233ñ÷÷·Ú¶m› V™Ø¾}{Ñ‚ &FGGQ©TTTT`ee%´ŠJ¥oooFFF0™LôõõñÁ,[¶Lñ{q sÉÊÊÒEFFÒÜÜLYY¾¾¾ŒŒŒZ¬þþþnÚÑÑQA<III ]]]¤¦¦réÒ% 2™Œ[·n122BKK ñññäååáâòlºja›VTTÐ×ׇ««+ ,àáÇÿ}‚GGG©¯¯§¥¥‘H„­­-999|øá‡ÂPÀÍÍ •JEoo/øøø¼@71™Lèõz–.]Jqq1!!!¤¤¤`á]k4ôz=J¥’��rrrÈÊÊÂÇÇ‘H„••+V¬Àl6?g­dÉ2¿cªœ8q‚°°0æÌ™Cff&W®\¡µµ[[[¢££Q«Õ”””àççGpp0_~ù%sçΕÿ¡º{÷n¯µµõDYYf³™‚‚¢££  ¾ÁÁA~ûí7<==‘Éd:tˆÂÂÂç̸gÍšå544ÄÍ›7 !** ©TŠB¡`pp±XLBB Ûîîn:::ÈÍÍ%==��;w ]ŒÁ`ÀÞÞž�� ááá1sæL�ËåÔÕÕñèÑ#bcc‘ÉdTTT`2™(..fÖÀ®ññqBCC]Íèè(+W®dÿþýlݺ�FƒD"áØ±c°\SSCpp°4""Bˆruuuÿ²eˆ‹‹‹™œœäáÇ(•Jjjjxøð!ûöíÃÍÍ�ÜÜ\îß¿O||<ííítvv2<<Ìøø8åååØØØ°k×./±X,ãöíÛí%%%“¯¾ú*–'e``€ŒŒ &''ñööfxx˜—^z‰ŒŒ <==ñõõE­VÄÝ»wùË_þ ‰„ Êùó绺ºÆD"ÙÙÙ‚j>>>ž×^{�/¾ø­V+(Õj5iii444Œ®^½ÚM*•Úýž=zôdrrrüܹs�FFFFP(ôöö…Á` !!ÁK*• ß©±±±#))é©…‘ÙÛÛ+Pa-ûºÉd"66OOOìííIIIáÉ“'ddd ‹‰ŠŠ¢±±‘ššœœœ°³³ÃÝÝ777zzzþ VWWƒX,fîܹÂ@;66–   8rä>>>ØÛÛ³|ùrBCC¥>>>B€srrú¿üòËá¡¡!ÂÃÃyï½÷øä“Oˆ‹‹Ã`0PZZŠ———Ь×ÕÕNOO¯¾ú*ŽŽŽLŸ>�'Ožðꫯz‰D"ábÈd²§!!!’éÓ§Küýý%666’�;wJRSS%aaa’uëÖI”J¥dÞ¼y’µk×J\]]%aaa•Je°µµ�Ü¿¿‹¿¿¿px´V«úùçŸ;1�H¥Rúúú8xð gΜ¡»»›Í›7#‘HˆŽŽF«ÕÒÐÐÀ¦M›‹Å ã 0eÊ”)“wîÜtvvfóæÍ”——c6›Y¹r%}}}èt:Ö®]û\€ÿþ÷¿w=-//ÇÙÙ™;vàááÁž={8{ö,{÷î%-- �FChh(z½žÓ§O£T*… £×ë¾úš5k˜9s&k×®åîÝ»ètºg{°e£ž1c………Âxï�7Þ --�€€D"Û·oî”´´´æÌr¹œÐÐgçGÖ××óÓO?‘’’B^^ \¿~gggt:UUUôõõ100ÀÊ•+ùú믅=gÚ´i/´ .ôY¸p¡ð{LLÌÿÆÿ½–.] €ÉdêZ¾|9cccÏ™”^»v­[¥Ra2™˜={6jµš-[¶�œœÌ·ß~‹B¡à_ÿúo¾ù&‡fÏž=DGGÓÑÑÁ{ï½G^^Þ“Éäg¡ô̘1ÃÃÝÝ]³`Á‚‰¯¿þZp_/(( ((ˆòòòZ?;;;Ž=Êúõëqttäûï¿Çl6ÓÖÖÆæÍ›9uê[¶láÂ… ܼy“ÞÞ^ÂÃÃ9~ü8ÞÞÞܸqƒ·ß~›ëׯ çÎ�ãÊ•+$''söìÙg{°e€PWW'TtìÚµ ¹\Nww7Z­–²²2�ó»cÇŽgâ­?,™LFAAZ­BCCÉÏÏgýúõ8;;³`Á\\\¸~ý:ÅÅÅBkP\\ŒÑhD$±råJâãã_دþ·+77— .Ø vlll<##CÛÕÕE`` ­­­$&&òøñcÞzë-zzzðÂ"¿éë룡¡�FcAÕ&ZZZ„a¼H$²Y»v­ûo¿ýFTT!!!ØÙÙ±mÛ6¤R)2™ì°axx˜o¾ù†ÜÜ\–/_ŽN§cbb�NGff&VVV�F”J%QQQœ?žêêjÖ­[‡——nnn|ôÑG,_¾œäädÊÊÊ‹ÅÈd2š}š7ß|“žžRRR¸ÿ>¶¶¶„„„ ÀòåËy÷Ýw‰DÑÜÜÌçŸΡC‡bÓ¦M466bmmMuu5555lÞ¼ggg1�„……a0(,,ä•W^áÂ… PQQ!XElß¾]˜«O�:•Ë—/#‘Hyª——]]]¬Y³†²²2 %++‹ÔÔTa²wúôiàY_k!§òÉ'ìß¿ŸÞÞ^¡ª D.—óúë¯óÖ[o¡P(ÈÏÏ'==�ÔÔT/^Lxx8b±˜G�QQQÁúõë9sæ ÞÞÞ8;; päÄÄF£‘Ï>ûŒC‡±qãF._¾L@@jµ???òòòžY§N�"66–žžt:��� –ööö1}út4 ëׯ§££ƒ––œ��ùæ›ohllX”ééé  ×ëÙ²e ÖÖÖèõz¤R)_}õƒƒƒÓÒÒ‚R©Þ{``ggg.^¼Èo¼!ÈMûûûY²d <@,311! M, øÚÚZº»»Y¸p!ñññèõz –ÉáÇ9uêb±­Vk9†�FƒH$¢¥¥±XLXX[·nåöíÛ$$$^‘&“‰wÞy‡ÂÂB^{í5úûûÉÉÉÔ}•‡‡ƒƒƒäçç£Õjquu¸ßwîÜ!::šââb:::øðÃÑjµÜ¾}[Øâär9ÿüç?A½^φ øùçŸÄÛÛ›˜˜ÜÜÜ„Ïokk+´²^^^š¦×ëŸØÑÑ‘'N R©èééòþ† T©··W¸£-�š³³32™Lh1±µµeçÎ�Œ�� -ÐܹsÉÌÌdpp�·Þz‹°°0îÝ»ÇÀÀ~~~,]ºTàHµ¶¶211Áðð0´µµáææÆÅ‹Q(ô÷÷#‹ÉÏϧ´´™5k–`>&•J)**ÂßߟÁÁAººº„`'$$PZZJ\\Ó¦M£¿¿ŸÊÊJ"##Y²d Ë—/çý÷ßÇÏÏ�úúz¼¼¼¨©©áóÏ?çǤ¿¿Ÿððp.^¼ˆŸŸOŸ>†––Y‰L&C­VãááÁýû÷ áÁƒÌœ9///Nž<)0hÞ~ûm °¶¶&**Šºº:šššö¦H$bÑ¢E( º»»©­­å¥—^¢««KøÙâ®ÐÐÐ@ddä³,ìzòä ÖÖÖÄÇÇÓ××ÇÒ¥KÆÛÛ›öövÂÃÃ-j`` f³™ýû÷s÷î]4 &“‰àà`�DVRRBCCÃÃÃtttàááA]]§OŸ&''‡ÚÚZ¢££ñôô GquueïÞ½³páB~ùåaèÞÞÞŽ“““` ±lÙ2ððð ""‚‚‚6mÚ$ÈÕj5...‚+­ÙlfãÆ� N}}=qqqddd ×ë‘ËåTVVb0¶ÄØØ/½ô’0ÐwrrÂÓÓ“ÊÊJâã㙜œdÆŒ‚xì�wÞáǤ··—G�áííÍË/¿ÌÙ³gIMMeÕªUX†*111hµZ m±XÌ믿Naa!·nÝbll ½^�ƒƒƒp�ªªªÈÍÍeÛ¶m477£×ëQ«ÕÂÐÇÆÆ†íÛ·“——‡““Óå£ÁÁÁ,[¶Œòòr.\(̧OŸF¡P0mÚ4ìííimmØ÷öööbcc#ÅV¬XAUUÕÕÕjttÜÝÝyðà�Іuww“œœ,½óóó9zô(GŽ|( �OOOºººhkkcÍš5‚Ú¢¦¦F ¨iµZZ[[™2e ÍÍÍ‚Q˜E23>>.|qµZMbb"ÙÙÙ “””Ä£G�°±±DèúÓŸ„‘cHH.\`ÕªUdggc0X¼x1eeeÏDÖ¿{B[ªJJJ¢¤¤„„„Nœ8Áœ9s¨¨¨ ²²£Ñˆ««+‚ü¦··—²²2Ôj5Û·o§²²’ÉÉIŽ;Æ¥K—hnn¦££C`™”——ãææ†››tvvb4‰‰‰!77™LÆ“'OÐjµÏìîîNaa¡0Nœ:u*III‚—bQQ‰‰‰Itt4<@¯×³qãFlllÐjµ‚"Ý¢/Z½z5���”••±dÉîܹC__S§Neúôédff¢×뉊ŠÂÕÕ•7nàä䄯¯/GŽÁl63}útΟ?ÏÀÀÁÁÁ”••±eË�œ×××Ç”)S‡¹¥K—"‰HLLdbb‚½{÷ÒÑÑ�B¡@©TRUUEee%”––"“ÉCcc#ûÛß�Ëåܸqƒ²²2JJJ‹Å´·· Ä:Þxã ¾ûî;ÚÚÚG�ÜÜ\:;;inn¦³³+++6mÚ„££#;vìÀÝÝ�ââb–-[&l?–½»ªªŠ¦¦&†‡‡qqqŠÐŒŒ üýýijj"** ;;;FFFX¾|9õõõâÖ­[‘ššÊµk×èèè 33“ÉÄØØ LLLÐÝÝ-ì�­­­øûûB^^sæÌapp�ÎÎNÉÎÎf||œÑÑQº´ -Är>ÅÄĉ™LÆ÷ßOkk+r¹œ¡¡!’““ÞX[[‹-¢¡¡Apë±ÈSqrrÂÃø¸8t:���Ô××S\\LYYåååôõõ!‘HðôôÄd2ÑÒÒÂÄÄ©©©BѺyófT*—.]l-d‹ó_jj*çÎ�œ˜?>ƒA@kkkŸxë֭ܽ{—¬¬,._¾ÌÉ“'gÆ LŸ>]P¯ïÙ³‡~øÌf3³fÍbllLà �ŒŒʱcǘ1ceeeŒ��“““#¤¦šš<==ñôô$11‘O>ù„þþ~”J%ùùùôõõLll¬àÁQ__�Á`àСCTUUQQQACC~~~ðÁpðàANž<ÉÕ«WQ(x{{ ëððpT*NNNãÄòù›››W¹mÛ¶Q]]�··7f³™‘‘JKK±²²"44Tt͘1ƒ¼¼<ìììcï޽ܹs¥RÉãÇ�™2e III¬Æ,õfIDAT^½‘HôLBbmÍÔ©SñòòÂÆÆFèckkkÙµk_|ñ…0#°HS,Pkaa!MMMÌš5‹O?ý”ôôtæÏŸOgg'ýýýBͯ¿þJRRÙÙÙ˜L¦ÿ7ßÿÿúïú?8,A©³l¹IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/darkref.svg0000644000175000017500000010165015153325210027162 0ustar00paynopayno image/svg+xml DARK FLAT & ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/delta_beta_range.png0000644000175000017500000001260514757047403031010 0ustar00paynopayno‰PNG  IHDR[Sðe{ôsBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î<IDATxœí]{xTÕµÿ­sf2¯„¼ˆ ¯@ 4€ˆ+*å!¢<3ÜbHD½ß­­ßgŸô•^µíµííµ÷–V D4ÉTôƒ–¨ˆoyÉû¥„@ ‰„€yLž3gÝ?ö 93™É<2 é½þ¾/_röìµÎ:kÖÙ{¯ÇÞ!üGÞ’%i²^7·s�` €@=˜OC’ö3óö1ÙÙï©Ñ–…¢Íp�àË`� /6w˜LO(„Pn88M.×ÂâW_ý,AŠ&³@€õâuzláBC‡É´Àw¾¢`,Ëò°ÈD ]´öè]9×AH €f�šââ¾`–Oó1&Ú,1âb¾"-À€I"JT™Ç�$å€ù£ûü$~0X”�àYáXSoC ÕçzÝèìì‡C‡ó—-»ÌÂ�%$ †1{!€ |Y†ð«�|«µÀPMÓìõåå;"/z –ý(Š‹�=>cêÔ½^oÒɲ_ lmkÓ½»c‡gx<ß0ׂ課 ø¶¢({ìv{gT%ƒAÙ³`ê¤IÕ#22æõÖÑår5h.¿ Dv7x.È7M[a³=ï”åò—_~ùJeŽ×ZÙC¤@rRRR˜´-ÛÐÖö‡“i€[4Í9Äü?z§óù|«õ8€]ìd—ë“Ñ99Çûc]²À„÷ïÆ8‹ed˜´e_»eK«ÜÞ¾D/ðU¢ àkfàÈò‘3ÇŽ�Í·Z³réÒ1aÊ�àŸà{î†x�p�±ËI’Rû(‹^ܼ¹Y"zDU!tàû.Y>‘oµþ—¢(±Ñ”Ѿ(;ÀûÞð{[pG<&ÀuC‡:ú ‡_ä[­?SUõ#0 ke>ÀF£ü€mΑzÿf–¤=ýa呎ÙãTðt@*€qÞ°ÀÞ^o˜ i©©¡~±Âj]`µ¦©ôl}}Þ{ï½çÔöSE¶ÝÅÌOƒhÒÕ˜'8eyëCŠòõìöËÑ’+Ëž`„¢³¦M{{yn®sÞm·m7�'!V ùVþ@/|t&@RBB$.µ_¬°Zo'àß5MoŸ½x±‡¢Àn·»ŠËË·op�ïWA@–“èùhÉ„¯ìŶH!¢†ùsæËÊÌœ«Óé2†¥§ÏU/Θ>eÊn"r@Xz €7Ñý@ €^„pÍ9ÖlŽÊx=gÎA÷ÜÑA’ômŠÖbíÚµ]ëËÊPêó‘5éÒIþh"A8Ê.ð³Á`8Ÿ»hQýд´ÚD7)+k¦uñ⺴ÔÔÃîæyXàÕCPètº�N—Þ×€‘ééyÆjš^+.-­ •ÞÀü(€&M“Y~8² fÁA¯åŸȱË©¥‹©±fó„@F£qìÂÛoϾcöìýz�î3€§üb]­ÆZ,'§O™²{ÉÂ…m!ÊÌ^‚m ‡|­ÝÞ¢ ^,�Û£ €Ð&È5~ É Ÿ.œ;7C–¤P,Q‘‘1mÙ}÷Õ²ÿÁS••“ z}CVfæéñcÆÄY,– ˆâ:¿PQâ;€›µm’Ó¹/\>¬ªïÑw<×ääååYJJJú¼b ¦ì±ÖˆaC‡~ôÍ[oÍ&¢°<=I’Rož>=uÚ”)u�.D7E*loh“åq’ªê5M\ÙÐp.\>’ªaÙË]�ÐÞžàL_e fYS�$I•sgÏ[ÑZôú¡ 2DJ ’Ëåû¶9‚MŒþ ªjÏ¥ž,'G*—Á”}Ö-À¨3çÎ}� "¢Œ:]�/ˆ\.½¿¾á"˜@{!–zÒŽ={¦:Z[�Fã¦ý|-Ò\XX¶’\.WB�FI 朅„P¾ýåj˜9yëöí•ùR4nm¨=]ot64Œõ×·W>²ÜƒF¯ªQyæP”ý€ût¶¶µe~¸kW%zFÒ®92'Mª„¯uKÒ ÿ½ÃEä›»¬Š–Ë긶îå_UuõÌÓgÎì�ÆÍ£‰¢¢"ÌkÛ˜È.þÅçúý¾ÊæA8“Èï”ÀG{öLnjj:-!¢&*óiZ°Òf›*ý ›í^ˆX·å}•kùòåCE‰ wÆ~ÀQÆ­ï¾›îr¹jû*HÐc(3&$”8¯i’]Ì/äååY‚1+P”¡ÄüGŸæ#Ååå‘ ¨(JL¾¢꺺NY$é‘p•í°@SGGÇÐwwìè1)E ´;]®:§Óy‘™CZ/¯]»¶ "´«Å�rGÇ?ÈÍ X&Q°té&zÀM³ Iz\ˆ õùŠRh&ªÑŸ¤3ó’HJâ Ö߉7ÝpÃî ãÆÍŒ€‡?¸¾llth×û�På�Q¾Íö'0ÿ«Os#€u*ð†Ž¹ZUU"YÃD÷‚ù^«7”—ÿ"Ìg ›í~f~"æÕ`~²x!’äÁ£u:Ýù¬Ì̬è}áªùâ‹#»öîMhv8&úëÀÌi5uui5uu^Í�¶ªêcf¢.ˆò3â<.�«D€, ܃ ðëõåå¿ ç!VX­s x–™§¹›.1ð[ÉlþCqqq;~aŒ"F0ìæéÓß?fÌmaÒ{¡Ëé¬ÙöÁMõ—.i#ˆ•Þð)IJ³ÂJf¸ @¢»ßH½Æ>òm¶å LD«×——ÛûÂûê:[’¤~¯ûû¬²Òóþ @GÙE5ëSTT$U?¾”�g~‹;Ö+´Êîïì ™ŒÆË­mmñðŽ® T”l•¨ªz?„Ò:AT¬—¤_üõ•W¾ðô+T”ø¢ÿ†P´?ÈÑu Ló#_~Y›oµ>¶¾¼üÕÞîß­læ~Ou¥¥¤´VUW‘y)ZËyy(7w¤S¯_¥v{}N&z…Uõ—%åå^õ +–,Iî ú@vr ð·EùI±ÝþL NW•íRÕ¨M�0vÔ(�²ï‡ˆÈµõNÑ7<¨(©Lô„ẍ/ÈÎD?ÛPVvÊ étÅè©ès *!`¿ÊÜ$ aæ˜(Oäb¢5ùË–íY_ZºÝoDmuÚ™sçqfó}LÌHôÓö�aéé£eYv¸ËVøy˜,B²ì‡%ÉEôCx ¢ÎÞ–ˆ~´®¬l º|«õ;(ºoBT"™L…~&ÌMŠ¢¬1•@$T„|ªº¢üïðà ´7Çèõ’““é)))IIú!qq±“)%ZÛ0Ÿ8±kÿ¡C³ ÖÙ·Øy,ºwõöˆúi¼¾Ãí¬ØI’´ª¸´ô½`ÌWØl‰ù[š¦=g/^üzoË?EQbÍDg vdIºÎ_PJ!ØHˆXq\gWׄں:ÔzêÕ˜˜˜š¤øøÆÔääÖÉÙÙÃ#-óýZVVÖÉÏ??ëhm ›àHˆä~-[Q”3Ñ£èèX±ýðÓâòò­¡ÊFÌs´×Ìüt°u¶ÝnoÉ·Z·xÐÓæRÕ›ô˜,%ˆzäEÁ¨G<¡„Jˆx/H���uõõŸ8qãá“'Ãm^} ¢ÄEsçvéuºzÉ>†»V;rÍßW_k‹Å"AäÓT�ù‘Væéá(zå²eP\Æöö7C¡eàs¯k"¿†¨]úvÿha€È’Lpÿ¾ÀÂ#Ç��ž2qâEI’ÒBÆ&£1ó¾… ?ÿû¶mÔÖÞž±çAˆäÁÛÈi®¯®k‹‹‹Û l¶ï³ª&ž�Ôëcö&‰*×nÙÒ )ùÌqÄlö×/˜SÓï/!ÀiUU‡Ÿª¬ü`BffDʳɔ¹tÑ¢‹ïíÜyò|MMDÑùíûÑ=i±:ˆ È×!Þ:m5©šsGŠËÊú$r1Ç{50=ÓĆigk P¢®Ù 1Ì<·ïС̬±c‰(>Q ȲœvçìÙ©õ ÇvíÛg¾üå—£ ޹xš1Ѓ8‹ål³ÃáYjE5¼À@ŒÃ�eÌ<Úh‘ß´X$K¼¿hp:�ŸWU}´wpPjrröâyó®_ºhÑéi99{S“’*%Iº·W›nÞœ9ÏŸ´Øf Q`³ÍQަ‰»œÎCþúF ÷,jk�ãFGí)Öb›3q"r&ŠŠfn%"=D¾ñzŸƒú5y VÞsOœ‹y-¼ß²=7mò›® ײl`1 fÏš•Œ / "3Ä®[Gè®÷ %Çe4¾±;£ÌÅ�h±l ÀF™DÔr÷ܹõ:IšŒ¨1`ÊV%Ö$Ëã$—+…‰&˜ÏÀ�èi¬» ‰‰ Ä'e? qê ß:kÖþX‹åá‹ýÏ ³$Ý U}‰{ùïW»ºîí-Ôê0’ à0fäÈí£GŒ¸%Hÿ�À5³5h%æß'´·7öÖ)eO†p:hH\ܾÙ3gÞˆH¡…€Á¤l3mh2äd�ͦêLÙzˆbp‹,IUwßyg,õë¤ì01RÕ£&æÖh)ÈÛš̲‹íöðSãR¸x±¹Ãl¶�ùÇè.€'ò­ÖÚõååÿ¡í̲ÓÀd4žKNLôÝþ0à`æk¢ì@X»eKëú²²uªÁ0 Àë>¯Î[²Ä+œLÙà¶öö Û·SUÕ¯¸©¹ù(3÷:�„€A·K JJJªÁð¼‹óM¤Óy�·LÙG Ž­@ýåË·l~óÍZ§ÓÙk¥¦/º:;ÏmÿðÃý¯UTdoÜ´IÝ{àÀ'-Çat‡oCÆ`³l-JJJ`^§m#¢ÙÚëPÖÙ« r…¿jlnžòzEÅg÷ÌŸ_3*]û©ÊÊCŸìß?^UÕëÀår%=uꦣ§N±ÅdúlâøñWÆŒ™l23C|¦AiÙÑ! ®½u�½b§˜ÓÑÖ6îÕ­[cšŽ€[«››�¼^QqvçÞ½3UUM€HP<àIµÈÑÖ6~ïÁƒ7½ñÎ;!‡ Ø[كʲ@í.Ô÷@ xëÜ ¥³³3ãµ­[‡ÕÔÕíÖvp:�5;öìÙýzEÅ„ÆæfÏ~;ÄYPÏA$x¯ðM¸KšZZ2XUC‹{—[ :e“(âÑÂkgp¸Q¿ ˆÿß™9}ÛäL›<ùÍÌQ£2ªª«/ì;xp²»Jiµï¸i´pBdcvø££½½*ÖlZ\ï3fFhC­`"¯Dn$ñì½'Öœ`ÚèÐüòÍ›svúé—ªf@,ôÿÀôT´-pçî®\¹â÷l_°÷¤Úßã÷ćrsÃ:E“Å�eZìÒ^DZr¢ á-Ÿöw BŽßCÏñËÀÅK¡z@»Ivêt¯¯¼çž€'ÐkQ`³å’00X§ª^õ#})Æ©‡8tÄáà9aÇcað8µõõ!á_ƒ rªËhÜ[ (½†’WX­·3³wh•ù�ív¯-,ѨbÝëþ‰àò•+CÁÜ ‘,eÔ2p<í]aµ¾)1—’,Ÿ¦®®:ètqNæÑ{ám¸í,Ë?õet­�t>ÌœØÖÞ~Üd2ùÝáë�ªªÚÀÏ@N–2w1Ñ]¬ª€,Ì�"a.=âosÓµ>Ò¹¢Öõ ACªªäÉî§!Ž8 $æyëËÊ6øûðZ[6 â/÷íÜ·/M§×d2=C É’KšPêõõZe÷·eתù³s%«ê M�&ªA˜wðJ\KË+¬¨X1þÁÄ7!Ž…÷-3#Š%Çî-Û4M­//¿R.((0rsóX–¤!$Ëf‰ùŠÔÕÕ0bòäêP77 ËÞáÜ<`Ttý^O®…»d¸gˆbSè'�eâ8¤2ˆ“‰{[×Ä—RŸ,É?‹²=¨‡Ÿ#ã|0Ç7Øq­W#ÿ¯ð•²_){ñ•²_){ñ¿ÃsITz†|MIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/delta_beta_range.svg0000644000175000017500000003515514757047403031030 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/esrf.png0000644000175000017500000031660614757047403026517 0ustar00paynopayno‰PNG  IHDRú,êü®» cHRMz&€„ú€èu0ê`:˜pœºQ<bKGDÿÿÿ ½§“ pHYs.#.#x¥?vtIMEà 93Xgc€IDATxÚìý}|\gyç�¿Ïó<�$?'-UJJ+(¤Ð"(MëÖ¥ÛîoØv»ì¦´«–P.&á±:)�!à•¦!Pz\©Aà˜@‚›Ð Y‡Ž1(A ²cE’e=kæœÏ÷�ûœ±ìþº/¶14>¯×yÙ²G3ç̹¯û¾îëú@ºŠ Ô>pÀrj5ÅXÎój<„üí´¿•?wüÇ=ÎÍìÿ¡Ë.€];ÖQ°-°ŽÖ�Vöªâvóÿœ{þ�›ãÜŠþ~܇U‰AO³X’t7–—ëBÔÂêÄxgOnYX€%qnEçfôÿPGЖÝ«òNtÀ²×ÜÖíÓëÜ,ÿ89ÎúOø1Ë °bVsh÷ðéÃÍåp³×IøÅãbã ØÐÞ¹Šûãç8—ºÿÄ– ¦ªÐ@&È-‹e!ë¡ +ÈåpsÉ-‚µånféWël_ý¹ã±9έè?ñ‡Ú€­[ÈꃤÜp¿7O^Ⱥ’Ûì¾@k'7E«%«qê+˜þÜalî¶¼³}õçŽÇæ8èÿQŽ—„:�n¼�¤Úî+p%C”­$MÄ¢g&µÖÎçãÞwòÜó¼çôOüa¹�úñ V¸ÆV·l —�*tï}¦}%/pjDª=ûO­ëÀÏiå©¿©µ³}õçŽÇæ8èÿ1Ž„(´à%éÊ>dñS|é;@Üû0ÖÐÀm<뙡^Äq¥õ£}ì¹ã'å8WŒûI?,ì¼ÄzÁÔ�ÀÆ�´ õ’—¤ˆ7ÁöV®w­·÷âýÒZ¡�Ëšåö]LÜäܪþx8έè?áÇ�uˆ·S±j5QdÙýþƒØ›±_»ˆKt´À¡ý:z Ÿíë?w<6‡û£¿Å¹ã¬‘E­¦¬ÅMH\i?’•«‚mýw¸ô£ãñ×^»m`ŠàùO6Âmm.½íî;..ógûÎÿþǹÔý'þ°lP²ËîÀm„¼ ×­W"aýÕž~ö-àZÂA¬èT÷-CÌÜø^ÁÒÙ¾ƒsÇcpHzœŸ”$rMá£Ð¦&‡†<ÔïíÁ!Q”$숚#B;Dn„Ñð¾ÿýȰ¥éÏMƒH³Âk ¿!< ·ó:ä Ù’8Hhƒ!§|ç@FR¹â� ¿ ¹5±R°´ É*h­v‹ï”wš´ÿÑÇw�ô§ßÖ÷èÏËîÏbH;ØÑ¬ÞÍ$ýà°{§ÅÝX?Î{gñØÁ;êÁ–‡a ›ø#õп¸°Hë6pÃDz,+;èÔŒ”dmèv&[±7–ÿ_t ?„ž³=ÓœõÙJW5Üc¢|HG„G(;›ýKN¶"MMQž=éÊð\Yj—Q2±/+4+¸"?B=<¥õKX}çâwàé9ìU‘Æ;«Œ &s�+ó§!'d ³z›{m5LÆ@ºÚ�íÉû¬¾5Ï·[¤%J $²ù—eÊ'ßñèÕ 7ŠÌêmÞG mBÙ kÝkíôsì>OO$òÜz5‡vè²"­·Äß»MØ«b–-„!n=Är/e<×Y±›øjà�ù>)ÏŠ.Ú +»_s_ʘw?Šþø:Ïúœõ3 !›4Å<"Š ƒ老œA�YŒ‹®u󇺨ÙI×m�-BÛ¤ÿnˆ|v¼ë8ož¸ME¾Òv¸ê¹!4å›ß‘kÎÐ6×[s²-Az–ià§ï_3›ñÀE¸/ñ‘ éËáë«\ _^èYÚ¿þ~}?gî5›$JûÇé¢_OÁ}Ó×|ê+._^´¹yÉã£GyúMOGr£&þ�‡(JØjâ ·—Ñ ¢öƒ�NhÏŠ®iQÉ®#ÛRDNvž ôs�þqš•,¼Ùž:«–• î(Âé¬(¡lþƒ\aˆ¦“é¾r“…9Oåægà¶D>‰qÎ\b£V™XüüÊ‹P³d² Js¢'Í ÊÀ=³w=3™ ©9ÙÞÕ]ùT^~e‘Ë9¢•"Ñj™O.ãþÙ›QÃËî/[1;{üô3«~ŒB6��“—•ºÑW<æe1'¬µe˜Mr,Æ_û(½cA 9û"ò'NP”È}H”O�_?Ѧ{ñÂÄùY3‰–׺¹.Y€]Ž©¬ŸhØy¶Ç×�Çyn�nöiÉ�XQ„]«!Z5KfPe‡ ð§„1\i1„ Cëö”?ì°ì¡!’€(ýýmÎylk}�ëíGøÈo`¹b¹eáäAÄжc,øîÇŸÍW7[ô½Äzøa²%Öž‹wŸé�¿ËI¯ˆÒ3;b øû㫞Äÿïw\jW;Ô®þY~ï?ñÙpÿÔﯿÚüºžü™[¸Ò>pÀrÀº;ûÿÙ뮄ù¿sØ4Cò<�o%èTÎ+Av˾í¹oΉD pß}Ø<‚75ûè±·°};N׺ÚIa¨ÁKj¡¨aS“õ"°0pÙ÷o=ÎöLs¶ÏlÚI‘©æ¦©äúªï1QŽ"³’ ³ý?d ¶„;.r{ö‘œZö^Ⱦ”ñ\•K^‡µ$Pl¡ØA1Ö|R`&aóÞ73Ô(0PwÓÏÏI”¥ÿi¥} Ž[Svíašæ‡v§º¯—K•CòÛ0ÚDN„òÙ½±.sÉVõ¦ð›2ßAöó÷¯æBöþqºL-ਠ¬´ÓW+i{¬Éæ½35”òDòG‡ 8±¥ÈØp '¢æL‹Ê¬èʶõÐd-j¦]…&¾ÖocD!=íÛyöÇÚÙç?qV¿€P&г��<5ðÖúœèY¿gü?¿ï™=ïð(A îrá\Šrrz¹åçq“Ä¢%‡$ñhÇ>+*² ~AÏAÊQ3ƒÆÉIä”n²@ìËÚ‚Y»)ýŒ40=$“¾KéÙŸÖ °Õiš÷Ì®»äé=¤×Ÿýig­5![Â{Æ8]IF , á)†5Häpç?ôÑô¯æDQD¾$Æ/%·CäÆÍýÙ³¢Ëº:ïŸÕ"ÆEn<½÷�×´5M»íßäî¹@?èì„Ïðh0€Ü'(ª‰?6J Ýãf%í™]f‡Äv3ñµ›@#gŠ_ü�ýl$9­+ÈI& Ï8åO¿Áâse¾®Ž´Š|d©Àè_26DéÄS£éKôè~ªB^DÍIûèþˆðÆÉIBÈU¯nzÔ)6 îÒñ~]ô„¢ë l¹Eœ'd×�sH'E!¢ædŸ$²¾øÄy¥º(2™LCx·ÞOu\äÒ€žˆ~Æâ=ßÀþÌ<ÖÍKðñÓØû-.ßζ¡‚y]h a;Ÿ†<#^Cx³¢ë¡ÓlXär¦¦(kšŠHWtñ„oLs�fÍê†Y/¾S$L{ô¦>¢s+û¹@—DïAŸð¨»Böx�®‰}äâ+Ä×(ÁèWØ$ñ„e±#ļ®±‹Âè0�ÖÚÖz–OL�t w*å&Ð[A¿p>ñ¾Äï}ËÏïG…K÷“ë~6‘g0è�õ­Îç‡vHÝm¯OøŒí 8qQ‘‘™*:X@òyé%ÞÄ`®yÃwRMùìVPÛG>Ë ¢'E‘HÁ;‡'Èåq‘l$—Â}í"‹‰G,�5¹¬$óÊ1{Ü»Ræð/AäP“Ó'S„%ÈjÙ96Jpx‚ü�‡(Ò?âÑ'B—GŠH4‘gXÁ¬èºî:ºGÇ$Jä3 ‹)Zž©²SlP§]—4)K”!r�‹ú=TÏù¼ï pW;àÎeü·,rÞÇB!;CÙIf¿nVøìyœ ôs�¾n`¤ˆ­‚„kX“.¼ýyy³¶a*�xÅe%)“$ôêùìWNiëg=|ôûßÿ‡µã:)–UÀ~å(ióÄoèAŸ¨�Dˆ_w§ž²�‰|/c˜`“ÈORW×!ô\³ºËàÜ÷ªhóµ+󴓀Ĵ½œD¸«Â™Ž¬¶¶1þŽíLäQhïùãbÓq±)Û÷³ãÒà�›¿+Î{ûØ€)¨yÏFO…Õ7Úèc=´£Ÿ¡uùnæû„Jb"Rw§e¶&#�ƈêð² àѧìè$¥P”8¦2ÛNÿr…ÕvžXEâ¶Íª°W[¸SÚÈ%ýBö #È2fò=+î� ôÿ�žõO×­ é¿ÿ@o;­$gÿ¥­(í1-0�“»”ñŠ|Ž©Ì×¼5àTì±,­Ù¬*@qŽ9Q½ë�H¹aQy»Ø�±¬¢“”FÇÒXЉO‹k) ,BŽ"eÕæ�Ú¶�γ*˜9ÅX§…ÛÄkU4Ï3´ƒ†¼1±iB¦ÝtÏ Ûd�Ž|å8›nÝèD‘M·¼Ý'‘Åšð²=~[°$‹Åvá_¦{úõ°„&òÈtÂÓûØ0-*c¢2H¿‡&òì×S!žÁRÙ´…ÕZ„Gd‘Ä%’9Þ¢'a84^CRœ~�DÎLF¡mVùmNl)ÒI™x5xx‚üIQ":Y¢úæ×˜U€Zf‚j +NÌýüáë hÈuÓ p×·Ø2àMS†_oxõ}RÆÓìl\).a]úÿ}ÅT7›¬ÏþøÜúº þ¾@W:»g(;×Ïô5G5òÍÈzHÝeŸòHž½ü‚€Y¬¬Ârb¯z´Ta¥ÍF=ŸC*�“»Z Ü~äÕÇé£ÒÌh¨¡ì�:n–bgm°šۅ ð¦?-0�”h¯, æ„·hråi‰M7¾‚HþwØ¢Yº†ÿ�ŠRdÛ( „ìq‘›š¢ÍPE*ÑÛºÄf-1$ô5“®»IbÄ'âU¬Óº½d£‹ó¨žCÊ¥�î6…?5Eù_¯e«¦(ÊG“úÿó«,Lêo£5X3”½ÜrIV<Ú¢÷Õ¯æÎé ª»i'`czæÒ6œ ¶±�Á‘#’O­ÏÔ Lk³\¯Ó…”£W?_fZ>KrP KÂU GòøÚ³�\úäg$£áQ‚ýCäÖ­äîú@ïPo¥N �§…Ìõ�že3’X_LmOŽ~ÈVíÇõ<ëð£žû ÖÛìWgE×q±)ƒ®ª‘>œ´èÓypÈ‘;:L YºN‹�ŸŸbÛ]œT‰žOý¥Íû—þi!Ïç–mÞ6 W]ñù9S5¾t¿ÙŸg ƒçnx…±1*c2+l¦Ô’õ׳‚C'Šw�™Kæ Ï‹Í ìI6+‰ÇÃKø_½‰K•«‰ü¤(À Ç`¿7:F�¡ÔL›Ê´ÇúB|&”'8p½Ë§×r,&yZ*�ÈðÑ?¾Lî“ ¯IŠR“\#’wèűQ‚&ò3‘rA6‡NÉ}å&­8Ć?æ¬ÿtŒ½°32)ö×ßÏ>åk"MÉå yYöaVõºKMyúB¿£Ø³›`üRrŠp¨É¡w4`T¼ÿÍo>ísÛ²Ç?/ì[å‰7¼§OøÃ"¹•êºIßY�®™<›e¡°M@¯OëÍ¿…)cQ?¬ÛîìÇÀã"Ð3ž²àiÏ7™•9Ñ3›a¨ëé—g„ šη�€1‰{E÷KO°EyBUv°öì*«ïrY½ºÀâ3Ùqiîƒb˽¢{8k™Ú;ÌDþjN�‰ršònjÌP�Ò@_OI¯»àp× ENÉ¢�`ʼnE"X9%°çxHpÇ~ÓÎp_÷:º«V3“Ÿȩ�ךH°½f*÷;UñY¹ª‹d!ÏZR$Ñ’ŀֻةŠ�3ÄÁˆðˆjNèÙê7ÊpRw/BEÀ¢¡•¯~Z²PÛ"i°§3rˆ•c1�»¯çuv2©4Ðk�ɶ&ˆœ,ˉ�³þ>@59ìSžKT¤¬‹«ÄWçÑ_óÔµg3¦MÃ"¸êC”³•Ö@bÕ¡_�w‚u]�ÄZ¿r_pXë€O�¢èvA~ bàñè"o‚m½8Ä™ªnÆ„R§‡k&ƒaD"¿œ®c¢|DO�ÚêC>ãCÛ ›"J¨ß#”}ëýTeXd.DN´�¼RàÒÜrUËZ_"¤îê‡1ÂÎààm4Yà‰¯zmžµÄgEÐná- o¥'äÑÖf$žòüË©×s¼üöîtÏÐ//ý»‘#B{êÊš¢<ˆ¼Ý(8q‚¢é}Ëç)·ôòÔß{2ÊPo ïdHIWSTÚ¦’pûGÎd:ƒŒxJ'B.ÚR¤¡[_wE‘•UŸ%Y,ÈFkqb-N%÷·ÙúîËÑž<5e�b —Ùj˜áÒHœ7ÊXÐDþ‰S¥C¼v=Ľd¯QZ4­]F)1 šIÄæ ÙLvá€û}㢳}ëœY ¤cc}«ïûTuÜñ4½—(uØv?1ð¸ôC¢8,‚hñ"Jhë{ýE8Ã"™¤0**·Šê½¢{Rú‘WOWÀÁ°�<ö+W§KG(¦PÙ ™öžÍꦃ-¦ t³kÊVÞõäó& ¼éÔ“Jħ ,%K¦gkfb%Hy�.ÀìŸ}úåe¢‹YÊÝ�”MTsè@z×-ëT~2˜³:ÅÜu×ÖÙƒŸÜh 2¨œ]¦ÀxöcàqèÙÃ|”ÄP#e•�™�m­C§u´ÖÒßGø¤óŽ;(«ß@Q…‚�ºû¡—QÖŠž¢;K=w§ÿG(Ÿ§h3C“jyÔEC^ÿHŠtK9ëé£Îja΋çè¹BTÙ¸Ø�õ¶‡<îX-qתËUâplñŠq6ÖŸ‰L�ö…ø#*kEÈYWq¶EÍÊ5‘?'z ÃK^ˆì›î¤’®ªåãclrDÔázwøßYo»‰ßlR’¨NM,{ D)mŸ Ï“÷?+ÇŸ?ðõ¶Ëaܹìó¥U‡×=ÄSÔ™(½â lˆÒ-Ji�ͶRëžWM8—OQÞ% |èX™P^¤*(H»>59Ïå–rˆìfd®WûÉM‹Êi±±Ñ 0´Ÿ¡Œ’¯i3þ�ÔÚds¢ç´Ø˜ñú3ͽõ<ü Í×AKòèâœÉÎÎ~ <Ž{<ÝSfMâ,]é;¯�7¾®}B(ŸÆˆÍPÍ`¤B–a©E¾í±Q‚{Ò?…f" ;µ‰Âå—á¼r{÷èþËW0ðÐvÔo„Lu×Rgw¦òX7ÏÒõËGÙÆ� V¤ý‘­è/)<°�èd‰�ºk �°Ò­’�j~ºöÆQNÈ»/])#jNˆÜ°‰,\<.6)-Œ5…ߌð�på€ ¡¡}š(ß›²ÝÌ÷Úõ“”FE…Þ±àt^ñ_i¤ˆ>¾ ýOÑ4Tø½Û&eÈ/2»âž8AqjêÌžú`ÃpÊG„ÇïÿôylûýArÿóz‚p„üg_ɫ޶E> e5{t˜@ <¤ÐœH‹­)7…¦ÿÊ&j>*K ¼už³Lc}�gci½Ÿ¾/ÕïÔF~ bàñèÙÀŒpö™j­šø)aw Ž›µŠ$qèE¥E¹~äe¨²=2 ³‡áLŠÂÉ�Ò¸ÈÕ•µÉäsÙÉ,>³€æ]–•c1 8¥ ª¢E6äR.[ÑΈCÊʘ_“¢0RY È�f¨vØr—*7’R]wgÀ¶ýãt ö�kÈõœ�‡d™ýùžÖŸß¯‡ÿã~žõ ø‘Ï´ØV»Ø<”ÑÞ´‡ÚÀS?žL�÷…øûö�oï¥{)†i�n�à ÕÙ—ÚÍÈ€.$r:B±^§kh„’KCvÎo²xŸG[I;Çœr,Å>§UbE¸ïþ6;—¶£(ŸµñÖ{²¢ÎDjÚ�Ñ*£“”F&)0ªÕÝ�qrÍÈðÁ3pÌ^®.Þqå‰ òûDÏ5¢+¬SY�*LIê/ð¬Ò¯Pxû^ÿYœ7~çº÷óôg=)#¢@Y¶gùoŠ ™œuX´¾]Ehk7Á.Qx‘¨^>EyLlš›$65‘o2"3¹e�žfgûR¯çøÂC\þaÒçÁÄA-�X.혓͸r|áö©)÷Î[©Jiû Y™PÈúVZ–Ée6„W»–Ò°öï —’^œ&†GÀðh�mMPh_|±©DÍLi—(âýÛ”†~|γ~?úŠŽ}í¥�ô(´Ãô¡ŠÂÀ8¹AQè~Ô4âQ„Öð�°¥¨´ £´=§”l15E9û¿K÷“K5Ö W\ÕntQqº<à[J�(1V;±h [²h)Ǹò´^óìUÖ‘cîÔ  §¾Ÿœ“¿U›†ë y ÈÝûRŠ·ˆóŽŠmu\òjMJõ“™Nü w…¨Þ9M…ШÍ4#üHäÙ­€ÞùM=( ˜—a¯% Hä±&‡i9Ä71¤­4T@ý^˜ÖÌj7âf"?ôuÎ3œ~�¦J½¢ŠRS†Jz*öeà °ê!îµf ÓâÛ£ÕjU·�*œÿ•ך^"˜Nðæ„3ŸPLHV}ÖD¹ñ4Y@õ}M_¡ª4T;�ŒL¨³?ßA=7xÐh ŠÂ !y©Jnžqr½cfÒRo`€;rÙÄ<) ³�âÕÎÄò#9Å<¶çO¼ ¬°/»ŒåQþ[+´žoõ‘Tkä¾ñÏèìþãðgw‘;ч¥Û¾œð’CÂö·ø••ÛB+Sqm‰+-"ËãJŠŒ‹ÇþKY»0Ä!²àðÎÙ¹dÓÔ½Ö*ß½ÈÅka¹1ÂÆ±‘ç€Úwu +n³|Ñw¦ÌûÜö™Ôñ$�E#t@ B_†‡.€"÷¶›ïâ™Ö}ü�]«[zðFVž ±ýÖmËrøÖB­ïÌ`�g…i¤õBh­4ÄÚ j]xa³Ðæ°øÎþ×µ9Yƒ6m,35â.6Gÿ #¯|#ó·%Ð ü›Q`â5.q.æáöËžÌòºñx¸áÓw[ûgÁÞN$/á÷FG[/�ä(·Y€5Ї.ÛA{û_°Viâ¬Wwý¡ÇÃÄ,ßûäÑ&AÎÂÊ›$ky ü¼;û¸{Ü=`Óìk}Ä%—¤®9}¨ÄQ´”*û‚e[wã�k`åU»hßê‡V×#8€8°Ù润Ø�¶ôâ_ñoöc×ë¬é¶ñµìÒ·¥�@’dÎ.}¸µ³=ðÿ¯åÇ`¶ùÑRw3£ÿùç]t#E$ŸUQ³Ä§´�»´©ÂÍ÷te©ß¥¯e+¦ªÞ©^kÖTƒ§+�¾kh7‘/a‡È™¤ÀäHa+­U¾×šoáÌ{1Æ[,&6Zõx()¢�£ºY]2èmZ$U‘5PÙšsZlüàMl¿UT�”JžëqXü�úXÝU¡uW‰öÇ@;‘zh46š¢V˜�@†öç�rôâß”Ã#ksÂU«e2W-‹ÅÄb©•çXR¦ýâ½¢šu9-–ÙýÈãã§7rZºÐ²ÑM ÛºÑWŠÄ7<ý·ªÊ^‘\úG¼«¯f³šøäµ›àÄ cˆAŠûY‡'9&‚O~ÀK$ÂKaº)¦Ý¦¥"K1¹O�ýÊ1n e»Sدicâ›N‹�²“I¤ããw_φ‹n¤ÈØÎ€©©2j–Q•+TeŸòÜz¼q‰óßñIž<’¶•m·ÒçÖ9Ï!ãóÔÝ:Ìá|JVðyÇóºÑd�¾¹gsÞkÿ’Í{ßÌ3–~ M䩽³ºC&?ÌD¾³�£Ö ôHäû3;&dÓžQ‘‘,š–Á“ˆß\`L6'…?ŸàM {Þ�FXRŽïª]�d0×Y!'Má3¬uV°ºõ O˜=ƒÿÈF´­ÀÌL•ž—^žÍq×Z‘ã­®|Mÿ°Â¶ÿñA4VL¹×Fê)Ý—Ÿ8R,ÿmžo¯z|Ïôå­UaņÁfµ…Õ–Çiù|{¥‹µ·ˆâÕ¦ëPºgÜA t™Pž-ôA›Û–<¾®€oÉçÛkßX-px…îßþû&òìÙ—g{-/QfÓè0A3Â?"Šã"GTsˆŒbÌ™Š5†¹m‘D†)Ø–™�‘��¤0/xèÕ4ä…Mük#³u1ôZCºOl>nê†<³NM½aj»{+L(Ï“nøE /{›÷¾™ kÏBÊ|œ�7ÏÒuÿ ÕZ“’:’ZáRË:éés�þØ®èöð(¦�Õ�—*¼­H¢"meôV^v¬lˆu×´”°Bä†È�š2è8$™v”?”Uqo¾‡®z= €aœ×Ÿ×>`´ËÕ²Xˆ-[-³×ì~ý8¯˜}¢±UZñL+¶}Âïê7ýö†<ƒzS©«„X”…ÌÞßjª©/ÃjËKØúûC¦yß§Ø ™š:Tì!¹3ϲ¬l•tæJ "gè©XÉšËJR`&éBw09R 4¸~¶EþVZŸ)ÐjYœÁâ2î# Ì&8–VóÌiЏcªÌ ÿä¶H”ÔÄïy¦–°£0“Láp�ºrŒžpøVŒ7Õš´—±ð½¤Ì¿ÎР ÿ꽦šõå d7´;û;�†§ÖÜhPÇ€�^¬r]ÕêºQReUÝœJªè�;P,ŒŽ �¥�õݘLÕw2Eøq®÷Ø®è2Õ|ÎÓ/9¼o¾L’ø¬&>«I‰vì2²ÀùºE~JMo /¤îNMsÅŒ¾8P7�Ǻpwï$˜…1¥ÖÀrÙ{¤kÏÊÓ> KJƒ/±HbÍóÜÖ¯!™­DZ¤Z¯¡n”Sðê¸ìVÀ¾”:£*/xîo–˜YõYL,’«-r‰°Ú‚– mFple+¯|�$¦E%[‰� ]$·{Ì'&¨["˜I°I`5ÁJb‹–\–Ÿ©¤›äv¤<½£A¶ƒ,~ºï…›X•Çiáϵáaá>, «±Áã·”cJ]|s•m_úušõÒá ò·ÞOuÏaò¹ƒäÔMÛŠ¬»‘)äÊ 7ÐúÕ€‡¦ð¾'œÓ‚Y,·+¬�î¥u ©¦šF�× áäÒ0@¢,Ð;Ú:£‡c¢¼S4F¼ kÏ)ð¡¥�HÖTa9ÙÊ’r\¿ÓÏ1Ϭæïø>$ßúLd|�¾þÙÿ�›@7�:àÜeZ_%ôVŸo¯aµÜXxËÂ^Y+ÓL6 ·§ÐHãO®Ù6 ·Wc¢2‚¼†ðHO %ÉôÓ›:ãBxz#›^󪀿¼>àõ7ؼçOŸ†6Ð/O½ñÅC¢HM¦?/ʺšb–I4‰üT{Îì‰÷+‡ý¥Q‹ÜÃ1ö„pNǸ©€íVÖo.2ú‘&òw œ„ûM±á´Ø¸�ù�wñ`+O,ü81øù¥wÆø¼ù‰,W×´ÿ¿Šn3Iôüü° ÷P☠  JðŽÇ¸±GœQb¨¯«bÃÜ8R<.6=xŠî±Q±/ dY:QL{æ9¢š3%Ê:L�D¡n¶S%~ñW7œÇþ¸Ä«?ˆýšáïy/;Vfh��±�A/£Á™VY 'mbpàî9µDÊd™3�r&>ßȪì=RÜÅd¡—Ñ`ûÍž´ÖçK”LPwAö¡ŽŠìþœ˜,(Ýëí@9“¾?Ø :TF±Ù¯Nµp'…3—à·eVâŒ9¶¦ùGŒå‘=:FpË×9ï¾y6_„þsÊgÅì{YMÈ­ŠüŒl¦‹¶,mâ{zzñÀ8¹—‰r#sw©©ç#Ÿ±�èF˼¾%ìÉ5ì�5I„µdXvÿáË„ªhžMzˆ ·šÖW“ÈO-¡Rk¨Èï3E:‰B½Nפ(ȤÖVêŠPiÊu£*»dÀCœ1ÁLIJ™hžW†i÷ÇDåˆ(6'è1ʳÊ+å$ ~Ï'þ+‡cF´‚aÇf[ä~)Æm½‘?¼³’µZG ²~}ØL]q2+íøtÖÇÿã%Ð'&È_~‹ È}ö,‡<Úq€”G*‘¬æ¹qáIè¢&‘¿UÖ±ªr¹/¡82ˆ·‡íùËùé²�]#ôÕIµ z‡È¡šÏ8¹íéNÈ4ÕØ¯ŠÍ�fÃD&ðx‘Š\¡*Í/�ßLxz#R ©ÀäHajв&)ž ÏÕ/-räPÑáÓŸ/°*h­Ù,§"턜Œójªã±ç¸ù¶Æ»R?¸Î Ä%*Òý;ÃU¾Ýò8-­bµdÑRžöZŽyU]¿ú× ¨k÷¨!ù„¢tx‚<û”wùÌ?(ñQb¤›ÔÆMÖp…«8žXÅš¹Ï†^U”òÖMú\3Û)ÝXDêâ“‹Û(kϽ£|!'K—3U6✡bˆ9DMŸ�¹±Q‚C©…µÒô;eÚ!u7³Íª7بƒº©n'ʇÈfhÒˆf¦Ï.¤înc¨À€Ü"ºÈçãóZk–�ùÄaaÅæc‹.º˜Ý DhOßDÅ%)K3TGEe$…Å®w­ýI8Ïúü¨gSøáÍtÁ ™á‡ï¬Ø¬¾Å€ÀY´d³’leí}wpKyÜ`Á]Úì©åÇÆ¨ÌÞLWºJø@ rÃZÆ‹îð–Ý="¿SŒí AHÓÀ1pu„¢æÙ$Ñ5ñ¹BU.üÊs)ì!xë!œ¿ü ÝòVþø78¦2Ú[üÇo±ñÄ Š�ª4û|&”·ùÖµAªÚJ°œà'-#×´dVUG"XœÒFZïéÅ[ñz .áÆ"59„ê© ¿w˜•…Û øR$ß¼6 ›¾³BJþ¹KE×ë¿Éj*AóŸ5Y(ÆQ‚ÓÖ)ÁŒl´j¡®Ú6-Ü-½c��7€\�ˆÞ ý§.žýÛßö.ü¿þ¼ó36W\‡7ñl$¹ô§{í~ݽ,4$£´ÕW˜šÊn�•T–6ß[¢”z†rÌŠ�g{ü?n�½‡ŠHVæPÂaòŒ*àÂãÏbÛ¼� öFžpo¿šø³¢ë¨Ø65ÅyH>à ¸sºÂ�Ójꡦ<—�,±o"ÏA š¥KbëÂÃl‰�RwGÏ0±:XîwRÕ¬!‹Ü'6_>E¹—ã›¶°öq�V’§�äiÅ& n'yÖXþרKÈ(­ì4È>¢f‰Ÿ=ôkf•gAó1Ì+Y³HL:O²l kÿ²ÀSžÿ‚íùÁ42fÞ;r¨aþEóB¼�ŽàïÅ o�·ü5ÝÍ_f@nïAÿ­&Í®¡|(lÇŸ'½þ—«œJ\Z‚x Vܵ{͈3º-ùL%e¾&~vï’'Ü�·.r4F<.U—‡þΦÃr‚5+�ŵ‰Š¬©Ý¢Qè#™{þS刚“[GmwDxõ”à ¹aˆ;‚ DMí-ò¡ce^=ÛÅU*s•Êõg„Æ1Û#°Øtó3ÈýùëØ´ûm©¡e¡¶�¼Æ¨¤Ÿ™Ù‹)wÄJÒBªÂ[Z/òñ“pžõ øÑoÀ´VÆ31‚qrì›È3£*jTù˜ºš,ÐìóSF×ö¥%.@¡Í/k¼élø³¼êZ ä…KçS“3PÇMYQ[5ÏæNº–R3Üyøl*:BqNôœždãÔå÷ϳ¹Äç?Xக<‰å⧆îNàl?ÖçÁZ0õÚs.3I@¢.¤€hyÑ�DÍ£ ê!n&2n ŒfUMfaÓœ¦%9’KÍÄôg?w>÷ Rý‹à]q=¥ƒÆ<¼…†¼H¿ØDM¿y\(#'}¯º™š*3Nîæ{Rtª¸ÛÁP¤�žn%ÊjÖßÙÿ�Ÿ@¿ú¥EùÛ*(µÕ�P~tžMŸ=ÉVBÙ½» >œàŠwREø}è…9™Ã™K %›¶lV•c~z#0쮃ˆœ0u)=q‚â¬è’èi"rEÊ2C‘OÔ¨R]þÕ‰°—…½c©e$£We³*—V˳”ô¢_§&gç¨À›n=\¥2Þ»>hñöù_Z.1½–ã» hÄ7NS¹b?'ŽïJÉ'©ù£ÛŒðu˜|&�%cÅšpU0œÊ/E¡¨µ7ÊX�¶¥òBùÅE¶IlECœk>hñ±iŸ;Úy¾­€—þeÑâïW(þÏ1 —í¦Âž5Ò/Ï|³Â:mzùV;ë´d‘´-’8 QµyÁÿúu¤Bc†êßÝÂyMê%1ÔC:˜‡ŽÎœÒ¶Z¦s§‰üVZ/¨0? ‹òˆ‹8qˆððl=‡ÉÁÂë�³Iól¾™'ì#Ê‹šÑ¤SÝý¬xâ ±Y¢úÜŸ¦ XÛ)�:¾d-¼Ñ1‚´íæžÌ<–7Ð�Çd£`zâ¦wQsêbã‘y6íÉK¦-3x�ÂØ(Ñöžnn?åó`‚s:•?Nä£$àx;à ó·v>’g½î*44+º¦E¥£ˆBÃcȤ‡H¦¦Ê”Gö•XQ@KKf�K»…µ*-a�V@¬R‰·€~£yþö16Ý*ªæºO–¸P%ÜÖ¯èÚ.’¯•IîØB|ÃÚ¿Ã_/laBùoŠ †_ÚBÞè‡Ù¤#M叿ÃéDÊ6ÅÈš3ž O˜�<��t¼ñŽŒ±ÁdØøôçrâ6ûðUùz/E¥Á¡K(;¥#¢5M›Ê Òú½Z ÍÔ]EhïåÆ"»X|êŸr¬ÖZä&EîDÒ r75ÆpÚòˆEõ _¤®ÒÀ8¹f¾ÑÀSA4¼ƒ4 YeÞZ1°Ðe‘ÃûØ{¤È‹UÎ4é)?"¼¡qr �çR ‹7x�'TÄhºU¨|üv—•5,µqæM€çãÆ²Y´ä£Äã´6òÅ/íb²PKQ_£ÆzÉ™]ßx˜-4ûÒ>tÝÈ$ +èe,P-­$§ä›´ˆ†wÓŒc�Z©¡i¦…¦Rö»Jx˜Þ ¤îNÝB9õus×kî 6¨†¢Ò§t<Øï]|˜|ïîT—ЈKf@¢]�‚Ë-ÿä1ŸØ¬ �õ=Þ±âÄ¢�à%²HT@1¹/ÕŸíBÛóMá7‰|s‘SÝ€”3�µ“Ñ`‡óìU‘ÂÞïv¶­üµ˜ÜªpÛ‰Eœ‰ =ýò¶\b6ªí‚&ò›©ó:m»ù}j3JM ³vß¹@¬o å7g¸âŽ�å4EõjÂéeÔîU‘ÜM×ÛœöŠ v?QÆì* U‰cü¿ÿ‘|åkûÈgíúBŸ¡Ks¤8õTèÁ•ðv Q`¿rô¼aÄ£�v ¡ÄY3À•ò\Lqi Öä vž¾k“œùÁ]f‰ÐÞ?D®&#†A8àÖDÖ~r¾)6ü磃BUhÊïþ‘yCîXçÅ^иû¤…D7BN¦p#yåÙ¦y63PÏ`¥%$ŸáÑÊá òâüñev(4UñTáÅHýÎ#jÎÎ�âüñT*rÿ5Hdä —-cK ÄÔ/–ËI@’P½ýZ¤ÊŸ=ÂùšgÓ\“žÆ.£)@TsÞ ‚Ñ1‚iQYü.çižMìSžÜW÷8½š=-ZÂ_î’ɤ¬vBá×sól‘üÔÍ÷šf7'NPœV§ÚþCœ~ÎhŸqkÉþýìÇÀ¿åü‰ç£‡`Ã�çy`Vïf’ Ä­ÉQ°¼¤ÏùyýfÛÒ�Ë»JØúÂo‚�à .X1ØwE(>Í’E0Ф‰ Äìam#ù,‡&móIýÉîv_Éõƒ–~ç·CZôàÑõ†¨„ƒGÐÂ.,Áš°¼¶,Ä‚Íʪ $ ±]äÒÏ}†ë×ˆŽºD8ø™þVmÀ²Žö…î/^HYÒõ_Àf¨ó5hE,îëç·±Â�eõ Y+ô`;x_·°ÛßðÏ8ýG±Žì á%f_ëoú°ÚÜ*Qä²Í6ý$D´y‡_Ú¹|`VÁ.-°Æ±ûŽ*x è²Tò¶¦(¾àsýI¬Ùàù´yÂ?®’`“OÀ]kq* ic·IÖÀε!hµ aËó>Ã#_Õ%h}±‰ý¥óHúÒºmÇ@›Z”0ý?P|~/î—¿ˆWè¦�H˜;nÑ~NsÉš÷-bÉs×À²Ü`­r ÿ¢{¹µÕ¦ú°7®¬å^Kˆ¶lÁ²Á¶7b�Ë2žù–”€ÚË »Áë'+vÎöL󣞇3ùߌe”¦îc©² ¦H—¿z¯�®Ž�?:¯ÄÑG`<Á›“ÅŠl´êÓVŽqå8t|kĦh†*„f¯6Ïæƒßâü‘I ½chÐÃ8Ĉ«B«UÃcꎲç÷8ÔÎq\KrYISð[ɱ&ì›OQ¹éÆË§(ß9Må²Ð¤ÓY�á )úŒÈ5¨äÐl¯V×V4°…Õ7n@ÎÓþЇö•ˆß¶•Ö èU…WßÓ…9¡¢¡ÛžÁm+íÿg`”Wˆ {�n®Q/R·õ\Ð_UÐû ´ÿÙ§ý!ŸÖ;˜؉*ìR¡J �¿Ùþúü„œK8R¬ÉÔ<>±?Ï¡Ùk*£Äf%ñI”'V޶l>½‚ã�Lüz�I�£ÌKÎ6®¶a E%t�Užp/Ý;Eº¯ž, Ðæã¿½±È×.qŸl¦Û9V×G•ãÐq^»c+QÍ‘°/ ))42Qéøx´u¶Z?J>ª£õžÊt[§³=þ7©{Ø4ÒIë]È=&ÊÇD™]*H¢Ù4iýˆð¸ùž®'³ü«yô°)Ú,ÈB-‹$®°4óó´žÿ<Ñ}�èÂ`Š[%6Þt'•~áíLuá%]’¶©"†Æ ÇËè£9Iò´×Ú ¬&6í” ²ö1®¸¿zHï•Ý£F);pëûÉML��dtáÐEEžùÌã¾ûfŸ›Vþe¡Ä�k‡—]nm»|eÎçà"Îû>ÍSŽüÍz °�Mñ:W×ô{KSÕkD×3DÅæ¯b}øÓ8øÊ,ÜŸø<°–ç­:|~>à-‡ý7³ñ=»0� ¥d�Ì2š”I"?ÛV]ÎT¹Ìê'}Vc%•ˆÛÔ. h„«Œ† ŒöVÌïa]‘"µ‰<“ƒN^fj¤§nïFç£&þëx°[ ˜^½ÂÒÓÐó{˜?å2­+-ì9ù,ÅyŽ? 0Që¡1b\`FÍD}p…uºÿ�’s–Ä™Éq}°›ºÅHÊ 8ÛãÿqèFÜðÑüwNS¹sšŠñ)ÃM�ƒFº'åÄ–"¯þõm”ÿ|û5Ã>¯¿ñ¾zÏ~Ö +d×Çéºgœ®‡{.Dÿy#kŸ¨ÐjäÐí>ŠžÆÊ®~Tí»�Ã/'@ èÆ"S*sþì p?þv‡«?ëóÎQ›Ëþ:ÇuÏïh¨÷í²¦Œøb¦O'uÐ_9î˜*oEï.°¼³‰ÅBÛ"NL?ÚN°ÚrˆeóˆJœZ†•=ì˜íblg�¡å0Å·²R¢�í*ê®Òº¼‹öª1ŽXI`F8§„·Ò6ŸÑ–�T@I‰¹E½©ŠT1ˆ¶ÔìÁ¬„%e&…à¾s†êe¢ÄÏ_ÿ|òá»àï?‹õ¡/±ã÷¯ãw†~“kÔ…B»1CU¢‰|ê[z*ú­ èS]èö<­)¢�è·^„ª©Œu'‹`lgÀÛ~f¾þJòo¹‰-WÞÀyW]FxÕvš*…©8çQÔ•Ô„1×ÁЇF­f4Í;F©`èzygÀ#Ôqöcàqèu\SXÉlu̪uL”S�L¡FŸß ß ÂgS‘pÑ%EÆÆö)²K…~† 5ç0¤ ãPÒôOŠÒ¢Zá×õðU9ÞÊ3!ŸZ.GWK¼¯Uå×bØQ…>á�“clØ´Ü f¼Ô‹*—sGy7 RL¸¡¥Öäô§žaõT Öø†ãùl~m7�(Çt ³m8%¬¤�¥V;§X1ê©kk“±Çu ä¾c=eÔL mM’yº»BvÀôž·,çi)@íÔ©t oY¸ó©h…Ú-$ª0£ÿ¼Ê/ÿ #âùHF:¬u�U; qoݻǨp¯ºù㹞T¡¿QeV]Hd”X33Lã"Óð*¼ï}ö­V¸/)ò­–ËÑ–ÇØªÅ[ó\ý7™„v˜VÌQ-Ï89.;Yâåêæfuqx®‡” XïDÕt¢+�ömøc¢�¤D*8r«¨Ž‹®Ž¢LŠ2ïØ1¥œ÷ªÃ¢r¶ÇÿON Ú!u7j†Ž¥Î€RçË´š~’R&ݦ8c£ÌZÏè«FtÃm‰ó>xRI(0YÍ€+M•¨~°žñÒ�–ܪpÚ2AÝN’AWÓÿ�X[Åš[Àþ†(|ûÐˤûPšÂ¢Ð®é�+F‚:lâÓìóͳ1Í™âL3J½ëjrРǺgÿšC,XM,RÀ «‰Å餀‖È_×âçÚ»í¤ž ô”“`@?2žù¢§*7ÍÿäרªÓlEבc¨Q@Ê�¨s·�;ÆÎ`RÞy+UjÀ48D!“¯ ÷r¦Êû©ç$Q»Ì0—ábŒ/ÊÒÿ&¾A"Ö?�>4nÌ"‘QD¢ñTÏ…>5•ØÕ(Ð;Ð;|\l¼Aô ³¢_ŠrƒƒFægLf_^§+:3{ºë‹Qœé�f)ì£úENã¦�äoD+pª�ÈfUXZ5{âÅU¬GR1ÈvËçÔêôaöïÈeˆ+¡@Ê_ën*aeuj£Z`«ÄV¡`ˆƒ…{ÆéúªØÌÇìæB=×e)Á:-Xia/Çx w¶m¥xnœ¶0œñ4ÐS�EwIÓ²¹·åÒú%³‚ÔS “Ç“O?çöŽ „¹§Õ¬ïlÛigZuFXÒPVÛXJq±(èàDñRÆs5B?bO¾ákþŒë™BiÍ™•iQ1ì?c„9:œjþ©YÊÓ¾ÑenÅØ1+±XžÚq É*–¡ÚZœ\!ߘÖr)©œ¥Ö:S)·£g\FîÁStëAºÓ 'ò›Dþö òŸQD†Çp"™@1B™Šª†bÜ,q§*4F¼ýurGDñ˜(ïêOc%FR·”šn¦*9á’Gù·ÿô(mQÅZ¥ e3zgÝX¤0÷,‚·ìñ¹êÍ”uqmŽžÃsô ­sK5>Ö‡'È“I›ÇSJãzÿ¬Î^†{­l¯zfpdžc —ƈ×�¾’ãdÊãV ÈPb±ØÆ™O@ nûLª}•fŸ¿gy3�^'CЀáÀ§«IDÍ™˜ ?&6�[G ö3ž“Ìj@C6}è–åÓnÙÌÈe^¸'ìSkIb(«Š±â4ЕzbVfoVxÿcëµBî>çk(OMåÖåx_mgA~&à“4èãÄZœJ/kͦm2–ɪG[t¿m”[çGh”@ÇÙ$±ñLkïŒ$×Ôå‚1C¤5û|•r¬Ô-¾g²w¶©H¦…Ú&¥?ÞÆ:ý%Bc÷4›­ÀÙÀ>óyÆ+½‰x‚üœèÑ<›”Âi³`'g¶rQ=U°ix5¥rRQÓçÄ‘"?¿ü+l{Õ[8ïwöòŒËžE´'Ö)E¦˜XNƒÊe8׃oÂŽ4ug žYt�ÞþKOPÌôÉ;ÚÛÑÉ’‹Þê¡UXN\I\èõ ¨D$dˆ‚šôè>6ëÌ@sS×�tÍD eÉ�´:©»=•àO`19#t©+NìlÅ'‘Q»]n %øÚþä +eu‰ŽsŠx™Œv6ÑNÊ‹Ìó2~èFÏ�5K9Ú_r8ž a*Á_îZ‚cp°Ô6+úÃkXó_0Þzf‚Ξi(ì1³Â—²çݘ¡:&*ë&¯!<Ãv¬9¡Áÿ—cÃ�ñb‹œk£Tqç§U½ÁbRqËIž¸Ufùíý¨€jþöˆ¼šøƒƒ¤ˆÉОNÙ‚�­b'б׻úþ‡ôýõl& íÔs&¿C䨍~Ü÷Îc�–G[s²91�ýÞ9<=—ÓÙ{èJí�ÝŒ’íÓÔ?óç¶•¶SŽÉгÙ6û¿‰ òf²h¬wTsžD|S…¹Õ"Ë‚iážZÃzD«mìeá(ÁŠã€ã«Uâë¯5ýöîÆ™r«3بÉ8ðRŸ2ïÐ!ŠWï¥Èe'KøŸ=hÓ2Ò¢ZxF¾ÙCêB*x§½’8Ärˆe1c�2€ÕN,¾³_û"}ò{QÀÎÞÀL"3w8œnCbÒuçø ô–,Ûh-káY,ÄX­%ìeùHeܲ�(¿åÅ}QjJ˜Âb%#Þ1+º2°É¤(œùže4õf¨¦ôÓRýmŽÓ+vJ8²˜AJ€q“Äéb9ÌÌãé†t2·Æ;˜t3®Ò:I!ËðÖ¨@Vd|œ~ä…ÔÝ]¢p…¨bÔkMº^“£ÔF‹²~ÉãÆy›Ù%cª)9¬)Çû«¨Ÿ¨é_t#Å]CFL© ÎljñÕÞ÷ºCíYô~äíb²³¯Q„ÃK÷ Ä•çh‚­e‹Ì½cM>ãIzÏþ:¹h†êÄ„\»G1>áOV•'ÏTéU…¡q#BÑy”7ºIá#³ê§¦õ”ݮÂ_!ª.³;Ÿ'V�¥²v,üS"¿ ‹¶\Ve±™rë¹ìW._@ê¾Ú�áª+òw‰Â°¨tRÅÝ "dŠ:¡!‡„Ô]¢¦O×?Öµ„²pf�>»µØîB©8cœ&XœXF±Õ®�m&pŸâw19R0b˜cÚ[tÑ;\þ5ÉRtcð°.uO'ƒÙOVaµmj§ÒŽÃ²,’ø¾sí(cA¦¿WO÷†Nª”RšrÇ;üñTë=Õw?<‘ªI9ª­Â—”JSÇ-›Ó`Qyâ8ÇbBîºezuÉ:3ˆGÉ/ŸÑt3RPößÔ^"m+0…!,q¨H8ÑÃëÔÍ i¨�1ØnÝc¢ÒE¼¯È„™ph¥®7Éb‰ïè<âwñ"UQ=מ&) SIÑ�\�døúÙùXÆÙYÇëÞÍ�ä ׯüÿÃ?`áÜ]Ãî¿ñÝk`·Û8±•È—•€e�%,òkÉòì=žÕÍêöûp¾¸ñ�í[xàk¿Ï¸š‡ö^Íuײy»Gõ…ögŽbå1§y³—Q³8én`sæ«Å 8•oµ/êú—ßý Y£e.B ØNBk-‘%|<,^ú1v¸G¹”Ä€3,¢Zâ*¨5û_Àú_©_¼[ô<`]NßÅ÷Ìá i ñå„—Tø™׳XYvNØŽ…,g-{»e‘ؘ{Š­d¾¨Ø° â<¶ë[ôŠÞ{E90 ¹Ä\jla­Ëè +!¦VìB˱$Ä$Ë®�ø‰¬Ä.ñÄïÞÅ1àŸÀ¹a~;6Dð7XP¶èO¯uïm‚+ÓïyHÈüsu;1cq.»þ¾áñ_þ>!¶||PËM,7�‡‚ViÛ6Ø/Žxÿwîê;šBù-I’°°±ÒÏgŽÒ’¾£æSŠ£5à¸]]Âå�7þOœ¼šk>ðn>ýW>ø•Íô›gÿ¹¿ÁùYÐ�Ï$°þ*´pG.ÐʃØ1o¼m¦’“�ÿðçpv¿2\`­3#Ý`ãŸ\Ã~rí,ÄÝÙ^Ñ¿ðŽ¥nc£ûÈ�LR {õéð®‹ÄˆÚñ¢±^* _ˆ�3hªš>R×3ÐouϹœ–C,ß ¹’ §æž‚^𪶞3m:jr.ÝOÎìÑêiU^vMÿˆ(¦ ÏàËåÓñr|ô†"Ÿ8]àŽÄåÛË6“Ëð@l󉕟üŠòÑ Õ»Ä=H÷.Q &‡ÉF�>õxè9%Vß\E×çÐçËèoôZ6é—ù»ÅóR/õ¼¦Óªt„ÃO…¿XfF�Q§IpŒ˜‚1O8%˜[!w\”ç³"aÛTÅO ÖVóLËâÆy<=û’3ŠªåÛE÷SÐs»øâZZèji¨¶°Úm˜N°Ö–qæµMµÝø áœVêvÊr{#¯éG²vŠà`ƒ†ª[bû\Ï6ô+›Ð¶Ðþh™ögtí&ZorÑż~3R`� ¦imcÄÕkDÞU׺\¿\åÁ¸À7Tâ»+>ÍÄá}§Þ{ÑHu§ KQ×ÑQsö3žëS „‚z�ÒØ(AŒ-²<ÆÆ*?Íò ª,Ï{¨�£­€Eù<œx<üH/úu& Máßhä¹mÐÏÛì[ 8­ÉR@,¾xïçëçhž,eæ ™ÄÔ82>ð)¬YÈíd0FHãñSŒ“(M‹JcˆÂ‰)fé¡z\ôFX‹-–„sZK‚øõr²$#ydõ�UÆgs<,—•5X‹óÄ-�5WŽO>ü2qÞ]bÃ¥YeøÅiË+Ÿ펈âÇn§û`ƒB'ín¨ÀÔ]¦ýÛyôÞ<ºÓEÿb³vM…öoý1=Hþ%¢8"ª×,²mPÌ–k^äð¦Oº¼w.Ï—Ûš±Çå¸{럖p?´J÷ñäë^„”£ò±éN+À~úZŽ5ÓÚ Z«Xm³Wµây˜ÁÞù8ïQ ˜—ÍT‚uä p¢8,‚h†j4CuZT†™®t1;,')ÈX?±$ü¤…õ�pfÌÏv²€›4zÉ"Ö#ÂZˆqÚw ù„²ohÒó‡ÓT� <õ㿆õws|ºUæ_âw-ç¹M9þiÅçÓË6#sTöä7_¿ëâÃä›ÂO}Ô¬‡îbC(JÐ,mB¿¹�ö»Ð]=èö*qÑ%S$Û³�¼d°ò¯Z` ’ÏU*#S‰È�Ž¡ ;ùד (´ûŒ¢�-܃‡9VtÝrÌ`¹V%¼©WYŠ-æ;{&ÖZ§dÓŠSuÚ×�1 2⩆"—+óÄé‹Ùòú×±å’×óì7\ħ~qÚ“ß!r‘È÷2„o?‰BVÌZ¼GÒ‚l3ƒ%?^}�O‡ÉŸ8Aq¼N—¨9»Éd“ê9tz#³õ.öžØŒîéâþUM¿½æŒ â5K”>÷AŸIÁbB »#@à«Éãý×õÑô/Fy¢šÓ¦EBÃÄJU?%#ç;@½D*YRw£LÈaÕœÌñÃÓ\p\l•„ìÆ Õ·eùOý…ËOåù¦ hÑô½ Ö&^µ³*²Ǹk‰ËIå¹'&ÿ[¯6YÊˆÇØp@m"ŸGW”Pj¹šÀª‘§²Úmìc·ÄbbÓN\V’Kq‰9=™øJ2YkdeRL¦ý9€å¢×;Ì(@±gZm±άŰ Ü™6îtb¶­O‹jë�ÑæÑÔ…š6ýåyn_s™J<ÔÎËá‘5¬ï) içIÚ°˜ “ÓmøØ|•#¯ewo% {'= ÷²¥O=Ć+D•† Œ Œ*S¿ä"“Vׄ³œ®Q%4‚^Æ¡à´Ø¨´ÓÁи�Kó±÷ûL+ŸNœ6máEX‹‹,+Ç�#Mä#£8ƒŒgÍ“%þèø&©È!›©qr' ¤/ý~Ã÷`ÃHp˰­L¡&s˜}\z$ü(%d ‹&‘qÚ4>åtSMsç4•ýur!ucPè¼÷Ú ©Ä¶éŸÖéÄ!V•$qxïûèñú� ›þ/ŠpÞö0[†ÄV Sezµ‰WÏvqHEFPS>lâkšÊ'GØvF)µæy3 ª'Óª.½£{AÏ+ò=åXJ§%Üá-¦Þik2ºì31ÁZË´ëå±øÞÂvô»|jïf$—=ûòD5'Ï-¯*³¦Ì Yn»ÌÉc^Ô¡ú¬&EXp¹~Þ壯EʽsÆ\߸ȹcÓGNqÚ6ªù<é%opxÏ© ÷/æYUÅy“ÒÆíÄ#NòÌ$y‰Í;Obø•—‰Ò³EÕsüö䯧±ú{&ó<”àÌ·a6ÁÕš1tÌTfVcÓÛO̶ 0Á泘pAëW¸JåL*Š ¥˜ˆ¢(�ú½oŠ ‡çèIr\4ÛÅÔeÏõ°÷Äf^¯MH4T E]§®/ï8E7Êã}êƒAFâ±–Ìá­¦Û%V…sóuý©ÖÞ‰)>tš ÷ÏP%í(…nß.ºïöïÈv Âq3¯ãbÓq±i}€7”y¬?vºðg=г½J/cAF8ØÁþœ:dˆF#t¸äP1ÐÏí})Å9ìV€û…×Y�C’R73SÁöZ@Q‚÷•Wñ~ôŠ".Þž•½b3Õú‹pÞù>üw$~ŽÒŸ¼ŸóÞökHîî1*ű1*“l+ 2âEÔœÑt pìò´O…fõÌ}¤žã;‰Åœ”…™•UüãUŽœ¥e‡iYœ–™”Ûóm‡cI�ï0)ü€‹dõ!ÿ¹+ŸÇÊooFwç9�8,´}–äÒV>%zt£v7ºg Úu*r­J£cf[ETS_5k'»ƒ(·óCÎgå·¶ÿ/c_ÕN2ȯO¢"R‘õк3@;Ù9]ù݇Ø`°ÜHn•é;=ŽÊcr g>Á9§.³ÂŽ—-æ‹Ó2�¯U›“2™Âb’c^põç̵Ùêìÿö lÐ4•´5—«‹�c)Œ¶¾ŸoÕùG×,jaiO ž’3Ì·µÄJ‰'6Z5B‘ÉjEÍÔayÞ7ˆN–‘76J0+SxŠ„ÏOý×_¤ûÞW°åÃû†›ñ÷¿ƒ�±—ç†ÏDç9H�ú@N©hcÆq§/ôkûREäZ„œ&ò¯úPÊ´ºðsÏâIïy#ÝûßEå5éy÷_ó„‘WÒ{úâL·–ÂWé÷š,ð¼ot!åig°Ü„ÂrŒJ¸6 sÂ^I;k© ¬ÚøjÁÈÿµJN¿Ü?Cõ¡Ólò&P>Å«;ˆ`ÏaòDÆ}~›åç�Nm>-™?[ò‘zX˜íGÏCrÙ¶«�ºÏXL(χ?}�ÅçŽ[< ‹Óò‰×`M8Š-¾—X9Éi6ÞiÐu¹‘!C¤êe,0ÛÍ~¯)|í&D^È€;:F�¦é�1~Ý0õ¡C¡=œÒ…IÅ9”šD>~=Ú“ï`Œ_zcE~Sø×F†Í&pÇ/5ÕŒð'&È:”zmõI£&òŸÆÊ%ægXÏÄBqÀÜìFô|Dñ`#5°�Û?’‚gÊŸúþæ M-#è�ÄJ<Úòùä Î'?@J¯$pûQ!&(©‰ùËRˆã~åŠèµÍUƒ2[0”O?6Ü•Ù÷¢¥,° KK‰…Ö`EÆT�'¿e’O$¿)üz�.‰ªYE•ãwµ™pºÂÅ= 4KœP‘[UE» ¨¿­Ã—àWKKG„·{” Öè4<Úu‘ë>/V™;¦ÊD�*¯×&î!ÔFŽÉ0ìBÙ»wš­pUÀþêÕe ©«•n�æ¼Yq>»Œ5g²®c±ÒaÅÙ4Wð´çšT7ÿŽ•�´sÍH> ßHxVß3˜{V7W·XŠMÛшpØ´b³�y@UnŸfkOŸ‘Å픂Z@³]°öl›ÙY‹¥Ø�•bSĵ[3E.ÙxŒ²Æ¨œ¸Ñ¬Â»Q�vë CÜf3³e’»ƒº‘Ò£Ñ ÀkÆ~çº@϶}aæ'"ÐùAXŸ›‘ö;*�>]¥šÙ ‘ꃯë)¦”ÃtÖëP×íÛ\¥4Ï9ãJQQ°ws77xãõ6W\‡ýÁWðÎ[«4ž\ E×­i±Æ¬b‘ÿS<ô«^ºŠb­ÊA:ƒ©NbíZP…ï´Ù²ò"nR%ÕwékúMäLsè"�« [×㜈 æÓ¾tF Éè -ul�ÜÕ”i–$sÂZlQì²’`O¿ …�)_Þ|7™K©Ñmç1$EüoŸÿÈL•êíK«XiM"Ÿ~�î#žI:l;«mF�·˜à-±ßV™ÉöÏ ¿54Ú—)vt59)dÖ¹t?9–(êNüù¤È¢Š(ñSÃ<%vÚÍ0‘_¯SSéâÃäSIl7 >þihC�×]æñ_¯s¨]ç°÷�@[0¦ š•»#B‘2!×#î$Ü< ©…³B¨mFƒ6 Wºš‡ø�¥Iã¿G ÛY§û”ôGÁQ#^ækeÞ“G dçØ ®š†å– ØD5§¶ÏèÆ]�ª—3U~3Õ^ÆêQ ä.Å»dÚ/¦ ùݼ|8�0Až¶}ð�bƒDEîoSzÿ_36PÊÑoR®ÃÎ+¥£¦¢ ‡ö­¸$8'LËæ}Õü»—Š;äeZlÞ²r,Å+Úˆ„õéÏóRÆÉ©,Ó��2²L*VxÖ]ÍÅá[}Ú«°`”o¼ôžr2°]û‘$cÆ� ô%³ê[Æ|²È¸žÆT=ý>]T7zpý#ž)~5 c ŸóÏþæVì{¬YU‘¨ÿÿ¿~XÃ"¨‹\'�³ßO«î�Ô�%ÕiÏ,qlÀÚ% ¨ß‹D~XŸ¹—îÔ6Ç&2šbȽKl›2|y/cÁÝeÓv{­“{8§[Ø'SMv%…´ïò¹CôŽl)l¹š¢Œaãy ãl•ÈõŽЬ—lùŸo&”bã�Jвœ¡„ÂrbRƶ°cYLÊfºU0©{‚ý±¿Fò?”’pÒ{Ïu„:+ÊÙ ôù¾õ¾“"mSeUøk1œ’)Â-&™Ž“Ñh­–ÙË{Š ¤<ßÓôaúG¼HäÆÉ=[T¨É©ÑL餑ß$ò)y¡­$+±ÁãÛ§×ÈÏ&X'E¾•à()¢¶ÏḂ~sýbQsÂ:¥¨‰o‰‘�ê®Ù‚U]änºÇ:õóû /•ïÞ.±=Ë 2!’Ç0óúÑS÷ïgâðCRôK ŸoSd3U˰ó:Î(¹š"TЀE¿¼h]Š;ÊXp¿Ñð*�‰ŠÆ¨¹£|3Â'ª9¦ðÚ¼\Ý9ÚWJ¡¤§c‹¥–…!ôÐÇØ9]IÝR=P jŽféš=4d|ºkrŒ…ÐDžUŠøÊóžIèíäQ�nÐY«°¦€–ò¬ìåÅ*…éý¬3¦HÑV…¬cq¶ÝØ(_œçæ{º(ÇWX¬gQø±gðVÓÉ-¸hŸŰâÄeVÝè ÆÈAÖƒ§è6è€Ë€ÙŽ¥F–^DÍ™kÒs¯0›–¥€ (¶˜•ÃÂJ�ç*ÌÍ=…å ƒö)X5”7UïšÃŽzîÌX ݇óëÇîè0AÁö¨@?3AV¸?Xék )J^èOÈŠ{©ývþ'&е®Â¾~Æ[w³nÇÕ3­˜ßt'•¬ZÙùÒúš>`¿ôÅaP›È“Ù×^kü¨›È¯Ñô%ñq±åô$gE—êæÿGS¯ë04Úè�ÏÞOnÿ�Á7ûð•â¾ëûÉÉØû”~c€Âû«×|1Ͼ@þ5ïàÉïýÕg‹Ê q{±²v^æJ ²GñL 6¼q”Sª‰†j>Û~í/n™Çºï¸pÕ‚%Y(ñi¯æ˜S�“ÊqLûg)6^…ŒœVâF™jkªt*‘«§ÿ~¶<;ë"g@<µR…ž[÷�¿æ4Η˜iÙ´ŸxÍe^0£"ŠMÏ{l ç¦ÓxûöP“s\lš]©£Ž±·Â´±Nœ ¨ÌÁy!²GDõe¢Ìe—n¥úß^žãÝŸp G]ö| û=ÊkŸµuhÜ€€vžiOºš¦2u å(µ¨6ãf8˜š¢Üœ 'ìx¥wœgìrêÂíÝmÜb5Ŷ™U¥ÈÑÁ3®.‘ðG&)Ü)¶?°h¸£F ØV?^?òTKí™ÃË¿{ ‡i 4) õ“Fÿ˜(�›�ëÖ�3h\T,ÀºZ/%ä^Šr©Þ»{�FÁ€)LAã.±áãb‹¾ÅF¡¨u¢�;R}í�ôjàeðC&?6šÂ?C|ÝBy_DÞà¨ë.5å/D¥ŸæX™èd‰kÔŠÒͳ)CWlP0ýشׯT[ åCä~}”M’ÑC'Š”—~×BuœÉ4ГU#?•¬8Ì*Ï\«Lòý5•8qQ±/Ó>3+Ùêu@¡3ßýÙ ô#©z¯‘KV‘úäFž°TÃJ¾�c±•ŠH¶N ku%�Z.‹²h×ÙÖþ]>t¬, ͳéä8[�.¼üZjK•Ž“ÜþäFRÁEÝwœ¢{@”�ò|èXùŽaª\a¢‡©ÊØp°­A�fŸo ©Ø/Fåt+WØûRŠ„² ¢æŒ~…Mž¢;+œ5„G¿<êÆ+]¡OŠ­ÇŽñ¤YÑ54H¡Ñ PqÙ¯59O{ŸÁµ1í×�a¦4â×ȼõìÌÙæ?D K¦Ÿ˜i^g�nú�5€ÌÁd²@¨î˜*3Ⱦ,¤d8éʪy&£ºßÈ*6—*§Ý[®-( ÿÃbSs‚$Ÿ�ªÜ:ÃŽŠm)U÷¸Ø´ð0[ê!ç2öäÀ89& {YÙLÖõœ]á¸}4}ˆœ�FÁƲˆš~ŠðôØ{¤Èð�FÇ*\¥ò5¢ë¤(u´S¹ïT¹&÷X=§ÿ�Þ)Äe/›ýÒ³tL”3Tïœ6zëRÊC'´9r¨ÈϾü"J{ßHù5¯£äÙ¨ž#Üß²›È¯‡¸æõÆø°³ž, e�ÄMS!ª9ô‘ö+'L+*Mû!+¬¥ ¢|2~)¹[ŽQnfƒ4ÚïEÁ‰Fõ¦A¿¦à›T’ÈE‘/³÷ÚªaCp*Ž2»ÁÐ~ÓÎ;¡"¯V—œ(^ÈÉÒ”c{”GÊ£(¿KÞ>ƦÝ(©»—p¤¨uÖi —;™Dª ¶}åÆPEÈ@îÈ­T;Ü…z=‡A›Ø6R`G=w )ýWõÜ@êy–Ž£\8Lde&“ë\vìZ p¦Dùð=)³ÌV G—’Û�!êP Ü˧8ïÑCMyÔïÝ!Î[\dÛ~†ru”;.6é[lܽÓXn×Q.¢æÔEŽqŒ„˜ä3Ù( ¹»G F ÐÅ®Ñô Í7tá¢"ê7ÏþÞ9}ù9ïÚ? |z㢬º±SDzªá�‹œ!fýdúú½¹-a7›”$òã)ò "CãK ~[À#²XiITfA[X»MÐ%ÅéLªw”`¹ü´Êôê)­×æi(¡Ø€®à¿¬þ ‡çzŒ›†ü,À_ñ 6Hxa�Í>?5.,pêÁnt¢ˆTbXÆuDUjrt˜ü½¢[¢{Ôð£íiQ¹?ÕE‰ÉÁBúY%hx‚ºû˜ëá"Ù§<2RRFÁ&›°ÒÁ›a§s€µ…½E¥…�}¾�µ°ÊÓgÅÏKôhİÌRø«­Þtj{|¶ýŽ;(kœœ¨9 TÐ,]¥«¹¨˜z›å4I¡VËŒåf‘ÑaÔÕÅÉkKÔ£¡*ü¶6ò»Ú@¨ :T4ˆÃ>ŸÔqhœÜÁ…&òOp¤!§)üÛE·féBòÙs8Ͻîù s=9Tä3¯3<]RÜ6rºšýÍP½DÙ_ï¢_O�ø5úDEEâײYOfd¦ŠöäêgdÈjÂaBùnž^å¡ïPË'VñÃüÌ©_`l8èÝmì¥k„¾�;5Eùžqº~b}=yåÑ{ŽÎŠÔORÚ‘WŠc7Ô>¹;y6|5ɳ¼ì°¦"jå˜W…1ñ¢?yNŸðo9fàŸ Q|¶Ì<öŽÙÜÙÆú_-�{Û%¢°ç»üòÄEé ì 9}4M…3ô„M|îØXæÄ‘";‡ŸÂÅöël}É ø�ú®P•¨ésËåå[E5[Ç�U’©œ¦æ#·R}ÅØÐ+Ìãü/\ ùc›Ï¾þr÷}ïdË»vÓ{ÑsLê'"§7Mõ†�ÚICxO¾‚ê²³"B{ð …Ôʺ˜íùYñs«âgS…”TB:å4ñ\]ãä¦n¡,T5GÒ=ÿu6ÕCÜË¡üß_Á†¦ðG„·‹ÉBˆìíLäÃÔà�“×–øýÜ/ó„ð•ø#Wá¾õŸ(z;Û^3ÈÓÿàâ>ásâ¢"¯ží¢6‘OÇ”;Êp &òBÞ˜Ñ (¿}”Mg §*ò”·üçßùžtÛ¯!Qd„z�ýâ«(æ3tGû –}DTÿ“èâ)'~oïw¾Ü¶¸}ÅáŽU�/·ñ®ø.üº8ŸÕPšÈ§6‘g¿r‡>UáÈ¢�0<£ƒðá¿eh<'‰f_–Iʾgܰô~"ýûVz;C í¯“KS¯ŽP^�Ãù�ì}-®‘}ÂNV`:±ˆã‰(~ù5¼ìX9³/®Ñô)kÃ6´`$•–¼öù$Æ[,¨BkŽë´?sÐ0+’a )†Èíb0ÄŠclùbgmÙ¦�x,ŠÒ?¾•èd‰�ºÛáõÿýOK¬) –�V�bÉiQŒc¬ù$ϬØ4òJ4àî‹Èk7�)ŽÉì§z_qa‘›Où®Œ‚J;$)iå_øø—¼ó—²ô?Šp4EÙðˆ/6ª³59¸ð>2_åÓö“˜`JxKcdÚg+ÏðÒ¾ò ±!µ 2�pvÔÉ ²­ N�Üô¥ûBÓëgh²ŠÒ` %3ìë8Ãòc˜yny‹(^!£Â"‘Ë 0CT p›Â¿L”î•KDñÑÓÅ­»»¸~ÕáDâ¦z’ͪåi· $*ómÙÜ0ƒÿ‘ËiŒx÷‰ÍŸ<Âöq‘ o€aÄE*|äº<Y.3­"§dh¬ ª0£.îùÁë2«.ãÆ+—õMù<á-¯Êñ°,N' eŒYƒ<´–cAy¾'ž°û•4å÷!ÿjQ%N=½»J¬¼!ëÄØËúÿØû÷0¹ÎòÌý­óªcŸt°|Ä!"qB:@Œ iNJD&dOe“ù<Ÿ‡™é$& ŒíU6vÒ`‡¶1c)ä4(†`£( 2´MÛ´h7Ýên©Ï]UkÝû�÷]Õm‡Ù³¯ÍÄ6C¸®ué`!u¯ZÏzß÷yîûwãt ](ºy�Z£ æ+¡MZ­o’`~L ýùü0…›ù±ìÆ»·å1mY]J`.íå» ¿õ[¿À¡ësPóÆÇˆÎg2Wæ‹·•iµ]Z&éÓK·(Í’¤�$ øúûاÂÝÝ€ûJȰòÛXÙsÿbH˰Â2õ–sV.ó†Hã,(àþ³—£ÝB9Ù\.H`Œ´�¼þÈááNÈJ겞âYõ[¦úÊ„!Þr’…0ºtD¨«ù¸zß"v~Kìšœ|ìÄÿ¶—áºÉŽ�¦Ä¶ûÄÀÖú*uÙ$�ÃSy]iâ�eTrNÇ ˆë[ï¤Æ`C,ÃŽ¦Své�èÔRÌPÝ·ÿ¦Ç näÉë-8K)~ÚÉ(³ÐÚ€ÓÆ$ê)ñXÔNÚ×/Šmµã†=WE>W¨àòOï5Ž7 ll´“Xq¸{5àïgÿøvdrøNÈCM‚Íc'xzL ýÑÒÁ¬à�<¾® Xn é†bÖÛçÑú+n}ǹ4dŒ.5ÂLå8ù79–,ŠÈ"ˆr±‰Ê‘(ÇøM\ªø˜(LOS¨™¬ñ|Èò•1ßÜðÙΪÒ³¢Ÿéൗqæs 9¹>@û*ѺÈá2sc‘ýÏýMü{—<¦Sèlø¬˜"÷Φ�(t'1Ì4û †h�à½g8wñ7þh…]cKlo4ÈW«�ÿŠü¿¡ÐM6™™Ü+úL¡Û<òªûh0`j8Ï9ßÞ�ÿŽù’¶1·t¶H‚3œW’ŽÛ¢Ý1uüÉ”üçWØ÷Ë¿iè«ò c–öÊKÕïøîjê²aVS§-ܳÂYkÙ8èÔg£ÝËìFcžžE±mr’\ y +ïòåwF™�ÖOüÄìUmˆED"ܯ¼ƒÊd. 9Œ�D/bîYýÌž* 4@�¬>Ò»˜�-Ùó¶?ÎHôøê�\讲0 {¤ØìàÞvŒB­IHU®éN§wÁ¤p >º›ÇÎFêt=ûv·å®M|˜¤>‰ÁF?<¶•kT<öVÆöŒáëE'V2,5œáºpWLk� O©K'íEâ‚O=Çê8œÁQLâOÿï¿®Àh§Ú.k2”ØÎFÀ¢Bæ:ô¾æuH^…jXá_Œ³]¢Ä¥ŠÙ7½ƒ'�üλúÏxêðïò% 0©Cò+¶Ï4Ìh žîü8ÍÑÿ*ôîø ðÀ¢†ÁC¿ÓljK TçÊ\®^4•g~¾§Ö$l6)S‡¼ÿvˆ~îø©¾>ÚsÒ¶c Iä,¥ÔÙNr–½êï¦G+œ{b•óM–:Å^ô�‡¡6~š­¦D«Æpá)1<·Î†Ï)õÒ¹äh” fm‡äõ‹8GV´á’ wMn÷¥!c·dÝHÐJ6 ÝðâB´ò@Ê Gž�LÀÀc ø7*t³Ð7�i[F¬FÎÚ Ø{ÃÏçh*‡– ³•š„ÖŽ…ešívÎaøs†3ï,¥Ëë[ÛAû¢*òk¶qyÅuˆ:¯ðøÆºáѵEÐiáÎ ·Õ�µ”¼g �€–øó—îÍnÂåyãeª‹ÛzÑ™�V@K.Iⳑ$*�¶KtæøÃņzÍ3�¯zõ}H†¨{»ÊÜ3WF*ÓT?R&sCȯ"ÿq…Õ&áI=vSÿ12ɹŽcRð€Ä±¿pÇ“S\þmFýZÓi¿ë ½¿çhÑÁY« 9¡ÀÁi×.âì­ï{ˆ…ÜÚËY»ö/î¥Ýö=’Ôa5Yqî>»¢·๬.œ«ÖrÞ gWp H°!g}ƒ…˜Žg”ˆ®‰—Bâà´œV˜ÈY^áþuŽ<#r Í>Ò¡‰þ*/ú>¿œO™Ç£DšÆ’éžrœ4µ6]‘’:‹à¦Ž¼‚hµ@弸À ¾pð—ÛÏúVSzV�ïâ‚Î>FŸÁ¿Éÿ>âHÐSäx á>ˆãEf ¸nQ )ª²Çv'ùÎÅ Ð!‰!pÒÈ�ö‚„‹£‚ãàZkâÈ[¤ ’Aê)$a=ŒtzqŸ`ÞùÖ“Ò»¾OøÜÿ‡ þÚûA2óMÑzš~›öFàÒ›¦Ž›ÂšÇFœà”RÔ]æv·“o}UªVœ€¯¢ê=O[®žRtæ“G�ùx)9´=¥å�—z„éb|ý<ÏØ÷|ƱÔÂAþW|`ýÉï%•œÔIÔaüañÌ]m¾øÌxüâowÎ�Bq�k@ûw—6»ðví%I`ã1û £Ýã‘«úÖ3»§Þû>Ã@CF)ÄÈX$äXµSp%³&Ngä`Ç ÃGó=$ï™ZÇ=k`’¾:NÖP²«’gÙs.�w>Å?�­Êa)ÅWR I‰îºªþ±cf?ñ˜ƒÿˆWâÙì¬»ÐØ;‡‡íù}H>¼ç¯ûH�˜lù(îB‚s&u,†*~6ü’q»ùJÔŽHÔÏlç:·Ö¾Æö{æ(ß%úŽ £: >öµLó¬e¶ý¬ Gí /mÆž+L,ô22VnŠðâgP¢jÇlcãeöiÇzS?úÐ6:µ]èMìÓ®U‰†òá ]No­†§1"!3:-±½)BŽìŽ-Œ1�‘�†Ã zöŒ5DÞ lòbÈä³Uö†¼|ùâ7M—Ìêžâœn9œ’Ç‚p–Ú0§2Ë)ñL1¬mˆ°6OÏ;x·è/Ñ y8u餆h2'¢v ?±h©º”Þ•˜Ó€IDATçï—×OÀïÿ!{ Ï`÷¥dYêñ„ÍCëe,Í'Sv>¢Ñh/»&¬�Ö¦´%ãÐÔÿGæQÈÐöòKBÐãÿ la·o-ô Ÿ$—ÅÌn}!lúV}=]ö{·Øí‡FU.×]RàöƒeT R±Œžv>zåO¡ÿøLôôó™Ì1T÷«MBŽ“ËU£Säw‹xí_.ñí6,˜€€@©É?mçèëÐÙ0c"Ùq*â³"g;’”ÿ°ú|¤p„{Ê›¾òçËx6þ¶ãžz ïYȨŽáØ`v·§fìec°Œ¢p]í6á†ÉxÞ)áÍ´ÒÄgM¾»ÞGûH4™Ëv Ø('0Øèa›Î=½ „”ÐE0^fp4`pÔ$­ ×.$ù uÕ›AÄÙØôHd Höó­H¯-áÅ-W^[É@[žo²AkÒù‰)ô“¢Ô�Ý­Èë¦sH> TÕ …�å¹[cI¢”ñ³³ »˜åE±M§9oe…]™Ý³V£ÿã_§—††ç|ù Š®A=Ä eª¾�[.j\«’ǵÿ`xíiÇ<„óM ´ºÌr#úH;Xµ—Iu}pÉãËŸâÌC}UQÔ8åûÄÀã}ÿÔË®dù­/Xó’µöaA¹Æ�¶+s籈‡V7-’’Ž:°nÒVœŽ�0VÇ¥-Ÿ5œMC¦Ÿ±äâ»K¿.ú>}–þ¯Á` !|&®Úøj¤�©á<ãã£/íAÆA˜Q[mîý£Pe8ÕMÐG–IJ%G Sûéa%µnh¢‘þfÌ€Œ�5)OŠRMäF3eÜc¸¢?îÑÓÀô£~¯BÕ�?MüSC�E-³KÍœgœ]�îú*í-\yªU’~S}�éZùÿiWþeÎ4< œÔòä:�„¡6tpR‡§ãÉïøláÞÅý?µqã,|·þU9×ür�]±gÔgøÏZ|õfÿ#]’°Ã—ø”gŸ—Ô<5r„œ*ÈÁæÏ>Š<ìlý…ë8Ýç~»*8LÔ%ÇòÛ8TÅ^Ò‡1Ï:Àg …¡>ÿØqùï!KÐ0+·ý½-b‹ÑGÇ;!× …´Åȯ@¢xB@f«nƒç+sÆÊÞ²™¿Ý¢�b&•cR9›kMXÁ Qå;0Á†‹íãb{Ž»…|pç´"CMÒĬÜôè$I`ö–*ð  ŒuÞ3Œ*ë#T‡|¨ýøoÝ­å–ª½ïvG–}Ž›ç^ ò¬*$þËáˆ�´r|Cy±"Ÿ%™tÙÁzâ’´C”ú´òpòÑõß:Dc4µ÷°"¯ZÅhÞô¨I¿2î�†b¦/,ü…ÌÔä�c a�eq�Ї†ü±"»3,vA$Õ¸ &éB9ÝGö€Ì6=ÛÑȜՃìÿow Af=Þz²d—,³í'bëžÙ/‘¶6 F7#ln%Íf{^·Ån }F»GãK6Å~9Y’è'¾Áηž¡ULøÃ¤rLËÒ\UQØDáØ{Ø>#ŠÇ'ÉUjôOȞɩ�^ôº�ÖF`ÎÝ&EÔfk›Ñ]ÚÁY”‰s:ݺ€�7•¸o€šÂ+®£ á²OjÍÇìƒþ·»ÌÃÝ=nÙ衬ÐkÈ»£m`oÓäÇïU]UàÁõ˜•¶Ã¬|V;>ë)´;Ytµƒ’�µ´ŸµN½~o7.¾ZŠkMBÏ�_#§zçôÜ{}cUÊèPMæ*⼊�§<Ú}é4ò€wp¬[è[€6dË6={aeÄ›,û|v–RvÙB�µ)æK˜žO殳 Šî1T?V„™ñ ° -ûVÌw Ø�Jú›v ±õjˆà„L‹õûÝ7®ÍÏÎF#»ëÄY3È¥¦UÂ]4òW¢•;{¸]åZ olƒ€Ê0A¸çWÈU…[¥î7Q¨%¶ç|žußoP8òüwÎÃ'×p¿uïkÂù— ¼F‡òÍó䪟å§~í%53Js'P, ±Üû? çûñ»lnKÆXµI˜q�çÞ$¡ª�Y�U ¹õd‰§ÿùK‰oýîÑøäªË—7|¾!ŸÉeÂ�¬“»a‰Â;?ƒ¿ü2þpq@MÂæéÉØƒuÇì9Ü{}�Y\´Ï�Š0[BÛ.ædé먷ÆLQb»•¬Æ¨ªÛ(3ö߬œQZ³Dœ¬é¶µá+Û/zä™\]]Á‚è=&C5fò`_~Ýçü'¥ÐE—ù–u+ÝòΊ~‰³ZlIȵ\l³U§‹ÛíRd²Y¨já!‘«"×’<]*“9vz©Ë57á_ýIâ«î ÿ–[!÷‚Ì–jr¹ÍÝ çC>y_;FÄvšêç¿�í·lñ?!—܄߹›br;’?ãõrª*ÛÝ‚7Å�-“ƒJx|’.©äÇûÚZèõGºùc”œ5*^½Š¯*E6ÇjþÆ£»Dßóô€ÛŽˆè±$ýo,ôÍùÑWÆvoŠðhƒüñIrÇ'É©O0�3��ÊfìÖ!{Æ#*ò $‚ÙYJã¢\›¡xëIJhÐ*–&sÈ›ÔBȯ…5*Þì'(u ]*R~û‘<ßQÌY…–0б� +iÌd›þß9ÂøHt÷µ”tØ !Ž“Cµ�ññhh‚x¿ 94›ƒƒÜo5Ø5-vÂ,Y¤JÝÏ$–ŒÒóÐú 'ŒmžÊ›3ú£ ]&ý&+t%Úi<Þ+yVè¶ú(÷š} ¸~õ73>ýLÄMjáØÑ„ˆº‹¾ã5úeqÚcãDÇ'ÉÕdrŇ²†ko˜Á Ê�oôó8Yw¯EDó’o\ñÕ˜\Ãý~oÁ8Ù­ãœÕIêñî‡ ´~žªÜ½UBš{C�0/óÙY«y?|i|B®œ¥ôñz¯…=‰ìK½({¾1dØ™€ïTuÇFˆt)±¸>'5)“0S«á Žf���]3öÛÖíÿÛ5ôÏ9æóCŲº2K_ AÛ¦{ζ{P}Xäo¿Ç|€YPÌè‚Ü*fe¾¾FÎ#î)³oº£HÞŠ«¿öHïvIn&ÔÕÄí!vOôr­Jµ¦-Ö;éyôKQÙ|ÕŽ³fQög²#Ðã^àÙÕ4†¤Ùí¹Õ,l¾Ìåì­�‘sÙL‘W.ÄèW $o؉ní£óùô7Ûhÿñ¹èùìU?+3¦ˆúáx7õ¸)±1Êü$ÛduÑq ÒéFÊô2r�5Yl´pçS%8®¶qNË¡­"Úx6í_áR“•76NÄÕ7õqXçô ¹µ£rL<”zH!Zï!™ã°Îáêô…ɬAgšv1Ržûî@ ½ÌÏ÷p¯úö‰Â•¯2¤$1äëR“Ÿ—uàÿ(ôÍ&]¶]ÏšslÚT]Ô,òsß~.åÿþÇô ¿‘§üñshŒ€sä0ñœ(��S¦¡÷S‡ò¬§>«)n»mf­†çqZ9¾™ýék‘|†Í9®©�†òÛèÔ‹ÌÚˆ›là,'ø«†Ú(%PJBN'=¤Ÿß>cfjXQ†-ôͦ_ÅC~µŠÏ¡JŽóþÓ‹ /ÿxÈÇWî=_•Ë}kðåœ;>¼áð±¿çÉø ³ã'=ª¿Ñ-ä†_t%™OÌBoŠÐš8JY¡o>À¸†'ÿ¢ãäö|ÑMŸôxÿ™ˆºJ|«SäÞV�/§1Ÿî¸|ô þMŸæâg¼È7Næ`ºP©˜—_Ö«CÑ(Ê‹FÐD!ýÚGx—±µæÒfg ¶qžN)%P¡ô©Ü»äÔD8d’Yb¶½úu1§Sœ³Âétº´Gmœå9-Î=ô¤¸"rÁ•¯¢„äpD1o>}O½ñpîUžñ»¿Ç½êCGóÇŽQCÑn9lƒ=‡ÛÈëó"ï&alj¡]IT�·“c½g}#f­“cIý,ëgHn♋j{Æ"¼±wäH s;4®'"YxD'ͱ¡˜“³Å[ÝmP¾ýM�É4GÚ�¶p—SÂT„mówqF.í¶Ë½ŠXº©h¿cx°çé9QÖl7)`÷B/¾^_$Ý€uy$‚•Œ!×6JGêD¤iíµsIÞ†Td|<ÚzÏ"Øpp³­q¶;É ]O ù{ExYTµ4±%EÕB¦Oø¯ÚŽ«+bV;.3rétŒòmV«m%‰bV—3 YдßÈÇÕKCù½6%·)Â+_EI"W¯bÔm4Ðr·.úpÛ¶ÑjLn{§c?‡Å´Ìwžù¥§Û(>>IŽ=ãÜûÎ�UðËËðÖÈM¾Ïš<¾q#åº:ŽCu?D{Kœz÷ûm£ìë´Êh޽3Ï®cù€MBÍQžž¦pi�Þì¾ýØúæêóÈØ¦*rŸÂ�=;xÛSq§Z0/Ÿ%õ�(fVÛ8›°ãï.äúÉœ1ºÈ犼�ÜZ$éx(…�.òÙ±Lð>’ï‹Gv£ õ#Ä{m2çSÙxe‰I$­â,а%— álÈ4jZ��“­<�W0>8lKM¬Q6'ÊZ pš(ÄýÖkÞ¿œ£­J=Öå’®ã¯ÊÅî,ѤxœQã)Ozõ�â-’ÊÍB—m`ýÏ ý C�Ýo|ûQ¶Ýòý˜Î²&s&Uö«oÀ}ÏÙs HÛ™ȧµŽ3£�Ty$‡E9¬¶–:&ÅÞ—¿†;Õƒ²°ÅE5 �&ÞÏž,s-OßW>oÀ�êxÈÒ~Ú6ìCÂSŠFè+TV‘oû 1—Õ‹ðÏGr$m—Ž¥Ü(ÅSêØä•<�üó.«'l/p†êøw~<â«ð]Á¼r¤Ê“Šø GöØlºZ O ôž¥"?"38è¿y¡__#—­®€³…{l7=ägÞHé¤ðÎ$°¬mäI•g#ÁÿðŸRS84A\iRD�€'xµyP–R“ì²ni¡É†ÇºÙZõ½áÕ gõçŸZdà�yz¬1¢ø�F|¾²¸æ³¤�tÃÄ|tÔÃr«‡ï¤rRØûqzí–ÔW ïÔ—ÐåšÈí±ÙaìøÁ¾Lp—최â®È!IèÒgÒ6œ‘Ï|ï[+Xƒ}Î Ýlßm3(5_ã†\:-ŸåܯˆÂ7Žu)) öÊ�A�O’ƒÚ#ü÷�¾·O¤BïnAm“q|ÌÌÈíH2O¡:æÒIs˜ÏÊ¡#ÂåÎXæ^bøpîjšÝ+XI}N§y¾Û)ò½:šÊsÓOõm¹~w�"c=•¿ýZ‰ÕµˆTmy$g¦U U/ZÄ×Ï–0ù|ŽP0†"v×c^¡�½$gZ¦ ó\š¸¥^t–Wh'(³é­Æ@SË•Y1¬@/�äÒJ:Šùûö ¸·OÄYRO yÜzwɤñþØú#3?¬ØM¡oŽ‘L,�œTýýŒE»97DpÉŽ0›»5CØ1Ú¹èâ˜{SüÄ £ƒ5á­ÛÔYž{G8ˉÇbj¸tg;kÂouæÛXùÅ Q�z=¦:ä×¾Æv+íÝ,ò­ :{oŸ0…n¥¢[Óa»‘Ñ  çúœH£ŒÓî¬tpg-t"í‚9MðE§›xãÐIM≳.^zðÙÌΖ¨U¼!ë%¯bvû9i‘�c÷sÁ}b€þÆ6zþéJòÕ¿'~ã�äÿì#lÿ£ƒüWmªã9êdŽÊeÅÉëÉM‰ü¨8¨ˆ_øÁ…Äÿã»!÷t\¾²áóåVÈñ„ø|—§NÿŒíÔ»““äf?A‰£ä96]Èñ��øÊ2î}-�³‰ÏzZ@)ñ»oãð‘xDD‡2  rˆüð�—©…G=„�üo#æ Ôm�ܽ(Ì~NAow9�@¢%eæt.É_šØdÅ5;G5†”fÈï?ÔÇN=¹€®,¢�hým]¡§@³xx‚x|œ²š„U†üQC!5«Ë Õ^š3Eîž-qƒzÙ§œßìçZ• æU�I=­áQ»(wñ«(™‡J‘hä•A ^õ‰R™ä`Ì7ÛÝB÷7„×ÚB”MmPß’–E°ÖÁ9“âÌ›¼8G-¼T7þ· F8*ל7+Uµ+4Ñ–>ÇéÊ\‚Ùü|Ë‹ eV/Ïñí–O«ƒ»!ÂE.š-¼›˜Ý�tí�i’Å4™<¶4-�¤<û—^ƒSò3–àVBϧ¿Å.‰í—L³ Å ÕŠ¼\çp•z¸|¡—ÚL‘+NöŠpO•rf��¥4!b*ò’ÏUôð =¹@ûÊ��”ÐGrèJž£§pÕ=Œ(ª oBf…¶£µBúوęX Y�ÏF² Íò³äˆâjÝqL=ˆ=ãDû¼Îè][Þ}ÍhÊèØ‡‡·ü°9·«V¤òÔAòïx#îÛ¯âç>ð\FÆ"^u²¸×׌\¶Z76T‰ÜèyD„Æ#¤’Oc4¨ËœG“&ËìzŸ8o\lÿÚ çÞ°Â.Év‰ P-üÏM7T'(4F�i¢Ö$Ü/¢áa í¹{i†fä“Üã`è&æ86uÄéXÛªA»t„»•xjh*x©bne¨î3¦ˆªÜ±q¢f“¢•Ñ>Ò¶û¨&ÜaUµžk[à]FÀ¤8ïý+ìê%¹-Ç| órІuÉvÀÛæˆã¤”ÉY;•�ûžÉZsΤ‰Ê¬‹èÆÇ#Õðn;fc4´ß«DϘ(ï'zÊUôÈJ�…Õð¨Èž2jÑÛ—¦ÙUß,$fš‘©Õ�|Ô ÒxªYßé� f4è¶= ‘ƒ/þ­'åø«7Ñ÷¿Ãÿ­]¦0 Ëd²ß3G¹Z§(ºþ±Ëßû‘ÿ‚Í.ð/ô¬SZ­â>b |vÔfbµ"º­Ànõîa<âõfúuûÉl¦A­fÎÍwЦ/,05lÈN·ž,¡ZXkQÅ„ˆ³•ùSùòîù;¿-Ð+ä_ÊD,Õ+D!ù{Ɖ†ŽÐKEÞ¾ )¹M¾J”Ð`þY̫ȿŽé‚h42|4ÿ±]s”…r2Ž4©„§÷‡<¼˜³xše†u³Äº/€uá¶7—�*Ï™I]N·lüP'DZë-8FUwD¦ñWµ¾õ-´�Ìéõ„*ôì3žåìUEþPMæ\ÖÞãòý ÜdÃ¥“~Wx߳߿‰GrYÛ²…ou·ñf¬•È%i×o¦¡üˆ%Iäu…ᬙv©bƒ|6δÆaò:NNLåE%¼ú^ú®™§Ç,•pÅÃ(`øhÉgø@~ Õ5µÎCK¥ ´…Ëá]y$�C×ç2Yî0£A¥Bøïa»Æ»šÿbc\5tšðø$9 ¿i'?Ö…þè"Ïì§ö&ºfËbòº2Lî„ͤzXl?µÈ€��ºþ§¼D<û J{i†UáeÖVÉÉxðwÜKß0£A�Š7z˜|C É߃¢a‘ªãg”ïÍP¼Zô‰ª{~ê.núåÞôb^¦s9¢øNÑs—è3—F0Ìh€¦òDº&RC™é؇u-}—œÔòÝ×…³ Ü33Jœîj'dž Ì^£¾ê^2MA2€ÊFÝ÷D/tY}Á‚ÌøÈ(†¦å'¯ƒSë61eï;›H³�‹�Uù,Ùüµ¬Ð7ÝVˆRº±~ˆi†&ˆ�6È�Üc^,¦áÚ¸àÐ>v½ù…œ÷ß^Bc48^!§䳂Û®;�ÝÖŠÖFl¸‡/�GDt}�Ü¡ãäêGˆeÍL£(h¢PÇÉÕ®'wÛ1 £"àÐõ6 •XGÉ+DÚ—Á»?m"™ YG!’S‘ñ}HÄ2¡?î‚™ÿÿW†Gÿzëˆ)S\Ù¯+áfvW3j1þ~Æ¢ad™â'%L¢œeÆm—2¤ód®ÄêEet<ÏzŠÛ¬*@í<é=äôFÆ¢* ÷‹hBôÞ+ú~™ÖsËŒ®ãžJ Û)Á²Ew:m¨å³"—Å5ø��Îæ¶|ÖÓ§çîU·Y#Æœ+%Ž6ìôÀŽ$÷¢0»'• ¶™Yó"˜ž¦�5§²{8.Ê'Dá˜(T›„Õ*~5kìY\vw…zä½¶çìª55‹H1‡'b$ovÖ�wE-ãž2�Ñàðv2¡àkc†àrR”.:NŽ@¿Poã$Ë8‹iD'5A‹IÌrÇܵMÑ'ö>­tð6ÖqΤ‹ £óÙq!xƒ„Ïåêå*AòX_1"up–…£3Äí?g¿ÊL5òBNs/a�½áÃæ³ßNÍX[e±Ï—Üf Ø€Kª.˜ ö㓆Ÿ°ù¬šmf.úŸéÕýƒrff¤ýû‰¦7ø™Iñ´Z ۨ¹ø”PÕ=tÜt�Ç�ª,ôNd¤Õ¡Ý1S�<¿rñ‹Š|-1÷ImÓuWÛüí3Â]h{¶3o$É…–„÷®EJ:ÀAE†7W÷Q%ÜAr]ÈCih¢–œ¶ ³�?+µUØP¥yôÇì3,@ªî±+(hÔú줠JݯVëG0çvpkóô¼õŒÙ™H›Rè­zþL¨'àØó‰XèÖ¤ñà }Ê&iLˆØ€ï7 £Ù*•y¶Ç~0¥ì��ñ Q0ÖX¼CÇÉÕDŽA|î58 g1ÅYn§E¬ÏlÎZ@’ráŸféá휸¤€.2¨hŸCòÇ1§ÚTÕÍ+MŒ¢jÍ+ü¬#ßI ,«@ûêLåG-BiTÇDaV”7•³»Ž ö>šåS‹ Hô¯¬°K"|‡®oÆ#eÂ{O7‹<–6©?vß;)ú'ìv>{ ì­šUë¬xÚYñ4»ƒp÷ì¡\«™Nõžq"»u��P¤ ™µ7¦¡üôg1‹©Cj‹²-üN‡x¹ƒsZ.g”c# ŒN=ñP‚»!"½�ÛU6Ê7·àèK{b™Ióæ›àL–1-üGë¦orã÷ٽР8×Tè©Wñ�]Aal‹3G•fÍ챻Ǚ�rŽÕ KÒÙD”ócQì�ÿð¨ÆÝÿïæaÍ{£öAœñŠM7¼t ^r¨È£Ö k2̯ŒÓ~Häv׉QÔË�Ÿ l›Ü•1£0%œÕ–é�/%°¸§DþóŸæv•‘é”C…¬Q}]Ì-KE¾¿æÐ–Q�}/�©U—Vꑨ@;õ8“Â;¦)¼íµªá]ÈxÙ‡…VÔc^¹8ÀSÔÓ�Ê ÇÏ ÖíûË»ä©ÈÛK3ò›(¼Wô5æéÉVò­Ûo{èfÒeñ­£»­÷¾Vë‰Üá b£à‘(½§ÆvYËéîK‰ŽaT†×+GSEnT‘ý*³Gež¡µZŽW\[¹KÀeH>Û_øê€Ñ¥˜‰Ä¡“âJ>KÂ]SH»•£­”ø, çöYÎÿç+ÑxÕŠ5ÖElÿ�‹B–²‘º´“ve’úR‡›ç¦vÀýí§²zñ –é'äíC….-vKØ”Èß+ú:CŸlCî/R+ÞÚ ‰|45éñ®§'p¡ËùŸû#É+[Gu]gœížŠ �›ñ³ªûCÄÃ.pÏåÿøYÜ–ñ»‰LSh­ƒ³(‡µ hmþ÷ŶO�Ã:Î×�gšÅë˜.DÑÓЯçIÿÅÄõªã2‘8À�Š•ëÉ��UÎÒoh+#Ï|åE ¼ù2òz Á ÿHø…ëØù¶C<ÿ+?c”‚‡r ðzj9Qñ¢è>1И§§&r›(as­Qñ²‡Ó®^n:)‹%Þ ˆä9óâ1/Í9Q66΃QFD¹î4ñäÚséûÓß§|õ�„W|$à†·¼éw¹àºŸa¨îgÁG¨ÇH> ½äõò�»ÔrPŠsV>­VŽD!ëIžTeÒ/Et^Îõêg^=ˆè?4\v è?ùkIj2Ô�VâtÏçk©�dN:òyhý\ô×Ì[r¬%µfÑdž�`0Ïw>`PÒ'E)›Ø¨+CÞ,ôîKuK[¶ƒú××ã_äOˆBÏnF÷Ì]£+/<µÈ@²¨G‡Øeg¥ ]¯Çh2Çå ½¼U}¼õLÓ*0­S�<ûT "ï�ÈU›„P‘7„|.›)öÒye/é ¬t\Öä²!�嬮˜ÉÂFšCõè7S´—fxœÉ\÷<¢ˆ§?ç9<í%¯eûçÿšâ�Ÿ¡ð×ÕÿÎÏ<óù42>bb‹kͰVÃ4!…üÌŸï+±ºa:íëÂI[JÖSâï‹ø‚XéÀ߬ö2ól†ê>�›å“¢dPT vÑÈ÷cw"—/ô¢ñˆúP|H›xç,tQ65uv–Rv´ÙRä?¤×ôï…¾µÐ7»î2žï ?t†¾i±#»±ÓӦ͌Ù<À[V( —†þà‚sÉ¿˜ü¡›é}ý­ì~ý!þpi;“Ê™„�Áà%c`Xä9¨è|Ößà Ô%µ>èΚ)ð¶B’VˆÒQmêJ®Wî¬è_žà÷RQ#DwËÐBo½Üz²ÄÝ'K¼õLûµ�O¨Äß,í0‹�ÊH1ÍgÍ�è�C·�)ð°ò¬wb–”£Ó1¹Þg‘Ú•ëÛ©Ï{gà¶C4œXbǸØþ°Ø~|ÒŽ 7 =–ÈÏäÒ–B—{VôŸZd`Á$Ϙsg»õÈBoŠplÜ„Z080$Ÿè£=nœ�Oó¬ÉA-h g)5Ç�4qè(Çt«@m÷W�ÁÑL»`@š#cM…HeÞ¢�¼óÔ—Õ‹ì�� «ýöýeTËѰÑÒUBU œq*¿�tÕ8ÄŒ^ÁhWSr3"ÿƒÔaQ> üí÷^�JQ\mNO„såzøOõmDÿô‚·½‹èð-ßý»ü—Cç1¾?:”a²B·È-‹M–Êò?»þ½Ðq5 ›MŠwßMé�yz$Š““äª#”«–´R¯âD‘yX‡ü#LtOl@}ᩬï/ÑZˆ8­€5¹¤Šè¤Eæšö ­¬v3õeÿžˆß¬öºÜ9ë2‘àvŒ¨Ão'›&‹…4æ{Šùì,¯\@ƒÁ­')Ýù={e¤±f'bfµG˜ˆk"WžÙÞæ,ß03ë=]½5ÍbDr…áÊwäÒ2ÛNwÍh¿=kúpkîP곞FL¦ÛИŸïaR9L(@Ô=Ú BakÊ2é$g/&jãQÍÊE…rãŒD²È¯áa‚=‰ê¶ùYለvr]¡‡ö•>ófô&ÝÞô“+[Z«�§­ˆÓº€äMÏ@¥z߈Qð³ãÏå ôV ‡Šùõ™užªÓœwâó±ŽsZ�´Ì6½-œåNȬzXP/k_ø+®ÊÕæéA‡rL«°�µ”XY »|ÿD!Ë*²8?@û¥Ý—² �wŒñH(�ÀüÜc"¸¬jï¯YݼõxGÂn¡¯Û¦àªõe')®Åf¹¤Ê‘ªÈ:y>¹ÁKÿÛ¯££y S½ŠÜ]˜þÁ¥('ÒñóôŒ‹²¨ºÃ](§œŠ+Â*ò�3™S ï×RÊFoÙŠÎôÎÂøÑí—º|t.ÇRâ°hxaG.ök\M ÖS‚T„-án$F8´”öó`ßza¦fe Ã*C¾•BþÔ·¾Å“Æ�­œr™nö´ eôÏÆÑeé4Þ¼ðL#Éo›ìu/œAËÂ5ÚŠ,Àîý—Í»Hjm2Ûj5<êC1�Qƒ©¾\æHqY½*rÙLј‡Ôû;¢ï>1pR”ìq(TÕt–§„Ñ��ç·£/;¬ ç¬ð–:x©ðåI‘ ÎvðÎl®èÑ\‚?›ßùYQø§Ï26^F×›(*ä £€Á]yj¯~„Ø8's¢Yœž6˜ä#LÄW¢R•º*ˆª»ûRb“·®"ç½ã/ˆ¯}>uÆåkðÞu‡ëÆÙvNÕ4ÓŒo]æòù @òÚ<2*Å|«CpVËÂY´H«T¾~%šÌíáí÷P®P5Áã”'Dï®Qòv7•·»©îgP­âW«Fâýï…n¯¦Ýe3JÓªYQ‚™SƒD·Sêã#Vãtëù»›#Ù¹·™ÕºËrXV@;-!å¹ûÈ ¬%Ñ9B=c ¥¹7| ôðì•sØø-vé7)é¼à¡>nT‘ZÅÓ ÁmûljÍZUÇÇÌöî  Ëº‰+œ£%¶›ÝÇ�/EU.¿ôÇ{œìÀÊê# ýlŠ»‘o»-ôܲ”E1G$*¡çC3ìѾl»¸U†ü, \¸³€óì?øEzß~9þ-†÷‡ŸÂýà_²ãí¯c߇žw…ØQŃ_`ûá â¬Éy|ÒL�BžýÝH“<éºË¼WD 7Q)OjÆdÎ’q$":�Ìt •¸h�ÜÈ2çêùèYÅŠ«Ôý¬/PžŽ˜¦` '˜ˆ­è©çS–ôj¦+ÙjIí¢:V`éáí /nÃׯxt^ çõ2ÑËìÝ% ¿ÆÞð0»ãjzš£ó=¸_¼9 �BÒ"œá‘;+ÜõŽIÇ•(½kMæ.E3Ý1=†‡Î˜H¦ý2¹oæ9Þœ¿ËžÏkVvüDÙ¾?î…nüq¶å4E޳ï 5R;”£"o·ˆˆ|cžžê»é?h {â½ó¦ˆÓòYO ;2b—�^KYK=ÞwsÅJKgD±†rFVZ÷'P<=M¡ùiú‡êf,u¾]Y&'ÉÝÿ{¦)8>fAˆãû#¦U@õ˜æö" ¨Y~5oãQ]l³q=ñÜí”u€¼0]^\ý>îéÖE×c-¬ÞBŠ?»iŒq:“"³Þ†NÛD3¯ËczƒPW ¹âÒ8ÃCsòU%Ô,ò% ÀÚ‹ è+9ÖÓôâØ8Q?*g2×D³<~Û�œ#ë§·¾æ<“ÊqßKv‰|¿Ó'¨�wR”ÆDy¾AÏômÆÇˆjÈÛ�bÜ7àžNp×�š.+öle÷Owm›†ZÛjã,'8K‰1¤."Òh yÍaM„ŒŒ¨UCt4ÏÀíWÂÛÖcÎnø,È%í˜÷I…ÌuŒµ¶•L&×â§~÷µ†Á^uAîÉ+í,Y*Püð;rØ#…»–˜ãÄJfþÑfŸ¡m©:[¬ºV¸âò=$71±Ð‹ê±„{x”üLÖõ:´CÇÉÕš„œ_ÉY¹flâ~‰Ž6Œ×l±«>þ‘Ï$kÅÖ*:öçmkwMR­H[°‘ºÌ&¸ó� ^á0·Dt곚3þì]0xµÝ ½1É›bæ;žÙ(Á]ILW|øì<¥T“\ºsF{Ñ_Ž3Îóô,Šm³uǧMèÅ¢\ÒÞºò¶(â³"^°¬8ntáLÄ—2~÷m°$|cÏtȶ¹«ÙÞ°…žf/‚gnwVj‡Ý©½º5óó7k„L«€¿øË¸·¬D,µLGÀþ¹2Rh¹ýF¯ozžæl¢ŽÈe®GdšŒæßSxêq9ú.Wߘ窛K¼ó¿ÿÁŸóäÉI3ai¢ð¤Ýªo£ý¢�ï¬ú¬wpEqUxKi™oê)´_€TäH½É£"oåUÛž¦0ó¨øëLM·IYú (ôqF¢!‹º4?Ierko…û6pÔ1çîÅÿ{ižf²ƒ�k_eãh³ŽèÞª x)ó=WrwéyÜSCQu‚^‹ï‰2Ø&¤¡káôÏŠ~-2 ã亡ŠM…œßþ5 ·´’G¼…”`Π‹ýĤ€°’úÜ´ÎÚ'«·oˆ .3-r¸l{qh‚˜ÙÙ¿©AcÇ”)ŽÀæ{±f­®ö¥â¦ë°,|™¦‘³¨¬ˆáËk\Ü~Yö½üÔïÓÇ+ν8ÏFb^JÍße Ý][ìIjh¬gÔÕ‰;IN ç]§aéWØs02_-dç??Ï„SHY3. MÒ$�—Vê³aWÅ$�Vöou"Rõ!•øBû©èùÛg(ªŠË%WêU|�0a…£Ã5*=í—¼·•1øÔ1 6R�Ô4üÜ­·‡L¡uC ³û1'Êš34à†…>"9S"Ÿ½Xs4Ïîzü Tz*íC…,ë/óœ¥ç‰rHûÏó|3õ8Ó!\4’h=)3žœƒþ’“*¡FÀÈX´ûÒ®)ÈÏÔœ�ôr£QlòQè÷ÞAŸ�Û-JÄÇDQ€ï½)âkë¡}ƒG¨å0™–øNk€ä̓"8¼‹|…5ä-Šm÷‰ì؃ªÅCËFÓÚU|v–Òø¸MB‘@5£T’_µæu�r‡r½¬Ý3o¼•nBŒ‹Z&à1‘”#i_€>ú�9.˜;†�¯Þ¾+(  “ û#4™ó©2à¤U•¥Ù¢me«Â1Üw‚ÕÔaɦ½¤iÌ’"&Öé»åÓÜ«>kê ¨U<žtÍ«#ÒÔ¥-ܳmÜ™-äÙ•4Ã]ÁJ—ºê –ÑŒ§‚œêäH^;x”|}†â³n¤HUnÄxÝe"­š3ÿô΄�nøjãÛT“(1¹el¤¶1·æÒñácfR±+•è©Õð*–ˆS­ÿzÝ/¡÷Ãä ñTj:ágí®§mMG‹"˜“ÃC+yô®jVÈÖ'‘¹É¦,uU™¼×R`­�Ù0j„ûDÕ½"�2˜íMÈ…†T¤1”QµÌ7Z8?P€6Ì1%IB>¼TäkoBÍ¢yé v½ü0üëBߌÊ~,·ñ�{¡7EQuŠ�ù“¢td‚^4˜'n¿0¤±e‚ çlâsv#O³½½8Ûº EbÈ_½Ÿ>K¿ÝÆ™~PC]ÿz6Í´ó[[¶Ðë¾ÕÍû¾A ]”+2÷ùˆï§Ž-4C�餶0;øY¼îí¤ý¥š8ï[b—ì±ÀºÃº¨,‡ûôBN­:$ ΆŒÆ^-8#ÇlÕSÃ~_²&—Nˬ(à[bÏÆ`^=ÊÔnC*²û¿ý¬Z¬ò´Õ¹ëV¦ºÔ¥Þà,vÙv&ñ¦-‡$5Ûø‡Û.z÷Å¢T›§§"¼ ÊmG//pʼDHäð ¦RÂ¥Ô¼(ÚVÚJí4! íË£€Ö9ÿìËÑTþy2±V6ÜÁÍôCȧ2™Ë‘~¾#r§ÌñÂ]M³—¡ñ°·ü¹çdZàôg*«YƒÉ£*Ý̼šU6D0³Åe"�/Ê1¾?¶ŠFÀ¶t£ñ¨ºHÁSÑ‹r|­]`µí°*«ZLŠ|t}2ëڡ܈ˆš5ÂaCqm¡çÿu¡ÿ„�Ñí9ªÇXp&'É 02á_vµÏ+yþa-âVòüÃ*çÿÖaN+ìãD!Û†«†76NÔùš 2ÙêäýÌ”�õìî¡”ýûÙœ´)ÂŒBb¶ô&óº‡ôŸ#³ótbH2‰9ëz2àG. xHÛÑ]{eHŸ]N¯.üÚÛ¾No�Šw#µ¢P@ÿe‡\XN\ÒŽK[ë+mÓ$kÉ¡­œ�yXTž±•ö¾©À˜"ÆÇ#3z2È,4˜á¿=OÄ9ô9‡E~J„óƨҵ ¶D°šͧ0‘öÐùœ ·èRZ·‘¹[’|�lg•‘‡ll”aÓg/‰&á´ØñÝevÞ%ú^rHyòö¦�-ç8¶òÙõ�úªKýM{‹†&L*«êøÇ+&ýEVÖ-›`³EPã?Ö<¹Ç½Ðo¿ÇÀ ÌKîõ‡È]r…õ;_¢B?Ë/+¡¿,Ó~sícR9Fe[ö ÇsCÈW“ð„( MŸoC2›¡-r_È·…Þ“mχêdú÷@�-ñÎ’�&sÛH>\`½mšoëf›š5ÑX5é,ñ™4bfý|:·w³à OÜÝÏžH—{£NP˜@v"ŸCÇsä×{,¦²ºñ•4dÙ¬ð´[ õ<&´—5í@:ÄLqøAvÝ+úêuzEÕe¨V,2ñ7w:kÝÐc6Yó‰íè›N?Áj‚³Ü2vÏNŠ?ÕÆíÜ‚dˆ³¯ÏúßûIþ$Ç‚ZÜ;mÆkaËÜ ÷ì:œ–Ã)ÅÌŠ¾¥72ª“^ ‘ÂáaŒÀyh80rV³ræèÜæpz™h6!X–¹Ç¶‰èËäµ…g0½Ú‹nÝ ÝŠÛdXÅU×r]!צ¨v�yƒ(°GwJäï|yŽ §Øf�à M×ú¾ôæˆöÛ ,ïãyãå òö�™`†Z O ‚ú Å3F›ofÀEVè�e±?î…nH£/CùÉh#¨°7<ÀÑüPŸOWúÑ`pþ$9_S*¢Áàº+ºvUsãöŒjT¼ªåeïç`T³ÑL¶Ð]«CÏŸ¥»LüQqb mv–Ò‚ òÑë£}ŸZ y8u™ëÀlŠ»œÚxÞıús¸n…â}Cf±´é wo9ªIx·DÅ»ðB ¦‰ôÖ>~ý§_JôGc7��ùÂbÌ=Êsr=G3ÉóÅÞèÑÛ>ÅÀé£ÉUÇ»tˆ8MpLv¾÷5&ß{QfœΛ-°ÅOÅZ6¶K…sZÄgR“˜ÒN<îßhdZ»Í=Wâ£4”çi|Ñu�û®µˆû“ˆZ'Tä~õq�z¨­•x×Q¸ûEU‹d§\7n9pFÎ׫øæxeÇ`5<|½ï#¦'âlÈa£å°’zÈ&”Jiâò¡Õ^^´Õ+>¡- stÛ/ΠMir^"oŸ‰à Š$Üû—LžÀ¥LÄPóªU[ŒW¨€ì©RÞ5Jž©FžZ5,M±­>C‘!Ùkâ´d—ž�Ò6‹ew[ }SR[ýÉ9£wý¾T¼Zµ7+ž rw5,fiª‘ß+BTËŽÚíUË[ÜDù ›¼¹%7ÀläqÏå»DßfçÞPT%SèÙX…=*{èˆÇÃmÜY.&xgLwÙMⳞ·neÏxU¿ 1¬Ê=8nùãuŠ:b&¦8l¶Ûªûh¼ÌìÝ%^ú@¬þÒ¹è­Ûi½£}¶—ä=}$oôi¿„ßQC*f $ªV�ݳ†<ª*óÓg~!fÉ(éXÞŠé+ê†vÓd¬½Ô�ï-Ù-òJpÿú6Ú/B“9‰’fÙ5#ÎÑ�ôØ)EÈêã*õ°½ýÂ"zSŽÎm½¤wî$y÷“ÑŸ Ñz=Ú¶‡ñèjÀâ»Eÿì,¥ª}™g(nÓ o{«„Õ !/U^ò~Ã�OlG=õ�Âî$McZ؇̋ÞzÈÈb¶ÌU íäíRϺàùlAArjMÂÆƒìzXl¯ZßÀðp–ï>äg^vÛè ‰ÆD¹Oô Ót­‰\£A^Y4•9’Æ�^Á'²ßûI,ôîy¹‹b[¶ªNX ¼,$üìÏh g;WØí³�LO\JlW—ýÕ²)°šÑ=£Â>{Ms¢PÅdn]tœÜu'(Xk™è曎,÷1½îs0Þñ¸{#à£K!„šÙIT‘_G±HÖc¤<'Uâ°Y)v£˜Š¼W‹�Ëèm4È��X¤°e¾U1çF&•c|´O®=×ÌÓS¾�cLC¾,½õÎèaZ…˜ücÄ÷SŸ X)°»–à§›©¥�d^V‹ÜDøJZʱ,�«�‚ ·ÜÂU“9[ÆÙVwDDdÕx5…UQ´ŸG\^“Z8�ÌÙô ¢Šð�ï¡¡€K#P-<Ú ?%òõ#Äõ*>S�<šÊÓ{óûpßs¶Ì·:%šIÄÝòøÜ<Ü|–Ò»ÞmÔŒo�‘› †Z3äŠ**r­J\¥t(wxÂBÿð� ˜æ_ÅÓ·Ù¶ z³­ü‚è�Óæ8n¨Žo�ÌÆsÙó'»Sérîkd¡˜f÷ø¯è3fŽ?±ÙKxL…3OˆBïžU¨º‹bÛYÑ?'£–ê&Š>âÆànÒ^ÍïmåvmÅ)Iä'.%¶9Ú&omDǦ üÖÜù.vyÝ;\^û¾"ïÿ]ž¼¼äìQMäгŠH¹g¢�t^¹ �æéü³OúÐ;ÏG//1µ�ƒŠQ”5þ¸çye“ 2•ç°Î¡ï†‹ñ¯~1Lž‡êþÛÄ9ï\d ~ÄP^jæçí¥aǃõzÌøHtþ$¹W‰Rõ‘Nª@(8+úW¾Ç¹Õ z‘ò!ú�9nwsÍ¢µgÑÎý;)ž<%øË"Z5n3kþéEòÑ>¨yµÞ�AòÆMh´j­BV臄M˜Q8"ÊÍIú›MŠ2C_ÔB˜¨…4òÂ×]@ÿç¾ñùTÞ³=cò_ýúš"lÖ0+ð´ ¼YçQXÿµ]èæ2�/Äè 94âÑù ®œ=Éf0hR �3™CuŸ+¯<—Ÿ¼Œøuï§|åß0ð·¯æÊmç"ŠÙÊ4+Þ·§Ø&QÌž¯Ñ» z³BÏÂ#3r›�-LÇ'É�¥¹,ê‡zÖóÉž]$§¾¹Êÿdú£ßz›7Ìt¿»[p Ûýa�ŒŒ7g ¼$Q:Îñ\ yÓÓö Óõ=¤þ§Ð~A™ÙiÓT P'¤£"Kó/@C\6S¤¹7ü†ØyÛüôIQšE¶€S‡XÈ3Ù]u_â)gÖyêÃb;—Õ‹VžÒÜóËèK9;9ÖÓgÕÏ¢Pƒ½z1SÚfü×ÊÕ¨xà EGMÂÆ<=÷‰�»D_öà�f†i9L<6N4#Š#¢Œj!ùÛ^rOR`}ÃÀ)%‡õ¶ÃŠa²nÍ'ë6)Už;Ö·±ð:{lò¯¸„‚*¦BE^MFY˜u²3@…5˜xÇ3~þ j^s'=CÄÌÏ÷ðSzA€î Yë8†–£€ÕvLû‹;X¼˜ÝõøKc@"¿ÇÒ[‰Ü+î6ÛßáÃäßõ߃¥¾(~ ßÝ 8ãbûbÇÓY|A?gÎäØPR¦È+±òƒ]è…FE7äKf%¹×s<×]H6ãžóS6·<+ìG‹Ø£R¾™á 7ÿžnÒÍÖ�hö¢¨uƒÛÛ¯Ð7oºy º…ž�iþç…nWûØ^yÙæÈ( ƪ”‡&ˆi*ä²Õ ¼kÒå_¬¾¼-—´e¤–÷+æSS\ªsÐ�ÿà »–Äv-Ð{Û1 ‡�t9kΈñkGÔ+ŵ3�“¢tB¶ÎH7w6ªÈœ1£ë˜.ÔDnD”9óPÅ—•H *8^L)¶¬á£µžCmܳ"zà‡§ò\«RÕ4ó¢ƒ�D¤:E›c�Bû Jº^§—ZÅ£¤�"éYµñSCcayf䲡€NbK6–ضr®„{øˆÑ×�7�Ì9ÎÒO»ßŸº/:ëzE˃«ÕðvS�QÝç¼Ã¿ö÷>ùÄFÄ”ç^•øN+fL>7/‘ó§yÒ'^dWäµÂi]›¡X9{Ün—ßæŒ›P�ºò Oþ¶8¯JÝCcŠø=%�Ö<”™!̋⺠¸pÓõ˜µv�S§yæâ€iÒ)W¥îŸ…†È EMj!,ù*Qz�èÓ ªÒÏ¥Š‰Æ/YUµq6VðÎÈCmœ¤]@�‹Šùî0(βÔ8TÉuyí[®ìûËŒ,b*[Œº©±ÝÔ 6?“Ííû&"Ú>ßžb¦1›/‘Ç.$óq/òî7¼…lrBÆ–ÝȆN-2`üfK|’Üè”MLÝÊ…Ï>´-”Ø*uÿ�_bÀU¦ôŽ›}Ö A4\4" ç¬`UmP‚û®QÆ ‘4{ÐDū۸'Ñj5¼ †ðÀ<=wÝKGã¾ý÷CÖ­Ú­%hËc)ñXìdæ £a_Ü øÿ®±:š·ü°ÅN)› ײ¬œÍ7{¨p4Ÿ¥§°Ç`«—Z-Çe3EPq€õ—ö“\Þ�nÞIZßIòží$oòY{/Uy‰¸1JϨ5[Tšiî «ö|ÛÍ®C¾¨˜Ý·�,0$ÿûâ‚ûÅf•lQÌùo8³ÑrXŽQ¬ˆÜ¼«ð8“ú4¢+ïR&âÍËŒ¼ò×ÜI�‘ø‰+È3^{Â"æúê36»ðž[{‘ FA)œ˜��4d#õ9�âÝô7ìm†Œí‰®¸Žªûd»Æ-�ZÙ³#`v�ýMÁÕæ¹Û~&þÖcgVèA§Ú$Ìš{fçj�¦?)…žhÆÊ®`Ü?YÃ#^Ý­�‰Úúß•avíÙÕž!ݪ×ùH_¿´—“*±óC·ú¬wBZÂI¬{+m…t6pÎ(æÁ”â§ofT=Ôë1¯¸¸dwÑբόZ,E©¦�Šrš0sr˜Ì¸çÎȸî6ˆ+®9c:ÝA²«ÂI—|6ò•��ý`~Ï8‘y‰dÍ,E™Vz3 àßo�5îê"¾ÿ;Ίþ{Æ9_Ù÷mωªäÐPL½Z�Y]êq†t>ÂáXT¼ÛŽQxÖ�Q­È½ê�2š“\ÒdÑ_f"0n,¾¶XÆFˆ²3þQ—õ¯³§DnyƒP[ô÷ÙŽG©Ç�ÇØÛ /:n"µ/¹‚‚&€�ÇÇ)3¾?b|$Ž&P̾éÅOßlÄF©(t:‰)ËD.I’gCxÿt3×Oæ>šÏVc7µ9ëζ߶ÐKÊb�­Ãñ»GÓ…ÏÒ]³ÃftSÖg²…>"K'ªê'»Ð%Š32 Ã`7#“͇zëmGªû›[ 2)d^Ýs“r+ì ùÄ­2­OýÞ.³i@bÔmŽ�J†H>«�§D®uÈÐJ”Ûk·²æ¼8˜GåhÖ‹¢0Hbø0ùQ¼õÜs'NÇÌ­ýÄ8Ò¼ÅoI°–ú¤ë¸k"Håñ™O³Wá�èÝ-âëkä×ê |Y·Õ#_›+;òQtÛ1 ¢÷[b—ÄöÌìÒ g¨5ÃK�W›„•šM=¨h|ŒÈÎ šº†W1_èEŠ«2É%:NN¦Q5‘k4•ͨ}!nîµ/× á |n+‘�}´`ô÷N§ë¤3:c†q¨¦ ûET½Œ¢D�Ñnš(üú½÷ˆ²IµÙWÓÍQDÏú"›¥N°"üYsFi@' X‘^Ãá©,�&¢¦,`2ËXó3¸¦¬TzN”3}z6¾íªíª™b³Ð»™LcÏæ‚5’MqQè?Aʸù‰PÍà”/%¶Š§¨ZÅŸœ$×DfÛ=Ki⛜#3´Ð[à‹ Eæ„cžÕ“÷sZýÔOsIu�Ñ c,dã#Ÿ-niÈx“ p¸l¦ˆ÷áè.¦äeè®N+%7oÜï�Ñ ïâÃÝÃX4c ê/ël;¦l~?•gZ._è…f‘ÿ|O™kUb|0p o91G„Ì¿ÿPÇãŽÆþëv$ßÎݽ Ñ[_æœæé™;¦§ × #ÙM—×M;Ž�N‘7c×jw¡ùq¸÷/àGþî¬ô 対š¾jÚ˜]Šõ*¾öQ¨!¯ÎPüÐú´ÈÀÁÿlF4Ϥ=ÔÃê¢I=m)¢“$é6VÎ^ˆ^Lc4‘uÈY1È–b/næw™~Àá âAp¸‘Ç?se�Ô€#âÄ §#»×(¯ Î$¸ív@’î¥õš1YºhqL”ÇDÎ3>qÞ^BT½ïmÿ„7ò)J¯y;ç¾ýùH³ó©˜�ˆ&sh*?4A|ø±�' ùÖwïù�&È!èú!Sä÷ÌQ¾X”ÐѼaºÍßù=}€>UqÇPD|߯üÕ�ø×ßApý�ôº™g¾ãW‘æzÝŸ©RT�^¡¨]n’T´fv8‰ñ¾ûiJ0�â/tp:ŠPŠÿÅ×3r0b~¾Må³]�l—{Ó„¢)lÖLÿÂl�Ð bfæáŒÕ÷·ê,.”X½˜†FGó€S¡ž;î}ßœáœ9Q®~œ^š)¿Jµ¬&á­›³8àŒŠ Ú4†©c¢�é ïçÿ'¦Ð%ܱqc ¼ˆós®Á/«‡é>¦š*ÒPþhƒü‰%v|C줩�—ëÎùz.¿…ÜÝHôÉßåÙ+çR‘w§]¹» {mÍ3oˆ`‚‰Ls¬FÅ;¿Bކò·�‰ùÎ ,t\Úòi·]’6¬¥!�vÄTs×ÔÓYÜ6ˆ‚ cVçZ-÷³¨oúP�ŽJ¤imå‘ ´”gMeÒ¿gHE‰žÏ¼��ìüh·ü.˜„$Ÿ¹÷¡>>¦ª“ý¼»ÙϽ÷öQSx”F> ĨR÷G‡ œãÄ*ç�‹íûQy;úˆ1ÖtRÜ9á.´]:2²¸•÷ñL  Ãùš³—ËØåm7°Ëåý“>'Mt“Ó‘‹ÉI‹HäÒNb¦×bþî,#£�×S6)wŸ(¨j :K�µÆ˜ kRiŒ�arÚž§ó¹àæË(½m”øí·F|ë²ß¹ƒ§œZd >cvaCÈÄKÕj9ªse&&z©×{™¶/N&M7^bN”ÏŠþ…l¼iÅ2™^£{<ü1¸÷/àG½*7R1ëe Þ—P@òøÕÚsÙyé[8÷õÂs/¢¡ *Š®°ë±“†fT¤©~>¾ÐË.p­JTçÊL*7Ü0i1�îæg+¤l„Q y'¹µ¤*¡³Lòɾ.ÊsjÞgqÍa%Å1QOiÇg=Í1·º�ö‹²‡*Ké¤Z-R›)F|å]%îêäQbðÃêä ­%)²®<ÇÏâ~ô=jŽ[&��{˜Ñ| y²Ó ¶ªC>?ýú—Ñû'ï¥ç�ÿ‘Bõ¥�pá]¿Æˆl®y#_C»ë1V$ò°Ø>!Î)ò··”ùòFÞ £V]f„³”˜„ØŽn[$ºåݨB6 ”[k¢ >í‹ ü`G†Ž³*µŒí6U�¹ù>ƒbò*Â;Ú0>ñ‹®§lœHU¬)g¤Á£AVè5*ž‡GÉïE!—Õ‹Œ�—ùY-þų¥oˆ�÷‰�±q¢®F V yößý"}—¼‘�ox+¿ _BSy®ŸÌQ«xCvlzÇ[éË”š�ž§wÁO€ø‰(ô &âæÊuÇ çSy½ÙPI égCä4Ê ¹Íš ÛkŒÒcÃ"\ÙheYÕÈc<ꦼfóUäV«øÙ™ºÑ Ç†:YùK^É#c»Þü‹>¯ý‡�7/D|"Éó饀kç=~ïÓ¼ðÒŸ¥¡àGó€3ˆûç9ï³/Î3›æY6VP–E î’`%ui'.ÊqVø¾¸‰Âavå©Ú�Ç ±�òmЇ<ÎÊpÜÓ4 M\:)ÎÃ"§p¥ÎŠŽ0gqW�ä’Oßúþ &˜ÁSš‘j Ó6îjŠ¿!èl¸´R.ºãWiZEà�õ ÉGŠyÁ­?‡ÿºO¹¼ýLÌkE>¦×�-ò‡ŸaàËÏDÁ;s®MyíΨ³#�hZ´°Jé&™¯Xú®]m–¡üê: “ד[e—ôh_ŒE#Ì•s诋§ŽHбÞÊ»Ïö3©ÜoŠÞÜ£cÖ£³ä·úÛŸ5ðQèB¹YTR6FÊ­>nY"°Ì4O)®Öàæ³œ?¡Y‘É[?rwü4|ØÌä«Uzýwè9Y¡KF•ù™³9þñIrw>`¶øƒ(øÏTËjØÌ2jM…0™{&‹OßC{ß^ôÛÏEOß�b&•ãÎzd3Å$Ñ;Üùÿ¼£‡µ¥Œ6cXl–«î'm’pFEZm—×¼¹Ê�ß…"¢¨V³’Âð_ùA²ng÷ë¶Ã½Ñ™N‰¾Ü¦|éˆ�ÝMd,½™Ÿ>zËM9æKfDè«M ƒŒ2Ùk ´”Gk<ù’w£©<4‹5*Þ^LÜ1—¨À�ôPQŒžt+ž†ôÒúù+¹»DM!CÊ\e¥Ã7rÎÑùZ �½ÍÐâ½-YL·u§ÕjxMj�|½Šÿ,fŠ˜ÊŸý÷Ÿ`GS&}Uѧ/°ýÎAzšÔÂ>6.tùð¢OgÝÈžSù´ÛDXç§ -øÊYJ·ˆ�_;d�l[ýí›ó'NZêÿù…~‡Ù^M‹Ÿ`÷9´ÿ,â{ò2ʪ»&‚éÔãÛɹèÚl<Õ¼‘âĥĪ�‡H£fö>�bQñî–IMÕêˆ,µ³VÃ;! 'Eé¢ãä˜Û¿•FêÕñ_ýn¿‡òÎ}�±àŽÊ¤† 9;¹®`_T¾¨…s¢üûÑGm¦÷0mȪ��fͤÐ8-ƒ�ŠeR_Kïÿ,W«ÏvàCn3Yéú x0qPÇµÜø¥9’ÄŒ·Rcµu¿!žÙù-T)ªI¨!£Îã²™"¹÷}Ρ“ºhÍ ªmº‰:>k‚�ŽƒZ¸g…sÏ1>sjÇÚ;¿dÎÅ'DáÎèAuŸë®+Pk†5FpèúÜA]ÉlI»JÚ­ùÏOлg|ËÜÙÞŒfÜ“Œ|úà8åQì!GÉ[å™o^^�ÀŒk¡…‰äct |Sä¿+“–sF>+rùz‚Ÿ¼‰QõÔš„ßžbÛ'¿Í¶¬Ð%·Ú]]÷¹x¼ŸÿŸ”BŸù¥ivÜ3ÎùZbÇ“HÞ^dÖ̰½Të)¥³ ¹¯3@ûÚ!äwƒ�›\´J8#Š%ÊÕ�÷‰“†#{ïd¸íÇD¡6Cñ€ÈS¯ÇH!#cªº=eBÄ ·jÓ[kדÃâ€3}Ö<»ã^ú‹s˜V>ü™<í Cgíˆ0Iq’„\*‹€Šd0Ð…÷ÿ#Ǧ T¬ƒ T cns™\7[Tµ l²“šJ±('áwZ”þå6Îüzߨ8Q…cŒGS�ü‡ï´ÝëwCøiDZ° h¯ã,ZL²Lø¹/RU™©FþÀaw�(Ú¦fÞXZk!ªûV½"9]AŒ—0d,ºDþ’i =…3¡L�dÐÞ²2g£Á%ÓªUüÃÄÝ‘× �Pl2ÞjF¶«C¹í¿toQž”u®(`Q1÷¶C’?C*ïj�?+úµÄöL»žiû·á6e°Oüëqÿ~ÔkÐâ¬ Õ zAž÷­,·–R�ù4d¶róÊ³Ñ¯Èæ¬™-9+–(e\m†âèùÚŒiòQ‘w)ñì¬q¯U„Lj¢�ç�—ù=É¥ý‡eô·ÛI?9@rå6Vv¡Á<Æ›ýÞ‚áÇŸ¥šͬۄGîE!cŠè½òÓ•N‡$1„Õ�´«½b-µc)qþÕÅí*—*¾dÚ¼€">ç0mÙs‰[ˆ£Gj²Øýeá�íäÑݨV”ÌX®&r\«=o»Îv6eÚëê¦ûªB–峤�9qÞ›þŠIå¸ê�Ài<È.-±]Ÿ°þë†�bÞò{qMä~µÁ.ÆñÒµŸÚ�ªE’Û{IÞ{úNŸÇµ*È\eÈŸ`"~Xl×;l•Š>vÆž½P2‹éá âk 貇gµ_€Ãr�41räNj`ì7-AëyÔ*„¤ûcÅ{TÑdLÁŸ£?fU÷Ðõ†9gÆ'3Å]ã±”äYVŽ9ø� $×^ÉlI6\ñö{ bzzÚpÅeÏa£Sä‡ d2Wmb‰ŒB­pí‡8 Udò¿Š{)_;çpl-bf½—IE|ü,\>ÎóKíQ–nªÌä0GyÁ@5z'¬q¥VÃÛEÃx¿k3EžþðËûP; 阇VB˜&¸kæ|œK³�o‹ §~ )ÞM=æ€òUJÀCÇỆ,t³Ý6Ôrè¤øJðΦ. :Ç‘â}¢p÷Ý”æn§Œj9~VÿwNfû¯ulÐbdÓSÖZ!«I?-~n}·Ëaίä¾!vJlËŠ;ÛúvwFF¢ÿæ×é½r–Ž?—üåÓîjùçõ�ϨÄ݉ˡÙ}ö—2$•h…‚qÎÃbûIYé´lä’¾ê> FDùšyzгŠL,ôê/bVeÃ’IfÔ5\6S¤¡`¨Žß`0&è £¶¸ÙªÂzÔ‡þ½ÐÃo ¤VËi‰ígDß…ì+P«xœô¹ô½ê�øƒ7ò¤SQ‘w%³%-ÐûÀ<=7ˆ^£�m¬˜ØÛ†‚}¢`Xßve‡A{n†Úïá>Îv˨ê Ų±Ì¶#õ²xkÌwa¢cFZu“ZHËÂ[J{ype7ïûÍKé1 µb2gæÙ»ò |â}ð…—Ó‚µU�³‰Ç™ŽÛõ±ëôò÷·!¢êPæÅ®ºÆí·ùYe½ £Ü³Ýl©À »s´#£Oq:* –‰uZMÊ,žÙÎÌ94Fƒf�pâRâ C¯q³žB6öÌ\~™LzDD7Ö,´9/½ŠTuŸBë9=¼æjJ¯¼Š§\ý¤`'Ç Íš‰pš¸Ô¼„75ëÆOn^(U7;º=ÞÏÿOP¡WŠðþ¼Æ“k_c»„{>µšÊsƒz¹üë½4”gw=òî?ÁŽ›>ÀSj3÷ŒYs�›usw[¡†)t“ð*ä�ŠàYÏ2L¥BØÇòJÜÕ1Œ÷45òtÅ¡£JBêë CH&T0sHÙUÁ$y�´=Ófö|ØèPÎoö÷¡ä­Û-"M=Ò4Çšb¾›âu>È[ÕW«á5÷*Ó WåJ;è¼2Ï7„{ªå°˜سµÓ¡‰T"ZOrܧ—¢ÿׄˆ5„?jõñÕ z/™¦@õx¿‹nXLÎÊg%ñXi;$i@K%’Û@f~-c]…š7Ìè#]…öûÞZèî™§=çŠk hYF¾ÒêÀ¼<Ó2ó-xßë¨5Ã{žG¹^ů"·I-4c3m)öÌég~<>I®!‚§0ß³E Ü~åÊ_Áuj3E£‡'b$glÑ¡_¥?Šf™¬Ð«–|R”îÞB8z¢_�ûð£^�yz¬uÔ+šu£rÛž >I.{©<ÞÏÿOL¡×æéyí2;-1Äi6M‡Õ�{5Ûð×'è­aškܾ¿¼wËC‘�)öÊø†GDÔ�îgÇÃb»}@¼+îgGÏCô]€j!?0¡$-�–פˆ4�™IËèƒHy4LŠþE±M�ô;Ç÷ÌQžù}LyR”®º†Ó`ªûL¨—ŠrÏb¦¸›¯÷îålÿÆ¢ÁQN\Rо.%n04k0y!*dzúxæ½wiu\6’�ŽBN'ÛЇëLô ù¢‚ýºÜƒVX•{†£�šEnÔ9¼~j—/ôrƒz[ÚŽ Ç)_b-µŸü6ÛÀZ„Uè¹Ã(ØK3$:6�&f6Ÿt$Ó,sHÒí6|í}\ª8C8eÞû¬k?>f²õ2^{4ð„ÜKPaú6ã,«2dhÀÖ[OEC¦S?lçõßäœ÷½��ìEaŸ�pT"žù-}â^�ûð#ö¼+T¹Ã �ä«Â¥Ö _%J69¥h¢�å_ÇtáÖ“”.3жŒýåo†ñuQI‘‹šÌ-Ø©6 ™¹¬HÏúB¾ºjV›´ƒ“¶ÌY8•‡R�Ù ·|ÅÅÎoˆ�›‚ÓÅí6yjJ &áñ 9ÉRlëf�é×î'ºKôMˆ^�¥¿ÆLQ4‚áa‚“¢ôA±í*a(«ã#Ñð(=&r¨òÜß{1¥ßMoõ3ôTÿ1ftôÉüí «ÈŸñU×ЃfKœ8f\cG,áfÔä¯�½žþS‹ ̉ò0 Ø[Í&n£A~ÂŒM¶Üˆ¢Êõäî5_k¼i!6ßWÓ®ŠöE—?ŸZ÷­¿‡³,HW“Ô°ó„³¶�;'¼¥”§îuh2wêK ÌÎRú¯5¶�Š Û¦OÙ®ü¸…ŠZ&½å¹ÉáüZd|ƒ N,±£±È6«ÞóÞ-úÇdÂs4OEÞÝ¢tb‰÷‰jϋ̵Eèôãp=î_À�zí¥Ò°T”«Wñ5Š!œHá°È·DÙ*¡¬‰ãÑûÖ3ôÉÚ •EåXW’-ôø±Ìv?Ò>ã{Êè%^¶r.|õlˆÖMÒiÛdž¹mE( øîûtÁg–Ùùmqž6yb]x`4è6‹dÐÔ5ë†S“°JݦÑcµð½_^6ÝfYˆ£cc”�Ÿ¥ÿšyzاÒæ¶*—©Fž÷h;7Lôr¤ÞËSÔ#ŽÄ5 Ô±!jåÐ5= sNG�^³”>NïCgèûÌ)�a±_Îå½°u¾­®f`¿ˆŽ‰Âô4…ê–U1+ò¦³È"$‡mÚå¡y‡$�yákÍø¢ s>�çuëOGÊÉæ¶ŸšÏ*bµùYQOO8¥,æÎL #ÈaІQªîß"v~PìDÆÓ~BÆEùq“ZHUnmžžKì7@ߺyV¬’ðñ~þb ýG½Ì9RXŸ±ÉO—@Cþð°�ûVð&+äÄî¸)B{Öóмògàog]>¿ó¥N‰YÏ1¶îñÇSµ—é�…«œÿMñSv+fJ-M™3ú×o WŒ�ê‡cdM6GÔË·Q?g�Þ Û‹/ü2K�‘µinºÏª„MjÆ‹nòÓÜ›17.Êzˆ¾ƒ(š`"–Øöí)¶Mlæƒy["¬¢¦ ÿöÞ<¾®«<÷ÿ®µ‡3hôljÆ8 È  C ù’†: t<¢%ÐÖ�pM’–:êe 5·¦Ð+êhÏé…BR§ ie ˜4‰¤2±ƒ�íXže 眽×óûcí}¤Zè 4Íï²ýÙÉ’Î9{¯½Öz§ç}ž<þýÔ µà�ð*:7Êo.¨“5#åªè­ŠÞÍ¢àAAygŸ÷NË{>;>f ·+YÙü1ÌÛ¾]äÎfÄç–=g;Ù“¼yã—f´J¸åVÊý#D7� ç~Ñ•7ÁìËB‚=(íõuûüÙ>:)˜Yåð‰Ô”ò£…þ:·‹Â®) [P[¼‚G�`lŒ²÷*qÎÌ:µ‹Âe¬-� ÿíä“Cô‡E’�®$ùØ9hèéèÉTTBkKSs¬= ÎU;’aÊå9âÊ£;)f}ІÊ�ó¹èßÀÊ×}ŒeoaÕ?þwþò²ó¹®’Ó›�£Þ3ÚIQôsõÍtl`W¡F%È®5#lÑhØÇD¼YªÄÇåëøÓLwM±½�/<ïx^º *]Á½»˜*Ô&|÷Ø�m”T!Ècâ-·R¾ì:Χøg¿Eámï#zë‡ L¼înåÂ<Íòu£KD –�Jž½Ïx!¤ht½c'èáÆoö°òÌEèw ¤ï/ O®B¿_DOêË’p#[¼æ|m‚¸*:_+ºªU¿`o£ü¡;¼êNÖœôHV¢-ôÇÿ"Ï3'ãÏ�rQ®ÛFÍ£¡�B†Æ<ÂÔT�Š®ÛãûÞkñ‹Ä²›D;ßÝ‹ùVljÉÜ:Öά—•%¥ÚÊ4¹j+²lSi3Ú¼œä4æ["˜oú~o§e,L? ½Ä'Ø2„Ö@f©6l-dýÙž{Ý[Íh'£Å|AùÒP´vË«¢]Wâ½t*£‘Ϊf;‹YøÝ:FùdV%ØÉP0ûæY÷Íyžô{b׊Ÿ@W,ca:âp N¨‹T1r%NŸ¸ýR7R9 =šÙ/t_÷o7 Uäyä�•«¢së. µœ wî‚$®È’†ÜpC‰F¾€+/²¸¸Øÿ­ç΢ þ_`þh¡ÿ'œ[wy9¤œï«Ê€ç«ôÅý#DÞ2�Eh¨Èý/ì¢�¼RÈNŸ/º9²Ú×ÝïžîbLW©Ì•ÖÖ2Qƒ‰E¹¨%ÍKü Óî[¶’3gŠL Žøì½9+Lê < î:o÷ñ±O>ÅhKT­fÂYÖ¸†‚¨$æj7žyt[i�(®žµ¦V 2F›•9μŠ,l‰$ì>ï÷~C¬PD™O=9Ϻ�ˆe¼õï/èæÞé(à€"Ψ€ZETä!Ùu˜ê»VúšúÂÅ%TÈ9„tÛ bm; ‰òŠ×vm…í÷ÐíAM²£xM4äûÒ¥0ãËúÇ=�—Ú– ÿý‰Õ”ò£…þXÀc›Í®íyÅ„GF1°Î7ªÜwß2Öêy鶘ôO(ê%\ë‰!«Y„F霘 slŒò½¯ò ¯Û¨•D›ÜÒfYà®ão½�­GCÿþ߾Ѱ_!�J° ×Ijvq\–ôõWqk¹OÄ£žÈ°G"äÐHõG}"¾n¥ ˜cX3Rf›Jp t1:ïI¤Ü…û».Üß=…ô�(ï_úѢU<×y–À‹%±e Q…¾Éìd_ezi‡´’‚þ{�“.&ie×™R<-‚ù9‹kZæEéÈu\¯ßÀ#£Ea�qÏ@(5W«„PiJb�×Ïz~ï>–¡Ñ�«T~*ú©sQõɤ7ŸGër6¨d×1Z̳ï’Ï»€gú÷Ÿÿ�úÿ3g•Ý™±wŠp3[ mJçÕoy;ñïÍc>wÖòÏ ßz‚âÿúc&F;7gbÅw~À—ñTõ­®UÂ6$™\�ozš®)ѽ]ÚD½ûAÃÑ9Ìl‚=ë<Ñ„4Ó�9qÐEüÝW©Œ*ÁÍ×Ó¡Ìr!Ÿ!Í,YF åkß*²¾y)öO*ò/®“‰ùå|£Qâ«)ö�÷³JÏÉH´/Kd©­‚“U!r¦Ý{ªÝh,bÏéåtÜñ��iÙ¬Ú@ ‡yXÉæ\J)~èýlU�Z%X"zÙ å]hï¥Sïc_qš»»2eÝxl„•Ó¢kJ¸ûâ.øË?êàžìà.uñùf‰Îaï~Kް`gqçe�ÿ_ŠÁ´Ð¿ÇY[ú£Ñ�Ûì Ç"r�^\&iZÔ‚†ó~å‚[Fêèm>‡«UÑÕ>:�<%°dFwRÔNo%Û½ÌK˜I*"ã¯?ÞÍ9##1‰, Ž¢R"ùF“º©‰B}µ‰xå KĆv/ÛC‰Z%Ø5å‰,Éä¦SÄÀáu+P³„[€yy6çÑ{šï@�•LŸGU¶š (ŒúdW­FPEá|IêÈ:úϰ©›òÇF<?õ-´E‰Î†°ÉÌË2/¢ÛÞÇõêhk�å|ûK„�Ì Ó^Ry×6o(øä¤B¡€í*ð�–ñ²Ö‹#RYÔ 8í0'ePjih ¯½TÈz¨ò¢F_¥’éÄ-*©ü?c½´Ð¿ëT-ý^)e´J˜ƒjؾ«@÷ª! Îài”œ"æÕI’¶?¦$:Zõ5p�7Ï9åj�¶f™ßLQs$ç)¯f 1³3Í›v|‚/¬mŽ#ú˜õ:Ê q»¡ù>3áž}‚³}ã¨V3½£GéཎSÏ{v´‘ Ó ÅÈRÄÊ8Q,)¡iŠüÒ øuÆ1«&&ã¯ßŽýçwc.½’•/«Ð#ßÙŸx¾f£ùêqÓbë�ÿŸÿp´È×Màfe4¯ mQJ[Ä<üó¡Ö_~ôïXsÛBŸ©&_½R‰Ù¨–ÙH pã^À1ì;©5ßÅ�™KÀæ&ªj?õš1Œï€“'!y.-R�u¤Ev¥2iàp�÷ôxâ�÷NóxŸßËu/àd3öRŒ1‰zi¥té2®V1Ϩ³”AVB˰Ñ�ŒÛúí�]}"¦r tG^ºœ¹oÃ1u0¯Næ]Ȭz8rf%ÚÄ‘{;2áÙ¥j«Õœ2©j3¼âW÷Ñ{¯èàÝê%úø_™öí³¦åw9'BOQÕÍ'v²Q�¨?ºBtŒˆèÈ:‹U‡Åª‰L‚É3ñT-º¢ƒ©©ÂÅÌoêæÀ©ˆ¹VÀs\!GUæÐ±s99€Ô‰<Ð�i¦q–åÈTXQF¶!ypM–à¬/ä¨ÓËù)½Ì’fŒ;òÌ6&mä~亿žë�‹xÜ]÷/wþ;þˆðƳ†š ù§yâ?ž¡óÄjñ†) ›3Ä™/cõçšfYùg1ëÞþ¼GÑGçBŠk+”x½–E|ü oû ¢?x¯å½×ñÒ³«™š* äÚn늹(åÈ�çH#úh·kV®­uÒù—×øfRàL&:˜Pd�†3î\¾z-ëF‹Ÿ=7�ðXù<— d§Ø^‚]Lîæþ® è‰Ø¾µÀ–êJ £¿ñöÞö?)äõ–•`Ò” Aëì3ÑúÚqí=ÛåëÖTe²Å™³žîCÅ _Å¡r[x— ¨ó*n-óòC+Ù|¼Û+Æ(ôcáŪ™7 Q>î›Nz•N(ç =ߤrBFe‚…Ô&:¹^eN?·@ú®t+Õ�´òGåµ-ôïëüž€™«ä;¬T‰=:n{yqA4V…­æª-¢˜+ätÐ9uR~æ:Ûª¨FÀ¯V£TP°†±2’¹ä:úD|·èÒ4]YIÍþï{èžè#Þ‚¢«ÙWdjªÀ˜"¯,ë9鳞rŸy_¦K°òP_T�/·b>Ó(ó©ñï<ÄÚÆ%m+Ø?yŠ$/XÅËE‹�pb‚Ι¯xWÉT˜ˆsuY2TÝfQØ"ÊÛEÁW&b 8x†Ïø–Ïœ|#‰ôŸãe­ÛòV9ãnF•wùùÍ¢æ¡ÂRø2±|ý zø`æG ýû9¿¬Ac^\¡v]‰ë¶•¨Ê²SEÆÔF»-]è‡ä[7÷eñùwYè¶½ÐåG6°«PÍúÁ}‡•ÌÐNŠccô|àþ\Ô€ü{än:[UÈÙj;Qóðϱ}W�u²âØù«Ð[:ÐG:Ї—¡xòþ5\q¤£†W&ÈÚpÙâ=’ ¶f{ÓŸô›ÍçïåœÜš×Žú¶_jÊšgúËÛwQ¨ŠNîùÕnOÃU ¿!V콋´L�êáÎr"‡6_»è<.ºÅX´3˦�2T¬z ìp‹( cxáGØ-ôï÷ü·šZö]MñŽ+r޳±hb‚Κˆ70UXBa´xV‚GüçrI�83 wFNô •Ù®•¥LªÙìòªŸÑô4]£ûè­m£ôZ_C+ôÅÖ/°%¤¸v”ÎOÞïã]‰bî #…ÔªñQX7J±Rñ «ÊYV®&/I%ʶRÈ“~¨j÷ tH”ï~§ÿìêvº_~¬z+=ÑG\a"FU»�ãÝ™új@ßD '/¯±„VË[pÏ�Åì¨3µ½à%™GÃ)±J_çÜL¶9» 5¬¾ƒŽ¡}ÔÔò£…þ}�ßW›j?Ñ­WQU[%�ÒYÍøÄ´ØÒ)[øz”Õª-�Øù™AA‰XÿGÏ¥ôÒ°—¿žwÑ–-¹$” ÓÓtZ„ŽÚj5XÈ颤"»T¨ŽÒ™!ÛŠ^ï<çd˘Q·ï*Tä+@FàX ä|fjŠî29àZ­„FÃ\ „»¦üF8 ‘œ cÀóÈgtN¶—Ÿí-ñÁWùƒ·°â'¯f½z2<ºÑ„oï]ŠwWjÔj‹aÃe%¯A¯):-–Ÿ9ÄÊoŽÐSCÁm£VÚs€R®Yÿ£6Õï}y¬3Ïâeñ_ëÎf ÓPY¥³Æ#I`,`'Áö�£Ž¬ †€áÇ»Bø�![gP0T&&¹q/…K/C/]…]~ ˧™a0Ÿ-FHÀ …-ã[Pÿ5÷Úi-cŒ•äŒ1„„꘸s/`ó5¨›`xPæ*.5ýŒaÎuïæTë7Y €‰T¦þçòU  ´dpL˜�»ÑäL„ 90¡1¤¢j U!± ÓUšÆ-_….�FLR·NE#Ô 'Ëô’n»†…‘µëè™ñk·Ä<�§'ÏÜšÝkAÖ¤ã6~báJ>ÓñÀW1åòn‹6 œšdÔöÉ$—câ1]ä!ž`0�äZ3D—�~8dŒ€aCÔÁ ‚«ÕŒÝX!èƒðØ1‚•«ª³�ïü{lǪv\ ~®$û�¹:nã ZòxlÂÛÙkï厅{ÿšâÞ0=«ƒªÆ˜z` ÷;"Œû¯u&L=ÿÙø¨ó¦hPU­Nr{Œyõ+h\² ó¿>NÇÞ^\¾Èa!#ÔÃc)ý‡ÓG½�ü"‡öÐL“7 ³_%1Æ3(‡àAÆÜSùȳ™½÷»p*&ôjÇŽ”Üï00ФùgçÇ2¯XŠ1LÕ�Ú¿«`ìù�._…Nø×ºáª¡Î*÷û Sq{¿ÀüÅ{1;v(öøc;f–X}XÌ}~(æØ Ò–5)©PKصLüù0WRì.º„¦aÔÕ!63Écýø>Ó µx¨“1\šr«)Üy½)û±�:CíyZcÐV€øvÌÃ?ñç.ÀÅ S�Ã�eú{擄 }Üfn�ë :ÈÌ‹u÷%8~1šÙ´Û„»?#G!ëÑÀŒÑª�%³ Øê«û�¬Œ>¡lÃ7{·W[ .#æô¸a²¿±g›‰{Ö’n¤šÔêUS©PxøaÌêã´˜GõKå*2fÑ¢c–î}™72‰�ìƒ÷¿›`ÛušÏ6ÛÁOþî¬ÝõNã–̡(Pi.¢XޱœYù·Ã\ýë7só¦†Ì¨£f ƒUݧjéI-Ö™ZŸ1/ªPXP§a=T¬VÃVª‚!qß»Ê\²©ù;¦¿c7°X n¯HØO¬uœz,ãW¯›`°õÌîÞ_ýòñZf�‚ƒY¡‰éİk®—𜇯ºBý/7­±-9E@/óï¶¢Æcùüáý¦÷ �¤÷ƒ]>@ë�ô;Xo¯ v[–¼bôï �q0Éè^÷æf�›ã· „ì?l©®i°woX¹ó¨z-Í>£ üÜ4ÑSVá¾ú¢§]†aX0Š…KcÚ=>br+00s�ªUQA ÁøF»w»šŒ²‘”34¨ÎX ~ë}Û6`yYµóð‘ºYý0ðív¼÷}Lo1''€¾ì'Æ cLÕÀg0Î:CSƒ+9lþÖ)Ï›lÁ€ÿœÁª dã=4Ì Uí9XÕšµ¨>X¡v’š�C/  n¹äú—?ã¢Þðûóæ_®@�™ãwpyëfîÜ kñ\,€IDATÓøÝu–‘¸ÑúÕÄXb !¤ägPI±—+íÇYø› °Ó “�~y/œûU*�íù½®Dë½g‰èGÚ�;w»Žq³ÿ–ãpµ‡öúÅžý;ùãOhCÅ/íh2¸EÔH\QŸ ¨ô¥7n 8ùy d^“á§–ñ×ŧ /  ’4Â… q¡ó—€3‚ñè*ÈçÛcö½ï£ÜÄ{ö“Ð9d[4š®·}öî•9ð\еžé*PÜSŒÉI°Ô¢K‹î»„¹}/Ñ9pÖq• ºÐLE¿ÆÁtˆ·Ž·?ûoOHHIÓ‚ á[8î;;ÿ¬‰ÍüËEãw0h¯c ³B‹©:Sò´nœäÓuM…�W5¸”~à'BÖo;'Øwð®”sž‘ỄÿÊ/œûÓªuï},Ã7Œ±ÕÃ[Š�çýÆSÌ/¤<C1I8XRÓ îüô3¯¿h…0`Þ¥\MÌ-4¥ÇX7¿Ê“ù$¿B8¿ŒùRGLâR °eâþ]SÔ|‚æ .ÂbiyŽGØ´‰HH¯=ñq®{u äîžó9¼õ‹Ÿè°ll´p�MŠΞpœê2 iÀfc–æáÚ C:‘„sØkiÍÙP.fH–¦³4ä[7åòŸ?QO¯6Ú”!Q€1£�æ‚áÛ®›cÏ}VÂ3¬„¨j=+kqý÷V1·}mÕ’l¦™* =`F�\þó/ ë-ofÙ�7ð‚?}!Ûwu£ÑbÿQ5§‡–åÜ/O^á¡¶9­•—•ª¡ ïûöm±×•BÒjÀ7„qI®»fQ+âYÒêc.ÝäM=º¾ƒ«v~ìjÎæ)ñ› éÜŠ®{ŽÓ-OqUÊÇý`”N(éË×qd.äÌ‚o½u ÔÏÙÄåóÖ’8¯ÿÿ“ù‹4„™kYšIDSEÒ¹�/¹�oå€JP)äœà •ŽÇ$k �4pFB:š ó±Ú\¤™)K ="íûDãè½ÄI‰tƒÅÒA@A©Il ‹Ÿ«Þª k„‘ï7‡žÐó×bSYÔ $8 %¹ô)]Ÿa­w= RÄùÏZßuèê«RNw7‰‰5¥o�"HVrö¢9°àJ`[HÖ!¸Ù'ô@AÃb‡ CèhbOZ’³˜eò”ÿq{Í1Õ°õA›Æ-ôg÷Q8ÁF Æí03êc@•1c)a†7Žº!>ãö«oónj)Tœ Á²Ó„¬Äòr-ÔÁ þ&+ùèoÜQœ«>˦óÖrÖÌð¡¯ê¢w]¡8öXF¯n*`‡Ù­>Þ§Ijª ËøCÿ-cŒ©2 1`�)àwºX‡Ë盿~ ‹×h3Éþ§ãVÏuщ…8!n%—pB0¶‰Ï(…àb,]@`OðùÛ5aH2÷Ì&¡M`¶L7(îÿòÀÂ>7*ãïz¯åSoxpÕ¥—¿ßâ`{Ï«[~ãWăëN>jÇ-!8¬…y ÷ï}BÇ8÷nˆ& ËB^D“/á6NNÇ/ÜKc�ÕÒ³¹d‘·ý_'t$cHýÜ7œ�à¼cØd˜š`÷â÷aûH Ús°jž²« ;Ì�m_Ó±% ¦·3Ë�í¯ÖÅ·þi‘(æ’ÛÕùöߥ‹Ó?ˆ1^b•'À0ˆ¨v€Í6:õ1 ÌÿNLâæú~þ¬‹h¾í¶øøAö—:èHЬr-0÷mØ›ÀÔ£^t!nïƽOì…þ«¡a|�eáÁÛ‘ðàW’ {¡gá�ÜnLJžD«�È4º2Øæ>QüԬ̉þÛZÓ€ÝsÀ3†²D ÷‰|V˜ˆ«xA{Fü,oB!ëÏu³5F”(d<­�1Æ­äm ³”ÿ<ïU÷ÒL G2’ Iä²FwˆŽû廼„"MÓ塦™Ú.¨f䇯Ê7� çàVìËÚNóõOÑ­{}›éD�ø°X5#VȤžrˆ«Æˆ–¶¢fm¨�¹©$'ÜÌÉ-Ú½ïÈö£ï Ø~t>åñž�ùSäÃ�J0�⭨Пõ1äôf¢jme Ý ¶°#¸Æ>ˆyòEÌOƒŽ=ºV\‘8|0óû�1~B=qÏ}n‚÷ZcLÈègý¨^¯wƒ&ê^ZgÂôAʃ¸ñ~¨‡ÁîÏà…ÿ÷‡±¬Çnœ€ÁAœ6o…ªô�ë[�˜G°›Ã jU&ìˬh×A\Ü$_|ëš±0gC»-ÝÇbNöÛS˰{ºˆ~ÒÓ|Œ×w‘;K­N_V’q�®=CºJ˜JE)â*l̬gí±~lûX¹’Öñ•@®t%·GWòÆèF�1cŒ©×1ãÔë˜zÝ&;ïù÷XO.5Év„ÃÔ̤/f0¹Ü hãä"ÄÙ ªeÓK,£Ÿq[o¯Fÿ´]ô/”“gÓ¼�Ñ& d¾ÿý°ß†‡`h÷º¾6}lSéÐJÜ·!xìØ ÜG–³‚MÄŒšžZ_™äÔûŽâvOWÄúË톞kì^6£ »þ]d×£cp)Oþ´c÷�UÆa¡Òû àcõaÿUí)èìÕ뜔Feì8Æý¢b£@È&ÁmD­þ&ÙýF)Ʋ[nwÕØ� –>5y,‡¶†!Iˆº ØH@ö0ØóŒæsl�ƒ^u0„Áhq<þ/?~S½“wUô㨬_#Ø·‘2„øž›ñîÇtû�÷1Á&;q’ÒÑ�ðïŽ3»{ÝhÂø€áÖý­ãÈM¾ª28d¸Ký }¼§r«ëcÜü·g3p[{0ü9Œc*TMÝäpðu¡&pÔ8‰ŠG¯ZNxƒ ×ÖšÎ/BÖv »».ÀÞ •Hl7 ¦Ï�a°̃uÜ¥•*÷Re ˜ð’¨àM¸{˜œÄP�p 7Þo‚~°†C>6s7á…×ì²—^se³ ÁñÝ Þ3°›«D¼®·î±Þ@­j�ˆ¨:Aœ'ýØä÷~S¼_tÝ//>Q¶&J5ù…ÿØNlþ™™,tÎð³´ßü‘ãï_³TPã‰zæ$"ÚIqjÊ'ОaÅ�”|4[èïËï퉆G€]¶ÇsžÝt‚žO‹ž1ùùÉ^8°�R­maü„ávQ¨És¥e$ž"È‹õðƒL­xšß,«Ÿ?„ÅDƒãË~žSí{E“–8@IStŸ£GŒEÕœ·ml$bh¬L¿"jUÏz3æ¡£9 S•—-_ ¥*Á"U“b‰Â+^K×òd“ì¡ÄÔöÂ:Q¼aš.¤°"‚{D÷}bÙž,™°>œ[œØÆ›�Q¾ r¾¼öf#:³Åµè±P ¡H¢„hô(�‡äUq&PìU`Ç"UT!Ðñô´÷þqË�ñãG!ö›LÆF»äzi{YdFrFQÝéçÌȧéYw5ETµ½'é]-q³XÔŒ´w¯Œ(“ò¡¦˜í*äX^t¨Œ•_+ºØG]Wbj{a»èþ‹/²e`h_‘ª¬¦èþÐtdsÑ‚?ê<.º?ó5.¨¡à*T®Õj¢4z–sç¿Pte2Êeþúð*ÔËsfÏ£K?ÞEòò�ôí¤ïè!½)F7[o+¡ èÅü™.à5ZEí+«�º9¢îùÕnFŠßÑ»ž=]œ½šâ7Þ²u9âg+"¨ ;¢Œþ*㨿uä“miØ„}LÄK,nv„ê'R®yK!ªv´J¸k;…]Û)äšæ[‰ª9QåÒç��Wqk9�úÉ,ðînqÞ¨Xé­ÏhȆ]Ö�½uÁ“h …ö”j5‚} ç–z½Ð—.IlE…*a®êºæ*Ê>TR„äq {¼÷ ÌÒêý,ß7Jov�¡‹t/eU‰UÍXƒ�Ó-QöFQTQ|óõtLí¢ðÕ}ôJ™’KqeùÚ]5Þ`la$Ê�LM”ªþÙ�»O¬ËŒÕâs˜áœ#âœl£(÷ž¤÷WÄ2ÍpÎ×Å“ªÕ̘öMÄ í+¶=f¡pûŠcôGµ¬è^e4d`ÔÓ��Dl˜* ZÌ;ÕµaŠBUt3µ½à“ ž–7w¡'´$N“ â‰ %‰Z¶Ø'ü`It�”�|¡çI£²k;…\�C9Ϙ°5/°`�Šž ñP •W‹´¦Œj%ÆF¢kEçØ z¨xkÙW� ï]K\ÍE�U—ÄÛØ“¢wzš®­Luç®ò=Çé¾w޵ç­e¤2¯|åSYù+×þÅ톑£˜¿h`?~&äÍ�;!ߘkÜí0_8Eá–„âÍóßsçÿÕï²õEÏâˆ:ÐhSbÕ>Ñ›ïè�b™²â¨+àÕÃë¦ù�ÓË�ñ›ÕÒ]~IXŠª­0o¡?Ú’…-KÝð¶åϦ*m’KU‰5@˜‡yî&_èíŸ/±¢�޳Ÿçw†ª,[ú£ª°Ÿç|T¬^'ŠH™ ï7õLÝ€!ܺ™Bû¾3×xq¡/ ÁÄ¢Ç)ÏI7¦ˆj¥Õb* 4A<2Dù¡Ï±,›Ç]ú&=‡DY[½÷VCA6O yÞêh>ï§èÖNŠ~“©Nø±¿ß+ÁvK‹À ïZXUeö‰âfQ¨Nß?Íy_™çÉ~¡Ws2Ò «ža…DYÄD÷rÑ}öaVK¬ÊŸ‹�øÐO ½$‘jñ_‹U-V…´^Và½÷òM×ÉuÒT‰V«DC1óΰÐÂ.xi_šj«˜ä»œ-�Lâ`^° 8-ÃLj˜q˜328y©�†0-’ö™½o‚�M½Šæ1aOçïë@i©@K1ÎoÑ$Š˜W�T8ur¯[ÉìO£[ËLm.øû­Úí¢°u³pù&ƒªv—èÞ%ºÛ“t«W ©‰˜‰¾]Vâäh/R'¿?³ŠMÚHQ¡ÄpF1MÅ4Õ�²kP#"ULâu‡HšpZ0ëfRLKrg\ÝÙ…®•¹v´“«U¼äCtÜsœîŠè¹Qôl yU�=Mâ�ÍóÑ3+sëík%8)zï݈R¾rS�:ÕÉq9­€Ó)œödŠ9¶øüp~LMÓaÿÕÎË�sØY¦^Ò)LE�“º�y…Ìfç¼BŠhf]b¾C f„9-‚Æ1bý %}‘ròy–%Ÿê@7õк~5zy�…§²îd//¼»‹¡C~³> Ûw¼«.Õ0WuÙEFu­ª­M´©´‹ÊBïÚS»®DECcå L–Q¿ã\öj5ÇTæ¬BfTB-ßÕ–:pþþ–üX¤Ž°•ý?õÿ·gfÆÎ Óœy�Lœ .ÁÎ4¼”ô’µñȵâ0 Î Mÿ¹-?ÆÆ¥ÐL júõ!ç;ð’¶à§!u˜D%œzHÜ Ò·_Å¡rnGDÄõ«ÛU�°~… OL;WÐ<&èT‰ îï`ý>¡$%½p�³@“€² '‰¨…±¹2(Þs{Ôa˜ÄwÓ8ˆškš‘Hp*7� ¦ýú¼¬j|eÖ´²_ÎÛØÈ P¤-PÀ´{“ C�E.ÒrÊ�cû_îØÐïj¦ªK Þ¨‰Dïªl¬¦ýø^òaª&ò/óï&‰7úÿ¹£s&Ý¥;HÆ_´1àÏVò�;ÞÈü�­$Ï /¥D¹!ZÌdz`:ˆZ³œŽ ôpMZ8…„XJ�¦9S4²Î�‰�åøÀ,»|‰NŒð™ý›?,áö.'x*Ø]{ˆŽü˜„4 XÓÅÝ ù 3^§ÆOb˜YrŸó¯váøWRz{ìù)�î”ù&J   ¸c�Á`0™€ª1¾YQA꟱3¾ÜŸ=òÔÿ6¡!ƒ5†ÈØì©9Bd|ç£u˜ÎÓ �zqgºqIˆK É‚ZÙì8f8ÙL9¹À�³Ç9:7É× ·S3w3Ê>¶^èv¿ìH�×¼&E;3lÞÀûJïåZß3ĵ„-7�ÒxéÚ�qä} RƒMC\ Xù'—LbP`¬‡C°ƒN€•‘gÁL ŒeŽkY“NÖ /;HpÁüH2ÚyMÃds!KÑ˾̨H0Xaªxø­~¾ƒþÿ¶Ûï4«ПB”ÜŽ6l¦…¯aw÷-×/oñ÷O¿8Ü}0 fž�éÆ@«iŠˆqp>åó¸Žoþ3ñÏ}œ|ýÈ�»n8¶ôÅÝCM^÷ßÖ°ïžgu5 ?>ŸùiÒõO)§Ï)…lHæPàˆTÀ6[œ%éêüŽ»éJçƒ#Á+‹èÌ n�M~õ)ç×~法 ÂT�!ÎÈôÎC˜Ì�¶ºHŸBmŽŸ©ø³½M6lp@ÀSþøù|«÷•e×ûê9®°Ë"(`q8/ J⪉œ‘ËP|V22Æ»¡‚VÀ7�cNbÑ”ðÈør«n«4vP³×<•K8ü{w±ðëèÉ`:"ãRDàbRÐ<µšRõû?xê½ëúv'|æ’ø¦7®0·.Ã} x…µLþ…)óßW_ÚIð[âì/Xºh"Z´\ÄŒmD÷6ýX.PWXàYAfž¿=“<ç•—ðUó-I9ÄÔœ’éî�!à$Žnd.™åÆÃ†Ê�¥>rY_Ê×p¼‘ÂÓ÷6^ô§ÿ& §a ‡Í8Ò<¹•ùVFÙ™A^Íèl„ùë—7Ñ;°)`"’¢%ŒFÏ Ä…Ž¹5¢ C(HCáÀ&‚i Hw~ #;K) Y9Säd«É?…�®[>Ìó~ümÜõþ×q�w-TÙ i7 Äcj5l¥Bù˜å�£y_ê"Ø!Ä5—š7ŒŒwo€ôº^›røU­Ol*„m×t"ì¾½÷Õ Ì¼«Eg¬À‚ËvµÜ koÉŠŒœ5D�2 HvÁÂB‹ÎÞ¿ à 4Ýæ­¥éd±À…Ùð™‡Ô »ÇSAeƒérèbAd %ÒHÌ:ƒ±Ð8d2¯6ö†M¡¢ÔÑ*ßý'Ì>üÎ3_,ó\t×bý=O6UD°]jGé¼aš.¶¼eM‰¿ýÃ{?ÕÍ-gºø\ºœ£>æ·òqi˜*n—d1o#bV§Ô�Ž•Ð/³î蹿"–m«¾&VŸË••·rpl‰”K(“×ñy×_.kíe¡kñ˜ˆ.ÛC‰}ûzYyóŽ�ã©Á¥í=̧ҀTQ›©&Q�TÝÌ*âoçY¯Þ©.¤ø‘‰Bå%J›'�ÛÉʉ¾�E¨ÚÉ�<ƒÒo(òÖîà–Æ ¾‘ö°O�̩Ȍ ¤©Å‰0Mý5%Žó?ûvÆTΓÖ[�O˜fóÞf¼Ï€oâ<ü0f¿ÿ‘óqÅPîKxÖ̉ Õ÷%C¬)´¡Í†K�¹9‹A¢ßëÓ|kLB1qÐyr}ÿîKÃú¥MÆ ŽÜÉߦÀ3¾‚ÕŸÛBç_ÅÛžÊ+¯åi‹M nyÊ�4ÄÌ`È`0 ™5ÇŽy ½zbÁÚ3¤½�L•ð®¼owëîôë·c ТvÕku&ùø�=Ì[>�`J¡BØ$I18RZA�§}CÏúåA^±¦1s’`|Šh¸Zm) Í xÐ�iÖ¥æW»š„†|ü“ŸO¯¸þâ'vˆ…À(ÖXï %9¸ ±.ÈrÙx«ÂFù÷¢’=ÏEîývǘ›¨“ypý޵iͦÖŽxÖ F´LúR¸Áúx¯)K¨Lƒ¬ç=bpp±ÿ¡q?]¿¶’�‘·�šç©·¿œku?wE�}J$�ÑNX&%° ceR �bE³+·|�éå—‡`-4F¡Ã ‹ÝÔõF†¢ËÁU«;r ½©ù/v‚ò’Ã~Ôš`0…Š]ÁzúRJgZ,{áxD$‘ÊÏOgp9Þ 6‹�-†ÔÈx¦¥‘’øûxÊ´ß!††©ø Ž †q|�ÉÀ¶µÅAL@_Ilš“CMÎýW½ù=ëÙú‹OæÕ/èb}-¢'�cVœuF2‰,Æš6Ta5¢f,5cÎMW×wˆŽ»EW–Š�QÍ«†j´]Ú€ZP�EôÍV~êÝ~GK2KÚȲçN0ï`ÞaZ~g¶©$C¢"3¢çkoåȽŸ=Ÿ˲²\± LÈK$¾–XÖ±WµWµô+ºé=¿ÿ Vðûo_Å9¿ù§1ÿÔ²õYz£†A͹2{Óº’ÚD¯ß®�¢ð¸è>,V)SÍPûPìë㵩c-ºß0“Ɯ氈SGès$íâ3âµÿãbäÕ>=öø@)—^šqD‘!ÝrµUIÜÌ‘Ž1QÞåË1!•%VÝy5Á¶S˜} ÑŒÁÉÒJ-.1œÁZ\ W´Ki@åј€¬iª¾rPºaš®kE§/gQ൜pg£Ìtf©”=ÏÄÈ-VPRgð_RÁ‰”Ð}î¸èÎK•�¨iK¦"‚~ ì£ø+·±lBÄP‰]*p£zèþ­W>7o9{Ö{e-afqS„NJ1s¤)v^Zê$Q'i“Î…ÿNUÝä˜��Ñ�~E9l9÷¤x™ªrîyÍÀUYæÞfȼÒÔ. µôp@%^û%]H–ÔW‡˜mg»áXj9–F$Šq>ûm%Câ«(á-óܨî}UÇu¢tî!çe¿¥tä`1Ñ�¢-(ZD0^WB•¸º�Þ_+yÝŸCù÷Äœj„ÌŠ0M ­¬ú‘8.øç·#Å'Eïqy5“ä2HƦL€¥K¶-T,ýýÀ˜!ÕÀÖ¨°ìùZh Wž´û”iŽÅf¶l7ñ½‰‹v‡V_¢ô ÁJ°÷�ö·Í¹ÿg¨j²7}éð°  x‰åÆISX†Ùð4š¼ý÷gøø;þG‘�7YŒƒÎÆ2IÔ4’<=µ¨d©éš1žéÄ3ÅÜųÀ ¨B…ÏŸð²S瀣8å–ŠåÜŸ¼îg..¦"�° ZcÎÆ¼èC|àpåK‹o„6Aem3sƒìAˆ÷<ëã; ÀÁµþÜaˆÞ\ÛºÐæ|H/4 èX+~òSôl´Zs8aºS¡i�±ŽfP pD‚µ-Tß#ÆÒöØ*Æ\Õ‡V�žÚ"Mò‡´w3Ü4"Ù0ép*ÓmcFÞl›ô{5vµÝ2æ¡RãÓV5ÐC7R\µŽVë§™­|€NÖ"6ãXŽã£®ý¡3§;®� %H#HMŠœ% HlàŠ4�sÎ2Ñüà;áÙTH†Ùmk»40Žê5c®Ü Y{†E–`¸uã¤j¸ì8—&Î'ìYFÂÚ:\ýSßN�ÏvgÞ‹Ëî×âÉ»_—ú£c��é—Lê2`Å#Ækè;F°êÛåmèrÝå 9ÄÞûTx`á<$üåÏ>ÄoÿìO7Mçm« ±ö®ðBäÏêÞ{¤â¡â¤èõÐ:ß„à;¹*A•Ñp ý‘ÖPV?QÞðÑ�¢"ÿ “£Š™Ë,y¢œQ3gÙ„…Ô[ö¦�op*#Qû“ Öi€0³æ�m°‚(ç»YL xh åÑ*á¶m,ŸÚåkÛ¯}]>.+£Ñ"Ï~ö«áë IçKYý:àι�³/Cj[¼,v EÕ®=@i‹({¼°�£'P|H”·<ÀÊUè9lF¨…9#¢³¢0—ÕQϦw�ñuz¯‚ª�vRô˜ã±è¤è½[teØõ¢Ç±çL²2+ï7ÝD�¶zÐìúzvͰŠè�ßÄ|äX€sE$Ììst|Éñtýl^GΠªíÆ£#GèнtLLÐéE3h0*´“¢¶Rà>-£ü™°VÈ‚ pÎãšYM=u.‹�ý÷†Ôœ…äs¹ü󢷴ؕťA?kÊ[¶dÇÅf— E¨ÖÉÊßüÛNu WFÙü9%Š' ÞS,H––œó˜…9u¢tiÕ‰B¤¨Äcì •äµ÷(.¹åŸšòM0|9FêàÔ©e%œ<"«å=�6„jÁ?û`ÆÏr-E$ê ©ˆ�̓:Ø©âÒç‘�Δ«Ê>tŠeêÎjŒèº=”®ÛFiË¢©x3ê¸n˯�H=¬|ý_õ0“Æ8M&utßÿ?¨)­ªF�ƒ»r/ÒZ°ìîju‰E¨ÑÇû4Ò?¿HjÆq+ˆJž¥#mr<ô»[°$# ‹1M~ØÅÍ4�élhè2up·ÿAþv%æDO®÷?«dnàC`ª;ÔèC¿t ï»ßK}à“š]C‹÷ ˆ¯~õï1}»E#˜7iì/,% #·3°Ó,(1Tuðá‘änHèCÝM‚­q[X€ðÑóV(ŠªÖ3iøŸ•.ž÷W�RƳñ H…bGXhÊ šMŸéÁ‘€…âÜ<ÉZ;S¹†¯ï^à–ý!\Êñ‹ »7µ=ŒÉö$÷³Š~`Öc;6xšÓÃákBzl`1òD~‹^Kn¶ÿ­ü’% À˜�`X·@u†L…­gêÏݪ2ƒ¸'M“R&˜¬ri5}Úe$Û~‚ddÝŒWBëêËhty7¢Åo¼ïzCç7!máð¥ëDŽ÷áÀ²[aÚ>BUd�ŠÆ]+:«¢ó^yÌn;c<ê»Î²MusÁÃ7û¸;uDÇEt:‹áœr$¦é|üàRou Ñyç0[Uð°Ê±(ɇ�8«Ê[ã�ûè�Êâ«ß©ÒÛ—7Ž\-�Yçî®}¨(±ü½â\Þ»÷J{ëy¯cÆÂ,ëžñÝõzHl�T­Äè@j�Pxt€ÎJÕ*!?§�¸yCâˆ)Ѭ�#9“¡ñ,?Ëú=èCÏ¿ÇÇF(>½�åy]Qµd]H†=¾slõÍtìò–6•Î)(xßPõ—ËÓ¬¡óô?Zö»ˆW¢•FÜ×díé+ÝÍ7&¢ýçŸéH䵯kÙy].K\FêäÓßì!ýçÔèÍ~hi‰ð¬°sí¸|1Fwi;FG»óì~†Jóý6ÚÐÇêUFà oØJab‚Î]S>ø/œŸX†Ï_ÄOB×Ã~×ÍBp2 8å< ²ácа•ZÂjÖÐÌ)àŒëåSÇÎCOâ u ÅÛE÷ö{èF2}(Τ¤óÇbÛóPöó LE‡¶”9roÒrï‚9yljà¤#8µˆ ÌÏlÞG¤*ãóÑ98Ò�úË ÙC`3ˆqÞø•ÍûynÀj•p #Ѧ ·^Eù°X%±| Šö¡bm‚¸¿Ÿ2SÛ H]�Ÿ�øëYïM;Ñù•áêdî¡ûþ„ÌK‰ídÎÄY7âz40 ÷¡ù› &Ùm&©ßJIÊ)-Ø’*Éös_7Wò]XBò®TgÀHFÞ08OxQß-.uôïÎ^»Æw†½õBn=è²u¤ÇOÀÝ +~•ùÉá»UÙiCÃìç…­u4·L7 É«+ŸŠœó¶H @ü0¦éŠe™ç�ó²<ÇP©0 ¬ÚMcm} U­)ðOïx¾wuM‹ñèÀh±¾à˜]¶œÃwks 0H¸îë˜ß÷~ÊàY\jÈÔ|Öv/º:–½¯¶+®§u%´†6Î}•J²…[�0!'Âpnå g »Ï¢Ä`LŠlJ�t›9psàæA9�Üå`}.˃w9úr‹|YŸ5pŸyX|> Ðh1Ï1Ÿ™j#“ᄯ‚š,ýîs³¾º‚1À`¥ªÁJUý‹‰Æû—3l†´ÉÕͨ›ÚN롘օ(üú³˜æ ö’1T縂4% ,Ʀ&Lp)Ä1„�Á9œuàea.òÀžÎ9?Ã%Þ¨þéAZ·?Ÿï¹=žÔnwa±�”³ÓÖkU“Y:2¬j°6µa±æj±ú’p é#Í5f±Ú`˜ÔäyëÍ|û-ÁËùôM.U}óÖõè^l­è÷©òêd5|pœ°Z•;�‹ôöÚ…ÉUï$I =Œd<€•�•t|œy6œk9}º“™øÎ€g~¡í¬$Òî,÷2;Cýª3±ä4z˨GÔöò8ÒwåŒf¢ñ™š*Ðù•a�aþNo;ûžÇx(ÏJú½üÏÃP›i$W™Ý:î-¢P¨)º5EwÖˆPF;9з\Ubm¥0²ÅãÓ+Tã¼ójûvº%–?k ³®Œ„ùZ“'ëç�ï<ËcÄJÖ¹•[¤U2"¾Bt°í@‰pæ–ÛJ’aÁ½…ÉñÆ1©½}q‡FÊÕ}ôVEgY¨äýòżE0S¢{ŸèýÒYÎ�Ý»¦|½Þo 2�$üP_ônüãU4�!M ¿<Ï ôÊÇÌ3t¨ ·ÿcDêqé&Ç[·ä±ß™ÅðõZ(ÃkŸrEôÙÇüùY�ÛT2Ü|"ÎÇ»0ßœʬ§Ï äײˆ÷NI+BßDê–°ÚIqì*ÊÚGqI_1ï]Ïsíï3Vß¼¤FųùÊÃwör<êÿ‹Ùxy|AáC nTSÛ aþslÁÀ(aÿ’Æ#T+!uúnAÅo+®½ÚI±†‚âü³³zS…•`b‚N�Á�RßxuŒSHKÄC¹·cì='DÏ*ç¼ c"ú/@ìè÷¼Är2MkoöÜ>Мx’eíEŽ'cyO%ñûœ¡ÂPŠŒ»ÌÖ7n™ß ɲßâxDñ>G+ëh¦À‡MÅó™q;l…¾ô.vØÁA¹JEéµ5£ZÍØ‰I¸Z|ý+!Éž§·ËÐí„r†lòU,PL ¾ ž×bÍ7ƒ]‡ÂCˆ�É$4?ÕŠL}0ؼ™x4»Á]ÜAs Ø»깪¨ðµöy­»«† µÐl;ÓëÈ%¬%¢@gãìãýôëQ‘±µzÕx­€sö«]­I¬Óò°ê6^#OäN‘ Eº‚×Y¾ÉÈò®ÿ)¤ÆT*ÕÔsöf/ªÊ†qßçÈtå²ç˜Ï½u9êGìÝé€tÿø¾àaˆJ�¾ìÁ“˜Ê ¦üm0‡ÏÁÝÎ*ÔT>Jx÷§ék�p€ÒF¢ËØæY9D´s”âwP?I1'{>r(fÖïÔ92ÊžuØZþ>mK$¢G>®sò¬úÐÊbméÌYqxŠUû®¦¸%ãÛ®2^�ŠÂ×8‘2"ßZ¹”M'gtG:W [înÜݤ¬?yÂ[ô~ßÏNm¢“øÃ.øñ™ÿ �…óÊNnÑ[‚Y‡™q˜Ó‚câBý$kk%ïŽEw\ï9ö<�B-Ϋd&íVäˆEw™E׋>UðØ�Å–kkUë)À2ÏBžßï굘ÑÑ"ºµ,*ñD-‹å+ 6d]Tí‰1ÏÍ?%º èë–oŠŽ‡~ß³ „aæé¶Û‡øÝ|¯Zìå®`ˆ˜˜ çä[÷ÇÏ\z¾ãÎß¶<üóu`Å�ýM^¾%¥Žcï•Í!‘\x%M^ƒé!Ü”ÝÜ]ŽrÃØ€Fú³ŒÇ{ ;¸&¹Ž/4+}¸M?GGÇ98cŒ­OšØc¨Êp;†’s) YÛÒ’LknI|5öº¼)37ý%ÿkî^t(äš±buDs;¶Lº."=7&Y÷fܤ“™‹ð0·«žµ$Áð#ÂÁÁAsÏ�«T”b¯ùMºXÕH |^ÌÆD¥A–ðx"ãËÜ@Ï áÖ?´¨‘–yLœÕ°ÛÝZÛÀaÌÝöT^FÌîê¥Úß‘YLÔ© S«W�À0X•ñååìRìÈ’cjy£Ñw«Ÿ/þ¼¢á›W…«oNR�äI¸ŠájÝõíÊÖç�ؽÒÉjÝÔ™0§ûi|iŽàîýXƒ»/&v¸ãÝ|°¨0T˜H_Îmm‹þ_Àuß gÐ×ab(–¡|ìÉû æaÆŸòÌˆç• «ËwQ³2æ6™¨:a¢í¢ëc·š•÷§ëš˜ô·A _µ0·­|¿cô@Èì¦Ðú{*s$‘0ÏÙU†åõ \¥σÔjX††á™X–ËDßýÁ.~mÒb�4(¸7ôÄwÞÿ™è¼‘KÖ쨂¶;vˆáeÉä“k³lp€㶸Êîôº2XµÏtƔǨCÈ#ãc‚ë¸>¯§Ôj$¼lö$Ç6ó·bê!Ç¢âŒm}ïñý¯}hb0@úV;ly>h/æP¸¥ HÆ÷ƶ$›øæ%×®hЊ'ן»Ž½Úá@Ú²‘@urÜl¦nþ¢J…Â"$xØÔëæ1 Xô(¸wv<ì\³ø™ßyüÃt}ù™÷NÇÇ.�úÀ¬üÉuØaÆO°Z¿Œ[ƼÜÙ×…¾>´ì›õÎã�nÿ'^sƒföÁ{3§vW¨î�vlÙm*ªÛ['^ž€éÓù¸.t�ÿŒ«°»½�‡Ùæ³re&ã:*¢1³.!:›"{9¸ ›Ìí =}DÏ;¿ürΟ£õËç¡k®é‡‰ƒ…Þ7Q0<ù_"Bg¡—Ý}vç(I½Ž)>{ú0®4Ctû^" 3¸‘tpG}°ö œÀÊ7Ñk1ýš7på1#`,*¤¤Ö†w×Z/7Tõ®ªÑõ9¨°ƒÑxœKÍ­\µ°}ñ4˜3 Ò5�ö�go„15M�J–O�ÛÆ\ªnKùûé`ÍRôü=¡° ‹bõOècxøNEÊU{ƒŒkM¯@›~.?ònº\)µïgSr˜ƒÏ<Ü2C°û(î5 u�u Áð�ÇŽ=æÃ÷—û+{ôrú7^3Ðþî‚U4¾~7sÍÛÙËöRC¬yŽ·ADÿÁ�£DŒï0•ŠÒe'i1N4:�TGÉÝçp§ãgB@}ÎmÙQq¼‰ðp_»âðø[ô ªá�`sÅ�9˜›ƒ9  :Ë�Ío\â8RšÃhUÕ˜÷ìÚŒ€ÜKò‚:k5ÿ… Ô|MugøîÍãª] Sºt6}úÛ«Žóêˆb‰ ¢º*Ô”Yw³{è–�1’Útµ|ÏÏ>Çñ�‹„w¾‘v?ÁÅ3è#ü©­”¹p/4×F�b�Ç^Ù¼”•ýqÖ®Ðÿ.H Š0OÏ .cm †0mRò®Ìsy&y5 CÃPyð‡>ÿ+ «­´Ó>vãËmÜéònZŸº‚èÀ– ]ý)ϰ�\Ï×.mÀXóR“¾¿ÿš®0]ýК¹�¦•m²³áÝ-ýÒ Æ¿ã•2±&6Ú‡�Ô‹ü*É¿˜íiÝh¾n4ÿ8.tß×Üaÿɰ‰ìOcAÇ2‘|ù'Rl#1šÿ×C˜7^I³öB/ˆ)Ø<—«ÍÅÏ`·~d¼Ää�}½\ø¥u ð¾:…¡±Ý¦6A5;@Åà»� `¿ú)|-¸²Q|a: x¾ƒ5ûÚ–›õ6îY²¹‰Q+F%Bµp¤HóÜñëÇxÛ?qåΟarcxr5ºï.Ì©˜)-´°¤_Ø�p%%¤êÕ µº±_üÅ{ið) \üÚO†üö[-|åñ{~?°Ã†ûrSݰž>ͤçÛãuÈ,‰‰eÀ˜T¤`—ÏîÞ°7Àwcš Þk‡ÚÞŽ9ÛJUð’ÐÜÿ^{í£¬úð0€Ïþ±ÜÙ“Øm—Ñú󧻚¤�b!èaukpPb÷dðsýXó­&„ô“nªÊ�÷ƒawJM�‰€¿½�&;°«Wcv�`3[—Èmý§gÝw{2GŸuÌEwy*é~ÝÌ‘M�Š"kÏ>ÓðÙFȾf‰ä³ðÔÌB†�Ñpzš.ß­Si«‚´OϪ™%~Hµ•jT#¨Vˆ3FN˘Ê,zwçûÝ‘#VžmO -YÔj#¤Âc"8åO;Ó�È×Ûàœc?Ç´©L­ô£²ï…®Ú]áQˆ#zÅÝtÕÚ*®�ìYÎû©}6ÙóðÿWϺ“»>‹ÿ$¥w­T¨Æ\¥rȮϕQâçЬ#lÈrBgä™xä|ïúÉö€ JCÏ×O¢Œ@1ÃDlEmÚñœ&›¼»nl$BýÑcͺCÃù>þ,ë´Áfu³]…|~Ýz•ÇÒ8@i»(Œòÿßv%6l- ��¾‰öÿ<æÛ"8Öèá3ÿM(ò Ì£aMþµ{PÒÈbßÀÀ(a®ê“¯‹ŒRÚ÷ŽdÝr�»ëþÌÏa†pûwø0bÒ7×¶.¼¡N<0‰ãPÇË 1Š@õÝÒˆaØh÷€[¹Ò¿n�úwl­f·�PZ̰[¡šuêùWÞ2AÄzìP w9w9¨œ¶tþÒ?%@Šm@ÃÐ$U`hYÎ;“†>#¿´cÏ�|Xop´XÒ 8ùé�ì¸ùcüXå2Ö×ìËÙÝ<ÍÃ�žµ6<ý}@Ç^ˆ«€ÝÀTlú&Û1–1�›̓ü=ì~¼ß÷<$¥øf:cLÆN³ø5¨ ÖèàÕ–¢”cç,�Z©ÂÐàZrA˜àZ±Öƒ†%1¨e°gcL(Ѱbà ÷~êØ+ycÆa8lÞC=™_’Àöè{„ÆýçøäfÓqÕ;IúÀþ�]Äç‚>ÖÀõ�»n í]Ñb|ÔÐ_è�øè¦³Az*>‡�³¯aP¬‰a¯÷c\ lïñ®Ìå`ëdÄ@B“ý˜ýœ‚`vöq·èªl[KI¢0=M×õ{9ç#bR±ÅEô@ç0GQòÝÚ&¾÷VbŒè�(W”©bä$þcDG=*í\yŽìÞ¼.½ôï²T[ðhFv®+úúý?.ð-PbHÓ%—Àl­åYi3 t�äl©¾§::+‚‡vÚÅœš/ñ°V£/<““?û´ŒŠJž²Zåu£Ÿ/º@ÕLß;ë×_BÍ 9N¿jÿ«[ô%Výb ù÷¢]ÝKáÔúßšµÌûþˆÂ Gð°#œ,(@΢†÷¨šó—:ñð\_ÿìó³¾x {5ûŠ9ítÞ½Öžß`”p`”ð±×Ñ[²´þM‹®L¡çÝŸðóohÅ]S¶0m㺒g»Uçr¦ÖFŒ;:œ£(õpçB…\0ïͨf ¯9kÐ>Ñ;-º–êÜ-éÚk{0ÿ ]ßs×¼î`µÁ§ˆO­Ä<é©,ÜõUBê“n2üÄ‹RÒ‹¤(L!°Ãq7 AÝÐOp’:£†!,ÕŒ¥³„Yµ@¥ H¿ n°’+“ûš*>~n…hv‘/… Â^m¡’®¬ƒu �HL+R Ò€ ,‹Íîn‰3ái^Ä�wŠ0 .t´hpäùìÿ~+ù7üóM—Á» ãïŒöG+£S 7n¦ÁFÂñ©÷X¾KXC±åõ_üÈÈ^É ØßÇÁך4x­c¡QtV©ç|ˆ:S\ˆ¡�ÆÑˆeC,Q,RKŠ g‹†‹>¶?«@LB¸Ÿu }“Ñ`¥*CÕÕë>n¯3h(aú'1»ªmnÀê1‰v隸ášß†Èü Åë7 ‘±kX˶&/¿µõfƒu×&”f˜5˜…T>]“³†|qyæÏÁ¬ªS¡Æ:HW‚rä]½n‚¬µ25FU#ªæ?Á¢ûžÙï´èžIfd‹ßa«£tnÔyNu½lP÷94¿ÞîG¶'›tº/<ÊÃbÔÀLOÓuäˆWÍz¼Cªj÷Öç’9çUÙ—W—at¨˜c�«UB߯\ ¦D÷7Ä Öèé†÷|3ä_ç ³‰¿×fÆ×5ãN;‚“‹L,v^ØYåž 4=[K|Òÿ­IS�…9¡"É|LªåèópúJvª—ûZ†&:¹ûþ.–2îPµ™FYòrF?5Òÿ$‹¾ÔšxJf�:z÷¾^¶œYÙÁÌ·#f2œ»DᔈÏh‘/}NpV5¡)LÓ\±ã¡‹ÑyŸ¼Ÿ.ÝKG/€‘Í�,«U‚GKWe9óöè¶QÒÎL´D„\²ºUíNöÇP™;ÔÁJýØrÒÓÐÅQœV™7öáÞŽœÃ>¥ôž£¡äD”‰m,z{´‘–"Ιu÷ýŠ‚Û  }ãÞÍôŸ<Û¸}®´—ߘå+-…¤`[!Æ„çwvÏJ•”ªLšâZ-ܹ :£†ñ†«* >Þ'¨ÉPU»S-ûºdWb˜6îr°«Þ‡ÂÍóNÁFõC§OÐbËá‡T|Mݰ(c¢Ã„)ɼ}D[×¥³2.öÙyÉ’5Æ6ŒMçŒUb Å,“ÁC,ó4œp×'¸ömç5Á³ùØE^xqÂ�ÉÒ»«Uwú Á`¾æô4?ôót(‹Ë3J‰$Ÿ>ÿ�uMnýøï]eSð w’ ¥Ù„ 5"±‘,±Œ°–°eHËkþâ� o<Þ] àLµ:ઙŸ5½K?¢r­©dœz‹—4$ñ÷èk¯®†zÁ¦ÝÀ½G¢jOòeÓ ³õÞ„F78GC«A“ñqhU¸ÑtîÅ‘O¸áw˜Ÿ'€šñ|€ƒþ+tP¥úèGðøZô�\˜nÅ>ó;ê�ÐÊœÕ2Ô"tÞ ÚiGw뤀Ñ�b®a5FÖ×íwº¦éÚ./¦(/2XÜ'Š÷›ßá«‹Œ©¾7»oÙB¤ �Ï„+Шo¤¢€ë÷žñÍ/ù,¯óýÚ…f ;·„}Åïî'\Àé4W�1¤©Íº›(©å™cOˆr"¢YÓŽ)@ILª˜³:wWºˆõ'zÈcÚG?ŸŒƒî¿ºEçQ1ù’ï-P>—ÖKJ|;Åœ4qšx {"JÎGš&M-I2+h*µ¿ Îùô] *{«çY\Àk†ïšaÕM'èaBžŒj5â¥rß?ì¬û® Ž|ˆŽ-ŒDUa©ú ûŠ·0»æ)¨s,-qÒó¿r”œžËg_*TP?QÎoç½�þ¨½6‘É=S‰®{EG¦h.Î Ÿ£xÜ-úî*ŽÚ&Sý ÉëÀðþÚoÃo*QÒ,Í€´e3>ø†ð½È²1 ÛÏØÄÓËìÜÉÏlã�F�íXòý ‹½gÍȈZ“õZÐÇ&Øý>x’€ÚÁ˜›Ÿ:Ûêìx­u眲 g 4Ï„D�¶¨9>Êæê²£œwl! IH¡¤ŒÉØ`cÅfê%Qˆhrü¥3üÞ—ùÖ›~rá0à™IPÕç#2þ¹ÿêG—g_ókîÎ9Ã?~¢E+‰ÕåÙ‰4P,°ÎΧ�¶„µÆÙFqâ €ž\sùu<Mz×FõœåVU³Žu:Õ‰Ü2Búy-ùÏõ‚J¿Fú•S$ÏÐ5¶Š„v†4có¾ù¤ÿÃË?r–û+)©M°:ƒàÍ/pÐ2. –±ù Þ¥ USGÆ`pǼgzÊ3Ü¥� ‹ñsãcѳ#9¯d�]>í9É™w5X¾ð§ é<*ZÎïZIU+¹(¹’ît¡;@Q)vÎó†sº™[À™´íѽtxéa_Wβæy�9Ü—±­ä 'Êu·}ŒÔ•ëLgÿQYJÿž’Øs€R.Ûûv±‚û_ØÅÅ÷\R›îàp«Ãk©ùx2ïU÷1yêuÕÎ$§‘("Q€rJNŸ©·'vz1coÚL.)Èóuã„™ßG·®äˆ:˜PçfQ˜¨‹±Œ®j/»ŒRÎçî»GCßEG|2ã̵Օ‰fzs6·è…¥}÷�œ•eÁÙŒÍ?㬖m\§TFwïʼnZ¦„ú*/y�(ýÁÎ×C,Ë*!l.0¦ˆûÕEU+±�·4NP<)l#ÍÆÀùÚ™K1J09oyÓAS1­$ä_]�O¿ëi?ˆªÃcµèžõæ¬ Yhbna?s–§œ]Í'Nö2¢Þ½¯—#ê ªn^¡Õõâú›ˆ¦b”P8á(u©<oÓœÑ:¾<�³ÄH"¯£/Å€,·ü^gøÚž¾ïcEf$+B01NgbãƒüÙ‰ç C¶QÄ-üé éFc“'•]Ú…E ‰I°Vx½«Ô9çHÅ,®t�”~ÀT©ÈØ:8c0î8¤y\­†­"Ìû‚SCF†îñÐílpvÁ9Á]¸a-ÁJà0„�_¤Åó?ßàOŸ¿ï‚ŸyÖ/œ¤qk×bM#5X §†f ¬0κ”f`ˆRÛF»="y® Þ)# 8�³[”ÉÊ4-öÐZf>ûwüØ?¿�oè�wAÊ.BèOa“`€={4_7od(šÔ‡£J¥šž…Ð�sÇÐtµ"€ý�x@ßÏ!¥˜6Ÿ»œñX„M‡‚ävt°BÄàÀµÝ ~ý…w¨¿9ö´ñ³'–¡Ó{±ox7E´k�g-\À±?®pºó7�{ù“œ±Ä=Ð2 L£`T ýÍ ¤!ÅHŒ°%.ü†Xó‹�'}næJÐÐ÷+?„ÃÏ‘ãDTT1Y0ów¼Ž-ÿ§Hsr†Î‡,ï°],~ŒÙ'=wÑêÛ�§±`š$ZÒ[Ÿ½©u°”ñYç¶=× ¢¡ÿú±Zôð˜|6¹•YôFfѳݯÐHg„I�E §Ó2Gµ‚DeæÕA"Ë‚+�ú¬j)uJ±ÇR8Õ¥žŸn&-¢»« øŒmÖÇ�Ç~™Å.,±Ð~ç[Òœõ!{ÄPv¿9¢(ïÿÎ�©-2›†Œ)zË$kÞ,ÎEêä)Íç|hª‡o("ue”ÂéÄ0“œ"”x/¦åYCMÓ-ÖÚó<Æ£z«ƒS"8á­úoÉ’¦eœ Ìj5Ú» �ÛîÅÕc‡xÒýÓœ·E#(ªV éW´O+Ûù2ã òõñ ŸvħD¨{rB¿ŠF2a¿Z� ¨ |TóD^¢R^ÈÅò¿[$cÌ^–è„Z.mR•]¾�nOO4ZäêåÚ£�]̽pÉݽÌ;_¦J±špzø6|Ù*§¤ ÎsÆåTDíäepÆ7ÅØùÌ�u©%m(�H]L#)1/ºÞqˆËo}Ñ”èù+¯¿Ùƒgª „Bvû. »¦(,& sš® åå%ý®»s²4´’¹Åbâ0i Ž*æÔ\�ÓIóŠ™u˜9_"C)Ñ‚óðßìù§Ìå÷÷Y<™ 4ÌgPâÔÓBE _áIÚÈ+´šõøRl-¿Þb•ѰÊ"õØãîºG³"Ò|ÈIyб}st=—ë�œÃù_\Áe–Ó£Ë#š[KèC!î,¸†åˆ£p¼MA ã2‰¥Ôùð‹Av •¶]B ú¨f§ÿ ×]‘?� ÿ)rYL´Šl�@xÐqn….t/ÖÚVŸ–·Þ<ѹû¸ì5 ÿ‡§Ñý™áWÏ„$&¡­nh•}³HíW5¦Ÿè,„×d„ø•ŠÒåÐ\Íœt`?ć1å%,"†9Å}´)vêuÌ$&¾¯�èáµÄ¾Œ5DݨQ7š¿_ƒåÙ�¦ë¶¯™®ŸÝoºÿ×+³{Ì¶à ›:u¹‰ß÷ºs¢™�¥ñ“ ®8Å'~]üéјÑYÓüvT¦ ÓèÄ4;1I,ëGÝ´ðž©�q~)yw>íôÌ) =1"órL‡)˜¶éH‚yl‹³¿³’Ï\µã™F˯ù°N>íJ Ó˜Î>Fµ»jì·>F¸ù4®ž©#N‚-eO8y[ð=¬�VL‘oèµ.]´` ÄôhôüÙËfÏçK›OÿÈl¼ï ÊŸ½&“¨UHhnYJ«lPK†TÁ‚ÅÉ.tRXèSLdlK¤:Eòг9Ì�³ƒ³LÝ™`.hŽ:m¤c¢fÜKª›øÕ]&ØòYV? j�óaZ ¦5[´ôÐá: ¹;aíªÙçß|î»>?åº7�æ•Õ=¯Qü�Wɼ.yëÛ/æÜ·½®ÌžÃ]�ý Ñ×$ûmd#ëÁmPäb Fë+�LÀIƒ‘§­þþ�ÀB„‹WÜl�‚C6d s!-Œm’Ó“w“| Ü�V'&<õÎÏ3ÇMÏ}£m½øÀ˜ˆX´×iKxœž?‰¨¯wy[“K]rXá°KŠ gÃvÈâ3¶¹~Yä›w9 Òq�dófZ?ýLZŸØIã�Ôì�sAó(Ø9KðÊg’2s»˜$áºuÿ§‡_ë/pù_ÇœwdžyåŸì}Š$cCI—ìvñkÎ�濉Åt¦žœ>)8 -hE îá§wrçoóâÛÃ/õ±p/“ T¸ùå,@[µõ»OÒ%Ziÿæã¥i.‹ÓÃŒù%±ÐÀ’åcÃwóËC_äï~뾶⋜÷’7ЧZ”e”(hb"'ŒIi � 3vx«4€™˜ rV¤ØR‚ùÈŸòöÝOáæ84°Ÿðào�ö•ê7<›àê§pê+,‘“}œCÑB0N8 AÈãé°§ö³Àúše¤:¿ƒ+ÌIˆøÍ?8Åß½îïžÎ•/.ð¬�ƒŒqy²!mÏ…Bô�C¾AW*jcBÖW°è?²Ø¿‡ëÎ¥ ‰"»”¹î9.QÎÒékÞ  ^é1GTeîi™yQÜû'l;PbQ+ºóøÿθÍEŒ^ÑÅ©g.‹Ù_[É7ÕV á¨(ësTªV uœnµk´>Kž%±Œä5åt’ÞZ�€ [ TŒ‰è³Ó¬Ù+Α}ñ'ï§kŸ(RU ²¹2©�‡ÞæUW–+ÕO™L‘u*ÒïÑXïøˆW Ý. Œ�D¬üÖyÝüù{;Ø>×ÉD£ÈŒºP¦VêäëÄ-œM±³>üépyW7jµ¾Ã]Äeõ÷.ÿÿ2ö%}4ŸÍ‘ÕCûÚJ$¡ÕŸõ-·1¢ÝŸ�#ÕÞ©®€;ïXtÝ[YÖ}A–œ¿¾ÕVkñòÆ {•Ñç•é²o«á“5º®ÄÓ/þ�(æäfºÇ…Õ¼WKUR@)vV%rý÷D>¼óúëœ ™þúë9µl`”Pû(J�¡C(ºŒm%4²SÅÇÛuÏUZ ¤ê¤åb>²0ÀÑNÆF¢}>8é=)z—bÑÛŸMÕò¬Ñ×Qøóù¤^ä[ÂÌé<ô"j•`_Žì̪Aùóó�yßÿ}þ³îòXß<ÓÎ2§>b&gÖ:#–­Uµj,¦ê&ïûU’§oÀܰËá±=»,«oL)ÏZ‚Ô¿m©I oç=®ZUÊAÒcÇÚØiU2—Ý''²L|/vprcIoO¢:îÍÎàÅ+i…sæ=ª“ç^Lºí#Ä Ñ“ Þÿ‚jËÐnkú‡aÌu/¥ñõ£D@ŒÐÚÉþÆÍ—¡Å¸'œ\¾‰Fø:—L^óŒo}2oüÃ'ñºyÚÿ±ÎrÖ8ܼ‘IÑ|€ A�Å9¯€7»`(v§´I -²qm Ý&óÁ1z«×»Ãë°†!ÕTýZTï3ÿV‡bfÍ¿‹Eø�&²ÇƒË*õøº -&ú"v÷LÞV·¬Ý�ЊQ+ èh7_ÌÕú&±W$!N±.@òÉücdäHŒã¡uåô »˜Ã;F´:"¨ƒÛ£ëæy×X�í}Ü»÷ Óî•§¬n1벿ñzóƒÙ*©̰õ/‚ÿ9ðw¸7þ¥EJ�!I!µÀÑ2ÕZ›q(ïBë›\´ðÿ±ã±Zôðaa�eVfv‰‚Fnísnî³*q\t|˜ÚDœ!´Êò*+E¡Â*×D<0JÈК2¥ >Ã'–F =bk!ï7¯M,²‡äØõ¬~Þ+:$:F}_n?e$3&¢Ê6JU¿ÉEš ~ßûXÖF–mé�<ž¸# [n¥œãè'P®ºÑ Q $1�£ï„}èËŽ‹n�Z«»˜* …!¯æYCÁwZô¼ŽÞ\‚uOÜ#-ú¼-úX´«xµÚm5Jϼ�eTµn¹ÏëÓ5DÔj`Έ¢Rh8:O:÷DpPŽ%3"Tjüý§–yõâšôS\GÇjÑ¡1¢ ì*@- :>Ùø8%ãŸl f–裳‡é»»².3«±¼ܳMÔˆõË”ø¹».ZÆ÷÷°O3Â×9´.ÛÌ®ÂÒç•%‰‹š þÎþóºEÏß±ȴò¨·}·{K¬ïÀÁƒh˜ÝLRw·1ôCs�+¢ÝX6¾¨Áßÿë]D³18Ç‚M‚I¶+¯ín|ŽÙc�ëuÿ»Ùƒ¸û@luÇ×÷%{ÀrÍê¦Q¿‰¯=sïó ®-ó´¿û7#‡ëávàW‘ò{¦L�Ý®ÞOX©° ªf?µhÓnîÆ¤•šáÎ;)=©·ü[oæÃñ$µ`3oIØ8l¹¥ÿ0¯{õ›‹\{Y'ýQê¹Å›Å”$‚x¢T&5¨�’œ-øÛ“°D{¾ýÕ‚;ˬøô_B}ØÑñã!@�Am5–>lβbÀä 5íaëDßI&û] F;£%×ÐÏ!éc0½ò×è¼®_{fƒ_¢Å9¿öÇ&qÆ´fcL(‰ 2ÌÏK…˜‚ÃyÔ«�ý ƧåÕ �`çŸñÑu¥?€äÃlj{Øì¨UGS³î–Ç=FÇe„ÿƘ¶>:ë�`|ÀÔëúµH˽;_Aƒ AŒ˜\ðñ—XÅE#)S†°Ë%¤�·seó;ž䘑ÿàñ-zna`6CLå¥"eV i+Nvà|÷ÚvÚÝczàƒÇ€j†U'Nð¤éiºn`º«@úÃç {�|VY6£a®h¢Lë0y )›­fLD9F¸V#¸‚{;¶¢B¥B¼òºvŽR¼ûnºrÄRdoàî®ËQÏÕ¨Hm"¾é=÷‰eŸ=̪C¢<�S‘J¦6A<5E÷Ø=^�¥´¯ÓcñÉ1«:ùä ]¨¿Lÿ7ž ù¿BþúDÈ×Z1rßåÇ15(ÁÎ9�®[DÌ-¢êÚè¹ñž¿§6ÖƒjñöçÓ-d« „Å1å %•Œû†¬LCíhgÀíw|gy-·è-oÑÛ¿K|¿½=æÊèówg]S—p}’ÙÆž’P0Z%Dµ¥#ï°|!Ÿ&Æ%X-*°˜´å½˜yG|F˜Ù„àŒ"\ËfÝÇ’üg´©›]*°kCA3¬ú†Xñ¸[ôÜË1‰ 9ëw.p£z�:ÑhØ?’ÅÓ‹*®á˜ˆ¨(¨ˆ &J}"~>ZÝÇŽf¶Ñ(zθУ?YÔžÏböÿè}þ€bô% ddL��°âÊØ;3K1“Ô ÒWõ/¬1h„:qž¡µë^âKY9ç°±P�±‰Oùš†Äè0•ŠÒ>pã`rð€G|-%0A�H ¹÷ îŒFèNW0ÕQzì�£óWw‘¾ð…´d†ô,óæêuËáGyá wÿí½{|ee}ïÿ~žuÛ—Ü&“¹a€aŒE3­¡Z¼†SJD‹þºÓVk‹—†ØŽµÇ›•žþj~ÄsB«cñÚ½[­šé6Q0a030qî“É=Ù{¯õ|ßËçó¡ÿàçÙù Fºó§ÖŒ~�øµ›YÝr%-àŠTMßDÝ}7NOÕÛQQEA�—^fÃIå bþê6Tèî¬ÀxÄ/~ì�øý?†¾ßpøù{5U¡”K¬PލˆÆ©3žÖ(§¥‘ÕF‹ ÐæáWPê©ì Ou}�²BÉ0 ¦±OJ¶:Τišç`Âh´èw@üÈ÷p.–O¬nU�ÜRä[~ÁÐSþ¸â—îÓRõÀ8h:¶hD‰TU¡D¡=”ıAa0ÄÄ nYó“7pÍ~�Sßv dÇTùÑÇp7Âó/`¡´ZS™iáá™Z¢åCë0…ÂÚ#ÒÇÀP°>{_©Pù}Pßã»ËšËî³ä¯ºç­¨úà'?Ϧ®ÿßÄ¢›Ä¢¯˜5;b­‘^5è%ɱjhùjbÑ-ãÇÍBþða²× 9!Ô[É„‚f¢Û—ëÈðÀéò_ܯ9»Èw /ø©p>Òã%zen…L#’‚_@œqÿø‹¬;|˜laY âìCò¯AÖ%z\~}Î cŸé;º›ØøbfÞ”çsKm|õ'×q°­¦g=Rh*ì"+‚[L˜<-ë¦Pœw#¿C,{g¨ñ�~o˹bÑê–ïÜEö3Ÿ±ÚéÉ ¯nfÃ7 0t¨‰Ù²Ë’hL–]î3ÉɨÁ²ú‡ì¥— ÞŠ(þy•Ù‚ìÌÚÞH˜ð¥‰e¾EšU¯�|žµE¯$=§L¹w˹‘$*<�X�÷@N[uÜÝBÀ‹ÿºÇçŸÃã&KH„šU«ý–Èff*bkÝMR÷žž£ïè奛„üûÈ âîçÍÍÏ·E×DâQ‘#­Ä’åÊoFšÙ=$\�IÝGOçèA!sDÈÉÞ}Îö"®Ãß÷¡æÅ#Ž6òù_¡®ZQç#˜X‹Éøw³èõ­*±ê�¥°¶ÞBáH²99jM™"K ¾Ò‰¾ V¡|¼xE5T NêÒÕTyÂóq_{ŸaU&Ò¶LÄàXNv»€é�8åÌ›ßΨêùèÛ¨îïÄ/í쉸ÿ÷·]ËÛžz˜�|ŽË ÂÀ`t‹zV„ʈûyÇ›`ëÄÃq*Ìly��±0šgüv¡÷Cåp'ñEïÄ-Œ#;wQï�{UpåõèÏofyoŸDܹàt¸]¯ë!꼿çöÐÙõ~)_ ÆÁܳ�S§à–_هݛ…æ'<Q(•�ëýjùíæœ"�´�wq„TÝSl‡oGWÿ6¹s2”§;ÔI¯K á÷lGùéíhO§·'µ;}Ê‹Nº1”ì:'OÒ<%´XcÌ£W\šþv h,Û¬åÒ›ºŸnwî,±ÀBhÙ7ðNž¤ù Ð6'´‹ÕE„=™Ä*h±xó,};;X’ÍÈÞ#lú¬°¡�D¹ó‰‹]Ì";k,³¡�>ûp8Ksôô¾ 9ùóÞ4 ±VVD¸sŒÜÁ:MŽ\ôF—Ñå&©nFBxe‹îÁëÈì*’9AÓ�Ð* —K-d±ˆ#cX¾ðÔ/³¾•7!ø÷&{Bh² 1½®¹™1Ze™qÙz¦ÍáO?ÕÊ£’aNPs‚”Tp�±þq,š²eeIgÕ� lZ}Ó°ÐrFh$kñÌVQ³ 8Ý)|¶bOox|ã™­–pÓÇ©þ;µX@œ ðp}Òd‰¾�dO¬…‘P‰-OÜ„…µI¦h¹ >òß›¨ˆeÑ�²«Im€Y…ã‚:]Õ”ESµï¦W , :^rY[Š+»¹Mš^#¬;y’f¹‘@lÔß²žZö"‘<2¤ ª©ÊªPôCF\$ÔE!+BsÒ_ZD˜ZŠB¶^šœÔht,>Fü;�Š�—XtMÅ cüÏ­Ò+M쑌$¬³VÏÜöÏN!Û{� �ðŠ+„zHè¸IØx²Ú†ç˯rd(‡ØSg�óÎr¶»Cb×è³¶è–O+Ù<ž°V`LGÒvêéÕU X˜_¼æ˜¬ù,ù�ÅW7~,qŒ‰Àœ€¨L‚¢—I�}j&G¼c‚E¥ÚÒu,ý~ѶZÈæŠ…Þˆ{ .Jðº!Üâ}ŽCz‚ÎX-üÍ •¨|tÊ/ã÷õ‰QJ©õ›Òý˜p…ƒ28*Bœy¯ü^ù(ø[?€y]�èï?�Ÿ¼ éyZlÀöaݧš•�ïD­uJ¯™û'‚u=‰ ÊÅJÜû¬yñ·-� F¡V=t ÊÁ8(­%kkªPÚe60Öº�€Ù{¤‘Ë|ã(DDDõÕžW­�±¬�·<³nZ'ᤓA[¸'9Aô‚éëÃ0 tQ½ªå ÌâýT¨8äóF­”AÅ(8Ê üÈ¢†EÕN-Ú« –³† îòz>½begº‡[û QF) ˜ìŒ9Ž¥*d4*L²4} ² “©Þš ¥sÚΓ<³RJÅõ «¤qþÖú¦ñtc?³ÿ&9Í®Ô ÖÖRj™÷ƒyëÖúRe�S]@\¨*Ì£† †‰~/Ñwÿ7hI46õÍ_ÜK±Þ2a&ÖXtw<±èqÝwTUA•“ëŠõãœy©q»c,gœ?r£‚¨‘ЪLÔv&B-½6‚.Bîˆ�C$ÇÅrq†âJS£œ¼¸¹kŠd§Ý´Â+õ�¾v†¶¯�¡�T$9¼…•×k¾VÁûú,YyË«bã5BÎZþ„ËÔ�à!;³l’k\ÆÊ>Ëâ²$¼N^ÄaÉ!^É ¢úÏ‚,F\’¿Á ˆÑÔU3d�¨´’,¬©†„.à^·‡ŒµH¡FÄçÊ• >1XËY ³Ë‡Â>Yy)Ö|¿ì²ò:dÄ éu¥€eµ'%}Ph{@h©�kb£@2ß¾;KœŒgYÐ+q R²¹ûêÓ,ºô)“E¾�úŽéûïòû„|Ã�e(|†»²Õ×àܱªˆ—5e³du¢ð²* +–Ŧ"ŠyÁ­ îâ ”&kñè‘2,Á”Ð2ÒÉØ�'" ´Üý¯šû…Oóo„ G… µñIXaS€SÊûŸf4jœyŽežõ¨ˆGÕ¤õ!G'ìA‘ÁýÊ*KsÍ¢§'[¡i¤—©© ;Í*%jBÉ)I§'ñggÑ쮟îÊkÚ rÿ|C¢u!µéu7P×ýǧå[Uºšyx9Š6yru˜A”F £6Âxü8jÞšŒˆëæNø¼å“pшÓ9MŒ …­ºJ)%bÅó6„J½° Õц*­ÙI€ÝÎwñSãÆ˜J†|yR¶}xž ¼^—Š žQ=@7·ÄTb#h<2‘‹‚Go|'�`ú‹Êé«”@ŸÓM¯„X%�'J˜È# /È *­ÙÑ•Ýå)2À ­’* H¢ö\GåÖ½xœß@ ~yj÷�þ›õcQ O0"H¤´µºF™(‘ùv"Mì8¨ŸÂI}„U* 0®þÖ“hyÔ ™$©½ö8¢]]³ä'üÉ?Kã-q×Ä[„��y ¢Ç jˆôË=*(€âB_¸À}(¿ý£Â\Ö(¿Œªæ ªAQÚ( ê+ žM Ý˜x.ã°©\A‚eVš˜üìãE·òøý¸;þ�E.»>Rã·{ƒßŸ0÷OãÿÊ$åk×çô ãÝÈÜfþ(R*¡„A5Þ�Œw#¥b¨J%T_rÒI’ãÉ{PQít#5”oúÿi'€Ÿ¸&Í ÛÐdíñçµà> 2Ñ]_O!}q7D/;I”™¥âüPøÅ»ÙØÑÖæ×ºwº¤*»ÏÍ¢KXS°¨Õz'¾M²èZ%Õn ðôˆ_¼œ\O«É®Yú´Ö=69DhúrÈÔî@Äj�¥~cÊôBÊc.4�Z®r]SÜ"m Kð¡9a½ÔC:§Ã÷Ø1òÇŽ‘·‘mQ©ERsdä‚rÆcÎà~jžÛ7‡‰e%eË´š]Z„¦‡„<9¹Úe¢KF#+S3l’‹xàt‹ˆ@×T¨BÓ~±yxBÑÄ¡�ÀZEjºX PY5â¦Ì�;…ìV!³[zo  upcW rM®‰‰)Ÿ£u¦ë·Ç¾­±6š²¸,G¸_šá•Ã-ˆdj5ûØØ‹ zNh?(´5ÂvÅ5c9—‘oü gœJ|t5'¨ù$—_œÔgŸ59ä;5žô3mÒÉXNPô'WѲ£P<Ñ„H3Îß û|ÃZke*Öz›Ì ,¦‡×X *¢‘ªƒˆ&2. åvd‘Gr„¢¸37%´û.S‹™VNL¸&{ßa²ieªÐ“ÂAkïÑ0—‘àÍ Î‚qY—T[OŒ&2šj�§´J—´X‹n×ÕÔ0ÁA!S²aÃÚ*"N!‰MMMѲCø‚´ðfiFF2Ëí™ÀŸ¶<iL)íççu_o™$ŸfÕSM§F€¿'*e6ý_6•޵Jl½²VÛ�¢g­zh²“*,ϼ*%Îú££öOë)pg;P¥êzˆCFuJì8èM›Ð…mèšùééW@U¯Þrƒa±ÅÅ1ø[㢣ËyÈNrCJÒ–Z& ¨KAˈ!T¬ 3™ˆÙfŽW~›W>\Qj:Ë�®ÊP?î ¨2˜¡JOF�­D(¥R!½‡J·Ý�šÕ Îâ‡ðfÀÛp+¨0s ¤Êï~`…ïþžcè¾;áÔP  ʉÁ!¢ŠAãàŠ‹qTtñ�É^h(�t郄N%Ióå.èÚ�¤îš„èi1˜ÆîH¦ÑwO-ÙÓb7�ï/¡A¶ÓÝ îëîÀ]¾!¦tRX÷î?ªÒ|Œ8Íå»XžvqÁQNŒ(M9 ߉�Š]Aª Gb–ýYîç—ëe„[ªÂ,ÞQn6½Šåa¦üB’Y(G§mŒ$êD¶tÖN5Q¡ q#*¬XDÓÝW‡õ¥~ºQöƒ$û*Ù-m¼Â4„Mkûæè´íÔº5·w(‚7 ’ÉP�:|ÃGO ·¿4`KO”þû® ‘5Y’Ág›S¯ixÙŠ›´Š§‘m’—¢ø4Ýú�Ñõ´{MޱÚÀp�òº7í 9,Ùú}F\Dœ°Æñ–D©¿¹À„_Dœž![Û^¹‘@j¾V«™‰Äב„Ûûn¡õZ¡-ÃÂr8PFŸ40-·ÝÍ×δ%Üsª(dwÁAf ý®&—ê¯âÜ_&ˆm\Y™ØC*ô®leL<Úm´6%°¢všûni b�ª+¡>vÌÖØ(�wo½þ6†§Q¼úd³Oôë.{bñ-IAd3–À"ÀH3"l¹íÙ#ŽŒåÄF“3éÉ'¹2ÃSi�4ieÜÀXõõ^ƒ^K²$k,ºª¤9v;Öάd0ß9#´¥÷Iã= sÊž,î$—Œ‹{ßí§m¬ÀÅ)½÷'eÔ~Á9ºdñQÄqñ'å—ÓbÑ‘úIƒ{ÈhŒíçñy÷\;'O6Ó;âÚÿÓ-é}S+H±PÓ/«½-cC-ư_hZÖf”ÊgÁÔ-új-îä'J-É:ð¿TfÇé¦viŽ~$Ä�übšõH-q=^ãîê$î¦å¡e:� {î¦éuÓ,ÎÓQkÏÍGoØúúÝ51VÅ‹¸`´‘gÚ3jp¨uZûÿ±88 )ENê÷z@8( DJô¥�IFtÇ÷€n¾ gè>„Çïb~²€ä >uªŽCï®MàP= Òf>n0ÚR�eª¨7ÜÇϵE¿ËWzp·CB|ÄF®;ñÚ«ë?�wÀ±ŒÀ…R(”` ÙùUê«ajãâØ¼FCì!9qÔ¨üQ¸jM¿¤]œr l9)t=¢Ç{€¾PzÃЬ€œi\k ¤À_ÝôÉÎi)wof)“Ežš!¿’•þëGí}ž¨Ï›ÚúT¡<;í½„ÜVPÕ+x†…–‡„¼jƬ/\öIž Ÿúp=[¯Øjd7EÍÅx‹ vy)®ñƒû÷ÿ »gq Løµ“Ã~êg‹�)Rp^G¦˜ø»‡ «Y%ˆ+¡õ ÷ ÍCGȘð««Ö'¹¿DZóÄ_BÍ ¾­ÑVˆá‚=7²ÛêfO 'ØqWF,nX„Œ ª¹ÆáÑ ÁŠÕLóÏX\ñ8��ìLýB.8!lN”B\[êB?­)eÓØš|§�Â'ëö3ä ÿ!!/÷‘M|¶¬ Šc—æs¬îÈòc£X2°(0[E\©¢bÓÄ㦉ñ¿G¶7 !÷.±\ô²“laïEÒì„Þi«ú<€(&FšhúÚ75gÊè•ÄŽd·*ÊÆ(*VWN’¨x9BùV˜ úî;LöŽ}vì>³Ÿfzí=çÄZð}uØúÇË3ÏÇä<‚¿ýAÀS’Çj×¹DMdì½´ôªA/Üe‹_·eUŸE!�k¬ÿßkç]AÊço-鈋ˆÚ!½#¸‚ÃHPœ°È¾NŠYá)á…/RHµ5˜R€yöd%õSìªhâ²Õ¬Á—y™´ý�Ð>=ÏúZ?©e  ź\‚†làR —Ö&4d.ôH˜f£jó¨Võøì|ôqãk÷€•šËTJ‘˜«¨bfó¢´¤U×u3Ö0XIlŒ¦lÀh·£ z>Ãû;Õ›¸Ë/IwµW èÁAôý-8§O£6}a¯ÕÉÚú¶‡ÑHˆÓü=»Ë>É¡0“EàfôW¦ñÖeð „ñ;9ä¯uå5Dÿ�ŸÜ°Ì¿¼×*Nl øõê'¸ÑZ¯®(zúFaÞž�‚V(*”%&†¨ªp”Bgª¨™Œ�¯æøáŸð©Ží  YdµiOQ’Ïó� \ã\9Äò_]oïs™"ªw3Œ[¿QJ F¿?È æR¨LŸúø,¸ïìU›nB¼®L,¹·Œk\üæ³êZ:û²Êòò¿a¦Io ÎË òÍÂÛ‰D ª’Âiâ¨ýõÊAïÚIˆ?r5Zá½.h± NŒr¬Ã®â@EnR�©„cWpÁqœd¸u ‡øÑ%ÜŽmDö"Û.¦Ú; }}Ê_ÇÔê0èL38¥äwï BÛo|PÈ.£ˆq´aU)³&Ô'¨•dD®C.¦|ëçž§š7\1ša¿]�dT±=ŒJ3Øk´s¨w#ˆ䊸Ð-•üŽÊOKaUÝjkÁ»jÍÍŸ¹ˆTò¯bðªh“וe2ùfbaP¥XôBšŸ,Ú‡ï¶yË‚ÔÀœ3dm‰«ôv?“þÀ³i©NSš§K*pÖ=luÊ•Œáõ&„|Èá,¹±ÿŠÇVqdÙX"êülý{²#‹Ãœ¸ž$ÜéD&ƒ\Hïˆ;QÄß=L�Ö¥K¢E}°¶“®¾&Êxkª¢9%pF²”ã,eÉpt9OõJ°H¼0ÑÆJO$2�/#¸iÔ;ÝYk5ÎÉÿï¶*°Ýø7ßD>ÝÑÉ13ÓÚŒLjªqÂÜ#èX&r‘—Ó¢ùÐ.(: ‹UB‘7õG‹Eœ„,R%' oLðö�¹éfò-³N ù‘{4'"¨Ä5-¹†(·�Ç$y|Çî¢À\%ƒ|—Pt¿­» L,OrzHÇ2=Õ$u9r5ôâD·�Îâžú¯YF¢ÖšÅ4MYjõiVÇÆ L-òàVE³">«ñzÌÇ$ϰo¾—f‘:9fŠëî±µ‰€·gÄf<èžðAÔCB>š çú3Xt�8Í* ¬ÆYA-ˆÊ¸ß©ðÊ©–]‰EO¹ �FBÝhÑë\Ël¥ù÷ÚI°· ušG¯áÔÿ•½~tO‚céB¿[,,3-L)&F\%yÖ}ë£bXN R¦¨áJ©�Dp£HcV5‡„ìç¾Å.iÿ� ¢5Q£�ªè§¿;"äN›O›wmZ$L�b=âÑ5pì¡Ò‘㮡ö-eX”bðŒàÆ¢ˆL¦ ’e¢Û§Xp&?–· ]\2¶ aõ ¨—í3‚¿² ³§¤‰²q9¶ß9²Ž?¸”ÔQ»iS^„ÌÍ‘³Åk. ƒöhVsYï"+ÉŒ„¸3c´¾ãyDzþå�YNV³T’¢‰qlËq@eŽ9�^+2aÝ�¢/"t3á ¡.p_6%< ø{Flš) mj‰w}½™àB­¢W,ÈÄ5U‰bñ�¨Æê«âØ rœ®æ‘G‘‚Oˆû©w4º€i°+�˜Sâ„Dî—©r8ËËFÚZ‘oæ“úUÅ|„[–Fñ »ð*u" ÍŠ æM3§…‹þä&º9_²#éÑ6%l‚tÁI:îEœ~!g J„¿fƒ-Q-Üô~Qm¡'iM©‰±b R…J½ øßŒÙ6Óú®ýœ7/t¤)ε =)¤J6›g\è�GóZ)µÔ¶·g½ÐÓšÙš�|aQÈ>$Vw|w’ÃëA¼‹Ù߬8úOŠ9Á±MuŒtŠ“n\èÆ.o5ÊðTDöÑq�&DZ�—‚8Å4}IØô7B{ºñt ~—Ð�( ¦—ØZöcyDZ8y²™OË:2ò®€Õ§²œ˜�5U[Í”9#äËâ0kÎÃü4­â²¬'‰bâ âç´ÐÒ/ää�°¿¢:bTÙj­U]V�JüÇ ËóPùÞ"ëi¿IØ8q˜vvK�œL2µÝÛÞG§÷yr–uÉàN pÝumLMH±•_\>ßC~hµÀMÖ²ÓŠÎǹ¨òŠ1Á“‡Ès£6ßã±gkÆfIªó†Èí°ÏrBh:(d¶2’áYç1±¨¨ZÍw]¶TÍ*ñÕUlR¦‹]¨œŠXíµJ…âDCâÑ#ên&ü"§Ÿ/eÝ©-.±ÔÜcvcU)¡—Mû„<›}�fßiÍ“U�‰På5¹ì5ó*EHê•Ø2‰q‰ÄãÔ¼Ãê›iâØCyzÅ ÷ð.²6új)â;F¾x‚&™À¿¦'a8’£ Îzª¿Œ#ó‘Ù`°ã#ÉBO³MKbsÿ«‚’*ªä©^…\ž-iJ×Tzº©eaRÚÜ:Ý¸èÆ“ˆÝ“ Ã:ý³ûlxã¨t40°ÿE!{瘅ÒÙ`˜èr²}ï„b1ÙíÒ D9Xl”NNJu¼gDsdõµerK;øÄcLØ‚ý#BnlžŽ¯�!…ƒº;„éI¬”xÈ‘_—fzGž#c9D2LH/yï{X÷çû`ïlž§â ÒĪ-G̈àÎÄägÅå´lÃ|»@·_D¬%ªÁ[…±ÚBÇ1òòFÅTµa "Œ&Ÿrdᣡ¤ê3·êñ­˜öÛnF¦Zn^`ã‡'Ù‚ˆß�¤)µÌÔ°-|H2å¡Ô®�dCl*…©©€c’§åëóã%Ed,¿»¬j"É#†`õz>&Í{ÈôŽà¦Ó®†ZmÒŒá õÛ£»Là¿Ãº. |º5c«V©áÖe¤ê8)�#°£ª1,K†Uáòñ®ÄýSôޏ)þ0S�ÔƒL:µì GøÄŠI¦Ÿ!¯÷M]BKy›Çt5/¾-�•FpÉϸ†zÕ(âÅ2j<ÇŠÿy‚¿øÑÏ%ÏeÏ2‡w‘M… �¹‡„|8� :™wNâ]€¼Ã–o›¨¾ÐŸfÑÓÊBe*0+踬ˆŒæÉØCÞ•Â…S·4ÝìvKB‚šü>]µOdÜöYƧÅI ØÜ†þûWãj*� ÖÜæWœú”Ð"Bî¦EDxå·å9u¢•5x]–’ÈðŠA-X9÷”µ*””5eÉ!ÒNuaò¶!­Àìº÷e{o+#™íHS’£k* p8Û…´t3×~)’¿Ƀœ×‚üv3寵!ó9,gZja]*©àbhZ1䎉ϓå—}jJh™ÚÉ ‡³i5àHh'þ¡íCB+¹Õk«xD1zÕdX–,«F<ò'oÚØh«”•r9µ¹šß™^�H¦¿?Ù¹bé‰"(ËM—Ô<´/ß…loFî´J¦+‚ž³Ñe½hà”àí9ƒóã÷ E¿†?àXþ!!ò$ÍŸ8BÇA¡­�äl� |‚ÍéIâæ›È ÙA’k¥zs†™Š=ªÆ‰€Äi‹UP+[ùU÷�ó >½RÎ!¦‰x€L¯Gz¼!Á»-µb‰�Ú(@ I}y­‚NDmýÃ4ë7 ö”Öõ©Oéý>»°ç ÌÄ:å$T©PˆD°h­©kŸU!eŸ¹Ÿ¼¹�{;š‡wØÚÿ^7ÝÐIsbûŽå…ˆË‹ß»>Dš.`ÿ¿�_Šq\ÇFþS´Z]ývQ`µšå=V*ÍÈ×ù£3m!–)ÝðD„ýBó½ Úv3²¨¿#Ñ$BS¢ö«Ï$,²©{˜n�©ð¯]èîˆf&m>8 žÛêq$Õyˆn¿‡Ì•7b.SoÊ�âƒ7UhmC7ŧÎLªb…B){ì ?-8â;±-3ãºHv…‘ÿ±›ÉŸ:äï®°<q×¢ÑJió¤ ÄšŽyjÑ;Æ•A™ý/€SV9ºÍáâu«\Ьù91lsyY!Rà࢖ qNáÆ"ÊÁ7 ªŠÕÀÓ.Ή.0Ãa3F<°2EßÂÖ£@™ò,¬lZ Ê7ZÅTQx‘à¸D1¸ÊàfFÛX#Umˆ[Oê¯}�;Žì㮿ýÚ™Óܱ 4Jb;0–×®XD+Bcó }ZJ¡RqyÍ» �sì}y~á¥/QetKD¼âà(å˜u³±zÇ{ùåS_g¼ E�«\aº²²¦ý»§(õtéJQ¡Õ"HÇL T�Aùô+P¿^ V/Ú¬ãàËcºoŒ¸ÄqpUlÖ{£c%ƱE.1àZ)”«ˆV•"çV18ÜÚŸýéyß\¹õUß¿çÆñˆiâÂÐå)${Q’÷5µšsI«ç^¯a”"ê\-̱ðÆ|–Ô ¾w—~»ôF¨n•ÔÓ×õü¬¬«UŸuDŽ&_6R ˆ<ˆDžÈôù�sïßñw§~ý‹˜_Ü[ˆ (,×½ˆˆbP ›–Ô‘þn�ytÙÛ¿[áþ×±´^á<%]#ã�´FI€ˆ(XÅÁ¸U~3ŸýÀBÞS+ ™DIR ¿x]SIÄB`@ÝCh.™F¼ ª£¡/”¨W-à,-&ð|Pã(Õ“üŸ^™ø¿kÃBËÈ š¶Ž�aL¼÷eÛ‘>ôx+ýÒÁG^ÇeÙx§O¼ßeE|Ähâ²Nu³Ÿ×kÞ êG)]ŽíÑÓ$:ã‘�âê¿_`½üÃ05„|A±U]MÖÂKÎr}�up™¼]ZÖD&�‰}Åß­à}tï“÷hþË„ÃÎÓä÷Ç0kqáé3yK°Õ*ÃIDATI´Ö“E<ù;ÖÇï£EÞÈ›¤ƒËz˜j9�Óço¥òJ.‘~Úd¾<Ž:!Æ8Ä$h¿,?‰¾°äò±{A¶q�duZh9,´'Ui¹Ú‰!ñ놅–}B¾“ÃY:‹Yº¤…mÒJ—l yå5ÑçNŸõø¹¬š«&KTÄ­¾šni§[ÚùYÇ@$ñɰ[‚Ô5¼ë.Ö‰ÐôÀiZ†È‹M°ÿ&G÷ò+È~ø°ËDÅcV4‘­ywíaÖ7‰ÄÕ’½^B›×^�Hbɱ"-˜l"*Ð~ú|†%à:É<€´| é`—´ó'žÏ/Èëq¢/øœL�¥\?MÔù­Õ]›X…e±u¦¬XŸê*Žì£cå BigÛLëÏ1ßq)’§k*(ž én¡uÍQý9\õ µÌUã•~¦DÈÝ?�ÜR‚ÒÎBŒúâK]þb0r}…ã³Ûð‚vV^ÙâÆ/Ñè*U¥ð”†jUEÞ¿zWù?Д,# ”älY½ª&»­“|Âß­ÊE¯xO\tˆqL¡G™ï¿ïàÔ?þˆà-/+.Ãåt:€Ï%\ÆcÿðO¹ê[]kõÕƒYø‹å·o„ï½’Þ³úÚÖ­n6à WSŽ.ÄUŽR‘A”-±ïq�ã«ÈS Î@—Ç¡¹¢�–js·GeÄ…Y)Óâ8塪âe9:¯9 ÏÊßÿtà†S¼iOf•è&¿ôºã¬nÚ„*©Â )0(H˜=‰ÊįÚú߯Vñäï‹Ú`PMp·Q½(ðxe¤Ù”-«œsÝOVÜHXv"«jž æØJÌÊã8‹GP�h² _cþ÷áŠQúGoRCŒÅ‹Ê^š@ÃöÞŠþ1æúq�W¡Ù=­ùrgžwò›nyÿͺ6 ±>éà5�øö¥4¢EIFY(A5Éíy¸8Ê'ÆaUæÙ³$™÷¼™©Ì¼ðŠ�öʵ/¯àËb«?u å®&¢m¸òó.4Ç<•°¶ƒA”µ¶9¢’{âqcaÎE¾ â8,鈙9²wåPÇ«TÏû.Ñü¢+3yCæÁ÷� ?éGÄÛ KÿgV†=9¥ º–= ¿G34&PÒ�ºêõŠ?ÿbßrÊPQèÀ ÐF£—p«ÒàúºDgó8gÛÊ(\%d•IÄ|„c‚B|\É)G cåKøÜ—ô*s|´K®eÊégpÕ~Ë€�%Ù�7ï+e¸ 𕼿4ÿt¬7[ž:õÛ^ÇksËô°Lv»’îÉH½»#/ÿùTùÖ2ï{ÍŸö8Qåmšìë�ç.t4ÛhÁh‹\ÌÇc‘OJ´C`01íà‰C…*?1U~°€ÿð 6U?Ï»×�÷¾÷4Ov¬òéÏf¸àó+—†—¯û'œÝ_`Q " ¥”zh� ^ކÅ+Yjâ«!<þ‡ŠM•–›"æ«x(¢¬:ÖR9«ñ3ÎiÁ‰=$9Õ âÐ(Œbá©Öý?Ñu¼õâ—(ï±Ê¢ Ôà : ‹RP¢òÇÀß g®W¢>0¬ôÍ1Îí×H•+fóùѸ=fî CµCÑ´Pf:ÂÅ%n‹‘|woÿ壷�FGQCl—æm¥(µ ¾Á—ìÊÛ¸ðêÝŸgŽ*>;Ÿ¡sÂЭ Ÿ9¹x=*;4Éêû¢ß{à­~à.ÏMÿŠƒS(#—N^$D‚ÄÄ¢qÐ&¦ê N¸>J Áðâ»éxÉWøðï>ÌNbÃÐALÿåï+|xDF-ÿeˆ_*¡U`É×DP?à (Š}êµ}ÅO´Ám`ùD³/fÐtBËäZ(ú³m³×ÍküáQäüÑClÄs.æÎFÌ«AÞúææ {F£ø²å+ET,"ðio€ÉÊñû6_ŠÐ,æZx]1=çáp+š…¶¥_ã×O±-p‰+³2C›šì4fi?´ÕÌ\ŒÃú åÍ\'\>ó-°¡u~´â^²¸¹ú£M“š/¨ò†o~îÛ¿yÕ;�êóØ’ËA´È�ƒVüx‰óô2Óñ¼ØðŽp¨rhkè¶Ä>€1JµæÔì <‡9Gó²[^£˜Ãea31«h3ó þ埾Â8œÊ.ÑQþ&¬Pš4j¨ÆçÜæ’Ÿí‰¿~XP‡‘l'·€¼_&?C®{šÅäñÞyÕn¤¢^´7è¿åjgèÌ ø3À‹J…%úŠfLÔÙk¬ŸEë)aè E1( þ!à'GÑGÏ…Ý=ÂàX,¥TFoôΧ?Нd‘¾1�ôTAå¹ áMR†qýó¼èÂÇx÷ÿµ9ûyä+ßØÝ©ÌǧÑÓLJ"zúÍž‹”wÝA*(ñÙ j‡=ÇEI‰bu+__jã¾}]¨';ˆŽ_‚›–ÈU  ¥íËš“{¾Ûuà ç¶.ËÓõ«×÷TÂÛÇԃчxoþ÷ør¥‹÷™éî|�ØïÛ­ºˆ4cï�È¢JÛí¹2%š(1¡ lû³¨úÀ+Š*ß<ÌÆ—¿)æYžFþ±“³Ú¨¯íÃíº�ê[{ɵ}ƒøÎ«X-"±R()*M¹æµ´Þuo8êEo+%Ûd’'ÔyÒ—;æ‡%–¦ïÇLJq;¨Fð›ï'Þô;²2Èz@FMŸº/¸!|UõŠPâ^p@�1àa”¾e�П…LÛ,Œ·±ô‘«Ñ×~§¼…xf�ødzÃÂÊ0÷ö°5d”�^c…£z7£¹'ÇñzX¾ä˜™I¤Ø “ôHï踼µ'8ŠÓ¿…Ì¡ üÓ«¬ÐÃò%L_Ÿ=8Œ�¡Ü'J˜Rß}þ:‰ Ÿ+Áǫ̂&€m׳x6ý¯JVxFÑÌô3·Ì8_4=ãOº¨îw³ ¨wBõ¯T�Ü.(¦vÄ=`únÁ½öq^õ„¾¢ô¬!�{žZAâ]*á,ƒÙ1ê|…¯ÒK¾ö­°õ:àsrÆÃ)ö3àn=±D~7f~ΉP©¯†¢'zx2/ÝÞœOußwhÛÕÎR_ÏÑøÒ—ªìuYQ/ºÑö;Ô6~͇¯W`ÐŒì =E(lžˆø¯�åÃ7>Äfª`„WŒG\°êðT&&×ã°wt…‘¿JzSŒÿ¨�£+w_©Ì‹ú†½¯ÓQþ!7Æ6;v÷Éu%bx•¥òéÁ#‘hµ5ÕÛ±‘Ü>¡ #Þ^ «JÁÈ"¬äYi„à—4P—>Ƕ«H xc§�©˜¨4(¢Âë½N>âöõI¥8¦œ›®d¡tï„úÎŽ’ûþ½‡¸ŸË�V:ã >·.à´7c ¼Iˆ;¬Š»š¡ Fôêsî——é¶Ì0›¹<8ί.'¡gÕÍ€À§íûOb膙6Ì�ŸÃ9ÿ|⣷ @x!îm—P&,Ê$£Ñ^îtº¹1çƒîÃa¼Êïì¡zê2Ç.ayfÒ>Sß$Œž— ½Hæ’ͪ};•�™½èBJ¯´2¡zG·;ëÅ H——ûyÄ©pȹƒÀë¶­ƒ”Âî¹6)ŠÔN*‹jûÙ¦’ wzÕÙi­^mÈMpÛJ‘÷€þCP'BeCá¯Eå*ûp}ƒÓÕÆbi:ÉC=Oí♥iŒßI”M$‡² ã²-Y’Ë%æNÆUÄvÉÓÍJwQ9“·t:ì|O™[¼p«jn•—ƒQ…å¾Â.Ÿ«;¥ÿìx!ê%mÄÿp‚ÜŸü¹ÌòÚ¾h¤·”m߀¼ô³÷jÞõê•J6ïÅ=¶ƒhœÉÛ{\úÇVR¤n‘>µ�¢3±Me ¢úäKh½ðˆi–™A&3”–™]šÈsÑ�½T~ó#8cã² ƒ\Á€îŠJîê ¶p}õ ÆLAHÈ1-Ée±ˆîëCŠÅTj«ÿÿþ#þµ×²º*j{èÒ7»ÿÿ¥“ÿw­µO2WA¥DŸ�"ÛÁ¡`i·‹¯Áûà¯P¾egç®Dpa}ê½óhµMV(MÝP¸ÌNÒ+Ædà·”ß×O´0Cf};t�¹÷¼ÍYâ®.ª3àµO²:¸]Œµäî<ȨtóiÙ^,9Ý«B¯FMI‰ Á™,öÅô•Ì;n"÷Ç7SÝNÙñ ݉Cèõ[‘÷)̘ÔÀHŠôRP£”„BŠƒ2Dèüø-£xM?O|Û†‘èÕéº]%M�¹üŸ>/x•ÉåîB�}óÀÜ®.™?»°æDý nXÁ!'w’»ï0Ù�÷‘µäŒ6lßoé•‚�^wñnD‚Ó¶€&óø ­2EK±ÁórL(‚j4XI]uZù”ÔÓ[rÆî —Ý —g»Ÿ]‡³lš­x‚¦ÞV˜‘°× “RàkHÛØ­§…Š>Å‚s��Û/4S‡-9¤ÇÒbÝFS*J!I…ZȈ+ˆs�ƒ ñŽXŠë9¡}ØR[{;éÌ»ƒüþDâ¨ø!Z“V¿íÅFÀH�n?…¾&PÇZucR3í ¡ž&¢õˆ�Û3BfÈ‚‚ÈEÎâB‚"Ĥï¶¢#{,™ÉDx·¥±$˜î”Ðrò$Íì;–GF\z†<Š¡Ÿ„˜a(!‚øÞ£¬¡éäIš§¦ì¿“ºH§•‰N`Âui⤰׋Úo"þ†ôž2–JÔ„Xá Á¯XIl]+?MjÖS˜è!'‘¡Móì8÷ºBÑ—^Ü©)ZŽ žœeÝÄMÇŽ‘O+$ÇÆ,aÊY P$¥³ ¥´ÏHF‡%‹HŽc—æ‘-¹«„üÖ2ÈHÆr¤ý„ëÜEÄel(-K={%˃Ë*Ÿ¦—­ºj¨!Î$•FÍ�H*AôQaÃô<ëëx|ËÚ!BÇQaƒÅ•�yb7;÷äIËÿ�ô¼Ð1'´×úclÈ«-vÁ·o–_¾Vùf1Ñk®!Á æœÚçcâu[F’lïA2–­vÌ«�ÅÔŽàKBÇÂ&›ÿÉ$꯵«[ðwØrËìN!‹ôº�ÏÐ�zζÿòi)ilq±ï’¢é’ûí�þßOø×3 Gr�ՔƼðÏLÖúgéçLˆ�ôxw ­÷ Íû|‰ný爛r¤œîû„üÆ™µ (ÙÈÖæ£æjÓ±!qû…\(4…BÝ~ZÖ�nbH¨»“1zú|x¶W?âu3aÇ‘^7a�õFö�aM¾Ý˜Ý"ä~ál@®Êó@h‰k`’d b)yjpÒçy¡� y…z‡)+F!)ÅnºÐ›juü ˜ VZ˜Ò]×kˆÛ§çY?�ø ™…2âžÃ‚[[òY›¸ÖÐØïéñB¡)-²8‰‘5ï»ö§ÅRØ¿û_¬hÒ(SöŒ ýé‹Ï¾kºÐ»?탴¬Ü’dœúÆóܯô”ÑßoC’“I«$ȼt£RBÁù÷¾ÏÝÛ¤TžžÆ�éD?¦ «Ã|Üû\ak5Ü®ÔФAŸØËÒ¯.D¶8c\†—= :›û¶‹ÃWGãÞÑ^F@QcϸI¸qÔáåÖW�|gÑäøEm)£®ˆ Gõ©÷¬®u†Éiâî>1£¡¢÷½dg;pÚ`˜ÆL^!€îzÙ¡IØ£4?@¸ÃøXòQ�@ŸÐ[RÇ¿B­ŽòôiÔÊ &ûÑD_!î£(2¬<ÚÐäÑ,aø2†[{c¸A R00J÷ÄúX7jf¡„ CK^0<Õç¶eÐç�¬b+È=…\y»˜B-u3žüì¡Þ?=0ž•‹Î@hi¥'éQÝ ô(xŠ·àqš+¥QY3Gìs�'ta=ª›q /“ÎWàd.Awf1<ˆ”ÂB E&AmµÎÖ;°½XržüÔÕ¿73ÚkŽSYÇAëÔI�+– ¨„‚}ÁPiF1Œ„Þ’*�dCXR+oǹð‡H÷$Œ‚9¤ÐSÒ¼ Í‘ÁØ1?ÞL¼ð¢é‰O†ûNÅ}}öó^D�‚�’žês+ÛÓçU4+;5‹8 -<ç¦n(M?t�ì8à9ƒç¯Cs%T?ùer½¿•dàRx¦º€Ü ¡é‹ßa ,ìуS ¸VjHžWÿ\¬d“Ý%‹§†�îÅ Ø_î qS±…�·˜HûJB)B&… ¦(¶9¡=õS¢„Ú=*¨y@cŸ¬%îÏÖNBÓ!—Ƭ5±è$I)„’gMïQ+m�°øã!I!,‰YŠŽ“„ܳN?ÔˆF\K¸Y#Ãø·¿ä;m¿J½ß‚‰:L³áxœB¡û³.�mû#é×¹ãšãµEÁMH�:9u!Ž$©¯JBP’5J db¿/…�¦cX?5„)‡@SÕK}yRlyƒ"u’P- PÒÆ¿I¥¡BzR’Ÿ-[}6ׄàwÉrŸ~˜uG… ‡…vIäΤžZ`ã—oå¼"âLPô0Ì9Hf_eL�ïsB{ºš“ üšv×Y=Îö Å¿êÇã¢O±àìØ*ž )œHüÃÚ6ÔõãóÈš#æÓ�{)1EïH]ï õHÂøš^uæ×µJ(5Xf]#»¾I$zaõ¿oôEe­Šf–.┸¡6yíw«µ‹0LшõÉ›ðŒ§ ñlû¿î5l(5˜ìÚßMˆÅÂ?$äÓÏ)ˆSwŸÉ j¸_ꢬ¹´äÄWm!$êµ’mk›OM�TÔw„uc3´Žœ Éúö½îÚ¸ÊÓŽÿ鳦nTº€“÷«m阈ðôøP:5>ü³¹,># ú I+2â2ü@ aØÔ#xéHbµÚÊ âžI"Ì"dúéñÒNœÚ„ '„¦ú®&êßsQ?Óõõý4ßw8E'>»3t„\ñM÷ ͵@�RŸ¹>`5zb+Ã\;!$”nÁß™ˆÕ§PÌô¤Óèß­ÝÕë>Þ„$Ö¢Á_jŒâ>£Øp:¨/˜pͯ¡ªMðt¡Ûû׬Yb='˜¹c–Éælº=‰¬ÁQS›à’nHÉ)'¼¨ýMm[†œÆEnýÛÆøF}#Ø!»K¶±¦_6ÆÔBÛþh<9¥Ñz}·ÐúÀiK„º[,­Wݤó{díBO�:"™TxdLð†§,AK#±FíjŒˆ'›ÂÁùãç¾Ð“ ægö7'‹ÞgX†% ÜÞ”žp]Ò‚‹×±ÿÌ/¹dòKd—+,ci™c‰ˆ\„„Ó/ê§Œäβ„ïl[ Ë9¢äÅ—­Ç8y®˜XµLl Œ%ßpD² ×Gf‰£Ô.±*hÊ‘!H\ì2&`YgÉ%µÃgÄ¡EÍÅà<�=°Ü!Œƒ¤�üZ˜CC,ø(f£$÷™Ü§‚P&yÖ†ßc©ˆí;¥ß]NÿB9:½o pÊBܳLïm›JªTsùY@Ÿ¡-4—“¾D;‚ƒåœwËå R›”ö>NYpPvN• ¤ý§Pq2Ï JRélKçÙ2˜ä¿•úp.¶¹ùeGrà@¬lßÛqŽSÑ�ÀÑkïo)›s Ž8öûIæNã|NpÖNMC)×8°ðY§ì˜ä>"åè 6–õ2¹ ¿œ|o ˆ�, X>»ä DßÁQ>²ZÆd3øËÕ“¿ÇØ£ï/\^±^X~_ÿÍû›*¿³© U¡"€T©j0ÊáBG¨ŠP£ªà$z[ƒwV�yöÍáŒØ~mÕ WEZâ¤àKѬ…HìU[æˆÂÕ¢Q9“q@±ÊѲ©À*n©&+JêÍÚ÷�=ƒ1F‹¯=´*¢Ñªl¹Ü”B«Æ§ª3(i£D'šeªbûPEv™è¤hÅÄ‚A0bRJ’·hl’Š›¤ßâŠ&ïX 5#¢c�ªÔðÛ– }U,”[ÙiZ Öâ±|Vý_õľ¾8–]¯u�2*Œ=ºêäÝç�Ø*Ý;¢ˆª±UÖòQ¸ª®è#Äx´$bf1BEcZ)|­ñÕŠÿSCì·*'e"V1U«�JFŒ‘àÄÇ€R “µ4¶U- �ˆ… ¤ªBÿžŽc:ÍÙ"D…2¨¸œü�1–.8§4y ˆB눑(£pPh­±ú˜Kõ¬6Z·ºb2dtDk*TV–œŽŸöùÓk— Þ�l?¬�ÞÂÒ¾ä®þš£É{U¼Тg ʱCWÕük,¸‚’³B9žkçÚ¹vM¨ ª` EÕ:ƒˆa\ —ýÙ²Lÿ%€&眢êűgT–Aªˆ“”ê‰Jhb|T£©y^OíçÚ¹v®”ã U ¢< LE)2««˜#é_¹¼ëÐ÷ùco¯ÿÁ»|6›a¶=fz#¼˜$‡="Gï«Ë *H%ó<Þϵsí?p \-‰*ÆÄ²ì¬d(g+Ò<ÎûÍà]€²ÒB±ô¨NÕ MÂÊcÍø¼ãd™“ Œ¢Š‚ûåíS°ðJkÙÿgƒvú¹v®�kÿ¾m.Ïj´æÉ–˜× |¡Šæ‰Ò"ò1<–ÿ|^ö¶Î¼‰ƒ§ûP¦qYP‹\¥écEYHq®Å"z[ÁJŤòÊ[‘Õçû]ϵsí?jSJ9¼²W_5*g èÿ´ý½7¼ý…:ÈN&,§ú¡921D#½‡¢íØ|ìFöêÂ.2û |VB_Ÿ˜ËQª <-¥t®�kçÚ¿oDÂ6,áõcKˆ7m@Ñ{÷¢sØ @¥è:‹Y°š]ô÷x`µŸx†b�:‰üó�`;w�»þ£^ݶ ϪòZY±‘÷iZ Zõ#Þí¨ˆ‚h^»×-ÜxuTDl•€R¦€è’Õˆ®EÛÇ,Y=–�ÿ\0î\;מ§&—…Ni\L�q=È‚ ÐëÀ¸)q™[(R¡/µÔjúTï J½µg3èÎihí$îFö˜„Á$ɧ H©¤œ¾> r.‘~®�kÏW;‚ò·(Yµ"¢B…H¢oíÂë5Û1€Ú ìC'ú�íÉÂíUKš+P…]bôù~×sí\ûÛ¶$zê%úR% �3 ¬]³()¢g ä5èèqG•˜# ¿WO¢„P¢J_(–xpÆB'ùüyÅ£ŸkçÚäv¨~àzD`”#\á,Aü"¤" g¡+"¢”2§ ˜ŽŽ$/~Æ{ ›DØ»Ÿ~‡s ü\;מ÷ö¦IÔQ€îQ�o™-`ìE*;iéü¼B&£m(«‰IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/nabu_2d.png0000644000175000017500000000026015153325210027036 0ustar00paynopayno‰PNG  IHDRí•tÇsBIT|dˆ pHYs°°œÔtEXtSoftwarewww.inkscape.org›î<-IDAT™�Ì¡ ÄÀ�¯ó5-P•�†¸ˆD’èîÀÑÂòϸ+˜Oñ ` ”«  IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/nabu_2d.svg0000644000175000017500000000763715153325210027070 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/nabu_3d.png0000644000175000017500000000557415153325210027054 0ustar00paynopayno‰PNG  IHDR<@FÈsBIT|dˆ pHYs°°œÔtEXtSoftwarewww.inkscape.org›î< ùIDATh�Íš{pTÕÇ?çîn’E’!w—MÂDâ”Q„ð6TP°cÇhÕqÔVë‹jéÔ–j}L�écjglщ}ŒŽÊè(N�‰ÓAÑÚè°AcÀ´•G1&› ‰‚�…$»÷×?ÎÝdC6ÉîÝ,ñ;“ÙGÎ=ç÷ÝßóüÎ�ìâ Ȱ"Ëk'…‘åùs/p*á»^ LÉòÚ†�»Ôî³À�‰*ÛP ¾n"ɶIã0„ݰæYÃw€Wt]ˆGJpÇÍúSà7@ÑÙHeiÞs��53pq5¹˜¸PÀWX|D{‰E"ÀÃÀSY’c²A¸æ J—’Ãw§Îdö+˜zóux ˆ9\÷{ššØ=M}ÇzøqdÉ:\ÀGå¸e“åÍ뤿i· C4&-[ß•Çg•Ë£äËMxåJòžháÓÆ<<÷ßÂ$y„|©½æz‘Þ¾ádÐÙÙ) }¹¯üšüÈaŠ6E „êov`xõ“¶ÜÊ$¹`Útééé•l›7o@&£äAòÿ ˜?ÌŸ æJ¡¬`¢¹ ƒ`– ¾ŸtSôÐ|< wÜqGJdED"‘ˆx½Þxô~Y¨v ¾ù‚ïÁ÷ˆà«ÌYã%¯ã<,ø§ E77€Ú·„®ºÝô+€9sæ¤<�×ë%Ä?ÎRÔGm»mµ /Øßß.ø¤ˆ—S™ÁA ,ð@Ç2�*Pm{Vîüñ1'OžLkÎH$2ðhâ÷Šp Ð"¦@t°V þ�`5*‘3ç i³¡ý* Ô›Þ£´)´_Á`0å9››› …Bñ�Ÿ'£h9¼+T|G/U ªJðžÅéðBY�à¿V0ÌuBIÞC7b†ìÚµ+%^¿~}â>¹:u™Ì€íß� æ„@…dZ* 5.Á·Xð=¤}Èïã‘  �òòréìì•ì–-[Ä0Œ8ÙœÉ蟪#º¹Qð? ˜U‚ßë`¢âRÁ¼O0¡I§\•=„­±@ uuuÈvwwËÆ�ÅårÅÉÊÓrˆ¼e¹:‡›ëµ‚ÌuÂÌégŽFB(χ“+ÁºŒ=`½�fp0�VÌËï÷SYYIAA­­­ƒAN�Jl‚° ¸?�5F„VL ¢‹�óA}ò„÷+58°ÆÁJPÕ ŽÿT„Ú¬yð7 _¯?¢eă�š�Ù ß� „ÒлÔE =àÚáÖÿ˜YÁ«´�Æ;ÐÚ¤œ/¾ݼè@w8®Jõüö ·ˆõhÂû¹÷®9Š»à`ˆLk²[0×—§!ö¼�S3Áhsîž‚ö_2l¾o�_Ï8JJ`ÿZÀ Æ6�5`œP‚o1Èjà¨BPŸ€»AÑÜí`�B  ½k: \̹ÕF1ð?{| ­é°ƒu ˜“Ð5øD[lNœÞò¦FTÍ{ äu°fBß‚y“0ËLs½e VK_2:Ùø˜çÑÖnMs½!À}À,p¿¤×)B§À²ãˆb1ý!j(Âûáçl!€Ø�:©›©¦ŒËÐ}èð—Ÿy­á\t¤N»VÖ¹Øw Ä®ãc˜S«h948"N1@Yú}l �(Â-ŠðË«ã¨ëß]ºxµšY xÐ%ëk)ÊÛ‚ŽêQ`:ÚS‚.ŒÌ*�{ȳŠP½¢>:tdœ›² 0âöË*::¡7À³ T °�Ø'Ù¤çsí÷M@:)í ôñ‹AŠ­¡¨‚wËÀÚ m/(ÂGF=`ÒnˆÆtfÈÑ”ì¶U0ßcX߆ýU‚ù!LiT|Ö,Dûb/©›sí@-ð° ˜….^’õ{ÁZ \2Xµ�QYÊ6Lqšôp Ÿ »âª* û` [*ø§^{+^Ãz€Àô*òÑÝÍ-<tî7Ðåé=ÃÉ* zpZ¥D? ^CëÁ°ÜÚ¤-ìäœl�~(Ô| óÀªÚÀäÛèsÙ]È¿' ·€ã6™n ˜†v�‘p#:€õk¢þ© WC¬ŒíP¶}¸ŸŽ†�ŠRÜಠ{ÒŽŽŠ-1`w |º÷“UäX¿¥à¿{ˆ~]G¤0Œ5Û&?)œšðø tΣ+¯&à °�Ï× 5u\R „tPj;!ÒCœp¿¸¡ßZ1Ç­“-0¢yŸ=ñ%ù×Üäŵœ8 Û½„{ì¡SжՅ.L’á)`㸄  LÖA©}—órw0JÛ>,€•I¯¨Ê~}µ˜ŽCÀ!]¸÷/ÍúM0C@0¾cm¢¼O÷!?½ÏâíD7WáÞ4vP ’Xx¸m §îÃI°Ê~}.þ…â‹�ÒÜ›Àhuøî-— �Š×˜rÓrß{‘Sj9�ÅNúVIf ¬„ç�ë^p½®hýÔáŒ]èZx#hP˜qx‚U ªøfîTìì JƒÚ^Éñ½�ô4'ÌÙëP.{í¢bP·ƒë%7¸ì´äؤKÑÁèwŒb®ŠŽ“@½P¶"—‚ZíËóÈ]÷¾êL•Ø×J†“èØp0ÉÙCæ7Æt—ÔQûº³à¤Ùœ²ô²Öhk?ì%£HŸ_‰sm“6œh8Fš¾;ÆXÝLxË^Ë)Mz‹H>œ Û�2*zRÀ€‹¡K=eeÑdˆkXFÓð8À“hÒX¤á8᳤áSqg–¸&€°Û6é¬]Ÿ²1dó@lbLÚekØ�mÂ67#þFÅtŠ:ÛèÎjв»šKõ©ƒ: Dâ$CÀ|ÁôBÎEss6WÖ‚–¾­\ 䃪‡¶F–@ÑöšP2úBÿÍ‚¯Köå»Ó륋 úO ¾i « Z|üKÑ6°§Nr><}2ä^ Ö"À£Éé’±…+Ë…È/�wô*“¹*ràøR}Ù†VÈy+ÙÝ�a~«øêP/To‡`-¼@Ý®8üU&‚ E®èBÊy”ÖྋàØ@¸ßP´ŒXý�¨lSÞ-°gðDݸWð 9Qw*¨ÆtK—ãζ¦úΉµ8Œ†TÚ·cFfMª%¡1×»ÈîOuIÆ~>]`?é-}%ñôåúZ†úänQ:žJûÖ‘)%ô§2òsmŽæc ÞW´ý{ìñ <Ð^ j9¨.°¶*ÂI�dF‚£Ü;ØŸÊÌψŒ~dúȶc5(7XÛœö©3*6ÆÉÏG%¬¯¹W�”Mà}OqÐñÞx\ª«Ìü\I²äîßfÿ`㎳F8¶Ÿ/5ÏÞ¥YúJEÎÖq¿ |&„pºnÏYê[ŠÐ?ÎÆšÿIÉØ ´ŠŽIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/nabu_3d.svg0000644000175000017500000001404215153325210027055 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/nabu_cast.png0000644000175000017500000000571714757047403027515 0ustar00paynopayno‰PNG  IHDR?:’�lsBIT|dˆ pHYs°°œÔtEXtSoftwarewww.inkscape.org›î< LIDATh�ÍÛ}�ÕÕyðÏïîÝwaU@Ø{//"‚Eñ•Œø®� Ó˜±ic�&Ö&ãLlÇ?:N§mš61}IÌ4ÚÎgšÖÚ¤MµŽ‰ ˆcŒDaYÁˆ¨À"»{ïéç·p¹Ü].Ë]à;s8o¿óœç<Ïùžç9$†�`qËÏ'3“°ŽÞ¿Ý9œ±Ž&’Cíä&áR’רü<¹‰dÎ!d°2±¹«þÓÔ,|PhÅ')µP|2±uWEý‰”æ�äð›_N(Õ{ÂõÄA…$ägæ’}&±qýÐí§5³{6fÞ$³&ѵ»n3®#†>8y<½W�lä‚gÿQ¬uà¸h¹é8=X‘è~ï0ç[WT>˜ÛÈÖ‹(�§iibÇó‘`r'ýsÑFÃêƒíž#…„r30ŸìŠÄÆWÓâVLÆ8dÑ…7ÕfÓãq2ZjÚö¤“Æ&Qz…ܯkúê"Éá ˜tB�ûlP¸*˜Ù”_†UèE¨ømÆ�ÈTî,|oWé·¾MÃm½ògù[‚ÜÂ`ƨ‘”mP‹‚‰…ÏÆUTß!Nø üîǬµO˜ïWöþ´®Ëð¯x¯—õûF W¹»‚écë/ÝAtÞt~5R•ê©â–­D‚¯Ù'ÈÙõßÀß WQžÅß!')=aì�q§uÞŒo?,A†ƒ cÐyzÔ@þ3A¾pÝ7ˆÂ¹Ö‹i˜§iÓ´…yš¾çPø£ ×vH¯²$%’�‰®Çƒ©ô^ä/!¬Jt¯=HÿDGXµM‰Ð•7Ú¾ñ!» E¡!­ÉÐtÄ Q†R‘¦H¬ÿ0Ñõá2�Aþ÷ƒüY¡ºS›‡™Ø�§‡úHô+¹ù„kðÄ#v�- 0pä%džýÅA–¤H±¡¼0Ñ݃g¢×ÿ`ÎN�·Þá£ðñ†ÝŠ£E¿ý¸U<úª"ÈMdùe„—è^’p3¦cÝûIÍa$ é¶Õ4+ñJ/VNÓÚÕ®ÓbÍ^×o�>}B>‹åÕúSZè¿„ÐNÿ¿§w�Sq_ÚälM[gW¹í´ˆ;kD�¡X¤Ô0T£7ìÞþ’¾?_¢çîv™%¢}íÍ…VÉÏñg•í#Qêý=¬KlþÏTð“ð#ŒÂá[e]Æ h¾!­Û%Òâg1íp­ŠH2&Í<´>’/j»õmýWi §kZËgŒŠ§Ç~D Æà¥ØÕchڼܩ_y áaq—ÌÁj¼¬ºß9<ùK‚¬av¿oªl¸Sûª ¿8È!òøýp<Öˆ‚?-RåŠ9¾/BžÂq»àt‘F_7Ì9ŠÌP6_~¹^¿{íj$9žÆÿN¼ýNY}–Šü¹(@UNââÀ |\VõšèÎæE6uaH›Ó?ß'ôVÔ�Æã8WtŠ×ˆv|0ôT)Û)úŠº"ƒ ƒ ?eˆ¾Óñ¥ôïK( ÜG‰¶}>Vâj5¡tÜr´‹‹\÷kp–Lqˆm¿¿/'° �¢PŸC³¸-¿K²ˆâÀ8ßÅ…éß߯ß2þj’šsp•¸xp—È'~\»Xµ!%9¥æAê·âÒôW‰ÁíØE1� h¾üvxÓßïp ðOà{âMr4抷˭C 2d)µíÏ·áâÖë�Ñ:üLÔjŠ$”iþnûŸãƒ¡R »D‡¸¿+ž_�ººc@ó£RµU£˜¯§¿ƒ¡DÛ€æ_¬åã1عë BwZô‹²êkãp�¥q-Åò·áe¦ÿ*ñLÿ0Æ ”j:2÷E„{æ’Y–Ø\ËâÖ{cx1 óÜ8›ämJ«Ò NMò‹É,OlêºÝäNú’lbÚ²a.t]0Hô67‰ä|J}„e‰-¿=Ø@AþF’‰®ÍÕë ­X@©ƒ–Çë?<¼©>²Õ ݱ1˜2�¾ó‚| !ç$ªDƒeèœM˜Iég‰wÞ®Öûh ¦tU0î8šÏ‰!çꩨ °ˆÒštáÒ²)Sè½$Íë­:ÖÒWU5_‰4›7Þ?“üÍAx‹¦Õ‰ )/íÕ|0m4=ŸbOB釕y½c‡œ¥¥<•™‡m4=ÇÇ È¼Bia2Íÿ—ذ¥¾Ó­/*…ODbóËZ:'“9/ l™géúõ œá˜Æ5¢]>ŒI‡Ò1È� òcFdVG10Ù-^-ÿVä×G Á”–4£´`�ÄJÝÑ.{Ä…¸MŒ­1¤áî9Aáê˜G\� &ÍŒa·Ây)oQðÑÖàâ‘þ`ÌßMš䮋<£Z›ü˜ 7?È]Lš†é¸kÅ@4&ˆ Ë©#ñ‘(HþÚ`”ÚÚKbŸÎ+b,rÊñ#1/âê.ƒ{ð�â·ˆÁŽCB�/ùk¢Æ‡{üZ£™ä.�Y¦¹�Ãç`hcõ;ð¾bŸ?ȉ�Æ×6áÜØ¨µÎ¹ƒ¤Ä†…`b.:ÈÜÂ*Ñäº �A¯âÊ´¼[\€Ê\Ùä¦vDG–??X0À2ÛŨÍB¦¼«!Álü!þT<¥fKÈDǘÿãà”ª§D=Å9â+ŒùbÜ}—…Y'Æñ¶Uv&žB8»þÒGãþÚŽë{…BÙ|–á«C|³C<†çU©ûrPØNé4’qÍ˪Ý"ë±ÕV‹§ÀgĴҵ⋌i¢'Ø¥ØGñÝD×ãK}®×2úví¯Ì褆ï5àŸÄ]ò}\!.ÂÕó5Ýû¬qgÚèþßÄæ-›ô÷¾Ìˆ²ÍY¢ö#¦›JâÉ0`û9ƛܿlZóR'^v£Ö×/ÕòÐ>à&qÁo-ë;:ÚwîÂ23‚ŸÓúƃFUež5ÝêjÀ'qƒÊNìÛ¾œ&Þf‰NÙ"½iñ7öˆ�Ê�fkì¥py�ôл¦âVx½xÚ<œ¦ÐçÒ3ŠâòØnÿ@Rú$U5_/áÿ9ý�Æïˆ6?_LPŽ“/ã ìdOÑŒñE};âK‘£(�tvи.±q¦fxíIãÎù ›nzЮìFÅíb¤÷ÇöOuI°C¦$*b´è“úê)ü>ÂOÒ‡‹Ä¸û©bŠúº¨ù¡Óâqâkw`eŒ/®<ý§Æ^ú;FO’Íßfû_½©¿(ž,³ÄS⑊¸oŒÄ½vž+:ГDÊ~¿ø:숢c¢�毭R?A´ç¤ÿìÛµ¿•¶¹O<‰ZýZZ~OYû íÍVÉ£âU}´˜izÕ?ç=4vc;†›ÝÓ/ Øï7íK|–DÆù�¸ö²»ø¼#ó€ø>` ÷¿Ÿ?Ò§h-’Žðï$Ñá½UQ×+&3[°÷Ac4ôæ_T´}§%áÇ Wóï6Jvf¢¯ªÖ ç¸÷=oBRÔ³§¢Ý´%á×ô£m8|~‚†W2’¬È,Ë1N$VïJYåÍZÇg°õÀTûÉè:*ÂÇø^érŸÚ,wÙ¹š>-Úêü´ÉØôß E¾¾‹´>Ý}ÇÝ"Ëk¯Ø_5ÿƒ � W�*Ûñ€ž÷û"ÿx4Ud…?Ñ @-¸XËÉ%¥ŸtjhÜ¢Ø÷¼¾Ý½ûœ<'^\@P¸a²-[7ê¿G<ÛPš%û£5Æ­Îò8DÚýMüP$b›ñ ‘uÞqÔ…5r |Éq']¥iZBò¨¾ßü›ÛD�^–),Â㉮D¼8u^¨Ñ·uôŸ«i#ÓŸ/Ëÿ�£QkŇM§Šf±RÙ3’c ‘Ÿ¯ŸA'a;'¾œ>ˆä>�'Ý=1rÓ7—°›Îõ?.“—#þ€ä42Md_¥o�/Ð7“†^šŸOc^øİԖOæ`MËö¥Ê†‡ÿ€]½/�³¸IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/nabu_cast.svg0000644000175000017500000002726714757047403027534 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/nabu_prepare_weights_double.png0000644000175000017500000000024314757047403033272 0ustar00paynopayno‰PNG  IHDR )$sBIT|dˆ pHYs––Ú �[tEXtSoftwarewww.inkscape.org›î< IDAT™cüÿÿÿàß¿ ÌÌÌ  <<< L½##¦ IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/nabu_prepare_weights_double.svg0000644000175000017500000001202014757047403033301 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/norm_I.png0000644000175000017500000000534014757047403026771 0ustar00paynopayno‰PNG  IHDRaH楛]sBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î< ]IDATxœíœ{´UÀ{ιr‘5à =L|U€ei+K+K­©¹åC�xÜ9\ËÖUÓ¸™ ,)+E ­¤€$I$u©(†‚B(”<ÄáœÝ{¦³ÏÜ™9¯9÷^`~kÝ5s÷þfß™oöë›Ù™8mZßǹ¤-tm¡äP$'D'!åo'ΘñÁZëêPN0m{`ƒeõoo;D:�zä²Ù&L™Òµ–º €ŒmŸ9qæÌµTT Rˆ„��·¬ÓÛÛr¹4BœeÔ×ÿ¢–ª )ħrÙì?2ŽsA-••@è�b…iYƒÛÓ)D�öïU¦e�¯•.@@ 8YJ¹Ì´¬I×Íž]WäºÚ#eÖ=í‰g¦O?¯=ì@ÊtÁÿB4glû‹µPeøŽ)„Èôxï½gÎ<µ £Èæ�Ð]ÆÃ¦ã\ÔÖvHð?ˆ) ÷M°í~që2rRtÐÎÍe³+MË·ÂHc �Ð)2mû²¶´ %D* ¹§¿7››»Å©Ë»ù逼±À´¬_×ztà!…È$ך¶}}[Øà‘+ìtΦK—yMMMA÷¬"TŸà« 1TÔׯ4m{`\JC�I¥ü5Á#ÌÊXÖ-H)jm€ð÷ …|yo¯^-qéò÷ ÁÁiÀ –uÓ7çϪ¦±�mÝ …ø‘é8÷6͘qt­lÈ+‹tF5ØöØ8T©šÜþù©BÜÞoÛ¶åµê´�\.Ò .ßz7—{&ã8jaƒG@ÇÜ S,ëšju®ÂržîOç²Ù2¶mÆÙ.Ü'´ƒÓ¤”O5XÖ°Xõë: £”ß&„wg,ëÒjt•ÔÐEBóž^½VNpœs«1 À˜"Í‘�®Bˆ_fl{i£ã|8.þO‘æH#-…˜7Ѷ/¬TU~~PgR>aÚölÓ²NªÔ�ƒét9N@²R®6mûÖ±--�«µÁ#Wº:ç`a¥sšJk‚¿Œëb}ƶ[-ë¸J J•Ö'Ñ ¸¹®®nMƒe]ÇàA„QÃè‚”Uþ.§c.F½„±Y!6š¶}ÇØY³N,·€�yB9ôBÜÓoûö5¦meY�*-¨È5Œz!åƒǹ¢œ‹TÇœËÅ9ì<h¬;xp“é8 2–uiSSÓQ¥\˜*¯OGÊ�s: ±É´í›MÛî]v%ŒŽBè$¥¼ßtœÆR/¦ãLFʆ •–ÂN„X ,=(IJ–nØ$Ô`Yý…/×@XœbÎþ\n‘=zôþb˜Žó}¤œV�R!Äœ]uu×ß5bÄ�H9Ó²¦"ĸj–É«rR®7„Ø"a›„w ){J!~VcÝ»%üÑ�r~çnÝi>|_�Pƶ'H˜R­2O‰TêêI#GnŒ��Œmß)aLµ AÞR.BÊÅÍcƼêe˜ŽÓˆ”wÄ¡DÀ[RÊ‘“G�¾7$2¶mI‡ÂCœ À£Ç~O„ø]&L½ñÆW ’LÛžŒŒUaB{‘ÒbïÞÛ'g2oC>„Ý¡^øætFˆ ]»vÆíª�1'TŠöú ÎÉZB…¨Éš”‰ÚU%¢Þ¬%Ôﻣ¤&´#úwG í„焤9jG*y½™3É訠š!ÃHš£vÄûø+© íH¶èÄñ¢?¡J’ÑQ © €4€!e‹4Œ¹ímÌ‘„”rM{Û�������@›¬ÿ: 9ø6ð8ð0àÇGÈú×ó�gôÌd’V>×[€yÀÛnú~à2à3ÀàWî à`0˜tþÚ¦VF\‚ú¸xVHþp@ºaß±Žpó'ÆnÝ@'à?Àk@غîo�wÂÍe=@5kI¸¢ †½QµàÝ*Ëš‚ŠVŒ‡Ä åpµ{¼/†²–;�+€”¾$¨ð1`#°ÚM3€ P�@U£Õ”FT'õ~à=`ð7Š?Eý€s€õÀ‹nÚ'Q�Ú}�É)ÀYÀvài7í(à³ÀéÀ.`)ª Ñ9øªóÜ„º)oNw÷·lâXÄr5²º ðà òm™÷MþùÀ?µt‰Ú�È&zh{*ðgW~'°å¼,°ø1êFùY‚ºiž®¸z&iiÞÐn¡[¶—~§›> u£t›÷’Šë€Û€w|2[�¨¥ÀŸsåDÈ@é}ÀM®ÜX€³QŸÅgÝÄ?¡ñ �q þ!°CS0,¤àþÀ]™%€¾ÊÇQO¬D ÝüÃãA¨ïéøp7…7ëß®ì@×6/}!0UsF—“QOœD /D »ö_ Ü£•±[‚;Ú•¹-$ߣ' qåæè‰ú´ èé»è|-ÿiZ#P‹+¼Ð+@æJ­Œ 8èæg�Ô$ÇD5OßõÉïÕÊ[Dëv …Nüi€Î´ü°U—ÓÝü!ùå8a°+·\OܨpfÈ…Ï»ùh½ºñ<íz;äúùšò*Áƒ}nþn Kôïà-òMÎòh6í øIÿ<ÑN¸ßÍÿj{Êq‰®Üº ›°5à b�{LïóåéT- ¹> ,sÏOFu¸a¬Eõ!¥ð,­;_P¿Åã9”³üüK;[¬{¬vhªã•ul�vE\¸];÷/¶¤�o =ïr¯Gäùy'$}Êñ~whçaa¯9±R¼²êƒœ #.ŒZqŠvþF„œž×§B]~¢l–EdJÑã5½E×?—Á~Ww *åí|g„œþ„w�Q-ñjSœ[ ¥Q}â�8� o‰e¬>‚9£þZâ-8/6P(¯‰Û§ÞÔÎ� •*úîŽQ-ñìŒm+ò}3N'¬Ó΃æúd]¨TÇb«{¬x¡¼—@¯Åé„'µó°y†?ïÉP©ŽÅ÷Ø7Æ2½AÉ–8�0—üH#lO¸n¨àÀJTlêPÀ $ƹ£WÖ‹º¼ š¢öùÑ7qòËm~îž_Npm‹Ú h? ƒ|Ç]a‡ßž0›SäÇþa2Q¿Éãy÷Xlu½Ï(f¿WÖ*€�¢b29òÁ®«€iô.¦0´1 üÓ•u%?Ú„Š7�ú¡ãÈÇ…LŸA)TˆÁ‹,JÔìT¨º[€ì8Mv7ð5òOWÚ•iÔd^GÕо®Lp…ñ¥­ÀW(œóx¼„õwýQ÷çq­¬—�¯£BêAQçM¨ÿ1‚ðÙí.T´à.TŒ%ˆ!¸Þt©CE¿ç·õt `p+꽂ÎñD÷�¨¯@…Kž ‘Û\„Š#ý=Df-ÊýÙþ,­ƒy?A½¾˜íË[DmÄx…³íÁÀSÀ_Pï5jJoÔ‹¢NæENBµÏQý§BsPµåâj�:ñ^0}§Š2¡šå%±Xt’F½·ØCø0ŠsPïmÖ=—J(‚�êó^B}gT*Q}V3¾ðÇÿÕ~B¿F@IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/norm_I.svg0000644000175000017500000001620714757047403027010 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/refCopy.png0000644000175000017500000000142714757047403027157 0ustar00paynopayno‰PNG  IHDR$�½oösBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<”IDATX…Í–MH”Q†Ÿ÷›qFÍLRû1­‘œ1[D�-jÑ¢aA®ú…A¸JÛ¸—¢AD« hS‹VB Œh—`ääXÃ…E !BÎ蜎6þÕØŒóõÂ…ïžsïýιçpefüOrÜú±¤RI§$mË´{]‚)®u@ø<ïs#e’®�Ìlp‰Ï% 1`·™}]ìËùIª“´_’#é°¤’ ßI­’¶fØ@P.iC^�$µQàÐôçÒ¾‹À ’t@’èLoï®,9ÔÌrÀ Ô! ØÜËXÓª, ô›Ù—ŒÈ�vJº‘ö¿^fsX¾Ê~fѼ3³ÎåÿIkÕG%mœ3H*Ëfc>"T˜$ÙïÒ ŒŸ$=&��Àm :½¦XRö9õ!Ig˜½Ì) È̺3|ë�óÌ^âçfÖ#©¸üJ€ûf6š áæfSS»šb±%Ý6­:e¯ëë+¼~—à8ŽZ] «}Ï-¯ßß‚Ùv žåVQeßkkÇ1Ǭ@ â®êïŸ^—Ht qÌfdöÞ5 €>ßMÁf’ɤ©Œîœ/e_e’"Áà Çì]S,ö6ms0KèMCÃ&Çãé-’Ž…GFò•Le•2Çã¹ Äײ(ûÁ`°Úë8]EŽ3¶Ö0ð—E÷9NÜ'M4F£ß\¬[p§©šÓŠ)‡N'm3••“…‚�" …N¦ài‰ß_ºw` é:R› ½�©š×‚G6( ]þçúøÿ×± BCáðU cÚëõ<2i-NYÙ œmˆÅ&\¡~ÃAp¦|òþIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/refCopy.svg0000644000175000017500000001517214757047403027174 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/saaxis.png0000644000175000017500000000635114757047403027041 0ustar00paynopayno‰PNG  IHDRVVUVa÷sBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î< fIDATxœíœyPÔçÇ?¿=aY@vaEñ@ðX¼HLÔD‰Mm'ml;�v:팴ʹ�üÓigŒÓÉL3m§“«´ý'=Ò6iÒÃz´ž1ŠÇ* DäF.•åöüõ�—„½waw™~fv\Ößû{¾üö}ŸçyŸ÷…ø§,ÖÌVÎócmÄl# °_‹µ!¡¢ˆµ(ÔÀ3±6d¶ñk@úÿŸ(Ñ„V¶Ç֔Ј硠X<áç„âYØÉnÖž˜X1 9Êø0ày-Š©E³€d`„©Â~'–FÍv3UT8K£f?Ç»°m íJxjð.¬Œâžxô  \-_$„Û�Âr«þïv…Éûø<¯ü˜Y— ¨y�@ÂŒ•�‰ÊV‹*ÿŠ•�Áocìî ¯{ÐM§!‘¢Šaß«€y“>ÛdÛdD¶ëßQµ(ÁÑ#"¨`¾òþ^¿šiÃã�× UÀµÑ[MØ;3mx(H1èó°ì™;*²ŒÆ$I-‰¯ö#œ¿|™Û���îeê¦ÃÈH™éÉK‡ðAïf�ù’$¥y5â6X˜iaWŠ4½¾K!I™Q¸_܆·‘;XGhO\!Àüìì‡ô;‘í@j”îUÂVüè@L<ÍÀ· n¼.È6™¢õMÑ |Ú¸#Ô_0 ø ðÝѶ6 x 8IྠcΜ”ûõG\޳¡›öJ’dÝùä“ç¾´oßÝMëÖýG’$+ðÂmú ôq�B@Öét¦HŒžDB ›…x"ŸV*=Ÿ--½³`þü­jµ:wåòå%/îÝ{/ÛdªBÌú¿Î1žSU"BÕ?9•ªC¥PDSØ…Œ~â‰`BÚEÀq`E’VÛþÜîÝCÉIIE/ШÕy»ŸzÊÙÚÞ~ùìÅ‹K�.×ã€ø3°Èñ\k2™z'þ%ö7¢|ψ4á˜áç]rrÃÞ²2¥Z­Îõ×Àétv||éRos[ÛÏg�¦iåòåKss�):ÝR|c x8ƒŠâÂ&!ÆÌe©zý�çJKÓU*Õ ï+wöôTµ¶·kó/1fd˜Gï4! ëD W}¡ô1�ø Š¢Þ|¾¬Ì T(B©Q•²³²Öfge…m˜$I6¦®È6óhÙ‘b‘ñ¯aweüM^€Íf–b°ä¬P(½|ü} ÞG“¸òü û Ðdw86^©¬¬ž)ƒp؆XŸÌ3Ä&©äÂÚ�¯ÎÚúúmݽ½—gÈ&H@'°ƒ©âf#Bì¸ �{ø  8qöì‡ÓÙ:6ùÃóDvá]ܸ‚ ^Ž:�ÎÌc§O[Åj±bâW½ Ø…ÈïzH(aÝÀW€¶{÷ïV×ÖVN³Mþ˜<†v ’0ždw1`œQ‹|lHÛ¼8,ÕÕ›îõõY¦Ñ&²—ϼMNˆôa "ð(�N£‚%”$ÌEàm@Qqõj$Yÿ‰È6›­¥»§çÊíÆÆó ÍÍ—ôõ]w»Ý¾}_³¾g̽Iœ$¿CYþ–Ý`±¹¨(¢DõˆÍfknk«©ª©É|8<¼ˆI•Ú’$ «T*o¾³?wª ‘—xñÀ¸#±1RBv°6]¯¯Ê4Ö†ÙŸ»¡©©þ¢Å’ít:=‰'âIë}¿J–å<‡Ãá­} ?µ xȺô1*V‰!—?ؼ~ý`í¦"ËÏ_¾\»©ÉóG¹ü Qtñ`ÒÕ¹ˆÔã‚IŸt†lÛ4àHlÖËB®@¬h<kµÚîyÙÙá<­ö3·šZZÖÃ@9ð[¼OP öwõž°q� 1¾ýð%˜#E§ë6fdôšÍ²!'©ën4µ´¬¬ˆqðj˜ö&”°o Dµ¦èt�Ù&ÓH–ÁàΘ3G�ª×g$iµs%IÊ!Ìä´Ãáh­°ẌÉäs/j°îV\¢B8ØCŸöÙ½NõX»ª¶¶K–å…ÀoË;‘�0Â*Ejý):]Ô7§É`¯»}{¡xËOCo>…„V ËQ¯Šir8�së_Ñ(bK–5M§!#ãÁÚ‚G¶Ér¦öÖ­ŠKׯˆÂŠKA4»ÆÔU×/ µÿX D,þ�ñ�óЊ¨}M’].WêàÐPVÛÝ»ŠUf3Ò„ŒW0d�&ëÀ@eŸÕš |Q`Áwv ¼?±gÅo¾˜èp·!¶R¾|Ø‚xšç#2RÛl6ÓÝÎÎ�%Ðl{챂ùùUˆ®·�J„È“ÿôÀa¼{ 3Ɔbh p"]¯¿±wÏ3áíj”Û;;oœ½pa¡Ýá˜3ú™ ¨ÚžÉˆ?¨7¿£ß'`9åîÏÛìöµ çÍ«Ô%'OÞ® Rš^?·Ðl¶ëõúZ«Õj·ÙíˆïRD‚]m^ºôzRR’º``ò~Ù¿!* ãžPŸºó@ѵ›7SJ¶n »SI’Ò–ææ®[š›+ÛŽöþ��žá‘—B¡Ðd��Z½¾ÂbéòÖ4ìNg˜P„}±;Æ]´jU´ü]I£Vçd Á&ÑFØ`³E ËÊÊ¢Õ«Ï †MÓh“?f•°jÄÆŒ¬L£ñòê‚‚�Ól“?f•°¯OªTª¶ÝÛ·gE¸÷5:¤ $ì~ıw#{vîlR©T¹Óo’_FX“×ÄÁ¸l\³ætFzúŒB®T*û‘×kÀ)Ä*oíLÚ þ„-æd çWšÍ3(®$ �¾û±Ï,¡ð7Œ<Is:�Þ|ÊiEv�-høË'Ä-þžØS@ÃÐÇ«?:zôæÞ²²f•Jåm+�7œ-Wëêë“‹ �F£± äIO–=‚¦#ÊõÍ„)Æ‚„UÌÎÄãÀÂ䤤†}ee µF³Ä_›ÝÞxê“O¬]ÝÝc)?ÏÎÄeK–uÉÉAíL¬°X,ŸÞ¾½^’¤û²,ÿNqƒ øB0³ì"à`ÖjµíÏ•–è’“Í^®¹uçNe…ÅRàv»ÓG’¾‡(ÿ+n[‘ŸoylÆõ�:½xõêÕº†† åååäääðæ›opèÐ!¶mÛæ·ý«¯¾Jww7ÅÅÅ8p`ÊÿïÛ·�ªª*t:ÕÕÞw[õ÷÷ST$ªMwíÚÅ;ï¼ã·Ï+W®ðÒK/ÉN§óf0!m bo՛Ͷñƒ#Gz>SRbÉHOgpp°ú¿çÎ)ûŠG?: |±Z @ˆûuà…Ž®®9ÇØØzðàAŽ;Fk«Ø´“ššJ^^žßÆ.\ ®®Ž¹sçz½V«uÍ’$ù¼W_ßxayJJJÀ>óòò8|ø°T]]]l® QŠþ¡ËåÚñ�ãÇ5ÛŠ‹O™²² U55½u O ò¬€¿c\7â‰?ìÌqËr¿B’Ò¼ô3†KŸ³”ÊxZǵUJf±|ó®,Ë/œ¹xqò‘!ÿDdýÛ}´—�j`ëððpcÊøÒ¸÷‹]Q_�„Í›7“žžNR’ï½Ó*•Š’qðš5k|^çµmˆöØëN�Àˈ�³p÷Þ»g’aØ_Ðàt8"ª%;tèP$Í#f¦Ë"‡€Y–çuuw_ÄO¸êpMóì5MxF°Xœû!ðÃc§O?®V©ê>\)»Ý>„œ image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/sadeltabeta.png0000644000175000017500000001001314757047403030010 0ustar00paynopayno‰PNG  IHDRP[äÖnsBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î<ˆIDATxœíœyp×}Ç? ‚^/‘”HJThš)ê uE‘ìêJ-G‰ÒÊ3©•dÜ6‡�4M]×é1nÇ'±Ú4™´u’Ú�LãÆiçpmI¶lIÖ1i‰´u…ºLI¦xS")‚ıýã�‹%ì AºþÎ`¸ ¾÷öí¿÷ÞïzOaú£Ø ¬î €LÀÜz€ À›À.àXrº9õ� ü'àTŸƒIèë”C*ðÌüô&²#ÖD66‰Ø¬ÒÜÿ ìš’<€ Èæ‹€{�²IíéÅ „JÕVu×LH�¦öJ`F²:bIÖƒãD‹î~Ów:J îaìâpøKàCIì×´Â?1þJÛ üøs`~²:8Õ¡‚¬¸ÑT—7�m�: ;ð-D… å%2‘€Â$ôuÊÁ¼Â(1íÀýˆÞW <|Ylô$¶³&¿ËS ?$Ô²X4N¹à`ˆPO üÿ› %ãu6n]½ÏOT§2à$£$œÂøÂð¡6›¨û¾Á:BIxÔD];Ц«_o‡¦›%²YwÄDÝ!àEÝw«ãëÎô#Pÿ§MÖSw_G_€©MàjàÓ@Žæ»b͵è3Ùf«îÞC¿B0• ü,ð¡î§L͵;†6oéîgÄÐF’åÁX<̋Ї  ›¢ù®È \;‘UT5ñÜtݽY ƒd¸xH3X^;Jzµ"R€\ Óijót÷q»÷“Aà×€´¼œœÆÒÙ³[-߃KW¯æw÷ô,$TW»ˆHo5È�aµºûË&ê†E2\øÖ¯Y“b·Ù>:^!¯ß_ßÝÓ¡x Ø¢¹_‡97êîãqNö"’ÌTå²-5u^”²Á¹M+�ûte¶##X,ÔÜw!VM\˜läæÞT%Ú$PÛÇ7�zÍ}ðUÏM¾£ûî?U(.ÄJ`>ðuàÇÀç0.ÕÅ……±¨ A|Kwÿ$ðñåSïÍJÍw·€�£u€3MÀãÀg€g€`™�ºÕyyF ‡_ÏkîSß=M¨û>™óªkã+ÀõŸïžŽOš%ð#¼º»ýÜܲ²Š¢\Gˆ9ŠÄ)" Íj€ì¬¬l³½Öá!$´„x1퀫À °‡Ð<ˆÄþ8Æç®BæÍ¯~ × � t(;?/¯~Û–-®5Ë—ßý©­[ýe³g ¼Ä£@#B´ň âvØíE1¾@}H–Á¿#¹1Z8�ÙŒU�z�/ #Ç,Ò©;܉ŒÀÀ×�¸ø%�VVRÒðû÷Üs§EQf¤Z­%w¯Zµbóúõo9Ž$[ê òryñ?Þ²2œÎ÷EÉ ÿS¾,~ܧÜià›�~=ÃsôR·¸ x Œ9Aâ Ê‚ÊÊcuµµKgÑð«jÏ[MMOŸ?¿™ƒTÍ3<¹¹Í‹ª«ÝE3g.‰öÐÆ3g~{ê�w–!?ÞóÑÊž3 e©ê†CðÀ_!£«x�êM‘~ a\]\SsxaUÕ‡‰°r[ÅUW[[wGyùÙ}‡eÜ(Iw:ß­­ªº:§´´$55u"c´*2÷]M@[«©®@œ;€oFí‰Dàì@%ïòÅ‹�ÜYQ±ƒ.ð¬Ì̪­÷Þ{{pxøZšÝ^ÊôɈrϨÔþ8;^…HÖÖü¼¼CwVTÜmº+ŠâL³Û�¦ë%‘9² YÁŸ@¦.ý"‚H‹ÈÀßÑÙYÛ×ß·É3…‘…,x¯"äE¦D!"ØŒèKÙ¯ìßïô«ª·ÑtÁG�w�§økÄ�{ÎhÑÔ˜?Î ºÝ•GNœ¸„,ãïd#R·(AÒ…aPê´ˆFàðI ïrK˲–ë×õA™éˆ{•ºAF¥îw±4fD‘>|àÀÑ£Õn·Û°xO1Ì@¤n¢aF¬;ˆcdµDž~¤ªjúîýûmªª&4Ó= ÌÄ<ÆÃ}ŒJÝ-Ĥ[‹,”qÁŒ-üe ©¯¿¿üxCCÜž$¸©{‰¥ìAÔ³gHÌcÊ¥?ˆÓ ­VkÜWa £«ëwWZZx¯­-ãV_ŸÓ¢(Ž\—«mniiOo¯m´hL؆¸¸ò‘K�ÏÆÑ^X˜!0xPQ”þEÕÕ1{STUl¾|ùt}cc¹ÇãY¬ýŸOUiïêÊmïê ©bò3�þ0pÿ 2t¯ÅÚçH0CàC@zå¼y‡R­Ö˜öZ¸‡†.îÞ»×Ú70Pøê 2©F²_Ðû=xɃ‘º‡�ÔŒX± ñ:od4]N‹nD|š(ù3ÚÕ6áÞv»‡—úÝ•F$ðI„¼ëˆM{?±“§ ºˆ¢Ž<�¹õÄÍõ/DàfB³³,Šl?žœW¿ˆHFà/Â58òbªIG¢8Žà¼ZG3¿F¤.^òªTÿ0‡Qëg"}Ÿ!TOý ¢#��V2N`†Ó9[Q”aÄai4#5ˆDo‚ù¡#î§À§�€¿^à¿ÝeA±1° ÄYU¿?á>>EQ² òóÏ#Cb[ŒÍ$Ê{¢ÝcâatçÒxØEhldm¸B–@¡ü=^9{á«�==¿öx.‘k�¥55AÉþ&¡YöÑ�H ,@†j‘9/Ni®Kð" î/Û;:>ÜÞ1’¡¦¤¤´æ¹\=ùùùù.3²³�™ÅŠ¢ä„kh<äçæ.Èq¹Þîîé©AŽ&ùæ~œDH`±î¾Ñ`=m&BØߊا+‘ü"drù|¾â¶ÎÎâ¶ÎQ%¿¸°ðì†5kL¤nZ»6ý…�;;½^ïfDùý,bøGBP1ôûAŒªAùšë°S\p©G4ûUÈ*T„è^#Êä>`à½7*Ýîó>›ÍV¾eÓ¦«ÕÚ�dk�Dv!�§F î3Ox¼Ð[YCaK…ÂBhÒhûx…Âá’Àø$²É“±œ:}:lCÑ�™ž^µí¾ûº\3f¼‹Ø´Ï—§Àvd’^…䦜gt‡R²ÒCþ€Ðmfo…+dFÁý!Ðß|éÒ�ד{Üf³•}lãÆ¢5+Wžr8]ˆ~øDm8€hþO(Šâp¦¥ÝRÉØŽ6 øgÝw/‡+hÆ|s#C{µŠfÎŒ).¢@Š+;»°º²ÒRZ\|Ön³]÷ûýýÀ�Ãn÷TÌ�Û¼nÍ¿ªªm7ÚÛ‹'„Ù]™zÌC¦Œ ^#¼�kA¦˜_ªü·"‰©ô6=2ôCÃÉX9.WMŽkŒ-8l‚SEB£ha° ´W"ÓÈ\Ýÿ}HP*¬+Î �ßæg8�–/Y’gk$¨£«ðDø�ÈÈ ‡[ˆÇ~çx•�Î/_>­(ÊÍÍ6 +àx�€‰&0Ö!S@X!p�4ßu«WŸrØí“s”’ªN…!²�Eî ¬Ó§hC¸™Ämåå¯Ï**ZŸð.FÇDK`"H ò¾åHŽôŒšo6d‡Ô „ÈD“ÀŸ³2ÓÓëW.]ZÇûó˜�àAµÝˆ_`7bÞ–#û^´+ïcˆÛk‘\l°X,­›×¯O›äyT5ÙsŸÑµG«(H(`‘,(›5ë¢}²æ= Ô°—IÁÓ„Æš�i‰ÀzÀwùêÕïœ;÷&“ýªÚÓÝÛÛDŒ[JÕQ L6�>ÄB Â�æð²H‹H3ðwÀS MM÷x¼Þ#‹««WaÀzéêî>¹÷È‘\·Û½Ð™–öîÂùó¯–—””¦Úla}já &k¡÷9‚ÑVሠ÷ݦ3g>âñxŽßµxñeœ­^>¿¿íh}}Ë¥+W‚ Žÿöà`Ùñ††²ã ž‚ÜÜÓu‹yòssÇ;mmSHalônĵeDübGzÎ67¯8pôh£:öüϵÖÖcÿóâ‹ê¥+WîB^úD-Ø‚Är•ö®®¿=yÒ�hp*¨]¼hü‰F-‘ç‘Ô±Û-׮ݵ{ïÞs>Ÿ¯àöààéÝûö5î;|x¥×ë-DÜàË´ ñbÜ�ؘžîÞÞBUN�Œˆ Â1þîs ìsà$šþ›±…w›€—;»»—ýü¥—š³33�ttw× ‰�ƒÈ1ß&¼ùpÎï÷× _¶Ûlz£=þ‰•ÀMÈôô˜�öŸ ”ì×µÿ4ëk;‚x,®{<ÝÝ«òÞ@”xŠÈ.øF€¾þþ¨1^Õ?²èO”$>Šì�/aÔŽìÀ׺Á†§ÊbÉLhB‚Ì"^ŒýÈ>3#/ÚÐÑÕ5œ—9´2IsàV$]d'24¯"ÇCU!Á/ýY«O Ëz�5µ£‡±ÇˆA@k[›­ª¢"bA �½½,!2ÚyüÏ2öÄ�Iw—7Üèèp…¯ÏüÿDHà÷�Äv#¸€ ãχëËdýÔ ´{<žÒ¡¡¡³v»}Áx=^ïDJ^ âã\ŽìØ\ŒxÂ�@?¢=4!$ Â��Œ³³ŽŸ|õÀ�Û•óæJ±X,Š¢øm©©U3"nÞºÜâ0‘sà‰ÀgZ¡‰/D;¾=øI„r£®ÍGÐ&� ¬–"Šv¤Å«‡æxÇ™L $ëËsŒ“°¨A12÷|@`Œ˜Ôý±b*B;-ð�qâãÄÿ$ì�"öyÙìIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/sadeltabeta.svg0000644000175000017500000003457014757047403030041 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/reconstruction/icons/tomogui.png0000644000175000017500000001527614757047403027242 0ustar00paynopayno‰PNG  IHDRX�Ø<Ö cHRMz&€„ú€èu0ê`:˜pœºQ<bKGDÿ‡�Ì¿ pHYs  šœtIMEà  Òúš;#IDATxÚíÝ{¬gyÇñ߯ö9¾ÆqÜØ$&rO @b Ó¨Ê%EP‘–ªUU¨•hå’V¨…JTíU«¦U%*(4€ªJNÓªI[i äâÜš˜$M0±cǹØNâÄ·ØžþqÎî̼sÙ÷��Ý�gæûñ>»gÞ¹ì™}öyÞ÷�Y ÐB½�Ñ´w’ÎìM{ WECQÃîØÑã¬D�“¦½à‹€À ’ïVkZ±W' Ç."Ã`ŸR­ÑælÊ9Wû‘a0ƒ€À ’h£(ýP&¶ 3XÌ a6`ÜåßÕÓ>@Ç–1¯Ÿ2Ñ.2,f°˜ArÜ8ã)›VöU5žr‘"Ñ 2,fðÉÒ£çUmÉ¡ª«#û"×j62,f°˜A2,f°˜AÒŒR‡ÓB†À "0¿ ‹¼ªür-2¬º�a0ƒ€À RUO‚(Gq8 dXÌ `0ƒµ… BùÎÑ¢8¬‚ €,f�–æ D7¬3ˆî9Ê3,2+„*˵ȰB�a0ƒ€À ÒÑ„²R°«…à5cYë·§}XSCq82,f°˜±pÚ;0}¡·–Оû6dY- -¼Æ}l]+Û~�†3XÌ `0ƒ€À æa5ë„êZW{‘a0ƒ€À ã%aïÛ€P”‚±¶Î¿ê#Ã` €­I Û|‘N¬©ã…Õ‹²êGD!¸%ç9JBh3Œ�vMÓ&“N¾,£ì62,f´&ÃêÚŒ¬~¦ÑŒLkôãÀ(ÚÞÕ#Ã` €,f°˜AÀ`F G²£„í»D'Ï4Æ 㛼.^�#Ã` €­™8ëÚÒ¾É]¶C!Ø Ý)cdXÌ `0£ÕIeWÇ cã)) §!;:HI ÖÂNwIJ¹·$†edXÌ `0£Õ%a¿S²[ó±Êåv¯ñ\MÐÅ®ö3XÌèDzÙ�/YE1û*� €,f´z”°¯«÷o@›t»ì#Ã`FÇ¢6Ýï° Û·A.C†À 3:Ñé£û¶P¦‘a0ƒ€ÀŒÎ&œŒ¢iŽ €,f�pòÝ:˜* ÁdXÌèØ<,LæÌ3·O{—`3XÌ s/�î÷M%¿»Ý«Ýí¥¿ [k»qóã*Ȱ˜AÀ`£„ ]ýâÕM�KÝ^Ò²¼8D…`2,f°˜AIX*ÉéÚx!ÆcËè«è42,f°˜ÁE)nóW®%äŽ u¡ -TÔSć�uDyO\¶Ót¡ÝÙþ¿ªáÏ�ò³­¢ù€]ÎÍ:|èaXÍ5ÊÈÛð¿â–Ê­Cö+„ʦ/w7duöÀ³òO�âÙï¬&¨cš@Ù_rØúGi›–Bî¶èjÈ¢k^Ñ Es§_ÁÚ<ùá­zQuP‡uLÇtBÒ-Ьk©VèúDîzÆûñÓëqÞÔƒ€%©üdê‡,4‹®®×�Ú£ƒ9KÓ1ÑK’¤OêSZ¥ÓôHÎÚÊ‚–{ T�>akªo»í@À‚An°ºTÛuسm¤}Ú§žVèL=쬕2¿éÈ$ÅVúåèš ë]à4Ÿ¬t¸ºX�ëxÅ5-ЙڞzÆý[ö·U”édÿöEs®òϱag™ßÒÝÁLw“ oÕ=Z9\IÇõ3-ÐùkGó°`J2 œ«»¼ Áb'ô„–è-Ó>0x¡+Xv¢÷t˜”d¸Z­}¹ËôtŠNÑJ½W_N=¿A¯hŸöéXN›Ãº»Ö}›ß“Ž–mãDÀ‚I+çGýÒVë,Ý[ÐâžùÿoПj·ŽNûP Ÿ’Â:Ý‹['‘kÕ/ÎaòÂÕiz6`]—ëq½œz&¿}X§{VÑÙB§{èÂq¸Z› W µ!(\I÷逮ÐâiQNDÞØÓ8r°êÛçÖ±îxgBÓŠÜòpø„ƒ­’.Ðã5%&¡£‰e,]Îå—„ÅÜļÚåÕCJÜvøp|ÑVª·¬²¿£ýn½Öù»œ¬ƒÖçî× ºN‡4zIèÛq@I8ŠŽvŸ`BVè%«ÅªßªäêBC½A%|½áGïö^ͦ&6øî§»kôË„Žöœlx XéSg” \ë»îßo+“¿Tõµ÷×x…îËüæö0»—¯Ìx'`5YG{Ný+o�;õýP7h™Žê¸¤…Z¤¥Z®Sµ5³®êeۜ˵OtPÇtB 5£åZ¥ŸänÃ]ãÚ¯uHÇtL 4«e:UßÔ¯½+ßÓ+´O¯èàG¯u™sqóëôÓ ½óy]Öà `Õ¡£‡=§è¤ðl=ÿq†uT_×ßëG%ë8Ug99CþÛ.ÿm“ÜØõú»Âq²St¥nMm#ùF½GïÓ³Áy….JM© +\߬Ú_ãÑ_9˜K5gQb6UÕ7d…^KHÀš¬ŽöœºV:\}]×ë)�õ,Ñ%©l#ï­7,`�®=C¶rºv!kÝ [{‘^¯#Ú‘Ñ{PÏê‹Zæ´Ù&IZ9¸ÉÊ\Ë�©ñ·ü–îôˆX¼¯«3yÒIºD‡õxb”òV=®#º8sê ;úômú– ]DÀª×§2ß˾Ko‹¾eê�Y}AGÞâæYÏëo6Ö÷[¥£z(w‰/ëe§çê°Öë’A÷{yËtPxYç* ¦—eîPµXÇçC¤ë'º3“g=¯7ëÎãS^§á¶ þÅz½^¯«]ÛÍÕé€UÇéØë%ò«Óœ{ÆI{õÎèþ¢¶Ñ]ÿ©“�ç>?øÉ·,\Sp#»¾ÎHÓcz̳åËNË�¹KÅûé~Í"*YûÉt¡ÆÁm‹ó¿;¹B袎wº'ÃMµö©‡ŸÎÄŸ�F�e—�·y™¾¦§¼ ‹³‹|,u:£ó.½9WO$–èOQXæÑòœÔW4¸ÝÞifîå¹9wýÉ@üfg*è±Â£wCßrg­è†Ž¬l)^fèš–êi穎þ=o=É0ù!é½'¹Ôs:<Ÿ¦þ[»ìMycâçôrñ|öÇsfšõt›GËŸ¦Z× 9_CÚ·Ýy|z¢ß*¹þ«Gvwf2èvås'¡~L~ÂGý(›¬Ó%a¡îƒZ™úÕQ}&~�îI½)®K÷'ïx“�QzéoüÌ)9-7xµLÒ_Íÿïaÿ§õN~ÕK̬/[¿{9Ñ«ƒýJ¿ nÀ*œIU&)ð ÍMFÀªÏ5Î㊕XöS;qAÏCîûê½7éûõÙi wy¶L (\n—ó8*Í_üìéÎoò/g:¦pUçT²š‹€U“ÞŒÞéyP†µL�1¾R¸œ;·}�÷Á»KæÏ’¯þ݃hV]®tÞÛûuKÿÇü^‘ij7§Á8]ÑEV]¢޶VnysêÙ¢Ùè79e‘îtÖS¼…»�ŽÔãº)géQVÏûšŽ€Uw¢Ð#ï+T¢Cº#ýÌ}^íN­¼³«¼—LÏ‚- X_iÏÜ¥¯¯|\h;V].s?ÔÚYú“ƒù£e“¿6ÿøÐþÖŠ-ÝëûŪ۷u²ÇºŠ—î§›ÉRxAÐÝI h V]Îu?Øÿ¡8à$~óÀ�µåªžaUUt¡µÛ·ÕAåñjg龃9ˆ,´UççaÕÆ½‚ð± ÖîlÉÔÚŠ¦·ö »²/¨˜ wÒ�_\ß¿8ïy7þ[Xpò¨n!ê‹;sàÅ Öî•'k|-÷Yh"Fûâw7Öçõ”¹_yzô9S%êAÀªËRçñ� ÖnÀZÔzêê�t�·67`}ÍgEó|î¸Q�h²XuqßQ/µvó± ïP/¾¯À¤ ¦zV^OÙG�Ç¿\ø:Ä&tðAz¼ãF¡Fë÷¹ƒ°Û<ÚֲܯÜ�­¶šÌ=uÈЂ°êâö�6²ïó…3 Rï^ÞI¹Þy¼ÕgEu†,·cm¦ÒZ²íŒý¥§�QºtîwvæìÈ~p�zÞ›sXK]%ã‚À¢0½Ý'œß®ÎYîb-KMžxT½3¢ÝÅG^öªTêy:ì”éþsoÓܹ(‡÷†ÆPdXuyÎy¼2¨µ»ô³A­§®jº1ÇíÀË"=I?ï>uUÿ‡‰t|¿à<þš‘yîUQ/TYIw°êâ~OéA­/²¶†sÇ®œÿß/ƒs§¬åÎûÜ'>2ÑCtoGqVÅõœã<6ö—ž6Jº<á|áàöäQTT²$2ƒ7eÖV‹awTõ¹}a¾t(ú�þ6õø=Ëås§ùß:¸O`¯ïݵë´3õ{Uom4Ôâ׸6îý¡Ã>�bç;�}¾dX¼ÞÐÿë<~£G›˜° j=uî^Øîg.»ÌmíRêþ­Z¤ß�à!>ì<\ìîsv$–q/’hxkÀÍKÏ+Œy´|›3'q¯ k=øý¬^pZ¿5ݶ|ÿªÙ¨-'qô‰¿Âû�åö럿‘ï±å½.…ÛþYÈ–Ë>é¬ç½ùkñßCtÐà4x5uz̬…z©èTÌoŸøí�–/j�±€5™£?I�8ËþuE^Gãsl¥kµŽ;K_ê»åÄropÖq\§°BP¦¥gÅ\ ½ªï9O]ãÝøW�ÇÿU¹#ðMæè£ã™o]ÛÛœøý߯Ñó©o© ;Ââc½3Ú[a-躂„ýBÿ +ŠôçÓð°Î)þ Nüæ"uZ~Øm×ô k2GEQ¤;œ¥÷h]”âÿ×ɰ¢HŸu–~Z‹}¶šXf‰ö8ëøLÑȰPbpÜYTÖŸ(ƒß,Ö>çôúN~[çÙ›�VÏgKѦ¬É}êM©9-ÖZŸ¿SîÖ=^—Ásk3¡õs¾çÆüï?ï´?ª5Em X(18 ¾•:=¾ ‘lEú#÷ôÒ/ ]Ã2mþ°øMÞÜ€5Σw¶óéL›Gâ\8LHÀŠ"}ÓYþ�Þ°­7dBí7ò�µøÕ'`ARâôH§ýÿ�už†ÉúTíwN°gtniëK2-öæ�|埾>'ï¸[Nâè�íôôíLÈzI¿î:ë Xçer¬'u¶ç–ÎÉŒM¾:~¯> ’§ÇFçùËxĪðTLžÒŸÈ¼•v ër=�Yþ·óNâüÓ×çäËñ}f;³º=Ó2Ò´Ñ/xDQ©§8…¯K¢ÕŸd¶ºgxEz—žÉ´Läᆵ> ’§GO»œSd›>§wèt-S¯àdLžÐ'é{™óe}:›©iFŸÕÁ̲·&·’³ÍXc:zw;Q¤•úïœ�éÇúxÜ/T>.Õgõ@^û¡kF÷ç´ûŽÖ—lm½¾›Óæ>ͰÂ5ò&g“Ÿ½/éKžmú-z©ökuoηˆ>­Ðèaí•´Z¯×»õZ›Yj‡ÖGƒ‹¨“›ôןþsE9KÙ8[Žûè³Û‘zKõ½?wÇOh«îÖ½Ú®�Ú«C:¢ÅZ®åZ©óu±.ÖÆÂ¯øˆ¢^þÖGx¶~œù²jIzDÿ¦»ô¨v逎jF+´NéJý’.ÉYz·6F;|ŽÕý•Ï_­—ø¬;Y»s?»K?ëRŸ¨¯×s~kÈ¥3·ìþ51ÃÿÑlé$ý�ŽUÚVþ¿ûôv¯ìî2ß3¤ðß®t¡ìÿê“aa^âôy‡Ž„¬Ì)ýdðIüS]R|7;`�ûè‹¶Ez»¶Õ¬žÔµÉÞÊòíêìü‚Òóß:Ë?4°�+u mÊôd XÎNÓ­A'ñ¿juÙIÜô€5Þ£/ÞRi¡~GÏ�¬¶éÚdRѤ~?«¯:—qùý{U_Mo+ìÕ'`a u­Ðµ#,`eÞJ¿©§{�¸ëè´«u�á±' 1¦°å”M@%ƒù×N;y„™À„/nòFÃ<“*¢• Ñj ÷´{÷¦ÂŽ"U%CñÂrX£•œ¼G©{Ä Ï£zæ™Ìgm J_|@ïÊê\Xuó€‰qm`0d,-™¤U| Ø&åü· ×YŠp7ÊÞø¸]ʘïI¬ŽB ¿D9ef=XAÊVáUùL«ØÛE³}Þ÷æ‹8KÏé<óñâY”wPi%w¶ATL.@K„Jo*ìX¹ì‹{W”©æãˆs; âÂJSÞJøä ¾Êà$]ň›2…«´’oeé"‰SŸG¬Ž•X3€�€Ï€k³jûÝ IÒ�±]37"ü ˆ �3e‘ ¤éðPì›ÕõúÏ[®ŠK<+Ÿu´ ÇàRáη¤s(–©4¸:ÖôÔ¿÷Q=ûIË=«p÷´�<ƒò?à>йÍõ“ë’TõÔ_| ¼ühW$Õ-±´Š½‰pJ#Ê_drjýGgÓƒ^Ò‹�ˆP„�XK>`Ð ¥„”í–d«Pj€�øÙDëåBëûö¸�‡éCÀÀGP&±Î#V®H5›})äß`CXEYˆò†TðUV?SMOyUÿ[#SÙ쫽ƪ�ôú¢ ú" Dè‡ÒôÑÊâM-°±6l5ÿ74ÃVkr«k€æ0D¶8È î�Àïƒ^�Í¿ž�¡_WèÝ%åéž.”k\ê~HÑ2)g^®Ç#¯£´’R|ôFé ô&Bo z¡ôAh}n’¨‘~Q�QlÒ! _ךk6ÃÚ-°n ¬®‰‘gƒE¤õµ1µ'J aH/ÖGŽ‚3C8 8@çp¨+©£¢¡`·Ÿ ut¦3�‰P tJQŠQº#ôŽN;z[ïûZŸõŠÝžk{¬Ýl’åëZXUcþ_]ëjíß5‡óï!*;BE ó7©àl—úÕÇ@?ë£ øØO&±!çÄÒ ×!qŠ(t±I2¡Ä6ÀJ7•(ÕUÌÿE@©E¢6;èZ¦äh�†6l5IÑ*UÖZR¦•<!Yv6ž»N>ÈêUe¤Tð… wÆ0ü\„1x0[+RCÜŒr=ð!>Îh/RŠÝG5fƒ†f¨o‚ÍÛÍ×Û¡¶Þ|]×[ëaÓ6sºY¿ÕN õ[¡fÛžgTœp¼r}ô�ž.å<Ð᪆P§BL“rnëÆÇ!�m�¦¢ ɃZ×Í- ¤i޽GLÒÔ7™ß퉤h¬Ûb{Û£ÃO¸�¬`3bEÆFXÛnÊû/ÿÏÐ|Á˜Á¶·‹¬ÞÎ4rð `Ê/¥‚¯whºK‹VrÊ¥¼I9/´!„:¥ò®{ê@ú èÖÉt ´þuëÝJ {)ù¡Ð¥Ö²u§B(²l®n%`Ä­[lÞfïÈÆfÓ ¨­‡ÆsêßÚ`Î Û¡f{ìu}ì;fŸûô7' " kuÚj5…4òà›q§XN‡È6¹Ô¥&¡ŒCYF˜;³YØíÜ mE‘ö£À^½``wèÛ úwƒÝc$ê\œ——ß„ðcÛJ@H0”F¦3\èRSPæDE‰�#€Ó#˜�0ÖFÊpfRé†ác(J %,’ ¸r¿j%ÃQú㣎Bþ›¶�P�r0Ô&máO.»ö`Pb½¿GÊ-ÉÛA�÷nC}†I0‰ä÷¥”Ù ¥a³Õ µ–þ°Å2m7#(ÊV P~ ÙÚ}/6¥X&üý:s j)¢¿L ^çr ßÃàýlâ½u6](ävàÛÀ:„û¤œ¿§Q†÷G™e}6€[)ç�©v=kˆcP~dSÄár ðT"Áà”1ÀR|ü\&ñ?×÷WÅ"œ|$[ÌWÇ+�ƒ´a ʰþL}ÄüL¬Ï” ¶a ~¶ ÔÒÌ© +o–å¾`ÿëàÓÕé�ïÓÖü.ªK…$@À…”‚ð= –&^�ilmÓÌb"¼õÿ$ãN p�ÃàŽ%Âó8/U)p�øs›®IBŒö'Â;2™·s9{û1¬pX¡%LÛdBÇο)ô…V±Â…}ä¨8]2K& r:ðXtP Y¦�ð=™ÂÒ6 `0 ©®ÒOI9oFÛÍ¢ªH½þ)ÀýZÅËY/ËTSHˆÇ�Ó-íä.©àê\Ë�2–IËd¤Œšœ�Ê$Ö~+7™á(™p؈¸7ÞÉ aºÁ„A�Á½Y_g�c€C2ÚaÊOlŸ”rfèN:”aZÖ×ÔÈQRÅ®à* rlΈ•î���˜&õ'.“õÛvPG1Ÿ¦=8Ì0ÌEñÄá?^5ËáH—G–ðàܦvî®ilЇõ;1^¿ŸLÏn†ç¼~“sÿå‡ko†1#&­r×ä[ã/ßÏh‰ùhI¡IÖe“ZȬb—TlkÔiöf“i9‰�ºŽ®KæÆ¼ýÇÝáÜù±™"˜֗n$Ö f4¦õ´~äbˆƒc^«ym�nwQ'JÑÅ;ä³J?ï8ÝÇ6"<Ýî³KˆS5Ä[´«?ù®�Úù²K'+b�hˆŒ&·L ŒrD•é`.EÎ[¸ô~Š´šnŽ?ÖÄ à";ŸP• 5Ÿ–²ðx Y±Îq–fRÎ?®ˆûýuD(sÏÕ]ø1”£€ŸjˆI­ÿñU»äÊb©¹4¢ð¿Õ.ˆeW�G¹4|%¾M])¢TL‘ Ô'XŽÇk�WèA-�lÖ Ë5È-ñ*ÓØŠrE†Ó½F!�ÙÎ?‰u(¿ÈÐî©D“VrŽy?ÛðS¯AÞ× SÈu/EôÁ`ƒ,“³“VäB òŒ¹<å1÷'…=äµòŽ˜kÙ׿Š&ì;ÀFÊqY�j[�,_ r!ðà„8ýh0?¯ëìØz TD˜Ž/cp¦“Þ'ü ¸-ïG)ŠIëšîB¨¶¬ÐÖ±:xXƒ„ ™@½”±îˆóõï†í–˜ûâ€AÈ¢U1I¥Š¤òÓýv"rÍ£y°�P+¹Cƒ¨ÑÑQHÿ7ªŸy¬Q­L/…šÿÒ*Û6±Œþ„‚xRÎKbMa ¸Êº&g¦¸Á¾1dÆY ƒ'›“ÔÎE$©?‡kŸVý*âÂÞÞ'5±d"+€Ë2üÌ2Ͻ+. ¸³»LP­d6Â�ý?[~­b£‘Ëm÷.|I!wµ¾=�ž—ÎåÃKçò¡Y�p ð)�c»–Bê}9‘X–%1à󶸌6†¯ æ�ÀiŽØ†ÁEym3“ô[ÉÖÓ•6L ÉÚÔz3Âã¿Âà°øl€7ÿ ¦“I€û¤œ ©HåÎxÍV3¼u^^ìRqÒË&íÚT¸HÆÒ¢³9…B*!)ðï  \Êx?Ÿy%¨Ó c1×X¿›ðõ™šüàYi‹nwúÍQýØ{ÒÒ/Ng‹ÜèXñ®—k`÷8ÖDûúR Ì4¶J€318áàB„Ó¨a¿ÄXð¼%W€5à”#Q*€ ‰0ž"ÏTî÷¡iÉc~ݩퟡ97KÖjw-[ï®É XPðj§5= 23Ö}°˜î–©©])c¤xË{‚Uðà?®º|.û üa¯�e=ÂÍRÆ;ƒ{²ßù³Ó'UÙuˆe0¤•Ë]fÁ#VÒ– �Go¼ Œ»³h%g›§kwDÔAÚêË2ãEŽÕyzïst¾¢ª#†87k/0­Á5.  øL?–Õv•ÃÔz¥�T&ö¶ƒR9H›¹àŠ*Þu�þGk�«Ý,éä—IJ2¯Ýì.ªa@÷¸$k†Ã¶(MQ£YL§äw5>˜‚0Ó£½ å%Â<˜5ÿR^·C¸Lº¼TR$9S´†˜Š2Ëû®•\*ü~×�X˜þ•K|P‰öÕG“³$EÓ¯Ó�ª�¼Šðgà{˜9 ¾ƒðKü¼«U®–Nvú”¦!žÀtlÎC¨h�7™—&‡Ej‡ïR‡c/#Ã’N|ƧEèœK«ñae¶[¹É]›�=’¦¾‚„÷w[ŽúœÂd¯qœmù p\ŠoGá™TÙ]rBª,ÃetFì˜uÛy6¥ _ÅŽqü‰EBmK::ü:!«˜�«‰­>,·«oWÛõv?–LfŽþŠY¤ûO4sŒLpNpZ'Ì ±Œ˜~´bcˆ•ZŸÊÚ*uq\¯¼˜Íh‚lÂe¢^ô࿲+Äe%¹Ïús>&Ã:an¦Â8KÍíTØ+>À¸†Míp]^ëú¼�U](¥-á2Àï'“ê�[Û^ù6­B�ùSÖnqפgL}¬“é4º:M�Qâ�Ë ¼êòZóÂ3o¹>²—Y4ß‚åÉÄ:ü»±ˆM/]Ö…ˆ:GÅ]µ* òàs”W0øBCÜl(s»}¦E× øy(| Ìvq”-\fÿŒLŒswÚ;¸»«˜Å!·»Ì„ЭS´s3Ê8+Lö"›Õ¢ÜªAŽNÐFÎ…” ¶uLȇjðQd.“*ÎýîÀΉçÏ™ÄÚ˜E›â‚¨ÄÚîâðT»pN´I­‰¬¦ˆ#€_s¤ÖUâTàI¦�wÞ±Âi�t.½tFl|,×ÉXpœÆ?@8Þ.“bÇG*_´É;’ U³ŒmÖÄRWú•/…"žÔÖ¬ë�ëõ~Šœô7 Ñ•w €îô ¬!æá&+º ýäx„_¢ #ؤ•Ê@Zx±™ú>”qÇk%“¤Â9/{ÖÝâ|”Y6ÿšYêF 9Q«/eÔ€»p™–0ŸøûÿsHNî¡óM„:)ge{ÜO.Ü E`ãvM¬X޾­ädY, ‘ÅZÛícùXª~ƒ™?  å2)O^Åψ*Óø�üs²ÝuìHªJÆ X… .„Œˆ«VÀ »è #ùF©â¯åÜ4�ý5pO†_^H s㬻¾ˆ«êgÅ;?ñs°*Ãy‹ãÆ�ŽP±0›ÃFìÀ8Gx-î\/äóT¸ {§¸ ð®=·Ìm8giŠÏÓOȃ¹ M¹^ø §'ø¿öqÙ§�3BdˆprÊÊL©àþjªxö¨#ô€Am_” !Âx„sØ”Pç:ϬÂU¨iåõ,…�.ŠËþ{‰­ý‘À#YjuSÈH*òAÚK5c“.Ð*%Ì�­*_^ ˆ9IIG|ÔG½g™Ðl�n•É,Ô9LÓ¬RyÀR„9HR°ãI÷±#mâ*µî?h‡l2¯ä¿»!n_à v‹™êhSà�˺c¦±ÕÚ}ò(­eD„/ s©«öæºáüŒnäz°2ZoKœvYŸÝeý¹ƒ‹„ Þùi™vþT‰éƒ³(yô|,2jd[ò„J9Oæ„2”S€ƒd²ëúÎîÎ1�F+WW&Ü×nçLp„64sW¢#ô»ûsÒŽî̉e°¢ÕðÖÇ}³çÀå'FÅüÉ8„�h5>ùf²ŒÅø¸)>ôE¦°§-OD›ï´i5ð+ ¸ªg“8ÅÝBÇZ»XœðKm%YÜY¶q[䑨y롉:B_¾žïŽŸiÞóÀô\z7‹ý<Àî̉Uȇ–QÌ!ÃÜ7{cqܵèŸ “T·Ç毮­šB"¼leS…¹-ìY­blÖd* lcœeQÆOô5ÀÍ æ™áZ³»rˆ&;~¦V³h&þÕ5l*ö3 7©wubY"ús€ïŒvß®±6ņ©oŠÃNIxÿ­r‘I¥�qHR�>ÊumºÇ Ù.®¤ˆ¾VV›ÙN? p{¶õšÝºqÀõÑótvi!ïâS¡‰g�+Gõƒo….²]õéý»G;ziŠÃ×·Rà")ˆ$­?¶N¹Cvð!ª§=2Ú¸p)¤iû$j“Rsv_b…yWrÓðÃû379,5žIqØ­Ö4Ö3læW¥à >tœœ$9e¤ÎÀ`'a(‡í‘SË*¿r:Ð@KŠ@páRHc´\ç&õcû{•r+—æyw¿×<š:éÁCáÍ›£ YÊÁ©ô�G?Œޓ@Úq{» óÀ¶óy+ÊÑñùHµ’R„— NÇî—r~ºýpÂcĪȯ¾íZM!�¼íàR8Ôq7s —Ä*µ:ô€7?ƒªá_Ÿ�ÆìÄ!tQtÓjaŽ”),Ò‡éC§áÍöpXƒw©å€]C˜ß'þ®Vrâ°›ØàˆV -zì£ $ÌL«�ù„[‹qêŠñ³ÜAgü§솃†èŠòS„oK0¸»=6{h%¥Ài(´§û%·õ «ñÑÄí(W¶:.×l†OVBm½Y¦wLL»Ø@„Óe2o[$øsý¯?c¬¬É{½!^Dù¾C/Þ åÌŒ7‹Ntâ#ì±N�D8J&óaœ”<(…ÖÂv:9úl÷{ ò&p4f8Ó‘;ZA,wî»r–r~†²ÊÀòÝaü8û°(©6#üå™l•¡mf(±Eå®´dïh#jS(ùu v×9$Ða$ElKi§®éøM¥ÖŽ£Öø°â¸×»6±¢«à ©`º†Ÿ!GY ŸRD?)ç"[Qí–Å=é5(ÿlÓzµùRƒ,²bŽ\42«Á& ’’îH1?ØããËYŠózå<·¾. 2Uƒ|©•|ª•î‰!º�¤u©ªMS7{Wš ÛAG;ÅÒ±VeIªS°Wx¯ÇÏ(§ú†Óáå(·a®.¦HÀNl‡ßoŃàbÛ±U %B3ì8üå<7¹Su.bðaœ€Pààl¦3­¦„&N¤™�Òxïj~¬ö�rÛpÿ�âq:.!ž²„0Ç�¹0ßïÕÙ̦€R‘"òs)/0’±o’]‹‘¼FÊXŽYq¬/aš²JQip\¬#ÖtæšX–¯íÉÝÃ�•kDø"IV‹{ׄLc+�r/·Ì ¢ÕœE?ÁàÛ(ËñsO:Ã6Õ»@–:/ a%¸¡IDATÏ‹Oä•VSB#Ïc®)*Êï¤"eˆrþÞ‡"„‚•Zx„2ΡÚÖ{$±¢ƒRÅÂlr££é\!Œ¢ž·:Ú  !¾A3[Ýê<­›vÛR Ú#V.Id"03ªó+"ŒoïX.K’úhà +ŠAد~.ax´É8Ø…Àˆ%q‚/厖Ķ=5Ä™úHŠ<ô‰häG©Ì‡^™Þ–Ð�|À¡¼ëŠñqÅ„ù�­–_&ÔÑ�‚„Bæš9¨Vq8�üè†ÕJ.Ë`§ IšC")"/ÒI½&.†#ÜmY�žÄêø¸áf”k1Üoº�óX ›Ü8d#\Kló† üÚEn­Ä]ÞMY–{kb2Ê=(Ó‰ð´7v¬&9:îuöÙaüL^DY�òõöÔ“)�x]JÿôAvRÁ«ÀÅÀg(ÿ&e-q졇{Sa‡Î…<€03mä̬yiúŸNʲÙKÄW¾Pæ» qq“ê:ƒ¨á ´OJ"Ï*LÇ­ùøYO�åiÞJ¿�&®G9 áS ®·2àì,ƒ£0UevaíÃC¦§¿3MA˜YY“íqP(¼·«õ›çÇJ7°³( ‘·­|ñ霷CGž;Ä$  ¼«¡Œ™h None: self.widget.setConfiguration(config=config) def getConfiguration(self) -> dict: return self.widget.getConfiguration() def _storeSettings(self): self._ewoks_default_inputs = self.widget.getConfiguration() @Inputs.tomo_obj def addTomoObj(self, tomo_obj, *args, **kwargs): self.widget.addTomoObj(tomo_obj) @Inputs.series def setSeries(self, series, *args, **kwargs): self.widget.setSeries(series) self._storeSettings() def validate(self): config = self.widget.getConfiguration() assert isinstance(config, dict) self.Outputs.stitching_config.send(config) def keyPressEvent(self, event): """ To shortcut orange and make sure the `F5` <=> refresh stitching preview """ if event.key() == qt.Qt.Key_F5: self.widget._trigger_update_preview() else: super().keyPressEvent(event) def close(self): self.widget.close() super().close() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/stitching/__init__.py0000644000175000017500000000051214764622416024746 0ustar00paynopayno""" (Ewoks)Orange Widgets for pre or post processing stitching """ NAME = "stitching" ID = "orangecontrib.tomwer.widgets.stitching" DESCRIPTION = "widgets for data stitching" LONG_DESCRIPTION = "Contains widget for stitching operation" ICON = "../../widgets/icons/tomwer_stitching.png" BACKGROUND = "#C0CCFF" PRIORITY = 12 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9051008 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/stitching/tests/0000755000175000017500000000000015153325403023766 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/stitching/tests/__init__.py0000644000175000017500000000000014757047403026077 0ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9051008 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/tests/0000755000175000017500000000000015153325403021772 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/tests/__init__.py0000644000175000017500000000000014757047403024103 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/utils.py0000644000175000017500000000205315153325210022336 0ustar00paynopayno"""utils for orange widget""" from __future__ import annotations class WidgetLongProcessing: """Class to display processing for some widgets with long processing""" def processing_state(self, working: bool, info=None) -> None: """ :param working: :param info: """ # default orange version don't have Processing. try: if working: self.Processing._add_general( info or "processing", text=None, shown=True ) else: try: self.Processing.clear() except Exception: pass except AttributeError: # in case we are on an orange version not having `Processing` pass def setDryRun(self, dry_run): pass def _startProcessing(self, *args, **kwargs): self.processing_state(working=True, info="processing") def _endProcessing(self, *args, **kwargs): self.processing_state(working=False, info="processing") ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9091008 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/0000755000175000017500000000000015153325403023531 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/DataViewerOW.py0000644000175000017500000000773215153325210026411 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging from orangewidget import gui, settings, widget from orangewidget.widget import Input from silx.gui import qt import tomwer.core.process.visualization.dataviewer from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui import icons, utils from tomwer.gui.visualization.dataviewer import DataViewer _logger = logging.getLogger(__name__) class DataViewerOW(widget.OWBaseWidget, openclass=True): """a data viewer able to: - display slices (latest reconstructed if any) - display radios with or without normalization :param parent: the parent widget """ name = "data viewer" id = "orange.widgets.tomwer.dataviewer" description = "allow user too browse through data" icon = "icons/eye.png" priority = 70 keywords = ["tomography", "file", "tomwer", "acquisition", "validation"] want_main_area = True want_control_area = False resizing_enabled = True ewokstaskclass = tomwer.core.process.visualization.dataviewer._DataViewerPlaceHolder _viewer_config = settings.Setting(dict()) class Inputs: data = Input( name="data", type=TomwerScanBase, multiple=True, ) def __init__(self, parent=None): super().__init__(parent) self._imagejThreads = [] # threads used to open frames with image j self._layout = gui.vBox(self.mainArea, self.name).layout() self.viewer = DataViewer(parent=self) self.viewer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding) self._layout.addWidget(self.viewer) self._setSettings(settings=self._viewer_config) # open with ImageJ button types = qt.QDialogButtonBox.Apply self._buttons = qt.QDialogButtonBox(self) self._buttons.setStandardButtons(types) self._buttonOpenImageJ = self._buttons.button(qt.QDialogButtonBox.Apply) self._buttonOpenImageJ.setText("open with ImageJ") self._buttonOpenImageJ.setIcon(icons.getQIcon("Imagej_icon")) self.layout().addWidget(self._buttons) # connect signal / slot self.viewer.sigConfigChanged.connect(self._updateSettings) self._buttonOpenImageJ.released.connect(self._openCurrentInImagej) def _openCurrentInImagej(self): current_url = self.viewer.getCurrentUrl() if current_url is None: _logger.warning("No active image defined") else: try: self._imagejThreads.append(utils.open_url_with_image_j(current_url)) except OSError as e: msg = qt.QMessageBox(self) msg.setIcon(qt.QMessageBox.Warning) msg.setWindowTitle("Unable to open image in imagej") msg.setText(str(e)) msg.exec() @Inputs.data def addScan(self, scan, *args, **kwargs): if scan is None: return self.viewer.setScan(scan) def sizeHint(self): return qt.QSize(400, 500) def _updateSettings(self): self._viewer_config["mode"] = ( # pylint: disable=E1137 self.viewer.getDisplayMode().value ) self._viewer_config["slice_opt"] = ( # pylint: disable=E1137 self.viewer.getSliceOption().value ) self._viewer_config["radio_opt"] = ( # pylint: disable=E1137 self.viewer.getRadioOption().value ) def _setSettings(self, settings): old_state = self.viewer.blockSignals(True) if "mode" in settings: self.viewer.setDisplayMode(settings["mode"]) if "slice_opt" in settings: self.viewer.setSliceOption(settings["slice_opt"]) if "radio_opt" in settings: self.viewer.setRadioOption(settings["radio_opt"]) self.viewer.blockSignals(old_state) def close(self): [thread.quit() for thread in self._imagejThreads] self.viewer.close() self.viewer = None super().close() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/DiffViewerOW.py0000644000175000017500000000277415153325210026411 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging from orangewidget import gui, widget from orangewidget.widget import Input from silx.gui import qt import tomwer.core.process.visualization.diffviewer from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui.visualization.diffviewer import DiffFrameViewer _logger = logging.getLogger(__name__) class DiffViewerOW(widget.OWBaseWidget, openclass=True): """ Associate TomoScanBase with the silx's ComparaImage tool. Allows to compare two random frame. """ name = "diff frame viewer" id = "orangecontrib.tomwer.widgets.visualization.diffviewerow" description = "Allows comparison between two random frame from a scan" icon = "icons/diff.png" priority = 107 keywords = ["tomography", "diff", "tomwer", "compare", "comparison"] want_main_area = True want_control_area = False resizing_enabled = True ewokstaskclass = tomwer.core.process.visualization.diffviewer._DiffViewerPlaceHolder class Inputs: data = Input(name="data", type=TomwerScanBase) def __init__(self, parent=None): widget.OWBaseWidget.__init__(self, parent) self._layout = gui.vBox(self.mainArea, self.name).layout() self.viewer = DiffFrameViewer(parent=self) self._layout.addWidget(self.viewer) @Inputs.data def addScan(self, scan): if scan is None: return self.viewer.addScan(scan) def sizeHint(self): return qt.QSize(500, 700) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/NXtomoMetadataViewerOW.py0000644000175000017500000000357514757047403030444 0ustar00paynopaynofrom orangewidget import gui, widget from orangewidget.widget import Input, Output from silx.gui import qt from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui.visualization.nxtomometadata import NXtomoMetadataViewer class NXtomoMetadataViewerOW(widget.OWBaseWidget, openclass=True): """ Widget to siplay NXtomo metadata """ name = "nxtomo-metadata-viewer" id = "orange.widgets.tomwer.visualization.NXtomoMetadataViewerOW.NXtomoMetadataViewerOW" description = "Interface to display some metadata of a NXtomo" icon = "icons/nx_tomo_metadata_viewer.svg" priority = 13 keywords = [ "hdf5", "nexus", "tomwer", "file", "visualize", "visualization", "display", "NXTomo", "editor", "energy", "distance", "pixel size", ] class Inputs: data = Input(name="data", type=TomwerScanBase) class Outputs: data = Output(name="data", type=TomwerScanBase) want_main_area = True resizing_enabled = True def __init__(self, parent=None, *args, **kwargs): super().__init__(parent=parent, *args, **kwargs) _layout = gui.vBox(self.mainArea, self.name).layout() self.widget = NXtomoMetadataViewer(parent=self) _layout.addWidget(self.widget) def _validateScan(self, scan): self.Outputs.data.send(scan) super().hide() @Inputs.data def setScan(self, scan): if scan is None: pass elif not isinstance(scan, NXtomoScan): raise TypeError( f"expect to have an instance of {NXtomoScan}. {type(scan)} provided." ) else: self.widget.setScan(scan) self.show() self.raise_() def sizeHint(self): return qt.QSize(400, 500) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/RadioStackOW.py0000644000175000017500000000404515153325210026374 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging from orangewidget import gui, widget from orangewidget.widget import Input from silx.gui import qt import tomwer.core.process.visualization.radiostack from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui.stacks import RadioStack logger = logging.getLogger(__name__) class RadioStackOW(widget.OWBaseWidget, openclass=True): """ This widget will make stack radios incoming and allow user to browse into it. """ name = "radio stack" id = "orange.widgets.tomwer.slicesstack.radiostack" description = ( "This widget will save all scan path given to here " "and extract received radio files with there shortest" "unique basename to be able to browse them" ) icon = "icons/radiosstack.svg" priority = 27 keywords = ["tomography", "radio", "tomwer", "stack", "group"] ewokstaskclass = tomwer.core.process.visualization.radiostack._RadioStackPlaceHolder want_main_area = True want_control_area = False resizing_enabled = True class Inputs: data = Input( name="data", type=TomwerScanBase, multiple=True, ) def __init__(self, parent=None): widget.OWBaseWidget.__init__(self, parent) self._box = gui.vBox(self.mainArea, self.name) self._viewer = RadioStack(parent=self) self._box.layout().addWidget(self._viewer) @Inputs.data def addLeafScan(self, scanID, *args, **kwargs): if scanID is None: return self._viewer.addTomoObj(scanID) def keyPressEvent(self, e): # TODO: fixme # here we want to avoid loading imageJ when enter is pressed. # the correct way would be to install an event filer # but this is ignored because the KeyPressEvent goes other it. # I don't really see why too annoyed at the point to look deeper if e.key() in (qt.Qt.Key_Enter, qt.Qt.Key_Return): pass else: super().keyPressEvent(e) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/SampleMovedOW.py0000644000175000017500000000530615153325210026565 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging import os from orangewidget import gui, widget from orangewidget.widget import Input from silx.gui import qt import tomwer.core.process.visualization.samplemoved from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui.samplemoved import SampleMovedWidget logger = logging.getLogger(__name__) class SampleMovedOW(widget.OWBaseWidget, openclass=True): """ Simple widget exposing two images side by side to see if a sample moved during the acquisition. :param parent: the parent widget """ name = "sample moved" id = "orange.widgets.tomwer.samplemoved" description = ( "This widget is used to display two scan side by side " "to know if a sample moved during the acquisition by " "simple observation." ) icon = "icons/sampleMoved.svg" priority = 85 keywords = ["tomography", "sample", "moved", "visualization"] ewokstaskclass = ( tomwer.core.process.visualization.samplemoved._SampleMovedPlaceHolder ) want_main_area = True want_control_area = False resizing_enabled = True class Inputs: data = Input(name="data", type=TomwerScanBase) def __init__(self, parent=None): super().__init__(parent) layout = gui.vBox(self.mainArea, self.name).layout() self._widgetScanPath = qt.QWidget(parent=self) self._widgetScanPath.setLayout(qt.QHBoxLayout()) self._widgetScanPath.layout().addWidget( qt.QLabel("scan: ", parent=self._widgetScanPath) ) self._scanNameQLabel = qt.QLabel("", parent=self._widgetScanPath) self._widgetScanPath.layout().addWidget(self._scanNameQLabel) spacer = qt.QWidget(parent=self._widgetScanPath) spacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) self._widgetScanPath.layout().addWidget(spacer) layout.addWidget(self._widgetScanPath) self._mainWidget = SampleMovedWidget(parent=self) layout.addWidget(self._mainWidget) def sizeHint(self): return qt.QSize(400, 200) @Inputs.data def updateScan(self, scan): if scan is None: return assert isinstance(scan, TomwerScanBase) if os.path.isdir(scan.path): self._scanNameQLabel.setText(os.path.basename(scan.path)) rawSlices = scan.get_proj_angle_url() self._mainWidget.clearOnLoadActions() self._mainWidget.setImages(rawSlices) self._mainWidget.setScan(scan) self._mainWidget.setOnLoadAction(scan.flat_field_correction) def clear(self): self._scanNameQLabel.setText("") self._mainWidget.clear() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/SinogramViewerOW.py0000644000175000017500000000352415153325210027312 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging from orangewidget import gui, widget from orangewidget.widget import Input import tomwer.core.process.visualization.sinogramviewer from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui.visualization.sinogramviewer import SinogramViewer from ..utils import WidgetLongProcessing logger = logging.getLogger(__name__) class SinogramViewerOW(WidgetLongProcessing, widget.OWBaseWidget, openclass=True): """ This widget can be used to compute and display a specific sinogram from an acquisition. """ name = "sinogram viewer" id = "orange.widgets.tomwer.visualization.sinogramviewer" description = ( "This widget can be used to compute and display a " "specific sinogram from an acquisition." ) icon = "icons/sinogramviewer.png" priority = 5 keywords = ["tomography", "sinogram", "radio"] ewokstaskclass = ( tomwer.core.process.visualization.sinogramviewer._SinogramViewerPlaceHolder ) want_main_area = True want_control_area = False resizing_enabled = True class Inputs: data = Input(name="data", type=TomwerScanBase) def __init__(self, parent=None): widget.OWBaseWidget.__init__(self, parent) WidgetLongProcessing.__init__(self) self._box = gui.vBox(self.mainArea, self.name) self._viewer = SinogramViewer(parent=self) self._box.layout().addWidget(self._viewer) # connect signal / slot self._viewer.sigSinoLoadStarted.connect(self._startProcessing) self._viewer.sigSinoLoadEnded.connect(self._endProcessing) @Inputs.data def addLeafScan(self, scanID): if scanID is None: return self._viewer.setScan(scanID) def close(self): self._viewer.close() super().close() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/SliceStackOW.py0000644000175000017500000000530415153325210026374 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging from orangewidget import gui, widget from orangewidget.widget import Input from silx.gui import qt import tomwer.core.process.visualization.slicestack from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui.stacks import SliceStack logger = logging.getLogger(__name__) class SlicesStackOW(widget.OWBaseWidget, openclass=True): """ This widget will make copy or virtual link to all received *slice* files in order to group them all in one place and be able to browse those (using the image stack of view in orange or a third software as silx view) Options are: - copy files or create sym link (set to sym link) - overwrite if existing (set to False) Behavior: When the process receives a new data path ([scanPath]/[scan]) and if no output folder has been defined manually them it will try to create the folder [scanPath]/slices if not existing in order to redirect the slices files. If fails will ask for a directory. If the output folder is already existing then move directly to the copy. """ name = "slice stack" id = "orange.widgets.tomwer.slicesstack.slicesstack" description = ( "This widget will save all scan path given to here " "and extract received *slice* files with there shortest" "unique basename to be able to browse them" ) icon = "icons/slicesstack.svg" priority = 26 keywords = ["tomography", "slices", "tomwer", "stack", "group"] ewokstaskclass = tomwer.core.process.visualization.slicestack._SliceStackPlaceHolder want_main_area = True want_control_area = False resizing_enabled = True class Inputs: data = Input( name="data", type=TomwerScanBase, multiple=True, ) def __init__(self, parent=None): widget.OWBaseWidget.__init__(self, parent) self._box = gui.vBox(self.mainArea, self.name) self._viewer = SliceStack(parent=self) self._box.layout().addWidget(self._viewer) @Inputs.data def addLeafScan(self, scanID, *args, **kwargs): if scanID is None: return self._viewer.addTomoObj(scanID) def keyPressEvent(self, e): # TODO: fixme # here we want to avoid loading imageJ when enter is pressed. # the correct way would be to install an event filer # but this is ignored because the KeyPressEvent goes other it. # I don't really see why too annoyed at the point to look deeper if e.key() in (qt.Qt.Key_Enter, qt.Qt.Key_Return): pass else: super().keyPressEvent(e) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/VolumeViewerOW.py0000644000175000017500000000671715153325210027011 0ustar00paynopaynofrom __future__ import annotations import logging from orangecontrib.tomwer.orange.managedprocess import TomwerUnsupervisedOneThreadPerRun from orangewidget import gui from ewokscore.missing_data import is_missing_data from tomwer.tasks.visualization.volume_viewer import VolumeViewerTask from tomwer.gui.visualization.volume_viewer.VolumeViewerWindow import ( VolumeViewerWindow, ) _logger = logging.getLogger(__name__) class VolumeViewerOW( TomwerUnsupervisedOneThreadPerRun, ewokstaskclass=VolumeViewerTask, ): """ Widget embedding a viewer to display reconstructed volume. Several views are possible. One per axis or an 'overall' view (displaying the three axis in parallel). By default this widget allow users to browse the volume along the 'fast axis' and will sample 3 slices along each axis that could be displayed. If users agrees on loading the full volume then browsing can be done along any direction. """ name = "volume viewer" id = "orange.widgets.tomwer.visualization.VolumeViewerOW.VolumeViewerOW" description = "Widget for browsing reconstructed volume." icon = "icons/volumeviewer.svg" priority = 31 keywords = [ "tomography", "volume", "tomwer", "reconstruction", "summary", "slices", "axis", ] _ewoks_inputs_to_hide_from_orange = ("load_volume",) want_main_area = True want_control_area = False resizing_enabled = True def __init__(self, *args, **kwargs): super().__init__(self, *args, **kwargs) self._window = VolumeViewerWindow() self._box = gui.vBox(self.mainArea, self.name) self._box.layout().addWidget(self._window) self.loadSettings() # make sure 'load_volume' is defined. self.set_default_input("load_volume", self._window.isLoadingVolume()) self._window.sigLoadVolume.connect(self._loadVolumeHasChanged) def handleNewSignals(self): volume = self.get_task_input_value("volume") if not is_missing_data(volume): self._startProcessing() self._window.initVolumePreview(volume=volume, message="Loading slices") super().handleNewSignals() def _loadVolumeHasChanged(self, load: bool): self.set_default_input("load_volume", load) def loadSettings(self): load_volume = self.get_default_input_value("load_volume", None) if load_volume is not None: self._window.setLoadingVolume(loading_volume=load_volume) def task_output_changed(self): slices = self.get_task_output_value("slices") volume_metadata = self.get_task_output_value("volume_metadata") volume_shape = self.get_task_output_value("volume_shape") loaded_volume = self.get_task_output_value("loaded_volume") if (not is_missing_data(slices)) and (not is_missing_data(volume_metadata)): self._window.setSlicesAndMetadata( slices=slices, metadata=volume_metadata, volume_shape=volume_shape, ) if not is_missing_data(loaded_volume) and loaded_volume is not None: self._window.setVolume(loaded_volume) else: self._window.clear() _logger.warning( "Fail to load volume slices and metadata. Did the volume reconstruction failed ?" ) self._window.setLoading(False) self._endProcessing() super().task_output_changed() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/__init__.py0000644000175000017500000000061414764622416025656 0ustar00paynopayno""" (Ewoks)Orange Widgets for tomography raw and processed data visualization """ NAME = "visualization" ID = "orangecontrib.tomwer.widgets.visualization" DESCRIPTION = "widgets for data visualization" LONG_DESCRIPTION = ( "Contains widgets for visualization of the acquisitions," " reconstruction..." ) ICON = "../../widgets/icons/tomwer_visu.png" BACKGROUND = "#C0CCFF" PRIORITY = 3 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9091008 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/icons/0000755000175000017500000000000015153325403024644 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/icons/diff.png0000644000175000017500000000057214757047403026300 0ustar00paynopayno‰PNG  IHDR=:gQQsBIT|dˆ pHYs77±d£tEXtSoftwarewww.inkscape.org›î<÷IDATh�íÚ1 ÂP„áY ¢ÑBìlµ³õ 9”ÇðÁÊBA‚½•Vóˆb,<�›"ÈÌ×/ËOªåÅ’$)á—˜9g75ìEÃ;øÏÍBÑ,ÍBÑ,ÍBÑ,"|¯—óp”›áæ™íÞoY‚kwY–¹™¹ößhïy‡t6M‹fËuâÍ÷»M‚k·™é´ü•¢Y(š…¢Y(š…¢Y(šETeøøX¢ó|¹fWï èUYïFù¥ÍBÑ,ÍBÑ,ÍBÑ,*=àm/ƒ¼ß.\i×eÞݵ>à­OãZþ Õžƒ¢Y(š…¢Y(š…¢Y(šÅT"6µ`…ÿ�IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/icons/diff.svg0000644000175000017500000001701514757047403026313 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/icons/esrf.png0000644000175000017500000031660614757047403026337 0ustar00paynopayno‰PNG  IHDRú,êü®» cHRMz&€„ú€èu0ê`:˜pœºQ<bKGDÿÿÿ ½§“ pHYs.#.#x¥?vtIMEà 93Xgc€IDATxÚìý}|\gyç�¿Ïó<�$?'-UJJ+(¤Ð"(MëÖ¥ÛîoØv»ì¦´«–P.&á±:)�!à•¦!Pz\©Aà˜@‚›Ð Y‡Ž1(A ²cE’e=kæœÏ÷�ûœ±ìþº/¶14>¯×yÙ²G3ç̹¯û¾îëú@ºŠ Ô>pÀrj5ÅXÎój<„üí´¿•?wüÇ=ÎÍìÿ¡Ë.€];ÖQ°-°ŽÖ�Vöªâvóÿœ{þ�›ãÜŠþ~܇U‰AO³X’t7–—ëBÔÂêÄxgOnYX€%qnEçfôÿPGЖÝ«òNtÀ²×ÜÖíÓëÜ,ÿ89ÎúOø1Ë °bVsh÷ðéÃÍåp³×IøÅãbã ØÐÞ¹Šûãç8—ºÿÄ– ¦ªÐ@&È-‹e!ë¡ +ÈåpsÉ-‚µånféWël_ý¹ã±9έè?ñ‡Ú€­[ÈꃤÜp¿7O^Ⱥ’Ûì¾@k'7E«%«qê+˜þÜalî¶¼³}õçŽÇæ8èÿQŽ—„:�n¼�¤Úî+p%C”­$MÄ¢g&µÖÎçãÞwòÜó¼çôOüa¹�úñ V¸ÆV·l —�*tï}¦}%/pjDª=ûO­ëÀÏiå©¿©µ³}õçŽÇæ8èÿ1Ž„(´à%éÊ>dñS|é;@Üû0ÖÐÀm<뙡^Äq¥õ£}ì¹ã'å8WŒûI?,ì¼ÄzÁÔ�ÀÆ�´ õ’—¤ˆ7ÁöV®w­·÷âýÒZ¡�Ëšåö]LÜäܪþx8έè?áÇ�uˆ·S±j5QdÙýþƒØ›±_»ˆKt´À¡ý:z Ÿíë?w<6‡û£¿Å¹ã¬‘E­¦¬ÅMH\i?’•«‚mýw¸ô£ãñ×^»m`ŠàùO6Âmm.½íî;..ógûÎÿþǹÔý'þ°lP²ËîÀm„¼ ×­W"aýÕž~ö-àZÂA¬èT÷-CÌÜø^ÁÒÙ¾ƒsÇcpHzœŸ”$rMá£Ð¦&‡†<ÔïíÁ!Q”$숚#B;Dn„Ñð¾ÿýȰ¥éÏMƒH³Âk ¿!< ·ó:ä Ù’8Hhƒ!§|ç@FR¹â� ¿ ¹5±R°´ É*h­v‹ï”wš´ÿÑÇw�ô§ßÖ÷èÏËîÏbH;ØÑ¬ÞÍ$ýà°{§ÅÝX?Î{gñØÁ;êÁ–‡a ›ø#õп¸°Hë6pÃDz,+;èÔŒ”dmèv&[±7–ÿ_t ?„ž³=ÓœõÙJW5Üc¢|HG„G(;›ýKN¶"MMQž=éÊð\Yj—Q2±/+4+¸"?B=<¥õKX}çâwàé9ìU‘Æ;«Œ &s�+ó§!'d ³z›{m5LÆ@ºÚ�íÉû¬¾5Ï·[¤%J $²ù—eÊ'ßñèÕ 7ŠÌêmÞG mBÙ kÝkíôsì>OO$òÜz5‡vè²"­·Äß»MØ«b–-„!n=Är/e<×Y±›øjà�ù>)ÏŠ.Ú +»_s_ʘw?Šþø:Ïúœõ3 !›4Å<"Š ƒ老œA�YŒ‹®u󇺨ÙI×m�-BÛ¤ÿnˆ|v¼ë8ož¸ME¾Òv¸ê¹!4å›ß‘kÎÐ6×[s²-Az–ià§ï_3›ñÀE¸/ñ‘ éËáë«\ _^èYÚ¿þ~}?gî5›$JûÇé¢_OÁ}Ó×|ê+._^´¹yÉã£GyúMOGr£&þ�‡(JØjâ ·—Ñ ¢öƒ�NhÏŠ®iQÉ®#ÛRDNvž ôs�þqš•,¼Ùž:«–• î(Âé¬(¡lþƒ\aˆ¦“é¾r“…9Oåægà¶D>‰qÎ\b£V™XüüÊ‹P³d² Js¢'Í ÊÀ=³w=3™ ©9ÙÞÕ]ùT^~e‘Ë9¢•"Ñj™O.ãþÙ›QÃËî/[1;{üô3«~ŒB6��“—•ºÑW<æe1'¬µe˜Mr,Æ_û(½cA 9û"ò'NP”È}H”O�_?Ѧ{ñÂÄùY3‰–׺¹.Y€]Ž©¬ŸhØy¶Ç×�Çyn�nöiÉ�XQ„]«!Z5KfPe‡ ð§„1\i1„ Cëö”?ì°ì¡!’€(ýýmÎylk}�ëíGøÈo`¹b¹eáäAÄжc,øîÇŸÍW7[ô½Äzøa²%Öž‹wŸé�¿ËI¯ˆÒ3;b øû㫞Äÿïw\jW;Ô®þY~ï?ñÙpÿÔﯿÚüºžü™[¸Ò>pÀrÀº;ûÿÙ뮄ù¿sØ4Cò<�o%èTÎ+Av˾í¹oΉD pß}Ø<‚75ûè±·°};N׺ÚIa¨ÁKj¡¨aS“õ"°0pÙ÷o=ÎöLs¶ÏlÚI‘©æ¦©äúªï1QŽ"³’ ³ý?d ¶„;.r{ö‘œZö^Ⱦ”ñ\•K^‡µ$Pl¡ØA1Ö|R`&aóÞ73Ô(0PwÓÏÏI”¥ÿi¥} Ž[Svíašæ‡v§º¯—K•CòÛ0ÚDN„òÙ½±.sÉVõ¦ð›2ßAöó÷¯æBöþqºL-ਠ¬´ÓW+i{¬Éæ½35”òDòG‡ 8±¥ÈØp '¢æL‹Ê¬èʶõÐd-j¦]…&¾ÖocD!=íÛyöÇÚÙç?qV¿€P&г��<5ðÖúœèY¿gü?¿ï™=ïð(A îrá\Šrrz¹åçq“Ä¢%‡$ñhÇ>+*² ~AÏAÊQ3ƒÆÉIä”n²@ìËÚ‚Y»)ýŒ40=$“¾KéÙŸÖ °Õiš÷Ì®»äé=¤×Ÿýig­5![Â{Æ8]IF , á)†5Häpç?ôÑô¯æDQD¾$Æ/%·CäÆÍýÙ³¢Ëº:ïŸÕ"ÆEn<½÷�×´5M»íßäî¹@?èì„Ïðh0€Ü'(ª‰?6J Ýãf%í™]f‡Äv3ñµ›@#gŠ_ü�ýl$9­+ÈI& Ï8åO¿Áâse¾®Ž´Š|d©Àè_26DéÄS£éKôè~ªB^DÍIûèþˆðÆÉIBÈU¯nzÔ)6 îÒñ~]ô„¢ë l¹Eœ'd×�sH'E!¢ædŸ$²¾øÄy¥º(2™LCx·ÞOu\äÒ€žˆ~Æâ=ßÀþÌ<ÖÍKðñÓØû-.ßζ¡‚y]h a;Ÿ†<#^Cx³¢ë¡ÓlXär¦¦(kšŠHWtñ„oLs�fÍê†Y/¾S$L{ô¦>¢s+û¹@—DïAŸð¨»Böx�®‰}äâ+Ä×(ÁèWØ$ñ„e±#ļ®±‹Âè0�ÖÚÖz–OL�t w*å&Ð[A¿p>ñ¾Äï}ËÏïG…K÷“ë~6‘g0è�õ­Îç‡vHÝm¯OøŒí 8qQ‘‘™*:X@òyé%ÞÄ`®yÃwRMùìVPÛG>Ë ¢'E‘HÁ;‡'Èåq‘l$—Â}í"‹‰G,�5¹¬$óÊ1{Ü»Ræð/AäP“Ó'S„%ÈjÙ96Jpx‚ü�‡(Ò?âÑ'B—GŠH4‘gXÁ¬èºî:ºGÇ$Jä3 ‹)Zž©²SlP§]—4)K”!r�‹ú=TÏù¼ï pW;àÎeü·,rÞÇB!;CÙIf¿nVøìyœ ôs�¾n`¤ˆ­‚„kX“.¼ýyy³¶a*�xÅe%)“$ôêùìWNiëg=|ôûßÿ‡µã:)–UÀ~å(ióÄoèAŸ¨�Dˆ_w§ž²�‰|/c˜`“ÈORW×!ô\³ºËàÜ÷ªhóµ+󴓀Ĵ½œD¸«Â™Ž¬¶¶1þŽíLäQhïùãbÓq±)Û÷³ãÒà�›¿+Î{ûØ€)¨yÏFO…Õ7Úèc=´£Ÿ¡uùnæû„Jb"Rw§e¶&#�ƈêð² àѧìè$¥P”8¦2ÛNÿr…ÕvžXEâ¶Íª°W[¸SÚÈ%ýBö #È2fò=+î� ôÿ�žõO×­ é¿ÿ@o;­$gÿ¥­(í1-0�“»”ñŠ|Ž©Ì×¼5àTì±,­Ù¬*@qŽ9Q½ë�H¹aQy»Ø�±¬¢“”FÇÒXЉO‹k) ,BŽ"eÕæ�Ú¶�γ*˜9ÅX§…ÛÄkU4Ï3´ƒ†¼1±iB¦ÝtÏ Ûd�Ž|å8›nÝèD‘M·¼Ý'‘Åšð²=~[°$‹Åvá_¦{úõ°„&òÈtÂÓûØ0-*c¢2H¿‡&òì×S!žÁRÙ´…ÕZ„Gd‘Ä%’9Þ¢'a84^CRœ~�DÎLF¡mVùmNl)ÒI™x5xx‚üIQ":Y¢úæ×˜U€Zf‚j +NÌýüáë hÈuÓ p×·Ø2àMS†_oxõ}RÆÓìl\).a]úÿ}ÅT7›¬ÏþøÜúº þ¾@W:»g(;×Ïô5G5òÍÈzHÝeŸòHž½ü‚€Y¬¬Ârb¯z´Ta¥ÍF=ŸC*�“»Z Ü~äÕÇé£ÒÌh¨¡ì�:n–bgm°šۅ ð¦?-0�”h¯, æ„·hråi‰M7¾‚HþwØ¢Yº†ÿ�ŠRdÛ( „ìq‘›š¢ÍPE*ÑÛºÄf-1$ô5“®»IbÄ'âU¬Óº½d£‹ó¨žCÊ¥�î6…?5Eù_¯e«¦(ÊG“úÿó«,Lêo£5X3”½ÜrIV<Ú¢÷Õ¯æÎé ª»i'`czæÒ6œ ¶±�Á‘#’O­ÏÔ Lk³\¯Ó…”£W?_fZ>KrP KÂU GòøÚ³�\úäg$£áQ‚ýCäÖ­äîú@ïPo¥N �§…Ìõ�že3’X_LmOŽ~ÈVíÇõ<ëð£žû ÖÛìWgE×q±)ƒ®ª‘>œ´èÓypÈ‘;:L YºN‹�ŸŸbÛ]œT‰žOý¥Íû—þi!Ïç–mÞ6 W]ñù9S5¾t¿ÙŸg ƒçnx…±1*c2+l¦Ô’õ׳‚C'Šw�™Kæ Ï‹Í ìI6+‰ÇÃKø_½‰K•«‰ü¤(À Ç`¿7:F�¡ÔL›Ê´ÇúB|&”'8p½Ë§×r,&yZ*�ÈðÑ?¾Lî“ ¯IŠR“\#’wèűQ‚&ò3‘rA6‡NÉ}å&­8Ć?æ¬ÿtŒ½°32)ö×ßÏ>åk"MÉå yYöaVõºKMyúB¿£Ø³›`üRrŠp¨É¡w4`T¼ÿÍo>ísÛ²Ç?/ì[å‰7¼§OøÃ"¹•êºIßY�®™<›e¡°M@¯OëÍ¿…)cQ?¬ÛîìÇÀã"Ð3ž²àiÏ7™•9Ñ3›a¨ëé—g„ šη�€1‰{E÷KO°EyBUv°öì*«ïrY½ºÀâ3Ùqiîƒb˽¢{8k™Ú;ÌDþjN�‰ršònjÌP�Ò@_OI¯»àp× ENÉ¢�`ʼnE"X9%°çxHpÇ~ÓÎp_÷:º«V3“Ÿȩ�ךH°½f*÷;UñY¹ª‹d!ÏZR$Ñ’ŀֻةŠ�3ÄÁˆðˆjNèÙê7ÊpRw/BEÀ¢¡•¯~Z²PÛ"i°§3rˆ•c1�»¯çuv2©4Ðk�ɶ&ˆœ,ˉ�³þ>@59ìSžKT¤¬‹«ÄWçÑ_óÔµg3¦MÃ"¸êC”³•Ö@bÕ¡_�w‚u]�ÄZ¿r_pXë€O�¢èvA~ bàñè"o‚m½8Ä™ªnÆ„R§‡k&ƒaD"¿œ®c¢|DO�ÚêC>ãCÛ ›"J¨ß#”}ëýTeXd.DN´�¼RàÒÜrUËZ_"¤îê‡1ÂÎààm4Yà‰¯zmžµÄgEÐná- o¥'äÑÖf$žòüË©×s¼üöîtÏÐ//ý»‘#B{êÊš¢<ˆ¼Ý(8q‚¢é}Ëç)·ôòÔß{2ÊPo ïdHIWSTÚ¦’pûGÎd:ƒŒxJ'B.ÚR¤¡[_wE‘•UŸ%Y,ÈFkqb-N%÷·ÙúîËÑž<5e�b —Ùj˜áÒHœ7ÊXÐDþ‰S¥C¼v=Ľd¯QZ4­]F)1 šIÄæ ÙLvá€û}㢳}ëœY ¤cc}«ïûTuÜñ4½—(uØv?1ð¸ôC¢8,‚hñ"Jhë{ýE8Ã"™¤0**·Šê½¢{Rú‘WOWÀÁ°�<ö+W§KG(¦PÙ ™öžÍꦃ-¦ t³kÊVÞõäó& ¼éÔ“Jħ ,%K¦gkfb%Hy�.ÀìŸ}úåe¢‹YÊÝ�”MTsè@z×-ëT~2˜³:ÅÜu×ÖÙƒŸÜh 2¨œ]¦ÀxöcàqèÙÃ|”ÄP#e•�™�m­C§u´ÖÒßGø¤óŽ;(«ß@Q…‚�ºû¡—QÖŠž¢;K=w§ÿG(Ÿ§h3C“jyÔEC^ÿHŠtK9ëé£Îja΋çè¹BTÙ¸Ø�õ¶‡<îX-qתËUâplñŠq6ÖŸ‰L�ö…ø#*kEÈYWq¶EÍÊ5‘?'z ÃK^ˆì›î¤’®ªåãclrDÔázwøßYo»‰ßlR’¨NM,{ D)mŸ Ï“÷?+ÇŸ?ðõ¶Ëaܹìó¥U‡×=ÄSÔ™(½â lˆÒ-Ji�ͶRëžWM8—OQÞ% |èX™P^¤*(H»>59Ïå–rˆìfd®WûÉM‹Êi±±Ñ 0´Ÿ¡Œ’¯i3þ�ÔÚds¢ç´Ø˜ñú3ͽõ<ü Í×AKòèâœÉÎÎ~ <Ž{<ÝSfMâ,]é;¯�7¾®}B(ŸÆˆÍPÍ`¤B–a©E¾í±Q‚{Ò?…f" ;µ‰Âå—á¼r{÷èþËW0ðÐvÔo„Lu×Rgw¦òX7ÏÒõËGÙÆ� V¤ý‘­è/)<°�èd‰�ºk �°Ò­’�j~ºöÆQNÈ»/])#jNˆÜ°‰,\<.6)-Œ5…ߌð�på€ ¡¡}š(ß›²ÝÌ÷Úõ“”FE…Þ±àt^ñ_i¤ˆ>¾ ýOÑ4Tø½Û&eÈ/2»âž8AqjêÌžú`ÃpÊG„ÇïÿôylûýArÿóz‚p„üg_ɫ޶E> e5{t˜@ <¤ÐœH‹­)7…¦ÿÊ&j>*K ¼už³Lc}�gci½Ÿ¾/ÕïÔF~ bàñèÙÀŒpö™j­šø)aw Ž›µŠ$qèE¥E¹~äe¨²=2 ³‡áLŠÂÉ�Ò¸ÈÕ•µÉäsÙÉ,>³€æ]–•c1 8¥ ª¢E6äR.[ÑΈCÊʘ_“¢0RY È�f¨vØr—*7’R]wgÀ¶ýãt ö�kÈõœ�‡d™ýùžÖŸß¯‡ÿã~žõ ø‘Ï´ØV»Ø<”ÑÞ´‡ÚÀS?žL�÷…øûö�oï¥{)†i�n�à ÕÙ—ÚÍÈ€.$r:B±^§kh„’KCvÎo²xŸG[I;Çœr,Å>§UbE¸ïþ6;—¶£(ŸµñÖ{²¢ÎDjÚ�Ñ*£“”F&)0ªÕÝ�qrÍÈðÁ3pÌ^®.Þqå‰ òûDÏ5¢+¬SY�*LIê/ð¬Ò¯Pxû^ÿYœ7~çº÷óôg=)#¢@Y¶gùoŠ ™œuX´¾]Ehk7Á.Qx‘¨^>EyLlš›$65‘o2"3¹e�žfgûR¯çøÂC\þaÒçÁÄA-�X.혓͸r|áö©)÷Î[©Jiû Y™PÈúVZ–Ée6„W»–Ò°öï —’^œ&†GÀðh�mMPh_|±©DÍLi—(âýÛ”†~|γ~?úŠŽ}í¥�ô(´Ãô¡ŠÂÀ8¹AQè~Ô4âQ„Öð�°¥¨´ £´=§”l15E9û¿K÷“K5Ö W\ÕntQqº<à[J�(1V;±h [²h)Ǹò´^óìUÖ‘cîÔ  §¾Ÿœ“¿U›†ë y ÈÝûRŠ·ˆóŽŠmu\òjMJõ“™Nü w…¨Þ9M…ШÍ4#üHäÙ­€ÞùM=( ˜—a¯% Hä±&‡i9Ä71¤­4T@ý^˜ÖÌj7âf"?ôuÎ3œ~�¦J½¢ŠRS†Jz*öeà °ê!îµf ÓâÛ£ÕjU·�*œÿ•ך^"˜Nðæ„3ŸPLHV}ÖD¹ñ4Y@õ}M_¡ª4T;�ŒL¨³?ßA=7xÐh ŠÂ !y©Jnžqr½cfÒRo`€;rÙÄ<) ³�âÕÎÄò#9Å<¶çO¼ ¬°/»ŒåQþ[+´žoõ‘Tkä¾ñÏèìþãðgw‘;ч¥Û¾œð’CÂö·ø••ÛB+Sqm‰+-"ËãJŠŒ‹ÇþKY»0Ä!²àðÎÙ¹dÓÔ½Ö*ß½ÈÅka¹1ÂÆ±‘ç€Úwu +n³|Ñw¦ÌûÜö™Ôñ$�E#t@ B_†‡.€"÷¶›ïâ™Ö}ü�]«[zðFVž ±ýÖmËrøÖB­ïÌ`�g…i¤õBh­4ÄÚ j]xa³Ðæ°øÎþ×µ9Yƒ6m,35â.6Gÿ #¯|#ó·%Ð ü›Q`â5.q.æáöËžÌòºñx¸áÓw[ûgÁÞN$/á÷FG[/�ä(·Y€5Ї.ÛA{û_°Viâ¬Wwý¡ÇÃÄ,ßûäÑ&AÎÂÊ›$ky ü¼;û¸{Ü=`Óìk}Ä%—¤®9}¨ÄQ´”*û‚e[wã�k`åU»hßê‡V×#8€8°Ù润Ø�¶ôâ_ñoöc×ë¬é¶ñµìÒ·¥�@’dÎ.}¸µ³=ðÿ¯åÇ`¶ùÑRw3£ÿùç]t#E$ŸUQ³Ä§´�»´©ÂÍ÷te©ß¥¯e+¦ªÞ©^kÖTƒ§+�¾kh7‘/a‡È™¤ÀäHa+­U¾×šoáÌ{1Æ[,&6Zõx()¢�£ºY]2èmZ$U‘5PÙšsZlüàMl¿UT�”JžëqXü�úXÝU¡uW‰öÇ@;‘zh46š¢V˜�@†öç�rôâß”Ã#ksÂU«e2W-‹ÅÄb©•çXR¦ýâ½¢šu9-–ÙýÈãã§7rZºÐ²ÑM ÛºÑWŠÄ7<ý·ªÊ^‘\úG¼«¯f³šøäµ›àÄ cˆAŠûY‡'9&‚O~ÀK$ÂKaº)¦Ý¦¥"K1¹O�ýÊ1n e»Sدicâ›N‹�²“I¤ããw_φ‹n¤ÈØÎ€©©2j–Q•+TeŸòÜz¼q‰óßñIž<’¶•m·ÒçÖ9Ï!ãóÔÝ:Ìá|JVðyÇóºÑd�¾¹gsÞkÿ’Í{ßÌ3–~ M䩽³ºC&?ÌD¾³�£Ö ôHäû3;&dÓžQ‘‘,š–Á“ˆß\`L6'…?ŸàM {Þ�FXRŽïª]�d0×Y!'Má3¬uV°ºõ O˜=ƒÿÈF´­ÀÌL•ž—^žÍq×Z‘ã­®|Mÿ°Â¶ÿñA4VL¹×Fê)Ý—Ÿ8R,ÿmžo¯z|Ïôå­UaņÁfµ…Õ–Çiù|{¥‹µ·ˆâÕ¦ëPºgÜA t™Pž-ôA›Û–<¾®€oÉçÛkßX-px…îßþû&òìÙ—g{-/QfÓè0A3Â?"Šã"GTsˆŒbÌ™Š5†¹m‘D†)Ø–™�‘��¤0/xèÕ4ä…Mük#³u1ôZCºOl>nê†<³NM½aj»{+L(Ï“nøE /{›÷¾™ kÏBÊ|œ�7ÏÒuÿ ÕZ“’:’ZáRË:éés�þØ®èöð(¦�Õ�—*¼­H¢"meôV^v¬lˆu×´”°Bä†È�š2è8$™v”?”Uqo¾‡®z= €aœ×Ÿ×>`´ËÕ²Xˆ-[-³×ì~ý8¯˜}¢±UZñL+¶}Âïê7ýö†<ƒzS©«„X”…ÌÞßjª©/ÃjËKØúûC¦yß§Ø ™š:Tì!¹3ϲ¬l•tæJ "gè©XÉšËJR`&éBw09R 4¸~¶EþVZŸ)ÐjYœÁâ2î# Ì&8–VóÌiЏcªÌ ÿä¶H”ÔÄïy¦–°£0“Láp�ºrŒžpøVŒ7Õš´—±ð½¤Ì¿ÎР ÿ꽦šõå d7´;û;�†§ÖÜhPÇ€�^¬r]ÕêºQReUÝœJªè�;P,ŒŽ �¥�õݘLÕw2Eøq®÷Ø®è2Õ|ÎÓ/9¼o¾L’ø¬&>«I‰vì2²ÀùºE~JMo /¤îNMsÅŒ¾8P7�Ǻpwï$˜…1¥ÖÀrÙ{¤kÏÊÓ> KJƒ/±HbÍóÜÖ¯!™­DZ¤Z¯¡n”Sðê¸ìVÀ¾”:£*/xîo–˜YõYL,’«-r‰°Ú‚– mFple+¯|�$¦E%[‰� ]$·{Ì'&¨["˜I°I`5ÁJb‹–\–Ÿ©¤›äv¤<½£A¶ƒ,~ºï…›X•Çiáϵáaá>, «±Áã·”cJ]|s•m_úušõÒá ò·ÞOuÏaò¹ƒäÔMÛŠ¬»‘)äÊ 7ÐúÕ€‡¦ð¾'œÓ‚Y,·+¬�î¥u ©¦šF�× áäÒ0@¢,Ð;Ú:£‡c¢¼S4F¼ kÏ)ð¡¥�HÖTa9ÙÊ’r\¿ÓÏ1Ϭæïø>$ßúLd|�¾þÙÿ�›@7�:àÜeZ_%ôVŸo¯aµÜXxËÂ^Y+ÓL6 ·§ÐHãO®Ù6 ·Wc¢2‚¼†ðHO %ÉôÓ›:ãBxz#›^󪀿¼>àõ7ؼçOŸ†6Ð/O½ñÅC¢HM¦?/ʺšb–I4‰üT{Îì‰÷+‡ý¥Q‹ÜÃ1ö„pNǸ©€íVÖo.2ú‘&òw œ„ûM±á´Ø¸�ù�wñ`+O,ü81øù¥wÆø¼ù‰,W×´ÿ¿Šn3Iôüü° ÷P☠  JðŽÇ¸±GœQb¨¯«bÃÜ8R<.6=xŠî±Q±/ dY:QL{æ9¢š3%Ê:L�D¡n¶S%~ñW7œÇþ¸Ä«?ˆýšáïy/;Vfh��±�A/£Á™VY 'mbpàî9µDÊd™3�r&>ßȪì=RÜÅd¡—Ñ`ûÍž´ÖçK”LPwAö¡ŽŠìþœ˜,(Ýëí@9“¾?Ø :TF±Ù¯Nµp'…3—à·eVâŒ9¶¦ùGŒå‘=:FpË×9ï¾y6_„þsÊgÅì{YMÈ­ŠüŒl¦‹¶,mâ{zzñÀ8¹—‰r#sw©©ç#Ÿ±�èF˼¾%ìÉ5ì�5I„µdXvÿáË„ªhžMzˆ ·šÖW“ÈO-¡Rk¨Èï3E:‰B½Nפ(ȤÖVêŠPiÊu£*»dÀCœ1ÁLIJ™hžW†i÷ÇDåˆ(6'è1ʳÊ+å$ ~Ï'þ+‡cF´‚aÇf[ä~)Æm½‘?¼³’µZG ²~}ØL]q2+íøtÖÇÿã%Ð'&È_~‹ È}ö,‡<Úq€”G*‘¬æ¹qáIè¢&‘¿UÖ±ªr¹/¡82ˆ·‡íùËùé²�]#ôÕIµ z‡È¡šÏ8¹íéNÈ4ÕØ¯ŠÍ�fÃD&ðx‘Š\¡*Í/�ßLxz#R ©ÀäHajв&)ž ÏÕ/-räPÑáÓŸ/°*h­Ù,§"턜Œójªã±ç¸ù¶Æ»R?¸Î Ä%*Òý;ÃU¾Ýò8-­bµdÑRžöZŽyU]¿ú× ¨k÷¨!ù„¢tx‚<û”wùÌ?(ñQb¤›ÔÆMÖp…«8žXÅš¹Ï†^U”òÖMú\3Û)ÝXDêâ“‹Û(kϽ£|!'K—3U6✡bˆ9DMŸ�¹±Q‚C©…µÒô;eÚ!u7³Íª7بƒº©n'ʇÈfhÒˆf¦Ï.¤înc¨À€Ü"ºÈçãóZk–�ùÄaaÅæc‹.º˜Ý DhOßDÅ%)K3TGEe$…Å®w­ýI8Ïúü¨gSøáÍtÁ ™á‡ï¬Ø¬¾Å€ÀY´d³’leí}wpKyÜ`Á]Úì©åÇÆ¨ÌÞLWºJø@ rÃZÆ‹îð–Ý="¿SŒí AHÓÀ1pu„¢æÙ$Ñ5ñ¹BU.üÊs)ì!xë!œ¿ü ÝòVþø78¦2Ú[üÇo±ñÄ Š�ª4û|&”·ùÖµAªÚJ°œà'-#×´dVUG"XœÒFZïéÅ[ñz .áÆ"59„ê© ¿w˜•…Û øR$ß¼6 ›¾³BJþ¹KE×ë¿Éj*AóŸ5Y(ÆQ‚ÓÖ)ÁŒl´j¡®Ú6-Ü-½c��7€\�ˆÞ ý§.žýÛßö.ü¿þ¼ó36W\‡7ñl$¹ô§{í~ݽ,4$£´ÕW˜šÊn�•T–6ß[¢”z†rÌŠ�g{ü?n�½‡ŠHVæPÂaòŒ*àÂãÏbÛ¼� öFžpo¿šø³¢ë¨Ø65ÅyH>à ¸sºÂ�Ójꡦ<—�,±o"ÏA š¥KbëÂÃl‰�RwGÏ0±:XîwRÕ¬!‹Ü'6_>E¹—ã›¶°öq�V’§�äiÅ& n'yÖXþרKÈ(­ì4È>¢f‰Ÿ=ôkf•gAó1Ì+Y³HL:O²l kÿ²ÀSžÿ‚íùÁ42fÞ;r¨aþEóB¼�ŽàïÅ o�·ü5ÝÍ_f@nïAÿ­&Í®¡|(lÇŸ'½þ—«œJ\Z‚x Vܵ{͈3º-ùL%e¾&~vï’'Ü�·.r4F<.U—‡þΦÃr‚5+�ŵ‰Š¬©Ý¢Qè#™{þS刚“[GmwDxõ”à ¹aˆ;‚ DMí-ò¡ce^=ÛÅU*s•Êõg„Æ1Û#°Øtó3ÈýùëØ´ûm©¡e¡¶�¼Æ¨¤Ÿ™Ù‹)wÄJÒBªÂ[Z/òñ“pžõ øÑoÀ´VÆ31‚qrì›È3£*jTù˜ºš,ÐìóSF×ö¥%.@¡Í/k¼élø³¼êZ ä…KçS“3PÇMYQ[5ÏæNº–R3Üyøl*:BqNôœždãÔå÷ϳ¹Äç?Xக<‰å⧆îNàl?ÖçÁZ0õÚs.3I@¢.¤€hyÑ�DÍ£ ê!n&2n ŒfUMfaÓœ¦%9’KÍÄôg?w>÷ Rý‹à]q=¥ƒÆ<¼…†¼H¿ØDM¿y\(#'}¯º™š*3Nîæ{Rtª¸ÛÁP¤�žn%ÊjÖßÙÿ�Ÿ@¿ú¥EùÛ*(µÕ�P~tžMŸ=ÉVBÙ½» >œàŠwREø}è…9™Ã™K %›¶lV•c~z#0쮃ˆœ0u)=q‚â¬è’èi"rEÊ2C‘OÔ¨R]þÕ‰°—…½c©e$£We³*—V˳”ô¢_§&gç¨À›n=\¥2Þ»>hñöù_Z.1½–ã» hÄ7NS¹b?'ŽïJÉ'©ù£ÛŒðu˜|&�%cÅšpU0œÊ/E¡¨µ7ÊX�¶¥òBùÅE¶IlECœk>hñ±iŸ;Úy¾­€—þeÑâïW(þÏ1 —í¦Âž5Ò/Ï|³Â:mzùV;ë´d‘´-’8 QµyÁÿúu¤Bc†êßÝÂyMê%1ÔC:˜‡ŽÎœÒ¶Z¦s§‰üVZ/¨0? ‹òˆ‹8qˆððl=‡ÉÁÂë�³Iól¾™'ì#Ê‹šÑ¤SÝý¬xâ ±Y¢úÜŸ¦ XÛ)�:¾d-¼Ñ1‚´íæžÌ<–7Ð�Çd£`zâ¦wQsêbã‘y6íÉK¦-3x�ÂØ(Ñöžnn?åó`‚s:•?Nä£$àx;à ó·v>’g½î*44+º¦E¥£ˆBÃcȤ‡H¦¦Ê”Gö•XQ@KKf�K»…µ*-a�V@¬R‰·€~£yþö16Ý*ªæºO–¸P%ÜÖ¯èÚ.’¯•IîØB|ÃÚ¿Ã_/laBùoŠ †_ÚBÞè‡Ù¤#M叿ÃéDÊ6ÅÈš3ž O˜�<��t¼ñŽŒ±ÁdØøôçrâ6ûðUùz/E¥Á¡K(;¥#¢5M›Ê Òú½Z ÍÔ]EhïåÆ"»X|êŸr¬ÖZä&EîDÒ r75ÆpÚòˆEõ _¤®ÒÀ8¹f¾ÑÀSA4¼ƒ4 YeÞZ1°Ðe‘ÃûØ{¤È‹UÎ4é)?"¼¡qr �çR ‹7x�'TÄhºU¨|üv—•5,µqæM€çãÆ²Y´ä£Äã´6òÅ/íb²PKQ_£ÆzÉ™]ßx˜-4ûÒ>tÝÈ$ +èe,P-­$§ä›´ˆ†wÓŒc�Z©¡i¦…¦Rö»Jx˜Þ ¤îNÝB9õus×kî 6¨†¢Ò§t<Øï]|˜|ïîT—ЈKf@¢]�‚Ë-ÿä1ŸØ¬ �õ=Þ±âÄ¢�à%²HT@1¹/ÕŸíBÛóMá7‰|s‘SÝ€”3�µ“Ñ`‡óìU‘ÂÞïv¶­üµ˜ÜªpÛ‰Eœ‰ =ýò¶\b6ªí‚&ò›©ó:m»ù}j3JM ³vß¹@¬o å7g¸âŽ�å4EõjÂéeÔîU‘ÜM×ÛœöŠ v?QÆì* U‰cü¿ÿ‘|åkûÈgíúBŸ¡Ks¤8õTèÁ•ðv Q`¿rô¼aÄ£�v ¡ÄY3À•ò\Lqi Öä vž¾k“œùÁ]f‰ÐÞ?D®&#†A8àÖDÖ~r¾)6ü磃BUhÊïþ‘yCîXçÅ^иû¤…D7BN¦p#yåÙ¦y63PÏ`¥%$ŸáÑÊá òâüñev(4UñTáÅHýÎ#jÎÎ�âüñT*rÿ5Hdä —-cK ÄÔ/–ËI@’P½ýZ¤ÊŸ=ÂùšgÓ\“žÆ.£)@TsÞ ‚Ñ1‚iQYü.çižMìSžÜW÷8½š=-ZÂ_î’ɤ¬vBá×sól‘üÔÍ÷šf7'NPœV§ÚþCœ~ÎhŸqkÉþýìÇÀ¿åü‰ç£‡`Ã�çy`Vïf’ Ä­ÉQ°¼¤ÏùyýfÛÒ�Ë»JØúÂo‚�à .X1ØwE(>Í’E0Ф‰ Äìam#ù,‡&móIýÉîv_Éõƒ–~ç·CZôàÑõ†¨„ƒGÐÂ.,Áš°¼¶,Ä‚Íʪ $ ±]äÒÏ}†ë×ˆŽºD8ø™þVmÀ²Žö…î/^HYÒõ_Àf¨ó5hE,îëç·±Â�eõ Y+ô`;x_·°ÛßðÏ8ýG±Žì á%f_ëoú°ÚÜ*Qä²Í6ý$D´y‡_Ú¹|`VÁ.-°Æ±ûŽ*x è²Tò¶¦(¾àsýI¬Ùàù´yÂ?®’`“OÀ]kq* ic·IÖÀε!hµ aËó>Ã#_Õ%h}±‰ý¥óHúÒºmÇ@›Z”0ý?P|~/î—¿ˆWè¦�H˜;nÑ~NsÉš÷-bÉs×À²Ü`­r ÿ¢{¹µÕ¦ú°7®¬å^Kˆ¶lÁ²Á¶7b�Ë2žù–”€ÚË »Áë'+vÎöL󣞇3ùߌe”¦îc©² ¦H—¿z¯�®Ž�?:¯ÄÑG`<Á›“ÅŠl´êÓVŽqå8t|kĦh†*„f¯6Ïæƒßâü‘I ½chÐÃ8Ĉ«B«UÃcꎲç÷8ÔÎq\KrYISð[ɱ&ì›OQ¹éÆË§(ß9Må²Ð¤ÓY�á )úŒÈ5¨äÐl¯V×V4°…Õ7n@ÎÓþЇö•ˆß¶•Ö èU…WßÓ…9¡¢¡ÛžÁm+íÿg`”Wˆ {�n®Q/R·õ\Ð_UÐû ´ÿÙ§ý!ŸÖ;˜؉*ìR¡J �¿Ùþúü„œK8R¬ÉÔ<>±?Ï¡Ùk*£Äf%ñI”'V޶l>½‚ã�Lüz�I�£ÌKÎ6®¶a E%t�Užp/Ý;Eº¯ž, Ðæã¿½±È×.qŸl¦Û9V×G•ãÐq^»c+QÍ‘°/ ))42Qéøx´u¶Z?J>ª£õžÊt[§³=þ7©{Ø4ÒIë]È=&ÊÇD™]*H¢Ù4iýˆð¸ùž®'³ü«yô°)Ú,ÈB-‹$®°4óó´žÿ<Ñ}�èÂ`Š[%6Þt'•~áíLuá%]’¶©"†Æ ÇËè£9Iò´×Ú ¬&6í” ²ö1®¸¿zHï•Ý£F);pëûÉML��dtáÐEEžùÌã¾ûfŸ›Vþe¡Ä�k‡—]nm»|eÎçà"Îû>ÍSŽüÍz °�Mñ:W×ô{KSÕkD×3DÅæ¯b}øÓ8øÊ,ÜŸø<°–ç­:|~>à-‡ý7³ñ=»0� ¥d�Ì2š”I"?ÛV]ÎT¹Ìê'}Vc%•ˆÛÔ. h„«Œ† ŒöVÌïa]‘"µ‰<“ƒN^fj¤§nïFç£&þëx°[ ˜^½ÂÒÓÐó{˜?å2­+-ì9ù,ÅyŽ? 0Që¡1b\`FÍD}p…uºÿ�’s–Ä™Éq}°›ºÅHÊ 8ÛãÿqèFÜðÑüwNS¹sšŠñ)ÃM�ƒFº'åÄ–"¯þõm”ÿ|û5Ã>¯¿ñ¾zÏ~Ö +d×Çéºgœ®‡{.Dÿy#kŸ¨ÐjäÐí>ŠžÆÊ®~Tí»�Ã/'@ èÆ"S*sþì p?þv‡«?ëóÎQ›Ëþ:ÇuÏïh¨÷í²¦Œøb¦O'uÐ_9î˜*oEï.°¼³‰ÅBÛ"NL?ÚN°ÚrˆeóˆJœZ†•=ì˜íblg�¡å0Å·²R¢�í*ê®Òº¼‹öª1ŽXI`F8§„·Ò6ŸÑ–�T@I‰¹E½©ŠT1ˆ¶ÔìÁ¬„%e&…à¾s†êe¢ÄÏ_ÿ|òá»àï?‹õ¡/±ã÷¯ãw†~“kÔ…B»1CU¢‰|ê[z*ú­ èS]èö<­)¢�è·^„ª©Œu'‹`lgÀÛ~f¾þJòo¹‰-WÞÀyW]FxÕvš*…©8çQÔ•Ô„1×ÁЇF­f4Í;F©`èzygÀ#Ôqöcàqèu\SXÉlu̪uL”S�L¡FŸß ß ÂgS‘pÑ%EÆÆö)²K…~† 5ç0¤ ãPÒôOŠÒ¢Zá×õðU9ÞÊ3!ŸZ.GWK¼¯Uå×bØQ…>á�“clØ´Ü f¼Ô‹*—sGy7 RL¸¡¥Öäô§žaõT Öø†ãùl~m7�(Çt ³m8%¬¤�¥V;§X1ê©kk“±Çu ä¾c=eÔL mM’yº»BvÀôž·,çi)@íÔ©t oY¸ó©h…Ú-$ª0£ÿ¼Ê/ÿ #âùHF:¬u�U; qoݻǨp¯ºù㹞T¡¿QeV]Hd”X33Lã"Óð*¼ï}ö­V¸/)ò­–ËÑ–ÇØªÅ[ó\ý7™„v˜VÌQ-Ï89.;Yâåêæfuqx®‡” XïDÕt¢+�ömøc¢�¤D*8r«¨Ž‹®Ž¢LŠ2ïØ1¥œ÷ªÃ¢r¶ÇÿON Ú!u7j†Ž¥Î€RçË´š~’R&ݦ8c£ÌZÏè«FtÃm‰ó>xRI(0YÍ€+M•¨~°žñÒ�–ܪpÚ2AÝN’AWÓÿ�X[Åš[Àþ†(|ûÐˤûPšÂ¢Ð®é�+F‚:lâÓìóͳ1Í™âL3J½ëjrРǺgÿšC,XM,RÀ «‰Å餀‖È_×âçÚ»í¤ž ô”“`@?2žù¢§*7ÍÿäרªÓlEבc¨Q@Ê�¨s·�;ÆÎ`RÞy+UjÀ48D!“¯ ÷r¦Êû©ç$Q»Ì0—ábŒ/ÊÒÿ&¾A"Ö?�>4nÌ"‘QD¢ñTÏ…>5•ØÕ(Ð;Ð;|\l¼Aô ³¢_ŠrƒƒFægLf_^§+:3{ºë‹Qœé�f)ì£úENã¦�äoD+pª�ÈfUXZ5{âÅU¬GR1ÈvËçÔêôaöïÈeˆ+¡@Ê_ën*aeuj£Z`«ÄV¡`ˆƒ…{ÆéúªØÌÇìæB=×e)Á:-Xia/Çx w¶m¥xnœ¶0œñ4ÐS�EwIÓ²¹·åÒú%³‚ÔS “Ç“O?çöŽ „¹§Õ¬ïlÛigZuFXÒPVÛXJq±(èàDñRÆs5B?bO¾ákþŒë™BiÍ™•iQ1ì?c„9:œjþ©YÊÓ¾ÑenÅØ1+±XžÚq É*–¡ÚZœ\!ߘÖr)©œ¥Ö:S)·£g\FîÁStëAºÓ 'ò›Dþö òŸQD†Çp"™@1B™Šª†bÜ,q§*4F¼ýurGDñ˜(ïêOc%FR·”šn¦*9á’Gù·ÿô(mQÅZ¥ e3zgÝX¤0÷,‚·ìñ¹êÍ”uqmŽžÃsô ­sK5>Ö‡'È“I›ÇSJãzÿ¬Î^†{­l¯zfpdžc —ƈ×�¾’ãdÊãV ÈPb±ØÆ™O@ nûLª}•fŸ¿gy3�^'CЀáÀ§«IDÍ™˜ ?&6�[G ö3ž“Ìj@C6}è–åÓnÙÌÈe^¸'ìSkIb(«Š±â4ЕzbVfoVxÿcëµBî>çk(OMåÖåx_mgA~&à“4èãÄZœJ/kͦm2–ɪG[t¿m”[çGh”@ÇÙ$±ñLkïŒ$×Ôå‚1C¤5û|•r¬Ô-¾g²w¶©H¦…Ú&¥?ÞÆ:ý%Bc÷4›­ÀÙÀ>óyÆ+½‰x‚üœèÑ<›”Âi³`'g¶rQ=U°ix5¥rRQÓçÄ‘"?¿ü+l{Õ[8ïwöòŒËžE´'Ö)E¦˜XNƒÊe8׃oÂŽ4ug žYt�ÞþKOPÌôÉ;ÚÛÑÉ’‹Þê¡UXN\I\èõ ¨D$dˆ‚šôè>6ëÌ@sS×�tÍD eÉ�´:©»=•àO`19#t©+NìlÅ'‘Q»]n %øÚþä +eu‰ŽsŠx™Œv6ÑNÊ‹Ìó2~èFÏ�5K9Ú_r8ž a*Á_îZ‚cp°Ô6+úÃkXó_0Þzf‚Ξi(ì1³Â—²çݘ¡:&*ë&¯!<Ãv¬9¡Áÿ—cÃ�ñb‹œk£Tqç§U½ÁbRqËIž¸Ufùíý¨€jþöˆ¼šøƒƒ¤ˆÉОNÙ‚�­b'б׻úþ‡ôýõl& íÔs&¿C䨍~Ü÷Îc�–G[s²91�ýÞ9<=—ÓÙ{èJí�ÝŒ’íÓÔ?óç¶•¶SŽÉгÙ6û¿‰ òf²h¬wTsžD|S…¹Õ"Ë‚iážZÃzD«mìeá(ÁŠã€ã«Uâë¯5ýöîÆ™r«3بÉ8ðRŸ2ïÐ!ŠWï¥Èe'KøŸ=hÓ2Ò¢ZxF¾ÙCêB*x§½’8Ärˆe1c�2€ÕN,¾³_û"}ò{QÀÎÞÀL"3w8œnCbÒuçø ô–,Ûh-káY,ÄX­%ìeùHeܲ�(¿åÅ}QjJ˜Âb%#Þ1+º2°É¤(œùže4õf¨¦ôÓRýmŽÓ+vJ8²˜AJ€q“Äéb9ÌÌãé†t2·Æ;˜t3®Ò:I!ËðÖ¨@Vd|œ~ä…ÔÝ]¢p…¨bÔkMº^“£ÔF‹²~ÉãÆy›Ù%cª)9¬)Çû«¨Ÿ¨é_t#Å]CFL© ÎljñÕÞ÷ºCíYô~äíb²³¯Q„ÃK÷ Ä•çh‚­e‹Ì½cM>ãIzÏþ:¹h†êÄ„\»G1>áOV•'ÏTéU…¡q#BÑy”7ºIá#³ê§¦õ”ݮÂ_!ª.³;Ÿ'V�¥²v,üS"¿ ‹¶\Ve±™rë¹ìW._@ê¾Ú�áª+òw‰Â°¨tRÅÝ "dŠ:¡!‡„Ô]¢¦O×?Öµ„²pf�>»µØîB©8cœ&XœXF±Õ®�m&pŸâw19R0b˜cÚ[tÑ;\þ5ÉRtcð°.uO'ƒÙOVaµmj§ÒŽÃ²,’ø¾sí(cA¦¿WO÷†Nª”RšrÇ;üñTë=Õw?<‘ªI9ª­Â—”JSÇ-›Ó`Qyâ8ÇbBîºezuÉ:3ˆGÉ/ŸÑt3RPößÔ^"m+0…!,q¨H8ÑÃëÔÍ i¨�1ØnÝc¢ÒE¼¯È„™ph¥®7Éb‰ïè<âwñ"UQ=מ&) SIÑ�\�døúÙùXÆÙYÇëÞÍ�ä ׯüÿÃ?`áÜ]Ãî¿ñÝk`·Û8±•È—•€e�%,òkÉòì=žÕÍêöûp¾¸ñ�í[xàk¿Ï¸š‡ö^Íuײy»Gõ…ögŽbå1§y³—Q³8én`sæ«Å 8•oµ/êú—ßý Y£e.B ØNBk-‘%|<,^ú1v¸G¹”Ä€3,¢Zâ*¨5û_Àú_©_¼[ô<`]NßÅ÷Ìá i ñå„—Tø™׳XYvNØŽ…,g-{»e‘ؘ{Š­d¾¨Ø° â<¶ë[ôŠÞ{E90 ¹Ä\jla­Ëè +!¦VìB˱$Ä$Ë®�ø‰¬Ä.ñÄïÞÅ1àŸÀ¹a~;6Dð7XP¶èO¯uïm‚+ÓïyHÈüsu;1cq.»þ¾áñ_þ>!¶||PËM,7�‡‚ViÛ6Ø/Žxÿwîê;šBù-I’°°±ÒÏgŽÒ’¾£æSŠ£5à¸]]Âå�7þOœ¼šk>ðn>ýW>ø•Íô›gÿ¹¿ÁùYÐ�Ï$°þ*´pG.ÐʃØ1o¼m¦’“�ÿðçpv¿2\`­3#Ý`ãŸ\Ã~rí,ÄÝÙ^Ñ¿ðŽ¥nc£ûÈ�LR {õéð®‹ÄˆÚñ¢±^* _ˆ�3hªš>R×3ÐouϹœ–C,ß ¹’ §æž‚^𪶞3m:jr.ÝOÎìÑêiU^vMÿˆ(¦ ÏàËåÓñr|ô†"Ÿ8]àŽÄåÛË6“Ëð@l󉕟üŠòÑ Õ»Ä=H÷.Q &‡ÉF�>õxè9%Vß\E×çÐçËèoôZ6é—ù»ÅóR/õ¼¦Óªt„ÃO…¿XfF�Q§IpŒ˜‚1O8%˜[!w\”ç³"aÛTÅO ÖVóLËâÆy<=û’3ŠªåÛE÷SÐs»øâZZèji¨¶°Úm˜N°Ö–qæµMµÝø áœVêvÊr{#¯éG²vŠà`ƒ†ª[bû\Ï6ô+›Ð¶Ðþh™ögtí&ZorÑż~3R`� ¦imcÄÕkDÞU׺\¿\åÁ¸À7Tâ»+>ÍÄá}§Þ{ÑHu§ KQ×ÑQsö3žëS „‚z�ÒØ(AŒ-²<ÆÆ*?Íò ª,Ï{¨�£­€Eù<œx<üH/úu& Máßhä¹mÐÏÛì[ 8­ÉR@,¾xïçëçhž,eæ ™ÄÔ82>ð)¬YÈíd0FHãñSŒ“(M‹JcˆÂ‰)fé¡z\ôFX‹-–„sZK‚øõr²$#ydõ�UÆgs<,—•5X‹óÄ-�5WŽO>ü2qÞ]bÃ¥YeøÅiË+Ÿ펈âÇn§û`ƒB'ín¨ÀÔ]¦ýÛyôÞ<ºÓEÿb³vM…öoý1=Hþ%¢8"ª×,²mPÌ–k^äð¦Oº¼w.Ï—Ûš±Çå¸{럖p?´J÷ñäë^„”£ò±éN+À~úZŽ5ÓÚ Z«Xm³Wµây˜ÁÞù8ïQ ˜—ÍT‚uä p¢8,‚h†j4CuZT†™®t1;,')ÈX?±$ü¤…õ�pfÌÏv²€›4zÉ"Ö#ÂZˆqÚw ù„²ohÒó‡ÓT� <õ㿆õws|ºUæ_âw-ç¹M9þiÅçÓË6#sTöä7_¿ëâÃä›ÂO}Ô¬‡îbC(JÐ,mB¿¹�ö»Ð]=èö*qÑ%S$Û³�¼d°ò¯Z` ’ÏU*#S‰È�Ž¡ ;ùד (´ûŒ¢�-܃‡9VtÝrÌ`¹V%¼©WYŠ-æ;{&ÖZ§dÓŠSuÚ×�1 2⩆"—+óÄé‹Ùòú×±å’×óì7\ħ~qÚ“ß!r‘È÷2„o?‰BVÌZ¼GÒ‚l3ƒ%?^}�O‡ÉŸ8Aq¼N—¨9»Éd“ê9tz#³õ.öžØŒîéâþUM¿½æŒ â5K”>÷AŸIÁbB »#@à«Éãý×õÑô/Fy¢šÓ¦EBÃÄJU?%#ç;@½D*YRw£LÈaÕœÌñÃÓ\p\l•„ìÆ Õ·eùOý…ËOåù¦ hÑô½ Ö&^µ³*²Ǹk‰ËIå¹'&ÿ[¯6YÊˆÇØp@m"ŸGW”Pj¹šÀª‘§²Úmìc·ÄbbÓN\V’Kq‰9=™øJ2YkdeRL¦ý9€å¢×;Ì(@±gZm±άŰ Ü™6îtb¶­O‹jë�ÑæÑÔ…š6ýåyn_s™J<ÔÎËá‘5¬ï) içIÚ°˜ “ÓmøØ|•#¯ewo% {'= ÷²¥O=Ć+D•† Œ Œ*S¿ä"“Vׄ³œ®Q%4‚^Æ¡à´Ø¨´ÓÁи�Kó±÷ûL+ŸNœ6máEX‹‹,+Ç�#Mä#£8ƒŒgÍ“%þèø&©È!›©qr' ¤/ý~Ã÷`ÃHp˰­L¡&s˜}\z$ü(%d ‹&‘qÚ4>åtSMsç4•ýur!ucPè¼÷Ú ©Ä¶éŸÖéÄ!V•$qxïûèñú� ›þ/ŠpÞö0[†ÄV Sezµ‰WÏvqHEFPS>lâkšÊ'GØvF)µæy3 ª'Óª.½£{AÏ+ò=åXJ§%Üá-¦Þik2ºì31ÁZË´ëå±øÞÂvô»|jïf$—=ûòD5'Ï-¯*³¦Ì Yn»ÌÉc^Ô¡ú¬&EXp¹~Þ壯EʽsÆ\߸ȹcÓGNqÚ6ªù<é%opxÏ© ÷/æYUÅy“ÒÆíÄ#NòÌ$y‰Í;Obø•—‰Ò³EÕsüö䯧±ú{&ó<”àÌ·a6ÁÕš1tÌTfVcÓÛO̶ 0Á泘pAëW¸JåL*Š ¥˜ˆ¢(�ú½oŠ ‡çèIr\4ÛÅÔeÏõ°÷Äf^¯MH4T E]§®/ï8E7Êã}êƒAFâ±–Ìá­¦Û%V…sóuý©ÖÞ‰)>tš ÷ÏP%í(…nß.ºïöïÈv Âq3¯ãbÓq±i}€7”y¬?vºðg=г½J/cAF8ØÁþœ:dˆF#t¸äP1ÐÏí})Å9ìV€û…×Y�C’R73SÁöZ@Q‚÷•Wñ~ôŠ".Þž•½b3Õú‹pÞù>üw$~ŽÒŸ¼ŸóÞökHîî1*ű1*“l+ 2âEÔœÑt pìò´O…fõÌ}¤žã;‰Åœ”…™•UüãUŽœ¥e‡iYœ–™”Ûóm‡cI�ï0)ü€‹dõ!ÿ¹+ŸÇÊooFwç9�8,´}–äÒV>%zt£v7ºg Úu*r­J£cf[ETS_5k'»ƒ(·óCÎgå·¶ÿ/c_ÕN2ȯO¢"R‘õк3@;Ù9]ù݇Ø`°ÜHn•é;=ŽÊcr g>Á9§.³ÂŽ—-æ‹Ó2�¯U›“2™Âb’c^põç̵Ùêìÿö lÐ4•´5—«‹�c)Œ¶¾ŸoÕùG×,jaiO ž’3Ì·µÄJ‰'6Z5B‘ÉjEÍÔayÞ7ˆN–‘76J0+SxŠ„ÏOý×_¤ûÞW°åÃû†›ñ÷¿ƒ�±—ç†ÏDç9H�ú@N©hcÆq§/ôkûREäZ„œ&ò¯úPÊ´ºðsÏâIïy#ÝûßEå5éy÷_ó„‘WÒ{úâL·–ÂWé÷š,ð¼ot!åig°Ü„ÂrŒJ¸6 sÂ^I;k© ¬ÚøjÁÈÿµJN¿Ü?Cõ¡Ólò&P>Å«;ˆ`ÏaòDÆ}~›åç�Nm>-™?[ò‘zX˜íGÏCrÙ¶«�ºÏXL(χ?}�ÅçŽ[< ‹Óò‰×`M8Š-¾—X9Éi6ÞiÐu¹‘!C¤êe,0ÛÍ~¯)|í&D^È€;:F�¦é�1~Ý0õ¡C¡=œÒ…IÅ9”šD>~=Ú“ï`Œ_zcE~Sø×F†Í&pÇ/5ÕŒð'&È:”zmõI£&òŸÆÊ%ægXÏÄBqÀÜìFô|Dñ`#5°�Û?’‚gÊŸúþæ M-#è�ÄJ<Úòùä Î'?@J¯$pûQ!&(©‰ùËRˆã~åŠèµÍUƒ2[0”O?6Ü•Ù÷¢¥,° KK‰…Ö`EÆT�'¿e’O$¿)üz�.‰ªYE•ãwµ™pºÂÅ= 4KœP‘[UE» ¨¿­Ã—àWKKG„·{” Öè4<Úu‘ë>/V™;¦ÊD�*¯×&î!ÔFŽÉ0ìBÙ»wš­pUÀþêÕe ©«•n�æ¼Yq>»Œ5g²®c±ÒaÅÙ4Wð´çšT7ÿŽ•�´sÍH> ßHxVß3˜{V7W·XŠMÛшpØ´b³�y@UnŸfkOŸ‘Å픂Z@³]°öl›ÙY‹¥Ø�•bSĵ[3E.ÙxŒ²Æ¨œ¸Ñ¬Â»Q�vë CÜf3³e’»ƒº‘Ò£Ñ ÀkÆ~çº@϶}aæ'"ÐùAXŸ›‘ö;*�>]¥šÙ ‘ꃯë)¦”ÃtÖëP×íÛ\¥4Ï9ãJQQ°ws77xãõ6W\‡ýÁWðÎ[«4ž\ E×­i±Æ¬b‘ÿS<ô«^ºŠb­ÊA:ƒ©NbíZP…ï´Ù²ò"nR%ÕwékúMäLsè"�« [×㜈 æÓ¾tF Éè -ul�ÜÕ”i–$sÂZlQì²’`O¿ …�)_Þ|7™K©Ñmç1$EüoŸÿÈL•êíK«XiM"Ÿ~�î#žI:l;«mF�·˜à-±ßV™ÉöÏ ¿54Ú—)vt59)dÖ¹t?9–(êNüù¤È¢Š(ñSÃ<%vÚÍ0‘_¯SSéâÃäSIl7 >þihC�×]æñ_¯s¨]ç°÷�@[0¦ š•»#B‘2!×#î$Ü< ©…³B¨mFƒ6 Wºš‡ø�¥Iã¿G ÛY§û”ôGÁQ#^ækeÞ“G dçØ ®š†å– ØD5§¶ÏèÆ]�ª—3U~3Õ^ÆêQ ä.Å»dÚ/¦ ùݼ|8�0Až¶}ð�bƒDEîoSzÿ_36PÊÑoR®ÃÎ+¥£¦¢ ‡ö­¸$8'LËæ}Õü»—Š;äeZlÞ²r,Å+Úˆ„õéÏóRÆÉ©,Ó��2²L*VxÖ]ÍÅá[}Ú«°`”o¼ôžr2°]û‘$cÆ� ô%³ê[Æ|²È¸žÆT=ý>]T7zpý#ž)~5 c ŸóÏþæVì{¬YU‘¨ÿÿ¿~XÃ"¨‹\'�³ßO«î�Ô�%ÕiÏ,qlÀÚ% ¨ß‹D~XŸ¹—îÔ6Ç&2šbȽKl›2|y/cÁÝeÓv{­“{8§[Ø'SMv%…´ïò¹CôŽl)l¹š¢Œaãy ãl•ÈõŽЬ—lùŸo&”bã�Jвœ¡„ÂrbRƶ°cYLÊfºU0©{‚ý±¿Fò?”’pÒ{Ïu„:+ÊÙ ôù¾õ¾“"mSeUøk1œ’)Â-&™Ž“Ñh­–ÙË{Š ¤<ßÓôaúG¼HäÆÉ=[T¨É©ÑL餑ß$ò)y¡­$+±ÁãÛ§×ÈÏ&X'E¾•à()¢¶ÏḂ~sýbQsÂ:¥¨‰o‰‘�ê®Ù‚U]änºÇ:õóû /•ïÞ.±=Ë 2!’Ç0óúÑS÷ïgâðCRôK ŸoSd3U˰ó:Î(¹š"TЀE¿¼h]Š;ÊXp¿Ñð*�‰ŠÆ¨¹£|3Â'ª9¦ðÚ¼\Ý9ÚWJ¡¤§c‹¥–…!ôÐÇØ9]IÝR=P jŽféš=4d|ºkrŒ…ÐDžUŠøÊóžIèíäQ�nÐY«°¦€–ò¬ìåÅ*…éý¬3¦HÑV…¬cq¶ÝØ(_œçæ{º(ÇWX¬gQø±gðVÓÉ-¸hŸŰâÄeVÝè ÆÈAÖƒ§è6è€Ë€ÙŽ¥F–^DÍ™kÒs¯0›–¥€ (¶˜•ÃÂJ�ç*ÌÍ=…å ƒö)X5”7UïšÃŽzîÌX ݇óëÇîè0AÁö¨@?3AV¸?Xék )J^èOÈŠ{©ývþ'&е®Â¾~Æ[w³nÇÕ3­˜ßt'•¬ZÙùÒúš>`¿ôÅaP›È“Ù×^kü¨›È¯Ñô%ñq±åô$gE—êæÿGS¯ë04Úè�ÏÞOnÿ�Á7ûð•â¾ëûÉÉØû”~c€Âû«×|1Ͼ@þ5ïàÉïýÕg‹Ê q{±²v^æJ ²GñL 6¼q”Sª‰†j>Û~í/n™Çºï¸pÕ‚%Y(ñi¯æ˜S�“ÊqLûg)6^…ŒœVâF™jkªt*‘«§ÿ~¶<;ë"g@<µR…ž[÷�¿æ4Η˜iÙ´ŸxÍe^0£"ŠMÏ{l ç¦ÓxûöP“s\lš]©£Ž±·Â´±Nœ ¨ÌÁy!²GDõe¢Ìe—n¥úß^žãÝŸp G]ö| û=ÊkŸµuhÜ€€vžiOºš¦2u å(µ¨6ãf8˜š¢Üœ 'ìx¥wœgìrêÂíÝmÜb5Ŷ™U¥ÈÑÁ3®.‘ðG&)Ü)¶?°h¸£F ØV?^?òTKí™ÃË¿{ ‡i 4) õ“Fÿ˜(�›�ëÖ�3h\T,ÀºZ/%ä^Šr©Þ»{�FÁ€)LAã.±áãb‹¾ÅF¡¨u¢�;R}í�ôjàeðC&?6šÂ?C|ÝBy_DÞà¨ë.5å/D¥ŸæX™èd‰kÔŠÒͳ)CWlP0ýشׯT[ åCä~}”M’ÑC'Š”—~×BuœÉ4ГU#?•¬8Ì*Ï\«Lòý5•8qQ±/Ó>3+Ùêu@¡3ßýÙ ô#©z¯‘KV‘úäFž°TÃJ¾�c±•ŠH¶N ku%�Z.‹²h×ÙÖþ]>t¬, ͳéä8[�.¼üZjK•Ž“ÜþäFRÁEÝwœ¢{@”�ò|èXùŽaª\a¢‡©ÊØp°­A�fŸo ©Ø/Fåt+WØûRŠ„² ¢æŒ~…Mž¢;+œ5„G¿<êÆ+]¡OŠ­ÇŽñ¤YÑ54H¡Ñ PqÙ¯59O{ŸÁµ1í×�a¦4â×ȼõìÌÙæ?D K¦Ÿ˜i^g�nú�5€ÌÁd²@¨î˜*3Ⱦ,¤d8éʪy&£ºßÈ*6—*§Ý[®-( ÿÃbSs‚$Ÿ�ªÜ:ÃŽŠm)U÷¸Ø´ð0[ê!ç2öäÀ89& {YÙLÖõœ]á¸}4}ˆœ�FÁƲˆš~ŠðôØ{¤Èð�FÇ*\¥ò5¢ë¤(u´S¹ïT¹&÷X=§ÿ�Þ)Äe/›ýÒ³tL”3Tïœ6zëRÊC'´9r¨ÈϾü"J{ßHù5¯£äÙ¨ž#Üß²›È¯‡¸æõÆø°³ž, e�ÄMS!ª9ô‘ö+'L+*Mû!+¬¥ ¢|2~)¹[ŽQnfƒ4ÚïEÁ‰Fõ¦A¿¦à›T’ÈE‘/³÷ÚªaCp*Ž2»ÁÐ~ÓÎ;¡"¯V—œ(^ÈÉÒ”c{”GÊ£(¿KÞ>ƦÝ(©»—p¤¨uÖi —;™Dª ¶}åÆPEÈ@îÈ­T;Ü…z=‡A›Ø6R`G=w )ýWõÜ@êy–Ž£\8Lde&“ë\vìZ p¦Dùð=)³ÌV G—’Û�!êP Ü˧8ïÑCMyÔïÝ!Î[\dÛ~†ru”;.6é[lܽÓXn×Q.¢æÔEŽqŒ„˜ä3Ù( ¹»G F ÐÅ®Ñô Í7tá¢"ê7ÏþÞ9}ù9ïÚ? |z㢬º±SDzªá�‹œ!fýdúú½¹-a7›”$òã)ò "CãK ~[À#²XiITfA[X»MÐ%ÅéLªw”`¹ü´Êôê)­×æi(¡Ø€®à¿¬þ ‡çzŒ›†ü,À_ñ 6Hxa�Í>?5.,pêÁnt¢ˆTbXÆuDUjrt˜ü½¢[¢{Ôð£íiQ¹?ÕE‰ÉÁBúY%hx‚ºû˜ëá"Ù§<2RRFÁ&›°ÒÁ›a§s€µ…½E¥…�}¾�µ°ÊÓgÅÏKôhİÌRø«­Þtj{|¶ýŽ;(kœœ¨9 TÐ,]¥«¹¨˜z›å4I¡VËŒåf‘ÑaÔÕÅÉkKÔ£¡*ü¶6ò»Ú@¨ :T4ˆÃ>ŸÔqhœÜÁ…&òOp¤!§)üÛE·féBòÙs8Ͻîù s=9Tä3¯3<]RÜ6rºšýÍP½DÙ_ï¢_O�ø5úDEEâײYOfd¦ŠöäêgdÈjÂaBùnž^å¡ïPË'VñÃüÌ©_`l8èÝmì¥k„¾�;5Eùžqº~b}=yåÑ{ŽÎŠÔORÚ‘WŠc7Ô>¹;y6|5ɳ¼ì°¦"jå˜W…1ñ¢?yNŸðo9fàŸ Q|¶Ì<öŽÙÜÙÆú_-�{Û%¢°ç»üòÄEé ì 9}4M…3ô„M|îØXæÄ‘";‡ŸÂÅöël}É ø�ú®P•¨ésËåå[E5[Ç�U’©œ¦æ#·R}ÅØÐ+Ìãü/\ ùc›Ï¾þr÷}ïdË»vÓ{ÑsLê'"§7Mõ†�ÚICxO¾‚ê²³"B{ð …Ôʺ˜íùYñs«âgS…”TB:å4ñ\]ãä¦n¡,T5GÒ=ÿu6ÕCÜË¡üß_Á†¦ðG„·‹ÉBˆìíLäÃÔà�“×–øýÜ/ó„ð•ø#Wá¾õŸ(z;Û^3ÈÓÿàâ>ásâ¢"¯ží¢6‘OÇ”;Êp &òBÞ˜Ñ (¿}”Mg §*ò”·üçßùžtÛ¯!Qd„z�ýâ«(æ3tGû –}DTÿ“èâ)'~oïw¾Ü¶¸}ÅáŽU�/·ñ®ø.üº8ŸÕPšÈ§6‘g¿r‡>UáÈ¢�0<£ƒðá¿eh<'‰f_–Iʾgܰô~"ýûVz;C í¯“KS¯ŽP^�Ãù�ì}-®‘}ÂNV`:±ˆã‰(~ù5¼ìX9³/®Ñô)kÃ6´`$•–¼öù$Æ[,¨BkŽë´?sÐ0+’a )†Èíb0ÄŠclùbgmÙ¦�x,ŠÒ?¾•èd‰�ºÛáõÿýOK¬) –�V�bÉiQŒc¬ù$ϬØ4òJ4àî‹Èk7�)ŽÉì§z_qa‘›Où®Œ‚J;$)iå_øø—¼ó—²ô?Šp4EÙðˆ/6ª³59¸ð>2_åÓö“˜`JxKcdÚg+ÏðÒ¾ò ±!µ 2�pvÔÉ ²­ N�Üô¥ûBÓëgh²ŠÒ` %3ìë8Ãòc˜yny‹(^!£Â"‘Ë 0CT p›Â¿L”î•KDñÑÓÅ­»»¸~ÕáDâ¦z’ͪåi· $*ómÙÜ0ƒÿ‘ËiŒx÷‰ÍŸ<Âöq‘ o€aÄE*|äº<Y.3­"§dh¬ ª0£.îùÁë2«.ãÆ+—õMù<á-¯Êñ°,N' eŒYƒ<´–cAy¾'ž°û•4å÷!ÿjQ%N=½»J¬¼!ëÄØËúÿØû÷0¹ÎòÌý­óªcŸt°|Ä!"qB:@Œ iNJD&dOe“ù<Ÿ‡™é$& ŒíU6vÒ`‡¶1c)ä4(†`£( 2´MÛ´h7Ýên©Ï]UkÝû�÷]Õm‡Ù³¯ÍÄ6C¸®ué`!u¯ZÏzß÷yîûwãt ](ºy�Z£ æ+¡MZ­o’`~L ýùü0…›ù±ìÆ»·å1mY]J`.íå» ¿õ[¿À¡ësPóÆÇˆÎg2Wæ‹·•iµ]Z&éÓK·(Í’¤�$ øúûاÂÝÝ€ûJȰòÛXÙsÿbH˰Â2õ–sV.ó†Hã,(àþ³—£ÝB9Ù\.H`Œ´�¼þÈááNÈJ겞âYõ[¦úÊ„!Þr’…0ºtD¨«ù¸zß"v~Kìšœ|ìÄÿ¶—áºÉŽ�¦Ä¶ûÄÀÖú*uÙ$�ÃSy]iâ�eTrNÇ ˆë[ï¤Æ`C,ÃŽ¦Své�èÔRÌPÝ·ÿ¦Ç näÉë-8K)~ÚÉ(³ÐÚ€ÓÆ$ê)ñXÔNÚ×/Šmµã†=WE>W¨àòOï5Ž7 ll´“Xq¸{5àïgÿøvdrøNÈCM‚Íc'xzL ýÑÒÁ¬à�<¾® Xn é†bÖÛçÑú+n}ǹ4dŒ.5ÂLå8ù79–,ŠÈ"ˆr±‰Ê‘(ÇøM\ªø˜(LOS¨™¬ñ|Èò•1ßÜðÙΪÒ³¢Ÿéൗqæs 9¹>@û*ѺÈá2sc‘ýÏýMü{—<¦Sèlø¬˜"÷Φ�(t'1Ì4û †h�à½g8wñ7þh…]cKlo4ÈW«�ÿŠü¿¡ÐM6™™Ü+úL¡Û<òªûh0`j8Ï9ßÞ�ÿŽù’¶1·t¶H‚3œW’ŽÛ¢Ý1uüÉ”üçWØ÷Ë¿iè«ò c–öÊKÕïøîjê²aVS§-ܳÂYkÙ8èÔg£ÝËìFcžžE±mr’\ y +ïòåwF™�ÖOüÄìUmˆED"ܯ¼ƒÊd. 9Œ�D/bîYýÌž* 4@�¬>Ò»˜�-Ùó¶?ÎHôøê�\讲0 {¤ØìàÞvŒB­IHU®éN§wÁ¤p >º›ÇÎFêt=ûv·å®M|˜¤>‰ÁF?<¶•kT<öVÆöŒáëE'V2,5œáºpWLk� O©K'íEâ‚O=Çê8œÁQLâOÿï¿®Àh§Ú.k2”ØÎFÀ¢Bæ:ô¾æuH^…jXá_Œ³]¢Ä¥ŠÙ7½ƒ'�üλúÏxêðïò% 0©Cò+¶Ï4Ìh žîü8ÍÑÿ*ôîø ðÀ¢†ÁC¿ÓljK TçÊ\®^4•g~¾§Ö$l6)S‡¼ÿvˆ~îø©¾>ÚsÒ¶c Iä,¥ÔÙNr–½êï¦G+œ{b•óM–:Å^ô�‡¡6~š­¦D«Æpá)1<·Î†Ï)õÒ¹äh” fm‡äõ‹8GV´á’ wMn÷¥!c·dÝHÐJ6 ÝðâB´ò@Ê Gž�LÀÀc ø7*t³Ð7�i[F¬FÎÚ Ø{ÃÏçh*‡– ³•š„ÖŽ…ešívÎaøs†3ï,¥Ëë[ÛAû¢*òk¶qyÅuˆ:¯ðøÆºáѵEÐiáÎ ·Õ�µ”¼g �€–øó—îÍnÂåyãeª‹ÛzÑ™�V@K.Iⳑ$*�¶KtæøÃņzÍ3�¯zõ}H†¨{»ÊÜ3WF*ÓT?R&sCȯ"ÿq…Õ&áI=vSÿ12ɹŽcRð€Ä±¿pÇ“S\þmFýZÓi¿ë ½¿çhÑÁY« 9¡ÀÁi×.âì­ï{ˆ…ÜÚËY»ö/î¥Ýö=’Ôa5Yqî>»¢·๬.œ«ÖrÞ gWp H°!g}ƒ…˜Žg”ˆ®‰—Bâà´œV˜ÈY^áþuŽ<#r Í>Ò¡‰þ*/ú>¿œO™Ç£DšÆ’éžrœ4µ6]‘’:‹à¦Ž¼‚hµ@弸À ¾pð—ÛÏúVSzV�ïâ‚Î>FŸÁ¿Éÿ>âHÐSäx á>ˆãEf ¸nQ )ª²Çv'ùÎÅ Ð!‰!pÒÈ�ö‚„‹£‚ãàZkâÈ[¤ ’Aê)$a=ŒtzqŸ`ÞùÖ“Ò»¾OøÜÿ‡ þÚûA2óMÑzš~›öFàÒ›¦Ž›ÂšÇFœà”RÔ]æv·“o}UªVœ€¯¢ê=O[®žRtæ“G�ùx)9´=¥å�—z„éb|ý<ÏØ÷|ƱÔÂAþW|`ýÉï%•œÔIÔaüañÌ]m¾øÌxüâowÎ�Bq�k@ûw—6»ðví%I`ã1û £Ýã‘«úÖ3»§Þû>Ã@CF)ÄÈX$äXµSp%³&Ngä`Ç ÃGó=$ï™ZÇ=k`’¾:NÖP²«’gÙs.�w>Å?�­Êa)ÅWR I‰îºªþ±cf?ñ˜ƒÿˆWâÙì¬»ÐØ;‡‡íù}H>¼ç¯ûH�˜lù(îB‚s&u,†*~6ü’q»ùJÔŽHÔÏlç:·Ö¾Æö{æ(ß%úŽ £: >öµLó¬e¶ý¬ Gí /mÆž+L,ô22VnŠðâgP¢jÇlcãeöiÇzS?úÐ6:µ]èMìÓ®U‰†òá ]No­†§1"!3:-±½)BŽìŽ-Œ1�‘�†Ã zöŒ5DÞ lòbÈä³Uö†¼|ùâ7M—Ìêžâœn9œ’Ç‚p–Ú0§2Ë)ñL1¬mˆ°6OÏ;x·è/Ñ y8u餆h2'¢v ?±h©º”Þ•˜Ó€IDATçï—×OÀïÿ!{ Ï`÷¥dYêñ„ÍCëe,Í'Sv>¢Ñh/»&¬�Ö¦´%ãÐÔÿGæQÈÐöòKBÐãÿ la·o-ô Ÿ$—ÅÌn}!lúV}=]ö{·Øí‡FU.×]RàöƒeT R±Œžv>zåO¡ÿøLôôó™Ì1T÷«MBŽ“ËU£Säw‹xí_.ñí6,˜€€@©É?mçèëÐÙ0c"Ùq*â³"g;’”ÿ°ú|¤p„{Ê›¾òçËx6þ¶ãžz ïYȨŽáØ`v·§fìec°Œ¢p]í6á†ÉxÞ)áÍ´ÒÄgM¾»ÞGûH4™Ëv Ø('0Øèa›Î=½ „”ÐE0^fp4`pÔ$­ ×.$ù uÕ›AÄÙØôHd Höó­H¯-áÅ-W^[É@[žo²AkÒù‰)ô“¢Ô�Ý­Èë¦sH> TÕ …�å¹[cI¢”ñ³³ »˜åE±M§9oe…]™Ý³V£ÿã_§—††ç|ù Š®A=Ä eª¾�[.j\«’ǵÿ`xíiÇ<„óM ´ºÌr#úH;Xµ—Iu}pÉãËŸâÌC}UQÔ8åûÄÀã}ÿÔË®dù­/Xó’µöaA¹Æ�¶+s籈‡V7-’’Ž:°nÒVœŽ�0VÇ¥-Ÿ5œMC¦Ÿ±äâ»K¿.ú>}–þ¯Á` !|&®Úøj¤�©á<ãã£/íAÆA˜Q[mîý£Pe8ÕMÐG–IJ%G Sûéa%µnh¢‘þfÌ€Œ�5)OŠRMäF3eÜc¸¢?îÑÓÀô£~¯BÕ�?MüSC�E-³KÍœgœ]�îú*í-\yªU’~S}�éZùÿiWþeÎ4< œÔòä:�„¡6tpR‡§ãÉïøláÞÅý?µqã,|·þU9×ür�]±gÔgøÏZ|õfÿ#]’°Ã—ø”gŸ—Ô<5r„œ*ÈÁæÏ>Š<ìlý…ë8Ýç~»*8LÔ%ÇòÛ8TÅ^Ò‡1Ï:Àg …¡>ÿØqùï!KÐ0+·ý½-b‹ÑGÇ;!× …´Åȯ@¢xB@f«nƒç+sÆÊÞ²™¿Ý¢�b&•cR9›kMXÁ Qå;0Á†‹íãb{Ž»…|pç´"CMÒĬÜôè$I`ö–*ð  ŒuÞ3Œ*ë#T‡|¨ýøoÝ­å–ª½ïvG–}Ž›ç^ ò¬*$þËáˆ�´r|Cy±"Ÿ%™tÙÁzâ’´C”ú´òpòÑõß:Dc4µ÷°"¯ZÅhÞô¨I¿2î�†b¦/,ü…ÌÔä�c a�eq�Ї†ü±"»3,vA$Õ¸ &éB9ÝGö€Ì6=ÛÑȜՃìÿow Af=Þz²d—,³í'bëžÙ/‘¶6 F7#ln%Íf{^·Ån }F»GãK6Å~9Y’è'¾Áηž¡ULøÃ¤rLËÒ\UQØDáØ{Ø>#ŠÇ'ÉUjôOȞɩ�^ôº�ÖF`ÎÝ&EÔfk›Ñ]ÚÁY”‰s:ݺ€�7•¸o€šÂ+®£ á²OjÍÇìƒþ·»ÌÃÝ=nÙ衬ÐkÈ»£m`oÓäÇïU]UàÁõ˜•¶Ã¬|V;>ë)´;Ytµƒ’�µ´ŸµN½~o7.¾ZŠkMBÏ�_#§zçôÜ{}cUÊèPMæ*⼊�§<Ú}é4ò€wp¬[è[€6dË6={aeÄ›,û|v–RvÙB�µ)æK˜žO殳 Šî1T?V„™ñ ° -ûVÌw Ø�Jú›v ±õjˆà„L‹õûÝ7®ÍÏÎF#»ëÄY3È¥¦UÂ]4òW¢•;{¸]åZ olƒ€Ê0A¸çWÈU…[¥î7Q¨%¶ç|žußoP8òüwÎÃ'×p¿uïkÂù— ¼F‡òÍó䪟å§~í%53Js'P, ±Üû? çûñ»lnKÆXµI˜q�çÞ$¡ª�Y�U ¹õd‰§ÿùK‰oýîÑøäªË—7|¾!ŸÉeÂ�¬“»a‰Â;?ƒ¿ü2þpq@MÂæéÉØƒuÇì9Ü{}�Y\´Ï�Š0[BÛ.ædé먷ÆLQb»•¬Æ¨ªÛ(3ö߬œQZ³Dœ¬é¶µá+Û/zä™\]]Á‚è=&C5fò`_~Ýçü'¥ÐE—ù–u+ÝòΊ~‰³ZlIȵ\l³U§‹ÛíRd²Y¨já!‘«"×’<]*“9vz©Ë57á_ýIâ«î ÿ–[!÷‚Ì–jr¹ÍÝ çC>y_;FÄvšêç¿�í·lñ?!—܄߹›br;’?ãõrª*ÛÝ‚7Å�-“ƒJx|’.©äÇûÚZèõGºùc”œ5*^½Š¯*E6ÇjþÆ£»Dßóô€ÛŽˆè±$ýo,ôÍùÑWÆvoŠðhƒüñIrÇ'É©O0�3��ÊfìÖ!{Æ#*ò $‚ÙYJã¢\›¡xëIJhÐ*–&sÈ›ÔBȯ…5*Þì'(u ]*R~û‘<ßQÌY…–0б� +iÌd›þß9ÂøHt÷µ”tØ !Ž“Cµ�ññhh‚x¿ 94›ƒƒÜo5Ø5-vÂ,Y¤JÝÏ$–ŒÒóÐú 'ŒmžÊ›3ú£ ]&ý&+t%Úi<Þ+yVè¶ú(÷š} ¸~õ73>ýLÄMjáØÑ„ˆº‹¾ã5úeqÚcãDÇ'ÉÕdrŇ²†ko˜Á Ê�oôó8Yw¯EDó’o\ñÕ˜\Ãý~oÁ8Ù­ãœÕIêñî‡ ´~žªÜ½UBš{C�0/óÙY«y?|i|B®œ¥ôñz¯…=‰ìK½({¾1dØ™€ïTuÇFˆt)±¸>'5)“0S«á Žf���]3öÛÖíÿÛ5ôÏ9æóCŲº2K_ AÛ¦{ζ{P}Xäo¿Ç|€YPÌè‚Ü*fe¾¾FÎ#î)³oº£HÞŠ«¿öHïvIn&ÔÕÄí!vOôr­Jµ¦-Ö;éyôKQÙ|ÕŽ³fQög²#Ðã^àÙÕ4†¤Ùí¹Õ,l¾Ìåì­�‘sÙL‘W.ÄèW $o؉ní£óùô7Ûhÿñ¹èùìU?+3¦ˆúáx7õ¸)±1Êü$ÛduÑq ÒéFÊô2r�5Yl´pçS%8®¶qNË¡­"Úx6í_áR“•76NÄÕ7õqXçô ¹µ£rL<”zH!Zï!™ã°Îáêô…ɬAgšv1Ržûî@ ½ÌÏ÷p¯úö‰Â•¯2¤$1äëR“Ÿ—uàÿ(ôÍ&]¶]ÏšslÚT]Ô,òsß~.åÿþÇô ¿‘§üñshŒ€sä0ñœ(��S¦¡÷S‡ò¬§>«)n»mf­†çqZ9¾™ýék‘|†Í9®©�†òÛèÔ‹ÌÚˆ›là,'ø«†Ú(%PJBN'=¤Ÿß>cfjXQ†-ôͦ_ÅC~µŠÏ¡JŽóþÓ‹ /ÿxÈÇWî=_•Ë}kðåœ;>¼áð±¿çÉø ³ã'=ª¿Ñ-ä†_t%™OÌBoŠÐš8JY¡o>À¸†'ÿ¢ãäö|ÑMŸôxÿ™ˆºJ|«SäÞV�/§1Ÿî¸|ô þMŸæâg¼È7Næ`ºP©˜—_Ö«CÑ(Ê‹FÐD!ýÚGx—±µæÒfg ¶qžN)%P¡ô©Ü»äÔD8d’Yb¶½úu1§Sœ³Âétº´Gmœå9-Î=ô¤¸"rÁ•¯¢„äpD1o>}O½ñpîUžñ»¿Ç½êCGóÇŽQCÑn9lƒ=‡ÛÈëó"ï&alj¡]IT�·“c½g}#f­“cIý,ëgHn♋j{Æ"¼±wäH s;4®'"YxD'ͱ¡˜“³Å[ÝmP¾ýM�É4GÚ�¶p—SÂT„mówqF.í¶Ë½ŠXº©h¿cx°çé9QÖl7)`÷B/¾^_$Ý€uy$‚•Œ!×6JGêD¤iíµsIÞ†Td|<ÚzÏ"Øpp³­q¶;É ]O ù{ExYTµ4±%EÕB¦Oø¯ÚŽ«+bV;.3rétŒòmV«m%‰bV—3 YдßÈÇÕKCù½6%·)Â+_EI"W¯bÔm4Ðr·.úpÛ¶ÑjLn{§c?‡Å´Ìwžù¥§Û(>>IŽ=ãÜûÎ�UðËËðÖÈM¾Ïš<¾q#åº:ŽCu?D{Kœz÷ûm£ìë´Êh޽3Ï®cù€MBÍQžž¦pi�Þì¾ýØúæêóÈØ¦*rŸÂ�=;xÛSq§Z0/Ÿ%õ�(fVÛ8›°ãï.äúÉœ1ºÈ犼�ÜZ$éx(…�.òÙ±Lð>’ï‹Gv£ õ#Ä{m2çSÙxe‰I$­â,а%— álÈ4jZ��“­<�W0>8lKM¬Q6'ÊZ pš(ÄýÖkÞ¿œ£­J=Öå’®ã¯ÊÅî,ѤxœQã)Ozõ�â-’ÊÍB—m`ýÏ ý C�Ýo|ûQ¶Ýòý˜Î²&s&Uö«oÀ}ÏÙs HÛ™ȧµŽ3£�Ty$‡E9¬¶–:&ÅÞ—¿†;Õƒ²°ÅE5 �&ÞÏž,s-OßW>oÀ�êxÈÒ~Ú6ìCÂSŠFè+TV‘oû 1—Õ‹ðÏGr$m—Ž¥Ü(ÅSêØä•<�üó.«'l/p†êøw~<â«ð]Á¼r¤Ê“Šø GöØlºZ O ôž¥"?"38è¿y¡__#—­®€³…{l7=ägÞHé¤ðÎ$°¬mäI•g#ÁÿðŸRS84A\iRD�€'xµyP–R“ì²ni¡É†ÇºÙZõ½áÕ gõçŸZdà�yz¬1¢ø�F|¾²¸æ³¤�tÃÄ|tÔÃr«‡ï¤rRØûqzí–ÔW ïÔ—ÐåšÈí±ÙaìøÁ¾Lp—최â®È!IèÒgÒ6œ‘Ï|ï[+Xƒ}Î Ýlßm3(5_ã†\:-ŸåܯˆÂ7Žu)) öÊ�A�O’ƒÚ#ü÷�¾·O¤BïnAm“q|ÌÌÈíH2O¡:æÒIs˜ÏÊ¡#ÂåÎXæ^bøpîjšÝ+XI}N§y¾Û)ò½:šÊsÓOõm¹~w�"c=•¿ýZ‰ÕµˆTmy$g¦U U/ZÄ×Ï–0ù|ŽP0†"v×c^¡�½$gZ¦ ó\š¸¥^t–Wh'(³é­Æ@SË•Y1¬@/�äÒJ:Šùûö ¸·OÄYRO yÜzwɤñþØú#3?¬ØM¡oŽ‘L,�œTýýŒE»97DpÉŽ0›»5CØ1Ú¹èâ˜{SüÄ £ƒ5á­ÛÔYž{G8ˉÇbj¸tg;kÂouæÛXùÅ Q�z=¦:ä×¾Æv+íÝ,ò­ :{oŸ0…n¥¢[Óa»‘Ñ  çúœH£ŒÓî¬tpg-t"í‚9MðE§›xãÐIM≳.^zðÙÌΖ¨U¼!ë%¯bvû9i‘�c÷sÁ}b€þÆ6zþéJòÕ¿'~ã�äÿì#lÿ£ƒüWmªã9êdŽÊeÅÉëÉM‰ü¨8¨ˆ_øÁ…Äÿã»!÷t\¾²áóåVÈñ„ø|—§NÿŒíÔ»““äf?A‰£ä96]Èñ��øÊ2î}-�³‰ÏzZ@)ñ»oãð‘xDD‡2  rˆüð�—©…G=„�üo#æ Ôm�ܽ(Ì~NAow9�@¢%eæt.É_šØdÅ5;G5†”fÈï?ÔÇN=¹€®,¢�hým]¡§@³xx‚x|œ²š„U†üQC!5«Ë Õ^š3Eîž-qƒzÙ§œßìçZ• æU�I=­áQ»(wñ«(™‡J‘hä•A ^õ‰R™ä`Ì7ÛÝB÷7„×ÚB”MmPß’–E°ÖÁ9“âÌ›¼8G-¼T7þ· F8*ל7+Uµ+4Ñ–>ÇéÊ\‚Ùü|Ë‹ eV/Ïñí–O«ƒ»!ÂE.š-¼›˜Ý�tí�i’Å4™<¶4-�¤<û—^ƒSò3–àVBϧ¿Å.‰í—L³ Å ÕŠ¼\çp•z¸|¡—ÚL‘+NöŠpO•rf��¥4!b*ò’ÏUôð =¹@ûÊ��”ÐGrèJž£§pÕ=Œ(ª oBf…¶£µBúوęX Y�ÏF² Íò³äˆâjÝqL=ˆ=ãDû¼Îè][Þ}ÍhÊèØ‡‡·ü°9·«V¤òÔAòïx#îÛ¯âç>ð\FÆ"^u²¸×׌\¶Z76T‰ÜèyD„Æ#¤’Oc4¨ËœG“&ËìzŸ8o\lÿÚ çÞ°Â.Év‰ P-üÏM7T'(4F�i¢Ö$Ü/¢áa í¹{i†fä“Üã`è&æ86uÄéXÛªA»t„»•xjh*x©bne¨î3¦ˆªÜ±q¢f“¢•Ñ>Ò¶û¨&ÜaUµžk[à]FÀ¤8ïý+ìê%¹-Ç| órІuÉvÀÛæˆã¤”ÉY;•�ûžÉZsΤ‰Ê¬‹èÆÇ#Õðn;fc4´ß«DϘ(ï'zÊUôÈJ�…Õð¨Èž2jÑÛ—¦ÙUß,$fš‘©Õ�|Ô ÒxªYßé� f4è¶= ‘ƒ/þ­'åø«7Ñ÷¿Ãÿ­]¦0 Ëd²ß3G¹Z§(ºþ±Ëßû‘ÿ‚Í.ð/ô¬SZ­â>b |vÔfbµ"º­Ànõîa<âõfúuûÉl¦A­fÎÍwЦ/,05lÈN·ž,¡ZXkQÅ„ˆ³•ùSùòîù;¿-Ð+ä_ÊD,Õ+D!ù{Ɖ†ŽÐKEÞ¾ )¹M¾J”Ð`þY̫ȿŽé‚h42|4ÿ±]s”…r2Ž4©„§÷‡<¼˜³xše†u³Äº/€uá¶7—�*Ï™I]N·lüP'DZë-8FUwD¦ñWµ¾õ-´�Ìéõ„*ôì3žåìUEþPMæ\ÖÞãòý ÜdÃ¥“~Wx߳߿‰GrYÛ²…ou·ñf¬•È%i×o¦¡üˆ%Iäu…ᬙv©bƒ|6δÆaò:NNLåE%¼ú^ú®™§Ç,•pÅÃ(`øhÉgø@~ Õ5µÎCK¥ ´…Ëá]y$�C×ç2Yî0£A¥Bøïa»Æ»šÿbc\5tšðø$9 ¿i'?Ö…þè"Ïì§ö&ºfËbòº2Lî„ͤzXl?µÈ€��ºþ§¼D<û J{i†UáeÖVÉÉxðwÜKß0£A�Š7z˜|C É߃¢a‘ªãg”ïÍP¼Zô‰ª{~ê.núåÞôb^¦s9¢øNÑs—è3—F0Ìh€¦òDº&RC™é؇u-}—œÔòÝ×…³ Ü33Jœîj'dž Ì^£¾ê^2MA2€ÊFÝ÷D/tY}Á‚ÌøÈ(†¦å'¯ƒSë61eï;›H³�‹�Uù,Ùüµ¬Ð7ÝVˆRº±~ˆi†&ˆ�6È�Üc^,¦áÚ¸àÐ>v½ù…œ÷ß^Bc48^!§䳂Û®;�ÝÖŠÖFl¸‡/�GDt}�Ü¡ãäêGˆeÍL£(h¢PÇÉÕ®'wÛ1 £"àÐõ6 •XGÉ+DÚ—Á»?m"™ YG!’S‘ñ}HÄ2¡?î‚™ÿÿW†Gÿzëˆ)S\Ù¯+áfvW3j1þ~Æ¢ad™â'%L¢œeÆm—2¤ód®ÄêEet<ÏzŠÛ¬*@í<é=äôFÆ¢* ÷‹hBôÞ+ú~™ÖsËŒ®ãžJ Û)Á²Ew:m¨å³"—Å5ø��Îæ¶|ÖÓ§çîU·Y#Æœ+%Ž6ìôÀŽ$÷¢0»'• ¶™Yó"˜ž¦�5§²{8.Ê'Dá˜(T›„Õ*~5kìY\vw…zä½¶çìª55‹H1‡'b$ovÖ�wE-ãž2�Ñàðv2¡àkc†àrR”.:NŽ@¿Poã$Ë8‹iD'5A‹IÌrÇܵMÑ'ö>­tð6ÖqΤ‹ £óÙq!xƒ„Ïåêå*AòX_1"up–…£3Äí?g¿ÊL5òBNs/a�½áÃæ³ßNÍX[e±Ï—Üf Ø€Kª.˜ ö㓆Ÿ°ù¬šmf.úŸéÕýƒrff¤ýû‰¦7ø™Iñ´Z ۨ¹ø”PÕ=tÜt�Ç�ª,ôNd¤Õ¡Ý1S�<¿rñ‹Š|-1÷ImÓuWÛüí3Â]h{¶3o$É…–„÷®EJ:ÀAE†7W÷Q%ÜAr]ÈCih¢–œ¶ ³�?+µUØP¥yôÇì3,@ªî±+(hÔú줠JݯVëG0çvpkóô¼õŒÙ™H›Rè­zþL¨'àØó‰XèÖ¤ñà }Ê&iLˆØ€ï7 £Ù*•y¶Ç~0¥ì��ñ Q0ÖX¼CÇÉÕDŽA|î58 g1ÅYn§E¬ÏlÎZ@’ráŸféá휸¤€.2¨hŸCòÇ1§ÚTÕÍ+MŒ¢jÍ+ü¬#ßI ,«@ûêLåG-BiTÇDaV”7•³»Ž ö>šåS‹ Hô¯¬°K"|‡®oÆ#eÂ{O7‹<–6©?vß;)ú'ìv>{ ì­šUë¬xÚYñ4»ƒp÷ì¡\«™Nõžq"»u��P¤ ™µ7¦¡üôg1‹©Cj‹²-üN‡x¹ƒsZ.g”c# ŒN=ñP‚»!"½�ÛU6Ê7·àèK{b™Ióæ›àL–1-üGë¦orã÷ٽР8×Tè©Wñ�]Aal‹3G•fÍ챻Ǚ�rŽÕ KÒÙD”ócQì�ÿð¨ÆÝÿïæaÍ{£öAœñŠM7¼t ^r¨È£Ö k2̯ŒÓ~Häv׉QÔË�Ÿ l›Ü•1£0%œÕ–é�/%°¸§DþóŸæv•‘é”C…¬Q}]Ì-KE¾¿æÐ–Q�}/�©U—Vꑨ@;õ8“Â;¦)¼íµªá]ÈxÙ‡…VÔc^¹8ÀSÔÓ�Ê ÇÏ ÖíûË»ä©ÈÛK3ò›(¼Wô5æéÉVò­Ûo{èfÒeñ­£»­÷¾Vë‰Üá b£à‘(½§ÆvYËéîK‰ŽaT†×+GSEnT‘ý*³Gež¡µZŽW\[¹KÀeH>Û_øê€Ñ¥˜‰Ä¡“âJ>KÂ]SH»•£­”ø, çöYÎÿç+ÑxÕŠ5ÖElÿ�‹B–²‘º´“ve’úR‡›ç¦vÀýí§²zñ –é'äíC….-vKØ”Èß+ú:CŸlCî/R+ÞÚ ‰|45éñ®§'p¡ËùŸû#É+[Gu]gœížŠ �›ñ³ªûCÄÃ.pÏåÿøYÜ–ñ»‰LSh­ƒ³(‡µ hmþ÷ŶO�Ã:Î×�gšÅë˜.DÑÓЯçIÿÅÄõªã2‘8À�Š•ëÉ��UÎÒoh+#Ï|åE ¼ù2òz Á ÿHø…ëØù¶C<ÿ+?c”‚‡r ðzj9Qñ¢è>1И§§&r›(as­Qñ²‡Ó®^n:)‹%Þ ˆä9óâ1/Í9Q66΃QFD¹î4ñäÚséûÓß§|õ�„W|$à†·¼éw¹àºŸa¨îgÁG¨ÇH> ½äõò�»ÔrPŠsV>­VŽD!ëIžTeÒ/Et^Îõêg^=ˆè?4\v è?ùkIj2Ô�VâtÏçk©�dN:òyhý\ô×Ì[r¬%µfÑdž�`0Ïw>`PÒ'E)›Ø¨+CÞ,ôîKuK[¶ƒú××ã_äOˆBÏnF÷Ì]£+/<µÈ@²¨G‡Øeg¥ ]¯Çh2Çå ½¼U}¼õLÓ*0­S�<ûT "ï�ÈU›„P‘7„|.›)öÒye/é ¬t\Öä²!�嬮˜ÉÂFšCõè7S´—fxœÉ\÷<¢ˆ§?ç9<í%¯eûçÿšâ�Ÿ¡ð×ÕÿÎÏ<óù42>bb‹kͰVÃ4!…üÌŸï+±ºa:íëÂI[JÖSâï‹ø‚XéÀ߬ö2ól†ê>�›å“¢dPT vÑÈ÷cw"—/ô¢ñˆúP|H›xç,tQ65uv–Rv´ÙRä?¤×ôï…¾µÐ7»î2žï ?t†¾i±#»±ÓӦ͌Ù<À[V( —†þà‚sÉ¿˜ü¡›é}ý­ì~ý!þpi;“Ê™„�Áà%c`Xä9¨è|Ößà Ô%µ>èΚ)ð¶B’VˆÒQmêJ®Wî¬è_žà÷RQ#DwËÐBo½Üz²ÄÝ'K¼õLûµ�O¨Äß,í0‹�ÊH1ÍgÍ�è�C·�)ð°ò¬wb–”£Ó1¹Þg‘Ú•ëÛ©Ï{gà¶C4œXbǸØþ°Ø~|ÒŽ 7 =–ÈÏäÒ–B—{VôŸZd`Á$Ϙsg»õÈBoŠplÜ„Z080$Ÿè£=nœ�Oó¬ÉA-h g)5Ç�4qè(Çt«@m÷W�ÁÑL»`@š#cM…HeÞ¢�¼óÔ—Õ‹ì�� «ýöýeTËѰÑÒUBU œq*¿�tÕ8ÄŒ^ÁhWSr3"ÿƒÔaQ> üí÷^�JQ\mNO„såzøOõmDÿô‚·½‹èð-ßý»ü—Cç1¾?:”a²B·È-‹M–Êò?»þ½Ðq5 ›MŠwßMé�yz$Š““äª#”«–´R¯âD‘yX‡ü#LtOl@}ᩬï/ÑZˆ8­€5¹¤Šè¤Eæšö ­¬v3õeÿžˆß¬öºÜ9ë2‘àvŒ¨Ão'›&‹…4æ{Šùì,¯\@ƒÁ­')Ýù={e¤±f'bfµG˜ˆk"WžÙÞæ,ß03ë=]½5ÍbDr…áÊwäÒ2ÛNwÍh¿=kúpkîP곞FL¦ÛИŸïaR9L(@Ô=Ú BakÊ2é$g/&jãQÍÊE…rãŒD²È¯áa‚=‰ê¶ùYለvr]¡‡ö•>ófô&ÝÞô“+[Z«�§­ˆÓº€äMÏ@¥z߈Qð³ãÏå ôV ‡Šùõ™užªÓœwâó±ŽsZ�´Ì6½-œåNȬzXP/k_ø+®ÊÕæéA‡rL«°�µ”XY »|ÿD!Ë*²8?@û¥Ý—² �wŒñH(�ÀüÜc"¸¬jï¯YݼõxGÂn¡¯Û¦àªõe')®Åf¹¤Ê‘ªÈ:y>¹ÁKÿÛ¯££y S½ŠÜ]˜þÁ¥('ÒñóôŒ‹²¨ºÃ](§œŠ+Â*ò�3™S ï×RÊFoÙŠÎôÎÂøÑí—º|t.ÇRâ°hxaG.ök\M ÖS‚T„-án$F8´”öó`ßza¦fe Ã*C¾•BþÔ·¾Å“Æ�­œr™nö´ eôÏÆÑeé4Þ¼ðL#Éo›ìu/œAËÂ5ÚŠ,Àîý—Í»Hjm2Ûj5<êC1�Qƒ©¾\æHqY½*rÙLј‡Ôû;¢ï>1pR”ìq(TÕt–§„Ñ��ç·£/;¬ ç¬ð–:x©ðåI‘ ÎvðÎl®èÑ\‚?›ßùYQø§Ï26^F×›(*ä £€Á]yj¯~„Ø8's¢Yœž6˜ä#LÄW¢R•º*ˆª»ûRb“·®"ç½ã/ˆ¯}>uÆåkðÞu‡ëÆÙvNÕ4ÓŒo]æòù @òÚ<2*Å|«CpVËÂY´H«T¾~%šÌíáí÷P®P5Áã”'Dï®Qòv7•·»©îgP­âW«Fâýï…n¯¦Ýe3JÓªYQ‚™SƒD·Sêã#Vãtëù»›#Ù¹·™ÕºËrXV@;-!å¹ûÈ ¬%Ñ9B=c ¥¹7| ôðì•sØø-vé7)é¼à¡>nT‘ZÅÓ ÁmûljÍZUÇÇÌöî  Ëº‰+œ£%¶›ÝÇ�/EU.¿ôÇ{œìÀÊê# ýlŠ»‘o»-ôܲ”E1G$*¡çC3ìѾl»¸U†ü, \¸³€óì?øEzß~9þ-†÷‡ŸÂýà_²ãí¯c߇žw…ØQŃ_`ûá â¬Éy|ÒL�BžýÝH“<éºË¼WD 7Q)OjÆdÎ’q$":�Ìt •¸h�ÜÈ2çêùèYÅŠ«Ôý¬/PžŽ˜¦` '˜ˆ­è©çS–ôj¦+ÙjIí¢:V`éáí /nÃׯxt^ çõ2ÑËìÝ% ¿ÆÞð0»ãjzš£ó=¸_¼9 �BÒ"œá‘;+ÜõŽIÇ•(½kMæ.E3Ý1=†‡Î˜H¦ý2¹oæ9Þœ¿ËžÏkVvüDÙ¾?î…nüq¶å4E޳ï 5R;”£"o·ˆˆ|cžžê»é?h {â½ó¦ˆÓòYO ;2b—�^KYK=ÞwsÅJKgD±†rFVZ÷'P<=M¡ùiú‡êf,u¾]Y&'ÉÝÿ{¦)8>fAˆãû#¦U@õ˜æö" ¨Y~5oãQ]l³q=ñÜí”u€¼0]^\ý>îéÖE×c-¬ÞBŠ?»iŒq:“"³Þ†NÛD3¯ËczƒPW ¹âÒ8ÃCsòU%Ô,ò% ÀÚ‹ è+9ÖÓôâØ8Q?*g2×D³<~Û�œ#ë§·¾æ<“ÊqßKv‰|¿Ó'¨�wR”ÆDy¾AÏômÆÇˆjÈÛ�bÜ7àžNp×�š.+öle÷Owm›†ZÛjã,'8K‰1¤."Òh yÍaM„ŒŒ¨UCt4ÏÀíWÂÛÖcÎnø,È%í˜÷I…ÌuŒµ¶•L&×â§~÷µ†Á^uAîÉ+í,Y*Püð;rØ#…»–˜ãÄJfþÑfŸ¡m©:[¬ºV¸âò=$71±Ð‹ê±„{x”üLÖõ:´CÇÉÕš„œ_ÉY¹flâ~‰Ž6Œ×l±«>þ‘Ï$kÅÖ*:öçmkwMR­H[°‘ºÌ&¸ó� ^á0·Dt곚3þì]0xµÝ ½1É›bæ;žÙ(Á]ILW|øì<¥T“\ºsF{Ñ_Ž3Îóô,Šm³uǧMèÅ¢\ÒÞºò¶(â³"^°¬8ntáLÄ—2~÷m°$|cÏtȶ¹«ÙÞ°…žf/‚gnwVj‡Ý©½º5óó7k„L«€¿øË¸·¬D,µLGÀþ¹2Rh¹ýF¯ozžæl¢ŽÈe®GdšŒæßSxêq9ú.Wߘ窛K¼ó¿ÿÁŸóäÉI3ai¢ð¤Ýªo£ý¢�ï¬ú¬wpEqUxKi™oê)´_€TäH½É£"oåUÛž¦0ó¨øëLM·IYú (ôqF¢!‹º4?Ierko…û6pÔ1çîÅÿ{ižf²ƒ�k_eãh³ŽèÞª x)ó=WrwéyÜSCQu‚^‹ï‰2Ø&¤¡káôÏŠ~-2 ã亡ŠM…œßþ5 ·´’G¼…”`Π‹ýĤ€°’úÜ´ÎÚ'«·oˆ .3-r¸l{qh‚˜ÙÙ¿©AcÇ”)ŽÀæ{±f­®ö¥â¦ë°,|™¦‘³¨¬ˆáËk\Ü~Yö½üÔïÓÇ+ν8ÏFb^JÍße Ý][ìIjh¬gÔÕ‰;IN ç]§aéWØs02_-dç??Ï„SHY3. MÒ$�—Vê³aWÅ$�Vöou"Rõ!•øBû©èùÛg(ªŠË%WêU|�0a…£Ã5*=í—¼·•1øÔ1 6R�Ô4üÜ­·‡L¡uC ³û1'Êš34à†…>"9S"Ÿ½Xs4Ïîzü Tz*íC…,ë/óœ¥ç‰rHûÏó|3õ8Ó!\4’h=)3žœƒþ’“*¡FÀÈX´ûÒ®)ÈÏÔœ�ôr£QlòQè÷ÞAŸ�Û-JÄÇDQ€ï½)âkë¡}ƒG¨å0™–øNk€ä̓"8¼‹|…5ä-Šm÷‰ì؃ªÅCËFÓÚU|v–Òø¸MB‘@5£T’_µæu�r‡r½¬Ý3o¼•nBŒ‹Z&à1‘”#i_€>ú�9.˜;†�¯Þ¾+(  “ û#4™ó©2à¤U•¥Ù¢me«Â1Üw‚ÕÔaɦ½¤iÌ’"&Öé»åÓÜ«>kê ¨U<žtÍ«#ÒÔ¥-ܳmÜ™-äÙ•4Ã]ÁJ—ºê –ÑŒ§‚œêäH^;x”|}†â³n¤HUnÄxÝe"­š3ÿô΄�nøjãÛT“(1¹el¤¶1·æÒñácfR±+•è©Õð*–ˆS­ÿzÝ/¡÷Ãä ñTj:ágí®§mMG‹"˜“ÃC+yô®jVÈÖ'‘¹É¦,uU™¼×R`­�Ù0j„ûDÕ½"�2˜íMÈ…†T¤1”QµÌ7Z8?P€6Ì1%IB>¼TäkoBÍ¢yé v½ü0üëBߌÊ~,·ñ�{¡7EQuŠ�ù“¢td‚^4˜'n¿0¤±e‚ çlâsv#O³½½8Ûº EbÈ_½Ÿ>K¿ÝÆ™~PC]ÿz6Í´ó[[¶Ðë¾ÕÍû¾A ]”+2÷ùˆï§Ž-4C�餶0;øY¼îí¤ý¥š8ï[b—ì±ÀºÃº¨,‡ûôBN­:$ ΆŒÆ^-8#ÇlÕSÃ~_²&—Nˬ(à[bÏÆ`^=ÊÔnC*²û¿ý¬Z¬ò´Õ¹ëV¦ºÔ¥Þà,vÙv&ñ¦-‡$5Ûø‡Û.z÷Å¢T›§§"¼ ÊmG//pʼDHäð ¦RÂ¥Ô¼(ÚVÚJí4! íË£€Ö9ÿìËÑTþy2±V6ÜÁÍôCȧ2™Ë‘~¾#r§ÌñÂ]M³—¡ñ°·ü¹çdZàôg*«YƒÉ£*Ý̼šU6D0³Åe"�/Ê1¾?¶ŠFÀ¶t£ñ¨ºHÁSÑ‹r|­]`µí°*«ZLŠ|t}2ëڡ܈ˆš5ÂaCqm¡çÿu¡ÿ„�Ñí9ªÇXp&'É 02á_vµÏ+yþa-âVòüÃ*çÿÖaN+ìãD!Û†«†76NÔùš 2ÙêäýÌ”�õìî¡”ýûÙœ´)ÂŒBb¶ô&óº‡ôŸ#³ótbH2‰9ëz2àG. xHÛÑ]{eHŸ]N¯.üÚÛ¾No�Šw#µ¢P@ÿe‡\XN\ÒŽK[ë+mÓ$kÉ¡­œ�yXTž±•ö¾©À˜"ÆÇ#3z2È,4˜á¿=OÄ9ô9‡E~J„óƨҵ ¶D°šͧ0‘öÐùœ ·èRZ·‘¹[’|�lg•‘‡ll”aÓg/‰&á´ØñÝevÞ%ú^rHyòö¦�-ç8¶òÙõ�úªKýM{‹†&L*«êøÇ+&ýEVÖ-›`³EPã?Ö<¹Ç½Ðo¿ÇÀ ÌKîõ‡È]r…õ;_¢B?Ë/+¡¿,Ó~sícR9Fe[ö ÇsCÈW“ð„( MŸoC2›¡-r_È·…Þ“mχêdú÷@�-ñÎ’�&sÛH>\`½mšoëf›š5ÑX5é,ñ™4bfý|:·w³à OÜÝÏžH—{£NP˜@v"ŸCÇsä×{,¦²ºñ•4dÙ¬ð´[ õ<&´—5í@:ÄLqøAvÝ+úêuzEÕe¨V,2ñ7w:kÝÐc6Yó‰íè›N?Áj‚³Ü2vÏNŠ?ÕÆíÜ‚dˆ³¯ÏúßûIþ$Ç‚ZÜ;mÆkaËÜ ÷ì:œ–Ã)ÅÌŠ¾¥72ª“^ ‘ÂáaŒÀyh80rV³ræèÜæpz™h6!X–¹Ç¶‰èËäµ…g0½Ú‹nÝ ÝŠÛdXÅU×r]!צ¨v�yƒ(°GwJäï|yŽ §Øf�à M×ú¾ôæˆöÛ ,ïãyãå òö�™`†Z O ‚ú Å3F›ofÀEVè�e±?î…nH£/CùÉh#¨°7<ÀÑüPŸOWúÑ`pþ$9_S*¢Áàº+ºvUsãöŒjT¼ªåeïç`T³ÑL¶Ð]«CÏŸ¥»LüQqb mv–Ò‚ òÑë£}ŸZ y8u™ëÀlŠ»œÚxÞıús¸n…â}Cf±´é wo9ªIx·DÅ»ðB ¦‰ôÖ>~ý§_JôGc7��ùÂbÌ=Êsr=G3ÉóÅÞèÑÛ>ÅÀé£ÉUÇ»tˆ8MpLv¾÷5&ß{QfœΛ-°ÅOÅZ6¶K…sZÄgR“˜ÒN<îßhdZ»Í=Wâ£4”çi|Ñu�û®µˆû“ˆZ'Tä~õq�z¨­•x×Q¸ûEU‹d§\7n9pFÎ׫øæxeÇ`5<|½ï#¦'âlÈa£å°’zÈ&”Jiâò¡Õ^^´Õ+>¡- stÛ/ΠMir^"oŸ‰à Š$Üû—LžÀ¥LÄPóªU[ŒW¨€ì©RÞ5Jž©FžZ5,M±­>C‘!Ùkâ´d—ž�Ò6‹ew[ }SR[ýÉ9£wý¾T¼Zµ7+ž rw5,fiª‘ß+BTËŽÚíUË[ÜDù ›¼¹%7ÀläqÏå»DßfçÞPT%SèÙX…=*{èˆÇÃmÜY.&xgLwÙMⳞ·neÏxU¿ 1¬Ê=8nùãuŠ:b&¦8l¶Ûªûh¼ÌìÝ%^ú@¬þÒ¹è­Ûi½£}¶—ä=}$oôi¿„ßQC*f $ªV�ݳ†<ª*óÓg~!fÉ(éXÞŠé+ê†vÓd¬½Ô�ï-Ù-òJpÿú6Ú/B“9‰’fÙ5#ÎÑ�ôØ)EÈêã*õ°½ýÂ"zSŽÎm½¤wî$y÷“ÑŸ Ñz=Ú¶‡ñèjÀâ»Eÿì,¥ª}™g(nÓ o{«„Õ !/U^ò~Ã�OlG=õ�Âî$McZ؇̋ÞzÈÈb¶ÌU íäíRϺàùlAArjMÂÆƒìzXl¯ZßÀðp–ï>äg^vÛè ‰ÆD¹Oô Ót­‰\£A^Y4•9’Æ�^Á'²ßûI,ôîy¹‹b[¶ªNX ¼,$üìÏh g;WØí³�LO\JlW—ýÕ²)°šÑ=£Â>{Ms¢PÅdn]tœÜu'(Xk™è曎,÷1½îs0Þñ¸{#à£K!„šÙIT‘_G±HÖc¤<'Uâ°Y)v£˜Š¼W‹�Ëèm4È��X¤°e¾U1çF&•c|´O®=×ÌÓS¾�cLC¾,½õÎèaZ…˜ücÄ÷SŸ X)°»–à§›©¥�d^V‹ÜDøJZʱ,�«�‚ ·ÜÂU“9[ÆÙVwDDdÕx5…UQ´ŸG\^“Z8�ÌÙô ¢Šð�ï¡¡€K#P-<Ú ?%òõ#Äõ*>S�<šÊÓ{óûpßs¶Ì·:%šIÄÝòøÜ<Ü|–Ò»ÞmÔŒo�‘› †Z3äŠ**r­J\¥t(wxÂBÿð� ˜æ_ÅÓ·Ù¶ z³­ü‚è�Óæ8n¨Žo�ÌÆsÙó'»Sérîkd¡˜f÷ø¯è3fŽ?±ÙKxL…3OˆBïžU¨º‹bÛYÑ?'£–ê&Š>âÆànÒ^ÍïmåvmÅ)Iä'.%¶9Ú&omDǦ üÖÜù.vyÝ;\^û¾"ïÿ]ž¼¼äìQMäгŠH¹g¢�t^¹ �æéü³OúÐ;ÏG//1µ�ƒŠQ”5þ¸çye“ 2•ç°Î¡ï†‹ñ¯~1Lž‡êþÛÄ9ï\d ~ÄP^jæçí¥aǃõzÌøHtþ$¹W‰Rõ‘Nª@(8+úW¾Ç¹Õ z‘ò!ú�9nwsÍ¢µgÑÎý;)ž<%øË"Z5n3kþéEòÑ>¨yµÞ�AòÆMh´j­BV臄M˜Q8"ÊÍIú›MŠ2C_ÔB˜¨…4òÂ×]@ÿç¾ñùTÞ³=cò_ýúš"lÖ0+ð´ ¼YçQXÿµ]èæ2�/Äè 94âÑù ®œ=Éf0hR �3™CuŸ+¯<—Ÿ¼Œøuï§|åß0ð·¯æÊmç"ŠÙÊ4+Þ·§Ø&QÌž¯Ñ» z³BÏÂ#3r›�-LÇ'É�¥¹,ê‡zÖóÉž]$§¾¹Êÿdú£ßz›7Ìt¿»[p Ûýa�ŒŒ7g ¼$Q:Îñ\ yÓÓö Óõ=¤þ§Ð~A™ÙiÓT P'¤£"Kó/@C\6S¤¹7ü†ØyÛüôIQšE¶€S‡XÈ3Ù]u_â)gÖyêÃb;—Õ‹VžÒÜóËèK9;9ÖÓgÕÏ¢Pƒ½z1SÚfü×ÊÕ¨xà EGMÂÆ<=÷‰�»D_öà�f†i9L<6N4#Š#¢Œj!ùÛ^rOR`}ÃÀ)%‡õ¶ÃŠa²nÍ'ë6)Už;Ö·±ð:{lò¯¸„‚*¦BE^MFY˜u²3@…5˜xÇ3~þ j^s'=CÄÌÏ÷ðSzA€î Yë8†–£€ÕvLû‹;X¼˜ÝõøKc@"¿ÇÒ[‰Ü+î6ÛßáÃäßõ߃¥¾(~ ßÝ 8ãbûbÇÓY|A?gÎäØPR¦È+±òƒ]è…FE7äKf%¹×s<×]H6ãžóS6·<+ìG‹Ø£R¾™á 7ÿžnÒÍÖ�hö¢¨uƒÛÛ¯Ð7oºy º…ž�iþç…nWûØ^yÙæÈ( ƪ”‡&ˆi*ä²Õ ¼kÒå_¬¾¼-—´e¤–÷+æSS\ªsÐ�ÿà »–Äv-Ð{Û1 ‡�t9kΈñkGÔ+ŵ3�“¢tB¶ÎH7w6ªÈœ1£ë˜.ÔDnD”9óPÅ—•H *8^L)¶¬á£µžCmܳ"zà‡§ò\«RÕ4ó¢ƒ�D¤:E›c�Bû Jº^§—ZÅ£¤�"éYµñSCcayf䲡€NbK6–ضr®„{øˆÑ×�7�Ì9ÎÒO»ßŸº/:ëzE˃«ÕðvS�QÝç¼Ã¿ö÷>ùÄFÄ”ç^•øN+fL>7/‘ó§yÒ'^dWäµÂi]›¡X9{Ün—ßæŒ›P�ºò Oþ¶8¯JÝCcŠø=%�Ö<”™!̋⺠¸pÓõ˜µv�S§yæâ€iÒ)W¥îŸ…†È EMj!,ù*Qz�èÓ ªÒÏ¥Š‰Æ/YUµq6VðÎÈCmœ¤]@�‹Šùî0(βÔ8TÉuyí[®ìûËŒ,b*[Œº©±ÝÔ 6?“Ííû&"Ú>ßžb¦1›/‘Ç.$óq/òî7¼…lrBÆ–ÝȆN-2`üfK|’Üè”MLÝÊ…Ï>´-”Ø*uÿ�_bÀU¦ôŽ›}Ö A4\4" ç¬`UmP‚û®QÆ ‘4{ÐDū۸'Ñj5¼ †ðÀ<=wÝKGã¾ý÷CÖ­Ú­%hËc)ñXìdæ £a_Ü øÿ®±:š·ü°ÅN)› ײ¬œÍ7{¨p4Ÿ¥§°Ç`«—Z-Çe3EPq€õ—ö“\Þ�nÞIZßIòží$oòY{/Uy‰¸1JϨ5[Tšiî «ö|ÛÍ®C¾¨˜Ý·�,0$ÿûâ‚ûÅf•lQÌùo8³ÑrXŽQ¬ˆÜ¼«ð8“ú4¢+ïR&âÍËŒ¼ò×ÜI�‘ø‰+È3^{Â"æúê36»ðž[{‘ FA)œ˜��4d#õ9�âÝô7ìm†Œí‰®¸Žªûd»Æ-�ZÙ³#`v�ýMÁÕæ¹Û~&þÖcgVèA§Ú$Ìš{fçj�¦?)…žhÆÊ®`Ü?YÃ#^Ý­�‰Úúß•avíÙÕž!ݪ×ùH_¿´—“*±óC·ú¬wBZÂI¬{+m…t6pÎ(æÁ”â§ofT=Ôë1¯¸¸dwÑբόZ,E©¦�Šrš0sr˜Ì¸çÎȸî6ˆ+®9c:ÝA²«ÂI—|6ò•��ý`~Ï8‘y‰dÍ,E™Vz3 àßo�5îê"¾ÿ;Ίþ{Æ9_Ù÷mωªäÐPL½Z�Y]êq†t>ÂáXT¼ÛŽQxÖ�Q­È½ê�2š“\ÒdÑ_f"0n,¾¶XÆFˆ²3þQ—õ¯³§DnyƒP[ô÷ÙŽG©Ç�ÇØÛ /:n"µ/¹‚‚&€�ÇÇ)3¾?b|$Ž&P̾éÅOßlÄF©(t:‰)ËD.I’gCxÿt3×Oæ>šÏVc7µ9ëζ߶ÐKÊb�­Ãñ»GÓ…ÏÒ]³ÃftSÖg²…>"K'ªê'»Ð%Š32 Ã`7#“͇zëmGªû›[ 2)d^Ýs“r+ì ùÄ­2­OýÞ.³i@bÔmŽ�J†H>«�§D®uÈÐJ”Ûk·²æ¼8˜GåhÖ‹¢0Hbø0ùQ¼õÜs'NÇÌ­ýÄ8Ò¼ÅoI°–ú¤ë¸k"Håñ™O³Wá�èÝ-âëkä×ê |Y·Õ#_›+;òQtÛ1 ¢÷[b—ÄöÌìÒ g¨5ÃK�W›„•šM=¨h|ŒÈÎ šº†W1_èEŠ«2É%:NN¦Q5‘k4•ͨ}!nîµ/× á |n+‘�}´`ô÷N§ë¤3:c†q¨¦ ûET½Œ¢D�Ñnš(üú½÷ˆ²IµÙWÓÍQDÏú"›¥N°"üYsFi@' X‘^Ãá©,�&¢¦,`2ËXó3¸¦¬TzN”3}z6¾íªíª™b³Ð»™LcÏæ‚5’MqQè?Aʸù‰PÍà”/%¶Š§¨ZÅŸœ$×DfÛ=Ki⛜#3´Ð[à‹ Eæ„cžÕ“÷sZýÔOsIu�Ñ c,dã#Ÿ-niÈx“ p¸l¦ˆ÷áè.¦äeè®N+%7oÜï�Ñ ïâÃÝÃX4c ê/ël;¦l~?•gZ._è…f‘ÿ|O™kUb|0p o91G„Ì¿ÿPÇãŽÆþëv$ßÎݽ Ñ[_æœæé™;¦§ × #ÙM—×M;Ž�N‘7c×jw¡ùq¸÷/àGþî¬ô 対š¾jÚ˜]Šõ*¾öQ¨!¯ÎPüÐú´ÈÀÁÿlF4Ϥ=ÔÃê¢I=m)¢“$é6VÎ^ˆ^Lc4‘uÈY1È–b/næw™~Àá âAp¸‘Ç?se�Ô€#âÄ §#»×(¯ Î$¸ív@’î¥õš1YºhqL”ÇDÎ3>qÞ^BT½ïmÿ„7ò)J¯y;ç¾ýùH³ó©˜�ˆ&sh*?4A|ø±�' ùÖwïù�&È!èú!Sä÷ÌQ¾X”ÐѼaºÍßù=}€>UqÇPD|߯üÕ�ø×ßApý�ôº™g¾ãW‘æzÝŸ©RT�^¡¨]n’T´fv8‰ñ¾ûiJ0�â/tp:ŠPŠÿÅ×3r0b~¾Må³]�l—{Ó„¢)lÖLÿÂl�Ð bfæáŒÕ÷·ê,.”X½˜†FGó€S¡ž;î}ßœáœ9Q®~œ^š)¿Jµ¬&á­›³8àŒŠ Ú4†©c¢�é ïçÿ'¦Ð%ܱqc ¼ˆós®Á/«‡é>¦š*ÒPþhƒü‰%v|C줩�—ëÎùz.¿…ÜÝHôÉßåÙ+çR‘w§]¹» {mÍ3oˆ`‚‰Ls¬FÅ;¿Bކò·�‰ùÎ ,t\Úòi·]’6¬¥!�vÄTs×ÔÓYÜ6ˆ‚ cVçZ-÷³¨oúP�ŽJ¤imå‘ ´”gMeÒ¿gHE‰žÏ¼��ìüh·ü.˜„$Ÿ¹÷¡>>¦ª“ý¼»ÙϽ÷öQSx”F> ĨR÷G‡ œãÄ*ç�‹íûQy;úˆ1ÖtRÜ9á.´]:2²¸•÷ñL  Ãùš³—ËØåm7°Ëåý“>'Mt“Ó‘‹ÉI‹HäÒNb¦×bþî,#£�×S6)wŸ(¨j :K�µÆ˜ kRiŒ�arÚž§ó¹àæË(½m”øí·F|ë²ß¹ƒ§œZd >cvaCÈÄKÕj9ªse&&z©×{™¶/N&M7^bN”ÏŠþ…l¼iÅ2™^£{<ü1¸÷/àG½*7R1ëe Þ—P@òøÕÚsÙyé[8÷õÂs/¢¡ *Š®°ë±“†fT¤©~>¾ÐË.p­JTçÊL*7Ü0i1�îæg+¤l„Q y'¹µ¤*¡³Lòɾ.ÊsjÞgqÍa%Å1QOiÇg=Í1·º�ö‹²‡*Ké¤Z-R›)F|å]%îêäQbðÃêä ­%)²®<ÇÏâ~ô=jŽ[&��{˜Ñ| y²Ó ¶ªC>?ýú—Ñû'ï¥ç�ÿ‘Bõ¥�pá]¿Æˆl®y#_C»ë1V$ò°Ø>!Î)ò··”ùòFÞ £V]f„³”˜„ØŽn[$ºåݨB6 ”[k¢ >í‹ ü`G†Ž³*µŒí6U�¹ù>ƒbò*Â;Ú0>ñ‹®§lœHU¬)g¤Á£AVè5*ž‡GÉïE!—Õ‹Œ�—ùY-þų¥oˆ�÷‰�±q¢®F V yößý"}—¼‘�ox+¿ _BSy®ŸÌQ«xCvlzÇ[éË”š�ž§wÁO€ø‰(ô &âæÊuÇ çSy½ÙPI égCä4Ê ¹Íš ÛkŒÒcÃ"\ÙheYÕÈc<ꦼfóUäV«øÙ™ºÑ Ç†:YùK^É#c»Þü‹>¯ý‡�7/D|"Éó饀kç=~ïÓ¼ðÒŸ¥¡àGó€3ˆûç9ï³/Î3›æY6VP–E î’`%ui'.ÊqVø¾¸‰Âavå©Ú�Ç ±�òmЇ<ÎÊpÜÓ4 M\:)ÎÃ"§p¥ÎŠŽ0gqW�ä’Oßúþ &˜ÁSš‘j Ó6îjŠ¿!èl¸´R.ºãWiZEà�õ ÉGŠyÁ­?‡ÿºO¹¼ýLÌkE>¦×�-ò‡ŸaàËÏDÁ;s®MyíΨ³#�hZ´°Jé&™¯Xú®]m–¡üê: “ד[e—ôh_ŒE#Ì•s诋§ŽHбÞÊ»Ïö3©ÜoŠÞÜ£cÖ£³ä·úÛŸ5ðQèB¹YTR6FÊ­>nY"°Ì4O)®Öàæ³œ?¡Y‘É[?rwü4|ØÌä«Uzýwè9Y¡KF•ù™³9þñIrw>`¶øƒ(øÏTËjØÌ2jM…0™{&‹OßC{ß^ôÛÏEOß�b&•ãÎzd3Å$Ñ;Üùÿ¼£‡µ¥Œ6cXl–«î'm’pFEZm—×¼¹Ê�ß…"¢¨V³’Âð_ùA²ng÷ë¶Ã½Ñ™N‰¾Ü¦|éˆ�ÝMd,½™Ÿ>zËM9æKfDè«M ƒŒ2Ùk ´”Gk<ù’w£©<4‹5*Þ^LÜ1—¨À�ôPQŒžt+ž†ôÒúù+¹»DM!CÊ\e¥Ã7rÎÑùZ �½ÍÐâ½-YL·u§ÕjxMj�|½Šÿ,fŠ˜ÊŸý÷Ÿ`GS&}Uѧ/°ýÎAzšÔÂ>6.tùð¢OgÝÈžSù´ÛDXç§ -øÊYJ·ˆ�_;d�l[ýí›ó'NZêÿù…~‡Ù^M‹Ÿ`÷9´ÿ,â{ò2ʪ»&‚éÔãÛɹèÚl<Õ¼‘âĥĪ�‡H£fö>�bQñî–IMÕêˆ,µ³VÃ;! 'Eé¢ãä˜Û¿•FêÕñ_ýn¿‡òÎ}�±àŽÊ¤† 9;¹®`_T¾¨…s¢üûÑGm¦÷0mȪ��fͤÐ8-ƒ�ŠeR_Kïÿ,W«ÏvàCn3Yéú x0qPÇµÜø¥9’ÄŒ·Rcµu¿!žÙù-T)ªI¨!£Îã²™"¹÷}Ρ“ºhÍ ªmº‰:>k‚�ŽƒZ¸g…sÏ1>sjÇÚ;¿dÎÅ'DáÎèAuŸë®+Pk†5FpèúÜA]ÉlI»JÚ­ùÏOлg|ËÜÙÞŒfÜ“Œ|úà8åQì!GÉ[å™o^^�ÀŒk¡…‰äct |Sä¿+“–sF>+rùz‚Ÿ¼‰QõÔš„ßžbÛ'¿Í¶¬Ð%·Ú]]÷¹x¼ŸÿŸ”BŸù¥ivÜ3ÎùZbÇ“HÞ^dÖ̰½Të)¥³ ¹¯3@ûÚ!äwƒ�›\´J8#Š%ÊÕ�÷‰“†#{ïd¸íÇD¡6Cñ€ÈS¯ÇH!#cªº=eBÄ ·jÓ[kדÃâ€3}Ö<»ã^ú‹s˜V>ü™<í Cgíˆ0Iq’„\*‹€Šd0Ð…÷ÿ#Ǧ T¬ƒ T cns™\7[Tµ l²“šJ±('áwZ”þå6Îüzߨ8Q…cŒGS�ü‡ï´ÝëwCøiDZ° h¯ã,ZL²Lø¹/RU™©FþÀaw�(Ú¦fÞXZk!ªûV½"9]AŒ—0d,ºDþ’i =…3¡L�dÐÞ²2g£Á%ÓªUüÃÄÝ‘× �Pl2ÞjF¶«C¹í¿toQž”u®(`Q1÷¶C’?C*ïj�?+úµÄöL»žiû·á6e°Oüëqÿ~ÔkÐâ¬ Õ zAž÷­,·–R�ù4d¶róÊ³Ñ¯Èæ¬™-9+–(e\m†âèùÚŒiòQ‘w)ñì¬q¯U„Lj¢�ç�—ù=É¥ý‡eô·ÛI?9@rå6Vv¡Á<Æ›ýÞ‚áÇŸ¥šͬۄGîE!cŠè½òÓ•N‡$1„Õ�´«½b-µc)qþÕÅí*—*¾dÚ¼€">ç0mÙs‰[ˆ£Gj²Øýeá�íäÑݨV”ÌX®&r\«=o»Îv6eÚëê¦ûªB–峤�9qÞ›þŠIå¸ê�Ài<È.-±]Ÿ°þë†�bÞò{qMä~µÁ.ÆñÒµŸÚ�ªE’Û{IÞ{úNŸÇµ*È\eÈŸ`"~Xl×;l•Š>vÆž½P2‹éá âk 貇gµ_€Ãr�41räNj`ì7-AëyÔ*„¤ûcÅ{TÑdLÁŸ£?fU÷Ðõ†9gÆ'3Å]ã±”äYVŽ9ø� $×^ÉlI6\ñö{ bzzÚpÅeÏa£Sä‡ d2Wmb‰ŒB­pí‡8 Udò¿Š{)_;çpl-bf½—IE|ü,\>ÎóKíQ–nªÌä0GyÁ@5z'¬q¥VÃÛEÃx¿k3EžþðËûP; 阇VB˜&¸kæ|œK³�o‹ §~ )ÞM=æ€òUJÀCÇỆ,t³Ý6Ôrè¤øJðΦ. :Ç‘â}¢p÷Ý”æn§Œj9~VÿwNfû¯ulÐbdÓSÖZ!«I?-~n}·Ëaίä¾!vJlËŠ;ÛúvwFF¢ÿæ×é½r–Ž?—üåÓîjùçõ�ϨÄ݉ˡÙ}ö—2$•h…‚qÎÃbûIYé´lä’¾ê> FDùšyzгŠL,ôê/bVeÃ’IfÔ5\6S¤¡`¨Žß`0&è £¶¸ÙªÂzÔ‡þ½ÐÃo ¤VËi‰ígDß…ì+P«xœô¹ô½ê�øƒ7ò¤SQ‘w%³%-ÐûÀ<=7ˆ^£�m¬˜ØÛ†‚}¢`Xßve‡A{n†Úïá>Îv˨ê Ų±Ì¶#õ²xkÌwa¢cFZu“ZHËÂ[J{ype7ïûÍKé1 µb2gæÙ»ò |â}ð…—Ó‚µU�³‰Ç™ŽÛõ±ëôò÷·!¢êPæÅ®ºÆí·ùYe½ £Ü³Ýl©À »s´#£Oq:* –‰uZMÊ,žÙÎÌ94Fƒf�pâRâ C¯q³žB6öÌ\~™LzDD7Ö,´9/½ŠTuŸBë9=¼æjJ¯¼Š§\ý¤`'Ç Íš‰pš¸Ô¼„75ëÆOn^(U7;º=ÞÏÿOP¡WŠðþ¼Æ“k_c»„{>µšÊsƒz¹üë½4”gw=òî?ÁŽ›>ÀSj3÷ŒYs�›usw[¡†)t“ð*ä�ŠàYÏ2L¥BØÇòJÜÕ1Œ÷45òtÅ¡£JBêë CH&T0sHÙUÁ$y�´=Ófö|ØèPÎoö÷¡ä­Û-"M=Ò4Çšb¾›âu>È[ÕW«á5÷*Ó WåJ;è¼2Ï7„{ªå°˜سµÓ¡‰T"ZOrܧ—¢ÿׄˆ5„?jõñÕ z/™¦@õx¿‹nXLÎÊg%ñXi;$i@K%’Û@f~-c]…š7Ìè#]…öûÞZèî™§=çŠk hYF¾ÒêÀ¼<Ó2ó-xßë¨5Ã{žG¹^ů"·I-4c3m)öÌég~<>I®!‚§0ß³E Ü~åÊ_Áuj3E£‡'b$glÑ¡_¥?Šf™¬Ð«–|R”îÞB8z¢_�ûð£^�yz¬uÔ+šu£rÛž >I.{©<ÞÏÿOL¡×æéyí2;-1Äi6M‡Õ�{5Ûð×'è­aškܾ¿¼wËC‘�)öÊø†GDÔ�îgÇÃb»}@¼+îgGÏCô]€j!?0¡$-�–פˆ4�™IËèƒHy4LŠþE±M�ô;Ç÷ÌQžù}LyR”®º†Ó`ªûL¨—ŠrÏb¦¸›¯÷îålÿÆ¢ÁQN\Rо.%n04k0y!*dzúxæ½wiu\6’�ŽBN'ÛЇëLô ù¢‚ýºÜƒVX•{†£�šEnÔ9¼~j—/ôrƒz[ÚŽ Ç)_b-µŸü6ÛÀZ„Uè¹Ã(ØK3$:6�&f6Ÿt$Ó,sHÒí6|í}\ª8C8eÞû¬k?>f²õ2^{4ð„ÜKPaú6ã,«2dhÀÖ[OEC¦S?lçõßäœ÷½��ìEaŸ�pT"žù-}â^�ûð#ö¼+T¹Ã �ä«Â¥Ö _%J69¥h¢�å_ÇtáÖ“”.3жŒýåo†ñuQI‘‹šÌ-Ø©6 ™¹¬HÏúB¾ºjV›´ƒ“¶ÌY8•‡R�Ù ·|ÅÅÎoˆ�›‚ÓÅí6yjJ &áñ 9ÉRlëf�é×î'ºKôMˆ^�¥¿ÆLQ4‚áa‚“¢ôA±í*a(«ã#Ñð(=&r¨òÜß{1¥ßMoõ3ôTÿ1ftôÉüí «ÈŸñU×ЃfKœ8f\cG,áfÔä¯�½žþS‹ ̉ò0 Ø[Í&n£A~ÂŒM¶Üˆ¢Êõäî5_k¼i!6ßWÓ®ŠöE—?ŸZ÷­¿‡³,HW“Ô°ó„³¶�;'¼¥”§îuh2wêK ÌÎRú¯5¶�Š Û¦OÙ®ü¸…ŠZ&½å¹ÉáüZd|ƒ N,±£±È6«ÞóÞ-úÇdÂs4OEÞÝ¢tb‰÷‰jϋ̵Eèôãp=î_À�zí¥Ò°T”«Wñ5Š!œHá°È·DÙ*¡¬‰ãÑûÖ3ôÉÚ •EåXW’-ôø±Ìv?Ò>ã{Êè%^¶r.|õlˆÖMÒiÛdž¹mE( øîûtÁg–Ùùmqž6yb]x`4è6‹dÐÔ5ë†S“°JݦÑcµð½_^6ÝfYˆ£cc”�Ÿ¥ÿšyzاÒæ¶*—©Fž÷h;7Lôr¤ÞËSÔ#ŽÄ5 Ô±!jåÐ5= sNG�^³”>NïCgèûÌ)�a±_Îå½°u¾­®f`¿ˆŽ‰Âô4…ê–U1+ò¦³È"$‡mÚå¡y‡$�yákÍø¢ s>�çuëOGÊÉæ¶ŸšÏ*bµùYQOO8¥,æÎL #ÈaІQªîß"v~PìDÆÓ~BÆEùq“ZHUnmžžKì7@ߺyV¬’ðñ~þb ýG½Ì9RXŸ±ÉO—@Cþð°�ûVð&+äÄî¸)B{Öóмògàog]>¿ó¥N‰YÏ1¶îñÇSµ—é�…«œÿMñSv+fJ-M™3ú×o WŒ�ê‡cdM6GÔË·Q?g�Þ Û‹/ü2K�‘µinºÏª„MjÆ‹nòÓÜ›17.Êzˆ¾ƒ(š`"–Øöí)¶Mlæƒy["¬¢¦ ÿöÞ<¾®«<÷ÿ®µ‡3hôljÆ8 È  C ù’†: t<¢%ÐÖ�pM’–:êe 5·¦Ð+êhÏé…BR§ ie ˜4‰¤2±ƒ�íXže 眽×óûcí}¤Zè 4Íï²ýÙÉ’Î9{¯½Öz§ç}ž<þýÔ µà�ð*:7Êo.¨“5#åªè­ŠÞÍ¢àAAygŸ÷NË{>;>f ·+YÙü1ÌÛ¾]äÎfÄç–=g;Ù“¼yã—f´J¸åVÊý#D7� ç~Ñ•7ÁìËB‚=(íõuûüÙ>:)˜Yåð‰Ô”ò£…þ:·‹Â®) [P[¼‚G�`lŒ²÷*qÎÌ:µ‹Âe¬-� ÿíä“Cô‡E’�®$ùØ9hèéèÉTTBkKSs¬= ÎU;’aÊå9âÊ£;)f}ІÊ�ó¹èßÀÊ×}ŒeoaÕ?þwþò²ó¹®’Ó›�£Þ3ÚIQôsõÍtl`W¡F%È®5#lÑhØÇD¼YªÄÇåëøÓLwM±½�/<ïx^º *]Á½»˜*Ô&|÷Ø�m”T!Ècâ-·R¾ì:Χøg¿Eámï#zë‡ L¼înåÂ<Íòu£KD –�Jž½Ïx!¤ht½c'èáÆoö°òÌEèw ¤ï/ O®B¿_DOêË’p#[¼æ|m‚¸*:_+ºªU¿`o£ü¡;¼êNÖœôHV¢-ôÇÿ"Ï3'ãÏ�rQ®ÛFÍ£¡�B†Æ<ÂÔT�Š®ÛãûÞkñ‹Ä²›D;ßÝ‹ùVljÉÜ:Öά—•%¥ÚÊ4¹j+²lSi3Ú¼œä4æ["˜oú~o§e,L? ½Ä'Ø2„Ö@f©6l-dýÙž{Ý[Íh'£Å|AùÒP´vË«¢]Wâ½t*£‘Ϊf;‹YøÝ:FùdV%ØÉP0ûæY÷Íyžô{b׊Ÿ@W,ca:âp N¨‹T1r%NŸ¸ýR7R9 =šÙ/t_÷o7 Uäyä�•«¢së. µœ wî‚$®È’†ÜpC‰F¾€+/²¸¸Øÿ­ç΢ þ_`þh¡ÿ'œ[wy9¤œï«Ê€ç«ôÅý#DÞ2�Eh¨Èý/ì¢�¼RÈNŸ/º9²Ú×ÝïžîbLW©Ì•ÖÖ2Qƒ‰E¹¨%ÍKü Óî[¶’3gŠL Žøì½9+Lê < î:o÷ñ±O>ÅhKT­fÂYÖ¸†‚¨$æj7žyt[i�(®žµ¦V 2F›•9μŠ,l‰$ì>ï÷~C¬PD™O=9Ϻ�ˆe¼õï/èæÞé(à€"Ψ€ZETä!Ùu˜ê»VúšúÂÅ%TÈ9„tÛ bm; ‰òŠ×vm…í÷ÐíAM²£xM4äûÒ¥0ãËúÇ=�—Ú– ÿý‰Õ”ò£…þXÀc›Í®íyÅ„GF1°Î7ªÜwß2Öêy鶘ôO(ê%\ë‰!«Y„F霘 slŒò½¯ò ¯Û¨•D›ÜÒfYà®ão½�­GCÿþ߾Ѱ_!�J° ×Ijvq\–ôõWqk¹OÄ£žÈ°G"äÐHõG}"¾n¥ ˜cX3Rf›Jp t1:ïI¤Ü…û».Üß=…ô�(ï_úѢU<×y–À‹%±e Q…¾Éìd_ezi‡´’‚þ{�“.&ie×™R<-‚ù9‹kZæEéÈu\¯ßÀ#£Ea�qÏ@(5W«„PiJb�×Ïz~ï>–¡Ñ�«T~*ú©sQõɤ7ŸGër6¨d×1Z̳ï’Ï»€gú÷Ÿÿ�úÿ3g•Ý™±wŠp3[ mJçÕoy;ñïÍc>wÖòÏ ßz‚âÿúc&F;7gbÅw~À—ñTõ­®UÂ6$™\�ozš®)ѽ]ÚD½ûAÃÑ9Ìl‚=ë<Ñ„4Ó�9qÐEüÝW©Œ*ÁÍ×Ó¡Ìr!Ÿ!Í,YF åkß*²¾y)öO*ò/®“‰ùå|£Qâ«)ö�÷³JÏÉH´/Kd©­‚“U!r¦Ý{ªÝh,bÏéåtÜñ��iÙ¬Ú@ ‡yXÉæ\J)~èýlU�Z%X"zÙ å]hï¥Sïc_qš»»2eÝxl„•Ó¢kJ¸ûâ.øË?êàžìà.uñùf‰Îaï~Kް`gqçe�ÿ_ŠÁ´Ð¿ÇY[ú£Ñ�Ûì Ç"r�^\&iZÔ‚†ó~å‚[Fêèm>‡«UÑÕ>:�<%°dFwRÔNo%Û½ÌK˜I*"ã¯?ÞÍ9##1‰, Ž¢R"ùF“º©‰B}µ‰xå KĆv/ÛC‰Z%Ø5å‰,Éä¦SÄÀáu+P³„[€yy6çÑ{šï@�•LŸGU¶š (ŒúdW­FPEá|IêÈ:úϰ©›òÇF<?õ-´E‰Î†°ÉÌË2/¢ÛÞÇõêhk�å|ûK„�Ì Ó^Ry×6o(øä¤B¡€í*ð�–ñ²Ö‹#RYÔ 8í0'ePjih ¯½TÈz¨ò¢F_¥’éÄ-*©ü?c½´Ð¿ëT-ý^)e´J˜ƒjؾ«@÷ª! Îài”œ"æÕI’¶?¦$:Zõ5p�7Ï9åj�¶f™ßLQs$ç)¯f 1³3Í›v|‚/¬mŽ#ú˜õ:Ê q»¡ù>3áž}‚³}ã¨V3½£GéཎSÏ{v´‘ Ó ÅÈRÄÊ8Q,)¡iŠüÒ øuÆ1«&&ã¯ßŽýçwc.½’•/«Ð#ßÙŸx¾f£ùêqÓbë�ÿŸÿp´È×Màfe4¯ mQJ[Ä<üó¡Ö_~ôïXsÛBŸ©&_½R‰Ù¨–ÙH pã^À1ì;©5ßÅ�™KÀæ&ªj?õš1Œï€“'!y.-R�u¤Ev¥2iàp�÷ôxâ�÷NóxŸßËu/àd3öRŒ1‰zi¥té2®V1Ϩ³”AVB˰Ñ�ŒÛúí�]}"¦r tG^ºœ¹oÃ1u0¯Næ]Ȭz8rf%ÚÄ‘{;2áÙ¥j«Õœ2©j3¼âW÷Ñ{¯èàÝê%úø_™öí³¦åw9'BOQÕÍ'v²Q�¨?ºBtŒˆèÈ:‹U‡Åª‰L‚É3ñT-º¢ƒ©©ÂÅÌoêæÀ©ˆ¹VÀs\!GUæÐ±s99€Ô‰<Ð�i¦q–åÈTXQF¶!ypM–à¬/ä¨ÓËù)½Ì’fŒ;òÌ6&mä~亿žë�‹xÜ]÷/wþ;þˆðƳ†š ù§yâ?ž¡óÄjñ†) ›3Ä™/cõçšfYùg1ëÞþ¼GÑGçBŠk+”x½–E|ü oû ¢?x¯å½×ñÒ³«™š* äÚn늹(åÈ�çH#úh·kV®­uÒù—×øfRàL&:˜Pd�†3î\¾z-ëF‹Ÿ=7�ðXù<— d§Ø^‚]Lîæþ® è‰Ø¾µÀ–êJ £¿ñöÞö?)äõ–•`Ò” Aëì3ÑúÚqí=ÛåëÖTe²Å™³žîCÅ _Å¡r[x— ¨ó*n-óòC+Ù|¼Û+Æ(ôcáŪ™7 Q>î›Nz•N(ç =ߤrBFe‚…Ô&:¹^eN?·@ú®t+Õ�´òGåµ-ôïëüž€™«ä;¬T‰=:n{yqA4V…­æª-¢˜+ätÐ9uR~æ:Ûª¨FÀ¯V£TP°†±2’¹ä:úD|·èÒ4]YIÍþï{èžè#Þ‚¢«ÙWdjªÀ˜"¯,ë9鳞rŸy_¦K°òP_T�/·b>Ó(ó©ñï<ÄÚÆ%m+Ø?yŠ$/XÅËE‹�pb‚Ι¯xWÉT˜ˆsuY2TÝfQØ"ÊÛEÁW&b 8x†Ïø–Ïœ|#‰ôŸãe­ÛòV9ãnF•wùùÍ¢æ¡ÂRø2±|ý zø`æG ýû9¿¬Ac^\¡v]‰ë¶•¨Ê²SEÆÔF»-]è‡ä[7÷eñùwYè¶½ÐåG6°«PÍúÁ}‡•ÌÐNŠccô|àþ\Ô€ü{än:[UÈÙj;Qóðϱ}W�u²âØù«Ð[:ÐG:Ї—¡xòþ5\q¤£†W&ÈÚpÙâ=’ ¶f{ÓŸô›ÍçïåœÜš×Žú¶_jÊšgúËÛwQ¨ŠNîùÕnOÃU ¿!V콋´L�êáÎr"‡6_»è<.ºÅX´3˦�2T¬z ìp‹( cxáGØ-ôï÷ü·šZö]MñŽ+r޳±hb‚Κˆ70UXBa´xV‚GüçrI�83 wFNô •Ù®•¥LªÙìòªŸÑô4]£ûè­m£ôZ_C+ôÅÖ/°%¤¸v”ÎOÞïã]‰bî #…ÔªñQX7J±Rñ «ÊYV®&/I%ʶRÈ“~¨j÷ tH”ï~§ÿìêvº_~¬z+=ÑG\a"FU»�ãÝ™új@ßD '/¯±„VË[pÏ�Åì¨3µ½à%™GÃ)±J_çÜL¶9» 5¬¾ƒŽ¡}ÔÔò£…þ}�ßW›j?Ñ­WQU[%�ÒYÍøÄ´ØÒ)[øz”Õª-�Øù™AA‰XÿGÏ¥ôÒ°—¿žwÑ–-¹$” ÓÓtZ„ŽÚj5XÈ颤"»T¨ŽÒ™!ÛŠ^ï<çd˘Q·ï*Tä+@FàX ä|fjŠî29àZ­„FÃ\ „»¦üF8 ‘œ cÀóÈgtN¶—Ÿí-ñÁWùƒ·°â'¯f½z2<ºÑ„oï]ŠwWjÔj‹aÃe%¯A¯):-–Ÿ9ÄÊoŽÐSCÁm£VÚs€R®Yÿ£6Õï}y¬3Ïâeñ_ëÎf ÓPY¥³Æ#I`,`'Áö�£Ž¬ †€áÇ»Bø�![gP0T&&¹q/…K/C/]…]~ ˧™a0Ÿ-FHÀ …-ã[Pÿ5÷Úi-cŒ•äŒ1„„꘸s/`ó5¨›`xPæ*.5ýŒaÎuïæTë7Y €‰T¦þçòU  ´dpL˜�»ÑäL„ 90¡1¤¢j U!± ÓUšÆ-_….�FLR·NE#Ô 'Ëô’n»†…‘µëè™ñk·Ä<�§'ÏÜšÝkAÖ¤ã6~báJ>ÓñÀW1åòn‹6 œšdÔöÉ$—câ1]ä!ž`0�äZ3D—�~8dŒ€aCÔÁ ‚«ÕŒÝX!èƒðØ1‚•«ª³�ïü{lǪv\ ~®$û�¹:nã ZòxlÂÛÙkï厅{ÿšâÞ0=«ƒªÆ˜z` ÷;"Œû¯u&L=ÿÙø¨ó¦hPU­Nr{Œyõ+h\² ó¿>NÇÞ^\¾Èa!#ÔÃc)ý‡ÓG½�ü"‡öÐL“7 ³_%1Æ3(‡àAÆÜSùȳ™½÷»p*&ôjÇŽ”Üï00ФùgçÇ2¯XŠ1LÕ�Ú¿«`ìù�._…Nø×ºáª¡Î*÷û Sq{¿ÀüÅ{1;v(öøc;f–X}XÌ}~(æØ Ò–5)©PKصLüù0WRì.º„¦aÔÕ!63Écýø>Ó µx¨“1\šr«)Üy½)û±�:CíyZcÐV€øvÌÃ?ñç.ÀÅ S�Ã�eú{擄 }Üfn�ë :ÈÌ‹u÷%8~1šÙ´Û„»?#G!ëÑÀŒÑª�%³ Øê«û�¬Œ>¡lÃ7{·W[ .#æô¸a²¿±g›‰{Ö’n¤šÔêUS©PxøaÌêã´˜GõKå*2fÑ¢c–î}™72‰�ìƒ÷¿›`ÛušÏ6ÛÁOþî¬ÝõNã–̡(Pi.¢XޱœYù·Ã\ýë7só¦†Ì¨£f ƒUݧjéI-Ö™ZŸ1/ªPXP§a=T¬VÃVª‚!qß»Ê\²©ù;¦¿c7°X n¯HØO¬uœz,ãW¯›`°õÌîÞ_ýòñZf�‚ƒY¡‰éİk®—𜇯ºBý/7­±-9E@/óï¶¢Æcùüáý¦÷ �¤÷ƒ]>@ë�ô;Xo¯ v[–¼bôï �q0Éè^÷æf�›ã· „ì?l©®i°woX¹ó¨z-Í>£ üÜ4ÑSVá¾ú¢§]†aX0Š…KcÚ=>br+00s�ªUQA ÁøF»w»šŒ²‘”34¨ÎX ~ë}Û6`yYµóð‘ºYý0ðív¼÷}Lo1''€¾ì'Æ cLÕÀg0Î:CSƒ+9lþÖ)Ï›lÁ€ÿœÁª dã=4Ì Uí9XÕšµ¨>X¡v’š�C/  n¹äú—?ã¢Þðûóæ_®@�™ãwpyëfîÜ kñ\,€IDATÓøÝu–‘¸ÑúÕÄXb !¤ägPI±—+íÇYø› °Ó “�~y/œûU*�íù½®Dë½g‰èGÚ�;w»Žq³ÿ–ãpµ‡öúÅžý;ùãOhCÅ/íh2¸EÔH\QŸ ¨ô¥7n 8ùy d^“á§–ñ×ŧ /  ’4Â… q¡ó—€3‚ñè*ÈçÛcö½ï£ÜÄ{ö“Ð9d[4š®·}öî•9ð\еžé*PÜSŒÉI°Ô¢K‹î»„¹}/Ñ9pÖq• ºÐLE¿ÆÁtˆ·Ž·?ûoOHHIÓ‚ á[8î;;ÿ¬‰ÍüËEãw0h¯c ³B‹©:Sò´nœäÓuM…�W5¸”~à'BÖo;'Øwð®”sž‘ỄÿÊ/œûÓªuï},Ã7Œ±ÕÃ[Š�çýÆSÌ/¤<C1I8XRÓ îüô3¯¿h…0`Þ¥\MÌ-4¥ÇX7¿Ê“ù$¿B8¿ŒùRGLâR °eâþ]SÔ|‚æ .ÂbiyŽGØ´‰HH¯=ñq®{u äîžó9¼õ‹Ÿè°ll´p�MŠΞpœê2 iÀfc–æáÚ C:‘„sØkiÍÙP.fH–¦³4ä[7åòŸ?QO¯6Ú”!Q€1£�æ‚áÛ®›cÏ}VÂ3¬„¨j=+kqý÷V1·}mÕ’l¦™* =`F�\þó/ ë-ofÙ�7ð‚?}!Ûwu£ÑbÿQ5§‡–åÜ/O^á¡¶9­•—•ª¡ ïûöm±×•BÒjÀ7„qI®»fQ+âYÒêc.ÝäM=º¾ƒ«v~ìjÎæ)ñ› éÜŠ®{ŽÓ-OqUÊÇý`”N(éË×qd.äÌ‚o½u ÔÏÙÄåóÖ’8¯ÿÿ“ù‹4„™kYšIDSEÒ¹�/¹�oå€JP)äœà •ŽÇ$k �4pFB:š ó±Ú\¤™)K ="íûDãè½ÄI‰tƒÅÒA@A©Il ‹Ÿ«Þª k„‘ï7‡žÐó×bSYÔ $8 %¹ô)]Ÿa­w= RÄùÏZßuèê«RNw7‰‰5¥o�"HVrö¢9°àJ`[HÖ!¸Ù'ô@AÃb‡ CèhbOZ’³˜eò”ÿq{Í1Õ°õA›Æ-ôg÷Q8ÁF Æí03êc@•1c)a†7Žº!>ãö«oónj)Tœ Á²Ó„¬Äòr-ÔÁ þ&+ùèoÜQœ«>˦óÖrÖÌð¡¯ê¢w]¡8öXF¯n*`‡Ù­>Þ§Ijª ËøCÿ-cŒ©2 1`�)àwºX‡Ë盿~ ‹×h3Éþ§ãVÏuщ…8!n%—pB0¶‰Ï(…àb,]@`OðùÛ5aH2÷Ì&¡M`¶L7(îÿòÀÂ>7*ãïz¯åSoxpÕ¥—¿ßâ`{Ï«[~ãWăëN>jÇ-!8¬…y ÷ï}BÇ8÷nˆ& ËB^D“/á6NNÇ/ÜKc�ÕÒ³¹d‘·ý_'t$cHýÜ7œ�à¼cØd˜š`÷â÷aûH Ús°jž²« ;Ì�m_Ó±% ¦·3Ë�í¯ÖÅ·þi‘(æ’ÛÕùöߥ‹Ó?ˆ1^b•'À0ˆ¨v€Í6:õ1 ÌÿNLâæú~þ¬‹h¾í¶øøAö—:èHЬr-0÷mØ›ÀÔ£^t!nïƽOì…þ«¡a|�eáÁÛ‘ðàW’ {¡gá�ÜnLJžD«�È4º2Øæ>QüԬ̉þÛZÓ€ÝsÀ3†²D ÷‰|V˜ˆ«xA{Fü,oB!ëÏu³5F”(d<­�1Æ­äm ³”ÿ<ïU÷ÒL G2’ Iä²FwˆŽû廼„"MÓ塦™Ú.¨f䇯Ê7� çàVìËÚNóõOÑ­{}›éD�ø°X5#VȤžrˆ«Æˆ–¶¢fm¨�¹©$'ÜÌÉ-Ú½ïÈö£ï Ø~t>åñž�ùSäÃ�J0�⭨Пõ1äôf¢jme Ý ¶°#¸Æ>ˆyòEÌOƒŽ=ºV\‘8|0óû�1~B=qÏ}n‚÷ZcLÈègý¨^¯wƒ&ê^ZgÂôAʃ¸ñ~¨‡ÁîÏà…ÿ÷‡±¬Çnœ€ÁAœ6o…ªô�ë[�˜G°›Ã jU&ìˬh×A\Ü$_|ëš±0gC»-ÝÇbNöÛS˰{ºˆ~ÒÓ|Œ×w‘;K­N_V’q�®=CºJ˜JE)â*l̬gí±~lûX¹’Öñ•@®t%·GWòÆèF�1cŒ©×1ãÔë˜zÝ&;ïù÷XO.5Év„ÃÔ̤/f0¹Ü hãä"ÄÙ ªeÓK,£Ÿq[o¯Fÿ´]ô/”“gÓ¼�Ñ& d¾ÿý°ß†‡`h÷º¾6}lSéÐJÜ·!xìØ ÜG–³‚MÄŒšžZ_™äÔûŽâvOWÄúË톞kì^6£ »þ]d×£cp)Oþ´c÷�UÆa¡Òû àcõaÿUí)èìÕ뜔Feì8Æý¢b£@È&ÁmD­þ&ÙýF)Ʋ[nwÕØ� –>5y,‡¶†!Iˆº ØH@ö0ØóŒæsl�ƒ^u0„Áhq<þ/?~S½“wUô㨬_#Ø·‘2„øž›ñîÇtû�÷1Á&;q’ÒÑ�ðïŽ3»{ÝhÂø€áÖý­ãÈM¾ª28d¸Ký }¼§r«ëcÜü·g3p[{0ü9Œc*TMÝäpðu¡&pÔ8‰ŠG¯ZNxƒ ×ÖšÎ/BÖv »».ÀÞ •Hl7 ¦Ï�a°̃uÜ¥•*÷Re ˜ð’¨àM¸{˜œÄP�p 7Þo‚~°†C>6s7á…×ì²—^se³ ÁñÝ Þ3°›«D¼®·î±Þ@­j�ˆ¨:Aœ'ýØä÷~S¼_tÝ//>Q¶&J5ù…ÿØNlþ™™,tÎð³´ßü‘ãï_³TPã‰zæ$"ÚIqjÊ'ОaÅ�”|4[èïËï퉆G€]¶ÇsžÝt‚žO‹ž1ùùÉ^8°�R­maü„ávQ¨És¥e$ž"È‹õðƒL­xšß,«Ÿ?„ÅDƒãË~žSí{E“–8@IStŸ£GŒEÕœ·ml$bh¬L¿"jUÏz3æ¡£9 S•—-_ ¥*Á"U“b‰Â+^K×òd“ì¡ÄÔöÂ:Q¼aš.¤°"‚{D÷}bÙž,™°>œ[œØÆ›�Q¾ r¾¼öf#:³Åµè±P ¡H¢„hô(�‡äUq&PìU`Ç"UT!Ðñô´÷þqË�ñãG!ö›LÆF»äzi{YdFrFQÝéçÌȧéYw5ETµ½'é]-q³XÔŒ´w¯Œ(“ò¡¦˜í*äX^t¨Œ•_+ºØG]Wbj{a»èþ‹/²e`h_‘ª¬¦èþÐtdsÑ‚?ê<.º?ó5.¨¡à*T®Õj¢4z–sç¿Pte2Êeþúð*ÔËsfÏ£K?ÞEòò�ôí¤ïè!½)F7[o+¡ èÅü™.à5ZEí+«�º9¢îùÕnFŠßÑ»ž=]œ½šâ7Þ²u9âg+"¨ ;¢Œþ*㨿uä“miØ„}LÄK,nv„ê'R®yK!ªv´J¸k;…]Û)äšæ[‰ª9QåÒç��Wqk9�úÉ,ðînqÞ¨Xé­ÏhȆ]Ö�½uÁ“h …ö”j5‚} ç–z½Ð—.IlE…*a®êºæ*Ê>TR„äq {¼÷ ÌÒêý,ß7Jov�¡‹t/eU‰UÍXƒ�Ó-QöFQTQ|óõtLí¢ðÕ}ôJ™’KqeùÚ]5Þ`la$Ê�LM”ªþÙ�»O¬ËŒÕâs˜áœ#âœl£(÷ž¤÷WÄ2ÍpÎ×Å“ªÕ̘öMÄ í+¶=f¡pûŠcôGµ¬è^e4d`ÔÓ��Dl˜* ZÌ;ÕµaŠBUt3µ½à“ ž–7w¡'´$N“ â‰ %‰Z¶Ø'ü`It�”�|¡çI£²k;…\�C9Ϙ°5/°`�Šž ñP •W‹´¦Œj%ÆF¢kEçØ z¨xkÙW� ï]K\ÍE�U—ÄÛØ“¢wzš®­Luç®ò=Çé¾w޵ç­e¤2¯|åSYù+×þÅ톑£˜¿h`?~&äÍ�;!ߘkÜí0_8Eá–„âÍóßsçÿÕï²õEÏâˆ:ÐhSbÕ>Ñ›ïè�b™²â¨+àÕÃë¦ù�ÓË�ñ›ÕÒ]~IXŠª­0o¡?Ú’…-KÝð¶åϦ*m’KU‰5@˜‡yî&_èíŸ/±¢�޳Ÿçw†ª,[ú£ª°Ÿç|T¬^'ŠH™ ï7õLÝ€!ܺ™Bû¾3×xq¡/ ÁÄ¢Ç)ÏI7¦ˆj¥Õb* 4A<2Dù¡Ï±,›Ç]ú&=‡DY[½÷VCA6O yÞêh>ï§èÖNŠ~“©Nø±¿ß+ÁvK‹À ïZXUeö‰âfQ¨Nß?Íy_™çÉ~¡Ws2Ò «ža…DYÄD÷rÑ}öaVK¬ÊŸ‹�øÐO ½$‘jñ_‹U-V…´^Và½÷òM×ÉuÒT‰V«DC1óΰÐÂ.xi_šj«˜ä»œ-�Lâ`^° 8-ÃLj˜q˜328y©�†0-’ö™½o‚�M½Šæ1aOçïë@i©@K1ÎoÑ$Š˜W�T8ur¯[ÉìO£[ËLm.øû­Úí¢°u³pù&ƒªv—èÞ%ºÛ“t«W ©‰˜‰¾]Vâäh/R'¿?³ŠMÚHQ¡ÄpF1MÅ4Õ�²kP#"ULâu‡HšpZ0ëfRLKrg\ÝÙ…®•¹v´“«U¼äCtÜsœîŠè¹Qôl yU�=Mâ�ÍóÑ3+sëík%8)zï݈R¾rS�:ÕÉq9­€Ó)œödŠ9¶øüp~LMÓaÿÕÎË�sØY¦^Ò)LE�“º�y…Ìfç¼BŠhf]b¾C f„9-‚Æ1bý %}‘ròy–%Ÿê@7õк~5zy�…§²îd//¼»‹¡C~³> Ûw¼«.Õ0WuÙEFu­ª­M´©´‹ÊBïÚS»®DECcå L–Q¿ã\öj5ÇTæ¬BfTB-ßÕ–:pþþ–üX¤Ž°•ý?õÿ·gfÆÎ Óœy�Lœ .ÁÎ4¼”ô’µñȵâ0 Î Mÿ¹-?ÆÆ¥ÐL júõ!ç;ð’¶à§!u˜D%œzHÜ Ò·_Å¡rnGDÄõ«ÛU�°~… OL;WÐ<&èT‰ îï`ý>¡$%½p�³@“€² '‰¨…±¹2(Þs{Ôa˜ÄwÓ8ˆškš‘Hp*7� ¦ýú¼¬j|eÖ´²_ÎÛØÈ P¤-PÀ´{“ C�E.ÒrÊ�cû_îØÐïj¦ªK Þ¨‰Dïªl¬¦ýø^òaª&ò/óï&‰7úÿ¹£s&Ý¥;HÆ_´1àÏVò�;ÞÈü�­$Ï /¥D¹!ZÌdz`:ˆZ³œŽ ôpMZ8…„XJ�¦9S4²Î�‰�åøÀ,»|‰NŒð™ý›?,áö.'x*Ø]{ˆŽü˜„4 XÓÅÝ ù 3^§ÆOb˜YrŸó¯váøWRz{ìù)�î”ù&J   ¸c�Á`0™€ª1¾YQA꟱3¾ÜŸ=òÔÿ6¡!ƒ5†ÈØì©9Bd|ç£u˜ÎÓ �zqgºqIˆK É‚ZÙì8f8ÙL9¹À�³Ç9:7É× ·S3w3Ê>¶^èv¿ìH�×¼&E;3lÞÀûJïåZß3ĵ„-7�ÒxéÚ�qä} RƒMC\ Xù'—LbP`¬‡C°ƒN€•‘gÁL ŒeŽkY“NÖ /;HpÁüH2ÚyMÃds!KÑ˾̨H0Xaªxø­~¾ƒþÿ¶Ûï4«ПB”ÜŽ6l¦…¯aw÷-×/oñ÷O¿8Ü}0 fž�éÆ@«iŠˆqp>åó¸Žoþ3ñÏ}œ|ýÈ�»n8¶ôÅÝCM^÷ßÖ°ïžgu5 ?>ŸùiÒõO)§Ï)…lHæPàˆTÀ6[œ%éêüŽ»éJçƒ#Á+‹èÌ n�M~õ)ç×~法 ÂT�!ÎÈôÎC˜Ì�¶ºHŸBmŽŸ©ø³½M6lp@ÀSþøù|«÷•e×ûê9®°Ë"(`q8/ J⪉œ‘ËP|V22Æ»¡‚VÀ7�cNbÑ”ðÈør«n«4vP³×<•K8ü{w±ðëèÉ`:"ãRDàbRÐ<µšRõû?xê½ëúv'|æ’ø¦7®0·.Ã} x…µLþ…)óßW_ÚIð[âì/Xºh"Z´\ÄŒmD÷6ýX.PWXàYAfž¿=“<ç•—ðUó-I9ÄÔœ’éî�!à$Žnd.™åÆÃ†Ê�¥>rY_Ê×p¼‘ÂÓ÷6^ô§ÿ& §a ‡Í8Ò<¹•ùVFÙ™A^Íèl„ùë—7Ñ;°)`"’¢%ŒFÏ Ä…Ž¹5¢ C(HCáÀ&‚i Hw~ #;K) Y9Säd«É?…�®[>Ìó~ümÜõþ×q�w-TÙ i7 Äcj5l¥Bù˜å�£y_ê"Ø!Ä5—š7ŒŒwo€ôº^›røU­Ol*„m×t"ì¾½÷Õ Ì¼«Eg¬À‚ËvµÜ koÉŠŒœ5D�2 HvÁÂB‹ÎÞ¿ à 4Ýæ­¥éd±À…Ùð™‡Ô »ÇSAeƒérèbAd %ÒHÌ:ƒ±Ð8d2¯6ö†M¡¢ÔÑ*ßý'Ì>üÎ3_,ó\t×bý=O6UD°]jGé¼aš.¶¼eM‰¿ýÃ{?ÕÍ-gºø\ºœ£>æ·òqi˜*n—d1o#bV§Ô�Ž•Ð/³î蹿"–m«¾&VŸË••·rpl‰”K(“×ñy×_.kíe¡kñ˜ˆ.ÛC‰}ûzYyóŽ�ã©Á¥í=̧ҀTQ›©&Q�TÝÌ*âoçY¯Þ©.¤ø‘‰Bå%J›'�ÛÉʉ¾�E¨ÚÉ�<ƒÒo(òÖîà–Æ ¾‘ö°O�̩Ȍ ¤©Å‰0Mý5%Žó?ûvÆTΓÖ[�O˜fóÞf¼Ï€oâ<ü0f¿ÿ‘óqÅPîKxÖ̉ Õ÷%C¬)´¡Í†K�¹9‹A¢ßëÓ|kLB1qÐyr}ÿîKÃú¥MÆ ŽÜÉߦÀ3¾‚ÕŸÛBç_ÅÛžÊ+¯åi‹M nyÊ�4ÄÌ`È`0 ™5ÇŽy ½zbÁÚ3¤½�L•ð®¼owëîôë·c ТvÕku&ùø�=Ì[>�`J¡BØ$I18RZA�§}CÏúåA^±¦1s’`|Šh¸Zm) Í xÐ�iÖ¥æW»š„†|ü“ŸO¯¸þâ'vˆ…À(ÖXï %9¸ ±.ÈrÙx«ÂFù÷¢’=ÏEîývǘ›¨“ypý޵iͦÖŽxÖ F´LúR¸Áúx¯)K¨Lƒ¬ç=bpp±ÿ¡q?]¿¶’�‘·�šç©·¿œku?wE�}J$�ÑNX&%° ceR �bE³+·|�éå—‡`-4F¡Ã ‹ÝÔõF†¢ËÁU«;r ½©ù/v‚ò’Ã~Ôš`0…Š]ÁzúRJgZ,{áxD$‘ÊÏOgp9Þ 6‹�-†ÔÈx¦¥‘’øûxÊ´ß!††©ø Ž †q|�ÉÀ¶µÅAL@_Ilš“CMÎýW½ù=ëÙú‹OæÕ/èb}-¢'�cVœuF2‰,Æš6Ta5¢f,5cÎMW×wˆŽ»EW–Š�QÍ«†j´]Ú€ZP�EôÍV~êÝ~GK2KÚȲçN0ï`ÞaZ~g¶©$C¢"3¢çkoåȽŸ=Ÿ˲²\± LÈK$¾–XÖ±WµWµô+ºé=¿ÿ Vðûo_Å9¿ù§1ÿÔ²õYz£†A͹2{Óº’ÚD¯ß®�¢ð¸è>,V)SÍPûPìë㵩c-ºß0“Ɯ氈SGès$íâ3âµÿãbäÕ>=öø@)—^šqD‘!ÝrµUIÜÌ‘Ž1QÞåË1!•%VÝy5Á¶S˜} ÑŒÁÉÒJ-.1œÁZ\ W´Ki@åј€¬iª¾rPºaš®kE§/gQ൜pg£Ìtf©”=ÏÄÈ-VPRgð_RÁ‰”Ð}î¸èÎK•�¨iK¦"‚~ ì£ø+·±lBÄP‰]*p£zèþ­W>7o9{Ö{e-afqS„NJ1s¤)v^Zê$Q'i“Î…ÿNUÝä˜��Ñ�~E9l9÷¤x™ªrîyÍÀUYæÞfȼÒÔ. µôp@%^û%]H–ÔW‡˜mg»áXj9–F$Šq>ûm%Câ«(á-óܨî}UÇu¢tî!çe¿¥tä`1Ñ�¢-(ZD0^WB•¸º�Þ_+yÝŸCù÷Äœj„ÌŠ0M ­¬ú‘8.øç·#Å'Eïqy5“ä2HƦL€¥K¶-T,ýýÀ˜!ÕÀÖ¨°ìùZh Wž´û”iŽÅf¶l7ñ½‰‹v‡V_¢ô ÁJ°÷�ö·Í¹ÿg¨j²7}éð°  x‰åÆISX†Ùð4š¼ý÷gøø;þG‘�7YŒƒÎÆ2IÔ4’<=µ¨d©éš1žéÄ3ÅÜųÀ ¨B…ÏŸð²S瀣8å–ŠåÜŸ¼îg..¦"�° ZcÎÆ¼èC|àpåK‹o„6Aem3sƒìAˆ÷<ëã; ÀÁµþÜaˆÞ\ÛºÐæ|H/4 èX+~òSôl´Zs8aºS¡i�±ŽfP pD‚µ-Tß#ÆÒöØ*Æ\Õ‡V�žÚ"Mò‡´w3Ü4"Ù0ép*ÓmcFÞl›ô{5vµÝ2æ¡RãÓV5ÐC7R\µŽVë§™­|€NÖ"6ãXŽã£®ý¡3§;®� %H#HMŠœ% HlàŠ4�sÎ2Ñüà;áÙTH†Ùmk»40Žê5c®Ü Y{†E–`¸uã¤j¸ì8—&Î'ìYFÂÚ:\ýSßN�ÏvgÞ‹Ëî×âÉ»_—ú£c��é—Lê2`Å#Ækè;F°êÛåmèrÝå 9ÄÞûTx`á<$üåÏ>ÄoÿìO7Mçm« ±ö®ðBäÏêÞ{¤â¡â¤èõÐ:ß„à;¹*A•Ñp ý‘ÖPV?QÞðÑ�¢"ÿ “£Š™Ë,y¢œQ3gÙ„…Ô[ö¦�op*#Qû“ Öi€0³æ�m°‚(ç»YL xh åÑ*á¶m,ŸÚåkÛ¯}]>.+£Ñ"Ï~ö«áë IçKYý:àι�³/Cj[¼,v EÕ®=@i‹({¼°�£'P|H”·<ÀÊUè9lF¨…9#¢³¢0—ÕQϦw�ñuz¯‚ª�vRô˜ã±è¤è½[teØõ¢Ç±çL²2+ï7ÝD�¶zÐìúzvͰŠè�ßÄ|äX€sE$Ììst|Éñtýl^GΠªíÆ£#GèнtLLÐéE3h0*´“¢¶Rà>-£ü™°VÈ‚ pÎãšYM=u.‹�ý÷†Ôœ…äs¹ü󢷴ؕťA?kÊ[¶dÇÅf— E¨ÖÉÊßüÛNu WFÙü9%Š' ÞS,H––œó˜…9u¢tiÕ‰B¤¨Äcì •äµ÷(.¹åŸšòM0|9FêàÔ©e%œ<"«å=�6„jÁ?û`ÆÏr-E$ê ©ˆ�̓:Ø©âÒç‘�Δ«Ê>tŠeêÎjŒèº=”®ÛFiË¢©x3ê¸n˯�H=¬|ý_õ0“Æ8M&utßÿ?¨)­ªF�ƒ»r/ÒZ°ìîju‰E¨ÑÇû4Ò?¿HjÆq+ˆJž¥#mr<ô»[°$# ‹1M~ØÅÍ4�élhè2up·ÿAþv%æDO®÷?«dnàC`ª;ÔèC¿t ï»ßK}à“š]C‹÷ ˆ¯~õï1}»E#˜7iì/,% #·3°Ó,(1Tuðá‘änHèCÝM‚­q[X€ðÑóV(ŠªÖ3iøŸ•.ž÷W�RƳñ H…bGXhÊ šMŸéÁ‘€…âÜ<ÉZ;S¹†¯ï^à–ý!\Êñ‹ »7µ=ŒÉö$÷³Š~`Öc;6xšÓÃákBzl`1òD~‹^Kn¶ÿ­ü’% À˜�`X·@u†L…­gêÏݪ2ƒ¸'M“R&˜¬ri5}Úe$Û~‚ddÝŒWBëêËhty7¢Åo¼ïzCç7!máð¥ëDŽ÷áÀ²[aÚ>BUd�ŠÆ]+:«¢ó^yÌn;c<ê»Î²MusÁÃ7û¸;uDÇEt:‹áœr$¦é|üàRou Ñyç0[Uð°Ê±(ɇ�8«Ê[ã�ûè�Êâ«ß©ÒÛ—7Ž\-�Yçî®}¨(±ü½â\Þ»÷J{ëy¯cÆÂ,ëžñÝõzHl�T­Äè@j�Pxt€ÎJÕ*!?§�¸yCâˆ)Ѭ�#9“¡ñ,?Ëú=èCÏ¿ÇÇF(>½�åy]Qµd]H†=¾slõÍtìò–6•Î)(xßPõ—ËÓ¬¡óô?Zö»ˆW¢•FÜ×díé+ÝÍ7&¢ýçŸéH䵯kÙy].K\FêäÓßì!ýçÔèÍ~hi‰ð¬°sí¸|1Fwi;FG»óì~†Jóý6ÚÐÇêUFà oØJab‚Î]S>ø/œŸX†Ï_ÄOB×Ã~×ÍBp2 8å< ²ácа•ZÂjÖÐÌ)àŒëåSÇÎCOâ u ÅÛE÷ö{èF2}(Τ¤óÇbÛóPöó LE‡¶”9roÒrï‚9yljà¤#8µˆ ÌÏlÞG¤*ãóÑ98Ò�úË ÙC`3ˆqÞø•ÍûynÀj•p #Ѧ ·^Eù°X%±| Šö¡bm‚¸¿Ÿ2SÛ H]�Ÿ�øëYïM;Ñù•áêdî¡ûþ„ÌK‰ídÎÄY7âz40 ÷¡ù› &Ùm&©ßJIÊ)-Ø’*Éös_7Wò]XBò®TgÀHFÞ08OxQß-.uôïÎ^»Æw†½õBn=è²u¤ÇOÀÝ +~•ùÉá»UÙiCÃìç…­u4·L7 É«+ŸŠœó¶H @ü0¦éŠe™ç�ó²<ÇP©0 ¬ÚMcm} U­)ðOïx¾wuM‹ñèÀh±¾à˜]¶œÃwks 0H¸îë˜ß÷~ÊàY\jÈÔ|Öv/º:–½¯¶+®§u%´†6Î}•J²…[�0!'Âpnå g »Ï¢Ä`LŠlJ�t›9psàæA9�Üå`}.˃w9úr‹|YŸ5pŸyX|> Ðh1Ï1Ÿ™j#“ᄯ‚š,ýîs³¾º‚1À`¥ªÁJUý‹‰Æû—3l†´ÉÕͨ›ÚN롘օ(üú³˜æ ö’1T縂4% ,Ʀ&Lp)Ä1„�Á9œuàea.òÀžÎ9?Ã%Þ¨þéAZ·?Ÿï¹=žÔnwa±�”³ÓÖkU“Y:2¬j°6µa±æj±ú’p é#Í5f±Ú`˜ÔäyëÍ|û-ÁËùôM.U}óÖõè^l­è÷©òêd5|pœ°Z•;�‹ôöÚ…ÉUï$I =Œd<€•�•t|œy6œk9}º“™øÎ€g~¡í¬$Òî,÷2;Cýª3±ä4z˨GÔöò8ÒwåŒf¢ñ™š*Ðù•a�aþNo;ûžÇx(ÏJú½üÏÃP›i$W™Ý:î-¢P¨)º5EwÖˆPF;9з\Ubm¥0²ÅãÓ+Tã¼ójûvº%–?k ³®Œ„ùZ“'ëç�ï<ËcÄJÖ¹•[¤U2"¾Bt°í@‰pæ–ÛJ’aÁ½…ÉñÆ1©½}q‡FÊÕ}ôVEgY¨äýòżE0S¢{ŸèýÒYÎ�Ý»¦|½Þo 2�$üP_ônüãU4�!M ¿<Ï ôÊÇÌ3t¨ ·ÿcDêqé&Ç[·ä±ß™ÅðõZ(ÃkŸrEôÙÇüùY�ÛT2Ü|"ÎÇ»0ßœʬ§Ï äײˆ÷NI+BßDê–°ÚIqì*ÊÚGqI_1ï]Ïsíï3Vß¼¤FųùÊÃwör<êÿ‹Ùxy|AáC nTSÛ aþslÁÀ(aÿ’Æ#T+!uúnAÅo+®½ÚI±†‚âü³³zS…•`b‚N�Á�RßxuŒSHKÄC¹·cì='DÏ*ç¼ c"ú/@ìè÷¼Är2MkoöÜ>Мx’eíEŽ'cyO%ñûœ¡ÂPŠŒ»ÌÖ7n™ß ɲßâxDñ>G+ëh¦À‡MÅó™q;l…¾ô.vØÁA¹JEéµ5£ZÍØ‰I¸Z|ý+!Éž§·ËÐí„r†lòU,PL ¾ ž×bÍ7ƒ]‡ÂCˆ�É$4?ÕŠL}0ؼ™x4»Á]ÜAs Ø»깪¨ðµöy­»«† µÐl;ÓëÈ%¬%¢@gãìãýôëQ‘±µzÕx­€sö«]­I¬Óò°ê6^#OäN‘ Eº‚×Y¾ÉÈò®ÿ)¤ÆT*ÕÔsöf/ªÊ†qßçÈtå²ç˜Ï½u9êGìÝé€tÿø¾àaˆJ�¾ìÁ“˜Ê ¦üm0‡ÏÁÝÎ*ÔT>Jx÷§ék�p€ÒF¢ËØæY9D´s”âwP?I1'{>r(fÖïÔ92ÊžuØZþ>mK$¢G>®sò¬úÐÊbméÌYqxŠUû®¦¸%ãÛ®2^�ŠÂ×8‘2"ßZ¹”M'gtG:W [înÜݤ¬?yÂ[ô~ßÏNm¢“øÃ.øñ™ÿ �…óÊNnÑ[‚Y‡™q˜Ó‚câBý$kk%ïŽEw\ï9ö<�B-Ϋd&íVäˆEw™E׋>UðØ�Å–kkUë)À2ÏBžßï굘ÑÑ"ºµ,*ñD-‹å+ 6d]Tí‰1ÏÍ?%º èë–oŠŽ‡~ß³ „aæé¶Û‡øÝ|¯Zìå®`ˆ˜˜ çä[÷ÇÏ\z¾ãÎß¶<üóu`Å�ýM^¾%¥Žcï•Í!‘\x%M^ƒé!Ü”ÝÜ]ŽrÃØ€Fú³ŒÇ{ ;¸&¹Ž/4+}¸M?GGÇ98cŒ­OšØc¨Êp;†’s) YÛÒ’LknI|5öº¼)37ý%ÿkî^t(äš±buDs;¶Lº."=7&Y÷fܤ“™‹ð0·«žµ$Áð#ÂÁÁAsÏ�«T”b¯ùMºXÕH |^ÌÆD¥A–ðx"ãËÜ@Ï áÖ?´¨‘–yLœÕ°ÛÝZÛÀaÌÝöT^FÌîê¥Úß‘YLÔ© S«W�À0X•ñååìRìÈ’cjy£Ñw«Ÿ/þ¼¢á›W…«oNR�äI¸ŠájÝõíÊÖç�ؽÒÉjÝÔ™0§ûi|iŽàîýXƒ»/&v¸ãÝ|°¨0T˜H_Îmm‹þ_Àuß gÐ×ab(–¡|ìÉû æaÆŸòÌˆç• «ËwQ³2æ6™¨:a¢í¢ëc·š•÷§ëš˜ô·A _µ0·­|¿cô@Èì¦Ðú{*s$‘0ÏÙU†åõ \¥σÔjX††á™X–ËDßýÁ.~mÒb�4(¸7ôÄwÞÿ™è¼‘KÖ쨂¶;vˆáeÉä“k³lp€㶸Êîôº2XµÏtƔǨCÈ#ãc‚ë¸>¯§Ôj$¼lö$Ç6ó·bê!Ç¢âŒm}ïñý¯}hb0@úV;ly>h/æP¸¥ HÆ÷ƶ$›øæ%×®hЊ'ן»Ž½Úá@Ú²‘@urÜl¦nþ¢J…Â"$xØÔëæ1 Xô(¸wv<ì\³ø™ßyüÃt}ù™÷NÇÇ.�úÀ¬üÉuØaÆO°Z¿Œ[ƼÜÙ×…¾>´ì›õÎã�nÿ'^sƒföÁ{3§vW¨î�vlÙm*ªÛ['^ž€éÓù¸.t�ÿŒ«°»½�‡Ùæ³re&ã:*¢1³.!:›"{9¸ ›Ìí =}DÏ;¿ürΟ£õËç¡k®é‡‰ƒ…Þ7Q0<ù_"Bg¡—Ý}vç(I½Ž)>{ú0®4Ctû^" 3¸‘tpG}°ö œÀÊ7Ñk1ýš7på1#`,*¤¤Ö†w×Z/7Tõ®ªÑõ9¨°ƒÑxœKÍ­\µ°}ñ4˜3 Ò5�ö�go„15M�J–O�ÛÆ\ªnKùûé`ÍRôü=¡° ‹bõOècxøNEÊU{ƒŒkM¯@›~.?ònº\)µïgSr˜ƒÏ<Ü2C°û(î5 u�u Áð�ÇŽ=æÃ÷—û+{ôrú7^3Ðþî‚U4¾~7sÍÛÙËöRC¬yŽ·ADÿÁ�£DŒï0•ŠÒe'i1N4:�TGÉÝçp§ãgB@}ÎmÙQq¼‰ðp_»âðø[ô ªá�`sÅ�9˜›ƒ9  :Ë�Ío\â8RšÃhUÕ˜÷ìÚŒ€ÜKò‚:k5ÿ… Ô|MugøîÍãª] Sºt6}úÛ«Žóêˆb‰ ¢º*Ô”Yw³{è–�1’Útµ|ÏÏ>Çñ�‹„w¾‘v?ÁÅ3è#ü©­”¹p/4×F�b�Ç^Ù¼”•ýqÖ®Ðÿ.H Š0OÏ .cm †0mRò®Ìsy&y5 CÃPyð‡>ÿ+ «­´Ó>vãËmÜéònZŸº‚èÀ– ]ý)ϰ�\Ï×.mÀXóR“¾¿ÿš®0]ýК¹�¦•m²³áÝ-ýÒ Æ¿ã•2±&6Ú‡�Ô‹ü*É¿˜íiÝh¾n4ÿ8.tß×Üaÿɰ‰ìOcAÇ2‘|ù'Rl#1šÿ×C˜7^I³öB/ˆ)Ø<—«ÍÅÏ`·~d¼Ää�}½\ø¥u ð¾:…¡±Ý¦6A5;@Åà»� `¿ú)|-¸²Q|a: x¾ƒ5ûÚ–›õ6îY²¹‰Q+F%Bµp¤HóÜñëÇxÛ?qåΟarcxr5ºï.Ì©˜)-´°¤_Ø�p%%¤êÕ µº±_üÅ{ið) \üÚO†üö[-|åñ{~?°Ã†ûrSݰž>ͤçÛãuÈ,‰‰eÀ˜T¤`—ÏîÞ°7Àwcš Þk‡ÚÞŽ9ÛJUð’ÐÜÿ^{í£¬úð0€Ïþ±ÜÙ“Øm—Ñú󧻚¤�b!èaukpPb÷dðsýXó­&„ô“nªÊ�÷ƒawJM�‰€¿½�&;°«Wcv�`3[—Èmý§gÝw{2GŸuÌEwy*é~ÝÌ‘M�Š"kÏ>ÓðÙFȾf‰ä³ðÔÌB†�Ñpzš.ß­Si«‚´OϪ™%~Hµ•jT#¨Vˆ3FN˘Ê,zwçûÝ‘#VžmO -YÔj#¤Âc"8åO;Ó�È×Ûàœc?Ç´©L­ô£²ï…®Ú]áQˆ#zÅÝtÕÚ*®�ìYÎû©}6ÙóðÿWϺ“»>‹ÿ$¥w­T¨Æ\¥rȮϕQâçЬ#lÈrBgä™xä|ïúÉö€ JCÏ×O¢Œ@1ÃDlEmÚñœ&›¼»nl$BýÑcͺCÃù>þ,ë´Áfu³]…|~Ýz•ÇÒ8@i»(Œòÿßv%6l- ��¾‰öÿ<æÛ"8Öèá3ÿM(ò Ì£aMþµ{PÒÈbßÀÀ(a®ê“¯‹ŒRÚ÷ŽdÝr�»ëþÌÏa†pûwø0bÒ7×¶.¼¡N<0‰ãPÇË 1Š@õÝÒˆaØh÷€[¹Ò¿n�úwl­f·�PZ̰[¡šuêùWÞ2AÄzìP w9w9¨œ¶tþÒ?%@Šm@ÃÐ$U`hYÎ;“†>#¿´cÏ�|Xop´XÒ 8ùé�ì¸ùcüXå2Ö×ìËÙÝ<ÍÃ�žµ6<ý}@Ç^ˆ«€ÝÀTlú&Û1–1�›̓ü=ì~¼ß÷<$¥øf:cLÆN³ø5¨ ÖèàÕ–¢”cç,�Z©ÂÐàZrA˜àZ±Öƒ†%1¨e°gcL(Ѱbà ÷~êØ+ycÆa8lÞC=™_’Àöè{„ÆýçøäfÓqÕ;IúÀþ�]Äç‚>ÖÀõ�»n í]Ñb|ÔÐ_è�øè¦³Az*>‡�³¯aP¬‰a¯÷c\ lïñ®Ìå`ëdÄ@B“ý˜ýœ‚`vöq·èªl[KI¢0=M×õ{9ç#bR±ÅEô@ç0GQòÝÚ&¾÷VbŒè�(W”©bä$þcDG=*í\yŽìÞ¼.½ôï²T[ðhFv®+úúý?.ð-PbHÓ%—Àl­åYi3 t�äl©¾§::+‚‡vÚÅœš/ñ°V£/<““?û´ŒŠJž²Zåu£Ÿ/º@ÕLß;ë×_BÍ 9N¿jÿ«[ô%Výb ù÷¢]ÝKáÔúßšµÌûþˆÂ Gð°#œ,(@΢†÷¨šó—:ñð\_ÿìó³¾x {5ûŠ9ítÞ½Öžß`”p`”ð±×Ñ[²´þM‹®L¡çÝŸðóohÅ]S¶0m㺒g»Uçr¦ÖFŒ;:œ£(õpçB…\0ïͨf ¯9kÐ>Ñ;-º–êÜ-éÚk{0ÿ ]ßs×¼î`µÁ§ˆO­Ä<é©,ÜõUBê“n2üÄ‹RÒ‹¤(L!°Ãq7 AÝÐOp’:£†!,ÕŒ¥³„Yµ@¥ H¿ n°’+“ûš*>~n…hv‘/… Â^m¡’®¬ƒu �HL+R Ò€ ,‹Íîn‰3ái^Ä�wŠ0 .t´hpäùìÿ~+ù7üóM—Á» ãïŒöG+£S 7n¦ÁFÂñ©÷X¾KXC±åõ_üÈÈ^É ØßÇÁך4x­c¡QtV©ç|ˆ:S\ˆ¡�ÆÑˆeC,Q,RKŠ g‹†‹>¶?«@LB¸Ÿu }“Ñ`¥*CÕÕë>n¯3h(aú'1»ªmnÀê1‰v隸ášß†Èü Åë7 ‘±kX˶&/¿µõfƒu×&”f˜5˜…T>]“³†|qyæÏÁ¬ªS¡Æ:HW‚rä]½n‚¬µ25FU#ªæ?Á¢ûžÙï´èžIfd‹ßa«£tnÔyNu½lP÷94¿ÞîG¶'›tº/<ÊÃbÔÀLOÓuäˆWÍz¼Cªj÷Öç’9çUÙ—W—at¨˜c�«UB߯\ ¦D÷7Ä Öèé†÷|3ä_ç ³‰¿×fÆ×5ãN;‚“‹L,v^ØYåž 4=[K|Òÿ­IS�…9¡"É|LªåèópúJvª—ûZ†&:¹ûþ.–2îPµ™FYòrF?5Òÿ$‹¾ÔšxJf�:z÷¾^¶œYÙÁÌ·#f2œ»DᔈÏh‘/}NpV5¡)LÓ\±ã¡‹ÑyŸ¼Ÿ.ÝKG/€‘Í�,«U‚GKWe9óöè¶QÒÎL´D„\²ºUíNöÇP™;ÔÁJýØrÒÓÐÅQœV™7öáÞŽœÃ>¥ôž£¡äD”‰m,z{´‘–"Ιu÷ýŠ‚Û  }ãÞÍôŸ<Û¸}®´—ߘå+-…¤`[!Æ„çwvÏJ•”ªLšâZ-ܹ :£†ñ†«* >Þ'¨ÉPU»S-ûºdWb˜6îr°«Þ‡ÂÍóNÁFõC§OÐbËá‡T|Mݰ(c¢Ã„)ɼ}D[×¥³2.öÙyÉ’5Æ6ŒMçŒUb Å,“ÁC,ó4œp×'¸ömç5Á³ùØE^xqÂ�ÉÒ»«Uwú Á`¾æô4?ôót(‹Ë3J‰$Ÿ>ÿ�uMnýøï]eSð w’ ¥Ù„ 5"±‘,±Œ°–°eHËkþâ� o<Þ] àLµ:ઙŸ5½K?¢r­©dœz‹—4$ñ÷èk¯®†zÁ¦ÝÀ½G¢jOòeÓ ³õÞ„F78GC«A“ñqhU¸ÑtîÅ‘O¸áw˜Ÿ'€šñ|€ƒþ+tP¥úèGðøZô�\˜nÅ>ó;ê�ÐÊœÕ2Ô"tÞ ÚiGw뤀Ñ�b®a5FÖ×íwº¦éÚ./¦(/2XÜ'Š÷›ßá«‹Œ©¾7»oÙB¤ �Ï„+Шo¤¢€ë÷žñÍ/ù,¯óýÚ…f ;·„}Åïî'\Àé4W�1¤©Íº›(©å™cOˆr"¢YÓŽ)@ILª˜³:wWºˆõ'zÈcÚG?ŸŒƒî¿ºEçQ1ù’ï-P>—ÖKJ|;Åœ4qšx {"JÎGš&M-I2+h*µ¿ Îùô] *{«çY\Àk†ïšaÕM'èaBžŒj5â¥rß?ì¬û® Ž|ˆŽ-ŒDUa©ú ûŠ·0»æ)¨s,-qÒó¿r”œžËg_*TP?QÎoç½�þ¨½6‘É=S‰®{EG¦h.Î Ÿ£xÜ-úî*ŽÚ&Sý ÉëÀðþÚoÃo*QÒ,Í€´e3>ø†ð½È²1 ÛÏØÄÓËìÜÉÏlã�F�íXòý ‹½gÍȈZ“õZÐÇ&Øý>x’€ÚÁ˜›Ÿ:Ûêìx­u眲 g 4Ï„D�¶¨9>Êæê²£œwl! IH¡¤ŒÉØ`cÅfê%Qˆhrü¥3üÞ—ùÖ›~rá0à™IPÕç#2þ¹ÿêG—g_ókîÎ9Ã?~¢E+‰ÕåÙ‰4P,°ÎΧ�¶„µÆÙFqâ €ž\sùu<Mz×FõœåVU³Žu:Õ‰Ü2Búy-ùÏõ‚J¿Fú•S$ÏÐ5¶Š„v†4có¾ù¤ÿÃË?r–û+)©M°:ƒàÍ/pÐ2. –±ù Þ¥ USGÆ`pǼgzÊ3Ü¥� ‹ñsãcѳ#9¯d�]>í9É™w5X¾ð§ é<*ZÎïZIU+¹(¹’ît¡;@Q)vÎó†sº™[À™´íѽtxéa_Wβæy�9Ü—±­ä 'Êu·}ŒÔ•ëLgÿQYJÿž’Øs€R.Ûûv±‚û_ØÅÅ÷\R›îàp«Ãk©ùx2ïU÷1yêuÕÎ$§‘("Q€rJNŸ©·'vz1coÚL.)Èóuã„™ßG·®äˆ:˜PçfQ˜¨‹±Œ®j/»ŒRÎçî»GCßEG|2ã̵Օ‰fzs6·è…¥}÷�œ•eÁÙŒÍ?㬖m\§TFwïʼnZ¦„ú*/y�(ýÁÎ×C,Ë*!l.0¦ˆûÕEU+±�·4NP<)l#ÍÆÀùÚ™K1J09oyÓAS1­$ä_]�O¿ëi?ˆªÃcµèžõæ¬ Yhbna?s–§œ]Í'Nö2¢Þ½¯—#ê ªn^¡Õõâú›ˆ¦b”P8á(u©<oÓœÑ:¾<�³ÄH"¯£/Å€,·ü^gøÚž¾ïcEf$+B01NgbãƒüÙ‰ç C¶QÄ-üé éFc“'•]Ú…E ‰I°Vx½«Ô9çHÅ,®t�”~ÀT©ÈØ:8c0î8¤y\­†­"Ìû‚SCF†îñÐílpvÁ9Á]¸a-ÁJà0„�_¤Åó?ßàOŸ¿ï‚ŸyÖ/œ¤qk×bM#5X §†f ¬0κ”f`ˆRÛF»="y® Þ)# 8�³[”ÉÊ4-öÐZf>ûwüØ?¿�oè�wAÊ.BèOa“`€={4_7od(šÔ‡£J¥šž…Ð�sÇÐtµ"€ý�x@ßÏ!¥˜6Ÿ»œñX„M‡‚ävt°BÄàÀµÝ ~ý…w¨¿9ö´ñ³'–¡Ó{±ox7E´k�g-\À±?®pºó7�{ù“œ±Ä=Ð2 L£`T ýÍ ¤!ÅHŒ°%.ü†Xó‹�'}næJÐÐ÷+?„ÃÏ‘ãDTT1Y0ów¼Ž-ÿ§Hsr†Î‡,ï°],~ŒÙ'=wÑêÛ�§±`š$ZÒ[Ÿ½©u°”ñYç¶=× ¢¡ÿú±Zôð˜|6¹•YôFfѳݯÐHg„I�E §Ó2Gµ‚DeæÕA"Ë‚+�ú¬j)uJ±ÇR8Õ¥žŸn&-¢»« øŒmÖÇ�Ç~™Å.,±Ð~ç[Òœõ!{ÄPv¿9¢(ïÿÎ�©-2›†Œ)zË$kÞ,ÎEêä)Íç|hª‡o("ue”ÂéÄ0“œ"”x/¦åYCMÓ-ÖÚó<Æ£z«ƒS"8á­úoÉ’¦eœ Ìj5Ú» �ÛîÅÕc‡xÒýÓœ·E#(ªV éW´O+Ûù2ã òõñ ŸvħD¨{rB¿ŠF2a¿Z� ¨ |TóD^¢R^ÈÅò¿[$cÌ^–è„Z.mR•]¾�nOO4ZäêåÚ£�]̽pÉݽÌ;_¦J±špzø6|Ù*§¤ ÎsÆåTDíäepÆ7ÅØùÌ�u©%m(�H]L#)1/ºÞqˆËo}Ñ”èù+¯¿Ùƒgª „Bvû. »¦(,& sš® åå%ý®»s²4´’¹Åbâ0i Ž*æÔ\�ÓIóŠ™u˜9_"C)Ñ‚óðßìù§Ìå÷÷Y<™ 4ÌgPâÔÓBE _áIÚÈ+´šõøRl-¿Þb•ѰÊ"õØãîºG³"Ò|ÈIyб}st=—ë�œÃù_\Áe–Ó£Ë#š[KèC!î,¸†åˆ£p¼MA ã2‰¥Ôùð‹Av •¶]B ú¨f§ÿ ×]‘?� ÿ)rYL´Šl�@xÐqn….t/ÖÚVŸ–·Þ<ѹû¸ì5 ÿ‡§Ñý™áWÏ„$&¡­nh•}³HíW5¦Ÿè,„×d„ø•ŠÒåÐ\Íœt`?ć1å%,"†9Å}´)vêuÌ$&¾¯�èáµÄ¾Œ5DݨQ7š¿_ƒåÙ�¦ë¶¯™®ŸÝoºÿ×+³{Ì¶à ›:u¹‰ß÷ºs¢™�¥ñ“ ®8Å'~]üéјÑYÓüvT¦ ÓèÄ4;1I,ëGÝ´ðž©�q~)yw>íôÌ) =1"órL‡)˜¶éH‚yl‹³¿³’Ï\µã™F˯ù°N>íJ Ó˜Î>Fµ»jì·>F¸ù4®ž©#N‚-eO8y[ð=¬�VL‘oèµ.]´` ÄôhôüÙËfÏçK›OÿÈl¼ï ÊŸ½&“¨UHhnYJ«lPK†TÁ‚ÅÉ.tRXèSLdlK¤:Eòг9Ì�³ƒ³LÝ™`.hŽ:m¤c¢fÜKª›øÕ]&ØòYV? j�óaZ ¦5[´ôÐá: ¹;aíªÙçß|î»>?åº7�æ•Õ=¯Qü�Wɼ.yëÛ/æÜ·½®ÌžÃ]�ý Ñ×$ûmd#ëÁmPäb Fë+�LÀIƒ‘§­þþ�ÀB„‹WÜl�‚C6d s!-Œm’Ó“w“| Ü�V'&<õÎÏ3ÇMÏ}£m½øÀ˜ˆX´×iKxœž?‰¨¯wy[“K]rXá°KŠ gÃvÈâ3¶¹~Yä›w9 Òq�dófZ?ýLZŸØIã�Ôì�sAó(Ø9KðÊg’2s»˜$áºuÿ§‡_ë/pù_ÇœwdžyåŸì}Š$cCI—ìvñkÎ�濉Åt¦žœ>)8 -hE îá§wrçoóâÛÃ/õ±p/“ T¸ùå,@[µõ»OÒ%Ziÿæã¥i.‹ÓÃŒù%±ÐÀ’åcÃwóËC_äï~뾶⋜÷’7ЧZ”e”(hb"'ŒIi � 3vx«4€™˜ rV¤ØR‚ùÈŸòöÝOáæ84°Ÿðào�ö•ê7<›àê§pê+,‘“}œCÑB0N8 AÈãé°§ö³Àúše¤:¿ƒ+ÌIˆøÍ?8Åß½îïžÎ•/.ð¬�ƒŒqy²!mÏ…Bô�C¾AW*jcBÖW°è?²Ø¿‡ëÎ¥ ‰"»”¹î9.QÎÒékÞ  ^é1GTeîi™yQÜû'l;PbQ+ºóøÿθÍEŒ^ÑÅ©g.‹Ù_[É7ÕV á¨(ësTªV uœnµk´>Kž%±Œä5åt’ÞZ�€ [ TŒ‰è³Ó¬Ù+Α}ñ'ï§kŸ(RU ²¹2©�‡ÞæUW–+ÕO™L‘u*ÒïÑXïøˆW Ý. Œ�D¬üÖyÝüù{;Ø>×ÉD£ÈŒºP¦VêäëÄ-œM±³>üépyW7jµ¾Ã]Äeõ÷.ÿÿ2ö%}4ŸÍ‘ÕCûÚJ$¡ÕŸõ-·1¢ÝŸ�#ÕÞ©®€;ïXtÝ[YÖ}A–œ¿¾ÕVkñòÆ {•Ñç•é²o«á“5º®ÄÓ/þ�(æäfºÇ…Õ¼WKUR@)vV%rý÷D>¼óúëœ ™þúë9µl`”Pû(J�¡C(ºŒm%4²SÅÇÛuÏUZ ¤ê¤åb>²0ÀÑNÆF¢}>8é=)z—bÑÛŸMÕò¬Ñ×Qøóù¤^ä[ÂÌé<ô"j•`_Žì̪Aùóó�yßÿ}þ³îòXß<ÓÎ2§>b&gÖ:#–­Uµj,¦ê&ïûU’§oÀܰËá±=»,«oL)ÏZ‚Ô¿m©I oç=®ZUÊAÒcÇÚØiU2—Ý''²L|/vprcIoO¢:îÍÎàÅ+i…sæ=ª“ç^Lºí#Ä Ñ“ Þÿ‚jËÐnkú‡aÌu/¥ñõ£D@ŒÐÚÉþÆÍ—¡Å¸'œ\¾‰Fø:—L^óŒo}2oüÃ'ñºyÚÿ±ÎrÖ8ܼ‘IÑ|€ A�Å9¯€7»`(v§´I -²qm Ý&óÁ1z«×»Ãë°†!ÕTýZTï3ÿV‡bfÍ¿‹Eø�&²ÇƒË*õøº -&ú"v÷LÞV·¬Ý�ЊQ+ èh7_ÌÕú&±W$!N±.@òÉücdäHŒã¡uåô »˜Ã;F´:"¨ƒÛ£ëæy×X�í}Ü»÷ Óî•§¬n1벿ñzóƒÙ*©̰õ/‚ÿ9ðw¸7þ¥EJ�!I!µÀÑ2ÕZ›q(ïBë›\´ðÿ±ã±Zôðaa�eVfv‰‚Fnísnî³*q\t|˜ÚDœ!´Êò*+E¡Â*×D<0JÈК2¥ >Ã'–F =bk!ï7¯M,²‡äØõ¬~Þ+:$:F}_n?e$3&¢Ê6JU¿ÉEš ~ßûXÖF–mé�<ž¸# [n¥œãè'P®ºÑ Q $1�£ï„}èËŽ‹n�Z«»˜* …!¯æYCÁwZô¼ŽÞ\‚uOÜ#-ú¼-úX´«xµÚm5Jϼ�eTµn¹ÏëÓ5DÔj`Έ¢Rh8:O:÷DpPŽ%3"Tjüý§–yõâšôS\GÇjÑ¡1¢ ì*@- :>Ùø8%ãŸl f–裳‡é»»².3«±¼ܳMÔˆõË”ø¹».ZÆ÷÷°O3Â×9´.ÛÌ®ÂÒç•%‰‹š þÎþóºEÏß±ȴò¨·}·{K¬ïÀÁƒh˜ÝLRw·1ôCs�+¢ÝX6¾¨Áßÿë]D³18Ç‚M‚I¶+¯ín|ŽÙc�ëuÿ»Ùƒ¸û@luÇ×÷%{ÀrÍê¦Q¿‰¯=sïó ®-ó´¿û7#‡ëávàW‘ò{¦L�Ý®ÞOX©° ªf?µhÓnîÆ¤•šáÎ;)=©·ü[oæÃñ$µ`3oIØ8l¹¥ÿ0¯{õ›‹\{Y'ýQê¹Å›Å”$‚x¢T&5¨�’œ-øÛ“°D{¾ýÕ‚;ˬøô_B}ØÑñã!@�Am5–>lβbÀä 5íaëDßI&û] F;£%×ÐÏ!éc0½ò×è¼®_{fƒ_¢Å9¿öÇ&qÆ´fcL(‰ 2ÌÏK…˜‚ÃyÔ«�ý ƧåÕ �`çŸñÑu¥?€äÃlj{Øì¨UGS³î–Ç=FÇe„ÿƘ¶>:ë�`|ÀÔëúµH˽;_Aƒ AŒ˜\ðñ—XÅE#)S†°Ë%¤�·seó;ž䘑ÿàñ-zna`6CLå¥"eV i+Nvà|÷ÚvÚÝczàƒÇ€j†U'Nð¤éiºn`º«@úÃç {�|VY6£a®h¢Lë0y )›­fLD9F¸V#¸‚{;¶¢B¥B¼òºvŽR¼ûnºrÄRdoàî®ËQÏÕ¨Hm"¾é=÷‰eŸ=̪C¢<�S‘J¦6A<5E÷Ø=^�¥´¯ÓcñÉ1«:ùä ]¨¿Lÿ7ž ù¿BþúDÈ×Z1rßåÇ15(ÁÎ9�®[DÌ-¢êÚè¹ñž¿§6ÖƒjñöçÓ-d« „Å1å %•Œû†¬LCíhgÀíw|gy-·è-oÑÛ¿K|¿½=æÊèówg]S—p}’ÙÆž’P0Z%Dµ¥#ï°|!Ÿ&Æ%X-*°˜´å½˜yG|F˜Ù„àŒ"\ËfÝÇ’üg´©›]*°kCA3¬ú†Xñ¸[ôÜË1‰ 9ëw.p£z�:ÑhØ?’ÅÓ‹*®á˜ˆ¨(¨ˆ &J}"~>ZÝÇŽf¶Ñ(zθУ?YÔžÏböÿè}þ€bô% ddL��°âÊØ;3K1“Ô ÒWõ/¬1h„:qž¡µë^âKY9ç°±P�±‰Oùš†Äè0•ŠÒ>pã`rð€G|-%0A�H ¹÷ îŒFèNW0ÕQzì�£óWw‘¾ð…´d†ô,óæêuËáGyá wÿí½{|ee}ïÿ~žuÛ—Ü&“¹a€aŒE3­¡Z¼†SJD‹þºÓVk‹—†ØŽµÇ›•žþj~ÄsB«cñÚ½[­šé6Q0a030qî“É=Ù{¯õ|ßËçó¡ÿàçÙù Fºó§ÖŒ~�øµ›YÝr%-àŠTMßDÝ}7NOÕÛQQEA�—^fÃIå bþê6Tèî¬ÀxÄ/~ì�øý?†¾ßpøù{5U¡”K¬PލˆÆ©3žÖ(§¥‘ÕF‹ ÐæáWPê©ì Ou}�²BÉ0 ¦±OJ¶:Τišç`Âh´èw@üÈ÷p.–O¬nU�ÜRä[~ÁÐSþ¸â—îÓRõÀ8h:¶hD‰TU¡D¡=”ıAa0ÄÄ nYó“7pÍ~�Sßv dÇTùÑÇp7Âó/`¡´ZS™iáá™Z¢åCë0…ÂÚ#ÒÇÀP°>{_©Pù}Pßã»ËšËî³ä¯ºç­¨úà'?Ϧ®ÿßÄ¢›Ä¢¯˜5;b­‘^5è%ɱjhùjbÑ-ãÇÍBþða²× 9!Ô[É„‚f¢Û—ëÈðÀéò_ܯ9»Èw /ø©p>Òã%zen…L#’‚_@œqÿø‹¬;|˜laY âìCò¯AÖ%z\~}Î cŸé;º›ØøbfÞ”çsKm|õ'×q°­¦g=Rh*ì"+‚[L˜<-ë¦Pœw#¿C,{g¨ñ�~o˹bÑê–ïÜEö3Ÿ±ÚéÉ ¯nfÃ7 0t¨‰Ù²Ë’hL–]î3ÉɨÁ²ú‡ì¥— ÞŠ(þy•Ù‚ìÌÚÞH˜ð¥‰e¾EšU¯�|žµE¯$=§L¹w˹‘$*<�X�÷@N[uÜÝBÀ‹ÿºÇçŸÃã&KH„šU«ý–Èff*bkÝMR÷žž£ïè奛„üûÈ âîçÍÍÏ·E×DâQ‘#­Ä’åÊoFšÙ=$\�IÝGOçèA!sDÈÉÞ}Îö"®Ãß÷¡æÅ#Ž6òù_¡®ZQç#˜X‹Éøw³èõ­*±ê�¥°¶ÞBáH²99jM™"K ¾Ò‰¾ V¡|¼xE5T NêÒÕTyÂóq_{ŸaU&Ò¶LÄàXNv»€é�8åÌ›ßΨêùèÛ¨îïÄ/í쉸ÿ÷·]ËÛžz˜�|ŽË ÂÀ`t‹zV„ʈûyÇ›`ëÄÃq*Ìly��±0šgüv¡÷Cåp'ñEïÄ-Œ#;wQï�{UpåõèÏofyoŸDܹàt¸]¯ë!꼿çöÐÙõ~)_ ÆÁܳ�S§à–_هݛ…æ'<Q(•�ëýjùíæœ"�´�wq„TÝSl‡oGWÿ6¹s2”§;ÔI¯K á÷lGùéíhO§·'µ;}Ê‹Nº1”ì:'OÒ<%´XcÌ£W\šþv h,Û¬åÒ›ºŸnwî,±ÀBhÙ7ðNž¤ù Ð6'´‹ÕE„=™Ä*h±xó,};;X’ÍÈÞ#lú¬°¡�D¹ó‰‹]Ì";k,³¡�>ûp8Ksôô¾ 9ùóÞ4 ±VVD¸sŒÜÁ:MŽ\ôF—Ñå&©nFBxe‹îÁëÈì*’9AÓ�Ð* —K-d±ˆ#cX¾ðÔ/³¾•7!ø÷&{Bh² 1½®¹™1Ze™qÙz¦ÍáO?ÕÊ£’aNPs‚”Tp�±þq,š²eeIgÕ� lZ}Ó°ÐrFh$kñÌVQ³ 8Ý)|¶bOox|ã™­–pÓÇ©þ;µX@œ ðp}Òd‰¾�dO¬…‘P‰-OÜ„…µI¦h¹ >òß›¨ˆeÑ�²«Im€Y…ã‚:]Õ”ESµï¦W , :^rY[Š+»¹Mš^#¬;y’f¹‘@lÔß²žZö"‘<2¤ ª©ÊªPôCF\$ÔE!+BsÒ_ZD˜ZŠB¶^šœÔht,>Fü;�Š�—XtMÅ cüÏ­Ò+M쑌$¬³VÏÜöÏN!Û{� �ðŠ+„zHè¸IØx²Ú†ç˯rd(‡ØSg�óÎr¶»Cb×è³¶è–O+Ù<ž°V`LGÒvêéÕU X˜_¼æ˜¬ù,ù�ÅW7~,qŒ‰Àœ€¨L‚¢—I�}j&G¼c‚E¥ÚÒu,ý~ѶZÈæŠ…Þˆ{ .Jðº!Üâ}ŽCz‚ÎX-üÍ •¨|tÊ/ã÷õ‰QJ©õ›Òý˜p…ƒ28*Bœy¯ü^ù(ø[?€y]�èï?�Ÿ¼ éyZlÀöaݧš•�ïD­uJ¯™û'‚u=‰ ÊÅJÜû¬yñ·-� F¡V=t ÊÁ8(­%kkªPÚe60Öº�€Ù{¤‘Ë|ã(DDDõÕžW­�±¬�·<³nZ'ᤓA[¸'9Aô‚éëÃ0 tQ½ªå ÌâýT¨8äóF­”AÅ(8Ê üÈ¢†EÕN-Ú« –³† îòz>½begº‡[û QF) ˜ìŒ9Ž¥*d4*L²4} ² “©Þš ¥sÚΓ<³RJÅõ «¤qþÖú¦ñtc?³ÿ&9Í®Ô ÖÖRj™÷ƒyëÖúRe�S]@\¨*Ì£† †‰~/Ñwÿ7hI46õÍ_ÜK±Þ2a&ÖXtw<±èqÝwTUA•“ëŠõãœy©q»c,gœ?r£‚¨‘ЪLÔv&B-½6‚.Bîˆ�C$ÇÅrq†âJS£œ¼¸¹kŠd§Ý´Â+õ�¾v†¶¯�¡�T$9¼…•×k¾VÁûú,YyË«bã5BÎZþ„ËÔ�à!;³l’k\ÆÊ>Ëâ²$¼N^ÄaÉ!^É ¢úÏ‚,F\’¿Á ˆÑÔU3d�¨´’,¬©†„.à^·‡ŒµH¡FÄçÊ• >1XËY ³Ë‡Â>Yy)Ö|¿ì²ò:dÄ éu¥€eµ'%}Ph{@h©�kb£@2ß¾;KœŒgYÐ+q R²¹ûêÓ,ºô)“E¾�úŽéûïòû„|Ã�e(|†»²Õ×àܱªˆ—5e³du¢ð²* +–Ŧ"ŠyÁ­ îâ ”&kñè‘2,Á”Ð2ÒÉØ�'" ´Üý¯šû…Oóo„ G… µñIXaS€SÊûŸf4jœyŽežõ¨ˆGÕ¤õ!G'ìA‘ÁýÊ*KsÍ¢§'[¡i¤—©© ;Í*%jBÉ)I§'ñggÑ쮟îÊkÚ rÿ|C¢u!µéu7P×ýǧå[Uºšyx9Š6yru˜A”F £6Âxü8jÞšŒˆëæNø¼å“pшÓ9MŒ …­ºJ)%bÅó6„J½° Õц*­ÙI€ÝÎwñSãÆ˜J†|yR¶}xž ¼^—Š žQ=@7·ÄTb#h<2‘‹‚Go|'�`ú‹Êé«”@ŸÓM¯„X%�'J˜È# /È *­ÙÑ•Ýå)2À ­’* H¢ö\GåÖ½xœß@ ~yj÷�þ›õcQ O0"H¤´µºF™(‘ùv"Mì8¨ŸÂI}„U* 0®þÖ“hyÔ ™$©½ö8¢]]³ä'üÉ?Kã-q×Ä[„��y ¢Ç jˆôË=*(€âB_¸À}(¿ý£Â\Ö(¿Œªæ ªAQÚ( ê+ žM Ý˜x.ã°©\A‚eVš˜üìãE·òøý¸;þ�E.»>Rã·{ƒßŸ0÷OãÿÊ$åk×çô ãÝÈÜfþ(R*¡„A5Þ�Œw#¥b¨J%T_rÒI’ãÉ{PQít#5”oúÿi'€Ÿ¸&Í ÛÐdíñçµà> 2Ñ]_O!}q7D/;I”™¥âüPøÅ»ÙØÑÖæ×ºwº¤*»ÏÍ¢KXS°¨Õz'¾M²èZ%Õn ðôˆ_¼œ\O«É®Yú´Ö=69DhúrÈÔî@Äj�¥~cÊôBÊc.4�Z®r]SÜ"m Kð¡9a½ÔC:§Ã÷Ø1òÇŽ‘·‘mQ©ERsdä‚rÆcÎà~jžÛ7‡‰e%eË´š]Z„¦‡„<9¹Úe¢KF#+S3l’‹xàt‹ˆ@×T¨BÓ~±yxBÑÄ¡�ÀZEjºX PY5â¦Ì�;…ìV!³[zo  upcW rM®‰‰)Ÿ£u¦ë·Ç¾­±6š²¸,G¸_šá•Ã-ˆdj5ûØØ‹ zNh?(´5ÂvÅ5c9—‘oü gœJ|t5'¨ù$—_œÔgŸ59ä;5žô3mÒÉXNPô'WѲ£P<Ñ„H3Îß û|ÃZke*Öz›Ì ,¦‡×X *¢‘ªƒˆ&2. åvd‘Gr„¢¸37%´û.S‹™VNL¸&{ßa²ieªÐ“ÂAkïÑ0—‘àÍ Î‚qY—T[OŒ&2šj�§´J—´X‹n×ÕÔ0ÁA!S²aÃÚ*"N!‰MMMѲCø‚´ðfiFF2Ëí™ÀŸ¶<iL)íççu_o™$ŸfÕSM§F€¿'*e6ý_6•޵Jl½²VÛ�¢g­zh²“*,ϼ*%Îú££öOë)pg;P¥êzˆCFuJì8èM›Ð…mèšùééW@U¯Þrƒa±ÅÅ1ø[㢣ËyÈNrCJÒ–Z& ¨KAˈ!T¬ 3™ˆÙfŽW~›W>\Qj:Ë�®ÊP?î ¨2˜¡JOF�­D(¥R!½‡J·Ý�šÕ Îâ‡ðfÀÛp+¨0s ¤Êï~`…ïþžcè¾;áÔP  ʉÁ!¢ŠAãàŠ‹qTtñ�É^h(�t郄N%Ióå.èÚ�¤îš„èi1˜ÆîH¦ÑwO-ÙÓb7�ï/¡A¶ÓÝ îëîÀ]¾!¦tRX÷î?ªÒ|Œ8Íå»XžvqÁQNŒ(M9 ߉�Š]Aª Gb–ýYîç—ëe„[ªÂ,ÞQn6½Šåa¦üB’Y(G§mŒ$êD¶tÖN5Q¡ q#*¬XDÓÝW‡õ¥~ºQöƒ$û*Ù-m¼Â4„Mkûæè´íÔº5·w(‚7 ’ÉP�:|ÃGO ·¿4`KO”þû® ‘5Y’Ág›S¯ixÙŠ›´Š§‘m’—¢ø4Ýú�Ñõ´{MޱÚÀp�òº7í 9,Ùú}F\Dœ°Æñ–D©¿¹À„_Dœž![Û^¹‘@j¾V«™‰Äב„Ûûn¡õZ¡-ÃÂr8PFŸ40-·ÝÍ×δ%Üsª(dwÁAf ý®&—ê¯âÜ_&ˆm\Y™ØC*ô®leL<Úm´6%°¢všûni b�ª+¡>vÌÖØ(�wo½þ6†§Q¼úd³Oôë.{bñ-IAd3–À"ÀH3"l¹íÙ#ŽŒåÄF“3éÉ'¹2ÃSi�4ieÜÀXõõ^ƒ^K²$k,ºª¤9v;Öάd0ß9#´¥÷Iã= sÊž,î$—Œ‹{ßí§m¬ÀÅ)½÷'eÔ~Á9ºdñQÄqñ'å—ÓbÑ‘úIƒ{ÈhŒíçñy÷\;'O6Ó;âÚÿÓ-é}S+H±PÓ/«½-cC-ư_hZÖf”ÊgÁÔ-új-îä'J-É:ð¿TfÇé¦viŽ~$Ä�übšõH-q=^ãîê$î¦å¡e:� {î¦éuÓ,ÎÓQkÏÍGoØúúÝ51VÅ‹¸`´‘gÚ3jp¨uZûÿ±88 )ENê÷z@8( DJô¥�IFtÇ÷€n¾ gè>„Çïb~²€ä >uªŽCï®MàP= Òf>n0ÚR�eª¨7ÜÇϵE¿ËWzp·CB|ÄF®;ñÚ«ë?�wÀ±ŒÀ…R(”` ÙùUê«ajãâØ¼FCì!9qÔ¨üQ¸jM¿¤]œr l9)t=¢Ç{€¾PzÃЬ€œi\k ¤À_ÝôÉÎi)wof)“Ežš!¿’•þëGí}ž¨Ï›ÚúT¡<;í½„ÜVPÕ+x†…–‡„¼jƬ/\öIž Ÿúp=[¯Øjd7EÍÅx‹ vy)®ñƒû÷ÿ »gq Løµ“Ã~êg‹�)Rp^G¦˜ø»‡ «Y%ˆ+¡õ ÷ ÍCGȘð««Ö'¹¿DZóÄ_BÍ ¾­ÑVˆá‚=7²ÛêfO 'ØqWF,nX„Œ ª¹ÆáÑ ÁŠÕLóÏX\ñ8��ìLýB.8!lN”B\[êB?­)eÓØš|§�Â'ëö3ä ÿ!!/÷‘M|¶¬ Šc—æs¬îÈòc£X2°(0[E\©¢bÓÄ㦉ñ¿G¶7 !÷.±\ô²“laïEÒì„Þi«ú<€(&FšhúÚ75gÊè•ÄŽd·*ÊÆ(*VWN’¨x9BùV˜ úî;LöŽ}vì>³Ÿfzí=çÄZð}uØúÇË3ÏÇä<‚¿ýAÀS’Çj×¹DMdì½´ôªA/Üe‹_·eUŸE!�k¬ÿßkç]AÊço-鈋ˆÚ!½#¸‚ÃHPœ°È¾NŠYá)á…/RHµ5˜R€yöd%õSìªhâ²Õ¬Á—y™´ý�Ð>=ÏúZ?©e  ź\‚†làR —Ö&4d.ôH˜f£jó¨Võøì|ôqãk÷€•šËTJ‘˜«¨bfó¢´¤U×u3Ö0XIlŒ¦lÀh·£ z>Ãû;Õ›¸Ë/IwµW èÁAôý-8§O£6}a¯ÕÉÚú¶‡ÑHˆÓü=»Ë>É¡0“EàfôW¦ñÖeð „ñ;9ä¯uå5Dÿ�ŸÜ°Ì¿¼×*Nl øõê'¸ÑZ¯®(zúFaÞž�‚V(*”%&†¨ªp”Bgª¨™Œ�¯æøáŸð©Ží  YdµiOQ’Ïó� \ã\9Äò_]oïs™"ªw3Œ[¿QJ F¿?È æR¨LŸúø,¸ïìU›nB¼®L,¹·Œk\üæ³êZ:û²Êòò¿a¦Io ÎË òÍÂÛ‰D ª’Âiâ¨ýõÊAïÚIˆ?r5Zá½.h± NŒr¬Ã®â@EnR�©„cWpÁqœd¸u ‡øÑ%ÜŽmDö"Û.¦Ú; }}Ê_ÇÔê0èL38¥äwï BÛo|PÈ.£ˆq´aU)³&Ô'¨•dD®C.¦|ëçž§š7\1ša¿]�dT±=ŒJ3Øk´s¨w#ˆ䊸Ð-•üŽÊOKaUÝjkÁ»jÍÍŸ¹ˆTò¯bðªh“וe2ùfbaP¥XôBšŸ,Ú‡ï¶yË‚ÔÀœ3dm‰«ôv?“þÀ³i©NSš§K*pÖ=luÊ•Œáõ&„|Èá,¹±ÿŠÇVqdÙX"êülý{²#‹Ãœ¸ž$ÜéD&ƒ\Hïˆ;QÄß=L�Ö¥K¢E}°¶“®¾&Êxkª¢9%pF²”ã,eÉpt9OõJ°H¼0ÑÆJO$2�/#¸iÔ;ÝYk5ÎÉÿï¶*°Ýø7ßD>ÝÑÉ13ÓÚŒLjªqÂÜ#èX&r‘—Ó¢ùÐ.(: ‹UB‘7õG‹Eœ„,R%' oLðö�¹éfò-³N ù‘{4'"¨Ä5-¹†(·�Ç$y|Çî¢À\%ƒ|—Pt¿­» L,OrzHÇ2=Õ$u9r5ôâD·�Îâžú¯YF¢ÖšÅ4MYjõiVÇÆ L-òàVE³">«ñzÌÇ$ϰo¾—f‘:9fŠëî±µ‰€·gÄf<èžðAÔCB>š çú3Xt�8Í* ¬ÆYA-ˆÊ¸ß©ðÊ©–]‰EO¹ �FBÝhÑë\Ël¥ù÷ÚI°· ušG¯áÔÿ•½~tO‚céB¿[,,3-L)&F\%yÖ}ë£bXN R¦¨áJ©�Dp£HcV5‡„ìç¾Å.iÿ� ¢5Q£�ªè§¿;"äN›O›wmZ$L�b=âÑ5pì¡Ò‘㮡ö-eX”bðŒàÆ¢ˆL¦ ’e¢Û§Xp&?–· ]\2¶ aõ ¨—í3‚¿² ³§¤‰²q9¶ß9²Ž?¸”ÔQ»iS^„ÌÍ‘³Åk. ƒöhVsYï"+ÉŒ„¸3c´¾ãyDzþå�YNV³T’¢‰qlËq@eŽ9�^+2aÝ�¢/"t3á ¡.p_6%< ø{Flš) mj‰w}½™àB­¢W,ÈÄ5U‰bñ�¨Æê«âØ rœ®æ‘G‘‚Oˆû©w4º€i°+�˜Sâ„Dî—©r8ËËFÚZ‘oæ“úUÅ|„[–Fñ »ð*u" ÍŠ æM3§…‹þä&º9_²#éÑ6%l‚tÁI:îEœ~!g J„¿fƒ-Q-Üô~Qm¡'iM©‰±b R…J½ øßŒÙ6Óú®ýœ7/t¤)ε =)¤J6›g\è�GóZ)µÔ¶·g½ÐÓšÙš�|aQÈ>$Vw|w’ÃëA¼‹Ù߬8úOŠ9Á±MuŒtŠ“n\èÆ.o5ÊðTDöÑq�&DZ�—‚8Å4}IØô7B{ºñt ~—Ð�( ¦—ØZöcyDZ8y²™OË:2ò®€Õ§²œ˜�5U[Í”9#äËâ0kÎÃü4­â²¬'‰bâ âç´ÐÒ/ää�°¿¢:bTÙj­U]V�JüÇ ËóPùÞ"ëi¿IØ8q˜vvK�œL2µÝÛÞG§÷yr–uÉàN pÝumLMH±•_\>ßC~hµÀMÖ²ÓŠÎǹ¨òŠ1Á“‡Ès£6ßã±gkÆfIªó†Èí°ÏrBh:(d¶2’áYç1±¨¨ZÍw]¶TÍ*ñÕUlR¦‹]¨œŠXíµJ…âDCâÑ#ên&ü"§Ÿ/eÝ©-.±ÔÜcvcU)¡—Mû„<›}�fßiÍ“U�‰På5¹ì5ó*EHê•Ø2‰q‰ÄãÔ¼Ãê›iâØCyzÅ ÷ð.²6új)â;F¾x‚&™À¿¦'a8’£ Îzª¿Œ#ó‘Ù`°ã#ÉBO³MKbsÿ«‚’*ªä©^…\ž-iJ×Tzº©eaRÚÜ:Ý¸èÆ“ˆÝ“ Ã:ý³ûlxã¨t40°ÿE!{瘅ÒÙ`˜èr²}ï„b1ÙíÒ D9Xl”NNJu¼gDsdõµerK;øÄcLØ‚ý#BnlžŽ¯�!…ƒº;„éI¬”xÈ‘_—fzGž#c9D2LH/yï{X÷çû`ïlž§â ÒĪ-G̈àÎÄägÅå´lÃ|»@·_D¬%ªÁ[…±ÚBÇ1òòFÅTµa "Œ&Ÿrdᣡ¤ê3·êñ­˜öÛnF¦Zn^`ã‡'Ù‚ˆß�¤)µÌÔ°-|H2å¡Ô®�dCl*…©©€c’§åëóã%Ed,¿»¬j"É#†`õz>&Í{ÈôŽà¦Ó®†ZmÒŒá õÛ£»Là¿Ãº. |º5c«V©áÖe¤ê8)�#°£ª1,K†Uáòñ®ÄýSôޏ)þ0S�ÔƒL:µì GøÄŠI¦Ÿ!¯÷M]BKy›Çt5/¾-�•FpÉϸ†zÕ(âÅ2j<ÇŠÿy‚¿øÑÏ%ÏeÏ2‡w‘M… �¹‡„|8� :™wNâ]€¼Ã–o›¨¾ÐŸfÑÓÊBe*0+踬ˆŒæÉØCÞ•Â…S·4ÝìvKB‚šü>]µOdÜöYƧÅI ØÜ†þûWãj*� ÖÜæWœú”Ð"Bî¦EDxå·å9u¢•5x]–’ÈðŠA-X9÷”µ*””5eÉ!ÒNuaò¶!­Àìº÷e{o+#™íHS’£k* p8Û…´t3×~)’¿Ƀœ×‚üv3寵!ó9,gZja]*©àbhZ1䎉ϓå—}jJh™ÚÉ ‡³i5àHh'þ¡íCB+¹Õk«xD1zÕdX–,«F<ò'oÚØh«”•r9µ¹šß™^�H¦¿?Ù¹bé‰"(ËM—Ô<´/ß…loFî´J¦+‚ž³Ñe½hà”àí9ƒóã÷ E¿†?àXþ!!ò$ÍŸ8BÇA¡­�äl� |‚ÍéIâæ›È ÙA’k¥zs†™Š=ªÆ‰€Äi‹UP+[ùU÷�ó >½RÎ!¦‰x€L¯Gz¼!Á»-µb‰�Ú(@ I}y­‚NDmýÃ4ë7 ö”Öõ©Oéý>»°ç ÌÄ:å$T©PˆD°h­©kŸU!eŸ¹Ÿ¼¹�{;š‡wØÚÿ^7ÝÐIsbûŽå…ˆË‹ß»>Dš.`ÿ¿�_Šq\ÇFþS´Z]ývQ`µšå=V*ÍÈ×ù£3m!–)ÝðD„ýBó½ Úv3²¨¿#Ñ$BS¢ö«Ï$,²©{˜n�©ð¯]èîˆf&m>8 žÛêq$Õyˆn¿‡Ì•7b.SoÊ�âƒ7UhmC7ŧÎLªb…B){ì ?-8â;±-3ãºHv…‘ÿ±›ÉŸ:äï®°<q×¢ÑJió¤ ÄšŽyjÑ;Æ•A™ý/€SV9ºÍáâu«\Ьù91lsyY!Rà࢖ qNáÆ"ÊÁ7 ªŠÕÀÓ.Ή.0Ãa3F<°2EßÂÖ£@™ò,¬lZ Ê7ZÅTQx‘à¸D1¸ÊàfFÛX#Umˆ[Oê¯}�;Žì㮿ýÚ™Óܱ 4Jb;0–×®XD+Bcó }ZJ¡RqyÍ» �sì}y~á¥/QetKD¼âà(å˜u³±zÇ{ùåS_g¼ E�«\aº²²¦ý»§(õtéJQ¡Õ"HÇL T�Aùô+P¿^ V/Ú¬ãàËcºoŒ¸ÄqpUlÖ{£c%ƱE.1àZ)”«ˆV•"çV18ÜÚŸýéyß\¹õUß¿çÆñˆiâÂÐå)${Q’÷5µšsI«ç^¯a”"ê\-̱ðÆ|–Ô ¾w—~»ôF¨n•ÔÓ×õü¬¬«UŸuDŽ&_6R ˆ<ˆDžÈôù�sïßñw§~ý‹˜_Ü[ˆ (,×½ˆˆbP ›–Ô‘þn�ytÙÛ¿[áþ×±´^á<%]#ã�´FI€ˆ(XÅÁ¸U~3ŸýÀBÞS+ ™DIR ¿x]SIÄB`@ÝCh.™F¼ ª£¡/”¨W-à,-&ð|Pã(Õ“üŸ^™ø¿kÃBËÈ š¶Ž�aL¼÷eÛ‘>ôx+ýÒÁG^ÇeÙx§O¼ßeE|Ähâ²Nu³Ÿ×kÞ êG)]ŽíÑÓ$:ã‘�âê¿_`½üÃ05„|A±U]MÖÂKÎr}�up™¼]ZÖD&�‰}Åß­à}tï“÷hþË„ÃÎÓä÷Ç0kqáé3yK°Õ*ÃIDATI´Ö“E<ù;ÖÇï£EÞÈ›¤ƒËz˜j9�Óço¥òJ.‘~Úd¾<Ž:!Æ8Ä$h¿,?‰¾°äò±{A¶q�duZh9,´'Ui¹Ú‰!ñ놅–}B¾“ÃY:‹Yº¤…mÒJ—l yå5ÑçNŸõø¹¬š«&KTÄ­¾šni§[ÚùYÇ@$ñɰ[‚Ô5¼ë.Ö‰ÐôÀiZ†È‹M°ÿ&G÷ò+È~ø°ËDÅcV4‘­ywíaÖ7‰ÄÕ’½^B›×^�Hbɱ"-˜l"*Ð~ú|†%à:É<€´| é`—´ó'žÏ/Èëq¢/øœL�¥\?MÔù­Õ]›X…e±u¦¬XŸê*Žì£cå BigÛLëÏ1ßq)’§k*(ž én¡uÍQý9\õ µÌUã•~¦DÈÝ?�ÜR‚ÒÎBŒúâK]þb0r}…ã³Ûð‚vV^ÙâÆ/Ñè*U¥ð”†jUEÞ¿zWù?Д,# ”älY½ª&»­“|Âß­ÊE¯xO\tˆqL¡G™ï¿ïàÔ?þˆà-/+.Ãåt:€Ï%\ÆcÿðO¹ê[]kõÕƒYø‹å·o„ï½’Þ³úÚÖ­n6à WSŽ.ÄUŽR‘A”-±ïq�ã«ÈS Î@—Ç¡¹¢�–js·GeÄ…Y)Óâ8塪âe9:¯9 ÏÊßÿtà†S¼iOf•è&¿ôºã¬nÚ„*©Â )0(H˜=‰ÊįÚú߯Vñäï‹Ú`PMp·Q½(ðxe¤Ù”-«œsÝOVÜHXv"«jž æØJÌÊã8‹GP�h² _cþ÷áŠQúGoRCŒÅ‹Ê^š@ÃöÞŠþ1æúq�W¡Ù=­ùrgžwò›nyÿͺ6 ±>éà5�øö¥4¢EIFY(A5Éíy¸8Ê'ÆaUæÙ³$™÷¼™©Ì¼ðŠ�öʵ/¯àËb«?u å®&¢m¸òó.4Ç<•°¶ƒA”µ¶9¢’{âqcaÎE¾ â8,鈙9²wåPÇ«TÏû.Ñü¢+3yCæÁ÷� ?éGÄÛ KÿgV†=9¥ º–= ¿G34&PÒ�ºêõŠ?ÿbßrÊPQèÀ ÐF£—p«ÒàúºDgó8gÛÊ(\%d•IÄ|„c‚B|\É)G cåKøÜ—ô*s|´K®eÊégpÕ~Ë€�%Ù�7ï+e¸ 𕼿4ÿt¬7[ž:õÛ^ÇksËô°Lv»’îÉH½»#/ÿùTùÖ2ï{ÍŸö8Qåmšìë�ç.t4ÛhÁh‹\ÌÇc‘OJ´C`01íà‰C…*?1U~°€ÿð 6U?Ï»×�÷¾÷4Ov¬òéÏf¸àó+—†—¯û'œÝ_`Q " ¥”zh� ^ކÅ+Yjâ«!<þ‡ŠM•–›"æ«x(¢¬:ÖR9«ñ3ÎiÁ‰=$9Õ âÐ(Œbá©Öý?Ñu¼õâ—(ï±Ê¢ Ôà : ‹RP¢òÇÀß g®W¢>0¬ôÍ1Îí×H•+fóùѸ=fî CµCÑ´Pf:ÂÅ%n‹‘|woÿ壷�FGQCl—æm¥(µ ¾Á—ìÊÛ¸ðêÝŸgŽ*>;Ÿ¡sÂЭ Ÿ9¹x=*;4Éêû¢ß{à­~à.ÏMÿŠƒS(#—N^$D‚ÄÄ¢qÐ&¦ê N¸>J Áðâ»éxÉWøðï>ÌNbÃÐALÿåï+|xDF-ÿeˆ_*¡U`É×DP?à (Š}êµ}ÅO´Ám`ùD³/fÐtBËäZ(ú³m³×ÍküáQäüÑClÄs.æÎFÌ«AÞúææ {F£ø²å+ET,"ðio€ÉÊñû6_ŠÐ,æZx]1=çáp+š…¶¥_ã×O±-p‰+³2C›šì4fi?´ÕÌ\ŒÃú åÍ\'\>ó-°¡u~´â^²¸¹ú£M“š/¨ò†o~îÛ¿yÕ;�êóØ’ËA´È�ƒVüx‰óô2Óñ¼ØðŽp¨rhkè¶Ä>€1JµæÔì <‡9Gó²[^£˜Ãea31«h3ó þ埾Â8œÊ.ÑQþ&¬Pš4j¨ÆçÜæ’Ÿí‰¿~XP‡‘l'·€¼_&?C®{šÅäñÞyÕn¤¢^´7è¿åjgèÌ ø3À‹J…%úŠfLÔÙk¬ŸEë)aè E1( þ!à'GÑGÏ…Ý=ÂàX,¥TFoôΧ?Нd‘¾1�ôTAå¹ áMR†qýó¼èÂÇx÷ÿµ9ûyä+ßØÝ©ÌǧÑÓLJ"zúÍž‹”wÝA*(ñÙ j‡=ÇEI‰bu+__jã¾}]¨';ˆŽ_‚›–ÈU  ¥íËš“{¾Ûuà ç¶.ËÓõ«×÷TÂÛÇԃчxoþ÷ør¥‹÷™éî|�ØïÛ­ºˆ4cï�È¢JÛí¹2%š(1¡ lû³¨úÀ+Š*ß<ÌÆ—¿)æYžFþ±“³Ú¨¯íÃíº�ê[{ɵ}ƒøÎ«X-"±R()*M¹æµ´Þuo8êEo+%Ûd’'ÔyÒ—;æ‡%–¦ïÇLJq;¨Fð›ï'Þô;²2Èz@FMŸº/¸!|UõŠPâ^p@�1àa”¾e�П…LÛ,Œ·±ô‘«Ñ×~§¼…xf�ødzÃÂÊ0÷ö°5d”�^c…£z7£¹'ÇñzX¾ä˜™I¤Ø “ôHï踼µ'8ŠÓ¿…Ì¡ üÓ«¬ÐÃò%L_Ÿ=8Œ�¡Ü'J˜Rß}þ:‰ Ÿ+Áǫ̂&€m׳x6ý¯JVxFÑÌô3·Ì8_4=ãOº¨îw³ ¨wBõ¯T�Ü.(¦vÄ=`únÁ½öq^õ„¾¢ô¬!�{žZAâ]*á,ƒÙ1ê|…¯ÒK¾ö­°õ:àsrÆÃ)ö3àn=±D~7f~ΉP©¯†¢'zx2/ÝÞœOußwhÛÕÎR_ÏÑøÒ—ªìuYQ/ºÑö;Ô6~͇¯W`ÐŒì =E(lžˆø¯�åÃ7>Äfª`„WŒG\°êðT&&×ã°wt…‘¿JzSŒÿ¨�£+w_©Ì‹ú†½¯ÓQþ!7Æ6;v÷Éu%bx•¥òéÁ#‘hµ5ÕÛ±‘Ü>¡ #Þ^ «JÁÈ"¬äYi„à—4P—>Ƕ«H xc§�©˜¨4(¢Âë½N>âöõI¥8¦œ›®d¡tï„úÎŽ’ûþ½‡¸ŸË�V:ã >·.à´7c ¼Iˆ;¬Š»š¡ Fôêsî——é¶Ì0›¹<8ί.'¡gÕÍ€À§íûOb膙6Ì�ŸÃ9ÿ|⣷ @x!îm—P&,Ê$£Ñ^îtº¹1çƒîÃa¼Êïì¡zê2Ç.ayfÒ>Sß$Œž— ½Hæ’ͪ};•�™½èBJ¯´2¡zG·;ëÅ H——ûyÄ©pȹƒÀë¶­ƒ”Âî¹6)ŠÔN*‹jûÙ¦’ wzÕÙi­^mÈMpÛJ‘÷€þCP'BeCá¯Eå*ûp}ƒÓÕÆbi:ÉC=Oí♥iŒßI”M$‡² ã²-Y’Ë%æNÆUÄvÉÓÍJwQ9“·t:ì|O™[¼p«jn•—ƒQ…å¾Â.Ÿ«;¥ÿìx!ê%mÄÿp‚ÜŸü¹ÌòÚ¾h¤·”m߀¼ô³÷jÞõê•J6ïÅ=¶ƒhœÉÛ{\úÇVR¤n‘>µ�¢3±Me ¢úäKh½ðˆi–™A&3”–™]šÈsÑ�½T~ó#8cã² ƒ\Á€îŠJîê ¶p}õ ÆLAHÈ1-Ée±ˆîëCŠÅTj«ÿÿþ#þµ×²º*j{èÒ7»ÿÿ¥“ÿw­µO2WA¥DŸ�"ÛÁ¡`i·‹¯Áûà¯P¾egç®Dpa}ê½óhµMV(MÝP¸ÌNÒ+Ædà·”ß×O´0Cf};t�¹÷¼ÍYâ®.ª3àµO²:¸]Œµäî<ȨtóiÙ^,9Ý«B¯FMI‰ Á™,öÅô•Ì;n"÷Ç7SÝNÙñ ݉Cèõ[‘÷)̘ÔÀHŠôRP£”„BŠƒ2Dèüø-£xM?O|Û†‘èÕéº]%M�¹üŸ>/x•ÉåîB�}óÀÜ®.™?»°æDý nXÁ!'w’»ï0Ù�÷‘µäŒ6lßoé•‚�^wñnD‚Ó¶€&óø ­2EK±ÁórL(‚j4XI]uZù”ÔÓ[rÆî —Ý —g»Ÿ]‡³lš­x‚¦ÞV˜‘°× “RàkHÛØ­§…Š>Å‚s��Û/4S‡-9¤ÇÒbÝFS*J!I…ZȈ+ˆs�ƒ ñŽXŠë9¡}ØR[{;éÌ»ƒüþDâ¨ø!Z“V¿íÅFÀH�n?…¾&PÇZucR3í ¡ž&¢õˆ�Û3BfÈ‚‚ÈEÎâB‚"Ĥï¶¢#{,™ÉDx·¥±$˜î”Ðrò$Íì;–GF\z†<Š¡Ÿ„˜a(!‚øÞ£¬¡éäIš§¦ì¿“ºH§•‰N`Âui⤰׋Úo"þ†ôž2–JÔ„Xá Á¯XIl]+?MjÖS˜è!'‘¡Móì8÷ºBÑ—^Ü©)ZŽ žœeÝÄMÇŽ‘O+$ÇÆ,aÊY P$¥³ ¥´ÏHF‡%‹HŽc—æ‘-¹«„üÖ2ÈHÆr¤ý„ëÜEÄel(-K={%˃Ë*Ÿ¦—­ºj¨!Î$•FÍ�H*AôQaÃô<ëëx|ËÚ!BÇQaƒÅ•�yb7;÷äIËÿ�ô¼Ð1'´×úclÈ«-vÁ·o–_¾Vùf1Ñk®!Á æœÚçcâu[F’lïA2–­vÌ«�ÅÔŽàKBÇÂ&›ÿÉ$꯵«[ðwØrËìN!‹ôº�ÏÐ�zζÿòi)ilq±ï’¢é’ûí�þßOø×3 Gr�ՔƼðÏLÖúgéçLˆ�ôxw ­÷ Íû|‰ný爛r¤œîû„üÆ™µ (ÙÈÖæ£æjÓ±!qû…\(4…BÝ~ZÖ�nbH¨»“1zú|x¶W?âu3aÇ‘^7a�õFö�aM¾Ý˜Ý"ä~ál@®Êó@h‰k`’d b)yjpÒçy¡� y…z‡)+F!)ÅnºÐ›juü ˜ VZ˜Ò]×kˆÛ§çY?�ø ™…2âžÃ‚[[òY›¸ÖÐØïéñB¡)-²8‰‘5ï»ö§ÅRØ¿û_¬hÒ(SöŒ ýé‹Ï¾kºÐ»?탴¬Ü’dœúÆóܯô”ÑßoC’“I«$ȼt£RBÁù÷¾ÏÝÛ¤TžžÆ�éD?¦ «Ã|Üû\ak5Ü®ÔФAŸØËÒ¯.D¶8c\†—= :›û¶‹ÃWGãÞÑ^F@QcϸI¸qÔáåÖW�|gÑäøEm)£®ˆ Gõ©÷¬®u†Éiâî>1£¡¢÷½dg;pÚ`˜ÆL^!€îzÙ¡IØ£4?@¸ÃøXòQ�@ŸÐ[RÇ¿B­ŽòôiÔÊ &ûÑD_!î£(2¬<ÚÐäÑ,aø2†[{c¸A R00J÷ÄúX7jf¡„ CK^0<Õç¶eÐç�¬b+È=…\y»˜B-u3žüì¡Þ?=0ž•‹Î@hi¥'éQÝ ô(xŠ·àqš+¥QY3Gìs�'ta=ª›q /“ÎWàd.Awf1<ˆ”ÂB E&AmµÎÖ;°½XržüÔÕ¿73ÚkŽSYÇAëÔI�+– ¨„‚}ÁPiF1Œ„Þ’*�dCXR+oǹð‡H÷$Œ‚9¤ÐSÒ¼ Í‘ÁØ1?ÞL¼ð¢é‰O†ûNÅ}}öó^D�‚�’žês+ÛÓçU4+;5‹8 -<ç¦n(M?t�ì8à9ƒç¯Cs%T?ùer½¿•dàRx¦º€Ü ¡é‹ßa ,ìуS ¸VjHžWÿ\¬d“Ý%‹§†�îÅ Ø_î qS±…�·˜HûJB)B&… ¦(¶9¡=õS¢„Ú=*¨y@cŸ¬%îÏÖNBÓ!—Ƭ5±è$I)„’gMïQ+m�°øã!I!,‰YŠŽ“„ܳN?ÔˆF\K¸Y#Ãø·¿ä;m¿J½ß‚‰:L³áxœB¡û³.�mû#é×¹ãšãµEÁMH�:9u!Ž$©¯JBP’5J db¿/…�¦cX?5„)‡@SÕK}yRlyƒ"u’P- PÒÆ¿I¥¡BzR’Ÿ-[}6ׄàwÉrŸ~˜uG… ‡…vIäΤžZ`ã—oå¼"âLPô0Ì9Hf_eL�ïsB{ºš“ üšv×Y=Îö Å¿êÇã¢O±àìØ*ž )œHüÃÚ6ÔõãóÈš#æÓ�{)1EïH]ï õHÂøš^uæ×µJ(5Xf]#»¾I$zaõ¿oôEe­Šf–.┸¡6yíw«µ‹0LшõÉ›ðŒ§ ñlû¿î5l(5˜ìÚßMˆÅÂ?$äÓÏ)ˆSwŸÉ j¸_ꢬ¹´äÄWm!$êµ’mk›OM�TÔw„uc3´Žœ Éúö½îÚ¸ÊÓŽÿ鳦nTº€“÷«m阈ðôøP:5>ü³¹,># ú I+2â2ü@ aØÔ#xéHbµÚÊ âžI"Ì"dúéñÒNœÚ„ '„¦ú®&êßsQ?Óõõý4ßw8E'>»3t„\ñM÷ ͵@�RŸ¹>`5zb+Ã\;!$”nÁß™ˆÕ§PÌô¤Óèß­ÝÕë>Þ„$Ö¢Á_jŒâ>£Øp:¨/˜pͯ¡ªMðt¡Ûû׬Yb='˜¹c–Éælº=‰¬ÁQS›à’nHÉ)'¼¨ýMm[†œÆEnýÛÆøF}#Ø!»K¶±¦_6ÆÔBÛþh<9¥Ñz}·ÐúÀiK„º[,­Wݤó{díBO�:"™TxdLð†§,AK#±FíjŒˆ'›ÂÁùãç¾Ð“ ægö7'‹ÞgX†% ÜÞ”žp]Ò‚‹×±ÿÌ/¹dòKd—+,ci™c‰ˆ\„„Ó/ê§Œäβ„ïl[ Ë9¢äÅ—­Ç8y®˜XµLl Œ%ßpD² ×Gf‰£Ô.±*hÊ‘!H\ì2&`YgÉ%µÃgÄ¡EÍÅà<�=°Ü!Œƒ¤�üZ˜CC,ø(f£$÷™Ü§‚P&yÖ†ßc©ˆí;¥ß]NÿB9:½o pÊBܳLïm›JªTsùY@Ÿ¡-4—“¾D;‚ƒåœwËå R›”ö>NYpPvN• ¤ý§Pq2Ï JRélKçÙ2˜ä¿•úp.¶¹ùeGrà@¬lßÛqŽSÑ�ÀÑkïo)›s Ž8öûIæNã|NpÖNMC)×8°ðY§ì˜ä>"åè 6–õ2¹ ¿œ|o ˆ�, X>»ä DßÁQ>²ZÆd3øËÕ“¿ÇØ£ï/\^±^X~_ÿÍû›*¿³© U¡"€T©j0ÊáBG¨ŠP£ªà$z[ƒwV�yöÍáŒØ~mÕ WEZâ¤àKѬ…HìU[æˆÂÕ¢Q9“q@±ÊѲ©À*n©&+JêÍÚ÷�=ƒ1F‹¯=´*¢Ñªl¹Ü”B«Æ§ª3(i£D'šeªbûPEv™è¤hÅÄ‚A0bRJ’·hl’Š›¤ßâŠ&ïX 5#¢c�ªÔðÛ– }U,”[ÙiZ Öâ±|Vý_õľ¾8–]¯u�2*Œ=ºêäÝç�Ø*Ý;¢ˆª±UÖòQ¸ª®è#Äx´$bf1BEcZ)|­ñÕŠÿSCì·*'e"V1U«�JFŒ‘àÄÇ€R “µ4¶U- �ˆ… ¤ªBÿžŽc:ÍÙ"D…2¨¸œü�1–.8§4y ˆB눑(£pPh­±ú˜Kõ¬6Z·ºb2dtDk*TV–œŽŸöùÓk— Þ�l?¬�ÞÂÒ¾ä®þš£É{U¼Тg ʱCWÕük,¸‚’³B9žkçÚ¹vM¨ ª` EÕ:ƒˆa\ —ýÙ²Lÿ%€&眢êűgT–Aªˆ“”ê‰Jhb|T£©y^OíçÚ¹v®”ã U ¢< LE)2««˜#é_¹¼ëÐ÷ùco¯ÿÁ»|6›a¶=fz#¼˜$‡="Gï«Ë *H%ó<Þϵsí?p \-‰*ÆÄ²ì¬d(g+Ò<ÎûÍà]€²ÒB±ô¨NÕ MÂÊcÍø¼ãd™“ Œ¢Š‚ûåíS°ðJkÙÿgƒvú¹v®�kÿ¾m.Ïj´æÉ–˜× |¡Šæ‰Ò"ò1<–ÿ|^ö¶Î¼‰ƒ§ûP¦qYP‹\¥écEYHq®Å"z[ÁJŤòÊ[‘Õçû]ϵsí?jSJ9¼²W_5*g èÿ´ý½7¼ý…:ÈN&,§ú¡921D#½‡¢íØ|ìFöêÂ.2û |VB_Ÿ˜ËQª <-¥t®�kçÚ¿oDÂ6,áõcKˆ7m@Ñ{÷¢sØ @¥è:‹Y°š]ô÷x`µŸx†b�:‰üó�`;w�»þ£^ݶ ϪòZY±‘÷iZ Zõ#Þí¨ˆ‚h^»×-ÜxuTDl•€R¦€è’Õˆ®EÛÇ,Y=–�ÿ\0î\;מ§&—…Ni\L�q=È‚ ÐëÀ¸)q™[(R¡/µÔjúTï J½µg3èÎihí$îFö˜„Á$ɧ H©¤œ¾> r.‘~®�kÏW;‚ò·(Yµ"¢B…H¢oíÂë5Û1€Ú ìC'ú�íÉÂíUKš+P…]bôù~×sí\ûÛ¶$zê%úR% �3 ¬]³()¢g ä5èèqG•˜# ¿WO¢„P¢J_(–xpÆB'ùüyÅ£ŸkçÚäv¨~àzD`”#\á,Aü"¤" g¡+"¢”2§ ˜ŽŽ$/~Æ{ ›DØ»Ÿ~‡s ü\;מ÷ö¦IÔQ€îQ�o™-`ìE*;iéü¼B&£m(«‰IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/icons/eye.png0000644000175000017500000002655714757047403026165 0ustar00paynopayno‰PNG  IHDR00Wù‡ pzTXtRaw profile type exifxÚÝœYv¹Ò¤ß±Š^æa9Ïéôòû3D’"YTi¸÷ï‡K$•‰|07s Êìÿó¿�ù_üi­zS©¹ålù[l¾óKµÏŸç§³ñ~¿Âë-þýéuóþ†ç¥ðãʼ_×w^O?>PâëõñùuSækœúèõÆÛ€Awöüòº®¾ þyݽþmÚës=~XÎëo(wˆ÷‹¿þ;Œ±/oü.X¾ëƒ><;ëýž¸È…pÏ|÷!~o;óþëã½ÿöÅv¶¿^ŸMal~]�¿ØèõºKßÛîZèãŒÜ�;zcWŸìÇ?lwΪçìgu=f,•ÍkQoK¹¿qáÀ”á~,óUø›ø½Ü¯ÆWe‰£/¼9øšÆ5ç±öqÑ-×Ýqûþœn2Åè·/üô~úp_«¡øæg� ¢¾Üñ%´° ÞñaâµÀËþ}.îÞ·ÝûMW¹ór\éƒ9>ñ�/óÝ‹óõ>Ð9 ]çl}·óò @¦!Ïé;Wáw^6M×¾÷Ë|ˆûÁ±¦kæÊ»Ï#¹±®Ÿ×%�}ÂÝ•õqïÄd\À6»�\v¶x_œÃŽÿtfN�û�\J~9sðMçT¯{ó™âîµ>ùçe G$R¤àš:Ί1?%Vb¨§�¢I)åTRM-õrÌ)ç\²0ª—PbI%—Rji¥×PcM5×Rkmµ7ß–ZnÅ´ÚZë�›v†î|ºsEïÃ�0âH#�2êh£OÂgÆ™fžeÖÙf_~…Eú¯¼ŠYuµÕ·Û„ÒŽ;í¼Ë®»í~ˆµN<éäSN=íôw¯½¼úÙkî‹çþÝkîå5y,Þëʯñr)oC8ÁI’Ïð˜��y€€öò™­.F/ÏÉg¶y’"y¼æ’œ³œ<†ãv>÷ûW¿™ÿÈoþgž3rÝÃsF®{yîŸ~ûÆk«ßŠ®ƒ”…²© `;ʧŽÌÝÜè,¶× Ú¯9Á�jµ~ &òö}®v(­˜�€ž-bÏq&6 Þå4ÜJ`hqs&Rœìv“@+>›G;¸p�em¥¾JÜ5ÛšXb ¬Ý}>O•v~î\-a�åû:µŒŽì§hüG®“}ãøaOt{í“vßà^²}¹mrs;眪þž•·Ï©‰·ÜÔÌÚñ+•³ÏŠEÿž¼¥Ÿvô0C;'ìÔ±6Z§W½…•úTøÏ“ç³sëõÍòî  ÈÖÏš¨•þ{Vîw`SŽ ÷ÍÊÚw_5žà‹|xf]ë·gg>NïËìÜÏîþáæál—ê®Ãè…ppx9‹¼¤îy_Oãœámf¿¶›ùÎp_fægfæmj¿7³ŸÛÌü›KÿÄfæ«ÑþÖfæw‚íwlf~æÎ?µ™ù“4ø·™™_ÚïÎÌüM‚~73ó»)ð«™™?MΟÍÌün üjfæwSàW33šœ?›™ùÓäüÙÌÌßÂÆ×™™¿…�?�Zÿ?µëÿs¨õÿP»þßAmn§æÔaxzÌ]¾õUÕaUp¸ã¡¡§ì0 x´Q`Ð&OÅAVŒ²áˆðœÂœy‹‘ŸêÇÌ£óË 1·‘âò�š!¢Mïf­–wC˜T˜Nʬ¿ÏË”ÜbÊC£¹tt»ìù¨Ï†�U�÷;µrF_܉¤Å€L¼¤Î’V/³1ûʼ1îsyhÎCöm˜ÍºX¹ßŠ9ØF�ÁÀ<‹�ÛÔ±s=ÓçU7í³ÏƒHmKj˜ ívöcèàÒ=š _¢q[Á3U<Ø­ÇkÕCô|Î-$Ô4õ¬„¯ËŠ©Œ ϼ†n.ïM�Œ½nˆ ú^r<ýZ¥˜Ð°gŸ)µ)Ã6íX£m¸'oǤmXöŒ3”~[èúnqN˜5zbîœ>ÔÓCŒd‚§žÂ8úž“¯;Ã×�Çz[ô¨þ´ÞO”�…’†µ«¾›ÝÑáb®^�j jÔ¾=Pz¤y‘µ ‰"§3õx\ìØž‘ëøþ£c£O³˜í¾;Á #¸QÉį¹KkJçBElib¿sêâúÈ:nV¶ã#Ü©|ŠäÄ]Öv7æ›mÑpQšñ•'Ú‹dlC–¶ƒ„JÄ?p‹g<ß™×ââÖ=¢–kBÿ"€§œúbðgΕ4lСֿ’O„ïÕ:ý‚^d4iŒä]¢ákg ø’’$íj€ v¬ë|ÇS…õ 15¨5‰%_ÜûFŸli¯»™�'—ZPçqõ†pG:M/£ÚÕiê0�Œí©)¨/àúÙ•$añ¼ ˜G0ðB󟛡øôÝ�\ùºåÌt©ß²ƒÐM½¨zäzí ‘æå‰âÍ{Ó{ƒêB�©\É�¤ì¸åp«€û™OL 0î=º÷ð‚¶�‘ñ!.Â�‹ƒD†y‚ð F…Gʈæ5ÏÎQaN´4óh[>>¨ç´žëä¯ùCĆŸ€Bœ×{d)Ø€epœ¦®÷Ê=¬k„P ,®Däây€²&«såøŒ<“y¿[�@,©aq#`©GJÛ×{@h£×¢ R”9êV=ë/H0�¬ÙxÍ™ÿýÀw +ì½(=S~Ïá)”Š—p6?M×õ“tUÝ”ÂxàÌ ‹Ž+�Ñx³öŒï0ìMÄ=jÅâ”Ȉ�MY a¹.ªPŽwçCÂ*_ÍÇ„-ÿ’°çqµ kz—ˆÞ™!†kF÷B{M…e_¡Ý(E7j‹‚2¼'zˆO¢Ÿ[‹�‹#g �íMíj|‘miÊ{¤[è+I«kAíjbbØ6âRDPgIÞ8¼WÄi`¡äe¦óÌŽ�ÀÐRçHJ&?ó’1ZÑêJ;ìYw©š÷"F• ïROEk6¦îw/)}_�{ÿø$Ÿke‹óÁä´çvÆÃ¨áаRN±TüÝÛ¢|¤'«§§î‘£ó8åNÄþµ_®øñVæã½˜ák‚TÚ¶Èšèï¢ë©Šq=ºƒÂ\ÂMºvp+F#@y|x‹ÂEv•e¨áYï`"s�‘ˆý0õn�šT×4U¨jh³º5Å_Á—Öªeƨ^Ü�/¬:}‰›Q)–Š$ðøºq·4š†B«)¸ÙUÒ ØñJp ŸWåY¡œFÒ¿x¾Ú±¹øJš¼Ã«4­âAØS> ,(ýcßöÁ×Oà*Ý__ø ]ã“6_÷ùiv}®†&øÉ®ñ}n9rëkjåV,?Z=ö‘ 5ïk§| Dƒ»eQÓÖÄJ�rÖÕ]P»ød¨’ÓÐ[L.#ï¸)ÌÔl€%‚r�¨š`vxª(¬¾‹*°i�„ )-úÆ"Ÿ^7…R•£ÍMÝŒÑS! Ww±¬gÔ”ê™ÜÖ ˆnBœÝ�ȱ =t’ýЯcV€"# ê] oß¡‚…C _y3”ˆKRøÄ&b9™¶Kj̳©R�wq£,Îc_?…Pq?µ/d¤‹Pv{ÜHšÔ‘E¶Á!k’áBE±h†ÁMa„‡©æ¢ás³’Ðâ’R°4öØâ¨K@�#fj0qOá#+X¥ •àæNq@ŒÅ«×e4 �!Áô2áZÀ)É Uà f[ÇMm'Ó¨K”\Ä#œ:Ì!Žõ˜¹[ñÜŠœ6ˇæ†UǺ •4›5A\M{ ”På·‡Dô‹„å"a…ÄO¹7âÂ#³ N/;�ûªáµm›2êÈG€b]xì›lãN`r‰õ¤.æÈ3P!Pž€b̯MŠË¸Ù#\fî $Ád÷ŽG­üNaíßZ%-Ñ^ΜQµr²(�[…+~yÜ|qy]¾¤\C%àJ‚ÄÉ©(2í"r!xy�Úʰã4™$ŒÜ é$jÉôÀ¨š5ÜŠt!øø70‚¸”îž„MÑ~‰öW½?mƒÊÖåL‚5“ö" mG�cÂ…ÝO~@tƒ…a´å6*è (S’:ÐV F±!2XËÕþŒ‰d.ø‹{Ç �•xï�9fª/RûZ¥îÒÝ—wn›/*5#-³ – {S±áJkÚ‚aù|¹…ó_õì#ºzÙP¹l.d´»ýN…$¸UŒ?Qï÷Òð‰|( S±@¥¥Væ“¿s¿TJå{¥dÖ¿Ö†/¥AûM¯ÒP„?"Põ–ÜïƒfW´R«&Í~²Cû¾¹çR�Vcá@¬t^&†/àJÛ<iža $„EX92Ž†Â½~ˆTƒYî×{-œsñ‚׈Ÿ–"~\Áàâ^Àö›¸ìEYRbÊ͆ü5ždˆ×7G韨“ejèã¶€åZ£`eIVÛa…ëƒõÌ›�*ˆ ½�„Žê˜! ¯ˆ -òì§RìkMpKA8[©÷IÚv|H œ|“Å?Ç++Ü„CŽÍäÅ‹¬æ1æ ¨šÊ59˜ixð«óàÔ qœÛ;XzÒVRÕÛÂ^$=9‡Ì�¨ï(mº¶œÃHHB™*£•qåC†;7éf3PdÜAÖØ”šmLU íÉ']VøÇüf˜ÇŠo7Ð+zB£Sr¥X¼£r˜TA9LBÁ…‘7êE»�´á>ÉF¬ 1Ó[!ž“:ˆÜH…_l.9 "!F7JFg8°~Œ¬ºqk0<PËU*'Ê;E¨/#Ì�Ç»”q_%ŒÙÛ(ÿQ€®~�­kZÖÜ!þŽ»î wéøA]0Ô TdògäX•Ã#Pj…gQl6¬<ƈ-—B Ê%È]w1S¸‡‘¬ª$‘‹Š? Î!tKÃHe"ïf­ñ3à2Ô4ìÈòNG0*¤¿ëÎÝ%T€7Rƒ ì?¾÷ ßcIDšUï4æ(ñ‘-3ÓHDë Šï¦ _ÛÇ=lu톑!,SŽ…rA¥žrq\ô >"FÐ2ðKzAõ€â™IK5!H½e¨åѽãÄ­~┢ڎ,„ºÄ®´U�ñð ¾ñùöprîb+AsD–ÐuÈZ‹�¶=u6A6 qNô¤ ,€ØpT>ˆ”øQ¥Ä‚¿ùhc|O2£Ûº©fwÃ{ñ±¾Y„}ðº ê±&µ�p@S̺ ïëÅá+¶©ý©/&¾Rû‡ÐvåµÅ|_\>Ö–™>(�ÁM¿í²˜ð¡Ë2Þ»,jŒ—§þÙiù®²˜”–ð£‘ÞTÀÐÕ¦#Q­]cW¿ ‡EøQQÌäM;-x3fU+ÌQóì"ÞÁ—ä1píBá&°s`‡ØY¤ŒŽo :HD…œ[+ÿˆ"! ¯£§ÞIη–Íxã%@]'Q(IÆdŒ‰ÛZ3B bñ­²ú¤MF \PgW‹ }ÏAäºSˆê+䌑 �³œôg~�肊šÎ¼<–ÅA DãA�jÉRèá\si#àˆ‹#×I='ÿ÷tj¨Vq¿ÕÎäÚqÚnyú96¼Õ`jêuG•ßMé6pàÔ–¸*ŽŒdIˆû½WÐBdîît€d¼i³‡n¯àAÓtÑ(¦»a öèÝÜyoV„ÛɈÚR“@ça®<‘8YbvïêäÄq$_çÊšW€€b&À>H,ŠÌIG1l¶’Qø5[hœ 6—!™[q? °l"-G£¬$GL¶Î¼»ˆ$†6H_ <Ì+(£öejV­ë+vÃU�[.ˆ©FL¢��ù'[A ò|·O�1•vË›j¼ÊÚéXôGÐæ—A´”˜¨•Óa˜À*qÂun"Œ­äìÍ’T�×?qŸM+žmg7uK½J²:x1ç)©…¡ÑD}tU«~´Îœ¦xÃUºä¢�|éeU;ô«¾DéÎÌ\w¢ÞÌ‚´;§Å§¡—–8¹˜Û&ü2µæ€Ù”d)Z8^ÖY½JJ„ *¯}T\ID±ÚÒâïFÙ ˆ)¬®(~ê·€~hÅ Hÿ-bšß£ãŸØxï�É®–É휘ó—ôøkçÄ|n�¤­“ž®ä�ΉϗRèÛyöÊ�`®é¢¼Ù-ŠáMx,1Õ!íû9Kóô9Àu:ÔæÓ^—¸¹¶VÅì@-ÿ|ôD&�?7gAr�br'U9»"ã3´Ÿ~?݇š^ÍÔ”nt»²*3,pùH²OºèTóÂW§’'Ž�Ñ!™PAF“ Õ¡»Θw2{%’ç·òkßwr¯Û7t Çñ»�¨�gÜ8nðvlŒZ6¿îØì.wø+™QÎ…ÌÍ‚rrÍœñ“iþÙBXD#è 5VIŽŠZÝ c)„=#º-…Ž%ÅÅZ�P©1&Š CÈ÷íC<£Â£=ñ̯iõ[%´uÇÌ‘•Œ‡kŠÊ9¦z ÀÄ Žœ¶b7‘Þ r•ì!p Q3mn'�ɪa)è‹¶ ’z&úâp6WcÕ´®:ìAsm€c> µ�ˆÕâ1XUJ¹5©ÖB&˜Ê–a9„\ävÆ5+óQ‚ÔÃÓtCÚUG +º½û¹êmÀóçÎPþˆ, ¸Ù¢]`/šÔ†]†ÅtëGV½Öþy¦ºÇÝsUË�lq„ ²^�óN›ñ:¹©cÃÌ«ïT†qWº±µ—�Óâ³EXiÛç­i6�e SpAïQ8;É Swk{÷6ð2/>ñ™/Ù ¯†¥“,uWÂm¨LCa« uÛ&M;5¶w�wEeK.ÂHf¤¼ð¡r�Zg�AR)щ”š+²¨#¾·.‘;éîçò´ÞŽk3x‡KÁè AŸ`òw6]Í'vù(?Áä·{8,â•ÉüŒ\þœ[Îo¹¥ùeÛ¢þƒ[¶¦œèò¡!YQGˆ×î.»kÓÕ‘•ä&·%íÔÉ$òï1Œ§šv)ïí"I‚ÁËØÛMRÇ—è®|÷1ë”3¢Ÿ C’2xö›¼Z–µ¼X R˜ª« ³ÑäÙõ<Å[CI'¾‹¤!0„ê§Ô´ˆ0hê™òEÑ>ļ'\ziÉ %Í¥ Ctaüš.à§�øP¿—Ê|©É~¢}$BÁ@ûsγ#ã eøþ–†gãezµ6q^Ë÷M椷uâ6hb2éyˆtYýõ6ýA[êñðpºŠf 2ª>e”Rùµ@¡ ¥¶¢Ðª­&�³#‰®·�1E@’Hê¼ pì""E—M‹n5µö D=,%Ç“(›€Ábj0ƒdmmØùHF… é€ÇrKÌ[¢Ñ‡ À’ð¡Ó>/DY;`mˆ |±Ó­>Txj:¡Þ)ëƒ6šê_ÍÓ¨¸ ÑQΜ·ìHQ®R‹x i°) êÄV*ÃrÁ_“)"E7¡—§³‚_€ÁéTvÞ¶Þ]-µ nR)¹pSánÆ¡Ì1Þ(T·Ð<½'„†bnÐ<ÄX�»ÔNt!}uN¥è˜H¯²æôKóÏ£AÃ2†éIÓ¢Ækˆ‰´AéüšÚóÁß6jÔ9s÷ˆ–-‚œ‘I[;¨¶Q¨˜f‚^—*½˜¢UzaÁW+ÐÂ[€ Lh õUMaA2äçä¥W§ ¸±yHÍÛ.V%ZFQó9¤™ë B75æˆÇ1°J´ÚMªX´¿RzÙ}e#ëÀ–Îo�8pVj þœ}Þ ~×€¨ K�l�lˆÇò쇼ˆ„é‚hýľõ†?Ì0¿:™1§vog8ß~ðOÃæ—ûå ÍϘ¯ùnÓðkg "` Ö‚Ûå î“{}úÛõƒ»MµL~©o-B‹XÒ)´Ê&�!ïH=~ 5fÞԡΜÃqù9€rw"M"!H=í¢ñÙ.n•Õœ°áò#rž3‡S'ôÖí`ÀÍŒ¯""ýuòÿŒ­‘›½r€®#õža¡÷<©ÞR„Ÿ}ÚÁ˜þý®°t±�TŸ,u\ q¯“,zÜíÛ9ÅúãgóU¨:ÊŸ´È?'}gmH�¤zfþL[Ô¯TûG!Ž?¥�-åºrÏ ­aIÈeÕðUY�¡æ¨¨†¬#LµßÔ±ÎDG|�'Úuó#w5¬uªßMïÖÛçäZ~vÛ¡uÌäãAógÖÎç û‘`æçVž ¥Àtøíß¶ÈÍ7ÇOî¾ÿOÉÒwÇ�°Ÿy�Zò:GŠ€Z¨àuêð9±b•WÎÎÜøWƒ6묒U[U‡Âî‘¢Ê/ðl™›4§èÄ{ÚHÇô,Þ=}d1¬*6ë�|t›ÏjË5Ý«�Ž™€s6ÇoÚ§ÍžYÇÃsâI'à�]z×+0zÎ?µ\õ´î뎔êw4ú=ܤØxÎ%ý±ê×aø?Uýy¼QYËëïDÖü“ýu—Ôü&“M^éª.)õ ¸ †áÊ}U‡á#‚CôîJ§×fm#]XôŒrÔõ±Wí «–ê°úc»Ý/¡®¡�Ѳ™øèÍÅà´Õ‘‘ƒJèhìÞ^û<V‡yÎ&uGߔ܄œHø=*Ú£©HLê|CÓ6� ‰Ò .$—²ž­CÞÞ #!½4“Ð.Úqê? æ´¡Þ/\!i¿/k¿oçÕüÝG ¢º—N©À‰NE†eŽF†Ð¸Äü˜bè‰ÑgQ{{�–†ÊhûÅJ@ê`R0Cz…�)‰š7÷,m.KmPÿÛf¼¬©âEG^ÚÔ‡Z'o[ü°ÚÜÏ·C[:Î �´jÞfHKá<¨Õ£SGí½Þý^`vÞ7kÄO«Z1?§ÓŽz'Ü\שŠ\©²ROŽpÉ•óDæÈµ™÷Ðü.2u†í,þþÑw túÚ2¥Mé'm˜ÜËý’€�ëz.žh€×ži»ûñù Àµ™üœ |ÛN6êJF Ît¼”ˆ$}×'Ôð¶® "K«ƒs©H¯ ¨yHèdbÔó cøY'Ît΂öö-RúxR RCÉvçá³ é;ŸÝ¬¶!àGM•Ñ“„·2†Á’Ÿ•º¢C¢�kŠ â2«]¦Ö×$Öš„�â´K»Do ºÐ¦—XwnÜ/ ¼~øã÷Üa~í”ivýîy£d´ííÕž7È `%D&K7Õé4~ÓN@h¢6;XR½S=™´Ž&.‰"ñö>õ¥�îf„[ç“ …QÇaÀÇÁ¸$…I7 dQÜn`ÄSžâýý¨ÕµÁG³¢¤‹¢ÎKÑ FÇÊÝ=}Ëß’c˜0I=(œ>~üö3 "xO³/Ï‘¤]cˆ$¶É¤L}/C`x:èêÒpO‡dÈò¨Ä‡ÊëE�»>t>‰@Ãt’¶Ÿ¥Ü×€óžNC­C€E#þ`@ó6âçý=îfõ]ÒæRøo ö¬xhÅh-:¼-š° wÕeOìˆBz³^xÄÆ�ÆkUÒ1¯Yh ïïEV­¨ >—^Ã¥×pím8óŒw‡óoÃ=[ˆÏ€çóü¬Ú:8$½ìóZ˜þ/1_ö¯&N§ë<ÈËÑÕö<$y˜…ù0�_ÅÌc¼×jÛ�œ»ßËeþ¯�‹zïã¿q„Üס‹�\ÌÏŒ÷+Û=ãédóLS×,þó ~,tü«Û߃ϼ…óOüY¶…/– fµ©Ç¼òl =3OiΩͥ�K=©§$Ö¹ªü3DÈ~ £zEt1Âò΂Z‹ø¡ÁbÕw_6«@ƒªMæƒøš{°ôç˜Cûò”#º©]£R?“‡ƒ;µ…îCV»!8ËP_r˜Ïs�ðÊ—üÄ¿÷€Æœ™w€Ÿc4�ÒèÔs¨Å.ðÖ1¡P£3—’ ñvmve-JBEòö6zR~ÞìêžÍZS­÷+®<ˆÖã^0¶º]I'Ú¥À\B¥Nÿö¼Èoÿ4ú�×Ï�ãÓ¥‡b¨ì F¨ˆñ ¹zë!™½ædï£j =ôÿÚ³‘1<„0l½Ð‘äØˆ'>ÆIÈ>¢éüò¾9SÜPþõÿ Q‡²Àak[‡;%]�½¨]Ÿb`ò]gÒžƒy:•¯�»Òn#Ð4¯ÿÍôF@^ ÐOáÆÅ÷*~@Ó6Ö LAg€_žÖŠó*›Žÿ0œb�Y%=—!Ê2€“k¥�áÌY�Ïêp ¡3Ï_eôPÆc(£iý7†2Ï ÿó¡Ì›±þÓ¡Ì»ÿgC™�.üO†2Ÿ£áï‡2_ëo‡2ÿŒÑ¿Ê|î3”ù>sþh¨™�s‚zîC]½X”ÌeU—oW >|y'¨ŽˆÊ6†LÑJQý°Á§ƒÄñ}vÀ“ú]ÀpV3ÿÜ�ɧƒ"»bKGDÿÿÿ ½§“ pHYs  šœtIMEä ̘ö €IDAThÞíY{ŒUÿ�ÇÌÜÇ>î¶ì–®< @‘·k€`)T Ŷ ,-»´„@Â#�‰‰� ]ŠŠ©`»å�‚h¡K 5åebådí»Û½½{÷î�™óð�sæÎ¹wïVãÆ&NrsgΜÇ÷ø}¿ó}gˆÖûòÅ€· 8øtÀó÷ ©£ à©ÐZƒB€óÖâ¸%—áûG>Oû)´Éø™Úÿ+² à¶¿; !àh?ð[qÛÀÎ]Ào¶L’÷gpÒî^ŒšN’îÅÇÓ&ã¢~Þfó7ÊpñÉÀwÎrŠÜ,€ùÈr`ã6@F€Tö?PMo# +æŸ(3Ž Û9}æ‘ åô9‚óÎŽA³µ"#c– £ýäÍ: f¦­ék*5‰ômðp€Pc5€Eé}@Í8ˆtÞšU…—ÌÇ¢†yaÆ*mióô XÍ}�8Be'Q@h!‘.” +<ˆ`BA0v�1аÂÊô—¢>ššq¡ÓîÊç„p4bÜZÜXÂDlrÏ\`Zá¤3iâ™DYÁS…5¸Uš;äN €°ï95ò$ %q.Êg wá¸&àxßÕ<ÁÆ G:®rn”Öæ©X#ÝñÔÓÉÒ| T=+¸ÖªM`ÖåŽÀŒ˜ËND¤÷�€´/j VÇP0óJϱ­g-­øÒ½—ÒÆà‚¸œîŒ@[XÅgõAn„”´Þ3Z§�ÒKa)­µUï‘d^@Ç©L�2mRMÉ!m°hcÝÄÊ@Ê4�JÛŒT@ÀÒ@æv¡À¾ =£°@Êb),jíÐ, l©fçÕ4í6@rZs2�9�U}§$›!7±ã™2}x“>Ü�³¡£uȪSV×{�ÔAˆ5,ÂtóàNÞqná£-Λ šÌ­í˜†—î>MûÖ)”¬…æÆp‘N¦EÌ`BŒ+¥²ÏžÁh³ÎYÀà½ÜÁ;ž2‡Òbçö !9©µÞ£”ú«b°R©ì8vùø³’˜µ$¤4F$ž%mž¥Cñ´�™¸ÎT¥,y€oIêRfÁ¿¬ë¾Éó¼ùïÒÂÛ `L)õ>€’Öº ÔZ BˆGi#„tSJ¿Á÷‚ Ày5Š¢'޾d×]’LìËØ^C³U·a!ÚÌD¼¯€žåE¼¾¶��Ô·GÖ°œ¸Gšç·ÖußìyÞYžçM•R¾¦µž¤”H)ý!d.€YÖòSF”RCJ©·…;´ÖÜó/pÎoÊd2_Þùè¡×FQtÿäääí=Ë‹’9XÞÞ_`=Ë‹2ñÄŽ» ‹Š²)„� !ØÑ_`=½E¹½¿ÀR.ææóùo{žWð‘…Å$çü\BÈÑ{É‚dŒÏ;OkýwSRÊÆÆÆæóùÎL&ó`·ù¾¿ä͇æöŸtÙðÝ!±Â[zz‹2pêªbÉ×…Þ¼UElï/ §·({z‹2p,ŸÏßšÏç/°Gk=fÙRÇqü&€ýþÍt^(¥ž ÃðNÎù%³gÏþ€î¡¡¡ „?&„™ÍfúçõmxuM; Ÿ¶Ì(‘¼›ÒfšxÒì[î/dO»ª([ZZî䜡µþ@@\.—×ŽŽŽ®ãœe!“’�”÷T*•sªÕêåZëw]È2ÆV•Ëå÷‡††¾%¥ìÏd2?ìîîþîØØØÓ¥Ré ÎùâY³f½—ÉdV€ŠNKš{æ-/‚z&¨/º±8õÚCŸ¹�Rº¿Rê#•Jåñ±±±õB²àêÉ—c'k­?P´Âÿjttô±ÖË?~¦\.022r5€’»f[[Û¹_½.zfdddC†Ë(¥'Ι3ç9CCC‹µÖoBÎår÷½þðwQ œÚW”TMºi2Ç$ðÒ³r™Læ:ÆXV)õ¶”rdbbâ=Ƙ·àêÉ-ŠKBX†×���;;;O×Z—ϸvò%Gö•^°óÑCwBÚj„Aˆg_SÙüš¶S´ÖK2™Ì†¶¶¶G8ç×ß0wîÜ;!'ø¾¥¸Äx¢ÑâÔM%|››h0Æ.ÐZ�EQ´}bbâ•J¥òÁ™}åÁWïÙn(×7iÐ�ÔZW9ç ýØX†*à�_ï¿’òÙºšZ©)5ëœuUik¹\ŽãøÈår÷ttt6<<|‹Rêq¥Ô³µòQU—Ì9 6±Š¥!Ä?¢(RØü•{^fµö4‰�R>AŸçyï0ÆÎÀw55/Z5µõ‰5-U­5›wÝä M]\—¯QÐMƒ8 ’@,Mg&€sWìÙ¤<à·?kS6···ŸíyÞ· ô°Öº,¥B|äûþpÇq†ƒJ)@SJI6›m ‚àó/®?`!¥ô�\.7[k=Q­V¯/‹#A°E}åa ¹  2Å=ã@LÄ6»šÑ1 l µ§Òú‘jà‚«JÛ$€§îoÓJ)–Ïç»=Ï;šs~ çüðL&£mY4jœ’µ«„J©×Ëåò–0 çœ.]9õ¢"fOYÄNÍm­Í½Þ[=à ê7Ò2�äõ'‹V”¶��ß_˜?55õ;kí„�¤ÖšB4’œ~'m„2oUiël'»u™„ £„rö¤£ƒ¨‚XRÀ‹Ó†¤xH‚.ùOõóûŠ›š1�‘Æ&ž¨Sc×Rs¤óºÅV Ö$×aª¾Ž¤®VLÕ—�®† åù T›üx³ýÄø ‡�W2ÑâÞñЋSd–2=eö¬Ò1MS“�þŽö¤"ôÅcš*¾tÙxH0ÐßÑ6ÐßÁ/�ú;˜ÖšQ2Íùv‹"TK¯·ÇÆIQ“ÖŸ±uáâÞñØS¶Ýº˜[�yö šWž÷Žï© /­×-<•Ó–®/){V´tŸT’PK¡©"6q�S˜ÔÀÌÅ7¯®åFÚžÎyö¨OyN`9qŸ‘n°ÐÍ)bwTiòªÍ{jûy"ýx‘°RbbŽ4ÈçõS€ªš Vû ¸e'°îÑa´eþóo©M‡@¹ LOhš�Oú5ô/U�›w6a¡íOnÄ‚}ðK=Ei×´3ë}âR‘U :|üæ¾§ÀG¯8õ½Ÿ޹è: Úþ·¯��w6âÿ×ÿÂõOu ³Ú×ÈÔGIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/icons/eyecrack.png0000644000175000017500000001026714757047403027160 0ustar00paynopayno‰PNG  IHDR00Ø`nÐ ÙzTXtRaw profile type exifxÚí˜in,É „ÿç)|„ܘL'WÀ7ðñý±º¥·Î{fÃÀ¨¥îV-¹�Áˆ`…ó¯Þð~ŠôªhoÖZä§Zµ<øÒãëçõ™b}ÞŸŸò>Åÿߟ'2‡Ê—+Ûy_?8._nÐú>>¿=t½Çéï�Þ'>,>sæËûºþ¨ä×ñôþ?Øû¾Q¿ÚÎû¯è3ÄçÅßÿ_•`lá`É!Ÿ’JäÝoÌåõ7øSÞsI\”Š¿}»8ÞÇË·¡±½/hßÅè}<ÉÏc÷Dèë¥/3sâì�ðþ»{w¿÷¼v7j#R-¼7õ±•çNBYžÛ/åOø®ÏËxu¶¸ºO7y­�,e¢}SM;�tÓy>WZ,±æ“•Ïœq÷c½h¶¼Š§ ú+ݬ¤a‡ÒÉÍ"k…Ãùs-é™×žùVê̼WæÄ`‰;~x…Ÿü#¯Ï�îõئûg¬XWvÔ° Ïœ¿s I÷Syâû¼ÂW¸‰_%¶�AyÂÜÙàˆó5Ä”ô[åÉsá:‰5ÄÜ“î÷„ˆ¹…ŤBbØ©¥¨9kJı“ŸÁÊs©y’�$’w —Ü”ÒHNÏ>7÷hz®Í’_‡¡!¥Q6Ý …dÕ*àGkCCŠÔ "MTº˜ŒVZmÒZÓæ5´hUѦª]MG/½vé­kïÝú°l k¦Áº™�Á¤ƒ¡w®cæYf�2ÛÔ٧ͱ€ÏªKV[ºú²5vÞeSþ»m »oÛ㤔N=rÚÑÓ��qÁÚ-·^¹íêí×îøÌÚ;«ßf-}—¹_g-½³æ«Ïuú%kVý"9�ˆçŒŒåšÈ¸ztöœÅžjÍž9ÏY´LQH&kI<9;yÆÈ`=)ËMŸ¹û’¹_æ-Hý¯ò–+sÁS÷Wd.xêÞ™û1o?ÉÚ�¢”'A^…ÓX.ÄveŽÜù…�ÿøgø³ü=Ðÿn ?+p�©ù©áîäw?kn6¤o`45Ä�ÇëZ¾�jY]ê™§·1§WH¶YÍåžRqKw.�;�¯ô2æ^­œƒc»†8$/³™ €»WŸŸ7Îûº¥¬•Ε…|j>5Þiñžªw5›ˆá *q)\q3ûBµ¢©éÊ�½ò´Óù:-ï ÿS9ÝïkéõNL®½¡~L]Øa¢Ö**ÝåP~c!U1Ñ�ª¸Ã’Ÿ§0*žhÃ~HÜ‘ýðÛÈ U²Å‘b8<ŒXM£§s,I˜(½Öçß´{c)|ßò3Ö!–k<Ó­ Ç#Ä1”{I—y’˜c—²pä RW(ÜFöæÂØw“²×4ÌMƒ{m_îd3�U^8‘Áîe�ª{H"wįg2qq@>*¬ "Žùc-=–¶©m $¿ÞܤŽÔôAð6–¹6ä1}Cë¬SSå„â¶®õ n{«d‘ò ,Y5ïÆÂ¶-G¿M¡AJo©æ±fF{޲Kk=µS¡f¢�Öõ8Âî±é¹Ë®uŸ ½‹„Aw; aÄxÚjä×G™5§9ªYœ™<2ûŸˆG»¹öÄ”ñ¨ì)ɰF¥Ü°˜±öyîç–p´h#³M ës͈t�j¾õ±ª×­~�Éð|ù&A ¶%•iÒ@#˜ÃëDð‡ñE_CÅ•æl½ª‡­íh3±�(ÛªužÑìÌÔÅ…—1¸»·LnœVé'Ϭžlº£+Çqt¹e6–Ë÷ òø¼Kѵ"‹C åÖ;çâ ÁAGÀ+¸j!)b e[n}Í’_ê[>u)«gÓ^G‘#&›L–jÑ ¡†Üð©O~è%ÖYH¦ü}Ä™Ån�Å} z)–eÇ¥\ú$ ;œ�¨[æ�ܲÝlØçš!õ:ˆ¸L<À ý-Ão½ƒb3Êv¬N�Ûôå�¨‡µ/NÈ ”%OÑ:G¬gÍ�;´3+tëÛ]³oø-—¾R¾IeQëb8…µšçÂjbRUêÖ6ânæH$ÍÆy¨P’tÈ`Ôw! d�L�#ØÂó�¥ÚnÀa‘|Iã*.gmX&ážÜ„{Í8p;¦j£B_“S“ �•w>Ý‹R&ĵ7ô£±Ðº»9ĦI‡Æˆ¤�Ýðð‹ºšn I®Lm,¬ÆÀî Q'øéeŸÑ÷’°Wc!$ÏOî¡�Ìž (] ÌP¨C ôï4Âu] %ö(�¡ã.0S̾}9n#\ÕÒ›yËËú©³.¯áG}5§ÒŠmËŽÜdÌ` húÍe;:¼fN@NÕÓ ¯•kòQ \D›N]5Πÿuׄ"Å :¼©.Á;\X³ Ô—´ÐJÁ³‡5SkÃRÎpPĆUÀ—”ŽDœ`Äç‰R €™{Öð.º´èBAl%ºÎ.NFÏà "D6dr ¤7Ä9P„fø¼�÷Fª‰Gû‘ ÊBF nJ-;ßA²ÓÑ~?¥Å[§§ò‡m ÚdB 8ù%?ð·žçÙ•A?pÏØ—–hchšpœ´åÛÐf7Aíôã-ý §�ºãÉÚ×ë`NÜ>ºù�“�\J"&¢ƒÊšÈ‘ó´ÅV0yTN[j'|[°¹8ϰˆò"Èl�·…Q"�Ø>ÎuO‰à,ãÜS�Ý¡qv·ã2å6a­L :ãÉþä ã‡çÁ-úGN`ß”‰çH°KSTE&šrö9Ž>EÓRÜ”Z¿N4µ +>Õ˜…ËÎ06wÌv4øœ‹ `/J¨u-\b¿`üÓ�20Z%ÒgyïùÊÅÇ„jjJ#�-748JF*GY ¾ïû°¶pΡK]]]u:Ðf&  AA:¿©BH†Ãá0Ë2)ååååùù¹VÒ)ÒÒh…™³··×h4à<õùùcŒ1†îEäÃôéä]…ʚ眗Í–Â0ìv» ãk^æ&£¦ÖVw¯Ýn3ÆJ'GGG§§§aRJákîkWD-Ïs!¥´Z­–…Öl6÷÷÷ûýþùù¹ÖZ†´BÌ­Q§ÓY]]�¢*ãææ¦ßï?>>îìì4›Í$IB¥x_»:Œ1yžk­á~€”‚ªmâ8BŒÇc!BÈûc¾ïcnnn|ßߨØ‚ Z­¦iŠªT*ß&H&)e’$€eŒ¡”Z–U&Ay¹*¥„è,ËcKKKÐNkµ¥´ì±ß¼ía§mÛ¶mB<ÏËóÑiž:‡5@.“Éܬ”Ú¬TJ]ä€S@MD< | ì(—Ë?ºùâbï ôààà 1æ ­õuATŒ1[µÖk�¿µÖCJ©ëEdLDš"’RJmÍçó«EdÜ÷}ß�xg Q*•V)¥î Ãp¢V«íÉårÍ ´Rêû………�1ÏóîRJ¯×ëÛS©Ô0 E¤�ÍfŸßáByÚѼ�Xã#à!÷þðVbü©™™™]�Fc¥RÙ½¸¸xDDŽj­/QJmèëë{Ùó8à‰ÈÕjµÒl6_ò<ï€z½þ|<˜rÇ€•î=‚xxØìŠØ}v … cLÖó¼ñ©©©É���;Òéô‹J©iA°¿Ñh¼�ÉdÖxž÷€ˆÔ�“årùÉCJÅ~j‘¦�-À`(«�¿ …¥ƘaWa«Õ ”Ré0 [Ƙ­uZD‚F£ñÉìììon=?•è¯ÀºD\N9¨1|LT«Õ#ÀD.—+¦Óé7GZ­–‘ÚÜÜÜ"¶‰½$¼ìŠÙâgà^` »}€gºI¿ÀéÈÆ)žâ§?ëâsVÒ¢Sj7:}Ș€mË 1нx†:øÞr:.W,'DÓ�¬oãwp ð0p-°ÊÙ·�Ïa3UîÖbË~ÛWÊ@¸øx¬Ø-¹½ Äð•ƒü¸ÛÙw¯Ïb{É�Kc«ài·[ÚÛ€[�O±¾�}[ï›Û€.sNƒ½_~‰=% [â?c3Ób 讎يÀ0°Ï}ïÃf«�˜&ôql‰t*66\Ô ¢ |‰½¤"Ùû°‡ów`S"FR·“h,Ô:A|žøŽoE$`«D°iÎbÿ¬¬èácÞìÖ-A|�Í@$;[»‡+€=‰`ïc_x{HDZá ·ÈI`{ÞÄ6»Ñx°îy?sÛ™?IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/icons/nx_tomo_metadata_viewer.svg0000644000175000017500000005417214757047403032314 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/icons/radiosstack.png0000644000175000017500000000522014757047403027672 0ustar00paynopayno‰PNG  IHDREIkOëRsBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î< IDATxœíœy�UÅÆß}of˜6YÊ&DVY‚â‚(bÜ5 H¡F“.¸ &¥E’r©! Z&ZQ‹Ò¸¯ÄÄ+Bˆ"ÄS¨ ‚¢Š80 óNþè¾Ìóqß:‹cê}USýºût÷¹ß=}út÷­‘™Ñ\ © 8 8ÓÌ&UzÄ%½t¾ö%@̧›�·�{Ílec)!©°èïÇ]!Ó8XhfÛK¼¥ Ìÿý (¾œ ¼$€Ù€ÌŒÆøz{ž�¨¿Ï×ý±±tÿÏÍ? ÀJ3ûÂ̶˜ÙsÀ1ÀûÀÀ´F|9ë�>ûy„H¨ãšÆÒ!DàÚìöeUÉfV Üá³S$©õÙ“®ÂÌn2³q|€ý–u–õÐáÛiôkT�2ÀÌ¢,¨ÁäXÖÖ§ àƒl�JŠç£„¤6’ZYÛIªÌA¦]>:øñ÷CQ–2Ƨ¿7³i:î+i–¤W€Ý’–Jê’A‘¸¤$½lvàœiª\ é[’®�4x#M�%=.é=àŸ@µ¤·$E.í’ZIú�¤­À`�¤5’ú'{÷jÜ:7©,nöåÿZE¬ 1`*Î9úòm–¦Yi+�Ÿ€ÎÀXàCRV #ð$ð©¯{9¢¿ã�­À#@{_6XìÛÌ‚$yÏãÂ�C’úØœEÊï€IÀ/¼âŸyåKÓ<àDßnNRY+`§/œ"0n N‹èë¢TR’ê&ùºRÊ[ïmRêºâ,Ѐ%•‡!È’ù[�)Q¤Ì®^õùO�Nâ‹^ÀÓÀ ”ò¹¾ýy)åKýXm"ú—�”ÑiH¹Þ—ß�F¿›|ýçø8 gÍæ-eh Á£|ÊßÍì.\¸ý ÐÎ[O$Ìì¿f6ÞÌÞ Ë$µñÙ’¤ò®À`M+I"MùpŸ{,òikàP¯óà_8–JºER¹™í6³­Q¤ànÅY ÀxIc3i,©LÒXI�-#ÄNöéöL}å‰>Ý•¦þ?I¿{&ý>ø PÌVK:¢WŸý0³9À3>{¯¤CRe$•Jºç'Ž®1³1D¯±åê‹->M?íjýïýÖdfUfv.nZ®ºÏIš˜‘�«pÓ¨ð¸¤Ô63pózŽ™Ýlf™¬`•O»K”A®<½B„äNSß ÷2ª€÷R+Í쯸•jnUúeò†s?žÒh ®õ£pKt2Fùt]¥’ÇX�[)Ì’T’"ŽÝ>¢Ÿ°.µÍÀ>àDI£8ßöé, ×ci’¤sB3ÛMÝsÕ„^·‚º]òi¼øƒ¾¾˜œT~¿/\†{+¼„‹ˆK½üw’ÆZœ�#~ƒ/ÿèšfé_¡Û¯}Ý* cRy{ÜñÇ«@IRùU¸˜¨mDÿwÜü9IÑÕÀt gÊÀeÀí¸M›á£ëq«Ì»Ií·àbŠÃ�_¶ E©ó© ÌËÝ \êóûpr´a·oúº=ÀÝÀI)ú]Š[v÷Oà,¨ ¸(O‘æûÚ ü ‡mÂ…eNóJíòÊT•Àë~ê| ’Ê�N8Sff/Iªð `®™íñ²‡yÒ^ M7©ŸŽÀ žì¿™Ùg’:ãæ÷s»s$•§ú¬öò•À‡fövJŸ•À@ÜŠô1ðš_E€¤þ8 íéû^nfË¡.˜i0Hšœ\•ªô×€¤Þ’î—ÔÇÇ#qVÐ, ©“¤n¹îœÃ•ap n~ÕË|:<£TÓâÇÀF\9#’2çx.�4°ž ,÷éqõì§!Ñçs�#Wâ"Wáª^ÆíSzKêPϾ Ý}º!áäÀ*´–±’†:º™UQ·ßh.S¨0Rü.÷iÆZš�_‘Ôw]c¸[‰¬HÝÇLÇ™þhIGÕC—�”æàWºá^ôæ0~ʆ/‘âãŠ?øì´z(:Û£ò=Änäåd!úè ´–³$Sˆf¶·³®À�Û~•ÈËŸ@)f¶wP õó-Íei®?)3p»áÓ%ê,›‹³m�éža>á³…ZË×ÖRÒÞ¼½q»fF¤“Ëо‚º£ƒƒómßPÀZ¯Ã�\Ûd:¸^ <æ³y[‹™íÂÝÁWd-þ*´›Ïæ<}²-—?.N–4ÒÌ–ä©×2ÜaöpÜ­!G�ˆO:läÙWNxÿ=[þâóµáKì„;ÙafŸåÚGFRÌl�¤Gp;èé¸s’|° ¸–$K‘|÷²àÚÛî+)x+‘ �ήØ©“Û¼ÙÖQ€“…,W3q¾aTšƒáL�íþ{6†L™|C<ÝÉ{½qñäX—#Ž‹ýÖgów²ä@й/ŒöÙ¼|‹™mÀB—ሠúebï~ŠeiZ0‚~pµNì;XgR )¹|RÜLFJ:wh�+^ÎÁ�Ä}úæk¬3¼fU–6õÆÞê /$zùì‡~c^gdDÖ3Úᣂù§œøìœÚƒÞXa•]ºkÏE—Ç>y½•ÖOY7XK&Z-^�hÓg€¾8rx°³KÕ´h‘ö^¸Añäýµí×½cå£Ï¶ ìziQÂÍO Îra—ÝRºì»rj¬ë˜ Žï½—M­lû6ëÄàÊ©™gÁSÔrÑå1/HPõ9å ç%ÊWl*¥Q¿šKÂÜ'Ýmé%×ÅÚ5"h×¢’�ÍÏþ>rq´Tm‡gç$8ïbGœkÙ´1û-ÀÇL½¼†X >ÞdMBÈkËTï„68»ö»ªsoŸ)­ÛB¯>bÞ3µÄbޤõk³“Òg€yj@¿œ’Ô ÏF¾¸ð”¶oƒxž~8ÁòÅ¹ÏØœH8mLÀô;â”–¹üGÛsøîyÆ�qZ¶r¿÷îÍY¯z¡ß €uï8JËàÑÙµŒ:#çGÍ�€ñb\wSɽ�¥ ³³ß±³8ú7LEÖïmÛAë6nžîª†³ÆÄòò"àÚcL¸:FE%¬Xž›IÞóT ßì+º÷j" ””º´¢®»)¿°(oRfÞgü„oý;·+×Ê–0îû1öÕ2Zahßѽ€®=´ÿw®(øütæ]qº»6» ÇÕ?‰QÖ¢ÐÑòÇÈÓV½‘àÖûòÄ‚,%ÄÄ)¹›e<—þ°Ñ¢û0üDÑ¡“v\þ�X/RòE¼ Ïõû®¼}Iˆ&%¥)Ѿ£÷½") ^`°øMJ¡(’�")(’�")(’�")(’�")(’�")(’�")(’�")(’�")(’�")(’�¬—kß¶ùžR³©)”ilTï AÝÿžJ‹ÿy–±Ö±IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/icons/radiosstack.svg0000644000175000017500000000470214757047403027711 0ustar00paynopayno image/svg+xml Radios ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/icons/sampleMoved.png0000644000175000017500000000240114757047403027635 0ustar00paynopayno‰PNG  IHDRG=ÿ t¸sBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î<~IDATxœÝ›[¨UÇ_ž“·|Ñó"¡á‚Hâ{¦õEOÑ©„²ÒçêÁŒcè1/õbØR¢Ä—BL‚^,ŠÑEÑ ´ x.¶·òïa͖ݰ÷왵fØkö›=³¾o}ëÇ̬™o­e€ðÓ½’~ó´ýŸÌl>0-É7–^þ‡�·€’~ÉkwGÁxhðƒ™m7³ÅøØ\0³ÏÌìÁ¼†ò,Ë$QVÆ¿Mà8°˜U‚_Îuˆÿð`¶ÑÀYÑ¡�ËÀÛ¸[Ø×ï£=úqx˜“¶5*|æ˜ÙýÀ0ÐH•ÛÿKj˜Ùp˜ÕÁ•€¯�CÀ1I�¼AšÙ`mŽªW�½À>I×Ú®äÊ& øk·rÖ; ¬ÊÑþz�~Mû€åUÃét¯—U¦�×È~fœðÿ}¥·€™îÖº˜�ü¦Ël܈u’ì´ üŒŸJšÌhw p6OGºèIˆç�ü@—vf€Ï“`ï*àïH@ß~&yöÅç` ȱ¢@Ú|-Ã]e¾}Û¬X†r`0™y Xèo< _� ëCÄ¡&°XÒõPGf6<àb·¤@p$](ÑÝ`ž§íuÜ0ÄómUŠ’Ø\�ôOëÏ@ÁžzÚ6€÷Ú œ$-ñj€‹#’®´8¸Qn‰§­€wÓNòþF€‹ã’Χ`°2Àþ�NζÛo$}×éDíá˜Ù:`4ÀÅŽn'jØ`{VÒÉn'k ÇÌV\ìÌ:Yk8¸ÊɪP[8f¶”$!å©1I·²*Ô°ÿç«À½*ÕŽ™-ž p±GÒL¯Jµ„¼ŒZbx?OÅÚÁ1³yÀK.Jú;OÅÚÁÁÝN‹†ÑÃ1³•¸%p¾*4Bµ+z8„¥%.û653[‚›rñÕ˜¤›¾ÆQÃÁMÒ {Ú^Ã-�óV´pÌl!nz×Wã’¦CbˆnAÀ|OÛ)ÜÊÐ E 'IKl pqHÒ_¡qD ·øhÄÓ¶PZ"KÑÁ)!-qTÒ¥2b‰ðnÁ£� §%²#œ�´Ä—’&Ê $*8fö°&ÀEá´D–¢‚CØæiI§K‹„ˆà˜ÙZÜF_y¥%² Â’YÀWeÒRpÌlnל¯vªµ¿DExÿ´Ä%àh‰±ÜVßá˜Ùݸ ª¾Ú%©YV<íê;܋ۇ¸-ŒEõ'nkc%ê;I¿Kz7Y÷&.“W{%MU™Sß·¥¶Í6ãväeµ?ŒTC«ôýÊIKÒŒ¤ýÀ}Àã@·ù¦ÃjÛÅ[Y<ž¥’+§ËÕ4ŠÛÊØÚ=ÜÝ!àO¨Áɤ¼’ô-ð˜™-Ç啇$]¬ºÝÿû¦<³¹ÜIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/icons/sampleMoved.svg0000644000175000017500000000231414757047403027653 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/icons/sinogramviewer.png0000644000175000017500000040604014757047403030431 0ustar00paynopayno‰PNG  IHDRÝÍóáÝisBIT|dˆtEXtSoftwaregnome-screenshotï¿> IDATxœì½Ûv¹Ž´KÙ’½ªûï÷Ò^]ÖÁÚkCŽù)ä”KU> ÆÐPÎÌ$ žÁȼYk=¯Á`0 ƒÁ`ðn¸ý§ü5ø×¿þµÖZë�?þXÿó?ÿ³ÖZëþçÖÿ÷¯µÖú¯ÿú¯µÖZÏÏÿYc}ýúu}ùòe­µÖ—/_ÖÃÃÃZk­ÇÇÇõøøøòÎׯ_×ÍÍÍZk­�?®»»»µÖZŸ>}zIó¿ÿû¿_þ*­zïææf}ýúõ"íº_ñòw÷ìÇëöööEž�?¾ÜÿðáÃËû„Æ­ï1-‡’­µžžž.òñüüüê·–�>Kye¹(JÖ>\ä5å½þ>|x•WW/ÏÏÏëéééå™^§¼¦ÿÌS¥_2~üø1Ê«Ðv÷áÇ—øU¶”V…¯²b¹ÝÞÞZØþTV×>+îOŸ>­µþÓ?þüòûööö¥Ý:h»Ñkm÷uÿññqÝß߯§§§—÷´¾ê~½¯y×¼j|æË—/ëßÿþ÷EšNª[mŸ777/õõñãÇ—wžŸŸ×ýýýËX£õ÷õë×WãN*“ºÖ4KÎ’õñññ%� Wiº>Yr§z­tˆTî·k›l{ÏÏÏöY…Ñ>¦×wä~Ý�‰úëÅ•ñׯ__õÓ”?E…[ërNÒ:®x]ûd½hßÕòúúõ뺿¿_k­õðð°þüóϵÖZÿû¿ÿ»þïÿþoýïÿþïZk½¼CYu<ûðáÃúôéÓúüùóZëõ¸Uy¸¿¿_þùçú÷¿ÿý’–ÎÅ•Vj§ƒŸ£tÿÐIáîîîbâÿã�?^®U®�j­õj@¬Aäñññbâ¿»»{Qîîî^—ýë_ëÿý¿ÿ÷¢ìÿñÇGJ7ÿë`œ”1æU¼N™Ó´U9(e” r©Ê'/ŽÊ«ô%¯æßÅE•ÊSz–¼Ÿ&pNdN¹cxÍ‹æƒåK¥WåsåðñãÇ Å˜Êóã”ët}{{ËKe*åÎÕóVíþ�?þXÿõ_ÿeû‹ƒSJ´ï©Âõðð°þïÿþïe¢NÊO…ãb­®“Ò­q?==½”÷®}êuå[徿¿¿P j|¡ÜÕo´ïèµöy £ŠöÃÃ�»þw |ý_éh;îúQåŸq§tºŸ›œÒìdª{‰ è”n�Oú^µ9�ƒÊ°^»q�QíäáááEÕ¶Z 8Çæ‚+­›Š£ÚúýýýEŸxxxxéÏŒËÍUµè®~~{{{1êñññÑŽÙ÷(Ý¿&FéþÀÁË)¢nðvƒ®€»t5�nMèXÞŠ;ÉÄI€ƒ•*j]N–Äêž<£ì|¶c·Ýäžò_ùsYZP0î:-*RxÊïXáRžwJNɾַI²&ÚûûûWÊvÉ@%Þɰ›èNúÇÇÇÇ‹6Xyøøñcl3iBwýU™@¾c,+~Êsww÷ja£yè¬N‰(v»Ê„l¤+Ó4èÿ’G°‡‡‡¥[ëâññ1ö·t­Êa•½ÖEÇ,k?ïXk½Ö0š×Ô/SÚNÅi›×¼k¾S»Ý¥áƲTŽ,33®aå ZwïN¶.¿i K‹¤’£îq!¢ï�²ýkcoÛ ƒÁ`0 ß…aº$vŒìóÎeÂÅ«ÿ+Aó«‚ì@ç’Ð1'NeÞ\Z‹r‚ÄïÞ×´”%tq°^Nå!ÔlžÜ•–+;úñ³ÿÕ{ô5zzz‘»3«“éÖ:¯ptó`�±\5ý]2&ÿõûûû ÷eÁ;†˜õïê�ã ™éŽõN,¨csë?Ù|ÍÃ5ìµëÃ]¿vyrïº0é��¥RÇ­Ä@ŸÊøËÌ17Í-»9éäž“ÇY‡Ýþ}0J÷/€¤hwJwR¬’’Õ=s›ôÒÄÚa§è¹÷k0U9µ�9y7)i:N†4`ê„NSqAãuåØ!)Š¿iýíLŸ» ¡”,—ÖÝÝÝ+?J·™O+õÕ­�NÎ?Wå*…>)6ɇ¾S6»ž“[•B•�nô›ÕxÓ2nVsý¨È8·†’Më_}Ó¹¨`xÖmÉWnÚwª-i%Ÿî1©ûªÐ» —���/‹±r!Iû4îStJ‘ËÛX·¨(°ÏëÂ4¹QiXÆ×-è»q^ã#’{^Zk»EåÉ"€cç®L]~]\lƒŒãTéNé»´wq�þ{aÜKƒÁ`0 ƒwÆ0Ý?9œY=¶Öåj;±™dK#L†‡ï){è˜D2�{ 7”íXÇtw&`—oþþ+ØeõÈpWdN®aæ Ž™"㤬¬–U1´»¼S.ºŽ¨K 74º¼”ÕÍÍŽÔ¸•å¯t¾|ùòªLx\¢¦¥ÿÈx²�¨|ÊLëx”Ú ¯i�T‹�¶…daKyIl¯æÃ…鬉®¿¹±2õË4‡0>–·cõ¹©2!¹LV?v›¬»ðÝÜбð‰Õï˜îÁ¯�QºpïήNfúÔéÓ`LÓònâwH �ÊC_dÈ’òDiwbÆÎÜ©×t3HèÑnb¤ùýDYHá©(¬•O�à ¾–IVgþ]«?¶�îz´œžc«ÊS:rŒùay½eÁâ  ¤ƒÊÀþ•ÜKxrˆ¶÷ºæñz<Ç:É’òÍzqåXòÔ¢`­u¡ð2lÝSßí’q­^‰HŠ••ú…ëI-zœaů ÷ÉE!õùjƒ:éño'® l�<õEßÓ<±ÿ_³xØ)ßš†Kã`R>©„&‚¦+Ž9Úžô˜OŽ ×€ò²wùuèæ·—ûÍ0ƒ_ã^2 ƒÁ`0¼3†éþÉÁ“CÜGT t#pæ-…c4šèNãkÛ„d¾%#­Ï{¬2uƒî4÷^Çl$“}—çŽårq(D0™Á�és'OµÁ�É–¦æÛÛÛ ÆT7 ò„ e‚ɪ׿)mØd¹9+JjϼÖ÷´]Ë]yJÀ ¬777gM+Ó�¾ ™ÚÿódŒ‚Þ+95¾’‡.Ÿžž.ÎàvòtV/Ž'j9c(¾|ùrQ<Ñ%¡cŒ;7‚J'õS×~ô·c·µ¾»¯]ºq‹i»tÞÊ–îæƒîZ YVÚ5.'7Ùëççç‹ò*ë]‰®‘Û•]76tè˜n—?7Æî¬iƒ_£tÿä¨Aà âz¬71ñT uÐ<èGNîïï-+«Ö wôŸZ:’å%•ï)œÊ‡2°ŒËèäqåúôôtá¾ñáÇ ”ÊrZÿš·b¦ïîî.êYMñtÒñãëׯ/.@‰]uý Y–ê¾ZGª´LÔíHÝH”éÞ¹\ì˜n—g�pï§þBë]’Á•ÝNÆd5ªr©û'ñÈðòYœ¼®¬Ü{»û]Y±]3Î}ìGÉ’§q³þ g�`9¸|Ž]¦û÷Ä(Ý?)’‰M�n£™—JNgJMiv>ÝiB¾Vq`*Sªð¸cψΜ|29¸øÜ{;…^ïw¼*~o5]Ös}§è9ñ8E‰ænº|¸ ôùùÒ‡ûùùÙžÇ�ŽîâĪqŸ~b>•¶‡Ô¶xªH: NÓåä®_—T¹N&`-› S÷xºÛ£sÒ1ƒí$¹E0]çÂÁ4ëUŒÔ¥$}ÒÝ� “dÙ-D;…ç-Š�SúÝ©0Zÿ»”ô>Q-׊_ÇÁ�2ìL– ÝlÞ:꽓²e{va´�VÛÒ9ɹBéo.–k^\ËqUËXÑ-ü4ÍSe”îßã^2 ƒÁ`0¼3†éþI¡lŠšŠkµÖ·}úª]AÙ®îÓFÊ‚²õ^bJ:f2™+îÄ vŒŒÆ­ìbb3É$1�ôa¡dîvñïd¦yÙ=?½ßÝ# {sssÑžÜi*›;©£âûòå˃É/+&y î¬igm©g»öä°�u"�| ò•<ɽDÍݶS _`ýë9íÚÇjœr§”¨ d~w.%FÓúÞó‘ûœÎŠ?aדUAãg8Z4OòæäIVP–q]w²ïpÂY˜Ò«Ö±dåÕ0”•×Î%…2ÑzãàÊ££»ycðëb”îŸ4aÞÞÞ®»»»µVxjpIæEE躢p —m ·Ëk7yñ„†.œ “?•¯´�BN9OóÞ™r�Ï»+÷nÑ”wÞ§«ˆóµÖ<ðþÓÓÓËéÚæJáJ“¸ÊÃü¤8NMßî>n>c=+œoûîÈŠãþþþŸšõžÃzͲSå–®&®Ï«Ük­‹… [Xö\œïvÅýüü|ñ�§ð¨Û‰+�¤èŸ´…’¡ÿv舄Ô&© ;× ‚[hSáÓ±‹äJj·é™#`’Ò͹e×V+n\LõZé¸qUÛIÅíN3âq¤Št: ¿pšÆlæç‡Qº/ŒÒý‚JY+§t×D–<Æ_Ð B• 2:Ý`êâæD“ǺvǨé}Çr¦ÉOã9Yp�åÿ4ñpÂréìšNgYp5'c–rTûq pÆUÖ—/_.ü$éÃ�âvÊTÅí{n!r2yQëÞ©÷4*ÚÎß¼ íF™ÛŠŸ¬¨*]Ûàp¢ì'LÖ7i—^yÑv£ mš¾žõÍg´$¦Ò•AÊ;Ë â½VÉI D¶Ûn\Ó{?\?pá\Z‰5¥Â«òpÀgN~í/»½4'å@öXã¦bìP㞎Iܬï:YXºÔöu²WçÚvµ›C¿&Ƨ{0 ƒÁ`0xg Óý‚~¤Ê@%¤X¥Ýé% ²4åñäˆÄ¶h<‰%Ú±=Îe"ùwwŒ·cZwŒ¸3�&–âû­p Pr³Ñ0‰ív®BOÅÍã5žûûû—SJÔL«>¼Î”î˜;mg® Ý *õ;ÿÕ±J‰�T6—Œ¶“Áå�V€µ^ïyøðáà û«,1û„¶oÊàÜ1h%R&¯êj­Ëz­òqL7YoÍ»º”hÙ‘Á¦µMËÇ�Ñ�m´cDOŽ…»†mtÖŸŠ#1ÅŠÄt»4Ndq¬¾ß”Õí\Oܵëvã-~»|èµó_g^4dºu JåMK�¶UM/Y Ø/Sž†ÉFéþ ¡JR)ÝnSÔZߦÇÇÇWS7Õó¤h«’TR¨;¤Uïñ�d"MJ»þÞ¹$ÜM\.TxvyUÇ!™�¹yªpê2³Ö7¥E7ñU·ÐJ²Ö†8�°Ô…€“’+U^\›K‹8âÔ”î�Stc`Ûgz†J�†çâ—ÊóÂ<¦t5�%§¶ý?ÿüó噞çÏ4U™Öý"ê6”6m×XSï•ûJ-üÝb‘ÇÔ9Y4ÿõŸc�S>¯QúÒ˜¨iqü%Ò"ÎýæýTçÕ®ÙøÉòcߨ-øë­ó_ï\0ºqÀ…×öÉüÓí#)Ýú¾ŽcÜTËk7–þU ôé9øµ0î%ƒÁ`0 ƒÁ;c˜îŸµÒv››Ò·´9)1,4Ñ+›ÑvÊ¢0=÷;±ÊüMS*wó'æ<�XÑ™ “Éž2uùrï¿å†ÊwÇvºüèoe:•I®k·IOÝnnn.N¡x~~¾`–N6‘=Ôk èÿ´�”qÓ”NT|êÞ ÷ Ü1Üzß¹Ö�±Ô|(‹šâ®~èØ{­£*Óz¯N”Yk­OŸ>]äUÙl̓ž^rwwOwÐãÿØ”'[ÚYÇN\(Kbº]û¹´¾¸}Nû¥{O¬Sé=–a7†8T™8+O7gÐtjMè~»|pœ «–+eº?~üxÑÙ÷ÒÑ„§îN‰縕0L÷ï…Qº"œ(Ýœô;¥»Sô~r)áä¬áO¬'àÄêç ¨á)gRŒ5M“ ݵH¦Ôd®{T6�r²3WÓ'·Þá{NÁÐö¤Ç½­õúë‡)}æÓ]»ó®5¬sp®\p0L]§:t L‚õ§uDL…)U4¬Êàú®+ÇÊ[ùo«ù�'–h^yJQ-Î>}úôr¿Ü‰\Ù©ï8�,Ôg§Šó—Þ¡ ]ÿOi§öªe侯«ùsí�uv’w×/]ÜŒ/úŒ.NÄnoó¤ã¥¾Ç1j7>¥°nÁËóþ¹`U—KÊì”pæGÛ7]ðÞ²0ì0Š÷ïƒq/ ƒÁ`0 ÞÃtÿDàæÉµÖË&Je•mK¦ÝkX&÷J²ÜduvñVdó’ ;Y•a*†1í~¯ü<>>¾’[•Äö$sç5lýµ #¯ M:±†øøñã‹«€Æ¥'fÔ3e�µŒ‹5Uš§+[e­q;‹'™¸²($pbÔô~1Y‰¥<ÚVµÎ5]ÝHìÄʤ}–®]´®ì˜µ‡‡‡õøø]Ï´ ³_ë&Ëj3üñÇ…Eíþþþb“šÆMv»äN츫/מ˜Ž9έÉ�{'fÿB•Or§c>Ü8è¬e×Îâç˜U>s¿S?`š�Ü).ÞÓñ¨³$$&ÿ”íMeÅ1Ò}©’}OÇ1çfBW˷µ™a·OŒÒýÁÝuwwOàaÿiÕÉÝ™å�¿)MÒ�¹óÄ”KŃÂάJ%BãH)…Ù üj~í”*˜Š“…'! —òÚ•5Ó×2Q÷]|¸ÉÀ)˜úÑ›¯_¿^|Åp­K3®S’*Þ¤\'¥ædb®zt2Ë8õ .¦’{‰º�°¿9™+>·@d¾¨°:9Ãh]ª;G¹�¸“tQ©§ÍTTÝÝݽøëÓ) ®½k>é‚”ˆNAq'è¸ÓJRŸ;ƒø]¬v§ÊTs‹‚$ÃnÞ�!®ŒÙ~Ò{�¢ÏzéÊÔ-8¦¦ë„Ž8Ðð5Fkpcˆ’R\¸ÒÝ)åûééÉÖ?Üï.¿ƒßã^2 ƒÁ`0¼3†éþIpssóÊ¥¤®»O¿ƒE€Äë;4«’™$S’˜½Ö¸OÌ‹4jü|_Ù‹S`¥ïÊÇÇÇÈ`Ÿ°�Üéšaô·«;Çœ’•­ëb¹•ýwndÉ_N½PS,ͲŒ[ë¹Ò©÷ÒÆÜŽIreäêMãsí„–E’­,%É,î\Jh%âI2d‰%V—²dIQvóáááb“¤>Ótµ=)ÛWéh9ÔXÃÓ]TV²žÎÀ÷v.'$ƛƆ°OjÙsC¯“…i§q¨c?;•÷vؽ«å{bpñïÂUýï,Wd™9'éûÚ§Ø—´­«ÅAÝ¥tÌ×ñ€›~9Æ&w¾“ùà„ñü¥û'�N~ê›[®%Név~· ÉD~ê ÿï© Ù…á¤•ÌòŠ�¯n2—&ó»[ÐÌYáO&¬ÎÜzbV%R~>~üøâPõ¥fV§tßÜÜ\¸Ð¥¤:—W-?~qq­K?áJWåq‹@Æ‘òÍ{ƙܙfÉãœØÝ"¥âfxíWN«¶®§$t.\ M»|íëøF•)-2Ü;OOOëÓ§Oéò”†-¨‹‹[ø•"äü½)'ÛCZ`qÜJa4l×G5ßÉýªCŠ»S<ù°SòõžSPÝ¢’ ½veçȃ.Ÿî½n¼;]L¤±œ}ÌŽַz­c/Ý‚•m“‹8çZåòæúìn¡õ=‹ÅÁÏ…Qºð˜@2ÝÚiÕW³;J‘'ú2:&±ž¹É"±YT¢v‹ÊÙÝï”î4xS†·lš¹fr>Q¢�òÉç:Á([§uÉÏšk���/_.TkÉ®=¹‰Œ‹NDI©ìØM·rï;fVe¢²¡ÏTé®vÛY¾®óÖÉä”î�?¾b¬ë·nh¤‘”°Ô�t±TqTÜú9mÆ£Ênî qò¹rtLìnQšú™I÷ž¦IËK ò¸Viº†M‹©ÓÅ~§�뽎Iñí°‹/-’*7V›K‹`§t»ý=ZŽé8KOhY¦bí,v©=~?ŒO÷`0 ƒÁ`ðΦûG­ˆuv}g­×þ†ÓMÆÀ1¼ÏÏϯŽLìÏn7�fcMß1]¼NÌDg%Ô™ùcÓù…“õ:a¦xÿ”IruÄøÉèÐq­oÇLºº\ëCôðð°¾|ùrá»�Nû(¸úQVV¡òuùf:;swÉáØ?eÃØ†y*ˆ²UZ¾��¸†uœúï˜÷Š×} ˆ×…§§§õôôôâR¢ær5‘W»O¬®Ê ãÉZßN>©c5ëÚ¯æò¤å­>ý´�¹cÚ(/­o'm�áõ^ryHcãHèʹs5èÆ7½ÇqúÔu0!1ÛÚŽ]ý8YïµcŸcñOÞc¹6£ï¤ýOšîZ~¬«ß<�¥�ïº7l÷`­Qºx¨?¬ÛHé÷58")¨úŒ ArèLƒ)MMÛ]ïdsïwŠZ·Øè&ˆ”nýæñqú}�u2=�$]˜JSÓ­ö .%tO¸»»‹uP ÜŸþyafu›‹Nàê©Ê„>¾õLßÛÕ­K�>™Ö¹¤ÐÝEB·Ps eH ”*ÜTè.™§U¶ûûû­BTïê{nÁÁ#Õôìí4N”¢Ÿ”U´uÆ}!š§ÝXàdÒºKî4Œ‹2§=+ s2NhØTyPÿ“¢Ý)‹'iº6蟻~™9¼—d`¼'㾎qz_Ç-]øÕ¹õZG]9º~Î6�pºhåû÷¸— ƒÁ`0 ïŒaºp¤ⸯD®•?ˆ³c)œ»„s/q¬à§'O¸ç;DA¦†Ì0ïïØçFÐ1`dÿOL¤gÇ$Ótªáô4Ö‘ZGèþ ñjãäÓÓÓzxxˆŒ¸†9Û=£ÛµGç àê¿ÂŸ´ Þw_så}‰MTùƒVa“è®]+—’µ^ŸP²ÛH§.!ÉZVÐã5ïéZË¡ Ì¢ždRùq.j ¸¦�ëu÷,õ¹Ä¼wîÌ/ßqr\Ãf¦~ÐÕ³ÓN­i”Oó@+ѵ¬·“Ó�—»“q’l Z�\˜ºVæ;¥™¬Êt»ù@åѸºwO-ƒŸ£tÿÀ¸¹éÏæ^ëõ§J7ÃÔ5•¶ÓdR¯g�âé&ˆdbMq$\™(v.1�IÓ½wª ¦ÉªSÔ5.UZÖºt)Q…§¾VZᙟR°þüóÏ …N<—ßt¯àN~Ð<œ¸f°]¸2¦¹=É¨Šž*˜OÛ Ê•âäT…¶A*äNFæ½ÒZëÒŸšï�.`Ÿžž.Ü�´,ôô")<íÁ)ÎOÚµ�äjäò’Ê‘‹8}ÆEÁŽ<èÀœ‚§Ï\:ÝxçÆh Ç÷õ·ó»Å§s‡`y'å0åa§LvJ|!�HâÒMcÛ\š¿(Ojûéˬ' Áºÿ–ÙàçǸ— ƒÁ`0 ïŒaº`¨{?ˆÃÓôÄ}´‹ IDATçà˜ Ç2Ðü«5éÊB† [Õ×µ27Ý&”ÄÊ»¼h9$Ù[âL‘N†ÄX3lÇwl”¾“L¤ü]§‘Ô}erëƒ8üЊÖóýýýË—&¿~½üè�²j]þÒo2žtßPKÌé 8ŠÄþQe3ÓGx*žµ.Yp­s¾Ç¶ÔYrÒi?‰åÒtÕô­ídÇ´³Î’{XJÇåCóRP9’ûÌÇ�/XAý�Xa¶U•#å{ÇrÜzK»£,epgB§4S^O˜à~çr•äúðáÃE9w7&vãi²øéØwb¹©1²ò—Úûe7§¹2((Óí,j=rc‘–)Û\’uðkc”î<&Ppu/Yër =ùø„Þ£ 1™ƒ“ÿc…WE#M~œvƒÍ©©YÓ*YT>5]wÊþ鄱Ã.oiÁÓå‰'Ù8…îÓ§OÖ¿{­o§^¬õ¥»&VýèIç7ÚMÉdëN×Q¥Õ} Gã¢ûÈnrNŠ_jßšÆZ+g˜ÚmjßÕÎv}Ç…/%øááÁú›»zHÊ�ŽO59Eçà2*�"ÂòÙ)œ©Í¨L=á‚í´[À¤<§ò>UèÙ/Ý^‹nÌÖëŽ�Hý…eÇñrwÍ:JùÛ��)'$…ÊîÒwcAçâ”d[ër\ÔýOOOö¤¦[}±dH ÎÁ¯�Qº@¨rµSºkÐq¾Ÿ¼8@QA¨´yíXB…Kçd KŠi’óL?±f§l—SŒNÉnâHŠcW&ÚT‰£DGMçË—//ì¶ZDœ÷Ž™ê¶! Ÿ6LRYѼ¥…$A\»u B-#Çð1ÍS MòÖ¼V™ê9éúå» Ã… óäŽD,¿m­«´Q’ò8…EÛ-t\L“¾¤L¯ò¦L¾cR]uÏ:Ë”Ö9û¨æ;ù"³=ó=çÎÁòaý騢mWËA™|º;°œÈØ»<$Kˤ;5CÁ¶zÂ`²mu.%úßÀõ7מ]¹2dÇÝ;Gгîu̾“¡›3øÌõù²ïƪ.nµ –%NßIí&Y*i5üÚ¥ûÍPé\]NPî ‚ÝWÞÒd£ƒ(²'ƒsÉQq§Á8™1Óäyf•©ËC2«v“ep÷y�ék[ ‚òùóçµÖåño,÷r'(…»”n~iRáS‡¤lðX>.�+�­d9©©˜²ª\Ø}g­oÌ�²‰ÝG&vLŽÛHéÞc\‰MTf­擹›ï$¶å{̱îÚ‡ך;OÌÁL[™[edŠåvmCYÓûûû—ÓJj³d:Ù&å·c¶T^ž¦âÚ`wbF²F8VÙ±°Õoëܹ$8vŒåãúB¥£ì:ÝIÛ®uTe¢¬³æÕ}Ô©žœå«þ?<<\0oîñññâÔ�7¹_‘qNùc=kú‰ÝdÜ»ßõ?Y KéÊóÔ¥$YNØÎR�»± î'Æ÷”�¾fœéäqyMÖÈ.nƣϺùÉÉÓ�÷´¨¤~αJ]½œÛ— ç,ƒÜì¬ùÓñV㺽½}õUé·Zs?FéþÁ huκvŸ~/…ûä˜@rnâ rÇ! €iøNñÕgi‚Jƒ}¦K‡×j*tÊž3iT6—V’É ²4O§£î>}útán¤Šèóóóű€åZPmäć²3³:S,}ÿ“¢í.·8ãB�mËùíîN%Hù£r˜Lö<=Äõ—››×'ti©Yd1]n¥œiqåòSuél§è»¸©¨k{äâØ•7ãNcØ©2�úkNûÇükÆÄ“16-Ðv ‘*^•¡ât–’küz^u©Ä–úws¡Ý�ç nž¬6õñãÇW–¥JëóçÏë_ÿú×…\ƒ_SÃÁ`0 ƒÁ;c˜î4ÙwÄq«}2݉))Ö‹'eÔõÎ|¿CÇ.wL™ó¡~k:|ϥ߽ëX¢$[—'2¹Î½¤\‹œ�¡2jÅr§ãÓ–Ìþš?šöKƧ>ÜÊðjyPnæ�eå,,U>Η\™ÍºvmW]ML†;ɰswxzzzñÝÖþż²4}ÓoÞ…aû¤»LÇB3%ÛIŸIL·ÆíÞI}L¿ªêÚŸ “Æ;-7ºßésm�···¶UÝ;ëÇXö�d½;±ˆ¥²ª÷NYÝݸ|—“áDîÝ»î='wj3;«JJ³~뾩OŸ>½¸špÜI²2Þ¯_¿¾œ$¥®"z’IY Õ�°˜î»»»õåË›‡Á¯�QºÿaðüíkÎæ^ëõ§•;óäZ¯�§s×nr©ßi2N›XNPNá= _×îÝNÑpŒ{7ùwÖ;ÝdQ×tI>¡ôáî\JêúÄ¥„P4•N§pN6lªÛ‡¶UÍ+å¤RC·*W&ô¹ÔpÌ“s¹ òÚùm³ì Ÿúb>??_|­NeuPÅσ¨‹Ío]kßqÊ­{OÁvšÚP§î”Ê®�¤…�»wÒ¶t!È2¡¬NgÞX&š?·ªp»1Í=ß)Ëî™k ×¢Sf¯‰»«gŽ¿Î}Cß/¤�¹IžÓÊÍÍÍ…;�ñK{7ܼÒU—’j“šŸ"TñÿüùóZk­ýë_ëßÿþ÷«0ƒ_ã^2 ƒÁ`0¼3†éþ‡ «Üä^Ð}GYÏt —²0dº5Ýä^â\ #“Xâ´ñM™»Žõ9avlvN𤋮‰±Óü9f+1§¬óµü—&K†úš_Ý×� °ìÃÇr Üd:�KIçÒ¢ï&ö—õB]Ë„Vg¦§uEˋ̴kƒL71ÝŽùu}ѵ1 ¨a i#óóó·�9–Ñõs–)ßsåáêĹ5¹p©­9ËûëRÓ©>áävn;Ü(Ìö™6¨±í»4Ý3Í_z¯û=­ÃŽ�>9Ö¹¸iM¤Õ¢câ]:l;§28‹‹Cê¿k}³"«{IY“K‘ÆË¼U9Üßß¿´cuq{||¼h�z‚Êüñ†ÇŒ~ ŒÒýÁ�JR ·;U„fU*?Ý T×irçù¤§;¨ÓdšÞc˜Îüš&wg†îÒfº§“¢B]MÜ„’|”éR⮹Ȣ’[J—*ô¡æäç&W¾u�ŸOçñ„î””îdŒ� Ú)ûµŸ¡äѲÒ8¹ê&Ótš ËË-†œÒí”\]Tt~õ���Öµ¦z´˜úS²$E«Sá6Žë™ÝþùçKøÁ¯ƒQºÿ¨¢M¥;}ú]'mý0Šós¾uÕ±OÜK8p¥É¢Ð½Çwõ^§Tœ*‘I‰H Á5p“ }�Ó¥dp+]Jz윚´ijL ÂiPùá)9®­ñk—twquAŸmºé⃟t×pÚ¦S¾S?PÐo»s5¡B }®@囋3í¿Î]¢âУ“"¢×é$}Vq9…'µ×÷5]]8$Péf?r}GëœfúnQ™âVÅ:-’‡[(¹k¢/O�iÁÚ¥u"ß[”ùJÃ-â\8}Ϲû¹ü;×¥käÝ•e7Nhý«{I)Þkýg|ªÅ0m\üºþrq¬º›é8ÁãÓ UƒŸ£tÿà&FÝH§>ÝdyLàZ^yMÊ"7†ìŽ ¤RÂÉ4)Û ã& 7ø)ºIèd`M8�Ü(›Öƒú@k¶õ‹ÊZ—›*õÁ»»»‹ý5Ú�µŠeòððpq~·ŽŸ:Ÿ|üøñŧûÓ§O/a†ñþu0>݃Á`0 ƒÁ;c˜î¿Î�ƒGÆuÄQ“ò/$ã¤i§4ÈtÓÄîVîdÁ™^rõÐwÛM“Ý Ã³cw“©™Hqpq©|k½vŸP’§s8–ñþþþ‚½ã±€)¯INÇ´©ISÙe‚4]•‡×ü8NýOìq¥»;ÓYJ\½¹:Jl0ã«ðΚÃðUZ&|ß]³/9¹¿|ùò*ïîã8»t«ÏëÎ}æ§Lwj·ú,¹¨8«…“�Àa~õ}2¬Œ«®¹W&•Án|sa˜¿¼5œ"õ^»6tÒÖ»çUç;&ÿææõq\Ü®Ý;†™íLÛRjûW±ÜênR.`ü0؉Å@O¢ªSªÔUKç�b×?þ|‘fW>ƒŸ£tÿ�HþÔ<§Ù™—u#�¯êÌoTô�»ý¸ÓFô‰éRßÛ)‹5ÌÉäs¢Œò^Š·sŸIeì6¤Ö{êJA…›>ÜîX¾� I*c�´žyL LÝ,TàFÊ.šTún»O» Ú½×µ}Æ‘ü©õžNünbíÎ!vyàFè‚ûºdMÈ�§¾°®“‡ñu~Î./õž3ͳLtÖ�ñ¹:§Â«õÒ¹¥Å°¾Ûõå´`qŠšËCʯóáÚIo7Ž¥¾éúËÉ3—n׿®QYg·‹?5N>'Çå”·^!X¾ÖÚµh÷ׯ_/”îäZScäZÿQºÿüóÏ—4çÜî_ã^2 ƒÁ`0¼3†éþ› +XeDÝ(Õ }˜Ä}œ¡~w,lÇÊVš¼NLPBÇZÒ¨L@w"‚c™\üIǨ¼õ=ÊEvs­oL²3ç¯u¹ÁFw¨ÓuèÄQaõ?Qò¸B”Ù.†7ÑÅã²T'«Þw›yÕÌx5¼š_“iœ÷»6­ï¹ü‘‰vG•9¨œL·˜.gEÑc"+î»»»WñÕ5O’q2\Ùî¬TdÈKn–q² ¤òVù\]è;®¼µýu_ùd:iÌpG®õŸ¶ª„›éòw‚ÄÖ2cÌëy’Ü»v¤nzüŸúQ²\кu"'ãIVÚÄö—;`mjüòåËÅq‚is9û¼>S÷Pks~¥«'™Tš���¯,dƒŸ£tÿMpŸ¶^ëRé¦ ÈZgG·éÿt ÍÝT~Nº„nÂÛAåwþâÉäÛ¥×™�ù;™!õ™SÚ:¥²ò ®œu'¼Ö1'ˆ©®’Y�uî&§t;…ƒ®é(>mëîÜyÝ·�òֵϤt�ºLQѦ²P߹7B']í¿ºp¬w´\µOÔØàò�Ú|§ä:8Åו�¶Í*],t>ЊÎ]¥ÞO‹!…ž}Ü)¿ît¦Ô·õ>ÏsOïQɽU÷Iù¼–Hi¸kÞ;}OQ2¥ÓGXv ³‹¿îŸ*ç»ø8¾r¼T|üøñ¥ÿ}þüù¥ ~þüÙždBùtŒÕtKéÖs»ÝQuƒ:=e\L~~Œ{É`0 ƒÁ`ðΦûoÀÍÍÍ«³¹Ó‡R” Tæ�æ[·™Ê¥KfÛ±Ž‰5##Ñ1-á‘ÝI,…cJ\ÜŽéÚ1.kåM?ŽÝ^«ÿ Jrª÷ôÌUuÒ/>²OØIBM¤lsÊ2ž0Ý<Þ±},e ui¹†¨EÙ�;ó½¦é6&óÔ½ !™¤KŽúÏòq.a”“æóÄþ“­M›ïÒó®-¥>Ër£eŠí¦ž¹ðÅè©ÅçÄ•!mÐÔòÕñÕå¯s_ÒruîEµé-±¶¬ók-ƒìG®�±�¨׸YèuúÝ]§8“ÜnOñœ0ÕŒ+¥—Â﬈*¯ž8¥gf;·�Š›îoÎ R–N=ÍJÇX�³•é¾»»{õm„ÁχQºÿPáagÖÎ÷–c×òJ¯S�‚˜ÌJ+¥Ã{o1ê@äN¨àïdÚíâæ@¬‹ *ÉÏ2MŠ–*›*Ù®^“Òt­éš‹.*D&?•‹ž³ž^Ǻð»~PL´cº;¾s)ÑvÑ�5íäy~þÏfKǺòNã†öe•™V•!Yk4½Ž…Mlw²`\ƒÄ¶k:U'®ÏïÆâ“q– '[’ÙÉ}*C’Gw–2mnS#¯w.Ÿlß:·;ˉÎ'dºuüü\¥ûAêÔ�yÌœSÎvÇ&xòé>9Ý¡âMÏœ©¯'¨Îìx¢xSâä’â£ïé®ì˜/n¢®øy2ÉZ¯¿ìx2ih¾*n7™ª¬ª˜Õûš®[ÐÕ"`g®Ö¶TiêÞ7™UýŸ(ôz/) Ì7•;…*Lüø�Sð˜®.f’›'ÂT_ì7å3Lùnoo_•y½“2m�;8© ï”s…Sº5¯š•R·¨ÐzУúêYRè96UÉ/žyI.\ôÍÕü©«‰ÆÁ¾¬u”ÚYR¸ùìTáv}7�‡ì‡iÑs"C3 ©�¹ß.ž�Hýß�¥Lãéé)*Þš&‰²ô¥J–cš;Õ}êáá!~™WçÕø�žÁσQºßꃙ6OR�[ë’¥¯íZç«;¦PÉ49wƒlR˜ø¾l¾nÒ%kJ…;å¯c·U‘ÕrÕÁXÃW:Z» {»I­{–Øm-¨/~}±S*�º®Í’ªètL•{ÖMÚÌŸé;ú['z*tWbÞ4|õ͇*Sœt]¾;¥[••¯Ž«ôT1×Åùnã%•Þzæuæ“ùP0¿n� ivãÅ_ñ™kÆçú/áWÌC…×ñWYô´ØgÜz¿{uqºxpãr7ºø:ëŒËÁ…ÏNV½î”r×_vùéÀ±&-†Ø.œuZðZt'¹™¾›çuóýZëÕü­é*i2øy0>݃Á`0 ƒÁ;c˜îw‚såP¦»v?ó(AžXâ|&;ƈlPM«‹ƒ÷²t9 “Òeþv,zǦ*«@LÇhÔ-«TŽt¥àõt¤Z’»s!IŒZw*�2IÚžôc&êúÂtdGóÃüéoÖ›²‡§,yúíîWœü0MbâÈ~1nÇ&òô“ŽåLÏ:†W­_Ú¶Øæ´^XŽ�LíÛY ’u+ÉͶڕé‰üZ‹™Z™øQ¦ÔÖ)+Ùúz¦Öž>Óå…–L}×±¿'¢.?Îj•�ÆÈN¦ÝÅ�~wÖÛ†Ö±ôLÃ^Ãúk\Úwèê±Öå\ÎD¥>O¹iÑÒ÷8—kºuí>Ð3øq1J÷;�›ê’’â>ûî”n:ªéy­×Ÿ~×tœÒ�̉D'à º¸;å;™5wî!U~»÷:—–©n~ÕA’'é+Íüì6�vfcç*àü¸×úÖ–Ê‚.%??ûwmŹ.ê~¡ïu‹W½§yåDÎ~éÂó~统üÏYç•fµ]P9å òíaÚ†uáx�rK— ½¢@uʂާµ¾“ÚÓI‹3}�ypõàÂt>Ý ·�aY±¿%Å;Ýï”×î¾_v8Ïç5}ñT†kºwuì;YðPùUÿnuÑp\ܱÿ*9ã\ŠjÜt.ªº~ðãcÜKƒÁ`0 ƒwÆ0Ý1;ªŒ6™ne¦vN©÷ Ü,¥÷Ü)Žõ¢ ùZæºVí»pŽIº–Ua˜ÎÅ$™KÉz¹S Ô=ÁÕ¥s)y~~½q2™O�‹E½—Ø8Ö¿Û<É0µYòééi=<<\0*‰E׸x’…Zkc�X"nÒK–²Œ‰�âN-ß·f \ IDATnÌs›Pëz·q)µ¿ÊÇ [«2°^”¹UÖ+±f<¾’e§í›ï¦~ÙY—˜í'uÄöàâ®÷ÒØPeRrï1n2Ó®ÏÒÕ„ñhûìNÎ…ש͸÷æDaK‹Ö_·˜Ò~yMš×7'ñuïéxé”ßRºynw…á¸ãÊ�+ÝEÝI&•öàÇŸ— ƒÁ`0 ïŒaºÿb8殘Rýxˆ2§…b&u¥œŒ´’ndh¯a‘*îäîpbò%œ ÁIú×2"i㤓Á¹”¤ûŽÅR–‚çª;¹OMô‰ÕêÜchª¤ÕÄ1Á”‘mWÏ”§É=É­ïÑ”îz}Ï™�][£Û ûK:£ë;®Ìk£Ò‰«�"Y†œ'1éÿk]j92ŒšÌµþ”¡KU>ÊNfù¤ Ÿ~x‰ñu–}§cåºÙ”mÈÉäòèÊÛY‰Ü¦º.î]rý`gQIŒøéÉ1®|Ü ''›óÓ¸³“Áµ‡Óy'µ÷Ë7Yš´Õøøõë×WËqî"U.Oú±ž�uSO/Ñëï=ï~ð¾¥û/D÷¥B휪t«)®&ÒÝW(UA!Ô‚®t-Ù Dlw“ZRN&”]\»AWóÃ/Ú%óp b�;NÝwõU2¤#é†àò¾[xh^é*àü;u çON `™P9£\]ÞˆRÒœß48¶u¥PÔDËòrÐûnU2pñ˾ؕóË´]Ù%庻¯nDÚn™_-;mÓªŒ¸PL 9Û‰ÖåÜ�ÀTáO•¦®nݸӽw²øw .>Ò»õŒeÒzï\{Ø'vmãTïÞKèÞO‹×/;ùRz'2%·¯Ê›Æâ$+ÝÕTáýôéÓÅ‚©íkzúŒ}™é똯D�ûRåàÇÄ(Ý!’Ò] ·2†:Yñ³ïélîºæ™ÆT$’_yRº‰Ë½›d*t]7àî”ý?I­ �StN•núK«"óüüüŠÝÖ÷4n�uòìÍ’Y'M·®;›?Ê�Ž“ë&µNy¨çº“éºEDýN ?æ')ÝT$õ¿*n?­©]nBß),Z¯*ãru®,.ÓÓ8hÍPYÒ§±]{æ©2•úG ãÊÛ=ï‚¶Sô]©xô=–7o 2.Ÿ,>ºòæ¸Õ¥·—]NÌ9ÛôɼÓ-¬Ò½nŒíÒ<™—ºùH�ñ+¶{­ÿìѹ¡«;7–ws‰‘j[µ©rïãÓ= ƒÁ`0¼3†éþ  +Ne~hþqÇêʖǺ‘]sÌT­šÕT¬l»ó×°‰!ê —˜\½¾Æ½âÄL¬L‚KÃÉS哨mšÝ5]uápŒcÇÈÐ×´ø^§øž¤Ù½wͽ´XH -77¥2ÖñM•îÏŸ?¯/_¾¬µ.÷×TŸJ.Q:–k:]{â¦J7¦ ~ Œ{É`0 ƒÁ`ðΦû;¡ ¤;±d­ÿšÏc•âæ-Ç`tìXŹ֥‹ Mùs’˜ Ž}qHÌ-ßéXÇ,)ËMfºcb¹ÑÔ¹)sç˜Dž âòE†]ï;�QSFŒ›g¹1'±Y‰Ñö¤L �–Llm‡bü*>Z;ºÖ¥ëBr ãØ!�Ü£éÑ�«àÚ㮼£Z¿S¾ë¾cÿ¸y2•eã=×;®} à޽ëØëdYb>X^ìo;F´³RûÙ�EŽ¥Þ±®'lµÞ£{a׎OÚzgmé6ïú�ûaçZå~Ÿ¦yÂä§´:¹5þúbqÓg)Ͳé*‹õæ©"i\¥Õ2Y–´Té‰Sãfòãa”îï}‚麰ַϾ;?YUºKpæåtòHuÌîÄ’JSÃ)’R[Ïvk7ŸšOw2jºîÓË]šz� #ºV¤Sè?½sçprh9¹kæI•áJ«þÓ\é–µš¾9PóD�ÝDF¹]Z7ݪR=»öͶ¥uÑ!™ðonn.¹ìo<l­×uìN¦©ÿ¼¯iÓ'[ßqùs~Ü N†®ïQNýt¼’Ý"‡ŠÑÎeBÛŸun1©L]úÝøâ�”®4î1Þ]y»ÅŒ¦YŠëɉE�‚Ù)ÖÝ‚ÌåëdAGyv ø[|Æ‘äÞ…aÒ"ðyR::®ªÒ}±w«³ungÿOóÉ>u7IŸ–ü3÷’Á`0 ƒÁà�1L÷Q+SžX¢+N~ ‡»Üë?Ïòt«rç>Qÿ麢×dŸNLqú¼cŽœy¬Cgvåª?±Idÿ]ü”…ŒbºÉr;‹ƒž£ÎgŽÁ>µÔµ¶“d†®6ã6ÜÐ �eâÚ Ý/ƒ­¿iúäÇV‹žXþ®¾�5€rViÃdAë�çoóºP mbò[èÂwí„gövîe ©ÿvró™Û¬ì¬\‰…£)?�c›ù–±jgÝÓ|ð=gñи]\®Î5ï®mrC]ÿ™—nwí™q»÷5;f¹cÑÝ{;üÕï©L«Ïk¶‹4§¸1¬N%Q ÷çÏŸ×Zk}ùòåÕ©djuLL·Ö»†qsÜZßÎì.¦›óÕàŸÇ(Ýo„SŒÔÀ}�Ò™ŠõËwî#é¤H’Õ)SŠk±µ^JÙý/œ*îI*À…¤„pbOÇÔUùÐ_Ú¥™µ$÷nâʼ_•Õ�ÚP2Ôb�“³;²âU…œ»î+.. œ}jçy¦Q÷ÓXÅ}7*›Ž¿úáœQ¾ Œ{É`0 ƒÁ`ðΦû�pLž²¦Êt;×ÝÌ¥gjêj¶3—ë;4ç» ;Ä K±K×…Mi�„éØák6O꪿þ+ÓÄûŽuR&B?š¢ìÓ#CœÜ'´°�(ƒÅ ú[ãHì Ë û`Y›º§ÏYæjâLm�mαTάÊ÷yÍMšZ<û¾cºë­¶�V�ýšP+˜ËC—™.¦™Xô‚c׋•{xx°ì•‡žõ­ Ÿ~àCÓ9±z1O×0²ZF®}§°Ý½ê£©^œ…4~×ï:]ûÛ‰µ$YÁJÞkò·ËS —æ'÷IÜ]}'»“Óõkׯeãiq`šÚKOøüùóŇr¢E"1÷¬c×¾k\W=Ä}loðÏa”î7À�ÈP×<±¤Þç`Z�•“ZòÏ­çõ¿®»¼8åt×Ñ;t6M®)Lç‚ÂpômíÒ­ÿÉ�[e£Â]iñºû`‘ÊêðTn Ï³†éÜ"-.Æv‹€šÌ;EمѶŸÜ<\Þ]ŸHîõ_Ë+¹¨û (,_×'ºÓ4xäç ¨D&ň ‡.¾Bg.§Ò�âÖ0÷÷÷¯Ž1]ë² V�×§yÒ/.:¤>˾âÚ]·ˆK}Œ¦x÷N‡r—9);Æéu'Oýzz²û8º¸S[åÁ¶ß‘ižØÝßAÛã[q¢øë{©>®EêG:¨2œN2©>¥ÊðŽ\såíd¨1_•îÕ-fðÏa”î7 ù«/•û¥vN[V÷É’¤�PeI×89]Ãtéý´ çö=šÂ d;eQŸ•2–”î4À‘µpõâþï˜D")Žn"v2¸�ÓMnS­kO)®Jw§$ÕärºÑÏ)ŸTJ;pcfũ啎TìêrçëdHJw·pPp¯‚¶‡®Ž˜V§¼:¹µìTŽ*ƒ¤tkšªTh]j[`[½flp}¾[,ž”ßëú,ËG7¾um}7Îrá c’–#‰š4pñzÍ‚9!)÷|žræo§_û¬žwýt·x{+X_©Žô½ÛÛÛ—M•E´¥±FÓé‰ÚßÚ/U'!q3øg0>݃Á`0 ƒÁ;c˜î+AV�«YžX²Öº`ƒÖúæÓµÖ·cõ9Ý ôY]“etî%4;‘Y<ÅŽev.úÌÉÝŧi#°c&´Ó�\œ™u­×§6$F3Õ Ÿéo²íŽq\ë’™pGÛU�óx³dõ y±c;Ól¥ã|¸wùV$·!Wß®¼\Ù¹SJêYÅ�\…’Ïcǘ©ÿ²Ë÷ ë¨æeº—iýZÉz£é&vÕíp㓳zpª2©ëŠÇÉÆºLx~öq&öŽ�Õ|ŸŒƒÉâGËëAßK²Òbèòçü…;êÊ/Í”ggÕqiîXæwÀ$c‡Îšqâ³ÜÍU.îÄ@§º¤’ZõK•Ú¯t¬¢ª“�®^õÞÍÍ�eº£jð÷a”î+QJšltó$¿@©fÚäoZqj¸z¦×ê/ž|Ì;¢âïž×ï4 w¥S6NçµüqX;¥Þ)ÙIQcþNÉÝ•ãé{NWN·6¶Ö¥rÝ×ÇI±[u¦âŠ[�¥r u½Ï Á¹”0 óêŽÎÔëZ$9eŠÊ·æ-™y]y¤…ˆ.8®Qæ\ð¸½$[·øà}*xL‡v.”å.Nñç˜È2I}‘ãÖN!Kù®0IaêÎÓERA¿[òpáÔÁ-.»:wŠ¿Æãüv;…Ú½—ö8%;�}©LÙ·OÐ)ÚLëdQ²[à+vsŸÖÓå{êzš6(_;?¯µ^)ú•^ýŸM•?ƽd0 ƒÁ`0xg Ó}5%VÇ�XRP¦ûáááÕ1�õN25r­Ìæ ÓM†ysÏv,€†Olò5LybMÓ�Ø>'Ï®L׺tO «tµ *|ªÓÄ$ò×ç•Õ§ÜŒ�V8gýqL~Ç:§0]Þ\ÞsëÞÙY÷:üD–k ²jÿãØ{"ï.}7·püf]¨žðéÓ§‹:×#i5 Ž©Úîô™nªÔ÷´MêI&?~|¹ü½¥ûô“ÕF­f£¤tóÄç6PØ ”: ðH ~SÃr—õn�Ôßirã³ÅÜå‡ùt¦yç«ê¼î˜ºN¹× Ïù×WøÓ‰„®Iqs jÉàm—¾ó©v§¡0Ïšw7eU¥"ùqwåÁòw "ÁzÕ0�û͉b‘”î.]|š/ío×Ä—”½ä^Ä>¢ý^Ç&úõëñaWÅWß Ðs¶ÝØB9¨äèøT |™âw‹O"=KJ{É¥ -«ŽLèÚBZ¤°é=¶ûTn;Që�Zð¦±FãeûÚ¹>$e<ýÞÍ\xœ‚ò¥ëî´™T¯¬#Ê[ÿSNþݵ÷Ë�®¤Š0û ãsõEýAÇžd’ö¢ Þã^2 ƒÁ`0¼3†é>€šXiÚ×Õ£;±d­o,n­bÓÇV4^ «ÿ+nž�6Ì1ÍÓ©ù<±Æ' wbgœ|'ÌÂZû“,hjÖ°<éƒ ûŽéÞ1:Ž¥'s^²(Ay+¼2ܸv‚ŽyS¤ÓPÜ.û3mçþ¤×)e·_•ÝI¾¯eÇß‚bS9¨€6ÜšÔÜ‘<···Ö[�Ê�XÂÉ MÏÏÏŠ?•îS“§"M˜ŠS…{7€véwér¦²™d8‘©§tkøÓ‰…uIó  OÅJ™4‰S™JeÂÉ&Õ‹sqJ¯*Ptgè&m�³[\¹<ÐE@%7ÁÉVq8týÀývaÒI$8ѦvÖ)¹ê;ÊÓC\ÛRźmû»2­üé35w—»Åç©Âì åÄ/:R¦Åú£<ÎöæærS-¦¤@ó|ó¤Ü‘QÞ±„¾!úÝ>ëʦžq¼tï¥ð•�¤ïʾÒÕrpJ)Aå,�ÅTîµ=×½’!…ç= Ómj¾Æ�›}ªS”ÓBrׯ®U€)n. Ü³”f·\ËïH Z€tÓ¯ÛÌß剺†ö±’«þëžœÙTùÏ`|ºƒÁ`0 ƒwÆ0Ý Ü© µJU¦Ù�X¢«æbºÓIdCë˜nž¦¢á5N"±¿º¸v,@Jg^v§W$†×¥ÑÝ/³Úî='§«#2?é+�Û‰¾«yÕ6WŒEbk êÛ§²'™4n-ã݇ixTVr™ríÍY-”‘+æ&õ•?1¤×X3\�_ô¥6£î=§ñ‘ñg›I§ý(;š¬ ,ÇÎÔ¬Ïv{G\ôZË�þ¦Î*äâ;íÿ×ßNÂÒ"Óíg¨¸ùß¹J1 Çg�`y«Y/ÜÙZv‰Ñî6‰�ZK®AÇfj[p'W¸~°³@© H±f´>�ݮ뇇‡Wl6dž¯ñϱm'(¯–»sŸ¢|l3©]×3æË1§CߥŸÆN¶ŸÄˆS®Ô†Uí¼¯ j’É�uIöN¶kß!�GׄOHsÃIX÷Þé˜ßõƒT—ÏÏß\U·ÐÏvò³Ý A©¿Õ<3Ëù{0Jw@Rlë~MlTºu2å1\©#èuR^ØI’K ‘z¾Ó Ri@¼¶sº�"ùž9³óiütåP¥Ëù.^3ðw¦ÆÁÉ®s'ÑüQ¹N®K;ób…wr1¯ôá®ôê™›8NŽ6¤l];K~ÛUÞ'ÇÖ%…EÓrõ¯íιÈ0½�ÙØýæûZÞÌÛν¤�ú­§áÜÝݽ:é")UJ§Þ¥»\ò×ïÍFË8)Ž777¯NøqØ)]®Î+\RD©°®õúì{¶i¶³¤°ê; i�YŠYrÁ©ßº�ƒùL~Û”Ç-R˜ßsqìòÚ)²]Ý~¯RØ)¬i¾äëÐåÕ� ÚG*NUºùÅÝÓ¼iä^ M“ÇιÝƽd0 ƒÁ`0xg Ó (»áNV(¦Û�X²Ö%X+ÆZ±:Û­¬•ïN,©ð‰ÕSyê=eAë˜Vþ‰ÁÜ!±&db5¯º"§ÉE… ¯2j:Û•ÕI»�²ÛZÆõ¬ûè ë¡‹CÓa8ýPIÁ1ªŽwùÐëÄÂ%–]Û#-A Ǧg‰%ta\}WÈx'º~°3q×ýÔÈLé¤uβ׶žÚ£¾W_¡¬tÒ (Žùsl]Çzw–7¶ŸÄÓ¹cÓøHy©¯8¦¹âæ;]ûª¸Õu¤sÐsÐ׺lË®w ï®>X´œ°Ýo©Sæt<¿æ�z�s©ƒ>Ó¼“)O}Du 2ÝÝ8˜Ê˜'i_¤n¡sÃ÷Z£tNñSe¥\Kôô§t׉%k½>ö,M¬€©ˆ:Eß)`�²éL_î?‘Â1Ý–OR6Óàµ3ªÂ›º$·*5»Ϲ¿8%Ý™*5ý2ù¥6˜Ò×ãŸÜ³Š›ƒ»~FZeáBR°î$ ý�&]-W•/)SÝ„ïò™Þ¿vv§v¤8Üd̉¹ëCÚöU�f? KJů -çÆF‘µ.ǧ§§§W‹Rç#¬yýúõëÅÉ%o=sí›}Yãc™$ÿn*ËTpºE¡æ/õEÊ‘dLrßÜÜX%*ßÝâ#ÉŸÚ”Ö±k®\9¥ñûdÁs2u`¼i¾"áòVåp·€âuz/ÕGo¹X9W&ž*¢.ª'ù©2ÑôÜBÒ)Ý:îtnvƒïø— ƒÁ`0 ïŒaº·�Œ›tó$7·(“”ÎåîØh2éÄMóïÔäí®ËÜ¥§,,ÓHæ.º;�uM¬Pb³ºM¬*«“wŸ,wbX¹ -1˜ÚÖÃÏt´Lv§,(»Ág^˿˃ _×<ƒ»þ_s óÉß Ï6 H ýŽ9Mé(:òβB¦›Öíÿdû”ÉT ™rµhèæÉ‡‡‡—0´8h;qõUõ˜,6Ê®ÑÂw²1ºkû©.wÖ}–ÞuV�*ƒ]]ò^’átS\‡d•¡%áãÇ�ÏNúÞ)SÝõÍ“8R½f}oÇ�;F&±ãÉ•"±L®¾œ5Bý�OxbÄCH\^O, »´NöQ$v»~ëÿºNndž &Y+'Ç=±DÝKt¬*Ò£W$ IDATöرێ=Vù\›¦ëÇ´ä^¢áxÚ‡²p]»M'ž(:«ÕI›M¿cÊÖ:s5IõåØ_Ç¢²Ži]«1)1Ý^-qÅt?>>^lÊ"ªaj|º½½}U¦ÚVí6ŒQÖn#eWç,ëŽi®ÿKOâa§¶Å:ëdqñuHý=…åH¹œµ¶Þs' ½•=îÂtØõ_'O×6ö$MÇdwãL×®\[á5-�Ê>ók•ÎŤdHåе[gÙWkÛ_qÔå`”îWî:Y¤“ChšK~Ü'G£ix�¿dã)¦°:óä5aNÞ/yº÷ê]ú«vJ7Óq^}^xRdº�ÕÉ­rœô•¾‹#™´ij¦ò’Â;Ù ÉïWÛ°ç”i­¿Tï4='_]†×ú=iS§J÷©žîѬÎzßMÞl×ltqÊkçB¤a¹g­g7Vé;OOO¯ò® ø‰«ûµŽgl.nŽ ú¯»… óÆwê·ëo®¼µ 9·˜k”íN¡ÜÉÓáææÛ1ÝŠ´øæâÈ�»*O§@êóô~ŽƒÝ{%Þº"Üâší>-€Rß)}DûÒίÛÝ×qFݼ\Z•Žî¡|?ƽd0 ƒÁ`0xg ÓÜt…www÷êt]1¦³¹ Žm¬txr@:É 1–•Ö5¬öé{;–‚,Ob}Üi,d³Êì«ÏNärìS'gdž2M'ƒ+wÍúR&!¥Sype¢ïíʧàuÇØwŒŽ«3¢ÚðŽª4 ™Â'�r/Cæ¶³n¤0”[ãpýºäÖ1िÕ)JîYÊúÿðð`¿’Kv\Ùv2Ýž²)»éÜoŠ]ÓúS367”;¶u×Î\©YvaRxÊÁq‡puÁüœ„ç˜H™S�sLL–M�®•jupéÐÒádtù;±vèØè4–œXÐvò±}»:úæ]ÛªëG5~¤FÞ’M[óÑ�d2l÷÷ã·Vº9ÐÐÊKê½µ.ÍÁn"sJ·3í©‰È™�ô ™…NYì”,Ö�ÊÆ‰¹,Å‘”6gæ=‘‰ƒl™Wžè ÏSÚÉÌ[ЉÆË¸ïé) éÄ ýÍzIévå›íRx´½§rÒv¯»é»"óÞ)õ"nrÝ)1»t(¯Ÿk3,+Ž'®LK6gÚïйi›Ô‰2í9aßQE»Úd¥éNgÒr¡lT~µï¨®Ÿ¼v '«ó/hÙ«)½SÚÓøTi¦qGeÜõ9wÝչ浫ónLÔ߉HÐòÒ1»++}~Òf)ëé}>;éË ;9]9ºwÜxä(ݘïÚŠ.x´”^ Êpé']_ì ¦ãæìôyøÁÛ1J7BרÉ8kƒ%ûã”»Š_¯«ñ—¥Ê£2¸NëLבO~N>awšc�N‘é�²Uÿ�¢âMÊõµr»0\À¸wOÙˆô~’UŸÕ¤šâf»uÌ ç�«qÝ¢ÈýV¸Áž“͉‚áòîäq²¨—då&¨Ô—uÑÆ‰¶“UeN‹3¶ûÚ<ÉñÉ•UÝ׺Õ|«UOŸ±};¦[ó]ÏÞÂܹ͗,#•�²�ÔŸÛC“²Ôæ´Žø^º×õ 7îó½Nëh¶A·p˜îïÃo©t;ß5*¼···gdkG Ò�㮣їÛÉ�ü€ÝDŸ”À·(í)üÎÔèÊ5Å—ä-è`“øtVÕƒS0ÒX'Ï8)1¿nÖ[F<±™]ÙéuŠ›¬nJs×µü8‰ªÿîYŠ;m(íÆÇî^²°i[æ‡ÜR½$YRÙ%9º0§ù#Ü8ýW Æ)Wgi¬ã{úÛ1݉ÝV·¯Žñ×ûz�,LS™ïôqžA�ßNéNþÆÕ˜jÒTó0Í‘�ɶà&Žú­ƒ~Ÿ<÷�:E—Î5HÊÏ©²B—’4‘½EÖNÑv&Ml§ b'�†×rIþªn°ëNP©¸¨L»S-8Q§… áqÊSr« Ñ-^N'+–ÉÂÂw’RÁx:¥Û…uŠ�–ÏnAXϺӆÒi!nÄ´&)#I­ô“KP· t �†}xxXŸ>}º8N,ù¢v}^ýÅur¯W˜wÊ”âݹæ¸kWöî?Á6Èþ’dÕ8S_f¤oB8œŒ ÉíŽe¥é3�“…‰^wï¤>ç¤ÅѵóànpªÐ»>ËwÒ= ã\�¢ýôôdO2éòG95>•Ç)úÚgÿªËï„q/ ƒÁ`0 Þ¿5ÓMFVwê’�VÖT™n®´;‹z�›(“{IbšÉD$è­Œ·cßê·‹³d&·KçŽeê˜N½NaRulÔi˜&¸³Zh9ê{ÊD¸2pìšc. 4 +k¦›ƒ;7–Ob†w,u‡Tß.Þ¦íëÍÉ3µŽ)#XLdbº)›c–Y¾©¼SùÐBðÖS\?ªSQj,SË Ë˜L©;9„c1- �\úNgM¨´ÓÀ¸OÛSÙDEgtmUÇ�úïÎ3ßYe\;+8+HwòŒ¶ï÷®�R¾ôînÌ/\ÿ޹ œ±ÖëSEtÌwßM`\Ý|É4©Ÿ(ÃÞ�©?ðøm”n�$ÝqV՘܉%777¯»�ÉÖ)pê’âd¨4ÝœN¸Fyåãâ¸F qn:”¯‹3 úÌ)ÐÌ×Z¯?ºAEÒ¥sM^9!8ó4•§4éjÜ�ÀI×-‚\þRÓTìÊ®\ŸÒ }²ØSœNZÝ„uÿéì”פð(Xnî”'ª �|IÉNy«¸Ù'’£õÊñéZE -^Ë¿»”ûA,],ºqÁYá»ZÒØÒµ™º.síÇ;·Ž#©¿íˆwr;Iò—»ö~Úžºû©Ý%·G¾§÷wý8õƒ“Ï.-‡·*¿§ñueì\ëZû�ë£üO²®t‹ÒoN\LØ–*Lé@•O2qéÎ1î%ƒÁ`0 ƒÁ;ã·aº+K¦[O,Ñ•äZ¯ÍzÎlœL•uO]RÈê” *_:‡ú-Lw’)ýÞ=Ó²+y®aÎwr'ÓY€Äüœ\SnÊÕ±Ú'›]•ãÊÏ û£yçç‚SÜ©}>??_XaÔ½„eâXýë�Ø-'‡ËgŠ+±°§éÔ;;Ëó—>äB �2šd›“å$Éà,`‰yåi%§ÖwBµÝHY›yrK¡ëo´øtn …tz†ËË[7(»öÆö}r&=ÿwõ•úebÑɶ§öääx 4¬Ûpí¬miNJyR8«ÞŽÕOñ—Ì»~Ͱî·k).O.înœ'Ó­÷iuГ֔éNgi'¹Ý«éh™Ò½DO¶œá·Qº�2Íë»»;{œ �JK;ÇÓ„Rƒ6�[¢ îô7§£âܽnAp¢¸3®N¹KÊe©ç�)®S®\|Tx:%<å¯{Ö)d»I–q$¥›²vJ£Æ­G¹}þüù"½¤ÌÝÜÜØx¨t3NúÎÉÇCRún·ðà{'ÊÐ[ÁúW—}¶;¡ÄÉÃ:îÚÃZþ8;­3�üøuº4‰Ÿ å¡â­´ôC9OOO/&j­#5[— é$)’»ò©¼ï¹.?;W� ß�Wîº{Ï¥Á÷4Mw‚ÏNžk”ï..-{mgªøÕ½zÏ)åL§[ð°}§ñÿD©|kÞº…ºÊt�,ÝxWÏ9o�0\ë[?¬gÉýƒrj?H'™TšL«Â Îð[(Ýip¿¹¹¹X-òŒlUº{t¢tWºbLŠ¿;&ˆyè&EÇ>°|Ò}§\•¬'aJ§dsŒXÝ`Ôù8v!óà&¼¿¬K½ÿ–ð4•�êêȵéîX¹Š³þ§ÉAe SÎxÜïTN1w“qWŽ;ådWdxدÓbƒéº~í~k®Í8EFëO?ûîò[×'lòná§ãb¥›ö¼¸rrã•œÒV÷SÙ=??_( ©?2nU8OÛwR*S¾—”î¶[Ø%ìÆ<�GFlCZϧóÓÉónl?�SÆÓ\£pc®>ÛÉ�Þ£<œOæU}Æï‹è‚é¸U7ßêÜÐí9s>ÝÝ¢tp‰ñé ƒÁ`0 Þ¿ÓÍKt…¨&c2ÝÊ2(££+ïĨ�1Q3uia|éºCg¢ê~ïÞKl{ú�l‰Íì˜îÄüt+îŽýí,|ÇÕ?ÓîâëÐ¥[i(›¤nI;ë}·yíò‘'2wÚ¦5¾Î¼«3Çr%–êZ‹…+WÞÅ$é³ÝÉ8üíN8ÒßNö®¿¹>²Ö%ã¬L´‹ÛÉãØµ“¶®ŒÚãããÖõ¯ŽéVË‚;uÇÕÊ_ÊCÇÊê}Z 5üµ œ]ÛOV‚®}/ãØÕ¿Öëı«×0 Î‚SÿÓ8ÑÅ}:Þž²èÎR±«¿ÎR¤q¸¸]úúžZ7õø@=IèšcýœU…ºJçK>_¨<Ão­t«Rý•Žÿ¢ÿ«S>Ò„â6¦i:4[ïLM×*�éŠïìoÁÎäÇàTYç='÷_±4ù�ž.d �y;]»ö§ bj›É�$)ȼwÍ„×ùž—–ÒÖ¼sÂã‚ÃÉ}Únonn.ŽÕ0ÚŸ“ò[ ÓnqÎß|vâR¦é8׎ÝÂf§t;0N–Ïýý½Í}EÓØÂÉ}WŽUßnÓßnüpcˆ+�7XÏ ï~ëøžú3z~Bãpa®Qº]x—·Èpc§ºÐÕÄÍi�\©OÆ{Â-ÆNú]'¨0n#4ãïâvc†Æ]×···ëöööEÖÅb+]¾u£q¡ô#*áÌß÷.ú~uŒ{É`0 ƒÁ`ðÎø¥™î´¡LWäúᆴu ¡c0xM¶öäÄ�£c‚:F¥[‘ïVÔ.ýtdÞ ë�XÇ<8ö¨cº]9¸¸»côhÝHLËÞ1o,§®Œw›ÊxOóÅü±Ž´Ýqs#�¾d^5�„†çÉ 3Õ}\¤kÓš®æIá˜+½Ÿâ«w³LwM;±›”³s=8í‡]›p2�…?aaulbzŽ•­çd�ÝfNZ^žŸŸ_�bBÐŒMÓµ“�r2]ûîÞ«ÿC\?èÆdE²Â¬õzsx·Vï¥üt,øµÌ¤“Û�«Zw‹Ìø˜ï“¼2¾Ý<´›7»ùÉÅ­÷iÁK̲Kûd.MÐ6èŽ>ÞåÝ=×±.Í—ÔŸôÔ¤AÆ/­t»†wsssqŸ_ Tó¤N TPœÙˆ“$ýñÒ•”îzîâ.¸7)m×vhN6”ǽߡÜ“ÂâईvnZ8Ð|–Œ‚3ÕéûI™r“¢{¯S¸©,¦/ý©¬¥¬ÔçÜKÜD–&7‰vƒ·¶9Wv.¿L') ›Ê˜y`¹öÀÉŠí3)9ìó;…†&[…ºÅ¥¼¨|k½v/aYîúh×»÷5ïznüÃÃë6ãòäÃê^Rg€ë"N÷tý-¥Sï¥zå‚PÝÝ‚÷t¡åúÚ®_ºqýdáÐõ'Ÿ¥ö�¿u­{¥©|º>º˜9Å÷ÆwÚÖôÙŽ8égÚ*Âåb²ÖåþŠ´`q2jŸàÞ #ÝQÌ£t÷÷’Á`0 ƒÁà�ñË2ݺÚ&³¬«p2Ýw6÷ZÞD—V©éÜÒä^☷S³S2ßñºc[˜N¥Ÿ˜|–ÁŽUI¦¼úíÊ8�ùÌøÜ™ÍIîºN_ä{L«“#1ÝÊfueïº0j¥Ñ²g9ëP&HLj�²^ú[Û4™šdyÑ2  Ìÿ ëåúᎵrõâ,bÌs*;–IÇä9k‹ë×Ú>“e‰òðt¥’çZ¦;ÉIY»6ª–A¾G¦Ìå»4~eo­ÿ0wj�T–YÿÓ2Ä4R?peÅ:ê6ƒ*ïòæ~§ºìâIc'Ÿ)Ø_´|»½÷RÿMîJ���±w}þ„¡ÝÍ‘.l7'iîìà¬wNΓ9¤ƒö ýXŽŽ!Ée‡PY•é®tô”µ¶ê‰)o9ÕçwÁ/«t'_]*¼Îœ¼VžÈºŽIó� s>Ýn"ë`‡“ŽÔ HÉ\J“ÖnÒeœ;YÓ€ÇãìºÉBÃSiÓ|¤ëd²ÓûÝ #)¯T(Nöì”mUÆê´¦Õù€v® šF§œ%¥„i%ù9Áw¦Í„ÓþÇgLg­ÜݤïÒ¥;åtùs2§öy’·ççg{LàéÉ?NÎÔ>“² û’ëÁ‡ÖãããËo=•„ï±^trwÊK)»]Û¨÷N:¦Sqèç¯]ù¤rH8Qº»ñ6-+œË+ݧRÿ»F×0ª:¶»<¸Å¢S’w2u8‰[‘æ�î½”æ.Ž.nÎqŒ¯”b=•M?–Õõy·ÓñMɉúŸt©Qº3~Y¥›,‘óC¢âÂ*ùÙUœõßMTd½:Å6mÀKŠ2åL¸FÑîÒOÊÚÉÀ¡º–iuL÷¬³,0¾$W*Sõ1¤HE=)‡©¼œ©žNÂð½´é—rº¯òÖùä'4ŽNþt ÞW?ÜN9àýEœõ’&I]¼¤¶½SÌÒ¤í”vö=�4Õ‚Ñ-~ÜÄè”nM3-rN2�Ò;­L·2Ö777û 4>UV;ßQ-«-b§ý�ypm°ú޶ãn<Ðü¸ruc Δ‡]¿ìðÅÜå¯+×ÔGØfÜ\Ó)Ð�ÒÝ)µ©.øÞI| ©|êz7/vr&�ÁÅëÆÿZ òKÛk½žWUžŸöë�Òí6U¾uQô+c|ºƒÁ`0 ƒwÆ/Ét£æšäïDsXrqè˜n†'âVˆtÑø:ŸîÄþªl¼f9–‰i&3¤c½N™ïúŸXpWÞK“äÖ¼%¿]šÙ\3ßü�ò™˜©Îr�ºdÊcy°Ýñ™îaHèØ¨tŸétmÁírgÖq²nt,Sj·'mÁ±ž‰�T$ßÚdyQ9ëÚí÷ nnn.,C,K̓‹£c,™NrwḬ֥ºb”kI={||¼`õ•Iæ˜íX4'/åÓß&±z‰Ôñ‰ãf¿OÕ®miÔŠÀ÷ºãõøî)NÆòÓðÝéNº¨²:±@¸pkåñmg)è�ƽ—Æ|—æ522Ýd�(ëŠ2Ýz’ɵõªí¾ú�öKÝ34'™œá—TºK)Ù¹—8s»vnwÔN§tëÄáÌDN)tŠëΠxWº—&Štížu迵¾MÆÎ…ÇåÑ ºÝF,*ݪÈh¼ª $3Ÿ¦[›Gvu£ƒå;]<©¼777¯f�ß¹p`¿¹¹¹0û»|7i°ýkúI1vy­|œúþ�ÄÝMôõûöööÕ3ןœæa NAëú¿k»na[÷UÑz||´}Ç�Y©þ˜Ïn|Ò¸vŠ�¶Çêóš×N™r$…èÒ=—´N|æ%«ëWì«lg'GLrNIJiZHîà©'cAŠG¯�‚©ñ܆ù�ÒíÒsåàÔÓ¸¯Eê³§ „´8tÏSüJ,п[ušnìuý±ÛTùôôt¡WéýÁ%ƽd0 ƒÁ`0xgü’Lw± ºÊvGÛ�U"+“>R@6Cá 2Ý�{‰3W2�»�˜j¾§i:v-±â]š%_Ǽ¬uÉx»0\i»�üd3x­,±û°E}ÄÃ1Üd{:†?1DÌ{2'ªé8YD¸18}y0íP§¹O™óØ–Sù(»Ks8ã©÷X^š†CêÕSßqõÏtëåÚcßsuαà­ýÿÔJ´c0w̯ÖË ‹Êt”íÒ6­íV7_2ïÉ:©_©ìpÂ<^s?•]1÷.=Zu\ß=�ÛÌÙ±µ§íVÑY‚Nä9CûCš‹»ÓKTžn~KõЕÏ)Èœó~²p|;I[Ã8�ÂÅÃyC]Mô$“.-wŸ–*M‡Ö(u;™“L.ñK)ÝlNÉeGO“HwL SLùµäîà&Ü¥y§xïžqPLiž*îÜ€Y“ÍnR¨2Ý™õw)Y鋤:¸èd�<]^ÝÀÈLÍr•–“Û¹Æ0…StcÐ.¾N�Ni°Lø^ן©ÿ§…²+ïBr­U¿ëÓñŒã%uοu}ÿï‚q/ ƒÁ`0 Þ¿ ÓíNàp› Z+Äîƒ8·[§U åëN(èØ™´ZìÂ1nÇ 'FÎÅëV׎õ(�­à‰‰H,LÊ·[Ñ;yœÉß½wR¦]^Ý3WÞnï¶×¶ÈjyíÎ^MŒ¸î6'£•Îv¬`]'öÕýf§¬¥k·i“�KŸŒqwˆþ?uIý�ñsLJ VÁ1ò®þ)7Ù¶TÞêR’,"®�¤:R$¦››‡•9xx°mƹé¤6y-ÓæÚ°c?]ÙíÀ¾§m£s éÚ±†IáõÝŽE¥»Ij?Œ/�åÝ=­?º$¨ÃÉ9æŠT÷dÞO­çnNJ¬~*û“4»9¶c’µm¥“Lº2`Ù% ÝX4ÍÛÛÛuœç_¿ŒÒ­J–Sº»c×ê™4@:å¼ÒÔA…+'Žk:e÷¾KÇ)©)®“It­~0¦bG¥ÀMº§Š6ëX;z*º|h�™/ ~kåc"yOO Ñ/ñ©l¬›ÍíS IDAT7‰W9²íÖu§t'ŽÔ{LßåÅ ú齤(Òân§|³=»Ét§tw‹D‡Ÿn*!Ý^�nAÎtK.•SÝvååÚ†+m'éT™n²NãO/qyªþ»“µ[@3L§0é³ÅÊ�wŠÝ)®Ž\Ÿï”X-{*êioD×GOÑõå…�ýÒ�±5_kþ*O×|lådÁâäW9ß²pKí©k3§qkÛHq³\�Ò­Dd-~w‹‚*%h4Ï�¾uÒ¯~ü2JwÇtó*Pk­—Æ´[QSy]«Wº*MÊ ²&Æ9ɱSbÜÄÃ2a§uá«óž.œ¬ô™åû»câÜ*>)ÚÜ8—Ê)MЪ`t`Ýký3Í_÷%ÔºN‹Çöh¹º �×Z–dÞë¾ÛĤØ)#Œïšð'‹¼T^\@v¡O˜û�R’&¨´ÈM×κá@%«[ìï”—/]`8<)/©?sÁàòÄa‚ë+nl§ ”Uqª¤|“ Աȅá"+-x»yIãv~÷×*ا åô¬ëÿ*ÇÇŠ«|ºÓøö_ï´àéÚÅ[Æ:*¯§åèä9�{w .fÖò›*]í~I¹çu¥uz¶þ¯Œñé ƒÁ`0 Þ?=Ó�le�noo-˨+ºbZ’{‰c&Ý{dâ4Í�ߦcˆvLÂÎlz¼i<Ý;’ 1­l+o4“»<ðw·¢Na]±|O6Æ—ýÍö©mã-é¸ß”�ñ¸öNyÊâãXp—G—_ǰ'9’"Å­aèR–Ê+Y/NÊÌ=Ol”c,»ñàÿcïêÖÛÖ•�Ò¸ûý_÷´Ns.Ö7] `†rœ8]Ä�e‰?Cr8‚Å×εq1ŽýC9‹Ê,#ÇCÖÙ•=é…êc\ŸXÔ9õÞ‡ª/þÀÇd…¦ë߉™vÏp?6Çq«`øÜµ?n±`[ÉeRºîNð¹Ü–jea«ûnüÆzÀpÝÉ0êÛÎ„éØ—˜f®'¼žô%Œãìªw\n·[-U²áö0”Am/©|&ïÁüWðå�n·OÚ l< óžBeÈ*^¥åœT¼ ‹ò¨4Ü �é»gˆÎ™æ½UÎÙwN~É’œ|¬÷¹Y¸”ÑN2°1V{£YV”MM$”c’ ³srÙ©}zz»�ß7Ñr5p8ÇŸåÆkçXñQ×^I§Â*Åõ+îË®NœLÝ‹§Yìè°Mâëún@׿“ÓíÌäø³>¡œ“—ù’H÷¹î«¾~ýúõÛf¤ t²�îý%—«ï¤�NWÒv¥41ÁøÎ¢=šl}Ã|Ê¡Ÿè·³‚Ò#7é™8µÎŽ2IÅN7ÖƒÛ΃iªvx� È*¸�ݸêúåJ)B…'¯ì+=V¶õK}‡BíéÆ|§zü·bO?6666666666îŒ/ÍtóÌ�gt8“ÃY¢fm///|dDåÃàc ŠiwÛKë2a¸YVÇ9Ö#ÉÀLÆ„ý­º¬û)¾š‘«—�ê——ÅÜ6Ǻ œ•�bºÝÑH(3§�ÏÔ _±Yœ?3j‰­q2¤0ª�ù¥J.‡K»c°�]«UÅz±<È‚M˜-Õ×ùÆÇ:t×®,Ê>Ç[Vy«ûe§”nLí‚OcafÑ骓ÕÙ-Ö1NÛŽ4Õ�ÔÖ…ŽéTzìÚ˜Ã)ÝJz•dDY Èt³MSòq¿Ä¾ÝÙî k­n&åéd¨k¿Yð§ûøßõ–wZîÙŠ=túµ²Ú0±;|í(~v²"Ryv¬<¯Rð©)ÿu¦û¯qºÙiSK®€JÃK¶õ¼â³±I�˜eã­8P°cŒi³3àsÔ§‰®$§�ÿ+ûŸì£Ó­Ò‘[ì*BmÓTß(Q@½Rº•œîçççÿü &{{ÉÆÆÆÆÆÆÆÆÆÆ�ñ¥™nõAœãx¦»c,ÝÇHÔËÙí%S8ÆÖmoàp‰ñåûnëï_¿Ú¯y¦ôK\À«xKIZÒsL=ÏÊU\d•óÇõPñ0Çn(&™ÓNo”»üÝýJÛ±m)-ÅLuŒ•b{ºU ŒÃ/ºmDŠuIàþªÊy PžËå"™®´ZãXuu²ÒD7¸�Z÷Ò‹”NÓÍÿÕŠ¢ÎŠwzå^ûöí›üÊ^bŸ±¸˜ÍC¹•-èÒSL¤ªcŨv¶Oµ·Ÿ¸í”ŒgÑÕ·‚Ò¥ Ó­Æp¾¯úŠê‰ñŸÈ½ e#'ùMâàø¢îãj[mAªÿ¸=T¥�ºQéã–´äûàõu›É—vºÝ›ì¥@n?m�çŠÓíŒ.§›Ñ  * „ì°¨<“cí œ¸ãø÷äç¤bœ´GQÉQm©öçO—*1_Ì«d˜,¦ãº n QAm¥á ÜêþÞe˜Ý@„Fš·?uηAj‹¤÷ª-Ù)u'”pì&§œ—IWþì;‚ËZåR_sUý�år:�[Àð~•ÕmrmÌ2¸~„u„qø£LXÜç•�ýþýûq½^ßœš4™”8¨É†š¤¸òð³äœ±þLcµ�e¨´ð²ƒNî×ßøþÔ©t2({úúúú{òZÀ­&îýN[Õƒ*÷YçºÒK¤EWßÜ–.NrÀ�Ÿ ÆØôåÏnbSiª´Ñ¹ÿ¯:Ý{{ÉÆÆÆÆÆÆÆÆÆÆ�ñ%™nÅtÇŸK'j{Éq¼�©M^PÌ_Çtò‰)i¹”åRpŒX¥«¶´¥¤»7²piÖ‹×éƒj¦¬Þ~^•ëDmçp[;Sq{¤^�E&Y~Ç`ñI˜ï03Âew28f)åã˜Sf‚ñ>Ÿw=9•ıŒNvÅÂMXkNñº\¨Ój…NÉŒ+qÓí3ɦ¸òqü•ƒzÖÕWJ“YXüð 3ìX�¨—ËåøùóçqÇ›ínŠÉUàrsßé˜eeÛœ=á0]»¨¶ÇúrŠqú4µ¡lU¹\<'Bõµ*à^6>Ž·gãc¾nIõá•F·ôY×n eLÃqXÎW-מq°Ý €–É~:%·»W×üñnKw}ùã .ɤîó€ŒÆŠã¨#]ýÔ’ñ­†Ú (Ê‘`ê™:2�ããýiÝñ=5ˆ¨/ñ©>‹¨=øjË…Û×ÈᜃÉú”tšû£äR8Uwœ)˘&Sn`ÄgJ®ÎÙf¨þ’³ÜõŸ�4;Ž·ïZ £PöÚM�CÅ×�ÝRepõ=í»n—žËÏ à.^]«Á”�2ê¯z¤ö[u ø:ísO_ÅE8²À9{8ÁpLf*krÒÙ6°Ó§tZ퓞L§N)êÿÓÓÓïÿ×ëõøþýûï°¨£è ³Àåã¾çœ@åüò~z.SÒ!Ìc:á˜|å>íxWžÉŽUÜd�1÷u•¶ÒÕïU?ÀkW�\f5³mPíÊÏœœ·@•o2˜¦[é±ÓîòPéó;gLÜMôۜۈ�n$©þ‹N÷ÞÓ½±±±±±±±±±qg|9¦Ûm5Pì¨c ÕìLÍæÜ^6f»=Ý^‚3Džñ+(¦FÍð§,·J�eUÀá:ák•ç¥V*ð~ÇzàlŸǼ&&ÉíÚ¡â¨!ð>Çq ¿+Wlf0+Žõê˜Ì$ ë Ó[–‡?x¡äQ¬•c-&:ê˜Àô^‰*¿ ‡ù+¦›utÒßÔûêÝÅÊ£<†mC±ð.ßQûM1í²xc…c;ïôŽû‡ÓA'·êSŽÝœ°‡©Þ’>r˜Î§~¤äse˜>ëòà牉~zzúc‹Ñq¼}‡Fµñ¤|îýšdë& s çâuìøê˜ lñ-l´³GÕ×ÔÖüPδ>þ|I§{º§Û èuÍ_´ceQƒd-o«½ºœ'Ë9l]§g¥vKî*—¶3˜nϬrŒº2²‘@¹qËËä &×w*Ÿr~9mgy«×7—~ç:‡×•Aù——&m4uTÚn’À:ˆu£&,(õQŒ£ÊÊíµRo®ìi’¡ú›³MJnÖgç@«í|Ÿ¡lSÉÐ9?¼5�mìÔyq[$Òdm,ꞌ÷±<ìtã±giâà ÞQq}6Á9C)¾jÿd—¹|¨�øß•»l“’5É=±!“‰ —�í„»fùعãíJ•7OÖ\Ú,³ªcW.–�1qÐU›Lm\׿Öù1ü²2ƒ')âtãýÿÒ6“½½dcccccccccãÎø’L·šwÛ9 8ËMÇ Mâ»|9¾cCxÆ�÷]x·•f:ÓîXxwl™c‚øY’Ám)a9ºr¹2¨29öF}†ãÔ,¾Ûº¤þ+¶-ÕÊÃ,üä«�3áî»¶dp>Ìîs¸j#>�óÁúQ:§V=”¾¹z˜°”Ž•ÆrTY'L÷Tçœ}rl8—GÕ�Òc¾æ~˜Ê¯ÊqfåÄõW%w1aøEZÔ~a �T6µäà#ÑÒØàê?õ7UnU?“U0†c?™eœ2¹’�à2Mì—…íÄDo+<§�º Žku¬<·ƒêÃÝ8£dU:6Ñ›³Pl9ßwõíV øƒZ\Ǫo¦û-¾”Ó]F¤ëdÆíéâ½zç8(cŒyÕõd{Irb’óèœÀ[·”¨rÔ)%NÙÎ�¨e'çðâqD˜7×±+ ×Mr°óW<<Âî8òV�‰ ÇáÏ+O#†q“¦nP]u’T%7§á¶'`;£>ñµ3ÂhÜÕä�}$�ó}f²¦&Úèª_åX©ã̺>¦NÒÀ8XVÞ­Ž‚ära¿r`ävá²(°S‚aq2‚í̶€Û�ntºØùq“^å,¦¾£«dR>Ók¾—ê›ûߪÓÍz?-Ǭ·X“-&lj�­Bû„ûì¹-ÔÞñëõz—ÉÇ#bo/ÙØØØØØØØØØ¸3¾ÓÍ/±Õ½úuÛKÌñLͱēpn†Ø±°iÙJ=ã™cbǧP3|~i´c·»kÅDà¬Ã%æë;-ÛML·üÆËþN>'#¿A?Éu˱‡õ_± .1Sê>owHqÃÇ ®fp|þÀR]«|*m'OÚÆ¥Xf&=›ôEf�™ñÆrL®“žMV5˜�RÛ•Žãí·¸|Šác ›ìú%_§þÉ'GT<<³[Õ=®:t'ž ì,¢â¬2†“öR,º³·*�z–Ql—‚êcJ×\ŸPöõLÉéäSÏ’ÎqX_Jùe@\ùÂôT{)™Ü*�Zy@LëB­L¤¸Ýˆ«;ê¾êã¸J„דöSºªläõC9_Úéf‡—5Ð&'²ââo]s§DªÓ¯8Å“°�ÓíœN—¶x™Å èY$ñYJ;9?Éh'ã¥âñ Üþ¨[îÚ�p§'ì$aødØ'Ët�Ã6�j%ïÕWƒ³3èÊ¡wá&G|M'tÊ)Á¾­ô–û<Ú$DšLq8%kÅWu¢î«-%ˆŽ HΆ³ª�–lÊ©P(¹q{Úo´·\ßx’ .]s»¦Éž*çê³.|çèMóìœäz戄UÒd!É9ÍgâtwŽ(ê4nwpùª‰ž*ßÊxîÊ€÷VõG¥7­#'ùUè߸ñÒÙ z¦ü´ít?0ƒâfPÌ8Ç!BÍÖã£ØåH:Å�8ÑÇuÆ”§rü&y«|Ôî —X�ÉÌ�÷¿ª˜÷s¢Œ6súŒ�’ãÐ_;EÇ©ê$9lXVv:0_,W•íÛ··Ç Mö,ã5·¿ŒÝ¡ê¾›Hp>,–‰åAf‘'u®¬ÉQéà5�RùðÄÖ9݆'n®,Ü6Èþ«:`½uú„髼•]e‡Â•ÏMKnåÜ•œ�nU}àdÃÕÙ¾Šä@¡ñŸ?¾9>�ëÇ9Ž,§rd:'WéSçt»g.ßïÆ�ãx{¬›êË)ý•ë©sšÊŠv0•�ûêF…eÇ‘Ós}Ž�|U¨ö^uÈ+.ç‰÷S?N2`Ÿp{ãÕ$BÙºêcª­;ÙœÓÍïá�™€|5ì=ÝwÆ—dºÝÒ‡ÛrÁK‰!êökÕ,rÂt9¶ýõÕŸîÀåî–|ºe¦t_± ŽAÃð|­ÒUr«™­bÄTÛ©úÂ8g†*«Ê·þó5ÏÆC¤ädÆÃÇŸ'šð<êƒZÚW¬�cDYþIW™™ä2V9y9±c@“¬Gé�cüŠSíRÏ1N·� Ó~zzúƒév Û§br¹M¹_ª)îË Ýrý¡òMí<‘g¢oÌœãJÛa<½¤˜nÕ^ªîøšË­¶z)tì¶ ÓÙÖé=ÅD:›Äñ&l«“Ù�í²cJ;(û‹íÈéq?Æû¸]ij‹ùžóRý2+¼Âêv,pªc7v©ç|Oí pº¨|ˆËåòǪÚQÞjò_Øbò%œn·••_-‘ªŽå޽Ãxu]àeÎ×]'gZåÉÿ9ÏéËN *m.o¥Qõ¥Œ®ëЪ“ñr;ÖìL+‡ŒËãꙟ)]HeP“7(q›c]v/HñÄÏÕ ¦�2U6îª\î dî,mîv^ð낪¾Xל£‡õ•Òv“!ÃñÔD›÷³mJNkåo?yŽŸFvqØéîÊãäsò8¹�Þ°Þ¹û*�jöqü³Wûÿûß›òTÚhk¾ÿ~üøñã8ŽÛ°#°~YœÃÅesåìl§jƒi>][9Ë9dî=‰nÀº�œÑ ŸêŽ'>%›ƒ›l”ŽÔ~ÿ×W}„0ÿ29”ÞɘŒUwÅIvùbY];OlßgÿÆ·‰eQÛ|8=uf÷ÁéÞÛK6666666666îŒ/ÍtOXæB:&°®ÝKz< w/¹¦‚›U:Vgˆjöœ «ØÇþW¹'ì�Êë8üÛÊUVÅ&©:è˜ ÃËÀ\7é¥XNµñ¤ý˜PzÇpÇåñR¾cßû£XW?©��>:ýDf[1�ŽáqL¤CÕ‰b ÔJæ©ê˜ÃðöµôÒvÝïXîžü�õ…ñXp›N¥¡ Ê[ò­„¯|Ux–ϱ£)—.ÇÁ¶¼^¯¿Kfîqµær¹È“LXnÅtºò¬²¿N�;Æ{²Ê€ò¨0h‹Žíβº>å€r;Æ:¥ÓéG7¶V<¶wò¡Íçg¸•‰íoC;ƒiÝ*¹;Ýì|’ÔFŠé®ÿxâŽ/�ÍÆôª_–}uzó7áá�n5˜wNwµT˜–¤Ü–Þ†�òu{�¹LxÍyªxnpWá�CÈÆÉÕ³USÇÂ2©-%JÌ×9ÓüŸŠÉ@ïÞàæ|±>”¥òå0lÀ»e¹:©ÊIRu¢®¹½Sý8ÇÛÕ7ËÆº‰K¶| …`ºw)TÙ¹œ£ÄíÇuçQ.«êçn¢®Êê5ìì*ÇZ9Ê)e&r³.óäÃ¥úWi²Ã·â\¡ Xµçÿûß›½º8Ùÿþý»ýÊÑ9àlºôn_r§Äõe¿Tújâï&bÓ Bš,t¬ÒAÔ=ÞӭʧtDM*‘XqöC¥×• ËÇrrÚÇ¥‘ÒSòV8¶óªŽÜ±&¿XÿiO7:ô+öö’����������;ãá™îÄ2:æ†gœÌ2*ö¡ÒU³5ÅŒ)M±Öœ¦£âpY;fJÅë–þ¸Nûë‹4SF–I­@LÊ€3íĈpxuÏ1�*®*¿±�í¢tH¥3eyÅÁé“cëûètR±èªL˜3æååEö·b=:}àºï^~Vñ[¯ ÚÓf†õ{Ú_]-–[}™“eÆ0S•åVußé?êIªouݵ¯BŠÃq‘鯏lƒ¸½\I6µõ ­@9Lì3ÿwvŸ¹´¦Ï�á'vÆÅwa¦ý×Ù~Õ�°�Ö³zþüüüÇK•j¼Ä4pÛI7¶¤ûÓ>1©;gW§~‚+o/a¿Á­ð¸ô1­b½ÿ L÷—rº•Ãë¶y‡ÞR�Âuvœ£�¶€`úÉÑf9Ô 91¸Œ2<Ø×õ4�dDݲ‘š •J.É“×FÜߨ)Tù 0�®/*¤2azn"Ãÿq©ÓO}Ã===½ÙÆÀÏXV”YõK ‡Ž9‡ã¶â<±_*{¢H Õþ|tÛ“¤k~2ð30,CݯýÝX&Õ.ì8`ÚS'„÷xOú¼ÓÍ”÷JÝ8'Ë9ñ\nW¬»é„ªsò9þjۯµ �¥èCð—+ÕÇ»Øp¶Néˆ+“ë\†©ÐùNgT:˜7û\®m°¿:`}×ÇòTßþÛ°·—llllllllllÜËt§™Zzy²®ÝÒ�c™Í:Ž·/.%¶ÝÉŠy¸gŠåÆpÌ&ª8?Í>‘ÝvojszÆ-ùñ —sÕò·eÇŽMXW˜¯bÚÛ¤Œ*'þwg¶:6!±¿*ìqü¹Œ9�Zqò8ÖŸÏ¡VíUz¥¶+±¬îd fTð>³I¯³‚òðËvœ2Õ(�ë¿, o/qõ�×Ü/•Ý“˜�Ã|Q>e/;¶¾dàrUÝ$Û¢Ú/é*÷=d•î–l*ýŸ?JöºÊí^Øêdtp/ž»²'Û¢î3¸�:z…eæ6OzÝ¥™ÊÚ�ILW&ã†ãþÁL·óÒ CŽaO²(æšmâ”Eç4Ü}LÛ­rž¼]­ûV× Ëâ¶—üÍL÷Ã;Ýjo¤rºÕžgtX:ã ¶…(Cƃir]™Ü€7uèUš\ÞÎ1âNæœRÕÕÑ€è0±¬j‹B¥��ž—?» ‚ÚòÑ9�õ«Œ/is:h¨»6Lî!Ô±…iPKÆ™ÿ§¼�~«ò—Ãíöq+9Ý; ¸e&�À‚ëëζ(ÙT_œØ&–�õ�h®;µe§î+;¡¶ à3瀳œX_¨ßN âÝ}ç,q�8ñ¨sµDÍá°]¾ÿ~üßÿý_kW§Î°š 8[¥ìÌ›€y©ðnLù¸ö;“n‡U\MRùšå›\œÓÍãöÑŸx¢Æ FÕµslU™RßἸÿM®X´Å]ª1]tº±ÿòV¿¿ ïts‡qƒˆ0�Óíf•¬¸*\ VÎI�Ë¡îW˜— ç :sÕ�{y2<çÐÊX©£xoegôÕ3–Ÿ�_7(UÙÜèœçÈNV¸~]ù&l×�sXÒ}.cb·ë: †\�ne VØ7Ü‹†ª3Ôn:()Gï«Ï�;GËÕUÉxoÏìÆI :ܪœX>g#�s¨Ž¯sýÕO…ÅûJ?9-¯Êƒ²bZ?~üøýéw–§ÊZ»kçÎÖ)¹œÓ”ÆU6õŸÓPmÖÙÚ”×ʽnr– ôÕéK—fÒ¥[Ήåð¨[ÏÏÏø ³›�Håø6ÉÅaxlpeVñ\–G­Þ(9• Y±o*-åCü­ø{K¶±±±±±±±±±ñ xX¦;1ÉŠéfvue¶¥Òv§Rp8žù!��IŒ8§åÒ›Ìr1_UŽ%tñx–Šÿ1-Çæ;FœÙu–ÅÉå¶2¸vQG¯©p©ËT骕 §�,‡cÝrƒuÎíÕUqœ®– ¼Ç8Á1ÛnùPm)+ð‡-¦l¤cT£]×nK‘cèqyÚÉÁrƒ�ÏÔjÃXíß­bð¶�—킪/Åê©ü¹Ìª³<‹ªòb›Àò¹Õ\Æ~~~þ}ì ÃÉíþ+}rö‹Ë°jƒX>g‡c?-æãlA‡$ß4 ?×Q×¹<ŽYFæm ¿¥ÊÀ'Mñ8æØgÕ/ê>_w~Œ*“k?&¥]ù«­£éøÀt²¦u¹\äjùªŽ<:ÒévŠÂNi·çY)wTgô�ƒRùLeÀûnpÇÿj/(Ë� ¢ºîœ=÷ßÉ‚—Û*â™´%9ÝlÀ�QsPu’ÊØ=Cg69Ö“A'Éâ^ S駺wG'âÅ'æ…Û\9ø>¶ê6–‰ÓÃq¹ÍÕã3†Y9©ÿº~©&›Îñ”ØVáçá'Î;ª8vèú�{Æ[¸Ô¤09 ·=Ðõ+ž@Ç?/TÇ?ÛH”Íxzzz3¸ã’vz˜Ë1uü•Íïì­z�#ÕIršÒ¤‡í“+oWÂë ‰3ÁÊĆï;g˜ëÈÅç>S÷�ÓíLå3LœdŽÇ4×–�_à&�¼7ÛÙb—¶7–wõPvJ}ßão;³{o/ÙØØØØØØØØØ¸3–éN[,Ô ‘ú¶*ÂÕw÷i¿2ö1¶ßÊéRÏnu´]œ•|�^£>à'âÑá¶/N—·ªü’“Ý¥×ùÊyv“#7Y@Û‡º¡¶Â¥ñÓª~ù7ŸÙ½·—llllllllllÜÉt»—ëg@éä5;v _];¶-m/QPl}bαܓ™pbëkæÒv³HžÙòÌŸëÞ-i©³7�ü(&©c` £X},+ÞWÌž’'•C± nCµcbü9oU&Öoµ­ÁÉæäueuíÃ/öà}×ß3ÉÏ«Ã×,ƒb‚• neªcãêùõzµ[J¦§ñà=żO˜|•�’›óÆ• ,CÁõ#%7—Aõ+f’U>ÇñƒÍl2†­ó¼üøñfI›íeÅçzH@Y«-¹¸ŸvmãBï�±«îžzqŽû‚“Õ±ÖéyÁ½àÚµK·2Sÿ]¹qìz}}•+'h—QÞúU㉂³ÛS°ž¨ò9Û×ù2)Ï”–Çm=)¤í%Óý�N·rN댹#t§T¨|:ç\å«:L à ê>*“®�ÁqÇ�uËTi Åúv²ºe,ìHÉYDt¨Ê„'p|w²B·?×a2¹«ôð:9gÝ$¨òqi(¹ýúõÇ'Ý•1fù¹LI&ÎÝdk Ÿñëׯ߆ãIÊÇúɧ¡ð5§Ý•õÔI[`¿äßrÂS|•—+÷q¼ý’Þª~O1íÎù`»ÎÏP7Ô–9¥›µ¿›·'¡ÍårLHUö. î?gûÏñRëÚ¬Óç¼NËWé»­JgÏW&3©Ž;Zµe79æñ’ §4 Ä:B¸­9NÞI{s:ÉAMN²ó5”äì¯Ú^ƺÅí�2 ÁÛW»U¾Êé÷t+ãuÿj'À¿n†èŒ3ËÌåRÏ8­•Á°dVû@§/OV:êåquÏàAM•K”É`ƒŽwf¾¯&É(w%Îó8< Çy³qù&HúìÊ•&[èŒT¸——ù~ÄqøóÁ»AÛÉÈ]é ë·ÓÞoÎ,¨{™寲¹ý¸Oé7Ê�ú³Ùü¤ª”£ÒƲ+pùpòÒ½ø¬äè÷nO¯ÊÏÙ¶§›'?N÷Ñ>].—ãÇ�Çq¼Ý·Ë/†a:�sèôWR½(}TyOœ¶ÔÇ\Ý¥}ûg&qÉ–9»êðäL'G²“ç8fN·r0Ù!¯´Ø6Oû˜*“³?ª¬Î¯Jã“Ê“ÓC?Fù�/VrT|f÷ß„¿«4ˆ‡bºƒÍ³)\vèXüϘÎÎÕ~<7+œÎ$»ªdš0ŽÝvû˜;0«ì¶ó¸x¼ %!±QõY"fgÕI�åfÌÍÖ]cžœ–GÕ�jŽ;a:U90OÇð$†ÁyNY3–GÅc�÷ ã±…ª½Š}Æzu+\ž®¬xOÉ0±!¨7|Z ¾íŸê•í„Ú¶¥XjìêøG•6—9Ýç|”>ñý‚²-,§á¶ ºph�¸,üuJÔ™Õ%펵­k^Mbrᄌ>‹ÏVÆŽIÿU+˜çd\Å>–˜å©<Ö´ëG«ŒÙ¾Ïï�ð;anõÇåvõÀÕë¤Ô8˜ôÈÙXµÉìêShÓxÛ—[ÁøŠx(§Û5ºsº�r”ÁuF{¢\Nùë:íMDYù~Á9²É‰W¨rò >A§ÀÕ º­4õ¬ž§8Ýñ}.ŽÚÓË�Þ9IÝþî-”Ó]÷Òö’N‡VÐ9<êy—ǪÜÎÑç{©%GV¥Í†Üõ\ò­ÿ˜oÚwÝ9Õæ“—¡T]U9êLqì£×ëõMû±}rŽ÷1—/õ–�‚tN‘»Çpp½K àú˜J»ËS•»Ò¼^¯v?-ˆÎpÚWÞ9$nÜÁk5‰,y¸o¥I“Cçè9Ç&M&”Œê~gëÙëÚ6É1‘§sâ”ÌÊñË·8qÿWùOdÅ´œ�èâuå»u –ImÍB{àÆ'´Ó³Ó½·—llllllllllÜËtã=f�qF¥fy5›š0©˜¶û€ ‡ï^BRróï”év,³“™¤KÏ•¡fô]:¦;…e…qaܪEZÁàÓ0T{ò3ÇÂñÑ‹¼Ê�€/š$L,Ç:ãÅX×=õ5?•?§§XœÄ`ߊbݪ‘{Ãݱk\o®¿)öØ1�ŽqBÝÀ-%///oXo„cT1lm—À~Zp6Ì=ïòTu¤dâ{Ngxu*éw·*¦ìžê¿×ëõͲ5âÛ·?È�ÇbÿÀºp²¸2t mÉŒŒï*ûŸÆ 'C×]žŽy-Ù�£Q4¥?‘{²ºÑ•ϵ%�'je�Y¶ÿj<`]Å4Tþîz:†Nl_w;X/Yp|Kc‹Zbp Wõþ†SLÆéNïáîNÐP[)¥X.\rÚT’3ÝmcpJ­ÊWoóO�ÑâòrJ¾ãøw�£Kåå£]Ú)\r ”¡/™UÝ©ec·ÓKÇOvƒ§—œ %‡»‡y)}ê ¦­ú‚Ê<ÃÛ¨À;ç…û¯k>Ç}:˜¿‡pÛ¸>Ü`Ï}ŒeåSJŽãŸ£ìÜàÁí§Ò®r+½åI·Ól/µô=ðYöBšø;»ËŽzr®8~rº�ãø=ÉQº„ƒ;Ú0wÃÔIEù¸¬ÜWÔ~a—Žz¶ç8´Ž«gÜ..}Îé^ý*§Vµÿ©NtXµ±Ñ–WÛ±ž¸w5ؾ9”ì°»×¥Á¶¯•ícI¾€òÙT[ª÷³8?~/ìo:Áäï)ÉÆÆÆÆÆÆÆÆÆÆƒâ¡˜îî­í “بãÈÛKkÍá•<|É$mõëØúŽÑä²ÖµZŠu,eÊ‹g˜Ì”)Ö˜—»U™�ãÏe'ÇF°<\v,�bÔ¬ããó¤sœ·ÊãMÙ0§?*\úß=KL‡K/ývŒË™“œf‚ëY×ņ8f±˜N§/Š¥RϸO– È€q?p«2¨·Š�ž°Â.3ÝfibKº21ÜêdúÞ€cGÓÍe«’ãøóô’)»¦˜[”­ƒcõÓYñ* •g÷ŸËÀaVmAÝOL·ÊWõ¯©Nc¼4¾°lJÖ$§ó'pe˜Ëä¶š¸çt2¨ÿªœ]™”¯Òí àr8œÓvewrÇÛm_Û×)Êév×ìðvoí³‘vDgÈœ¥%é´UarJF2rª|¯¯¯qùÜ¥å:0oßqi`8ÞûÍíç>¨àò¨4�ìÊYÀ8*5(ñ¤BM”TÞ·|1�±âX;LdPÇ9uÔª Tƒžº�×n� §ÃN*žáöN'@._vôÔ6¯ãøÇÑÆ­&©8g�퇛`ð}UÇÉÑ›8S \§l¿”íúlr"�l˜öõz=.—‹”�äw‡Òv ©cËå«kLƒOF*p›§q‚ï9‡|âXuåPi±ó›úlšL%�vrºúqõ•Ê:-SÝWï $VãÈÊd!…ëì¼r’»~咞�ý¥äqí—üü€�ÓÓÙ{{ÉÆÆÆÆÆÆÆÆÆÆ�ñPLwÇþÛã˜ênf�yq|5{U³Ež®”AÍ$»Êà™?2ji¶îfþ ÇÂ;py0ü„=LLDbØÓ*2D¼„¬Òì˜n7;WËñ*NbËWêÊ¡‹‡:ƒŸ·Vqùc4*Ç´MäPá°ìcÙµ¹ê¯l7TÚ,“jKÇÕ3ÔM\:ýõKÞ�ÁéM¶Ùaš¬O˜Ã1Ýîá®î:ÛmÓp 2Ê”XOU*-ÔA'2jé[]™WÀc–[�È3a§'ì¿ê‹XG]<5Ö:¶Ö}ËÓK6¿ksgC&ãÇsåuá8~!Ö•�Ós²Nì¬w\ÚÎ~»>ß龪ûäÓp¿ÆûìSà¶�é6«¯€‡tºÝý´�á8¼c6ɇӘ:Ægºþ«m1SgÓu`Þ¿Î\u U'N¶ä€¥}é.߉QIÕµ-.Ë&ÇQ•Ÿñο3žŒnY eMËf®~UÙ&rc¾OOOqpŸè†Kƒv çœ\—xªmê¶+ÖsrÔ õq&×·]ã–WŽ®?8‡—í�BrºyƒÛšÃý#É‹÷’MD}J²«÷T\¹Y‡]ºÜ&\6<>�‰ˆé{ J‡’n2°�p[”s†8íN/:¹Uúª]TÿWuÇý¼Ëƒã¬8`“q'uçÒs6µžñ$\¥Íc桜d–�ÛŠí“k—Uÿ$!ÙQÌóï>œUòðd8½ŸóðéN·sl•s§˜Éä`8#ç”UÉÅÿÕ~'7ãsÞ+�œó‰£Íeueq�Ì•I…ÁN«Œ¾2«puWíêœnåü”ÌhS}+ùÕĆïcX%�kK.·ÛoÌᦔêj¯±J¯z<Ö)~•VÒÅÔÎJoUø®½0/ÆIû»ÕåXp5Y*–uH¥År³>¢nðÀåú9²Î!S«l;y‚èÚ–ëzbë’“ìlŸs†*mõî×Áõz•ö�nf×x/ijƒI?MN�J›mDg/»|ùšû ÚNg·ØÆV8Ô–gűårñµrîWÁi¤ô”mHvB�á}ÿ¾H­êèååE½Ë2¤ëÔ–ªîK—&þÀd¢”œnÌ;Õ;3ÝÓ×)÷žî����������;ãәµñ[ä‰�š,«¹Yšbºó®dTeHr«òªY¥còñz¬¨¼Ô>î‡O,Im¦føiæŽu¢XýŽ1V¬�+Ëí–lUúÝ,=é—ŠËzâ˜èŽéæe»”g…q+üᛩ ©þ0¾cÑT=bûðìÿüÁ [eUý¯[)ðñ¼:¢ž%v“™2§ëiµÁ¬¼:IˆÛ€ÙH<FÕßã�qýv}™mGbë9¥[Ì®£®³]PûHÙ~wL²Êwb#ÜGT&+•—c7“ÜŠå4NŸÛ]ùLÆ1ÖÕ•ú[AÇœO™U´çÊŽª#�±Np,Ù¤©Ü]8¶ËÎ7pã—ºv«·ÊFr\Në}�¯zŠÉ§;ÝG”�>7hMöÜq>ç©s˜�â±»�hê¨)eUqÔî¬îe¢T¾nʪ1t/Œ­8Ýj™¯Â$Ã÷Tç5É3ÖïÔÉåûNnÞÃ}»¬ Ø—pß�Àk0àý§Nænâ‚a«Ü ÀËíÎYP÷§Û¡ê(9åб®º� 9B\Ž´¼\÷SÝ©ð,·‘›T¢cÄK߬¯ølêtcþξ¹pÜ÷œÓÍÀíj///ö¥Ê鸓twêlwmˆÛ½êÅáIäÔqd9SŸUéL&É+GÜAÙ�«íÅá¦i»°ìtc{ñ1¿ØGÝD+Éе_£Ül;Ó»iSp|gkp‹—'À¸íë^“®�ÂÞ^²±±±±±±±±±qg<$Óí®y™Ñ1|j—äá{nææØß§›¡vGe)6cº¼4a­y¬˜ÎžÁ+6Dµ£šWYÓé!œ�:2¯ÓñCª¾»º�°Ž\*Üôe)L³òìXùºïô�uAmCÀçŒ××?¿˜¨äd¹\¹¸ï ‹êV°m]>J•\Ì®§¥ýª«ëõÙÕTVÕ±]ùÊëÚUååô›¯3ÅzÂödòò¤K[épZ]R÷±Ž\»V9p•ÇõE~‘rÂn:¤~ƒÏ“]w§\𠩬ÎÞqßAY]Ÿà|\?w«|=yé3ÉÐÅåkÎÙå‰]ïdÂ8°¹Õœ§'ý1¹iºò)9• JLwÊ‹¯Ó–ôÓÀ|©ò«žbòPN·»ÏÆÜ9KSçG¡â»�ƒ W§ j@rá\9ØÑV°sBëç™N;Üݲ“8T5O`e„±¬i@Àk5�:܃󜂗“¡œ8PwRŽØU[bÊÐ×tdœœê¿j—ÒA×çjÂÂr» ï1Tû�ãøã uw²GÊÉ™8,ˆä@©ûŒdg’sÏõ«NHöMÉQùNNŸš:B.ë5ÛT ‡Ç®” 1q¶§åàúç´ŽCoÍélRÙJU>'ÿJ»²Œ�­RyuŽ£Š3ñ0MCº<8¾’K9޵MË£èlXçx+pÊÊò(Y±ün’“®9oT\”›÷qc¨òª4Rݰ x4Så‹i¥tð¨½)ÜÀ\ò¥�}¸åɉÓíUL�OQ¨ûJö*J>îS<áKκJÛ�âkΗû ×¥srœÁïL&²uÊ�’�Ë”œ-×R]¹A;Ùçh'‡S¥­&ˆ]_ìì  Ïû¤Uy~~>~þüÙÚ|…ÎYTNÑÄÞðé%J«-Qß�­éþ3TŸg}¯{©ÍœÎý"9ÿÊNÇ{ ë&*_—O’õ‰?œãúoêìä*™ÒKù.ø¼³'ÊOP2¨ò¡NÜžnÔû¯„Ogº'Ýd€êRÌ®Mð§49œõ› ‘ƒ›]§ ‹«Ë•²:9ºˆáSTá8¿d\؈;Lê; ŒneLm,“r:YOœœ\¶Wßx�ŠzYuªOÊQôðŒd%§ªŸúïœu^.Ëàt�Ó쎴cyù:õÖU–�}»›¨ü’ó«ž©þ«:”­+ë´ÿw×.�’!õ ÕG”Žv¶³ƒ²UÊn%çF•ÁMÌTÿH619bœ>÷åd?Ô¯ ‡ÏоðxÂññ^w h¥5™ ¹ýÆ+ίúÿíÛ·ßlw¥çö¾;ßÓKmɺŸtÐù\Ž„›ÔÇa�™ŒO(;Ý__Sê����������/„Oß^‚׎eN3-Ç>1&³¢ kÝ1ƹ;¦[Í€;(&€eHqã˜ÊÇ,§šMs|UîîxÄ)S; £X*Ì£«of3ÁÏY‡Ò)õË[4&l¦“G•ÁLDb 0—AÁm὿ŠÁ`†Çµ]Õ)Ö‘ªÛÄæáRªÚÚ�ÛŸ0®ªã) {n¿éX8Ç×®Ï8f’ïsÛNû^ÇtsÚh³Ó>îé}wåPi¥wŽCŶc;yœ|'É�×N¿quŠÛHÙ¦$—ú¯ÀÛYî®]ëWQCëdKzëô{µsžÎöóu�Ëê½—´Åë¿V›Ú„ÛvÒ¯•¿£òáò%?ÈA‹ýŸÓ,°]FÖ{jŸ Ÿît»A°s~ Óå g$y°áx?9±ÊÑÆk'½4ØM$P~%·Ú³ê®�Üœn7Ð×µK�ËêÊîîŸAçxvy9�©gx?éÆAGT9èõëöm»ÿ+ÎÊÓM9>ÊÅGú9‡®òQº�ˆÓ2)ÿ«Í*/N§~'Ç 2*9˜ö•;gsâä(gÃ9".^§Ã˜ž³y\ß“#6ñ9:ª¬8Ýê^70^w.~9H?þ|“.£Úuâ(sœ[�Ê€íÇøÄ�®4YþTÖαN/¶ª{®Õ„'ÙÕ•ò©ô�SÎc¢›Ä±¬Êévc¢§íÇeêž±­Rû»Éévý*•�årÛK¾¢Ó½·—llllllllllÜÃt»k^‚¾•éVq]¸‰ Iî)CÏÌ�ccëf¦\ÇÐOØmWn…4#>Ž?™É³ m=ã%ÈÇ^8¦úìLšÓPú ˜NÕækæ^´sì!‡sÿ{¬ŽZK `ýâ²èqo f^Õs•?³¾îŸaJ\ì{ݱ�X§ê¹*¦åò®8pÉ¡SŽ,+ÏÔÑNÎ_'™8ÞWr+ÀÿÕ>nÞ•›;žëXékié:ÐT¾[ê鳩ÃÔÕ�:Â09Ý'gUnU‡ÎÐãçé²|l™z×"é7¢Ûšár ï_Ï'„¨�¬«O•W•çLc¹°-ÔD‚ïc^øßÉ�ʤÒãtÓi+ÇOå¥î¹c×:]ti§A??=�䤶prN�$¶¬sjLSaYßêWݯðîä ·}b¥Œ“³ù'zœÊ€8[÷œWš@áø[_?Å8]½¹þÏPºªl¥ów”£ÊžìQòá\ùÔD û!oŸý*øzolllllllll|1|:Ó�×j¦�Þž=ŽK‘fWyÓ­âá³î­ß Ó­XdÊÔì¯Êƒià’~bŒ'a\3#Çu?a½&¬Ë–Œ”ç”=p28}Lì6†ãSJ[?}qMáL\æe™™EQew«E•ž’©ÒrŒ4—ÇÙÇþ¹U.ç¯ÊÊý?}ˆ¯Ë^÷xëŠcÔ°ÿw«%ê>—W¡ë·¨›¨3®�9Í ™ì Ã1�.}nWd#üø1büRüN~›Ú•ÇÔõ¡«$›ê×SÖÚ½<9©+l3՗Ѿ8››甯ºæ´œd{‘úkê_�V¬s'ù>Û ÒRLwò}T:ÇñÖ¿ùªL÷§9Ý©]#©ðÇcbdUX·¬’äK§—¤A¯ñ2¶�Ïr¸òð^y5Ù¯­.˜—rÚ«�ÜÄÝ9%©/¹ºÄ²ò\7ù`¨¾—þO&ž¨¸¼x/i•Ií)M“™‰¬“8TÛ«�Ìð»CÜç&ùbœ´¯vbãñ>;Ï.^7>%=s}Ñ�'a·@9ãøn êOé™j#w _—w¥—Â(ß§œÜ3F76 <‰`Äø¼§û–>òøzÓ„����������/†Oß^âf«j9A1‰–`:3s2à9Äêwr�ä^]ncp}¹òàÌÒ•UÉëÂñ}µ„7eaßX†Ž™gy#›äSåq³k¾¯Ò`ö@1Ü\'x_m/˜°T®]Ýs8LóåååͶÇТ>¦å@dC•œêÃ4©¬,»cZPnÖ n/%»:ÅEåÏíˆåaýR vê¯\.ì„‘U}Ù1â¼ZÀ}oÂNV4\ÿ(ùVmiZ9Ž·a\.—ãz½Çñ¶/{Ü1»Êžtáβ«î¬xÌóׯ_öô Ì»c‡ÓsUÎIûª°XßΞ(6y*³“©³±«Œ³j[fºãïì7?S2ª0œ¶òcÔŠ׆g2Nó8„Pþ`­>Õ^Q{T|úö¾ÇÏVœWLgª„. ²JÙT9Ò€âŠïwJÌ`‡ sJ»m%*~gð9nrâ Ó#y²àdëätNwjWŽ‹ò¨p*æë޽â{ÊIê ÒtpVN¥2ì®.Ô22ocp:W29{œg•{2‰ÃçN7¸M”U&®õŒóNz?éç÷q+™JfÞ7�åqÏ.m”‡Ã%»šÞKH¿JÏÙK—7çƒqª‘£€q.—Ë›ø8èwm›Ê9½ß=say0ÞWúuÚçž‘‘ì‘‹«äÁöľ“âMdÇ8Üÿ•Í™¤ëÆ_ühN]—n©qãŒÎu“e[ª|+eÄx|�`;�is|O¶Ó=ÞähO�´Ë‘”Ä5®’aEîB÷2ÉJÇa9Uqþn?–«ã©W×XUV5À%ƒÞå›duŽ”r�ñsΡ’…Ãñ=®c%�ªoå¼$§»ÓoWþ¢�’ÉÅŽ­­�ƒÓfvãp¹�1VuÀ20ÃÎÆ99¶x�ÏpŸ:ï»D¤FåÃá0µŸžË®Úëeít�åpýÄ•ý8ôÊ„sR®ÿN‘Âb]b>Ê©)‹qê¥Êz‰å�|‘ð¬Ü(ÓÝd¯ìõ¤]¸~Ð(�N¡³½Ê±wýÛűõɆ­@éIº¿’Þ«û¥c�ÜÉî¤I$§¡d`ßbr4¬’Å�q«“–í+¾Lùµ¤ÝØØØØØØØØØø‚x¨í%êÏ´ –ò8‹´—¼“�\Jâ IDAT㨙ú¦[1®5ûtǪkÎÍD];u³W%ëÙ%1Ç‚'†~ÂtººKÏc¸ÂLpy”ÜŽíÁxêô�i¹8ÝtïÓíNÚHy"ˌ˪Óü;F‡e`FŽOaQyV>Ø�ŒÓ•'…å=ônÅ…Ÿ)ƶd�ØGÇê©:p« µ,?=Þ4mÂû«,æ”…EùŸŸŸ³�?þ´õ˜êØ­T8$=ïòÀ¸ÈÖc8<ͤ[�ÀxgƱ V™[~æÊ�XØd³Ýj¦y†åVi£oQ6ñõõõ÷•×ê* —Óä1�·Ùºq?•ÕùH¬3JŸ8ŽÛ^2éG�€‡z‘²s^�3àî)ãÀùqcªçInÎÛ�¿©:úê w µï’eëí._WF÷Œ¯•éœ%GºÆŽYiÕ²:†/G¦› ¨ü;Ý«ßÎ ð}·_Ðå£ÒKÿÕýäNŒ˜šd¥ ™’A½6ÉŸŒÎQzª& ©Ð6(ç,ÉQñ'Çèu“¬iÛb9}týÒÙ žLM0ÖoÕ/®-œã¢â¸~�Ž1Ûô+Üóóó›íEjL¨øéKŠF9@.ì¤LüÜýçö¶˜:V*ož|ºðgÒVaT¿McÄt‚ÀéNú[’“e˜ä‹N7Ë�Úe"àœïºæqUM”ÙQwyt>Īïó�î½½dcccccccccãÎøô)ݳ ëÝ-M—?”\ÓKðßw MbÑ&3`·ÜÂr¦ÿ“2¸_†š…»òL'« ëX8ÞNÀ:¤ØÖŽÉœê`·|[ò¨²ª�¸•ņLÙØŠïN"A¨å¿‚z!Q±ÒX>�a £˜?Ü¢RÏÝ)0ܪ…Ê»òç“B\8d—¦ö™HfœTûW8,?Ö¾T‰ù9Tåp}Ç1 NÖtü›Ã {È}Þ…QúU÷ÕV¨ËårüøñãwÚnŦûâè-XaøœÞ±ýVý_é©[!9Ã$ŸEÇþ®0÷·ÊÊmäXtǨ×VõÒvbúC¯dá8Ì,§ºì|:N�Ç*þíl'èúÞ£áÓ÷t;ã®¶o0Î(ç 9å`Ù”Ó뜒ºîŒÒÔ@áµgvj`œÓå&®|�#3 7‘5ÉÆ×j€ác³8MåHvõ˜–å&íËŽ5¶í¤¾Ü£òpeN“5�aÊ«róÞïiùØáQíZa” ×ëU:Ì]ßA¹/—‹¬7¡S§9L&0Ý=uß•AM |t£ë£É:¹œC dWõåô­Cêoì„ ¬j«Pj;œðà ¯ÆõþQê+JV…•º™8<ÉF*:§ý=l>ç§ÊÃaœÓ=M›Ñ9Ûª~nÕ[•7n39Ž|<^7Ît28]Wú�yv¾•ºf¹»ºãø(ßW9ÅäkH¹±±±±±±±±±ñ…ñáL·cM&,ó”éf¶ ü¦.§Ç³=^âU �c¹'eQ`¶�Ÿ%Ë™ÚB]#ËÑ…U,š+Ç�Èäž»3d‹íSÛ>\~\Ÿi[„c·£ÆL7ʖήÆ|“àê-½¼©XpÎG�—Ь2‰Ž�˜²3ÌÈ`[ºrt ý‰½¯tÕ©]¹cè€:ÝÙ*ŽWÀÕƒéŠâŒÜÉö©ù\Þ.7F(�át±½ÔJ€² øR%3oéãViKàj™SøÌ­T¨söÑî(œVf\Ý'9;Æ?•Kå•dÅzp_¸íÒSc{Çxsy\ùÜ*Ÿf2ñ#Rû¹>ÆíÅv^éSW�Ý}÷®”Gùlﱺr/|©=ÝŒ[+V)Ww* ;Ý'W£[Ž=TÆÄ�æÿ�ƒ©œÕÑ«S¸r¤¥ÆU:9Æ\ÊØ;Ç©ÊëÊÉÏ&†6µ­«GLÓ9…Éh£�RqU[+‡I=ãtØøaÚjOh92\ï\†Ôç�>+çÓ/‡.-—º¼J—Ôˆ�l;çt«A$}Á‘åQöĽÇzÛ ôªì ,ggû x�ù¸¹NWÓWG�\Ê'rÛiSù’/¥dO“ŒÏöü+àÓ™î®1”ázOg›eëö’'¹]>Ê@�)ƒrÆø7í“MF×9㇠;VÝ€ÆÎªì”ÌÉ!sr«¼ù^!¼‡L‚0»2WÚç ¤:`CËé)ù8mçtqºé¸Glg·—Õ± øÅ¾ºï͉>ðË2<v=ž®Oð}î¿îEQN{Â&;Âç<;çÏïMr”Û�ËÜ ˜ªÌî™KOé>×/:N>7THö¶sÊÙñ3|©ÏSONê©›\¿‡�u—VDP&tèÙ�Æ´[ÇgWŽJ;�] Ýx‹i»±�s7v¥ñ¯“1�Y,Ëqüc“­ëôxÅñgýq¶BÕ‰j«Iüä7`ZÌt×õ#~ïéÞØØØØØØØØØ¸3>õã8 Çt¯B-;%¦¢~'{#U¸Ž}áôY–[í]âràõ”P³G¼vlÆ”=š<ïfÞ®¾Ý}'ßK§a86Ú1êX¿$KÝŸ´W:‰eumÌLl'›ëFÝã6áÌS1çŽíM20xKɤN\}«~í˜.×æÈ‚–|N±fgl2;n›”[%Àën‹¦Ë6÷6«ºïú3wJOVà˜ù¤ûs¯îñêÏÊr7³úÓxTÛMlçqøc q‹¯F¬ÚùÉjVbŽÙÖ¸öDf:!Ù-–EÉu¦¿r:<ž¨ëú�ýWe'¦sãVwnõ}8=¾æ¸“ºdy’_ôˆøÔí%øËaÜÒâd+U|§�C§–XV˜ÎaUx~~~#¦ÅÁ-!Mu7ñ`¹UçPΫ+«2–ÉO& ªXF„Ú㦖Üù«u<@ò@ädìþ4i`ä#Ö’cTaœ3†y³l<ø&g¬s®p« ?SÛ"0\Õ÷ËËËx�Mz†v‡'ÎÑv}óB"`úâb‡n‚Ï[8¼zÁµkžÔ(G�ód'b21u×Ɇ%c2&p_vá8ÿJ»œne+ÔQ¥x�{¼'ކé¶.¹‰­ËÇí»çw$°ýS?p²¥ ™‹§äï&J©¯9{—ì ÷k•f—�Ë+Õ ÆqÛ~Òùê.'—µÛ^¢�Ú(Õcj?ƒ¦¶ëQðønlllllllll|q|ú‹”x¿c™ï-Wbòø¾c'ÿ§,2PÌT¢\ÝÌåWÿs?eº9ïÉj¦™Àåsòq›àÌݱ”êZ±Öª½Ý’«cõ&ÌM’ Û?­ `<ÎÓÕO×ÇpÛ€b3�¼õ%ÂúÅ—*1®K+�ÆáX¢Ž�Ie*ù¹íº£¹�Üj”Z rŒ‚ã¡nàV“§'½ÌÞõlsUæÊÂH³-Heç2rÞΨ8®¼g˜×”‡b¶“¬Évò˳˜g*›³Ë{©Æ©Î^VŸPùNÇ7%/ÞK}U=Wìm'�kËÔ'¹î&:£Ê¡ìt²}øïã—*U¹:Y;߀}·}Ê¥ÉåK¶Øµ™‹¯äã< ¿§û£óì T ×9ÝjOgR T"6èOí§ui¥œö!NŽ7tÎk‚3’JN×Q'{‚§Få~yy±{T9¾J_9�ÁKé°ÓÍù:6©L›¿Š‰§”¸|:ç>9Àjù]íÛTÆtRœg:2 ¯�C‘þ«�FMø= þMƒ‘+†K“×ÏÙΨpÜWø¬ptÈ\|®×nB òFY]œä4ás֟亴1<×�j󬓕¥rg[Ò˜†×N6nc ™qfòÂò$y•Ü©�¦Ú‰$Ÿ“a%�‰3ÌeÀ¸¸§»®A ê�a•·*«ú¿RÖtÍ2wõÊýÍ�†½½dcccccccccãÎøôí%j&Ô½°5™Á¤™NšÑ¥ÞŠ<8S+YÒÌÓAfAÍâxÆ;©.—]És³—¾º™õ*ëÍÌf’[•Á1”Ý=f™’þ¨gSü2gŠãX˜ çØOF±YÅœ liû2/(3›‰uvÛyø¿ZyQ/—b|Çð:ÆOõ_ΓóQzÀ¬ðDŸTZŽ…FÙ¸-Q¿#ËÏjéšÛrÚ?xõËžäwp«‰5saS«^JS2 xìRLwWn §V R¿)9RÞJõâò-ÛKVŸ;û_×.ï©L“¾çäá1ÖÙâé8íäHö›ý„ôÑg;:ù*m7æº8\>¿cÌUÚÊg[99è³ðiNwzv¶1n‘G¨ät»�[ ã–y0®;)C�XrKùÒ¤ÂÉÌpËScw‹�êÊÀÛx¦:²Ü îîh-üÏÛ4¸|xÍËÉnPÎæ¥dÂûîƒ#çr¹È¥{µíCɇP³KC ô%grâùšÁõ¥LNëGµãÔùTqP†4Hb8NÏå…eR§Å(»¡NÜPï8‡Y•/m‘Pm>í£X>”�‚”g¥Ãé¥ð©ñ³n{ N~ÜxÁi§É‚*—Q¥‘òFðŽ(›êS�e¨¾çÊÂáY†IŸäôø>Û�©­qm™â«ô”}u6¤ôìùùù�_©4Y ‹Ï”SëÆW®_výµ³±ßm/yTìí%wƧŸÓíž%zšÇ$œc°'LðqhŒñúúúK�f¶Ý¹“‰qD;Æ •©~Ýì:±US–�ï©2©%-%·*CDztò¨çéÔ”?‡wõ˜˜d|Æz�ì>¦ÍQçsºø‰áÔùc1®ýÓ}”‡™KüEöV1jJ6UõB22§‰)t:ïî'†áØnÇR+–Q•§â¨•%C=O/(ò*’b9ü„ÍR2!\¿pËîi;¶ ¿ÔºÂÌr¶ß®ï8ýSi«ë„Ô_ùJSÕ±ú®�ÓÁIº]fXWÒ;#Cb ™ÉW¶Eõ‰ ;îî³lÌöò ¯ªÍ‹žþc>iÜUqø×Å?Óÿ0�¯Ât¨ÓíZ]O µºŸ*¼sP�C7�¸�Ç)5Ìnù†åqxêÉÑîÏ„©Óý^Pƒ櫌Պ¡åðºúàr–sɬ:ÇQ«?8`ºÓP/µª8“U+õœz´â+ÇÖå¯Ê e«ØIåû¯¯ù}€YÒ$ªž³^$}RûÊSÝJ…zP• Óf}vúíÆ•Ê×Ùb×Þ¬n ™8IÊ)QvK•½“'íÕ_�P8y&ãAšÀ8taø¾rþ�Ã÷QNßÙÖ=Ÿ8Þì3 ½s/—s|7)ç~bÏ1Îd,Wes>‰Óï¯Âtï=ÝwƇo/™Îz>jÆ’XÅL$Ɖ1™ù+FNå…2tLBbº§,qw?…›°Þi JÁ•©€,WÇÈ2óÖ±¯ŠÁVy%&ϱ:iŸ$/‘1cå˜JË©êEs–˜0†ÚW«Ø•žc³Ü±jÌ$ᶬo>*Ï1÷ê—óU:¢X"ÅŽbx÷‘)L›—±ÝVÜžX!÷ŸåámŽe-õ{¾§ê1±ñªŽ;{ëVrØf8]Ví§äq`}vìvßélÍdÜJåã|ñ>2¥Io]n�c¿“=è®]ºuŸõC¥ÿô”¿òšä :Uò ½­-&Çñö¶·é¾Ê»ò™œ€åî�õóRuL÷´?ŸúEʤü‘¯2��BT‡S ê @…w w÷"Ž*Cr\8üT)Ï*kçøMÓLް{æ\•¯«¯äLó ‰“r¸ä’3Ä÷�²Þ¨3®U>XGj‰˜¿@É{Ù1>;‘G[•‘ãL¿Rèœ NÏ ~�S£ädyR8L�W§õ¿;fO•ÇémJ§®ñhÁ²U®¾Y6Ôïξ•Î9{ÖÞ`Zêe\Dõ•n²€i­ÊÕõÖ[gÃÕ}øß‘3˜ÿœ¾Û …:ܽЯîMíÂtìëò›È‘Ê Û$C»œL)üd,N>Äóóóq½^c>*�³¹Jîät«1�åJàtÒ„à‘°·—llllllllllÜŸ¶½¤›¹p Ån®ÌpÔl)ɳ’—{ኞ©M˜nWWõ汫»÷b¾ ŽIJÿùþdví–A;¨:vŒ³º®Ì`¥ÓOÒj ¶†ÃÿŽéJì!³`|d\Ç*ì̲ªbå�EG™ê³:N•�YËÄR©ÿ)\ª+,.óª¼\�IF]êú,–ubCQN¯ðŠ ¶Ë¤ÿM_VåzœØtÅÔrPvŽ3I··_·¥D�-“þ›är¶)±À¼�Äm…Â8)=5¶89ÕýTGS(›Ëõ�ôÎéª{–äwãÉÊ*æÃL7žd¢Òà1-µmbªR8.¯k³©½dçñ©ÛKŽ£wW ¤KÛ=O�{".óñ}µÄÊi aVޱÔº2©´+Ý®c)§dª¼+†V-©N œË“ïu†Cåëâ¨Sº“Ôd¡›ä¤åRÔ3•';‚ê>—½«'‹ºŸœÙÎiåpøE5î_Î6°óŽy¨“D* ¦ŸôŒ·”©÷+”㙎[S@ÝÂòp�pU÷]¿AYq8þ^.—ßûCQU–év ÷µ¼©Sáú+·1N غÉçWqÒ‰ÎÙoìç\~¶ |aê r»%=Æûˆ]›ÈÁýÚ9ˆ“´»ÉŠj‹$›¯8ŒB²ÅJ^΃m•?•l|šÉqüÙÎþ 0Ê5±¿*†QºâxNÃÝSýMõ½GÃcJµ±±±±±±±±±ñá!O/éf뫌7çÓͺ”±G.ÙªnLri'ýQð0{º]åuP‡2¤cÅi rM7x¢sÆŽ±{yÒ-=*™QîÎØ¦{j tNÝ*:ÞuÐÕ’öÙA[¥Ã÷RøãÐûE“xF¶dÈÙqT{øT¾ìˆ`¸Îy�\%ïĘbšI×¹,,Ê:©~ÑÈõ¼NÇâ/ëç«êÕÕ —ƒÛnªki’�å«/Ú½¾þû‚eÕiWß\v'ƒ*wªW–¹+£û‚kšGvhU� �Ÿ¶‰JSÝsÛex+�s¬___ÿ˜©>’œÃÉÄAa:¶8¹§yrÿRöõ¶'SÚê™ 7™0ªtÔ³$›:>Ð}I¶þ×=·5�1 —ã3¾Å$½Gsº÷ö’����������;ãaŽ ¬ç*ÜÙÐÊRL—§c°j®f׉õ^™éb\üUr­°(g–'åqÿ™ÅqoÖw,C’ŸMÊ— ÷""·sz¡EéXwê2ŽQcFÙLfq]_Xaµùš�Ct/¾ªk¥Ó(NÏ}°‚ÙMuŸŸ9¬öž²±ê…K–�uK-';–Øl.«cò u²ŽÒI'O¥åXT.·JcÚæ�mpicZ.O7Ž©²M™· “‹qÕ–îsªÏ3Ó�õµ²š t-1ô+˜¬Êœ•Gåãô%É5Íw:.%;ÌáS{±Q×5uö�Ó^ñO˜Õï˜iuzЪ§Ò~$|ˆÓ=)t2d.�®1Tzî,ÍÊÒPÎ wË]IÙðz¢l\•¦qÆY®xXÖ[˜å:ã컳F±|É)Mi»ö›êŸJÀG/¡ð—û¨X'f 4J__ý—/ii×9îª\x÷»8<ˆ»#'ï¨pþ©ª.¦Ž §—¶¾ ò)<†í£rüœÞ©qoâÔ°N§¶Ä{Ê©)ý[q°ùrJ�­pc~Êk’§Ë«“gŠé¸<•‰Ótú}v wNwú‚¬z/@µ‰ó—&¶0Åá|Rº�_õhØÛK6666666666îŒO;½dÊ$w˜Îþ¦K"j––y\>Èö¤.—cÕ±Ó, ¿Œ©ä9‹ÕÕ…I“ðÜ•¯{á/¥1aq’ÌnéO�Ð4KO2'¹ù¬pd½˜åF6 ™\~‘†0ոŹTÈò»ò8…ÓÃSX\ýps}V1Žné“eR2²>òг‰¿ÒE[á®ÒÖüÅ:I+FÌ‚bL ?ÞÄõêØÞtj×ObH»0)mþŸ¾XYù¹1IõY–“ÿ³ž&9U~%çÔæ«�Zaû+¦{Âz¯Œ½»Ù�©je©“U±Ä¥›ïÉ‚rþ“´ÝŠÈ´LÓågJÔ™ÿiåÄé®[ â_wÍùLõ«³óu}«/ô^øÔÓK¦ àð^Ë<œýŸ.cb¥¬Éé>Ž?—'§–`Zîíõ3J› Ád²1Ejën‰tšçĨ¹�æ¬òÞ\eøÑ9›~: 4ÊÙ;Ž?÷Ã???Û“_ÐÉÂçÝ (\6Î7 ˜¼dï&ÆX&U•'Cé­ZÚW'Yà¤�ÛèõõõÍçÝ]ž(·Ó5N;íÝg8'®›´Ož)§›í¨¨®QnÐQ± J†‰3;±;É‘qúÉu� çŒÔ3W�In¶ùgÒP?œè¥c]yÒ½4©@tNWÁ}D+ÙïÔæïáp»òsÙ;�Hé%Y]yºúVcƒòuêo“œ”Å�õët8Ù×ÿSÿèÒý,ìí%wƇ¾HÙÍ8Ò é–|§axæ5™}º™7/©ñR¿z)åé Xî[Ù[‡n¡ê1±3® ÝÒçêêHÂt *±›x�Y&õRœzùo•©d.f‚Ù:d·\}ªgŽYÂ<Ï0*�T6•Þ*krúÃ.õ‹mTõÈuÆ[3œÍà“Z&ì?‚uFɫʦ˜M%Ÿëž;ýBå‹/_¥Sj�Es2LðÎV«úæ°N×1~ɬL•§ Ç,ÜdiåcR>¼J�Œ6懫5É R87~»pÞ±Â�ÝXÅ™±b26°ü¯•þt+I禲:äS…0µ-N¥�ý_Ùb•¶Òç)k�iMYô÷Ô¡[ðáÛK¦Ë%i�8%oRÙÜ€�í±SãÊäŽ{Béò­kuƒ’Áʤ-’£½b8]–�—âØ@©ÁÐóŠŸîSç„ï¡ÜîÃ)jBvÿ~%lE_ùÿóó³ÜßÍò`>lÕi*ÞçÓ+\� œ>²^àoÒ¹d7œ3å&@<ˆÇ¿N"ïãîòà´U«¶À<]{W\7Øp[º99;¦êã׳ëõúæyMXÔ6”U�¦Qu0ù²bªÿ®�ªgüje•ÁÙ1'ÓÄ1Ÿ¦Uò­œ$~§× IDATTõ«ôŽ÷Ö¿‡�Ÿ”Á=Sc|71�:Q]]ÝZ¾iÞ WÿiÜš”%Õ‹²ê˜b5p¸4™J~ŽwÎn¥qCåÙ•õ‘ðé_¤¼g‡èœ3^=Cc—Àç£R³¡uG )y“œÉX�A×i'†zÚÜdê8ÛÑ�<®ÝøY×�C°Z§ÕÎ�Rz’&]J&Ôo·WóæI¡›Èpy»Á/µ¥rÔ]ÚØ_ð9³­˜¯c­“Þ°Ó­êñ8üþü ¦6‡õeÀûÝ1s˜÷±t4˦pÕ^¬#8€òäE½TËò$½w{ÿWÆÖG§û.¢cþ'N·Ó[çÆG7 ãöGùåIžÔL&# <�uÏÒ€á;»“dK“®ÉX>Í'…í&Ê]ÚÉ7Hí¯þs8ÔAu~>æë¾=¡äpPz>�|ª1Ä¥ÑåóØ{º7666666666ÚÓ­â(Lf�ƒ¾.™dxx†é«í!2KulF‡Ä¾T:“4ϰénVÊi2ÛçòKLù”ÝÆ°îx´*¯bÜGó“òà•“‚Ò5–G1|˜¶bÞUXž¤ƒ®Ý¦K…‰mÅzÀýëÌ b[bZ\—vÇ*ù'åKá³Tep «»_õá˜n×nü?m/Q,êõz}SwØ&¼‡YÉ®tGõ� [­â8öžËÆqÔX�+ *�n)�YWÇÊ©¾æX=מx�cn¥ap'{œpvU‚å~�<™íN,êJ¾ªî][®Ú g'r¸0¨ƒ®O¨Õ¨•1Äé¨ ‡ÿWWRÚ�†Oß^R˜,5¬Vdj”ºž.U&™Ò>îúåó¸»/=9y1½NÖ3†ŠÓI¼Ë_Ýwmœ–�\tNÚŠ±dè¶€¬8�l41 u¿ò™´?ꀸ�ã­#¤.å¤ò¦Åí_OP†ßå¥^Òsל^šD8›¢ôÞ9á]|þÏõ›œ@§3ü ÃO¬èœMœl£_¿~ýþÚ©zEí+g‡|jù¹šh1&_¡ä´ÓÀÏåêœx¾¯œ½©l)œªC÷uQ—>Û­)*ìÊVv0'N÷ªcÅeYñ)\¿LýÃÉé&0�¢Æ —®û_¿Îáe™œÀùªÿê~ç€w2¸±*Ý$|o/ÙØØØØØØØØØ¸3>t{Éê³gØÖÄF¯À±‰jy›g’g^䘲ÄiFÎùpœ[sU×,Wгòñf:vL±‚c*OZ%(V™²§§Žû+–¡¶�ðÖŠž²�Œ%–éÛ·ood@F%½„¨î'ÆF1:øL½PœXs΃™îîTfûx û2®zà3þÀ‹oWêô‘ˇàúI/'¢sY»—*UzjK‘jsUǸu�_ªtÇ.ª¯Vv'™LmKz¦˜E ïŽDsÇ#:]MR« *\÷yÇÐ"X&W†„)CßµU²�I>—Ç™ñ+­‚q>i% ­"¸|ù¥iN«®•n¤U0~ÎvõFÅQ+%j|Ÿúe�NÒä{�†OÛ^✠ú휵IÚ.�‰rpzi™G ÀÊÉÆÿ«F!9Ý Ó´Ýý•�kÒf\†UcêÒæ6rŽÛ{wF§«jàÀk%O}îχv* ˆ2¸¯Î¥ÉM7¸`zn[§Ÿœ#î+ù¸´ªîÔ€…Î&Ÿ}í&W|7OD&Ç#ªÿ,Û¤Þ1?•†å£ ÝÙÕGTZ.Ÿ©†qÐé®öAÇÛÕ©“‰÷¶cã~˜tß9¢i2¤Ú’�ïT—ª¿ÕµsDÏØ|nW×÷Ý—''�¸²ñ5;¯)ËÒµ›’'ùI¾ºïƉäIÛŒ•|W&j¶¨fÉ.=çQ°2cMq³á˜ô…-·ÜVá0Î-KšYGL›™Ifk1mduy[–Y]Ö'µôݕѱºÌ ³ÞvìÖÕóóó–ˆÙ fQUIË¥ÜûËu\ÏÔÛR^¦äì¶«0 ‹u¤¶}”lÜžg˜SW¾Ž©¬ëÚÆÄ'Ì\.—7_E,”þ¸¶Pgø3ˈõ¥ê^Õ�O.,dŠÙn÷Áì¯W·Ôi1«‡uÃ[¤:{ÅaÜi&l'è˜hÕ'Ô=§äYÑå ãÚ=[ÜsÅt§¼qK ËO¥5]y™œ×îôiÂR»|ñ:� _ýïü¥GÀ§îéž’edSþ+†c¢.;®¬“Άi° ·–eU…ä'G4ÅIƒ¤È”¡9ãø+™º%M×?´ù~éM9œ•ÞOû¸•aæãñعg§fÒ/Ù¡Ä2ñ~h”Á9,jà­ýËÉPc>ÎЪ2°Ž±ÃÂH_W¬{O¥—&œN×XïYnµ¯¸³É)Uq¦6–Ó©ë:%‡·IÕ3,×õÔ)SùrØÉ�ÊÊúÍí¢NiA(½íƱÎ�p:¼â$¥I¡’mâütò¯nqrÏUÚN6¿ 7 “t+õéïã¶µ%y\8çðºqUéSÒUõÅœø8.m%Ã->Î{âaŽ DL {¶«dVH4*]'Pƒ©SÜãè� ìÊ d�`ªä*|b…Î䉨ºvõÅàýµ,ã Ò7Ñ™©‘ưìhóþU¼ÆÁw|qÌ———7N·zA­òW(çÃŽ„Ò‰ä¨qÚ(‹è'NrÁ±ÞìàcÝc8ž` ,ª ü›Ž#TeS×În`Ø4ˆ¤A—ËÐ9ôÓßÉÖ…g‡W1T�°�¨2(ÆY Ôi’ãîq{¸úWvIõ+·ÂpM�n¼ÆÕ-œäLœ3å(ºWÏ8¥Î¶s¹“< ©]&ŽžK㬤³âp§qd¥�:¹Ó$ï¡íì^¤Á±‚Ûß]OføÌ(pÔò´ªÓËåß.ÊÛ4�ѽ±Jîª+ÅóÊ—Ÿ«|Xvfº;öb\ÅvsùRß›l]`6e(ö‡óáãÚººrL�“™Ë79©#±‚ø¡¤Ô.+ìÊ‹rºã2™is,¸êSŠt}�åžØ�dÓÜŠ׫ʟ÷¯³nMÆ7µ¥¤î³|Ó>‡ t÷.’‚c0¹�œís÷T'˪?Ñ¥•Æ/•oj¿´ª“V'T=žµ£«c3Ý.½U9ðZõÅ.Ý4þ>"Æéf¬:SÇ‘—R¦Ë]¾IÑ•£]÷§gs;ÇÁ幂÷TÄd€±¾�36]ú)#”œN'9ðêw_¥? 7I»{q±œn• äèt»²sò±m¨·©<“>á&L©~Y7œÓîöm'}â=³…Î1žô?î¯<àvëïÔç>†NÒ¤o±áœ"WÖ)”œ¸ÊMþø³éè�»:eÙ&g’¯lŸPN–§î£LÕÏ8†Ç­‡¼Õ‹Ë§&übïäÈ@5VºpjB Ê‘Ve“º—�Ýýä,b˜[Æ;Ž?Õ}çœ;Û‘®WœMγsŒ•]ŸÖ«“!Ýëäïü§'§}E¦�ÀÞ^²±±±±±±±±±qg<ü)Wf+¶›¹�a6s X*wÍy§™âDî3³Ê)º÷*›¬X|UV÷"GA½(8-ßÊjÁ”¥pl{ª•6ßC O2)6 ™îU–ˆHf•|Î1Úœ³í“6s'ž¤~åXyÇ”2Ø}PIé'¦Ím™^Òä:âr«òpfí]8LÏé4ÛJÕÇÒµƒ²{XߥøòR+j êO:/Õ÷Ì1‰Ì8»ôxņ¯QßSžO½<‰Ì´ÒïÄ,;{Žñy«‰¿Rçþçò»Îtis»®ŒÅJ†ôÜ�Y»¶Ra¹½Òj^OOCRà2&_b…aÇ4;¶�ý‡~Ý‚‡Ù^r–þÇŠœ*)")Rr*U8t’P�º­%Nù]˜)nuè'éaÕùSGš ~]GOΫJ'åáâ*ãÙé+;˜ÎAíœ<Ô!vVÔÇS=ám˜7Á±;w˜÷àr™PNt08,Þc§[õ+5¸«¶LzÆeRñ»(ÜD„¬ät;Y“þ£>¨ûªnT]°ít}6õe•Ÿ’�BvîQ/Òé3ª¾UK}aºÝÏ•áòt_1UŽž]~½^�ãxëärwû¸1íÎÉU˜Ø­©.LÄÎwÏÜ$Óîá”Vç´u¯KßåÃõ–&9]Yœ]èÒq圤áÊÊiLÛ Ó`Îú”÷ÆÞ^²±±±±±±±±±qg< Ó}=S¢Ð1Ôü¿›AM—735eáRþ+³½é,•eMa““¡L.ߎiWi8ÖÊ1“ŠEžB19ޱVá«0)ÃqdFì8þa³®×ëxK�ºFÏK®pøËË×U† ÓÍl&¦…¬>¦Å+H*ŽÓþß½hèØm×F®û0 §—dp aÙMŽ[÷•ªëÄ:ªíJF‡¤w,¿Š[í^qT¿TéNVÆVÙ°Ž‘�ØA¬ÇççgÛføuJ–Ót[EÒö)wíòRåà“zœn¸±�ó�¬þ¼'¦ì)cêC¤±ÂÉàV™ø ”ɯÁ´ÒŠV*Oç­´Qg»* ûΞ£ž¸þ;¹~|øgà'÷>JµÜæœÂÉÒ;«K˜ÉMÎÏj· 9¢®c(C ~ÊóÀÁé¨eÃÉd…ã¯>K²táR8½{}}•N–‚’ƒ÷cÕW1¾úÈ {†i»ý¬jpwƒ€ê{5À¥>:é?ìЫ:®z©pi�³ûP‡Uà¯Iº¸jr§s8gÏÕqšHv}¶+g*?ê:‹ÕÖè|¸“?0ÿtœY‚ÓÛIü´�;}è&}r[}]´ê ú`·�¯§N·²íʹSHN·Ó[Ž3³Òøy«2`ÄtLrýUÅUÑ.§�Ϋ4;?îlšØo*Ç#`o/ÙØØØØØØØØØ¸3j{‰Cš½Ü2ÃCtŒgZšAFƱpÙx‰%ÉÅŒå„qXa[UÞi¶>e†ø™û(§Ý1ŠÝ[‰£žMX�ô,±°‰ÃgÈn#ËåØ�¤«øåQ§TîÜ`¬Ç1jé…ËJÓÃk|¦V���Ç{•¯Zªd¦O�ÁðŠA�°9Ž©N,£ëû¬i{ˆméäuårvŒå]a©¸n+nÍIö*õ#UgÉ>NítZM˜ÈÂÿùãJ�¬éÌq÷²s¥=y™×!ÙNg—Õ¦úâTžÉøv/Ü’ïdçç+ã£êol¿�<*^ ÛÉíâ¤q�ós}~ºš²âw|&îît¯TDç@OÌJC²éà§ÒÃç.må€OÑí„é2ØåëÚe¥§aØQ›ãœ©–Í-ߥÜíéÅgõ¿ÀÇ…¡~¢£íöSN ›’[9Ö•¾ûBžÚŸ]u¥NPàüxO5n%ÀûìdãщêX5U¶n@ç¶bç‡í„›äp¾X�ˆ‰-t“EçÄ8YU~///r¿p’1Ù4n³nRÉpuWýW9©¨[�£Ÿl¢»‡qÒ:•Ã…Uú¨¶}á–Œ«Úý8²#ëtƒÁ㘃’©â¸øh¦NØ R¾|ÿÌ8Õå=©SÏÅÁ0Ø÷x{Ÿ³É(¹Wêàl}­NòRrý²³�‚O?§[…™ïiÅv³õ.N§0j·:ëX¨$Ÿ’w%|vRÆÎ¨¤¸)ÎÊ1Š+éºÿ«�09V˜Vvž&áø%ÁÊïååE:„Ìþ:“Û79�˜§sÌØⲩô”‘T=× ÷)wd ÓtDxß¶ËëÛ·o¿�kÃ2¨ÿÎÉåvp΢KŸ§AÛ9S,£r¼Q®Ê/å£t•Û|2àu}eç/Rº "—AMŒVäHÎ;†qõíVœ=©‰':¥Ê6ò*§}«Ó�0�ü©ºS_}}/y’]Æç©uy¼'R=vùUßëÆ¥ ›ì_¯8ÄS;ÁÏRš˜¶J#�[),§õ(ŽøÞÓ½±±±±±±±±±qg|‰=݈4Û*$†je¶ã˜ÜÄð 9‘IÍî:91¨gÙu\2Té­®npÚ·.Ar½(6ò ¦,™Ú²¡Úìr¹üÁ,#ë…_åãôU¾Že`æ=éçËË‹d–1×ãDª]Ãâú‘;ˆÓbMµUÇ TÚÈx×3þÂ$æËyò›³,—ªc¥ÛJ§Ó=Ǩvò8öÈÙÁ$“êŸxíX+Þû�a\ŸŸØ#¬g?&iLØr–õF½CÁ+ h¹ýÏ2Én%fuÜàzSì¹Én¨û©<ÍÛrU?ê—mî­cø„éîlèä¾Ë£Ó³UòžþÍ=ñ0N÷™JzG��Á-K.|=]Va¬¦'\)¦s„ª ÎÁHiw÷ÙÃ4»x Õ9ïáÌ»ÎÎûÑ‘T×Ußøy÷©n)GDMôºzäA'OOOoþ£œ˜;“Á< :¸�—XÙ0óŽîË— ˜¿¼Við —®/ð3ÕFÜV¼L[÷Ñ[�z·€óÁûê™ê—ì,¦¾Ÿú^ê�ªÿrÿâIi7ð&{{Ö1šŽNO\=ª ÝÄ^²n:›íÊÊ:ˆ²òu²í� ·Úâédj%½ô1Û¹¬Î÷pi+y¦ßètÿl½�­ónÌú´’ÇWq¶ {{ÉÆÆÆÆÆÆÆÆÆÆ�ñ0L7‚™×3Œ•ÃJ|Ç´¸eœ‰vL·Š¿‚)ݱŒ¬Ój‚¡Âá}þh;Äœ^7qLÿU»¸/ r^® Éùa]àcêº>Ï×êc`JN÷|Ũ°uÂMç@wy8]@Ýrú�ÊÄéMÛ…O@êöõOõÑÉ5 £dSr¦>Í“s' —ƒõèVk¢3+“ω®NmÊYßã&ÝçüÎæ�é$G{Å×û Ž6âK9Ý…‰bŸ18l°&3<œÓìÕ9«ƒéj¹Ôµ{†uà˜¶./7;îVg¼&†çVéòUñ”sˆŽ5ÞcÝP2àW'ùyçð`;©zP_�Ti§�ã0ÛËŸj¯—kQáJ¦bä9^åãöµ¾¼¼üNÛɪ&à ÊUeÅ4ø] ÖãÔ^Ü.Ù{e�\ùUZÉQPñùìkOåÃ2$§«K;ÙN‡«:¸âÓéýd‚Àu¿jk’SÉår,1ç™Úžï«ÿg ìz];Ý/tÎ÷ÔI] 3Ic5�i½&Ûr&OnÛÕ~ŽaUzݵjó•±�û[çC¤°«Ï>{O÷ÆÆÆÆÆÆÆÆÆÆ�ñáL÷G.MY† �ÇrñWÝlï,²žÅÊ,óž°íÝìy"w'Û´ìïµ”8M³«WÕæŠÙÄ£ µGø8Þn)I,,Ÿ<Ñ1¬,·iÇøb¾Ì:«ðÈT???ÿ>ñWÓ�l²ªÓú@²úJVµú NêHåå>àÚ–u?­Ú¨Õw�ñtmÄm¬¶óteEyTÚuÊT;ÆÛ±úi…¥«S~†rÖªÎê‘­./®S Ã'ò¸´[Ǻ öçNÆ0NïÞ8³¢¢â«ç©/'Lêh•Q_W�<É7pé»>:�? ŸlÇq>ƒkË´ÂÃ}~ÚænŒægù>Ÿ¶½äÌ’ƒŠ7í@êZ9žnù.-{Lœn×§MJãž5Îg,¥•Ê—œ 'Ãjþ*ß.þÏåéY÷ÿ8þu¸Ý’ÎyM˘ÜFêhAÞ²�à½Ù“zN}�KûxÆ5;BüuIw�yâ$ë;‡÷\¿VeQ]…QÛ_Ò1š©¾0þtpHiLœFÒ­®/V¿îœJ—ßD®édé8þ¬G>{Üå‘lþçsÓ„®«w–ÕÕ·ÚÞ×ÕÍ=�o5qt(Dçx¯ÊàÒ]�ßa꣤±wÕÇ鯭‰ƒy¦Ÿ¥6b{r¦ýº1¶s ”=ü¨Éç-ØÛK66666666663Ý+ÌéÓ™^ZšÃ2¸½¤[Öé–\ÔÌñ£gaFö8z&P¥y†�NÌAÇŽ¸4o¿„8e®ÒÊÇq°Ü˜6ÿåбÞõYfֹͻÓ˜Áâ|‘]åxÈTÿþýw8f qË�;É„Ë]ÛUžžžÞ¼TÉ2tm©â¸¶`[ÐoÈõÄeW[cxn»ƒksî‹N·ÜuZeRÿ9~‡‰=ÀöV ý”¥LõP¿©_qxggù„'7ök~©vÂ6®Úè)ØÖájPǼŸY˜„›²è“4¦mº‚I|Ô‡nåÅéÛµýÄ6VÚ<ÖMÇðîžòO&¾Ô*�ÿÔÓKÎVædÙa’¶2"jðc§•|2Ð×3µÕ@98¨l�‚¯,ùL:Ì{ê$KçTrx—Î4}—rêK‘œnúü5žÅÍòá— UO� v(W=CÝ8ãäLœîµ÷ºþW=\.—7[Cp ~ªÝõ�rÑñUŸ/ï%»ú{A}u²Òî¶µTiå°j°L“@×wXŸØ1í ÚûŒMèÊ»š·3_‡ï¿�N¨þÒ9 ˜¶;ŸóEÇHM˜+t´“ÓíìÓª=é ê1M:`87&N0ž°Nì§Ãm>™Ì¸²¨ÿ·ÂõE7É­òLt>µ�Ÿ¦7×ï¤î8׿)ÎWÀÞ^²±±±±±±±±±qg|(Ó=�±Lg‹ÝÌ«›ól*½•–X&Ì;畘”nIêÌl:Í4§çqwL¾‚›A§´óŸòt¬�’!åë¶àµkÿççç?N½)Ô×&•Œ“~¡fþŠ©pl_…Q †b¹ÝŠþÇòàÇqp ^—lîËœ ªO:6’ÛE1“ü%·ÄsY1=üR Ê“Ùº¤ÓÜ~ŠYš2x,禛ÿ«:Qá&+"+«/N¾Ô×Õ5N¨>çúDýŸÚ¾•ÕN—uO9rŒ¿“g¥®SZéË®Ý`]w}t"[7n$»íÒä4\˜Õ1Òåé|‘NždCØfœéë jìSÏœ^¤p+m¾¶Kû³ñ¥>ŽÓU>Ã�^Õœ®‰<�Ñïdš¤æÙ´~ºA[•Í Œ©ÓNô÷îLÝ—»Fyð¨<.š*=¾—žaÚj›…›8ð@ÀqøÚ{%Oå©ê ·“ðqœø åF`ù~œåœL^ºÓ!Ô䦠NZQo41§‡jKBçøã„£dLñùª¯dß”ã]é!\ìlNÀ“!Ö“ÎñëL×W'öVÝWý퇪{g'¸¾§ö]ÝK_uN·’gÅnŸµñ«ù¼Wz«ýÙÉ�#YÏ“=I6¿“¿ó¿T?êÒž8õï1q|$ìí%wƇ3ÝÝ LauÆ3IÓÅð›[Ì&2¤Ùïj¹VÒŸ2P)nb0:f*¥½RS&âÌÊBbx±ýë…@f…~ýúõûåÉN¾ãøwkAW&®[–9�f‚y&æ•ﳬŽñd ›Í ÂUÎwÂÈb8õÉ{%÷ÓÓ“Ý^âØvÅF«^I,7Ëàâa>Åz*¶KAõÁÎ^u¶61›]_^e«U=0‹–V‡ª¾pëSê_N&vî8tÝNÇ.¥“|š–c:Ý‹½Še^e49Ì™³þ“ýu:q ÛÍñSÚ++7Ó~çäJ+)NV·j‘V°ýÜj�Ë#ÉS骶™ŽÓ¼'ã ‹÷èø§{ÕØ:p£§AóU ïdt‹óLÆ^ÅùHLòMu•ÒMvtWßïa\•Ѽ¥Ž§‘ú¹\ìQr///£Á¾Ë‹eä0¾SÉ“òqÎ?l2) IDAT‹�R|õL9Ú¸%M9Ý(ê·³Ã�==ýÞÃ­ŽºS'q$Ö Íérg:rŽOqË“ŽÁrìîÛærp»"‹v½^ß|8ÇíÏVyªrW\–Õéq•™EUÖŽB[�¶%–)}ð‡ãÔ}חݪo³Hû»Ó‰×êk£*>§ãòKìX§ Ëhry¸>1µ·ÌÞ»´k\×¼õH�ã¨>¯ôÄ•3Ù_ÖÑ ãØö·Œ‡ª�ÜïÁ€ª>–lÓ¤LJîÔ'éqZ¨ãNŸ\yS>µi+eàpª-SÿséMï>tO÷{„;SyjùEåé–\”!땉1ŸÊîÒDtõâ:œÊc²Ü¤Ò»u¹h*Ã-˜8�õë–¯ØáfGÄ¥=1Úiàp†ˆÛ�a0�ÞÞ2–,“—ôPn>NPÕ÷Êç¯ybƒeruÅKøøLɯž»—A1çã2~ V9ÝUž4i¼U¹x¢„ñ';Ýgú¬Óï©#ÍiMÀG ª>Ç`Ýv¶Ž'•¹ªN•ó¢&�êÞWN¿ê©Œ,¿³iéÊgÒ¾,ë½Æ'sWV‡•~ÐÕƒò!&v�Ÿ«þßÙ·é$ÓUåYõKœ<ÓôÎæõ‘ØÛK6666666666‘rºæSÉTáœ<Ž®p�Íef[•§Ð�¶“Ê ¶i¹zr ½[ º*Ÿ3mÞåqfÅ„óéXè¹§i;$8G'¶.­þ¤|“NŸ)ë„ÕŸ®,|¤?ÖáaœîÉ 2u°T·\Êy¸´¹“¹}{o5^�²ºdƒ÷»¸Î‘˜,‘�™¨¼GNi¦¥fls<­„>·äëòuúÈ÷ðYw ”j·¤›ÝùÝÝÒ®r¬°ŽÒ1Š*÷yö’§[epYÃbZ¼lÞ D ¼G:-û»ô°¾Qî4ð°œg&¶ÆÉçmud ÚÂtÆùYq¾ØnuyqÛói&J®7©Pm¤ÒæûJ'»8X–©óä œ,ÕÏÚÞÎiraÞÓ™b{rÓx™&üÉŽeK}Y…W÷øKÁ“üÓØçÒXѧäGLœóGÂÞ^²±±±±±±±±±qg|ê‹”g—soY†tÌKb ë�2¸8·Î¨ïÅè¾Gz+iß’÷GÌ^•>áu�/�aÓW 1ÝŽéR¬°jL+�'�q0\•ã¹'ºËrs}©¾Å/±Çq|ÿþý�ôø£ SÆG}´®‘�äs�ë“Ê_²œégie Ûë4É8YiâÿJ”LNFþ ÊÝ�d’Ê¢X6–myj3~¦VÜê�²ù†u¡“[±Ün A{“ú=§Wà$„[½KL7ÊÖÉ1 wf,Ÿ¤‡×jEdŠÉJÕ ¾N_µ© ì%?ŸÈæ˜e·â6±�³íü‘x˜í%Œ[+m¢ÔÊј83ÎéæÁ}EV–g‡¡Œ.?çø+ƒ×D†îÙ ÜòqÊ£3NiyJ]???ÿGÃÔéœsΓœJ7¸�\yÕçàÓ§ª1µ} õ›?=�Î;äèt#p_-§ç޹JûXy¿ºûò%¦­ •¯Ë˵’Ü'±.œ#Ìò$}Röˆ�EçTªø�®²ÓÍ“Bå ª2(Çewù'¹TùT~ÇqØýÝl x"©&˜ì@»¶T²w[ӦޔÃ&“”á̧Þ'áSG½ò�ÆÃðJoS^X�z¦:ç¾ÒueÇ{�Ý`¨:˜ô¼Ne]ÚN¾îz‚GqÄ÷ö’����������;ãa™î{a:íïÉŒ‹�÷ZBšÊ{vV˜¦)C»š/Ï€'ìb9R=N™nÜR‚qj©—óIKl‰Iàr¸­¼$îôJ1m///ãÓ&XÎJçùùYn(fÛ±#Ìt#K¬V‰�±æ¥quŠ ÇQi#›Wr`;*8ÝK/¡âµb�Yž*ʪôF¥íX8\¥pr¬YÅWŸ"G9XÇø¤•ôR¥ËWɈñ¸î©ï©ôñy}Ðêr¹X6›Û\­©íJª];fZë9=Oºã>¼¤Òp/5;¬Øyw?�£«cbjoüß…SiÞ“1uee¿£w:âÒ_}Ö¡äìdXñ_’<ŸÝ~|Ú)Óó.ÜÊò“ú?u‚]j ™¤wKcŸIû=m7X¤r'ÚÉÜÉ—ÒrKXݬœnt0ÙIHèêàÃ2ÕÝä~wž;u'9’ÿÏÞ·µ7®ó¼:ÓÌþÿ¿÷›v²/Þ‡³P)§YMg 7ql¨EB²ŒÎ‡ÚBR{ÞS}Ç?{º;åw¹\þ,ùó^V4PnÞì Y4´'{d±Êáæ0爨4œƒ«ŒZ6º9ïÕU}�·ó$ù’lªŽqü©ýÝ]•&ÙÔoœ®rñ¹V¿ÃúU[KÜž~—v2®Ý)C©]Ü)9©?»1ÎméÒ;cü&œ5žÎàŒ‘�pÆÉHyu6„n¹ù ÓéæÄNκîòQX5~ïís_md3¾œéžÚÇÑ$©á•N†YRìN¦io,=SŠÃM2<˜ÿ-¥yoz“þ�&ÖÉäÎu‚“)îãæ´ØX[=.‰ûqr^Ôet9c¡ŽÐc¨‰™_"å2”Á­ÒäUþE™ð\m~I÷@ã3Åš3n·›d·+ÎÔ¡Eþ3TùÖW7Æ;Ç¡dqÇ2¢¼l w²©¼œ|nbîê,Úgœø”¯*ö�ëõj_F=¡êj2�No©r¸´�^tr³>{´‘Ò9­gÚ>…ý Çá3æ:¶œ2¯Õ—L+¾ÓA+ÎH×?¦ú­ÃTÇNe[5ö…½§{cccccccccãÁøW� ì”UÈ1£Ê›�0‹Nf‚&×g¼©òW=2Çt'¯¹KOýv²¯bêõ¦p“¶Té¹k·�ÛõáÄ&;t{¨»giÛ€’ ï#›¬dår;F�QT§» ›ìö¢£¬¯¯¯ŽDF®XîJoü°‰úE&¯dàã±Ó*CÕ±º‡ÛyÜÊ æáXbÕÆõ_Õ?æß1§Ë]σÆ÷¸oòv •/÷;‡�¡ds²°¯ò{8þ\Z—Ë¥=NT1àNç»¶àôPn¬ûÚË^ò¬èûÏÂtlMÓZ�ܪÀJ«èú°*�–{¢9�i]%;«k«•¶œ°ÔÝý¯f±'øòí%¬V¤3˜ÔõdɆӯ_¼NÆÎt¯ɪã«ÁT2tʽSú�Ì“ÿ+i§üVÚÒ-Uá}·/yú¥I¾çœž•~ç”$S“O5óÄzzw¥­ŽdœUgœ6÷A6¢ñï³ÁÏù`ñ…QNÇI˯\ßÎðr}�5]¾g�µÍG½üêdæúYÑGJÖdлúîôi2Ô¦F©3lÐÁ¨0U§ÉØvp2pO�8„›ãðÞÔ™áv¿«ë=ïªážtä=i¶Áçæ�ºNóN:Zµ~“!ßÉ•Â'"ûè°*™ÝÿNÎgÃÞ^²±±±±±±±±±ñ`|ùé%Óe¿ÂÔsç8]~ŠarÏÓ²è=ŒqÂt‰Ç1KÊ[üÌ¥!ÎÃ1w«2pz]y'y³·¯^žÄôn�Ÿ« Ü2_’7±°î#/*>ÃñVé;¦[m)á1€[8˜Fù‘‘éXŽÊ÷z½þIÛ}`¦ÒÆ—'U{©ãðÔÖõ�©I}c›ó7]9ÓxéØRËäXt¾çV�kíÒP2óJ†“ß­hás§ßR™\>ÜþU¿///r+“’É­T9y¦löÙyÏÅs§Ÿ¨4&uÌqøzUö ÒŠáj:®ïUø,&åàñçìŽItº®ž©4*m×w§}ÕÍåSûO]wi|V_ù |ùgà]Õ°ÝÆ8n)Ÿ©Fï”!Ëð3 &‡ÉÐ¥ãäžLg—|>S‰¹ÈuØ�U¬öq¯*û+8œÐ“¡�ò°lØ]ùR[âþn¼Ç† Xr³Œ¸…£ Ë#�iN¿d¸^¯ïœ ·L¯N)ák”¹ÊçNPqorìxòqÇ5r]LõþW{‘ËaB§ Û ¯;gË”dcÑéRcëÞ‰P�ÎC9êÎÈwÞëö¶;L í3puÊåTÇeº¶®ggŒíG‡™„w΂ҥ«ùÝÛ†Ó4ÜüáÂÕµ²wXñ©R�ƒ¨òÂòl̰·—llllllllll<_ö"¥[ÚtϦL®[.é䙜kœ–Rºe•®cè9ÝG-w}FÚg–BïÉkòÌ1[¼M¢àØ~Ƙ¬@$yVê^•/1åNÖ)YËìu/±hJ†*Ÿcå°îŠÍ.ƹN6ÁU ~A�™nÇnc~øŒëŸ?¸Ãqëw• ä—*Ý [ZEsÌ–ú ^ó©0u=y!U�ŸÞA�£‰^Lã@=ã3ÉS\W'|ºÖ=Ÿ>ƒ«- 7¶Q'çŠÞìV[ù¥Ú4&R_SaV0Yí:“ötþWùuú[­T=jÎ�Ž#g+¤•*§ŸRÙxŒ*�ÊqVÊó™¶�Ó'�´‘îÅ¿¾§»›<&¸wpºå®[ýì�91âÓ’ÐDçˆL'5‰tusÏ`ë&·d°ºv® —'¦Ï”QÕ1n�PméÊêÚH-òµªgXÇûzèöq_.ÿ;~ �îtšF·µ†¿ùÿþßÿ{÷4^ñ>ç¡ê+�‰···å*V ”;�%¯Užjo|Õ¯r*»ô”‘v¯¦žÏ0ì:]À: ®�!ûúú*÷¢«:™”#9S�Þîî9Ú}ÔKõ9U†IyÜýdà­@Í3¨»î�ÏŒ‘¯0îÜ|§œ)çØ¸ín¨CÔ6=7?9=3)C×ç§ýpuì|¾Å‘�+�ë¼ÞäñN�O÷¢§7‘7ÜΣãxSƒ\)”)s³‚3“ÏÙôÜs5™ªä{0•»3jÓD‹¿‰¡©k6º'_fLŠZ• Ó¯ûÎ(¹ÝôQs©_ºÉW•Ï•�û···v¯µÊ×9³êˆ?…i8Nxéx/ì«îÅQî[©?uf¥…i$ƒie,¦¾—ƇS8KØ0»�öñãÊ@’Ç9Ji|Oû�2 ¸Ÿà}Ì÷Ì>n§Îè`—ï�¼õÛéØ$ƒ3¸SØÏ(ÏÔatiÜ;wV?él$ÖU÷8O«˜Ú4éÿ³`ïéÞØØØØØØØØØx0¾ôô|6ñDWá¼rµ¤ÙÉæ–hTú.�©¼«ñ0ìJ®Î;–CÁ1/)üªGïÒáëŽéÆ}ÉœþjßCFt*3>Ç­êx=%›b³;ŠÙ f6˜‘Sé¹´ÕÑ{F¬cA�ã[$øxC•Æôí~®»T&®«®L¼ï¹|¼:¦ê‚ÛË:auª¬&÷¯OêgÂ<¥xéþ=¬³¼œ×·û”’U­h¤U�•‚3¬%¦§V[Õ npó¿s�äžÊwæÙtsûê\ìæý{l”nì¤>äd¸‡É¯²9Ä'Þt«;º2Rq¦²OÓDYž_¾§›Ÿã/ßçᲄå–N:y»ôVŒGgø(Îï5àyBø cXÉro]­æ¥®ñeÀãøX¯÷L~+˜(L®/'dÓ½šu�_â, !‚ÖZÝMü*]Ã^¯×?apYS½<©þ;!Õ¯;R� woÿ©´&1ïÁLD@=g‡¥3®YÇvƽӃÉi›ÔÑc,¥Çýû*öuL‹Ûåæc1ÿ‰ìØ—ð\{Žÿs›«wªýqü&¢þ;Ç�óJiMÃ¥úsižuº±3)çj>]�»¸ø_é�dp»veÙܘÇ|x{‰Ò¿êþgƒóìÞgz6ìí%ÆÓèþ߯¬x°i)J1]Úì•&yc¯–.Ïxq•–[BJ¸×kíØü³i¥<8œ[Bî^.ryMâ$–hÂtwcBÕ+.—«Õ¬wTšû0 oÁ/>2{èê òKÀÕÅÖ©K*Ÿz–¾¸Çõ¦äÁºSGº2`©—Ú8\åÏé9ŽãÊ«ŽeB¸£»^+éC>.=wÄâ”scɵ]·Âàê„Ùmì·êƒJÇñq ¾TéÚØÉ¥dsòOæ?£˜÷ä^ÉYaê' }b_ƒ=� ›æË$óg1ÜJÎ ¯»•€*��nŒ¨ÿ|Ç;§u»}ü²¯c«öÍg¯fux$û¾‚§ü üÔtwey*ɆϒÒTKU+ÊÓåÅù¦¥ªU”BV²:p¾÷ÐSL ÷ 6$¥È\ó½ãX;–*9S.ýÉÙð*ÆAãG}rü8ÞŸx‚yñ}샿ÿ–g;³�ÉF$�§¨ëšóGÃÛKµÊà&wç�¹ñööööal»·øq즽è^«Xr¹Kx’T:±òg™*>–㿼¼Ø/ŠvFbŠÃPï0¬"9¬NGó>n_Õ§‡_OUÛÔÜ0­Ÿ;êÈH6Ä“ñédróê+†²Ësge.= e|Oœ¿ÏÊ�Áã­s VÀzÔõýÚ^ÒÍ;�DrŒ¦öÜWco/ÙØØØØØØØØØx0žêœî3Þ‰ò´“Wzfù(m/é–Ê0Ÿ ë‘dúŒåç þ[¬õg`ºü©XOÇÖGö”'}ˆY¡)û³š¯[M©_ÅÜò²¤ûúÞõzµ/”ÝnÿûHˆ“GÉÊ2º¾�_�ä6RKæ‡W!“Ë2®2VÅ«­+©}W˜\dI™•U²¹|¹<¬ øa"UO“�­®þuºŽõ·êŸ�,._,¾8œÚÇŽ:™e­kÅ>sù¸~8M%O;ÜÆnKÑj;*¹'ŒxÂtãºìæÖ•´UÜŠ&�Up[¦p<Ÿ(¦ÛÅåkÕïT^•>磘n5Ç&¹Üœ˜úèŠMâÊðLøÒÓK’±ñX=w \uâivÊae '%©&'SJ7¥½*ï#0uxâëN!t†±SPn’šFiÿ,Iiq¹Yyª}ܸ¥äz½~0ê?¿½Žqœ \~†Æ¾:Óåÿ¯¯¯ñ轺æí*,ÛdŸ$3nì©2«mJרÓbPv¬û4a+�æô“3Jù¿ûèQêßSgcªç;ƒ@±êºúº2Ž]{«÷TüÎpVPrOŒ) çœëNçO‘>Nåp�!ÜabÜ��{FÞÕ¹xšC9T*Oã;ér¹üÑU<®Ò)'ýÖå¯ìœkºº¼§|%öö’����������ãË^¤Tì•c0ÜR\ZnSyt2%YÝ[í–‡™¿ŽSžä+Kvx�Ye²ÒÝ;ƒgf¿ÿõ=ÝÅöè ›¼Ü Ór7¦«YWž‰Ñ5ÅŠâQeíäW†Ö¿9P’¬ø2ñ'E¿"›«³‰be‡ŽóJF’2x8?ž¤ÑˆCC$}¥�ŒRÛ ØØpJ_}€Gû\'\on;ÀËËË»râ>iÕøè½äl*£�ÃV=pZ¿ëKU'xd ¸ópcBMÔ*,Ê]Ž×Ç©:HÎ$†C¹’a¤>T¤â9ypûTÕ£s$Ý}–Õ�e>mfª#“AVàñãæ�Õ2¨¾šοîO ÷G"9ÿˆ¤çÿ #ñLÝ$'‹ûY7&U8 Ë:cº½Äõõ©·:ÿs–íY ï/?2P=_ñ*WŒLŽÃ†cêØèí¹Ž‡×ì©»Îâ<ÌLñÔÛOéO•êTùuùaž¥‚“ìÙü»I2åÏÏR}¡ÁÃý¾3^ë¹:ò�ÁF Ö§ÛÇ�áñ˜@.oooöv×3ÞG®Œ}„2^ð™2ÕW1Ñ�DYQ>4*¹]]Pgj³lìì(ç �y»½íêìt…¤S°ýñ‹¢h”r™Óí^Æuò(Ø9"θvŽ4;ììMêÎ9FÎÀV`¯qãäVz¦ëOgç.ÛÄPºLx——ËÃ9qœg§ë“C�¨T—«u<N¾‰<×ÍQÎVÏ•C§lŸ©Nê°wb¬?«Á}{O÷ÆÆÆÆÆÆÆÆÆÆÃñ¥ÛKðÿ™¥ÇTZ;š 'gÚ €iò‡-�Qs ûtß§ÊÏ�ëtrª×2 Ž™¸—Ýæ|ùþwLЄuãô“,‰ÅéX';ËÀìZØ·�QKÌ~ݯ­Ø–ÅL§•7.qËF±nÕßùH6fºqK‰b.ùKŒx­öd^__ÿ0¶œ¶J«Ê†ÛPëãXPÞ_¯Ú‹ëQmiQíçN]©¶T§ pY'Œ,¶]µQןÓ�â&V6­©ºÃ:a¦›?€ãV$0¯)Óíäf&™}L£;¥(ÍiJ'·K‚ŽEVs�j—Ïf»ôœÜéÿ=óÖtUàlž“úSöÍ$}ÕOë>³Û|óâuÆvÉ]ÏêË“(3†Uã” ?'›ÓiÉÈEÝÂÛmîíCX—Ëû­&X_ÜŸØÑSŽŸÓGÕ&j[Çq/ »=ølt³³‡²LëH�)þŸê~¢ÿ+-5–ñ…Žìqz”‘æçp*#*¥Í}fU—6’ \¶Éœ±b“LçÕ.ŸÕ>;ý�è¶+M�n%ÓÔYrýÓÅqcqÿ«°·—llllllllll<_úq÷lêIvËÎÛv™cœñ?›“˜d�iT[øL8ÆB…YIO¥£Â¤úMù®2ûÌlMä\ñ„«vó›ÈÑ­!«ëfû‹6•Ï…Qì¸bŒê´’bº™�tgàÿ“Õ÷B›ÚæÅ¬³+ëJŸ*P6Ç”s¾Š­E6ºäV_±d9',3XL·êCõï«Õ’):=ÜÕ·ê÷iKI••Ùè®~*m%Wê=¯t ®Ô¹16•A•%ÉÃaÒ}Ç ãít˜Kk2G'¸yyªË•ÞIy¥´øÙ4ÜJ»N�t�›{T`Xu„¥Êë¢'Vû¦Šÿl wáK??éS¯ÝÇÏV–ßðº›äê7ms˜ìßNt¥ó­bZß“ðÎHRƒRÕ£ ×Ý+Æ+Ópý$õ/N1Ù0é·•Võ/Þ�ûš¹?–Á‹é«þìÊÄ2Ç?[WTz8^^^Ž———w2 ±§ê‡¿‚Éõ‚²qÀ=æî”>ët Õ§«®º¾ÇÏÝ—!/—ËñëׯwqÐ0Æc�#21ªN”C§ú“ÚÂÑåádJ×ÎhIò¨±¬Œ)§¿§HóXÏ*.Ž_ìÃåt9chÕáI2p8üj:tõ8M¯Æ¥jçéXI²±Ãp¦]”>93‡¥gÊÆRùMÆJ]Ol1¥+�­�êåY mÄÞ^²±±±±±±±±±ñ`|Ùé%ê×yT ‰™˜¤Áž_ç])¦ÓÂÿ¼üë_u¦/§wfÉOy„‰­Påv`Ùΰ%X'®~:¯}…iKé°œ.Ì„IÁ´Û– žs]á¯:}¢òÆâpk÷a~ÁP�E·ì‹L{Óã3 U;óyåŽéNã€ë _T_â¬-(È«�ÛLÇ„b‚Ü×%yÕ åS«7ø�Åf#C¯ØÓ‰ì•6æËüqL¼;?ÿ+†Þm—p÷Ü fºYòµ;3}ªg§sÕ„Qw/‡vds_t:ÓQs‹Ò¹S}ÇHó¢“gÕ·VW';Þ­`®2Љõæ¼Ô<ÁéOYc%G’•™î©-æú÷-üï>ðäþ»²¨r}ü©öt»pÎXqÔ<Od¨°¸UMÔ8¡¼¼¼ÄcÐÎL’ª,`]žÉGåYiMŒüÔ–N q¸{Ú<Á9,(Om¥èYR|?…IŽnïp'BTØÚÖ�JOÅŸmi‚r†:ÆÏm¹QûÃSù”LÇ¢ûø‹;�ce‰ÔmsÎKr‚ùÈ9Ï̱©®§óQgܪëIxü¯d�Ø+.}7?uåñ0ãÇ IDATTóAÉææW¦‰Ü|Ô¥“�û÷™~;mç¤7žÉ¸vøÒ#Ï" ×Ý¥Óy{¥´Ó×Å’lŒd|N‡›Lr�\�¼g�„3´]>õŸ'þI^*�©¼êE·ÕÁ=U"+áÔ¤é ÞŸ?¾+tÌN&Cž¬ÐˆW“6§ƒû¸¹lhè9¦[M6®?%ÖÛM^iòì&cu¬#Êâ¾&êdÀv('óT횎¬K˜LÀUwNÇ­Ž¿Îà™LðN6~Ý™S£‰ePÀ±çÒCLÞš¬°ò<“äSåíŒ'ÖMݼsF/OÒíä[ÉkÓ<¸þWmÆÔ9â1¡ž©±’æf¾?±�8Oþßñ“gÏ„½§{cccccccccãÁxš/Râubº“w5a#'Þ™“eSÇ›q¸WÛåËñ¹>ΰ+Ì~ÊgšÆÊ’QZKrc;¹�º|VÙÇ$ÕuÚ³êòîÊTy:†ëÛ¡¦Ê‚i9F-ÅqÌ9£Ò~}}•ùàJ’b3˜ÚE1ÞÇñÏ †cåÓ�é)]Ur#­¶öÔ‰ +lbÉŒ:ËÄzôÌê”ÓÅNnN[mIqy`çXa<7GX§N×u˜èK—÷g õy7®U›Nì�3Ž›³qTœ®?¹0]žé8Ê•t9ÜÔàNõ�Úï™�k‡½½dcccccccccãÁøÒí%é:yAÇLuK$*�Ä”³lÌøÔ³´d§ØZ\æár88FGýWl‡ëXø‰79•gܾ\w޹qŒÁ”Y™¬ŒÇG6’™ÎŽ=8[7·›>uCÉXr96ç £NõIìïår‘_šd~ýú5úªž[!Hlæ—V êš?€Ãõƒ×///ïV·”܉µWåÀ_ÕPVD•Ç!èNˆÁ|\=ªvUŒq­Xàq�J†n¥bÂ<ó ›êXÀúï^ÌåöHŒ¤»¯¶Ì(¶ç†î(SW­,T>ªb:ÌLws’“¥Ó'ó;eE«º°c–'éNWb8�3åã|•Þ˜Æq²M™àdÓLëËÉÃóíÊü«tCW×NǪçÏ€§9§Û]O6wÎs2HÜT×õßÝ¥äSù0ÒÀþÌ¥¸i�¬`¢Ü'KE�‘‹áÏ,y1&ÿjº�"S÷“RUùº½Èjï0~�Qååúš3^9 ž#ÍF–÷qc8õåIWn'³“»ÒWò¸4¹ÑÉ9ýÅJgX§gX~•/§�À/}*Ýé¶§(°çÚŸ�n׿�³�ÀF»j>Gµ+§75ÏèW5>0,o1äk4°9ŸÛíý»C£;…qåèæ6ü¹¼&z>9f* ¼ŸÊëâ®Î}©ý§s»Ë{eîVu¦Œ\…4>Ò{4œwçè(Go*“»&þ³ÙŒ½½dcccccccccãÁø²)³\˜x¼õßyèÎKìαÄ7ú•÷Yà/áq™”w6aaT9\z¦Ãoq²t–ØŨ~6+ï Ú¯™ýtËe]»tu^l¨zYçãøÈ´a8쫸ÕËæÎ}Vy"[Š2àªÐ¯_¿ÞÝWÛº/ñ¥zéî[j‹I•¯]Ù“,ùÓí@§Pïpû©¾Ài)¶Ð1Õ¬÷Ô—P¹oa>® ,¦‡ý„ï'vÒwÒ|Âuï˜ÅÉjÊÇL7¯ ¸yð^¦[1�®î™œ\)~7gL˜Ü)º>Yù­Î}I.îßîMý¯Ò^e‚ñ÷ÁÎét��.”a:GºrLòúj|éö’ÉÒ@R¬Çá•�Ë7)7á)yÐ@˜ìQEÆ?ûëÞRŸ(—³�iꈜÅ=�\µI2Ò'é8¬Ö*Œ:ÉAå3éû˜NR:lt»£�±èNµà- \.忼¼¼3ºñš þ¨K·W�iר S2;GHå�ãU�F¤dqFN2dù?²˜®›\ÐÉá:År¨ºPå™|tªôÊZ{úSq&Æ«>쌷É8âwîÑu*ìg©/tFiµ¶Y:fô£›åqÏV ¸.NÒÛÉYqrr:©mS›ßãTtPý_9Z+NáTŽIÝ¢ xí¾Œåq[ßÜû'œn>ãô`zÏdd3öö’����������ãË·—8ÏFy,Ê«N×ÈÊ ¤òwK(,›úU²ª3Z•'ˆ Zç�±§Ü¥�îc~Ž�û ¤• ”ÁÅ›²TfdŨMóíòÆþ8 ÏíâØld3Õ¶ŽÊÓ�rÁL†{¡ÑmI)yÜi*¯¯¯~±=ë?Ê’ê€ÿOV" \ê>·9¯tlbǺ)¬ÒuºW ¸ý®ÊîV&c®y\ p[dXVLC±h?m)Á´ÒêËÐɷ”%‡ãEÉÍ«?nå´âóŠDÅQ÷+|7o¦{ˆT'iÞH«êþ*«ëþãýÉê]bÛSúø|¢ÿWæy¼×Í•.ÏÉ †ÛÖ„ñX¯Oä™Ô;^«:JõêôÁ3ãé·—`¾F¬LÀ jòÇ¥%7ž¡ŒžR„¸ë–�œrf…‹a’bíœ «ÊÍr¸¥3Žw¯á{ïÒ 3d&JCå£ ”Jc2è]ŸÖ¹XGµ½£Â¹vÁÉ�Ãñ¤­ SVº,�3üÑèæg•¯Ær»ñ‚aÕDåê› ^õŒÇÛÄÐVÆ­2†ø9ë%O×Õ’rüÓØf¸úåxUw|š‰*+§�2+'ŽË‡}O‹Rº­3èÔ¶•©!01†8mÕ.jluŒâÿ® j\óüÂX1V:eJÿWòî ú‰ÑÕA=KÆŸÃDŸ™‹Tßrq�S:ŽÃ”}£œ=ÞV—H‡‰#¢®§}c’žúÿUxª/Rºá+uŸÓ˜ƒî¸­J ŸáÄ“&Gg¸±Ât†íjÎv²ÏŽ71^V©þ¡äZ58Tº�óXÊ©;†©ƒ2ÚÊpÀ#úÜÙØœÐ‘uûÕÜhX³á©Œfdò”²v¤3x]�p[¹6Wº¥3ºX>å0*ÝÎØ¸Ýnr}’A1NøÌ½<Ér¦þèÆiªWõn³ÔI÷q8·j“œ)×fwÅPZÿN‡ 3ÄzÝ�ïÒe§ÐíÛçxêÅådÜ9LuYr*Q¶I_\E2ÆW熉ÝóIÚ©~&º)•'æÎèÆxLö8LÇ ÒÅÊY˜èPηÓ_‰½§{cccccccccãÁøòí%‰MæëÌ0¨´W˜Såe&†ÞygÌzñ5îÍ;Å )\ÿŒJ†”¶òð»8ŽýïX9w/ÉÅ×* ×Wãâ+°îበÕgëìÊÀ{Gñ9Ê�ìyÅÃtê9ÊSáUÃ�áÇÇ-.¼ÊÃù°¬n1¸»6bÆOÝÇ�*ƒc“ \7…ôæ?3â·²Á 1ç‡ï¶$v½ck¹½R�)Kû�1<ö'fá¦íªd˜¢ÓIo)6™¯qU ±Œ® ŽMLãí¨¬èÿŽÅìàæåÕ4\þ;ÊÏîeA§«)NÏœ•-ÍIØ¿\ü¯XfÌGõçzvO[:ÛOÁµëÔV|&¶ûË_¤tpÊŠ¡&‡nIc7™Ö nÙ°€FQ…qÊ�'¥‰Ü�ìDnI‹óŸ”˜Þ4Ì™  Kóå>Í[)¥¨ÉO½œÈF÷¤îø%Êd$¡ï¶¡à6îÏ·Û?û¸q)½Œ‹‰óéö‹;£òUËóN‡¨þ­ú¾ÚŸ­Æ,·§Ÿ^àt/׺ø®Í±Uû”^B¹YϤcKSŸV†$†»Ýnïú‰s°®ª�îsF7‡UFNšøÞY��zŸ�Èä´ñ‹“Ižº¯œÔdtã/Ý®½W05ÖWõ ÷9L£3X»¼*Lgðuí?qüSÚiKæáæýä¤OŒOe¬*C�Ç虣;�Ó¯ëI›3R�>‹á½·—llllllllll<_ú"¥ó,3å�<|÷ïÔkfÖEÉ^ù`|ÇÂ0«‡÷Ë5e–§ìË3©Ž£î”—zf9rSæÝÅS}ˆ¡˜‡É’–b-\Åþ¢lü1–ÿó ZØ]/—ˇm&u­Ž-ä­%ooo˜nu•êïÌü {¬^¬TåFLtKŠçtPåë^žÄ²¥g¹xü\éün ¯^œT+ż©ü9m–Ç1†Ø~|ú�ê·ÜS�8¤ðî…[%‡ŠÏ}Ím\Ñ•Nbþ\zX¯îXUßÜ'ëz¢·ÎÂ�Ñ {¼2‡�•͵ó4¾*_É­Vb\þxÓIywHíªÆhõA77¸í¯+mÔ�1žÜøTåIé=#¾üô§´»k†2<”Q¹¢hPQ;°ó²±ƒƒ��DsFÄt)æ3•’KwÅP<£(§F“{–ŒÆÏœ8ŽããÖ€ÎÀwgbsZ)_u¼YÝŸl/Á¾Yÿ'† ûj‰2ºñØ3<±$�µ§·3x•3œâ%}¢êŒ¯»ãÿÔ$;={ŸÁuä&w·M‡�[…ØÁ/p±<“qÊcÂ�TƒÇ[b|µ‡;É„i²¬ÌS‚¡ž©úvsoW\)ƒ‹ƒc´ò¨0|†w—ŸsèÓ:7_'’¬]ݬÈÓåŘØNVüfãy‡óMv•ëûì uŽ%—­3š�ì�ã¦Ò]×_…½½dcccccccccãÁxªí%ü\…C°5eŒ• ʃwé9vû8Þ/ç󋔘²„¸«dbYyÙø³Yo®SWÖ)©äs^,ËÐy¨ŠÑ¨<#¶"«ê§6ƒŸMØn·t‰Œ³:/UÉ=e Y÷1·¥„û#ç›ÎvËÝŽ=ÄgŠ­]aº9 „baÔ oÓp+"+c4é; ÃØá0uÿz½þ)ƒëwî4 Ç@*]àt¬ƒ“[…›¤çâMXIþ¿ÂˆòWÇi,:Ý®Æ!çýãÇ�§©´ÒVÆU$&Xõ§C™Eåk.SšKÜsFg{t˜ö'U|¦¶¨MëµË×ÅQºJÙ'ª©—(±ÍSÎrªq ¶?¦t”Ü®º¹ú߯—Ÿ^â*']w�ïqã¦#¾x)Ù-™så‰Ë-¿ð© îx,%g¥½:¹'…ÀpŠq'Ý›.UMK2¬ïU¬ÉhU÷•"SJMɪ¶�¤Æ8ç,Mî|ŸûªšÈœÑ͆šª¾Çuâ”,ד;šP•/ɰŠéøUrU¸ÉØqmÄia:i« ÊÇû€±NY§tΰz¦dä{¬/q_º;�…óI“;—ƒÓReHmbÙ“|%›ÚkͲ1&eWùUøŠÃ†ë ‡ënª/;1ÉœÒZq&a;]þYy±ÃÕ…WvÃêØ¯ë‰~㾩ô#ç£úÒ=Κ’eèÆoJË¥ýlx*¦ûÌ„©Œƒ®cœ1ÀÔÑ9œ×ïß¿ÿL"h„0ƒ�ŠŸ_4rž)_O½ûnºòNà”¤Sú*g@±r™´Y ãòÁgNž©ñšdàÉÞ½HËgn;#7µÑt?±3ÀùåS/RV_Ÿ:‹xWƒøÁ$Ë–ôɽÊ7)öãxï”°Q£V6r]ziï?ê w®.Ë€mÆç§ó¹ìî¬éT,?Ê€q°�'ãŸ9SÅqàþ‰åÃr»•S>÷öA~÷gЉ‘äú#;Ú¬«¦m„a’cÜ•¡ËgbŒÝ •¿Ë×9ÓÉIu:Ü92ÉÁQý¬3Εѭú ë4UnLß=C�æl;¶«\ZœßÄV|&|ïéÞØØØØØØØØØx0¾œéž°ÛÎ#C¤{è%²7†^\bnÔþ8õ ÓÀÓp鉽8Þ–RÿyŸžª«ÏdôWâ¥U‡ÉTÇV<Ò3u^ô*ÃÏÿ¹?§~W@&�÷j#3‰ñÒ2_òð'uª˜I%;2ïÅP(†ûýṪ�lÈqä%üÕ²Ÿ�K7ºqºÊnqšŠÁR2aÂcy<*f óa¹³¥>†ñÝr<³² ‰�L÷S�:F=¥çŽ^øTßIn¾¯˜ÉºßéÚ “t:ÿïÆÓ=ã¼cˆ'ù&Vvºáê$É7‘•ëpÚ7•õ;avq¼¥÷}¸Ïp\]aHåCÜÑ— “¶œ´õ¿‰/ÝÓ=Y.IGàǹí%*ÿH©#Ö//ƒ¨N…ÆFm!Á­'¸„îŒv7¡«2¸}ê.üÄØUŠ‹z’-Ý?vêL•b2^“R;#[2¼•<|,`š<;Y;Ù\ÚI©%cÓ�LÔÉÐgyœ¿jp«²*¹Õ/ê§{&ài_�DÛ·p`x|4íCe#n"÷ì4²±ªôWÕ¯ÓçjMõZ¥Íÿ'Põ˜ô„ë«I¯Çç,¯s0ø9U–'õA5~Wê�ã*Y&÷ùy’Û�åUÃËŸØoÝœèÒâÿ©-UyøÞtÞAbDÝn>çën¾LóËÃ÷ÕØž´1ßScñY°·—llllllllll<OóqÇL%“*Ï$�gÄSm/qÆâ¤R•š6Z†ÓžtŒ_Ë:jBÀ°l´»e1¥˜'Š…Ãu F…Oõ¢äî&€N™ªIgUér:n™o_ÝŸL¬lðsî4>Ôö•×ôÄ–©òKŸÉVŠúv»ýÙ\÷»zä¯O¦>3™\œ¾HÏ9ßåvºçvûÇùPmìÎfçþì>µìŒÜTN,~ª}¯×ë;ƒÑ��©!â¶”pû§öq:ÄÉVeKaÉTaÜùÙJÿOõAý&CÉ™.-ŽïŒ[ÌãÜ£§a¦íã®Ä_EG[%É£ä^MƒóOýLé·½DÉ—æíY»ù$9]^i¼9Ãü°·—llllllllll<_Ît;/¥c� ‰mÅkåM½JµTÉgp«2 —Ç_´Ã8Èbð NŠáUjçÉ©:HÌò &¬ö½iN¿•t•\&Ñ­LÒTá˜Ñãm$Øg\=v/cZªïð×%S{«‹ã2½HÉù«±à/C}̪cv:¦L3ïn5Á�×ãÐ %žJ¤òR÷•~œŒ7fâÕ‚?~üùjå¯_¿>èìé´µEérùçKªU�J_âÖ>ÅÇõ[LC}¥7é 7LÒNóÓ”éÆüSŸäyÂ��I^ ÕÆ*=UWÝêÚ‹ó?ÃOò<Ž÷+†®MœÞšÎ«NF%Ódl'LÛdKM^²u}!­Êðu “ÆÆïæ†IÙÕõWãË�nõªÔÓe€i0:ƒ×Úh pzooo>@Á2ð¤å&ž3F,Ë;Q ®}¦KM«ePFl§¬”2YUü˜÷9õ¿“Ÿ'6eŒÕ6.9HSƒ×ÉàŽ&Tùᖼ連Ð1žêëŒÉÖ•2ü;ã•ï±Ü<ÁàýÔJ®—ËÕ�\onlªrâÑ¥îT‘ú½^ÿ´q…s§ià笥/ˆâ®_Üv¥>:ĘÞ[Ñ?܇�¬É�™Àõ Õç\¸¤ë÷O¬ N[Íog 7—r9œÜ�žèœŠ‰|GÍ ÎéHåIŽÊ=†àŠ¡Þ}…R9¹®î]™0=×79œšCV ìd+>+öö’����������ãË™îäõÇûÍÿ‰IHL™Ê·â¬xŒõ›N,HÌ@-óv[RÃã®9�Äê%ÏePepŒƒZvÂ|'̆ór8­oÇ*9™ÜýUOeåÏ_³lêEJ–gâÕ'ñ„‰i�¸à$FH±É(ƒ– O¹pý¬Æ¥b^;ÝàÆPx?±G\N»cwóÆ,:†Sòøc[J†êêñJ6Åœßnúꪟ žwz±pªÜë9­7–Û½àêÚ?ɓƥ“¯Òžœ2”0-;æ{æãV.Õ�Uº©ý'8«Û“ƒá”Þtc„ﻃRžÓ´ŸOct×üMa Å‘òwy'ƒ.uBÜë̓—yÔ1jlóÑ‚EÖ n§ÐUZNuH¸’cš¦Š—Tgìs]q=*tý1Á}èÆ}�s5éŸq8P'�Sº¸ï–'c7Iª}Àø¬“ŸË­ŽX¬p|BÐê$ÂcoÒÿ•AV÷“²Ÿô%‡ 3ã<áÇ{ûۃ}Çã›�ˆt4`…SãåäÿÊïŒîθM:{2¹»£f§ïS8:]5I{jÐuó„2†Õ{ JN•Æé ·tÏÍ'gê�ÿwiœ)» Ãóª3®§òu÷±*Òóg�¯l 7‘‡ËÚÃJ‡vy©<'6äWãiŒnWIêºþOöúMdÀ_¥ð\gUùb' 'gé³½h`ðžpÌÝ$§ iç`¨0Ž©úMà<»gÝLé%L'5ÞåËŠ ‘ú_¿\6g ºãS½"3™ TüïØm6àÜÄɆ£bG1}î·“~ºaªº>­äãk¼§ÚI•CÕo‚r4ºñV:G=Om‡ÿßÞÞìJczé7éK”ÏÕ#­Ò9ˆ˜.·�2j*¾³ Ü·0M7‡¥ô:°cò¨´ï1*’Á›ÈžiþÎ)p}ƒçA~†÷\¾éˆG•NÝû ãÌÕ—OÍ]g~†c¶Û)À:ŸËÀ}ÁÙH$;󚌗îúÙ°÷tolllllllll<_Êt‡÷ä&LcÅKâ´§rª8*¿ô1œ···?,xçía8·ÕDÅ­{,CÇÐuLBÚ‡‹Hì æ™XLΕoÅ«ul§ãúã´¡Ü“£‹Vý&1[Ó²O˜n–ïr¹¼;&óÄS-x?uW|ø9æëú3÷YwŸ^Òõ+wO]«/ÄNØ? çØìj•Û‹?˜âØc^YPrqÔIxb ögŒ‡ùtLrÇ2'†ßEPeUì¡Ê«ÓwŽÙæë•í%ðŠ—ûÓݧú°:n¯Ý<Æq\»Näsc0=[Y­À8Æ8¥“ôÅÊêÆÊªA*«{ß ž©>�˜müßéTe›©:îh¥�VØî.Ì3á[l/áå5á¥F:3¹‡^ÆWñ�"p�Í_†rÎI8`xéºSÀÓŽ‰2¤¯VñÿnIMÝ?;î1~R¸‰2^‘ç8Û~ã÷Lý¤IÑ-Ós8|æ”6Ÿ«|»ýó ¾³€í\{Ô]y±OÆ¥*·ŠÇc”�7þVÇ’2~ÝV žÔÔ$Çá�A  V¼ï¾jˆõˆ†¬ëøB+ç�GüuõæÚ…ú}žè $=˜ê´3$Õ>õB¡jW÷åQ×§“>ã2tuÛéduÏ�þŸÈ.ë#°Ó‹ilWøUgÁååÒXA7OMótŽ<ÛJ±“<™¿;ý˜ú¦ÓËIL¨Õ|ž{{ÉÆÆÆÆÆÆÆÆÆÆƒñ”ÛK:�å^KZòP½QáÙ3s Óqüó"ÏUÞ§ò.ñK•Ì*®–k%<3FÈn2SÁ׉åê0eƒƒ™X‡nuC¥Waº—'™¹cY�,Q×ÎÌ`+™ÕÕoÃ8YåI/\ª<Ì€N˜L�ÛãuÌÍ”iVqÜv fÛ9%·?ççÊš¶¼qYT¿efÃñI4ª<›ÅýëÃc^IªñÁ:C×ï8m·ú£Ê ®;¸6Âk^MrùLLׯ•<®¾¹:&‚•ðÖm¥Jí¥úgW�jn9;Ÿ¥>¤æ^ŸÓr'–(Y•B¤9[¥­d�Øv˜W· òre}&–û8žÈè^m$†3dVäH�zbø§ „¿Ú^R×jpà^Æ×××vòtåpË‹˜·‰RÊI©N–‰”ÜIùŸQÓ‰¥3^&†½ —¾Ò§ÎâîdS†W'ßd ñvûx>ªS^ªß&£[M^ê89–'M6Ê�u'¢¤|¦Æ+—ƒëÞµÛ¤+Ý€ù¨ôx’œ~øŸ�ÿS_­Sájw}îÈ@5±NÆ#ʇ†?©ùãÇ�ç�s9ð™j¿t7ÿNNœYAgl¨>ª¾ªÆ›«cÕ+Ž2D1-u¨JkÅàquÐýÇ~5]þÞÕߟØ<Æ�|É™a({"ÝÇ‘çÕf\Î4ß9ÙÒ\šì9—.·±³ŸÍØ.ìí%ÆS2Ý챤)g—wœ\ŠQKấ•²ÖÇ‘ÏEU'™0[—˜;Ǩ)™1Žz6a³ùþ„‰Vñ§,E×)…{½„Ç ²ŒéÅ9Åf8‡åf™XÎ CïÂ'–q¼¨þÝmÝâ±ìä.=¡úU×1„Ø�ñ~}7 cÇT{uçЧ.ö-d_]Tÿ'ãÜÍ;I'âóÄö9Ù&Lâ*Íļ¦vÁí%‰qvò)&¾“9• ÛÙ}l+µÛ”yM2Ü6õ­¤[œþB=íCày'�‘©­�dsº ¯ÝÖZ—obºŸ™ñ~*¢c/ IDAT£»»æ·pÝä71b’�<) TJi`c™jY´–‰Ô2–÷w« ÊM„“7×OJÇA«i¨|»¶žN“vv`ç‰eRK{IÑtíÕ)¨N±ª¾U÷;%É÷�<Õ§]9ÔXUãÚ-—â8š8•©Ÿ¤qîŒ�GöÛt<§;ªN9(Ê(A9ØXa e,#· \¥«#SݸP¦çƦáŒMÕgWçƒÉóÂäë¬ngu?̓ª®ÝI;®/GÞKÏò¬Â9 .œsDY¶dä:ãQ9…*Ï8ïù$¢Nî"/܉%ÛÈà]ŸŸØüÌ�ù‰íö6ÛWàË�îÂd¢WF)Ù‰’Y‘Ç]«gÎÈaÓ(£» °îÓÏÌ>ñà0ü™‰°3\¸ ü¥ª©³£Ø–J{jˆrzª© Ï ÔN±:c“§,C2lëzÂL$%댕—ëûfMY®Ê§ŽœSËã”±36ÓdŠñ;§FÕ·Z±pép|7YNúºÊ[ÅIåâ \w¥C*?†ÊØW˜ŽÑT>eèÕþn%£ÊÓMÈJMÑ jü㳉 n¬p®îU_u}²sà:Ù&åH†µº¯ú~’'�Å$“ÓÙÉ N:v:?MPaËàîl’d#umïòWz£ú_²ŸÎä¥òíÞÉxì=ÝÆ—3ÝŽÉÃë´´¼âwáØ#sÇ™°ÄŠ}v,JåSû$'_À«eÞ´üÔyîê>—�?êâÊ̲Nömªü'˜°c“6ª835•�÷¸"³0ÙÇ­XÆÄØtì6ßwHù¦mR ˜/²bø�•Ëåý’6Þwý±[½™2§XÇT»þÊÇð¥<՘ǴQ_p>\w˜ç´¯»òq|Ç8á3\a«¯êªxxŠˆ*S'ûdU¢îñ~p¼¥²&ÝXq\�¤ÕþíX½Ä’®àžz¬û( ÷KŽË}såA%ãê3f¢óË}F6Þõ™”gškœÍàÒ«¾‰ñÔ„òuó»ƒc°Õ\ât,ç=™¯\ÚîúÙðTFw×0Ü¡iù'�-Ÿ™�²(¹YVL×�íí:CMdêH5>*«Â\¯×ãׯ_VÖ4P'÷�2Ni0’±­ -~žòIËŽ ©~xŸÂ-¹bP/­u²¹{ê™3âWëG½7ÑMJ+çíöϱsxÜœ3üÔ˜gdžÓÇ_–!M+ýlr^1˪Peè¥ôÜôJ¦nÜ'£ó)£V¥­ŽïÃkW'“pîºÚáz½þ‰ïަœêÈ3ÄÀÔIíôÇïô`‚/�lª?uºÅµùªQË}xª_\})6i#NÿŒ¾syNŒBÕ^]ÿ¯9L�ç³vQ’�óW²¹ûN¯wpõ8qž{{ÉÆÆÆÆÆÆÆÆÆÆƒñåLwaâ±0ë嘒‰·ÉPÞœûª“óRù>2-¸¬ž¼À××Wùáöz‘]}yyy÷2f·=ÅåÝ=S§àsô®ª=ÔR\bÀ ž°Â(óý6Ìõ;þŽ«Îcê¡wl†bêƒäÿÉx«kÅZ¨2cÚÌv«|#’úP*ÊâX½´*³:Æ\ÿæ{ÜgRÚ“ò�a¶jû[…OeRí0ÕËœ6Ö7‡å¶CÆ›õ/ÇUHý§Ó'Ì2º±³Â8NÀc�õÂtÎSp:çÎ7m¹Â¸*¯IœI¸®L“~0eÛ'p6� [y&½‡õí>nåæL›ë¬+«cºÓÊTw�ËxfÅ`¥Ž¿Oet«ÿÊ茒³J�;òê– ~†ˆ÷x«OÄ×}4 •AÀŸæOÉOʹ:Qs§N“ÒŸ=qÚ©.ºÏ@wi«}·e<­.í%#Wå­î)Å• nÎj8ªœ«“æ“¶š8¨ñ¡òåñÆi«/ëuŽã4\g,«zKN“KÓÁÉ7MÃtÇñqËÊ—¶S¹ô0¼3Ü�Üjváø?¦�äacö8ŽÎö5–gÕù8.OrŒ©ŸTœt¼)êÁn.HN³ —t'·Ë¤þR;Oîá}NgÒ×S�ÎÙø_¨êîÌüªÚ{b@»1î ã3ó2º•LÏ‚½½dcccccccccãÁx*¦Û±ÛèÑ%æm•U¬°./·d“˜8ÅlðKW—õÛퟥPd°ùm|dj‹ ç«äRè^ìê’?L’ÒIÌËt ÑÉ•â8Ö,õ»I9;S')t,Ã=Þx'ý«=ê¿Ê§®Ïäë¶šð©&³Äl;Ž·5�˷´MËê˜"÷µR¾×­8¨´î uÇ2±a}Ui:öOIza2^ùš¿:©ÂÔ3>EEå›t‚·íaù˜ÙVýmeNríœÚ(¥ãþ«t9\bz¹]¦ý©C·ztF¯¡,“~7m¯nÕ‚m—6ÝKzK­þOW 0ŽÓƒIÎîƒJÒ'ÎFãùÛ­Ð>žÒè®ÿ|?-'(`uа “}­®q•C &"N÷FÕi&%‹Ûëy¹¼?BPÕ£šüœó2…ëàgӛݓÉfº™¾6‘•û�Ú�¯dvyžQg&‡®/8E¦”¡ú]í[˜EÆõŠiº=ÆnŒ%ƒ É—ú¦› 8,;x¿ÛÇ�ô “¥þwΙJÛ?[ȆWÉ—ŒR‡Ôh ¨:*Yê?ܼÍË¥�05r¹�\œ‰�£Âœ³pÆØá¸¬#UXõ_�ÓÕÛT?tõØÁé·._•F'g7ŸtcÀÙAÜï§û¸Uß_™c°$�¤ê%ÙKNæ�^T²>öö’����������ã)™îäÉt£¨ß3KPè=òKZI&w™»ô eþÀ²LN.s¥Ïñ™!z„÷—˜·ŽÁr÷WdRì¦5=“[Éæ_<—;±B« ˆBZ‚Srr^+¬j—7æ•úº’£Pì$üÛ‰ÇæÉŒ¬Û†�V :aáÔøêúwÇÐ+$=˜Xw•¯z>aëŽã};9FíÇ�Îew/{%y�ü®Ç×í¤Ž¦ã�åMãeÚ.܇]}»—FݸQ6„ºNÀpüò$ëüÉ8ŸÈ ÊÆöؤ<Ó1’êÝ¥5Ù‘ðLxJ£»þóýêhêO6n#‚ã8c£;1eÒÀjÉœãò’íÛÛÛ»“LÔ$ÂåÇ}à.Ü%›Pß}ŒBÁÉßÉànJ»KC…OqÓ̸2ø�C°‚Iýpûc~ÉÀ˜Ê5s]ߪÿ8Æðh:~ârùg+U2üÑðà�EàµrŽ”œx�ÛTMÓró^tîƒîhÂä ¥±„zB�õ o/áþÃåP²âû&ÎùPi:ùÒ”Ãp¹±_Mô�ksÃmÒ9F.‡íú“Ó3N•�JÃ…Qí ô :-HÉŒive›ÎO®üÓyÁ¡«‡n;Uj�$«²…ê:ÝJîçÜ%yR8—¯j×® ”�¦l¶Gë߯ÓÝÇ¡‰òd&Êdepª´±£¨#y:T£;ã 'Vœ�‘áI-OõU6.OîNÉv†™ƒk¿É$Úɲ¿Ës:�CçdP†ÇdòZU]ßž´eªcc®üÆ®.ý.Üíöþ«•Ž9gÆÚMÖ¨Cð~�o®-'F»s†ªî”ÃçÚA�³©ñÚ}n>MdŒd¼¨q™>Q�ÒSé«|˜ý璿蹊d�¬ÖÕÙ<§óÎÔ°u÷Üs50m&™:çC¥¥úwšÃÎÐcý;Õ]˜¯{ÇdÅØëÂ)½Œ†¶#׸L«NJ׿Wt—£«—·›ç•}xóUì¯ÀÞÓ½±±±±±±±±±ñ`<Óí–e˜±ê–oÒKç¹¥<ë�÷Ñów½a/ óå%wޝ<òëõúᘫ3̆Ÿ°<+Þ~'³ŒŸÁ"œeÕUü¯X”{Zn••Ke똈ŽõPlÊdiÐ¥éê�Ï<Ž�Çß1sÛ�Åt| ˘ØE·jÕÕ›Šãdà1¥ÒqÏ8Ìqø�› ó;ÕoU†ô ó­|x;‡ºžŽ·BP׎íB&vºý�ǯk¿Ëåãžj•—%…qeèâU[vì!ÇOŒö™>w³ci;&�ÓVÏ� vaR�¤´JOÜÃr§Õ L;�X‚ò¤þéòPà1>™çY.§ÇÎÌo*ÿ©¾|<•Ñí†�_×èi‰±:áu†¾sP6õÂ&æ[áÐèÆ—%•bÅ´k ýׯ_£Ní ø \çw†ÈÄ@=Ž�/lM&å4‘r¹´U�ª_¬ï¤üTÚg&Ù•6á Á-‹NÓJyŸ1*& œΉ iÌrûŸ‘ÛÝ܇'†öwÔoîš ×–Ü�ÃÂqœRrwºï•Þª­CÉ)œul$£Ëíñæwe*m÷<Õ�KÏ}í8!ÕW‚Ó¿.m÷,õÛ©qžŒá%—kÅè]Í7êŸaèMú`·�¯�NriOd_1ºÓXp6›úåk•ÿw{‘ro/ÙØØØØØØØØØx0ž–évÌ”ólÌ2um·Tá^æTò;¹Ñ‹s’`– ÃÕRûÛÛ›õá�æLÞÚgÏ2± |Í2M=\N;1h�<ÉËMíæXÕ—�)›œ”3–ýìªCªÛéÿŽáa6Ó˜Œ5u=eÿù%-¼çX%S�‰®¬®nêÚ±3®ý�‘årp¾î%!÷©:.N½<é^%·ÂÊj ÆÁSSœžŸ¦­úp'wÕ©ÒÅgVF± ¾n‰i¨8g�ÚU=ÏqÓ©@Ö�jnHŒì=ºÝÉÞ�W7:–ûŒnîr¶Ïïß¿ÿØ�Ýãt¶Ó½ÎÉ›˜nW{eWr$» õâw`ºŸÞè^©d^RqoêO”;wÌ“e�”KÉW×î¨=d8Q¿¾¾Æ‰BuÜ———wƺSrJI;å�& 4†êÚS–ÒfåÇqÒ@Ÿ*k† 'ïdB»)Ÿn)î8f@ª§»<§“”GßjØþüÉo4X�Ül€©çœ�*¯Ë<Î�qŸö«sp+Ž::QSÙ˜S=ˆa» Xár¹×ëõOoooÖÙHuîô‘jo.C2°î”\N»p©N¸o¥tT¼îžÂÔ°�€Ûèv»Éù¶à¶Ó¤|ݘU²ð³i>�³Ñé1ž«Î"ÍcÇ¡�K.ð¸vF÷TçW:–ÇNÚ§ït˪¡¯Òeû�íÔÏ3`o/ÙØØØØØØØØØx0ž–év÷Ù›Qž¶b™ ¢®ùç];oÒ±OÈ®¨7é1ߊƒ ¸b¶”—Y/Uþßÿýß’ß1e®'-§=aò;ÏvÕóuý‡WQÒÖ×ïRy¦uÔåUi%¶pÂ2¯Èíîs|—/ƯguN7²Ý¼¥¤î¹�NqÚÌ2§/TVZÜ.êÇ"÷÷¡$¥Oœnq¬>S2p+·Ë´ºò%V—õ�«cÜr‘bÌ31[© Ž¡ÇzÄ¥|Ǽ;½žÐµëgbšöjûóÿ´úƒíÄoKi;¦Ûé±T6–3Í]$}7…êC®N˜éÆøÝ*‰›K'ã51Û“ºgvœóUsë$½ºžœf÷lx*£»àN(©ûÓ=Ý«{m“·Òw†O˜t8âv LOp`£Óc#ë?4‚áºcÔ\ýL; n¢/9/¥d’0Qj*=gŒ¹£×8]W?É©påè ce¨>�Ògyð~’!9M8ž]xRï›WûÙxÅ4°-”ܪ¸¾¨  ÞÊ3MŒ*ÍÔ.Îp(½QÏxü;çqbx¬%nÌXWá)Lüþ §«ê!Ý]ùÜüâ¶Hp[ªøÜæS£$é WªÌ.~×.I§üœnVcLµ-÷ó¤S�ÃÃõ�aœ.à¹y 69ˆ ÉfC»®Ù†À´Võ²²uºv¯pjÌusl§Cœæñïæ´gÅSÝ®‘¸ÑÓ'ì|îÅOÉÁò°·é&UžÎx©I[)m·¿�qLë¯ëAåµvu’¸Ážê‡�!%·º¯ wWï©êf|“ÜNרëúïŒÊB9)?uϽ§¢Â*=�gnTݱlÉ ›:•X†:Lœ'ÝÏåÅáÓŸ:¦ŠaWF¶3º'ù&£²389—/ÇWc?ÆSc{<îœá¨â¹¹}•ÙTsë –—ÁýN9gç§‹�­ÃùuFwýŸœ•^¿n\:ý�ñ± jsc&9 ÎèN¶Ù³bïéÞØØØØØØØØØx0žžé®ÿÇ‘·—(¯×±[Š5QÞ˜“!} gR¦Ûí&ÙŸËåò�-ôyKIÝKDZü•þõz=~ýúõ'Üö!1â‰EÃ0Šy™²G,O—§ƒJƒ½nÜÃÝ} Ó]a?¦a;†*±aŽÕM,¨cÔ§ò¦¼ð~¥÷òòòŽévŒ?.¿r¨'p[UÊ7õiWVî·<®ƒ¥ä`#—ƹc–�~ÄkÕg–>îÂeàS˜íæ|«]Ýïé ®|NVfèñz²2˜êŸ'¹\_ï0aÇñšuX’=�‰É¼Á«¯X·SÆÞ�Ñɘu,w §äs+"+é©8ÎÖP§û(›F�W”¯Û>šÚ01ËS»Gý*Ù§+<¼Õwïéþ¸†­ çJç85Ù8Ã6å«þ³<“†ž<ÉèvõÀû»ñÁãx?‘a>8øpi÷ׯ_rMx:øÔ ÅëÎpã‰zªÈ0콓¶ /ߟ]R\]Ê]YuáØHuñ“A=Gœ^«íY•^¥‰[º—‹ùe7åL TN;½\‰ý19@i,q8%c×ïUÝa|åh8Œãvåse*�J ÇnŸÃß©‘¥ò¨{ì8¨zpÆIɉÇRNuËÔxíÀOÊoj M�ñsÙD)]‚ý Y•.cºg7éÇi&sádãôSßa£’ú¹§·Nv•–ou½bû¤y‘挣l1¿ßÁèÞÛK6666666666ŒoÁt;Ï‹½zÔÊìØZ%Ãôˆ/üŸØÅÂwl�z©òõõõ8Žãøùó§dëTÝà×*ùã",gz¦Xk噫zÃÿÌFñ}•ÞgÂ1†ŽAey:¬°b*üj?Qù'ÆFýwŒ?/a¦rpþÓÁ/ß¡<Ì´0;©NçaYSûá8ŸÉiÕüU¥Çú€ë¥Ã¤ž§}“óŸ2Ú“ºs[ªÿ¸mX÷ܧ§Ì²+Cbo1•Ô˱}Õ®n\®è Ìkr?�9®ë'n•(å›t3¦çŽ­t}2Õ·ƒcüù~bxñ×õõ”^‚󼊎c%±Ü«Ìv7ŽÔ8Ps¶’‡Ó™Œ_¥—UÛ([lºÝìYð´F·2¢Ór6M5é”J):ÃÚå›$N<*-ÉÉGªá@G£ÿ»ÏC+Ù*ìÏŸ?¥l]gf¥S†Sã¢ÌiàªçN§4:C»3þ'Fð™°JvRV ;e¤&ƒubà¥zR†¶‚s´95‰W·ueê¡óÁ÷QM–;KNgœ­LRø«Òrý„Ç[2À“ñŠé¤}»îäÎÇ¥­� ÇNÿcÚÊÈá-ÓelÌWí Wr;C4Õ�3î'ú8=wyu÷“³áú#;¥ÜWݵÎÉIóüåâ÷?§1ê€eèæ ¬Ü^Âé¥ÿu/å5÷SÛ§C “ô‰K‡�îŽx}Fìí%ÆS2ÝÇá=-dÁÝ �ìÁß{®òïß¿ßmÅHùN½?Åæ‚ÿUzèió9ݯ¯¯²¬éË•õµÊН^ná|ÌÞsÙ0 ¬ç5'VÇ1¦+L±K¯Sÿ™0>Ó¼¸¿vL¿c5x[Ô®ÍWÆ‘kcdŒ™=Ƹ8æ;ÖË1"¸EÀ�Þ’‚§Ÿ¸²§“lÜ8çòL1Åu}±ëWª]˜eæ6Ré³®2NV ’|œï„ywº?¥ÑéÁ¤·îYMp÷Ô˜Çç8×`Ÿ™ŒyÎkZµÀ׊e^]Hù°œÎ¦aÜ®;U&–-É�ì¯.}5—«ôÜ|ËÏÛ~ÚûxZ£Û½!ËË .œkP70•q¡º&„Ô)•<Vàîx*œ|ÜõÇñ~ÿ(ï÷ÆûnÐÞn·w'žtRÝÃ:RËFN)¡”GRê]zXv‡4ðÝÑk)�U¸%½‰¬O…Ÿ*`NÏ9SçÕ�¼Æ-%|*Œëï+Žƒ¿˜�š\:î#/Θ¯2¨4Õמɀø©?¸IN…©úÅ-8©Í•¬iü³¾SuQ'…¨~Çåá²M [g¨¹¥s^îŸêvÎß�5i;–ÝéH¾¿%C×ñ~§¼¥KÍIèÜ©r8Ý8Õ®¿'ÉóËdN[u*žêƒIþ©#Yés>]\U'ltOË–ÂNÆ«ÓÿßuO÷Þ^²±±±±±±±±±ñ`<-Ó­<$ö´˜™à%[dNðTƒ”ßd9Ƚa<}ÉÀy‹¼½$1‹(/Ÿ>¢>¢“^RÃ{×ëõOÚîDU>n—Ž!à4:/µcÈ«Túã äK ß ËÐaÂXW¸ +€H¬DbÛT:N¦I8Ž£Æ¥ÛvÀ,c÷6¿ZÑÂ1ŠŒš’7­²(VŽW“ë♊¿Â,ÖuÇ’w˜¬qYYNÖ_,�bPWW*0mõ—!!1´?~üøs ”Òÿ¥Ó nS9ºù¡Ã„iVý7Å™°ègʆñÜù÷x?Í;«ys>ie�õ%¯tiW˜n¾ãß銽úאּÑNκfûfjãÔ¯›ç§óÛ¼½äž²~žÞèV'…¨ýOŽ'%œÜÓñxn©…'pÕ©\SƒËÇûZÕdSaS=U•îï®´\çfÃË:6®8Î=Å+I±r|w¯› T™ºe:—·2:$ÁÅQ†Œ’UÝKíªŒ¸Ú’�ãÓQNW�Ü(ïévýÔÈãfâ,ðvŒ�íÊ·'É¢ �θP2¤úVÂ9NÜg”¡ÍqÒ=ĤLÎi¯y¦Ú�ÛÑ9"œ“Bu=Ç.måŸbUO&G¾‹ÏϦecL T׿�®šêb–eêø9C2¥<–ÔØã2aši p¸tÝÕ‹ê]ßàò9G]9ßåÔ’ÂÓݪá3ü"]ê\j˜2ªã9c? î´n"SJ»Òà Á9ÎÇ|ðSñõÌ©äÊ„Oª“©IJ&YÔä“”ûív³ÆÔjŸ©ôTê ,ÕÎÜ/”Ret re²ç|±®8œSîed×Ü_Íõ¦V’’lî?¦Éé)c0¹nŸsÒ;•—‡�í˜ÁgÅqSiM€ú?/¸²Àã`bt»8gœN5¹wFrÜÅ‚»ÕÈË“ñ‹Ï¦úQùLâ²ÁØÍ ˜~WÎíáž–u¥ýY§ž1�ŸÂ©ô؆8Û�'XÕñ*~²¿&õÈqœ}Ó¥q™éþ.Ø{º7666666666Œ§eº g·—‡f[:�*É¡d`/Ì-Ë$OO+af(©ädWìZÅw2)vµŽ,†§îqYS™�1zyyù�?Ö�c8¦^½«õß];†‡Ë7‘‰?ˆáÒN²:¤º_¹¯žq_sõÕ1÷õ ™Kw ¦‡'Wà¯4\>ŽmÅkÅÚ¨m|ß1Ý©Ü%?ç›ú÷´ïŸeº˜Ev2tíÌuâhu_Õ1³fÓq™ú{jÿN÷áóß¿ÿ÷Å_Ôƒ¨#WØg–»ï©o¸Õ½T�÷°‚Ýäâ på3•gÒS<—vÍG[»Ò.ܧ&z11Æ}0Måéàl¼ž2Ë« »*ç[׸»�ç‡ï€§7ºÕ p�‘^F˜L˜ÉøaúÛ^‚{µ•QãʃÏ�ñ£¾n¦ŒnŒSû»Q1tÊár¹¼Û «ŒxeLO ¿nÙÉP“8êyWß,ç¤ÜØVÇ1ÿZ–3r“ñ2…28]¸‰rg¹�CÇï,¸2©­b¬äÝKl©?²"OýFÕí�?Ž———xޏ*Ozi›åž|Û•kÅ¡R÷U¿ïú~éet+C«îsÝ£NI: 3Î�áÄicZJ&.oÉÿöööî(VÕ^J¯OÚ¨ A•†+ÓªQs6¬k‡$ƒë;*œ»ïtô=NCÅwóq—öĘætTšl¼213­×I=wÿœþ­ûnþQõÃqXþU'bo/ÙØØØØØØØØØØhñôLwçi)ƹ®Õ×îœw5].S2$FÜ¥¡þó}<ÉÄ1 )=~y˽–ê�Ù=<Žp¸b%ÏÖ±°g˜ÖÕx¶4ÅŸ€O¥IÌœcõ\Ÿãg‰¹Ye&lDêÜçÜJ“[1RáX>–S=ÃþÄòâ˜U§œÓíävŒS×Þ,£z6IƒŸ¥§7°ïMÆ)orGlâs¹�“�eÇ•=d…8÷B*–‰YkÖ実§>¨ú]Ç(»ûgæ+ŒçúRš[R_p:Wµ‘ªW–-å;éû]ÜÍYNw²|8�NÝèÆçêü9I_é UO¼•c2O§•.�Òœ†bº¿žÞèV®ÛÓ�¶—ð¤’ò«8 ¬€Ýþ0u„agVÙ”³€†QÛLpád…_®d£Y œô¸~p2M[]ø>ÖOš&ŠÛ¼›`&ç ¯‚û§79‘ƒ'/Wî¤dÏ •½®;+>9ÍÇ‘—G;‡@MÚjBIÆ^ãXT_}å|¦}ˆ LUÞTéþÄXá2³ŽtuËewçyc»rzNa8g@wïK°¬œg]»¾ÁN *êXvÌRÝ;c³›#T.¯©þR�JGÕ£k£„ÎÉa}‘Ú™Û$�|ʸŸ”Åê(/öÕŸ’1ìÐ9S|¯Ó.“¹f§Ó��¡ý·–ÇÞ^²±±±±±±±±±ñp| ¦›OP,žx ¼+żuìË�y*/L±#•§c4ø¦�Ë·ÌZ;9̨zÀ<Û[§™¸ò9¨:)w•ív,ççX̧å IDATPU¾•eÉĨ:9T·Jàäé¶+¡|Ž¥Hq8ÿ®œj|`zÈzâ– Œ›V§0lÇvã/Êàêñ &̲*ÄÁÂúÂçS6›ÓNL^ú�÷\¿Ml¨ëj{Ëêtu=Sã¥Ó;NfÎW�0“ÚÒ1â¥Ï{ëdêXÍ)[=E;*O^õàñ¥Úy’‡Su­ö4¾Òʦ±Âš¦vsãûIb¹Ï”5éy•çïäS}}œ;ùÒj?S‡d¼½½íí%ÿxbV S-A¨/ß¹¥Sîxlt+¥Ë²M'㊣–y·JÇå…u‚�7}ÞYë‘?œÃ2(y¸®N¹;9T>,C7©TyV éî9×cç )…;qª:ÇCÝç8g&ô4É(‡N�·¤Ð9Ÿ©‚OŽV'¯·Ëí¦·”°Âøl¼¨ä8§¡“Ï…Uí:éCxÏì°ü®^± U½‡ÿ¼{…AY±&í¯äÃ{¨¿�‡á.O$¸ñ¶:UM +•_;(LuOéóiY*­Ôþît—NÇ­ 9Iœw𫔬ŒÕ•öãñ¨ôSúÏq¦eÀkõnƒJ;éu.CgËpÃö’oat;O +]1ÝÈΆî¼T7(V™nVÄ\&î°îÅC7"PAñÀÁ=Ý.=e„ªÁ‰¬wG¨&¯¤xÐÁàpÝd¥à·cĪ&éO¬(”-k©�º>”dr2r¿X1°OpTYÒD4�3ôÊ`ä|�A¯dUi—ƒê‰:¿Y¥…F¥3ºÜdÏã@=O×i»6Rù¸¯Nbx&9’\ʸâñ?ùÂ¥#(œ¬Jg ð|âÊ…qKÏ;Ñ•§Ë£î¯èBDÒ}xÝÝ*~—v×ݘW환ͤOÎgçÃåÃ}ƒçe—¶º~$Ø®Jr+#ºdå4Ug‹q:lç•£ÍL÷wÄÞÓ½±±±±±±±±±ñ`| ¦ÛmÓè–»•XoçÁ*&Ú±ÛnIÄy¬‰Ábù‹Ir¬ßCÊkVxà�Þ WêØãã8ÞÉãNFárqÙp5B¡X¯ #Zù3Ót¹ècÆ:O{ Ç2NtþˆÒ”UWeJý̱˜çŠÜ˜Vúè�c�UÿdyT™;Ú­&%FÎiWøýû_$Ä÷Tdù“~q¬³‹Sp}»þ�ÚÙ� ÄõËã¯SÚårì6×kú@‹ZéHp§’¤}·¥ç' Byy["§?AÇLs¸Ät§´YÇ«q ¶B:Ý6)Ÿ[QèÒ›²ëÕ‡Óü<É#�¨¦úWšo;6ÙÉÒµ«šܸîöÇ«ûN†4>’m§Vò¿¾…ÑÍ�ì ÛÉ‘<<ɦ¼œrGƒ¯yÛ .‰ñD†i¹NÌË2…n S)(eìºcÏÜÀùÕu#j¯¥›D”((=¨ÒK†,?Sz]•C•U9ÊÄl–*k1ÿŠévËÖ*ßäÑ+öfzDá”UêØ×NŽ‘ä+»t•<®¯%r€:&’™nWw8>U3‰Ï:Ö Ÿ©±Ìã™\N‹ÇǤ]˜ís}Z1³õ›Úã«zTò¸q0e½ÓØÁ¸3\rOÆÄä>?s×éC` µj™ÆÏÜטÑVpÛ¢TÞiŒ(T,O×îÑËÃ�ÆÄD‡î™«G§ãº4n+ëÕÎNžÉÊÁDNµRá~9Üô´NÛ�95&&¶ÝÞ^ò/B-o¤møLíQT�î7ÊpÇ;£[)"%§3ø’¡ï”¦å ÛÔ©±~øë’è8¸½Ö˜vÌxšI哵«/ÞB’ŒÅN6Ž£”ªRx÷h–ÁM*iò›%ÙÓdÜ�×9>/ONŒW”[ÕQ=ãø]=pZNp}±âOûœ+-vL0­dàLÚ/ éÚµ9ËÓù–ÚcbŒ¥4Ó3žÀÕ{.)­’Aõ�鄞ڨÒQqÜøÇ1‘ ÖU�”ŒX5^ÕÂñ¡tˆÊ/96Nÿwpý6¥¡êQ¼© «uÎvˆÚʺeeY¸¾’ьת+Y1-—N —ÒSåJã€ÓBûD]Wìí%Æ·bºÕ¶µQ^>SÊQÌ�J[±˜¶Z’TL7nÛpL‰óâñúÇ�ïÇR*V¯Ñ w[M˜QÞ)çs½^ßµ…Ê_=SL7/ýOØè³Ìí=á]¾“ô+7a£¹ßT}§¼”,®LI6×oy\®Ô•*«ªCÇ‚¨°µµÄÕ#ö¹ß¿ÿùÔõz}—Ÿzù²ôLw:#­©û®lx=e·ñ¾c²ñ:¥(µ‡ëO+ÿ•l‰aÇpœÊêÚß�óÄò²NS/¤rYÜí×Ô\Ÿ˜ö¡³ »“Sé(Õ^ø‹s•ë“ÛÉÆe˜¤‡i*»ãLú]ýuHz~î·|�cDé>ÇÚóµš[œ]¥¶—|W|K£» &ô çNIH_[Ã_¨|ßuJµ�»®š€�¡ÏÏÜ©éX¿Ô©1ŽëàUWüoFšÌñ4µ_­Zb­r»6sÌâŒvÜÔ˜P'¡¸vå#1ëÚ9Е†z¿B•=µ‡I“šê÷ªÍÜøPcÇ"ê‚Tîɸ“8õU–/=W2¨ÿõB²ÊS±}n•£Ëß�—¯ê»cXQnîG‰sãÏ1ÖŠQVçØ+vNÕ�bMÕ¸T vÚNÇqxË ³ÛŽÝt,œjŸÄZº8(Ÿº_ÏT[NôzÝ¿G(¹Õ*ëGŒ{³­ÒâöOsêÕï:¶xÂ|:(V¿C•ûjJåtz"õ—Û#Ó6só¼ÊªÇU»¸9–ãuzG•Mõ 5‡9ýËm®^BýÛ˜îogt§Á�¤žá~L^^NËjØið>oÍÀ-$¼ÕÃ)%ËåSyqœËåÛ?ÒžìT—ø_Õ#¦ÁG²"SyáþsµÕÛR)tnJ†,ORæI±¦ºë&Éé2 ‡y¦#(�ó’UW?j¼¤­ØÎ*o%‹“OíeÃÖ¥ÁãĥdždýâxÅgoooö� 7iÖ8­0œçd2�ö-ÿªì<^™ˆpãÜ-å'\•…ãp>\Õ–]½)ý�Œ’î~g¸«¾Ð2JW%§@!9/ª¿»8nîKpi»´R¸Ï©´UŸSóâ´_¬À¯Ÿir\¿Ur©4¦˜ØUlŸ¸øI^7–• h‡ðq³ßßÊè>Ž�/»8¦[u–‚cºÕoÁMVnÐ1ÆÙM6˜žÊ‹ó¬¯è)ãUÂjbãÁ�<2ßè¥r'+Æ©²Ü9ÝX¾ £ ,‡r6&F7>?«0�™Èà”N=S2)'NÅé&O×^.¶¥2xÕ^ÆÏ˜„X&·¿›Ã$£²À/vª>¨äè^�DC·Ò«{¼Ü9qÎiRÉt¸=ÝéÈGÌ—Ë�/¨«zäøNn†SI¶‰¡ÏaÏîãNž“#íNOLŒTއ}/õ‡dXa:S¶~nŽâ|ÎäUm?qr1}§c™t[qVVuã$|7n]ºÜ7�>ICÍcN?qêÝ2fº¿;öžî����������ãÛ1Ý“%;Åt»%dÞ_”Øαí¼Ç9É­òãp‰ã#1\b£9¯Ê‡·—ði&œ�Ú#«®ÝÞP.¦Ï¿¼·¹ �É1mÌ2&ÆWa²’ÐÅ›0 ×mõù 8f߇@T¿WL¨ ëÀ}ºòäxnõã¹2(¹8f ‰Ywr©ÿ˜o¹rõ’î;Æ(1Ý®]ÓÊ„»ÇzÈÕ7÷ÓNî “öo«ø�ŽUsƒ‹ŸÀuèt6¯öq»$vÓëßÔ•ÞRm™Vd&õŸê.•ç8z}Èý›Ç¢Ò�ªï�aœ»Ý­x¤¹Áõ»ÕUÖ—S}˿ξquìòäúîl·¥DéåïŠogtóä®:G5*9¼N/Rvƒ’ÃUš˜oÅá<;g�'%Þr�ל6¿X‰²ª´8”�·š¨8˜þ/8ÛÛ˧êú8ôž|÷›œ©d89¸p«ñ�³¡ž9£„ëè3“3Îð¹êÃŒéÄÁy'ƒÕ¥�uâŒÊŠw_lì 0tüÔ}Ž31 .ýyù®Ž8ÿdt£œ8‹ª¯ª­pÉÉ™kJÇ:yx¬;Ö!lTLÆoÒ}Îv:Ÿ�E÷2¨Ê[ÝS}ÎéHÔó)'‡3xñ¿Ò¯.½dà;$£;•I�Û%…s†è4¯³˜8d.ŽkWu¨Áê–™TwI¹4Üö’¿{{ÉÆÆÆÆÆÆÆÆÆÆƒñí˜nçe¢GVž‘c ‘U`fL±£Šéf™8Ÿô"¥bªë~beUžUÅ c™8n÷"„*+²Ûè}ÇñaKË„Áâ¸ê…4lãôáf˜�‰ÄzDVódæM}¼§+G 3a#CÐ1 (·k?Lk…�QŒ(—ÇÛ¤ÏV“r1«ïV-¼r…/ù¡l®¾qübüTw\'‰aKLЄm=#ƒb¾�ããV!ÇXv÷”sýdÊ>ªq“äSi¹±ÌºØ1â©MϬ”a«—òº4¸ü\GNçs9°�[›ú*æïV4Ôu*_'¥ãVº>³lg^9ç¼Ï¤�8»òÅrÇÇ·Ú‚¿é°ŠI?IL·;Ö·òÅí%uÔ0Þÿð-�î´LwùôÞ^2=c™ :·l¨ }µ|“:� Ìɲ  |J ¢jÀb9”‚ë–ÿÜÿ´ÇïcÙÙIéN‘Pùª Ì=ãçݤ6ÉÓY™ð\š| LÊï« Jpn’ä}vJñ¦Érj@±!ªâó¸tûÏÑqÄ>uï�:TTgØN�JµG‘ϯ¯ø«}/ÝC£ËM~�è&WÕ�Uüô,é“TÇñÑèD=¡t ¶y'wªw„Ò']=² Úÿ«¼§Ggâ˜àm˜®{–ô—‰áôj2ÖV :žß&s�ë×õ�"ñR^¬?\MïOÛÂ�Ç«3®Óžu¼Çu§t�“ów'–|†ãô,ØÛK6666666666ŒoÇtÇ1òÈÜö^â“7ÛÂ^–:™„óQ 8o7Ág•'çëuö€+�:·»®™5ënåù+öèv{ž·ûƒ3ï˜73?Ž‘IrOÞJÛ1˜Ž±q,qÇt¥{)U/îÃ9‹˜˜n„êëIfn¿ôlºr¢–t¹]ÔyÜ%'³Wn\MÙÅ´³ÈãoU¾®OãõtÕb¢ëÜø¨ò¨²;.1�|‚ʤ¬é×#�-<Á�;×ÏŒùÄâº9 éëÄr{M_ÒtúŽç'Ob¤1œ 3•'!m)âvPs�’UÙŽy]™[]øTf'k—NZaÁëôL¥ëìÌ“õ²«£ªS\�BÖûobº¿¥Ñí:ÙÊ@àÓ/&{º¨È¸¦í%¸bÒÁ1}Þ*âŒR4ŒÕG8ÜÞ?•§2ìÑЮò¼¾¾?þ´Æ^2”±þqyßM©MpââÉgjÜ)cjÄ»4IÑ'%‡y°aƒÏp{Ñê^84Z9mvÀ¸�œ�‘ò°˜'·—K›Ç¯’ÛÕ¿£àÆüJyÎôÞ¶å>`ãê¤ËW…Kã’ã:]ÃåÀ¾‘–Ü»:š#É©`�ÈÿÝÒµSNžNV•6Ërz{œj#Ÿ•ž“‡ßñqõ˜¶›¸þãÊ” ÃéXêêÿ;�íʲ¢{•}qÖtsb’)¥Õéè.¾#\ÖÉÜ9/Ý6ÞÊ í¿é+”ˆomt'ö÷9c˜Y7)q‡ÂxÜY�QÂ{ ݾdÎGMx+F`&À¥Y@OϾ\.Çõz•u‡åA8ÅãXÁ̳ʪ ÷­d;£ i’LÏ:#ŒÃðË£ŽqÀþ\ñ’b¬ô°~SÿIîÄHM“ –çååE:Zžu�“!µ3æ«V™”ãçâ»6絩1�Ïy’«|ÜÙÜCáêë˃PúN¥=-7"�uq·JÃc~ l§d„pe|«v�|{ À/”»y£+çt\*p¿�Îc˜f§oÝÑ©)Íî^Ýä¾bg_8°ž˜Ô¿Ó�ê:=Sy¸gÊŽêÆeÜeh¿¾¾Þíä<+öžî����������ã[3ÝÉ#sKˆx�KoêC+É“tKአ®<;Ÿ=ufM:†ŸeÀò]¯×?Gðp=t¬ÊÀlr=}}ýó Ù-—–*Ÿú]•¯óê1L±�ne�Ù1%[ªfè\xÇÜ9¶V1 ª|I^¾§Ž\dùÜ5ËàVu8_Çöq}s[(tm‚}ŽËªöNËÀ²;p.Ï= ŸÀÂû~Õ’-·Ÿê‡,;³�(?_»òN˜NżOØöÄ¢)�‘d¾Ýnïöˆ&†�W3»>êÞJù(ù” ©|, *«b)][LóM}À…Qs ËåâÔµcWeãûé]°nu@¥¿ºŠ”àÊÊr¹•Õ¦ì6ÇSáPN>ÊU¥Wu­N/ùÛ˜î¿ÊèæecõÑ´½Ä-ç&5}©ÿcÞñû÷ïwç+……eMÇE¡±©ŽPë ƒ�ƒªß’÷ׯ_ÂâÉ«†-Ö ó«Põ�i©mªÍÕÝT&5ù»IHµ·3¬�¡Æ¨0ÊøÆúNƯÚkÏïF$ãZÉ®îcl¨9cЛn9˜Ç%OJ«™ ×A•Áí[TÛ JΉå�#–Ÿ+C¨ëß<OûŒ÷Û4fñzú®Ã¤búgÊÀi þçùÉ•ãó±€ø ¯SZS§mR¾Vÿ+Ÿ3Ýä^7VUìúɤNR_˜ÄOΰª/—>ÛuûÚ�ÞçÊ1žÝîÓïöö’����������ã[2Ý·T¬–†Ô5¾x¥^¤,(¯R±„õ e@9;±î+\±­xíd@9q‹‰óÂ;WÉÍ/.¦­&ÌÎ:9˜ááöHàçoooï–\y«‰cú\>¶–1an˜évi+VC}DÕ3ý|ŸËà‡¶?•¥c«k‹åf¶ŠeVc�óplMW–nud5 –ù8>žVáâ«ënµ¥k××CŠ÷xÌ+¶Îé0•6³h n{ajWÖô‘¯@¤ñœàÊ—ú¤[YdùÔÖ÷ŸóÄ6r+*ÏÉxSñ¦P:�™[ ›˜w¶Ü89»¢áòuσœÒqú$ÙK.œ“‰¯Ýu}–m$ü %n/ùÛð­�n×qØxåÆÅû¼ýBí•N�nÜ“­”>nO¶Ú×­äÁ´ÒÒ'o¥Á­+“N�8^sÙkðð ›²x�öO¯6¼¶î9§)íMJÛ¡Sdx­äqËr(WÉ­¶ÒÔÿÉ>àã8¤ÁÂùN'!n¥o¨ÿê,n%‡36:C7M\÷Éi¨û?~üøð•L΋�EN[å£ÚÕõAï3&>gd�©_gds·Ûmé,îz–duÇÄb˜”Æl@²ÃÒÅIùò{<.�t�dpÎÆªþæù¡Œ»‰£;éÏiÎvõ¥ÂLçƒUpcZ®Í’‘Ì×î§åŒu•ÙTN²Ñ­Æì߆½½dcccccccccãÁø«˜nd™ÝÆgåM1KÁYÇ„a<Îçrùç娒Ž<É ¯Z²™z©•ËZ¬.2ÝX¦3[{TùÇÿ¶šÔùÝxß} ÃT¸)CÆaÔò"¾Xré9f Óî ^NqaJî »¢žs8~îNëÁ:¨üÝK5œßïà˜3ÌÇ�¸¢ÊÇr ÓÜ17ÌL&™' =æÏg$»8u¿Û€rvõ39˹côY'©pSvT}ăÃâ˜êÂ¥ô îEúªG¥#;¦4µ †›0´œv={yyy§£yŒº±ít±›\_L÷:8v”ì¤É餾áòQm§ôNZùjTÛ»ºe=“ì"¾ß1Ý“p•7_§~„ã²¶–ü­ÄAüµF·Sº|] .}Ç-×ð#1Îíãgî¨3eTà/¦å&=–»ò¯U¦í.*�•{ظ¿›ËíòTKšÎèâü;#WB®ýÙQy’!Mاb:  Ü¼Õ„Ÿ¥-NJnžÈX¾éd:™8ùHNe�;ƒ»äVŽÇIý'Éëºq�ú–:…ƒóæöO§€$ãeVºEåŸú:¦áÚ&å«?Õ.ªß*™PGÖ7Ö½ÉxUiqùÎ,}w=ÎC. ê&nœüIº9£sê0}wͲu}Ç9ÆV9�Óq Â¢Þ˜êb‡iŸ8£+•Á͆¶“×ÉGMí*žs´Õ a˜ø_1º÷ö’����������ã[3ÝÇ¡—ïÙÃÇ7a–^¤tŒ /w&æ}²|ÃesK©_m]Qu…Œ3Ï•˜nf Ñf†^åSuêØm,ObÊX®ãøçóõÈì¨úÆ<+ml[UÜ.©~ Û•cÊ$ò©-“ÏLĽé˜'÷d£[¦dFžÇ\ÝslØÈ0r<§'Ô ÑØW™¥RÛ¾ðÚfÅuŠáÜ H¬«°~n·›üÀ•cƱ•ç„ycÖ’e@8æŒëû±ë ˜Þ cíÆ©kg5o0Jwz¾êG…ë˜î3¬ªºß•¥cTù¿+k’mnEÕË“+i¯†_Åd5€û>WLµJ+µYbÄ�¬¨ T9Žã½]V,÷ʼó]ñí�îԹܖÜGÄF .!ª EMõìåååÏbxf”qÏ–Áô)œRj÷r6d¸®]Új`¹Ayï©3zqâQÊFÉ“”¾rTžxÓ{yy±†uR⮎©-ùž ǧ•°2L²ñurü&“J2ÄX6·ÄíÆ;9j\¹r8Y§‡ªûÒx�uñ‡F=n R2©|�!Z×]yUx•vê <^Ô5CmÁqé«Sw8-g@a¿``}»~’t¾+nÞPåa=ÌýåaÇË÷¦ëÇNÏ©p��¯î;¬qI7»ûÊàäôx¤üï5]Ýaÿéæ •&§Ý]OÃ)ÃØÍÑj¼âÜW$OݸE÷oÅ_ct³!‹J×1Ýüâ#NönâP^aáåååݧÖ�ÑÍ™_¾ÂøŠÁv ¶ò*¤ôp`àþn•'Ö‘S(‹2>”¼hl8…ÏOBÔTº—]S8ÞÿœÚI„\ΑI8;"|í4׃ƒ{–Œ;”[küŒ�átF¥ªcçà©><™Ô'PùT}(Ç =eHMårÆB‚g“öW¡j3Ô-ʹSmÁ«MœOÇÇñáÈ1 “Œf,ƒÓuÉ0JúÑ�ßê舩8(—WéDÕŽSãµs””®rBÒ£“yÌ9J':§û÷e¤üÓù匾LΔÓiiŽUF2;¥,›²”í£ÊÀ¤‰³A”Ñ}¯ó°÷tolllllllll< Ó­¼³n{ z{ÅÔ¨e^fØ“D6¢â×~a”-í?çk.ïVL)?s[døÙ�?þë‡Ë;Ý>ï {„é ÷ûúúú�tKR\ÿx_yÔSÖ¯äT«%¿ÿŽûZ1d«Ôq”˜_�™—ŠïVC¬žá}fÊ\â:qõíÊ“àdgÆOp`GÉͧ•86’evýÔ±k ^UôñÚ…«2²\|¿Ó X¥«R](=–ÊÌéU>ÝÊ bዚƿc̹~ð‹vNÇr=¸²r=ª~“Z.7®,N�QLá\™œ< Nßrúö_Ééê+•!ÕMÇ�óZõNóg*G‚Ò']x•®³5ÝܱÖx=�ãê]ÙAJ6ÜÞ‹§—œ9è;âÛÝ…Ô‰xk7ôq|œÜù¥ÊFø õ"�ÛoÈ×J ðþÇ4O^ªä‰ÚíñÅpêÖ‹ºve¨ � §dÝr'‡+”Ã4Uäµ<›^ s˘Iy°l<9¤g]Y¸¸ Øæ(+;ÏS¸þ€íІBõ‹4vÎ(m×wÝdÁ†•s^Rd#_¤Tí¯úŒrD¸Í\>ªÉáuÏÒxIÿ9¾úïŒìÇnÛ€2 U>¼õ�ÛyRwø û·jÕïRûÇ!÷¿òw}UÅSŽRš?V nõÌ힤¡æË$Çqè/MNô­"I�IÝ«8…*›²50MÕ~꙲UÔ|€ÿÓ|ɲÕ;pÿ•ýÜDZ·—llllllllll< Ó­ÞVÇÿ݇r˜…pÇ«Uz˜6³‹‡åYeºs†yà3W'i»„b 9 ¿‰qÝòë„Ù¨´+îËˢáIK­õÙûŽ1PËy¼5'11Ša–ÉÉÛ…Q[\’ x­XOdò0ņTxuÒÎ=@YùãT•/Oâ’䄹™0`ÝJ�k5f9ÏÔG™ÍÂÕ< ‡W]ød%Õ8–Õ ‘ª;Å*«þ©Ø¸`þ» IDATP§ûÒŠÁ¤aêE8†bøÜ©$©�Ò¸œ0ª‰ýKaP§·X?¹í�ØO0?Þ¢èt·�o®cWß 5vêÚ1ª.�Žçb„[©pLpwÏé G�¡ 7+Sý4mKU_uít¤›¿yÅ_žÄí`ÝvÖ¿�Ñ­:—RÀî$“ãðû’”²rãóþhב'Ë7\VÌn’ç%q¥`0Üõz}÷ÙvÄÊ pù°¼XGXßÊùá´Ó„É{ò9ŒJ�ÉÆF’2f8~ROõ™¤T»‰g¢üX‰+y¸ Óí3NF•ž;½†ÛÌM"gò�ÄIõ­ÆÕqhǶÂñ}l/ާNàpsɃáxÛ˜’»sJÔ˜IõÃý.Õ_×—+?ìø®ŒB•Mé4W�,·› ’ñ›ðãÇë4;º#±¯Îè�Î�RiOóédpF †wH:Ë¥ÍýÂåµ¢SY§º'9)|?9 ,;œ“yÇéXõn„ÇŽ°D$£û¿‚½½dcccccccccãÁøk˜îãøø¡zQŒ·yàiÊûWט³·õüååå�÷Æ2 ÎË÷Êsw^<3ïŽÃ 2ʦغëõú!Ý{˜2¼æ_l >Ç81lŽ�¸\.òå´Ž‘QióVÕ8 ^wy)Ù˜éëàú*¿ ìÚŽÁ´q5bÂ4;6þ8þ׿\Ûrý¨±|Ï*�‹¯äæ1ÆlrA±”®Ž±]p{Éív{÷2¶Ãd¥¢Æ{W~ׇÕÿŽ-eLÓRPÏy±€ýïá¯zæÎæNìvÇ‚»­zJòj#1±�ët]Ú†4ÉÇÁÍ[œ–Ó�§c¡;9ÝÍy¥4VÀõ˜Xr7ŽTØ”‡Q+>øÌÙÇqH‰m'÷''#3Ýx¨Å•ÑÍÊÚn« *I4XxRÄAÃ�Z<¼\œ–”AÍ×¼= L6UÚ÷Ù¦åÑ©ñŠÿݲ(¶~)”�…$ j®ýÒr³*ߊÑ�éº-.n2ìÚ1奔_gp¥ â§¢sÆjû’«Gå,:cÈÉ�®SüT5æy뙓…ï³a¤ŒîôµÓÉd\ò¹gªNÙàÁþÔååîqý¹ôxŒ)#Ã1y‘ú —ÙµY'WÅq†múÒ/^»1Šá°žªlÎQä6Ä_¾Ïù&cqêØªg.þÔiV2¨ü ŒI{rŸ)fƒ·š¤úÁSj¸ ªŸ1ÃçÆ5çé ˜².³Ñ˜�?Õçê¾Ê‡·ÂñJEA­Mú1¯Š©¾�i «Xé´Â“ØmǨâÕ&®ï+&_mwš0ùŽÕ�ê.žÇ�Æš:å Ÿ¯ÈÑ�k§óƒ?E±—“¸jRa\|ž¶ìñq/Ò&†þ ÎÖ£Ò}ÓzTºý8ôŠH²50ŒÛv«ÚA•ÁÙK•æqüo>¯³¹___—gø[ðWÝ…š¹#Öµ2ÀßÞÞ>ì1ÅÉ�'wg «øgœpK“±+ øbÊÍ+j¼–ÂVŒ2¬“aÇqTYS²‡X–äõ*6¡ÒFÆß½¡ÌeO¬‡«>±¤Âq;q:Jõ[áy‰W>\[byÜÞx>¹€·%©•ÅM>,»c1nǺÿŽ)Ml÷­ªfu97F]¿U2¸ÿª?:ÆÛ•ï+fŸÇ¢Ó Þ"¦ö`cŸ›Bm%Ã:VýG…O{5U=$v»cÕ•<(wÒaŽ]e=Ãpí¯ÂT8µÁL'–CíûÇ<ÏÜs׬›T=¸±§ÒC$½• V&Œz7Ÿ§±ÇL÷*Òxéâ¹ð“¶äðI_ªp˜ßsÛnÓJ�…JO,ù/~ñ×ݼ �\4²ðœÈÚ×]ÀAÂiá3·´S(ã ‰2šyòå Æ)^6ÓÄÒåËFÕÍq¼7*•œ)_¾¾\.Î2ç2U84^Q!¸¾T}aÞé|Ún¯g2è+M΃óâý«x}Æ`qŠR˜iræ{§3˜Ô$ÇGoâXb�1ÅÏ8_uíʧÆÑdÒTõÆé!~ÿþýaÿ:Æá6WÎY¥ƒáŽã£>qrveàíc•v2Ô°îxüuý3õ±Ò•–“uï7uÆ5ËÍãÂÍ\ìÓÎÈà±�ÂU8_g;8G´ž%�­â8`ŸÁ{+p†ÿdL1ªý•ÞètçT—¢LfÕhWsÍ*¸+{‚Á6?«øh ©1ÂrÔ/*ø¼ÒÂ}ÜÿÕ³¹{{ÉÆÆÆÆÆÆÆÆÆÆƒñW2ÝÇñÑÃS/Râÿº¯â+-5¥%)µ%… §d1mõ«Œ©40]>ª\%÷õzý³§© ç”Ý,O²�’콫·,îŽ3â½n·” ž×Ë2&£Ô…cçÀõ»ÎXTò¤ s–‡ÏƒfÃJ>ìMœœ$Cšð”~ÎPSFwA½;PÏñ+”Øïy >cç%ìä:Óâí%ªÍ•#Ši`¹Ý«ì'|„iÉÁõ°â´©z¬²ºw2œQ‚é9#�ï¹>Ü�ôàÒfÃÍ•ùì¸çtø×ýÔÈuNÏ�“mVª|®¾\]�ÕÎPw²âs5‡ñ¼xz̧yŸÃ°í“¶– ||r�BÝu6÷õ˜@ÄÞ^²±±±±±±±±±ñ`üÕL·zQ�ßÒåí%ø5Fd–øÌnõ‚SwB„òþÓR:_»râ/³cœ§c#ãê‘—Y#Ȩ́íÞêǼ/—NáúV×UnUw\ß,ƒn;Ri0‹Y÷™ívìvbÄcܱ%(‹Jã$&1�ŽygÖ“W‰ÔŠˆÛ’¤˜2N±z“xø,­Ž0:¶Ž™{n3ì'ŽÝd½Ãc\•É•Íýçû+ÌdZÑÀkn”�ÏpWr:†Ç¥b¼kÕélû)^Áé·êp»½?¦c1œ’›ÛÈéµ³Œ3ÆQדønå#Åqú›W‰»ñ{–Áîæ.uÿÌÊBj —nk•Ó{Žéæqä˜î´£V_9ÏÚZ‚'–Lúûߌ¿Öè>½Ä‚ŠKícRûÃŽãýäà¶—TúáÂuûW�!;)k·<åê‡ËŒ2£‘‹Íá¸Ê(U LMΜO^jÂâ�‡8# •M÷59öh¢ÈT<‘AÅQÛ-œñª”˃u¢”¹›üT;0Ü„U²©7Ùù¤'7–Ÿ¯R;«¼\9ð~Ê×�;¬ûT>„3ȹýpl)G¿“‘'øT–ºïtˆ:­„ÇqJ»Þ‡ÁpèT° \ŽJCÎuÏ8]×�7Œ‡ÏXr¥[U=+j2PvNG¥ÁFÒÄ�võ žMâ`׿llò<¡dàq™Ê3™Ÿ&à8Ó:�Ô!Û쀹:NuÊ tcIÍÕÇñÞQfg�ì_¿~½Û^ò_Ç_mt«}Ó¬´ñ¥Jü¯˜ÜãøÇR{qÂTŠZ då¹;ƒÕy¬üßÎÉÈQa”ÒÀ ¥êêçÏŸÇõz}Ç,aýð£êÂP///ïönòäŒÆ92^Õ+pÞ+›Î!¯8ãPµ‹Sî\îÎÐNÆ�cŒ±>êz2)©xJ6'²„ÜŸœq·b|§IjbL�{þ¯ÒÀ¶ãqèò-9»ñÂý{â8TÚ];«û˜öGt"�~seåq‰ã��ça=`Ú¬;Y®Ô§”^Bƒ‚ûRg�ã3^ÑàøI¶‰œü¬Ë*;Zê9ßSé(gAýWy¨²ª9Ç•K—Óœêþ?Õ+ãª�W¶ þ{çºÝF®+áV,9óþ/»'¶':?æÀ)}®)g<“ j-/·úB‚l^ÀˆvбÓVãuö«N¾ÕBYå,¦ûw¨ŸîÁ`0 ƒÁàƒñK3ݲGºZdø@Çt+ƒE¦›¬Egî,è}ßëÓí®¹çÉf¤c•­cÔô™ú¨�~XHÙcçÎô5}¦®¹²®ºÉŒÐêàÊZu¯2¹ôÎçó›:é|�úÁ�.üŸ+�ƒOYS;¹ÇôÙ1jd·ë˜¦Æô¡“Fexs·zNŸa[ë°S_Úîu¬¡EEïO}BŸat�N¶Îú’˜™oÝ WeÝQ$ÓdãL¾)7!×qÚ IYÝÃM;ò¹É5•õ‹ç:wžwJ}–]š.Oí;IéÖ6èòÖtÙ_WJúN»â½�O·>çÚ³sQYÉ�H ]¿TæÅJÛmJÇÝGå')ü©¬ÚftoJ§8î*¼.�îºË««»�Å1ûö’モ7�¿wÁÂúÕùåžçS½&82ê8Þú¯sC?ïWÙÝq¥so?õ®åìÞw"™‡*ݧ{0î%ƒÁ`0 ƒÁ‡ã·`º•)aè­:_Îþn%HÆš¦ÞÄ`¯BÑ•ld�;“”žKé¥ã”¶+ËQõ–ØH2ÝzŸºæhh&LL�šÁ”½s»×y\ùè;Wö›Ç޽'cÈè5ZWŸ]“-P¤kƒš¬#”c‡±ri¸ö­_-Æ2…sV&'ƒûÝÉÝ=¿‹ŽÕO,^bxÓæÌªú<û%û„¶ÁÄt³Ñâ“Úe¨ü:›eHåwm†LY²²-«|l?쇩:y ®¿9v6Õ‰«G^SV¿¿W¬ðª¾9~óšbg¡5"•OŸI}ªËGïa4 Z0î±Ì¤sš–+_é + Ij ÷ÈÀçS»OVBM¿+?-FN×qi³ï¬ôe¶+\à® ßï€ßBé>Žã�²WÇÚðœŸÓqܺÔ ”L¤nvƒ ÛÊÓ)áúl�ƒƒS8�%ùœr^i©|I™r>Ô>«Ò„ “•~~Þå[÷©2­¿“Oçw[¿]>Ú8 tŽ*i ×A­Ûîþ×}t¯Ñ<]ùô>78Ri:Ž·á¢ô']@¥÷¬uÂ÷@tJäîä¬é¬”^K‹E—¦¶Õ’RûHJ[ÇçÎÃÈ=, åKåîdpõ¹sŽõV{?ÒxÄßÚGÓøHÅLû,eá>½¦i³Ý»1¨S*w/]¾ºÅâêÞãèû9eHõØõµ¤øSçÁÕ¢ñ¤úÑq‹mæž:®ó¬—¤wî‚+%yõLw£µÕq׆õ¸#Œ4½ ¨1ºcÜKƒÁ`0 ƒÆoÃt'ö˜› ÓíVþúa˜?Wânºã*p/žòI s£¿;—2UÑ„Œ˜ï.3å˜eçj¢×”ý¥•AåÖ|Û¯ãèÊLV^ËëòuìIbQ[ãÌ¥;ŒšÞ£egý¤èŽ¥\±*dþ:æh‡Aã}ІÇÉ—�ú#Y*-_çÊ–Ú ³ìÔ1Ùc'7­7©]°=2íÔ_Rý�ÏçèΡ²%–/¹ƒ¹¶åú|õƒ´¹Û•»ê{—µÝ©¶é�¾¸Ê¯»Ç]ëØß”6ÙpÇœ»gVlµ²°»¬®c–»û�Ü”SYo–euÜÉãÆ^gY õƹ12ß”ŸKÏé7ÎJæää\E¨«®2ÝãZr‹ßNéVÅ‘�:}®ôëׯ¯ÊcuUºu2t¾Ã.lZ’-)×TDˆ•Y‘é%e¦K; n.­zæáááµîhfJƒ+ËÒ…[Ó´œ)¬îs #F"áNu7ÀTº•÷ù|¶Š¿S\Ü�´O'6Ñ!µ…493JFšhiZ¤˜”»3q7¹«¶*çNÚ»÷R)YMJú '¿T.üxÍMî5ætmÈÉëÔé™Ôt™I“³¶Ÿî“êìÏNé^�aÝ8V2h=°Oq‘©ÿW2×ó;‹3}ž ¾Sø\~)BнpŠèj±°3ßðw�sqèæ«ü˜7ï­rº>梕è»tew |š/u¼MʹŽ©Ý+bBÛ:IFÖ�+Ç×¾¯×ëëüþüü<Ÿ}o0î%ƒÁ`0 ƒÁã·aº 4OÔÇ_ê] ¦H&ŠŽ=TvW¬dtƒéXǾwé‘mwæd'»®†]üîT6‚¬Y±ÓÇ‘#8Yõ5‰j\\=ÖçɆ¨¼×ëÕFjqLw*¯cñK½g‡9Ûe]’,î9çR¢Çîƒ"‰áÝeeõ|Ú÷Voõ¼¶õd¡"›éÊíúQÚp{Ç͸£õéúTEŽÑo¸t‹5]1oŠö[ËçÒH®&dÊ’,´n踼b³Ó9~¬)¹«¹ö½Ê#µ™n\æøŸÚSÊ—Län_èênÅt»ü“kgÜI®}«²tÖš÷Œ :¦§z}ÏØ›®w ê$‰%^ååØrÕivÝ>ØSûÔ´õc8³‰ò-~;¥[µvªjœê¦>޳ ¸úØCç M’ùÔMâzÞ r�M?çdÚë&€EŽ Upy¿“Çur½OÓѲÑmÄ)Ó G¨×ÒàRçu ¦›…ÖÏjÐfÒÕÃÝ»šh:ÅÉ¥ÑÉ™m]L9y’/b§ $?[­ïäÍrvH‹Ò„ºïŨÚ`Z\³=j}é"NeÐÈ1ÚÖZ?®ÎîUºûYîXëà|>·é%‚€fñäj¢ù:ªþ»Et=Ó¹’89]$…µ««�Ðî{éäÝÁê�Öqê{ižâ¹•ÏòV‹°VeÕv’úï{òêæsW'iÜÖÿ —ž.^»0�Ú†9?²}W>)bɸ–¼Åo§tÇ-ËÁÀ­up¨M‘ª| þüülYïb2\cÕc*Ýé>§Œ¹ûÜÀ˜”ëîù•âß±T¦5\˜®‚“ŸóŠHu¢Š67bj}ë}šŸëÀS¿Ý5·É²S€¨¸kz®¬)½]6Ä=§uçü¸yÌt3¹’1)+z-M~]Ú\T¾÷Ö±{G:ž°Ü:ºÐ‚|'´¥¾“¬»Ê/Ïï*z_õy†íòï”î4†1ÿ¤XS·1Ú‘iì”c=—ëNQçóI±Ýé;´:QÞDt¤w¾êÛ»cƒÖWª»ÕB¥#)\™8®k¿ºgáÚ½gÍß½—Õ¢Ò�õÃçœÒ�ö˜ð7û‘«ËJ»”n�ÓýÞñöWÆøtƒÁ`0 ŒßšéÖ¡cº�w¹œN'ï³Ü1Û µ*uLŽ®Î;öyÅ€$3–š´¹"×gW¦,ÊAYëØ…Q$ã¯é¸•·²‚ºû]„ú¯Ï¨lún¹{]ìÄ.“ в&_òÄl±xœÎ‘êбVzOb7vX�Ĩuò𸞧Ï-˰Ãt®òwu·b‡w™ogR«ËðòòòÊ Óº¢löù|~e–’%§³tã‘ê'¹Ó1WžJ×µuŽÅiŽëZß�«ˆkÇt¹ã<±ªËÊ_Û®»¯ëßk¾Š‚•°s_W6÷ŽSº“�ŽÓ»ãDW_»V4½ß1ÚuÌúvלdG¦•æâdÉ¡ ©¯2=µ¢¥=U*+ëGçA–§òш%ª; Þâ·Tº ti Ò­ao’ùW•n5ŸRYPŶ“§3)¹ÁgeâKipÁ‘\v:ºÏ옺ÊDÞɪpiÇq£0'ÿ1útëÂHeRw�´ÕÕ™bÕé+–�ƒëU'~=·;ÁìN N«/®vþÄII¦ü]è8*ON‘|O9W a·àì¶]þ;‹ÊJ[Í´Õ/—‹Í÷z½Þì%¡ï§[üºã�…Új±™ÚtAÝ“œ Œ�®×k4…wãcRPÝ{v ê4†ÕïÔî´O¸¶ë�úrR✢öQP¹9Žílvt‹)UöVi°ïðw§”ºc}f5.w{rœÂËñ;�qnžæ"“÷¹ö½zïU¿ìKÇñ–Hdùõw7�i^&ðÞMš¿+ƽd0 ƒÁ`0ø`üöL7͉Êzº�¾d£•É9ŸÏ7‚ÑÕbb*¹‚ïV½‰…azÝÊ;1F)róå5-_2ç¹|ªî”ý×r§0Nõœ+Ÿš‰ •¤3�©ldx;¦Kóaä'+™­ÇÎb iP–ÔN«îîKeWÖÃ1IŽÁrìLb SÛê®ue]±Blß̇ò®°b½³Åv¡L·²ÙdqùÑ)gmqé;Y]ßeRÝÆqm'Ü<™êGë¤ÆÛ�0�|_«±�ò¹²Ç­Õ«Ú‰¾³dña}×1Ýé8»6M9Ýó®|zOê‹iì �'¥íd*pþtyî2çÝšÆ7͇¿Y'Ü8ùžq @ Ç07SOØí‡©=éxÒ}1™uçæ;Z[¾~½�ö¦ù 2~k¥›©þfc¥î¾Ä¶ ˜&Z•g5Àè½îºë®ê|RŒÜ"À)¶)Ÿ‚ó‡§â�ÿTF7‘©Œ|/š¶*<N~+eOŸY-´ØNº‰ŒåK 0eqçÜ„¬r»EA23º¨;i¢ÞQÀܵÕs©®Ý3L7)g ®_Ô³®MÕo·øtý×})Î)ÒêÖVíÖÝçLÉ© ]™ºóIYÜñ«.pìuäC—FÊË-XÒÂMÛ:£ä¤þÒ)t7^jÙRÚ ;‹ÊôÜÎ=®|÷(Ú…š/wä; ¸»¾[¦t¯?¾GžUù\t´”n'•v.`“›V×n]_vò»0�£t÷÷’Á`0 ƒÁàƒñ[3ÝÇqëÒ +D5�¨y¬VŽÅDY�IKöie"U9êø֛ǎt&-®”Él8–|Åà®ÊJóÝù|~½v>Ÿß¬ü]~d¶ô~4GËDF>­Ìëý f1ÌŽýqLgb½´ dÚÜ{quáÌÝz=mªc÷^+-·c�¬™['+óÙ‘Á•Õ•ƒlÍjóÏßË&Y“‹Åqx3uêoumg³“º­Ü˜RßqV‚]FЕWeè"–¤ã]¦;ÉÖYDR´˜Äø»:a~IžT‡«¶ÞÉàê YoV¬µæ»ê�ÝóÇqû…UçZq/º|Wõ™êÊ=¯ãÞ=§nó¤×Wsñ= %Á¹ÉÒ�¶PeK}Y¡ò¥`ï‘ÿwÂo¯tsòsî%.| NXn²Ñ�^Õˆi®t²èEßO'7ÿ'åÎM©Ó»ŽéÒë7¹RÁШ)Ée‡å£2¾ãcìä;ÿUÌäK®‹ý�Þ+£©¤‰¬›8Ó¢‹Ïh=êu•Ç)Ìi²qJ¸K{Çü¯ÏìLŽDê+uRè]:̃‹œ]pѤò¤>Ãrèâ^ÓÐcg´m2/ý$¼Ë3-€];Ñ=*;Ðw«~ÜnOÀjIsûê½t ‡Õ"ˆåaßqe¾÷Z�Ríº¸ð9—~ýïÆ7V¤1Èå«Ê÷@­°šOºçvÒN‹�4n8wµT�|.É�c¦uïxD·Ý¡ºK·XqJx•‡s�~î}ÂÞ�ß^é.Ôä§"…ÔköNÙ§Ëår<==½>Ÿ”M'Ç=+`wÞM<«Ó¥ÇyRÚ8!¤‰^ÓªÎì&Aeºkv ‹>× \n ­óŒË]÷=<<ÜȦ«\Aæ©Jw“ÀÎBÆ)ðiq¦eK“.•l†yset“±k'î÷ÎBµ%Þ×)Ú¬ãTß.ï{ Êp·HM}¹ÂYº÷Ö-º5¿´áRÃij^”� <ïnaØ¥A¹]{q~­Üðżv6K¦ûØžºóLñ€ IDAT¶ÅçÓxÉ~äÞ•>»b~Ý¿îKm5�ì#Ýxõ¥[ÓrŒ*Ç„{ ;瘆›ûº1#�!iÁåÀqÙ-´uÎrý`§Ž™v:V+=I¼”.ë«›«œÒí>+?ðŸîÁ`0 ƒÁàƒ1L÷ÿ£Vçêî Kè»”" ¨‰µXðçççvE®ÐkëݱjÝÊÝå³sÌ|³œØä•_k•µ n:tçqyWÚ‰9Iþáu¿¾Ë•i�ÑMûß™'ÉwfGWÖj§Êˆ¹rkž%[jlÃŽéÐô];Y±Bl;‰ßeôvêΜÒÞŪ½è;u¬óM}ÄëWdÕ‡“÷u¬j�Wfšaþœlîz²Žè3dùÓ½bûÒD‹M¡³t$«œ¦WÑNväsåuHyumºc†wÆüÎjÔY´ºÈ#ú.]”Œ®+æ¼ûíÊÇk»u¹»ûuÎX•+õË4Î'yë™´÷‹úJzls‰éV(‹®.%:î zŒÒ-àF§t—¿š0t19Ž¿êÚlùåË—h²«¼ê<'Ÿ�Ž™”ø]e5¹»I;»¼ Ý&ͤЗ+‡SŒ™˨.!+ÿîºßù•å«ý¦#*dI‘Õò¤zpõË ¡îÞ´hJ“J ¸«Ié{X'ëî¹Â*=§¬¤²Ü;i³ ²îS_æ~}FÝØèV¥J¡~�’‹7m_® œdwÞÿ* w•[Ž£ª€3m­“n\Ó>§åÝéÿ”9•ƒJejs;Š'Ëê6®ŽïYˆv æÎâšïD]‚î]”$tsÉnuJeº¯;^Õ9ó¡¬Ý\îÊÑ�ù¼Ï½£RŠ]¿bZŽ4§U­ùOõ¢q-ÙǸ— ƒÁ`0 ŒaºtçP¦›»�õšF´pî%çóùÍfÊÄÓl”VÊ 둘˜Ä,Tž)šÉNÞú|—7ͼÊÒ©%!AŸçÇCtï6´èoÇ;vTYFŽLYÖI·Ùñ8¾¹»tÖ„¶§k3.J‰ž_¹Mè³Üèªù%fm7í{ÑY>ŽãíWCwX —†c·ûX¿éBUç]û*(“H&JËZm�‘•’©ŸÌ–Ž[dïv"‘°h9ÓøÆÍ“ÝF/E*Ob‰¹q‘itì_ý×:®4™Nµ¹ëMÊKÑ1¼‰ñ%3›Æ Çä»ûº1$Y*:kRÇTïXKWØ[îa°]ºŽf_Nl4™îÕ{VtéÇ· .zLg HL7Ç¢&p˜î}ŒÒ ¨Â£#™¸OÄÓͤ&¡Šd¢ 9… ;Ž[óëŽÒÝ 4ìp«�–Ê MWêGšÒX�Ók.:ƒËSë¶›HꙤ4r`LSŠjR“¯º»èW5uNƒ—þv¡‹6áÊ¡Ç+å¶«Í“;ðS¼bU^;ÿõ”_WÞ«åÓãn'%E’ò­Â2Vš®\𶫝”·î!Ðo¨ 5IÓva+Ý¢’íTëȵ Í›ÏQ6–1¹f¨çÒX-2»ð�÷(Æ®}ºyÇ]{î¬陎%LÖ­tÎm¢TyÔ=ÄmΫô4ßÄf;æÛó¿«7ž¬Æ²™É’òñj�lÇÚ¶\xŽQ®’œ“©ï&õs—÷*½ŽyM÷ñ½¸ô )BÉêy7ï¤ò¬Æ‘®L÷œïбÜ]œxÎßz_ªm7�›Fg½¡>ÂMÉ%_WV[_ózyy9žŸŸo¬þãVr?FéÐOÓ‡›Jw«„š|ŽÇÇÇ×�åtJ‰v,v=Ÿ:­¦Ù .�âà&0ÊšžÕrt÷¸c—OM�ÎÇût:½Q  ÝÇ=R=¦2ªŸìétû¡5Ùk›q!Wƒ=ß¿„<9Q§ô\úUÎô^WëyU*“{ #ë8…Þíx�Ò�®í€ùPÁI ²î¹±‚J—kU÷FFayv®w ]Rë¹�}*;J7Cåî.zSz<Ïy+�;Ýow�ï±S>U–toO8~k_våÜYäèuŽù:�ÑÏú=î%®¨ÛWŽš×n¿|ø— ƒÁ`0 ŒaºÈ2«YM?šv ssÓù|~ý­‘L\ìÜÓ}/Ëà°b#5Ÿ#ºb‹�|÷°æ¬#·"gô]ɧºsìN*“n°=Žo±º/—‹�Æ Ñ\™v@VÑ¥Åòí¤Åç+�º¯Ût©é‘áqu·b¦RÛØ©£nCbW^>“>2D&èž~æär ?û˜FCÒr(ËÅè%zŸc°Ý†We¶\Ù4 =ÖëdȵL*w*+�É`;f¹«ã]ƹc:w¬¬c½'õîݧúÚ‘™2¸:H1àݱ»æÆ·Ý>êÒOèît÷ÎRÿH²9öW±Šw¿jß»pºA½—6£ˆè{bÙ»ãd©J‘ÛÆµä}¥»A5®OŸ>½*Ù—Ëå&@<ÑkçR÷’óùü}àùùÙš‰¨kÇJ»•WtJ[ïÓ|::'™si¾u“¬Ë‡÷¹kI1tJzšdvCW¢M+ýH‰NvZ^ú”¦¼*MýÏ´ºrhÝ» IÛ–ÊÖùM'…ú|>Û¯´:™vÌ»©\ÝDŸd£RÃÉ}¥2=¶9ï(m”¿®±�§múŒ+KZ�QžU™èîÂg\;£²¨y“pêÚsRÞ£ˆòÜÎ;[-˜w®i½vcbš³wQ NM�éÖouk¤O÷jÁªe«>®÷iÚŒV2J÷÷a”îŽé®F§ Qre•tóßóóó«Ò­!çC¤�Ö± TŠ’R¡`Ú«�HÓÞQÀv˜§(&…¼l’¡²q@ÐÉQ7¦Átw²ÐçÉ‘1N駉cG¯ßnC SàC§ 3Óv“;•ˆnq–°£@W’Ò¤÷ï0oÝQÓÞÉo…ÔXWýõ×M›LJÛÎB›ÊôqÜŽcî‹«É7›2èµR¸Ó¢Îµu7ž¤‰›þç.ÝN©IõÈ÷›ÆÁîýò~.À;¥9¥woŸI„ƒ;ïÚwg9¥B—ÆÇ$·›tÜØ-k×Îõ8õÙTW)7?º±Tórs“Ö×N;ÚiÃî¿ æ�Xn-“;¦Ò]ù8]gÂ~Ƨ{0 ƒÁ`0ø` Ó½]=vL7™ÎBùsÓ]Ì÷q¼eºë\ýN¬� THÌrŠqtÌMÇ,¾gåžž_1ÝZšºé‡}oÍÁ÷0gî÷ËËË £Xm¡BvŒ¶K—eJeíØ?ç«[ï+™±õ˜ìHb3“<%Ç=p¬|ɳò/w²í²ŒzïÊT½ËЭ õ]®=é](ÈX“•;Ž[ [Eè>ŠÄç;“½ö±b¹“õeUþ*GÇ”:7Œ㿲VUù’…,¥µº÷8úH&kªéu¬°ÊÝYÍÔ½ˆò¤ç8†8—’ïiÿïyÖÕñª�êïô1+ýßµ[ݳÀHi½gMj¿Ž)§•ˆÖw·÷‹ù¥~N–»Ò©´Sd”Áû0J÷ØðT¹z~~~U ÙøéÓ­n(>°óKî%ªXí(v+$åŽ&Ä•2¼J›URuà¹çë}œH©Øð>ú»ÇaMgÝä~½^_ß«Nº///7±ÙO§ÛÐ]š•§ô>ùnµ $Sªš“©„« š6]U4 §Ð«Ë�K{;“,ñ=“y½W'Î$½2ïBMêÈÖ5§€k¾5±:ÿlwjá—6ҥɘÿ�Ò­ IaµwŠCªK�7®÷ݳ0NíÉ•—ϬÆÕTV�ýÎ:vrî¸hZI>MOÛBÛ™ßK·°ás,KWŽUšŠÕ"§»Ç)’zÏjÁVõèîïÉß»Há{àyçòÊc-§[Dó¼óçææÉãø¦tÿSäÃïŠq/ ƒÁ`0 >Ãto‚¦] j$“r!Q¶ "—»}¹\^M€>Э�ÓÊ–«ë€K•ØÑÄ–&fÚ�w ™2û«|ÈÀiXGšh5<›¦AÆ›l=™�ÊGÃB*ƒ@6Ó¥MÆYáe*\=v,º2ï,Ÿ2*É\KöTïÓH&l«»lXb"»öö¬~'†{ånàžïîÕzØùèMj'�©[Û‚nØv2tfgw�–²h.|`W.öå®=ï°µ»èØ¿.m-»Ž5ìcdš]Úß;>óš¶ß’mÅŽ—¬�‹BŠÁ&‹~Oš©îÉú÷Þú¼'¯­0©NhíHój²~ë{I›'Ó­ùwÖ-ÍǹÏÎ&Ê£to‚»¹UÑRW“ÏŸ?ÇñÖ7ë|>¿*xúåJ5£Ö½ÎIÓR2Ù«Ág羕 q•ÿî Ôå�ɤlRùpù”RÜ™ �¬©®t°:�N7 *ä8³ì)¯4q;Så£n ©¬š¶*„ÇáÝmêþ¤ ºAœy¸|v”Ó½} úZš vÒaYRÛ<Žoe`ä.šÝ;Ò6úHåÓ�~…ôÙ{B`�†’”šäß½Zh;Y8¦%œclW–�²¾g u}7™íÓ3zŽí†ãü® l߬»¤,Þ£ weº÷–mwî*ì>“æ >¯ó,ëQ±³Xáó”!Íí”Å‘pƯòbÞ”AÇoŽ+ A¨Çïyσ[Œ{É`0 ƒÁ`ðÁ¦{µÂ+f[ÝŠÝ|zzz½â8¾mn*ד§§§¦[ÙQ2Ai3w8;“-å¿—9`ÙõØ1VÎTº2o¦´É*¬Z½§˜CÇþ*#Pl¸‹‘üæçz½Ý §ÿõ£%Êrp“g*[b/´,Z&æÃ´•5Y1D.†÷étº)+ò1ý[Ê ÷0ídzÝ}Wd£UÖ[êÚ÷n^nST'v‹Öe­;¶[�—;YŒ˜–cº�yºÛX[ù$ ¯±NVïšLdãœl�EÂÕI’›õÈ~Ðõ¿t¬¿iMrÖ·®ŸwVÎ-÷²˜ï/Wc~É}ï|µãÖEBJV'۪˫K›÷§þ¯ÇÚ'î‰Xâd ¥²Ò©´�{ɸ–ü3¥ûN0lNŠdòøøøÆô©!õC9úCvv×¹]‡ÛQ6ôÿ꾄NévJSzÞ ŠI!ÐßTR�ÜUWTª <4šÉŽÍ“i¢O&ñJÃÉÆwÒ)`�‚áž×{™•�TwzL…‰÷Ü£¼nA±«­”î4AvéêB¯î£ï'åvÿ;¥;õÍSˤ ‚ûÈ—Þ“ê$ÕiZ˜vJ7•d÷<Ñ)¸TüÒG§Üó.ÿ´¸Nr:…ÎÝÇ/ Þ«p;¤z¹÷žn bZ�r¾3é}®�;Û³žßQ~y/Çå´�¹^¯7ï,)ݬwÜE,Iî%;.~ƒ5Fé¾×ëõfCÁÃÃÃÍFJ=VeZCyé¦J�ÙÍ/ûU~•†'¦[ó¹; ïëX ÷Œ›<ÓCÏ;Ø:ŸØ¢c½�rÎ�,…Ñ[)¨ªl¯äéØŽÕäëêŸí -X’‚C* —�¾ýR!ów *摘BwN"-ÎÒÕÕ�¦·« t 7'\íÏ:¶¸´ê÷Jù¬~©ò;¥ÛMÒj9qu§t+Üx¡é¹°gn\XùÍV9]=¬qiaÃúqJÁ1‰1ÓSùÜ»tãh/ù¬¦ëävŠšbÕÆ»2쟾¢èÒîÎ¥ù©çWïá¸=Z<®þá”î47ñ·»E¼‡˜Í“‡ñé ƒÁ`0 >Ãt߉b¢Ôw[WˆÅ`3| ®‚5d`}­ò8nÝF*¯BbÃê¼[¯Lj+™•iÇLHÈqU¯ŒƒcgÎ[�æ_F©ëj–W¶Ú™4;Ó£cºµèƒÍ4:Ì1�¼Ÿlw—o]Oï‚÷9¦¥îS³lÕeµïdÉI'?áì„Ô&y¼›¯»ïÞvéêauÿŠévV7Ö8æ?±Ûü �s=!:Ë—–›uçÚT¯ŽåV¹ù\Oºzä½î>½×…L²;K�Êþ±ëÂ:vn ,G'[ºÖ1÷;`ÛZÝ«ÇïÉËýÞ?vË·jƒn®çûÒë)LàjŽÐ¶“Üe:÷’q+ùg1J÷;p½^o6¸M•ÏÏÏÇãããq+pL7U^.—7_y[ùw9®Îty÷MŠ]¹�‚Ù)ù» «É—ŠŸ;^Éí¾ÞwÞ£òÕÏ)³Ì»ŠQRL«mìNÆÎLØ)”››µNÒÂÊ]s÷¹Í£ªÜëù´°L‹˜zÿ }˜°Û–5m�twÌÚ«sIŽT¯I©\µíNiVÔ¯ßm¸¥¼L#… LÊy*3¯s³¤>Cwº„ÔnÒBØÉ‘dMýkõ^VJɽξãäáïN)>ŽÃ*S”)ɺêÿ®½vý¤ë/éý}ºyì8ÞŽ é>žß)C7÷Q™®4ªX•dæåæŠ:îBË:÷’ øÏcÜKƒÁ`0 ƒÆ0Ý8_^^n¾.©áëC9åB¢ †º—èóÊFéJ–+`F2qLwZ©‰5©çWl†;·Ãªw ýJfw­cõ•-S¶Ž›Õp>ŸoLõ»2�N>º†¾²*»¾s·qr‡‰ëXŽÄÚ'¶5±u%£²žn³kW!³¤å¦<;V”]v,•cõüŠñéÚǶ²¸ç\Ú+–�ï›cPŠ€BS¿c³ëXYðUYY–®¬‰ýO﫳ú¬,;àøDk Ëàduò²ï0=–+Y¾’[bZŽמÈÊwï²c³Ó<ä6ì®Þ•ʰúq"¥±3îZ:x̺Ji;K·cºS=wL·“§XneºÕ:2øg1J÷; �Aèׯ_m$“ËåòF�ÒH&¿[M¸T¦¿GéN %‘”ìTÝowšD:¥»[Hð¾ãø¦P$SZ� ƒúçT„“�iš0¨HjÄšzÿLCÓby:sl7«K‰Æ'W°­uñoõym“NQ«üÕ¯Ø)ˆT"ZÎ-$8!vJÄÎ9MËݧגòÚõ#­³äwïž[¥ácêÖæC,c2Ió¼F©Iõ­Ê=÷ŸhÜ|µ¨X�ß}ÿzm‡¤ÐtÜ¥¨iûv}=-&œÒËû´~©¨ñy.’Ý5¯J<ïÚÅJ!\½£E»{>½ãîÝwŠy—¾>ŸÚ7•k.šê?ß­“ÇåŸá:^ë>5UÀ¿§®ã^2 ƒÁ`0|0†é~'”½©âår¹1Ñ(ë­QJ”eÔM•Å´êÊTWœš§²ájB$+¨Øan³Ñ±›|æ^8&Ÿ æ=lûq|«e[ô~²¨‰ PæœïÄ1K+9•�¨ãççç×´4b åfú;Œ?Ó¢¹›Î)ÐT�,««"›uÏ>J6LjñS¦sÇ|Y¾$#Yª°|®muèòìy­¯‡‡‡›àÊ¢Ñ2¡¿“«‰^KåeT„T_‰ù{/:Vøž4ŽÃ³«ÎúÃ÷ÓY,©Ç»Œª2çZßβ Ïkùø;ÓõaÕܬ2tÑoV}¹Ë#¥åÞUŠšro»éÞW×¾uNâØÇw™h–/õ_—'™î‰Íý±¥û�Ф�µ™ççç7�Ø™ù¨t???ß(œ;‘LRD½/ z¼Ö™ïV¦×¤ävJ`�!ãvLqÌg7_­;M' š¬ÛÓét3(¥è nò2d¡ºt!VïVïÕÿšv�«è:Z·éòÔz¥y”3´í;Y™¿NŒ ­ÇnÂL“±›è»¶¿Ó/Vé¤gîY´2mU¬œ ’Ö·‹D¢éQ™æ‚“‘–œ2¤Ê™NæN)MǬ“näîÙYXñºkÇñ¶s!™úDr¥©4ôœ¦ÑùÇ'èØ¢uÏ:Imµ«k·xqeKJeês\»ó «�c]zT¬ø;M(ÎÇ»Ž]¾nòÔ‰'m˜ÔôÈ€hÚª,¤²rcŒøë¾ºVïQ™n7‘uÊ •ƒ]%ƒõ“|;¬d5q8_â*ËPÇ®í2Ü^bÿïY ì(©~Ùß(ORºw:'S¥OßøUº¹©²à|º;Ö[Û®¶yîP¹Wýwµ¸Ñ´îE§ ¥ñò½ïˆ2v ÌÝ:qÊY·™{§­º>æÆâÔ7ˆ®Ž¹À¡{¾ùlZ³ìZ–”–þîîl7¼¦÷¸zÕÀ ú^»ùÄɦõíÆ$—{îãÓ= ƒÁ`0|0†éþN8ÿêãðþÝÅ‚k´e¶n¾PI3­ú`’Ur¬G]¯ÿ;lwÇ‘µ¼‡A¬ë*Ob0É>Хñĉ½à3Ž]Oì–šßé[ݱ?uŸ†bs²TèJ¡þËIn¾‹Ää§÷êÞ_�l”cÑﱜ¸¼�ã­UF¯ÓZãêá|>ßøÃë}4Ûw,e*ǽ Ÿ{fe "3•Õ÷°¬îY­;µ,°ý0J e«ó.R™în rïè&”i½§žî}G#êÆ¸Ý[}ò^…z;í¡[ŒuuÇtÓ‰côJ!wõ«þÕÜx¬ÿ�<š'ë[A?nÝsÖÅÐü³÷’Á`0 ƒÁàƒ1L÷?·‚Õè%ÅrkAu!aDN01Ål¥0CdZ~”Õlb®2Æ,Sb6»ôº w‰ÕQמdº¤ ÊȪ« ™0²éý‘¡_½Ke=Õ¢Âk¬E Ñ×1Œ+¸ú×:&s»íááᡵˆ8&Ñ™lw˜e"Y#˜gþ^–o‡ÕÓ|¸YV-d&«ŸÏ盺ë6Oºó�5Šçwîå}�•®K«cõx'í$ŸKV/æÃ:í¢”¬òÔßsÊw¶káq훡%õZÇ>wù¥±GóYm.wy86› ²“;õ=Î[ɦ®´‚Óå#õ­oº:Ý`>†óßa”îÉ�£”îŠ\â>³ªJE§tkÇ r¨2¨i·•mgr.ì* �âÀA›÷¸ˆÉ [ÿS=8·Š$¯>“üßœ2UÊ ãZ³<΄ؙ_Ý3º Óó4c²NRÚ®Œu_7Á%e¡ƒ»�ùhÝSÙ`Û£Ä|tqêÊë™JË™ì»4xnG9àù´àÙ}ÆÉáäá3Zß%‡÷h,u�´Äö픊2Е‰òï )S]ú;‹ŸºèL]»pŠW—ÝïÊäêtgQÉsIn½/�U»Ï±®SÕ{9æïŒG+ÿí4/ÕwŸ¶ƒúŸ¹�¬î>öU´]Ä·@¨cN¹§Ò}O}¾ã^2 ƒÁ`0|0†éþ�V³µz}~~~ÍD#™0f·nSÆIY&ݨÄU³3ó2ºÃ{°ÃÕ}+–ȱ+‰‘P&#¹wÐcÅ,© nc%ëŠlw]ãfÅëT­ 2lCÅF\.—7Ìvb^sŸX}}¾ä Œ*_ºOÓÚaSZ¬½Îúfyœ;ަ£õæX:Ç$vV‚³œÌê+»{FÏQæŽÍs–�޹;�²KIbë´¾é±S>Ê�®ñ|‡Ä¦ûôz²¼­@+�Kãž²¬ÜI\þ.ŸºÖÉÓµó�üº¶îê5}/a•_²@î&ÿ IDATt°L�àŽõ…²º¹ÁYÇ8Nó™:ÖokìÄ\WùR�2f?7ߪ‹ë|�ò¿Á(Ýÿ ’.•n�dòòòò&R@òéÞñÕîv¸óÿŽ 1™1yì~§s)ÝμèÂ%ª_jú€åp2;Ž~kÞš¶ó+ïˆëõzóERçÿË ‘ŠLáC�]�0=æ—ê»3'Ey¥H¸K§ hhAÊF9WJ ¶™NÎN`¿Jét‹Ïîž{L¾“4i§P€,�.üë:á”n%vÑ)?®}³�ìŒAÝu-ÃÃÃUÔÜbsgÁÈ|“»ËTÏ3ÕÊÝ`iÝɶ»¨Ôs3Òx¢ù¤ÅðJAvŠmú�›÷ºÅÂŽ7ÑÍCu^Ý@w¾éät‹i¾Wm7Jö©¢Ï¢rðý¥û„[ÍÇß \CòkP—Ëå8Žo…*ÝîËp+_m÷ùRÚºÁB˱B7ÈïN;`ù’RÁ…GRD\ìkÇLðk{\L)âd«ÒÊ<¬X4§8ô]’5'£ë|Äùÿ=ï¯[p1ßôœÞ§ ·>ËÐí.Ý@T×Ò†Öz>)%%c=—«„®î:t‹Åt-Õ?Ç“ºïr¹Ü”M7ݦ± êÀí%IõãÒpr®®uçôš¶õnñŸ«”žÞK9»Åcº§[,¦þ«2ì¾ÿTÆÊ§[H°VuÕ)ˆé]î*šVÚh˜B]ÛTÙjüOû‡’2­÷9ËP�gá�½(Ún(k²h¿,òï8nýÁ¿‹ñé ƒÁ`0 >ÃtÿƒèV¶jÚa$ýªžþOL·sµJ¦$Eà±cøÌîGv®ï0&éþÄäÒ…À1<,+Ù—º(hÚ꟯(ÆÖ=“&FI! ŸØLj—‹ÆŠ�îÞëÊ�/ùÒûMˆŽéÒºKlOYˆ4=­ïêcνfö'_J³3]ï¤Ñ1ü»ìyCôº¶M¯cõôZv,Y¤Øîw™Î„T§¬og]â5×¾W mª§úï˜o–»ó‡Ol{×�,+Ù˜g¥ç,|nÑ1ºžß�7vÐYª\ùô¸kcŽ‘ïæÅ”^ºF«�º›ê5úe'ù\¿Ötê¿úqOÄ’ÿ£tÿÃpþ´ÕÉô PåR¢f¦óù|3™2d C ‡Ì�ÒMb0W¦87‘­:oš`vÍ•� n€s‹….Oý�&˜B�×wëüéêýë{®ôèâà6ü¹úÒ<Õ`Çsw‘ÓM’«É�Š·{žífWáÑIÅ-^êX _ëŽ ¦¤¯¦®~W<&˜gRV wrQ+<<<Ü,JÒ¢Ð�3΂ G}FÓëÚO§¦klO;cU ¸jß¼7�Omˆõ›ÄÔîÒ¸ßVHíÚ�«|º¾¨Ç;m•ãÂîÜ�ÞŸ;^•iåÃ�dpÿy�º»Ñ�;íµá±ó�w®%ºæ—'ëüà¿Á¸— ƒÁ`0 Œaºÿa¤AÊh???¿2 µáî8nðãÈ,CÖ¹°E% ¾´ïÌd÷0ÝC´b^;¹¸ÙQ¯34\:v+KfÇf×oÇT“iU6‘®9Êr8v�28–ÑɪP6£\/êÜ*t c WíAßËîæ4÷Ûåã\Šø^x¿“G­D®¾ï±¸tX1…ÌÓ±¼d…“ÉžisÌHì˜F2Q ]ç¤l]bºµ Š*�{σMì¶Çô.µ.ß“_²Öh»\Éç,÷ ½{Z…X¯Ë{*½{,8Çñv¬KÖ¦£õKù’åe§ï¬�ú”ócýºg­„L÷ŠÕg=²_SžX]Yïmoƒ£tÿÃp�¾”$vºã8Þøv©Û€ �Ò�húÒŒå”MÊ]rÜådØ©§n€q÷×5•ÏÕIM6NQc>©î8±Òmˆ>Þõ§N&RM›¾°�¹”íiGqдÕç9¹ÏhPn½Æ ',÷^˜¶+#óeþŒÜ£ï…pòœÏç×ç+ö½ËË)„NÑâsi!¡i²®R¾ú¼ÛO‘úbçOë"#Õsuþtº�Ú ²‘T¸GÁì˜Ý…û{u•Ànœ«ë+%^ïM å47(vˆˆnÑîÆöôŒÊ±s}µG¤S¸S?Z) �ìïY¼¸Eé{ê)-4�ã­Ò�bs§hL%Û®‹i¥ýôôt&° ;9øw0î%ƒÁ`0 ƒÁc˜îc;++Ô1ݺ{¹cºÉ¼&“VŠ^’"­ÔïVÌÏ=l…>ç@ÙV,˺bD]þdrÉӔ̴‹…×6�ØÍ]ð½¸*z_bàëǼ®òOlMŸ®¬ßÃêiÚÎ…‹Y&ÇöºvÂûõ÷{Ú´+å$ãŸòíÜÐt Ñ�Ù¬›ºçr¹ÜlôU¸1#±ºî¸òZ�/Ýu>Ÿ¬)M­>×Y0>}útãÆ•,gzÌzLu¾“,"ݘ¸k�HŒ±Ê@"Ê—,9Lתáäqù¬Ú`—G×w¬riL,¸9¿˜nuÍJ2èyn„NãªnždÄ’aºÿ{ŒÒýAàÀªæ%~‘R#\pÂs¦/�$©Ð+ô|Éãà¤tSÉè”ì]â÷¢S’Ô—1ù¯ïš »ëÜi®i2ÜÓªîô¿F…@Ë .I¹WÔ»w“Í=¾äN¶’Å}í�uÐ-ðº‰GÓSŸl¦“"®ÜåªBÅ�uàdJèó{«EDR´“Ò�”M]ˆ8w§`T{J{XR?KJé=ʹë«~æê€ù¤Å+ó[)�©îÎM�S»cù\>ÝB¤ÛVjï.>sOY)ꮜ«²¸ôÒ±+;ËêÚczI¶ëÕûV×<¿³¸®c×—Ýó"p"–ü¸÷’Á`0 ƒÁàƒ1L÷A™ n¾ãgà5N7ãqëJ×¹—Ôʸc7똬ž‹)^÷Ö=;ŒÓN]Üs¿c;’Lɽà1Ÿ£[DÇ¥ˆ%š®Êª_RYËT�˜|¦­¿�ûŒ«o'7Ys­“.¸‚¦¾‡éÕ{KNÇdªÜ¬o¦á¬G×ë­ �n²t –kƒ¼îÚ¦“»à¸t¬Ï§¨$døa21‹¼GY1'-l‰ÁÖçÈêvÏt÷éõvµcQWϹ|T&gyÓòºñÖ=ïúm׆œ,Ö£^c»ß�ë’…CïKÁ^^^Þ|/ å©r><<¼~{@eÐz,×Çt�kÉ��Qº?�Âë\MJW¿Ë¤Ò½$)t/é&‹BgÊKƒ®Êº3x}�RæÊ@bòݦ¯ýq|xÄMúUNç�çêW«?ž‚!¾’Éžù¸|éj¢yèoºÈP½¶R0¹ð£<;Š‘K_ÓV³ éÒ5‡¾öIy=�Þúxó˜ ÈŽò³Bª;M_ý6õŽÓâ\#”h{Jý‚mž¿]�—bž&òÔwÜ‚Ñ=»[—�Rê«îù*Snq­çõrçãù´hæ¥õš|ÉÓ¸ÎçwÆb7öQ6÷LZˆ¤|E*¹¶Õ-€Ò;âù®M»E°C×>UÖ0Á:çï.fد“¡*÷±D•îÁ��Qº?x”év)_^^ŽóùlýRÓæ4*%i0p~Î*—c9º2)œÒåžy¯¢Ý |;Œe Ã�Í?M>š¶Ö]åÃ<*·¡­©0»ØÇ]ÙUNʬòéûWE�!¬ÜÂA�� n±Àß*Cj·U'Ú\{ª…ìª}SfMOCìi‘š&Ow=)݃Á`0 ƒÁc˜î„2md=5”�š�tÕÚ™yÉü¹U8Yú&¶¦KC�“Z2ÑÜïd[±R.^så¦)V^WÇv¬X\ÇF’éÖ|•¥RæU-L�¦AZLœEDë„~ÖÇ‘#$wŒÄ’t¾ãÓ�ÚLjw´äð²°©kcZî]ýúõ5ªÐÊD›˜DÊã¢Í°Lu�çÝþýM—æM¹X§Z–TßšMäÌ£c·wYm>Çãdà5Å= h²Z8vû8¾�ë;~îi,L,ªkçi|£5+=CÅ$�k'š~*ëŒi»4y/åÞµ2uõxÏø´‚ÿk¬è|«Sÿgþ:Oè¢ÇÊ¢Ó=K~\ŒÒý/À¹ ¸M•Õyj³„nš8Ž·Êd��Ö p5Шª¸M>}z£ h�¨ ÉÓÓÓkžÎ•eðã`ÜKƒÁ`0 ƒÆ0ÝÿÈ€¨û™nþV¶[Ù'²Yn#¥2Võ;mòÑ{ˆÄ`v&ÜÄt%ómzf‡¡ªôT¶Ä”:†‡LÅq|ÛPèdàoÍKëW­”AïWƒLŽn–)ö¢Ê§ìOgÑtÓE뇋`R÷¹2Ô5×N¾~ýz¤3/§�Š Ž!vÌ™i²f)Ú‹Ûìz·.*©Ü<îäÖßšoçB¢_—d{JmAe"CGKB*»+Ë=H¬îêÜ*ÿïeeYL×=Gv[ÝÈ;WÇL»÷Âçºò¸èCŽÁv.�¥©«“Ä:wÖMS­ILëö¾ûM0Š× ]f~ÕÔ¥„a�£¯J VÍ 5^ë½êÆòåË—×ã‰Xòcc”î TrU9ã ­J·*"ÎÄî®í xÉDÚ)Óï™ “ëJg¾ï1Ië¥ÿKÞã¸U¬Žãx£8:?`¦}½^ob°»w¤m¡\UêýëDÈÅS2w§�eÖk|ÿU~–Iß%ýõY•Mc_s¢ê;°{Fßߪ¬u_j“ɯ_ßQ2ßvîÚÖùŸÊtr/Q·$¶“®/»²v‹€ÕÂzÕÿ\ÛJ&û{ú0�WÊWÊ“}1)ÛIVmg¼§k[»ãVw=E¹¢O·Sè]›I‹k§x»:I×R©ºE‰Ëouî8Þ.´Ý3;íÞ=£ 0~ R]@vó­ãóùü&|pýVו/_¾¼º—TžãVòãbÜKƒÁ`0 ƒÆ0Ýÿ¿Õ¹ k¢L·c:W&wÇê�õp Ôê™]ì˜o»gVH ËÖ1•Çñ�R¦Â¥G&IÁع)m�¥ëب’[MŠÊ¶»h3jF.\¯Wëž@ù´\Ýi�8–ŠQøþ´­wl)ë²Î;ó¶û­ÏÒµ"±º;¬>åL.ÕŒò¥6äÞƒc·y¬î%Œ0“êKËOÖÓÝCù’ËFÕIJ¯c³wúzºÏµ_•y—ýL +å§Lõß¹éñËÐ�[+f•éñÇLw ŽÝ—ØÿtÎ1º«4ºòïÔáJÖ$[Jg%—ž× Ü<©.�) Ž ÕÏ/—ËÍx¦VoucùòåËÖ†ÍÁ��Qºÿ%¤ÁØ…t®'ÚÉQ MîÝ·«tó÷{µÐÆV¦b=ß™U>'+ͪ¬o�„’¯¦©iQ)Ñ´;…‰J³¶uq9ŽoLN§·ü¡ÜNV‡N�æó:ÙT~”¡SW T§Å¢S*’âîÊݵדBžV;JE¥»R´+d˜¦•\JÒ»Uÿú•’—z²°»PZ=çäédK‹+—Ž{7+RÀ�Ù¬ï¥ä^e¯ž¡l®Ÿs¬Jãy’£ê*í r f'·»–4» }w·˜ÙIoG±NÏè8X®%¥ kè¾Ýäétº‰XRçëðêºR~ÜOOOÖw|ðcb”î:P;źX3Ufô*tš¦Â)Ýnðul$ÜfÊå‘ÑnpÏï*àÌ3±G̃“”óïV¹K‰tŒ•ûÄh3Ü•§ºO-•±ãÊ÷åå%²&+åJëm…´pxyy9®×ëëdÁ ‘lúž\hºN!J 4ï× ¬üžʵ³Ààú×ëb(ùÓ2*ÙNéV¿m=f=¸réçû«×‰´àÔ²Ó§ß�é¸S ùL'[·èN <íoîÞÔ¶h©tãnùív Zæãdwϸzs‹ÜÓé–Õ6¹ÇÝ8–�ËW êÔ>»ÇÒ•ÜÄn˜A׆ܨé6:&2\àŽXP庾 ï²Îi^þùçk>j-üØŸîÁ`0 ƒÁàƒ1L÷¿e°•ÁÔóê#Jv…;™ 4w%¤?Y…ó$YŠŽµP9¿‰ñwù$fI˪i�R:±Ñ¬;æíØÀëõjÝXÈ*›XL‡ƒcïºr3_²ûZvÖW+£B—º?i:» fbø ‡åVÈø¹:HÌ+­lk® ê×EËÕÄõ­2ÝeF®c­Û]s¹"½óÕ»ÐãA…ù$WÊíʱ*ӻݡóy_1ÓU¶Äïšó;ËLê§ÎZáäK{~\ý;¬¬&%ý–³•u…Ö/•ÙÉDR{ç˜4?&k`ÇtWúÇq¼a¶»ˆ%É©ãÁù|¾ ¨®&êFò矾‰X¢r ~\ŒÒý …¤{‰š®4ôÚqä¯SÝ„—cgÒw÷1Ÿ•rµ8p°KÃɺ:·3Ù&ùt ¯É×  n#Ÿ3Ij]q³$M—5;²œ7 µ¤Xí(¼L;=Ã6\e¬2u“8C$:y˜�Ê£õ�”Êä6”|n™6Ÿezn4T¥´›t“{ Cºw¹«l¦~]e*ðË·”UÛMöÚvwäJ Ö•Bš–nQYèÂ(v¤¸îZ—VªÊIÙ;EŸäH*wçïÏ:I ”2Qž´0êá¬GW7ZžäƒÎsXînó½¾u eˆ@‹]Y*-—ïår¹QÀ_Ÿûúõë«¢ýçŸÚЄƒã^2 ƒÁ`0|0†éþ�6å|ýúõÍJY¯%3/7Šuìfb™“èÒèX�&.1 Ì£cH\+F%ÉÂkŽéPv¶Ž•QUæ–,Œ¦á" (“TLb2«¦ Šõìq¼ý( ™²•u£ê$m(tuYÌ�¶IÇÐ% á´ÔS»Ñ>’ÚšcøS>ìcΜ¯ïÿtú{7ÍÇÛÍ’Ênë†É´Q‘é©ÿ+S™,"®9‹J•Õ¹Iuruìv²Zt dÇæwõ—,_*7±»kÎrâÆžÔN»ñvÅÖîXùè—ú%ë[ÛCŠ>åúO'›Ë×Y ˜FÇŽ« jYJïÛY²’E…²¨¬ŒXRǺy²sùã^VL .—Ë›�Ḉ%ÏÏÏãVòa”îÿT´´3w>ÝnbLqt5¯z>™�B×¥å~ï˜;õwÝŸ&–µ,S>ibåo=—|° ¥¬è@¯yÒU$™H�<Î-ÃMôŸ>}:oÂQ©²¯îJšvRÆ\»è|`‰’MCêD­ &ßqRî©pufö$çJ«r&_䕜,«ËÃ),ê·é>éÞ)d+¸½®_¥ˆE©Œ%«º¢èø´+grÇp‹_×vÚc=³£Ü§÷Ìw®÷v.%»²išLõG7ž¹:g›á‚Eåv.L»+Ç;·ˆ£ì‰ê|µU~×nÓ"¼C"q8߸¾C?îêÛ¥p»0�i¤¾Ûª€ÓµD#–0LààçÁ¸— ƒÁ`0 Œaºÿ#$÷e ¹©Ò­œ‹rìÙl2¶Ž!p±€WLBb©UÎ:&«°Jϱ;Ž™`^ú»3ió~­­;•�)]Ìô²`¬L¶*Óõz½‰¹­.EzßétºaG+N6ëît:Ý|�æWeÎÓ†82ÁÉâ é)D]Ó`�i›ÖsúžiñIl$áÞ×étºa Ý{Ö<µì.^ùõz½a™5 µh馨r'á\ÖSW&-7­+Z^öƒ¡F¡åÖ�”Ũ' D'cÇpkVuÒ1ôIžÎúÅñR¡ f··CWÇz¬÷¥ñͱ².=¾²ÆšÖªLi|=Ž·›lӳݻgÖ÷ïÞ{õÿ•kEW6Frãuå©›'•e.÷’²RwÖ„ú¯}þ|>߸—}þüùõ˜Ã)÷’‰Xòób”îÿª è×Ý:¥['ðÍï gÊwáñôÞî#Ä®ëAšlè6�&V÷åî”oÊšE}V¯Q‘¡Âêê±”·˜Ie¡[ˆ¦]Švå¯ ÞãããÍìÞeÉìD,+ëEÛÌŽ�NP///¯¦S·hKæå.Š@*ƒ“Ã=Ï´5ßî rî`\Xi^n’­û\û¥ rè‚#…‹«ßNaY¹—è¹ÔF»Åšß?sÏŠ«“ÝEs'ÿ'bC�ù¡2wßî"É‘+7�¤`»ò¥Eñ”ßýv¤‡ûŸÆ†n±ÔÍ zŽ}ˆïk—PqòP¹ç>M[Ç4÷©÷š£w/:žëGÐ.—Ë·’Êçÿûßkô�š2ø¹0î%ƒÁ`0 ƒÁc˜îÿt/QF…;¡¹›þ8Þ~¦9±=Ŧ(£¢ÇŽ=ti$–Øýî@#¹ P¶ÄþéïÎ\êØÖ†*™pÃWõ«ås:©2é3}_ŒB 2¨»‚¶eëܩ^iÒÞawÚ‰22µ‘reU¡%�yª5Aϧ6Çû´<é“Ù÷@ûMùZV�J�6ÓÒm ‹¦“,>´¸÷Ô1Ý­Ö6•¡“51§Ì#¹(Ò{fŸïÆ•i‡™¬1ygÃí=2ð9W¹´|Ý;ÓûÔÕ+õÿ‚s=Òô5-wOÇž§MÉz.�ó¬ßnLêÞC²&é±¶ u/ªÏ½ÇíFÊ®�0Oº˜•5ðóçϯÇOOO¯i—k‰F,™O¾ÿœ¥û?•iíÜ)Ð~Mèu¬aÆÒ`ɼN§Ó�ƒȺÈ(Î4˜þ{'7€»É†ƒä{MŸšóuט6#˜ÇÛðZZ>ú§úV4² hU~.—Ë�{’FQ¥’uÊ÷$¥½S’´.hUÜ×#µÜT$ i‚sr!Õ±ÖcÅ&•Uûn¥«¾š5ɪ9¹Þ‰SÒbº+›¢ÒJJG·(uï–õ£ �º”duùiz®ßêoW*Y+e‘åëŽ9.ïÔù=ŠvýïúNRºYÇNÙä;f¤,Y'É©²èï•íÒ[�å.½�´wÁ…RÀ�ãÖ½Ã}ŒFI†kå;¡Ò­‹jl(îÊ›_ ¬wUn&ƒŸ£tÿÇP¥­Ø#·!�Œ8}Bé‹VÇðœÒ­_»ìXÊ�”n>“Ò¾g�îØ-—VRš©,2ßnd:Yo*,ZOn“X)iI�“¿†Ÿª4ë¼2*Tܨ¬¸‰ˆ ¿TÖÔuSçqÜú6w›FL›>ÅI�ê”ÇÞu x·ÈP¥FÓÐzt{2Ë˶šúQR<\ˆÆ�…¨ëÛ*k¥ÍØì«¾C9©ä$ö?¥‘÷Zw­#&\û¡ï°Ë;ÉœÎq£¦ëÒ¦Ò­2t Ïã8ìX“ö"¬ Ï$K“ÊÉöäÒ*“’íú®æ“n^ªóÎBãöÀ¨Òí6Oº ¶©h>jí:ŸÏ¯Êöù|¾™ÿõ ”Ü´9ø91>݃Á`0 ƒÁc˜î\);¦;íž§™WCÎ9Ç™¿A¥‹`²câîVû‰Y"£Êë£ÍóëMFóc¹ÛçÒ($F41y޽Jl´Ê«,#åPßáB…tiwþ½*Âé½t…pìT…ÓZYDCëêË1jŠ• ¿úƒ2Ý£–Ú–“Iû›~ £ÊL´¿º¶�,9ÎJáÊàÐã迤G÷’ÓíÞË*ú�Kƒ÷SnÉÂõ�Ž�æøØ�u;L|ºæÆˆnürвw®ywîɃùèsïóÉp«¬zÝ¥Ý1æ©î••g�$+q±Üêê©î%:gëq‚–¯>Ž¥ãtE,ùôéÓ £^!¿|ùrÃ|ïZ&?Féþ J‰š—Ô§‹›*9èé¤Ý™žt௴/—‹�xÔ…Eÿ»4»A×)Vn"Se�ØÎà¾cžÖ· F¹y~5Á8…NSZgÞ<Ž[7ºvh(>}VóT?bšy©@§:a=èÆÌn�á&BmçLWÍ­º¤ é½Vý®Ìù]IJw•GëË=Ç:àÂÆõ·ãx§· ñ×]™ÒyöÛ®/èÿº7)¹ú»úº/ÄÝÇü¹™/)êéù”¶û¿Cè3T¸SÚi!ãd/¨rÆ4œÂéòI׺úR¥rå—îÊ—ÒvïDÛî~·(äb±[`j:iQ�ò¬ñ?É ÏrþuŸ]×½ ]ÝžN§%[‰²ÇÇÇ2DýRºŸŸŸ_ÿ?7ƽd0 ƒÁ`0ø` Óý�!‡t�"™ÇÛ Nµ"W�ÍÑUýËËË+#ªií0L+¬˜•ÄðÔon�ÛaŸ;¤ÂYܳÎí$±2¼O­ZVÇö+•˜@²ÿ‰aqì‘2)•—º%óyb×h1¨4yŸ^¯÷¨í[óÓZº¹˜ï?1[´�¸öªV¶eõz½;}—.ŸÎ=Eû¤Zôú»äJ,¬"õ�ó¶ãÐ1²É4¯i$¶±{f—áå{ ;ê\sÜ»w÷­Òvrw÷&ë#ÝXFžëØnžc{ÖûVc¤Ö�ÖIz^ÇÄd¥teIåÖ¾ÜYjØŽw¬:Ê:“馕9}y2E,Iùê÷²lÕïËårãªJþüóÏ×|ÔÚ=øy1J÷„2Aò •ÇñVé¦k€š§;÷ 7hºPg¼g+Ÿ»—fÌ41惡¨�ÃÇØ^ Ú]zɵ�yQuÙ8Ž[ŽºOýœé¿Ú¹â¨RÄ�ašÏÎnø�\/z IDAT4á»…‡«“’9ɭϪ«IŠlÐ)SL�‘_ê<ÛŠósvÊbª žs_U|.‚ù¹ø:¯ýŸ2ð]¤ö˜¢…¬”7‡RèÒ{á}«´wÞëÜAœíÜ?ô¾•÷Š8ØYt§2±»q†i»g®×ì^Ô•©{ß]ùºÅH¥Ë±ÝåÙ�'éùzÎ]Óg8²í»öO¥ûùùù&ú’ÎË«Åíqü­h+© aÕMP]Z¾|ùrãGþüü|÷œ<øñ0î%ƒÁ`0 ƒÁc˜î ºANè.’‰®ÔuSVÇ^* ®ù(#×m¼¹‡�NÏu,Q¡X�Ä%–£ËWÏ%ÓdÇ®0¯BAÆKÙ¿Ä>ÑÕ„+]ú‰1*6M7ó�Y/tï¨3sï0j¼æ,OOO¯,7™¦wB«…ºqã±æŸXkÖËÎ/}jz®ÞX?dk�â|>¿öye½ùÁ =æFÑFœr$ö�i¤û’lî~Ç~wÖ‹´ù¹êteE9Ž·nM)=¶áÎ’¥Øq‹ÐãôŽÒ3.o2ç*KbÿS=ï°©´Z¥q"•×]ã˜x¯åRe×gœ…'Y ê™rít›'•�^Yh´/ë˜Æ/Rj¾Ån?==ݸ´8·ÑÁχQº0¨¬¾ŸéC98ù¥+ NÉQ%žù¿×œµc¦N¦É�‰Ý¥½3É1ú&9ôùÝ …PßggÞ.EOëD¨¦Jõ÷W9´m0r�¦÷ððð¦ªvÈSN÷»S TW�N‰qŠèq|ûâZ…×rùÐ_•Qa˜Š>¢iU�ÇÛ/ûizêgÏ44ú‡»>:} y:½Ýà–U¸Ï¤œ¹…óxÏbVMù|ÿiQŸ">ÃEÛ*:‡>ß- ]>D:§ý/Õ#ËØ-LÒ8Êüµ_óžÝúvé“ðH^RÚiÂcö‘ݶç"7¥v\í1¹Vq•ºw¸¹˜P9S„’òïv}›J·ú”Ïq~ ŒÒýƒA;~bº]ø@�t«3???ß 6Ô8añ˜;ÝÆ…ä8øñþÄ*R `"MDTu"#›¬÷¹ºëX—’ÕÉ“XPú÷êÄ¡¬'ó%ëíÒ~yy¹il'uüøøxŠŠý�]]¥:pLPšäÝ‚°ü5æ¸Ûè«õÉsúŽ»öÈPb¬o¾§*‹æ�ˤ4•¢¦ýœå<Ž[¿Ïj›Ú6\;éúMRî(o·`åõ´Juº»˜æ¦F•‡ã`ê§\X;…:-]Ÿwù89“â·«twõ¯ïÙ½’;¤ïKã]ÝóžÍŽ+t vj§š—;Ÿäaýp¾Õ/O®ü¸9�¤Í’u^Ç1M»òT?ò•ïøàçÁøtƒÁ`0 Œaº@èj[ý³»ð�ºš×ðcµRN&~¦­æmFSÙaÃÜoÇ8î˜;<>·b:ëX‡ŽÉO2RÖ:N!ìÔLKzºý(kB†·Ø_ºšhYVPÿk˜É:þòåËM9T~ÖcWÉJ�ê˱ru�²<Êx³ Ñ%€&e–‡²R¦n�LÃò^÷ ÙHÇÔS.Ýë¡ò)£Æç\:®l©>øLúΙìÙ¿Ûê\ÜÞWwu¬ Ë�ê›m.EFqy¸g’%%µ3÷?Y‚È:ëûßi[,åIîj,óaÚŽ¹O}Û=Op áó._·'£Ðígà(�ÕYû»«}/ŒXRÇüꮦ]®u̘î_£tÿ€ {G�«ÈÎHÅH7o¨y,)©4oÓŒî|Yߣh§ÉÈÉ”&n† sf˜“I2Ýç6¡Q7w“©“•Ϩ¯nª×Óé6¶¬æÏ¯*T™SE›å®ãÏŸ?ßlJ¦*X¦¤”Ç[eRŸq‹ ne¾î½;w¢$7È–|¬o]±}¤bRX4]ti 3w¹\nòÔGiaEóûJ�OJ¼¶³NQwi•Li`Úƒ¡ÐkÎyÕ¦y=µ'>sï¸èê;=Ã…Ir)I.7*eÝ©GÞ·C@tåa>|Ö¥§cXýîÆ_¦¯sI�×1’J·Ö¥sÁcÛäü«˜ ë[i¯>7_ã÷àçǸ— ƒÁ`0 Œaº`$¦›áÉÔ*z>P™ ǜױ2o�Û�ßamî¹FÓàîêç¾Ä€(s«×Üý•öŠqÒ÷àž'ÛïL͉Yª´•­Õû4íÇÇÇ›ö¥ò)k˜ÜŽî"$YÉz–|ÚÞõ¾JKßa²t$†œõ‘¬ŽæóŽmÞiƒÉ½èz½ÞÈ­¦odLÑIìæ.CëÙÔד;�ÞǶ u@s:]&ôœÃêywMŸ¡Ü�e‚åreJ¬¾«Ã Er)¡lÝægÖ‰ëc¬o–wÙhÅܯÆO—6Ë©pnSšOõk÷Î"Pë�ÑC\�”õ�_ž<Ž·QŘFbºWU?Féþ�A׎.f·*SNéî"Ф­¾gú›¡î Ý$“&«:Ö+™.»A<)÷(;Χ›ŠŸK7ɪÇtQèî§)^'5UÀê]ºIRCÛ1­Õ$¬2W8A�lh夿©Ä)ÅZ~«Â_¿u‚ªô.—ËMûìòI&h¾/ž§<óqeqý€í¹3áô]–‹†#SÅ!ù•kû^)L©�séÚò*ÊQ!ùÖ&…™Ç,]=ô™]¥ÛùrÉÏ9µ+‡�ú昘¢”(ºEI7&vã¯[ˆp‘ËpWîÕ8˜žsrj:©]T!·0q!ÝXêò®´éF¢óoRºé^â¾Ç±ãÊ7ø90î%ƒÁ`0 ƒÁc˜î×ë·Èd0u5LÕ bv;Æ€«ýZ‘Ó½„n(d[Ñ�ß1¿—Åî˜S—Íã.íUYSÚú»³8‡ßXIf;É}·1�5--�se©g5_�òòòb?¼D¶¶cÓS§÷èX-e3ÕåB-;ÊꪎqîêRóMÖgæg~z]…R{fÙµ¾Õå¦Ê^×háÐ6àâÈ3ÿôθa;1¾tÍé,Aš¯ZvØ"Ex`ÛLõÚ¹¤ð¿++ËD¸¾¼;v‹êÚZ*ë.:kK²¨lÇÑ[–ô\êGI¦:îêØmWKŽ{Ö•O];Še®ßš6­ u¾˜m#]„(æK¦Û¹zÞûN?.FéþÁá”a5A•Ì)"ªtßã^BW8ôZ)dÝD]¿ë?ön€Öã4è¬Øîx¥ÃtÿàH ´Æìæ.ge¦4N¨‹ÈÀ|\ô’.²I¥Ý1]³‘Øe'É¢8³#Yô{àdØa©V÷íäÙ�'ÂkºaV-úŽR„…²=NžÊW?]¬–—ú­Ì²cÔ*­d¦wlXýN›4•yå†)·A–ï.™Å� Ùµo•Ám4V¦21Ý..9óa¹�ã»ÏH4t*™ôSÔ‰=îú(Û–¦ÁòiYh™)¤±¥~;TöÔ.êZמVîì{©Nºãîþ�1DÛI7¾u–2úÉ…¤«¯.Ÿô^ôžTÇ�¬Ú7YöÔÿ\NNZ@4b‰Z�5?ÓÖ>š>z£}Û�-n>×ãaºMŒÒý“ …,0×QUé.…É D:ÈÒ¥Aº±¨<�Bï�]ï*´©<…�Á8) �"’̬N†¤´ue*|ýúõuB¨´ëÝ2â £ŒÇ­«I¥¡P7 }·ä8nÛÓétŠn%i2^Aë§ó³uisrg´Í#½3=ÏEï_µË’Óùn«2Å÷µÓªOê» ï¹”€º®ïOI]ßåbƒuêÚrªïZX9"¡S0T±â¢-¡S²õŠXBE1-ºv‘”쮾ÝWh]Wо[˜$å{U†4^ß³€~|tüÑ:ÙY�éþ(õ§~zzj˪çÙ—ÝXœô%·*Ýiìü¥û'Y!í¤és±¦¨”'nàÑô�ã­wRº�ž6®9[ï)¨ÜzO7`%…8±5DJK=æ¬i¤òð'ž%�¬êï­“@áëׯÇåry}ÆùÐÖ}Ì«|÷µ”ÑÑ;•¶–E¶‡�ÅeÔúN÷iût!Ãôy÷.¿~ýzóþ G¹Èæºþ¦“1™îÔ.Ȩi½r� ì¨~ŠZó¹g!’úX§iùô[\¬ë¢í1)fl›[œ²çŽ];qÊù8n­”ÅU}§/Ϻt*÷¾:òÁ)ÃIž�tꇬïNq/Ô8ã®iKó ÏiZÕ¯ulP¥[7R&ù´¾ùy÷n¡ÝµA§t¿·=~lŒO÷`0 ƒÁ`ðÁ¦û'ÁõÚ‡L¡üÔï—æ.Ç�‰Ò0q4}ÑOÏ­ÆÉúÜëjÀcæãî#SFf¬cÑ\zZ�L£‹j°btˆŽ9tltg¢>Ž·Óøúõ«uq¦ý*W…š¤|Z'—Ëåx~~¾iwÊv§]û ´ÖtÌ'ˬù8w,•geEѺPÖ1½gÇôºú"Ö±Î.Múekù´ÜÅ´é{*臅“Ÿ,9l ‰É-ÏçóMI®pÉ€2t÷¥÷×1¡´Þue]�–ŽôLW�t7JeKcC›˜†cQ]útéÊļœÜ®\•O7ÞºcÝ_²“]×çµ�h´�ççç›�úl²:ñ˜¿S™9ž¯¬?ƒ_£tÿDH/ÒW¬ŽãmÌn§pppÐ åË 3™‡wL“DšÈWऑLšzºO•¡Î-‡ùò·®,œlV“¬›lÔÕ€Ÿ!VeX}Ýä¬ÇÕ¶šît:Ùð„*ãq¼õéU'‡>çdc¸½ä›L—}ß�ËŸ× ½[liYÓ‚E•š%Cë¸ÒÖ6æÊW÷Õ×EëÜqüýKõÁ§¢·«\¥²««ëme>wãÑJ)':3màLyì.øÒxêîë”8-C—§«³NQ£KCR¦)r¥bû¾×¢#9(ÇÎ9*ÝÌKåTR¡Æ·§§§e¿®ói“v÷.Ý‚ð8ò¼ª÷�òýë`ÜKƒÁ`0 ƒÆ0Ý?Ü®ÿr-á—´ŽãïÕ1?”£ì­‹6áX!ukéÌ`n…¾ÃPvͱ‰ÁN,\b0ù|2» „Ž-u,͈•^‡]¶Ko-ŸcÀËÕDhuêÞ“²B e·O§Ó«û™qº!©LŒ‘�>pÃwäÞsbò«¬JæÉM–Ž ,Æ+1s‰seªséƒ8,Ÿ¾cô 3ÉH/4Íwì¿æíÞ#éì²Û]ùxŸûÝ1¾�9g¼Zݳûœ+E²æìŒo‰e®ó®N:ë–câ™�“é^V6Y\9“•à8<¯¿Ý3j~zzz=—ê�Çš§¦Íw©²¤÷ꂸg¿Féþ Asw`»I¤L¾êãËPoUæ44YC4 (•—;æ=+÷ —†”Ü ìî£Ü:©¤onç|S éÙnqrwƒ¯šËUn*ãœ,tÀ¶�d¢ÏãqÜFË8Ž¿}‡Uñ¦xÏBLe/Y �’ë”8-_É£_Víüqù.�<œ|ÓäÌþÀò鯠_·Sÿí‚s)Ó~[ÿ�Yü�?þ¸I“íNÛ<þªØ¤àÎ-¡ƒ[Ä»ô’BÙ=S}TDZB·ÀÐs\œï¹¨%%Mer2è9ë9*ÚÉͪ˟ 2æ¡yñØÉ¼³ÈM}Þõÿ´(pé׸§á6Kéf{¦ïÊ_pm¸ÞYìôŽ%we×¶®cÇ Äf; DªÇaº=ŒÒýâzýQ¢”_ {”–rtOâ:p8¿Iš#ù)úä{ÆAÜMÆ�’ä&›åª3-&%ÙÝË|ÜñÊ„¸J[ŸMr§úêäW¥V' *Sê® ï™>ëI&mƒå éÜ4\TWN�\:÷ =^™b]„Šî·pÔ¼´îê<ýÓi¾kOÕO+=F,Q9(_*“–Ý-Èõ™ËåòÆ]IÛ�s/¢Ý¢’Š›>Kßÿ´˜ÝQd’"ÊèN»‹ú÷ �An¯rvc@�Q.’2îêu…¤„Óu­äèÒvJu:ÖüÓBÛ=“\fÜôõë×ãéééÍØÅr¯”î4†qìì%; ÉQº=ŒÒý“‚ì³~ž ùq|S²Té®ûºI\• õçž&äìî²+.��‰²»OÌŽyI, ¯u¾Ñ*O’SÃø¥EŪ®Üu]ŒÕ¤¡Ê¤N"Õ.ªNVïRËx½^_Yïã8n¾|IF�,ªóE®IWËæXB*p‰%J¾¬|ÿdŸœný®ûÈzq’&£™Òs“;¿&©ïrgñéÊW¿]Û¨{ÎçóͦX}—.-æëXðúOX·rå¹Wéf=èxIeu¥0&™V÷0-§´UZ«>O%oW�ëêun¬sy9Å¥0wå^)ìî}»=zßËËËñôôôºxLÄ{”nŽ®þW ÄN9üZŸîÁ`0 ƒÁàƒ1L÷OŠZAûì˜n5¥–¨š®;æEóQö6}TbgµNöAY�{XfgVu÷:0O¦•ê„HQ)è÷—Ê—êdŒ"Ð¥­l&]&{|¹\nØ@ú*ô÷_ýu|ùòåõ|1¥d½Îçó«LŪÖóZ>-›þO¦ygNví„e`ùÔ}ªêK™{æ«õèØqצ�éܱêj™b]Üðês®¬d³¯×oî3üñÇ�Cec;qcCÝ{ßBŽî°ÄÉÌÞkÚŸ:—’U]®¬ d{ݽêÎ¥÷¬ú<­ i\UF5�Ë «÷±²²Q6×ï\ÛíÆ°{Þ‘æ›\—êw}uÒ¹`:ð4ŠÖ¤.¢OjÇîžÁ¯ƒQºr8¥;ÅìV¥›1»»I@Íç»_¤,ð8)÷ŠÕ»3I2ýT¾•2´’�Çêpþ«‘)­ã¸UÜ:ðž¤tëqú­“C-ÆTnNâõ<ë´îûòåË—™’ùÓ§O¯ ¹*Ú§Óí§ã†0½#ÖAg*.Ðä«ò;÷ Z,¨¬õèò¯ßÎÆÅw“»öQ.î4=.0X'«Í˜Z÷¥jzüñÇqÇñ¿ÿýïÍÆÜº/…å"¢”u'çŽù]ót÷¸¶ÊͳŠN©IíLŸã;'ܦخmv„CZô² §ñ·CW9žtéudH§¤ò¶-¶ýn\Ó~¤í¬ŽËŸ[Ûª>òh¾úþ\=ÔXéÆ`·8K ¨Dr ~ Œ{É`0 ƒÁ`ðÁ¦û'G1Ljßeº•�MPŽÃG?д»’VéÊ 04Ý{ÌçjìØ�Äâ�é^¹—°nÓ­÷ðXŸseuóVÏèµ´yêz½¾¶�óùÜ–¡Î‘•T¦3½ã¯_¿¾ºšç²•Æ\ÞãÊÄöø= ¿“»ê¼6OÖ1Û‰Žùé}¦÷§e¨ûuü©Mweüü¥û'GE!ÐIÓ}�²LçêF B7¥�^㛦AD��²Ø ÔuœäIƒv'pR”wü…;e3M¸Ç‘MîîXë;…ÓsN‘rÐwôòòòÆFePѽK~:~Ç´ÿùóç›¶Æh/©~苞Þ安\'ßoÊ í]ëL'Y×u²^µ3>“Þ몯j>tkØQÀu®ï‹mFÍô®o§:Ѷ•ê.™ÙéJ‘\…H8P¦�@åïÚwW÷I6¾sWÞãxë³þO‚ï¡k‡; tº¶z'n âÂOëU냽tAv‡UºUq^ÉH¥[eum0¹•ìœüü÷’Á`0 ƒÁàƒ1L÷/e´•év»´•©R¦;1¼\¡;“f±J+fŠX­þUžÓ×�KæåbF«—˜)2¥‰]íbñ2íÄzjÝ9yûîä!–Þb¦kÓàétº‰0BFÔÉÊw^í‘yiÙéî’6-¹6éÊ—êžÌ½¦¡Ïi[?�Nvó_¥§.Zþwåæ»φ;æÃM±.jFªãÚTë,_¾|yyF?–ÃÈ=¬ßzZ_Ã�ås¬®Þ뢕¤g{Ù1�+V6½—†WßÇ�iç–;¹1t–�.ýÄh'ëFwœd;ŽÛ�eñ>µ,hž\@û/Ç>×nëØÉ×½?¶S½$̓ߣtÿ`ä€NéÖÉ]¿v—&„¥» MÅóœ€Ýà³;@¥‰¢Îëo'[):h¯&IÊ·RÀu‘³rc`«‰¨ÀøNùísº 餤ÑG´ êúRŠÙJÉ©°‚*kµ!F¡o¼Nº*7Ë×-Ž˜6/][åÂÍ¥]!ñ4ŸºO÷P¸6ç”nÊ­ç’Ë„¦]ié5*û,�ÖÅqÜîùßÿþ÷:¶<==×ëõÕ_ÿÏ?ÿ|M�þð\L©K‘ÊCW÷^xÌñ(ÝçʺBªcÞ£ç»z½wlÑßU67þºçvÊã”û:Ÿ"�c¼Ç)ª)jû²^w 7ž()@² µ}wŒBâòSYÝõTw;ïê=÷~Œ{É`0 ƒÁ`ðÁ¦û€2•zì> ¯l›ûP&²­)zÉŽi— J2Óݳºÿ'Ó ëáØ(Çfw ЊµLϹßU¿Î$ïØ62aÃWí¤Ú…ʪî j.-Ô1“)/�lro®ä3Œ'­m�ÌéŠuÒk•^Ý£} ®©œZVe¾èj¢ò軡ÕB]v´¿ñCU.R‚c)S=p#er#SÙ¸™L- Êt«;‰ÖëçÏŸ_ÙnÆ_ç;JV5¶[ןw­m«¾–Ú§s!Ø˵SÖ._-�c“ü‰Ñæ¹dÝèÆéd-ã8§}lçý»ßŽ&�ú‹ºYr¼^ýçâ]9ôy·¡\á¬Ý8Å|¿Féþp½^o|-»¯SºÉ�!МyLóÒôŽã›¢¿cBsjý¦ÒSçSè¼ô| ìn‚pfÞd"Ý€�\:é¸òuj’§Ž9ñì˜A;è$YïÑ•� U0Õ­…ïÂÉÇ�«‰*ú×ëõFÑg]éW6�?µÊìÊê”Í’Ë¥áŸt#©ç«ïÕ€´ìν¤Þ±ºz¹29e*)/Ú¯»~ž¢©PÙ+eúééé&©~¼çt:½ºšè¶ÍWe§LòÑWW:}T¶Ó·p\õÕ¤<¦¨P|&)¶\`tY\ŸH 5¾s¦Ã²9Ò$‘«‡ƒ¦—ö ¹Å>÷ñ™’[ßQ±*åëà\Rº1)õßÁ¯�Qº¨¢­ƒMú$üqì1ÝüMåŒÌö ㎻{9H&¦¤cdô^¸œôš{Þ¥ï&gNª”ê½Tô˜§�«®» ˜|þ¥”mÅ¥§ Ååry³Y2MÀ¼§”8ú×ó¥(Vûþôé“ýtüétÛ¹~³ì®m«âï|Fëù¤”¸±¯SÖý¶©k¾”Cÿk›æ"µÒM¡Aõ>Z´Œ///¯J·î)ÅZËWPßö§§§×kµY–_µ¤<Õ¶¹Q—Çn‘Ôõ%W—ì#z?‘î§p¯6fw`;s¾ñ”Õ¥Á´T¾”§{.-(\ùµ¿±Ü; fZ¤±‹uê6÷×}œOøÅ[ÊÀö—äÔr»väÞÓ{ƒƒ_ãÓ= ƒÁ`0|0†éþEàüÝ×)#¶20± ô7TØdv<ŽÞ„KÆ2™iw@¦EËêXî÷‚l»¦É¼ô=ÐBàX!gêì\ux\&û݈ußóóó ûZ`4ºSt¬ÄÊǽ—jKü€Oå«~›úœúZ®¬êÎQÌ-]H’ÜzÍàê ÁwB?ùn�ykβäúµ«×îKŸ*ëËËËÍ¢>ÝêNÃ~¤‘hÔ‡?ù•3_M“Ñ'´NvØß.�î¹”NgyëÆg‰«óÎ¥„m0•7Õ‰k3ßc1Ðç9_8v[ë �­‰QgùÜÝøôºOp¯&XݘIT¹ÔuAÝÔ�¸äq /åP%—ÊÙjAÈߪ$U_S÷.÷^ëÓêI1L3óUeˆ}YÛ†s5áÂH»½õ •·ˆ×vQn*êÖæLøT<¸¿€ãS�O~àØçW 5'ïsciçÇ̱Së{�K‰Ê–”û´xIcâqd<Ž9©/¥´K§h»¾—”îÝÎH"¸zÞ™WRyv‚Ýx8øu1î%ƒÁ`0 ƒÁc˜î_ÊL*Ó]L[±�ºòNî%däóVæsÍ31'Ç8:†Æ1陿œ2(#ãÊË´S:�¬|61wLcÇ„L6å÷…SÞ òIDAT8kÁ <×ëm¨,—?+Kô×_ݰDêj î&���v/,Ö‘º´ð;¶VŸ?ŸÏo¾<Çt®|+ÖRŸIæjw­?Êz_.—›6¨Q@qGµtèiÇtëÆÇÔθ!´à\ÊT6µ,¸oUXÁz.màî¬MÊ®ë3÷°ÂY~æ©VæKÙÈt;÷52¿¬ïkÚÎØ©yVÚzܹ®¸çY^çFØô|jßÉj‘ÞËqÜö—ä>çÆ½§ÒswW¨®½t«daáñà×Ã(Ý¿’2LåÇ)g:QïN~šMû�ɉ'MÝÀãžáD˜Òp“b2¦�7)Žn2^)tnPŦ[€t2óÖGç;ÌI/Mè…———7‹u5Q¿kºY¸‰‰.l“ªT*Ô�˜‹KçQeu æ_òësIye)øjƒº˜Ñ>êk.^ØFؾ]”"'3åweMÑ4˜Ž†NÔw÷øøøzßËËË�¬)ZD]¯ÿÎïv× Cê;îRº¹èYåUíÄùçS–´ð£²I¹œ�xòyvrîŒ;zCSv �Â΃Ϻ…­ëoZºr‘TP™»:Y�‰«48÷�¢ýû`ÜKƒÁ`0 ƒÆ0Ý¿Üj_7–Ô¦Ê�ˆŽÙåq¥_i“eXEÖp,§Êݱ�+¦»3“²¬¼æ�˜ú®L+æ"=ŸØíU™³”ÞÓé6Uí°ÑÅvÇ­Yýñññõøéé)–…쥚|5úÅüñzì˜[eŒÕâã\MÈ®6â¹/�&6‹l4ݾȼ'«“¦§ÇdGÙ¦ëø|>[W�G×±:v}œõ íI7»–lÅòëø¤ý²ƒZ:ÔjR øŠéNíYÓwyv+¾»UCS½*G²F¤û:ÀÝzHHï�ý`g¬êÆ:¦Í6éæ>Z½©kÌW�w,¬Óùû=sÈàçÄ(Ý¿Üd¨ÑKÊß5)Ý�{‰sQ ©’a½œ²×M^•ÎÎ}®ÜDrópÑJÒ ™ÊÍ|œ«ÈnœvZ¼¤�šå-з²S¼ œŒ»gøqý”¼æ«nê¯�” *t§ÓéUa?ŽoŸŽ¯¼ô¿>Su¢îOŒàB3/ÓX«Û‡+‡ÞçYu5©´�{‚>¯ç´,w)�ú.vËêÆ¾oM‡ïÌÉ]¾ëõìããã�Á-¸]Ó{JésåÛmÏL/�ƒ¼–Â0ò¾´(YõI•+)Ún|ª{îu)Qtm›mFÛYr—az; ¾³4~ÐU$¹!±ÿ®dãµÝËNýiÞzOZƒ£tÿbèØ5�@U!;ŽÛI�TbK5Ÿ———­ /¥�&Æn0V¹Ý}nb\)Ýi± Ç«úÚAz&1FTîv޵<‰�Ñ{vev²i{RÖûz½Þ„ûûôéÓ«M¦Ô½‡b]ëš*g×ë·¸Ú¥ðÔ}iAà§�³Ü©Ž]Ò´˨Çdl•ÉUv]¿úI%W?n¤L ²S*N§ÓÍ8ñüü|Sw¬×O³ùõëÛ˜ëuüùóç×|®×k £Èð�õ|å© ÷.wYTžKmŸc‹Þ›”&²³ ©N;YùŒÛÈìòM f­ï�M£îùÝ|Üoþ§eWÁ¹@ßKÚ »³8ãX¢cÈn=R>Î1ƒ_ ãÓ= ƒÁ`0|0†éþÅà˜ŽãxëÓí\ŽãíÎóÎKÏEH «c@4=eÇœK@¥¡PW 2Ð.„Õ{™ÇØ¿7=2+d&;¦ëž|;ÖÏ1“]4w¾{ÿzß§Oß¾^Ù±wt[P‹�ÞSç?þ|ó.Ô¥Eå¦ÙyÅ¢Õóc§m‹ïÎYbè'ý×_Ù¾¨íž ±‚lkr)êÚ ëÈE&b]‘Õsí‰l¼2öZF¼!kíäTyèoÏ('�õͱòš—û¯ïˆõ½bKݘèÚ -"ì/É2TÇŒX•úÛ=Œs²Ê¥òtã<�cOk‰Þ¯uD?îdÉa?JLwÓv}À=Ó�Ÿn,¦û×Ä(Ý¿Òä^púLîÎ$’\*-gÂw¾¶úU†ÕdÓ=Ÿ|-©„ìL:Iî•ÒÝ ´•wšÜéî@Þ¤ ¤ /…årÂJáqeY)Ý•nÝ_JV=›L¶šv÷î?þ|ãZQŠ7Ý7tbNŠ™SÆVõí>UŸÚ–* \°8úz½¾Ù`©ùj¹éÃ­Š¨ƒ–¡>õ®}¹SÚÜûHn úŽãoåZ•åºöùóç›:I¾ÚT~J*¸ð†*ëjí”M×è“];FùŒ Ý}J´Ô»ëú•îòéÊKK1w ·nãòÎb˜sû‘ëƒÜ/ m‹}ÇÉAt}")çD³9÷~ Œ{É`0 ƒÁ`ðÁ¦ûC2O:÷çBðž��Ŧ8€Îä¦ ËÁ¨;ŒË�¨ÎܹÃw÷iš)O²¨î|ýv.ŽùßeÙ�ùÕå[H#IéÇ-‹þððpÃVë—+Õ¥@ÙUWÞÔ¶È®»È&çóù¦ÝëFEæé˜²:NíÁ™§ë¼«/²}»®Yu|¹\Žÿýï¯å¸\.7_šdÚÉRå˜Å§§§›/{vLijƒlO‰­½^¯¯cÉf_.—™ê-�Ö½CŠXÓÕƒƒëû:¶Ð² ýJ^gmc}9+ŸÞïÆFíHVÂÕºb­õ|¹!¦ûÒïÝh-„«ªl È••!9™žZŒRË.òKbåw‘ÚS]üZ¥ûC´kbwᣒQH&M=fd”¤Ä­Òeú5¨º0b«ôÜÕ•C¯L~«´;å|ÇDÏk:qpÁ”dežÎ\íòë&ФXqÂÖ¶ .,»*ÆNžš—¶*`ª@?>>ÞD6©c×îSœÞ¤èhé¢lèçÝÓ;*ÅÓ) é]><<Ü„T¥[9UÖ”¶–U£•Ð¥DŸIŠ·*²Z?.¬›k{\üœN§÷# ©ãSR’¸pWWæ³3Ntï™ýÚõ±.Ÿä†ÐµAÖ}Z$u„E×R]¤�; ºô»îO M›åÞñY×÷ïÆ^§ðòþ4^ºÅgW¯zÎÕq7–~ Œ{É`0 ƒÁ`ðÁ¦ûƒcŽãí—Ï:3_·‘Ò=Sù¨‰Ó¹$t1²;6æ^ó]1ºñl‡yïÌå.ïJ†”þŠÙvåK1¤Wy;ÖŒ×ôW>e}›•Xbm ÅÆÖµËår³ÙU]$Êí ÒÒôéz¤ç\ùN§on:çó9¾ge[ÝFÓkíÚL•ér¹Ø�Þh”Ê­‘„ø>>þ|c%H_±ÔÍ‹dÎôqãd²Z±~\ÒͪzÞ1“*‹¾C-;]Mœ5Jë¦Ò«:Ѹñ[›ƒ�õ'Õ'ËÐ哬“®¿¹ûRDž4V»ò鵎åîÆëdÉá=îÚ®ÓÍo+×,ÊÝY ãživ²º±jdÛ‡éþµ1J÷/†4€SéÖÁ‡Qî ¡Ä]òTXœIrW�ä@×™´©ðì(×ü�Ì�:(*V t!íÔO“¹““s7ñ�iÓ•?)ä�¢žtü³¶u!P¼Ò|zzjC¿±]¨gZ4©2—”Ruqayéw©×õ¼F¹\.¯.!Úߨ€jQWú¥RÑva é^Ð-ÈKé^…™Û9.W÷t ø_ýõZ_§ÓéfÁV 2 µÈþÅ÷£.D»‹pö‘.4¤–ÉE±Ù…Ö·S¸õýé;ë×ߋ՘ÁkîújŒI÷\{¬6œæ—–«§t3t®SÖ)7ß‘^ëÞ‹¶§Qº}Œ{É`0 ƒÁ`ðÁø?õ_>@«tIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/icons/slicesstack.png0000644000175000017500000000462614757047403027704 0ustar00paynopayno‰PNG  IHDR@HF:ó³sBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î< IDATxœíœ{�TÅÆçÎì.,„g²ò(vay ò ˆ…@”—F00òŠ!¤äQ1‰ˆEI �ªD-RZE  „H ‰ÁÒ°BxŠ á‘åÀ‚‚@ñ�]fNþè.÷ÎÜ™]˜�îWu«÷vŸ>çôw»O÷=wjEUñ‚ˆ4žzW�ÀV` °xZUŸ²²�á@ð±ªövéÊæ›Uu™§ÁLAUoº€öÀ`�këÄÖo.[âäkmý‡ú: œð²—ÉK¼f€ˆ®ªj+�¶°ˆ¨jWWÛ* ‰ª~Õ£Ï$àŸªº:ÍguKà¸+ìÔo,öê ª`º�¾Ë~}Tu~EkË'D¤±—`¨ê'˜=ߺ¤«§œ‘œU]ü“ŠúI Æâ@EY1Žz5Æoƒ±Y0FDš–Á`…!@DêapŸ©ê)/™k¨êZà]ÌÛÖ3e°‹]â^b2…X<î'àvp†-‘fiݜǼ{·NSGy!áúªºó–æ:)AU£\Ïðdz$\ÿà}Ž |”ˆ´ðh‚Šr JxTu &·"ÍY@Å9%]~¹³¯aÞÝ#@ë4so«£n:ù»ò¸€÷­ýüd<£´ªnä«®o��asûìm&—Al øÆß|€ˆtÀ¤¤Ú«ênOA?Å" �±ÀUýQ¬¾s�ð˜f­ùf*º‚âøýÇú¿E¦ZûU1&ŤÎ<¸¾FTu‡ˆ¬†bfÁˆýÙ„!àZgäΤŸÿ&+h8%¬ü]¤SãYzì�nãúú?å7xHžyÃà0wf5b�ð®Øgñö�œ'ÇM Ji§ƒ!#C_nÛ14×Þ&Ý! vÚ/Ǥ—g¦èO1æ+N.ÐNDœVݼ¥„RÔ“¾;=Ô­m§ð·²�` Àµ+¼€™þˆH7̇Ơ؊ùÈÒ 8¿'»†÷*Ý™Bÿ´pù"y@-{{BDªØ¿¯¨+è%LŠv¿ÛYÛo`¨à�Å‘:ûvkn~¡|6tTèÌ©“n’/%ÉYûV´Æ†¢h�VíäR»NÎ¥FM¥¤J¢é,üñõH�=jnß�ÎÙî}œ {wE�K¢ýTu¼\ÂPй:aZ¨á½8ômSÂáb­rî¬æÕ¬ ¦%žÉK_‹ðÈøŠ¢\¼@nÑêhî'²¹ùûÏ­AÑê( Œª5`ˆSkÍ›rqÅ’›¹ô¶V¼G8܈¾±8Ê�½ÉSé»8<=±Ç�c‡•¬,nËàwmWΞ��Žïl,\ºè/ˆ€‹”wߊâ8ðéiåÈÁä¶zõwˆ­°pÒ_"”²³á¡¾%üç#cxcQ”¿,�øÊ"`ø£!¦Ï “�cî�RJ|~nA˜êö—%I#Fù  …ðßPZbHin„A#ü—kà„ŘI!›h]-…ï%�eõê ]z¹Õ‚Z*²²¡v]ów$_¿G¨VÝ_>¥ŒÍŒ_„ñXˆplÛì“ÚË˲hÞJhÔô6E?¸6SÃY0å¹Äk/å”ÕüEa?âý�Áv³ª¹ðà·C\-MÕRú¨×À�]ÿ+B~abâÓÊÙÍ_¦Ï€à]ÇO qïý·/=8h¸CvŽ™±É�–W"0úÉà'ÚPFï–ž€o@‡.µë ÷ K>¼ÛöXB·oü´ÆO :wd:m}K���O Æøç’0;@|n ŠJ2í@¦QI@¦È4* È´™F%™v Ó¨$ Ód•dÚ�L£’€L;�iT�i2�J2í@¦ñ…' á—ƒ=èê‡ï)Mù_eTD”–"˜ÿNqþ‘_-:¤žúÊIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/icons/slicesstack.svg0000644000175000017500000001546714757047403027724 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/icons/tomwer.png0000644000175000017500000002144014757047403026702 0ustar00paynopayno‰PNG  IHDR––<qâbKGDÿÿÿ ½§“ pHYsÄÄ•+tIMEá 5J’“” IDATxÚí�y˜ÕÕÆ§ºgcØ÷Mv•hÔ¸G#w£F Ìô5nÄ}‰FqIBw“b™îÁ8ƨŸ{45jâŠ(1( È.ËÀ00k÷ùþ¨šî®îêîêa†n Þç™gz©ÛUuï[çžsî¹ç€{�¸ëè´«u�á±' 1¦°å”M@%ƒù×N;y„™À„/nòFÃ<“*¢• Ñj ÷´{÷¦ÂŽ"U%CñÂrX£•œ¼G©{Ä Ï£zæ™Ìgm J_|@ïÊê\Xuó€‰qm`0d,-™¤U| Ø&åü· ×YŠp7ÊÞø¸]ʘïI¬ŽB ¿D9ef=XAÊVáUùL«ØÛE³}Þ÷æ‹8KÏé<óñâY”wPi%w¶ATL.@K„Jo*ìX¹ì‹{W”©æãˆs; âÂJSÞJøä ¾Êà$]ň›2…«´’oeé"‰SŸG¬Ž•X3€�€Ï€k³jûÝ IÒ�±]37"ü ˆ �3e‘ ¤éðPì›ÕõúÏ[®ŠK<+Ÿu´ ÇàRáη¤s(–©4¸:ÖôÔ¿÷Q=ûIË=«p÷´�<ƒò?à>йÍõ“ë’TõÔ_| ¼ühW$Õ-±´Š½‰pJ#Ê_drjýGgÓƒ^Ò‹�ˆP„�XK>`Ð ¥„”í–d«Pj€�øÙDëåBëûö¸�‡éCÀÀGP&±Î#V®H5›})äß`CXEYˆò†TðUV?SMOyUÿ[#SÙ쫽ƪ�ôú¢ ú" Dè‡ÒôÑÊâM-°±6l5ÿ74ÃVkr«k€æ0D¶8È î�Àïƒ^�Í¿ž�¡_WèÝ%åéž.”k\ê~HÑ2)g^®Ç#¯£´’R|ôFé ô&Bo z¡ôAh}n’¨‘~Q�QlÒ! _ךk6ÃÚ-°n ¬®‰‘gƒE¤õµ1µ'J aH/ÖGŽ‚3C8 8@çp¨+©£¢¡`·Ÿ ut¦3�‰P tJQŠQº#ôŽN;z[ïûZŸõŠÝžk{¬Ýl’åëZXUcþ_]ëjíß5‡óï!*;BE ó7©àl—úÕÇ@?ë£ øØO&±!çÄÒ ×!qŠ(t±I2¡Ä6ÀJ7•(ÕUÌÿE@©E¢6;èZ¦äh�†6l5IÑ*UÖZR¦•<!Yv6ž»N>ÈêUe¤Tð… wÆ0ü\„1x0[+RCÜŒr=ð!>Îh/RŠÝG5fƒ†f¨o‚ÍÛÍ×Û¡¶Þ|]×[ëaÓ6sºY¿ÕN õ[¡fÛžgTœp¼r}ô�ž.å<Ð᪆P§BL“rnëÆÇ!�m�¦¢ ɃZ×Í- ¤i޽GLÒÔ7™ß퉤h¬Ûb{Û£ÃO¸�¬`3bEÆFXÛnÊû/ÿÏÐ|Á˜Á¶·‹¬ÞÎ4rð `Ê/¥‚¯whºK‹VrÊ¥¼I9/´!„:¥ò®{ê@ú èÖÉt ´þuëÝJ {)ù¡Ð¥Ö²u§B(²l®n%`Ä­[lÞfïÈÆfÓ ¨­‡ÆsêßÚ`Î Û¡f{ìu}ì;fŸûô7' " kuÚj5…4òà›q§XN‡È6¹Ô¥&¡ŒCYF˜;³YØíÜ mE‘ö£À^½``wèÛ úwƒÝc$ê\œ——ß„ðcÛJ@H0”F¦3\èRSPæDE‰�#€Ó#˜�0ÖFÊpfRé†ác(J %,’ ¸r¿j%ÃQú㣎Bþ›¶�P�r0Ô&máO.»ö`Pb½¿GÊ-ÉÛA�÷nC}†I0‰ä÷¥”Ù ¥a³Õ µ–þ°Å2m7#(ÊV P~ ÙÚ}/6¥X&üý:s j)¢¿L ^çr ßÃàýlâ½u6](ävàÛÀ:„û¤œ¿§Q†÷G™e}6€[)ç�©v=kˆcP~dSÄár ðT"Áà”1ÀR|ü\&ñ?×÷WÅ"œ|$[ÌWÇ+�ƒ´a ʰþL}ÄüL¬Ï” ¶a ~¶ ÔÒÌ© +o–å¾`ÿëàÓÕé�ïÓÖü.ªK…$@À…”‚ð= –&^�ilmÓÌb"¼õÿ$ãN p�ÃàŽ%Âó8/U)p�øs›®IBŒö'Â;2™·s9{û1¬pX¡%LÛdBÇο)ô…V±Â…}ä¨8]2K& r:ðXtP Y¦�ð=™ÂÒ6 `0 ©®ÒOI9oFÛÍ¢ªH½þ)ÀýZÅËY/ËTSHˆÇ�Ó-íä.©àê\Ë�2–IËd¤Œšœ�Ê$Ö~+7™á(™p؈¸7ÞÉ aºÁ„A�Á½Y_g�c€C2ÚaÊOlŸ”rfèN:”aZÖ×ÔÈQRÅ®à* rlΈ•î���˜&õ'.“õÛvPG1Ÿ¦=8Ì0ÌEñÄá?^5ËáH—G–ðàܦvî®ilЇõ;1^¿ŸLÏn†ç¼~“sÿå‡ko†1#&­r×ä[ã/ßÏh‰ùhI¡IÖe“ZȬb—TlkÔiöf“i9‰�ºŽ®KæÆ¼ýÇÝáÜù±™"˜֗n$Ö f4¦õ´~äbˆƒc^«ym�nwQ'JÑÅ;ä³J?ï8ÝÇ6"<Ýî³KˆS5Ä[´«?ù®�Úù²K'+b�hˆŒ&·L ŒrD•é`.EÎ[¸ô~Š´šnŽ?ÖÄ à";ŸP• 5Ÿ–²ðx Y±Îq–fRÎ?®ˆûýuD(sÏÕ]ø1”£€ŸjˆI­ÿñU»äÊb©¹4¢ð¿Õ.ˆeW�G¹4|%¾M])¢TL‘ Ô'XŽÇk�WèA-�lÖ Ë5È-ñ*ÓØŠrE†Ó½F!�ÙÎ?‰u(¿ÈÐî©D“VrŽy?ÛðS¯AÞ× SÈu/EôÁ`ƒ,“³“VäB òŒ¹<å1÷'…=äµòŽ˜kÙ׿Š&ì;ÀFÊqY�j[�,_ r!ðà„8ýh0?¯ëìØz TD˜Ž/cp¦“Þ'ü ¸-ïG)ŠIëšîB¨¶¬ÐÖ±:xXƒ„ ™@½”±îˆóõï†í–˜ûâ€AÈ¢U1I¥Š¤òÓýv"rÍ£y°�P+¹Cƒ¨ÑÑQHÿ7ªŸy¬Q­L/…šÿÒ*Û6±Œþ„‚xRÎKbMa ¸Êº&g¦¸Á¾1dÆY ƒ'›“ÔÎE$©?‡kŸVý*âÂÞÞ'5±d"+€Ë2üÌ2Ͻ+. ¸³»LP­d6Â�ý?[~­b£‘Ëm÷.|I!wµ¾=�ž—ÎåÃKçò¡Y�p ð)�c»–Bê}9‘X–%1à󶸌6†¯ æ�ÀiŽØ†ÁEym3“ô[ÉÖÓ•6L ÉÚÔz3Âã¿Âà°øl€7ÿ ¦“I€û¤œ ©HåÎxÍV3¼u^^ìRqÒË&íÚT¸HÆÒ¢³9…B*!)ðï  \Êx?Ÿy%¨Ó c1×X¿›ðõ™šüàYi‹nwúÍQýØ{ÒÒ/Ng‹ÜèXñ®—k`÷8ÖDûúR Ì4¶J€318áàB„Ó¨a¿ÄXð¼%W€5à”#Q*€ ‰0ž"ÏTî÷¡iÉc~ݩퟡ97KÖjw-[ï®É XPðj§5= 23Ö}°˜î–©©])c¤xË{‚Uðà?®º|.û üa¯�e=ÂÍRÆ;ƒ{²ßù³Ó'UÙuˆe0¤•Ë]fÁ#VÒ– �Go¼ Œ»³h%g›§kwDÔAÚêË2ãEŽÕyzïst¾¢ª#†87k/0­Á5.  øL?–Õv•ÃÔz¥�T&ö¶ƒR9H›¹àŠ*Þu�þGk�«Ý,éä—IJ2¯Ýì.ªa@÷¸$k†Ã¶(MQ£YL§äw5>˜‚0Ó£½ å%Â<˜5ÿR^·C¸Lº¼TR$9S´†˜Š2Ëû®•\*ü~×�X˜þ•K|P‰öÕG“³$EÓ¯Ó�ª�¼Šðgà{˜9 ¾ƒðKü¼«U®–Nvú”¦!žÀtlÎC¨h�7™—&‡Ej‡ïR‡c/#Ã’N|ƧEèœK«ñae¶[¹É]›�=’¦¾‚„÷w[ŽúœÂd¯qœmù p\ŠoGá™TÙ]rBª,ÃetFì˜uÛy6¥ _ÅŽqü‰EBmK::ü:!«˜�«‰­>,·«oWÛõv?–LfŽþŠY¤ûO4sŒLpNpZ'Ì ±Œ˜~´bcˆ•ZŸÊÚ*uq\¯¼˜Íh‚lÂe¢^ô࿲+Äe%¹Ïús>&Ã:an¦Â8KÍíTØ+>À¸†Míp]^ëú¼�U](¥-á2Àï'“ê�[Û^ù6­B�ùSÖnqפgL}¬“é4º:M�Qâ�Ë ¼êòZóÂ3o¹>²—Y4ß‚åÉÄ:ü»±ˆM/]Ö…ˆ:GÅ]µ* òàs”W0øBCÜl(s»}¦E× øy(| Ìvq”-\fÿŒLŒswÚ;¸»«˜Å!·»Ì„ЭS´s3Ê8+Lö"›Õ¢ÜªAŽNÐFÎ…” ¶uLȇjðQd.“*ÎýîÀΉçÏ™ÄÚ˜E›â‚¨ÄÚîâðT»pN´I­‰¬¦ˆ#€_s¤ÖUâTàI¦�wÞ±Âi�t.½tFl|,×ÉXpœÆ?@8Þ.“bÇG*_´É;’ U³ŒmÖÄRWú•/…"žÔÖ¬ë�ëõ~Šœô7 Ñ•w €îô ¬!æá&+º ýäx„_¢ #ؤ•Ê@Zx±™ú>”qÇk%“¤Â9/{ÖÝâ|”Y6ÿšYêF 9Q«/eÔ€»p™–0ŸøûÿsHNî¡óM„:)ge{ÜO.Ü E`ãvM¬X޾­ädY, ‘ÅZÛícùXª~ƒ™?  å2)O^Åψ*Óø�üs²ÝuìHªJÆ X… .„Œˆ«VÀ »è #ùF©â¯åÜ4�ý5pO†_^H s㬻¾ˆ«êgÅ;?ñs°*Ãy‹ãÆ�ŽP±0›ÃFìÀ8Gx-î\/äóT¸ {§¸ ð®=·Ìm8giŠÏÓOȃ¹ M¹^ø §'ø¿öqÙ§�3BdˆprÊÊL©àþjªxö¨#ô€Am_” !Âx„sØ”Pç:ϬÂU¨iåõ,…�.ŠËþ{‰­ý‘À#YjuSÈH*òAÚK5c“.Ð*%Ì�­*_^ ˆ9IIG|ÔG½g™Ðl�n•É,Ô9LÓ¬RyÀR„9HR°ãI÷±#mâ*µî?h‡l2¯ä¿»!n_à v‹™êhSà�˺c¦±ÕÚ}ò(­eD„/ s©«öæºáüŒnäz°2ZoKœvYŸÝeý¹ƒ‹„ Þùi™vþT‰éƒ³(yô|,2jd[ò„J9Oæ„2”S€ƒd²ëúÎîÎ1�F+WW&Ü×nçLp„64sW¢#ô»ûsÒŽî̉e°¢ÕðÖÇ}³çÀå'FÅüÉ8„�h5>ùf²ŒÅø¸)>ôE¦°§-OD›ï´i5ð+ ¸ªg“8ÅÝBÇZ»XœðKm%YÜY¶q[䑨y롉:B_¾žïŽŸiÞóÀô\z7‹ý<Àî̉Uȇ–QÌ!ÃÜ7{cqܵèŸ “T·Ç毮­šB"¼leS…¹-ìY­blÖd* lcœeQÆOô5ÀÍ æ™áZ³»rˆ&;~¦V³h&þÕ5l*ö3 7©wubY"ús€ïŒvß®±6ņ©oŠÃNIxÿ­r‘I¥�qHR�>ÊumºÇ Ù.®¤ˆ¾VV›ÙN? p{¶õšÝºqÀõÑótvi!ïâS¡‰g�+Gõƒo….²]õéý»G;ziŠÃ×·Rà")ˆ$­?¶N¹Cvð!ª§=2Ú¸p)¤iû$j“Rsv_b…yWrÓðÃû379,5žIqØ­Ö4Ö3læW¥à >tœœ$9e¤ÎÀ`'a(‡í‘SË*¿r:Ð@KŠ@páRHc´\ç&õcû{•r+—æyw¿×<š:éÁCáÍ›£ YÊÁ©ô�G?Œޓ@Úq{» óÀ¶óy+ÊÑñùHµ’R„— NÇî—r~ºýpÂcĪȯ¾íZM!�¼íàR8Ôq7s —Ä*µ:ô€7?ƒªá_Ÿ�ÆìÄ!tQtÓjaŽ”),Ò‡éC§áÍöpXƒw©å€]C˜ß'þ®Vrâ°›ØàˆV -zì£ $ÌL«�ù„[‹qêŠñ³ÜAgü§솃†èŠòS„oK0¸»=6{h%¥Ài(´§û%·õ «ñÑÄí(W¶:.×l†OVBm½Y¦wLL»Ø@„Óe2o[$øsý¯?c¬¬É{½!^Dù¾C/Þ åÌŒ7‹Ntâ#ì±N�D8J&óaœ”<(…ÖÂv:9úl÷{ ò&p4f8Ó‘;ZA,wî»r–r~†²ÊÀòÝaü8û°(©6#üå™l•¡mf(±Eå®´dïh#jS(ùu v×9$Ða$ElKi§®éøM¥ÖŽ£Öø°â¸×»6±¢«à ©`º†Ÿ!GY ŸRD?)ç"[Qí–Å=é5(ÿlÓzµùRƒ,²bŽ\42«Á& ’’îH1?ØããËYŠózå<·¾. 2Uƒ|©•|ª•î‰!º�¤u©ªMS7{Wš ÛAG;ÅÒ±VeIªS°Wx¯ÇÏ(§ú†Óáå(·a®.¦HÀNl‡ßoŃàbÛ±U %B3ì8üå<7¹Su.bðaœ€Pààl¦3­¦„&N¤™�Òxïj~¬ö�rÛpÿ�âq:.!ž²„0Ç�¹0ßïÕÙ̦€R‘"òs)/0’±o’]‹‘¼FÊXŽYq¬/aš²JQip\¬#ÖtæšX–¯íÉÝÃ�•kDø"IV‹{ׄLc+�r/·Ì ¢ÕœE?ÁàÛ(ËñsO:Ã6Õ»@–:/ a%¸¡IDATÏ‹Oä•VSB#Ïc®)*Êï¤"eˆrþÞ‡"„‚•Zx„2ΡÚÖ{$±¢ƒRÅÂlr££é\!Œ¢ž·:Ú  !¾A3[Ýê<­›vÛR Ú#V.Id"03ªó+"ŒoïX.K’úhà +ŠAد~.ax´É8Ø…Àˆ%q‚/厖Ķ=5Ä™úHŠ<ô‰häG©Ì‡^™Þ–Ð�|À¡¼ëŠñqÅ„ù�­–_&ÔÑ�‚„Bæš9¨Vq8�üè†ÕJ.Ë`§ IšC")"/ÒI½&.†#ÜmY�žÄêø¸áf”k1Üoº�óX ›Ü8d#\Kló† üÚEn­Ä]ÞMY–{kb2Ê=(Ó‰ð´7v¬&9:îuöÙaüL^DY�òõöÔ“)�x]JÿôAvRÁ«ÀÅÀg(ÿ&e-q졇{Sa‡Î…<€03mä̬yiúŸNʲÙKÄW¾Pæ» qq“ê:ƒ¨á ´OJ"Ï*LÇ­ùøYO�åiÞJ¿�&®G9 áS ®·2àì,ƒ£0UevaíÃC¦§¿3MA˜YY“íqP(¼·«õ›çÇJ7°³( ‘·­|ñ霷CGž;Ä$  ¼«¡Œ™h§H€K°Ó]„5Lk©+H?XcH¬¡]vÚ à€KÐö=2ºX%iH…M>ë«´�ôÆÐì€\„-äVS7¹X ©«…-˜6,$V‹töÚ`'l_VB«##-�v0àÔ ÝR "¢A"*Q†ˆ\fB‘þ•Ì,‘. ˆH+¥fž0¥”š ‚`jffæ.€ú}ì\K­œ ¶µÂ1Øíãû„„,‹�¥R)ë8Ž›$‰à%)åú‰¨@Dl¾éÇM ’ˆˆ43GÌ<ÍÌef¾®”º!„øÀÍjµZ¯V«3X¦6ZBƒÆRRn­‰ ¶Ù“°‹ª…D±XìÎçó/¹®;œzƒoŒa ÅÆ˜@ÈÌ1%̬ˆH3;2DTBtÑDT ˜yÄs&I’„¿(—ËËÙÒÒ�¬WïLûÚ\ 5É\’ ú ¾ìÓÀAiKãSdÿ.Ñßßÿ´ã8{„[aë�"ìè4˜¹ÁÌR‘#¢€Ÿz`+͘ˆBcLÈÌu "r`=Å#¢"Ú ÃÌãDtV)uÎóq¹\þK{ɽU9ÛvŸÕÖÓøE:¸.×Yxç8°¹Ë&H¯œî®`‰ÌÜÑÑÑåºno6›ÐZ'¢½ú$ÌÜ ¢€Bt1sAQ° @�ˆò°^ ˜ÙQ  !¥¬2ó3O0ó$3Ï0sHDãéóúÓ{¿#„8`÷Ö­[»´Ö·fffʵZml@©—Kík0ÐXèåóÈ`ÀÕv‰�0¥m&¦¹¯!Z®])å>Çq¾ÊÌ_—RưÞ5 ÀQ Kñ$mK;ÐD´ð_LD†™ï¨˜2Æ\Ãð„Rj"“Éô»®û×BˆCRÊ}Ìü-­õ»…Bá­Z­vs3±½Ø«�é—¿-çŽó0� u`´ 8Îvö��¦J¥RG.—{^J9,„ØBDucL(„‡™c­õ„i¼/òÀû€a ÁO�1—˜™¤”/d³Ù¯c.Æqü~†?ñ}ÈuÝ'¤”_qçO¥”»†††öÇqüúøøøXÙzáQ(ÅÀ™ï—ßtš\•òíŒÔd8ËÀy�kà` ®#/öõÕ®9Î!O !úˆÈaæ€Ø3eŒ™ÐZ'DäJ)·Q'ìÌ1×Sæ/˜ùl†÷ì ¢Çaçé}’ˆ†˜ùÓ(Š.:Ž“s]w§bÀu݈èªÖú3—=Ï»+„x–ˆŽQ)/e釥ÒT¹Ñ�½J}äoù6/Þ ›v#ÐŽŒf8 �©K¯WþØ)¥<ö7Õêð/óù-ÿãyq�9fæ €€™•RêjE#õz½ÞÓÓó5"Ú “`RׯcNi­ß‹ãøu{ž÷Bˆ?BbfŸèÞ>ËAg¢(úu¥Rù—îîî#žç=ã8Îq)å.¥ÔûQ½Çñ§ù|Þ‘R>;dÌá#a¸/tœË?êèøù§¾¥\.›´_­d¬Ì3œ?~ P¯—{zž: uñˆÖ]?¨ÕôUÇ™=éywn$ÉÇI’„Zk%¥ “$¹à8΋DÔÇÌÓ"Ê2sÀÌï…aø~½^?Y¯×/år¹ýŽã™Læn.—ÛBD=°ÙHJùX>Ÿß6;;ûÓjµÚÈd2£Ùlö¬ëºåºîŸK)Ôjµô§¦Þþ–””ó¼ç.z^çù|þ`œZûƒƒƒo”ËåK-}j»ï»¬g¤�ÝÝÝŽãe!¶Ÿ—rú<ð»Ýq¬ž�¢ÂßÖë¥ °ãCcÞû™çÝff BcÌ¿RJÅRÊ^!D'3ßB\¨×ëW„�Fãj>Ÿ¿MD À3—ˆÈmEOJéˆ�Æ!DHD‘âu)å7!÷¼W_ˆã«�R£ozÞëÓ®û;…Û|OJùØ�³&VL†i1…B¡[ñ8í&"ÖZß1ÆÌœ' >n¾,¿¬õŽH’Ãÿœ$=Î`˜Ù!¢zÇgëõú”ïû™Lf¥”æÊ㊔r“ã8Yf–´xjI07;ÌÔj5[30»}¿÷°RC.pôD¡ ?.Q4’SÊ‘R6ˆh;uaÎÓú}ÉÐhIxRʭƘmBˆ™8ŽkƘJ3°õïÁèëÀÿ¶,”že`æ»q¼é´çåô»®!œ”ˆ£Dt¢¿¿??::ª·lÙBZ냞'¢AÌå˜f§kJ©)̹øì«µÚµAÏ;œ ‚ðd.÷Á‰bñ�#¢ã®1ÐÌ“•JåD±Xó}Øã¦y­m°T˜ÜcLM)5¦”ÖZß ‚àzúõ½žl=pš�Ïìþ£ZÍÙåyg=ïÏ.ærµD´?]¬ýÐ÷ýß¼iŒÉº®û”â÷‰¨ÀÌ÷Ú&"ÅÌq—1WEnÑÀÓSq¬ÿ®Pøù¿»îÓàÛdGg&“ùK­õ?EQt1Žãk( Ãò‚>®8�´x�EQ@&“Ù–Ævµ³i+!€³{}ÿßž"¿S©—ö(5tÙóü×íTÌDDG<æºî$3{D´™ˆú[Ã$]·|àT†WÇ€Loº›&� ½ÀÙ72™a_Ê®–Ð*ÑÎL&3†á;µZícÃpj){WBƽљ���‚]²S&“ÙæºnW___ªZ­Ö°Ävá�Fãòt©ô~.“9ô˜R»v'Iáq¥èºãàsÏë…è^Dä\ºˆŒ)¥þÛI’ÓõF£à«°äPíéééÏf³ÃDt(-×eÚ_±/›Í¾;11±ÔêzU ´mL !|!ć]×�êìì<5==}­Ýoƒ ¸�Ífÿ«fÌÌõ\îÕ›®{x@ëìÞ$ÁŽF·#®‹šXÜ3�1óo÷W«W~\«í‡õÄ3°GÜÛÛ[ð}ÿ"ú®â3_�-ܺ–è|;2V&mÉPJU=Ï«èô\H)¯I)3žçm–R!º…!„À7Æ™9I÷<55«L C¥JŽ1>cL…™+qÁÍ8ŽÉó<2ÆL…axco‡U‡ÉRžÑ†áõôž|±Xô™y&}Vë^£%ôš^ѼÜE]Ìù­O6¯”º†áMH’¤Õ¾Áª=£íô³ š�¬¸�V…óJûv´®Ëž5¦PJDt®ù¿0 XíÈšèZ «Õêš”7OÚ•,­õþUbí:l–ùn£±dÁ·ÎhêØýs!Ö&ë�…aµQh&ízÐ0yP< 2Ú¢�ìñË“‡å­%6�.ôŒ/“Œ “TI°7½\8CqSÚÎ3ö0m� l)l©’à(ì¶âi؃±y?YDã£À Øß |›�É pq0 [‘.'*kʯ×*<[HÆjÔË­Ç ÷pèÜnOà²kµ¨ +kFJ†Æ|ã©ßzÇãõ{2À3Wtg6Ù –åN¼%Ö‡ Ñò¬•]2½_Þ±: pP0ZÞÙf7‰ÚÙÎL“ŒV6ýôºÑk 9ýpvصÉî~?ÁV�€æh’ú rÄ&NjG‚•y�vò5@|Ø; ç�ºÞs�2æ„1í¦U`‹]±™T�Fš€¶ÀJ„6aNë]Á:h28`o¦v4 ^!låG #>{8ÿÊüº‰ÐÞË5;ÞÚØ’Ò t³ç€lÉØ àEžª®Veצ?÷rΊµ�lµ[ð £kYà×¹ÅKúå‹�ö™{U¯\´UwÃnª\Â|‰ÐŠ‘ÊðÓþ¾)Í>€4ÏѼ‘°ÜæÎŠ@@ À'éáÑã©qÃl?ͼ²ÊGÞ<ÿm…ß­‡uµ"’%Ñ”/°�¿‡`GëOؾds‘¬`õ~¸ï@¤áyV‹6à³õÒ¡®M¤9ã€[-yå¼²wHšGˆ‹6£SqÚAØ­ à-º�&t ¶o image/svg+xml ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9091008 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/tests/0000755000175000017500000000000015153325403024673 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/orangecontrib/tomwer/widgets/visualization/tests/__init__.py0000644000175000017500000000000014757047403027004 0ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9091008 tomwer-1.6.17/src/tomwer/0000755000175000017500000000000015153325403014326 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/__init__.py0000644000175000017500000000071414764622416016454 0ustar00paynopayno# coding: utf-8 """ Applications and library for tomography processing. Provides ewoks tasks, several GUI for nabu as several utils. """ from __future__ import absolute_import, division, print_function from tomwer.core.log import processlog # noqa F401 from tomwer.version import version as __version # noqa F401 try: # try to first load hdf5plugin before h5py import hdf5plugin # noqa F401 except ImportError: pass __version__ = __version ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/__main__.py0000644000175000017500000002127215153325210016420 0ustar00paynopayno#!/usr/bin/env python # coding: utf-8 # /*########################################################################## # # Copyright (c) 2017 European Synchrotron Radiation Facility # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # # ###########################################################################*/ """This module describe tomwer applications which are available through the silx launcher. Your environment should provide a command `tomwer`. You can reach help with `tomwer --help`, and check the version with `tomwer --version`. """ __authors__ = ["V. Valls", "P. Knobel", "H. Payno"] __license__ = "MIT" __date__ = "10/11/2020" import sys from collections import namedtuple import tomwer.version from tomwer.utils import Launcher as _Launcher from tomwer.core.utils.deprecation import deprecated_warning DeprecationWarning = namedtuple( "DeprecationWarning", ["since", "reason", "replacement"] ) class Launcher(_Launcher): """ Manage launch of module. Provides an API to describe available commands and feature to display help and execute the commands. """ def __init__( self, prog=None, usage=None, description=None, epilog=None, version=None ): super().__init__( prog=prog, usage=usage, description=description, epilog=epilog, version=version, ) self._deprecations = {} "deprecations with prog names as key and deprecation info as values" def add_command( self, name=None, module_name=None, description=None, command=None, deprecated=False, deprecated_since_version=None, deprecated_reason=None, deprecated_replacement=None, ): super().add_command( name=name, module_name=module_name, description=description, command=command ) if deprecated: self._deprecations[name] = DeprecationWarning( since=deprecated_since_version, reason=deprecated_reason, replacement=deprecated_replacement, ) def execute(self, argv=None): if argv is None: argv = sys.argv if len(argv) <= 1: self.print_help() return 0 command_name = argv[1] if command_name in self._deprecations: deprecation_info = self._deprecations[command_name] deprecated_warning( type_="application", name=command_name, reason=deprecation_info.reason, replacement=deprecation_info.replacement, since_version=deprecation_info.since, ) super().execute(argv=argv) def main(): """Main function of the launcher This function is referenced in the setup.py file, to create a launcher script generated by setuptools. :returns: The execution status """ _version = tomwer.version.version launcher = Launcher(prog="tomwer", version=_version) launcher.add_command( "axis", module_name="tomwer.app.axis", description="Compute center of rotation of a scan or " "between two projections", ) launcher.add_command( "canvas", module_name="tomwer.app.canvas", description="open the orange-canvas" ) launcher.add_command( "dark-ref", module_name="tomwer.app.reducedarkflat", description="Compute mean / median darks and flat fields", deprecated=True, deprecated_reason="improve name", deprecated_replacement="reduce-dark-flat", deprecated_since_version=1.2, ) launcher.add_command( "dark-ref-patch", module_name="tomwer.app.patchrawdarkflat", description="patch raw dark and / or flat to a NXtomo entry", deprecated=True, deprecated_reason="improve name", deprecated_replacement="patch-raw-dark-flat", deprecated_since_version=1.2, ) launcher.add_command( "diff-frame", module_name="tomwer.app.diffframe", description="Tool to compare any frame from the acquisition", ) launcher.add_command( "image-key-editor", module_name="tomwer.app.imagekeyeditor", description="Tool to modify in place frames image key parameter.", ) launcher.add_command( "image-key-upgrader", module_name="tomwer.app.imagekeyupgrader", description="Tool to upgrade in place frames image key parameter.", ) launcher.add_command( "norm-intensity", module_name="tomwer.app.intensitynormalization", description="Tool to compute intensity normalization.", ) launcher.add_command( "multi-cor", module_name="tomwer.app.multicor", description="Compute a slice with different values of cor", ) launcher.add_command( "multi-pag", module_name="tomwer.app.multipag", description="compute a slice with different values of delta / beta values", ) launcher.add_command( "nabu", module_name="tomwer.app.nabuapp", description="Use nabu to reconstruct a given scan", ) launcher.add_command( "nxtomo-editor", module_name="tomwer.app.nxtomoeditor", description="Use to edit a NXtomo", ) launcher.add_command( "ows-to-script", module_name="tomwer.app.ows_to_script", description="Convert a .ows file to python script", ) launcher.add_command( "patch-raw-dark-flat", module_name="tomwer.app.patchrawdarkflat", description="patch raw dark and / or flat to a NXtomo entry", ) launcher.add_command( "reduce-dark-flat", module_name="tomwer.app.reducedarkflat", description="Compute reduce darks / flats (mean / median of raw darks and flats)", ) launcher.add_command( "rsync", module_name="tomwer.app.rsync", description="Tool for synchronization between " "acquisition contained in a folder and " "a target folder", ) launcher.add_command( "sample-moved", module_name="tomwer.app.samplemoved", description="Interface to check if a sample have " "moved during acquisition ", ) launcher.add_command( "slice-stack", module_name="tomwer.app.slicestack", description="Display each reconstruction contained " "in the ROOT_DIR or sub-folders", ) launcher.add_command( "sinogram-viewer", module_name="tomwer.app.sinogramviewer", description="Allows to compute on the fly sinogram " "and display them", ) launcher.add_command( "scan-viewer", module_name="tomwer.app.scanviewer", description="Scan viewer / browser", ) launcher.add_command( "stop-data-listener", module_name="tomwer.app.stopdatalistener", description="Send SIGTERM or SIGKILL signal to the process occupying" "rpc-server port", ) launcher.add_command( "test", module_name="tomwer.app.test_", description="Launch tomwer unittest" ) launcher.add_command( "volume-viewer", module_name="tomwer.app.volume_viewer", description="Launch tomwer volume-viewer. Allow to browse a volume.", ) launcher.add_command( "y-stitching", module_name="tomwer.app.ystitching", description="Launch y-stitcher interface", ) launcher.add_command( "z-stitching", module_name="tomwer.app.zstitching", description="Launch z-stitcher interface", ) status = launcher.execute(sys.argv) return status if __name__ == "__main__": # executed when using python -m PROJECT_NAME status = main() sys.exit(status) ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1772989186.913101 tomwer-1.6.17/src/tomwer/app/0000755000175000017500000000000015153325403015106 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/app/__init__.py0000644000175000017500000000012414764622416017227 0ustar00paynopayno"""This package contains all the applications that can be launched from 'tomwer'""" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/app/axis.py0000644000175000017500000001335415153325210016426 0ustar00paynopayno#!/usr/bin/env python # -*- coding: utf-8 -*- """Application to compute the center of rotation of a scan""" import argparse import functools import logging import signal import sys import silx from silx.gui import qt from tomwer.core.process.reconstruction.axis.axis import ( AxisMode, AxisTask, NoAxisUrl, ) from tomwer.core.process.reconstruction.darkref.darkrefs import ( requires_reduced_dark_and_flat, ) from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils.resource import increase_max_number_file from tomwer.gui import icons from tomwer.gui.reconstruction.axis import AxisMainWindow from tomwer.gui.utils.splashscreen import getMainSplashScreen from tomwer.synctools.axis import QAxisRP logging.basicConfig(level=logging.WARNING) _logger = logging.getLogger(__name__) class _AxisProcessGUI(AxisMainWindow): def __init__(self, scan, axis_params, parent=None, backend=None): axis_params.frame_width = scan.dim_1 super().__init__(parent=parent, axis_params=axis_params, backend=backend) self.hideLockButton() self.hideApplyButton() self.setScan(scan=scan) # connect Signal / Slot callback = functools.partial(self.compute, scan) self.sigComputationRequested.connect(callback) self.setWindowIcon(icons.getQIcon("tomwer")) def compute(self, scan, wait=True): mess = " ".join( ("start axis calculation with", scan.axis_params.axis_url_1.url.path()) ) _logger.info(mess) process = AxisTask( inputs={ "data": scan, "axis_params": self._axis_params, "wait": wait, "serialize_output_data": False, } ) try: process.run() except NoAxisUrl: msg = qt.QMessageBox(self) msg.setIcon(qt.QMessageBox.Warning) text = ( "Unable to find url to compute the axis, please select them " "from the `axis input` tab" ) msg.setText(text) msg.exec() return None else: position = scan.axis_params.relative_cor_value assert isinstance(position, (float, type(None))) self.setPosition(relative_value=position) return position def _updatePosition(self, scan): self._widget.setPosition(relative_value=scan.axis_params.relative_cor_value) def main(argv): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "scan_path", help="For EDF acquisition: provide folder path, for HDF5 / nexus " "provide the master file", ) parser.add_argument( "--entry", help="For Nexus files: entry in the master file", default=None ) parser.add_argument( "--use-sinogram", help="use the signoram from radio for computing COR. This only work" "with the =scan-path option", action="store_true", default=False, ) parser.add_argument( "--debug", dest="debug", action="store_true", default=False, help="Set logging system in debug mode", ) parser.add_argument( "--mode", default=None, help=f"Use a specific mode. Available modes are {[item.value for item in AxisMode]}", ) parser.add_argument( "--full-image", action="store_true", default=False, help="Define the mode 'full' when display shifted images from manual" " mode", ) parser.add_argument( "--use-opengl-plot", "--opengl-backend", help="Use OpenGL for plots (instead of matplotlib)", action="store_true", default=False, ) options = parser.parse_args(argv[1:]) if options.debug: logging.root.setLevel(logging.DEBUG) if options.use_opengl_plot: silx.config.DEFAULT_PLOT_BACKEND = "gl" else: silx.config.DEFAULT_PLOT_BACKEND = "matplotlib" increase_max_number_file() global app # QApplication must be global to avoid seg fault on quit app = qt.QApplication.instance() or qt.QApplication(["tomwer"]) splash = getMainSplashScreen() qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor) qt.QApplication.processEvents() qt.QLocale.setDefault(qt.QLocale(qt.QLocale.English)) qt.QLocale.setDefault(qt.QLocale.c()) signal.signal(signal.SIGINT, sigintHandler) sys.excepthook = qt.exceptionHandler timer = qt.QTimer() timer.start(500) # Application have to wake up Python interpreter, else SIGINT is not # catch timer.timeout.connect(lambda: None) mode = options.mode if mode is not None: mode = AxisMode.from_value(mode) try: scan = ScanFactory.create_scan_object( scan_path=options.scan_path, entry=options.entry ) except ValueError: scan = ScanFactory.mock_scan() requires_reduced_dark_and_flat(scan=scan, logger_=_logger) # define the process_index is any tomwer_processes_existing if scan.axis_params is None: scan.axis_params = QAxisRP() if options.debug: _logger.setLevel(logging.DEBUG) axis_params = QAxisRP() window = _AxisProcessGUI(scan=scan, axis_params=axis_params) window.setWindowTitle("axis") window.setWindowIcon(icons.getQIcon("tomwer")) if mode is not None: window.setMode(mode) if options.full_image: window.manual_uses_full_image(True) splash.finish(window) window.show() qt.QApplication.restoreOverrideCursor() app.exec() def getinputinfo(): return "tomwer axis [scanDir]" def sigintHandler(*args): """Handler for the SIGINT signal.""" qt.QApplication.quit() if __name__ == "__main__": main(sys.argv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771230222.0 tomwer-1.6.17/src/tomwer/app/canvas.py0000644000175000017500000000300215144552016016730 0ustar00paynopayno"""Application to define a tomography workflow (also as know as 'ewoks-canvas' or 'orange canvas')""" import logging import platform import sys import psutil from tomwer.app.canvas_launcher.mainwindow import OMain as QMain from tomwer.app.canvas_launcher.utils import get_tomotools_stack_versions from tomwer.core.utils.resource import increase_max_number_file _logger = logging.getLogger(__name__) def print_versions(): """Prints the Tomotools packages versions""" print( "\n - ".join( [ "Tomotools packages versions:", ] + list( [ f"{soft_name: <11}: {version}" for soft_name, version in get_tomotools_stack_versions().items() ] ) ) ) def check_free_space(): """Check if enough space exists. Else could bring issues on processing""" if platform.system() == "Linux": try: free_home_space = psutil.disk_usage("/home").free except OSError: pass else: if free_home_space < 100 * 1024 * 1024: # if no space Qt might fail to create the display and log file not be created _logger.warning( f"only {free_home_space / 1024} ko available. Display might fail" ) def main(argv=None): print_versions() check_free_space() increase_max_number_file() return QMain().run(argv) if __name__ == "__main__": sys.exit(main()) ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1772989186.913101 tomwer-1.6.17/src/tomwer/app/canvas_launcher/0000755000175000017500000000000015153325403020242 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/app/canvas_launcher/__init__.py0000644000175000017500000000000014757047403022353 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/app/canvas_launcher/config.py0000644000175000017500000000774215153325210022067 0ustar00paynopayno# coding: utf-8 from __future__ import annotations from orangewidget.settings import set_widget_settings_dir_components from orangewidget.workflow import config from silx.gui import qt import logging import tomwer.version from tomwer.gui import icons try: from ewoksorange.pkg_meta import entry_points except ImportError: # ewoksorange < 2.0 from ewoksorange.pkg_meta import iter_entry_points as entry_points from . import environ from .splash import getIcon, splash_screen from .widgetsscheme import WidgetsScheme _logger = logging.getLogger(__name__) def version(): return tomwer.version.version class TomwerConfig(config.Config): """ Configuration defined for tomwer """ OrganizationDomain = "esrf" ApplicationName = "tomwer" ApplicationVersion = version() def init(self): super().init() qt.QApplication.setApplicationName(self.ApplicationName) qt.QApplication.setOrganizationDomain(self.OrganizationDomain) qt.QApplication.setApplicationVersion(self.ApplicationVersion) qt.QApplication.setApplicationDisplayName(self.ApplicationName) widget_settings_dir_cfg = environ.get_path("widget_settings_dir", "") if widget_settings_dir_cfg: # widget_settings_dir is configured via config file set_widget_settings_dir_components( widget_settings_dir_cfg, self.ApplicationVersion ) canvas_settings_dir_cfg = environ.get_path("canvas_settings_dir", "") if canvas_settings_dir_cfg: # canvas_settings_dir is configured via config file qt.QSettings.setPath( qt.QSettings.IniFormat, qt.QSettings.UserScope, canvas_settings_dir_cfg ) @staticmethod def splash_screen(): """""" return splash_screen() @staticmethod def core_packages(): return super().core_packages() + ["tomwer-add-on"] @staticmethod def application_icon(): return getIcon() @staticmethod def workflow_constructor(*args, **kwargs): return WidgetsScheme(*args, **kwargs) @staticmethod def widgets_entry_points(): """ Return an `EntryPoint` iterator for all 'orange.widget' entry points. """ # Ensure the 'this' distribution's ep is the first. iter_entry_points # yields them in unspecified order. WIDGETS_ENTRY = "orange.widgets" def accept_extension(entry): # safer to ignore some extension like ewoks demo return entry.name.lower() not in ("ewoks demo",) try: all_eps = filter(accept_extension, entry_points(group=WIDGETS_ENTRY)) except Exception as e: _logger.error(f"fail to find add-ons. Error is {e}") return iter(all_eps) @staticmethod def addon_entry_points(): return TomwerConfig.widgets_entry_points() APPLICATION_URLS = { #: Submit a bug report action in the Help menu "Bug Report": "https://gitlab.esrf.fr/tomotools/tomwer/-/issues", #: A url quick tour/getting started url "Quick Start": "https://www.youtube.com/playlist?list=PLddRXwP6Z6F9KOu1V5o6H24KPH5Ikuk2f", #: The 'full' documentation, should be something like current /docs/ #: but specific for 'Visual Programing' only "Documentation": "https://tomotools.gitlab-pages.esrf.fr/tomwer/index.html", #: YouTube tutorials "Screencasts": "https://www.youtube.com/@tomotools", } class TomwerSplashScreen(qt.QSplashScreen): def __init__( self, parent=None, pixmap=None, textRect=None, textFormat=qt.Qt.PlainText, **kwargs, ): super(TomwerSplashScreen, self).__init__(pixmap=icons.getQPixmap("tomwer")) def showMessage(self, message, alignment=qt.Qt.AlignLeft, color=qt.Qt.black): version = f"tomwer version {tomwer.version.version}" super().showMessage(version, qt.Qt.AlignLeft | qt.Qt.AlignBottom, qt.Qt.white) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/app/canvas_launcher/environ.py0000644000175000017500000000462514757047403022315 0ustar00paynopayno""" environ ======= This module contains some basic configuration options for Orange (for now mostly changing directories where settings and data are saved). How it works ------------ The configuration is read from '{sys.prefix}/etc/orangerc.cfg' which is a standard `configparser` file. orangerc.cfg ------------ .. code-block:: cfg # An exemple orangerc.cfg file # ---------------------------- # # A number of variables are predefined: # - prefix: `sys.prefix` # - name: The application/library name ('Orange') # - version: The application/library name ('Orange.__version__') # - version.major, version.minor, version.micro: The version components [paths] # The base path where persistent application data can be stored # (here we define a prefix relative path) data_dir_base = %(prefix)s/share # the base path where application data can be stored cache_dir = %(prefix)s/cache/%(name)s/%(version)s # The following is only applicable for a running orange canvas application. # The base dir where widgets store their settings widget_settings_dir = %(prefix)s/config/%(name)s/widgets # The base dir where canvas stores its settings canvas_settings_dir = %(prefix)s/config/%(name)s/canvas """ from __future__ import annotations import configparser import os import sys import sysconfig import tomwer def _get_parsed_config(): version = tomwer.__version__.split(".") data = sysconfig.get_path("data") vars = { "home": os.path.expanduser("~/"), "prefix": sys.prefix, "data": sysconfig.get_path("data"), "name": "Orange", "version": tomwer.__version__, "version.major": version[0], "version.minor": version[1], "version.micro": version[2], } conf = configparser.ConfigParser(vars) conf.read( [ os.path.join(data, "etc/tomwerrc.conf"), ], encoding="utf-8", ) if not conf.has_section("paths"): conf.add_section("paths") return conf def get_path(name: str, default: str | None = None) -> str | None: """ Get configured path :param name: The named config path value :param default: The default to return if `name` is not defined """ cfg = _get_parsed_config() try: return cfg.get("paths", name) except (configparser.NoOptionError, configparser.NoSectionError): return default ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/app/canvas_launcher/mainwindow.py0000644000175000017500000005332715153325210022776 0ustar00paynopaynofrom __future__ import annotations import argparse import logging import os import shutil import signal import sys import pkg_resources import silx from contextlib import closing from logging.handlers import RotatingFileHandler from xml.sax.saxutils import escape import pyqtgraph from orangecanvas.application.canvasmain import DockWidget from orangecanvas.application.outputview import ( ExceptHook, TerminalTextDocument, TextStream, ) from orangecanvas.document.usagestatistics import UsageStatistics from orangecanvas.main import Main as ocMain from orangewidget.workflow import config from orangewidget.workflow.config import data_dir_base from orangewidget.workflow.errorreporting import handle_exception from orangewidget.workflow.mainwindow import OWCanvasMainWindow as _MainWindow from processview.gui.processmanager import ProcessManagerWindow from silx.gui import qt import tomwer.version from orangecanvas.preview import previewdialog, previewmodel from orangecanvas.application import examples as orange_examples import tomoscan.version from .config import TomwerConfig, TomwerSplashScreen from tomwer.core.log.processlog import ( PROCESS_ENDED_NAME, PROCESS_FAILED_NAME, PROCESS_INFORM_NAME, PROCESS_SKIPPED_NAME, PROCESS_STARTED_NAME, PROCESS_SUCCEED_NAME, ) try: import nabu except ImportError: has_nabu = False else: has_nabu = True try: import nxtomomill.version except ImportError: has_nxtomomill = False else: has_nxtomomill = True try: import nxtomo except ImportError: has_nxotmo = False else: has_nxotmo = True try: import sluurp except ImportError: has_sluurp = False else: has_sluurp = True _logger = logging.getLogger(__file__) MAX_LOG_FILE = 10 """Maximal log file kepts for orange""" LOG_FILE_NAME = "tomwer.log" LOG_FOLDER = "/var/log/tomwer" # These are the sequences need to get colored ouput _RESET_SEQ = "\033[0m" _BLACK = "\033[30m" _RED = "\033[31m" _GREEN = "\033[32m" _YELLOW = "\033[33m" _BLUE = "\033[34m" _MAGENTA = "\033[35m" LOG_COLORS = { "WARNING": _MAGENTA, "INFO": _BLACK, "DEBUG": _BLUE, "CRITICAL": _YELLOW, "ERROR": _RED, PROCESS_SKIPPED_NAME: _MAGENTA, PROCESS_ENDED_NAME: _BLACK, PROCESS_INFORM_NAME: _BLACK, PROCESS_STARTED_NAME: _BLACK, PROCESS_FAILED_NAME: _RED, PROCESS_SUCCEED_NAME: _GREEN, } class MainWindow(_MainWindow): HELPDESK_URL = "https://requests.esrf.fr/plugins/servlet/desk/portal/41" FORCE_OBJECT_SUPERVISOR_DISPLAY = True """If true will always display the processed supervisor at start up. Restore state will be ignored.""" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.process_supervisor_dock = DockWidget( self.tr("object supervisor"), self, objectName="processes-dock", allowedAreas=qt.Qt.BottomDockWidgetArea, visible=self.show_processes_manager_action.isChecked(), ) self.process_supervisor_dock.setWidget(ProcessManagerWindow(parent=None)) self.process_supervisor_dock.visibilityChanged[bool].connect( self.show_processes_manager_action.setChecked ) self.addDockWidget(qt.Qt.BottomDockWidgetArea, self.process_supervisor_dock) def restoreState(self, state, version=0): # for now we always want to display the process supervisor restored = super().restoreState(state=state, version=version) if self.FORCE_OBJECT_SUPERVISOR_DISPLAY: self.show_processes_manager_action.setChecked(True) self.process_supervisor_dock.setVisible(True) return restored def setup_actions(self): super().setup_actions() # create the action to connect with it self.show_processes_manager_action = qt.QAction( self.tr("&object supervisor"), self, toolTip=self.tr("Show object states relative to processes."), checkable=True, triggered=lambda checked: self.process_supervisor_dock.setVisible(checked), ) def setup_menu(self): super().setup_menu() self.view_menu.addAction(self.show_processes_manager_action) self.simple_example_action = qt.QAction( self.tr("simple use cases"), self, objectName="simple-use-cases", toolTip=self.tr("Some simple examples."), triggered=self.open_simple_examples, menuRole=qt.QAction.AboutRole, ) self.dark_flat_example_action = qt.QAction( self.tr("darks and flats manipulations"), self, objectName="dark-flat-manipulation", toolTip=self.tr("Examples around dark and flat."), triggered=self.open_dark_flat_examples, menuRole=qt.QAction.AboutRole, ) self.slurm_execution_example_action = qt.QAction( self.tr("remote processing with slurm"), self, objectName="execution-on-slurm", toolTip=self.tr("Examples of some execution over slurm."), triggered=self.open_slurm_execution_example, menuRole=qt.QAction.AboutRole, ) self.cor_search_example_action = qt.QAction( self.tr("cor search advance example"), self, objectName="cor-search-example", toolTip=self.tr("Examples of ways to search for the Center of rotation."), triggered=self.open_cor_search_example, menuRole=qt.QAction.AboutRole, ) self.python_script_example_action = qt.QAction( self.tr("python script examples"), self, objectName="python-script-example", toolTip=self.tr("Examples of some python script usage."), triggered=self.open_python_script_example, menuRole=qt.QAction.AboutRole, ) self.python_script_example_action = qt.QAction( self.tr("ID16b examples"), self, objectName="id16b-example", toolTip=self.tr("ID16b use case."), triggered=self.open_id16b_example, menuRole=qt.QAction.AboutRole, ) # Predefined workflows menu. self.predefined_workflows_menu = qt.QMenu( self.tr("&Examples"), self.menuBar(), objectName="examples-menu", ) self.predefined_workflows_menu.addActions( [ self.simple_example_action, self.cor_search_example_action, self.dark_flat_example_action, self.slurm_execution_example_action, self.python_script_example_action, ] ) self.menuBar().addMenu(self.predefined_workflows_menu) self._helpdeskButton = qt.QAction( self.tr("&Helpdesk"), self, objectName="helpdeskButton", triggered=self._contactUs, toolTip="contact esrf data processing helpdesk if you have some troubles with the application", ) self.menuBar().addAction(self._helpdeskButton) def _contactUs(self, *args, **kwargs): try: qt.QDesktopServices.openUrl(qt.QUrl(self.HELPDESK_URL)) except Exception as e: _logger.error( f"Failed to launch helpdesk web page ({self.HELPDESK_URL}). Error is {e}" ) def __open_examples(self, examples, filter_names=None): """ filter the existing tutorials by names contained in the file name """ items = [previewmodel.PreviewItem(path=t.abspath()) for t in examples] def my_filter(value): for filter_name in filter_names: if filter_name in value: return True return False if filter_names is not None: items = filter( lambda item: my_filter(os.path.basename(item.path())), items, ) dialog = previewdialog.PreviewDialog(self) model = previewmodel.PreviewModel(dialog, items=items) title = self.tr("Example Workflows") dialog.setWindowTitle(title) template = '

\n' "{0}\n" "

" dialog.setHeading(template.format(title)) dialog.setModel(model) model.delayedScanUpdate() status = dialog.exec() index = dialog.currentIndex() dialog.deleteLater() if status == qt.QDialog.Accepted: selected = model.item(index) self.open_example_scheme(selected.path()) return status def open_about(self): dlg = AboutDialog(self) dlg.setAttribute(qt.Qt.WA_DeleteOnClose) dlg.exec() def open_simple_examples(self): return self.__open_examples( orange_examples.workflows(), filter_names=("simple", "EBS_tomo_listener") ) def open_slurm_execution_example(self): return self.__open_examples( orange_examples.workflows(), filter_names=("slurm",) ) def open_dark_flat_examples(self): return self.__open_examples( orange_examples.workflows(), filter_names=("darks",) ) def open_python_script_example(self): return self.__open_examples( orange_examples.workflows(), filter_names=("_script",) ) def open_id16b_example(self): return self.__open_examples( orange_examples.workflows(), filter_names=("ID16b",) ) def open_cor_search_example(self): return self.__open_examples( orange_examples.workflows(), filter_names=("find_cor", "cor_search") ) log = logging.getLogger(__name__) def check_for_updates() -> bool: return False def send_usage_statistics() -> bool: return False def pull_notifications() -> bool: return False def make_sql_logger(level=logging.INFO): sql_log = logging.getLogger("sql_log") sql_log.setLevel(level) handler = RotatingFileHandler( os.path.join(config.log_dir(), "sql.log"), maxBytes=1e7, backupCount=2 ) sql_log.addHandler(handler) class _OMain(ocMain): DefaultConfig = "tomwer.app.canvas_launcher.launcher.TomwerConfig" def run(self, argv): # Allow termination with CTRL + C signal.signal(signal.SIGINT, signal.SIG_DFL) # Disable pyqtgraph's atexit and QApplication.aboutToQuit cleanup handlers. pyqtgraph.setConfigOption("exitCleanup", False) super().run(argv) def argument_parser(self) -> argparse.ArgumentParser: parser = super().argument_parser() parser.add_argument( "--use-opengl-plot", "--opengl-backend", help="Use OpenGL for plots (instead of matplotlib)", action="store_true", default=False, ) return parser def parse_arguments(self, argv: list[str]): super().parse_arguments(argv) # define silx plot backend. For now the si;pler is to # define an environment variable. # this way we should also be able to let the user define it # on it's own later... if self.options.use_opengl_plot: # other standalones are not passing by the silx.config # but for the canvas this is way simpler to use it. # then all plot which have backend==None will pick the default plot backend silx.config.DEFAULT_PLOT_BACKEND = "gl" else: silx.config.DEFAULT_PLOT_BACKEND = "matplotlib" def setup_logging(self): level = self.options.log_level logformat = "%(asctime)s:%(levelname)s:%(name)s: %(message)s" # File handler should always be at least INFO level so we need # the application root level to be at least at INFO. root_level = min(level, logging.INFO) rootlogger = logging.getLogger() rootlogger.setLevel(root_level) # Standard output stream handler at the requested level if sys.platform in ("linux", "linux2", "darwin"): stream_hander = make_linux_stream_colored_handler( level, fileobj=self.__stderr__ ) else: stream_hander = make_stream_handler( level, fileobj=self.__stderr__, fmt=logformat ) rootlogger.addHandler(stream_hander) # Setup log capture for MainWindow/Log log_stream = TextStream(objectName="-log-stream") self.output.connectStream(log_stream) self.stack.push(closing(log_stream)) # close on exit log_handler = make_stream_handler(level, fileobj=log_stream, fmt=logformat) rootlogger.addHandler(log_handler) # Also log to file file_handler = make_file_handler( root_level, os.path.join(config.log_dir(), "canvas.log"), mode="w", ) rootlogger.addHandler(file_handler) make_sql_logger(self.options.log_level) def setup_application(self): super().setup_application() # NOTE: No OWWidgetBase subclass should be imported before this self._update_check = check_for_updates() self._send_stat = send_usage_statistics() self._pull_notifs = pull_notifications() settings = qt.QSettings() settings.setValue( "startup/launch-count", settings.value("startup/launch-count", 0, int) + 1, ) UsageStatistics.set_enabled(False) def show_splash_message(self, message: str, color=qt.QColor("#FFD39F")): super().show_splash_message(message, color) def create_main_window(self): window = MainWindow() return window def setup_sys_redirections(self): super().setup_sys_redirections() if isinstance(sys.excepthook, ExceptHook): sys.excepthook.handledException.connect(handle_exception) def tear_down_sys_redirections(self): if isinstance(sys.excepthook, ExceptHook): sys.excepthook.handledException.disconnect(handle_exception) super().tear_down_sys_redirections() def splash_screen(self): """Return the application splash screen""" settings = qt.QSettings() options = self.options want_splash = ( settings.value("startup/show-splash-screen", True, type=bool) and not options.no_splash ) if want_splash: pm, rect = self.config.splash_screen() splash_screen = TomwerSplashScreen(pixmap=pm, textRect=rect) splash_screen.setAttribute(qt.Qt.WA_DeleteOnClose) splash_screen.setFont(qt.QFont("Helvetica", 12)) palette = splash_screen.palette() color = qt.QColor("#b3baba") palette.setColor(qt.QPalette.Text, color) splash_screen.setPalette(palette) else: splash_screen = None return splash_screen def data_dir(): return os.path.join(data_dir_base(), "tomwer", tomwer.version.version) def widget_settings_dir(): return os.path.join(data_dir(), "widgets") ABOUT_TEMPLATE = """\

{name}

tomwer version: {tomwer_version}

nabu version: {nabu_version}

nxtomo version: {nxtomo_version}

nxtomomill version: {nxtomomill_version}

tomoscan version: {tomoscan_version}

ewokscore version: {ewokscore_version}

ewoksorange version: {ewoksorange_version}

sluurp version: {sluurp_version}

""" class AboutDialog(qt.QDialog): def __init__(self, parent=None, **kwargs) -> None: super().__init__(parent, **kwargs) layout = qt.QVBoxLayout() label = qt.QLabel(self) pixmap, _ = TomwerConfig.splash_screen() pixmap = pixmap.scaled(150, 150) label.setPixmap(pixmap) layout.addWidget(label, qt.Qt.AlignCenter) text = ABOUT_TEMPLATE.format( name=escape("tomwer"), tomwer_version=escape(tomwer.version.version), nabu_version=escape(nabu.version if has_nabu else "not installed"), nxtomomill_version=escape( nxtomomill.version.version if has_nxtomomill else "not installed" ), nxtomo_version=escape( nxtomo.__version__ if has_nxotmo else "not installed" ), tomoscan_version=escape(tomoscan.version.version), sluurp_version=escape( sluurp.__version__ if has_sluurp else "not installed" ), ewokscore_version=escape( pkg_resources.get_distribution("ewokscore").version ), ewoksorange_version=escape( pkg_resources.get_distribution("ewoksorange").version ), ) text_label = qt.QLabel(text) layout.addWidget(text_label, qt.Qt.AlignCenter) buttons = qt.QDialogButtonBox(qt.QDialogButtonBox.Close, qt.Qt.Horizontal, self) layout.addWidget(buttons) buttons.rejected.connect(self.accept) layout.setSizeConstraint(qt.QVBoxLayout.SetFixedSize) self.setLayout(layout) class OMain(_OMain): config: TomwerConfig DefaultConfig = "tomwer.app.canvas_launcher.config.TomwerConfig" def run(self, argv): log.info("Clearing widget settings") shutil.rmtree(widget_settings_dir(), ignore_errors=True) dealWithLogFile() super().run(argv) def setup_application(self): qt.QLocale.setDefault(qt.QLocale(qt.QLocale.English)) return super().setup_application() def setup_logging(self): super().setup_logging() # rootlogger = logging.getLogger() # rootlogger = TomwerLogger(rootlogger) # logging.setLoggerClass(TomwerLogger) def setup_sys_redirections(self): self.output = doc = TerminalTextDocument() stdout = TextStream(objectName="-stdout") stderr = TextStream(objectName="-stderr") doc.connectStream(stdout) doc.connectStream(stderr, color=qt.Qt.red) if sys.stdout is not None: stdout.stream.connect(sys.stdout.write, qt.Qt.DirectConnection) self.__stdout__ = sys.stdout sys.stdout = stdout if sys.stderr is not None: stderr.stream.connect(sys.stderr.write, qt.Qt.DirectConnection) self.__stderr__ = sys.stderr sys.stderr = stderr self.__excepthook__ = sys.excepthook sys.excepthook = ExceptHook(stream=stderr) self.stack.push(closing(stdout)) self.stack.push(closing(stderr)) def argument_parser(self) -> argparse.ArgumentParser: parser = super().argument_parser() for action in parser._actions: # avoid clearing settings because this make people confused if action.dest == "clear_widget_settings": parser._remove_action(action) break # by default log are only displaying errors. But we want to get warning as well (for deprecation for example). if action.dest == "log_level": action.default = logging.WARNING parser.add_argument( "--no-color-stdout-logs", "--no-colored-logs", action="store_true", help="instead of having logs in the log view, color logs of the stdout", default=False, ) return parser def create_main_window(self): window = MainWindow() return window def dealWithLogFile(): """Move log file history across log file hierarchy and create the new log file""" # move log file if exists for i in range(MAX_LOG_FILE): logFile = LOG_FILE_NAME if os.path.exists(LOG_FOLDER) and os.access(LOG_FOLDER, os.W_OK): logFile = os.path.join(LOG_FOLDER, logFile) defLogName = logFile iLog = MAX_LOG_FILE - i maxLogNameN1 = logFile + "." + str(iLog) if iLog - 1 == 0: maxLogNameN2 = defLogName else: maxLogNameN2 = logFile + "." + str(iLog - 1) if os.path.exists(maxLogNameN2): try: stat = os.stat(maxLogNameN2) shutil.copy(maxLogNameN2, maxLogNameN1) os.utime(maxLogNameN1, (stat.st_atime, stat.st_mtime)) except Exception: pass # create a new log file if os.path.exists(LOG_FOLDER) and os.access(LOG_FOLDER, os.W_OK): logFile = os.path.join(LOG_FOLDER, logFile) logging.basicConfig( filename=logFile, filemode="w", level=logging.WARNING, format="%(asctime)s %(message)s", ) class _ColoredFormatter(logging.Formatter): """Dedicated colors to highlight level name by coloring logs (only for linux terminals)""" @staticmethod def color_formatting(message: str, levelname: str, ascii_time): """colors message using ascii""" return ( f"{ascii_time} {LOG_COLORS[levelname]}[{levelname}]{_RESET_SEQ} {message}" ) def format(self, record): record.asctime = self.formatTime(record, "%Y-%m-%d %H:%M:%S") record.message = record.getMessage() return self.color_formatting( message=record.message, levelname=record.levelname, ascii_time=record.asctime, ) def make_linux_stream_colored_handler(level, fileobj=None): handler = logging.StreamHandler(fileobj) handler.setLevel(level) formatter = _ColoredFormatter() handler.setFormatter(formatter) return handler def make_stream_handler(level, fileobj=None, fmt=None): handler = logging.StreamHandler(fileobj) handler.setLevel(level) if fmt: handler.setFormatter(logging.Formatter(fmt)) return handler def make_file_handler(level, filename, mode="w", fmt=None): handler = logging.FileHandler(filename, mode=mode, encoding="utf-8") handler.setLevel(level) if fmt: handler.setFormatter(logging.Formatter(fmt)) return handler ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/app/canvas_launcher/splash.py0000644000175000017500000000077414757047403022130 0ustar00paynopaynofrom silx.gui import qt from tomwer.gui import icons def splash_screen(): """ :return: splash screen for orange-canvas :note: QRect is used by orange to define a mask to display the message. In our case we overwrite the QSplashScreen so we don't need this. """ pixmap = icons.getQPixmap("tomwer") return pixmap, qt.QRect(0, 0, 400, 400) def getIcon(): """ :return: application icon """ pixmap = icons.getQPixmap("tomwer") return qt.QIcon(pixmap) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/app/canvas_launcher/utils.py0000644000175000017500000000237615153325210021760 0ustar00paynopaynofrom __future__ import annotations from importlib.metadata import version as get_version import tomoscan.version import ewokscore import ewoksorange import tomwer.version import sluurp try: import nxtomomill.version except ImportError: has_nxtomomill = False else: has_nxtomomill = True try: import nabu except ImportError: has_nabu = False else: has_nabu = True try: import nxtomo.version except ImportError: has_nxtomo = False else: has_nxtomo = True def get_tomotools_stack_versions() -> dict[str, str]: """Return the version of the main libraries used by tomwer""" stack = { "tomwer": tomwer.version.version, } if has_nabu: stack["nabu"] = nabu.version if has_nxtomo: stack["nxtomo"] = nxtomo.version.version if has_nxtomomill: stack["nxtomomill"] = nxtomomill.version.version stack["tomoscan"] = tomoscan.version.version try: stack["ewokscore"] = ewokscore.__version__ except AttributeError: stack["ewokscore"] = get_version("ewokscore") try: stack["ewoksorange"] = ewoksorange.__version__ except AttributeError: stack["ewoksorange"] = get_version("ewoksorange") stack["sluurp"] = sluurp.__version__ return stack ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/app/canvas_launcher/widgetsscheme.py0000644000175000017500000000527015153325210023447 0ustar00paynopaynofrom orangecanvas.scheme import Scheme from orangewidget.settings import SettingsPrinter from orangewidget.workflow.widgetsscheme import WidgetManager from orangewidget.workflow.widgetsscheme import ( WidgetsSignalManager as _WidgetsSignalManager, ) from silx.gui import qt class WidgetsSignalManager(_WidgetsSignalManager): # skip signal compresion done in original orange version def compress_signals(self, signals): return signals class WidgetsScheme(Scheme): def __init__(self, parent=None, title=None, description=None, env={}, **kwargs): super().__init__(parent, title, description, env=env, **kwargs) self.widget_manager = WidgetManager() self.signal_manager = WidgetsSignalManager(self) self.widget_manager.set_scheme(self) self.__report_view = None self.set_loop_flags(self.AllowLoops) def widget_for_node(self, node): """ Return the OWBaseWidget instance for a `node`. """ return self.widget_manager.widget_for_node(node) def node_for_widget(self, widget): """ Return the SchemeNode instance for the `widget`. """ return self.widget_manager.node_for_widget(widget) def sync_node_properties(self): """ Sync the widget settings/properties with the SchemeNode.properties. Return True if there were any changes in the properties (i.e. if the new node.properties differ from the old value) and False otherwise. """ changed = False for node in self.nodes: settings = self.widget_manager.widget_settings_for_node(node) if settings != node.properties: node.properties = settings changed = True return changed def show_report_view(self): return def has_report(self) -> bool: """ Does this workflow have an associated report """ return self.__report_view is not None def report_view(self): """ Return a OWReport instance used by the workflow. :return: report """ return None def set_report_view(self, view): """ Set the designated OWReport view for this workflow. :param view: """ self.__report_view = None def dump_settings(self, node): widget = self.widget_for_node(node) pp = SettingsPrinter(indent=4) pp.pprint(widget.settingsHandler.pack_data(widget)) def event(self, event): if event.type() == qt.QEvent.Close: if self.__report_view is not None: self.__report_view.close() self.signal_manager.stop() return super().event(event) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/app/darkref.py0000644000175000017500000000042415153325210017072 0ustar00paynopaynofrom tomwer.core.utils.deprecation import deprecated_warning deprecated_warning( "module", name="tomwer.app.darkref", reason="Has been moved", replacement="tomwer.app.reducedarkflat", only_once=True, ) from tomwer.app.reducedarkflat import * # noqa F401 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/app/darkrefpatch.py0000644000175000017500000000043515153325210020114 0ustar00paynopaynofrom tomwer.core.utils.deprecation import deprecated_warning deprecated_warning( "module", name="tomwer.app.darkrefpatch", reason="Has been moved", replacement="tomwer.app.patchrawdarkflat", only_once=True, ) from tomwer.app.patchrawdarkflat import * # noqa F401 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/app/diffframe.py0000644000175000017500000000627115143647637017430 0ustar00paynopayno#!/usr/bin/env python # -*- coding: utf-8 -*- """Application to display the difference between two frames.""" import argparse import logging import signal import sys import silx from silx.gui import qt from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils.resource import increase_max_number_file from tomwer.gui import icons from tomwer.gui.utils.splashscreen import getMainSplashScreen from tomwer.gui.visualization.diffviewer import DiffFrameViewer logging.basicConfig(level=logging.WARNING) _logger = logging.getLogger(__name__) def getinputinfo(): return "tomwer nabu [scan_path]" def sigintHandler(*args): """Handler for the SIGINT signal.""" qt.QApplication.closeAllWindows() # needed because get a waiting thread behind qt.QApplication.quit() def main(argv): import os parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "scan_path", help="Data file to show (h5 file, edf files, spec files)" ) parser.add_argument( "--entry", default=None, help="An entry should be specify for hdf5 files" ) parser.add_argument("--second-scan", default=None, help="Second data files") parser.add_argument("--second-entry", default=None, help="Second entry") parser.add_argument( "--use-opengl-plot", "--opengl-backend", help="Use OpenGL for plots (instead of matplotlib)", action="store_true", default=False, ) options = parser.parse_args(argv[1:]) options.scan_path = options.scan_path.rstrip(os.path.sep) if options.second_entry is not None and options.second_scan is None: options.second_scan = options.scan_path increase_max_number_file() app = qt.QApplication.instance() or qt.QApplication(["tomwer"]) qt.QLocale.setDefault(qt.QLocale(qt.QLocale.English)) qt.QLocale.setDefault(qt.QLocale.c()) signal.signal(signal.SIGINT, sigintHandler) sys.excepthook = qt.exceptionHandler timer = qt.QTimer() timer.start(500) # Application have to wake up Python interpreter, else SIGINT is not # catch timer.timeout.connect(lambda: None) splash = getMainSplashScreen() # create scan scan_1 = ScanFactory.create_scan_object(options.scan_path, entry=options.entry) if scan_1 is None: raise ValueError( "Given scan path is not recognized as a path" "containing a scan" ) if options.second_scan is not None: scan_2 = ScanFactory.create_scan_object( options.second_scan, entry=options.second_entry ) else: scan_2 = None if options.use_opengl_plot: silx.config.DEFAULT_PLOT_BACKEND = "gl" else: silx.config.DEFAULT_PLOT_BACKEND = "matplotlib" # handle gui widget = DiffFrameViewer(parent=None) widget.addScan(scan_1) if scan_2 is not None: widget.addScan(scan_2) widget.setRightScan(scan_2) # for the application we run for the reconstruction to be finished # to give back hand to the user widget.setWindowTitle("Frame diff") widget.setWindowIcon(icons.getQIcon("tomwer")) splash.finish(widget) widget.show() app.exec() if __name__ == "__main__": main(sys.argv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/app/imagekeyeditor.py0000644000175000017500000000562215153325210020463 0ustar00paynopayno#!/usr/bin/env python # -*- coding: utf-8 -*- """Application to edit (key by key) the 'imagekey' value of a NXtomo ('imagekey' defines if a frame is a 'dark', 'flat' or a 'projection')""" import argparse import logging import signal import sys from silx.gui import qt from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.utils.resource import increase_max_number_file from tomwer.core.process.edit.imagekeyeditor import ImageKeyEditorTask from tomwer.gui import icons from tomwer.gui.edit.imagekeyeditor import ImageKeyDialog as _ImageKeyDialog from tomwer.gui.utils.splashscreen import getMainSplashScreen logging.basicConfig(level=logging.WARNING) _logger = logging.getLogger(__name__) class ImageKeyDialog(_ImageKeyDialog): def __init__(self, *args, **kwargs): _ImageKeyDialog.__init__(self, *args, **kwargs) self._scan = None def setScan(self, scan): if not isinstance(scan, NXtomoScan): raise TypeError("This only manage NXtomoScan") self._scan = scan _ImageKeyDialog.setScan(self, scan) def _validateReleased(self): if not self._scan: raise ValueError("Scan should be set first") task = ImageKeyEditorTask( inputs={ "data": self._scan, "configuration": {"modifications": self.getModifications()}, } ) try: task.run() except Exception as e: _logger.error(e) else: print("edition succeed") def getinputinfo(): return "tomwer image-key-editor [scan_path] [entry]" def sigintHandler(*args): """Handler for the SIGINT signal.""" qt.QApplication.quit() def main(argv): import os parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("scan_path", help="HDF5File to edit") parser.add_argument("entry", default=None, help="Entry to treat") options = parser.parse_args(argv[1:]) # image key can only handle NXtomoScan for now scan = NXtomoScan(scan=options.scan_path, entry=options.entry) increase_max_number_file() app = qt.QApplication.instance() or qt.QApplication(["tomwer"]) qt.QLocale.setDefault(qt.QLocale(qt.QLocale.English)) qt.QLocale.setDefault(qt.QLocale.c()) signal.signal(signal.SIGINT, sigintHandler) sys.excepthook = qt.exceptionHandler timer = qt.QTimer() timer.start(500) # Application have to wake up Python interpreter, else SIGINT is not # catch timer.timeout.connect(lambda: None) splash = getMainSplashScreen() options.scan_path = options.scan_path.rstrip(os.path.sep) widget = ImageKeyDialog(parent=None) widget.setWindowFlags(qt.Qt.Window) widget.setScan(scan) widget.setWindowTitle("Image key editor") widget.setWindowIcon(icons.getQIcon("tomwer")) splash.finish(widget) widget.show() app.exec() if __name__ == "__main__": main(sys.argv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/app/imagekeyupgrader.py0000644000175000017500000000644215153325210021007 0ustar00paynopayno#!/usr/bin/env python # -*- coding: utf-8 -*- """Application to edit (group by group) the 'imagekey' value of a NXtomo ('imagekey' defines if a frame is a 'dark', 'flat' or a 'projection')""" import argparse import logging import signal import sys from silx.gui import qt from tomwer.core.process.edit.imagekeyeditor import ImageKeyUpgraderTask from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.utils.resource import increase_max_number_file from tomwer.gui import icons from tomwer.gui.edit.imagekeyeditor import ( ImageKeyUpgraderWidget as _ImageKeyUpgraderWidget, ) from tomwer.gui.utils.splashscreen import getMainSplashScreen logging.basicConfig(level=logging.WARNING) _logger = logging.getLogger(__name__) class ImageKeyUpgraderDialog(qt.QDialog): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._scan = None self.setLayout(qt.QVBoxLayout()) self._widget = _ImageKeyUpgraderWidget(self) self.layout().addWidget(self._widget) types = qt.QDialogButtonBox.Ok | qt.QDialogButtonBox.Cancel self._buttons = qt.QDialogButtonBox(self) self._buttons.setStandardButtons(types) self.layout().addWidget(self._buttons) # signal / slot connection self._buttons.button(qt.QDialogButtonBox.Ok).released.connect(self.validate) self._buttons.button(qt.QDialogButtonBox.Cancel).released.connect(self.close) def setScan(self, scan): if not isinstance(scan, NXtomoScan): raise TypeError("This only manage NXtomoScan") self._scan = scan def validate(self): operations = self._widget.getOperations() task = ImageKeyUpgraderTask( inputs={ "data": self._scan, "operations": operations, }, ) task.run() print("edition finished") self.close() def getinputinfo(): return "tomwer image-key-upgrader [scan_path] [entry]" def sigintHandler(*args): """Handler for the SIGINT signal.""" qt.QApplication.quit() def main(argv): import os parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("scan_path", help="NXtomo to edit") parser.add_argument("entry", default=None, help="Entry to treat") options = parser.parse_args(argv[1:]) # image key can only handle NXtomoScan for now scan = NXtomoScan(scan=options.scan_path, entry=options.entry) increase_max_number_file() app = qt.QApplication.instance() or qt.QApplication(["tomwer"]) qt.QLocale.setDefault(qt.QLocale(qt.QLocale.English)) qt.QLocale.setDefault(qt.QLocale.c()) signal.signal(signal.SIGINT, sigintHandler) sys.excepthook = qt.exceptionHandler timer = qt.QTimer() timer.start(500) # Application have to wake up Python interpreter, else SIGINT is not # catch timer.timeout.connect(lambda: None) splash = getMainSplashScreen() options.scan_path = options.scan_path.rstrip(os.path.sep) widget = ImageKeyUpgraderDialog(parent=None) widget.setWindowFlags(qt.Qt.Window) widget.setScan(scan) widget.setWindowTitle("Image key upgrader") widget.setWindowIcon(icons.getQIcon("tomwer")) splash.finish(widget) widget.show() app.exec() if __name__ == "__main__": main(sys.argv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/app/intensitynormalization.py0000644000175000017500000001355515153325210022322 0ustar00paynopayno#!/usr/bin/env python # -*- coding: utf-8 -*- import argparse import logging import os import signal import sys from silx.gui import qt from tomwer.core.process.reconstruction.normalization import SinoNormalizationTask from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.scanfactory import ScanFactory from tomwer.gui import icons from tomwer.gui.reconstruction.normalization.intensity import ( SinoNormWindow as _SinoNormWindow, ) from tomwer.gui.utils.splashscreen import getMainSplashScreen logging.basicConfig(level=logging.INFO) _logger = logging.getLogger(__name__) class IntensityNormalizationThread(qt.QThread): """ Thread to call the normalization process when needed (to avoid gui freeze) """ def __init__(self, *args, **kwargs): qt.QThread.__init__(self, *args, **kwargs) self._result = None @property def result(self): return self._result def init(self, data, configuration): if not isinstance(configuration, dict): raise TypeError("Configuration is expected to be a dict") if not isinstance(data, TomwerScanBase): raise TypeError("Scan is expected to be an instance of " "TomwerScanBase") self.scan = data self._configuration = configuration self._result = None def run(self) -> None: process = SinoNormalizationTask( process_id=None, inputs={ "data": self.scan, "configuration": self._configuration, "serialize_output_data": False, }, varinfo=None, ) process.run() self._result = self.scan.intensity_normalization.tomwer_processing_res class NormIntensityWindow(_SinoNormWindow): def __init__(self, parent=None): _SinoNormWindow.__init__(self, parent) self._processingThread = IntensityNormalizationThread() self._hideLockButton() # connect signal / slot self._optsWidget.sigProcessingRequested.connect(self._launchProcessing) self._processingThread.finished.connect(self._threadedProcessEnded) def _validated(self): self.close() def _launchProcessing(self): self.clear() if self._processingThread.isRunning(): _logger.error( "a calculation is already launch. You must wait for " "it to end prior to launch a new one" ) else: qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor) self._processingThread.init( data=self.getScan(), configuration=self.getConfiguration(), ) self._processingThread.start() def _threadedProcessEnded(self): qt.QApplication.restoreOverrideCursor() def close(self) -> None: self._stopProcessingThread() super().close() def _stopProcessingThread(self): if self._processingThread: self._processingThread.terminate() self._processingThread.wait(500) self._processingThread = None def stop(self): self._stopProcessingThread() super().stop() def main(argv): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "scan_path", help="For EDF acquisition: provide folder path, for HDF5 / nexus" "provide the master file", default=None, ) parser.add_argument( "entry", help="For Nexus files: entry in the master file", default=None, nargs="?", ) parser.add_argument( "--debug", dest="debug", action="store_true", default=False, help="Set logging system in debug mode", ) options = parser.parse_args(argv[1:]) if options.debug: logging.root.setLevel(logging.DEBUG) global app # QApplication must be global to avoid seg fault on quit app = qt.QApplication.instance() or qt.QApplication(["tomwer"]) splash = getMainSplashScreen() qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor) qt.QApplication.processEvents() qt.QLocale.setDefault(qt.QLocale(qt.QLocale.English)) qt.QLocale.setDefault(qt.QLocale.c()) signal.signal(signal.SIGINT, sigintHandler) sys.excepthook = qt.exceptionHandler timer = qt.QTimer() timer.start(500) # Application have to wake up Python interpreter, else SIGINT is not # catch timer.timeout.connect(lambda: None) if options.scan_path is not None: if os.path.isdir(options.scan_path): options.scan_path = options.scan_path.rstrip(os.path.sep) scan = ScanFactory.create_scan_object(scan_path=options.scan_path) else: if not os.path.isfile(options.scan_path): raise ValueError( "scan path should be a folder containing an" " EDF acquisition or an hdf5 - nexus " "compliant file" ) if options.entry is None: raise ValueError("entry in the master file should be specify") scan = NXtomoScan(scan=options.scan_path, entry=options.entry) else: scan = ScanFactory.mock_scan() # define the process_index is any tomwer_processes_existing if options.debug: _logger.setLevel(logging.DEBUG) window = NormIntensityWindow(parent=None) window.setWindowTitle("sinogram-norm-intensity") window.setWindowIcon(icons.getQIcon("tomwer")) window.setScan(scan) splash.finish(window) window.show() qt.QApplication.restoreOverrideCursor() app.aboutToQuit.connect(window.stop) app.exec() def getinputinfo(): return "tomwer intensity normalization [scanDir entry]" def sigintHandler(*args): """Handler for the SIGINT signal.""" qt.QApplication.quit() if __name__ == "__main__": main(sys.argv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/app/multicor.py0000644000175000017500000002166515153325210017324 0ustar00paynopayno#!/usr/bin/env python # -*- coding: utf-8 -*- """Application to reconstruct a slice for a set of center of rotation value. Interface to nabu multicor""" from __future__ import annotations import argparse import logging import signal import sys import time import os import silx from silx.gui import qt from tomwer.core.process.reconstruction.axis.axis import AxisTask, NoAxisUrl from tomwer.core.process.reconstruction.darkref.darkrefs import ( requires_reduced_dark_and_flat, ) from tomwer.core.process.reconstruction.saaxis.saaxis import SAAxisTask from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils.resource import increase_max_number_file from tomwer.gui import icons from tomwer.gui.reconstruction.saaxis.saaxis import SAAxisWindow as _SAAxisWindow from tomwer.gui.utils.splashscreen import getMainSplashScreen from tomwer.synctools.axis import QAxisRP from tomwer.synctools.saaxis import QSAAxisParams from tomoscan.esrf.scan.utils import cwd_context logging.basicConfig(level=logging.WARNING) _logger = logging.getLogger(__name__) class SAAxisThread(qt.QThread): """ Thread to call nabu and reconstruct one slice with several cor value """ def init(self, data, configuration, dump_roi): self.scan = data self._configuration = configuration self._dump_roi = dump_roi def run(self) -> None: process = SAAxisTask( process_id=None, inputs={ "data": self.scan, "sa_axis_params": self._configuration, "serialize_output_data": False, }, ) process.dump_roi = self._dump_roi t0 = time.time() process.run() print(f"execution time is {time.time() - t0}") class SAAxisWindow(_SAAxisWindow): def __init__(self, parent=None, dump_roi=False, backend=None): self._scan = None super().__init__(parent, backend=backend) # thread for computing cors self._processingThread = SAAxisThread() self._processingThread.finished.connect(self._threadedProcessEnded) self.sigStartSinogramLoad.connect(self._callbackStartLoadSinogram) self.sigEndSinogramLoad.connect(self._callbackEndLoadSinogram) self._dump_roi = dump_roi # hide the validate button self._saaxisControl._applyBut.hide() self.hideAutoFocusButton() def _launchReconstructions(self): if self._processingThread.isRunning(): _logger.error( "a calculation is already launch. You must wait for " "it to end prior to launch a new one" ) else: qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor) self._processingThread.init( configuration=self.getConfiguration(), data=self.getScan(), dump_roi=self._dump_roi, ) self._processingThread.start() def _threadedProcessEnded(self): saaxis_params = self._processingThread.scan.saaxis_params if saaxis_params is None: scores = None else: scores = saaxis_params.scores scan = self.getScan() assert scan is not None, "scan should have been set" self.setCorScores( scores, img_width=scan.dim_1, score_method=self.getScoreMethod() ) if scan.saaxis_params.autofocus is not None: self.setCurrentCorValue(scan.saaxis_params.autofocus) self.showResults() qt.QApplication.restoreOverrideCursor() def _callbackStartLoadSinogram(self): print(f"start loading sinogram for {self.getScan()}. Can take some time") def _callbackEndLoadSinogram(self): print(f"sinogram loaded for {self.getScan()} loaded.") def close(self) -> None: self._stopProcessingThread() super().close() def _stopProcessingThread(self): if self._processingThread: self._processingThread.terminate() self._processingThread.wait(500) self._processingThread = None def stop(self): self._stopProcessingThread() def _computeEstimatedCor(self) -> float | None: scan = self.getScan() if scan is None: return _cor_estimation_process = AxisTask( inputs={ "axis_params": self.getQAxisRP(), "data": scan, "serialize_output_data": False, } ) _logger.info(f"{scan} - start cor estimation for") qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor) try: _cor_estimation_process.compute(scan=scan, wait=True) except NoAxisUrl: qt.QApplication.restoreOverrideCursor() msg = qt.QMessageBox(self) msg.setIcon(qt.QMessageBox.Warning) text = ( "Unable to find url to compute the axis, please select them " "from the `axis input` tab" ) msg.setText(text) msg.exec() return None else: self.setEstimatedCorPosition( value=scan.axis_params.relative_cor_value, ) qt.QApplication.restoreOverrideCursor() self.getAutomaticCorWindow().hide() return scan.axis_params.relative_cor_value def setDumpScoreROI(self, dump): self._dump_score_roi = dump def main(argv): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "scan_path", help="For EDF acquisition: provide folder path, for HDF5 / nexus " "provide the master file", default=None, ) parser.add_argument( "--entry", help="For Nexus files: entry in the master file", default=None ) parser.add_argument( "--debug", dest="debug", action="store_true", default=False, help="Set logging system in debug mode", ) parser.add_argument( "--read-existing", dest="read_existing", action="store_true", default=False, help="Load latest sa-delta-beta processing from *_tomwer_processes.h5 " "if exists", ) parser.add_argument( "--dump-roi", dest="dump_roi", action="store_true", default=False, help="Save roi where the score is computed on the .hdf5", ) parser.add_argument( "--use-opengl-plot", "--opengl-backend", help="Use OpenGL for plots (instead of matplotlib)", action="store_true", default=False, ) options = parser.parse_args(argv[1:]) if options.debug: logging.root.setLevel(logging.DEBUG) increase_max_number_file() global app # QApplication must be global to avoid seg fault on quit app = qt.QApplication.instance() or qt.QApplication(["tomwer"]) splash = getMainSplashScreen() qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor) qt.QApplication.processEvents() qt.QLocale.setDefault(qt.QLocale(qt.QLocale.English)) qt.QLocale.setDefault(qt.QLocale.c()) signal.signal(signal.SIGINT, sigintHandler) sys.excepthook = qt.exceptionHandler timer = qt.QTimer() timer.start(500) # Application have to wake up Python interpreter, else SIGINT is not # catch timer.timeout.connect(lambda: None) # define the process_index is any tomwer_processes_existing if options.debug: _logger.setLevel(logging.DEBUG) scan = ScanFactory.create_scan_object( scan_path=os.path.abspath(options.scan_path), entry=options.entry ) requires_reduced_dark_and_flat(scan=scan, logger_=_logger) if options.use_opengl_plot: silx.config.DEFAULT_PLOT_BACKEND = "gl" else: silx.config.DEFAULT_PLOT_BACKEND = "matplotlib" with cwd_context(scan.working_directory): window = SAAxisWindow(dump_roi=options.dump_roi) window.setWindowTitle("saaxis") window.setWindowIcon(icons.getQIcon("tomwer")) if scan.axis_params is None: scan.axis_params = QAxisRP() if scan.saaxis_params is None: scan.saaxis_params = QSAAxisParams() # force load of reduced_flats and reduced_darks scan.reduced_flats scan.reduced_darks window.setScan(scan) window.setDumpScoreROI(options.dump_roi) if options.read_existing is True: scores, selected = SAAxisTask.load_results_from_disk(scan) if scores is not None: window.setCorScores(scores, score_method="standard deviation") if selected not in (None, "-"): window.setCurrentCorValue(selected) splash.finish(window) window.show() qt.QApplication.restoreOverrideCursor() app.aboutToQuit.connect(window.stop) exit(app.exec()) def getinputinfo(): return "tomwer saaxis [scanDir]" def sigintHandler(*args): """Handler for the SIGINT signal.""" qt.QApplication.quit() if __name__ == "__main__": main(sys.argv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/app/multipag.py0000644000175000017500000002775515153325210017316 0ustar00paynopayno#!/usr/bin/env python # -*- coding: utf-8 -*- """Application to reconstruct a slice with Paganin for a set of delta/beta values.""" from __future__ import annotations import argparse import logging import signal import sys import time import os import silx from silx.gui import qt from tomwer.core.process.reconstruction.axis.axis import AxisTask, NoAxisUrl from tomwer.core.process.reconstruction.darkref.darkrefs import ( requires_reduced_dark_and_flat, ) from tomwer.core.process.reconstruction.sadeltabeta.sadeltabeta import ( SADeltaBetaTask, ) from tomwer.core.process.reconstruction.utils.cor import ( relative_pos_to_absolute, absolute_pos_to_relative, ) from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils.resource import increase_max_number_file from tomwer.gui import icons from tomwer.gui.reconstruction.saaxis.saaxis import NabuAutoCorDiag from tomwer.gui.reconstruction.sadeltabeta.saadeltabeta import ( SADeltaBetaWindow as _SADeltaBetaWindow, ) from tomwer.gui.utils.splashscreen import getMainSplashScreen from tomwer.synctools.axis import QAxisRP from tomwer.synctools.sadeltabeta import QSADeltaBetaParams from tomoscan.esrf.scan.utils import cwd_context logging.basicConfig(level=logging.WARNING) _logger = logging.getLogger(__name__) class SADeltaBetaThread(qt.QThread): """ Thread to call nabu and reconstruct one slice with several cor value """ def init(self, data, configuration, dump_roi): self.scan = data self._configuration = configuration self._dump_roi = dump_roi def run(self) -> None: process = SADeltaBetaTask( process_id=None, inputs={ "scan": self.scan, "serialize_output_data": False, }, ) process.set_configuration(self._configuration) process.dump_roi = self._dump_roi t0 = time.time() process.run() print(f"execution time is {time.time() - t0}") class SADeltaBetaWindow(_SADeltaBetaWindow): def __init__(self, parent=None, dump_roi=False, backend=None): self._scan = None super().__init__(parent, backend=backend) self._insert_cor_gui() # thread for computing cors self._processingThread = SADeltaBetaThread() self._processingThread.finished.connect(self._threadedProcessEnded) # thread to compute the COR self._dump_roi = dump_roi # hide the validate button self._sadbControl._applyBut.hide() self.hideAutoFocusButton() def _insert_cor_gui(self): self._imageWidth = None self._automaticCorWidget = None self._qaxis_rp = QAxisRP() # dialog used to compute automatically the cor widget = self._tabWidget._deltaBetaSelectionWidget self._corGB = qt.QGroupBox(self) self._corGB.setTitle("center of rotation") self._corGB.setLayout(qt.QFormLayout()) # auto cor calculation self._autoPB = qt.QPushButton("auto", self) self._corGB.layout().addRow(self._autoPB) # relative position self._relativeCORValueQLE = qt.QDoubleSpinBox(self) self._relativeCORValueQLE.setRange(-99999999, 99999999) self._corGB.layout().addRow("cor relative position", self._relativeCORValueQLE) # absolute position self._absoluteCORValueQLE = qt.QDoubleSpinBox(self) self._corGB.layout().addRow("cor absolute position", self._absoluteCORValueQLE) self._absoluteCORValueQLE.setRange(0, 99999999) widget.layout().insertWidget(2, self._corGB) # connect signal / slot self._relativeCORValueQLE.editingFinished.connect(self._relativeValueEdited) self._absoluteCORValueQLE.editingFinished.connect(self._absolueValueEdited) self._autoPB.pressed.connect(self._autoCorRequested) def _autoCorRequested(self): window = self.getAutomaticCorWindow() window.activateWindow() window.raise_() window.show() def getAutomaticCorWindow(self): if self._automaticCorWidget is None: self._automaticCorWidget = NabuAutoCorDiag(self, qarixrp=self._qaxis_rp) self._automaticCorWidget.setWindowTitle( "compute estimated center of rotation" ) auto_cor_icon = icons.getQIcon("a") self._automaticCorWidget.setWindowIcon(auto_cor_icon) self._automaticCorWidget.sigRequestAutoCor.connect( self._computeEstimatedCor ) return self._automaticCorWidget def setScan(self, scan): self._imageWidth = scan.dim_1 # force update of the cor value self._relativeCORValueQLE.editingFinished.emit() super().setScan(scan=scan) def _relativeValueEdited(self): old = self._absoluteCORValueQLE.blockSignals(True) value = relative_pos_to_absolute( relative_pos=self._relativeCORValueQLE.value(), det_width=self._imageWidth ) self._absoluteCORValueQLE.setValue(value) self._absoluteCORValueQLE.blockSignals(old) def _absoluteValueEdited(self): old = self._relativeCORValueQLE.blockSignals(True) value = absolute_pos_to_relative( absolute_pos=self._absoluteCORValueQLE.value(), det_width=self._imageWidth ) self._relativeCORValueQLE.setValue(value) self._relativeCORValueQLE.blockSignals(old) def setRelativeCorPosition(self, value): self._relativeCORValueQLE.setValue(value) self._relativeCORValueQLE.editingFinished.emit() def getAbsoluteCorPosition(self): return self._absoluteCORValueQLE.value() def _launchReconstructions(self): if self._processingThread.isRunning(): _logger.error( "a calculation is already launch. You must wait for " "it to end prior to launch a new one" ) else: qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor) self._processingThread.init( configuration=self.getConfiguration(), data=self.getScan(), dump_roi=self._dump_roi, ) self._processingThread.start() def getConfiguration(self) -> dict: config = super().getConfiguration() # insert rotation_axis_position if "reconstruction" not in config["nabu_params"]: config["nabu_params"]["reconstruction"] = {} config["nabu_params"]["reconstruction"][ "rotation_axis_position" ] = self.getAbsoluteCorPosition() return config def _threadedProcessEnded(self): sa_delta_beta_params = self._processingThread.scan.sa_delta_beta_params if sa_delta_beta_params is None: scores = None else: scores = sa_delta_beta_params.scores scan = self.getScan() assert scan is not None, "scan should have been set" self.setDBScores( scores, img_width=scan.dim_1, score_method=self.getScoreMethod() ) if scan.sa_delta_beta_params.autofocus is not None: self.setCurrentDeltaBetaValue(scan.sa_delta_beta_params.autofocus) qt.QApplication.restoreOverrideCursor() self.showResults() def _stopProcessingThread(self): if self._processingThread: self._processingThread.terminate() self._processingThread.wait(500) self._processingThread = None def stop(self): self._stopProcessingThread() def _computeEstimatedCor(self) -> float | None: scan = self.getScan() if scan is None: return _cor_estimation_process = AxisTask( inputs={ "data": scan, "axis_params": self._qaxis_rp, "serialize_output_data": False, } ) _logger.info(f"{scan} - start cor estimation for") qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor) try: _cor_estimation_process.compute(scan=scan, wait=True) except NoAxisUrl: qt.QApplication.restoreOverrideCursor() msg = qt.QMessageBox(self) msg.setIcon(qt.QMessageBox.Warning) text = ( "Unable to find url to compute the axis, please select them " "from the `axis input` tab" ) msg.setText(text) msg.exec() return None else: self.setRelativeCorPosition( value=scan.axis_params.relative_cor_value, ) qt.QApplication.restoreOverrideCursor() self.getAutomaticCorWindow().hide() return scan.axis_params.relative_cor_value def main(argv): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "scan_path", help="For EDF acquisition: provide folder path, for HDF5 / nexus " "provide the master file", default=None, ) parser.add_argument( "--entry", help="For Nexus files: entry in the master file", default=None, ) parser.add_argument( "--debug", dest="debug", action="store_true", default=False, help="Set logging system in debug mode", ) parser.add_argument( "--read-existing", dest="read_existing", action="store_true", default=False, help="Load latest sa-delta-beta processing from *_tomwer_processes.h5 " "if exists", ) parser.add_argument( "--dump-roi", dest="dump_roi", action="store_true", default=False, help="Save roi where the score is computed on the .hdf5", ) parser.add_argument( "--use-opengl-plot", "--opengl-backend", help="Use OpenGL for plots (instead of matplotlib)", action="store_true", default=False, ) options = parser.parse_args(argv[1:]) if options.debug: logging.root.setLevel(logging.DEBUG) if options.use_opengl_plot: silx.config.DEFAULT_PLOT_BACKEND = "gl" else: silx.config.DEFAULT_PLOT_BACKEND = "matplotlib" increase_max_number_file() scan = ScanFactory.create_scan_object( scan_path=os.path.abspath(options.scan_path), entry=options.entry ) requires_reduced_dark_and_flat(scan=scan, logger_=_logger) global app # QApplication must be global to avoid seg fault on quit app = qt.QApplication.instance() or qt.QApplication([]) splash = getMainSplashScreen() qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor) qt.QApplication.processEvents() qt.QLocale.setDefault(qt.QLocale(qt.QLocale.English)) qt.QLocale.setDefault(qt.QLocale.c()) signal.signal(signal.SIGINT, sigintHandler) sys.excepthook = qt.exceptionHandler timer = qt.QTimer() timer.start(500) # Application have to wake up Python interpreter, else SIGINT is not # catch timer.timeout.connect(lambda: None) with cwd_context(scan.working_directory): window = SADeltaBetaWindow(dump_roi=options.dump_roi) window.setWindowTitle("sa-delta-beta") window.setWindowIcon(icons.getQIcon("tomwer")) if ( not hasattr(scan, "sa_delta_beta_params") or scan.sa_delta_beta_params is None ): scan.sa_delta_beta_params = QSADeltaBetaParams() window.setScan(scan) if options.read_existing is True: scores, selected = SADeltaBetaTask.load_results_from_disk(scan) if scores is not None: window.setDBScores(scores, score_method="standard deviation") if selected not in (None, "-"): window.setCurrentDeltaBetaValue(selected) splash.finish(window) window.show() qt.QApplication.restoreOverrideCursor() app.aboutToQuit.connect(window.stop) app.exec() def getinputinfo(): return "tomwer saaxis [scanDir]" def sigintHandler(*args): """Handler for the SIGINT signal.""" qt.QApplication.quit() if __name__ == "__main__": main(sys.argv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/app/nabuapp.py0000644000175000017500000001700715153325210017107 0ustar00paynopayno#!/usr/bin/env python # -*- coding: utf-8 -*- """Application to reconstruct a slice with nabu""" import argparse import logging import signal import sys from silx.gui import qt from tomwer.core.process.reconstruction.nabu.nabuslices import run_slices_reconstruction from tomwer.core.process.reconstruction.utils.cor import relative_pos_to_absolute from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils.resource import increase_max_number_file from tomwer.gui import icons from tomwer.gui.reconstruction.nabu.slices import NabuDialog from tomwer.gui.utils.splashscreen import getMainSplashScreen from tomwer.gui.visualization.dataviewer import DataViewer as _DataViewer logging.basicConfig(level=logging.WARNING) _logger = logging.getLogger(__name__) def getinputinfo(): return "tomwer nabu [scan_path]" def sigintHandler(*args): """Handler for the SIGINT signal.""" qt.QApplication.quit() class DataViewer(_DataViewer): """The data viewer with an update when F5 is press""" closed = qt.Signal() """signal emitted when the widget is closing""" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setAttribute(qt.Qt.WA_DeleteOnClose) def keyPressEvent(self, event): if event.key() is qt.Qt.Key_F5: self._updateDisplay() class NabuProcessingThread(qt.QThread): def init(self, data, config, dry_run=False): self._scan = data self._config = config self._dry_run = dry_run def run(self): run_slices_reconstruction( scan=self._scan, config=self._config, dry_run=self._dry_run ) class _CORWidget(qt.QWidget): def __init__(self, parent=None): qt.QWidget.__init__(self, parent) self.setLayout(qt.QHBoxLayout()) self.layout().addWidget(qt.QLabel("center of rotation", self)) self._corCN = qt.QCheckBox("auto", self) self.layout().addWidget(self._corCN) self._corQLE = qt.QLineEdit("0", self) self._corQLE.setValidator(qt.QDoubleValidator(self)) self.layout().addWidget(self._corQLE) self._corQLE.setToolTip("Value should be in -width/2, width/2") # set up self._corCN.setChecked(True) self._corQLE.setEnabled(False) # connect signal / slot self._corCN.toggled.connect(self._corQLE.setDisabled) def getCOR(self): if self._corCN.isChecked(): return "auto" else: return float(self._corQLE.text()) class NabuWindow(NabuDialog): def __init__(self, parent=None): NabuDialog.__init__(self, parent) self.setWindowFlags(qt.Qt.Widget) self.setAttribute(qt.Qt.WA_DeleteOnClose) self.__scan = None self.__processingThread = NabuProcessingThread() self._dry_run = False # add center of rotation widget self._corWidget = _CORWidget(parent=self) rw = ( self._widget._mainWidget._nabuSettingsWidget._configuration._reconstructionWidget ) rw.layout().addWidget(self._corWidget, 99, 0, 1, 2) self._dataViewer = None self.setModal(False) # add view button self._showPB = qt.QPushButton("show scan", self) self._buttons.addButton(self._showPB, qt.QDialogButtonBox.ActionRole) # connect signal / slot self._computePB.released.connect(self._requireComputation) self._showPB.released.connect(self._showScan) # export API self.getCOR = self._corWidget.getCOR def _showScan(self): self._getDataViewer().setScan(self.__scan) self._getDataViewer().show() self._getDataViewer().raise_() def _getDataViewer(self): if self._dataViewer is None: self._dataViewer = DataViewer(parent=None) self._dataViewer.closed.connect(self._viewerDeleted) return self._dataViewer def _viewerDeleted(self): self._dataViewer = None def setScan(self, scan): self.__scan = scan NabuDialog.setScan(self, scan) def getScan(self): return self.__scan def getConfiguration(self): config = super().getConfiguration() cor = self.getCOR() if cor != "auto": # move the cor value to the nabu reference cor = relative_pos_to_absolute( relative_pos=cor, det_width=self.__scan.dim_1 ) config["reconstruction"]["rotation_axis_position"] = str(cor) return config def _requireComputation(self, *arg, **kwargs): _logger.info("start computation") scan = self.getScan() if scan is not None: qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor) self._launchComputation(scan=scan, config=self.getConfiguration()) def _computationEnded(self): _logger.info("end computation") qt.QApplication.restoreOverrideCursor() if self._dataViewer is not None: self._dataViewer.setScan(self.__scan) def getProcessingThread(self): return self.__processingThread def _launchComputation(self, scan, config): # update the processing thread thread = self.getProcessingThread() thread.init(data=scan, config=config, dry_run=self._dry_run) thread.finished.connect(self._computationEnded) # start processing thread.start(priority=qt.QThread.LowPriority) def set_dry_run(self, dry_run): self._dry_run = dry_run def close(self): super().close() if self._dataViewer is not None: self._dataViewer.close() self._dataViewer = None def main(argv): import os parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "scan_path", help="Data file to show (h5 file, edf files, spec files)" ) parser.add_argument( "--entry", default=None, help="An entry should be specify for hdf5 files" ) parser.add_argument( "--output-dir", help="output directory of the reconstruction(s)" ) parser.add_argument( "--debug", dest="debug", action="store_true", default=False, help="Set logging system in debug mode", ) parser.add_argument( "--dry-run", dest="dry_run", action="store_true", default=False, help="Only create the .nabu file and print the configuration used", ) options = parser.parse_args(argv[1:]) increase_max_number_file() app = qt.QApplication.instance() or qt.QApplication(["tomwer"]) qt.QLocale.setDefault(qt.QLocale(qt.QLocale.English)) qt.QLocale.setDefault(qt.QLocale.c()) signal.signal(signal.SIGINT, sigintHandler) sys.excepthook = qt.exceptionHandler timer = qt.QTimer() timer.start(500) # Application have to wake up Python interpreter, else SIGINT is not # catch timer.timeout.connect(lambda: None) splash = getMainSplashScreen() options.scan_path = options.scan_path.rstrip(os.path.sep) scan = ScanFactory.create_scan_object(options.scan_path, entry=options.entry) widget = NabuWindow(parent=None) widget.setScan(scan) if options.output_dir is not None: widget.setOutputDir(options.output_dir) # for the application we run for the reconstruction to be finished # to give back hand to the user widget.set_dry_run(options.dry_run) widget.setWindowTitle("Nabu reconstruction") widget.setWindowIcon(icons.getQIcon("tomwer")) splash.finish(widget) widget.show() app.exec() if __name__ == "__main__": main(sys.argv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/app/nxtomoeditor.py0000644000175000017500000000570315153325210020214 0ustar00paynopayno#!/usr/bin/env python # -*- coding: utf-8 -*- """Application to edit several entries of a NXtomo""" import argparse import logging import signal import sys from silx.gui import qt from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.process.edit.nxtomoeditor import NXtomoEditorTask from tomwer.gui.edit.nxtomoeditor import NXtomoEditorDialog as _NXtomoEditorDialog from tomwer.gui.utils.splashscreen import getMainSplashScreen logging.basicConfig(level=logging.WARNING) _logger = logging.getLogger(__name__) class NXtomoEditorDialog(_NXtomoEditorDialog): def __init__(self) -> None: super().__init__() # connect signal / slot self._buttons.button(qt.QDialogButtonBox.Ok).released.connect(self._triggerTask) def getScan(self): return self.mainWidget.getScan() def _triggerTask(self, *args, **kwargs): task = NXtomoEditorTask( inputs={ "data": self.getScan(), "configuration": self.getConfigurationForTask(), } ) task.run() print("edition finished") def main(argv): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("scan_path", help="nexus file (HDF5 file) to edit.") parser.add_argument( "entry", help="path to the file where starts the NXtomo. Usually named 'entry', or 'entryXXXX'", ) parser.add_argument( "--debug", dest="debug", action="store_true", default=False, help="Set logging system in debug mode", ) options = parser.parse_args(argv[1:]) if options.debug: logging.root.setLevel(logging.DEBUG) global app # QApplication must be global to avoid seg fault on quit app = qt.QApplication.instance() or qt.QApplication([]) splash = getMainSplashScreen() qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor) app.processEvents() qt.QLocale.setDefault(qt.QLocale(qt.QLocale.English)) qt.QLocale.setDefault(qt.QLocale.c()) signal.signal(signal.SIGINT, sigintHandler) sys.excepthook = qt.exceptionHandler timer = qt.QTimer() timer.start(500) # Application have to wake up Python interpreter, else SIGINT is not # catch timer.timeout.connect(lambda: None) try: scan = ScanFactory.create_scan_object( scan_path=options.scan_path, entry=options.entry ) except Exception as e: _logger.error( f"Fail to find a NXtomo from {options.scan_path} at {options.entry}. Error is {e}" ) return dialog = NXtomoEditorDialog() dialog.setWindowFlags(qt.Qt.Window) dialog.setScan(scan) dialog.show() splash.finish(dialog) qt.QApplication.restoreOverrideCursor() app.exec() def getinputinfo(): return "tomwer nxtomo-editor [scanDir]" def sigintHandler(*args): """Handler for the SIGINT signal.""" qt.QApplication.quit() if __name__ == "__main__": main(sys.argv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/app/patchrawdarkflat.py0000644000175000017500000000730215153325210021000 0ustar00paynopayno#!/usr/bin/env python # -*- coding: utf-8 -*- """Application to append dark of flat frames to an existing NXtomo""" import argparse import logging import signal import sys from nxtomomill.utils import add_dark_flat_nx_file from silx.gui import qt from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils.resource import increase_max_number_file from tomwer.gui import icons from tomwer.gui.edit.dkrfpatch import DarkRefPatchWidget from tomwer.gui.utils.splashscreen import getMainSplashScreen logging.basicConfig(level=logging.WARNING) _logger = logging.getLogger(__name__) class _DarkRefPatchDialog(qt.QDialog): def __init__(self, parent): qt.QDialog.__init__(self, parent) self._scan = None self.setLayout(qt.QVBoxLayout()) self._mainWidget = DarkRefPatchWidget(self) self.layout().addWidget(self._mainWidget) # buttons types = qt.QDialogButtonBox.Ok self._buttons = qt.QDialogButtonBox(parent=self) self._buttons.setStandardButtons(types) self._buttons.button(qt.QDialogButtonBox.Ok).setText("Apply") self.layout().addWidget(self._buttons) # connect signal slot self._buttons.button(qt.QDialogButtonBox.Ok).clicked.connect(self._apply) def _apply(self): if self._scan is None: raise ValueError("Scan should be set before applying patch") url_sd = self._mainWidget.getStartDarkUrl() url_sf = self._mainWidget.getStartFlatUrl() url_ed = self._mainWidget.getEndDarkUrl() url_ef = self._mainWidget.getEndFlatUrl() add_dark_flat_nx_file( file_path=self._scan.master_file, entry=self._scan.entry, darks_start=url_sd, flats_start=url_sf, darks_end=url_ed, flats_end=url_ef, ) def setScan(self, scan): self._scan = scan def main(argv): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "scan_path", help="HDF5 - Nexus file path", default=None, ) parser.add_argument("entry", help="NXTomo entry to load", default=None) parser.add_argument( "--debug", dest="debug", action="store_true", default=False, help="Set logging system in debug mode", ) options = parser.parse_args(argv[1:]) if options.debug: logging.root.setLevel(logging.DEBUG) increase_max_number_file() global app # QApplication must be global to avoid seg fault on quit app = qt.QApplication.instance() or qt.QApplication(["tomwer"]) splash = getMainSplashScreen() qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor) qt.QApplication.processEvents() qt.QLocale.setDefault(qt.QLocale(qt.QLocale.English)) qt.QLocale.setDefault(qt.QLocale.c()) signal.signal(signal.SIGINT, sigintHandler) sys.excepthook = qt.exceptionHandler timer = qt.QTimer() timer.start(500) # Application have to wake up Python interpreter, else SIGINT is not # catch timer.timeout.connect(lambda: None) scan = ScanFactory.create_scan_object( scan_path=options.scan_path, entry=options.entry ) if options.debug: _logger.setLevel(logging.DEBUG) window = _DarkRefPatchDialog(parent=None) window.setScan(scan=scan) window.setWindowTitle("patch dark & flat") window.setWindowIcon(icons.getQIcon("tomwer")) splash.finish(window) window.show() qt.QApplication.restoreOverrideCursor() app.exec() def getinputinfo(): return "tomwer darkref-patch [scanDir]" def sigintHandler(*args): """Handler for the SIGINT signal.""" qt.QApplication.quit() if __name__ == "__main__": main(sys.argv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/app/radiostack.py0000644000175000017500000000515415143647637017630 0ustar00paynopayno#!/usr/bin/env python # -*- coding: utf-8 -*- """Application to display scan radios as a stack""" import argparse import logging import os import signal import sys import silx from silx.gui import qt from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.utils.resource import increase_max_number_file from tomwer.gui import icons from tomwer.gui.stacks import RadioStack from tomwer.gui.utils.splashscreen import getMainSplashScreen logging.basicConfig(level=logging.WARNING) _logger = logging.getLogger(__name__) def getinputinfo(): return "tomwer radio-stack [scanName]" def addFolderAndSubFolder(stack, path): stack.addLeafScan(path) for f in os.listdir(path): _path = os.path.join(path, f) if os.path.isdir(_path) is True: addFolderAndSubFolder(stack, _path) elif os.path.isfile(_path) and NXtomoScan.is_nexus_nxtomo_file(_path): stack.addLeafScan(_path) def sigintHandler(*args): """Handler for the SIGINT signal.""" qt.QApplication.quit() def main(argv): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "root_dir", help="Root dir to browse and to extract all radio under it." ) parser.add_argument( "--use-opengl-plot", "--opengl-backend", help="Use OpenGL for plots (instead of matplotlib)", action="store_true", default=False, ) parser.add_argument( "--debug", dest="debug", action="store_true", default=False, help="Set logging system in debug mode", ) increase_max_number_file() options = parser.parse_args(argv[1:]) if options.use_opengl_plot: silx.config.DEFAULT_PLOT_BACKEND = "gl" else: silx.config.DEFAULT_PLOT_BACKEND = "matplotlib" global app # QApplication must be global to avoid seg fault on quit app = qt.QApplication.instance() or qt.QApplication(["tomwer"]) qt.QLocale.setDefault(qt.QLocale(qt.QLocale.English)) qt.QLocale.setDefault(qt.QLocale.c()) signal.signal(signal.SIGINT, sigintHandler) sys.excepthook = qt.exceptionHandler timer = qt.QTimer() timer.start(500) # Application have to wake up Python interpreter, else SIGINT is not # cached timer.timeout.connect(lambda: None) splash = getMainSplashScreen() widget = RadioStack() widget.setWindowIcon(icons.getQIcon("tomwer")) options.root_dir = options.root_dir.rstrip(os.path.sep) addFolderAndSubFolder(stack=widget, path=options.root_dir) splash.finish(widget) widget.show() app.exec() if __name__ == "__main__": main(sys.argv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/app/reducedarkflat.py0000644000175000017500000001462515153325210020444 0ustar00paynopayno#!/usr/bin/env python # -*- coding: utf-8 -*- """Application to compute reduced darks and flats for a given scan""" import argparse import logging import signal import sys from silx.gui import qt from tomwer.core.process.reconstruction.darkref.darkrefs import DarkRefsTask from tomwer.core.process.reconstruction.darkref.params import DKRFRP, ReduceMethod from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils.resource import increase_max_number_file from tomwer.gui import icons from tomwer.gui.reconstruction.darkref.darkrefwidget import DarkRefWidget from tomwer.gui.utils.splashscreen import getMainSplashScreen from tomwer.synctools.darkref import QDKRFRP logging.basicConfig(level=logging.WARNING) _logger = logging.getLogger(__name__) def getinputinfo(): return "tomwer darkref [scanDir]" def _exec_without_interaction(scan, dark_method, flat_method, overwrite): recons_params = DKRFRP() recons_params.overwrite_dark = overwrite recons_params.overwrite_ref = overwrite recons_params.dark_calc_method = dark_method recons_params.flat_calc_method = flat_method dark_ref = DarkRefsTask( inputs={ "data": scan, "dark_ref_params": recons_params, "serialize_output_data": False, } ) _logger.info(f"Start processing of {scan}") dark_ref.run() _logger.info(f"End processing of {scan}") return 0 def _exec_with_interaction(scan, dark_method, flat_method, overwrite): class ProcessingThread(qt.QThread): """ Thread used to run the processing """ def __init__(self, inputs: dict) -> None: super().__init__() self._inputs = inputs def run(self): process = DarkRefsTask(inputs=self._inputs) process.run() class _DarkRefWidgetRunnable(DarkRefWidget): sigScanReady = qt.Signal(str) """emit when scan ready""" def __init__(self, scan, parent=None): self.__scan = scan self.__darkref_rp = QDKRFRP() DarkRefWidget.__init__(self, parent=parent, reconsparams=self.__darkref_rp) buttonExec = qt.QPushButton("execute", parent=self) buttonExec.setAutoDefault(True) # needed to be used as an application to return end only when the # processing thread is needed self._forceSync = True self.layout().addWidget(buttonExec) buttonExec.pressed.connect(self._process) self.setWindowIcon(icons.getQIcon("tomwer")) self._processingThread = None def _notifyEnd(self, *args, **kwargs): self._processingThread.finished.disconnect(self._notifyEnd) print(f"computation of {self.__scan} reduced dark and flat done.") self._processingThread = None def _process(self): if self._processingThread is not None: print("processing already on-going...") else: self._processingThread = ProcessingThread( inputs={ "data": self.__scan, "dark_ref_params": self.__darkref_rp, "force_sync": self._forceSync, } ) self._processingThread.finished.connect(self._notifyEnd) print(f"start reducing dark and flat of {self.__scan} ...") self._processingThread.start() def sigintHandler(*args): """Handler for the SIGINT signal.""" qt.QApplication.quit() global app # QApplication must be global to avoid seg fault on quit app = qt.QApplication.instance() or qt.QApplication(["tomwer"]) qt.QLocale.setDefault(qt.QLocale(qt.QLocale.English)) qt.QLocale.setDefault(qt.QLocale.c()) signal.signal(signal.SIGINT, sigintHandler) sys.excepthook = qt.exceptionHandler timer = qt.QTimer() timer.start(500) # Application have to wake up Python interpreter, else SIGINT is not # catched timer.timeout.connect(lambda: None) splash = getMainSplashScreen() widget = _DarkRefWidgetRunnable(scan) # set up widget.recons_params.overwrite_dark = overwrite widget.recons_params.overwrite_flat = overwrite widget.recons_params.dark_calc_method = dark_method widget.recons_params.flat_calc_method = flat_method splash.finish(widget) widget.show() return app.exec() def main(argv): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "scan_path", help="Data file to show (h5 file, edf files, spec files)" ) parser.add_argument( "--entry", help="an entry can be specify in case of hdf5 the master file", default=None, ) parser.add_argument( "--dark-method", help="Define the method to be used for computing dark", default=ReduceMethod.MEAN, ) parser.add_argument( "--flat-method", help="Define the method to be used for computing flat", default=ReduceMethod.MEDIAN, ) parser.add_argument( "--no-gui", help="Will run directly the dark and ref without any interaction", dest="run", action="store_true", default=False, ) parser.add_argument( "--overwrite", dest="overwrite", action="store_true", default=False, help="Overwrite dark/flats if exists", ) parser.add_argument( "--debug", dest="debug", action="store_true", default=False, help="Set logging system in debug mode", ) options = parser.parse_args(argv[1:]) if options.debug: logging.root.setLevel(logging.DEBUG) increase_max_number_file() scan = ScanFactory.create_scan_object(options.scan_path, entry=options.entry) dark_method = ReduceMethod(options.dark_method) flat_method = ReduceMethod(options.flat_method) if options.run: exit( _exec_without_interaction( scan=scan, dark_method=dark_method, flat_method=flat_method, overwrite=options.overwrite, ) ) else: exit( _exec_with_interaction( scan=scan, dark_method=dark_method, flat_method=flat_method, overwrite=options.overwrite, ) ) if __name__ == "__main__": main(sys.argv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/app/rsync.py0000644000175000017500000000776115153325210016625 0ustar00paynopayno#!/usr/bin/env python # -*- coding: utf-8 -*- import argparse import glob import logging import os import shutil import sys from tomwer.core.scan.scanfactory import ScanFactory from tomwer.synctools.utils.scanstages import ScanStages logging.basicConfig(level=logging.WARNING) logger = logging.getLogger(__name__) def getinputinfo(): return "tomwer rsync [source_dir] [dest_dir] [options]" def main(argv): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "source_dir", help="folder containing the acquisition to copy." "To copy /dir_path/scan_dir into /dir_path2/scan_dir source-dir " "should be /dir_path/scan_dir", ) parser.add_argument( "dest_dir", help="destination folder. If doesn't exists will create it." "Will synchronize" "If exists and contains some files, those won't be remove" "except if the --fresh option is activated" "To copy /dir_path/scan_dir into /dir_path2/scan_dir dest-dir " "should be /dir_path2", ) parser.add_argument( "--advancement", help="An acquisition contains several steps (initialization, " "acquisition, complete...). You can ask to synchronize file until" " a specific stage. \n" "For edf for example if you specify the stage `on_going` no .info" " while be created and the targeted directory won't contain " "any 'slice' files. \n" "Default value is `complete`" "Valid advancement values are: %s" % str(ScanStages.AcquisitionStage.get_command_names()), ) parser.add_argument( "--fresh", help="first file to be used for computing axis", action="store_true", default=False, ) parser.add_argument( "--force", "-f", help="force folder removal", action="store_true", default=False ) parser.add_argument( "--rm-final-xml", help="util option: remove the .xml created at the end of some .edf" "acquisition (which notify the end of the acquisition). \n" "Warning: this is an exclusive option. So it cannot be associated" "with any other option.", action="store_true", default=False, ) options = parser.parse_args(argv[1:]) if options.rm_final_xml is True and ( (options.advancement is not None) or (options.fresh is True) ): logger.error( "--rm-final-xml is an `exclusive`option. It cannot be" "associated with an other option" ) return if options.advancement is None and options.rm_final_xml is False: options.advancement = "complete" for scan_path in glob.glob(options.source_dir): try: scan = ScanFactory.create_scan_object(scan_path=scan_path) except ValueError: logger.error(scan_path + " is not containing a scan") continue dest_dir = os.path.join(options.dest_dir, os.path.basename(options.source_dir)) # fresh option treatment def refresh_dir(dir_): logger.info(f"recreate {dir_}") shutil.rmtree(dir_) os.makedirs(dir_) if options.rm_final_xml is True: final_xml = os.path.join(dest_dir, os.path.basename(dest_dir) + ".xml") if os.path.exists(final_xml): os.remove(final_xml) # if the xml option is created then other options are ignore continue if options.fresh and os.path.exists(dest_dir): if options.force is False: conf = input("do you want to remove %s (yes/y) ?" % dest_dir) if conf.lower() in ("yes", "y"): refresh_dir(dir_=dest_dir) else: refresh_dir(dir_=dest_dir) scan_stages = ScanStages(scan=scan) stage = ScanStages.AcquisitionStage.from_command_name(options.advancement) scan_stages.rsync_until(stage=stage, dest_dir=dest_dir) if __name__ == "__main__": main(sys.argv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/app/samplemoved.py0000644000175000017500000000515115143647637020015 0ustar00paynopayno#!/usr/bin/env python # -*- coding: utf-8 -*- """Application to display a couple of projections at 180 degree and estimate (by eye) if a sample has moved""" import argparse import logging import os import signal import sys import silx from silx.gui import qt from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils.resource import increase_max_number_file from tomwer.gui import icons from tomwer.gui.samplemoved import SampleMovedWidget from tomwer.gui.utils.splashscreen import getMainSplashScreen logging.basicConfig(level=logging.WARNING) _logger = logging.getLogger(__name__) def getinputinfo(): return "tomwer samplemoved [scanDir]" def sigintHandler(*args): """Handler for the SIGINT signal.""" qt.QApplication.quit() def main(argv): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "scan_path", help="Data file to show (h5 file, edf files, spec files)" ) parser.add_argument( "--debug", dest="debug", action="store_true", default=False, help="Set logging system in debug mode", ) parser.add_argument( "--entry", help="For Nexus files: entry in the master file", default=None, ) parser.add_argument( "--use-opengl-plot", "--opengl-backend", help="Use OpenGL for plots (instead of matplotlib)", action="store_true", default=False, ) options = parser.parse_args(argv[1:]) if options.use_opengl_plot: silx.config.DEFAULT_PLOT_BACKEND = "gl" else: silx.config.DEFAULT_PLOT_BACKEND = "matplotlib" increase_max_number_file() global app # QApplication must be global to avoid seg fault on quit app = qt.QApplication.instance() or qt.QApplication(["tomwer"]) qt.QLocale.setDefault(qt.QLocale(qt.QLocale.English)) qt.QLocale.setDefault(qt.QLocale.c()) signal.signal(signal.SIGINT, sigintHandler) sys.excepthook = qt.exceptionHandler timer = qt.QTimer() timer.start(500) # Application have to wake up Python interpreter, else SIGINT is not # catch timer.timeout.connect(lambda: None) splash = getMainSplashScreen() widget = SampleMovedWidget() widget.setWindowIcon(icons.getQIcon("tomwer")) options.scan_path = options.scan_path.rstrip(os.path.sep) scan = ScanFactory.create_scan_object(options.scan_path, options.entry) rawSlices = scan.get_proj_angle_url() widget.setImages(rawSlices) # TODO: set back the flat field correction splash.finish(widget) widget.show() app.exec() if __name__ == "__main__": main(sys.argv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/app/scanviewer.py0000644000175000017500000000533015143647637017646 0ustar00paynopayno#!/usr/bin/env python # -*- coding: utf-8 -*- """Application to browse a given scan""" import argparse import logging import signal import sys from silx.gui import qt from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils.resource import increase_max_number_file from tomwer.gui import icons from tomwer.gui.utils.splashscreen import getMainSplashScreen from tomwer.gui.visualization.dataviewer import DataViewer logging.basicConfig(level=logging.WARNING) _logger = logging.getLogger(__name__) def main(argv): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "scan_path", help="For EDF acquisition: provide folder path, for HDF5 / nexus " "provide the master file", default=None, ) parser.add_argument( "entry", help="For Nexus files: entry in the master file", default=None, nargs="?", ) parser.add_argument( "--use-opengl-plot", "--opengl-backend", help="Use OpenGL for plots (instead of matplotlib)", action="store_true", default=False, ) options = parser.parse_args(argv[1:]) scan = ScanFactory.create_scan_object( scan_path=options.scan_path, entry=options.entry ) import silx if options.use_opengl_plot: silx.config.DEFAULT_PLOT_BACKEND = "gl" else: silx.config.DEFAULT_PLOT_BACKEND = "matplotlib" increase_max_number_file() global app # QApplication must be global to avoid seg fault on quit app = qt.QApplication.instance() or qt.QApplication(["tomwer"]) splash = getMainSplashScreen() qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor) qt.QApplication.processEvents() qt.QLocale.setDefault(qt.QLocale(qt.QLocale.English)) qt.QLocale.setDefault(qt.QLocale.c()) signal.signal(signal.SIGINT, sigintHandler) sys.excepthook = qt.exceptionHandler timer = qt.QTimer() timer.start(500) # Application have to wake up Python interpreter, else SIGINT is not # catch timer.timeout.connect(lambda: None) window = DataViewer(parent=None) window.setDisplayMode("projections-radios") window.setWindowTitle("tomwer: scan-viewer") window.setWindowIcon(icons.getQIcon("tomwer")) window.setScan(scan) splash.finish(window) window.show() qt.QApplication.restoreOverrideCursor() app.aboutToQuit.connect(window.close) exit(app.exec()) def getinputinfo(): return "tomwer scan-viewer [file_path] [[file_entry]]" def sigintHandler(*args): """Handler for the SIGINT signal.""" qt.QApplication.closeAllWindows() # needed because get a waiting thread behind qt.QApplication.quit() if __name__ == "__main__": main(sys.argv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/app/sinogramviewer.py0000644000175000017500000000725415143647637020550 0ustar00paynopayno#!/usr/bin/env python # -*- coding: utf-8 -*- """Application to display a sinogram from a scan""" import argparse import logging import signal import sys import weakref import silx from silx.gui import qt from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils.resource import increase_max_number_file from tomwer.gui import icons from tomwer.gui.utils.splashscreen import getMainSplashScreen from tomwer.gui.visualization.sinogramviewer import SinogramViewer as _SinogramViewer logging.basicConfig(level=logging.WARNING) _logger = logging.getLogger(__name__) class SinogramViewer(_SinogramViewer): def setScan(self, scan): if self._scan is None or self._scan() != scan: self._scan = weakref.ref(scan) self._options.setScan(scan) def getinputinfo(): return "tomwer sinogram-viewer [scan_path --entry entry --line line --subsampling subsampling]" def sigintHandler(*args): """Handler for the SIGINT signal.""" qt.QApplication.closeAllWindows() # needed because get a waiting thread behind qt.QApplication.quit() def main(argv): import os parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "scan_path", help="path to the acquisition (folder for EDF, master file for HDF5)", ) parser.add_argument( "--entry", default=None, help="For HDF5 acquisition you should provide an entry if several" "acquisitions are contained in the master file", ) parser.add_argument( "--line", default=None, help="line to extract from radios to create the sinogram. Take the " "middle of projections by default", ) parser.add_argument( "--subsampling", default=1, help="You can define a subsampling to generate the sinogram in order" "to speed up creation", ) parser.add_argument( "--use-opengl-plot", "--opengl-backend", help="Use OpenGL for plots (instead of matplotlib)", action="store_true", default=False, ) options = parser.parse_args(argv[1:]) if options.use_opengl_plot: silx.config.DEFAULT_PLOT_BACKEND = "gl" else: silx.config.DEFAULT_PLOT_BACKEND = "matplotlib" scan = ScanFactory.create_scan_object(options.scan_path, entry=options.entry) increase_max_number_file() global app # QApplication must be global to avoid seg fault on quit app = qt.QApplication.instance() or qt.QApplication(["tomwer"]) qt.QLocale.setDefault(qt.QLocale(qt.QLocale.English)) qt.QLocale.setDefault(qt.QLocale.c()) signal.signal(signal.SIGINT, sigintHandler) sys.excepthook = qt.exceptionHandler timer = qt.QTimer() timer.start(500) # Application have to wake up Python interpreter, else SIGINT is not # catch timer.timeout.connect(lambda: None) splash = getMainSplashScreen() options.scan_path = options.scan_path.rstrip(os.path.sep) if options.subsampling < 1: raise ValueError("subsampling should be at least 1") if options.line is None: options.line = scan.dim_2 // 2 if options.line < 0: raise ValueError("Line value should be at least 0") if options.line > scan.dim_2: raise ValueError( f"Line value is outside frame dimension. Should be at most {scan.dim_2}" ) widget = SinogramViewer(parent=None) widget.setLine(options.line) widget.setSubsampling(options.subsampling) widget.setScan(scan) widget.setWindowTitle("Sinogram viewer") widget.setWindowIcon(icons.getQIcon("tomwer")) splash.finish(widget) widget.show() app.exec() if __name__ == "__main__": main(sys.argv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/app/slicestack.py0000644000175000017500000000464015143647637017630 0ustar00paynopayno#!/usr/bin/env python # -*- coding: utf-8 -*- """Application to display findable reconstructed slice of a scan (as a stack). reconstructed slices can be added by hand or as input(s) of the command line. """ import argparse import logging import signal import sys import os import silx from silx.gui import qt from tomwer.core.utils.resource import increase_max_number_file from tomwer.gui import icons from tomwer.gui.stacks import SliceStack from tomwer.gui.utils.splashscreen import getMainSplashScreen logging.basicConfig(level=logging.WARNING) _logger = logging.getLogger(__name__) def getinputinfo(): return "tomwer slice-stack [scanDir]" def sigintHandler(*args): """Handler for the SIGINT signal.""" qt.QApplication.quit() def main(argv): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "volume_paths", help="Volumes to be added to the slice stack visualization. Warning: volumes should be single slice volumes.", nargs="*", ) parser.add_argument( "--use-opengl-plot", "--opengl-backend", help="Use OpenGL for plots (instead of matplotlib)", action="store_true", default=False, ) parser.add_argument( "--debug", dest="debug", action="store_true", default=False, help="Set logging system in debug mode", ) options = parser.parse_args(argv[1:]) if options.use_opengl_plot: silx.config.DEFAULT_PLOT_BACKEND = "gl" else: silx.config.DEFAULT_PLOT_BACKEND = "matplotlib" increase_max_number_file() global app # QApplication must be global to avoid seg fault on quit app = qt.QApplication.instance() or qt.QApplication(["tomwer"]) qt.QLocale.setDefault(qt.QLocale(qt.QLocale.English)) qt.QLocale.setDefault(qt.QLocale.c()) signal.signal(signal.SIGINT, sigintHandler) sys.excepthook = qt.exceptionHandler timer = qt.QTimer() timer.start(500) # Application have to wake up Python interpreter, else SIGINT is not # catched timer.timeout.connect(lambda: None) splash = getMainSplashScreen() widget = SliceStack() widget.setWindowIcon(icons.getQIcon("tomwer")) widget._addTomoObjectsFromStrList( [os.path.abspath(volume_path) for volume_path in options.volume_paths] ) splash.finish(widget) widget.show() app.exec() if __name__ == "__main__": main(sys.argv) ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1772989186.913101 tomwer-1.6.17/src/tomwer/app/stitching/0000755000175000017500000000000015153325403017102 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/app/stitching/__init__.py0000644000175000017500000000000014757047403021213 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/app/stitching/common.py0000644000175000017500000006030515153325210020744 0ustar00paynopayno"""Common module for y and z stitcher""" from __future__ import annotations import os import argparse import logging import signal import sys import functools from tqdm import tqdm import silx from silx.gui import qt from silx.io.url import DataUrl from nabu.pipeline.config import generate_nabu_configfile from nabu.stitching.config import get_default_stitching_config, SECTIONS_COMMENTS from nabu.stitching.config import StitchingType from nabu.stitching.overlap import OverlapStitchingStrategy from tomwer.core.volume.volumefactory import VolumeFactory from tomwer.core.settings import SlurmSettingsMode from tomwer.core.utils.resource import increase_max_number_file from tomwer.gui import icons from tomwer.core.process.stitching.nabustitcher import StitcherTask from tomwer.io.utils.tomoobj import get_tomo_objs_instances from tomwer.gui.utils.splashscreen import getMainSplashScreen from tomwer.gui.stitching.StitchingWindow import ZStitchingWindow as _ZStitchingWindow from tomwer.gui.stitching.StitchingWindow import YStitchingWindow as _YStitchingWindow from tomwer.gui.stitching import action as stitching_action from tomwer.gui.cluster.slurm import SlurmSettingsWidget from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.volume import HDF5Volume from tomwer.core.volume import MultiTIFFVolume from tomwer.core.volume.volumebase import TomwerVolumeBase from tomwer.core.tomwer_object import TomwerObject class MainWidget(qt.QTabWidget): DEFAULT_NB_WORKERS = 10 def __init__( self, axis: int, parent=None, ) -> None: super().__init__(parent) if axis == 0: self._stitchingConfigWindow = _ZStitchingWindow( parent=self, with_configuration_action=False, ) elif axis == 1: self._stitchingConfigWindow = _YStitchingWindow( parent=self, with_configuration_action=False ) else: raise ValueError("stitching is only available along axis 0 and 1") self.addTab(self._stitchingConfigWindow, "stitching config") settingsClass = SlurmSettingsMode.get_settings_class( SlurmSettingsMode.STITCHING ) self._slurmConfig = SlurmSettingsWidget( parent=self, n_gpu=settingsClass.N_GPUS_PER_WORKER, jobLimitation=None ) self._slurmConfig.setConfiguration( { "cpu-per-task": settingsClass.N_CORES_PER_TASK, "n_tasks": settingsClass.N_TASKS, "n_jobs": settingsClass.N_JOBS, "memory": settingsClass.MEMORY_PER_WORKER, "partition": settingsClass.PARTITION, "n_gpus": settingsClass.N_GPUS_PER_WORKER, "job_name": settingsClass.PROJECT_NAME, "python_venv": settingsClass.PYTHON_VENV, } ) style = qt.QApplication.style() help_icon = style.standardIcon(qt.QStyle.SP_TitleBarContextHelpButton) self._helpButton = qt.QPushButton(help_icon, "help") self._slurmConfig.layout().addWidget( self._helpButton, 99, 0, qt.Qt.AlignLeft, qt.Qt.AlignTop ) self._stitchingConfigWindow.setCallbackToGetSlurmConfig( self._slurmConfig.getConfiguration ) self._stitchingConfigWindow.setCallbackToSetSlurmConfig( self._slurmConfig.setConfiguration ) self.addTab(self._slurmConfig, "slurm config") # add an option to clearly activate / deactivate slurm config slurm_config_idx = self.indexOf(self._slurmConfig) self._slurmCB = qt.QCheckBox(self) self.tabBar().setTabButton( slurm_config_idx, qt.QTabBar.LeftSide, self._slurmCB, ) self._slurmCB.setChecked(True) # set up self._slurmConfig.setNWorkers(self.DEFAULT_NB_WORKERS) # connect signal / slot self._helpButton.released.connect(self._showSlurmSettingHelpForStitching) def close(self): self._stitchingConfigWindow.close() # requested for the waiting plot update super().close() def keyPressEvent(self, event): """ To shortcut orange and make sure the `F5` <=> refresh stitching preview """ modifiers = event.modifiers() key = event.key() if key == qt.Qt.Key_F5: self._stitchingConfigWindow._trigger_update_preview() elif key == qt.Qt.Key_O and modifiers == qt.Qt.KeyboardModifier.ControlModifier: self._stitchingConfigWindow._loadSettings() elif key == qt.Qt.Key_S and modifiers == qt.Qt.KeyboardModifier.ControlModifier: self._stitchingConfigWindow._saveSettings() def getStitchingConfiguration(self) -> dict: return self._stitchingConfigWindow.getConfiguration() def getClusterConfig(self) -> dict: return self._slurmConfig.getConfiguration() def _showSlurmSettingHelpForStitching(self): msg = qt.QMessageBox() msg.setWindowTitle("Help") msg.setText(""" Stitching Process Hints:
  • Processing Mode: Stitching is performed using CPU only (GPU acceleration is not supported).
  • Memory Management:
    • Stitching is processed in chunks, based on available memory.
    • At least one slice from each element must be loaded into memory at all times.
  • Job Parallelization:
    • The stitching task is split into n parallel jobs (where n = number of jobs).
    • For optimal performance, we recommend each job processes a "reasonable" data size (e.g., 30 GB to 100 GB).
See application documentation and stitching tutorial for more details. """) msg.setIcon(qt.QMessageBox.Information) msg.exec() # expose API def addTomoObj(self, *args, **kwargs): self._stitchingConfigWindow.addTomoObj(*args, **kwargs) def setStitchingType(self, stitching_type): self._stitchingConfigWindow.setStitchingType(stitching_type) def getStitchingType(self): return self._stitchingConfigWindow.getStitchingType() def loadSettings(self, config_file): self._stitchingConfigWindow._loadSettings(config_file) def get_available_pre_processing_stitching_mode(self): return self._stitchingConfigWindow.get_available_pre_processing_stitching_mode() def get_available_post_processing_stitching_mode(self): return ( self._stitchingConfigWindow.get_available_post_processing_stitching_mode() ) def getTomoObjs(self): return self._stitchingConfigWindow.getTomoObjs() class _StitcherThread(qt.QThread): DEFAULT_OUTPUT_CONFIG_NAME = "stitching_conf_autosave.conf" def __init__(self, parent, stitching_config, cluster_config) -> None: super().__init__(parent) assert isinstance(stitching_config, dict) assert isinstance(cluster_config, dict) self._stitching_config = stitching_config self._cluster_config = cluster_config def save_configuration(self): stitching_type = self._stitching_config["stitching"]["type"] if "preproc" in stitching_type: output_file = self._stitching_config.get("preproc", {}).get("location", "") output_folder = os.path.dirname(output_file) else: output_volume = self._stitching_config.get("postproc", {}).get( "output_volume", None ) if output_volume is None: output_folder = "" else: volume = VolumeFactory.create_tomo_object_from_identifier(output_volume) output_folder = os.path.dirname(volume.data_url.file_path()) os.makedirs(output_folder, exist_ok=True) generate_nabu_configfile( fname=os.path.join( output_folder, _StitcherThread.DEFAULT_OUTPUT_CONFIG_NAME, ), default_config=get_default_stitching_config( self._stitching_config["stitching"]["type"] ), comments=True, sections_comments=SECTIONS_COMMENTS, options_level="advanced", prefilled_values=self._stitching_config, ) def run(self): self.save_configuration() task = StitcherTask( inputs={ "stitching_config": self._stitching_config, "cluster_config": self._cluster_config, "progress": tqdm(desc="stitching"), "serialize_output_data": False, }, ) task.run() print("stitching finished") class MainWindow(qt.QDialog): sigTomoObjAdded = qt.Signal(TomwerObject) def __init__(self, axis: int, parent=None) -> None: super().__init__(parent) self.setLayout(qt.QVBoxLayout()) # menu self._menuBar = qt.QMenuBar(self) self.layout().addWidget(self._menuBar) self._menu = qt.QMenu("&Stitching") self._menuBar.addMenu(self._menu) # save / load configuration self._loadConfigurationAction = stitching_action.LoadConfigurationAction( self, "&Load configuration" ) self._menu.addAction(self._loadConfigurationAction) self._saveConfigurationAction = stitching_action.SaveConfigurationAction( self, "&Save configuration" ) self._menu.addAction(self._saveConfigurationAction) # separator self._menu.addSeparator() # add tomo object self._addTomoObjectAction = stitching_action.AddTomoObjectAction( self, "&Add tomo object (volume or NXtomo)" ) self._menu.addAction(self._addTomoObjectAction) # main window self.setWindowTitle("tomwer z-stitching") self._mainWindow = MainWidget(parent=self, axis=axis) self.layout().addWidget(self._mainWindow) # button types = qt.QDialogButtonBox.Apply self._buttons = qt.QDialogButtonBox(self) self._buttons.setStandardButtons(types) self.layout().addWidget(self._buttons) self._buttons.button(qt.QDialogButtonBox.Apply).setText("Launch stitching") # set up self._mainWindow._stitchingConfigWindow.setPreProcessingOutput( NXtomoScan( scan=os.path.join(os.getcwd(), "stitching", "stitched.nx"), entry="entry0000", ) .get_identifier() .to_str() ) self._mainWindow._stitchingConfigWindow.setPostProcessingOutput( HDF5Volume( file_path=os.path.join( os.getcwd(), "stitching", "stitched_volume.hdf5" ), data_path="stitched_volume", ) .get_identifier() .to_str() ) # connect signal / slot self._buttons.button(qt.QDialogButtonBox.Apply).clicked.connect(self.accept) self._loadConfigurationAction.triggered.connect( functools.partial( self._mainWindow._stitchingConfigWindow._loadSettings, file_path=None ) ) self._saveConfigurationAction.triggered.connect( functools.partial( self._mainWindow._stitchingConfigWindow._saveSettings, file_path=None ) ) self._addTomoObjectAction.triggered.connect(self._callbackAddTomoObj) def _callbackAddTomoObj(self, *args, **kwargs): """move interface to the z-ordered list and call the 'add tomo obj' callback""" orderedListWidget = ( self._mainWindow._stitchingConfigWindow._widget._mainWidget._axisOrderedList ) self._mainWindow._stitchingConfigWindow._widget._mainWidget.setCurrentWidget( orderedListWidget ) tomo_objs = orderedListWidget._callbackAddTomoObj() for tomo_obj in tomo_objs: if len(tomo_objs) > 0: self.__updateStitchingTypeFromObjAdded(tomo_obj=tomo_objs[0]) def __updateStitchingTypeFromObjAdded(self, tomo_obj: TomwerObject): if isinstance(tomo_obj, TomwerScanBase): self.setStitchingType(self.get_available_pre_processing_stitching_mode()[0]) elif isinstance(tomo_obj, TomwerVolumeBase): self.setStitchingType( self.get_available_post_processing_stitching_mode()[0] ) else: raise TypeError( f"tomo_obj is expected to be an instance of {type(TomwerObject)}. Got {type(tomo_obj)}" ) def close(self): self._mainWindow.close() # requested for the waiting plot update super().close() def reject(self): self.close() super().reject() @classmethod def can_write_to_folder(cls, folder_path): if not os.path.exists(folder_path): parent_dir = os.path.dirname(folder_path) if ( not parent_dir ): # If folder_path is just a filename in the current directory parent_dir = os.getcwd() return cls.can_write_to_folder(parent_dir) return os.access(folder_path, os.W_OK) def __checkOutputDirWritable(self) -> bool: """Make sure the output directory is writable""" error = None config = self.getStitchingConfiguration() stitching_type = self.getStitchingType() if stitching_type in (StitchingType.Y_PREPROC, StitchingType.Z_PREPROC): output_file = config.get("preproc", {}).get("location", "") output_dir, _ = os.path.split(output_file) elif stitching_type in (StitchingType.Z_POSTPROC,): output_volume_identifier = config.get("postproc", {}).get( "output_volume", None ) if output_volume_identifier: output_volume = VolumeFactory.create_tomo_object_from_identifier( output_volume_identifier ) if isinstance(output_volume, (HDF5Volume, MultiTIFFVolume)): output_dir = os.path.dirname(output_volume.data_url.file_path()) else: output_dir = output_volume.data_url.file_path() else: output_dir = None error = "No output file/directory defined." else: raise ValueError(f"stitching type {stitching_type!r} not handled.") if output_dir is not None: if not self.can_write_to_folder(output_dir): error = f"No write rights on {output_dir!r}. Unable to save stitching." config.get("preproc") if error is None: return True error_dialog = qt.QMessageBox() error_dialog.setIcon(qt.QMessageBox.Warning) error_dialog.setWindowTitle("Error - cannot process") error_dialog.setText(error) error_dialog.setInformativeText("Please check your input and try again.") error_dialog.exec() return False def __checkStitchingModeSeemsValid(self) -> bool: """ Check whether the requested stitching mode matches the input data (pre-processing or post-processing). If not, warn the user and block processing. """ warning = None tomo_objs = self._mainWindow.getTomoObjs() stitching_type = self.getStitchingType() if len(tomo_objs) == 0: warning = "No object to be stitched together." else: scans = tuple( filter( lambda obj: isinstance(obj, TomwerScanBase), tomo_objs, ) ) volumes = tuple( filter( lambda obj: isinstance(obj, TomwerVolumeBase), tomo_objs, ) ) if len(scans) > 0 and len(volumes) > 0: warning = "Both scans and volumes to be stitched have been found. It should be one or the other. Processing will fail." elif stitching_type in (StitchingType.Y_PREPROC, StitchingType.Z_PREPROC): if len(scans) == 0: warning = f"No scans found but {stitching_type.value!r} requested. Maybe you want to stitch reconstructed volumes instead of scans ? If so please select 'stitching method' to one of the 'postproc' mode." elif stitching_type in (StitchingType.Z_POSTPROC,): if len(volumes) == 0: warning = f"No volumes found but {stitching_type.value!r} requested. Maybe you want to stitch scans instead of volumes ? If so please select 'stitching method' to one of the 'preproc' mode." else: raise NotImplementedError( f"No consistency check is available for stitching type: {stitching_type.value}!)" ) if warning is None: return True error_dialog = qt.QMessageBox() error_dialog.setIcon(qt.QMessageBox.Warning) error_dialog.setWindowTitle("Error - cannot process") error_dialog.setText(warning) error_dialog.setInformativeText("Please check your input and try again.") error_dialog.exec() return False def accept(self): if self.__checkStitchingModeSeemsValid() and self.__checkOutputDirWritable(): self.process_stitching() def process_stitching(self): self._processingThread = _StitcherThread( parent=self, stitching_config=self.getStitchingConfiguration(), cluster_config=self.getClusterConfig(), ) self._processingThread.start() def disableSlurmconfig(self): self._mainWindow._slurmCB.setChecked(False) self._mainWindow._slurmCB.setCheckable(False) slurm_config_idx = self._mainWindow.indexOf(self._mainWindow._slurmConfig) self._mainWindow.setTabEnabled( slurm_config_idx, False, ) self._mainWindow.setTabToolTip( slurm_config_idx, "not available because unable to find slurm command (computer is probably not a slurm client ?", ) # expose API def addTomoObj(self, *args, **kwargs): self._mainWindow.addTomoObj(*args, **kwargs) def getTomoObjs(self): return self._mainWindow._stitchingConfigWindow.getTomoObjs() def getClusterConfig(self) -> dict: if self._mainWindow._slurmCB.isChecked(): return self._mainWindow.getClusterConfig() else: return {} def getStitchingConfiguration(self) -> dict: return self._mainWindow.getStitchingConfiguration() def setStitchingType(self, stitching_type): self._mainWindow.setStitchingType(stitching_type) def getStitchingType(self): return self._mainWindow.getStitchingType() def loadSettings(self, config_file: str): self._mainWindow.loadSettings(config_file) def setPreProcessingOutput(self, url: DataUrl) -> None: self._mainWindow._stitchingConfigWindow.setPreProcessingOutput(url=url) def setPostProcessingOutput(self, url: DataUrl) -> None: self._mainWindow._stitchingConfigWindow.setPostProcessingOutput(url=url) def get_available_pre_processing_stitching_mode(self) -> tuple[StitchingType]: return self._mainWindow.get_available_pre_processing_stitching_mode() def get_available_post_processing_stitching_mode(self) -> tuple[StitchingType]: return self._mainWindow.get_available_post_processing_stitching_mode() def main(argv, stitcher_name: str, stitching_axis: int, logger): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "tomo_objs", help="All tomo objects to be stitched together", nargs="*", ) parser.add_argument( "--debug", dest="debug", action="store_true", default=False, help="Set logging system in debug mode", ) parser.add_argument( "--config", "--config-file", dest="config_file", default=None, help="Provide stitching configuration file to load parameters from it", ) parser.add_argument( "--use-opengl-plot", "--opengl-backend", help="Use OpenGL for plots (instead of matplotlib)", action="store_true", default=False, ) parser.add_argument( "--inspect", help="Set up stitching to be oriented 'stitching' inspected.", action="store_true", default=False, ) parser.add_argument( "--check-scans", help="If True will check scans before adding them. This check scan validity (virtual dataset contains data...)", action="store_true", default=False, ) options = parser.parse_args(argv[1:]) if options.use_opengl_plot: silx.config.DEFAULT_PLOT_BACKEND = "gl" else: silx.config.DEFAULT_PLOT_BACKEND = "matplotlib" if options.debug: logging.root.setLevel(logging.DEBUG) increase_max_number_file() global app # QApplication must be global to avoid seg fault on quit app = qt.QApplication.instance() or qt.QApplication(["tomwer"]) splash = getMainSplashScreen() qt.QApplication.processEvents() qt.QLocale.setDefault(qt.QLocale(qt.QLocale.English)) qt.QLocale.setDefault(qt.QLocale.c()) signal.signal(signal.SIGINT, sigintHandler) sys.excepthook = qt.exceptionHandler timer = qt.QTimer() timer.start(500) # Application have to wake up Python interpreter, else SIGINT is not # catch timer.timeout.connect(lambda: None) window = MainWindow(axis=stitching_axis) window.setWindowFlags(qt.Qt.Window) window.setWindowTitle(stitcher_name) window.setWindowIcon(icons.getQIcon("tomwer")) if options.inspect: stitching_options = ( window._mainWindow._stitchingConfigWindow._stitchingOptsWidget._stitchingStrategiesWidget ) stitching_options.setStitchingStrategy(OverlapStitchingStrategy.CLOSEST) stitching_options._stitchingHeight._autoCB.setChecked(False) window.show() from sluurp.utils import has_sbatch_available # load configuration is some provided if options.config_file is not None: window.loadSettings(options.config_file) if not has_sbatch_available(): window.disableSlurmconfig() tomo_objs, (has_scans, has_vols) = get_tomo_objs_instances(options.tomo_objs) for tomo_obj in tomo_objs: if isinstance(tomo_obj, TomwerScanBase): tomo_obj.set_check_behavior( run_check=options.check_scans ) # speed up processing window.addTomoObj(tomo_obj=tomo_obj) if has_scans and has_vols: logger.warning( "seems like you have both volumes and scan on your inputs. Unable to stitch the two at the same time" ) elif has_scans: if stitching_axis == 0: window.setStitchingType(StitchingType.Z_PREPROC) elif stitching_axis == 1: window.setStitchingType(StitchingType.Y_PREPROC) else: raise ValueError( f"stitching on scans is not possible along the axis {stitching_axis} (must be 0 or 1)" ) elif has_vols: if stitching_axis == 0: window.setStitchingType(StitchingType.Z_POSTPROC) else: raise ValueError( f"stitching on volumes is not possible along the axis {stitching_axis} (must be 0). Should be possible in theory. Please contact us so we can have a dataset and test it" ) window.setAttribute(qt.Qt.WA_DeleteOnClose) splash.finish(window) exit(app.exec()) def sigintHandler(*args): """Handler for the SIGINT signal.""" qt.QApplication.closeAllWindows() # needed because get a waiting thread behind qt.QApplication.quit() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/app/stopdatalistener.py0000644000175000017500000000175315115744275021065 0ustar00paynopayno#!/usr/bin/env python # -*- coding: utf-8 -*- """ Application to stop possible running data listener (and free used port) """ import argparse import sys from signal import SIGKILL, SIGTERM from tomwer.core.utils.process import send_signal_to_local_rpc_servers from tomwer.core.settings import JSON_RPC_PORT def getinputinfo(): return "tomwer stop-data-listener [[--port --sigkill]]" def main(argv): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "--port", default=JSON_RPC_PORT, help="Define the port occupy by the rpc-server", ) parser.add_argument( "--sigkill", action="store_true", default=False, help="send a SIGKILL signal instead of a SIGTERM", ) options = parser.parse_args(argv[1:]) signal = SIGTERM if options.sigkill: signal = SIGKILL send_signal_to_local_rpc_servers(port=int(options.port), signal=signal) if __name__ == "__main__": main(sys.argv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/app/volume_viewer.py0000644000175000017500000001126115153325210020345 0ustar00paynopayno#!/usr/bin/env python # -*- coding: utf-8 -*- """Application to browse a given scan""" import numpy import argparse import logging import signal import sys import silx from silx.gui import qt from tomwer.tasks.visualization.volume_viewer import VolumeViewerTask from tomwer.core.volume.volumefactory import VolumeFactory from tomoscan.esrf.volume.utils import guess_volumes from tomwer.core.utils.resource import increase_max_number_file from tomwer.gui import icons from tomwer.gui.utils.splashscreen import getMainSplashScreen from tomwer.gui.visualization.volume_viewer.VolumeViewerWindow import ( VolumeViewerWindow, ) logging.basicConfig(level=logging.WARNING) _logger = logging.getLogger(__name__) class VolumeSummaryTaskThread(qt.QThread): def __init__(self, parent, inputs): super().__init__(parent) self._inputs = inputs def run(self): self._task = VolumeViewerTask(inputs=self._inputs) self._task.execute() def result(self): return { "slices": self._task.outputs.slices, "metadata": self._task.outputs.volume_metadata, "volume_shape": self._task.outputs.volume_shape, } def get_loaded_volume_data(self) -> numpy.array: return self._task.outputs.loaded_volume def main(argv): parser = argparse.ArgumentParser(description=__doc__) parser.add_argument( "volume", help="Volume identifier or location of the volume to display", ) parser.add_argument( "--load-volume", help="Load the full volume in memory. Allows fast browsing along the three axis.", action="store_true", default=False, ) parser.add_argument( "--use-opengl-plot", help="Use OpenGL for plots (instead of matplotlib)", action="store_true", default=False, ) options = parser.parse_args(argv[1:]) try: volumes = VolumeFactory.create_tomo_object_from_identifier(options.volume) except Exception: volumes = [] if len(volumes) == 0: volumes = guess_volumes( options.volume, ) if len(volumes) == 0: raise ValueError(f"No volume found in {options.volume}") if len(volumes) > 1: _logger.warning( f"More than one volume found in {options.volume}. Pick the first one." ) volume = VolumeFactory.create_tomo_object_from_identifier( volumes[0].get_identifier().to_str() ) if options.use_opengl_plot: silx.config.DEFAULT_PLOT_BACKEND = "gl" else: silx.config.DEFAULT_PLOT_BACKEND = "matplotlib" increase_max_number_file() global app # QApplication must be global to avoid seg fault on quit app = qt.QApplication.instance() or qt.QApplication(["tomwer"]) splash = getMainSplashScreen() qt.QApplication.setOverrideCursor(qt.Qt.WaitCursor) qt.QApplication.processEvents() qt.QLocale.setDefault(qt.QLocale(qt.QLocale.English)) qt.QLocale.setDefault(qt.QLocale.c()) signal.signal(signal.SIGINT, sigintHandler) sys.excepthook = qt.exceptionHandler timer = qt.QTimer() timer.start(500) # Application have to wake up Python interpreter, else SIGINT is not # catch timer.timeout.connect(lambda: None) window = VolumeViewerWindow(parent=None) # there is options from the CLI to load or not the volume at start. This option has no sense # in the CLI tool. window.setLoadingVolumeOptionVisible(False) window.setWindowTitle("tomwer: volume-viewer") window.setWindowIcon(icons.getQIcon("tomwer")) if options.load_volume: loading_message = "Loading volume." else: loading_message = "Loading slices." window.initVolumePreview(volume, message=loading_message) splash.finish(window) window.show() taskThread = VolumeSummaryTaskThread( parent=window, inputs={ "volume": volume, "load_volume": options.load_volume, }, ) taskThread.finished.connect( lambda: window.setSlicesAndMetadata(**taskThread.result()) ) if options.load_volume: taskThread.finished.connect( lambda: window.setVolume(taskThread.get_loaded_volume_data()) ) taskThread.finished.connect(lambda: window.setLoading(False)) taskThread.start() qt.QApplication.restoreOverrideCursor() app.aboutToQuit.connect(window.close) exit(app.exec()) def getinputinfo(): return "tomwer volume-viewer [file_path] [[file_entry]]" def sigintHandler(*args): """Handler for the SIGINT signal.""" qt.QApplication.closeAllWindows() # needed because get a waiting thread behind qt.QApplication.quit() if __name__ == "__main__": main(sys.argv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/app/ystitching.py0000644000175000017500000000106315143647637017664 0ustar00paynopayno#!/usr/bin/env python # -*- coding: utf-8 -*- """ Application to stitch along y (aka axis 0) a set of scans or reconstructed volumes """ from __future__ import annotations import sys import logging from tomwer.app.stitching.common import main as common_main logging.basicConfig(level=logging.WARNING) _logger = logging.getLogger(__name__) def getinputinfo(): return "tomwer y-stitching [tomo objects]" def main(argv): common_main(argv, stitcher_name="y-stitching", stitching_axis=1, logger=_logger) if __name__ == "__main__": main(sys.argv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/app/zstitching.py0000644000175000017500000000106315143647637017665 0ustar00paynopayno#!/usr/bin/env python # -*- coding: utf-8 -*- """ Application to stitch along z (aka axis 0) a set of scans or reconstructed volumes """ from __future__ import annotations import sys import logging from tomwer.app.stitching.common import main as common_main logging.basicConfig(level=logging.WARNING) _logger = logging.getLogger(__name__) def getinputinfo(): return "tomwer z-stitching [tomo objects]" def main(argv): common_main(argv, stitcher_name="z-stitching", stitching_axis=0, logger=_logger) if __name__ == "__main__": main(sys.argv) ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1772989186.913101 tomwer-1.6.17/src/tomwer/core/0000755000175000017500000000000015153325403015256 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/core/__init__.py0000644000175000017500000000010714764622416017400 0ustar00paynopayno"""This package contains all the core functions / classes of tomwer""" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1772989186.913101 tomwer-1.6.17/src/tomwer/core/cluster/0000755000175000017500000000000015153325403016737 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/core/cluster/__init__.py0000644000175000017500000000016414764622416021064 0ustar00paynopayno"""cluster related functions and classes (slurm...)""" from .cluster import SlurmClusterConfiguration # noqa F401 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/cluster/cluster.py0000644000175000017500000001051015153325210020763 0ustar00paynopayno# coding: utf-8 """ Contains processing relative to a `Slurmcluster` """ from __future__ import annotations import logging from tomwer.core.settings import SlurmSettings as _SlurmSettings _logger = logging.getLogger(__name__) class SlurmClusterConfiguration: """Object shipping the configuration of a slurm cluster""" def __init__( self, n_cpu_per_task=_SlurmSettings.N_CORES_PER_TASK, n_tasks=_SlurmSettings.N_TASKS, memory=_SlurmSettings.MEMORY_PER_WORKER, queue=_SlurmSettings.PARTITION, n_gpus=_SlurmSettings.N_GPUS_PER_WORKER, project_name=_SlurmSettings.PROJECT_NAME, walltime=_SlurmSettings.DEFAULT_WALLTIME, python_venv=_SlurmSettings.PYTHON_VENV, n_jobs=_SlurmSettings.N_JOBS, modules_to_load: tuple = _SlurmSettings.MODULES_TO_LOAD, sbatch_extra_params: dict = _SlurmSettings.SBATCH_EXTRA_PARAMS, ) -> None: self._n_cpu_per_task = n_cpu_per_task self._n_task = n_tasks self._memory = memory self._queue = queue self._n_gpus = n_gpus self._project_name = project_name self._walltime = walltime self._python_venv = python_venv self._modules_to_load = modules_to_load self._n_jobs = n_jobs self._sbatch_extra_params = sbatch_extra_params if python_venv not in (None, "") and len(modules_to_load) > 0: _logger.warning( "Either 'modules to load' of 'python venv' can be provided. Not both" ) @property def n_cpu_per_task(self): return self._n_cpu_per_task @property def n_task(self): return self._n_task @property def memory(self): return self._memory @property def queue(self): return self._queue @property def n_gpus(self): return self._n_gpus @property def n_jobs(self): return self._n_jobs @property def project_name(self): return self._project_name @property def walltime(self): return self._walltime @property def python_venv(self): return self._python_venv @property def modules_to_load(self) -> tuple: return self._modules_to_load @property def port_range(self) -> tuple: """port range as (start:int, strop:int, step: int)""" return self._port_range @property def sbatch_extra_params(self) -> dict: return self._sbatch_extra_params @property def dashboard_port(self): return self._dashboard_port def to_dict(self) -> dict: return { "cpu-per-task": self.n_cpu_per_task, "n_tasks": self.n_task, "n_jobs": self.n_jobs, "memory": self.memory, "partition": self.queue, "n_gpus": self.n_gpus, "job_name": self.project_name, "walltime": self.walltime, "python_venv": self.python_venv, "modules": self.modules_to_load, "sbatch_extra_params": self.sbatch_extra_params, } @staticmethod def from_dict(dict_: dict): return SlurmClusterConfiguration().load_from_dict(dict_=dict_) def load_from_dict(self, dict_: dict): if "cpu-per-task" in dict_: self._n_cpu_per_task = dict_["cpu-per-task"] if "n_tasks" in dict_: self._n_task = dict_["n_tasks"] if "n_jobs" in dict_: self._n_jobs = dict_["n_jobs"] if "memory" in dict_: self._memory = dict_["memory"] if "partition" in dict_: self._queue = dict_["partition"] if "n_gpus" in dict_: self._n_gpus = dict_["n_gpus"] if "job_name" in dict_: self._project_name = dict_["job_name"] if "walltime" in dict_: self._walltime = dict_["walltime"] if "python_venv" in dict_: self._python_venv = dict_["python_venv"] modules = dict_.get("modules", None) if modules is not None: self._modules_to_load = modules if "port_range" in dict_: self._port_range = dict_["port_range"] if "dashboard_port" in dict_: self._dashboard_port = dict_["dashboard_port"] if "sbatch_extra_params" in dict_: self._sbatch_extra_params = dict_["sbatch_extra_params"] return self ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/core/futureobject.py0000644000175000017500000001177114764622416020353 0ustar00paynopayno"""contains 'FutureTomwerObject'. Class used when computation is done asynchronously (when submitted to slurm for example)""" from __future__ import annotations import datetime import logging from typing import Iterable from sluurp.job import get_job_status, cancel_slurm_job from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.tomwer_object import TomwerObject _logger = logging.getLogger(__name__) class FutureTomwerObject: """Container for an existing TomwerScanBase with some future object (like slice reconstruction on slurm...) :param scan: scan at the origin of the FutureTomwerScan :param futures: tuple of Future :param start_time: start_time of the FutureTomwerScan. If not provided this will be set to the date of creation of the object. :param process_requester_id: process of the id requesting future processing. This is useful to keep a trace on the source of the computation. To display supervisor 'request' for example. """ def __init__( self, tomo_obj: TomwerObject, futures: tuple | list | None, start_time: datetime.time | None = None, process_requester_id: int | None = None, ): if not isinstance(tomo_obj, TomwerObject): raise TypeError( f"tomo_obj is expected to be an instance of {TomwerObject} not {type(tomo_obj)}" ) self._job_id = None self._tomo_obj = tomo_obj self._start_time = ( start_time if start_time is not None else datetime.datetime.now() ) self._process_requester_id = process_requester_id # handle futures if futures is None: self._futures = None elif not isinstance(futures, (tuple, list)): raise TypeError( f"futures is expected to be a tuple or a list not {type(futures)}" ) else: self._futures = list(futures) @property def job_id(self) -> int | None: return self._job_id @property def status(self) -> str | None: all_status = [ get_job_status(fut.job_id) if hasattr(fut, "job_id") else "unknown" for fut in self._futures ] # small hack to get a common status for a list of future. # if at least one running we can wait for all to be processed # Then after this condition it means all jobs are finished # and we can check if there is an error # otherwise everything is "green" for status in ( "pending", "running", "error", "cancelled", "finished", "completed", ): if status in all_status: return status return "finished" @property def logs(self) -> str: new_line = "\n" return "\n".join( [ f"~~~~~~ job id = {fut.job_id} ~~~~~{new_line}{f'{new_line}'.join(fut.collect_logs() or ['',])}" for fut in self._futures ] ) @property def start_time(self) -> datetime.time | None: return self._start_time @property def tomo_obj(self) -> TomwerScanBase: # TODO: replace the scan by the DatasetIdentifier return self._tomo_obj @property def futures(self) -> tuple | None: if self._futures is None: return None else: return tuple(self._futures) def extend_futures(self, futures: Iterable) -> None: if not isinstance(futures, Iterable): raise TypeError(f"futures should be an Iterable not {type(futures)}") if self._futures is None: self._futures = [] self._futures.extend(futures) @property def process_requester_id(self) -> int | None: return self._process_requester_id def results(self) -> TomwerScanBase: """Force future and callback synchronization""" results = [] [results.append(fut.result()) for fut in self._futures] return results def cancelled(self): cancelled = False for future in self.futures: cancelled = cancelled and future.cancelled() return cancelled def done(self): done = True for future in self.futures: done = done and future.done() return done def exceptions(self) -> dict | None: """ Return exception with future as key and exception as value """ exceptions = {} for future in self.futures: if future.exception(): exceptions[future] = future.exception() if len(exceptions) == 0: return None else: return exceptions def cancel(self): for future in self.futures: if hasattr(future, "job_id"): print("cancel ", future.job_id) cancel_slurm_job(future.job_id) ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1772989186.913101 tomwer-1.6.17/src/tomwer/core/log/0000755000175000017500000000000015153325403016037 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/core/log/__init__.py0000644000175000017500000000010614764622416020160 0ustar00paynopayno"""contains some log utils (used to notify processing advancement)""" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/log/processlog.py0000644000175000017500000000444615153325210020575 0ustar00paynopayno# coding: utf-8 """ Simple logs levels definition relative to process status """ import logging PROCESS_STARTED_NAME = "PROCESS_STARTED" PROCESS_STARTED_LEVEL = 32 PROCESS_SUCCEED_NAME = "PROCESS_SUCCEED" PROCESS_SUCCEED_LEVEL = 33 PROCESS_FAILED_NAME = "PROCESS_FAILED" PROCESS_FAILED_LEVEL = 38 PROCESS_ENDED_NAME = "PROCESS_ENDED" """String name of the process ended""" PROCESS_ENDED_LEVEL = 35 """Level of the process ended""" PROCESS_SKIPPED_NAME = "PROCESS_SKIPPED" """String name of the process skipped""" PROCESS_SKIPPED_LEVEL = 36 """Level of the process skipped""" PROCESS_INFORM_NAME = "PROCESS_INFORM" """Name of the process information""" PROCESS_INFORM_LEVEL = 31 """Level for information send to graylog""" logging.addLevelName(PROCESS_STARTED_LEVEL, PROCESS_STARTED_NAME) logging.addLevelName(PROCESS_SUCCEED_LEVEL, PROCESS_SUCCEED_NAME) logging.addLevelName(PROCESS_FAILED_LEVEL, PROCESS_FAILED_NAME) logging.addLevelName(PROCESS_ENDED_LEVEL, PROCESS_ENDED_NAME) logging.addLevelName(PROCESS_SKIPPED_LEVEL, PROCESS_SKIPPED_NAME) logging.addLevelName(PROCESS_INFORM_LEVEL, PROCESS_INFORM_NAME) def processEnded(self, message, *args, **kws): if self.isEnabledFor(PROCESS_ENDED_LEVEL): self._log(PROCESS_ENDED_LEVEL, message, args, **kws) def processSkipped(self, message, *args, **kws): if self.isEnabledFor(PROCESS_SKIPPED_LEVEL): self._log(PROCESS_SKIPPED_LEVEL, message, args, **kws) def inform(self, message, *args, **kws): if self.isEnabledFor(PROCESS_INFORM_LEVEL): self._log(PROCESS_INFORM_LEVEL, message, args, **kws) def processSucceed(self, message, *args, **kws): if self.isEnabledFor(PROCESS_SUCCEED_LEVEL): self._log(PROCESS_SUCCEED_LEVEL, message, args, **kws) def processFailed(self, message, *args, **kws): if self.isEnabledFor(PROCESS_FAILED_LEVEL): self._log(PROCESS_FAILED_LEVEL, message, args, **kws) def processStarted(self, message, *args, **kws): if self.isEnabledFor(PROCESS_STARTED_LEVEL): self._log(PROCESS_STARTED_LEVEL, message, args, **kws) logging.Logger.processEnded = processEnded logging.Logger.processSkipped = processSkipped logging.Logger.inform = inform logging.Logger.processSucceed = processSucceed logging.Logger.processFailed = processFailed logging.Logger.processStarted = processStarted ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9171011 tomwer-1.6.17/src/tomwer/core/process/0000755000175000017500000000000015153325403016734 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/process/__init__.py0000644000175000017500000000000014757047403021045 0ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9171011 tomwer-1.6.17/src/tomwer/core/process/cluster/0000755000175000017500000000000015153325403020415 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/cluster/__init__.py0000644000175000017500000000000015153325210022510 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/cluster/supervisor.py0000644000175000017500000000555615153325210023217 0ustar00paynopayno# coding: utf-8 """module containing FutureSupervisorTask.""" from typing import Iterable from ewokscore.task import Task as EwoksTask from tomwer.core.futureobject import FutureTomwerObject from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.process.drac.processeddataset import DracReconstructedVolumeDataset from tomwer.core.volume.volumebase import TomwerVolumeBase from tomwer.core.volume.volumefactory import VolumeFactory class FutureSupervisorTask( EwoksTask, input_names=("future_tomo_obj",), output_names=("data", "volume", "data_portal_processed_datasets"), ): """ Task used to wait for a 'FutureTomwerObject' and convert it to original instance of: * TomwerScanBase (data): if the FutureTomwerObject is based on a scan instance * TomwerVolumeBase (volume): if the FutureTomwerObject is based on a volume instance * tuple of IcatReconstructedVolumeDataset (data_portal_processed_datasets): if the FutureTomwerObject is based on a volume instance """ def run(self): future_tomo_obj = self.inputs.future_tomo_obj if not isinstance(future_tomo_obj, FutureTomwerObject): raise TypeError( f"future_data is expected to be an instance of {FutureTomwerObject}. Got {type(future_tomo_obj)}" ) future_tomo_obj.results() tomo_obj = future_tomo_obj.tomo_obj if isinstance(tomo_obj, TomwerScanBase): self.outputs.data = tomo_obj # the volume reconstruction return an instance of 'FutureTomwerObj' with a scan. # so to make drac publication compatible with it we also need to send the 'data_portal_processed_datasets' def build_drac_dataset(vol_id): volume = VolumeFactory.create_tomo_object_from_identifier(vol_id) return DracReconstructedVolumeDataset( tomo_obj=volume, source_scan=tomo_obj, ) assert isinstance(tomo_obj.latest_vol_reconstructions, Iterable) self.outputs.data_portal_processed_datasets = tuple( [ build_drac_dataset(vol_id=vol_id) for vol_id in tomo_obj.latest_vol_reconstructions ] ) if len(tomo_obj.latest_vol_reconstructions) > 0: # at the moment we expect at most one volume from a scan. # If it changes we will need to replace `volume` by `volumes` self.outputs.volume = VolumeFactory.create_tomo_object_from_identifier( tomo_obj.latest_vol_reconstructions[0] ) else: self.outputs.volume = None elif isinstance(tomo_obj, TomwerVolumeBase): self.outputs.volume = tomo_obj self.outputs.data_portal_processed_datasets = () self.outputs.data = None ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9171011 tomwer-1.6.17/src/tomwer/core/process/conditions/0000755000175000017500000000000015153325403021105 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/conditions/__init__.py0000644000175000017500000000000015153325210023200 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/conditions/filters.py0000644000175000017500000001331215153325210023123 0ustar00paynopayno# coding: utf-8 """ This module is used to define the process of the reference creator. This is related to the issue #184 """ from __future__ import annotations import fnmatch import logging import os import re import tomwer.version from tomwer.core.process.task import Task from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils.deprecation import deprecated_warning _logger = logging.getLogger(__name__) class BaseFilter(object): """ Apply a filter to an object """ def description(self): pass def isFiltered(self, value): """ Return True if the value not filtered """ raise NotImplementedError("Base class") class _PatternBaseFilter(BaseFilter): """Filter based on a pattern""" def __init__(self, pattern): BaseFilter.__init__(self) self.setPattern(pattern) def setPattern(self, pattern): """ compile th filter for the given pattern :param pattern: """ self._pattern = pattern def getPattern(self): return self._pattern class RegularExpressionFilter(_PatternBaseFilter): """Filter a string based on a defined pattern""" def __init__(self, pattern): _PatternBaseFilter.__init__(self, pattern=pattern) def setPattern(self, pattern): """ compile th filter for the given pattern :param pattern: """ super().setPattern(pattern) if self._pattern is not None: try: self._filter = re.compile(self._pattern) except re.error as e: self.unvalidPatternDefinition(self, self._pattern, e) _logger.error(e) def description(self): return "Filter a string base on a regular expression" def isFiltered(self, value): try: match = self._filter.match(value) is None except Exception: return False else: return match def unvalidPatternDefinition(self, cls, pattern, error): _logger.error(f"{cls} {pattern} is not a valid pattern. Error is {error}") class UnixFileNamePatternFilter(_PatternBaseFilter): """Filter a string based on 'fnmatch' module (unix filename pattern matching)""" def __init__(self, pattern): _PatternBaseFilter.__init__(self, pattern) def description(self): return "Filter a string base on a glob (unix style pathname)" def isFiltered(self, value): try: match = fnmatch.fnmatch(value, self._pattern) except Exception: match = False return not match class FileNameFilterTask( _PatternBaseFilter, Task, input_names=("data", "pattern"), output_names=("data",), optional_input_names=("serialize_output_data",), ): """ Task to filter a scan according to his name and a 'unix file name pattern' or a 'regular expression' """ UNIX_PATTERN_FILTER = "unix file name pattern" REGULAR_EXP_FILTER = "regular expression" FILTER_TYPES = UNIX_PATTERN_FILTER, REGULAR_EXP_FILTER _DEFAULT_FILTER_TYPE = FILTER_TYPES[0] _FILTER_CONSTR = { UNIX_PATTERN_FILTER: UnixFileNamePatternFilter, REGULAR_EXP_FILTER: RegularExpressionFilter, } def __init__( self, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None ): Task.__init__( self, varinfo=varinfo, inputs=inputs, node_id=node_id, node_attrs=node_attrs, execinfo=execinfo, ) pattern = inputs.get("pattern", None) if pattern is None: raise ValueError("'pattern' should be provided") filter_type = inputs.get("filter_type", self._DEFAULT_FILTER_TYPE) self._invert = inputs.get("invert_result", False) self._filter = self._FILTER_CONSTR[filter_type](pattern) _PatternBaseFilter.__init__(self, pattern) @property def invert_result(self): return self._invert @property def filter(self): return self._filter def isFiltered(self, value): result = self._filter.isFiltered(value) if self.invert_result: return not result else: return result def run(self): scan = self.inputs.data if scan is None: raise ValueError("'data' should be provided") if isinstance(scan, dict): scan = ScanFactory.create_scan_object_frm_dict(scan) if scan is None: return False assert isinstance(scan, TomwerScanBase) if not self.isFiltered(os.path.basename(scan.path)): if self.get_input_value("serialize_output_data", True): self.outputs.data = scan.to_dict() else: self.outputs.data = scan else: self.outputs.data = None @staticmethod def program_name(): return "scan filter" @staticmethod def program_version(): """version of the program used for this processing""" return tomwer.version.version @staticmethod def definition(): """definition of the process""" return "filter a scan according to his name" class FileNameFilter(FileNameFilterTask): def __init__( self, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None ): deprecated_warning( name="tomwer.core.process.conditions.filters.FileNameFilter", type_="class", reason="improve readibility", since_version="1.2", replacement="FileNameFilterTask", ) super().__init__(varinfo, inputs, node_id, node_attrs, execinfo) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9171011 tomwer-1.6.17/src/tomwer/core/process/control/0000755000175000017500000000000015153325403020414 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/__init__.py0000644000175000017500000000000015153325210022507 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/datadiscovery.py0000644000175000017500000000057115153325210023626 0ustar00paynopaynofrom ewokscore.task import Task as EwoksTask from tomwer.core.utils.scanutils import data_identifier_to_scan class _DataDiscoveryPlaceHolder(EwoksTask, input_names=["data"], output_names=["data"]): """ Task to recursivly search under a root folder for any scan / data. """ def run(self): self.outputs.data = data_identifier_to_scan(self.inputs.data) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9171011 tomwer-1.6.17/src/tomwer/core/process/control/datalistener/0000755000175000017500000000000015153325403023073 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/datalistener/__init__.py0000644000175000017500000000006415153325210025200 0ustar00paynopaynofrom .datalistener import DataListener # noqa F401 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/datalistener/datalistener.py0000644000175000017500000002271115153325210026123 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging import os import socket import time from ewokscore.task import Task as EwoksTask from nxtomomill import converter as nxtomomill_converter from nxtomomill.models.h52nx import H52nxModel from silx.io.utils import open as open_hdf5 import tomwer.version from tomwer.core import settings from tomwer.core.process.task import BaseProcessInfo from tomwer.core.scan.blissscan import BlissScan from tomwer.core.scan.nxtomoscan import NXtomoScan from .rpcserver import DataListenerThread _logger = logging.getLogger(__name__) def nxtomomill_input_callback(entry, desc): """note: for the data listener we want to avoid any user interaction. In order to avoid any time lost""" if entry == "energy": default_energy = 19.0 _logger.warning(f"Energy is missing. Set it to default to {default_energy}") return default_energy else: _logger.warning(f"missing {entry}. Won't be set") return None class _DataListenerTaskPlaceHolder(EwoksTask, output_names=["data"]): pass class DataListener(BaseProcessInfo): # TODO: update this, DataListener is not properly a task """ class able to connect with a redis database. During an acquisition at esrf the redis database expose the scan under acquisition. This allow use to know when a scan is finished. In order to insure connection the machine need to know where is located the 'bacon server' (see https://bliss.gitlab-pages.esrf.fr/bliss/master/bliss_data_life.html). This is why the 'BEACON_HOST' environment variable should be defined. For example for id19 - lbs 191 we have: export BEACON_HOST="europa" On id19 - europa we would have export BEACON_HOST="localhost" """ TIMOUT_READ_FILE = 30 "When the event 'scan_ended' is received all data might not have been write" " yet" SWMR_MODE = None """The bliss writer is not using the swmr mode. This class has independent behavior regarding the tomoscan / nxotmo get_swmr_mode which is dedicated to the internal tomotools behavior """ def __init__(self): super().__init__() self._rpc_host = settings.JSON_RPC_HOST # if host is None then use hostname if self._rpc_host is None: self._rpc_host = socket.gethostname() self._rpc_port = settings.JSON_RPC_PORT self._listening_thread = None @staticmethod def program_name(): """Name of the program used for this processing""" return "scan listener" @staticmethod def program_version(): """version of the program used for this processing""" return tomwer.version.version @staticmethod def definition(): """definition of the process""" "convert bliss sequence with a proposal to a NXTomo nexus file" @property def port(self): return self._rpc_port @property def host(self): return self._rpc_host def get_listening_thread(self): """ return the listening thread to ear at tango server """ if self._listening_thread is None: self._listening_thread = self.create_listening_thread() return self._listening_thread def create_listening_thread(self): """ Procedure to create the listening thread :return: listening thread """ return DataListenerThread(host=self.host, port=self.port) def delete_listening_thread(self): """ Procedure to delete the listening thread """ if hasattr(self, "_listening_thread"): if self._listening_thread is not None: self._listening_thread.stop() self._listening_thread.join(5) del self._listening_thread self._listening_thread = None def set_configuration(self, properties): # for now the NXProcess cannot be tune if isinstance(properties, H52nxModel): self._settings = properties.to_dict() elif isinstance(properties, dict): self._settings = properties else: raise TypeError(f"invalid type: {type(properties)}") def run(self): pass def process_sample_file( self, sample_file: str, entry: str, proposal_file: str, master_sample_file: str | None, ) -> tuple: """ :param sample_file: file to be converted :param entry: entry in the tango .h5 file to be converter :return: tuple scan succeeded. """ if not os.path.isfile(sample_file): raise ValueError(f"Given file {sample_file} does not exists.") scans = [] for mf_emf in self.convert(bliss_file=sample_file, entry=entry): master_file, entry_master_file = mf_emf if master_file is not None and entry_master_file is not None: scan = NXtomoScan(scan=master_file, entry=entry_master_file) self._signal_scan_ready(scan) scans.append(scan) return tuple(scans) def convert(self, bliss_file: str, entry: str) -> tuple: """ :param bliss_file: file to be converted :param entry: entry in the tango .h5 file to be converter :return: tuple (output file, output file entry). Both are set to None if conversion fails. """ from tomwer.core.process.control.nxtomomill import ( H5ToNxProcess as NxTomomillProcess, ) conf = self.get_configuration() if conf is None: conf = {} configuration = H52nxModel.from_dict(conf) if configuration.output_file is None: output_file_path = NxTomomillProcess.deduce_output_file_path( bliss_file, output_dir=None, scan=BlissScan( master_file=bliss_file, entry=entry, proposal_file=bliss_file ), ) else: output_file_path = configuration.output_file if os.path.exists(output_file_path): if not self._ask_user_for_overwritting(output_file_path): return ((None, None),) if entry.startswith("/"): entries = (entry,) else: entries = ("/" + entry,) # work around: we need to wait a bit before converting the file # otherwise it looks like the file might not be ended to be # write def sequence_is_finished(): try: with open_hdf5(bliss_file) as h5f: end_scan_path = "/".join((entry, "end_time")) return end_scan_path in h5f except Exception: return False timeout = self.TIMOUT_READ_FILE while timeout > 0 and not sequence_is_finished(): timeout -= 0.2 time.sleep(0.2) if timeout <= 0: _logger.error(f"unable to access {entry}@{bliss_file}. (Write never ended)") return ((None, None),) # one more delay to insure we can read it. Some frame might need more time to be dump from lima. time.sleep(4) # force some parameters configuration.input_file = bliss_file configuration.output_file = output_file_path configuration.entries = entries configuration.single_file = False configuration.overwrite = True configuration.request_input = True configuration.file_extension = ".nx" try: convs = nxtomomill_converter.from_h5_to_nx( configuration=configuration, input_callback=nxtomomill_input_callback, progress=None, ) except Exception as e: _logger.error( f"Fail to convert from tango file: {bliss_file} to NXTomo. Error is: {e}" ) return ((None, None),) else: return convs def _ask_user_for_overwritting(self, file_path): res = None while res not in ("Y", "n"): res = input( "The process will overwrite %s. Do you agree ? (Y/n)" "" % file_path ) return res == "Y" def _signal_scan_ready(self, scan): assert isinstance(scan, NXtomoScan) pass def activate(self, is_using_rpc: bool, activate=True): """ activate or deactivate the thread. When deactivate call join and delete the thread :param activate: """ if activate: if self._listening_thread is not None: _logger.info("listening is already activate") else: assert isinstance(self, DataListener) if is_using_rpc and not self.is_port_available(): raise OSError( f"Port {self._rpc_host}:{self._rpc_port} already used" ) if self.get_listening_thread() is not None: self.get_listening_thread().start() else: if self._listening_thread is None: return else: self.delete_listening_thread() def is_active(self): if self._listening_thread is None: return False else: return True def is_port_available(self): """ :return: True if the port is available else False """ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: return not s.connect_ex((self._rpc_host, self._rpc_port)) == 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/datalistener/rpcserver.py0000644000175000017500000001674715153325210025473 0ustar00paynopayno# coding: utf-8 from __future__ import annotations from enum import Enum as _Enum import logging import socket import threading import time from multiprocessing import Process from jsonrpc import JSONRPCResponseManager, dispatcher from werkzeug.serving import run_simple from werkzeug.wrappers import Request, Response _logger = logging.getLogger(__name__) class TangoAcquisitionStatus(_Enum): """list of possible status of the acquisition""" STARTED = "started" ON_GOING = "on going" CANCELED = "canceled" ENDED = "ended" class BlissAcquisition: """Define an acquisition made with bliss / tango""" def __init__(self, file_path, entry_name, proposal_file, sample_file, start_time): self.entry = entry_name self.master_file = file_path self.proposal_file = proposal_file self.sample_file = sample_file self.scan_numbers = [] self.status = TangoAcquisitionStatus.STARTED self._start_time = start_time self._end_time = None self._error = None self._state = None @property def state(self): return self._state @state.setter def state(self, state): self._state = state def add_scan_number(self, scan_number): self.scan_numbers.append(scan_number) def set_status(self, status): self.status = TangoAcquisitionStatus(status) def end(self, end_time, succeed: bool, error: str | None): if succeed is True: self.status = TangoAcquisitionStatus.ENDED else: self.status = TangoAcquisitionStatus.CANCELED self._error = error self._end_time = end_time @property def has_error(self): return self._error is not None @property def start_time(self): return self._start_time @property def end_time(self): return self._end_time @property def error(self) -> str | None: return self.error class _BaseDataListenerThread: """Base class for data listener thread. Thread can be a threading.Thread or a qt.QThread. On the current bliss system (2020) a sequence is an acquisition. A sequence is composed of several scans. A scan can be the 'init' information, dark frames, flat frames, projections frames, return projections... """ _JOIN_TIMEOUT = 5 # s def __init__(self, host, port, acquisitions=None): assert host is not None assert port is not None # connect to the tango device self.acquisitions = acquisitions or [] """acquisition with scan information, as key and acquisition status as value""" self._host = host # if host is None then use hostname if self._host is None: self._host = socket.gethostname() self._port = port self._tomo_state = None # state of the current sequence self._current_sequence = None # current sequence self._current_scan_number = None # scan of the sequence currently recording self._server = None self._stop = False def _rpc_sequence_started( self, saving_file, scan_title, sequence_scan_number, proposal_file, sample_file ): self._current_sequence = BlissAcquisition( file_path=saving_file, entry_name=sequence_scan_number, proposal_file=proposal_file, start_time=time.ctime(), sample_file=sample_file, ) self.sequence_started(acquisition=self._current_sequence) def sequence_started(self, acquisition: BlissAcquisition): print( "sequence {}@{} started. Title is {}, proposal file {}" "".format( acquisition.entry, acquisition.master_file, acquisition.title, acquisition.proposal_file, ) ) def _rpc_scan_started(self, scan_number): if self._current_sequence is not None: self._current_sequence.add_scan_number(scan_number=scan_number) self.scan_added(acquisition=self._current_sequence, scan_number=scan_number) def scan_added(self, acquisition: BlissAcquisition, scan_number: int): print(f"scan {scan_number} started") def _rpc_scan_ended(self, scan_number): if self._current_sequence is not None: self.scan_ended(acquisition=self._current_sequence, scan_number=scan_number) def scan_ended(self, acquisition: BlissAcquisition, scan_number): print(f"scan {scan_number} ended") def _rpc_sequence_ended(self, saving_file, sequence_scan_number, success: bool): if success is False: _logger.warning(f"sequence {sequence_scan_number}@{saving_file} failed") if self._current_sequence is not None: try: self.sequence_failed(self._current_sequence) except Exception as e: _logger.warning(f"Fail to catch cancel scan. error is {e}") return if self._current_sequence is not None: if ( self._current_sequence.master_file == saving_file and self._current_sequence.entry == sequence_scan_number ): self.sequence_ended(self._current_sequence) else: name = "@".join((sequence_scan_number, saving_file)) name_current = "@".join( (self._current_sequence.entry, self._current_sequence.master_file) ) _logger.warning( f"End of {name} detected but does not fit the current acquisition {name_current}" ) def sequence_ended(self, acquisition: BlissAcquisition): """callback when a sequence end (with success)""" print( f"sequence {acquisition.entry}@{acquisition.master_file} ended. Succeed: {acquisition.status}" ) def sequence_failed(self, acquisition: BlissAcquisition): """callback when a sequence fails (probably canceled)""" print(f"sequence {acquisition.entry}@{acquisition.master_file} failed") @Request.application def application(self, request): dispatcher["scan_started"] = self._rpc_scan_started dispatcher["scan_ended"] = self._rpc_scan_ended dispatcher["sequence_started"] = self._rpc_sequence_started dispatcher["sequence_ended"] = self._rpc_sequence_ended response = JSONRPCResponseManager.handle(request.data, dispatcher) return Response(response.json, mimetype="application/json") def start(self) -> None: self._stop = False _logger.info(f"launch rpc server on {self._host}:{self._port}") self._server = Process( target=run_simple, args=(self._host, self._port, self.application) ) self._server.start() _logger.info(f"launcher server with pid {self._server.pid}") def stop(self): self._stop = True if self._server is not None: _logger.info(f"stop rpc server on {self._host}:{self._port}") self._server.terminate() self._server.join(_BaseDataListenerThread._JOIN_TIMEOUT) self._server = None class DataListenerThread(_BaseDataListenerThread, threading.Thread): """Implementation of _BaseDataListenerThread with a threading.Thread""" def __init__(self, host, port, acquisitions=None): threading.Thread.__init__(self) _BaseDataListenerThread.__init__( self, host=host, port=port, acquisitions=acquisitions ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9171011 tomwer-1.6.17/src/tomwer/core/process/control/datawatcher/0000755000175000017500000000000015153325403022703 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/datawatcher/__init__.py0000644000175000017500000000006215153325210025006 0ustar00paynopaynofrom .datawatcher import DataWatcher # noqa F401 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/datawatcher/datawatcher.py0000644000175000017500000003564115153325210025551 0ustar00paynopaynofrom __future__ import annotations import logging import os import threading import time from ewokscore.task import Task as EwoksTask from tomwer.core.process.control.datawatcher.datawatcherobserver import ( _DataWatcherObserver, _OngoingObservation, ) from tomwer.core.process.task import BaseProcessInfo from tomwer.core.process.utils import LastReceivedScansDict from tomwer.core.scan.blissscan import BlissScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.settings import get_dest_path, get_lbsram_path from tomwer.core.signal import Signal from tomwer.core.utils import logconfig from .status import * # noqa F403 logger = logging.getLogger(__name__) class DataWatcherEwoksTask(EwoksTask, input_names=["data"], output_names=["data"]): """ For now the data watcher is a 'special case'. Because it will trigger downstream workflows / prcessing each time it discover a new scan. To move to 'default' ewoks workflows. Like launching it from the command line the simpler for now is to simply pass the `data` input that user can fill manually. """ def run(self): self.outputs.data = self.inputs.data class _DataWatcher(BaseProcessInfo): # TODO: change: this is not properly a Task """DataWatcher is the class use to mange observation of scans It basically have one DataWatcherObserver thread which is dealing with the observations. It parse all folder contained under the RootDir. This DataWatcherObserver is run every `maxWaitBtwObsLoop`. The call to the DataWatcherObserver is managed by the `loopObservationThread` which is calling back `_launchObservation` DataWatcher can run infinite search or stop observation after the discovery of the first valid scan (`setInfiniteIteration`) """ folderObserved = None NB_STORED_LAST_FOUND = 20 """All found acquisition are stored until we reach this number. In this case the oldest one will be removed""" DEFAULT_OBS_METH = DET_END_XML # noqa F405 def __init__(self): super().__init__() """use to know if we want to continue observation when the finished scan is found ?""" self.lastFoundScans = LastReceivedScansDict(self.NB_STORED_LAST_FOUND) self.isObserving = False self._initClass() # get ready observation self._setCurrentStatus("not processing") self._launchObservation() self._checkThread = None self._serialize_output_data = False def set_serialize_output_data(self, serialize: bool): self._serialize_output_data = serialize def _launchObservation(self): """Main function of the widget""" raise NotImplementedError("Base class") def _initClass(self): self.srcPattern = get_lbsram_path() self.destPattern = get_dest_path() self.observationThread = None """Thread used to parse directories and found where some :class`DataWatcherFixObserver` have to be launcher""" self.obsThIsConnected = False self.maxWaitBtwObsLoop = 5 """time between two observation loop, in sec""" self.obsMethod = self.DEFAULT_OBS_METH """Pattern to look in the acquisition file to know of the acquisition is ended or not""" self.startByOldest = False self.linux_filter_file_pattern = None def _switchObservation(self): """Switch the status of observation""" if self.isObserving is True: self.stop() else: self.start() def setObsMethod(self, obsMethod): """Set the observation method to follow. .. Note:: For now this will be apply on the next observation iteration. We don't wan't to stop and restart an observation as sometimes It can invoke a lot of start/stop if the user is editing the pattern of the file for example. But this might evolve in the future. """ assert type(obsMethod) in (str, tuple) if type(obsMethod) is tuple: assert len(obsMethod) == 1 or ( type(obsMethod[1]) is dict and len(obsMethod) == 2 ) obsMethod = obsMethod[0] self.obsMethod = obsMethod if self.isObserving: self._restartObservation() def setObservation(self, b): """Start a new observation (if none running ) or stop the current observation :param b: the value to set to the observation """ self.start() if b else self.stop() def stop(self, sucess=False): """ Stop the thread of observation :param sucess: if True this mean that we are stopping the observation because we found an acquisition finished. In this case we don't want to update the status and the log message """ if self.isObserving is False: return False self._setIsObserving(False) if self.observationThread is not None: # remove connection self.observationThread.quitEvent.set() if self.observationThread.is_alive(): self.observationThread.join() if self._checkThread and self._checkThread.is_alive(): self._checkThread.join() self.observationThread = None if sucess is False: self._setCurrentStatus(str("not processing")) logger.info("stop observation from %s" % self.folderObserved) return True def start(self): """Start the thread of observation :return bool: True if the observation was started. Otherwise this mean that an observation was already running """ if self.isObserving is True: return False else: logger.info("start observation from %s" % self.folderObserved) self._setIsObserving(True) self._setCurrentStatus("not processing") self._launchObservation() return True def _setIsObserving(self, b): self.isObserving = b def resetStatus(self): """ Reset the status to not processing. Needed to restart observation, like when the folder is changing """ self._setCurrentStatus("not processing") def getFolderObserved(self): return self.folderObserved def getLinuxFilePattern(self): return self.linux_filter_file_pattern def setLinuxFilePattern(self, pattern: str | None): if pattern is None: self.linux_filter_file_pattern = pattern else: pattern = pattern.lstrip(" ").rstrip(" ") if pattern == "": self.linux_filter_file_pattern = None else: self.linux_filter_file_pattern = pattern def setFolderObserved(self, path): assert type(path) is str if not os.path.isdir(path): warning = "Can't set the observe folder to ", path, " invalid path" logger.warning(warning, extra={logconfig.DOC_TITLE: self._scheme_title}) else: self.folderObserved = os.path.abspath(path) def getTimeBreakBetweenObservation(self): """ :return: the duration of the break we want to do between two observations (in sec) """ return self.maxWaitBtwObsLoop def setWaitTimeBtwLoop(self, time): if not time > 0: err = "invalid time given %s" % time raise ValueError(err) self.maxWaitBtwObsLoop = time def setStartByOldest(self, b): """ When parsing folders, should we start by the oldest or the newest file :param b: if True, will parse folders from the oldest one """ self.startByOldest = b def setSrcAndDestPattern(self, srcPattern: str | None, destPattern: str | None): """Set the values of source pattern and dest pattern :param srcPattern: the value to set to the source pattern (see datawatcher) :param destPattern: the value to set to the destination pattern (see datawatcher) """ self.srcPattern = srcPattern self.destPattern = destPattern def _initObservation(self): """Init the thread running the data watcher functions""" if self.observationThread is None: self._createDataWatcher() headDir = self.getFolderObserved() if headDir is None or not os.path.isdir(headDir): self._messageNotDir(headDir) self.stop() return False # update information on the head folder and the start by the oldest self.observationThread.setHeadFolder(headDir) self.observationThread.setObservationMethod(self.obsMethod) self.observationThread.setUnixFileNamePattern(self.linux_filter_file_pattern) return True def _messageNotDir(self, dir_): message = "Given path (%s) isn't a directory." % dir_ logger.warning(message, extra={logconfig.DOC_TITLE: self._scheme_title}) def _createDataWatcher(self): self.observationThread = _DataWatcherObserver( observationClass=self._getObservationClass(), obsMethod=self.obsMethod, time_between_loops=self.maxWaitBtwObsLoop, srcPattern=self.srcPattern, destPattern=self.destPattern, ) def _observation_thread_running(self): return self.observationThread is not None and self.observationThread.is_alive() def _init_check_finished_scan(self): self._checkThread = threading.Thread(target=self._check_finished_scan) self._checkThread.start() def _getObservationClass(self): return _OngoingObservation def _check_finished_scan(self): """check scanReady event""" while self.isObserving is True: if self.observationThread is not None: self.observationThread._check_scans_ready() with self.observationThread.lock: if self.observationThread.scanReadyEvent.isSet(): for scanID in self.observationThread.latestScanReady: try: _scan = ScanFactory.create_scan_object(scan_path=scanID) except Exception as e: logger.error( f"Fail to create TomoBase from {scanID}. Error is {e}" ) else: self._signalScanReady(scan=_scan) self.observationThread.scanReadyEvent.clear() time.sleep(0.05) def _restartObservation(self): """Reset system to launch a new observation""" if self.observationThread is not None: self.observationThread.quit() self._setCurrentStatus("not processing") self._launchObservation() def _statusChanged(self, status): assert status[0] in OBSERVATION_STATUS # noqa 320 self._setCurrentStatus(status[0], status[1] if len(status) == 2 else None) def informationReceived(self, info): logger.info(info) def _setCurrentStatus(self, status, info=None): """Change the current status to status""" assert type(status) is str assert status in OBSERVATION_STATUS # noqa 320 self.currentStatus = status self._updateStatusView() if hasattr(self, "sigTMStatusChanged"): self.sigTMStatusChanged.emit(status) _info = status if info is not None: _info += " - " + info self.informationReceived(_info) if status == "acquisition ended": # info should be the directory path assert info is not None assert type(info) is str logger.processEnded( "Find a valid scan", extra={ logconfig.DOC_TITLE: self._scheme_title, logconfig.SCAN_ID: info, }, ) try: scan = ScanFactory.create_scan_object(scan_path=info) except Exception as e: logger.warning(f"Fail to create scan object from {info}. Reason is {e}") else: self._signalScanReady(scan=scan) def _signalScanReady(self, scan): assert isinstance(scan, (TomwerScanBase, BlissScan)) self.lastFoundScans.add(scan) self.sigScanReady.emit(scan) # pylint: disable=E1101 def mockObservation(self, folder): # simple mocking emitting a signal to say that the given folder is valid self._setCurrentStatus(status="acquisition ended", info=folder) def _updateStatusView(self): pass def _setMaxAdvancement(self, max): """ """ pass def _advance(self, nb): """Update the progress bar""" pass def set_configuration(self, properties): for observe_folder_alias in ("observed_folder", "folderObserved"): if observe_folder_alias in properties: self.setFolderObserved(properties[observe_folder_alias]) def waitForObservationFinished(self): if self.observationThread is not None: self.observationThread.waitForObservationFinished() self.observationThread.quitEvent.set() def getIgnoredFolders(self): if self.observationThread is None: return [] else: return self.observationThread.observations.ignoredFolders class DataWatcher(_DataWatcher): """For now to avoid multiple inheritance from QObject with the process widgets we have to define two classes. One only for the QObject inheritance """ sigTMStatusChanged = Signal(str) """emit when the status of the scan changed""" sigScanReady = Signal(object) """emit when scan ready""" import threading scan_found_event = threading.Event() def __init__(self): _DataWatcher.__init__(self) self.scan = None """last found scan""" def _signalScanReady(self, scan): assert isinstance(scan, TomwerScanBase) super()._signalScanReady(scan) self.scan_found_event.set() def _launchObservation(self): """Main function of the widget""" if self.isObserving is False: return # manage data watcher observation if self.observationThread is None or not self._observation_thread_running(): if self._initObservation() is False: self._setCurrentStatus("failure") logger.info( "failed on observation", extra={logconfig.DOC_TITLE: self._scheme_title}, ) return self._init_check_finished_scan() # starting the observation thread self.observationThread.start() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/datawatcher/datawatcherobserver.py0000644000175000017500000005720515153325210027321 0ustar00paynopaynofrom __future__ import annotations import logging import os import threading import time from collections import OrderedDict from fnmatch import fnmatch import h5py from tomwer.core.process.control.datawatcher import status as datawatcherstatus from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.utils.threads import LoopThread from .datawatcherprocess import _DataWatchEmpty from .edfdwprocess import ( _DataWatcherProcessParseInfo, _DataWatcherProcessUserFilePattern, _DataWatcherProcessXML, ) from .hdf5dwprocess import _BlissScanWatcherProcess, _DataWatcherProcessHDF5 logger = logging.getLogger(__name__) class _DataWatcherStaticObserverMixIn: def __init__( self, scanID, obsMethod, srcPattern: str | None, destPattern: str | None, patternObs: str | None, observationRegistry, ): """ :param scanID: path to the scan :param obsMethod: method fo rdetecting end of acquisition :param srcPattern: :param destPattern: :param patternObs: :param observationRegistry: what registry the observation should update """ self.obsMethod = obsMethod self.srcPattern = srcPattern self.destPattern = destPattern self.patternObs = patternObs """The pattern to use for the DET_END_USER_ENTRY method""" self.setDirToObserve(scanID) self.dataWatcherProcess = self._getDataWatcherProcess() self.status = "not processing" self.observationRegistry = observationRegistry self.file_name_pattern = None def setProperties(self, properties): assert isinstance(properties, dict) if "scan" in properties: self.setDirToObserve(properties["scan"]) def setDirToObserve(self, directory): self.path = directory if hasattr(self, "dataWatcherProcess") and self.dataWatcherProcess: self.dataWatcherProcess.RootDir = directory self.dataWatcherProcess.parsing_dir = "" def quit(self): if self.dataWatcherProcess is not None: self.dataWatcherProcess.quitting = True def run(self): look_for_hdf5_file = self.obsMethod in ( datawatcherstatus.BLISS_SCAN_END, datawatcherstatus.NXtomo_END, ) if not look_for_hdf5_file and not os.path.isdir(self.path): logger.info("can't observe %s, not a directory" % self.path) self.status = "failure" if self.observationRegistry: self.observationRegistry._updateStatus( status=datawatcherstatus.OBSERVATION_STATUS[self.status], scan=self.path, ) self.validation = -1 return if self.dataWatcherProcess.is_abort(): if self.status != "aborted": logger.info("Acquisition %s has been aborted" % self.path) self.dataWatcherProcess._removeAcquisition( scanID=self.path, reason="acquisition aborted by the user" ) self.status = "aborted" if self.observationRegistry: self.observationRegistry._updateStatus( status=datawatcherstatus.OBSERVATION_STATUS[self.status], scan=self.path, ) self.validation = -2 return dataComplete = self.dataWatcherProcess.is_data_complete() if dataComplete is True: self.status = "acquisition ended" if self.observationRegistry: self.observationRegistry._updateStatus( status=datawatcherstatus.OBSERVATION_STATUS[self.status], scan=self.path, ) self.validation = 1 else: self.status = "waiting for acquisition ending" if self.observationRegistry: self.observationRegistry._updateStatus( status=datawatcherstatus.OBSERVATION_STATUS[self.status], scan=self.path, ) self.validation = 0 return def _getDataWatcherProcess(self): if self.obsMethod == datawatcherstatus.DET_END_XML: return _DataWatcherProcessXML( dataDir=self.path, srcPattern=self.srcPattern, destPattern=self.destPattern, ) elif self.obsMethod == datawatcherstatus.PARSE_INFO_FILE: return _DataWatcherProcessParseInfo( dataDir=self.path, srcPattern=self.srcPattern, destPattern=self.destPattern, ) elif self.obsMethod == datawatcherstatus.DET_END_USER_ENTRY: return _DataWatcherProcessUserFilePattern( dataDir=self.path, srcPattern=self.srcPattern, destPattern=self.destPattern, pattern=self.patternObs, ) elif self.obsMethod == datawatcherstatus.BLISS_SCAN_END: return _BlissScanWatcherProcess( dataDir=self.path, srcPattern=self.srcPattern, destPattern=self.destPattern, ) elif self.obsMethod == datawatcherstatus.NXtomo_END: return _DataWatcherProcessHDF5( dataDir=self.path, srcPattern=self.srcPattern, destPattern=self.destPattern, ) else: raise ValueError("requested observation method not recognized") def setSourceToDestinationPatterns(self, srcPattern, destPattern): """set the patterns to replace strings sequence in directories path. For example during acquisition in md05 acquisition files are stored in /lbsram/data/visitor/x but some information (as .info) files are stored in /data/visitor/x. So we would like to check information in both directories. Furthermore we would like that all file not in /data/visitor/x will be copied as soon as possible into /data/visitor/x (using RSyncManager) To do so we can define a srcPattern ('/lbsram' in our example) and destPattern : a string replacing to srcPattern in order to get both repositories. ('' in out example) If srcPattern or destPattern are setted to None then we won't apply this 'two directories' synchronization and check :param srcPattern: the pattern to change by destPattern. :param destPattern: the pattern that will replace srcPattern in the scan path """ self.srcPattern = srcPattern self.destPattern = destPattern def setUnixFileNamePattern(self, pattern): self.file_name_pattern = pattern def setObservationMethod(self, obsMeth: str | None, info=None): """ Set if we are looking for the .xml file :param obsMeth: :param info: some extra information needed for some observation method """ assert info is None or type(info) is dict assert type(obsMeth) in (tuple, str) if type(obsMeth) is str: self.obsMethod = obsMeth if self.obsMethod == datawatcherstatus.DET_END_USER_ENTRY: assert "pattern" in info self.patternObs = info["pattern"] else: self.patternObs = None else: assert len(obsMeth) > 0 assert type(obsMeth[0]) is str self.obsMethod = obsMeth[0] if self.obsMethod == datawatcherstatus.DET_END_USER_ENTRY: assert len(obsMeth) == 2 assert type(obsMeth[1]) is dict assert "pattern" in obsMeth[1] self.patternObs = obsMeth[1]["pattern"] else: self.patternObs = None class _DataWatcherStaticObserver(_DataWatcherStaticObserverMixIn, threading.Thread): """Observe one specific directory and signal when the state of this directory change""" def __init__( self, scanID, obsMethod, srcPattern, destPattern, patternObs, observationRegistry, ): threading.Thread.__init__(self) _DataWatcherStaticObserverMixIn.__init__( self, scanID=scanID, obsMethod=obsMethod, srcPattern=srcPattern, destPattern=destPattern, patternObs=patternObs, observationRegistry=observationRegistry, ) class _DataWatcherObserver_MixIn: """Thread launching the data watcher process (observation of acquisition) :param headDir: the root dir to make to fin dacquisition :param time_between_loops: seconds between observation threads :param startByOldest: if True then we parse folder from the oldest to the newest :param funcAdvancementHandler: handlers of the signals sended by data watcher (one for sigNbDirExplored and one for sigAdvanceExploration) :param obsMethod: is True then will the creation of the xml file will notice the end of the acquisition. Otherwise we will look for .info file and for all .edf file to be copied :param srcPattern: see data watcher :param destPattern: see data watcher """ latestScanReady = [] def __init__( self, obsMethod, time_between_loops, observationClass, headDir: str | None = None, startByOldest=False, srcPattern: str | None = None, destPattern: str | None = None, ignoredFolders: str | None = None, file_name_pattern: str | None = None, ): self.observations = observationClass() self.observations.ignoredFolders = ( [] if ignoredFolders is None else ignoredFolders ) """dict of observer on one specific scan. Key is the directory, value the :class:`DataWatcherFixObserver`""" self.setHeadFolder(headDir) self.setObservationMethod(obsMethod) self.srcPattern = srcPattern self.destPattern = destPattern self._file_name_pattern = file_name_pattern self.dataWatcherProcess = None self._patternObs = None """The pattern to use for the DET_END_USER_ENTRY method""" self.lock = threading.Lock() self.restartEvent = None self._firstRun = True @property def file_name_pattern(self) -> str | None: return self._file_name_pattern @file_name_pattern.setter def file_name_pattern(self, pattern: str | None): if pattern is None or pattern.lstrip(" ").rstrip(" ") == "": self._file_name_pattern = None else: self._file_name_pattern = pattern.lstrip(" ").rstrip(" ") def resetObservations(self): self.observations.reset() def registerRestartProcess(self, event): self.restartEvent = event def run(self): look_for_hdf5_file = self.obsMethod in ( datawatcherstatus.BLISS_SCAN_END, datawatcherstatus.NXtomo_END, ) def process_observations(file_path): do_observation = ( self.observations.isObserving(file_path) is False and ( (look_for_hdf5_file and h5py.is_hdf5(file_path)) or (self.dataWatcherProcess._isScanDirectory(file_path)) ) and file_path not in self.observations.ignoredFolders ) if ( do_observation and self.file_name_pattern is not None and not fnmatch(os.path.basename(file_path), self.file_name_pattern) ): do_observation = False if do_observation: # do the observation self.observe(file_path) if os.path.isdir(file_path): try: for f in os.listdir(file_path): full_file_path = os.path.join(file_path, f) if os.path.isdir(full_file_path) or ( look_for_hdf5_file and h5py.is_hdf5(full_file_path) ): # parse files to check if some observations should be done process_observations(full_file_path) except Exception: pass if self._firstRun or ( self.restartEvent is not None and self.restartEvent.isSet() ): self._firstRun = False if self.restartEvent: self.restartEvent.clear() if not os.path.isdir(self.headDir): logger.warning("can't observe %s, not a directory" % self.headDir) return self._check_scans_ready() # pylint: disable=E1101 self.dataWatcherProcess = self._getDataWatcherProcess() process_observations(self.headDir) self._processObservation() self._check_scans_ready() # pylint: disable=E1101 else: time.sleep(0.5) def _processObservation(self): threads = list(self.observations.dict.values()) for thread in threads: thread.start() def quit(self): threads = list(self.observations.dict.values()) for thread in threads: thread.quitting = True if self.dataWatcherProcess is not None: self.dataWatcherProcess.quitting = True self.lastObsDir = None def setUnixFileNamePattern(self, pattern): self.file_name_pattern = pattern def setObservationMethod(self, obsMeth, info=None): """ Set if we are looking for the .xml file from .edf observation or any .hdf5 file :param or tuple obsMeth: :param info: some extra information needed for some observation method """ assert info is None or type(info) is dict assert type(obsMeth) in (tuple, str) if type(obsMeth) is str: self.obsMethod = obsMeth if self.obsMethod == datawatcherstatus.DET_END_USER_ENTRY: assert "pattern" in info self._patternObs = info["pattern"] else: self._patternObs = None else: assert len(obsMeth) > 0 assert type(obsMeth[0]) is str self.obsMethod = obsMeth[0] if self.obsMethod == datawatcherstatus.DET_END_USER_ENTRY: assert len(obsMeth) == 2 assert type(obsMeth[1]) is dict assert "pattern" in obsMeth[1] self._patternObs = obsMeth[1]["pattern"] else: self._patternObs = None for _, thread in self.observations.dict.items(): thread.setObservationMethod(obsMeth, info=info) def setHeadFolder(self, headDir): assert type(headDir) in (type(None), str) self.headDir = headDir def setSourceToDestinationPatterns(self, srcPattern, destPattern): """set the patterns to replace strings sequence in directories path. For example during acquisition in md05 acquisition files are stored in /lbsram/data/visitor/x but some information (as .info) files are stored in /data/visitor/x. So we would like to check information in both directories. Furthermore we would like that all file not in /data/visitor/x will be copied as soon as possible into /data/visitor/x (using RSyncManager) To do so we can define a srcPattern ('/lbsram' in our example) and destPattern : a string replacing to srcPattern in order to get both repositories. ('' in out example) If srcPattern or destPattern are setted to None then we won't apply this 'two directories' synchronization and check :param srcPattern: the pattern to change by destPattern. :param destPattern: the pattern that will replace srcPattern in the scan path """ self.srcPattern = srcPattern self.destPattern = destPattern for _, thread in self.observations.items(): thread.setSourceToDestinationPatterns(self.srcPattern, self.destPattern) def observe(self, scanID): self.observations.add(self._getObserver(scanID)) # pylint: disable=E1101 def cancelObservation(self, scanID): if self.observations.isObserving(scanID) is False: logger.warning( "Can't cancel observation on %s, no observation " "registred" % scanID ) return self.observations.ignoredFolders.append(scanID) if scanID in self.observations.dict: self.observations.remove(self.observations.dict[scanID]) def isObserve(self, scanID): return self.observations.isObserving(scanID) def _getDataWatcherProcess(self): if self.obsMethod == datawatcherstatus.NXtomo_END: return _DataWatcherProcessHDF5( dataDir=self.headDir, srcPattern=self.srcPattern, destPattern=self.destPattern, ) elif self.obsMethod == datawatcherstatus.BLISS_SCAN_END: return _BlissScanWatcherProcess( dataDir=self.headDir, srcPattern=self.srcPattern, destPattern=self.destPattern, ) elif EDFTomoScan.directory_contains_scan( self.headDir, src_pattern=self.srcPattern, dest_pattern=self.destPattern ): if self.obsMethod == datawatcherstatus.DET_END_XML: return _DataWatcherProcessXML( dataDir=self.headDir, srcPattern=self.srcPattern, destPattern=self.destPattern, ) elif self.obsMethod == datawatcherstatus.PARSE_INFO_FILE: return _DataWatcherProcessParseInfo( dataDir=self.headDir, srcPattern=self.srcPattern, destPattern=self.destPattern, ) elif self.obsMethod == datawatcherstatus.DET_END_USER_ENTRY: return _DataWatcherProcessUserFilePattern( dataDir=self.headDir, srcPattern=self.srcPattern, destPattern=self.destPattern, pattern=self._patternObs, ) else: return _DataWatchEmpty( dataDir=self.headDir, srcPattern=self.srcPattern, destPattern=self.destPattern, ) class _DataWatcherObserver(_DataWatcherObserver_MixIn, LoopThread): """DataWatcherObserver using Threads""" scanReadyEvent = threading.Event() """Event set when at least one new scan is found""" def __init__( self, obsMethod, time_between_loops, observationClass, headDir=None, startByOldest=False, srcPattern=None, destPattern=None, ignoredFolders=None, ): LoopThread.__init__(self, time_between_loops=time_between_loops) _DataWatcherObserver_MixIn.__init__( self, obsMethod=obsMethod, observationClass=observationClass, headDir=headDir, startByOldest=startByOldest, srcPattern=srcPattern, destPattern=destPattern, ignoredFolders=ignoredFolders, time_between_loops=time_between_loops, ) def _check_scans_ready(self): with self.observations.lock: if self.observations.scanReadyEvent.isSet(): for scanReady in self.observations._latestScanReady: self._signalScanReady(scanID=scanReady) self.observations.scanReadyEvent.clear() self.observations._latestScanReady.clear() def _signalScanReady(self, scanID): with self.lock: self.scanReadyEvent.set() self.latestScanReady.append(scanID) def _getObserver(self, scanID): return _DataWatcherStaticObserver( scanID=scanID, obsMethod=self.obsMethod, srcPattern=self.srcPattern, destPattern=self.destPattern, patternObs=self._patternObs, observationRegistry=self.observations, ) def waitForObservationFinished(self, timeOut=10): threads = list(self.observations.dict.values()) for thread in threads: if thread.is_alive(): thread.join(timeOut) class _OngoingObservation(object): """ Simple container of observed directory """ scanReadyEvent = threading.Event() """Event set a finished acquisition is detected""" obsAddedEvent = threading.Event() """Event set when an observation is added""" obsRemovedEvent = threading.Event() """Event set when an observation is removed""" obsStatusReceivedEvent = threading.Event() """Event set when receiving a new observation status""" def __init__(self): self.dict = OrderedDict() """keys are path, value are observers""" self.ignoredFolders = [] self.lock = threading.Lock() self._latestObsEnded = [] """list of latest observation with scan""" self._latestObsAdded = [] """list of latest removed observations with scan""" self._latestObsStatusChanged = [] """list of latest modify observation with (scan, status)""" self._latestScanReady = [] """list of latest scan ready""" def add(self, observer): if self.isObserving(observer.path) is False: with self.lock: assert isinstance(observer, _DataWatcherStaticObserverMixIn) self.dict[observer.path] = observer self.obsAddedEvent.set() self._latestObsEnded.append(observer.path) def remove(self, observer): assert isinstance(observer, _DataWatcherStaticObserverMixIn) if self.isObserving(observer.path) is True: # observer.sigStatusChanged.disconnect(self._updateStatus) observer.quit() del self.dict[observer.path] with self.lock: self.obsRemovedEvent.set() self._latestObsEnded.append(observer.path) def _updateStatus(self, status, scan): if self.isObserving(scan) is True: with self.lock: self.obsStatusReceivedEvent.set() self._latestObsStatusChanged.append( (scan, datawatcherstatus.DICT_OBS_STATUS[status]) ) if status == datawatcherstatus.OBSERVATION_STATUS["acquisition ended"]: self._acquisition_ended(scan) if status in ( datawatcherstatus.OBSERVATION_STATUS["failure"], datawatcherstatus.OBSERVATION_STATUS["aborted"], ): observer = self.dict[scan] self.remove(observer) def _acquisition_ended(self, scanID): with self.lock: self.ignoredFolders.append(scanID) observer = self.dict[scanID] self.remove(observer) # TODO : disconnect the thread and delete it if finisehd # add the scan to the one to ignore. Those ignore # should be removed at each start and stop of the observation with self.lock: self.scanReadyEvent.set() self._latestScanReady.append(scanID) def isObserving(self, scan): return scan in self.dict def reset(self): for scanID, observer in self.dict: # observer.sigStatusChanged.disconnect(self._updateStatus) observer.quit() self.dict = {} def __len__(self): return len(self.dict) def __str__(self): return str(self.dict.keys()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/datawatcher/datawatcherprocess.py0000644000175000017500000001775415153325210027155 0ustar00paynopayno# coding: utf-8 """ This module analyze headDir data directory to detect scan to be reconstructed """ from __future__ import annotations import logging import os import subprocess from glob import glob from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.signal import Signal from .status import OBSERVATION_STATUS logger = logging.getLogger(__name__) try: from tomwer.synctools.rsyncmanager import RSyncManager has_rsync = False except ImportError: logger.warning("rsyncmanager not available") has_rsync = True """ Useful tools """ class _DataWatcherProcess: """ DataWatcherProcess is the process managing the observation of acquisition. Since we want to loop infinitly on a root folder we have to ignore the folder we previously detected. Otherwise if those folders are not removed we will loop infinitly. That is why we now have the ignoredFolders parameter. Example of usage of srcPattern and destPattern: For example during acquisition in md05 acquisition files are stored in /lbsram/data/visitor/x but some information (as .info) files are stored in /data/visitor/x. So we would like to check information in both directories. Furthermore we would like that all file not in /data/visitor/x will be copied as soon as possible into /data/visitor/x (using RSyncManager) To do so we can define a srcPattern ('/lbsram' in our example) and destPattern : a string replacing to srcPattern in order to get both repositories. ('' in out example) If srcPattern or destPattern are setted to None then we won't apply this 'two directories' synchronization and check :param dataDir: Root directory containing data :param waitXML: if True then we will be waiting for the XML of the acquisition to be writted. Otherwise we will look for the .info file and wait until all file will be copied :param srcPattern: the pattern to change by destPattern. :param destPattern: the pattern that will replace srcPattern in the scan path :param list ignoredFolders: the list of folders to ignored on parsing (them and sub folders) """ sigNbDirExplored = Signal(int) """Signal emitted to notice the number of directory at the top level""" sigAdvanceExploration = Signal(int) """signal emitted each time a top level directory is parsed""" sigNewObservation = Signal(tuple) """used to signal a new step on the acquisition (first element of the tuple should be on eof OBSERVATION_STATUS, second element can be extra information to be displayed )""" sigNewInformation = Signal(str) """Signal used to communicate some random information (will originally be displayed in DataWatcherOW)""" INITIAL_STATUS = "not processing" def __init__( self, dataDir: str, srcPattern: str | None = None, destPattern: str | None = None, ): super().__init__() self.RootDir = os.path.abspath(dataDir) self.parsing_dir = os.path.abspath(dataDir) self.oldest = 0 self.curdir = "" self.scan_name = "" self.scan_completed = False self.reconstructed = False self.status = self.INITIAL_STATUS """contains the step of acquisition we are looking for and the status on this step""" self.quitting = False self._removed = None srcPatternInvalid = srcPattern not in [None, ""] and not os.path.isdir( srcPattern ) destPatternInvalid = destPattern not in [None, ""] and not os.path.isdir( destPattern ) if srcPatternInvalid or destPatternInvalid: srcPattern = None destPattern = None self.srcPattern = srcPattern if destPattern is not None else None self.destPattern = destPattern if srcPattern is not None else None def _setStatus(self, status, info=None): assert status in OBSERVATION_STATUS self.status = status if info is None: self.sigNewObservation.emit((status,)) else: self.sigNewObservation.emit((status, info)) def _removeAcquisition(self, scanID, reason): raise NotImplementedError("Base class") def dir_explore(self): """ Explore directory tree until valid .file_info_ext file is found. Tree explored by ascending order relative to directory date depending self.oldest :return: True if the acquisition as started else False """ self.status = "start acquisition" def _sync(self): """Start to copy files from /lbsram/path to path if on lbsram :return: True if the synchronization starts """ if has_rsync: return False if self.srcPattern: assert os.path.isdir(self.srcPattern) or self.srcPattern == "" assert os.path.isdir(self.destPattern) or self.destPattern == "" if self.RootDir.startswith(self.srcPattern): source = os.path.join(self.RootDir, self.parsing_dir) target = source.replace(self.srcPattern, self.destPattern, 1) info = f"Start synchronization between {source} and {target}" self.sigNewInformation.emit(info) target_dirname = os.path.dirname(target) # check if a synchronization is already running, avoid # duplication try: if not RSyncManager().has_active_sync(source, target_dirname): RSyncManager().sync_file(source, target_dirname) except subprocess.TimeoutExpired: # if time out expired, do the synchronization anyway RSyncManager().sync_file(source, target_dirname) return True else: return False def is_data_complete(self): """ Check that data file is found and complete :return: - 0 if the acquisition is no finished - 1 if the acquisition is finished - -1 observation has been stopped """ raise NotImplementedError("_DataWatcherProcess is a pure virtual class") def getCurrentDir(self): """Return the current dircetory parsed absolute path""" return os.path.join(self.RootDir, self.parsing_dir) def _isScanDirectory(self, directory): if EDFTomoScan.directory_contains_scan( directory, src_pattern=self.srcPattern, dest_pattern=self.destPattern ): scan = EDFTomoScan(directory) # keep compatibility EDF: get detector aux = directory.split(os.path.sep) infoname = os.path.join(directory, aux[-1] + EDFTomoScan.INFO_EXT) if self.srcPattern: infoname = infoname.replace(self.srcPattern, self.destPattern, 1) """ assume 1st it is standard info filename """ gd = glob(os.path.join(directory, infoname)) if len(gd) == 0: """ To detect if it is PCO like, check if info filename contains 0000 """ gd = glob(os.path.join(directory, EDFTomoScan.INFO_EXT)) if len(gd) > 0: self.detector = "Dimax" else: return False if scan.is_abort(src_pattern=self.srcPattern, dest_pattern=self.destPattern): self._removeAcquisition( scanID=directory, reason="acquisition aborted by the user" ) # TODO: add a scan.get_status() function to get the acquisition status? self._setStatus("started") return True def is_abort(self): raise NotImplementedError("Base class") class _DataWatchEmpty(_DataWatcherProcess): """A data watcher which just look under sub directories""" def is_data_complete(self): return False def _removeAcquisition(self, scanID, reason): pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/datawatcher/edfdwprocess.py0000644000175000017500000001306715153325210025750 0ustar00paynopayno# coding: utf-8 """ data watcher classes used to define the status of an acquisition for EDF acquisitions """ from __future__ import annotations import logging import os import shutil from glob import glob from tomwer.core.scan.edfscan import EDFTomoScan from .datawatcherprocess import _DataWatcherProcess _logger = logging.getLogger(__name__) try: from tomwer.synctools.rsyncmanager import RSyncManager has_rsync = False except ImportError: _logger.warning("rsyncmanager not available") has_rsync = True class _DataWatcherEDFProcess(_DataWatcherProcess): """ Base class for edf acquisition observation """ XML_EXT = ".xml" SLICE_WC = "slice" INFO_EXT = ".info" FILE_INFO_KEYS = ["TOMO_N", "REF_ON", "REF_N", "DARK_N"] DEFAULT_DETECTOR = "Frelon" DATA_EXT = "0000.edf" def __init__(self, dataDir, srcPattern=None, destPattern=None): super(_DataWatcherEDFProcess, self).__init__( dataDir=dataDir, srcPattern=srcPattern, destPattern=destPattern ) self.expected_dirsize = 0 self.dirsize = 0 self.file_rec_ext = ".rec" # never used def _removeAcquisition(self, scanID, reason): if os.path.exists(scanID) and os.path.isdir(scanID): if self._removed is None: _logger.info(f"removing folder {scanID} because {reason}") if has_rsync: RSyncManager().removeDir(scanID) # avoid multiple removal as removal is asynchronous and might # fail self._removed = scanID else: shutil.rmtree(scanID) def is_abort(self): if os.path.exists(path=self.scan_name): return EDFTomoScan(scan=self.scan_name).is_abort( src_pattern=self.srcPattern, dest_pattern=self.destPattern ) else: return False class _DataWatcherProcessXML(_DataWatcherEDFProcess): """ This method will parse the [scan].info file and look if all .edf file specified in the .info file are recorded and complete. """ def __init__(self, dataDir, srcPattern, destPattern): _DataWatcherEDFProcess.__init__(self, dataDir, srcPattern, destPattern) # hack for acquisition on lbsram: # in this case .info and .xml are in /data instead of /lbsram. To simplify we copy those from /data to /lbsram # not very elegant but as this is expected to be 'legacy code' if self.srcPattern is not None and self.destPattern is not None: for ext in (self.INFO_EXT, self.XML_EXT): aux = self.parsing_dir.split(os.path.sep) file_on_lbsram = os.path.join( self.RootDir, self.parsing_dir, aux[len(aux) - 1] + ext ) file_on_nice = file_on_lbsram.replace( self.srcPattern, self.destPattern, 1 ) if os.path.exists(file_on_nice) and not os.path.exists(file_on_lbsram): try: shutil.copyfile(file_on_nice, file_on_lbsram) except Exception: # in case for example dest pattern doesn't exists pass def is_data_complete(self): self._sync() aux = self.parsing_dir.split(os.path.sep) xmlfilelbsram = os.path.join( self.RootDir, self.parsing_dir, aux[len(aux) - 1] + self.XML_EXT ) if self.srcPattern is None: self.scan_completed = os.path.isfile(xmlfilelbsram) else: xmlfilenice = xmlfilelbsram.replace(self.srcPattern, self.destPattern, 1) self.scan_completed = os.path.isfile(xmlfilenice) or os.path.isfile( xmlfilelbsram ) return self.scan_completed class _DataWatcherProcessUserFilePattern(_DataWatcherEDFProcess): """ This method will look for a specific pattern given by the user. If a file in the given folder exists then we will consider the acquisition ended :param pattern: the pattern we are looking for """ def __init__(self, dataDir, srcPattern, destPattern, pattern): _DataWatcherEDFProcess.__init__(self, dataDir, srcPattern, destPattern) self.pattern = pattern def is_data_complete(self): self._sync() fullPattern = os.path.join(self.getCurrentDir(), self.pattern) self.scan_completed = len(glob(fullPattern)) > 0 return self.scan_completed class _DataWatcherProcessParseInfo(_DataWatcherEDFProcess): """ This method will look for a '[scan].info' pattern """ def __init__(self, dataDir, srcPattern, destPattern): _DataWatcherEDFProcess.__init__(self, dataDir, srcPattern, destPattern) @staticmethod def get_data_size(edfType): if edfType in _DataWatcherProcessParseInfo.TYPES: # pylint: disable=E1101 return _DataWatcherProcessParseInfo.TYPES[edfType] # pylint: disable=E1101 else: return 2 def is_data_complete(self): self._sync() aux = self.parsing_dir.split(os.path.sep) info_file = os.path.join( self.RootDir, self.parsing_dir, aux[len(aux) - 1] + self.INFO_EXT ) if self.srcPattern is None: self.scan_completed = os.path.isfile(info_file) else: infofilenice = info_file.replace(self.srcPattern, self.destPattern, 1) self.scan_completed = os.path.isfile(infofilenice) or os.path.isfile( info_file ) return self.scan_completed ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/datawatcher/hdf5dwprocess.py0000644000175000017500000000323715153325210026036 0ustar00paynopayno# coding: utf-8 """ data watcher classes used to define the status of an acquisition for EDF acquisitions """ from __future__ import annotations import logging import h5py from .datawatcherprocess import _DataWatcherProcess _logger = logging.getLogger(__name__) class _DataWatcherProcessHDF5(_DataWatcherProcess): """ look for hdf5 information """ def __init__(self, dataDir, srcPattern, destPattern): super(_DataWatcherProcessHDF5, self).__init__(dataDir, srcPattern, destPattern) if h5py.is_hdf5(dataDir): self._nxtomo_file = dataDir def _removeAcquisition(self, scanID, reason): _logger.warning( "removing acquisition is not done for hdf5 data watcher " "process" ) def is_data_complete(self): # For now data complete and is abort_is not handled for hdf5 and Nxtomo return True def is_abort(self): # For now data complete and is abort_is not handled for hdf5 and Nxtomo return False class _BlissScanWatcherProcess(_DataWatcherProcess): def __init__(self, dataDir, srcPattern=None, destPattern=None): super().__init__(dataDir, srcPattern, destPattern) if h5py.is_hdf5(dataDir): self._blissScanFile = dataDir def _removeAcquisition(self, scanID, reason): _logger.warning( "remoing acquisition is not done for hdf5 data watcher " "process" ) def is_data_complete(self): # For now data complete and is abort_is not handled for hdf5 and Nxtomo return True def is_abort(self): # For now data complete and is abort_is not handled for hdf5 and Nxtomo return False ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/datawatcher/status.py0000644000175000017500000000333015153325210024573 0ustar00paynopayno# coding: utf-8 from __future__ import annotations # TODO: change this for enum OBSERVATION_STATUS = { "not processing": 0, # data watcher is not doing anything "parsing": 1, # data watcher is parsing folders "none found": 2, # data watcher haven't found anything "starting": 3, # data watcher have found an acquisition starting "started": 4, # data watcher have found an acquisition started "waiting for acquisition ending": 5, # data watcher is waiting for all .edf file to be copied "acquisition ended": 6, # data watcher have found an acquisition completed "acquisition canceled": 7, # data watcher have found an acquisition canceled "failure": -1, # data watcher have encountered an issue. Should be associated with an info describing it "aborted": -2, # if aborted by acquisition } DICT_OBS_STATUS = {} for name, value in OBSERVATION_STATUS.items(): DICT_OBS_STATUS[value] = name " Possible status of a data watcher observation" DET_END_XML = "[scan].xml" """DET_END for detection end. In this case we are looking for the scan.xml file. On it is here then the acquisition is considered ended """ PARSE_INFO_FILE = "[scan].info" """ In this case we will end for the .info to be here and then parse it to know how many .edf file we are waiting for and wait for all of them to be recorded. """ DET_END_USER_ENTRY = "from file pattern" """DET_END for detection end. In this case the user specify the pattern we are looking for """ DET_END_METHODS = (DET_END_XML, PARSE_INFO_FILE, DET_END_USER_ENTRY) """List of option that can notice the end of the acquisition""" BLISS_SCAN_END = "bliss scan - end_time dataset" NXtomo_END = "already converted NXtomo" EDF_SCAN_END = "Any EDF scan" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/emailnotifier.py0000644000175000017500000001052115153325210023610 0ustar00paynopaynoimport platform import os import string from processview.core.manager import ProcessManager try: from ewoksnotify.tasks.email import EmailTask except ImportError: has_ewoksnotify = False else: has_ewoksnotify = True from tomwer.core.process.task import Task from tomwer.core.tomwer_object import TomwerObject from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.volume.volumebase import TomwerVolumeBase from tomwer.core.volume.hdf5volume import HDF5Volume from datetime import datetime from tomwer.version import version as __version class TomoEmailTask( Task, input_names=("tomo_obj", "configuration"), output_names=("tomo_obj",), ): """Dedicated task for tomography and gui approach""" def __init__( self, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None ): super().__init__(varinfo, inputs, node_id, node_attrs, execinfo) if not has_ewoksnotify: raise ImportError( "ewoksnotify not install but required. Please run 'pip install ewoksnotify[full]'" ) def run(self): tomo_obj = self.inputs.tomo_obj configuration = self.inputs.configuration configuration["text"] = format_email_info( configuration.get("text", ""), tomo_obj=tomo_obj ) configuration["subject"] = format_email_info( configuration.get("subject", ""), tomo_obj=tomo_obj ) task = EmailTask(inputs=configuration) task.run() self.outputs.tomo_obj = self.inputs.tomo_obj def _ls_tomo_obj(tomo_obj) -> tuple: """ list information regarding a tomo obj """ if isinstance(tomo_obj, TomwerScanBase): # for tomoscan base use the `path` attribut file_path_to_list = tomo_obj.path elif isinstance(tomo_obj, TomwerVolumeBase): if isinstance(tomo_obj, HDF5Volume): file_path_to_list = os.path.dirname(tomo_obj.url.file_path()) else: file_path_to_list = tomo_obj.url.file_path() else: raise TypeError def get_size(file_path, decimal_places=2) -> str: size = os.path.getsize(file_path) for unit in ("B", "KiB", "MiB", "GiB", "TiB", "PiB"): if size < 1024.0 or unit == "PiB": break size /= 1024.0 return f"{size:.{decimal_places}f} {unit}" return tuple( [ f"{get_size(os.path.join(file_path_to_list, file_path))} - {file_path}" for file_path in os.listdir(file_path_to_list) ] ) def _ls_dataset_state(tomo_obj) -> str: """ list the status of all met processes by the tomo_obj """ states = {} for process in ProcessManager().get_processes(): state = ProcessManager().get_dataset_state( dataset_id=tomo_obj.get_identifier(), process=process, ) if state is not None: states[process] = state return "\n".join( [f"* {process.name}: {state.value}" for process, state in states.items()] ) def format_email_info(my_str: str, tomo_obj: TomwerObject) -> str: """ format `my_str` string. It can contain one of the following keyword: - {tomo_obj_short_id}: tomo_obj 'short id' (calling identifier.short_description) - {tomo_obj_id}: tomo_obj id - {ls_tomo_obj}: ls of the scan folder - {timestamp}: current time - {footnote}: some footnote defined by tomwer - {dataset_processing_states}: list the status of all met processing """ keywords = { "tomo_obj_short_id": tomo_obj.get_identifier().short_description(), "tomo_obj_id": tomo_obj.get_identifier().to_str(), "ls_tomo_obj": "\n".join(_ls_tomo_obj(tomo_obj)), "timestamp": datetime.utcnow().isoformat(timespec="seconds"), "footnote": f"email send by tomwer - {__version} from {platform.node()}", "dataset_processing_states": _ls_dataset_state(tomo_obj), } # filter necessary keywords def get_necessary_keywords(): formatter = string.Formatter() return [field for _, field, _, _ in formatter.parse(my_str) if field] requested_keywords = get_necessary_keywords() def keyword_needed(pair): keyword, _ = pair return keyword in requested_keywords keywords = dict(filter(keyword_needed, keywords.items())) return my_str.format(**keywords) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/nxtomoconcatenate.py0000644000175000017500000000743215153325210024521 0ustar00paynopaynoimport os import logging from tomoscan.series import Series from ewokscore.missing_data import is_missing_data from tomwer.core.process.task import TaskWithProgress from tomwer.core.scan.nxtomoscan import NXtomoScan from nxtomo.application.nxtomo import NXtomo from nxtomomill.utils.nexus import concatenate as nx_concatenate _logger = logging.getLogger(__name__) class ConcatenateNXtomoTask( TaskWithProgress, input_names=( "series", "output_file", "output_entry", "overwrite", ), optional_input_names=( "progress", "serialize_output_data", ), output_names=("data",), ): """ Task used to concatenate a list of NXtomo (NXtomoScan) into a single NXtomo """ def run(self): scans_series = self.inputs.series if is_missing_data(scans_series) or len(scans_series) < 1: raise ValueError("expected at least one nxtomo to be concatenated") elif not isinstance(scans_series, Series): raise TypeError( f"series is expected to be a Series. Get {type(scans_series)}" ) # format output location if necessary output_file = format_output_location( file_path=self.inputs.output_file, series=scans_series ) # cast scan from NXtomoScan to NXtomo def cast_scan_to_nxtomo(obj: NXtomoScan): # convert NXtomoScan to NXtomo as we expect to get NXtomoScan if isinstance(obj, NXtomoScan): return NXtomo().load( file_path=obj.master_file, data_path=obj.entry, ) else: raise TypeError( f"nxtomos are supposed to be instances of {NXtomo} or {NXtomoScan}. Get {type(obj)}" ) scans_series = tuple([cast_scan_to_nxtomo(nxtomo) for nxtomo in scans_series]) # apply concatenation output_nxtomo = nx_concatenate(scans_series) # dump result output_nxtomo.save( file_path=output_file, data_path=self.inputs.output_entry, overwrite=self.inputs.overwrite, ) # cast back nxtomomill NXtomo to NXtomoScan (reference object for tomwer) scan = NXtomoScan( scan=output_file, entry=self.inputs.output_entry, ) if self.get_input_value("serialize_output_data", True): self.outputs.data = scan.to_dict() else: self.outputs.data = scan def format_output_location(file_path, series: Series): """ format possible keys from the location like {scan_dir} or {scan_path} :param: :param: series of NXtomoScan :return: """ if series is None: _logger.warning("scan is !none, enable to format the nabu output location") for scan in series: if not isinstance(scan, NXtomoScan): raise TypeError def get_common_path(): if len(series) == 0: return "" elif len(series) == 1: return os.path.dirname(series[0].master_file) else: return os.path.commonpath( [os.path.dirname(scan.master_file) for scan in series] ) keywords = { "common_path": get_common_path(), } # filter necessary keywords def get_necessary_keywords(): import string formatter = string.Formatter() return [field for _, field, _, _ in formatter.parse(file_path) if field] requested_keywords = get_necessary_keywords() def keyword_needed(pair): keyword, _ = pair return keyword in requested_keywords keywords = dict(filter(keyword_needed, keywords.items())) file_path = file_path.format(**keywords) file_path = os.path.abspath(file_path) return file_path ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/nxtomomill.py0000644000175000017500000001663115153325210023173 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging import os import pathlib from tomoscan.series import Series from nxtomomill import converter as nxtomomill_converter from nxtomomill.models.h52nx import H52nxModel from nxtomomill.models.edf2nx import EDF2nxModel from nxtomomill.converter.hdf5.utils import ( get_default_output_file, ) from tomwer.io.utils.raw_and_processed_data import to_raw_data_path from tomwer.core.process.output import ProcessDataOutputDirMode from tomwer.core.process.task import TaskWithProgress from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.utils.scanutils import format_output_location _logger = logging.getLogger(__name__) class H5ToNxProcess( TaskWithProgress, input_names=("h5_to_nx_configuration",), optional_input_names=( "progress", "bliss_scan", "serialize_output_data", ), output_names=("data", "series"), ): """ Task to convert from a bliss dataset to a nexus compliant dataset """ @staticmethod def deduce_output_file_path(master_file_name, scan, output_dir): master_file_name = os.path.abspath(master_file_name) # step 1: get output dir try: output_dir = ProcessDataOutputDirMode.from_value(output_dir) except ValueError: # case path provided directly output_folder = format_output_location(output_dir, scan=scan) else: if output_dir is ProcessDataOutputDirMode.OTHER: raise ValueError( f"When output dir mode is {ProcessDataOutputDirMode.OTHER} we expect to received the output dir directly" ) if output_dir is ProcessDataOutputDirMode.PROCESSED_DATA_FOLDER: path = pathlib.Path( get_default_output_file(input_file=master_file_name) ) output_folder = str(path.parent) elif output_dir is ProcessDataOutputDirMode.IN_SCAN_FOLDER: output_folder = os.path.dirname(master_file_name) else: raise RuntimeError(f"output dir {output_dir} not handled") # deduce output file from file basename and output directory file_basename = os.path.basename(master_file_name) file_name = os.path.splitext(file_basename)[0] file_name = file_name.replace(".", "_") file_name = file_name.replace(":", "_") output_file_name = file_name + ".nx" return os.path.join(output_folder, output_file_name) def run(self): config = self.inputs.h5_to_nx_configuration if isinstance(config, dict): config = H52nxModel.from_dict(config) elif not isinstance(config, H52nxModel): raise TypeError( f"h5_to_nx_configuration should be a dict or an instance of {H52nxModel}" ) config.bam_single_file = True config.no_master_file = True try: convs = nxtomomill_converter.from_h5_to_nx( configuration=config, progress=self.progress ) except Exception as e: _logger.error(e) return if len(convs) == 0: return series = [] for conv in convs: conv_file, conv_entry = conv scan_converted = NXtomoScan(scan=conv_file, entry=conv_entry) _logger.processSucceed( f"{config.input_file} {config.entries} has been translated to {scan_converted}" ) if self.get_input_value("serialize_output_data", True): data = scan_converted.to_dict() else: data = scan_converted series.append(data) self.outputs.series = Series( name=f"series created from {config.input_file}", iterable=series ) self.outputs.data = series[-1] if len(series) > 0 else None class EDFToNxProcess( TaskWithProgress, input_names=("edf_to_nx_configuration",), optional_input_names=( "progress", "edf_scan", "serialize_output_data", ), output_names=("data",), ): """ Task calling edf2nx in order to insure conversion from .edf to .nx (create one NXtomo to be used elsewhere) """ def run(self): config = self.inputs.edf_to_nx_configuration if isinstance(config, dict): config = EDF2nxModel.from_dict(config) elif not isinstance(config, EDF2nxModel): raise TypeError( f"edf_to_nx_configuration should be a dict or an instance of {EDF2nxModel}" ) os.makedirs(os.path.dirname(config.output_file), exist_ok=True) file_path, entry = nxtomomill_converter.from_edf_to_nx( configuration=config, progress=self.progress ) scan = NXtomoScan(entry=entry, scan=file_path) if self.get_input_value("serialize_output_data", True): self.outputs.data = scan.to_dict() else: self.outputs.data = scan @staticmethod def deduce_output_file_path( folder_path, output_dir: ProcessDataOutputDirMode | str, scan ): try: output_dir = ProcessDataOutputDirMode.from_value(output_dir) except Exception: pass if output_dir is ProcessDataOutputDirMode.OTHER: raise ValueError("if mode is other, we expect 'output_dir' to be the path") elif output_dir in (None, ProcessDataOutputDirMode.IN_SCAN_FOLDER): output_folder = os.path.dirname(folder_path) elif output_dir is ProcessDataOutputDirMode.PROCESSED_DATA_FOLDER: path = pathlib.Path(get_default_output_file(folder_path)) output_folder = str(path.parent) else: # else we expect people to provide output location output_folder = format_output_location(output_dir, scan=scan) return os.path.join(output_folder, os.path.basename(folder_path) + ".nx") def get_default_raw_data_output_file( input_file: str, output_file_extension: str = ".nx" ) -> str: """ Policy: look for any 'RAW_DATA' in file directory. If find any (before any 'PROCESSED_DATA' directory) replace it "RAW_DATA". Then replace input_file by the expected file_extension and make sure the output file is different than the input file. Else append _nxtomo to it. :param input_file: file to be converted from bliss to NXtomo :param output_file_extension: :return: default output file according to policy """ if isinstance(input_file, pathlib.Path): input_file = str(input_file) if not isinstance(input_file, str): raise TypeError( f"input_file is expected to be an instance of str. {type(input_file)} provided" ) if not isinstance(output_file_extension, str): raise TypeError("output_file_extension is expected to be a str") if not output_file_extension.startswith("."): output_file_extension = "." + output_file_extension input_file = os.path.abspath(input_file) input_file_no_ext, _ = os.path.splitext(input_file) output_path = to_raw_data_path(input_file_no_ext) output_file = output_path + output_file_extension if output_file == input_file: # to be safer if the default output file is the same as the input file (if the input file has a .nx extension and not in any 'RAw_DATA' directory) return output_path + "_nxtomo" + output_file_extension else: return output_file ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/scanlist.py0000644000175000017500000000127115153325210022603 0ustar00paynopayno# coding: utf-8 """ This module is used to define a set of folders to be emitted to the next box. """ import logging from tomwer.core.process.task import Task from tomwer.core.utils.scanutils import data_identifier_to_scan logger = logging.getLogger(__name__) class _ScanListPlaceHolder( Task, optional_input_names=("data",), output_names=("data",) ): """For now data can only be a single element and not a list. This must be looked at. Also when part of an ewoks graph 'data' is mandatory which is not the class when part of a orange workflow. Those can be added interactively""" def run(self): self.outputs.data = data_identifier_to_scan(self.inputs.data) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/scanselector.py0000644000175000017500000000056015153325210023450 0ustar00paynopaynofrom ewokscore.task import Task as EwoksTask from tomwer.core.utils.scanutils import data_identifier_to_scan class _ScanSelectorPlaceHolder(EwoksTask, input_names=["data"], output_names=["data"]): """ task to select one or several scan / data to be processed """ def run(self): self.outputs.data = data_identifier_to_scan(self.inputs.data) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/scantransfer.py0000644000175000017500000005745615153325210023474 0ustar00paynopaynofrom __future__ import annotations import fnmatch import logging import os import shutil from tomoscan.esrf.scan.utils import get_unique_files_linked import tomwer.version from tomwer.core.utils.deprecation import deprecated_warning from tomwer.core.process.reconstruction.nabu.settings import NABU_CFG_FILE_FOLDER from tomwer.core.process.reconstruction.nabu.utils import update_cfg_file_after_transfer from tomwer.core.process.task import Task from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.settings import get_dest_path, get_lbsram_path from tomwer.core.signal import Signal from tomwer.core.utils import logconfig from tomwer.core.utils.spec import rebaseParFile from tomwer.core.utils.scanutils import data_identifier_to_scan from tomwer.io.utils import get_linked_files_with_entry from tomwer.core.process.reconstruction.saaxis.saaxis import ( DEFAULT_RECONS_FOLDER as MULTI_COR_DEFAULT_FOLDER, ) from tomwer.core.process.reconstruction.sadeltabeta.sadeltabeta import ( DEFAULT_RECONS_FOLDER as MULTI_DB_DEFAULT_FOLDER, ) logger = logging.getLogger(__name__) try: from tomwer.synctools.rsyncmanager import RSyncManager except ImportError: logger.warning("rsyncmanager not available") has_rsync = False else: has_rsync = True class ScanTransferTask( Task, input_names=("data",), optional_input_names=( "serialize_output_data", "copying", "block", "turn_off_print", "dest_dir", "move", "noRsync", "overwrite", ), output_names=("data",), ): """Manage the copy of scan. .. warning : the destination directory is find out from the file system if /lbsramxxx exists for example... In the case we couldn't found the output directory then we will ask for the user to set it. """ scanready = Signal(TomwerScanBase) """emit when scan ready""" def __init__( self, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None ): super().__init__( varinfo=varinfo, inputs=inputs, node_id=node_id, node_attrs=node_attrs, execinfo=execinfo, ) self.turn_off_print = inputs.get("turn_off_print", False) self._destDir = inputs.get("dest_dir", None) """ output directory if forced. By default based by the env variable 'TARGET_OUTPUT_FOLDER' if exists, else set to '/data/visitor' """ self._copying = inputs.get("copying", False) force_sync = inputs.get("force_sync", None) if force_sync is not None: from tomwer.core.utils.deprecation import deprecated_warning deprecated_warning( type_="Parameter", name="force_sync", reason="Two parameters for the same option", replacement="block", ) else: force_sync = False self._block = self.get_input_value("block", force_sync) self._move = self.get_input_value("move", False) if not isinstance(self._move, bool): raise TypeError("move is expected to be a boolean") self._overwrite = self.get_input_value("overwrite", False) if not isinstance(self._overwrite, bool): raise TypeError("move is expected to be a boolean") self._noRsync = self.get_input_value( "noRsync", False ) # TODO: rename noRsync to no_rsync if not isinstance(self._noRsync, bool): raise TypeError("move is expected to be a boolean") def set_configuration(self, properties): # No properties stored for now if "dest_dir" in properties: self.setDestDir(properties["dest_dir"]) @staticmethod def program_name(): """Name of the program used for this processing""" return "data transfer" @staticmethod def program_version(): """version of the program used for this processing""" return tomwer.version.version @staticmethod def definition(): """definition of the process""" return "transfer data from a folder to another" @staticmethod def getDefaultOutputDir(): """Return the default output dir based on the computer setup""" if "TARGET_OUTPUT_FOLDER" in os.environ: return os.environ["TARGET_OUTPUT_FOLDER"] if os.path.isdir("/data/visitor"): return "/data/visitor" return "" def _process_edf_scan(self, scan, move=False, overwrite=True, noRsync=False): if not isinstance(scan, EDFTomoScan): raise TypeError(f"{scan} is expected to be an instance of {EDFTomoScan}") outputdir = self.getDestinationDir(scan.path) if outputdir is None: return self._pretransfertOperations(scan.path, outputdir) # as we are in the workflow we want this function to be bloking. # so we will not used a thread for folder synchronization # for now rsync is not delaing with overwrite option if not has_rsync or noRsync is True or RSyncManager().has_rsync() is False: logger.info("Can't use rsync, copying files") try: if move is True: self._moveFiles( scanPath=scan.path, outputdir=os.path.dirname(outputdir), overwrite=overwrite, ) else: self._copyFiles( scanPath=scan.path, outputdir=outputdir, overwrite=overwrite ) except shutil.Error as e: raise e else: output_scan = scan._deduce_transfert_scan(outputdir) try: output_scan._update_latest_recons_identifiers( old_path=scan.path, new_path=output_scan.path ) except Exception as e: logger.warning( "Fail to convert url of latest reconstruction. Reason is:" + e ) output_scan.clear_latest_reconstructions() self.__noticeTransfertSuccess(input_scan=scan, output_scan=output_scan) else: source = scan.path if not source.endswith(os.path.sep): source = source + os.path.sep target = outputdir if not target.endswith(os.path.sep): target = target + os.path.sep self._signalCopying(scanID=source, outputdir=target) output_scan = scan._deduce_transfert_scan(outputdir) try: output_scan._update_latest_recons_identifiers( old_path=scan.path, new_path=output_scan.path ) except Exception as e: logger.warning( "Fail to convert url of latest reconstruction. Reason is:" + e ) output_scan.clear_latest_reconstructions() RSyncManager().sync_file( source=source, target=target, wait=self._block, delete=True, callback=self.__noticeTransfertSuccess, callback_parameters=(scan, output_scan), rights=777, ) return output_scan def _get_hdf5_dst_scan(self, bliss_scan_folder_path): if self._destDir is not None: rel_path = os.path.join(*bliss_scan_folder_path.split(os.sep)[-2:]) return os.path.dirname(os.path.join(self._destDir, rel_path)) # try to get outputdir from spec scanIDPath = os.path.abspath(bliss_scan_folder_path) return self._getOutputDirSpec() or os.path.join( *self._getOutputDirLBS(scanIDPath).split(os.sep)[:-1] ) def _get_hdf5_sample_file_or_nx_dst(self, bliss_sample_file): bliss_sample_file = os.path.abspath(bliss_sample_file) if self._destDir is not None: rel_path = os.path.join(*bliss_sample_file.split(os.sep)[-2:]) return os.path.join(self._destDir, rel_path) # try to get outputdir from spec bliss_sample_file = os.path.abspath(bliss_sample_file) return self._getOutputDirSpec() or self._getOutputDirLBS(bliss_sample_file) def _get_master_sample_file_dst(self, master_sample_file): if self._destDir is not None: rel_path = os.path.join(*master_sample_file.split(os.sep)[-2:]) return os.path.join(self._destDir, rel_path) # try to get outputdir from spec master_sample_file = os.path.abspath(master_sample_file) return self._getOutputDirSpec() or self._getOutputDirLBS(master_sample_file) def _get_hdf5_proposal_file_dst(self, bliss_proposal_file): if self._destDir is not None: return os.path.join(self._destDir, os.path.split(bliss_proposal_file)[-1]) # try to get outputdir from spec bliss_sample_file = os.path.abspath(bliss_proposal_file) return self._getOutputDirSpec() or self._getOutputDirLBS(bliss_sample_file) def _process_hdf5_scan(self, scan) -> TomwerScanBase: assert isinstance(scan, NXtomoScan) logger.warning( "scan transfer for HDF5 is a prototype. Please check transfer is properly executed." ) files_sources = [] files_dest = [] delete_opt = [] associated_files = get_unique_files_linked(url=scan.get_detector_url()) associated_files = filter( lambda file_: os.path.abspath(file_) == os.path.abspath(scan.master_file), associated_files, ) # manage .nx file if os.path.exists(scan.master_file): ( new_nx_file, files_sources_for_nx, files_dest_for_nx, ) = self.handle_nexus_file(scan.master_file, scan.entry) files_sources.extend(files_sources_for_nx) files_dest.extend(files_dest_for_nx) delete_opt.append([True] * len(files_dest_for_nx)) files_sources.append(scan.master_file) files_dest.append(new_nx_file) delete_opt.append(True) output_scan = NXtomoScan(scan=new_nx_file, entry=scan.entry) else: output_scan = None # manage files generated (*slice*.h5/edf, *.cfg, *.par...) # for reconstructed file, .h5, .edf if there is some conflict at one # point I guess we might need to check file entry ? or rename the file # according to the entry. # manage .par, .cfg and .rec files if any patterns = ["*.par", "*.cfg", "*.rec", "*.log"] # manage *slice*.hdf5 and *slice*.edf files (reconstructed slice) patterns += [ "*slice*.hdf5", "*slice*.h5", "*slice*.jpeg", "*slice*.jpg", "*slice*.tiff", "*slice*.tif", "*slice*.j2k", ] # manage *vol files patterns += [ "*_vol", "*_vol.hdf5", ] # manage nabu and tomwer processes files patterns += [ "*tomwer_processes.h5", "*nabu_processes.hdf5", "steps_file_basename_nabu_sinogram_save_step.hdf5", ] # manage new dark and flat files patterns += [ "*dark.hdf5", "*darks.hdf5", "*flats.hdf5", ] def match_pattern(file_name): file_name = file_name.lower() for pattern in patterns: if fnmatch.fnmatch(file_name, pattern): return True return False dir_name = os.path.dirname(scan.master_file) for file_ in os.listdir(dir_name): if match_pattern(file_name=file_): full_file_path = os.path.join(dir_name, file_) files_sources.append(full_file_path) files_dest.append(self._get_hdf5_sample_file_or_nx_dst(full_file_path)) delete_opt.append(True) # manage folders patterns = [ NABU_CFG_FILE_FOLDER, "*slice*", MULTI_COR_DEFAULT_FOLDER, MULTI_DB_DEFAULT_FOLDER, "steps_file_basename_nabu_sinogram_save_step", ] for folder_ in os.listdir(dir_name): if match_pattern(file_name=folder_): full_file_path = os.path.join(dir_name, folder_) files_sources.append(full_file_path) # don't know why we need this os.sep ? call another get dest ? # os.path.join(os.sep, self._get_hdf5_dst_scan(full_file_path), folder_) dest = os.path.join(os.sep, self._get_hdf5_dst_scan(full_file_path)) files_dest.append(dest) delete_opt.append(True) RSyncManager().sync_files( sources=files_sources, targets=files_dest, wait=self._block, delete=delete_opt, callback=self.__noticeTransfertSuccess, callback_parameters=(scan, output_scan), ) return output_scan def handle_nexus_file(self, src_nexus_file: str, entry: str) -> tuple: """ Return a tuple of three elemts: src_nexus_file, files_sources_for_nx, files_dest_for_nx :param src_nexus_file: source file to treat :return: (dst_nexus_file, files_sources_for_nx, files_dest_for_nx) * dst_nexus_file: str -> output nexus file that will be created by the transfer * list files_sources_for_nx: list of relative files connected to source nexus file * files_dest_for_nx: list of creating files from files_sources_for_nx once transfer is accomplish """ dst_nx_file = self._get_hdf5_sample_file_or_nx_dst(src_nexus_file) linked_datasets_src = get_linked_files_with_entry( hdf5_file=src_nexus_file, entry=entry ) linked_files_src = list(map(lambda x: x[0], linked_datasets_src)) relative_linked_files_src = list( filter(lambda file_path: not os.path.isabs(file_path), linked_files_src) ) relative_linked_files_dst = [ os.path.normpath(os.path.join(os.path.dirname(dst_nx_file), file_path)) for file_path in relative_linked_files_src ] relative_linked_files_src = [ os.path.normpath(os.path.join(os.path.dirname(src_nexus_file), file_path)) for file_path in relative_linked_files_src ] return dst_nx_file, relative_linked_files_src, relative_linked_files_dst def run(self): """Launch the process process :param scan: the path to the file we want to move/process :param move: if True, directly move the files. Otherwise copy the files :param overwrite: if True then force the copy even if the file/folder already exists :param noRSync: True if we wan't do sue shutil instead of rsync. """ scan = data_identifier_to_scan(self.inputs.data) if scan is None: raise ValueError("'scan' should be provided") if scan is None: self.outputs.data = None _scan = scan if type(_scan) is dict: _scan = ScanFactory.create_scan_object_frm_dict(scan) assert isinstance(_scan, TomwerScanBase) logger.info("synchronisation with scanPath") if isinstance(scan, EDFTomoScan): output_scan = self._process_edf_scan( scan=scan, move=self._move, overwrite=self.get_input_value("overwrite", True), noRsync=self._noRsync, ) elif isinstance(scan, NXtomoScan): if self._move is True: raise NotImplementedError("move option not implemented") if self._noRsync is True: raise NotImplementedError("noRsync option not implemented") output_scan = self._process_hdf5_scan(scan=scan) else: raise TypeError("Other scan than EDF or HDF5 are not managed") if self.get_input_value("serialize_output_data", True): self.outputs.data = output_scan.to_dict() else: self.outputs.data = output_scan def _pretransfertOperations(self, scanfolder, outputdir): """Operation to be run before making the transfert of the scan""" self._updateParFiles(scanfolder, outputdir) self._updateNabuConfigFiles(scanfolder, outputdir) def _updateNabuConfigFiles(self, scanfolder, outputdir): nabu_cfg_folder = os.path.join(scanfolder, NABU_CFG_FILE_FOLDER) if os.path.exists(nabu_cfg_folder): for _file in os.listdir(nabu_cfg_folder): try: update_cfg_file_after_transfer( config_file_path=os.path.join(nabu_cfg_folder, _file), old_path=scanfolder, new_path=outputdir, ) except Exception: pass def _updateParFiles(self, scanfolder, outputdir): """Update all path contained in the .par files to fit the new outpudir""" if not os.path.exists(scanfolder): return for _file in os.listdir(scanfolder): if _file.lower().endswith(".par"): rebaseParFile( os.path.join(scanfolder, _file), oldfolder=scanfolder, newfolder=outputdir, ) def __noticeTransfertSuccess(self, input_scan, output_scan): self._signalCopySucceed() logger.processSucceed( f"transfer succeed of {input_scan} to {output_scan}", extra={ logconfig.DOC_TITLE: self._scheme_title, logconfig.FROM: str(input_scan), logconfig.TO: str(output_scan), }, ) self.signalTransfertOk(input_scan=input_scan, output_scan=output_scan) def signalTransfertOk(self, input_scan, output_scan): if input_scan is None or output_scan is None: return assert isinstance(input_scan, TomwerScanBase) assert isinstance(output_scan, TomwerScanBase) self.scanready.emit(output_scan) def _copyFiles(self, scanPath, outputdir, overwrite): """Copying files and removing them""" assert type(scanPath) is str assert type(outputdir) is str assert os.path.isdir(scanPath) # create the destination dir if not os.path.isdir(outputdir): def createDirAndTopDir(_dir): if not os.path.isdir(os.path.dirname(_dir)): createDirAndTopDir(os.path.dirname(_dir)) os.makedirs(_dir) createDirAndTopDir(outputdir) # we can't copy directly the top folder because he is already existing for f in os.listdir(scanPath): file = os.path.join(scanPath, f) fileDest = os.path.join(outputdir, f) if overwrite is True: if os.path.isdir(fileDest): shutil.rmtree(fileDest) if os.path.isfile(fileDest): os.remove(fileDest) if os.path.exists(fileDest): raise FileExistsError(fileDest, "already exists") if os.path.isdir(file): shutil.copytree(src=file, dst=fileDest) else: shutil.copy2(src=file, dst=fileDest) info = "Removing directory at %s" % scanPath logger.info(info) shutil.rmtree(scanPath) info = "sucessfuly removed file at %s !!!" % scanPath logger.info(info) def _moveFiles(self, scanPath, outputdir, overwrite): """Function simply moving files""" assert os.path.isdir(scanPath) logger.debug( "synchronisation with scanPath", extra={logconfig.DOC_TITLE: self._scheme_title}, ) target = os.path.join(outputdir, os.path.basename(scanPath)) if overwrite is True and os.path.isdir(target): shutil.rmtree(target) shutil.move(scanPath, outputdir) def _requestFolder(self): out = None while out is None: out = input("please give the output directory : \n") if not os.path.isdir(out): warning = "given path " + out warning += " is not a directory, please give a valid directory" logger.warning(warning) out = None return out def _getOutputDirSpec(self): return None def _getOutputDirLBS(self, scanPath): if scanPath.startswith(get_lbsram_path()): return scanPath.replace(get_lbsram_path(), get_dest_path(), 1) else: return None def getDestinationDir(self, scanPath, ask_for_output=True): """Return the destination directory. The destination directory is the root directory""" if self._destDir is not None: return os.path.join(self._destDir, os.path.basename(scanPath)) # try to get outputdir from spec scanIDPath = os.path.abspath(scanPath) outputdir = self._getOutputDirSpec() or self._getOutputDirLBS(scanIDPath) if outputdir is None and ask_for_output: outputdir = self._requestFolder() return outputdir def setDestDir(self, dist): """Force the outpudir to dist. :param dist: path to the folder. If None remove overwrite behavior """ self._destDir = dist if self._destDir is not None and os.path.isdir(self._destDir): logger.warning("Given path %s is not a directory" % self._destDir) # some function to print the output in the terminal # def _signalCopying(self, scanID, outputdir): self._copying = True if self.turn_off_print is False: print("######################################") print("###") print("###") print("### copying files ", scanID, " to ", outputdir) print("### ...") info = f"start moving folder from {scanID} to {outputdir}" logger.processStarted(info, extra={logconfig.DOC_TITLE: self._scheme_title}) def _signalCopyFailed(self): self._copying = False if self.turn_off_print is False: print("###") print("### copy failed") print("###") print("######################################") def _signalCopySucceed(self): self._copying = False if self.turn_off_print is False: print("###") print("### copy succeeded") print("###") print("######################################") def isCopying(self): """ :return: True if the folder transfert is actually doing a copy """ return self._copying def setForceSync(self, b): """ :param b: if True then folderTransfert will wait until transfert is done to be released. Otherwise will launch a 'free' thread wich will notice transfert end later. """ self._block = b def getOutput(self, scan): """ :param scan: :return: """ return os.path.join(self.getDestinationDir(scan), os.path.basename(scan)) class ScanTransfer(ScanTransferTask): def __init__( self, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None ): deprecated_warning( name="tomwer.core.process.control.scantransfer.ScanTransfer", type_="class", reason="improve readibility", since_version="1.2", replacement="ScanTransferTask", ) super().__init__(varinfo, inputs, node_id, node_attrs, execinfo) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/scanvalidator.py0000644000175000017500000002207715153325210023624 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging from ewokscore.task import Task as EwoksTask from tomwer.core import settings from tomwer.core.utils.lbsram import is_low_on_memory from tomwer.core.process.task import BaseProcessInfo from tomwer.core.scan.scanbase import TomwerScanBase, _TomwerBaseDock from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.signal import Signal from tomwer.core.utils import logconfig from tomwer.core.utils.scanutils import data_identifier_to_scan logger = logging.getLogger(__name__) class _ScanValidatorPlaceHolder(EwoksTask, input_names=["data"], output_names=["data"]): def run(self): self.outputs.data = data_identifier_to_scan(self.inputs.data) class ScanValidator(BaseProcessInfo): """ Simple workflow locker until the use validate scans :param memReleaserWaitLoop: the time to wait in second between two memory overload if we are in lbsram. """ def __init__(self, memoryReleaser): super().__init__() self._manualValidation = True self._hasToLimitScanBlock = settings.isOnLbsram() self._memoryReleaser = memoryReleaser self._scans = {} """associate scanId (keys) to :class:`.TomoBase` object (value)""" # add callback _loopMemoryReleaserto free memory if necessary on lbsram if self._hasToLimitScanBlock: self._memoryReleaser.finished.connect(self._loopMemoryReleaser) self._memoryReleaser.start() def __del__(self): self._clearMemoryReleaser() def _clearMemoryReleaser(self): if self._memoryReleaser is not None: self._memoryReleaser.should_be_stopped = True self._memoryReleaser.wait(4000) self._memoryReleaser = None def addScan(self, scan): """ Return the index on the current orderred dict :param scan: :return: """ _ftserie = scan if type(scan) is str: _ftserie = ScanFactory.create_scan_object(_ftserie) logger.info(f"Scan {_ftserie} has been added by the Scan validator") self._scans[str(_ftserie)] = _ftserie index = len(self._scans) - 1 self._freeStackIfNeeded() return index def _freeStackIfNeeded(self): # if we are low in memory in lbsram: we will automatically validate the current scan isLowMemoryLbs = is_low_on_memory(settings.get_lbsram_path()) is True if not self.isValidationManual(): self._validateStack() elif isLowMemoryLbs: mess = "low memory, free ScanValidator stack " logger.processSkipped(mess) self._validateStack(filter_="lbsram") def _loopMemoryReleaser(self): """ simple loop using the _memoryReleaser and calling the _freeStackIfNeeded function """ self._freeStackIfNeeded() if self._memoryReleaser and not hasattr( self._memoryReleaser, "should_be_stopped" ): self._memoryReleaser.start() def _validateStack(self, filter_=None): """ :param filter: can be None or 'lbsram' if lbsram will only free scan located on lbsram. Validate all the scans in the stack. """ for scanID in list(self._scans.keys()): scan = self._scans[scanID] if filter_ is None or settings.isOnLbsram(scan): self._validated(scan) def _validateScan(self, scan): """This will validate the ftserie currently displayed :warning: this will cancel the currently displayed reconstruction. But if we are validating a stack of ftserie make sure this is the correct one you want to validate. Execution order in this case is not insured. """ if scan is not None: assert isinstance(scan, TomwerScanBase) self._validated(scan) def _cancelScan(self, scan): """This will cancel the ftserie currently displayed :warning: this will cancel the currently displayed reconstruction. But if we are validating a stack of ftserie make sure this is the correct one you want to validate. Execution order in this case is not insured. """ if scan is not None: assert isinstance(scan, TomwerScanBase) self._canceled(scan) def _redoAcquisitionScan(self, scan): """This will emit a signal to request am acquisition for the current ftSerieReconstruction :warning: this will cancel the currently displayed reconstruction. But if we are validating a stack of ftserie make sure this is the correct one you want to validate. Execution order in this case is not insured. """ if scan is not None: assert isinstance(scan, TomwerScanBase) self._redoacquisition(scan) # ------ callbacks ------- def _validated(self, scan): """Callback when the validate button is pushed""" if scan is not None: assert isinstance(scan, TomwerScanBase) info = f"{str(scan)} has been validated" logger.processEnded( info, extra={ logconfig.DOC_TITLE: self._scheme_title, logconfig.SCAN_ID: str(scan), }, ) self._sendScanReady(scan) # in some case the scan can not be in the _scans # (if the signal) come from an other window that 'scan to treat' if str(scan) in self._scans: del self._scans[str(scan)] def _canceled(self, scan): """Callback when the cancel button is pushed""" if scan is not None: assert isinstance(scan, TomwerScanBase) info = "%s has been canceled" % str(scan) logger.processEnded( info, extra={ logconfig.DOC_TITLE: self._scheme_title, logconfig.SCAN_ID: str(scan), }, ) self._sendScanCanceledAt(scan) # in some case the scan can not be in the _scans # (if the signal) come from an other window that 'scan to treat' if str(scan) in self._scans: del self._scans[str(scan)] self.clear() def _redoacquisition(self, ftserie): """Callback when the redo acquisition button is pushed""" raise NotImplementedError("_redoacquisition not implemented yet") def _changeReconsParam(self, ftserie): """Callback when the change reconstruction button is pushed""" if ftserie is None: return _ftserie = ftserie if type(ftserie) is str: _ftserie = ScanFactory.create_scan_object(_ftserie) if _ftserie.path in self._scans: del self._scans[str(_ftserie)] self._sendUpdateReconsParam(_TomwerBaseDock(tomo_instance=_ftserie)) def setManualValidation(self, b): """if the validation mode is setted to manual then we will wait for user approval before validating. Otherwise each previous and next scan will be validated :paramean b: False if we want an automatic validation """ self._manualValidation = b if not self.isValidationManual(): self._validateStack() def isValidationManual(self): """ :return: True if the validation is waiting for user interaction, otherwise False """ return self._manualValidation def _sendScanReady(self, scan): raise RuntimeError("ScanValidator is a pure virtual class.") def _sendScanCanceledAt(self, scan): raise RuntimeError("ScanValidator is a pure virtual class.") def _sendUpdateReconsParam(self, scan): raise RuntimeError("ScanValidator is a pure virtual class.") def clear(self): scans = list(self._scans.values()) # need to be copy because cancel will update self._scans for scan in scans: self._cancelScan(scan=scan) class ScanValidatorP(ScanValidator): """ For now to avoid multiple inheritance from QObject with the process widgets we have to define two classes. One only for the QObject inheritance. :param memReleaserWaitLoop: the time to wait in second between two memory overload if we are in lbsram. """ scanReady = Signal(TomwerScanBase) """Signal emitted when a scan is ready""" scanCanceledAt = Signal(str) """Signal emitted when a scan has been canceled""" updateReconsParam = Signal(TomwerScanBase) """Signal emitted when a scan need to be reconstructed back with new parameters""" def __init__(self, memoryReleaser=None): ScanValidator.__init__(self, memoryReleaser) def _sendScanReady(self, scan): self.scanReady.emit(scan) def _sendScanCanceledAt(self, scan): self.scanCanceledAt.emit(scan) def _sendUpdateReconsParam(self, scan): self.updateReconsParam.emit(scan) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/singletomoobj.py0000644000175000017500000000105315153325210023634 0ustar00paynopaynofrom tomwer.core.process.task import Task from tomwer.core.utils.scanutils import data_identifier_to_scan class SingleTomoObjProcess( Task, optional_input_names=("tomo_obj",), output_names=("tomo_obj",) ): """For now data can only be a single element and not a list. This must be looked at. Also when part of an ewoks graph 'data' is mandatory which is not the class when part of a orange workflow. Those can be added interactively""" def run(self): self.outputs.tomo_obj = data_identifier_to_scan(self.inputs.tomo_obj) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9171011 tomwer-1.6.17/src/tomwer/core/process/control/tests/0000755000175000017500000000000015153325403021556 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/tests/__init__.py0000644000175000017500000000000015153325210023651 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/tests/test_concatenate_nxtomos.py0000644000175000017500000000420715153325210027241 0ustar00paynopaynoimport os from tomoscan.series import Series from tomwer.core.process.control.nxtomoconcatenate import ( ConcatenateNXtomoTask, format_output_location, ) from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.utils.scanutils import MockNXtomo def test_concatenate_nx_tomo_task(tmp_path): """ test execution of ConcatenateNXtomoTask with two NXtomoScan """ scan_1 = MockNXtomo( scan_path=os.path.join(tmp_path, "scan1"), n_proj=10, n_ini_proj=10, scan_range=180, dim=20, energy=12.3, ).scan scan_2 = MockNXtomo( scan_path=os.path.join(tmp_path, "scan2"), n_proj=10, n_ini_proj=10, scan_range=180, dim=20, energy=12.3, ).scan output_scan_file = os.path.join(tmp_path, "concatenation.nx") assert not os.path.exists(output_scan_file) task = ConcatenateNXtomoTask( inputs={ "series": Series(iterable=[scan_1, scan_2]), "output_file": output_scan_file, "output_entry": "my_entry", "overwrite": False, "serialize_output_data": False, } ) task.run() assert isinstance(task.outputs.data, NXtomoScan) assert os.path.exists(output_scan_file) # note: correct processing of the concatenation is done at nxtomomill def test_format_output_location(): """test behavior of format_output_location""" scan1 = NXtomoScan( "/path/to/scan_1.nx", entry="entry0000", ) scan2 = NXtomoScan( "/path/to/scan_2.nx", entry="entry0001", ) assert ( format_output_location( "{common_path}/concatenate.nx", Series(iterable=[scan1, scan2]) ) == "/path/to/concatenate.nx" ) assert format_output_location( "concatenate.nx", Series("my_serie", [scan1, scan2]) ) == os.path.abspath("concatenate.nx") assert ( format_output_location( "{common_path}/concatenate.nx", Series( iterable=[ scan1, ] ), ) == "/path/to/concatenate.nx" ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/tests/test_email.py0000644000175000017500000000302115153325210024246 0ustar00paynopaynoimport os import numpy from tomwer.core.process.control.emailnotifier import format_email_info, _ls_tomo_obj from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.volume.hdf5volume import HDF5Volume from tomwer.core.utils.scanutils import HDF5MockContext def test__ls_tomo_obj(tmp_path): """simple test of the `_ls_tomo_obj` function""" for i in range(2): open(os.path.join(tmp_path, f"{i}.nx"), "a").close() scan = NXtomoScan( scan=os.path.join(tmp_path, "1.nx"), entry="entry0000", ) assert isinstance(scan, NXtomoScan) assert len(_ls_tomo_obj(scan)) == 2 volume = HDF5Volume( file_path=os.path.join(tmp_path, "myvolume.hdf5"), data_path="myvolume", data=numpy.linspace(0, 10, 100 * 100 * 3).reshape( # pylint: disable=E1121 3, 100, 100 ), ) volume.save() assert len(_ls_tomo_obj(volume)) == 3 def test_format_email_info(tmp_path): """ simple test of formatting some information related to an email """ with HDF5MockContext( scan_path=os.path.join(tmp_path, "test", "scan"), n_proj=100 ) as scan: res = format_email_info( my_str="{tomo_obj_short_id} \n {tomo_obj_id} \n {ls_tomo_obj} \n {timestamp} \n {footnote}", tomo_obj=scan, ) for keyword in ( "{tomo_obj_short_id}", "{tomo_obj_id}", "{ls_tomo_obj}", "{timestamp}", "{footnote}", ): assert keyword not in res ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/tests/test_h52nx_process.py0000644000175000017500000001221415153325210025665 0ustar00paynopaynoimport os from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.process.output import ProcessDataOutputDirMode from tomwer.core.process.control.nxtomomill import ( EDFToNxProcess, H5ToNxProcess, get_default_raw_data_output_file, ) from tomwer.core.utils.scanutils import MockNXtomo, MockEDF from nxtomomill.converter.hdf5.utils import PROCESSED_DATA_DIR_NAME, RAW_DATA_DIR_NAME def test_h52nx_process_deduce_output_file_path(tmp_path): """test H5ToNxProcess.deduce_output_file_path function""" scan_path = str(tmp_path / "path" / RAW_DATA_DIR_NAME / "my_scan") os.makedirs(scan_path) scan = MockNXtomo(scan_path=scan_path, n_proj=0).scan # test H52NXDefaultOutput.PROCESSED_DATA assert H5ToNxProcess.deduce_output_file_path( master_file_name=scan.master_file, scan=scan, output_dir=ProcessDataOutputDirMode.PROCESSED_DATA_FOLDER.value, ) == str(tmp_path / "path" / PROCESSED_DATA_DIR_NAME / "my_scan" / "my_scan.nx") # test H52NXDefaultOutput.NEAR_BLISS_FILE assert H5ToNxProcess.deduce_output_file_path( master_file_name=scan.master_file, scan=scan, output_dir=ProcessDataOutputDirMode.IN_SCAN_FOLDER.value, ) == str(tmp_path / "path" / RAW_DATA_DIR_NAME / "my_scan" / "my_scan.nx") # test providing output dir with some formatting to be done assert H5ToNxProcess.deduce_output_file_path( master_file_name=scan.master_file, scan=scan, output_dir="{scan_parent_dir_basename}/../../toto/{scan_dir_name}", ) == str(tmp_path / "toto" / "my_scan" / "my_scan.nx") # test providing output folder directly assert ( H5ToNxProcess.deduce_output_file_path( master_file_name=scan.master_file, scan=scan, output_dir="/tmp/", ) == "/tmp/my_scan.nx" ) def test_edf2nx_process_deduce_output_file_path(tmp_path): """test EDFToNxProcess.deduce_output_file_path function""" scan_path = str(tmp_path / "path" / RAW_DATA_DIR_NAME / "my_edf_scan") MockEDF( scan_path=scan_path, n_radio=10, n_ini_radio=10, n_extra_radio=0, dim=128, dark_n=1, flat_n=1, ) scan = EDFTomoScan(scan_path) # test NEAR_INPUT_FILE assert EDFToNxProcess.deduce_output_file_path( folder_path=scan_path, output_dir=ProcessDataOutputDirMode.IN_SCAN_FOLDER.value, scan=scan, ) == os.path.join(tmp_path, "path", RAW_DATA_DIR_NAME, "my_edf_scan.nx") # test PROCESSED_DATA assert EDFToNxProcess.deduce_output_file_path( folder_path=scan_path, output_dir=ProcessDataOutputDirMode.PROCESSED_DATA_FOLDER.value, scan=scan, ) == os.path.join(tmp_path, "path", PROCESSED_DATA_DIR_NAME, "my_edf_scan.nx") # test providing output dir with some formatting to be done assert EDFToNxProcess.deduce_output_file_path( folder_path=scan_path, output_dir="{scan_parent_dir_basename}/../../toto/", scan=scan, ) == str(tmp_path / "toto" / "my_edf_scan.nx") # test providing output folder directly assert ( EDFToNxProcess.deduce_output_file_path( folder_path=scan_path, output_dir="/tmp/output", scan=scan, ) == "/tmp/output/my_edf_scan.nx" ) def test_get_default_raw_data_output_file(): """test 'get_default_raw_data_output_file' function""" assert get_default_raw_data_output_file("/tmp/path/file.h5") == "/tmp/path/file.nx" assert ( get_default_raw_data_output_file(f"/tmp/{PROCESSED_DATA_DIR_NAME}/file.h5") == f"/tmp/{RAW_DATA_DIR_NAME}/file.nx" ) assert ( get_default_raw_data_output_file( f"/tmp/path/{PROCESSED_DATA_DIR_NAME}/toto/file.h5" ) == f"/tmp/path/{RAW_DATA_DIR_NAME}/toto/file.nx" ) # note: _RAW_DATA_DIR_NAME part of the path but not a folder assert ( get_default_raw_data_output_file(f"/tmp/path_{RAW_DATA_DIR_NAME}/toto/file.h5") == f"/tmp/path_{RAW_DATA_DIR_NAME}/toto/file.nx" ) # 2. advance test # 2.1 use case: '_RAW_DATA_DIR_NAME' is present twice in the path -> replace the deeper one assert ( get_default_raw_data_output_file( f"/tmp/{PROCESSED_DATA_DIR_NAME}/path/{RAW_DATA_DIR_NAME}/toto/file.h5" ) == f"/tmp/{PROCESSED_DATA_DIR_NAME}/path/{RAW_DATA_DIR_NAME}/toto/file.nx" ) # 2.2 use case: contains both '_RAW_DATA_DIR_NAME' and '_PROCESSED_DATA_DIR_NAME' in the path assert ( get_default_raw_data_output_file( f"/tmp/{PROCESSED_DATA_DIR_NAME}/path/{RAW_DATA_DIR_NAME}/toto/file.h5" ) == f"/tmp/{PROCESSED_DATA_DIR_NAME}/path/{RAW_DATA_DIR_NAME}/toto/file.nx" ) assert ( get_default_raw_data_output_file( f"/tmp/{RAW_DATA_DIR_NAME}/path/{PROCESSED_DATA_DIR_NAME}/toto/file.h5" ) == f"/tmp/{RAW_DATA_DIR_NAME}/path/{RAW_DATA_DIR_NAME}/toto/file.nx" ) # 2.3 use case: expected output file is the input file. Make sure append '_nxtomo' assert ( get_default_raw_data_output_file("/tmp/path/file.nx") == "/tmp/path/file_nxtomo.nx" ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/timer.py0000644000175000017500000000441015153325210022101 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging import time from tomwer.core.process.task import Task from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils.scanutils import data_identifier_to_scan from tomwer.core.utils.deprecation import deprecated_warning, deprecated _logger = logging.getLogger(__name__) class TimerTask( Task, input_names=("data", "wait"), output_names=("data",), optional_input_names=("serialize_output_data",), ): """ Simple timer / time out - function """ def __init__( self, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None ): Task.__init__( self, varinfo=varinfo, inputs=inputs, node_id=node_id, node_attrs=node_attrs, execinfo=execinfo, ) if inputs is None: inputs = {} @property @deprecated(replacement="task.wait", since_version="1.2") def waiting_time(self): return self.inputs.wait @waiting_time.setter @deprecated(replacement="task.wait", since_version="1.2") def waiting_time(self, wait): self.inputs.wait = wait def run(self): scan = data_identifier_to_scan(self.inputs.data) if type(scan) is dict: scan = ScanFactory.create_scan_object_frm_dict(scan) else: scan = scan if not isinstance(scan, TomwerScanBase): raise TypeError( f"scan is expected to be a dict or an instance of TomwerScanBase. Not {type(scan)}" ) time.sleep(self.inputs.wait) if self.get_input_value("serialize_output_data", True): self.outputs.data = scan.to_dict() else: self.outputs.data = scan class Timer(TimerTask): def __init__( self, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None ): deprecated_warning( name="tomwer.core.process.control.timer.Timer", type_="class", reason="improve readibility", since_version="1.2", replacement="TimerTask", ) super().__init__(varinfo, inputs, node_id, node_attrs, execinfo) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/tomoobjseries.py0000644000175000017500000000041215153325210023643 0ustar00paynopaynofrom ewokscore.task import Task as EwoksTask class _TomoobjseriesPlaceHolder( EwoksTask, input_names=["series"], output_names=["series"] ): """ task to define a tomography 'serie' """ def run(self): self.outputs.s = self.inputs.series ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/control/volumeselector.py0000644000175000017500000000056215153325210024035 0ustar00paynopaynofrom ewokscore.task import Task as EwoksTask from tomwer.core.utils.scanutils import data_identifier_to_scan class _VolumeSelectorPlaceHolder( EwoksTask, input_names=["volume"], output_names=["volume"] ): """ task to select a volume or a set of volumes """ def run(self): self.outputs.volume = data_identifier_to_scan(self.inputs.volume) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9171011 tomwer-1.6.17/src/tomwer/core/process/drac/0000755000175000017500000000000015153325403017645 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/drac/__init__.py0000644000175000017500000000000015153325210021740 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/drac/binning.py0000644000175000017500000000236715153325210021647 0ustar00paynopaynoimport numpy from enum import Enum as _Enum class Binning(_Enum): ONE_BY_ONE = "1x1" TWO_BY_TWO = "2x2" FOUR_BY_FOUR = "4x4" HEIGHT_BY_HEIGHT = "8x8" SIXTEEN_BY_SIXTEEN = "16x16" THIRTY_TWO_BY_THIRTY_TWO = "32x32" SIXTY_FOUR_BY_SIXTY_FOUR = "64x64" ONE_HUNDRED_TWENTY_HEIGHT_BY_ONE_HUNDRED_TWENTY_HEIGHT = "128x128" @staticmethod def _bin_data(data, binning): if not isinstance(data, numpy.ndarray): raise TypeError("data should be a numpy array") if not data.ndim == 2: raise ValueError("data is expected to be 2d") binning = Binning(binning) if binning is Binning.ONE_BY_ONE: return data elif binning is Binning.TWO_BY_TWO: return data[::2, ::2] elif binning is Binning.FOUR_BY_FOUR: return data[::4, ::4] elif binning is Binning.HEIGHT_BY_HEIGHT: return data[::8, ::8] elif binning is Binning.SIXTEEN_BY_SIXTEEN: return data[::16, ::16] elif binning is Binning.THIRTY_TWO_BY_THIRTY_TWO: return data[::32, ::32] elif binning is Binning.SIXTY_FOUR_BY_SIXTY_FOUR: return data[::64, ::64] else: raise NotImplementedError ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/drac/dracbase.py0000644000175000017500000001312015153325210021754 0ustar00paynopaynofrom __future__ import annotations import os import numpy import logging import pathlib from PIL import Image from silx.io.url import DataUrl from .binning import Binning from .output import OutputFormat from tomoscan.utils.io import filter_esrf_mounting_points from tomoscan.esrf.scan.utils import get_data, from_bliss_original_file_to_raw from tomwer.core.process.drac.output import DATASET_GALLERY_DIR_NAME from tomwer.core.tomwer_object import TomwerObject from tomwer.core.scan.scanbase import TomwerScanBase _logger = logging.getLogger(__name__) __all__ = [ "DracDatasetBase", ] class DracDatasetBase: """ Abstract class for a drac dataset (that should be publish to the data portal). A drac dataset is defined by the following elements: * a directory * metadata """ def __init__(self, data_dir: str, tomo_obj: TomwerObject) -> None: """ :param data_dir: directory containing processed data :param tomo_obj: tomwer object referee for the processing """ data_dir = pathlib.Path(data_dir).resolve() self._data_dir = filter_esrf_mounting_points(str(data_dir)) self._tomo_obj = tomo_obj self._gallery_file_binning = Binning.FOUR_BY_FOUR self._gallery_output_format = OutputFormat.PNG self._gallery_overwrite = True @property def gallery_output_binning(self) -> Binning: "Binning factor to be used when saving gallery images" return self._gallery_file_binning @gallery_output_binning.setter def gallery_output_binning(self, binning: Binning): binning = Binning(binning) self._gallery_file_binning = binning @property def gallery_output_format(self) -> OutputFormat: "Output format of the images stored in the gallery" return self._gallery_output_format @gallery_output_format.setter def gallery_output_format(self, format: OutputFormat): format = OutputFormat(format) self._gallery_output_format = format @property def gallery_overwrite(self) -> bool: return self._gallery_overwrite @gallery_overwrite.setter def gallery_overwrite(self, overwrite: bool) -> None: self._gallery_overwrite = overwrite @property def dataset_name(self) -> str: """ Return the name of the dataset to be given to the drac dataset. A drac dataset is store according to a (dataset_path, dataset_name). By default if several are pushed with the same key, only the most recent one will be stored """ raise NotImplementedError("Base class") def get_gallery_dir(self) -> str: return os.path.join(self.data_dir, DATASET_GALLERY_DIR_NAME) def build_gallery(self): """callback to build the drac-dataset gallery""" pass @property def data_dir(self): return self._data_dir @property def tomo_obj(self): return self._tomo_obj @property def metadata(self) -> dict: raise NotImplementedError("Base class") @property def bliss_raw_datasets(self) -> tuple[str]: raise NotImplementedError("Base class") @staticmethod def from_scan_to_raws(scan: TomwerScanBase) -> tuple[str]: assert isinstance( scan, TomwerScanBase ), f"scan should be an instance of {TomwerScanBase}. Got {type(scan)}" bliss_original_files = scan.get_bliss_original_files() if bliss_original_files is None: bliss_original_files = () return tuple( [ from_bliss_original_file_to_raw(bliss_original_file) for bliss_original_file in bliss_original_files ] ) def to_dict(self): return { "output_dir": self.data_dir, "drac_metadata": self.metadata, } def save_to_gallery( self, output_file_name: str, image: numpy.ndarray | DataUrl, lower_bound: float | None = None, upper_bound: float | None = None, ) -> None: format = self.gallery_output_format overwrite = self.gallery_overwrite binning = self.gallery_output_binning gallery_dir = self.get_gallery_dir() os.makedirs(gallery_dir, exist_ok=True) if isinstance(image, DataUrl): image = get_data(image) if image.ndim == 3 and image.shape[0] == 1: image = image.reshape(image.shape[1:]) elif image.ndim != 2: raise ValueError(f"Only 2D grayscale images are handled. Got {image.shape}") # If both bounds are provided, apply clamping and normalization # If not it will use the min/max of each image if lower_bound is not None and upper_bound is not None: image = numpy.clip(image, lower_bound, upper_bound) image = image - lower_bound image *= 255.0 / (upper_bound - lower_bound) else: min_val, max_val = image.min(), image.max() image = image - min_val if max_val > min_val: # Avoid division by zero if image is constant image *= 255.0 / (max_val - min_val) # Binning the data if required image = Binning._bin_data(data=image, binning=binning) # Convert to a PIL Image and save img = Image.fromarray(image.astype(numpy.uint8), mode="L") if not output_file_name.endswith(f".{format.value}"): output_file_name = output_file_name + f".{format.value}" if not overwrite and os.path.exists(output_file_name): raise OSError(f"File already exists ({output_file_name})") img.save(output_file_name) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/drac/gallery.py0000644000175000017500000001126615153325210021660 0ustar00paynopaynofrom __future__ import annotations import os from nxtomomill.converter.hdf5.utils import PROCESSED_DATA_DIR_NAME, RAW_DATA_DIR_NAME from tomwer.io.utils.raw_and_processed_data import to_processed_data_path from tomwer.core.scan.scanbase import TomwerScanBase from .output import DATASET_GALLERY_DIR_NAME, PROPOSAL_GALLERY_DIR_NAME __all__ = ["deduce_dataset_gallery_location", "deduce_proposal_GALLERY_location"] def deduce_dataset_gallery_location(scan_obj: TomwerScanBase) -> str: """ From scan path deduce the 'dataset' path to the gallery. Warning: dataset gallery is different then the 'proposal' gallery """ if not isinstance(scan_obj, TomwerScanBase): raise TypeError(f"'scan_obj' is expected to be an instance of {TomwerScanBase}") file_path = os.path.abspath(scan_obj.path) split_path = file_path.split(os.sep) # reverse it to find the lower level value of 'PROCESSED_DATA_DIR_NAME' or 'RAW_DATA_DIR_NAME' if by any 'chance' has several in the path # then we will replace the 'lower one' in the string. This is where the GALLERY will be added split_path = split_path[::-1] # check if already contain in a "PROCESSED_DATA" directory try: index_processed_data = split_path.index(PROCESSED_DATA_DIR_NAME) except ValueError: pass index_processed_data = None try: index_raw_data = split_path.index(RAW_DATA_DIR_NAME) except ValueError: # if the value is not in the list index_raw_data = None if index_processed_data is None and index_raw_data is None: # if not in any "PROCESSED_DATA" or "RAW_DATA" directory return scan_obj.get_relative_file( file_name=DATASET_GALLERY_DIR_NAME, with_dataset_prefix=False ) elif index_processed_data is not None and index_raw_data is not None: if index_raw_data > index_processed_data: # if PROCESSED_DATA lower in the path than RAW_DATA split_path[index_processed_data] = RAW_DATA_DIR_NAME # reorder path to original split_path = list(split_path[::-1]) split_path.append(DATASET_GALLERY_DIR_NAME) # move it to PROCESSED_DATA when possible path = os.sep.join(split_path) path = to_processed_data_path(path) return path def deduce_proposal_GALLERY_location(scan_obj: TomwerScanBase) -> str: """ Policy: look if the scan_obj.path is in 'PROCESSED_DATA_DIR_NAME' or 'RAW_DATA_DIR_NAME' directories. If find any (before any 'GALLERY_DIR_NAME' directory) replace it "GALLERY_DIR_NAME". If none of those are found then create it at the same level as the scan :param scan_obj: scan_obj for which we want the GALLERY directory :return: gallery path (to save screenshots for example) """ if not isinstance(scan_obj, TomwerScanBase): raise TypeError(f"'scan_obj' is expected to be an instance of {TomwerScanBase}") file_path = os.path.abspath(scan_obj.path) split_path = file_path.split(os.sep) # reverse it to find the lower level value of 'PROCESSED_DATA_DIR_NAME' or 'RAW_DATA_DIR_NAME' if by any 'chance' has several in the path # then we will replace the 'lower one' in the string. This is where the GALLERY will be added split_path = split_path[::-1] # check if already contain in a "PROCESSED_DATA" directory try: index_processed_data = split_path.index(PROCESSED_DATA_DIR_NAME) except ValueError: pass index_processed_data = None try: index_raw_data = split_path.index(RAW_DATA_DIR_NAME) except ValueError: # if the value is not in the list index_raw_data = None if index_processed_data is None and index_raw_data is None: # if not in any "PROCESSED_DATA" or "RAW_DATA" directory return scan_obj.get_relative_file( file_name=PROPOSAL_GALLERY_DIR_NAME, with_dataset_prefix=False ) elif index_processed_data is not None and index_raw_data is not None: if index_raw_data > index_processed_data: # if PROCESSED_DATA lower in the path than RAW_DATA split_path[index_processed_data] = PROPOSAL_GALLERY_DIR_NAME else: # if RAW_DATA lower in the path than PROCESSED_DATA split_path[index_raw_data] = PROPOSAL_GALLERY_DIR_NAME elif index_raw_data is not None: # if the path contains only PROCESSED_DATA or RAW_DATA (expected behavior for online acquistion) split_path[index_raw_data] = PROPOSAL_GALLERY_DIR_NAME else: assert index_processed_data is not None, "index_processed_data is None" split_path[index_processed_data] = PROPOSAL_GALLERY_DIR_NAME # reorder path to original split_path = split_path[::-1] return os.sep.join(split_path) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/drac/output.py0000644000175000017500000000033715153325210021556 0ustar00paynopaynofrom enum import Enum as _Enum PROPOSAL_GALLERY_DIR_NAME = "GALLERY" DATASET_GALLERY_DIR_NAME = "gallery" class OutputFormat(_Enum): """possible output format to save screenshots""" PNG = "png" JPEG = "jpg" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/drac/processeddataset.py0000644000175000017500000001331715153325210023555 0ustar00paynopaynofrom __future__ import annotations import os import numpy from .dracbase import DracDatasetBase from tomoscan.esrf.volume.singleframebase import VolumeSingleFrameBase from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.volume.volumebase import TomwerVolumeBase from tomwer.core.process.reconstruction.nabu.plane import NabuPlane from tomwer.core.process.reconstruction.output import ( PROCESS_FOLDER_RECONSTRUCTED_VOLUMES, ) from tomwer.core.process.reconstruction.output import ( PROCESS_FOLDER_CAST_VOLUME, ) __all__ = ["DracReconstructedVolumeDataset"] class DracReconstructedVolumeDataset(DracDatasetBase): """ Class to associate reconstructed volume(s) to an drac (processed) dataset """ def __init__(self, tomo_obj: TomwerVolumeBase, source_scan: TomwerScanBase) -> None: if not isinstance(tomo_obj, TomwerVolumeBase): raise TypeError( f"tomo_obj should be an instance of {TomwerVolumeBase}. Got {type(tomo_obj)}" ) super().__init__(tomo_obj=tomo_obj, data_dir=tomo_obj.icat_data_dir) self._n_slices_per_axis = 3 self.__source_scan = source_scan self.__bliss_raw_dataset = self.from_scan_to_raws(scan=self.__source_scan) @staticmethod def make_serializable(obj): """ Recursively convert numpy arrays to lists and replace string "None" with None in a given object. """ if isinstance(obj, dict): return { key: DracReconstructedVolumeDataset.make_serializable(value) for key, value in obj.items() } elif isinstance(obj, (list, tuple)): return [ DracReconstructedVolumeDataset.make_serializable(item) for item in obj ] elif isinstance(obj, numpy.ndarray): return obj.tolist() else: return obj @property def metadata(self) -> dict: assert isinstance(self.tomo_obj, TomwerVolumeBase) metadata = self.tomo_obj.build_drac_metadata() metadata["Sample_name"] = self.source_scan.sample_name return metadata @property def dataset_name(self) -> str: """name to give to the drac (processed) dataset.""" return PROCESS_FOLDER_RECONSTRUCTED_VOLUMES @property def source_scan(self) -> TomwerScanBase: return self.__source_scan @property def bliss_raw_datasets(self) -> tuple[str]: return self.__bliss_raw_dataset @property def n_slices_per_axis(self) -> int: "number of slices to sample per axis" return self._n_slices_per_axis @n_slices_per_axis.setter def n_slices_per_axis(self, n: int) -> None: self._n_slices_per_axis = n def get_slices_to_extract(self) -> tuple[tuple[int, tuple[int]]]: """ Compute the slices to be retrieve along each dimension according to 'n_slices_per_axis' return tuple (A) is a two elements tuple. First element if the axis (B). Second is the tuple of indices to extract along the axis (B) indices are equally spaced in each dimensions """ result: list[tuple[int, tuple[int]]] = [] volume = self.tomo_obj if not isinstance(volume, TomwerVolumeBase): raise TypeError( f"Volume is expected to be an instance of {TomwerVolumeBase}. Got {type(volume)}" ) volume_shape = volume.get_volume_shape() for axis, axis_len in enumerate(volume_shape): for slice_index in numpy.linspace( 0, axis_len, endpoint=False, num=self.n_slices_per_axis + 1 )[1:]: result.append((axis, numpy.round(slice_index).astype(numpy.uint16))) return tuple(result) def build_gallery(self): gallery_dir = self.get_gallery_dir() volume = self.tomo_obj slices = volume.get_slices(slices=self.get_slices_to_extract()) # Stack all slices into a single array to compute the global percentiles all_slices = numpy.concatenate([slice_ for slice_ in slices.values()]) lower_bound = numpy.percentile(all_slices, 0) upper_bound = numpy.percentile(all_slices, 100) for (axis, slice_index), slice_ in slices.items(): self.save_to_gallery( output_file_name=self.get_output_file_name( output_dir=gallery_dir, axis=axis, slice_index=slice_index, volume=volume, ), image=slice_, lower_bound=lower_bound, upper_bound=upper_bound, ) @staticmethod def get_output_file_name( output_dir: str, axis: int, slice_index: int, volume: TomwerVolumeBase ) -> str: axis = NabuPlane.from_value(axis) if isinstance(volume, VolumeSingleFrameBase): basename = volume.get_volume_basename() else: basename = os.path.splitext(os.path.basename(volume.data_url.file_path()))[ 0 ] axis_folder = os.path.join( os.path.abspath(output_dir), str(axis.value), ) os.makedirs(axis_folder, exist_ok=True) # warning: for ordering drac needs to have the axis in a dedicated folder return os.path.join( axis_folder, f"{basename}_capture_{axis.value}_{str(slice_index).zfill(6)}", ) class DracCastReconstructedVolume(DracReconstructedVolumeDataset): """ Class to associate casted - reconstructed volume(s) to an drac (processed) dataset """ @property def dataset_name(self) -> str: """name to give to the drac (processed) dataset.""" return PROCESS_FOLDER_CAST_VOLUME ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/drac/publish.py0000644000175000017500000000740515153325210021667 0ustar00paynopaynofrom __future__ import annotations import logging from tomwer.core.process.task import Task from tomwer.core.process.drac.dracbase import DracDatasetBase from processview.core.manager import DatasetState, ProcessManager try: from pyicat_plus.client.main import IcatClient # noqa F401 except ImportError: has_pyicat_plus = False else: has_pyicat_plus = True _logger = logging.getLogger(__name__) __all__ = [ "PublishICatDatasetTask", ] class PublishICatDatasetTask( Task, input_names=( "data_portal_processed_datasets", "beamline", "proposal", "dataset", ), optional_input_names=( "dry_run", "__process__", ), ): """ publish a list of 'IcatDataBase' instances. `IcatDataBase` provide API to retrieve data and metadata to be publish input field: * data_portal_processed_datasets: list of 'DracDatasetBase' instances. * beamline: name of the beamline (bm05, id19...) * proposal: proposal name """ def run(self): for icat_data in self.inputs.data_portal_processed_datasets: if not isinstance(icat_data, DracDatasetBase): raise TypeError(f"icat_data should be an instance of {DracDatasetBase}") # build gallery (if needed by the icat data) process = self.get_input_value("__process__", None) if process is not None and icat_data.tomo_obj is not None: ProcessManager().notify_dataset_state( dataset=icat_data.tomo_obj, process=process(), state=DatasetState.ON_GOING, ) icat_data.build_gallery() try: self.publish_to_data_portal( path=icat_data.data_dir, metadata=icat_data.metadata, raw=icat_data.bliss_raw_datasets, dataset=icat_data.dataset_name, ) except Exception as e: if process is not None and icat_data.tomo_obj is not None: ProcessManager().notify_dataset_state( dataset=icat_data.tomo_obj, process=process(), state=DatasetState.FAILED, ) raise e else: if process is not None and icat_data.tomo_obj is not None: ProcessManager().notify_dataset_state( dataset=icat_data.tomo_obj, process=process(), state=DatasetState.SUCCEED, ) def publish_to_data_portal(self, path: str, metadata: dict, raw: str, dataset: str): """publish path to data_portal (drac) with given metadata""" if not self.inputs.dry_run: if not has_pyicat_plus: raise RuntimeError( "pyicat_plus not installed it. Please install it to be able to publish dataset to icat" ) icat_client = IcatClient( metadata_urls=("bcu-mq-01.esrf.fr:61613", "bcu-mq-02.esrf.fr:61613") ) _logger.info( "publish to icat: %s", { "path": path, "beamline": self.inputs.beamline, "proposal": self.inputs.proposal, "raw": raw, "dataset": dataset, "metadata": metadata, }, ) icat_client.store_processed_data( beamline=self.inputs.beamline, proposal=self.inputs.proposal, dataset=dataset, path=path, metadata=metadata, raw=raw, ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/drac/rawdataset.py0000644000175000017500000001206715153325210022360 0ustar00paynopaynofrom __future__ import annotations import numpy import os import shutil from .dracbase import DracDatasetBase from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.hdf5scan import HDF5TomoScan from tomoscan.esrf.scan.utils import from_bliss_original_file_to_raw from tomwer.core.utils.dictutils import concatenate_dict from tomwer.io.utils.raw_and_processed_data import to_raw_data_path __all__ = [ "DracRawDataset", ] class DracRawDataset(DracDatasetBase): """ Class to associate a raw dataset (TomwerScanBase) to an icat (raw) dataset """ def __init__( self, tomo_obj: TomwerScanBase, raw_darks_required: bool = True, raw_flats_required: bool = True, raw_projections_required: bool = True, raw_projections_each: float = 90, ) -> None: if not isinstance(tomo_obj, TomwerScanBase): raise TypeError( f"tomo_obj should be an instance of {TomwerScanBase}. Got {type(tomo_obj)}" ) data_dir = DracRawDataset.get_data_dir(scan=tomo_obj) super().__init__(data_dir=data_dir, tomo_obj=tomo_obj) self.__raw_darks_required = raw_darks_required self.__raw_flats_required = raw_flats_required self.__raw_projections_each = raw_projections_each self.__raw_projections_required = raw_projections_required @property def metadata(self) -> dict: scan = self.tomo_obj assert isinstance(scan, TomwerScanBase) if scan is not None: return scan.build_drac_metadata() else: return {} @property def bliss_raw_datasets(self) -> tuple[str]: return super().from_scan_to_raws(scan=self.tomo_obj) @property def raw_darks_required(self) -> bool: return self.__raw_darks_required @property def raw_flats_required(self) -> bool: return self.__raw_flats_required @property def raw_projections_each(self) -> float: return self.__raw_projections_each @property def raw_projections_required(self) -> bool: return self.__raw_projections_required def build_gallery(self): if os.path.exists(self.get_gallery_dir()): if self.gallery_overwrite: shutil.rmtree(self.get_gallery_dir()) else: raise RuntimeError( f"Gallery output dir ({self.get_gallery_dir()} already exists and cannot overwrite it.)" ) scan = self.tomo_obj # collect all the data to be saved data_to_save: dict[str, numpy.ndarray] = {} if self.raw_darks_required and len(scan.darks) > 0: data_to_save["dark"] = next(iter(scan.darks.values())) if self.raw_flats_required and len(scan.flats) > 0: data_to_save["flat"] = next(iter(scan.flats.values())) if self.raw_projections_required: projections = scan.projections_with_angle() picked_angles = DracRawDataset.select_angles( angles_list=sorted(projections.keys()), each_angle=self.raw_projections_each, ) data_to_save = concatenate_dict( data_to_save, { f"projection_{angle:.1f}": projections[angle] for angle in picked_angles }, ) # dump to disk for img_name, img_data in data_to_save.items(): self.save_to_gallery( output_file_name=os.path.join(self.get_gallery_dir(), img_name), image=img_data, ) @staticmethod def select_angles(angles_list: tuple, each_angle: int) -> tuple: angles_list = sorted(angles_list) if len(angles_list) > 0: start_angle = angles_list[0] stop_angle = angles_list[-1] picked_angle = numpy.arange(start_angle, stop_angle + 1, step=each_angle) return tuple( [ DracRawDataset.get_closest_projection(angle, angles_list) for angle in picked_angle ] ) else: return tuple() @staticmethod def get_closest_projection(angle, angles_list): idx_closest = numpy.argmin(numpy.abs(angles_list - angle)) return angles_list[idx_closest] @staticmethod def get_data_dir(scan: HDF5TomoScan) -> str | None: """Deduce (bliss) data directory from a scan. If the scan can get the information from 'get_bliss_original_files' then we use it as this is most reliable information. Else we use the nxtomo location as a fallback (in case the data doesn't comes from bliss for example). """ # the most reliable way is to get it from 'get_bliss_original_files' as this is set during conversion # else raw_data_file = scan.get_bliss_original_files() if scan.master_file is None: return None else: raw_data_file = to_raw_data_path(scan.master_file) return from_bliss_original_file_to_raw(os.path.dirname(raw_data_file)) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9171011 tomwer-1.6.17/src/tomwer/core/process/drac/tests/0000755000175000017500000000000015153325403021007 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/drac/tests/test_gallery.py0000644000175000017500000000441715153325210024061 0ustar00paynopaynofrom tomwer.core.process.drac.gallery import ( deduce_dataset_gallery_location, deduce_proposal_GALLERY_location, PROPOSAL_GALLERY_DIR_NAME, ) from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.scan.nxtomoscan import NXtomoScan def test_deduce_dataset_gallery_dir(): """test the deduce_gallery_dir function""" assert ( deduce_dataset_gallery_location( NXtomoScan(scan="/path/to/PROCESSED_DATA/my_scan.nx", entry="entry") ) == "/path/to/PROCESSED_DATA/gallery" ) assert ( deduce_dataset_gallery_location( NXtomoScan(scan="/path/to/RAW_DATA/collection/my_scan.nx", entry="entry") ) == "/path/to/PROCESSED_DATA/collection/gallery" ) assert ( deduce_dataset_gallery_location( NXtomoScan(scan="/any/random/path/my_scan.nx", entry="entry") ) == "/any/random/path/gallery" ) assert ( deduce_dataset_gallery_location( EDFTomoScan(scan="/path/to/PROCESSED_DATA/dataset/toto") ) == "/path/to/PROCESSED_DATA/dataset/toto/gallery" ) assert ( deduce_dataset_gallery_location(EDFTomoScan(scan="/path/to/dataset/toto")) == "/path/to/dataset/toto/gallery" ) def test_deduce_proposal_gallery_dir(): """test the deduce_gallery_dir function""" assert ( deduce_proposal_GALLERY_location( NXtomoScan(scan="/path/to/PROCESSED_DATA/my_scan.nx", entry="entry") ) == f"/path/to/{PROPOSAL_GALLERY_DIR_NAME}" ) assert ( deduce_proposal_GALLERY_location( NXtomoScan(scan="/path/to/PROCESSED_DATA/dataset/my_scan.nx", entry="entry") ) == f"/path/to/{PROPOSAL_GALLERY_DIR_NAME}/dataset" ) assert ( deduce_proposal_GALLERY_location( NXtomoScan(scan="/any/random/path/my_scan.nx", entry="entry") ) == f"/any/random/path/{PROPOSAL_GALLERY_DIR_NAME}" ) assert ( deduce_proposal_GALLERY_location( EDFTomoScan(scan="/path/to/PROCESSED_DATA/dataset/toto") ) == "/path/to/GALLERY/dataset/toto" ) assert ( deduce_proposal_GALLERY_location(EDFTomoScan(scan="/path/to/dataset/toto")) == "/path/to/dataset/toto/GALLERY" ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/drac/tests/test_icat_processed_dataset.py0000644000175000017500000000524215153325210027113 0ustar00paynopaynofrom __future__ import annotations import os import pytest import numpy from tomwer.core.process.drac.processeddataset import DracReconstructedVolumeDataset from tomwer.tests.conftest import nxtomo_scan_180 # noqa F811 from tomwer.core.volume.hdf5volume import HDF5Volume from tomwer.core.volume.edfvolume import EDFVolume @pytest.mark.parametrize( "output_dir_use_case", ("default", "change_name", "change_dir") ) @pytest.mark.parametrize("MetaVolumeClass", (HDF5Volume, EDFVolume)) def test_IcatReconstructedVolumeDataset( output_dir_use_case: str, nxtomo_scan_180, MetaVolumeClass, tmp_path # noqa F811 ): if output_dir_use_case == "default": output_dir = os.path.join( os.path.dirname(nxtomo_scan_180.master_file), "reconstructed_volumes" ) elif output_dir_use_case == "change_name": output_dir = os.path.join( os.path.dirname(nxtomo_scan_180.master_file), "my_vols" ) elif output_dir_use_case == "change_dir": output_dir = tmp_path / "test" / "reconstructed_volumes" output_dir.mkdir(parents=True) if MetaVolumeClass is HDF5Volume: volume = MetaVolumeClass( file_path=os.path.join(output_dir, "test.hdf5"), data_path="data", ) elif MetaVolumeClass is EDFVolume: volume = MetaVolumeClass(folder=os.path.join(output_dir, "folder")) else: raise NotImplementedError volume.data = numpy.random.random((10, 10, 10)) volume.save() icat_dataset = DracReconstructedVolumeDataset( tomo_obj=volume, source_scan=nxtomo_scan_180 ) gallery_dir = icat_dataset.get_gallery_dir() assert gallery_dir == os.path.join(output_dir, "gallery") assert not os.path.exists(gallery_dir) assert icat_dataset.get_slices_to_extract() == ( (0, 2), (0, 5), (0, 8), (1, 2), (1, 5), (1, 8), (2, 2), (2, 5), (2, 8), ) icat_dataset.build_gallery() assert os.path.exists(gallery_dir) # make sure we have three slice over each direction assert len(os.listdir(gallery_dir)) == 3 assert "XY" in os.listdir(gallery_dir) if MetaVolumeClass is HDF5Volume: assert "test_capture_XY_000008.png" in os.listdir( os.path.join(gallery_dir, "XY") ) assert "test_capture_YZ_000002.png" in os.listdir( os.path.join(gallery_dir, "YZ") ) elif MetaVolumeClass is EDFVolume: assert "folder_capture_XY_000008.png" in os.listdir( os.path.join(gallery_dir, "XY") ) assert "folder_capture_YZ_000002.png" in os.listdir( os.path.join(gallery_dir, "YZ") ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/drac/tests/test_icat_raw_dataset.py0000644000175000017500000000534015153325210025714 0ustar00paynopaynofrom __future__ import annotations import os import pytest import numpy from tomwer.tests.conftest import nxtomo_scan_180 # noqa F811 from tomwer.core.process.drac.rawdataset import DracRawDataset def test_IcatRawDataset(nxtomo_scan_180): # noqa F811 """ test CreateRawDataScreenshotsTask task """ # test nothing requested dataset = DracRawDataset( tomo_obj=nxtomo_scan_180, raw_projections_required=False, raw_darks_required=False, raw_flats_required=False, ) assert not os.path.exists(dataset.get_gallery_dir()) dataset.build_gallery() assert not os.path.exists(dataset.get_gallery_dir()) # test only flat requested dataset = DracRawDataset( tomo_obj=nxtomo_scan_180, raw_projections_required=False, raw_darks_required=False, raw_flats_required=True, ) dataset.build_gallery() assert len(os.listdir(dataset.get_gallery_dir())) == 1 # test only dark requested dataset = DracRawDataset( tomo_obj=nxtomo_scan_180, raw_projections_required=False, raw_darks_required=True, raw_flats_required=False, ) dataset.gallery_overwrite = False with pytest.raises(RuntimeError): dataset.build_gallery() dataset.gallery_overwrite = True dataset.build_gallery() assert len(os.listdir(dataset.get_gallery_dir())) == 1 # test only projection requested dataset = DracRawDataset( tomo_obj=nxtomo_scan_180, raw_projections_required=True, raw_darks_required=False, raw_flats_required=False, ) dataset.gallery_overwrite = True dataset.build_gallery() assert len(os.listdir(dataset.get_gallery_dir())) == 2 # test all requested dataset = DracRawDataset( tomo_obj=nxtomo_scan_180, raw_projections_required=True, raw_darks_required=True, raw_flats_required=True, raw_projections_each=10, ) dataset.gallery_overwrite = True dataset.build_gallery() assert len(os.listdir(dataset.get_gallery_dir())) == 12 def test_select_angles(): """test the select_angles function""" numpy.testing.assert_allclose( DracRawDataset.select_angles( numpy.linspace(start=-20, stop=40, num=201, endpoint=True), each_angle=20 ), numpy.array([-20, 0.1, 19.9, 40]), ) assert DracRawDataset.select_angles((), each_angle=20) == () assert DracRawDataset.select_angles((10,), each_angle=10) == (10,) angles = DracRawDataset.select_angles( numpy.linspace(start=0, stop=10, num=400, endpoint=False), each_angle=1 ) assert len(angles) == 11 assert numpy.isclose(angles[0], 0, atol=0.1) assert numpy.isclose(angles[-1], 10, atol=0.1) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9171011 tomwer-1.6.17/src/tomwer/core/process/edit/0000755000175000017500000000000015153325403017661 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/edit/__init__.py0000644000175000017500000000000015153325210021754 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/edit/darkflatpatch.py0000644000175000017500000000707215153325210023045 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import nxtomomill.version from nxtomomill.utils import add_dark_flat_nx_file from silx.io.url import DataUrl from tomwer.core.utils.deprecation import deprecated_warning, deprecated from tomwer.core.process.task import Task from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.utils.scanutils import data_identifier_to_scan def apply_dark_flat_patch(scan: NXtomoScan, config: dict) -> TomwerScanBase: """ :param scan: :param config: :return: """ if not isinstance(scan, NXtomoScan): raise ValueError( f"Dark and flat patch only manage NXtomoScan and not {type(scan)}" ) if config is None: return scan for param in ("darks_start", "darks_end", "flats_start", "flats_end"): if param not in config: config[param] = None add_dark_flat_nx_file( file_path=scan.master_file, entry=scan.entry, **config, ) return scan class DarkFlatPatchTask( Task, input_names=("data", "configuration"), output_names=("data",), optional_input_names=("serialize_output_data",), ): """ Patch an existing NXtomo calling nxtomomill """ def run(self): scan = data_identifier_to_scan(self.inputs.data) if scan is None: return if not isinstance(scan, TomwerScanBase): raise TypeError( f"scan is expected to be a dict or an instance of TomwerScanBase. Not {type(scan)}" ) if not isinstance(scan, NXtomoScan): raise ValueError(f"input type of {scan}: {type(scan)} is not managed") config = self.inputs.configuration if not isinstance(config, dict): raise TypeError(f"config is expected to be a dict. {type(config)} provided") apply_dark_flat_patch(scan=scan, config=config) keys = config.keys() for key in keys: value = config[key] if isinstance(value, DataUrl): config[key] = value.path() if self.get_input_value("serialize_output_data", True): self.outputs.data = scan.to_dict() else: self.outputs.data = scan @staticmethod def program_name(): return "nxtomomill.utils.change_image_key_control" @staticmethod def program_version(): return nxtomomill.version.version @staticmethod def definition(): return "Apply patch for dark and references on a scan (TomwerScanBase)" @deprecated( since_version="1.2", replacement="DarkFlatPatchTask.inputs.configuration", reason="ewoksification", ) def get_configuration(self): """ :return: configuration of the process """ return self.inputs.configuration @deprecated( since_version="1.2", replacement="DarkFlatPatchTask.inputs.configuration", reason="ewoksification", ) def set_configuration(self, configuration: dict) -> None: self.inputs.configuration = configuration class DarkFlatPatch(DarkFlatPatchTask): def __init__( self, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None ): deprecated_warning( name="tomwer.core.process.edit.darkflatpatch.DarkFlatPatch", type_="class", reason="improve readibility", since_version="1.2", replacement="DarkFlatPatchTask", ) super().__init__(varinfo, inputs, node_id, node_attrs, execinfo) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/edit/imagekeyeditor.py0000644000175000017500000001627315153325210023242 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import copy import logging import nxtomomill.version from nxtomomill.utils import change_image_key_control as _change_image_key_control from nxtomo.nxobject.nxdetector import ImageKey from tomwer.core.utils.deprecation import deprecated_warning, deprecated from tomwer.core.process.task import Task from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.utils.scanutils import data_identifier_to_scan _logger = logging.getLogger(__name__) IMAGE_KEYS = { "projection": ImageKey.PROJECTION, "invalid": ImageKey.INVALID, "dark": ImageKey.DARK_FIELD, "flat": ImageKey.FLAT_FIELD, } def change_image_key_control(scan: NXtomoScan, config: dict) -> TomwerScanBase: """ :param scan: :param config: :raises KeyError: if 'frames_indexes' or 'image_key_control_value' are not in config :return: """ if scan is None: return elif not isinstance(scan, NXtomoScan): raise ValueError( f"Image key control only handle NXtomoScan and not {type(scan)}" ) if "modifications" not in config: raise KeyError("modifications are not provided") else: modifications = config["modifications"] if modifications is None: modifications = {} image_keys_set = set(modifications.values()) image_keys_set = set([ImageKey(image_key) for image_key in image_keys_set]) for image_key_type in image_keys_set: frame_indexes_dict = dict( filter(lambda item: item[1] is image_key_type, modifications.items()) ) frame_indexes = tuple(frame_indexes_dict.keys()) _logger.info(f"will modify {frame_indexes} to {image_key_type}") _change_image_key_control( file_path=scan.master_file, entry=scan.entry, frames_indexes=frame_indexes, image_key_control_value=image_key_type.value, logger=_logger, ) scan.clear_frames_cache() return scan class ImageKeyEditorTask( Task, input_names=("data", "configuration"), output_names=("data",), optional_input_names=("serialize_output_data",), ): """ task to edit `image_key` field of a NXtomo ('data' input) """ def __init__( self, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None ): super().__init__( varinfo=varinfo, inputs=inputs, node_id=node_id, node_attrs=node_attrs, execinfo=execinfo, ) def run(self): scan = data_identifier_to_scan(self.inputs.data) if scan is None: return if not isinstance(scan, TomwerScanBase): raise TypeError( f"scan is expected to be a dict or an instance of TomwerScanBase. Not {type(scan)}" ) if not isinstance(scan, NXtomoScan): raise ValueError(f"input type of {scan}: {(type(scan))} is not managed") config = self.inputs.configuration if not isinstance(config, dict): raise TypeError # apply configuration change_image_key_control(scan=scan, config=config) modif_keys = list(config.get("modifications", {}).keys()) # dump modifications to the tomwer processes file # note: we need to cast image keys to str to save it config = copy.deepcopy(config) new_modif = {} for key in modif_keys: value = config["modifications"][key] config["modifications"][str(key)] = value config["modifications"] = new_modif if self.get_input_value("serialize_output_data", True): self.outputs.data = scan.to_dict() else: self.outputs.data = scan @staticmethod def program_name(): return "nxtomomill.utils.change_image_key_control" @staticmethod def program_version(): return nxtomomill.version.version @staticmethod def definition(): return "Modify image keys on a NXtomo" class ImageKeyUpgraderTask( Task, input_names=("data", "operations"), output_names=("data",), optional_input_names=("serialize_output_data",), ): """ close to ImageKeyEditor but convert a full "family" of frame type to another like all projections to dark field """ def run(self): scan = data_identifier_to_scan(self.inputs.data) if not isinstance(scan, NXtomoScan): raise TypeError(f"scan is expected to be an instance of {NXtomoScan}") operations = self.inputs.operations if not isinstance(operations, dict): raise TypeError("operations is expected to be an dict") configuration = {} for key_image_value_from, key_image_value_to in operations.items(): configuration.update( self.from_operation_to_config( scan=scan, from_image_key=key_image_value_from, to_image_key=key_image_value_to, ) ) configuration = { "modifications": configuration, } # apply modification using tomoscan change_image_key_control(scan=scan, config=configuration) if self.get_input_value("serialize_output_data", True): self.outputs.data = scan.to_dict() else: self.outputs.data = scan @staticmethod def from_operation_to_config( scan: TomwerScanBase, from_image_key: ImageKey, to_image_key: ImageKey ): """ retrieve frame indices to be updated """ from_image_key = ImageKey(from_image_key) to_image_key = ImageKey(to_image_key) config = {} for i_frame, frame in enumerate(scan.frames): if frame.image_key == from_image_key: config[i_frame] = to_image_key return config @staticmethod def program_name(): return "nxtomomill.utils.ImageKeyUpgraderTask" @staticmethod def program_version(): return nxtomomill.version.version @staticmethod def definition(): return "Modify image keys on a NXtomo" @deprecated( since_version="1.2", replacement="DarkFlatPatchTask.inputs.configuration", reason="ewoksification", ) def get_configuration(self): """ :return: configuration of the process """ return self.inputs.configuration @deprecated( since_version="1.2", replacement="DarkFlatPatchTask.inputs.configuration", reason="ewoksification", ) def set_configuration(self, configuration: dict) -> None: self.inputs.configuration = configuration class ImageKeyUpgrader(ImageKeyUpgraderTask): def __init__( self, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None ): deprecated_warning( name="tomwer.core.process.edit.imagekeyeditor.ImageKeyUpgrader", type_="class", reason="improve readibility", since_version="1.2", replacement="ImageKeyUpgraderTask", ) super().__init__(varinfo, inputs, node_id, node_attrs, execinfo) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/edit/nxtomoeditor.py0000644000175000017500000003064615153325210022773 0ustar00paynopaynofrom __future__ import annotations import gc import logging import h5py import numpy from collections import namedtuple from typing import Any from silx.io.utils import h5py_read_dataset from tomoscan.io import HDF5File from nxtomo.paths.nxtomo import get_paths as get_nexus_paths from nxtomo.nxobject.nxtransformations import NXtransformations from nxtomo.utils.transformation import ( DetXFlipTransformation, DetYFlipTransformation, ) from tomwer.core.process.task import Task from tomwer.core.scan.nxtomoscan import NXtomoScan _EditorFieldInfo = namedtuple( "_EditorFieldInfo", ["nexus_path", "name", "expected_type", "units", "n_value"] ) _logger = logging.getLogger(__name__) class NXtomoEditorKeys: """namespace to store all keys used by the nxtomo editor""" ENERGY = "instrument.beam.energy" DETECTOR_X_PIXEL_SIZE = "instrument.detector.x_pixel_size" DETECTOR_Y_PIXEL_SIZE = "instrument.detector.y_pixel_size" SAMPLE_DETECTOR_DISTANCE = "instrument.detector.distance" SAMPLE_SOURCE_DISTANCE = "instrument.source.distance" SAMPLE_X_PIXEL_SIZE = "sample.x_pixel_size" SAMPLE_Y_PIXEL_SIZE = "sample.y_pixel_size" PROPAGATION_DISTANCE = "sample.propagation_distance" FIELD_OF_VIEW = "instrument.detector.field_of_view" LR_FLIPPED = "instrument.detector.lr_flipped" UD_FLIPPED = "instrument.detector.ud_flipped" X_TRANSLATION = "sample.x_translation" Y_TRANSLATION = "sample.y_translation" Z_TRANSLATION = "sample.z_translation" class NXtomoEditorTask( Task, input_names=("data", "configuration"), output_names=("data",), ): """ task to edit a couple of field of a NXtomo """ def run(self): scan = self.inputs.data if scan is None: _logger.warning("no scan found to be saved") return if not isinstance(scan, NXtomoScan): raise TypeError( f"data is expected to be an instance of {NXtomoScan}. Got {type(scan)}" ) configuration = self.inputs.configuration if not isinstance(configuration, dict): raise TypeError( f"configuration is expected to be an instance of {dict}. Got {type(configuration)}" ) n_frames = len(scan.image_key_control) mapping = self.build_mapping( nexus_version=scan.nexus_version, n_frames=n_frames ) lr_flip = configuration.pop(NXtomoEditorKeys.LR_FLIPPED, None) ud_flip = configuration.pop(NXtomoEditorKeys.UD_FLIPPED, None) with HDF5File(scan.master_file, mode="a") as h5f: entry = h5f[scan.entry] for field, field_value in configuration.items(): if field not in mapping: raise ValueError(f"field unknown ({field})") self.__write_to_file( entry=entry, path=mapping[field].nexus_path, value=field_value, name=mapping[field].name, expected_type=mapping[field].expected_type, units=mapping[field].units, n_value=mapping[field].n_value, ) # solve NXtransformations if lr_flip is not None or ud_flip is not None: nx_transformations, detector_transformation_path = ( self.get_detector_transformations( scan_entry=scan.entry, lr_flip=( lr_flip if lr_flip is not None else scan.detector_is_lr_flip ), ud_flip=( ud_flip if ud_flip is not None else scan.detector_is_ud_flip ), nexus_version=scan.nexus_version, ) ) else: nx_transformations = detector_transformation_path = None # make sure the file has been removed (fix https://gitlab.esrf.fr/tomotools/tomwer/-/merge_requests/874#note_366688). gc.collect() if nx_transformations is not None: nx_transformations.save( file_path=scan.master_file, data_path=detector_transformation_path, nexus_path_version=scan.nexus_version, overwrite=True, ) # clear caches to make sure all modifications will be considered scan.clear_cache() scan.clear_frames_cache() self.outputs.data = scan @staticmethod def get_detector_transformations( scan_entry: str, lr_flip: bool, ud_flip: bool, nexus_version: float | None ) -> dict: nexus_paths = get_nexus_paths(nexus_version) if nexus_paths.nx_detector_paths.NX_TRANSFORMATIONS is None: # old NXtomo are not handling NX_TRANSFORMATIONS _logger.debug( "Old version of NXtomo found. No information about transformation will be saved" ) return None, None nx_transformations = NXtransformations() nx_transformations.add_transformation(DetXFlipTransformation(flip=ud_flip)) nx_transformations.add_transformation(DetYFlipTransformation(flip=lr_flip)) detector_transformation_path = "/".join( ( scan_entry, nexus_paths.INSTRUMENT_PATH, nexus_paths.nx_instrument_paths.DETECTOR_PATH, nexus_paths.nx_detector_paths.NX_TRANSFORMATIONS, ), ) return nx_transformations, detector_transformation_path @staticmethod def __write_to_file( entry: h5py.Group, path: str, value: Any, name: str, expected_type: type, n_value: int = 1, units=None, ) -> None: if path is None: # if the path does not exists (no handled by this version of nexus for example) return # try to cast the value if isinstance(value, str): value = value.replace(" ", "") if value.lower() == "none" or "..." in value: # if value is not defined or is an array not overwrite by the user (case of the ... ) return elif value is None: pass else: try: value = expected_type(value) except (ValueError, TypeError) as e: _logger.error(f"Fail to overwrite {name} of {entry.name}. Error is {e}") return if path in entry: if not NXtomoEditorTask.isFieldValueDifferent( dataset=entry[path], new_value=value, units=units ): # if no need to overwrite return else: del entry[path] if value is None: return elif n_value == 1: entry[path] = value else: entry[path] = numpy.array([value] * n_value) if units is not None: entry[path].attrs["units"] = units @staticmethod def isFieldValueDifferent(dataset: h5py.Dataset, new_value, units) -> bool: """ return False if the given value is the same as the one stored. This is a small improvement to avoid rewrite field if we can avoid it. The reason behind is that the orange widget will update the field when it receive a scan (of the unlock field). But then users can edit any field. As we don't want to bother with complex stuff like for each field keep track if It has been modified or not the orange widget will always require to modify all possible field even is not modified. """ current_value = h5py_read_dataset(dataset) attrs = dataset.attrs current_unit = attrs.get("units", attrs.get("unit", None)) if units != current_unit: # if the unit is not the same, even if the value is the same we will overwrite it return True else: if isinstance(new_value, numpy.ndarray) and isinstance( current_value, numpy.ndarray ): return not numpy.array_equal(new_value, current_value) elif numpy.isscalar(current_value) and numpy.isscalar(new_value): return current_value != new_value else: return True @staticmethod def build_mapping( nexus_version: float | None, n_frames: int ) -> dict[NXtomoEditorKeys, _EditorFieldInfo]: """ for the different field that can be edited we provide an instance of _EditorFieldInfo with all metadata needed to save this particular field. Note: X_flip and y_flip are saved differently as the two parameters are coupled we want either to save both or none of it. """ nexus_paths = get_nexus_paths(nexus_version) mapping = { # energy NXtomoEditorKeys.ENERGY: _EditorFieldInfo( nexus_path=nexus_paths.ENERGY_PATH, expected_type=float, units="kev", name="energy", n_value=1, ), # sample / detector distance NXtomoEditorKeys.SAMPLE_DETECTOR_DISTANCE: _EditorFieldInfo( nexus_path=nexus_paths.SAMPLE_DETECTOR_DISTANCE_PATH, expected_type=float, units="m", name="sample detector distance", n_value=1, ), # sample / source distance NXtomoEditorKeys.SAMPLE_SOURCE_DISTANCE: _EditorFieldInfo( nexus_path=nexus_paths.SAMPLE_SOURCE_DISTANCE_PATH, expected_type=float, units="m", name="sample detector distance", n_value=1, ), # overwrite FOV NXtomoEditorKeys.FIELD_OF_VIEW: _EditorFieldInfo( nexus_path=nexus_paths.FOV_PATH, expected_type=str, units=None, name="field of view", n_value=1, ), # x translation NXtomoEditorKeys.X_TRANSLATION: _EditorFieldInfo( nexus_path=nexus_paths.X_TRANS_PATH, expected_type=float, units="m", name="x translation", n_value=n_frames, ), # y translation NXtomoEditorKeys.Y_TRANSLATION: _EditorFieldInfo( nexus_path=nexus_paths.Y_TRANS_PATH, expected_type=float, units="m", name="y translation", n_value=n_frames, ), # z translation NXtomoEditorKeys.Z_TRANSLATION: _EditorFieldInfo( nexus_path=nexus_paths.Z_TRANS_PATH, expected_type=float, units="m", name="z translation", n_value=n_frames, ), # detector x pixel size NXtomoEditorKeys.DETECTOR_X_PIXEL_SIZE: _EditorFieldInfo( nexus_path=nexus_paths.DETECTOR_X_PIXEL_SIZE_PATH, expected_type=float, units="m", name="detector x pixel size", n_value=1, ), # detector y pixel size NXtomoEditorKeys.DETECTOR_Y_PIXEL_SIZE: _EditorFieldInfo( nexus_path=nexus_paths.DETECTOR_Y_PIXEL_SIZE_PATH, expected_type=float, units="m", name="detector y pixel size", n_value=1, ), # sample x pixel size NXtomoEditorKeys.SAMPLE_X_PIXEL_SIZE: _EditorFieldInfo( nexus_path=nexus_paths.SAMPLE_X_PIXEL_SIZE_PATH, expected_type=float, units="m", name="sample x pixel size", n_value=1, ), # sample y pixel size NXtomoEditorKeys.SAMPLE_Y_PIXEL_SIZE: _EditorFieldInfo( nexus_path=nexus_paths.SAMPLE_Y_PIXEL_SIZE_PATH, expected_type=float, units="m", name="sample y pixel size", n_value=1, ), # propagation distance NXtomoEditorKeys.PROPAGATION_DISTANCE: _EditorFieldInfo( nexus_path=nexus_paths.PROPAGATION_DISTANCE, expected_type=float, units="m", name="propagation distance", n_value=1, ), } return mapping ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1772989186.921101 tomwer-1.6.17/src/tomwer/core/process/edit/tests/0000755000175000017500000000000015153325403021023 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/edit/tests/test_darkflatpatch.py0000644000175000017500000002222615153325210025244 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import shutil import tempfile import unittest import h5py import numpy from silx.io.url import DataUrl from silx.io.utils import h5py_read_dataset from tomoscan.esrf.scan.mock import MockNXtomo from tomwer.core.process.edit.darkflatpatch import DarkFlatPatchTask from tomwer.core.scan.nxtomoscan import NXtomoScan class BaseTestAddDarkAndFlats(unittest.TestCase): """ Unit test on nxtomomill.utils.add_dark_flat_nx_file function """ def setUp(self) -> None: self.tmpdir = tempfile.mkdtemp() simple_nx_path = os.path.join(self.tmpdir, "simple_case") self.dim = 55 self.nproj = 20 self._simple_nx = MockNXtomo( scan_path=simple_nx_path, n_proj=self.nproj, n_ini_proj=self.nproj, create_ini_dark=False, create_ini_flat=False, create_final_flat=False, dim=self.dim, ).scan with h5py.File(self._simple_nx.master_file, mode="r") as h5s: data_path = "/".join( (self._simple_nx.entry, "instrument", "detector", "data") ) self._raw_data = h5py_read_dataset(h5s[data_path]) nx_with_vds_path = os.path.join(self.tmpdir, "case_with_vds") self._nx_with_virtual_dataset = MockNXtomo( scan_path=nx_with_vds_path, n_proj=0, n_ini_proj=0, create_ini_dark=False, create_ini_flat=False, create_final_flat=False, dim=self.dim, ).scan self._create_vds( source_file=self._simple_nx.master_file, source_data_path=self._simple_nx.entry, target_file=self._nx_with_virtual_dataset.master_file, target_data_path=self._nx_with_virtual_dataset.entry, copy_other_data=True, ) self._patch_nxtomo_flags(self._nx_with_virtual_dataset) nx_with_vds_path_and_links = os.path.join( self.tmpdir, "case_with_vds_and_links" ) self._nx_with_virtual_dataset_with_link = MockNXtomo( scan_path=nx_with_vds_path_and_links, n_proj=0, n_ini_proj=0, create_ini_dark=False, create_ini_flat=False, create_final_flat=False, dim=self.dim, ).scan self._create_vds( source_file=self._simple_nx.master_file, source_data_path=self._simple_nx.entry, target_file=self._nx_with_virtual_dataset_with_link.master_file, target_data_path=self._nx_with_virtual_dataset_with_link.entry, copy_other_data=True, ) self._patch_nxtomo_flags(self._nx_with_virtual_dataset_with_link) # create dark self.start_dark = ( numpy.random.random((self.dim * self.dim)) .reshape(1, self.dim, self.dim) .astype("f") ) self.start_dark_file = os.path.join(self.tmpdir, "dark.hdf5") self.start_dark_entry = "data" self.start_dark_url = self._save_raw( data=self.start_dark, entry=self.start_dark_entry, file_path=self.start_dark_file, ) self.end_dark = ( numpy.random.random((self.dim * self.dim * 2)) .reshape(2, self.dim, self.dim) .astype("f") ) self.end_dark_file = os.path.join(self.tmpdir, "dark.hdf5") self.end_dark_entry = "data2" self.end_dark_url = self._save_raw( data=self.end_dark, entry=self.end_dark_entry, file_path=self.end_dark_file ) # create flats self.start_flat = ( numpy.random.random((self.dim * self.dim * 3)) .reshape(3, self.dim, self.dim) .astype("f") ) self.start_flat_file = os.path.join(self.tmpdir, "start_flat.hdf5") self.start_flat_entry = "/root/flat" self.start_flat_url = self._save_raw( data=self.start_flat, entry=self.start_flat_entry, file_path=self.start_flat_file, ) self.end_flat = ( numpy.random.random((self.dim * self.dim)) .reshape(1, self.dim, self.dim) .astype("f") ) # save the end flat in the simple case file to insure all cases are # consider self.end_flat_file = self._simple_nx.master_file self.end_flat_entry = "flat" self.end_flat_url = self._save_raw( data=self.end_flat, entry=self.end_flat_entry, file_path=self.end_flat_file ) def _save_raw(self, data, entry, file_path) -> DataUrl: with h5py.File(file_path, mode="a") as h5s: h5s[entry] = data return DataUrl(file_path=file_path, data_path=entry, scheme="silx") def _create_vds( self, source_file: str, source_data_path: str, target_file: str, target_data_path: str, copy_other_data: bool, ): """Create virtual dataset and links from source to target :param source_file: :param source_data_path: :param target_file: :param target_data_path: :param copy_other_data: we want to create two cases: one copying datasets 'image_key'... and the other one linking them. Might have a difference of behavior when overwriting for example """ assert source_file != target_file, "file should be different" # link data n_frames = 0 # for now we only consider the original data with h5py.File(source_file, mode="r") as o_h5s: old_path = os.path.join(source_data_path, "instrument", "detector", "data") n_frames += o_h5s[old_path].shape[0] shape = o_h5s[old_path].shape data_type = o_h5s[old_path].dtype layout = h5py.VirtualLayout(shape=shape, dtype=data_type) assert os.path.exists(source_file) with h5py.File(source_file, mode="r") as ppp: assert source_data_path in ppp layout[:] = h5py.VirtualSource(path_or_dataset=o_h5s[old_path]) det_path = os.path.join(target_data_path, "instrument", "detector") with h5py.File(target_file, mode="a") as h5s: detector_node = h5s.require_group(det_path) detector_node.create_virtual_dataset("data", layout, fillvalue=-5) for path in ( os.path.join("instrument", "detector", "image_key"), os.path.join("instrument", "detector", "image_key_control"), os.path.join("instrument", "detector", "count_time"), os.path.join("sample", "rotation_angle"), ): old_path = os.path.join(source_data_path, path) new_path = os.path.join(target_data_path, path) with h5py.File(target_file, mode="a") as h5s: if copy_other_data: with h5py.File(source_file, mode="r") as o_h5s: if new_path in h5s: del h5s[new_path] h5s[new_path] = h5py_read_dataset(o_h5s[old_path]) elif source_file == target_file: h5s[new_path] = h5py.SoftLink(old_path) else: relpath = os.path.relpath(source_file, os.path.dirname(target_file)) h5s[new_path] = h5py.ExternalLink(relpath, old_path) def _patch_nxtomo_flags(self, scan): """Insure necessary flags are here""" with h5py.File(scan.master_file, mode="a") as h5s: instrument_path = os.path.join(scan.entry, "instrument") instrument_node = h5s.require_group(instrument_path) if "NX_class" not in instrument_node.attrs: instrument_node.attrs["NX_class"] = "NXinstrument" detector_node = instrument_node.require_group("detector") if "NX_class" not in detector_node.attrs: detector_node.attrs["NX_class"] = "NXdetector" if "data" in instrument_node: if "interpretation" not in instrument_node.attrs: instrument_node["data"].attrs["interpretation"] = "image" sample_path = os.path.join(scan.entry, "sample") sample_node = h5s.require_group(sample_path) if "NX_class" not in sample_node: sample_node.attrs["NX_class"] = "NXsample" def tearDown(self) -> None: shutil.rmtree(self.tmpdir) class TestDaarkFlatPatch(BaseTestAddDarkAndFlats): def test(self): scan = NXtomoScan( self._nx_with_virtual_dataset_with_link.master_file, self._nx_with_virtual_dataset_with_link.entry, ) process = DarkFlatPatchTask( inputs={ "data": scan, "serialize_output_data": False, "configuration": { "darks_start": self.start_dark_url, }, }, ) process.definition() process.program_version() process.program_name() # TODO: properties should be part of inputs process.run() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/edit/tests/test_imagekey_editor.py0000644000175000017500000000445115153325210025575 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import shutil import tempfile import unittest import pytest from nxtomo.nxobject.nxdetector import ImageKey from tomwer.core.process.edit.imagekeyeditor import ( ImageKeyEditorTask, ImageKeyUpgraderTask, ) from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.utils.scanutils import MockNXtomo class TestImageKeyEditor(unittest.TestCase): def setUp(self): self.tempdir = tempfile.mkdtemp() dim = 10 mock = MockNXtomo( scan_path=os.path.join(self.tempdir, "scan1"), n_proj=10, n_ini_proj=10, scan_range=180, dim=dim, ) self.scan = mock.scan def tearDown(self): shutil.rmtree(self.tempdir) def test(self): process = ImageKeyEditorTask( inputs={ "data": self.scan, "serialize_output_data": False, "configuration": { "modifications": { 0: ImageKey.INVALID.value, 3: ImageKey.ALIGNMENT.value, }, }, } ) process.definition() process.program_version() process.program_name() process.run() def test_ImageKeyUpgraderTask(tmp_path): """ test ImageKeyUpgraderTask task """ test_dir = tmp_path / "test_image_key_upgrader" os.makedirs(test_dir) scan = MockNXtomo( scan_path=test_dir, n_proj=20, n_ini_proj=20, create_ini_dark=False, ).scan operations = { ImageKey.PROJECTION: ImageKey.DARK_FIELD, } with pytest.raises(TypeError): ImageKeyUpgraderTask( inputs={ "data": None, "operations": operations, }, ).run() with pytest.raises(TypeError): ImageKeyUpgraderTask( inputs={ "data": scan, "operations": None, }, ).run() task = ImageKeyUpgraderTask( inputs={ "data": scan, "operations": operations, }, ) task.run() scan = NXtomoScan(scan.master_file, scan.entry) assert len(scan.projections) == 0 assert len(scan.darks) == 20 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/output.py0000644000175000017500000000347315153325210020651 0ustar00paynopaynofrom __future__ import annotations import os from enum import Enum import warnings class ProcessDataOutputDirMode(Enum): IN_SCAN_FOLDER = "same folder as scan" PROCESSED_DATA_FOLDER = "PROCESSED_DATA folder" OTHER = "other" @classmethod def from_value(cls, value): # ensure backward compatibility if value == "near input": return cls.IN_SCAN_FOLDER elif value == "processed data dir": return cls.PROCESSED_DATA_FOLDER elif value == "raw data dir": # Deprecation logic warnings.warn( "'RAW_DATA output' is deprecated since writing to 'RAW_DATA' folder is forbidden." "Redirecting to 'PROCESSED_DATA_FOLDER'.", DeprecationWarning, stacklevel=2, ) return cls.PROCESSED_DATA_FOLDER return ProcessDataOutputDirMode(value) class NabuOutputFileFormat(Enum): TIFF = "tiff" TIFF_3D = "tiff3d" HDF5 = "hdf5" JP2K = "jp2" EDF = "edf" RAW = "vol" @classmethod def from_value(cls, value): if isinstance(value, str): value = value.lstrip(".") return NabuOutputFileFormat(value) def get_file_format(file_str): extension = os.path.splitext(file_str.lower())[-1] extension = extension.lstrip(".") if extension in ("tiff", "tif"): return NabuOutputFileFormat.TIFF elif extension in ("hdf5", "hdf", "h5"): return NabuOutputFileFormat.HDF5 elif extension in ("jp2", "jp2k", "jpg2k"): return NabuOutputFileFormat.JP2K elif extension in ("edf",): return NabuOutputFileFormat.EDF elif extension in ("vol", "raw"): return NabuOutputFileFormat.RAW else: raise ValueError(f"Unrecognized file extension {extension} from {file_str}") ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1772989186.921101 tomwer-1.6.17/src/tomwer/core/process/reconstruction/0000755000175000017500000000000015153325403022015 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/__init__.py0000644000175000017500000000023715153325210024124 0ustar00paynopayno# coding: utf-8 """The reconstruction module is contains all processes relative to reconstruction (lamino, tomography reconstruction, axis calculation...)""" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1772989186.921101 tomwer-1.6.17/src/tomwer/core/process/reconstruction/axis/0000755000175000017500000000000015153325403022761 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/axis/__init__.py0000644000175000017500000000012015153325210025057 0ustar00paynopaynofrom .axis import AxisTask # noqa F401 from .params import AxisRP # noqa F401 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/axis/anglemode.py0000644000175000017500000000101015153325210025252 0ustar00paynopayno# coding: utf-8 from enum import Enum as _Enum class CorAngleMode(_Enum): use_0_180 = "0-180" use_90_270 = "90-270" manual_selection = "manual" @classmethod def from_value(cls, value): # TODO: back compatibility if is int if value == 0: return CorAngleMode.use_0_180 elif value == 1: return CorAngleMode.use_90_270 elif value == 2: return CorAngleMode.manual_selection else: return CorAngleMode(value=value) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/axis/axis.py0000644000175000017500000004137015153325210024300 0ustar00paynopayno"""contain the AxisTask class""" from __future__ import annotations import logging from nabu.pipeline.estimators import estimate_cor from nabu.resources.nxflatfield import update_dataset_info_flats_darks from processview.core.manager import DatasetState, ProcessManager from processview.core.superviseprocess import SuperviseProcess import tomwer.version from tomwer.core.process.reconstruction.utils.cor import absolute_pos_to_relative from tomwer.core.process.task import Task from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils import image, logconfig from tomwer.core.utils.scanutils import data_identifier_to_scan from tomwer.utils import docstring from .mode import AxisMode from .params import ( DEFAULT_CMP_N_SUBSAMPLING_Y, DEFAULT_CMP_NEAR_POS, DEFAULT_CMP_NEAR_WIDTH, DEFAULT_CMP_OVERSAMPLING, DEFAULT_CMP_TAKE_LOG, DEFAULT_CMP_THETA, AxisRP, ) from .projectiontype import ProjectionType _logger = logging.getLogger(__name__) # vertically, work on a window having only a percentage of the frame. pc_height = 10.0 / 100.0 # horizontally. Global method supposes the COR is more or less in center # % of the detector: pc_width = 50.0 / 100.0 def _absolute_pos_to_relative_with_warning(absolute_pos: float, det_width: int | None): """ nabu returns the value as absolute. tomwer needs it as relative Also handle the case (unlikely) the detector width cannot be found """ if det_width is None: det_width = 2048 _logger.warning("unable to find image width. Set width to 2048") else: det_width = det_width return absolute_pos_to_relative(absolute_pos=absolute_pos, det_width=det_width) def adapt_tomwer_scan_to_nabu(scan: TomwerScanBase, do_flatfield: bool): """simple util to convert tomwer scan to a nabu DataAnalizer and updating infos regarding flat and dark if needed """ dataset_infos = scan.to_nabu_dataset_analyser() if isinstance(scan, NXtomoScan): try: update_dataset_info_flats_darks( dataset_infos, flatfield_mode=do_flatfield, loading_mode="load_if_present", ) except ValueError as exception: # nabu raise an error if no darks / flats set. But this can make sense at this stage if the NXtomo has no # raw dark / flat and is already normalized. In this case only fire a warning if ( scan.reduced_darks is not None and len(scan.reduced_darks) > 0 and scan.reduced_flats is not None and len(scan.reduced_flats) > 0 ): raise exception else: _logger.warning( "Fail to update nabu dataset info flats and darks. Expected if the dataset contains already normalized projections" ) return dataset_infos def get_composite_options(scan) -> tuple: theta = scan.axis_params.composite_options.get("theta", DEFAULT_CMP_THETA) n_subsampling_y = scan.axis_params.composite_options.get( "n_subsampling_y", DEFAULT_CMP_N_SUBSAMPLING_Y ) oversampling = scan.axis_params.composite_options.get( "oversampling", DEFAULT_CMP_OVERSAMPLING ) take_log = scan.axis_params.composite_options.get("take_log", DEFAULT_CMP_TAKE_LOG) near_pos = scan.axis_params.composite_options.get("near_pos", DEFAULT_CMP_NEAR_POS) near_width = scan.axis_params.composite_options.get( "near_width", DEFAULT_CMP_NEAR_WIDTH ) return theta, n_subsampling_y, oversampling, take_log, near_pos, near_width def read_scan_x_rotation_axis_pixel_position(scan: TomwerScanBase): """read center of rotation estimation from metadata""" if isinstance(scan, EDFTomoScan): raise TypeError("EDFTomoScan have not information about estimated cor position") else: res = scan.x_rotation_axis_pixel_position if res is None: _logger.error( f"unable to find x_rotation_axis_pixel_position from {scan.get_identifier()}" ) return res class NoAxisUrl(Exception): pass class AxisTask( Task, SuperviseProcess, input_names=("data",), output_names=("data",), optional_input_names=("serialize_output_data",), ): """ Process used to compute the center of rotation of a scan """ def __init__( self, process_id=None, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None, ): Task.__init__( self, varinfo=varinfo, inputs=inputs, node_id=node_id, node_attrs=node_attrs, execinfo=execinfo, ) if "recons_params" in inputs: raise KeyError("do not use 'recons_params' but use 'axis_params' instead") axis_params = inputs.get("axis_params", None) if isinstance(axis_params, dict): axis_params = AxisRP.from_dict(axis_params) elif not (axis_params is None or isinstance(axis_params, AxisRP)): raise TypeError( "'axis_params' is expected to be None or an instance of AxisRP or a dict" ) SuperviseProcess.__init__(self, process_id=process_id) self._mode_calculation_fct = {} """dict with function pointer to call for making the mode calculation. Function should have only one 'scan' parameter as input""" self._axis_params = axis_params or AxisRP() """Axis reconstruction parameters to apply""" self._locked = False """Boolean used to lock reconstruction parameters edition""" self._recons_params_before_lock = None """Recons parameters register before locking the position""" def set_configuration(self, configuration): if "_rpSetting" in configuration: recons_params = AxisRP.from_dict(configuration["_rpSetting"]) else: recons_params = AxisRP.from_dict(configuration) self.set_recons_params(recons_params=recons_params) def set_recons_params(self, recons_params): assert isinstance(recons_params, AxisRP) self._axis_params = recons_params def lock_position_value(self, lock=True): """ lock the position currently computed or defined by the user. In this case we will lock the axis as defined 'fixed' with the current value :param lock: if true lock the currently existing position value """ self._locked = lock if lock: self._recons_params_before_lock = self._axis_params.to_dict() if self._axis_params != AxisMode.manual: self._axis_params.mode = AxisMode.manual else: if self._recons_params_before_lock: self._axis_params.load_from_dict( self._recons_params_before_lock ) # noqa def run(self): """ Compute the position value then get ready to the next. And call .. note:: this simply call `compute`. But this is needed for the AxisProcessThreaded class """ scan = data_identifier_to_scan(self.inputs.data) if scan is None: self.outputs.data = None return if isinstance(scan, TomwerScanBase): scan = scan elif isinstance(scan, dict): scan = ScanFactory.create_scan_object_frm_dict(scan) else: raise ValueError(f"input type {scan} is not managed") _logger.info("start axis calculation for %s" % scan.path) self._axis_params.frame_width = scan.dim_1 cor = error = None try: scan_res = self.compute(scan=scan) except Exception as e: scan_res = None error = e else: if isinstance(scan_res, TomwerScanBase): cor = scan_res.axis_params.relative_cor_value elif scan_res is None: if scan.axis_params.relative_cor_value is not None: cor = scan.axis_params.relative_cor_value elif isinstance(scan_res, float): cor = scan_res else: assert isinstance(scan_res, dict) b_dict = scan_res if TomwerScanBase._DICT_AXIS_KEYS in scan_res: b_dict = scan_res["axis_params"] cor = b_dict["POSITION_VALUE"] finally: if cor != "...": self._process_end(scan, cor=cor, error=error) if self.get_input_value("serialize_output_data", True): self.outputs.data = scan_res.to_dict() else: self.outputs.data = scan_res def _process_end(self, scan, cor, error=None): assert isinstance(scan, TomwerScanBase) try: extra = { logconfig.DOC_TITLE: self._scheme_title, logconfig.SCAN_ID: scan.path, } if error is not None: info = " ".join( ( "fail to compute axis position for scan", str(scan.path), "reason is ", str(error), ) ) _logger.processFailed(info, extra=extra) ProcessManager().notify_dataset_state( dataset=scan, process=self, state=DatasetState.FAILED, details=info ) elif scan.axis_params.relative_cor_value is None: info = " ".join( ("fail to compute axis position for scan", str(scan.path)) ) _logger.processFailed(info, extra=extra) ProcessManager().notify_dataset_state( dataset=scan, process=self, state=DatasetState.FAILED, details=info ) else: info = "axis calculation defined for {}: {} (using {})".format( str(scan.path), str(scan.axis_params.relative_cor_value), scan.axis_params.mode.value, ) _logger.processSucceed(info, extra=extra) ProcessManager().notify_dataset_state( dataset=scan, process=self, state=DatasetState.SUCCEED, details=info ) except Exception as e: _logger.error(e) @staticmethod def get_input_radios(scan) -> tuple: """Make sure we have valid projections to be used for axis calculation :param scan: scan to check :raise: NoAxisUrl if fails to found :return: tuple of AxisResource """ if ( scan.axis_params and scan.axis_params.axis_url_1 and scan.axis_params.axis_url_1.url ): return scan.axis_params.axis_url_1, scan.axis_params.axis_url_2 return scan.get_opposite_projections(mode=scan.axis_params.angle_mode) @staticmethod def get_inputs(scan): assert isinstance(scan, TomwerScanBase) radio_1, radio_2 = AxisTask.get_input_radios(scan=scan) if radio_1 and radio_2: mess = " ".join( ("input radios are", radio_1.url.path(), "and", radio_2.url.path()) ) _logger.info(mess) log_ = scan.axis_params.projection_type is ProjectionType.transmission # if necessary normalize data if radio_1.normalized_data is None: radio_1.normalize_data(scan, log_=log_) if radio_2.normalized_data is None: radio_2.normalize_data(scan, log_=log_) if scan.axis_params.paganin_preproc: data_1 = radio_1.normalized_data_paganin data_2 = radio_2.normalized_data_paganin else: data_1 = radio_1.normalized_data data_2 = radio_2.normalized_data if scan.axis_params.scale_img2_to_img1: data_2 = image.scale_img2_to_img1(img_1=data_1, img_2=data_2) return data_1, data_2 else: _logger.info("fail to find any inputs") return None, None def compute(self, scan, wait=True): """ Compute the position value for the scan :param scan: :param wait: used for threaded process. True if we want to end the computation before releasing hand. :return: scan as a TomoBase """ assert scan is not None if isinstance(scan, dict): _logger.warning("convert scan from a dict") _scan = ScanFactory.create_scan_object_frm_dict(scan) else: _scan = scan assert isinstance(_scan, TomwerScanBase) # if the scan has no tomo reconstruction parameters yet create them if _scan.axis_params is None: _scan.axis_params = AxisRP() # copy axis recons parameters. We skip the axis_url which are specific # to the scan _scan.axis_params.copy( self._axis_params, copy_axis_url=False, copy_flip_lr=False ) assert scan.axis_params is not None return self._process_computation(scan=_scan) def scan_ready(self, scan): _logger.info(scan, "processed") def _process_computation(self, scan): """ :param TomwerScanBase scan: scan for which we want to compute the axis position. :return: scan as a TomoBase or a dict if serialize_output_data activated """ _logger.info("compute center of rotation for %s" % scan.path) try: position = self.compute_axis_position(scan) except NotImplementedError as e: scan.axis_params.set_relative_value(None) raise e except ValueError as e: scan_name = scan.path or "undef scan" scan.axis_params.set_relative_value(None) raise Exception( f"Fail to compute axis position for {scan_name} reason is {e}" ) else: scan.axis_params.set_relative_value(position) self._axis_params.frame_width = scan.dim_1 self._axis_params.set_relative_value(position) scan_name = scan.path or "undef scan" r_cor_value = scan.axis_params.relative_cor_value mess = f"Compute axis position ({r_cor_value}) with {scan.axis_params.mode.value}" _logger.info(mess) return scan def setMode(self, mode, value): if mode is AxisMode.manual: self._axis_params.cor_position = value else: raise NotImplementedError("mode not implemented yet") def define_calculation_mode(self, mode: AxisMode, fct_pointer): """Register the function to call of the given mode :param mode: the mode to register :param fct_pointer: pointer to the function to call """ self._mode_calculation_fct[mode] = fct_pointer def compute_axis_position(self, scan): """ :param scan: scan for which we compute the center of rotation :return: position of the rotation axis. Use the `.AxisMode` defined by the `.ReconsParams` of the `.AxisTask` """ mode = self._axis_params.mode if mode is AxisMode.manual: # If mode is read or manual the position_value is not computed and # we will keep the actual one (should have been defined previously) res = self._axis_params.relative_cor_value elif mode is AxisMode.read: res = read_scan_x_rotation_axis_pixel_position(scan=scan) else: has_darks = scan.reduced_darks is not None and len(scan.reduced_darks) > 0 has_flats = scan.reduced_flats is not None and len(scan.reduced_flats) > 0 do_flatfield = has_darks and has_flats res = estimate_cor( method=mode.value, dataset_info=adapt_tomwer_scan_to_nabu( scan=scan, do_flatfield=do_flatfield ), do_flatfield=do_flatfield, cor_options=scan.axis_params.get_nabu_cor_options_as_dict(), ) # convert back to relative res = _absolute_pos_to_relative_with_warning( absolute_pos=res, det_width=scan.dim_1 ) return res @docstring(Task.program_name) @staticmethod def program_name(): return "tomwer_axis" @docstring(Task.program_version) @staticmethod def program_version(): return tomwer.version.version @docstring(Task.definition) @staticmethod def definition(): return "Compute center of rotation" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/axis/mode.py0000644000175000017500000002245215153325210024260 0ustar00paynopaynoimport logging from enum import Enum as _Enum from tomwer.core.process.reconstruction.axis.side import Side _logger = logging.getLogger(__name__) class AxisModeMetadata: """ Util class to store metadata regarding processing of a mode. Ease processing and display Maybe this function should be part of nabu ? :param lockable: True if this value can be lock and process automatically when a new scan is received :param tooltip: short description of the mode (to be used by the GUI) :param computing_constrains: some constrain like need to have a 0-360 acquisition (so no Half acquisition) :param allows_padding: does the algorithm applies padding (and so can the user provide some mode) :param valid_inputs: compatible input type (pair of radios or sinogram...) :param valid_sides: can a side be provided :param allows_estimated_cor_as_numerical_value: can a numerical value (first guess) be provided to the algorithm """ def __init__( self, lockable, tooltip="", computing_constrains=(), allows_padding=False, valid_inputs=(), valid_sides=(), allows_estimated_cor_as_numerical_value: bool = True, ) -> None: self._lockable = lockable self._tooltip = tooltip self._computing_constrains = computing_constrains self._allows_padding = allows_padding self._valid_inputs = valid_inputs self._valid_sides = valid_sides self._allows_estimated_cor_as_numerical_value = ( allows_estimated_cor_as_numerical_value ) @property def is_lockable(self) -> bool: return self._lockable @property def tooltip(self) -> str: return self._tooltip @property def computing_constrains(self) -> tuple: return self._computing_constrains @property def allows_padding(self) -> bool: return self._allows_padding @property def valid_inputs(self) -> tuple: return self._valid_inputs @property def valid_sides(self) -> tuple: return self._valid_sides @property def allows_estimated_cor_as_numerical_value(self) -> bool: return self._allows_estimated_cor_as_numerical_value class _InputType(_Enum): SINOGRAM = "sinogram" RADIOS_X2 = "2 radios" COMPOSITE = "composite" class _Constrain(_Enum): FULL_TURN = "full turn" class AxisMode(_Enum): centered = "centered" global_ = "global" manual = "manual" growing_window_sinogram = "sino-growing-window" growing_window_radios = "growing-window" sliding_window_sinogram = "sino-sliding-window" sliding_window_radios = "sliding-window" sino_coarse_to_fine = "sino-coarse-to-fine" composite_coarse_to_fine = "composite-coarse-to-fine" fourier_angles = "fourier-angles" octave_accurate_radios = "octave-accurate" read = "read 'x_rotation_axis_pixel_position'" # alias to composite_coarse_to_fine with near mode near = "near" @classmethod def from_value(cls, value): # ensure backward compatibility with workflow defined before COR method on sinograms if value in ("global_", "global"): value = AxisMode.global_ if value == "radio-growing-window": _logger.warning( f"Axis mode requested is '{value}'. To insure backward compatibility replace it by '{AxisMode.growing_window_radios.value}'" ) value = AxisMode.growing_window_radios elif value == "radio-sliding-window": _logger.warning( f"Axis mode requested is '{value}'. To insure backward compatibility replace it by '{AxisMode.sliding_window_radios.value}'" ) value = AxisMode.sliding_window_radios elif value in ("radios-octave-accurate", "accurate"): _logger.warning( f"Axis mode requested is '{value}'. To insure backward compatibility replace it by '{AxisMode.octave_accurate_radios.value}'" ) value = AxisMode.octave_accurate_radios elif value in ("read", "read from estimated cor"): value = AxisMode.read return AxisMode(value) def requires_radio_indices(self) -> bool: return self in ( AxisMode.growing_window_radios, AxisMode.sliding_window_radios, AxisMode.octave_accurate_radios, ) def requires_sinogram_index(self) -> bool: return self in ( AxisMode.growing_window_sinogram, AxisMode.sliding_window_sinogram, AxisMode.fourier_angles, AxisMode.sino_coarse_to_fine, ) AXIS_MODE_METADATAS = { # manual AxisMode.manual: AxisModeMetadata( lockable=False, tooltip="Enter or find manually the COR value", computing_constrains=(), allows_padding=False, valid_inputs=(_InputType.RADIOS_X2,), allows_estimated_cor_as_numerical_value=False, ), # read AxisMode.read: AxisModeMetadata( lockable=True, tooltip="Read COR value from nexus file ({entry}/instrument/detector/x_rotation_axis_pixel_position dataset). Will work only for NXtomo / hdf5 datasets", computing_constrains=(), allows_padding=False, valid_inputs=None, allows_estimated_cor_as_numerical_value=False, ), # radio algorithm AxisMode.centered: AxisModeMetadata( lockable=True, tooltip="Dedicated to fullfield. Previously named 'accurate'", computing_constrains=(), allows_padding=True, valid_inputs=(_InputType.RADIOS_X2,), valid_sides=(Side.CENTER,), ), AxisMode.global_: AxisModeMetadata( lockable=True, tooltip="Algorithm which can work for both half acquisition and standard ('full field') acquisition", computing_constrains=(), allows_padding=True, valid_inputs=(_InputType.RADIOS_X2,), allows_estimated_cor_as_numerical_value=False, ), AxisMode.growing_window_radios: AxisModeMetadata( lockable=True, tooltip="A auto-Cor method", computing_constrains=(), allows_padding=True, valid_inputs=(_InputType.RADIOS_X2,), valid_sides=(Side.RIGHT, Side.LEFT, Side.CENTER, Side.ALL), allows_estimated_cor_as_numerical_value=False, ), AxisMode.sliding_window_radios: AxisModeMetadata( lockable=True, tooltip="A method for estimating semi-automatically the CoR position. You have to provide a hint on where the CoR is (left, center, right).", computing_constrains=(), allows_padding=True, valid_inputs=(_InputType.RADIOS_X2,), valid_sides=(Side.RIGHT, Side.LEFT, Side.CENTER), ), AxisMode.octave_accurate_radios: AxisModeMetadata( lockable=True, tooltip="Same method as the 'accurate' octave code", computing_constrains=(_Constrain.FULL_TURN,), allows_padding=True, valid_inputs=(_InputType.RADIOS_X2,), valid_sides=(Side.CENTER,), allows_estimated_cor_as_numerical_value=False, ), # sinogram algorithm AxisMode.growing_window_sinogram: AxisModeMetadata( lockable=True, tooltip="A auto-Cor method", computing_constrains=(), allows_padding=True, valid_inputs=(_InputType.SINOGRAM,), valid_sides=(Side.RIGHT, Side.LEFT, Side.CENTER, Side.ALL), allows_estimated_cor_as_numerical_value=False, ), AxisMode.sliding_window_sinogram: AxisModeMetadata( lockable=True, tooltip="A method for estimating semi-automatically the CoR position. You have to provide a hint on where the CoR is (left, center, right).", computing_constrains=(), allows_padding=True, valid_inputs=(_InputType.SINOGRAM,), valid_sides=( Side.RIGHT, Side.LEFT, Side.CENTER, ), ), AxisMode.sino_coarse_to_fine: AxisModeMetadata( lockable=True, tooltip="Estimate CoR from sinogram. Only works for 360 degrees scans.", computing_constrains=(_Constrain.FULL_TURN,), allows_padding=True, valid_inputs=(_InputType.SINOGRAM,), valid_sides=( Side.RIGHT, Side.LEFT, ), allows_estimated_cor_as_numerical_value=False, ), AxisMode.fourier_angles: AxisModeMetadata( lockable=True, tooltip="", computing_constrains=(_Constrain.FULL_TURN,), allows_padding=True, valid_inputs=(_InputType.SINOGRAM,), valid_sides=( Side.RIGHT, Side.LEFT, Side.CENTER, ), ), # coarse-to-fine algorithm AxisMode.composite_coarse_to_fine: AxisModeMetadata( lockable=True, tooltip="A auto-Cor method", computing_constrains=(_Constrain.FULL_TURN,), allows_padding=True, valid_inputs=(_InputType.COMPOSITE,), valid_sides=( Side.RIGHT, Side.LEFT, Side.CENTER, ), ), AxisMode.near: AxisModeMetadata( lockable=True, tooltip="Alias to composite_coarse_to_fine", computing_constrains=(_Constrain.FULL_TURN,), allows_padding=True, valid_inputs=(_InputType.COMPOSITE,), valid_sides=( Side.RIGHT, Side.LEFT, Side.CENTER, ), ), } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/axis/params.py0000644000175000017500000006773715153325210024636 0ustar00paynopaynofrom __future__ import annotations import logging from collections import namedtuple import numpy from silx.io.url import DataUrl from enum import Enum as _Enum from tomoscan.esrf.scan.utils import get_data from tomwer.core.process.reconstruction.utils.cor import relative_pos_to_absolute from tomwer.core.process.reconstruction.axis.side import Side from tomwer.core.scan.scanbase import TomwerScanBase from .anglemode import CorAngleMode from .mode import AxisMode, AXIS_MODE_METADATAS from .projectiontype import ProjectionType from nabu.preproc.phase import PaganinPhaseRetrieval _logger = logging.getLogger(__name__) _calculation_conf = namedtuple( "_calculation_conf", ["projection_type", "paganin"] ) # noqa _WITH_PAG = "withpag" _NO_PAG = "nopag" DEFAULT_CMP_THETA = 5 DEFAULT_CMP_N_SUBSAMPLING_Y = 40 DEFAULT_CMP_NEAR_POS = 0 DEFAULT_CMP_NEAR_WIDTH = 40 DEFAULT_CMP_OVERSAMPLING = 4 DEFAULT_CMP_TAKE_LOG = True class AxisCalculationInput(_Enum): """Define the different mode of input the user can have for axis calculation""" emission = _calculation_conf(ProjectionType.absorption, False) transmission = _calculation_conf(ProjectionType.transmission, False) transmission_pag = _calculation_conf(ProjectionType.transmission, True) def name(self): # pylint: disable=E0102 if self.value.paganin is True: return " ".join((self.value.projection_type.value, "paganin")) else: return self.value.projection_type.value def to_dict(self): pag_text = _WITH_PAG if self.value.paganin is True else _NO_PAG return "_".join((self.value.projection_type.value, pag_text)) @classmethod def from_value(cls, value): if type(value) is str and len(value.split("_")) == 2: proj_type, pag = value.split("_") value_pag = True if pag == _WITH_PAG else False value_proj = ProjectionType(proj_type) return cls(_calculation_conf(value_proj, value_pag)) elif isinstance(value, cls): return value else: for member in cls: if value in (member.value, member.name()): return member raise ValueError(f"Cannot convert: {value}") class AxisResource(object): """Helper for axis file relative stuff""" _PAGANIN_CONFIG = {"distance": 100e-3, "energy": 35, "delta_beta": 1e3} """Paganin configuration for axis calculation. To simplify we have only one static configuration for now. Otherwise complicate stuff""" def __init__(self, url: None | DataUrl, angle: float | None = None): assert url is None or isinstance(url, DataUrl) assert url is None or url.is_valid() self.__url = url self.__raw_data = None self.__norme_data = None self.__norm_paganin = None self.__angle = angle def __str__(self): return f"{type(self)}, url: {self.__url.path() if self.__url else None}" @property def url(self): return self.__url @property def data(self): """ :return: 2D numpy.array """ if self.__url is None: return None if self.__raw_data is None: self.__raw_data = get_data(self.url) return self.__raw_data @data.setter def data(self, data): self.__raw_data = data @property def normalized_data(self): return self.__norme_data @normalized_data.setter def normalized_data(self, data): self.__norme_data = data @property def angle(self) -> float | None: return self.__angle def normalize_data(self, scan, log_): """Normalize data for axis calculation""" if not isinstance(scan, TomwerScanBase): raise TypeError( f"scan is expected to be an instance of {TomwerScanBase}. {type(scan)} provided" ) if self.__url is None: return None else: self.__norme_data = scan.data_flat_field_correction(data=self.data) if log_ is True: self.__norme_data[numpy.isnan(self.__norme_data)] = ( self.__norme_data.max() ) if self.__norme_data.max() < 0: _logger.error("max data value < 0 unable to compute log") else: try: data = self.__norme_data data[data <= 1] = 1 self.__norme_data = -numpy.log(data) except Exception as e: _logger.error("Fail to apply log on radio" + e) else: self.__norme_data[numpy.isnan(self.__norme_data)] = ( self.__norme_data.min() ) return self.__norme_data @property def normalized_data_paganin(self): """ :return: data processed by the Pagagin phase retrieval """ if self.__url is None: return None if self.__norm_paganin is None: if self.normalized_data is None: raise ValueError("data should be normalized before applying " "paganin") else: data = self.normalized_data phase_retrieval = PaganinPhaseRetrieval( data.shape, **AxisResource._PAGANIN_CONFIG ) self.__norm_paganin = phase_retrieval.apply_filter(data) return self.__norm_paganin @normalized_data_paganin.setter def normalized_data_paganin(self, data): self.__norm_paganin = data def __eq__(self, other): if not isinstance(other, AxisResource): return False if self.url is None and other.url is None: return True elif self.url is None or other.url is None: return False else: return self.url == other.url class AxisRP: """ Configuration class for a tomwer :class:`AxisTask` note: every modification on the parameters will process a call fo changed except `axis_url_1` and `axis_url_2` which will produce a call to the dedicated axis_url_changed """ AXIS_POSITION_PAR_KEY = "ROTATION_AXIS_POSITION" """Key used for the axis position in par files""" _MANAGED_KEYS = ( "MODE", "POSITION_VALUE", "CALC_INPUT_TYPE", "USE_SINOGRAM", "ANGLE_MODE", "SINOGRAM_LINE", "AXIS_URL_1", "AXIS_URL_2", "LOOK_AT_STDMAX", "NEAR_WX", "FINE_STEP_X", "SCALE_IMG2_TO_IMG1", "NEAR_POSITION", "MOTOR_OFFSET", "X_ROTATION_AXIS_PIXEL_POSITION", "SINOGRAM_SUBSAMPLING", "PADDING_MODE", "FLIP_LR", "COMPOSITE_OPTS", "COR_OPTIONS", ) def __init__(self): self.__mode = AxisMode.manual """Mode used for defining the COR (center of rotation)""" self.__relative_value = None """Value of the center of rotation in [0; image_width]. None is not processing. This value is on the *raw* frames referential as expected by nabu. It means it doesn't take into account possible detector flips. """ self.__absolute_value = None """ Value of the center of rotation in [-image_width/2; image_width/2]. None is not processing. This value is on the *raw* frames referential as expected by nabu. It means it doesn't take into account possible detector flips. """ self.__angle_mode = CorAngleMode.use_0_180 """Angle to use for radios""" self.__x_rotation_axis_pixel_position = None """rotation axis position obtained from motor. In the **raw** frame referential.""" self.__x_rotation_axis_pos_px_offset = 0.0 """motor offset to be used to compute the 'estimated_cor' from 'x_rotation_axis_pixel_position'""" self.__estimated_cor = 0.0 """Estimated position of the center of rotation. Given by the user or computed from 'x_rotation_axis_pixel_position' and 'pixel_offset'. In the **raw** frame referential. """ self.__axis_url_1 = AxisResource(url=None) """first data url to use for axis cor calculation""" self.__axis_url_2 = AxisResource(url=None) """second data url to use for axis cor calculation""" self.__calculation_input_type = AxisCalculationInput.transmission """Type of input (emission, absorption, with or without paganin)""" self.__sinogram_line = "middle" """Line of the radios to use for getting the sinogram""" self.__sinogram_subsampling = 10 """if use sinogram activate, we can use a subsampling to reduce computation time""" self.__look_at_stdmax = False """do the near search at X position which as the max Y column standard deviation""" self.__composite_window_size = 5 """do the near search in an X window of size +-near_wx""" self.__composite_fine_step = 0.1 """shift step x for fine shifting image""" self.__scale_img2_to_img1 = False """do image scaling""" self.__padding_mode = None self.__frame_width = None self.__flip_lr = True self.__composite_options = { "theta": DEFAULT_CMP_THETA, "n_subsampling_y": DEFAULT_CMP_N_SUBSAMPLING_Y, "oversampling": DEFAULT_CMP_OVERSAMPLING, "take_log": DEFAULT_CMP_TAKE_LOG, "near_pos": DEFAULT_CMP_NEAR_POS, "near_width": DEFAULT_CMP_NEAR_WIDTH, } """specific options for composite cor search""" self.__extra_cor_options = "" """Automatic cor options as str. side, near_pos and near_width are provided independantly""" @property def mode(self): return self.__mode @mode.setter def mode(self, mode): self.__mode = AxisMode.from_value(mode) self.changed() @property def frame_width(self) -> float | None: return self.__frame_width @frame_width.setter def frame_width(self, value): if not isinstance(value, (type(None), float, int)): raise TypeError( f"Value is expected to be None or a float. Not {type(value)}" ) if value is None: self.__frame_width = value else: self.__frame_width = float(value) @property def angle_mode(self): return self.__angle_mode @angle_mode.setter def angle_mode(self, mode): if type(mode) is str: mode = CorAngleMode.from_value(mode) if self.__angle_mode != mode: self.__angle_mode = mode self.changed() @property def relative_cor_value(self): return self.__relative_value @property def absolute_cor_value(self): return self.__absolute_value def set_relative_value(self, value): if not isinstance(value, (int, float, str, type(None))): raise TypeError( f"value is expected to be an instance of {int}, {float}, {str}, or {None}. {type(value)} provided" ) if value is None: changed = self.__relative_value is not None elif isinstance(value, str) and value == "...": changed = self.__relative_value != "..." else: changed = self.__relative_value != float(value) if changed: if value is None or (isinstance(value, str) and value == "..."): self.__relative_value = value self.__absolute_value = value else: self.__relative_value = float(value) if self.frame_width is not None: self.__absolute_value = relative_pos_to_absolute( relative_pos=self.__relative_value, det_width=self.frame_width ) self.changed() @property def estimated_cor(self) -> Side | float | None: return self.__estimated_cor @estimated_cor.setter def estimated_cor(self, value: Side | float | None): try: value = Side(value) except ValueError: pass if self.__estimated_cor != value: self.__estimated_cor = value self.changed() @property def x_rotation_axis_pos_px_offset(self) -> float: return self.__x_rotation_axis_pos_px_offset @x_rotation_axis_pos_px_offset.setter def x_rotation_axis_pos_px_offset(self, value: float): assert isinstance( value, float ), f"x_rotation_axis_pos_px_offset should be a float. Got {type(value)}" self.__x_rotation_axis_pos_px_offset = value @property def x_rotation_axis_pixel_position(self) -> float | None: return self.__x_rotation_axis_pixel_position @x_rotation_axis_pixel_position.setter def x_rotation_axis_pixel_position(self, value: float | None): assert isinstance( value, (float, type(None)) ), f"x_rotation_axis_pixel_position should be None or a float. Got{type(value)}" self.__x_rotation_axis_pixel_position = value @property def axis_url_1(self): """the first file to be used for the axis calculation""" return self.__axis_url_1 def _get_rsrc_frm_url(self, old_resource, new_url_): """ Util function to compare new resource / url with an existing one. """ new_resource = None changed = False if isinstance(new_url_, AxisResource): if old_resource != new_url_: changed = True new_resource = new_url_ elif isinstance(new_url_, str): if new_url_ == "": new_resource = AxisResource(None) else: new_resource = AxisResource(DataUrl(path=new_url_)) if old_resource != new_resource: changed = True else: assert isinstance(new_url_, DataUrl) or new_url_ is None new_resource = AxisResource(new_url_) if old_resource != new_resource: changed = True return new_resource, changed @axis_url_1.setter def axis_url_1(self, url_): new_resource, changed = self._get_rsrc_frm_url( old_resource=self.__axis_url_1, new_url_=url_ ) if changed is True: self.__axis_url_1 = new_resource self.axis_urls_changed() @property def axis_url_2(self): """the second file to be used for the axis calculation""" return self.__axis_url_2 @axis_url_2.setter def axis_url_2(self, url_): new_resource, changed = self._get_rsrc_frm_url( old_resource=self.__axis_url_2, new_url_=url_ ) if changed is True: self.__axis_url_2 = new_resource self.axis_urls_changed() @property def flip_lr(self): return self.__flip_lr @flip_lr.setter def flip_lr(self, flip: bool): if not isinstance(flip, bool): raise TypeError("flip should be a boolean") self.__flip_lr = flip @property def projection_type(self): return self.__calculation_input_type.value.projection_type @property def paganin_preproc(self): return self.__calculation_input_type.value.paganin @property def calculation_input_type(self): return self.__calculation_input_type @calculation_input_type.setter def calculation_input_type(self, type_): assert isinstance(type_, AxisCalculationInput) value = AxisCalculationInput.from_value(type_) if value != self.__calculation_input_type: self.__calculation_input_type = type_ self.changed() @property def sinogram_line(self): return self.__sinogram_line @sinogram_line.setter def sinogram_line(self, line): if line == "": if self.__sinogram_line is not None: self.__sinogram_line = None self.changed() else: if line == "middle": line = line elif line is not None: line = int(line) if self.__sinogram_line != line: self.__sinogram_line = line self.changed() @property def sinogram_subsampling(self) -> int: """Subsample radio to speed up processing of the sinogram generation""" return self.__sinogram_subsampling @sinogram_subsampling.setter def sinogram_subsampling(self, subsampling: int) -> None: subsampling = int(subsampling) if subsampling != self.__sinogram_subsampling: self.__sinogram_subsampling = subsampling self.changed() @property def look_at_stdmax(self): return self.__look_at_stdmax @look_at_stdmax.setter def look_at_stdmax(self, stdmax): self.__look_at_stdmax = stdmax @property def composite_window_size(self): return self.__composite_window_size @composite_window_size.setter def composite_window_size(self, width): if self.__composite_window_size != width: self.__composite_window_size = width self.changed() @property def composite_fine_step(self): """Fine step along x axis""" return self.__composite_fine_step @composite_fine_step.setter def composite_fine_step(self, step_size): if self.__composite_fine_step != step_size: self.__composite_fine_step = step_size self.changed() @property def scale_img2_to_img1(self): return self.__scale_img2_to_img1 @scale_img2_to_img1.setter def scale_img2_to_img1(self, scale): if self.__scale_img2_to_img1 != scale: self.__scale_img2_to_img1 = scale self.changed() @property def extra_cor_options(self) -> str: return self.__extra_cor_options @extra_cor_options.setter def extra_cor_options(self, cor_options: str): if not isinstance(cor_options, str): raise TypeError(f"{type(cor_options)} provided when {str} expected") else: clean_opts_str = ( cor_options.replace(" ", "").strip(";").rstrip(";").replace(";", " ; ") ) self.__extra_cor_options = clean_opts_str self.changed() @property def composite_options(self) -> dict: """return specific options for composite cor search""" return self.__composite_options @composite_options.setter def composite_options(self, opts: dict) -> None: """ :param opts: options to use for the composite COR search :raises: * KeyError if some provided keys are not handled * TypeError if opts is not an instance of dictionary """ if not isinstance(opts, dict): raise TypeError( f"opts is expected to be an instance of dict not {type(opts)}" ) # insure backward compatibility if "subsampling_y" in opts: opts["n_subsampling_y"] = opts.pop("subsampling_y") for key in opts.keys(): if key not in ( "theta", "oversampling", "n_subsampling_y", "take_log", "near_pos", "near_width", ): raise KeyError(f"{key} is not recognized") self.__composite_options = opts @property def padding_mode(self): return self.__padding_mode @padding_mode.setter def padding_mode(self, mode): if self.__padding_mode != mode: self.__padding_mode = mode self.changed() def changed(self): """callback to overwrite when the parameter value changed""" pass def n_url(self): """ :return: number of available url from url_1, url_2 """ n_url = 0 if self.axis_url_1 and self.axis_url_1.url: n_url += 1 if self.axis_url_2 and self.axis_url_2.url: n_url += 1 return n_url def to_dict(self): # keep octave compatibility axis_urls_1 = self.axis_url_1.url if axis_urls_1 is None: axis_urls_1 = "" else: axis_urls_1 = axis_urls_1.path() axis_urls_2 = self.axis_url_2.url if axis_urls_2 is None: axis_urls_2 = "" else: axis_urls_2 = axis_urls_2.path() _dict = { "MODE": self.mode.value, "POSITION_VALUE": self.relative_cor_value, "CALC_INPUT_TYPE": self.calculation_input_type.to_dict(), "ANGLE_MODE": self.angle_mode.value, "SINOGRAM_LINE": ( self.sinogram_line if self.mode.requires_sinogram_index() else "" ), "SINOGRAM_SUBSAMPLING": self.sinogram_subsampling, "AXIS_URL_1": axis_urls_1, "AXIS_URL_2": axis_urls_2, "LOOK_AT_STDMAX": self.look_at_stdmax, "NEAR_WX": self.composite_window_size, "FINE_STEP_X": self.composite_fine_step, "SCALE_IMG2_TO_IMG1": self.scale_img2_to_img1, "NEAR_POSITION": ( self.estimated_cor.value if isinstance(self.estimated_cor, Side) else self.estimated_cor ), "PADDING_MODE": self.padding_mode, "FLIP_LR": self.flip_lr, "COMPOSITE_OPTS": self.composite_options, "COR_OPTIONS": self.extra_cor_options, "MOTOR_OFFSET": self.x_rotation_axis_pos_px_offset, "X_ROTATION_AXIS_PIXEL_POSITION": self.x_rotation_axis_pixel_position, } return _dict @staticmethod def from_dict(_dict): axis = AxisRP() axis.load_from_dict(_dict=_dict) return axis def load_from_dict(self, _dict): # Convert managed keys to upper case _dict = { key.upper() if key.upper() in self._MANAGED_KEYS else key: value for key, value in _dict.items() } if "MODE" in _dict: self.mode = _dict["MODE"] if "POSITION_VALUE" in _dict: self.set_relative_value(_dict["POSITION_VALUE"]) if "CALC_INPUT_TYPE" in _dict: self.calculation_input_type = AxisCalculationInput.from_value( _dict["CALC_INPUT_TYPE"] ) if "ANGLE_MODE" in _dict: self.angle_mode = CorAngleMode.from_value(_dict["ANGLE_MODE"]) if "SINOGRAM_LINE" in _dict: self.sinogram_line = _dict["SINOGRAM_LINE"] if "AXIS_URL_1" in _dict: self.axis_url_1 = _dict["AXIS_URL_1"] if "AXIS_URL_2" in _dict: self.axis_url_2 = _dict["AXIS_URL_2"] if "LOOK_AT_STDMAX" in _dict: self.look_at_stdmax = _dict["LOOK_AT_STDMAX"] if "NEAR_WX" in _dict: self.composite_window_size = _dict["NEAR_WX"] if "FINE_STEP_X" in _dict: self.composite_fine_step = _dict["FINE_STEP_X"] if "SCALE_IMG2_TO_IMG1" in _dict: self.scale_img2_to_img1 = _dict["SCALE_IMG2_TO_IMG1"] if "NEAR_POSITION" in _dict: self.estimated_cor = _dict["NEAR_POSITION"] if "SINOGRAM_SUBSAMPLING" in _dict: self.sinogram_subsampling = _dict["SINOGRAM_SUBSAMPLING"] if "PADDING_MODE" in _dict: self.padding_mode = _dict["PADDING_MODE"] if "FLIP_LR" in _dict: self.flip_lr = bool(_dict["FLIP_LR"]) if "COMPOSITE_OPTS" in _dict: self.composite_options = _dict["COMPOSITE_OPTS"] self.extra_cor_options = _dict.get("COR_OPTIONS", "") def copy(self, axis_params, copy_axis_url=True, copy_flip_lr=True): assert isinstance(axis_params, AxisRP) self.mode = axis_params.mode self.frame_width = axis_params.frame_width self.set_relative_value(axis_params.relative_cor_value) self.calculation_input_type = axis_params.calculation_input_type self.angle_mode = axis_params.angle_mode self.sinogram_line = axis_params.sinogram_line self.sinogram_subsampling = axis_params.sinogram_subsampling self.look_at_stdmax = axis_params.look_at_stdmax self.composite_window_size = axis_params.composite_window_size self.composite_fine_step = axis_params.composite_fine_step self.scale_img2_to_img1 = axis_params.scale_img2_to_img1 self.estimated_cor = axis_params.estimated_cor self.x_rotation_axis_pixel_position = axis_params.x_rotation_axis_pixel_position self.x_rotation_axis_pos_px_offset = axis_params.x_rotation_axis_pos_px_offset self.padding_mode = axis_params.padding_mode self.composite_options = axis_params.composite_options self.extra_cor_options = axis_params.extra_cor_options if copy_axis_url: self.axis_url_1 = axis_params.axis_url_1 self.axis_url_2 = axis_params.axis_url_2 if copy_flip_lr: self.flip_lr = axis_params.flip_lr def __str__(self): return str(self.to_dict()) def axis_urls_changed(self): """Callback when the axis url change""" pass def get_simple_str(self): """ special information as a str for mode able to handle both sinogram and radios """ results = f"{self.mode.value}" if self.mode in ( AxisMode.growing_window_radios, AxisMode.growing_window_sinogram, AxisMode.sliding_window_radios, AxisMode.sliding_window_sinogram, ): extra_info = f"side: {self.estimated_cor}" results = ", ".join((results, extra_info)) return results def get_nabu_cor_options_as_dict(self) -> str: options = {} # provide side. Scalar if a first guess is provided else a value in ('left', 'right', 'center', 'all') if ( isinstance(self.estimated_cor, Side) and AXIS_MODE_METADATAS[self.mode].valid_sides ): options["side"] = self.estimated_cor.value elif AXIS_MODE_METADATAS[self.mode].allows_estimated_cor_as_numerical_value: options["side"] = self.estimated_cor if self.mode in (AxisMode.composite_coarse_to_fine, AxisMode.near): options["near_width"] = self.composite_options.get( "near_width", DEFAULT_CMP_NEAR_WIDTH ) options["theta_interval"] = self.composite_options.get( "theta_interval", DEFAULT_CMP_THETA ) options["oversampling"] = self.composite_options.get( "oversampling", DEFAULT_CMP_OVERSAMPLING ) options["n_subsampling_y"] = self.composite_options.get( "n_subsampling_y", DEFAULT_CMP_N_SUBSAMPLING_Y ) options["take_log"] = self.composite_options.get( "take_log", DEFAULT_CMP_TAKE_LOG ) # provide radio indices or sinogram index if self.mode.requires_radio_indices: # warning: nabu expect radio angles to be in rad, in nxtomo and tomwer they are in degrees options["radio_angles"] = ( numpy.deg2rad(self.axis_url_1.angle or 0.0), numpy.deg2rad(self.axis_url_2.angle or 180.0), ) if self.mode.requires_sinogram_index: options["slice_idx"] = self.sinogram_line # append "extra_cor_options" to already handled cor options # expected values: low_pass, high_pass extra_cor_options = self.extra_cor_options.replace(" ", "") if extra_cor_options != "": for opt in self.extra_cor_options.replace(" ", "").split(";"): if len(opt.split("=")) == 2: key, value = opt.split("=") if key in ("low_pass", "high_pass"): value = float(value) options[key] = value else: _logger.warning( f"key {key} is not recognized by nabu. Ignore it." ) else: _logger.info(f"ignore option {opt}. Invalid syntax") return options ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/axis/projectiontype.py0000644000175000017500000000025515153325210026407 0ustar00paynopayno# coding: utf-8 from enum import Enum as _Enum class ProjectionType(_Enum): """Type of projection""" transmission = "transmission" absorption = "absorption" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/axis/side.py0000644000175000017500000000020015153325210024243 0ustar00paynopaynofrom enum import Enum as _Enum class Side(_Enum): LEFT = "left" RIGHT = "right" CENTER = "center" ALL = "all" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1772989186.921101 tomwer-1.6.17/src/tomwer/core/process/reconstruction/darkref/0000755000175000017500000000000015153325403023433 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/darkref/__init__.py0000644000175000017500000000000015153325210025526 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/darkref/darkrefs.py0000644000175000017500000004110615153325210025604 0ustar00paynopayno""" This module provides global definitions and functions to manage dark and flat fields especially for tomo experiments and workflows """ from __future__ import annotations import logging import os from queue import Queue from processview.core.manager import DatasetState, ProcessManager from processview.core.superviseprocess import SuperviseProcess from tomwer.core.utils.deprecation import deprecated_warning from tomoscan.framereducer.target import REDUCER_TARGET from tomoscan.framereducer.method import ReduceMethod import tomwer.version from tomwer.core import settings from tomwer.core.utils.lbsram import is_low_on_memory from tomwer.core.process.task import Task from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils.scanutils import data_identifier_to_scan from tomwer.utils import docstring from . import params as dkrf_reconsparams logger = logging.getLogger(__name__) class DarkRefsTask( Task, SuperviseProcess, Queue, # TODO: fixme: this does not make much sense for a task input_names=("data",), output_names=("data",), optional_input_names=("serialize_output_data",), ): """Compute median/mean dark and ref from originals (dark and ref files)""" WHAT_REF = "refs" WHAT_DARK = "dark" VALID_WHAT = (WHAT_REF, WHAT_DARK) """Tuple of valid option for What""" info_suffix = ".info" TOMO_N = "TOMO_N" def __init__( self, process_id=None, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None, ): """ :param file_ext: :param reconsparams: reconstruction parameters """ Task.__init__( self, varinfo=varinfo, inputs=inputs, node_id=node_id, node_attrs=node_attrs, execinfo=execinfo, ) SuperviseProcess.__init__(self, process_id=process_id) Queue.__init__(self) if inputs is None: inputs = {} if "recons_params" in inputs or "reconsparams" in inputs: raise ValueError( "wrong key: recons_params / reconsparams use dark_ref_params instead" ) self._recons_params = inputs.get("dark_ref_params", None) if self._recons_params is None: self._recons_params = dkrf_reconsparams.DKRFRP() elif isinstance(self._recons_params, dict): self._recons_params = dkrf_reconsparams.DKRFRP.from_dict( self._recons_params ) if not isinstance(self._recons_params, dkrf_reconsparams.DKRFRP): raise TypeError( f"'reconsparams' should be an instance of {dkrf_reconsparams.DKRFRP} or {dict}. Not {type(self._recons_params)}" ) self._file_ext = inputs.get("file_ext", ".edf") if not type(self._file_ext) is str: raise TypeError("'file_ext' is expected to be a string") self._forceSync = inputs.get("force_sync", False) self.__new_hdf5_entry_created = False "used to know if the process has generated a new entry or not" @property def recons_params(self): return self._recons_params def set_recons_params(self, recons_params): if isinstance(recons_params, dkrf_reconsparams.DKRFRP): self._recons_params = recons_params else: raise TypeError( "recons_params should be an instance of " "ReconsParams or DKRFRP" ) def setPatternRecons(self, pattern): self._patternReconsFile = pattern def setForceSync(self, b): self._forceSync = True @staticmethod def getRefHSTFiles(directory, prefix, file_ext=".edf"): """ :return: the list of existing refs files in the directory according to the file pattern. """ assert isinstance(directory, str) res = [] if os.path.isdir(directory) is False: logger.error( directory + " is not a directory. Cannot extract " "RefHST files" ) return res for file in os.listdir(directory): if file.startswith(prefix) and file.endswith(file_ext): res.append(os.path.join(directory, file)) assert os.path.isfile(res[-1]) return res @staticmethod def getDarkHSTFiles(directory, prefix, file_ext=".edf"): """ :return: the list of existing refs files in the directory according to the file pattern. """ res = [] if os.path.isdir(directory) is False: logger.error( directory + " is not a directory. Cannot extract " "DarkHST files" ) return res for file in os.listdir(directory): _prefix = prefix if prefix.endswith(file_ext): _prefix = prefix.rstrip(file_ext) if file.startswith(_prefix) and file.endswith(file_ext): _file = file.lstrip(_prefix).rstrip(file_ext) if _file == "" or _file.isnumeric() is True: res.append(os.path.join(directory, file)) assert os.path.isfile(res[-1]) return res @staticmethod def getDarkPatternTooltip(): return ( "define the pattern to find, using the python `re` library.\n" "For example: \n" " - `.*conti_dark.*` to filter files containing `conti_dark` sentence\n" " - `darkend[0-9]{3,4}` to filter files named `darkend` followed by three or four digit characters (and having the .edf extension)" ) @staticmethod def getRefPatternTooltip(): return ( "define the pattern to find, using the python `re` library.\n" "For example: \n" " - `.*conti_ref.*` for files containing `conti_dark` sentence\n" " - `ref*.*[0-9]{3,4}_[0-9]{3,4}` to filter files named `ref` followed by any character and ending by X_Y where X and Y are groups of three or four digit characters." ) @staticmethod def properties_help(): return """ - refs: 'None', 'Median', 'Average', 'First', 'Last' \n - dark: 'None', 'Median', 'Average', 'First', 'Last' \n """ def set_configuration(self, properties): # No properties stored for now if "dark" in properties: self._recons_params.dark_calc_method = properties["dark"] if "refs" in properties: self._recons_params.flat_calc_method = properties["refs"] if "_rpSetting" in properties: self._recons_params.load_from_dict(properties["_rpSetting"]) else: self._recons_params.load_from_dict(properties) def run(self): if isinstance(self.inputs.data, str): try: scan = data_identifier_to_scan(self.inputs.data) except ValueError: # in the case fails to cast str to identifier (data can be a simple folder in the case of dark ref) scan = self.inputs.data else: scan = self.inputs.data if scan is None: self.outputs.data = None return if type(scan) is str: assert os.path.exists(scan) scan = ScanFactory.create_scan_object(scan_path=scan) elif isinstance(scan, TomwerScanBase): pass elif isinstance(scan, dict): scan = ScanFactory.create_scan_object_frm_dict(scan) else: raise TypeError( "scan should be an instance of TomoBase or path to " "scan dircetory" ) assert isinstance(self._recons_params, dkrf_reconsparams.DKRFRP) assert self._recons_params is not None ProcessManager().notify_dataset_state( dataset=scan, process=self, state=DatasetState.ON_GOING, ) logger.processStarted(f"start dark and ref for {scan}") if ( settings.isOnLbsram(scan) and is_low_on_memory(settings.get_lbsram_path()) is True ): mess = ( "low memory, do compute dark and flat field mean/median " "for %s" % scan.path ) logger.processSkipped(mess) ProcessManager().notify_dataset_state( dataset=scan, process=self, state=DatasetState.SKIPPED, details=mess, ) self.outputs.data = None return if not (scan and os.path.exists(scan.path)): mess = f"folder {scan.folder} is not existing" logger.warning(mess) ProcessManager().notify_dataset_state( dataset=scan, process=self, state=DatasetState.FAILED, details=mess ) self.outputs.data = None return whats = (DarkRefsTask.WHAT_REF, DarkRefsTask.WHAT_DARK) overwrites = ( self.recons_params.overwrite_flat, self.recons_params.overwrite_dark, ) modes = ( self.recons_params.flat_calc_method, self.recons_params.dark_calc_method, ) has_reduced = ( scan.reduced_flats not in (None, {}), scan.reduced_darks not in (None, {}), ) for what, mode, overwrite, exists in zip(whats, modes, overwrites, has_reduced): # if reduced already exists and user didn't asked for overwritting it if exists and not overwrite: continue logger.debug(f"compute {what} using mode {mode} for {scan}") try: self.compute(scan=scan, target=what, method=mode, overwrite=True) except Exception as e: info = f"Fail computing dark and flat for {scan}. Reason is {e}" self.notify_to_state_to_managed( dataset=scan, state=DatasetState.FAILED, details=info ) logger.processFailed(info) self.outputs.data = None return results = {} interpretations = {} if ( self.recons_params.dark_calc_method is not dkrf_reconsparams.ReduceMethod.NONE and scan.reduced_darks is not None ): # cast darks and flats keys from int (index) to str o_darks = scan.reduced_darks o_darks_infos = scan.reduced_darks_infos f_darks = {} for index, data in o_darks.items(): f_darks[str(index)] = data interpretations["/".join(("darks", str(index)))] = "image" results["darks"] = f_darks scan.save_reduced_darks(f_darks, darks_infos=o_darks_infos, overwrite=True) if ( self.recons_params.flat_calc_method is not dkrf_reconsparams.ReduceMethod.NONE and scan.reduced_flats is not None ): results["flats"] = scan.reduced_flats o_flats = scan.reduced_flats o_flats_infos = scan.reduced_flats_infos f_flats = {} for index, data in o_flats.items(): f_flats[str(index)] = data interpretations["/".join(("flats", str(index)))] = "image" results["flats"] = f_flats scan.save_reduced_flats(f_flats, flats_infos=o_flats_infos, overwrite=True) logger.processSucceed(f"Dark and flat reduction succeeded for {scan}") self.notify_to_state_to_managed( dataset=scan, state=DatasetState.SUCCEED, details=None ) if self.get_input_value("serialize_output_data", True): self.outputs.data = scan.to_dict() else: self.outputs.data = scan @staticmethod def _target_to_reducer_target(target): """ util to insure connection between 'historical' tomwer dark / ref and latest tomoscan FrameReducer """ if target == "refs": return REDUCER_TARGET.FLATS elif target == "dark": return REDUCER_TARGET.DARKS return REDUCER_TARGET(target) def compute( self, scan, target: REDUCER_TARGET, method: ReduceMethod, overwrite: bool ): target = self._target_to_reducer_target(target) method = ReduceMethod(method) if target is REDUCER_TARGET.DARKS: reduced_darks, metadata = scan.compute_reduced_darks( reduced_method=method, overwrite=overwrite, return_info=True, ) scan.set_reduced_darks(darks=reduced_darks, darks_infos=metadata) try: scan.save_reduced_darks( darks=reduced_darks, darks_infos=metadata, overwrite=True ) except Exception as e: logger.error(f"Fail to save reduced darks. Error is {e}") elif target is REDUCER_TARGET.FLATS: reduced_flats, metadata = scan.compute_reduced_flats( reduced_method=method, overwrite=overwrite, return_info=True, ) scan.set_reduced_flats(flats=reduced_flats, flats_infos=metadata) try: scan.save_reduced_flats( flats=reduced_flats, flats_infos=metadata, overwrite=True ) except Exception as e: logger.error(f"Fail to save reduced flats. Error is {e}") else: raise RuntimeError(f"{target} not handled") @docstring(Task.program_name) @staticmethod def program_name(): return "tomwer_dark_refs" @docstring(Task.program_version) @staticmethod def program_version(): return tomwer.version.version @docstring(Task.definition) @staticmethod def definition(): return "Compute mean or median dark and refs per each series" def requires_reduced_dark_and_flat( scan: TomwerScanBase, logger_: logging.Logger | None = None ) -> tuple: r"""helper function: If no dark / flat are computed yet then will pick the first dark and the first flat. Expected usage: for tomwer application which requires some time and flat and to avoid some warnings within standalones. :params scan: scan for which we want to get quick dark and flat :params logger\_: if provided will add some warning when attempt to get reduced flat / dark. :returns: tuple of what was missing and has been computed """ computed = [] if scan.reduced_flats in (None, {}): # set the first flat found recons_params = dkrf_reconsparams.DKRFRP() recons_params.overwrite_dark = False recons_params.overwrite_flat = False recons_params.dark_calc_method = dkrf_reconsparams.ReduceMethod.NONE recons_params.flat_calc_method = dkrf_reconsparams.ReduceMethod.FIRST drp = DarkRefsTask( inputs={ "data": scan, "dark_ref_params": recons_params, "serialize_output_data": False, } ) if logger_ is not None: logger.warning( "No 'reduced' flat found. Will try to pick the first flat found as the `calculated` flat." ) drp.run() computed.append("flat") if scan.reduced_darks in (None, {}): # set the first dark found recons_params = dkrf_reconsparams.DKRFRP() recons_params.overwrite_dark = False recons_params.overwrite_flat = False recons_params.dark_calc_method = dkrf_reconsparams.ReduceMethod.FIRST recons_params.flat_calc_method = dkrf_reconsparams.ReduceMethod.NONE drp = DarkRefsTask( inputs={ "data": scan, "dark_ref_params": recons_params, "serialize_output_data": False, } ) if logger_ is not None: logger.warning( "No 'reduced' dark found. Will try to pick the first flat found as the `calculated` dark." ) drp.run() computed.append("dark") return tuple(computed) class DarkRefs(DarkRefsTask): def __init__( self, process_id=None, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None, ): deprecated_warning( name="tomwer.core.process.reconstruction.darkref.darkref.DarkRefs", type_="class", reason="improve readibility", since_version="1.2", replacement="DarkRefsTask", ) super().__init__(process_id, varinfo, inputs, node_id, node_attrs, execinfo) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/darkref/darkrefscopy.py0000644000175000017500000003123715153325210026503 0ustar00paynopayno""" This module is used to define the process of the reference creator. This is related to the issue #184 """ from __future__ import annotations import logging import os import h5py import tempfile from silx.io.dictdump import dicttoh5, h5todict from silx.io.url import DataUrl from silx.io.utils import open as open_hdf5 from tomoscan.esrf.scan.utils import ( copy_h5_dict_darks_to, copy_h5_dict_flats_to, cwd_context, ) from tomoscan.framereducer.target import REDUCER_TARGET from tomoscan.io import HDF5File from tomwer.core.process.reconstruction.darkref.darkrefs import DarkRefsTask from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.utils.scanutils import data_identifier_to_scan logger = logging.getLogger(__name__) class DarkRefsCopy(DarkRefsTask): """ Reimplement Dark ref to deal with copy when there is no median/mean files """ DEFAULT_SRCURRENT = 200.0 # mA def __init__( self, process_id=None, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None, ): super().__init__( process_id=process_id, varinfo=varinfo, inputs=inputs, node_id=node_id, node_attrs=node_attrs, execinfo=execinfo, ) if inputs is None: inputs = {} self._mode_auto = inputs.get("mode_auto", True) if "savedir" in inputs: raise KeyError("savedir is not a valid key. Use save_dir") self._savedir = inputs.get("save_dir", tempfile.mkdtemp()) self._save_file = self.get_save_file(self._savedir) self._darks_url = self.get_darks_url(self._savedir) self._flats_url = self.get_flats_url(self._savedir) logger.info(f"Flats and darks will be stored in {self._save_file}") self._processOnlyCopy = inputs.get("process_only_copy", False) self._processOnlyDkRf = inputs.get("process_only_dkrf", False) init_ref_scan = inputs.get("init_dkrf_from", None) if init_ref_scan: if not isinstance(init_ref_scan, TomwerScanBase): raise TypeError( f"init_ref_scan is expected to be an instance of TomwerScanBase. Not {type(init_ref_scan)}" ) else: self.set_darks_and_flats_from_scan(init_ref_scan) @staticmethod def get_save_file(save_dir): return os.path.join(save_dir, "darks_and_flats.h5") @staticmethod def get_flats_url(save_dir): return DataUrl( file_path=DarkRefsCopy.get_save_file(save_dir), data_path="/flats", scheme="silx", ) @staticmethod def get_darks_url(save_dir): return DataUrl( file_path=DarkRefsCopy.get_save_file(save_dir), data_path="/darks", scheme="silx", ) def set_process_only_dkRf(self, value: bool) -> None: self._processOnlyDkRf = value self._processOnlyCopy = False def set_process_only_copy(self, value: bool) -> None: self._processOnlyDkRf = False self._processOnlyCopy = value @staticmethod def get_reduced_frame_data( url: DataUrl, reduced_target: REDUCER_TARGET, check_for_reduced_key: bool = True ) -> tuple: """ :param url: url expected to contain the dict with one key per serie of reduced frame :param reduced_target: what we are looking for (used when check_for_reduced_key is set to True) :param check_for_reduced_key: if True then if the dict contains the given key then return the value of this key instead of the loaded dict. Used as a user friendly feature to be able to load dict when upper data path is provided instead of the 'darks' or 'flats' one. :return: tuple as (data, metadata) """ reduced_target = REDUCER_TARGET(reduced_target) with cwd_context(url.file_path()): try: reduced_info_dict = h5todict( h5file=url.file_path(), path=url.data_path(), ) except Exception as e: logger.error(e) return None else: if check_for_reduced_key and reduced_target.value in reduced_info_dict: return reduced_info_dict[reduced_target.value] else: return reduced_info_dict @staticmethod def save_flats_to_be_copied(save_dir, data: DataUrl | dict): if isinstance(data, DataUrl): data = DarkRefsCopy.get_reduced_frame_data(url=data, reduced_target="flats") if data is None: return flat_url = DarkRefsCopy.get_flats_url(save_dir) # remove group if already exists: else can end up by copying several dark / flat from different datasets with HDF5File(flat_url.file_path(), mode="a") as h5f: if flat_url.data_path() in h5f: del h5f[flat_url.data_path()] dicttoh5( data, h5file=flat_url.file_path(), h5path=flat_url.data_path(), mode="a", update_mode="replace", ) @staticmethod def save_darks_to_be_copied(save_dir, data: DataUrl | dict): if isinstance(data, DataUrl): data = DarkRefsCopy.get_reduced_frame_data(url=data, reduced_target="darks") if data is None: return dark_url = DarkRefsCopy.get_darks_url(save_dir) # remove group if already exists: else can end up by copying several dark / flat from different datasets with HDF5File(dark_url.file_path(), mode="a") as h5f: if dark_url.data_path() in h5f: del h5f[dark_url.data_path()] dicttoh5( data, h5file=dark_url.file_path(), h5path=dark_url.data_path(), mode="a", update_mode="replace", ) def clear_cache(self): """ remove the file used to cache the reduced darks / flats. This can be used in the case it contain unrelevant data. Like frame with another shape... """ cache_file = DarkRefsCopy.get_save_file(self._savedir) if os.path.exists(cache_file): os.remove(cache_file) def _clear_cache_data_path(self, file_path: str, data_path: str): if not os.path.exists(file_path): return with h5py.File(file_path, mode="a") as h5f: if data_path in h5f: del h5f[data_path] def set_darks_and_flats_from_scan(self, scan: TomwerScanBase) -> bool: has_flats = scan.reduced_flats not in (None, {}) has_darks = scan.reduced_darks not in (None, {}) if has_flats and has_darks: # if the scan has darks and flats remove directly the cache file # else in append mode HDF5 is not removing the dataset and # the cache size will continue to increase self.clear_cache() if not has_flats: logger.warning(f"No flat found for {scan}. Unable to copy them") else: self._clear_cache_data_path( file_path=self._flats_url.file_path(), data_path=self._flats_url.data_path(), ) dicttoh5( scan.reduced_flats, h5file=self._flats_url.file_path(), h5path=self._flats_url.data_path(), mode="a", update_mode="replace", ) if not has_darks: logger.warning(f"No dark found for {scan}. Unable to copy them") else: self._clear_cache_data_path( file_path=self._darks_url.file_path(), data_path=self._darks_url.data_path(), ) dicttoh5( scan.reduced_darks, h5file=self._darks_url.file_path(), h5path=self._darks_url.data_path(), mode="a", update_mode="replace", ) self._ref_has_been_set(scan=scan) def _ref_has_been_set(self, scan): pass def _copy_to(self, scan): if not isinstance(scan, TomwerScanBase): raise TypeError( f"{scan} is expected to be an instance of {TomwerScanBase} and not {type(scan)}" ) if self.has_dark_stored(): copy_h5_dict_darks_to( scan=scan, darks_url=self._darks_url, save=True, raise_error_if_url_empty=True, overwrite=True, ) if self.has_flat_stored(): copy_h5_dict_flats_to( scan=scan, flats_url=self._flats_url, save=True, raise_error_if_url_empty=True, overwrite=True, ) def run(self): """ This is function triggered when a new scan / data is received. As explained in issue #184 the behavior is the following: * if the scan has already ref files files won't be overwrite * if the mode is in `auto` will register last ref file met * if the scan has no ref files and refCopy has some register. Will create a copy of those, normalized from srCurrent (for flat field) """ scan = data_identifier_to_scan(self.inputs.data) if not isinstance(scan, (type(None), TomwerScanBase, dict)): raise TypeError( f"self.inputs.data is expected to be an instance " f"of None, TomwerScanBase or dict. Not {type(scan)}" ) if scan is None or scan.path is None: return # process dark and ref calculation if not self._processOnlyCopy: super().run() # then copy if necessary if not self._processOnlyDkRf: if self.contains_dark_or_ref(scan): if self.is_on_mode_auto: self.set_darks_and_flats_from_scan(scan) if self.has_missing_dark_or_ref(scan): self._copy_to(scan) def has_flat_or_dark_stored(self) -> bool: """ :return: True if the process has at least registered one flat or one dark """ return self.has_flat_stored() or self.has_dark_stored() def has_flat_stored(self) -> bool: """ :return: True if the process has registered at least one ref """ if not os.path.exists(self._save_file): return False else: with open_hdf5(self._save_file) as h5f: return self._flats_url.data_path() in h5f def has_dark_stored(self) -> bool: """ :return: True if the process has registered at least one dark """ if not os.path.exists(self._save_file): return False else: with open_hdf5(self._save_file) as h5f: return self._darks_url.data_path() in h5f def contains_dark(self, scan: TomwerScanBase) -> bool: """Return True if the scan has already some dark processed""" if not isinstance(scan, TomwerScanBase): return TypeError( f"scan is expected to be an instance of {TomwerScanBase} and not {type(scan)}" ) else: return scan.reduced_darks or scan.load_reduced_darks() def contains_flat(self, scan: TomwerScanBase): """Return True if the scan has already some dark processed""" if not isinstance(scan, TomwerScanBase): return TypeError( f"scan is expected to be an instance of {TomwerScanBase} and not {type(scan)}" ) else: return scan.reduced_flats or scan.load_reduced_flats() def contains_dark_or_ref(self, scan): return self.contains_dark(scan=scan) or self.contains_flat(scan=scan) def has_missing_dark_or_ref(self, scan: TomwerScanBase) -> bool: """return True if the scan has no ref or no dark registered""" assert isinstance(scan, TomwerScanBase) return not self.contains_dark(scan) or not self.contains_flat(scan) def _signal_done(self, scan): assert isinstance(scan, TomwerScanBase) raise NotImplementedError("Abstract class") def set_mode_auto(self, b): self._mode_auto = b @property def is_on_mode_auto(self): return self._mode_auto @property def refHST_prefix(self): return self._refHstPrefix @property def darkHST_prefix(self): return self._darkHstPrefix def set_refHST_prefix(self, prefix): self._refHstPrefix = prefix def set_darkHST_prefix(self, prefix): self._darkHstPrefix = prefix ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/darkref/params.py0000644000175000017500000002100315153325210025260 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import enum from tomoscan.framereducer.method import ReduceMethod from tomwer.core.process.reconstruction.darkref.settings import ( DARKHST_PREFIX, REFHST_PREFIX, ) from tomwer.core.process.reconstruction.paramsbase import _ReconsParam from tomwer.core.utils.deprecation import deprecated # TODO: those classes (when, method) should be linked / embedded in the DarkRef # method @enum.unique class When(enum.Enum): never = (0,) before = (1,) after = (2,) def _from_value_reduce_method_backward_compatibility(value) -> ReduceMethod: if value in ("none", 0, (0,)): return ReduceMethod.NONE elif value in ("average", 1, (1,)): return ReduceMethod.MEAN elif value in ("median", 2, (2,)): return ReduceMethod.MEDIAN elif value in ("first", 10, (10,)): return ReduceMethod.FIRST elif value in ("last", 11, (11,)): return ReduceMethod.FIRST else: return ReduceMethod(value) class DKRFRP(_ReconsParam): """Settings for the calculation of dark and flat fields mean or median""" def __init__(self): _ReconsParam.__init__(self) self.__do_when = When.before self.__dark_calc = ReduceMethod.MEAN self.__overwrite_dark = False self.__remove_dark = False self.__dark_pattern = "darkend[0-9]{3,4}" self.__flat_calc = ReduceMethod.MEDIAN self.__overwrite_flat = False self.__remove_flats = False self.__flat_pattern = "ref*.*[0-9]{3,4}_[0-9]{3,4}" self.__dark_prefix = DARKHST_PREFIX self.__ref_prefix = REFHST_PREFIX self._managed_params = { "DOWHEN": self.__class__.do_when, "DARKCAL": self.__class__.dark_calc_method, "DARKOVE": self.__class__.overwrite_dark, "DARKRMV": self.__class__.remove_dark, "DKFILE": self.__class__.dark_pattern, "REFSCAL": self.__class__.flat_calc_method, "REFSOVE": self.__class__.overwrite_flat, "REFSRMV": self.__class__.remove_raw_flats, "RFFILE": self.__class__.flat_pattern, } @property def do_when(self): """When should we process calculation. Should be removed now that DKRF process exists. Was needed for fastomo3""" return self.__do_when @do_when.setter def do_when(self, when): assert isinstance(when, (int, When)) when = When(when) if when != self.__do_when: self.__do_when = when self.changed() @property def dark_calc_method(self): """Dark calculation Method""" return self.__dark_calc @dark_calc_method.setter def dark_calc_method(self, method): assert isinstance(method, (int, ReduceMethod, str)) _dark_calc = _from_value_reduce_method_backward_compatibility(method) if self.__dark_calc != _dark_calc: self.__dark_calc = _dark_calc self.changed() @property def overwrite_dark(self): """Overwrite Dark results if already exists""" return self.__overwrite_dark @overwrite_dark.setter def overwrite_dark(self, overwrite): assert isinstance(overwrite, (int, bool, float)) _overwrite_dark = bool(overwrite) if self.__overwrite_dark != _overwrite_dark: self.__overwrite_dark = _overwrite_dark self.changed() @property def remove_dark(self): """Remove original Darks files when done""" return self.__remove_dark @remove_dark.setter def remove_dark(self, remove): assert isinstance(remove, (int, bool, float)) _remove_dark = bool(remove) if _remove_dark != self.__remove_dark: self.__remove_dark = _remove_dark self.changed() @property def dark_pattern(self): """File pattern to detect edf Dark field""" return self.__dark_pattern @dark_pattern.setter def dark_pattern(self, pattern): _dark_pattern = pattern if self.__dark_pattern != _dark_pattern: self.__dark_pattern = _dark_pattern self.changed() @property def flat_calc_method(self): """Dark calculation method (None, Average, Median)""" return self.__flat_calc @flat_calc_method.setter def flat_calc_method(self, method): assert isinstance(method, (int, ReduceMethod, str)) _ref_calc = _from_value_reduce_method_backward_compatibility(method) if self.__flat_calc != _ref_calc: self.__flat_calc = _ref_calc self.changed() @property @deprecated(replacement="overwrite_flat", since_version="0.9") def overwrite_ref(self): return self.overwrite_flat @overwrite_ref.setter @deprecated(replacement="overwrite_flat", since_version="0.9") def overwrite_ref(self, overwrite): self.overwrite_flat = overwrite @property def overwrite_flat(self): """Overwrite Dark results if already exists""" return self.__overwrite_flat @overwrite_flat.setter def overwrite_flat(self, overwrite): assert isinstance(overwrite, (int, bool, float)) _overwrite_flat = bool(overwrite) if self.__overwrite_flat != _overwrite_flat: self.__overwrite_flat = _overwrite_flat self.changed() @property def remove_raw_flats(self): """Remove original flat / ref files when done (for EDF only)""" return self.__remove_flats @remove_raw_flats.setter def remove_raw_flats(self, remove): # TODO: float should be removed, but this is a legacy from fastomo3 assert isinstance(remove, (int, bool, float)) _remove_flats = remove if self.__remove_flats != _remove_flats: self.__remove_flats = _remove_flats self.changed() @property def flat_pattern(self): """File pattern to detect EDF flats files""" return self.__flat_pattern @flat_pattern.setter def flat_pattern(self, pattern): if pattern != self.__flat_pattern: self.__flat_pattern = pattern self.changed() @property def flat_prefix(self): """flat prefix for EDF""" return self.__ref_prefix @flat_prefix.setter def flat_prefix(self, prefix): if prefix != self.__ref_prefix: self.__ref_prefix = prefix self.changed() @property def dark_prefix(self): """dark prefix for EDF""" return self.__dark_prefix @dark_prefix.setter def dark_prefix(self, prefix): if prefix != self.__dark_prefix: self.__dark_prefix = prefix self.changed() def _set_remove_opt(self, rm): self.remove_raw_flats = rm self.remove_dark = rm def _set_skip_if_exist(self, skip): self.overwrite_flat = not skip self.overwrite_dark = not skip def to_dict(self): _dict = { "DOWHEN": self.do_when.name, "DARKCAL": self.dark_calc_method.value, "DARKOVE": int(self.overwrite_dark), "DARKRMV": int(self.remove_dark), "DKFILE": self.dark_pattern, "REFSCAL": self.flat_calc_method.value, "REFSOVE": int(self.overwrite_flat), "REFSRMV": int(self.remove_raw_flats), "RFFILE": self.flat_pattern, } _dict.update(self.unmanaged_params) return _dict @staticmethod def from_dict(_dict): params = DKRFRP() params.load_from_dict(_dict) return params def load_from_dict(self, _dict): # Convert managed keys to upper case _dict = { key.upper() if key.upper() in self.managed_params else key: value for key, value in _dict.items() } self._load_unmanaged_params(_dict=_dict) if "DOWHEN" in _dict: self.do_when = getattr(When, _dict["DOWHEN"]) if "DARKCAL" in _dict: self.dark_calc_method = _dict["DARKCAL"] if "DARKOVE" in _dict: self.overwrite_dark = _dict["DARKOVE"] if "DARKRMV" in _dict: self.remove_dark = _dict["DARKRMV"] if "DKFILE" in _dict: self.dark_pattern = _dict["DKFILE"] if "REFSCAL" in _dict: self.flat_calc_method = _dict["REFSCAL"] if "REFSOVE" in _dict: self.overwrite_flat = _dict["REFSOVE"] if "REFSRMV" in _dict: self.remove_raw_flats = _dict["REFSRMV"] if "RFFILE" in _dict: self.flat_pattern = _dict["RFFILE"] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/darkref/settings.py0000644000175000017500000000027415153325210025644 0ustar00paynopaynoREFHST_PREFIX = "refHST" DARKHST_PREFIX = "dark.edf" """Warning: here define the extension to in order to make difference between darkendXXXX.edf and dark.edf. dark only is not enough""" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1772989186.921101 tomwer-1.6.17/src/tomwer/core/process/reconstruction/nabu/0000755000175000017500000000000015153325403022742 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/nabu/__init__.py0000644000175000017500000000000015153325210025035 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/nabu/castvolume.py0000644000175000017500000002611215153325210025474 0ustar00paynopayno# coding: utf-8 """ This module is dedicated to cast of volume from one file format to the other. """ from __future__ import annotations import logging import os import numpy import pathlib from nabu.io.cast_volume import RESCALE_MAX_PERCENTILE, RESCALE_MIN_PERCENTILE from nabu.io.cast_volume import cast_volume as _nabu_cast_volume from nabu.io.cast_volume import get_default_output_volume from processview.core.manager import DatasetState, ProcessManager from processview.core.superviseprocess import SuperviseProcess from sluurp.executor import submit as submit_to_slurm_cluster from sluurp.job import SBatchScriptJob from tomoscan.volumebase import VolumeBase from tomoscan.utils.io import filter_esrf_mounting_points from tomwer.core.cluster.cluster import SlurmClusterConfiguration from tomwer.core.futureobject import FutureTomwerObject from tomwer.core.process.reconstruction.nabu import settings from tomwer.core.process.output import NabuOutputFileFormat from tomwer.core.process.reconstruction.nabu.utils import ( get_default_output_volume_for_tiff_3d, ) from tomwer.core.process.task import Task from tomwer.core.utils.scanutils import ( format_output_location as format_scan_output_location, ) from tomwer.core.utils.slurm import get_slurm_script_name from tomwer.core.utils.volumeutils import volume_identifier_to_volume from tomwer.core.volume.volumebase import TomwerVolumeBase from tomwer.core.volume.volumefactory import VolumeFactory from tomwer.core.process.drac.processeddataset import ( DracReconstructedVolumeDataset, ) _logger = logging.getLogger(__name__) CAST_VOLUME_WORKING_SUB_DIRECTORY = "cast_volume" DEFAULT_OUTPUT_DIR = ( "{volume_data_parent_folder}" f"/{CAST_VOLUME_WORKING_SUB_DIRECTORY}" ) class CastVolumeTask( Task, SuperviseProcess, input_names=( "volume", "configuration", ), optional_input_names=("scan", "output_volume"), output_names=( "volume", "future_tomo_obj", "data_portal_processed_datasets", ), ): def __init__( self, process_id=None, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None, ): SuperviseProcess.__init__(self, process_id=process_id) Task.__init__( self, varinfo=varinfo, inputs=inputs, node_id=node_id, node_attrs=node_attrs, execinfo=execinfo, ) self._cluster_config = None def run(self): input_volume = volume_identifier_to_volume(self.inputs.volume) if not isinstance(input_volume, VolumeBase): raise TypeError( f"input_volume is a {type(input_volume)} when {VolumeBase} expected" ) configuration = self.inputs.configuration self._cluster_config = configuration.pop("cluster_config", None) if isinstance(self._cluster_config, SlurmClusterConfiguration): self._cluster_config = self._cluster_config.to_dict() if self.inputs.scan: scan = self.inputs.scan else: scan = None if self.inputs.output_volume: output_volume = self.inputs.output_volume if not isinstance(output_volume, TomwerVolumeBase): output_volume = VolumeFactory.create_tomo_object_from_identifier( output_volume ) else: output_file_format = configuration.get( "output_file_format", None ) # expects values like hdf5, edf ... output_dir = configuration.get("output_dir", None) if output_file_format is None or output_dir is None: mess = "'output_volume' or ('output_file_format' and 'output_dir' from configuration) should be provided." _logger.processFailed(f"volume cast of {str(input_volume)} failed") ProcessManager().notify_dataset_state( dataset=scan or input_volume, process=self, state=DatasetState.FAILED, ) raise ValueError(mess) try: output_dir = TomwerVolumeBase.format_output_location( location=output_dir, volume=input_volume, ) except KeyError: pass if scan: try: output_dir = format_scan_output_location( location=output_dir, scan=scan, ) except KeyError: pass output_file_format = NabuOutputFileFormat.from_value(output_file_format) if output_file_format is NabuOutputFileFormat.TIFF_3D: output_volume = get_default_output_volume_for_tiff_3d( input_volume=input_volume, output_dir=output_dir, ) else: output_volume = get_default_output_volume( input_volume=input_volume, output_type=output_file_format.value, output_dir=output_dir, ) # convert from tomoscan volume to tomwer volume output_volume = VolumeFactory.create_tomo_object_from_identifier( output_volume.get_identifier().to_str() ) # build output volume object overwrite = configuration.get("overwrite", False) remove_input_volume = configuration.get("remove_input_volume", False) output_volume.overwrite = overwrite cratios = configuration.get("compression_ratios", None) if cratios is not None: output_volume.cratios = cratios output_data_type = numpy.dtype( configuration.get("output_data_type") ) # expects values like numpy uint8, unint16... rescale_min_percentile = configuration.get( "rescale_min_percentile", RESCALE_MIN_PERCENTILE ) rescale_max_percentile = configuration.get( "rescale_max_percentile", RESCALE_MAX_PERCENTILE ) data_min = configuration.get("data_min", None) data_max = configuration.get("data_max", None) # run volume cast locally if self._cluster_config is None: try: _nabu_cast_volume( input_volume=input_volume, output_volume=output_volume, output_data_type=output_data_type, data_min=data_min, data_max=data_max, scan=scan, rescale_min_percentile=rescale_min_percentile, rescale_max_percentile=rescale_max_percentile, save=True, store=False, remove_input_volume=remove_input_volume, ) except Exception as e: mess = f"volume cast of {str(input_volume)} failed. Reason is {str(e)}" _logger.processFailed(mess) state = DatasetState.FAILED else: mess = f"volume cast of {str(input_volume)} succeed" _logger.processSucceed(mess) state = DatasetState.SUCCEED ProcessManager().notify_dataset_state( dataset=scan or input_volume, process=self, state=state, details=mess, ) self.outputs.future_tomo_obj = None self.outputs.volume = output_volume if scan is not None: scan.cast_volume = output_volume.get_identifier() else: input_volume.cast_volume = output_volume.get_identifier() self.outputs.data_portal_processed_datasets = tuple() # run volume cast remotely else: def get_command(): command = f"python3 -m {settings.NABU_CAST_APP_PATH} '{input_volume.get_identifier().to_str()}'" command += ( f" --output_volume='{output_volume.get_identifier().to_str()}'" ) if overwrite: command += " --overwrite" command += f" --output-data-type={str(output_data_type)}" if data_min is not None: command += f" --data_min={data_min}" if data_max is not None: command += f" --data_max={data_max}" if rescale_min_percentile is not None: command += f" --rescale_min_percentile={rescale_min_percentile}" if rescale_max_percentile is not None: command += f" --rescale_max_percentile={rescale_max_percentile}" if remove_input_volume: command += " --remove-input-volume" return command script_name = get_slurm_script_name(prefix="nabu_cast") if scan is not None: working_directory = str(scan.working_directory.resolve()) script_path = os.path.join( scan.resolved_path, "slurm_scripts", script_name ) else: working_directory = os.path.dirname(input_volume.data_url.file_path()) working_directory = str(pathlib.Path(working_directory).resolve()) script_path = os.path.join( working_directory, "slurm_scripts", script_name ) # for now force job name self._cluster_config["job_name"] = ( f"tomwer-cast-volume {input_volume.get_identifier().to_str()} to {output_volume.get_identifier().to_str()}" ) job = SBatchScriptJob( slurm_config=self._cluster_config, script=(get_command(),), script_path=filter_esrf_mounting_points(script_path), clean_script=False, working_directory=filter_esrf_mounting_points(working_directory), ) future_slurm_job = submit_to_slurm_cluster(job) if scan is not None: future_obj = scan else: future_obj = output_volume self.outputs.future_tomo_obj = FutureTomwerObject( tomo_obj=future_obj, futures=(future_slurm_job,), process_requester_id=self.process_id, ) self.outputs.volume = output_volume if scan is not None: drac_reconstructed_dataset = DracReconstructedVolumeDataset( tomo_obj=output_volume, source_scan=scan, ) self.outputs.data_portal_processed_datasets = ( drac_reconstructed_dataset, ) # for now at the task level we consider this is succeed if it has been submitted ProcessManager().notify_dataset_state( dataset=scan or input_volume, process=self, state=DatasetState.SUCCEED, details="cast has been correctly submitted to slurm", ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/nabu/helical.py0000644000175000017500000000400215153325210024705 0ustar00paynopaynoimport logging from nabu.resources.nxflatfield import update_dataset_info_flats_darks from nabu.resources.dataset_analyzer import HDF5DatasetAnalyzer from nabu.io.reader import load_images_from_dataurl_dict from nabu.app.prepare_weights_double import create_heli_maps from tomwer.core.process.task import TaskWithProgress from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.utils.scanutils import format_output_location _logger = logging.getLogger(__name__) class NabuHelicalPrepareWeightsDouble( TaskWithProgress, input_names=( "data", "transition_width_vertical", "transition_width_horizontal", "processes_file", "rotation_axis_position", ), optional_input_names=("progress",), output_names=("data",), ): def run(self): # TODO: handle future /cluster config ??? scan = self.inputs.data if not isinstance(scan, NXtomoScan): raise TypeError(f"data is expected to be an instance of {NXtomoScan}") dataset_info = HDF5DatasetAnalyzer( scan.master_file, extra_options={"h5_entry": scan.entry}, ) update_dataset_info_flats_darks( dataset_info, flatfield_mode=1, loading_mode="load_if_present" ) mappe = 0 my_flats = load_images_from_dataurl_dict(dataset_info.flats) for _, flat in my_flats.items(): mappe += flat mappe = mappe / len(list(dataset_info.flats.keys())) scan.helical.processes_files = format_output_location( location=self.inputs.processes_file, scan=scan ) create_heli_maps( profile=mappe, process_file_name=scan.helical.processes_files, entry_name=scan.entry, transition_width_vertical=self.inputs.transition_width_vertical, transition_width_horizontal=self.inputs.transition_width_horizontal, rotation_axis_position=self.inputs.rotation_axis_position, ) self.outputs.data = scan ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/nabu/nabucommon.py0000644000175000017500000006032715153325210025456 0ustar00paynopayno"""contain utils for score process""" from __future__ import annotations import logging import os import subprocess import uuid from typing import Iterable import signal import psutil import sys import numpy from silx.io.url import DataUrl from silx.io.utils import open as open_hdf5 from silx.gui.utils import concurrent from sluurp.executor import submit as submit_to_slurm_cluster from sluurp.job import SBatchScriptJob from tomoscan.io import HDF5File from tomoscan.normalization import Method as INormMethod from tomoscan.identifier import VolumeIdentifier from tomoscan.utils.io import filter_esrf_mounting_points from tomwer.core.process.reconstruction.nabu.plane import NabuPlane from tomwer.core.cluster.cluster import SlurmClusterConfiguration from tomwer.core.process.reconstruction.nabu.target import Target from tomwer.core.process.reconstruction.nabu.utils import ( _NabuPhaseMethod, nabu_std_err_has_error, ) from tomwer.core.process.reconstruction.output import ( ProcessDataOutputDirMode, get_output_folder_from_scan, NabuOutputFileFormat, ) from tomwer.core.process.reconstruction.normalization.params import ( _ValueSource as INormSource, ) from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.utils.slurm import get_slurm_script_name, is_slurm_available from tomwer.core.volume.volumefactory import VolumeFactory from tomwer.core.resourcemanager import HDF5VolumeManager from tomwer.core.volume.hdf5volume import HDF5VolumeIdentifier from . import settings, utils _logger = logging.getLogger(__name__) try: from nabu.pipeline.fullfield.reconstruction import ( # noqa F401 FullFieldReconstructor, ) except (ImportError, OSError) as e: try: from nabu.pipeline.fullfield.local_reconstruction import ( # noqa F401 ChunkedReconstructor, ) except (ImportError, OSError): # import of cufft library can bring an OSError if cuda not install _logger.error(e) has_nabu = False else: has_nabu = True else: has_nabu = True class ResultsRun: """ Base class of results for nabu """ def __init__(self, success, config) -> None: self.__success = success self.__config = config @property def success(self) -> bool: return self.__success @property def config(self) -> dict: return self.__config def __str__(self) -> str: return f"result from nabu run: {'succeed' if self.success else 'failed'} with \n - config:{self.config} \n" class ResultsWithStd(ResultsRun): """Nabu result with std""" def __init__(self, std_out, std_err, *args, **kwargs): super().__init__(*args, **kwargs) self.__std_err = std_err self.__std_out = std_out @property def std_out(self) -> str: return self.__std_out @property def std_err(self) -> str: return self.__std_err def __str__(self) -> str: res = super().__str__() res += f"\n {self.std_out} \n {self.std_err}" return res class ResultsLocalRun(ResultsWithStd): """Nabu result when run locally. If this is the case we should be able to retrieve directly the results urls""" def __init__( self, results_identifiers: tuple, *args, **kwargs, ) -> None: super().__init__(*args, **kwargs) if not isinstance(results_identifiers, Iterable): raise TypeError( f"results_urls is expected to be an Iterable not {type(results_identifiers)}" ) # check all identifiers def check_identifier(identifier): if isinstance(identifier, str): vol = VolumeFactory.create_tomo_object_from_identifier( identifier=identifier ) return vol.get_identifier() elif not isinstance(identifier, VolumeIdentifier): raise TypeError( f"identifiers are expected to be VolumeIdentifier. Get {type(identifier)} instead." ) else: return identifier self.__results_identifiers = tuple( [ check_identifier(identifier=identifier) for identifier in results_identifiers ] ) @property def results_identifiers(self) -> tuple: return self.__results_identifiers def __str__(self) -> str: res = super().__str__() res += f"\n - result urls: {self.results_identifiers}" return res class ResultSlurmRun(ResultsWithStd): """Nabu result when run on slurm. on this case we expect to get a future and a distributed client""" def __init__( self, future_slurm_jobs: tuple, job_id: int | None, *args, **kwargs, ) -> None: super().__init__(*args, **kwargs) self.__future_slurm_jobs = future_slurm_jobs self.__job_id = job_id @property def future_slurm_jobs(self): return self.__future_slurm_jobs @property def job_id(self) -> int | None: return self.__job_id def __str__(self) -> str: res = super().__str__() res += f"\n - future job slurms: {self.future_slurm_jobs} \n" return res class _NabuBaseReconstructor: """ Base class to submit a job to nabu """ TIMEOUT_SLURM_JOB_SUBMISSION = 30 """Timeout when submit a job to slurm cluster. In second""" EXPECTS_SINGLE_SLICE = True def __init__( self, scan: TomwerScanBase, dry_run: bool, target: Target, cluster_config: dict | SlurmClusterConfiguration | None, process_name: str, axis: NabuPlane = NabuPlane.XY, ) -> None: self._scan = scan self._target = Target(target) self._dry_run = dry_run self._process_name = process_name self._process = None self._cancelled = False self._axis = NabuPlane.from_value(axis) # nabu subprocess if run locally if isinstance(cluster_config, SlurmClusterConfiguration): self._cluster_config = cluster_config elif isinstance(cluster_config, dict): self._cluster_config = SlurmClusterConfiguration.from_dict(cluster_config) elif cluster_config is None: self._cluster_config = None else: raise TypeError( f"cluster config is expected to be a dict or an instance of {SlurmClusterConfiguration}. Not {type(cluster_config)}" ) @property def scan(self): return self._scan @property def target(self): return self._target @property def cluster_config(self): return self._cluster_config @property def dry_run(self): return self._dry_run @property def process_name(self): return self._process_name @property def axis(self) -> NabuPlane: return self._axis @property def processed_data_folder_name(self) -> str: """return the specific processed folder name associated to this type of reconstruction.""" raise NotImplementedError("Base class") def only_create_config_file(self): """Should we run the reconstruction or only create the configuration file""" return False def run(self) -> Iterable: """ run the requested slices. :return: Iterable of ResultsRun. """ raise NotImplementedError("Base class") def _process_config( self, config_to_dump: dict, config_file: str, file_format: str, info: str | None, process_name: str, ): """ process provided configuration :param info: """ if self.dry_run is True or self.only_create_config_file(): return ResultsRun( success=True, config=config_to_dump, ) elif self.target in (Target.LOCAL, Target.SLURM): axis = config_to_dump["reconstruction"].get("slice_plane", "XY") if file_format in ("hdf5", "h5", "hdf"): vol_identifiers = utils.get_recons_volume_identifier( file_prefix=config_to_dump["output"]["file_prefix"], location=config_to_dump["output"]["location"], slice_index=None, scan=self.scan, file_format=file_format, axis=axis, ) # release potential resource lockers (like the HDF5 volume viewer) for vol_identifier in vol_identifiers: if isinstance(vol_identifier, HDF5VolumeIdentifier): concurrent.submitToQtMainThread( HDF5VolumeManager.release_resource, vol_identifier.file_path, ) if self.target is Target.LOCAL: _logger.info(f"run {info} for {self.scan} with {config_to_dump}") return self._run_nabu_locally( conf_file=config_file, file_format=file_format, config_to_dump=config_to_dump, axis=axis, ) elif self.target is Target.SLURM: _logger.info( f"run {info} on slurm for {self.scan.path} with {config_to_dump}" ) return self._run_nabu_on_slurm( conf_file=config_file, config_to_dump=config_to_dump, cluster_config=self.cluster_config.to_dict(), process_name=process_name, info=info, ) else: raise ValueError(f"{self.target} is not recognized as a valid target") @staticmethod def _get_gpu_and_cpu_mem_fraction(config_to_dump: dict): gpu_mem_fraction = config_to_dump.get("resources", {}).get( "gpu_mem_fraction", config_to_dump.get("gpu_mem_fraction", 0.9) ) assert gpu_mem_fraction <= 1 cpu_mem_fraction = config_to_dump.get("resources", {}).get( "cpu_mem_fraction", config_to_dump.get("cpu_mem_fraction", 0.9) ) assert cpu_mem_fraction <= 1 return gpu_mem_fraction, cpu_mem_fraction def _run_nabu_locally( self, axis: NabuPlane, conf_file: str, file_format: str, config_to_dump: dict, ) -> ResultsLocalRun: """ run locally nabu for a single configuration file. :param conf_file: path to the nabu .cfg file :param file_format: format of the generated file :param config_to_dump: configuration saved in the .cfg as a dictionary :return: results of the local run """ if not has_nabu: raise ImportError("Fail to import nabu") assert isinstance(config_to_dump, dict) gpu_mem_fraction, cpu_mem_fraction = self._get_gpu_and_cpu_mem_fraction( config_to_dump ) command = " ".join( ( sys.executable, "-m", settings.NABU_FULL_FIELD_APP_PATH, f"'{conf_file}'", # adding ' around file name allows to handle config file with spaces "--gpu_mem_fraction", str(gpu_mem_fraction), "--cpu_mem_fraction", str(cpu_mem_fraction), ) ) _logger.info(f'call nabu from "{command}"') self._process = subprocess.Popen( command, shell=True, cwd=self.scan.path, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) try: outs, errs = self._process.communicate() except (TimeoutError, KeyboardInterrupt): self._process.kill() outs, errs = self._process.communicate() recons_vol_identifiers = utils.get_recons_volume_identifier( file_prefix=config_to_dump["output"]["file_prefix"], location=config_to_dump["output"]["location"], slice_index=None, scan=self.scan, file_format=file_format, axis=axis, ) return ResultsLocalRun( success=not nabu_std_err_has_error(errs), results_identifiers=recons_vol_identifiers, std_out=outs, std_err=errs, config=config_to_dump, # config_slices, ) def _run_nabu_on_slurm( self, conf_file: str, config_to_dump: dict, cluster_config: dict, process_name: str, info: str, ) -> ResultSlurmRun: """ Run a nabu reconstruction on slurm of a single configuration :return: results of the slurm run """ if not isinstance(conf_file, str): raise TypeError( f"conf_file is expected to be a string not {type(conf_file)}" ) if not isinstance(config_to_dump, dict): raise TypeError( f"config_to_dump is expected to be a string not {type(config_to_dump)}" ) if not is_slurm_available(): raise RuntimeError("slurm not available") if not isinstance(cluster_config, dict): raise ValueError( f"cluster config is expected to be a dict not {type(cluster_config)}" ) # create slurm cluster project_name = cluster_config.get( "job_name", "tomwer_{scan}_-_{process}_-_{info}" ) project_name = project_name.format( scan=str(self.scan), process=process_name, info=info ) # project name should not contain any spaces as it will be integrated in a script and interpreted. project_name = project_name.replace(" ", "_") cluster_config["job_name"] = project_name # extract gpu_mem_fraction and cpu_mem_fraction assert isinstance(config_to_dump, dict) gpu_mem_fraction, cpu_mem_fraction = self._get_gpu_and_cpu_mem_fraction( config_to_dump ) # submit job script_name = get_slurm_script_name(prefix="nabu") conf_file = filter_esrf_mounting_points(conf_file) # for now force job name cluster_config["job_name"] = f"tomwer-nabu {conf_file}" job = SBatchScriptJob( slurm_config=cluster_config, script=( f"python3 -m {settings.NABU_FULL_FIELD_APP_PATH} '{conf_file}' --gpu_mem_fraction {gpu_mem_fraction} --cpu_mem_fraction {cpu_mem_fraction}", ), script_path=filter_esrf_mounting_points( os.path.join(self.scan.resolved_path, "slurm_scripts", script_name) ), clean_script=False, working_directory=filter_esrf_mounting_points( str(self.scan.working_directory.resolve()) ), ) future_slurm_job = submit_to_slurm_cluster(job) callbacks = self._get_futures_slurm_callback(config_to_dump) assert isinstance( callbacks, tuple ), f"callbacks is expected to an instance of tuple and not {type(callbacks)}" for callback in callbacks: future_slurm_job.add_done_callback(callback.process) return ResultSlurmRun( success=True, config=config_to_dump, future_slurm_jobs=(future_slurm_job,), std_out=None, std_err=None, job_id=job.job_id, ) def _get_futures_slurm_callback(self, config_to_dump) -> tuple: """Return a tuple a potential callback to be launch once the future is done""" return tuple() def _treateOutputSliceConfig(self, config) -> tuple: """ - add or overwrite some parameters of the dictionary - create the output directory if does not exist :return: (config: dict, nabu_cfg_folder: str) """ # handle phase pag = False ctf = False db = None if "phase" in config: pag = ( "method" in config["phase"] and config["phase"]["method"] == _NabuPhaseMethod.PAGANIN.value ) ctf = ( "method" in config["phase"] and config["phase"]["method"] == _NabuPhaseMethod.CTF.value ) if pag or ctf: if "delta_beta" in config["phase"]: if not numpy.isscalar(config["phase"]["delta_beta"]): if len(config["phase"]["delta_beta"]) > 1: raise ValueError( "expects at most one value for 'delta_beta'" ) else: config["phase"]["delta_beta"] = config["phase"][ "delta_beta" ][0] db = round(float(config["phase"]["delta_beta"])) # retrieve axis used axis = config.get("reconstruction", {}).get("slice_plane", "XY") # handle output if "output" in config: _file_name = self._get_file_basename_reconstruction( pag=pag, db=db, ctf=ctf, axis=axis ) config["output"]["file_prefix"] = _file_name location, location_cfg_files = get_output_folder_from_scan( mode=ProcessDataOutputDirMode.from_value( config["output"].get( "output_dir_mode", ProcessDataOutputDirMode.OTHER ) ), nabu_location=config["output"].get("location", None), scan=self.scan, file_basename=_file_name, file_format=config["output"].get( "file_format", NabuOutputFileFormat.HDF5 ), processed_data_folder_name=self.processed_data_folder_name, ) # add reconstruction path to the list. scan `reconstruction_paths` register all the existing path where # reconstruction are saved in order to be able to browse them all self.scan.add_reconstruction_path(location) config["output"]["location"] = location else: # don't think this could ever happen location_cfg_files = self.scan.path # handle preproc if "preproc" not in config: config["preproc"] = {} if self.scan.intensity_normalization.method is INormMethod.NONE: config["preproc"]["sino_normalization"] = "" else: config["preproc"][ "sino_normalization" ] = self.scan.intensity_normalization.method.value extra_infos = self.scan.intensity_normalization.get_extra_infos() nabu_cfg_folder = os.path.join( location_cfg_files, settings.NABU_CFG_FILE_FOLDER ) os.makedirs(nabu_cfg_folder, exist_ok=True) # configuration file and nabu_tomwer_serving_hatch must be in the same folder serving_hatch_file = os.path.join( nabu_cfg_folder, settings.NABU_TOMWER_SERVING_HATCH ) source = extra_infos.get("source", INormSource.NONE) source = INormSource(source) if source is INormSource.NONE: pass elif source is INormSource.MANUAL_SCALAR: if "value" not in extra_infos: raise KeyError( "value should be provided in extra)infos for scalar defined manually" ) else: # check if the dataset has already been saved once and if we can reuse it dataset_url = extra_infos.get("dataset_created_by_tomwer", None) if dataset_url is not None: # if an url exists insure we can access it dataset_url = DataUrl(path=dataset_url) if os.path.exists(dataset_url.file_path()): with open_hdf5(dataset_url.file_path()) as h5f: if dataset_url.data_path() not in h5f: dataset_url = None else: dataset_url = None # if unable toi reuse an existing url them dump the value if dataset_url is None: value = extra_infos["value"] if isinstance(value, (tuple, list)): value = numpy.asarray(value) dataset_url = dump_normalization_array_for_nabu( scan=self.scan, array=value, output_file=serving_hatch_file, ) extra_infos.update( {"dataset_created_by_tomwer": dataset_url.path()} ) self.scan.intensity_normalization.set_extra_infos(extra_infos) config["preproc"]["sino_normalization_file"] = dataset_url.path() elif source is INormSource.DATASET: url = extra_infos["dataset_url"] if isinstance(url, DataUrl): config["preproc"]["sino_normalization_file"] = url.path() elif isinstance(url, str): config["preproc"]["sino_normalization_file"] = url else: raise TypeError( f"dataset_url is expected to be an instance of DataUrl or str representing a DataUrl. Not {type(url)}" ) else: raise NotImplementedError(f"source type {source.value} is not handled") return config, nabu_cfg_folder def _get_file_basename_reconstruction(self, pag, db, ctf, axis): """return created file base name""" raise NotImplementedError("Base class") def cancel(self): self._cancelled = True if self._process: # kill childs processes try: parent = psutil.Process(self._process.pid) except psutil.NoSuchProcess: pass else: # TODO: see with Pierre. But from my point of view this # might be handled by nabu it self.... childrens = parent.children(recursive=True) for child in childrens: try: child.send_signal(signal.SIGKILL) except psutil.NoSuchProcess: pass else: child.wait() self._process.kill() self._process.wait() finally: self._process = None def dump_normalization_array_for_nabu( scan: TomwerScanBase, output_file: str, array: numpy.ndarray | float | int ) -> DataUrl: if not isinstance(array, (numpy.ndarray, float, int)): raise TypeError( f"array is expected to be a numpy array or a scalar and not {type(array)}" ) # save the value to a dedicated path in "nabu_tomwer_serving_hatch" if isinstance(scan, NXtomoScan): entry_path = scan.entry elif isinstance(scan, EDFTomoScan): entry_path = "entry" else: raise TypeError with HDF5File(output_file, mode="a") as h5f: serving_hatch_data_path = None # create a unique dataset path to avoid possible conflicts while serving_hatch_data_path is None or serving_hatch_data_path in h5f: serving_hatch_data_path = "/".join([entry_path, str(uuid.uuid1())]) # adapt value to what nabues expects. if isinstance(array, (float, int)) or ( isinstance(array, numpy.ndarray) and array.ndim == 1 and len(array) == 1 ): dim_1 = scan.dim_1 array = numpy.asarray( numpy.asarray([array] * len(scan.projections) * dim_1) ) array = array.reshape(len(scan.projections), dim_1) elif isinstance(array, numpy.ndarray) and array.ndim == 1: dim_1 = scan.dim_1 array = numpy.repeat(array, dim_1).reshape(len(array), dim_1) h5f[serving_hatch_data_path] = array file_path = os.path.join( settings.NABU_CFG_FILE_FOLDER, settings.NABU_TOMWER_SERVING_HATCH ) return DataUrl( file_path=file_path, data_path=serving_hatch_data_path, scheme="silx", ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/nabu/nabuscores.py0000644000175000017500000006162415153325210025465 0ustar00paynopaynofrom __future__ import annotations try: from nabu.pipeline.fullfield.reconstruction import ( # noqa F401 FullFieldReconstructor, ) except (ImportError, OSError): try: from nabu.pipeline.fullfield.local_reconstruction import ( # noqa F401 ChunkedReconstructor, ) except (ImportError, OSError): # import of cufft library can bring an OSError if cuda not install has_nabu = False else: has_nabu = True else: has_nabu = True import logging import os import sys from copy import deepcopy import subprocess from typing import Iterable import numpy from tqdm import tqdm from nabu.pipeline.fullfield.nabu_config import ( nabu_config as nabu_fullfield_default_config, ) from processview.core.manager.manager import ProcessManager from sluurp.job import SBatchScriptJob from sluurp.executor import submit as submit_to_slurm_cluster from tomoscan.utils.io import filter_esrf_mounting_points from tomwer.core.futureobject import FutureTomwerObject from tomwer.core.process.reconstruction.nabu.nabuslices import ( SingleSliceRunner, _NabuBaseReconstructor, generate_nabu_configfile, ) from tomwer.core.process.reconstruction.nabu.utils import ( slice_index_to_int, get_nabu_multicor_file_prefix, ) from tomwer.core.process.reconstruction.utils.cor import ( relative_pos_to_absolute, absolute_pos_to_relative, ) from tomwer.core.process.reconstruction.nabu.target import Target from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.utils.slurm import get_slurm_script_name, is_slurm_available from tomwer.utils import docstring from tomwer.core.process.reconstruction.nabu.utils import nabu_std_err_has_error from tomwer.core.process.reconstruction.nabu.plane import NabuPlane from ..nabu import settings as nabu_settings from . import utils, settings from .nabucommon import ResultsLocalRun, ResultSlurmRun, ResultsWithStd, ResultsRun _logger = logging.getLogger(__name__) def run_nabu_one_slice_several_config( scan: TomwerScanBase, nabu_configs: list | tuple, cluster_config: dict | None, dry_run: bool, slice_index: int | str, file_format: str, axis: NabuPlane, advancement: tqdm | None = None, process_id: int | None = None, instantiate_classes_only: bool = False, output_file_prefix_pattern=None, ) -> tuple: """ Run several reconstruction of a specific slice. :param scan: dataset :param nabu_configs: set of nabu configurations to be run :param dry_run: :param slice_index: slice index to reconstruct or "middle" :param advancement: optional class to display advancement :param process_id: id of the process requesting this computation :param cluster_config: cluster configuration if :return: success, recons_urls (list of output urls), tuple of outs, tuples of errs, dict future_scans (key is cor, value is future_scan) if `instantiate_classes_only` set to True then return a list of :class:`_Reconstructor` """ if cluster_config in (None, {}): target = Target.LOCAL elif isinstance(cluster_config, dict): if not is_slurm_available(): raise RuntimeError("Slurm computation requested but unvailable") target = Target.SLURM else: raise TypeError( f"cluster_config should be None or a dict not {type(cluster_config)}" ) if process_id is not None: try: process_name = ProcessManager().get_process(process_id=process_id).name except KeyError: process_name = "unknow" else: process_name = "" reconstructor = _Reconstructor( scan=scan, nabu_configs=nabu_configs, advancement=advancement, slice_index=slice_index, target=target, dry_run=dry_run, file_format=file_format, cluster_config=cluster_config, process_name=process_name, output_file_prefix_pattern=output_file_prefix_pattern, axis=axis, ) if instantiate_classes_only: return (reconstructor,) try: results = reconstructor.run() except TimeoutError as e: _logger.error(e) return None else: assert isinstance( results, dict ), "results should be a dictionary with var_value as key and urls as value" success = True recons_urls = {} std_outs = [] std_errs = [] future_tomo_objs = {} for var_value, res in results.items(): success = success and res.success if isinstance(res, ResultsWithStd): std_outs.append(res.std_out) std_errs.append(res.std_err) if isinstance(res, ResultsLocalRun): recons_urls[var_value] = res.results_identifiers if isinstance(res, ResultSlurmRun): future_tomo_obj = FutureTomwerObject( tomo_obj=scan, process_requester_id=process_id, futures=res.future_slurm_jobs, ) future_tomo_objs[var_value] = future_tomo_obj return success, recons_urls, std_outs, std_errs, future_tomo_objs def run_nabu_multicor( scan: TomwerScanBase, nabu_config: dict, cors: tuple, cluster_config: dict | None, dry_run: bool, slice_index: int | str, file_format: str, process_id: int | None = None, instantiate_classes_only: bool = False, output_file_prefix_pattern=None, ): if cluster_config in (None, {}): target = Target.LOCAL elif isinstance(cluster_config, dict): if not is_slurm_available(): raise RuntimeError("Slurm computation requested but unvailable") target = Target.SLURM else: raise TypeError( f"cluster_config should be None or a dict not {type(cluster_config)}" ) if process_id is not None: try: process_name = ProcessManager().get_process(process_id=process_id).name except KeyError: process_name = "unknow" else: process_name = "" # TODO: FIXME small hack to make sure the configuration will be accepted when valie # for now even if the cor values are given from a dedicated parameter nabu is still # checking the value provided in the config file. If this value is invalid for # half acquisition it will be refused nabu_config["reconstruction"]["rotation_axis_position"] = numpy.mean(cors) axis = nabu_config["reconstruction"].get("slice_plane", "XY") reconstructor = _ReconstructorMultiCor( scan=scan, nabu_config=nabu_config, cors=cors, slice_index=slice_index, target=target, dry_run=dry_run, file_format=file_format, cluster_config=cluster_config, process_name=process_name, axis=axis, output_file_prefix_pattern=output_file_prefix_pattern, ) if instantiate_classes_only: return reconstructor try: result = reconstructor.run() except TimeoutError as e: _logger.error(e) return None else: recons_urls = {} std_outs = [] std_errs = [] future_tomo_obj = None success = result.success if isinstance(result, ResultsWithStd): std_outs.append(result.std_out) std_errs.append(result.std_err) if isinstance(result, ResultsLocalRun): recons_urls = result.results_identifiers if isinstance(result, ResultSlurmRun): future_tomo_obj = FutureTomwerObject( tomo_obj=scan, process_requester_id=process_id, futures=result.future_slurm_jobs, ) return success, recons_urls, (future_tomo_obj,), std_outs, std_errs class _Reconstructor(_NabuBaseReconstructor): def __init__( self, scan: TomwerScanBase, nabu_configs: Iterable, advancement: tqdm | None, slice_index: int | str, axis: str | NabuPlane, target: Target, dry_run: bool, file_format: str, cluster_config: dict | None, process_name: str, output_file_prefix_pattern=None, ) -> None: """ :param scan: scan to reconstruct :param nabu_configs: all the configuration to run :param advancement: Progress object to notify advancement :param slice_index: index of the slice to reconstruct. :param axis: axis over which we want to do the reconstruction :param target: is the reconstruction is to made locally or remotly :param file_format: reconstructed volume file format :param cluster_config: cluster configuration in the case of a remote execution :param extra_output_file_pattern: possible extra file name pattern like for cor we want to add 'cor_' as prefix and cor value as suffix. To make the file name unique. For delta/beta it is already forseen to be unique. For now keywords are: * file_name: default file name according to db values and dataset name * value: value of the nabu_configs keys """ super().__init__( scan=scan, dry_run=dry_run, target=target, cluster_config=cluster_config, process_name=process_name, axis=axis, ) if not isinstance(slice_index, (int, str)): raise TypeError( f"slice_index should be an int or a string not {type(slice_index)}" ) self.advancement = advancement self.slice_index = slice_index self.nabu_configs = nabu_configs self.file_format = file_format self._output_file_prefix_pattern = output_file_prefix_pattern @docstring(_NabuBaseReconstructor) def run(self) -> Iterable: self.slice_index = slice_index_to_int( slice_index=self.slice_index, scan=self.scan ) results = {} if self.advancement is not None: self.advancement.total = len(self.nabu_configs) for var_value, config in self.nabu_configs.items(): if self._cancelled: break config, conf_file = self.preprocess_config(deepcopy(config), var_value) # add some tomwer metadata and save the configuration # note: for now the section is ignored by nabu but shouldn't stay that way with utils.TomwerInfo(config) as config_to_dump: generate_nabu_configfile( conf_file, nabu_fullfield_default_config, config=config_to_dump, options_level="advanced", ) results[var_value] = self._process_config( config_to_dump=config_to_dump, config_file=conf_file, file_format=self.file_format, info="nabu slice reconstruction", process_name=self.process_name, ) # specific treatment for cor: rename output files if self.advancement is not None: self.advancement.update() return results def _format_file_prefix(self, file_prefix, value): if self._output_file_prefix_pattern is None: return file_prefix keywords = { "file_name": file_prefix, "value": value, } # filter necessary keywords def get_necessary_keywords(): import string formatter = string.Formatter() return [ field for _, field, _, _ in formatter.parse(self._output_file_prefix_pattern) if field ] requested_keywords = get_necessary_keywords() def keyword_needed(pair): keyword, _ = pair return keyword in requested_keywords keywords = dict(filter(keyword_needed, keywords.items())) return self._output_file_prefix_pattern.format(**keywords) def treateOutputConfig(self, _config, value): """ - add or overwrite some parameters of the dictionary - create the output directory if does not exist """ pag = False ctf = False db = None if "phase" in _config: phase_method = _config["phase"].get("method", "").lower() if phase_method in ("pag", "paganin"): pag = True elif phase_method in ("ctf",): ctf = True if "delta_beta" in _config["phase"]: db = round(float(_config["phase"]["delta_beta"])) if "output" in _config: file_prefix = SingleSliceRunner.get_file_basename_reconstruction( scan=self.scan, slice_index=self.slice_index, pag=pag, db=db, ctf=ctf, axis=self.axis, ) file_prefix = self._format_file_prefix(file_prefix=file_prefix, value=value) _config["output"]["file_prefix"] = file_prefix assert _config["output"]["location"] not in ("", None) if not os.path.isdir(_config["output"]["location"]): os.makedirs(_config["output"]["location"]) if "reconstruction" not in _config: _config["reconstruction"] = {} if self.axis is NabuPlane.YZ: _config["reconstruction"]["start_x"] = self.slice_index _config["reconstruction"]["end_x"] = self.slice_index elif self.axis is NabuPlane.XZ: _config["reconstruction"]["start_y"] = self.slice_index _config["reconstruction"]["end_y"] = self.slice_index elif self.axis is NabuPlane.XY: _config["reconstruction"]["start_z"] = self.slice_index _config["reconstruction"]["end_z"] = self.slice_index else: raise ValueError( f"self.axis has an invalid value: {self.axis} when expected to be in {[item.value for item in NabuPlane]}" ) return _config, file_prefix def preprocess_config(self, config, value) -> tuple: dataset_params = self.scan.get_nabu_dataset_info() if "dataset" in config: dataset_params.update(config["dataset"]) config["dataset"] = dataset_params config["resources"] = config.get("resources", {}) config["resources"]["method"] = "local" # force overwrite results if "output" not in config: config["output"] = {} config["output"].update({"overwrite_results": 1}) config, file_prefix = self.treateOutputConfig(config, value=value) # the policy is to save nabu .cfg file at the same location as the # force overwrite results cfg_folder = os.path.join( config["output"]["location"], nabu_settings.NABU_CFG_FILE_FOLDER, ) os.makedirs(cfg_folder, exist_ok=True) conf_file = os.path.join( cfg_folder, file_prefix + nabu_settings.NABU_CONFIG_FILE_EXTENSION ) return config, conf_file class _ReconstructorMultiCor(_NabuBaseReconstructor): def __init__( self, nabu_config: dict, axis: str | NabuPlane, cors: tuple, file_format, slice_index: int | str = "middle", output_file_prefix_pattern=None, *args, **kwargs, ): if not isinstance(cors, tuple): raise TypeError( f"cors are expected to be an instance of tuple. Get {type(cors)} instead" ) self.__cors = cors self.__slice_index = slice_index self.__nabu_config = nabu_config self.file_format = file_format self._output_file_prefix_pattern = output_file_prefix_pattern super().__init__(*args, **kwargs) @property def cors(self) -> tuple: return self.__cors @property def slice_index(self) -> int | str: return self.__slice_index @property def nabu_config(self) -> dict: return self.__nabu_config def _process_config( self, config_to_dump: dict, config_file: str, file_format: str, info: str | None, process_name: str, ): """ process provided configuration :param info: """ if self.dry_run is True or self.only_create_config_file(): return ResultsRun( success=True, config=config_to_dump, ) elif self.target is Target.LOCAL: _logger.info(f"run {info} for {self.scan} with {config_to_dump}") return self._run_nabu_multicor_locally( conf_file=config_file, file_format=file_format, config_to_dump=config_to_dump, ) elif self.target is Target.SLURM: _logger.info( f"run {info} on slurm for {self.scan.path} with {config_to_dump}" ) return self._run_nabu_multicor_on_slurm( conf_file=config_file, config_to_dump=config_to_dump, cluster_config=self.cluster_config.to_dict(), process_name=process_name, info=info, ) else: raise ValueError(f"{self.target} is not recognized as a valid target") def _run_nabu_multicor_locally( self, conf_file: str, file_format: str, config_to_dump: dict, ) -> ResultsLocalRun: """ run locally nabu for a single configuration file. :param conf_file: path to the nabu .cfg file :param file_format: format of the generated file :param config_to_dump: configuration saved in the .cfg as a dictionary :return: results of the local run """ if not has_nabu: raise ImportError("Fail to import nabu") slice_index = slice_index_to_int(self.slice_index, scan=self.scan) cor_in_nabu_ref = tuple( [ relative_pos_to_absolute(relative_pos=cor, det_width=self.scan.dim_1) for cor in self.cors ] ) cor_in_nabu_ref = ",".join([str(cor) for cor in cor_in_nabu_ref]) command = " ".join( ( sys.executable, "-m", settings.NABU_MULTICOR_PATH, f"'{conf_file}'", # input file f"{slice_index}", # slice f"{cor_in_nabu_ref}", # cor ) ) _logger.info(f'call nabu from "{command}"') self._process = subprocess.Popen( command, shell=True, cwd=self.scan.path, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) try: outs, errs = self._process.communicate() except (TimeoutError, KeyboardInterrupt): self._process.kill() outs, errs = self._process.communicate() file_prefix = get_nabu_multicor_file_prefix(self.scan) recons_vol_identifiers = utils.get_multi_cor_recons_volume_identifiers( slice_index=slice_index, location=config_to_dump["output"]["location"], file_prefix=file_prefix, scan=self.scan, file_format=file_format, cors=[ relative_pos_to_absolute(relative_pos=cor, det_width=self.scan.dim_1) for cor in self.cors ], ) # convert back from abs ref to rel ref recons_vol_identifiers = { absolute_pos_to_relative( absolute_pos=cor, det_width=self.scan.dim_1 ): identifiers for cor, identifiers in recons_vol_identifiers.items() } return ResultsLocalRun( success=not nabu_std_err_has_error(errs), results_identifiers=recons_vol_identifiers.values(), std_out=outs, std_err=errs, config=config_to_dump, # config_slices, ) def _run_nabu_multicor_on_slurm( self, conf_file: str, config_to_dump: dict, cluster_config: dict, process_name: str, info: str, ) -> ResultSlurmRun: """ Run a nabu reconstruction on slurm of a single configuration :return: results of the slurm run """ if not isinstance(conf_file, str): raise TypeError(f"conf_file is expected to be a strg not {type(conf_file)}") if not isinstance(config_to_dump, dict): raise TypeError( f"config_to_dump is expected to be a strg not {type(config_to_dump)}" ) if not is_slurm_available(): raise RuntimeError("slurm not available") if not isinstance(cluster_config, dict): raise ValueError( f"cluster config is expected to be a dict not {type(cluster_config)}" ) # create slurm cluster project_name = cluster_config.get( "job_name", "tomwer_{scan}_-_{process}_-_{info}" ) project_name = project_name.format( scan=str(self.scan), process=process_name, info=info ) # project name should not contain any spaces as it will be integrated in a script and interpreted. project_name = project_name.replace(" ", "_") cluster_config["job_name"] = project_name slice_index = slice_index_to_int(self.slice_index, scan=self.scan) cor_in_nabu_ref = tuple( [ relative_pos_to_absolute(relative_pos=cor, det_width=self.scan.dim_1) for cor in self.cors ] ) cor_in_nabu_ref = ",".join([str(cor) for cor in cor_in_nabu_ref]) # submit job script_name = get_slurm_script_name(prefix="nabu") # for now force job name cluster_config["job_name"] = f"tomwer-nabu {conf_file}" job = SBatchScriptJob( slurm_config=cluster_config, script=( f"python3 -m {settings.NABU_MULTICOR_PATH} {conf_file} {slice_index} {cor_in_nabu_ref}", ), script_path=filter_esrf_mounting_points( os.path.join(self.scan.resolved_path, "slurm_scripts", script_name) ), clean_script=False, working_directory=filter_esrf_mounting_points( str(self.scan.working_directory.resolve()) ), ) future_slurm_job = submit_to_slurm_cluster(job) callbacks = self._get_futures_slurm_callback(config_to_dump) assert isinstance( callbacks, tuple ), f"callbacks is expected to an instance of tuple and not {type(callbacks)}" for callback in callbacks: future_slurm_job.add_done_callback(callback.process) return ResultSlurmRun( success=True, config=config_to_dump, future_slurm_jobs=(future_slurm_job,), std_out=None, std_err=None, job_id=job.job_id, ) def preprocess_config(self, config): dataset_params = self.scan.get_nabu_dataset_info() if "dataset" in config: dataset_params.update(config["dataset"]) config["dataset"] = dataset_params config["resources"] = config.get("resources", {}) config["resources"]["method"] = "local" # force overwrite results if "output" not in config: config["output"] = {} config["output"].update({"overwrite_results": 1}) cfg_folder = os.path.join( config["output"]["location"], nabu_settings.NABU_CFG_FILE_FOLDER, ) os.makedirs(cfg_folder, exist_ok=True) cfg_folder = os.path.join( self.nabu_config["output"]["location"], nabu_settings.NABU_CFG_FILE_FOLDER, ) os.makedirs(cfg_folder, exist_ok=True) conf_file = os.path.join( cfg_folder, f"{self.scan.get_dataset_basename()}_multi_cor" + nabu_settings.NABU_CONFIG_FILE_EXTENSION, ) return config, conf_file def run(self) -> Iterable: nabu_config, conf_file = self.preprocess_config(deepcopy(self.nabu_config)) # the policy is to save nabu .cfg file at the same location as the # force overwrite results # add some tomwer metadata and save the configuration # note: for now the section is ignored by nabu but shouldn't stay that way with utils.TomwerInfo(nabu_config) as config_to_dump: generate_nabu_configfile( conf_file, nabu_fullfield_default_config, config=config_to_dump, options_level="advanced", ) results = self._process_config( config_to_dump=nabu_config, config_file=conf_file, file_format=self.file_format, info="nabu sa-axis reconstruction", process_name=self.process_name, ) return results ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/nabu/nabuslices.py0000644000175000017500000010014015153325210025434 0ustar00paynopaynofrom __future__ import annotations import copy import functools import logging import os import gc from collections.abc import Callable from tomwer.io.utils import format_stderr_stdout from silx.utils.deprecation import deprecated, deprecated_warning from silx.io.utils import open as open_hdf5 from processview.core.manager.manager import ProcessManager, DatasetState from tomwer.core.futureobject import FutureTomwerObject from tomwer.core.utils.scanutils import data_identifier_to_scan from tomwer.core.utils.slurm import is_slurm_available from tomwer.core.process.reconstruction.nabu.utils import ( update_nabu_config_for_tiff_3d, from_nabu_config_to_file_format, ) from tomwer.core.process.reconstruction.nabu.plane import NabuPlane from tomwer.core.process.reconstruction.nabu.utils import slice_index_to_int from tomwer.core.process.reconstruction.utils.cor import relative_pos_to_absolute from tomwer.core.volume.volumefactory import VolumeFactory from tomwer.core.process.reconstruction.output import ( PROCESS_FOLDER_RECONSTRUCTED_SLICES, ) try: from nabu.pipeline.fullfield.reconstruction import ( # noqa F401 FullFieldReconstructor, ) except (ImportError, OSError) as e: _err_import_nabu = e try: from nabu.pipeline.fullfield.local_reconstruction import ( # noqa F401 ChunkedReconstructor, ) except (ImportError, OSError): # import of cufft library can bring an OSError if cuda not install has_nabu = False else: has_nabu = True _err_import_nabu = None else: has_nabu = True _err_import_nabu = None from typing import Iterable from nabu import version as nabu_version from nabu.pipeline.config import ( _extract_nabuconfig_keyvals, generate_nabu_configfile, get_default_nabu_config, ) from nabu.pipeline.fullfield.nabu_config import ( nabu_config as nabu_fullfield_default_config, ) from processview.core.superviseprocess import SuperviseProcess from enum import Enum as _Enum from tomwer.core.process.task import Task from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.scanfactory import ScanFactory from tomwer.utils import docstring from . import settings as nabu_settings from . import utils from .nabucommon import ( ResultsLocalRun, ResultSlurmRun, ResultsRun, _NabuBaseReconstructor, ) from .target import Target _logger = logging.getLogger(__name__) if not has_nabu: _logger.error(_err_import_nabu) def run_slices_reconstruction( scan: TomwerScanBase, config: dict, dry_run: bool = False, advancement=None, process_id: int | None = None, instantiate_classes_only: bool = False, invalid_slice_callback: Callable[[str], None] | None = None, ) -> tuple: """ call nabu for a reconstruction on scan with the given configuration :param scan: scan to reconstruct :param config: configuration to run the reconstruction. Contains nabu reconstruction parameters and slurm cluster configuration if requested (key: `slurm-cluster`). :param dry_run: do we want to run dry :param local: do we want to run a local reconstruction :param stderr: file to redirect stderr :param stdout: file to redirect stdout :param advancement: optional Progress class to display advancement :param process_id: optional process id :param instantiate_class_only: if we don't want to run the SingleSliceRunner but only return them. Use case: we want to keep a hand on processing and it can be cancelled :return: (all_succeed, stdouts, stderrs, final_configs, future_scan) * all_succeed: bool, True if all the reconstruction succeed or if all job request succeed. * stdouts: list of stdout of job reconstruction or job requests * stderrs: list of stderr of job reconstruction or job requests * final_configs: list of configurations submits to nabu * future_scan: FutureTomwerScan | None future scan containing futures pointing to job submited to the cluster. None if local reconstruction Behavior: will clear the last slices reconstructed """ # TODO: remove the local parameter _logger.info(f"start reconstruction of {scan}") cluster_config = config.pop("cluster_config", None) if cluster_config == {}: cluster_config = None is_cluster_job = cluster_config is not None if is_cluster_job and not is_slurm_available(): raise ValueError( "job on cluster requested but no access to slurm cluster found" ) # beam shape is not directly used by nabu (uses ctf_geometry directly) config.get("phase", {}).pop("beam_shape", None) # if scan contains some center of position copy it to nabu if scan.axis_params is not None and scan.axis_params.relative_cor_value is not None: if "reconstruction" in config: # move the cor value to the nabu reference cor_nabu_ref = relative_pos_to_absolute( relative_pos=scan.axis_params.relative_cor_value, det_width=scan.dim_1, ) config["reconstruction"]["rotation_axis_position"] = str(cor_nabu_ref) _logger.info(f"set nabu reconstruction parameters to {scan}") # update nabu recons_params used sc_config = get_default_nabu_config(nabu_fullfield_default_config) sc_config.update(config) scan.nabu_recons_params = sc_config # handle special cases like several db... nabu_configurations = interpret_tomwer_configuration( config, scan=scan, invalid_slice_callback=invalid_slice_callback ) output_urls = [] stderrs = [] stdouts = [] final_configs = [] futures = [] instantiated_classes = [] all_succeed = True if advancement is not None: advancement.total = len(nabu_configurations) scan.clear_latest_reconstructions() for nabu_configuration in nabu_configurations: l_config, slice_index = nabu_configuration result = run_single_slice_reconstruction( nabu_config=l_config, cluster_config=cluster_config, scan=scan, slice_index=slice_index, dry_run=dry_run, instantiate_class_only=instantiate_classes_only, axis=config.get("reconstruction", {}).get("slice_plane", "XY"), ) # specific treatments of results if result is None: # in case of timeout or another issue. Log should already have been provided pass elif instantiate_classes_only: instantiated_classes.append(result) continue if slice_index is None: continue elif isinstance(result, ResultsLocalRun): assert not is_cluster_job, "cluster job should not return ResultsLocalRun" stderrs.append(result.std_err) stdouts.append(result.std_out) output_urls.extend(result.results_identifiers) # if slice_index is None this mean that we are simply creating the # .cfg file for nabu full volume. elif isinstance(result, ResultSlurmRun): assert ( is_cluster_job ), "local reconstruction should not return ResultSlurmRun" stderrs.append(result.std_err) stdouts.append(result.std_out) futures.extend(result.future_slurm_jobs) elif not isinstance(result, ResultsRun): raise ValueError( f"result is expected to be an instance of {ResultsRun} not {type(result)}" ) # common treatments of results if result is not None: final_configs.append(result.config) all_succeed = all_succeed and result.success if advancement is not None: advancement.update() if instantiate_classes_only: return instantiated_classes if is_cluster_job: future_tomo_obj = FutureTomwerObject( tomo_obj=scan, futures=tuple(futures), process_requester_id=process_id, ) scan.set_latest_reconstructions(output_urls) return all_succeed, stdouts, stderrs, final_configs, future_tomo_obj else: # tag latest reconstructions scan.set_latest_reconstructions(output_urls) return all_succeed, stdouts, stderrs, final_configs, None class NabuSlicesTask( Task, SuperviseProcess, input_names=( "data", "nabu_params", ), optional_input_names=( "dry_run", "serialize_output_data", "invalid_slice_callback", ), output_names=("data", "nabu_params", "future_tomo_obj"), ): """ Definition of the nabu reconstruction volume reconstruction process """ def __init__( self, process_id=None, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None, ): SuperviseProcess.__init__(self, process_id=process_id) Task.__init__( self, varinfo=varinfo, inputs=inputs, node_id=node_id, node_attrs=node_attrs, execinfo=execinfo, ) self._dry_run = inputs.get("dry_run", False) self._current_processing = None # we can sometime call several time a nabu subprocess. The idea is to keep track of it # if we want to stop the processing def run(self): scan = data_identifier_to_scan(self.inputs.data) configuration = self.inputs.nabu_params self.outputs.nabu_params = None if scan is None: self.outputs.data = None return if isinstance(scan, TomwerScanBase): scan = scan elif isinstance(scan, dict): scan = ScanFactory.create_scan_object_frm_dict(scan) else: raise ValueError(f"input type of {scan}: {type(scan)} is not managed" "") assert isinstance(configuration, dict), "configuration is expected to be a dict" output_urls = [] stderrs = [] stdouts = [] final_configs = [] futures = [] all_succeed = True is_cluster_job = configuration.get("cluster_config", None) is not None # loop is required for distributed since version 2021 try: single_slice_runner_instances = run_slices_reconstruction( config=configuration, scan=scan, dry_run=self._dry_run, process_id=self.process_id, instantiate_classes_only=True, invalid_slice_callback=self.get_input_value( "invalid_slice_callback", None ), ) except Exception as e: mess = f"Fail to instantiate slice reconstructor for {str(scan)}. Reason is {e}." _logger.processFailed(mess) ProcessManager().notify_dataset_state( dataset=scan, process=self, state=DatasetState.FAILED, details=mess, ) self.outputs.future_tomo_obj = None return for slice_runner in single_slice_runner_instances: self._current_processing = slice_runner result = self._current_processing.run()[ 0 ] # we are expecting a single slice per run in this configuration if result is None: # in case of timeout or another issue. Log should already have been provided pass elif isinstance(result, ResultsLocalRun): assert ( not is_cluster_job ), "cluster job should not return ResultsLocalRun" stderrs.append(result.std_err) stdouts.append(result.std_out) output_urls.extend(result.results_identifiers) # if slice_index is None this mean that we are simply creating the # .cfg file for nabu full volume. elif isinstance(result, ResultSlurmRun): assert ( is_cluster_job ), "local reconstruction should not return ResultSlurmRun" stderrs.append(result.std_err) stdouts.append(result.std_out) futures.extend(result.future_slurm_jobs) elif not isinstance(result, ResultsRun): raise ValueError( f"result is expected to be an instance of {ResultsRun} not {type(result)}" ) # common treatments of results if result is not None: final_configs.append(result.config) all_succeed = all_succeed and result.success # update future object and scan latest reconstructions self._current_processing = None if not self._cancelled and is_cluster_job: future_tomo_obj = FutureTomwerObject( tomo_obj=scan, futures=tuple(futures), process_requester_id=self.process_id, ) scan.set_latest_reconstructions(output_urls) else: # tag latest reconstructions scan.set_latest_reconstructions(output_urls) future_tomo_obj = None volume_urls = [] for rec_identifier in scan.latest_reconstructions: volume_urls.extend( VolumeFactory.from_identifier_to_vol_urls(rec_identifier) ) # update processes information / registration gc.collect() # TODO: check output files with the tomoscan validator ? if self._cancelled: state = DatasetState.CANCELLED details = "cancelled by user" future_tomo_obj = None _logger.info(f"Slices computation for {scan} cancelled") else: if not all_succeed: mess = f"Slices computation for {scan} failed." state = DatasetState.FAILED _logger.processFailed(mess) else: state = DatasetState.SUCCEED mess = f"Slices computed for {scan}." _logger.processSucceed(mess) elmts = [ format_stderr_stdout(stderr=stderr, stdout=stdout) for stderr, stdout in zip(stderrs, stdouts) ] elmts.insert(0, mess) details = "\n".join(elmts) ProcessManager().notify_dataset_state( dataset=scan, process=self, state=state, details=details, ) if self.get_input_value("serialize_output_data", True): self.outputs.data = scan.to_dict() else: self.outputs.data = scan self.outputs.nabu_params = scan.nabu_recons_params self.outputs.future_tomo_obj = future_tomo_obj def set_configuration(self, configuration: dict) -> None: Task.set_configuration(self, configuration=configuration) if "dry_run" in configuration: self.set_dry_run(bool(configuration["dry_run"])) @staticmethod def program_name(): return "nabu-slices" @staticmethod def program_version(): return nabu_version @deprecated(replacement="provide dry_run to the task inputs", since_version="1.2") def set_dry_run(self, dry_run): self._dry_run = dry_run @property @deprecated(replacement="Task.inputs.dry_run", since_version="1.2") def dry_run(self): return self._dry_run def cancel(self): """ stop current processing """ self._cancelled = True if self._current_processing is not None: self._current_processing.cancel() def interpret_tomwer_configuration( config: dict, scan: TomwerScanBase | None, invalid_slice_callback: Callable[[str], None] | None = None, ) -> tuple: """ tomwer can 'mock' the nabu reconstruction to request more feature. Typical use case is that we can ask for reconstruction of several slices and not only the volume :param config: tomwer configuration for nabu :param scan: requested if we want to get slices :return: tuple of tuples (nabu configuration, is slice) """ if not isinstance(config, dict): raise TypeError("config is expected to be a dict") def get_nabu_config(config): nabu_config = copy.deepcopy(config) if "tomwer_slices" in nabu_config: del nabu_config["tomwer_slices"] return nabu_config if "tomwer_slices" in config and scan is not None: reconstruction_axis = NabuPlane.from_value( config.get("reconstruction", {}).get("slice_plane", "XY") ) slices = list( NabuSliceMode.getSlices( config["tomwer_slices"], scan=scan, axis=reconstruction_axis, ) ) def filter_slice(slice_index: int, axis: NabuPlane): """remove slices that 'cannot' be reconstructed (out of bounds)""" if axis is NabuPlane.XY: index_max = scan.dim_2 elif axis in (NabuPlane.XZ, NabuPlane.YZ): index_max = scan.dim_1 else: raise ValueError if index_max is None: return True index_max = index_max - 1 if slice_index > index_max: error_message = f"{scan.get_identifier().short_description()}\n\nCannot reconstruct slice {slice_index} along plane {axis.value}. Must be in [0-{index_max}]" _logger.error(error_message) if invalid_slice_callback is not None: invalid_slice_callback(error_message) return False return True slices = list( filter( lambda slice_index: filter_slice( int(slice_index), axis=reconstruction_axis ), slices, ) ) else: slices = [] if "phase" in config and "delta_beta" in config["phase"]: pag_dbs = config["phase"]["delta_beta"] if isinstance(pag_dbs, str): pag_dbs = utils.retrieve_lst_of_value_from_str(pag_dbs, type_=float) if len(pag_dbs) == 0: pag_dbs = (None,) else: pag_dbs = (None,) # by default add the slice 'None' which is the slice for the volume slices.append(None) nabu_config = get_nabu_config(config=config) res = [] for slice_ in slices: for pag_db in pag_dbs: local_config = copy.deepcopy(nabu_config) if pag_db is not None: local_config["phase"]["delta_beta"] = str(pag_db) res.append((local_config, slice_)) return tuple(res) class SingleSliceRunner(_NabuBaseReconstructor): def __init__( self, scan: TomwerScanBase, config: dict, dry_run: bool, slice_index: int | str | None, axis: NabuPlane, target: Target, cluster_config: dict | None, process_name: str, add_to_latest_reconstructions: bool = True, ) -> None: super().__init__( scan=scan, dry_run=dry_run, target=target, cluster_config=cluster_config, process_name=process_name, axis=axis, ) self._slice_index = slice_index if not isinstance(config, dict): raise TypeError(f"config is expected to be a dictionary not {type(dict)}") self._config = config self._add_to_latest_reconstructions = add_to_latest_reconstructions @property def slice_index(self): return self._slice_index @property def config(self): return self._config @property def add_to_latest_reconstructions(self): return self._add_to_latest_reconstructions @property def processed_data_folder_name(self): """return the specific processed folder name associated to this type of reconstruction.""" return PROCESS_FOLDER_RECONSTRUCTED_SLICES @docstring(_NabuBaseReconstructor) def only_create_config_file(self): return self.slice_index is None @docstring(_NabuBaseReconstructor) def run(self) -> Iterable: """ If the target is local will wait for the reconstruction to be finish to return :raise: TIMEOUT_SLURM_JOB_SUBMISSION if not all workers spwan """ if isinstance(self.slice_index, str): self._slice_index = slice_index_to_int( slice_index=self.slice_index, scan=self.scan, axis=self.axis, ) elif ( isinstance(self.slice_index, float) and int(self.slice_index) == self.slice_index ): self._slice_index = int(self.slice_index) elif not isinstance(self.slice_index, (int, type(None))): raise TypeError( f"slice index is expected to an int or 'middle' or None and not {type(self.slice_index)}" ) config_complete = _extract_nabuconfig_keyvals(nabu_fullfield_default_config) config_complete["dataset"] = self.scan.get_nabu_dataset_info() for key in config_complete.keys(): if key in self.config: config_complete[key].update(self.config[key]) config = config_complete config["resources"] = config.get("resources", {}) config["resources"]["method"] = "local" # force overwrite results if "output" not in config: config["output"] = {} config["output"].update({"overwrite_results": 1}) config, cfg_folder = self._treateOutputSliceConfig(config) # the policy is to save nabu .cfg file at the same location as the # force overwrite results if self.slice_index is not None: if self.axis is NabuPlane.YZ: config["reconstruction"]["start_x"] = self.slice_index config["reconstruction"]["end_x"] = self.slice_index elif self.axis is NabuPlane.XZ: config["reconstruction"]["start_y"] = self.slice_index config["reconstruction"]["end_y"] = self.slice_index elif self.axis is NabuPlane.XY: config["reconstruction"]["start_z"] = self.slice_index config["reconstruction"]["end_z"] = self.slice_index else: raise ValueError( f"self.axis has an invalid value: {self.axis} when expected to be in {[item.value for item in NabuPlane]}" ) if self.slice_index is not None: os.makedirs(config["output"]["location"], exist_ok=True) name = ( config["output"]["file_prefix"] + nabu_settings.NABU_CONFIG_FILE_EXTENSION ) if not isinstance(self.scan, EDFTomoScan): name = "_".join((self.scan.entry.lstrip("/"), name)) conf_file = os.path.join(cfg_folder, name) _logger.info(f"{self.scan}: create {conf_file}") file_format = config["output"]["file_format"] update_nabu_config_for_tiff_3d(config) # add some tomwer metadata and save the configuration # note: for now the section is ignored by nabu but shouldn't stay that way with utils.TomwerInfo(config) as config_to_dump: generate_nabu_configfile( conf_file, nabu_fullfield_default_config, config=config_to_dump, options_level="advanced", ) return tuple( [ self._process_config( config_to_dump=config_to_dump, config_file=conf_file, info="nabu slice reconstruction", file_format=file_format, process_name=self.process_name, ), ] ) @docstring(_NabuBaseReconstructor) def _get_futures_slurm_callback(self, config_to_dump): if self.add_to_latest_reconstructions: # add callback to set slices reconstructed urls class CallBack: # we cannot create a future directly because distributed enforce # the callback to have a function signature with only the future # as single parameter. def __init__(self, f_partial, scan) -> None: self.f_partial = f_partial self.scan = scan def process(self, fn): if fn.done() and not (fn.cancelled() or fn.exception()): # update reconstruction urls only if processing succeed. recons_urls = self.f_partial() self.scan.add_latest_reconstructions(recons_urls) file_format = from_nabu_config_to_file_format(config_to_dump) callback = functools.partial( utils.get_recons_volume_identifier, file_prefix=config_to_dump["output"]["file_prefix"], location=config_to_dump["output"]["location"], file_format=file_format, scan=self.scan, slice_index=None, axis=self.axis, ) return (CallBack(callback, self.scan),) else: return super()._get_futures_slurm_callback(config_to_dump) @staticmethod def get_file_basename_reconstruction( scan, pag, ctf, db, slice_index: str | int, axis: NabuPlane, ): axis = NabuPlane.from_value(axis) if pag: assert db is not None, "if paganin defined, db should not be None" if slice_index is not None: slice_index = slice_index_to_int(slice_index, scan=scan, axis=axis) assert type(db) in (int, type(None)) if isinstance(scan, NXtomoScan): basename, _ = os.path.splitext(scan.master_file) basename = os.path.basename(basename) try: with open_hdf5(scan.master_file) as h5f: if len(h5f.keys()) > 1: # if there is more than one entry in the file append the entry name to the file basename basename = "_".join((basename, scan.entry.lstrip("/"))) except Exception: pass else: basename = os.path.basename(scan.path) if slice_index is None: if pag: return "_".join((basename + "pag", "db" + str(db).zfill(4))) elif ctf: return "_".join((basename + "ctf", "db" + str(db).zfill(4))) else: return basename else: if pag: return "_".join( ( basename + "slice_pag", str(slice_index).zfill(6), "db" + str(db).zfill(4), "plane", axis.value, ) ) elif ctf: return "_".join( ( basename + "slice_ctf", str(slice_index).zfill(6), "db" + str(db).zfill(4), "plane", axis.value, ) ) else: return "_".join( ( basename + "slice", str(slice_index).zfill(6), "plane", axis.value, ) ) @docstring(_NabuBaseReconstructor) def _get_file_basename_reconstruction(self, pag, db, ctf, axis): """ :param pag: is it a paganin reconstruction :param db: delta / beta parameter :return: basename of the file reconstructed (without any extension) """ return self.get_file_basename_reconstruction( scan=self.scan, db=db, pag=pag, slice_index=self.slice_index, ctf=ctf, axis=axis, ) def run_single_slice_reconstruction( scan, nabu_config, dry_run, slice_index: int | str | None, process_id: int | None = None, cluster_config: dict | None = None, add_to_latest_reconstructions=True, instantiate_class_only=False, axis: NabuPlane = NabuPlane.XY, ) -> ResultsRun | None: """ # TODO: might need something like a context or an option "keep" slice in memory :param scan: :param nabu_config: configuration of nabu process :param cluster_config: configuration of cluster (slurm-cluster only for now) :param dry_run: :param slice_index: slice index to reconstruct. If str should be "middle" :param local: :param stdout: file to redirect stdout :param stderr: file to redirect stderr :param add_to_latest_reconstructions: if true add reconstructed slice to the latest reconstruction. We wan't to avoid this treatment for saaxis and sadeltebeta for example :param instantiate_class_only: if we don't want to run the SingleSliceRunner but only return them. Use case: we want to keep a hand on processing and it can be cancelled :return: result of the slice reconstruction if succeed to launch it. """ # TODO: remove local from the function signature target = Target.SLURM if cluster_config not in ({}, None) else Target.LOCAL axis = NabuPlane.from_value(axis) # FIXEME: nabu fails if outer_circle activated and if the axis != z if axis != NabuPlane.XY and nabu_config.get("reconstruction", {}).get( "clip_outer_circle", False ): nabu_config["reconstruction"]["clip_outer_circle"] = False if process_id is not None: try: process_name = ProcessManager().get_process(process_id=process_id).name except KeyError: process_name = "unknow" else: process_name = "" slice_reconstructor = SingleSliceRunner( scan=scan, config=nabu_config, dry_run=dry_run, slice_index=slice_index, axis=axis, target=target, cluster_config=cluster_config, add_to_latest_reconstructions=add_to_latest_reconstructions, process_name=process_name, ) if instantiate_class_only: return slice_reconstructor try: results = slice_reconstructor.run() except TimeoutError as e: _logger.error(e) return None else: assert len(results) == 1, "only one slice should be reconstructed" return results[0] class NabuSliceMode(_Enum): MIDDLE = "middle" OTHER = "other" @staticmethod def getSlices(slices, scan, axis=NabuPlane.XY) -> tuple: res = [] try: mode = NabuSliceMode(slices) except ValueError: try: res = utils.retrieve_lst_of_value_from_str(slices, type_=int) except Exception: pass else: if mode == mode.MIDDLE: axis = NabuPlane(axis) if axis is NabuPlane.XY: n_slice = scan.dim_2 or 2048 elif axis in (NabuPlane.YZ, NabuPlane.XZ): n_slice = scan.dim_1 or 2048 else: raise NotImplementedError(f"unknow axis {axis}") res.append(n_slice // 2) else: raise ValueError( "there should be only two ways of defining " "slices: middle one or other, by giving " "an unique value or a list or a tuple" ) return tuple(res) class NabuSlices(NabuSlicesTask): def __init__( self, process_id=None, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None, ): deprecated_warning( name="tomwer.core.process.reconstruction.nabu.nabuslices.Nabuslices", type_="class", reason="improve readibility", since_version="1.2", replacement="NabuSlicesTask", ) super().__init__(process_id, varinfo, inputs, node_id, node_attrs, execinfo) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/nabu/nabuvolume.py0000644000175000017500000004747415153325210025505 0ustar00paynopaynofrom __future__ import annotations import copy import functools import logging import os from typing import Iterable from nabu import version as nabu_version from nabu.pipeline.config import generate_nabu_configfile from nabu.pipeline.fullfield.nabu_config import ( nabu_config as nabu_fullfield_default_config, ) from processview.core.manager.manager import ProcessManager, DatasetState from processview.core.superviseprocess import SuperviseProcess from silx.io.utils import open as open_hdf5 from tomwer.core.utils.deprecation import deprecated_warning from tomwer.core.cluster.cluster import SlurmClusterConfiguration from tomwer.core.futureobject import FutureTomwerObject from tomwer.core.process.reconstruction.nabu.plane import NabuPlane from tomwer.core.process.reconstruction.nabu.utils import ( from_nabu_config_to_file_format, update_nabu_config_for_tiff_3d, ) from tomwer.core.process.task import Task from tomwer.core.process.drac.processeddataset import DracReconstructedVolumeDataset from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils.dictutils import concatenate_dict from tomwer.core.utils.scanutils import data_identifier_to_scan from tomwer.core.volume.volumefactory import VolumeFactory from tomwer.utils import docstring from tomwer.io.utils import format_stderr_stdout from tomwer.core.process.reconstruction.output import ( PROCESS_FOLDER_RECONSTRUCTED_VOLUMES, ) from . import settings, utils from .nabucommon import ResultsLocalRun, ResultSlurmRun, _NabuBaseReconstructor from .target import Target _logger = logging.getLogger(__name__) def run_volume_reconstruction( scan: TomwerScanBase, config: dict, dry_run: bool, process_id: int | None = None, ) -> tuple: """ Run a volume reconstruction. Scan need to have reconstruction parameters for nabu. Behavior: will clear link to the last volume reconstructed :param process_id: optional process id :return: succeed, stdouts, stderrs, configs, future_scan """ if scan.nabu_recons_params in ({}, None): raise ValueError( "no configuration provided. You should run a " "reconstruction from nabuslices first." ) cluster_config = config.pop("cluster_config", None) if cluster_config == {}: cluster_config = None elif isinstance(cluster_config, SlurmClusterConfiguration): cluster_config = cluster_config.to_dict() if cluster_config is None: target = Target.LOCAL else: target = Target.SLURM # # beam shape is not directly used by nabu (uses ctf_geometry directly) # config.get("phase", {}).pop("beam_shape", None) # config_volume = copy.copy(config) # config_nabu_slices = copy.deepcopy(scan.nabu_recons_params) # if "tomwer_slices" in config_nabu_slices: # del config_nabu_slices["tomwer_slices"] # if "phase" in config_nabu_slices and "delta_beta" in config_nabu_slices["phase"]: # pag_dbs = config_nabu_slices["phase"]["delta_beta"] # if isinstance(pag_dbs, str): # pag_dbs = utils.retrieve_lst_of_value_from_str(pag_dbs, type_=float) # if len(pag_dbs) > 1: # raise ValueError( # "Several value of delta / beta found for volume reconstruction" # ) # scan.clear_latest_vol_reconstructions() if process_id is not None: try: process_name = ProcessManager().get_process(process_id=process_id).name except KeyError: process_name = "unknow" else: process_name = "" volume_reconstructor = VolumeRunner( scan=scan, config_nabu=config, cluster_config=cluster_config, dry_run=dry_run, target=target, process_name=process_name, ) try: results = volume_reconstructor.run() except TimeoutError as e: _logger.error(e) return None else: assert len(results) == 1, "only one volume should be reconstructed" res = results[0] # tag latest reconstructions if isinstance(res, ResultsLocalRun) and res.results_identifiers is not None: scan.set_latest_vol_reconstructions(res.results_identifiers) # create future if needed if isinstance(res, ResultSlurmRun): future_tomo_obj = FutureTomwerObject( tomo_obj=scan, futures=tuple(res.future_slurm_jobs), process_requester_id=process_id, ) else: future_tomo_obj = None succeed = res.success stdouts = ( [ res.std_out, ] if hasattr(res, "std_out") else [] ) stderrs = ( [ res.std_err, ] if hasattr(res, "std_err") else [] ) configs = ( [ res.config, ] if res is not None else [] ) return succeed, stdouts, stderrs, configs, future_tomo_obj class VolumeRunner(_NabuBaseReconstructor): """ Class used to reconstruct a full volume with Nabu. Locally or on a cluster. """ EXPECTS_SINGLE_SLICE = False def __init__( self, scan: TomwerScanBase, config_nabu, cluster_config: dict | None, dry_run: bool, target: Target, process_name: str, ) -> None: super().__init__( scan=scan, dry_run=dry_run, target=target, cluster_config=cluster_config, process_name=process_name, ) self._config = config_nabu @property def configuration(self): return self._config @property def processed_data_folder_name(self): """return the specific processed folder name associated to this type of reconstruction.""" return PROCESS_FOLDER_RECONSTRUCTED_VOLUMES @docstring(_NabuBaseReconstructor) def run(self) -> Iterable: dataset_params = self.scan.get_nabu_dataset_info() if "dataset" in self.configuration: dataset_params.update(self.configuration["dataset"]) self.configuration["dataset"] = dataset_params self.configuration["resources"] = self.configuration.get("resources", {}) self.configuration["resources"]["method"] = "local" # force overwrite results if "output" not in self.configuration: self.configuration["output"] = {} config_slices, cfg_folder = self._treateOutputConfig(self.configuration) # force overwriting results config_slices["output"].update({"overwrite_results": 1}) # check and clamp `start_z` and `end_z` if "reconstruction" in self.configuration: for key in ("start_z", "end_z"): value = config_slices["reconstruction"].get(key) if value is None: continue value = int(value) if self.scan.dim_2 is not None and value >= self.scan.dim_2: _logger.warning( f"{key} > max_size (radio height: {self.scan.dim_2}). Set it to -1 (maximum)" ) value = -1 config_slices["reconstruction"][key] = value name = ( config_slices["output"]["file_prefix"] + settings.NABU_CONFIG_FILE_EXTENSION ) if not isinstance(self.scan, EDFTomoScan): name = "_".join((self.scan.entry.lstrip("/"), name)) conf_file = os.path.join(cfg_folder, name) _logger.info(f"{self.scan}: create {conf_file}") # make sure output location exists os.makedirs(config_slices["output"]["location"], exist_ok=True) file_format = config_slices["output"]["file_format"] update_nabu_config_for_tiff_3d(config_slices) # add some tomwer metadata and save the configuration # note: for now the section is ignored by nabu but shouldn't stay that way with utils.TomwerInfo(config_slices) as config_to_dump: generate_nabu_configfile( conf_file, nabu_fullfield_default_config, config=config_to_dump, options_level="advanced", ) return tuple( [ self._process_config( config_to_dump=config_to_dump, config_file=conf_file, info="nabu volume reconstruction", file_format=file_format, process_name=self.process_name, ) ] ) @docstring(_NabuBaseReconstructor) def _get_futures_slurm_callback(self, config_to_dump) -> tuple: # add callback to set slices reconstructed urls class CallBack: # we cannot create a future directly because distributed enforce # the callback to have a function signature with only the future # as single parameter. def __init__(self, f_partial, scan) -> None: self.f_partial = f_partial self.scan = scan def process(self, fn): if fn.done() and not (fn.cancelled() or fn.exception()): # update reconstruction urls only if processing succeed. recons_identifiers = self.f_partial() self.scan.add_latest_vol_reconstructions(recons_identifiers) file_format = from_nabu_config_to_file_format(config_to_dump) callback = functools.partial( utils.get_recons_volume_identifier, file_prefix=config_to_dump["output"]["file_prefix"], location=config_to_dump["output"]["location"], file_format=file_format, scan=self.scan, slice_index=None, axis=NabuPlane.XY, # for volume we always reconstruct along XY plane ) return (CallBack(callback, self.scan),) def _treateOutputConfig(self, config) -> tuple: """ :return: (nabu config dict, nabu extra options) """ config = copy.deepcopy(config) config, nabu_cfg_folder = super()._treateOutputSliceConfig(config) os.makedirs(config["output"]["location"], exist_ok=True) # adapt config_s to specific volume treatment if "postproc" in config: config["postproc"] = config["postproc"] # make sure start_[x] and end_[x] come from config for key in ("start_x", "end_x", "start_y", "end_y", "start_z", "end_z"): if key in config: config["reconstruction"][key] = config[key] del config[key] return config, nabu_cfg_folder @docstring(_NabuBaseReconstructor) def _get_file_basename_reconstruction(self, pag, db, ctf, axis): """ :param pag: is it a Paganin reconstruction :param db: delta / beta parameter :param axis: axis over which the reconstruction goes. For volume always expected to be z. So ignored in the function :return: basename of the file reconstructed (without any extension) """ assert type(db) in (int, type(None)) assert not pag == ctf == True, "cannot ask for both pag and ctf active" if isinstance(self.scan, NXtomoScan): basename, _ = os.path.splitext(self.scan.master_file) basename = os.path.basename(basename) try: # if there is more than one entry in the file append the entry name to the file basename with open_hdf5(self.scan.master_file) as h5f: if len(h5f.keys()) > 1: basename = "_".join((basename, self.scan.entry.strip("/"))) except Exception: pass else: basename = os.path.basename(self.scan.path) if pag: return "_".join((basename + "pag", "db" + str(db).zfill(4), "vol")) elif ctf: return "_".join((basename + "ctf", "db" + str(db).zfill(4), "vol")) else: return "_".join((basename, "vol")) class NabuVolumeTask( Task, SuperviseProcess, input_names=("data", "nabu_params"), output_names=( "data", "volumes", "future_tomo_obj", "data_portal_processed_datasets", ), optional_input_names=( "dry_run", "nabu_extra_params", # some parameter that must update 'nabu_params' before launching the reconstruction. Such as z range... "serialize_output_data", ), ): def __init__( self, process_id=None, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None, ): SuperviseProcess.__init__(self, process_id=process_id) Task.__init__( self, varinfo=varinfo, inputs=inputs, node_id=node_id, node_attrs=node_attrs, execinfo=execinfo, ) self._dry_run = inputs.get("dry_run", False) self._current_processing = None def run(self): scan = data_identifier_to_scan(self.inputs.data) if scan is None: self.outputs.data = None return # update scan reconstruction parameters used nabu_params = concatenate_dict( copy.deepcopy(self.inputs.nabu_params), self.get_input_value("nabu_extra_params", dict()), ) scan.nabu_recons_params = nabu_params scan.clear_latest_vol_reconstructions() cluster_config = nabu_params.pop("cluster_config", None) if cluster_config == {}: cluster_config = None elif isinstance(cluster_config, SlurmClusterConfiguration): cluster_config = cluster_config.to_dict() if "tomwer_slices" in nabu_params: del nabu_params["tomwer_slices"] if "phase" in nabu_params and "delta_beta" in nabu_params["phase"]: pag_dbs = nabu_params["phase"]["delta_beta"] if isinstance(pag_dbs, str): pag_dbs = utils.retrieve_lst_of_value_from_str(pag_dbs, type_=float) if len(pag_dbs) > 1: raise ValueError( "Several value of delta / beta found for volume reconstruction" ) if isinstance(scan, TomwerScanBase): scan = scan elif isinstance(scan, dict): scan = ScanFactory.create_scan_object_frm_dict(scan) else: raise ValueError(f"input type {scan} is not managed") if cluster_config is None: target = Target.LOCAL else: target = Target.SLURM state = None details = None try: self._current_processing = VolumeRunner( scan=scan, config_nabu=nabu_params, cluster_config=cluster_config, dry_run=self._dry_run, target=target, process_name=self.program_name, ) res = self._current_processing.run()[0] except Exception as e: _logger.error(f"Failed to process {scan}. Error is {e}") state = DatasetState.FAILED details = None future_tomo_obj = None else: # tag latest reconstructions if isinstance(res, ResultsLocalRun) and res.results_identifiers is not None: scan.set_latest_vol_reconstructions(res.results_identifiers) # create future if needed if isinstance(res, ResultSlurmRun): future_tomo_obj = FutureTomwerObject( tomo_obj=scan, futures=tuple(res.future_slurm_jobs), process_requester_id=self.process_id, ) else: future_tomo_obj = None if self._cancelled: state = DatasetState.CANCELLED details = "cancelled by user" _logger.info(f"Slices computation for {scan} cancelled") else: succeed = res.success stdouts = ( [ res.std_out, ] if hasattr(res, "std_out") else [] ) stderrs = ( [ res.std_err, ] if hasattr(res, "std_err") else [] ) if not succeed: mess = f"Volume computed for {scan} failed." _logger.processFailed(mess) state = DatasetState.FAILED else: mess = f"Volume computed for {scan}." _logger.processSucceed(mess) state = DatasetState.SUCCEED # format stderr and stdout elmts = [ format_stderr_stdout(stderr=stderr, stdout=stdout) for stderr, stdout in zip(stderrs, stdouts) ] elmts.insert(0, mess) details = "\n".join(elmts) finally: ProcessManager().notify_dataset_state( dataset=scan, process=self, state=state, details=details, ) if self.get_input_value("serialize_output_data", True): self.outputs.data = scan.to_dict() else: self.outputs.data = scan self.outputs.volumes = scan.latest_vol_reconstructions self.outputs.future_tomo_obj = future_tomo_obj # build screenshots data_portal_processed_datasets = [] if scan.latest_vol_reconstructions is not None: for volume_id in scan.latest_vol_reconstructions: try: volume = VolumeFactory.create_tomo_object_from_identifier( identifier=volume_id ) except Exception as e: _logger.error( f"Fail to build volume from {volume_id}. Error is {e}" ) else: icatReconstructedDataset = DracReconstructedVolumeDataset( tomo_obj=volume, source_scan=scan, ) data_portal_processed_datasets.append(icatReconstructedDataset) self.outputs.data_portal_processed_datasets = tuple( data_portal_processed_datasets ) def set_configuration(self, configuration: dict) -> None: Task.set_configuration(self, configuration=configuration) if "dry_run" in configuration: self.set_dry_run(bool(configuration["dry_run"])) @staticmethod def program_name(): return "nabu-volume" @staticmethod def program_version(): return nabu_version def set_dry_run(self, dry_run): self._dry_run = dry_run @property def dry_run(self): return self._dry_run def cancel(self): """ stop current processing """ self._cancelled = True if self._current_processing is not None: self._current_processing.cancel() class NabuVolume(NabuVolumeTask): def __init__( self, process_id=None, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None, ): deprecated_warning( name="tomwer.core.process.reconstruction.nabu.nabuvolume.NabuVolume", type_="class", reason="improve readibility", since_version="1.2", replacement="NabuVolumeTask", ) super().__init__(process_id, varinfo, inputs, node_id, node_attrs, execinfo) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/nabu/plane.py0000644000175000017500000000057415153325210024415 0ustar00paynopayno"""Define nabu Axis""" from enum import Enum as _Enum class NabuPlane(_Enum): YZ = "YZ" XZ = "XZ" XY = "XY" @classmethod def from_value(cls, value): if value == 0: return NabuPlane.XY elif value == 1: return NabuPlane.XZ elif value == 2: return NabuPlane.YZ return NabuPlane(value=value) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/nabu/settings.py0000644000175000017500000000167315153325210025157 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging _logger = logging.getLogger(__name__) NABU_CONFIG_FILE_EXTENSION = ".cfg" NABU_CFG_FILE_FOLDER = "nabu_cfg_files" # foler where nabu configuraiton will be saved NABU_TOMWER_SERVING_HATCH = "nabu_tomwer_serving_hatch.h5" # file used to insure some passing from tomwer to nabu like providing normalization values try: import nabu.app.reconstruct # noqa: F401 except ImportError: try: import nabu.resources.cli.reconstruct # noqa: F401 except ImportError: _logger.warning( "Fail to get path to nabu reconstruct main path. Take the most recent path" ) NABU_FULL_FIELD_APP_PATH = "nabu.app.reconstruct" else: NABU_FULL_FIELD_APP_PATH = "nabu.resources.cli.reconstruct" else: NABU_FULL_FIELD_APP_PATH = "nabu.app.reconstruct" NABU_CAST_APP_PATH = "nabu.app.cast_volume" NABU_MULTICOR_PATH = "nabu.app.multicor" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/nabu/target.py0000644000175000017500000000015715153325210024601 0ustar00paynopayno# coding: utf-8 from enum import Enum as _Enum class Target(_Enum): LOCAL = "local" SLURM = "slurm" ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1772989186.921101 tomwer-1.6.17/src/tomwer/core/process/reconstruction/nabu/test/0000755000175000017500000000000015153325403023721 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/nabu/test/test_castvolume.py0000644000175000017500000000762115153325210027516 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import numpy import pytest from tomwer.core.process.reconstruction.nabu.castvolume import CastVolumeTask from tomwer.core.process.reconstruction.output import NabuOutputFileFormat from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.volume.edfvolume import EDFVolume from tomwer.core.volume.hdf5volume import HDF5Volume from tomwer.core.volume.tiffvolume import TIFFVolume def test_cast_volume_32bitstiff_to_16bits_tiff(tmp_path): """test 32 bits tiffs to 16 bits works""" dir_test = tmp_path / "test_dir" dir_test.mkdir() save_dir = tmp_path / "output_dir" save_dir.mkdir() vol_data = numpy.random.random(20 * 100 * 100) * 3600.4 vol_data = vol_data.reshape(20, 100, 100) vol_data = vol_data.astype(numpy.float32) volume = TIFFVolume( folder=dir_test, volume_basename="test_dir_vol_", data=vol_data, ) volume.save() # test with output datadir as None with pytest.raises(ValueError): CastVolumeTask( inputs={ "volume": volume, "configuration": { "output_file_path": None, "output_file_format": NabuOutputFileFormat.EDF, "output_data_type": numpy.uint16, }, }, ).run() # test providing save dir and tiff assert len(os.listdir(save_dir)) == 0 task = CastVolumeTask( inputs={ "volume": volume, "configuration": { "output_dir": str(save_dir), "output_file_format": NabuOutputFileFormat.EDF, "output_data_type": numpy.uint16, }, } ) task.run() assert len(os.listdir(save_dir)) == 20, "no files have been generated" assert task.outputs.volume.load_data().shape == (20, 100, 100) assert task.outputs.volume.load_data().dtype == numpy.uint16 # test providing save dir, a scan and hdf5 scan = NXtomoScan(scan=os.sep.join([str(tmp_path), "scan"]), entry="entry0000") task = CastVolumeTask( inputs={ "volume": volume, "configuration": { "output_dir": str(save_dir), "output_file_format": NabuOutputFileFormat.HDF5, "output_data_type": numpy.float32, }, "scan": scan, }, ) task.run() assert task.outputs.volume.load_data().shape == (20, 100, 100) assert task.outputs.volume.load_data().dtype == numpy.float32 # test providing a volume as output volume output_volume = HDF5Volume( file_path=os.path.join(str(tmp_path), "my_volume.hdf5"), data_path="entry0002" ) task = CastVolumeTask( inputs={ "volume": volume, "configuration": { "output_dir": str(save_dir), "output_file_format": NabuOutputFileFormat.HDF5, "output_data_type": numpy.uint8, }, "output_volume": output_volume, }, ) task.run() assert task.outputs.volume.load_data().shape == (20, 100, 100) assert task.outputs.volume.load_data().dtype == numpy.uint8 # test providing a volume us as output volume output_volume = EDFVolume(folder=os.path.join(str(tmp_path), "my_edf_vol")) task = CastVolumeTask( inputs={ "volume": volume, "configuration": { "output_dir": str(save_dir), "output_file_format": NabuOutputFileFormat.HDF5, "output_data_type": numpy.int16, "remove_input_volume": True, }, "output_volume": output_volume.get_identifier().to_str(), }, ) task.run() assert task.outputs.volume.load_data().shape == (20, 100, 100) assert task.outputs.volume.load_data().dtype == numpy.int16 assert not os.path.exists(volume.data_url.file_path()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/nabu/test/test_nabu_utils.py0000644000175000017500000004354015153325210027501 0ustar00paynopaynoimport pytest from tomwer.core.process.reconstruction.nabu.utils import ( get_recons_volume_identifier, get_multi_cor_recons_volume_identifiers, nabu_std_err_has_error, get_default_output_volume_for_tiff_3d, ) from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.volume.edfvolume import EDFVolume from tomwer.core.volume.hdf5volume import HDF5Volume from tomoscan.esrf.volume.jp2kvolume import has_minimal_openjpeg _scans = ( NXtomoScan( scan="/my_scan_file.nx", entry="entry_test", ), EDFTomoScan("/my_scan_folder"), ) @pytest.mark.parametrize("scan", _scans) @pytest.mark.parametrize("axis", ("YZ", "XZ", "XY")) def test_get_recons_volume_identifier(scan, axis): """ test get_recons_volume_identifier behavior """ entry = scan.entry if isinstance(scan, NXtomoScan) else "entry" # check some exceptions with pytest.raises(ValueError): get_recons_volume_identifier( file_prefix="volume_rec", location="/this/is/a/test", file_format="toto", slice_index=1080, scan=scan, axis=axis, ) # check hdf5 reconstructions id_rec_vols = get_recons_volume_identifier( file_prefix="volume_rec", location="/this/is/a/test", file_format="hdf5", slice_index="1080", scan=scan, axis=axis, ) assert len(id_rec_vols) == 1 assert ( id_rec_vols[0].to_str() == f"hdf5:volume:/this/is/a/test/volume_rec_plane_{axis}_001080.hdf5?path={entry}/reconstruction" ) # check edf and jp2k slice reconstructions (are expected to have the same behavior) id_rec_vols = get_recons_volume_identifier( file_prefix="volume_rec", location="/this/is/a/test", file_format="edf", slice_index="1080", scan=scan, axis=axis, ) assert len(id_rec_vols) == 1 assert ( id_rec_vols[0].to_str() == "edf:volume:/this/is/a/test?file_prefix=volume_rec" ) id_rec_vols = get_recons_volume_identifier( file_prefix="volume_recslice", location="/this/is/a/test", file_format="jp2k", slice_index="1080", scan=scan, axis=axis, ) assert len(id_rec_vols) == 1 assert ( id_rec_vols[0].to_str() == "jp2k:volume:/this/is/a/test?file_prefix=volume_recslice" ) if not has_minimal_openjpeg: pytest.skip("Missing minimal opengl version") # check tiff slice reconstructions id_rec_vols = get_recons_volume_identifier( file_prefix="volume_rec", location="/this/is/a/test", file_format="tiff", slice_index="1080", scan=scan, axis=axis, ) assert len(id_rec_vols) == 1 assert ( id_rec_vols[0].to_str() == "tiff:volume:/this/is/a/test?file_prefix=volume_rec" ) @pytest.mark.parametrize("scan", _scans) def test_get_multi_cor_recons_volume_identifier(scan): """ test the get_multi_cor_recons_volume_identifier function """ entry = scan.entry if isinstance(scan, NXtomoScan) else "entry" # dummy test with hdf5 id_rec_vols = get_multi_cor_recons_volume_identifiers( scan=scan, slice_index="middle", location="/this/is/a/test", file_prefix="rec", cors=(10, 12), file_format="hdf5", ) assert isinstance(id_rec_vols, dict) assert len(id_rec_vols) == 2 assert 10 in id_rec_vols.keys() assert 12 in id_rec_vols.keys() assert ( id_rec_vols[10].to_str() == f"hdf5:volume:/this/is/a/test/rec_10.000_01024.hdf5?path={entry}/reconstruction" ) # dummy test with tiff id_rec_vols = get_multi_cor_recons_volume_identifiers( scan=scan, slice_index="middle", location="/this/is/a/test", file_prefix="rec", cors=(10, 12), file_format="tiff", ) assert isinstance(id_rec_vols, dict) assert len(id_rec_vols) == 2 assert 10 in id_rec_vols.keys() assert 12 in id_rec_vols.keys() assert id_rec_vols[10].to_str() == "tiff:volume:/this/is/a?file_prefix=test" def test_get_default_output_volume_for_tiff_3d(): """test 'get_default_output_volume_for_tiff_3d' function""" # test from EDF input_edf_volume = EDFVolume( folder="/path/to/my_folder", ) assert ( get_default_output_volume_for_tiff_3d( input_volume=input_edf_volume, output_dir="/path/to/my_folder", ).data_url.file_path() == "/path/to/my_folder/my_folder.tiff" ) # test from hdf5 input_hdf5_volume = HDF5Volume( file_path="/path/to/my_file.hdf5", data_path="entry0012", ) assert ( get_default_output_volume_for_tiff_3d( input_volume=input_hdf5_volume, output_dir="/cast_volume", ).data_url.file_path() == "/cast_volume/my_file.tiff" ) def test_nabu_std_err_has_error(): assert nabu_std_err_has_error(None) is False assert nabu_std_err_has_error(b"") is False assert nabu_std_err_has_error(b"this is an error") is True assert ( nabu_std_err_has_error( b"warnings.warn('creating CUBLAS context to get version num" ) is False ) assert ( nabu_std_err_has_error( b"warnings.warn('creating CUBLAS context to get version num\n this is an error" ) is True ) assert ( nabu_std_err_has_error( b"""/nobackup/lbs0511/tomotools/venvs/2023_10_04/lib/python3.8/site-packages/skcuda/cublas.py:284: UserWarning: creating CUBLAS context to get version number warnings.warn('creating CUBLAS context to get version number') /nobackup/lbs0511/tomotools/venvs/2023_10_04/lib/python3.8/site-packages/nabu/cuda/kernel.py:49: UserWarning: The CUDA compiler succeeded, but said the following: nvcc warning : The 'compute_35', 'compute_37', 'sm_35', and 'sm_37' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning). self.module = SourceModule(self.src, **self.sourcemodule_kwargs) /nobackup/lbs0511/tomotools/venvs/2023_10_04/lib/python3.8/site-packages/pycuda/elementwise.py:47: UserWarning: The CUDA compiler succeeded, but said the following: nvcc warning : The 'compute_35', 'compute_37', 'sm_35', and 'sm_37' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning). return SourceModule( /nobackup/lbs0511/tomotools/venvs/2023_10_04/lib/python3.8/site-packages/nabu/cuda/kernel.py:49: UserWarning: The CUDA compiler succeeded, but said the following: nvcc warning : The 'compute_35', 'compute_37', 'sm_35', and 'sm_37' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning). self.module = SourceModule(self.src, **self.sourcemodule_kwargs) /nobackup/lbs0511/tomotools/venvs/2023_10_04/lib/python3.8/site-packages/pycuda/elementwise.py:47: UserWarning: The CUDA compiler succeeded, but said the following: nvcc warning : The 'compute_35', 'compute_37', 'sm_35', and 'sm_37' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning). return SourceModule( /nobackup/lbs0511/tomotools/venvs/2023_10_04/lib/python3.8/site-packages/nabu/cuda/kernel.py:49: UserWarning: The CUDA compiler succeeded, but said the following: nvcc warning : The 'compute_35', 'compute_37', 'sm_35', and 'sm_37' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning). self.module = SourceModule(self.src, **self.sourcemodule_kwargs) /nobackup/lbs0511/tomotools/venvs/2023_10_04/lib/python3.8/site-packages/nabu/cuda/kernel.py:49: UserWarning: The CUDA compiler succeeded, but said the following: nvcc warning : The 'compute_35', 'compute_37', 'sm_35', and 'sm_37' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning). self.module = SourceModule(self.src, **self.sourcemodule_kwargs) /nobackup/lbs0511/tomotools/venvs/2023_10_04/lib/python3.8/site-packages/nabu/cuda/kernel.py:49: UserWarning: The CUDA compiler succeeded, but said the following: nvcc warning : The 'compute_35', 'compute_37', 'sm_35', and 'sm_37' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning). kernel.cu(111): warning #1215-D: function "tex2D(texture, float, float) [with T=float]" /cvmfs/hpc.esrf.fr/software/packages/ubuntu20.04/x86_64/cuda/11.8.0//bin/../targets/x86_64-linux/include/texture_fetch_functions.h(198): here was declared deprecated kernel.cu(112): warning #1215-D: function "tex2D(texture, float, float) [with T=float]" /cvmfs/hpc.esrf.fr/software/packages/ubuntu20.04/x86_64/cuda/11.8.0//bin/../targets/x86_64-linux/include/texture_fetch_functions.h(198): here was declared deprecated kernel.cu(113): warning #1215-D: function "tex2D(texture, float, float) [with T=float]" /cvmfs/hpc.esrf.fr/software/packages/ubuntu20.04/x86_64/cuda/11.8.0//bin/../targets/x86_64-linux/include/texture_fetch_functions.h(198): here was declared deprecated kernel.cu(114): warning #1215-D: function "tex2D(texture, float, float) [with T=float]" /cvmfs/hpc.esrf.fr/software/packages/ubuntu20.04/x86_64/cuda/11.8.0//bin/../targets/x86_64-linux/include/texture_fetch_functions.h(198): here was declared deprecated self.module = SourceModule(self.src, **self.sourcemodule_kwargs) /nobackup/lbs0511/tomotools/venvs/2023_10_04/lib/python3.8/site-packages/pycuda/elementwise.py:47: UserWarning: The CUDA compiler succeeded, but said the following: nvcc warning : The 'compute_35', 'compute_37', 'sm_35', and 'sm_37' architectures are deprecated, and may be removed in a future release (Use -Wno-deprecated-gpu-targets to suppress warning). return SourceModule(""" ) is False ) assert ( nabu_std_err_has_error( b"""/cvmfs/tomo.esrf.fr/software/packages/linux/x86_64/tomotools/2024_02_26/lib/python3.11/site-packages/cupyx/jit/_interface.py:173: FutureWarning: cupyx.jit.rawkernel is experimental. The interface can change in the future. cupy._util.experimental('cupyx.jit.rawkernel') /cvmfs/tomo.esrf.fr/software/packages/linux/x86_64/tomotools/2024_02_26/lib/python3.11/site-packages/skcuda/cublas.py:284: UserWarning: creating CUBLAS context to get version number warnings.warn('creating CUBLAS context to get version number')""" ) is False ) assert ( nabu_std_err_has_error( b"""/cvmfs/tomo.esrf.fr/software/packages/linux/x86_64/tomotools/2024_04_09/lib/python3.11/site-packages/cupyx/jit/_interface.py:173: FutureWarning: cupyx.jit.rawkernel is experimental. The interface can change in the future. cupy._util.experimental('cupyx.jit.rawkernel') z_translation Not supported for EDF y_translation Not supported for EDF x_translation Not supported for EDF /cvmfs/tomo.esrf.fr/software/packages/linux/x86_64/tomotools/2024_04_09/lib/python3.11/site-packages/skcuda/cublas.py:284: UserWarning: creating CUBLAS context to get version number warnings.warn('creating CUBLAS context to get version number') unable to load metadata from /lbsram/data/id16b/inhouse1/comm_24apr/tomwerUpdate/testTomwer04/reconstructed_volumes/testTomwer04slice_pag_001080_db0500_plane_XY.vol.info""" ) is False ) assert ( nabu_std_err_has_error( b"""/cvmfs/tomo.esrf.fr/software/packages/linux/x86_64/tomotools/2024_04_19/lib/python3.11/site-packages/cupyx/jit/_interface.py:173: FutureWarning: cupyx.jit.rawkernel is experimental. The interface can change in the future. cupy._util.experimental('cupyx.jit.rawkernel') /cvmfs/tomo.esrf.fr/software/packages/linux/x86_64/tomotools/2024_04_19/lib/python3.11/site-packages/nabu/cuda/kernel.py:49: UserWarning: The CUDA compiler succeeded, but said the following: kernel.cu(228): warning #177-D: variable "x_stop_other" was declared but never referenced kernel.cu(230): warning #177-D: variable "y_stop_other" was declared but never referenced self.module = SourceModule(self.src, **self.sourcemodule_kwargs) /cvmfs/tomo.esrf.fr/software/packages/linux/x86_64/tomotools/2024_04_19/lib/python3.11/site-packages/skcuda/cublas.py:284: UserWarning: creating CUBLAS context to get version number warnings.warn('creating CUBLAS context to get version number') /cvmfs/tomo.esrf.fr/software/packages/linux/x86_64/tomotools/2024_04_19/lib/python3.11/site-packages/nabu/cuda/kernel.py:49: UserWarning: The CUDA compiler succeeded, but said the following: kernel.cu(228): warning #177-D: variable "x_stop_other" was declared but never referenced kernel.cu(230): warning #177-D: variable "y_stop_other" was declared but never referenced self.module = SourceModule(self.src, **self.sourcemodule_kwargs) /cvmfs/tomo.esrf.fr/software/packages/linux/x86_64/tomotools/2024_04_19/lib/python3.11/site-packages/nabu/cuda/kernel.py:49: UserWarning: The CUDA compiler succeeded, but said the following: kernel.cu(131): warning #1215-D: function "tex2D(texture, float, float) [with T=float]" /cvmfs/hpc.esrf.fr/software/packages/ubuntu20.04/x86_64/cuda/11.7.1/bin/../targets/x86_64-linux/include/texture_fetch_functions.h(198): here was declared deprecated kernel.cu(132): warning #1215-D: function "tex2D(texture, float, float) [with T=float]" /cvmfs/hpc.esrf.fr/software/packages/ubuntu20.04/x86_64/cuda/11.7.1/bin/../targets/x86_64-linux/include/texture_fetch_functions.h(198): here was declared deprecated kernel.cu(133): warning #1215-D: function "tex2D(texture, float, float) [with T=float]" /cvmfs/hpc.esrf.fr/software/packages/ubuntu20.04/x86_64/cuda/11.7.1/bin/../targets/x86_64-linux/include/texture_fetch_functions.h(198): here was declared deprecated kernel.cu(134): warning #1215-D: function "tex2D(texture, float, float) [with T=float]" /cvmfs/hpc.esrf.fr/software/packages/ubuntu20.04/x86_64/cuda/11.7.1/bin/../targets/x86_64-linux/include/texture_fetch_functions.h(198): here was declared deprecated kernel.cu(21): warning #177-D: function "linear_interpolation" was declared but never referenced self.module = SourceModule(self.src, **self.sourcemodule_kwargs) /cvmfs/tomo.esrf.fr/software/packages/linux/x86_64/tomotools/2024_04_19/lib/python3.11/site-packages/cupy/cuda/compiler.py:233: PerformanceWarning: Jitify is performing a one-time only warm-up to populate the persistent cache, this may take a few seconds and will be improved in a future release... jitify._init_module()""" ) is False ) assert ( nabu_std_err_has_error( b"""pytools.persistent_dict: unable to import 'siphash24.siphash13', """ ) is False ) assert ( nabu_std_err_has_error( b"""CompilerWarning: Non-empty compiler output encountered. Set the environment variable PYOPENCL_COMPILER_OUTPUT=1 to see more. _create_built_program_from_source_cached( /cvmfs/tomo.esrf.fr/software/packages/linux/x86_64/tomotools/2024_09_06/lib/python3.11/site-packages/pyopencl/cache.py:499: CompilerWarning: Non-empty compiler output encountered. Set the environment variable PYOPENCL_COMPILER_OUTPUT=1 to see more. prg.build(options_bytes, devices)""" ) is False ) assert ( nabu_std_err_has_error( b"""Performing MLEM-WL2 iterations: 0%| | 0/200[00:00" kernel.cu(230): warning #177-D: variable "y_stop_other" was declared but never referenced int y_stop_other = other_y_range.y; self.module = SourceModule(self.src, **self.sourcemodule_kwargs) /cvmfs/tomo.esrf.fr/software/packages/ubuntu24.04/x86_64/tomotools/2025_08_13_stable/lib/python3.12/site-packages/nabu/cuda/kernel.py:58: UserWarning: The CUDA compiler succeeded, but said the following: kernel.cu(228): warning #177-D: variable "x_stop_other" was declared but never referenced int x_stop_other = other_x_range.y; Remark: The warnings can be suppressed with "-diag-suppress " kernel.cu(230): warning #177-D: variable "y_stop_other" was declared but never referenced int y_stop_other = other_y_range.y; self.module = SourceModule(self.src, **self.sourcemodule_kwargs) """ ) is False ) assert ( nabu_std_err_has_error( b"""Warning: Warning: kernel support is too large for data dimension 0 (17). Forcing convolution mode to 'nearest' warn( """ ) is False ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/nabu/test/test_nabunormalization.py0000644000175000017500000001357215153325210031072 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import configparser from collections import namedtuple import numpy import pytest from silx.io.url import DataUrl from tomoscan.io import HDF5File from nabu.pipeline.config import get_default_nabu_config from nabu.pipeline.fullfield.nabu_config import ( nabu_config as nabu_fullfield_default_config, ) from tomwer.core.process.reconstruction.nabu import settings as nabu_settings from tomwer.core.process.reconstruction.nabu.nabuslices import NabuSlicesTask from tomwer.core.process.reconstruction.normalization.normalization import ( SinoNormalizationTask, ) from tomwer.core.process.reconstruction.normalization.params import ( SinoNormalizationParams, ) from tomwer.core.utils.scanutils import MockNXtomo from tomwer.core.process.reconstruction.output import ( PROCESS_FOLDER_RECONSTRUCTED_SLICES, ) try: import nabu except ImportError: has_nabu = False else: has_nabu = True import os _norm_setting = namedtuple("_norm_setting", ["method", "source", "extra_infos"]) _nabu_norm_field = namedtuple( "_nabu_norm_field", ["sino_normalization", "has_sino_normalization_file"], ) normalization_config_test = ( # no normalization ( _norm_setting(method="none", source=None, extra_infos=None), _nabu_norm_field( sino_normalization="", has_sino_normalization_file=False, ), ), # chebyshev normalization ( _norm_setting(method="chebyshev", source=None, extra_infos=None), _nabu_norm_field( sino_normalization="chebyshev", has_sino_normalization_file=False, ), ), # divide by a scalar ( _norm_setting(method="division", source="scalar", extra_infos={"value": 12.0}), _nabu_norm_field( sino_normalization="division", has_sino_normalization_file=True, ), ), # substract a roi ( _norm_setting( method="subtraction", source="manual ROI", extra_infos={ "start_x": 0.0, "end_x": 1.0, "start_y": 0.0, "end_y": 1.0, "calc_fct": "mean", "calc_area": "volume", "calc_method": "scalar", }, ), _nabu_norm_field( sino_normalization="subtraction", has_sino_normalization_file=True, ), ), # substract from a dataset ( _norm_setting( method="subtraction", source="from dataset", extra_infos={ "dataset_url": DataUrl( file_path="random_dataset.hdf5", data_path="data", scheme="silx", ), "calc_fct": "median", "calc_area": "volume", "calc_method": "scalar", }, ), _nabu_norm_field( sino_normalization="subtraction", has_sino_normalization_file=True, ), ), ) @pytest.mark.skipif( (not has_nabu or nabu.version < "2022.2"), reason="nabu not available or the current version doesn't handle sino normlaization yet", ) @pytest.mark.parametrize( "norm_setting, expected_nabu_conf", [item for item in normalization_config_test] ) def test_normalization(norm_setting, expected_nabu_conf, tmp_path): """ Insure normalization is correctly provided to nabu configuration file For this run a normalization process followed by a nabu process. """ scan_dir = tmp_path / "scan" scan_dir.mkdir() nabu_cfg_folders = os.path.join(scan_dir, nabu_settings.NABU_CFG_FILE_FOLDER) os.makedirs(nabu_cfg_folders, exist_ok=True) random_dataset_file = os.path.join(nabu_cfg_folders, "random_dataset.hdf5") # create a random dataset if necessary with HDF5File(random_dataset_file, mode="w") as h5f: h5f["data"] = numpy.ones((20, 20)) mock = MockNXtomo( scan_path=scan_dir, n_proj=10, n_ini_proj=10, scan_range=180, dim=20, ) scan = mock.scan cfg_folder = os.path.join( str(scan_dir), PROCESS_FOLDER_RECONSTRUCTED_SLICES, "nabu_cfg_files" ) cfg_file = os.path.join(cfg_folder, "entry_scan.cfg") assert not os.path.exists(cfg_file) norm_params = SinoNormalizationParams( method=norm_setting.method, source=norm_setting.source, extra_infos=norm_setting.extra_infos, ) normalization = SinoNormalizationTask( inputs={ "data": scan, "configuration": norm_params.to_dict(), "serialize_output_data": False, }, varinfo=None, ) normalization.run() # insure the method is style valid assert scan.intensity_normalization.method.value == norm_setting.method assert ( "tomwer_processing_res_code" in scan.intensity_normalization.get_extra_infos() ) process = NabuSlicesTask( inputs={ "data": scan, "dry_run": True, "nabu_params": get_default_nabu_config(nabu_fullfield_default_config), "serialize_output_data": False, }, varinfo=None, ) process.run() assert os.path.exists(cfg_file) configuration = configparser.ConfigParser(allow_no_value=True) configuration.read(cfg_file) preproc_section = configuration["preproc"] sino_normalization = preproc_section.get("sino_normalization", "") sino_normalization_file = preproc_section.get("sino_normalization_file", "") assert sino_normalization == expected_nabu_conf.sino_normalization if expected_nabu_conf.has_sino_normalization_file: url = DataUrl(path=sino_normalization_file) assert url.is_valid() else: assert sino_normalization_file == "" assert ( "tomwer_processing_res_code" in scan.intensity_normalization.get_extra_infos() ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/nabu/utils.py0000644000175000017500000004777315153325210024472 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import datetime import logging import os from contextlib import AbstractContextManager from nabu.pipeline.config import generate_nabu_configfile, parse_nabu_config_file from nabu.pipeline.fullfield.nabu_config import ( nabu_config as nabu_fullfield_default_config, ) from enum import Enum from tomoscan.identifier import VolumeIdentifier from tomoscan.volumebase import VolumeBase import tomwer.version from tomwer.core.process.reconstruction.nabu.plane import NabuPlane from tomwer.core.process.output import NabuOutputFileFormat from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.volume.volumebase import TomwerVolumeBase from tomwer.core.volume.edfvolume import EDFVolume from tomwer.core.volume.hdf5volume import HDF5Volume from tomwer.core.volume.jp2kvolume import JP2KVolume from tomwer.core.volume.rawvolume import RawVolume from tomwer.core.volume.tiffvolume import TIFFVolume, MultiTIFFVolume _logger = logging.getLogger(__name__) class TomwerInfo(AbstractContextManager): """Simple context manager to add tomwer metadata to a dict before writing it""" def __init__(self, config_dict): self.config = config_dict def __enter__(self): self.config["other"] = { "tomwer_version": tomwer.version.version, "date": datetime.datetime.now().strftime("%d/%m/%Y %H:%M:%S"), } return self.config def __exit__(self, exc_type, exc_val, exc_tb): del self.config["other"]["tomwer_version"] del self.config["other"]["date"] def retrieve_lst_of_value_from_str(my_string: str, type_) -> tuple: """ Return a list of value from a string like '12,23' or '(12, 23)', '[12;23]', '12;23' or with the pattern from:to:step like '0:10:1' :param mystring: :return: list of single value """ if not isinstance(my_string, str): raise TypeError( f"my_string is expected to be a string. {type(my_string)} provided" ) res = [] my_string = my_string.replace("(", "") my_string = my_string.replace(")", "") my_string = my_string.replace("[", "") my_string = my_string.replace("]", "") if my_string.count(":") == 2: _from, _to, _step = my_string.split(":") _from, _to, _step = float(_from), float(_to), float(_step) if _from > _to: tmp = _to _to = _from _from = tmp while _from <= _to: res.append(_from) _from += _step return tuple(res) else: vals = my_string.replace(" ", "") vals = vals.replace("_", "") vals = vals.replace(";", ",").split(",") for val in vals: try: res.append(type_(val)) except Exception: pass return tuple(res) def get_nabu_about_desc(overwrite: bool) -> dict: """ Create the description for nabu's 'about' """ return {"overwrite_results": str(bool(overwrite))} def get_recons_volume_identifier( file_prefix: str, location: str, file_format: str | NabuOutputFileFormat, scan: TomwerScanBase, slice_index: int | None, axis: NabuPlane, ) -> tuple[VolumeIdentifier]: """ return tuple of DataUrl for existings slices """ axis = NabuPlane.from_value(axis) if isinstance(file_format, NabuOutputFileFormat): file_format = file_format.value file_format = file_format.lower() if file_format in ("hdf5", "h5", "hdf"): if slice_index is not None: # case of a single hdf5 file file_name = "_".join( (file_prefix, "plane", axis.value, str(slice_index).zfill(6)) ) else: file_name = file_prefix file_name = ".".join((file_name, file_format)) file_path = os.path.join(location, file_name) if isinstance(scan, NXtomoScan): entry = scan.entry elif isinstance(scan, EDFTomoScan): entry = "entry" else: raise NotImplementedError(f"unrecognized scan type ({type(scan)})") volumes = ( HDF5Volume( file_path=file_path, data_path="/".join([entry, "reconstruction"]), ), ) elif file_format in ("vol", "raw"): if slice_index is not None: # case of a single hdf5 file file_name = "_".join( (file_prefix, "plane", axis.value, str(slice_index).zfill(6)) ) else: file_name = file_prefix file_name = ".".join((file_name, file_format)) file_path = os.path.join(location, file_name) volumes = (RawVolume(file_path=file_path),) elif file_format in ("jp2", "jp2k", "edf", "tiff"): if file_format in ("jp2k", "jp2"): constructor = JP2KVolume elif file_format == "edf": constructor = EDFVolume elif file_format == "tiff": constructor = TIFFVolume else: raise NotImplementedError basename = file_prefix file_path = location volumes = ( constructor( folder=location, volume_basename=basename, ), ) elif file_format == "tiff3d": if slice_index is not None: # case of a single hdf5 file file_name = "_".join( (file_prefix, "plane", axis.value, str(slice_index).zfill(6)) ) else: file_name = file_prefix file_name = ".".join((file_name, "tiff")) file_path = os.path.join(location, file_name) volumes = ( MultiTIFFVolume( file_path=file_path, ), ) else: raise ValueError(f"file format not managed: {file_format}") return tuple([volume.get_identifier() for volume in volumes]) def get_multi_cor_recons_volume_identifiers( scan: TomwerScanBase, slice_index: int, location: str, file_prefix: str, cors: tuple, file_format: str, axis=NabuPlane.XY, ) -> dict: """ util to retrieve Volumes (identifier) reconstructed by nabu-multicor :param scan: scam processed by the nabu-multicor :param location: location of the files :param cors: cors for which we want the reconstructed slices. As this extension is created by nabu the cor reference is in absolute. :param file_format: file format of the reconstruction :return: a dict with absolute cor value as key and the Volume identifier as value """ _logger.info("Deduce volume identifiers for nabu-multicor") if isinstance(slice_index, str): slice_index = slice_index_to_int( slice_index=slice_index, scan=scan, axis=axis, # for now we always expect the multicor to be done along Z ) assert isinstance( slice_index, int ), "slice_index is expected to be an int or to be converted to it" res = {} if isinstance(scan, EDFTomoScan): entry = "entry" else: entry = scan.entry for cor in cors: file_path = os.path.join( location, f"{file_prefix}_{cor:.3f}_{str(slice_index).zfill(5)}.{file_format}", ) if file_format in ("hdf5", "h5", "hdf"): file_path = os.path.join( location, f"{file_prefix}_{cor:.3f}_{str(slice_index).zfill(5)}.{file_format}", ) volume = HDF5Volume( file_path=file_path, data_path="/".join([entry, "reconstruction"]), ) elif file_format in ("vol", "raw"): volume = (RawVolume(file_path=file_path),) elif file_format in ("jp2", "jp2k", "edf", "tiff"): if file_format in ("jp2k", "jp2"): constructor = JP2KVolume elif file_format == "edf": constructor = EDFVolume elif file_format == "tiff": constructor = TIFFVolume else: raise NotImplementedError file_path = location volume = constructor( folder=os.path.dirname(file_path), volume_basename=os.path.basename(file_path), ) else: raise ValueError(f"file_format {file_format} is not handled for now") res[cor] = volume.get_identifier() return res class _NabuMode(Enum): FULL_FIELD = "standard acquisition" HALF_ACQ = "half acquisition" # HELICAL = "helical acquisition" class _NabuStages(Enum): INI = "initialization" PRE = "pre-processing" PHASE = "phase" PROC = "processing" POST = "post-processing" VOLUME = "volume" @staticmethod def getStagesOrder(): return ( _NabuStages.INI, _NabuStages.PRE, _NabuStages.PHASE, _NabuStages.PROC, _NabuStages.POST, ) @staticmethod def getProcessEnum(stage): """Return the process Enum associated to the stage""" stage = _NabuStages(stage) if stage is _NabuStages.INI: raise NotImplementedError() elif stage is _NabuStages.PRE: return _NabuPreprocessing elif stage is _NabuStages.PHASE: return _NabuPhase elif stage is _NabuStages.PROC: return _NabuProcessing elif stage is _NabuStages.POST: return _NabuPostProcessing raise NotImplementedError() class _NabuPreprocessing(Enum): """Define all the preprocessing action possible and the order they are applied on""" FLAT_FIELD_NORMALIZATION = "flat field normalization" CCD_FILTER = "hot spot correction" @staticmethod def getPreProcessOrder(): return ( _NabuPreprocessing.FLAT_FIELD_NORMALIZATION, _NabuPreprocessing.CCD_FILTER, ) class _NabuPhase(Enum): """Define all the phase action possible and the order they are applied on""" PHASE = "phase retrieval" UNSHARP_MASK = "unsharp mask" LOGARITHM = "logarithm" @staticmethod def getPreProcessOrder(): return (_NabuPhase.PHASE, _NabuPhase.UNSHARP_MASK, _NabuPhase.LOGARITHM) class _NabuProcessing(Enum): """Define all the processing action possible""" RECONSTRUCTION = "reconstruction" @staticmethod def getProcessOrder(): return (_NabuProcessing.RECONSTRUCTION,) class _NabuPostProcessing(Enum): """Define all the post processing action available""" SAVE_DATA = "save" @staticmethod def getProcessOrder(): return (_NabuPostProcessing.SAVE_DATA,) class _NabuReconstructionMethods(Enum): CONE = "cone" FBP = "FBP" HBP = "HBP" MLEM = "MLEM" class _NabuPhaseMethod(Enum): """ Nabu phase method """ PAGANIN = "Paganin" CTF = "CTF" NONE = "None" @classmethod def from_value(cls, value): if value in (None, ""): return _NabuPhaseMethod.NONE elif isinstance(value, str): if value.lower() == "paganin": return _NabuPhaseMethod.PAGANIN elif value.lower() == "none": return _NabuPhaseMethod.NONE elif value.lower() == "ctf": return _NabuPhaseMethod.CTF else: return _NabuPhaseMethod(value=value) class _NabuFBPFilterType(Enum): RAMLAK = "ramlak" SHEPP_LOGAN = "shepp-logan" COSINE = "cosine" HAMMING = "hamming" HANN = "hann" TUKEY = "tukey" LANCZOS = "lanczos" HILBERT = "hilbert" class _NabuPaddingType(Enum): ZEROS = "zeros" EDGES = "edges" class RingCorrectionMethod(Enum): NONE = "None" MUNCH = "munch" VO = "vo" MEAN_SUBTRACTION = "mean-subtraction" MEAN_DIVISION = "mean-division" def nabu_std_err_has_error(errs: bytes | None): """ small util to parse stderr where some warning can exists. But I don't think we want to catch all warnings from nabu so this is a (bad) concession This will disapear when execution will be done directly from a tomwer thread instead of a subprocess """ def ignore(line) -> bool: return ( "warning" in line or "Warning" in line or "warn(" in line or "cupyx.jit.rawkernel" in line or "deprecated" in line or line.replace(" ", "") == "" or "unable to load" in line or "deprecated" in line or "self.module = SourceModule(self.src, **self.sourcemodule_kwargs)" in line or "return SourceModule(" in line or "CUBLAS" in line or "Not supported for EDF" in line # debatable but very disturbing from the gui side... anyway EDF days are coming to an end or "PerformanceWarning" in line or "jitify._init_module()" in line or " unable to import 'siphash24.siphash13" in line or "_create_built_program_from_source_cached" in line or "prg.build(options_bytes," in line or ( "Performing MLEM" in line and "iterations" in line ) # corrct usage of tqdm (goes to stderr) or "Remark: The" in line or "int x_stop_other = other_x_range.y;" in line or "int y_stop_other = other_y_range.y;" in line ) if errs is None: return False else: for line in errs.decode("UTF-8").split("\n"): if not ignore(line): print("\n\nline is", line) return True return False def update_cfg_file_after_transfer(config_file_path, old_path, new_path): """ update nabu configuration file path from /lbsram/data to /data """ if old_path is None or new_path is None: return # load configucation file config_as_dict = parse_nabu_config_file(config_file_path) assert isinstance(config_as_dict, dict) # update paths paths_to_update = ( ("dataset", "location"), ("output", "location"), ("pipeline", "steps_file"), ) for section, field in paths_to_update: # update dataset location and output location if section in config_as_dict: location = config_as_dict[section].get(field, None) if location is not None: config_as_dict[section][field] = location.replace(old_path, new_path, 1) # overwrite file generate_nabu_configfile( fname=config_file_path, default_config=nabu_fullfield_default_config, config=config_as_dict, options_level="advanced", ) def slice_index_to_int( slice_index: int | str, scan: TomwerScanBase, axis=NabuPlane.XY, ) -> int: """ cast a slice to an index. The slice can be a string in ['first', 'last', 'middle'] """ axis = NabuPlane.from_value(axis) if slice_index == "fisrt": return 0 elif slice_index == "last": if scan is None: # backward compatibility in the case the scan is not provided. Should not happen anymore _logger.warning("Scan not provided. Consider the 2048 width detector") return 2047 elif scan.dim_2 is not None: return scan.dim_2 - 1 else: # this could happen on some EDF scans. Not expected to happen for HDF5 _logger.warning("unable to get dim size, guess this is 2048 width") # in this return 2047 elif slice_index == "middle": if scan is None: # backward compatibility in the case the scan is not provided. Should not happen anymore _logger.warning("Scan not provided. Consider the 1024 width detector") # default middle. return 1024 elif axis is NabuPlane.XY: if scan.dim_2 is None: _logger.warning("unable to get dim size, guess this is 2048 height") return 1024 else: return scan.dim_2 // 2 elif axis in (NabuPlane.YZ, NabuPlane.XZ): if scan.dim_1 is None: _logger.warning("unable to get dim size, guess this is 2048 width") return 1024 else: return scan.dim_1 // 2 else: raise ValueError(f"axis {axis} is not handled") else: return int(slice_index) def get_nabu_multicor_file_prefix(scan): if isinstance(scan, EDFTomoScan): dataset_path = scan.path elif isinstance(scan, NXtomoScan): dataset_path = scan.master_file else: raise TypeError(f"{type(scan)} is not handled") if os.path.isfile(dataset_path): # hdf5 file_prefix = os.path.basename(dataset_path).split(".")[0] elif os.path.isdir(dataset_path): file_prefix = os.path.basename(dataset_path) else: raise ValueError(f"dataset location {scan.path} is neither a file or directory") file_prefix += "_rec" # avoid overwriting dataset return file_prefix def update_nabu_config_for_tiff_3d(config: dict) -> None: """ Adapts the nabu configuration for 3D TIFF file format. Nabu currently distinguishes TIFF files as either single-file or multi-file, but does not natively support the concept of a 3D TIFF format. This function bridges that gap by adjusting the configuration to handle 3D TIFF files as a single logical unit. """ file_format = NabuOutputFileFormat( config.get("output", {}).get("file_format", "tiff") ) if file_format is NabuOutputFileFormat.TIFF_3D: config["output"]["file_format"] = "tiff" config["output"]["tiff_single_file"] = "1" _logger.debug("Mapping tiff3d -> nabu tiff + tiff_single_file=1") def from_nabu_config_to_file_format(nabu_config) -> NabuOutputFileFormat: """ Infers the file format from a Nabu configuration dictionary. This function is specifically designed to handle the special case of 3D TIFF files. See 'update_nabu_config_for_tiff_3d' """ file_format = NabuOutputFileFormat(nabu_config["output"]["file_format"]) tiff_single_file = nabu_config["output"].get("tiff_single_file", False) if tiff_single_file in (True, 1, "1") and file_format is NabuOutputFileFormat.TIFF: return NabuOutputFileFormat.TIFF_3D else: return file_format def get_default_output_volume_for_tiff_3d( input_volume: TomwerVolumeBase, output_dir: str ) -> TomwerVolumeBase: """ Does what nabu.io.cast_volume.get_default_output_volume does but for for 3d-tiff For a given input volume and output type return output volume as an instance of VolumeBase :param intput_volume: volume for which we want to get the resulting output volume for a cast :param output_dir: output dir to save the cast volume """ if not isinstance(input_volume, VolumeBase): raise TypeError(f"input_volume is expected to be an instance of {VolumeBase}") if isinstance(input_volume, (EDFVolume, TIFFVolume, JP2KVolume)): file_path = os.path.join( input_volume.data_url.file_path(), output_dir, input_volume.get_volume_basename() + ".tiff", ) volume = MultiTIFFVolume( file_path=file_path, ) assert ( volume.get_identifier() is not None ), "volume should be able to create an identifier" return volume elif isinstance(input_volume, (HDF5Volume, MultiTIFFVolume)): data_file_parent_path, data_file_name = os.path.split( input_volume.data_url.file_path() ) # replace extension: data_file_name = ".".join( [ os.path.splitext(data_file_name)[0], "tiff", ] ) volume = MultiTIFFVolume( file_path=os.path.join(data_file_parent_path, output_dir, data_file_name), ) assert ( volume.get_identifier() is not None ), "volume should be able to create an identifier" return volume else: raise NotImplementedError(f"input volume format {input_volume} is not handled") ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1772989186.921101 tomwer-1.6.17/src/tomwer/core/process/reconstruction/normalization/0000755000175000017500000000000015153325403024703 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/normalization/__init__.py0000644000175000017500000000016715153325210027014 0ustar00paynopaynofrom .normalization import SinoNormalizationTask # noqa F403 from .params import SinoNormalizationParams # noqa F403 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/normalization/normalization.py0000644000175000017500000002711015153325210030140 0ustar00paynopayno# coding: utf-8 """ material for radio and sinogram normalization """ from __future__ import annotations import functools import logging import numpy import tomoscan.esrf.scan.utils from processview.core.dataset import DatasetIdentifier from processview.core.superviseprocess import SuperviseProcess from silx.io.url import DataUrl from tomoscan.esrf.scan.utils import get_data from tomoscan.normalization import Method as NormMethod import tomwer.version from tomwer.core.process.task import Task from tomwer.core.utils.scanutils import data_identifier_to_scan from .params import SinoNormalizationParams, _ValueCalculationFct, _ValueSource _logger = logging.getLogger(__name__) class SinoNormalizationTask( Task, SuperviseProcess, input_names=("data",), output_names=("data",), optional_input_names=("serialize_output_data",), ): """ Task to define the normalization to apply to a sinogram before reconstructing it with nabu """ def __init__( self, process_id=None, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None, ): Task.__init__( self, varinfo=varinfo, inputs=inputs, node_id=node_id, node_attrs=node_attrs, execinfo=execinfo, ) SuperviseProcess.__init__(self, process_id=process_id) self._dry_run = False if "configuration" in inputs: self.set_configuration(inputs["configuration"]) def set_properties(self, properties): if isinstance(properties, SinoNormalizationParams): self._settings = properties.to_dict() else: self._settings = properties def set_configuration(self, configuration: dict) -> None: self.set_properties(configuration) def run(self): scan = data_identifier_to_scan(self.inputs.data) if scan is None: return extra_infos = scan.intensity_normalization.get_extra_infos() extra_infos.update( { "tomwer_processing_res_code": None, } ) scan.intensity_normalization.set_extra_infos(extra_infos) params = SinoNormalizationParams.from_dict(self._settings) # define the method used to the scan scan.intensity_normalization.method = params.method # after this processing the source try: if params.method in (NormMethod.NONE, NormMethod.CHEBYSHEV): final_norm_info = {} elif params.source is _ValueSource.MANUAL_ROI: value = self._compute_from_manual_roi(scan) # need_conversion_to_tomoscan = True # insure this could be hashable (for caches) if isinstance(value, numpy.ndarray): value = tuple(value) final_norm_info = { "value": value, "source": _ValueSource.MANUAL_SCALAR.value, } elif params.source is _ValueSource.AUTO_ROI: value = self._compute_from_automatic_roi(scan) # need_conversion_to_tomoscan = True # insure this could be hashable (for caches) if isinstance(value, numpy.ndarray): value = tuple(value) final_norm_info = { "value": value, "source": _ValueSource.MANUAL_SCALAR.value, } elif params.source is _ValueSource.DATASET: final_norm_info = { "dataset_url": params.extra_infos.get("dataset_url", None), "source": _ValueSource.DATASET.value, } elif params.source is _ValueSource.MANUAL_SCALAR: final_norm_info = { "value": params.extra_infos.get("value", None), "source": _ValueSource.MANUAL_SCALAR.value, } else: raise ValueError(f"method {params.method} is not handled") except Exception as e: _logger.error(e) final_norm_info = {"tomwer_processing_res_code": False} else: final_norm_info.update({"tomwer_processing_res_code": True}) scan.intensity_normalization.set_extra_infos(final_norm_info) if self.get_input_value("serialize_output_data", True): self.outputs.data = scan.to_dict() else: self.outputs.data = scan def _compute_from_manual_roi(self, scan): params = SinoNormalizationParams.from_dict(self.get_configuration()) extra_info = params.extra_infos start_x = extra_info.get("start_x", None) end_x = extra_info.get("end_x", None) start_y = extra_info.get("start_y", None) end_y = extra_info.get("end_y", None) calc_fct = extra_info.get("calc_fct", None) if calc_fct is None: raise ValueError("calc_fct should be provided") else: calc_fct = _ValueCalculationFct(calc_fct) try: value = self._cache_compute_from_manual_roi( dataset_identifier=scan.get_identifier(), start_x=start_x, start_y=start_y, end_x=end_x, end_y=end_y, )[calc_fct.value] except Exception as e: _logger.error(e) return None else: return value @staticmethod @functools.lru_cache( maxsize=6 ) # maxsize=6 to at most keep info at volume and at frame level for 3 scans def _cache_compute_from_manual_roi( dataset_identifier: DatasetIdentifier, start_x, end_x, start_y, end_y, ) -> dict: """ compute mean and median on a volume or a slice. To improve io performances compute both mean and median for both cases one per frame or one for the entire volume :param projections: :param start_x: :param end_x: :param start_y: :param end_y: :param calc_area: :return: """ if start_x is None or end_x is None or start_y is None or end_y is None: raise ValueError("min_x, max_x, min_y and max_y should all be provided.") else: start_x = int(start_x) start_y = int(start_y) end_x = int(end_x) end_y = int(end_y) # clamp ROI with 0 border start_x = max(0, start_x) start_y = max(0, start_y) end_x = max(0, end_x) end_y = max(0, end_y) scan = dataset_identifier.recreate_dataset() projections = scan.projections roi_area = numpy.zeros( (len(projections), int(end_y - start_y), int(end_x - start_x)) ) # as dataset can be large we try to split the load of # the data proj_compacted = tomoscan.esrf.scan.utils.get_compacted_dataslices( projections, max_grp_size=20, ) proj_indexes = sorted(proj_compacted.keys()) # small hack to avoid loading several time the same url url_treated = set() def url_has_been_treated(url: DataUrl): return ( url.file_path(), url.data_path(), url.data_slice().start, url.data_slice().stop, url.data_slice().step, url.scheme(), ) in url_treated def append_url(url: DataUrl): url_treated.add( ( url.file_path(), url.data_path(), url.data_slice().start, url.data_slice().stop, url.data_slice().step, url.scheme(), ) ) current_idx = 0 url_idxs = {v.path(): k for k, v in scan.projections.items()} for proj_index in proj_indexes: url = proj_compacted[proj_index] if url_has_been_treated(url): continue append_url(url) data = get_data(url) if data.ndim < 2: raise ValueError("data is expected to be at least 2D") # clamp ROI with frame size start_x = min(data.shape[-1], start_x) start_y = min(data.shape[-2], start_y) end_x = min(data.shape[-1], end_x) end_y = min(data.shape[-2], end_y) def retrieve_data_proj_indexes(url_): urls = [] for data_slice in range( url_.data_slice().start, url_.data_slice().stop, url_.data_slice().step or 1, ): urls.append( DataUrl( file_path=url_.file_path(), data_path=url_.data_path(), scheme=url_.scheme(), data_slice=data_slice, ) ) # try to retrieve the index from the projections else # keep the slice index as the frame index (should be the # case in most case res = [] for my_url in urls: my_url_path = my_url.path() if my_url_path in url_idxs: res.append(url_idxs[my_url_path]) else: _logger.warning( f"unable to retrieve frame index from url {my_url_path}. Take the slice index as frame index" ) return res data_indexes = retrieve_data_proj_indexes(url) # apply flat field correction if data.ndim == 2: projs = (data,) else: projs = list(data) data = scan.flat_field_correction(projs=projs, proj_indexes=data_indexes) if data is None: continue data = numpy.asarray(data) if data.ndim == 2: roi_area[current_idx] = data[start_y:end_y, start_x:end_x] current_idx += 1 elif data.ndim == 3: length = data.shape[0] roi_area[current_idx : current_idx + length] = data[ :, start_y:end_y, start_x:end_x ] current_idx += length else: raise ValueError(f"Frame where expected and not a {data.ndim}D object") return SinoNormalizationTask.compute_stats(roi_area) @staticmethod def compute_stats(data): results = {} for calc_fct in _ValueCalculationFct: if data.ndim == 3: res = getattr(numpy, calc_fct.value)(data, axis=(-2, -1)) elif data.ndim == 2: res = getattr(numpy, calc_fct.value)(data, axis=(-1)) elif data.ndim in (0, 1): res = data else: raise ValueError(f"dataset dimension not handled ({data.ndim}D)") results[calc_fct.value] = res return results def _compute_from_automatic_roi(self, scan): raise NotImplementedError("Not implemented yet") @staticmethod def program_name(): """Name of the program used for this processing""" return "Intensity normalization" @staticmethod def program_version(): """version of the program used for this processing""" return tomwer.version.version @staticmethod def definition(): """definition of the process""" return "Normalize intensity." ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/normalization/params.py0000644000175000017500000000645715153325210026550 0ustar00paynopayno# coding: utf-8 """ material for radio and sinogram normalization """ from __future__ import annotations from enum import Enum as _Enum from tomoscan.normalization import Method class _ValueSource(_Enum): MONITOR = "intensity monitor" MANUAL_ROI = "manual ROI" AUTO_ROI = "automatic ROI" DATASET = "from dataset" MANUAL_SCALAR = "scalar" NONE = "none" class _ValueCalculationFct(_Enum): MEAN = "mean" MEDIAN = "median" class _DatasetScope(_Enum): LOCAL = "local" GLOBAL = "global" class _DatasetInfos: def __init__(self): self._scope = _DatasetScope.GLOBAL self._file_path = None self._data_path = None @property def scope(self) -> _DatasetScope: return self._scope @scope.setter def scope(self, scope: str | _DatasetScope): self._scope = _DatasetScope(scope) @property def file_path(self): return self._file_path @file_path.setter def file_path(self, file_path): self._file_path = file_path @property def data_path(self): return self._data_path @data_path.setter def data_path(self, data_path: str): self._data_path = data_path class _ROIInfo: def __init__(self, x_min=None, x_max=None, y_min=None, y_max=None): self.x_min = x_min self.x_max = x_max self.y_min = y_min self.y_max = y_max class SinoNormalizationParams: """Information regarding the intensity normalization to be done""" def __init__(self, method=Method.NONE, source=_ValueSource.NONE, extra_infos=None): self._method = Method.NONE self._source = _ValueSource.NONE self._extra_infos = {} self.method = method self.extra_infos = extra_infos if extra_infos is not None else {} self.source = source @property def method(self): return self._method @method.setter def method(self, method: str | Method | None): if method is None: method = Method.NONE self._method = Method(method) @property def source(self): return self._source @source.setter def source(self, source): if source is None: source = _ValueSource.NONE self._source = _ValueSource(source) @property def extra_infos(self): return self._extra_infos @extra_infos.setter def extra_infos(self, extra_infos: dict): if not isinstance(extra_infos, dict): raise TypeError("extra infos is expected to be a dictionary") elif "method" in extra_infos: raise KeyError("'method' is a reserved key name") else: self._extra_infos = extra_infos def to_dict(self): _dict = self._extra_infos _dict["method"] = self.method.value _dict["source"] = self.source.value return _dict @staticmethod def from_dict(dict_): params = SinoNormalizationParams() params.load_from_dict(dict_=dict_) return params def load_from_dict(self, dict_): tmp_dict = dict_.copy() if "method" in tmp_dict: self.method = tmp_dict["method"] del tmp_dict["method"] if "source" in tmp_dict: self.source = tmp_dict["source"] del tmp_dict["source"] self.extra_infos = tmp_dict ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/output.py0000644000175000017500000000621015153325210023722 0ustar00paynopaynofrom __future__ import annotations import os import logging from tomwer.io.utils.raw_and_processed_data import ( to_processed_data_path, ) from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.process.output import ProcessDataOutputDirMode from tomwer.core.utils.scanutils import format_output_location from tomwer.core.process.output import NabuOutputFileFormat _logger = logging.getLogger(__name__) PROCESS_FOLDER_RECONSTRUCTED_VOLUMES = "reconstructed_volumes" PROCESS_FOLDER_RECONSTRUCTED_SLICES = "reconstructed_slices" PROCESS_FOLDER_CAST_VOLUME = "cast_volume" def get_output_folder_from_scan( mode: ProcessDataOutputDirMode, scan: TomwerScanBase, nabu_location: str | None, file_basename: str, file_format: NabuOutputFileFormat, processed_data_folder_name: str | None, ) -> tuple[str, str]: """ :param mode: output mode, should save this to raw data, processed data... :param scan: scan for which we want to get the output folder :param nabu_location: output location provided by user (in case mode is 'other') :param file_basename: file basename to take in order to create output files :param file_format: output volume format (edf...) :param processed_data_folder_name: name of the processed data folder. Like 'reconstructed_volumes' or 'reconstructed_slices'... :return: (location, location_cfg_files). Location is the nabu configuration field 'output/location' 'location_cfg_files' is the information on where to save the nabu configuration file """ output_mode = ProcessDataOutputDirMode.from_value(mode) file_format = NabuOutputFileFormat.from_value(file_format) if output_mode is ProcessDataOutputDirMode.OTHER and nabu_location in ("", None): _logger.error( "'other' output dir requested but no path provided. Fall back on the output dir to the scan folder" ) # note: this is only an info because we expect to pass by this one for all .ows configuration (before 1.3 version) # as there was no different option by the time output_mode = ProcessDataOutputDirMode.IN_SCAN_FOLDER if output_mode is ProcessDataOutputDirMode.OTHER: location = format_output_location(nabu_location, scan=scan) location_cfg_files = location elif output_mode in ( ProcessDataOutputDirMode.IN_SCAN_FOLDER, ProcessDataOutputDirMode.PROCESSED_DATA_FOLDER, ): # otherwise default location will be the data root level location = os.path.join(scan.path, processed_data_folder_name) location_cfg_files = location if file_format in ( NabuOutputFileFormat.EDF, NabuOutputFileFormat.TIFF, NabuOutputFileFormat.JP2K, ): # if user specify the location location = "/".join([location, file_basename]) if output_mode is ProcessDataOutputDirMode.PROCESSED_DATA_FOLDER: location = to_processed_data_path(location) location_cfg_files = to_processed_data_path(location_cfg_files) else: raise NotImplementedError(f"mode {output_mode.value} is not implemented yet") return location, location_cfg_files ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/params_cache.py0000644000175000017500000000276715153325210025005 0ustar00paynopaynofrom __future__ import annotations from tomwer.core.scan.scanbase import TomwerScanBase from collections import OrderedDict _CACHE: {str, tuple[float | None, dict | None]} = OrderedDict() """ In the case we want to reprocess a scan we (might) need to know the cor and the nabu reconstruction parameters (for nabu slice and volume reconstructions) But we are not keeping all those object during the full 'orange canvas' lifecycle, it would be too heavy. As a consequence we cache those (small) values (and only those) of the last n scans (n==30) in case users want to reprocess some of those. n value is an arbitrary value. """ _CACHE_SIZE = 30 def save_reconstruction_parameters_to_cache(scan: TomwerScanBase): # pop if exists. Will move this item as 'last-in' _CACHE.pop(scan.get_identifier().to_str(), None) _CACHE[scan.get_identifier().to_str()] = ( None if scan.axis_params is None else scan.axis_params.relative_cor_value, None if scan.nabu_recons_params is None else scan.nabu_recons_params, ) if len(_CACHE) > _CACHE_SIZE: _CACHE.popitem(last=False) def load_reconstruction_parameters_from_cache(scan: TomwerScanBase): cor, nabu_recons_params = _CACHE.get(scan.get_identifier().to_str(), (None, None)) if cor is not None and scan.axis_params is not None: scan.axis_params.set_relative_value(cor) if nabu_recons_params is not None: scan.nabu_recons_params = nabu_recons_params def clear_reconstruction_parameters_cache(): _CACHE.clear() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/paramsbase.py0000644000175000017500000001431015153325210024500 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import copy import itertools from collections import OrderedDict class _ReconsParam(object): """ Base class of the Reconstruction parameters """ _UNSPLIT_KEYS = tuple() """keys that we don't want to treat in `to_unique_recons_set` function""" def __init__(self): self.__unmanaged_params = {} """dict of unmanaged option. Key is param name. Value is Value""" self._managed_params = {} """tuple of octave parameters we expect to get. Other will be moved to unmanaged params""" def changed(self): """callback function when a parameter value is changed""" pass @property def unmanaged_params(self): return self.__unmanaged_params @property def managed_params(self): return self._managed_params @property def all_params(self): res = list(self.managed_params.keys()) res.extend(self.unmanaged_params.keys()) return res def _add_unmanaged_param(self, param, value): self.__unmanaged_params[param] = value def _reset_unmanaged_params(self): self.__unmanaged_params = {} def _remove_unmanaged_param(self, param): if param in self.__unmanaged_params: del self.__unmanaged_params[param] def to_dict(self): """convert object to a dict readable by fastomo3""" raise NotImplementedError() @staticmethod def from_dict(_dict): """create _ReconsParam from a dict readable / writable by fastomo3""" raise NotImplementedError() def load_from_dict(self, _dict): """Update current paramters values from a dictionary""" raise NotImplementedError() def _get_parameter_value(self, parameter): """Find the parameter value from a dict name, to keep compatibility with fastomo3.""" if parameter in self._managed_params: return self._managed_params[parameter].fget(self) elif parameter in self.__unmanaged_params: return self.unmanaged_params[parameter] else: raise ValueError("requested parameter is not registered (%s)" % parameter) def _set_parameter_value(self, parameter, value): """Find the parameter value from a dict name, to keep compatibility with fastomo3.""" if parameter in self._managed_params: assert self._managed_params[parameter] is not None self._managed_params[parameter].fset(self, value) else: self.__unmanaged_params[parameter] = value self.changed() def to_unique_recons_set(self, as_to_dict: bool = False) -> tuple: """ :return: a tuple of unique reconstruction parameters in order to have each parameter as a single value (and no list) :param as_to_dict: True if we want to get the same value as if we where exporting it with to_dict function. There is some cast in the to_dict function. """ params_list = OrderedDict() dict_values = self.to_dict() for parameter in self.all_params: value = self._get_parameter_value(parameter) if isinstance(value, _ReconsParam): value = value.to_unique_recons_set(as_to_dict=as_to_dict) elif as_to_dict is True: value = dict_values[parameter] params_list[parameter] = value if parameter in self._UNSPLIT_KEYS: params_list[parameter] = [params_list[parameter]] continue if parameter in ("DB", "DB2") and isinstance(params_list[parameter], str): params_list[parameter] = _get_db_fromstr(params_list[parameter]) if type(params_list[parameter]) not in (list, tuple): params_list[parameter] = [params_list[parameter]] if not isinstance(params_list[parameter][0], dict): params_list[parameter] = set(params_list[parameter]) res = list() for _set_rp in itertools.product(*list(params_list.values())): _dict_set = {} for key, value in zip(params_list.keys(), _set_rp): _dict_set[key] = value res.append(_dict_set) return tuple(res) def __getitem__(self, arg): return self._get_parameter_value(arg) def __setitem__(self, key, value): self._set_parameter_value(parameter=key, value=value) def _load_unmanaged_params(self, _dict): """reset unmanaged parameters and store all parameters not defined in `_managed_params` into __unmanaged_params :params dict _dict: dict to parse to find unmanaged parameters """ if not isinstance(_dict, dict): raise TypeError(f"{_dict} is expected to be an instance of {dict}") self._reset_unmanaged_params() for _key in _dict: if _key not in self.managed_params: _tmp_dict = {_key: _dict[_key]} self.__unmanaged_params.update(_tmp_dict) def copy(self, other_rp): """ copy parameters value from other_rp :param other_rp: reconsparam to copy """ if other_rp is None: return for parameter_name in other_rp._managed_params: value = other_rp._get_parameter_value(parameter=parameter_name) if isinstance(value, _ReconsParam) and parameter_name in self: self._managed_params[parameter_name].copy(value) else: self._set_parameter_value(parameter=parameter_name, value=value) self._set_unmanaged_params(other_rp.unmanaged_params) def _set_unmanaged_params(self, params): assert type(params) is dict self.__unmanaged_params = copy.copy(params) def _get_db_fromstr(vals): vals = vals.replace(" ", "") vals = vals.replace("(", "") vals = vals.replace(")", "") vals = vals.replace("]", "") vals = vals.replace("[", "") vals = vals.replace(";", ",").split(",") if vals[-1] == "": del vals[-1] res = [] [res.append(float(val)) for val in vals] if len(res) == 1: return res[0] else: return tuple(res) ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1772989186.921101 tomwer-1.6.17/src/tomwer/core/process/reconstruction/saaxis/0000755000175000017500000000000015153325403023305 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/saaxis/__init__.py0000644000175000017500000000021115153325210025404 0ustar00paynopaynofrom .params import SAAxisParams # noqa F401 from .saaxis import SAAxisProcess # noqa F401 from .saaxis import SAAxisTask # noqa F401 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/saaxis/params.py0000644000175000017500000001011315153325210025132 0ustar00paynopaynofrom __future__ import annotations from typing import Iterable import numpy from enum import Enum as _Enum from tomwer.core.process.reconstruction.scores.params import SABaseParams class ReconstructionMode(_Enum): VERTICAL = "Vertical" TILT_CORRECTION = "Tilt correction" class SAAxisParams(SABaseParams): """Parameters for the semi-automatic axis calculation""" def __init__(self): super().__init__() self._research_width = 10 # in pixel self._estimated_cor = None self._n_reconstruction = 20 self._mode = ReconstructionMode.VERTICAL self._image_width = None self._cluster_config = None @property def research_width(self): return self._research_width @research_width.setter def research_width(self, research_width): self._research_width = research_width @property def estimated_cor(self): return self._estimated_cor @estimated_cor.setter def estimated_cor(self, estimated_cor): self._estimated_cor = estimated_cor @property def cors(self) -> Iterable: return self.compute_cors( estimated_cor=self.estimated_cor, research_width=self.research_width, n_reconstruction=self.n_reconstruction, ) @property def mode(self): return self._mode @mode.setter def mode(self, mode): mode = ReconstructionMode(mode) self._mode = mode @property def image_width(self) -> float | None: return self._image_width @image_width.setter def image_width(self, width): if not isinstance(width, (type(None), float, int)): raise TypeError(f"None, int or float expected. Not {type(width)}") else: self._image_width = width def to_dict(self): ddict = super().to_dict() ddict.update( { "estimated_cor": self.estimated_cor, "research_width": self.research_width, "n_reconstruction": self.n_reconstruction, "mode": self.mode.value, } ) return ddict def load_from_dict(self, dict_: dict): super().load_from_dict(dict_) if "research_width" in dict_: self.research_width = dict_["research_width"] if "estimated_cor" in dict_: self.estimated_cor = dict_["estimated_cor"] if "n_reconstruction" in dict_: self.n_reconstruction = dict_["n_reconstruction"] if "mode" in dict_: self.mode = ReconstructionMode(dict_["mode"]) @staticmethod def from_dict(dict_): params = SAAxisParams() params.load_from_dict(dict_=dict_) return params def check_configuration(self): """ Insure all requested information for processing the SAAXis are here. :raises: ValueError if some information are missing """ missing_information = [] if self.cors is None or len(self.cors) == 0: missing_information.append("no values for center of rotation provided") if self.slice_indexes is None: missing_information.append("slice index not provided") if len(missing_information) > 0: missing_information_str = " ; ".join(missing_information) raise ValueError( f"Some informations are missing: {missing_information_str}" ) @staticmethod def compute_cors(estimated_cor, research_width, n_reconstruction): if estimated_cor is None: raise ValueError("No estimated cor provided") if estimated_cor == "middle": estimated_cor = 0 if n_reconstruction % 2 == 0: n_reconstruction = n_reconstruction + 1 # insure we have an odd number of cor to insure the estimated # one is reconstructed if n_reconstruction == 1: return (estimated_cor,) return numpy.linspace( start=estimated_cor - research_width / 2.0, stop=estimated_cor + research_width / 2.0, num=n_reconstruction, ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/saaxis/saaxis.py0000644000175000017500000007443515153325210025160 0ustar00paynopayno"""contain the SAAxisProcess. Half automatic center of rotation calculation""" from __future__ import annotations import logging import os import h5py from nabu.preproc.phase import compute_paganin_margin import numpy from multiprocessing import Pool from processview.core.manager import DatasetState, ProcessManager from processview.core.superviseprocess import SuperviseProcess from silx.io.url import DataUrl from silx.io.utils import h5py_read_dataset from tomwer.core.utils.deprecation import deprecated_warning from tomoscan.io import HDF5File import tomwer.version from tomwer.core.process.reconstruction.axis import AxisRP from tomwer.core.process.reconstruction.nabu.nabuscores import ( run_nabu_multicor, ) from tomwer.core.process.reconstruction.nabu.nabuslices import ( interpret_tomwer_configuration, ) from tomwer.core.process.reconstruction.scores import ( ComputedScore, apply_roi, compute_score, get_disk_mask_radius, ) from tomwer.core.process.reconstruction.scores.params import ScoreMethod from tomwer.core.process.reconstruction.utils.cor import relative_pos_to_absolute from tomwer.core.process.task import Task from tomwer.core.process import utils as core_utils from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils import logconfig from tomwer.core.utils.scanutils import data_identifier_to_scan from tomwer.core.utils.slurm import is_slurm_available from tomwer.core.process.reconstruction.nabu.utils import update_nabu_config_for_tiff_3d from tomwer.io.utils.h5pyutils import EntryReader from tomwer.core.volume.volumefactory import VolumeFactory from tomwer.io.utils.utils import get_slice_data from tomwer.io.utils import format_stderr_stdout from tomwer.core.process.reconstruction.nabu.nabucommon import ( ResultsLocalRun, ResultSlurmRun, ResultsWithStd, ) from tomwer.core.futureobject import FutureTomwerObject from tomwer.core.process.reconstruction.saaxis.params import ReconstructionMode from tomwer.core.process.reconstruction.nabu.utils import ( get_multi_cor_recons_volume_identifiers, get_nabu_multicor_file_prefix, ) from .params import SAAxisParams _logger = logging.getLogger(__name__) DEFAULT_RECONS_FOLDER = "multi_cor_results" def one_slice_several_cor( scan, configuration: dict, process_id: int | None = None, ) -> tuple: """ Run a slice reconstruction using nabu per Center Of Rotation (cor) provided Then for each compute a score (quality) of the center of rotation .. warning:: if target if the slurm cluster this will wait for the processing to be done to return the result. as this function is returning the result of the score process on reconstructed slices :param scan: :param configuration: nabu reconstruction parameters (can include 'slurm-cluster' key defining the slurm configuration) :param process_id: process id :return: cor_reconstructions, outs, errs cor_reconstructions is a dictionary of cor as key and a tuple (url, score) as value """ task = SAAxisTask( process_id=process_id, inputs={ "data": scan, "sa_axis_params": configuration, "serialize_output_data": False, }, ) task.run() return ( task.outputs.scores, task.outputs.std_out, task.outputs.std_err, task.outputs.rois, ) class SAAxisTask( Task, SuperviseProcess, input_names=("data", "sa_axis_params"), output_names=("data", "best_cor"), optional_input_names=( "dry_run", "dump_roi", "dump_process", "serialize_output_data", "compute_scores", # for GUI we want to post pone the score calculation "pool_size", ), ): """ Main process to launch several reconstruction of a single slice with several Center Of Rotation (cor) values As the saaxis is integrating the score calculation we will never get a future_tomo_scan as output """ DEFAULT_POOL_SIZE = 10 def __init__( self, process_id=None, inputs=None, varinfo=None, node_attrs=None, execinfo=None ): Task.__init__( self, varinfo=varinfo, inputs=inputs, node_attrs=node_attrs, execinfo=execinfo, ) SuperviseProcess.__init__(self, process_id=process_id) self._dry_run = inputs.get("dry_run", False) self._dump_process = inputs.get("dump_process", True) self._dump_roi = inputs.get("dump_roi", False) self._std_outs = tuple() self._std_errs = tuple() self._current_processing = None self._cancelled = False @property def std_outs(self): return self._std_outs @property def std_errs(self): return self._std_errs def set_dry_run(self, dry_run): self._dry_run = dry_run @property def dry_run(self): return self._dry_run @property def dump_roi(self): return self._dump_roi @dump_roi.setter def dump_roi(self, dump): self._dump_roi = dump @staticmethod def autofocus(scan) -> float | None: scores = scan.saaxis_params.scores if scores is None: return score_method = scan.saaxis_params.score_method best_cor, best_score = None, 0 for cor, (_, score_cls) in scores.items(): if score_cls is None: # if score calculation failed continue score = score_cls.get(score_method) if score is None: continue if score > best_score: best_cor, best_score = cor, score scan.saaxis_params.autofocus = best_cor if scan.axis_params is None: # create parameter if needed because will set it once he find the best cor scan.axis_params = AxisRP() scan.axis_params.frame_width = scan.dim_1 scan.axis_params.set_relative_value(best_cor) return best_cor def _config_preprocessing( self, scan, config, file_format, output_dir, cluster_config ): """convert general configuration to nabu - single reconstruction - configuration""" nabu_configurations = interpret_tomwer_configuration(config, scan=None) if len(nabu_configurations) == 0: raise RuntimeWarning( "Unable to get a valid nabu configuration for " "reconstruction." ) elif len(nabu_configurations) > 1: _logger.warning( "Several configuration found for nabu (you probably " "ask for several delta/beta value or several slices). " "Picking the first one." ) # work on file name... if output_dir is None: output_dir = os.path.join(scan.path, DEFAULT_RECONS_FOLDER) nabu_configuration = nabu_configurations[0][0] if cluster_config == {}: cluster_config = None is_cluster_job = cluster_config is not None if is_cluster_job and not is_slurm_available(): raise ValueError( "job on cluster requested but no access to slurm cluster found" ) # handle reconstruction section if "reconstruction" not in nabu_configuration: nabu_configuration["reconstruction"] = {} nabu_configuration["reconstruction"]["rotation_axis_position"] = "" # handle output section if "output" not in nabu_configuration: nabu_configuration["output"] = {} nabu_configuration["output"]["location"] = output_dir nabu_configuration["output"]["file_format"] = file_format update_nabu_config_for_tiff_3d(nabu_configuration) # handle resources section nabu_configuration["resources"] = nabu_configuration.get("resources", {}) nabu_configuration["resources"]["method"] = "local" return nabu_configuration def _run_nabu_multicor( self, scan, nabu_config, cors, slice_index, file_format, cluster_config: dict | None, dry_run=False, ): if not (cluster_config is None or isinstance(cluster_config, dict)): raise TypeError( f"cluster_config is expected to be a dict. Get {type(cluster_config)} instead." ) runner = run_nabu_multicor( nabu_config=nabu_config, scan=scan, cors=cors, slice_index=slice_index, dry_run=dry_run, file_format=file_format, cluster_config=cluster_config if cluster_config is not None else None, process_id=self.process_id, instantiate_classes_only=True, output_file_prefix_pattern="cor_{file_name}_{value}", # as the cor is evolving, create different files to make sure the name will be unique ) future_tomo_obj = None recons_urls = dict() std_outs = [] std_errs = [] self._current_processing = runner try: result = runner.run() except TimeoutError as e: _logger.error(e) else: success = result.success if isinstance(result, ResultsWithStd): std_outs.append(result.std_out) std_errs.append(result.std_err) if isinstance(result, ResultsLocalRun): recons_urls = { cor: recons for cor, recons in zip(cors, result.results_identifiers) } if isinstance(result, ResultSlurmRun): future_tomo_obj = FutureTomwerObject( tomo_obj=scan, process_requester_id=self.process_id, futures=result.future_slurm_jobs, ) return success, recons_urls, (future_tomo_obj,), std_outs, std_errs def _resolve_futures( self, scan, nabu_config, slice_index, file_format, cors, cor_reconstructions, future_tomo_objs: dict, output_dir, ): """ in case the task is launching jobs over slurm wait for them to be finished before resuming 'standard processing' """ if output_dir is None: output_dir = os.path.join(scan.path, DEFAULT_RECONS_FOLDER) file_prefix = get_nabu_multicor_file_prefix(scan) for future_tomo_obj in future_tomo_objs: if self._cancelled: break if future_tomo_obj is None: continue future_tomo_obj.results() if future_tomo_obj.cancelled() or future_tomo_obj.exceptions(): continue for cor in cors: cor_nabu_ref = relative_pos_to_absolute( relative_pos=cor, det_width=scan.dim_1, ) volume_identifiers = get_multi_cor_recons_volume_identifiers( scan=scan, slice_index=slice_index, location=nabu_config["output"]["location"], file_prefix=file_prefix, file_format=file_format, cors=(cor_nabu_ref,), ) volume_identifier = volume_identifiers.get(cor_nabu_ref, None) if volume_identifier is None: _logger.warning( f"failed to load volume for {cor}. Something went wrong on slurm submission job" ) cor_reconstructions[cor] = volume_identifier def _post_processing(self, scan, slice_index, cor_reconstructions: dict): """ compute score along the different slices :param cor_reconstructions: key is expected to be a float with the cor value and the value is expected to be a volume identifier (volume with a single frame) """ post_processing = _PostProcessing( slice_index=slice_index, scan=scan, cor_reconstructions=cor_reconstructions, pool_size=self.get_input_value("pool_size", self.DEFAULT_POOL_SIZE), ) post_processing._cancelled = self._cancelled self._current_processing = post_processing return post_processing.run() def _compute_mess_details(self, mess=""): """ util to join a message and nabu std err and std out """ nabu_logs = [] for std_err, std_out in zip(self._std_errs, self.std_outs): nabu_logs.append(format_stderr_stdout(stdout=std_out, stderr=std_err)) self._nabu_log = nabu_logs nabu_logs.insert(0, mess) return "\n".join(nabu_logs) @staticmethod def _preprocess_slice_index(slice_index, mode: ReconstructionMode): if isinstance(slice_index, str): if not slice_index == "middle": raise ValueError(f"slice index {slice_index} not recognized") else: return slice_index elif not len(slice_index) == 1: raise ValueError(f"{mode.value} mode only manage one slice") else: return list(slice_index.values())[0] def get_output_dir(self, params: SAAxisParams, scan: TomwerScanBase): output_dir = params.output_dir or None if output_dir is None: output_dir = ( params.nabu_recons_params.get("output", {}).get("location", None) or None ) if output_dir is None: output_dir = os.path.join(scan.path, DEFAULT_RECONS_FOLDER) return output_dir def run(self): scan = data_identifier_to_scan(self.inputs.data) if scan is None: self.outputs.data = None return if isinstance(scan, TomwerScanBase): scan = scan elif isinstance(scan, dict): scan = ScanFactory.create_scan_object_frm_dict(scan) else: raise ValueError(f"input type of {scan}: {type(scan)} is not managed") # TODO: look and update if there is some nabu reconstruction # or axis information to be used back configuration = self.inputs.sa_axis_params params = SAAxisParams.from_dict(configuration) # insure output dir is created params.output_dir = self.get_output_dir(params=params, scan=scan) if not os.path.exists(params.output_dir): os.makedirs(params.output_dir) # try to find an estimated cor # from a previously computed cor if params.estimated_cor is None and scan.axis_params is not None: relative_cor = scan.axis_params.relative_cor_value if relative_cor is not None and numpy.issubdtype( type(relative_cor), numpy.number ): params.estimated_cor = relative_cor _logger.info( f"{scan}: set estimated cor from previously computed cor ({params.estimated_cor})" ) # from scan.x_rotation_axis_pixel_position if ( params.estimated_cor is None and scan.x_rotation_axis_pixel_position is not None ): params.estimated_cor = scan.x_rotation_axis_pixel_position _logger.info( f"{scan}: set estimated cor from motor position ({params.estimated_cor})" ) if scan.dim_1 is not None: params.image_width = scan.dim_1 scan.saaxis_params = params mode = ReconstructionMode(params.mode) if mode is not ReconstructionMode.VERTICAL: raise ValueError(f"{mode} is not handled for now") nabu_config = configuration.get("nabu_params", {}) nabu_output_config = configuration.get("output", {}) file_format = nabu_output_config.get("file_format", "hdf5") slice_index = self._preprocess_slice_index( params.slice_indexes, mode=mode, ) cluster_config = params.cluster_config dry_run = self._dry_run # step one: complete nabu configuration(s) nabu_config = self._config_preprocessing( scan=scan, config=nabu_config, file_format=file_format, output_dir=params.output_dir, cluster_config=cluster_config, ) # step 2: run reconstructions cors_res = {} rois = {} try: ( _, cor_reconstructions, future_tomo_objs, self._std_outs, self._std_errs, ) = self._run_nabu_multicor( scan=scan, nabu_config=nabu_config, cors=tuple(params.cors), slice_index=slice_index, file_format=file_format, cluster_config=cluster_config, dry_run=dry_run, ) except Exception as e: _logger.error(e) mess = f"sa-axis -nabu- computation for {str(scan)} failed." state = DatasetState.FAILED else: # step 3: wait for future if any self._resolve_futures( scan=scan, nabu_config=nabu_config, slice_index=slice_index, file_format=file_format, cor_reconstructions=cor_reconstructions, cors=tuple(params.cors), future_tomo_objs=future_tomo_objs, output_dir=params.output_dir, ) # step 4: run post processing (compute score for each slice) if self.get_input_value("compute_scores", True): try: cors_res, rois = self._post_processing( scan=scan, slice_index=slice_index, cor_reconstructions=cor_reconstructions, ) except Exception as e: _logger.error(e) mess = ( f"sa-axis -post-processing- computation for {str(scan)} failed." ) state = DatasetState.FAILED cors_res = {} else: state = DatasetState.WAIT_USER_VALIDATION mess = "sa-axis computation succeeded" else: cors_res = {} state = DatasetState.FAILED mess = "couldn't find 'compute_scores'" if self._cancelled: state = DatasetState.CANCELLED mess = "scan cancelled by the user" ProcessManager().notify_dataset_state( dataset=scan, process=self, state=state, details=self._compute_mess_details(mess), ) scan.saaxis_params.scores = cors_res best_relative_cor = self.autofocus(scan=scan) if best_relative_cor is not None: scan.axis_params.set_relative_value(best_relative_cor) self._process_end(scan=scan, cors_res=cors_res, score_rois=rois) if self.get_input_value("serialize_output_data", True): self.outputs.data = scan.to_dict() else: self.outputs.data = scan self.outputs.best_cor = best_relative_cor def _process_end(self, scan, cors_res, score_rois): assert isinstance(scan, TomwerScanBase) state = ProcessManager().get_dataset_state( dataset_id=scan.get_identifier(), process=self ) if state not in ( DatasetState.CANCELLED, DatasetState.FAILED, DatasetState.SKIPPED, ): try: extra = { logconfig.DOC_TITLE: self._scheme_title, logconfig.SCAN_ID: str(scan), } slice_index = self.inputs.sa_axis_params.get("slice_index", None) if cors_res is None: info = f"fail to compute cor scores of slice {slice_index} for scan {scan}." _logger.processFailed(info, extra=extra) ProcessManager().notify_dataset_state( dataset=scan, process=self, state=DatasetState.FAILED, details=info, ) else: info = ( f"cor scores of slice {slice_index} for scan {scan} computed." ) _logger.processSucceed(info, extra=extra) ProcessManager().notify_dataset_state( dataset=scan, process=self, state=DatasetState.WAIT_USER_VALIDATION, details=info, ) except Exception as e: _logger.error(e) else: if self._dump_process: self.save_results_to_disk(scan=scan) if self.dump_roi: self.dump_rois(scan, score_rois=score_rois) @staticmethod def dump_rois(scan, score_rois): if scan.saaxis_params.scores in (None, {}): return process_url = SAAxisTask.get_results_url(scan=scan) with HDF5File(process_url.file_path(), mode="w") as h5f: nx_process = h5f.require_group(process_url.data_path()) score_roi_grp = nx_process.require_group("score_roi") for cor, roi in score_rois.items(): score_roi_grp[str(cor)] = roi score_roi_grp[str(cor)].attrs["interpretation"] = "image" @staticmethod def program_name(): """Name of the program used for this processing""" return "semi-automatic axis" @staticmethod def program_version(): """version of the program used for this processing""" return tomwer.version.version @staticmethod def definition(): """definition of the process""" return "Semi automatic center of rotation / axis calculation" @staticmethod def get_results_url(scan): return DataUrl( file_path=scan.get_relative_file( os.path.join(DEFAULT_RECONS_FOLDER, "tomwer_saaxis.h5") ), data_path=scan.entry or "entry", scheme="silx", ) @staticmethod def save_results_to_disk(scan): if scan.saaxis_params.scores in (None, {}): return saaxis_results_url = SAAxisTask.get_results_url(scan=scan) if not os.path.exists(saaxis_results_url.file_path()): _logger.error("no result saved") return # save it to the file with HDF5File(saaxis_results_url.file_path(), mode="a") as h5f: nx_process = h5f.require_group(saaxis_results_url.data_path()) if "NX_class" not in nx_process.attrs: nx_process.attrs["NX_class"] = "NXprocess" results = nx_process.require_group("results") for cor, (url, score) in scan.saaxis_params.scores.items(): results_cor = results.require_group(str(cor)) for method in ScoreMethod: method_score = score.get(method) if method_score is None: results_cor[method.value] = "None" else: results_cor[method.value] = method_score link_path = os.path.relpath( url.file_path(), os.path.dirname(saaxis_results_url.file_path()), ) results_cor["reconstructed_slice"] = h5py.ExternalLink( link_path, url.data_path() ) @staticmethod def load_results_from_disk(scan): saaxis_results_url = SAAxisTask.get_results_url(scan=scan) if saaxis_results_url.file_path() is None or not os.path.exists( saaxis_results_url.file_path() ): _logger.warning( "Unable to find process file. Unable to read " "existing processing" ) return None, None try: with EntryReader(saaxis_results_url) as h5f_entry_node: scores = core_utils.get_scores(h5f_entry_node) if ( "results" in h5f_entry_node and "center_of_rotation" in h5f_entry_node["results"] ): selected = h5py_read_dataset( h5f_entry_node["results"]["center_of_rotation"] ) else: _logger.warning(f"no results found for {scan}") selected = None return scores, selected except ValueError: _logger.warning(f"Data path ({saaxis_results_url.data_path()}) not found") return None, None def cancel(self): """ stop current processing """ if self._current_processing is not None: self._cancelled = True self._current_processing.cancel() class _PostProcessing: """class used to run SA-axis post-processing on reconstructed slices""" def __init__(self, cor_reconstructions, slice_index, scan, pool_size) -> None: self._cor_reconstructions = cor_reconstructions self._slice_index = slice_index self._scan = scan self._cancelled = False self.pool_size = pool_size @staticmethod def compute_score(item: tuple): cor, (url, data), mask_disk_radius, cancelled = item if cancelled: return (None, None), None if data is None: score = None data_roi = None else: if not isinstance(data, numpy.ndarray): raise TypeError( f"data should be a numpy array. Get {type(data)} instead" ) assert data.ndim == 2, f"data should be 2D. Get {data.ndim} instead" data_roi = apply_roi(data=data, radius=mask_disk_radius, url=url) # move data_roi to [0-1] range # preprocessing: get percentile 0 and 99 from image and # "clean" highest and lowest pixels from it min_p, max_p = numpy.percentile(data_roi, (1, 99)) data_roi_int = data_roi[...] data_roi_int[data_roi_int < min_p] = min_p data_roi_int[data_roi_int > max_p] = max_p data_roi_int = (data_roi_int - min_p) / (max_p - min_p) score = ComputedScore( tv=compute_score(data=data_roi_int, method=ScoreMethod.TV), std=compute_score(data=data_roi_int, method=ScoreMethod.STD), tomo_consistency=None, ) return {cor: (url, score)}, {cor: data_roi} def run(self): datasets = self.load_datasets() assert isinstance(datasets, dict) mask_disk_radius = get_disk_mask_radius(datasets) with Pool(self.pool_size) as pool: res = pool.map( self.compute_score, [ ( *item, mask_disk_radius, self._cancelled, ) for item in datasets.items() ], ) scores = {} rois = {} for mydict in res: myscores, myrois = mydict scores.update(myscores) rois.update(myrois) return scores, rois @staticmethod def _load_dataset(item: tuple): cor, volume_identifier = item if volume_identifier is None: return {cor: (None, None)} volume = VolumeFactory.create_tomo_object_from_identifier(volume_identifier) urls = tuple(volume.browse_data_urls()) if len(urls) == 0: _logger.error( f"volume {volume.get_identifier().to_str()} has no url / slices. Unable to load any data." ) return {cor: (None, None)} if len(urls) != 1: _logger.error( f"volume is expected to have at most one url (single slice volume). get {len(urls)} - most likely nabu reconstruction failed. Do you have GPU ? Are the requested COR values valid ? - Especially for Half-acquisition" ) url = urls[0] if not isinstance(url, (DataUrl, str)): raise TypeError(f"url is expected to be a str or DataUrl not {type(url)}") try: data = get_slice_data(url=url) except Exception as e: _logger.error(f"Fail to compute a score for {url.path()}. Reason is {e}") return {cor: (url, None)} else: if data.ndim == 3: if data.shape[0] == 1: data = data.reshape(data.shape[1], data.shape[2]) elif data.shape[2] == 1: data = data.reshape(data.shape[0], data.shape[1]) else: raise ValueError(f"Data is expected to be 2D. Not {data.ndim}D") elif data.ndim == 2: pass else: raise ValueError("Data is expected to be 2D. Not {data.ndim}D") return {cor: (url, data)} def load_datasets(self): with Pool(self.pool_size) as pool: res = pool.map( self._load_dataset, self._cor_reconstructions.items(), ) datasets_ = {} for mydict in res: datasets_.update(mydict) return datasets_ def cancel(self): self._cancelled = True class SAAxisProcess(SAAxisTask): def __init__( self, process_id=None, inputs=None, varinfo=None, node_attrs=None, execinfo=None ): deprecated_warning( name="tomwer.core.process.reconstruction.saaxis.SAAxisProcess", type_="class", reason="improve readibility", since_version="1.2", replacement="SAAxisTask", ) super().__init__(process_id, inputs, varinfo, node_attrs, execinfo) def _is_margin_too_large( dims: tuple[int, int], sample_detector_distance: float, energy_kev: float, delta_beta, pixel_size: float, margin_threshold: int, ) -> bool: """Check if resulting margin for phasing are too large (and nabu reconstruction failed)""" v_margin, _ = compute_paganin_margin( dims, distance=sample_detector_distance, energy=energy_kev, delta_beta=delta_beta, pixel_size=pixel_size, ) return v_margin > margin_threshold ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1772989186.921101 tomwer-1.6.17/src/tomwer/core/process/reconstruction/sadeltabeta/0000755000175000017500000000000015153325403024266 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/sadeltabeta/__init__.py0000644000175000017500000000024215153325210026371 0ustar00paynopaynofrom .params import SADeltaBetaParams # noqa F401 from .sadeltabeta import SADeltaBetaProcess # noqa F401 from .sadeltabeta import SADeltaBetaTask # noqa F401 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/sadeltabeta/params.py0000644000175000017500000000520315153325210026117 0ustar00paynopayno# coding: utf-8 from __future__ import annotations from tomwer.core.process.reconstruction.nabu.utils import retrieve_lst_of_value_from_str from tomwer.core.process.reconstruction.scores.params import SABaseParams class SADeltaBetaParams(SABaseParams): """Parameters for the semi-automatic axis calculation""" def __init__(self): super().__init__() self._delta_beta_values = (100,) self._selected_db = None @property def delta_beta_values(self): return self._delta_beta_values @delta_beta_values.setter def delta_beta_values(self, delta_beta_values): if isinstance(delta_beta_values, str): self._delta_beta_values = retrieve_lst_of_value_from_str( delta_beta_values, type_=float ) else: self._delta_beta_values = delta_beta_values def set_db_selected_value(self, value): self._selected_db = value @property def selected_delta_beta_value(self) -> float | None: return self._selected_db def to_dict(self) -> dict: my_dict = super().to_dict() my_dict.update( { "delta_beta_values": self.delta_beta_values, "selected_db_value": self.selected_delta_beta_value, } ) return my_dict def load_from_dict(self, dict_: dict): if not isinstance(dict_, dict): raise TypeError(f"dict_ should be an instance of dict not {type(dict_)}") super().load_from_dict(dict_) if "delta_beta_values" in dict_: self.delta_beta_values = dict_["delta_beta_values"] if "selected_db_value" in dict_: self.set_db_selected_value(value=dict_["selected_db_value"]) @staticmethod def from_dict(dict_): params = SADeltaBetaParams() params.load_from_dict(dict_=dict_) return params def check_configuration(self): """ Insure all requested information for processing the SAAXis are here. :raises: ValueError if some information are missing """ missing_information = [] if self.delta_beta_values is None or len(self.delta_beta_values) == 0: missing_information.append("no values for center of rotation provided") if self.slice_indexes is None: missing_information.append("slice index not provided") if len(missing_information) > 0: missing_information_str = " ; ".join(missing_information) raise ValueError( f"Some informations are missing: {missing_information_str}" ) def __str__(self): return str(self.to_dict()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py0000644000175000017500000007062315153325210027115 0ustar00paynopayno"""contain the SADeltaBetaProcess. Half automatic best delta / beta finder""" from __future__ import annotations import logging import os from copy import copy, deepcopy import h5py import numpy from multiprocessing import Pool from tqdm import tqdm from nabu.pipeline.config import get_default_nabu_config from nabu.pipeline.fullfield.nabu_config import ( nabu_config as nabu_fullfield_default_config, ) from processview.core.manager import DatasetState, ProcessManager from processview.core.superviseprocess import SuperviseProcess from tomoscan.esrf.scan.utils import get_data from tomoscan.io import HDF5File from silx.io.utils import h5py_read_dataset import tomwer.version from tomwer.core.process.reconstruction.nabu.nabucommon import ( ResultsLocalRun, ResultSlurmRun, ResultsWithStd, ) from tomwer.core.process.reconstruction.nabu.nabuslices import SingleSliceRunner from tomwer.core.process.reconstruction.utils.cor import relative_pos_to_absolute from tomwer.core.process.reconstruction.scores import ( ComputedScore, ScoreMethod, apply_roi, compute_score, get_disk_mask_radius, ) from tomwer.core.process.task import Task from tomwer.core.process import utils as core_utils from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils import logconfig from tomwer.core.utils.scanutils import data_identifier_to_scan from tomwer.core.volume.volumefactory import VolumeFactory from tomwer.io.utils import format_stderr_stdout from tomwer.io.utils.h5pyutils import EntryReader from tomwer.core.process.reconstruction.nabu.nabuscores import ( run_nabu_one_slice_several_config, ) from tomwer.core.futureobject import FutureTomwerObject from silx.io.url import DataUrl from silx.utils.deprecation import deprecated, deprecated_warning from ..nabu import utils as nabu_utils from .params import SADeltaBetaParams _logger = logging.getLogger(__name__) DEFAULT_RECONS_FOLDER = "multi_delta_beta_results" def one_slice_several_db( scan: TomwerScanBase, configuration: dict | SADeltaBetaParams, process_id: int | None = None, ) -> tuple: """ Run a slice reconstruction using nabu per Center Of Rotation (cor) provided Then for each compute a score (quality) of the center of rotation :param scan: :param configuration: :return: cor_reconstructions, outs, errs cor_reconstructions is a dictionary of cor as key and a tuple (url, score) as value """ if isinstance(configuration, SADeltaBetaParams): configuration = configuration.to_dict() task = SADeltaBetaTask( process_id=process_id, inputs={ "data": scan, "sa_axis_params": configuration, "serialize_output_data": False, }, ) task.run() return ( task.outputs.scores, task.outputs.std_out, task.outputs.std_err, task.outputs.rois, ) class SADeltaBetaTask( Task, SuperviseProcess, input_names=("data", "sa_delta_beta_params"), output_names=("data", "best_db"), optional_input_names=( "dry_run", "dump_roi", "dump_process", "serialize_output_data", "compute_scores", # for GUI we want to post pone the score calculation "pool_size", ), ): """ Main process to launch several reconstruction of a single slice with several Center Of Rotation (cor) values """ DEFAULT_POOL_SIZE = 10 def __init__( self, process_id=None, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None, ): Task.__init__( self, varinfo=varinfo, inputs=inputs, node_id=node_id, node_attrs=node_attrs, execinfo=execinfo, ) SuperviseProcess.__init__(self, process_id=process_id) self._dry_run = inputs.get("dry_run", False) self._dump_process = inputs.get("dump_process", True) self._dump_roi = inputs.get("dump_roi", False) self._sa_delta_beta_params = inputs.get("sa_delta_beta_params", None) self._std_outs = tuple() self._std_errs = tuple() self._cancelled = False @property def dump_roi(self): return self._dump_roi @dump_roi.setter def dump_roi(self, dump): self._dump_roi = dump @property def std_outs(self): return self._std_outs @property def std_errs(self): return self._std_errs def set_dry_run(self, dry_run): self._dry_run = dry_run @property def dry_run(self): return self._dry_run @deprecated(replacement="ewoks task inputs.sa_delta_beta_params") def set_configuration(self, configuration: dict) -> None: if isinstance(configuration, SADeltaBetaParams): self._settings = configuration.to_dict() elif isinstance(configuration, dict): self._settings = configuration else: raise TypeError( "configuration should be an instance of dict or " "SAAxisParams" ) @staticmethod def autofocus(scan) -> float | None: scores = scan.sa_delta_beta_params.scores if scores is None: return score_method = scan.sa_delta_beta_params.score_method best_db, best_score = None, 0 for cor, (_, score_cls) in scores.items(): if score_cls is None: # if score calculation failed continue score = score_cls.get(score_method) if score is None: continue if score > best_score: best_db, best_score = cor, score scan.sa_delta_beta_params.autofocus = best_db scan.sa_delta_beta_params.value = best_db return best_db def get_output_dir(self, params: SADeltaBetaParams, scan: TomwerScanBase): output_dir = params.output_dir or None if params.output_dir is None: output_dir = ( params.nabu_recons_params.get("output", {}).get("location", None) or None ) if output_dir is None: output_dir = os.path.join(scan.path, DEFAULT_RECONS_FOLDER) return output_dir def run(self): scan = data_identifier_to_scan(self.inputs.data) if scan is None: self.outputs.data = scan return if isinstance(scan, TomwerScanBase): scan = scan elif isinstance(scan, dict): scan = ScanFactory.create_scan_object_frm_dict(scan) else: raise ValueError(f"input type of {scan}: {type(scan)} is not managed") config = copy(self.inputs.sa_delta_beta_params) axis = config.get("reconstruction", {}).get("slice_plane", "XY") params = SADeltaBetaParams.from_dict(config) # insure scan contains some parameter regarding sa delta / beta if scan.sa_delta_beta_params is None: scan.sa_delta_beta_params = params # insure it also contains some axis_params if scan.axis_params is None: from tomwer.core.process.reconstruction.axis import AxisRP scan.axis_params = AxisRP() # create dir if does not exists params.output_dir = self.get_output_dir(params=params, scan=scan) if not os.path.exists(params.output_dir): os.makedirs(params.output_dir) slice_index = self._preprocess_slice_index(params.slice_indexes) delta_beta_s = params.delta_beta_values # TODO: check: dry run should only be settable at one location dry_run = self._dry_run or params.dry_run cluster_config = params.cluster_config nabu_config = params.nabu_recons_params # step one: complete nabu configuration(s) configs = self._config_preprocessing( scan=scan, config=nabu_config, delta_beta_s=delta_beta_s, output_dir=params.output_dir, ) # step 2: run reconstructions advancement = tqdm( desc=f"sa-delta-beta - slice {slice_index} of {scan.get_identifier().short_description()}" ) dbs_res = {} rois = {} try: ( _, dbs_res, future_tomo_objs, self._std_outs, self._std_errs, ) = self._run_one_slice_several_db( scan=scan, configs=configs, advancement=advancement, slice_index=slice_index, dry_run=dry_run, cluster_config=cluster_config, axis=axis, ) except Exception as e: _logger.error(e) mess = f"sa-delta-beta -nabu- computation for {str(scan)} failed." state = DatasetState.FAILED else: # step 3: wait for future if any self._resolve_futures( scan=scan, nabu_config=next(iter(configs.items()))[ 1 ], # db is not used but paganin and other parameters are. Take the first nabu configuration available slice_index=slice_index, db_reconstructions=dbs_res, future_tomo_objs=future_tomo_objs, axis=axis, ) # step 4: run post processing (compute score for each slice) if self.get_input_value("compute_scores", True): try: dbs_res, rois = self._post_processing( scan=scan, db_reconstructions=dbs_res, ) except Exception as e: _logger.error(e) mess = f"sa-delta-beta -post-processing- computation for {str(scan)} failed." state = DatasetState.FAILED dbs_res = {} else: state = DatasetState.WAIT_USER_VALIDATION self.delta_beta_s = scan.sa_delta_beta_params.autofocus mess = "sa-delta-beta computation succeeded" else: dbs_res = {} state = DatasetState.FAILED mess = "couldn't find 'compute_scores'" if self._cancelled: state = DatasetState.CANCELLED mess = "scan cancelled by the user" ProcessManager().notify_dataset_state( dataset=scan, process=self, state=state, details=self._compute_mess_details(mess), ) scan.sa_delta_beta_params.scores = dbs_res best_db = self.autofocus(scan=scan) # store nabu recons parameters to be used within the nabu volume for example. sc_config = get_default_nabu_config(nabu_fullfield_default_config) sc_config.update(nabu_config) if best_db is not None: sc_config["phase"]["delta_beta"] = ( best_db, ) # warning: at this tage delta_beta expects a list of value # store used reconstruction parameters - to be used later on scan.nabu_recons_params = sc_config # end processing if self.get_input_value("serialize_output_data", True): self.outputs.data = scan.to_dict() else: self.outputs.data = scan self.outputs.best_db = best_db self._process_end(scan=scan, db_res=dbs_res, score_rois=rois) def _compute_mess_details(self, mess=""): """ util to join a message and nabu std err and std out """ nabu_logs = [] for std_err, std_out in zip(self._std_errs, self.std_outs): nabu_logs.append(format_stderr_stdout(stdout=std_out, stderr=std_err)) self._nabu_log = nabu_logs nabu_logs.insert(0, mess) return "\n".join(nabu_logs) def _config_preprocessing(self, scan, config, delta_beta_s, output_dir) -> dict: config.get("phase", {}).pop("beam_shape", None) if ( scan.axis_params is not None and scan.axis_params.relative_cor_value is not None ): if "reconstruction" in config: cor_nabu_ref = relative_pos_to_absolute( relative_pos=scan.axis_params.relative_cor_value, det_width=scan.dim_1, ) config["reconstruction"]["rotation_axis_position"] = str(cor_nabu_ref) _logger.info(f"set nabu reconstruction parameters to {scan}") scan.nabu_recons_params = config res = {} for db in delta_beta_s: l_config = deepcopy(config) if "output" not in config: l_config["output"] = {} if output_dir is None: l_config["output"]["location"] = os.path.join( scan.path, DEFAULT_RECONS_FOLDER ) else: l_config["output"]["location"] = output_dir # TODO: allow file format modifications l_config["output"]["file_format"] = "hdf5" if "phase" not in config: l_config["phase"] = {} l_config["phase"]["delta_beta"] = db l_config["phase"]["method"] = "Paganin" res[db] = l_config return res def _run_one_slice_several_db( self, scan, configs, slice_index, advancement, dry_run, axis, cluster_config: dict | None, ): future_tomo_objs = {} success = True recons_urls = {} std_outs = [] std_errs = [] if not isinstance(cluster_config, (dict, type(None))): raise TypeError( f"'cluster_config' is expected to be a dict or None. Get {type(cluster_config)} instead." ) runners = run_nabu_one_slice_several_config( nabu_configs=configs, scan=scan, slice_index=slice_index, dry_run=dry_run, file_format="hdf5", advancement=advancement, cluster_config=cluster_config, process_id=self.process_id, instantiate_classes_only=True, output_file_prefix_pattern=None, axis=axis, ) for runner in runners: if self._cancelled: break self._current_processing = runner try: results = runner.run() except TimeoutError as e: _logger.error(e) else: assert isinstance( results, dict ), "results should be a dictionary with delta-beta as key and urls as value" for db, res in results.items(): success = success and res.success if isinstance(res, ResultsWithStd): std_outs.append(res.std_out) std_errs.append(res.std_err) if ( isinstance(res, ResultsLocalRun) and len(res.results_identifiers) > 0 ): assert ( len(res.results_identifiers) == 1 ), "only one slice expected" recons_urls[db] = res.results_identifiers[0] if isinstance(res, ResultSlurmRun): future_tomo_obj = FutureTomwerObject( tomo_obj=scan, process_requester_id=self.process_id, futures=res.future_slurm_jobs, ) future_tomo_objs[db] = future_tomo_obj if advancement is not None: advancement.update() return success, recons_urls, future_tomo_objs, std_outs, std_errs def _post_processing( self, scan, db_reconstructions, ): post_processing = _PostProcessing( scan=scan, db_reconstructions=db_reconstructions, pool_size=self.get_input_value("pool_size", self.DEFAULT_POOL_SIZE), ) post_processing._cancelled = self._cancelled self._current_processing = post_processing return post_processing.run() def _resolve_futures( self, scan, nabu_config: dict, db_reconstructions, slice_index, axis, future_tomo_objs: dict, ): assert isinstance(nabu_config, dict) pag = False ctf = False if "phase" in nabu_config: phase_method = nabu_config["phase"].get("method", "").lower() if phase_method in ("pag", "paganin"): pag = True elif phase_method in ("ctf",): ctf = True # treat future. for db, future_tomo_obj in future_tomo_objs.items(): if self._cancelled: break future_tomo_obj.results() if future_tomo_obj.cancelled() or future_tomo_obj.exceptions(): continue file_prefix = SingleSliceRunner.get_file_basename_reconstruction( scan=scan, slice_index=slice_index, pag=pag, db=int(db) if db is not None else None, ctf=ctf, axis=axis, ) # retrieve url volume_identifier = nabu_utils.get_recons_volume_identifier( file_prefix=file_prefix, location=nabu_config["output"]["location"], file_format=nabu_config.get("file_format", "hdf5"), scan=scan, slice_index=None, axis=axis, ) assert len(volume_identifier) <= 1, "only one slice expected" if len(volume_identifier) == 1: db_reconstructions[db] = volume_identifier[0] else: _logger.warning( f"something went wrong with reconstruction of {db} from {str(scan)}" ) @staticmethod def _preprocess_slice_index(slice_index): if isinstance(slice_index, str): if not slice_index == "middle": raise ValueError(f"slice index {slice_index} not recognized") else: return slice_index elif not len(slice_index) == 1: raise ValueError("only manage one slice") else: return list(slice_index.values())[0] def _process_end(self, scan, db_res, score_rois): assert isinstance(scan, TomwerScanBase) state = ProcessManager().get_dataset_state( dataset_id=scan.get_identifier(), process=self ) if state not in ( DatasetState.CANCELLED, DatasetState.FAILED, DatasetState.SKIPPED, ): try: extra = { logconfig.DOC_TITLE: self._scheme_title, logconfig.SCAN_ID: str(scan), } slice_index = self.inputs.sa_delta_beta_params.get("slice_index", None) if db_res is None: info = f"fail to compute delta/beta scores of slice {slice_index} for scan {scan}." _logger.processFailed(info, extra=extra) ProcessManager().notify_dataset_state( dataset=scan, process=self, state=DatasetState.FAILED, details=info, ) else: info = f"delta/beta scores of slice {slice_index} for scan {scan} computed." _logger.processSucceed(info, extra=extra) ProcessManager().notify_dataset_state( dataset=scan, process=self, state=DatasetState.WAIT_USER_VALIDATION, details=info, ) except Exception as e: _logger.error(e) else: if self._dump_process: self.save_results_to_disk(scan=scan) if self.dump_roi: self.dump_rois(scan, score_rois=score_rois) @staticmethod def dump_rois(scan, score_rois: dict): if not isinstance(score_rois, dict): raise TypeError("score_rois is expected to be a dict") if score_rois is None or len(score_rois) == 0: return if scan.saaxis_params.scores in (None, {}): return sa_delta_beta_results_url = SADeltaBetaTask.get_results_url(scan=scan) # save it to the file with HDF5File(sa_delta_beta_results_url.file_path(), mode="a") as h5f: nx_process = h5f.require_group(sa_delta_beta_results_url.data_path()) score_roi_grp = nx_process.require_group("score_roi") for db, roi in score_rois.items(): score_roi_grp[str(db)] = roi score_roi_grp[str(db)].attrs["interpretation"] = "image" @staticmethod def program_name(): """Name of the program used for this processing""" return "semi-automatic delta/beta finder" @staticmethod def program_version(): """version of the program used for this processing""" return tomwer.version.version @staticmethod def definition(): """definition of the process""" return "Semi automatic center of rotation / axis calculation" @staticmethod def get_results_url(scan): return DataUrl( file_path=scan.get_relative_file( os.path.join(DEFAULT_RECONS_FOLDER, "tomwer_sadelta_beta.h5") ), data_path=scan.entry or "entry", scheme="silx", ) @staticmethod def save_results_to_disk(scan): if scan.saaxis_params.scores in (None, {}): return results_url = SADeltaBetaTask.get_results_url(scan=scan) # save it to the file with HDF5File(results_url.file_path(), mode="w") as h5f: nx_process = h5f.require_group(results_url.data_path()) if "NX_class" not in nx_process.attrs: nx_process.attrs["NX_class"] = "NXprocess" results = nx_process.require_group("results") for cor, (url, score) in scan.sa_delta_beta_params.scores.items(): results_db = results.require_group(str(cor)) for method in ScoreMethod: if method is ScoreMethod.TOMO_CONSISTENCY: continue results_db[method.value] = score.get(method) link_path = os.path.relpath( url.file_path(), os.path.dirname(results_url.file_path()), ) results_db["reconstructed_slice"] = h5py.ExternalLink( link_path, url.data_path() ) @staticmethod def load_results_from_disk(scan): results_url = SADeltaBetaTask.get_results_url(scan=scan) process_file = results_url.file_path() if process_file is None or not os.path.exists(process_file): _logger.warning( "Unable to find process file. Unable to read " "existing processing" ) return None, None try: with EntryReader(results_url) as h5f_entry_node: scores = core_utils.get_scores(h5f_entry_node) if ( "results" in h5f_entry_node and "delta_beta" in h5f_entry_node["results"] ): selected = h5py_read_dataset( h5f_entry_node["results"]["delta_beta"] ) else: _logger.warning(f"no results found for {scan}") selected = None return scores, selected except ValueError: _logger.warning(f"Data path ({results_url.data_path()}) not found") return None, None def cancel(self): """ stop current processing """ if self._current_processing is not None: self._cancelled = True self._current_processing.cancel() class _PostProcessing: """class used to run SA-delta-beta post-processing on reconstructed slices""" DEFAULT_POOL_SIZE = 10 def __init__(self, db_reconstructions, scan, pool_size) -> None: self._db_reconstructions = db_reconstructions self._scan = scan self._cancelled = False self.pool_size = pool_size @staticmethod def compute_score(item: tuple): db, (url, data), mask_disk_radius, cancelled = item if data is None: score = None data_roi = None else: assert data.ndim == 2 data_roi = apply_roi(data=data, radius=mask_disk_radius, url=url) # move data_roi to [0-1] range # preprocessing: get percentile 0 and 99 from image and # "clean" highest and lowest pixels from it min_p, max_p = numpy.percentile(data_roi, (1, 99)) data_roi_int = data_roi[...] data_roi_int[data_roi_int < min_p] = min_p data_roi_int[data_roi_int > max_p] = max_p data_roi_int = (data_roi_int - min_p) / (max_p - min_p) score = ComputedScore( tv=compute_score(data=data_roi_int, method=ScoreMethod.TV), std=compute_score(data=data_roi_int, method=ScoreMethod.STD), ) return {db: (url, score)}, {db: data_roi} def run(self): datasets = self.load_datasets() assert isinstance(datasets, dict) mask_disk_radius = get_disk_mask_radius(datasets) with Pool(self.pool_size) as pool: res = pool.map( self.compute_score, [ ( *item, mask_disk_radius, self._cancelled, ) for item in datasets.items() ], ) scores = {} rois = {} for mydict in res: myscores, myrois = mydict scores.update(myscores) rois.update(myrois) return scores, rois @staticmethod def _load_dataset(item: tuple): db, volume_identifier = item slice_url = None # in case the try processing fails try: volume = VolumeFactory.create_tomo_object_from_identifier(volume_identifier) volumes_urls = tuple(volume.browse_data_urls()) if len(volumes_urls) > 1: _logger.warning( f"found a volume with mode that one url ({volumes_urls})" ) slice_url = volumes_urls[0] data = get_data(slice_url) except Exception as e: _logger.error( f"Fail to compute a score for {volume_identifier}. Reason is {e}" ) return {db: (slice_url, None)} else: if data.ndim == 3: if data.shape[0] == 1: data = data.reshape(data.shape[1], data.shape[2]) elif data.shape[2] == 1: data = data.reshape(data.shape[0], data.shape[1]) else: raise ValueError(f"Data is expected to be 2D. Not {data.ndim}D") elif data.ndim == 2: pass else: raise ValueError(f"Data is expected to be 2D. Not {data.ndim}D") return {db: (slice_url, data)} def load_datasets(self): with Pool(self.pool_size) as pool: res = pool.map( self._load_dataset, self._db_reconstructions.items(), ) datasets_ = {} for mydict in res: datasets_.update(mydict) return datasets_ def cancel(self): self._cancelled = True class SADeltaBetaProcess(SADeltaBetaTask): def __init__( self, process_id=None, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None, ): deprecated_warning( name="tomwer.core.process.reconstruction.sadeltabeta.sadeltabeta.SADeltaBetaProcess", type_="class", reason="improve readibility", since_version="1.2", replacement="SADeltaBetaTask", ) super().__init__(process_id, varinfo, inputs, node_id, node_attrs, execinfo) ././@PaxHeader0000000000000000000000000000003300000000000010211 xustar0027 mtime=1772989186.921101 tomwer-1.6.17/src/tomwer/core/process/reconstruction/scores/0000755000175000017500000000000015153325403023313 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/scores/__init__.py0000644000175000017500000000043215153325210025417 0ustar00paynopaynofrom .params import SABaseParams # noqa F401 from .scores import ComputedScore # noqa F401 from .scores import ScoreMethod # noqa F401 from .scores import apply_roi # noqa F401 from .scores import compute_score # noqa F401 from .scores import get_disk_mask_radius # noqa F401 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/scores/params.py0000644000175000017500000001375615153325210025160 0ustar00paynopaynofrom __future__ import annotations from tomwer.core.cluster.cluster import SlurmClusterConfiguration from tomwer.core.process.reconstruction.scores.scores import ScoreMethod from tomwer.core.utils.deprecation import deprecated class SABaseParams: """Parameters for the semi-automatic axis calculation""" _VALID_FILE_FORMAT = ("hdf5", "h5", "hdf", "npy", "npz", "tiff", "jp2", "jp2k") def __init__(self): self._n_reconstruction = 20 self._slice_indexes = "middle" self._nabu_recons_params = {} self._dry_run = False self._output_dir = None self._score_method = ScoreMethod.TV self._scores = None self._autofcous = None "scores. expected cor value as key and a tuple (score, url) as value" self._file_format = "hdf5" self._image_width = None self._cluster_config = None @property def autofocus(self): return self._autofcous @autofocus.setter def autofocus(self, autofocus): self._autofcous = autofocus @property def n_reconstruction(self): return self._n_reconstruction @n_reconstruction.setter def n_reconstruction(self, n): self._n_reconstruction = n @property def slice_indexes(self) -> dict | str | None: return self._slice_indexes @slice_indexes.setter def slice_indexes(self, indexes: dict | str | None): if isinstance(indexes, str): if not indexes == "middle": raise ValueError("the only valid indexes values is 'middle'") elif not isinstance(indexes, (type(None), dict)): raise TypeError( f"index should be an instance of int or None and not {type(indexes)}" ) self._slice_indexes = indexes @property def nabu_recons_params(self) -> dict: return self._nabu_recons_params @nabu_recons_params.setter def nabu_recons_params(self, params: dict): if not isinstance(params, dict): raise TypeError(f"params should be a dictionary and not {type(params)}") self._nabu_recons_params = params @property @deprecated(replacement="nabu_recons_params", since_version="1.2") def nabu_params(self) -> dict: return self.nabu_recons_params @nabu_params.setter @deprecated(replacement="nabu_recons_params", since_version="1.2") def nabu_params(self, params: dict): self.nabu_recons_params = params @property def dry_run(self) -> bool: return self._dry_run @dry_run.setter def dry_run(self, dry_run: bool): if not isinstance(dry_run, bool): raise ValueError("dry_run should be a bool") self._dry_run = dry_run @property def output_dir(self) -> str | None: """nabu cfg_files output dir. If not provided will use nabu slice output with saaxis/cfg_files as postfix""" return self._output_dir @output_dir.setter def output_dir(self, output_dir: str | None) -> None: if not isinstance(output_dir, (str, type(None))): raise TypeError("output_dir should be None or a str") self._output_dir = output_dir @property def score_method(self): return self._score_method @score_method.setter def score_method(self, method): self._score_method = ScoreMethod(method) @property def scores(self) -> dict | None: return self._scores @scores.setter def scores(self, scores: dict | None): if not isinstance(scores, (type(None), dict)): raise TypeError("scores should be None or a dictionary") self._scores = scores @property def file_format(self) -> str: return self._file_format @file_format.setter def file_format(self, format_: str): if not isinstance(format_, str): raise TypeError("format should be a str") if format_ not in self._VALID_FILE_FORMAT: raise ValueError( f"requested format ({format_}) is invalid. valid ones are {self._VALID_FILE_FORMAT}" ) self._file_format = format_ @property def cluster_config(self) -> dict | None: return self._cluster_config @cluster_config.setter def cluster_config(self, config: dict | None): if isinstance(config, SlurmClusterConfiguration): config = config.to_dict() if not isinstance(config, (dict, type(None))): raise TypeError( "config is expected to be None, a dict or SlurmClusterConfiguration" ) self._cluster_config = config def to_dict(self) -> dict: return { "slice_index": self.slice_indexes or "", "nabu_params": self.nabu_recons_params, "dry_run": self.dry_run, "output_dir": self.output_dir or "", "score_method": self.score_method.value, "cluster_config": ( self.cluster_config if self.cluster_config is not None else "" ), } def load_from_dict(self, dict_: dict): if "slice_index" in dict_: slice_index = dict_["slice_index"] if slice_index == "": slice_index = None self.slice_indexes = slice_index if "nabu_params" in dict_: self.nabu_recons_params = dict_["nabu_params"] if "dry_run" in dict_: self.dry_run = bool(dict_["dry_run"]) if "output_dir" in dict_: output_dir = dict_["output_dir"] if output_dir == "": output_dir = None self.output_dir = output_dir if "score_method" in dict_: self.score_method = ScoreMethod(dict_["score_method"]) if "cluster_config" in dict_: if dict_["cluster_config"] in (None, ""): self.cluster_config = None else: self.cluster_config = dict_["cluster_config"] @staticmethod def from_dict(dict_): res = SABaseParams() res.load_from_dict(dict_=dict_) return res ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/scores/scores.py0000644000175000017500000001333715153325210025166 0ustar00paynopaynofrom __future__ import annotations import logging import sys import numpy from enum import Enum as _Enum _logger = logging.getLogger(__name__) class ScoreMethod(_Enum): STD = "standard deviation" TV = "total variation" TV_INVERSE = "1 / (total variation)" STD_INVERSE = "1 / std" TOMO_CONSISTENCY = "tomo consistency" class ComputedScore: def __init__(self, tv, std, tomo_consistency=None): self._tv = tv self._std = std self._tomo_consistency = tomo_consistency @property def total_variation(self): return self._tv @property def std(self): return self._std @property def tomo_consistency(self): return self._tomo_consistency def get(self, method: ScoreMethod): method = ScoreMethod(method) if method is ScoreMethod.TV: return self.total_variation / float(10e5) elif method is ScoreMethod.TV_INVERSE: return (1.0 / self.total_variation) * float(10e5) elif method is ScoreMethod.STD: return self.std elif method is ScoreMethod.STD_INVERSE: return 1.0 / self.std elif method is ScoreMethod.TOMO_CONSISTENCY: return self.tomo_consistency else: raise ValueError(f"{method} is an unrecognized method") def __eq__(self, __value: object) -> bool: if not isinstance(__value, ComputedScore): return False else: return ( self.total_variation == __value.total_variation and self.std == __value.std and self.tomo_consistency == __value.tomo_consistency ) def __str__(self) -> str: return f"std: {self.std} - tv: {self.total_variation} - tomo-consistency: {self.tomo_consistency}" def compute_tomo_consistency( data: numpy.ndarray, original_sinogram, angles, original_axis_position, detector_width, ): from silx.opencl.projection import Projection projector = Projection( slice_shape=data.shape, angles=angles, detector_width=detector_width, axis_position=original_axis_position, ) sinogram = projector.projection(data) sinogram_n = (sinogram - sinogram.min()) / (sinogram.max() - sinogram.min()) original_sinogram_n = (original_sinogram - original_sinogram.min()) / ( original_sinogram.max() - original_sinogram.min() ) return 1.0 / (numpy.sum(numpy.abs(sinogram_n - original_sinogram_n)) + 1) def compute_score_contrast_std(data: numpy.ndarray): """ Compute a contrast score by simply computing the standard deviation of the frame :param data: frame for which we should compute the score :return: score of the frame """ if data is None: return None else: return data.std() * 100 def compute_tv_score(data: numpy.ndarray): """ Compute the data score as image total variation :param data: frame for which we should compute the score :return: score of the frame """ tv = numpy.sum( numpy.sqrt( numpy.gradient(data, axis=0) ** 2 + numpy.gradient(data, axis=1) ** 2 ) ) return tv _METHOD_TO_FCT = { ScoreMethod.STD: compute_score_contrast_std, ScoreMethod.TV: compute_tv_score, } def compute_score( data: numpy.ndarray, method: ScoreMethod, angles: list | None = None, original_sinogram: numpy.array | None = None, original_axis_position: float | None = None, detector_width: float | None = None, ) -> float | None: """ :param data: frame for which we should compute the score :param method: :return: score of the frame """ method = ScoreMethod(method) if data.ndim == 3: if data.shape[0] == 1: data = data.reshape(data.shape[1], data.shape[2]) elif data.shape[2] == 1: data = data.reshape(data.shape[0], data.shape[1]) else: raise ValueError(f"Data is expected to be 2D. Not {data.ndim}D") elif data.ndim == 2: pass else: raise ValueError(f"Data is expected to be 2D. Not {data.ndim}D") if method is ScoreMethod.TOMO_CONSISTENCY: try: return compute_tomo_consistency( data=data, angles=angles, original_sinogram=original_sinogram, original_axis_position=original_axis_position, detector_width=detector_width, ) except ImportError: return None except Exception as e: _logger.warning(f"Fail to compute 'tomo consistency' score. Reason is {e}") return None else: fct = _METHOD_TO_FCT.get(method, None) if fct is not None: return fct(data) else: raise ValueError(f"{method} is not handled") def get_disk_mask_radius(datasets_) -> int: """compute the radius to use for the mask""" radius = sys.maxsize # get min radius for _, (_, data) in datasets_.items(): if data is None: continue assert data.ndim == 2, "data is expected to be 2D" min_ = numpy.array(data.shape).min() if radius >= min_: radius = min_ return radius // 2 def apply_roi(data, radius, url) -> numpy.array: """compute the square included in the circle of radius and centered in the middle of the data""" half_width = int(radius / 2**0.5) center = numpy.array(data.shape[:]) // 2 min_x, max_x = center[0] - half_width, center[0] + half_width min_y, max_y = center[1] - half_width, center[1] + half_width try: return data[min_y:max_y, min_x:max_x] except Exception: _logger.error(f"Fail to apply roi for {url.path()}. Take the entire dataset") return data ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9251013 tomwer-1.6.17/src/tomwer/core/process/reconstruction/tests/0000755000175000017500000000000015153325403023157 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/tests/__init__.py0000644000175000017500000000000015153325210025252 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/tests/test_axis.py0000644000175000017500000000322315153325210025530 0ustar00paynopaynoimport h5py from nxtomo.paths.nxtomo import get_paths as get_nexus_paths from tomwer.core.process.reconstruction.axis import AxisTask from tomwer.tests.conftest import nxtomo_scan_360 # noqa F811 from tomwer.core.process.reconstruction.axis import AxisRP def test_read_x_rotation_axis_pixel_position(nxtomo_scan_360): # noqa F811 """ test reading of the estimated cor from the motor using scan metadata """ nexus_paths = get_nexus_paths(None) x_rotation_axis_pixel_position_path = "/".join( [ nxtomo_scan_360.entry, nexus_paths.INSTRUMENT_PATH, nexus_paths.nx_instrument_paths.DETECTOR_PATH, nexus_paths.nx_detector_paths.X_ROTATION_AXIS_PIXEL_POSITION or nexus_paths.nx_detector_paths.ESTIMATED_COR_FRM_MOTOR_PATH, ] ) with h5py.File(nxtomo_scan_360.master_file, mode="r") as h5f: assert x_rotation_axis_pixel_position_path not in h5f axis_params = AxisRP() axis_params.mode = "read" task = AxisTask( inputs={ "data": nxtomo_scan_360, "axis_params": axis_params, } ) # test the task when there is no metadata task.run() assert nxtomo_scan_360.axis_params.absolute_cor_value is None assert nxtomo_scan_360.axis_params.relative_cor_value is None # test the task when there is metadata with h5py.File(nxtomo_scan_360.master_file, mode="a") as h5f: h5f[x_rotation_axis_pixel_position_path] = 12.5 nxtomo_scan_360.clear_cache() task.run() assert nxtomo_scan_360.axis_params.absolute_cor_value == 22.5 assert nxtomo_scan_360.axis_params.relative_cor_value == 12.5 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/tests/test_axis_params.py0000644000175000017500000000311615153325210027074 0ustar00paynopaynoimport os import numpy import pytest from tomwer.core.process.reconstruction.axis.params import ( AxisCalculationInput, AxisResource, ) from tomwer.core.utils.scanutils import MockNXtomo def test_axis_resource(tmp_path): """ Test AxisResource class """ mock = MockNXtomo( scan_path=os.path.join(tmp_path, "scan1"), n_proj=10, n_ini_proj=10, scan_range=180, dim=100, ) scan = mock.scan first_proj = list(scan.projections.keys())[0] data_url = scan.projections[first_proj] axis_resource = AxisResource(url=data_url) assert axis_resource.data is not None with pytest.raises(TypeError): axis_resource.normalize_data(scan=None, log_=True) assert isinstance( axis_resource.normalize_data(scan=scan, log_=False), numpy.ndarray ) assert isinstance(axis_resource.normalize_data(scan=scan, log_=True), numpy.ndarray) assert isinstance(axis_resource.normalized_data_paganin, numpy.ndarray) assert isinstance(str(axis_resource), str) axis_resource.data = None assert axis_resource is not None def test_AxisCalculationInput(): """test all class AxisCalculationInput which is a bit 'malformed'""" assert ( AxisCalculationInput.from_value("transmission_withpag") is AxisCalculationInput.transmission_pag ) assert ( AxisCalculationInput.from_value("transmission_nopag") is AxisCalculationInput.transmission ) assert ( AxisCalculationInput.from_value("transmission") is AxisCalculationInput.transmission ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/tests/test_darkref.py0000644000175000017500000000212115153325210026176 0ustar00paynopayno# coding: utf-8 from __future__ import annotations from tomwer.core.process.reconstruction.darkref.darkrefs import ( requires_reduced_dark_and_flat, ) from tomwer.core.utils.scanutils import MockEDF, MockNXtomo def test_quick_run_necessary_edf(tmpdir): """test the `quick_run_necessary` function for EDFTomoScan""" scan = MockEDF.mockScan(scanID=str(tmpdir), start_dark=True, start_flat=True) assert scan.reduced_darks in (None, {}) assert scan.reduced_flats in (None, {}) requires_reduced_dark_and_flat(scan=scan) assert len(scan.reduced_darks) == 1 assert len(scan.reduced_flats) == 1 def test_quick_run_necessary_hdf5(tmpdir): """test the `quick_run_necessary` function for NXtomoScan""" scan = MockNXtomo( scan_path=tmpdir, n_proj=20, n_ini_proj=20, dim=10, ).scan assert scan.reduced_darks in (None, {}) assert scan.reduced_flats in (None, {}) computed = requires_reduced_dark_and_flat(scan=scan) assert len(computed) == 2 assert len(scan.reduced_darks) == 1 assert len(scan.reduced_flats) == 1 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/tests/test_darkref_copy.py0000644000175000017500000001416215153325210027240 0ustar00paynopaynoimport os import numpy import pytest from silx.io.dictdump import dicttoh5 from tomwer.core.process.reconstruction.darkref.darkrefscopy import DarkRefsCopy from tomwer.core.utils.scanutils import MockNXtomo @pytest.mark.parametrize( "process_only_copy_scan_without_raw, process_only_dkrf_scan_without_raw", ((False, False), (True, False), (False, True), (True, True)), ) @pytest.mark.parametrize( "process_only_copy_scan_with_raw, process_only_dkrf_scan_with_raw", ((False, False), (True, False), (False, True), (True, True)), ) def test_register_and_copy_darks_and_flats( tmp_path, process_only_copy_scan_with_raw, process_only_dkrf_scan_with_raw, process_only_copy_scan_without_raw, process_only_dkrf_scan_without_raw, ): """ Test registration and copy of darks and flats """ scan_folder_with_raw = tmp_path / "test_dir_1" scan_folder_without_raw = tmp_path / "test_dir_2" save_dir = tmp_path / "save_dir" for my_dir in (save_dir, scan_folder_with_raw, scan_folder_without_raw): os.makedirs(my_dir) scan_with_raw = MockNXtomo( scan_path=scan_folder_with_raw, create_ini_dark=True, create_ini_flat=True, create_final_flat=False, n_proj=10, n_ini_proj=10, dim=12, ).scan scan_without_raw = MockNXtomo( scan_path=scan_folder_without_raw, create_ini_dark=False, create_ini_flat=False, create_final_flat=False, n_proj=10, n_ini_proj=10, dim=12, ).scan # get task ready process_with_raw = DarkRefsCopy( inputs={ "data": scan_with_raw, "save_dir": save_dir, "process_only_copy": process_only_copy_scan_with_raw, "process_only_dkrf": process_only_dkrf_scan_with_raw, "serialize_output_data": False, } ) # test processing with flat and dark materials process_with_raw.run() if process_only_copy_scan_with_raw: assert scan_with_raw.load_reduced_darks() in (None, {}) assert scan_with_raw.load_reduced_flats() in (None, {}) else: assert scan_with_raw.load_reduced_darks() not in (None, {}) assert scan_with_raw.load_reduced_flats() not in (None, {}) # test processing without flat and dark materials (where copy can happen) process_without_raw = DarkRefsCopy( inputs={ "data": scan_without_raw, "save_dir": save_dir, "process_only_copy": process_only_copy_scan_without_raw, "process_only_dkrf": process_only_dkrf_scan_without_raw, "serialize_output_data": False, } ) process_without_raw.run() if process_only_copy_scan_with_raw or process_only_dkrf_scan_without_raw: assert scan_without_raw.load_reduced_darks() in (None, {}) assert scan_without_raw.load_reduced_flats() in (None, {}) elif process_only_dkrf_scan_without_raw: assert scan_without_raw.load_reduced_darks() not in (None, {}) assert scan_without_raw.load_reduced_flats() not in (None, {}) def test_save_reduced_frames_to_be_copied(tmp_path): """ test save_flats_to_be_copied and save_darks_to_be_copied functions """ # create raw data from silx.io.url import DataUrl from tomoscan.scanbase import ReducedFramesInfos raw_data = tmp_path / "raw_data" raw_data.mkdir() dark_file_path = os.path.join(raw_data, "darks.h5") darks_dict = { "0": numpy.linspace(0, 100, 10000).reshape(100, 100), ReducedFramesInfos.COUNT_TIME_KEY: numpy.array( [ 0.2, ] ), ReducedFramesInfos.MACHINE_ELECT_CURRENT_KEY: numpy.array( [ 12.2, ] ), ReducedFramesInfos.LR_FLIP: True, ReducedFramesInfos.UD_FLIP: True, } dicttoh5( darks_dict, h5file=dark_file_path, h5path="entry0000/darks", update_mode="modify", mode="a", ) flat_file_path = os.path.join(raw_data, "flats.hdf5") flats_dict = { "0": numpy.linspace(0, 100, 10000).reshape(100, 100), "200": numpy.ones((100, 100)).reshape(100, 100), ReducedFramesInfos.COUNT_TIME_KEY: numpy.array([0.2, 0.3]), ReducedFramesInfos.MACHINE_ELECT_CURRENT_KEY: numpy.array([12.2, 12.1]), ReducedFramesInfos.LR_FLIP: True, ReducedFramesInfos.UD_FLIP: True, } dicttoh5( flats_dict, h5file=flat_file_path, h5path="entry0000/flats", update_mode="modify", mode="a", ) raw_darks_url_1 = DataUrl( file_path=dark_file_path, data_path="entry0000", ) raw_darks_url_2 = DataUrl( file_path=dark_file_path, data_path="entry0000/darks", ) raw_darks_url_3 = DataUrl( file_path=dark_file_path, data_path="", ) assert ( DarkRefsCopy.get_reduced_frame_data( url=raw_darks_url_1, reduced_target="darks" ).keys() == darks_dict.keys() ) assert ( DarkRefsCopy.get_reduced_frame_data( url=raw_darks_url_2, reduced_target="darks" ).keys() == darks_dict.keys() ) assert ( DarkRefsCopy.get_reduced_frame_data( url=raw_darks_url_3, reduced_target="darks" ).keys() != darks_dict.keys() ) flat_darks_url_1 = DataUrl( file_path=flat_file_path, data_path="entry0000", ) flat_darks_url_2 = DataUrl( file_path=flat_file_path, data_path="entry0000/flats", ) flat_darks_url_3 = DataUrl( file_path=flat_file_path, data_path="", ) assert ( DarkRefsCopy.get_reduced_frame_data( url=flat_darks_url_1, reduced_target="flats" ).keys() == flats_dict.keys() ) assert ( DarkRefsCopy.get_reduced_frame_data( url=flat_darks_url_2, reduced_target="flats" ).keys() == flats_dict.keys() ) assert ( DarkRefsCopy.get_reduced_frame_data( url=flat_darks_url_3, reduced_target="flats" ).keys() != flats_dict.keys() ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/tests/test_params_cache.py0000644000175000017500000000232615153325210027175 0ustar00paynopaynoimport os from tomwer.core.process.reconstruction.params_cache import ( _CACHE, _CACHE_SIZE, save_reconstruction_parameters_to_cache, clear_reconstruction_parameters_cache, ) from tomwer.core.utils.scanutils import MockNXtomo def test_cache(tmp_path): nxtomos = [ MockNXtomo( scan_path=os.path.join(tmp_path, f"my_nxtomo_{i_scan}"), n_proj=10, ).scan for i_scan in range(31) ] new_nxtomo = MockNXtomo( scan_path=os.path.join(tmp_path, "my_nxtomo_99"), n_proj=10, ).scan clear_reconstruction_parameters_cache() # test saving it in the original order [save_reconstruction_parameters_to_cache(scan=scan) for scan in nxtomos] assert len(_CACHE) == _CACHE_SIZE assert _CACHE == { nxtomo.get_identifier().to_str(): (None, None) for nxtomo in nxtomos[1:] } # try updating the next last one to make sure it won't be removed save_reconstruction_parameters_to_cache(scan=nxtomos[1]) save_reconstruction_parameters_to_cache(scan=new_nxtomo) assert nxtomos[1].get_identifier().to_str() in _CACHE assert nxtomos[2].get_identifier().to_str() not in _CACHE clear_reconstruction_parameters_cache() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/tests/test_paramsbase.py0000644000175000017500000000274115153325210026706 0ustar00paynopaynoimport pytest from tomwer.core.process.reconstruction.axis.params import AxisRP from tomwer.core.process.reconstruction.darkref.params import DKRFRP from tomwer.core.process.reconstruction.paramsbase import _get_db_fromstr, _ReconsParam def test_paramsbase(): """ Test _ReconsParam class """ params = _ReconsParam() assert isinstance(params.all_params, list) def test_get_db_fromstr(): """ test '_get_db_fromstr' function """ assert _get_db_fromstr(vals="12") == 12.0 assert _get_db_fromstr(vals="12.0") == 12.0 assert _get_db_fromstr(vals="(12.0, )") == 12.0 assert _get_db_fromstr(vals="(12.0, 13.5)") == (12.0, 13.5) assert _get_db_fromstr(vals="[12.0, 13.5]") == (12.0, 13.5) def test_basic_DKRFRP(): """ dummy test for DKRFRP """ recons_params = DKRFRP() ddict = recons_params.to_dict() DKRFRP.from_dict(ddict) assert isinstance( recons_params.to_unique_recons_set(), tuple, ) @pytest.mark.parametrize("param_klass", [DKRFRP, AxisRP]) def test_ReconsParams_from_dict(param_klass): """ Test from_dict with upper and lower case keys """ ref_dict = param_klass().to_dict() # Default case (upper) result = param_klass.from_dict(ref_dict.copy()) assert result.to_dict() == ref_dict # Lower case lower_dict = {key.lower(): value for key, value in ref_dict.items()} result = param_klass.from_dict(lower_dict.copy()) assert result.to_dict() == ref_dict ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/tests/test_saaxis.py0000644000175000017500000000462115153325210026057 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import pytest import numpy from tomwer.core.process.reconstruction.saaxis.params import SAAxisParams from tomwer.core.process.reconstruction.saaxis.saaxis import SAAxisTask from tomwer.core.process.reconstruction.scores.scores import ( _METHOD_TO_FCT, compute_score_contrast_std, ) from tomwer.core.utils.scanutils import MockNXtomo def test_img_contrast_std_score(): """simple test of the API to call compute_score_contrast_std""" data = numpy.random.random(100 * 100).reshape(100, 100) compute_score_contrast_std(data) @pytest.mark.parametrize("fct", _METHOD_TO_FCT.values()) def test_method_to_function(fct): """Test the dictionary used to for linking the score method to the callback function""" data = numpy.random.random(100 * 100).reshape(100, 100) res = fct(data) assert res is not None assert isinstance(res, float) def testSAAxisProcess(tmp_path): """Test the SAAxisProcess class""" scan_path = tmp_path / "mock_nxtomo" scan_path.mkdir() # set up dim = 10 mock = MockNXtomo( scan_path=scan_path, n_proj=10, n_ini_proj=10, scan_range=180, dim=dim ) mock.add_alignment_radio(index=10, angle=90) mock.add_alignment_radio(index=10, angle=0) scan = mock.scan default_saaxis_params = SAAxisParams() default_saaxis_params.output_dir = os.path.join(scan_path, "output_dir") default_saaxis_params.slice_indexes = {"slice": 4} default_saaxis_params.nabu_config = {} default_saaxis_params.dry_run = True default_saaxis_params.file_format = "hdf5" # test processing process = SAAxisTask( inputs={ "data": scan, "sa_axis_params": default_saaxis_params.to_dict(), "serialize_output_data": False, "dry_run": True, } ) default_saaxis_params.estimated_cor = 11 default_saaxis_params.research_width = 2 process = SAAxisTask( inputs={ "data": scan, "sa_axis_params": default_saaxis_params.to_dict(), "serialize_output_data": False, "dry_run": True, }, ) process.run() process = SAAxisTask( inputs={ "data": scan, "sa_axis_params": default_saaxis_params.to_dict(), "serialize_output_data": False, "dry_run": True, }, ) process.run() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/tests/test_sadeltabeta.py0000644000175000017500000000232015153325210027032 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import shutil import tempfile import unittest from tomwer.core.process.reconstruction.sadeltabeta.sadeltabeta import ( SADeltaBetaParams, SADeltaBetaTask, ) from tomwer.core.utils.scanutils import MockNXtomo class TestSADeltaBetaProcess(unittest.TestCase): """Test the SAAxisProcess class""" def setUp(self) -> None: super().setUp() self.tempdir = tempfile.mkdtemp() dim = 10 mock = MockNXtomo( scan_path=self.tempdir, n_proj=10, n_ini_proj=10, scan_range=180, dim=dim ) self.scan = mock.scan def tearDown(self) -> None: shutil.rmtree(self.tempdir) super().tearDown() def test(self): process = SADeltaBetaTask( inputs={ "data": self.scan, "sa_delta_beta_params": SADeltaBetaParams().to_dict(), "serialize_output_data": False, } ) default_sadelta_beta_params = SADeltaBetaParams() default_sadelta_beta_params.output_dir = os.path.join( self.tempdir, "output_dir" ) default_sadelta_beta_params.dry_run = True process.run() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/tests/test_utils.py0000644000175000017500000000175615153325210025735 0ustar00paynopaynoimport numpy from tomwer.core.process.reconstruction.utils.cor import ( absolute_pos_to_relative, relative_pos_to_absolute, ) def test_cor_conversion(): """ test absolute_pos_to_relative and relative_pos_to_absolute functions """ assert relative_pos_to_absolute(relative_pos=0.0, det_width=100) == 50.0 assert relative_pos_to_absolute(relative_pos=0.0, det_width=101) == 50.5 assert absolute_pos_to_relative(absolute_pos=20, det_width=500) == -230.0 assert absolute_pos_to_relative(absolute_pos=300, det_width=500) == 50.0 for det_width in (10, 20, 30, 50): for relative_cor_pos in (0, -2.3, -4.5): numpy.testing.assert_almost_equal( relative_cor_pos, absolute_pos_to_relative( absolute_pos=relative_pos_to_absolute( relative_pos=relative_cor_pos, det_width=det_width ), det_width=det_width, ), ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9251013 tomwer-1.6.17/src/tomwer/core/process/reconstruction/utils/0000755000175000017500000000000015153325403023155 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/utils/__init__.py0000644000175000017500000000000015153325210025250 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/reconstruction/utils/cor.py0000644000175000017500000000102415153325210024303 0ustar00paynopaynodef relative_pos_to_absolute(relative_pos: float, det_width: int): """ Convert relative center of rotation to absolute. """ # Compute the midpoint differently for even and odd widths midpoint = det_width / 2.0 return relative_pos + midpoint def absolute_pos_to_relative(absolute_pos: float, det_width: int): """ Convert absolute center of rotation to relative. """ # Compute the midpoint differently for even and odd widths midpoint = det_width / 2.0 return absolute_pos - midpoint ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9251013 tomwer-1.6.17/src/tomwer/core/process/script/0000755000175000017500000000000015153325403020240 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/script/__init__.py0000644000175000017500000000000015153325210022333 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/script/python.py0000644000175000017500000000403215153325210022126 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import code import logging import tomwer.version from tomwer.core.process.task import Task from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils.scanutils import data_identifier_to_scan from tomwer.core.utils.volumeutils import volume_identifier_to_volume _logger = logging.getLogger(__name__) class PythonScript( Task, optional_input_names=("data", "volume", "serialize_output_data"), output_names=("data", "volume"), ): def run(self): # load data scan = data_identifier_to_scan(self.inputs.data) if isinstance(scan, dict): scan = ScanFactory.create_scan_object_frm_dict(scan) elif isinstance(scan, (TomwerScanBase, type(None))): scan = scan else: raise ValueError(f"input type of {scan}: {type(scan)} is not managed") # load volume volume = volume_identifier_to_volume(self.inputs.volume) cfg = self.get_configuration() interpreter = code.InteractiveConsole(locals={"in_data": scan}) interpreter = code.InteractiveConsole(locals={"in_volume": volume}) interpreter.runcode(cfg["scriptText"]) out_data = data_identifier_to_scan(interpreter.locals.get("out_data")) out_volume = data_identifier_to_scan(interpreter.locals.get("out_volume")) if out_data is not None and self.get_input_value("serialize_output_data", True): self.outputs.data = out_data.to_dict() else: self.outputs.data = out_data self.outputs.volume = out_volume @staticmethod def program_name(): """Name of the program used for this processing""" return "Python script" @staticmethod def program_version(): """version of the program used for this processing""" return tomwer.version.version @staticmethod def definition(): """definition of the process""" return "Execute some random python code" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9251013 tomwer-1.6.17/src/tomwer/core/process/script/tests/0000755000175000017500000000000015153325403021402 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/script/tests/test_script.py0000644000175000017500000000200015153325210024303 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import shutil import tempfile import unittest from tomwer.core.process.script.python import PythonScript from tomwer.core.utils.scanutils import MockNXtomo class TestPythonScript(unittest.TestCase): def setUp(self): self.tempdir = tempfile.mkdtemp() dim = 10 mock = MockNXtomo( scan_path=os.path.join(self.tempdir, "scan1"), n_proj=10, n_ini_proj=10, scan_range=180, dim=dim, ) self.scan = mock.scan def tearDown(self): shutil.rmtree(self.tempdir) def test(self): process = PythonScript(inputs={"data": self.scan}) process.definition() process.program_version() process.program_name() # TODO: configuration should be passed in inputs during construction process.set_configuration( { "scriptText": "print('toto')", } ) process.run() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9251013 tomwer-1.6.17/src/tomwer/core/process/stitching/0000755000175000017500000000000015153325403020730 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/stitching/__init__.py0000644000175000017500000000000015153325210023023 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/stitching/metadataholder.py0000644000175000017500000001503215153325210024255 0ustar00paynopaynofrom __future__ import annotations import weakref import logging import numpy from tomoscan.tomoobject import TomoObject from tomoscan.scanbase import TomoScanBase from tomoscan.volumebase import VolumeBase _logger = logging.getLogger(__name__) class StitchingMetadata: """ overload of a TomoObject to register metadata set by the user on positions """ KEY_PIXEL_OR_VOXEL_SIZE = "pixel_or_voxel_size" KEY_PIXEL_POSITION = "position_px" KEY_METRIC_POSITION = "position_m" def __init__(self, tomo_obj) -> None: super().__init__() if tomo_obj is None: self._tomo_obj = None else: self._tomo_obj = weakref.ref(tomo_obj) self._pixel_or_voxel_size = [None, None, None] self._pos_as_px = [None, None, None] self._pos_as_m = [None, None, None] @property def tomo_obj(self) -> TomoObject: if self._tomo_obj is None: return None else: return self._tomo_obj() def setPixelOrVoxelSize(self, value, axis): if value is not None and not isinstance( value, (float, numpy.float32, numpy.float64) ): raise TypeError(f"Invalid type for value. Got {type(value)}") self._pixel_or_voxel_size[axis] = value def setPxPos(self, value, axis): if value is not None and not isinstance(value, (int, numpy.int32)): raise TypeError(f"Invalid type for value. Got {type(value)}") self._pos_as_px[axis] = value def setMetricPos(self, value, axis): if value is not None and not isinstance( value, (int, numpy.float32, numpy.float64, float) ): raise TypeError(f"Invalid type for value. Got {type(value)}") self._pos_as_m[axis] = value def get_raw_position_m(self, axis): if self.tomo_obj is None: return bb = self.tomo_obj.get_bounding_box(axis) return (bb.max - bb.min) / 2 + bb.min def get_abs_position_px(self, axis, warn=True) -> int | None: if axis not in (0, 1, 2): raise ValueError("axis is expected to be in (0, 1, 2)") # if user registered position as pixels if self._pos_as_px[axis] is not None: return int(self._pos_as_px[axis]) else: # get position as m from the user input pos_as_m = self._pos_as_m[axis] # or from metadata if not provided if pos_as_m is None: try: pos_as_m = self.get_raw_position_m(axis=axis) except Exception as e: if warn: _logger.warning( f"Fail to get bounding box of {self.tomo_obj}. Error is {e}" ) return None # else if user registered position as meter pixel_or_voxel_size = self.get_pixel_or_voxel_size(axis=axis) if pixel_or_voxel_size is None: if warn: if isinstance(self.tomo_obj, TomoScanBase): missing = "pixel" else: missing = "voxel" _logger.warning( f"Unable to get {missing} from {self.tomo_obj}. Please provide it manually" ) return None else: return int(pos_as_m / pixel_or_voxel_size) def reset(self): self._pixel_or_voxel_size = [None, None, None] self._pos_as_px = [None, None, None] self._pos_as_m = [None, None, None] def get_pixel_or_voxel_size(self, axis) -> float | None: """ return value provided by the user if any else return the value contained in metadata """ if self.tomo_obj is None: return if self._pixel_or_voxel_size[axis] is not None: return self._pixel_or_voxel_size[axis] elif isinstance(self.tomo_obj, TomoScanBase): if axis == 0: return self.tomo_obj.sample_y_pixel_size elif axis in (1, 2): return self.tomo_obj.sample_x_pixel_size else: raise TypeError(f"axis is expected to be in (0, 1, 2). {axis} provided") elif isinstance(self.tomo_obj, VolumeBase): voxel_size = self.tomo_obj.voxel_size if voxel_size is None: return None else: return voxel_size[axis] else: raise NotImplementedError def to_dict(self) -> dict: def cast_values(values): return ",".join(["" if val is None else str(val) for val in values]) return { self.KEY_PIXEL_OR_VOXEL_SIZE: cast_values(self._pixel_or_voxel_size), self.KEY_PIXEL_POSITION: cast_values(self._pos_as_px), self.KEY_METRIC_POSITION: cast_values(self._pos_as_m), } @staticmethod def from_dict(ddict, tomo_obj): res = StitchingMetadata(tomo_obj=tomo_obj) res.load_from_dict(ddict) return res def load_from_dict(self, ddict) -> dict: def cast_str(my_str: str, expected_type): return list( [ None if part_ == "" else expected_type(part_) for part_ in my_str.split(",") ] ) if self.KEY_METRIC_POSITION in ddict: self._pos_as_m = cast_str( ddict[self.KEY_METRIC_POSITION], expected_type=float ) if self.KEY_PIXEL_POSITION in ddict: self._pos_as_px = cast_str( ddict[self.KEY_PIXEL_POSITION], expected_type=int ) if self.KEY_PIXEL_OR_VOXEL_SIZE in ddict: self._pixel_or_voxel_size = cast_str( ddict[self.KEY_PIXEL_OR_VOXEL_SIZE], expected_type=float ) def __eq__(self, __o: object) -> bool: return ( self._pixel_or_voxel_size == __o._pixel_or_voxel_size and self._pos_as_px == __o._pos_as_px and self._pos_as_m == __o._pos_as_m ) def __str__(self) -> str: metadatas = { "pixel_or_voxel_size": self._pixel_or_voxel_size, "metric position (m)": self._pos_as_m, "pixel position (px)": self._pos_as_px, } metadata_str = "\n -".join( [f"{key}: {value}" for key, value in metadatas.items()] ) tomo_obj = self.tomo_obj or "?" return ( f"user override stitching metadata for {tomo_obj} metadata: \n" + metadata_str ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/stitching/nabustitcher.py0000644000175000017500000001623615153325210024001 0ustar00paynopaynoimport logging from tqdm import tqdm from ewokscore.missing_data import is_missing_data from sluurp.executor import submit as submit_to_slurm_cluster from nabu.stitching.config import ( dict_to_config_obj, PreProcessedZStitchingConfiguration, PostProcessedZStitchingConfiguration, SlurmConfig, StitchingConfiguration, StitchingType, ) from nabu.stitching.z_stitching import z_stitching from nabu.stitching.y_stitching import y_stitching from nabu.stitching.utils.post_processing import ( StitchingPostProcAggregation as _StitchingPostProcAggregation, ) from nabu.stitching.slurm_utils import split_stitching_configuration_to_slurm_job from processview.core.superviseprocess import SuperviseProcess from tomwer.core.process.task import Task from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.volume.volumefactory import VolumeFactory _logger = logging.getLogger(__name__) class StitcherTask( Task, SuperviseProcess, input_names=("stitching_config",), optional_input_names=( "cluster_config", "progress", "serialize_output_data", ), output_names=( "data", "future_tomo_obj", "volume", ), ): def __init__(self, process_id=None, *args, **kwargs): SuperviseProcess.__init__(self, process_id=process_id) super().__init__(*args, **kwargs) def run(self): cluster_config = self.inputs.cluster_config assert cluster_config is None or isinstance(cluster_config, dict) stitching_config = self.inputs.stitching_config assert isinstance(stitching_config, dict) config = dict_to_config_obj(stitching_config) config.slurm_config = SlurmConfig.from_dict(cluster_config) if cluster_config in ({}, None): # opt1: run locally config.slurm_config = SlurmConfig.from_dict(cluster_config) progress = ( None if is_missing_data(self.inputs.progress) else self.inputs.progress ) if config.stitching_type in ( StitchingType.Z_PREPROC, StitchingType.Y_PREPROC, ): if config.stitching_type is StitchingType.Z_PREPROC: stitched_identifier = z_stitching( configuration=config, progress=progress ) else: stitched_identifier = y_stitching( configuration=config, progress=progress ) nx_tomo = ScanFactory.create_tomo_object_from_identifier( stitched_identifier.to_str() ) if self.get_input_value("serialize_output_data", True): self.outputs.data = nx_tomo.to_dict() else: self.outputs.data = nx_tomo self.outputs.volume = None self.outputs.future_tomo_obj = None elif config.stitching_type is StitchingType.Z_POSTPROC: stitched_identifier = z_stitching( configuration=config, progress=progress ) volume = VolumeFactory.create_tomo_object_from_identifier( stitched_identifier.to_str() ) self.outputs.volume = volume self.outputs.data = None self.outputs.future_tomo_obj = None else: raise NotImplementedError() else: # opt2: run remotely and aggregate locally futures = {} # 2.1 launch jobs # TODO: refactor: nabu.app.stitching could be called or something like that... slurm_job_progress_bars: dict = {} for i_job, (job, sub_config) in enumerate( split_stitching_configuration_to_slurm_job( config, yield_configuration=True ) ): _logger.info(f"submit job nb {i_job}: handles {sub_config.slices}") output_tomo_obj = ( sub_config.get_output_object().get_identifier().to_str() ) futures[output_tomo_obj] = submit_to_slurm_cluster(job, timeout=999999) # note on total=100: we only consider percentage in this case (providing advancement from slurm jobs) slurm_job_progress_bars[job] = tqdm( total=100, position=i_job + 1, desc=f" part {str(i_job).ljust(3)}", delay=0.5, # avoid to mess with terminal and (near) future logs bar_format="{l_bar}{bar}", # avoid using 'r_bar' as 'total' is set to 100 (percentage) leave=False, ) # handle post processing data_aggregation = StitchingPostProcAggregation( futures=futures, stitching_config=config, progress_bars=slurm_job_progress_bars, ) # will wait and provide feedback until the stitching is completed. data_aggregation.process() if config.stitching_type is StitchingType.Z_PREPROC: output_nx_tomo_file = config.output_file_path output_nx_tomo_entry = config.output_data_path self.outputs.data = NXtomoScan( scan=output_nx_tomo_file, entry=output_nx_tomo_entry ) self.outputs.future_tomo_obj = None self.outputs.volume = None elif config.stitching_type is StitchingType.Z_POSTPROC: tomwer_volume = VolumeFactory.create_tomo_object_from_identifier( config.output_volume.get_identifier().to_str() ) self.outputs.future_tomo_obj = None self.outputs.volume = tomwer_volume self.outputs.data = None class StitchingPostProcAggregation(_StitchingPostProcAggregation): """ once stitching is done remotly we need to 'aggregate' the different part in the correct order """ def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) if isinstance(self.stitching_config, dict): stitching_type = StitchingType(self.stitching_config["stitching"]["type"]) if stitching_type is StitchingType.Z_PREPROC: self._stitching_config = PreProcessedZStitchingConfiguration.from_dict( self.stitching_config ) elif stitching_type is StitchingType.Z_POSTPROC: self._stitching_config = PostProcessedZStitchingConfiguration.from_dict( self.stitching_config ) else: raise NotImplementedError("stitching type not handled") elif not isinstance(self.stitching_config, StitchingConfiguration): raise TypeError( f"stitching_config is expected to be an instance of {StitchingConfiguration}. {type(self.stitching_config)} provided instead" ) def process(self): super().process() _logger.info("Stitching finished.") ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9251013 tomwer-1.6.17/src/tomwer/core/process/stitching/tests/0000755000175000017500000000000015153325403022072 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/stitching/tests/test_metadataholder.py0000644000175000017500000000116715153325210026462 0ustar00paynopaynofrom tomwer.core.process.stitching.metadataholder import StitchingMetadata def test_to_dict_from_dict(): """Test conversion of StitchingMetadata from dict and to dict""" metadata = StitchingMetadata(tomo_obj=None) metadata._pixel_or_voxel_size = [12.3, 2.5, None] metadata._pos_as_m = [None, 3.6, None] metadata._pos_as_px = [5, 9, 8] ddict = metadata.to_dict() assert isinstance(ddict, dict) loaded_metadata = StitchingMetadata.from_dict(ddict, tomo_obj=None) assert loaded_metadata == metadata assert loaded_metadata.to_dict() == ddict assert isinstance(str(loaded_metadata), str) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/task.py0000644000175000017500000000652215153325210020251 0ustar00paynopayno""" Define the tomwer Task class. Insure connection with ewoks. All instances of tomwer Tasks should avoid gui import (as qt). """ from __future__ import annotations import logging from collections import namedtuple from ewokscore.task import Task as _EwoksTask from ewokscore.taskwithprogress import TaskWithProgress as _EwoksTaskWithProgress _logger = logging.getLogger(__name__) _process_desc = namedtuple( "_process_desc", ["process_order", "configuration", "results"] ) class BaseProcessInfo: """Tomwer base process class""" def __init__(self, inputs=None): """ :param return_dict: if True serialize (to_dict / from_dict functions) between each task """ self._scheme_title = ( "scheme_title" # TODO: have a look, this must be get somewhere and reused ? ) """should the return type of the handler should be TomoBase instance objects or dict""" self._settings = {} self._cancelled = False # a useful variable that can be set to True if the task has been cancelled @staticmethod def properties_help(): """ :return: display the list of all managed keys and possible values """ # TODO: use argsparse instead of this dict ? raise NotImplementedError("BaseProcess is an abstract class") @staticmethod def program_name(): """Name of the program used for this processing""" raise NotImplementedError("Base class") @staticmethod def program_version(): """version of the program used for this processing""" raise NotImplementedError("Base class") @staticmethod def definition(): """definition of the process""" raise NotImplementedError("Base class") def get_configuration(self) -> dict | None: """ :return: configuration of the process """ if self._settings is None: return None if len(self._settings) > 0: return self._settings else: return None def set_configuration(self, configuration: dict) -> None: self._settings = configuration class TaskWithProgress(_EwoksTaskWithProgress, BaseProcessInfo): """Class from which all tomwer process should inherit :param logger: the logger used by the class """ def __init__( self, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None, progress=None, ): BaseProcessInfo.__init__(self, inputs=inputs) _EwoksTaskWithProgress.__init__( self, varinfo=varinfo, inputs=inputs, node_id=node_id, node_attrs=node_attrs, execinfo=execinfo, progress=progress, ) class Task(_EwoksTask, BaseProcessInfo): """Class from which all tomwer process should inherit :param logger: the logger used by the class """ def __init__( self, varinfo=None, inputs=None, node_id=None, node_attrs=None, execinfo=None, ): BaseProcessInfo.__init__(self, inputs=inputs) _EwoksTask.__init__( self, varinfo=varinfo, inputs=inputs, node_id=node_id, node_attrs=node_attrs, execinfo=execinfo, ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9251013 tomwer-1.6.17/src/tomwer/core/process/tests/0000755000175000017500000000000015153325403020076 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/process/tests/__init__.py0000644000175000017500000000000014757047403022207 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/tests/test_conditions.py0000644000175000017500000000413415153325210023656 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import shutil import tempfile import unittest from tomwer.core.process.conditions.filters import ( FileNameFilterTask, RegularExpressionFilter, ) from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.utils.scanutils import MockEDF class TestConditionalFilter(unittest.TestCase): """ Small unit test for the core.conditions """ def testPattern1(self): filter_ = RegularExpressionFilter("name10") self.assertTrue(filter_.isFiltered("toto") is True) self.assertTrue(filter_.isFiltered("name10") is False) self.assertTrue(filter_.isFiltered("name100") is False) def testInputOutput(self): pass class TestConditionIO(unittest.TestCase): """Test inputs and outputs types of the handler functions""" def setUp(self): self.scan_folder = tempfile.mkdtemp() self.scan = MockEDF.mockScan( scanID=self.scan_folder, nRadio=10, nRecons=1, nPagRecons=4, dim=10 ) def tearDown(self): shutil.rmtree(self.scan_folder) def testInputOutput(self): for input_type in (dict, TomwerScanBase): for serialize_output_data in (True, False): with self.subTest( return_dict=serialize_output_data, input_type=input_type, ): input_obj = self.scan if input_type is dict: input_obj = self.scan.to_dict() filter_process = FileNameFilterTask( inputs={ "pattern": "*", "serialize_output_data": serialize_output_data, "data": input_obj, } ) filter_process.run() out = filter_process.outputs.data if serialize_output_data: self.assertTrue(isinstance(out, dict)) else: self.assertTrue(isinstance(out, TomwerScanBase)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/tests/test_dark_and_flat.py0000644000175000017500000003270515153325210024263 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import shutil import tempfile import unittest import numpy from tomoscan.esrf.scan.utils import get_data from tomwer.core.process.reconstruction.darkref.params import DKRFRP from tomwer.core.process.reconstruction.darkref.params import ReduceMethod as cMethod from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.utils.scanutils import MockEDF, MockNXtomo from tomwer.tests.datasets import TomwerCIDatasets from ..reconstruction.darkref.darkrefs import DarkRefsTask from ..reconstruction.darkref.darkrefscopy import DarkRefsCopy class TestDarkRefIO(unittest.TestCase): """Test inputs and outputs types of the handler functions""" def setUp(self): self.scan_folder = tempfile.mkdtemp() self.scan_edf = MockEDF.mockScan( scanID=self.scan_folder, nRadio=10, nRecons=1, nPagRecons=4, dim=10 ) self.mock_hdf5 = MockNXtomo( scan_path=self.scan_folder, n_proj=10, n_pag_recons=0 ) self.scan_hdf5 = self.mock_hdf5.scan self.recons_params = DKRFRP() def tearDown(self): shutil.rmtree(self.scan_folder) def testInputOutput(self): for scan, scan_type in zip( (self.scan_edf, self.scan_hdf5), ("edf scan", "hdf5 scan") ): for input_type in (dict, TomwerScanBase): for serialize_output_data in (True, False): with self.subTest( return_dict=serialize_output_data, input_type=input_type, scan_type=scan_type, ): input_obj = scan if input_obj is dict: input_obj = input_obj.to_dict() process = DarkRefsTask( inputs={ "dark_ref_params": self.recons_params, "data": input_obj, "serialize_output_data": serialize_output_data, } ) process.run() out = process.outputs.data if serialize_output_data: self.assertTrue(isinstance(out, dict)) else: self.assertTrue(isinstance(out, TomwerScanBase)) class TestDarkRefCopyIO(unittest.TestCase): """Test inputs and outputs types of the handler functions""" def setUp(self): self.scan_folder = tempfile.mkdtemp() self.scan_edf = MockEDF.mockScan( scanID=self.scan_folder, nRadio=10, nRecons=1, nPagRecons=4, dim=10 ) self.scan_hdf5 = MockNXtomo( scan_path=self.scan_folder, n_proj=10, n_pag_recons=0 ).scan self.recons_params = DKRFRP() self._save_dir = tempfile.mkdtemp() def tearDown(self): shutil.rmtree(self.scan_folder) def testInputOutput(self): for scan, scan_type in zip( (self.scan_edf, self.scan_hdf5), ("edf scan", "hdf5 scan") ): for input_type in (dict, TomwerScanBase): for serialize_output_data in (True, False): with self.subTest( return_dict=serialize_output_data, input_type=input_type, scan_type=scan_type, ): input_obj = scan if input_obj is dict: input_obj = input_obj.to_dict() dkrf_process = DarkRefsCopy( inputs={ "dark_ref_params": self.recons_params, "data": input_obj, "serialize_output_data": serialize_output_data, "save_dir": self._save_dir, } ) dkrf_process.run() out = dkrf_process.outputs.data if serialize_output_data: self.assertTrue(isinstance(out, dict)) else: self.assertTrue(isinstance(out, TomwerScanBase)) class TestDarkRefEdf(unittest.TestCase): """ Test dark ref is correctly processing with h5 refs """ def setUp(self) -> None: self.scan_folder = tempfile.mkdtemp() self.dark_data = numpy.array( # pylint: disable=E1121 numpy.random.random(4 * 200 * 200) * 100, dtype=numpy.uint16, ).reshape(4, 200, 200) self.flat_data = numpy.array( # pylint: disable=E1121 numpy.random.random(4 * 200 * 200) * 100, dtype=numpy.uint32, ).reshape(4, 200, 200) self.scan = MockEDF.mockScan( scanID=self.scan_folder, nRadio=10, nRecons=1, nPagRecons=4, dim=200, start_dark=True, start_flat=True, start_dark_data=self.dark_data, start_flat_data=self.flat_data, ) self.recons_params = DKRFRP() self.recons_params.overwrite_dark = True self.recons_params.overwrite_ref = True def tearDown(self) -> None: shutil.rmtree(self.scan_folder) def testDark(self): """ Test darks are computed when only dark are requested """ method_to_test = ( cMethod.MEDIAN, cMethod.MEAN, cMethod.FIRST, cMethod.LAST, ) th_results = ( numpy.median(self.dark_data, axis=0), numpy.mean(self.dark_data, axis=0), self.dark_data[0], self.dark_data[-1], ) for method, th_res in zip(method_to_test, th_results): with self.subTest(method=method): process = DarkRefsTask( inputs={ "dark_ref_params": self.recons_params, "data": self.scan, "serialize_output_data": False, } ) self.recons_params.dark_calc_method = method self.recons_params.flat_calc_method = cMethod.NONE process.run() numpy.testing.assert_array_almost_equal( self.scan.reduced_darks[0], th_res.astype(numpy.uint16) ) def testFlat(self): """ Test flats are computed when only flat are requested """ method_to_test = ( cMethod.MEDIAN, cMethod.MEAN, cMethod.FIRST, cMethod.LAST, ) th_results = ( numpy.median(self.flat_data, axis=0), numpy.mean(self.flat_data, axis=0), self.flat_data[0], self.flat_data[-1], ) for method, th_res in zip(method_to_test, th_results): with self.subTest(method=method): self.recons_params.dark_calc_method = cMethod.NONE self.recons_params.flat_calc_method = method process = DarkRefsTask( inputs={ "dark_ref_params": self.recons_params, "data": self.scan, "serialize_output_data": False, } ) process.run() numpy.testing.assert_array_almost_equal( self.scan.reduced_flats[0], th_res.astype(numpy.uint16) ) class TestDarkRefNx(unittest.TestCase): """ Test dark ref is correctly processing with h5 refs """ def setUp(self) -> None: super().setUp() dataset_name = "frm_edftomomill_twoentries.nx" self.scan_folder = tempfile.mkdtemp() self._file_path = os.path.join(self.scan_folder, dataset_name) shutil.copyfile( src=TomwerCIDatasets.get_dataset(f"h5_datasets/{dataset_name}"), dst=self._file_path, ) self.scan = NXtomoScan(scan=self._file_path, entry="entry0000") self.recons_params = DKRFRP() self.recons_params.overwrite_dark = True self.recons_params.overwrite_ref = True def tearDown(self) -> None: shutil.rmtree(self.scan_folder) super().tearDown() def testDark(self): """ Test darks are computed when only dark are requested """ darks = self.scan.darks self.assertEqual(len(darks), 1) method_to_test = (cMethod.MEAN, cMethod.MEDIAN, cMethod.FIRST, cMethod.LAST) for method in method_to_test: with self.subTest(method=method): self.recons_params.dark_calc_method = method self.recons_params.flat_calc_method = cMethod.NONE process = DarkRefsTask( inputs={ "dark_ref_params": self.recons_params, "data": self.scan, "serialize_output_data": False, } ) process.run() flats = self.scan.load_reduced_flats() self.assertEqual(len(flats), 0) darks = self.scan.load_reduced_darks() self.assertEqual(len(darks), 1) def testFlat(self): """ Test flats are computed when only flat are requested """ flats = self.scan.flats self.assertEqual(len(flats), 42) url_flat_serie_1 = [flats[index] for index in range(1, 22)] url_flat_serie_2 = [flats[index] for index in range(1521, 1542)] assert len(url_flat_serie_1) == 21 assert len(url_flat_serie_2) == 21 data_flat_serie_1 = [get_data(url) for url in url_flat_serie_1] data_flat_serie_2 = [get_data(url) for url in url_flat_serie_2] self.recons_params.overwrite_dark = True self.recons_params.overwrite_ref = True method_to_test = (cMethod.MEAN, cMethod.MEDIAN, cMethod.FIRST, cMethod.LAST) for method in method_to_test: with self.subTest(method=method): if method is cMethod.MEDIAN: expected_res_s1 = numpy.median(data_flat_serie_1, axis=0) expected_res_s2 = numpy.median(data_flat_serie_2, axis=0) elif method is cMethod.MEAN: expected_res_s1 = numpy.mean(data_flat_serie_1, axis=0) expected_res_s2 = numpy.mean(data_flat_serie_2, axis=0) elif method is cMethod.FIRST: expected_res_s1 = data_flat_serie_1[0] expected_res_s2 = data_flat_serie_2[0] elif method is cMethod.LAST: expected_res_s1 = data_flat_serie_1[-1] expected_res_s2 = data_flat_serie_2[-1] else: raise ValueError("method not managed") self.recons_params.dark_calc_method = cMethod.NONE self.recons_params.flat_calc_method = method process = DarkRefsTask( inputs={ "dark_ref_params": self.recons_params, "data": self.scan, "serialize_output_data": False, } ) process.run() darks = self.scan.load_reduced_darks() self.assertEqual(len(darks), 0) flats = self.scan.load_reduced_flats() self.assertEqual(len(flats), 2) self.assertTrue(1 in flats) self.assertTrue(1521 in flats) self.assertTrue(numpy.allclose(flats[1], expected_res_s1)) self.assertTrue(numpy.allclose(flats[1521], expected_res_s2)) def testDarkAndFlat(self): """ Test darks and flats are computed when both are requested """ flats = self.scan.flats self.assertEqual(len(flats), 42) url_flat_serie_1 = [flats[index] for index in range(1, 22)] url_flat_serie_2 = [flats[index] for index in range(1521, 1542)] assert len(url_flat_serie_1) == 21 assert len(url_flat_serie_2) == 21 data_flat_serie_1 = [get_data(url) for url in url_flat_serie_1] data_flat_serie_2 = [get_data(url) for url in url_flat_serie_2] self.recons_params.dark_calc_method = cMethod.MEAN self.recons_params.flat_calc_method = cMethod.MEDIAN darks = self.scan.darks self.assertEqual(len(darks), 1) dark_data = get_data(list(darks.values())[0]) expected_flats_s1 = numpy.median(data_flat_serie_1, axis=0) expected_flats_s2 = numpy.median(data_flat_serie_2, axis=0) process = DarkRefsTask( inputs={ "dark_ref_params": self.recons_params, "data": self.scan, "serialize_output_data": False, } ) process.run() darks = self.scan.load_reduced_darks() flats = self.scan.load_reduced_flats() self.assertEqual(len(darks), 1) self.assertEqual(len(flats), 2) self.assertTrue(0 in darks) self.assertTrue(1 in flats) self.assertTrue(1521 in flats) self.assertTrue(numpy.allclose(flats[1], expected_flats_s1)) self.assertTrue(numpy.allclose(flats[1521], expected_flats_s2)) self.assertTrue(numpy.allclose(darks[0], dark_data)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/tests/test_data_listener.py0000644000175000017500000000450515153325210024325 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import shutil import tempfile import unittest import h5py from tomwer.core.process.control.datalistener.rpcserver import _BaseDataListenerThread class JSONRPCClient: """Simulate call from bliss""" def scan_started(self, scan_number): return { "method": "scan_started", "params": [scan_number], "jsonrpc": "2.0", "id": 0, } def scan_ended(self, scan_number): return { "method": "scan_ended", "params": [scan_number], "jsonrpc": "2.0", "id": 1, } def sequence_started( self, saving_file, scan_title, sequence_scan_number, proposal_file, sample_file ): params = [ saving_file, scan_title, sequence_scan_number, proposal_file, sample_file, ] return { "method": "sequence_started", "params": params, "jsonrpc": "2.0", "id": 2, } def sequence_ended(self, saving_file, sequence_scan_number, success): return { "method": "sequence_ended", "params": [saving_file, sequence_scan_number, success], "jsonrpc": "2.0", "id": 3, } class TestJsonRPCServer(unittest.TestCase): """test the json rpc server""" def setUp(self): self.input_dir = tempfile.mkdtemp() sample_dir = os.path.join(self.input_dir, "sample") os.makedirs(sample_dir) self._proposal_file = os.path.join(sample_dir, "ihpayno_sample.h5") with h5py.File(self._proposal_file, mode="w") as h5f: h5f["test"] = "toto" os.makedirs(os.path.join(sample_dir, "sample_29042021")) self._sample_file = os.path.join( sample_dir, "sample_29042021", "sample_29042021.h5" ) self._sample_file_entry = "1.1" with h5py.File(self._sample_file, mode="w") as h5f: h5f[self._sample_file_entry] = "tata" self.data_listener = _BaseDataListenerThread(host="localhost", port=4000) def tearDown(self): shutil.rmtree(self.input_dir) self.data_listener.stop() def testStartStop(self): self.data_listener.start() self.data_listener.stop() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/tests/test_data_transfer.py0000644000175000017500000003327715153325210024334 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc import os import shutil import tempfile import time import unittest import h5py import numpy import pytest from nxtomomill.converter import from_h5_to_nx from nxtomomill.models.h52nx import H52nxModel from nxtomo.nxobject.nxdetector import ImageKey from silx.io.utils import open as open_hdf5 from tomoscan.io import HDF5File from tomoscan.validator import is_valid_for_reconstruction from tomwer.core.process.control.datalistener import DataListener from tomwer.core.process.control.scantransfer import ScanTransferTask from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.utils.scanutils import MockEDF from tomwer.synctools.rsyncmanager import RSyncManager from tomwer.tests.datasets import TomwerCIDatasets class TestDataTransferIO(unittest.TestCase): """Test inputs and outputs types of the handler functions""" def setUp(self): super().setUp() self._used_folders = [] self.origin_folder = None self.output_folder = None def tearDown(self): for folder in self._used_folders: shutil.rmtree(folder) super().tearDown() def testInputOutput(self): """Test that io using TomoBase instance work""" for input_type in (dict, TomwerScanBase): for serialize_output_data in (True, False): with self.subTest( return_dict=serialize_output_data, input_type=input_type, ): output_folder = tempfile.mkdtemp() origin_folder = tempfile.mkdtemp() scan_folder = os.path.join(origin_folder, "scan_toto") os.makedirs(scan_folder) os.makedirs(os.path.join(output_folder, "scan_toto")) self._used_folders.append(output_folder) self._used_folders.append(origin_folder) scan = MockEDF.mockScan( scanID=scan_folder, nRadio=10, nRecons=1, nPagRecons=4, dim=10, ) transfert_process = ScanTransferTask( inputs={ "data": scan, "dest_dir": output_folder, "serialize_output_data": serialize_output_data, } ) self.assertTrue(os.path.exists(output_folder)) input_obj = scan if input_obj is dict: input_obj = input_obj.to_dict() transfert_process.run() out = transfert_process.outputs.data if serialize_output_data: self.assertTrue(isinstance(out, dict)) else: self.assertTrue(isinstance(out, TomwerScanBase)) @pytest.mark.skipif(not RSyncManager().has_rsync(), reason="requires rsync") class TestBlissDataTransfer(unittest.TestCase): """Make sure we can transfer data from bliss acquisition""" def setUp(self): self.input_dir = tempfile.mkdtemp() self.output_dir = tempfile.mkdtemp() shutil.copytree( TomwerCIDatasets.get_dataset("bliss/sample"), os.path.join(self.input_dir, "sample"), ) self._proposal_file = os.path.join( self.input_dir, "sample", "ihpayno_sample.h5" ) self._sample_file = os.path.join( self.input_dir, "sample", "sample_29042021", "sample_29042021.h5" ) self._sample_file_entry = "1.1" assert os.path.exists(self._sample_file) # mock data listener: the processing of the Data transfer requires # knowledge of bliss files origin. self.assertTrue(os.path.exists(self._proposal_file)) data_listener = DataListener() scans = data_listener.process_sample_file( sample_file=self._sample_file, entry=self._sample_file_entry, proposal_file=self._proposal_file, master_sample_file=None, ) self.scan = scans[0] def tearDown(self): shutil.rmtree(self.input_dir) shutil.rmtree(self.output_dir) gc.collect() def testDataTransfer(self): """Make sure the data transfer is able to retrieve the scan, proposal file and scan file to transfer. Check that only the specific scan folders will be copy and removed and the other won't be affected. """ out_proposal = os.path.join(self.output_dir, "ihpayno_sample.h5") self.assertFalse(os.path.exists(out_proposal)) out_sample_file = os.path.join( self.output_dir, "sample_29042021", "sample_29042021.h5" ) self.assertFalse(os.path.exists(out_sample_file)) out_included_scans = [ os.path.join(self.output_dir, "sample_29042021", "scan0002") ] for scan_path in out_included_scans: self.assertFalse(os.path.exists(scan_path)) out_not_included_scans = [ os.path.join(self.output_dir, "sample_29042021", "scan0004"), os.path.join(self.output_dir, "sample_29042021", "scan0006"), os.path.join(self.output_dir, "sample_29042021", "scan0008"), ] for scan_path in out_not_included_scans: self.assertFalse(os.path.exists(scan_path)) process = ScanTransferTask( inputs={ "data": self.scan, "block": True, "dest_dir": self.output_dir, } ) process.run() time.sleep(1) self.assertTrue(os.path.exists(out_proposal), f"{out_proposal} does not exists") self.assertTrue( os.path.exists(out_sample_file), f"{out_sample_file} does not exists" ) for scan_path in out_included_scans: self.assertTrue(os.path.exists(scan_path)) for scan_path in out_not_included_scans: self.assertFalse(os.path.exists(scan_path)) # ensure we can convert it using nxtomomill once transferred output_file = out_sample_file.replace("29042021.h5", "29042021.nx") assert output_file != out_sample_file configuration = H52nxModel() configuration.input_file = out_sample_file configuration.output_file = output_file configuration.single_file = True configuration.file_extension = ".nx" from_h5_to_nx(configuration, input_callback=lambda *arg: 0) assert os.path.exists(output_file) assert is_valid_for_reconstruction(NXtomoScan(output_file, entry="entry0000")) @pytest.mark.skipif(not RSyncManager().has_rsync(), reason="requires rsync") class NXTomoDataTransferBase(unittest.TestCase): """Make sure we can transfer data from a NXtomo with linked dependancies""" def setUp(self) -> None: super().setUp() self._src_dir = tempfile.mkdtemp() self._dst_dir = tempfile.mkdtemp() def create_nexus_file(self, relative_links=True): dims = 100, 200 n_darks = 2 n_flats = 3 n_projections = 10 scans = { "scan0002": (ImageKey.DARK_FIELD, n_darks), "scan0003": (ImageKey.FLAT_FIELD, n_flats), "scan0004": (ImageKey.PROJECTION, n_projections), } self.nexus_file_path = os.path.join(self._src_dir, "my_acquisition.nx") sources = [] sources_len = [] image_keys = [] # create raw data for scan_name, (image_key, n_frames) in scans.items(): dir_path = os.path.join(self._src_dir, scan_name) os.makedirs(dir_path) file_path = os.path.join(dir_path, "pcolinux_0000.h5") with HDF5File(file_path, mode="w") as h5s: pcolinux_grp = h5s.require_group("entry0000/instrument/pcolinux") shape = (n_frames, dims[1], dims[0]) data = numpy.random.random(shape) data *= 100 pcolinux_grp["data"] = data.astype(dtype=numpy.uint16) # create a link tp measurement h5s["entry0000/measurement/data"] = h5py.SoftLink( "/".join(("/entry0000", "instrument", "pcolinux", "data")) ) vsource_path = os.path.join(scan_name, "pcolinux_0000.h5") if not relative_links: vsource_path = os.path.normpath( os.path.join(self._src_dir, vsource_path) ) sources.append( h5py.VirtualSource( vsource_path, name="entry0000/instrument/pcolinux/data", shape=shape, ) ) sources_len.append(n_frames) image_keys.extend([image_key.value] * n_frames) # create virtual dataset to the raw data with HDF5File(self.nexus_file_path, mode="w") as h5s: entry_node = h5s.require_group("entry0000") # write detector detector_node = entry_node.require_group("detector") shape = ( n_darks + n_flats + n_projections, dims[1], dims[0], ) layout = h5py.VirtualLayout(shape=shape, dtype=numpy.uint16) i_frame = 0 for v_source, v_source_length in zip(sources, sources_len): layout[i_frame : i_frame + v_source_length] = v_source i_frame += v_source_length n_frames = i_frame detector_node.create_virtual_dataset("data", layout, fillvalue=numpy.nan) detector_node["count_time"] = numpy.array([0.1] * n_frames) detector_node["distance"] = 0.17 detector_node["distance"].attrs["unit"] = "m" # write general information entry_node["definition"] = "NXtomo" entry_node["end_time"] = "2021-03-03T15:51:00.986554+01:00" entry_node["start_time"] = "2021-03-03T15:43:00.693382+01:00" entry_node["title"] = "0001" entry_node["field_of_view"] = "Half" entry_node["tomo_n"] = n_frames entry_node["x_pixel_size"] = 3.25e-7 entry_node["y_pixel_size"] = 3.25e-7 # write beam: add an absolute link for energy to ensure this is style valid and that relative files won't be moved file_with_energy = os.path.join(self._src_dir, "energy.h5") with HDF5File(file_with_energy, mode="w") as energy_file: energy_file["energy"] = 19 energy_file["energy"].attrs["unit"] = "keV" entry_node["instrument/beam/incident_energy"] = h5py.ExternalLink( file_with_energy, "/energy" ) entry_node["beam"] = h5py.SoftLink( "/".join(("/entry0000", "instrument", "beam")) ) # write sample sample_node = entry_node.require_group("sample") sample_node["name"] = "sample name" sample_node["image_key"] = numpy.array(image_keys) sample_node["image_key_control"] = numpy.array(image_keys) sample_node["rotation_angle"] = numpy.linspace(0, 360, n_frames) sample_node["x_translation"] = numpy.array([0.13] * n_frames) sample_node["y_translation"] = numpy.array([0.0063] * n_frames) sample_node["z_translation"] = numpy.array([0.6] * n_frames) def tearDown(self) -> None: shutil.rmtree(self._src_dir) shutil.rmtree(self._dst_dir) return super().tearDown() def _test(self): src_scan = NXtomoScan(self.nexus_file_path, entry="entry0000") assert is_valid_for_reconstruction(src_scan) process = ScanTransferTask( inputs={ "data": src_scan, "turn_off_print": True, "dest_dir": self._dst_dir, "block": True, "noRsync": False, } ) process.run() dst_scan = process.outputs.data assert dst_scan.master_file != self.nexus_file_path assert is_valid_for_reconstruction(dst_scan, check_values=True) with open_hdf5(src_scan.master_file) as h5s_src: src_dataset = h5s_src["entry0000/detector/data"][...] with open_hdf5(dst_scan.master_file) as h5s_dst: dst_dataset = h5s_dst["entry0000/detector/data"][...] assert numpy.array_equal(src_dataset, dst_dataset) @pytest.mark.skipif(not RSyncManager().has_rsync(), reason="requires rsync") class TestNXtomoTransferRelativeLink(NXTomoDataTransferBase): """Ensure NXtomo conversion will work if it contains relative links""" def setUp(self) -> None: super().setUp() self.create_nexus_file(relative_links=True) def test(self): super()._test() # make sure there is the .nx file there and the folder containing file linked the relative assert ( len( os.listdir(os.path.join(self._dst_dir, self._src_dir.split(os.sep)[-1])) ) == 4 ) @pytest.mark.skipif(not RSyncManager().has_rsync(), reason="requires rsync") class TestNXtomoTransferAbsoluteLink(NXTomoDataTransferBase): """Ensure NXtomo conversion will work if it contains absolute links""" def setUp(self) -> None: super().setUp() self.create_nexus_file(relative_links=False) def test(self): super()._test() # make sure there is only the .nx file there assert ( len( os.listdir(os.path.join(self._dst_dir, self._src_dir.split(os.sep)[-1])) ) == 1 ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/tests/test_data_watcher.py0000644000175000017500000000235615153325210024137 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import time import pytest from tomwer.core.process.control.datawatcher import DataWatcher from tomwer.core.process.control.datawatcher.status import DET_END_XML, PARSE_INFO_FILE from tomwer.core.utils.scanutils import MockEDF from tomwer.core.utils.threads import LoopThread @pytest.mark.skipif(os.name != "posix", reason="not tested under windows yet") @pytest.mark.parametrize("det_method", (PARSE_INFO_FILE, DET_END_XML)) def test_data_watcher_io(tmp_path, det_method): """Test inputs and outputs types of the handler functions""" scan_folder = tmp_path / "folder" / "my_scan" data_watcher_process = DataWatcher() data_watcher_process.setWaitTimeBtwLoop(1) data_watcher_process.setObsMethod(det_method) MockEDF.mockScan( scanID=str(scan_folder), nRadio=10, nRecons=1, nPagRecons=4, dim=10 ) data_watcher_process.setFolderObserved(str(tmp_path / "folder")) data_watcher_process.set_serialize_output_data(True) LoopThread.quitEvent.clear() data_watcher_process.start() time.sleep(0.5) data_watcher_process.stop() data_watcher_process.waitForObservationFinished() import gc gc.collect() LoopThread.quitEvent.clear() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989076.0 tomwer-1.6.17/src/tomwer/core/process/tests/test_nabu.py0000644000175000017500000004321515153325224022442 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import shutil import tempfile import unittest from glob import glob from tomwer.core.process.reconstruction.axis import AxisRP from tomwer.core.process.reconstruction.nabu import nabuslices as nabu from tomwer.core.process.reconstruction.nabu import settings as nabu_settings from tomwer.core.process.reconstruction.nabu.nabuslices import NabuSliceMode from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils.scanutils import MockEDF from tomwer.tests.datasets import TomwerCIDatasets class TestNabuDescUtils(unittest.TestCase): """Test the util function for creating the description of nabu""" def setUp(self): unittest.TestCase.setUp(self) self.top_dir = tempfile.mkdtemp() self.dataset = "scan_3_" data_test_dir = TomwerCIDatasets.get_dataset(f"edf_datasets/{self.dataset}") scan_folder = os.path.join(self.top_dir, self.dataset) shutil.copytree(data_test_dir, scan_folder) self.scan = ScanFactory.create_scan_object(scan_folder) def tearDown(self) -> None: shutil.rmtree(self.scan.path) def testDatasetDescriptor(self): self.scan.get_nabu_dataset_info() class TestNabuIni(unittest.TestCase): """Test creation of nabu .cfg files according to tomwer configuration""" def setUp(self) -> None: self.dataset = "scan_3_" self._root_dir = tempfile.mkdtemp() data_test_dir = TomwerCIDatasets.get_dataset("edf_datasets/scan_3_") scan_folder = os.path.join(self._root_dir, self.dataset) shutil.copytree(data_test_dir, scan_folder) self.scan = EDFTomoScan(scan_folder) self._nabu_cfg_folder = os.path.join( self.scan.path, nabu_settings.NABU_CFG_FILE_FOLDER ) [os.remove(cfg_file) for cfg_file in glob(self.scan.path + os.sep + "*.cfg")] if os.path.exists(self._nabu_cfg_folder): shutil.rmtree(self._nabu_cfg_folder) assert len(self.getNabuIniFiles()) == 0 # a random configuration self.config = get_nabu_default_config(output_dir=self.scan.path) def tearDown(self) -> None: shutil.rmtree(self._root_dir) def testNoSlices(self): """If no slices selected, in this case we will only create a .cfg for the volume """ self.config["tomwer_slices"] = None self.config["phase"]["method"] = "" self.assertEqual( len( nabu.interpret_tomwer_configuration(config=self.config, scan=self.scan) ), 1, ) nabu.run_slices_reconstruction(scan=self.scan, config=self.config, dry_run=True) nabu_files = self.getNabuIniFiles() self.assertEqual(len(nabu_files), 1) # check volume and slice .cfg files for nabu reconstruction are here ini_file = os.path.basename(self.scan.path) + ".cfg" ini_file = os.path.join(self._nabu_cfg_folder, ini_file) self.assertTrue(ini_file in nabu_files) def testSingleSlice(self): """Test the behavior if we only request one slice without Paganin""" self.config["tomwer_slices"] = "1" self.config["phase"]["method"] = "" self.assertEqual( len( nabu.interpret_tomwer_configuration(config=self.config, scan=self.scan) ), 2, ) nabu.run_slices_reconstruction(scan=self.scan, config=self.config, dry_run=True) nabu_files = self.getNabuIniFiles() self.assertEqual(len(nabu_files), 2) # check volume and slice .cfg files for nabu reconstruction are here for file_name in ( os.path.basename(self.scan.path) + ".cfg", os.path.basename(self.scan.path) + "slice_000001_plane_XY" + ".cfg", ): with self.subTest(file_name=file_name): self.assertTrue( os.path.join(self._nabu_cfg_folder, file_name) in nabu_files ) def testSinglePagSlice(self): """Test the behavior if we only request one Paganin slice""" self.config["phase"]["method"] = "Paganin" self.config["tomwer_slices"] = "1" self.config["phase"]["delta_beta"] = "100.0" self.assertEqual( len( nabu.interpret_tomwer_configuration(config=self.config, scan=self.scan) ), 2, ) nabu.run_slices_reconstruction(scan=self.scan, config=self.config, dry_run=True) nabu_files = self.getNabuIniFiles() self.assertEqual(len(nabu_files), 2) # check volume and slice .cfg files for nabu reconstruction are here for file_name in ( os.path.basename(self.scan.path) + "pag_db0100.cfg", os.path.basename(self.scan.path) + "slice_pag_000001_db0100_plane_XY" + ".cfg", ): with self.subTest(file_name=file_name): self.assertTrue( os.path.join(self._nabu_cfg_folder, file_name) in nabu_files ) def testSeveralSlices(self): """Test the behavior if we request several slices without Paganin""" slices = (1, 4, 12) self.config["tomwer_slices"] = str(slices) self.config["phase"]["method"] = "" self.assertEqual( len( nabu.interpret_tomwer_configuration(config=self.config, scan=self.scan) ), len(slices) + 1, ) nabu.run_slices_reconstruction(scan=self.scan, config=self.config, dry_run=True) nabu_files = self.getNabuIniFiles() self.assertEqual(len(nabu_files), len(slices) + 1) # check volume and slice .ini files for nabu reconstruction are here ini_files = [os.path.basename(self.scan.path) + ".cfg"] for slice_index in slices: ini_files.append( os.path.basename(self.scan.path) + "slice_" + str(slice_index).zfill(6) + "_plane_XY" + ".cfg" ) print("nabu_files are", nabu_files) for ini_file in ini_files: print("check ini_file", ini_file) with self.subTest(file_name=ini_file): self.assertTrue( os.path.join(self._nabu_cfg_folder, ini_file) in nabu_files ) def testSeveralPags(self): """behavior when several paganin slices are requested""" self.config["tomwer_slices"] = "1" self.config["phase"]["method"] = "Paganin" pag_dbs = [200.0, 300.0, 600.0, 700.0] self.config["phase"]["delta_beta"] = str(pag_dbs) sub_configs = nabu.interpret_tomwer_configuration( config=self.config, scan=self.scan ) self.assertEqual(len(sub_configs), len(pag_dbs) * 2) # check that each dbs and slices values are in sub configurations existing_dbs = [config[0]["phase"]["delta_beta"] for config in sub_configs] existing_dbs = set(existing_dbs) for pag_db in pag_dbs: with self.subTest(pag_db=pag_db): self.assertTrue(str(pag_db) in existing_dbs) nabu.run_slices_reconstruction(scan=self.scan, config=self.config, dry_run=True) nabu_files = self.getNabuIniFiles() self.assertEqual(len(nabu_files), len(pag_dbs) * 2) # check volume and slice .conf files for nabu reconstruction are here ini_files = [] for pag_db in pag_dbs: # add volume ini file ini_files.append( os.path.basename(self.scan.path) + "pag_db" + str(int(pag_db)).zfill(4) + ".cfg" ) # add slice ini file # note: plane is only specify for slice. ini_files.append( os.path.basename(self.scan.path) + "slice_pag_000001_db" + str(int(pag_db)).zfill(4) + "_plane_XY" + ".cfg" ) for ini_file in ini_files: with self.subTest(file_name=ini_file): self.assertTrue( os.path.join(self._nabu_cfg_folder, ini_file) in nabu_files ) def testSeveralPagsSeveralSlices(self): """behavior when several paganin slices are requested with several delta / beta values""" slices = (1, 4, 12) self.config["tomwer_slices"] = str(slices) self.config["phase"]["method"] = "Paganin" pag_dbs = [200, 300, 600, 700] self.config["phase"]["delta_beta"] = str(pag_dbs) self.assertEqual( len( nabu.interpret_tomwer_configuration(config=self.config, scan=self.scan) ), len(slices) * len(pag_dbs) + len(pag_dbs), ) nabu.run_slices_reconstruction(scan=self.scan, config=self.config, dry_run=True) nabu_files = self.getNabuIniFiles() self.assertEqual(len(nabu_files), len(slices) * len(pag_dbs) + len(pag_dbs)) # check volume and slice .cfg files for nabu reconstruction are here ini_files = [] for slice_index in slices: for pag_db in pag_dbs: # add volume ini file ini_files.append( os.path.basename(self.scan.path) + "pag_db" + str(pag_db).zfill(4) + ".cfg" ) # add slice ini file ini_files.append( os.path.basename(self.scan.path) + "slice_pag_" + str(slice_index).zfill(6) + "_db" + str(pag_db).zfill(4) + "_plane_XY" + ".cfg" ) for ini_file in ini_files: with self.subTest(file_name=ini_file): self.assertTrue( os.path.join(self._nabu_cfg_folder, ini_file) in nabu_files ) def getNabuIniFiles(self): return glob(self._nabu_cfg_folder + os.sep + "*.cfg") class TestTomwerConfForNabu(unittest.TestCase): """ Test the nabu configuration created from tomwer. Tomwer can request several slice or several paganin db values. We insure we can retrieve the correct nabu configuration for those note: the `_interpret_tomwer_configuration` function create each time a 'None' slice which is the reconstruction of the entire volume """ def setUp(self) -> None: self.scan = MockEDF.mockScan(scanID=tempfile.mkdtemp()) # initial configuration self.conf = {"reconstruction": {}} def tearDown(self) -> None: shutil.rmtree(self.scan.path) def testSlices(self): # check if single value for data_slice in ("1", NabuSliceMode.MIDDLE): with self.subTest(data_slice=data_slice): self.conf["tomwer_slices"] = data_slice sub_confs = nabu.interpret_tomwer_configuration( self.conf, scan=self.scan ) # not 1 because return each time the 'None' slice which is # the reconstruction of the entire volume self.assertEqual(len(sub_confs), 1 + 1) # check single values or list of values for data_slice in ("[2, 3, 7]", "(6, 9,56)", "5;6; 9"): with self.subTest(slice=data_slice): self.conf["tomwer_slices"] = data_slice sub_confs = nabu.interpret_tomwer_configuration( self.conf, scan=self.scan ) self.assertEqual(len(sub_confs), 3 + 1) # check from:to:step self.conf["tomwer_slices"] = "2:10:2" sub_confs = nabu.interpret_tomwer_configuration(self.conf, scan=self.scan) self.assertEqual(len(sub_confs), 5 + 1) def testPaganinDB(self): """Test that tomwer generate one configuration per paganin db""" self.conf["phase"] = {} # check if single value self.conf["phase"]["delta_beta"] = "100" sub_confs = nabu.interpret_tomwer_configuration(self.conf, scan=self.scan) # not 1 because return each time the 'None' slice which is # the reconstruction of the entire volume self.assertEqual(len(sub_confs), 1) # check single values or list of values for pag_db in ("[100, 200, ]", "(225, 230)", "5;6;"): with self.subTest(pag_db=pag_db): self.conf["phase"]["delta_beta"] = pag_db sub_confs = nabu.interpret_tomwer_configuration( self.conf, scan=self.scan ) self.assertEqual(len(sub_confs), 2) # check from:to:step self.conf["phase"]["delta_beta"] = "200:1000:100" sub_confs = nabu.interpret_tomwer_configuration(self.conf, scan=self.scan) self.assertEqual(len(sub_confs), 9) class TestNabuAndAxis(unittest.TestCase): """Test that nabu process and axis process are compatible""" def setUp(self) -> None: self.dataset = "scan_3_" self._root_dir = tempfile.mkdtemp() data_test_dir = TomwerCIDatasets.get_dataset("edf_datasets/scan_3_") scan_folder = os.path.join(self._root_dir, self.dataset) shutil.copytree(data_test_dir, scan_folder) self.scan = EDFTomoScan(scan_folder) [os.remove(cfg_file) for cfg_file in glob(self.scan.path + os.sep + "*.cfg")] # initial configuration self.conf = get_nabu_default_config(output_dir=self.scan.path) self.nabu_process = nabu.NabuSlicesTask( inputs={ "data": self.scan, "nabu_params": self.conf, "dry_run": True, "serialize_output_data": False, }, ) self.scan._axis_params = AxisRP() self.nabu_cfg_folder = os.path.join( self.scan.path, nabu_settings.NABU_CFG_FILE_FOLDER ) # make sure no .cfg files already exists assert len(glob(self.nabu_cfg_folder + os.sep + "*.cfg")) == 0 def tearDown(self) -> None: shutil.rmtree(self._root_dir) def test_output_dir(self): self.conf["output"]["location"] = "{scan_basename}/output" self.nabu_process.set_configuration(self.conf) output_dir = self.scan.scan_basename() + os.sep + "output" self.assertFalse(os.path.exists(output_dir)) self.nabu_process.run() self.assertTrue(os.path.exists(output_dir)) nabu_conf_files = glob( output_dir + os.sep + nabu_settings.NABU_CFG_FILE_FOLDER + os.sep + "*.cfg" ) self.assertEqual(len(nabu_conf_files), 1) def get_saved_rotation_axis(self, nabu_out_file): """return the saved value for 'rotation axis' in the nabu configuration file""" with open(nabu_out_file, "r") as nabu_file: lines = nabu_file for line in lines: if line.startswith("rotation_axis_position"): return line.replace("\n", "").replace(" ", "").split("=")[-1] return None def testNoCOR(self): """test if axis is executed and no COR are set, nabu won't mind""" self.scan._axis_params.set_relative_value(None) self.nabu_process.run() nabu_conf_files = glob(self.nabu_cfg_folder + os.sep + "*.cfg") self.assertEqual(len(nabu_conf_files), 1) nabu_rotation_axis_value = self.get_saved_rotation_axis(nabu_conf_files[0]) self.assertEqual(nabu_rotation_axis_value, "") def testCOR(self): """test that if cor is computed, cor will be registered for nabu""" self.scan._axis_params.set_relative_value(2.3) self.nabu_process.run() nabu_conf_files = glob(self.nabu_cfg_folder + os.sep + "*.cfg") self.assertEqual(len(nabu_conf_files), 1) nabu_rotation_axis_value = self.get_saved_rotation_axis(nabu_conf_files[0]) self.assertEqual( nabu_rotation_axis_value, str(self.scan._axis_params.relative_cor_value + (self.scan.dim_1 / 2.0)), ) def get_nabu_default_config(output_dir): """:return a default configuration for nabu""" return { "phase": { "padding_type": "edge", "method": "", "delta_beta": "100.0", "margin": 50, "unsharp_sigma": 0, "unsharp_coeff": 0, }, "preproc": { "ccd_filter_threshold": 0.04, "take_logarithm": True, "log_min_clip": 1e-06, "ccd_filter_enabled": 0, "log_max_clip": 10.0, "flatfield": 1, }, "dataset": { "job_name": "hair_A1_50nm_tomo3_1_", "location": "/tmp_14_days/payno/hair_A1_50nm_tomo3_1_", "flat_file_prefix": "refHST", "projections_subsampling": 1, "binning": 1, "dark_file_prefix": "dark.edf", "binning_z": 1, }, "reconstruction": { "positivity_constraint": 1, "start_z": 0, "end_y": -1, "optim_algorithm": "chambolle-pock", "enable_halftomo": 0, "end_z": -1, "iterations": 200, "start_x": 0, "fbp_filter_type": "ramlak", "angle_offset": 0.0, "end_x": -1, "method": "FBP", "angles_file": "", "rotation_axis_position": "", "start_y": 0, "preconditioning_filter": 1, "padding_type": "zeros", "regularization_weight": 0.01, "translation_movements_file": "", "axis_correction_file": "", }, "output": {"file_format": "hdf5", "location": output_dir}, } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/tests/test_normalization.py0000644000175000017500000000523715153325210024400 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import shutil import tempfile import unittest import h5py import numpy from tomoscan.normalization import Method from tomwer.core.process.reconstruction.normalization import normalization, params from tomwer.core.utils.scanutils import MockNXtomo class TestNormalization(unittest.TestCase): """ Test the normalization process """ def setUp(self) -> None: self.tempdir = tempfile.mkdtemp() dim = 100 self.scan = MockNXtomo( scan_path=self.tempdir, n_proj=2, n_ini_proj=2, scan_range=180, dim=dim, create_ini_dark=False, create_ini_flat=False, create_final_flat=False, ).scan def tearDown(self) -> None: shutil.rmtree(self.tempdir) def testManualROI(self): # step1: rewrite the detector data to simplify result check with h5py.File(self.scan.master_file, mode="a") as h5f: dataset = h5f["/entry/instrument/detector/data"] assert dataset.shape == (2, 100, 100) # pylint: disable=E1101 del h5f["/entry/instrument/detector/data"] h5f["/entry/instrument/detector/data"] = numpy.arange( 100 * 100 * 2 ).reshape(2, 100, 100) process_params = normalization.SinoNormalizationParams() process_params.method = Method.SUBTRACTION process_params.source = params._ValueSource.MANUAL_ROI expected_results = { "mean": numpy.array([800.5, 10800.5]), "median": numpy.array([800.5, 10800.5]), } for item in params._ValueCalculationFct: calc_fct = item.value with self.subTest(calc_fct=calc_fct): process_params.extra_infos = { "start_x": 0, "end_x": 2, "start_y": 8, "end_y": 9, "calc_fct": calc_fct, "calc_area": "volume", } process = normalization.SinoNormalizationTask( inputs={ "data": self.scan, "configuration": process_params, "serialize_output_data": False, } ) process.run() res = self.scan.intensity_normalization.get_extra_infos().get("value") if isinstance(res, numpy.ndarray): numpy.testing.assert_array_equal(res, expected_results[calc_fct]) else: numpy.testing.assert_array_equal(res, expected_results[calc_fct]) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/tests/test_timer.py0000644000175000017500000000325015153325210022623 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import shutil import tempfile import unittest from tomwer.core.process.control.timer import TimerTask from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.utils.scanutils import MockEDF class TestTimerIO(unittest.TestCase): """Test inputs and outputs types of the handler functions""" def setUp(self): self.scan_folder = tempfile.mkdtemp() self.scan = MockEDF.mockScan( scanID=self.scan_folder, nRadio=10, nRecons=1, nPagRecons=4, dim=10 ) def tearDown(self): shutil.rmtree(self.scan_folder) def testInputOutput(self): """Test that io using TomoBase instance work""" for input_type in (dict, TomwerScanBase): for serialize_output_data in (True, False): with self.subTest( return_dict=serialize_output_data, input_type=input_type, ): input_obj = self.scan if input_obj is dict: input_obj = input_obj.to_dict() timer_process = TimerTask( inputs={ "wait": 0.1, "serialize_output_data": serialize_output_data, "data": input_obj, } ) timer_process.run() out = timer_process.outputs.data if serialize_output_data: self.assertTrue(isinstance(out, dict)) else: self.assertTrue(isinstance(out, TomwerScanBase)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/utils.py0000644000175000017500000000511215153325210020441 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import datetime import logging from collections import OrderedDict import h5py from silx.io.url import DataUrl from silx.io.utils import h5py_read_dataset from tomwer.core.process.reconstruction.scores import ComputedScore from tomwer.core.scan.blissscan import BlissScan from tomwer.core.scan.scanbase import TomwerScanBase _logger = logging.getLogger(__name__) class LastReceivedScansDict(OrderedDict): """List the received scan from the first received to the last received""" def __init__(self, limit=None): """Simple structure in order to store the received last elements and the time of acquisition """ assert limit is None or (type(limit) is int and limit > 0) OrderedDict.__init__(self) self.limit = limit def add(self, scan): assert isinstance(scan, (TomwerScanBase, BlissScan)) self[str(scan)] = datetime.datetime.now() if self.limit is not None and len(self) > self.limit: self.pop(list(self.keys())[0]) class IgnoreProcess: """Simple util class to ignore a processing when using ewoks""" def process(self, scan): return scan __call__ = process def get_scores(node: h5py.Group) -> dict | None: """read all the score from the 'results' sub group. Read the url and computed scores :return: a dictionary with (url, ComputedScore) for each node """ if "results" not in node: _logger.warning(f"no results found in {node}") return None else: res_node = node["results"] scores = {} for res_item in res_node: score_node = res_node[res_item] try: float(res_item) except Exception: is_a_score = False else: is_a_score = True if not is_a_score: continue try: url = DataUrl( file_path=node.file.filename, data_path="/".join((score_node.name, "reconstructed_slice")), scheme="silx", ) score = ComputedScore( tv=h5py_read_dataset(score_node["total variation"]), std=h5py_read_dataset(score_node["standard deviation"]), ) scores[float(res_item)] = (url, score) except Exception as e: _logger.warning(f"Unable to load {score_node.name}. Reason is {e}") scores = dict(sorted(scores.items(), key=lambda item: item[0])) return scores ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9251013 tomwer-1.6.17/src/tomwer/core/process/visualization/0000755000175000017500000000000015153325403021635 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/visualization/__init__.py0000644000175000017500000000000015153325210023730 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/visualization/dataviewer.py0000644000175000017500000000051715153325210024341 0ustar00paynopayno# coding: utf-8 from __future__ import annotations from ewokscore.task import Task as EwoksTask class _DataViewerPlaceHolder(EwoksTask, input_names=("data",)): """ Task to browse a scan and associated processing (display raw frames, normalized projections, recosntructed slices...) """ def run(self): pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/visualization/diffviewer.py0000644000175000017500000000042115153325210024332 0ustar00paynopayno# coding: utf-8 from __future__ import annotations from ewokscore.task import Task as EwoksTask class _DiffViewerPlaceHolder(EwoksTask, input_names=("data",)): """ task to compare frames (between one or several dataset) """ def run(self): pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/visualization/imagestackviewer.py0000644000175000017500000000033515153325210025536 0ustar00paynopayno# coding: utf-8 from ewokscore.task import Task as EwoksTask class _ImageStackViewerPlaceHolder(EwoksTask, input_names=("data",)): """ Task to aggregate several images """ def run(self): pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/visualization/radiostack.py0000644000175000017500000000040315153325210024324 0ustar00paynopayno# coding: utf-8 from ewokscore.task import Task as EwoksTask class _RadioStackPlaceHolder(EwoksTask, input_names=("data",)): """ Task to aggregate radios of several scans and allow to browse along them all """ def run(self): pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/visualization/samplemoved.py0000644000175000017500000000036315153325210024521 0ustar00paynopayno# coding: utf-8 from ewokscore.task import Task as EwoksTask class _SampleMovedPlaceHolder(EwoksTask, input_names=("data",)): """ Task to check if a sample has moved along time / projections """ def run(self): pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/visualization/sinogramviewer.py0000644000175000017500000000032415153325210025243 0ustar00paynopayno# coding: utf-8 from ewokscore.task import Task as EwoksTask class _SinogramViewerPlaceHolder(EwoksTask, input_names=("data",)): """ Task to display a sinogram """ def run(self): pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/visualization/slicestack.py0000644000175000017500000000041315153325210024326 0ustar00paynopayno# coding: utf-8 from ewokscore.task import Task as EwoksTask class _SliceStackPlaceHolder(EwoksTask, input_names=("data",)): """ Task to aggregate reconstructed slices of several scans and allow users to along them """ def run(self): pass ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9251013 tomwer-1.6.17/src/tomwer/core/process/visualization/tests/0000755000175000017500000000000015153325403022777 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/visualization/tests/test_data_viewer.py0000644000175000017500000000035615153325210026702 0ustar00paynopayno# coding: utf-8 from tomwer.core.process.visualization.dataviewer import _DataViewerPlaceHolder def test_data_viewer(): process = _DataViewerPlaceHolder( inputs={ "data": None, } ) process.run() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/visualization/tests/test_diff_viewer.py0000644000175000017500000000035615153325210026701 0ustar00paynopayno# coding: utf-8 from tomwer.core.process.visualization.diffviewer import _DiffViewerPlaceHolder def test_diff_viewer(): process = _DiffViewerPlaceHolder( inputs={ "data": None, } ) process.run() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/visualization/tests/test_image_stack_viewer.py0000644000175000017500000000042015153325210030230 0ustar00paynopayno# coding: utf-8 from tomwer.core.process.visualization.imagestackviewer import ( _ImageStackViewerPlaceHolder, ) def test_image_stack_viewer(): process = _ImageStackViewerPlaceHolder( inputs={ "data": None, } ) process.run() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/visualization/tests/test_radio_stack.py0000644000175000017500000000035615153325210026673 0ustar00paynopayno# coding: utf-8 from tomwer.core.process.visualization.radiostack import _RadioStackPlaceHolder def test_radio_stack(): process = _RadioStackPlaceHolder( inputs={ "data": None, } ) process.run() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/visualization/tests/test_sample_moved.py0000644000175000017500000000041215153325210027054 0ustar00paynopayno# coding: utf-8 from tomwer.core.process.visualization.imagestackviewer import ( _ImageStackViewerPlaceHolder, ) def test_sample_moved(): process = _ImageStackViewerPlaceHolder( inputs={ "data": None, } ) process.run() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/visualization/tests/test_sinogram_viewer.py0000644000175000017500000000037715153325210027613 0ustar00paynopayno# coding: utf-8 from tomwer.core.process.visualization.sinogramviewer import _SinogramViewerPlaceHolder def test_sinogram_viewer(): process = _SinogramViewerPlaceHolder( inputs={ "data": None, } ) process.run() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/visualization/tests/test_slice_stack.py0000644000175000017500000000035715153325210026675 0ustar00paynopayno# coding: utf-8 from tomwer.core.process.visualization.slicestack import _SliceStackPlaceHolder def test_slice_stack(): process = _SliceStackPlaceHolder( inputs={ "data": None, } ) process.run() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/process/visualization/volumeviewer.py0000644000175000017500000000033415153325210024734 0ustar00paynopayno# coding: utf-8 from ewokscore.task import Task as EwoksTask class _VolumeViewerPlaceHolder(EwoksTask, input_names=("data",)): """ Task to plot a (reconstructed) volume """ def run(self): pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/core/resourcemanager.py0000644000175000017500000000205314764622416021025 0ustar00paynopaynoclass BaseResourceObserver: """base class of the resource observer""" def release_resource(self, resource): raise NotImplementedError("Base class") class _DummyResourceManager: """ Simple resource manager. It holds a set of observer tha must release a resource when requested Observers must implement the 'BaseResourceObserver' """ def __init__(self): self._observers = set() def register(self, observer): """Register a process to be notified when the resource should be released.""" if observer not in self._observers: self._observers.add(observer) def unregister(self, observer): """Unregister a process so it won't be notified anymore.""" if observer in self._observers: self._observers.remove(observer) def release_resource(self, resource: str): """Force all observer to release the given resource""" for observer in self._observers: observer.release_resource(resource) HDF5VolumeManager = _DummyResourceManager() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9251013 tomwer-1.6.17/src/tomwer/core/scan/0000755000175000017500000000000015153325403016202 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/scan/__init__.py0000644000175000017500000000027214757047403020326 0ustar00paynopayno# coding: utf-8 """contains scan classes and function. Abstraction layer for scans, based on tomoscan classes. See https://gitlab.esrf.fr/tomotools/tomoscan """ TYPES = ["EDF", "HDF5"] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/scan/blissscan.py0000644000175000017500000001536415153325210020542 0ustar00paynopaynofrom __future__ import annotations import logging import os import h5py from nxtomomill.settings import Tomo from silx.io.utils import h5py_read_dataset from silx.io.utils import open as open_hdf5 H5_INIT_TITLES = Tomo.H5.INIT_TITLES H5_ZSERIE_INIT_TITLES = Tomo.H5.ZSERIE_INIT_TITLES H5_PCOTOMO_INIT_TITLES = Tomo.H5.PCOTOMO_INIT_TITLES H5_BACK_AND_FORTH_INIT_TITLES = Tomo.H5.BACK_AND_FORTH_INIT_TITLES _logger = logging.getLogger(__name__) class BlissScan: """Simple class to define a Bliss sequence aka as Bliss scan inside tomwer. :warning: BlissScan is not compatible with tomwer treatment. This is why it does not inherit from TomwerScanBase. This is a utility class. """ _TYPE = "bliss_hdf5" def __init__( self, master_file, entry, proposal_file, scan_numbers=None, saving_file=None ): self._master_file = master_file if isinstance(entry, str) and not entry.startswith("/"): self._entry = "/" + entry else: self._entry = entry self._proposal_file = proposal_file self._scan_numbers = scan_numbers or [] self._saving_file = saving_file self._tomo_n = None self._n_acquired = None self._dir_path = os.path.dirname(self.master_file) @property def tomo_n(self): """total number of projections""" return self._tomo_n @property def proposal_file(self): return self._proposal_file @property def saving_file(self): return self._saving_file @tomo_n.setter def tomo_n(self, n): self._tomo_n = n @property def n_acquired(self): """ number of frame acquired until now. Does not take into account dark, flats or alignment""" return self._n_acquired @n_acquired.setter def n_acquired(self, n): self._n_acquired = n @property def master_file(self): return self._master_file @property def entry(self): return self._entry @property def path(self): return self._dir_path @property def scan_numbers(self): return self._scan_numbers def add_scan_number(self, scan_number): self._scan_numbers.append(scan_number) def __str__(self): return self.get_id_name(master_file=self.master_file, entry=self.entry) @staticmethod def get_id_name(master_file, entry): return "@".join((str(entry), master_file)) def _deduce_transfert_scan(self, output_dir): new_master_file = os.path.join( output_dir, os.path.basename(os.path.dirname(self.master_file)), os.path.basename(self.master_file), ) new_proposal_file = os.path.join( output_dir, os.path.basename(self.proposal_file) ) return BlissScan( master_file=new_master_file, proposal_file=new_proposal_file, entry=self.entry, ) @staticmethod def is_bliss_file(file_path): return len(BlissScan.get_valid_entries(file_path)) > 0 def is_abort(self, *args, **kwargs): # for now there is not real way to know if a scan is abort or not return False def scan_dir_name(self) -> str | None: """for 'this/is/my/acquisition' returns 'acquisition'""" if self.path is not None: return self.path.split(os.sep)[-1] else: return None def scan_basename(self) -> str | None: """for 'this/is/my/acquisition' returns 'acquisition'""" if self.path is not None: return self.path else: return None def scan_parent_dir_basename(self) -> str | None: if self.path is not None: try: return os.path.dirname(self.path) except Exception: return None else: return None @staticmethod def is_bliss_valid_entry(file_path: str, entry: str): def is_pcotmo_tomo(current_title: str): for title in H5_PCOTOMO_INIT_TITLES: if current_title.startswith(title): return True return False def is_standard_tomo(current_title: str): for title in H5_INIT_TITLES: if current_title.startswith(title): return True return False def is_zseries_tomo(current_title: str): for title in H5_ZSERIE_INIT_TITLES: if current_title.startswith(title): return True return False def is_back_and_forth_tomo(current_title: str): for title in H5_BACK_AND_FORTH_INIT_TITLES: if current_title.startswith(title): return True return False with open_hdf5(file_path) as h5s: if not isinstance(h5s, h5py.Group) or not isinstance( h5s[entry], h5py.Group ): return False if "title" in h5s[entry]: title = h5py_read_dataset(h5s[entry]["title"]) try: return ( is_standard_tomo(title) or is_zseries_tomo(title) or is_pcotmo_tomo(title) or is_back_and_forth_tomo(title) ) except Exception: pass return False @staticmethod def get_valid_entries(file_path) -> tuple: if not h5py.is_hdf5(file_path): _logger.warning("Provided file %s is not a hdf5 file" % file_path) return tuple() else: res = [] with open_hdf5(file_path) as h5s: for entry in h5s: if BlissScan.is_bliss_valid_entry(file_path=file_path, entry=entry): res.append(entry) return tuple(res) def to_dict(self): return { "DICT_TYPE_KEY": self._TYPE, "master_file": self.master_file, "entry": self.entry, "proposal_file": self.proposal_file, "scan_numbers": self.scan_numbers, } @staticmethod def from_dict(ddict): master_file = ddict["master_file"] entry = ddict["entry"] return BlissScan( master_file=master_file, entry=entry, proposal_file=None ).load_frm_dict(ddict=ddict) def load_frm_dict(self, ddict): if "master_file" in ddict: self._master_file = ddict["master_file"] if "entry" in ddict: self._entry = ddict["entry"] if "proposal_file" in ddict: self._proposal_file = ddict["proposal_file"] if "scan_numbers" in ddict: self._scan_numbers = ddict["scan_numbers"] return self ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/scan/edfscan.py0000644000175000017500000005072715153325210020166 0ustar00paynopaynofrom __future__ import annotations import functools import logging import os import re from collections import OrderedDict from glob import glob from math import ceil import pathlib from datetime import datetime from pathlib import Path import fabio import numpy from tqdm import tqdm from processview.core.dataset import DatasetIdentifier from silx.io.url import DataUrl from tomoscan.esrf.identifier.edfidentifier import ( EDFTomoScanIdentifier as _EDFTomoScanIdentifier, ) from tomoscan.esrf.scan.edfscan import EDFTomoScan as _tsEDFTomoScan from tomoscan.esrf.scan.utils import get_data from nxtomo.nxobject.nxdetector import FOV from tomwer.core.process.reconstruction.darkref.settings import ( DARKHST_PREFIX, REFHST_PREFIX, ) from tomwer.utils import docstring from .scanbase import TomwerScanBase _logger = logging.getLogger(__name__) global counter_rand counter_rand = 1 # used to be sure to return a unique index on recons slices class EDFTomoScanIdentifier(_EDFTomoScanIdentifier, DatasetIdentifier): def __init__(self, object, folder, file_prefix, metadata=None): super().__init__(object, folder, file_prefix) DatasetIdentifier.__init__(self, EDFTomoScan.from_identifier, metadata=metadata) @staticmethod def from_str(identifier): from tomoscan.esrf.scan.edfscan import EDFTomoScan return _EDFTomoScanIdentifier._from_str_to_single_frame_identifier( identifier=identifier, SingleFrameIdentifierClass=EDFTomoScanIdentifier, ObjClass=EDFTomoScan, ) def long_description(self) -> str: """used for processview header tooltip for now""" return self.to_str() def short_description(self) -> str: return f"scan: {os.path.basename(os.path.basename(self.folder))} (EDF)" class EDFTomoScan(_tsEDFTomoScan, TomwerScanBase): """ Class used to represent a tomography acquisition with hdf5 files. :param scan: path of the scan """ def __init__(self, scan, overwrite_proc_file=False, update=True): _tsEDFTomoScan.__init__(self, scan=scan) TomwerScanBase.__init__(self) # register at least the 'default' working directory as a possible reconstruction path self.add_reconstruction_path(self.path) self._dark = None if scan is not None and update: try: self.update() except IOError: # fabio can raise some empty file error when data is not on disk (can be the case for the datawatcher when acquisiton is on going) pass try: reduced_darks, metadata = self.load_reduced_darks(return_info=True) except (KeyError, OSError, ValueError): # file or key does not exists pass else: self.set_reduced_darks(reduced_darks, darks_infos=metadata) try: reduced_flats, metadata = self.load_reduced_flats(return_info=True) except (KeyError, OSError, ValueError): pass else: self.set_reduced_flats(reduced_flats, flats_infos=metadata) @staticmethod def is_tomoscan_dir( directory: str, dataset_basename: str | None = None, src_pattern=None, dest_pattern=None, **kwargs, ) -> bool: info_file = EDFTomoScan.get_info_file( directory=directory, dataset_basename=dataset_basename, kwargs=kwargs ) if src_pattern is not None and dest_pattern is not None: infofilenice = info_file.replace(src_pattern, dest_pattern, 1) return os.path.isfile(infofilenice) or os.path.isfile(info_file) else: return os.path.isfile(info_file) @property def working_directory(self) -> None | Path: if self.path is None: return None else: return Path(self.path) @staticmethod def from_identifier(identifier): """Return the Dataset from a identifier""" if not isinstance(identifier, EDFTomoScanIdentifier): raise TypeError( f"identifier should be an instance of {EDFTomoScanIdentifier} not {type(identifier)}" ) return EDFTomoScan(scan=identifier.folder) def clear_cache(self): _tsEDFTomoScan.clear_cache(self) TomwerScanBase.clear_cache(self) @staticmethod def directory_contains_scan(directory, src_pattern, dest_pattern): """ Check if the given directory is holding an acquisition :param directory: directory we want to check :param src_pattern: buffer name pattern ('lbsram') :param dest_pattern: output pattern (''). Needed because some acquisition can split the file produce between two directories. This is the case for edf, where .info file are generated in /data/dir instead of /lbsram/data/dir :return: does the given directory contains any acquisition """ aux = directory.split(os.path.sep) info_name = os.path.join(directory, aux[-1] + EDFTomoScan.INFO_EXT) if src_pattern: info_name = info_name.replace(src_pattern, dest_pattern, 1) return os.path.isfile(info_name) def data_flat_field_correction(self, data, index=None): """ Apply the flat field correction on the given data. :param data: radio to correct :return numpy.ndarray: corrected data """ dark = self.getDark() flat = self.getFlat() return self._flat_field_correction( data=data, dark=dark, flat1=flat, flat2=None, index_flat1=-1, index_flat2=-1, index_proj=index, ) def update(self): """update list of radio and reconstruction by parsing the scan folder""" _tsEDFTomoScan.update(self) self.reconstructions = EDFTomoScan.get_reconstructions_paths(self.path) def projections_with_angle(self): return self.get_proj_angle_url() @staticmethod def get_reconstructions_paths(scanID, withIndex=False): """ Return the dict of files: * fitting with a reconstruction pattern and ending by .edf * .vol files :param scanID: is the path to the folder of acquisition :param withIndex: if False then return a list of slices otherwise return a dict with the index of the slice reconstructed. """ def containsDigits(input_): return any(char.isdigit() for char in input_) if (scanID is None) or (not os.path.isdir(scanID)): if withIndex is True: return {} else: return [] pyhst_files = TomwerScanBase.get_pyhst_recons_file(scanID) if pyhst_files is not None: return TomwerScanBase.getReconstructedFilesFromParFile( pyhst_files, with_index=withIndex ) else: folderBasename = os.path.basename(scanID) files = {} if withIndex is True else [] if os.path.isdir(scanID): for f in os.listdir(scanID): if ( f.endswith(TomwerScanBase.VALID_RECONS_EXTENSION) and f.startswith(folderBasename) and "slice_" in f ): local_str = f for extension in TomwerScanBase.VALID_RECONS_EXTENSION: if local_str.endswith(extension): local_str = local_str.rsplit(extension, 1)[0] if "slice_" in local_str: if "slice_pag_" in local_str: indexStr = local_str.split("slice_pag_")[-1].split("_")[ 0 ] elif "slice_ctf_" in local_str: indexStr = local_str.split("slice_ctf_")[-1].split("_")[ 0 ] else: indexStr = local_str.split("slice_")[-1].split("_")[0] if containsDigits(indexStr): gfile = os.path.join(scanID, f) assert os.path.isfile(gfile) if withIndex is True: files[ EDFTomoScan.get_index_reconstructed(f, scanID) ] = gfile else: files.append(gfile) if f.endswith(".vol"): if withIndex is True: files[EDFTomoScan.get_index_reconstructed(f, scanID)] = ( os.path.join(scanID, f) ) else: files.append(os.path.join(scanID, f)) return files def load_from_dict(self, desc): _tsEDFTomoScan.load_from_dict(self, desc) TomwerScanBase.load_from_dict(self, desc) return self def _get_scheme(self): """ :return: scheme to read url """ return "fabio" @docstring(TomwerScanBase.get_sinogram) @functools.lru_cache(maxsize=16, typed=True) def get_sinogram(self, line, subsampling=1, norm_method=None, **kwargs): """ extract the sinogram from projections :param line: which sinogram we want :param subsampling: subsampling to apply if any. Allows to skip some io :return: sinogram from the radio lines """ _logger.info( f"compute sinogram for line {line} of {self.path} (subsampling: {subsampling})" ) assert isinstance(line, int) if self.tomo_n is not None and self.dim_2 is not None and line > self.dim_2: raise ValueError("requested line %s is not in the scan") else: y_dim = ceil(self.tomo_n / subsampling) sinogram = numpy.empty((y_dim, self.dim_1)) proj_urls = self.get_proj_angle_url() assert len(proj_urls) >= self.tomo_n proj_sort = list(proj_urls.keys()) proj_sort = list(filter(lambda x: not isinstance(x, str), proj_sort)) proj_sort.sort() advancement = tqdm( desc=f"compute sinogram for {os.path.basename(self.path)}, line={line}, sampling={subsampling}" ) advancement.total = len(proj_sort) for i_proj, proj in enumerate(proj_sort): if i_proj % subsampling == 0: url = proj_urls[proj] radio = get_data(url) radio = self.data_flat_field_correction(radio) sinogram[i_proj // subsampling] = radio[line] advancement.update() return sinogram @functools.lru_cache(maxsize=3) def getFlat(self, index: int | None = None): """ If projectionI is not requested then return the mean value. Otherwise return the interpolated value for the requested projection. :param index: index of the projection for which we want the flat :return: Flat field value or None if can't deduce it """ data = self._extractFromOneFile("refHST.edf", what="flat") if data is not None: return data data = self._extractFromPrefix(REFHST_PREFIX, what="flat", proI=index) if data is not None: return data _logger.warning("Cannot retrieve flat file from %s" % self.path) return None @docstring(TomwerScanBase.get_proj_angle_url) def get_proj_angle_url(self, use_cache: bool = True, *args, **kwargs): if not use_cache: self._cache_proj_urls = None if self._cache_proj_urls is None: self._cache_proj_urls = _tsEDFTomoScan.get_proj_angle_url( self, *args, **kwargs ) return self._cache_proj_urls @functools.lru_cache() def getDark(self): """ For now only deal with one existing dark file. :return: image of the dark if existing. Else None """ if self._dark is None: # first try to retrieve data from dark.edf file or darkHST.edf files self._dark = self._extractFromOneFile("dark.edf", what="dark") if self._dark is None: self._dark = self._extractFromOneFile("darkHST.edf", what="dark") if self._dark is None: self._dark = self._extractFromPrefix(DARKHST_PREFIX, what="dark") if self._dark is None: self._dark = self._extractFromPrefix("darkend", what="dark") if self._dark is None: _logger.warning("Cannot retrieve dark file from %s" % self.path) return self._dark def _extractFromOneFile(self, f, what): if self.path is None: return None path = os.path.join(self.path, f) if os.path.exists(path): _logger.info(f"Getting {what} from {f}") try: data = fabio.open(path).data except Exception: return None else: if data.ndim == 2: return data elif data.ndim == 3: _logger.warning( "%s file contains several images. Taking " "the mean value" % what ) return numpy.mean(data.ndim) else: return None @staticmethod def guess_index_frm_EDFFile_name(_file): name = _file if name.endswith(".edf"): name = name.rstrip(".edf") ic = [] while name[-1].isdigit(): ic.append(name[-1]) name = name[:-1] if len(ic) == 0: return None else: orignalOrder = ic[::-1] return int("".join(orignalOrder)) def _extractFromPrefix(self, pattern, what, proI=None): if self.path is None: return None files = glob(os.path.join(self.path, pattern + "*.edf")) if len(files) == 0: return None else: d = {} for f in files: index = self.guess_index_frm_EDFFile_name(f) if index is None: _logger.error("cannot retrieve projection index for %s" "" % f) return None else: d[index] = fabio.open(f).data if len(files) == 1: return d[list(d.keys())[0]] oProj = OrderedDict(sorted(d.items())) # for now we only deal with interpolation between the higher # and the lower acquired file () lowPI = list(oProj.keys())[0] uppPI = list(oProj.keys())[-1] lowPD = oProj[lowPI] uppPD = oProj[uppPI] if len(oProj) > 2: _logger.info( f"Only bordering projections ({lowPI} and {uppPI}) will be used for extracting {what}" ) uppPI = uppPI index = proI if index is None: index = (uppPI - lowPI) / 2 if (index >= lowPI) is False: index = lowPI _logger.warning( "ProjectionI not in the files indexes range (projectionI >= lowerProjIndex)" ) if (index <= uppPI) is False: index = uppPI _logger.warning( "ProjectionI not in the files indexes range upperProjIndex >= projectionI" ) # simple interpolation _nRef = uppPI - lowPI lowPI = lowPI w0 = (lowPI + (uppPI - index)) / _nRef w1 = index / _nRef return w0 * lowPD + w1 * uppPD @staticmethod def get_index_reconstructed(reconstructionFile, scanID): """Return the slice reconstructed of a file from her name :param reconstructionFile: the name of the file """ folderBasename = os.path.basename(scanID) if reconstructionFile.endswith(".edf") and reconstructionFile.startswith( folderBasename ): localstring = reconstructionFile.rstrip(".edf") # remove the scan localstring = re.sub(folderBasename, "", localstring) s = localstring.split("_") if s[-1].isdigit(): return int(s[-1]) else: _logger.warning( "Fail to find the slice reconstructed for " "file %s" % reconstructionFile ) else: global counter_rand counter_rand = counter_rand + 1 return counter_rand @docstring(_tsEDFTomoScan.to_dict) def to_dict(self): res = _tsEDFTomoScan.to_dict(self) res.update(TomwerScanBase.to_dict(self)) return res @docstring(TomwerScanBase._deduce_transfert_scan) def _deduce_transfert_scan(self, output_dir): if os.path.basename(output_dir) != os.path.basename(self.path): raise ValueError( "Transfert to a new EDFTomoScan requires an equal basename. " f"Current path is {self.path}, requested one is {output_dir}" ) # here: avoir reloading the metadata because not sure there will be some processing after the 'data transfert'. And can be long with EDF + GPFS at esrf return EDFTomoScan(scan=output_dir, update=False) def __str__(self): return self.path # Dataset implementation @docstring(_tsEDFTomoScan) def get_identifier(self): try: stat = pathlib.Path(self.path).stat() except Exception: stat = None return EDFTomoScanIdentifier( object=self, folder=self.path, file_prefix=self.dataset_basename, metadata={ "name": self.path, "creation_time": ( datetime.fromtimestamp(stat.st_ctime) if stat else None ), "modification_time": ( datetime.fromtimestamp(stat.st_ctime) if stat else None ), }, ) @docstring(TomwerScanBase) def get_nabu_dataset_info(self, binning=1, binning_z=1, proj_subsampling=1): return { "hdf5_entry": "", "location": self.path, "binning": binning, "binning_z": binning_z, "projections_subsampling": proj_subsampling, } @docstring(TomwerScanBase) def to_nabu_dataset_analyser(self): from nabu.resources.dataset_analyzer import EDFDatasetAnalyzer analyzer = EDFDatasetAnalyzer(location=self.path) n_angles = analyzer.n_angles if analyzer.rotation_angles is None: if self.field_of_view is FOV.HALF: angles = numpy.linspace(0, 2 * numpy.pi, n_angles, True) else: angles = numpy.linspace(0, numpy.pi, n_angles, False) analyzer.rotation_angles = angles return analyzer @docstring(TomwerScanBase) def scan_dir_name(self) -> str | None: """for 'this/is/my/acquisition' returns 'acquisition'""" if self.path is not None: return self.path.split(os.sep)[-1] else: return None @docstring(TomwerScanBase) def scan_basename(self) -> str | None: """for 'this/is/my/acquisition' returns 'acquisition'""" if self.path is not None: return self.path else: return None @docstring(TomwerScanBase) def scan_parent_dir_basename(self) -> str | None: if self.path is not None: try: return os.path.dirname(self.path) except Exception: return None else: return None def _get_urls_list(radio): """create the list of urls contained in a .edf file""" with fabio.open(radio) as edf_reader: if edf_reader.nframes == 1: return [DataUrl(file_path=radio, scheme="fabio")] else: res = [] for iframe in range(edf_reader.nframes): res.append( DataUrl(file_path=radio, data_slice=[iframe], scheme="fabio") ) return res ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/scan/futurescan.py0000644000175000017500000000032515153325210020727 0ustar00paynopaynofrom silx.utils.deprecation import deprecated from tomwer.core.futureobject import TomwerScanBase @deprecated(replacement="TomwerScanBase", since_version="1.0") class FutureTomwerScan(TomwerScanBase): pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/scan/hdf5scan.py0000644000175000017500000000170615153325210020247 0ustar00paynopaynofrom tomwer.core.scan.nxtomoscan import NXtomoScanIdentifier, NXtomoScan from tomwer.core.utils.deprecation import deprecated_warning class HDF5TomoScanIdentifier(NXtomoScanIdentifier): def __init__(self, metadata=None, *args, **kwargs): deprecated_warning( name="tomwer.core.scan.nxtomoscan.NXtomoScanIdentifier", type_="class", reason="improve readibility", since_version="1.3", replacement="NXtomoScanIdentifier", ) super().__init__(metadata, *args, **kwargs) class HDF5TomoScan(NXtomoScan): def __init__(self, scan, entry, index=None, overwrite_proc_file=False): deprecated_warning( name="tomwer.core.scan.nxtomoscan.NXtomoScan", type_="class", reason="improve readibility", since_version="1.3", replacement="NXtomoScan", ) super().__init__(scan, entry, index, overwrite_proc_file) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/scan/helicalmetadata.py0000644000175000017500000000073014757047403021670 0ustar00paynopaynoclass HelicalMetadata: def __init__(self) -> None: self._processes_files = ( "{scan_parent_dir_basename}/{scan_dir_name}/map_and_doubleff.hdf5" ) @property def processes_files(self) -> str: return self._processes_files @processes_files.setter def processes_files(self, path: str): if not isinstance(path, str): raise TypeError(f"expects a str. Get {path}") self._processes_files = path ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/scan/nxtomoscan.py0000644000175000017500000004422115153325210020744 0ustar00paynopaynofrom __future__ import annotations import functools import io import json import logging import os import pathlib from datetime import datetime from urllib.parse import urlparse from pathlib import Path import h5py from processview.core.dataset import DatasetIdentifier from silx.io.utils import open as open_hdf5 from silx.io.url import DataUrl from tomoscan.esrf.identifier.hdf5Identifier import ( NXtomoScanIdentifier as _NXtomoScanIdentifier, ) from tomoscan.esrf.identifier.url_utils import UrlSettings, split_path, split_query from tomoscan.esrf.scan.nxtomoscan import NXtomoScan as _tsNXtomoScan from tomoscan.utils.io import filter_esrf_mounting_points from nxtomo.nxobject.nxdetector import ImageKey from nxtomo.paths.nxtomo import get_paths as _get_nexus_paths from tomwer.utils import docstring from tomwer.core.scan.helicalmetadata import HelicalMetadata from .scanbase import TomwerScanBase _logger = logging.getLogger(__name__) class NXtomoScanIdentifier(_NXtomoScanIdentifier, DatasetIdentifier): def __init__(self, metadata=None, *args, **kwargs): super().__init__(*args, **kwargs) DatasetIdentifier.__init__( self, data_builder=NXtomoScan.from_identifier, metadata=metadata ) @staticmethod def from_str(identifier): info = urlparse(identifier) paths = split_path(info.path) if len(paths) == 1: hdf5_file = paths[0] tomo_type = None elif len(paths) == 2: tomo_type, hdf5_file = paths else: raise ValueError("Failed to parse path string:", info.path) if tomo_type is not None and tomo_type != NXtomoScanIdentifier.TOMO_TYPE: raise TypeError( f"provided identifier fits {tomo_type} and not {NXtomoScanIdentifier.TOMO_TYPE}" ) queries = split_query(info.query) entry = queries.get(UrlSettings.DATA_PATH_KEY, None) if entry is None: raise ValueError(f"expects to get {UrlSettings.DATA_PATH_KEY} query") return NXtomoScanIdentifier(object=NXtomoScan, hdf5_file=hdf5_file, entry=entry) def long_description(self) -> str: """used for processview header tooltip for now""" return self.to_str() def short_description(self) -> str: return f"scan: {self.data_path.lstrip('/')}@{os.path.basename(self._file_path)}" class NXtomoScan(_tsNXtomoScan, TomwerScanBase): """ This is the implementation of a TomoBase class for an acquisition stored in a HDF5 file. For now several property of the acquisition is accessible thought a getter (like get_scan_range) and a property (scan_range). This is done to be compliant with TomoBase instantiation. But his will be replace progressively by properties at the 'TomoBase' level :param scan: scan directory or scan masterfile.h5 """ _TYPE = "hdf5" def __init__( self, scan: str | None, entry: str | None, index: int | None = None, overwrite_proc_file: bool = False, ): TomwerScanBase.__init__(self) _tsNXtomoScan.__init__(self, scan=scan, entry=entry, index=index) # speed up for now, avoid to run check by default self.set_check_behavior(run_check=False) # register at least the 'default' working directory as a possible reconstruction path self.add_reconstruction_path(self.path) self._helical = HelicalMetadata() self._reconstruction_urls = None self._projections_with_angles = None try: reduced_darks, metadata = self.load_reduced_darks(return_info=True) except (KeyError, OSError, ValueError): # file or key does not exists pass else: self.set_reduced_darks(reduced_darks, darks_infos=metadata) try: reduced_flats, metadata = self.load_reduced_flats(return_info=True) except (KeyError, OSError, ValueError): pass else: self.set_reduced_flats(reduced_flats, flats_infos=metadata) @property def working_directory(self) -> None | Path: if self.master_file is None: return None else: return Path(os.path.dirname(self.master_file)).absolute() @property def helical(self): return self._helical @staticmethod def from_identifier(identifier): """Return the Dataset from a identifier""" if not isinstance(identifier, NXtomoScanIdentifier): raise TypeError( f"identifier should be an instance of {NXtomoScanIdentifier}. Not {type(identifier)}" ) return NXtomoScan(scan=identifier.file_path, entry=identifier.data_path) def get_identifier(self): try: stat = pathlib.Path(self.master_file).stat() except Exception: stat = None return NXtomoScanIdentifier( object=self, hdf5_file=self.master_file, entry=self.entry, metadata={ "name": self.master_file, "creation_time": ( datetime.fromtimestamp(stat.st_ctime) if stat else None ), "modification_time": ( datetime.fromtimestamp(stat.st_ctime) if stat else None ), }, ) @staticmethod def directory_contains_scan(directory, src_pattern=None, dest_pattern=None): """ Check if the given directory is holding an acquisition :param directory: directory we want to check :param src_pattern: buffer name pattern ('lbsram') :param dest_pattern: output pattern (''). Needed because some acquisition can split the file produce between two directories. This is the case for edf, where .info file are generated in /data/dir instead of /lbsram/data/dir :return: does the given directory contains any acquisition """ master_file = os.path.join(directory, os.path.basename(directory)) if os.path.exists("master_file.hdf5"): return True else: return os.path.exists(master_file + ".h5") def clear_cache(self): _tsNXtomoScan.clear_cache(self) TomwerScanBase.clear_cache(self) def is_abort(self, src_pattern, dest_pattern): """ Check if the acquisition have been aborted. In this case the directory should contain a [scan].abo file :param src_pattern: buffer name pattern ('lbsram') :param dest_pattern: output pattern (''). Needed because some acquisition can split the file produce between two directories. This is the case for edf, where .info file are generated in /data/dir instead of /lbsram/data/dir :return: True if the acquisition have been abort and the directory should be abort """ # for now there is no abort definition in .hdf5 return False @staticmethod def from_dict(_dict): path = _dict[NXtomoScan.DICT_PATH_KEY] entry = _dict[NXtomoScan._DICT_ENTRY_KEY] scan = NXtomoScan(scan=path, entry=entry) scan.load_from_dict(_dict=_dict) return scan @docstring(TomwerScanBase) def load_from_dict(self, _dict): """ :param _dict: :return: """ if isinstance(_dict, io.TextIOWrapper): data = json.load(_dict) else: data = _dict if not (self.DICT_TYPE_KEY in data and data[self.DICT_TYPE_KEY] == self._TYPE): raise ValueError("Description is not an EDFScan json description") _tsNXtomoScan.load_from_dict(self, _dict) TomwerScanBase.load_from_dict(self, _dict) return self @docstring(TomwerScanBase) def to_dict(self) -> dict: ddict = _tsNXtomoScan.to_dict(self) ddict.update(TomwerScanBase.to_dict(self)) return ddict def update(self): """update list of radio and reconstruction by parsing the scan folder""" if self.master_file is None: return if not os.path.exists(self.master_file): return _tsNXtomoScan.update(self) self.reconstructions = self.get_reconstructed_slices() def _get_scheme(self): """ :return: scheme to read url """ return "silx" def is_finish(self): return len(self.projections) >= self.tomo_n @docstring(TomwerScanBase.get_sinogram) @functools.lru_cache(maxsize=16, typed=True) def get_sinogram(self, line, subsampling=1, norm_method=None, **kwargs): """ extract the sinogram from projections :param line: which sinogram we want :param subsampling: subsampling to apply if any. Allows to skip some io :return: sinogram from the radio lines """ return _tsNXtomoScan.get_sinogram( self, line=line, subsampling=subsampling, norm_method=norm_method, **kwargs, ) @docstring(TomwerScanBase.get_proj_angle_url) def get_proj_angle_url(self, use_cache: bool = True, with_alignment=True): if not use_cache: self._cache_proj_urls = None if self._cache_proj_urls is None: frames = self.frames if frames is None: return {} self._cache_proj_urls = {} for frame in frames: if frame.image_key is ImageKey.PROJECTION: if frame.is_control and with_alignment: self._cache_proj_urls[f"{frame.rotation_angle} (1)"] = frame.url elif frame.is_control: continue else: self._cache_proj_urls[str(frame.rotation_angle)] = frame.url return self._cache_proj_urls @docstring(TomwerScanBase._deduce_transfert_scan) def _deduce_transfert_scan(self, output_dir): new_master_file_path = os.path.join( output_dir, os.path.basename(self.master_file) ) return NXtomoScan(scan=new_master_file_path, entry=self.entry) def data_flat_field_correction(self, data, index=None): flats = self.reduced_flats flat1 = flat2 = None index_flat1 = index_flat2 = None if flats is not None: flat_indexes = sorted(list(flats.keys())) if len(flats) > 0: index_flat1 = flat_indexes[0] flat1 = flats[index_flat1] if len(flats) > 1: index_flat2 = flat_indexes[-1] flat2 = flats[index_flat2] darks = self.reduced_darks dark = None if darks is not None and len(darks) > 0: # take only one dark into account for now dark = list(darks.values())[0] return self._flat_field_correction( data=data, dark=dark, flat1=flat1, flat2=flat2, index_flat1=index_flat1, index_flat2=index_flat2, index_proj=index, ) @docstring(_tsNXtomoScan.ff_interval) @property def ff_interval(self): """ Make some assumption to compute the flat field interval: """ def get_first_two_ff_indexes(): if self.flats is None: return None, None else: self._last_flat_index = None self._first_series_flat_index = None for flat_index in self.flats: if self._last_flat_index is None: self._last_flat_index = flat_index elif flat_index == self._last_flat_index + 1: self._last_flat_index = flat_index continue else: return self._last_flat_index, flat_index return None, None first_series_index, second_series_index = get_first_two_ff_indexes() if first_series_index is None: return 0 elif second_series_index is not None: return second_series_index - first_series_index - 1 else: return 0 def projections_with_angle(self): """projections / radio, does not include the return projections""" if self._projections_with_angles is None: if self.frames: proj_frames = tuple( filter( lambda x: x.image_key == ImageKey.PROJECTION and x.is_control is False, self.frames, ) ) self._projections_with_angles = {} for proj_frame in proj_frames: self._projections_with_angles[proj_frame.rotation_angle] = ( proj_frame.url ) return self._projections_with_angles @staticmethod def is_nexus_nxtomo_file(file_path: str) -> bool: if h5py.is_hdf5(file_path): return len(NXtomoScan.get_nxtomo_entries(file_path)) > 0 @staticmethod def get_nxtomo_entries(file_path: str) -> tuple: if not h5py.is_hdf5(file_path): return tuple() else: res = [] with open_hdf5(file_path) as h5s: for entry_name, node in h5s.items(): if isinstance(node, h5py.Group): if NXtomoScan.entry_is_nx_tomo(node): res.append(entry_name) return tuple(res) @staticmethod def entry_is_nx_tomo(entry: h5py.Group): return ("beam" in entry and "instrument" in entry and "sample" in entry) or ( hasattr(entry, "attrs") and "definition" in entry.attrs and entry.attrs["definition"] == "NXtomo" ) @staticmethod def is_nxdetector(grp: h5py.Group): """ Check if the grp is an nx detector :param grp: :return: True if this is the definition of a group """ if hasattr(grp, "attrs"): if "NX_class" in grp.attrs and grp.attrs["NX_class"] == "NXdetector": return True return False # Dataset implementation @docstring(TomwerScanBase) def get_nabu_dataset_info(self, binning=1, binning_z=1, proj_subsampling=1): if not isinstance(binning, int): raise TypeError(f"binning should be an int. Not {type(binning)}") if not isinstance(binning_z, int): raise TypeError(f"binning_z should be an int. Not {type(binning_z)}") if not isinstance(proj_subsampling, int): raise TypeError( f"proj_subsampling should be an int. Not {type(proj_subsampling)}" ) return { "hdf5_entry": self.entry, "location": filter_esrf_mounting_points( str(pathlib.Path(self.master_file).resolve()) ), "binning": binning, "binning_z": binning_z, "projections_subsampling": proj_subsampling, } @docstring(TomwerScanBase) def to_nabu_dataset_analyser(self): from nabu.resources.dataset_analyzer import HDF5DatasetAnalyzer return HDF5DatasetAnalyzer( location=self.master_file, extra_options={"hdf5_entry": self.entry} ) @docstring(TomwerScanBase) def scan_dir_name(self) -> str | None: """for 'this/is/my/file.h5' returns 'my'""" if self.master_file is not None: return os.path.dirname(self.master_file).split(os.sep)[-1] else: return None @docstring(TomwerScanBase) def scan_basename(self): if self.master_file is not None: try: return os.path.dirname(self.master_file) except Exception: return None else: return None @docstring(TomwerScanBase) def scan_parent_dir_basename(self): if self.master_file is not None: try: return os.path.dirname(os.path.dirname(self.master_file)) except Exception: return None else: return None def get_proposal_name(self) -> str | None: if self._proposal_name is None and self.master_file is not None: bliss_raw_data_files = self.get_bliss_original_files() or () bliss_raw_data_file = ( bliss_raw_data_files[0] if len(bliss_raw_data_files) > 0 else None ) if bliss_raw_data_file is not None: bliss_raw_data_file = filter_esrf_mounting_points( str(pathlib.Path(bliss_raw_data_file)) ) strips = bliss_raw_data_file.lstrip("/").split("/") if len(strips) > 2 and bliss_raw_data_file.startswith( ("/data/visitor", "/data/visitor") ): self._proposal_name = strips[2] elif ( bliss_raw_data_file.startswith(("/data", "data")) and len(strips) > 3 and strips[2] == "inhouse" ): self._proposal_name = strips[3] else: _logger.warning( "this doesn't looks like a bliss file acquired at the ESRF. Unable to find proposal name" ) return self._proposal_name def get_detector_url(self) -> DataUrl | None: """ compute and return the url where the detector data can be found """ if self.master_file is None: return None else: nexus_paths = _get_nexus_paths(version=self.nexus_version) return DataUrl( file_path=self.master_file, data_path="/".join( ( self.entry, nexus_paths.INSTRUMENT_PATH, nexus_paths.nx_instrument_paths.DETECTOR_PATH, nexus_paths.nx_instrument_paths.DATA, ) ), scheme="silx", ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/scan/scanbase.py0000644000175000017500000006417115153325210020340 0ustar00paynopaynofrom __future__ import annotations import io import json import logging import os import copy from glob import glob import functools import pathlib from typing import Iterable import numpy from silx.io.url import DataUrl from enum import Enum as _Enum from pathlib import Path from tomoscan.identifier import VolumeIdentifier from tomoscan.normalization import IntensityNormalization from tomoscan.volumebase import VolumeBase from tomoscan.identifier import BaseIdentifier from tomoscan.esrf.volume.utils import guess_volumes from tomoscan.utils.io import filter_esrf_mounting_points from tomwer.core.tomwer_object import TomwerObject from tomwer.core.utils.ftseriesutils import orderFileByLastLastModification from tomwer.io.utils.raw_and_processed_data import ( to_raw_data_path, to_processed_data_path, ) logger = logging.getLogger(__name__) class TomwerScanBase(TomwerObject): """ Interface to extend tomoscan.TomoScanBase with custom functionality. ..warning:: All classes inheriting from this interface must also inherit from a child class of tomoscan.TomoScanBase """ _DICT_DARK_REF_KEYS = "dark_ref_params" _DICT_NABU_RP_KEY = "nabu_params" _DICT_AXIS_KEYS = "axis_params" _DICT_SA_AXIS_KEYS = "sa_axis_params" _DICT_SA_DELTA_BETA_KEYS = "sa_delta_beta_params" _DICT_NORMALIZATION_KEY = "norm_params" VALID_RECONS_EXTENSION = ".edf", ".npy", ".npz", ".hdf5", ".tiff", ".jp2", ".vol" def __init__(self, overwrite_proc_file=False): super().__init__() self._stitching_metadata = None self._reconstructions = [] self._nabu_params = None """nabu reconstruction parameters""" self._axis_params = None """Axis parameters""" self._saaxis_params = None """Information relative to saaxis""" self._sa_delta_beta_params = None """Information regarding sa_delta_beta_params""" self._dark_ref_params = None """Information regarding dark - ref reconstruction""" self._cache_proj_urls = None """cache for the projection urls""" self._cache_radio_axis = {} """cache for the radio axis. Key is tuple (mode, nearest), value is (url1, url2)""" self._notify_ffc_rsc_missing = True """Should we notify the user if ffc fails because cannot find dark or flat. Used to avoid several warnings. Only display one""" self._latest_reconstructions = [] "list of url related to latest slice reconstruction from nabu" self._latest_vol_reconstructions = [] """list of url related to latest volume reconstruction from nabu""" self._reconstruction_paths = set() """set of paths containing reconstructions of the scan. Make sure we have an entry point for it""" self._proposal_name = None def _clear_heavy_cache(self): """For scan for now we don't want to remove any information from the cache. Mor eusefull for volume use case """ pass @property def resolved_path(self) -> str | None: """ return tomoscan 'path' with link resolved """ if self.path is None: # pylint: disable=E1101 return None return filter_esrf_mounting_points( str(Path(self.path).resolve()) # pylint: disable=E1101 ) @property def working_directory(self) -> Path | None: """ working directory once all links have been solved (required for submitting jobs to slurm) """ if self.working_directory is None: return None return pathlib.Path(self.working_directory) def clear_cache(self): self._cache_proj_urls = None self._notify_ffc_rsc_missing = True super().clear_cache() def _flat_field_correction( self, data, index_proj: int | None, dark, flat1, flat2, index_flat1: int, index_flat2: int, ): """ compute flat field correction for a provided data from is index one dark and two flats (require also indexes) """ if not isinstance(data, numpy.ndarray): raise TypeError("data is expected to be an instance of numpy.ndarray") can_process = True if dark is None: if self._notify_ffc_rsc_missing: logger.warning("cannot make flat field correction, dark not found") can_process = False if dark is not None and dark.ndim != 2: logger.error( "cannot make flat field correction, dark should be of " "dimension 2" ) can_process = False if flat1 is None: if self._notify_ffc_rsc_missing: logger.warning("cannot make flat field correction, flat not found") can_process = False elif not isinstance(flat1, numpy.ndarray): raise TypeError("flat1 is expected to be an instance of numpy.ndarray") else: if flat1.ndim != 2: logger.error( "cannot make flat field correction, flat should be of " "dimension 2" ) can_process = False if flat2 is not None and flat1.shape != flat2.shape: logger.error("the tow flats provided have different shapes.") can_process = False if dark is not None and flat1 is not None and dark.shape != flat1.shape: logger.error("Given dark and flat have incoherent dimension") can_process = False if dark is not None and data.shape != dark.shape: logger.error( "Image has invalid shape. Cannot apply flat field" "correction it" ) can_process = False if can_process is False: self._notify_ffc_rsc_missing = False return data if flat2 is None: flat_value = flat1 else: # compute weight and clip it if necessary if index_proj is None: w = 0.5 else: w = (index_proj - index_flat1) / (index_flat2 - index_flat1) w = min(1, w) w = max(0, w) flat_value = flat1 * w + flat2 * (1 - w) div = flat_value - dark div[div == 0] = 1 return (data - dark) / div @property def reconstructions(self): """list of reconstruction files""" return self._reconstructions @reconstructions.setter def reconstructions(self, reconstructions): self._reconstructions = reconstructions @property def reconstruction_paths(self): return self._reconstruction_paths def add_reconstruction_path(self, path: str): self._reconstruction_paths.add(path) @property def nabu_recons_params(self): return self._nabu_params @nabu_recons_params.setter def nabu_recons_params(self, recons_params): self._nabu_params = recons_params @property def axis_params(self): return self._axis_params @axis_params.setter def axis_params(self, parameters): self._axis_params = parameters @property def saaxis_params(self): return self._saaxis_params @saaxis_params.setter def saaxis_params(self, saaxis_params): self._saaxis_params = saaxis_params @property def sa_delta_beta_params(self): return self._sa_delta_beta_params @sa_delta_beta_params.setter def sa_delta_beta_params(self, sa_delta_beta_params): self._sa_delta_beta_params = sa_delta_beta_params # TODO: change name. Should be generalized to return Dataurl def getReconstructedFilesFromParFile(self, with_index): raise NotImplementedError("Base class") def projections_with_angle(self): raise NotImplementedError("Base class") def scan_dir_name(self) -> str | None: """return name of the directory containing the acquisition""" raise NotImplementedError("Base class") def scan_basename(self) -> str | None: """return basename of the directory containing the acquisition""" raise NotImplementedError("Base class") def scan_parent_dir_basename(self) -> str | None: """return parent basename of the directory containing the acquisition""" raise NotImplementedError("Base class") @functools.lru_cache(maxsize=3) def get_opposite_projections(self, mode) -> tuple: """ Return the two best opposite projections for the required mode. """ from tomwer.core.process.reconstruction.axis.anglemode import CorAngleMode from ..process.reconstruction.axis.params import ( AxisResource, ) # avoid cyclic import radios_with_angle = copy.deepcopy(self.projections_with_angle()) def mod_angle(key: str | float) -> str | float: """ Convert angles to %360 and keep link to the value to be used later. Note: alignment scans have keys as str """ if isinstance(key, str): return key return key % 360 radios_with_angle = { mod_angle(key): value for key, value in radios_with_angle.items() } angles = numpy.array( tuple( filter( lambda a: numpy.issubdtype(type(a), numpy.number), radios_with_angle.keys(), ) ) ) mode = CorAngleMode.from_value(mode) if len(angles) < 2: logger.warning("less than two angles found. Unable to get opposite angles") return None, None initial_angle = angles[0] % 360 if mode in (CorAngleMode.use_0_180, CorAngleMode.manual_selection): couples = (initial_angle, (initial_angle + 180.0) % 360) elif mode is CorAngleMode.use_90_270: couples = ((initial_angle + 90.0) % 360, (initial_angle + 270.0) % 360) else: raise ValueError(f"{mode} is not handle") def find_nearest(angles: numpy.ndarray, angle: float): if len(angles) == 0: return None dist = numpy.abs(angles % 360 - angle) idx = dist.argmin() if isinstance(idx, numpy.ndarray): idx = idx[0] return angles[idx] nearest_c1 = find_nearest(angles=angles, angle=couples[0]) nearest_c2 = find_nearest(angles=angles, angle=couples[1]) if nearest_c1 is not None and nearest_c2 is not None: return ( AxisResource(radios_with_angle[nearest_c1], angle=nearest_c1), AxisResource(radios_with_angle[nearest_c2], angle=nearest_c2), ) else: return None, None def data_flat_field_correction( self, data: numpy.ndarray, index: int | None = None ) -> numpy.ndarray: """Apply flat field correction on the given data :param data: the data to apply correction on :param index: index of the data in the acquisition sequence :return: corrected data """ raise NotImplementedError("Base class") def to_dict(self): res = {} # nabu reconstruction parameters if self._nabu_params: res[self._DICT_NABU_RP_KEY] = ( self.nabu_recons_params if isinstance(self.nabu_recons_params, dict) else self.nabu_recons_params.to_dict() ) else: res[self._DICT_NABU_RP_KEY] = None # axis reconstruction parameters if self.axis_params is None: res[self._DICT_AXIS_KEYS] = None else: res[self._DICT_AXIS_KEYS] = self.axis_params.to_dict() # saaxis reconstruction parameters if self.saaxis_params is None: res[self._DICT_SA_AXIS_KEYS] = None else: res[self._DICT_SA_AXIS_KEYS] = self.saaxis_params.to_dict() # sa delta-beta reconstruction parameters if self._sa_delta_beta_params is None: res[self._DICT_SA_DELTA_BETA_KEYS] = None else: res[self._DICT_SA_DELTA_BETA_KEYS] = self.sa_delta_beta_params.to_dict() # dark ref if self._dark_ref_params is None: res[self._DICT_DARK_REF_KEYS] = None else: res[self._DICT_DARK_REF_KEYS] = self._dark_ref_params.to_dict() # normalization if self.intensity_normalization is None: res[self._DICT_NORMALIZATION_KEY] = None else: res[self._DICT_NORMALIZATION_KEY] = self.intensity_normalization.to_dict() return res def load_from_dict(self, desc): from tomwer.core.process.reconstruction.axis.params import ( AxisRP, ) # avoid cyclic import if isinstance(desc, io.TextIOWrapper): data = json.load(desc) else: data = desc if not ( self.DICT_PATH_KEY in data # pylint: disable=E1101 and data[self.DICT_TYPE_KEY] == self._TYPE # pylint: disable=E1101 ): raise ValueError("Description is not an EDFScan json description") assert self.DICT_PATH_KEY in data # pylint: disable=E1101 # load axis reconstruction parameters axis_params = data.get(self._DICT_AXIS_KEYS, None) if axis_params is not None: self.axis_params = AxisRP.from_dict(axis_params) # load nabu reconstruction parameters if self._DICT_NABU_RP_KEY in data: self._nabu_params = data[self._DICT_NABU_RP_KEY] # load dark-ref parameters dark_ref_params = data.get(self._DICT_DARK_REF_KEYS, None) if dark_ref_params is not None: from tomwer.core.process.reconstruction.darkref.params import DKRFRP self._dark_ref_params = DKRFRP.from_dict(dark_ref_params) # load normalization intensity_normalization = data.get(self._DICT_NORMALIZATION_KEY, None) if intensity_normalization is not None: self.intensity_normalization = IntensityNormalization.from_dict( intensity_normalization ) # load saaxis parameters saaxis_params = data.get(self._DICT_SA_AXIS_KEYS, None) if saaxis_params is not None: from tomwer.core.process.reconstruction.saaxis.params import SAAxisParams self._saaxis_params = SAAxisParams.from_dict(saaxis_params) # load sa delta beta parameters sa_delta_beta_params = data.get(self._DICT_SA_DELTA_BETA_KEYS, None) if sa_delta_beta_params is not None: from tomwer.core.process.reconstruction.sadeltabeta.params import ( SADeltaBetaParams, ) self._sa_delta_beta_params = SADeltaBetaParams.from_dict( sa_delta_beta_params ) def equal(self, other): """ :param other: instance to compare with :return: True if instance are equivalent :note: we cannot use the __eq__ function because this object need to be picklable """ return ( isinstance(other, self.__class__) or isinstance(self, other.__class__) and self.type == other.type # pylint: disable=E1101 and self.nabu_recons_params == other.nabu_recons_params and self.path == other.path # pylint: disable=E1101 ) def get_sinogram( self, line: int, subsampling: int = 1, norm_method=None, **kwargs ) -> numpy.ndarray: """ extract the sinogram from projections :param line: which sinogram we want :param subsampling: subsampling to apply on the sinogram :return: sinogram from the radio lines """ raise NotImplementedError("Base class") def get_normed_sinogram(self, line: int, subsampling: int = 1) -> numpy.ndarray: """ Util to get the sinogram normed with settings currently defined on the 'intensity_normalization' property :param line: :param subsampling: :return: """ return self.get_sinogram( line=line, subsampling=subsampling, norm_method=self.intensity_normalization.method, **self.intensity_normalization.get_extra_infos(), ) def __str__(self): raise NotImplementedError("Base class") @staticmethod def get_pyhst_recons_file(scanID): """Return the .par file used for the current reconstruction if any. Otherwise return None""" if scanID == "": return None if scanID is None: raise RuntimeError("No current acquisition to validate") assert type(scanID) is str assert os.path.isdir(scanID) folderID = os.path.basename(scanID) # look for fasttomo files ending by slice.par parFiles = glob(os.path.join(scanID + folderID) + "*_slice.par") if len(parFiles) > 0: return orderFileByLastLastModification(scanID, parFiles)[-1] else: return None def _deduce_transfert_scan(self, output_dir): """ Create the scan that will be generated if this scan is copy to the output_dir :param output_dir: """ raise NotImplementedError("Base class") def get_proj_angle_url( self, use_cache: bool = True, *args, **kwargs ) -> dict[int | str, DataUrl]: """ retrieve the url for each projections (including the alignment / return one) and associate to each (if possible) the angle. Alignment angle are set as angle (1) to specify that this is an alignment one. :param use_cache: :return: dictionary with angle (str or int) as key and url as value """ raise NotImplementedError("Base class") def get_reconstructed_slices(self) -> set[str]: """ Return a set of all the reconstructed **slices** that can be discovered for the scan (it will only look for reconstructed slices and not the volumes!!!!) slices are given as a string representing volume identifier """ from tomwer.core.process.reconstruction.output import ( PROCESS_FOLDER_RECONSTRUCTED_SLICES, ) # avoid cyclic import all_recons_ids = set() recons_paths = self.reconstruction_paths # extend set reconstruction paths to some 'default' paths. if self.working_directory is not None: # default output folder if using working directory working_dir_output_folder = os.path.join( str(self.working_directory), PROCESS_FOLDER_RECONSTRUCTED_SLICES, ) # add possible output folder: in raw_data (deprecated) raw_data_output_folder = to_raw_data_path(working_dir_output_folder) recons_paths.add(raw_data_output_folder) # add expected output folder: in processed data processed_data_output_folder = to_processed_data_path( working_dir_output_folder ) recons_paths.add(processed_data_output_folder) for path in recons_paths: all_recons_ids.update(self.get_reconstructed_slices_from_path(path)) return all_recons_ids def get_reconstructed_slices_from_path(self, path, check_url=False) -> set[str]: """ Look for some reconstructed slices at a specific position slices are given as a string representing volume identifier """ if path is None or not os.path.exists(path): return set() volumes = guess_volumes(path) or () # note: guess_volumes will find a volume only if the path fits a volume location # like a hdf5 file containing a volume or a top level EDF volume folder. # In the case path = xxx/reconstructed_slices for example it returns an empty set. if len(volumes) > 0: return set( [volume.get_identifier().to_str() for volume in guess_volumes(path)] ) elif os.path.isdir(path): # in the case the location is a folder and doesn't fit any volume # we want to look into sub folders from tomwer.core.process.reconstruction.saaxis.saaxis import ( DEFAULT_RECONS_FOLDER as MULTI_COR_DEFAULT_FOLDER, ) from tomwer.core.process.reconstruction.sadeltabeta.sadeltabeta import ( DEFAULT_RECONS_FOLDER as MULTI_DB_DEFAULT_FOLDER, ) from tomwer.core.process.reconstruction.nabu.settings import ( NABU_CFG_FILE_FOLDER, ) res = set() filtered_name = ( "steps_file_basename_nabu_sinogram_save_step", MULTI_COR_DEFAULT_FOLDER, MULTI_DB_DEFAULT_FOLDER, NABU_CFG_FILE_FOLDER, ) # filter files that we already know they won't contain any reconstructed volume sub_files = filter( lambda name: name not in filtered_name, os.listdir(path), ) for f in sub_files: current_path = os.path.join(path, f) res.update( self.get_reconstructed_slices_from_path( path=current_path, check_url=check_url ) ) return res return set() @property def latest_reconstructions(self): """List of latest slices reconstructions (as VolumeIdentifier) - single slice volume""" return self._latest_reconstructions @property def latest_vol_reconstructions(self): """List of latest volume reconstructions (as VolumeIdentifier)""" return self._latest_vol_reconstructions def clear_latest_reconstructions(self): self._latest_reconstructions = [] def set_latest_reconstructions(self, urls: Iterable): if urls is None: self._latest_reconstructions = None else: self._latest_reconstructions = list( [self._process_volume_url(url) for url in urls] ) def add_latest_reconstructions(self, urls: Iterable): self._latest_reconstructions.extend(urls) def clear_latest_vol_reconstructions(self): self._latest_vol_reconstructions = [] @staticmethod def _process_volume_url(url): if isinstance(url, str): return VolumeIdentifier.from_str(url) elif isinstance(url, VolumeIdentifier): return url elif isinstance(url, VolumeBase): return url.get_identifier() else: raise TypeError( f"url should be a {VolumeIdentifier} or a string reprenseting a {VolumeIdentifier}. {type(url)} provided instead" ) def set_latest_vol_reconstructions(self, volume_identifiers: Iterable | None): volume_identifiers = volume_identifiers or tuple() self._latest_vol_reconstructions = list( [self._process_volume_url(url) for url in volume_identifiers] ) def add_latest_vol_reconstructions(self, volume_identifiers: tuple): assert isinstance( volume_identifiers, tuple ), "volume_identifiers is expected to be a tuple" self._latest_vol_reconstructions.extend( self._process_volume_url(volume_identifier) for volume_identifier in volume_identifiers ) def _update_latest_recons_identifiers(self, old_path, new_path): def update_identifier(identifier): assert isinstance( identifier, BaseIdentifier ), f"identifier is expected to be an instance of {BaseIdentifier}" # small hack as this is not much used: simply try to replace a path by another. this is only used by the data transfer and EDF / SPEC # this time is almost over # FIXME: correct way to do this would be to recreate the volume, modify file or folder path and # recreate the new identifier identifier.replace(old_path, new_path, 1) self._latest_reconstructions = [ update_identifier(identifier=identifier) for identifier in self._latest_reconstructions ] self._latest_vol_reconstructions = [ update_identifier(identifier=identifier) for identifier in self._latest_vol_reconstructions ] def get_url_proj_index(self, url): """Return the index in the acquisition from the url""" def invert_dict(ddict): res = {} if ddict is not None: for key, value in ddict.items(): assert isinstance(value, DataUrl) res[value.path()] = key return res proj_inv_url_to_index = invert_dict(self.projections) # pylint: disable=E1101 alig_inv_url_to_index = invert_dict( self.alignment_projections # pylint: disable=E1101 ) if url.path() in proj_inv_url_to_index: return proj_inv_url_to_index[url.path()] elif url.path() in alig_inv_url_to_index: return alig_inv_url_to_index[url.path()] else: return None def get_nabu_dataset_info(self, binning=1, binning_z=1, proj_subsampling=1) -> dict: """ :return: nabu dataset descriptor """ raise NotImplementedError("Base class") def to_nabu_dataset_analyser(self): """Return the equivalent DatasetAnalyzer for nabu""" raise NotImplementedError("Base class") def get_proposal_name(self) -> str | None: return self._proposal_name def set_proposal_name(self, proposal_name: str) -> None: self._proposal_name = proposal_name class _TomwerBaseDock(object): """ Internal class to make difference between a simple TomoBase output and an output for a different processing (like scanvalidator.UpdateReconsParam) """ def __init__(self, tomo_instance): self.__instance = tomo_instance @property def instance(self): return self.__instance def _containsDigits(input_): return any(char.isdigit() for char in input_) class NormMethod(_Enum): MANUAL_ROI = "manual ROI" AUTO_ROI = "automatic ROI" DATASET = "from dataset" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/scan/scanfactory.py0000644000175000017500000002163415153325210021072 0ustar00paynopaynofrom __future__ import annotations import glob import logging import os from urllib.parse import urlparse import h5py from tomoscan.esrf.identifier.url_utils import split_path from tomoscan.factory import Factory as _oScanFactory from tomoscan.identifier import BaseIdentifier, ScanIdentifier, VolumeIdentifier from tomoscan.scanbase import TomoScanBase from tomoscan.tomoobject import TomoObject from nxtomo.application.nxtomo import NXtomo from tomwer.utils import docstring from .blissscan import BlissScan from .edfscan import EDFTomoScan, EDFTomoScanIdentifier from .hdf5scan import NXtomoScan, NXtomoScanIdentifier _logger = logging.getLogger(__name__) @docstring(_oScanFactory) class ScanFactory(object): @docstring(_oScanFactory.create_scan_object) @staticmethod def create_tomo_object_from_identifier( identifier: str | BaseIdentifier, ) -> TomoObject: """ Create an instance of TomoScanBase from his identifier if possible :param identifier: identifier of the TomoScanBase :raises: TypeError if identifier is not a str :raises: ValueError if identifier cannot be converted back to an instance of TomoScanBase """ from tomoscan.identifier import BaseIdentifier as _TomoScanIdentifier if not isinstance(identifier, (str, BaseIdentifier, _TomoScanIdentifier)): raise TypeError( f"identifier is expected to be a str or an instance of {BaseIdentifier} not {type(identifier)}" ) # step 1: convert identifier to an instance of BaseIdentifier if necessary if isinstance(identifier, str): info = urlparse(identifier) paths = split_path(info.path) scheme = info.scheme if len(paths) == 1: # insure backward compatibility. Originally (until 0.8) there was only one type which was scan tomo_type = ScanIdentifier.TOMO_TYPE elif len(paths) == 2: tomo_type, _ = paths else: raise ValueError("Failed to parse path string:", info.path) if tomo_type == VolumeIdentifier.TOMO_TYPE: raise ValueError("This factory creates scan object and not volumes") elif tomo_type == ScanIdentifier.TOMO_TYPE: # otherwise consider this is a scan. Insure backward compatibility if scheme == "edf": identifier = EDFTomoScanIdentifier.from_str(identifier=identifier) elif scheme == "hdf5": identifier = NXtomoScanIdentifier.from_str(identifier=identifier) else: raise ValueError(f"Scheme {scheme} not recognized") else: raise ValueError(f"{tomo_type} is not an handled tomo type") # step 2: convert identifier to a TomoBaseObject assert isinstance(identifier, BaseIdentifier) scheme = identifier.scheme tomo_type = identifier.tomo_type if scheme == "edf": if tomo_type == ScanIdentifier.TOMO_TYPE: return EDFTomoScan.from_identifier(identifier=identifier) else: raise NotImplementedError() elif scheme == "hdf5": if tomo_type == ScanIdentifier.TOMO_TYPE: return NXtomoScan.from_identifier(identifier=identifier) else: raise NotImplementedError() else: raise ValueError(f"Scheme {scheme} not recognized") @staticmethod def create_scan_object( scan_path: str, entry: str | None = None, accept_bliss_scan: bool = False ) -> TomoScanBase: """ :param scan_path: path to the scan directory or file :param entry: entry on the file. Requested for hdf5 files :param accept_bliss_scan: if True the factory can return some BlissScan But this is only compatible with the Tomomill processing. :return: TomwerScanBase instance fitting the scan folder or scan path :raises: ValueError if scan_path is not containing a scan """ if scan_path is None: raise ValueError("'scan_path' should be provided") if entry is not None and not entry.startswith("/"): entry = "/" + entry if os.path.isfile(scan_path) and ScanFactory.is_hdf5_tomo(scan_path): valid_entries = NXtomo.get_valid_entries(scan_path) if entry is None: if len(valid_entries) > 1: _logger.warning( "more than one entry found for %s." "Pick the last entry" % scan_path ) entry = valid_entries[-1] elif entry not in valid_entries: raise ValueError( f"entry {entry} is invalid. Does it exists ? Is the " f"file NXTomo compliant ?. Valid entry are {valid_entries}" ) return NXtomoScan(scan=scan_path, entry=entry) elif ScanFactory.is_edf_tomo(scan_path): return EDFTomoScan(scan=scan_path) elif accept_bliss_scan and BlissScan.is_bliss_file(scan_path): if entry is None: valid_entries = BlissScan.get_valid_entries(scan_path) if len(valid_entries) > 1: _logger.warning( f"more than one entry found for {scan_path}. Pick the last entry" ) entry = valid_entries[-1] return BlissScan(master_file=scan_path, entry=entry, proposal_file=None) raise ValueError(f"Unable to generate a scan object from {scan_path}") @docstring(_oScanFactory.create_scan_objects) @staticmethod def create_scan_objects(scan_path, accept_bliss_scan=True) -> tuple: scan_path = scan_path.rstrip(os.path.sep) if EDFTomoScan.is_tomoscan_dir(scan_path): return (EDFTomoScan(scan=scan_path),) elif NXtomoScan.is_tomoscan_dir(scan_path): scans = [] master_file = NXtomoScan.get_master_file(scan_path=scan_path) entries = NXtomo.get_valid_entries(master_file) for entry in entries: scans.append(NXtomoScan(scan=scan_path, entry=entry, index=None)) return tuple(scans) elif accept_bliss_scan and BlissScan.is_bliss_file(scan_path): scans = [] for entry in BlissScan.get_valid_entries(scan_path): scans.append( BlissScan(master_file=scan_path, entry=entry, proposal_file=None) ) return tuple(scans) return tuple() @staticmethod def mock_scan(type_="edf"): """Mock a scan structure which is not associated to any real acquistion""" if type_ == "edf": return EDFTomoScan(scan=None) else: raise NotImplementedError("Other TomoScan are not defined yet") @staticmethod def create_scan_object_frm_dict(_dict): if TomoScanBase.DICT_TYPE_KEY not in _dict: raise ValueError( f"given dict is not recognized. Cannot find {TomoScanBase.DICT_TYPE_KEY}" ) elif _dict[TomoScanBase.DICT_TYPE_KEY] == EDFTomoScan._TYPE: return EDFTomoScan(scan=None).load_from_dict(_dict) elif _dict[TomoScanBase.DICT_TYPE_KEY] == NXtomoScan._TYPE: return NXtomoScan.from_dict(_dict) else: raise ValueError( f"Scan type {_dict[TomoScanBase.DICT_TYPE_KEY]} is not managed" ) @staticmethod def is_tomo_scandir(scan_path: str) -> bool: """ :param scan_path: path to the scan directory or file :return: True if the given path / file is a tomo_scandir. For now yes by default """ return True @staticmethod def is_edf_tomo(scan_path: str) -> bool: """ :param scan_path: path to the scan directory or file :return: True if given path define a tomo scan based on .edf file """ if scan_path and os.path.isdir(scan_path): file_basename = os.path.basename(scan_path) has_info_file = ( len(glob.glob(os.path.join(scan_path, file_basename + "*.info"))) > 0 ) not_lbs_scan_path = scan_path.replace("lbsram", "", 1) has_notlbsram_info_file = ( len( glob.glob(os.path.join(not_lbs_scan_path, file_basename + "*.info")) ) > 0 ) if has_info_file or has_notlbsram_info_file: return True return False @staticmethod def is_hdf5_tomo(scan_path): """ :param scan_path: :return: """ if os.path.isfile(scan_path): return h5py.is_hdf5(scan_path) else: return NXtomoScan.directory_contains_scan(scan_path) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/core/scan/scantype.py0000644000175000017500000000017615115744275020420 0ustar00paynopaynofrom enum import Enum as _Enum class ScanType(_Enum): BLISS = "bliss-hdf5" SPEC = "spec-edf" NX_TOMO = "NXtomo" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9291012 tomwer-1.6.17/src/tomwer/core/scan/tests/0000755000175000017500000000000015153325403017344 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/scan/tests/__init__.py0000644000175000017500000000000014757047403021455 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/core/scan/tests/test_edf.py0000644000175000017500000000151015143647637021527 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.utils.scanutils import MockEDF def test_scan_dir(tmpdir): full_path = os.path.join(tmpdir, "my", "aquisition", "folder") MockEDF.fastMockAcquisition(full_path) scan = EDFTomoScan(full_path) assert scan.scan_dir_name() == "folder" assert scan.scan_basename() == full_path def test_working_directory(): """test behavior of the working directory function""" scan = EDFTomoScan(scan=None) assert scan.working_directory is None scan = EDFTomoScan(scan="my_folder") assert str(scan.working_directory) == os.path.abspath("my_folder") scan = EDFTomoScan(scan="/full/path/to/my/folder") assert str(scan.working_directory) == os.path.abspath("/full/path/to/my/folder") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/scan/tests/test_future_scan.py0000644000175000017500000000152115153325210023266 0ustar00paynopayno# coding: utf-8 """Unit test for the scan defined at the hdf5 format""" from __future__ import annotations import asyncio import os from tomwer.core.futureobject import FutureTomwerObject from tomwer.core.utils.scanutils import MockNXtomo def test_simple_future_tomo_obj(tmpdir): """Simple test of the FutureTomwerScan API""" scan = MockNXtomo( scan_path=os.path.join(tmpdir, "scan_test"), n_proj=10, n_ini_proj=10, create_ini_dark=False, create_ini_flat=False, dim=10, ).scan future = asyncio.Future() future.set_result(None) future_tomo_obj = FutureTomwerObject( tomo_obj=scan, futures=[ future, ], ) future_tomo_obj.results() assert future_tomo_obj.exceptions() is None assert future_tomo_obj.cancelled() is False ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/scan/tests/test_nxtomoscan.py0000644000175000017500000001123615153325210023145 0ustar00paynopaynoimport os import shutil import numpy from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.utils.scanutils import MockNXtomo from tomwer.tests.datasets import TomwerCIDatasets from tomwer.core.volume.hdf5volume import HDF5Volume from tomwer.core.volume.edfvolume import EDFVolume from tomwer.core.process.reconstruction.output import ( PROCESS_FOLDER_RECONSTRUCTED_SLICES, ) from nxtomomill.converter.hdf5.utils import PROCESSED_DATA_DIR_NAME, RAW_DATA_DIR_NAME def test_scan_dir(tmp_path): """test result of NxtomoScan.scan_dir_name is correct""" tmp_dir = tmp_path / "frm_edftomomill_twoentries_dataset" tmp_dir.mkdir() tmp_dir = str(tmp_dir) dataset_file = os.path.join(tmp_dir, "frm_edftomomill_twoentries.nx") shutil.copyfile( TomwerCIDatasets.get_dataset( "h5_datasets/frm_edftomomill_twoentries.nx", ), dataset_file, ) assert os.path.isfile(dataset_file) scan = NXtomoScan(scan=dataset_file, entry="entry0000") assert scan.scan_dir_name() == tmp_dir.split(os.sep)[-1] def test_flat_field_interval(tmp_path): """test the call to ff_interval""" tmp_dir = tmp_path / "test_flat_field_interval" scan_path = os.path.join(tmp_dir, "my_scan_1") scan_1 = MockNXtomo( scan_path=scan_path, n_ini_proj=20, n_proj=20, n_alignement_proj=2, create_final_flat=True, create_ini_dark=True, create_ini_flat=True, n_refs=5, ).scan numpy.testing.assert_equal(scan_1.ff_interval, 20) scan_path2 = os.path.join(tmp_dir, "my_scan_2") scan_2 = MockNXtomo( scan_path=scan_path2, n_ini_proj=10, n_proj=10, n_alignement_proj=2, create_final_flat=False, create_ini_dark=True, create_ini_flat=True, n_refs=1, ).scan numpy.testing.assert_equal(scan_2.ff_interval, 0) def test_working_directory(): """test behavior of the working directory function""" scan = NXtomoScan(scan=None, entry="my_entry") assert scan.working_directory is None scan = NXtomoScan(scan="/full/path/my_file.sh", entry="my_entry") assert str(scan.working_directory) == os.path.abspath("/full/path") scan = NXtomoScan(scan="my_file.sh", entry="my_entry") assert str(scan.working_directory) == os.path.abspath(".") def test_get_reconstructions_slices(tmp_path): """test NXtomoscan.get_reconstruction_urls and make sure all related scan can be found from a scan (as long as they are stored at a 'searched' location) """ test_dir = tmp_path / "test_get_reconstructions_urls" test_dir.mkdir() raw_data_dir = test_dir / RAW_DATA_DIR_NAME / "frm_edftomomill_twoentries" raw_data_dir.mkdir(parents=True) processed_data_dir = ( test_dir / PROCESSED_DATA_DIR_NAME / "frm_edftomomill_twoentries" ) processed_data_dir.mkdir(parents=True) third_path_dir = test_dir / "third_part" third_path_dir.mkdir(parents=True) output_file_path = os.path.join(raw_data_dir, "frm_edftomomill_twoentries.nx") shutil.copyfile( TomwerCIDatasets.get_dataset( "h5_datasets/frm_edftomomill_twoentries.nx", ), output_file_path, ) scan = NXtomoScan( scan=output_file_path, entry="entry0000", ) assert str(scan.working_directory) == str(raw_data_dir) assert os.path.exists(output_file_path) # create a edf volume in PROCESSED_DATA data = numpy.linspace(start=0, stop=100, num=100).reshape( # pylint: disable=E1121 1, 10, 10 ) edf_volume = EDFVolume( folder=os.path.join( raw_data_dir, PROCESS_FOLDER_RECONSTRUCTED_SLICES, ), volume_basename="frm_edftomomill_twoentries_slice", data=data, ) edf_volume.save() # create an hdf5 volume in RAW_DATA hdf5_volume = HDF5Volume( file_path=os.path.join( processed_data_dir, PROCESS_FOLDER_RECONSTRUCTED_SLICES, "frm_edftomomill_twoentries_slice.h5", ), data_path="/entry0000", data=data, ) hdf5_volume.save() # create a third hdf5 volume in 'third_part_dir' third_part_volume = HDF5Volume( file_path=os.path.join( third_path_dir, PROCESS_FOLDER_RECONSTRUCTED_SLICES, "frm_edftomomill_twoentries_slice.h5", ), data_path="entry0000", data=data, ) third_part_volume.save() reconstructions_urls = scan.get_reconstructed_slices() assert len(reconstructions_urls) == 2 assert edf_volume.get_identifier().to_str() in reconstructions_urls assert hdf5_volume.get_identifier().to_str() in reconstructions_urls ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/scan/tests/test_scan.py0000644000175000017500000002770415153325210021707 0ustar00paynopaynoimport contextlib import logging import os import shutil import tempfile import unittest import fabio.edfimage import numpy from tomwer.core.process.reconstruction.nabu import nabuslices from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils.scanutils import MockEDF from tomwer.tests.datasets import TomwerCIDatasets logging.disable(logging.INFO) class TestScanFactory(unittest.TestCase): """Make sure the Scan factory is correctly working. Able to detect the valid scan type for a given file / directory """ def test_no_scan(self): scan_dir = tempfile.mkdtemp() with self.assertRaises(ValueError): ScanFactory.create_scan_object(scan_dir) def test_scan_edf(self): scan_dir = TomwerCIDatasets.get_dataset( "edf_datasets/test10", ) scan = ScanFactory.create_scan_object(scan_dir) self.assertTrue(isinstance(scan, EDFTomoScan)) class TestScanValidatorFindNabuFiles(unittest.TestCase): """ Make sure files produced by nabu can be seen as reconstruction files """ class FileCreator(contextlib.AbstractContextManager): def __init__(self, file_path): self.__file_path = file_path def __enter__(self): with open(self.__file_path, "w"): pass def __exit__(self, exc_type, exc_val, exc_tb): if os.path.exists(self.__file_path): os.remove(self.__file_path) def setUp(self) -> None: self.scan = MockEDF.mockScan(tempfile.mkdtemp(), nPagRecons=0, nRecons=0) assert ( len(self.scan.get_reconstructions_paths(self.scan.path)) == 0 ), "make sure the initial environment is clear" def tearDown(self) -> None: shutil.rmtree(self.scan.path) def test(self) -> None: for slice_index in (None, 1, 15): for delta_beta in (None, 100, 500): for pag in (True, False): for ctf in (True, False): file_name = nabuslices.SingleSliceRunner.get_file_basename_reconstruction( slice_index=slice_index, scan=self.scan, pag=pag if delta_beta is not None else False, ctf=ctf if delta_beta is not None else False, db=delta_beta, axis="XY", ) with self.subTest( slice_index=slice_index, pag_db=delta_beta, ): file_path = os.path.join( self.scan.path, file_name + ".hdf5" ) # simple context Manager which create the file # and remove it when leave with TestScanValidatorFindNabuFiles.FileCreator(file_path): n_to_discover = 1 if slice_index is None: n_to_discover = 0 self.assertEqual( len( self.scan.get_reconstructions_paths( self.scan.path ) ), n_to_discover, ) class TestScanValidatorFindPyHSTFiles(unittest.TestCase): """Function testing the getReconstructionsPaths function is correctly functioning""" DIM_MOCK_SCAN = 10 N_RADIO = 20 N_RECONS = 10 N_PAG_RECONS = 5 def setUp(self): # create scan folder self.path = tempfile.mkdtemp() MockEDF.mockScan( scanID=self.path, nRadio=self.N_RADIO, nRecons=self.N_RECONS, nPagRecons=self.N_PAG_RECONS, dim=self.DIM_MOCK_SCAN, ) basename = os.path.basename(self.path) # add some random files for _file in ("45gfdgfg1.edf", "465slicetest1.edf", "slice_ab.edf"): with open(os.path.join(self.path, basename + _file), "w+") as ofile: ofile.write("test") def tearDown(self): if os.path.isdir(self.path): shutil.rmtree(self.path) def testGetRadioPaths(self): nFound = len(EDFTomoScan.get_proj_urls(self.path)) self.assertTrue(nFound == self.N_RADIO) def testGetReconstructionsPaths(self): reconstruction_found = EDFTomoScan.get_reconstructions_paths(self.path) self.assertEqual(len(reconstruction_found), self.N_RECONS + self.N_PAG_RECONS) def testGetSliceReconstruction(self): self.assertTrue( EDFTomoScan.get_index_reconstructed("dfadf_slice_32.edf", "dfadf") == 32 ) self.assertTrue( EDFTomoScan.get_index_reconstructed("dfadf_slice_slice_002.edf", "dfadf") == 2 ) self.assertTrue( EDFTomoScan.get_index_reconstructed("scan_3slice_0050.edf", "scan_3") == 50 ) self.assertTrue( EDFTomoScan.get_index_reconstructed("scan3slice_012.edf", "scan3") == 12 ) class TestRadioPath(unittest.TestCase): """Test static method getRadioPaths for EDFTomoScan""" def test(self): files = [ "essai1_0008.edf", "essai1_0019.edf", "essai1_0030.edf", "essai1_0041.edf", "essai1_0052.edf", "essai1_0063.edf", "essai1_0074.edf", "essai1_0085.edf", "essai1_0096.edf", "essai1_.par", "refHST0100.edf", "darkend0000.edf", "essai1_0009.edf", "essai1_0020.edf", "essai1_0031.edf", "essai1_0042.edf", "essai1_0053.edf", "essai1_0064.edf", "essai1_0075.edf", "essai1_0086.edf", "essai1_0097.edf", "essai1_.rec", "essai1_0000.edf", "essai1_0010.edf", "essai1_0021.edf", "essai1_0032.edf", "essai1_0043.edf", "essai1_0054.edf", "essai1_0065.edf", "essai1_0076.edf", "essai1_0087.edf", "essai1_0098.edf", "essai1_slice_1023.edf", "essai1_0001.edf", "essai1_0011.edf", "essai1_0022.edf", "essai1_0033.edf", "essai1_0044.edf", "essai1_0055.edf", "essai1_0066.edf", "essai1_0077.edf", "essai1_0088.edf", "essai1_0099.edf", "essai1_slice.info", "essai1_0001.par", "essai1_0012.edf", "essai1_0023.edf", "essai1_0034.edf", "essai1_0045.edf", "essai1_0056.edf", "essai1_0067.edf", "essai1_0078.edf", "essai1_0089.edf", "essai1_0100.edf", "essai1_slice.par", "essai1_0002.edf", "essai1_0013.edf", "essai1_0024.edf", "essai1_0035.edf", "essai1_0046.edf", "essai1_0057.edf", "essai1_0068.edf", "essai1_0079.edf", "essai1_0090.edf", "essai1_0101.edf", "essai1_slice.xml", "essai1_0003.edf", "essai1_0014.edf", "essai1_0025.edf", "essai1_0036.edf", "essai1_0047.edf", "essai1_0058.edf", "essai1_0069.edf", "essai1_0080.edf", "essai1_0091.edf", "essai1_0102.edf", "essai1_.xml", "essai1_0004.edf", "essai1_0015.edf", "essai1_0026.edf", "essai1_0037.edf", "essai1_0048.edf", "essai1_0059.edf", "essai1_0070.edf", "essai1_0081.edf", "essai1_0092.edf", "essai1_0103.edf", "histogram_essai1_slice", "essai1_0005.edf", "essai1_0016.edf", "essai1_0027.edf", "essai1_0038.edf", "essai1_0049.edf", "essai1_0060.edf", "essai1_0071.edf", "essai1_0082.edf", "essai1_0093.edf", "essai1_0104.edf", "machinefile", "essai1_0006.edf", "essai1_0017.edf", "essai1_0028.edf", "essai1_0039.edf", "essai1_0050.edf", "essai1_0061.edf", "essai1_0072.edf", "essai1_0083.edf", "essai1_0094.edf", "essai1_.cfg", "pyhst_out.txt", "essai1_0007.edf", "essai1_0018.edf", "essai1_0029.edf", "essai1_0040.edf", "essai1_0051.edf", "essai1_0062.edf", "essai1_0073.edf", "essai1_0084.edf", "essai1_0095.edf", ] nbRadio = 0 for f in files: nbRadio += EDFTomoScan.is_a_proj_path(f, "essai1_") self.assertTrue(nbRadio == 105) class TestGetReconstructionPath(unittest.TestCase): """Test static method getReconstructionPaths for EDFTomoScan""" def setUp(self): self.tmpDir = tempfile.mkdtemp() self.dir = os.path.join(self.tmpDir, "scan_3") os.makedirs(self.dir) def tearDown(self): shutil.rmtree(self.tmpDir) def test1(self): """Make sure he can read 3 simple slice""" file_desc = fabio.edfimage.EdfImage(data=numpy.random.random((100, 100))) file_desc.write(os.path.join(self.dir, "scan_3slice_0050.edf")) file_desc.write(os.path.join(self.dir, "scan_3slice_0000.edf")) file_desc.write(os.path.join(self.dir, "scan_3slice_0010.edf")) assert len(os.listdir(self.dir)) == 3 self.assertEqual( len( EDFTomoScan.get_reconstructions_paths( os.path.join(self.tmpDir, "scan_3") ) ), 3, ) def test2(self): """Make sure he can read a paganin and non-paganin at the same time""" file_desc = fabio.edfimage.EdfImage(data=numpy.random.random((100, 100))) file_desc.write(os.path.join(self.dir, "scan_3slice_0050.edf")) file_desc.write(os.path.join(self.dir, "scan_3slice_pag_0050.edf")) assert len(os.listdir(self.dir)) == 2 self.assertEqual( len( EDFTomoScan.get_reconstructions_paths( os.path.join(self.tmpDir, "scan_3") ) ), 2, ) class TestPaganinPath(unittest.TestCase): """Test static method getIndexReconstructed from EDFTomoScan""" def setUp(self): self.tmpDir = tempfile.mkdtemp() self.dir = os.path.join(self.tmpDir, "scan25") os.makedirs(self.dir) def tearDown(self): shutil.rmtree(self.tmpDir) def testPagFile(self): open(os.path.join(self.dir, "scan25slice_pag_db0500_0115.edf"), "a").close() self.assertEqual(len(EDFTomoScan.get_reconstructions_paths(self.dir)), 1) self.assertEqual( EDFTomoScan.get_index_reconstructed( "scan25slice_pag_db0500_0115.edf", scanID=self.dir ), 115, ) def test_get_sinogram(tmp_path): edf_scan_folder = tmp_path / "scan_dir" os.makedirs(edf_scan_folder, exist_ok=True) mock = MockEDF( scan_path=edf_scan_folder, scene="arange", n_radio=4, n_ini_radio=4, dim=2 ) mock.end_acquisition() scan = EDFTomoScan(scan=mock.scan_path) assert len(scan.projections) == 4 assert scan.tomo_n == 4 sinogram_1 = scan.get_sinogram(line=1) assert sinogram_1.shape == (4, 2) numpy.testing.assert_array_equal( sinogram_1, numpy.array([[2, 3], [6, 7], [10, 11], [14, 15]]), ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/settings.py0000644000175000017500000000762515153325210017476 0ustar00paynopaynoimport os from enum import Enum as _Enum __LBSRAM_PATH = "/lbsram" __DEST_PATH = "" MOCK_LBSRAM = False MAX_MEM_USED = 80 "Maximal percentage of used memory from which we should skip some processing" MAKE_OAR_PYST2_PATH = "/data/id19/inhouse/OAR_UTILITIES/pyhst/make_oar_pyhst2" """path to the make_oar_pyhst2 path""" JSON_RPC_HOST = None """you specify an host name. If None is provided then will use HOSTNAME""" JSON_RPC_PORT = 4000 TOMO_BEAMLINES = sorted( ("bm05", "bm18", "id11", "id15a", "id16a", "id16b", "id17", "id19") ) def mock_lsbram(b): assert type(b) is bool global MOCK_LBSRAM MOCK_LBSRAM = b def isOnLbsram(scan=None): if MOCK_LBSRAM: return True elif scan is None: return os.path.isdir(get_lbsram_path()) else: if isinstance(scan, str): return os.path.abspath(scan).startswith(__LBSRAM_PATH) else: return os.path.abspath(scan.path).startswith(__LBSRAM_PATH) def get_lbsram_path(): return __LBSRAM_PATH def get_dest_path(): return __DEST_PATH def _set_lbsram_path(path): global __LBSRAM_PATH __LBSRAM_PATH = path def _set_dest_path(path): global __DEST_PATH __DEST_PATH = path class SlurmSettingsMode(_Enum): MANUAL = "manual" GENERIC = "generic" CAST_VOLUME = "cast_volume" SLICE_RECONSTRUCTION = "slice_reconstruction" VOLUME_RECONSTRUCTION = "volume_reconstruction" STITCHING = "stitching" @staticmethod def get_settings_class(mode): assert isinstance(mode, SlurmSettingsMode) if mode is SlurmSettingsMode.MANUAL: return None elif mode is SlurmSettingsMode.GENERIC: return SlurmSettings elif mode is SlurmSettingsMode.CAST_VOLUME: return DefaultSlurmSettingsCastVolume elif mode is SlurmSettingsMode.SLICE_RECONSTRUCTION: return DefaultSlurmSettingsSliceReconstruction elif mode is SlurmSettingsMode.VOLUME_RECONSTRUCTION: return DefaultSlurmSettingsVolumeReconstruction elif mode is SlurmSettingsMode.STITCHING: return DefaultSlurmSettingsStitching else: raise ValueError(f"{mode} not handled") class SlurmSettings: # Default slurm cluster configuration N_CORES_PER_TASK = 16 """Number of CPU per worker""" N_TASKS = 1 """Number of worker""" N_JOBS = 1 """on how many job we want to split the EwoksTask""" MEMORY_PER_WORKER = 128 # memory in GB """Amount of memory per worker""" PARTITION = "gpu" """Queue / partition to use""" DEFAULT_WALLTIME = "01:00:00" # None if the default wall time N_GPUS_PER_WORKER = 1 """number of gpu per worker""" PYTHON_VENV = None """Python executable to take. Useful if compute nodes have a different environment from the front end. """ PROJECT_NAME = "tomwer_{scan}_-_{process}_-_{info}" """Slurm cluster project name. `scan`, `process` and `info` will be format. """ MODULES_TO_LOAD = ("tomotools/stable",) SBATCH_EXTRA_PARAMS = { "export": "ALL", # value to provide to sbatch --export={} } class DefaultSlurmSettingsCastVolume(SlurmSettings): """ default proposed configuration for casting a volume remotely """ N_JOBS = 1 N_GPUS_PER_WORKER = 0 MEMORY_PER_WORKER = 128 # memory in GB PARTITION = "nice-long" class DefaultSlurmSettingsSliceReconstruction(SlurmSettings): """ default proposed configuration for reconstructing a single slice remotely """ N_JOBS = 1 N_GPUS_PER_WORKER = 1 MEMORY_PER_WORKER = 220 # memory in GB class DefaultSlurmSettingsVolumeReconstruction(DefaultSlurmSettingsSliceReconstruction): pass class DefaultSlurmSettingsStitching(SlurmSettings): """ default proposed configuration for stitching """ N_CORES_PER_TASK = 1 N_JOBS = 16 N_GPUS_PER_WORKER = 0 PARTITION = "nice-long" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/signal.py0000644000175000017500000001374314757047403017127 0ustar00paynopayno# coding: utf-8 # This file come from the django project (https://github.com/django/django) and # distributed under the BSD license ########################################################################### # Copyright (c) Django Software Foundation and individual contributors. # All rights reserved. # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # 1. Redistributions of source code must retain the above copyright notice, # this list of conditions and the following disclaimer. # # 2. Redistributions in binary form must reproduce the above copyright # notice, this list of conditions and the following disclaimer in the # documentation and/or other materials provided with the distribution. # # 3. Neither the name of Django nor the names of its contributors may be used # to endorse or promote products derived from this software without # specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # ############################################################################# __author__ = "Dhruv Govil" __copyright__ = "Copyright 2016, Dhruv Govil" __credits__ = [ "Dhruv Govil", "John Hood", "Jason Viloria", "Adric Worley", "Alex Widener", ] __license__ = "MIT" __version__ = "1.1.1" __maintainer__ = "Dhruv Govil" __email__ = "dhruvagovil@gmail.com" __status__ = "Beta" __date__ = "09/01/2018" import inspect import weakref from functools import partial class Signal(object): """ The Signal is the core object that handles connection and emission . .. warning: This intends to work only for Signal/Slot executed in the same thread. """ def __init__(self, *arg_types): super(Signal, self).__init__() self._block = False self._slots = [] self._arguments_types = arg_types def emit(self, *args, **kwargs): """ Calls all the connected slots with the provided args and kwargs unless block is activated """ if self._block: return for slot in self._slots: if not slot: continue elif isinstance(slot, partial): slot() elif isinstance(slot, weakref.WeakKeyDictionary): # For class methods, get the class object and call the method accordingly. for obj, method in slot.items(): method(obj, *args, **kwargs) elif isinstance(slot, weakref.ref): # If it's a weakref, call the ref to get the instance and then call the func # Don't wrap in try/except so we don't risk masking exceptions from the actual func call if slot() is not None: slot()(*args, **kwargs) else: # Else call it in a standard way. Should be just lambdas at this point slot(*args, **kwargs) def connect(self, slot): """ Connects the signal to any callable object """ if not callable(slot): raise ValueError( "Connection to non-callable '%s' object failed" % slot.__class__.__name__ ) if isinstance(slot, partial) or "<" in slot.__name__: # If it's a partial or a lambda. The '<' check is the only py2 and py3 compatible way I could find if slot not in self._slots: self._slots.append(slot) elif inspect.ismethod(slot): # Check if it's an instance method and store it with the instance as the key slotSelf = slot.__self__ slotDict = weakref.WeakKeyDictionary() slotDict[slotSelf] = slot.__func__ if slotDict not in self._slots: self._slots.append(slotDict) else: # If it's just a function then just store it as a weakref. newSlotRef = weakref.ref(slot) if newSlotRef not in self._slots: self._slots.append(newSlotRef) def disconnect(self, slot): """ Disconnects the slot from the signal """ if not callable(slot): return if inspect.ismethod(slot): # If it's a method, then find it by its instance slotSelf = slot.__self__ for s in self._slots: if ( isinstance(s, weakref.WeakKeyDictionary) and (slotSelf in s) and (s[slotSelf] is slot.__func__) ): self._slots.remove(s) break elif isinstance(slot, partial) or "<" in slot.__name__: # If it's a partial or lambda, try to remove directly try: self._slots.remove(slot) except ValueError: pass else: # It's probably a function, so try to remove by weakref try: self._slots.remove(weakref.ref(slot)) except ValueError: pass def clear(self): """Clears the signal of all connected slots""" self._slots = [] def block(self, isBlocked): """Sets blocking of the signal""" self._block = bool(isBlocked) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9291012 tomwer-1.6.17/src/tomwer/core/tests/0000755000175000017500000000000015153325403016420 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/tests/__init__.py0000644000175000017500000000000014757047403020531 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/tests/test_scanutils.py0000644000175000017500000000151414757047403022051 0ustar00paynopayno# coding: utf-8 import os import tempfile import unittest from nxtomo.application.nxtomo import NXtomo from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.utils.scanutils import MockNXtomo class TestMockNXtomo(unittest.TestCase): """Test the MockNXtomo file""" def test_creation(self): folder = tempfile.mkdtemp() mock = MockNXtomo(scan_path=folder, n_proj=10, n_ini_proj=10) self.assertEqual( mock.scan_master_file, os.path.join(folder, os.path.basename(folder) + ".h5"), ) tomoScan = NXtomoScan(mock.scan_path, entry=mock.scan_entry) self.assertEqual(len(NXtomo.get_valid_entries(mock.scan_master_file)), 1) tomoScan.update() self.assertEqual(tomoScan.scan_range, 360) self.assertEqual(len(tomoScan.projections), 10) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/tests/test_utils.py0000644000175000017500000002220515153325210021166 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import shutil import tempfile import unittest import numpy from tomwer.core.utils import spec as spec_utils from tomwer.core.utils.normalization import flatFieldCorrection from tomwer.core.utils.scanutils import MockEDF, MockNXtomo from tomwer.tests.datasets import TomwerCIDatasets class TestGetClosestEnergy(unittest.TestCase): def setUp(self): self.topSrcFolder = tempfile.mkdtemp() self.dataSetID = "scan_3_" self.dataDir = TomwerCIDatasets.get_dataset( f"edf_datasets/{self.dataSetID}", ) self.sourceS3 = os.path.join(self.topSrcFolder, self.dataSetID) shutil.copytree(src=os.path.join(self.dataDir), dst=self.sourceS3) self.sourceT01 = os.path.join(self.topSrcFolder, "test01") shutil.copytree( src=TomwerCIDatasets.get_dataset( "edf_datasets/test01", ), dst=self.sourceT01, ) self.S3XMLFile = os.path.join(self.sourceS3, "scan_3_.xml") self.S3Ref0000 = os.path.join(self.sourceS3, "ref0000_0000.edf") self.S3Ref0010 = os.path.join(self.sourceS3, "ref0000_0010.edf") def tearDown(self): shutil.rmtree(self.topSrcFolder) def testEnergyFromEDF(self): os.remove(self.S3XMLFile) self.assertTrue( spec_utils.getClosestEnergy(scan=self.sourceS3, refFile=self.S3Ref0000) == 61 ) self.assertTrue( spec_utils.getClosestEnergy(scan=self.sourceS3, refFile=self.S3Ref0010) == 61 ) def testEnergyFromXML(self): os.remove(self.S3Ref0000) os.remove(self.S3Ref0010) self.assertTrue( spec_utils.getClosestEnergy(scan=self.sourceS3, refFile=self.S3Ref0000) == 10 ) self.assertTrue( spec_utils.getClosestEnergy(scan=self.sourceS3, refFile=self.S3Ref0010) == 10 ) def testEnergyFromInfo(self): self.assertTrue( spec_utils.getClosestEnergy(scan=self.sourceT01, refFile=None) == 19 ) def testDefaultEnergy(self): os.remove(self.S3XMLFile) os.remove(self.S3Ref0000) os.remove(self.S3Ref0010) self.assertTrue( spec_utils.getClosestEnergy(scan=self.sourceS3, refFile=self.S3Ref0000) is None ) self.assertTrue( spec_utils.getClosestEnergy(scan=self.sourceS3, refFile=self.S3Ref0010) is None ) class TestGetClosestSREnergy(unittest.TestCase): def setUp(self): self.topSrcFolder = tempfile.mkdtemp() self.dataSetID = "test10" self.dataDir = TomwerCIDatasets.get_dataset( f"edf_datasets/{self.dataSetID}", ) self.sourceT10 = os.path.join(self.topSrcFolder, self.dataSetID) shutil.copytree(src=os.path.join(self.dataDir), dst=self.sourceT10) self.T10XMLFile = os.path.join(self.sourceT10, "test10.xml") self.T10InfoFile = os.path.join(self.sourceT10, "test10.info") self.T10Ref0000 = os.path.join(self.sourceT10, "ref0000_0000.edf") def tearDown(self): shutil.rmtree(self.topSrcFolder) class TestMockEDFScan(unittest.TestCase): """Test that mock scan are adapted to other unit test""" def setUp(self): self.tmpdir = tempfile.mkdtemp() self.scan_id = os.path.join(self.tmpdir, "myscan") def tearDown(self): shutil.rmtree(self.tmpdir) def testScanEvolution360(self): """Test get scan evolution from a mock scan with a 360 range and no extra radio""" scan = MockEDF.mockScan( scanID=self.scan_id, nRadio=5, nRecons=1, nPagRecons=1, dim=10, scan_range=360, ) scan_dynamic = scan.get_proj_angle_url() self.assertEqual(len(scan_dynamic), 5) self.assertTrue(0 in scan_dynamic) self.assertEqual( scan_dynamic[0].file_path(), os.path.join(self.tmpdir, "myscan", "myscan_0000.edf"), ) self.assertTrue(180 in scan_dynamic) self.assertEqual( scan_dynamic[180].file_path(), os.path.join(self.tmpdir, "myscan", "myscan_0002.edf"), ) self.assertTrue(360 in scan_dynamic) self.assertEqual( scan_dynamic[360].file_path(), os.path.join(self.tmpdir, "myscan", "myscan_0004.edf"), ) def testScanEvolution180(self): """Test get scan evolution from a mock scan with a 180 range and no extra radio""" scan = MockEDF.mockScan( scanID=self.scan_id, nRadio=8, nRecons=0, nPagRecons=0, dim=10, scan_range=180, ) scan_dynamic = scan.get_proj_angle_url() self.assertEqual(len(scan_dynamic), 8) self.assertTrue(0 in scan_dynamic) self.assertEqual( scan_dynamic[0].file_path(), os.path.join(self.tmpdir, "myscan", "myscan_0000.edf"), ) self.assertTrue(180 in scan_dynamic) self.assertEqual( scan_dynamic[180].file_path(), os.path.join(self.tmpdir, "myscan", "myscan_0007.edf"), ) self.assertFalse(360 in scan_dynamic) def testScanEvolution360Extra4(self): """Test get scan evolution from a mock scan with a 360 range and 4 extra radio""" scan = MockEDF.mockScan( scanID=self.scan_id, nRadio=21, nRecons=0, nPagRecons=0, dim=10, scan_range=360, n_extra_radio=4, ) scan_dynamic = scan.get_proj_angle_url() self.assertEqual(len(scan_dynamic), 21 + 4) self.assertTrue(0 in scan_dynamic) self.assertEqual( scan_dynamic[0].file_path(), os.path.join(self.tmpdir, "myscan", "myscan_0000.edf"), ) self.assertTrue(180 in scan_dynamic) self.assertEqual( scan_dynamic[180].file_path(), os.path.join(self.tmpdir, "myscan", "myscan_0010.edf"), ) self.assertTrue(360 in scan_dynamic) self.assertEqual( scan_dynamic[360].file_path(), os.path.join(self.tmpdir, "myscan", "myscan_0020.edf"), ) extra_angles = (0, 90, 180, 270) # note: 0(1) is the last file acquire for iAngle, angle in enumerate(extra_angles): angle_id = str(angle) + "(1)" self.assertTrue(angle_id in scan_dynamic) file_name = os.path.join( self.tmpdir, "myscan", "myscan_%04d.edf" % (21 + 4 - 1 - iAngle) ) self.assertEqual(scan_dynamic[angle_id].file_path(), file_name) def testScanEvolution180Extra2(self): """Test get scan evolution from a mock scan with a 360 range and 3 extra radios""" scan = MockEDF.mockScan( scanID=self.scan_id, nRadio=4, nRecons=2, nPagRecons=2, dim=10, scan_range=180, n_extra_radio=2, ) scan_dynamic = scan.get_proj_angle_url() self.assertEqual(len(scan_dynamic), 4 + 2) self.assertTrue(0 in scan_dynamic) self.assertEqual( scan_dynamic[0].file_path(), os.path.join(self.tmpdir, "myscan", "myscan_0000.edf"), ) self.assertTrue(180 in scan_dynamic) self.assertEqual( scan_dynamic[180].file_path(), os.path.join(self.tmpdir, "myscan", "myscan_0003.edf"), ) self.assertTrue(360 not in scan_dynamic) extra_angles = (0, 90) # note: 0(1) is the last file acquire for iAngle, angle in enumerate(extra_angles): angle_id = str(angle) + "(1)" self.assertTrue(angle_id in scan_dynamic) file_name = os.path.join( self.tmpdir, "myscan", "myscan_%04d.edf" % (4 + 2 - 1 - iAngle) ) self.assertEqual(scan_dynamic[angle_id].file_path(), file_name) class TestMockNXtomo(unittest.TestCase): """Test MockNXtomo to check that the file produced is valid""" def setUp(self) -> None: self._folder = tempfile.mkdtemp() def tearDown(self) -> None: shutil.rmtree(self._folder) def testSimpleMockCreationOneCall(self): """Test mock of an acquisition starting by one dark, then 10 ref, then 20 radios, then 10 'final' ref and 2 alignment radio""" mock = MockNXtomo( scan_path=self._folder, n_proj=20, n_ini_proj=20, n_alignement_proj=2, create_ini_dark=True, create_ini_flat=True, create_final_flat=True, n_refs=10, ) self.assertTrue(0 in mock.scan.darks.keys()) self.assertTrue(1 in mock.scan.flats.keys()) self.assertTrue(10 in mock.scan.flats.keys()) def test_flat_field_normalization(): """test flatFieldCorrection function""" f = numpy.ones((10, 10)) d = numpy.ones((10, 10)) imgs = { 0: numpy.random.random((10, 10)), 12: numpy.random.random((10, 10)), } flatFieldCorrection(imgs, d, f) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/tomwer_object.py0000644000175000017500000000374615153325210020501 0ustar00paynopayno"""contains TomwerObject class. Mother object of all the object used as input / output through the tomwer project. At the moment those objects are either a scan (ready to be processed), a volume or a bliss scan (raw scan that needs to be converted to scan to be processed) """ from processview.core.dataset import Dataset class TomwerObject(Dataset): """Common tomwer object""" _DICT_USER_STITCHING_METADATA = "user_def_stitching_metadata" def __init__(self) -> None: super().__init__() self._cast_volume = None self._stitching_metadata = None def _clear_heavy_cache(self): """util function to clear some heavy object from the cache""" raise NotImplementedError() def clear_cache(self): pass @property def cast_volume(self): # for now this is used as an east way to cache the identifier and provide it to the remaining of the orange canvas. # but this is a wrong designa and should be removed at one point. return self._cast_volume @cast_volume.setter def cast_volume(self, volume): from tomwer.core.volume.volumebase import TomwerVolumeBase if not (volume is None or isinstance(volume, TomwerVolumeBase)): from tomwer.core.volume.volumefactory import ( VolumeFactory, ) # avoid cyclic import volume = VolumeFactory.create_tomo_object_from_identifier(identifier=volume) self._cast_volume = volume @property def stitching_metadata(self): return self._stitching_metadata @stitching_metadata.setter def stitching_metadata(self, metadata): from tomwer.core.process.stitching.metadataholder import StitchingMetadata if metadata is not None and not isinstance(metadata, StitchingMetadata): raise TypeError( f"metadata is expected to be an optional instance of {StitchingMetadata}. Not {type(metadata)}" ) self._stitching_metadata = metadata ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9291012 tomwer-1.6.17/src/tomwer/core/utils/0000755000175000017500000000000015153325403016416 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/core/utils/__init__.py0000644000175000017500000000003114764622416020534 0ustar00paynopayno"""Several core utils""" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/utils/char.py0000644000175000017500000000055314757047403017722 0ustar00paynopayno# coding: utf-8 ALPHA_CHAR = (b"\xce\xb1").decode("utf-8") BETA_CHAR = (b"\xce\xb2").decode("utf-8") GAMMA_CHAR = (b"\xce\xb3").decode("utf-8") DELTA_CHAR = (b"\xce\xb4").decode("utf-8") PSI_CHAR = (b"\xcf\x88").decode("utf-8") THETA_CHAR = (b"\xce\xb8").decode("utf-8") MU_CHAR = (b"\xce\xbc").decode("utf-8") DEGREE_CHAR = (b"\xc2\xb0").decode("utf-8") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/utils/deprecation.py0000644000175000017500000000632214757047403021302 0ustar00paynopayno# coding: utf-8 """Bunch of useful decorators""" import functools import logging import sys import traceback depreclog = logging.getLogger("tomwer.DEPRECATION") deprecache = set([]) def deprecated( func=None, reason=None, replacement=None, since_version=None, only_once=True, skip_backtrace_count=1, ): """ Decorator that deprecates the use of a function :param reason: Reason for deprecating this function (e.g. "feature no longer provided", :param replacement: Name of replacement function (if the reason for deprecating was to rename the function) :param since_version: First *silx* version for which the function was deprecated (e.g. "0.5.0"). :param only_once: If true, the deprecation warning will only be generated one time. Default is true. :param skip_backtrace_count: Amount of last backtrace to ignore when logging the backtrace """ def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): name = func.func_name if sys.version_info[0] < 3 else func.__name__ deprecated_warning( type_="Function", name=name, reason=reason, replacement=replacement, since_version=since_version, only_once=only_once, skip_backtrace_count=skip_backtrace_count, ) return func(*args, **kwargs) return wrapper if func is not None: return decorator(func) return decorator def deprecated_warning( type_, name, reason=None, replacement=None, since_version=None, only_once=True, skip_backtrace_count=0, ): """ Function to log a deprecation warning :param type_: Nature of the object to be deprecated: "Module", "Function", "Class" ... :param name: Object name. :param reason: Reason for deprecating this function (e.g. "feature no longer provided", :param replacement: Name of replacement function (if the reason for deprecating was to rename the function) :param since_version: First *silx* version for which the function was deprecated (e.g. "0.5.0"). :param only_once: If true, the deprecation warning will only be generated one time for each different call locations. Default is true. :param skip_backtrace_count: Amount of last backtrace to ignore when logging the backtrace """ if not depreclog.isEnabledFor(logging.WARNING): # Avoid computation when it is not logged return msg = "%s %s is deprecated" if since_version is not None: msg += " since silx version %s" % since_version msg += "." if reason is not None: msg += " Reason: %s." % reason if replacement is not None: msg += " Use '%s' instead." % replacement msg += "\n%s" limit = 2 + skip_backtrace_count backtrace = "".join(traceback.format_stack(limit=limit)[0]) backtrace = backtrace.rstrip() if only_once: data = (msg, type_, name, backtrace) if data in deprecache: return else: deprecache.add(data) depreclog.warning(msg, type_, name, backtrace) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/utils/dictutils.py0000644000175000017500000000072214757047403021007 0ustar00paynopaynodef concatenate_dict(dict_1, dict_2) -> dict: """update dict which has dict as values. And we want concatenate those values to""" res = dict_1.copy() for key in dict_2: if key in dict_1: if isinstance(dict_1[key], dict): res[key] = concatenate_dict(dict_1=dict_1[key], dict_2=dict_2[key]) else: res.update({key: dict_2[key]}) else: res[key] = dict_2[key] return res ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/utils/ftseriesutils.py0000644000175000017500000000205014757047403021704 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging import operator import os logger = logging.getLogger(__name__) def get_vol_file_shape(file_path): ddict = {} f = open(file_path, "r") lines = f.readlines() for line in lines: if "=" not in line: continue line_str = line.rstrip().replace(" ", "") line_str = line_str.split("#")[0] key, value = line_str.split("=") ddict[key.lower()] = value dimX = None dimY = None dimZ = None if "num_z" in ddict: dimZ = int(ddict["num_z"]) if "num_y" in ddict: dimY = int(ddict["num_y"]) if "num_x" in ddict: dimX = int(ddict["num_x"]) return (dimZ, dimY, dimX) def orderFileByLastLastModification(folder, fileList): """Return the list of files sorted by time of last modification. From the oldest to the newest modify""" res = {} for f in fileList: res[os.path.getmtime(os.path.join(folder, f))] = f return sorted(res.items(), key=operator.itemgetter(0)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/utils/gpu.py0000644000175000017500000000071214757047403017575 0ustar00paynopayno# coding: utf-8 import logging _logger = logging.getLogger(__name__) def getNumberOfDevice(): try: import pycuda # noqa F401 pylint: disable=E0401 from pycuda import compiler # noqa F401 pylint: disable=E0401 from pycuda import driver # pylint: disable=E0401 driver.init() return driver.Device.count() except Exception: _logger.error("fail to discover the number of gpu") return None ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/core/utils/image.py0000644000175000017500000000675015143647637020101 0ustar00paynopaynofrom __future__ import annotations import enum import logging import numpy from numpy.linalg import inv _logger = logging.getLogger(__file__) try: from scipy.ndimage import shift as shift_scipy has_scipy_shift = True except ImportError: has_scipy_shift = False _logger.info("no scipy.ndimage.shift detected, will use numpy.fft instead") def shift_img( data: numpy.ndarray, dx: float, dy: float, cval: float = 0.0, use_scipy=True, ) -> numpy.ndarray: """ Apply simple 2d image shift in 'constant mode'. :param data: :param dx: x translation to be applied :param dy: y translation to be applied :param cval: value to replace the shifted values :return: shifted image """ assert data.ndim == 2 assert dx is not None assert dy is not None _logger.debug(f"apply shift dx={dx}, dy={dy} ") if use_scipy and has_scipy_shift: return shift_scipy( input=data, shift=(dy, dx), order=1, mode="constant", cval=cval ) else: if use_scipy: _logger.warning( "scipy not installed. Will shift image from local shift routine" ) ynum, xnum = data.shape xmin = int(-numpy.fix(xnum / 2)) xmax = int(numpy.ceil(xnum / 2) - 1) ymin = int(-numpy.fix(ynum / 2)) ymax = int(numpy.ceil(ynum / 2) - 1) nx, ny = numpy.meshgrid( numpy.linspace(xmin, xmax, xnum), numpy.linspace(ymin, ymax, ynum) ) # cast variables to float ny = numpy.asarray(ny, numpy.float32) nx = numpy.asarray(nx, numpy.float32) res = abs( numpy.fft.ifft2( numpy.fft.fft2(data) * numpy.exp(1.0j * 2.0 * numpy.pi * (-dy * ny / ynum + -dx * nx / xnum)) ) ) # apply constant filter if dx > 0: res[:, 0 : int(numpy.ceil(dx))] = cval elif dx < 0: res[:, xnum + int(numpy.ceil(dx)) :] = cval return res class ImageScaleMethod(enum.Enum): RAW = "raw" MEAN = "mean" MEDIAN = "median" def scale_img2_to_img1( img_1: numpy.array, img_2: numpy.array, method: ImageScaleMethod = ImageScaleMethod.MEAN, ): """ scale image2 relative to image 1 in such a way they have same min and max. Scale will be apply from and to 'data' / raw data :param img_1: reference image :param img_2: image to scale :param method: method to apply scaling :return: """ assert method in ImageScaleMethod assert img_1.ndim == 2 assert img_2.shape == img_1.shape min1 = img_2.min() max1 = img_2.max() min0 = img_1.min() max0 = img_1.max() if method is ImageScaleMethod.RAW: a = (min0 - max0) / (min1 - max1) b = (min1 * max0 - min0 * max1) / (min1 - max1) return a * img_2 + b else: if method is ImageScaleMethod.MEAN: me0 = img_1.mean() me1 = img_2.mean() elif method is ImageScaleMethod.MEDIAN: me0 = img_1.median() me1 = img_2.median() else: raise ValueError("method not managed", method) vec0 = numpy.asmatrix([[min0], [me0], [max0]]) matr = numpy.asmatrix( [[min1 * min1, min1, 1.0], [me1 * me1, me1, 1.0], [max1 * max1, max1, 1.0]] ) vec1 = inv(matr) * vec0 return ( float(vec1[0, 0]) * (img_2 * img_2) + float(vec1[1, 0]) * img_2 + float(vec1[2, 0]) ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/utils/lbsram.py0000644000175000017500000000173415153325210020251 0ustar00paynopaynoimport os import psutil from tomwer.core import settings MOCK_LOW_MEM = False # if True will simulate the case the computer run into low memory IGNORE_LOW_MEM = False def is_low_on_memory(path=""): """ :return: True if the RAM usage is more than MAX_MEM_USED (or low memory is simulated) """ if IGNORE_LOW_MEM is True: return False if path == settings.get_dest_path(): if settings.MOCK_LBSRAM is True: return MOCK_LOW_MEM else: assert os.path.isdir(path) return psutil.disk_usage(path).percent > settings.MAX_MEM_USED else: return (MOCK_LOW_MEM is True) or ( os.path.exists(path) and (psutil.disk_usage(path).percent > settings.MAX_MEM_USED) ) def mock_low_memory(b=True): """Mock the case the computer is running into low memory""" global MOCK_LOW_MEM MOCK_LOW_MEM = b return psutil.virtual_memory().percent > settings.MAX_MEM_USED ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/utils/logconfig.py0000644000175000017500000000012515153325210020731 0ustar00paynopayno# coding: utf-8 DOC_TITLE = "doc_title" SCAN_ID = "scan_ID" FROM = "from" TO = "to" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/utils/normalization.py0000644000175000017500000000301414757047403021666 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging import fabio _logger = logging.getLogger(__name__) def flatFieldCorrection(imgs, dark, flat): """ Simple normalization of a list of images. Normalization is made for X-Ray imaging: (img - dark) / (flat - dark) :param imgs: list of imgs to correct. key: index of the image, value: the image path or numpy.ndarray :param dark: dark image :param flat: flat image :return: list of corrected images """ res = {} conditionOK = True if dark.ndim != 2: _logger.error( "cannot make flat field correction, dark should be of " "dimension 2" ) conditionOK = False if flat.ndim != 2: _logger.error( "cannot make flat field correction, flat should be of " "dimension 2" ) conditionOK = False if dark.shape != flat.shape: _logger.error("Given dark and flat have incoherent dimension") conditionOK = False if conditionOK is False: return res for index, img in imgs.items(): imgData = img if type(img) is str: assert img.endswith(".edf") imgData = fabio.open(img).data if imgData.shape != dark.shape: _logger.error("Image has invalid. Cannot apply flat field" "correction it") corrrectedImage = imgData else: corrrectedImage = (imgData - dark) / (flat - dark) res[index] = corrrectedImage return res ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/utils/nxtomoutils.py0000644000175000017500000000242515153325210021374 0ustar00paynopaynofrom __future__ import annotations import numpy from nxtomo.nxobject.nxdetector import ImageKey def get_n_series(image_key_values: tuple | list, image_key_type: ImageKey) -> int: """ Return the number of series of an image_key. Image key can be dark, flat, or projection. A series is defined as a contiguous elements in image_key_values :param image_key_values: list or tuple of image_keys to consider. Can be integers or tomoscan.esrf.scan.hdf5scan.ImageKey """ image_key_type = ImageKey(image_key_type) if image_key_type is ImageKey.INVALID: raise ValueError( "we can't count Invalid image keys series because those are ignored from tomoscan" ) image_key_values = [ImageKey(img_key) for img_key in image_key_values] # remove invalid frames image_key_values = numpy.array( image_key_values ) # for filtering invalid value a numpy aray is requested image_key_values = image_key_values[image_key_values != ImageKey.INVALID] n_series = 0 is_in_a_serie = False for frame in image_key_values: if frame == image_key_type and not is_in_a_serie: is_in_a_serie = True n_series += 1 elif frame != image_key_type: is_in_a_serie = False return n_series ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/core/utils/process.py0000644000175000017500000000346015143647637020470 0ustar00paynopaynofrom __future__ import annotations import psutil import logging from psutil import process_iter import getpass _logger = logging.getLogger(__name__) def send_signal_to_local_rpc_servers(signal, port: int, extended_find: bool = True): """ :param signal: signal to be emit :param port: port to check :param extended_find: if True then will try to find a process that occupy the port even if this is not a process launched by the user and launched by tomwer. """ found = False for proc in process_iter(): # try to find a process we can handle if proc.username() == getpass.getuser(): try: for conns in proc.connections(): # make sure we will kill the correct process if conns.laddr.port == port and proc.name() in ( "tomwer", "orange-canvas", ): _logger.warning(f"send {signal} signal to pid {proc.pid}") proc.send_signal(signal) found = True return except (PermissionError, psutil.AccessDenied): pass if not extended_find: return # if process not found try to find one to inform the user if not found: for proc in process_iter(): try: for conns in proc.connections(): # make sure we will kill the correct process if conns.laddr.port == port: _logger.warning( f"process pid: {proc.pid} - {proc.name()} seems to be one occupying port {port}" ) return except (PermissionError, psutil.AccessDenied): pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/utils/resource.py0000644000175000017500000000107014757047403020627 0ustar00paynopayno# coding: utf-8 import logging import resource _logger = logging.getLogger(__name__) def increase_max_number_file(): """increase the maximal number of file the software can open within respect of the hard limit""" try: hard_nofile = resource.getrlimit(resource.RLIMIT_NOFILE)[1] resource.setrlimit(resource.RLIMIT_NOFILE, (hard_nofile, hard_nofile)) except (ValueError, OSError): _logger.warning("Failed to retrieve and set the max opened files limit") else: _logger.debug("Set max opened files to %d", hard_nofile) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/utils/scanutils.py0000644000175000017500000003514215153325210020776 0ustar00paynopayno# coding: utf-8 """ Utils to mock scans """ from __future__ import annotations import logging import os import time from typing import Any import h5py import numpy from silx.io.utils import h5py_read_dataset from tomoscan.esrf.scan.mock import MockEDF as _MockEDF from tomoscan.esrf.scan.mock import MockNXtomo as _MockNXtomo from tomoscan.io import HDF5File from tomoscan.tests.utils import MockContext from tomwer.core.scan.blissscan import BlissScan from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.scan.scanfactory import ScanFactory _logger = logging.getLogger(__name__) class MockNXtomo(_MockNXtomo): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.scan = NXtomoScan(scan=self.scan_master_file, entry="entry") class MockEDF(_MockEDF): @staticmethod def mockScan( scanID, nRadio=5, nRecons=1, nPagRecons=0, dim=10, scan_range=360, n_extra_radio=0, start_dark=False, end_dark=False, start_flat=False, end_flat=False, start_dark_data=None, end_dark_data=None, start_flat_data=None, end_flat_data=None, ): """ Create some random radios and reconstruction in the folder :param scanID: the folder where to save the radios and scans :param nRadio: The number of radios to create :param nRecons: the number of reconstruction to mock :param nRecons: the number of paganin reconstruction to mock :param dim: dimension of the files (nb row/columns) :param scan_range: scan range, usually 180 or 360 :param n_extra_radio: number of radio run after the full range is made usually used to observe any sample movement during acquisition :param start_dark: do we want to create dark serie at start :param end_dark: do we want to create dark serie at end :param start_flat: do we want to create flat serie at start :param end_flat: do we want to create flat serie at end :param start_dark_data: if start_dark set to True Optional value for the dark serie. Else will generate some random values :param end_dark_data: if end_dark set to True Optional value for the dark serie. Else will generate some random values :param start_flat_data: if start_flat set to True Optional value for the flat serie. Else will generate some random values :param end_flat_data: if end_flat set to True Optional value for the flat serie. Else will generate some random values """ assert type(scanID) is str assert type(nRadio) is int assert type(nRecons) is int assert type(dim) is int _MockEDF.fastMockAcquisition( folder=scanID, n_radio=nRadio, scan_range=scan_range, n_extra_radio=n_extra_radio, ) _MockEDF.mockReconstruction( folder=scanID, nRecons=nRecons, nPagRecons=nPagRecons ) if start_dark: _MockEDF.add_dark_series( scan_path=scanID, n_elmt=4, index=0, dim=dim, data=start_dark_data ) if start_flat: _MockEDF.add_flat_series( scan_path=scanID, n_elmt=4, index=0, dim=dim, data=start_flat_data ) if end_dark: _MockEDF.add_dark_series( scan_path=scanID, n_elmt=4, index=nRadio - 1, dim=dim, data=end_dark_data, ) if end_flat: _MockEDF.add_flat_series( scan_path=scanID, n_elmt=4, index=nRadio - 1, dim=dim, data=end_flat_data, ) return ScanFactory.create_scan_object(scanID) class _BlissSample: """ Simple mock of a bliss sample. For now we onyl create the hierarchy of files. """ def __init__( self, sample_dir, sample_file, n_sequence, n_scan_per_sequence, n_darks, n_flats, with_nx, detector_name="pcolinux", ): self.__sample_dir = sample_dir self.__sample_file = sample_file self.__n_sequence = n_sequence self.__n_scan_per_seq = n_scan_per_sequence self.__n_darks = n_darks self.__n_flats = n_flats self.__scan_folders = [] self._index = 1 self.__with_nx = with_nx self.__detector_name = detector_name self.__det_width = 256 self.__det_height = 256 self.__n_frame_per_scan = 100 self.__energy = 19.0 for _ in range(n_sequence): self.add_sequence() def get_next_free_index(self): idx = self._index self._index += 1 return idx @staticmethod def get_title(scan_type): if scan_type == "dark": return "dark images" elif scan_type == "flat": return "reference images 1" elif scan_type == "projection": return "projections 1 - 2000" else: raise ValueError("Not implemented") def add_sequence(self): # reserve the index for the 'initialization' sequence. No scan folder # will be created for this one. seq_ini_index = self.get_next_free_index() # add sequence init information with h5py.File(self.sample_file, mode="a") as h5f: seq_node = h5f.require_group(str(seq_ini_index) + ".1") seq_node.attrs["NX_class"] = "NXentry" seq_node["title"] = "tomo:fullturn" # write energy seq_node["technique/scan/energy"] = self.__energy def register_scan_in_parent_seq(parent_index, scan_index): with h5py.File(self.sample_file, mode="a") as h5f: # write scan numbers seq_node = h5f.require_group(str(parent_index) + ".1") if "measurement/scan_numbers" in seq_node: scan_numbers = h5py_read_dataset( seq_node["measurement/scan_numbers"] ) res = list(scan_numbers) del seq_node["measurement/scan_numbers"] else: res = [] res.append(scan_index) seq_node["measurement/scan_numbers"] = numpy.asarray(res) def add_scan(scan_type): scan_idx = self.get_next_free_index() scan_name = str(scan_idx).zfill(4) scan_path = os.path.join(self.path, scan_name) self.__scan_folders.append( _BlissScan(folder=scan_path, scan_type=scan_type) ) register_scan_in_parent_seq(parent_index=seq_ini_index, scan_index=scan_idx) # register the scan information with h5py.File(self.sample_file, mode="a") as h5f: seq_node = h5f.require_group(str(scan_idx) + ".1") # write title title = self.get_title(scan_type=scan_type) seq_node["title"] = title # write data data = ( numpy.random.random( self.__det_height * self.__det_width * self.__n_frame_per_scan ) * 256 ) data = data.reshape( self.__n_frame_per_scan, self.__det_height, self.__det_width ) data = data.astype(numpy.uint16) det_path_1 = "/".join(("instrument", self.__detector_name)) det_grp = seq_node.require_group(det_path_1) det_grp["data"] = data det_grp.attrs["NX_class"] = "NXdetector" acq_grp = det_grp.require_group("acq_parameters") acq_grp["acq_expo_time"] = 4 det_path_2 = "/".join(("technique", "scan", self.__detector_name)) seq_node[det_path_2] = data seq_node.attrs["NX_class"] = "NXentry" # write rotation angle value and translations hrsrot_pos = seq_node.require_group( "/".join(("instrument", "positioners")) ) hrsrot_pos["hrsrot"] = numpy.random.randint( low=0.0, high=360, size=self.__n_frame_per_scan ) hrsrot_pos["sx"] = numpy.array( numpy.random.random(size=self.__n_frame_per_scan) ) hrsrot_pos["sy"] = numpy.random.random(size=self.__n_frame_per_scan) hrsrot_pos["sz"] = numpy.random.random(size=self.__n_frame_per_scan) if self.n_darks > 0: add_scan(scan_type="dark") if self.__n_flats > 0: add_scan(scan_type="flat") for i_proj_seq in range(self.__n_scan_per_seq): add_scan(scan_type="projection") # write end time with HDF5File(self.sample_file, mode="a") as h5f: h5f["/".join((str(seq_ini_index) + ".1", "end_time"))] = str(time.ctime()) if self.__with_nx: nx_file = f"sample_{seq_ini_index:04}.nx" nx_file = os.path.join(self.path, nx_file) with h5py.File(nx_file, "a") as h5f: pass @property def path(self): return self.__sample_dir @property def sample_directory(self): return self.__sample_dir @property def sample_file(self): return self.__sample_file def scans_folders(self): return self.__scan_folders @property def n_darks(self): return self.__n_darks class _BlissScan: """ mock of a bliss scan """ def __init__(self, folder, scan_type: str): assert scan_type in ("dark", "flat", "projection") self.__path = folder def path(self): return self.__path class MockBlissAcquisition: """ :param n_sequence: number of sequence to create :param n_scan_per_sequence: number of scans (projection series) per sequence :param n_projections_per_scan: number of projection frame in a scan :param n_darks: number of dark frame in the serie. Only one series at the beginning :param n_flats: number of flats to create. In this case will only create one series of n flats after dark if any :param output_dir: will contain the proposal file and one folder per sequence. """ def __init__( self, n_sample, n_sequence, n_scan_per_sequence, n_darks, n_flats, output_dir, with_nx=False, ): self.__folder = output_dir if not os.path.exists(output_dir): os.makedirs(output_dir) self.__proposal_file = os.path.join(self.__folder, "ihproposal_file.h5") # create sample self.__samples = [] for sample_i in range(n_sample): dir_name = "_".join(("sample", str(sample_i))) sample_dir = os.path.join(self.path, dir_name) os.makedirs(sample_dir) sample_file = os.path.join(sample_dir, dir_name + ".h5") self.__samples.append( _BlissSample( sample_dir=sample_dir, sample_file=sample_file, n_sequence=n_sequence, n_scan_per_sequence=n_scan_per_sequence, n_darks=n_darks, n_flats=n_flats, with_nx=with_nx, ) ) @property def samples(self): return self.__samples @property def proposal_file(self): # for now a simple file return self.__proposal_file @property def path(self): return self.__folder def create_bliss_scan(self): master_file = self.samples[0].sample_file assert os.path.exists(master_file) return BlissScan( master_file=master_file, entry="/1.1", proposal_file=self.__proposal_file ) class HDF5MockContext(MockContext, mock_class=MockNXtomo): """ Util class to provide a context with a new Mock HDF5 file """ def __init__(self, scan_path, n_proj, **kwargs): super().__init__(output_folder=os.path.dirname(scan_path)) self._n_proj = n_proj self._mocks_params = kwargs self._scan_path = scan_path def __enter__(self): return MockNXtomo( scan_path=self._scan_path, n_proj=self._n_proj, **self._mocks_params ).scan def data_identifier_to_scan(data_identifier: Any): """ from a identifier (as str) try to create a scan. Mostly used when 'data' parameter is set from ewoks. In this case we expect it to be a (string) identifier """ if isinstance(data_identifier, str): return ScanFactory.create_tomo_object_from_identifier(data_identifier) elif isinstance(data_identifier, dict): return ScanFactory.create_scan_object_frm_dict(data_identifier) else: return data_identifier def format_output_location(location: str, scan): """ format possible keys from the location like {scan_dir} or {scan_path} :param location: :param scan: :return: """ if scan is None: _logger.warning("scan is !none, enable to format the nabu output location") keywords = { "scan_dir_name": scan.scan_dir_name(), "scan_basename": scan.scan_basename(), "scan_parent_dir_basename": scan.scan_parent_dir_basename(), } if isinstance(scan, NXtomoScan): keywords.update( { "scan_file_name": ( os.path.splitext(os.path.basename(scan.master_file))[0] if scan.master_file is not None else "" ), "scan_entry": ( scan.entry.replace("/", "_") if scan.entry is not None else "" ), } ) elif isinstance(scan, EDFTomoScan): keywords.update( { "scan_file_name": "", "scan_entry": "", } ) # filter necessary keywords def get_necessary_keywords(): import string formatter = string.Formatter() return [field for _, field, _, _ in formatter.parse(location) if field] requested_keywords = get_necessary_keywords() def keyword_needed(pair): keyword, _ = pair return keyword in requested_keywords keywords = dict(filter(keyword_needed, keywords.items())) location = os.path.abspath(location.format(**keywords)) return location ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/utils/slurm.py0000644000175000017500000000117114757047403020144 0ustar00paynopayno# coding: utf-8 """ Utils for slurm """ from __future__ import annotations import uuid from datetime import datetime from sluurp.utils import has_sbatch_available def is_slurm_available() -> bool: """ Return True if the environment knows about slurm command (sbatch) """ return has_sbatch_available() def get_slurm_script_name(prefix: str | None = None) -> str: now_str = datetime.now().strftime("%y-%m-%d_%H:%M:%S") random_str = str(uuid.uuid4()).split("-")[0] suffix = f"{now_str}_{random_str}_.sh" if prefix in ("", None): return suffix else: return f"{prefix}_{suffix}" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/utils/spec.py0000644000175000017500000001666115153325210017730 0ustar00paynopaynofrom __future__ import annotations import fileinput import logging import os import pint import fabio from lxml import etree _logger = logging.getLogger(__name__) _ureg = pint.get_application_registry() def _getInformation(scan, refFile, information, _type, aliases=None): """ Parse files contained in the given directory to get the requested information :param scan: directory containing the acquisition. Must be an absolute path :param refFile: the refXXXX_YYYY which should contain information about the scan. :return: the requested information or None if not found """ def parseRefFile(filePath): header = fabio.open(filePath).header for k in aliases: if k in header: return _type(header[k]) return None def parseXMLFile(filePath): try: for alias in info_aliases: tree = etree.parse(filePath) elmt = tree.find("acquisition/" + alias) if elmt is None: continue else: info = _type(elmt.text) if info == -1: return None else: return info except etree.XMLSyntaxError as e: _logger.warning(e) return None def parseInfoFile(filePath): def extractInformation(text, alias): text = text.replace(alias, "") text = text.replace("\n", "") text = text.replace(" ", "") text = text.replace("=", "") return _type(text) info = None f = open(filePath, "r") line = f.readline() while line: for alias in info_aliases: if alias in line: info = extractInformation(line, alias) break line = f.readline() f.close() return info info_aliases = [information] if aliases is not None: assert type(aliases) in (tuple, list) [info_aliases.append(alias) for alias in aliases] if not os.path.isdir(scan): return None if refFile is not None and os.path.isfile(refFile): try: info = parseRefFile(refFile) except IOError as e: _logger.warning(e) else: if info is not None: return info baseName = os.path.basename(scan) infoFiles = [os.path.join(scan, baseName + ".info")] infoOnDataVisitor = infoFiles[0].replace("lbsram", "", 1) # hack to check in lbsram, would need to be removed to add some consistency if os.path.isfile(infoOnDataVisitor): infoFiles.append(infoOnDataVisitor) for infoFile in infoFiles: if os.path.isfile(infoFile) is True: info = parseInfoFile(infoFile) if info is not None: return info xmlFiles = [os.path.join(scan, baseName + ".xml")] xmlOnDataVisitor = xmlFiles[0].replace("lbsram", "", 1) # hack to check in lbsram, would need to be removed to add some consistency if os.path.isfile(xmlOnDataVisitor): xmlFiles.append(xmlOnDataVisitor) for xmlFile in xmlFiles: if os.path.isfile(xmlFile) is True: info = parseXMLFile(xmlFile) if info is not None: return info return None def getClosestEnergy(scan, refFile=None): """ Parse files contained in the given directory to get information about the incoming energy for the serie `iSerie` :param scan: directory containing the acquisition :param refFile: the refXXXX_YYYY which should contain information about the energy. :return: the energy in keV or none if no energy found """ return _getInformation( os.path.abspath(scan), refFile, information="Energy", aliases=["energy", "ENERGY"], _type=float, ) def getTomo_N(scan): """Return the number of radio taken""" return _getInformation( os.path.abspath(scan), refFile=None, information="TOMO_N", _type=int, aliases=["tomo_N", "Tomo_N"], ) def getDARK_N(scan): return _getInformation( os.path.abspath(scan), refFile=None, information="DARK_N", _type=int, aliases=["dark_N"], ) def rebaseParFile(_file, oldfolder, newfolder): """Update the given .par file to replace oldfolder location by the newfolder. .. warning:: make the replacement in place. :param _file: par file to update :param oldfolder: previous location of the .par file :param newfolder: new location of the .par file """ with fileinput.FileInput(_file, inplace=True, backup=".bak") as parfile: for line in parfile: line = line.rstrip().replace(oldfolder, newfolder, 1) print(line) def getDim1Dim2(scan: str) -> tuple[int]: """ :param scan: path to the acquisition :return: detector definition """ d1 = _getInformation( scan=scan, refFile=None, information="Dim_1", aliases=["projectionSize/DIM_1"], _type=int, ) d2 = _getInformation( scan=scan, refFile=None, information="Dim_2", aliases=["projectionSize/DIM_2"], _type=int, ) return d1, d2 def getParametersFromParOrInfo(_file): """ Create a dictionary from the file with the information name as keys and their values as values """ assert os.path.exists(_file) and os.path.isfile(_file) ddict = {} f = open(_file, "r") lines = f.readlines() for line in lines: if "=" not in line: continue line_str = line.replace(" ", "") line_str = line_str.rstrip("\n") # remove on the line comments if "#" in line_str: line_str = line_str.split("#")[0] if line_str == "": continue try: key, value = line_str.split("=") except ValueError: _logger.error('fail to extract information from "%s"' % line_str) else: ddict[key.lower()] = value return ddict def getFirstProjFile(scan): """Return the first .edf containing a projection""" if os.path.isdir(scan) is False: return None files = sorted(os.listdir(scan)) while ( len(files) > 0 and (files[0].startswith(os.path.basename(scan)) and files[0].endswith(".edf")) is False ): files.remove(files[0]) if len(files) > 0: return os.path.join(scan, files[0]) else: return None def getPixelSize(scan) -> float | None: """ Try to retrieve the pixel size from the set of files. :return: the pixel size in meter or None """ if os.path.isdir(scan) is False: return None value = _getInformation( scan=scan, refFile=None, information="PixelSize", _type=float, aliases=["pixelSize"], ) if value is None: parFile = os.path.join(scan, os.path.basename(scan) + ".par") if os.path.exists(parFile): ddict = getParametersFromParOrInfo(parFile) if "IMAGE_PIXEL_SIZE_1".lower() in ddict: value = float(ddict["IMAGE_PIXEL_SIZE_1".lower()]) # for now pixel size are stored in microns. We want to return them in meter if value is not None: return (value * _ureg.micrometer).to_base_units().magnitude else: return None ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9291012 tomwer-1.6.17/src/tomwer/core/utils/tests/0000755000175000017500000000000015153325403017560 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/utils/tests/__init__.py0000644000175000017500000000000014757047403021671 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/utils/tests/test_image.py0000644000175000017500000000160314757047403022265 0ustar00paynopaynoimport numpy import pytest from tomwer.core.utils.image import ImageScaleMethod, scale_img2_to_img1, shift_img @pytest.mark.parametrize( "use_scipy, dx, dy, cval", ((True, 1.0, -2.3, 0), (False, 0.0, 3.6, 2)) ) def test_shift_image(use_scipy, dx, dy, cval): data = numpy.linspace(0, 12, 100 * 100).reshape(100, 100) assert isinstance( shift_img(data=data, dx=dx, dy=dy, cval=cval, use_scipy=use_scipy), numpy.ndarray, ) def test_scale_img2_to_img1(): """ test scale_img2_to_img1 function """ img_1 = numpy.linspace(0, 10, 100 * 100, dtype=numpy.float16).reshape(100, 100) img_2 = numpy.linspace(20, 100, 100 * 100, dtype=numpy.float16).reshape(100, 100) rescale_img = scale_img2_to_img1(img_2, img_1, method=ImageScaleMethod.MEAN) numpy.testing.assert_array_almost_equal( img_2, rescale_img, decimal=1, ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/utils/tests/test_nxtomo.py0000644000175000017500000000224014757047403022525 0ustar00paynopayno# coding: utf-8 import pytest from nxtomo.nxobject.nxdetector import ImageKey from tomwer.core.utils.nxtomoutils import get_n_series def test_get_n_series(): """test tomwer.core.utils.nxtomoutils.get_n_series function""" array_1 = ( [ImageKey.DARK_FIELD] * 2 + [ImageKey.FLAT_FIELD] + [ImageKey.PROJECTION] * 4 + [ImageKey.FLAT_FIELD] ) with pytest.raises(ValueError): get_n_series(array_1, ImageKey.INVALID) with pytest.raises(ValueError): get_n_series(array_1, 3) assert len(array_1) == 8 assert get_n_series(array_1, ImageKey.DARK_FIELD) == 1 assert get_n_series(array_1, ImageKey.FLAT_FIELD) == 2 assert get_n_series(array_1, ImageKey.PROJECTION) == 1 assert get_n_series(array_1, 0) == 1 array_2 = ( [ImageKey.FLAT_FIELD.value] + [ImageKey.PROJECTION.value] * 4 + [ImageKey.INVALID.value] * 2 + [ImageKey.PROJECTION.value] * 3 + [ImageKey.FLAT_FIELD.value] ) assert get_n_series(array_2, ImageKey.DARK_FIELD) == 0 assert get_n_series(array_2, ImageKey.PROJECTION) == 1 assert get_n_series(array_2, ImageKey.FLAT_FIELD) == 2 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/core/utils/tests/test_scan_utils.py0000644000175000017500000000312115115744275023344 0ustar00paynopaynoimport os from tomwer.core.scan.blissscan import BlissScan from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.utils.scanutils import format_output_location def test_format_output_location(tmp_path): """ test different use cases of 'format_output_location' """ bliss_raw_dir = tmp_path / "raw" bliss_raw_dir.mkdir() bliss_sample_dir = bliss_raw_dir / "sample" bliss_sample_dir.mkdir() bliss_master_file = bliss_sample_dir / "dataset.h5" bliss_proposal_file = bliss_raw_dir / "ihsample.h5" bliss_proposal_file = os.path.abspath(bliss_proposal_file) bliss_scan = BlissScan( master_file=bliss_master_file, entry="1.1", proposal_file=bliss_proposal_file ) expected_path = os.path.join(tmp_path, "reduced", "sample") assert ( format_output_location( location="{scan_parent_dir_basename}/../reduced/{scan_dir_name}", scan=bliss_scan, ) == expected_path ) edf_scan = EDFTomoScan("/test/my/folder/") assert ( format_output_location( location="{scan_parent_dir_basename}/output", scan=edf_scan ) == "/test/my/output" ) hdf5_scan = NXtomoScan("/ddsad/my/file.hdf5", entry="nxtomos/entry0000") assert ( format_output_location(location="{scan_basename}/output.nx", scan=hdf5_scan) == "/ddsad/my/output.nx" ) assert format_output_location( location="{scan_file_name}/{scan_entry}.nx", scan=hdf5_scan ) == os.path.abspath("file/nxtomos_entry0000.nx") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/utils/tests/test_time.py0000644000175000017500000000015014757047403022135 0ustar00paynopaynofrom tomwer.core.utils.time import Timer def test_timer(): with Timer("timer name"): pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/core/utils/threads.py0000644000175000017500000000345615143647637020451 0ustar00paynopayno# coding: utf-8 """ This module is used to manage observations. Initially on files. Observations are runned on a thread and run each n seconds. They are manage by thread and signals """ import threading import time class LoopThread(threading.Thread): """ Thread looping on a defined process, as long not receiving the stopEvent. Wait for `_time_between_loops` between two loops """ startEvent = threading.Event() """Event to restart the loop on process""" stopEvent = threading.Event() """Event to stop the loop on process""" quitEvent = threading.Event() """Event to quit the Thread""" def __init__(self, time_between_loops): threading.Thread.__init__(self) self._time_between_loops = time_between_loops self._status = None self._last_processing = None def run(self): threading.Thread.run(self) while not self.quitEvent.isSet(): if self._status is None or ( self._status == "not running" and self.startEvent.isSet() ): self._status = "running" self.startEvent.clear() if self._status == "running" and self.stopEvent.isSet() is True: self.stopEvent.clear() self._status = "not running" if self._status == "running" and self.should_process(): self._last_processing = time.time() self.process() time.sleep(0.05) def process(self): raise NotImplementedError("Pure virtual class") def should_process(self): if self._last_processing is None: return True _pass_time_since_last_pro = time.time() - self._last_processing return _pass_time_since_last_pro > self._time_between_loops def _stop(self): pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/utils/time.py0000644000175000017500000000075614757047403017750 0ustar00paynopayno# coding: utf-8 """ This module is used to manage observations. Initially on files. Observations are runned on a thread and run each n seconds. They are manage by thread and signals """ from time import time class Timer: def __init__(self, title): self.title = title def __enter__(self): self._start_time = time() def __exit__(self, type, value, traceback): exec_time = time() - self._start_time print(f"{self.title} exec time: {exec_time} s") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/utils/volumeutils.py0000644000175000017500000000075214757047403021376 0ustar00paynopaynofrom typing import Any from tomwer.core.volume.volumefactory import VolumeFactory def volume_identifier_to_volume(volume_identifier: Any): """ from a str identifier try to create a volume. Mostly used when 'volume' parameter is set from ewoks. In this case we expect it to be a (string) identifier """ if isinstance(volume_identifier, str): return VolumeFactory.create_tomo_object_from_identifier(volume_identifier) else: return volume_identifier ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9291012 tomwer-1.6.17/src/tomwer/core/volume/0000755000175000017500000000000015153325403016565 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/volume/__init__.py0000644000175000017500000000062214757047403020710 0ustar00paynopayno"""contains volumes classes and function. Abstraction layer for scans, based on tomoscan volumes. See https://gitlab.esrf.fr/tomotools/tomoscan """ from .edfvolume import EDFVolume # noqa F401 from .hdf5volume import HDF5Volume # noqa F401 from .jp2kvolume import JP2KVolume # noqa F401 from .rawvolume import RawVolume # noqa F401 from .tiffvolume import MultiTIFFVolume, TIFFVolume # noqa F401 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/volume/edfvolume.py0000644000175000017500000000452514757047403021145 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import pathlib from datetime import datetime from processview.core.dataset import Dataset, DatasetIdentifier from tomoscan.esrf.identifier.edfidentifier import ( EDFVolumeIdentifier as _EDFVolumeIdentifier, ) from tomoscan.esrf.volume.edfvolume import EDFVolume as _EDFVolume from tomwer.core.volume.volumebase import TomwerVolumeBase class EDFVolumeIdentifier(_EDFVolumeIdentifier, DatasetIdentifier): def __init__(self, object, folder, file_prefix, metadata=None): super().__init__(object, folder, file_prefix) DatasetIdentifier.__init__( self, data_builder=EDFVolume.from_identifier, metadata=metadata ) @staticmethod def from_str(identifier): return _EDFVolumeIdentifier._from_str_to_single_frame_identifier( identifier=identifier, SingleFrameIdentifierClass=EDFVolumeIdentifier, ObjClass=EDFVolume, ) def long_description(self) -> str: """used for processview header tooltip for now""" return self.to_str() class EDFVolume(_EDFVolume, TomwerVolumeBase, Dataset): @staticmethod def from_identifier(identifier): """Return the Dataset from a identifier""" if not isinstance(identifier, EDFVolumeIdentifier): raise TypeError( f"identifier should be an instance of {EDFVolumeIdentifier} and not {type(identifier)}" ) return EDFVolume( folder=identifier.folder, volume_basename=identifier.file_prefix, ) def get_identifier(self) -> EDFVolumeIdentifier: if self.url is None: raise ValueError("no file_path provided. Cannot provide an identifier") try: stat = pathlib.Path(self.url.file_path()).stat() except Exception: stat = None return EDFVolumeIdentifier( object=self, folder=self.url.file_path(), file_prefix=self._volume_basename, metadata={ "name": self.url.file_path(), "creation_time": ( datetime.fromtimestamp(stat.st_ctime) if stat else None ), "modification_time": ( datetime.fromtimestamp(stat.st_ctime) if stat else None ), }, ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/core/volume/hdf5volume.py0000644000175000017500000001372015153325210021214 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import pathlib import logging from datetime import datetime from urllib.parse import urlparse from processview.core.dataset import Dataset, DatasetIdentifier from tomoscan.esrf.identifier.hdf5Identifier import ( HDF5VolumeIdentifier as _HDF5VolumeIdentifier, ) from tomoscan.esrf.identifier.url_utils import UrlSettings, split_path, split_query from tomoscan.esrf.volume.hdf5volume import HDF5Volume as _HDF5Volume from tomoscan.esrf.scan.utils import get_data from tomwer.core.volume.volumebase import TomwerVolumeBase from silx.io.url import DataUrl _logger = logging.getLogger(__name__) class HDF5VolumeIdentifier(_HDF5VolumeIdentifier, DatasetIdentifier): def __init__(self, object, hdf5_file, entry, **args): super().__init__(object, hdf5_file, entry) DatasetIdentifier.__init__( self, data_builder=HDF5Volume.from_identifier, **args ) @staticmethod def from_str(identifier): info = urlparse(identifier) paths = split_path(info.path) if len(paths) == 1: hdf5_file = paths[0] tomo_type = None elif len(paths) == 2: tomo_type, hdf5_file = paths else: raise ValueError("Failed to parse path string:", info.path) if tomo_type is not None and tomo_type != HDF5VolumeIdentifier.TOMO_TYPE: raise TypeError( f"provided identifier fits {tomo_type} and not {HDF5VolumeIdentifier.TOMO_TYPE}" ) queries = split_query(info.query) entry = queries.get(UrlSettings.DATA_PATH_KEY, None) if entry is None: raise ValueError("expects to get a data_path") return HDF5VolumeIdentifier(object=HDF5Volume, hdf5_file=hdf5_file, entry=entry) def long_description(self) -> str: """used for processview header tooltip for now""" return self.to_str() class HDF5Volume(_HDF5Volume, TomwerVolumeBase, Dataset): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) # load metadata to avoid any possible conflict later on it try: self.load_metadata() except (OSError, KeyError): _logger.debug("cannot pre-load metadata. Missing file / path most likely.") except Exception as e: _logger.exception(e) self._volume_shape_cache = None try: self.get_volume_shape() except (OSError, KeyError): _logger.debug( "cannot pre-load volume shape. Missing file / path most likely." ) except Exception as e: _logger.exception(e) def get_volume_shape(self, url=None): # at tomwer side the volume are only "read". So too smooth # a bit - because volume shape is required on main thread sometime (volume viewer) # we use a cache to avoid bottleneck on this resource. if self._volume_shape_cache is None: self._volume_shape_cache = super().get_volume_shape(url=url) return self._volume_shape_cache def _reset_volume_shape_cache(self): self._volume_shape_cache = None @_HDF5Volume.data.setter # pylint: disable=no-member def data(self, data): # shape is obtain from the hdf5 dataset. Safer to reset the cache in case this volume is changed. super(_HDF5Volume, HDF5Volume).data.__set__(self, data) self._reset_volume_shape_cache() @_HDF5Volume.url.setter # pylint: disable=no-member def url(self, url): super(_HDF5Volume, HDF5Volume).url.__set__(self, url) self._reset_volume_shape_cache() @staticmethod def from_identifier(identifier): """Return the Dataset from a identifier""" if not isinstance(identifier, HDF5VolumeIdentifier): raise TypeError( f"identifier should be an instance of {HDF5VolumeIdentifier}" ) return HDF5Volume( file_path=identifier.file_path, data_path=identifier.data_path, ) def get_identifier(self) -> HDF5VolumeIdentifier: if self.url is None: raise ValueError("no file_path provided. Cannot provide an identifier") try: stat = pathlib.Path(self.url.file_path()).stat() except Exception: stat = None return HDF5VolumeIdentifier( object=self, hdf5_file=self.url.file_path(), entry=self.url.data_path(), metadata={ "name": self.url.file_path(), "creation_time": ( datetime.fromtimestamp(stat.st_ctime) if stat else None ), "modification_time": ( datetime.fromtimestamp(stat.st_ctime) if stat else None ), }, ) def load_metadata(self, url: DataUrl | None = None, store: bool = True) -> dict: # nabu stores software version outside the expected metadata dict (depends on the version). # But we need those as part of the metadata to notify the user. So this section will try to read it when outside the # expected metadata dict. metadata = super().load_metadata(url=url, store=store) # software version url = url or self.metadata_url if url.scheme() != "silx": return metadata data_path = url.data_path() if data_path is None or len(data_path.split("/")) == 1: return metadata version_data_path = "/".join( list(data_path.split("/")[:-1]) + [ "version", ] ) version_url = DataUrl( file_path=url.file_path(), data_path=version_data_path, scheme=url.scheme(), ) try: version = get_data(version_url) except Exception: pass else: metadata["version"] = version if store: self.metadata = metadata return metadata ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/volume/jp2kvolume.py0000644000175000017500000000453214757047403021253 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import pathlib from datetime import datetime from processview.core.dataset import Dataset, DatasetIdentifier from tomoscan.esrf.identifier.jp2kidentifier import ( JP2KVolumeIdentifier as _JP2KVolumeIdentifier, ) from tomoscan.esrf.volume.jp2kvolume import JP2KVolume as _JP2KVolume from tomwer.core.volume.volumebase import TomwerVolumeBase class JP2KVolumeIdentifier(_JP2KVolumeIdentifier, DatasetIdentifier): """Identifier specific to JP2K volume""" def __init__(self, object, folder, file_prefix, metadata=None): super().__init__(object, folder, file_prefix) DatasetIdentifier.__init__(self, JP2KVolume.from_identifier, metadata=metadata) @staticmethod def from_str(identifier): return _JP2KVolumeIdentifier._from_str_to_single_frame_identifier( identifier=identifier, SingleFrameIdentifierClass=JP2KVolumeIdentifier, ObjClass=JP2KVolume, ) def long_description(self) -> str: """used for processview header tooltip for now""" return self.to_str() class JP2KVolume(_JP2KVolume, TomwerVolumeBase, Dataset): @staticmethod def from_identifier(identifier): """Return the Dataset from a identifier""" if not isinstance(identifier, JP2KVolumeIdentifier): raise TypeError( f"identifier should be an instance of {JP2KVolumeIdentifier}" ) return JP2KVolume( folder=identifier.folder, volume_basename=identifier.file_prefix, ) def get_identifier(self) -> JP2KVolumeIdentifier: if self.url is None: raise ValueError("no file_path provided. Cannot provide an identifier") try: stat = pathlib.Path(self.url.file_path()).stat() except Exception: stat = None return JP2KVolumeIdentifier( object=self, folder=self.url.file_path(), file_prefix=self._volume_basename, metadata={ "name": self.url.file_path(), "creation_time": ( datetime.fromtimestamp(stat.st_ctime) if stat else None ), "modification_time": ( datetime.fromtimestamp(stat.st_ctime) if stat else None ), }, ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/volume/rawvolume.py0000644000175000017500000000530614757047403021176 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import pathlib from datetime import datetime from urllib.parse import urlparse from processview.core.dataset import Dataset, DatasetIdentifier from tomoscan.esrf.identifier.rawidentifier import ( RawVolumeIdentifier as _RawVolumeIdentifier, ) from tomoscan.esrf.identifier.url_utils import split_path from tomoscan.esrf.volume.rawvolume import RawVolume as _RawVolume from tomwer.core.volume.volumebase import TomwerVolumeBase class RawVolumeIdentifier(_RawVolumeIdentifier, DatasetIdentifier): """Identifier specific to .vol volume""" def __init__(self, object, file_path, metadata=None): super().__init__(object, file_path) DatasetIdentifier.__init__(self, RawVolume.from_identifier, metadata=metadata) @staticmethod def from_str(identifier): info = urlparse(identifier) paths = split_path(info.path) if len(paths) == 1: vol_file = paths[0] tomo_type = None elif len(paths) == 2: tomo_type, vol_file = paths else: raise ValueError("Failed to parse path string:", info.path) if tomo_type is not None and tomo_type != RawVolumeIdentifier.TOMO_TYPE: raise TypeError( f"provided identifier fits {tomo_type} and not {RawVolumeIdentifier.TOMO_TYPE}" ) return RawVolumeIdentifier(object=RawVolume, file_path=vol_file) def long_description(self) -> str: """used for processview header tooltip for now""" return self.to_str() class RawVolume(_RawVolume, TomwerVolumeBase, Dataset): @staticmethod def from_identifier(identifier): """Return the Dataset from a identifier""" if not isinstance(identifier, RawVolumeIdentifier): raise TypeError( f"identifier should be an instance of {RawVolumeIdentifier}" ) return RawVolume( file_path=identifier.file_path, ) def get_identifier(self) -> RawVolumeIdentifier: if self.url is None: raise ValueError("no file_path provided. Cannot provide an identifier") try: stat = pathlib.Path(self.url.file_path()).stat() except Exception: stat = None return RawVolumeIdentifier( object=self, file_path=self.url.file_path(), metadata={ "name": self.url.file_path(), "creation_time": ( datetime.fromtimestamp(stat.st_ctime) if stat else None ), "modification_time": ( datetime.fromtimestamp(stat.st_ctime) if stat else None ), }, ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9291012 tomwer-1.6.17/src/tomwer/core/volume/tests/0000755000175000017500000000000015153325403017727 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/core/volume/tests/test_volumes.py0000644000175000017500000000217115143647637023052 0ustar00paynopaynoimport numpy from tomwer.core.volume import EDFVolume, HDF5Volume, RawVolume from tomwer.core.volume.rawvolume import RawVolumeIdentifier def test_volume_data_parent_folder(): edf_volume = EDFVolume(folder="/my/folder/path") assert edf_volume.volume_data_parent_folder() == "/my/folder" hdf5_volume = HDF5Volume(file_path="/path/to/hdf5/file.hdf5", data_path="entry") assert hdf5_volume.volume_data_parent_folder() == "/path/to/hdf5" raw_volume = RawVolume(file_path="/path/to/raw.vol") assert raw_volume.volume_data_parent_folder() == "/path/to" def test_raw_identifier(): raw_volume = RawVolume(file_path="/path/to/raw.vol") assert ( RawVolumeIdentifier.from_str(raw_volume.get_identifier().to_str()) == raw_volume.get_identifier() ) def test_volume_shape_cache(): hdf5_volume = HDF5Volume( file_path="/path/to/hdf5/file.hdf5", data_path="entry", data=numpy.random.random((1, 2, 3)), ) assert hdf5_volume.get_volume_shape() == (1, 2, 3) hdf5_volume.data = numpy.random.random((3, 2, 1)) assert hdf5_volume.get_volume_shape() == (3, 2, 1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/volume/tiffvolume.py0000644000175000017500000001115414757047403021333 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import pathlib from datetime import datetime from processview.core.dataset import Dataset, DatasetIdentifier from tomoscan.esrf.identifier.tiffidentifier import ( MultiTiffVolumeIdentifier as _MultiTiffVolumeIdentifier, ) from tomoscan.esrf.identifier.tiffidentifier import ( TIFFVolumeIdentifier as _TIFFVolumeIdentifier, ) from tomoscan.esrf.volume.tiffvolume import MultiTIFFVolume as _MultiTIFFVolume from tomoscan.esrf.volume.tiffvolume import TIFFVolume as _TIFFVolume from tomwer.core.volume.volumebase import TomwerVolumeBase class TIFFVolumeIdentifier(_TIFFVolumeIdentifier, DatasetIdentifier): def __init__(self, object, folder, file_prefix, metadata=None): super().__init__(object, folder, file_prefix) DatasetIdentifier.__init__(self, TIFFVolume.from_identifier, metadata=metadata) @staticmethod def from_str(identifier): return _TIFFVolumeIdentifier._from_str_to_single_frame_identifier( identifier=identifier, SingleFrameIdentifierClass=TIFFVolumeIdentifier, ObjClass=TIFFVolume, ) def long_description(self) -> str: """used for processview header tooltip for now""" return self.to_str() class MultiTiffVolumeIdentifier(_MultiTiffVolumeIdentifier, DatasetIdentifier): def __init__(self, object, tiff_file, metadata=None): super().__init__(object, tiff_file) DatasetIdentifier.__init__(self, TIFFVolume.from_identifier, metadata=metadata) @staticmethod def from_str(identifier): identifier_no_scheme = identifier.split(":")[-1] tiff_file = identifier_no_scheme return MultiTiffVolumeIdentifier(object=TIFFVolume, tiff_file=tiff_file) class TIFFVolume(_TIFFVolume, TomwerVolumeBase, Dataset): @staticmethod def from_identifier(identifier): """Return the Dataset from a identifier""" if not isinstance(identifier, TIFFVolumeIdentifier): raise TypeError( f"identifier should be an instance of {TIFFVolumeIdentifier} not {type(identifier)}" ) return TIFFVolume( folder=identifier.folder, volume_basename=identifier.file_prefix, ) def get_identifier(self) -> TIFFVolumeIdentifier: if self.url is None: raise ValueError("no file_path provided. Cannot provide an identifier") try: stat = pathlib.Path(self.url.file_path()).stat() except Exception: stat = None return TIFFVolumeIdentifier( object=self, folder=self.url.file_path(), file_prefix=self._volume_basename, metadata={ "name": self.url.file_path(), "creation_time": ( datetime.fromtimestamp(stat.st_ctime) if stat else None ), "modification_time": ( datetime.fromtimestamp(stat.st_ctime) if stat else None ), }, ) def volume_data_parent_folder(self): if self.data_url is None: raise ValueError("data_url doesn't exists") else: return os.path.dirname(self.data_url.file_path()) class MultiTIFFVolume(_MultiTIFFVolume, TomwerVolumeBase, Dataset): @staticmethod def from_identifier(identifier): """Return the Dataset from a identifier""" if not isinstance(identifier, MultiTiffVolumeIdentifier): raise TypeError( f"identifier should be an instance of {MultiTiffVolumeIdentifier}" ) return MultiTIFFVolume( file_path=identifier.file_path, ) def get_identifier(self) -> MultiTiffVolumeIdentifier: if self.url is None: raise ValueError("no file_path provided. Cannot provide an identifier") try: stat = pathlib.Path(self.url.file_path()).stat() except Exception: stat = None return MultiTiffVolumeIdentifier( object=self, tiff_file=self.url.file_path(), metadata={ "name": self.url.file_path(), "creation_time": ( datetime.fromtimestamp(stat.st_ctime) if stat else None ), "modification_time": ( datetime.fromtimestamp(stat.st_ctime) if stat else None ), }, ) def volume_data_parent_folder(self): if self.data_url is None: raise ValueError("data_url doesn't exists") else: return os.path.dirname(self.data_url.file_path()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/volume/volumebase.py0000644000175000017500000000332314757047403021314 0ustar00paynopaynoimport os from tomwer.core.tomwer_object import TomwerObject class TomwerVolumeBase(TomwerObject): def _clear_heavy_cache(self): """util user""" self.data = None self.metadata = None @property def icat_data_dir(self) -> str: """Return the data directory to be used by icat for the volume""" return os.path.dirname(self.data_url.file_path()) # pylint: disable=E1101 @staticmethod def format_output_location(location: str, volume): if not isinstance(volume, TomwerVolumeBase): raise TypeError( f"volume is expected to be an instance of {TomwerVolumeBase}" ) keywords = { "volume_data_parent_folder": volume.volume_data_parent_folder(), } # filter necessary keywords def get_necessary_keywords(): import string formatter = string.Formatter() return [field for _, field, _, _ in formatter.parse(location) if field] requested_keywords = get_necessary_keywords() def keyword_needed(pair): keyword, _ = pair return keyword in requested_keywords keywords = dict(filter(keyword_needed, keywords.items())) location = os.path.abspath(location.format(**keywords)) return location def volume_data_parent_folder(self): if self.data_url is None: # pylint: disable=E1101 raise ValueError("data_url doesn't exists") else: return os.path.dirname(self.data_url.file_path()) # pylint: disable=E1101 def __str__(self) -> str: try: return self.get_identifier().to_str() except Exception: return super().__str__() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/core/volume/volumefactory.py0000644000175000017500000001474214757047403022060 0ustar00paynopaynofrom __future__ import annotations import logging from urllib.parse import urlparse from tomoscan import identifier as _identifier_mod from tomoscan.esrf.identifier.url_utils import split_path from tomoscan.factory import Factory as _oVolumeFactory from tomoscan.identifier import BaseIdentifier, ScanIdentifier, VolumeIdentifier from tomwer.core.scan.edfscan import EDFTomoScan, EDFTomoScanIdentifier from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.volume.volumebase import TomwerVolumeBase from tomwer.core.volume import ( EDFVolume, HDF5Volume, JP2KVolume, MultiTIFFVolume, RawVolume, TIFFVolume, ) from tomwer.core.volume.edfvolume import EDFVolumeIdentifier from tomwer.core.volume.hdf5volume import HDF5VolumeIdentifier from tomwer.core.volume.jp2kvolume import JP2KVolumeIdentifier from tomwer.core.volume.rawvolume import RawVolumeIdentifier from tomwer.core.volume.tiffvolume import ( MultiTiffVolumeIdentifier, TIFFVolumeIdentifier, ) from tomwer.utils import docstring _logger = logging.getLogger(__name__) class VolumeFactory(_oVolumeFactory): @staticmethod def from_identifier_to_vol_urls(identifier) -> tuple | None: """ convert an identifier to a volume and return all the existing url of this volume """ try: vol = VolumeFactory.create_tomo_object_from_identifier( identifier=identifier ) except Exception as e: _logger.error(e) return None else: return tuple(vol.browse_data_urls()) @docstring(_oVolumeFactory.create_tomo_object_from_identifier) @staticmethod def create_tomo_object_from_identifier( identifier: str | BaseIdentifier, ) -> TomwerVolumeBase: """ :param scan_path: path to the scan directory or file :param entry: entry on the file. Requested for hdf5 files :param accept_bliss_scan: if True the factory can return some BlissScan But this is only compatible with the Tomomill processing. :return: TomwerScanBase instance fitting the scan folder or scan path :raises: ValueError if scan_path is not containing a scan """ if isinstance(identifier, BaseIdentifier): identifier = identifier.to_str() elif not isinstance(identifier, str): raise TypeError( f"identifier is expected to be a str or an instance of {BaseIdentifier} not {type(identifier)}" ) # step 1: convert identifier to an instance of BaseIdentifier if necessary if isinstance(identifier, str): info = urlparse(identifier) paths = split_path(info.path) scheme = info.scheme if len(paths) == 1: # insure backward compatibility. Originally (until 0.8) there was only one type which was scan tomo_type = ScanIdentifier.TOMO_TYPE elif len(paths) == 2: tomo_type, _ = paths else: raise ValueError("Failed to parse path string:", info.path) if tomo_type == _identifier_mod.VolumeIdentifier.TOMO_TYPE: if scheme == "edf": identifier = EDFVolumeIdentifier.from_str(identifier=identifier) elif scheme == "hdf5": identifier = HDF5VolumeIdentifier.from_str(identifier=identifier) elif scheme == "tiff": identifier = TIFFVolumeIdentifier.from_str(identifier=identifier) elif scheme == "tiff3d": identifier = MultiTiffVolumeIdentifier.from_str( identifier=identifier ) elif scheme == "jp2k": identifier = JP2KVolumeIdentifier.from_str(identifier=identifier) elif scheme in ("raw", "vol"): identifier = RawVolumeIdentifier.from_str(identifier=identifier) else: raise ValueError(f"Scheme {scheme} is not recognized") elif tomo_type == _identifier_mod.ScanIdentifier.TOMO_TYPE: # otherwise consider this is a scan. Insure backward compatibility if scheme == "edf": identifier = EDFTomoScanIdentifier.from_str(identifier=identifier) elif scheme == "hdf5": identifier = HDF5VolumeIdentifier.from_str(identifier=identifier) else: raise ValueError(f"Scheme {scheme} not recognized") else: raise ValueError(f"{tomo_type} is not an handled tomo type") # step 2: convert identifier to a TomoBaseObject assert isinstance(identifier, BaseIdentifier) scheme = identifier.scheme tomo_type = identifier.tomo_type if scheme == "edf": if tomo_type == VolumeIdentifier.TOMO_TYPE: return EDFVolume.from_identifier(identifier=identifier) elif tomo_type == ScanIdentifier.TOMO_TYPE: return EDFTomoScan.from_identifier(identifier=identifier) else: raise NotImplementedError() elif scheme == "hdf5": if tomo_type == VolumeIdentifier.TOMO_TYPE: return HDF5Volume.from_identifier(identifier=identifier) elif tomo_type == ScanIdentifier.TOMO_TYPE: return NXtomoScan.from_identifier(identifier=identifier) else: raise NotImplementedError() elif scheme == "jp2k": if tomo_type == VolumeIdentifier.TOMO_TYPE: return JP2KVolume.from_identifier(identifier=identifier) else: raise NotImplementedError elif scheme == "tiff": if tomo_type == VolumeIdentifier.TOMO_TYPE: return TIFFVolume.from_identifier(identifier=identifier) else: raise NotImplementedError elif scheme == "tiff3d": if tomo_type == VolumeIdentifier.TOMO_TYPE: return MultiTIFFVolume.from_identifier(identifier=identifier) else: raise NotImplementedError elif scheme in ("raw", "vol"): if tomo_type == VolumeIdentifier.TOMO_TYPE: return RawVolume.from_identifier(identifier=identifier) else: raise NotImplementedError else: raise ValueError(f"Scheme {scheme} not recognized") ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9291012 tomwer-1.6.17/src/tomwer/gui/0000755000175000017500000000000015153325403015112 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/__init__.py0000644000175000017500000000014414757047403017234 0ustar00paynopayno"""This package contains all the widget which are not inheriting from WidgetOW (orange widgets) """ ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9331014 tomwer-1.6.17/src/tomwer/gui/cluster/0000755000175000017500000000000015153325403016573 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/gui/cluster/__init__.py0000644000175000017500000000004414764622416020715 0ustar00paynopayno"""Widgets for remote processing""" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/cluster/slurm.py0000644000175000017500000010366115153325210020312 0ustar00paynopaynofrom __future__ import annotations import os import re import logging from functools import lru_cache as cache from silx.gui import qt from sluurp.utils import get_partitions, get_partition_gpus, get_partition_walltime from tomwer.core.settings import SlurmSettings, SlurmSettingsMode from tomwer.gui import icons from tomwer.gui.utils.qt_utils import block_signals from tomwer.gui.configuration.action import ( BasicConfigurationAction, ExpertConfigurationAction, ) from tomwer.gui.configuration.level import ConfigurationLevel from nxtomomill.models.utils import convert_str_to_tuple _logger = logging.getLogger(__name__) class SlurmSettingsDialog(qt.QDialog): sigConfigChanged = qt.Signal() """Signal emit when the SlurmSetting changed""" def __init__(self, parent=None): super().__init__(parent=parent) self.setLayout(qt.QVBoxLayout()) self._mainWidget = SlurmSettingsWindow(parent=self) self._mainWidget.setWindowFlags(qt.Qt.Widget) self.layout().addWidget(self._mainWidget) # buttons for validation self._buttons = qt.QDialogButtonBox(self) types = qt.QDialogButtonBox.Close self._buttons.setStandardButtons(types) self.layout().addWidget(self._buttons) self._buttons.button(qt.QDialogButtonBox.Close).clicked.connect(self.close) # connect signal /slot self._mainWidget.sigConfigChanged.connect(self.sigConfigChanged) def isSlurmActive(self): return self._mainWidget.isSlurmActive() def getConfiguration(self) -> dict: return self._mainWidget.getConfiguration() def setConfiguration(self, config: dict) -> None: self._mainWidget.setConfiguration(config=config) class SlurmSettingsWindow(qt.QMainWindow): """ Main window to define slurm settings. Composed of the SlurmSettingsWidget and a combobox with some predefined settings """ sigConfigChanged = qt.Signal() """Signal emit when the SlurmSetting changed""" def __init__(self, parent: qt.QWidget | None = None) -> None: super().__init__(parent) # define toolbar toolbar = qt.QToolBar(self) self.addToolBar(qt.Qt.TopToolBarArea, toolbar) self.__configurationModesAction = qt.QAction(self) self.__configurationModesAction.setCheckable(False) menu = qt.QMenu(self) self.__configurationModesAction.setMenu(menu) toolbar.addAction(self.__configurationModesAction) self.__configurationModesGroup = qt.QActionGroup(self) self.__configurationModesGroup.setExclusive(True) self.__configurationModesGroup.triggered.connect(self._userModeChanged) self._basicConfigAction = BasicConfigurationAction(toolbar) menu.addAction(self._basicConfigAction) self.__configurationModesGroup.addAction(self._basicConfigAction) self._expertConfiguration = ExpertConfigurationAction(toolbar) menu.addAction(self._expertConfiguration) self.__configurationModesGroup.addAction(self._expertConfiguration) # define maini widget self._mainWidget = qt.QWidget(self) self._mainWidget.setLayout(qt.QFormLayout()) self._modeCombox = qt.QComboBox(self) self._mainWidget.layout().addRow("configuration: ", self._modeCombox) self._modeCombox.addItems([item.value for item in SlurmSettingsMode]) self._modeCombox.setCurrentText(SlurmSettingsMode.GENERIC.value) self._settingsWidget = SlurmSettingsWidget(self, jobLimitation=None) self._mainWidget.layout().addRow(self._settingsWidget) self.setCentralWidget(self._mainWidget) # set up self._reloadPredefinedSettings() self._basicConfigAction.setChecked(True) self._userModeChanged(self._basicConfigAction) # connect signal / slot self._modeCombox.currentIndexChanged.connect(self._reloadPredefinedSettings) self._settingsWidget.sigConfigChanged.connect(self._configChanged) self._modeCombox.currentIndexChanged.connect(self.sigConfigChanged) # when the settings widget is edited them we automatically move to 'manual' settings. To notify visually the user self._settingsWidget.sigConfigChanged.connect(self._switchToManual) def _userModeChanged(self, action): self.__configurationModesAction.setIcon(action.icon()) self.__configurationModesAction.setToolTip(action.tooltip()) if action is self._basicConfigAction: level = ConfigurationLevel.OPTIONAL elif action is self._expertConfiguration: level = ConfigurationLevel.ADVANCED else: raise NotImplementedError self._settingsWidget.setConfigurationLevel(level) def _reloadPredefinedSettings(self, *args, **kkwargs): """ reload settings from some predefined configuration """ mode = self.getCurrentSettingsMode() settingsClass = SlurmSettingsMode.get_settings_class(mode) if settingsClass: with block_signals(self._settingsWidget): self.setConfiguration( { "cpu-per-task": settingsClass.N_CORES_PER_TASK, "n_tasks": settingsClass.N_TASKS, "n_jobs": settingsClass.N_JOBS, "memory": settingsClass.MEMORY_PER_WORKER, "partition": settingsClass.PARTITION, "n_gpus": settingsClass.N_GPUS_PER_WORKER, "job_name": settingsClass.PROJECT_NAME, "walltime": settingsClass.DEFAULT_WALLTIME, "python_venv": settingsClass.PYTHON_VENV, "modules": settingsClass.MODULES_TO_LOAD, } ) def _configChanged(self, *args, **kwargs): self.sigConfigChanged.emit() def _switchToManual(self): self._modeCombox.setCurrentText(SlurmSettingsMode.MANUAL.value) def getCurrentSettingsMode(self) -> SlurmSettingsMode: return SlurmSettingsMode(self._modeCombox.currentText()) def setCurrentSettingsMode(self, mode: SlurmSettingsMode) -> SlurmSettingsMode: mode = SlurmSettingsMode(mode) self._modeCombox.setCurrentText(mode.value) def setMode(self, mode: SlurmSettingsMode) -> None: """Alias for setCurrentSettingsMode(), used by SlurmClusterOW.""" self.setCurrentSettingsMode(mode) def mode(self) -> SlurmSettingsMode: """Alias for getCurrentSettingsMode(), used by SlurmClusterOW.""" return self.getCurrentSettingsMode() # expose API def getConfiguration(self) -> dict: return self._settingsWidget.getConfiguration() def getSlurmClusterConfiguration(self) -> dict: return self._settingsWidget.getSlurmClusterConfiguration() def setConfiguration(self, config: dict) -> None: self._settingsWidget.setConfiguration(config=config) def isSlurmActive(self): return self._settingsWidget.isSlurmActive() class SlurmSettingsWidget(qt.QWidget): """Widget used to define Slurm configuration to be used""" sigConfigChanged = qt.Signal() """Signal emit when the SlurmSetting changed""" WALL_TIME_INVALID_COLOR = qt.QColor("#FF0000") def __init__( self, parent=None, n_gpu=SlurmSettings.N_GPUS_PER_WORKER, jobLimitation: int | None = 1, ) -> None: """ :param n_gpu: if provided will set the value to the number of gpu requested (default is one as most of the job are nabu reconstruction) :param jobLimitation: if set then will hide the option to define the number of job """ super().__init__(parent=parent) self.setLayout(qt.QGridLayout()) """Action to display warning in case of possible 'wrong' setting""" # define some optional warning warning_icon = icons.getQIcon("warning") self._warning_opd_p9 = qt.QLabel("") self._warning_opd_p9.setPixmap(warning_icon.pixmap(20, state=qt.QIcon.On)) self._warning_opd_p9.setToolTip( f"'{get_login()}' account cannot submit job on p9 architecture" ) self._warning_opd_export_opts = qt.QLabel("") self._warning_opd_export_opts.setPixmap( warning_icon.pixmap(20, state=qt.QIcon.On) ) self._warning_opd_export_opts.setToolTip( f"'{get_login()}' account needs to export job with ALL option (advanced settings)" ) # queues self._queueLabel = qt.QLabel("queue / partition") self.layout().addWidget(self._queueLabel, 0, 0, 1, 1) self._queueCB = qt.QComboBox(self) self._queueCB.setEditable(True) for partition in get_partitions(): if partition in ("nice*",): # filter some node that we cannot access in fact continue self._queueCB.addItem(partition) self.layout().addWidget(self._queueCB, 0, 1, 1, 1) self.layout().addWidget(self._warning_opd_p9, 0, 2, 1, 1) # n workers self._nWorkersLabel = qt.QLabel("number of task", self) self.layout().addWidget(self._nWorkersLabel, 1, 0, 1, 1) self._nWorkersSP = qt.QSpinBox(self) self._nWorkersSP.setRange(1, 100) self.layout().addWidget(self._nWorkersSP, 1, 1, 1, 1) # ncores active self._nCoresLabel = qt.QLabel("number of cores per task") self.layout().addWidget(self._nCoresLabel, 2, 0, 1, 1) self._nCoresSB = qt.QSpinBox(self) self._nCoresSB.setRange(1, 500) self.layout().addWidget(self._nCoresSB, 2, 1, 1, 1) # memory self._memoryLabel = qt.QLabel("memory per task") self.layout().addWidget(self._memoryLabel, 3, 0, 1, 1) self._memorySB = qt.QSpinBox(self) self._memorySB.setRange(1, 10000) self._memorySB.setSuffix("GB") self.layout().addWidget(self._memorySB, 3, 1, 1, 1) # gpu self._nGpuLabel = qt.QLabel("number of GPUs per task") self.layout().addWidget(self._nGpuLabel, 4, 0, 1, 1) self._nGpuSB = qt.QSpinBox(self) self._nGpuSB.setRange(0, 12) self.layout().addWidget(self._nGpuSB, 4, 1, 1, 1) # n jobs self._nJobsLabel = qt.QLabel("number of job", self) self.layout().addWidget(self._nJobsLabel, 5, 0, 1, 1) self._nJobs = qt.QSpinBox(self) self._nJobs.setRange(1, 100000) self._nJobs.setValue(1) self._nJobs.setToolTip("Define on how many part the job should be split in") self._nJobsLabel.setVisible(jobLimitation is None) self._nJobs.setVisible(jobLimitation is None) self.layout().addWidget(self._nJobs, 5, 1, 1, 1) # wall time self._wallTimeLabel = qt.QLabel("wall time", self) self.layout().addWidget(self._wallTimeLabel, 6, 0, 1, 1) self._wallTimeQLE = qt.QLineEdit("", self) self.__reWallTime = qt.QRegularExpression( r"[0-9]?[0-9]:[0-9]?[0-9]:[0-9]?[0-9]" ) self._wallTimeQLE.setPlaceholderText("HH:MM:SS") self._wallTimeValidator = qt.QRegularExpressionValidator( self.__reWallTime, self ) self._wallTimeQLE.setValidator(self._wallTimeValidator) self.layout().addWidget(self._wallTimeQLE, 6, 1, 1, 1) self.__defaultWallTimeBackgroundColor = self.palette().color( self._wallTimeQLE.backgroundRole() ) self._warningWallTime = qt.QLabel("") self._warningWallTime.setPixmap(warning_icon.pixmap(20, state=qt.QIcon.On)) self.layout().addWidget(self._warningWallTime, 6, 2, 1, 1) # python exe / modules self._preProcessingGroup = qt.QGroupBox("pre-processing", self) self._preProcessingGroup.setLayout(qt.QFormLayout()) self._preProcessingButtonGroup = qt.QButtonGroup(self) self._preProcessingButtonGroup.setExclusive(True) self.layout().addWidget(self._preProcessingGroup, 10, 0, 1, 2) # python venv self._sourceScriptCB = qt.QRadioButton("source script (python venv)", self) self._pythonVenv = qt.QLineEdit("/scisoft/tomotools/activate stable", self) self._preProcessingButtonGroup.addButton(self._sourceScriptCB) self._pythonVenv.setToolTip(""" Optional path to a bash script to source before executing the script. """) self._preProcessingGroup.layout().addRow(self._sourceScriptCB, self._pythonVenv) # module self._modulesQLE = qt.QLineEdit(", ".join(SlurmSettings.MODULES_TO_LOAD), self) self._modulesCB = qt.QRadioButton("module(s) to load", self) self._preProcessingButtonGroup.addButton(self._modulesCB) self._preProcessingGroup.setToolTip(""" Optional list of modules to load before executing the script. each module must be separated by a coma """) self._preProcessingGroup.layout().addRow(self._modulesCB, self._modulesQLE) # job name self._job_nameQLabel = qt.QLabel("job name", self) self.layout().addWidget(self._job_nameQLabel, 13, 0, 1, 1) self._jobName = qt.QLineEdit("", self) self._jobName.setToolTip( """Job name. Can contains several keyword that will be formatted: - scan: will be replaced by the scan name - process: will be replaced by the process name (nabu slices, nabu volume...) - info: some extra information that can be provided by the process to `specify` the processing note: those key word have to be surrounding by surrounded `{` and `}` in order to be formatted. """ ) self.layout().addWidget(self._jobName, 13, 1, 1, 1) # port # fixme: replace by a dedicated widget / validator for TCP adress self._portLabel = qt.QLabel("port", self) self.layout().addWidget(self._portLabel, 14, 0, 1, 1) self._port = _PortRangeSelection(self) self._port.setRange(0, 99999) self._port.setToolTip("TCP Port for the dask-distributed scheduler") self.layout().addWidget(self._port, 14, 1, 1, 1) # dashboard port self._dashboardPort = qt.QSpinBox(self) self.layout().addWidget(self._dashboardPort, 15, 0, 1, 1) self._dashboardPort.setRange(0, 99999) self._dashboardPort.setToolTip("TCP Port for the dashboard") self._dashboardPortLabel = qt.QLabel("dashboard port", self) self.layout().addWidget(self._dashboardPort, 15, 1, 1, 1) # sbatch advance parameters self._sbatchAdvancedParameters = qt.QGroupBox("sbatch advanced settings", self) self._sbatchAdvancedParameters.setLayout(qt.QFormLayout()) self.layout().addWidget(self._sbatchAdvancedParameters, 16, 0, 1, 2) ## export parameter self._exportValueCM = qt.QComboBox(self) self._exportValueCM.addItems(("NONE", "ALL")) self._exportValueCM.setItemData( self._exportValueCM.findText("NONE"), """ Only SLURM_* variables from the user environment will be defined. User must use absolute path to the binary to be executed that will define the environment. User can not specify explicit environment variables with "NONE". However, Slurm will then implicitly attempt to load the user's environment on the node where the script is being executed, as if --get-user-env was specified. \nThis option is particularly important for jobs that are submitted on one cluster and execute on a different cluster (e.g. with different paths). To avoid steps inheriting environment export settings (e.g. "NONE") from sbatch command, the environment variable SLURM_EXPORT_ENV should be set to "ALL" in the job script. """, ) self._exportValueCM.setItemData( self._exportValueCM.findText("ALL"), """ All of the user's environment will be loaded (either from the caller's environment or from a clean environment if --get-user-env is specified). \nCan fail when submitting cross-platform jobs and user has some module loaded """, ) self._exportValueCM.setCurrentText("ALL") self._sbatchAdvancedParameters.layout().addRow("--export", self._exportValueCM) self.layout().addWidget(self._warning_opd_export_opts, 16, 2, 1, 1) ## gpu card self._gpuCardCB = qt.QComboBox(self) self._gpuCardCB.setToolTip( "Specify a GPU card to be used. Using the -C command from sbatch" ) self._gpuCardCB.setEditable( True ) # let the user the ability to provide a GPU that is not found for now (expecting he knows what he is doing) self._sbatchAdvancedParameters.layout().addRow("-C (gpu card)", self._gpuCardCB) # simplify gui self._dashboardPort.hide() self._dashboardPortLabel.hide() self._jobName.hide() self._job_nameQLabel.hide() self._portLabel.hide() # for now we don't use the port. This can be done automatically self._port.hide() # for now we don't use the port. This can be done automatically # for now nworker == ntask is not used self._nWorkersSP.setVisible(False) self._nWorkersLabel.setVisible(False) # set up the gui self._nCoresSB.setValue(SlurmSettings.N_CORES_PER_TASK) self._nWorkersSP.setValue(SlurmSettings.N_TASKS) self._memorySB.setValue(SlurmSettings.MEMORY_PER_WORKER) if self._queueCB.findText(SlurmSettings.PARTITION) >= 0: self._queueCB.setCurrentText(SlurmSettings.PARTITION) self._nGpuSB.setValue(n_gpu) self._jobName.setText(SlurmSettings.PROJECT_NAME) self._wallTimeQLE.setText(SlurmSettings.DEFAULT_WALLTIME) self._modulesCB.setChecked(True) # by default we go for modules self._warning_opd_p9.setVisible(False) self._warning_opd_export_opts.setVisible(False) self._warningWallTime.setVisible(False) self._preProcessingModeChanged() self._partitionChanged() self._sbatchAdvancedSettingsChanged() self._nGpuChanged() # connect signal / slot self._nCoresSB.valueChanged.connect(self._configurationChanged) self._nWorkersSP.valueChanged.connect(self._configurationChanged) self._memorySB.valueChanged.connect(self._configurationChanged) self._queueCB.currentTextChanged.connect(self._configurationChanged) self._queueCB.currentTextChanged.connect(self._updateWallTimeWarnings) self._queueCB.currentTextChanged.connect(self._updateWallTimeTooltip) self._nGpuSB.valueChanged.connect(self._configurationChanged) self._jobName.editingFinished.connect(self._configurationChanged) self._wallTimeQLE.editingFinished.connect(self._configurationChanged) self._wallTimeQLE.editingFinished.connect(self._updateWallTimeWarnings) self._wallTimeQLE.editingFinished.connect(self._updateWallTimeTooltip) self._pythonVenv.editingFinished.connect(self._configurationChanged) self._modulesQLE.editingFinished.connect(self._configurationChanged) self._preProcessingButtonGroup.buttonClicked.connect(self._configurationChanged) self._port.sigRangeChanged.connect(self._configurationChanged) self._dashboardPort.valueChanged.connect(self._configurationChanged) self._preProcessingButtonGroup.buttonClicked.connect( self._preProcessingModeChanged ) self._queueCB.currentTextChanged.connect(self._partitionChanged) self._nGpuSB.valueChanged.connect(self._nGpuChanged) self._gpuCardCB.currentTextChanged.connect(self._configurationChanged) self._exportValueCM.currentIndexChanged.connect(self._configurationChanged) self._exportValueCM.currentIndexChanged.connect( self._sbatchAdvancedSettingsChanged ) def _updateWallTimeWarnings(self): time_limit, _ = self._getPartitionWallTime(partition=self.getQueue()) palette = self._wallTimeQLE.palette() wall_time_limit_exceed = time_limit is not None and _WallTime( self.getWallTime() ) > _WallTime(time_limit) if wall_time_limit_exceed: palette.setColor(self.backgroundRole(), self.WALL_TIME_INVALID_COLOR) else: palette.setColor( self.backgroundRole(), self.__defaultWallTimeBackgroundColor ) self._warningWallTime.setVisible(wall_time_limit_exceed) self._wallTimeQLE.setPalette(palette) def _updateWallTimeTooltip(self): partition = self.getQueue() time_limit, default_wall_time = self._getPartitionWallTime(partition=partition) if time_limit is not None and default_wall_time is not None: tooltip = "\n".join( ( f"for partition {partition}:", f"time limit: {time_limit}", f"default limit: {default_wall_time}", ) ) else: tooltip = f"no wall time found for {partition}" self._wallTimeQLE.setToolTip(tooltip) self._warningWallTime.setToolTip(tooltip) def _nGpuChanged(self, *args, **kwargs): nGpu = self.getNGPU() self._gpuCardCB.setEnabled(nGpu > 0) def _configurationChanged(self, *args, **kwargs): self.sigConfigChanged.emit() def getNCores(self) -> int: return self._nCoresSB.value() def setNCores(self, n: int) -> None: self._nCoresSB.setValue(int(n)) def getNWorkers(self) -> int: return self._nWorkersSP.value() def setNWorkers(self, n) -> None: self._nWorkersSP.setValue(int(n)) def getMemory(self) -> int: return self._memorySB.value() def setMemory(self, memory: int) -> None: self._memorySB.setValue(int(memory)) def getQueue(self) -> str: return self._queueCB.currentText() def setQueue(self, text: str) -> None: self._queueCB.setCurrentText(text) def getNGPU(self) -> int: return self._nGpuSB.value() def setNGPU(self, n: int) -> None: self._nGpuSB.setValue(int(n)) def getNJobs(self) -> int: return self._nJobs.value() def setNJobs(self, value: int): self._nJobs.setValue(int(value)) def getProjectName(self): return self._jobName.text() def setProjectName(self, name): self._jobName.setText(name) def getWallTime(self): parts = self._wallTimeQLE.text().split(":") hours = parts[0] if len(parts) > 1: minutes = parts[1] else: minutes = "" if len(parts) > 2: seconds = parts[2] else: seconds = "" return ":".join( [ hours.zfill(2), minutes.zfill(2), seconds.zfill(2), ] ) def setWallTime(self, walltime): self._wallTimeQLE.setText(walltime) self._updateWallTimeWarnings() self._updateWallTimeTooltip() def getPythonExe(self): if self._sourceScriptCB.isChecked(): return self._pythonVenv.text() else: return None def setPythonExe(self, python_venv): self._pythonVenv.setText(python_venv) if python_venv != "": self._sourceScriptCB.setChecked(True) def getModulesToLoad(self) -> tuple: if self._modulesCB.isChecked(): return convert_str_to_tuple(self._modulesQLE.text()) else: return tuple() def setModulesToLoad(self, modules: tuple): if not isinstance(modules, (tuple, list)): raise TypeError( f"modules is expected to be a tuple or a list. Get {type(modules)} instead" ) self._modulesQLE.setText(str(modules)) if len(modules) > 0: self._modulesCB.setChecked(True) def getGpuCard(self) -> str | None: card = self._gpuCardCB.currentText() if card == "any" or self._nGpuSB == 0: return None else: return card def getSBatchExtraParams(self): return { "export": self._exportValueCM.currentText(), "gpu_card": self.getGpuCard(), } def setSBatchExtraParams(self, params: dict): export_ = params.get("export", None) if export_ is not None: index = self._exportValueCM.findText(export_) if index >= 0: self._exportValueCM.setCurrentIndex(index) gpu_card = params.get("gpu_card", None) if gpu_card is not None: index = self._gpuCardCB.findText("gpu_card") if index >= 0: self._gpuCardCB.setCurrentIndex(index) else: # policy when setting the extra params: if doesn't exists / found then won't set it. # because they can be part of .ows, this parameter is hidden by default. # so safer to use 'any' in the case it is unknown (debatable). _logger.warning(f"unable to find gpu {gpu_card}. Won't set it") def setConfiguration(self, config: dict) -> None: with block_signals(self): active_slurm = config.get("active_slurm", None) if active_slurm is not None: self._slurmCB.setChecked(active_slurm) n_cores = config.get("cpu-per-task", None) if n_cores is not None: self.setNCores(n_cores) n_workers = config.get("n_tasks", None) if n_workers is not None: self.setNWorkers(n_workers) memory = config.get("memory", None) if memory is not None: if isinstance(memory, str): memory = memory.replace(" ", "").lower().rstrip("gb") self.setMemory(int(memory)) queue_ = config.get("partition", None) if queue_ is not None: queue_ = queue_.rstrip("'").rstrip('"') queue_ = queue_.lstrip("'").lstrip('"') self.setQueue(queue_) n_gpu = config.get("n_gpus", None) if n_gpu is not None: self.setNGPU(int(n_gpu)) project_name = config.get("job_name", None) if project_name is not None: self.setProjectName(project_name) wall_time = config.get("walltime", None) if wall_time is not None: self.setWallTime(wall_time) python_venv = config.get("python_venv", None) if python_venv is not None: python_venv = python_venv.rstrip("'").rstrip('"') python_venv = python_venv.lstrip("'").lstrip('"') self.setPythonExe(python_venv) modules = config.get("modules", None) if modules is not None: modules = convert_str_to_tuple(modules) self.setModulesToLoad(modules) sbatch_extra_params = config.get("sbatch_extra_params", {}) self.setSBatchExtraParams(sbatch_extra_params) n_jobs = config.get("n_jobs", None) if n_jobs is not None: self.setNJobs(n_jobs) self._preProcessingModeChanged() # make sure modules and python venv is enabled according to the activate mode self.sigConfigChanged.emit() def getConfiguration(self) -> dict: config = { "cpu-per-task": self.getNCores(), "n_tasks": self.getNWorkers(), "n_jobs": self.getNJobs(), "memory": self.getMemory(), "partition": self.getQueue(), "n_gpus": self.getNGPU(), "job_name": self.getProjectName(), "walltime": self.getWallTime(), "sbatch_extra_params": self.getSBatchExtraParams(), } if self._modulesCB.isChecked(): config["modules"] = self.getModulesToLoad() elif self._sourceScriptCB.isChecked(): config["python_venv"] = self.getPythonExe() else: raise ValueError("'modules' or python environment should be enable") return config def getSlurmClusterConfiguration(self): from tomwer.core.cluster import SlurmClusterConfiguration return SlurmClusterConfiguration().from_dict(self.getConfiguration()) def _preProcessingModeChanged(self): self._modulesQLE.setEnabled(self._modulesCB.isChecked()) self._pythonVenv.setEnabled(self._sourceScriptCB.isChecked()) def setConfigurationLevel(self, level: ConfigurationLevel): self._sbatchAdvancedParameters.setVisible(level >= ConfigurationLevel.ADVANCED) self._wallTimeLabel.setVisible(level >= ConfigurationLevel.ADVANCED) self._wallTimeQLE.setVisible(level >= ConfigurationLevel.ADVANCED) def _partitionChanged(self, *args, **kwargs): partition = self.getQueue() # op(erator) accounts (from icc computers) cannot export to p9. they don't have home directories self._warning_opd_p9.setVisible( current_login_is_op_account() and partition.lower().startswith("p9") ) gpus = self._getGpus(partition=partition) self._gpuCardCB.clear() self._gpuCardCB.addItems(gpus) self._gpuCardCB.setCurrentText("any") def _sbatchAdvancedSettingsChanged(self, *args, **kwargs): # op(erator) accounts (from icc computers) must export ALL environment variable. Else job fails # warning: we want to display the warning no matter if we are in 'advance options' or not. # this way the user always see the warning when necessary self._warning_opd_export_opts.setVisible( current_login_is_op_account() and self._exportValueCM.currentText() == "NONE" ) @cache(maxsize=None) def _getGpus(self, partition) -> tuple: try: gpus = get_partition_gpus(partition) except Exception as e: _logger.error(f"Failed to detect GPU on {partition}. Error is {e}") gpus = ("any",) else: gpus = list(gpus) + [ "any", ] return gpus @cache(maxsize=None) def _getPartitionWallTime(self, partition: str) -> tuple[str | None, str | None]: try: times = get_partition_walltime(partition=partition) except Exception: return None, None else: return times["time"], times["default_time"] class _PortRangeSelection(qt.QWidget): sigRangeChanged = qt.Signal() """Signal emit when the port range change""" def __init__(self, parent=None) -> None: super().__init__(parent=parent) self.setLayout(qt.QHBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) # from label self._fromLabel = qt.QLabel("from", self) self._fromLabel.setAlignment(qt.Qt.AlignRight | qt.Qt.AlignVCenter) self.layout().addWidget(self._fromLabel) self._fromQSpinBox = qt.QSpinBox(self) self.layout().addWidget(self._fromQSpinBox) # to label self._toLabel = qt.QLabel("to", self) self._toLabel.setAlignment(qt.Qt.AlignRight | qt.Qt.AlignVCenter) self.layout().addWidget(self._toLabel) self._toQSpinBox = qt.QSpinBox(self) self.layout().addWidget(self._toQSpinBox) # steps label self._stepLabel = qt.QLabel("step", self) self._stepLabel.setAlignment(qt.Qt.AlignRight | qt.Qt.AlignVCenter) self.layout().addWidget(self._stepLabel) self._stepQSpinBox = qt.QSpinBox(self) self.layout().addWidget(self._stepQSpinBox) # connect signal / slot self._fromQSpinBox.valueChanged.connect(self._rangeChanged) self._toQSpinBox.valueChanged.connect(self._rangeChanged) self._stepQSpinBox.valueChanged.connect(self._rangeChanged) def _rangeChanged(self, *args, **kwargs): self.sigRangeChanged.emit() def getRange(self) -> tuple: return ( self._fromQSpinBox.value(), self._toQSpinBox.value(), self._stepQSpinBox.value(), ) def setRange(self, min_: int, max_: int, step: int | None = None) -> None: self._fromQSpinBox.setValue(min(min_, max_)) self._toQSpinBox.setValue(max(min_, max_)) if step is not None: self._stepQSpinBox.setValue(step) def get_login() -> str | None: try: return os.getlogin() except OSError: """In CI computer this raises the following error OSError: [Errno 6] No such device or address """ return None def current_login_is_op_account() -> bool: """ return True if the current login is a op[i]dXX login. """ return is_op_account(get_login()) def is_op_account(user: str | None) -> bool: """ Determines if a given username follows the 'op' account format, specifically 'opdXX' or 'opidXX', where 'XX' are numeric digits. Args: user (Optional[str]): The username to check. Returns: bool: True if the username matches the pattern, False otherwise. """ if user is None: return False op_account_pattern = r"^opi?d\d{2}$" return bool(re.match(op_account_pattern, user)) class _WallTime: """Util class to compare two walltime provided as D-HH:MM:SS or as HH:MM:SS""" def __init__(self, walltime: str): parts = walltime.split("-") if len(parts) > 1: assert len(parts) == 2, f"unexpected walltime format ({walltime})" days = int(parts[0]) else: days = 0 def minutes_to_seconds(value): return value * 60 def hours_to_seconds(value): return minutes_to_seconds(value * 60) def days_to_seconds(value): return hours_to_seconds(value * 24) hours, minutes, seconds = map(int, parts[-1].split(":")) self.value = ( seconds + minutes_to_seconds(minutes) + hours_to_seconds(hours) + days_to_seconds(days) ) def __lt__(self, other): return self.value < other.value def __gt__(self, other): return self.value > other.value def __eq__(self, other): return self.value == other.value ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/cluster/supervisor.py0000644000175000017500000003720015153325210021364 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import functools from collections import OrderedDict from silx.gui import qt from tomwer.core.futureobject import FutureTomwerObject try: from processview.gui.utils.qitem_model_resetter import qitem_model_resetter except ImportError: from tomwer.third_part.qitem_model_resetter import qitem_model_resetter class FutureTomwerScanObserverWidget(qt.QWidget): """Widget used to observe a set of :class:`FutureTomwerScan`""" sigConversionPolicyChanged = qt.Signal() """Signal emit when the user change rule for converting finished scan""" sigConversionRequested = qt.Signal(object) """signal emit when a conversion is requested. Parameter is the future scan""" def __init__(self, parent=None): super().__init__(parent) self.setLayout(qt.QVBoxLayout()) # filter widget self.filterWidget = FilterWidget(parent=self) self.layout().setContentsMargins(4, 4, 4, 4) self.layout().setSpacing(4) self.filterWidget.layout().setSpacing(4) self.layout().addWidget(self.filterWidget) # observation table self.observationTable = ObservationTable(self) self.layout().addWidget(self.observationTable) self.observationTable.setModel( _DatasetProcessModel(parent=self.observationTable, header=tuple()) ) self.observationTable.setSelectionBehavior(qt.QAbstractItemView.SelectRows) self.observationTable.resizeColumnsToContents() self.observationTable.setSortingEnabled(True) self.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding) # converter option self._commandWidget = qt.QWidget(self) self.layout().addWidget(self._commandWidget) self._commandWidget.setLayout(qt.QGridLayout()) self._commandWidget.setContentsMargins(0, 0, 0, 0) spacer = qt.QWidget(self._commandWidget) spacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) self._commandWidget.layout().addWidget(spacer, 0, 0, 1, 1) self._convertWhenFinished = qt.QCheckBox( "convert back to 'data' when finished", self ) self._commandWidget.layout().addWidget(self._convertWhenFinished, 0, 1, 1, 2) self._convertSelectedPB = qt.QPushButton(self) self._convertSelectedPB.setText("convert selected") self._commandWidget.layout().addWidget(self._convertSelectedPB, 1, 2, 1, 1) self._cancelSelectedPB = qt.QPushButton(self) self._cancelSelectedPB.setText("cancel selected") style = qt.QApplication.style() stopIcon = style.standardIcon(qt.QStyle.SP_BrowserStop) self._cancelSelectedPB.setIcon(stopIcon) self._commandWidget.layout().addWidget(self._cancelSelectedPB, 1, 1, 1, 1) # set up self._convertWhenFinished.setChecked(True) # connect signal / slot self.filterWidget.sigChanged.connect(self._filterUpdated) self._convertWhenFinished.toggled.connect(self._conversionPolicyChanged) self._convertSelectedPB.released.connect(self._convertSelected) self._cancelSelectedPB.released.connect(self._cancelSelected) def _convertSelected(self, *args, **kwargs): for cell in self.observationTable.selectionModel().selectedRows(): future_tomo_obj = self.observationTable.model().futureTomoObjs.get( cell.row(), None ) if future_tomo_obj is not None: self.sigConversionRequested.emit(future_tomo_obj) self.observationTable.model().updateIndices() self.observationTable.model().layoutChanged.emit() def _cancelSelected(self, *args, **kwargs): for cell in self.observationTable.selectionModel().selectedRows(): future_tomo_obj = self.observationTable.model().futureTomoObjs.get( cell.row(), None ) if future_tomo_obj is not None: future_tomo_obj.cancel() self.observationTable.model().layoutChanged.emit() def addFutureTomoObj(self, future_tomo_obj: FutureTomwerObject): self.observationTable.model().addFutureTomoObj(future_tomo_obj) def removeFutureTomoObj(self, future_tomo_obj: FutureTomwerObject): self.observationTable.model().removeFutureTomoObj(future_tomo_obj) def _filterUpdated(self): with qitem_model_resetter(self.observationTable.model()): self.observationTable.model().filtered_status = ( self.filterWidget.getFilteredStatus() ) def updateView(self): """ Update scan view and each future scan status """ self.observationTable.model().updateStatusAllFutureTomoObjs() self.observationTable.model().layoutChanged.emit() def convertWhenFinished(self): return self._convertWhenFinished.isChecked() def _conversionPolicyChanged(self, *args, **kwargs): self.sigConversionPolicyChanged.emit() def futureTomoObjs(self): return self.observationTable.model().futureTomoObjs def setConvertWhenFinished(self, convert): self._convertWhenFinished.setChecked(convert) class _DatasetProcessModel(qt.QAbstractTableModel): sigStatusUpdated = qt.Signal(object, str) """Signal emit when the status of scan changes""" def __init__(self, parent, header, *args): qt.QAbstractTableModel.__init__(self, parent, *args) self.header = header self.futureTomoObjs = OrderedDict() # key is index, value is scan self._filteredFutureTomoObjs = OrderedDict() # key is index, value is scan but only for the scan we want to display self._tomoObjStatus = dict() # key is the future scan, value is the status of the scan self._filteredStatus = tuple() # list of status to filter """FutureTomwerScan with this status will be hide""" self._headers = { 0: "start-time", 1: "dataset", 2: "status", 3: "requester", 4: "slurm-job", 5: "info", } self._headersI = {v: k for k, v in self._headers.items()} assert len(self._headers) == len(self._headersI), "insure values are unique" def is_filtered(self, future_scan): return future_scan.status in self._filteredStatus def _computeUnfilteredFutureTomoObjs(self): i_row = 0 self._filteredFutureTomoObjs = OrderedDict() for _, scan in self.futureTomoObjs.items(): if not self.is_filtered(scan): self._filteredFutureTomoObjs[i_row] = scan i_row += 1 return self._filteredFutureTomoObjs def endResetModel(self, *args, **kwargs): self._computeUnfilteredFutureTomoObjs() super().endResetModel(*args, **kwargs) def addFutureTomoObj(self, future_tomo_obj): if not isinstance(future_tomo_obj, FutureTomwerObject): raise TypeError( f"future_tomo_obj is expected to be an instance of {FutureTomwerObject} and not {type(future_tomo_obj)}" ) self.futureTomoObjs[len(self.futureTomoObjs)] = future_tomo_obj self._tomoObjStatus[future_tomo_obj] = "pending" for future in future_tomo_obj.futures: callback = functools.partial( self._updateStatus, future_tomo_obj=future_tomo_obj, ) # TODO: remove this since we are not using distributed anymore... class CallBack: # we cannot create a future directly because distributed enforce # the callback to have a function signature with only the future # as single parameter. def __init__(self, f_partial) -> None: self.f_partial = f_partial def process(self, fn): self.f_partial() future.add_done_callback(CallBack(callback).process) obj_index = len(self._filteredFutureTomoObjs) if not self.is_filtered(future_tomo_obj): self._filteredFutureTomoObjs[obj_index] = future_tomo_obj self.dataChanged.emit( self.createIndex(obj_index, 0), self.createIndex(obj_index, len(self._headers) - 1), ) self.layoutChanged.emit() def updateStatusAllFutureTomoObjs(self): for future_tomo_obj in self._tomoObjStatus: self._tomoObjStatus[future_tomo_obj] = future_tomo_obj.status def _updateStatus(self, future_tomo_obj): if future_tomo_obj is None: return status = future_tomo_obj.status trigger_update = ( future_tomo_obj not in self._tomoObjStatus or status != self._tomoObjStatus[future_tomo_obj] or status in ( "finished", "completed", ) # hack: when several finish at the same time, ensure the conversion is done :() ) if trigger_update: self._tomoObjStatus[future_tomo_obj] = status obj_index = list(self._tomoObjStatus.keys()).index(future_tomo_obj) try: self.sigStatusUpdated.emit(future_tomo_obj, status) except Exception: pass else: self.dataChanged.emit( self.createIndex(obj_index, 0), self.createIndex(obj_index, len(self._headers) - 1), ) def removeFutureTomoObj(self, future_tomo_obj): for container in (self.futureTomoObjs, self._filteredFutureTomoObjs): futureTomoObjsI = {v: k for k, v in container.items()} idx = futureTomoObjsI.get(future_tomo_obj, None) if idx is not None: del container[idx] if future_tomo_obj in self._tomoObjStatus: del self._tomoObjStatus[future_tomo_obj] self.layoutChanged.emit() def updateIndices(self): """ Update tomo object indices when a tomo object has been removed (during a convertion for example) """ tomo_objs = list(self.futureTomoObjs.values()) self.futureTomoObjs.clear() for i_tomo_obj, tomo_obj in enumerate(tomo_objs): self.futureTomoObjs[i_tomo_obj] = tomo_obj self._computeUnfilteredFutureTomoObjs() def getUnfilteredFutureTomoObjs(self): return self._filteredFutureTomoObjs @property def filtered_status(self): return self._filteredStatus @filtered_status.setter def filtered_status(self, filters): self._filteredStatus = filters self.layoutChanged.emit() def clear(self): self.futureTomoObjs = OrderedDict() self._filteredFutureTomoObjs = OrderedDict() self.layoutChanged.emit() def rowCount(self, parent=None): return len(self.getUnfilteredFutureTomoObjs()) def columnCount(self, parent=None): return len(self._headers) def headerData(self, col, orientation, role): if orientation == qt.Qt.Horizontal and role == qt.Qt.DisplayRole: if col < len(self._headers): return self._headers[col] else: return None def data(self, index, role): if not index.isValid(): return None if role not in (qt.Qt.DisplayRole, qt.Qt.ToolTipRole, qt.Qt.BackgroundRole): return None key = list(self._filteredFutureTomoObjs.keys())[index.row()] f_scan = self._filteredFutureTomoObjs[key] if role == qt.Qt.BackgroundRole: if index.column() in (self._headersI["status"],): # color are the same as the one defined by the process manager if f_scan.status == "error": return qt.QColor("#f52718") elif f_scan.status == "pending": return qt.QColor("#609ab3") elif f_scan.status == "cancelled": return qt.QColor("#fcba03") elif f_scan.status == "running": return qt.QColor("#839684") elif f_scan.status in ("finished", "completed"): return qt.QColor("#068c0c") elif role == qt.Qt.DisplayRole: col_type = self._headers[index.column()] if col_type == "start-time": return f_scan.start_time.strftime("%H:%M:%S") elif col_type == "dataset": return str(f_scan.tomo_obj.get_identifier()) elif col_type == "requester": from processview.core.manager import ProcessManager id_ = f_scan.process_requester_id process = ProcessManager().get_process(id_) if process is not None: return process.name else: return "unknown" elif col_type == "status": return f_scan.status elif col_type == "slurm-job": infos_job = ",".join( [ str(future.job_id) if hasattr(future, "job_id") else "" for future in f_scan.futures ] ) return infos_job class ObservationTable(qt.QTableView): def sizeHintForColumn(self, column): # warning: to be called we need to call resizeColumnsToContents upper if column == 1: # dataset column return 400 elif column in ( 0, 2, 3, 4, ): # start-time, status, requester, slurm-job return 55 elif column == 5: return 200 else: return super().sizeHintForColumn(column) class FilterWidget(qt.QGroupBox): """ Interface to define which future to be displayed """ sigChanged = qt.Signal() """signal emit when filter change""" def __init__(self, parent=None): super().__init__("show job with status", parent) self.setLayout(qt.QHBoxLayout()) # spacer spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) self.layout().addWidget(spacer) # pending self._pending = qt.QCheckBox("pending", self) self.layout().addWidget(self._pending) # running self._running = qt.QCheckBox("running", self) self.layout().addWidget(self._running) # finished self._finished = qt.QCheckBox("finished", self) self.layout().addWidget(self._finished) # error self._error = qt.QCheckBox("error", self) self.layout().addWidget(self._error) # cancelled self._cancelled = qt.QCheckBox("cancelled", self) self.layout().addWidget(self._cancelled) # set up self._pending.setChecked(True) self._cancelled.setChecked(True) self._running.setChecked(True) self._finished.setChecked(True) self._error.setChecked(True) # connect signal / slot self._pending.toggled.connect(self._updated) self._cancelled.toggled.connect(self._updated) self._running.toggled.connect(self._updated) self._finished.toggled.connect(self._updated) self._error.toggled.connect(self._updated) def _updated(self): self.sigChanged.emit() def getFilteredStatus(self): filters = [] cbs_filter = { "pending": self._pending, "cancelled": self._cancelled, "running": self._running, "finished": self._finished, "error": self._error, } for status, status_cb in cbs_filter.items(): if not status_cb.isChecked(): filters.append(status) return tuple(filters) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9331014 tomwer-1.6.17/src/tomwer/gui/cluster/tests/0000755000175000017500000000000015153325403017735 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/cluster/tests/__init__.py0000644000175000017500000000000014757047403022046 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/cluster/tests/test_cluster.py0000644000175000017500000000620615153325210023027 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import pytest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from tomwer.core.settings import SlurmSettings from tomwer.gui.cluster.slurm import ( is_op_account, SlurmSettingsMode, SlurmSettingsWidget, SlurmSettingsWindow, _WallTime, ) from tomwer.tests.utils import skip_gui_test from tomwer.tests.conftest import qtapp # noqa F401 @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestSlurmWidget(TestCaseQt): def setUp(self): TestCaseQt.setUp(self) self.slurmWidget = SlurmSettingsWidget(parent=None) def tearDown(self): self.slurmWidget.setAttribute(qt.Qt.WA_DeleteOnClose) self.slurmWidget.close() self.slurmWidget = None def testGetConfiguration(self): dict_res = self.slurmWidget.getConfiguration() expected_dict = { "cpu-per-task": SlurmSettings.N_CORES_PER_TASK, "n_tasks": SlurmSettings.N_TASKS, "memory": SlurmSettings.MEMORY_PER_WORKER, "partition": "", "n_gpus": SlurmSettings.N_GPUS_PER_WORKER, "job_name": "tomwer_{scan}_-_{process}_-_{info}", "n_jobs": 1, "modules": ("tomotools/stable",), "walltime": "01:00:00", "sbatch_extra_params": { "export": "ALL", "gpu_card": None, }, } assert dict_res == expected_dict, f"{dict_res} vs {expected_dict}" def testSetConfiguration(self): self.slurmWidget.setConfiguration( { "cpu-per-task": 2, "n_tasks": 3, "memory": 156, "partition": "test-queue", "n_gpus": 5, "modules": "mymodule, mysecond/10.3", "sbatch_extra_params": { "export": "NONE", }, } ) assert self.slurmWidget.getNCores() == 2 assert self.slurmWidget.getNWorkers() == 3 assert self.slurmWidget.getMemory() == 156 assert self.slurmWidget.getQueue() == "test-queue" assert self.slurmWidget.getNGPU() == 5 assert self.slurmWidget.getSBatchExtraParams() == { "export": "NONE", "gpu_card": None, } def test_SlurmSettingsWindow(qtapp): # noqa F811 """ test that slurm SettingsWindow can load all the different slurm settings modes """ widget = SlurmSettingsWindow() for mode in SlurmSettingsMode: widget.setCurrentSettingsMode(mode) widget.getConfiguration() def test_is_op_account(): assert is_op_account("opid19") assert not is_op_account("opid0") assert not is_op_account("dopid05") assert not is_op_account("opid") assert is_op_account("opd12") def test__WallTime(): assert _WallTime("11:00:02") > _WallTime("10:25:45") assert _WallTime("1-00:00:00") > _WallTime("10:25:45") assert _WallTime("01:00:0") < _WallTime("01:00:01") assert _WallTime("1-00:00:00") == _WallTime( "24:00:0" ), f"{_WallTime('1-00:00:00').value} != {_WallTime('24:00:0').value} " ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/cluster/tests/test_supervisor.py0000644000175000017500000000354715153325210023574 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import asyncio import os import shutil import tempfile from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from tomwer.core.futureobject import FutureTomwerObject from tomwer.core.utils.scanutils import MockNXtomo from tomwer.gui.cluster.supervisor import FutureTomwerScanObserverWidget class TestSupervisor(TestCaseQt): """Test the supervisor GUI""" def setUp(self): super().setUp() self.tempdir = tempfile.mkdtemp() # set up scans self._scans = [] self._future_tomo_objs = [] for i in range(5): # create scan scan = MockNXtomo( scan_path=os.path.join(self.tempdir, f"scan_test{i}"), n_proj=10, n_ini_proj=10, create_ini_dark=False, create_ini_flat=False, dim=10, ).scan self._scans.append(scan) # create future future = asyncio.Future() if i == 1: future.set_result(None) self._future_tomo_objs.append( FutureTomwerObject( tomo_obj=scan, futures=(future,), ) ) # set up gui self._supervisor = FutureTomwerScanObserverWidget() self._supervisor.setConvertWhenFinished(False) def tearDown(self): self._supervisor.setAttribute(qt.Qt.WA_DeleteOnClose) self._supervisor.close() self._supervisor = None shutil.rmtree(self.tempdir) self._scans.clear() self._future_tomo_objs.clear() super().tearDown() def test(self): for future_tomo_obj in self._future_tomo_objs: self._supervisor.addFutureTomoObj(future_tomo_obj=future_tomo_obj) self._supervisor.show() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9331014 tomwer-1.6.17/src/tomwer/gui/conditions/0000755000175000017500000000000015153325403017263 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/gui/conditions/__init__.py0000644000175000017500000000012014764622416021400 0ustar00paynopayno"""Widgets for conditions (filters to let a scan continue processing or not)""" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/conditions/filter.py0000644000175000017500000001021315153325210021113 0ustar00paynopayno# coding: utf-8 """ This module is used to define the process of the reference creator. This is related to the issue #184 """ from __future__ import annotations from silx.gui import qt from tomwer.core.process.conditions.filters import FileNameFilterTask from tomwer.gui import icons from tomwer.gui.utils.sandboxes import ( RegularExpressionSandBox, RegularExpressionSandBoxDialog, ) class FileNameFilterWidget(qt.QWidget): """ Simple widget allowing the user to define a pattern and emitting a signal 'sigValid' or 'sigUnvalid' if passing through the filter or not """ sigValid = qt.Signal(str) """Signal emitted when the string pass through the filter""" sigUnvalid = qt.Signal(str) """Signal emitted when the string doesn't pass through the filter""" def __init__(self, parent=None): super().__init__(parent) self.setLayout(qt.QGridLayout()) self._invertCB = qt.QCheckBox("Invert filter action", parent=self) self._invertCB.setToolTip( "If not inverted and match the filter " "condition then let the scan pass through" ) self.layout().addWidget(self._invertCB, 0, 0, 1, 3) self.layout().addWidget(qt.QLabel("filter type:", self), 1, 0) self._filterTypeCB = qt.QComboBox(parent=self) for filter_type in FileNameFilterTask.FILTER_TYPES: self._filterTypeCB.addItem(filter_type) self.layout().addWidget(self._filterTypeCB, 1, 1, 1, 2) self.layout().addWidget(qt.QLabel("pattern:", parent=self), 2, 0) self._patternLE = qt.QLineEdit(parent=self) self._patternLE.setToolTip(self.getPatternTooltip()) self.layout().addWidget(self._patternLE, 2, 1) icon = icons.getQIcon("information") self._sandBoxPB = qt.QPushButton(icon=icon, parent=self) # self._sandBoxPB.setPixmap(icon.pixmap(qt.QSize(32, 32))) self._sandBoxPB.setToolTip(RegularExpressionSandBox.description()) self._sandBoxPB.pressed.connect(self._showSandBox) self.layout().addWidget(self._sandBoxPB, 2, 2) # set up self._sandBoxPB.setVisible(False) self._filterTypeCB.setCurrentText(FileNameFilterTask._DEFAULT_FILTER_TYPE) self.sandboxDialog = None def _showSandBox(self): self.getSandboxDialog().show() def getSandboxDialog(self): if self.sandboxDialog is None: self.sandboxDialog = RegularExpressionSandBoxDialog( parent=None, pattern=self.getPattern() ) self.sandboxDialog.setModal(False) return self.sandboxDialog def getPatternTooltip(self): return ( "define the pattern to accept file using the python `re` " "library.\n" "For example if we two series of acquisition named serie_10_XXX\n" "and serie_100_YYY and we want to filter all the serie_10_XXX\n" 'then we can define the pattern "serie_100_" \n' "which will only let the serie_100_YYY go through." ) def _updateSandBoxPattern(self): self.getSandboxDialog().setPattern(self._patternLE.text()) def getPattern(self) -> str: return self._patternLE.text() def setPattern(self, pattern): self._patternLE.setText(pattern) def unvalidPatternDefinition(self, pattern, error): """Overwrite NameFilter.unvalidPatternDefinition""" title = "regular expression %s is invalid" % pattern mess = qt.QMessageBox( qt.QMessageBox.warning, title, parent=self, text=str(error) ) mess.setModal(False) mess.show() def setActiveFilter(self, filter_): valid_fiters = ("regular expression", "unix file name pattern") if filter_ not in valid_fiters: raise ValueError( f"filter is expected to be one of {valid_fiters}. Not {filter_}" ) self._sandBoxPB.setVisible(filter_ == "regular expression") self._filterTypeCB.setCurrentText(filter_) def getActiveFilter(self): return self._filterTypeCB.currentText() def invertFilterAction(self): return self._invertCB.isChecked() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9331014 tomwer-1.6.17/src/tomwer/gui/configuration/0000755000175000017500000000000015153325403017761 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/gui/configuration/__init__.py0000644000175000017500000000017314764622416022106 0ustar00paynopayno"""Widgets to define the configuration level we want to display (display only basic configuration/settings, advance...)""" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/configuration/action.py0000644000175000017500000000472014757047403021625 0ustar00paynopaynofrom silx.gui import qt from tomwer.gui import icons as tomwer_icons class MinimalisticConfigurationAction(qt.QAction): """ Action to display the 'minimalistic' options only """ def __init__(self, parent): self.__icon = tomwer_icons.getQIcon("minimalistic_user") qt.QAction.__init__(self, self.__icon, "minimalistic options", parent) self.setIconVisibleInMenu(True) self.setCheckable(True) self.setToolTip(self.tooltip()) def tooltip(self): return "configuration: minimalistic level limit the number of options" def icon(self): return self.__icon def text(self): return "Minimalistic configuration" class BasicConfigurationAction(qt.QAction): """ Action to display the 'basic' options only """ def __init__(self, parent): self.__icon = tomwer_icons.getQIcon("basic_user") qt.QAction.__init__(self, self.__icon, "basic options", parent) self.setIconVisibleInMenu(True) self.setCheckable(True) self.setToolTip(self.tooltip()) def tooltip(self): return "configuration: basic level limit the number of options" def icon(self): return self.__icon def text(self): return "Basic configuration" class ExpertConfigurationAction(qt.QAction): """ Action to display the 'advanced' / expert options """ def __init__(self, parent): self.__icon = tomwer_icons.getQIcon("advanced_user") qt.QAction.__init__(self, self.__icon, "advanced options", parent) self.setIconVisibleInMenu(True) self.setCheckable(True) self.setToolTip(self.tooltip()) def tooltip(self): return ( "configuration: advanced level give user all the possible \n" "option to tune the reconstructions" ) def icon(self): return self.__icon def text(self): return "Advanced configuration" class FilterAction(qt.QAction): """ Action to activate the filtering from the nabu stage """ def __init__(self, parent): style = qt.QApplication.style() icon = style.standardIcon(qt.QStyle.SP_FileDialogContentsView) qt.QAction.__init__(self, icon, "filter configuration", parent) self.setToolTip( "If activated will only display the configuration" "for the active nabu step" ) self.setCheckable(True) self.setShortcut(qt.QKeySequence(qt.Qt.Key_F)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/gui/configuration/level.py0000644000175000017500000000120215115744275021447 0ustar00paynopaynofrom enum import Enum as _Enum class ConfigurationLevel(_Enum): REQUIRED = "required" OPTIONAL = "optional" ADVANCED = "advanced" def _get_num_value(self) -> int: if self is self.REQUIRED: return 0 elif self is self.OPTIONAL: return 1 elif self is self.ADVANCED: return 2 def __le__(self, other): if not isinstance(other, ConfigurationLevel): raise TypeError( f"other is expected to be an instance of ConfigurationLevel. {type(other)} provided" ) return self._get_num_value() <= other._get_num_value() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9331014 tomwer-1.6.17/src/tomwer/gui/control/0000755000175000017500000000000015153325403016572 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/gui/control/__init__.py0000644000175000017500000000013414764622416020714 0ustar00paynopayno"""Widgets related to 'control' tasks (select a scan, convert a scan with nxtomomill...)""" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/control/_host.py0000644000175000017500000000020215143647637020271 0ustar00paynopaynofrom __future__ import annotations from dataclasses import dataclass @dataclass class Host: name: str | None port: int ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/gui/control/actions.py0000644000175000017500000000646515115744275020631 0ustar00paynopayno# coding: utf-8 from __future__ import annotations from silx.gui import qt from functools import partial from tomwer.gui import icons as tomwer_icons from tomwer.gui.control.tomoobjdisplaymode import DisplayMode class NXTomomillParamsAction(qt.QAction): """ Action to display a window with nxtomomill configuration """ def __init__(self, parent): icon = tomwer_icons.getQIcon("parameters") qt.QAction.__init__(self, icon, "filter configuration", parent) self.setToolTip("Open dialog to configure nxtomomill parameters") self.setCheckable(False) class CFGFileActiveLabel(qt.QLabel): """Label used to display if the .cfg file is active or not""" def __init__(self, parent): super().__init__(parent) icon = tomwer_icons.getQIcon("cfg_file_inactive") self.setToolTip("no valid cfg file provided") self.setPixmap(icon.pixmap(self.width(), self.height())) def setActive(self, active=True): if active is True: icon = tomwer_icons.getQIcon("cfg_file_active") tooltip = "will use the provided .cfg file" else: icon = tomwer_icons.getQIcon("cfg_file_inactive") tooltip = "will use default configuration" self.setPixmap(icon.pixmap(self.width(), self.height())) self.setToolTip(tooltip) def setInactive(self): self.setActive(active=False) class TomoObjDisplayModeToolButton(qt.QToolButton): """ Button to change the way tomo object are displayed. Either using the full url or only a 'short' description. """ sigDisplayModeChanged = qt.Signal(str) """signal emit when the display mode change""" _SHORT_DESC_TOOLTIP = "Use a short description of the tomo object. Two different scans can have the same short desciption" _URL_TOOLTIP = ( "Use the full url to display the tomo object. Url is guaranted to be unique." ) def __init__(self, parent=None) -> None: super().__init__(parent) self._shortDescIcon = tomwer_icons.getQIcon("short_description") shortDescAction = qt.QAction(self._shortDescIcon, "short description", self) shortDescAction.setToolTip(self._SHORT_DESC_TOOLTIP) self._urlIcon = tomwer_icons.getQIcon("url") urlDescAction = qt.QAction(self._urlIcon, "url", self) urlDescAction.setToolTip(self._URL_TOOLTIP) menu = qt.QMenu(self) menu.addAction(shortDescAction) menu.addAction(urlDescAction) self.setMenu(menu) self.setPopupMode(qt.QToolButton.InstantPopup) # set up self.setDisplayMode(DisplayMode.SHORT) # connect signal / slot shortDescAction.triggered.connect( partial(self.setDisplayMode, DisplayMode.SHORT) ) urlDescAction.triggered.connect(partial(self.setDisplayMode, DisplayMode.URL)) def setDisplayMode(self, mode: DisplayMode): mode = DisplayMode(mode) if mode is DisplayMode.SHORT: self.setIcon(self._shortDescIcon) self.setToolTip(self._SHORT_DESC_TOOLTIP) elif mode is DisplayMode.URL: self.setIcon(self._urlIcon) self.setToolTip(self._URL_TOOLTIP) else: raise ValueError(f"display mode {mode} not handled") self.sigDisplayModeChanged.emit(mode.value) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/control/datadiscovery.py0000644000175000017500000001376715153325210022017 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from tomwer.core.scan.scantype import ScanType from tomwer.gui.control import datareacheractions from tomwer.gui.control.datawatcher.controlwidget import ControlWidget class ScanDiscoveryConfigWidget(qt.QGroupBox): sigScanTypeChanged = qt.Signal() """emit when scan typo change""" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setLayout(qt.QVBoxLayout()) self._nxtomoQRB = qt.QRadioButton(ScanType.NX_TOMO.value, parent=self) self.layout().addWidget(self._nxtomoQRB) self._blissQRB = qt.QRadioButton(ScanType.BLISS.value, parent=self) self.layout().addWidget(self._blissQRB) self._specQRB = qt.QRadioButton(ScanType.SPEC.value, parent=self) self.layout().addWidget(self._specQRB) # set up self._nxtomoQRB.setChecked(True) # connect signal / slot self._nxtomoQRB.toggled.connect(self._configChanged) self._blissQRB.toggled.connect(self._configChanged) self._specQRB.toggled.connect(self._configChanged) def _configChanged(self, *args, **kwargs): self.sigScanTypeChanged.emit() def getScanType(self) -> ScanType: if self._specQRB.isChecked(): return ScanType.SPEC elif self._blissQRB.isChecked(): return ScanType.BLISS elif self._nxtomoQRB.isChecked(): return ScanType.NX_TOMO else: raise NotImplementedError def setScanType(self, mode: ScanType): mode = ScanType(mode) if mode is ScanType.SPEC: self._specQRB.setChecked(True) elif mode is ScanType.BLISS: self._blissQRB.setChecked(True) elif mode is ScanType.NX_TOMO: self._nxtomoQRB.setChecked(True) else: raise NotImplementedError class _MainWidget(qt.QWidget): sigStart = qt.Signal() def __init__(self, parent=None) -> None: super().__init__(parent) self.setLayout(qt.QVBoxLayout()) self.controlWidget = ControlWidget() self.layout().addWidget(self.controlWidget) self.configWidget = ScanDiscoveryConfigWidget(parent=self) self.layout().addWidget(self.configWidget) # set up self.configWidget.setVisible(False) self.controlWidget.setVisible(False) self.controlWidget._qpbstartstop.setText("start discovery") # connect signal / slot self.controlWidget._qpbstartstop.released.connect(self._startDiscovery) # expose api self.sigScanTypeChanged = self.configWidget.sigScanTypeChanged def getConfigWindow(self): return self.configWidget def _startDiscovery(self): self.sigStart.emit() def getFolderObserved(self): return self.controlWidget._qteFolderSelected.text() def setFolderObserved(self, dir_): return self.controlWidget._qteFolderSelected.setText(dir_) def getLinuxFilePattern(self) -> str | None: text = self.controlWidget._filterQLE.text() if text.replace(" ", "") == "": return None else: return text def setLinuxFilePattern(self, pattern: str | None): if pattern is None: pattern = "" self.controlWidget._filterQLE.setText(pattern) def setSearchScanType(self, scan_type): self.configWidget.setScanType(scan_type) def getSearchScqnType(self): return self.configWidget.getScanType() class DataDiscoveryWidget(qt.QMainWindow): sigTMStatusChanged = qt.Signal(str) """Signal emitted when the state changed""" sigScanReady = qt.Signal(object) """Signal emitted when a scan is considered as ready""" sigFolderObservedChanged = qt.Signal() """Signal emitted when the user change the observed folder""" sigObservationStart = qt.Signal() """Signal emitted when the observation starts""" sigObservationEnd = qt.Signal() """Signal emitted when the observation end""" sigFilterFileNamePatternChanged = qt.Signal(str) """Signal emut when the filter pattern change""" def __init__(self, parent=None, **kwargs) -> None: super().__init__(parent, **kwargs) self.setWindowFlags(qt.Qt.Widget) self._mainWidget = _MainWidget(parent=self) self.setCentralWidget(self.widget) # create toolbar toolbar = qt.QToolBar("", parent=self) toolbar.setIconSize(qt.QSize(32, 32)) self._controlAction = datareacheractions.ControlAction(parent=self) self._configurationAction = datareacheractions.ConfigurationAction(parent=self) toolbar.addAction(self._controlAction) toolbar.addAction(self._configurationAction) self._actionGroup = qt.QActionGroup(self) self._actionGroup.addAction(self._controlAction) self._actionGroup.addAction(self._configurationAction) self.addToolBar(qt.Qt.LeftToolBarArea, toolbar) toolbar.setMovable(False) # connect signal / slot self._controlAction.toggled[bool].connect( self._mainWidget.controlWidget.setVisible ) self._configurationAction.toggled[bool].connect( self._mainWidget.configWidget.setVisible ) self._controlAction.setChecked(True) def getConfiguration(self) -> dict: return { "start_folder": self.widget.getFolderObserved(), "file_filter": self.widget.getLinuxFilePattern(), "scan_type_searched": self.widget.getConfigWindow().getScanType().value, } def setConfiguration(self, config: dict): if "start_folder" in config: self.widget.setFolderObserved(config["start_folder"]) if "file_filter" in config: self.widget.setLinuxFilePattern(config["file_filter"]) type_searched = config.get("scan_type_searched", None) if type_searched is not None: self.widget.getConfigWindow().setScanType(type_searched) @property def widget(self) -> qt.QWidget: return self._mainWidget ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/control/datalist.py0000644000175000017500000012324615153325210020755 0ustar00paynopaynofrom __future__ import annotations import logging import os from collections import OrderedDict from typing import Any from nxtomomill import converter as nxtomomill_converter from nxtomomill.io import generate_default_edf_config, generate_default_h5_config from nxtomomill.models.h52nx import H52nxModel from nxtomomill.models.edf2nx import EDF2nxModel from silx.gui import qt from tomoscan.esrf.volume.utils import guess_volumes from tomoscan.identifier import BaseIdentifier from tomoscan.esrf.identifier.hdf5Identifier import NXtomoScanIdentifier from tomwer.core.scan.blissscan import BlissScan from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.tomwer_object import TomwerObject from tomwer.core.volume.volumefactory import VolumeFactory from tomwer.io.utils.tomoobj import DEFAULT_SCHEME_TO_VOL from tomwer.gui.control.actions import CFGFileActiveLabel, NXTomomillParamsAction from tomwer.gui.dialog.QDataDialog import QDataDialog from tomwer.gui.dialog.QVolumeDialog import QVolumeDialog from tomwer.gui.utils.inputwidget import ( EDFConfigFileSelector, HDF5ConfigFileSelector, NXTomomillOutputDirSelector, ) from tomwer.gui.utils.qt_utils import block_signals from tomwer.gui.control.tomoobjdisplaymode import DisplayMode from tomwer.gui.control.actions import TomoObjDisplayModeToolButton from tomwer.gui import icons logger = logging.getLogger(__name__) class _DataListDialog(qt.QDialog): """A simple list of dataset path.BlissHDF5DataListDialog .. warning: the widget won't check for scan validity and will only emit the path to folders to the next widgets :param parent: the parent widget """ sigUpdated = qt.Signal() """signal emitted when the list is updated""" def __init__(self, parent=None): qt.QDialog.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) # add list self.datalist = self.createDataList() self.layout().addWidget(self.datalist) # add buttons self._buttons = qt.QDialogButtonBox(parent=self) self._addButton = qt.QPushButton("Add", parent=self) self._buttons.addButton(self._addButton, qt.QDialogButtonBox.ActionRole) self._rmButton = qt.QPushButton("Remove", parent=self) self._buttons.addButton(self._rmButton, qt.QDialogButtonBox.ActionRole) self._rmAllButton = qt.QPushButton("Remove all", parent=self) self._buttons.addButton(self._rmAllButton, qt.QDialogButtonBox.ActionRole) self._sendSelectedButton = qt.QPushButton("Send selected", parent=self) self._buttons.addButton( self._sendSelectedButton, qt.QDialogButtonBox.AcceptRole ) self.layout().addWidget(self._buttons) # connect signal / slot self._addButton.clicked.connect(self._callbackAddPath) self._rmButton.clicked.connect(self._removeSelected) self._rmAllButton.clicked.connect(self._callbackRemoveAllFolders) def selectAll(self): return self.datalist.selectAll() def clear(self): self.datalist.clear() def add(self, scan) -> tuple: added_objs = self.datalist.add(scan) self.datalist.setMySelection(added_objs) self.sigUpdated.emit() return added_objs def remove(self, scan): self.datalist.remove(scan) self.sigUpdated.emit() def n_scan(self): return len(self.datalist._myitems) def _callbackAddPath(self): """ """ self.sigUpdated.emit() def _removeSelected(self): """remove all selected items""" selected_items = self.datalist.selectedItems() tomwer_objs_to_remove = [item.data(qt.Qt.UserRole) for item in selected_items] for tomwer_obj in tomwer_objs_to_remove: self.remove(tomwer_obj) self.sigUpdated.emit() def _callbackRemoveAllFolders(self): self.datalist.selectAll() self._removeSelected() def createDataList(self): raise NotImplementedError("Base class") class _NXtomomillConfigFileDialog(qt.QDialog): sigConfigFileChanged = qt.Signal(str) sigOutputdirChanged = qt.Signal() sigMechanicalFlipsChanged = qt.Signal() def __init__( self, parent, warning: str, callback_new_config_file: Any, ConfigFileSelectorClass: Any, ): super().__init__(parent) self.setLayout(qt.QFormLayout()) self._warningLabel = qt.QLabel(warning, self) self._warningLabel.setWordWrap(False) font = self._warningLabel.font() font.setItalic(True) font.setPixelSize(12) self._warningLabel.setFont(font) self._warningLabel.setAlignment(qt.Qt.AlignLeft | qt.Qt.AlignVCenter) #: add left intendation + lower size + italic self.layout().addRow(self._warningLabel) # handle configuration file self._configurationWidget = ConfigFileSelectorClass(self, try_load_cfg=False) self.layout().addRow("configuration file", self._configurationWidget) # button to create a default configuration file self._cdcfWidget = qt.QWidget(self) # widget for layout self._cdcfWidget.setLayout(qt.QHBoxLayout()) self._cdcfSpacer = qt.QWidget(self._cdcfWidget) self._cdcfSpacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) self._cdcfWidget.layout().addWidget(self._cdcfSpacer) self._createDefaultConfigFileB = qt.QPushButton( "create new default configuration file", self._cdcfWidget ) self._cdcfWidget.layout().addWidget(self._createDefaultConfigFileB) self.layout().addRow(self._cdcfWidget) # vline 1 self._vLine1 = qt.QFrame() self._vLine1.setFrameShape(qt.QFrame.Shape.HLine) self._vLine1.setFrameShadow(qt.QFrame.Shadow.Sunken) self.layout().addRow(self._vLine1) # mechanical flips self._lrMechanicalFlipLabel = qt.QLabel() lr_icon = icons.getQIcon("lr_mirroring") self._lrMechanicalFlip = qt.QCheckBox() self._lrMechanicalFlip.setIcon(lr_icon) self._lrMechanicalFlip.setToolTip( "Detector image is flipped **left-right** for mechanical reasons that are not propagated with bliss-tomo hdf5 metadata (mirror,..)." ) self.layout().addRow("left-right mechanical flip", self._lrMechanicalFlip) self._udMechanicalFlipLabel = qt.QLabel("left-right mechanical flip") ud_icon = icons.getQIcon("ud_mirroring") self._udMechanicalFlip = qt.QCheckBox() self._udMechanicalFlip.setIcon(ud_icon) self._udMechanicalFlip.setToolTip( "Detector image is flipped **up-down** for mechanical reasons that are not propagated with bliss-tomo hdf5 metadata (mirror,..)." ) self.layout().addRow("up-down mechanical flip", self._udMechanicalFlip) # vline 2 self._vLine2 = qt.QFrame() self._vLine2.setFrameShape(qt.QFrame.Shape.HLine) self._vLine2.setFrameShadow(qt.QFrame.Shadow.Sunken) self.layout().addRow(self._vLine2) # handle configuration file self._nxTomomillOutputWidget = NXTomomillOutputDirSelector() self.layout().addRow("nexus file output dir", self._nxTomomillOutputWidget) # buttons types = qt.QDialogButtonBox.Ok self.__buttons = qt.QDialogButtonBox(parent=self) self.__buttons.setStandardButtons(types) self.layout().addWidget(self.__buttons) # connect signal / slot self.__buttons.accepted.connect(self.accept) if callback_new_config_file is not None: self._createDefaultConfigFileB.released.connect(callback_new_config_file) self._configurationWidget.sigConfigFileChanged.connect( self.sigConfigFileChanged ) self._nxTomomillOutputWidget.sigChanged.connect(self.sigOutputdirChanged) self._lrMechanicalFlip.toggled.connect(self.sigMechanicalFlipsChanged) self._udMechanicalFlip.toggled.connect(self.sigMechanicalFlipsChanged) def setNewconfigFileCreationCallback(self, callback): self._createDefaultConfigFile = callback def getCFGFilePath(self): return self._configurationWidget.getCFGFilePath() def setCFGFilePath(self, cfg_file): self._configurationWidget.setCFGFilePath(cfg_file) def getOutputFolder(self): return self._nxTomomillOutputWidget.getOutputFolder() def setOutputDialog(self, output_dir): self._nxTomomillOutputWidget.setOutputFolder(output_dir) def accept(self): self.hide() def _createConfigFileSelector(self): raise NotImplementedError def getMechanicalFlips(self) -> tuple[bool, bool]: """ :return: mechanical flips as (left-right, up-down) """ return self._lrMechanicalFlip.isChecked(), self._udMechanicalFlip.isChecked() def setMechanicalFlips(self, lr_flip: bool, ud_flip: bool) -> None: self._lrMechanicalFlip.setChecked(lr_flip) self._udMechanicalFlip.setChecked(ud_flip) class BlissHDF5DataListDialog(_DataListDialog): """Dialog used to load .h5 files only (used for nxtomomillOW when we need to do a conversion from bliss.h5 to NXtomo)""" def __init__(self, parent): assert isinstance(parent, _RawDataListMainWindow) _DataListDialog.__init__(self, parent) self._sendSelectedButton.setText("Send selected") def createDataList(self): return BlissScanList(self) def _callbackAddPath(self): # pragma: no cover """Open file dialog to select HDF5 files or directories, allowing multi-selection""" dialog = qt.QFileDialog(self) dialog.setFileMode(qt.QFileDialog.ExistingFiles) dialog.setNameFilters( [ "HDF5 files (*.h5 *.hdf5)", "Nexus files (*.h5 *.hdf5 *.nx *.nxs *.nexus)", "Any files (*)", ] ) # Set default directory if available if os.environ.get("TOMWER_DEFAULT_INPUT_DIR", None) and os.path.exists( os.environ["TOMWER_DEFAULT_INPUT_DIR"] ): dialog.setDirectory(os.environ["TOMWER_DEFAULT_INPUT_DIR"]) elif dialog.directory() != os.getcwd() or str(dialog.directory()).startswith( "/data" ): # if the directory as already been set by the user. Avoid redefining it pass elif os.path.isdir("/data"): dialog.setDirectory("/data") if not dialog.exec(): dialog.close() return filesSelected = dialog.selectedFiles() added_scans = [] for file_ in filesSelected: added_scans = self.add(file_) if added_scans is None: continue added_scans.extend(added_scans) super()._callbackAddPath() self.datalist.setMySelection(added_scans) class EDFDataListDialog(_DataListDialog): """Dialog used to load EDF directories and files for conversion""" def __init__(self, parent): assert isinstance(parent, EDFDataListMainWindow) _DataListDialog.__init__(self, parent) self._sendSelectedButton.setText("Convert and send selected") def createDataList(self): return EDFDataList(self) def _callbackAddPath(self): # pragma: no cover """Open file dialog to select EDF directories or files""" dialog = qt.QFileDialog(self) dialog.setFileMode(qt.QFileDialog.DirectoryOnly) # Set default directory if available if os.environ.get("TOMWER_DEFAULT_INPUT_DIR", None) and os.path.exists( os.environ["TOMWER_DEFAULT_INPUT_DIR"] ): dialog.setDirectory(os.environ["TOMWER_DEFAULT_INPUT_DIR"]) elif os.path.isdir("/data"): dialog.setDirectory("/data") if not dialog.exec(): dialog.close() return filesSelected = dialog.selectedFiles() added_scans = [] for file_ in filesSelected: added = self.add(file_) assert added is not None added_scans.extend(added) super()._callbackAddPath() self.datalist.setMySelection(added_scans) class _RawDataListMainWindow(qt.QMainWindow): sigNXTomoCFGFileChanged = qt.Signal(str) """signal emitted when the configuration file change""" sigUpdated = qt.Signal() """signal emitted when the list of raw data to convert change""" def __init__( self, parent, DataListConstructor, ConfigClass, warning, ConfigFileSelectorClass ): super().__init__(parent) self._widget = DataListConstructor(self) self.__configConstructor = ConfigClass # rework BlissHDF5DataListDialog layout self._subWidget = qt.QWidget(self) self._subWidget.setLayout(qt.QVBoxLayout()) self._subWidget.layout().addWidget(self._widget.datalist) self._subWidget.layout().addWidget(self._widget._buttons) self.setCentralWidget(self._subWidget) self._dialog = _NXtomomillConfigFileDialog( self, warning=warning, callback_new_config_file=self._createNewConfigFile, ConfigFileSelectorClass=ConfigFileSelectorClass, ) self._dialog.setWindowTitle("Select nxtomomill configuration file") # add toolbar toolbar = qt.QToolBar(self) toolbar.setMovable(False) toolbar.setFloatable(False) self.addToolBar(qt.Qt.TopToolBarArea, toolbar) # add filtering self._parametersAction = NXTomomillParamsAction(toolbar) toolbar.addAction(self._parametersAction) self._parametersAction.triggered.connect(self._parametersTriggered) # add tomo obj display mode self._tomoObjdisplayAction = TomoObjDisplayModeToolButton(self) toolbar.addWidget(self._tomoObjdisplayAction) # toolbar spacer spacer = qt.QWidget(toolbar) spacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) toolbar.addWidget(spacer) # add information if cfg file is activate or not self._cfgStatusLabel = CFGFileActiveLabel(toolbar) toolbar.addWidget(self._cfgStatusLabel) # expose API self.getCFGFilePath = self._dialog.getCFGFilePath self.setCFGFilePath = self._dialog.setCFGFilePath self._sendSelectedButton = self._widget._sendSelectedButton self.add = self._widget.add self.n_scan = self._widget.n_scan self.datalist = self._widget.datalist # connect signal / slot self._dialog.sigConfigFileChanged.connect(self._cfgFileChanged) self._dialog.sigOutputdirChanged.connect(self.sigUpdated) self._dialog.sigMechanicalFlipsChanged.connect(self.sigUpdated) self._widget.sigUpdated.connect(self.sigUpdated) self._tomoObjdisplayAction.sigDisplayModeChanged.connect(self.setDisplayMode) def setDisplayMode(self, *args, **kwargs): self.datalist.setDisplayMode(*args, **kwargs) def getOutputFolder(self): return self._dialog.getOutputFolder() def setOutputFolder(self, output_dir): self._dialog.setOutputDialog(output_dir) def _parametersTriggered(self): self._dialog.show() self._dialog.raise_() def _cfgFileChanged(self): cfg_file = self._dialog.getCFGFilePath() if cfg_file in (None, "") or not os.path.exists(cfg_file): self._cfgStatusLabel.setInactive() elif os.path.exists(cfg_file): try: self._load_cfg_file(cfg_file=cfg_file) except Exception: self._cfgStatusLabel.setInactive() else: self._cfgStatusLabel.setActive() else: self._cfgStatusLabel.setInactive() if cfg_file is None: cfg_file = "" self.sigNXTomoCFGFileChanged.emit(cfg_file) def _load_cfg_file(self, cfg_file): """The idea is to load the file before using it. This way the user can see if something is wrong with the file""" raise NotImplementedError("Base class") def getConfigInstance(self): """Return default HDF5Config or the one created from use input""" cfg_file = self._dialog.getCFGFilePath() if cfg_file in (None, ""): return self.__configConstructor() else: try: config = self.__configConstructor.from_cfg_file(cfg_file) except Exception: return self.__configConstructor() else: return config def createNXtomomillConfigFileDialog(self): # pragma: no cover file_dialog = qt.QFileDialog() file_dialog.setAcceptMode(qt.QFileDialog.AcceptSave) file_dialog.setWindowTitle("Select file path to save configuration file") file_dialog.setNameFilters( [ "Any file (*)", "Configuration file (*.txt *.cfg *.conf *.config)", ] ) file_dialog.setFileMode(qt.QFileDialog.AnyFile) return file_dialog def _createNewConfigFile(self): """ callback for the configuration file creation """ raise NotImplementedError("Base class") class BlissHDF5DataListMainWindow(_RawDataListMainWindow): def __init__(self, parent, *args, **kwargs): super().__init__( parent, DataListConstructor=BlissHDF5DataListDialog, ConfigClass=H52nxModel, warning="""Note: some parameters of the configuration file will be ignored:\n - input_file will be replaced from the item of the data list treated - output_file will be deduce from the output folder you defined""", ConfigFileSelectorClass=HDF5ConfigFileSelector, *args, **kwargs, ) def _createNewConfigFile(self): # pragma: no cover file_dialog = self.createNXtomomillConfigFileDialog() if file_dialog.exec(): files_selected = file_dialog.selectedFiles() if len(files_selected) > 0: file_path = files_selected[0] try: # nxtomomill 1.1.0a5 or higher configuration = ( generate_default_h5_config() # pylint: disable=E1123 ) except TypeError: configuration = generate_default_h5_config( # pylint: disable=E1123 config_3dxrd=False ) H52nxModel.dict_to_cfg(file_path=file_path, dict_=configuration) # if we create a configuration file then let consider we want to use it self.setCFGFilePath(file_path) def _load_cfg_file(self, cfg_file): H52nxModel.from_cfg_file(cfg_file) def setConfiguration(self, config: dict): if not isinstance(config, H52nxModel): raise TypeError self.datalist.configuration = config class EDFDataListMainWindow(_RawDataListMainWindow): def __init__(self, parent, *args, **kwargs): super().__init__( parent, DataListConstructor=EDFDataListDialog, ConfigClass=EDF2nxModel, warning="""Note: some parameters of the configuration file will be ignored:\n - input_folder will be replaced from the item of the data list treated - dataset_basename (if will be deduce when the input folder is provided) - output_file will be deduce from the output folder you defined""", ConfigFileSelectorClass=EDFConfigFileSelector, *args, **kwargs, ) def _createNewConfigFile(self): # pragma: no cover file_dialog = self.createNXtomomillConfigFileDialog() if file_dialog.exec(): files_selected = file_dialog.selectedFiles() if len(files_selected) > 0: file_path = files_selected[0] configuration = generate_default_edf_config(level="advanced") EDF2nxModel.dict_to_cfg(file_path=file_path, dict_=configuration) # if we create a configuration file then let consider we want to use it self.setCFGFilePath(file_path) def _load_cfg_file(self, cfg_file): EDF2nxModel.from_cfg_file(cfg_file) class GenericScanListDialog(_DataListDialog): """Dialog used to load EDFScan or HDF5 scans""" def createDataList(self): return GenericScanList(self) def _callbackAddPath(self): # pragma: no cover """ """ dialog = QDataDialog(self, multiSelection=True) dialog.setNameFilters( [ "HDF5 files (*.h5 *.hdf5 *.nx *.nxs *.nexus)", "Nexus files (*.nx *.nxs *.nexus)", "Any files (*)", ] ) if not dialog.exec(): dialog.close() return files_or_folders = dialog.files_selected() added_scans = [] for file_or_folder in files_or_folders: new_scans = self.add(file_or_folder) if new_scans is not None: added_scans.extend(new_scans) super()._callbackAddPath() self.datalist.setMySelection(added_scans) class GenericScanListWindow(qt.QMainWindow): def __init__(self, parent=None) -> None: super().__init__(parent) self.setWindowFlags(qt.Qt.Widget) self._widget = GenericScanListDialog() self.datalist = self._widget.datalist self.setCentralWidget(self._widget) # toolbar toolbar = qt.QToolBar() toolbar.setMovable(False) toolbar.setFloatable(False) self.addToolBar(qt.Qt.TopToolBarArea, toolbar) tomoObjdisplayAction = TomoObjDisplayModeToolButton(self) toolbar.addWidget(tomoObjdisplayAction) # set up self.setDisplayMode(DisplayMode.SHORT) # expose API self.sigUpdated = self._widget.sigUpdated # connect signal / slot tomoObjdisplayAction.sigDisplayModeChanged.connect(self.setDisplayMode) def setDisplayMode(self, display_mode: DisplayMode): self.datalist.setDisplayMode(display_mode) # expose API def n_scan(self): return self._widget.n_scan() def add(self, *args, **kwargs): return self._widget.add(*args, **kwargs) class VolumeListDialog(_DataListDialog): """Dialog used to load EDFScan or HEDF5 scans""" def createDataList(self): return VolumeList(self) def _callbackAddPath(self): # pragma: no cover """ """ dialog = QVolumeDialog(self) if not dialog.exec(): dialog.close() return files_or_folders = dialog.files_selected() added_volumes = [] for file_or_folder in files_or_folders: new_volumes = self.add(file_or_folder) if new_volumes is not None: added_volumes.extend(new_volumes) super()._callbackAddPath() self.datalist.setMySelection(added_volumes) class _TomwerObjectList(qt.QTableWidget): HEADER_NAMES = ("undefined object",) dataReady = qt.Signal(TomwerObject) listChanged = qt.Signal() """emit when containt of the list changed""" def __init__(self, parent): self._copy_target = None qt.QTableWidget.__init__(self, parent) self.setRowCount(0) self.setColumnCount(1) self.setHorizontalHeaderLabels(self.HEADER_NAMES) self.setSortingEnabled(True) self.verticalHeader().hide() if hasattr(self.horizontalHeader(), "setSectionResizeMode"): # Qt5 self.horizontalHeader().setSectionResizeMode(0, qt.QHeaderView.Stretch) else: # Qt4 self.horizontalHeader().setResizeMode(0, qt.QHeaderView.Stretch) self.setAcceptDrops(True) self._myitems = OrderedDict() # key is the TomoObject identifier and value is the QTableWidgetItem. # Text is the identifier, QTableWidgetItem data under UserRole is the TomoObject object # QMenu self.menu = qt.QMenu(self) self._copyAction = qt.QAction("copy") self._copyAction.triggered.connect(self._copyRequested) self._pasteAction = qt.QAction("paste") self._pasteAction.triggered.connect(self._pasteRequested) self.menu.addAction(self._copyAction) self.menu.addAction(self._pasteAction) self.setDisplayMode(DisplayMode.SHORT) def setDisplayMode(self, mode: DisplayMode) -> None: self._displayMode = DisplayMode(mode) self._update() def n_data(self): return len(self._myitems) def remove_item(self, item): """Remove a given folder""" try: del self._myitems[item.data(qt.Qt.UserRole).get_identifier().to_str()] except RuntimeError: # look like this could failed on some Qt or PyQt version (see issue 802) # no much that we can do so ignore it. pass self._update() def _sendSelected(self): raise NotImplementedError for _, item in self._myitems.items(): data = item.data(qt.Qt.UserRole) self.dataReady.emit(data) def remove(self, data: TomwerObject | str | None): if data is None: return if isinstance(data, str): data = self._getTomoObject(data, allow_several=False) if data is None: logger.warning(f"unable to get a {TomwerObject} from {data}") return identifier_as_str = data.get_identifier().to_str() if not isinstance(data, TomwerObject): raise ValueError(f"{data} is not a TomwerObject") identifier_as_str = data.get_identifier().to_str() if identifier_as_str not in self._myitems: logger.info(f"{identifier_as_str} not in {self._myitems}") return else: item = self._myitems[identifier_as_str] self.remove_item(item) self.listChanged.emit() def _update(self): tomwer_objects = [ self._myitems[identifier_as_str].data(qt.Qt.UserRole) for identifier_as_str in self._myitems.keys() ] self.clear() with block_signals(self): for tomwer_object in tomwer_objects: self.add(tomwer_object) self.sortByColumn(0, self.horizontalHeader().sortIndicatorOrder()) self.listChanged.emit() def _getTomoObject(self, obj: str, allow_several: bool = False): """ some rules to return a TomwerObject from an object (probably a path) from children class :param allow_several: allow returning several objects for one input. This can be the case for example if 'obj' is a file path. """ raise NotImplementedError("Base class") def add(self, obj: TomwerObject | BaseIdentifier | str | None) -> tuple | None: """add a data""" if obj is None: return if isinstance(obj, TomwerObject): # remove heavy cache obj. This could bring troubles if some processing is done. # but I guess this is better than keeping in memory volumes... # nevertheless processing using volume.data should keep a reference on the data. obj._clear_heavy_cache() elif isinstance(obj, str): obj = self._getTomoObject(obj, allow_several=True) if obj is None: return elif isinstance(obj, (tuple, list)): # in the case it contains in fact several objects. Related to allow_several=True new_objs = [] for o in obj: new_objs.extend(list(self.add(o))) return new_objs elif not isinstance(obj, TomwerObject): raise TypeError( f"return object from _getTomoObject is not a {TomwerObject} but {type(obj)}" ) elif isinstance(obj, BaseIdentifier): try: obj = ScanFactory.create_tomo_object_from_identifier(obj) except Exception: try: obj = VolumeFactory.create_tomo_object_from_identifier(obj) except Exception: raise ValueError(f"Unable to create an TomwerObject from {obj}") else: raise TypeError( f"is expected to be an instance of str or of {TomwerObject} but {type(obj)}" ) identifier_as_str = obj.get_identifier().to_str() if identifier_as_str in self._myitems: # in this case we will update the value. Because if the same identifier already exists at launch time # it will create two different objects that could be an issue. # this is better to have it unified with block_signals(self): self.remove(self._myitems[identifier_as_str].data(qt.Qt.UserRole)) item = qt.QTableWidgetItem() item.setText(self.getTextToDisplay(obj)) item.setFlags(qt.Qt.ItemIsEnabled | qt.Qt.ItemIsSelectable) item.setData(qt.Qt.UserRole, obj) row = self.rowCount() self.setRowCount(row + 1) self.setItem(row, 0, item) self._myitems[identifier_as_str] = item self.listChanged.emit() return (obj,) def getTextToDisplay(self, obj: TomwerObject): if self._displayMode is DisplayMode.SHORT: return obj.get_identifier().short_description() elif self._displayMode is DisplayMode.URL: return obj.get_identifier().to_str() else: raise ValueError( f"Requested display mode {self._displayMode} is not handled" ) def setMySelection(self, datasets: tuple[str | TomwerObject]): if datasets is None: datasets = tuple() def convert_dataset(dataset: str | TomwerObject): if isinstance(dataset, TomwerObject): return dataset.get_identifier().to_str() else: return dataset datasets = tuple([convert_dataset(dataset) for dataset in datasets]) for row in range(self.rowCount()): item = self.item(row, 0) select_it = ( item.data(qt.Qt.UserRole).get_identifier().to_str() in datasets or item.text() in datasets ) item.setSelected(select_it) def clear(self): """Remove all items on the list""" self._myitems = OrderedDict() qt.QTableWidget.clear(self) self.setRowCount(0) self.setHorizontalHeaderLabels(self.HEADER_NAMES) if hasattr(self.horizontalHeader(), "setSectionResizeMode"): # Qt5 self.horizontalHeader().setSectionResizeMode(0, qt.QHeaderView.Stretch) else: # Qt4 self.horizontalHeader().setResizeMode(0, qt.QHeaderView.Stretch) def dropEvent(self, event): if event.mimeData().hasFormat("text/uri-list"): added_scans = set() with block_signals(self): for url in event.mimeData().urls(): new_scans = self.add(str(url.path())) if new_scans is not None: for new_scan in new_scans: if not isinstance(new_scan, TomwerObject): raise ValueError( f"new_scan should be an instance of {TomwerObject} and not {type(new_scan)}" ) added_scans.update(new_scans) self.setMySelection(added_scans) self.listChanged.emit() def supportedDropActions(self): """Inherited method to redefine supported drop actions.""" return qt.Qt.CopyAction | qt.Qt.MoveAction def dragEnterEvent(self, event): if hasattr(event, "mimeData") and event.mimeData().hasFormat("text/uri-list"): event.accept() event.setDropAction(qt.Qt.CopyAction) else: try: qt.QListWidget.dragEnterEvent(self, event) except TypeError: pass def dragMoveEvent(self, event): if hasattr(event, "mimeDatamyitems") and event.mimeDatamyitems().hasFormat( "text/uri-list" ): event.setDropAction(qt.Qt.CopyAction) event.accept() else: try: qt.QListWidget.dragMoveEvent(self, event) except TypeError: pass def _datasetAt(self, point): item = self.itemAt(point) if item is not None: return item.data(qt.Qt.UserRole) def contextMenuEvent(self, event): self._copy_target = self._datasetAt(event.pos()) self._copyAction.setVisible(self._copy_target is not None) self.menu.exec(event.globalPos()) def _copyRequested(self): clipboard = qt.QGuiApplication.clipboard() def get_info(item): user_data = item.data(qt.Qt.UserRole) if isinstance(user_data, TomwerObject): return user_data.get_identifier().to_str() else: return str(user_data) selection = [get_info(item) for item in self.selectedItems()] clipboard.setText("\n".join(selection)) def _pasteRequested(self): clipboard = qt.QGuiApplication.clipboard() identifiers = clipboard.text() # handle paste of several lines... identifiers.replace(";", "\n") for identifier in identifiers.split("\n"): try: self.add(identifier) except Exception as e: logger.error(f"Failed to add '{identifier}'. Error is {e}") class GenericScanList(_TomwerObjectList): """Data list able to manage directories (EDF/HDF5?) or files (HDF5)""" HEADER_NAMES = ("dataset",) def _getTomoObject(self, obj: str, allow_several: bool = False): """ some rules to return a TomwerObject from an object (probably a path) from children class """ return self.getScanObject(obj, allow_several=allow_several) @staticmethod def getScanObject(obj, allow_several: bool = False): if not isinstance(obj, str): raise TypeError(f"obj is an instance of {type(obj)} when {str} expected") try: scan_obj = ScanFactory.create_tomo_object_from_identifier(obj) except ValueError as e1: try: if allow_several: scan_obj = ScanFactory.create_scan_objects(obj) else: scan_obj = ScanFactory.create_scan_object(obj) except Exception as e2: logger.warning( f"Unable to create scan object from identifier ({e1}) or as a file or a folder ({e2})" ) return None else: return scan_obj else: return scan_obj class BlissScanList(_TomwerObjectList): """ Widget dedicated to convert bliss entries to TomwerScanBase) """ HEADER_NAMES = ("bliss scan",) def __init__(self, parent): self._configuration = H52nxModel() super().__init__(parent) @property def configuration(self): return self._configuration @configuration.setter def configuration(self, config: H52nxModel): assert isinstance( config, H52nxModel ), "config is expect to be an instance of dict" self._configuration = config def _update(self): list_data = list(self._myitems.keys()) self.clear() for data in list_data: self.add(data) self.sortByColumn(0, self.horizontalHeader().sortIndicatorOrder()) def add(self, data) -> tuple: """Add the path folder d in the scan list :param data: the path of the directory to add """ possible_entries = [] if os.path.exists(data): if not BlissScan.is_bliss_file(data): msg = qt.QMessageBox(self) msg.setIcon(qt.QMessageBox.Warning) types = qt.QMessageBox.Ok | qt.QMessageBox.Cancel msg.setStandardButtons(types) if NXtomoScan.is_nexus_nxtomo_file(data): text = ( f"The input file `{data}` seems to contain `NXTomo` entries. " "and no valid `Bliss` valid entry. \n" "This is probably not a Bliss file. Do you still want to translate ?" ) else: text = ( f"The input file `{data}` does not seems to contain any " "valid `Bliss` entry. \n" "This is probably not a Bliss file. Do you still want to translate ?" ) msg.setText(text) if msg.exec() != qt.QMessageBox.Ok: return try: for entry in nxtomomill_converter.get_bliss_tomo_entries( data, self.configuration ): possible_entries.append(entry) except Exception: logger.error(f"Faild to find entries for {data}") return else: file_path = data else: identifier = NXtomoScanIdentifier.from_str(data) possible_entries.append(identifier.data_path) file_path = identifier.file_path created_scans = [] for entry in possible_entries: scan = NXtomoScan(scan=file_path, entry=entry) scan_objs = super().add(scan) if scan_objs is not None: for scan_obj in scan_objs: created_scans.append(scan_obj) return created_scans class EDFDataList(_TomwerObjectList): HEADER_NAMES = ("edf scan url",) def __init__(self, parent): super().__init__(parent) def _getTomoObject(self, obj: str, allow_several: bool = False): # note: allow several is not used there. No sense for EDF scan try: tomo_obj = ScanFactory.create_scan_object(obj) except Exception as e1: try: tomo_obj = ScanFactory.create_tomo_object_from_identifier(obj) except Exception as e2: logger.warning( f"Unable to create a EDFVolume from {obj}. Error is {e1} or {e2}" ) return if isinstance(tomo_obj, EDFTomoScan): return tomo_obj else: logger.warning( f"Unable to create a EDFVolume from {obj}. But creates a {type(tomo_obj)}. Atre you sure provided path leads to EDF acquisition ?" ) return None def getEDFTomoScan(self, scan_id: str, default=None): if scan_id in self._myitems: return self._myitems[scan_id].data(qt.Qt.UserRole) else: return default class VolumeList(_TomwerObjectList): """ Widget dedicated to the VolumeBase object """ HEADER_NAMES = ("volume url",) def _getTomoObject(self, obj: str, allow_several: bool = False): return self.getVolumeObject(obj=obj, allow_several=allow_several) @staticmethod def getVolumeObject(obj, allow_several: bool = False, warn=True): """ get volume from identifier... even if not contained in the list of items (using factory) """ try: tomo_obj = VolumeFactory.create_tomo_object_from_identifier(obj) except Exception as e: try: tomo_obj = guess_volumes(obj, scheme_to_vol=DEFAULT_SCHEME_TO_VOL) except Exception: if warn: logger.warning( f"Unable to create a volume from {obj}. Error is {e}" ) return None else: # filter potential 'nabu histogram' if tomo_obj is not None: def is_not_histogram(vol_identifier): return not ( hasattr(vol_identifier, "data_path") and vol_identifier.data_path.endswith("histogram") ) tomo_obj = tuple(filter(is_not_histogram, tomo_obj)) if tomo_obj is None or len(tomo_obj) == 0: logger.warning(f"Unable to create a volume from {obj}.") return None else: if len(tomo_obj) > 1 and not allow_several: if warn: logger.warning( f"more than one volume deduce from {obj}. Will only take the first one ({tomo_obj[0]})" ) return tomo_obj[0] elif len(tomo_obj) == 1: return tomo_obj[0] else: return tomo_obj else: return tomo_obj def getVolume(self, volume_id: str, default=None): """ get volume from id contained in the current items, else default """ if volume_id in self._myitems: return self._myitems[volume_id].data(qt.Qt.UserRole) else: return default class TomoObjList(_TomwerObjectList): HEADER_NAMES = ("tomo object",) def _getTomoObject(self, obj: str, allow_several: bool = False): try: tomo_obj = VolumeList.getVolumeObject(obj=obj, allow_several=allow_several) except Exception: pass else: if tomo_obj not in (None, tuple()): return tomo_obj try: tomo_obj = GenericScanList.getScanObject( obj=obj, allow_several=allow_several ) except Exception: return None else: return tomo_obj def getTextToDisplay(self, obj: TomwerObject): return obj.get_identifier().short_description() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/control/datalistener.py0000644000175000017500000006217615153325210021633 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import socket import logging from silx.gui import qt from tomwer.core import settings from tomwer.core.process.utils import LastReceivedScansDict from tomwer.core.scan.blissscan import BlissScan from tomwer.gui import icons as tomwericons from tomwer.gui.control import datareacheractions as actions from tomwer.gui.control.history import ScanHistory from tomwer.gui.control.observations import ScanObservation from tomwer.gui.utils.inputwidget import ( HDF5ConfigFileSelector, NXTomomillOutputDirSelector, ) from tomwer.gui.utils.host_editor import HostEditor from tomwer.synctools.rsyncmanager import BlissSequenceRSyncWorker from ._host import Host _logger = logging.getLogger(__name__) class DataListenerWidget(qt.QMainWindow): """ Widget to display the bliss acquisition on going and finished """ NB_STORED_LAST_FOUND = 20 sigActivate = qt.Signal() """Signal emitted when the listening start""" sigDeactivate = qt.Signal() """Signal emitted when the listening end""" sigConfigurationChanged = qt.Signal() """Signal emitted when the configuration for the bliss client is updated""" sigAcquisitionEnded = qt.Signal(tuple) """Signal emitted when an acquisition is ended without errors. Tuple contains (master_file, entry, proposal_file)""" sigServerStopped = qt.Signal() """Signal emitted when the server is stopped by a sigkill or sigterm""" sigCFGFileChanged = qt.Signal(str) """Signal emitted when path to the nxtomomill configuration file change""" sigMechanicalFlipsChanged = qt.Signal() """Signal emitted when the mechanical flips have been changed""" def __init__(self, parent=None, host_discovery=None): qt.QMainWindow.__init__(self, parent) self.setWindowFlags(qt.Qt.Widget) self._listener = None self.lastFoundScans = LastReceivedScansDict(self.NB_STORED_LAST_FOUND) self._blissScans = {} # keep a trace of the bliss scans. key is bliss scan strings # (used as id), value is BlissScan instance self._syncWorkers = {} # associate scan path (directory) to the RSyncWorker # create widgets self._centralWidget = qt.QWidget(parent=self) self._centralWidget.setLayout(qt.QVBoxLayout()) self._controlWidget = DataListenerControl(parent=self) """Widget containing the 'control' of the datalistener: start of stop the listener""" self._centralWidget.layout().addWidget(self._controlWidget) self._historyWindow = ScanHistory(parent=self) """Widget containing the latest valid scan found by the listener""" self._centralWidget.layout().addWidget(self._historyWindow) self._configWindow = ConfigurationWidget( parent=self, host_discovery=host_discovery ) """Widget containing the configuration to communicate with bliss""" self._centralWidget.layout().addWidget(self._configWindow) self._observationWidget = ScanObservation(parent=self) """Widget containing the current observed directory by the listener""" self._centralWidget.layout().addWidget(self._observationWidget) # create toolbar toolbar = qt.QToolBar("") toolbar.setIconSize(qt.QSize(32, 32)) self._controlAction = actions.ControlAction(parent=self) self._observationsAction = actions.ObservationAction(parent=self) self._configurationAction = actions.ConfigurationAction(parent=self) self._historyAction = actions.HistoryAction(parent=self) toolbar.addAction(self._controlAction) toolbar.addAction(self._observationsAction) toolbar.addAction(self._configurationAction) toolbar.addAction(self._historyAction) self._actionGroup = qt.QActionGroup(self) self._actionGroup.addAction(self._controlAction) self._actionGroup.addAction(self._observationsAction) self._actionGroup.addAction(self._configurationAction) self._actionGroup.addAction(self._historyAction) self.addToolBar(qt.Qt.LeftToolBarArea, toolbar) toolbar.setMovable(False) # signal / slot connection self._actionGroup.triggered.connect(self._updateCentralWidget) self._controlWidget.sigActivated.connect(self.sigActivate) self._controlWidget.sigDeactivated.connect(self.sigDeactivate) self._configWindow.sigConfigurationChanged.connect(self.sigConfigurationChanged) self._configWindow.sigCFGFileChanged.connect(self.sigCFGFileChanged) self._configWindow.sigMechanicalFlipsChanged.connect( self.sigMechanicalFlipsChanged ) self._configWindow.sigRestart.connect(self._restartListener) # expose api self.activate = self._controlWidget.activate self.getCFGFilePath = self._configWindow.getCFGFilePath self.getOutputFolder = self._configWindow.getOutputFolder # set up self.setCentralWidget(self._centralWidget) self._controlAction.setChecked(True) self._updateCentralWidget(self._controlAction) def setHostAndPortToolTip(self, tooltip: str): self._configWindow._hostQLE.setToolTip(tooltip) self._configWindow._hostLabel.setToolTip(tooltip) self._configWindow._portLabel.setToolTip(tooltip) self._configWindow._portSpinBox.setToolTip(tooltip) def _updateCentralWidget(self, action_triggered): action_to_widget = { self._controlAction: self._controlWidget, self._historyAction: self._historyWindow, self._observationsAction: self._observationWidget, self._configurationAction: self._configWindow, } for action, widget in action_to_widget.items(): widget.setVisible(action is action_triggered) def _serverStopped(self): self.sigServerStopped.emit() def _acquisitionStarted(self, arg: tuple): master_file, entry, proposal_file, saving_file = arg scan = self._getBlissScan( master_file=master_file, entry=entry, proposal_file=proposal_file ) if settings.isOnLbsram(scan.path): self._attachRSyncWorker(scan.path, proposal_file, saving_file) self.addAcquisitionObserve(scan=scan) def _acquisitionEnded(self, arg: tuple): master_file, entry, proposal_file, saving_file, succeed = arg scan = self._getBlissScan( master_file=master_file, entry=entry, proposal_file=proposal_file ) self.setAcquisitionEnded(scan=scan, success=succeed) if self._hasRSyncWorkerAttach(scan.path): self._detachRSyncWorker(scan.path) self.sigAcquisitionEnded.emit( (master_file, entry, proposal_file, saving_file, succeed) ) def _acquisitionUpdated(self, arg: tuple): master_file, entry, proposal_file, saving_file, scan_number = arg scan = self._getBlissScan( master_file=master_file, entry=entry, proposal_file=proposal_file ) scan.add_scan_number(scan_number) if settings.isOnLbsram(scan.path): if not self._hasRSyncWorkerAttach(scan.path): self._attachRSyncWorker( scan.path, proposal_file=proposal_file, saving_file=saving_file ) self.updateAcquisitionObserve(scan=scan) def _getBlissScan(self, master_file, entry, proposal_file): scan_id = BlissScan.get_id_name(master_file=master_file, entry=entry) if scan_id in self._blissScans: return self._blissScans[scan_id] else: bliss_scan = BlissScan( master_file=master_file, entry=entry, proposal_file=proposal_file ) self._blissScans[str(bliss_scan)] = bliss_scan return bliss_scan def addAcquisitionObserve(self, scan): self._observationWidget.addObservation(scan) self._observationWidget.update(scan, "on going") def setAcquisitionEnded(self, scan, success): if success is False: self._observationWidget.update(scan, "failed") else: self._observationWidget.removeObservation(scan) self.lastFoundScans.add(scan) self._historyWindow.update(list(self.lastFoundScans.items())) def updateAcquisitionObserve(self, scan): self._observationWidget.update(scan, "on going") def sizeHint(self): return qt.QSize(600, 400) def _restartListener(self, host_name, host_port): # At the moment we still pass by the `BEACON_HOST` environment variable # Because the interface is still the same for the old data listener and the new one. # This is the most straightforward. os.environ["BEACON_HOST"] = f"{host_name}:{host_port}" self.activate(False) self.activate(True) def _attachRSyncWorker(self, scan_path, proposal_file, saving_file): dest_dir = scan_path.replace( settings.get_lbsram_path(), settings.get_dest_path() ) dest_dir = os.path.dirname(dest_dir) if proposal_file is not None: dest_proposal_file = proposal_file.replace( settings.get_lbsram_path(), settings.get_dest_path() ) else: dest_proposal_file = None if saving_file is not None: dest_saving_file = saving_file.replace( settings.get_lbsram_path(), settings.get_dest_path() ) else: dest_saving_file = None worker = BlissSequenceRSyncWorker( src_dir=scan_path, dst_dir=dest_dir, delta_time=1, src_proposal_file=proposal_file, dst_proposal_file=dest_proposal_file, src_sample_file=saving_file, dst_sample_file=dest_saving_file, ) self._syncWorkers[scan_path] = worker worker.start() def _detachRSyncWorker(self, scan_path): if self._hasRSyncWorkerAttach(scan_path=scan_path): worker = self._syncWorkers[scan_path] worker.stop() del self._syncWorkers[scan_path] def _hasRSyncWorkerAttach(self, scan_path): return scan_path in self._syncWorkers # expose API def getHost(self) -> str: """Return server host""" return self._configWindow.getHost() def getPort(self) -> int: """Return server port""" return self._configWindow.getPort() def getBlissServerConfiguration(self) -> dict: return self._configWindow.getConfiguration() def setBlissServerConfiguration(self, config): self._configWindow.setConfiguration(config=config) def setCFGFilePath(self, cfg_file): self._configWindow.setCFGFilePath(cfg_file) def setOutputFolder(self, output_dir): self._configWindow.setOutputFolder(output_dir) def setMechanicalFlips(self, left_right_flip: bool, up_down_flip: bool) -> None: self._configWindow.setMechanicalFlips( left_right_flip=left_right_flip, up_down_flip=up_down_flip ) def getMechanicalFlips(self) -> tuple[bool, bool]: return self._configWindow.getMechanicalFlips() class DataListenerControl(qt.QWidget): """Interface to control the activation of the datalistener""" sigActivated = qt.Signal() """signal emitted when the datalistener is start""" sigDeactivated = qt.Signal() """signal emitted when the datalistener is stop""" def __init__(self, parent=None): qt.QWidget.__init__(self, parent=parent) self.setLayout(qt.QGridLayout()) # add left spacer lspacer = qt.QWidget(self) lspacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) self.layout().addWidget(lspacer, 0, 0, 1, 1) # add start / stop icon frame self._iconLabel = qt.QLabel(parent=self) self._iconLabel.setMinimumSize(qt.QSize(55, 55)) self.layout().addWidget(self._iconLabel, 0, 1, 1, 1) # add button self._button = qt.QPushButton(self) self.layout().addWidget(self._button, 1, 1, 1, 1) # add right spacer rspacer = qt.QWidget(self) rspacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) self.layout().addWidget(rspacer, 0, 2, 1, 1) # bottom spacer bspacer = qt.QWidget(self) bspacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(bspacer, 2, 1, 1, 1) # set up self._updateIconAndText(activate=False) # connect signal / slot self._button.released.connect(self._buttonCallback) def _buttonCallback(self): self.activate(not self.isActivate()) def isActivate(self): return self._button.text() == "stop" def activate(self, activate=True, *args, **kwargs): self._updateIconAndText(activate=activate) if activate is True: self.sigActivated.emit() else: self.sigDeactivated.emit() def _updateIconAndText(self, activate): if activate: icon = tomwericons.getQIcon("datalistener_activate") else: icon = tomwericons.getQIcon("datalistener_deactivate") text = "stop" if activate else "start" self._button.setText(text) self._iconLabel.setPixmap(icon.pixmap(80, 80)) class ConfigurationWidget(qt.QTabWidget): """Widget for data listener configuration""" sigConfigurationChanged = qt.Signal() """Signal emitted when the configuration change""" sigCFGFileChanged = qt.Signal(str) sigMechanicalFlipsChanged = qt.Signal() """Signal emitted when the mechanical flip has been changed""" sigRestart = qt.Signal(str, int) """Emit when use ask for a restart of the data listener. This can happen when the host / port are changed""" DEFAULT_PORT = 25_000 def __init__( self, parent=None, host_discovery: str | None = None, enable_host_pinging: bool = True, ): """ :param host_discovery: define a policy regarding host discovery when creating the widget. If None no discovery will be made. If 'BEACON_HOST' given then will try to discover the host name and port using the environment variable BEACON_HOST. """ super().__init__(parent) # host tab self._hostWidget = qt.QDialog() self._hostWidget.setLayout(qt.QGridLayout()) self._currentHost = self._getHost(host_discovery) """ Current address listen by bliss data. As host, port. setPort and setHost will update this value. Else it will be updated when users are asking for a restart of the bliss-data listener. Used to handle the '_restartButton' and '_resetButton' """ # host self._hostLabel = qt.QLabel("host name", self) self._hostWidget.layout().addWidget(self._hostLabel, 0, 0, 1, 1) self._hostQLE = HostEditor( parent=self, name=self._currentHost.name, port=self._currentHost.port, enable_host_pinging=enable_host_pinging, ) self._hostQLE.setEnabled(self._hostEditable) self._hostWidget.layout().addWidget(self._hostQLE, 0, 1, 1, 2) # port self._portLabel = qt.QLabel("host port", self) self._hostWidget.layout().addWidget(self._portLabel, 1, 0, 1, 1) self._portSpinBox = qt.QSpinBox(self) self._portSpinBox.setRange(0, 100000) self._portSpinBox.setValue(self._currentHost.port) self._portSpinBox.setEnabled(self._hostEditable) self._hostWidget.layout().addWidget(self._portSpinBox, 1, 1, 1, 2) # restart & reset buttons self._buttons = qt.QDialogButtonBox(parent=self) style = qt.QApplication.style() icon = style.standardIcon(qt.QStyle.SP_MediaPlay) self._restartButton = qt.QPushButton(icon, "restart bliss-data listener") self._buttons.addButton(self._restartButton, qt.QDialogButtonBox.ActionRole) icon = style.standardIcon(qt.QStyle.SP_DialogResetButton) self._resetButton = qt.QPushButton(icon, "reset host") self._buttons.addButton(self._resetButton, qt.QDialogButtonBox.ActionRole) self._hostWidget.layout().addWidget(self._buttons, 2, 2, 1, 2) # spacer spacer = qt.QWidget(parent=self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self._hostWidget.layout().addWidget(spacer, 90, 0, 1, 1) # h52nx tab self._h52nxConfigWidget = qt.QWidget() self._h52nxConfigWidget.setLayout(qt.QGridLayout()) # configuration file to use self._cfgLabel = qt.QLabel("config file") self._h52nxConfigWidget.layout().addWidget(self._cfgLabel, 11, 0, 1, 1) self._cfgWidget = HDF5ConfigFileSelector(self) self._cfgWidget.setContentsMargins(0, 0, 0, 0) self._cfgWidget.layout().setContentsMargins(0, 0, 0, 0) self._h52nxConfigWidget.layout().addWidget(self._cfgWidget, 11, 1, 1, 2) tooltip = ( "You can provide a configuration file to tune conversion " "done by nxtomomill. If None is provided then the default " "parameters will be used." ) self._cfgLabel.setToolTip(tooltip) self._cfgWidget.setToolTip(tooltip) # mechanical flip self._lrMechanicalFlipLabel = qt.QLabel("left-right mechanical flip") lr_icon = tomwericons.getQIcon("lr_mirroring") self._h52nxConfigWidget.layout().addWidget( self._lrMechanicalFlipLabel, 12, 0, 1, 1 ) self._lrMechanicalFlip = qt.QCheckBox() self._lrMechanicalFlip.setIcon(lr_icon) self._lrMechanicalFlip.setToolTip( "Detector image is flipped **left-right** for mechanical reasons that are not propagated with bliss-tomo hdf5 metadata (mirror,..)." ) self._h52nxConfigWidget.layout().addWidget(self._lrMechanicalFlip, 12, 1, 1, 2) self._udMechanicalFlipLabel = qt.QLabel("up-down mechanical flip") ud_icon = tomwericons.getQIcon("ud_mirroring") self._h52nxConfigWidget.layout().addWidget( self._udMechanicalFlipLabel, 13, 0, 1, 1 ) self._udMechanicalFlip = qt.QCheckBox() self._udMechanicalFlip.setIcon(ud_icon) self._udMechanicalFlip.setToolTip( "Detector image is flipped **up-down** for mechanical reasons that are not propagated with bliss-tomo hdf5 metadata (mirror,..)." ) self._h52nxConfigWidget.layout().addWidget(self._udMechanicalFlip, 13, 1, 1, 2) # vline 2 self._vLine2 = qt.QFrame() self._vLine2.setFrameShape(qt.QFrame.Shape.HLine) self._vLine2.setFrameShadow(qt.QFrame.Shadow.Sunken) self._h52nxConfigWidget.layout().addWidget(self._vLine2, 20, 0, 1, 3) # output folder self._outputFolderLabel = qt.QLabel("nexus file output dir") self._h52nxConfigWidget.layout().addWidget(self._outputFolderLabel, 21, 0, 1, 1) self._nxTomomillOutputWidget = NXTomomillOutputDirSelector(self) self._nxTomomillOutputWidget.setContentsMargins(0, 0, 0, 0) self._nxTomomillOutputWidget.layout().setContentsMargins(0, 0, 0, 0) self._h52nxConfigWidget.layout().addWidget( self._nxTomomillOutputWidget, 21, 1, 1, 2 ) # buttons types = qt.QDialogButtonBox.Apply self._buttons = qt.QDialogButtonBox(self) self._buttons.setStandardButtons(types) self._buttons.button(qt.QDialogButtonBox.Apply).setToolTip( "Once apply if a listening is on going" "then it will stop the current listening and" "restart it with the new parameters" ) self._h52nxConfigWidget.layout().addWidget(self._buttons, 21, 0, 1, 3) # height spacer spacer = qt.QWidget(parent=self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self._h52nxConfigWidget.layout().addWidget(spacer, 90, 0, 1, 1) # connect signal / slot self._cfgWidget.sigConfigFileChanged.connect(self.sigCFGFileChanged) self._buttons.button(qt.QDialogButtonBox.Apply).clicked.connect(self.validate) self._nxTomomillOutputWidget.sigChanged.connect(self.validate) self._lrMechanicalFlip.toggled.connect(self.sigMechanicalFlipsChanged) self._udMechanicalFlip.toggled.connect(self.sigMechanicalFlipsChanged) self._portSpinBox.valueChanged.connect(self._updateRestartAndResetAvailability) self._portSpinBox.editingFinished.connect(self._portHasChanged) self._hostQLE.currentTextChanged.connect( self._updateRestartAndResetAvailability ) self._restartButton.released.connect(self._restartBlissData) self._resetButton.released.connect(self._resetHostAndPortValues) # set up self._buttons.hide() # update host name and port in case one was none at start up. self._currentHost.name = self.getHost() self._currentHost.port = self.getPort() self._updateRestartAndResetAvailability() self.addTab(self._hostWidget, "host") self.addTab(self._h52nxConfigWidget, "h52nx") def _getHost(self, host_discovery) -> Host: if settings.JSON_RPC_HOST is not None: # use case settings.JSON_RPC_HOST is defined # if defined in the settings file take it self._hostEditable = False return Host(settings.JSON_RPC_HOST, settings.JSON_RPC_PORT) if host_discovery is None: # use case settings.JSON_RPC_HOST is not defined but 'host_discovery' is None (requires JSON-RPC) self._hostEditable = False return Host( socket.gethostname(), settings.JSON_RPC_PORT, ) # default use case - using bliss-data and BEACON_HOST self._hostEditable = True err_beacon_host = "Unable to determine host name and host port from 'BEACON_HOST'. Please export it as host_name:host_port. For example 'export BEACON_HOST=icc:0000'" beacon_host = os.environ.get("BEACON_HOST") if beacon_host is None: _logger.warning(err_beacon_host) return Host(None, self.DEFAULT_PORT) try: host_name, host_port = beacon_host.split(":") try: host_port = int(host_port) except ValueError: host_port = self.DEFAULT_PORT except ValueError: _logger.error(err_beacon_host) return Host(None, self.DEFAULT_PORT) else: return Host(host_name, host_port) def _restartBlissData(self): self._currentHost.name = self.getHost() self._currentHost.port = self.getPort() self.sigRestart.emit(self._currentHost.name, self._currentHost.port) self._updateRestartAndResetAvailability() def _resetHostAndPortValues(self): self.setHost(self._currentHost.name) self.setPort(self._currentHost.port) def _updateRestartAndResetAvailability(self): host_name_or_port_has_changed = ( self._currentHost.name != self.getHost() or self._currentHost.port != self.getPort() ) self._resetButton.setEnabled(host_name_or_port_has_changed) self._restartButton.setEnabled(host_name_or_port_has_changed) def _portHasChanged(self): # update port to the host (so it can update the icons). This requires a bit of processing so # we do this when edition is finished only. self._hostQLE.setPort(self.getPort()) def getCFGFilePath(self): return self._cfgWidget.getCFGFilePath() def setCFGFilePath(self, cfg_file): self._cfgWidget.setCFGFilePath(cfg_file) def getOutputFolder(self): return self._nxTomomillOutputWidget.getOutputFolder() def setOutputFolder(self, output_dir): self._nxTomomillOutputWidget.setOutputFolder(output_dir) def addBlissSession(self, session: str) -> None: if self._blissSession.findText(session) >= 0: return else: self._blissSession.addItem(session) def getConfiguration(self) -> dict: return {"host": self.getHost(), "port": self.getPort()} def setConfiguration(self, config: dict): if "host" in config: self.setHost(config["host"]) if "port" in config: self.setPort(config["port"]) def getHost(self) -> str: return self._hostQLE.currentText() def setHost(self, name: str): self._hostQLE.setCurrentText(name) self._currentHost.name = name def getPort(self) -> int: return self._portSpinBox.value() def setPort(self, port: int) -> None: assert isinstance(port, int) self._portSpinBox.setValue(port) self._currentHost.port = port def getMechanicalFlips(self) -> tuple[bool, bool]: """ :return: left-right flip, up-down flip """ return self._lrMechanicalFlip.isChecked(), self._udMechanicalFlip.isChecked() def setMechanicalFlips(self, left_right_flip: bool, up_down_flip: bool) -> None: self._lrMechanicalFlip.setChecked(left_right_flip) self._udMechanicalFlip.setChecked(up_down_flip) def validate(self): self.sigConfigurationChanged.emit() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/control/datareacheractions.py0000644000175000017500000000232414757047403023003 0ustar00paynopayno# coding: utf-8 from __future__ import annotations from silx.gui import qt from tomwer.gui import icons as tomwericons class HistoryAction(qt.QAction): """ Action displaying the history of finished scans """ def __init__(self, parent): icon = tomwericons.getQIcon("history") qt.QAction.__init__(self, icon, "history", parent) self.setCheckable(True) class ConfigurationAction(qt.QAction): """ Action to show the configuration dialog """ def __init__(self, parent): icon = tomwericons.getQIcon("parameters") qt.QAction.__init__(self, icon, "configuration", parent) self.setCheckable(True) class ObservationAction(qt.QAction): """ Action to show the observation dialog """ def __init__(self, parent): icon = tomwericons.getQIcon("loop") qt.QAction.__init__(self, icon, "observations", parent) self.setCheckable(True) class ControlAction(qt.QAction): """ Action to control the datawatcher (see status and select folder) """ def __init__(self, parent): icon = tomwericons.getQIcon("health") qt.QAction.__init__(self, icon, "control", parent) self.setCheckable(True) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/control/datatransfert.py0000644000175000017500000001041515153325210022003 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging import os from silx.gui import qt from tomwer.io.utils import get_default_directory _logger = logging.getLogger(__file__) class DataTransfertSelector(qt.QWidget): """ Simple GUI for selecting the datatransfert root folder """ sigSelectionChanged = qt.Signal(str) """If None: default mode, send it to rnice, else send it to the given root folder""" def __init__(self, parent, rnice_option, default_root_folder): qt.QWidget.__init__(self, parent) assert type(default_root_folder) is str assert type(rnice_option) is bool self.setLayout(qt.QVBoxLayout(self)) self.layout().setSpacing(0) self._buttonGrp = qt.QButtonGroup(self) self._buttonGrp.setExclusive(True) # rnice option if rnice_option is True: self._rniceOpt = qt.QRadioButton("to rnice", self) self._rniceOpt.setChecked(True) self._buttonGrp.addButton(self._rniceOpt) else: self._rniceOpt = None self.layout().addWidget(self._rniceOpt) # folder option self._rootFolderOpt = qt.QWidget(parent=self) self._rootFolderOpt.setLayout(qt.QHBoxLayout()) self._rootFolderOpt.layout().setContentsMargins(0, 0, 0, 0) self._folderOpt = qt.QRadioButton("to root folder", self._rootFolderOpt) self._buttonGrp.addButton(self._folderOpt) self._folderOpt.setChecked(not rnice_option) self._rootFolderOpt.layout().addWidget(self._folderOpt) self._folderSelection = qt.QLineEdit( default_root_folder or get_default_directory(), self._rootFolderOpt ) self._rootFolderOpt.layout().addWidget(self._folderSelection) self._folderSelPB = qt.QPushButton("select folder", self._folderSelection) self._folderSelPB.setAutoDefault(True) self._rootFolderOpt.layout().addWidget(self._folderSelPB) self.layout().addWidget(self._rootFolderOpt) # default visibility values self._updateFolderVisibility(not rnice_option) # connect signal / SLOT self._folderOpt.toggled.connect(self._updateFolderVisibility) if self._rniceOpt: self._rniceOpt.toggled.connect(self._updateRniceAction) self._folderSelPB.clicked.connect(self._changeFolder) self._folderSelection.textChanged.connect(self.__updateFolder) def __updateFolder(self, folder_path): """Inform connected QObject that the selection just changed""" assert folder_path is None or type(folder_path) is str self.sigSelectionChanged.emit(folder_path) def _updateFolderVisibility(self, b): """Deal with the select folder widget visibility""" self._folderSelection.setEnabled(b) self._folderSelPB.setEnabled(b) if b is True: self.__updateFolder(self._folderSelection.text()) def _updateRniceAction(self, b): """if necessary connect with rnice radio button with __updateFolder""" if b is True: self.__updateFolder(None) def _changeFolder(self): # pragma: no cover """Callback when folder selection is choose""" defaultDirectory = self._folderSelection.text() if os.path.isdir(defaultDirectory): defaultDirectory = get_default_directory() dialog = qt.QFileDialog(self, directory=defaultDirectory) dialog.setFileMode(qt.QFileDialog.DirectoryOnly) if not dialog.exec(): dialog.close() return self._folderSelection.setText(dialog.selectedFiles()[0]) def setFolder(self, folder_path): """ Define the root folder to move scan :param folder_path: root folder for received scan """ assert type(folder_path) is str or folder_path is None if folder_path is None: if self._rniceOpt is None: _logger.warning("rnice option is not available") else: self._rniceOpt.setChecked(True) else: self._folderOpt.setChecked(True) self._folderSelection.setText(folder_path) def getFolder(self): if self._rniceOpt.isChecked(): return None else: return self._folderSelection.text() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/control/datavalidator.py0000644000175000017500000003141615153325210021764 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging import time import weakref from packaging.version import Version from contextlib import AbstractContextManager from silx.gui import qt from tomwer.core.process.control.scanvalidator import ScanValidator as BaseDataValidator from tomwer.core.scan.scanbase import TomwerScanBase, _TomwerBaseDock from tomwer.core.scan.scanfactory import ScanFactory from tomwer.gui.dialog.QDataDialog import QDataDialog from tomwer.gui.utils.waiterthread import QWaiterThread from tomwer.gui.visualization.dataviewer import DataViewer _logger = logging.getLogger(__file__) WAIT_TIME_MEM_REL = 20 """Time (in sec) to wait to check if the scan validator has to release his stack of scans. This is a security to make sure we are not keeping unnecessary data during an acquisition in lbsram""" class DataValidator(qt.QMainWindow, BaseDataValidator): """ Widget used to validate an acquisition or recall some processing """ sigScanReady = qt.Signal(TomwerScanBase) """signal emitted when a scan is validated""" sigChangeReconsParams = qt.Signal(_TomwerBaseDock) """signal emitted when the user request modifications on reconstruction parameters""" class SliderCM(AbstractContextManager): """Simple context manager to hida / show button dialogs""" def __init__(self, slider): self._slider = slider self._old = None def __enter__(self): self._old = self._slider.blockSignals(True) def __exit__(self, exc_type, exc_val, exc_tb): self._slider.blockSignals(self._old) def __init__(self, parent, timeout_loop_memory=WAIT_TIME_MEM_REL): qt.QMainWindow.__init__( self, parent, memoryReleaser=QWaiterThread(timeout_loop_memory) ) # needed on lbs191... otherwise crash with PyQt5.11. with a QThread destroyed... time.sleep(0.01) BaseDataValidator.__init__( self, memoryReleaser=QWaiterThread(timeout_loop_memory) ) self._centralWidget = DataViewer(parent=parent) self.setCentralWidget(self._centralWidget) # scan slider and add scan self._lateralWidget = qt.QWidget(self) self._lateralWidget.setLayout(qt.QVBoxLayout()) self._addScanButton = qt.QPushButton(self) style = qt.QApplication.style() icon = style.standardIcon(qt.QStyle.SP_DirIcon) self._addScanButton.setIcon(icon) self._lateralWidget.layout().addWidget(self._addScanButton) self._scanSelectorSlider = _ScanSelectorWidget(parent=self) self._lateralWidget.layout().addWidget(self._scanSelectorSlider) self._lateralWidget.layout().setContentsMargins(0, 0, 0, 0) self._scanSelectorSliderDocker = qt.QDockWidget(self) self._scanSelectorSliderDocker.setWidget(self._lateralWidget) self._scanSelectorSliderDocker.setFeatures(qt.QDockWidget.DockWidgetMovable) self.addDockWidget(qt.Qt.RightDockWidgetArea, self._scanSelectorSliderDocker) # control buttons self._controlButtons = _DataControlWidget(parent=self) self._controlButtonsDocker = qt.QDockWidget(self) self._controlButtonsDocker.setWidget(self._controlButtons) self._controlButtonsDocker.setFeatures(qt.QDockWidget.DockWidgetMovable) self.addDockWidget(qt.Qt.BottomDockWidgetArea, self._controlButtonsDocker) self._scanSelectorSlider.setMinimum(0) self._scanSelectorSlider.setMaximum(0) # connect signal / slot self._scanSelectorSlider.sigScanChanged.connect(self._updateCurrentScan) _controlButtons = self._controlButtons _controlButtons.sigValidateScan.connect(self.validateCurrentScan) _controlButtons.sigChangeReconstructionParametersScan.connect( self.changeReconsParamCurrentScan ) _controlButtons.toggled.connect(self.setManualValidation) self._addScanButton.pressed.connect(self._addNewScanCallback) def close(self) -> bool: self._centralWidget.setAttribute(qt.Qt.WA_DeleteOnClose) self._centralWidget.close() self._centralWidget = None qt.QMainWindow.close(self) def addScan(self, scan): """ :param scan: :return: """ assert isinstance(scan, TomwerScanBase) BaseDataValidator.addScan(self, scan) with self.SliderCM(self._scanSelectorSlider): current_index = self._scanSelectorSlider.value() self._scanSelectorSlider.setRange(0, len(self._scans) - 1) self._scanSelectorSlider.setValue(current_index) if str(scan) in self._scans: self.setActiveScan(scan) def setActiveScan(self, scan: TomwerScanBase): """ :param scan: :return: """ if scan is None: self.clear() elif str(scan) not in self._scans: _logger.warning("scan has not been registered") else: with self.SliderCM(self._scanSelectorSlider): self._centralWidget.setScan(scan) self._controlButtons.setScan(scan) index = list(self._scans.keys()).index(str(scan)) self._scanSelectorSlider.setValue(index) def _updateCurrentScan(self): with self.SliderCM(self._scanSelectorSlider): self.setActiveScan(self.getCurrentScan()) def getCurrentScan(self) -> TomwerScanBase: """ :return: """ current_scan_index = self._scanSelectorSlider.value() if current_scan_index >= len(self._scans): return None else: scan_id = list(self._scans.keys())[current_scan_index] scan = self._scans[scan_id] assert isinstance(scan, TomwerScanBase) return scan def validateCurrentScan(self): scan = self.getCurrentScan() if scan is None: return else: BaseDataValidator._validateScan(self, scan) with self.SliderCM(self._scanSelectorSlider): current_index = self._scanSelectorSlider.value() self._scanSelectorSlider.setRange(0, len(self._scans) - 1) # note: slider force the value to be in [minimum, maximum] self._scanSelectorSlider.setValue(current_index) self._updateCurrentScan() def changeReconsParamCurrentScan(self): current_scan = self.getCurrentScan() if current_scan: assert isinstance(current_scan, TomwerScanBase) BaseDataValidator._changeReconsParam(self, current_scan) def _sendScanReady(self, scan): if scan is not None: assert isinstance(scan, TomwerScanBase) self.sigScanReady.emit(scan) def _sendUpdateReconsParam(self, scan): if scan is not None: assert isinstance(scan, _TomwerBaseDock) self.sigChangeReconsParams.emit(scan) def clear(self): try: self._centralWidget.clear() except AttributeError: # if has been removed before calling clear pass def _validateStack(self, filter_=None): BaseDataValidator._validateStack(self, filter_=filter_) self._updateCurrentScan() def setAutomaticValidation(self, auto): self._controlButtons.setChecked(not auto) def _addNewScanCallback(self): """Callback when we want to add a new scan to the scan validator""" dialog = QDataDialog(self, multiSelection=True) if not dialog.exec(): dialog.close() return foldersSelected = dialog.files_selected() new_active_scan = None for folder in foldersSelected: try: scans = ScanFactory.create_scan_objects(scan_path=folder) except Exception as e: _logger.error( f"cannot create scan instances from {folder}. Error is {e}" ) else: for scan in scans: self.addScan(scan=scan) new_active_scan = scan if new_active_scan is not None: self.setActiveScan(new_active_scan) class _ScanSelectorWidget(qt.QWidget): """Slider to select the scan we want to 'check'""" sigScanChanged = qt.Signal(int) """signal emitted when the scan change. Value is the scan index""" def __init__(self, parent): qt.QWidget.__init__(self, parent) self.setLayout(qt.QHBoxLayout()) self._qslider = qt.QSlider(qt.Qt.Vertical, self) self.layout().addWidget(self._qslider) self._verticalLabel = _VerticalLabel( "stack of received scan", parent=self, revert=True ) self.layout().addWidget(self._verticalLabel) # connect signal / slot self._qslider.valueChanged.connect(self._valueHasChanged) def _valueHasChanged(self, *args, **kwargs): self.sigScanChanged.emit(self._qslider.value()) def value(self): return self._qslider.value() def setValue(self, value): self._qslider.setValue(value) def setMinimum(self, p_int): self._qslider.setMinimum(p_int) def setMaximum(self, p_int): self._qslider.setMaximum(p_int) def setRange(self, p_int, p_int_1): self._qslider.setRange(p_int, p_int_1) class _DataControlWidget(qt.QGroupBox): """Set of buttons to control the current scan""" sigValidateScan = qt.Signal(str) sigCancelScan = qt.Signal(str) sigRedoAcquisitionScan = qt.Signal(TomwerScanBase) sigChangeReconstructionParametersScan = qt.Signal(TomwerScanBase) def __init__(self, parent=None): qt.QGroupBox.__init__(self, title="Validate manually", parent=parent) self._scan = None self.setCheckable(True) layout = qt.QGridLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) # validate button self.validateButton = qt.QPushButton("Validate") style = qt.QApplication.style() self.validateButton.setIcon(style.standardIcon(qt.QStyle.SP_DialogApplyButton)) self.validateButton.pressed.connect(self.__validated) layout.addWidget(self.validateButton, 0, 2) spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) layout.addWidget(spacer, 0, 1) # change reconstruction parameters button self.changeReconsParamButton = qt.QPushButton( "Change reconstruction parameters" ) self.changeReconsParamButton.setIcon( style.standardIcon(qt.QStyle.SP_FileDialogContentsView) ) self.changeReconsParamButton.pressed.connect( self.__updateReconstructionParameters ) layout.addWidget(self.changeReconsParamButton, 2, 0) def setScan(self, scan): self._scan = weakref.ref(scan) def setEnabled(self, b): self.validateButton.setEnabled(b) self.changeReconsParamButton.setEnabled(b) def __validated(self): """Callback when the validate button is pushed""" self.sigValidateScan.emit("") def __redoacquisition(self): """Callback when the redo acquisition button is pushed""" if self._scan is not None and self._scan() is not None: self.sigRedoAcquisitionScan.emit(self._scan()) def __updateReconstructionParameters(self): """Callback when the change reconstruction button is pushed""" if self._scan is not None and self._scan() is not None: self.sigChangeReconstructionParametersScan.emit(self._scan()) class _VerticalLabel(qt.QLabel): """Display vertically the given text""" def __init__(self, text, parent=None, revert=False): """ :param text: the legend :param parent: the Qt parent if any """ qt.QLabel.__init__(self, text, parent) self.revert = revert self.setLayout(qt.QVBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) def paintEvent(self, event): painter = qt.QPainter(self) painter.setFont(self.font()) painter.translate(0, self.rect().height()) painter.rotate(90) if self.revert: newRect = qt.QRect( -self.rect().height(), -self.rect().width(), self.rect().height(), self.rect().width(), ) else: newRect = self.rect() painter.drawText(newRect, qt.Qt.AlignHCenter, self.text()) fm = qt.QFontMetrics(self.font()) if Version(qt.QT_VERSION_STR) >= Version("5.11"): preferedHeight = fm.horizontalAdvance(self.text()) else: preferedHeight = fm.width(self.text()) preferedWidth = fm.height() self.setFixedWidth(preferedWidth) self.setMinimumHeight(preferedHeight) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9331014 tomwer-1.6.17/src/tomwer/gui/control/datawatcher/0000755000175000017500000000000015153325403021061 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/control/datawatcher/__init__.py0000644000175000017500000000011115153325210023157 0ustar00paynopayno# coding: utf-8 from .datawatcher import DataWatcherWidget # noqa F401 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/control/datawatcher/configuration.py0000644000175000017500000002123115153325210024275 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import functools from silx.gui import qt from tomwer.core.process.control.datawatcher import status from tomwer.core.process.control.datawatcher.datawatcher import _DataWatcher class _DWConfigurationWidget(qt.QWidget): startByOldestStateChanged = qt.Signal(bool) def __init__(self, parent): qt.QWidget.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) self._observationMethod = _ObservationMethodSelector(parent=self) self.layout().addWidget(self._observationMethod) # checkbox start scan from oldest self._qcboldest = qt.QCheckBox("Start scan by the oldest", parent=self) tooltip = ( "If NOT activated will explore folders from the latest to " "the newest. Otherwise will explore the folders from the " "newest to the oldest." ) self._qcboldest.setToolTip(tooltip) self.startByOldestStateChanged = self._qcboldest.toggled self.layout().addWidget(self._qcboldest) def getMode(self) -> tuple: return self._observationMethod.getMode() def setMode(self, mode: tuple): self._observationMethod.setMode(mode) class _ObservationMethodSelector(qt.QWidget): sigSelectionChanged = qt.Signal(tuple) """Return the selection made as a string and some information if needed in a dictionary""" def __init__(self, parent=None) -> None: super().__init__(parent) self.__button_group = qt.QButtonGroup(self) self.setLayout(qt.QVBoxLayout()) self._edfObservations = _SpecEDFObservationMethodSelector(self) self.layout().addWidget(self._edfObservations) self._blissScanObservations = _BlissHDF5ObservationMethodSelector(self) self.layout().addWidget(self._blissScanObservations) self._nxtomoObservations = _NXtomoObservationMethodSelector(self) self.layout().addWidget(self._nxtomoObservations) self._edfObservations.sigSelectionChanged.connect( self._propagateSigSelectionChanged ) self.__button_group.addButton(self._edfObservations._qrbInfo) self.__button_group.addButton(self._edfObservations._qrbUserEntry) self.__button_group.addButton(self._edfObservations._qrbXml) self.__button_group.addButton(self._blissScanObservations._qrbBlissHDF5) self.__button_group.addButton(self._nxtomoObservations._qrbNXtomo) # connect signal / slot self._edfObservations.sigSelectionChanged.connect( self._propagateSigSelectionChanged ) self._blissScanObservations._qrbBlissHDF5.toggled.connect( functools.partial( self._propagateSigSelectionChanged, (status.BLISS_SCAN_END,) ) ) self._nxtomoObservations._qrbNXtomo.toggled.connect( functools.partial(self._propagateSigSelectionChanged, (status.NXtomo_END,)) ) def _propagateSigSelectionChanged(self, infos: tuple): self.sigSelectionChanged.emit(infos) def getMode(self): if self._blissScanObservations._qrbBlissHDF5.isChecked(): return (status.BLISS_SCAN_END,) elif self._nxtomoObservations._qrbNXtomo.isChecked(): return (status.NXtomo_END,) else: return self._edfObservations.getMode() def setMode(self, mode: tuple): if mode[0] == status.BLISS_SCAN_END: self._blissScanObservations._qrbBlissHDF5.setChecked(True) elif mode[0] == status.NXtomo_END: self._nxtomoObservations._qrbNXtomo.setChecked(True) else: self._edfObservations.setMode(mode) class _NXtomoObservationMethodSelector(qt.QGroupBox): def __init__(self, parent): super().__init__(parent, title="End acquisition observation method for NXtomo") self.setLayout(qt.QVBoxLayout()) self._qrbNXtomo = qt.QRadioButton(status.NXtomo_END, parent=self) self.layout().addWidget(self._qrbNXtomo) class _BlissHDF5ObservationMethodSelector(qt.QGroupBox): def __init__(self, parent): super().__init__( parent, title="End acquisition observation method for bliss-hdf5" ) self.setLayout(qt.QVBoxLayout()) self._qrbBlissHDF5 = qt.QRadioButton(status.BLISS_SCAN_END, parent=self) self.layout().addWidget(self._qrbBlissHDF5) class _SpecEDFObservationMethodSelector(qt.QGroupBox): """Group box allowing selection of an observation method""" sigSelectionChanged = qt.Signal(tuple) """Return the selection made as a string and some information if needed in a dictionary""" def __init__(self, parent): super().__init__(parent, title="End acquisition observation method for edf") self.setLayout(qt.QVBoxLayout()) self._qrbXml = qt.QRadioButton(status.DET_END_XML, parent=self) self.layout().addWidget(self._qrbXml) self._qrbInfo = qt.QRadioButton(status.PARSE_INFO_FILE, parent=self) self.layout().addWidget(self._qrbInfo) self._qrbAnyEDF = qt.QRadioButton(status.EDF_SCAN_END, parent=self) self.layout().addWidget(self._qrbAnyEDF) self._qwUserEntry = qt.QWidget(parent=self) self.layout().addWidget(self._qwUserEntry) self._qrbUserEntry = qt.QRadioButton(status.DET_END_USER_ENTRY, parent=self) self.layout().addWidget(self._qrbUserEntry) widgetFilePtrn = qt.QWidget(parent=self) widgetFilePtrn.setLayout(qt.QHBoxLayout()) widgetFilePtrn.layout().addWidget( qt.QLabel(text="pattern: ", parent=widgetFilePtrn) ) self._qleFilePattern = qt.QLineEdit(text="", parent=self._qwUserEntry) widgetFilePtrn.layout().addWidget(self._qleFilePattern) self.widgetFilePtrn = widgetFilePtrn self.layout().addWidget(self.widgetFilePtrn) self._qrbXml.setChecked(_DataWatcher.DEFAULT_OBS_METH == status.DET_END_XML) self._qrbInfo.setChecked( _DataWatcher.DEFAULT_OBS_METH == status.PARSE_INFO_FILE ) self._qrbUserEntry.setChecked( _DataWatcher.DEFAULT_OBS_METH == status.DET_END_USER_ENTRY ) self.widgetFilePtrn.setVisible(self._qrbUserEntry.isVisible()) spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer) # set up self._qrbAnyEDF.hide() # by default for the DataWatcher compatibility this one is hidded # deal with connections self._qrbUserEntry.toggled.connect(self.widgetFilePtrn.setVisible) self._qrbXml.toggled.connect(self._selectionChanged) self._qrbInfo.toggled.connect(self._selectionChanged) self._qrbAnyEDF.toggled.connect(self._selectionChanged) self._qrbUserEntry.toggled.connect(self._selectionChanged) self._qleFilePattern.editingFinished.connect(self._selectionChanged) # add some tooltips t = """If a file with this pattern is found in the [scan] folder then we will consider the acquisition as ended""" self._qrbUserEntry.setToolTip(t) t = """Wild charracter allowed""" self._qleFilePattern.setToolTip(t) t = """If we founf the [scan].xml in the [scan] folder then we will consider the acquisition ended""" self._qrbXml.setToolTip(t) t = """We will look for the [scan].info file in the [scan] directory. If it exists then we will parse it to get the number of .edf file we should have and wait for all of them to be acquired (also checking file size)""" self._qrbInfo.setToolTip(t) def _selectionChanged(self): mode = self.getMode() if mode is not None: self.sigSelectionChanged.emit((mode,)) def getMode(self): if self._qrbXml.isChecked(): return (status.DET_END_XML,) elif self._qrbInfo.isChecked(): return (status.PARSE_INFO_FILE,) elif self._qrbAnyEDF.isChecked(): return (status.EDF_SCAN_END,) elif self._qrbUserEntry.isChecked(): return (status.DET_END_USER_ENTRY, {"pattern": self._qleFilePattern.text()}) else: return None def setMode(self, mode: tuple): if mode[0] == status.DET_END_XML: self._qrbXml.setChecked(True) elif mode[0] == status.PARSE_INFO_FILE: self._qrbInfo.setChecked(True) elif mode[0] == status.EDF_SCAN_END: self._qrbAnyEDF.setChecked(True) elif mode[0] == status.DET_END_USER_ENTRY: self._qrbUserEntry.setChecked(True) if mode[1] not in (None, ""): self._qleFilePattern.setText(mode[1]) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/control/datawatcher/controlwidget.py0000644000175000017500000000742015153325210024316 0ustar00paynopaynoimport os from tomwer.gui.qlefilesystem import QLFileSystem from silx.gui import qt, icons as silxicons from tomwer.io.utils import get_default_directory class ControlWidget(qt.QWidget): _TXT_STOP_OBS = "Stop observation" _TXT_START_OBS = "Start observation" def __init__(self, parent=None, **kwargs) -> None: super().__init__(parent, **kwargs) self.setLayout(qt.QVBoxLayout()) layout = self.layout() self.mystatusBar = qt.QStatusBar(parent=self) self._qlInfo = qt.QLabel(parent=self) layout.addWidget(self._getFolderSelection()) layout.addWidget(self._qlInfo) layout.addWidget(self._buildFilterWidget()) layout.addWidget(self._buildStartStopButton()) layout.addWidget(self.mystatusBar) spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) layout.addWidget(spacer) def _getFolderSelection(self): """ Return the widget used for the folder selection """ widget = qt.QWidget(self) layout = qt.QHBoxLayout() self._qtbSelectFolder = qt.QPushButton("Select folder", parent=widget) self._qtbSelectFolder.setAutoDefault(True) self._qtbSelectFolder.clicked.connect(self._setFolderPath) self._qteFolderSelected = QLFileSystem("", parent=widget) layout.setContentsMargins(0, 0, 0, 0) layout.setSpacing(0) layout.addWidget(self._qteFolderSelected) layout.addWidget(self._qtbSelectFolder) self.animated_icon = silxicons.getWaitIcon() self._stateLabel = qt.QLabel(parent=widget) self.animated_icon.register(self._stateLabel) self._stateLabel.setFixedWidth(30) layout.addWidget(self._stateLabel) widget.setLayout(layout) return widget def _buildFilterWidget(self): widget = qt.QWidget(self) layout = qt.QHBoxLayout() widget.setLayout(layout) widget.layout().addWidget(qt.QLabel("filter")) self._filterQLE = qt.QLineEdit("", self) self._filterQLE.setToolTip( "You can provide a Linux Regular Expression that will insure only file fitting the expression will be discovered" ) self._filterQLE.setPlaceholderText("*file_pattern*") widget.layout().addWidget(self._filterQLE) return widget def _buildStartStopButton(self): """ Build the start/stop button in a QHLayout with one spacer on the left and one on the right """ widget = qt.QWidget(self) layout = qt.QHBoxLayout() widget.setLayout(layout) # left spacer spacerL = qt.QWidget(widget) spacerL.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) layout.addWidget(spacerL) # button self._qpbstartstop = qt.QPushButton(self._TXT_START_OBS) self._qpbstartstop.setAutoDefault(True) layout.addWidget(self._qpbstartstop) # right spacer spacerR = qt.QWidget(widget) spacerR.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) layout.addWidget(spacerR) return widget def _setFolderPath(self): # pragma: no cover """ Ask the user the path to the folder to observe """ defaultDirectory = self._qteFolderSelected.text() if defaultDirectory is None or not os.path.isdir(defaultDirectory): if defaultDirectory is None: defaultDirectory = get_default_directory() dialog = qt.QFileDialog(self, directory=defaultDirectory) dialog.setFileMode(qt.QFileDialog.DirectoryOnly) if not dialog.exec(): dialog.close() return self._qteFolderSelected.setText(dialog.selectedFiles()[0]) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/control/datawatcher/datawatcher.py0000644000175000017500000004747215153325210023734 0ustar00paynopaynofrom __future__ import annotations import logging import os from silx.gui import icons as silxicons from silx.gui import qt from tomwer.core.process.control.datawatcher.datawatcher import _DataWatcher from tomwer.core.scan.blissscan import BlissScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils import logconfig from tomwer.gui.control import datareacheractions, history, observations from tomwer.gui.control.datawatcher import configuration from tomwer.gui.control.datawatcher.controlwidget import ControlWidget from tomwer.gui.utils.waiterthread import QWaiterThread from tomwer.io.utils import get_default_directory from .datawatcherobserver import _QDataWatcherObserver, _QOngoingObservation logger = logging.getLogger(__name__) class DataWatcherWidget(_DataWatcher, qt.QMainWindow): """ Widget used to display the on-going acquisitions and the finished one. :param parent: the parent widget """ obsStatusToWidgetStatus = { "not processing": "Not processed", "none found": "Running", "starting": "Running", "started": "Running", "waiting for acquisition ending": "Running", "acquisition ended": "Executed", "acquisition canceled": "Failed", "failure": "Failed", } _animatedStates = ( "none found", "parsing", "waiting for acquisition ending", "starting", "started", ) DEFAULT_DIRECTORY = "/lbsram/data/visitor" sigTMStatusChanged = qt.Signal(str) """Signal emitted when the state changed""" sigScanReady = qt.Signal(object) """Signal emitted when a scan is considered as ready""" sigFolderObservedChanged = qt.Signal() """Signal emitted when the user change the observed folder""" sigObservationStart = qt.Signal() """Signal emitted when the observation starts""" sigObservationEnd = qt.Signal() """Signal emitted when the observation end""" sigFilterFileNamePatternChanged = qt.Signal(str) """Signal emut when the filter pattern change""" def __init__(self, parent=None): qt.QMainWindow.__init__(self, parent) self.setWindowFlags(qt.Qt.Widget) self._maxAdv = 100 # maximal progress bar advancement self._configWindow = None """Widget containing the configuration of the watcher""" self._historyWindow = None """Widget containing the latest valid scan found by the watcher""" self._observationWidget = None """Widget containing the current observed directory by the watcher""" self.controlWidget = None """Widget containing the 'control' of the datawatcher: select folder, status ...""" _DataWatcher.__init__(self) self.setFolderObserved(self.folderObserved) self._setStateIcon(silxicons.getQIcon("remove")) # connect signal / slot self._qteFolderSelected.textChanged.connect(self._updateFolderObserved) self._qteFolderSelected.editingFinished.connect(self._restartObservation) self._filterQLE.editingFinished.connect(self._restartObservation) self._filterQLE.editingFinished.connect(self._filterChanged) self._qpbstartstop.released.connect(self._switchObservation) # expose api self.sigObservationModeChanged = ( self.getConfigWindow()._observationMethod.sigSelectionChanged ) def _initClass(self): self.loopObservationThread = None _DataWatcher._initClass(self) toolbar = qt.QToolBar("", parent=self) toolbar.setIconSize(qt.QSize(32, 32)) self._controlAction = datareacheractions.ControlAction(parent=self) self._observationsAction = datareacheractions.ObservationAction(parent=self) self._configurationAction = datareacheractions.ConfigurationAction(parent=self) self._historyAction = datareacheractions.HistoryAction(parent=self) toolbar.addAction(self._controlAction) toolbar.addAction(self._observationsAction) toolbar.addAction(self._configurationAction) toolbar.addAction(self._historyAction) self._actionGroup = qt.QActionGroup(self) self._actionGroup.addAction(self._controlAction) self._actionGroup.addAction(self._observationsAction) self._actionGroup.addAction(self._configurationAction) self._actionGroup.addAction(self._historyAction) self.addToolBar(qt.Qt.LeftToolBarArea, toolbar) toolbar.setMovable(False) self._buildGUI() # set initial path to observe self.setFolderObserved(self._getInitPath()) # hide all windows by default for widget in ( self.getControlWindow(), self.getObservationWidget(), self.getConfigWindow(), self.getHistoryWindow(), ): widget.setVisible(False) # deal with toolbar connection self._controlAction.toggled[bool].connect(self.getControlWindow().setVisible) self._observationsAction.toggled[bool].connect( self.getObservationWidget().setVisible ) self._configurationAction.toggled[bool].connect( self.getConfigWindow().setVisible ) self._historyAction.toggled[bool].connect(self.getHistoryWindow().setVisible) self._controlAction.setChecked(True) # expose signal self.sigObservationModeChanged = ( self.getConfigWindow()._observationMethod.sigSelectionChanged ) def close(self): logger.info("closing the datawatacher") self.stop() if self.loopObservationThread is not None: self.loopObservationThread.blockSignals(True) self._disconnectObserverThread() self.loopObservationThread.wait(4000) self.loopObservationThread = None if ( self.observationThread is not None and self.observationThread.isRunning() # pylint: disable=E1101 ): self.observationThread.blockSignals(True) # pylint: disable=E1101 self.observationThread.wait(4000) self.observationThread = None super(DataWatcherWidget, self).close() def getConfigWindow(self): if self._configWindow is None: self._configWindow = configuration._DWConfigurationWidget(parent=self) self._configWindow.startByOldestStateChanged.connect(self.setStartByOldest) self._configWindow.startByOldestStateChanged.connect( self._restartObservation ) return self._configWindow def getObservationWidget(self): if self._observationWidget is None: self._observationWidget = observations.ScanObservation(parent=self) if self.observationThread: self._observationWidget.setOnGoingObservations( self.observationThread.observations ) return self._observationWidget def _changeCentralWidget(self, widget, action): actions = ( self._historyAction, self._observationsAction, self._configurationAction, self._controlAction, ) for _action in actions: _action.blockSignals(True) for _action in actions: if _action != action: _action.setChecked(False) _widgets = ( self.getControlWindow(), self.getObservationWidget(), self.getHistoryWindow(), self.getConfigWindow(), ) for _widget in _widgets: _widget.setVisible(False) widget.setVisible(action.isChecked()) for _action in actions: _action.blockSignals(False) def getControlWindow(self): if self.controlWidget is None: self.controlWidget = ControlWidget(parent=self) return self.controlWidget def _buildGUI(self): """Build the GUI of the widget""" self._mainWidget = qt.QWidget(parent=self) self._mainWidget.setLayout(qt.QVBoxLayout()) self._mainWidget.layout().addWidget(self.getControlWindow()) self._mainWidget.layout().addWidget(self.getConfigWindow()) self._mainWidget.layout().addWidget(self.getObservationWidget()) self._mainWidget.layout().addWidget(self.getHistoryWindow()) self.setCentralWidget(self._mainWidget) def _filterChanged(self, *args, **kwargs): self.sigFilterFileNamePatternChanged.emit(self._filterQLE.text()) def getFilterLinuxFileNamePattern(self) -> str | None: value = self._filterQLE.text().rstrip(" ").lstrip(" ") if value == "": return None else: return value def _buildLoopTimeBreak(self): """ Build the spin box to define the break we want to make between two observations """ widget = qt.QWidget(self.controlWidget) layout = qt.QHBoxLayout() widget.setLayout(layout) layout.addWidget(qt.QLabel("Waiting time between observations (in s)")) self._qsbLoopTimeBreak = qt.QSpinBox(parent=widget) self._qsbLoopTimeBreak.setMinimum(1) self._qsbLoopTimeBreak.setMaximum(1000000) self._qsbLoopTimeBreak.setValue(self.maxWaitBtwObsLoop) self._qsbLoopTimeBreak.valueChanged.connect(self.setWaitTimeBtwLoop) layout.addWidget(self._qsbLoopTimeBreak) return widget @property def _qlInfo(self): return self.getControlWindow()._qlInfo @property def _qteFolderSelected(self): return self.getControlWindow()._qteFolderSelected @property def _filterQLE(self): return self.getControlWindow()._filterQLE @property def _qpbstartstop(self): return self.getControlWindow()._qpbstartstop @property def _stateLabel(self): return self.getControlWindow()._stateLabel @property def mystatusBar(self): return self.getControlWindow().mystatusBar def _getInitPath(self): initPath = "" if "DATADIR" in os.environ: initPath = os.environ["DATADIR"] self.getControlWindow()._qlInfo.setText( "note : environment variable DATADIR found, " "$DATADIR setted has the root of the observe folder" ) myFont = self._qlInfo.font() myFont.setItalic(True) self._qlInfo.setFont(myFont) else: self._qlInfo.setText( "note : no DATADIR environment variable setted. " "Can't set a default root directory for observation" ) myFont = self._qlInfo.font() myFont.setItalic(True) self._qlInfo.setFont(myFont) return initPath def getHistoryWindow(self): if self._historyWindow is None: self._historyWindow = history.ScanHistory(parent=self) return self._historyWindow def stop(self, sucess=False): """ Stop the thread of observation :param sucess: if True this mean that we are stopping the observation because we found an acquisition finished. In this case we don't want to update the status and the log message. :return bool: True if the observation have been stopped. Otherwise this mean that not observation was executing """ if self.isObserving is False: return False self._setIsObserving(False) if self.loopObservationThread is not None: self.loopObservationThread.wait(int(self.maxWaitBtwObsLoop + 2)) if self.observationThread is not None: # remove connection self._disconnectObserverThread() self.observationThread.blockSignals(True) # pylint: disable=E1101 self.observationThread.wait(4000) if sucess is False: self._setCurrentStatus(str("not processing")) if sucess is False: if self._observationWidget is not None: self._observationWidget.clear() message = "observation stopped" self.sigObservationEnd.emit() logger.inform(message) self.mystatusBar.showMessage(message) self._setCurrentStatus("not processing") return True def start(self): """ Start the thread of observation :return bool: True if the observation was started. Otherwise this mean that an observation was already running """ if _DataWatcher.start(self): mess = f"start observation on {self.folderObserved}" logger.inform(mess) self.mystatusBar.showMessage(mess) self._setCurrentStatus("started") self.sigObservationStart.emit() return True else: return False def _setIsObserving(self, b): _DataWatcher._setIsObserving(self, b) if self.isObserving is True: # pylint: disable=E1101 self._qpbstartstop.setText(self.getControlWindow()._TXT_STOP_OBS) else: self._qpbstartstop.setText(self.getControlWindow()._TXT_START_OBS) def _setFolderPath(self): # pragma: no cover """ Ask the user the path to the folder to observe """ defaultDirectory = self.getFolderObserved() if defaultDirectory is None or not os.path.isdir(defaultDirectory): if os.path.isdir(self.DEFAULT_DIRECTORY): defaultDirectory = self.DEFAULT_DIRECTORY if defaultDirectory is None: defaultDirectory = get_default_directory() dialog = qt.QFileDialog(self, directory=defaultDirectory) dialog.setFileMode(qt.QFileDialog.DirectoryOnly) if not dialog.exec(): dialog.close() return self.setFolderObserved(dialog.selectedFiles()[0]) if self.isObserving: self._restartObservation() def _updateFolderObserved(self, txt): self.folderObserved = self._qteFolderSelected.text() self.sigFolderObservedChanged.emit() def setFolderObserved(self, path): if path is not None and os.path.isdir(path): super(DataWatcherWidget, self).setFolderObserved(os.path.abspath(path)) self._qteFolderSelected.setText(self.folderObserved) def setStartByOldest(self, b): """ Set if we want to start parsing files from the oldest or the newest :param b: """ _DataWatcher.setStartByOldest(self, b) self.getConfigWindow()._qcboldest.setChecked(self.startByOldest) def _initObservation(self): """ Init the thread running the data watcher functions """ if _DataWatcher._initObservation(self) is True: if self._observationWidget is not None: self._observationWidget.setOnGoingObservations( self.observationThread.observations ) return True else: return False def _messageNotDir(self, dir_): super()._messageNotDir(dir_=dir_) message = f"Given path ({dir_}) isn't a directory." self.mystatusBar.showMessage("!!! " + message + "!!!") def informationReceived(self, info): self.mystatusBar.showMessage(info) def _scanStatusChanged(self, scan, status): mess = f"scan {os.path.basename(scan)} is observed. Status: {status}" self.mystatusBar.showMessage(mess) def _connectObserverThread(self): if self.observationThread is not None and self.obsThIsConnected is False: self.observationThread.observations.sigObsStatusReceived.connect( self._scanStatusChanged ) self.observationThread.sigScanReady.connect(self._signalScanReady) self.obsThIsConnected = True def _disconnectObserverThread(self): if self.observationThread is not None and self.obsThIsConnected is True: self.observationThread.observations.sigObsStatusReceived.disconnect( self._scanStatusChanged ) self.observationThread.sigScanReady.disconnect(self._signalScanReady) self.obsThIsConnected = False def _updateStatusView(self): """Update the processing state""" if self.currentStatus in self._animatedStates: pass elif self.currentStatus == "acquisition ended": self._setStateIcon(silxicons.getQIcon("selected")) elif self.currentStatus == "failure": self._setStateIcon(silxicons.getQIcon("remove")) elif self.currentStatus == "not processing": self._setStateIcon(None) def _setStateIcon(self, icon): """set the icon pass in parameter to the state label :param icon:the icon to set""" # needed for heritage from DataWatcher if icon is None: self._stateLabel.setPixmap(qt.QIcon().pixmap(30, state=qt.QIcon.On)) else: self._stateLabel.setPixmap(icon.pixmap(30, state=qt.QIcon.On)) def _signalScanReady(self, scan): if type(scan) is str: try: _scan = ScanFactory.create_scan_object(scan_path=scan) except Exception as e: logger.error( f"Fail to create a TomoBase instance from {scan} Reason is {e}" ) return else: assert isinstance(scan, (TomwerScanBase, BlissScan)) _scan = scan _DataWatcher._signalScanReady(self, _scan) self.lastFoundScans.add(_scan) self._updateLastReceived() def _updateLastReceived(self): """ For now we are updating each time the list. It would be better to update it instead. """ self.getHistoryWindow().update(scans=list(self.lastFoundScans.items())) def _getObservationClass(self): return _QOngoingObservation def _createDataWatcher(self): self.observationThread = _QDataWatcherObserver( observationClass=self._getObservationClass(), obsMethod=self.obsMethod, srcPattern=self.srcPattern, destPattern=self.destPattern, file_name_pattern=self.linux_filter_file_pattern, ) self._connectObserverThread() def _check_finished_scan(self): # nothing to do: managed by signals pass def waitForObservationFinished(self): if self.observationThread.observations is not None: for _, thread in self.observationThread.observations.dict.items(): thread.wait(10) def _launchObservation(self): """Main function of the widget""" if self.isObserving is False: return # manage data watcher observation if ( self.observationThread is None or not self.observationThread.isRunning() # pylint: disable=E1101 ): if self._initObservation() is False: self._setCurrentStatus("failure") logger.info( "failed on observation", extra={logconfig.DOC_TITLE: self._scheme_title}, ) return # starting the observation thread self.observationThread.start() # manage observation loop if self.loopObservationThread is None: self.loopObservationThread = QWaiterThread( self.getTimeBreakBetweenObservation() ) self.loopObservationThread.finished.connect(self._launchObservation) if not self.loopObservationThread.isRunning(): self._connectObserverThread() self.loopObservationThread.start() def _observation_thread_running(self): return ( self.observationThread is not None and self.observationThread.isRunning() # pylint: disable=E1101 ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/control/datawatcher/datawatcherobserver.py0000644000175000017500000002204215153325210025466 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging import os from fnmatch import fnmatch import h5py from silx.gui import qt from tomwer.core.process.control.datawatcher import status as datawatcherstatus from tomwer.core.process.control.datawatcher.datawatcherobserver import ( _DataWatcherObserver_MixIn, _DataWatcherStaticObserverMixIn, _OngoingObservation, ) from tomwer.core.scan.blissscan import BlissScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.scanfactory import ScanFactory logger = logging.getLogger(__name__) class _QDataWatcherObserver(_DataWatcherObserver_MixIn, qt.QThread): """ DatWatcherObserver implementation with a qt.QThread We have two implementations in order to avoid hard dependancy on qt for tomwer.core package """ sigScanReady = qt.Signal(object) """emit when scan ready""" def __init__( self, obsMethod, observationClass, headDir=None, startByOldest=False, srcPattern=None, destPattern=None, ignoredFolders=None, file_name_pattern=None, ): qt.QThread.__init__(self) _DataWatcherObserver_MixIn.__init__( self, obsMethod=obsMethod, observationClass=observationClass, headDir=headDir, startByOldest=startByOldest, srcPattern=srcPattern, destPattern=destPattern, ignoredFolders=ignoredFolders, time_between_loops=0.2, file_name_pattern=file_name_pattern, ) self.observations.sigScanReady.connect(self._signalScanReady) def _signalScanReady(self, scan): assert isinstance(scan, (TomwerScanBase, BlissScan)) self.sigScanReady.emit(scan) def _getObserver(self, scanID): return _QDataWatcherStaticObserver( scanID=scanID, obsMethod=self.obsMethod, srcPattern=self.srcPattern, destPattern=self.destPattern, patternObs=self._patternObs, observationRegistry=self.observations, ) def run(self): look_for_hdf5_file = self.obsMethod in ( datawatcherstatus.BLISS_SCAN_END, datawatcherstatus.NXtomo_END, ) def process(file_path): do_observation = ( self.observations.isObserving(file_path) is False and ( (look_for_hdf5_file and h5py.is_hdf5(file_path)) or (self.dataWatcherProcess._isScanDirectory(file_path)) ) and file_path not in self.observations.ignoredFolders ) if ( do_observation and self.file_name_pattern is not None and not fnmatch(os.path.basename(file_path), self.file_name_pattern) ): do_observation = False if do_observation is True: # do the observation self.observe(file_path) if os.path.isdir(file_path): try: for f in os.listdir(file_path): full_file_path = os.path.join(file_path, f) if os.path.isdir(full_file_path) or ( look_for_hdf5_file and h5py.is_hdf5(full_file_path) ): process(full_file_path) except Exception: pass if not os.path.isdir(self.headDir): logger.warning("can't observe %s, not a directory" % self.headDir) return self.dataWatcherProcess = self._getDataWatcherProcess() process(self.headDir) self._processObservation() def waitForObservationFinished(self, timeOut=10): threads = list(self.observations.dict.values()) for thread in threads: thread.wait(timeOut) def wait(self, *args, **kwargs): self.waitForObservationFinished() super(_QDataWatcherObserver, self).wait(*args, **kwargs) class _QOngoingObservation(_OngoingObservation, qt.QObject): """ _OngoingObservation with a QObject and signals for each event """ sigScanReady = qt.Signal(object) """Emitted when a finished acquisition is detected""" sigObsAdded = qt.Signal(str) """Signal emitted when an observation is added""" sigObsRemoved = qt.Signal(str) """Signal emitted when an observation is removed""" sigObsStatusReceived = qt.Signal(str, str) """Signal emitted when receiving a new observation status""" def __init__(self): qt.QObject.__init__(self) _OngoingObservation.__init__(self) def _acquisition_ended(self, scanID): _OngoingObservation._acquisition_ended(self, scanID=scanID) try: scans = ScanFactory.create_scan_objects( scan_path=scanID, accept_bliss_scan=True ) except Exception as e: logger.error(f"Fail to create TomoBase instance from {scanID} Error is {e}") else: for scan in scans: self.sigScanReady.emit(scan) def add(self, observer): already_observing = self.isObserving(observer.path) _OngoingObservation.add(self, observer=observer) if not already_observing: observer.sigStatusChanged.connect(self._updateStatus) self.sigObsAdded.emit(observer.path) def remove(self, observer): observing = self.isObserving(observer.path) _OngoingObservation.remove(self, observer=observer) if observing is True: observer.sigStatusChanged.disconnect(self._updateStatus) self.sigObsRemoved.emit(observer.path) def _updateStatus(self, status, scan): if self.isObserving(scan) is True: self.sigObsStatusReceived.emit( scan, datawatcherstatus.DICT_OBS_STATUS[status] ) _OngoingObservation._updateStatus(self, status=status, scan=scan) def reset(self): # self.ignoreFolders = [] for scanID, observer in self.dict: observer.sigStatusChanged.disconnect(self._updateStatus) observer.quit() self.dict = {} class _QDataWatcherStaticObserver(_DataWatcherStaticObserverMixIn, qt.QThread): """ Implementation of the _DataWatcherFixObserverMixIn with a qt.QThread """ sigStatusChanged = qt.Signal(int, str) """signal emitted when the status for a specific directory change """ def __init__( self, scanID, obsMethod, srcPattern, destPattern, patternObs, observationRegistry, ): qt.QThread.__init__(self) _DataWatcherStaticObserverMixIn.__init__( self, scanID=scanID, obsMethod=obsMethod, srcPattern=srcPattern, destPattern=destPattern, patternObs=patternObs, observationRegistry=observationRegistry, ) def run(self): look_for_hdf5_file = self.obsMethod in ( datawatcherstatus.BLISS_SCAN_END, datawatcherstatus.NXtomo_END, ) if not look_for_hdf5_file and not os.path.isdir(self.path): logger.info("can't observe %s, not a directory" % self.path) self.status = "failure" self.sigStatusChanged.emit( datawatcherstatus.OBSERVATION_STATUS[self.status], self.path ) self.validation = -1 return try: scans = ScanFactory.create_scan_objects( scan_path=self.path, accept_bliss_scan=True ) except ValueError as e: logger.error(e) else: for scan in scans: if scan.is_abort( src_pattern=self.srcPattern, dest_pattern=self.destPattern ): if self.status != "aborted": logger.info("Acquisition %s has been aborted" % self.path) self.dataWatcherProcess._removeAcquisition( scanID=self.path, reason="acquisition aborted by the user" ) self.status = "aborted" self.sigStatusChanged.emit( datawatcherstatus.OBSERVATION_STATUS[self.status], self.path ) self.validation = -2 return dataComplete = self.dataWatcherProcess.is_data_complete() if dataComplete is True: self.status = "acquisition ended" self.sigStatusChanged.emit( datawatcherstatus.OBSERVATION_STATUS[self.status], self.path ) self.validation = 1 else: self.status = "waiting for acquisition ending" self.sigStatusChanged.emit( datawatcherstatus.OBSERVATION_STATUS[self.status], self.path ) self.validation = 0 return ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/control/history.py0000644000175000017500000000650114757047403020661 0ustar00paynopayno# coding: utf-8 from __future__ import annotations from operator import itemgetter from silx.gui import qt from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanbase import TomwerScanBase class ScanHistory(qt.QWidget): """Widget used to display the lastest discovered scans""" def __init__(self, parent): qt.QWidget.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) self.layout().addWidget(qt.QLabel("")) self.scanHistory = qt.QTableView(parent=parent) self.scanHistory.setSelectionBehavior(qt.QAbstractItemView.SelectRows) self.scanHistory.setModel( _FoundScanModel( parent=self.scanHistory, header=("time", "type", "scan ID"), mlist={} ) ) self.scanHistory.resizeColumnsToContents() self.scanHistory.setSortingEnabled(True) self.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding) self.layout().addWidget(self.scanHistory) header = self.scanHistory.horizontalHeader() header.setSectionResizeMode(0, qt.QHeaderView.Fixed) header.setSectionResizeMode(1, qt.QHeaderView.Fixed) header.setSectionResizeMode(2, qt.QHeaderView.Stretch) header.setStretchLastSection(True) def update(self, scans): self.scanHistory.setModel( _FoundScanModel( parent=self, header=("time", "type", "scan ID"), mlist=scans ) ) self.scanHistory.resizeColumnsToContents() class _FoundScanModel(qt.QAbstractTableModel): """ Model for :class:_ScanHistory :param mlist: list of tuple (scan, time stamp) """ def __init__(self, parent, header, mlist: list[tuple], *args): qt.QAbstractTableModel.__init__(self, parent, *args) self.header = header self.myList = mlist def rowCount(self, parent=None): if self.myList is None: return 0 else: return len(self.myList) def columnCount(self, parent=None): return 3 def sort(self, col, order): self.layoutAboutToBeChanged.emit() if self.myList is None: return self.myList = sorted(list(self.myList), key=itemgetter(col)) if order == qt.Qt.DescendingOrder: self.myList = list(reversed(sorted(list(self.myList), key=itemgetter(col)))) self.layoutChanged.emit() def data(self, index, role): if not index.isValid(): return None elif role != qt.Qt.DisplayRole: return None if index.column() == 0: return self.myList[index.row()][1].strftime("%a %m - %d - %Y - %H:%M:%S") elif index.column() == 1: path = self.myList[index.row()][0] if isinstance(path, TomwerScanBase): return path.type elif isinstance(path, str) and path.startswith("hdf5 scan"): return "hdf5" elif NXtomoScan.directory_contains_scan(path) or "@" in path: return "hdf5" else: return "edf" elif index.column() == 2: return self.myList[index.row()][0] def headerData(self, col, orientation, role): if orientation == qt.Qt.Horizontal and role == qt.Qt.DisplayRole: return self.header[col] return None ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/control/nxtomomill.py0000644000175000017500000001347415143647637021376 0ustar00paynopayno# coding: utf-8 from __future__ import annotations from silx.gui import qt class InputDialogWithCache(qt.QDialog): """ Input dialog for get missing information for nxtomomill translation Identical to a default QInputDialog adding a CheckBox to store answer. """ def __init__(self, parent, scan, title="", desc="", cache_answer=True): qt.QDialog.__init__(self, parent) self.setWindowFlags(qt.Qt.MSWindowsFixedSizeDialogHint) self.setWindowTitle(title) self.setLayout(qt.QGridLayout()) # entry self.layout().addWidget(qt.QLabel("entry:", self), 0, 0, 1, 1) self._entryQLE = qt.QLineEdit(scan.entry if scan else "", self) self._entryQLE.setReadOnly(True) self.layout().addWidget(self._entryQLE, 0, 1, 1, 1) # file name self.layout().addWidget(qt.QLabel("file:", self), 1, 0, 1, 1) self._fileQLE = qt.QLineEdit(scan.master_file if scan else "", self) self._fileQLE.setReadOnly(True) self.layout().addWidget(self._fileQLE, 1, 1, 1, 1) # label message self._label = qt.QLabel(desc, self) self.layout().addWidget(self._label, 2, 0, 1, 2) # input QLineEdit self._input = qt.QLineEdit("", self) self.layout().addWidget(self._input, 3, 0, 1, 2) # cache combobox self._cacheAnswerCB = qt.QCheckBox("keep answer in cache", self) self._cacheAnswerCB.setToolTip( "Will keep in memory the answer for the" " 'current cycle'. A cycle starts when " "you press 'send all' or " "'send selected' and ends when the last" " scan as been converted. The cache is " "reset after each cycle" ) font = self._cacheAnswerCB.font() font.setPixelSize(10) self._cacheAnswerCB.setFont(font) self.layout().addWidget(self._cacheAnswerCB, 4, 0, 1, 1) spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer, 5, 0, 1, 1) # buttons for validation self._buttons = qt.QDialogButtonBox(self) types = qt.QDialogButtonBox.Ok | qt.QDialogButtonBox.Cancel self._buttons.setStandardButtons(types) self.layout().addWidget(self._buttons, 4, 0, 1, 2) # set up self._cacheAnswerCB.setChecked(cache_answer) # connect signal / slot self._buttons.button(qt.QDialogButtonBox.Ok).clicked.connect(self.accept) self._buttons.button(qt.QDialogButtonBox.Cancel).clicked.connect(self.reject) def setLabelText(self, txt): self._label.setText(txt) def getText(self): return self._input.text() def setScan(self, entry, file_path): self._entryQLE.setText(entry) self._fileQLE.setText(file_path) def cache_answer(self): return self._cacheAnswerCB.isChecked() def setBlissScan(self, entry, file_path): self._fileQLE.setText(file_path) self._entryQLE.setText(entry) def clear(self): self.setWindowTitle("") self._label.setText("") self._input.setText("") class NXTomomillInput: """ callback provided to nxtomomill if an entry is missing. The goal is to ask the user the missing informations :param entry: name of the entry missing :param desc: description of the entry :return: user input or None """ def __init__(self, parent=None, scan=None): self._dialog = InputDialogWithCache(parent=None, scan=scan) self._cache = {} """Cache to be used the user want to uase back answer for some question """ def exec_(self, field, desc): self._dialog.clear() self._dialog.setWindowTitle(field) self._dialog.setLabelText(desc) if field in self._cache: return self._cache[field] else: if self._dialog.exec(): answer = self._dialog.getText() if self._dialog.cache_answer(): self._cache[field] = answer return answer else: return None def setBlissScan(self, entry, file_path): self._dialog.setScan(entry=entry, file_path=file_path) __call__ = exec_ class OverwriteMessage(qt.QDialog): def __init__(self, parent, message=""): qt.QDialog.__init__(self, parent) self.setLayout(qt.QGridLayout()) self._label = qt.QLabel(message, self) self.layout().addWidget(self._label, 0, 0, 1, 2) self._canOverwriteAllCB = qt.QCheckBox("overwrite all", self) self._canOverwriteAllCB.setToolTip( "Will keep in memory the right to overwrite nxtomomill output " "files for the 'current cycle'. A cycle starts when you press " "'send all' or 'send selected' and ends when the last scan as been" " converted. The cache is reset after each cycle" ) font = self._canOverwriteAllCB.font() font.setPixelSize(10) self._canOverwriteAllCB.setFont(font) self.layout().addWidget(self._canOverwriteAllCB, 2, 0, 1, 1) spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer, 3, 0, 1, 1) types = qt.QDialogButtonBox.Ok | qt.QDialogButtonBox.No self._buttons = qt.QDialogButtonBox(self) self._buttons.setStandardButtons(types) self.layout().addWidget(self._buttons, 8, 0, 1, 1) # signal / slot connection self._buttons.button(qt.QDialogButtonBox.Ok).clicked.connect(self.accept) self._buttons.button(qt.QDialogButtonBox.No).clicked.connect(self.reject) def setText(self, msg): self._label.setText(msg) def canOverwriteAll(self): return self._canOverwriteAllCB.isChecked() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/control/observations.py0000644000175000017500000001756615143647637021720 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import weakref from collections import OrderedDict from datetime import datetime from silx.gui import qt from tomwer.core.scan.blissscan import BlissScan from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanbase import TomwerScanBase try: from processview.gui.utils.qitem_model_resetter import qitem_model_resetter except ImportError: from tomwer.third_part.qitem_model_resetter import qitem_model_resetter class ScanObservation(qt.QWidget): """ Widget displayed the on-going observations (done by the data-listener) For each scan on-going we can display the following information: * time (when the scan has been discovered) * type: HDF5 or EDF * N projections: number of projections already acquired (a) * status of the scan (starting, on-going...) * acquisition: id of the scan (entry and data path in case of HDF5 scan) (a) the GUI was set up to display this information. Nevertheless this information is not provided by the rpc-call so this was never used. Context: when the 'data listener' gets triggered by bliss-tomo then we want to notify the user that a new scan is on-going. """ HEADER = ("Time", "Type", "N Projections", "Status", "Acquisition") def __init__(self, parent): qt.QWidget.__init__(self, parent) self._onGoingObservations = None self.setLayout(qt.QVBoxLayout()) self.layout().addWidget(qt.QLabel("")) self.observationTable = qt.QTableView(parent=parent) self.observationTable.setSelectionBehavior(qt.QAbstractItemView.SelectRows) self.observationTable.setModel( _ObservedScanModel(parent=self.observationTable, header=self.HEADER) ) self.observationTable.resizeColumnsToContents() self.observationTable.setSortingEnabled(True) self.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding) self.layout().addWidget(self.observationTable) header = self.observationTable.horizontalHeader() header.setSectionResizeMode(0, qt.QHeaderView.Fixed) header.setSectionResizeMode(1, qt.QHeaderView.Fixed) header.setSectionResizeMode(2, qt.QHeaderView.Fixed) header.setSectionResizeMode(3, qt.QHeaderView.Fixed) header.setSectionResizeMode(4, qt.QHeaderView.Stretch) header.setStretchLastSection(True) self.observationTable.setColumnWidth(0, 70) self.observationTable.setColumnWidth(1, 40) self.observationTable.setColumnWidth(2, 90) self.observationTable.setColumnWidth(3, 70) @property def onGoingObservations(self): if self._onGoingObservations: return self._onGoingObservations() else: return None def setOnGoingObservations(self, onGoingObservations): """ will update the table to display the observations contained in onGoingObservations :param onGoingObservations: the obsevations observed to display """ if self.onGoingObservations: self.onGoingObservations.sigObsAdded.disconnect(self.addObservation) self.onGoingObservations.sigObsRemoved.disconnect(self.removeObservation) self.onGoingObservations.sigObsStatusReceived.disconnect(self.update) self._onGoingObservations = weakref.ref(onGoingObservations) self.onGoingObservations.sigObsAdded.connect(self.addObservation) self.onGoingObservations.sigObsRemoved.connect(self.removeObservation) self.onGoingObservations.sigObsStatusReceived.connect(self.update) def update(self, scan, status): """ :param scan: the updated scan :param status: the status of the updated scan """ self.observationTable.model().update(scan, status) def addObservation(self, scan): """ :param scan: the scan observed """ self.observationTable.model().add(scan, "starting") def removeObservation(self, scan): """ :param scan: the scan removed """ self.observationTable.model().remove(scan) def clear(self): self.observationTable.model().clear() class _ObservedScanModel(qt.QAbstractTableModel): def __init__(self, parent, header, *args): qt.QAbstractTableModel.__init__(self, parent, *args) self.header = header self.observations = OrderedDict() self._time_stamps = OrderedDict() # note: the time stamp is the time of the discovery and not of the start scan (as we don't have this information) def add(self, scan, status): with qitem_model_resetter(self): self.observations[scan] = status self._time_stamps[scan] = datetime.now() def remove(self, scan): with qitem_model_resetter(self): self.observations.pop(scan, None) self._time_stamps.pop(scan, None) def update(self, scan, status): with qitem_model_resetter(self): self.observations[scan] = status def clear(self): with qitem_model_resetter(self): self.observations = OrderedDict() self._time_stamps = OrderedDict() def rowCount(self, parent=None): return len(self.observations) def columnCount(self, parent=None): return len(self.header) def sort(self, col, order): self.layoutAboutToBeChanged.emit() if self.observations is None: return to_order = {} for observation in self.observations.keys(): to_order[str(observation)] = observation ordering = sorted(list(to_order.keys())) if order == qt.Qt.DescendingOrder: ordering = reversed(ordering) _observations = OrderedDict() _time_stamps = OrderedDict() for str_key in ordering: key = to_order[str_key] _observations[key] = self.observations[key] _time_stamps[key] = self._time_stamps[key] self.observations = _observations self._time_stamps = _time_stamps self.layoutChanged.emit() def data(self, index, role): if index.isValid() is False: return None if role not in (qt.Qt.DisplayRole, qt.Qt.ToolTipRole): return None obs = list(self.observations.keys())[index.row()] time_stamp = self._time_stamps.get(obs, None) # time stamp if index.column() == 0: if time_stamp: return time_stamp.strftime("%H:%M:%S") else: return "Unknown timestamp" # acquisition type elif index.column() == 1: if isinstance(obs, TomwerScanBase): return obs.type elif isinstance(obs, BlissScan): return "hdf5" elif NXtomoScan.directory_contains_scan(directory=obs): return "hdf5" else: return "edf" # N projections elif index.column() == 2: if isinstance(obs, TomwerScanBase): return obs.tomo_n or 0 elif isinstance(obs, BlissScan): return f"(at least) {obs.n_acquired or '?'} over {obs.tomo_n or '?'}" elif os.path.exists(obs) and os.path.isdir(obs): return str(len(os.listdir(obs))) else: return None elif index.column() == 3: return self.observations[obs] # observation id elif index.column() == 4: if role == qt.Qt.ToolTipRole: return obs elif isinstance(obs, (TomwerScanBase, BlissScan)): return str(obs) else: return os.path.basename(obs) else: return None def headerData(self, col, orientation, role): if orientation == qt.Qt.Horizontal and role == qt.Qt.DisplayRole: return self.header[col] return None ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/control/reducedarkflatselector.py0000644000175000017500000005022515153325210023665 0ustar00paynopaynofrom __future__ import annotations from copy import copy import os import numpy import logging from silx.gui import qt from silx.gui.plot import Plot2D from silx.io.dictdump import h5todict from silx.io.url import DataUrl from silx.io.utils import open as open_hdf5 from silx.gui.dialog.DataFileDialog import DataFileDialog from tomoscan.esrf.scan.utils import cwd_context from tomoscan.framereducer.target import REDUCER_TARGET from tomwer.io.utils import get_default_directory _logger = logging.getLogger(__name__) class ReduceDarkFlatSelectorTableWidget(qt.QWidget): """ Table widget used to register and select a list of reduces frames """ sigActiveChanged = qt.Signal(object) """Signal emit when the active frame changed (the one to be displayed)""" sigUpdated = qt.Signal() """Signal emit when the table is updated""" def __init__(self, parent: qt.QWidget | None = None) -> None: super().__init__(parent) self._iDict = 0 self._dicts = {} # key are 'dict name', value are dict of the reduced frame (acquisition index as key, 2D numpy array as value). self.setLayout(qt.QVBoxLayout()) self._tree = qt.QTreeWidget(self) self._tree.setHeaderLabels(("reduce frames", "acq index", "select")) self._tree.header().setStretchLastSection(False) self._tree.header().setSectionResizeMode(0, qt.QHeaderView.Stretch) self._tree.setColumnWidth(1, 80) self._tree.setColumnWidth(2, 50) self.layout().addWidget(self._tree) self.setAcceptDrops(True) # connect signal / slot self._tree.currentItemChanged.connect(self._updateActiveChanged) def _updateActiveChanged(self, item, column: int): frame = item.data(0, qt.Qt.UserRole) self.sigActiveChanged.emit(frame) def popDictIndex(self) -> int: self._iDict = self._iDict + 1 return self._iDict - 1 def addReduceFrames(self, reduced_frames: dict, selected: tuple = ()): """ Add the reduced frames in the interface. :param reduced_frames: frame index as key and numpy.ndarray as value :param selected: if the frame index is in selected tuple then this item will be automatically selected """ reduced_frames = copy(reduced_frames) dict_key = ( reduced_frames.pop("reduce_frames_name", None) or f"reduced frames #{self.popDictIndex()}" ) # if the key already exists: remove it (avoid ) if dict_key in self._dicts: self._removeReduceFramesByLabel(dict_key) self._dicts[dict_key] = reduced_frames topLevelItem = qt.QTreeWidgetItem(self._tree) topLevelItem.setText(0, dict_key) for frame_index, frame in reduced_frames.items(): if not isinstance(frame, numpy.ndarray): _logger.error( f"frame are expected to be numpy.ndarray. Get {type(frame)} instead - will not add it" ) continue if frame.ndim != 2: _logger.error(f"frame are expected to be 2D. Get {frame.shape} instead") continue # frame info frameInfo = qt.QTreeWidgetItem(topLevelItem) frameInfo.setText(0, f"shape: {frame.shape}, dtype {frame.dtype}") frameInfo.setData(0, qt.Qt.UserRole, frame) # frame index indexItem = qt.QLineEdit(self._tree) # index can be provided as absolute indexes (integers) validator = qt.QRegularExpressionValidator( qt.QRegularExpression(r"([+-]?([0-9]*[.])?[0-9]+)*[r]"), self ) indexItem.setValidator(validator) indexItem.setText(str(frame_index)) self._tree.setItemWidget(frameInfo, 1, indexItem) indexItem.setToolTip( "Index of the reduced frames in the acquisition. Value can be provided as an absolute value - integer or as a relative value. In this case we expect users to provide a value between [0 and 1.0[ and postfix by 'r'" ) # item selection selectCB = qt.QCheckBox(self._tree) selectCB.setChecked(frame_index in selected) self._tree.setItemWidget(frameInfo, 2, selectCB) self.sigUpdated.emit() def clear(self): self._dicts.clear() self._tree.clear() self.sigUpdated.emit() def getConfiguration(self) -> tuple: """ return configuration as a tuple of 'reduced frames'. Each reduced_frames are provided with the following: * 'reduce_frames_name': str: name of the reduced frame * 'reduce_frames': tuple of dict for each reduce frame. This second dict contains: * index: index of this frame in the acquisition * data: the reduce frame as a 2D array * selected: is the frame selected by the user """ config = [] for i_child in range(self._tree.topLevelItemCount()): child = self._tree.topLevelItem(i_child) reduce_frames_infos = [] for j_child in range(child.childCount()): sub_child = child.child(j_child) reduce_frames_infos.append( { "data": sub_child.data(0, qt.Qt.UserRole), "index": self._get_reduce_frame_index( self._tree.itemWidget(sub_child, 1).text() ), "selected": self._tree.itemWidget(sub_child, 2).isChecked(), } ) config.append( { "reduce_frames_name": child.text(0), "reduce_frames": reduce_frames_infos, } ) return tuple(config) def setConfiguration(self, config: tuple | None): if config is None: return self.clear() for reduce_frames in config: frames_dict = { "reduce_frames_name": reduce_frames.get("reduce_frames_name", None) } selected = [] for reduce_frame in reduce_frames["reduce_frames"]: assert isinstance( reduce_frame, dict ), f"reduce_frames is expected to contain a list of dict. Get {type(reduce_frame)} instead" frame_index = reduce_frame["index"] assert isinstance(frame_index, int) or ( isinstance(frame_index, str) and frame_index.endswith("r") ), f"frame index should be an int or a str ending by 'r', get {type(frame_index)}" frames_dict[frame_index] = reduce_frame["data"] if reduce_frame["selected"]: selected.append(reduce_frame["index"]) self.addReduceFrames(frames_dict, selected) self.sigUpdated.emit() @staticmethod def _get_reduce_frame_index(index_as_str): """ simple util to return expected frame index depending if the index is provided as relative or as absolute. """ if index_as_str.endswith("r"): return index_as_str else: return int(index_as_str) def getSelectedReduceFrames(self) -> dict: """ Return the selected reduced frame as dict """ reduce_frames = {} for i_child in range(self._tree.topLevelItemCount()): child = self._tree.topLevelItem(i_child) for j_child in range(child.childCount()): sub_child = child.child(j_child) is_selected = self._tree.itemWidget(sub_child, 2).isChecked() if not is_selected: continue frame_index = self._get_reduce_frame_index( self._tree.itemWidget(sub_child, 1).text() ) data = sub_child.data(0, qt.Qt.UserRole) assert isinstance( data, numpy.ndarray ), f"frame are expected to be numpy.ndarray. Get {type(data)} instead" assert ( data.ndim == 2 ), f"frame are expected to be 2D. Get {data.shape} instead" if frame_index in reduce_frames: _logger.error( f"frame index {frame_index} defined twice. Ignore last one" ) reduce_frames[frame_index] = data return reduce_frames def clearSelection(self): """ Uncheck any check Combobox found """ for i_child in range(self._tree.topLevelItemCount()): child = self._tree.topLevelItem(i_child) for j_child in range(child.childCount()): sub_child = child.child(j_child) if self._tree.itemWidget(sub_child, 2).isChecked(): self._tree.itemWidget(sub_child, 2).setChecked(False) def _removeSelected(self): # note: simplest way to remove item it to reset the configuration configuration = self.getConfiguration() configuration = filter_unselected_reduced_frames(configuration=configuration) self.setConfiguration(configuration) self.sigUpdated.emit() def _removeReduceFramesByLabel(self, label: str): """ remove the label named 'label' if exists. The simplest way to remove reduced frames are by reseting the configuration for now """ configuration = list(self.getConfiguration()) new_configuration = tuple( filter( lambda my_dict: my_dict.get("reduce_frames_name", None) != label, configuration, ), ) if len(configuration) != len(new_configuration): self.setConfiguration(new_configuration) def _guessReduceFramesFromFile(self, file_path: str) -> tuple: if not os.path.exists(file_path): _logger.error(f"file doesn't exists ({file_path})") with open_hdf5(file_path) as h5f: entries = tuple(h5f.keys()) res = [] for entry in entries: res.extend( self.get_reduce_frames( DataUrl( file_path=file_path, data_path=entry, ) ) ) return tuple(res) @staticmethod def get_reduce_frames(url: DataUrl) -> tuple: """ try to guess location of darks / flats according to provided url. The idea is to be more robust if the user provide a file or an higher level data path :warning: Return a tuple and not a dict. Because in the case the user provide an entry which contains a 'darks' and a flats' groups we want to return both reduced_frames. And we cannot return them as a dict as they can have the same index - used as dict key """ if not isinstance(url, DataUrl): raise TypeError(f"url is expected to be a DataUrl. Get {type(url)} instead") if not os.path.exists(url.file_path()): _logger.error(f"file doesn't exists ({url.file_path()})") return tuple() result = [] with cwd_context(url.file_path()): reduced_info_dict = h5todict( h5file=url.file_path(), path=url.data_path(), ) for target in REDUCER_TARGET: if target.value in reduced_info_dict: reduced_frames = reduced_info_dict[target.value] reduced_frames["reduce_frames_name"] = ( f"{target.value} from {url.data_path()}@{os.path.basename(url.file_path())}" ) result.append(reduced_frames) if len(reduced_frames) == 0: # else we consider the data_path is the valid one reduced_frames["reduce_frames_name"] = ( f"{url.data_path()}@{os.path.basename(url.file_path())}" ) result.append(reduced_frames) return tuple(result) # drag / drop handling def dropEvent(self, event): if event.mimeData().hasFormat("text/uri-list"): for url in event.mimeData().urls(): reduced_frames_list = self._guessReduceFramesFromFile( file_path=url.path() ) for reduced_frames in reduced_frames_list: self.addReduceFrames(reduced_frames) def supportedDropActions(self): """Inherited method to redefine supported drop actions.""" return qt.Qt.CopyAction | qt.Qt.MoveAction def dragEnterEvent(self, event): if hasattr(event, "mimeData") and event.mimeData().hasFormat("text/uri-list"): event.accept() event.setDropAction(qt.Qt.CopyAction) else: try: qt.QListWidget.dragEnterEvent(self, event) except TypeError: pass def dragMoveEvent(self, event): if hasattr(event, "mimeDatamyitems") and event.mimeDatamyitems().hasFormat( "text/uri-list" ): event.setDropAction(qt.Qt.CopyAction) event.accept() else: try: qt.QListWidget.dragMoveEvent(self, event) except TypeError: pass class ReduceDarkFlatSelectorWidget(qt.QSplitter): """ Widget combining ReduceDarkFlatSelectorTableWidget and plot of the active item """ sigUpdated = qt.Signal() """Signal emmit when the table is updated""" def __init__(self, parent: qt.QWidget | None = None) -> None: super().__init__(parent) self._first_display = True self._plot = Plot2D(self) self.addWidget(self._plot) self._table = ReduceDarkFlatSelectorTableWidget(parent=self) self.addWidget(self._table) # connect signal / slot self._table.sigActiveChanged.connect(self._updatePlot) self._table.sigUpdated.connect(self._tableUpdated) def _tableUpdated(self, *args, **kwargs): self.sigUpdated.emit() def _updatePlot(self, obj: numpy.ndarray | None): if obj is None: self._plot.clear() else: self._plot.addImage( data=obj, replace=True, resetzoom=self._first_display, ) self._first_display = False # expose API def addReduceFrames(self, *args, **kwargs): self._table.addReduceFrames(*args, **kwargs) def getConfiguration(self) -> tuple: return self._table.getConfiguration() def setConfiguration(self, *args, **kwargs): self._table.setConfiguration(*args, **kwargs) def getSelectedReduceFrames(self) -> dict: return self._table.getSelectedReduceFrames() def clearSelection(self) -> None: self._table.clearSelection() def _removeSelected(self) -> None: self._table._removeSelected() def clear(self) -> None: self._table.clear() class ReduceDarkFlatSelectorDialog(qt.QDialog): """ 'Final' dialog to select reduce frames """ sigClearSelection = qt.Signal() """emit when user ask for the selection to be cleared""" sigSelectActiveAsDarks = qt.Signal(dict) """emit when user select the darks to be activated""" sigSelectActiveAsFlats = qt.Signal(dict) """emit when user select the flats to be activated""" sigUpdated = qt.Signal() """Signal emmit when the table is updated""" def __init__(self, parent=None) -> None: super().__init__(parent) self.setLayout(qt.QVBoxLayout()) # add list self._widget = ReduceDarkFlatSelectorWidget() self.layout().addWidget(self._widget) # add buttons self._buttons = qt.QDialogButtonBox(parent=self) # select reduce flats self._selectAsFlatButton = qt.QPushButton( "Select as reduce flat(s)", parent=self ) self._buttons.addButton( self._selectAsFlatButton, qt.QDialogButtonBox.AcceptRole ) # select reduce darks self._selectAsDarkButton = qt.QPushButton( "Select as reduce dark(s)", parent=self ) self._buttons.addButton( self._selectAsDarkButton, qt.QDialogButtonBox.AcceptRole ) # clear self._clearSelectionButton = qt.QPushButton("clear selection", parent=self) self._buttons.addButton( self._clearSelectionButton, qt.QDialogButtonBox.ResetRole ) # remove selected self._removeSelectionButton = qt.QPushButton("remove selection", parent=self) self._buttons.addButton( self._removeSelectionButton, qt.QDialogButtonBox.ActionRole ) # remove selected self._addButton = qt.QPushButton("add", parent=self) self._buttons.addButton(self._addButton, qt.QDialogButtonBox.ActionRole) self.layout().addWidget(self._buttons) # connect signal / slot self._selectAsFlatButton.released.connect(self._flatSelected) self._selectAsDarkButton.released.connect(self._darkSelected) self._clearSelectionButton.released.connect(self._clearSelection) self._removeSelectionButton.released.connect(self._removeSelected) self._addButton.released.connect(self._addFromFileSelection) self._widget.sigUpdated.connect(self._tableUpdated) def _tableUpdated(self, *args, **kwargs): self.sigUpdated.emit() def _flatSelected(self): self.sigSelectActiveAsFlats.emit( self._widget.getSelectedReduceFrames(), ) def _darkSelected(self): self.sigSelectActiveAsDarks.emit( self._widget.getSelectedReduceFrames(), ) def _clearSelection(self): self._widget.clearSelection() def _removeSelected(self): self._widget._removeSelected() def _addFromFileSelection(self): dialog = DataFileDialog() dialog.setDirectory(get_default_directory()) if dialog.exec(): url = dialog.selectedUrl() reduced_frames_tuple = ReduceDarkFlatSelectorTableWidget.get_reduce_frames( DataUrl(path=url) ) for reduced_frames in reduced_frames_tuple: try: self.addReduceFrames(reduced_frames) except Exception as e: _logger.error(e) # expose API def addReduceFrames(self, *args, **kwargs): self._widget.addReduceFrames(*args, **kwargs) def getConfiguration(self) -> tuple: self._widget.getConfiguration() def setConfiguration(self, configuration: tuple) -> None: self._widget.setConfiguration(configuration) def filter_selected_reduced_frames(configuration: tuple): """ remove all the frames not 'selected' from the configuration. If a reduce frame set becomes empty it will also be removed :param configuration: configuration of the reduced frames """ return _filter_reduced_frames(configuration=configuration, filter_selected=True) def filter_unselected_reduced_frames(configuration: tuple): """ remove all the frames 'selected' from the configuration. If a reduce frame set becomes empty it will also be removed :param configuration: configuration of the reduced frames """ return _filter_reduced_frames(configuration=configuration, filter_selected=False) def _filter_reduced_frames(configuration: tuple, filter_selected: bool): assert isinstance( configuration, (tuple, list, set) ), f"configuration is expected to be a tuple. Get {type(configuration)}" result = [] for reduce_group in configuration: reduce_frames = reduce_group.get("reduce_frames", tuple()) reduce_group_name = reduce_group.get("reduce_frames_name", None) res_set = tuple( filter( lambda my_dict: my_dict["selected"] == filter_selected, reduce_frames, ) ) if len(res_set) > 0: result_group = {} if reduce_group_name is not None: result_group["reduce_frames_name"] = reduce_group_name result_group["reduce_frames"] = res_set result.append(result_group) return tuple(result) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/control/scanselectorwidget.py0000644000175000017500000000200115143647637023045 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui.control.datalist import GenericScanList from tomwer.gui.dialog.QDataDialog import QDataDialog from .selectorwidgetbase import _SelectorWidget logger = logging.getLogger(__name__) class ScanSelectorWidget(_SelectorWidget): """Widget used to select a scan on a list""" def _buildDataList(self): return GenericScanList(parent=self) def n_scan(self) -> int: return super().n_data() def _callbackAddData(self): dialog = QDataDialog(self, multiSelection=True) if not dialog.exec(): dialog.close() return for folder in dialog.files_selected(): tomo_objs = self.add(folder) self.setMySelection(tomo_objs) self.sigUpdated.emit() def setActiveData(self, data): if isinstance(data, TomwerScanBase): data = data.path super().setActiveData(data) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1769073211.0 tomwer-1.6.17/src/tomwer/gui/control/selectorwidgetbase.py0000644000175000017500000001303715134365073023035 0ustar00paynopaynoimport logging from silx.gui import qt from tomwer.gui.utils.qt_utils import block_signals from tomwer.gui.control.actions import TomoObjDisplayModeToolButton from tomwer.gui.control.tomoobjdisplaymode import DisplayMode _logger = logging.getLogger(__name__) class _SelectorWidget(qt.QMainWindow): """widget used to select a dataset on a list (a scan or a volume for now)""" sigSelectionChanged = qt.Signal(list) """Signal emitted when the selection changed. List elements are tomo object identifier as str""" sigUpdated = qt.Signal() """signal emitted when the scan list change""" def __init__(self, parent=None): qt.QMainWindow.__init__(self, parent) # widget self._mainWidget = qt.QWidget(self) self._mainWidget.setLayout(qt.QVBoxLayout()) self.dataList = self._buildDataList() self.dataList.setSelectionMode(qt.QAbstractItemView.ExtendedSelection) self._mainWidget.layout().addWidget(self.dataList) self._mainWidget.layout().addWidget(self._getAddAndRmButtons()) self._mainWidget.layout().addWidget(self._getSendButtons()) self._mainWidget.setAcceptDrops(True) self.setAcceptDrops(True) self.setCentralWidget(self._mainWidget) # toolbar toolbar = qt.QToolBar() toolbar.setMovable(False) toolbar.setFloatable(False) self.addToolBar(qt.Qt.TopToolBarArea, toolbar) tomoObjDisplayAction = TomoObjDisplayModeToolButton(self) toolbar.addWidget(tomoObjDisplayAction) # set up self.setDisplayMode(DisplayMode.SHORT) # connect signal / slot # for drag / drop we need to have an indirect call to the sigUpdated self.dataList.listChanged.connect(self._updatedFromDragDrop) tomoObjDisplayAction.sigDisplayModeChanged.connect(self.setDisplayMode) def setDisplayMode(self, *args, **kwargs): self.dataList.setDisplayMode(*args, **kwargs) def _updatedFromDragDrop(self, *args, **kwargs): self.sigUpdated.emit() def add(self, scan): added_scans = self.dataList.add(scan) self.sigUpdated.emit() return added_scans def remove(self, scan): self.dataList.remove(scan) self.sigUpdated.emit() def n_data(self) -> int: return len(self.dataList.items) def _buildDataList(self): raise NotImplementedError("Base class") def _getAddAndRmButtons(self): lLayout = qt.QHBoxLayout() w = qt.QWidget(self) w.setLayout(lLayout) self._addButton = qt.QPushButton("Add") self._addButton.clicked.connect(self._callbackAddData) self._rmButton = qt.QPushButton("Remove") self._rmButton.clicked.connect(self._callbackRemoveSelectedDatasets) spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) lLayout.addWidget(spacer) lLayout.addWidget(self._addButton) lLayout.addWidget(self._rmButton) return w def _getSendButtons(self): layout = qt.QHBoxLayout() widget = qt.QWidget(self) widget.setLayout(layout) # select all button self._selectAllButton = qt.QPushButton("Select all") self._selectAllButton.setToolTip("Select all scan. (shortcut: Ctrl + A)") self._selectAllButton.clicked.connect(self.selectAll) layout.addWidget(self._selectAllButton) # horizontal spacer h_spacer = qt.QWidget(self) h_spacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) layout.addWidget(h_spacer) # send selected button self._sendButton = qt.QPushButton("Send selected") self._sendButton.clicked.connect(self._sendSelected) layout.addWidget(self._sendButton) return widget def selectAll(self): self.dataList.selectAll() def setMySelection(self, selection: tuple): self.dataList.setMySelection(selection) def _callbackAddData(self): raise NotImplementedError("Base class") def _sendSelected(self): sItem = self.dataList.selectedItems() if sItem and len(sItem) >= 1: selection = [ _item.data(qt.Qt.UserRole).get_identifier().to_str() for _item in sItem ] self.sigSelectionChanged.emit(list(selection)) else: _logger.warning("No active scan detected") def _sendAll(self): allItems = list(self.dataList._myitems.keys()) if len(allItems) > 0: self.sigSelectionChanged.emit(allItems) def _callbackRemoveSelectedDatasets(self): """ """ selected_items = self.dataList.selectedItems() tomwer_objs_to_remove = [ item.data(qt.Qt.UserRole).get_identifier().to_str() for item in selected_items ] for tomwer_obj in tomwer_objs_to_remove: self.remove(tomwer_obj) self.sigUpdated.emit() def setActiveData(self, data): """ set the given scan as the active one :param scan: the scan to set active """ data_id = data self.dataList.setCurrentItem(self.dataList.items[data_id]) def removeSelectedDatasets(self): sItem = self.dataList.selectedItems() selection = [ _item.data(qt.Qt.UserRole).get_identifier().to_str() for _item in sItem ] with block_signals(self): # make sure sigUpdated is called only once. for identifier in selection: self.remove(identifier) self.sigUpdated.emit() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9331014 tomwer-1.6.17/src/tomwer/gui/control/series/0000755000175000017500000000000015153325403020064 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/control/series/__init__.py0000644000175000017500000000000014757047403022175 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/control/series/nxtomoconcatenate.py0000644000175000017500000000607314757047403024207 0ustar00paynopaynofrom silx.gui import qt class NXtomoConcatenateWidget(qt.QWidget): """ Widget to define setting of a concatenation of NXtomo. User need to provide entry name (data_path), output file path (a default option is possible) and if they want to overwrite any existing file / entry if necessary """ sigConfigChanged = qt.Signal() """Emitted on configuration modifications""" class OutputWidget(qt.QWidget): def __init__(self, parent=None, *args, **kwargs) -> None: super().__init__(parent, *args, **kwargs) self.setLayout(qt.QFormLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self._outputFilePathQLE = qt.QLineEdit("{common_path}/concatenate.nx", self) self._outputFilePathQLE.setToolTip( """location of the concatenation. Possible keywords are: \n - 'common_path': common path of all the scans to concatenate """ ) self.layout().addRow("output file path", self._outputFilePathQLE) self._outputDataPathQLE = qt.QLineEdit("entry0000", self) self.layout().addRow("output entry", self._outputDataPathQLE) def __init__(self, parent=None, *args, **kwargs): super().__init__(parent=parent, *args, **kwargs) self.setLayout(qt.QVBoxLayout()) # output widget self._outputWidget = self.OutputWidget(parent=self) self.layout().addWidget(self._outputWidget) # overwrite option self._overwriteCB = qt.QCheckBox("overwrite", parent) self.layout().addWidget(self._overwriteCB) # spacer spacer = qt.QWidget(parent=self) spacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer) # conenct signal / slot self._outputWidget._outputFilePathQLE.textEdited.connect(self._changed) self._outputWidget._outputDataPathQLE.textEdited.connect(self._changed) self._overwriteCB.toggled.connect(self._changed) def _changed(self, *args, **kwargs): self.sigConfigChanged.emit() def getConfiguration(self) -> dict: return { "overwrite": self._overwriteCB.isChecked(), "output_file": self.getOutputFilePath(), "output_entry": self.getOutputEntry(), } def setConfiguration(self, config: dict) -> None: overwrite = config.get("overwrite", None) if overwrite is not None: self._overwriteCB.setChecked(overwrite in (True, "True", "1", "true")) output_file = config.get("output_file", None) if output_file is not None: self._outputWidget._outputFilePathQLE.setText(output_file) output_entry = config.get("output_entry", None) if output_entry is not None: self._outputWidget._outputDataPathQLE.setText(output_entry) # expose API def getOutputFilePath(self) -> str: return self._outputWidget._outputFilePathQLE.text() def getOutputEntry(self) -> str: return self._outputWidget._outputDataPathQLE.text() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/control/series/seriescreator.py0000644000175000017500000010252215143647637023331 0ustar00paynopaynofrom __future__ import annotations import logging from contextlib import AbstractContextManager from typing import Iterable from silx.gui import qt from silx.gui.utils import blockSignals from enum import Enum as _Enum from tomoscan.series import Series from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.tomwer_object import TomwerObject from tomwer.core.volume.volumefactory import VolumeFactory from tomwer.gui.control.datalist import TomoObjList from tomwer.gui.dialog.QDataDialog import QDataDialog from tomwer.gui.visualization.tomoobjoverview import TomoObjOverview _logger = logging.getLogger(__name__) class SeriesWidgetDialog(qt.QDialog): sigSeriesSelected = qt.Signal(Series) """ emit when a series is selected / triggered by the user """ def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.setLayout(qt.QVBoxLayout()) # add list self._widget = SeriesWidget() self.layout().addWidget(self._widget) # add buttons self._buttons = qt.QDialogButtonBox(parent=self) self._selectButton = qt.QPushButton("Select (active) series", parent=self) self._buttons.addButton(self._selectButton, qt.QDialogButtonBox.ActionRole) self.layout().addWidget(self._buttons) # connect signal / slot self._selectButton.released.connect(self._seriesSelected) def getSelectedSeries(self) -> Series | None: return self._widget.getSelectedSeries() def _seriesSelected(self, *args, **kwargs): series = self.getSelectedSeries() if series is not None: self.sigSeriesSelected.emit(series) # expose API def add(self, tomo_obj): self._widget.add(tomo_obj=tomo_obj) class SeriesWidget(qt.QTabWidget): sigCurrentSeriesChanged = qt.Signal() """signal emit when the current series changes""" sigHistoryChanged = qt.Signal() """signal emit when the history changed (a series has been added or removed""" sigSeriesSend = qt.Signal(Series) """Signal emit when a series has been send""" _HISTORY_MODE = "history" _DEFINITION_MODE = "series definition" def __init__(self, parent=None) -> None: super().__init__(parent) self.setWindowTitle("series of scans") self._seriesDefinitionWidget = SeriesDefinition(parent=self) self.addTab(self._seriesDefinitionWidget, self._DEFINITION_MODE) self._historyWidget = SeriesHistoryDialog(parent=self) self._historyWidget.setWindowFlags(qt.Qt.Widget) self.addTab(self._historyWidget, self._HISTORY_MODE) # connect signal / slot self._historyWidget.sigEditSeries.connect(self._seriesEditionRequested) self._historyWidget.sigSeriesSend.connect(self.sigSeriesSend) self._historyWidget.sigHistoryUpdated.connect(self._repeatHistoryUpdated) self._seriesDefinitionWidget.sigSeriesChanged.connect(self._repeatSeriesChanged) self._seriesDefinitionWidget.sigSeriesSend.connect(self.sigSeriesSend) self._seriesDefinitionWidget.sigSeriesSend.connect( self._historyWidget.addSeries ) def getHistoryWidget(self): return self._historyWidget def getDefinitionWidget(self): return self._seriesDefinitionWidget def getSelectedSeries(self) -> Series | None: return self._seriesDefinitionWidget.getSelectedSeries() def setMode(self, mode: str, definition_mode: str | None = None): valid_modes = (self._HISTORY_MODE, self._DEFINITION_MODE) if mode == self._HISTORY_MODE: self.setCurrentWidget(self._historyWidget) elif mode == self._DEFINITION_MODE: self.setCurrentWidget(self._seriesDefinitionWidget) self._seriesDefinitionWidget.setMode(definition_mode) else: raise ValueError( f"mode {mode} is no recognized. Valid modes are {valid_modes}" ) def _seriesEditionRequested(self, series: Series): if not isinstance(series, Series): raise TypeError(f"series is expected to be a series not {type(series)}") self.setMode("series definition", "manual") self.getDefinitionWidget().getManualDefinitionWidget().setSeries(series) def _repeatSeriesChanged(self, *args, **kwargs): self.sigCurrentSeriesChanged.emit() def _repeatHistoryUpdated(self, *args, **kwargs): self.sigHistoryChanged.emit() def add(self, tomo_obj): return self._seriesDefinitionWidget.addTomoObj(tomo_obj) class _SeriesDefinitionMode(_Enum): MANUAL = "manual" AUTO = "auto" class SeriesDefinition(qt.QWidget): sigSeriesChanged = qt.Signal() """signal emit when a the series defined manually changed""" sigSeriesSend = qt.Signal(Series) """Signal emited when a series has been send""" def __init__(self, parent=None) -> None: super().__init__(parent) self.setLayout(qt.QGridLayout()) self._modeLabel = qt.QLabel("Mode", self) self.layout().addWidget(self._modeLabel, 0, 0, 1, 1) self._modeCB = qt.QComboBox(self) for mode in _SeriesDefinitionMode: self._modeCB.addItem(mode.value) self.layout().addWidget(self._modeCB, 0, 1, 1, 1) self._manualDefWidget = SeriesManualFromTomoObj(parent=self) self.layout().addWidget(self._manualDefWidget, 1, 0, 1, 2) self._manualDefWidget.setWindowFlags(qt.Qt.Widget) self._automaticDefWidget = SeriesAutomaticDefinitionWidget(parent=self) self.layout().addWidget(self._automaticDefWidget, 2, 0, 1, 2) # connect signal / slot self._modeCB.currentIndexChanged.connect(self._updateVisibility) self._manualDefWidget._newSeriesWidget.sigUpdated.connect(self.sigSeriesChanged) # set up self._updateVisibility() def getSelectedSeries(self) -> Series | None: if self.getMode() == _SeriesDefinitionMode.MANUAL: return self._manualDefWidget.getSeries() else: raise ValueError(f"mode {self.getMode()} is not handled yet") def getMode(self) -> str: return _SeriesDefinitionMode(self._modeCB.currentText()) def setMode(self, mode: str): mode = _SeriesDefinitionMode(mode) idx = self._modeCB.findText(mode.value) self._modeCB.setCurrentIndex(idx) def _updateVisibility(self): self._manualDefWidget.setVisible(self.getMode() == _SeriesDefinitionMode.MANUAL) self._automaticDefWidget.setVisible( self.getMode() == _SeriesDefinitionMode.AUTO ) def getManualDefinitionWidget(self): return self._manualDefWidget def getAutoDefinitionWidget(self): return self._automaticDefWidget def createManualSeries(self): self._manualDefWidget.createSeries() def addTomoObj(self, tomo_obj: TomwerObject): self._manualDefWidget.addTomoObj(tomo_obj=tomo_obj) def setSeriesName(self, name: str): self._manualDefWidget.setSeriesName(name=name) class _SeriesDefinitionTree(qt.QWidget): """ Tree used to define manually series of scan. Drag and drop of files is handled """ sigUpdated = qt.Signal() """Signal emit when the series is updated""" class SignalBlocker(AbstractContextManager): """Simple context manager to hide / show button dialogs""" def __init__(self, serie_definition_widget) -> None: super().__init__() self.serie_definition_widget = serie_definition_widget def __enter__(self): self.old_widget = self.serie_definition_widget.blockSignals(True) self.old_tree = self.serie_definition_widget._tree.blockSignals(True) def __exit__(self, exc_type, exc_val, exc_tb): self.serie_definition_widget.blockSignals(self.old_widget) self.serie_definition_widget._tree.blockSignals(self.old_tree) def __init__(self, parent=None, serie_name="my_serie") -> None: self._tomo_objs = {} # associated serie name (key) to tuple (serie, QTreeWidgetItem) super().__init__(parent) self.setLayout(qt.QVBoxLayout()) self._tree = qt.QTreeWidget(self) self._tree.setSelectionMode(qt.QAbstractItemView.MultiSelection) self._tree.setColumnCount(2) self._tree.setHeaderLabels(("series", "scan ids")) self._tree.setItemsExpandable(False) self.layout().addWidget(self._tree) # set up the tree with the serie name that will stay during the entire # life time of the tree self._seriesItem = qt.QTreeWidgetItem(self._tree) self._seriesItem.setFlags(self._seriesItem.flags() | qt.Qt.ItemIsEditable) self._seriesItem.setExpanded(True) self.setAcceptDrops(True) # connect signal / slot self._tree.itemChanged.connect(self._updated) # set up self.setSeriesName(name=serie_name) # expose API self.itemChanged = self._tree.itemChanged @property def rootItem(self): return self._seriesItem def setSeriesName(self, name: str): with self.SignalBlocker(self): self._seriesItem.setText(0, name) self.sigUpdated.emit() def getSeriesName(self): return self._seriesItem.text(0) def addTomoObj(self, tomo_obj: TomwerObject): if not isinstance(tomo_obj, TomwerObject): raise TypeError( f"{tomo_obj} is expected to be an instance of {TomwerObject} not {type(tomo_obj)}" ) identifier = tomo_obj.get_identifier().to_str() if identifier in self._tomo_objs: _logger.warning(f"scan {identifier} already part of the serie") return with self.SignalBlocker(self): tomo_obj_item = qt.QTreeWidgetItem(self.rootItem) tomo_obj_item.setText(1, identifier) tomo_obj_item.setFlags(tomo_obj_item.flags() | qt.Qt.ItemIsUserCheckable) self._tomo_objs[identifier] = (tomo_obj, tomo_obj_item) self.sigUpdated.emit() def removeTomoObj(self, tomo_obj: TomwerObject): if not isinstance(tomo_obj, TomwerObject): raise TypeError( f"{tomo_obj} is expected to be an instance of {TomwerObject} not {type(tomo_obj)}" ) with self.SignalBlocker(self): identifier = tomo_obj.get_identifier().to_str() if identifier not in self._tomo_objs: _logger.warning(f"{identifier} is not in the serie") else: _, tomo_obj_item = self._tomo_objs.pop(identifier) root = self._tree.invisibleRootItem() root.removeChild(tomo_obj_item) self.sigUpdated.emit() @property def n_tomo_objs(self): return len(self._tomo_objs) def setSeries(self, series: Series) -> None: if not isinstance(series, Series): raise TypeError( f"serie is expected to be an instance of {Series} not {type(series)}" ) with self.SignalBlocker(self): self.clearTomoObjs() self.setSeriesName(series.name) for tomo_obj in series: if isinstance(tomo_obj, str): try: tomo_obj = ScanFactory.create_tomo_object_from_identifier( identifier=tomo_obj ) except Exception: try: tomo_obj = VolumeFactory.create_tomo_object_from_identifier( identifier=tomo_obj ) except Exception: _logger.warning(f"Fail to recreate scan from {tomo_obj}.") return elif not isinstance(tomo_obj, TomwerObject): raise TypeError( f"tomo_obj is expected to be an instance of {TomwerObject}. Not {type(tomo_obj)}" ) self.addTomoObj(tomo_obj) self.sigUpdated.emit() def getSeries(self, use_identifiers=False) -> Series: scans = [scan for scan, _ in self._tomo_objs.values()] return Series( name=self.getSeriesName(), iterable=scans, use_identifiers=use_identifiers, ) def clearTomoObjs(self): with self.SignalBlocker(self): keys = list(self._tomo_objs.keys()) for key in keys: _, scan_item = self._tomo_objs.pop(key) root = self._tree.invisibleRootItem() root.removeChild(scan_item) self.sigUpdated.emit() def setSelectedTomoObjs(self, objs): self.clearSelection() for scan in objs: scan_item = self._getTomoObjItem(scan) if scan_item is not None: scan_item.setSelected(True) def _getTomoObjItem(self, tomo_obj: TomwerObject) -> qt.QTreeWidgetItem | None: if not isinstance(tomo_obj, TomwerObject): raise TypeError( f"scan is expected to be an instance of {TomwerObject} not {type(tomo_obj)}" ) return self._tomo_objs.get(tomo_obj.get_identifier().to_str(), (None, None))[1] def getSelectedTomoObjs(self) -> tuple(): """return selected scans""" selected = [] for _, (scan, item) in self._tomo_objs.items(): if item.isSelected(): selected.append(scan) return tuple(selected) def removeSelectedTomoObjs(self) -> None: with self.SignalBlocker(self): for tomo_obj in self.getSelectedTomoObjs(): self.removeTomoObj(tomo_obj) def _updated(self, *args, **kwargs): self.sigUpdated.emit() def clearSelection(self) -> None: self._tree.selectionModel().clearSelection() def addScanFromNxFile(self, file_: str, entry: str | None = None): try: if entry is None: scans = ScanFactory.create_scan_objects(scan_path=file_) else: scans = [ScanFactory.create_scan_object(scan_path=file_, entry=entry)] except Exception as e: _logger.error(f"cannot create scan instances from {file_}. Error is {e}") else: changed = False with self.SignalBlocker(self): for scan in scans: if scan is not None: try: self.addTomoObj(tomo_obj=scan) except TypeError: _logger.error( f"fail to add scan {scan}. Invalid type encountered ({type(scan)})" ) else: changed = True if changed: self.sigUpdated.emit() def dropEvent(self, event): if event.mimeData().hasFormat("text/uri-list"): for url in event.mimeData().urls(): self.addScanFromNxFile(file_=str(url.path()), entry=None) def supportedDropActions(self): """Inherited method to redefine supported drop actions.""" return qt.Qt.CopyAction | qt.Qt.MoveAction def dragEnterEvent(self, event): if event.mimeData().hasFormat("text/uri-list"): event.accept() event.setDropAction(qt.Qt.CopyAction) else: qt.QListWidget.dragEnterEvent(self, event) def dragMoveEvent(self, event): if event.mimeData().hasFormat("text/uri-list"): event.setDropAction(qt.Qt.CopyAction) event.accept() else: qt.QListWidget.dragMoveEvent(self, event) class SeriesManualControlDialog(qt.QDialog): """ Same as the :class:`SeriesManualDefinitionDialog` but with control of the serie. This include a `create series` and a `create series and clear button` """ sigSeriesSend = qt.Signal(Series) """Signal emit when a series has been send""" def __init__(self, parent=None) -> None: super().__init__(parent) self.setLayout(qt.QVBoxLayout()) self._mainWidget = SeriesManualDefinitionDialog(parent=self) self._mainWidget.setWindowFlags(qt.Qt.Widget) self.layout().addWidget(self._mainWidget) self._buttons = qt.QDialogButtonBox(parent=self) self._createButton = qt.QPushButton("create serie", parent=self) self._buttons.addButton(self._createButton, qt.QDialogButtonBox.ActionRole) # connect signal / slot self._createButton.clicked.connect(self._sendSeries) self.layout().addWidget(self._buttons) # expose API self.sigUpdated = self._mainWidget.sigUpdated def _sendSeries(self): self.sigSeriesSend.emit(self._mainWidget.getSeries()) @property def n_tomo_objs(self): return self._mainWidget.n_tomo_objs def setSeriesName(self, name: str): self._mainWidget.setSeriesName(name=name) def getSeriesName(self) -> str: return self._mainWidget.getSeriesName() def setSeries(self, series: Series) -> None: self._mainWidget.setSeries(series) def getSeries(self, *args, **kwargs) -> Series: return self._mainWidget.getSeries(*args, **kwargs) def addScanFromNxFile(self, file_: str, entry: str | None = None): return self._mainWidget.addScanFromNxFile(file_=file_, entry=entry) def removeSelectedScans(self) -> None: return self._mainWidget.removeSelectedTomoObjs() def getSelectedScans(self) -> tuple: return self._mainWidget.getSelectedTomoObjs() def setSelectedScans(self, scans: Iterable) -> None: self._mainWidget.setSelectedTomoObjs(scans=scans) def addScan(self, scan: TomwerScanBase) -> None: self._mainWidget.addTomoObj(scan=scan) def removeScan(self, scan: TomwerScanBase) -> None: self._mainWidget.removeTomoObj(scan=scan) def clearSeries(self) -> None: self._mainWidget.clearSeries() def createSeries(self): self.sigSeriesSend.emit(self.getSeries()) class SeriesManualFromTomoObj(qt.QWidget): def __init__(self, parent=None) -> None: super().__init__(parent) style = qt.QApplication.style() self.setLayout(qt.QGridLayout()) # tomo objs list self._tomoObjList = TomoObjList(self) self._tomoObjList.setSizePolicy( qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding ) self._tomoObjListScrollArea = qt.QScrollArea(self) self._tomoObjListScrollArea.setWidgetResizable(True) self._tomoObjListScrollArea.setWidget(self._tomoObjList) self.layout().addWidget(self._tomoObjListScrollArea, 0, 0, 4, 2) # right arrow self._rightArrowButton = qt.QPushButton(self) rightArrowIcon = style.standardIcon(qt.QStyle.SP_ArrowRight) self._rightArrowButton.setIcon(rightArrowIcon) self._rightArrowButton.setFixedWidth(30) self.layout().addWidget(self._rightArrowButton, 1, 2, 1, 1) # left arrow self._leftArrowButton = qt.QPushButton(self) leftArrowIcon = style.standardIcon(qt.QStyle.SP_ArrowLeft) self._leftArrowButton.setIcon(leftArrowIcon) self._leftArrowButton.setFixedWidth(30) self.layout().addWidget(self._leftArrowButton, 2, 2, 1, 1) # new series self._newSeriesWidget = NewSeriesWidget(self) self._newSerieWidgetScrollArea = qt.QScrollArea(self) self._newSerieWidgetScrollArea.setWidgetResizable(True) self._newSerieWidgetScrollArea.setWidget(self._newSeriesWidget) self.layout().addWidget(self._newSerieWidgetScrollArea, 0, 3, 4, 2) # tomo obj details self._tomoObjInfos = TomoObjOverview(self) self._tomoObjInfos.setContentsMargins(0, 0, 0, 0) self.layout().addWidget(self._tomoObjInfos, 4, 0, 2, 2) # connect signals / slot self._leftArrowButton.released.connect(self._removeSelectedObjs) self._rightArrowButton.released.connect(self._addSelectedObjs) self._tomoObjList.selectionModel().selectionChanged.connect( self._updateTomoObjInfos ) def selectedTomoObjects(self) -> tuple: """ :return: tuple of tomo object selected on the list """ items = self._tomoObjList.selectedItems() return [item.data(qt.Qt.UserRole) for item in items] def _removeSelectedObjs(self, *args, **kwargs): for tomo_obj in self.selectedTomoObjects(): self._newSeriesWidget.removeTomoObjToCurrentSeries(tomo_obj) def _addSelectedObjs(self, *args, **kwargs): for tomo_obj in self.selectedTomoObjects(): self._newSeriesWidget.addTomoObjToCurrentSeries(tomo_obj) def _updateTomoObjInfos(self, *args, **kwargs): # should select_objs = self._tomoObjList.selectedItems() if select_objs and len(select_objs) > 0: tomo_obj = select_objs[0].data(qt.Qt.UserRole) self._tomoObjInfos.setTomoObj(tomo_obj) else: self._tomoObjInfos.setTomoObj(None) # expose API def setSeries(self, series: Series): self._newSeriesWidget.setSeries(series=series) def getSeries(self, *args, **kwargs) -> Series: return self._newSeriesWidget.getSeries(*args, **kwargs) def addTomoObj(self, tomo_obj): self._tomoObjList.add(tomo_obj) def addToCurrentSeries(self, tomo_obj): self._newSeriesWidget.addTomoObjToCurrentSeries(tomo_obj) def setSeriesName(self, name: str): self._newSeriesWidget.setSeriesName(name=name) class NewSeriesWidget(qt.QWidget): sigNameChanged = qt.Signal() """Emit when serie name changed""" sigUpdated = qt.Signal() """ Emit when the serie has been updated by the tree """ DEFAULT_SERIES_NAME = "my_series" def __init__(self, parent=None) -> None: super().__init__(parent) self.setLayout(qt.QVBoxLayout()) self._nameWidget = qt.QWidget(self) self._nameWidget.setLayout(qt.QHBoxLayout()) self._nameWidget.layout().addWidget(qt.QLabel("series name", self)) self._nameQLE = qt.QLineEdit(self.DEFAULT_SERIES_NAME, self) self._nameWidget.layout().addWidget(self._nameQLE) self.layout().addWidget(self._nameWidget) self._serieTree = _SeriesDefinitionTree( self, serie_name=self.DEFAULT_SERIES_NAME ) self.layout().addWidget(self._serieTree) # Signal / slot connection self._serieTree.itemChanged.connect(self._handleItemUpdate) self._serieTree.sigUpdated.connect(self.sigUpdated) self._nameQLE.textChanged.connect(self._nameChangedOnQLE) def setSeries(self, series: Series) -> None: with blockSignals(self._nameQLE): self._nameQLE.setText(series.name) self._serieTree.setSeries(series=series) def getSeries(self, *args, **kwargs) -> Series: return self._serieTree.getSeries(*args, **kwargs) def _nameChangedOnQLE(self, name): with blockSignals(self._serieTree): self._serieTree.setSeriesName(name) self.sigNameChanged.emit() def _handleItemUpdate(self, item, column): if item == self._serieTree.rootItem: old = self.blockSignals(True) self._nameQLE.setText(self._serieTree.rootItem.text(0)) self.blockSignals(old) self.sigUpdated.emit() def addTomoObjToCurrentSeries(self, tomo_obj: TomwerObject): assert isinstance( tomo_obj, TomwerObject ), f"invalid type {type(tomo_obj)}. {TomwerObject} expected" self._serieTree.addTomoObj(tomo_obj) def removeTomoObjToCurrentSeries(self, tomo_obj: TomwerObject): assert isinstance( tomo_obj, TomwerObject ), f"invalid type {type(tomo_obj)}. {TomwerObject} expected" self._serieTree.removeTomoObj(tomo_obj) def getSeriesName(self) -> str: return self._serieTree.getSeriesName() def setSeriesName(self, name: str): self._serieTree.setSeriesName(name=name) class SeriesManualDefinitionDialog(qt.QDialog): """Dialog to define a serie manually""" sigUpdated = qt.Signal() """emit when serie is updated""" def __init__(self, parent=None) -> None: super().__init__(parent) self.setLayout(qt.QVBoxLayout()) self._newSeriesWidget = NewSeriesWidget(self) self._buttons = qt.QDialogButtonBox(parent=self) self._addScanButton = qt.QPushButton("Add scan to the serie", parent=self) self._buttons.addButton(self._addScanButton, qt.QDialogButtonBox.ActionRole) self._removeSelectedButton = qt.QPushButton( "Remove selected scans", parent=self ) self._buttons.addButton( self._removeSelectedButton, qt.QDialogButtonBox.ActionRole ) self._clearButton = qt.QPushButton("Clear", parent=self) self._buttons.addButton(self._clearButton, qt.QDialogButtonBox.ActionRole) self.layout().addWidget(self._buttons) # connect signal / slot self._newSeriesWidget.sigNameChanged.connect(self._nameChanged) self._newSeriesWidget.sigUpdated.connect(self.sigUpdated) self._addScanButton.clicked.connect(self.addScanFromFileDialog) self._removeSelectedButton.clicked.connect(self.removeSelectedTomoObjs) self._clearButton.clicked.connect(self.clearSeries) @property def n_tomo_objs(self): serieTree = self._newSeriesWidget._serieTree return serieTree.n_tomo_objs def _nameChanged(self, new_name): serieTree = self._newSeriesWidget._serieTree with blockSignals(self._serieTree): serieTree.setSeriesName(name=new_name) self.sigUpdated.emit() def setSeriesName(self, name: str): self._newSeriesWidget.setSeriesName(name=name) def getSeriesName(self) -> str: return self._newSeriesWidget.getSeriesName() def setSeries(self, series: Series) -> None: self._newSeriesWidget.setSeries(series) def getSeries(self, *args, **kwargs) -> Series: return self._newSeriesWidget.getSeries(*args, **kwargs) def addScanFromFileDialog(self) -> None: dialog = QDataDialog(self, multiSelection=True) if not dialog.exec(): dialog.close() return foldersSelected = dialog.files_selected() for folder in foldersSelected: self.addScanFromNxFile(file_=folder, entry=None) def addScanFromNxFile(self, file_: str, entry: str | None = None): serieTree = self._newSeriesWidget._serieTree return serieTree.addScanFromNxFile(file_=file_, entry=entry) def removeSelectedTomoObjs(self) -> None: serieTree = self._newSeriesWidget._serieTree return serieTree.removeSelectedTomoObjs() def getSelectedTomoObjs(self) -> tuple: serieTree = self._newSeriesWidget._serieTree return serieTree.getSelectedTomoObjs() def setSelectedTomoObjs(self, scans: Iterable) -> None: serieTree = self._newSeriesWidget._serieTree serieTree.setSelectedTomoObjs(objs=scans) def addTomoObj(self, scan: TomwerScanBase) -> None: serieTree = self._newSeriesWidget._serieTree return serieTree.addTomoObj(tomo_obj=scan) def removeTomoObj(self, scan: TomwerScanBase) -> None: serieTree = self._newSeriesWidget._serieTree serieTree.removeTomoObj(tomo_obj=scan) def clearSeries(self) -> None: serieTree = self._newSeriesWidget._serieTree serieTree.clearTomoObjs() class SeriesAutomaticDefinitionWidget(qt.QWidget): pass class SeriesTree(qt.QWidget): """ Widget used to define a scan series from a list of scans. """ def __init__(self, parent=None, scans=tuple()) -> None: self._series = {} # associated series name (key) to tuple (series, QTreeWidgetItem) super().__init__(parent) self.setLayout(qt.QVBoxLayout()) self._tree = qt.QTreeWidget(self) self._tree.setSelectionMode(qt.QAbstractItemView.MultiSelection) self._tree.setColumnCount(2) self._tree.setHeaderLabels(("series", "scan ids")) self.layout().addWidget(self._tree) # set up [self.addSeries(scan) for scan in scans] def addSeries(self, series: Series): if not isinstance(series, Series): raise TypeError( f"{series} is expected to be an instance of {Series} not {type(series)}" ) if series.name in self._series: self.removeSeries(self._series[series.name][0]) root_item = qt.QTreeWidgetItem(self._tree) root_item.setText(0, series.name) self._series[series.name] = (series, root_item) for obj in series: scan_item = qt.QTreeWidgetItem(root_item) if isinstance(obj, TomwerObject): text = obj.get_identifier().to_str() else: text = obj scan_item.setText(1, text) scan_item.setFlags(qt.Qt.NoItemFlags) def removeSeries(self, series: Series): if not isinstance(series, Series): raise TypeError( f"{series} is expected to be an instance of {Series} not {type(series)}" ) if series.name in self._series: _, serie_item = self._series.pop(series.name) root = self._tree.invisibleRootItem() root.removeChild(serie_item) @property def n_series(self): return len(self._series) def series(self) -> tuple: series = [] [series.append(serie) for serie, _ in self._series.values()] return tuple(series) def clearSelection(self): self._tree.selectionModel().clearSelection() def setSelectedSeries(self, series): self.clearSelection() for serie in series: serie_item = self._getSeriesItem(serie) if serie_item is not None: serie_item.setSelected(True) def _getSeriesItem(self, series: Series) -> qt.QTreeWidgetItem | None: if not isinstance(series, Series): raise TypeError( f"serie is expected to be an instance of {Series} not {type(series)}" ) return self._series.get(series.name, (None, None))[1] def getSelectedSeries(self) -> tuple(): """return selected series""" selected = [] for _, (series, item) in self._series.items(): if item.isSelected(): selected.append(series) return tuple(selected) def removeSelected(self) -> None: for series in self.getSelectedSeries(): self.removeSeries(series) class SeriesHistoryDialog(qt.QDialog): sigSeriesSend = qt.Signal(Series) """signal emit when a serie has been selected by the user""" sigEditSeries = qt.Signal(Series) """Signal emit when user request to edit a serie""" sigHistoryUpdated = qt.Signal() """Signal emit when the history has been modified""" def __init__(self, parent=None) -> None: super().__init__(parent) self.setLayout(qt.QVBoxLayout()) self._serieList = SeriesTree(self) self.layout().addWidget(self._serieList) self._buttons = qt.QDialogButtonBox(parent=self) self._editButton = qt.QPushButton("Edit", parent=self) self._buttons.addButton(self._editButton, qt.QDialogButtonBox.ActionRole) self._sendButton = qt.QPushButton("Resend", parent=self) self._buttons.addButton(self._sendButton, qt.QDialogButtonBox.ActionRole) self._removeButton = qt.QPushButton("Remove", parent=self) self._buttons.addButton(self._removeButton, qt.QDialogButtonBox.ActionRole) self._clearButton = qt.QPushButton("Clear", parent=self) self._buttons.addButton(self._clearButton, qt.QDialogButtonBox.ActionRole) self.layout().addWidget(self._buttons) # connect signal / slot self._sendButton.clicked.connect(self.sendSelected) self._removeButton.clicked.connect(self.removeSelected) self._clearButton.clicked.connect(self.clearSelection) self._editButton.clicked.connect(self.editSelected) def addSeries(self, serie: Series): old = self.blockSignals(True) self._serieList.addSeries(serie) self.blockSignals(old) self.sigHistoryUpdated.emit() def removeSeries(self, serie: Series): old = self.blockSignals(True) self._serieList.removeSeries(serie) self.blockSignals(old) self.sigHistoryUpdated.emit() def getSelectedSeries(self): return self._serieList.getSelectedSeries() def setSelectedSeries(self, series): old = self.blockSignals(True) self._serieList.setSelectedSeries(series) self.blockSignals(old) self.sigHistoryUpdated.emit() def sendSelected(self): for serie in self.getSelectedSeries(): self.sigSeriesSend.emit(serie) def editSelected(self): selected = self.getSelectedSeries() if len(selected) == 0: return if len(selected) > 1: _logger.warning( "more than one serie selected for edition. Will only edit the first one" ) self.sigEditSeries.emit(selected[0]) def removeSelected(self): old = self.blockSignals(True) self._serieList.removeSelected() self.blockSignals(old) self.sigHistoryUpdated.emit() def clearSelection(self): self._serieList.clearSelection() def series(self) -> tuple: return self._serieList.series() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/control/series/serieswaiter.py0000644000175000017500000000000014757047403023144 0ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9331014 tomwer-1.6.17/src/tomwer/gui/control/series/test/0000755000175000017500000000000015153325403021043 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/control/series/test/test_creator.py0000644000175000017500000003413714757047403024135 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import shutil import tempfile from silx.gui import qt from silx.gui.utils.testutils import SignalListener, TestCaseQt from tomoscan.series import Series from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.utils.scanutils import MockEDF, MockNXtomo from tomwer.core.volume.hdf5volume import HDF5Volume from tomwer.gui.control.series.seriescreator import ( SeriesDefinition, SeriesHistoryDialog, SeriesManualControlDialog, SeriesManualFromTomoObj, SeriesTree, SeriesWidget, ) class _MockScanBase: def init(self): n_hdf5_scan = 11 self._scans = [] self._root_dir = tempfile.mkdtemp() for i_scan in range(n_hdf5_scan): scan_path = os.path.join(self._root_dir, f"scan_{i_scan}") scan = MockNXtomo(scan_path=scan_path, n_proj=10, n_ini_proj=0).scan self._scans.append(scan) n_edf_scan = 4 for i_scan in range(n_edf_scan): scan_path = os.path.join(self._root_dir, f"scan_{i_scan}") scan = MockEDF.mockScan( scanID=scan_path, nRadio=10, dim=10, ) self._scans.append(scan) def close(self): shutil.rmtree(self._root_dir) class _MockSeriesBase(_MockScanBase): def init(self): super().init() self._seriesList = [ Series("series1", self._scans[0:1], use_identifiers=True), Series("series2", self._scans[1:5], use_identifiers=False), Series("series3", self._scans[5:11], use_identifiers=True), Series("series4", self._scans[8:11], use_identifiers=True), Series("series5", self._scans[-2:-1], use_identifiers=False), Series("series6", self._scans[-5:], use_identifiers=True), ] def close(self): self._seriesList.clear() super().close() class TestSeriesTree(TestCaseQt, _MockSeriesBase): """Test the SeriesTree widget""" def setUp(self): super().setUp() super().init() self._widget = SeriesTree() def tearDown(self): self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None super().close() super().tearDown() def test_add_remove(self): """Test adding and removing series""" self._widget.show() self.qWaitForWindowExposed(self._widget) for series in self._seriesList: self._widget.addSeries(series) assert self._widget.n_series == 6 self._widget.removeSeries(self._seriesList[3]) assert self._widget.n_series == 5 self._widget.removeSeries(self._seriesList[2]) self._widget.removeSeries(self._seriesList[1]) self._widget.removeSeries(self._seriesList[0]) # make sure no error is raised if we try to remove twine the same serie self._widget.removeSeries(self._seriesList[0]) assert self._widget.n_series == 2 self._widget.addSeries(self._seriesList[1]) self._widget.addSeries(self._seriesList[2]) assert self._widget.n_series == 4 def test_selection(self): """Test selection of the SerieTree""" self._widget.show() self.qWaitForWindowExposed(self._widget) for series in self._seriesList: self._widget.addSeries(series) selection = (self._seriesList[2], self._seriesList[3]) self._widget.setSelectedSeries(selection) assert self._widget.getSelectedSeries() == selection self._widget.clearSelection() assert self._widget.getSelectedSeries() == () class TestSeriesHistoryDialog(TestCaseQt, _MockSeriesBase): """Test the SeriesHistoryDialog""" def setUp(self): super().setUp() super().init() self._widget = SeriesHistoryDialog() # create listener for the nabu widget self.signal_listener = SignalListener() # connect signal / slot self._widget.sigSeriesSend.connect(self.signal_listener) def tearDown(self): self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None super().close() super().tearDown() def test(self): self._widget.show() self.qWaitForWindowExposed(self._widget) for series in self._seriesList: self._widget.addSeries(series) selection = (self._seriesList[0], self._seriesList[4]) self._widget.setSelectedSeries(selection) assert self._widget.getSelectedSeries() == selection assert self.signal_listener.callCount() == 0 self._widget._sendButton.clicked.emit() self.qapp.processEvents() assert self.signal_listener.callCount() == 2 assert self._widget.getSelectedSeries() == selection self.signal_listener.clear() self._widget._clearButton.clicked.emit() assert self._widget.getSelectedSeries() == () assert self.signal_listener.callCount() == 0 self._widget._sendButton.clicked.emit() assert self.signal_listener.callCount() == 0 class TestSeriesDefinition(TestCaseQt): def setUp(self): super().setUp() self._widget = SeriesDefinition() def tearDown(self): self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None super().tearDown() def test_manual_selection(self): self._widget.setMode("manual") self._widget.show() self.qWaitForWindowExposed(self._widget) assert not self._widget._automaticDefWidget.isVisible() assert self._widget._manualDefWidget.isVisible() def test_automatic_selection(self): self._widget.setMode("auto") self._widget.show() self.qWaitForWindowExposed(self._widget) assert self._widget._automaticDefWidget.isVisible() assert not self._widget._manualDefWidget.isVisible() class TestSeriesManualDefinitionDialog(TestCaseQt, _MockScanBase): """Test interaction with the series manual definition""" def setUp(self): self._widget = SeriesManualControlDialog() super().setUp() super().init() def tearDown(self): self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None super().close() super().tearDown() def test(self): self._widget.show() self.qWaitForWindowExposed(self._widget) self._widget.setSeriesName("series test") self.qapp.processEvents() assert self._widget.getSeriesName() == "series test" self._widget._mainWidget._newSeriesWidget._serieTree.rootItem.setText( 0, "new series" ) self.qapp.processEvents() assert self._widget.getSeriesName() == "new series" for scan in self._scans[:5]: self._widget.addScan(scan) self.assertEqual(self._widget.n_tomo_objs, len(self._scans[:5])) self._widget.removeScan(self._scans[0]) self.assertEqual(self._widget.n_tomo_objs, len(self._scans[:5]) - 1) series_scan = tuple(self._scans[1:5]) assert isinstance(series_scan, tuple) current_series = self._widget.getSeries(use_identifiers=True) assert isinstance(current_series, Series) series_test_1 = Series( name="new series", iterable=series_scan, use_identifiers=True ) self.assertEqual(series_test_1, current_series) series_test_2 = Series(name="test", iterable=series_scan, use_identifiers=True) assert series_test_2.name == "test" assert current_series.name == "new series" self.assertNotEqual(series_test_2, current_series) self._widget.setSelectedScans([self._scans[2]]) self._widget.getSelectedScans() == (self._scans[2],) self._widget.removeSelectedScans() self.assertEqual(self._widget.n_tomo_objs, len(self._scans[:5]) - 2) self._widget.getSelectedScans() == tuple() self._widget.clearSeries() self.assertEqual(self._widget.n_tomo_objs, 0) self.assertEqual(Series(name="new series"), self._widget.getSeries()) # test adding an nx file hdf5_scan = self._scans[0] assert isinstance(hdf5_scan, NXtomoScan) self._widget.addScanFromNxFile(hdf5_scan.master_file) self.assertEqual(self._widget.n_tomo_objs, 1) class TestSeriesWidget(TestCaseQt, _MockSeriesBase): """ Test the SeriesWidget """ def setUp(self): super().setUp() super().init() self._widget = SeriesWidget() # create listeners self.signal_send_series_listener = SignalListener() self.signal_serie_changed_listener = SignalListener() self.signal_history_changed_listener = SignalListener() # connect signal / slot self._widget.sigSeriesSend.connect(self.signal_send_series_listener) self._widget.sigCurrentSeriesChanged.connect(self.signal_serie_changed_listener) self._widget.sigHistoryChanged.connect(self.signal_history_changed_listener) def tearDown(self): self._widget.sigSeriesSend.disconnect(self.signal_send_series_listener) self._widget.sigCurrentSeriesChanged.disconnect( self.signal_serie_changed_listener ) self._widget.sigHistoryChanged.disconnect(self.signal_history_changed_listener) self.signal_send_series_listener = None self.signal_serie_changed_listener = None self.signal_history_changed_listener = None self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None super().close() super().tearDown() def test(self): self._widget.show() self.qWaitForWindowExposed(self._widget) self._seriesList[3].name = "toto series" for series in self._seriesList[2:5]: self._widget.getHistoryWidget().addSeries(series) self._widget.setMode("history") self._widget.setMode("series definition", "manual") self._widget.getDefinitionWidget().getManualDefinitionWidget().setSeriesName( "new series" ) self.assertEqual( len( self._widget.getDefinitionWidget() .getManualDefinitionWidget() .getSeries() ), 0, ) self._widget.getHistoryWidget().setSelectedSeries( [ self._seriesList[3], ] ) assert len(self._widget.getHistoryWidget().getSelectedSeries()) == 1 self.signal_serie_changed_listener.clear() self._widget.getHistoryWidget().editSelected() self.qapp.processEvents() assert self.signal_serie_changed_listener.callCount() == 1 self.assertEqual( self._widget.getDefinitionWidget() .getManualDefinitionWidget() .getSeries() .name, "toto series", ) self.assertEqual( self._widget.getDefinitionWidget() .getManualDefinitionWidget() .getSeries(use_identifiers=True), self._seriesList[3], ) self.signal_serie_changed_listener.clear() self._widget.getDefinitionWidget().getManualDefinitionWidget().addToCurrentSeries( self._scans[0] ) self.qapp.processEvents() assert self.signal_serie_changed_listener.callCount() == 1 expected_scans = self._scans[8:11] expected_scans.append(self._scans[0]) expected_series = Series("toto series", expected_scans, use_identifiers=True) self.assertEqual( self._widget.getDefinitionWidget() .getManualDefinitionWidget() .getSeries(use_identifiers=True), expected_series, ) # check send edited serie self.signal_history_changed_listener.clear() self.signal_send_series_listener.clear() self.qapp.processEvents() # check send selected from the history self.signal_send_series_listener.clear() self._widget.getHistoryWidget().setSelectedSeries( [ self._seriesList[4], ] ) assert len(self._widget.getHistoryWidget().getSelectedSeries()) == 1 self._widget.getHistoryWidget().sendSelected() assert self.signal_send_series_listener.callCount() == 1 class TestSerieManualFromTomoObj(TestCaseQt): """ test the SerieManualFromTomoObj widget """ def setUp(self): super().setUp() self._tmp_dir = tempfile.mkdtemp() self._widget = SeriesManualFromTomoObj() self._volume_1 = HDF5Volume( file_path=os.path.join(self._tmp_dir, "vol1.hdf5"), data_path="data", ) self._volume_2 = HDF5Volume( file_path=os.path.join(self._tmp_dir, "vol2.hdf"), data_path="data", ) self._volume_3 = HDF5Volume( file_path=os.path.join(self._tmp_dir, "vol3.nx"), data_path="data", ) self._scan_1 = MockNXtomo( scan_path=os.path.join(self._tmp_dir, "scan_1"), n_proj=10, n_ini_proj=10 ).scan self._scan_2 = MockNXtomo( scan_path=os.path.join(self._tmp_dir, "scan_2"), n_proj=10, n_ini_proj=10 ).scan def tearDown(self): shutil.rmtree(self._tmp_dir) self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None return super().tearDown() def test(self): self._widget.show() for tomo_obj in ( self._volume_1, self._volume_2, self._volume_3, self._scan_1, self._scan_2, ): self._widget.addTomoObj(tomo_obj) current_serie = self._widget.getSeries() assert isinstance(current_serie, Series) assert len(current_serie) == 0 for tomo_obj in (self._volume_1, self._volume_2): self._widget.addToCurrentSeries(tomo_obj) current_serie = self._widget.getSeries() assert isinstance(current_serie, Series) assert len(current_serie) == 2 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/control/series/test/test_nxtomo_concatenate.py0000644000175000017500000000123514757047403026357 0ustar00paynopaynofrom tomwer.tests.conftest import qtapp # noqa F401 from tomwer.gui.control.series.nxtomoconcatenate import NXtomoConcatenateWidget def test_NXtomoConcatenateWidget( qtapp, # noqa F811 ): """simple test of the NXtomoConcatenateWidget""" widget = NXtomoConcatenateWidget() assert widget.getConfiguration() == { "output_file": "{common_path}/concatenate.nx", "output_entry": "entry0000", "overwrite": False, } config = { "output_file": "helical.hdf5", "output_entry": "my_entry", "overwrite": True, } widget.setConfiguration(config=config) assert widget.getConfiguration() == config ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/control/singletomoobj.py0000644000175000017500000001517515153325210022024 0ustar00paynopaynoimport logging import os from silx.gui import qt from tomoscan.esrf.volume.utils import guess_volumes from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.tomwer_object import TomwerObject from tomwer.core.volume.edfvolume import EDFVolume, EDFVolumeIdentifier from tomwer.core.volume.hdf5volume import HDF5Volume, HDF5VolumeIdentifier from tomwer.core.volume.jp2kvolume import JP2KVolume, JP2KVolumeIdentifier from tomwer.core.volume.rawvolume import RawVolume, RawVolumeIdentifier from tomwer.core.volume.tiffvolume import ( MultiTIFFVolume, MultiTiffVolumeIdentifier, TIFFVolume, TIFFVolumeIdentifier, ) from tomwer.gui.dialog.QDataDialog import QDataDialog from tomwer.gui.qlefilesystem import QLFileSystem _logger = logging.getLogger(__name__) class SingleTomoObj(qt.QWidget): sigTomoObjChanged = qt.Signal(str) """signal emit when the tomo object changed. Parameter is the identifier""" def __init__(self, parent=None, *args, **kwargs) -> None: super().__init__(parent, *args, **kwargs) self.setLayout(qt.QHBoxLayout()) self._tomoObjIdentifierLineQLE = _TomoObjQLE("", self) self._tomoObjIdentifierLineQLE.setPlaceholderText( "scheme:obj_type:path?queries" ) self.layout().addWidget(self._tomoObjIdentifierLineQLE) self._selectScanPB = qt.QPushButton("select", self) self.layout().addWidget(self._selectScanPB) self.setToolTip( "Define a Tomo object. You can also copy / paster folder or files to use the automatic detection. Each time it changed if fit a valid scan then this scan will be triggered" ) # signal / slot connect self._tomoObjIdentifierLineQLE.editingFinished.connect(self._scanChanged) self._selectScanPB.released.connect(self._selectObject) def getTomoObjIdentifier(self) -> str: return self._tomoObjIdentifierLineQLE.text() def _selectObject(self, *args, **kwargs): # pragma: no cover dialog = QDataDialog(self, multiSelection=True) dialog.setNameFilters( [ "HDF5 files (*.h5 *.hdf5 *.nx *.nxs *.nexus)", "Nexus files (*.nx *.nxs *.nexus)", "Any files (*)", ] ) if not dialog.exec(): dialog.close() return added_tomo_objs = [] for path in dialog.selectedFiles(): try: objs = self.guessTomoObj(path=path) except Exception as e: # noqa E722 _logger.error(f"Fail to create tomo object from {path}. Error is {e}") else: if objs is not None: added_tomo_objs.extend(objs) if len(added_tomo_objs) > 0: self.setTomoObject(added_tomo_objs[0]) def _scanChanged(self): obj_identifier = self.getTomoObjIdentifier() # if the identifier fullill a path then this is not an identifier but # we must find the tomo obj associated if os.path.exists(obj_identifier): path = obj_identifier try: objs = self.guessTomoObj(path=path) except Exception as e: # noqa E722 _logger.error(f"Fail to create tomo object from {path}. Error is {e}") else: if objs is not None and len(objs) > 0: old = self._tomoObjIdentifierLineQLE.blockSignals(True) self._tomoObjIdentifierLineQLE.setText( objs[0].get_identifier().to_str() ) self._tomoObjIdentifierLineQLE.blockSignals(old) self.sigTomoObjChanged.emit(self.getTomoObjIdentifier()) def setTomoObject(self, scan): if isinstance(scan, TomwerObject): text = scan.get_identifier().to_str() else: text = scan self._tomoObjIdentifierLineQLE.setText(text) self.sigTomoObjChanged.emit(self.getTomoObjIdentifier()) def guessTomoObj(self, path): path = os.path.abspath(path) try: scans = ScanFactory.create_scan_objects(path) if scans is None or len(scans) == 0: raise ValueError except: # noqa E722 try: volumes = guess_volumes( path, scheme_to_vol={ EDFVolumeIdentifier.scheme: EDFVolume, HDF5VolumeIdentifier.scheme: HDF5Volume, TIFFVolumeIdentifier.scheme: TIFFVolume, MultiTiffVolumeIdentifier.scheme: MultiTIFFVolume, JP2KVolumeIdentifier.scheme: JP2KVolume, RawVolumeIdentifier.scheme: RawVolume, }, ) except: # noqa E722 pass return None else: # filter potential 'nabu histogram' if volumes is not None: def is_not_histogram(vol_identifier): return not ( hasattr(vol_identifier, "data_path") and vol_identifier.data_path.endswith("histogram") ) volumes = tuple(filter(is_not_histogram, volumes)) return volumes else: return scans class _TomoObjQLE(QLFileSystem): """QLineEdit that try to get a Tomo object identifier once dropped""" def supportedDropActions(self): """Inherited method to redefine supported drop actions.""" return qt.Qt.CopyAction | qt.Qt.MoveAction def dropEvent(self, a0) -> None: if hasattr(a0, "mimeData") and a0.mimeData().hasFormat("text/uri-list"): for url in a0.mimeData().urls(): try: new_objs = self.parent().guessTomoObj(url.path()) except: # noqa E722 pass else: if new_objs is not None and len(new_objs) > 0: self.setText(new_objs[0].get_identifier().to_str()) a0.accept() self.editingFinished.emit() else: return super().dropEvent(a0) def dragEnterEvent(self, event): if event.mimeData().hasFormat("text/uri-list"): event.accept() event.setDropAction(qt.Qt.CopyAction) else: qt.QListWidget.dragEnterEvent(self, event) def dragMoveEvent(self, event): if event.mimeData().hasFormat("text/uri-list"): event.setDropAction(qt.Qt.CopyAction) event.accept() else: qt.QListWidget.dragMoveEvent(self, event) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9371016 tomwer-1.6.17/src/tomwer/gui/control/tests/0000755000175000017500000000000015153325403017734 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/control/tests/__init__.py0000644000175000017500000000000014757047403022045 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/control/tests/test_datadiscovery.py0000644000175000017500000000140715153325210024204 0ustar00paynopaynofrom tomwer.tests.conftest import qtapp # noqa F401 from tomwer.gui.control.datadiscovery import DataDiscoveryWidget from tomwer.core.scan.scantype import ScanType def test_data_discovery_widget(qtapp): # noqa F811 widget = DataDiscoveryWidget() pass widget.show() configuration = widget.getConfiguration() assert isinstance(configuration, dict) assert configuration == { "start_folder": "", "file_filter": None, "scan_type_searched": ScanType.NX_TOMO.value, } new_config = { "start_folder": "/my/folder", "file_filter": "*.nx", "scan_type_searched": ScanType.BLISS.value, } widget.setConfiguration(new_config) assert widget.getConfiguration() == new_config widget = None ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/control/tests/test_datalist.py0000644000175000017500000000236114757047403023166 0ustar00paynopaynofrom tomwer.tests.conftest import qtapp # noqa F401 import tempfile import pytest from silx.gui import qt from tomwer.core.utils.scanutils import MockEDF from tomwer.gui.control.datalist import GenericScanListDialog, VolumeList from tomwer.tests.utils import skip_gui_test @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") def test_DataListTest( qtapp, # noqa F811 tmp_path, ): widget = GenericScanListDialog(parent=None) widget._callbackRemoveAllFolders() widget.clear() folders = [] for _ in range(5): folders.append(tempfile.mkdtemp()) MockEDF.mockScan(scanID=folders[-1], nRadio=5, nRecons=5, nPagRecons=0, dim=10) for _folder in folders: widget.add(_folder) assert widget.n_scan() == len(folders) widget.remove(folders[0]) assert widget.n_scan() == (len(folders) - 1) assert folders[0] not in widget.datalist._myitems widget.selectAll() widget._removeSelected() assert widget.n_scan() == 0 widget.setAttribute(qt.Qt.WA_DeleteOnClose) widget.close() @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") def test_VolumeList( qtapp, # noqa F811 tmp_path, ): """Test VolumeList behave as expected""" VolumeList(parent=None) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/control/tests/test_datalistener.py0000644000175000017500000000205015143647637024040 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import pytest from silx.gui.utils.testutils import SignalListener from tomwer.gui.control.datalistener import ConfigurationWidget from tomwer.gui.utils.qt_utils import block_signals from tomwer.tests.utils import skip_gui_test from tomwer.tests.conftest import qtapp # noqa F401 @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") def test_TestDataListenerConfiguration( qtapp, # noqa F811 ): configWidget = ConfigurationWidget(parent=None, enable_host_pinging=False) sig_listener = SignalListener() configWidget.sigConfigurationChanged.connect(sig_listener) with block_signals(configWidget): configWidget.setHost("localhost") assert configWidget.getConfiguration() == {"host": "localhost", "port": 4000} with block_signals(configWidget): configWidget.setPort(0) with block_signals(configWidget): configWidget.setHost("toto") assert configWidget.getConfiguration() == {"host": "toto", "port": 0} assert sig_listener.callCount() == 0 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/control/tests/test_datavalidator.py0000644000175000017500000000127314757047403024201 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import unittest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from tomwer.gui.control.datavalidator import DataValidator class TestValidatorGUI(TestCaseQt): """Test that the ImageStackWidget can be load and remove without any issue""" def setUp(self): TestCaseQt.setUp(self) self._widget = DataValidator(None) def tearDown(self): self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None unittest.TestCase.tearDown(self) def test(self): """Make sur the addLeaf and clear functions are working""" pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/control/tests/test_inputwidget.py0000644000175000017500000000343114757047403023723 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import numpy import pytest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from tomwer.gui.utils import inputwidget from tomwer.tests.utils import skip_gui_test @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class SelectionLineEditTest(TestCaseQt): """Test the SelectionLineEdit""" def setUp(self): super().setUp() self.widget = inputwidget.SelectionLineEdit(parent=None) def tearDown(self): self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None super().tearDown() def testListSelection(self): self.widget.mode = inputwidget.SelectionLineEdit.LIST_MODE self.widget.setText("1.0, 2.0; 6.3") self.assertTrue(self.widget.selection == (1.0, 2.0, 6.3)) self.widget.setText("1.0:3.6:0.2") self.assertTrue( self.widget.selection == tuple(numpy.linspace(1.0, 3.6, num=int(2.6 / 0.2))) ) self.assertTrue( self.widget.getMode() == inputwidget.SelectionLineEdit.RANGE_MODE ) self.widget.setText("1.0") self.assertTrue(self.widget.selection == 1.0) def testRangeSelection(self): self.widget.mode = inputwidget.SelectionLineEdit.RANGE_MODE self.widget.setText("1.0:3.6:0.2") self.assertTrue( self.widget.selection == tuple(numpy.linspace(1.0, 3.6, num=int(2.6 / 0.2))) ) self.widget.setText("1.0") self.assertTrue(self.widget.selection == 1.0) self.widget.setText("1.0, 2.0, 6.3") self.assertTrue( self.widget.getMode() == inputwidget.SelectionLineEdit.LIST_MODE ) self.assertTrue(self.widget.selection == (1.0, 2.0, 6.3)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/control/tests/test_reducedarkflat_selector.py0000644000175000017500000002232615153325210026226 0ustar00paynopaynoimport numpy from silx.gui.utils.testutils import SignalListener from tomwer.tests.conftest import qtapp # noqa F401 from tomwer.gui.control.reducedarkflatselector import ( filter_selected_reduced_frames, filter_unselected_reduced_frames, ReduceDarkFlatSelectorWidget, ReduceDarkFlatSelectorDialog, ) def test_reduce_darkflat_selector( qtapp, # noqa F811 ): widget = ReduceDarkFlatSelectorWidget() widget.show() widget.addReduceFrames( { 0: numpy.random.random(100 * 100).reshape(100, 100), 1: numpy.random.random(100 * 100).reshape(100, 100), } ) widget.addReduceFrames( { "reduce_frames_name": "my_dict", -1: numpy.random.random(100 * 100).reshape(100, 100), 2: numpy.random.random(100 * 100).reshape(100, 100), } ) config = widget.getConfiguration() assert len(config) == 2 assert config[0]["reduce_frames_name"] == "reduced frames #0" assert config[1]["reduce_frames_name"] == "my_dict" widget.setConfiguration( ( { "reduce_frames_name": "toto frames", "reduce_frames": ( { "index": -1, # -1 will be interpreated as at the end of the acquisition "data": numpy.random.random(20 * 20).reshape(20, 20), "selected": True, }, { "index": 0, "data": numpy.random.random(20 * 20).reshape(20, 20), "selected": True, }, ), }, { "reduce_frames_name": "tata frames", "reduce_frames": ( { "index": "0.25r", "data": numpy.random.random(40 * 20).reshape(40, 20), "selected": False, }, ), }, ) ) config = widget.getConfiguration() assert len(config) == 2 # check selection has been well take into account assert config[0]["reduce_frames"][0]["selected"] assert config[0]["reduce_frames"][1]["selected"] assert not config[1]["reduce_frames"][0]["selected"] selected_frames = widget.getSelectedReduceFrames() assert -1 in selected_frames assert 0 in selected_frames assert 0.25 not in selected_frames # test receive twice the same 'reduce_frames_name' widget.clear() assert len(widget.getConfiguration()) == 0 for i in range(2): widget.addReduceFrames( { "reduce_frames_name": "my_dict", -1: numpy.random.random(100 * 100).reshape(100, 100), 2: numpy.random.random(100 * 100).reshape(100, 100), } ) assert len(widget.getConfiguration()) == 1 def test_reduce_darkflat_selector_dialog( qtapp, # noqa F811 ): dialog = ReduceDarkFlatSelectorDialog() flat_sel_signal_listener = SignalListener() dialog.sigSelectActiveAsFlats.connect(flat_sel_signal_listener) dark_sel_signal_listener = SignalListener() dialog.sigSelectActiveAsDarks.connect(dark_sel_signal_listener) dialog.show() dialog.addReduceFrames( { 0: numpy.random.random(100 * 100).reshape(100, 100), 1: numpy.random.random(100 * 100).reshape(100, 100), }, selected=(1,), ) dialog.addReduceFrames( { "reduce_frames_name": "my_dict", -1: numpy.random.random(100 * 100).reshape(100, 100), 2: numpy.random.random(100 * 100).reshape(100, 100), }, selected=(-1,), ) # check dark selection assert dark_sel_signal_listener.callCount() == 0 dialog._darkSelected() assert dark_sel_signal_listener.callCount() == 1 assert -1 in dark_sel_signal_listener.arguments()[0][0] # check flat selection assert flat_sel_signal_listener.callCount() == 0 dialog._flatSelected() assert flat_sel_signal_listener.callCount() == 1 assert -1 in flat_sel_signal_listener.arguments()[0][0] # check remove selected dialog._removeSelected() assert dialog._widget.getSelectedReduceFrames() == {} # check clear selection dialog.addReduceFrames( { "reduce_frames_name": "new dict", -1: numpy.random.random(100 * 100).reshape(100, 100), 2: numpy.random.random(100 * 100).reshape(100, 100), }, selected=(-1, 2), ) assert len(dialog._widget.getSelectedReduceFrames()) == 2 dialog._clearSelection() assert len(dialog._widget.getSelectedReduceFrames()) == 0 def test_reduced_frames_filtering(): """ dummy test of the filter_selected_reduced_frames filter_unselected_reduced_frames function """ check_reduce_frames_configuration( filter_selected_reduced_frames( ( { "reduce_frames_name": "toto frames", "reduce_frames": ( { "index": -1, # -1 will be interpreated as at the end of the acquisition "data": numpy.random.random(20 * 20).reshape(20, 20), "selected": True, }, { "index": 0, "data": numpy.random.random(20 * 20).reshape(20, 20), "selected": True, }, ), }, { "reduce_frames_name": "tata frames", "reduce_frames": ( { "index": "0.25r", "data": numpy.random.random(40 * 20).reshape(40, 20), "selected": False, }, ), }, ) ), ( { "reduce_frames_name": "toto frames", "reduce_frames": ( { "index": -1, # -1 will be interpreated as at the end of the acquisition "data": numpy.random.random(20 * 20).reshape(20, 20), "selected": True, }, { "index": 0, "data": numpy.random.random(20 * 20).reshape(20, 20), "selected": True, }, ), }, ), ) check_reduce_frames_configuration( filter_unselected_reduced_frames( ( { "reduce_frames_name": "toto frames", "reduce_frames": ( { "index": -1, # -1 will be interpreated as at the end of the acquisition "data": numpy.random.random(20 * 20).reshape(20, 20), "selected": True, }, { "index": 0, "data": numpy.random.random(20 * 20).reshape(20, 20), "selected": False, }, ), }, { "reduce_frames_name": "tata frames", "reduce_frames": ( { "index": "0.25r", "data": numpy.random.random(40 * 20).reshape(40, 20), "selected": False, }, ), }, ) ), ( { "reduce_frames_name": "toto frames", "reduce_frames": ( { "index": 0, "data": numpy.random.random(20 * 20).reshape(20, 20), "selected": False, }, ), }, { "reduce_frames_name": "tata frames", "reduce_frames": ( { "index": "0.25r", "data": numpy.random.random(40 * 20).reshape(40, 20), "selected": False, }, ), }, ), ) check_reduce_frames_configuration(filter_unselected_reduced_frames(()), ()) def check_reduce_frames_configuration(config_1, config_2): """ simple comparaison of two configurations """ assert len(config_1) == len(config_2) for reduce_frame_group_1, reduce_frame_group_2 in zip(config_1, config_2): assert reduce_frame_group_1.get( "reduce_frames_name", None ) == reduce_frame_group_2.get("reduce_frames_name", None) for reduce_frame_group_1, reduce_frame_group_2 in zip( reduce_frame_group_1.get("reduce_frames", tuple()), reduce_frame_group_2.get("reduce_frames", tuple()), ): assert reduce_frame_group_1["index"] == reduce_frame_group_2["index"] assert reduce_frame_group_1["selected"] == reduce_frame_group_2["selected"] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/control/tests/test_scan_observations.py0000644000175000017500000000161014757047403025077 0ustar00paynopaynofrom silx.gui import qt from tomwer.gui.control.observations import ScanObservation from tomwer.tests.conftest import qtapp # noqa F401 from tomwer.tests.conftest import nxtomo_scan_180 # noqa F401 def test_ScanObservation(qtapp, nxtomo_scan_180): # noqa F811 widget = ScanObservation(parent=None) widget.addObservation( scan=nxtomo_scan_180, ) model = widget.observationTable.model() # check time stamp assert len(model.data(model.createIndex(0, 0), qt.Qt.DisplayRole)) == 8 # check type assert model.data(model.createIndex(0, 1), qt.Qt.DisplayRole) == "hdf5" # check n projections assert model.data(model.createIndex(0, 2), qt.Qt.DisplayRole) == 0 # check status assert model.data(model.createIndex(0, 3), qt.Qt.DisplayRole) == "starting" # check identifier assert "NXtomo" in model.data(model.createIndex(0, 4), qt.Qt.DisplayRole) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/control/tests/test_scanselector.py0000644000175000017500000000236114757047403024046 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import shutil import tempfile import pytest from silx.gui.utils.testutils import TestCaseQt from tomwer.core.utils.scanutils import MockEDF from tomwer.gui.control.scanselectorwidget import ScanSelectorWidget from tomwer.tests.utils import skip_gui_test @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestScanSelector(TestCaseQt): """ Simple test for the ScanSelectorWidget """ def setUp(self): self._folder1 = tempfile.mkdtemp() self._folder2 = tempfile.mkdtemp() self._folder3 = tempfile.mkdtemp() for _folder in (self._folder1, self._folder2, self._folder3): MockEDF.mockScan(scanID=_folder, nRadio=5, nRecons=5, nPagRecons=0, dim=10) self.widget = ScanSelectorWidget(parent=None) def tearDown(self): shutil.rmtree(self._folder1) shutil.rmtree(self._folder2) shutil.rmtree(self._folder3) def test(self): self.widget.add(self._folder1) self.widget.add(self._folder2) self.widget.add(self._folder3) self.assertEqual(self.widget.dataList.n_data(), 3) self.widget.remove(self._folder3) self.assertEqual(self.widget.dataList.n_data(), 2) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/control/tests/test_scanvalidator.py0000644000175000017500000000502515153325210024175 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging import os import shutil import tempfile import time import pytest from silx.gui.utils.testutils import TestCaseQt from tomwer.core import settings from tomwer.core.utils.lbsram import mock_low_memory, is_low_on_memory from tomwer.core.process.control.scanvalidator import ScanValidatorP from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.utils.scanutils import MockEDF from tomwer.gui.utils.waiterthread import QWaiterThread from tomwer.tests.utils import skip_gui_test logging.disable(logging.INFO) @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestScanValidator(TestCaseQt): """ Simple test to make sure the timeout of data watcher is working properly """ LOOP_MEM_RELEASER_DURATION = 0.2 NB_SCANS = 2 def tearDown(self): mock_low_memory(False) @classmethod def setUpClass(cls): settings.mock_lsbram(True) cls.scanValidator = ScanValidatorP(memoryReleaser=QWaiterThread(0.5)) cls.scans = [] for _ in range(cls.NB_SCANS): scanID = tempfile.mkdtemp() MockEDF.mockScan(scanID=scanID, nRadio=10, nRecons=2, nPagRecons=0, dim=10) cls.scans.append(scanID) @classmethod def tearDownClass(cls): settings.mock_lsbram(False) for f in cls.scans: if os.path.isdir(f): shutil.rmtree(f) @pytest.mark.skipif( (settings.isOnLbsram() and is_low_on_memory(settings.get_lbsram_path())), reason="Lbsram already overloaded", ) def testMemoryReleaseLoop(self): """ Make sure the internal loop of the scan validator is active if we are on lbsram. """ def add_all_scans(): for scan in self.scans: self.scanValidator.addScan(EDFTomoScan(scan)) self.assertEqual(len(self.scanValidator._scans), self.NB_SCANS) def my_wait(): for _ in range(3): while self.qapp.hasPendingEvents(): self.qapp.processEvents() time.sleep(self.LOOP_MEM_RELEASER_DURATION * 2) add_all_scans() mock_low_memory(True) my_wait() self.assertEqual(len(self.scanValidator._scans), 0) mock_low_memory(False) add_all_scans() my_wait() self.assertEqual(len(self.scanValidator._scans), self.NB_SCANS) self.scanValidator.clear() my_wait() self.assertEqual(len(self.scanValidator._scans), 0) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/control/tests/test_single_tomo_obj.py0000644000175000017500000000434614757047403024537 0ustar00paynopaynoimport os import tempfile import numpy from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from tomwer.core.utils.scanutils import MockNXtomo from tomwer.core.volume.hdf5volume import HDF5Volume from tomwer.gui.control.singletomoobj import SingleTomoObj class TestSingletomoObj(TestCaseQt): """ Test of SingleTomoObj interface """ def setUp(self): super().setUp() self._tempdir = tempfile.mkdtemp() self._widget = SingleTomoObj() self._volume_file_path = os.path.join(self._tempdir, "volume.hdf5") self.volume = HDF5Volume( file_path=self._volume_file_path, data_path="my_volume", data=numpy.linspace(start=0, stop=200, num=200).reshape((2, 10, 10)), ) self.volume.save() self._scan_file_path = os.path.join(self._tempdir, "scan.nx") self.scan_hdf5 = MockNXtomo( scan_path=self._scan_file_path, n_proj=10, n_ini_proj=10, create_ini_dark=False, create_ini_flat=False, dim=10, ).scan def tearDown(self): self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None super().tearDown() def test_set_volume(self): self._widget.setTomoObject(self.volume) assert ( self._widget.getTomoObjIdentifier() == self.volume.get_identifier().to_str() ) self._widget.setTomoObject("") assert self._widget.getTomoObjIdentifier() == "" self._widget.setTomoObject(self.volume.get_identifier().to_str()) assert ( self._widget.getTomoObjIdentifier() == self.volume.get_identifier().to_str() ) def test_set_scan(self): self._widget.setTomoObject(self.scan_hdf5) assert ( self._widget.getTomoObjIdentifier() == self.scan_hdf5.get_identifier().to_str() ) self._widget.setTomoObject("") assert self._widget.getTomoObjIdentifier() == "" self._widget.setTomoObject(self.scan_hdf5.get_identifier().to_str()) assert ( self._widget.getTomoObjIdentifier() == self.scan_hdf5.get_identifier().to_str() ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/control/tests/test_volume_dialog.py0000644000175000017500000001512614757047403024212 0ustar00paynopaynofrom __future__ import annotations import os import shutil import tempfile import numpy import pytest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from tomoscan.esrf.volume.edfvolume import EDFVolume from tomoscan.esrf.volume.hdf5volume import HDF5Volume from tomwer.gui.dialog.QVolumeDialog import QVolumeDialog from tomwer.tests.utils import skip_gui_test @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestVolumeDialog(TestCaseQt): """Test QVolumeDialog""" def setUp(self): super().setUp() self.tmp_dir = tempfile.mkdtemp() self._dialog = QVolumeDialog() def tearDown(self): shutil.rmtree(self.tmp_dir) self._dialog.setAttribute(qt.Qt.WA_DeleteOnClose) self._dialog.close() self._dialog = None return super().tearDown() def test_provide_hdf5_volume_auto(self): """ Test everything can be discovered from a single 'default' hdf5 file """ self._dialog.setFullAuto(True) file_path = os.path.join(self.tmp_dir, "myvolume.nx") volume = HDF5Volume( file_path=file_path, data_path="entry", data=numpy.linspace(start=1, stop=10, num=300, dtype=numpy.uint8).reshape( (3, 10, 10) ), ) volume.save() self._dialog.show() self._dialog.setFilePath(file_path) self.qapp.processEvents() assert self._dialog.getDataPath() in ("entry", "/entry") assert self._dialog.getDataExtension() == "nx" assert self._dialog.getVolumeBasename() in ("", None) volume_defined = self._dialog.getVolume() assert volume_defined is not None volume_defined.load() assert volume_defined.data is not None assert ( self._dialog._volumeUrlQL.text() == volume_defined.get_identifier().to_str() ) def test_provide_hdf5_volume_manual(self): """ Test we can create a volume if everything is defined manually from hdf5 volume file """ self._dialog.setFullAuto(False) file_path = os.path.join(self.tmp_dir, "myvolume.nx") volume = HDF5Volume( file_path=file_path, data_path="entry", data=numpy.linspace(start=1, stop=10, num=300, dtype=numpy.uint8).reshape( (3, 10, 10) ), ) volume.save() self._dialog.setDataExtension("nx") assert self._dialog.getVolume() is not None self._dialog.setFilePath(file_path) self._dialog.setDataPath("entry") volume_defined = self._dialog.getVolume() volume_defined.load() assert volume_defined.data is not None assert ( self._dialog._volumeUrlQL.text() == volume_defined.get_identifier().to_str() ) def test_provide_edf_volume_auto(self): """ Test everything can be discovered from a single 'default' edf volume folder """ self._dialog.setFullAuto(True) volume = EDFVolume( folder=self.tmp_dir, data=numpy.linspace(start=1, stop=10, num=300, dtype=numpy.uint8).reshape( (3, 10, 10) ), ) volume.save() self._dialog.show() self._dialog.setFilePath(self.tmp_dir) self.qapp.processEvents() assert self._dialog.getDataPath() in ("", None) assert self._dialog.getDataExtension() == "edf" assert self._dialog.getVolumeBasename() == os.path.basename(self.tmp_dir) volume_defined = self._dialog.getVolume() assert volume_defined is not None volume_defined.load() assert volume_defined.data is not None assert ( self._dialog._volumeUrlQL.text() == volume_defined.get_identifier().to_str() ) def test_provide_edf_volume_manual(self): """ Test we can create a volume if everything is defined manually from edf volume folder """ self._dialog.setFullAuto(False) volume = EDFVolume( folder=self.tmp_dir, data=numpy.linspace(start=1, stop=10, num=300, dtype=numpy.uint8).reshape( (3, 10, 10) ), volume_basename="test", ) volume.save() self._dialog.show() self._dialog.setFilePath(self.tmp_dir) self.qapp.processEvents() self._dialog.setDataExtension( ".edf" ) # should be edf but test works also if user add the dot self._dialog.setVolumeBasename("test") volume_defined = self._dialog.getVolume() assert volume_defined is not None volume_defined.load() assert volume_defined.data is not None assert ( self._dialog._volumeUrlQL.text() == volume_defined.get_identifier().to_str() ) def test_provide_hdf5_volume_url(self): """ Test we can create a volume if the url (of a hdf5 volume) is provided by the user """ file_path = os.path.join(self.tmp_dir, "myvolume.hdf") volume = HDF5Volume( file_path=file_path, data_path="entry", data=numpy.linspace(start=1, stop=10, num=300, dtype=numpy.uint8).reshape( (3, 10, 10) ), ) volume.save() self._dialog.setVolumeUrl(volume.get_identifier().to_str()) volume_defined = self._dialog.getVolume() assert volume_defined is not None volume_defined.load() assert volume_defined.data is not None assert self._dialog.getDataPath() in ("entry", "/entry") assert self._dialog.getVolumeBasename() in ("", None) assert self._dialog.getFilePath() == file_path assert self._dialog.getDataExtension() == "hdf" def test_provide_edf_volume_url(self): """ Test we can create a volume if the url (of a EDFVolume) is provided by the user """ volume = EDFVolume( folder=self.tmp_dir, data=numpy.linspace(start=1, stop=10, num=300, dtype=numpy.uint8).reshape( (3, 10, 10) ), volume_basename="test", ) volume.save() self._dialog.setVolumeUrl(volume.get_identifier().to_str()) volume_defined = self._dialog.getVolume() assert volume_defined is not None volume_defined.load() assert volume_defined.data is not None assert self._dialog.getDataPath() in ("", None) assert self._dialog.getVolumeBasename() == "test" assert self._dialog.getFilePath() == self.tmp_dir assert self._dialog.getDataExtension() == "edf" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/control/tests/test_volumeselector.py0000644000175000017500000000405115143647637024434 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import shutil import tempfile import numpy import pytest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from tomwer.core.volume import EDFVolume, HDF5Volume from tomwer.gui.control.volumeselectorwidget import VolumeSelectorWidget from tomwer.tests.utils import skip_gui_test @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestVolumeSelector(TestCaseQt): """ Simple test for the VolumeSelector """ def setUp(self): super().setUp() self.folder = tempfile.mkdtemp() self.volume_1 = HDF5Volume( file_path=os.path.join(self.folder, "my_volume.hdf5"), data_path="entry0000", data=numpy.linspace(start=1, stop=100, num=300).reshape((3, 10, 10)), ) self.volume_1.save() self.volume_2 = HDF5Volume( file_path=os.path.join(self.folder, "my_volume.hdf5"), data_path="entry0001", data=numpy.linspace(start=1, stop=100, num=400).reshape((4, 10, 10)), ) self.volume_2.save() self.volume_3 = EDFVolume( folder=os.path.join(self.folder, "vol"), data=numpy.linspace(start=1, stop=100, num=500).reshape((5, 10, 10)), ) self.volume_3.save() self.widget = VolumeSelectorWidget(parent=None) def tearDown(self): self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None shutil.rmtree(self.folder) super().tearDown() def test(self): for volume in (self.volume_1, self.volume_2, self.volume_3): self.widget.add(volume) # self.widget.show() # self.qapp.exec() self.assertEqual(self.widget.dataList.n_data(), 3) self.widget.remove(self.volume_2) self.assertEqual(self.widget.dataList.n_data(), 2) self.widget.remove(self.volume_3) self.assertEqual(self.widget.dataList.n_data(), 1) assert self.widget.dataList.rowCount() == 1 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/gui/control/tomoobjdisplaymode.py0000644000175000017500000000022415115744275023060 0ustar00paynopaynofrom enum import Enum as _Enum class DisplayMode(_Enum): """possible display mode for the tomo object""" URL = "url" SHORT = "short" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/control/volumeselectorwidget.py0000644000175000017500000000136615143647637023445 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging from tomwer.gui.control.datalist import VolumeList from tomwer.gui.dialog.QVolumeDialog import QVolumeDialog from .selectorwidgetbase import _SelectorWidget logger = logging.getLogger(__name__) class VolumeSelectorWidget(_SelectorWidget): """Widget used to select a volume on a list""" def _buildDataList(self): return VolumeList(self) def _callbackAddData(self): dialog = QVolumeDialog(self) if not dialog.exec(): dialog.close() return volume = dialog.getVolume() if volume is not None: added_objs = self.add(volume) self.setMySelection(added_objs) self.sigUpdated.emit() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9371016 tomwer-1.6.17/src/tomwer/gui/dataportal/0000755000175000017500000000000015153325403017245 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/gui/dataportal/__init__.py0000644000175000017500000000004514764622416021370 0ustar00paynopayno"""Widgets related to icat / drac""" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/dataportal/createscreenshots.py0000644000175000017500000000607014757047403023360 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt class CreateRawDataScreenshotsWidget(qt.QWidget): """ Widget to allow the user define the screenshot to make of the raw data """ sigConfigChanged = qt.Signal() """emit when the configuration change""" def __init__(self, parent=None): super().__init__(parent) self.setLayout(qt.QFormLayout()) # projections self._projectionsCB = qt.QCheckBox("raw projections each", self) self._projectionsSB = qt.QSpinBox(parent) self._projectionsSB.setSuffix("°") self.layout().addRow(self._projectionsCB, self._projectionsSB) # flat field self._flatFieldCB = qt.QCheckBox("first raw flat") self.layout().addRow(self._flatFieldCB) # dark field self._darkFieldCB = qt.QCheckBox("first raw dark") self.layout().addRow(self._darkFieldCB) # set up self._projectionsCB.setChecked(True) self._flatFieldCB.setChecked(True) self._darkFieldCB.setChecked(True) # connect signal / slot self._projectionsCB.toggled.connect(self._changed) self._projectionsSB.valueChanged.connect(self._changed) self._projectionsSB.setRange(0, 360) self._projectionsSB.setValue(90) self._flatFieldCB.toggled.connect(self._changed) self._darkFieldCB.toggled.connect(self._changed) def _changed(self, *args, **kwargs): self.sigConfigChanged.emit() def getConfiguration(self) -> dict: return { "raw_projections_required": self._projectionsCB.isChecked(), "raw_projections_each": self._projectionsSB.value(), "raw_darks_required": self._darkFieldCB.isChecked(), "raw_flats_required": self._flatFieldCB.isChecked(), } def setRawProjections(self, required: bool, each_proj: int | None): self._projectionsCB.setChecked(required) if each_proj is not None: self._projectionsSB.setValue(int(each_proj)) def setFlatFieldRequired(self, required: bool): self._flatFieldCB.setChecked(required) def setDarkFieldRequired(self, required: bool): self._darkFieldCB.setChecked(required) def setConfiguration(self, configuration: dict): assert isinstance(configuration, dict) # handle raw projections raw_projections_required = configuration.get( "raw_projections_required", self._projectionsCB.isChecked() ) raw_projections_each = configuration.get("raw_projections_each", None) self.setRawProjections( required=raw_projections_required, each_proj=raw_projections_each ) # handle flat field flat_field_required = configuration.get("raw_flats_required", None) if flat_field_required is not None: self.setFlatFieldRequired(flat_field_required) # handle flat field dark_field_required = configuration.get("raw_darks_required", None) if dark_field_required is not None: self.setDarkFieldRequired(dark_field_required) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/dataportal/gallery.py0000644000175000017500000001137515153325210021261 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from tomwer.core.process.drac.output import OutputFormat from tomwer.gui import icons from tomwer.core.process.drac.binning import Binning class GalleryOptionsAction(qt.QAction): def __init__(self, parent): icon = icons.getQIcon("icat_gallery_opts") qt.QAction.__init__(self, icon, "Icat gallery options", parent) class GalleryWidget(qt.QWidget): """Widget to let the user define the output location of the screenshots""" sigConfigChanged = qt.Signal() """emit when the configuration has changed""" def __init__(self, parent=None): super().__init__(parent) self.setLayout(qt.QFormLayout()) # screenshot precision self._precisionQCB = qt.QComboBox(self) self._precisionQCB.addItem("uint8") self.layout().addRow("precision", self._precisionQCB) # binning self._binningQCB = qt.QComboBox(self) self._binningQCB.addItems([item.value for item in Binning]) self.layout().addRow("binning", self._binningQCB) self._binningQCB.setCurrentText(Binning.SIXTEEN_BY_SIXTEEN.value) self._binningQCB.setToolTip( "To speed up display of the gallery at the data portal side it is highly recommended to bin screenshots" ) # recommended size: 5ko for the entire gallery # output format self._outputFormat = qt.QComboBox(self) self._outputFormat.addItems([item.value for item in OutputFormat]) self.layout().addRow("output format", self._outputFormat) # overwrite self._overwriteCB = qt.QCheckBox("overwrite", self) self._overwriteCB.setChecked(True) self.layout().addRow(self._overwriteCB) # connect signal / slot self._outputFormat.currentIndexChanged.connect(self._configChanged) self._overwriteCB.toggled.connect(self._configChanged) self._binningQCB.currentIndexChanged.connect(self._configChanged) def getOutputFormat(self) -> OutputFormat: return OutputFormat(self._outputFormat.currentText()) def setOutputFormat(self, format: OutputFormat): format = OutputFormat(format) self._outputFormat.setCurrentText(format.value) def getBinning(self) -> Binning: return Binning(self._binningQCB.currentText()) def setBinning(self, binning: Binning): binning = Binning(binning) self._binningQCB.setCurrentText(binning.value) def overwrite(self) -> bool: return self._overwriteCB.isChecked() def setOverwrite(self, overwrite: bool) -> None: return self._overwriteCB.setChecked(overwrite) def getConfiguration(self): return { "output_format": self.getOutputFormat().value, "overwrite": self.overwrite(), "binning": self.getBinning().value, } def setConfiguration(self, config: dict): if not isinstance(config, dict): raise TypeError(f"config is a expected to be a dict. got {type(config)}") output_format = config.get("output_format", None) if output_format is not None: self.setOutputFormat(output_format) overwrite = config.get("overwrite", None) if overwrite is not None: overwrite = overwrite in (True, "True", 1) self.setOverwrite(overwrite=overwrite) binning = config.get("binning", None) if binning is not None: self.setBinning(binning=binning) def _configChanged(self, *args, **kwargs): self.sigConfigChanged.emit() class GalleryDialog(qt.QDialog): def __init__(self, parent: qt.QWidget | None = None) -> None: super().__init__(parent) self.setLayout(qt.QVBoxLayout()) self._widget = GalleryWidget() self.layout().addWidget(self._widget) types = qt.QDialogButtonBox.Ok | qt.QDialogButtonBox.Cancel self._buttons = qt.QDialogButtonBox(self) self._buttons.setStandardButtons(types) self.layout().addWidget(self._buttons) # expose API def setConfiguration(self, gallery_options: dict) -> None: self._widget.setConfiguration(gallery_options) def getConfiguration(self) -> dict: return self._widget.getConfiguration() def getOutputFormat(self) -> OutputFormat: return self._widget.getOutputFormat() def setOutputFormat(self, format: OutputFormat): return self._widget.setOutputFormat(format=format) def getBinning(self) -> Binning: return self._widget.getBinning() def setBinning(self, binning: Binning): self._widget.setBinning(binning=binning) def overwrite(self) -> bool: return self._widget.overwrite def setOverwrite(self, overwrite: bool) -> None: self._widget.setOverwrite(overwrite=overwrite) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/dataportal/outputformat.py0000644000175000017500000000000014757047403022370 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/dataportal/publish.py0000644000175000017500000000722314757047403021303 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from tomwer.gui.configuration.action import ( ExpertConfigurationAction, BasicConfigurationAction, ) from tomwer.gui.configuration.level import ConfigurationLevel from tomwer.core.scan.scanbase import TomwerScanBase try: from ewoksnotify.gui.icat import PublishProcessedDataWidget except ImportError: has_ewoksnotify = False else: has_ewoksnotify = True class PublishProcessedDataWindow(qt.QMainWindow): def __init__(self, parent: qt.QWidget | None, beamlines: tuple) -> None: super().__init__(parent) if not has_ewoksnotify: raise RuntimeError( f"ewoksnotify not installed. Please install it to instantiate {PublishProcessedDataWindow}" ) # define toolbar toolbar = qt.QToolBar(self) self.addToolBar(qt.Qt.TopToolBarArea, toolbar) self.__configurationModesAction = qt.QAction(self) self.__configurationModesAction.setCheckable(False) menu = qt.QMenu(self) self.__configurationModesAction.setMenu(menu) toolbar.addAction(self.__configurationModesAction) self.__configurationModesGroup = qt.QActionGroup(self) self.__configurationModesGroup.setExclusive(True) self._basicConfigAction = BasicConfigurationAction(toolbar) menu.addAction(self._basicConfigAction) self.__configurationModesGroup.addAction(self._basicConfigAction) self._expertConfiguration = ExpertConfigurationAction(toolbar) menu.addAction(self._expertConfiguration) self.__configurationModesGroup.addAction(self._expertConfiguration) # define widget self._centralWidget = PublishProcessedDataWidget( parent=parent, beamlines=beamlines, ) # hide the dataset field has defined automatically by tomwer self._centralWidget._datasetPLB.setDisabled(True) self._centralWidget._datasetQLE.setDisabled(True) self._centralWidget._datasetQLE.setToolTip("This field is imposed by tomwer") self.setCentralWidget(self._centralWidget) # connect signal / slot self.__configurationModesGroup.triggered.connect(self._userModeChanged) # set up # for the time beeing let's hide the toolbar and use the 'expert configuration' toolbar.hide() self._expertConfiguration.trigger() def _userModeChanged(self, action): self.__configurationModesAction.setIcon(action.icon()) self.__configurationModesAction.setToolTip(action.tooltip()) if action is self._basicConfigAction: level = ConfigurationLevel.OPTIONAL elif action is self._expertConfiguration: level = ConfigurationLevel.ADVANCED else: raise NotImplementedError self.centralWidget().setVisible(ConfigurationLevel.ADVANCED <= level) # expose API def getConfiguration(self) -> dict: return self._centralWidget.getConfiguration() def setConfiguration(self, configuration: dict) -> None: self._centralWidget.setConfiguration(configuration=configuration) def setScan(self, scan: TomwerScanBase): if not isinstance(scan, TomwerScanBase): raise TypeError( f"scan is expected to be an instance of {TomwerScanBase}, {type(scan)} provided instead" ) new_config = {} if not self._centralWidget._proposalPLB.isChecked(): new_config["proposal"] = scan.get_proposal_name() if not self._centralWidget._beamlinePLB.isChecked(): new_config["beamline"] = scan.instrument_name self.setConfiguration(new_config) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9371016 tomwer-1.6.17/src/tomwer/gui/dataportal/tests/0000755000175000017500000000000015153325403020407 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/dataportal/tests/test_create_screenshots_gui.py0000644000175000017500000000131214757047403026556 0ustar00paynopaynofrom tomwer.tests.conftest import qtapp # noqa F401 from tomwer.gui.dataportal.createscreenshots import CreateRawDataScreenshotsWidget def test_CreateRawDataScreenshotsWidget(qtapp): # noqa F811 widget = CreateRawDataScreenshotsWidget() assert widget.getConfiguration() == { "raw_projections_required": True, "raw_projections_each": 90, "raw_darks_required": True, "raw_flats_required": True, } new_config = { "raw_projections_required": True, "raw_projections_each": 26, "raw_darks_required": False, "raw_flats_required": False, } widget.setConfiguration(new_config) assert widget.getConfiguration() == new_config ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/dataportal/tests/test_gallery_gui.py0000644000175000017500000000102114757047403024327 0ustar00paynopaynofrom tomwer.tests.conftest import qtapp # noqa F401 from tomwer.gui.dataportal.gallery import GalleryWidget def test_GalleryWidget( qtapp, # noqa F811 ): widget = GalleryWidget() assert widget.getConfiguration() == { "output_format": "png", "overwrite": True, "binning": "16x16", } new_config = { "output_format": "jpg", "overwrite": False, "binning": "4x4", } widget.setConfiguration(new_config) assert widget.getConfiguration() == new_config ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9371016 tomwer-1.6.17/src/tomwer/gui/debugtools/0000755000175000017500000000000015153325403017261 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/gui/debugtools/__init__.py0000644000175000017500000000011614764622416021403 0ustar00paynopayno"""Widgets useful to debut a tomography workflow (generate random scan...)""" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/debugtools/datasetgenerator.py0000644000175000017500000002213515153325210023166 0ustar00paynopayno# coding: utf-8 from __future__ import annotations from silx.gui import qt from tomwer.core.scan.blissscan import BlissScan from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.scan.nxtomoscan import NXtomoScan class DatasetGeneratorDialog(qt.QDialog): sigGenerationStarted = qt.Signal() """signal emitted when the generation is started""" sigGenerationStopped = qt.Signal() """signal emitted when the generation is stopped""" sigCreateOne = qt.Signal() """signal emitted when user ask to create one dataset""" def __init__(self, parent=None): qt.QDialog.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) self.mainWidget = DatasetGeneratorConfig(parent=self) self.layout().addWidget(self.mainWidget) # add a spacer for style spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer) self._loopControlPB = qt.QPushButton("start creation in loop", self) self._loopControlPB.setCheckable(True) self._loopControlPB.setCheckable(True) self._createOnePB = qt.QPushButton("create one", self) self._buttons = qt.QDialogButtonBox(self) self._buttons.addButton(self._loopControlPB, qt.QDialogButtonBox.ActionRole) self._buttons.addButton(self._createOnePB, qt.QDialogButtonBox.ActionRole) self.layout().addWidget(self._buttons) # expose API self.getTimeout = self.mainWidget.getTimeout self.getTypeToGenerate = self.mainWidget.getTypeToGenerate self.getRootDir = self.mainWidget.getRootDir self.getNProj = self.mainWidget.getNProj self.getFrameDims = self.mainWidget.getFrameDims self.isDarkNeededAtBeginning = self.mainWidget.isDarkNeededAtBeginning self.isFlatNeededAtBeginning = self.mainWidget.isFlatNeededAtBeginning self.sigConfigChanged = self.mainWidget.sigConfigChanged # connect signal / slot self._loopControlPB.clicked.connect(self._updateControlPB) self._createOnePB.clicked.connect(self._creationOneDatasetReq) def _updateControlPB(self, *args, **kwargs): if self._loopControlPB.isChecked(): self._loopControlPB.setText("stop creation in loop") self.sigGenerationStarted.emit() else: self._loopControlPB.setText("start creation in loop") self.sigGenerationStopped.emit() def _creationOneDatasetReq(self): self.sigCreateOne.emit() def getConfiguration(self): return self.mainWidget.getConfiguration() def setConfiguration(self, config): return self.mainWidget.setConfiguration(config) class DatasetGeneratorConfig(qt.QWidget): """ Interface to define the type of dataset we want to generate """ sigConfigChanged = qt.Signal() """Signal emitted when the configuration changed""" def __init__(self, parent=None): qt.QWidget.__init__(self, parent) self.setLayout(qt.QGridLayout()) # class type to generate self._typeCB = qt.QComboBox(self) for _typeClass in ( EDFTomoScan, NXtomoScan, BlissScan, ): self._typeCB.addItem(_typeClass.__name__) self.layout().addWidget(qt.QLabel("type", self), 0, 0, 1, 1) self.layout().addWidget(self._typeCB, 0, 1, 1, 2) txt_index = self._typeCB.findText(NXtomoScan.__name__) self._typeCB.setCurrentIndex(txt_index) # generation timeout self.layout().addWidget(qt.QLabel("generate each", self), 1, 0, 1, 1) self._timeoutLE = qt.QDoubleSpinBox(self) self._timeoutLE.setValue(5) self._timeoutLE.setRange(0.0002, 9999999999999) self._timeoutLE.setSuffix("s") self.layout().addWidget(self._timeoutLE, 1, 1, 1, 2) # root folder self.layout().addWidget(qt.QLabel("root folder", self), 2, 0, 1, 1) self._rootFolderLE = qt.QLineEdit("/tmp", self) self.layout().addWidget(self._rootFolderLE, 2, 1, 1, 1) self._selectRootDirPB = qt.QPushButton("select", self) self.layout().addWidget(self._selectRootDirPB, 2, 2, 1, 1) # number of projections to include self.layout().addWidget(qt.QLabel("number of projections", self), 3, 0, 1, 1) self._nbProjQSB = qt.QSpinBox(self) self._nbProjQSB.setRange(0, 10000) self._nbProjQSB.setValue(120) self.layout().addWidget(self._nbProjQSB, 3, 1, 1, 2) # frame size self.layout().addWidget(qt.QLabel("frame dimension:", self), 4, 0, 1, 1) self._dimXQSB = qt.QSpinBox(self) self._dimXQSB.setRange(1, 4096) self._dimXQSB.setValue(128) self._dimXQSB.setPrefix("width:") self.layout().addWidget(self._dimXQSB, 4, 1, 1, 1) self._dimYQSB = qt.QSpinBox(self) self._dimYQSB.setRange(1, 4096) self._dimYQSB.setValue(128) self._dimYQSB.setPrefix("height:") self.layout().addWidget(self._dimYQSB, 4, 2, 1, 1) # dark option self._darkQCB = qt.QCheckBox("darks at the beginning", self) self._darkQCB.setChecked(True) self.layout().addWidget(self._darkQCB, 5, 0, 1, 3) # flat option self._flatQCB = qt.QCheckBox("flats at the beginning", self) self._flatQCB.setChecked(True) self.layout().addWidget(self._flatQCB, 6, 0, 1, 3) # connect signal / slot self._selectRootDirPB.released.connect(self._selectRootFolder) self._typeCB.currentIndexChanged.connect(self._signalUpdated) self._timeoutLE.valueChanged.connect(self._signalUpdated) self._rootFolderLE.editingFinished.connect(self._signalUpdated) self._darkQCB.toggled.connect(self._signalUpdated) self._flatQCB.toggled.connect(self._signalUpdated) self._dimXQSB.valueChanged.connect(self._signalUpdated) self._dimYQSB.valueChanged.connect(self._signalUpdated) def _signalUpdated(self, *args, **kwargs): self.sigConfigChanged.emit() def _selectRootFolder(self): # pragma: no cover defaultDirectory = self._outputQLE.text() dialog = qt.QFileDialog(self, directory=defaultDirectory) dialog.setFileMode(qt.QFileDialog.DirectoryOnly) if not dialog.exec(): dialog.close() return if len(dialog.selectedFiles()) > 0: self._selectRootDirPB.setText(dialog.selectedFiles()[0]) def getTimeout(self, unit: str = "s"): if unit == "ms": return self._timeoutLE.value() elif unit == "s": return self._timeoutLE.value() * 1000 else: raise ValueError("unit should be 's' or 'ms'") def setTimeout(self, timeout): self._timeoutLE.setValue(timeout) def getTypeToGenerate(self): return self._typeCB.currentText() def setTypeToGenerate(self, type_): idx = self._typeCB.findText(type_) if idx >= 0: self._typeCB.setCurrentIndex(idx) def getRootDir(self): return self._rootFolderLE.text() def setRootDir(self, root_dir): self._rootFolderLE.setText(root_dir) def getNProj(self): return self._nbProjQSB.value() def setNProj(self, n): self._nbProjQSB.setValue(int(n)) def isDarkNeededAtBeginning(self): return self._darkQCB.isChecked() def setDarkNeededAtBeginning(self, value): self._darkQCB.setChecked(value) def isFlatNeededAtBeginning(self): return self._flatQCB.isChecked() def setFlatNeededAtBeginning(self, value): self._flatQCB.setChecked(value) def getFrameDims(self): """ :return: (frame width, frame height) """ return self._dimXQSB.value(), self._dimYQSB.value() def setFrameDims(self, dims): assert len(dims) == 2, "expected two dimensions" self._dimXQSB.setValue(int(dims[0])) self._dimYQSB.setValue(int(dims[1])) def getConfiguration(self) -> dict: return { "scan_type": self.getTypeToGenerate(), "loop_timeout": self.getTimeout("ms"), "root_folder": self.getRootDir(), "n_proj": self.getNProj(), "frame_dimension": self.getFrameDims(), "dark_at_beginning": self.isDarkNeededAtBeginning(), "flat_at_beginning": self.isFlatNeededAtBeginning(), } def setConfiguration(self, config: dict): old = self.blockSignals(True) if "scan_type" in config: self.setTypeToGenerate(config["scan_type"]) if "loop_timeout" in config: self.setTimeout(config["loop_timeout"]) if "root_folder" in config: self.setRootDir(config["root_folder"]) if "n_proj" in config: self.setNProj(config["n_proj"]) if "frame_dimension" in config: self.setFrameDims(config["frame_dimension"]) if "dark_at_beginning" in config: self.setDarkNeededAtBeginning(config["dark_at_beginning"]) if "flat_at_beginning" in config: self.setFlatNeededAtBeginning(config["flat_at_beginning"]) self.blockSignals(old) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/debugtools/objectinspector.py0000644000175000017500000000307314757047403023045 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import sys from silx.gui import qt class ObjectInspector(qt.QWidget): def __init__(self, parent): qt.QWidget.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) self.__model = qt.QStandardItemModel() self._treeInspectorView = qt.QTreeView(self) self._treeInspectorView.setModel(self.__model) self.layout().addWidget(self._treeInspectorView) def setObject(self, object): self.__model.clear() root_item = qt.QStandardItem(f"{str(object)}") size_item = qt.QStandardItem(f"{sys.getsizeof(object) * 10e-6} (M bytes)") self.__model.invisibleRootItem().appendRow((root_item, size_item)) def add_sub_elmts(parent_item, python_obj): if hasattr(python_obj, "__dict__"): for i_elmt, elmt in enumerate(python_obj.__dict__): if hasattr(object, elmt): children_obj = getattr(object, elmt) # TODO: check if is a property or is a function item = qt.QStandardItem(f"{elmt}") # TODO: add size size_item = qt.QStandardItem( f"{sys.getsizeof(children_obj) * 10e-6} (M bytes)" ) parent_item.appendRow((item, size_item)) # TODO: add children add_sub_elmts(parent_item=item, python_obj=children_obj) add_sub_elmts(parent_item=root_item, python_obj=object) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9371016 tomwer-1.6.17/src/tomwer/gui/dialog/0000755000175000017500000000000015153325403016351 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/dialog/QDataDialog.py0000644000175000017500000000626215143647637021062 0ustar00paynopayno"""contains dialogs to select a Scan (aka Data)""" from __future__ import annotations import logging import os from silx.gui import qt _logger = logging.getLogger() class QDataDialog(qt.QFileDialog): """dialog to select a scans (aka data)""" def __init__(self, parent, multiSelection=False): qt.QFileDialog.__init__(self, parent) self.setNameFilters( [ "HDF5 files (*.h5 *.hdf5 *.nx *.nxs *.nexus)", "Nexus files (*.nx *.nxs *.nexus)", "Any files (*)", ] ) self._selected_files = [] self.setFileMode(qt.QFileDialog.ExistingFiles) # self.QDialogButtonBox self.multiSelection = multiSelection # check if 'TOMWER_DEFAULT_INPUT_DIR' has been set if os.environ.get("TOMWER_DEFAULT_INPUT_DIR", None) and os.path.exists( os.environ["TOMWER_DEFAULT_INPUT_DIR"] ): self.setDirectory(os.environ["TOMWER_DEFAULT_INPUT_DIR"]) elif self.directory() != os.getcwd() or str(self.directory()).startswith( "/data" ): # if the directory as already been set by the user. Avoid redefining it pass elif os.path.isdir("/data"): self.setDirectory("/data") btns = self.findChildren(qt.QPushButton) if len(btns) == 0: _logger.error( "Cannot retrieve open button. switch to none " "native QFileDialog" ) self.setOption(qt.QFileDialog.DontUseNativeDialog) btns = self.findChildren(qt.QPushButton) if self.multiSelection is True: # to make it possible to select multiple directories: self.file_view = self.findChild(qt.QListView, "listView") if self.file_view: self.file_view.setSelectionMode(qt.QAbstractItemView.MultiSelection) self.file_view.setSelectionMode(qt.QAbstractItemView.ExtendedSelection) self.f_tree_view = self.findChild(qt.QTreeView) if self.f_tree_view: self.f_tree_view.setSelectionMode(qt.QAbstractItemView.MultiSelection) self.f_tree_view.setSelectionMode( qt.QAbstractItemView.ExtendedSelection ) if len(btns) > 0: self.openBtn = [x for x in btns if "open" in str(x.text()).lower()][0] self.openBtn.clicked.disconnect() self.openBtn.hide() parent = self.openBtn.parent() self.openBtn = qt.QPushButton("Select", parent=parent) self.openBtn.clicked.connect(self.openClicked) parent.layout().insertWidget(0, self.openBtn) def openClicked(self): inds = self.f_tree_view.selectionModel().selectedIndexes() for i in inds: if i.column() == 0: self._selected_files.append( os.path.join(str(self.directory().absolutePath()), str(i.data())) ) self.accept() self.done(1) def files_selected(self): for file_ in self.selectedFiles(): self._selected_files.append(file_) return self._selected_files ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/dialog/QVolumeDialog.py0000644000175000017500000004420115143647637021453 0ustar00paynopayno"""contains dialogs to select a Volume (reconstruction of a scan)""" from __future__ import annotations import logging import os import h5py from silx.gui import qt from silx.gui.dialog.DataFileDialog import DataFileDialog from silx.gui.utils import blockSignals from silx.io.url import DataUrl from tomoscan.esrf.volume.utils import ( get_most_common_extension as get_most_common_extension, ) from tomoscan.esrf.volume.utils import guess_volumes as tomoscan_guess_volumes from tomoscan.volumebase import VolumeBase from tomwer.core.volume import ( EDFVolume, HDF5Volume, JP2KVolume, MultiTIFFVolume, RawVolume, TIFFVolume, ) from tomwer.core.volume.volumefactory import VolumeFactory as Factory from tomwer.io.utils.tomoobj import DEFAULT_SCHEME_TO_VOL from tomwer.gui.qlefilesystem import QLFileSystem from .QDataDialog import QDataDialog _logger = logging.getLogger() class QVolumeDialog(qt.QDialog): """ dialog to select / define a volume """ _EDF_EXTENSIONS = ("edf",) _TIFF_EXTENSIONS = ( "tiff", "tif", ) _JP2K_EXTENSIONS = ( "jp2", "jp2k", ) _HDF5_EXTENSIONS = ("hdf", "hdf5", "h5", "nx", "nexus") _RAW_EXTENSIONS = ( "vol", "raw", ) _VOLUME_TO_EXT = { EDFVolume: "edf", HDF5Volume: "hdf5", TIFFVolume: "tiff", MultiTIFFVolume: "tiff", JP2KVolume: "jp2", RawVolume: "vol", } def __init__(self, parent=None) -> None: super().__init__(parent) self.setLayout(qt.QGridLayout()) # add volume url self.layout().addWidget(qt.QLabel("volume url", parent=self), 0, 0, 1, 1) self._volumeUrlQL = qt.QLineEdit(parent=self) self._volumeUrlQL.setPlaceholderText("scheme:obj_type:path?queries") self._volumeUrlQL.setToolTip( "volume url defining the volume. Will be automatically updated from the other widgets" ) self.layout().addWidget(self._volumeUrlQL, 0, 1, 1, 3) # add file path self.layout().addWidget( qt.QLabel("file or folder path", parent=self), 1, 0, 1, 1 ) self._filePathQL = QLFileSystem(text="", parent=self) self._filePathQL.setToolTip( "File path (for hdf5 and multi-tiff) or folder path (for edf, jp2k, tiff...)" ) self.layout().addWidget(self._filePathQL, 1, 1, 1, 2) self._selectPathPB = qt.QPushButton("select", self) self.layout().addWidget(self._selectPathPB, 1, 3, 1, 1) # data path self.layout().addWidget( qt.QLabel("data path", parent=self), 3, 0, 1, 1, ) self._dataPathQL = qt.QLineEdit(parent=self) self._dataPathQL.setToolTip("data path for hdf5 file") self.layout().addWidget(self._dataPathQL, 3, 1, 1, 1) self._guessDataPathAuto = qt.QCheckBox("guess auto") self.layout().addWidget(self._guessDataPathAuto, 3, 2, 1, 1) self._guessDataPathAuto.setToolTip( "If checked will try to guess automatically data path from given hdf5 file" ) self._selectDataPathPB = qt.QPushButton("select", self) self.layout().addWidget(self._selectDataPathPB, 3, 3, 1, 1) # basename self.layout().addWidget( qt.QLabel("basename", parent=self), 4, 0, 1, 1, ) self._basenameQL = qt.QLineEdit(parent=self) self._basenameQL.setToolTip( "volume basename. Used for edf, tiff and jp2k volumes" ) self.layout().addWidget(self._basenameQL, 4, 1, 1, 1) self._guessBasenameAuto = qt.QCheckBox("guess auto") self.layout().addWidget(self._guessBasenameAuto, 4, 2, 1, 1) self._guessBasenameAuto.setToolTip( "If checked will try to guess automatically basename from given folder" ) # file extension self.layout().addWidget( qt.QLabel("extension", parent=self), 5, 0, 1, 1, ) self._extensionQL = qt.QLineEdit(parent=self) self._extensionQL.setToolTip("file extension") self.layout().addWidget(self._extensionQL, 5, 1, 1, 1) self._guessExtensionAuto = qt.QCheckBox("guess auto") self.layout().addWidget(self._guessExtensionAuto, 5, 2, 1, 1) self._guessExtensionAuto.setToolTip( "If checked will try to guess automatically basename from given folder" ) examples_text = """ --- extra informations. --- This dialog has been though to be work with "automatic guess" active. It should work if you didn't used any 'fancy' volumes definition. In this case providing the file path of folder path should be enought. Regarding the 'fancy' definition be aware that: \n - for an hdf5 file: expects hdf5 file path and a data_path. \n - for multitiff file: expects the file path only \n - for 'folder' volumes (edf, tiff and jp2k): expects folder, basename (default is the folder name) \n """ self._examplesQLE = qt.QTextEdit(self) self._examplesQLE.setText(examples_text) self._examplesQLE.setReadOnly(True) self.layout().addWidget(self._examplesQLE, 99, 0, 4, 4) # buttons for validation self._buttons = qt.QDialogButtonBox(self) types = qt.QDialogButtonBox.Ok | qt.QDialogButtonBox.Cancel self._buttons.setStandardButtons(types) self.layout().addWidget(self._buttons, 200, 0, 1, 4) # connect signal / slot self._buttons.button(qt.QDialogButtonBox.Ok).clicked.connect(self.accept) self._buttons.button(qt.QDialogButtonBox.Cancel).clicked.connect(self.reject) self._guessBasenameAuto.toggled.connect(self._basenameQL.setDisabled) self._guessDataPathAuto.toggled.connect(self._dataPathQL.setDisabled) self._guessExtensionAuto.toggled.connect(self._extensionQL.setDisabled) self._volumeUrlQL.textChanged.connect(self._volumeUrlChanged) self._filePathQL.textChanged.connect(self._filePathChanged) self._dataPathQL.textChanged.connect(self._dataChanged) self._basenameQL.textChanged.connect(self._basenameChanged) self._extensionQL.textChanged.connect(self._extensionChanged) self._selectPathPB.released.connect(self._selectFileOrFolder) self._selectDataPathPB.released.connect(self._selectDataPath) # set up - by default try to guess most of it automatically self._guessBasenameAuto.setChecked(True) self._guessDataPathAuto.setChecked(True) self._guessExtensionAuto.setChecked(True) def _selectFileOrFolder(self): dialog = QDataDialog(self, multiSelection=True) # AnyFile because for HDF5 a file is expected, for .edf... a folder is expected dialog.setFileMode(qt.QFileDialog.AnyFile) dialog.setNameFilters( [ "Any files (*)", "HDF5 files (*.h5 *.hdf5 *.hdf *.nx *.nxs *.nexus)", "Nexus files (*.nx *.nxs *.nexus)", "multitiff files (*.tiff *.tif)", "raw files (*.vol *.raw)", ] ) if dialog.exec() == qt.QDialog.Accepted: selected_files = dialog.selectedFiles() if len(selected_files) > 0: file_or_folder = selected_files[0] # in case the user provided a .edf, .tiff... file try to make is life simpler. if file_or_folder.endswith( ( f".{EDFVolume.DEFAULT_DATA_EXTENSION}", f".{TIFFVolume.DEFAULT_DATA_EXTENSION}", f".{JP2KVolume.DEFAULT_DATA_EXTENSION}", f".{JP2KVolume.DEFAULT_DATA_EXTENSION}", ) ): file_or_folder = os.path.dirname(file_or_folder) self.setFilePath(file_or_folder) def _selectDataPath(self): self._guessDataPathAuto.setChecked(False) file_path = self.getFilePath() if file_path in (None, "") or not h5py.is_hdf5(file_path): _logger.warning( f"{file_path} is not an hdf5 file. can't browse it to define a data path" ) return dialog = DataFileDialog(self) dialog.selectFile(file_path) if dialog.exec(): try: url = dialog.selectedUrl() url = DataUrl(path=url) if url is not None: if url.file_path() != self.getFilePath(): # in case user get data path from another file update it too with blockSignals(self._filePathQL): self.setFilePath(url.file_path()) with blockSignals(self._dataPathQL): self.setDataPath(url.data_path()) self._updateVolume_url() except Exception as e: _logger.error(e) def _volumeUrlChanged(self): url = self._volumeUrlQL.text() try: volume = Factory.create_tomo_object_from_identifier(url) except Exception as e: _logger.info(f"fail to create a volume from {url}. Error is {e}") else: try: if isinstance(volume, HDF5Volume): data_path = volume.url.data_path() file_path = volume.file_path volume_basename = "" volume_extension = os.path.splitext(volume.file_path)[-1].lstrip( "." ) # handle case no file path provided but only the extension if volume_extension == "": volume_extension = None elif isinstance(volume, MultiTIFFVolume): data_path = "" file_path = volume.file_path volume_basename = "" if volume.file_path is not None: volume_extension = os.path.splitext(volume.file_path)[ -1 ].lstrip(".") else: volume_extension = None elif isinstance(volume, (EDFVolume, TIFFVolume, JP2KVolume)): data_path = "" file_path = volume.url.file_path() volume_basename = volume.get_volume_basename() volume_extension = volume.data_extension elif isinstance(volume, RawVolume): data_path = "" file_path = volume.url.file_path() volume_basename = "" volume_extension = os.path.splitext(volume.file_path)[-1].lstrip( "." ) else: raise TypeError(f"volume type {type(volume)} is not handled") except (AttributeError, ValueError) as e: _logger.error( f"fail to update volume interface from url {url}. Error is {e}" ) if volume_extension is not None: with blockSignals(self._extensionQL): self.setDataExtension(volume_extension) assert url == self._volumeUrlQL.text() with blockSignals(self._filePathQL): self.setFilePath(file_path) assert url == self._volumeUrlQL.text() with blockSignals(self._dataPathQL): self.setDataPath(data_path) assert url == self._volumeUrlQL.text() with blockSignals(self._basenameQL): self.setVolumeBasename(volume_basename) assert url == self._volumeUrlQL.text() def _updateVolume_url(self, *args, **kwargs): volume = self.getVolume() if volume is None: return else: identifier = volume.get_identifier().to_str() with blockSignals(self._volumeUrlQL): self._volumeUrlQL.setText(identifier) def _filePathChanged(self, *args, **kwargs): guess_basename = self._guessBasenameAuto.isChecked() guess_data_path = self._guessDataPathAuto.isChecked() guess_extension = self._guessExtensionAuto.isChecked() file_path = self.getFilePath() try_guess_volume = ( guess_basename or guess_data_path or guess_extension ) and os.path.exists(file_path) if try_guess_volume: guessed_volumes = tomoscan_guess_volumes( file_path, scheme_to_vol=DEFAULT_SCHEME_TO_VOL, filter_histograms=True, ) if guessed_volumes is None or len(guessed_volumes) == 0: data_path = "" data_extension = "" basename = "" else: first_vol = guessed_volumes[0] if len(guessed_volumes) > 1: _logger.warning( f"More than one volume found in {file_path}. Will only take the first one." ) if isinstance(first_vol, HDF5Volume): data_path = first_vol.url.data_path() else: data_path = "" if os.path.isfile(file_path): _, data_extension = os.path.splitext(file_path) if data_extension == "": # in the folder use case provide a valid extension data_extension = self._VOLUME_TO_EXT[type(first_vol)] else: data_extension = data_extension.lstrip(".") else: data_extension = get_most_common_extension(file_path) or "" if isinstance(first_vol, (HDF5Volume, MultiTIFFVolume, RawVolume)): basename = "" elif isinstance(first_vol, (EDFVolume, TIFFVolume, JP2KVolume)): basename = os.path.basename(first_vol.get_volume_basename()) else: raise NotImplementedError if guess_extension: with blockSignals(self._extensionQL): self._extensionQL.setText(data_extension) if guess_basename: with blockSignals(self._basenameQL): self._basenameQL.setText(basename) if guess_data_path: with blockSignals(self._dataPathQL): self._dataPathQL.setText(data_path) self._updateVolume_url() def _dataChanged(self, *args, **kwargs): self._updateVolume_url() def _basenameChanged(self, *args, **kwargs): self._updateVolume_url() def _extensionChanged(self, *args, **kwargs): self._updateVolume_url() def setFullAuto(self, auto: bool): for widget in ( self._guessBasenameAuto, self._guessDataPathAuto, self._guessExtensionAuto, ): widget.setChecked(auto) def getFilePath(self): return self._filePathQL.text() def setFilePath(self, text): self._filePathQL.setText(text) def getDataPath(self): return self._dataPathQL.text() def setDataPath(self, text): self._dataPathQL.setText(text) def getVolumeBasename(self): return self._basenameQL.text() def setVolumeBasename(self, text: str): self._basenameQL.setText(text) def getDataExtension(self): return self._extensionQL.text() def setDataExtension(self, text): self._extensionQL.setText(text) def setVolumeUrl(self, text: str): self._volumeUrlQL.setText(text) def getVolume(self) -> VolumeBase: """ Return possible volume from current information. this function is also used to determine the volume url :warning: the return volume might not exists (at all). """ data_path = self._dataPathQL.text() file_path = self._filePathQL.text() basename = self._basenameQL.text() file_extension = self._extensionQL.text().lower().lstrip(".") single_frame_extensions = ( list(self._EDF_EXTENSIONS) + list(self._TIFF_EXTENSIONS) + list(self._JP2K_EXTENSIONS) ) if file_extension in self._TIFF_EXTENSIONS and os.path.isfile(file_path): for name, var in {"basename": basename, "data path": data_path}.items(): if var not in ("", None): _logger.warning( f"{name} provided but not used for {MultiTIFFVolume}. Will be ignored" ) return MultiTIFFVolume(file_path=file_path) if file_extension in single_frame_extensions: if file_extension in self._EDF_EXTENSIONS: constructor = EDFVolume elif file_extension in self._TIFF_EXTENSIONS: constructor = TIFFVolume elif file_extension in self._JP2K_EXTENSIONS: constructor = JP2KVolume else: raise NotImplementedError( f"unhandled file extension ({file_extension})" ) volume = constructor( folder=file_path, volume_basename=None if basename in ("", None) else basename, data_extension=self._extensionQL.text().lstrip("."), ) if data_path not in (None, ""): _logger.warning( f"{constructor} are not handling 'data path'. This information will be ignored" ) return volume elif file_extension in self._HDF5_EXTENSIONS: if basename not in ("", None): _logger.warning( f"basename provided but not used for {HDF5Volume}. Will be ignored" ) return HDF5Volume( file_path=file_path, data_path=data_path, ) elif file_extension in self._RAW_EXTENSIONS: return RawVolume(file_path=file_path) elif file_extension in (None, ""): return None ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/gui/dialog/_PortOccupyDialog.py0000644000175000017500000000530715115744275022330 0ustar00paynopaynofrom __future__ import annotations import signal from silx.gui import qt from tomwer.core.utils.process import send_signal_to_local_rpc_servers class PortOccupyDialog(qt.QDialog): """Widget for the user to send a sig kill / sig term to the port listening to bliss-tomo TomoSync json-rpc code""" def __init__(self, parent, port, host): qt.QDialog.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) self._retry = False self.port = port self.host = host mess = ( f"port ({port}) of {host} already in use. \n Maybe an other " "instance of `datalistener` is running in this session or " "another tomwer session. \n As this widget is connecting with " "bliss we enforce it to be unique." ) self.layout().addWidget(qt.QLabel(mess, self)) self.setWindowTitle("Unable to launch two listener in parallel") types = qt.QDialogButtonBox.Cancel | qt.QDialogButtonBox.Retry self._buttons = qt.QDialogButtonBox(self) self._buttons.setStandardButtons(types) self.layout().addWidget(self._buttons) self._sendSIGTERMMsb = qt.QPushButton("send SIGTERM", self) self._sendSIGTERMMsb.setToolTip( "Try to send SIGTERM signal to the " "local tomwer-rpcserver if any " "occupies the reserved port" ) self._buttons.addButton(self._sendSIGTERMMsb, qt.QDialogButtonBox.ActionRole) self._sendSIGKILLMsb = qt.QPushButton("send SIGKILL", self) self._sendSIGKILLMsb.setToolTip( "Try to send SIGKILL signal to the " "local tomwer-rpcserver if any " "occupies the reserved port" ) self._buttons.addButton(self._sendSIGKILLMsb, qt.QDialogButtonBox.ActionRole) # set up # for now we don't want to show "send signal" feature self._sendSIGTERMMsb.hide() self._sendSIGKILLMsb.hide() # connect signal / slot self._buttons.button(qt.QDialogButtonBox.Cancel).released.connect(self.reject) self._buttons.button(qt.QDialogButtonBox.Retry).released.connect( self._retry_connect ) self._sendSIGTERMMsb.released.connect(self._emitSigterm) self._sendSIGKILLMsb.released.connect(self._emitSigkill) @property def retry_connection(self): return self._retry def _emitSigterm(self, *args, **kwargs): send_signal_to_local_rpc_servers(signal.SIGTERM, port=self.port) def _emitSigkill(self, *args, **kwargs): send_signal_to_local_rpc_servers(signal.SIGKILL, port=self.port) def _retry_connect(self, *args, **kargs): self._retry = True self.accept() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/dialog/__init__.py0000644000175000017500000000013014757047403020466 0ustar00paynopayno"""Different dialog used to select TomwerObject (like a scans - aka data or volumes)""" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9371016 tomwer-1.6.17/src/tomwer/gui/edit/0000755000175000017500000000000015153325403016037 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/gui/edit/__init__.py0000644000175000017500000000013414764622416020161 0ustar00paynopayno"""Widgets related to 'control' tasks (select a scan, convert a scan with nxtomomill...)""" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/edit/dkrfpatch.py0000644000175000017500000003721015153325210020356 0ustar00paynopaynofrom __future__ import annotations import logging import h5py from silx.gui import qt from silx.gui.dialog.DataFileDialog import DataFileDialog from silx.io.url import DataUrl from silx.io.utils import h5py_read_dataset from silx.io.utils import open as open_hdf5 from nxtomo.nxobject.nxdetector import ImageKey import tomwer.core.utils.nxtomoutils as nxtomo_utils from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.io.utils import get_default_directory _logger = logging.getLogger(__name__) class _DarkOrFlatUrl(qt.QWidget): editingFinished = qt.Signal() """Signal emit when the url changes""" def __init__(self, parent, type_: ImageKey, when: str): assert when in ("start", "end") qt.QWidget.__init__(self, parent) self._type = type_ self._when = when self.setLayout(qt.QHBoxLayout()) self._qle = qt.QLineEdit("", self) self._qle.setPlaceholderText("scheme:file_path?data_path") self.layout().addWidget(self._qle) self._optionsCB = qt.QComboBox(self) self._optionsCB.addItem("full dataset") self.layout().addWidget(self._optionsCB) # connect signal / slot self._qle.editingFinished.connect(self._tryUpdateOptions) self._qle.editingFinished.connect(self.editingFinished) self._optionsCB.currentIndexChanged.connect(self.editingFinished) def setUrl(self, url): """ Define the url where the dataset can be picked If this is a dataset from an NXEntry containing dark / flat then we will propose to pick only a part of the dataset (only start / end of dark / flat) :param url: :return: """ url = self._redirectDataPath(url, logger=_logger) def dataset_invalid(url): with open_hdf5(url.file_path()) as h5s: if not isinstance(h5s[url.data_path()], h5py.Dataset): return True return False if url.data_path() in (None, "") or dataset_invalid(url): msg = qt.QMessageBox(self) msg.setIcon(qt.QMessageBox.Warning) text = "You should provide a path to a dataset or to a NXtomo entry" msg.setText(text) msg.exec() return old = self.blockSignals(True) self._qle.setText(url.path()) self._updateOptions(url) self.blockSignals(old) self.editingFinished.emit() def setSeries(self, series): type_name = self._type.name.lower().replace("_", " ") item_txt = f"{type_name} series n°{series}" idx = self._optionsCB.findText(item_txt) if idx >= 0: self._optionsCB.setCurrentIndex(idx) def getSeriesIndex(self): return self._optionsCB.currentIndex() def _redirectDataPath(self, url, logger=None): try: with open_hdf5(url.file_path()) as h5s: node = h5s[url.data_path()] if NXtomoScan.entry_is_nx_tomo(node): if ( "detector" in node["instrument"] and "data" in node["instrument"]["detector"] ): if logger: _logger.info( "NXTomo entry found. Set the directly the" "detector data" ) data_path = "/".join( (url.data_path(), "instrument", "detector", "data") ) url = DataUrl(file_path=url.file_path(), data_path=data_path) elif NXtomoScan.is_nxdetector(node): if "data" in node: if logger: _logger.info( "NX_detector entry found. Set the directly" " the detector data" ) data_path = "/".join((url.data_path, "data")) url = DataUrl(file_path=url.file_path(), data_path=data_path) except Exception: pass return url def _tryUpdateOptions(self): try: url = DataUrl(path=self._qle.text()) self._updateOptions(url) except Exception: pass def _updateOptions(self, url: DataUrl): self._optionsCB.clear() if url is None: return assert isinstance(url, DataUrl) assert h5py.is_hdf5(url.file_path()), "only manage hdf5 file" self._optionsCB.addItem("full dataset") if url.data_path() == "": _logger.error("data path should be specify") return # if we are on a 'detector / data dataset' then we can try to reach # image_key information image_keys = self._getImageKey(url) if image_keys is not None: n_series = nxtomo_utils.get_n_series( image_key_values=image_keys, image_key_type=self._type ) if n_series is not None: type_name = self._type.name.lower().replace("_", " ") series_indexes = list(range(n_series)) for i_series in series_indexes: self._optionsCB.addItem(f"{type_name} series n°{i_series}") # if this is a end url then set to the last found entry if self._when == "end": opt_idx = self._optionsCB.findText( f"{type_name} series n°{series_indexes[-1]}" ) else: # else set it to the first entry opt_idx = self._optionsCB.findText( f"{type_name} series n°{series_indexes[0]}" ) if opt_idx >= 0: self._optionsCB.setCurrentIndex(opt_idx) def _getImageKey(self, url): # if we are on a 'detector / data dataset' then we can try to reach # image_key information with open_hdf5(url.file_path()) as h5s: dataset = h5s[url.data_path()] grp_parent = dataset.parent if grp_parent is not None and NXtomoScan.is_nxdetector(grp_parent): if "image_key" in grp_parent: return h5py_read_dataset(grp_parent["image_key"]) return None def _getSlices(self, image_key_values, series_index): n_series = -1 start = None is_in_a_series = False for i_frame, frame in enumerate(image_key_values): if frame == self._type.value and not is_in_a_series: n_series += 1 is_in_a_series = True if n_series == series_index: start = i_frame elif frame != self._type.value and is_in_a_series: is_in_a_series = False if n_series == series_index: return slice(start, i_frame) if start is not None: return slice(start, len(image_key_values)) return None def getUrl(self): try: url_no_slices = DataUrl(path=self._qle.text()) series_index = self._optionsCB.currentText() if series_index in ("", None): return None if series_index == "full dataset": slices = None else: series_index = int(series_index.split("n°")[1]) slices = self._getSlices( image_key_values=self._getImageKey(url_no_slices), series_index=series_index, ) data_path = url_no_slices.data_path() url_slices = slices if url_slices is not None: url_slices = list(range(slices.start, slices.stop)) url = DataUrl( file_path=url_no_slices.file_path(), data_path=data_path, data_slice=url_slices, scheme="silx", ) except Exception as e: _logger.warning(f"Fail to create url. Reason is {e}") return None else: return url class DarkRefPatchWidget(qt.QWidget): """ Widget to add dark and flat """ sigConfigurationChanged = qt.Signal() """Signal emit when the configuration changed (url update)""" def __init__(self, parent): qt.QWidget.__init__(self, parent) self.setLayout(qt.QGridLayout()) # start dark self._sdCB = qt.QCheckBox("start dark", self) self.layout().addWidget(self._sdCB, 0, 0, 1, 1) self._sdQLE = _DarkOrFlatUrl(self, ImageKey.DARK_FIELD, when="start") self.layout().addWidget(self._sdQLE, 0, 2, 1, 1) self._selectSD = qt.QPushButton("select", self) self.layout().addWidget(self._selectSD, 0, 3, 1, 1) # start flat self._sfCB = qt.QCheckBox("start flat", self) self.layout().addWidget(self._sfCB, 1, 0, 1, 1) self._sfQLE = _DarkOrFlatUrl(self, ImageKey.FLAT_FIELD, when="start") self.layout().addWidget(self._sfQLE, 1, 2, 1, 1) self._selectSF = qt.QPushButton("select", self) self.layout().addWidget(self._selectSF, 1, 3, 1, 1) # end dark self._edCB = qt.QCheckBox("end dark ", self) self.layout().addWidget(self._edCB, 2, 0, 1, 1) self._edQLE = _DarkOrFlatUrl(self, ImageKey.DARK_FIELD, when="end") self.layout().addWidget(self._edQLE, 2, 2, 1, 1) self._selectED = qt.QPushButton("select", self) self.layout().addWidget(self._selectED, 2, 3, 1, 1) # end flat self._efCB = qt.QCheckBox("end flat", self) self.layout().addWidget(self._efCB, 3, 0, 1, 1) self._efQLE = _DarkOrFlatUrl(self, ImageKey.FLAT_FIELD, when="end") self.layout().addWidget(self._efQLE, 3, 2, 1, 1) self._selectEF = qt.QPushButton("select", self) self.layout().addWidget(self._selectEF, 3, 3, 1, 1) # signal / slot connection # connect select button self._selectSD.released.connect(self._selectSDDataset) self._selectSF.released.connect(self._selectSFDataset) self._selectED.released.connect(self._selectEDDataset) self._selectEF.released.connect(self._selectEFDataset) # set up for widget_ in ( self._sdQLE, self._selectSD, self._edQLE, self._selectED, self._sfQLE, self._selectSF, self._efQLE, self._selectEF, ): widget_.setEnabled(False) # connect checkbox buttons self._sdCB.toggled.connect(self._toggleSD) self._sfCB.toggled.connect(self._toggleSF) self._edCB.toggled.connect(self._toggleED) self._efCB.toggled.connect(self._toggleEF) # connect QLE modifications self._sdQLE.editingFinished.connect(self.sigConfigurationChanged) self._sdCB.toggled.connect(self.sigConfigurationChanged) self._sfQLE.editingFinished.connect(self.sigConfigurationChanged) self._sfCB.toggled.connect(self.sigConfigurationChanged) self._efQLE.editingFinished.connect(self.sigConfigurationChanged) self._efCB.toggled.connect(self.sigConfigurationChanged) self._edQLE.editingFinished.connect(self.sigConfigurationChanged) self._edCB.toggled.connect(self.sigConfigurationChanged) def _selectSDDataset(self): self._selectDataset("start dark", self._sdQLE) def _selectSFDataset(self): self._selectDataset("start flat", self._sfQLE) def _selectEDDataset(self): self._selectDataset("end dark", self._edQLE) def _selectEFDataset(self): self._selectDataset("end flat", self._efQLE) def _updateEnable(self, toggled, widgets): for w in widgets: w.setEnabled(toggled) def _toggleSD(self, toggled): self._updateEnable(toggled=toggled, widgets=(self._sdQLE, self._selectSD)) def _toggleSF(self, toggled): self._updateEnable(toggled=toggled, widgets=(self._sfQLE, self._selectSF)) def _toggleED(self, toggled): self._updateEnable(toggled=toggled, widgets=(self._edQLE, self._selectED)) def _toggleEF(self, toggled): self._updateEnable(toggled=toggled, widgets=(self._efQLE, self._selectEF)) def _selectDataset(self, what, outputQLE): # we can select a dataset or an entry. If this is an entry then we # will copy the target dark / flat... # ou ajouter un from: to assert isinstance(outputQLE, _DarkOrFlatUrl) dialog = DataFileDialog() dialog.setWindowTitle(what) dialog.setDirectory(get_default_directory()) if dialog.exec() and dialog.selectedDataUrl() is not None: old = outputQLE.blockSignals(True) url = dialog.selectedDataUrl() try: outputQLE.setUrl(url) except Exception as e: _logger.error(e) outputQLE.blockSignals(old) outputQLE.editingFinished.emit() def getStartDarkUrl(self) -> DataUrl | None: """ :return: url defined by the user for patching the start darks """ if self._sdCB.isChecked(): return self._sdQLE.getUrl() else: return None def getStartDarkIndex(self): return self._sdQLE.getSeriesIndex() def setStartDarkUrl(self, url: DataUrl, series_index: int | None = None) -> None: """ :param url: :param series_index: index of the series to set """ self._sdCB.setChecked(True) self._sdQLE.setUrl(url) if series_index is not None: self._sdQLE.setSeries(series_index) def getStartFlatUrl(self) -> DataUrl | None: """ :return: url defined by the user for patching the start flats """ if self._sfCB.isChecked(): return self._sfQLE.getUrl() else: return None def getStartFlatIndex(self): return self._sfQLE.getSeriesIndex() def setStartFlatUrl(self, url: DataUrl, series_index: int | None = None) -> None: """ :param url: :param series_index: index of the serie to set """ self._sfCB.setChecked(True) self._sfQLE.setUrl(url) if series_index is not None: self._sfQLE.setSeries(series_index) def getEndDarkUrl(self) -> DataUrl | None: """ :return: url defined by the user for patching the end darks """ if self._edCB.isChecked(): return self._edQLE.getUrl() else: return None def getEndDarkIndex(self): return self._edQLE.getSeriesIndex() def setEndDarkUrl(self, url: DataUrl, series_index: int | None = None) -> None: """ :param series_index: index of the serie to set """ self._edCB.setChecked(True) self._edQLE.setUrl(url) if series_index is not None: self._edQLE.setSeries(series_index) def getEndFlatUrl(self) -> DataUrl | None: """ :return: url defined by the user for patching the end flats """ if self._efCB.isChecked(): return self._efQLE.getUrl() else: return None def getEndFlatIndex(self): return self._efQLE.getSeriesIndex() def setEndFlatUrl(self, url: DataUrl, series_index: int | None = None) -> None: """ :param series_index: index of the serie to set """ self._efCB.setChecked(True) self._efQLE.setUrl(url) if series_index is not None: self._efQLE.setSeries(series_index) def clear(self): for cb in self._sdCB, self._edCB, self._efCB, self._sfCB: cb.setChecked(False) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/edit/imagekeyeditor.py0000644000175000017500000006673315153325210021426 0ustar00paynopaynofrom __future__ import annotations import functools import logging import weakref from typing import Iterable from silx.gui import qt from nxtomo.nxobject.nxdetector import ImageKey as _ImageKey from tomwer.core.process.edit.imagekeyeditor import IMAGE_KEYS from tomwer.core.scan.nxtomoscan import NXtomoScan _logger = logging.getLogger(__name__) class ImageKeyDialog(qt.QDialog): """ Dialog used to tune the ImageKey parameter. """ sigValidated = qt.Signal() """Signal send when the user validate the image keys""" def __init__(self, parent): qt.QDialog.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) self._widget = ImageKeyWindow(self) self.layout().addWidget(self._widget) types = qt.QDialogButtonBox.Ok | qt.QDialogButtonBox.Cancel self._buttons = qt.QDialogButtonBox(self) self._buttons.setStandardButtons(types) self.layout().addWidget(self._buttons) # signal / slot connection self._buttons.button(qt.QDialogButtonBox.Ok).released.connect( self._validateReleased ) self._buttons.button(qt.QDialogButtonBox.Ok).setText("validate") self._buttons.button(qt.QDialogButtonBox.Cancel).released.connect( self._resetReleased ) self._buttons.button(qt.QDialogButtonBox.Cancel).setText("reset") def _validateReleased(self, *args, **kwargs): self.sigValidated.emit() def _resetReleased(self, *args, **kwargs): self._widget.reset() def getModifications(self) -> list[int]: """ :return: list of indexes to be modified """ return self._widget.getModifications() def setModifications(self, modifications): self._widget.setModifications(modifications) def setScan(self, scan: NXtomoScan): """ :param scan: scan to be edited """ self._widget.setScan(scan) class ImageKeyWindow(qt.QMainWindow): def __init__(self, parent): qt.QMainWindow.__init__(self, parent) self.setWindowFlags(qt.Qt.Widget) # dock widget editor self._editorControl = _ImageKeyEditor(self) self._editorDockWidget = qt.QDockWidget(self) self._editorDockWidget.setWidget(self._editorControl) self._editorDockWidget.setFeatures(qt.QDockWidget.DockWidgetMovable) self.addDockWidget(qt.Qt.TopDockWidgetArea, self._editorDockWidget) # main window self._mainWindow = _ImageKeyListFiltered(parent=self) self.setCentralWidget(self._mainWindow) # signal / slot connection self._editorControl.sigApply.connect(self._updateModifications) def setScan(self, scan: NXtomoScan) -> None: """ :param scan: scan to be edited """ self._mainWindow.setScan(scan=scan) self._editorControl.setScan(scan=scan) def _updateModifications(self): modifications = self._editorControl.getModifications() to_ = self._editorControl.getUpgradeToImagKey() self._mainWindow.applyModifications( modifications=modifications, new_image_key=to_ ) def getModifications(self) -> list[int]: """ :return: list of indexes to be modified """ return self._mainWindow.getModifications() def setModifications(self, modifications): self._mainWindow.clearModifcations() image_keys_set = set(modifications.values()) image_keys_set = set([_ImageKey(image_key) for image_key in image_keys_set]) for image_key_type in image_keys_set: self._mainWindow.applyModifications( modifications=modifications, new_image_key=image_key_type ) def reset(self): self._mainWindow.reset() class _ImageKeyEditor(qt.QDialog): sigApply = qt.Signal() """Signal emitted when the user request to apply the current modifications """ def __init__(self, parent): qt.QDialog.__init__(self, parent) self.setWindowFlags(qt.Qt.Widget) self.setLayout(qt.QGridLayout()) # scan name + entry self._scanLabel = qt.QLabel("", parent=self) self.layout().addWidget(qt.QLabel("scan id"), 0, 0, 1, 1) self.layout().addWidget(self._scanLabel, 0, 1, 1, 1) # mode selection self.layout().addWidget(qt.QLabel("selection mode"), 1, 0, 1, 1) self._selectionModeCB = qt.QComboBox(self) for mode in ("range", "list"): self._selectionModeCB.addItem(mode) self._selectionModeCB.setCurrentIndex(self._selectionModeCB.findText("list")) self.layout().addWidget(self._selectionModeCB, 1, 1, 1, 1) # image selection self._selectionWidget = _EditionSelection(parent=self) self.layout().addWidget(self._selectionWidget, 2, 0, 1, 3) # upgrade to self._upgradeToLabel = qt.QLabel("Upgrade to:", self) self._upgradeToLabel.setAlignment(qt.Qt.AlignRight | qt.Qt.AlignVCenter) self.layout().addWidget(self._upgradeToLabel, 2, 3, 1, 1) self._upgradeToCB = qt.QComboBox(self) for image_key in IMAGE_KEYS: self._upgradeToCB.addItem(image_key) self.layout().addWidget(self._upgradeToCB, 2, 4, 1, 1) types = qt.QDialogButtonBox.Ok self._buttons = qt.QDialogButtonBox(self) self._buttons.setStandardButtons(types) self._buttons.button(qt.QDialogButtonBox.Ok).setText( "update modifications to apply" ) self.layout().addWidget(self._buttons, 5, 0, 1, 5) self._warningLabel = qt.QLabel( "!!! `update list` this will only modify key value on the following list. To apply modification you must `validate` those modifications", self, ) self._warningLabel.setStyleSheet("font: italic; color: red") self._warningLabel.setAlignment(qt.Qt.AlignRight) self.layout().addWidget(self._warningLabel, 6, 0, 1, 5) # setup self._selectionWidget.setSelectionMode(self._selectionModeCB.currentText()) # connect signal / slot self._selectionModeCB.currentTextChanged.connect( self._selectionWidget.setSelectionMode ) self._buttons.button(qt.QDialogButtonBox.Ok).clicked.connect(self.sigApply) def getUpgradeToImagKey(self) -> str: """ :return: selected image key as literal """ return self._upgradeToCB.currentText() def getSelectionMode(self) -> str: """ :return: frame indexes selection mode. Can be 'range' or 'list' """ return self._selectionModeCB.currentText() def getModifications(self) -> list[int]: """ :return: list of indexes to be modified """ if self.getSelectionMode() == "range": return self._selectionWidget.getSlice() elif self.getSelectionMode() == "list": return self._selectionWidget.getList() else: raise NotImplementedError("Not implemented") def setScan(self, scan): self._selectionWidget.setScan(scan=scan) if scan is not None: self._scanLabel.setText(scan.get_identifier().to_str()) else: self._scanLabel.setText("") class _SliceSelection(qt.QWidget): """ Widget used to define a set of frames from a range """ def __init__(self, parent): qt.QWidget.__init__(self, parent) self.setLayout(qt.QHBoxLayout()) # from self._fromLabel = qt.QLabel("from: ", self) self._fromLabel.setAlignment(qt.Qt.AlignRight | qt.Qt.AlignVCenter) self.layout().addWidget(self._fromLabel) self._fromQLE = qt.QSpinBox(self) self._fromQLE.setRange(0, 1000000) self.layout().addWidget(self._fromQLE) # to self._toLabel = qt.QLabel("to: ", self) self._toLabel.setAlignment(qt.Qt.AlignRight | qt.Qt.AlignVCenter) self.layout().addWidget(self._toLabel) self._toQLE = qt.QSpinBox(self) self._toQLE.setRange(0, 1000000) self.layout().addWidget(self._toQLE) # steps self._stepsLabel = qt.QLabel("steps: ", self) self._stepsLabel.setAlignment(qt.Qt.AlignRight | qt.Qt.AlignVCenter) self.layout().addWidget(self._stepsLabel) self._stepsQLE = qt.QSpinBox(self) self._stepsQLE.setRange(1, 1000000) self.layout().addWidget(self._stepsQLE) def getSlice(self) -> slice: """ :return: slice defined """ return slice(self._fromQLE.value(), self._toQLE.value(), self._stepsQLE.value()) class _ListSelection(qt.QWidget): """ Widget to define a list of frames """ def __init__(self, parent): qt.QWidget.__init__(self, parent) self._scan = None self.setLayout(qt.QHBoxLayout()) # list selection self._listQLE = qt.QLineEdit("", self) self._listQLE.setPlaceholderText("0, 8, -1, ...") self.layout().addWidget(self._listQLE) reg_exp = qt.QRegularExpression(r"(\d+)(,[ ]?\s*\d+)*") # list of int with optional space validator = qt.QRegularExpressionValidator(reg_exp) self._listQLE.setValidator(validator) # select button self._selectButton = qt.QPushButton("select", self) self.layout().addWidget(self._selectButton) # signal / slot selection self._selectButton.released.connect(self._selectFrames) def _selectFrames(self): if self._scan is None or self._scan() is None: _logger.warning( "No scan set or has been moved. Unable to select slices from it." ) return scan = self._scan() dialog = _FrameSelectionDialog(parent=self) dialog.setFrames(scan.frames) if dialog.exec(): frame_indexes = dialog.getSelectedFrameIndexes() return self.setList(frame_indexes) def getList(self) -> list[int]: """ :return: list of indexes selected """ text = self._listQLE.text() text = text.replace(" ", "") if text == "": return [] else: return [int(element) for element in text.split(",")] def setList(self, list_: str | Iterable[str]): """ :param list_: """ if isinstance(list_, str): txt = list_ else: txt = ", ".join(str(elmt) for elmt in list_) self._listQLE.setText(txt) def setScan(self, scan): self._scan = weakref.ref(scan) class _EditionSelection(qt.QWidget): def __init__(self, parent): qt.QWidget.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) # slice selection self._sliceSelection = _SliceSelection(parent=self) self.layout().addWidget(self._sliceSelection) self._listSelection = _ListSelection(parent=self) self.layout().addWidget(self._listSelection) def setSelectionMode(self, mode: str) -> None: """ :param mode: define indexes selection mode. Can be 'range' or 'list' """ if mode == "slice": # for backward compatibility (user can have .ows with old name) mode = "range" assert mode in ("range", "list") self._sliceSelection.setVisible(mode == "range") self._listSelection.setVisible(mode == "list") def getList(self) -> list: return self._listSelection.getList() def getSlice(self) -> slice: return self._sliceSelection.getSlice() def setScan(self, scan): self._listSelection.setScan(scan) class _ImageKeyComboBox(qt.QComboBox): def __init__(self, parent, image_key): qt.QComboBox.__init__(self, parent) for img_key_type in IMAGE_KEYS: self.addItem(img_key_type) self.setImageKey(image_key) def setImageKey(self, image_key): if image_key in _ImageKeyList._IMAGE_KEYS_INV: image_key = _ImageKeyList._IMAGE_KEYS_INV[image_key] idx = self.findText(image_key) assert idx >= 0, "image key not recognized" self.setCurrentIndex(idx) class _ImageKeyList(qt.QTableWidget): sigKeyUpdated = qt.Signal(tuple) """Signal emitted when a key has been updated. tuple contains (frame index, ImageKey)""" COLUMNS = ( "index", "current image type", "new image type", ) _IMAGE_KEYS_INV = {v: k for k, v in IMAGE_KEYS.items()} def __init__(self, parent): qt.QTableWidget.__init__(self, parent) self._filterMode = None self.__frames_modifications = {} """contains new and old values""" self._imageKeyComboboxes = {} """Qt / python needs to keep a pointer on those""" def setFilterMode(self, mode: str) -> None: """ Define the filter mode to use and update the QTableWidget :param mode: filtering mode """ self._filterMode = mode self.updateFiltering() def clear(self) -> None: self._imageKeyComboboxes.clear() qt.QTableWidget.clear(self) def setFrames(self, frames: Iterable, frames_new_keys: dict) -> None: """ Update the QTableWidget for the provided frames :param frames: Iterable of tomoscan.esrf.scan.NXtomoScan.Frame :param frames_new_keys: dictionary with frame edited. key is frame index. Value is the new `image_key` value """ self.clear() self.setRowCount(len(frames)) self.setColumnCount(len(self.COLUMNS)) self.setHorizontalHeaderLabels(self.COLUMNS) self.horizontalHeader().setSectionResizeMode(qt.QHeaderView.ResizeToContents) self.verticalHeader().hide() for i_frame, frame in enumerate(frames): # frame index index = frame.index _item = qt.QTableWidgetItem() _item.setText(str(index)) _item.setFlags(qt.Qt.ItemIsEnabled | qt.Qt.ItemIsSelectable) _item.setData(qt.Qt.UserRole, weakref.ref(frame)) self.setItem(i_frame, 0, _item) # current image key current_image_key = _ImageKey(frame.image_key) current_image_key = self._IMAGE_KEYS_INV[current_image_key] currentImgKeyItem = qt.QLabel(current_image_key, self) self.setCellWidget(i_frame, 1, currentImgKeyItem) # new image key if frame.index in frames_new_keys: new_image_key = frames_new_keys[frame.index] else: new_image_key = frame.image_key new_image_key = _ImageKey(new_image_key) new_image_key = self._IMAGE_KEYS_INV[new_image_key] newImgKeyItem = _ImageKeyComboBox(parent=self, image_key=new_image_key) self._imageKeyComboboxes[index] = newImgKeyItem callback = functools.partial(self.notify_modified, frame.index) newImgKeyItem.currentIndexChanged.connect(callback) self.setCellWidget(i_frame, 2, newImgKeyItem) self.updateFiltering() def clearFrameModifications(self) -> None: """ undo modifications """ for frame_index in self.__frames_modifications: item_index = self._getFrameRowIndex(frame_index) if item_index: frame_item = self.item(item_index, 0).data(qt.Qt.UserRole) if frame_item() is not None: new_image_key = frame_item().image_key new_image_key = self._IMAGE_KEYS_INV[new_image_key] old = self._imageKeyComboboxes[frame_index].blockSignals(True) self._imageKeyComboboxes[frame_index].setImageKey(new_image_key) self._imageKeyComboboxes[frame_index].blockSignals(old) self.__frames_modifications = {} self.updateFiltering() def applyModifications( self, modifications: Iterable, new_image_key: _ImageKey ) -> None: """ Update the current QTableWidget with provided modications :param modifications: iterable of frame indexes to be modify :param new_image_key: new `image_key` value """ if isinstance(modifications, slice): sl = modifications my_list = list(range(sl.start, sl.stop, sl.step)) else: my_list = modifications to_apply = {} for frame_index in my_list: assert isinstance(frame_index, int), "frame_index should be an int" to_apply[frame_index] = new_image_key if frame_index in self._imageKeyComboboxes: self._imageKeyComboboxes[frame_index].setImageKey(new_image_key) for _, value in to_apply.items(): assert isinstance(value, _ImageKey), "values should be instance of" + str( _ImageKey ) self.__frames_modifications.update(to_apply) self.updateFiltering() def updateFiltering(self) -> None: for i in range(self.rowCount()): frame = self.item(i, 0).data(qt.Qt.UserRole)() if not frame: continue if self._filterMode is None: return if self._filterMode == _ImageKeyListFiltered.ALL_IMG_FILTER: visible = True elif self._filterMode == _ImageKeyListFiltered.MODIFIED_IMG_FILTER: visible = frame.index in self.__frames_modifications else: visible = frame.image_key == IMAGE_KEYS[self._filterMode] if visible: self.showRow(i) else: self.hideRow(i) def notify_modified(self, frame_index: int) -> None: """ Update list of modification and emit sigKeyUpdated :param frame_index: """ assert isinstance(frame_index, int), "frame index should be an int" frame_row = self._getFrameRowIndex(frame_index) if frame_row is not None: new_image_key = self._imageKeyComboboxes[frame_index].currentText() new_image_key = IMAGE_KEYS[new_image_key] self.__frames_modifications[frame_index] = new_image_key self.sigKeyUpdated.emit((frame_index, new_image_key)) def _getFrameRowIndex(self, frame_index): for i in range(self.rowCount()): frame = self.item(i, 0).data(qt.Qt.UserRole)() if frame and frame.index == frame_index: return i return None def getModifications(self): return self.__frames_modifications class _ImageKeyListFiltered(qt.QWidget): MODIFIED_IMG_FILTER = "modified" ALL_IMG_FILTER = "all" sigFilterchanged = qt.Signal() """Signal emitted when the filter to apply change""" def __init__(self, parent): qt.QWidget.__init__(self) self.setLayout(qt.QGridLayout()) """Expected frames type once modifications will be done""" # add filter self.layout().addWidget(qt.QLabel("image filter:"), 0, 0, 1, 1) self._filterCB = qt.QComboBox(self) for filter_name in IMAGE_KEYS: self._filterCB.addItem(filter_name) self._filterCB.addItem(_ImageKeyListFiltered.MODIFIED_IMG_FILTER) self._filterCB.addItem(_ImageKeyListFiltered.ALL_IMG_FILTER) self.layout().addWidget(self._filterCB) # add TableWidget self._imageKeyList = _ImageKeyList(self) self.layout().addWidget(self._imageKeyList) # set up self._filterCB.setCurrentIndex( self._filterCB.findText(_ImageKeyListFiltered.ALL_IMG_FILTER) ) self._updateFilter() # connect signal / slot self._filterCB.currentIndexChanged.connect(self._updateFilter) def applyModifications(self, modifications: slice | list, new_image_key): if new_image_key in IMAGE_KEYS: new_image_key = IMAGE_KEYS[new_image_key] self._imageKeyList.applyModifications(modifications, new_image_key) def reset(self): self._imageKeyList.clearFrameModifications() def getModifications(self): return self._imageKeyList.getModifications() def clearModifcations(self): self._imageKeyList.clearFrameModifications() def getFilerMode(self): return self._filterCB.currentText() def setScan(self, scan): if not isinstance(scan, NXtomoScan): raise TypeError( f"scan should be an instance of {NXtomoScan}. {type(scan)} provided" ) self.__frames_modifications = {} self._scan = weakref.ref(scan) frames = scan.frames self._imageKeyList.setFrames(frames, self.__frames_modifications) def _updateFilter(self): self._imageKeyList.setFilterMode(mode=self.getFilerMode()) self._imageKeyList.updateFiltering() class _FrameSelectionDialog(qt.QDialog): def __init__(self, parent): qt.QDialog.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) # list widget self._listWidget = qt.QListWidget(parent=self) self._listWidget.setSelectionMode(qt.QAbstractItemView.ExtendedSelection) self.layout().addWidget(self._listWidget) # add buttons types = qt.QDialogButtonBox.Ok | qt.QDialogButtonBox.Cancel self._buttons = qt.QDialogButtonBox(self) self._buttons.setStandardButtons(types) self.layout().addWidget(self._buttons) # connect signal / slot self._buttons.button(qt.QDialogButtonBox.Ok).clicked.connect(self.accept) self._buttons.button(qt.QDialogButtonBox.Cancel).clicked.connect(self.reject) def setFrames(self, frames): item_texts = [] for frame in frames: item_texts.append(f"{frame.index} ({frame.image_key.value})") self._listWidget.addItems(item_texts) def getSelectedFrameIndexes(self): item_selected = self._listWidget.selectedItems() def get_index(my_str): return int(my_str.replace(" ", "").split("(")[0]) return [get_index(item.text()) for item in item_selected] class ImageKeyUpgraderList(qt.QTableWidget): """ List defining image key upgrade operations so to upgrade all frames with a specific Image_key to another image_key """ COLUMNS = ("operations", "remove") sigOperationsChanged = qt.Signal() """signal emit when the operations changed""" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._operations = {} # operations. dict with image_key 'from' as key and image_key to as value. # this ensure we will not ask for contradictory operations (like upgrading one image_key to two different image_key) self._update() def getOperations(self) -> tuple: return self._operations def setOperations(self, operations: dict): self._operations.clear() for from_image_key, to_image_key in operations.items(): self.addOperation(from_image_key=from_image_key, to_image_key=to_image_key) def _update(self): self.setColumnCount(len(self.COLUMNS)) self.setRowCount(len(self._operations)) self.setHorizontalHeaderLabels(self.COLUMNS) self.horizontalHeader().setSectionResizeMode(qt.QHeaderView.ResizeToContents) self.verticalHeader().hide() for i_operation, (from_image_key, to_image_key) in enumerate( self._operations.items() ): item_info = qt.QTableWidgetItem() item_info.setText( f"convert all `{_ImageKeyList._IMAGE_KEYS_INV[from_image_key]}` frames to `{_ImageKeyList._IMAGE_KEYS_INV[to_image_key]}`" ) self.setItem(i_operation, 0, item_info) remove_button = qt.QPushButton(parent=self) style = qt.QApplication.style() stopIcon = style.standardIcon(qt.QStyle.SP_DialogCloseButton) remove_button.setIcon(stopIcon) remove_button.released.connect( functools.partial( self.removeOperation, from_image_key, to_image_key, ) ) self.setCellWidget(i_operation, 1, remove_button) def addOperation(self, from_image_key: _ImageKey, to_image_key: _ImageKey): from_image_key = _ImageKey(from_image_key) to_image_key = _ImageKey(to_image_key) self._operations[from_image_key] = to_image_key self._update() self.sigOperationsChanged.emit() def removeOperation(self, from_image_key: _ImageKey, to_image_key: _ImageKey): from_image_key = _ImageKey(from_image_key) to_image_key = _ImageKey(to_image_key) if ( from_image_key not in self._operations or self._operations[from_image_key] != to_image_key ): return self._operations.pop(from_image_key) self._update() self.sigOperationsChanged.emit() class _AddImageKeyUpgradeOperation(qt.QGroupBox): sigOperationAdded = qt.Signal(dict) """Signal emit when a new operation is requested. Dict contains keys 'from_image_key' and 'to_image_key' to define the operation""" def __init__(self, title="add operation", *args, **kwargs): super().__init__(title=title, *args, **kwargs) self.setLayout(qt.QHBoxLayout()) self.layout().addWidget(qt.QLabel("from")) self._fromCB = _ImageKeyComboBox(parent=self, image_key=_ImageKey.PROJECTION) self.layout().addWidget(self._fromCB) self.layout().addWidget(qt.QLabel("to")) self._toCB = _ImageKeyComboBox(parent=self, image_key=_ImageKey.DARK_FIELD) self.layout().addWidget(self._toCB) self._addButtonPB = qt.QPushButton("add") self.layout().addWidget(self._addButtonPB) # signal / slot connection self._addButtonPB.released.connect(self._addButtonCallback) def _addButtonCallback(self, *args, **kwargs): self.sigOperationAdded.emit(self._getCurrentOperation()) def _getCurrentOperation(self): return { "from_image_key": IMAGE_KEYS[self._fromCB.currentText()].value, "to_image_key": IMAGE_KEYS[self._toCB.currentText()].value, } class ImageKeyUpgraderWidget(qt.QWidget): """ Main widget to define ImageKey upgrade operations. Will upgrade all image_key within a specific value to another value. """ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setLayout(qt.QVBoxLayout()) self._addOperationWidget = _AddImageKeyUpgradeOperation(parent=self) self.layout().addWidget(self._addOperationWidget) self._operationList = ImageKeyUpgraderList(parent=self) self.layout().addWidget(self._operationList) # connect signal / slot self._addOperationWidget.sigOperationAdded.connect(self._addOperationCallback) # expose signal self.sigOperationsChanged = self._operationList.sigOperationsChanged def _addOperationCallback(self, operation_as_dict: dict): return self.addOperation(**operation_as_dict) # exposing some API def getOperations(self) -> tuple: return self._operationList.getOperations() def addOperation(self, from_image_key: _ImageKey, to_image_key: _ImageKey): self._operationList.addOperation( from_image_key=from_image_key, to_image_key=to_image_key ) def removeOperation(self, from_image_key: _ImageKey, to_image_key: _ImageKey): self._operationList.removeOperation( from_image_key=from_image_key, to_image_key=to_image_key ) def setOperations(self, operations: dict): return self._operationList.setOperations(operations=operations) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/edit/nxtomoeditor.py0000644000175000017500000010535115153325210021145 0ustar00paynopaynofrom __future__ import annotations import logging import weakref import pint import numpy from silx.gui import qt from nxtomo.nxobject.nxdetector import ImageKey, FOV from nxtomo.paths.nxtomo import LATEST_VERSION as _LATEST_NXTOMO_VERSION from tomwer.core.process.edit.nxtomoeditor import NXtomoEditorKeys from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.gui.utils.buttons import PadlockButton from tomwer.gui.utils.scandescription import ScanNameLabelAndShape from tomwer.gui.utils.unitsystem import MetricEntry from tomwer.gui.edit.nxtomowarmer import NXtomoProxyWarmer _logger = logging.getLogger(__name__) _ureg = pint.get_application_registry() class NXtomoEditorDialog(qt.QDialog): """ Dialog embedding instances of NXtomoEditor and NXtomoProxyWarmer """ def __init__(self, parent=None, hide_lockers=True) -> None: super().__init__(parent) self.setLayout(qt.QVBoxLayout()) self.mainWidget = NXtomoEditor(parent=self, hide_lockers=hide_lockers) self.layout().addWidget(self.mainWidget) self._warmer = NXtomoProxyWarmer(parent=self) self.layout().addWidget(self._warmer) types = qt.QDialogButtonBox.Ok self._buttons = qt.QDialogButtonBox(parent=self) self._buttons.setStandardButtons(types) self._buttons.button(qt.QDialogButtonBox.Ok).setText("validate") self.layout().addWidget(self._buttons) # expose API def setScan(self, scan: NXtomoScan) -> None: self.mainWidget.setScan(scan) self._warmer.setScan(scan) def hasLockField(self) -> bool: return self.mainWidget.hasLockField() def getConfiguration(self) -> dict: return self.mainWidget.getConfiguration() def setConfiguration(self, config: dict) -> None: self.mainWidget.setConfiguration(config) def getConfigurationForTask(self) -> dict: return self.mainWidget.getConfigurationForTask() class NXtomoEditor(qt.QWidget): """ Widget to edit a set of field from a NXtomo. The preliminary goal is to let the user define pixel / voxel position and x and z positions in order to simplify stitching down the line As energy and field of view was also often requested this part is also editable. Each field contains a widget to define it values and a LockButton. The LockButton can be used to automate the processing. When the scan to edit is set each field widget will be updated **at the condition** the field is not locked. Else existing value will be kept. """ sigEditingFinished = qt.Signal() """emit when edition is finished""" def __init__(self, parent=None, hide_lockers=True): super().__init__(parent) self._editableWidgets = [] self._lockerPBs = [] # list of all lockers self._scan = None self.setLayout(qt.QVBoxLayout()) self._scanInfoQLE = ScanNameLabelAndShape(parent=self) self.layout().addWidget(self._scanInfoQLE) # nxtomo tree self._tree = qt.QTreeWidget(self) if hide_lockers: self._tree.setColumnCount(2) self._tree.setHeaderLabels(("entry", "value")) else: self._tree.setColumnCount(3) self._tree.setHeaderLabels(("entry", "value", "lockers")) self._tree.header().setStretchLastSection(False) self._tree.setColumnWidth(2, 20) self._tree.header().setSectionResizeMode(1, qt.QHeaderView.Stretch) self.layout().addWidget(self._tree) # 1: instrument self._instrumentQTWI = qt.QTreeWidgetItem(self._tree) self._instrumentQTWI.setText(0, "instrument") # handle energy self._beamQTWI = qt.QTreeWidgetItem(self._instrumentQTWI) self._beamQTWI.setText(0, "beam") self._energyQTWI = qt.QTreeWidgetItem(self._beamQTWI) self._energyQTWI.setText(0, "energy (keV)") self._energyEntry = EnergyEntry("", self) self._energyEntry.setPlaceholderText("energy in kev") self._tree.setItemWidget(self._energyQTWI, 1, self._energyEntry) self._editableWidgets.append(self._energyEntry) self._energyLockerLB = PadlockButton(self) self._energyLockerLB.setMaximumSize(30, 30) self._lockerPBs.append(self._energyLockerLB) self._tree.setItemWidget(self._energyQTWI, 2, self._energyLockerLB) # 1.1 detector self._detectorQTWI = qt.QTreeWidgetItem(self._instrumentQTWI) self._detectorQTWI.setText(0, "detector") ## pixel size self._xDetectorPixelSizeQTWI = qt.QTreeWidgetItem(self._detectorQTWI) self._xDetectorPixelSizeQTWI.setText(0, "x pixel size") self._xDetectorPixelSizeMetricEntry = MetricEntry("", parent=self) self._xDetectorPixelSizeMetricEntry.layout().setContentsMargins(2, 2, 2, 2) self._tree.setItemWidget( self._xDetectorPixelSizeQTWI, 1, self._xDetectorPixelSizeMetricEntry ) self._editableWidgets.append(self._xDetectorPixelSizeMetricEntry) self._xDetectorPixelSizeLB = PadlockButton(self) self._xDetectorPixelSizeLB.setMaximumSize(30, 30) self._lockerPBs.append(self._xDetectorPixelSizeLB) self._tree.setItemWidget( self._xDetectorPixelSizeQTWI, 2, self._xDetectorPixelSizeLB ) self._yDetectorPixelSizeQTWI = qt.QTreeWidgetItem(self._detectorQTWI) self._yDetectorPixelSizeQTWI.setText(0, "y pixel size") self._yDetectorPixelSizeMetricEntry = MetricEntry("", parent=self) self._yDetectorPixelSizeMetricEntry.layout().setContentsMargins(2, 2, 2, 2) self._tree.setItemWidget( self._yDetectorPixelSizeQTWI, 1, self._yDetectorPixelSizeMetricEntry ) self._editableWidgets.append(self._yDetectorPixelSizeMetricEntry) self._yDetectorPixelSizeLB = PadlockButton(self) self._yDetectorPixelSizeLB.setMaximumSize(30, 30) self._lockerPBs.append(self._yDetectorPixelSizeLB) self._tree.setItemWidget( self._yDetectorPixelSizeQTWI, 2, self._yDetectorPixelSizeLB ) ## sample - distance self._sampleDetectorDistanceQTWI = qt.QTreeWidgetItem(self._detectorQTWI) self._sampleDetectorDistanceQTWI.setText(0, "sample-detector distance") self._sampleDetectorDistanceMetricEntry = MetricEntry("", parent=self) self._sampleDetectorDistanceMetricEntry.layout().setContentsMargins(2, 2, 2, 2) self._tree.setItemWidget( self._sampleDetectorDistanceQTWI, 1, self._sampleDetectorDistanceMetricEntry ) self._editableWidgets.append(self._sampleDetectorDistanceMetricEntry) self._sampleDetectorDistanceLB = PadlockButton(self) self._sampleDetectorDistanceLB.setMaximumSize(30, 30) self._lockerPBs.append(self._sampleDetectorDistanceLB) self._tree.setItemWidget( self._sampleDetectorDistanceQTWI, 2, self._sampleDetectorDistanceLB ) ## field of view self._fieldOfViewQTWI = qt.QTreeWidgetItem(self._detectorQTWI) self._fieldOfViewQTWI.setText(0, "field of view") self._fieldOfViewCB = qt.QComboBox(self) for FOV_item in FOV: self._fieldOfViewCB.addItem(FOV_item.value) self._tree.setItemWidget(self._fieldOfViewQTWI, 1, self._fieldOfViewCB) self._editableWidgets.append(self._fieldOfViewCB) self._fieldOfViewLB = PadlockButton(self) self._fieldOfViewLB.setMaximumSize(30, 30) self._lockerPBs.append(self._fieldOfViewLB) self._tree.setItemWidget(self._fieldOfViewQTWI, 2, self._fieldOfViewLB) ## x flipped self._lrFlippedQTWI = qt.QTreeWidgetItem(self._detectorQTWI) self._lrFlippedQTWI.setText(0, "lr flipped") self._lrFlippedCB = qt.QCheckBox("", self) self._tree.setItemWidget(self._lrFlippedQTWI, 1, self._lrFlippedCB) self._editableWidgets.append(self._lrFlippedCB) self._lrFlippedLB = PadlockButton(self) self._lrFlippedLB.setMaximumSize(30, 30) self._lockerPBs.append(self._lrFlippedLB) self._tree.setItemWidget(self._lrFlippedQTWI, 2, self._lrFlippedLB) ## y flipped self._udFlippedQTWI = qt.QTreeWidgetItem(self._detectorQTWI) self._udFlippedQTWI.setText(0, "ud flipped") self._udFlippedCB = qt.QCheckBox("", self) self._tree.setItemWidget(self._udFlippedQTWI, 1, self._udFlippedCB) self._editableWidgets.append(self._udFlippedCB) self._udFlippedLB = PadlockButton(self) self._udFlippedLB.setMaximumSize(30, 30) self._lockerPBs.append(self._udFlippedLB) self._tree.setItemWidget(self._udFlippedQTWI, 2, self._udFlippedLB) # source self._sourceQTWI = qt.QTreeWidgetItem(self._instrumentQTWI) self._sourceQTWI.setText(0, "source") ## source - sample self._sampleSourceDistanceQTWI = qt.QTreeWidgetItem(self._sourceQTWI) self._sampleSourceDistanceQTWI.setText(0, "sample-source distance") self._sampleSourceDistanceMetricEntry = MetricEntry("", parent=self) self._sampleSourceDistanceMetricEntry.setToolTip( "sample-source distance. Expected to be negative" ) self._sampleSourceDistanceMetricEntry.layout().setContentsMargins(2, 2, 2, 2) self._tree.setItemWidget( self._sampleSourceDistanceQTWI, 1, self._sampleSourceDistanceMetricEntry ) self._editableWidgets.append(self._sampleSourceDistanceMetricEntry) self._sampleSourceDistanceLB = PadlockButton(self) self._sampleSourceDistanceLB.setMaximumSize(30, 30) self._lockerPBs.append(self._sampleSourceDistanceLB) self._tree.setItemWidget( self._sampleSourceDistanceQTWI, 2, self._sampleSourceDistanceLB ) # 2: sample self._sampleQTWI = qt.QTreeWidgetItem(self._tree) self._sampleQTWI.setText(0, "sample") # ## pixel size self._xSamplePixelSizeQTWI = qt.QTreeWidgetItem(self._sampleQTWI) self._xSamplePixelSizeQTWI.setText(0, "x pixel size") self._xSamplePixelSizeMetricEntry = MetricEntry("", parent=self) self._xSamplePixelSizeMetricEntry.layout().setContentsMargins(2, 2, 2, 2) self._tree.setItemWidget( self._xSamplePixelSizeQTWI, 1, self._xSamplePixelSizeMetricEntry ) self._editableWidgets.append(self._xSamplePixelSizeMetricEntry) self._xSamplePixelSizeLB = PadlockButton(self) self._xSamplePixelSizeLB.setMaximumSize(30, 30) self._lockerPBs.append(self._xSamplePixelSizeLB) self._tree.setItemWidget( self._xSamplePixelSizeQTWI, 2, self._xSamplePixelSizeLB ) self._ySamplePixelSizeQTWI = qt.QTreeWidgetItem(self._sampleQTWI) self._ySamplePixelSizeQTWI.setText(0, "y pixel size") self._ySamplePixelSizeMetricEntry = MetricEntry("", parent=self) self._ySamplePixelSizeMetricEntry.layout().setContentsMargins(2, 2, 2, 2) self._tree.setItemWidget( self._ySamplePixelSizeQTWI, 1, self._ySamplePixelSizeMetricEntry ) self._editableWidgets.append(self._ySamplePixelSizeMetricEntry) self._ySamplePixelSizeLB = PadlockButton(self) self._ySamplePixelSizeLB.setMaximumSize(30, 30) self._lockerPBs.append(self._ySamplePixelSizeLB) self._tree.setItemWidget( self._ySamplePixelSizeQTWI, 2, self._ySamplePixelSizeLB ) ## propagation distance self._propagationDistanceQTWI = qt.QTreeWidgetItem(self._sampleQTWI) self._propagationDistanceQTWI.setText(0, "propagation distance") self._propagationDistanceMetricEntry = MetricEntry("", parent=self) self._propagationDistanceMetricEntry.layout().setContentsMargins(2, 2, 2, 2) self._tree.setItemWidget( self._propagationDistanceQTWI, 1, self._propagationDistanceMetricEntry ) self._editableWidgets.append(self._propagationDistanceMetricEntry) self._propagationDistanceLB = PadlockButton(self) self._propagationDistanceLB.setMaximumSize(30, 30) self._lockerPBs.append(self._propagationDistanceLB) self._tree.setItemWidget( self._propagationDistanceQTWI, 2, self._propagationDistanceLB ) ## x translation self._xTranslationQTWI = qt.QTreeWidgetItem(self._sampleQTWI) self._xTranslationQTWI.setText(0, "x translation") self._xTranslationQLE = _TranslationMetricEntry(name="", parent=self) self._tree.setItemWidget(self._xTranslationQTWI, 1, self._xTranslationQLE) self._editableWidgets.append(self._xTranslationQLE) ## z translation self._zTranslationQTWI = qt.QTreeWidgetItem(self._sampleQTWI) self._zTranslationQTWI.setText(0, "z translation") self._zTranslationQLE = _TranslationMetricEntry(name="", parent=self) self._tree.setItemWidget(self._zTranslationQTWI, 1, self._zTranslationQLE) self._editableWidgets.append(self._zTranslationQLE) # set up self._instrumentQTWI.setExpanded(True) self._sampleQTWI.setExpanded(True) self._beamQTWI.setExpanded(True) self._detectorQTWI.setExpanded(True) self.hideLockers(hide_lockers) # connect signal / slot self._energyEntry.editingFinished.connect(self._editingFinished) self._energyLockerLB.toggled.connect(self._editingFinished) self._xDetectorPixelSizeMetricEntry.editingFinished.connect( self._editingFinished ) self._xDetectorPixelSizeLB.toggled.connect(self._editingFinished) self._yDetectorPixelSizeMetricEntry.editingFinished.connect( self._editingFinished ) self._yDetectorPixelSizeLB.toggled.connect(self._editingFinished) self._xSamplePixelSizeMetricEntry.editingFinished.connect(self._editingFinished) self._xSamplePixelSizeLB.toggled.connect(self._editingFinished) self._ySamplePixelSizeMetricEntry.editingFinished.connect(self._editingFinished) self._ySamplePixelSizeLB.toggled.connect(self._editingFinished) self._sampleDetectorDistanceMetricEntry.editingFinished.connect( self._editingFinished ) self._sampleDetectorDistanceLB.toggled.connect(self._editingFinished) self._propagationDistanceMetricEntry.editingFinished.connect( self._editingFinished ) self._propagationDistanceLB.toggled.connect(self._editingFinished) self._fieldOfViewCB.currentIndexChanged.connect(self._editingFinished) self._fieldOfViewLB.toggled.connect(self._editingFinished) self._lrFlippedCB.toggled.connect(self._editingFinished) self._lrFlippedLB.toggled.connect(self._editingFinished) self._udFlippedCB.toggled.connect(self._editingFinished) self._udFlippedLB.toggled.connect(self._editingFinished) def update_tree(self) -> None: scan = self.getScan() if scan is not None: self._updateInstrument() self._updateSample() self._updateSource() self._tree.resizeColumnToContents(0) # update items according to NXtomo nexus version nexus_version = scan.nexus_version if nexus_version is None: nexus_version = _LATEST_NXTOMO_VERSION # handle nxtomo 1.4 version allow_source_sample_distance = bool(nexus_version >= 1.4) self._sampleSourceDistanceMetricEntry.setEnabled( allow_source_sample_distance ) self._sampleSourceDistanceLB.setEnabled(allow_source_sample_distance) # handle nxtomo 1.5 version allow_sample_pixel_size_and_prop_distance = bool(nexus_version >= 1.5) self._xSamplePixelSizeMetricEntry.setEnabled( allow_sample_pixel_size_and_prop_distance ) self._xSamplePixelSizeLB.setEnabled( allow_sample_pixel_size_and_prop_distance ) self._ySamplePixelSizeMetricEntry.setEnabled( allow_sample_pixel_size_and_prop_distance ) self._ySamplePixelSizeLB.setEnabled( allow_sample_pixel_size_and_prop_distance ) self._propagationDistanceMetricEntry.setEnabled( allow_sample_pixel_size_and_prop_distance ) self._propagationDistanceLB.setEnabled( allow_sample_pixel_size_and_prop_distance ) def _updateInstrument(self) -> None: scan = self.getScan() if scan is None: return update_dict = { "energy": self._updateEnergy, "detector pixel size": self._updateDetectorPixelSize, "frame flips": self._updateFlipped, "field of view": self._updateFieldOfView, "sample-detector distance": self._updateSampleDetectorDistance, } if scan.nexus_version is None or scan.nexus_version >= 1.4: update_dict.update( { "sample-source distance": self._updateSampleSourceDistance, } ) if scan.nexus_version is None or scan.nexus_version >= 1.5: update_dict.update( { "propagation distance": self._updatePropagationDistance, } ) for name, fct in update_dict.items(): try: fct(scan=scan) except Exception as e: _logger.error(f"Could not update {name}. Error is {e}") def _updateSample(self) -> None: scan = self.getScan() if scan is None: return update_dict = { "translations": self._updateTranslations, } if scan.nexus_version is None or scan.nexus_version >= 1.5: update_dict.update( { "sample pixel size": self._updateSamplePixelSize, "propagation distance": self._updatePropagationDistance, } ) for name, fct in update_dict.items(): try: fct(scan=scan) except Exception as e: _logger.error(f"Fail to update {name}. Error is {e}") def _updateSource(self) -> None: scan = self.getScan() if scan is None: return if scan.nexus_version is None or scan.nexus_version >= 1.4: try: self._updateSampleSourceDistance(scan=scan) except Exception as e: _logger.error( f"Could not update sample - source distance. Error is {e}" ) def _updateTranslations(self, scan: NXtomoScan) -> None: assert isinstance(scan, NXtomoScan) # note: for now and in order to allow edition we expect to have at most a unique value. Will fail for helicoidal def reduce(values): if values is None: return None values = numpy.array(values) values = numpy.unique( values[scan.image_key_control == ImageKey.PROJECTION.value] ) if values.size == 1: return values[0] elif values.size == 0: return None else: return f"{values[0]} ... {values[-1]}" x_translation = reduce(scan.x_translation) z_translation = reduce(scan.z_translation) self._xTranslationQLE.setValue(x_translation) self._zTranslationQLE.setValue(z_translation) def _updateFieldOfView(self, scan: NXtomoScan) -> None: if not self._fieldOfViewLB.isLocked(): # if in ''auto mode: we want to overwrite the NXtomo existing value by the one of the GUI idx = self._fieldOfViewCB.findText(FOV.from_value(scan.field_of_view).value) if idx > 0: self._fieldOfViewCB.setCurrentIndex(idx) def _updateFlipped(self, scan: NXtomoScan) -> None: flip_lr = scan.detector_is_lr_flip flip_ud = scan.detector_is_ud_flip if (not self._lrFlippedLB.isLocked()) and flip_lr is not None: self._lrFlippedCB.setChecked(flip_lr) if (not self._udFlippedLB.isLocked()) and flip_ud is not None: self._udFlippedCB.setChecked(flip_ud) def _updateSampleDetectorDistance(self, scan: NXtomoScan) -> None: if not self._sampleDetectorDistanceLB.isLocked(): # if in 'auto' mode: we want to overwrite the NXtomo existing value by the one of the GUI self._sampleDetectorDistanceMetricEntry.setValue( scan.sample_detector_distance ) def _updateSampleSourceDistance(self, scan: NXtomoScan) -> None: if not self._sampleSourceDistanceLB.isLocked(): self._sampleSourceDistanceMetricEntry.setValue(scan.source_sample_distance) def _updatePropagationDistance(self, scan: NXtomoScan) -> None: if not self._propagationDistanceLB.isLocked(): # if in 'auto' mode: we want to overwrite the NXtomo existing value by the one of the GUI self._propagationDistanceMetricEntry.setValue(scan.propagation_distance) def _updateEnergy(self, scan: NXtomoScan) -> None: assert isinstance(scan, NXtomoScan) if not self._energyLockerLB.isLocked(): # if in 'auto' mode: we want to overwrite the NXtomo existing value by the one of the GUI energy_in_kev: float | None = scan.energy if energy_in_kev is not None: # move from float to pint.Quantity assert not isinstance(energy_in_kev, pint.Quantity) self._energyEntry.setValue(energy_in_kev) def _updateDetectorPixelSize(self, scan: NXtomoScan) -> None: assert isinstance(scan, NXtomoScan) if not self._xDetectorPixelSizeLB.isLocked(): x_pixel_size = scan.detector_x_pixel_size self._xDetectorPixelSizeMetricEntry.setValue(x_pixel_size) if not self._yDetectorPixelSizeLB.isLocked(): y_pixel_size = scan.detector_y_pixel_size self._yDetectorPixelSizeMetricEntry.setValue(y_pixel_size) def _updateSamplePixelSize(self, scan: NXtomoScan) -> None: if not self._xSamplePixelSizeLB.isLocked(): # if in 'auto' mode: we want to overwrite the NXtomo existing value by the one of the GUI self._xSamplePixelSizeMetricEntry.setValue( scan.get_sample_pixel_size(which="x", fallback_to_det_pixel_size=False) ) if not self._ySamplePixelSizeLB.isLocked(): # if in 'auto' mode: we want to overwrite the NXtomo existing value by the one of the GUI self._ySamplePixelSizeMetricEntry.setValue( scan.get_sample_pixel_size(which="y", fallback_to_det_pixel_size=False) ) def _editingFinished(self, *args, **kwargs): self.sigEditingFinished.emit() def hasLockField(self) -> bool: """return True if the widget has at least one lock field""" return True in [locker.isLocked() for locker in self._lockerPBs] def hideLockers(self, hide: bool) -> None: for locker in self._lockerPBs: locker.setVisible(not hide) def getEditableWidgets(self) -> tuple[qt.QWidget]: return tuple(self._editableWidgets) def setScan(self, scan: NXtomoScan | None) -> None: if scan is None: self._scan = scan elif not isinstance(scan, NXtomoScan): raise TypeError( f"{scan} is expected to be an instance of {NXtomoScan}. Not {type(scan)}" ) else: self._scan = weakref.ref(scan) self._scanInfoQLE.setScan(scan) # scan will only be read and not kept self.update_tree() def getScan(self) -> NXtomoScan | None: if self._scan is None or self._scan() is None: return None else: return self._scan() def getConfiguration(self) -> dict: """ Return a dict with field full name as key and a tuple as value (field_value, is_locked) field_value is given in keV for energies else in 'base units' limitation: for now sample position are not handled because this is a 'corner case' for now """ def to_base_units_magnitude_if_exists(value: None | pint.Quantity): if value is None: return None else: return value.to_base_units().magnitude energy = self._energyEntry.getValue() if energy is not None: assert isinstance(energy, float) return { NXtomoEditorKeys.ENERGY: ( energy, self._energyLockerLB.isLocked(), ), NXtomoEditorKeys.DETECTOR_X_PIXEL_SIZE: ( to_base_units_magnitude_if_exists( self._xDetectorPixelSizeMetricEntry.getValue() ), self._xDetectorPixelSizeLB.isLocked(), ), NXtomoEditorKeys.DETECTOR_Y_PIXEL_SIZE: ( to_base_units_magnitude_if_exists( self._yDetectorPixelSizeMetricEntry.getValue() ), self._yDetectorPixelSizeLB.isLocked(), ), NXtomoEditorKeys.SAMPLE_X_PIXEL_SIZE: ( to_base_units_magnitude_if_exists( self._xSamplePixelSizeMetricEntry.getValue() ), self._xSamplePixelSizeLB.isLocked(), ), NXtomoEditorKeys.SAMPLE_Y_PIXEL_SIZE: ( to_base_units_magnitude_if_exists( self._ySamplePixelSizeMetricEntry.getValue() ), self._ySamplePixelSizeLB.isLocked(), ), NXtomoEditorKeys.SAMPLE_DETECTOR_DISTANCE: ( to_base_units_magnitude_if_exists( self._sampleDetectorDistanceMetricEntry.getValue() ), self._sampleDetectorDistanceLB.isLocked(), ), NXtomoEditorKeys.SAMPLE_SOURCE_DISTANCE: ( to_base_units_magnitude_if_exists( self._sampleSourceDistanceMetricEntry.getValue() ), self._sampleSourceDistanceLB.isLocked(), ), NXtomoEditorKeys.FIELD_OF_VIEW: ( self._fieldOfViewCB.currentText(), self._fieldOfViewLB.isChecked(), ), NXtomoEditorKeys.LR_FLIPPED: ( self._lrFlippedCB.isChecked(), self._lrFlippedLB.isChecked(), ), NXtomoEditorKeys.UD_FLIPPED: ( self._udFlippedCB.isChecked(), self._udFlippedLB.isChecked(), ), NXtomoEditorKeys.PROPAGATION_DISTANCE: ( to_base_units_magnitude_if_exists( self._propagationDistanceMetricEntry.getValue(), ), self._propagationDistanceLB.isLocked(), ), NXtomoEditorKeys.X_TRANSLATION: ( to_base_units_magnitude_if_exists(self._xTranslationQLE.getValue()), ), NXtomoEditorKeys.Z_TRANSLATION: ( to_base_units_magnitude_if_exists(self._zTranslationQLE.getValue()), ), } def setConfiguration(self, config: dict) -> None: """ Load given configuration. We expect all quantities to be given: * in keV for energies * else in base units """ # energy energy = config.get(NXtomoEditorKeys.ENERGY, None) if energy is not None: energy, energy_locked = energy assert energy is None or isinstance( energy, float ), "energy is expected to be dimensionless (float) already in keV" self._energyEntry.setValue(energy) self._energyLockerLB.setLock(energy_locked) # detector pixel size detector_x_pixel_size = config.get(NXtomoEditorKeys.DETECTOR_X_PIXEL_SIZE, None) if detector_x_pixel_size is not None: detector_x_pixel_size, detector_x_pixel_size_locked = detector_x_pixel_size self._xDetectorPixelSizeMetricEntry.setValue( detector_x_pixel_size, displayed_unit=_ureg.meter ) self._xDetectorPixelSizeLB.setLock(detector_x_pixel_size_locked) detector_y_pixel_size = config.get(NXtomoEditorKeys.DETECTOR_Y_PIXEL_SIZE, None) if detector_y_pixel_size is not None: detector_y_pixel_size, detector_y_pixel_size_locked = detector_y_pixel_size self._yDetectorPixelSizeMetricEntry.setValue( detector_y_pixel_size, displayed_unit=_ureg.meter ) self._yDetectorPixelSizeLB.setLock(detector_y_pixel_size_locked) # sample detector distance sample_detector_distance = config.get( NXtomoEditorKeys.SAMPLE_DETECTOR_DISTANCE, None ) if sample_detector_distance is not None: sample_detector_distance, distance_locked = sample_detector_distance self._sampleDetectorDistanceMetricEntry.setValue( sample_detector_distance, displayed_unit=_ureg.meter ) self._sampleDetectorDistanceLB.setLock(distance_locked) # field of view field_of_view = config.get(NXtomoEditorKeys.FIELD_OF_VIEW, None) if field_of_view is not None: field_of_view, field_of_view_locked = field_of_view field_of_view = FOV.from_value(field_of_view) self._fieldOfViewCB.setCurrentText(field_of_view.value) self._fieldOfViewLB.setLock(field_of_view_locked) lr_flipped = config.get(NXtomoEditorKeys.LR_FLIPPED, None) if lr_flipped is not None: lr_flipped, lr_flipped_locked = lr_flipped lr_flipped = lr_flipped in (True, "True", "true") self._lrFlippedCB.setChecked(lr_flipped) self._lrFlippedLB.setLock(lr_flipped_locked) ud_flipped = config.get(NXtomoEditorKeys.UD_FLIPPED, None) if ud_flipped is not None: ud_flipped, ud_flipped_locked = ud_flipped ud_flipped = ud_flipped in (True, "True", "true") self._udFlippedCB.setChecked(ud_flipped) self._udFlippedLB.setLock(ud_flipped_locked) # sample source distance sample_source_distance = config.get( NXtomoEditorKeys.SAMPLE_SOURCE_DISTANCE, None ) if sample_source_distance is not None: sample_source_distance, sample_source_distance_locked = ( sample_source_distance ) if sample_source_distance >= 0: _logger.warning("the sample-source is expected to be negative") self._sampleSourceDistanceMetricEntry.setValue(sample_source_distance) self._sampleSourceDistanceLB.setLock(sample_source_distance_locked) # sample pixel size sample_x_pixel_size = config.get(NXtomoEditorKeys.SAMPLE_X_PIXEL_SIZE, None) if sample_x_pixel_size is not None: sample_x_pixel_size, x_sample_pixel_size_locked = sample_x_pixel_size self._xSamplePixelSizeMetricEntry.setValue( sample_x_pixel_size, displayed_unit=_ureg.meter ) self._xSamplePixelSizeLB.setLock(x_sample_pixel_size_locked) sample_y_pixel_size = config.get(NXtomoEditorKeys.SAMPLE_Y_PIXEL_SIZE, None) if sample_y_pixel_size is not None: sample_y_pixel_size, sample_y_pixel_size_locked = sample_y_pixel_size self._ySamplePixelSizeMetricEntry.setValue( sample_y_pixel_size, displayed_unit=_ureg.meter ) self._ySamplePixelSizeLB.setLock(sample_y_pixel_size_locked) # propagation distance propagation_distance = config.get(NXtomoEditorKeys.PROPAGATION_DISTANCE, None) if propagation_distance is not None: propagation_distance, propagation_distance_locked = propagation_distance self._propagationDistanceMetricEntry.setValue(propagation_distance) self._propagationDistanceLB.setChecked(propagation_distance_locked) def getConfigurationForTask(self) -> dict: """ default configuration is stored as field: (field_value, filed_is_locked) when the task expects field_key: field_value Because we need to be able to reload settings of the LockButton. But the task doesn't care about it. She only want to know which field must be edited. So we need to filter the dict value. """ return {key: value[0] for key, value in self.getConfiguration().items()} def clear(self) -> None: self._tree.clear() class _TranslationMetricEntry(MetricEntry): """ Widget to define a translation along one axis. The behavior is limited at the moment. * either the array contains a unique value on the array and a float is displayed * either the array contains several unique values and then '...' will be displayed. Users cannot provide an array in this case. """ LOADED_ARRAY = "loaded array" class TranslationValidator(qt.QDoubleValidator): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setNotation(qt.QDoubleValidator.ScientificNotation) def validate(self, a0: str, a1: int): if "..." in a0: return (qt.QDoubleValidator.Acceptable, a0, a1) else: return super().validate(a0, a1) def __init__(self, name, default_unit=_ureg.meter, parent=None): super().__init__(name, default_unit=default_unit, parent=parent) self._qlePixelSize.setValidator(self.TranslationValidator(self)) def getValue(self) -> float: """ :return: the value in meter """ if "..." in self._qlePixelSize.text(): # in this case this is the representation of an array, we don;t wan't to overwrite it return self.LOADED_ARRAY if self._qlePixelSize.text() in ("unknown", ""): return None else: return float(self._qlePixelSize.text()) * self.getCurrentUnit() class EnergyEntry(qt.QLineEdit): """ QLineEdit enabling to handle an energy in keV """ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setValidator(MetricEntry.DoubleValidator()) def setValue(self, value_kev: float | None): if not isinstance(value_kev, (float, type(None))): raise TypeError( f"a0 is expected to be {None} or an instance of {float}. Got {type(value_kev)}" ) if value_kev is None: value_kev = "unknown" else: value_kev = str(value_kev) super().setText(value_kev) def getValue(self) -> float | None: """ Return energy in keV or None """ txt = self.text().replace(" ", "") if txt in ("unknown", ""): return None else: return float(txt) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/edit/nxtomowarmer.py0000644000175000017500000000446214757047403021173 0ustar00paynopaynofrom __future__ import annotations import h5py from silx.gui import qt from silx.io.utils import open as open_hdf5 from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.gui import icons class NXtomoProxyWarmer(qt.QWidget): """ Widget to warm in the case the NXtomo entry is a SoftLink or an ExternalLink (so editing it will modify another file). """ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setLayout(qt.QHBoxLayout()) # icon # warning about requires parameters from a nabu slice reconstruction self._warningIcon = qt.QLabel( "It seems this entry points to a soft link. Be carreful. Editing metadata will affect another file", parent=self, ) self._warningIcon.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum) self._warningIcon.setAlignment(qt.Qt.AlignRight | qt.Qt.AlignVCenter) warning_icon = icons.getQIcon("warning") self._warningIcon.setPixmap(warning_icon.pixmap(20, 20)) self.layout().addWidget(self._warningIcon) # label self._warningLabel = qt.QLabel( "It seems the NXtomo you are editing is pointing to another dataset.", parent=self, ) self._warningLabel.setAlignment(qt.Qt.AlignRight | qt.Qt.AlignVCenter) self._warningLabel.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum) font = self._warningLabel.font() font.setBold(True) font.setPixelSize(10) self._warningLabel.setFont(font) self.layout().addWidget(self._warningLabel) # set up self.setScan(None) def setScan(self, scan: NXtomoScan | None): if scan is None: self._activateWarning(False) elif isinstance(scan, NXtomoScan): with open_hdf5(scan.master_file) as h5f: entry = h5f.get( name=scan.entry, getclass=True, getlink=True, default=None ) self._activateWarning(entry in (h5py.ExternalLink, h5py.SoftLink)) else: raise TypeError(f"{scan} is expected to be an instance of {NXtomoScan}") def _activateWarning(self, activate: bool): self._warningIcon.setVisible(activate) self._warningLabel.setVisible(activate) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9371016 tomwer-1.6.17/src/tomwer/gui/edit/tests/0000755000175000017500000000000015153325403017201 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/edit/tests/__init__.py0000644000175000017500000000000014757047403021312 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/edit/tests/test_dkrf_patch.py0000644000175000017500000001503515153325210022717 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import shutil import tempfile import numpy import pytest from nxtomomill.utils import add_dark_flat_nx_file from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from silx.io.url import DataUrl from nxtomo.nxobject.nxdetector import ImageKey from tomoscan.esrf.scan.utils import get_data from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.utils.scanutils import MockNXtomo from tomwer.gui.edit.dkrfpatch import DarkRefPatchWidget, _DarkOrFlatUrl from tomwer.tests.utils import skip_gui_test @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestDarkOrFlatUrl(TestCaseQt): """ Test some critical utils of the _DarkOrFlatUrl widget """ def setUp(self): TestCaseQt.setUp(self) self._widgetForDark = _DarkOrFlatUrl( parent=None, type_=ImageKey.DARK_FIELD, when="start" ) self._widgetForFlat = _DarkOrFlatUrl( parent=None, type_=ImageKey.FLAT_FIELD, when="start" ) self.output_folder = tempfile.mkdtemp() # hdf5_mock = MockNXtomo( scan_path=self.output_folder, n_ini_proj=20, n_proj=20, create_ini_dark=True, create_ini_flat=True, create_final_flat=True, ) self._scan = hdf5_mock.scan self.scan_url = DataUrl( file_path=self._scan.master_file, data_path=self._scan.entry ) def tearDown(self): shutil.rmtree(self.output_folder) self._widgetForDark.setAttribute(qt.Qt.WA_DeleteOnClose) self._widgetForDark.close() self._widgetForDark = None self._widgetForFlat.setAttribute(qt.Qt.WA_DeleteOnClose) self._widgetForFlat.close() self._widgetForFlat = None def testSetUrlForFlat(self): self._widgetForFlat.setUrl(self.scan_url) self.assertEqual(self._widgetForFlat._optionsCB.count(), 3) data_url = self._widgetForFlat._redirectDataPath(self.scan_url) image_keys = self._widgetForFlat._getImageKey(data_url) self.assertTrue(image_keys is not None) slices_index_0 = self._widgetForFlat._getSlices(image_keys, 0) self.assertTrue(slices_index_0 is not None) self.assertEqual( list(range(slices_index_0.start, slices_index_0.stop)), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], ) slices_index_1 = self._widgetForFlat._getSlices(image_keys, 1) self.assertTrue(slices_index_1 is not None) self.assertEqual(slices_index_1, slice(31, 41)) def testSetUrlForDark(self): self._widgetForDark.setUrl(self.scan_url) self._widgetForDark.show() self.assertEqual(self._widgetForDark._optionsCB.count(), 2) data_url = self._widgetForDark._redirectDataPath(self.scan_url) image_keys = self._widgetForDark._getImageKey(data_url) slices_index_0 = self._widgetForDark._getSlices(image_keys, 0) self.assertEqual( list(range(slices_index_0.start, slices_index_0.stop)), [ 0, ], ) slices_index_1 = self._widgetForDark._getSlices(image_keys, 1) self.assertTrue(slices_index_1 is None) @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestDarkRefPatchWidget(TestCaseQt): """ Simple test to insure DarkRefWidget is working """ def setUp(self): TestCaseQt.setUp(self) self._widget = DarkRefPatchWidget(parent=None) self.output_folder1 = tempfile.mkdtemp() self.output_folder2 = tempfile.mkdtemp() hdf5_mock = MockNXtomo( scan_path=self.output_folder1, n_ini_proj=20, n_proj=20, create_ini_dark=True, create_ini_flat=True, create_final_flat=True, ) self._scanWithDarkAndRef = hdf5_mock.scan hdf5_mock = MockNXtomo( scan_path=self.output_folder2, n_ini_proj=20, n_proj=20, create_ini_dark=False, create_ini_flat=False, create_final_flat=False, ) self._scan = hdf5_mock.scan assert len(self._scan.darks) == 0 assert len(self._scan.flats) == 0 def tearDown(self): shutil.rmtree(self.output_folder1) shutil.rmtree(self.output_folder2) self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None self.qapp.processEvents() def testEdition(self): # insure the widget work and post processing made by the application # and the widget succeed to url = DataUrl( file_path=self._scanWithDarkAndRef.master_file, data_path=self._scanWithDarkAndRef.entry, ) self._widget.setStartDarkUrl(url, series_index=0) self._widget.setStartFlatUrl(url, series_index=1) self.assertTrue(self._widget.getStartDarkUrl() is not None) self.assertTrue(self._widget.getStartDarkUrl().is_valid()) self.assertTrue(self._widget.getStartFlatUrl() is not None) self.assertTrue(self._widget.getStartFlatUrl().is_valid()) self.assertTrue(self._widget.getEndDarkUrl() is None) self.assertTrue(self._widget.getEndFlatUrl() is None) self.process() new_scan = NXtomoScan(scan=self._scan.master_file, entry=self._scan.entry) self.assertEqual(len(new_scan.darks), 1) self.assertTrue(0 in new_scan.darks) numpy.testing.assert_array_equal( get_data(new_scan.darks[0]), get_data(self._scanWithDarkAndRef.darks[0]), ) self.assertEqual(len(self._scanWithDarkAndRef.flats), 20) self.assertEqual(len(new_scan.flats), 10) self.assertEqual(tuple(new_scan.flats.keys()), tuple(range(1, 11))) numpy.testing.assert_array_equal( get_data(new_scan.flats[1]), get_data(self._scanWithDarkAndRef.flats[31]), ) numpy.testing.assert_array_equal( get_data(new_scan.flats[10]), get_data(self._scanWithDarkAndRef.flats[40]), ) def process(self): url_sd = self._widget.getStartDarkUrl() url_sf = self._widget.getStartFlatUrl() url_ed = self._widget.getEndDarkUrl() url_ef = self._widget.getEndFlatUrl() add_dark_flat_nx_file( file_path=self._scan.master_file, entry=self._scan.entry, darks_start=url_sd, flats_start=url_sf, darks_end=url_ed, flats_end=url_ef, ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/edit/tests/test_image_key_editor.py0000644000175000017500000001104714757047403024127 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import tempfile import pytest from silx.gui import qt from silx.gui.utils.testutils import SignalListener, TestCaseQt from nxtomo.nxobject.nxdetector import ImageKey from tomwer.core.utils.scanutils import MockNXtomo from tomwer.gui.edit.imagekeyeditor import ( ImageKeyDialog, ImageKeyUpgraderWidget, _AddImageKeyUpgradeOperation, ) from tomwer.tests.utils import skip_gui_test @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestImageKeyEditorGUI(TestCaseQt): """ Simple test the interface for configuration is working """ def setUp(self): TestCaseQt.setUp(self) self._widget = ImageKeyDialog(parent=None) self.output_folder = tempfile.mkdtemp() hdf5_mock = MockNXtomo( scan_path=self.output_folder, n_ini_proj=20, n_proj=20, ) self._scan = hdf5_mock.scan def tearDown(self): self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None def testEdition(self): modifications = { 2: ImageKey.INVALID, } self._widget.setScan(self._scan) self._widget.setModifications(modifications) self.assertEqual(self._widget.getModifications(), modifications) @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class Test_AddImageKeyUpgradeOperation(TestCaseQt): def setUp(self): super().setUp() self._widget = _AddImageKeyUpgradeOperation() self._signalLisener = SignalListener() self._widget.sigOperationAdded.connect(self._signalLisener) def tearDown(self): self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None super().tearDown() def test(self): self._widget._addButtonPB.released.emit() self.qapp.processEvents() assert self._signalLisener.callCount() == 1 assert self._signalLisener.callCount() == 1 assert self._signalLisener.arguments() == [ ( { "from_image_key": ImageKey.PROJECTION.value, "to_image_key": ImageKey.DARK_FIELD.value, }, ), ] @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestImageKeyUpgraderList(TestCaseQt): def setUp(self): super().setUp() self._widget = ImageKeyUpgraderWidget() def tearDown(self): self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None super().tearDown() def test_add_remove_operations(self): """ test adding and remove operations to the list """ self._widget.addOperation( from_image_key=ImageKey.PROJECTION, to_image_key=ImageKey.DARK_FIELD ) assert self._widget.getOperations() == { ImageKey.PROJECTION: ImageKey.DARK_FIELD, } self._widget.addOperation( from_image_key=ImageKey.FLAT_FIELD, to_image_key=ImageKey.DARK_FIELD ) assert self._widget.getOperations() == { ImageKey.PROJECTION: ImageKey.DARK_FIELD, ImageKey.FLAT_FIELD: ImageKey.DARK_FIELD, } self._widget.addOperation( from_image_key=ImageKey.PROJECTION, to_image_key=ImageKey.FLAT_FIELD ) assert self._widget.getOperations() == { ImageKey.PROJECTION: ImageKey.FLAT_FIELD, ImageKey.FLAT_FIELD: ImageKey.DARK_FIELD, } self._widget.removeOperation( from_image_key=ImageKey.PROJECTION, to_image_key=ImageKey.FLAT_FIELD ) assert self._widget.getOperations() == { ImageKey.FLAT_FIELD: ImageKey.DARK_FIELD, } self._widget.removeOperation( from_image_key=ImageKey.PROJECTION, to_image_key=ImageKey.DARK_FIELD ) assert self._widget.getOperations() == { ImageKey.FLAT_FIELD: ImageKey.DARK_FIELD, } self._widget.removeOperation( from_image_key=ImageKey.FLAT_FIELD, to_image_key=ImageKey.DARK_FIELD ) assert self._widget.getOperations() == {} self._widget.setOperations( { ImageKey.PROJECTION: ImageKey.FLAT_FIELD, ImageKey.FLAT_FIELD: ImageKey.DARK_FIELD, } ) assert self._widget.getOperations() == { ImageKey.PROJECTION: ImageKey.FLAT_FIELD, ImageKey.FLAT_FIELD: ImageKey.DARK_FIELD, } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/edit/tests/test_nx_editor.py0000644000175000017500000004400415153325210022603 0ustar00paynopaynofrom __future__ import annotations import os import h5py import numpy import pytest import pint from silx.gui import qt from nxtomo.application.nxtomo import NXtomo from nxtomo.nxobject.nxdetector import ImageKey, FOV from nxtomo.utils.transformation import ( build_matrix, DetXFlipTransformation, DetYFlipTransformation, ) from tomwer.core.process.edit.nxtomoeditor import NXtomoEditorTask from nxtomo.nxobject.nxtransformations import ( NXtransformations, get_lr_flip, get_ud_flip, ) from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.gui.edit.nxtomoeditor import NXtomoEditor, _TranslationMetricEntry from tomwer.tests.conftest import qtapp # noqa F401 from tomwer.tests.test_utils import is_lr_flip, is_ud_flip _ureg = pint.get_application_registry() @pytest.mark.parametrize("detector_x_pixel_size", (0.12 * _ureg.millimeter,)) @pytest.mark.parametrize("detector_y_pixel_size", (None,)) @pytest.mark.parametrize("sample_x_pixel_size", (None,)) @pytest.mark.parametrize("sample_y_pixel_size", (None, 0.0066 * _ureg.meter)) @pytest.mark.parametrize("field_of_view", [item.value for item in FOV]) @pytest.mark.parametrize("sample_detector_distance", (1.2 * _ureg.meter,)) @pytest.mark.parametrize("sample_source_distance", (-10.2 * _ureg.meter,)) @pytest.mark.parametrize("propagation_distance", (1.01 * _ureg.meter,)) @pytest.mark.parametrize("energy", (None, 23.5 * _ureg.keV)) @pytest.mark.parametrize("lr_flipped", (False,)) @pytest.mark.parametrize("ud_flipped", (True, False)) @pytest.mark.parametrize( "x_translation", (None, numpy.ones(12) * _ureg.meter, numpy.arange(12) * _ureg.meter), ) @pytest.mark.parametrize( "z_translation", (None, numpy.zeros(12) * _ureg.meter, numpy.arange(12, 24) * _ureg.meter), ) def test_nx_editor( tmp_path, qtapp, # noqa F811 detector_x_pixel_size: pint.Quantity | None, detector_y_pixel_size: pint.Quantity | None, sample_x_pixel_size: pint.Quantity | None, sample_y_pixel_size: pint.Quantity | None, propagation_distance: pint.Quantity | None, sample_source_distance: pint.Quantity | None, field_of_view, sample_detector_distance: pint.Quantity, energy: pint.Quantity, lr_flipped, ud_flipped, x_translation: pint.Quantity, z_translation: pint.Quantity, ): """ :param x_translation: x translation on the ESRF coordinate system (will be converted to McStas coordinate when saved) :param z_translation: z translation on the ESRF coordinate system (will be converted to McStas coordinate when saved) """ # 1.0 create nx tomo with raw data nx_tomo = NXtomo() nx_tomo.energy = energy nx_tomo.instrument.detector.x_pixel_size = detector_x_pixel_size nx_tomo.instrument.detector.y_pixel_size = detector_y_pixel_size nx_tomo.instrument.detector.field_of_view = field_of_view nx_tomo.instrument.detector.distance = sample_detector_distance nx_tomo.instrument.detector.image_key_control = [ImageKey.PROJECTION.value] * 12 nx_tomo.instrument.detector.data = numpy.empty(shape=(12, 10, 10)) nx_tomo.sample.rotation_angle = numpy.linspace(0, 20, num=12) * _ureg.degree # warning: mapping from ESRF coordinate to McStas nx_tomo.sample.z_translation = x_translation nx_tomo.sample.y_translation = z_translation nx_tomo.sample.x_pixel_size = sample_x_pixel_size nx_tomo.sample.y_pixel_size = sample_y_pixel_size nx_tomo.sample.propagation_distance = propagation_distance nx_tomo.instrument.source.distance = sample_source_distance nx_tomo.instrument.detector.set_transformation_from_lr_flipped(flipped=lr_flipped) nx_tomo.instrument.detector.set_transformation_from_ud_flipped(flipped=ud_flipped) file_path = os.path.join(tmp_path, "nxtomo.nx") entry = "entry0000" nx_tomo.save( file_path=file_path, data_path=entry, ) scan = NXtomoScan(file_path, entry) # 2.0 create the widget and do the edition widget = NXtomoEditor() widget.setScan(scan=scan) # 3.0 check data have been correctly loaded def check_metric(expected_value, current_value): if expected_value is None: return current_value is None return numpy.isclose(expected_value, current_value) assert check_metric( detector_x_pixel_size, widget._xDetectorPixelSizeMetricEntry.getValue() ) assert widget._xDetectorPixelSizeMetricEntry._qcbUnit.currentText() == "m" assert check_metric( detector_y_pixel_size, widget._yDetectorPixelSizeMetricEntry.getValue() ) assert widget._yDetectorPixelSizeMetricEntry._qcbUnit.currentText() == "m" assert check_metric( sample_detector_distance, widget._sampleDetectorDistanceMetricEntry.getValue() ) assert widget._sampleDetectorDistanceMetricEntry._qcbUnit.currentText() == "m" assert check_metric( sample_x_pixel_size, widget._xSamplePixelSizeMetricEntry.getValue() ) assert check_metric( sample_y_pixel_size, widget._ySamplePixelSizeMetricEntry.getValue() ) assert check_metric( sample_source_distance, widget._sampleSourceDistanceMetricEntry.getValue() ) assert check_metric( propagation_distance, widget._propagationDistanceMetricEntry.getValue() ) assert field_of_view == widget._fieldOfViewCB.currentText() assert lr_flipped == widget._lrFlippedCB.isChecked() assert ud_flipped == widget._udFlippedCB.isChecked() if energy is None: assert widget._energyEntry.getValue() is None else: assert numpy.isclose( energy.to(_ureg.keV).magnitude, widget._energyEntry.getValue() ) def check_translation(expected_value, current_value): if expected_value is None: return current_value is None else: expected_value = expected_value.to_base_units().magnitude assert current_value is not None if isinstance(current_value, pint.Quantity): current_value = current_value.to_base_units().magnitude u_values = numpy.unique(expected_value) if u_values.size == 1: return float(current_value) == u_values[0] else: return current_value is _TranslationMetricEntry.LOADED_ARRAY assert check_translation(x_translation, widget._xTranslationQLE.getValue()) assert widget._xTranslationQLE._qcbUnit.currentText() == "m" assert check_translation(z_translation, widget._zTranslationQLE.getValue()) assert widget._zTranslationQLE._qcbUnit.currentText() == "m" # 4.0 edit some parameters widget._energyEntry.setText("23.789") widget._xDetectorPixelSizeMetricEntry.setUnit(_ureg.nanometer) widget._yDetectorPixelSizeMetricEntry.setValue(2.1e-7) widget._xSamplePixelSizeMetricEntry.setValue(value_m=5.6e-6) widget._sampleDetectorDistanceMetricEntry.setValue("unknown") widget._sampleSourceDistanceMetricEntry.setValue(-99) widget._propagationDistanceMetricEntry.setValue(88) widget._fieldOfViewCB.setCurrentText(FOV.HALF.value) widget._lrFlippedCB.setChecked(not lr_flipped) widget._xTranslationQLE.setValue(1.8) widget._xTranslationQLE.setUnit(_ureg.millimeter) widget._zTranslationQLE.setValue(2.8) widget._zTranslationQLE.setUnit(_ureg.meter) # 5.0 task = NXtomoEditorTask( inputs={ "data": scan, "configuration": widget.getConfigurationForTask(), } ) task.run() # 6.0 make sure data have been overwrite overwrite_nx_tomo = NXtomo().load( file_path=file_path, data_path=entry, ) assert overwrite_nx_tomo.energy == 23.789 * _ureg.keV if detector_x_pixel_size is None: assert overwrite_nx_tomo.instrument.detector.x_pixel_size is None else: assert numpy.isclose( overwrite_nx_tomo.instrument.detector.x_pixel_size, 0.12 * _ureg.nanometer, ) assert overwrite_nx_tomo.instrument.detector.y_pixel_size == 2.1e-7 * _ureg.meter assert overwrite_nx_tomo.instrument.detector.distance is None assert overwrite_nx_tomo.instrument.detector.field_of_view is FOV.HALF final_transformation = NXtransformations() final_transformation.add_transformation(DetXFlipTransformation(flip=ud_flipped)) final_transformation.add_transformation(DetYFlipTransformation(flip=not lr_flipped)) # note: the 'not' comes from inversion done with the _xFlippedCB combobox numpy.testing.assert_allclose( build_matrix( overwrite_nx_tomo.instrument.detector.transformations.transformations ), build_matrix(final_transformation.transformations), ) numpy.testing.assert_array_almost_equal( overwrite_nx_tomo.sample.x_translation, (numpy.array([1.8] * 12) * _ureg.millimeter).to_base_units(), ) numpy.testing.assert_array_almost_equal( overwrite_nx_tomo.sample.z_translation, numpy.array([2.8] * 12) * _ureg.meter, ) # end widget.setAttribute(qt.Qt.WA_DeleteOnClose) widget.close() widget = None def test_nx_editor_lock( tmp_path, qtapp, # noqa F811 ): """test the pad lock buttons of the NXtomo editor""" # 1.0 create nx tomos with raw data nx_tomo_1 = NXtomo() nx_tomo_1.instrument.source.distance = 54.8 * _ureg.meter nx_tomo_1.instrument.detector.x_pixel_size = 0.023 * _ureg.meter nx_tomo_1.instrument.detector.y_pixel_size = 0.025 * _ureg.meter nx_tomo_1.instrument.detector.field_of_view = "full" nx_tomo_1.instrument.detector.distance = 2.4 * _ureg.meter nx_tomo_1.instrument.detector.set_transformation_from_x_flipped(False) nx_tomo_1.instrument.detector.set_transformation_from_y_flipped(True) nx_tomo_1.energy = 5.9 * _ureg.keV nx_tomo_1.instrument.detector.image_key_control = [ImageKey.PROJECTION.value] * 12 nx_tomo_1.instrument.detector.data = numpy.empty(shape=(12, 10, 10)) nx_tomo_1.sample.rotation_angle = numpy.linspace(0, 20, num=12) * _ureg.degree nx_tomo_1.sample.propagation_distance = 22.0 * _ureg.meter nx_tomo_1.sample.x_pixel_size = 0.023 * _ureg.millimeter nx_tomo_1.sample.y_pixel_size = 0.025 * _ureg.millimeter file_path = os.path.join(tmp_path, "nxtomo.nx") entry = "entry0000" nx_tomo_1.save( file_path=file_path, data_path=entry, ) scan_1 = NXtomoScan(file_path, entry) nx_tomo_2 = NXtomo() nx_tomo_2.instrument.source.distance = 8 * _ureg.meter nx_tomo_2.instrument.detector.x_pixel_size = 4.023 * _ureg.meter nx_tomo_2.instrument.detector.y_pixel_size = 6.025 * _ureg.meter nx_tomo_2.instrument.detector.field_of_view = "full" nx_tomo_2.instrument.detector.distance = 2.89 * _ureg.meter lr_flip_sum = [ trans.transformation_values for trans in get_lr_flip( nx_tomo_1.instrument.detector.transformations.transformations ) ] lr_flip = numpy.isclose(lr_flip_sum, 180.0) nx_tomo_2.instrument.detector.set_transformation_from_x_flipped(not lr_flip) ud_flip_sum = [ trans.transformation_values for trans in get_ud_flip( nx_tomo_1.instrument.detector.transformations.transformations ) ] ud_flip = numpy.isclose(ud_flip_sum, 180.0) nx_tomo_2.instrument.detector.set_transformation_from_y_flipped(not ud_flip) nx_tomo_2.energy = 5.754 * _ureg.keV nx_tomo_2.instrument.detector.image_key_control = [ImageKey.PROJECTION.value] * 12 nx_tomo_2.instrument.detector.data = numpy.empty(shape=(12, 10, 10)) nx_tomo_2.sample.rotation_angle = numpy.linspace(0, 20, num=12) * _ureg.degree file_path = os.path.join(tmp_path, "nxtomo.nx") entry = "entry0001" nx_tomo_2.save( file_path=file_path, data_path=entry, ) scan_2 = NXtomoScan(file_path, entry) # 2.0 create the widget and do the edition widget = NXtomoEditor() widget.setScan(scan=scan_1) for lockerButton in widget._lockerPBs: lockerButton.setLock(True) widget.setScan(scan=scan_2) # widget values must be the same (NXtomo field value not loaded if the lockers are active) assert widget._energyEntry.getValue() == 5.9 assert widget._xDetectorPixelSizeMetricEntry.getValue() == 0.023 * _ureg.meter assert widget._yDetectorPixelSizeMetricEntry.getValue() == 0.025 * _ureg.meter assert widget._sampleDetectorDistanceMetricEntry.getValue() == 2.4 * _ureg.meter assert widget._propagationDistanceMetricEntry.getValue() == 22.0 * _ureg.meter assert widget._fieldOfViewCB.currentText() == "Full" assert not widget._lrFlippedCB.isChecked() assert widget._udFlippedCB.isChecked() assert widget._xSamplePixelSizeMetricEntry.getValue() == 0.023 * _ureg.millimeter assert widget._ySamplePixelSizeMetricEntry.getValue() == 0.025 * _ureg.millimeter assert widget._sampleSourceDistanceMetricEntry.getValue() == 54.8 * _ureg.meter # 3.0 save the nxtomo task = NXtomoEditorTask( inputs={ "data": scan_2, "configuration": widget.getConfigurationForTask(), } ) task.run() # 4.0 check save went well overwrite_nx_tomo = NXtomo().load( file_path=file_path, data_path=entry, ) assert ( overwrite_nx_tomo.instrument.detector.x_pixel_size == nx_tomo_1.instrument.detector.x_pixel_size ) assert ( overwrite_nx_tomo.instrument.detector.y_pixel_size == nx_tomo_1.instrument.detector.y_pixel_size ) assert ( overwrite_nx_tomo.instrument.detector.field_of_view == nx_tomo_1.instrument.detector.field_of_view ) assert ( overwrite_nx_tomo.instrument.detector.distance == nx_tomo_1.instrument.detector.distance ) assert is_lr_flip( overwrite_nx_tomo.instrument.detector.transformations.transformations ) == is_lr_flip(nx_tomo_1.instrument.detector.transformations.transformations) assert is_ud_flip( overwrite_nx_tomo.instrument.detector.transformations.transformations ) == is_ud_flip(nx_tomo_1.instrument.detector.transformations.transformations) assert overwrite_nx_tomo.energy == nx_tomo_1.energy assert ( overwrite_nx_tomo.sample.propagation_distance == nx_tomo_1.sample.propagation_distance ) assert overwrite_nx_tomo.sample.x_pixel_size == nx_tomo_1.sample.x_pixel_size assert overwrite_nx_tomo.sample.y_pixel_size == nx_tomo_1.sample.y_pixel_size assert ( overwrite_nx_tomo.instrument.source.distance == nx_tomo_1.instrument.source.distance ) assert widget.getConfiguration() == { "instrument.beam.energy": (5.9, True), "instrument.detector.distance": (2.4, True), "instrument.detector.field_of_view": ("Full", True), "instrument.detector.x_pixel_size": (0.023, True), "instrument.detector.y_pixel_size": (0.025, True), "instrument.detector.lr_flipped": (False, True), "instrument.detector.ud_flipped": (True, True), "instrument.source.distance": (54.8, True), "sample.propagation_distance": (22.0, True), "sample.x_pixel_size": (2.3e-5, True), "sample.y_pixel_size": (2.5e-5, True), "sample.x_translation": (None,), "sample.z_translation": (None,), } for lockerButton in widget._lockerPBs: lockerButton.setLock(False) assert widget.getConfiguration() == { "instrument.beam.energy": (5.9, False), "instrument.detector.distance": (2.4, False), "instrument.detector.field_of_view": ("Full", False), "instrument.detector.x_pixel_size": (0.023, False), "instrument.detector.y_pixel_size": (0.025, False), "instrument.detector.lr_flipped": (False, False), "instrument.detector.ud_flipped": (True, False), "instrument.source.distance": (54.8, False), "sample.x_translation": (None,), "sample.z_translation": (None,), "sample.propagation_distance": (22.0, False), "sample.x_pixel_size": (2.3e-5, False), "sample.y_pixel_size": (2.5e-5, False), "sample.x_translation": (None,), "sample.z_translation": (None,), } def test_nxtomo_editor_with_missing_paths( tmp_path, qtapp, # noqa F811 ): """ test widget behavior in the case some nxtomo path don't exist """ # create nx tomo with raw data nx_tomo = NXtomo() nx_tomo.instrument.detector.image_key_control = [ImageKey.PROJECTION.value] * 12 nx_tomo.instrument.detector.data = numpy.empty(shape=(12, 10, 10)) nx_tomo.sample.rotation_angle = numpy.linspace(0, 20, num=12) * _ureg.degree file_path = os.path.join(tmp_path, "nxtomo.nx") entry = "entry0000" nx_tomo.save( file_path=file_path, data_path=entry, ) # delete some path that can be missing in some case with h5py.File(file_path, mode="a") as h5f: assert "entry0000" in h5f assert "entry0000/beam" not in h5f assert "entry0000/instrument/beam" not in h5f assert "entry0000/instrument/detector/distance" not in h5f assert "entry0000/instrument/detector/x_pixel_size" not in h5f assert "entry0000/instrument/detector/y_pixel_size" not in h5f assert "entry0000/instrument/detector/transformations" not in h5f scan = NXtomoScan(file_path, entry) # create the widget and do the edition widget = NXtomoEditor() widget.setScan(scan=scan) widget._sampleDetectorDistanceMetricEntry.setValue(0.05) widget._energyEntry.setValue(50.0) widget._xDetectorPixelSizeMetricEntry.setValue(0.02) widget._yDetectorPixelSizeMetricEntry.setValue(0.03) # overwrite the NXtomo task = NXtomoEditorTask( inputs={ "data": scan, "configuration": widget.getConfigurationForTask(), } ) task.run() # check save went well overwrite_nx_tomo = NXtomo().load( file_path=file_path, data_path=entry, ) assert overwrite_nx_tomo.instrument.detector.x_pixel_size == 0.02 * _ureg.meter assert overwrite_nx_tomo.instrument.detector.y_pixel_size == 0.03 * _ureg.meter assert overwrite_nx_tomo.energy == 50 * _ureg.keV assert overwrite_nx_tomo.instrument.detector.distance == 0.05 * _ureg.meter ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/fonts.py0000644000175000017500000000020614757047403016625 0ustar00paynopaynofrom silx.gui import qt FONT_IMPORTANT = qt.QFont("Arial", 12) FONT_MEDIUM = qt.QFont("Arial", 10) FONT_SMALL = qt.QFont("Arial", 8) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/icons.py0000644000175000017500000002617315153325210016604 0ustar00paynopayno# coding: utf-8 """Set of icons for buttons. Use :func:`getQIcon` to create Qt QIcon from the name identifying an icon. """ import logging import os import weakref from silx.gui import qt from silx.utils import weakref as silxweakref from silx.utils.deprecation import deprecated import tomwer.resources _logger = logging.getLogger(__name__) """Module logger""" _cached_icons = weakref.WeakValueDictionary() """Cache loaded icons in a weak structure""" _supported_formats = None """Order of file format extension to check""" class AbstractAnimatedIcon(qt.QObject): """Store an animated icon. It provides an event containing the new icon everytime it is updated.""" def __init__(self, parent=None): """Constructor :param parent: Parent of the QObject :raises: ValueError when name is not known """ qt.QObject.__init__(self, parent) self.__targets = silxweakref.WeakList() self.__currentIcon = None iconChanged = qt.Signal(qt.QIcon) """Signal sent with a QIcon every time the animation changed.""" def register(self, obj): """Register an object to the AnimatedIcon. If no object are registered, the animation is paused. Object are stored in a weaked list. :param obj: An object """ if obj not in self.__targets: self.__targets.append(obj) self._updateState() def unregister(self, obj): """Remove the object from the registration. If no object are registered the animation is paused. :param object obj: A registered object """ if obj in self.__targets: self.__targets.remove(obj) self._updateState() def hasRegistredObjects(self) -> bool: """Returns true if any object is registered.""" return len(self.__targets) def isRegistered(self, obj) -> bool: """Returns true if the object is registered in the AnimatedIcon. :param object obj: An object """ return obj in self.__targets def currentIcon(self) -> qt.QIcon: """Returns the icon of the current frame.""" return self.__currentIcon def _updateState(self): """Update the object according to the connected objects.""" pass def _setCurrentIcon(self, icon): """Store the current icon and emit a `iconChanged` event. :param qt.QIcon icon: The current icon """ self.__currentIcon = icon self.iconChanged.emit(self.__currentIcon) class MovieAnimatedIcon(AbstractAnimatedIcon): """Store a looping QMovie to provide icons for each frames. Provides an event with the new icon every time the movie frame is updated.""" def __init__(self, filename, parent=None): """Constructor :param filename: An icon name to an animated format :param parent: Parent of the QObject :raises: ValueError when name is not known """ AbstractAnimatedIcon.__init__(self, parent) qfile = getQFile(filename) self.__movie = qt.QMovie(qfile.fileName(), qt.QByteArray(), parent) self.__movie.setCacheMode(qt.QMovie.CacheAll) self.__movie.frameChanged.connect(self.__frameChanged) self.__cacheIcons = {} self.__movie.jumpToFrame(0) self.__updateIconAtFrame(0) def __frameChanged(self, frameId): """Callback every time the QMovie frame change :param frameId: Current frame id """ self.__updateIconAtFrame(frameId) def __updateIconAtFrame(self, frameId): """ Update the current stored QIcon :param frameId: Current frame id """ if frameId in self.__cacheIcons: icon = self.__cacheIcons[frameId] else: icon = qt.QIcon(self.__movie.currentPixmap()) self.__cacheIcons[frameId] = icon self._setCurrentIcon(icon) def _updateState(self): """Update the movie play according to internal stat of the AnimatedIcon.""" self.__movie.setPaused(not self.hasRegistredObjects()) class MultiImageAnimatedIcon(AbstractAnimatedIcon): """Store a looping QMovie to provide icons for each frames. Provides an event with the new icon every time the movie frame is updated.""" def __init__(self, filename, parent=None): """Constructor :param filename: An icon name to an animated format :param parent: Parent of the QObject :raises: ValueError when name is not known """ AbstractAnimatedIcon.__init__(self, parent) self.__frames = [] for i in range(100): try: pixmap = getQPixmap("%s/%02d" % (filename, i)) except ValueError: break icon = qt.QIcon(pixmap) self.__frames.append(icon) if len(self.__frames) == 0: raise ValueError("Animated icon '%s' do not exists" % filename) self.__frameId = -1 self.__timer = qt.QTimer(self) self.__timer.timeout.connect(self.__increaseFrame) self.__updateIconAtFrame(0) def __increaseFrame(self): """Callback called every timer timeout to change the current frame of the animation """ frameId = (self.__frameId + 1) % len(self.__frames) self.__updateIconAtFrame(frameId) def __updateIconAtFrame(self, frameId): """ Update the current stored QIcon :param frameId: Current frame id """ self.__frameId = frameId icon = self.__frames[frameId] self._setCurrentIcon(icon) def _updateState(self): """Update the object to wake up or sleep it according to its use.""" if self.hasRegistredObjects(): if not self.__timer.isActive(): self.__timer.start(100) else: if self.__timer.isActive(): self.__timer.stop() class AnimatedIcon(MovieAnimatedIcon): """Store a looping QMovie to provide icons for each frames. Provides an event with the new icon every time the movie frame is updated. It may not be available anymore for the silx release 0.6. .. deprecated:: 0.5 Use :class:`MovieAnimatedIcon` instead. """ @deprecated def __init__(self, filename, parent=None): MovieAnimatedIcon.__init__(self, filename, parent=parent) def getWaitIcon(): """Returns a cached version of the waiting AbstractAnimatedIcon.""" return getAnimatedIcon("process-working") def getAnimatedIcon(name): """Create an AbstractAnimatedIcon from a resource name. The resource name can be prefixed by the name of a resource directory. For example "silx:foo.png" identify the resource "foo.png" from the resource directory "silx". If no prefix are specified, the file with be returned from the silx resource directory with a specific path "gui/icons". See also :func:`silx.resources.register_resource_directory`. Try to load a mng or a gif file, then try to load a multi-image animated icon. In Qt5 mng or gif are not used, because the transparency is not very well managed. :param name: Name of the icon, in one of the defined icons in this module. :return: Corresponding AbstractAnimatedIcon :raises: ValueError when name is not known """ key = name + "__anim" if key not in _cached_icons: qtMajorVersion = int(qt.qVersion().split(".")[0]) icon = None # ignore mng and gif in Qt5 if qtMajorVersion != 5: try: icon = MovieAnimatedIcon(name) except ValueError: icon = None if icon is None: try: icon = MultiImageAnimatedIcon(name) except ValueError: icon = None if icon is None: raise ValueError("Not an animated icon name: %s", name) _cached_icons[key] = icon else: icon = _cached_icons[key] return icon def getQIcon(name): """Create a QIcon from its name. The resource name can be prefixed by the name of a resource directory. For example "silx:foo.png" identify the resource "foo.png" from the resource directory "silx". If no prefix are specified, the file with be returned from the silx resource directory with a specific path "gui/icons". See also :func:`silx.resources.register_resource_directory`. :param name: Name of the icon, in one of the defined icons in this module. :return: Corresponding QIcon :raises: ValueError when name is not known """ if name not in _cached_icons: qfile = getQFile(name) pixmap = qt.QPixmap(qfile.fileName()) icon = qt.QIcon(pixmap) _cached_icons[name] = icon else: icon = _cached_icons[name] return icon def getQPixmap(name): """Create a QPixmap from its name. The resource name can be prefixed by the name of a resource directory. For example "silx:foo.png" identify the resource "foo.png" from the resource directory "silx". If no prefix are specified, the file with be returned from the silx resource directory with a specific path "gui/icons". See also :func:`silx.resources.register_resource_directory`. :param name: Name of the icon, in one of the defined icons in this module. :return: Corresponding QPixmap :raises: ValueError when name is not known """ qfile = getQFile(name) return qt.QPixmap(qfile.fileName()) def getQFile(name) -> qt.QFile: """Create a QFile from an icon name. Filename is found according to supported Qt formats. The resource name can be prefixed by the name of a resource directory. For example "silx:foo.png" identify the resource "foo.png" from the resource directory "silx". If no prefix are specified, the file with be returned from the silx resource directory with a specific path "gui/icons". See also :func:`silx.resources.register_resource_directory`. :param name: Name of the icon, in one of the defined icons in this module. :return: Corresponding QFile :raises: ValueError when name is not known """ global _supported_formats if _supported_formats is None: _supported_formats = [] supported_formats = qt.supportedImageFormats() order = ["svg", "png", "jpg"] for format_ in order: if format_ in supported_formats: _supported_formats.append(format_) if len(_supported_formats) == 0: _logger.error("No format supported for icons") else: _logger.debug("Format %s supported", ", ".join(_supported_formats)) for format_ in _supported_formats: format_ = str(format_) filename = tomwer.resources._resource_filename( "%s.%s" % (name, format_), default_directory=os.path.join("gui", "icons") ) qfile = qt.QFile(filename) if qfile.exists(): return qfile elif os.path.exists(filename): mess = filename + " exists, but is not supported by qt" _logger.warning(mess) raise ValueError("Not an icon name: %s" % name) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/illustrations.py0000644000175000017500000000760714757047403020424 0ustar00paynopayno"""Set of icons for buttons. Use :func:`getQIcon` to create Qt QIcon from the name identifying an icon. """ import logging import os import weakref from silx.gui import qt import tomwer.resources _logger = logging.getLogger(__name__) """Module logger""" _cached_icons = weakref.WeakValueDictionary() """Cache loaded icons in a weak structure""" _supported_formats = None """Order of file format extension to check""" def getQIcon(name): """Create a QIcon from its name. The resource name can be prefixed by the name of a resource directory. For example "silx:foo.png" identify the resource "foo.png" from the resource directory "silx". If no prefix are specified, the file with be returned from the silx resource directory with a specific path "gui/icons". See also :func:`silx.resources.register_resource_directory`. :param name: Name of the icon, in one of the defined icons in this module. :return: Corresponding QIcon :raises: ValueError when name is not known """ qfile = getQFile(name) pixmap = qt.QPixmap(qfile.fileName()) icon = qt.QIcon(pixmap) return icon def getQPixmap(name): """Create a QPixmap from its name. The resource name can be prefixed by the name of a resource directory. For example "silx:foo.png" identify the resource "foo.png" from the resource directory "silx". If no prefix are specified, the file with be returned from the silx resource directory with a specific path "gui/icons". See also :func:`silx.resources.register_resource_directory`. :param name: Name of the icon, in one of the defined icons in this module. :return: Corresponding QPixmap :raises: ValueError when name is not known """ qfile = getQFile(name) if qfile is None: raise ValueError("Not an illustration name: %s" % name) return qt.QPixmap(qfile.fileName()) def getQFile(name) -> qt.QFile: """Create a QFile from an icon name. Filename is found according to supported Qt formats. The resource name can be prefixed by the name of a resource directory. For example "silx:foo.png" identify the resource "foo.png" from the resource directory "silx". If no prefix are specified, the file with be returned from the silx resource directory with a specific path "gui/icons". See also :func:`silx.resources.register_resource_directory`. :param name: Name of the icon, in one of the defined icons in this module. :return: Corresponding QFile :raises: ValueError when name is not known """ # if the extension is given in the name, skip the supported_formats _name = name.replace(" ", "_") if "." in _name: return _getQFile(_name) global _supported_formats if _supported_formats is None: _supported_formats = [] supported_formats = qt.supportedImageFormats() order = ["mng", "gif", "svg", "png", "jpg"] for format_ in order: if format_ in supported_formats: _supported_formats.append(format_) if len(_supported_formats) == 0: _logger.error("No format supported for icons") else: _logger.debug("Format %s supported", ", ".join(_supported_formats)) for format_ in _supported_formats: format_ = str(format_) out = _getQFile("%s.%s" % (_name, format_)) if out and out.exists(): return out raise ValueError("Not an illustration name: %s" % _name) def getResourceFileName(name): return tomwer.resources._resource_filename( name, default_directory=os.path.join("gui", "illustrations") ) def _getQFile(name): filename = tomwer.resources._resource_filename( name, default_directory=os.path.join("gui", "illustrations") ) qfile = qt.QFile(filename) if qfile.exists(): return qfile else: return None ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/gui/imagefromfile.py0000644000175000017500000001001114764622416020276 0ustar00paynopayno"""Utils to load images from file""" from __future__ import annotations import functools import logging from silx.gui import qt from silx.io.url import DataUrl from silx.io.utils import open as open_hdf5 from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.synctools.imageloaderthread import ImageLoaderThread logger = logging.getLogger(__name__) class _Image(qt.QObject): def __init__(self, data): qt.QObject.__init__(self) self.data = data class ImageFromFile(_Image): """ Define an Image with a status """ LOADING_STATUS = {"loading": 0, "loaded": 1, "not loaded": 2} sigLoaded = qt.Signal(str) """Signal emitted when the file is loaded. Parameter is the file url""" def __init__(self, _file=None, index=None, data=None, _load=False, url=None): _Image.__init__(self, data) if url is not None: assert _file is None and index is None self.url = url else: assert isinstance(_file, str) data_path = None if _file.lower().endswith(".edf"): scheme = "fabio" else: def get_nabu_entry(): try: with open_hdf5(_file) as h5s: for node in h5s: if "reconstruction" in h5s[node]: return "/".join( (node, "reconstruction", "results", "data") ) except Exception as e: logger.error(e) data_path = get_nabu_entry() or None scheme = "silx" if index is not None: data_slice = (index,) else: data_slice = None self.url = DataUrl( file_path=_file, data_slice=data_slice, scheme=scheme, data_path=data_path, ) self._status = "not loaded" if data is None else "loaded" self.url_path = self.url.path() if _load is True: self.load() def load(self, sync=False): """ Load the data contained in the url. :param sync: if True: then wait for the image to be loaded for giving back hand """ if self._status == "loaded" and self.data is not None: self.sigLoaded.emit(self.url.path()) elif self._status == "loading": logger.debug("%s is already loading" % self.url.path()) else: self._status = "loading" self.loaderThread = ImageLoaderThread(url=self.url) callback = functools.partial( self._setData, self.url_path, self.loaderThread.getData ) self.loaderThread.finished.connect(callback) self.loaderThread.start() if sync is False: self.loaderThread.wait() def _setData(self, url_path, dataGetter): self.data = dataGetter() if self.data is not None: if self.data.ndim != 2: if self.data.shape[0] == 1: self.data = self.data.reshape(self.data.shape[1:]) elif self.data.shape[-1] == 1: self.data = self.data.reshape(self.data.shape[0:-1]) self._status = "loaded" self.sigLoaded.emit(url_path) def isLoaded(self): return self._status == "loaded" class FileWithImage(object): """Definition of file which can contain multiple images""" def __init__(self, _file): self.file = _file def getImages(self, _load): """ :param _load: if True then launch the load of the image :return: the list of images contained in the given file. """ if self.file.lower().endswith(TomwerScanBase.VALID_RECONS_EXTENSION): return [ImageFromFile(self.file)] else: logger.error("only deal with .edf and .vol extension") return [] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/gui/metadataloader.py0000644000175000017500000000167414764622416020456 0ustar00paynopayno"""Utils to load metadata (from a volume at the moment)""" import logging from silx.gui import qt from tomwer.core.volume.volumefactory import VolumeFactory _logger = logging.getLogger(__name__) __all__ = [ "VolumeMetadataLoader", ] class VolumeMetadataLoader(qt.QThread): """Thread to load metadata from a given volume""" def __init__(self, parent, tomo_obj_identifier: str): super().__init__(parent=parent) self.volume = VolumeFactory.create_tomo_object_from_identifier( tomo_obj_identifier ) self.metadata = None def run(self): try: self.metadata = self.volume.load_metadata() except IOError: self.metadata = None except Exception as e: _logger.error( "Fail to load metadata from %s. Error is %s", self.volume.get_identifier(), e, ) self.metadata = None ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/gui/qconfigfile.py0000644000175000017500000000141614764622416017767 0ustar00paynopayno"""contains 'QConfigFileDialog': dialog to get / set a .cfg file""" import os from silx.gui import qt class QConfigFileDialog(qt.QFileDialog): """dialog to get / set a configuration file (as a .cfg file)""" def __init__(self, parent, multiSelection=False): qt.QFileDialog.__init__(self, parent) self.setNameFilters( [ "config file (*.cfg *.conf *.config *.par)", "Any files (*)", ] ) self._selected_files = [] # check if 'TOMWER_DEFAULT_INPUT_DIR' has been set if os.environ.get("TOMWER_DEFAULT_INPUT_DIR", None) and os.path.exists( os.environ["TOMWER_DEFAULT_INPUT_DIR"] ): self.setDirectory(os.environ["TOMWER_DEFAULT_INPUT_DIR"]) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/qlefilesystem.py0000644000175000017500000000227415153325210020353 0ustar00paynopayno"""contains QLFileSystem class. Specific implementation of the QLineEdit to select a file path.""" from __future__ import annotations from silx.gui import qt class QLFileSystem(qt.QLineEdit): """ QLineEdit with a completer using a QDirModel """ def __init__(self, text, parent, filters=None, **kwargs): super().__init__(parent=parent, **kwargs) self.completer = create_completer(filters=filters) self.setCompleter(self.completer) if text is not None: self.setText(text) def create_completer(filters=None) -> qt.QCompleter: completer = qt.QCompleter() if qt.BINDING in ("PyQt5", "PySide2"): # note: should work with PyQt5 but we get some troubles with it on esrf deployment # see https://gitlab.esrf.fr/XRD/darfix/-/issues/174 model = qt.QDirModel(completer) else: completer.setCompletionRole(qt.QFileSystemModel.FilePathRole) model = qt.QFileSystemModel(completer) model.setRootPath(qt.QDir.currentPath()) model.setOption(qt.QFileSystemModel.DontWatchForChanges) if filters is not None: model.setFilter(filters) completer.setModel(model) return completer ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9371016 tomwer-1.6.17/src/tomwer/gui/reconstruction/0000755000175000017500000000000015153325403020173 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/__init__.py0000644000175000017500000000013714764622416022320 0ustar00paynopayno"""Widgets related to tomography reconstruction (cor search, nabu volume reconstruction...)""" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9371016 tomwer-1.6.17/src/tomwer/gui/reconstruction/axis/0000755000175000017500000000000015153325403021137 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/axis/AxisMainWindow.py0000644000175000017500000002265115153325210024414 0ustar00paynopayno""" contains gui relative to axis calculation using sinogram """ from __future__ import annotations import logging from silx.gui import qt from tomwer.gui.utils.qt_utils import block_signals from tomwer.core.process.reconstruction.axis.mode import AxisMode from tomwer.core.process.reconstruction.utils.cor import ( absolute_pos_to_relative, relative_pos_to_absolute, ) from tomwer.core.scan.scanbase import TomwerScanBase from ...utils.scandescription import ScanNameLabelAndShape from .AxisWidget import AxisWidget from .ControlWidget import ControlWidget _logger = logging.getLogger(__file__) class AxisMainWindow(qt.QMainWindow): """ Main window for the center of rotation search. It displays: * scan information * AxisWidget * allows to set the cor value as absolute and relative and edit it """ sigComputationRequested = qt.Signal() """emit when the user request for computation""" sigApply = qt.Signal() """emit when the user validate the axis value""" sigLockCORValueChanged = qt.Signal(bool) """bool: True if locked""" sigLockModeChanged = qt.Signal() """Signal emitted when the lock mode on the mode change""" sigModeChanged = qt.Signal(str) """signal emit when the mode is changed""" sigSinogramReady = qt.Signal() """signal emit when the sinogram load is complete and processing ready""" sigAxisEditionLocked = qt.Signal(bool) """Signal emitted when the status of the reconstruction parameters edition change""" def __init__(self, axis_params, parent=None, backend=None): super().__init__(parent) self._mainWidget = qt.QWidget(self) self._mainWidget.setLayout(qt.QVBoxLayout()) # add scan name self._scan_label = ScanNameLabelAndShape(parent=self) self._mainWidget.layout().addWidget(self._scan_label) self.setDockOptions(qt.QMainWindow.AnimatedDocks) # Axis Widget self._axis_params = axis_params self._axisWidget = AxisWidget( parent=self, axis_params=axis_params, backend=backend ) self._mainWidget.layout().addWidget(self._axisWidget) self.setCentralWidget(self._mainWidget) # append cor editor to the radio axis widget self._controlWidget = ControlWidget(parent=self) self._controlWidget.setSizePolicy( qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum ) self._controlDockWidget = qt.QDockWidget(parent=self) self._controlDockWidget.setSizePolicy( qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum ) self._controlDockWidget.layout().setContentsMargins(0, 0, 0, 0) self._controlDockWidget.layout().setSpacing(0) self._controlDockWidget.setMaximumHeight(150) self._controlDockWidget.setWidget(self._controlWidget) self._controlDockWidget.setFeatures(qt.QDockWidget.DockWidgetMovable) self._axisWidget.addDockWidget( qt.Qt.RightDockWidgetArea, self._controlDockWidget ) # set up if self._axis_params.mode is AxisMode.manual: self._controlWidget.setPosition( self._axis_params.relative_cor_value, self._axis_params.absolute_cor_value, ) self._controlWidget._positionInfo.setAxisParams(self._axis_params) # connect signal / slots self._controlWidget.sigComputationRequest.connect(self.sigComputationRequested) self._controlWidget.sigValidateRequest.connect(self.sigApply) self._controlWidget.sigLockCORValueChanged.connect(self._CORValueLocked) self._axisWidget.sigLockModeChanged.connect(self.sigLockModeChanged) self._axisWidget.sigPositionChanged.connect(self._setPositionFrmTuple) self._controlWidget._positionInfo.sigRelativeValueSet.connect( self._forceRelativePosition ) self._controlWidget._positionInfo.sigAbsolueValueSet.connect( self._forceAbsolutePosition ) def _forceRelativePosition(self, value: float): self.setMode(AxisMode.manual) self.setPosition( relative_value=value, absolute_value=None, ) def _forceAbsolutePosition(self, value: float): self.setMode(AxisMode.manual) self.setPosition( relative_value=None, absolute_value=value, ) def setAutoUpdateEstimatedCor(self, value): self._axisWidget._settingsWidget._mainWidget.setUpdateXRotationAxisPixelPositionOnNewScan( value ) def manual_uses_full_image(self, value): self._axisWidget.manual_uses_full_image(value) def _modeChanged(self): self.getAxisParams().mode = self.getMode() def _CORValueLocked(self, lock): if lock: self.setMode(AxisMode.manual) self.setModeLock(lock) self.sigLockCORValueChanged.emit(lock) def _setPositionFrmTuple(self, value): self.setPosition(relative_value=value[0]) def setPosition(self, relative_value: float, absolute_value: float = None) -> None: if ( absolute_value is None and self._axis_params.frame_width is not None and relative_value is not None ): try: absolute_value = relative_pos_to_absolute( relative_pos=relative_value, det_width=self._axis_params.frame_width ) except TypeError: absolute_value = None if ( relative_value is None and self._axis_params.frame_width is not None and absolute_value is not None ): try: relative_value = absolute_pos_to_relative( absolute_pos=absolute_value, det_width=self._axis_params.frame_width ) except TypeError: relative_value = None self._controlWidget.setPosition( relative_cor=relative_value, abs_cor=absolute_value ) if relative_value is not None: self._axisWidget.setXShift(relative_value) else: self._axisWidget.resetShift() def getAxisParams(self): return self._axis_params def setScan(self, scan: TomwerScanBase, set_position: bool = False): """ set the gui for this scan :param scan: """ self._axisWidget.setScan(scan=scan) if set_position is True and scan.axis_params is not None: self.setPosition( scan.axis_params.relative_cor_value, scan.axis_params.relative_cor_value ) elif set_position is False: if scan.dim_1 is not None: # if absolute position is know and relative position not (in the case the user already define absolute position only): has_absolute_val_already = not self._controlWidget._positionInfo._absolutePositionQLE.text().startswith( (".", "?") ) has_relative_val_already = not self._controlWidget._positionInfo._relativePositionQLE.text().startswith( (".", "?") ) if ( self.getMode() is AxisMode.manual and has_absolute_val_already and not has_relative_val_already ): self._controlWidget._updateRelativePosition(width=scan.dim_1) else: self._controlWidget._updateAbsolutePosition(width=scan.dim_1) def _computationRequested(self) -> None: self.sigComputationRequested.emit() def _setModeLockFrmSettings(self, lock): with block_signals(self): self._axisWidget._setModeLockFrmSettings(lock) def _setValueLockFrmSettings(self, lock): with block_signals(self): self.setValueLock(lock) def setModeLock(self, lock): assert type(lock) is bool self._axisWidget.setLocked(lock) def isModeLock(self): return self._axisWidget.isModeLock() def isValueLock(self): return self._controlWidget.isValueLock() def setValueLock(self, lock): self._controlWidget.setValueLock(lock) def setReconsParams(self, recons_params): self._axis_params = recons_params self._axisWidget.setReconsParams(axis=recons_params) if recons_params.mode is AxisMode.manual: self._controlWidget.setPosition( self._axis_params.relative_cor_value, self._axis_params.absolute_cor_value, ) # expose API def hideLockButton(self) -> None: self._controlWidget.hideLockButton() def hideApplyButton(self) -> None: self._controlWidget.hideApplyButton() def setMode(self, mode): mode = AxisMode.from_value(mode) self._axisWidget.setMode(mode) self._axis_params.mode = mode self.sigModeChanged.emit(mode.value) def getMode(self): return self._axisWidget.getMode() def getEstimatedCor(self) -> float: return self._axisWidget.getEstimatedCor() def setEstimatedCor(self, value: float): self._axisWidget.setEstimatedCor(value=value) def getAutoUpdateEstimatedCor(self): return self._axisWidget.updateXRotationAxisPixelPositionOnNewScan() def isYAxisInverted(self) -> bool: return self._axisWidget.isYAxisInverted() def setYAxisInverted(self, checked: bool): return self._axisWidget.setYAxisInverted(checked=checked) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/axis/AxisOptionsWidget.py0000644000175000017500000002761015153325210025137 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from tomwer.core.process.reconstruction.axis.mode import AxisMode, AXIS_MODE_METADATAS from tomwer.synctools.axis import QAxisRP from tomwer.core.process.reconstruction.axis.params import AxisCalculationInput from tomwer.gui.utils.qt_utils import block_signals from tomwer.gui.utils.scrollarea import QComboBoxIgnoreWheel, QSpinBoxIgnoreWheel from tomwer.core.process.reconstruction.axis.params import ( DEFAULT_CMP_N_SUBSAMPLING_Y, DEFAULT_CMP_OVERSAMPLING, DEFAULT_CMP_TAKE_LOG, DEFAULT_CMP_THETA, ) class AxisOptionsWidget(qt.QWidget): """ GUI to define (advanced) option of the AxisTask Used as a tab of the AxisSettingsTabWidget """ sigChanged = qt.Signal() """Emit when the options changed""" def __init__(self, parent, axis_params): qt.QWidget.__init__(self, parent=parent) assert isinstance(axis_params, QAxisRP) self._axis_params = axis_params self.setLayout(qt.QVBoxLayout()) # cor_options self._corOptsWidget = qt.QWidget(self) self._corOptsWidget.setLayout(qt.QFormLayout()) self._corOpts = qt.QLineEdit(self) self._corOpts.setToolTip( "Options for methods finding automatically the rotation axis position. 'side', 'near_pos' and 'near_width' are already provided by dedicated interface. The parameters are separated by commas and passed as 'name=value'. Mind the semicolon separator (;)." ) self._corOpts.setPlaceholderText("low_pass=1; high_pass=20") self._corOptsWidget.layout().addRow("cor advanced options", self._corOpts) self.layout().addWidget(self._corOptsWidget) # padding option self._padding_widget = qt.QGroupBox("padding mode") self._padding_widget.setCheckable(True) self.layout().addWidget(self._padding_widget) self._padding_widget.setLayout(qt.QHBoxLayout()) self._qbPaddingMode = QComboBoxIgnoreWheel(self._padding_widget) for _mode in ( "constant", "edge", "linear_ramp", "maximum", "mean", "median", "minimum", "reflect", "symmetric", "wrap", ): self._qbPaddingMode.addItem(_mode) def_index = self._qbPaddingMode.findText("edge") self._qbPaddingMode.setCurrentIndex(def_index) self._padding_widget.layout().addWidget(self._qbPaddingMode) # define common options self._commonOpts = qt.QWidget(parent=self) self._commonOpts.setLayout(qt.QFormLayout()) self._qcbDataMode = qt.QComboBox(parent=self) for data_mode in AxisCalculationInput: # paganin is not managed for sinogram self._qcbDataMode.addItem(data_mode.name(), data_mode) self._qcbDataMode.hide() self.layout().addWidget(self._commonOpts) # composite method advanced options self._compositeOptsGroup = CompositeOptsGroup( parent=self, axis_params=axis_params ) self.layout().addWidget(self._compositeOptsGroup) # set up self.setCalculationInputType(self._axis_params.calculation_input_type) self._compositeOptsGroup.setVisible( self._axis_params.mode in (AxisMode.near, AxisMode.composite_coarse_to_fine) ) # connect signal / slot self._corOpts.editingFinished.connect(self._updateAdvancedCorOptions) self._qcbDataMode.currentIndexChanged.connect(self._updateInputType) self._axis_params.sigChanged.connect(self._axis_params_changed) self._qbPaddingMode.currentIndexChanged.connect(self._paddingModeChanged) self._padding_widget.toggled.connect(self._paddingModeChanged) self._compositeOptsGroup.sigChanged.connect(self.sigChanged) def _axis_params_changed(self): with block_signals(self): # update according to AxisCalculationInput index = self._qcbDataMode.findText( self._axis_params.calculation_input_type.name() ) if index >= 0: self._qcbDataMode.setCurrentIndex(index) # update advanced cor options visibility (not relevant if mode is manual or read) axis_mode = self._axis_params.mode self._corOptsWidget.setVisible( axis_mode not in ( AxisMode.manual, AxisMode.read, ) ) # update cor options value self.setCorOptions(self._axis_params.extra_cor_options) self.setPaddingMode(self._axis_params.padding_mode) self._padding_widget.setVisible( AXIS_MODE_METADATAS[axis_mode].allows_padding ) def _updateInputType(self, *arg, **kwargs): self._axis_params.calculation_input_type = self.getCalculationInputType() self.sigChanged.emit() def _paddingModeChanged(self, *args, **kwargs): self._axis_params.padding_mode = self.getPaddingMode() self.sigChanged.emit() def getPaddingMode(self): if self._padding_widget.isChecked(): return self._qbPaddingMode.currentText() else: return None def setPaddingMode(self, mode): index = self._qbPaddingMode.findText(mode) if index >= 0: self._qbPaddingMode.setCurrentIndex(index) self._paddingModeChanged() def _updateAdvancedCorOptions(self, *args, **kwargs): self._axis_params.extra_cor_options = self.getCorOptions() self.sigChanged.emit() def getCalculationInputType(self, *arg, **kwargs): return AxisCalculationInput.from_value(self._qcbDataMode.currentText()) def setCalculationInputType(self, calculation_type): calculation_type = AxisCalculationInput.from_value(calculation_type) index_dm = self._qcbDataMode.findText(calculation_type.name()) self._qcbDataMode.setCurrentIndex(index_dm) def setAxisParams(self, axis): self._axis_params = axis with block_signals(self): index = self._qcbDataMode.findText(axis.calculation_input_type.name()) self._qcbDataMode.setCurrentIndex(index) self._compositeOptsGroup.setAxisParams(axis) def getCorOptions(self): return self._corOpts.text() def setCorOptions(self, opts: str | None): with block_signals(self._axis_params): self._corOpts.clear() if opts: self._corOpts.setText(opts) self._updateAdvancedCorOptions() def setMode(self, mode: AxisMode): composite_opts_visible = AxisMode.from_value(mode) in ( AxisMode.composite_coarse_to_fine, AxisMode.near, ) self._compositeOptsGroup.setVisible(composite_opts_visible) class CompositeOptsGroup(qt.QGroupBox): """Group box dedicated to the composite algorithms""" sigChanged = qt.Signal() """Emit when the options changed""" def __init__(self, title="composite options", parent=None, axis_params=None): self._axis_params = axis_params super().__init__(title, parent) ## options for the composite mode self.setLayout(qt.QFormLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self._thetaSB = QSpinBoxIgnoreWheel(self) self._thetaSB.setRange(0, 360) self._thetaSB.setValue(DEFAULT_CMP_THETA) self._thetaSB.setToolTip("a radio will be picked each theta degrees") self._thetaLabel = qt.QLabel("angle interval (in degree)", self) self._thetaLabel.setToolTip( "algorithm will take one projection each 'angle interval'. Also know as 'theta'" ) self.layout().addRow(self._thetaLabel, self._thetaSB) self._oversamplingSB = QSpinBoxIgnoreWheel(self) self._oversamplingSB.setRange(1, 999999) self._oversamplingSB.setValue(DEFAULT_CMP_OVERSAMPLING) self._oversamplingSB.setToolTip("sinogram oversampling") self.layout().addRow("oversampling", self._oversamplingSB) self._nearWidthSB = QSpinBoxIgnoreWheel(self) self._nearWidthSB.setRange(1, 999999) self._nearWidthSB.setValue(0) self._nearWidthSB.setToolTip("position to be used with near option") self._nearWidthLabel = qt.QLabel("near width", self) self._nearWidthLabel.setToolTip("position to be used with near option") self.layout().addRow(self._nearWidthLabel, self._nearWidthSB) self._subsamplingYSB = QSpinBoxIgnoreWheel(self) self._subsamplingYSB.setRange(1, 999999) self._subsamplingYSB.setValue(DEFAULT_CMP_N_SUBSAMPLING_Y) self._subsamplingYSB.setToolTip("sinogram number of subsampling along y") self.layout().addRow("n_subsampling_y", self._subsamplingYSB) self._takeLogCB = qt.QCheckBox(self) self._takeLogCB.setToolTip("Take logarithm") self._takeLogCB.setChecked(DEFAULT_CMP_TAKE_LOG) self._takeTheLogLabel = qt.QLabel("linearisation (-log(I/I0))") self._takeTheLogLabel.setToolTip( "take (-log(I/I0)) as input. Also know as 'take_log' option" ) self.layout().addRow(self._takeTheLogLabel, self._takeLogCB) # connect signal / slot self._thetaSB.valueChanged.connect(self._changed) self._oversamplingSB.valueChanged.connect(self._changed) self._subsamplingYSB.valueChanged.connect(self._changed) self._nearWidthSB.valueChanged.connect(self._changed) self._takeLogCB.toggled.connect(self._changed) def setAxisParams(self, axis_params): with block_signals(self): self.setConfiguration(axis_params.composite_options) self._axis_params = axis_params def _changed(self): if self._axis_params is not None: self._axis_params.composite_options = self.getConfiguration() self.sigChanged.emit() def getTheta(self) -> int: return self._thetaSB.value() def setTheta(self, theta: int) -> None: self._thetaSB.setValue(theta) def getOversampling(self) -> int: return self._oversamplingSB.value() def setOversampling(self, oversampling: int) -> None: self._oversamplingSB.setValue(oversampling) def getNearWidth(self) -> int: return self._nearWidthSB.value() def setNearWidth(self, value) -> int: return self._nearWidthSB.setValue(value) def getSubSamplingY(self) -> int: return self._subsamplingYSB.value() def setSubSamplingY(self, subsampling: int) -> None: self._subsamplingYSB.setValue(subsampling) def getTakeLog(self) -> bool: return self._takeLogCB.isChecked() def setTakeLog(self, log: bool) -> None: self._takeLogCB.setChecked(log) def getConfiguration(self) -> dict: return { "theta": self.getTheta(), "oversampling": self.getOversampling(), "n_subsampling_y": self.getSubSamplingY(), "take_log": self.getTakeLog(), "near_width": self.getNearWidth(), } def setConfiguration(self, opts: dict) -> None: if not isinstance(opts, dict): raise TypeError("opts should be an instance of dict") # theta theta = opts.get("theta", None) if theta is not None: self.setTheta(theta=theta) # oversampling oversampling = opts.get("oversampling", None) if oversampling is not None: self.setOversampling(oversampling) # n subsampling y n_subsampling_y = opts.get("n_subsampling_y", None) if n_subsampling_y is not None: self.setSubSamplingY(n_subsampling_y) # near_width near_width = opts.get("near_width", None) if near_width is not None: self.setNearWidth(near_width) # take log take_log = opts.get("take_log", None) if take_log is not None: self.setTakeLog(take_log) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/axis/AxisSettingsWidget.py0000644000175000017500000006672715153325210025320 0ustar00paynopaynofrom __future__ import annotations import enum import logging from silx.gui import qt from tomwer.core.process.reconstruction.axis import mode as axis_mode from tomwer.gui.utils.qt_utils import block_signals from tomwer.gui.utils.step import StepSizeSelectorWidget from tomwer.synctools.axis import QAxisRP from tomwer.gui.settings import EDITING_BACKGROUND_COLOR from .AxisOptionsWidget import AxisOptionsWidget from .CalculationWidget import CalculationWidget from .InputWidget import InputWidget _logger = logging.getLogger(__name__) @enum.unique class ShiftMode(enum.Enum): x_only = 0 y_only = 1 x_and_y = 2 class AxisSettingsWidget(qt.QWidget): """ Widget to define settings for COR search (which algorithm to use...) """ sigShiftChanged = qt.Signal(float, float) """Signal emitted when requested shift changed. Parameter is x, y""" sigModeLockChanged = qt.Signal(bool) """Signal emitted when the mode is lock or unlock""" sigResetZoomRequested = qt.Signal() """Signal emitted when request a zoom reset from the plot""" sigSubSamplingChanged = qt.Signal() """Signal emitted when sub-sampling change""" sigUrlChanged = qt.Signal() """Signal emit when frames urls changed""" sigModeChanged = qt.Signal(str) """Signal emit when mode (algorithm) is changed""" sigRoiChanged = qt.Signal(object) """Signal emitted when the ROI changed""" sigAuto = qt.Signal() """Signal emitted when the auto button is activated""" def __init__(self, parent, reconsParams): assert isinstance(reconsParams, QAxisRP) qt.QWidget.__init__(self, parent) self._xShift = 0 self._yShift = 0 self._recons_params = reconsParams self._axisParams = None self.setLayout(qt.QVBoxLayout()) self._manualSelectionWidget = ManualAxisSelectionWidget( parent=self, shift_mode=ShiftMode.x_only ) self._manualSelectionWidget.layout().setContentsMargins(0, 0, 0, 0) self._displacementSelector = self._manualSelectionWidget._displacementSelector self._shiftControl = self._manualSelectionWidget._shiftControl self._roiControl = self._manualSelectionWidget._roiControl self._imgOpts = self._manualSelectionWidget._imgOpts self._mainWidget = AxisSettingsTabWidget( parent=self, recons_params=self._recons_params, ) # append the Manual selection to the AxisTabWidget to have all widget related to axis settings together self._mainWidget._calculationWidget.layout().addWidget( self._manualSelectionWidget ) self.layout().addWidget(self._mainWidget) # signal / slot connection self._shiftControl.sigShiftLeft.connect(self._incrementLeftShift) self._shiftControl.sigShiftRight.connect(self._incrementRightShift) self._shiftControl.sigShiftTop.connect(self._incrementTopShift) self._shiftControl.sigShiftBottom.connect(self._incrementBottomShift) self._shiftControl.sigReset.connect(self._resetShift) self._shiftControl.sigShiftChanged.connect(self._setShiftAndSignal) self._mainWidget.sigLockModeChanged.connect(self._modeLockChanged) self._manualSelectionWidget.sigResetZoomRequested.connect( self._requestZoomReset ) self._imgOpts.sigSubSamplingChanged.connect(self.sigSubSamplingChanged) self._mainWidget.sigUrlChanged.connect(self.sigUrlChanged) self._roiControl.sigRoiChanged.connect(self.sigRoiChanged) self._shiftControl.sigAuto.connect(self.sigAuto) self._mainWidget.sigModeChanged.connect(self.sigModeChanged) # set up interface self.setAxisParams(self._recons_params) def setScan(self, scan): self._mainWidget.setScan(scan=scan) self._roiControl.setScan(scan=scan) def manual_uses_full_image(self, value): self._roiControl.manual_uses_full_image(value) def _incrementLeftShift(self): self._incrementShift("left") def _incrementRightShift(self): self._incrementShift("right") def _incrementTopShift(self): self._incrementShift("top") def _incrementBottomShift(self): self._incrementShift("bottom") def _setShiftAndSignal(self, x, y): if x == self._xShift and y == self._yShift: return self.setShift(x, y) self._shiftControl._updateShiftInfo(x=x, y=y) self.sigShiftChanged.emit(x, y) def setAxisParams(self, axis): if axis == self._axisParams: return assert isinstance(axis, QAxisRP) with block_signals(self): if self._axisParams: self._axisParams.sigChanged.disconnect(self._updateAxisView) self._axisParams = axis self.setXShift(self._axisParams.relative_cor_value) self._mainWidget.setAxisParams(self._axisParams) self._updateAxisView() self._axisParams.sigChanged.connect(self._updateAxisView) def _modeLockChanged(self, lock): self.sigModeLockChanged.emit(lock) def setMode(self, mode): with block_signals(self._axisParams): self._axisParams.mode = mode self._mainWidget._calculationWidget.setMode(mode) self._mainWidget._optionsWidget.setMode(mode) self._updateAxisView() self._axisParams.sigChanged.emit() def _updateAxisView(self): with block_signals(self._axisParams): if self._axisParams.relative_cor_value not in (None, "..."): self.setXShift(self._axisParams.relative_cor_value) self._manualSelectionWidget.setVisible( self._axisParams.mode is axis_mode.AxisMode.manual ) def getAxisParams(self): return self._axisParams def _incrementShift(self, direction): assert direction in ("left", "right", "top", "bottom") if direction == "left": self.setXShift(self._xShift - self.getShiftStep()) elif direction == "right": self.setXShift(self._xShift + self.getShiftStep()) elif direction == "top": self.setYShift(self._yShift + self.getShiftStep()) else: self.setYShift(self._yShift - self.getShiftStep()) self._shiftControl._updateShiftInfo(x=self._xShift, y=self._yShift) def _resetShift(self): with block_signals(self._axisParams): self.setXShift(0) self.setYShift(0) self._shiftControl._updateShiftInfo(x=self._xShift, y=self._yShift) self.sigShiftChanged.emit(self._xShift, self._yShift) def getXShift(self): if self._xShift == "...": return 0 return self._xShift def getYShift(self): if self._yShift == "...": return 0 return self._yShift def setXShift(self, x: float): self.setShift(x=x, y=self._yShift) def setYShift(self, y): self.setShift(x=self._xShift, y=y) def setShift(self, x, y): if x == self._xShift and y == self._yShift: return self._xShift = x if x is not None else 0.0 self._yShift = y if y is not None else 0.0 if self._axisParams: with block_signals(self._axisParams): self._axisParams.set_relative_value(x) self._shiftControl._updateShiftInfo(x=self._xShift, y=self._yShift) if not isinstance(self._xShift, str): # filter `...` and `?` values (used for issues or processing) self.sigShiftChanged.emit(self._xShift, self._yShift) def reset(self): with block_signals(self): self.setShift(0, 0) self.sigShiftChanged.emit(self._xShift, self._yShift) def setLocked(self, locked): self._mainWidget.setEnabled(not locked) def _requestZoomReset(self): self.sigResetZoomRequested.emit() # expose API def setEstimatedCor(self, value): self._mainWidget.setEstimatedCorValue(value=value) def updateXRotationAxisPixelPositionOnNewScan(self) -> bool: return self._mainWidget.updateXRotationAxisPixelPositionOnNewScan() def setUpdateXRotationAxisPixelPositionOnNewScan(self, update: bool): self._mainWidget.setUpdateXRotationAxisPixelPositionOnNewScan(update=update) def getEstimatedCor(self): return self._mainWidget.getEstimatedCor() def getROIDims(self): return self._roiControl.getROIDims() def getShiftStep(self): return self._displacementSelector.getStepSize() def setShiftStep(self, value): self._displacementSelector.setStepSize(value=value) def getROIOrigin(self): return self._roiControl.getROIOrigin() def getImgSubSampling(self): return self._imgOpts.getSubSampling() def getMode(self): return self._mainWidget.getMode() def isModeLock(self): return self._mainWidget.isModeLock() def setModeLock(self, mode): return self._mainWidget.setModeLock(mode=mode) def isYAxisInverted(self) -> bool: return self._mainWidget.isYAxisInverted() def setYAxisInverted(self, checked: bool): return self._mainWidget.setYAxisInverted(checked=checked) class ManualAxisSelectionWidget(qt.QWidget): sigResetZoomRequested = qt.Signal() """Signal emitted when a zoom request is necessary (when change to full image)""" def __init__(self, parent, shift_mode): qt.QWidget.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) self._displacementSelector = StepSizeSelectorWidget( parent=self, fine_value=0.1, medium_value=1.0, rough_value=None, dtype=float, ) self.layout().addWidget(self._displacementSelector) self._shiftControl = _ShiftControl(parent=self, shift_mode=shift_mode) self.layout().addWidget(self._shiftControl) self._roiControl = _ROIControl(parent=self) self.layout().addWidget(self._roiControl) self._imgOpts = _ImgOpts(parent=self) self.layout().addWidget(self._imgOpts) # connect signal / slot self._roiControl.sigResetZoomRequested.connect(self.sigResetZoomRequested) class _ROIControl(qt.QGroupBox): """ Widget used to define the ROI on images to compare """ sigRoiChanged = qt.Signal(object) """Signal emitted when the ROI changed""" sigResetZoomRequested = qt.Signal() """Signal emitted when a zoom request is necessary (when change to full image)""" def __init__(self, parent): qt.QGroupBox.__init__(self, "ROI selection", parent) self.setLayout(qt.QVBoxLayout()) self._buttonGrp = qt.QButtonGroup(parent=self) self._buttonGrp.setExclusive(True) self._roiWidget = qt.QWidget(parent=self) self._roiWidget.setLayout(qt.QHBoxLayout()) self._roiWidget.layout().setContentsMargins(0, 0, 0, 0) self._fullImgButton = qt.QRadioButton("full image", parent=self) self._buttonGrp.addButton(self._fullImgButton) self.layout().addWidget(self._fullImgButton) self._roiButton = qt.QRadioButton("ROI", parent=self._roiWidget) self._roiWidget.layout().addWidget(self._roiButton) self._buttonGrp.addButton(self._roiButton) self._roiDefinition = _ROIDefinition(parent=self) self._roiWidget.layout().addWidget(self._roiDefinition) self.layout().addWidget(self._roiWidget) # connect signal / Slot self._roiButton.toggled.connect(self._roiDefinition.setEnabled) self._fullImgButton.toggled.connect(self.sigResetZoomRequested) self._roiButton.toggled.connect(self.sigResetZoomRequested) self._roiDefinition.sigRoiChanged.connect(self.sigRoiChanged) # setup for full image self._fullImgButton.setChecked(True) def getROIDims(self): if self._roiButton.isChecked(): return self._roiDefinition.getROIDims() else: return None def manual_uses_full_image(self, activate): if activate: self._fullImgButton.setChecked(True) else: self._roiButton.setChecked(True) # expose API def getROIOrigin(self): return self._roiDefinition.getROIOrigin() def setLimits(self, width, height): self._roiDefinition.setLimits(width=width, height=height) def setScan(self, scan): self._roiDefinition.setScan(scan=scan) class _ROIDefinition(qt.QWidget): """ Widget used to define ROI width and height. :note: emit ROI == None if setDisabled """ sigRoiChanged = qt.Signal(object) """Signal emitted when the ROI changed""" def __init__(self, parent): qt.QWidget.__init__(self, parent) self.setLayout(qt.QGridLayout()) self._already_set = False # width & height self.layout().addWidget(qt.QLabel("dims", self), 0, 0) self._widthSB = qt.QSpinBox(parent=self) self._widthSB.setSingleStep(2) self._widthSB.setMaximum(10000) self._widthSB.setSuffix(" px") self._widthSB.setPrefix("w: ") self._widthSB.setToolTip("ROI width") self.layout().addWidget(self._widthSB, 0, 1) self._heightSB = qt.QSpinBox(parent=self) self._heightSB.setSingleStep(2) self._heightSB.setSuffix(" px") self._heightSB.setPrefix("h: ") self._heightSB.setToolTip("ROI height") self._heightSB.setMaximum(10000) self.layout().addWidget(self._heightSB, 0, 2) # origin x and y position self.layout().addWidget(qt.QLabel("origin", self), 1, 0) self._xOriginSB = qt.QSpinBox(parent=self) self._xOriginSB.setSingleStep(10) self._xOriginSB.setMaximum(10000) self._xOriginSB.setPrefix("x: ") self.layout().addWidget(self._xOriginSB, 1, 1) self._yOriginSB = qt.QSpinBox(parent=self) self._yOriginSB.setSingleStep(10) self._yOriginSB.setPrefix("y: ") self._yOriginSB.setMaximum(10000) self.layout().addWidget(self._yOriginSB, 1, 2) # Signal / Slot connection self._widthSB.editingFinished.connect(self.__roiChanged) self._heightSB.editingFinished.connect(self.__roiChanged) self._xOriginSB.editingFinished.connect(self.__roiChanged) self._yOriginSB.editingFinished.connect(self.__roiChanged) def __roiChanged(self, *args, **kwargs): self.sigRoiChanged.emit((self.getROIDims(), self.getROIOrigin())) def setLimits(self, width, height): """ :param x: width maximum value :param height: height maximum value """ for spinButton in (self._widthSB, self._heightSB): spinButton.blockSignals(True) assert type(width) is int assert type(height) is int valueChanged = False if self._widthSB.value() > width: self._widthSB.setValue(width) valueChanged = True if self._heightSB.value() > height: self._heightSB.setValue(height) valueChanged = True # if this is the first limit definition, propose default width and # height if self._widthSB.value() == 0: self._widthSB.setValue(min(256, width)) valueChanged = True if self._heightSB.value() == 0: self._heightSB.setValue(min(256, height)) valueChanged = True # define minimum / maximum self._widthSB.setRange(1, width) self._heightSB.setRange(1, height) for spinButton in (self._widthSB, self._heightSB): spinButton.blockSignals(False) if valueChanged is True: self.__roiChanged() def getROIDims(self) -> tuple | None: """ :return: (width, height) or None """ if self.isEnabled(): return (self._widthSB.value(), self._heightSB.value()) else: return None def getROIOrigin(self): return (self._xOriginSB.value(), self._yOriginSB.value()) def setEnabled(self, *arg, **kwargs): qt.QWidget.setEnabled(self, *arg, **kwargs) self.__roiChanged() def setScan(self, scan): if not self._already_set: self._already_set = True try: x_origin = scan.dim_1 // 2 y_origin = scan.dim_2 // 2 self._xOriginSB.setValue(x_origin) self._yOriginSB.setValue(y_origin) except Exception: _logger.warning(f"unable to determine origin for {scan}") class AxisSettingsTabWidget(qt.QTabWidget): """ TabWidget containing all the settings of the AxisTask """ sigLockModeChanged = qt.Signal(bool) """signal emitted when the mode lock change""" sigUrlChanged = qt.Signal() """Signal emit when frames urls changed""" sigModeChanged = qt.Signal(str) """Signal emit when mode (algorithm) is changed""" sigUpdateXRotAxisPixelPosOnNewScan = qt.Signal() def __init__( self, recons_params: QAxisRP | None, parent=None, ): """ :param recons_params: reconstruction parameters edited by the widget """ qt.QTabWidget.__init__(self, parent) assert recons_params is not None # first tab 'calculation widget' self._calculationWidget = CalculationWidget( parent=self, axis_params=recons_params ) # second tab: options self._optionsWidget = AxisOptionsWidget(parent=self, axis_params=recons_params) self._inputWidget = InputWidget(parent=self, axis_params=recons_params) for widget in self._calculationWidget, self._optionsWidget: spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) widget.layout().addWidget(spacer) self.addTab(self._calculationWidget, "calculation") self.addTab(self._optionsWidget, "options") # simplify set up. Hide options self.addTab(self._inputWidget, "input") # set up self.setAxisParams(recons_params) self._updatePossibleInput() # connect signal / slot self._calculationWidget.sigLockModeChanged.connect(self.sigLockModeChanged) self.sigModeChanged.connect(self._updatePossibleInput) self.sigModeChanged.connect(self._updatePossibleOptions) self._inputWidget._sigUrlChanged.connect(self._urlChanged) self._calculationWidget.sigModeChanged.connect(self.sigModeChanged) self._calculationWidget.sigUpdateXRotAxisPixelPosOnNewScan.connect( self.sigUpdateXRotAxisPixelPosOnNewScan ) def _urlChanged(self): self.sigUrlChanged.emit() def setScan(self, scan): if scan is not None: self._calculationWidget.setScan(scan) self._inputWidget.setScan(scan) def setAxisParams(self, axis): with block_signals(self): self._calculationWidget.setAxisParams(axis) self._optionsWidget.setAxisParams(axis) self._inputWidget.setAxisParams(axis) def _updatePossibleInput(self): """Update Input tab according to the current mode""" current_mode = self.getMode() valid_inputs = axis_mode.AXIS_MODE_METADATAS[current_mode].valid_inputs if valid_inputs is None: self._inputWidget.setEnabled(False) else: self._inputWidget.setEnabled(True) self._inputWidget.setValidInputs(valid_inputs) def _updatePossibleOptions(self): mode = self.getMode() self._optionsWidget.setMode(mode) # expose API def isModeLock(self) -> bool: return self._calculationWidget.isModeLock() def setModeLock(self, mode): self._calculationWidget.setModeLock(mode=mode) def setEstimatedCorValue(self, value): self._calculationWidget.setEstimatedCorValue(value=value) def getEstimatedCor(self): return self._calculationWidget.getEstimatedCor() def updateXRotationAxisPixelPositionOnNewScan(self) -> bool: return self._calculationWidget.updateXRotationAxisPixelPositionOnNewScan() def setUpdateXRotationAxisPixelPositionOnNewScan(self, update: bool): self._calculationWidget.setUpdateXRotationAxisPixelPositionOnNewScan( update=update ) def getMode(self): """Return algorithm to use for axis calculation""" return self._calculationWidget.getMode() def isYAxisInverted(self) -> bool: return self._calculationWidget._estimatedCorWidget.isYAxisInverted() def setYAxisInverted(self, checked: bool): return self._calculationWidget._estimatedCorWidget.setYAxisInverted( checked=checked ) class _ShiftControl(qt.QWidget): """ Widget to control the shift step we want to apply """ sigShiftLeft = qt.Signal() """Signal emitted when the left button is activated""" sigShiftRight = qt.Signal() """Signal emitted when the right button is activated""" sigShiftTop = qt.Signal() """Signal emitted when the top button is activated""" sigShiftBottom = qt.Signal() """Signal emitted when the bottom button is activated""" sigReset = qt.Signal() """Signal emitted when the reset button is activated""" sigAuto = qt.Signal() """Signal emitted when the auto button is activated""" sigShiftChanged = qt.Signal(float, float) """Signal emitted ony when xLE and yLE edition is finished""" def __init__(self, parent, shift_mode: ShiftMode): """ :param parent: qt.QWidget :param shift_mode: what are the shift we want to control """ qt.QWidget.__init__(self, parent) self.setLayout(qt.QGridLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self._leftButton = qt.QPushButton("left", parent=self) self.layout().addWidget(self._leftButton, 1, 0) self._rightButton = qt.QPushButton("right", parent=self) self.layout().addWidget(self._rightButton, 1, 3) self._shiftInfo = _ShiftInformation(parent=self) self.layout().addWidget(self._shiftInfo, 1, 1) self._shiftInfo._updateShiftInfo(x=0.0, y=0.0) self._topButton = qt.QPushButton("top", parent=self) self.layout().addWidget(self._topButton, 0, 1) self._bottomButton = qt.QPushButton("bottom", parent=self) self.layout().addWidget(self._bottomButton, 2, 1) self._resetButton = qt.QPushButton("reset", parent=self) self.layout().addWidget(self._resetButton, 3, 2, 3, 4) self._autoButton = qt.QPushButton("auto", parent=self) self.layout().addWidget(self._autoButton, 3, 0, 3, 2) self._autoButton.hide() # Signal / Slot connection self._leftButton.pressed.connect(self.sigShiftLeft.emit) self._rightButton.pressed.connect(self.sigShiftRight.emit) self._topButton.pressed.connect(self.sigShiftTop.emit) self._bottomButton.pressed.connect(self.sigShiftBottom.emit) self._resetButton.pressed.connect(self.sigReset.emit) self._autoButton.pressed.connect(self.sigAuto.emit) self._shiftInfo.sigShiftChanged.connect(self.sigShiftChanged.emit) # expose API self._updateShiftInfo = self._shiftInfo._updateShiftInfo self.setShiftMode(shift_mode) def setShiftMode(self, shift_mode): show_x_shift = shift_mode in (ShiftMode.x_only, ShiftMode.x_and_y) show_y_shift = shift_mode in (ShiftMode.y_only, ShiftMode.x_and_y) self._leftButton.setVisible(show_x_shift) self._rightButton.setVisible(show_x_shift) self._topButton.setVisible(show_y_shift) self._bottomButton.setVisible(show_y_shift) self._shiftInfo._xLE.setVisible(show_x_shift) self._shiftInfo._xLabel.setVisible(show_x_shift) self._shiftInfo._yLE.setVisible(show_y_shift) self._shiftInfo._yLabel.setVisible(show_y_shift) class _ImgOpts(qt.QGroupBox): sigSubSamplingChanged = qt.Signal() """Signal emitted when the sub sampling change""" def __init__(self, parent, title="Image Option"): super().__init__(title, parent) self.setLayout(qt.QFormLayout()) self._subSamplingQSpinBox = qt.QSpinBox(self) self.layout().addRow("sub-sampling:", self._subSamplingQSpinBox) self._subSamplingQSpinBox.setMinimum(1) # set up self._subSamplingQSpinBox.setValue(1) # connect signal / slot self._subSamplingQSpinBox.valueChanged.connect(self._subSamplingChanged) def _subSamplingChanged(self): self.sigSubSamplingChanged.emit() def getSubSampling(self): return self._subSamplingQSpinBox.value() def setSubSampling(self, value): return self._subSamplingQSpinBox.setValue(int(value)) class _ShiftInformation(qt.QWidget): """ Widget displaying information about the current x and y shift. Both x shift and y shift are editable. """ class _ShiftLineEdit(qt.QLineEdit): def __init__(self, *args, **kwargs): qt.QLineEdit.__init__(self, *args, **kwargs) self._defaultBackgroundColor = None # validator validator = qt.QDoubleValidator(parent=self, decimals=2) self.setValidator(validator) self._getDefaultBackgroundColor() # connect signal / slot self.textEdited.connect(self._userEditing) self.editingFinished.connect(self._userEndEditing) def sizeHint(self): return qt.QSize(40, 10) def _getDefaultBackgroundColor(self): if self._defaultBackgroundColor is None: self._defaultBackgroundColor = self.palette().color( self.backgroundRole() ) return self._defaultBackgroundColor def _userEditing(self, *args, **kwargs): palette = self.palette() palette.setColor(self.backgroundRole(), EDITING_BACKGROUND_COLOR) self.setPalette(palette) def _userEndEditing(self, *args, **kwargs): palette = self.palette() palette.setColor( self.backgroundRole(), self._getDefaultBackgroundColor(), ) self.setPalette(palette) sigShiftChanged = qt.Signal(float, float) """Signal emitted ony when xLE and yLE edition is finished""" def __init__(self, parent): qt.QWidget.__init__(self, parent) self.setLayout(qt.QHBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.layout().setSpacing(0) self._xLabel = qt.QLabel("x=", parent=self) self.layout().addWidget(self._xLabel) self._xLE = _ShiftInformation._ShiftLineEdit("", parent=self) self.layout().addWidget(self._xLE) self._yLabel = qt.QLabel("y=", parent=self) self.layout().addWidget(self._yLabel) self._yLE = _ShiftInformation._ShiftLineEdit("", parent=self) self.layout().addWidget(self._yLE) # connect Signal / Slot self._xLE.editingFinished.connect(self._shiftChanged) self._yLE.editingFinished.connect(self._shiftChanged) def _updateShiftInfo(self, x, y): with block_signals(self): if x is None: x = 0.0 if y is None: y = 0.0 x_text = x if x_text != "...": x_text = "%.1f" % float(x) y_text = y if y_text != "...": y_text = "%.1f" % float(y) self._xLE.setText(x_text) self._yLE.setText(y_text) def _shiftChanged(self, *args, **kwargs): self.sigShiftChanged.emit(float(self._xLE.text()), float(self._yLE.text())) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/axis/AxisWidget.py0000644000175000017500000004652215153325210023566 0ustar00paynopaynofrom __future__ import annotations import logging import numpy import scipy.signal from silx.gui import qt from tomwer.core.process.reconstruction.axis import mode as axis_mode from tomwer.core.process.reconstruction.axis.anglemode import CorAngleMode from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils import image from tomwer.gui.utils.qt_utils import block_signals from tomwer.synctools.axis import QAxisRP from .CompareImages import CompareImages from .AxisSettingsWidget import AxisSettingsWidget _logger = logging.getLogger(__name__) class AxisWidget(qt.QMainWindow): """ Main widget for the computing the rotation axis. It contains: * CompareImages widget as the central widget to display two opposite radios once shifted (and flip) with the cor found * A control widget on the left to select the algorithm to be applied, algorithm options... :raises ValueError: given axis is not an instance of _QAxisRP """ sigAxisEditionLocked = qt.Signal(bool) """Signal emitted when the status of the reconstruction parameters edition change""" sigLockModeChanged = qt.Signal(bool) """signal emitted when the lock on the mode change""" sigPositionChanged = qt.Signal(tuple) """signal emitted when the center of rotation center change""" def __init__(self, axis_params, parent=None, backend=None): super().__init__(parent) if isinstance(axis_params, QAxisRP): self.__recons_params = axis_params else: raise TypeError("axis should be an instance of _QAxisRP") self._imgA = None self._imgB = None self._shiftedImgA = None self._flipB = True """Option if we want to flip the image B""" self._scan = None self._axis_params = None self._lastManualFlip = None """Cache for the last user entry for manual flip""" self._lastXShift = None # cache to know if the x shift has changed since self._lastYShift = None # cache to know if the y shift has changed self._lastXOrigin = None # cache to know if the x origin has changed since self._lastYOrigin = None # cache to know if the y origin has changed since self.setWindowFlags(qt.Qt.Widget) self._plot = CompareImages(parent=self, backend=backend) self._plot.setAutoResetZoom(False) _mode = CompareImages.VisualizationMode.COMPOSITE_A_MINUS_B self._plot.setVisualizationMode(_mode) self._plot.setAlignmentMode(CompareImages.AlignmentMode.STRETCH) self.setCentralWidget(self._plot) self._dockWidgetCtrl = qt.QDockWidget(parent=self) self._dockWidgetCtrl.layout().setContentsMargins(0, 0, 0, 0) self._dockWidgetCtrl.setFeatures(qt.QDockWidget.DockWidgetMovable) self._settingsWidget = AxisSettingsWidget( parent=self, reconsParams=self.__recons_params ) self._settingsWidgetScrollArea = qt.QScrollArea(self) self._settingsWidgetScrollArea.setWidgetResizable(True) self._settingsWidgetScrollArea.setWidget(self._settingsWidget) self._dockWidgetCtrl.setWidget(self._settingsWidgetScrollArea) self.addDockWidget(qt.Qt.RightDockWidgetArea, self._dockWidgetCtrl) # signal / slot connection self._settingsWidget.sigShiftChanged.connect(self._updateShift) self._settingsWidget.sigShiftChanged.connect(self._corChanged) self._settingsWidget.sigRoiChanged.connect(self._updateShift) self._settingsWidget.sigAuto.connect(self._updateAuto) self._settingsWidget.sigModeChanged.connect(self.setMode) self._settingsWidget.sigModeLockChanged.connect(self._modeLockChanged) self._settingsWidget.sigResetZoomRequested.connect(self._resetZoomPlot) self._settingsWidget.sigSubSamplingChanged.connect(self._updateSubSampling) self._settingsWidget.sigUrlChanged.connect(self._urlChanged) self._plot.sigCropImagesChanged.connect(self._updateShift) # adapt gui to the axis value self.setReconsParams(axis=self.__recons_params) self.getPlot().getPlot().setAxesDisplayed(True) def manual_uses_full_image(self, value): self._settingsWidget.manual_uses_full_image(value) def _modeLockChanged(self, lock): self.sigLockModeChanged.emit(lock) def _corChanged(self): self.sigPositionChanged.emit((self.getXShift(), self.getYShift())) def getPlot(self): return self._plot def _resetZoomPlot(self): self._plot.getPlot().resetZoom() def setMode(self, mode): """ Define the mode to use for radio axis :param mode: :return: """ mode = axis_mode.AxisMode.from_value(mode) with block_signals(self._settingsWidget): with block_signals(self._axis_params): self._settingsWidget.setMode(mode) if mode is axis_mode.AxisMode.manual: self._setModeLockFrmSettings(False) def setEstimatedCor(self, value): self._settingsWidget.setEstimatedCor(value=value) def getEstimatedCor(self): return self._settingsWidget.getEstimatedCor() def updateXRotationAxisPixelPositionOnNewScan(self) -> bool: return self._settingsWidget.updateXRotationAxisPixelPositionOnNewScan() def _setModeLockFrmSettings(self, lock: bool): # only lock the push button with block_signals(self): self._settingsWidget._mainWidget._calculationWidget._lockMethodPB.setLock( lock ) def getROIDims(self): if self.getMode() == axis_mode.AxisMode.manual: return self._settingsWidget.getROIDims() else: return None def getROIOrigin(self): if self.getMode() == axis_mode.AxisMode.manual: return self._settingsWidget.getROIOrigin() else: return None def getImgSubSampling(self): return self._settingsWidget.getImgSubSampling() def _computationRequested(self): self.sigComputationRequested.emit() def setLocked(self, locked): with block_signals(self): if self._axis_params.mode not in (axis_mode.AxisMode.manual,): self._axis_params.mode = axis_mode.AxisMode.manual self._settingsWidget.setLocked(locked) self.sigAxisEditionLocked.emit(locked) def isModeLock(self): return self._settingsWidget.isModeLock() def _validated(self): """callback when the validate button is activated""" self.sigApply.emit() def _setRadio2Flip(self, checked): self._plot.setRadio2Flip(checked) def _flipChanged(self, checked): if self.getMode() == axis_mode.AxisMode.manual: self._lastManualFlip = self._plot.isRadio2Flip() if checked == self._flipB: return else: self._flipB = checked self._updatePlot() def setReconsParams(self, axis: QAxisRP): """ :param axis: axis to edit :return: """ assert isinstance(axis, QAxisRP) self._axis_params = axis with block_signals(self): self.resetShift() self._settingsWidget.setAxisParams(axis) def setScan(self, scan): """ Update the interface concerning the given scan. Try to display the radios for angle 0 and 180. :param scan: scan for which we want the axis updated. """ self.clear() _scan = scan if type(scan) is str: try: _scan = ScanFactory.create_scan_object(scan) except ValueError: raise ValueError("Fail to discover a valid scan in %s" % scan) elif not isinstance(_scan, TomwerScanBase): raise ValueError( f"type of {scan} ({type(scan)}) is invalid, scan should be a file/dir path or an instance of ScanBase" ) assert isinstance(_scan, TomwerScanBase) if _scan.axis_params is None: _scan.axis_params = QAxisRP() if self._scan is not None: self._scan.axis_params.sigAxisUrlChanged.disconnect(self._updatePlot) update_x_rotation_axis_pixel_position = ( self._settingsWidget._mainWidget.updateXRotationAxisPixelPositionOnNewScan() ) if ( update_x_rotation_axis_pixel_position and scan.x_rotation_axis_pixel_position is not None ): self.setEstimatedCor(scan.x_rotation_axis_pixel_position) # update visualization self._scan = _scan self._scan.axis_params.sigAxisUrlChanged.connect(self._updatePlot) self._settingsWidget.setScan(scan=self._scan) self._updatePlot() self.getPlot().getPlot().resetZoom() def _updatePlot(self): if self._scan is None: return self._urlChanged() def _urlChanged(self): with block_signals(self): coreAngleMode = CorAngleMode.from_value(self.__recons_params.angle_mode) if self._scan is None: return axis_rp = self._scan.axis_params if coreAngleMode is CorAngleMode.manual_selection: manual_sel_widget = ( self._settingsWidget._mainWidget._inputWidget._angleModeWidget._manualFrameSelection ) urls = manual_sel_widget.getFramesUrl(as_txt=False) axis_rp.axis_url_1, axis_rp.axis_url_2 = urls axis_rp.flip_lr = manual_sel_widget.isFrame2LRFLip() else: axis_rp.flip_lr = True res = self._scan.get_opposite_projections(mode=coreAngleMode) axis_rp.axis_url_1 = res[0] axis_rp.axis_url_2 = res[1] if axis_rp.n_url() < 2: _logger.error("Fail to detect radio for axis calculation") elif axis_rp.axis_url_1.url: # if necessary normalize data axis_rp.axis_url_1.normalize_data(self._scan, log_=False) axis_rp.axis_url_2.normalize_data(self._scan, log_=False) paganin = self.__recons_params.paganin_preproc # check if normed if paganin: imgA = axis_rp.axis_url_1.normalized_data_paganin imgB = axis_rp.axis_url_2.normalized_data_paganin else: imgA = axis_rp.axis_url_1.normalized_data imgB = axis_rp.axis_url_2.normalized_data assert imgA is not None assert imgB is not None self.setImages(imgA=imgA, imgB=imgB, flipB=axis_rp.flip_lr) else: _logger.error( "fail to find radios for angle 0 and 180. Unable to update axis gui" ) def clear(self): if self._scan is not None: self._scan.axis_params.sigAxisUrlChanged.disconnect(self._updatePlot) self._scan = None def setImages(self, imgA: numpy.array, imgB: numpy.array, flipB: bool): """ :warning: does not reset the shift when change images :param imgA: first image to compare. Will be the one shifted :param imgB: second image to compare :param flipB: True if the image B has to be flipped """ assert imgA is not None assert imgB is not None _imgA = imgA _imgB = imgB if _imgA.shape != _imgB.shape: _logger.error( "The two provided images have incoherent shapes " f"({_imgA.shape} vs {_imgB.shape})" ) elif _imgA.ndim != 2: _logger.error("Image shape are not 2 dimensional") else: self._imgA = _imgA self._imgB = _imgB self._flipB = flipB self._settingsWidget._roiControl.setLimits( width=self._imgA.shape[1], height=self._imgA.shape[0] ) self._updateShift() def _updateSubSampling(self): self._updateShift() self.getPlot().getPlot().resetZoom() def _updateShift(self, xShift=None, yShift=None): if self._imgA is None or self._imgB is None: return xShift = xShift or self.getXShift() yShift = yShift or self.getYShift() # TODO: we might avoid flipping image at each new x_shift... _imgA, _imgB = self._getRawImages() # apply shift if xShift == 0.0 and yShift == 0.0: self._shiftedImgA = _imgA self._shiftedImgB = _imgB else: try: cval_imgA = _imgA.min() cval_imgB = _imgB.min() except ValueError: _logger.warning("enable to retrieve imgA.min() and / or" "imgB.min().") cval_imgA = 0 cval_imgB = 0 try: x_shift = self.getXShift() / self.getImgSubSampling() y_shift = self.getYShift() / self.getImgSubSampling() self._shiftedImgA = image.shift_img( data=_imgA, dx=-x_shift, dy=y_shift, cval=cval_imgA, ) self._shiftedImgB = image.shift_img( data=_imgB, dx=x_shift, dy=y_shift, cval=cval_imgB, ) crop = self.getPlot().cropComparedImages() if not crop: # handling of the crop: # 1. we will concatenate the shifted array with the unshifted to avoid crop # 2. in order to handled properly the shift and overlaps we need to add an empty array abs_x_shift = abs(int(x_shift)) buffer_array_img_A = numpy.full( shape=(self._shiftedImgA.shape[0], abs_x_shift), fill_value=cval_imgA, ) buffer_array_img_B = numpy.full( shape=(self._shiftedImgB.shape[0], abs_x_shift), fill_value=cval_imgB, ) if x_shift == 0: pass elif x_shift > 0: self._shiftedImgA = numpy.concatenate( ( _imgA[:, :abs_x_shift], self._shiftedImgA, buffer_array_img_A, ), axis=1, ) self._shiftedImgB = numpy.concatenate( ( buffer_array_img_B, self._shiftedImgB, _imgB[:, -abs_x_shift:], ), axis=1, ) else: self._shiftedImgA = numpy.concatenate( ( buffer_array_img_A, self._shiftedImgA, _imgA[:, :abs_x_shift], ), axis=1, ) self._shiftedImgB = numpy.concatenate( ( _imgB[:, :abs_x_shift], self._shiftedImgB, buffer_array_img_B, ), axis=1, ) except ValueError as e: _logger.error(e) self._shiftedImgA = _imgA self._shiftedImgB = _imgB with block_signals(self): try: self._plot.setData( image1=self._shiftedImgA, image2=self._shiftedImgB, ) except ValueError: _logger.warning( "Unable to set images. Maybe there is some " "incomplete dataset or an issue with " "normalization." ) roi_origin = self.getROIOrigin() if roi_origin is not None: x_origin, y_origin = roi_origin else: x_origin = y_origin = None self._lastXShift = xShift self._lastYShift = yShift self._lastXOrigin = x_origin self._lastYOrigin = y_origin def _getRawImages(self): def selectROI(data, width, height, x_origin, y_origin, subsampling): assert subsampling > 0 x_min = x_origin - width // 2 x_max = x_origin + width // 2 y_min = y_origin - height // 2 y_max = y_origin + height // 2 return data[y_min:y_max:subsampling, x_min:x_max:subsampling] # get images and apply ROI if any _roi_dims = self.getROIDims() _origin = self.getROIOrigin() subsampling = self.getImgSubSampling() _imgA = self._imgA _imgB = self._imgB # flip image B _imgB = numpy.fliplr(_imgB) if self._flipB else _imgB if _roi_dims is not None: assert type(_roi_dims) is tuple, f"invalide roi value {_roi_dims}" _imgA = selectROI( _imgA, width=_roi_dims[0], height=_roi_dims[1], x_origin=_origin[0], y_origin=_origin[1], subsampling=subsampling, ) _imgB = selectROI( _imgB, width=_roi_dims[0], height=_roi_dims[1], x_origin=_origin[0], y_origin=_origin[1], subsampling=subsampling, ) return _imgA, _imgB def _updateAuto(self): _imgA, _imgB = self._getRawImages() correlation = scipy.signal.correlate2d(in1=_imgA, in2=_imgB) y, x = numpy.unravel_index(numpy.argmax(correlation), correlation.shape) self._setShift(x=x, y=y) def resetShift(self): with block_signals(self._settingsWidget): self._settingsWidget.reset() if self._imgA is not None and self._imgB is not None: self.setImages(imgA=self._imgA, imgB=self._imgB, flipB=self._flipB) # expose API def getXShift(self): return self._settingsWidget.getXShift() def setXShift(self, x): self._settingsWidget.setXShift(x=x) def getYShift(self): return self._settingsWidget.getYShift() def setYShift(self, y): self._settingsWidget.setYShift(y=y) def _setShift(self, x, y): self._settingsWidget.setShift(x, y) def getShiftStep(self): return self._settingsWidget.getShiftStep() def setShiftStep(self, value): self._settingsWidget.setShiftStep(value=value) def getAxisParams(self): return self._settingsWidget.getAxisParams() def getMode(self): return self._settingsWidget.getMode() def setModeLock(self, mode): return self._settingsWidget.setModeLock(mode=mode) def isYAxisInverted(self) -> bool: return self._settingsWidget.isYAxisInverted() def setYAxisInverted(self, checked: bool): return self._settingsWidget.setYAxisInverted(checked=checked) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/axis/CalculationWidget.py0000644000175000017500000002067315153325210025117 0ustar00paynopaynofrom __future__ import annotations import logging from silx.gui import qt from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.process.reconstruction.axis import mode as axis_mode from tomwer.gui.utils.buttons import PadlockButton from tomwer.gui.utils.qt_utils import block_signals from tomwer.synctools.axis import QAxisRP from tomwer.gui.utils.scrollarea import QComboBoxIgnoreWheel from tomwer.gui.reconstruction.axis.EstimatedCORWidget import EstimatedCORWidget _logger = logging.getLogger(__name__) class CalculationWidget(qt.QWidget): """ Main widget to select the algorithm to use for COR calculation Used as a tab of the AxisSettingsTabWidget """ sigModeChanged = qt.Signal(str) """signal emitted when the algorithm for computing COR changed""" sigLockModeChanged = qt.Signal(bool) """signal emitted when the mode has been lock or unlock""" sigUpdateXRotAxisPixelPosOnNewScan = qt.Signal() sigYAxisInvertedChanged = qt.Signal(bool) def __init__(self, parent, axis_params): assert isinstance(axis_params, QAxisRP) qt.QWidget.__init__(self, parent) self._axis_params = None self.setLayout(qt.QVBoxLayout()) # algorithm self._modeWidget = qt.QWidget(parent=self) self._modeWidget.setLayout(qt.QHBoxLayout()) self.layout().addWidget(self._modeWidget) self.__rotAxisSelLabel = qt.QLabel("algorithm to compute cor") self._modeWidget.layout().addWidget(self.__rotAxisSelLabel) self._qcbPosition = QComboBoxIgnoreWheel(self) algorithm_groups = ( # radio group ( axis_mode.AxisMode.centered, axis_mode.AxisMode.global_, axis_mode.AxisMode.growing_window_radios, axis_mode.AxisMode.sliding_window_radios, axis_mode.AxisMode.octave_accurate_radios, ), # sino group ( axis_mode.AxisMode.growing_window_sinogram, axis_mode.AxisMode.sino_coarse_to_fine, axis_mode.AxisMode.sliding_window_sinogram, axis_mode.AxisMode.fourier_angles, ), # composite coarse to fine ( axis_mode.AxisMode.composite_coarse_to_fine, axis_mode.AxisMode.near, ), # read (axis_mode.AxisMode.read,), # manual (axis_mode.AxisMode.manual,), ) current_pos = 0 for i_grp, algorithm_group in enumerate(algorithm_groups): if i_grp != 0: self._qcbPosition.insertSeparator(current_pos) current_pos += 1 for cor_algorithm in algorithm_group: self._qcbPosition.addItem(cor_algorithm.value) idx = self._qcbPosition.findText(cor_algorithm.value) self._qcbPosition.setItemData( idx, axis_mode.AXIS_MODE_METADATAS[cor_algorithm].tooltip, qt.Qt.ToolTipRole, ) current_pos += 1 self._modeWidget.layout().addWidget(self._qcbPosition) # method lock button self._lockMethodPB = PadlockButton(parent=self._modeWidget) self._lockMethodPB.setToolTip( "Lock the method to compute the cor. \n" "This will automatically call the " "defined algorithm each time a scan is received." ) self._modeWidget.layout().addWidget(self._lockMethodPB) # estimated cor self._estimatedCorWidget = EstimatedCORWidget(self, axis_params=axis_params) self.layout().addWidget(self._estimatedCorWidget) # connect signal / slot self._qcbPosition.currentIndexChanged.connect(self._modeChanged) self._lockMethodPB.sigLockChanged.connect(self.lockMode) self._estimatedCorWidget.sigUpdateXRotAxisPixelPosOnNewScan.connect( self.sigUpdateXRotAxisPixelPosOnNewScan ) self._estimatedCorWidget.sigYAxisInvertedChanged.connect( self.sigYAxisInvertedChanged ) # set up interface self._estimatedCorWidget._updateVisibleSides(mode=self.getMode()) self.setAxisParams(axis_params) def getMethodLockPB(self) -> qt.QPushButton: return self._lockMethodPB def setEstimatedCorValue(self, value): self._estimatedCorWidget.setEstimatedCor(value=value) # note: force to update the side values. self._estimatedCorWidget._updateVisibleSides(mode=self.getMode()) def getEstimatedCor(self): return self._estimatedCorWidget.getEstimatedCor() def updateXRotationAxisPixelPositionOnNewScan(self) -> bool: return self._estimatedCorWidget.updateXRotationAxisPixelPositionOnNewScan() def setUpdateXRotationAxisPixelPositionOnNewScan(self, update: bool): self._estimatedCorWidget.setUpdateXRotationAxisPixelPositionOnNewScan( update=update ) def _modeChanged(self, *args, **kwargs): mode = self.getMode() with block_signals(self._qcbPosition): with block_signals(self._axis_params): self._estimatedCorWidget._updateVisibleSides(mode) self._axis_params.mode = mode.value self._axis_params.changed() self.sigModeChanged.emit(mode.value) def isModeLock(self): return self._lockMethodPB.isLocked() def setModeLock(self, mode=None): """set a specific mode and lock it. :param mode: mode to lock. If None then keep the current mode """ if mode is not None: mode = axis_mode.AxisMode.from_value(mode) if mode is None and axis_mode.AXIS_MODE_METADATAS[self.getMode()].is_lockable(): raise ValueError( "Unable to lock the current mode is not an automatic algorithm" ) elif ( mode != self.getMode() and axis_mode.AXIS_MODE_METADATAS[mode].is_lockable() ): raise ValueError("Unable to lock %s this is not a lockable mode") if mode is not None: self.setMode(mode) if not self._lockMethodPB.isLocked(): with block_signals(self._lockMethodPB): self._lockMethodPB.setLock(True) self.lockMode(True) def lockMode(self, lock): with block_signals(self._lockMethodPB): self._lockMethodPB.setLock(lock) self._qcbPosition.setEnabled(not lock) self.sigLockModeChanged.emit(lock) def getMode(self): """Return algorithm to use for axis calculation""" return axis_mode.AxisMode.from_value(self._qcbPosition.currentText()) def setMode(self, mode: axis_mode.AxisMode): with block_signals(self._qcbPosition): index = self._qcbPosition.findText(mode.value) if index >= 0: self._qcbPosition.setCurrentIndex(index) else: raise ValueError("Unable to find mode", mode) self._lockMethodPB.setVisible(mode not in (axis_mode.AxisMode.manual,)) mode_metadata = axis_mode.AXIS_MODE_METADATAS[mode] estimated_cor_widget_visible = ( mode_metadata.allows_estimated_cor_as_numerical_value or len(mode_metadata.valid_sides) > 0 ) self._estimatedCorWidget.setVisible(estimated_cor_widget_visible) self._estimatedCorWidget._updateVisibleSides(mode=mode) def setAxisParams(self, axis): with block_signals(self): if self._axis_params is not None: self._axis_params.sigChanged.disconnect(self._axis_params_changed) self._axis_params = axis if self._axis_params.mode in (axis_mode.AxisMode.manual,): # those mode cannot be handled by the auto calculation dialog self._axis_params.mode = axis_mode.AxisMode.growing_window_radios self._axis_params.sigChanged.connect(self._axis_params_changed) self._axis_params_changed() def _axis_params_changed(self, *args, **kwargs): if self._axis_params.mode != self.getMode(): # setMode will force to update visible side. So avoid to reset it if not necessary self.setMode(self._axis_params.mode) def setScan(self, scan: TomwerScanBase | None): self._estimatedCorWidget.setPixelSize(pixel_size_m=scan.sample_x_pixel_size) self._estimatedCorWidget.setImageWidth(image_width=scan.dim_1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/axis/CompareImages.py0000644000175000017500000002624015153325210024225 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging import weakref import numpy from silx.gui import icons as silx_icons from silx.gui import qt from silx.gui.plot.CompareImages import ( CompareImages as _CompareImages, VisualizationMode, ) from silx.gui.plot.tools.compare.toolbar import VisualizationModeToolButton from silx.gui.plot import tools _logger = logging.getLogger(__name__) class CompareImages(_CompareImages): sigCropImagesChanged = qt.Signal() """Emit when cropping of the compared images has changed""" def __init__(self, parent=None, backend=None): super().__init__(parent, backend) # create crop images action icon = silx_icons.getQIcon("crop") action = qt.QAction(icon, "crop compared images", self) action.setCheckable(True) action.setChecked(True) action.triggered.connect(self.__cropComparedImagesChanged) self.__cropComparedImages = action self._compareToolBar.addAction(action) # define visible compare mode self._compareToolBar._visualizationToolButton.setVisibleModes( [ VisualizationMode.ONLY_A, VisualizationMode.ONLY_B, VisualizationMode.COMPOSITE_RED_BLUE_GRAY_NEG, VisualizationMode.COMPOSITE_A_MINUS_B, ] ) def __cropComparedImagesChanged(self): cropCompositeImage = self.__cropComparedImages.isChecked() self.setCropComparedImages(cropCompositeImage) def cropComparedImages(self) -> bool: return self.__cropComparedImages.isChecked() def setCropComparedImages(self, crop): self.__cropComparedImages.setChecked(crop) self.sigCropImagesChanged.emit() def _createToolBars(self, plot): """Create tool bars displayed by the widget""" toolBar = tools.InteractiveModeToolBar(parent=self, plot=plot) self._interactiveModeToolBar = toolBar toolBar = tools.ImageToolBar(parent=self, plot=plot) self._imageToolBar = toolBar toolBar = CompareImagesToolBar(self) toolBar.setCompareWidget(self) self._compareToolBar = toolBar class CompareImagesStatusBar(qt.QStatusBar): """StatusBar containing specific information contained in a :class:`CompareImages` widget Use :meth:`setCompareWidget` to connect this toolbar to a specific :class:`CompareImages` widget. :param parent: Parent of this widget. """ def __init__(self, parent=None): qt.QStatusBar.__init__(self, parent) self.setSizeGripEnabled(False) self.layout().setSpacing(0) self.__compareWidget = None self._label1 = qt.QLabel(self) self._label1.setFrameShape(qt.QFrame.WinPanel) self._label1.setFrameShadow(qt.QFrame.Sunken) self._label2 = qt.QLabel(self) self._label2.setFrameShape(qt.QFrame.WinPanel) self._label2.setFrameShadow(qt.QFrame.Sunken) self._transform = qt.QLabel(self) self._transform.setFrameShape(qt.QFrame.WinPanel) self._transform.setFrameShadow(qt.QFrame.Sunken) self.addWidget(self._label1) self.addWidget(self._label2) self.addWidget(self._transform) self._pos = None self._updateStatusBar() def setCompareWidget(self, widget): """ Connect this tool bar to a specific :class:`CompareImages` widget. :param widget: The widget to connect with. """ compareWidget = self.getCompareWidget() if compareWidget is not None: compareWidget.getPlot().sigPlotSignal.disconnect(self.__plotSignalReceived) compareWidget.sigConfigurationChanged.disconnect(self.__dataChanged) compareWidget = widget if compareWidget is None: self.__compareWidget = None else: self.__compareWidget = weakref.ref(compareWidget) if compareWidget is not None: compareWidget.getPlot().sigPlotSignal.connect(self.__plotSignalReceived) compareWidget.sigConfigurationChanged.connect(self.__dataChanged) def getCompareWidget(self) -> CompareImages: """Returns the connected widget.""" if self.__compareWidget is None: return None else: return self.__compareWidget() def __plotSignalReceived(self, event): """Called when old style signals at emmited from the plot.""" if event["event"] == "mouseMoved": x, y = event["x"], event["y"] self.__mouseMoved(x, y) def __mouseMoved(self, x, y): """Called when mouse move over the plot.""" self._pos = x, y self._updateStatusBar() def __dataChanged(self): """Called when internal data from the connected widget changes.""" self._updateStatusBar() def _formatData(self, data: int | float | None) -> str: """Format pixel of an image. It supports intensity, RGB, and RGBA. :param data: Value of a pixel """ if data is None: return "-" if isinstance(data, (int, numpy.integer)): return "%d" % data if isinstance(data, (float, numpy.floating)): return "%f" % data if isinstance(data, numpy.ndarray): # RGBA value if data.shape == (3,): return "R:%d G:%d B:%d" % (data[0], data[1], data[2]) elif data.shape == (4,): return "R:%d G:%d B:%d A:%d" % (data[0], data[1], data[2], data[3]) _logger.debug("Unsupported data format %s. Cast it to string.", type(data)) return str(data) def _updateStatusBar(self): """Update the content of the status bar""" widget = self.getCompareWidget() if widget is None: self._label1.setText("Frame 1: -") self._label2.setText("Frame 2: -") self._transform.setVisible(False) else: transform = widget.getTransformation() self._transform.setVisible(transform is not None) if transform is not None: has_notable_translation = not numpy.isclose( transform.tx, 0.0, atol=0.01 ) or not numpy.isclose(transform.ty, 0.0, atol=0.01) has_notable_scale = not numpy.isclose( transform.sx, 1.0, atol=0.01 ) or not numpy.isclose(transform.sy, 1.0, atol=0.01) has_notable_rotation = not numpy.isclose(transform.rot, 0.0, atol=0.01) strings = [] if has_notable_translation: strings.append("Translation") if has_notable_scale: strings.append("Scale") if has_notable_rotation: strings.append("Rotation") if strings == []: has_translation = not numpy.isclose( transform.tx, 0.0 ) or not numpy.isclose(transform.ty, 0.0) has_scale = not numpy.isclose( transform.sx, 1.0 ) or not numpy.isclose(transform.sy, 1.0) has_rotation = not numpy.isclose(transform.rot, 0.0) if has_translation or has_scale or has_rotation: text = "No big changes" else: text = "No changes" else: text = "+".join(strings) self._transform.setText("Align: " + text) strings = [] if not numpy.isclose(transform.ty, 0.0): strings.append("Translation x: %0.3fpx" % transform.tx) if not numpy.isclose(transform.ty, 0.0): strings.append("Translation y: %0.3fpx" % transform.ty) if not numpy.isclose(transform.sx, 1.0): strings.append("Scale x: %0.3f" % transform.sx) if not numpy.isclose(transform.sy, 1.0): strings.append("Scale y: %0.3f" % transform.sy) if not numpy.isclose(transform.rot, 0.0): _rot = transform.rot * 180 / numpy.pi strings.append(f"Rotation: {_rot:0.3f}deg") if strings == []: text = "No transformation" else: text = "\n".join(strings) self._transform.setToolTip(text) if self._pos is None: self._label1.setText("Frame 1: -") self._label2.setText("Frame 2: -") else: data1, data2 = widget.getRawPixelData(self._pos[0], self._pos[1]) if isinstance(data1, str): self._label1.setToolTip(data1) text1 = "-" else: self._label1.setToolTip("") text1 = self._formatData(data1) if isinstance(data2, str): self._label2.setToolTip(data2) text2 = "-" else: self._label2.setToolTip("") text2 = self._formatData(data2) self._label1.setText("Frame 1: %s" % text1) self._label2.setText("Frame 2: %s" % text2) class CompareImagesToolBar(qt.QToolBar): def __init__(self, parent=None): qt.QToolBar.__init__(self, parent) self.__compareWidget = None self._visualizationToolButton = VisualizationModeToolButton(self) self._visualizationToolButton.setPopupMode(qt.QToolButton.InstantPopup) self._visualizationToolButton.sigSelected.connect(self.__visualizationChanged) self.addWidget(self._visualizationToolButton) def __visualizationChanged(self, mode: VisualizationMode): widget = self.getCompareWidget() if widget is not None: widget.setVisualizationMode(mode) def setCompareWidget(self, widget: None | CompareImages): """ Connect this tool bar to a specific :class:`CompareImages` widget. :param widget: The widget to connect the toolbar with. """ compareWidget = self.getCompareWidget() if compareWidget is not None: compareWidget.sigConfigurationChanged.disconnect( self.__updateSelectedActions ) compareWidget = widget self.setEnabled(compareWidget is not None) if compareWidget is None: self.__compareWidget = None else: self.__compareWidget = weakref.ref(compareWidget) if compareWidget is not None: widget.sigConfigurationChanged.connect(self.__updateSelectedActions) self.__updateSelectedActions() def getCompareWidget(self) -> CompareImages: """Returns the connected widget.""" if self.__compareWidget is None: return None else: return self.__compareWidget() def __updateSelectedActions(self): """ Update the state of this tool bar according to the state of the connected :class:`CompareImages` widget. """ widget = self.getCompareWidget() if widget is None: return self._visualizationToolButton.setSelected(widget.getVisualizationMode()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/axis/ControlWidget.py0000644000175000017500000002472515153325210024303 0ustar00paynopaynofrom __future__ import annotations import logging import numpy from silx.gui import qt from tomwer.core.process.reconstruction.utils.cor import ( absolute_pos_to_relative, relative_pos_to_absolute, ) from tomwer.gui.utils.buttons import PadlockButton from tomwer.gui.settings import EDITING_BACKGROUND_COLOR from tomwer.synctools.axis import QAxisRP _logger = logging.getLogger(__file__) class ControlWidget(qt.QWidget): """ Widget to lock, compute or validate the cor position and display it value as absolute or relative This is the widget displayed at the bottom of the AxisOW """ sigComputationRequest = qt.Signal() """Signal emitted when user request a computation from the settings""" sigValidateRequest = qt.Signal() """Signal emitted when user validate the current settings""" sigLockCORValueChanged = qt.Signal(bool) """Signal emitted when the user lock the cor value. Param: True if lock""" def __init__(self, parent): qt.QWidget.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) # display 'center' information self._positionInfo = _PositionInfoWidget(parent=self) self.layout().addWidget(self._positionInfo) self._buttons = qt.QWidget(parent=self) self._buttons.setLayout(qt.QHBoxLayout()) self.layout().addWidget(self._buttons) self._lockBut = PadlockButton(parent=self) self._lockBut.setAutoDefault(False) self._lockBut.setDefault(False) self._buttons.layout().addWidget(self._lockBut) self._lockLabel = qt.QLabel("lock cor value", parent=self) self._buttons.layout().addWidget(self._lockLabel) spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) self._buttons.layout().addWidget(spacer) self._computeBut = qt.QPushButton("compute", parent=self) self._buttons.layout().addWidget(self._computeBut) style = qt.QApplication.style() applyIcon = style.standardIcon(qt.QStyle.SP_DialogApplyButton) self._applyBut = qt.QPushButton(applyIcon, "validate", parent=self) self._buttons.layout().addWidget(self._applyBut) self.layout().addWidget(self._buttons) # set up self._positionInfo.setPosition(None, None) # make connection self._computeBut.pressed.connect(self._needComputation) self._applyBut.pressed.connect(self._validate) self._lockBut.sigLockChanged.connect(self._lockValueChanged) def hideLockButton(self) -> None: self._lockLabel.hide() self._lockBut.hide() def hideApplyButton(self) -> None: self._applyBut.hide() def _lockValueChanged(self): self.sigLockCORValueChanged.emit(self._lockBut.isLocked()) self._computeBut.setEnabled(not self._lockBut.isLocked()) def _needComputation(self, *arg, **kwargs): """callback when the radio line changed""" self.sigComputationRequest.emit() def _validate(self): self.sigValidateRequest.emit() def setPosition(self, relative_cor, abs_cor): self._positionInfo.setPosition(relative_cor=relative_cor, abs_cor=abs_cor) def _updateAbsolutePosition(self, width): self._positionInfo._updateAbsolutePosition(width=width) def _updateRelativePosition(self, width): self._positionInfo._updateRelativePosition(width=width) def isValueLock(self): return self._lockBut.isLocked() def setValueLock(self, lock): self._lockBut.setLock(lock) class _PositionInfoValidator(qt.QDoubleValidator): def validate(self, a0: str, a1: int): if "..." in a0 or a0 == "?": return (qt.QDoubleValidator.Acceptable, a0, a1) else: return super().validate(a0, a1) class _PositionInfoWidget(qt.QWidget): """Widget used to display information relative to the current position""" sigRelativeValueSet = qt.Signal(float) """Emit when the user define manually the relative value""" sigAbsolueValueSet = qt.Signal(float) """Emit when the user define manually the absolute value""" def __init__(self, parent, axis=None): self._axis_params = None self._defaultBackgroundColor = None qt.QWidget.__init__(self, parent) self.setLayout(qt.QGridLayout()) centerLabel = qt.QLabel("center", parent=self) centerLabel.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum) font = centerLabel.font() font.setBold(True) centerLabel.setFont(font) self.layout().addWidget(centerLabel, 0, 0, 1, 1) self.layout().addWidget(qt.QLabel(" (relative):"), 0, 1, 1, 1) self._relativePositionQLE = qt.QLineEdit("", parent=self) self._positionValidator = _PositionInfoValidator(self) self._relativePositionQLE.setValidator(self._positionValidator) self._relativePositionQLE.setSizePolicy( qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum ) self._relativePositionQLE.setStyleSheet("color: red") self.layout().addWidget(self._relativePositionQLE, 0, 2, 1, 1) centerLabel = qt.QLabel("center", parent=self) centerLabel.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum) font = centerLabel.font() font.setBold(False) centerLabel.setFont(font) self.layout().addWidget(centerLabel, 1, 0, 1, 1) self.layout().addWidget(qt.QLabel(" (absolute):"), 1, 1, 1, 1) self._absolutePositionQLE = qt.QLineEdit("", parent=self) self._absolutePositionQLE.setValidator(self._positionValidator) self._absolutePositionQLE.setSizePolicy( qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum ) self._absolutePositionQLE.setStyleSheet("color: #ff8c00") self.layout().addWidget(self._absolutePositionQLE, 1, 2, 1, 1) if axis: self.setAxisParams(axis) # connect signal / slot self._relativePositionQLE.textEdited.connect( self._userStartEditingRelativePosition ) self._relativePositionQLE.editingFinished.connect( self._userUpdatedRelativePosition ) self._absolutePositionQLE.textEdited.connect( self._userStartEditingAbsolutePosition ) self._absolutePositionQLE.editingFinished.connect( self._userUpdatedAbsolutePosition ) def _getDefaultBackgroundColor(self): if self._defaultBackgroundColor is None: self._defaultBackgroundColor = self.palette().color( self._absolutePositionQLE.backgroundRole() ) return self._defaultBackgroundColor def _userStartEditingRelativePosition(self, *args, **kwargs): palette = self.palette() palette.setColor( self._relativePositionQLE.backgroundRole(), EDITING_BACKGROUND_COLOR ) self._relativePositionQLE.setPalette(palette) def _userStartEditingAbsolutePosition(self, *args, **kwargs): palette = self.palette() palette.setColor( self._absolutePositionQLE.backgroundRole(), EDITING_BACKGROUND_COLOR ) self._absolutePositionQLE.setPalette(palette) def _userUpdatedRelativePosition(self, *args, **kwargs): palette = self.palette() palette.setColor( self._relativePositionQLE.backgroundRole(), self._getDefaultBackgroundColor(), ) self._relativePositionQLE.setPalette(palette) if self._relativePositionQLE.text().startswith((".", "?")): return else: value = float(self._relativePositionQLE.text()) # make sure we only emit the signal if the value changed (and when the Qline has been edited). if isinstance(self._axis_params.relative_cor_value, (type(None), str)) or ( self._axis_params is not None and not numpy.isclose( value, self._axis_params.relative_cor_value, atol=1e-3 ) ): self.sigRelativeValueSet.emit(value) def _userUpdatedAbsolutePosition(self, *args, **kwargs): palette = self.palette() palette.setColor( self._absolutePositionQLE.backgroundRole(), self._getDefaultBackgroundColor(), ) self._absolutePositionQLE.setPalette(palette) if self._absolutePositionQLE.text().startswith((".", "?")): return else: value = float(self._absolutePositionQLE.text()) # make sure we only emit the signal if the value changed (and when the Qline has been edited). if self._axis_params.absolute_cor_value is None or ( self._axis_params is not None and not numpy.isclose( value, self._axis_params.absolute_cor_value, atol=1e-3 ) ): self.sigAbsolueValueSet.emit(value) def setAxisParams(self, axis): assert isinstance(axis, QAxisRP) if axis == self._axis_params: return self._axis_params = axis def getPosition(self): return float(self._relativePositionQLE.text()) def setPosition(self, relative_cor: float | None, abs_cor: float | None): if relative_cor is None: self._relativePositionQLE.setText("?") elif isinstance(relative_cor, str): self._relativePositionQLE.setText(relative_cor) else: self._relativePositionQLE.setText(f"{relative_cor:.3f}") if abs_cor is None: self._absolutePositionQLE.setText("?") else: self._absolutePositionQLE.setText(f"{abs_cor:.3f}") def _updateAbsolutePosition(self, width): if width is not None: try: rel_value = float(self._relativePositionQLE.text()) except Exception: return else: abs_value = relative_pos_to_absolute( relative_pos=float(rel_value), det_width=width ) self._absolutePositionQLE.setText(str(abs_value)) def _updateRelativePosition(self, width): if width is not None: try: abs_value = float(self._absolutePositionQLE.text()) except Exception: return else: rel_value = absolute_pos_to_relative( absolute_pos=float(abs_value), det_width=width ) self._relativePositionQLE.setText(str(rel_value)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/axis/EstimatedCORWidget.py0000644000175000017500000004206015153325210025136 0ustar00paynopaynofrom __future__ import annotations import pint from packaging.version import Version from silx.gui import qt import processview from processview.gui.DropDownWidget import DropDownWidget from tomwer.synctools.axis import QAxisRP from tomwer.gui.utils.qt_utils import block_signals from tomwer.gui.utils.buttons import PadlockButton from tomwer.gui.reconstruction.axis.EstimatedCorComboBox import EstimatedCorComboBox from tomwer.core.process.reconstruction.axis.side import Side from tomwer.core.process.reconstruction.axis import mode as axis_mode from tomwer.gui.fonts import FONT_SMALL from tomwer.gui.utils.scrollarea import QDoubleSpinBoxIgnoreWheel _ureg = pint.get_application_registry() class EstimatedCORWidget(qt.QGroupBox): """ Widget to define the estimated center of rotation. (based on the motor offset and the 'x_rotation_axis_pixel_position') """ sigValueChanged = qt.Signal() """Emit when one of the value changed""" sigUpdateXRotAxisPixelPosOnNewScan = qt.Signal() """Emit when user want to stop / activate x rotation axis pixel position when a new scan arrives""" sigYAxisInvertedChanged = qt.Signal(bool) def __init__(self, parent, axis_params: QAxisRP): self._axis_params = axis_params self._imageWidth = None super().__init__(parent) self.setLayout(qt.QGridLayout()) # estimated cor self._estimatedCORLabel = qt.QLabel("Estimated CoR (relative)", self) self.layout().addWidget(self._estimatedCORLabel, 0, 0, 1, 1) self._estimatedCORQCB = EstimatedCorComboBox(self) self.layout().addWidget(self._estimatedCORQCB, 0, 1, 1, 1) # offset calibration if Version(processview.__version__) < Version("2.0"): self._offsetWidgetDropdown = DropDownWidget( parent=self, direction=qt.Qt.LayoutDirection.RightToLeft ) else: self._offsetWidgetDropdown = DropDownWidget( # pylint: disable=E1123 title="`x_rotation_axis_pixel_position` && Offset", parent=self, ) self._offsetWidget = _OffsetCalibration(parent=self, axis_params=axis_params) self.layout().addWidget(self._offsetWidgetDropdown, 1, 0, 2, 2) self._offsetWidgetDropdown.setWidget(self._offsetWidget) # set up self._offsetWidgetDropdown.setChecked(False) # connect signal / slot self._estimatedCORQCB.sigEstimatedCorChanged.connect(self._corChanged) self._offsetWidget.sigOffsetChanged.connect( self._updateEstimatedCorFromMotorOffsetWidget ) self._offsetWidget.sigXRotationAxisPixelPositionChanged.connect( self._updateEstimatedCorFromMotorOffsetWidget ) self._offsetWidget.sigUpdateXRotAxisPixelPosOnNewScan.connect( self.sigUpdateXRotAxisPixelPosOnNewScan ) self._offsetWidget.sigYAxisInvertedChanged.connect(self.sigYAxisInvertedChanged) def getEstimatedCor(self): return self._estimatedCORQCB.getCurrentCorValue() def setEstimatedCor( self, value: float | Side | str, provided_with_offset: bool = False ): if isinstance(value, float): if self._offsetWidget.isYAxisInverted(): value = -1.0 * value if provided_with_offset: value_with_offset = value value_without_offset = value - self._offsetWidget.getOffset() else: value_with_offset = value + self._offsetWidget.getOffset() value_without_offset = value with block_signals(self._offsetWidget): self._offsetWidget.setXRotationAxisPixelPosition( value_without_offset, apply_flip=False ) else: # case this is a side value_with_offset = value self._estimatedCORQCB.setCurrentCorValue(value_with_offset) with block_signals(self._axis_params): self._axis_params.estimated_cor = value_with_offset def _corChanged(self, value): assert value is None or isinstance(value, (float, Side, None)) with block_signals(self._axis_params): self._axis_params.estimated_cor = value self.sigValueChanged.emit() def _updateVisibleSides(self, mode: axis_mode.AxisMode): """ Update the visibility and selection of sides (Left, Center, Right) for the Estimated Center of Rotation (CoR) ComboBox based on the provided axis mode and a calculated CoR guess. This method adjusts the available sides and determines the new side (Left, Center, or Right) based on the position of a CoR guess relative to the width of the image. The image is divided into thirds: - Left: From -infinity to the first third. - Center: From the first third to the second third. - Right: From the second third to infinity. If the CoR guess is not valid or falls outside the calculated bounds, a default valid side is selected. Behavior: --------- - By default if the method allows it, the side will be the estimated CoR. - If the method does not allow it, it will update the visible sides in the Estimated CoR ComboBox based on the valid sides defined in the axis mode metadata and dynamically determines the new side (Left, Center, Right) based on the CoR guess position within the image width. """ mode = axis_mode.AxisMode.from_value(mode) valid_sides = axis_mode.AXIS_MODE_METADATAS[mode].valid_sides self._estimatedCORQCB.setSidesVisible(valid_sides) first_guess_available = axis_mode.AXIS_MODE_METADATAS[ mode ].allows_estimated_cor_as_numerical_value self._estimatedCORQCB.setFirstGuessAvailable(first_guess_available) if first_guess_available: # if the first guess is valid, when the sides visibility is modify we want to activate it. self._estimatedCORQCB.selectFirstGuess() elif valid_sides: # Proceed only if there are valid sides current_side = self._estimatedCORQCB.getCurrentCorValue() if not isinstance(current_side, Side) or current_side not in valid_sides: with block_signals(self._estimatedCORQCB): cor_guess = self._estimatedCORQCB.getCurrentCorValue() if cor_guess is not None and self._imageWidth is not None: left_boundary = -float("inf") right_boundary = float("inf") middle_left_boundary = ( self._imageWidth / 3 - self._imageWidth / 2 ) middle_right_boundary = ( 2 * self._imageWidth / 3 - self._imageWidth / 2 ) if ( Side.LEFT in valid_sides and left_boundary <= cor_guess < middle_left_boundary ): new_side = Side.LEFT elif ( Side.CENTER in valid_sides and middle_left_boundary <= cor_guess < middle_right_boundary ): new_side = Side.CENTER elif ( Side.RIGHT in valid_sides and middle_right_boundary <= cor_guess <= right_boundary ): new_side = Side.RIGHT else: # Fallback to the first available valid side new_side = valid_sides[0] else: # If no guess or boundaries are available, fallback to the first valid side new_side = valid_sides[0] self._estimatedCORQCB.setCurrentCorValue(new_side) self._axis_params.estimated_cor = new_side def _updateEstimatedCorFromMotorOffsetWidget(self): self._estimatedCORQCB.setCurrentCorValue(self._offsetWidget.getEstimatedCor()) self.sigValueChanged.emit() def setImageWidth(self, image_width: float | None): self._imageWidth = image_width # expose API def updateXRotationAxisPixelPositionOnNewScan(self) -> bool: return self._offsetWidget.updateXRotationAxisPixelPositionOnNewScan() def setUpdateXRotationAxisPixelPositionOnNewScan(self, update: bool): self._offsetWidget.setUpdateXRotationAxisPixelPositionOnNewScan(update=update) def setPixelSize(self, pixel_size_m: float | None) -> None: self._offsetWidget.setPixelSize(pixel_size_m=pixel_size_m) def isYAxisInverted(self) -> bool: return self._offsetWidget.isYAxisInverted() def setYAxisInverted(self, checked: bool): return self._offsetWidget.setYAxisInverted(checked=checked) class _OffsetCalibration(qt.QGroupBox): sigOffsetChanged = qt.Signal() sigXRotationAxisPixelPositionChanged = qt.Signal() sigUpdateXRotAxisPixelPosOnNewScan = qt.Signal() sigYAxisInvertedChanged = qt.Signal(bool) def __init__(self, parent, axis_params: QAxisRP): super().__init__(parent) self._axis_params = axis_params self.setLayout(qt.QVBoxLayout()) # x_rotation_axis_pixel_position self._xRotationAxisPixelPositionGroup = qt.QGroupBox("NXtomo metadata ") self._xRotationAxisPixelPositionGroup.setLayout(qt.QGridLayout()) self.layout().addWidget(self._xRotationAxisPixelPositionGroup) self._xRotationAxisPixelPositionLabel = qt.QLabel( "x_rotation_axis_pixel_position" ) self._xRotationAxisPixelPositionGroup.layout().addWidget( self._xRotationAxisPixelPositionLabel, 0, 0, 2, 1 ) self._xRotationAxisPixelPositionDSB = QDoubleSpinBoxIgnoreWheel(self) self._xRotationAxisPixelPositionDSB.setDecimals(2) self._xRotationAxisPixelPositionDSB.setRange(-float("inf"), float("inf")) self._xRotationAxisPixelPositionDSB.setSuffix(" px") self._xRotationAxisPixelPositionDSB.setEnabled(False) self._xRotationAxisPixelPositionGroup.layout().addWidget( self._xRotationAxisPixelPositionDSB, 0, 1, 2, 1 ) self._xRotationAxisPixelPositionKeepUpdatedCB = qt.QCheckBox( "Update with\n new scan" ) self._xRotationAxisPixelPositionKeepUpdatedCB.setFont(FONT_SMALL) self._xRotationAxisPixelPositionKeepUpdatedCB.setToolTip( "Updates the value when a new scan arrives.\n" "Once updated this will change the numerical value of the estimated cor (from estimated relative cor)" ) self._xRotationAxisPixelPositionGroup.layout().addWidget( self._xRotationAxisPixelPositionKeepUpdatedCB, 0, 2, 1, 1 ) self._yAxisInvertedCB = qt.QCheckBox("Y axis inverted") self._yAxisInvertedCB.setFont(FONT_SMALL) self._yAxisInvertedCB.setToolTip( "Sometime the y axis can be inverted (like on ID11).\nIn this case the estimation of the CoR has a flip that must be handled downstream" ) self._xRotationAxisPixelPositionGroup.layout().addWidget( self._yAxisInvertedCB, 1, 2, 1, 1 ) # offset group self._offsetGroup = qt.QGroupBox("Custom Offset") self._offsetGroup.setLayout(qt.QFormLayout()) self.layout().addWidget(self._offsetGroup) # offset self._offsetSB = QDoubleSpinBoxIgnoreWheel(self) self._offsetSB.setSuffix(" px") self._offsetSB.setDecimals(2) self._offsetSB.setRange(-float("inf"), float("inf")) self._offsetSB.setEnabled(False) self._offsetGroup.layout().addRow("Offset", self._offsetSB) # motor offset self._motorOffsetSB = QDoubleSpinBoxIgnoreWheel(self) self._motorOffsetSB.setSuffix(" mm") self._motorOffsetSB.setDecimals(4) self._motorOffsetSB.setRange(-float("inf"), float("inf")) self._offsetGroup.layout().addRow("Y Motor Offset", self._motorOffsetSB) # pixel size self._pixelSizeSB = QDoubleSpinBoxIgnoreWheel(self) self._pixelSizeSB.setSuffix(" µm") self._pixelSizeSB.setDecimals(3) self._pixelSizeSB.setRange(0, float("inf")) # Add a horizontal layout for the pixel size and the padlock pixelSizeLayout = qt.QHBoxLayout() # Add the spin box to the layout pixelSizeLayout.addWidget(self._pixelSizeSB) # Add a padlock button self._pixelSizePadlock = PadlockButton(self) self._pixelSizePadlock.setChecked(True) # Default to locked self._pixelSizePadlock.setFixedSize(24, 24) self._pixelSizePadlock.setToolTip("Lock/Unlock pixel size") pixelSizeLayout.addWidget(self._pixelSizePadlock) # Add the layout to the offset group self._offsetGroup.layout().addRow("Pixel Size", pixelSizeLayout) # Initialize the spin box as disabled (locked by default) self._pixelSizeSB.setEnabled(False) # Connect signal to handle locking behavior self._pixelSizePadlock.toggled.connect(self._togglePixelSizeLock) # set up self._xRotationAxisPixelPositionKeepUpdatedCB.setChecked(True) self._yAxisInvertedCB.setChecked(False) # connect signal / slot self._offsetSB.editingFinished.connect(self._offsetEdited) self._xRotationAxisPixelPositionKeepUpdatedCB.toggled.connect( self.sigUpdateXRotAxisPixelPosOnNewScan ) self._motorOffsetSB.valueChanged.connect(self._motorOffsetChanged) self._pixelSizeSB.valueChanged.connect(self._pixelSizeChanged) self._yAxisInvertedCB.toggled.connect(self._yAxisInverted) def getXRotationAxisPixelPosition(self) -> float: return self._xRotationAxisPixelPositionDSB.value() def updateXRotationAxisPixelPositionOnNewScan(self) -> bool: return self._xRotationAxisPixelPositionKeepUpdatedCB.isChecked() def setUpdateXRotationAxisPixelPositionOnNewScan(self, update): self._xRotationAxisPixelPositionKeepUpdatedCB.setChecked(update) def setXRotationAxisPixelPosition( self, value: float, apply_flip: bool = True ) -> float: """Set the 'x_rotation_axis_pixel_position' and flip it if necessary""" if apply_flip and self.isYAxisInverted(): value = -1.0 * value self._xRotationAxisPixelPositionDSB.setValue(value) return value def getOffset(self) -> float: return self._offsetSB.value() def setOffset(self, value: float) -> None: self._offsetSB.setValue(value) self._offsetEdited() def _offsetEdited(self): with block_signals(self): self._axis_params.x_rotation_axis_pos_px_offset = self.getOffset() self.sigOffsetChanged.emit() def _motorOffsetChanged(self): """Recalculate the offset when the motor offset changes.""" if self._pixelSizeSB.value() and self._motorOffsetSB.value(): pixel_size = self._pixelSizeSB.value() * _ureg.micrometer motor_offset = self._motorOffsetSB.value() * _ureg.millimeter with block_signals(self): self.setOffset((motor_offset / pixel_size).to_base_units().magnitude) self.sigOffsetChanged.emit() def _pixelSizeChanged(self): """Recalculate the offset when the pixel size changes.""" if self._pixelSizeSB.value() and self._motorOffsetSB.value(): pixel_size = self._pixelSizeSB.value() * _ureg.micrometer motor_offset = self._motorOffsetSB.value() * _ureg.millimeter with block_signals(self): self.setOffset((motor_offset / pixel_size).to_base_units().magnitude) self.sigOffsetChanged.emit() def _xRotationAxisPixelPositionEdited(self): with block_signals(self._axis_params): self._axis_params.x_rotation_axis_pixel_position = ( self.getXRotationAxisPixelPosition() ) self.sigXRotationAxisPixelPositionChanged.emit() def _yAxisInverted(self): self.setXRotationAxisPixelPosition( value=-1.0 * self.getXRotationAxisPixelPosition(), apply_flip=False, ) self._xRotationAxisPixelPositionEdited() def isYAxisInverted(self) -> bool: return self._yAxisInvertedCB.isChecked() def setYAxisInverted(self, checked: bool): self._yAxisInvertedCB.setChecked(checked) def getEstimatedCor(self) -> float: return self.getXRotationAxisPixelPosition() + self.getOffset() def setPixelSize(self, pixel_size_m: float | None): if pixel_size_m is None: self._pixelSizeSB.clear() else: self._pixelSizeSB.setValue( (pixel_size_m * _ureg.meter).to(_ureg.micrometer).magnitude ) def _togglePixelSizeLock(self, locked: bool): """Lock or unlock the pixel size spin box.""" self._pixelSizeSB.setEnabled(not locked) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/axis/EstimatedCorComboBox.py0000644000175000017500000001051515153325210025523 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from tomwer.core.process.reconstruction.axis.side import Side from tomwer.gui.utils.scrollarea import QComboBoxIgnoreWheel from tomwer.gui.utils.qt_utils import block_signals class _EstimatedCorValidator(qt.QDoubleValidator): def __init__(self, parent=None): super().__init__(parent) self.setDecimals(3) def validate(self, a0: str, a1: int): """validate float or string that could be part of the side values...""" for side in Side: if side.value.startswith(a0): return (qt.QDoubleValidator.Acceptable, a0, a1) return super().validate(a0, a1) class EstimatedCorComboBox(QComboBoxIgnoreWheel): """ Combobox that display the sides available according to the cor algorithm (left, right, center, all) and a dedicated item for cor given manually. This combobox is also editable and and make sure the 'estimated cor' item is up to date according to the QCombobox current value """ ESTIMATED_COR_ITEM_DATA = "estimated_cor" sigEstimatedCorChanged = qt.Signal(object) """Emit when the estimated cor changed. Value can be a float (cor value) or a Side""" def __init__(self, parent=None): super().__init__(parent) self.addItem("0.0", self.ESTIMATED_COR_ITEM_DATA) for side in Side: self.addItem(side.value, side) self.setValidator(_EstimatedCorValidator()) self.setEditable(True) self.setToolTip( """Estimated position of the center of rotation (COR) to be given to the cor algorithms. \n If you don't have a fair estimate you can provide only a side """ ) # connect signal / slot self.lineEdit().editingFinished.connect(self._corHasBeenEdited) self.currentIndexChanged.connect(self._corChanged) def _corHasBeenEdited(self): current_cor = self.getCurrentCorValue() if isinstance(current_cor, float): # keep the item up to date self._setCorItemValue(current_cor) self.sigEstimatedCorChanged.emit(current_cor) def _corChanged(self): self.sigEstimatedCorChanged.emit(self.getCurrentCorValue()) def getCurrentCorValue(self) -> Side | float: try: return float(self.currentText()) except ValueError: return Side(self.currentText()) def setCurrentCorValue(self, value: float | Side): if isinstance(value, float): self._setCorItemValue(value) else: side = Side(value) item = self.findData(side) self.setCurrentIndex(item) def _setCorItemValue(self, value: float): item_index = self.findData(self.ESTIMATED_COR_ITEM_DATA) view = self.view() hidden = view.isRowHidden(item_index) with block_signals(self): self.setItemText(item_index, f"{value:.2f}") view.setRowHidden(item_index, hidden) def get_hidden_sides(self) -> tuple[Side]: """Return all sides currently hidden""" view = self.view() return tuple( filter( lambda side: view.isRowHidden(self.findData(side)), [Side(side) for side in Side], ) ) def setSidesVisible(self, sides: tuple[Side]): """Set side to be visible to the user""" sides_visibles = tuple([Side(side) for side in sides]) view = self.view() for side in Side: item_idx = self.findData(side) view.setRowHidden(item_idx, side not in sides_visibles) need_new_current_value = self.getCurrentCorValue() in self.get_hidden_sides() if need_new_current_value: # if the current side used cannot be used fall back to the estimated cor from motor self.setCurrentIndex(self.findData(self.ESTIMATED_COR_ITEM_DATA)) def setFirstGuessAvailable(self, available: bool): """ For some method (only growing window at the moment) a first guess (estimated cor as a float) cannot be given """ view = self.view() item_index = self.findData(self.ESTIMATED_COR_ITEM_DATA) view.setRowHidden(item_index, not available) def selectFirstGuess(self): item_index = self.findData(self.ESTIMATED_COR_ITEM_DATA) self.setCurrentIndex(item_index) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/axis/InputWidget.py0000644000175000017500000003134715153325210023760 0ustar00paynopaynofrom __future__ import annotations import logging from silx.gui import qt from tomwer.core.process.reconstruction.axis import mode as axis_mode from tomwer.core.process.reconstruction.axis.anglemode import CorAngleMode from tomwer.gui.utils.scrollarea import QComboBoxIgnoreWheel from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui.utils.qt_utils import block_signals from tomwer.synctools.axis import QAxisRP from .ManualFramesSelection import ManualFramesSelection _logger = logging.getLogger(__name__) class InputWidget(qt.QWidget): """ Widget used to define the radios or the sinogram to be used for computing the cor Used as a tab of the AxisSettingsTabWidget """ sigChanged = qt.Signal() """Signal emitted when input changed""" _sigUrlChanged = qt.Signal() """Signal emit when url to be used changed""" def __init__(self, parent=None, axis_params=None): assert isinstance(axis_params, QAxisRP) self._blockUpdateAxisParams = False super().__init__(parent) self.setLayout(qt.QVBoxLayout()) # radio input self._radioGB = qt.QGroupBox(self) self._radioGB.setTitle("radios") self._radioGB.setLayout(qt.QVBoxLayout()) self._radioGB.setCheckable(True) self.layout().addWidget(self._radioGB) ## angle mode self._angleModeWidget = _AngleSelectionWidget( parent=self, axis_params=axis_params ) self._radioGB.layout().addWidget(self._angleModeWidget) self._axis_params = axis_params # sinogram input self._sinogramGB = qt.QGroupBox(self) self._sinogramGB.setLayout(qt.QFormLayout()) self._sinogramGB.setTitle("sinogram") self._sinogramGB.setCheckable(True) self.layout().addWidget(self._sinogramGB) ## sinogram line self._sinogramLineSB = _SliceSelector(self) self._sinogramGB.layout().addRow("line", self._sinogramLineSB) ## sinogram subsampling self._sinogramSubsampling = qt.QSpinBox(self) self._sinogramSubsampling.setRange(1, 1000) self._sinogramSubsampling.setValue(10) self._sinogramGB.layout().addRow("subsampling", self._sinogramSubsampling) self._spacer = qt.QWidget(self) self._spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(self._spacer) # set up self._sinogramGB.setChecked(False) # connect signal / slot self._sinogramGB.toggled.connect(self._sinogramChecked) self._radioGB.toggled.connect(self._radiosChecked) self._sinogramSubsampling.valueChanged.connect(self._changed) self._sinogramLineSB.sigChanged.connect(self._changed) self._angleModeWidget.sigChanged.connect(self._sigUrlChanged) def setScan(self, scan: TomwerScanBase): if scan is not None: self._angleModeWidget.setScan(scan) self._angleModeWidget.setScanRange(scan.scan_range) def setAxisParams(self, axis_params): with block_signals(axis_params): with block_signals(self._axis_params): self._blockUpdateAxisParams = True if axis_params is not None: assert isinstance(axis_params, QAxisRP) with block_signals(self._sinogramGB): self._sinogramChecked( axis_params.mode.requires_sinogram_index(), on_load=True ) self._sinogramLineSB.setSlice(axis_params.sinogram_line) self._sinogramSubsampling.setValue(axis_params.sinogram_subsampling) self._angleModeWidget.setAxisParams(axis_params) self._axis_params = axis_params self._blockUpdateAxisParams = False def getSinogramLine(self) -> str | int: return self._sinogramLineSB.getSlice() def getSinogramSubsampling(self) -> int: return self._sinogramSubsampling.value() def _sinogramChecked(self, checked, on_load=False): with block_signals(self._radioGB): with block_signals(self._sinogramGB): if checked: self._radioGB.setChecked(False) self._sinogramGB.setChecked(True) elif self._radioGB.isEnabled(): self._radioGB.setChecked(not checked) elif on_load: self._sinogramGB.setChecked(checked) else: # ignore it if radio disabled self._sinogramGB.setChecked(True) self._changed() def _radiosChecked(self, checked, on_load=False): with block_signals(self._radioGB): with block_signals(self._sinogramGB): if checked: self._sinogramGB.setChecked(False) self._radioGB.setChecked(True) elif self._sinogramGB.isEnabled(): self._sinogramGB.setChecked(not checked) elif on_load: self._radioGB.setChecked(checked) else: # ignore it if sinogram disabled self._radioGB.setChecked(True) self._changed() def _changed(self, *args, **kwargs): self._updateAxisParams() self.sigChanged.emit() def _updateAxisParams(self): if not self._blockUpdateAxisParams: self._axis_params.sinogram_line = self.getSinogramLine() self._axis_params.sinogram_subsampling = self.getSinogramSubsampling() def setValidInputs(self, modes: list | tuple): """ Define possible inputs. :raises: ValueError if modes are invalid """ modes = set(modes) for mode in modes: try: axis_mode._InputType(mode) except ValueError: raise ValueError( f"mode {mode} should be an instance of {axis_mode._InputType}" ) if len(modes) == 2: self._sinogramGB.setEnabled(True) self._radioGB.setEnabled(True) elif len(modes) > 2: raise ValueError(f"invalid input {modes}") elif len(modes) < 0: raise ValueError("modes is empty") else: mode = axis_mode._InputType(modes.pop()) if mode is axis_mode._InputType.SINOGRAM: self._sinogramGB.setEnabled(True) self._radioGB.setEnabled(False) self._sinogramGB.setChecked(True) elif mode is axis_mode._InputType.RADIOS_X2: self._radioGB.setEnabled(True) self._sinogramGB.setEnabled(False) self._radioGB.setChecked(True) elif mode is axis_mode._InputType.COMPOSITE: # those mode are neither sinogram neither radio. Now one of the two will be checked but without any much meaning self._radioGB.setEnabled(False) self._sinogramGB.setEnabled(False) else: raise ValueError(f"Nothing implemented for {mode.value}") class _AngleSelectionWidget(qt.QWidget): """Group box to select the angle to used for cor calculation (0-180, 90-270 or manual)""" sigChanged = qt.Signal() """signal emitted when the selected angle changed""" def __init__(self, parent=None, axis_params=None): assert isinstance(axis_params, QAxisRP) qt.QWidget.__init__( self, parent=parent, ) self.setLayout(qt.QVBoxLayout()) self._groupBoxMode = qt.QGroupBox( self, title="Angles to use for axis calculation" ) self._groupBoxMode.setLayout(qt.QHBoxLayout()) self.layout().addWidget(self._groupBoxMode) self._corButtonsGps = qt.QButtonGroup(parent=self) self._corButtonsGps.setExclusive(True) self._qrbCOR_0_180 = qt.QRadioButton("0-180", parent=self) self._groupBoxMode.layout().addWidget(self._qrbCOR_0_180) self._qrbCOR_90_270 = qt.QRadioButton("90-270", parent=self) self._qrbCOR_90_270.setToolTip( "pick radio closest to angles 90° and " "270°. If disable mean that the scan " "range is 180°" ) self._groupBoxMode.layout().addWidget(self._qrbCOR_90_270) self._qrbCOR_manual = qt.QRadioButton("other", parent=self) self._qrbCOR_manual.setVisible(True) self._groupBoxMode.layout().addWidget(self._qrbCOR_manual) # add all button to the button group for b in (self._qrbCOR_0_180, self._qrbCOR_90_270, self._qrbCOR_manual): self._corButtonsGps.addButton(b) self.setAxisParams(axis_params) self._manualFrameSelection = ManualFramesSelection(self) self.layout().addWidget(self._manualFrameSelection) self._manualFrameSelection.setVisible(False) # connect signal / Slot self._corButtonsGps.buttonClicked.connect(self._angleModeChanged) self._manualFrameSelection.sigChanged.connect(self._changed) def setScan(self, scan: TomwerScanBase): if scan is not None: self.setScanRange(scan.scan_range) self._manualFrameSelection.setScan(scan=scan) def setScanRange(self, scanRange): if scanRange == 180: self._qrbCOR_90_270.setEnabled(False) # force using 0-180 if was using 90-270 if self._qrbCOR_90_270.isChecked(): self._qrbCOR_0_180.setChecked(True) self._axis_params.angle_mode = CorAngleMode.use_0_180 else: self._qrbCOR_90_270.setEnabled(True) def setAngleMode(self, mode): """ :param mode: mode to use (can be manual , 90-270 or 0-180) """ assert isinstance(mode, CorAngleMode) if mode == CorAngleMode.use_0_180: self._qrbCOR_0_180.setChecked(True) elif mode == CorAngleMode.use_90_270: self._qrbCOR_90_270.setChecked(True) else: self._qrbCOR_manual.setChecked(True) def getAngleMode(self) -> CorAngleMode: """ :return: the angle to use for the axis calculation """ if self._qrbCOR_90_270.isChecked(): return CorAngleMode.use_90_270 elif self._qrbCOR_0_180.isChecked(): return CorAngleMode.use_0_180 else: return CorAngleMode.manual_selection def setAxisParams(self, axis_params): with block_signals(self): self._axis_params = axis_params # set up self.setAngleMode(axis_params.angle_mode) def _angleModeChanged(self, *args, **kwargs): self._axis_params.angle_mode = self.getAngleMode() if self.getAngleMode() is CorAngleMode.manual_selection: self._axis_params.angle_mode_extra = ( self._manualFrameSelection.getFramesUrl() ) else: self._axis_params.angle_mode_extra = None self._manualFrameSelection.setVisible( self.getAngleMode() is CorAngleMode.manual_selection ) self._changed() def _changed(self): self.sigChanged.emit() class _SliceSelector(qt.QWidget): sigChanged = qt.Signal() """signal emit when the selected slice change""" def __init__(self, parent): qt.QWidget.__init__(self, parent) self.setLayout(qt.QHBoxLayout()) self.setContentsMargins(0, 0, 0, 0) self.layout().setContentsMargins(0, 0, 0, 0) self._modeCB = QComboBoxIgnoreWheel(self) self._modeCB.addItem("middle") self._modeCB.addItem("other") self.layout().addWidget(self._modeCB) self._otherSB = qt.QSpinBox(self) self._otherSB.setRange(0, 10000) self.layout().addWidget(self._otherSB) # connect signal / slot self._otherSB.valueChanged.connect(self._valueChanged) self._modeCB.currentIndexChanged.connect(self._modeChanged) # set up self._modeChanged() def getSlice(self) -> int | str: "return a specific slice index or 'middle'" if self.getMode() == "middle": return "middle" else: return self._otherSB.value() def setSlice(self, slice_): if slice_ is None: return if slice_ == "middle": idx = self._modeCB.findText("middle") self._modeCB.setCurrentIndex(idx) else: idx = self._modeCB.findText("other") self._modeCB.setCurrentIndex(idx) self._otherSB.setValue(slice_) self.sigChanged.emit() def getMode(self): return self._modeCB.currentText() def _valueChanged(self): self.sigChanged.emit() def _modeChanged(self, *args, **kwargs): self._otherSB.setVisible(self.getMode() == "other") self._valueChanged() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/axis/ManualFramesSelection.py0000644000175000017500000001452115153325210025731 0ustar00paynopaynofrom __future__ import annotations import logging from bisect import bisect_left from silx.gui import qt from silx.io.url import DataUrl from tomwer.core.scan.scanbase import TomwerScanBase _logger = logging.getLogger(__name__) class ManualFramesSelection(qt.QWidget): """Allows to select frame - angle to be used.""" sigChanged = qt.Signal() """Signal emit when the frame selection changes""" def __init__(self, parent=None) -> None: super().__init__(parent) self._anglesAvailable = [] # cache of the angles available from the current defined frames. Must be sorted !!! self.setLayout(qt.QGridLayout()) self.layout().addWidget(qt.QLabel("frame 1", self), 0, 0, 1, 1) self._frame1CB = qt.QComboBox(self) self._frame1CB.setEditable(True) self.layout().addWidget(self._frame1CB, 0, 1, 1, 1) self.layout().addWidget(qt.QLabel("frame 2", self), 1, 0, 1, 1) self._frame2CB = qt.QComboBox(self) self._frame2CB.setEditable(True) self.layout().addWidget(self._frame2CB, 1, 1, 1, 1) self._findAssociatedAnglePB = qt.QPushButton("+180°", self) button_180_font = self.font() button_180_font.setPixelSize(10) self._findAssociatedAnglePB.setFont(button_180_font) self._findAssociatedAnglePB.setFixedWidth(30) self._findAssociatedAnglePB.setSizePolicy( qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum ) self.layout().addWidget(self._findAssociatedAnglePB, 1, 2, 1, 1) self._flipLRCB = qt.QCheckBox("flip L-R") self._flipLRCB.setChecked(True) self.layout().addWidget(self._flipLRCB, 1, 3, 1, 1) self._flipLRCB.toggled.connect(self._changed) self._frame1CB.currentIndexChanged.connect(self._changed) self._frame2CB.currentIndexChanged.connect(self._changed) self._findAssociatedAnglePB.released.connect(self._findAssociatedAngle) def _findAssociatedAngle(self): if self._frame1CB.count() == 0 or len(self._anglesAvailable) == 0: _logger.warning("no angles available, unable to get '+180°' frame") else: angle = float(self._frame1CB.currentText()) # look for the closest 'associated' angle. # as the angles are not limited to [0-360] we need to check for any value. # if the angle is on the first part of the acquisition we expect to find it near angle +180 # if it is on the second part (for 360 degree) we expect to find it on the first part (0-180) closest_pls_180_angle = self._getClosestAssociatedAngle( angle + 180.0, self._anglesAvailable ) score_add = abs(closest_pls_180_angle - angle) closest_minus_180_angle = self._getClosestAssociatedAngle( angle - 180.0, self._anglesAvailable ) score_sub = abs(closest_minus_180_angle - angle) if score_add >= score_sub: closest_180_angle = closest_pls_180_angle else: closest_180_angle = closest_minus_180_angle item_idx = self._frame2CB.findText(self._angleToStr(closest_180_angle)) if item_idx < 0: _logger.error(f"Unable to find item for angle {closest_180_angle}") else: self._frame2CB.setCurrentIndex(item_idx) @staticmethod def _getClosestAssociatedAngle(angle: float, angles: tuple) -> float: """ return the angle closest angle to 'angle' from 'angles' :warning: angles should be already sorted !!! """ if angles is None or len(angles) == 0: return None if angle in angles: return angle pos = bisect_left(angles, angle) if pos == 0: return angles[0] elif pos > len(angles) - 1: return angles[-1] else: left_angle = angles[pos - 1] right_angle = angles[pos] if abs(right_angle - angle) > abs(left_angle - angle): return left_angle else: return right_angle def _changed(self): self.sigChanged.emit() @staticmethod def _angleToStr(angle: float) -> str: return f"{float(angle):0.3f}" def setScan(self, scan: TomwerScanBase | None) -> None: self._anglesAvailable.clear() self._frame1CB.clear() self._frame2CB.clear() if scan is None: return current_angle1 = self._getFrame1Angle() current_angle2 = self._getFrame2Angle() for proj_angle, proj_url in scan.get_proj_angle_url().items(): try: angle = self._angleToStr(proj_angle) except Exception: angle = proj_angle else: self._anglesAvailable.append(float(proj_angle)) self._frame1CB.addItem(angle, proj_url) self._frame2CB.addItem(angle, proj_url) self._anglesAvailable.sort() idx = self._frame1CB.findText(current_angle1) if idx >= 0: self._frame1CB.setCurrentIndex(idx) if current_angle1 == current_angle2: # if the two current angle are close then we consider it is better to look for angleX - angleX + 180 angles # instead of finding back angles self._findAssociatedAngle() else: idx = self._frame1CB.findText(current_angle1) if idx >= 0: self._frame1CB.setCurrentIndex(idx) idx = self._frame2CB.findText(current_angle2) if idx >= 0: self._frame2CB.setCurrentIndex(idx) def getFramesUrl(self, as_txt=False) -> tuple: """ Return a tuple of (frame 1 url, frame 2 url). Url can be None """ if as_txt: return self.getFrame1Url().path(), self.getFrame2Url().path() else: return self.getFrame1Url(), self.getFrame2Url() def getFrame1Url(self) -> DataUrl | None: return self._frame1CB.currentData() def getFrame2Url(self) -> DataUrl | None: return self._frame2CB.currentData() def _getFrame1Angle(self) -> str | None: return self._frame1CB.currentText() def _getFrame2Angle(self) -> str | None: return self._frame2CB.currentText() def isFrame2LRFLip(self): return self._flipLRCB.isChecked() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/axis/__init__.py0000644000175000017500000000015015153325210023240 0ustar00paynopaynofrom .AxisMainWindow import AxisMainWindow # noqa F401 from .AxisWidget import AxisWidget # noqa F401 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9371016 tomwer-1.6.17/src/tomwer/gui/reconstruction/darkref/0000755000175000017500000000000015153325403021611 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/darkref/__init__.py0000644000175000017500000000000015153325210023704 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/darkref/darkrefcopywidget.py0000644000175000017500000002464315153325210025705 0ustar00paynopaynofrom __future__ import annotations import logging import shutil from silx.gui import qt from silx.gui.dialog.DataFileDialog import DataFileDialog from silx.io.url import DataUrl from tomwer.core import settings from tomwer.core.utils.lbsram import is_low_on_memory from tomwer.core.process.reconstruction.darkref.darkrefscopy import DarkRefsCopy from tomwer.gui.reconstruction.darkref.darkrefwidget import DarkRefWidget from tomwer.io.utils import get_default_directory _logger = logging.getLogger(__name__) class DarkRefAndCopyWidget(DarkRefWidget): """ Widget associated to the DarkRefCopy process """ sigModeAutoChanged = qt.Signal() """Signal emitted when the mode auto change""" sigCopyActivationChanged = qt.Signal() """Signal emitted when the copy is activated or deactivated""" sigClearCache = qt.Signal() def __init__(self, save_dir: str, parent=None, reconsparams=None, process_id=None): DarkRefWidget.__init__( self, parent=parent, reconsparams=reconsparams, process_id=process_id ) self._mode_auto = True self._refCopyWidget = RefCopyWidget( parent=self, save_dir=save_dir, refCopy=self ) iCopy = self.mainWidget.addTab(self._refCopyWidget, "copy") tooltip = ( "When copy is activated it will record refHST and dark " "files. \n Then when an acquisition without dark or refHST " "go through the widget it will copy those dark and refHST " "in the acquisition." ) self.mainWidget.setTabToolTip(iCopy, tooltip) self.layout().setContentsMargins(0, 0, 0, 0) # connect signal / slot self._refCopyWidget.sigModeAutoChanged.connect(self._triggerModeAuto) self._refCopyWidget.sigCopyActivationChanged.connect( self._triggerCopyActivation ) self._refCopyWidget.sigClearCache.connect(self.sigClearCache) def setRefSetBy(self, scan_id: str): self._refCopyWidget._statusBar.showMessage(f"ref set from {scan_id}") def set_mode_auto(self, auto): self._mode_auto = auto def setRefsFromScan(self, value): raise NotImplementedError() def _triggerModeAuto(self, *args, **kwargs): self.sigModeAutoChanged.emit() def _triggerCopyActivation(self, *args, **kwargs): self.sigCopyActivationChanged.emit() def setCopyActive(self, active): self._refCopyWidget.setChecked(active) def isCopyActive(self): return self._refCopyWidget.isChecked() def setModeAuto(self, mode_auto): old = self.blockSignals(True) self._refCopyWidget.setModeAuto(mode_auto) self.blockSignals(old) def isOnModeAuto(self): return self._refCopyWidget.is_on_mode_auto() def close(self): self.blockSignals(True) self._refCopyWidget.close() super(DarkRefAndCopyWidget, self).close() def _dealWithMissingRef(self, scanID): # Security: if lbs is full, skip requesting fir user ref if ( settings.isOnLbsram(scanID) and is_low_on_memory(settings.get_lbsram_path()) is True ): # if computer is running into low memory on lbsram skip it mess = ( "low memory, do not ask user for references (refCopy) " "for %s" % scanID ) _logger.processSkipped(mess) return if (not self._gui.askForFlatUrl()) or (not self._gui.askForDarkUrl()): mes = "no reference created for %s, no link registred." % scanID _logger.processSkipped(mes) else: # process ref on this folder if only originals are here self.worker.set_process_only_dkRf(True) originalFolder = self.worker.directory self.worker.directory = self._gui.getCopyFolder() self.worker.process() self.worker.set_refs_from_scan(self.worker.directory) self.worker.directory = originalFolder if self.worker.has_flat_or_dark_stored() is True: self.worker.set_process_only_copy(True) self.worker.run() else: self._dealWithMissingRef(scanID) class RefCopyWidget(qt.QGroupBox): """ GUI for the :class:RefCopy """ sigModeAutoChanged = qt.Signal() """Signal emitted when the mode auto change""" sigCopyActivationChanged = qt.Signal() """Signal emitted when the copy is activated or deactivated""" sigClearCache = qt.Signal() """Signal when the cache needs to be cleared""" _DEFAULT_DIRECTORY = "/lbsram/data/visitor" """Default directory used when the user need to set path to references""" _MSG_NO_REF = "!!! No reference recorded !!!" def __init__(self, parent, save_dir: str, refCopy): """ :param parent: Qt parent :param save_dir: where the dark and flats 'references' are stored """ qt.QGroupBox.__init__(self, "activate", parent) self.__save_dir = save_dir self._refCopy = refCopy self.setLayout(qt.QVBoxLayout()) self.setCheckable(True) self._infoLabel = qt.QLabel( """ The copy action happen after the reduced (computed) darks and flats. It can be activate or not. \n\n Reduced darks and / or flats can be registered and then copy to scan without darks or flat. \n You can set manually Darks and flat (button displayed when the mode auto is unchecked.) \n Otherwise if the mode 'auto' is activated then each time he meets scan with dark and / or flat it will register those as the one to be copied. \n Then each time the copy action meets scan without reduced dark and / or flat it will copy them. \n """, self, ) self.layout().addWidget(self._infoLabel) self.layout().addWidget(self.__createManualGUI()) self._qcbAutoMode = qt.QCheckBox("auto", parent=self) self.layout().addWidget(self._qcbAutoMode) spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer) self._removeCacheFile = qt.QPushButton("clear cache") self._removeCacheFile.setToolTip( "Remove the file used for cacheing reduce dark / flat." ) self.layout().addWidget(self._removeCacheFile) self.layout().addWidget(self.__createStatusBarGUI()) self.setModeAuto(True) self._qcbAutoMode.toggled.connect(self._updateModeAuto) # expose API self.sigActivated = self.toggled # connect signal / slot self.toggled.connect(self._triggerCopyActivated) self._qcbAutoMode.toggled.connect(self._triggerModeAutoChanged) self._removeCacheFile.released.connect(self.sigClearCache) def _triggerCopyActivated(self, *args, **kwargs): self.sigCopyActivationChanged.emit() def _triggerModeAutoChanged(self, *args, **kwargs): self.sigModeAutoChanged.emit() def sizeHint(self): return qt.QSize(400, 200) def __createManualGUI(self): self._manualSelectionWidget = qt.QWidget(self) self._manualSelectionWidget.setLayout(qt.QFormLayout()) self._selectDarks = qt.QPushButton("select darks url", parent=self) self._manualSelectionWidget.layout().addRow(self._selectDarks) self._selectFlats = qt.QPushButton("select flats url", parent=self) self._manualSelectionWidget.layout().addRow(self._selectFlats) self._cacheFileLabel = qt.QLabel( DarkRefsCopy.get_save_file(self.__save_dir), self ) self._manualSelectionWidget.layout().addRow( "current cache file is", self._cacheFileLabel ) self._cacheFileLabel.setToolTip( "Dark-Flat copy mecanism store darks and flat at a specific location. If you want you can browse the file to see what are the dark and flat you will copy" ) self._selectDarks.released.connect(self.askForDarksUrl) self._selectFlats.released.connect(self.askForFlatsUrl) return self._manualSelectionWidget def __createStatusBarGUI(self): self._statusBar = qt.QStatusBar(parent=self) self._statusBar.showMessage(self._MSG_NO_REF) return self._statusBar def _clearRef(self): shutil.rmtree(self.__save_dir) def askForFlatsUrl(self): dialog = DataFileDialog() dialog.setDirectory(get_default_directory()) if dialog.exec(): url = dialog.selectedUrl() try: url = DataUrl(path=url) except Exception as e: _logger.error(f"Fails to define flat url. Error is {e}") return False else: self._statusBar.showMessage(f"darks set from {url.path()}") DarkRefsCopy.save_flats_to_be_copied(self.__save_dir, data=url) return True return False def askForDarksUrl(self): dialog = DataFileDialog() dialog.setDirectory(get_default_directory()) if dialog.exec(): url = dialog.selectedUrl() try: url = DataUrl(path=url) except Exception as e: _logger.error(f"Fails to define flat url. Error is {e}") return False else: self._statusBar.showMessage(f"darks set from {url.path()}") DarkRefsCopy.save_darks_to_be_copied(self.__save_dir, data=url) return True return False def setModeAuto(self, b): self._refCopy.set_mode_auto(b) self._manualSelectionWidget.setVisible(not b) self._qcbAutoMode.setChecked(b) def is_on_mode_auto(self): return self._qcbAutoMode.isChecked() def _updateModeAuto(self): """call back of `_qcbGiveManually`""" self._refCopy.set_mode_auto(self._qcbAutoMode.isChecked()) self._manualSelectionWidget.setVisible(not self._qcbAutoMode.isChecked()) def copyActivated(self): """ :return bool: Return True if the user want to copy reduced darks and flats """ return self.isChecked() def save_darks_to_be_copied(self, darks: DataUrl | dict): DarkRefsCopy.save_darks_to_be_copied(data=darks, save_dir=self.__save_dir) def save_flats_to_be_copied(self, flats: DataUrl | dict): DarkRefsCopy.save_flats_to_be_copied(data=flats, save_dir=self.__save_dir) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/darkref/darkrefwidget.py0000644000175000017500000003542315153325210025010 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging from silx.gui import qt from tomwer.core.process.reconstruction.darkref import params as dkrf from tomwer.core.process.reconstruction.darkref.darkrefs import DarkRefsTask from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui.utils.sandboxes import RegularExpressionSandBox from tomwer.synctools.darkref import QDKRFRP logger = logging.getLogger(__name__) class DarkRefWidget(qt.QWidget): """ A simple widget managing the copy of an incoming folder to an other one :param parent: the parent widget """ sigScanReady = qt.Signal(TomwerScanBase) """signal emitted when a scan is ready""" sigProcessingStart = qt.Signal() """signal emitted when a processing starts""" sigProcessingEnd = qt.Signal() """signal emitted when a processing ends""" def __init__(self, reconsparams, parent, process_id=None): qt.QWidget.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) self.mainWidget = DarkRefTab(parent=self, reconsparams=reconsparams) self.layout().addWidget(self.mainWidget) # expose API self.setReconsParams = self.mainWidget.setReconsParams # set up self.mainWidget.setReconsParams(recons_params=reconsparams) def _processingStarted(self): self.sigProcessingStart.emit() def _processingEnded(self): self.sigProcessingEnd.emit() def setName(self, name): self._darkRef.name = name def setForceSync(self, sync): raise NotImplementedError("") self._darkRef.setForceSync(sync) def _scanReady(self, scan): assert isinstance(scan, TomwerScanBase) self.sigScanReady.emit(scan) @property def recons_params(self): return self.mainWidget.recons_params class QDarkRefs(DarkRefsTask): def _computationStarts(self): pass def _computationEnds(self): pass class _WhatCheckBox(qt.QWidget): """ Widget grouping a checkbox and a combobox to know the requested mode (None, median, average) for a what (ref, dark) """ sigChanged = qt.Signal(dkrf.ReduceMethod) """Signal emitted when the calculation mode change""" def __init__(self, parent, text): qt.QWidget.__init__(self, parent) self.setLayout(qt.QHBoxLayout()) self._checkbox = qt.QCheckBox(text=text, parent=self) self.layout().addWidget(self._checkbox) self._modeCB = qt.QComboBox(parent=self) for mode in dkrf.ReduceMethod: if mode is dkrf.ReduceMethod.NONE: continue self._modeCB.addItem(mode.value) self._modeCB.setItemData( self._modeCB.findText(dkrf.ReduceMethod.MEDIAN.value), "Compute the median for each serie", qt.Qt.ToolTipRole, ) self._modeCB.setItemData( self._modeCB.findText(dkrf.ReduceMethod.MEAN.value), "Compute the average for each serie", qt.Qt.ToolTipRole, ) self._modeCB.setItemData( self._modeCB.findText(dkrf.ReduceMethod.FIRST.value), "Pick the first frame for a serie", qt.Qt.ToolTipRole, ) self._modeCB.setItemData( self._modeCB.findText(dkrf.ReduceMethod.LAST.value), "Pick the last frame for a serie", qt.Qt.ToolTipRole, ) self.layout().addWidget(self._modeCB) self.layout().setContentsMargins(0, 0, 0, 0) self._checkbox.setChecked(True) self._checkbox.toggled.connect(self._modeCB.setEnabled) self._checkbox.toggled.connect(self._modeChange) self._modeCB.currentIndexChanged.connect(self._modeChange) self._updateReconsParam = True """Boolean used to know if we have to apply modifications on the self._reconsParams (in the case user made modification) or not (in the case we are simply reading structure and to avoid looping in signals with other QObject)""" def getMode(self) -> dkrf.ReduceMethod: if self._checkbox.isChecked(): return dkrf.ReduceMethod(self._modeCB.currentText()) else: return dkrf.ReduceMethod.NONE def getModeName(self): return self.getMode().value def _modeChange(self, *a, **b): self.sigChanged.emit(self.getMode()) def setMode(self, mode): mode = dkrf.ReduceMethod(mode) assert mode in dkrf.ReduceMethod self._checkbox.toggled.disconnect(self._modeChange) self._modeCB.currentIndexChanged.disconnect(self._modeChange) self._checkbox.setChecked(mode is not dkrf.ReduceMethod.NONE) if mode is not dkrf.ReduceMethod.NONE: index = self._modeCB.findText(mode.value) if index < 0: logger.error(f"index for {mode.value} is not recognized") else: self._modeCB.setCurrentIndex(index) self._checkbox.toggled.connect(self._modeChange) self._modeCB.currentIndexChanged.connect(self._modeChange) self.sigChanged.emit(self.getMode()) class _TabGeneral(qt.QWidget): """Widget with the general information for dark and ref process""" def __init__(self, parent): qt.QWidget.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) self._grpWhat = qt.QGroupBox("what", parent=self) self._grpWhat.setLayout(qt.QVBoxLayout()) self._darkWCB = _WhatCheckBox(parent=self._grpWhat, text="dark") self._refWCB = _WhatCheckBox(parent=self._grpWhat, text="flat") self._grpWhat.layout().addWidget(self._darkWCB) self.sigDarkChanged = self._darkWCB.sigChanged self._grpWhat.layout().addWidget(self._refWCB) self.sigRefChanged = self._refWCB.sigChanged self.layout().addWidget(self._grpWhat) self._grpOptions = qt.QGroupBox("options", parent=self) self._grpOptions.setLayout(qt.QVBoxLayout()) self._rmOptionCB = qt.QCheckBox( parent=self._grpOptions, text="remove raw EDF files when done (for spec only)", ) self.sigRmToggled = self._rmOptionCB.toggled self._skipOptionCB = qt.QCheckBox( parent=self._grpOptions, text="skip if already existing" ) self.sigSkipToggled = self._skipOptionCB.toggled self._grpOptions.layout().addWidget(self._rmOptionCB) self._grpOptions.layout().addWidget(self._skipOptionCB) self.layout().addWidget(self._grpOptions) spacer = qt.QWidget(parent=self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer) class _TabExpert(qt.QWidget): """Expert process for dark and ref""" sigDarkPatternEdited = qt.Signal(str) sigRefPatternEdited = qt.Signal(str) def __init__(self, parent): qt.QWidget.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) self._patternsWidget = qt.QWidget(parent=self) self._patternsWidget.setLayout(qt.QGridLayout()) self._patternsWidget.layout().addWidget( qt.QLabel("pyhst dark file pattern", parent=self._patternsWidget), 0, 0 ) self._darkLE = qt.QLineEdit(parent=self._patternsWidget) self._darkLE.setToolTip(DarkRefsTask.getDarkPatternTooltip()) self._darkLE.editingFinished.connect(self._darkPatternEdited) self._patternsWidget.layout().addWidget(self._darkLE, 0, 1) self._patternsWidget.layout().addWidget( qt.QLabel("pyhst flat file pattern", parent=self._patternsWidget), 1, 0 ) self._refLE = qt.QLineEdit(parent=self._patternsWidget) self._refLE.setToolTip(DarkRefsTask.getRefPatternTooltip()) self._refLE.editingFinished.connect(self._refPatternEdited) self._patternsWidget.layout().addWidget(self._refLE, 1, 1) self.layout().addWidget(self._patternsWidget) textExtraInfo = ( "note: to have more information about pattern usage \n" "see tooltips over dark and flat field patterns." "\nYou can also see help to have advance" "information" ) labelNote = qt.QLabel(parent=self, text=textExtraInfo) labelNote.setSizePolicy(qt.QSizePolicy.Preferred, qt.QSizePolicy.Minimum) self.layout().addWidget(labelNote) spacer = qt.QWidget(parent=self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer) def _darkPatternEdited(self): self.sigDarkPatternEdited.emit(self._darkLE.text()) def _refPatternEdited(self): self.sigRefPatternEdited.emit(self._refLE.text()) class DarkRefTab(qt.QTabWidget): # TODO: should modify the reconsparams to def __init__(self, parent, reconsparams): self.recons_params = None qt.QTabWidget.__init__(self, parent) self.tabGeneral = _TabGeneral(parent=self) self.addTab(self.tabGeneral, "general") self.tabExpert = _TabExpert(parent=self) self.addTab(self.tabExpert, "expert") self.tabSandBox = RegularExpressionSandBox(parent=self, pattern="") extraSandBoxInfo = qt.QLabel( "This sand box allow you to play with" "regular expressions and check the " "validity of a defined pattern versus " "acquisition names. This way you can be " "insure of the regular expression " "behavior", parent=self.tabSandBox, ) extraSandBoxInfo.setWordWrap(True) self.tabSandBox.layout().insertWidget(0, extraSandBoxInfo) self.tabSandBox.setToolTip("play with regular expression") self.addTab(self.tabSandBox, "re sandbox") self._makeConnection() self.setReconsParams(recons_params=reconsparams) def _disconnectToReconsParams(self): assert self.recons_params try: self.tabGeneral.sigDarkChanged.disconnect( self.recons_params.__class__.dark_calc_method.setter ) self.tabGeneral.sigRefChanged.disconnect( self.recons_params.__class__.flat_calc_method.setter ) self.tabGeneral.sigRmToggled.disconnect(self.recons_params._set_remove_opt) self.tabGeneral.sigSkipToggled.disconnect( self.recons_params._set_skip_if_exist ) self.tabExpert.sigDarkPatternEdited.disconnect( self.recons_params.__class__.dark_pattern.setter ) self.tabExpert.sigRefPatternEdited.disconnect( self.recons_params.__class__.ref_pattern.setter ) self.recons_params.sigChanged.disconnect(self._updateReconsParams) except Exception: pass def _connectToReconsParams(self): assert self.recons_params self.tabGeneral.sigDarkChanged.connect( self.recons_params.__class__.dark_calc_method.setter ) self.tabGeneral.sigRefChanged.connect( self.recons_params.__class__.flat_calc_method.setter ) self.tabGeneral.sigRmToggled.connect(self.recons_params._set_remove_opt) self.tabGeneral.sigSkipToggled.connect(self.recons_params._set_skip_if_exist) self.tabExpert.sigDarkPatternEdited.connect( self.recons_params.__class__.dark_pattern.setter ) self.tabExpert.sigRefPatternEdited.connect( self.recons_params.__class__.flat_pattern.setter ) self.recons_params.sigChanged.connect(self._updateReconsParams) def _updateReconsParams(self): self.loadStructs(self.recons_params.to_dict()) def setReconsParams(self, recons_params): if not isinstance(recons_params, QDKRFRP): raise TypeError _recons_params = recons_params if self.recons_params: self._disconnectToReconsParams() self.recons_params = _recons_params self._updateReconsParams() self._connectToReconsParams() def _makeConnection(self): self.tabGeneral._refWCB.sigChanged.connect(self._refCalcModeChanged) self.tabGeneral._darkWCB.sigChanged.connect(self._darkCalcModeChanged) self.tabGeneral._rmOptionCB.toggled.connect(self._rmOptChanged) self.tabGeneral._skipOptionCB.toggled.connect(self._skipOptChanged) self.tabExpert._darkLE.editingFinished.connect(self._darkPatternChanged) self.tabExpert._refLE.editingFinished.connect(self._refPatternChanged) def loadStructs(self, structs): def warningKeyNotHere(key): logger.warning( "%s key not present in the given struct, " "cannot load value for it." % key ) assert isinstance(structs, dict) if "DARKCAL" not in structs: warningKeyNotHere("DARKCAL") else: self.setDarkMode(structs["DARKCAL"]) if "REFSCAL" not in structs: warningKeyNotHere("REFSCAL") else: self.setRefMode(structs["REFSCAL"]) if "REFSOVE" not in structs: warningKeyNotHere("REFSOVE") else: self.setSkipOption(not structs["REFSOVE"]) if "REFSRMV" not in structs: warningKeyNotHere("REFSRMV") else: self.setRemoveOption(structs["REFSRMV"]) if "RFFILE" not in structs: warningKeyNotHere("RFFILE") else: self.setRefPattern(structs["RFFILE"]) if "DKFILE" not in structs: warningKeyNotHere("DKFILE") else: self.setDarkPattern(structs["DKFILE"]) def setRemoveOption(self, rm): self.tabGeneral._rmOptionCB.setChecked(rm) def setSkipOption(self, skip): self.tabGeneral._skipOptionCB.setChecked(skip) def setDarkMode(self, mode): self.tabGeneral._darkWCB.setMode(mode) def setRefMode(self, mode): self.tabGeneral._refWCB.setMode(mode) def setRefPattern(self, pattern): self.tabExpert._refLE.setText(pattern) def setDarkPattern(self, pattern): self.tabExpert._darkLE.setText(pattern) def _rmOptChanged(self): value = self.tabGeneral._rmOptionCB.isChecked() self.recons_params._set_remove_opt(value) def _skipOptChanged(self): value = self.tabGeneral._skipOptionCB.isChecked() self.recons_params._set_skip_if_exist(value) def _refPatternChanged(self): value = self.tabExpert._refLE.text() self.recons_params["RFFILE"] = value def _darkPatternChanged(self): value = self.tabExpert._darkLE.text() self.recons_params["DKFILE"] = value def _darkCalcModeChanged(self): value = self.tabGeneral._darkWCB.getMode() self.recons_params["DARKCAL"] = value def _refCalcModeChanged(self): value = self.tabGeneral._refWCB.getMode() self.recons_params["REFSCAL"] = value ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9411016 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/0000755000175000017500000000000015153325403021120 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/__init__.py0000644000175000017500000000005415153325210023224 0ustar00paynopaynofrom .slices import NabuWidget # noqa F401 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/castvolume.py0000644000175000017500000003514615153325210023661 0ustar00paynopaynofrom __future__ import annotations import logging from silx.gui import qt from silx.gui.utils import blockSignals from tomwer.core.process.reconstruction.nabu.castvolume import ( DEFAULT_OUTPUT_DIR, RESCALE_MAX_PERCENTILE, RESCALE_MIN_PERCENTILE, ) from tomwer.core.process.reconstruction.output import NabuOutputFileFormat from tomwer.gui.qlefilesystem import QLFileSystem from tomwer.gui.reconstruction.nabu.nabuconfig.output import QNabuFileFormatComboBox from nxtomomill.models.utils import convert_str_to_tuple _logger = logging.getLogger(__name__) class CastVolumeWidget(qt.QWidget): sigConfigChanged = qt.Signal() """Signal emit when the configuration changed""" DEFAULT_OUTPUT_DATA_TYPE = "uint16" AVAILABLE_OUTPUT_DATA_TYPE = ("uint8", "uint16", "float32", "float64") assert DEFAULT_OUTPUT_DATA_TYPE in AVAILABLE_OUTPUT_DATA_TYPE def __init__(self, parent) -> None: super().__init__(parent=parent) self.setLayout(qt.QGridLayout()) # output data size self._castToLabel = qt.QLabel("cast to", self) self._castToLabel.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum) self.layout().addWidget(self._castToLabel, 0, 0, 1, 1) self._outputDataTypeCB = qt.QComboBox(self) for data_type in self.AVAILABLE_OUTPUT_DATA_TYPE: self._outputDataTypeCB.addItem(data_type) self.layout().addWidget(self._outputDataTypeCB, 0, 1, 1, 3) # output file format self._outputFileformatLabel = qt.QLabel("output file format", self) self.layout().addWidget(self._outputFileformatLabel, 1, 0, 1, 1) # for now cast to vol is not handle to better remove it from the list self._outputFileformatCB = QNabuFileFormatComboBox( self, filter_formats=("vol",) ) self.layout().addWidget(self._outputFileformatCB, 1, 1, 1, 3) # let the user provide min and max manually self._minMaxLabel = qt.QLabel("min max values") self.layout().addWidget(self._minMaxLabel, 2, 0, 1, 1) self._minMaxAuto = qt.QCheckBox("auto with rescale from percentiles") self._minMaxAuto.setChecked(True) self._minMaxAuto.setToolTip( "If set to auto will try to get min/max pixel values from nabu histogram else will compute it. Otherwise will values provided by the user" ) self.layout().addWidget(self._minMaxAuto, 2, 1, 1, 1) self._minPixValue = qt.QLineEdit("0.0", self) self._minPixValue.setPlaceholderText("min") self._maxPixValue = qt.QLineEdit("0.0", self) self._maxPixValue.setPlaceholderText("max") validator = qt.QDoubleValidator(self) validator.setNotation(qt.QDoubleValidator.ScientificNotation) self._minPixValue.setValidator(validator) self._maxPixValue.setValidator(validator) self.layout().addWidget(self._minPixValue, 4, 2, 1, 1) self.layout().addWidget(self._maxPixValue, 4, 3, 1, 1) self._minPixValue.setVisible(False) self._maxPixValue.setVisible(False) # or from percentiles self._percentilesLabel = qt.QLabel("rescale percentiles") self.layout().addWidget(self._percentilesLabel, 3, 1, 1, 1) self._lowPercentileQSB = qt.QSpinBox(self) self._lowPercentileQSB.setRange(0, 100) self._lowPercentileQSB.setPrefix("min:") self._lowPercentileQSB.setSuffix("%") self._lowPercentileQSB.setValue(RESCALE_MIN_PERCENTILE) self.layout().addWidget(self._lowPercentileQSB, 3, 2, 1, 1) self._highPercentileQSB = qt.QSpinBox(self) self._highPercentileQSB.setRange(0, 100) self._highPercentileQSB.setPrefix("max:") self._highPercentileQSB.setSuffix("%") self._highPercentileQSB.setValue(RESCALE_MAX_PERCENTILE) self.layout().addWidget(self._highPercentileQSB, 3, 3, 1, 1) # compression ratios for JP2K self._cRatiosLabel = qt.QLabel("compression ratios", self) self.layout().addWidget(self._cRatiosLabel, 5, 0, 1, 1) self._cRatiosQLE = qt.QLineEdit(self) fpm = "\\d*\\.?\\d+" # float or int matching qRegExp = qt.QRegularExpression( "(" + fpm + "[;]?[,]?[ ]?){1,}" + "|" + ":".join((fpm, fpm, fpm)) ) self._cRatiosQLE.setValidator(qt.QRegularExpressionValidator(qRegExp)) self._cRatiosQLE.setPlaceholderText( "l1 compression rate, l2 compression rate..." ) self._cRatiosQLE.setToolTip( "Optional list of int values defining the quality of the different layer. For example '20, 10, 1' will create 3 layers. The first one with a compression factor of 20, the second of 10 and the last will be lossless" ) self.layout().addWidget(self._cRatiosQLE, 5, 1, 1, 3) # save dir self._saveDirLabel = qt.QLabel("output directory", self) self.layout().addWidget(self._saveDirLabel, 15, 0, 1, 1) self._useDefaultSaveDirQCB = qt.QCheckBox("default", self) self._useDefaultSaveDirQCB.setToolTip( f"Default directory is: {DEFAULT_OUTPUT_DIR}" ) self._useDefaultSaveDirQCB.setSizePolicy( qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum ) self._useDefaultSaveDirQCB.setChecked(True) self.layout().addWidget(self._useDefaultSaveDirQCB, 15, 1, 1, 1) self._saveDirQLE = QLFileSystem(text=DEFAULT_OUTPUT_DIR, parent=self) # force text because this is not a valid path self._saveDirQLE.setText(DEFAULT_OUTPUT_DIR) self._saveDirQLE.setToolTip(""" can contains pattern / keywords. Those should be provided as '{keyword}'. Here are pattern currently handled: \n - 'volume_data_parent_folder': returns basename of the directory containing the volume (this will be the parent folder for edf, jp2k...)" """) self._saveDirQLE.setVisible(False) self.layout().addWidget(self._saveDirQLE, 15, 2, 1, 2) # overwrite self._overwriteCB = qt.QCheckBox("overwrite", self) self._overwriteCB.setChecked(True) self.layout().addWidget(self._overwriteCB, 16, 0, 1, 2) # remove input volume self._removeInputvolumeCB = qt.QCheckBox("remove input volume", self) self._removeInputvolumeCB.setChecked(False) self.layout().addWidget(self._removeInputvolumeCB, 17, 0, 1, 2) # spacer self._spacer = qt.QWidget(self) self._spacer.setSizePolicy( qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.Expanding ) self.layout().addWidget(self._spacer, 99, 0, 1, 3) # set up self._outputDataTypeCB.setCurrentText(self.DEFAULT_OUTPUT_DATA_TYPE) self._updateCRatiosVis() # connect signal / slot self._outputFileformatCB.currentIndexChanged.connect(self._configChanged) self._outputFileformatCB.currentIndexChanged.connect(self._updateCRatiosVis) self._outputDataTypeCB.currentIndexChanged.connect(self._configChanged) self._saveDirQLE.editingFinished.connect(self._configChanged) self._useDefaultSaveDirQCB.toggled.connect(self._configChanged) self._overwriteCB.toggled.connect(self._configChanged) self._useDefaultSaveDirQCB.toggled.connect(self._updateOutputDirVis) self._minMaxAuto.toggled.connect(self._configChanged) self._minMaxAuto.toggled.connect(self._updatePixMinMaxVis) self._minPixValue.textChanged.connect(self._configChanged) self._maxPixValue.textChanged.connect(self._configChanged) self._lowPercentileQSB.valueChanged.connect(self._configChanged) self._highPercentileQSB.valueChanged.connect(self._configChanged) self._removeInputvolumeCB.toggled.connect(self._configChanged) def _updateCRatiosVis(self, *args, **kwargs): self._cRatiosLabel.setVisible( self.getOutputFileFormat() == NabuOutputFileFormat.JP2K ) self._cRatiosQLE.setVisible( self.getOutputFileFormat() == NabuOutputFileFormat.JP2K ) def getOutputDataType(self) -> str: return self._outputDataTypeCB.currentText() def setOutputDataType(self, data_type) -> None: if hasattr(data_type, "value"): data_type = data_type.value idx = self._outputDataTypeCB.findText(data_type) if idx >= 0: self._outputDataTypeCB.setCurrentIndex(idx) def getOutputDir(self) -> str: if self._useDefaultSaveDirQCB.isChecked(): return DEFAULT_OUTPUT_DIR else: return self._saveDirQLE.text() def setOutputDir(self, output_dir: str) -> None: self._useDefaultSaveDirQCB.setChecked(output_dir == DEFAULT_OUTPUT_DIR) self._saveDirQLE.setText(output_dir) def getOutputFileFormat(self) -> NabuOutputFileFormat: return NabuOutputFileFormat.from_value(self._outputFileformatCB.currentText()) def setOutputFileformat(self, file_format: str) -> None: file_format = NabuOutputFileFormat.from_value(file_format) idx = self._outputFileformatCB.findText(file_format.value) if idx >= 0: self._outputFileformatCB.setCurrentIndex(idx) def getOverwrite(self) -> bool: return self._overwriteCB.isChecked() def setOverwrite(self, remove) -> None: self._overwriteCB.setChecked(remove) def isRemoveInputVolume(self) -> bool: return self._removeInputvolumeCB.isChecked() def setRemoveInputVolume(self, remove: bool) -> None: self._removeInputvolumeCB.setChecked(remove) def getDataMin(self) -> float | None: if ( self._minMaxAuto.isChecked() or self._minPixValue.text().replace(" ", "") == "" ): return None else: return float(self._minPixValue.text()) def setDataMin(self, value: float | None) -> None: with blockSignals(self._minMaxAuto): self._minMaxAuto.setChecked(value is None) if value is not None: with blockSignals(self._minPixValue): self._minPixValue.setText(str(value)) self._updatePixMinMaxVis() def getDataMax(self) -> float | None: if ( self._minMaxAuto.isChecked() or self._maxPixValue.text().replace(" ", "") == "" ): return None else: return float(self._maxPixValue.text()) def setDataMax(self, value: float | None) -> None: with blockSignals(self._minMaxAuto): self._minMaxAuto.setChecked(value is None) if value is not None: with blockSignals(self._maxPixValue): self._maxPixValue.setText(str(value)) self._updatePixMinMaxVis() def setCompressionRatios(self, c_ratios: list | None): if c_ratios in (None, tuple(), list()): c_ratios = "" self._cRatiosQLE.setText(str(c_ratios)) def getCompressionRatios(self) -> tuple: if self.getOutputFileFormat() is NabuOutputFileFormat.JP2K: # for now the compression ratios are only handled for JP2K return tuple( [int(value) for value in convert_str_to_tuple(self._cRatiosQLE.text())] ) else: return None def getRescalePercentiles(self) -> tuple[int | None, int | None]: if self._minMaxAuto.isChecked(): return self._lowPercentileQSB.value(), self._highPercentileQSB.value() else: return None, None def setRescalePercentiles(self, low: int | None, high: int | None) -> tuple: if low is not None: with blockSignals(self._minMaxAuto): self._minMaxAuto.setChecked(True) self._lowPercentileQSB.setValue(low) if high is not None: with blockSignals(self._minMaxAuto): self._minMaxAuto.setChecked(True) self._highPercentileQSB.setValue(high) self._updatePixMinMaxVis() def getConfiguration(self) -> dict: rescale_min_percentile, rescale_max_percentile = self.getRescalePercentiles() if (rescale_min_percentile, rescale_max_percentile) == (None, None): data_min, data_max = self.getDataMin(), self.getDataMax() else: data_min, data_max = None, None return { "output_data_type": self.getOutputDataType(), "output_file_format": self.getOutputFileFormat().value, "output_dir": self.getOutputDir(), "overwrite": self.getOverwrite(), "rescale_min_percentile": rescale_min_percentile, "rescale_max_percentile": rescale_max_percentile, "data_min": data_min, "data_max": data_max, "compression_ratios": self.getCompressionRatios(), "remove_input_volume": self.isRemoveInputVolume(), } def setConfiguration(self, config: dict) -> None: output_data_type = config.get("output_data_type", None) if output_data_type is not None: self.setOutputDataType(output_data_type) output_file_format = config.get("output_file_format", None) if output_file_format is not None: self.setOutputFileformat(output_file_format) output_dir = config.get("output_dir", None) if output_dir is not None: self.setOutputDir(output_dir) overwrite = config.get("overwrite", None) if overwrite is not None: self.setOverwrite(overwrite) rescale_min_percentile = config.get("rescale_min_percentile", None) rescale_max_percentile = config.get("rescale_max_percentile", None) self.setRescalePercentiles(rescale_min_percentile, rescale_max_percentile) if "data_min" in config: self.setDataMin(config["data_min"]) if "data_max" in config: self.setDataMax(config["data_max"]) if "compression_ratios" in config: self.setCompressionRatios(config["compression_ratios"]) remove_input_volume = config.get("remove_input_volume", None) if remove_input_volume is not None: self.setRemoveInputVolume(remove=remove_input_volume) def _configChanged(self, *args, **kwargs): self.sigConfigChanged.emit() def _updateOutputDirVis(self, *args, **kwargs): self._saveDirQLE.setVisible(not self._useDefaultSaveDirQCB.isChecked()) def _updatePixMinMaxVis(self, *args, **kwargs): self._minPixValue.setVisible(not self._minMaxAuto.isChecked()) self._maxPixValue.setVisible(not self._minMaxAuto.isChecked()) self._percentilesLabel.setVisible(self._minMaxAuto.isChecked()) self._lowPercentileQSB.setVisible(self._minMaxAuto.isChecked()) self._highPercentileQSB.setVisible(self._minMaxAuto.isChecked()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/check.py0000644000175000017500000000646615115744275022575 0ustar00paynopayno# coding: utf-8 from __future__ import annotations from silx.gui import qt from nxtomo.nxobject.nxdetector import ImageKey from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.utils.nxtomoutils import get_n_series def check_dark_series(scan: NXtomoScan, logger=None, user_input: bool = True) -> bool: """ check: - if scan has computed_dark attached. If there is more than one then ask confirmation to the user to process the dataset - else if the NXTomo has more than one series of dark. Otherwise ask confirmation to the user to process the dataset ask confirmation for processing is done by a pop up dialog. :param scan: scan to check :param user_input: if True and if n series of flat is invalid then ask the user to confirm the processing. Else print a warning and refuse processing :return: True if processing can be done else False :note: user can 'force' the processing to be done """ if not isinstance(scan, NXtomoScan): raise TypeError( f"scan is expected to be an instance of {NXtomoScan} not a {type(scan)}" ) try: image_keys = scan.image_keys except AttributeError: image_keys = scan.image_key n_series = get_n_series( image_key_values=image_keys, image_key_type=ImageKey.DARK_FIELD ) if n_series != 1: text = f"{n_series} series of dark found when one expected. Nabu won't be able to run reconstruction (flat field will fail)." if n_series > 1: text += "\nYou can edit image_keys from the `image-key-editor` to ignore a series (invalid all keys of series you want to ignore)." if user_input is False: text += "\n skip processing" if logger is not None: logger.error(text) return False else: msg = qt.QMessageBox() msg.setIcon(qt.QMessageBox.Warning) types = qt.QMessageBox.Ok | qt.QMessageBox.Cancel msg.setStandardButtons(types) text += "\nContinue ?" msg.setText(text) return msg.exec() == qt.QMessageBox.Ok else: return True def check_flat_series(scan: NXtomoScan, logger, user_input: bool = True) -> bool: """ Insure the scan contains at least one series of flat. Otherwise warn the user nabu will not be able to process """ if not isinstance(scan, NXtomoScan): raise TypeError( f"scan is expected to be an instance of {NXtomoScan} not a {type(scan)}" ) try: image_keys = scan.image_keys except AttributeError: image_keys = scan.image_key n_series = get_n_series( image_key_values=image_keys, image_key_type=ImageKey.FLAT_FIELD ) if n_series == 0: text = "No flat found. Nabu will no be able to do the flat field correction and to reconstruct dataset." if user_input is False: if logger is not None: logger.error(text) return False else: msg = qt.QMessageBox() msg.setIcon(qt.QMessageBox.Warning) types = qt.QMessageBox.Ok | qt.QMessageBox.Cancel msg.setStandardButtons(types) text += "\nContinue ?" msg.setText(text) return msg.exec() == qt.QMessageBox.Ok else: return True ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/helical.py0000644000175000017500000000717414757047403023116 0ustar00paynopaynofrom silx.gui import qt from tomwer.gui.qlefilesystem import QLFileSystem class HelicalPrepareWeightsDouble(qt.QWidget): sigConfigChanged = qt.Signal() """emit when the configuration has changed""" def __init__(self, parent=None, *args, **kwargs) -> None: super().__init__(parent, *args, **kwargs) self.setLayout(qt.QGridLayout()) # TODO: optional outptu file path. Default or set by the user self._outputFilePathLabel = qt.QLabel("output file", self) self.layout().addWidget(self._outputFilePathLabel, 0, 0, 1, 1) self._outputFilePathQLE = QLFileSystem( text="{scan_parent_dir_basename}/{scan_dir_name}/map_and_doubleff.hdf5", parent=self, ) self._outputFilePathQLE.setToolTip( "location of the output file. Which will contain the weight map." ) self.layout().addWidget(self._outputFilePathQLE, 0, 2, 1, 1) # transition_width_vertical self._verticalTransitionWidthQDSP = qt.QLabel("transition width", self) self.layout().addWidget(self._verticalTransitionWidthQDSP, 1, 0, 1, 1) self._verticalTransitionWidthQDSP = qt.QDoubleSpinBox(self) self._verticalTransitionWidthQDSP.setRange(0.0, 99999999) self._verticalTransitionWidthQDSP.setValue(50.0) self._verticalTransitionWidthQDSP.setToolTip( "the transition width is used to determine how the weights are apodised near the upper and lower border" ) # TODO: improve tooltip of this self.layout().addWidget(self._verticalTransitionWidthQDSP, 1, 1, 1, 2) # transition_width_vertical self._horizontalTransitionWidthQDSP = qt.QLabel("transition width", self) self.layout().addWidget(self._horizontalTransitionWidthQDSP, 1, 0, 1, 1) self._horizontalTransitionWidthQDSP = qt.QDoubleSpinBox(self) self._horizontalTransitionWidthQDSP.setRange(0.0, 99999999) self._horizontalTransitionWidthQDSP.setValue(50.0) self._horizontalTransitionWidthQDSP.setToolTip( "the transition width is used to determine how the weights are apodised near the upper and lower border" ) self.layout().addWidget(self._horizontalTransitionWidthQDSP, 1, 1, 1, 2) spacer = qt.QWidget(parent=self) spacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer, 100, 0, 1, 3) # connect signal / slot self._outputFilePathQLE.editingFinished.connect(self._changed) self._verticalTransitionWidthQDSP.valueChanged.connect(self._changed) self._horizontalTransitionWidthQDSP.valueChanged.connect(self._changed) def _changed(self, *args, **kwargs): self.sigConfigChanged.emit() def getConfiguration(self) -> dict: return { "processes_file": self._outputFilePathQLE.text(), "transition_width_vertical": self._verticalTransitionWidthQDSP.value(), "transition_width_horizontal": self._horizontalTransitionWidthQDSP.value(), } def setConfiguration(self, config: dict): processes_file = config.get("processes_file", None) if processes_file is not None: self._outputFilePathQLE.setText(processes_file) transition_width = config.get("transition_width_vertical", None) if transition_width is not None: self._verticalTransitionWidthQDSP.setValue(float(transition_width)) transition_width = config.get("transition_width_horizontal", None) if transition_width is not None: self._horizontalTransitionWidthQDSP.setValue(float(transition_width)) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9411016 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/nabuconfig/0000755000175000017500000000000015153325403023233 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/nabuconfig/__init__.py0000644000175000017500000000011514757047403025353 0ustar00paynopaynofrom .nabuconfig import NabuConfiguration, NabuConfigurationTab # noqa F401 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/nabuconfig/base.py0000644000175000017500000000412515153325210024515 0ustar00paynopaynofrom __future__ import annotations from tomwer.core.process.reconstruction.nabu.utils import _NabuStages from tomwer.gui.configuration.level import ConfigurationLevel class _FilteringObject: """ Simple class to define if the widget should be visible or not if visible (at some moment the 'option' wudget should be visible) and if filtered. Should avoid some conflict when set set visible """ def __init__(self, widget): self._widget = widget self._visible = True # is this self._filtered = False def setVisible(self, visible): self._visible = visible self._updateVisibility() def setFiltered(self, filtered): self._filtered = filtered self._updateVisibility() def _updateVisibility(self): self._widget.setVisible(self._visible and self._filtered) class _NabuStageConfigBase: """Define interface for a specific nabu stage configuration widget (or a part of the stage configuration) """ def __init__(self, stage: _NabuStages | str | None): if stage is None: self.__stage = None else: self.__stage = _NabuStages(stage) self._registeredWidgets = {} # list required widgets. Key is widget, value is the configuration # level def registerWidget(self, widget, config_level): """register a widget with a configuration level. :returns: _FilteringObject to use to define widget visibility """ filteringObj = _FilteringObject(widget=widget) self._registeredWidgets[filteringObj] = ConfigurationLevel(config_level) return filteringObj def getConfiguration(self) -> dict: raise NotImplementedError("Base class") def setConfiguration(self, config) -> None: raise NotImplementedError("Base class") def getStage(self) -> _NabuStages | None: return self.__stage def setConfigurationLevel(self, level): for widget in self._registeredWidgets: filtered = self._registeredWidgets[widget] <= level widget.setFiltered(filtered) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/nabuconfig/ctf.py0000644000175000017500000003041715153325210024362 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from silx.gui.utils import blockSignals from enum import Enum as _Enum from tomwer.core.process.reconstruction.nabu.utils import _NabuStages from tomwer.gui.reconstruction.nabu.nabuconfig import base from tomwer.gui.utils.illustrations import _IllustrationWidget from tomwer.gui.utils.scrollarea import QComboBoxIgnoreWheel def nabu_param_ligne_to_dict(str_ligne: str) -> dict: ddict = {} if "=" in str_ligne: for elmt in str_ligne.split(";"): kwv = elmt.lstrip(" ").rstrip(" ") key, value = kwv.split("=") ddict[key] = value return ddict class _DoubleScientific(qt.QLineEdit): """ A simple QLineEdit with a Doublevalidator with Scientific Notation """ def __init__(self, parent=None, *args, **kwargs): super().__init__(parent, *args, **kwargs) validator = qt.QDoubleValidator(parent=self) validator.setNotation(qt.QDoubleValidator.ScientificNotation) self.setValidator(validator) def value(self) -> float: if self.text() == "": return 0.0 else: return float(self.text()) def setValue(self, value): self.setText(str(value)) class OptionalDouble(qt.QWidget): """ A spin box with a Check box to handle 'None' case of the nabu CTF options """ sigChanged = qt.Signal() """emit when the combobox of the double spin box value changed""" def __init__(self, parent) -> None: super().__init__(parent) self.setLayout(qt.QHBoxLayout()) self._cb = qt.QCheckBox("", self) self.layout().addWidget(self._cb) self._dsb = _DoubleScientific(self) self.layout().addWidget(self._dsb) # connect signal ? slot self._cb.toggled.connect(self._updateVisibility) self._cb.toggled.connect(self._changed) self._dsb.textChanged.connect(self._changed) # set up self._updateVisibility() def _changed(self, *args, **kwargs): self.sigChanged.emit() def value(self) -> float | None: if self._cb.isChecked(): return self._dsb.value() else: return None def setValue(self, value: float | None): if value in (None, "None"): self._cb.setChecked(False) else: self._cb.setChecked(True) self._dsb.setValue(float(value)) def setText(self, text: str): self._cb.setText(text) def _updateVisibility(self, *args, **kwargs): self._dsb.setVisible(self._cb.isChecked()) class _BeamShape(_Enum): PARALLEL = "parallel" CONE = "cone" class ConeBeamOpts(qt.QGroupBox): """Specific settings for cone beam geometry""" sigConfChanged = qt.Signal() """emit when ctf parameters changed""" def __init__(self, parent=None, title="cone settings"): super().__init__(parent, title=title) self.setLayout(qt.QGridLayout()) # z1_v self._z1_v = _DoubleScientific(self) self._z1_v.setPlaceholderText("z1_v in meter") self.layout().addWidget(qt.QLabel("z1_v", self), 0, 0, 1, 1) self.layout().addWidget(self._z1_v, 0, 1, 1, 1) # z1_h self._z1_h = _DoubleScientific(self) self._z1_h.setPlaceholderText("z1_h in meter") self.layout().addWidget(qt.QLabel("z1_h", self), 1, 0, 1, 1) self.layout().addWidget(self._z1_h, 1, 1, 1, 1) # illustration to define z1, z2 self._ctfIllustration = _IllustrationWidget(parent=self, img="ctf_z1") self._ctfIllustration.setMinimumSize(qt.QSize(200, 90)) self._ctfIllustration.setSizePolicy( qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding ) self._ctfIllustration.setContentsMargins(0, 0, 0, 0) self._ctfIllustration.layout().setSpacing(0) self.layout().addWidget(self._ctfIllustration, 0, 2, 2, 2) # connect signal / slot self._z1_v.textChanged.connect(self._confChanged) self._z1_h.textChanged.connect(self._confChanged) def _confChanged(self, *args, **kwargs): self.sigConfChanged.emit() def getGeometry(self) -> dict: return { "z1_v": self._z1_v.value(), "z1_h": self._z1_h.value(), } def setGeometry(self, config: dict) -> None: with blockSignals(self): if "z1_v" in config: self._z1_v.setValue(float(config["z1_v"])) if "z1_h" in config: self._z1_h.setValue(float(config["z1_h"])) class CTFGeometry(qt.QGroupBox): """ widget for the ctf_geometry parameter of nabu """ sigConfChanged = qt.Signal() """emit when ctf parameters changed""" def __init__(self, parent=None, title="ctf-geometry") -> None: super().__init__(parent, title=title) self.setLayout(qt.QFormLayout()) self._beamShapeCB = QComboBoxIgnoreWheel(self) for shape in _BeamShape: self._beamShapeCB.addItem(shape.value) self.layout().addRow("shape", self._beamShapeCB) # cone beam settings self._coneBeamSettings = ConeBeamOpts(self) self.layout().addRow(self._coneBeamSettings) # detector pixel size self._detectorPixelSize = OptionalDouble(self) self._detectorPixelSize.setText("overwrite") self._detectorPixelSize._dsb.setPlaceholderText("pixel size in meter") self.layout().addRow("detector pixel size", self._detectorPixelSize) # magnification self._magnification = qt.QCheckBox("magnification", self) self.layout().addRow(self._magnification) # set up self._magnification.setChecked(True) self._updateView() # connect signal / slot self._coneBeamSettings.sigConfChanged.connect(self._confChanged) self._detectorPixelSize.sigChanged.connect(self._confChanged) self._magnification.toggled.connect(self._confChanged) self._beamShapeCB.currentIndexChanged.connect(self._updateView) self._beamShapeCB.currentIndexChanged.connect(self._confChanged) def getBeamShape(self): return _BeamShape(self._beamShapeCB.currentText()) def setBeamShape(self, shape: str | _BeamShape): shape = _BeamShape(shape) self._beamShapeCB.setCurrentText(shape.value) def _updateView(self, *args, **kwargs): self._coneBeamSettings.setVisible(self.getBeamShape() == _BeamShape.CONE) def _confChanged(self, *args, **kwargs): self.sigConfChanged.emit() def getConfiguration(self) -> dict: magnification = "True" if self._magnification.isChecked() else "False" beam_shape = self.getBeamShape() if beam_shape is _BeamShape.PARALLEL: z1_v = None z1_h = None elif beam_shape is _BeamShape.CONE: cone_params = self._coneBeamSettings.getGeometry() z1_v = cone_params["z1_v"] z1_h = cone_params["z1_h"] else: raise NotImplementedError(f"Geometry {beam_shape.value} is not handled") geometry = f" z1_v={z1_v}; z1_h={z1_h}; detec_pixel_size={self._detectorPixelSize.value()}; magnification={magnification}" return {"ctf_geometry": geometry, "beam_shape": beam_shape.value} def setConfiguration(self, ddict: dict) -> None: params = nabu_param_ligne_to_dict(ddict.get("ctf_geometry", "")) with blockSignals(self): for key, value in params.items(): if key == "detec_pixel_size": self._detectorPixelSize.setValue(value) elif key == "magnification": self._magnification.setChecked(value.lower() == "true") beam_shape = ddict.get("beam_shape", None) if beam_shape is not None: if _BeamShape(beam_shape) is _BeamShape.CONE: self._coneBeamSettings.setGeometry(params) self.setBeamShape(beam_shape) class CTFAdvancedParams(qt.QGroupBox): """ widget for the ctf_advanced_params parameter of nabu """ sigConfChanged = qt.Signal() """emit when ctf parameters changed""" def __init__(self, parent=None, title="ctf-advanced-params") -> None: super().__init__(parent, title=title) self.setLayout(qt.QFormLayout()) # length_scale self._length_scale = _DoubleScientific(self) self.layout().addRow("length_scale", self._length_scale) # lim1 self._lim1 = _DoubleScientific(self) self._lim1Label = qt.QLabel("lim1") self.layout().addRow(self._lim1Label, self._lim1) # lim2 self._lim2 = _DoubleScientific(self) self._lim2Label = qt.QLabel("lim2") self.layout().addRow(self._lim2Label, self._lim2) for w in (self._lim1, self._lim1Label, self._lim2, self._lim2Label): w.setToolTip( "parameter of the low-pass filter. Used in equation: 'lim = lim1 * r + lim2 * (1 - r)' where r is some low-pass filter (image dimensionality)" ) # normalize_by_mean self._normalize_by_mean = qt.QCheckBox("normalize by mean", self) self.layout().addRow(self._normalize_by_mean) # set up self._length_scale.setText("1e-5") self._lim1.setText("1e-5") self._lim2.setText("0.2") self._normalize_by_mean.setChecked(True) # connect sginal / slot self._length_scale.textChanged.connect(self._confChanged) self._lim1.textChanged.connect(self._confChanged) self._lim2.textChanged.connect(self._confChanged) self._normalize_by_mean.toggled.connect(self._confChanged) def getLengthScale(self) -> str: if self._length_scale.text() == "": return "0.0" else: return self._length_scale.text() def _confChanged(self, *args, **kwargs): self.sigConfChanged.emit() def getConfiguration(self) -> dict: normalize_by_mean = "True" if self._normalize_by_mean.isChecked() else "False" ctf_advanced_params = f" length_scale={self._length_scale.value()}; lim1={self._lim1.value()}; lim2={self._lim2.value()}; normalize_by_mean={normalize_by_mean}" return { "ctf_advanced_params": ctf_advanced_params, } def setConfiguration(self, ddict: dict) -> None: params = nabu_param_ligne_to_dict(ddict.get("ctf_advanced_params", {})) with blockSignals(self): for key, value in params.items(): if key == "length_scale": self._length_scale.setText(value) elif key == "lim1": self._lim1.setText(value) elif key == "lim2": self._lim2.setText(value) elif key == "normalize_by_mean": self._normalize_by_mean.setChecked(value.lower() == "true") class CTFConfig(qt.QGroupBox, base._NabuStageConfigBase): """ Widget dedicated for the CTF parameters """ sigConfChanged = qt.Signal(str) """emit when ctf parameters changed""" def __init__(self, parent=None, title="ctf parameters"): qt.QGroupBox.__init__(self, parent, title=title, stage=_NabuStages.PHASE) base._NabuStageConfigBase.__init__(self, stage=_NabuStages.PHASE) self.setLayout(qt.QFormLayout()) # geometry self._geometryWidget = CTFGeometry(parent=self, title="geometry") self.layout().addRow(self._geometryWidget) self.registerWidget(self._geometryWidget, "optional") # advanced parameters self._advancedParamsWidget = CTFAdvancedParams( parent=self, title="advanced parameters" ) self.layout().addRow(self._advancedParamsWidget) self.registerWidget(self._advancedParamsWidget, "advanced") # connect signal / slot self._geometryWidget.sigConfChanged.connect(self._confChanged) self._advancedParamsWidget.sigConfChanged.connect(self._confChanged) def _confChanged(self, *args, **kwargs): self.sigConfChanged.emit("phase") def getConfiguration(self) -> dict: ddict = self._geometryWidget.getConfiguration() ddict.update(self._advancedParamsWidget.getConfiguration()) return ddict def setConfiguration(self, ddict): self._geometryWidget.setConfiguration(ddict=ddict) self._advancedParamsWidget.setConfiguration(ddict=ddict) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/nabuconfig/nabuconfig.py0000644000175000017500000002153015153325210025715 0ustar00paynopayno# coding: utf-8 from __future__ import annotations from silx.gui import qt from tomwer.core.process.reconstruction.nabu.utils import _NabuStages from tomwer.gui.reconstruction.nabu.nabuconfig.output import _NabuOutputConfig from tomwer.gui.reconstruction.nabu.nabuconfig.phase import _NabuPhaseConfig from tomwer.gui.reconstruction.nabu.nabuconfig.preprocessing import ( _NabuPreProcessingConfig, ) from tomwer.gui.reconstruction.nabu.nabuconfig.reconstruction import ( _NabuReconstructionConfig, ) class NabuConfiguration(qt.QWidget): """ Top level widget for defining the nabu configuration """ sigConfChanged = qt.Signal(str, str) """Signal emitted when the configuration change. Parameters are (stage, index option modified) """ def __init__(self, parent): qt.QWidget.__init__(self, parent=parent) self._stageHided = [] # list of hided stage. Not taking into account the filter self.setLayout(qt.QVBoxLayout()) # pre processing options self._preProcessingGB = qt.QGroupBox("pre processing", self) self._preProcessingGB.setLayout(qt.QVBoxLayout()) self._preProcessingWidget = _NabuPreProcessingConfig(parent=self) self._preProcessingGB.layout().addWidget(self._preProcessingWidget) self.layout().addWidget(self._preProcessingGB) # phase options self._phaseGB = qt.QGroupBox("phase", self) self._phaseGB.setLayout(qt.QVBoxLayout()) self._phaseWidget = _NabuPhaseConfig(parent=self) self._phaseGB.layout().addWidget(self._phaseWidget) self.layout().addWidget(self._phaseGB) # reconstruction opts self._reconstructionGB = qt.QGroupBox("reconstruction", self) self._reconstructionGB.setLayout(qt.QVBoxLayout()) self._reconstructionWidget = _NabuReconstructionConfig(parent=self) self._reconstructionGB.layout().addWidget(self._reconstructionWidget) self.layout().addWidget(self._reconstructionGB) # output information self._outputGB = qt.QGroupBox("output", self) self._outputGB.setLayout(qt.QVBoxLayout()) self._outputWidget = _NabuOutputConfig(parent=self) self._outputGB.layout().addWidget(self._outputWidget) self.layout().addWidget(self._outputGB) # connect signal / slot self._preProcessingWidget.sigConfChanged.connect( self._signalConfChangedPreProcessing ) self._phaseWidget.sigConfChanged.connect(self._signalConfChangedPhase) self._reconstructionWidget.sigConfChanged.connect( self._signalConfChangedReconstruction ) self._outputWidget.sigConfChanged.connect(self._signalConfChangedOutput) # expose API self.getSlices = self._reconstructionWidget.getSlices self.setOutputDir = self._outputWidget.setOutputDir def setDeltaBetaValue(self, value): self._phaseWidget.setDeltaBetaValue(value) def hideSlicesInterface(self): self._reconstructionWidget.hideSlicesInterface() def hidePaganinInterface(self): self._stageHided.append(self._phaseGB) self._phaseGB.hide() def _signalConfChangedPhase(self, param): self.sigConfChanged.emit(self._phaseWidget.getStage().value, param) def _signalConfChangedPreProcessing(self, param): self.sigConfChanged.emit(self._preProcessingWidget.getStage().value, param) def _signalConfChangedReconstruction(self, param): self.sigConfChanged.emit(self._reconstructionWidget.getStage().value, param) def _signalConfChangedOutput(self, param): self.sigConfChanged.emit(self._outputWidget.getStage().value, param) def getConfiguration(self): config = { "preproc": self._preProcessingWidget.getConfiguration(), "reconstruction": self._reconstructionWidget.getConfiguration(), "dataset": self._reconstructionWidget.getDatasetConfiguration(), "tomwer_slices": self._reconstructionWidget.getSlices(), "output": self._outputWidget.getConfiguration(), "phase": self._phaseWidget.getConfiguration(), } return config def setConfiguration(self, config): if "preproc" in config: self._preProcessingWidget.setConfiguration(config["preproc"]) if "phase" in config: self._phaseWidget.setConfiguration(config["phase"]) if "reconstruction" in config: self._reconstructionWidget.setConfiguration(config["reconstruction"]) if "tomwer_slices" in config: self._reconstructionWidget.setSlices(config["tomwer_slices"]) if "dataset" in config: self._reconstructionWidget.setDatasetConfiguration(config["dataset"]) if "output" in config: self._outputWidget.setConfiguration(config["output"]) def applyFilter(self, stage, option): if stage is None: for widget in ( self._preProcessingGB, self._reconstructionGB, self._outputGB, self._phaseGB, ): widget.setVisible(True) else: stage = _NabuStages(stage) self._preProcessingGB.setVisible(stage is _NabuStages.PRE) self._reconstructionGB.setVisible(stage is _NabuStages.PROC) self._outputGB.setVisible(stage is _NabuStages.POST) self._phaseGB.setVisible(stage is _NabuStages.PHASE) # handle _stageHided list for widget in ( self._preProcessingGB, self._reconstructionGB, self._outputGB, self._phaseGB, ): if widget in (self._stageHided): self._phaseGB.setVisible(False) def setConfigurationLevel(self, level): for widget in ( self._preProcessingWidget, self._reconstructionWidget, self._outputWidget, self._phaseWidget, ): widget.setConfigurationLevel(level) class NabuConfigurationTab(qt.QTabWidget): """ Top level widget for defining the nabu configuration. Same as NabuConfiguration but inside a tab """ sigConfChanged = qt.Signal(str, str) """Signal emitted when the configuration change. Parameters are (stage, index option modified) """ def __init__(self, parent): qt.QTabWidget.__init__(self, parent=parent) # pre processing options self._preProcessingWidget = _NabuPreProcessingConfig(parent=self) self.addTab(self._preProcessingWidget, "pre processing") # phase options self._phaseGB = qt.QGroupBox("apply phase", self) self._phaseGB.setLayout(qt.QVBoxLayout()) self._phaseWidget = _NabuPhaseConfig(parent=self) self._phaseGB.layout().addWidget(self._phaseWidget) self.addTab(self._phaseGB, "phase") # reconstruction opts self._reconstructionWidget = _NabuReconstructionConfig(parent=self) self.addTab(self._reconstructionWidget, "reconstruction") # output information self._outputWidget = _NabuOutputConfig(parent=self) self.addTab(self._outputWidget, "output") # connect signal / slot self._preProcessingWidget.sigConfChanged.connect( self._signalConfChangedPreProcessing ) self._phaseWidget.sigConfChanged.connect(self._signalConfChangedPhase) self._reconstructionWidget.sigConfChanged.connect( self._signalConfChangedReconstruction ) # expose API self.getSlices = self._reconstructionWidget.getSlices self.setOutputDir = self._outputWidget.setOutputDir def _signalConfChangedPhase(self, param): self.sigConfChanged.emit(self._phaseWidget.getStage().value, param) def _signalConfChangedPreProcessing(self, param): self.sigConfChanged.emit(self._preProcessingWidget.getStage().value, param) def _signalConfChangedReconstruction(self, param): self.sigConfChanged.emit(self._reconstructionWidget.getStage().value, param) def getConfiguration(self): config = { "preproc": self._preProcessingWidget.getConfiguration(), "reconstruction": self._reconstructionWidget.getConfiguration(), "tomwer_slices": self.getSlices(), "output": self._outputWidget.getConfiguration(), } config["phase"] = self._phaseWidget.getConfiguration() return config def setConfiguration(self, config): if "preproc" in config: self._preProcessingWidget.setConfiguration(config["preproc"]) if "phase" in config: self._phaseWidget.setConfiguration(config["phase"]) if "reconstruction" in config: self._reconstructionWidget.setConfiguration(config["reconstruction"]) if "tomwer_slices" in config: self._reconstructionWidget.setSlices(config["tomwer_slices"]) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/nabuconfig/output.py0000644000175000017500000002753715153325210025157 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging import os from silx.gui import qt from tomwer.core.process.reconstruction.output import NabuOutputFileFormat from tomwer.core.process.reconstruction.nabu.utils import _NabuStages from tomwer.core.process.reconstruction.output import ProcessDataOutputDirMode from tomwer.gui.qlefilesystem import QLFileSystem from tomwer.gui.reconstruction.nabu.nabuconfig.base import _NabuStageConfigBase from tomwer.io.utils import get_default_directory try: import glymur # noqa #F401 needed for later possible lazy loading except ImportError: has_glymur = False else: has_glymur = True _logger = logging.getLogger(__name__) class QNabuFileFormatComboBox(qt.QComboBox): def __init__(self, parent: qt.QWidget | None = ..., filter_formats=tuple()) -> None: """ :param filter_format: if provided the given file format won't have an item on the ComboBox """ super().__init__(parent=parent) if not isinstance(filter_formats, tuple): raise TypeError( f"filter_format should be a tuple. Get {type(filter_formats)} instead" ) filter_formats = [ NabuOutputFileFormat.from_value(file_format) for file_format in filter_formats ] for ff in NabuOutputFileFormat: if ff in filter_formats: continue if ff is NabuOutputFileFormat.JP2K: if not has_glymur: _logger.warning( "could not load jp2k format, glymur and OpenJPEG requested" ) else: from glymur import version if version.openjpeg_version < "2.3.0": _logger.warning( "You must have at least version 2.3.0 of OpenJPEG " "in order to write jp2k images." ) else: self.addItem(ff.value) else: self.addItem(ff.value) class QNabuFileFormatComboBoxIgnoreWheel(QNabuFileFormatComboBox): def wheelEvent(self, e: qt.QWheelEvent) -> None: pass class NabuOutputLocationWidget(qt.QGroupBox): sigOutputChanged = qt.Signal() """Emit when location changed""" def __init__(self, *args, **kwargs) -> None: super().__init__(title="output folder", *args, **kwargs) self.setLayout(qt.QGridLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.layout().setSpacing(0) # in scan folder self._inScanFolderRB = qt.QRadioButton( ProcessDataOutputDirMode.IN_SCAN_FOLDER.value, self ) self._inScanFolderRB.setToolTip( "Reconstruction will be saved at the same level as the acquisition folder. (near the NXtomo file (.nx) or under the spec acquisition folder)" ) self.layout().addWidget(self._inScanFolderRB, 1, 0, 1, 1) # in processed data dir self._processedDataDirRB = qt.QRadioButton( ProcessDataOutputDirMode.PROCESSED_DATA_FOLDER.value, self ) self._inScanFolderRB.setToolTip( "Reconstruction will be saved under the PROCESSED_DATA/dataset folder. if exists else under the scan folder." ) self.layout().addWidget(self._processedDataDirRB, 2, 0, 1, 1) # other dir self._otherDirRB = qt.QRadioButton(ProcessDataOutputDirMode.OTHER.value, self) self._otherDirRB.setToolTip( "Reconstruction will be saved under user provided folder." ) self.layout().addWidget(self._otherDirRB, 4, 0, 1, 1) self._outputDirQLE = QLFileSystem( "", self, filters=qt.QDir.NoDotAndDotDot | qt.QDir.Dirs ) self.layout().addWidget(self._outputDirQLE, 4, 1, 1, 1) style = qt.QApplication.style() icon_opendir = style.standardIcon(qt.QStyle.SP_DirOpenIcon) self._selectOutputPB = qt.QPushButton(icon_opendir, "", self) self._selectOutputPB.setIcon(icon_opendir) general_tooltip = ( "You can enter a string with some keywords like {my_keyword}. Those will be interpreted during runtime according to scan metadata. Possible keywords are:" + "\n - 'scan_dir_name': returns name of the directory containing the acquisition (! not a path !)" + "\n - 'scan_basename': returns basename of the directory containing the acquisition" + "\n - 'scan_parent_dir_basename': returns basename of the PARENT directory containing the acquisition" + "\n - 'scan_file_name': for NXtomo scans only. Return the name of the file containing the NXtomo" + "\n - 'scan_entry': for NXtomo scans only. Return the name of the entry containing the NXtomo" ) self._selectOutputPB.setToolTip(general_tooltip) self._outputDirQLE.setToolTip(general_tooltip) self.layout().addWidget(self._selectOutputPB, 4, 2, 1, 1) # set up: self._inScanFolderRB.setChecked(True) # connect signal / slot self._inScanFolderRB.toggled.connect(self._outputModeChanged) self._processedDataDirRB.toggled.connect(self._outputModeChanged) self._otherDirRB.toggled.connect(self._outputModeChanged) self._selectOutputPB.released.connect(self._selectOutput) self._inScanFolderRB.setChecked(True) self._outputModeChanged() def getOutputDirMode(self) -> ProcessDataOutputDirMode: if self._inScanFolderRB.isChecked(): return ProcessDataOutputDirMode.IN_SCAN_FOLDER elif self._processedDataDirRB.isChecked(): return ProcessDataOutputDirMode.PROCESSED_DATA_FOLDER elif self._otherDirRB.isChecked(): return ProcessDataOutputDirMode.OTHER def setOutputDirMode(self, mode: ProcessDataOutputDirMode | str) -> None: mode = ProcessDataOutputDirMode.from_value(mode) if mode is ProcessDataOutputDirMode.IN_SCAN_FOLDER: self._inScanFolderRB.setChecked(True) elif mode is ProcessDataOutputDirMode.PROCESSED_DATA_FOLDER: self._processedDataDirRB.setChecked(True) elif mode is ProcessDataOutputDirMode.OTHER: self._otherDirRB.setChecked(True) def _outputModeChanged(self, *args, **kwargs): outputMode = self.getOutputDirMode() self._outputDirQLE.setVisible(outputMode is ProcessDataOutputDirMode.OTHER) self._selectOutputPB.setVisible(outputMode is ProcessDataOutputDirMode.OTHER) self.sigOutputChanged.emit() def _selectOutput(self): # pragma: no cover defaultDirectory = self._outputDirQLE.text() if not os.path.isdir(defaultDirectory): defaultDirectory = get_default_directory() dialog = qt.QFileDialog(self, directory=defaultDirectory) dialog.setFileMode(qt.QFileDialog.DirectoryOnly) if not dialog.exec(): dialog.close() return self._outputDirQLE.setText(dialog.selectedFiles()[0]) def getOutputDir(self): """ :return: None if the default output directory is selected else return path to the directory """ if self._otherDirRB.isChecked(): return self._outputDirQLE.text() else: return None def setOutputDir(self, output_dir): if output_dir in (None, ""): pass else: self._outputDirQLE.setText(output_dir) class _NabuOutputConfig(_NabuStageConfigBase, qt.QWidget): """ Widget to define the output configuration of nabu """ sigConfChanged = qt.Signal(str) """Signal emitted when the configuration change. Parameter is the option modified """ def __init__(self, parent): _NabuStageConfigBase.__init__(self, stage=_NabuStages.POST) qt.QWidget.__init__(self, parent) self.setLayout(qt.QGridLayout()) # output dir self._output_dir_widget = NabuOutputLocationWidget(parent=self) self.layout().addWidget(self._output_dir_widget, 0, 0, 1, 4) self.registerWidget(self._output_dir_widget, "advanced") # file format self._outputFileFormatLabel = qt.QLabel("output file format:", self) self.layout().addWidget(self._outputFileFormatLabel, 1, 0, 1, 1) self._fileFormatCB = QNabuFileFormatComboBoxIgnoreWheel(self) self.layout().addWidget(self._fileFormatCB, 1, 2, 1, 2) self.registerWidget(self._outputFileFormatLabel, "optional") self.registerWidget(self._fileFormatCB, "optional") # file per group self._filePerGroupLabel = qt.QLabel("frame per group:", self) self.layout().addWidget(self._filePerGroupLabel, 2, 0, 1, 1) self._framePerGroup = qt.QSpinBox(self) self._framePerGroup.setMinimum(100) self._framePerGroup.setSingleStep(50) self._framePerGroup.setMaximum(10000) # not managed for now so hide self._filePerGroupLabel.hide() self._framePerGroup.hide() self.layout().addWidget(self._framePerGroup, 2, 2, 1, 2) # spacer for style spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer, 200, 0, 1, 1) # set up self.setFramePerGroup(100) self.setFileformat("hdf5") # connect signal / slot self._output_dir_widget._outputDirQLE.editingFinished.connect( self._outputDirChanged ) self._output_dir_widget.sigOutputChanged.connect(self._outputDirChanged) self._fileFormatCB.currentTextChanged.connect(self._fileFormatChanged) self._framePerGroup.valueChanged.connect(self._framePerGroupChanged) def _outputDirChanged(self): self.sigConfChanged.emit("location") def _fileFormatChanged(self): self.sigConfChanged.emit("file_format") def _framePerGroupChanged(self): self.sigConfChanged.emit("frames_per_group") def getOutputDir(self): return self._output_dir_widget.getOutputDir() def setOutputDir(self, dir): return self._output_dir_widget.setOutputDir(dir) def getOutputdirMode(self): return self._output_dir_widget.getOutputDirMode() def setOutputdirMode(self, mode): return self._output_dir_widget.setOutputDirMode(mode=mode) def getFileFormat(self) -> NabuOutputFileFormat: return NabuOutputFileFormat.from_value(self._fileFormatCB.currentText()) def setFileformat(self, file_format): file_format = NabuOutputFileFormat.from_value(file_format) index = self._fileFormatCB.findText(file_format.value) self._fileFormatCB.setCurrentIndex(index) def getFramePerGroup(self): return self._framePerGroup.value() def setFramePerGroup(self, n_frames): self._framePerGroup.setValue(n_frames) def getConfiguration(self): return { "file_format": self.getFileFormat().value, "location": self.getOutputDir() or "", "output_dir_mode": self.getOutputdirMode().value, # 'frames_per_group': self.getFramePerGroup(), } def setConfiguration(self, config): if "file_format" in config: self.setFileformat(config["file_format"]) location = config.get("location", None) if location == "": location = None if location is not None: self.setOutputDir(location) if "frames_per_group" in config: self.setFramePerGroup(int(config["frames_per_group"])) # definition of default_output_dir_mode ensure backward compatibility default_output_dir_mode = ( None if location is None else ProcessDataOutputDirMode.OTHER ) output_dir_mode = config.get("output_dir_mode", default_output_dir_mode) if output_dir_mode is not None: self.setOutputdirMode(output_dir_mode) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/nabuconfig/phase.py0000644000175000017500000003755615153325210024721 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging from silx.gui import qt from enum import Enum as _Enum from tomwer.core.process.reconstruction.nabu.utils import _NabuPhaseMethod, _NabuStages from tomwer.core.utils.char import BETA_CHAR, DELTA_CHAR from tomwer.gui.reconstruction.nabu.nabuconfig import base from tomwer.gui.reconstruction.nabu.nabuconfig.ctf import CTFConfig from tomwer.gui.utils.inputwidget import SelectionLineEdit from tomwer.gui.utils.scrollarea import QComboBoxIgnoreWheel as QComboBox from tomwer.gui import icons from tomwer.utils import docstring _logger = logging.getLogger(__name__) class PaddingMode(_Enum): ZEROS = "zeros" MEAN = "mean" EDGE = "edge" SYMMETRIC = "symmetric" REFLECT = "reflect" class _NabuPhaseConfig(qt.QWidget, base._NabuStageConfigBase): """ Widget to define the configuration of the nabu preprocessing """ sigConfChanged = qt.Signal(str) """Signal emitted when the configuration change. Parameter is the option modified """ def __init__(self, parent): qt.QWidget.__init__(self, parent, stage=_NabuStages.PHASE) base._NabuStageConfigBase.__init__(self, stage=_NabuStages.PHASE) self.setLayout(qt.QGridLayout()) # phase method self._methodLabel = qt.QLabel("method", self) self.layout().addWidget(self._methodLabel, 1, 0, 1, 1) self._methodCB = QComboBox(parent=self) for method in _NabuPhaseMethod: self._methodCB.addItem(method.value) idx_ctf = self._methodCB.findText(_NabuPhaseMethod.CTF.value) self._methodCB.setItemData( idx_ctf, "Contrast Transfer Function", qt.Qt.ToolTipRole ) self.layout().addWidget(self._methodCB, 1, 1, 1, 3) self.registerWidget(self._methodLabel, "required") self.registerWidget(self._methodCB, "required") # paganin & ctf options self._paganinOpts = NabuPaganinConfig(parent=self) self.layout().addWidget(self._paganinOpts, 2, 0, 3, 3) # unsharp options self._unsharpOpts = NabuUnsharpConfig(parent=self) self.layout().addWidget(self._unsharpOpts, 6, 0, 3, 3) # ctf options self._ctfOpts = CTFConfig(parent=self) self.layout().addWidget(self._ctfOpts, 9, 0, 3, 4) self.registerWidget(self._ctfOpts, "advanced") # spacer for style spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer, 200, 1, 1, 1) # set up item_index = self._methodCB.findText(_NabuPhaseMethod.PAGANIN.value) assert item_index >= 0 self._methodCB.setCurrentIndex(item_index) # connect signal / slot self._methodCB.currentIndexChanged.connect(self._methodChanged) self._paganinOpts.sigConfChanged.connect(self.sigConfChanged) self._unsharpOpts.sigConfChanged.connect(self.sigConfChanged) self._ctfOpts.sigConfChanged.connect(self.sigConfChanged) # set up self._paganinOpts.setEnabled(self.getMethod() is not _NabuPhaseMethod.NONE) self._ctfOpts.setEnabled(self.getMethod() is _NabuPhaseMethod.CTF) def _methodChanged(self, *args, **kwargs): self._paganinOpts.setEnabled(self.getMethod() is not _NabuPhaseMethod.NONE) self._ctfOpts.setEnabled(self.getMethod() is _NabuPhaseMethod.CTF) self._unsharpOpts.setDiscourageUnsharpMask( self.getMethod() is _NabuPhaseMethod.NONE ) self._unsharpOpts._updateUnsharpMaskWarning() self.sigConfChanged.emit("method") def _signalConfChanged(self, param): self.sigConfChanged.emit(param) def getMethod(self) -> _NabuPhaseMethod: return _NabuPhaseMethod(self._methodCB.currentText()) @docstring(base._NabuStageConfigBase) def setConfiguration(self, config) -> None: if "method" in config: method = config.get("method", _NabuPhaseMethod.NONE) if method == "none": method = _NabuPhaseMethod.NONE self._paganinOpts.setConfiguration(config) method = _NabuPhaseMethod(method) index_method = self._methodCB.findText(method.value) if index_method >= 0: self._methodCB.setCurrentIndex(index_method) else: _logger.warning("unable to find method {method}") self._unsharpOpts.setConfiguration(config) self._ctfOpts.setConfiguration(config) @docstring(base._NabuStageConfigBase) def getConfiguration(self) -> dict: configuration = {"method": self.getMethod().value} if self.getMethod() in (_NabuPhaseMethod.PAGANIN, _NabuPhaseMethod.CTF): configuration.update(self._paganinOpts.getConfiguration()) configuration.update(self._unsharpOpts.getConfiguration()) configuration.update(self._ctfOpts.getConfiguration()) return configuration def setConfigurationLevel(self, level): base._NabuStageConfigBase.setConfigurationLevel(self, level) self._unsharpOpts.setConfigurationLevel(level=level) self._paganinOpts.setConfigurationLevel(level=level) def setDeltaBetaValue(self, value): self._paganinOpts.setDeltaBetaValue(value) def getUnsharpCoeff(self) -> float: return self._unsharpOpts.getUnsharpCoeff() def setUnsharpCoeff(self, coeff: float): self._unsharpOpts.setUnsharpCoeff(coeff) def getUnsharpSigma(self) -> float: return self._unsharpOpts.getUnsharpSigma() def setUnsharpSigma(self, sigma: float): self._unsharpOpts.setUnsharpSigma(sigma) def getPaddingType(self): return self._paganinOpts.getPaddingType() def setPaddingType(self, padding_type): return self._paganinOpts.setPaddingType(padding_type) class NabuPaganinConfig(qt.QWidget, base._NabuStageConfigBase): """Configuration widget dedicated to the paganin options for nabu""" sigConfChanged = qt.Signal(str) """Signal emitted when the configuration change. Parameter is the option modified """ def __init__(self, parent): qt.QWidget.__init__(self, parent=parent, stage=_NabuStages.PHASE) base._NabuStageConfigBase.__init__(self, stage=_NabuStages.PHASE) self.setLayout(qt.QGridLayout()) # paganin delta / beta label = DELTA_CHAR + " / " + BETA_CHAR self._db_label = qt.QLabel(label, self) self.layout().addWidget(self._db_label, 0, 0, 1, 1) self._deltaBetaQLE = SelectionLineEdit( "100.0", self, allow_negative_indices=False ) self.layout().addWidget(self._deltaBetaQLE, 0, 1, 1, 3) self.registerWidget(self._db_label, "required") self.registerWidget(self._deltaBetaQLE, "required") # paganin padding_type self._paddingLabel = qt.QLabel("padding", self) self.layout().addWidget(self._paddingLabel, 2, 0, 1, 1) self._paddingTypeCB = QComboBox(self) self._paddingTypeCB.setToolTip( "Padding type for the filtering step " "in Paganin/CTR." ) for padding_type in (PaddingMode.ZEROS, PaddingMode.EDGE): self._paddingTypeCB.addItem(padding_type.value) self.layout().addWidget(self._paddingTypeCB, 2, 1, 1, 3) self.registerWidget(self._paddingLabel, "advanced") self.registerWidget(self._paddingTypeCB, "advanced") # set up item_index = self._paddingTypeCB.findText(PaddingMode.EDGE.value) self._paddingTypeCB.setCurrentIndex(item_index) # connect signal - slot self._deltaBetaQLE.editingFinished.connect(self._paganinDBChanged) self._paddingTypeCB.currentIndexChanged.connect(self._paganinPaddingTypeChanged) def _paganinDBChanged(self, *args, **kwargs): self.sigConfChanged.emit("delta_beta") def _paganinMargeChanged(self, *args, **kwargs): self.sigConfChanged.emit("marge") def _paganinPaddingTypeChanged(self, *args, **kwargs): self.sigConfChanged.emit("padding_type") def getPaddingType(self) -> PaddingMode: current_text = self._paddingTypeCB.currentText() return PaddingMode(current_text) def setPaddingType(self, padding_type): padding_type = PaddingMode(padding_type) item_index = self._paddingTypeCB.findText(padding_type.value) self._paddingTypeCB.setCurrentIndex(item_index) def getDeltaBeta(self) -> str: return self._deltaBetaQLE.text() def setDeltaBetaValue(self, value): self._deltaBetaQLE.setText(str(value)) def getConfiguration(self): return { "delta_beta": self.getDeltaBeta(), # this one is not cast because can contain several values "padding_type": self.getPaddingType().value, } def setConfiguration(self, conf): # delta_beta delta_beta = conf.get("delta_beta", None) if delta_beta is not None: self._deltaBetaQLE.setText(str(delta_beta)) # padding_type padding_type = conf.get("padding_type", None) if padding_type is not None: self.setPaddingType(padding_type) class NabuUnsharpConfig(qt.QWidget, base._NabuStageConfigBase): """Configuration widget dedicated to the unsharp options for nabu""" sigConfChanged = qt.Signal(str) """Signal emitted when the configuration change. Parameter is the option modified """ def __init__(self, parent): qt.QWidget.__init__(self, parent=parent, stage=_NabuStages.PHASE) base._NabuStageConfigBase.__init__(self, stage=_NabuStages.PHASE) self.__discourageUnSharpMask = False self.setLayout(qt.QGridLayout()) warning_icon = icons.getQIcon("warning") warning_unsharp_no_phase = "Warning: applying unsharp mask without phase retrieval can lead to 'noisy' reconstruction" # unsharp coeff self._unsharpCoeffCB = qt.QCheckBox("unsharp coeff", self) self._unsharpCoeffCB.setToolTip( "Unsharp mask strength. The unsharped " "image is equal to\n UnsharpedImage " "= (1 + coeff)*originalPaganinImage " "- coeff * ConvolvedImage. Setting " "this coefficient to zero means that " "no unsharp mask will be applied." ) self.layout().addWidget(self._unsharpCoeffCB, 0, 0, 1, 1) self._unsharpCoeffQLE = qt.QLineEdit("", self) self._unsharpCoeffQLE.setValidator(qt.QDoubleValidator()) self.layout().addWidget(self._unsharpCoeffQLE, 0, 1, 1, 1) self.registerWidget(self._unsharpCoeffCB, "optional") self._unsharpCoeffOpt = self.registerWidget(self._unsharpCoeffQLE, "optional") # unsharp coeff warning self._unSharpCoeffWarning = qt.QLabel("") self._unSharpCoeffWarning.setToolTip(warning_unsharp_no_phase) self._unSharpCoeffWarning.setPixmap(warning_icon.pixmap(20, state=qt.QIcon.On)) self.layout().addWidget(self._unSharpCoeffWarning, 0, 2, 1, 1) self.registerWidget(self._unSharpCoeffWarning, "optional") # unsharp_sigma self._unsharpSigmaCB = qt.QCheckBox("unsharp sigma", self) self._unsharpSigmaCB.setToolTip( "Standard deviation of the Gaussian " "filter when applying an unsharp " "mask\nafter the Paganin filtering. " "Disabled if set to 0." ) self.layout().addWidget(self._unsharpSigmaCB, 1, 0, 1, 1) self._unsharpSigmaQLE = qt.QLineEdit("", self) self._unsharpSigmaQLE.setValidator(qt.QDoubleValidator()) self.layout().addWidget(self._unsharpSigmaQLE, 1, 1, 1, 1) self.registerWidget(self._unsharpSigmaCB, "optional") self._unsharpSigmaOpt = self.registerWidget(self._unsharpSigmaQLE, "optional") # unsharp coeff warning self._unSharpSigmaWarning = qt.QLabel("") self._unSharpSigmaWarning.setToolTip(warning_unsharp_no_phase) self._unSharpSigmaWarning.setPixmap(warning_icon.pixmap(20, state=qt.QIcon.On)) self.layout().addWidget(self._unSharpSigmaWarning, 1, 2, 1, 1) self.registerWidget(self._unSharpSigmaWarning, "optional") # set up self._unsharpCoeffCB.setChecked(False) self._unsharpCoeffQLE.setText(str(3.0)) self._unsharpSigmaCB.setChecked(False) self._unsharpSigmaQLE.setText(str(0.8)) self._showUnsharpCoeffQLE(False) self._showUnsharpSigmaQLE(False) self._updateUnsharpMaskWarning() # signal / slot connection ## unsharp coeff self._unsharpCoeffCB.toggled.connect(self._showUnsharpCoeffQLE) self._unsharpCoeffCB.toggled.connect(self._unsharpCoeffChanged) self._unsharpCoeffCB.toggled.connect(self._updateUnsharpMaskWarning) self._unsharpCoeffQLE.editingFinished.connect(self._unsharpCoeffChanged) ## unsharp sigma self._unsharpSigmaCB.toggled.connect(self._showUnsharpSigmaQLE) self._unsharpSigmaCB.toggled.connect(self._unsharpSigmaChanged) self._unsharpSigmaCB.toggled.connect(self._updateUnsharpMaskWarning) self._unsharpSigmaQLE.editingFinished.connect(self._unsharpSigmaChanged) def _unsharpCoeffChanged(self, *args, **kwargs): self.sigConfChanged.emit("unsharp_coeff") def _unsharpSigmaChanged(self, *args, **kwargs): self.sigConfChanged.emit("unsharp_sigma") def isUnsharpCoeffActive(self): return self._unsharpCoeffCB.isChecked() def isUnsharpSigmaActive(self): return self._unsharpSigmaCB.isChecked() def _showUnsharpCoeffQLE(self, visible): self._unsharpCoeffOpt.setVisible(visible) def _showUnsharpSigmaQLE(self, visible): self._unsharpSigmaOpt.setVisible(visible) def _signalConfChanged(self, param): self.sigConfChanged.emit(param) def getUnsharpCoeff(self) -> float | int: if self.isUnsharpCoeffActive(): return float(self._unsharpCoeffQLE.text()) else: return 0 def setUnsharpCoeff(self, coeff): if coeff == 0.0: self._unsharpCoeffCB.setChecked(False) else: self._unsharpCoeffCB.setChecked(True) self._unsharpCoeffQLE.setText(str(coeff)) def getUnsharpSigma(self) -> float | int: if self.isUnsharpSigmaActive(): return float(self._unsharpSigmaQLE.text()) else: return 0 def setUnsharpSigma(self, sigma): if sigma == 0.0: self._unsharpSigmaCB.setChecked(False) else: self._unsharpSigmaCB.setChecked(True) self._unsharpSigmaQLE.setText(str(sigma)) def getConfiguration(self): return { "unsharp_coeff": self.getUnsharpCoeff(), "unsharp_sigma": self.getUnsharpSigma(), } def setConfiguration(self, conf): if "unsharp_coeff" in conf: self.setUnsharpCoeff(float(conf["unsharp_coeff"])) if "unsharp_sigma" in conf: self.setUnsharpSigma(float(conf["unsharp_sigma"])) def setDiscourageUnsharpMask(self, discourage: bool): """Should we discourage the user to apply unsharp mask. This is the case if he tries to apply an unsharp mask without phase retrieval. """ self.__discourageUnSharpMask = discourage def _updateUnsharpMaskWarning(self): self._unSharpCoeffWarning.setVisible( self.__discourageUnSharpMask and self._unsharpCoeffCB.isChecked() ) self._unSharpSigmaWarning.setVisible( self.__discourageUnSharpMask and self._unsharpSigmaCB.isChecked() ) def setConfigurationLevel(self, level): super().setConfigurationLevel(level) # we also need to update the 'unsharp warning' # note: at the moment if the basic configuration level is selected, without phase and some mask # a warning will appear on bottom of the pahse GB. This is considered expected as this way we # won't hide any warning. self._updateUnsharpMaskWarning() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/nabuconfig/preprocessing.py0000644000175000017500000007736215153325210026503 0ustar00paynopaynofrom __future__ import annotations import logging import sys from silx.gui import qt from tomwer.core.process.reconstruction.nabu.utils import ( _NabuStages, RingCorrectionMethod, ) from tomwer.gui.reconstruction.nabu.nabuconfig.base import _NabuStageConfigBase from tomwer.gui.utils.scrollarea import QComboBoxIgnoreWheel as QComboBox from tomwer.gui.utils.scrollarea import QDoubleSpinBoxIgnoreWheel as QDoubleSpinBox from tomwer.gui.utils.scrollarea import QSpinBoxIgnoreWheel as QSpinBox from tomwer.utils import docstring _logger = logging.getLogger(__name__) class _NabuPreProcessingConfig(_NabuStageConfigBase, qt.QWidget): """ Widget to define the configuration of the nabu preprocessing """ sigConfChanged = qt.Signal(str) """Signal emitted when the configuration change. Parameter is the option modified """ def __init__(self, parent): _NabuStageConfigBase.__init__(self, stage=_NabuStages.PRE) qt.QWidget.__init__(self, parent) self.setLayout(qt.QGridLayout()) # default options ## flat field self._flatFieldCB = qt.QCheckBox("flat field correction", self) self._flatFieldCB.setToolTip("Whether to enable flat-field " "normalization") self.layout().addWidget(self._flatFieldCB, 0, 0, 1, 2) self.registerWidget(self._flatFieldCB, "optional") ## double flat field self._dffCB = qt.QCheckBox("double flat field correction", self) self._dffCB.setToolTip("Whether to enable double flat field " "normalization") self.layout().addWidget(self._dffCB, 1, 0, 1, 2) self._dffSigmaLabel = qt.QLabel("sigma:", self) self._dffSigmaLabel.setAlignment(qt.Qt.AlignRight) self.layout().addWidget(self._dffSigmaLabel, 1, 2, 1, 1) self._dffSigmaQDSB = QDoubleSpinBox(parent=self) self._dffSigmaQDSB.setMinimum(0.0) self._dffSigmaQDSB.setDecimals(2) self._dffSigmaQDSB.setSingleStep(0.1) self._dffSigmaQDSB.setToolTip( "Sigma value to give to the double flat field unsharp mask" ) self.layout().addWidget(self._dffSigmaQDSB, 1, 3, 1, 1) self.registerWidget(self._flatFieldCB, "required") self._dffOptWidgets = [ self.registerWidget(self._dffSigmaLabel, "required"), self.registerWidget(self._dffSigmaQDSB, "required"), ] ## sinogram ring correction self._sinoRingCorrectionCB = qt.QLabel("rings removal method", self) self._sinoRingCorrectionCB.setToolTip("Sinogram rings removal method") self.layout().addWidget(self._sinoRingCorrectionCB, 2, 0, 1, 2) self.registerWidget(self._sinoRingCorrectionCB, "required") self._sinoRingCorrectionMthd = QComboBox(parent=self) for method in RingCorrectionMethod: self._sinoRingCorrectionMthd.addItem(method.value) ## force method to be None by default idx = self._sinoRingCorrectionMthd.findText(RingCorrectionMethod.NONE.value) self._sinoRingCorrectionMthd.setCurrentIndex(idx) self.layout().addWidget(self._sinoRingCorrectionMthd, 2, 2, 1, 1) self.registerWidget(self._sinoRingCorrectionMthd, "required") self._sinoRingsOpts = SinoRingsOptions(parent=self) self.layout().addWidget(self._sinoRingsOpts, 3, 1, 1, 3) ## ccd filter self._ccdFilterCB = qt.QCheckBox("CCD hot spot correction", self) self._ccdFilterCB.setToolTip("Whether to enable the CCD hotspots " "correction") self.layout().addWidget(self._ccdFilterCB, 4, 0, 1, 2) self.registerWidget(self._ccdFilterCB, "optional") ## ccd filter threshold self._ccdHotspotLabel = qt.QLabel("threshold:", self) self._ccdHotspotLabel.setAlignment(qt.Qt.AlignRight) self.layout().addWidget(self._ccdHotspotLabel, 5, 2, 1, 1) self._ccdThreshold = QDoubleSpinBox(self) self._ccdThreshold.setMinimum(0.0) self._ccdThreshold.setMaximum(999999) self._ccdThreshold.setSingleStep(0.01) self._ccdThreshold.setDecimals(6) tooltip = ( "If ccd_filter_enabled = 1, a median filter is applied on " "the 3X3 neighborhood\nof every pixel. If a pixel value " "exceeds the median value more than this parameter,\nthen " "the pixel value is replaced with the median value." ) self._ccdThreshold.setToolTip(tooltip) self.layout().addWidget(self._ccdThreshold, 5, 3, 1, 1) self._ccdOptWidgets = [ self.registerWidget(self._ccdHotspotLabel, "optional"), self.registerWidget(self._ccdThreshold, "optional"), ] ## sr current normalization self._normalizeCurrent = qt.QCheckBox( "Normalize by machine electric current", self ) self._normalizeCurrent.setToolTip( "Whether to normalize frames with Synchrotron Current. This can correct the effect of a beam refill not taken into account by flats." ) self.layout().addWidget(self._normalizeCurrent, 6, 0, 1, 2) self.registerWidget(self._normalizeCurrent, "required") ## take logarithm self._takeLogarithmCB = qt.QCheckBox("take logarithm", self) self.layout().addWidget(self._takeLogarithmCB, 7, 0, 1, 2) self.registerWidget(self._takeLogarithmCB, "advanced") ## log min clip value self._clipMinLogValueLabel = qt.QLabel("log min clip value:", self) self._clipMinLogValueLabel.setAlignment(qt.Qt.AlignRight) self.layout().addWidget(self._clipMinLogValueLabel, 8, 2, 1, 1) self._clipMinLogValue = QDoubleSpinBox(self) self._clipMinLogValue.setMinimum(0.0) self._clipMinLogValue.setMaximum(9999999) self._clipMinLogValue.setSingleStep(0.01) self._clipMinLogValue.setDecimals(6) self.layout().addWidget(self._clipMinLogValue, 8, 3, 1, 1) self._takeLogOpt = [ self.registerWidget(self._clipMinLogValueLabel, "optional"), self.registerWidget(self._clipMinLogValue, "optional"), ] ## log max clip value self._clipMaxLogValueLabel = qt.QLabel("log max clip value:", self) self._clipMaxLogValueLabel.setAlignment(qt.Qt.AlignRight) self.layout().addWidget(self._clipMaxLogValueLabel, 9, 2, 1, 1) self._clipMaxLogValue = QDoubleSpinBox(self) self._clipMaxLogValue.setMinimum(0.0) self._clipMaxLogValue.setMaximum(9999999) self._clipMaxLogValue.setSingleStep(0.01) self._clipMaxLogValue.setDecimals(6) self.layout().addWidget(self._clipMaxLogValue, 9, 3, 1, 1) self._takeLogOpt.extend( [ self.registerWidget(self._clipMaxLogValueLabel, "optional"), self.registerWidget(self._clipMaxLogValue, "optional"), ] ) ## tilt correction self._tiltCorrection = TiltCorrection("tilt correction", self) self.registerWidget(self._tiltCorrection, "advanced") self.layout().addWidget(self._tiltCorrection, 10, 0, 1, 4) # option dedicated to Helical ## process file self._processFileLabel = qt.QLabel("file containing weights maps", self) self.registerWidget(self._processFileLabel, "advanced") self.layout().addWidget(self._processFileLabel, 20, 0, 1, 1) self._processFileQLE = qt.QLineEdit("", self) self.registerWidget(self._processFileQLE, "advanced") self._processFileQLE.setToolTip( "also know as 'process_file'. If you don't have this file it can be created from the 'helical-prepare-weights' widget" ) self.layout().addWidget(self._processFileQLE, 20, 1, 1, 3) # style # spacer for style spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer, 99, 0, 1, 1) # set up self._flatFieldCB.setChecked(True) self.setDFFOptVisible(False) self._ccdFilterCB.setChecked(False) self._normalizeCurrent.setChecked(False) self._ccdThreshold.setValue(0.04) self._clipMinLogValue.setValue(1e-6) self._clipMaxLogValue.setValue(10.0) self._takeLogarithmCB.setChecked(True) self.setCCDOptsVisible(False) self._sinoRingCorrectionMthd.setCurrentText("None") self._sinoRingsOpts.setVisible(False) self._tiltCorrection.setChecked(False) # connect signal / slot self._ccdFilterCB.toggled.connect(self.setCCDOptsVisible) self._takeLogarithmCB.toggled.connect(self.setLogClipValueVisible) self._flatFieldCB.toggled.connect(self._flatFieldChanged) self._dffCB.toggled.connect(self._dffChanged) self._dffCB.toggled.connect(self.setDFFOptVisible) self._dffSigmaQDSB.valueChanged.connect(self._dffSigmaChanged) self._ccdFilterCB.toggled.connect(self._ccdFilterChanged) self._normalizeCurrent.toggled.connect(self._normalizeCurrentChanged) self._ccdThreshold.editingFinished.connect(self._ccdFilterThresholdChanged) self._clipMinLogValue.editingFinished.connect(self._logMinClipChanged) self._clipMaxLogValue.editingFinished.connect(self._logMaxClipChanged) self._takeLogarithmCB.toggled.connect(self._takeLogarithmChanged) self._sinoRingCorrectionMthd.currentIndexChanged.connect( self._sinoRingCorrectionChanged ) self._sinoRingsOpts._levelsMunch.valueChanged.connect(self._sinoRingOptsChanged) self._sinoRingsOpts._sigmaMunch.valueChanged.connect(self._sinoRingOptsChanged) self._tiltCorrection.toggled.connect(self._tiltCorrectionChanged) self._tiltCorrection.sigChanged.connect(self._tiltCorrectionChanged) def _flatFieldChanged(self, *args, **kwargs): self._signalConfChanged("flatfield") def _dffChanged(self, *args, **kwargs): self._signalConfChanged("double_flatfield") def _dffSigmaChanged(self, *args, **kwargs): self._signalConfChanged("dff_sigma") def _ccdFilterChanged(self, *args, **kwargs): self._signalConfChanged("ccd_filter_enabled") def _normalizeCurrentChanged(self, *args, **kwargs): self._signalConfChanged("normalize_srcurrent") def _ccdFilterThresholdChanged(self, *args, **kwargs): self._signalConfChanged("ccd_filter_threshold") def _logMinClipChanged(self, *args, **kwargs): self._signalConfChanged("log_min_clip") def _logMaxClipChanged(self, *args, **kwargs): self._signalConfChanged("log_max_clip") def _takeLogarithmChanged(self, *args, **kwargs): self._signalConfChanged("take_logarithm") def _sinoRingCorrectionChanged(self, *args, **kwargs): method = self.getSinoRingcorrectionMethod() if method is not RingCorrectionMethod.NONE.value: self._sinoRingsOpts.setVisible(True) self._sinoRingsOpts.setMethod(method) else: self._sinoRingsOpts.setVisible(False) self._signalConfChanged("sino_rings_correction") def _sinoRingOptsChanged(self, *args, **kwargs): self._signalConfChanged("sino_rings_options") def _tiltCorrectionChanged(self, *args, **kwargs): self._signalConfChanged("tilt_correction") def _signalConfChanged(self, param, *args, **kwargs): self.sigConfChanged.emit(param) def setDFFOptVisible(self, visible): for widget in self._dffOptWidgets: widget.setVisible(visible) def setCCDOptsVisible(self, visible): for widget in self._ccdOptWidgets: widget.setVisible(visible) def setLogClipValueVisible(self, visible): for widget in self._takeLogOpt: widget.setVisible(visible) def isFlatFieldActivate(self): return self._flatFieldCB.isChecked() def isDoubleFlatFieldActivate(self): return self._dffCB.isChecked() def getDFFSigma(self) -> float: """ :return: double flat field sigma """ return self._dffSigmaQDSB.value() def isCCDFilterActivate(self): return self._ccdFilterCB.isChecked() def getCCDThreshold(self) -> float: return float(self._ccdThreshold.text()) def getNormalizeCurrent(self) -> bool: return self._normalizeCurrent.isChecked() def setNormalizeCurrent(self, normalize: bool) -> None: self._normalizeCurrent.setChecked(normalize) def getLogMinClipValue(self) -> float: return float(self._clipMinLogValue.text()) def getLogMaxClipValue(self) -> float: return float(self._clipMaxLogValue.text()) def getTakeLogarithm(self): return self._takeLogarithmCB.isChecked() def getSinoRingcorrectionMethod(self) -> str: return self._sinoRingCorrectionMthd.currentText() def getSinoRingcorrectionOptions(self) -> str: return " ; ".join( [ f"{key}={value}" for key, value in self._sinoRingsOpts.getOptions().items() ] ) def setSinoRingcorrectionOptions(self, options: str) -> None: opt_as_dict = {} for opt in options.split(";"): opt = opt.replace(" ", "") if len(opt.split("=")) == 2: key, value = opt.split("=") opt_as_dict[key] = value else: _logger.info(f"ignore option {opt}. Invalid synthax") self._sinoRingsOpts.setOptions(opt_as_dict) @docstring(_NabuStageConfigBase) def getConfiguration(self): tilt_correction, autotilt_opts = self._tiltCorrection.getTiltCorrection() return { "flatfield": int(self.isFlatFieldActivate()), "double_flatfield": int(self.isDoubleFlatFieldActivate()), "dff_sigma": self.getDFFSigma(), "ccd_filter_enabled": int(self.isCCDFilterActivate()), "ccd_filter_threshold": self.getCCDThreshold(), "take_logarithm": self.getTakeLogarithm(), "log_min_clip": self.getLogMinClipValue(), "log_max_clip": self.getLogMaxClipValue(), "sino_rings_correction": self.getSinoRingcorrectionMethod(), "sino_rings_options": self.getSinoRingcorrectionOptions(), "tilt_correction": tilt_correction, "autotilt_options": autotilt_opts, "normalize_srcurrent": int(self.getNormalizeCurrent()), "rotate_projections_center": self._tiltCorrection.getRotateProjectionsCenter() or "", } @docstring(_NabuStageConfigBase) def setConfiguration(self, conf): try: self._setConfiguration(conf) except Exception as e: _logger.error(e) def _setConfiguration(self, conf: dict): ff = conf.get("flatfield", None) if ff is not None: self._flatFieldCB.setChecked(bool(ff)) dff = conf.get("double_flatfield", None) if dff is not None: self._dffCB.setChecked(bool(dff)) dff_sigma = conf.get("dff_sigma", None) if dff_sigma not in (None, "", "none"): self._dffSigmaQDSB.setValue(float(dff_sigma)) ccd_filter = conf.get("ccd_filter_enabled", None) if ccd_filter not in (None, "", "none"): self._ccdFilterCB.setChecked(bool(ccd_filter)) ccd_filter_threshold = conf.get("ccd_filter_threshold", None) if ccd_filter_threshold not in (None, "", "none"): self._ccdThreshold.setValue(float(ccd_filter_threshold)) normalize_srcurrent = conf.get("normalize_srcurrent", None) if normalize_srcurrent is not None: self.setNormalizeCurrent(bool(normalize_srcurrent)) take_logarithm = conf.get("take_logarithm", None) if take_logarithm not in (None, "", "none"): self._takeLogarithmCB.setChecked(bool(take_logarithm)) clip_value = conf.get("log_min_clip", None) if clip_value not in (None, "", "none"): self._clipMinLogValue.setValue(float(clip_value)) clip_value = conf.get("log_max_clip", None) if clip_value not in (None, "", "none"): self._clipMaxLogValue.setValue(float(clip_value)) sino_rings_correction = conf.get("sino_rings_correction", None) if sino_rings_correction is not None: if sino_rings_correction == "": sino_rings_correction = RingCorrectionMethod.NONE sino_rings_correction = RingCorrectionMethod(sino_rings_correction).value idx = self._sinoRingCorrectionMthd.findText(sino_rings_correction) if idx >= 0: self._sinoRingCorrectionMthd.setCurrentIndex(idx) sino_rings_options = conf.get("sino_rings_options", None) if sino_rings_options is not None: self.setSinoRingcorrectionOptions(options=sino_rings_options) tilt_correction = conf.get("tilt_correction") autotilt_options = conf.get("autotilt_options") self._tiltCorrection.setTiltCorrection( tilt_correction=tilt_correction, auto_tilt_options=autotilt_options ) rotate_projections_center = conf.get("rotate_projections_center") if rotate_projections_center == "": rotate_projections_center = None self._tiltCorrection.setRotateProjectionsCenter(rotate_projections_center) class SinoRingsOptions(qt.QWidget): _VO_DIMS = ("horizontaly", "horizontaly and vertically") def __init__(self, parent=None, *args, **kwargs): super().__init__(parent, *args, **kwargs) self._method = None self.setLayout(qt.QFormLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.layout().setSpacing(0) # munch parameters self._sigmaMunchLabel = qt.QLabel("sigma", self) self._sigmaMunch = QDoubleSpinBox(self) self._sigmaMunch.setRange(0.0, 2147483647) self.layout().addRow(self._sigmaMunchLabel, self._sigmaMunch) self._levelsMunchLabel = qt.QLabel("levels", self) self._levelsMunch = QSpinBox(self) self._levelsMunch.setRange(0, 2147483647) self.layout().addRow(self._levelsMunchLabel, self._levelsMunch) self._paddingMunch = qt.QCheckBox("padding", self) self.layout().addWidget(self._paddingMunch) # vo parameters self._snrVOLabel = qt.QLabel("snr", self) self._snrVO = QDoubleSpinBox(self) self._snrVO.setMinimum(0.0) tooltip = "Ratio used to locate large stripes. Greater is less sensitive." self._snrVO.setToolTip(tooltip) self._snrVOLabel.setToolTip(tooltip) self.layout().addRow(self._snrVOLabel, self._snrVO) self._laSizeVOLabel = qt.QLabel("la_size", self) self._laSizeVO = QSpinBox(self) self._laSizeVO.setMinimum(0) tooltip = "Window size of the median filter to remove large stripes." self._laSizeVO.setToolTip(tooltip) self._laSizeVOLabel.setToolTip(tooltip) self.layout().addRow(self._laSizeVOLabel, self._laSizeVO) self._smSizeVOLabel = qt.QLabel("sm_size", self) self._smSizeVO = QSpinBox(self) self._smSizeVO.setMinimum(0) tooltip = "Window size of the median filter to remove small-to-medium stripes." self._laSizeVO.setToolTip(tooltip) self._smSizeVOLabel.setToolTip(tooltip) self.layout().addRow(self._smSizeVOLabel, self._smSizeVO) self._dimVOLabel = qt.QLabel("dimension", self) self._dimVO = QComboBox(self) self._dimVO.addItems(self._VO_DIMS) self.layout().addRow(self._dimVOLabel, self._dimVO) # sino mean deringer self._sigmaLowLabel = qt.QLabel("signal low", self) self._sigmaLow = QDoubleSpinBox(self) self._sigmaLow.setMinimum(0.0) self._sigmaHighLabel = qt.QLabel("signal high", self) self.layout().addRow(self._sigmaLowLabel, self._sigmaLow) self._sigmaHigh = QDoubleSpinBox(self) self._sigmaHigh.setMinimum(0.0) tooltip = ( "sigma low and sigma high values are defining the standard deviation of " "gaussian(sigma_low) * (1 - gaussian(sigma_high)). \n" "High values of sigma mean stronger effect of associated filters." ) self._sigmaHigh.setToolTip(tooltip) self._sigmaLow.setToolTip(tooltip) self.layout().addRow(self._sigmaHighLabel, self._sigmaHigh) # set up self.resetConfiguration() def resetConfiguration(self): self.setMethod(method=RingCorrectionMethod.MUNCH) self._levelsMunch.setValue(10) self._sigmaMunch.setValue(1.0) self._paddingMunch.setChecked(False) self._sigmaHigh.setValue(30.0) self._sigmaLow.setValue(0.0) self._snrVO.setValue(3.0) self._laSizeVO.setValue(51) self._smSizeVO.setValue(21) def getVoDim(self): if self._dimVO.currentText() == self._VO_DIMS[0]: return 1 elif self._dimVO.currentText() == self._VO_DIMS[1]: return 2 else: raise NotImplementedError def setVoDim(self, dim: int | str): if dim in ("1", 1, self._VO_DIMS[0]): self._dimVO.setCurrentText(self._VO_DIMS[0]) elif dim in ("2", 2, self._VO_DIMS[1]): self._dimVO.setCurrentText(self._VO_DIMS[1]) else: raise NotImplementedError(f"dim {dim} not handled") def getOptions(self) -> dict: if self.getMethod() is RingCorrectionMethod.NONE: return {} elif self.getMethod() is RingCorrectionMethod.MUNCH: return { "sigma": self._sigmaMunch.value(), "levels": self._levelsMunch.value(), "padding": self._paddingMunch.isChecked(), } elif self.getMethod() is RingCorrectionMethod.VO: return { "snr": self._snrVO.value(), "la_size": self._laSizeVO.value(), "sm_size": self._smSizeVO.value(), "dim": self.getVoDim(), } elif self.getMethod() in ( RingCorrectionMethod.MEAN_DIVISION, RingCorrectionMethod.MEAN_SUBTRACTION, ): return { "filter_cutoff": (self._sigmaLow.value(), self._sigmaHigh.value()), } else: raise NotImplementedError def setOptions(self, options: dict) -> None: # handle munch propertoies if "sigma" in options: self._sigmaMunch.setValue(float(options["sigma"])) if "levels" in options: self._levelsMunch.setValue(int(options["levels"])) padding = options.get("padding") if padding is not None: self._paddingMunch.setChecked(padding in (True, 1, "1", "True")) # handle VO properties snr = options.get("snr") if snr is not None: self._snrVO.setValue(float(snr)) la_size = options.get("la_size") if la_size is not None: self._laSizeVO.setValue(int(la_size)) sm_size = options.get("sm_size") if sm_size is not None: self._smSizeVO.setValue(int(sm_size)) dim = options.get("dim") if dim is not None: self.setVoDim(dim) # handle mean subtraction or division options filter_cutoff = options.get("filter_cutoff") if filter_cutoff is not None: low_pass, high_pass = filter_cutoff self._sigmaLow.setValue(float(low_pass)) self._sigmaHigh.setValue(float(high_pass)) def setMethod(self, method: RingCorrectionMethod): method = RingCorrectionMethod(method) self._method = method # handle munch options self._sigmaMunch.setVisible(method is RingCorrectionMethod.MUNCH) self._sigmaMunchLabel.setVisible(method is RingCorrectionMethod.MUNCH) self._levelsMunch.setVisible(method is RingCorrectionMethod.MUNCH) self._levelsMunchLabel.setVisible(method is RingCorrectionMethod.MUNCH) self._paddingMunch.setVisible(method is RingCorrectionMethod.MUNCH) # handle VO options self._snrVO.setVisible(method is RingCorrectionMethod.VO) self._snrVOLabel.setVisible(method is RingCorrectionMethod.VO) self._laSizeVO.setVisible(method is RingCorrectionMethod.VO) self._laSizeVOLabel.setVisible(method is RingCorrectionMethod.VO) self._smSizeVO.setVisible(method is RingCorrectionMethod.VO) self._smSizeVOLabel.setVisible(method is RingCorrectionMethod.VO) self._dimVO.setVisible(method is RingCorrectionMethod.VO) self._dimVOLabel.setVisible(method is RingCorrectionMethod.VO) # mean subtractions / division deringer self._sigmaLow.setVisible( method in ( RingCorrectionMethod.MEAN_DIVISION, RingCorrectionMethod.MEAN_SUBTRACTION, ) ) self._sigmaLowLabel.setVisible( method in ( RingCorrectionMethod.MEAN_DIVISION, RingCorrectionMethod.MEAN_SUBTRACTION, ) ) self._sigmaHigh.setVisible( method in ( RingCorrectionMethod.MEAN_DIVISION, RingCorrectionMethod.MEAN_SUBTRACTION, ) ) self._sigmaHighLabel.setVisible( method in ( RingCorrectionMethod.MEAN_DIVISION, RingCorrectionMethod.MEAN_SUBTRACTION, ) ) def getMethod(self) -> RingCorrectionMethod: return self._method class TiltCorrection(qt.QGroupBox): """ GroupBox dedicated to nabu TiltCorrection """ sigChanged = qt.Signal() """Signal emit when parameters of the tilt options changed""" def __init__(self, text, parent=None, *args, **kwargs) -> None: super().__init__(text, parent, *args, **kwargs) self.setCheckable(True) self.setLayout(qt.QFormLayout()) self._tiltManualRB = qt.QRadioButton("angle", self) self._angleValueSB = QDoubleSpinBox(self) self._angleValueSB.setRange(-360, 360) self._angleValueSB.setSuffix("°") self.layout().addRow(self._tiltManualRB, self._angleValueSB) self._autoManualRB = qt.QRadioButton("auto", self) self._autoModeCB = QComboBox(self) self._modes = { "1d-correlation": "auto-detect tilt with the 1D correlation method (fastest, but works best for small tilts)", "fft-polar": "auto-detect tilt with polar FFT method (slower, but works well on all ranges of tilts)", } for value, tooltip in self._modes.items(): self._autoModeCB.addItem(value) idx = self._autoModeCB.findText(value) self._autoModeCB.setItemData(idx, tooltip, qt.Qt.ToolTipRole) self.layout().addRow(self._autoManualRB, self._autoModeCB) self._autoTiltOptions = qt.QLineEdit("", self) self._autoTiltOptions.setPlaceholderText("low_pass=1; high_pass=20 ; ...") self._autotiltOptsLabel = qt.QLabel("autotilt options") self._autotiltOptsLabel.setToolTip(""" Options for methods computing automatically the detector tilt. \n The parameters are separated by commas and passed as 'name=value', for example: low_pass=1; high_pass=20. Mind the semicolon separator (;). \n For more details please see https://www.silx.org/pub/nabu/doc/apidoc/nabu.estimation.tilt.html#nabu.estimation.tilt.CameraTilt.compute_angle """) self.layout().addRow(self._autotiltOptsLabel, self._autoTiltOptions) ## `rotate_projections_center` option self._rotateProjectionCenter = RotateProjectionCenterWidget(self) self._rotateProjectionCenter.setToolTip( "\n".join( ( "Allows to correct detector tilt along beam orthogonal plan.", "By default the center of rotation is the middle of each radio, i.e ((Nx-1)/2.0, (Ny-1)/2.0).", ) ) ) self.layout().addRow(self._rotateProjectionCenter) # set up self._autoManualRB.setChecked(True) # connect signal / slot self._tiltManualRB.toggled.connect(self._updateVisibility) self._autoManualRB.toggled.connect(self._updateVisibility) self._tiltManualRB.toggled.connect(self._changed) self._autoManualRB.toggled.connect(self._changed) self._angleValueSB.valueChanged.connect(self._changed) self._updateVisibility() def _changed(self, *args, **kwargs): self.sigChanged.emit() def _updateVisibility(self): self._angleValueSB.setEnabled(self._tiltManualRB.isChecked()) self._autoModeCB.setEnabled(self._autoManualRB.isChecked()) self._autotiltOptsLabel.setVisible(self._autoManualRB.isChecked()) self._autoTiltOptions.setVisible(self._autoManualRB.isChecked()) def getTiltCorrection(self) -> tuple: """ return (tilt value, autotilt options (if any)) """ if not self.isChecked(): return "", "" elif self._tiltManualRB.isChecked(): return self._angleValueSB.value(), "" else: return self._autoModeCB.currentText(), self._autoTiltOptions.text() def setTiltCorrection( self, tilt_correction: str, auto_tilt_options: str | None = None ) -> None: if tilt_correction in ("", None): self.setChecked(False) elif tilt_correction in self._modes.keys(): self.setChecked(True) self._autoManualRB.setChecked(True) idx = self._autoModeCB.findText(tilt_correction) self._autoModeCB.setCurrentIndex(idx) else: self.setChecked(True) self._tiltManualRB.setChecked(True) self._angleValueSB.setValue(float(tilt_correction)) if auto_tilt_options is not None: self._autoTiltOptions.setText(auto_tilt_options) def getRotateProjectionsCenter(self): if self.isChecked(): return self._rotateProjectionCenter.getRotateProjectionsCenter() else: return None def setRotateProjectionsCenter(self, values): self._rotateProjectionCenter.setRotateProjectionsCenter(values=values) class RotateProjectionCenterWidget(qt.QWidget): RANGE_MIN_VALUE = -sys.float_info.max RANGE_MAX_VALUE = sys.float_info.max def __init__(self, parent: qt.QWidget | None = None) -> None: super().__init__(parent) self.setLayout(qt.QHBoxLayout()) self._label = qt.QLabel("rotate projections center") self.layout().addWidget(self._label) self._xQLE = QDoubleSpinBox(self) self._xQLE.setRange( RotateProjectionCenterWidget.RANGE_MIN_VALUE, RotateProjectionCenterWidget.RANGE_MAX_VALUE, ) self._xQLE.setPrefix("x=") self._xQLE.setToolTip("Value should be in [-radio width, radio width]") self._xQLE.setSuffix("px") self.layout().addWidget(self._xQLE) self._yQLE = QDoubleSpinBox(self) self._yQLE.setRange( RotateProjectionCenterWidget.RANGE_MIN_VALUE, RotateProjectionCenterWidget.RANGE_MAX_VALUE, ) self._yQLE.setPrefix("y=") self._xQLE.setToolTip("Value should be in [-radio heigh, radio heigh]") self._yQLE.setSuffix("px") self.layout().addWidget(self._yQLE) def getRotateProjectionsCenter(self) -> tuple | None: if self._xQLE.value() == 0 and self._yQLE.value() == 0: return None else: return (self._xQLE.value(), self._yQLE.value()) def setRotateProjectionsCenter(self, values: tuple[float] | None): if values is None: self._xQLE.setValue(0.0) self._yQLE.setValue(0.0) elif not isinstance(values, (tuple, list)) and len(values) != 2: raise TypeError("values should be a tuple of two elements") else: self._xQLE.setValue(values[0]) self._yQLE.setValue(values[1]) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989076.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py0000644000175000017500000012320415153325224026671 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import functools import logging from silx.gui import qt from silx.gui.dialog.DataFileDialog import DataFileDialog from enum import Enum as _Enum from nxtomomill.models.utils import convert_str_to_tuple from tomwer.core.utils.char import DEGREE_CHAR from tomwer.core.process.reconstruction.nabu.plane import NabuPlane from tomwer.core.process.reconstruction.nabu.nabuslices import NabuSliceMode from tomwer.core.process.reconstruction.nabu.utils import ( _NabuFBPFilterType, _NabuPaddingType, _NabuReconstructionMethods, _NabuStages, ) from tomwer.gui.reconstruction.nabu.nabuconfig.base import _NabuStageConfigBase from tomwer.gui.utils.inputwidget import SelectionLineEdit from tomwer.gui.utils.scrollarea import ( QComboBoxIgnoreWheel, QDoubleSpinBoxIgnoreWheel, QSpinBoxIgnoreWheel, ) from tomwer.gui.utils.RangeWidget import RangeWidget from tomwer.gui import icons from tomwer.utils import docstring _logger = logging.getLogger(__name__) class SliceGroupBox(qt.QGroupBox): """GroupBox to define slice to be reconstructed""" sigSlicesChanged = qt.Signal() """Signal emitted when the selected slices change""" def __init__(self, parent): qt.QGroupBox.__init__(self, "slices", parent) self.setCheckable(True) self.setLayout(qt.QHBoxLayout()) # mode self._modeCB = QComboBoxIgnoreWheel(parent=self) for mode in NabuSliceMode: self._modeCB.addItem(mode.value) self.layout().addWidget(self._modeCB) self._modeCB.setFocusPolicy(qt.Qt.FocusPolicy.NoFocus) # slice line edit self._sliceQLE = SelectionLineEdit(parent=self, allow_negative_indices=True) self.layout().addWidget(self._sliceQLE) # warning icon warningIcon = icons.getQIcon("warning") self._noSliceWarning = qt.QLabel("") self._noSliceWarning.setPixmap(warningIcon.pixmap(20, state=qt.QIcon.On)) self._noSliceWarning.setToolTip( "no slice defined, No slice reconstruction will be done" ) self.layout().addWidget(self._noSliceWarning) # spacer spacer = qt.QWidget(parent=self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer) # set up self.setChecked(True) self.setMode(NabuSliceMode.MIDDLE) self._sliceQLE.setVisible(False) self._noSliceWarning.setVisible(False) # connect signal / slot self._modeCB.currentIndexChanged.connect(self._updateSliceQLEVisibility) self._modeCB.currentIndexChanged.connect(self.sigSlicesChanged) self._sliceQLE.editingFinished.connect(self.sigSlicesChanged) self._sliceQLE.textChanged.connect(self._updateNoSliceWarningVisibility) self.toggled.connect(self.sigSlicesChanged) def _updateSliceQLEVisibility(self, *args, **kwargs): self._sliceQLE.setVisible(self.getMode() == NabuSliceMode.OTHER) self._updateNoSliceWarningVisibility() def _updateNoSliceWarningVisibility(self): def no_other_slice_defined() -> bool: slices_defined = self._sliceQLE.text().replace(" ", "") slices_defined = self._sliceQLE.text().replace(",", "") slices_defined = self._sliceQLE.text().replace(";", "") return slices_defined == "" self._noSliceWarning.setVisible( self.getMode() is NabuSliceMode.OTHER and no_other_slice_defined() ) def setMode(self, mode: NabuSliceMode): mode = NabuSliceMode(mode) item_index = self._modeCB.findText(mode.value) self._modeCB.setCurrentIndex(item_index) old = self.blockSignals(True) self._updateSliceQLEVisibility() self.blockSignals(old) def getMode(self) -> NabuSliceMode: mode = NabuSliceMode(self._modeCB.currentText()) return mode def _getSliceSelected(self): if self.getMode() is NabuSliceMode.MIDDLE: return NabuSliceMode.MIDDLE.value else: return self._sliceQLE.text() def getSlices(self): """Slice selected""" if self.isChecked(): return self._getSliceSelected() else: return None def setSlices(self, slices): if slices is None: self.setChecked(False) else: self.setChecked(True) if slices != NabuSliceMode.MIDDLE.value: self._sliceQLE.setText(slices) self.setMode(NabuSliceMode.OTHER) else: self.setMode(NabuSliceMode.MIDDLE) class TranslationMvtFileWidget(qt.QWidget): """Widget used to define a .cvs or a DataUrl""" class Mode(_Enum): HDF5 = "hdf5" TEXT = "text" fileChanged = qt.Signal() """Signal emitted when the file change""" def __init__(self, parent): qt.QWidget.__init__(self, parent) self.setLayout(qt.QHBoxLayout()) self._checkBox = qt.QCheckBox(self) self.layout().addWidget(self._checkBox) self._translationFileQLE = qt.QLineEdit("", self) self._translationFileQLE.setReadOnly(True) self.layout().addWidget(self._translationFileQLE) self._grpBox = qt.QGroupBox("file type", self) self._grpBox.setLayout(qt.QVBoxLayout()) self._grpBox.layout().setContentsMargins(0, 0, 0, 0) self._grpBox.layout().setSpacing(0) self._hdf5FileRB = qt.QRadioButton( TranslationMvtFileWidget.Mode.HDF5.value, self ) self._grpBox.layout().addWidget(self._hdf5FileRB) self._textFileRB = qt.QRadioButton( TranslationMvtFileWidget.Mode.TEXT.value, self ) self._grpBox.layout().addWidget(self._textFileRB) self.layout().addWidget(self._grpBox) self._selectButton = qt.QPushButton("select", self) self.layout().addWidget(self._selectButton) # set up self._grpBox.setEnabled(False) self._translationFileQLE.setEnabled(False) self._selectButton.setEnabled(False) self._textFileRB.setChecked(True) # connect signal / slot self._selectButton.released.connect(self._selectCallback) self._checkBox.toggled.connect(self._toggleSelection) def _selectCallback(self, *args, **kwargs): if self.getSelectionMode() is self.Mode.HDF5: file_or_url = self._selectHDF5() elif self.getSelectionMode() is self.Mode.TEXT: file_or_url = self._selectTextFile() else: raise ValueError("") if file_or_url is not None: self.setFile(file_or_url) def _selectHDF5(self): dialog = DataFileDialog() dialog.setFilterMode(DataFileDialog.FilterMode.ExistingDataset) if not dialog.exec(): dialog.close() return else: return dialog.selectedUrl() def _selectTextFile(self): # pragma: no cover dialog = qt.QFileDialog(self) dialog.setFileMode(qt.QFileDialog.ExistingFile) if not dialog.exec(): dialog.close() return if len(dialog.selectedFiles()) > 0: return dialog.selectedFiles()[0] def isChecked(self): return self._checkBox.isChecked() def setChecked(self, checked): self._checkBox.setChecked(checked) def getSelectionMode(self): if self._hdf5FileRB.isChecked(): return self.Mode.HDF5 else: return self.Mode.TEXT def setFile(self, file_): if file_ in (None, ""): self.setChecked(False) else: self.setChecked(True) self._translationFileQLE.setText(file_) self.fileChanged.emit() def getFile(self): if self.isChecked(): return self._translationFileQLE.text() else: return None def _toggleSelection(self): self._translationFileQLE.setEnabled(self._checkBox.isChecked()) self._grpBox.setEnabled(self._checkBox.isChecked()) self._selectButton.setEnabled(self._checkBox.isChecked()) class AnglesFileWidget(qt.QWidget): """widget to retrieve the text file for angles to provide to nabu""" def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.setLayout(qt.QHBoxLayout()) self._qle = qt.QLineEdit("", self) self.layout().addWidget(self._qle) self._selectPB = qt.QPushButton("select", self) self.layout().addWidget(self._selectPB) # connect signal / slot self._selectPB.released.connect(self._selectFile) def getFile(self) -> str: return self._qle.text().replace(" ", "") def setFile(self, file_path): self._qle.setText(file_path) def _selectFile(self) -> str: # pragma: no cover dialog = qt.QFileDialog() dialog.setFileMode(qt.QFileDialog.ExistingFile) dialog.setNameFilters( [ "Text file (*.txt)", "Any file (*)", ] ) if not dialog.exec(): dialog.close() return elif len(dialog.selectedFiles()) == 0: return else: file_path = dialog.selectedFiles()[0] self._qle.setText(file_path) class _NabuReconstructionConfig(qt.QWidget, _NabuStageConfigBase): """ Widget to define the configuration of nabu reconstruction processing and dataset configuration. At the gui side the "dataset" section as no real reason to be on its own. So we melt the two there. """ sigConfChanged = qt.Signal(str) """Signal emitted when the configuration change. Parameter is the option modified """ def __init__(self, parent): qt.QWidget.__init__(self, parent, stage=_NabuStages.PRE) _NabuStageConfigBase.__init__(self, stage=_NabuStages.PRE) self.setLayout(qt.QGridLayout()) self.__optimizationIteAlgo = "chambolle-pock" # slices to be reconstructed online self._slicesWidget = SliceGroupBox(parent=self) self.layout().addWidget(self._slicesWidget, 0, 0, 1, 2) # ignore listener of the mouse for the slice widget, can # come with an issue as we are on a scroll area self._slicesWidget.setFocusPolicy(qt.Qt.FocusPolicy.NoFocus) # axis self._axisLabel = qt.QLabel("reconstruction plane", self) self._axisLabel.setToolTip("Over which axis the slice must be picked") self.layout().addWidget(self._axisLabel) self._axisQCB = QComboBoxIgnoreWheel(self) axis_tooltips = { NabuPlane.YZ.value: "along axis x (aka axis 2 - expected to be slow)", NabuPlane.XZ.value: "along axis y (aka axis 1 - expected to be slow)", NabuPlane.XY.value: "along axis Z (aka axis 0 - fastest)", } for item, tooltip in axis_tooltips.items(): self._axisQCB.addItem(item) self._axisQCB.setItemData( self._axisQCB.findText(item), tooltip, qt.Qt.ToolTipRole, ) self.layout().addWidget(self._axisQCB, 1, 1, 1, 1) # method self._methodLabel = qt.QLabel("method", self) self.layout().addWidget(self._methodLabel, 2, 0, 1, 1) self._methodQCB = QComboBoxIgnoreWheel(parent=self) for method in _NabuReconstructionMethods: self._methodQCB.addItem(method.value) self.layout().addWidget(self._methodQCB, 2, 1, 1, 1) self.registerWidget(self._methodLabel, "required") self.registerWidget(self._methodQCB, "required") self._methodWarningLabel = qt.QLabel( f"\tWARNING: \n\t1.' {_NabuReconstructionMethods.MLEM.value}' can be EXTREMELY SLOW on transmission\n\tdata and may produce erroneous results.\n\t2.MLEM should only be used with XRFCT data." ) self._methodWarningLabel.setStyleSheet("color: red") self._methodWarningLabel.setVisible(False) self.layout().addWidget(self._methodWarningLabel, 3, 0, 1, 2) # angle_offset self._labelOffsetLabel = qt.QLabel("angle offset (in degree)", self) self.layout().addWidget(self._labelOffsetLabel, 4, 0, 1, 1) self._angleOffsetQDSB = QDoubleSpinBoxIgnoreWheel(self) self._angleOffsetQDSB.setMaximum(-180) self._angleOffsetQDSB.setMaximum(180) self.layout().addWidget(self._angleOffsetQDSB, 4, 1, 1, 1) self.registerWidget(self._labelOffsetLabel, "advanced") self.registerWidget(self._angleOffsetQDSB, "advanced") # fbp filter type self._fbpFilterCB = qt.QCheckBox("fbp filter", self) self.layout().addWidget(self._fbpFilterCB, 5, 0, 1, 1) self._fbpFilterType = QComboBoxIgnoreWheel(self) for filter_type in _NabuFBPFilterType: self._fbpFilterType.addItem(filter_type.value) self.layout().addWidget(self._fbpFilterType, 5, 1, 1, 1) self.registerWidget(self._fbpFilterCB, "advanced") self.registerWidget(self._fbpFilterType, "advanced") # padding type self._paddingTypeLabel = qt.QLabel("padding type", self) self.layout().addWidget(self._paddingTypeLabel, 6, 0, 1, 1) self._paddingType = QComboBoxIgnoreWheel(self) for fbp_padding_type in _NabuPaddingType: self._paddingType.addItem(fbp_padding_type.value) self.layout().addWidget(self._paddingType, 6, 1, 1, 1) self.registerWidget(self._paddingTypeLabel, "optional") self.registerWidget(self._paddingType, "optional") # sub region self._subRegionSelector = _NabuReconstructionSubRegion(parent=self) self.layout().addWidget(self._subRegionSelector, 8, 0, 1, 2) # iterations self._iterationsLabel = qt.QLabel("iterations", self) self.layout().addWidget(self._iterationsLabel, 9, 0, 1, 1) self._iterationSB = qt.QSpinBox(parent=self) self.layout().addWidget(self._iterationSB, 9, 1, 1, 1) self._iterationSB.setMinimum(1) self._iterationSB.setMaximum(9999) # not supported for now so hidden self._iterationsLabel.hide() self._iterationSB.hide() # binning - subsampling self._binSubSamplingGB = _BinSubSampling( "binning and sub-sampling", parent=self ) self.layout().addWidget(self._binSubSamplingGB, 10, 0, 1, 2) # optimization algorithm: # set has default value for now, because has only one at the moment # weight total variation self._tvLabel = qt.QLabel("total variation weight", self) self.layout().addWidget(self._tvLabel, 11, 0, 1, 1) self._totalVariationWeight = qt.QDoubleSpinBox(self) self._totalVariationWeight.setMinimum(0.0) self._totalVariationWeight.setMaximum(1.0) self._totalVariationWeight.setDecimals(4) self._totalVariationWeight.setSingleStep(0.002) self.layout().addWidget(self._totalVariationWeight, 10, 1, 1, 1) # not supported for now so hidden self._tvLabel.hide() self._totalVariationWeight.hide() # preconditioning filter self._preconditioningFilter = qt.QCheckBox("preconditioning_filter", self) self._preconditioningFilter.setToolTip( 'Whether to enable "filter ' 'preconditioning" for iterative' " methods" ) self.layout().addWidget(self._preconditioningFilter, 11, 0, 1, 2) # not supported for now so hidden self._preconditioningFilter.hide() # positivity constraint self._positivityConstraintCB = qt.QCheckBox("positivity constraint", self) self._positivityConstraintCB.setToolTip( "Whether to enforce a " "positivity constraint in the " "reconstruction." ) self.layout().addWidget(self._positivityConstraintCB, 12, 0, 1, 2) # not supported for now so hidden self._positivityConstraintCB.hide() # clip_outer_circle option self._clipOuterCircleCB = qt.QCheckBox("clip outer circle", self) self._clipOuterCircleCB.setToolTip( "Whether to set to zero voxels falling outside of the reconstruction region" ) self.layout().addWidget(self._clipOuterCircleCB, 13, 0, 1, 2) self.registerWidget(self._clipOuterCircleCB, "optional") # centered axis option self._centeredAxisCB = qt.QCheckBox("centered axis", self) self._centeredAxisCB.setToolTip("") self.layout().addWidget(self._centeredAxisCB, 14, 0, 1, 2) self.registerWidget(self._centeredAxisCB, "optional") # translation movement file self._transMvtFileLabel = qt.QLabel("translation movement file", self) self.layout().addWidget(self._transMvtFileLabel, 22, 0, 1, 1) self._transMvtFileWidget = TranslationMvtFileWidget(self) self.layout().addWidget(self._transMvtFileWidget, 22, 1, 1, 1) self.registerWidget(self._transMvtFileLabel, "advanced") self.registerWidget(self._transMvtFileWidget, "advanced") translation_movement_tooltip = """ A file where each line describes the horizontal and vertical translations of the sample (or detector). The order is 'horizontal, vertical' It can be created from a numpy array saved with 'numpy.savetxt'""" self._transMvtFileLabel.setToolTip(translation_movement_tooltip) self._transMvtFileWidget.setToolTip(translation_movement_tooltip) # angle files (if the user want's to overwrite rotation angles) self._angleFileLabel = qt.QLabel("angles file", self) self.layout().addWidget(self._angleFileLabel, 23, 0, 1, 1) self._anglesFileWidget = AnglesFileWidget(self) self.layout().addWidget(self._anglesFileWidget, 23, 1, 1, 1) self.registerWidget(self._angleFileLabel, "advanced") self.registerWidget(self._anglesFileWidget, "advanced") # exclude projections: [A, B] (if user want's to skip projection from degree A to degree B (included)) self._excludeProjectionsQCB = qt.QCheckBox("exclude proj angles", self) self.layout().addWidget(self._excludeProjectionsQCB, 24, 0, 1, 1) self._excludeProjectionsWidget = RangeWidget(self) self._excludeProjectionsWidget.setRange(0.0, 360.0) self._excludeProjectionsWidget.setSuffix(DEGREE_CHAR) self._excludeProjectionsWidget.setToolTip( "Projections with a rotation in [a, b] range will be ignored." ) self.layout().addWidget(self._excludeProjectionsWidget, 24, 1, 1, 1) self.registerWidget(self._excludeProjectionsQCB, "advanced") self.registerWidget(self._excludeProjectionsWidget, "advanced") # spacer for style spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer, 200, 1, 1, 1) # set up self.setNabuPlane("XY") self._fbpFilterCB.setChecked(True) fbp_item = self._methodQCB.findText(_NabuReconstructionMethods.FBP.value) self._methodQCB.setCurrentIndex(fbp_item) self._angleOffsetQDSB.setValue(0) ramlak_item = self._fbpFilterType.findText(_NabuFBPFilterType.RAMLAK.value) self._fbpFilterType.setCurrentIndex(ramlak_item) padding_type_item = self._paddingType.findText(_NabuPaddingType.ZEROS.value) self._fbpFilterType.setCurrentIndex(padding_type_item) self._iterationSB.setValue(200) self._totalVariationWeight.setValue(1.0e-2) self._preconditioningFilter.setChecked(True) self._positivityConstraintCB.setChecked(True) self._clipOuterCircleCB.setChecked(False) self._centeredAxisCB.setChecked(False) self._excludeProjectionsWidget.setEnabled(False) # connect signal / slot self._axisQCB.currentIndexChanged.connect(self._slicesChanged) self._methodQCB.currentIndexChanged.connect(self._methodChanged) self._angleOffsetQDSB.editingFinished.connect(self._angleOffsetChanged) self._fbpFilterCB.toggled.connect(self._FBPFilterTypeChanged) self._fbpFilterType.currentIndexChanged.connect(self._FBPFilterTypeChanged) self._paddingType.currentTextChanged.connect(self._paddingTypeChanged) self._subRegionSelector.sigConfChanged.connect(self._signalConfChanged) self._iterationSB.valueChanged.connect(self._nbIterationChanged) self._totalVariationWeight.valueChanged.connect(self._weightTvChanged) self._preconditioningFilter.toggled.connect(self._preconditionningFilterChanged) self._positivityConstraintCB.toggled.connect(self._positivityConstraintChanged) self._transMvtFileWidget.fileChanged.connect(self._mvtFileChanged) self._slicesWidget.sigSlicesChanged.connect(self._slicesChanged) self._binSubSamplingGB.binningChanged.connect(self._binningChanged) self._anglesFileWidget._qle.textChanged.connect(self._anglesFilechanged) self._clipOuterCircleCB.toggled.connect(self._clipOuterCircleChanged) self._centeredAxisCB.toggled.connect(self._centeredAxisChanged) self._excludeProjectionsQCB.toggled.connect(self._excludeProjectionsChanged) self._excludeProjectionsQCB.toggled.connect( self._excludeProjectionsWidget.setEnabled ) self._excludeProjectionsWidget.sigChanged.connect( self._excludeProjectionsChanged ) def getSlices(self): return self._slicesWidget.getSlices() def setSlices(self, slices): self._slicesWidget.setSlices(slices=slices) def hideSlicesInterface(self): self._slicesWidget.hide() def setConfigurationLevel(self, level): _NabuStageConfigBase.setConfigurationLevel(self, level) self._subRegionSelector.setConfigurationLevel(level=level) def _slicesChanged(self, *args, **kwargs): self._signalConfChanged("tomwer_slices") def _methodChanged(self, index): # *args, **kwargs): self._signalConfChanged("method") selected_method = self.getMethod() self._methodWarningLabel.setVisible( selected_method == _NabuReconstructionMethods.MLEM ) def _angleOffsetChanged(self, *args, **kwargs): self._signalConfChanged("angle_offset") def _FBPFilterTypeChanged(self, *args, **kwargs): self._signalConfChanged("fbp_filter_type") def _paddingTypeChanged(self, *args, **kwargs): self._signalConfChanged("padding_type") def _nbIterationChanged(self, *args, **kwargs): self._signalConfChanged("iterations") def _weightTvChanged(self, *args, **kwargs): self._signalConfChanged("regularization_weight") def _preconditionningFilterChanged(self, *args, **kwargs): self._signalConfChanged("preconditioning_filter") def _positivityConstraintChanged(self, *args, **kwargs): self._signalConfChanged("positivity_constraint") def _mvtFileChanged(self, *args, **kwargs): self._signalConfChanged("translation_movements_file") def _clipOuterCircleChanged(self, *args, **kwargs): self._signalConfChanged("clip_outer_circle") def _centeredAxisChanged(self, *args, **kwargs): self._signalConfChanged("centered_axis") def _binningChanged(self, *args, **kwargs): self._signalConfChanged("binning") self._signalConfChanged("binning_z") def _anglesFilechanged(self, *args, **kwargs): self._signalConfChanged("angles_file") def _excludeProjectionsChanged(self): self._signalConfChanged("exclude_projections") def setScan(self, scan): raise NotImplementedError() def getMethod(self) -> _NabuReconstructionMethods: return _NabuReconstructionMethods(self._methodQCB.currentText()) def setMethod(self, method): method = _NabuReconstructionMethods(method) item_index = self._methodQCB.findText(method.value) self._methodQCB.setCurrentIndex(item_index) def getAngleOffset(self) -> float: return self._angleOffsetQDSB.value() def setAngleOffset(self, value: str | float): self._angleOffsetQDSB.setValue(float(value)) def getFBPFilterType(self) -> _NabuFBPFilterType | None: if self._fbpFilterCB.isChecked(): return _NabuFBPFilterType(self._fbpFilterType.currentText()) else: return None def setFBPFilterType(self, filter_type): if type(filter_type) is str and filter_type.lower() == "none": filter_type = None if filter_type is None: self._fbpFilterCB.setChecked(False) else: self._fbpFilterCB.setChecked(True) filter_type = _NabuFBPFilterType(filter_type) filter_index = self._fbpFilterType.findText(filter_type.value) self._fbpFilterType.setCurrentIndex(filter_index) def getFBPPaddingType(self) -> _NabuPaddingType: return _NabuPaddingType(self._paddingType.currentText()) def setFBPPaddingType(self, padding): padding = _NabuPaddingType(padding) padding_index = self._paddingType.findText(padding.value) self._paddingType.setCurrentIndex(padding_index) def getNIterations(self): return self._iterationSB.value() def setNIterations(self, n_iterations): self._iterationSB.setValue(n_iterations) def getTotalVariationWeight(self) -> float: return self._totalVariationWeight.value() def setTotalVariationWeight(self, weight: float): self._totalVariationWeight.setValue(float(weight)) def isPreconditioningFilterEnable(self): return self._preconditioningFilter.isChecked() def setPreconditioningFilterEnable(self, enable: bool | int): self._preconditioningFilter.setChecked(bool(enable)) def isPositivityConstraintEnable(self): return self._positivityConstraintCB.isChecked() def setPositivityConstraintEnable(self, enable: bool | int): self._positivityConstraintCB.setChecked(bool(enable)) def getTranslationMvtFile(self): return self._transMvtFileWidget.getFile() def setTranslationMvtFile(self, file_): self._transMvtFileWidget.setFile(file_) def getHorizontalBinning(self): return self._binSubSamplingGB.getHorizontalBinning() def setHorizontalBinning(self, binning): return self._binSubSamplingGB.setHorizontalBinning(binning=binning) def getVerticalBinning(self): return self._binSubSamplingGB.getVerticalBinning() def setVerticalBinning(self, binning): return self._binSubSamplingGB.setVerticalBinning(binning=binning) def getProjSubsampling(self): return self._binSubSamplingGB.getProjSubsampling() def setProjSubsampling(self, subsampling): return self._binSubSamplingGB.setProjSubsampling(subsampling=subsampling) def getAnglesFile(self) -> str: return self._anglesFileWidget.getFile() def setAnglesFile(self, angles_file: str): return self._anglesFileWidget.setFile(angles_file) def getClipOuterCircle(self) -> bool: return self._clipOuterCircleCB.isChecked() def setClipOuterCircle(self, checked: bool) -> None: self._clipOuterCircleCB.setChecked(checked) def getCenteredAxis(self) -> bool: return self._centeredAxisCB.isChecked() def setCenteredAxis(self, checked: bool): self._centeredAxisCB.setChecked(checked) def getNabuPlane(self) -> NabuPlane: """return over which axis we expect to do the reconstruction""" return NabuPlane.from_value(self._axisQCB.currentText()) def setNabuPlane(self, axis: str | NabuPlane): axis = NabuPlane.from_value(axis) self._axisQCB.setCurrentText(axis.value) def getExcludeProjections(self) -> tuple: if self._excludeProjectionsQCB.isChecked(): return self._excludeProjectionsWidget.getRange() else: return tuple() def setExcludeProjections(self, projections: tuple): if not isinstance(projections, tuple): raise TypeError( f"projections should be an instance of tuple. Got {type(projections)}" ) if len(projections) == 0: self._excludeProjectionsQCB.setChecked(False) else: self._excludeProjectionsQCB.setChecked(True) self._excludeProjectionsWidget.setRange(*projections) @docstring(_NabuStageConfigBase) def getConfiguration(self) -> dict: fbp_filter_type = self.getFBPFilterType() if fbp_filter_type is None: fbp_filter_type = "none" else: fbp_filter_type = fbp_filter_type.value config = { "method": self.getMethod().value, "slice_plane": self.getNabuPlane().value, "angles_file": self.getAnglesFile(), "axis_correction_file": "", # not managed for now "angle_offset": self.getAngleOffset(), "fbp_filter_type": fbp_filter_type, "padding_type": self.getFBPPaddingType().value, "iterations": self.getNIterations(), "optim_algorithm": self.__optimizationIteAlgo, "regularization_weight": self.getTotalVariationWeight(), "preconditioning_filter": int(self.isPreconditioningFilterEnable()), "positivity_constraint": int(self.isPositivityConstraintEnable()), "rotation_axis_position": "", "translation_movements_file": self.getTranslationMvtFile() or "", "clip_outer_circle": int(self.getClipOuterCircle()), "centered_axis": int(self.getCenteredAxis()), } config.update(self._subRegionSelector.getConfiguration()) return config def getDatasetConfiguration(self) -> dict: exclude_projections = self.getExcludeProjections() if len(exclude_projections) == 0: exclude_projections = "" else: exclude_projections = f"angular_range={str(list(exclude_projections))}" config = self._binSubSamplingGB.getConfiguration() config["exclude_projections"] = exclude_projections return config def setDatasetConfiguration(self, config): exclude_proj = config.pop("exclude_projections", None) if exclude_proj is not None: if isinstance(exclude_proj, str): exclude_proj = exclude_proj.replace("angular_range=", "") exclude_proj = convert_str_to_tuple(exclude_proj) self.setExcludeProjections(exclude_proj) return self._binSubSamplingGB.setConfiguration(config) @docstring(_NabuStageConfigBase) def setConfiguration(self, config): if "method" in config: self.setMethod(config["method"]) if "angles_file" in config: self.setAnglesFile(config["angles_file"]) if "angle_offset" in config: self.setAngleOffset(value=config["angle_offset"]) if "fbp_filter_type" in config: self.setFBPFilterType(config["fbp_filter_type"]) if "padding_type" in config: self.setFBPPaddingType(config["padding_type"]) if "iterations" in config: self.setNIterations(int(config["iterations"])) if "optim_algorithm" in config: self.__optimizationIteAlgo = config["optim_algorithm"] if "regularization_weight" in config: self.setTotalVariationWeight(weight=config["regularization_weight"]) if "preconditioning_filter" in config: self.setPreconditioningFilterEnable(int(config["preconditioning_filter"])) if "positivity_constraint" in config: self.setPositivityConstraintEnable(int(config["positivity_constraint"])) if "translation_movements_file" in config: self.setTranslationMvtFile(config["translation_movements_file"]) if "clip_outer_circle" in config: self.setClipOuterCircle(bool(config["clip_outer_circle"])) if "centered_axis" in config: self.setCenteredAxis(bool(config["centered_axis"])) if "slice_plane" in config: self.setNabuPlane(config["slice_plane"]) self._subRegionSelector.setConfiguration(config=config) def _signalConfChanged(self, param): self.sigConfChanged.emit(param) class _SubRegionEditor(qt.QObject): sigConfChanged = qt.Signal(str) """Signal emitted each type a parameter is edited""" def __init__( self, parent, layout, layout_row: int, name: str, min_param: str, max_param: str ): assert type(layout_row) is int qt.QObject.__init__(self) self._layout = layout self.__minParam = min_param self.__maxParam = max_param validator = qt.QIntValidator() validator.setBottom(0) self._subRegionLabel = qt.QLabel(name, parent) self.layout().addWidget(self._subRegionLabel, layout_row, 0, 1, 1) # min self._minCB = qt.QCheckBox("min", parent) self.layout().addWidget(self._minCB, layout_row, 1, 1, 1) self._minQLE = qt.QLineEdit("0", parent) self._minQLE.setValidator(validator) self.layout().addWidget(self._minQLE, layout_row, 2, 1, 1) # max self._maxCB = qt.QCheckBox("max", parent) self.layout().addWidget(self._maxCB, layout_row, 3, 1, 1) self._maxQLE = qt.QLineEdit("0", parent) self._maxQLE.setValidator(validator) self.layout().addWidget(self._maxQLE, layout_row, 4, 1, 1) # spacer for style self._spacer = qt.QWidget(parent) self._spacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) self.layout().addWidget(self._spacer, layout_row, 5, 1, 1) # set up self._minCB.setChecked(False) self._minQLE.setEnabled(False) self._maxCB.setChecked(False) self._maxQLE.setEnabled(False) # connect signal / slot self._minCB.toggled.connect(self._minQLE.setEnabled) self._maxCB.toggled.connect(self._maxQLE.setEnabled) self._minCB.toggled.connect( functools.partial(self._signalConfChanged, self.__minParam) ) self._maxCB.toggled.connect( functools.partial(self._signalConfChanged, self.__maxParam) ) self._minQLE.editingFinished.connect( functools.partial(self._signalConfChanged, self.__minParam) ) self._maxQLE.editingFinished.connect( functools.partial(self._signalConfChanged, self.__maxParam) ) def layout(self): return self._layout def getSubRegionMin(self) -> int | None: """ :return: None if region is unbounded else the value of the bound """ if self._minCB.isChecked(): return int(self._minQLE.text()) else: return None def getSubRegionMax(self) -> int | None: """ :return: None if region is unbounded else the value of the bound """ if self._maxCB.isChecked(): return int(self._maxQLE.text()) else: return None def setSubRegionMin(self, sub_region_min: int | None) -> None: """ :param min: if min is None or -1 wr will expand it to - infinity """ if sub_region_min in (-1, 0): sub_region_min = None if sub_region_min is None: self._minCB.setChecked(False) else: self._minCB.setChecked(True) self._minQLE.setText(str(sub_region_min)) def setSubRegionMax(self, sub_region_max) -> None: """ :param max: if max is None or -1 wr will expand it to infinity """ if type(sub_region_max) is str: sub_region_max = int(sub_region_max) if sub_region_max == -1: sub_region_max = None if sub_region_max is None: self._maxCB.setChecked(False) else: self._maxCB.setChecked(True) self._maxQLE.setText(str(sub_region_max)) def getSubRegion(self) -> tuple: """ :return: min, max """ return self.getSubRegionMin(), self.getSubRegionMax() def setSubRegion( self, sub_region_min: int | None, sub_region_max: int | None, ): self.setSubRegionMin(sub_region_min) self.setSubRegionMax(sub_region_max) def _signalConfChanged(self, param): self.sigConfChanged.emit(param) def setVisible(self, visible): for widget in ( self._subRegionLabel, self._minCB, self._minQLE, self._maxCB, self._maxQLE, self._spacer, ): widget.setVisible(visible) class _NabuReconstructionSubRegion(qt.QGroupBox, _NabuStageConfigBase): """Widget to select a sub region to reconstruct""" sigConfChanged = qt.Signal(str) """Signal emitted each type a parameter is edited""" def __init__(self, parent): qt.QGroupBox.__init__(self, parent, stage=_NabuStages.PROC) _NabuStageConfigBase.__init__(self, stage=_NabuStages.PROC) self.setTitle("sub region") self.setLayout(qt.QGridLayout()) self._xSubRegion = _SubRegionEditor( parent=self, layout=self.layout(), layout_row=0, name="x", min_param="start_x", max_param="end_x", ) self.registerWidget(self._xSubRegion, "optional") self._ySubRegion = _SubRegionEditor( parent=self, layout=self.layout(), layout_row=1, name="y", min_param="start_y", max_param="end_y", ) self.registerWidget(self._ySubRegion, "optional") self._zSubRegion = _SubRegionEditor( parent=self, layout=self.layout(), layout_row=2, name="z", min_param="start_z", max_param="end_z", ) self.registerWidget(self._zSubRegion, "optional") # set up # connect signal / slot self._xSubRegion.sigConfChanged.connect(self._signalConfChanged) self._ySubRegion.sigConfChanged.connect(self._signalConfChanged) self._zSubRegion.sigConfChanged.connect(self._signalConfChanged) def getConfiguration(self) -> dict: return { "start_x": self._xSubRegion.getSubRegionMin() or 0, "end_x": self._xSubRegion.getSubRegionMax() or -1, "start_y": self._ySubRegion.getSubRegionMin() or 0, "end_y": self._ySubRegion.getSubRegionMax() or -1, "start_z": self._zSubRegion.getSubRegionMin() or 0, "end_z": self._zSubRegion.getSubRegionMax() or -1, } def setConfiguration(self, config): if "start_x" in config: self._xSubRegion.setSubRegionMin(int(config["start_x"])) if "end_x" in config: self._xSubRegion.setSubRegionMax(int(config["end_x"])) if "start_y" in config: self._ySubRegion.setSubRegionMin(int(config["start_y"])) if "end_y" in config: self._ySubRegion.setSubRegionMax(int(config["end_y"])) if "start_z" in config: self._zSubRegion.setSubRegionMin(int(config["start_z"])) if "end_z" in config: self._zSubRegion.setSubRegionMax(int(config["end_z"])) def _signalConfChanged(self, param): self.sigConfChanged.emit(param) class _BinSubSampling(qt.QGroupBox): binningChanged = qt.Signal() """signal emitted when binning change""" def __init__(self, text, parent): qt.QGroupBox.__init__(self, text) self.setLayout(qt.QFormLayout()) # binning self._binningSB = QSpinBoxIgnoreWheel(self) self._binningSB.setMinimum(1) self._binningSB.setMaximum(3) self.layout().addRow("binning", self._binningSB) self._binningSB.setToolTip( "Binning factor in the horizontal dimension when reading the data. \nThe final slices dimensions will be divided by this factor." ) # z binning self._zBinningSB = QSpinBoxIgnoreWheel(self) self._zBinningSB.setMinimum(1) self._zBinningSB.setMaximum(100) self.layout().addRow("vertical binning", self._zBinningSB) self._zBinningSB.setToolTip( "Binning factor in the vertical dimension when reading the data. \nThis results in a lesser number of reconstructed slices." ) # projection sub-sampling self._projSubsamplingSB = QSpinBoxIgnoreWheel(self) self._projSubsamplingSB.setMinimum(1) self._projSubsamplingSB.setMaximum(100) self.layout().addRow("projection sub-sampling", self._projSubsamplingSB) # connect signal / slot self._zBinningSB.valueChanged.connect(self._valueUpdated) self._binningSB.valueChanged.connect(self._valueUpdated) def getHorizontalBinning(self) -> int: return self._binningSB.value() def setHorizontalBinning(self, binning: int): return self._binningSB.setValue(int(binning)) def getVerticalBinning(self) -> int: return self._zBinningSB.value() def setVerticalBinning(self, binning: int): return self._zBinningSB.setValue(int(binning)) def getProjSubsampling(self) -> int: return self._projSubsamplingSB.value() def setProjSubsampling(self, subsampling: int): return self._projSubsamplingSB.setValue(int(subsampling)) def getConfiguration(self) -> dict: return { "binning": self.getHorizontalBinning(), "binning_z": self.getVerticalBinning(), "projections_subsampling": self.getProjSubsampling(), } def setConfiguration(self, config: dict): if "binning" in config: self.setHorizontalBinning(config["binning"]) if "binning_z" in config: self.setVerticalBinning(config["binning_z"]) if "projections_subsampling" in config: self.setProjSubsampling(subsampling=config["projections_subsampling"]) def _valueUpdated(self, *args, **kwargs): self.binningChanged.emit() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9411016 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/nabuconfig/tests/0000755000175000017500000000000015153325403024375 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/nabuconfig/tests/__init__.py0000644000175000017500000000000015115744275026506 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/nabuconfig/tests/test_NabuConfiguration.py0000644000175000017500000000342315153325210031421 0ustar00paynopaynofrom __future__ import annotations from tomwer.tests.conftest import qtapp # noqa F401 from tomwer.gui.reconstruction.nabu.nabuconfig.nabuconfig import ( NabuConfiguration, ) from nabu.pipeline.config import _extract_nabuconfig_keyvals from nabu.pipeline.fullfield.nabu_config import ( nabu_config as nabu_fullfield_default_config, ) def test_NabuConfiguration( qtapp, # noqa F811 ): """Test that the 'NabuConfiguration' produce only keys understandable by nabu""" widget = NabuConfiguration(parent=None) tomwer_config = widget.getConfiguration() nabu_config = _extract_nabuconfig_keyvals(nabu_fullfield_default_config) tomwer_section_keys = set(tomwer_config.keys()) nabu_section_keys = set(nabu_config.keys()) tomwer_section_keys.remove("tomwer_slices") assert tomwer_section_keys.issubset( nabu_section_keys ), f"tomwer provide sections undefined by nabu: {tomwer_section_keys - nabu_section_keys}" for section_key in nabu_config.keys(): if section_key in tomwer_config: nabu_sub_section_keys = set(nabu_config[section_key].keys()) tomwer_sub_section_keys = set(tomwer_config[section_key].keys()) if section_key == "phase": # this key is pop by tomwer before calling nabu. It is used internally only tomwer_sub_section_keys.remove("beam_shape") elif section_key == "reconstruction": tomwer_sub_section_keys.remove("slice_plane") elif section_key == "output": tomwer_sub_section_keys.remove("output_dir_mode") assert tomwer_sub_section_keys.issubset( nabu_sub_section_keys ), f"tomwer provides keys undefined by nabu: {tomwer_sub_section_keys - nabu_sub_section_keys}" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/nabuflow.py0000644000175000017500000003520115153325210023304 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import functools from typing import Iterable from silx.gui import qt from tomwer.core.process.reconstruction.nabu.utils import _NabuStages from tomwer.gui import icons from tomwer.utils import docstring from ...utils.flow import FlowCanvas, FlowDirection class NabuFlowControl(qt.QWidget): """ Widget which is composed of three `FlowCanvas`: one for pre processing (where dockers are not movable), one for processing (where dockers are movable) and one for post-processing (where dockers are not movable) """ sigConfigurationChanged = qt.Signal(tuple) """signal emitted when the `focus` process on the flow is changed. tuple is (stage, option) """ sigResetConfiguration = qt.Signal() """Signal emitted when the configuration should be reset""" def __init__(self, parent, direction): qt.QWidget.__init__(self, parent=parent) self._direction = FlowDirection(direction) if self._direction is FlowDirection.VERTICAL: self.setLayout(qt.QVBoxLayout()) else: self.setLayout(qt.QHBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.layout().setSpacing(0) # initialization self._iniProcessWidgets = FlowCanvas( direction=direction, parent=self, show_lock_state=False ) # preprocessing flow self._preProcessWidgets = FlowCanvas( direction=direction, parent=self, show_lock_state=False ) # phase processing flow self._phaseProcessWidgets = FlowCanvas( direction=direction, parent=self, show_lock_state=False ) # processing flow self._processWidgets = FlowCanvas( direction=direction, parent=self, show_lock_state=False ) # postprocessing flow self._postProcessWidgets = FlowCanvas( direction=direction, parent=self, show_lock_state=False ) for widget in ( self._iniProcessWidgets, self._preProcessWidgets, self._phaseProcessWidgets, self._processWidgets, self._postProcessWidgets, ): self.layout().addWidget(widget) spacer = qt.QWidget(parent=self) spacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer) # connect signal / slot self._iniProcessWidgets.sigWidgetActivated.connect( functools.partial(self._updateActiveProcess, _NabuStages.INI) ) self._iniProcessWidgets.sigWidgetDeactivated.connect(self.sigResetConfiguration) self._preProcessWidgets.sigWidgetActivated.connect( functools.partial(self._updateActiveProcess, _NabuStages.PRE) ) self._preProcessWidgets.sigWidgetDeactivated.connect(self.sigResetConfiguration) self._phaseProcessWidgets.sigWidgetActivated.connect( functools.partial(self._updateActiveProcess, _NabuStages.PHASE) ) self._phaseProcessWidgets.sigWidgetDeactivated.connect( self.sigResetConfiguration ) self._processWidgets.sigWidgetActivated.connect( functools.partial(self._updateActiveProcess, _NabuStages.PROC) ) self._processWidgets.sigWidgetDeactivated.connect(self.sigResetConfiguration) self._postProcessWidgets.sigWidgetActivated.connect( functools.partial(self._updateActiveProcess, _NabuStages.POST) ) self._postProcessWidgets.sigWidgetDeactivated.connect( self.sigResetConfiguration ) # set up self.setIniprocVisible(False) self.setPreProcVisible(True) self.setPhaseVisible(True) self.setProcVisible(True) self.setPostVisible(True) def _updateActiveProcess(self, stage): stage = _NabuStages(stage) if stage is _NabuStages.INI: activeWidget = self._iniProcessWidgets elif stage is _NabuStages.PRE: activeWidget = self._preProcessWidgets elif stage is _NabuStages.PHASE: activeWidget = self._phaseProcessWidgets elif stage is _NabuStages.PROC: activeWidget = self._processWidgets elif stage is _NabuStages.POST: activeWidget = self._postProcessWidgets else: raise ValueError("nabu stage not recognized") for widget in ( self._iniProcessWidgets, self._preProcessWidgets, self._phaseProcessWidgets, self._processWidgets, self._postProcessWidgets, ): if widget != activeWidget: widget.clearActiveProcess() self.sigConfigurationChanged.emit(self.getProcessFocused()) def setIniprocVisible(self, visible): """ change visibility of the widgets relative to initialization process :param visible: """ self._iniProcessWidgets.setVisible(visible) def setPreProcVisible(self, visible): """ change visibility of the widgets relative to pre processing process :param visible: """ self._preProcessWidgets.setVisible(visible) def setPhaseVisible(self, visible: bool): """ change visibility of the widgets relative to pre processing process """ self._phaseProcessWidgets.setVisible(visible) def setProcVisible(self, visible: bool): """ change visibility of the widgets relative to processing process """ self._processWidgets.setVisible(visible) def setPostVisible(self, visible: bool): """ change visibility of the widgets relative to post processing process """ self._postProcessWidgets.setVisible(visible) def setIniProcessing(self, processes: Iterable, icons: Iterable): """ Defines the processing to execute for initialization :param processes: processes to display :param icons: icons associated to the processes if any """ draggability = [False] * len(processes) self._iniProcessWidgets.setProcesses( processes=processes, icons=icons, draggability=draggability ) self.setIniprocVisible(len(processes) != 0) def setPreProcessing(self, processes: Iterable, icons: Iterable): """ :param processes: processes to display :param icons: icons associated to the processes if any """ draggability = [False] * len(processes) self._preProcessWidgets.setProcesses( processes=processes, icons=icons, draggability=draggability ) self.setPreProcVisible(len(processes) != 0) def setPhaseProcessing(self, processes: Iterable, icons: Iterable): """ :param processes: processes to display :param icons: icons associated to the processes if any """ draggability = [False] * len(processes) self._phaseProcessWidgets.setProcesses( processes=processes, icons=icons, draggability=draggability ) self.setPhaseVisible(len(processes) != 0) def setProcessing(self, processes: Iterable, icons: Iterable): """ :param processes: processes to display :param icons: icons associated to the processes if any """ draggability = [False] * len(processes) self._processWidgets.setProcesses( processes=processes, icons=icons, draggability=draggability ) self.setProcVisible(len(processes) != 0) def setPostProcessing(self, processes: Iterable, icons: Iterable): """ :param processes: processes to display :param icons: icons associated to the processes if any """ draggability = [False] * len(processes) self._postProcessWidgets.setProcesses( processes=processes, icons=icons, draggability=draggability ) self.setPostVisible(len(processes) != 0) def getIniProcessingFlow(self) -> list: """ :return: list of initialization processes """ return self._iniProcessWidgets.getFlow() def getPreProcessingFlow(self): """ :return: list of preprocessing """ return self._preProcessWidgets.getFlow() def getProcessingFlow(self): """ :return: list of processing """ return self._processWidgets.getFlow() def getPostProcessingFlow(self): """ :return: list of postprocessing """ return self._postProcessWidgets.getFlow() def getFlow(self) -> dict: """ Returns the concatenation of pre-processing, processing, and post-processing flows. :return: Dictionary where the keys are Nabu stages, and the values are lists of flows for each stage. :rtype: dict This method fetches the processing flows for all stages and returns them as a dictionary, allowing easy access to the current configuration. """ return { _NabuStages.INI: self._iniProcessWidget.getFlow(), _NabuStages.PRE: self._preProcessWidgets.getFlow(), _NabuStages.PHASE: self._phaseProcessWidget.getFlow(), _NabuStages.PROC: self._processWidgets.getFlow(), _NabuStages.POST: self._processWidgets.getFlow(), } def getProcessFocused(self) -> tuple: """ :return: the process under focus """ stages = ( _NabuStages.INI, _NabuStages.PRE, _NabuStages.PHASE, _NabuStages.PROC, _NabuStages.POST, ) widgets = ( self._iniProcessWidgets, self._preProcessWidgets, self._phaseProcessWidgets, self._processWidgets, self._postProcessWidgets, ) for stage, widget in zip(stages, widgets): process_id = widget.getProcessFocused() if process_id is not None: return stage, process_id return None, None def _removeActiveProcess(self): for widget in ( self._iniProcessWidgets, self._preProcessWidgets, self._phaseProcessWidgets, self._processWidgets, self._postProcessWidgets, ): if widget.hasProcessFocus(): widget._removeActiveProcess() self.sigConfigurationChanged.emit((None, None)) class NabuFlowArea(qt.QWidget): """Define the flow dedicated to nabu""" sigConfigurationChanged = qt.Signal(tuple) """signal emitted when the `focus` process on the flow is changed. tuple is (stage, option)""" sigResetConfiguration = qt.Signal() """Signal emitted when the configuration should be reset""" def __init__(self, parent, direction): qt.QWidget.__init__(self, parent=parent) direction = FlowDirection(direction) if direction is FlowDirection.VERTICAL: self.setLayout(qt.QHBoxLayout(self)) else: self.setLayout(qt.QVBoxLayout(self)) self._control = NabuFlowControl(parent=self, direction=direction) self._control.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum) self._addRmWidget = _AddRemoveProcessWidget(parent=self, direction=direction) self._addRmWidget.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum) self._control.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum) if direction is FlowDirection.VERTICAL: # if vertical illustration left sided self.layout().addWidget(self._control) self.layout().addWidget(self._addRmWidget) else: # if horizontal illustration bottom sided self.layout().addWidget(self._control) self.layout().addWidget(self._addRmWidget) # set up # for now hide the add and remove option self._addRmWidget.setVisible(False) # connect signal / slot self._addRmWidget.sigRmProcess.connect(self._control._removeActiveProcess) self._control.sigConfigurationChanged.connect(self.sigConfigurationChanged) self._control.sigResetConfiguration.connect(self.sigResetConfiguration) @docstring(NabuFlowControl) def setIniProcessing(self, processes, icons): return self._control.setIniProcessing(processes=processes, icons=icons) @docstring(NabuFlowControl) def setPreProcessing(self, processes, icons): return self._control.setPreProcessing(processes=processes, icons=icons) @docstring(NabuFlowControl) def setPhaseProcessing(self, processes, icons): return self._control.setPhaseProcessing(processes=processes, icons=icons) @docstring(NabuFlowControl) def setProcessing(self, processes, icons): return self._control.setProcessing(processes=processes, icons=icons) @docstring(NabuFlowControl) def setPostProcessing(self, processes, icons): return self._control.setPostProcessing(processes=processes, icons=icons) @docstring(NabuFlowControl) def getFlow(self): return self._control.getFlow() @docstring(NabuFlowControl) def getProcessFocused(self): return self._control.getProcessFocused() class _AddRemoveProcessWidget(qt.QWidget): sigAddProcess = qt.Signal() """Signal emitted when the user request a process to be added""" sigRmProcess = qt.Signal() """Signal emitted when the user request a process to be removed""" def __init__(self, parent, direction): qt.QWidget.__init__(self, parent=parent) if direction is FlowDirection.VERTICAL: self.setLayout(qt.QVBoxLayout()) spacer_size_policy = (qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) else: self.setLayout(qt.QHBoxLayout()) spacer_size_policy = (qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) add_icon = icons.getQIcon("add") rm_icon = icons.getQIcon("rm") self._addButton = qt.QPushButton(add_icon, "", self) self._addButton.setToolTip("add process") self._rmButton = qt.QPushButton(rm_icon, "", self) self._rmButton.setToolTip("remove process") spacer = qt.QWidget(parent=self) spacer.setSizePolicy(*spacer_size_policy) self.layout().addWidget(spacer) self.layout().addWidget(self._addButton) self.layout().addWidget(self._rmButton) # connect signal / slot self._addButton.pressed.connect(self._addProcess) self._rmButton.pressed.connect(self.sigRmProcess) def _addProcess(self): # should be able to add a process from ini, post, processing and pre raise NotImplementedError(" not implemented, to be defined") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/platform.py0000644000175000017500000000742315153325210023320 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from tomwer.gui.reconstruction.nabu.nabuconfig.base import _NabuStageConfigBase from tomwer.gui.utils.gpu import SelectGPUGroupBox class NabuPlatformSettings(qt.QWidget, _NabuStageConfigBase): """define settings to be used for the local reconstruction like gpu...""" sigConfigChanged = qt.Signal() DEFAULT_GPU_FRACTION = 90 DEFAULT_CPU_FRACTION = 90 def __init__(self, parent: qt.QWidget | None = None) -> None: qt.QWidget.__init__(self, parent, stage=None) _NabuStageConfigBase.__init__(self, stage=None) self.setLayout(qt.QFormLayout()) self._gpuSelWidget = SelectGPUGroupBox() self._gpuSelWidget.setChecked(False) # keep default behavior: don't set any default gpu self.layout().addRow(self._gpuSelWidget) # gpu percentage self._GPUFractionLabel = qt.QLabel("GPU percentage usage", self) self.registerWidget(self._GPUFractionLabel, "advanced") self._GPUFractionSB = qt.QSpinBox(self) self._GPUFractionSB.setSingleStep(10) self._GPUFractionSB.setSuffix("%") self._GPUFractionSB.setMinimum(1) self._GPUFractionSB.setMaximum(100) self._GPUFractionSB.setToolTip("Which fraction of GPU memory to use.") self.registerWidget(self._GPUFractionSB, "advanced") self.layout().addRow(self._GPUFractionLabel, self._GPUFractionSB) # cpu percentage self._CPUFractionLabel = qt.QLabel("CPU percentage usage", self) self.registerWidget(self._CPUFractionLabel, "advanced") self._CPUFractionSB = qt.QSpinBox(self) self._CPUFractionSB.setSingleStep(10) self._CPUFractionSB.setSuffix("%") self._CPUFractionSB.setMinimum(1) self._CPUFractionSB.setMaximum(100) self._CPUFractionSB.setToolTip("Which fraction of CPU memory to use.") self.registerWidget(self._CPUFractionSB, "advanced") self.layout().addRow(self._CPUFractionLabel, self._CPUFractionSB) # set up self._GPUFractionSB.setValue(NabuPlatformSettings.DEFAULT_GPU_FRACTION) self._CPUFractionSB.setValue(NabuPlatformSettings.DEFAULT_CPU_FRACTION) # connect signal / slot self._gpuSelWidget.sigGPUChanged.connect(self.sigConfigChanged) self._GPUFractionSB.valueChanged.connect(self._triggerSigConfChanged) self._CPUFractionSB.valueChanged.connect(self._triggerSigConfChanged) def getCPUFraction(self) -> float: return self._CPUFractionSB.value() / 100.0 def setCPUFraction(self, value: float): return self._CPUFractionSB.setValue(int(value * 100.0)) def getGPUFraction(self) -> float: return self._GPUFractionSB.value() / 100.0 def setGPUFraction(self, value: float): return self._GPUFractionSB.setValue(int(value * 100.0)) def _triggerSigConfChanged(self, *args, **kwargs) -> None: self.sigConfigChanged.emit() def getConfiguration(self) -> dict: config = { "gpu_mem_fraction": self.getGPUFraction(), "cpu_mem_fraction": self.getCPUFraction(), } selected_gpu_id = self._gpuSelWidget.getSelectedGPUId() if selected_gpu_id is not None: config["resources"] = { "gpu_id": selected_gpu_id, } return config def setConfiguration(self, config: dict) -> None: gpu_id = config.get("resources", {}).get("gpu_id", None) if gpu_id not in (None, ""): self._gpuSelWidget.setSelectedGPUId(value=gpu_id) self._gpuSelWidget.setChecked(True) if "gpu_mem_fraction" in config: self.setGPUFraction(config["gpu_mem_fraction"]) if "cpu_mem_fraction" in config: self.setCPUFraction(config["cpu_mem_fraction"]) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/slices.py0000644000175000017500000005733215153325210022762 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging from nabu.pipeline.config import get_default_nabu_config from nabu.pipeline.fullfield.nabu_config import ( nabu_config as nabu_fullfield_default_config, ) from silx.gui import icons as silx_icons from silx.gui import qt from enum import Enum as _Enum from nxtomo.nxobject.nxdetector import FOV from tomwer.core.utils.dictutils import concatenate_dict from tomwer.core.process.reconstruction.nabu.utils import _NabuMode from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui import icons as tomwer_icons from tomwer.gui.reconstruction.nabu.nabuflow import NabuFlowArea from tomwer.gui.reconstruction.nabu.platform import NabuPlatformSettings from tomwer.gui.utils.buttons import PadlockButton from tomwer.gui.settings import TAB_LABEL_PLATFORM_SETTINGS from ...utils.flow import FlowDirection from tomwer.gui.configuration.action import ( BasicConfigurationAction, ExpertConfigurationAction, FilterAction, MinimalisticConfigurationAction, ) from tomwer.gui.configuration.level import ConfigurationLevel from .nabuconfig import NabuConfiguration _logger = logging.getLogger(__name__) class _NabuStages(_Enum): INI = "initialization" PRE = "pre-processing" PHASE = "phase" PROC = "processing" POST = "post-processing" VOLUME = "volume" @staticmethod def getStagesOrder(): return ( _NabuStages.INI, _NabuStages.PRE, _NabuStages.PHASE, _NabuStages.PROC, _NabuStages.POST, ) @staticmethod def getProcessEnum(stage): """Return the process Enum associated to the stage""" stage = _NabuStages(stage) if stage is _NabuStages.INI: raise NotImplementedError() elif stage is _NabuStages.PRE: return _NabuPreprocessing elif stage is _NabuStages.PHASE: return _NabuPhase elif stage is _NabuStages.PROC: return _NabuProcessing elif stage is _NabuStages.POST: raise NotImplementedError() raise NotImplementedError() class _NabuPreprocessing(_Enum): """Define all the preprocessing action possible and the order they are applied on""" FLAT_FIELD_NORMALIZATION = "flat field normalization" CCD_FILTER = "hot spot correction" @staticmethod def getPreProcessOrder(): return ( _NabuPreprocessing.FLAT_FIELD_NORMALIZATION, _NabuPreprocessing.CCD_FILTER, ) class _NabuPhase(_Enum): """Define all the phase action possible and the order they are applied on""" PHASE = "phase retrieval" UNSHARP_MASK = "unsharp mask" LOGARITHM = "logarithm" @staticmethod def getPreProcessOrder(): return (_NabuPhase.PHASE, _NabuPhase.UNSHARP_MASK, _NabuPhase.LOGARITHM) class _NabuProcessing(_Enum): """Define all the processing action possible""" RECONSTRUCTION = 0 @staticmethod def getProcessOrder(): return _NabuProcessing.RECONSTRUCTION class _NabuProcess(qt.QWidget): def __init__(self, parent): qt.QWidget.__init__(self, parent=parent) self.setLayout(qt.QGridLayout()) self._stageCB = qt.QComboBox(parent=self) for stage in _NabuStages: self._stageCB.addItem(stage.value) self.layout().addWidget(qt.QLabel("stage:", self), 0, 0, 1, 1) self.layout().addWidget(self._stageCB, 0, 1, 1, 1) self._configurationWidget = _NabuConfiguration(parent=parent) self.layout().addWidget(self._configurationWidget, 1, 0, 2, 2) class _NabuConfiguration(qt.QWidget): def __init__(self, parent): qt.QWidget.__init__(self, parent=parent) self.setLayout(qt.QFormLayout) def filter(self, stage=None, process=None): """Apply a filter on the options to show :param stage: :param process: """ pass def setStages(self, stages: dict) -> None: """ :param stages: contains stages the user can edit and for each stages the associated processes. """ self.clear() for stage, processes in stages.items(): self.addStage(stage=stage, processes=processes) def addStage(self, stage, processes): stage = _NabuStages(value=stage) for process in processes: _NabuStages.getProcessEnum(stage=stage) class NabuDialog(qt.QDialog): sigComputationRequested = qt.Signal() """Signal emitted when a computation is requested""" def __init__(self, parent): qt.QDialog.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) self._widget = NabuWindow(self) self.layout().addWidget(self._widget) self._computePB = qt.QPushButton("compute", self) self._buttons = qt.QDialogButtonBox(self) self._buttons.addButton(self._computePB, qt.QDialogButtonBox.ActionRole) self.layout().addWidget(self._buttons) # set up # expose API self.setOutputDir = self._widget.setOutputDir def setScan(self, scan): self._widget.setScan(scan) def getWidget(self): return self._widget def getConfiguration(self): return self._widget.getConfiguration() class NabuWindow(qt.QMainWindow): sigConfigChanged = qt.Signal() """Signal emitted when the configuration change""" def __init__(self, parent, flow_direction="vertical"): qt.QMainWindow.__init__(self, parent=parent) self.setWindowFlags(qt.Qt.Widget) self._mainWidget = NabuTabWidget(parent=self, flow_direction=flow_direction) self.setCentralWidget(self._mainWidget) style = qt.QApplication.style() # add toolbar toolbar = qt.QToolBar(self) toolbar.setMovable(False) toolbar.setFloatable(False) self.addToolBar(qt.Qt.TopToolBarArea, toolbar) # add filtering self._filterAction = FilterAction(toolbar) toolbar.addAction(self._filterAction) self._filterAction.triggered.connect(self._filteringChanged) # add configuration mode self.__configurationModesAction = qt.QAction(self) self.__configurationModesAction.setCheckable(False) menu = qt.QMenu(self) self.__configurationModesAction.setMenu(menu) toolbar.addAction(self.__configurationModesAction) self.__configurationModesGroup = qt.QActionGroup(self) self.__configurationModesGroup.setExclusive(True) self.__configurationModesGroup.triggered.connect(self._userModeChanged) self._minimalisticAction = MinimalisticConfigurationAction(toolbar) menu.addAction(self._minimalisticAction) self.__configurationModesGroup.addAction(self._minimalisticAction) self._basicConfigAction = BasicConfigurationAction(toolbar) menu.addAction(self._basicConfigAction) self.__configurationModesGroup.addAction(self._basicConfigAction) self._expertConfiguration = ExpertConfigurationAction(toolbar) menu.addAction(self._expertConfiguration) self.__configurationModesGroup.addAction(self._expertConfiguration) # add load option self.__loadAction = qt.QAction(self) self.__loadAction.setToolTip("load nabu configuration from a text file") # load_icon = style.standardIcon(qt.QStyle.SP_) load_icon = silx_icons.getQIcon("document-open") self.__loadAction.setIcon(load_icon) toolbar.addAction(self.__loadAction) self.__loadAction.triggered.connect(self._loadParameters) # add save option self.__saveAction = qt.QAction(self) self.__saveAction.setToolTip("save nabu configuration to a text file") save_icon = silx_icons.getQIcon("document-save") self.__saveAction.setIcon(save_icon) toolbar.addAction(self.__saveAction) self.__saveAction.triggered.connect(self._saveParameters) # reset configuration option self.__resetAction = qt.QAction(self) self.__resetAction.setToolTip("reset nabu configuration") reset_icon = style.standardIcon(qt.QStyle.SP_DialogResetButton) self.__resetAction.setIcon(reset_icon) toolbar.addAction(self.__resetAction) self.__resetAction.triggered.connect(self._resetParameters) # toolbar spacer self.__tSpacer = qt.QWidget(toolbar) self.__tSpacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Preferred) toolbar.addWidget(self.__tSpacer) # connect signal / slot self._mainWidget.sigConfigChanged.connect(self.sigConfigChanged) # set up self._resetParameters() self._filterAction.setChecked(True) self._basicConfigAction.setChecked(True) self._userModeChanged() def getConfiguration(self): configuration = self._mainWidget.getConfiguration() assert ( "configuration_level" not in configuration ), "configuration_level is a reserved key" configuration["configuration_level"] = self.getConfigurationLevel().value configuration["mode_locked"] = self.isModeLocked() return configuration def setConfiguration(self, config): conf = config.copy() if "configuration_level" in conf: configuration_level = conf["configuration_level"] del conf["configuration_level"] else: configuration_level = None modeLocked = conf.get("mode_locked", None) if modeLocked is not None: self.setModeLocked(modeLocked) self._mainWidget.setConfiguration(conf) if configuration_level is not None: self.setConfigurationLevel(level=configuration_level) def _saveParameters(self): from nabu.pipeline.config import generate_nabu_configfile from tomwer.core.process.reconstruction.nabu.nabuslices import ( interpret_tomwer_configuration, ) # request output file config = interpret_tomwer_configuration( config=self.getConfiguration(), scan=None ) if len(config) == 0: return elif len(config) > 1: _logger.warning( "You requested several paganin values." "Only one will be saved" ) config = config[0][0] fname = self.askForNabuconfigFile() if fname is None: return generate_nabu_configfile( fname, nabu_fullfield_default_config, config=config, options_level="advanced", ) def _resetParameters(self): # reset nabu settings default_config = get_default_nabu_config(nabu_fullfield_default_config) self._mainWidget.nabuSettingsWidget._configuration._preProcessingWidget._sinoRingsOpts.resetConfiguration() default_config["tomwer_slices"] = "middle" default_config["preproc"]["ccd_filter_enabled"] = False default_config["preproc"]["double_flatfield"] = False default_config["preproc"]["flatfield"] = True default_config["preproc"]["take_logarithm"] = True self.setConfiguration(default_config) def _loadParameters(self): inputFile = self.askForNabuconfigFile(acceptMode=qt.QFileDialog.AcceptOpen) import os if inputFile and os.path.exists(inputFile): from nabu.pipeline.config import parse_nabu_config_file config = parse_nabu_config_file(inputFile) self.setConfiguration(config) def askForNabuconfigFile( # pragma: no cover self, acceptMode=qt.QFileDialog.AcceptSave ): dialog = qt.QFileDialog(self) dialog.setNameFilters( [ "Configuration files (*.cfg *.conf *.config)", "Any files (*)", ] ) dialog.setAcceptMode(acceptMode) dialog.setFileMode(qt.QFileDialog.AnyFile) if not dialog.exec(): dialog.close() return filesSelected = dialog.selectedFiles() if filesSelected is not None and len(filesSelected) > 0: output = filesSelected[0] if not output.endswith((".cfg", ".conf", ".config")): output = f"{output}.conf" return output def _userModeChanged(self, *args, **kwargs): selectedAction = self.__configurationModesGroup.checkedAction() self.__configurationModesAction.setIcon(selectedAction.icon()) self.__configurationModesAction.setToolTip(selectedAction.tooltip()) self._mainWidget.setConfigurationLevel(self.getConfigurationLevel()) self.sigConfigChanged.emit() def _filteringChanged(self, *args, **kwargs): self._mainWidget.setFilteringActive(self.isFilteringActive()) def isFilteringActive(self): return self._filterAction.isChecked() def setConfigurationLevel(self, level): level = ConfigurationLevel(level) if level == ConfigurationLevel.REQUIRED: self._minimalisticAction.setChecked(True) elif level == ConfigurationLevel.ADVANCED: self._expertConfiguration.setChecked(True) elif level == ConfigurationLevel.OPTIONAL: self._basicConfigAction.setChecked(True) else: raise ValueError("Level not recognize") self._userModeChanged() def getConfigurationLevel(self): if self._basicConfigAction.isChecked(): return ConfigurationLevel.OPTIONAL elif self._expertConfiguration.isChecked(): return ConfigurationLevel.ADVANCED elif self._minimalisticAction.isChecked(): return ConfigurationLevel.REQUIRED else: raise ValueError("Level not recognize") # expose API def setModeLocked(self, locked: bool): self._mainWidget.nabuSettingsWidget.setModeLocked(locked) def isModeLocked(self): return self._mainWidget.nabuSettingsWidget.isModeLocked() def setOutputDir(self, dir: str): self._mainWidget.nabuSettingsWidget.setOutputDir(dir=dir) def setScan(self, scan: TomwerScanBase): self._mainWidget.nabuSettingsWidget.setScan(scan=scan) def getMode(self): return self._mainWidget.nabuSettingsWidget.getMode() def setMode(self, mode): self._mainWidget.nabuSettingsWidget.setMode(mode=mode) def hideSlicesInterface(self): self._mainWidget.nabuSettingsWidget.hideSlicesInterface() def hidePaganinInterface(self): self._mainWidget.nabuSettingsWidget.hidePaganinInterface() class NabuWidget(qt.QWidget): """ Widget containing the entire gui for nabu (control flow + parameters settings) """ sigConfigChanged = qt.Signal() """Signal emitted when the configuration change""" def __init__(self, parent, flow_direction="vertical"): qt.QWidget.__init__(self, parent=parent) flow_direction = FlowDirection(flow_direction) self.setLayout(qt.QGridLayout()) self._filteringActive = True self._configuration_level = ConfigurationLevel.OPTIONAL # reconstruction type self._widget_recons = qt.QWidget(parent=self) self._widget_recons.setLayout(qt.QHBoxLayout()) self._modeLabel = qt.QLabel("mode:") self._widget_recons.layout().addWidget(self._modeLabel) self._nabuModeCB = qt.QComboBox(parent=self) for mode in _NabuMode: self._nabuModeCB.addItem(mode.value) self._widget_recons.layout().addWidget(self._nabuModeCB) self.layout().addWidget(self._widget_recons, 0, 1, 1, 2) # mode lock button self._lockModeButton = PadlockButton(parent=self) self._lockModeButton.setToolTip( "mode can be deduced automatically from the dataset " "if it contains information on Field of view. " "If you want to enforce the mode you can lock it. " "This way automatic deduction will be ignored." ) self._lockModeButton.setMaximumWidth(30) self._widget_recons.layout().addWidget(self._lockModeButton) # spacer spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum) self.layout().addWidget(spacer, 1, 8, 1, 1) # flow self._flow = NabuFlowArea(parent=self, direction=flow_direction) self._flow.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum) self.layout().addWidget(self._flow, 1, 1, 5, 1) # nabu configuration self._configurationScrollArea = qt.QScrollArea(self) self._configurationScrollArea.setWidgetResizable(True) self._configuration = NabuConfiguration(parent=self) self._configurationScrollArea.setWidget(self._configuration) self._configurationScrollArea.setHorizontalScrollBarPolicy( qt.Qt.ScrollBarAlwaysOff ) self.layout().addWidget(self._configurationScrollArea, 1, 2, 5, 1) self._configuration.setSizePolicy( qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum ) self._configurationScrollArea.setSizePolicy( qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum ) # expose API self.setIniProcessing = self._flow.setIniProcessing self.setPreProcessing = self._flow.setPreProcessing self.setPhaseProcessing = self._flow.setPhaseProcessing self.setProcessing = self._flow.setProcessing self.setPostProcessing = self._flow.setPostProcessing self.setOutputDir = self._configuration.setOutputDir self.getActiveProcess = self._flow.getProcessFocused # set up pre_processing = ("pre processing",) roman_one_icon = tomwer_icons.getQIcon("roman_one") self.setPreProcessing(pre_processing, icons=(roman_one_icon,)) phase_processing = ("phase",) roman_two_icon = tomwer_icons.getQIcon("roman_two") phase_icons = (roman_two_icon,) self.setPhaseProcessing(phase_processing, icons=phase_icons) processing = ("reconstruction",) processing_icons = (tomwer_icons.getQIcon("roman_three"),) self.setProcessing(processes=processing, icons=processing_icons) post_processing = ("save",) post_processing_icons = (tomwer_icons.getQIcon("roman_four"),) self.setPostProcessing(post_processing, icons=post_processing_icons) index_mode = self._nabuModeCB.findText(_NabuMode.FULL_FIELD.value) assert index_mode >= 0, "full filed should be registered in the widget" self._nabuModeCB.setCurrentIndex(index_mode) self._flow.setMaximumWidth(240) # signal / slot connections self._flow.sigConfigurationChanged.connect(self._processSelectionChanged) self._flow.sigResetConfiguration.connect(self._processSelectionChanged) self._configuration.sigConfChanged.connect(self._triggerConfigChanged) self._nabuModeCB.currentIndexChanged.connect(self._triggerConfigChanged) def _triggerConfigChanged(self, *args, **kwargs): self.sigConfigChanged.emit() def isModeLocked(self) -> True: """ Return True if the mode is locked (in this case there is no automatic detection of it) """ return self._lockModeButton.isLocked() def setModeLocked(self, locked: bool): if not isinstance(locked, bool): raise TypeError(f"locked is expeced to be a bool not {type(locked)}") self._lockModeButton.setLock(locked) def setScan(self, scan): """Tune the configuration from scan information if possible""" assert isinstance(scan, TomwerScanBase) if scan.field_of_view is not None and not self.isModeLocked(): if scan.field_of_view == FOV.FULL: self.setMode(_NabuMode.FULL_FIELD) elif scan.field_of_view == FOV.HALF: self.setMode(_NabuMode.HALF_ACQ) if scan.sa_delta_beta_params is not None: db = scan.sa_delta_beta_params.selected_delta_beta_value if db is not None: self.setDeltaBetaValue(db) def getConfiguration(self): conf = self._configuration.getConfiguration() enable_ht = int(self.getMode() is _NabuMode.HALF_ACQ) conf["reconstruction"]["enable_halftomo"] = enable_ht return conf def setConfiguration(self, config): if "reconstruction" in config and "enable_halftomo" in config["reconstruction"]: if config["reconstruction"]["enable_halftomo"] == 1: index = self._nabuModeCB.findText(_NabuMode.HALF_ACQ.value) else: index = self._nabuModeCB.findText(_NabuMode.FULL_FIELD.value) self._nabuModeCB.setCurrentIndex(index) self._configuration.setConfiguration(config=config) def setDeltaBetaValue(self, value): self._configuration.setDeltaBetaValue(value=value) def hideSlicesInterface(self): self._configuration.hideSlicesInterface() def hidePaganinInterface(self): self._configuration.hidePaganinInterface() def getMode(self): return _NabuMode(self._nabuModeCB.currentText()) def setMode(self, mode): mode = _NabuMode(mode) idx = self._nabuModeCB.findText(mode.value) self._nabuModeCB.setCurrentIndex(idx) def _processSelectionChanged(self, *arg): if self.isConfigFiltered(): self.updateConfigurationFilter() def isConfigFiltered(self): return self._filteringActive def updateConfigurationFilter(self, *args, **kwargs): if self.isConfigFiltered(): stage, option = self.getActiveProcess() else: stage = None option = None self._configuration.applyFilter(stage=stage, option=option) self._configuration.setConfigurationLevel(self.getConfigurationLevel()) # force scroll bar to update self._configurationScrollArea.updateGeometry() def setConfigurationLevel(self, level): level = ConfigurationLevel(level) self._configuration_level = level self.updateConfigurationFilter() def getConfigurationLevel(self): return self._configuration_level def setFilteringActive(self, active): self._filteringActive = active self.updateConfigurationFilter() class NabuTabWidget(qt.QTabWidget): """ Widget that group Nabu reconstruction settings and (local) platform settings """ sigConfigChanged = qt.Signal() def __init__(self, parent=None, flow_direction: str = "vertical"): super().__init__(parent=parent) self._nabuSettingsWidget = NabuWidget( parent=self, flow_direction=flow_direction ) self.addTab(self._nabuSettingsWidget, "reconstruction settings") self._platformSettingsWidget = NabuPlatformSettings(parent=self) self.addTab(self._platformSettingsWidget, TAB_LABEL_PLATFORM_SETTINGS) # connect signal / slot self._nabuSettingsWidget.sigConfigChanged.connect(self.sigConfigChanged) self._platformSettingsWidget.sigConfigChanged.connect(self.sigConfigChanged) def getConfiguration(self) -> dict: config = self._nabuSettingsWidget.getConfiguration() config = concatenate_dict( config, self._platformSettingsWidget.getConfiguration() ) return config def setConfiguration(self, config: dict): self._nabuSettingsWidget.setConfiguration(config=config) self._platformSettingsWidget.setConfiguration(config=config) def setConfigurationLevel(self, level): self._nabuSettingsWidget.setConfigurationLevel(level=level) self._platformSettingsWidget.setConfigurationLevel(level=level) def getConfigurationLevel(self): return self._nabuSettingsWidget.getConfigurationLevel() @property def nabuSettingsWidget(self): return self._nabuSettingsWidget @property def platformSettings(self): return self._platformSettingsWidget ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/slurm.py0000644000175000017500000000236414757047403022653 0ustar00paynopayno# coding: utf-8 from __future__ import annotations from silx.gui import qt from tomwer.gui.cluster.slurm import SlurmSettingsWidget class SlurmSettingsDialog(qt.QDialog): sigConfigChanged = qt.Signal() """Signal emit when the SlurmSetting changed""" def __init__(self, parent=None): super().__init__(parent=parent) self.setLayout(qt.QVBoxLayout()) self._mainWidget = SlurmSettingsWidget(parent=self) self.layout().addWidget(self._mainWidget) # buttons for validation self._buttons = qt.QDialogButtonBox(self) types = qt.QDialogButtonBox.Close self._buttons.setStandardButtons(types) self.layout().addWidget(self._buttons) self._buttons.button(qt.QDialogButtonBox.Close).clicked.connect(self.close) # connect signal /slot self._mainWidget.sigConfigChanged.connect(self._configChanged) def _configChanged(self, *args, **kwargs): self.sigConfigChanged.emit() def isSlurmActive(self): return self._mainWidget.isSlurmActive() def getConfiguration(self) -> dict: return self._mainWidget.getConfiguration() def setConfiguration(self, config: dict) -> None: self._mainWidget.setConfiguration(config=config) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9411016 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/test/0000755000175000017500000000000015153325403022077 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/test/test_cast_volume.py0000644000175000017500000000657315115744275026056 0ustar00paynopaynofrom tomwer.tests.conftest import qtapp # noqa F401 from tomwer.gui.reconstruction.nabu.castvolume import CastVolumeWidget def test_CastVolumeWidget(qtapp): # noqa F811 """simple test of the CastVolumeWidget""" widget = CastVolumeWidget(parent=None) assert widget.getConfiguration() == { "compression_ratios": None, "data_max": None, "data_min": None, "output_data_type": "uint16", "output_dir": "{volume_data_parent_folder}/cast_volume", "output_file_format": "tiff", "overwrite": True, "rescale_max_percentile": 90, "rescale_min_percentile": 10, "remove_input_volume": False, } widget._minMaxAuto.setChecked(False) assert widget.getConfiguration() == { "compression_ratios": None, "data_max": 0.0, "data_min": 0.0, "output_data_type": "uint16", "output_dir": "{volume_data_parent_folder}/cast_volume", "output_file_format": "tiff", "overwrite": True, "rescale_max_percentile": None, "rescale_min_percentile": None, "remove_input_volume": False, } widget.setDataMin(1.0) widget.setDataMax(10.0) assert widget.getConfiguration() == { "compression_ratios": None, "data_max": 10.0, "data_min": 1.0, "output_data_type": "uint16", "output_dir": "{volume_data_parent_folder}/cast_volume", "output_file_format": "tiff", "overwrite": True, "rescale_max_percentile": None, "rescale_min_percentile": None, "remove_input_volume": False, } widget.setOutputFileformat("edf") assert widget.getConfiguration() == { "compression_ratios": None, "data_max": 10.0, "data_min": 1.0, "output_data_type": "uint16", "output_dir": "{volume_data_parent_folder}/cast_volume", "output_file_format": "edf", "overwrite": True, "rescale_max_percentile": None, "rescale_min_percentile": None, "remove_input_volume": False, } widget.setOverwrite(False) assert widget.getConfiguration() == { "compression_ratios": None, "data_max": 10.0, "data_min": 1.0, "output_data_type": "uint16", "output_dir": "{volume_data_parent_folder}/cast_volume", "output_file_format": "edf", "overwrite": False, "rescale_max_percentile": None, "rescale_min_percentile": None, "remove_input_volume": False, } widget.setOutputDataType("float32") assert widget.getConfiguration() == { "compression_ratios": None, "data_max": 10.0, "data_min": 1.0, "output_data_type": "float32", "output_dir": "{volume_data_parent_folder}/cast_volume", "output_file_format": "edf", "overwrite": False, "rescale_max_percentile": None, "rescale_min_percentile": None, "remove_input_volume": False, } widget.setRemoveInputVolume(True) assert widget.getConfiguration() == { "compression_ratios": None, "data_max": 10.0, "data_min": 1.0, "output_data_type": "float32", "output_dir": "{volume_data_parent_folder}/cast_volume", "output_file_format": "edf", "overwrite": False, "rescale_max_percentile": None, "rescale_min_percentile": None, "remove_input_volume": True, } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/test/test_check.py0000644000175000017500000000441614757047403024604 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import pytest from nxtomo.nxobject.nxdetector import ImageKey from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.utils.scanutils import MockEDF, MockNXtomo from tomwer.gui.reconstruction.nabu import check def test_check_dark_series(tmpdir): """test check.check_dark_series function""" full_edf_path = os.path.join(tmpdir, "my", "aquisition", "folder") MockEDF.fastMockAcquisition(full_edf_path) edf_scan = EDFTomoScan(full_edf_path) with pytest.raises(TypeError): assert check.check_dark_series(edf_scan) full_hdf5_scan = os.path.join(tmpdir, "hdf5_scan") scan = MockNXtomo( scan_path=full_hdf5_scan, n_proj=20, n_ini_proj=20, dim=10, ).scan scan._image_keys = ( [ImageKey.DARK_FIELD] * 2 + [ImageKey.PROJECTION] * 4 + [ImageKey.DARK_FIELD] * 2 ) assert check.check_dark_series(scan, logger=None, user_input=False) is False scan._image_keys = [ImageKey.DARK_FIELD] * 2 + [ImageKey.PROJECTION] * 4 assert check.check_dark_series(scan, logger=None, user_input=False) is True scan._image_keys = [ImageKey.PROJECTION] * 4 assert check.check_dark_series(scan, logger=None, user_input=False) is False def test_check_flat_series(tmpdir): """test check.check_flat_series function""" full_edf_path = os.path.join(tmpdir, "my", "aquisition", "folder") MockEDF.fastMockAcquisition(full_edf_path) edf_scan = EDFTomoScan(full_edf_path) with pytest.raises(TypeError): assert check.check_flat_series(edf_scan) full_hdf5_scan = os.path.join(tmpdir, "hdf5_scan") scan = MockNXtomo( scan_path=full_hdf5_scan, n_proj=20, n_ini_proj=20, dim=10, ).scan scan._image_keys = ( [ImageKey.FLAT_FIELD] * 2 + [ImageKey.PROJECTION] * 4 + [ImageKey.FLAT_FIELD] * 2 ) assert check.check_flat_series(scan, logger=None, user_input=False) is True scan._image_keys = [ImageKey.FLAT_FIELD] * 2 + [ImageKey.PROJECTION] * 4 assert check.check_flat_series(scan, logger=None, user_input=False) is True scan._image_keys = [ImageKey.PROJECTION] * 4 assert check.check_flat_series(scan, logger=None, user_input=False) is False ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/test/test_ctf.py0000644000175000017500000000266115115744275024303 0ustar00paynopaynoimport pytest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from tomwer.gui.reconstruction.nabu.nabuconfig.ctf import CTFConfig from tomwer.tests.utils import skip_gui_test @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestFutureSupervisorOW(TestCaseQt): def setUp(self): super().setUp() self._widget = CTFConfig() def tearDown(self): self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None return super().tearDown() def test_configuration(self): """ test configuration setter and getter """ self._widget.show() config = self._widget.getConfiguration() assert isinstance(config, dict) assert config == { "ctf_geometry": " z1_v=None; z1_h=None; detec_pixel_size=None; magnification=True", "ctf_advanced_params": " length_scale=1e-05; lim1=1e-05; lim2=0.2; normalize_by_mean=True", "beam_shape": "parallel", } config["beam_shape"] = "cone" config["ctf_geometry"] = ( " z1_v=10.2; z1_h=3.6; detec_pixel_size=1e-05; magnification=False" ) config["ctf_advanced_params"] = ( " length_scale=2e-05; lim1=1e-08; lim2=0.1; normalize_by_mean=False" ) self._widget.setConfiguration(config) assert self._widget.getConfiguration() == config ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/test/test_helical.py0000644000175000017500000000136214757047403025125 0ustar00paynopaynofrom tomwer.tests.conftest import qtapp # noqa F401 from tomwer.gui.reconstruction.nabu.helical import HelicalPrepareWeightsDouble def test_DeltaBetaSelector( qtapp, # noqa F811 ): """simple test of the _DeltaBetaSelectorDialog""" widget = HelicalPrepareWeightsDouble() assert widget.getConfiguration() == { "processes_file": "{scan_parent_dir_basename}/{scan_dir_name}/map_and_doubleff.hdf5", "transition_width_vertical": 50.0, "transition_width_horizontal": 50.0, } config = { "processes_file": "test.hdf5", "transition_width_vertical": 12.5, "transition_width_horizontal": 11.5, } widget.setConfiguration(config=config) assert widget.getConfiguration() == config ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/test/test_nabu_preprocessing.py0000644000175000017500000000432214757047403027413 0ustar00paynopaynofrom tomwer.gui.reconstruction.nabu.nabuconfig.preprocessing import ( SinoRingsOptions, TiltCorrection, RingCorrectionMethod, ) from tomwer.tests.conftest import qtapp # noqa F401 def test_tilt_correction_widget(qtapp): # noqa F811 """ Test of TiltCorrection """ widget = TiltCorrection(text="") assert not widget._tiltManualRB.isChecked() assert widget._autoManualRB.isChecked() assert widget.getTiltCorrection() == ("1d-correlation", "") widget.setTiltCorrection(0.0) assert widget.getTiltCorrection() == (0.0, "") assert widget._tiltManualRB.isChecked() assert not widget._autoManualRB.isChecked() widget.setTiltCorrection("fft-polar", auto_tilt_options="low_pass=10") assert widget.getTiltCorrection() == ("fft-polar", "low_pass=10") assert not widget._tiltManualRB.isChecked() assert widget._autoManualRB.isChecked() def test_sino_rings_options(qtapp): # noqa F811 """ Test of SinoRingsOptions """ widget = SinoRingsOptions() # test munch options assert widget.getOptions() == { "sigma": 1.0, "levels": 10, "padding": False, } widget.setOptions( { "sigma": 3.25, "levels": 564, "padding": True, } ) assert widget.getOptions() == { "sigma": 3.25, "levels": 564, "padding": True, } # test mean division widget.setMethod(method=RingCorrectionMethod.MEAN_DIVISION) assert widget.getOptions() == { "filter_cutoff": (0, 30), } # test VO deringer widget.setMethod(method=RingCorrectionMethod.VO.value) assert widget.getOptions() == { "dim": 1, "la_size": 51, "sm_size": 21, "snr": 3.0, } new_vo_options = { "dim": 2, "la_size": 42, "sm_size": 22, "snr": 6.3, } widget.setOptions(new_vo_options) assert widget.getOptions() == new_vo_options # test mean division new_mean_division_options = { "filter_cutoff": (10, 23), } widget.setMethod(method=RingCorrectionMethod.MEAN_DIVISION) widget.setOptions(new_mean_division_options) assert widget.getOptions() == new_mean_division_options ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/nabu/volume.py0000644000175000017500000004264215153325210023005 0ustar00paynopayno# coding: utf-8 from __future__ import annotations from asyncio.log import logger from silx.gui import qt from tomwer.core.process.reconstruction.nabu.utils import ( _NabuStages, ) from tomwer.core.utils.dictutils import concatenate_dict from tomwer.gui import icons from tomwer.gui.configuration.action import ( BasicConfigurationAction, ExpertConfigurationAction, MinimalisticConfigurationAction, ) from tomwer.gui.configuration.level import ConfigurationLevel from tomwer.gui.reconstruction.nabu.nabuconfig.base import _NabuStageConfigBase from tomwer.gui.reconstruction.nabu.nabuconfig.output import ( NabuOutputLocationWidget, QNabuFileFormatComboBox, ) from tomwer.gui.reconstruction.nabu.platform import NabuPlatformSettings from tomwer.gui.settings import ( TAB_LABEL_RECONSTRUCTION_SETTINGS, TAB_LABEL_PLATFORM_SETTINGS, ) class SliceSelector(qt.QWidget): """ Widget to select a value for defining a ROI to reconstruction (start or end) """ valueChanged = qt.Signal() """emit when the slice value change""" def __init__( self, label, auto_alias, is_end, grid_layout, index_layout, parent=None ): qt.QWidget.__init__(self, parent=parent) self._label = qt.QLabel(label, parent=self) grid_layout.addWidget(self._label, index_layout, 0, 1, 1) self._qcb = qt.QCheckBox(auto_alias) grid_layout.addWidget(self._qcb, index_layout, 1, 1, 1) grid_layout.addWidget(qt.QLabel("or", self), index_layout, 2, 1, 1) self._qle = qt.QLineEdit("0", self) self._validator = qt.QIntValidator() self._qle.setValidator(self._validator) grid_layout.addWidget(self._qle, index_layout, 3, 1, 1) self._is_end = is_end if is_end is True: self._qle.setToolTip("-1 will be the last slice") self._validator.setBottom(-1) else: self._validator.setBottom(0) # set up self._qcb.setChecked(True) self._qle.setEnabled(False) if is_end: self._qle.setText("-1") # connect signal / slot self._qcb.toggled.connect(self._qle.setDisabled) self._qcb.toggled.connect(self._triggerValueChanged) self._qle.editingFinished.connect(self._triggerValueChanged) def _triggerValueChanged(self, *args, **kwargs): self.valueChanged.emit() def setMaximum(self, maximum): self._validator.setTop(maximum) def value(self): if self._qcb.isChecked(): return -1 if self._is_end else 0 else: return int(self._qle.text()) def setValue(self, value): self._qle.setText(str(value)) if self._is_end: self._qcb.setChecked(value == -1) else: self._qcb.setChecked(value == 0) class NabuVolumeWidget(_NabuStageConfigBase, qt.QWidget): """ Widget dedicated to manage the volume reconstruction from nabu """ sigConfigChanged = qt.Signal() """Signal emitted when the configuration change""" def __init__(self, parent=None): qt.QWidget.__init__(self, parent=parent) _NabuStageConfigBase.__init__(self, stage=_NabuStages.VOLUME) self.setLayout(qt.QGridLayout()) # warning about requires parameters from a nabu slice reconstruction self._warning_widget = qt.QWidget(parent=self) self._warning_widget.setLayout(qt.QHBoxLayout()) self._warningIconL = qt.QLabel("", parent=self) self._warningIconL.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum) self._warningIconL.setAlignment(qt.Qt.AlignRight | qt.Qt.AlignVCenter) self._warningIconR = qt.QLabel("", parent=self) self._warningIconR.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum) self._warningIconR.setAlignment(qt.Qt.AlignLeft | qt.Qt.AlignVCenter) warning_icon = icons.getQIcon("warning") self._warningIconL.setPixmap(warning_icon.pixmap(20, 20)) self._warningIconR.setPixmap(warning_icon.pixmap(20, 20)) self._warning_widget.layout().addWidget(self._warningIconL) self._labelWarning = qt.QLabel( "Requires parameters from nabu slice reconstruction.", parent=self ) self._labelWarning.setToolTip( 'This mean that a "nabu slice ' 'reconstruction" widget should exist upstream' ) self._warning_widget.layout().addWidget(self._labelWarning) self._warning_widget.layout().addWidget(self._warningIconR) self.layout().addWidget(self._warning_widget, 0, 0, 1, 2) # volume from and to option self._groupBox = qt.QGroupBox("volume to reconstruct", parent=self) self._groupBox.setLayout(qt.QGridLayout()) self.layout().addWidget(self._groupBox, 2, 0, 1, 2) self._fromSlice = SliceSelector( label="from slice", auto_alias="start", is_end=False, parent=self, grid_layout=self._groupBox.layout(), index_layout=0, ) self._groupBox.layout().addWidget(self._fromSlice) self.registerWidget(self._groupBox, "required") self._toSlice = SliceSelector( label="to slice", auto_alias="end", is_end=True, parent=self, grid_layout=self._groupBox.layout(), index_layout=1, ) self._groupBox.layout().addWidget(self._toSlice) # option to compute histogram self._histogramCB = qt.QCheckBox("compute volume histogram of values", self) self.layout().addWidget(self._histogramCB, 3, 0, 1, 2) self.registerWidget(self._histogramCB, "required") # output format can be redefined self._redefineNabuFileFormat = qt.QGroupBox( "change received file format from 'nabu slice'", self ) self._redefineNabuFileFormat.setCheckable(True) self._redefineNabuFileFormat.setLayout(qt.QVBoxLayout()) self._fileFormatCB = QNabuFileFormatComboBox(self._redefineNabuFileFormat) self._redefineNabuFileFormat.layout().addWidget(self._fileFormatCB) self.layout().addWidget(self._redefineNabuFileFormat, 4, 0, 1, 2) self.registerWidget(self._fileFormatCB, "advanced") self.registerWidget(self._redefineNabuFileFormat, "advanced") # redefine output location self._redefineNabuOutputLocation = qt.QGroupBox( "change received reconstruction output location from 'nabu slice'", self ) self._redefineNabuOutputLocation.setCheckable(True) self._redefineNabuOutputLocation.setLayout(qt.QVBoxLayout()) self._outputLocationWidget = NabuOutputLocationWidget(parent=self) self._redefineNabuOutputLocation.layout().addWidget(self._outputLocationWidget) self.layout().addWidget(self._redefineNabuOutputLocation, 5, 0, 1, 2) self.registerWidget(self._redefineNabuOutputLocation, "advanced") self.registerWidget(self._outputLocationWidget, "advanced") # opt use phase Paganin self._usePhaseQCB = qt.QCheckBox("Use phase Paganin") self.layout().addWidget(self._usePhaseQCB, 52, 0, 1, 2) self.registerWidget(self._usePhaseQCB, "advanced") self._usePhaseQCB.setToolTip( "Whether to use a margin when " "performing phase retrieval." ) # spacer for style spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer, 99, 0, 1, 1) # set up self._histogramCB.setChecked(True) self._usePhaseQCB.setChecked(True) self._redefineNabuFileFormat.setChecked(False) self._redefineNabuOutputLocation.setChecked(False) self.setConfigurationLevel("required") # connect signal / slot self._fromSlice.valueChanged.connect(self._triggerSigConfChanged) self._toSlice.valueChanged.connect(self._triggerSigConfChanged) self._usePhaseQCB.toggled.connect(self._triggerSigConfChanged) self._outputLocationWidget._outputDirQLE.editingFinished.connect( self._triggerSigConfChanged ) self._outputLocationWidget.sigOutputChanged.connect(self._triggerSigConfChanged) self._redefineNabuOutputLocation.toggled.connect(self._triggerSigConfChanged) def redefineOutputLocation(self): return self._redefineNabuOutputLocation.isChecked() def setRedefineOutputLocation(self, redefine: bool): self._redefineNabuOutputLocation.setChecked(redefine) def getNabuOutputLocation(self): if self.redefineOutputLocation(): return self._outputLocationWidget.getOutputDir() else: return None def setNabuOutputLocation(self, location: str | None): if location is None: self._redefineNabuOutputLocation.setChecked(False) else: self._redefineNabuOutputLocation.setChecked(True) self._outputLocationWidget.setOutputDirMode("other") self._outputLocationWidget.setOutputDir(location) def redefineNabuFileFormat(self): return self._redefineNabuFileFormat.isChecked() def getNabuFileFormat(self): if self.redefineNabuFileFormat(): return self._fileFormatCB.currentText() else: return None def setNabuFileFormat(self, file_format: str | None): if file_format is None: self._redefineNabuFileFormat.setChecked(False) else: assert isinstance(file_format, str) self._redefineNabuFileFormat.setChecked(True) idx = self._fileFormatCB.findText(file_format) if idx < 0: logger.error(f"unable to find file format {file_format}") else: self._fileFormatCB.setCurrentIndex(idx) def _triggerSigConfChanged(self, *args, **kwargs): self.sigConfigChanged.emit() def getStartZ(self): return self._fromSlice.value() def setStartZ(self, value): self._fromSlice.setValue(value) def getEndZ(self): return self._toSlice.value() def setEndZ(self, value): self._toSlice.setValue(value) def phasePaganinRequested(self): return self._usePhaseQCB.isChecked() def setPhasePaganinRequested(self, checked): self._usePhaseQCB.setChecked(checked) def setScan(self, scan): if len(scan.projections) > 0: self._fromSlice.setMaximum(len(scan.projections)) else: self._fromSlice.setMaximum(999999999) def isHistogramRequested(self): return self._histogramCB.isChecked() def setHistogramRequested(self, requested): self._histogramCB.setChecked(requested) def getConfiguration(self): return { "start_z": self.getStartZ(), "end_z": self.getEndZ(), "use_phase_margin": self.phasePaganinRequested(), "postproc": { "output_histogram": int(self.isHistogramRequested()), }, "new_output_file_format": self.getNabuFileFormat() or "", "new_output_location": self.getNabuOutputLocation() or "", "output_dir_mode": self._outputLocationWidget.getOutputDirMode().value, "overwrite_output_location": self.redefineOutputLocation(), } def setConfiguration(self, config): if "start_z" in config: self.setStartZ(config["start_z"]) if "end_z" in config: self.setEndZ(config["end_z"]) if "use_phase_margin" in config: self.setPhasePaganinRequested(config["use_phase_margin"]) if "postproc" in config: self.setPostProcConfiguration(config["postproc"]) if "new_output_file_format" in config: new_output_file_format = config["new_output_file_format"] if new_output_file_format == "": new_output_file_format = None self.setNabuFileFormat(new_output_file_format) if "new_output_location" in config: new_output_location = config["new_output_location"] if new_output_location == "": new_output_location = None self.setNabuOutputLocation(new_output_location) output_dir_mode = config.get("output_dir_mode", None) if output_dir_mode is not None: self._outputLocationWidget.setOutputDirMode(output_dir_mode) overwrite_output_location = config.get("overwrite_output_location", None) if overwrite_output_location is not None: self.setRedefineOutputLocation(overwrite_output_location) def setPostProcConfiguration(self, config): if "output_histogram" in config: self.setHistogramRequested(requested=bool(config["output_histogram"])) def setConfigurationLevel(self, level): level = ConfigurationLevel(level) _NabuStageConfigBase.setConfigurationLevel(self, level) def getConfigurationLevel(self): return self._configuration_level class NabuVolumeTabWidget(qt.QTabWidget): """ Widget that integrate the reconstruction settings and the platform (local) settings """ sigConfigChanged = qt.Signal() def __init__(self, parent: qt.QWidget | None = ...) -> None: super().__init__(parent) self._configurationLevel = ConfigurationLevel.OPTIONAL self._nabuSettingsWidget = NabuVolumeWidget(parent=self) self.addTab(self._nabuSettingsWidget, TAB_LABEL_RECONSTRUCTION_SETTINGS) self._platformSettingsWidget = NabuPlatformSettings(parent=self) self.addTab(self._platformSettingsWidget, TAB_LABEL_PLATFORM_SETTINGS) # connect signal / slot self._nabuSettingsWidget.sigConfigChanged.connect(self.sigConfigChanged) self._platformSettingsWidget.sigConfigChanged.connect(self.sigConfigChanged) def getConfiguration(self) -> dict: return concatenate_dict( self._nabuSettingsWidget.getConfiguration(), self._platformSettingsWidget.getConfiguration(), ) def setConfiguration(self, config: dict) -> None: self._nabuSettingsWidget.setConfiguration(config=config) self._platformSettingsWidget.setConfiguration(config=config) def setConfigurationLevel(self, level): self._configurationLevel = ConfigurationLevel(level) self._nabuSettingsWidget.setConfigurationLevel(level=self._configurationLevel) self._platformSettingsWidget.setConfigurationLevel( level=self._configurationLevel ) def getConfigurationLevel(self): return self._configuration_level class NabuVolumeWindow(qt.QMainWindow): """ Widget to define settings for a volume reconstruction """ sigConfigChanged = qt.Signal() """Signal emitted when configuration change""" def __init__(self, parent): qt.QMainWindow.__init__(self, parent=parent) self.setWindowFlags(qt.Qt.Widget) self._mainWidget = NabuVolumeTabWidget(parent=self) self.setCentralWidget(self._mainWidget) # add toolbar toolbar = qt.QToolBar(self) toolbar.setMovable(False) toolbar.setFloatable(False) self.addToolBar(qt.Qt.TopToolBarArea, toolbar) # add configuration mode self.__configurationModesAction = qt.QAction(self) self.__configurationModesAction.setCheckable(False) menu = qt.QMenu(self) self.__configurationModesAction.setMenu(menu) toolbar.addAction(self.__configurationModesAction) self.__configurationModesGroup = qt.QActionGroup(self) self.__configurationModesGroup.setExclusive(True) self.__configurationModesGroup.triggered.connect(self._userModeChanged) self._minimalisticAction = MinimalisticConfigurationAction(toolbar) menu.addAction(self._minimalisticAction) self.__configurationModesGroup.addAction(self._minimalisticAction) self._basicConfigAction = BasicConfigurationAction(toolbar) menu.addAction(self._basicConfigAction) self.__configurationModesGroup.addAction(self._basicConfigAction) self._expertConfiguration = ExpertConfigurationAction(toolbar) menu.addAction(self._expertConfiguration) self.__configurationModesGroup.addAction(self._expertConfiguration) # set up self._userModeChanged(action=self._basicConfigAction) self._basicConfigAction.setChecked(True) # connect signal / slot self._mainWidget.sigConfigChanged.connect(self._triggerSigConfigChanged) def _triggerSigConfigChanged(self, *args, **kwargs): self.sigConfigChanged.emit() def _userModeChanged(self, action): self.__configurationModesAction.setIcon(action.icon()) self.__configurationModesAction.setToolTip(action.tooltip()) if action is self._basicConfigAction: level = ConfigurationLevel.OPTIONAL elif action is self._expertConfiguration: level = ConfigurationLevel.ADVANCED else: level = ConfigurationLevel.REQUIRED self._mainWidget.setConfigurationLevel(level) # expose API def getConfigurationLevel(self): self._mainWidget.getConfigurationLevel() def setConfigurationLevel(self, level): self._mainWidget.setConfigurationLevel(level=level) def getConfiguration(self): return self._mainWidget.getConfiguration() def setConfiguration(self, config): return self._mainWidget.setConfiguration(config=config) def setScan(self, scan): return self._mainWidget.setScan(scan=scan) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9411016 tomwer-1.6.17/src/tomwer/gui/reconstruction/normalization/0000755000175000017500000000000015153325403023061 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/normalization/__init__.py0000644000175000017500000000000014757047403025172 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/normalization/intensity.py0000644000175000017500000007733215153325210025471 0ustar00paynopayno# coding: utf-8 """ contains gui relative to intensity normalization """ from __future__ import annotations import weakref from silx.gui import qt from silx.gui.dialog.DataFileDialog import DataFileDialog from silx.gui.plot.items.roi import HorizontalRangeROI, RectangleROI from silx.gui.plot.tools.roi import RegionOfInterestManager from silx.io.url import DataUrl from tomoscan.normalization import Method from tomwer.core.process.reconstruction.normalization import params as _normParams from tomwer.core.process.reconstruction.normalization.params import _ValueSource from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui.reconstruction.scores.control import ControlWidget from tomwer.gui.utils.buttons import PadlockButton from tomwer.gui.visualization.dataviewer import DataViewer from tomwer.gui.visualization.sinogramviewer import SinogramViewer as _SinogramViewer class SinoNormWindow(qt.QMainWindow): sigConfigurationChanged = qt.Signal() """signal emit when the configuration change""" def __init__(self, parent, backend=None): qt.QMainWindow.__init__(self, parent) self._scan = None self.setWindowFlags(qt.Qt.Widget) # central widget self._centralWidget = _Viewer(self, backend=backend) self.setCentralWidget(self._centralWidget) # control widget (options + ctrl buttons) self._dockWidgetWidget = qt.QWidget(self) self._dockWidgetWidget.setLayout(qt.QVBoxLayout()) self._optsWidget = _NormIntensityOptions(self) self._dockWidgetWidget.layout().addWidget(self._optsWidget) self._spacer = qt.QWidget(self) self._spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self._dockWidgetWidget.layout().addWidget(self._spacer) self._crtWidget = _NormIntensityControl(self) self._dockWidgetWidget.layout().addWidget(self._crtWidget) # dock widget self._dockWidgetCtrl = qt.QDockWidget(parent=self) self._dockWidgetCtrl.layout().setContentsMargins(0, 0, 0, 0) self._dockWidgetCtrl.setFeatures(qt.QDockWidget.DockWidgetMovable) self._dockWidgetCtrl.setWidget(self._dockWidgetWidget) self.addDockWidget(qt.Qt.RightDockWidgetArea, self._dockWidgetCtrl) # connect signal / slot # self._optsWidget.sigModeChanged.connect(self._modeChanged) self._optsWidget.sigValueUpdated.connect(self.setResult) self._optsWidget.sigConfigurationChanged.connect(self.sigConfigurationChanged) self._optsWidget.sigSourceChanged.connect(self._sourceChanged) self._crtWidget.sigValidateRequest.connect(self._validated) # set up self._centralWidget._updateSinogramROI() self._modeChanged() def _hideLockButton(self): self._optsWidget._hideLockButton() def _validated(self): pass def getConfiguration(self) -> dict: return self._optsWidget.getConfiguration() def setConfiguration(self, config: dict): self._optsWidget.setConfiguration(config=config) def setCurrentMethod(self, method): self._optsWidget.setCurrentMethod(method=method) def getCurrentMethod(self): return self._optsWidget.getCurrentMethod() def setCurrentSource(self, source): self._optsWidget.setCurrentSource(source=source) def getCurrentSource(self): return self._optsWidget.getCurrentSource() def _modeChanged(self): self._sourceChanged() def _sourceChanged(self): source = self.getCurrentSource() method = self.getCurrentMethod() scan = self.getScan() methods_using_manual_roi = (Method.DIVISION, Method.SUBTRACTION) self._centralWidget.setManualROIVisible( source is _ValueSource.MANUAL_ROI and method in methods_using_manual_roi ) if scan: methods_requesting_calculation = (Method.DIVISION, Method.SUBTRACTION) if method in methods_requesting_calculation: # if the normed sinogram can be obtained `directly` if source in (_ValueSource.MANUAL_SCALAR, _ValueSource.DATASET): scan.intensity_normalization = self.getCurrentMethod().value extra_info = self.getExtraArgs() extra_info.update( { "tomwer_processing_res_code": True, "source": source.value, } ) scan.intensity_normalization.set_extra_infos(extra_info) self._centralWidget._updateSinogramROI() def getScan(self): if self._scan is not None: return self._scan() else: return None def setScan(self, scan: TomwerScanBase | None): self._scan = weakref.ref(scan) self._centralWidget.setScan(scan=scan) self._optsWidget.setScan(scan=scan) def getExtraArgs(self) -> dict: return self._optsWidget.getExtraInfos() def getROI(self): return self._centralWidget.getROI() def setROI(self, start_x, end_x, start_y, end_y): self._centralWidget.setROI( start_x=start_x, end_x=end_x, start_y=start_y, end_y=end_y ) def setResult(self, result): self._crtWidget.setResult(result) def clear(self): self._crtWidget.clear() def isLocked(self): return self._optsWidget.isLocked() def setLocked(self, locked): self._optsWidget.setLocked(locked) class _Viewer(qt.QTabWidget): def __init__(self, parent, backend=None): if not isinstance(parent, SinoNormWindow): raise TypeError("Expect a NormIntensityWindow as parrent") qt.QTabWidget.__init__(self, parent) self._projView = _ProjPlotWithROI(parent=self, backend=backend) self.addTab(self._projView, "projection view") self._sinoView = SinogramViewer(parent=self, backend=backend) self.addTab(self._sinoView, "sinogram view") # connect signal / Slot self._sinoView.sigSinogramLineChanged.connect(self._projView.setSinogramLine) self._sinoView.sigSinoLoadEnded.connect(self._updateSinogramROI) self._projView.sigROIChanged.connect(self._updateSinogramROI) def setScan(self, scan: TomwerScanBase | None): """ :param scan: scan to handle :return: """ self._projView.setScan(scan) self._sinoView.setScan(scan, update=False) def _updateSinogramROI(self): source = self.parent().getCurrentSource() method = self.parent().getCurrentMethod() display_sino_roi = source is _ValueSource.MANUAL_ROI and method in ( Method.DIVISION, Method.SUBTRACTION, ) if display_sino_roi: roi = self._projView.getROI() sinogram_line = self._sinoView.getLine() y_min = roi.getOrigin()[1] y_max = roi.getOrigin()[1] + roi.getSize()[1] if y_min <= sinogram_line <= y_max: x_min = roi.getOrigin()[0] x_max = roi.getOrigin()[0] + roi.getSize()[0] self._sinoView.setROIRange(x_min, x_max) self._sinoView.setROIVisible(True) else: self._sinoView.setROIVisible(False) else: self._sinoView.setROIVisible(False) def setManualROIVisible(self, visible): self._projView.setManualROIVisible(visible=visible) self._sinoView.setROIVisible(visible=visible) def getROI(self): return self._projView.getROI() def setROI(self, start_x, end_x, start_y, end_y): self._projView.setROI( start_x=start_x, end_x=end_x, start_y=start_y, end_y=end_y ) class _ProjPlotWithROI(DataViewer): """DataViewer specialized on projections. Embed a RectangleROI""" sigROIChanged = qt.Signal() """signal emit when ROI change""" def __init__(self, *args, **kwargs): DataViewer.__init__(self, *args, **kwargs, show_overview=False) self._sinogramLine = 0 self._roiVisible = False self.setScanInfoVisible(False) self.setDisplayMode("projections-radios") self.setDisplayModeVisible(False) dw = self.getUrlListDockWidget() self.addDockWidget(qt.Qt.BottomDockWidgetArea, dw) dw.setFeatures(qt.QDockWidget.DockWidgetMovable) # add ROI self._roiManager = RegionOfInterestManager(self.getPlotWidget()) self._roi = RectangleROI() self._roi.setName("ROI") self._roi.setLineStyle("-.") self._roi.setGeometry(origin=(0, 0), size=(200, 200)) self._roi.setEditable(True) self._roi.setVisible(True) self._roiManager.addRoi(self._roi) # connect signal / slot self.getPlotWidget().sigActiveImageChanged.connect(self._updateSinogramLine) self.getPlotWidget().sigActiveImageChanged.connect(self._updateROI) self._roi.sigEditingFinished.connect(self._roiChanged) def getROI(self): return self._roi def setROI(self, start_x, end_x, start_y, end_y): self._roi.setOrigin((start_x, start_y)) self._roi.setSize((end_x - start_x, end_y - start_y)) def setManualROIVisible(self, visible): self._roiVisible = visible self._updateROIVisibility() def _updateROIVisibility(self): self._roi.setVisible(self._roiVisible) def _roiChanged(self): self.sigROIChanged.emit() def setSinogramLine(self, line): self._sinogramLine = line self._updateSinogramLine() def _updateROI(self): """ImageStack clean the plot which bring item removal. This is why we need to add them back""" if self._roi is not None: for item in self._roi.getItems(): if item not in self.getPlotWidget().getItems(): self.getPlotWidget().addItem(item) def _updateSinogramLine(self): self._roiManager = RegionOfInterestManager(self.getPlotWidget()) self.getPlotWidget().addYMarker( y=self._sinogramLine, legend="sinogram_line", text="sinogram line", color="blue", selectable=False, ) sino_marker = self.getPlotWidget()._getMarker("sinogram_line") if sino_marker: sino_marker.setLineStyle("--") def clear(self): super().clear() self.getPlotWidget().removeMarker("sinogram_line") class SinogramViewer(_SinogramViewer): """ "Sinogram viewer but adapated for Intensity normalization""" sigSinogramLineChanged = qt.Signal(int) """signal emit when the selected sinogram line changes""" def __init__(self, *args, **kwargs): _SinogramViewer.__init__(self, *args, **kwargs) dockWidget = self.getOptionsDockWidget() self.addDockWidget(qt.Qt.TopDockWidgetArea, dockWidget) dockWidget.setFeatures(qt.QDockWidget.DockWidgetMovable) # change ApplyButton name and icon self._loadButton = self._options._buttons.button(qt.QDialogButtonBox.Apply) self._loadButton.setText("load") style = qt.QApplication.style() self._loadButton.setIcon(style.standardIcon(qt.QStyle.SP_BrowserReload)) # ROI self._roiManager = RegionOfInterestManager(self.getPlotWidget()) self._roi = HorizontalRangeROI() self._roi.setRange(0, 0) self._roi.setVisible(True) self._roi.setColor((250, 50, 50, 150)) self._roi.setLineWidth(1.5) self._roi.setLineStyle("-.") self._roiManager.addRoi(self._roi) # connect signal / Slots self._options._lineSB.valueChanged.connect(self._sinogramLineChanged) self.sigSinogramLineChanged.connect(self._plot.clear) self.getPlotWidget().sigActiveImageChanged.connect(self._updateROI) def _sinogramLineChanged(self): self.sigSinogramLineChanged.emit(self.getLine()) def setROIRange(self, x_min, x_max): self._roi.setRange(x_min, x_max) def setROIVisible(self, visible): self._roi.setVisible(visible) def _updateROI(self): """ImageStack clean the plot which bring item removal. This is why we need to add them back""" if self._roi is not None: for item in self._roi.getItems(): if item not in self.getPlotWidget().getItems(): self.getPlotWidget().addItem(item) def getPlotWidget(self): return self._plot def _updatePlot(self, sinogram): self.getPlotWidget().addImage(data=sinogram) self.getPlotWidget().replot() class _NormIntensityOptions(qt.QWidget): sigValueCanBeLocked = qt.Signal(bool) sigProcessingRequested = qt.Signal() """Signal emit when the processing is requested""" sigModeChanged = qt.Signal() """signal emitted when the mode change""" sigSourceChanged = qt.Signal() """signal emitted when the source change""" sigValueUpdated = qt.Signal(object) """Signal emit when user defines manually the value""" sigConfigurationChanged = qt.Signal() """Signal emit when the configuration changes""" def __init__(self, parent): if not isinstance(parent, SinoNormWindow): raise TypeError( "parent is expected to be an instance of " "NormIntensityWindow " ) qt.QWidget.__init__(self, parent) self._getROI = self.parent().getROI self.setLayout(qt.QGridLayout()) # mode self._modeCB = qt.QComboBox(self) for mode in Method: if mode in (Method.LSQR_SPLINE,): continue else: self._modeCB.addItem(mode.value) self.layout().addWidget(qt.QLabel("mode:", self), 0, 0, 1, 1) self.layout().addWidget(self._modeCB, 0, 1, 1, 1) self._lockButton = PadlockButton(self) self._lockButton.setFixedWidth(25) self.layout().addWidget(self._lockButton, 0, 2, 1, 1) # source self._sourceCB = qt.QComboBox(self) for mode in _ValueSource: if mode == _ValueSource.NONE: # filter this value because does not have much sense for the GUI continue if mode in (_ValueSource.AUTO_ROI, _ValueSource.MONITOR): continue self._sourceCB.addItem(mode.value) self._sourceLabel = qt.QLabel("source:", self) self.layout().addWidget(self._sourceLabel, 1, 0, 1, 1) self.layout().addWidget(self._sourceCB, 1, 1, 1, 1) # method self._optsMethod = qt.QGroupBox(self) self._optsMethod.setTitle("options") self._optsMethod.setLayout(qt.QVBoxLayout()) self.layout().addWidget(self._optsMethod, 2, 0, 1, 3) # intensity calculation options self._intensityCalcOpts = _NormIntensityCalcOpts(self) self._optsMethod.layout().addWidget(self._intensityCalcOpts) # dataset widget self._datasetWidget = _NormIntensityDatasetWidget(self) self._optsMethod.layout().addWidget(self._datasetWidget) # scalar value self._scalarValueWidget = _NormIntensityScalarValue(self) self.layout().addWidget(self._scalarValueWidget, 3, 0, 1, 3) # buttons self._buttonsGrp = qt.QWidget(self) self._buttonsGrp.setLayout(qt.QGridLayout()) self._buttonsGrp.layout().setContentsMargins(0, 0, 0, 0) self._computeButton = qt.QPushButton("compute", self) self._buttonsGrp.layout().addWidget(self._computeButton, 0, 1, 1, 1) spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) self._buttonsGrp.layout().addWidget(spacer) self.layout().addWidget(self._buttonsGrp, 4, 0, 1, 3) self._modeChanged() # connect signal / slot self._modeCB.currentIndexChanged.connect(self._modeChanged) self._modeCB.currentIndexChanged.connect(self.sigConfigurationChanged) self._sourceCB.currentIndexChanged.connect(self._sourceChanged) self._sourceCB.currentIndexChanged.connect(self.sigConfigurationChanged) self._computeButton.released.connect(self.sigProcessingRequested) self._scalarValueWidget.sigValueChanged.connect(self._valueUpdated) self._scalarValueWidget.sigValueChanged.connect(self.sigConfigurationChanged) self._datasetWidget.sigConfigurationChanged.connect( self.sigConfigurationChanged ) self._intensityCalcOpts.sigConfigurationChanged.connect( self.sigConfigurationChanged ) self._lockButton.toggled.connect(self._lockChanged) self._lockButton.toggled.connect(self.sigConfigurationChanged) def _sourceChanged(self): source = self.getCurrentSource() method = self.getCurrentMethod() interactive_methods = (Method.DIVISION, Method.SUBTRACTION) interactive_sources = ( _ValueSource.MANUAL_ROI, _ValueSource.AUTO_ROI, _ValueSource.DATASET, ) self._datasetWidget.setVisible(source == _ValueSource.DATASET) self.setManualROIVisible(source == _ValueSource.MANUAL_ROI) self._optsMethod.setVisible( method in interactive_methods and source in interactive_sources ) self._intensityCalcOpts.setCalculationFctVisible( method in interactive_methods and source in interactive_sources and source is not _ValueSource.DATASET ) self._scalarValueWidget.setVisible(source == _ValueSource.MANUAL_SCALAR) self._buttonsGrp.setVisible( method in interactive_methods and source in interactive_sources ) self.sigSourceChanged.emit() def _lockChanged(self): self._scalarValueWidget.setEnabled(not self.isLocked()) self._datasetWidget.setEnabled(not self.isLocked()) self._intensityCalcOpts.setEnabled(not self.isLocked()) self._modeCB.setEnabled(not self.isLocked()) self._computeButton.setEnabled(not self.isLocked()) def isLocked(self): return self._lockButton.isLocked() def setLocked(self, locked): self._lockButton.setChecked(locked) def _hideLockButton(self): self._lockButton.hide() def getCurrentMethod(self): return Method(self._modeCB.currentText()) def setCurrentMethod(self, method): method = Method(method) idx = self._modeCB.findText(method.value) self._modeCB.setCurrentIndex(idx) def getCurrentSource(self): if self.getCurrentMethod() in (Method.DIVISION, Method.SUBTRACTION): return _ValueSource(self._sourceCB.currentText()) else: return _ValueSource.NONE def setCurrentSource(self, source): source = _ValueSource(source) idx = self._sourceCB.findText(source.value) self._sourceCB.setCurrentIndex(idx) def _modeChanged(self, *args, **kwargs): mode = self.getCurrentMethod() mode_with_calculations = (Method.DIVISION, Method.SUBTRACTION) self._intensityCalcOpts.setVisible(mode in mode_with_calculations) self._sourceCB.setVisible(mode in mode_with_calculations) self._sourceLabel.setVisible(mode in mode_with_calculations) self._sourceChanged() self.sigModeChanged.emit() self.sigSourceChanged.emit() def _valueUpdated(self, *args): self.sigValueUpdated.emit(args) def setManualROIVisible(self, visible): pass def getConfiguration(self) -> dict: return _normParams.SinoNormalizationParams( method=self.getCurrentMethod(), source=self.getCurrentSource(), extra_infos=self.getExtraInfos(), ).to_dict() def setConfiguration(self, config: dict): params = _normParams.SinoNormalizationParams.from_dict(config) self.setCurrentMethod(params.method) extra_infos = params.extra_infos if ( "start_x" in extra_infos and "start_y" in extra_infos and "end_x" in extra_infos and "end_y" in extra_infos ): start_x = extra_infos["start_x"] start_y = extra_infos["start_y"] end_x = extra_infos["end_x"] end_y = extra_infos["end_y"] self._getROI().setOrigin((start_x, start_y)) self._getROI().setSize((end_x - start_x, end_y - start_y)) if "calc_fct" in extra_infos: self._intensityCalcOpts.setCalculationFct(extra_infos["calc_fct"]) if "calc_area" in extra_infos: self._intensityCalcOpts.setCalculationArea(extra_infos["calc_area"]) if "calc_method" in extra_infos: self._intensityCalcOpts.setCalculationMethod(extra_infos["calc_method"]) if params.source is _ValueSource.MANUAL_SCALAR: if "value" in extra_infos: self._scalarValueWidget.setValue(extra_infos["value"]) def setScan(self, scan): self._datasetWidget.setScan(scan=scan) def getExtraInfos(self): method = self.getCurrentMethod() source = self.getCurrentSource() if method in (Method.CHEBYSHEV, Method.NONE): return {} else: if source is _ValueSource.MANUAL_SCALAR: return {"value": self._scalarValueWidget.getValue()} elif source is _ValueSource.AUTO_ROI: raise NotImplementedError("auto roi not implemented yet") elif source is _ValueSource.MANUAL_ROI: roi = self._getROI() return { "start_x": roi.getOrigin()[0], "end_x": roi.getOrigin()[0] + roi.getSize()[0], "start_y": roi.getOrigin()[1], "end_y": roi.getOrigin()[1] + roi.getSize()[1], "calc_fct": self._intensityCalcOpts.getCalculationFct().value, } elif source is _ValueSource.DATASET: return { "dataset_url": self._datasetWidget.getDatasetUrl().path(), } else: raise ValueError(f"unhandled source: {source} for method {method}") class _NormIntensityCalcOpts(qt.QWidget): """Options to compute the norm intensity""" sigConfigurationChanged = qt.Signal() """Signal emitted when configuration changes""" def __init__(self, parent): qt.QWidget.__init__(self, parent) self.setLayout(qt.QFormLayout()) # calculation function self._calculationModeCB = qt.QComboBox(self) for fct in _normParams._ValueCalculationFct: self._calculationModeCB.addItem(fct.value) self._calculationModeLabel = qt.QLabel("calculation fct", self) self.layout().addRow(self._calculationModeLabel, self._calculationModeCB) # connect signal / slot self._calculationModeCB.currentIndexChanged.connect( self.sigConfigurationChanged ) def setCalculationFctVisible(self, visible): self._calculationModeLabel.setVisible(visible) self._calculationModeCB.setVisible(visible) def getCalculationFct(self): return _normParams._ValueCalculationFct(self._calculationModeCB.currentText()) def setCalculationFct(self, fct): idx = self._calculationModeCB.findText(_normParams._ValueCalculationFct(fct)) self._calculationModeCB.setCurrentIndex(idx) class _NormIntensityControl(ControlWidget): def __init__(self, parent=None): ControlWidget.__init__(self, parent) self._resultWidget = qt.QWidget(self) self._resultWidget.setLayout(qt.QFormLayout()) self._result = None self._resultQLE = qt.QLineEdit("", self) self._resultWidget.layout().addRow("value:", self._resultQLE) self._resultQLE.setReadOnly(True) self.layout().insertWidget(0, self._resultWidget) self._computeBut.hide() def setResult(self, result): self._result = result if isinstance(result, tuple): result = ",".join([str(element) for element in result]) self._resultQLE.setText(str(result)) def getResult(self): return self._result def clear(self): self._resultQLE.clear() class _NormIntensityScalarValue(qt.QWidget): sigValueChanged = qt.Signal(float) """emit when the scalar value to norm intensity change""" def __init__(self, parent=None): qt.QWidget.__init__(self, parent=parent) self.setLayout(qt.QFormLayout()) self._QLE = qt.QLineEdit("0.0", self) validator = qt.QDoubleValidator(parent=self) self._QLE.setValidator(validator) self.layout().addRow("value", self._QLE) # connect signal / slot self._QLE.editingFinished.connect(self._valueChanged) def setValue(self, value): self._QLE.setText(str(value)) def getValue(self): return float(self._QLE.text()) def _valueChanged(self): self.sigValueChanged.emit(self.getValue()) class _NormIntensityDatasetWidget(qt.QWidget): _FILE_PATH_LOCAL_VALUE = "scan master file" sigConfigurationChanged = qt.Signal() """emit when configuration change""" def __init__(self, parent=None): qt.QWidget.__init__(self, parent) self._lastGlobalPath = None self._scan = None self.setLayout(qt.QGridLayout()) # file scope self._fileScopeGB = qt.QGroupBox("file scope", self) self._fileScopeGB.setLayout(qt.QVBoxLayout()) self._buttonGrpBox = qt.QButtonGroup(self) self._globalRB = qt.QRadioButton(_normParams._DatasetScope.GLOBAL.value, self) self._buttonGrpBox.addButton(self._globalRB) self._globalRB.setToolTip("Global dataset. Will be constant with time") self._fileScopeGB.layout().addWidget(self._globalRB) self._localRB = qt.QRadioButton(_normParams._DatasetScope.LOCAL.value, self) self._buttonGrpBox.addButton(self._localRB) self._localRB.setToolTip( "Local dataset." "Must be contained in the NXtomo entry " "provided (not compatible with EDF)." ) self._fileScopeGB.layout().addWidget(self._localRB) self.layout().addWidget(self._fileScopeGB, 0, 0, 3, 3) # file_path self._filePathLabel = qt.QLabel("file path", self) self.layout().addWidget(self._filePathLabel, 3, 0, 1, 1) self._filePathQLE = qt.QLineEdit("", self) self.layout().addWidget(self._filePathQLE, 3, 1, 1, 1) self._selectFileButton = qt.QPushButton("select", self) self.layout().addWidget(self._selectFileButton, 3, 2, 1, 1) # data path self._dataPathLabel = qt.QLabel("data path", self) self.layout().addWidget(self._dataPathLabel, 4, 0, 1, 1) self._dataPathQLE = qt.QLineEdit("", self) self.layout().addWidget(self._dataPathQLE, 4, 1, 1, 1) self._selectDataPathButton = qt.QPushButton("select", self) self.layout().addWidget(self._selectDataPathButton, 4, 2, 1, 1) # set up self._localRB.setChecked(True) self._updateFilePathVisibility() # connect signal / slot self._buttonGrpBox.buttonToggled.connect(self._updateFilePathVisibility) self._selectFileButton.released.connect(self._selectFile) self._selectDataPathButton.released.connect(self._selectDataPath) self._buttonGrpBox.buttonReleased.connect(self._configurationChanged) self._filePathQLE.editingFinished.connect(self._configurationChanged) self._dataPathQLE.editingFinished.connect(self._configurationChanged) def _configurationChanged(self, *args, **kwargs): self.sigConfigurationChanged.emit() def setScan(self, scan): if scan is not None: self._scan = weakref.ref(scan) return None def getScan(self): if self._scan is not None: return self._scan() else: return None def getMode(self) -> _normParams._DatasetScope: if self._localRB.isChecked(): return _normParams._DatasetScope.LOCAL else: return _normParams._DatasetScope.GLOBAL def getDataPath(self): return self._dataPathQLE.text() def setDataPath(self, path): self._dataPathQLE.setText(path) def getGlobalFilePath(self) -> str: return self._filePathQLE.text() def setGlobalFilePath(self, file_path): self._filePathQLE.setText(file_path) def getDatasetUrl(self) -> DataUrl: if self.getMode() is _normParams._DatasetScope.LOCAL: if self.getScan() is not None: scan = self.getScan() file_path = scan.master_file else: file_path = None else: file_path = self.getGlobalFilePath() data_path = self.getDataPath() if file_path is not None and file_path.lower().endswith("edf"): scheme = "fabio" else: scheme = "silx" return DataUrl( file_path=file_path, data_path=data_path, scheme=scheme, ) def setDatasetUrl(self, url: DataUrl): raise NotImplementedError("") def _updateFilePathVisibility(self): self._filePathQLE.setReadOnly(self.getMode() == _normParams._DatasetScope.LOCAL) self._filePathQLE.setEnabled(self.getMode() == _normParams._DatasetScope.GLOBAL) self._selectFileButton.setEnabled( self.getMode() == _normParams._DatasetScope.GLOBAL ) if ( self.getMode() == _normParams._DatasetScope.LOCAL and self.getGlobalFilePath() != self._FILE_PATH_LOCAL_VALUE ): self._lastGlobalPath = self.getGlobalFilePath() self.setGlobalFilePath(self._FILE_PATH_LOCAL_VALUE) elif ( self.getMode() == _normParams._DatasetScope.GLOBAL and self.getGlobalFilePath() == self._FILE_PATH_LOCAL_VALUE ): if self._lastGlobalPath is not None: self.setGlobalFilePath(self._lastGlobalPath) def _selectFile(self): # pragma: no cover dialog = qt.QFileDialog(self) dialog.setNameFilters(["HDF5 file *.h5 *.hdf5 *.nx *.nxs *.nexus"]) if not dialog.exec(): dialog.close() return filesSelected = dialog.selectedFiles() if len(filesSelected) > 0: self.setGlobalFilePath(filesSelected[0]) def _selectDataPath(self): """Open a dialog. If from a master file try to open the scan master file if any.""" if self.getMode() is _normParams._DatasetScope.LOCAL: if self.getScan() is not None: scan = self.getScan() if not isinstance(scan, NXtomoScan): mess = qt.QMessageBox( parent=self, icon=qt.QMessageBox.Warning, text="local mode is only available for HDF5 acquisitions", ) mess.setModal(False) mess.show() return else: file_ = scan.master_file else: mess = qt.QMessageBox( parent=self, icon=qt.QMessageBox.Information, text="No scan set. Unable to find the master file", ) mess.setModal(False) mess.show() return elif self.getMode() is _normParams._DatasetScope.GLOBAL: file_ = self.getGlobalFilePath() else: raise ValueError(f"{self.getMode()} is not handled") dialog = DataFileDialog() dialog.selectFile(file_) dialog.setFilterMode(DataFileDialog.FilterMode.ExistingDataset) if not dialog.exec(): dialog.close() return else: selected_url = dialog.selectedUrl() self.setDataPath(DataUrl(path=selected_url).data_path()) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9411016 tomwer-1.6.17/src/tomwer/gui/reconstruction/normalization/test/0000755000175000017500000000000015153325403024040 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/normalization/test/test_intensity.py0000644000175000017500000000653415153325210027503 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import shutil import tempfile from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from tomwer.core.process.reconstruction.normalization.params import ( Method as NormalizationMethod, ) from tomwer.core.process.reconstruction.normalization.params import ( _ValueSource as NormalizationSource, ) from tomwer.core.utils.scanutils import MockNXtomo from tomwer.gui.reconstruction.normalization.intensity import SinoNormWindow class TestNormIntensityWindow(TestCaseQt): def setUp(self): super(TestNormIntensityWindow, self).setUp() self._widget = SinoNormWindow(parent=None) self._tmp_dir = tempfile.mkdtemp() scan_path = os.path.join(self._tmp_dir, "my_scan_2") self.scan = MockNXtomo( scan_path=scan_path, n_ini_proj=10, n_proj=10, n_alignement_proj=2, create_final_flat=False, create_ini_dark=True, create_ini_flat=True, n_refs=1, ).scan def tearDown(self): self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self.qapp.processEvents() self._widget = None shutil.rmtree(self._tmp_dir) super(TestNormIntensityWindow, self).tearDown() def test(self): self._widget.setScan(self.scan) self._widget.show() self.qWaitForWindowExposed(self._widget) self._widget.setCurrentMethod(NormalizationMethod.NONE) self.qapp.processEvents() assert self._widget.getConfiguration() == {"source": "none", "method": "none"} self._widget.setCurrentMethod(NormalizationMethod.CHEBYSHEV) self.qapp.processEvents() assert self._widget.getConfiguration() == { "method": "chebyshev", "source": "none", } self._widget.setCurrentMethod(NormalizationMethod.SUBTRACTION) self.qapp.processEvents() self._widget.setCurrentSource(NormalizationSource.MANUAL_ROI) self.qapp.processEvents() output_configuration = self._widget.getConfiguration() assert output_configuration["method"] == "subtraction" assert output_configuration["source"] == "manual ROI" assert "start_x" in output_configuration assert "end_x" in output_configuration assert "start_y" in output_configuration assert "end_y" in output_configuration assert "calc_fct" in output_configuration self._widget.setCurrentMethod(NormalizationMethod.DIVISION) self.qapp.processEvents() self._widget.setCurrentSource(NormalizationSource.DATASET) self.qapp.processEvents() output_configuration = self._widget.getConfiguration() assert output_configuration["method"] == "division" assert output_configuration["source"] == "from dataset" assert "dataset_url" in output_configuration self._widget.setCurrentMethod(NormalizationMethod.DIVISION) self.qapp.processEvents() self._widget.setCurrentSource(NormalizationSource.MANUAL_SCALAR) self.qapp.processEvents() output_configuration = self._widget.getConfiguration() assert output_configuration["method"] == "division" assert output_configuration["source"] == "scalar" assert "value" in output_configuration ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9411016 tomwer-1.6.17/src/tomwer/gui/reconstruction/saaxis/0000755000175000017500000000000015153325403021463 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/saaxis/__init__.py0000644000175000017500000000000015153325210023556 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/saaxis/corrangeselector.py0000644000175000017500000007603515153325210025405 0ustar00paynopayno""" contains gui relative to semi-automatic axis calculation """ from __future__ import annotations import functools import logging import weakref import numpy from silx.gui import icons as silxicons from silx.gui import qt from silx.gui.dialog.ImageFileDialog import ImageFileDialog from silx.gui.plot import items from enum import Enum as _Enum from tomoscan.esrf.scan.utils import get_data from tomwer.core.process.reconstruction.utils.cor import ( absolute_pos_to_relative, relative_pos_to_absolute, ) from tomwer.core.process.reconstruction.saaxis.saaxis import ReconstructionMode from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui import icons from tomwer.gui.reconstruction.saaxis.sliceselector import SliceSelector from tomwer.gui.utils.lineselector import QSliceSelectorDialog from tomwer.gui.utils.slider import LogSlider from tomwer.gui.visualization.sinogramviewer import SinogramViewer as _SinogramViewer from tomwer.gui.fonts import FONT_MEDIUM, FONT_IMPORTANT _logger = logging.getLogger(__name__) class DetectionAccuracy(_Enum): """The different accuracy modes""" COARSE = "Coarse" FINE = "Fine" ACCURATE = "Accurate" DEFINED_RANGE = "Defined range" ACCURACIES = { DetectionAccuracy.COARSE: 500, DetectionAccuracy.FINE: 10, DetectionAccuracy.ACCURATE: 2, } class SinogramViewer(_SinogramViewer): """Redefine the main SinogramViewer for saaxis purpose: * options orientation is horizontal * add the display of the cor roi to be displayed * rename ApplyButton to load and change the icon * hide the line selection (control by the slice selector * move the dock widget to the bottom * rename subsampling "loaded sinogram subsampling" to provide more context """ sigCorEdited = qt.Signal(float) """Signal emitted when the cor position change. Provided in absolute position""" sigWidthEdited = qt.Signal(float) """Signal emitted when the detection accuracy (width) change.""" def __init__(self, parent): super().__init__(parent, opts_orientation=qt.Qt.Horizontal) self._fromMarker = None self._toMarker = None self._corMarker = None self._min = None self._max = None self._estimated_cor = None self._other_cors = None # hide line selection self._options.setLineSelectionVisible(False) # change ApplyButton name and icon self._loadButton = self._options._buttons.button(qt.QDialogButtonBox.Apply) self._loadButton.setText("load") style = qt.QApplication.style() self._loadButton.setIcon(style.standardIcon(qt.QStyle.SP_BrowserReload)) # change subsampling name self._options._subsamplingLabel.setText("Sinogram subsampling") self._options._subsamplingLabel.setToolTip( "Define subsampling of the " "sinogram to be displayed" ) def loadSinogram(self): """simulate the click on `load` of the QPushButton""" self._loadButton.clicked.emit() def getOptionsDockWidget(self): return self._dockOpt def _updatePlot(self, sinogram): super()._updatePlot(sinogram) if ( self._min is not None and self._max is not None and self._estimated_cor is not None ): self.setCorRange( cor_min=self._min, cor_max=self._max, estimated_cor=self._estimated_cor, other_cors=self._other_cors, ) def setCorRange(self, cor_min, cor_max, estimated_cor, other_cors=tuple()): """ For now we can only modify the estimated cor :param min: :param max: :param estimated_cor: :param display_n_recons: the grid created by all cor observe :return: """ self._min = cor_min self._max = cor_max self._estimated_cor = estimated_cor self._other_cors = other_cors if other_cors is not None else tuple() plot = self._plot if self._corMarker is not None: self._corMarker.sigDragFinished.disconnect(self._middleMarkerMoved) if self._fromMarker is not None: self._fromMarker.sigDragFinished.disconnect( self._fromCallback # pylint: disable=E0203 ) if self._toMarker is not None: self._toMarker.sigDragFinished.disconnect( self._toCallback # pylint: disable=E0203 ) # clear existing markers markers = [ item.getName() for item in plot.getItems() if isinstance(item, items.MarkerBase) ] for marker in markers: plot.removeMarker(marker) # recreate markers plot.addXMarker( x=cor_min, legend="from", text="from", color="#3449ebff", draggable=True ) plot.addXMarker( x=cor_max, legend="to", text="to", color="#3449ebff", draggable=True ) plot.addXMarker( x=estimated_cor, legend="estimated cor", text="estimated cor", color="#34dcebff", draggable=True, ) for i_cor, cor in enumerate(other_cors): plot.addXMarker( x=cor, legend=f"cor_{i_cor}", draggable=False, color="#34dceb42" ) # handle draggable markers self._fromMarker = plot._getMarker("from") self._fromCallback = functools.partial(self._limitMarkerMoved, self._fromMarker) self._fromMarker.sigDragFinished.connect(self._fromCallback) self._toMarker = plot._getMarker("to") self._toCallback = functools.partial(self._limitMarkerMoved, self._toMarker) self._toMarker.sigDragFinished.connect(self._toCallback) self._corMarker = plot._getMarker("estimated cor") self._corMarker.sigDragFinished.connect(self._middleMarkerMoved) def _middleMarkerMoved(self): if self._corMarker is not None: self.sigCorEdited.emit(self._corMarker.getXPosition()) def _limitMarkerMoved(self, marker): if self._corMarker is not None and marker is not None: new_half_width = numpy.abs( marker.getXPosition() - self._corMarker.getXPosition() ) self.sigWidthEdited.emit(new_half_width * 2.0) class _ReconstructionModeGB(qt.QGroupBox): reconstructionModeChanged = qt.Signal(str) reconstructionSliceChanged = qt.Signal() _DEFAULT_VERTICAL_SLICE_MODE = ("middle", "other") def __init__(self, parent=None, title="Slice to be reconstructed"): self.__scan = None qt.QGroupBox.__init__(self, parent) self.setTitle(title) self.setLayout(qt.QVBoxLayout()) self._verticalRB = qt.QRadioButton(ReconstructionMode.VERTICAL.value, self) self.layout().addWidget(self._verticalRB) self._tiltCorrectionRB = qt.QRadioButton( ReconstructionMode.TILT_CORRECTION.value, self ) self.layout().addWidget(self._tiltCorrectionRB) # slice choice combobox self._defaultSlicesCB = qt.QComboBox(self) for mode in self._DEFAULT_VERTICAL_SLICE_MODE: self._defaultSlicesCB.addItem(mode) self.layout().addWidget(self._defaultSlicesCB) # slice selector self._sliceVerticalQSB = SliceSelector(self, insert=False, invert_y_axis=True) self._sliceVerticalQSB.addSlice(value=0, name="Slice", color="green") self._sliceVerticalQSB.setFixedSize(qt.QSize(250, 250)) self.layout().addWidget(self._sliceVerticalQSB) self._sliceTiltCorrQSB = SliceSelector(self, insert=False, invert_y_axis=True) self._sliceTiltCorrQSB.addSlice(value=0, name="Slice 0", color="#7e8dff") self._sliceTiltCorrQSB.addSlice(value=0, name="Slice 1", color="cyan") self._sliceTiltCorrQSB.setFixedSize(qt.QSize(250, 230)) self.layout().addWidget(self._sliceTiltCorrQSB) # select on radio # line selector button onRadioIcon = silxicons.getQIcon("window-new") self._onRadioButton = qt.QPushButton( onRadioIcon, "select on radio", parent=self ) self._onRadioButton.setToolTip("Open a dialog to pick the rows from" "a radio") self.layout().addWidget(self._onRadioButton) # connect signal / slot self._verticalRB.toggled.connect(self._reconstructionModeChanged) self._tiltCorrectionRB.toggled.connect(self._reconstructionModeChanged) self._sliceVerticalQSB.sigSlicesChanged.connect(self.reconstructionSliceChanged) self._onRadioButton.released.connect(self._onRadioActivated) self._defaultSlicesCB.currentIndexChanged.connect(self._updateVerticalSelection) # set up self.blockSignals(True) self.setCurrentMode("vertical", "middle") self.blockSignals(False) self._tiltCorrectionRB.hide() # as for now only the Vertical mode is handled hide it to avoid confusing user self._verticalRB.hide() def setCurrentMode(self, mode, slices): valid_modes = ("vertical", "horizontal") if mode not in valid_modes: raise ValueError( f"mode {mode} is not recosgnized. Valid modes are {valid_modes}" ) self._verticalRB.setChecked(mode == "vertical") if mode == "vertical": if slices not in self._DEFAULT_VERTICAL_SLICE_MODE: raise ValueError( f"{slices} is not a vadid slice mode. Calid are {self._DEFAULT_VERTICAL_SLICE_MODE}" ) else: index = self._defaultSlicesCB.findText(slices) self._defaultSlicesCB.setCurrentIndex(index) self._defaultSlicesCB.currentIndexChanged.emit(index) def _updateVerticalSelection(self): current_mode = self._defaultSlicesCB.currentText() mode_is_middle = current_mode == "middle" self._sliceVerticalQSB.setVisible(not mode_is_middle) self._onRadioButton.setVisible(not mode_is_middle) self.reconstructionSliceChanged.emit() def _onRadioActivated(self): lineSelection = QSliceSelectorDialog(parent=self, n_required_slice=1) scan = self.__scan() if self.__scan else None if scan is None: _logger.info("No scan defined, request user for defining the image" "url") dialog = ImageFileDialog() if dialog.exec(): data = dialog.selectedImage() else: return else: assert isinstance(scan, TomwerScanBase) try: projections = scan.projections index_radio = list(projections.keys())[len(projections) // 2] data = get_data(projections[index_radio]) except Exception as e: _logger.error(f"Fail to load radio data: {str(e)}") return lineSelection.setData(data) lineSelection.setSelection(list(self.getReconstructionSlices().values())) if lineSelection.exec() == qt.QDialog.Accepted: selection = lineSelection.getSelection() if selection is not None and len(selection) > 0: self.setReconstructionSlices({"Slice": selection[0]}) def setScan(self, scan): self.__scan = weakref.ref(scan) def getReconstructionMode(self) -> ReconstructionMode: if self._tiltCorrectionRB.isChecked(): return ReconstructionMode.TILT_CORRECTION elif self._verticalRB.isChecked(): return ReconstructionMode.VERTICAL else: raise ValueError("No reconstruction mode selected") def setReconstructionMode(self, mode: ReconstructionMode | str) -> None: mode = ReconstructionMode(mode) if mode is ReconstructionMode.TILT_CORRECTION: self._tiltCorrectionRB.setChecked(True) elif mode is ReconstructionMode.VERTICAL: self._verticalRB.setChecked(True) else: raise ValueError("No reconstruction mode selected") def getReconstructionSlices(self): mode = self.getReconstructionMode() if mode is ReconstructionMode.TILT_CORRECTION: return self._sliceTiltCorrQSB.getSlicesValue() elif mode is ReconstructionMode.VERTICAL: if self._defaultSlicesCB.currentText() == "middle": return "middle" else: return self._sliceVerticalQSB.getSlicesValue() else: raise ValueError(f"mode {mode} is not handled") def setReconstructionSlices(self, slice_: dict | int | str): slice_name = None if slice_ == "middle" or isinstance(slice_, int) or len(slice_) == 1: self.setReconstructionMode(ReconstructionMode.VERTICAL) target = self._sliceVerticalQSB if slice_ == "middle": index = self._defaultSlicesCB.findText("middle") else: index = self._defaultSlicesCB.findText("other") slice_name = "Slice" self._defaultSlicesCB.setCurrentIndex(index) elif len(slice_) == 2: self.setReconstructionMode(ReconstructionMode.TILT_CORRECTION) target = self._sliceTiltCorrQSB else: raise ValueError("slice is expected to contain one or two element(s)") if slice_ not in ("middle",): if isinstance(slice_, int): target.setSliceValue(name=slice_name, value=slice_) else: for slice_name, slice_value in slice_.items(): target.setSliceValue(name=slice_name, value=slice_value) def _reconstructionModeChanged(self, *args, **kwargs): reconstruction_mode = self.getReconstructionMode() self.reconstructionModeChanged.emit(reconstruction_mode.value) self._sliceTiltCorrQSB.setVisible( reconstruction_mode is ReconstructionMode.TILT_CORRECTION ) self._sliceVerticalQSB.setVisible( reconstruction_mode is ReconstructionMode.VERTICAL ) def setSlicesRange(self, min_index, max_index): self._sliceTiltCorrQSB.setSlicesRange(min_index, max_index) self._sliceVerticalQSB.setSlicesRange(min_index, max_index) def getSlicesRange(self): return self._sliceVerticalQSB.getSlicesRange() class _DetectionAccuracyGB(qt.QGroupBox): detectionAccuracyChanged = qt.Signal() """signal emitted when the value change""" _MIN_RANGE = 0.1 _MAX_RANGE = 4000 _DEFAULT_VALUE = 10 def __init__(self, parent=None, title="Detection accuracy (width)"): qt.QGroupBox.__init__(self, parent) self.setTitle(title) self.setLayout(qt.QGridLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.layout().setSpacing(0) self.setContentsMargins(0, 0, 0, 0) # slider self._accuracySlider = LogSlider(parent=self) self._accuracySlider.setSuffix(" px") self.layout().addWidget(self._accuracySlider, 0, 0, 1, 5) # different accuracy buttons accuracy_opt_font = self.font() accuracy_opt_font.setPixelSize(10) self._coarsePB = qt.QPushButton(DetectionAccuracy.COARSE.value, self) self._coarsePB.setFont(accuracy_opt_font) self._coarsePB.setFlat(True) self.layout().addWidget(self._coarsePB, 1, 2, 1, 1) self._finePB = qt.QPushButton(DetectionAccuracy.FINE.value, self) self._finePB.setFont(accuracy_opt_font) self._finePB.setFlat(True) self.layout().addWidget(self._finePB, 1, 1, 1, 1) self._accuratePB = qt.QPushButton(DetectionAccuracy.ACCURATE.value, self) self._accuratePB.setFont(accuracy_opt_font) self._accuratePB.setFlat(True) self.layout().addWidget(self._accuratePB, 1, 0, 1, 1) # connect signal / slot self._coarsePB.released.connect(self._setCoarse) self._finePB.released.connect(self._setFine) self._accuratePB.released.connect(self._setAccurate) self._accuracySlider.valueChanged.connect(self.detectionAccuracyChanged) # set up self._accuracySlider.setRange(self._MIN_RANGE, self._MAX_RANGE) self._accuracySlider.setValue(self._DEFAULT_VALUE) def _detectionAccuracyChanged(self, *args, **kwargs): self.detectionAccuracyChanged.emit() def getResearchWidth(self) -> float: """Return research width (in pixel)""" return self._accuracySlider.value() def setResearchWidth(self, width: float): """set research width :param width: center of rotation research width """ return self._accuracySlider.setValue(width) def _setCoarse(self): self._accuracySlider.setValue(ACCURACIES[DetectionAccuracy.COARSE]) def _setFine(self): self._accuracySlider.setValue(ACCURACIES[DetectionAccuracy.FINE]) def _setAccurate(self): self._accuracySlider.setValue(ACCURACIES[DetectionAccuracy.ACCURATE]) class _EstimatedCorWidget(qt.QGroupBox): _MIDDLE_COR_TXT = "middle" _OTHER_COR_TXT = "other" sigAutoCorRequested = qt.Signal() """signal emitted when the calculation of automatic cor is asked""" sigAutoCorChanged = qt.Signal() """signal emitted when the estimated cor value change""" def __init__(self, parent=None, title=None): assert title is not None self._frameWidth = None qt.QGroupBox.__init__(self, parent) self.setTitle(title) self.setLayout(qt.QGridLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self._middlePositionRB = qt.QCheckBox("middle", self) self.layout().addWidget(self._middlePositionRB, 0, 0, 1, 2) # manual definition of the cor self._manualCORAbs = qt.QDoubleSpinBox(self) self._manualCORAbs.setDecimals(4) self._manualCORAbs.setMaximum(9999999) self._manualCORAbs.setSuffix(" px") self._absLabel = qt.QLabel("absolute: ") self.layout().addWidget(self._absLabel, 1, 0, 1, 1) self.layout().addWidget(self._manualCORAbs, 1, 1, 1, 1) self._manualCORRel = qt.QDoubleSpinBox(self) self._manualCORRel.setDecimals(4) self._manualCORRel.setSuffix(" px") self._manualCORRel.setMinimum(-9999999) self._manualCORRel.setMaximum(9999999) self._relLabel = qt.QLabel("relative: ") self.layout().addWidget(self._relLabel, 2, 0, 1, 1) self.layout().addWidget(self._manualCORRel, 2, 1, 1, 1) # auto cor button self._autoCorPB = qt.QPushButton("auto cor", self) auto_cor_icon = icons.getQIcon("a") self._autoCorPB.setIcon(auto_cor_icon) self.layout().addWidget(self._autoCorPB, 3, 1, 1, 1) # connect signal / slot self._middlePositionRB.toggled.connect(self._modeChanged) self._manualCORRel.editingFinished.connect(self._relativePositionChanged) self._manualCORAbs.editingFinished.connect(self._absolutePositionChanged) self._autoCorPB.released.connect(self.sigAutoCorRequested) self._middlePositionRB.toggled.connect(self.sigAutoCorChanged) self._manualCORRel.editingFinished.connect(self.sigAutoCorChanged) self._manualCORAbs.editingFinished.connect(self.sigAutoCorChanged) # set up self._middlePositionRB.setChecked(True) self._modeChanged() def getCorValue(self, mode="relative"): assert mode in ("rel", "relative", "abs", "absolute") if self._middlePositionRB.isChecked(): if mode in ("rel", "relative"): return 0.0 elif mode in ("abs", "absolute"): if self._frameWidth is not None: return relative_pos_to_absolute( relative_pos=0.0, det_width=self._frameWidth ) else: return self._MIDDLE_COR_TXT else: raise ValueError(f"Mode {mode} is not recognized") else: if mode in ("rel", "relative"): return self._manualCORRel.value() elif mode in ("abs", "absolute"): return self._manualCORAbs.value() else: raise ValueError(f"Mode {mode} is not recognized") def _modeChanged(self, *args, **kwargs): manual_opt_visible = not self._middlePositionRB.isChecked() self._absLabel.setVisible(manual_opt_visible) self._relLabel.setVisible(manual_opt_visible) self._manualCORRel.setVisible(manual_opt_visible) self._manualCORAbs.setVisible(manual_opt_visible) self._autoCorPB.setVisible(manual_opt_visible) def _relativePositionChanged(self, *args, **kwargs): if self._frameWidth is not None: old = self.blockSignals(True) old_mcor = self._manualCORAbs.blockSignals(True) self._manualCORAbs.setValue( relative_pos_to_absolute( relative_pos=self._manualCORRel.value(), det_width=self._frameWidth ) ) self._manualCORAbs.blockSignals(old_mcor) self.blockSignals(old) def _absolutePositionChanged(self, *args, **kwargs): if self._frameWidth is not None: old = self.blockSignals(True) old_mcor = self._manualCORRel.blockSignals(True) self._manualCORRel.setValue( absolute_pos_to_relative( absolute_pos=self._manualCORAbs.value(), det_width=self._frameWidth, ) ) self._manualCORRel.blockSignals(old_mcor) self.blockSignals(old) def setFrameWidth(self, width: float): self._frameWidth = width # if necessary auto reset of the absolute value if self._manualCORAbs.value() == self._manualCORRel.value(): self._relativePositionChanged() def getFrameWidth(self) -> float: return self._frameWidth def setCorValue(self, value: str | float) -> None: """ :param value: if a float expected to be given as the relative value """ if value is None: pass elif value == self._MIDDLE_COR_TXT: self._middlePositionRB.setChecked(True) else: self._middlePositionRB.setChecked(False) self._manualCORRel.setValue(float(value)) self._manualCORRel.editingFinished.emit() def setAbsoluteCorValue(self, value: str | float): if value is None: pass elif value == self._MIDDLE_COR_TXT: self._middlePositionRB.setChecked(True) else: self._middlePositionRB.setChecked(False) self._manualCORAbs.setValue(float(value)) self._manualCORAbs.editingFinished.emit() class SAAxisOptions(qt.QWidget): """ Options of the semi-automatic center of rotation detection """ sigReconstructionSliceChanged = qt.Signal() """signal emitted when the slice to reconstruct change""" sigReconstructionRangeChanged = qt.Signal() """signal emitted when the reconstruction parameters change""" sigConfigurationChanged = qt.Signal() """signal emitted when the configuration change""" def __init__(self, parent=None): qt.QWidget.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) # reconstruction mode self._reconstructionMode = _ReconstructionModeGB(parent=self) self._reconstructionMode.setFont(FONT_MEDIUM) self.layout().addWidget(self._reconstructionMode) # estimated cor self._estimatedCorWidget = _EstimatedCorWidget( self, title="Estimated cor position (x axis)", ) self._estimatedCorWidget.setFont(FONT_IMPORTANT) self.layout().addWidget(self._estimatedCorWidget) # detection accuracy self._detectionAccuracy = _DetectionAccuracyGB(parent=self) self._detectionAccuracy.setFont(FONT_MEDIUM) self.layout().addWidget(self._detectionAccuracy) # number of reconstructions eq volume size self._nReconsWidget = qt.QWidget(parent) self._nReconsWidget.setLayout(qt.QFormLayout()) self._nReconsWidget.layout().setContentsMargins(0, 0, 0, 0) self._nReconsSB = qt.QSpinBox(self._nReconsWidget) self._nReconsSB.setRange(0, 2000) self._nReconsSB.setValue(30) self._nReconsWidget.setFont(FONT_IMPORTANT) self._nReconsWidget.layout().addRow("Number of reconstruction", self._nReconsSB) self.layout().addWidget(self._nReconsWidget) # spacer spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer) # expose API self.sigAutoCorRequested = self._estimatedCorWidget.sigAutoCorRequested # connect signal / slot self._reconstructionMode.reconstructionSliceChanged.connect( self.sigReconstructionSliceChanged ) self._nReconsSB.valueChanged.connect(self._reconstructionRangeChanged) self._estimatedCorWidget.sigAutoCorChanged.connect( self._reconstructionRangeChanged ) self._detectionAccuracy.detectionAccuracyChanged.connect( self._reconstructionRangeChanged ) def setDetectionAccuracy(self, width): if width != self._detectionAccuracy.getResearchWidth(): self._detectionAccuracy.setResearchWidth(width) self.sigConfigurationChanged.emit() def setEstimatedCorPosition(self, value): if value != self._estimatedCorWidget.getCorValue("relative"): self._estimatedCorWidget.setCorValue(value) self.sigConfigurationChanged.emit() def setEstimatedAbsoluteCorPosition(self, value): if value != self._estimatedCorWidget.getCorValue("absolute"): self._estimatedCorWidget.setAbsoluteCorValue(value) self.sigConfigurationChanged.emit() def getEstimatedCorPosition(self, *args, **kwargs): return self._estimatedCorWidget.getCorValue(*args, **kwargs) def setScan(self, scan: TomwerScanBase): if scan is not None: self.setSlicesRange(0, scan.dim_2) self._estimatedCorWidget.setFrameWidth(scan.dim_1) self._reconstructionMode.setScan(scan) def getFrameWidth(self): return self._estimatedCorWidget.getFrameWidth() def setFrameWidth(self, width): if width != self._estimatedCorWidget.getFrameWidth(): self._estimatedCorWidget.setFrameWidth(width) self.sigConfigurationChanged.emit() def getSlicesRange(self) -> tuple: self._reconstructionMode.getSlicesRange() def setSlicesRange(self, min_index, max_index): self._reconstructionMode.setSlicesRange(min_index, max_index) self.sigConfigurationChanged.emit() def _reconstructionRangeChanged(self): self.sigReconstructionRangeChanged.emit() self.sigConfigurationChanged.emit() def getReconstructionSlices(self) -> tuple: return self._reconstructionMode.getReconstructionSlices() def setReconstructionSlices(self, slices) -> tuple: return self._reconstructionMode.setReconstructionSlices(slices) def getReconstructionMode(self): return self._reconstructionMode.getReconstructionMode() def setReconstructionMode(self, mode): self._reconstructionMode.setReconstructionMode(mode) self.sigConfigurationChanged.emit() def getNReconstruction(self): return self._nReconsSB.value() def setNReconstruction(self, n): self._nReconsSB.setValue(int(n)) self.sigConfigurationChanged.emit() def getResearchWidth(self): return self._detectionAccuracy.getResearchWidth() def setResearchWidth(self, width): self._detectionAccuracy.setResearchWidth(width) self.sigConfigurationChanged.emit() class SliceAndCorWidget(qt.QMainWindow): sigConfigurationChanged = qt.Signal() """signal emitted when the configuration changed""" def __init__(self, parent=None): qt.QMainWindow.__init__(self, parent) self.setWindowFlags(qt.Qt.Widget) # sinogram viewer self._sinogramViewer = SinogramViewer(self) self._sinogramViewer.setWindowFlags(qt.Qt.Widget) self.setCentralWidget(self._sinogramViewer) # slice and accuracy options self._saaxisOpts = SAAxisOptions(self) self._dockWidgetOpts = qt.QDockWidget(self) self._dockWidgetOpts.setFixedWidth(300) self._dockWidgetOpts.setWidget(self._saaxisOpts) self.addDockWidget(qt.Qt.RightDockWidgetArea, self._dockWidgetOpts) self._dockWidgetOpts.setFeatures(qt.QDockWidget.DockWidgetMovable) # sinogram options self.sinoOprsDW = self._sinogramViewer.getOptionsDockWidget() self.addDockWidget(qt.Qt.RightDockWidgetArea, self.sinoOprsDW) self.sinoOprsDW.setFeatures(qt.QDockWidget.DockWidgetMovable) self.sinoOprsDW.setFixedWidth(300) # expose API self.getEstimatedCorPosition = self._saaxisOpts.getEstimatedCorPosition self.setEstimatedCorPosition = self._saaxisOpts.setEstimatedCorPosition self.setEstimatedAbsoluteCorPosition = ( self._saaxisOpts.setEstimatedAbsoluteCorPosition ) self.setDetectionAccuracy = self._saaxisOpts.setDetectionAccuracy self.getNReconstruction = self._saaxisOpts.getNReconstruction self.setNReconstruction = self._saaxisOpts.setNReconstruction self.getResearchWidth = self._saaxisOpts.getResearchWidth self.setResearchWidth = self._saaxisOpts.setResearchWidth self.getReconstructionSlices = self._saaxisOpts.getReconstructionSlices self.setReconstructionSlices = self._saaxisOpts.setReconstructionSlices self.getReconstructionMode = self._saaxisOpts.getReconstructionMode self.setReconstructionMode = self._saaxisOpts.setReconstructionMode self.getFrameWidth = self._saaxisOpts.getFrameWidth self.setFrameWidth = self._saaxisOpts.setFrameWidth self.getSlicesRange = self._saaxisOpts.getSlicesRange self.setSlicesRange = self._saaxisOpts.setSlicesRange self.sigStartSinogramLoad = self._sinogramViewer.sigSinoLoadStarted self.sigEndSinogramLoad = self._sinogramViewer.sigSinoLoadEnded self.sigConfigurationChanged = self._saaxisOpts.sigConfigurationChanged # expose signals self.sigReconstructionSliceChanged = ( self._saaxisOpts.sigReconstructionSliceChanged ) self.sigAutoCorRequested = self._saaxisOpts.sigAutoCorRequested self.sigReconstructionRangeChanged = ( self._saaxisOpts.sigReconstructionRangeChanged ) # connect signal / slot self._sinogramViewer.sigCorEdited.connect(self.setEstimatedAbsoluteCorPosition) self._sinogramViewer.sigWidthEdited.connect(self.setDetectionAccuracy) def loadSinogram(self): """Enforce to load a sinogram with the current settings""" self._sinogramViewer.loadSinogram() def setScan(self, scan): self._sinogramViewer.setScan(scan, update=False) self._saaxisOpts.setScan(scan) def close(self): self._sinogramViewer.close() self._sinogramViewer = None super().close() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/saaxis/dimensionwidget.py0000644000175000017500000001771115153325210025231 0ustar00paynopayno""" contains gui relative to semi-automatic axis calculation """ from __future__ import annotations import pint from typing import Iterable from silx.gui import qt from tomwer.gui.utils.qt_utils import block_signals _ureg = pint.get_application_registry() class DimensionWidget(qt.QGroupBox): """ Simple widget to display value over 3 dimensions :param parent: :param title: QGroupBox title :param dims_name: name of the dimension. If set will be store in each QDoubleLine prefix :param dims_colors: color associated to the three dimensions if any """ valuesChanged = qt.Signal() """Signal emitted when a value change""" def __init__( self, parent=None, title=None, dims_name=None, dims_colors=None, title_size=10 ): qt.QGroupBox.__init__(self, parent) self.setFont(qt.QFont("Arial", title_size)) assert title is not None assert dims_name is None or ( isinstance(dims_name, Iterable) and len(dims_name) == 3 ) assert dims_colors is None or ( isinstance(dims_colors, Iterable) and len(dims_colors) == 3 ) self._displayUnit = _ureg.millimeter self._dim0Value: pint.Quantity = 1.0 * self._displayUnit self._dim1Value: pint.Quantity = 1.0 * self._displayUnit self._dim2Value: pint.Quantity = 1.0 * self._displayUnit # defined unit to display values. Always stored in m (International # System) ## set GUI self.setTitle(title) self.setLayout(qt.QHBoxLayout()) # dim 0 self._dim0ValueQLE = qt.QDoubleSpinBox(self) if dims_name is not None: self._dim0ValueQLE.setPrefix(dims_name[0]) self._dim0ValueQLE.setRange(0, 999999999999) self._dim0ValueQLE.setDecimals(10) self._dim0ValueQLE.setSingleStep(0.0001) self._dim0ValueQLE.setValue(self._dim0Value.magnitude) if dims_colors is not None: stylesheet = f"background-color: {dims_colors[0]}" self._dim0ValueQLE.setStyleSheet(stylesheet) self.layout().addWidget(self._dim0ValueQLE) # dim 1 self._dim1ValueQLE = qt.QDoubleSpinBox(self) if dims_name is not None: self._dim1ValueQLE.setPrefix(dims_name[1]) self._dim1ValueQLE.setRange(0, 999999999999) self._dim1ValueQLE.setDecimals(10) self._dim1ValueQLE.setSingleStep(0.0001) self._dim1ValueQLE.setValue(self._dim1Value.magnitude) if dims_colors is not None: stylesheet = f"background-color: {dims_colors[1]}" self._dim1ValueQLE.setStyleSheet(stylesheet) self.layout().addWidget(self._dim1ValueQLE) # dim 2 self._dim2ValueQLE = qt.QDoubleSpinBox(self) if dims_name is not None: self._dim2ValueQLE.setPrefix(dims_name[2]) self._dim2ValueQLE.setRange(0, 999999999999) self._dim2ValueQLE.setDecimals(10) self._dim2ValueQLE.setSingleStep(0.0001) self._dim2ValueQLE.setValue(self._dim2Value.magnitude) if dims_colors is not None: stylesheet = f"background-color: {dims_colors[2]}" self._dim2ValueQLE.setStyleSheet(stylesheet) self.layout().addWidget(self._dim2ValueQLE) # set up self.setUnit(self._displayUnit) # connect signal / slot self._dim0ValueQLE.editingFinished.connect(self._userSetDim0) self._dim1ValueQLE.editingFinished.connect(self._userSetDim1) self._dim2ValueQLE.editingFinished.connect(self._userSetDim2) def setUnit(self, unit: pint.Unit): """ define with which unit we should display the size :param unit: metric to be used for display. Internally this is always stored using the international metric system """ if not isinstance(unit, pint.Unit): raise TypeError( f"unit is expected be an instance of {pint.Unit}. Got {type(unit)}" ) for widget in (self._dim0ValueQLE, self._dim1ValueQLE, self._dim2ValueQLE): widget.setSuffix(f"{self._displayUnit:.4f~P}") # convert current values self._dim0Value = self._dim0Value.magnitude * self._displayUnit self._dim1Value = self._dim1Value.magnitude * self._displayUnit self._dim2Value = self._dim2Value.magnitude * self._displayUnit # update displayed values with block_signals(self): self._dim0ValueQLE.setValue(self._dim0Value.magnitude) self._dim1ValueQLE.setValue(self._dim1Value.magnitude) self._dim2ValueQLE.setValue(self._dim2Value.magnitude) def setQuantities( self, dim0: pint.Quantity, dim1: pint.Quantity, dim2: pint.Quantity, ) -> None: """ :param dim0: value to dim0 :param dim1: value to dim1 :param dim2: value to dim2 :param unit: unit used for the provided values """ with block_signals(self): self.setDim0Quantity(value=dim0) self.setDim1value(value=dim1) self.setDim2Quantity(value=dim2) self.valuesChanged.emit() def getQuantities( self, cast_unit_to: None | pint.Unit = None ) -> tuple[pint.Quantity]: """ :param cast_unit_to: if given will cast the quantities to the requested unit :return: (dim0 value, dim1 value, dim2 value) """ if cast_unit_to is None: return ( self.getDim0Quantity(), self.getDim1Quantity(), self.getDim2Quantity(), ) else: return ( self.getDim0Quantity().to(cast_unit_to), self.getDim1Quantity().to(cast_unit_to), self.getDim2Quantity().to(cast_unit_to), ) def getDim0Quantity(self) -> tuple: """Return Dim 0 value and unit. Unit is always meter""" return self._dim0Value def setDim0Quantity(self, value: pint.Quantity): """ :param value: value to set to dim 0. :return: """ assert isinstance(value, pint.Quantity) self._dim0Value = value with block_signals(self): self._dim0ValueQLE.setValue(self._dim0Value.magnitude) self.valuesChanged.emit() def getDim1Quantity(self) -> pint.Quantity: """Return Dim 1 Quantity""" return self._dim1Value def setDim1value(self, value: pint.Quantity): """ :param value: value to set to dim 1. :return: """ assert isinstance(value, pint.Quantity) self._dim1Value = value with block_signals(self): self._dim1ValueQLE.setValue(self._dim1Value.magnitude) self.valuesChanged.emit() def getDim2Quantity(self) -> pint.Quantity: """Return Dim 2 value and unit. Unit is always meter""" return self._dim2Value def setDim2Quantity(self, value: pint.Quantity): """ :param value: value to set to dim 2. :return: """ assert isinstance(value, pint.Quantity) self._dim2Value = value with block_signals(self): self._dim2ValueQLE.setValue(self._dim2Value.magnitude) self.valuesChanged.emit() def _valuesChanged(self, *args, **kwargs): self.valuesChanged.emit() def _userSetDim0(self): """callback when the user modify the dim 0 QDSP""" with block_signals(self): self._dim0Value = self._dim0ValueQLE.value() * self._displayUnit self.valuesChanged.emit() def _userSetDim1(self): """callback when the user modify the dim 1 QDSP""" with block_signals(self): self._dim1Value = self._dim1ValueQLE.value() * self._displayUnit self.valuesChanged.emit() def _userSetDim2(self): """callback when the user modify the dim 2 QDSP""" with block_signals(self): self._dim2Value = self._dim2ValueQLE.value() * self._displayUnit self.valuesChanged.emit() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/saaxis/saaxis.py0000644000175000017500000005366515153325210023340 0ustar00paynopayno""" contains gui relative to semi-automatic axis calculation """ from __future__ import annotations import logging import numpy from silx.gui import qt from tomwer.core.process.reconstruction.axis import mode as axis_mode from tomwer.core.process.reconstruction.nabu.utils import _NabuMode, slice_index_to_int from tomwer.core.process.reconstruction.saaxis.params import SAAxisParams from tomwer.core.process.reconstruction.saaxis.saaxis import ( SAAxisTask, _is_margin_too_large, ) from tomwer.core.process.reconstruction.nabu.utils import _NabuPhaseMethod from tomwer.gui import icons from tomwer.gui.reconstruction.axis.CalculationWidget import CalculationWidget from tomwer.gui.reconstruction.nabu.platform import NabuPlatformSettings from tomwer.gui.reconstruction.saaxis.corrangeselector import SliceAndCorWidget from tomwer.gui.reconstruction.scores.control import ControlWidget from tomwer.gui.reconstruction.scores.scoreplot import CorSelection from tomwer.gui.reconstruction.scores.scoreplot import ScorePlot as _ScorePlot from tomwer.gui.utils.buttons import TabBrowsersButtons from tomwer.gui.utils.scandescription import ScanNameLabelAndShape from tomwer.gui.settings import TAB_LABEL_PLATFORM_SETTINGS from tomwer.gui.reconstruction.sacommon import NabuWidgetWithToolbar as NabuWidget from tomwer.core.utils.char import BETA_CHAR, DELTA_CHAR from tomwer.synctools.axis import QAxisRP _logger = logging.getLogger(__file__) class ScorePlot(_ScorePlot, constructor=CorSelection): """Score plot dedicated to center of rotation. Redefine the current score value to display both the absolute and the relative values """ def _updateScores(self): scan = self.__scan() if self.__scan else None img_width = None if scan is not None: if scan.saaxis_params: scan.saaxis_params.score_method = self.getScoreMethod() img_width = scan.dim_1 # update autofocus SAAxisTask.autofocus(scan) self.setVarScores( scores=self._scores, score_method=self.getScoreMethod(), img_width=img_width, update_only_scores=True, ) def _applyAutofocus(self): scan = self.__scan() if self.__scan else None if scan is None: return if scan.saaxis_params: best_cor = scan.saaxis_params.autofocus if best_cor: self._varSlider.setVarValue(best_cor) class NabuAutoCorDiag(qt.QDialog): """ GUI to compute an estimation of the Center Of Rotation """ class CalculationWidget(CalculationWidget): def _modeChanged(self, *args, **kwargs): super()._modeChanged() self.getMethodLockPB().hide() sigRequestAutoCor = qt.Signal() """emit when user request auto cor""" def __init__(self, parent=None, qarixrp=None): assert qarixrp is not None, "An instance of QAxisRP should be provided" qt.QDialog.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) self._automatic_cor = NabuAutoCorDiag.CalculationWidget( parent=self, axis_params=qarixrp, ) self._automatic_cor.getMethodLockPB().hide() qcb = self._automatic_cor._qcbPosition for mode in (axis_mode.AxisMode.manual,): idx = qcb.findText(mode.value) if idx >= 0: qcb.removeItem(idx) self.layout().addWidget(self._automatic_cor) spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer) # buttons types = qt.QDialogButtonBox.Ok self._buttons = qt.QDialogButtonBox(parent=self) self._buttons.setStandardButtons(types) self.layout().addWidget(self._buttons) self._buttons.button(qt.QDialogButtonBox.Ok).clicked.connect( self.sigRequestAutoCor ) self._buttons.button(qt.QDialogButtonBox.Ok).setText("compute") class _SAAxisTabWidget(qt.QTabWidget): sigConfigurationChanged = qt.Signal() """signal emitted each time the 'input' configuration changed. like slice to reconstruct, number of reconstruction, research width, nabu reconstruction parameters...""" def __init__(self, parent, backend=None): qt.QTabWidget.__init__(self, parent) # select slice & cor range self._sliceAndCorWidget = SliceAndCorWidget(self) sinogram_icon = icons.getQIcon("sinogram") self.addTab(self._sliceAndCorWidget, sinogram_icon, "slice && cor range") # nabu reconstruction parameters self._nabuSettings = NabuWidget(self) self._nabuSettings.setConfigurationLevel(level="required") self._nabuSettings.hideSlicesInterface() nabu_icon = icons.getQIcon("nabu") self.addTab(self._nabuSettings, nabu_icon, "reconstruction settings") # platform settings self._localPlatformSettings = NabuPlatformSettings(self) settings_icons = icons.getQIcon("parameters") self.addTab( self._localPlatformSettings, settings_icons, TAB_LABEL_PLATFORM_SETTINGS ) # results self._resultsViewer = ScorePlot(self, variable_name="cor", backend=backend) results_icon = icons.getQIcon("results") self.addTab(self._resultsViewer, results_icon, "reconstructed slices") # connect signal / slot self._nabuSettings.sigConfigChanged.connect(self._configurationChanged) self._sliceAndCorWidget.sigConfigurationChanged.connect( self._configurationChanged ) self._resultsViewer.sigConfigurationChanged.connect(self._configurationChanged) self.sigReconstructionSliceChanged = ( self._sliceAndCorWidget.sigReconstructionSliceChanged ) self.sigAutoCorRequested = self._sliceAndCorWidget.sigAutoCorRequested self.sigReconstructionRangeChanged = ( self._sliceAndCorWidget.sigReconstructionRangeChanged ) # expose function API self.setCorScores = self._resultsViewer.setVarScores self.setImgWidth = self._resultsViewer.setImgWidth self.setVoxelSize = self._resultsViewer.setVoxelSize self.setVolumeSize = self._resultsViewer.setVolumeSize self.setCurrentCorValue = self._resultsViewer.setCurrentVarValue self.getCurrentCorValue = self._resultsViewer.getCurrentVarValue self.getEstimatedCorPosition = self._sliceAndCorWidget.getEstimatedCorPosition self.setEstimatedCorPosition = self._sliceAndCorWidget.setEstimatedCorPosition self.getNReconstruction = self._sliceAndCorWidget.getNReconstruction self.setNReconstruction = self._sliceAndCorWidget.setNReconstruction self.getResearchWidth = self._sliceAndCorWidget.getResearchWidth self.setResearchWidth = self._sliceAndCorWidget.setResearchWidth self.getReconstructionSlices = self._sliceAndCorWidget.getReconstructionSlices self.setReconstructionSlices = self._sliceAndCorWidget.setReconstructionSlices self.getReconstructionMode = self._sliceAndCorWidget.getReconstructionMode self.setReconstructionMode = self._sliceAndCorWidget.setReconstructionMode self.getFrameWidth = self._sliceAndCorWidget.getFrameWidth self.setFrameWidth = self._sliceAndCorWidget.setFrameWidth self.setNabuReconsParams = self._nabuSettings.setConfiguration self.getNabuReconsParams = self._nabuSettings.getConfiguration self.getSlicesRange = self._sliceAndCorWidget.getSlicesRange self.setSlicesRange = self._sliceAndCorWidget.setSlicesRange self.loadSinogram = self._sliceAndCorWidget.loadSinogram self.saveReconstructedSlicesTo = self._resultsViewer.saveReconstructedSlicesTo # expose signals self.sigStartSinogramLoad = self._sliceAndCorWidget.sigStartSinogramLoad self.sigEndSinogramLoad = self._sliceAndCorWidget.sigEndSinogramLoad def showResults(self): self.setCurrentWidget(self._resultsViewer) def _configurationChanged(self, *args, **kwargs): self.sigConfigurationChanged.emit() def lockAutoFocus(self, lock): self._resultsViewer.lockAutoFocus(lock=lock) def isAutoFocusLock(self): return self._resultsViewer.isAutoFocusLock() def hideAutoFocusButton(self): self._resultsViewer.hideAutoFocusButton() def getSinogramViewer(self): return self._sliceAndCorWidget._sinogramViewer def getCors(self, reference: str = "relative"): """Return cors to be computed""" if reference not in ("relative", "absolute"): raise ValueError("reference should be 'absolute' or 'relative'") return SAAxisParams.compute_cors( estimated_cor=self.getEstimatedCorPosition(reference), research_width=self.getResearchWidth(), n_reconstruction=self.getNReconstruction(), ) def loadPreprocessingParams(self): """load reconstruction nabu if tomwer has already process this dataset. Not done for now""" return False def setScan(self, scan): self._resultsViewer.setScan(scan) self._nabuSettings.setScan(scan) if self.loadPreprocessingParams() and scan.axis_params is not None: self._nabuSettings.setConfiguration(scan.axis_params) self._sliceAndCorWidget.setScan(scan) def getConfiguration(self): nabu_config = self.getNabuReconsParams() enable_ht = int(self._nabuSettings.getMode() is _NabuMode.HALF_ACQ) nabu_config["reconstruction"]["enable_halftomo"] = enable_ht return { "research_width": self.getResearchWidth(), "n_reconstruction": self.getNReconstruction(), "slice_index": self.getReconstructionSlices(), "nabu_params": nabu_config, "mode": self.getReconstructionMode().value, "score_method": self.getScoreMethod().value, "estimated_cor": self.getEstimatedCorPosition(), "output_dir": self.getNabuReconsParams() .get("output", {}) .get("location", None) or None, } def setConfiguration(self, config): if isinstance(config, SAAxisParams): config = config.to_dict() if not isinstance(config, dict): raise TypeError( f"config should be a dictionary or a SAAxisParams. Not {type(config)}" ) research_width = config.get("research_width", None) if research_width is not None: self.setResearchWidth(research_width) n_reconstruction = config.get("n_reconstruction", None) if n_reconstruction is not None: self.setNReconstruction(n_reconstruction) estimated_cor = config.get("estimated_cor", None) if estimated_cor is not None: self.setEstimatedCorPosition(estimated_cor) slice_indexes = config.get("slice_index", None) if slice_indexes is not None: self.setReconstructionSlices(slice_indexes) if "nabu_params" in config: self.setNabuReconsParams(config["nabu_params"]) if "mode" in config: self.setReconstructionMode(config["mode"]) if "score_method" in config: self.setScoreMethod(config["score_method"]) def getScoreMethod(self): return self._resultsViewer.getScoreMethod() def setScoreMethod(self, method): self._resultsViewer.setScoreMethod(method) def close(self): self._resultsViewer.close() self._resultsViewer = None self._sliceAndCorWidget.close() self._sliceAndCorWidget = None self._nabuSettings.close() self._nabuSettings = None super().close() class SAAxisWindow(qt.QMainWindow): """ Widget used to determine half-automatically the center of rotation """ _MARGIN_LIMIT_WARNING = 100 def __init__(self, parent=None, backend=None): qt.QMainWindow.__init__(self, parent) self._scan = None self._automaticCorWidget = None self._qaxis_rp = QAxisRP() self.setWindowFlags(qt.Qt.Widget) # central widget self._mainWidget = qt.QWidget(self) self._mainWidget.setLayout(qt.QVBoxLayout()) self._scanInfo = ScanNameLabelAndShape(self) self._mainWidget.layout().addWidget(self._scanInfo) self._tabWidget = _SAAxisTabWidget(self, backend=backend) self._mainWidget.layout().addWidget(self._tabWidget) self.setCentralWidget(self._mainWidget) # next and previous buttons for browsing the tab widget self._browserButtons = TabBrowsersButtons(self) self._dockWidgetBrwButtons = qt.QDockWidget(self) self._dockWidgetBrwButtons.setWidget(self._browserButtons) self.addDockWidget(qt.Qt.BottomDockWidgetArea, self._dockWidgetBrwButtons) self._dockWidgetBrwButtons.setFeatures(qt.QDockWidget.DockWidgetMovable) # control widget (validate, compute, cor positions) self._saaxisControl = ControlWidget(self) self._dockWidgetCtrl = qt.QDockWidget(self) self._dockWidgetCtrl.setWidget(self._saaxisControl) self.addDockWidget(qt.Qt.BottomDockWidgetArea, self._dockWidgetCtrl) self._dockWidgetCtrl.setFeatures(qt.QDockWidget.DockWidgetMovable) # expose API self.setCorScores = self._tabWidget.setCorScores self.setImgWidth = self._tabWidget.setImgWidth self.setVoxelSize = self._tabWidget.setVoxelSize self.setVolumeSize = self._tabWidget.setVolumeSize self.setCurrentCorValue = self._tabWidget.setCurrentCorValue self.getCurrentCorValue = self._tabWidget.getCurrentCorValue self.getEstimatedCorPosition = self._tabWidget.getEstimatedCorPosition self.setEstimatedCorPosition = self._tabWidget.setEstimatedCorPosition self.getNReconstruction = self._tabWidget.getNReconstruction self.setNReconstruction = self._tabWidget.setNReconstruction self.getResearchWidth = self._tabWidget.getResearchWidth self.setResearchWidth = self._tabWidget.setResearchWidth self.getReconstructionSlices = self._tabWidget.getReconstructionSlices self.setReconstructionSlices = self._tabWidget.setReconstructionSlices self.getNabuReconsParams = self._tabWidget.getNabuReconsParams self.setNabuReconsParams = self._tabWidget.setNabuReconsParams self.getSlicesRange = self._tabWidget.getSlicesRange self.setSlicesRange = self._tabWidget.setSlicesRange self.getCors = self._tabWidget.getCors self.getMode = self._tabWidget.getReconstructionMode self.loadSinogram = self._tabWidget.loadSinogram self.saveReconstructedSlicesTo = self._tabWidget.saveReconstructedSlicesTo # expose signals self.sigValidated = self._saaxisControl.sigValidateRequest self.sigStartSinogramLoad = self._tabWidget.sigStartSinogramLoad self.sigEndSinogramLoad = self._tabWidget.sigEndSinogramLoad self.sigConfigurationChanged = self._tabWidget.sigConfigurationChanged # connect signal / slot self._tabWidget.sigReconstructionSliceChanged.connect(self._updateSinogramLine) self._tabWidget.sigAutoCorRequested.connect(self._autoCorRequested) self._tabWidget.sigReconstructionRangeChanged.connect( self._estimatedCorValueChanged ) self._browserButtons.sigNextReleased.connect(self._showNextPage) self._browserButtons.sigPreviousReleased.connect(self._showPreviousPage) self._saaxisControl.sigComputationRequest.connect(self._launchReconstructions) self._saaxisControl.sigValidateRequest.connect(self._validate) def showResults(self): self._tabWidget.showResults() def getAutomaticCorWindow(self): if self._automaticCorWidget is None: self._automaticCorWidget = NabuAutoCorDiag(self, qarixrp=self._qaxis_rp) self._automaticCorWidget.setWindowTitle( "compute estimated center of rotation" ) auto_cor_icon = icons.getQIcon("a") self._automaticCorWidget.setWindowIcon(auto_cor_icon) self._automaticCorWidget.sigRequestAutoCor.connect( self._computeEstimatedCor ) return self._automaticCorWidget def compute(self): """force compute of the current scan""" self._saaxisControl.sigComputationRequest.emit() def getConfiguration(self) -> dict: return self._tabWidget.getConfiguration() def setConfiguration(self, config: dict): self._tabWidget.setConfiguration(config) def getQAxisRP(self): return self._qaxis_rp def setScan(self, scan): self._scan = scan self._tabWidget.setScan(scan) self._scanInfo.setScan(scan) self._updateSinogramLine() self._loadEstimatedCorFromScan(scan) def _loadEstimatedCorFromScan(self, scan): if scan.axis_params is not None: relative_cor = scan.axis_params.relative_cor_value else: relative_cor = None if relative_cor is None: relative_cor = scan.x_rotation_axis_pixel_position if relative_cor is not None and numpy.issubdtype( type(relative_cor), numpy.number ): self.setEstimatedCorPosition(relative_cor) def getScan(self): return self._scan def getScoreMethod(self): return self._tabWidget.getScoreMethod() def lockAutofocus(self, lock): self._tabWidget.lockAutoFocus(lock=lock) def isAutoFocusLock(self): return self._tabWidget.isAutoFocusLock() def hideAutoFocusButton(self): return self._tabWidget.hideAutoFocusButton() def _updateSinogramLine(self): r_slice = self.getReconstructionSlices() if r_slice == "middle": line = slice_index_to_int(slice_index="middle", scan=self._scan, axis="XY") else: line = list(r_slice.values())[0] self._tabWidget.getSinogramViewer().setLine(line) def _autoCorRequested(self): window = self.getAutomaticCorWindow() window.activateWindow() window.raise_() window.show() def _computeEstimatedCor(self) -> float | None: """callback when calculation of a estimated cor is requested. Should be implemted by OrangeWidget or application""" raise NotImplementedError("Base class") def _launchReconstructions(self): """callback when we want to launch the reconstruction of the slice for n cor value""" raise NotImplementedError("Base class") def _validate(self): raise NotImplementedError("Base class") def _estimatedCorValueChanged(self): cors = self.getCors("absolute") sino_viewer = self._tabWidget._sliceAndCorWidget._sinogramViewer estimated_cor = self.getEstimatedCorPosition("absolute") if estimated_cor == "middle": estimated_cor = 0 if len(cors) < 2: return elif len(cors) > 2: other_cors = cors[1:-1] else: other_cors = () sino_viewer.setCorRange( cor_min=cors[0], cor_max=cors[-1], estimated_cor=estimated_cor, other_cors=other_cors, ) def _showNextPage(self, *args, **kwargs): idx = self._tabWidget.currentIndex() idx += 1 if idx < self._tabWidget.count(): self._tabWidget.setCurrentIndex(idx) def _showPreviousPage(self, *args, **kwargs): idx = self._tabWidget.currentIndex() idx -= 1 if idx >= 0: self._tabWidget.setCurrentIndex(idx) def close(self): self._tabWidget.close() self._tabWidget = None super().close() def _checkCancelProcessingForMargins(self) -> bool: """ Check if the current reconstruction settings might lead to nabu multi-cor not being able to reconstruct the volume """ if self._isReconstructionMightFail( nabu_params=self.getConfiguration()["nabu_params"], margin_threshold=self._MARGIN_LIMIT_WARNING, ): answer = qt.QMessageBox.warning( self, "Multi-cor might fail", f"The execution of the current configuration might fail.\n" f"Because phase retrieval is enabled and {DELTA_CHAR} / {BETA_CHAR} is large.\n" f"Please consider editing the parameters to disable phase retrieval or decrease {DELTA_CHAR} / {BETA_CHAR}.\n\n" "Do you still want to run Multi‑Cor with these settings?", qt.QMessageBox.Ok | qt.QMessageBox.Cancel, qt.QMessageBox.Cancel, ) return answer == qt.QMessageBox.Cancel return False def _isReconstructionMightFail( self, nabu_params: dict, margin_threshold: int ) -> bool: # see https://gitlab.esrf.fr/tomotools/tomwer/-/issues/1533 scan = self.getScan() if scan is None: _logger.debug( "No scan found. Unable to predict if the reconstruction might fail." ) return False if nabu_params["phase"]["method"] not in ( _NabuPhaseMethod.PAGANIN.value, _NabuPhaseMethod.CTF.value, ): return False try: return _is_margin_too_large( dims=(scan.dim_2, scan.dim_1), delta_beta=float(nabu_params["phase"]["delta_beta"]), energy_kev=float(scan.energy), pixel_size=float(scan.pixel_size), sample_detector_distance=float(scan.sample_detector_distance), margin_threshold=margin_threshold, ) except Exception as e: _logger.info(f"Failed to check reconstruction margins. Error is {e}") def _get_circle_plot(center, radius, n_pts=1000): pts = numpy.linspace(-numpy.pi, numpy.pi, n_pts) x = radius * numpy.cos(pts) + center[0] y = radius * numpy.sin(pts) + center[1] return x, y ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/saaxis/sliceselector.py0000644000175000017500000002520315153325210024673 0ustar00paynopayno# coding: utf-8 from __future__ import annotations """ contains gui to select a slice in a volume """ import functools import numpy from silx.gui import qt from silx.gui.plot import PlotWidget class SliceSelector(qt.QWidget): """ Allow definition of n slices with a volume slice selector and spin boxes :param insert: if True add spin boxes at the beginning of the layout otherwise append them :param invert_y_axis: will be provided to silx plot """ sigSlicesChanged = qt.Signal() """signal emitted when slices value change""" def __init__(self, parent=None, insert: bool = True, invert_y_axis: bool = False): self._updatePlaneFrmSBLock = False self._insert = insert self._slicesQSB = [] qt.QWidget.__init__(self, parent) self.setLayout(qt.QBoxLayout(qt.QBoxLayout.BottomToTop)) self._volumeView = _SliceSelectorFrmVolume(self, invert_y_axis=invert_y_axis) self.layout().addWidget(self._volumeView) def setSlicesRange(self, min_index, max_index): self._volumeView.setSlicesRange(min_index, max_index) for widget in self._slicesQSB: widget.sliceSB.setRange(min_index, max_index) def clearSlices(self): self._volumeView.clearSlices() for sliceQSB in self._slicesQSB: self.layout().removeWidget(sliceQSB) self._slicesQSB.clear() def addSlice(self, value, name, color): self._volumeView.addSlice(value=value, name=name, color=color) # create the spin box widget = qt.QWidget(self) widget.setLayout(qt.QHBoxLayout()) widget.layout().setContentsMargins(0, 0, 0, 0) widget.layout().addWidget(qt.QLabel(name, self)) sb = qt.QSpinBox(self) stylesheet = f"background-color: {color}" sb.setStyleSheet(stylesheet) min_i, max_i = self.getSlicesRange() sb.setRange(min_i, max_i) sb.setValue(value) widget.sliceSB = sb widget.layout().addWidget(sb) if self._insert: self.layout().insertWidget(0, widget) else: self.layout().addWidget(widget) self._slicesQSB.append(widget) # connect signal / slot sb.valueChanged.connect(functools.partial(self._updatePlaneFrmSB, name, sb)) sb.valueChanged.connect(self._slicesChanged) marker = self._volumeView._getMarker(self._volumeView.getMarkerName(name)) marker.sigDragFinished.connect( functools.partial(self._updateSBFrmMarker, sb, marker) ) marker.sigDragFinished.connect(self._slicesChanged) # TODO: we might want to change the plane position when moving the # marker. This would require to add a loop when drag start and stop # it when drag is finished def _slicesChanged(self): if not self._updatePlaneFrmSBLock: self.sigSlicesChanged.emit() def _updatePlaneFrmSB(self, name: str, sb: qt.QSpinBox): """callback when a spin box value change from user input""" self._updatePlaneFrmSBLock = True old = self._volumeView.blockSignals(True) marker = self._volumeView._getMarker(self._volumeView.getMarkerName(name)) marker.setPosition(x=0, y=self._volumeView.valueToPlotSpace(value=sb.value())) marker.sigDragFinished.emit() self._volumeView.blockSignals(old) self._updatePlaneFrmSBLock = False def _updateSBFrmMarker(self, sb: qt.QSpinBox, marker): if not self._updatePlaneFrmSBLock: position = self._volumeView.plotSpaceToValue(marker.getPosition()[1]) sb.setValue(position) # expose API def getSlicesValue(self) -> dict: return self._volumeView.getSlicesValue() def setSliceValue(self, name: str, value: float): self._volumeView.setSliceValue(name=name, value=value) def getSlicesRange(self) -> tuple: return self._volumeView.getSlicesRange() class _SliceSelectorFrmVolume(PlotWidget): """ Allow definition of n slices on a volume """ sigSlicesChanged = qt.Signal() """signal emitted when slices value change""" ORIENTATION = -numpy.pi / 2.0 LOW_RADIUS = 0.4 HIGH_RADIUS = 1.0 HEIGHT = 3.0 PLOT_MARGINS = 1.0 def __init__(self, parent=None, invert_y_axis=False): self._yAxisInverted = invert_y_axis PlotWidget.__init__(self, parent) self.setAxesDisplayed(False) self._plotVolume() self.getXAxis().setLimits(-(self.PLOT_MARGINS + 0.5), self.PLOT_MARGINS + 0.5) self.getYAxis().setLimits(-self.PLOT_MARGINS, self.HEIGHT + self.PLOT_MARGINS) self._slices = [] self._slicesRange = (0, 1) # Retrieve PlotWidget's plot area widget plotArea = self.getWidgetHandle() # Set plot area custom context menu plotArea.setContextMenuPolicy(qt.Qt.CustomContextMenu) plotArea.customContextMenuRequested.connect(self._contextMenu) self.setInteractiveMode("select", zoomOnWheel=False) self.setPanWithArrowKeys(False) def _contextMenu(self, pos: qt.QPoint): """Handle plot area customContextMenuRequested signal. :param pos: Mouse position relative to plot area """ # avoir rest zoom action pass def setSlicesRange(self, min_index, max_index): if not isinstance(min_index, int): raise TypeError("Invalid type") if not isinstance(max_index, int): raise TypeError("Invalid type") slice_values = self.getSlicesValue() self._slicesRange = ( float(min(min_index, max_index)), float(max(min_index, max_index)), ) for slice_name, slice_value in slice_values.items(): try: self.setSliceValue(name=slice_name, value=slice_value) except Exception: pass def getSlicesRange(self) -> tuple: return self._slicesRange def _plotVolume(self): nbpoints = 60 angles = numpy.arange(nbpoints) * 2.0 * numpy.pi / nbpoints # draw ellipsis for y_offset, legend in zip( (0, self.HEIGHT), ("lower_ellipsis", "higher_ellipsis") ): X = self.LOW_RADIUS * numpy.cos(angles) * numpy.cos( self.ORIENTATION ) - self.HIGH_RADIUS * numpy.sin(angles) * numpy.sin(self.ORIENTATION) Y = self.LOW_RADIUS * numpy.cos(angles) * numpy.sin( self.ORIENTATION ) + self.HIGH_RADIUS * numpy.sin(angles) * numpy.cos(self.ORIENTATION) X = list(X) X.append(X[0]) X = numpy.array(X) Y = list(Y) Y.append(Y[0]) Y = numpy.array(Y) self.addCurve(X, Y + y_offset, legend=legend, color="gray") # draw sides self.addCurve((-1, -1), (0, self.HEIGHT), legend="left side", color="gray") self.addCurve((1, 1), (0, self.HEIGHT), legend="right side", color="gray") def addSlice(self, value, name, color): """ :param value: :param name: """ value = min(max(value, self._slicesRange[0]), self._slicesRange[1]) self._addSliceAnchor(value, name, color) self._slices.append(name) def clearSlices(self): self._slices.clear() def valueToPlotSpace(self, value): value = numpy.clip(value, self._slicesRange[0], self._slicesRange[1]) if self._yAxisInverted: value = self._slicesRange[1] - value value = (value - self._slicesRange[0]) / ( self._slicesRange[1] - self._slicesRange[0] ) return value * self.HEIGHT def plotSpaceToValue(self, y): value = y / self.HEIGHT res = int( value * (self._slicesRange[1] - self._slicesRange[0]) + self._slicesRange[0] ) if self._yAxisInverted: res = self._slicesRange[1] - res return int(res) def _updatePlane(self, y, curve_name, color): anchor_shift = 0.2 nbpoints = 4 angles = numpy.arange(nbpoints) * 2.0 * numpy.pi / nbpoints X = self.LOW_RADIUS * numpy.cos(angles) * numpy.cos( self.ORIENTATION ) - self.HIGH_RADIUS * numpy.sin(angles) * numpy.sin(self.ORIENTATION) Y = self.LOW_RADIUS * numpy.cos(angles) * numpy.sin( self.ORIENTATION ) + self.HIGH_RADIUS * numpy.sin(angles) * numpy.cos(self.ORIENTATION) y_min = y + min(Y) y_max = y + max(Y) x_min = min(X) x_max = max(X) xs = ( x_min + anchor_shift, x_max + anchor_shift, x_max - anchor_shift, x_min - anchor_shift, x_min + anchor_shift, ) self.addCurve( x=xs, y=(y_max, y_max, y_min, y_min, y_max), legend=curve_name, color=color, resetzoom=False, ) self.sigSlicesChanged.emit() def getMarkerName(self, name: str): return f"marker_{name}" def _addSliceAnchor(self, value, curve_name, color): y_value = self.valueToPlotSpace(value=value) old = self.blockSignals(True) self._updatePlane(y=y_value, curve_name=curve_name, color=color) marker_name = self.getMarkerName(curve_name) self.addYMarker(y=y_value, color=color, legend=marker_name, draggable=True) marker = self._getMarker(marker_name) if marker: marker.setLineStyle("--") marker.sigDragFinished.connect( functools.partial( self._updateSlicePlane, marker_name, curve_name, color ) ) self.blockSignals(old) def _updateSlicePlane(self, marker_name, curve_name, color): marker = self._getMarker(marker_name) if marker: if marker.getPosition()[1] < 0: marker.setPosition(0, 0) elif marker.getPosition()[1] > self.HEIGHT: marker.setPosition(0, self.HEIGHT) self._updatePlane( y=marker.getPosition()[1], curve_name=curve_name, color=color ) def getSlicesValue(self) -> dict: """ :return: dict with slice name as key and value as value """ res = {} for slice_ in self._slices: marker = self._getMarker(self.getMarkerName(slice_)) if marker: res[slice_] = int(self.plotSpaceToValue(marker.getPosition()[1])) return res def setSliceValue(self, name: str, value: float): if name not in self._slices: return marker = self._getMarker(self.getMarkerName(name)) marker.setPosition(0, self.valueToPlotSpace(float(value))) marker.sigDragFinished.emit() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/sacommon.py0000644000175000017500000001353615153325210022365 0ustar00paynopaynofrom __future__ import annotations import os from nabu.pipeline.config import parse_nabu_config_file from tomwer.gui.configuration.action import ( BasicConfigurationAction, ExpertConfigurationAction, MinimalisticConfigurationAction, ) from silx.gui import qt from nabu.pipeline.config import get_default_nabu_config from nabu.pipeline.fullfield.nabu_config import ( nabu_config as nabu_fullfield_default_config, ) from tomwer.gui.reconstruction.nabu.slices import NabuWidget from tomwer.gui.configuration.level import ConfigurationLevel class NabuWidgetWithToolbar(qt.QMainWindow): sigConfigChanged = qt.Signal() def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setWindowFlags(qt.Qt.Widget) self._nabuSettings = NabuWidget(parent=self) self.setCentralWidget(self._nabuSettings) self._createNabuSettingsToolbar() # connect signal / slot self._nabuSettings.sigConfigChanged.connect(self.sigConfigChanged) def _createNabuSettingsToolbar(self): style = qt.QApplication.style() # add toolbar toolbar = qt.QToolBar(self) toolbar.setMovable(False) toolbar.setFloatable(False) self.addToolBar(qt.Qt.TopToolBarArea, toolbar) # add configuration mode self.__configurationModesAction = qt.QAction(self) self.__configurationModesAction.setCheckable(False) menu = qt.QMenu(self) self.__configurationModesAction.setMenu(menu) toolbar.addAction(self.__configurationModesAction) self.__configurationModesGroup = qt.QActionGroup(self) self.__configurationModesGroup.setExclusive(True) self.__configurationModesGroup.triggered.connect(self._userModeChanged) self._minimalisticAction = MinimalisticConfigurationAction(toolbar) menu.addAction(self._minimalisticAction) self.__configurationModesGroup.addAction(self._minimalisticAction) self._basicConfigAction = BasicConfigurationAction(toolbar) menu.addAction(self._basicConfigAction) self.__configurationModesGroup.addAction(self._basicConfigAction) self._expertConfiguration = ExpertConfigurationAction(toolbar) menu.addAction(self._expertConfiguration) self.__configurationModesGroup.addAction(self._expertConfiguration) # reset configuration option self.__resetAction = qt.QAction(self) self.__resetAction.setToolTip("reset nabu configuration") reset_icon = style.standardIcon(qt.QStyle.SP_DialogResetButton) self.__resetAction.setIcon(reset_icon) toolbar.addAction(self.__resetAction) self.__resetAction.triggered.connect(self._resetParameters) # toolbar spacer self.__tSpacer = qt.QWidget(toolbar) self.__tSpacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Preferred) toolbar.addWidget(self.__tSpacer) # connect signal / slot self._nabuSettings.sigConfigChanged.connect(self.sigConfigChanged) # set up self._resetParameters() self._basicConfigAction.setChecked(True) self._userModeChanged() def _resetParameters(self): # reset nabu settings default_config = get_default_nabu_config(nabu_fullfield_default_config) self._nabuSettings._configuration._preProcessingWidget._sinoRingsOpts.resetConfiguration() default_config["tomwer_slices"] = "middle" default_config["preproc"]["ccd_filter_enabled"] = False default_config["preproc"]["double_flatfield"] = False default_config["preproc"]["flatfield"] = True default_config["preproc"]["take_logarithm"] = True self._nabuSettings.setConfiguration(default_config) def _userModeChanged(self, *args, **kwargs): selectedAction = self.__configurationModesGroup.checkedAction() self.__configurationModesAction.setIcon(selectedAction.icon()) self.__configurationModesAction.setToolTip(selectedAction.tooltip()) self._nabuSettings.setConfigurationLevel(self.getConfigurationLevel()) self.sigConfigChanged.emit() def _loadParameters(self): inputFile = self.askForNabuconfigFile(acceptMode=qt.QFileDialog.AcceptOpen) if inputFile and os.path.exists(inputFile): config = parse_nabu_config_file(inputFile) self._nabuSettings.setConfiguration(config) def setConfigurationLevel(self, level): level = ConfigurationLevel(level) if level == ConfigurationLevel.REQUIRED: self._minimalisticAction.setChecked(True) elif level == ConfigurationLevel.ADVANCED: self._expertConfiguration.setChecked(True) elif level == ConfigurationLevel.OPTIONAL: self._basicConfigAction.setChecked(True) else: raise ValueError("Level not recognize") self._userModeChanged() def getConfigurationLevel(self): if self._basicConfigAction.isChecked(): return ConfigurationLevel.OPTIONAL elif self._expertConfiguration.isChecked(): return ConfigurationLevel.ADVANCED elif self._minimalisticAction.isChecked(): return ConfigurationLevel.REQUIRED else: raise ValueError("Level not recognize") # expose API def hideSlicesInterface(self): return self._nabuSettings.hideSlicesInterface() def hidePaganinInterface(self): return self._nabuSettings.hidePaganinInterface() def setConfiguration(self, *args, **kwargs): self._nabuSettings.setConfiguration(*args, **kwargs) def getConfiguration(self): return self._nabuSettings.getConfiguration() def getMode(self): return self._nabuSettings.getMode() def setMode(self, *args, **kwargs): self._nabuSettings.setMode(*args, **kwargs) def setScan(self, scan): self._nabuSettings.setScan(scan=scan) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9411016 tomwer-1.6.17/src/tomwer/gui/reconstruction/sadeltabeta/0000755000175000017500000000000015153325403022444 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/sadeltabeta/__init__.py0000644000175000017500000000007115153325210024547 0ustar00paynopaynofrom .saadeltabeta import SADeltaBetaWindow # noqa F401 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py0000644000175000017500000004601615153325210025433 0ustar00paynopayno# coding: utf-8 """ contains gui relative to semi-automatic axis calculation """ from __future__ import annotations import logging from typing import Iterable import numpy from silx.gui import qt from tomwer.core.process.reconstruction.nabu.utils import ( _NabuMode, retrieve_lst_of_value_from_str, ) from tomwer.gui.configuration.level import ConfigurationLevel from tomwer.core.process.reconstruction.sadeltabeta.sadeltabeta import ( SADeltaBetaTask, ) from tomwer.core.process.reconstruction.scores.params import ScoreMethod from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui import icons from tomwer.gui.reconstruction.nabu.nabuconfig.phase import _NabuPhaseConfig from tomwer.gui.reconstruction.nabu.platform import NabuPlatformSettings from tomwer.gui.reconstruction.saaxis.sliceselector import SliceSelector from tomwer.gui.reconstruction.scores.control import ControlWidget from tomwer.gui.reconstruction.scores.scoreplot import DelaBetaSelection from tomwer.gui.reconstruction.scores.scoreplot import ScorePlot as _ScorePlot from tomwer.gui.utils.buttons import TabBrowsersButtons from tomwer.gui.utils.scandescription import ScanNameLabelAndShape from tomwer.gui.settings import TAB_LABEL_PLATFORM_SETTINGS from tomwer.synctools.sadeltabeta import QSADeltaBetaParams from tomwer.gui.reconstruction.sacommon import NabuWidgetWithToolbar as NabuWidget _logger = logging.getLogger(__name__) class ScorePlot(_ScorePlot, constructor=DelaBetaSelection): """Score plot dedicated to center delta / beta values.""" def _updateScores(self): scan = self.__scan() if self.__scan else None if scan is not None: assert isinstance(scan, TomwerScanBase) if scan.sa_delta_beta_params: scan.sa_delta_beta_params.score_method = self.getScoreMethod() # update autofocus SADeltaBetaTask.autofocus(scan) self.setVarScores( scores=self._scores, score_method=self.getScoreMethod(), update_only_scores=True, ) def _applyAutofocus(self): scan = self.__scan() if self.__scan else None if scan is None: return if scan.sa_delta_beta_params: best_db = scan.sa_delta_beta_params.autofocus if best_db: self._varSlider.setVarValue(best_db) class _SADeltaBetaTabWidget(qt.QTabWidget): sigConfigurationChanged = qt.Signal() """Signal emit when the configuration changes""" def __init__(self, parent=None, backend=None): qt.QTabWidget.__init__(self, parent=parent) self._deltaBetaSelectionWidget = DeltaBetaSelectionWidget(self) delta_beta_icon = icons.getQIcon("delta_beta") self.addTab( self._deltaBetaSelectionWidget, delta_beta_icon, "delta beta values" ) # nabu reconstruction parameters self._nabuSettings = NabuWidget(self) self._nabuSettings.setConfigurationLevel(level="required") self._nabuSettings.hidePaganinInterface() self._nabuSettings.hideSlicesInterface() nabu_icon = icons.getQIcon("nabu") self.addTab(self._nabuSettings, nabu_icon, "reconstruction settings") # platform settings self._localPlatformSettings = NabuPlatformSettings(self) settings_icons = icons.getQIcon("parameters") self.addTab( self._localPlatformSettings, settings_icons, TAB_LABEL_PLATFORM_SETTINGS ) # results self._resultsViewer = ScorePlot(self, variable_name="db", backend=backend) results_icon = icons.getQIcon("results") self.addTab(self._resultsViewer, results_icon, "reconstructed slices") # connect signal / slot self._nabuSettings.sigConfigChanged.connect(self._configurationChanged) self._deltaBetaSelectionWidget.sigConfigurationChanged.connect( self._configurationChanged ) self._resultsViewer.sigConfigurationChanged.connect(self._configurationChanged) # expose function API self.setNabuReconsParams = self._nabuSettings.setConfiguration self.getNabuReconsParams = self._nabuSettings.getConfiguration self.saveReconstructedSlicesTo = self._resultsViewer.saveReconstructedSlicesTo def setDeltaBetaScores(self, *args, **kwargs): self._resultsViewer.setVarScores(*args, **kwargs) def setCurrentVarValue(self, *args, **kwargs): self._resultsViewer.setCurrentVarValue(*args, **kwargs) def getCurrentVarValue(self): return self._resultsViewer.getCurrentVarValue() def showResults(self): self.setCurrentWidget(self._resultsViewer) def _configurationChanged(self, *args, **kwargs): self.sigConfigurationChanged.emit() def lockAutoFocus(self, lock): self._resultsViewer.lockAutoFocus(lock=lock) def isAutoFocusLock(self): return self._resultsViewer.isAutoFocusLock() def hideAutoFocusButton(self): self._resultsViewer.hideAutoFocusButton() def getDeltaBetaValues(self): """Return db values to be computed""" return self._deltaBetaSelectionWidget.getDeltaBetaValues() def setDeltaBetaValues(self, values): """set db values to be computed""" self._deltaBetaSelectionWidget.setDeltaBetaValues(values) def loadPreprocessingParams(self): """load reconstruction nabu if tomwer has already process this dataset. Not done for now""" return False def setScan(self, scan): self._resultsViewer.setScan(scan) self._nabuSettings.setScan(scan) if self.loadPreprocessingParams() and scan.axis_params is not None: self._nabuSettings.setConfiguration(scan.axis_params) self._deltaBetaSelectionWidget.setScan(scan) def getConfiguration(self): nabu_config = self.getNabuReconsParams() enable_ht = int(self._nabuSettings.getMode() is _NabuMode.HALF_ACQ) nabu_config["reconstruction"]["enable_halftomo"] = enable_ht # update phase option nabu_config["phase"][ "padding_type" ] = self._deltaBetaSelectionWidget.getPaddingType().value nabu_config["phase"][ "unsharp_coeff" ] = self._deltaBetaSelectionWidget.getUnsharpCoeff() nabu_config["phase"][ "unsharp_sigma" ] = self._deltaBetaSelectionWidget.getUnsharpSigma() return { "slice_index": self.getReconstructionSlice(), "nabu_params": nabu_config, "score_method": self.getScoreMethod().value, "delta_beta_values": self.getDeltaBetaValues(), "output_dir": nabu_config.get("output", {}).get("location", None) or None, } def getReconstructionSlice(self): return self._deltaBetaSelectionWidget.getSlice() def setReconstructionSlice(self, slice_): return self._deltaBetaSelectionWidget.setSlice(slice_=slice_) def setConfiguration(self, config): if isinstance(config, QSADeltaBetaParams): config = config.to_dict() if not isinstance(config, dict): raise TypeError( f"config should be a dictionary or a SAAxisParams. Not {type(config)}" ) db_values = config.get("delta_beta_values", None) if db_values is not None: self.setDeltaBetaValues(db_values) slice_index = config.get("slice_index", None) if slice_index is not None: self.setReconstructionSlice(slice_index) if "nabu_params" in config: nabu_params = config["nabu_params"] self.setNabuReconsParams(nabu_params) # special handling of unsharp coeff, sigma and padding type padding_type = nabu_params.get("phase", {}).get("padding_type", None) if padding_type is not None: self._deltaBetaSelectionWidget.setPaddingType(padding_type=padding_type) unsharp_coeff = nabu_params.get("phase", {}).get("unsharp_coeff", None) if unsharp_coeff is not None: self._deltaBetaSelectionWidget.setUnsharpCoeff(coeff=unsharp_coeff) unsharp_sigma = nabu_params.get("phase", {}).get("unsharp_sigma", None) if unsharp_sigma is not None: self._deltaBetaSelectionWidget.setUnsharpSigma(sigma=unsharp_sigma) if "score_method" in config: self.setScoreMethod(config["score_method"]) def getScoreMethod(self): return self._resultsViewer.getScoreMethod() def setScoreMethod(self, method): self._resultsViewer.setScoreMethod(method) def close(self): self._resultsViewer.close() self._resultsViewer = None self._deltaBetaSelectionWidget.close() self._deltaBetaSelectionWidget = None self._nabuSettings.close() self._nabuSettings = None super().close() def setSliceRange(self, min_, max_): self._deltaBetaSelectionWidget.setSliceRange(min_, max_) class SADeltaBetaWindow(qt.QMainWindow): """ Widget used to determine half-automatically the better delta / beta value """ def __init__(self, parent=None, backend=None): qt.QMainWindow.__init__(self, parent) self._db_values = [] self._urls = [] self._scan = None self._qdeltabeta_rp = QSADeltaBetaParams() self.setWindowFlags(qt.Qt.Widget) # central widget self._mainWidget = qt.QWidget(self) self._mainWidget.setLayout(qt.QVBoxLayout()) self._scanInfo = ScanNameLabelAndShape(self) self._mainWidget.layout().addWidget(self._scanInfo) self._tabWidget = _SADeltaBetaTabWidget(self, backend=backend) self._mainWidget.layout().addWidget(self._tabWidget) self.setCentralWidget(self._mainWidget) # next and previous buttons for browsing the tab widget self._browserButtons = TabBrowsersButtons(self) self._dockWidgetBrwButtons = qt.QDockWidget(self) self._dockWidgetBrwButtons.setWidget(self._browserButtons) self.addDockWidget(qt.Qt.BottomDockWidgetArea, self._dockWidgetBrwButtons) self._dockWidgetBrwButtons.setFeatures(qt.QDockWidget.DockWidgetMovable) # control widget (validate, compute, cor positions) self._sadbControl = ControlWidget(self) self._dockWidgetCtrl = qt.QDockWidget(self) self._dockWidgetCtrl.setWidget(self._sadbControl) self.addDockWidget(qt.Qt.BottomDockWidgetArea, self._dockWidgetCtrl) self._dockWidgetCtrl.setFeatures(qt.QDockWidget.DockWidgetMovable) # expose signals self.sigConfigurationChanged = self._tabWidget.sigConfigurationChanged # connect signal / slot self._browserButtons.sigNextReleased.connect(self._showNextPage) self._browserButtons.sigPreviousReleased.connect(self._showPreviousPage) self._sadbControl.sigComputationRequest.connect(self._launchReconstructions) self._sadbControl.sigValidateRequest.connect(self._validate) def showResults(self): self._tabWidget.showResults() def compute(self): """force compute of the current scan""" """force compute of the current scan""" self._sadbControl.sigComputationRequest.emit() def getConfiguration(self) -> dict: return self._tabWidget.getConfiguration() def setConfiguration(self, config: dict): self._tabWidget.setConfiguration(config) def getQDeltaBetaRP(self): return self._qdeltabeta_rp def setScan(self, scan): self._scan = scan self._tabWidget.setScan(scan) self._scanInfo.setScan(scan) def getScan(self): return self._scan def lockAutofocus(self, lock): self._tabWidget.lockAutoFocus(lock=lock) def isAutoFocusLock(self): return self._tabWidget.isAutoFocusLock() def hideAutoFocusButton(self): return self._tabWidget.hideAutoFocusButton() def _launchReconstructions(self): """callback when we want to launch the reconstruction of the slice for n delta/beta value""" raise NotImplementedError("Base class") def _validate(self): raise NotImplementedError("Base class") def _showNextPage(self, *args, **kwargs): idx = self._tabWidget.currentIndex() idx += 1 if idx < self._tabWidget.count(): self._tabWidget.setCurrentIndex(idx) def _showPreviousPage(self, *args, **kwargs): idx = self._tabWidget.currentIndex() idx -= 1 if idx >= 0: self._tabWidget.setCurrentIndex(idx) def close(self): self._tabWidget.close() self._tabWidget = None super().close() def setDBScores( self, scores: dict, score_method: str | ScoreMethod, img_width=None, update_only_scores=False, ): """ :param scores: cor value (float) as key and tuple(url: DataUrl, score: float) as value """ self._tabWidget.setDeltaBetaScores( scores=scores, score_method=score_method, img_width=img_width, update_only_scores=update_only_scores, ) def getScoreMethod(self): return self._tabWidget.getScoreMethod() def setCurrentDeltaBetaValue(self, value): self._tabWidget.setCurrentVarValue(value) def getCurrentDeltaBetaValue(self): return self._tabWidget.getCurrentVarValue() def setSlicesRange(self, min_, max_): self._tabWidget.setSliceRange(min_, max_) def saveReconstructedSlicesTo(self, output_folder): self._tabWidget.saveReconstructedSlicesTo(output_folder=output_folder) class DeltaBetaSelectionWidget(qt.QWidget): """Widget used to select the range of delta / beta to use""" sigConfigurationChanged = qt.Signal() """emit when configuration change""" _DEFAULT_VERTICAL_SLICE_MODE = ("middle", "other") def __init__(self, parent=None): qt.QWidget.__init__(self, parent) self.setWindowFlags(qt.Qt.Widget) self.setLayout(qt.QVBoxLayout()) # slice selection self._sliceGB = qt.QGroupBox("slice", self) self.layout().addWidget(self._sliceGB) self._sliceGB.setLayout(qt.QGridLayout()) self._label = qt.QLabel("slice", self) self._sliceGB.layout().addWidget(self._label, 0, 0, 1, 1) sl_spacer = qt.QWidget(self) sl_spacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) self._sliceGB.layout().addWidget(sl_spacer, 0, 5, 1, 1) self._defaultSlicesCB = qt.QComboBox(self) for mode in self._DEFAULT_VERTICAL_SLICE_MODE: self._defaultSlicesCB.addItem(mode) self._sliceGB.layout().addWidget(self._defaultSlicesCB, 0, 1, 1, 1) self._sliceSelectionQSB = SliceSelector(self, insert=False, invert_y_axis=True) self._sliceSelectionQSB.addSlice(value=0, name="Slice", color="green") self._sliceSelectionQSB.setFixedSize(qt.QSize(250, 250)) self._sliceGB.layout().addWidget(self._sliceSelectionQSB, 1, 0, 1, 5) # paganin main window self._paganinGB = qt.QGroupBox("paganin", self) self._paganinGB.setLayout(qt.QVBoxLayout()) self._mainWindow = _NabuPhaseConfig(self) self._mainWindow.setConfigurationLevel(ConfigurationLevel.ADVANCED) self._mainWindow._ctfOpts.hide() self._paganinGB.layout().addWidget(self._mainWindow) self._mainWindow._methodCB.hide() self._mainWindow._methodLabel.hide() self.layout().addWidget(self._paganinGB) # spacer widget_spacer = qt.QWidget(self) widget_spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(widget_spacer) # connect signal / slot self._sliceSelectionQSB.sigSlicesChanged.connect(self._updated) self._mainWindow.sigConfChanged.connect(self._updated) self._defaultSlicesCB.currentIndexChanged.connect(self._updated) self._defaultSlicesCB.currentIndexChanged.connect(self._updateModeCB) self.setSlice("middle") def _updated(self, *args, **kwargs): self.sigConfigurationChanged.emit() def setSlice(self, slice_: str | int): if isinstance(slice_, str): if slice_ != "middle": raise ValueError(f"Slice should be 'middle' or an int. Not {slice_}") else: self.setMode("middle") elif isinstance(slice_, int): self.setMode("other") self._sliceSelectionQSB.setSliceValue("Slice", slice_) elif isinstance(slice_, dict) and "Slice" in slice_: self.setMode("other") self._sliceSelectionQSB.setSliceValue("Slice", slice_["Slice"]) else: raise TypeError(f"slice should be an int or 'middle'. Not {type(slice_)}") def setSliceRange(self, min_, max_): self._sliceSelectionQSB.setSlicesRange(min_, max_) def getMode(self): return self._defaultSlicesCB.currentText() def setMode(self, mode): if mode not in self._DEFAULT_VERTICAL_SLICE_MODE: raise ValueError( f"mode should be in {self._DEFAULT_VERTICAL_SLICE_MODE}. Not {mode}." ) idx = self._defaultSlicesCB.findText(mode) self._defaultSlicesCB.setCurrentIndex(idx) self._updateModeCB() def _updateModeCB(self): self._sliceSelectionQSB.setVisible(self.getMode() == "other") def getSlice(self): if self.getSliceMode() == "middle": return "middle" else: return self._sliceSelectionQSB.getSlicesValue() def getSliceMode(self): return self._defaultSlicesCB.currentText() def setScan(self, scan: TomwerScanBase): self._sliceSelectionQSB.setSlicesRange(0, scan.dim_2) def getDeltaBetaValues(self) -> numpy.array: db_values = self._mainWindow._paganinOpts.getDeltaBeta() return retrieve_lst_of_value_from_str(db_values, type_=float) def setDeltaBetaValues(self, values: numpy.array | Iterable): values = numpy.array(values) step = None if len(values) > 3: deltas = values[1:] - values[:-1] if deltas.min() == deltas.max(): step = deltas.min() deltaBetaQLE = self._mainWindow._paganinOpts._deltaBetaQLE if step is None: deltaBetaQLE.setText(",".join([str(value) for value in values])) else: deltaBetaQLE.setText( "{from_}:{to_}:{step_}".format( from_=values.min(), to_=values.max(), step_=step ) ) def getPaddingType(self): return self._mainWindow.getPaddingType() def setPaddingType(self, padding_type: str): self._mainWindow.setPaddingType(padding_type=padding_type) def getUnsharpCoeff(self) -> float: return self._mainWindow.getUnsharpCoeff() def setUnsharpCoeff(self, coeff) -> float: return self._mainWindow.setUnsharpCoeff(coeff=coeff) def getUnsharpSigma(self) -> float: return self._mainWindow.getUnsharpSigma() def setUnsharpSigma(self, sigma): self._mainWindow.setUnsharpSigma(sigma=sigma) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9411016 tomwer-1.6.17/src/tomwer/gui/reconstruction/scores/0000755000175000017500000000000015153325403021471 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/scores/__init__.py0000644000175000017500000000000014757047403023602 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/scores/control.py0000644000175000017500000000273014757047403023537 0ustar00paynopayno# coding: utf-8 """ contains gui to select a slice in a volume """ from __future__ import annotations from silx.gui import qt class ControlWidget(qt.QWidget): """ Widget to lock cor position or compute it or validate it and to display the cor value """ sigComputationRequest = qt.Signal() """Signal emitted when user request a computation from the settings""" sigValidateRequest = qt.Signal() """Signal emitted when user validate the current settings""" def __init__(self, parent): qt.QWidget.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) self._buttons = qt.QWidget(parent=self) self._buttons.setLayout(qt.QHBoxLayout()) self.layout().addWidget(self._buttons) spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) self._buttons.layout().addWidget(spacer) self._computeBut = qt.QPushButton("compute", parent=self) self._buttons.layout().addWidget(self._computeBut) style = qt.QApplication.style() applyIcon = style.standardIcon(qt.QStyle.SP_DialogApplyButton) self._applyBut = qt.QPushButton(applyIcon, "validate", parent=self) self._buttons.layout().addWidget(self._applyBut) self.layout().addWidget(self._buttons) # make connection self._computeBut.pressed.connect(self.sigComputationRequest) self._applyBut.pressed.connect(self.sigValidateRequest) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/scores/scoreplot.py0000644000175000017500000007467415153325210024073 0ustar00paynopayno""" contains gui to select a slice in a volume """ from __future__ import annotations import logging import pint import os import weakref from contextlib import AbstractContextManager import numpy from matplotlib import image as _matplotlib_image from silx.gui import qt from silx.gui.plot import PlotWidget from tomwer.core.process.reconstruction.utils.cor import relative_pos_to_absolute from tomwer.core.process.reconstruction.scores.params import ScoreMethod from tomwer.gui import icons, settings from tomwer.gui.reconstruction.saaxis.dimensionwidget import DimensionWidget from tomwer.gui.utils.buttons import PadlockButton from tomwer.gui.utils.vignettes import VignettesQDialog from tomwer.gui.visualization.dataviewer import ImageStack from tomwer.io.utils import get_default_directory from tomwer.io.utils.h5pyutils import DatasetReader from tomwer.io.utils.utils import get_slice_data _logger = logging.getLogger(__name__) class VariableScorePlot(PlotWidget): sigMouseWheelActive = qt.Signal(object) """emit when the mouse wheel get activated""" MARKER_COLOR = "#ff292199" def __init__(self, parent, backend=None): PlotWidget.__init__(self, parent, backend=backend) self._scores = {} self.setAxesDisplayed(False) self.setMaximumHeight(150) self.setMinimumHeight(100) # cor marker # self.addXMarker( # x=100, legend="cor", text="cor", draggable=False, color=self.MARKER_COLOR # ) # self.corMarker = self._getMarker("cor") # self.corMarker.setLineWidth(3) # Retrieve PlotWidget's plot area widget plotArea = self.getWidgetHandle() # Set plot area custom context menu plotArea.setContextMenuPolicy(qt.Qt.CustomContextMenu) plotArea.customContextMenuRequested.connect(self._contextMenu) self.setInteractiveMode("select", zoomOnWheel=False) self.setPanWithArrowKeys(False) def clear(self): super().clear() # cor marker # self.addXMarker( # x=100, legend="cor", text="cor", draggable=False, color=self.MARKER_COLOR # ) # self.corMarker = self._getMarker("cor") def wheelEvent(self, event): self.sigMouseWheelActive.emit(event) def onMouseWheel(self, xPixel, yPixel, angleInDegrees): pass def _contextMenu(self, pos: qt.QPoint): """Handle plot area customContextMenuRequested signal. :param pos: Mouse position relative to plot area """ # avoir reset zoom pass class VariableSelection(qt.QWidget): """Widget to select which cor to select""" sigSelectionModeChanged = qt.Signal() """Signal emitted when selection mode changed""" sigAutoFocusLocked = qt.Signal() """signal send when the 'auto' mode is locked / activated""" sigAutoFocusUnLocked = qt.Signal() """signal send when the 'auto' mode is unlocked / unactivated""" sigVariableValueSelected = qt.Signal(float) """signal emitted when the cor value is selected by the user from vignettes""" sigScoreMethodChanged = qt.Signal() """Signal meit when the score method (std, tv) change""" def __init__(self, parent=None, variable_name=None): if not isinstance(variable_name, str): raise TypeError("variable_name should be a string") self._variable_name = variable_name qt.QWidget.__init__(self, parent) self._scores = {} self._img_width = None self._scan = None self.setLayout(qt.QGridLayout()) # score method self._scoreMethodLabel = qt.QLabel("score method", self) self.layout().addWidget(self._scoreMethodLabel, 0, 0, 1, 1) self._scoreMethodCB = qt.QComboBox(self) self.layout().addWidget(self._scoreMethodCB, 0, 1, 1, 1) for method in ScoreMethod: if method is ScoreMethod.TOMO_CONSISTENCY: # for now we avoid this method. Does not provide great results and is very time consuming # I guess when we will add it we will need to first display slices # and then only compute the score. It might be an "on demand" score but not computed by default. continue self._scoreMethodCB.addItem(method.value) # default score method is 1 / tv idx = self._scoreMethodCB.findText(ScoreMethod.TV_INVERSE.value) self._scoreMethodCB.setCurrentIndex(idx) # left spacer lspacer = qt.QWidget(self) lspacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) self.layout().addWidget(lspacer, 0, 2, 2, 1) # TODO: this should be inherite by a cor plot (to display variable and absloute value) # cor value self._currentVarValue = qt.QGroupBox(self) self._currentVarValue.setTitle(f"current {self._variable_name} value") self._currentVarValue.setLayout(qt.QFormLayout()) self.layout().addWidget(self._currentVarValue, 0, 3, 3, 2) # cor selection option self._currentcorRB = qt.QRadioButton("current value", self) self.layout().addWidget(self._currentcorRB, 0, 5, 1, 1) self._autofocusRB = qt.QRadioButton("autofocus", self) self._autofocusRB.setToolTip( f"Take the {self._variable_name} with the best score" ) self.layout().addWidget(self._autofocusRB, 1, 5, 1, 1) # lock autofocus button self._lockAutofocusButton = PadlockButton(self) self._lockAutofocusButton.setToolTip( "If autofocus is locked then " "the best center of rotation " "will be pick automatically" ) self.layout().addWidget(self._lockAutofocusButton, 1, 7, 1, 1) rspacer = qt.QWidget(self) rspacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) self.layout().addWidget(rspacer, 0, 8, 2, 1) openVignettePixmap = icons.getQPixmap("vignettes") openVignetteIcon = qt.QIcon(openVignettePixmap) self._vignetteButton = qt.QPushButton(self) self._vignetteButton.setFixedSize(qt.QSize(50, 50)) self._vignetteButton.setIconSize(qt.QSize(40, 40)) self._vignetteButton.setIcon(openVignetteIcon) self.layout().addWidget(self._vignetteButton, 0, 9, 2, 1) # radio button group self._buttonGrp = qt.QButtonGroup() self._buttonGrp.addButton(self._currentcorRB) self._buttonGrp.addButton(self._autofocusRB) # set up self._currentcorRB.setChecked(True) # connect signal / slot self._currentcorRB.toggled.connect(self._selectionModeChanged) self._autofocusRB.toggled.connect(self._selectionModeChanged) self._lockAutofocusButton.toggled.connect(self._lockButtonActive) self._vignetteButton.released.connect(self._openVignetteMode) self._scoreMethodCB.currentIndexChanged.connect(self._scoreMethodChanged) # update widget to fit set up self._selectionModeChanged() def getVarSelectionMode(self): if self._currentcorRB.isChecked(): return "current value" elif self._autofocusRB.isChecked(): return "autofocus" else: raise NotImplementedError("") def _openVignetteMode(self): colormap = None if self.parent() and hasattr(self.parent(), "getPlotWidget"): master_plot = self.parent().getPlotWidget() colormap = master_plot.getPlotWidget().getColorBarWidget().getColormap() dialog = VignettesQDialog( value_name=f"{self._variable_name} position", score_name="score", value_format="{:.3f}", score_format="{:.3f}", colormap=colormap, ) dialog.setWindowTitle(f"{self.getWindowTitle()} - vignettes") # set scores dialog.setScores(self._scores, score_method=self.getScoreMethod()) if dialog.exec() == qt.QDialog.Accepted: cor_selected = dialog.selectedValue() if cor_selected is not None: self.sigVariableValueSelected.emit(cor_selected) dialog.setAttribute(qt.Qt.WA_DeleteOnClose) def _selectionModeChanged(self, *args, **kwargs): self.sigSelectionModeChanged.emit() def setValue(self, relative_value): raise NotImplementedError("Base class") def getAutoFocusLockButton(self): return self._lockAutofocusButton def _scoreMethodChanged(self): self.sigScoreMethodChanged.emit() def isAutoFocusLock(self): return self._lockAutofocusButton.isChecked() def isAutoFocusActive(self): return self._autofocusRB.isChecked() def hideAutoFocusButton(self): self._lockAutofocusButton.hide() def lockAutoFocus(self, lock): self._currentcorRB.setEnabled(not lock) if lock and not self._autofocusRB.isChecked(): self._autofocusRB.setChecked(True) self._lockAutofocusButton.setChecked(lock) def _lockButtonActive(self, lock): self.lockAutoFocus(lock) if self._lockAutofocusButton.isChecked(): self.sigAutoFocusLocked.emit() else: self.sigAutoFocusUnLocked.emit() def setScores(self, scores: dict): self._scores = scores def setImgWidth(self, width): self._img_width = width def getScoreMethod(self): return ScoreMethod(self._scoreMethodCB.currentText()) def setScoreMethod(self, method): method_value = ScoreMethod(method).value index = self._scoreMethodCB.findText(method_value) self._scoreMethodCB.setCurrentIndex(index) class SingleValueSelection(VariableSelection): def __init__(self, *args, **kwargs): VariableSelection.__init__(self, *args, **kwargs) self._valueLE = qt.QLineEdit(self) self._valueLE.setReadOnly(True) self._currentVarValue.layout().addRow("value:", self._valueLE) def setValue(self, value): self._valueLE.setText(f"{value:.2f}") def getWindowTitle(self): raise NotImplementedError("Base class") class DelaBetaSelection(SingleValueSelection): # FIXME: fix typo Dela vs Delta def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) idx = self._scoreMethodCB.findText(ScoreMethod.TOMO_CONSISTENCY.value) if idx >= 0: self._scoreMethodCB.removeItem(idx) def getWindowTitle(self): return "sa delta/beta vignettes" class CorSelection(VariableSelection): def __init__(self, *args, **kwargs): VariableSelection.__init__(self, *args, **kwargs) self._relativeVarValueLE = qt.QLineEdit(self) self._relativeVarValueLE.setReadOnly(True) self._currentVarValue.layout().addRow("relative:", self._relativeVarValueLE) self._absoluteVarValueLE = qt.QLineEdit(self) self._absoluteVarValueLE.setReadOnly(True) self._currentVarValue.layout().addRow( "absolute:", self._absoluteVarValueLE, ) try: import pyopencl # noqa F401 pylint: disable=E0401 except Exception: idx = self._scoreMethodCB.findText(ScoreMethod.TOMO_CONSISTENCY.value) if idx >= 0: self._scoreMethodCB.removeItem(idx) def setValue(self, relative_value): if relative_value is None: self._relativeVarValueLE.clear() else: self._relativeVarValueLE.setText(f"{relative_value:.3f}") if relative_value is None or self._img_width is None: self._absoluteVarValueLE.clear() else: absolute_value = relative_pos_to_absolute( relative_pos=relative_value, det_width=self._img_width ) self._absoluteVarValueLE.setText(f"{absolute_value:.3f}") def getWindowTitle(self): return "sa axis - vignettes" class PainterRotationCM(AbstractContextManager): """ On enter move the painter to the position and rotate it of provided angle. On exits rotate back then translate back to the original position """ def __init__(self, painter, x: float, y: float, angle: float): self.painter = painter self.x = x self.y = y self.angle = angle def __enter__(self): self.painter.translate(self.x, self.y) self.painter.rotate(self.angle) return self.painter def __exit__(self, exc_type, exc_val, exc_tb): self.painter.rotate(-self.angle) self.painter.translate(-self.x, -self.y) class _VariableValueLabels(qt.QWidget): """ Display labels for center of rotation """ # TODO: could be used to define the current value displayed by underlying # and the one selected in red. _LABEL_WIDTH = 60 """Label width with rotation""" MIN_WIDTH_PER_LABEL = 40 """Label width without rotation""" # DEBUG OPTIONS: Deformation is not handled so you should put rotation to 0 PLOT_TICKS = False PLOT_CANVAS_LIM = False PLOT_LABEL_RECT = False def __init__(self, parent=None, angle: float = 45.0): qt.QWidget.__init__(self, parent) self._var_values = tuple() self._right_shift = 0 self._slider_ticks_margin = 0 self.rotation_angle_degree = angle def setVarValues(self, values): self._var_values = numpy.array(values) def setRightShift(self, shift: int): self._right_shift = shift def setSliderTicksMargin(self, margin: int): self._slider_ticks_margin = margin def getVarSteps(self) -> int: """ Return step for the cor values to be displayed. 1: display all cor values 2: display one cor per each 2 values :return: """ if len(self._var_values) == 0: return 1 width = self.width() # 1.8: as we are a 45 degree then / 2.0 should be good. Dividing by 1.8 # instead will increase visibility n_var_values = self._var_values.size for i in range(1, 9): if ((n_var_values / i) * self.MIN_WIDTH_PER_LABEL) < width: return i return 10 def paintEvent(self, event): n_var_values = len(self._var_values) if n_var_values == 0: return elif n_var_values < 5: var_indexes = numpy.arange(n_var_values) else: var_indexes = numpy.arange(0, self._var_values.size)[:: self.getVarSteps()] from_ = self._slider_ticks_margin to_ = self.width() - self._right_shift - self._slider_ticks_margin var_px_positions = numpy.linspace( from_, to_, self._var_values.size, endpoint=True ) painter = qt.QPainter(self) # painter.translate(self.rect().topLeft()) font = qt.QFont("Helvetica", 10) painter.setFont(font) txt_width = self._LABEL_WIDTH txt_height = self.height() for i_var in var_indexes: var_value = self._var_values[i_var] var_px_pos = var_px_positions[i_var] txt_value = f"{var_value:.3f}" # apply rotation to "invert" the painter rotation requested to # paint oblique text with PainterRotationCM( painter=painter, x=var_px_pos + (self._slider_ticks_margin / 2.0), y=0, angle=self.rotation_angle_degree, ) as l_painter: var_rect = qt.QRect(0, 0, txt_width, txt_height) l_painter.drawText(var_rect, qt.Qt.AlignLeft, txt_value) if self.PLOT_LABEL_RECT: painter.drawRect(var_rect) # print all ticks if self.PLOT_TICKS: painter.setPen(qt.QPen(qt.QColor(35, 234, 32))) tick_positions = numpy.linspace( from_, to_, len(self._var_values), endpoint=True ) for pos in tick_positions: var_rect = qt.QRect(pos, 0, 2, 6) painter.drawRect(var_rect) # print canvas if self.PLOT_CANVAS_LIM: painter.setPen(qt.QPen(qt.QColor(168, 34, 32))) x, y = self.width() - 2, self.height() - 2 var_rect = qt.QRect(0, 0, x, y) painter.drawRect(var_rect) class ScorePlot(qt.QWidget): """ Plot to display the scores """ sigConfigurationChanged = qt.Signal() """signal emitted when the configuration change""" _CENTRAL_SLICE_NAME = "central slice" def __init__( self, parent=None, variable_name=None, dims_colors=("#ffff5a", "#62efff", "#ff5bff"), backend=None, ): if not isinstance(variable_name, str): raise TypeError("a variable name should be provided as a string") self._dim_colors = dims_colors self._var_values = tuple() self._scores = {} self.__scan = None qt.QWidget.__init__(self, parent) # define GUI self.setLayout(qt.QGridLayout()) # main plot self._plot = ImageStack(self, show_overview=False, backend=backend) self._plot.getPlotWidget().setYAxisInverted(settings.Y_AXIS_DOWNWARD) self._plot.getPlotWidget().setKeepDataAspectRatio(True) self._plot._sliderDockWidget.hide() self._plot.getPlotWidget().getColorBarWidget().hide() self._plot.getPlotWidget().getPositionInfoWidget().hide() # add save all action save_all_icon = icons.getQIcon("multi-document-save") self._saveAllSnapshot = qt.QAction( save_all_icon, "save all screenshot as png", self ) toolbar = self._plot.getPlotWidget().toolBar() toolbar.addSeparator() toolbar.addAction(self._saveAllSnapshot) # hide dock widget self._plot._reconsInfoDockWidget.hide() self._plot._tableDockWidget.hide() self.layout().addWidget(self._plot, 0, 0, 1, 2) right_shift = 40 # pixel # cor score plot self._varScore = VariableScorePlot(self) self._varScore.setContentsMargins(15, 10, right_shift + 15, 0) self.layout().addWidget(self._varScore, 1, 0, 1, 2) # slider self._varSlider = _VarSlider(self, orientation=qt.Qt.Horizontal) self.layout().addWidget(self._varSlider, 2, 0, 1, 2) self._varSlider.setContentsMargins(0, 0, right_shift, 0) self.setContentsMargins(0, 0, 0, 0) self.layout().setSpacing(0) self.layout().addWidget(self._varSlider, 3, 0, 1, 2) # cor labels self._varLabels = _VariableValueLabels(self) self._varLabels.setContentsMargins(0, 0, 0, 0) self._varLabels.setFixedHeight(60) self.layout().addWidget(self._varLabels, 4, 0, 1, 2) self._varLabels.setRightShift(right_shift) self._varLabels.setSliderTicksMargin(15) # cor value self._varValueWidget = self._CorSlectionBuilder(self, variable_name) self._varValueWidget.layout().setContentsMargins(0, 0, 0, 0) self.layout().addWidget(self._varValueWidget, 5, 0, 1, 1) # voxel size self._voxelSizeW = DimensionWidget( title="Voxel size", dims_name=("x:", "y:", "z:"), dims_colors=self._dim_colors, ) self._voxelSizeW.layout().setContentsMargins(0, 0, 0, 0) self.layout().addWidget(self._voxelSizeW, 6, 0, 1, 1) # volume size W self._volumeSizeW = DimensionWidget( title="Volume size", dims_name=("x:", "y:", "z:"), dims_colors=self._dim_colors, ) self._volumeSizeW.layout().setContentsMargins(0, 0, 0, 0) self.layout().addWidget(self._volumeSizeW, 6, 0, 1, 1) # axis self.setContentsMargins(0, 0, 0, 0) self._axisLabel = qt.QLabel(parent=self) icon = icons.getQIcon("axis") self._axisLabel.setPixmap(icon.pixmap(qt.QSize(96, 96))) self.layout().addWidget(self._axisLabel, 7, 1, 2, 1) # connect signal / slot self._varSlider.valueChanged.connect(self._plot.setCurrentUrlIndex) self._varSlider.valueChanged.connect(self._sliderReleased) self._varSlider.valueChanged.connect(self._updateVarValue) self._varScore.sigMouseWheelActive.connect(self._varSlider.wheelEvent) self._varValueWidget.sigAutoFocusLocked.connect(self._autoFocusLockChanged) self._varValueWidget.sigAutoFocusUnLocked.connect(self._autoFocusLockChanged) self._varValueWidget.sigSelectionModeChanged.connect( self._varSelectionModeChanged ) self._varValueWidget.sigVariableValueSelected.connect( self._varSelectedFromVignettes ) self._varValueWidget.sigScoreMethodChanged.connect(self._updateScores) self._saveAllSnapshot.triggered.connect(self._saveAllReconstructedSlices) # set up # for now we don't want to use the volume and voxel size self._volumeSizeW.hide() self._voxelSizeW.hide() self._axisLabel.hide() # use mean mean+/-3std for the cor plotWidget = self._plot.getPlotWidget() colormap = plotWidget.getDefaultColormap() colormap.setAutoscaleMode(colormap.STDDEV3) plotWidget.setDefaultColormap(colormap=colormap) def __init_subclass__(cls, constructor, **kwargs): # pylint: disable=E0302 super().__init_subclass__() cls._CorSlectionBuilder = constructor def getScoreMethod(self): return self._varValueWidget.getScoreMethod() def setScoreMethod(self, method): self._varValueWidget.setScoreMethod(method) def _configurationChanged(self, *args, **kwargs): self.sigConfigurationChanged.emit() def getPlotWidget(self): return self._plot def close(self): self._plot.close() self._plot = None super().close() def getCurrentVarValue(self): cor_idx = self._varSlider.value() if cor_idx < len(self._var_values): return self._var_values[cor_idx] def setCurrentVarValue(self, value): self._varSlider.setVarValue(value=value) self._varValueWidget.setValue(value) def lockAutoFocus(self, lock): self._varValueWidget.lockAutoFocus(lock) def isAutoFocusLock(self): return self._varValueWidget.isAutoFocusLock() def hideAutoFocusButton(self): self._varValueWidget.hideAutoFocusButton() def isAutoFocusActive(self): return self._varValueWidget.isAutoFocusActive() def _autoFocusLockChanged(self): if self.isAutoFocusLock(): self._applyAutofocus() self._configurationChanged() def getVarSelectionMode(self): return self._varValueWidget.getVarSelectionMode() def _applyAutofocus(self): raise NotImplementedError("Base class") def _varSelectionModeChanged(self): if self.getVarSelectionMode() == "autofocus": self._applyAutofocus() def _updateVarValue(self): self._varValueWidget.setValue(self.getCurrentVarValue()) def _varSelectedFromVignettes(self, value): self._varSlider.setVarValue(value) def _get_closest_var(self, value): """return the closest cor value to value or None if no cor value defined""" if len(self._var_values) > 0: idx_closest = numpy.argmin(numpy.abs(self._var_values - value)) return self._var_values[idx_closest] else: return None def _markerReleased(self): return def _sliderReleased(self): return def setScan(self, scan): self.clear() self.__scan = weakref.ref(scan) def _updateScores(self): raise NotImplementedError("Base class") def setVarScores( self, scores: dict, score_method: str | ScoreMethod, img_width=None, update_only_scores=False, ): """ :param scores: cor value (float) as key and tuple(url: DataUrl, score: float) as value """ score_method = ScoreMethod(score_method) if not update_only_scores: self.clear() self._scores = scores self.setImgWidth(img_width) # set image width to deduce absolute position from relative self._var_values = [] score_list = [] self._urls = [] if scores is None or len(scores) == 0: return for cor_value, cor_info in scores.items(): url, score = cor_info if score is None: continue # in case score calculation failed self._var_values.append(cor_value) score_list.append(score.get(score_method)) self._urls.append(url) # insure cor and scores are numpy arrays self._var_values = list(self._var_values) score_list = numpy.array(score_list) # set zoom a priori if not update_only_scores and len(self._urls) > 0: try: with DatasetReader(url=self._urls[0]) as dataset: dataset.shape except Exception as e: _logger.warning(e) else: self._plot.setResetZoomOnNextIteration(True) if not update_only_scores: self._plot.setUrls(urls=self._urls) self._varSlider.setVarValues(self._var_values) old = self._varSlider.blockSignals(True) if len(self._var_values) > 0: self._varSlider.setVarValue(self._var_values[0]) self._varSlider.blockSignals(old) old = self._varValueWidget.blockSignals(True) self.setScoreMethod(score_method) self._varValueWidget.blockSignals(old) self._varScore.addCurve( x=numpy.array(self._var_values), y=score_list, baseline=0, fill=True, color="#0288d190", ) self._varLabels.setVarValues(self._var_values) # update cor marker position according to the slider position self._sliderReleased() self._varValueWidget.setScores(scores) scan = self.__scan() if self.__scan else None if scan is not None and self.isAutoFocusActive(): self._applyAutofocus() def setImgWidth(self, width): self._varValueWidget.setImgWidth(width) def clear(self): self._varSlider.setVarValues(tuple()) self._varScore.clear() self._varLabels.setVarValues(tuple()) self._plot.getPlotWidget().clear() self._varValueWidget.setImgWidth(None) def setVoxelSize( self, dim0: pint.Quantity, dim1: pint.Quantity, dim2: pint.Quantity ): """ :param dim0: :param dim1: :param dim2: :param unit: """ self._voxelSizeW.setQuantities(dim0=dim0, dim1=dim1, dim2=dim2) def setVolumeSize( self, dim0: pint.Quantity, dim1: pint.Quantity, dim2: pint.Quantity ): """ :param dim0: :param dim1: :param dim2: :param unit: """ self._volumeSizeW.setQuantities(dim0=dim0, dim1=dim1, dim2=dim2) def getDim0N(self): """return the number of elements in dimension 0 according to voxel size and volume size""" return int( numpy.ceil( self._volumeSizeW.getDim0Quantity().to_base_units().magnitude / self._voxelSizeW.getDim0Quantity().to_base_units().magnitude ) ) def getDim1N(self): """return the number of elements in dimension 1 according to voxel size and volume size""" return int( numpy.ceil( self._volumeSizeW.getDim1Quantity().to_base_units().magnitude / self._voxelSizeW.getDim1Quantity().to_base_units().magnitude ) ) def getDim2N(self): """return the number of elements in dimension 2 according to voxel size and volume size""" return int( numpy.ceil( self._volumeSizeW.getDim2Quantity().to_base_units().magnitude / self._voxelSizeW.getDim2Quantity().to_base_units().magnitude ) ) def _saveAllReconstructedSlices(self): # pragma: no cover """ save all reconstructed slices to a folder provided by the user """ dialog = qt.QFileDialog(self, directory=get_default_directory()) dialog.setFileMode(qt.QFileDialog.DirectoryOnly) if not dialog.exec(): dialog.close() return output_folder = dialog.selectedFiles()[0] try: self.saveReconstructedSlicesTo(output_folder=output_folder) except Exception as e: _logger.error(f"Fail to save snapshots. Error is {e}") else: _logger.info(f"snapshots have been saved to {output_folder}") def saveReconstructedSlicesTo(self, output_folder): """dump all slices with score as name""" # make sure the output dir exists os.makedirs(output_folder, exist_ok=True) i_missing_score = 0 for score, slice_url in zip(self._var_values, self._urls): try: data = get_slice_data(slice_url) if score is None: file_name = f"no_score_{i_missing_score}.png" i_missing_score += 1 else: file_name = f"{score}.png" _matplotlib_image.imsave( os.path.join(output_folder, file_name), data, format="png", ) except Exception as e: _logger.error(f"Failed to dump {slice_url.path()}. Raison is {e}") class _VarSlider(qt.QWidget): def __init__(self, parent, orientation): self._values = None qt.QWidget.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) self._slider = qt.QSlider(self) self.layout().addWidget(self._slider) self._slider.setMaximum(0) self._slider.setOrientation(orientation) self._slider.setTickPosition(qt.QSlider.TicksBelow) # connect signal / slot self.valueChanged = self._slider.valueChanged def wheelEvent(self, event) -> None: self._slider.wheelEvent(event) def setVarValues(self, values): self._slider.setRange(0, len(values) - 1) self._values = numpy.array(values, dtype=numpy.float32) def setVarValue(self, value): if value in self._values: where = numpy.where(self._values == value) if len(where) > 0: value = where[0] if isinstance(value, numpy.ndarray): value = value[0] self._slider.setValue(int(value)) def value(self): return self._slider.value() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9411016 tomwer-1.6.17/src/tomwer/gui/reconstruction/tests/0000755000175000017500000000000015153325403021335 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/tests/__init__.py0000644000175000017500000000000014757047403023446 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/tests/test_axis.py0000644000175000017500000001651215153325210023713 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import shutil import tempfile import h5py import numpy.random import pytest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from tomwer.core.process.reconstruction.axis.mode import AxisMode from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.gui.reconstruction.axis import AxisMainWindow from tomwer.gui.reconstruction.axis.ManualFramesSelection import ManualFramesSelection from tomwer.synctools.axis import QAxisRP from tomwer.tests.datasets import TomwerCIDatasets from tomwer.tests.utils import skip_gui_test from tomwer.core.utils.scanutils import MockNXtomo @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestWindowAxis(TestCaseQt): """Test that the axis widget work correctly""" def setUp(self): self.tempdir = tempfile.mkdtemp() self.recons_params = QAxisRP() self._window = AxisMainWindow(axis_params=self.recons_params) self.scan = MockNXtomo( scan_path=os.path.join(self.tempdir, "nx_tomo.nx"), n_proj=10, n_ini_proj=10, scan_range=180, dim=20, energy=12.3, ).scan self._window.show() self.qWaitForWindowExposed(self._window) def tearDown(self): shutil.rmtree(self.tempdir) self._window.setAttribute(qt.Qt.WA_DeleteOnClose) self._window.close() def testSetImagesNumpyArray(self): """Test the setImages function""" radio_axis = self._window._axisWidget radio_axis_plot = self._window._axisWidget.getPlot() numpy.testing.assert_array_equal( radio_axis_plot.getPlot().getActiveImage().getData(), numpy.empty((0, 0, 4)) ) imgA = numpy.random.random((100, 100)) imgB = numpy.random.random((100, 100)) radio_axis.setImages(imgA=imgA, imgB=imgB, flipB=True) self.qapp.processEvents() # make sur the image has been set assert radio_axis_plot.getPlot().getImage(legend="image1").getData().shape == ( 100, 100, ) def testSetScan(self): """Test the setScan function""" radio_axis_plot = self._window._axisWidget.getPlot() numpy.testing.assert_array_equal( radio_axis_plot.getPlot().getActiveImage().getData(), numpy.empty((0, 0, 4)) ) self._window.setScan(self.scan) self.qapp.processEvents() # make sur the image has been set assert radio_axis_plot.getPlot().getImage(legend="image1").getData().shape == ( 20, 20, ) def testShiftButtons(self): """Test that the 'left', 'right', ... buttons and the shift steps are correctly working""" imgA = numpy.random.random((100, 100)) imgB = numpy.random.random((100, 100)) radio_axis = self._window._axisWidget radio_axis.setImages(imgA=imgA, imgB=imgB, flipB=False) self.qapp.processEvents() self.assertTrue(radio_axis.getXShift() == 0) self.assertTrue(radio_axis.getYShift() == 0) self.assertTrue( radio_axis.getShiftStep() == 1.0, f"shift is {radio_axis.getShiftStep()} when 1.0 expected", ) radio_axis._settingsWidget._shiftControl._leftButton.click() self.qapp.processEvents() self.assertTrue(radio_axis.getXShift() == -1) self.assertTrue(radio_axis.getYShift() == 0) radio_axis._settingsWidget._shiftControl._rightButton.click() self.qapp.processEvents() self.assertTrue(radio_axis.getXShift() == 0) self.assertTrue(radio_axis.getYShift() == 0) radio_axis._settingsWidget._displacementSelector._fineButton.click() self.qapp.processEvents() self.assertTrue(radio_axis.getShiftStep() == 0.1) radio_axis._settingsWidget._shiftControl._topButton.click() self.qapp.processEvents() self.assertTrue(radio_axis.getXShift() == 0) self.assertTrue(radio_axis.getYShift() == 0.1) radio_axis.setShiftStep(0.2) self.assertTrue(radio_axis.getShiftStep() == 0.2) radio_axis._settingsWidget._shiftControl._bottomButton.click() self.qapp.processEvents() self.assertTrue(radio_axis.getXShift() == 0) self.assertTrue(radio_axis.getYShift() == -0.1) def testAxisObjectGlobal(self): """Test that the GUI change according to the Axis object""" axis_obj = QAxisRP() self._window.setReconsParams(axis_obj) self.qapp.processEvents() self.assertEqual(self._window._axisWidget.getMode(), axis_obj.mode) # TODO: change the mode to see if the object is modify def testAxisObjectManual(self): """Test that the GUI change according to the Axis object""" axis_params = QAxisRP() axis_params.mode = AxisMode.manual axis_params.set_relative_value(-6.0) # note : for now only the xshift is managed ! self._window.setReconsParams(axis_params) radio_axis = self._window._axisWidget self.assertEqual(radio_axis.getXShift(), -6.0) self.assertEqual(radio_axis.getYShift(), 0.0) @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestWindowsAxisSetScan(TestCaseQt): """Test that updates are correctly done in the case scan has some knowledge on""" def setUp(self): TestCaseQt.setUp(self) self.recons_params = QAxisRP() self.widget = AxisMainWindow(axis_params=self.recons_params) self.scan_dir = tempfile.mkdtemp() # create dataset self.master_file = os.path.join(self.scan_dir, "frm_edftomomill_twoentries.nx") shutil.copyfile( TomwerCIDatasets.get_dataset( "h5_datasets/frm_edftomomill_twoentries.nx", ), self.master_file, ) self.scan = NXtomoScan(scan=self.master_file, entry="entry0000") def tearDown(self): self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None def patch_fov(self, value: str): with h5py.File(self.scan.master_file, mode="a") as h5s: for entry in ("entry0000", "entry0001"): entry_node = h5s[entry] if "instrument/detector/field_of_view" in entry_node: del entry_node["instrument/detector/field_of_view"] entry_node["instrument/detector/field_of_view"] = value def test__getClosestAssociatedAngle(): """ test _getClosestAssociatedAngle function """ assert ( ManualFramesSelection._getClosestAssociatedAngle(angle=12.3, angles=(12.3,)) == 12.3 ) assert ( ManualFramesSelection._getClosestAssociatedAngle( angle=12.3, angles=(2.06, 10.3, 100.6) ) == 10.3 ) assert ( ManualFramesSelection._getClosestAssociatedAngle( angle=100.2, angles=(2.06, 10.3, 100.6) ) == 100.6 ) assert ( ManualFramesSelection._getClosestAssociatedAngle(angle=12.3, angles=()) is None ) assert ( ManualFramesSelection._getClosestAssociatedAngle( angle=300.2, angles=(2.06, 10.3, 100.6) ) == 100.6 ) assert ( ManualFramesSelection._getClosestAssociatedAngle( angle=-12, angles=(2.06, 10.3, 100.6) ) == 2.06 ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989076.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/tests/test_nabu.py0000644000175000017500000003240215153325224023675 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import pytest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from tomwer.gui.reconstruction.nabu.nabuconfig.output import _NabuOutputConfig from tomwer.gui.reconstruction.nabu.nabuconfig.phase import _NabuPhaseConfig from tomwer.gui.reconstruction.nabu.nabuconfig.preprocessing import ( _NabuPreProcessingConfig, RingCorrectionMethod, ) from tomwer.gui.reconstruction.nabu.nabuconfig.reconstruction import ( _NabuReconstructionConfig, ) from tomwer.gui.reconstruction.nabu.nabuflow import NabuFlowControl from tomwer.gui.reconstruction.nabu.volume import NabuVolumeTabWidget from tomwer.gui.reconstruction.axis.EstimatedCORWidget import EstimatedCORWidget from tomwer.tests.utils import skip_gui_test from tomwer.core.process.output import ProcessDataOutputDirMode from tomwer.tests.conftest import qtapp # noqa F401 from tomwer.synctools.axis import QAxisRP class ProcessClass: """Simple class for unit tests""" def __init__(self, name): self.name = name def __str__(self): return self.name @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestNabuFlow(TestCaseQt): def setUp(self) -> None: TestCaseQt.setUp(self) self.nabuWidget = NabuFlowControl(parent=None, direction="vertical") def tearDown(self): self.nabuWidget.setAttribute(qt.Qt.WA_DeleteOnClose) self.nabuWidget.close() del self.nabuWidget def testFlow1(self): style = qt.QApplication.style() icon_1 = style.standardIcon(qt.QStyle.SP_DialogApplyButton) icon_2 = style.standardIcon(qt.QStyle.SP_FileLinkIcon) icon_3 = style.standardIcon(qt.QStyle.SP_ArrowLeft) icon_4 = style.standardIcon(qt.QStyle.SP_ArrowRight) icon_5 = style.standardIcon(qt.QStyle.SP_BrowserStop) preprocess = "reading files", ProcessClass(name="other preprocessing") preprocess_icons = None, icon_1 self.nabuWidget.setPreProcessing(processes=preprocess, icons=preprocess_icons) processes = ( "processing 1", ProcessClass("in between processing"), "other processing", ) processes_icons = icon_2, None, icon_3 self.nabuWidget.setProcessing(processes=processes, icons=processes_icons) postprocess = "post processing", ProcessClass("writing result") postprocess_icons = icon_4, icon_5 self.nabuWidget.setPostProcessing( processes=postprocess, icons=postprocess_icons ) @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestNabuPreProcConfig(TestCaseQt): def setUp(self): TestCaseQt.setUp(self) self.nabuWidget = _NabuPreProcessingConfig(parent=None) def tearDown(self): self.nabuWidget.setAttribute(qt.Qt.WA_DeleteOnClose) self.nabuWidget.close() del self.nabuWidget self.qapp.processEvents() def testGetInitialConfiguration(self): """Test that the get configuration is working""" ini_conf = { "flatfield": 1, "double_flatfield": 0, "dff_sigma": 0.0, "ccd_filter_enabled": 0, "ccd_filter_threshold": 0.04, "log_min_clip": 1e-6, "log_max_clip": 10.0, "take_logarithm": True, "normalize_srcurrent": 0, "sino_rings_correction": RingCorrectionMethod.NONE.value, "sino_rings_options": "sigma=1.0 ; levels=10 ; padding=False", "tilt_correction": "", "autotilt_options": "", "rotate_projections_center": "", } self.assertEqual(self.nabuWidget.getConfiguration(), ini_conf) def testSetConfiguration(self): """Test that the set configuration is working""" conf = { "flatfield": 0, "double_flatfield": 1, "dff_sigma": 2.0, "ccd_filter_enabled": 1, "ccd_filter_threshold": 0.98, "log_min_clip": 1e-3, "log_max_clip": 250.0, "take_logarithm": False, "normalize_srcurrent": 1, "sino_rings_correction": RingCorrectionMethod.MUNCH.value, "sino_rings_options": "sigma=1.4 ; levels=11 ; padding=True", "tilt_correction": "1d-correlation", "autotilt_options": "low_pass=1; high_pass=20", "rotate_projections_center": (2.1, 3.0), } self.nabuWidget.setConfiguration(conf=conf) self.assertEqual(self.nabuWidget.getConfiguration(), conf) @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestNabuPhaseConfig(TestCaseQt): def setUp(self): TestCaseQt.setUp(self) self.nabuWidget = _NabuPhaseConfig(parent=None) def tearDown(self): self.nabuWidget.setAttribute(qt.Qt.WA_DeleteOnClose) self.nabuWidget.close() del self.nabuWidget def testGetInitialConfiguration(self): """Test that the get configuration is working""" ini_conf = { "method": "Paganin", "delta_beta": "100.0", "padding_type": "edge", "unsharp_coeff": 0, "unsharp_sigma": 0, "beam_shape": "parallel", "ctf_advanced_params": " length_scale=1e-05; lim1=1e-05; lim2=0.2; normalize_by_mean=True", "ctf_geometry": " z1_v=None; z1_h=None; detec_pixel_size=None; magnification=True", } self.assertEqual(self.nabuWidget.getConfiguration(), ini_conf) def testSetConfiguration(self): """Test that the set configuration is working""" conf = { "method": "Paganin", "delta_beta": "200.0", "padding_type": "zeros", "unsharp_coeff": 3.6, "unsharp_sigma": 2.1, "beam_shape": "cone", "ctf_advanced_params": " length_scale=1e-05; lim1=1e-05; lim2=0.2; normalize_by_mean=True", "ctf_geometry": " z1_v=0.0; z1_h=0.0; detec_pixel_size=None; magnification=True", } self.nabuWidget.setConfiguration(conf) self.nabuWidget.show() # check visibility of some widgets unsharp_widget = self.nabuWidget._unsharpOpts self.assertEqual(unsharp_widget._unsharpCoeffQLE.text(), "3.6") self.assertTrue(unsharp_widget._unsharpCoeffCB.isChecked()) self.assertEqual(unsharp_widget._unsharpSigmaQLE.text(), "2.1") self.assertTrue(unsharp_widget._unsharpSigmaCB.isChecked()) paganin_widget = self.nabuWidget._paganinOpts self.assertEqual(paganin_widget._deltaBetaQLE.text(), "200.0") self.assertEqual(paganin_widget._paddingTypeCB.currentText(), "zeros") # check the generated configuration self.assertEqual(self.nabuWidget.getConfiguration(), conf) @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestNabuReconstructionConfig(TestCaseQt): def setUp(self): TestCaseQt.setUp(self) self.nabuWidget = _NabuReconstructionConfig(parent=None) def tearDown(self): self.nabuWidget.setAttribute(qt.Qt.WA_DeleteOnClose) self.nabuWidget.close() del self.nabuWidget def testGetInitialConfiguration(self): """Test that the get configuration is working""" ini_conf = { "method": "FBP", "slice_plane": "XY", "angles_file": "", "axis_correction_file": "", "angle_offset": 0.0, "fbp_filter_type": "ramlak", "padding_type": "zeros", "start_x": 0, "end_x": -1, "start_y": 0, "end_y": -1, "start_z": 0, "end_z": -1, "iterations": 200, "optim_algorithm": "chambolle-pock", "regularization_weight": 1.0e-2, "preconditioning_filter": 1, "rotation_axis_position": "", "positivity_constraint": 1, "translation_movements_file": "", "clip_outer_circle": 0, "centered_axis": 0, } self.assertEqual(self.nabuWidget.getConfiguration(), ini_conf) def testSetConfiguration(self): """Test that the set configuration is working""" ini_conf = { "method": "FBP", "slice_plane": "XZ", "angles_file": "", "axis_correction_file": "", "angle_offset": 12.5, "fbp_filter_type": "none", "padding_type": "edges", "start_x": 0, "end_x": 23, "start_y": 12, "end_y": 56, "start_z": 560, "end_z": -1, "iterations": 20, "optim_algorithm": "chambolle-pock", "regularization_weight": 1.5e-2, "preconditioning_filter": 0, "rotation_axis_position": "", "positivity_constraint": 0, "translation_movements_file": "my_file.csv", "clip_outer_circle": 1, "centered_axis": 1, } self.nabuWidget.setConfiguration(ini_conf) self.qapp.processEvents() self.nabuWidget.show() # check visibility of some widgets self.assertEqual(self.nabuWidget._angleOffsetQDSB.value(), 12.5) subRegionWidget = self.nabuWidget._subRegionSelector self.assertFalse(subRegionWidget._xSubRegion._minCB.isChecked()) self.assertFalse(subRegionWidget._xSubRegion._minQLE.isEnabled()) self.assertTrue(subRegionWidget._xSubRegion._maxQLE.isEnabled()) self.assertTrue(subRegionWidget._ySubRegion._minQLE.isEnabled()) self.assertTrue(subRegionWidget._ySubRegion._maxQLE.isEnabled()) self.assertTrue(subRegionWidget._zSubRegion._minQLE.isEnabled()) self.assertFalse(subRegionWidget._zSubRegion._maxQLE.isEnabled()) self.assertFalse(self.nabuWidget._preconditioningFilter.isChecked()) self.assertTrue(self.nabuWidget._clipOuterCircleCB.isChecked()) self.assertTrue(self.nabuWidget._centeredAxisCB.isChecked()) assert self.nabuWidget._axisQCB.currentText() == ini_conf["slice_plane"] # check the generated configuration self.assertEqual(self.nabuWidget.getConfiguration(), ini_conf) @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestNabuOutputConfig(TestCaseQt): """Test the output configuration interface""" def setUp(self): TestCaseQt.setUp(self) self.nabuWidget = _NabuOutputConfig(parent=None) def tearDown(self): self.nabuWidget.setAttribute(qt.Qt.WA_DeleteOnClose) self.nabuWidget.close() self.nabuWidget = None self.qapp.processEvents() def testGetConfiguration(self): ini_conf = { "file_format": "hdf5", "location": "", "output_dir_mode": "same folder as scan", } self.assertEqual(self.nabuWidget.getConfiguration(), ini_conf) def testSetConfiguration(self): conf = { "file_format": "tiff", "location": os.sep.join(("tmp", "my_output")), "output_dir_mode": "other", } self.nabuWidget.setConfiguration(conf) self.nabuWidget.show() self.qapp.processEvents() # check some widget visibility self.assertTrue(self.nabuWidget._output_dir_widget._outputDirQLE.isVisible()) self.assertTrue(self.nabuWidget._output_dir_widget._otherDirRB.isChecked()) self.assertEqual(self.nabuWidget.getConfiguration(), conf) @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestNabuVolumeWidget(TestCaseQt): def setUp(self): TestCaseQt.setUp(self) self.nabuWidget = NabuVolumeTabWidget(parent=None) self.nabuWidget.setConfigurationLevel("advanced") def tearDown(self): self.nabuWidget.setAttribute(qt.Qt.WA_DeleteOnClose) self.nabuWidget.close() self.nabuWidget = None def testGetConfiguration(self): ini_conf = { "start_z": 0, "end_z": -1, "gpu_mem_fraction": 0.9, "output_dir_mode": ProcessDataOutputDirMode.IN_SCAN_FOLDER.value, "overwrite_output_location": False, "postproc": {"output_histogram": 1}, "cpu_mem_fraction": 0.9, "use_phase_margin": True, "new_output_file_format": "", "new_output_location": "", } self.assertEqual(self.nabuWidget.getConfiguration(), ini_conf) def testSetConfiguration(self): conf = { "start_z": 10, "end_z": 24, "gpu_mem_fraction": 0.8, "postproc": {"output_histogram": 0}, "cpu_mem_fraction": 0.1, "use_phase_margin": False, "new_output_file_format": "hdf5", "new_output_location": "/new/location", } self.nabuWidget.setConfiguration(conf) self.qapp.processEvents() # update the config dict has setting an other custom output directory update some items conf.update( { "overwrite_output_location": True, "output_dir_mode": ProcessDataOutputDirMode.OTHER.value, } ) self.assertEqual(self.nabuWidget.getConfiguration(), conf) def test_EstimatedCorWidget(qtapp): # noqa F811 """test of EstimatedCorWidget""" EstimatedCORWidget(parent=None, axis_params=QAxisRP()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/tests/test_saaxis.py0000644000175000017500000001520715153325210024237 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import pint import shutil import tempfile import h5py import numpy import pytest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from silx.io.url import DataUrl from tomwer.core.process.reconstruction.saaxis.params import ( ReconstructionMode, SAAxisParams, ) from tomwer.core.process.reconstruction.scores import ComputedScore from tomwer.core.process.reconstruction.scores.params import ScoreMethod from tomwer.core.utils.scanutils import MockNXtomo from tomwer.gui.reconstruction.saaxis.dimensionwidget import DimensionWidget from tomwer.gui.reconstruction.saaxis.saaxis import SAAxisWindow from tomwer.tests.utils import skip_gui_test _ureg = pint.get_application_registry() @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestDimensionWidget(TestCaseQt): """Test that the axis widget work correctly""" def setUp(self): self._window = DimensionWidget(title="test window") def tearDown(self): self._window.setAttribute(qt.Qt.WA_DeleteOnClose) self._window.close() def testDimension(self): """Insure setting dimensions values and unit are correct""" # check initial values self.assertEqual( self._window.getQuantities(), (1.0 * _ureg.millimeter, 1.0 * _ureg.millimeter, 1.0 * _ureg.millimeter), ) # set dim 0 to 20 mm self._window._dim0ValueQLE.setValue(20) self._window._dim0ValueQLE.editingFinished.emit() self.qapp.processEvents() self.assertEqual( self._window.getQuantities(cast_unit_to=_ureg.meter), (0.02 * _ureg.meter, 0.001 * _ureg.meter, 0.001 * _ureg.meter), ) # set dim 1 to 0.6 millimeter self._window._dim1ValueQLE.setValue(0.6) self._window._dim1ValueQLE.editingFinished.emit() self.qapp.processEvents() self.assertEqual( self._window.getQuantities(cast_unit_to=_ureg.meter), (0.02 * _ureg.meter, 0.0006 * _ureg.meter, 0.001 * _ureg.meter), ) # change display to micrometer self._window.setUnit(_ureg.millimeter) self.assertEqual( self._window.getQuantities(cast_unit_to=_ureg.meter), (0.02 * _ureg.meter, 0.0006 * _ureg.meter, 0.001 * _ureg.meter), ) self.assertEqual( self._window._dim0Value, 20 * _ureg.millimeter, ) self._window._dim2ValueQLE.setValue(500) self._window._dim2ValueQLE.editingFinished.emit() self.qapp.processEvents() self.assertEqual( self._window.getQuantities(cast_unit_to=_ureg.meter), (0.02 * _ureg.meter, 0.0006 * _ureg.meter, 0.5 * _ureg.meter), ) def testConstructorWithColors(self): """Insure passing colors works""" DimensionWidget(title="title", dims_colors=("#ffff5a", "#62efff", "#ff5bff")) def testConstructorWithDimNames(self): """Insure passing colors works""" DimensionWidget(title="title", dims_name=("x", "y", "z")) @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestSAAxisWindow(TestCaseQt): """Test the SAAxisWindow interface""" _N_OUTPUT_URLS = 10 def setUp(self): super().setUp() self._window = SAAxisWindow() self.folder = tempfile.mkdtemp() self._output_urls = [] self._cor_scores = {} for i in range(self._N_OUTPUT_URLS): output_file = os.path.join(self.folder, f"recons_{i}.h5") with h5py.File(output_file, mode="a") as h5f: h5f["data"] = numpy.random.random(100 * 100).reshape(100, 100) url = DataUrl(file_path=output_file, data_path="data", scheme="silx") assert url.is_valid() self._output_urls.append(url) score = ComputedScore( tv=numpy.random.randint(10), std=numpy.random.randint(100), ) self._cor_scores[i] = (url, score) # create a scan self.folder = tempfile.mkdtemp() dim = 10 mock = MockNXtomo( scan_path=self.folder, n_proj=10, n_ini_proj=10, scan_range=180, dim=dim ) mock.add_alignment_radio(index=10, angle=90) mock.add_alignment_radio(index=10, angle=0) self.scan = mock.scan self._window.setScan(self.scan) def tearDown(self): self._window.setAttribute(qt.Qt.WA_DeleteOnClose) self._window.close() self._window = None shutil.rmtree(self.folder) super().tearDown() def testGetConfiguration(self): """Insure configuration getter works""" conf = self._window.getConfiguration() # the configuration should be convertible to conf = SAAxisParams.from_dict(conf) self.assertEqual(conf.slice_indexes, "middle") self.assertEqual(conf.file_format, "hdf5") self.assertTrue(isinstance(conf.nabu_recons_params, dict)) for key in ( "preproc", "reconstruction", "dataset", "tomwer_slices", "output", "phase", ): with self.subTest(key=key): self.assertTrue(key in conf.nabu_recons_params) self.assertEqual(conf._dry_run, False) self.assertEqual(conf.mode, ReconstructionMode.VERTICAL) self.assertEqual(conf.score_method, ScoreMethod.TV_INVERSE) self.assertEqual(conf.output_dir, None) self.assertEqual(conf.scores, None) def testSetConfiguration(self): """Insure configuration setter works""" self._window.setSlicesRange(0, 20) configuration = { "slice_index": {"Slice": 2}, "estimated_cor": 0.24, "research_width": 0.8, "n_reconstruction": 5, } self._window.setConfiguration(configuration) res_conf = self._window.getConfiguration() for key in ( "slice_index", "estimated_cor", "research_width", "n_reconstruction", ): self.assertEqual(configuration[key], res_conf[key]) def testSetResults(self): """Test setting results and saving result to a folder""" self._window.setCorScores(self._cor_scores, score_method="standard deviation") # test saving snapshots with tempfile.TemporaryDirectory() as output_png_imgs: final_dir = os.path.join(output_png_imgs, "test/create/it") self._window.saveReconstructedSlicesTo(final_dir) assert os.path.exists(final_dir) assert len(os.listdir(final_dir)) == len(self._cor_scores) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/reconstruction/tests/test_sadeltabeta.py0000644000175000017500000001061315153325210025214 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import shutil import tempfile import h5py import numpy import pytest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from silx.io.url import DataUrl from tomwer.core.process.reconstruction.sadeltabeta.params import SADeltaBetaParams from tomwer.core.process.reconstruction.scores import ComputedScore from tomwer.core.process.reconstruction.scores.params import ScoreMethod from tomwer.core.utils.scanutils import MockNXtomo from tomwer.gui.reconstruction.sadeltabeta import SADeltaBetaWindow from tomwer.tests.utils import skip_gui_test @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestSADeltaBetaWindow(TestCaseQt): """Test the SAAxisWindow interface""" _N_OUTPUT_URLS = 10 def setUp(self): super().setUp() self._window = SADeltaBetaWindow() self.folder = tempfile.mkdtemp() self._output_urls = [] self._cor_scores = {} for i in range(self._N_OUTPUT_URLS): output_file = os.path.join(self.folder, f"recons_{i}.h5") with h5py.File(output_file, mode="a") as h5f: h5f["data"] = numpy.random.random(100 * 100).reshape(100, 100) url = DataUrl(file_path=output_file, data_path="data", scheme="silx") assert url.is_valid() self._output_urls.append(url) score = ComputedScore( tv=numpy.random.randint(10), std=numpy.random.randint(100), ) self._cor_scores[i] = (url, score) # create a scan self.folder = tempfile.mkdtemp() dim = 10 mock = MockNXtomo( scan_path=self.folder, n_proj=10, n_ini_proj=10, scan_range=180, dim=dim ) mock.add_alignment_radio(index=10, angle=90) mock.add_alignment_radio(index=10, angle=0) self.scan = mock.scan self._window.setScan(self.scan) def tearDown(self): self._window.setAttribute(qt.Qt.WA_DeleteOnClose) self._window.close() self._window = None shutil.rmtree(self.folder) super().tearDown() def testGetConfiguration(self): """Insure configuration getter works""" conf = self._window.getConfiguration() # the configuration should be convertible to conf = SADeltaBetaParams.from_dict(conf) self.assertEqual(conf.slice_indexes, "middle") self.assertTrue(isinstance(conf.nabu_recons_params, dict)) for key in ( "preproc", "reconstruction", "dataset", "tomwer_slices", "output", "phase", ): with self.subTest(key=key): self.assertTrue(key in conf.nabu_recons_params) self.assertEqual(conf._dry_run, False) self.assertEqual(conf.score_method, ScoreMethod.TV_INVERSE) self.assertEqual(conf.output_dir, None) self.assertEqual(conf.scores, None) def testSetConfiguration(self): """Insure configuration setter works""" nabu_specific_params = { "phase": { "padding_type": "zeros", "unsharp_coeff": 5.36, "unsharp_sigma": 4.1, }, } self._window.setSlicesRange(0, 20) configuration = { "slice_index": {"Slice": 2}, "delta_beta_values": (50, 100, 200), "score_method": "standard deviation", "nabu_params": nabu_specific_params, } self._window.setConfiguration(configuration) res_conf = self._window.getConfiguration() for key in ( "slice_index", "delta_beta_values", "score_method", ): self.assertEqual(configuration[key], res_conf[key]) for key, value in nabu_specific_params["phase"].items(): assert value == res_conf["nabu_params"]["phase"][key] def testSetResults(self): """Test setting results""" self._window.setDBScores(self._cor_scores, score_method="total variation") # test saving snapshots with tempfile.TemporaryDirectory() as output_png_imgs: final_dir = os.path.join(output_png_imgs, "test/create/it") self._window.saveReconstructedSlicesTo(final_dir) assert os.path.exists(final_dir) assert len(os.listdir(final_dir)) == len(self._cor_scores) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9411016 tomwer-1.6.17/src/tomwer/gui/samplemoved/0000755000175000017500000000000015153325403017426 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/samplemoved/__init__.py0000644000175000017500000002006015153325210021531 0ustar00paynopayno"""Some widget construction to check if a sample moved""" from __future__ import annotations import logging import weakref from collections import OrderedDict import silx.io.url import silx.io.utils from silx.gui import qt from tomoscan.esrf.scan.utils import get_data from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.gui.samplemoved.selectiontable import AngleSelectionTable from tomwer.gui.settings import Y_AXIS_DOWNWARD _logger = logging.getLogger(__name__) try: from silx.gui.plot.CompareImages import CompareImages except ImportError: _logger.warning("silx >0.7 should be installed to access the SampleMovedWidget") class SampleMovedWidget(qt.QMainWindow): """ Widget used to display two images with different color channel. The goal is to see if the sample has moved during acquisition. """ CONFIGURATIONS = OrderedDict( [ ("0-0(1)", (("0", "0.0", 0), ("0(1)", "0.0 (1)"))), ("90-90(1)", (("90", "90.0", 90), ("90(1)", "90.0 (1)"))), ("180-180(1)", (("180", "180.0", 180), ("180(1)", "180.0 (1)"))), ("270-270(1)", (("270", "270.0", 270), ("270(1)", "270.0 (1)"))), ("360-0", (("360", "360.0", 360), ("0", "0.0"))), ] ) """Define possible configurations for comparison. Key is the name of the configuration, value contains a couple valid values for the necessary two projections """ def __init__(self, parent=None, backend=None): qt.QMainWindow.__init__(self, parent) self._scan = None self.setWindowFlags(qt.Qt.Widget) self._isConnected = False self._images = {} self._symmetricalStates = {"first": False, "second": False} self._plot = CompareImages(parent=self, backend=backend) self._plot.setWindowFlags(qt.Qt.Widget) self._plot.getPlot().setYAxisInverted(Y_AXIS_DOWNWARD) self._on_load_callback = [] self._topWidget = self.getControlWidget() self._dockWidgetMenu = qt.QDockWidget(parent=self) self._dockWidgetMenu.layout().setContentsMargins(0, 0, 0, 0) self._dockWidgetMenu.setFeatures(qt.QDockWidget.DockWidgetMovable) self._dockWidgetMenu.setWidget(self._topWidget) self.addDockWidget(qt.Qt.BottomDockWidgetArea, self._dockWidgetMenu) self._plotsWidget = qt.QWidget(parent=self) self._plotsWidget.setLayout(qt.QHBoxLayout()) self._plotsWidget.layout().addWidget(self._plot) self.setCentralWidget(self._plotsWidget) if hasattr(self._selectorCB, "currentTextChanged"): self._selectorCB.currentTextChanged.connect(self.setConfiguration) else: self._selectorCB.currentIndexChanged["QString"].connect( self.setConfiguration ) self._selectionTable.sigImageAChanged.connect(self._setConfigManual) self._selectionTable.sigImageBChanged.connect(self._setConfigManual) # expose API self.setSelection = self._selectionTable.setSelection def getControlWidget(self): if hasattr(self, "_topWidget"): return self._topWidget self._topWidget = qt.QWidget(parent=self) self._configWidget = qt.QWidget(parent=self._topWidget) self._configWidget.setLayout(qt.QHBoxLayout()) self._configWidget.layout().addWidget( qt.QLabel("Configuration:", parent=self._topWidget) ) self._selectorCB = qt.QComboBox(parent=self._topWidget) self._configWidget.layout().addWidget(self._selectorCB) self._selectionTable = AngleSelectionTable(parent=self._topWidget) self._topWidget.setLayout(qt.QVBoxLayout()) self._topWidget.layout().setContentsMargins(0, 0, 0, 0) self._topWidget.layout().addWidget(self._configWidget) self._topWidget.layout().addWidget(self._selectionTable) self._selectionTable.sigImageAChanged.connect(self._changeImageA) self._selectionTable.sigImageBChanged.connect(self._changeImageB) return self._topWidget def setOnLoadAction(self, action): self._on_load_callback.append(action) def clearOnLoadActions(self): self._on_load_callback = [] def clear(self): self._selectorCB.clear() self._selectionTable.clear() self._images = {} @property def scan(self): if self._scan is None or self._scan() is None: return None else: return self._scan() def setScan(self, scan): if scan is None: self._scan = None elif not isinstance(scan, TomwerScanBase): raise TypeError( f"scan is expected to be None or an instance of {TomwerScanBase}. {type(scan)} provided" ) else: self._scan = weakref.ref(scan) def setImages(self, images): """ Set the images in a key value system. Key should be in (0, 90, 180, 270) and the value should be the image. images value can be str (path to the file) or data :param images: images to set. key is index or file name, value the image. """ self.clear() self._images = images # update the default config self._selectorCB.clear() def contains_at_least_one_key(keys): for key in keys: if key in images.keys(): return True return False self._selectorCB.blockSignals(True) for config in self.CONFIGURATIONS: proj_0_keys, proj_1_keys = self.CONFIGURATIONS[config] if contains_at_least_one_key(proj_0_keys) and contains_at_least_one_key( proj_1_keys ): self._selectorCB.addItem(config) self._selectorCB.addItem("manual") for angleValue, file_path in images.items(): self._selectionTable.addRadio(name=file_path, angle=angleValue) self._selectorCB.setCurrentIndex(0) self._selectorCB.blockSignals(False) if hasattr(self._selectorCB, "currentTextChanged"): self._selectorCB.currentTextChanged.emit(self._selectorCB.currentText()) else: self._selectorCB.currentIndexChanged["QString"].emit( self._selectorCB.currentText() ) def _updatePlot(self): imgA, imgB = self._selectionTable.getSelection() dataImgA = self._changeImageA(imgA) dataImgB = self._changeImageA(imgB) if dataImgA is not None and dataImgB is not None: self._plot.setData(image1=dataImgA, image2=dataImgB) def _changeImageA(self, img): if img is not None: imgAUrl = silx.io.url.DataUrl(path=img) if self.scan is None: dataImgA = get_data(imgAUrl) else: idxImgA = self.scan.get_url_proj_index(imgAUrl) dataImgA = self.scan.flat_field_correction((imgAUrl,), (idxImgA,))[0] self._plot.setImage1(image1=dataImgA) return dataImgA def _changeImageB(self, img): if img is not None: imgBUrl = silx.io.url.DataUrl(path=img) if self.scan is None: dataImgB = get_data(imgBUrl) else: idxImgB = self.scan.get_url_proj_index(imgBUrl) dataImgB = self.scan.flat_field_correction((imgBUrl,), (idxImgB,))[0] self._plot.setImage2(image2=dataImgB) return dataImgB def setConfiguration(self, config): if config == "manual": return if config not in self.CONFIGURATIONS: _logger.warning("Undefined configuration: %s" % config) return self._selectionTable.blockSignals(True) self._selectionTable.setAngleSelection( self.CONFIGURATIONS[config][0], self.CONFIGURATIONS[config][1] ) self._updatePlot() self._selectionTable.blockSignals(False) def _setConfigManual(self): indexItemManual = self._selectorCB.findText("manual") if indexItemManual >= 0: self._selectorCB.setCurrentIndex(indexItemManual) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/samplemoved/selectiontable.py0000644000175000017500000001744015153325210022777 0ustar00paynopayno"""Some widget construction to check if a sample moved""" from __future__ import annotations import functools import logging import os from collections import OrderedDict from silx.gui import qt from silx.io.url import DataUrl from tomwer.gui.imagefromfile import FileWithImage logger = logging.getLogger(__name__) class SelectionTable(qt.QTableWidget): """Table used to select the color channel to be displayed for each""" COLUMS_INDEX = OrderedDict([("url", 0), ("img A", 1), ("img B", 2)]) sigImageAChanged = qt.Signal(str) """Signal emitted when the image A change. Param is the image url path""" sigImageBChanged = qt.Signal(str) """Signal emitted when the image B change. Param is the image url path""" def __init__(self, parent=None): qt.QTableWidget.__init__(self, parent) self.clear() def clear(self): qt.QTableWidget.clear(self) self.setRowCount(0) self.setColumnCount(len(self.COLUMS_INDEX)) self.setHorizontalHeaderLabels(list(self.COLUMS_INDEX.keys())) self.horizontalHeader().setSectionResizeMode(qt.QHeaderView.ResizeToContents) self.verticalHeader().hide() self.setSortingEnabled(True) self._checkBoxes = {} def addRadio(self, name, **kwargs): if isinstance(name, DataUrl): self.addUrl(name, **kwargs) else: assert os.path.isfile(name) if not os.path.isfile(name): logger.error("%s is not a file path" % name) return imgFile = FileWithImage(name) for imgFrmFile in imgFile.getImages(_load=False): self.addUrl(imgFrmFile.url, **kwargs) def addUrl(self, url: DataUrl, **kwargs) -> int: """ :param url: DataUrl to add :return: index of the created items row """ assert isinstance(url, DataUrl) row = self.rowCount() self.setRowCount(row + 1) # nasty hack, should be done in silx or in tomoscan data_path_label = qt.QLabel(url.path()) self.setCellWidget(row, self.COLUMS_INDEX["url"], data_path_label) widgetImgA = qt.QCheckBox(self) self.setCellWidget(row, self.COLUMS_INDEX["img A"], widgetImgA) callbackImgA = functools.partial(self._activeImgAChanged, url.path()) widgetImgA.toggled.connect(callbackImgA) widgetImgB = qt.QCheckBox(self) self.setCellWidget(row, self.COLUMS_INDEX["img B"], widgetImgB) callbackImgB = functools.partial(self._activeImgBChanged, url.path()) widgetImgB.toggled.connect(callbackImgB) self._checkBoxes[url.path()] = {"img A": widgetImgA, "img B": widgetImgB} return row def _activeImgAChanged(self, name): self._updatecheckBoxes("img A", name) self.sigImageAChanged.emit(name) def _activeImgBChanged(self, name): self._updatecheckBoxes("img B", name) self.sigImageBChanged.emit(name) def _updatecheckBoxes(self, whichImg, name): assert name in self._checkBoxes assert whichImg in self._checkBoxes[name] if self._checkBoxes[name][whichImg].isChecked(): for radioUrl in self._checkBoxes: if radioUrl != name: self._checkBoxes[radioUrl][whichImg].blockSignals(True) self._checkBoxes[radioUrl][whichImg].setChecked(False) self._checkBoxes[radioUrl][whichImg].blockSignals(False) def getSelection(self, with_indexes=False): """ :return: url selected for img A and img B. """ imgA = imgB = None for radioUrl in self._checkBoxes: if self._checkBoxes[radioUrl]["img A"].isChecked(): imgA = radioUrl if self._checkBoxes[radioUrl]["img B"].isChecked(): imgB = radioUrl if with_indexes: raise NotImplementedError else: return imgA, imgB def setSelection(self, url_img_a, url_img_b): """ :param ddict: key: image url, values: list of active channels """ if isinstance(url_img_a, qt.QRect) or isinstance(url_img_b, qt.QRect): return for radioUrl in self._checkBoxes: for img in ("img A", "img B"): self._checkBoxes[radioUrl][img].blockSignals(True) self._checkBoxes[radioUrl][img].setChecked(False) self._checkBoxes[radioUrl][img].blockSignals(False) self._checkBoxes[radioUrl][img].blockSignals(True) self._checkBoxes[url_img_a]["img A"].setChecked(True) self._checkBoxes[radioUrl][img].blockSignals(False) self._checkBoxes[radioUrl][img].blockSignals(True) self._checkBoxes[url_img_b]["img B"].setChecked(True) self._checkBoxes[radioUrl][img].blockSignals(False) self.sigImageAChanged.emit(url_img_a) self.sigImageBChanged.emit(url_img_b) class AngleSelectionTable(SelectionTable): """The selection table but with the angle column. Allows to make selection on angles to """ class _AngleItem(qt.QTableWidgetItem): """Simple QTableWidgetItem allowing ordering on angles""" def __init__(self, type=qt.QTableWidgetItem.Type): qt.QTableWidgetItem.__init__(self, type=type) def __lt__(self, other): a1 = IntAngle(self.text()) a2 = IntAngle(other.text()) return a1 < a2 COLUMS_INDEX = OrderedDict( [("angle", 0), ("file name", 1), ("url", 2), ("img A", 3), ("img B", 4)] ) def __init__(self, parent): SelectionTable.__init__(self, parent) self._anglesToUrl = {} def addUrl(self, url, **kwargs): assert "angle" in kwargs row = SelectionTable.addUrl(self, url, **kwargs) _item = qt.QTableWidgetItem() _item.setText(os.path.basename(url.file_path())) _item.setFlags(qt.Qt.ItemIsEnabled | qt.Qt.ItemIsSelectable) self.setItem(row, self.COLUMS_INDEX["file name"], _item) angle = "???" if "angle" in kwargs: angle = kwargs["angle"] item = self._AngleItem() item.setText(str(angle)) self.setItem(row, self.COLUMS_INDEX["angle"], item) self._anglesToUrl[angle] = url.path() def setAngleSelection(self, angle_a_values, angle_b_values): """ :param tuple angle_a_values: tuple of valid angle for angle a :param tuple angle_b_values: tuple of valid angle for angle b """ url_angle_a = url_angle_b = None for angle_a_val in angle_a_values: if angle_a_val in self._anglesToUrl: url_angle_a = self._anglesToUrl[angle_a_val] break for angle_b_value in angle_b_values: if angle_b_value in self._anglesToUrl: url_angle_b = self._anglesToUrl[angle_b_value] break self.setSelection(url_angle_a, url_angle_b) def clear(self): SelectionTable.clear(self) self._anglesToUrl = {} class IntAngle(str): """Simple class used to order angles""" def __new__(cls, *args, **kwargs): return str.__new__(cls, *args, **kwargs) def getAngle(self): """Return the acquisition angle as an int""" val = self if "(" in self: val = self.split("(")[0] if val.isdigit() is False: return False else: return int(val) def getAngleN(self): """Return the second information if the acquisition is the first one taken at this angle or not.""" if "(" not in self: return 0 return int(self.split("(")[1][:-1]) def __lt__(self, other): if self.getAngle() == other.getAngle(): return self.getAngleN() < other.getAngleN() else: return self.getAngle() < other.getAngle() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/settings.py0000644000175000017500000000062415153325210017322 0ustar00paynopayno"""gui settings""" from silx.gui import qt Y_AXIS_DOWNWARD = True """Default axis direction Y""" EDITING_BACKGROUND_COLOR = qt.QColor("#c3d0d6") """Background color used to notify the user that application waits end of edition before taking it into account""" TAB_LABEL_PLATFORM_SETTINGS = "platform settings (for local reconstruction)" TAB_LABEL_RECONSTRUCTION_SETTINGS = "reconstruction settings" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/stackplot.py0000644000175000017500000000673715143647637017524 0ustar00paynopayno"""Contains the QImageFileStackPlot. Widget to display a set of files with metadata (either scan or volume metadata)""" from __future__ import annotations import logging import os import time from silx.gui import qt from tomwer.gui.visualization.imagestack import ImageStack from . import utils logger = logging.getLogger(__name__) class QImageFileStackPlot(ImageStack): """ Widget based on ImageStack and adding some widget to display metadata associated with urls. Like Paganin delta / beta values... """ def __init__(self, parent, show_overview=True, backend=None): """ Constructor :param parent: the Qt parent widget """ super().__init__(parent, show_overview=show_overview) self._plot.setBackend(backend=backend) self._imagejThreads = [] # dock widget: qslider self._plot.layout() self._fileInfoDockWidget = qt.QDockWidget(parent=self) self._fileInfoWidget = self.__buildFileInfo() self._fileInfoDockWidget.setWidget(self._fileInfoWidget) self.addDockWidget(qt.Qt.BottomDockWidgetArea, self._fileInfoDockWidget) self._fileInfoDockWidget.setFeatures(qt.QDockWidget.DockWidgetMovable) # connect signal / slot self._openWithImjButton.released.connect(self._openCurrentInImagej) self.sigCurrentUrlChanged.connect(self._updateUrlInfos) def __buildFileInfo(self): self._fileInfoWidget = qt.QWidget(parent=self) layout = qt.QGridLayout() layout.setContentsMargins(0, 0, 0, 0) self._fileInfoWidget.setLayout(layout) # file name label layout.addWidget(qt.QLabel("file :", self._fileInfoWidget), 0, 0, 1, 1) self._qlFileName = qt.QLabel("", parent=self._fileInfoWidget) layout.addWidget(self._qlFileName, 0, 1, 1, 2) # open in image j button style = qt.QApplication.style() open_icon = style.standardIcon(qt.QStyle.SP_FileLinkIcon) self._openWithImjButton = qt.QPushButton( open_icon, "open with ImageJ", parent=self ) self._openWithImjButton.setSizePolicy( qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum ) layout.addWidget(self._openWithImjButton, 0, 3, 1, 1) # date last modification layout.addWidget( qt.QLabel("last modification :", self._fileInfoWidget), 1, 0, 1, 1 ) self._qlLastModifications = qt.QLabel("", parent=self._fileInfoWidget) layout.addWidget(self._qlLastModifications, 1, 1, 1, 2) return self._fileInfoWidget def _openCurrentInImagej(self): current_url = self.getCurrentUrl() if current_url is None: logger.warning("No active image defined") else: try: self._imagejThreads.append(utils.open_url_with_image_j(current_url)) except OSError as e: msg = qt.QMessageBox(self) msg.setIcon(qt.QMessageBox.Warning) msg.setWindowTitle("Unable to open image in imagej") msg.setText(str(e)) msg.exec() def _updateUrlInfos(self): url = self.getCurrentUrl() name = url.file_path().split(os.path.sep)[-1] self._qlFileName.setText(name) self._qlFileName.setToolTip(url.path()) try: last_mod = time.ctime(os.path.getmtime(url.file_path())) except Exception: last_mod = "" self._qlLastModifications.setText(last_mod) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/stacks.py0000644000175000017500000003257615153325210016765 0ustar00paynopayno"""Some widget construction to check if a sample moved""" from __future__ import annotations import logging import sys import h5py from silx.gui import qt from silx.io.url import DataUrl from .metadataloader import VolumeMetadataLoader from tomwer.core.tomwer_object import TomwerObject from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.volume.volumefactory import VolumeFactory from tomwer.core.volume.volumebase import TomwerVolumeBase from tomwer.io.utils.tomoobj import get_tomo_objs_instances from tomwer.gui.dialog.QDataDialog import QDataDialog from tomwer.gui.stackplot import QImageFileStackPlot from tomwer.gui.utils.loadingmode import LoadingModeToolButton, LoadingMode _logger = logging.getLogger(__name__) class _ImageStack(qt.QMainWindow): """ Base class to :class:`SliceStack` and :class:`RadioStack` classes. Define the common layout and interaction. """ METADATA_LOADER_CLASS = None SHOW_SCAN_OVERVIEW = True SHOW_VOLUME_METADATA_OVERVIEW = True sigMetadataLoaded = qt.Signal() def __init__(self, parent=None, backend=None): super().__init__(parent) self.setWindowFlags(qt.Qt.Widget) self._viewer = QImageFileStackPlot( parent=self, backend=backend, show_overview=self.SHOW_SCAN_OVERVIEW ) if not self.SHOW_VOLUME_METADATA_OVERVIEW: self._viewer._reconsInfoDockWidget.hide() self.setCentralWidget(self._viewer) self._actionsToolbar = qt.QToolBar() self.addToolBar(qt.Qt.RightToolBarArea, self._actionsToolbar) self._clearAction = _ClearAction(parent=self._actionsToolbar) self._actionsToolbar.addAction(self._clearAction) self._clearAction.triggered.connect(self.clear) self._addTomoObjAction = _AddTomoObjectAction(parent=self._actionsToolbar) self._actionsToolbar.addAction(self._addTomoObjAction) self._addTomoObjAction.triggered.connect(self._callbackAddNewTomoObjFrmDialog) self._loadingMode = LoadingModeToolButton(parent=self) self._actionsToolbar.addWidget(self._loadingMode) # connect signal / slot self.sigMetadataLoaded.connect(self._viewer._updateUrlInfos) self._loadingMode.sigLoadModeChanged.connect(self.setLoadingMode) def addTomoObj(self, tomo_obj: TomwerObject | str): raise NotImplementedError def _callbackAddNewTomoObjFrmDialog(self) -> None: dialog = QDataDialog(self, multiSelection=True) dialog.setNameFilters( [ "Any files (*)", "HDF5 files (*.h5 *.hdf5 *.nx *.nxs *.nexus)", "Nexus files (*.nx *.nxs *.nexus)", ] ) if not dialog.exec(): dialog.close() return self._addTomoObjectsFromStrList(dialog.files_selected()) def _addTomoObjectsFromStrList(self, str_list: list[str]) -> None: tomo_objects, _ = get_tomo_objs_instances(str_list) for tomo_obj in tomo_objects: self.addTomoObj(tomo_obj) def clear(self): self._viewer.reset() def close(self) -> None: # clearing free the loading thread. Safer to remove them when closing self.clear() super().close() def setLoadingMode(self, mode: LoadingMode | str) -> None: mode = LoadingMode(mode) if mode is LoadingMode.LAZY_LOADING: # set to the default N_PRELOAD value n_prefetch = self._viewer.N_PRELOAD else: n_prefetch = sys.maxsize self._viewer.setNPrefetch(n_prefetch) class _ClearAction(qt.QAction): def __init__(self, parent): style = qt.QApplication.instance().style() icon = style.standardIcon(qt.QStyle.SP_DialogResetButton) qt.QAction.__init__(self, icon, "Clear", parent) class _AddTomoObjectAction(qt.QAction): def __init__(self, parent): style = qt.QApplication.instance().style() icon = style.standardIcon(qt.QStyle.SP_DirIcon) qt.QAction.__init__(self, icon, "Add tomo object", parent) class SliceStack(_ImageStack): """ Widget displaying all slices contained in a list of acquisition folder """ SHOW_SCAN_OVERVIEW = False SHOW_VOLUME_METADATA_OVERVIEW = True METADATA_LOADER_CLASS = VolumeMetadataLoader def __init__(self, parent=None, backend=None): super().__init__(parent, backend) self._loadingMetadataThreads = [] "list of thread processing metadata loading" self._volume_id_to_urls: dict[str, tuple[DataUrl]] = {} # allow user to edit the list (user can remove an url) url_list = self._viewer._urlsTable._urlsTable url_list.setEditable(True) # allow multiple selection (more convenient when users want to remove a set of url) # not for now: seems to have a bug on it # url_list.setSelectionMode(qt.QAbstractItemView.MultiSelection) @property def url_to_volume_id(self, volume_id) -> str | None: urls_to_volume_id = { (value, key) for key, value in self._volume_id_to_urls.items() } return urls_to_volume_id.get(volume_id, None) def getImagesUrls(self) -> dict[str, dict]: """ Parse all self._scans and find the images to be displayed on the widget :return: images to display for each scan. Key is the volume identifier, value is a dict with index as key and DataUrl as value """ slices = {} for volume in self._tomoObjects.values(): assert isinstance(volume, TomwerVolumeBase) slices[volume.get_identifier().to_str()] = tuple(volume.browse_data_urls()) return slices def __tomoObjIdToInstance(self, tomo_obj: TomwerObject | str) -> TomwerObject: """Convert a tomo obj to it TomwerObject""" if isinstance(tomo_obj, str): try: tomo_obj = VolumeFactory.create_tomo_object_from_identifier(tomo_obj) except (ValueError, TypeError) as e1: try: tomo_obj = ScanFactory.create_tomo_object_from_identifier(tomo_obj) except (ValueError, TypeError) as e2: raise ValueError( f"Unable to create a tomo object from {tomo_obj}. Errors are {e1}, {e2}" ) return tomo_obj def addTomoObj(self, tomo_obj: TomwerObject | str): tomo_obj = self.__tomoObjIdToInstance(tomo_obj=tomo_obj) if isinstance(tomo_obj, TomwerScanBase): reconstructed_volumes = ( tomo_obj.latest_reconstructions or tomo_obj.get_reconstructed_slices() ) for volume_id in reconstructed_volumes: if isinstance(volume_id, str): volume_id_as_str = volume_id elif isinstance(volume_id, TomwerVolumeBase): volume_id_as_str = volume_id.get_identifier().to_str() else: volume_id_as_str = volume_id.to_str() self.addTomoObj(tomo_obj=volume_id_as_str) elif isinstance(tomo_obj, TomwerVolumeBase): self._addVolume(volume=tomo_obj) # set the latest slice as the active one try: active_url = next(tomo_obj.browse_data_urls()) except StopIteration: pass else: try: self._viewer.setCurrentUrl(active_url) except Exception: # the url might not exist or might have been removed. # Because each tome we add an object the urls are reset # FIXME: in this case the urls must be updated instead of resetting pass else: raise TypeError(f"tomo obj type is not handled ({type(tomo_obj)})") def _addVolume(self, volume: TomwerVolumeBase): new_urls = [url.path() for url in volume.browse_data_urls()] self._volume_id_to_urls[volume.get_identifier().to_str()] = tuple(new_urls) self._loadMetadata(volume) # work around. See issue: TODO add silx issue if self._viewer._urlIndexes is None: current_urls = tuple() else: current_urls = self._viewer.getUrls() or tuple() updated_urls = {*new_urls} | {*current_urls} updated_urls = tuple([DataUrl(path=url_path) for url_path in updated_urls]) self._viewer.setUrls(updated_urls) def setCurrentUrl(self, url: DataUrl): if url in ("", None): url = None elif isinstance(url, str): url = DataUrl(path=url) elif not isinstance(url, DataUrl): raise TypeError if url is None: pass # FIXME: add a function to clear the metadata widget super().setCurrentUrl(url) # metadata loading def _load(self, url: DataUrl): # load the frame super()._load() # load metadata url_path = url.path() volume_id = self.url_to_volume_id(url_path) if volume_id is None: _logger.warning(f"Failed to find volume associated to {url_path}") return volume = VolumeFactory.create_tomo_object_from_identifier(volume_id) if volume not in self._loadingMetadataThreads: # if a thread is already loading metadata for this volume avoid launching another thread for it self._loadMetadata(tomo_obj=volume) def _loadMetadata(self, tomo_obj: TomwerObject): if not isinstance(tomo_obj, TomwerObject): raise TypeError( f"volume should be an instance of {TomwerObject}. Got {type(tomo_obj)} instead" ) loader = self.METADATA_LOADER_CLASS( tomo_obj_identifier=tomo_obj.get_identifier().to_str(), parent=self ) loader.finished.connect(self._metadataLoaded, qt.Qt.QueuedConnection) self._loadingMetadataThreads.append(loader) loader.start() def _metadataLoaded(self): sender = self.sender() if sender in self._loadingMetadataThreads: self._loadingMetadataThreads.remove(sender) self._viewer.updateSliceMetadata( {url.path(): sender.metadata for url in sender.volume.browse_data_urls()} ) self.sigMetadataLoaded.emit() def _freeMetadataLoadingThreads(self): for thread in self._loadingMetadataThreads: thread.blockSignals(True) thread.wait(50) self._loadingMetadataThreads.clear() def close(self): # clearing free the loading thread. Safer to remove them when closing self._freeMetadataLoadingThreads() super().close() def clear(self): self._volume_id_to_urls.clear() self._freeMetadataLoadingThreads() super().clear() class RadioStack(_ImageStack): """ Widget displaying all radio contained in a list of acquisition folder """ SHOW_SCAN_OVERVIEW = True SHOW_VOLUME_METADATA_OVERVIEW = False def getImagesUrls(self) -> dict: """ Parse all self._scans and find the images to be displayed on the widget :return: images to display for each scan """ slices = {} for scan in self._tomoObjects.values(): # manage hdf5 if isinstance(scan, TomwerScanBase): imgs = scan.projections if len(imgs) > 0: slices[str(scan)] = imgs elif h5py.is_hdf5(scan): try: scans = ScanFactory.create_scan_objects(scan_path=scan) except Exception as e: _logger.warning(e) else: for scan_ in scans: imgs = scan_.projections if len(imgs) > 0: slices[str(scan_)] = imgs else: # manage edf try: scan_ = ScanFactory.create_scan_object(scan_path=scan) except ValueError: pass else: imgs = scan_.projections if len(imgs) > 0: slices[scan] = imgs return slices def addTomoObj(self, tomo_obj: TomwerScanBase | str): if isinstance(tomo_obj, str): try: tomo_obj = ScanFactory.create_tomo_object_from_identifier(tomo_obj) except (ValueError, TypeError) as e: _logger.error( f"Fail to create a scan object from {tomo_obj}. Error is {e}" ) if not isinstance(tomo_obj, TomwerScanBase): raise TypeError( f"tomo_obj should be an instance of {TomwerScanBase}. Get {type(tomo_obj)}" ) self._addScan(scan=tomo_obj) self._viewer.updateScanToUrl( {url.path(): tomo_obj for url in tomo_obj.projections.values()} ) def _addScan(self, scan: TomwerScanBase): new_urls = tuple([url.path() for url in scan.projections.values()]) # work around. See issue: TODO add silx issue if self._viewer._urlIndexes is None: current_urls = tuple() else: current_urls = self._viewer.getUrls() or tuple() updated_urls = {*new_urls} | {*current_urls} updated_urls = tuple([DataUrl(path=url_path) for url_path in updated_urls]) self._viewer.setUrls(updated_urls) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9451017 tomwer-1.6.17/src/tomwer/gui/stitching/0000755000175000017500000000000015153325403017106 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/stitching/SingleAxisStitchingWidget.py0000644000175000017500000003326615153325210024555 0ustar00paynopaynofrom __future__ import annotations import logging from nabu.stitching.config import StitchingType from nabu.stitching.config import identifiers_as_str_to_instances from nxtomomill.models.utils import convert_str_to_tuple as _convert_str_to_tuple from silx.gui import qt from tomoscan.series import Series from tomoscan.scanbase import TomoScanBase as _TomoScanBase from tomoscan.volumebase import VolumeBase as _VolumeBase from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.volume.volumefactory import VolumeFactory from tomwer.core.volume.volumebase import TomwerVolumeBase from tomwer.core.tomwer_object import TomwerObject from tomwer.gui.stitching.stitching_preview import PreviewStitchingPlot from tomwer.gui.stitching.stitching_raw import RawStitchingPlot from tomwer.gui.stitching.axisorderedlist import EditableOrderedTomoObjWidget from .singleaxis import _SingleAxisMixIn _logger = logging.getLogger(__name__) def convert_str_to_tuple(input_str, none_if_empty): if input_str is None: return None elif isinstance(input_str, (tuple, list)): return tuple(input_str) else: return _convert_str_to_tuple(input_str=input_str, none_if_empty=none_if_empty) class SingleAxisStitchingWidget(qt.QWidget, _SingleAxisMixIn): """ Main widget for (single axis) stitching. It contains display and options definition. """ sigStitchingTypeChanged = qt.Signal(str) """emit when stitching type changes""" sigTomoObjsLoaded = qt.Signal(tuple) """Signal emit when during setting a configuration this trigger some addition of tomo object""" def __init__(self, axis: int, parent=None) -> None: super().__init__(parent) assert axis in (0, 1, 2) self._axis = axis # used from _SingleAxisMixIn interface self.setLayout(qt.QGridLayout()) self._stitchingTypeCB = qt.QComboBox(parent=self) # filter stitching types that does belong to the axis (GUI is specific to a given axis. The other have no sense at this level) stitching_types = filter( lambda s_type: s_type.lower().startswith(self.axis_alias(axis).lower()), [item.value for item in StitchingType], ) for mode in stitching_types: self._stitchingTypeCB.addItem(mode) self._stitchingTypeCB.currentIndexChanged.connect(self._stitchingTypeChanged) self.layout().addWidget(qt.QLabel("stitching method:"), 0, 0, 1, 1) self.layout().addWidget(self._stitchingTypeCB, 0, 1, 1, 1) self._mainWidget = _SingleAxisStitchingCentralTabWidget(parent=self, axis=axis) self.layout().addWidget(self._mainWidget, 1, 0, 4, 4) # set up self.setStitchingType(self.getStitchingType()) self._mainWidget.setCurrentWidget(self._mainWidget._previewPlot) # connect signal / slot self._stitchingTypeCB.currentIndexChanged.connect(self._stitchingTypeChanged) def close(self): self._mainWidget.close() # requested for the waiting plot update super().close() def clean(self): self._mainWidget.clean() def _stitchingTypeChanged(self, *args, **kwargs): self.sigStitchingTypeChanged.emit(self.getStitchingType().value) def getStitchingType(self): return StitchingType(self._stitchingTypeCB.currentText()) def setStitchingType(self, mode): mode = StitchingType(mode) idx = self._stitchingTypeCB.findText(mode.value) if idx >= 0: self._stitchingTypeCB.setCurrentIndex(idx) def get_available_pre_processing_stitching_mode(self): pre_proc_modes: tuple[str] = tuple( filter( lambda mode: "preproc" in mode, [ self._stitchingTypeCB.itemText(i_item) for i_item in range(self._stitchingTypeCB.count()) ], ) ) return tuple([StitchingType(mode) for mode in pre_proc_modes]) def get_available_post_processing_stitching_mode(self): post_proc_modes: tuple[str] = tuple( filter( lambda mode: "postproc" in mode, [ self._stitchingTypeCB.itemText(i_item) for i_item in range(self._stitchingTypeCB.count()) ], ) ) return tuple([StitchingType(mode) for mode in post_proc_modes]) def addTomoObj(self, tomo_obj: TomwerObject): self._mainWidget.addTomoObj(tomo_obj) self._updatePreviewPixelSize() def getTomoObjs(self) -> tuple: return self._mainWidget.getTomoObjs() def removeTomoObj(self, tomo_obj: TomwerObject): self._mainWidget.removeTomoObj(tomo_obj) self._updatePreviewPixelSize() def _updatePreviewPixelSize(self): """update the pixel size of the preview from existing tomo obj""" def get_pixel_size(): tomo_objs = self._mainWidget.getTomoObjs() for tomo_obj in tomo_objs: if ( isinstance(tomo_obj, NXtomoScan) and tomo_obj.sample_x_pixel_size is not None and tomo_obj.sample_y_pixel_size is not None ): return tomo_obj.sample_x_pixel_size, tomo_obj.sample_y_pixel_size elif ( isinstance(tomo_obj, TomwerVolumeBase) and tomo_obj.voxel_size is not None ): # warning: axis are inverted between the volume and the voxel_size. voxel_size are given as (x, y, z) instead of (z, y, x) return ( tomo_obj.voxel_size[2 - self.first_axis], tomo_obj.voxel_size[2 - self.first_axis], ) return None, None pixel_size = get_pixel_size() self._mainWidget._previewPlot.setPixelSize(pixel_size_m=pixel_size) def getConfiguration(self) -> dict: # missing parameters: # * overwrite # * slices # * slurm stuff... tomo_objs = self._mainWidget.getTomoObjs() def filter_empty_list_and_cast_as_int(elmts): new_list = [int(elmt) for elmt in elmts if elmt is not None] if len(new_list) == 0: return None else: return elmts first_axis_pos_px = filter_empty_list_and_cast_as_int( [ obj.stitching_metadata.get_abs_position_px(axis=self.first_axis) or 0 for obj in tomo_objs ] ) second_axis_pos_px = filter_empty_list_and_cast_as_int( [ obj.stitching_metadata.get_abs_position_px(axis=self.second_axis) or 0 for obj in tomo_objs ] ) return { "stitching": { "type": self.getStitchingType().value, f"axis_{self.first_axis}_pos_px": ( "" if first_axis_pos_px is None else first_axis_pos_px ), f"axis_{self.second_axis}_pos_px": ( "" if second_axis_pos_px is None else second_axis_pos_px ), }, "inputs": { "input_datasets": [obj.get_identifier().to_str() for obj in tomo_objs], }, } def setConfiguration(self, config: dict) -> None: stitching_type = config.get("stitching", {}).get("type", None) if stitching_type is not None: self.setStitchingType(stitching_type) tomo_obj_ids = config.get("inputs", {}).get("input_datasets", None) tomo_obj_ids = identifiers_as_str_to_instances(tomo_obj_ids) first_axis_pos = convert_str_to_tuple( config.get("stitching", {}).get(f"axis_{self.first_axis}_pos_px", None), none_if_empty=True, ) second_axis_pos = convert_str_to_tuple( config.get("stitching", {}).get(f"axis_{self.second_axis}_pos_px", None), none_if_empty=True, ) if tomo_obj_ids is not None: self._mainWidget.clearTomoObjs() if first_axis_pos is None: first_axis_pos = [None] * len(tomo_obj_ids) if second_axis_pos is None: second_axis_pos = [None] * len(tomo_obj_ids) if len(first_axis_pos) != len(tomo_obj_ids): _logger.error( f"incoherent axis {self.first_axis} position compared to the number of input datasets. Will ignore those" ) first_axis_pos = [None] * len(tomo_obj_ids) if len(second_axis_pos) != len(tomo_obj_ids): _logger.error( f"incoherent axis {self.second_axis} position compared to the number of input datasets. Will ignore those" ) second_axis_pos = [None] * len(tomo_obj_ids) new_tomo_objs = [] for tomo_obj_id, first_axis_v, second_axis_v in zip( tomo_obj_ids, first_axis_pos, second_axis_pos ): if isinstance(tomo_obj_id, TomwerObject): tomo_obj = tomo_obj_id elif isinstance(tomo_obj_id, _TomoScanBase): # for now we need to convert it back because object are not the same tomo_obj = ScanFactory.create_tomo_object_from_identifier( tomo_obj_id.get_identifier().to_str() ) elif isinstance(tomo_obj_id, _VolumeBase): tomo_obj = VolumeFactory.create_tomo_object_from_identifier( tomo_obj_id.get_identifier().to_str() ) else: tomo_obj = ScanFactory.create_tomo_object_from_identifier( tomo_obj_id ) self.addTomoObj(tomo_obj=tomo_obj) # set metadata information if any for axis, axis_value in zip((0, 1), (first_axis_v, second_axis_v)): if axis_value is not None: tomo_obj.stitching_metadata.setPxPos(int(axis_value), axis=axis) new_tomo_objs.append(tomo_obj) self.sigTomoObjsLoaded.emit(tuple(new_tomo_objs)) self._mainWidget._axisOrderedList._orderMightHaveChanged() # expose API def setAddTomoObjCallbacks(self, *args, **kwargs): self._mainWidget.setAddTomoObjCallbacks(*args, **kwargs) def setRemoveTomoObjCallbacks(self, *args, **kwargs): self._mainWidget.setRemoveTomoObjCallbacks(*args, **kwargs) class _SingleAxisStitchingCentralTabWidget(qt.QTabWidget): """ Tab widget containing: * preview interface of the stitching * ordered list of the scan / volume position over the main stitching axis """ def __init__(self, axis: int, parent=None) -> None: super().__init__(parent) assert axis in (0, 1, 2) self._seriesName = None self._axisOrderedList = EditableOrderedTomoObjWidget(parent=self, axis=axis) self.addTab(self._axisOrderedList, f"axis {axis} ordered list") self._previewPlot = PreviewStitchingPlot(parent=self, axis=axis) self.addTab(self._previewPlot, "stitching preview") # TODO: add a raw display to print frame from raw position z positions ... self._rawDisplayPlot = RawStitchingPlot( parent=self, aspectRatio=True, logScale=False, copy=False, save=False, print_=False, grid=False, curveStyle=False, mask=False, alpha_values=True, ) self._rawDisplayPlot.setKeepDataAspectRatio(True) self._rawDisplayPlot.setAxesDisplayed(False) self.addTab(self._rawDisplayPlot, "raw display") # add an option to activate / deactivate auto update of the raw display as it can be time consuming. raw_display_idx = self.indexOf(self._rawDisplayPlot) self._rawDisplayCB = qt.QCheckBox(self) self.tabBar().setTabButton( raw_display_idx, qt.QTabBar.LeftSide, self._rawDisplayCB, ) self.setTabToolTip( raw_display_idx, "If toggled will keep the raw display up to date from axis 0 modifications", ) # set up: turn overlay one by default self._previewPlot._backGroundAction.setChecked(True) def _handleRawDisplayConnection(self, toggled: bool): if toggled: self._connectRawDisplayConnection() else: self._disconnectRawDisplayConnection() def setSeries(self, series: Series): for elmt in series: self._axisOrderedList.addTomoObj(elmt) self.setSeriesName(series.name) def addTomoObj(self, tomo_obj: TomwerObject): self._axisOrderedList.addTomoObj(tomo_obj) def removeTomoObj(self, tomo_obj: TomwerObject): self._axisOrderedList.removeTomoObj(tomo_obj=tomo_obj) def getSeriesName(self) -> str: return self._seriesName def setSeriesName(self, name: str): self._seriesName = name def getTomoObjs(self) -> tuple: return self._axisOrderedList.getTomoObjsAxisOrdered() def clearTomoObjs(self): self._axisOrderedList.clearTomoObjs() def clean(self) -> None: self.clearTomoObjs() self._previewPlot.clear() def close(self): self._previewPlot.close() # requested for the waiting plot update super().close() def setAddTomoObjCallbacks(self, *args, **kwargs): self._axisOrderedList.setAddTomoObjCallbacks(*args, **kwargs) def setRemoveTomoObjCallbacks(self, *args, **kwargs): self._axisOrderedList.setRemoveTomoObjCallbacks(*args, **kwargs) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/stitching/StitchingOptionsWidget.py0000644000175000017500000004340315143647637024157 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from nabu.stitching.config import StitchingType from nabu.stitching import config as stitching_config from nabu.stitching.config import ( KEY_RESCALE_MAX_PERCENTILES, KEY_RESCALE_MIN_PERCENTILES, RESCALE_FRAMES, RESCALE_PARAMS, STITCHING_SECTION, ) from nabu.stitching.utils import ShiftAlgorithm as StitchShiftAlgorithm from nxtomomill.models.utils import convert_str_to_bool as _convert_str_to_bool from tomwer.gui.configuration.level import ConfigurationLevel from tomwer.gui.stitching.config.stitchingstrategies import StitchingStrategies from tomwer.gui.stitching.z_stitching.fineestimation import _SliceGetter from tomwer.gui.stitching.alignment import _AlignmentGroupBox from tomwer.gui.stitching.config.axisparams import StitcherAxisParams from tomwer.gui.stitching.normalization import NormalizationBySampleGroupBox from tomwer.io.utils.utils import str_to_dict from .utils import concatenate_dict class StitchingOptionsWidget(qt.QWidget): """ Widget to let the user define the different options for z-stitching such as which algorithm to search shift, which stitching strategy... """ sigChanged = qt.Signal() """Signal emit when the options change""" sigSliceForPreviewChanged = qt.Signal(object) """Signal emit when the slice requested for the preview has changed. Parameter is a str or an int""" sigFlipLRChanged = qt.Signal(bool) """Signal emit when the request to flip LR frame has changed""" sigFlipUDChanged = qt.Signal(bool) """Signal emit when the request to flip UD frame has changed""" def __init__( self, first_axis: int, second_axis: int, parent=None, *args, **kwargs ) -> None: super().__init__(parent, *args, **kwargs) # stitching strategy (aka stitcher behavior) self.setLayout(qt.QFormLayout()) self._stitchingStrategiesWidget = StitchingStrategies( parent=self, axis=first_axis ) self._stitchingStrategiesWidget.setObjectName("strategy") self.layout().addRow(self._stitchingStrategiesWidget) # slice for preview self._previewSlices = _SliceGetter("middle", parent=self) self._previewSlices.setPlaceholderText( "slice index or one of ('middle', 'first', 'last')" ) self._previewSlices.setToolTip( "expects a slice index (int > 0) or a str in ('first', 'middle', 'last')" ) self.layout().addRow("slice for preview", self._previewSlices) # invert frame up - down self._flipLR_CB = qt.QCheckBox("flip frame left-right", self) self._flipLR_CB.setChecked(False) self._flipLR_CB.setToolTip( "Flip frame for stitching. This is mostly for volume has no metadata are existing to specify the direction of the frame" ) self.layout().addRow(self._flipLR_CB) # invert frame left-right self._flipUD_CB = qt.QCheckBox("flip frame up-down", self) self._flipUD_CB.setChecked(False) self._flipUD_CB.setToolTip( "Flip frame for stitching. This is mostly for volume has no metadata are existing to specify the direction of the frame" ) self.layout().addRow(self._flipUD_CB) # avoid data duplication self._avoidDataDuplication_CB = qt.QCheckBox("avoid data duplication", self) self._avoidDataDuplication_CB.setChecked(False) self._avoidDataDuplication_CB.setEnabled(False) self._avoidDataDuplication_CB.setToolTip( "Avoid data duplication (only enabled for stitching on reconstructed volumes)" ) self.layout().addRow(self._avoidDataDuplication_CB) # alignment options self._alignmentGroup = _AlignmentGroupBox(self) self.layout().addRow(self._alignmentGroup) # slices to be reconstructed self._slices = _SlicesSelector(parent=self) self._slices.setToolTip( "for pre processing stitching those are projections and for post processing stitching those are volume slices" ) self.layout().addRow(self._slices) # axis 0 params for shift search self._firstAxisGroup = qt.QGroupBox(f"axis {first_axis}", self) self._firstAxisGroup.setLayout(qt.QVBoxLayout()) self.layout().addRow(self._firstAxisGroup) self._firstAxisShiftSearchParams = StitcherAxisParams( axis=first_axis, parent=self ) self._firstAxisShiftSearchParams.layout().setContentsMargins(0, 0, 0, 0) self._firstAxisShiftSearchParams.layout().setSpacing(0) self._firstAxisGroup.layout().addWidget(self._firstAxisShiftSearchParams) # axis 2 params for shift search self._secondAxisGroup = qt.QGroupBox(f"axis {second_axis}", self) self._secondAxisGroup.setLayout(qt.QVBoxLayout()) self.layout().addRow(self._secondAxisGroup) self._secondAxisShiftSearchParams = StitcherAxisParams( axis=second_axis, parent=self ) self._secondAxisShiftSearchParams.layout().setContentsMargins(0, 0, 0, 0) self._secondAxisShiftSearchParams.layout().setSpacing(0) self._secondAxisGroup.layout().addWidget(self._secondAxisShiftSearchParams) # by default avoid doing shift along second axis by default self._secondAxisShiftSearchParams.setShiftSearchMethod( StitchShiftAlgorithm.NONE ) # frame rescaling option self._rescalingWidget = RescalingWidget(parent=self) self.layout().addRow(self._rescalingWidget) # normalization by sample self._normalizationBySampleWidget = NormalizationBySampleGroupBox(parent=self) self._normalizationBySampleWidget.setChecked(False) self.layout().addRow(self._normalizationBySampleWidget) # connect signal / slot self._stitchingStrategiesWidget.sigChanged.connect(self._updated) self._previewSlices.editingFinished.connect(self._sliceForPreviewHasChanged) self._flipLR_CB.toggled.connect(self._flipLRHasChanged) self._flipUD_CB.toggled.connect(self._flipUDHasChanged) def _sliceForPreviewHasChanged(self): slice_for_preview = self.getSlicesForPreview() try: slice_for_preview = int(slice_for_preview) except ValueError: pass self.sigSliceForPreviewChanged.emit(slice_for_preview) self._updated() def _flipLRHasChanged(self): self.sigFlipLRChanged.emit(self._flipLR_CB.isChecked()) def _flipUDHasChanged(self): self.sigFlipUDChanged.emit(self._flipUD_CB.isChecked()) def _updated(self, *args, **kwargs): self.sigChanged.emit() def getSlicesForPreview(self): return self._previewSlices.text() def getSlices(self): slices = self._slices.getSlices() if slices == (0, -1, 1): return None else: return (str(slices[0]), str(slices[1]), str(slices[2])) def setSlices(self, slices: tuple): if isinstance(slices, str): slices = slices.replace(" ", "").split(":") if len(slices) > 2: step = int(slices[2]) else: step = None self._slices.setSlices(int(slices[0]), int(slices[1]), step) def getAvoidDataDuplication(self) -> bool: return ( self._avoidDataDuplication_CB.isChecked() and self._avoidDataDuplication_CB.isEnabled() ) def setAvoidDataDuplication(self, avoid: bool): self._avoidDataDuplication_CB.setChecked(avoid) def getConfiguration(self) -> dict: slices = self.getSlices() if slices is None: slices = "" else: slices = ":".join(slices) res = { stitching_config.STITCHING_SECTION: { stitching_config.FLIP_LR: self._flipLR_CB.isChecked(), stitching_config.FLIP_UD: self._flipUD_CB.isChecked(), stitching_config.ALIGNMENT_AXIS_1_FIELD: self._alignmentGroup.getAlignmentAxis1().value, stitching_config.ALIGNMENT_AXIS_2_FIELD: self._alignmentGroup.getAlignmentAxis2().value, stitching_config.PAD_MODE_FIELD: self._alignmentGroup.getPadMode(), stitching_config.AVOID_DATA_DUPLICATION_FIELD: self.getAvoidDataDuplication(), }, stitching_config.INPUTS_SECTION: { stitching_config.STITCHING_SLICES: slices, }, stitching_config.NORMALIZATION_BY_SAMPLE_SECTION: self._normalizationBySampleWidget.getConfiguration(), } for ddict in ( self._stitchingStrategiesWidget.getConfiguration(), self._firstAxisShiftSearchParams.getConfiguration(), self._secondAxisShiftSearchParams.getConfiguration(), self._rescalingWidget.getConfiguration(), ): res = concatenate_dict(res, ddict) return res def setConfiguration(self, config: dict): self._stitchingStrategiesWidget.setConfiguration(config) self._firstAxisShiftSearchParams.setConfiguration(config) self._secondAxisShiftSearchParams.setConfiguration(config) self._rescalingWidget.setConfiguration(config) slices = config.get(stitching_config.STITCHING_SECTION, {}).get( stitching_config.STITCHING_SLICES, "" ) # slices if slices == "": slices = None if slices is not None: self.setSlices(slices) # flip_lr flip_lr = config.get(stitching_config.STITCHING_SECTION, {}).get( stitching_config.FLIP_LR, None ) if flip_lr is not None: self._flipLR_CB.setChecked(flip_lr in (True, "True", 1, "1")) # flip_ud flip_ud = config.get(stitching_config.STITCHING_SECTION, {}).get( stitching_config.FLIP_UD, None ) if flip_ud is not None: self._flipUD_CB.setChecked(flip_ud in (True, "True", 1, "1")) # avoid data duplication avoid_data_duplication = config.get( stitching_config.AVOID_DATA_DUPLICATION_FIELD, None ) if avoid_data_duplication is not None: self.setAvoidDataDuplication(avoid=avoid_data_duplication) # alignment alignment_axis_1 = config.get(stitching_config.STITCHING_SECTION, {}).get( stitching_config.ALIGNMENT_AXIS_1_FIELD, None ) if alignment_axis_1 is not None: self._alignmentGroup.setAlignmentAxis1(alignment_axis_1) alignment_axis_2 = config.get(stitching_config.STITCHING_SECTION, {}).get( stitching_config.ALIGNMENT_AXIS_2_FIELD, None ) if alignment_axis_2 is not None: self._alignmentGroup.setAlignmentAxis2(alignment_axis_2) # pad_mode pad_mode = config.get(stitching_config.STITCHING_SECTION, {}).get( stitching_config.PAD_MODE_FIELD, None ) if pad_mode is not None: self._alignmentGroup.setPadMode(pad_mode=pad_mode) # normalization by sample normalization_by_sample = config.get( stitching_config.NORMALIZATION_BY_SAMPLE_SECTION, None ) if normalization_by_sample is not None: self._normalizationBySampleWidget.setConfiguration(normalization_by_sample) def _stitchingTypeChanged(self, stitching_type: str): stitching_type = StitchingType(stitching_type) self._alignmentGroup.setAlignmentAxis1Enabled( stitching_type is StitchingType.Z_POSTPROC ) self._avoidDataDuplication_CB.setEnabled( stitching_type is StitchingType.Z_POSTPROC ) def setConfigurationLevel(self, level: ConfigurationLevel): self._alignmentGroup.setVisible(level >= ConfigurationLevel.ADVANCED) self._previewSlices.setVisible(level >= ConfigurationLevel.OPTIONAL) self._flipLR_CB.setVisible(level >= ConfigurationLevel.ADVANCED) self._flipUD_CB.setVisible(level >= ConfigurationLevel.ADVANCED) self._avoidDataDuplication_CB.setVisible(level >= ConfigurationLevel.OPTIONAL) self._rescalingWidget.setVisible(level >= ConfigurationLevel.ADVANCED) self._firstAxisShiftSearchParams.setConfigurationLevel(level) self._secondAxisShiftSearchParams.setConfigurationLevel(level) self._normalizationBySampleWidget.setVisible( level >= ConfigurationLevel.ADVANCED ) class _SlicesSelector(qt.QGroupBox): """ Widget to determine the slices values (to be stitched) """ def __init__(self, parent=None) -> None: super().__init__("slices", parent) # start interface self.setLayout(qt.QHBoxLayout()) self._startSliceCB = qt.QCheckBox("start", self) self.layout().addWidget(self._startSliceCB) self._startSliceSB = qt.QSpinBox(self) self._startSliceSB.setMinimum(0) self._startSliceSB.setMaximum(9999999) self._startSliceSB.setValue(0) self.layout().addWidget(self._startSliceSB) # stop interface self._stopSliceCB = qt.QCheckBox("stop", self) self.layout().addWidget(self._stopSliceCB) self._stopSliceSB = qt.QSpinBox(self) self._stopSliceSB.setMinimum(-1) self._stopSliceSB.setMaximum(9999999) self._stopSliceSB.setValue(-1) self.layout().addWidget(self._stopSliceSB) # step interface self._stepSliceLabel = qt.QLabel("step", self) self.layout().addWidget(self._stepSliceLabel) self._stepSliceSB = qt.QSpinBox(self) self._stepSliceSB.setMinimum(1) self._stepSliceSB.setMaximum(9999999) self._stepSliceSB.setValue(1) self.layout().addWidget(self._stepSliceSB) # connect signal / slot self._startSliceCB.toggled.connect(self._startSliceSB.setDisabled) self._stopSliceCB.toggled.connect(self._stopSliceSB.setDisabled) self._startSliceCB.setChecked(True) self._stopSliceCB.setChecked(True) def getSlices(self) -> tuple: if self._startSliceCB.isChecked(): start = 0 else: start = self._startSliceSB.value() if self._stopSliceCB.isChecked(): stop = -1 else: stop = self._stopSliceSB.value() step = self._stepSliceSB.value() return (start, stop, step) def setSlices(self, start: int, stop: int, step: int | None = None): start = int(start) stop = int(stop) if start == 0: self._startSliceCB.setChecked(True) else: self._startSliceCB.setChecked(False) self._startSliceSB.setValue(start) if stop == -1: self._stopSliceCB.setChecked(True) else: self._stopSliceCB.setChecked(False) self._stopSliceSB.setValue(stop) if step is not None: self._stepSliceSB.setValue(int(step)) class RescalingWidget(qt.QWidget): DEFAULT_MIN_PERCENTILE = 0 DEFAULT_MAX_PERCENTILE = 100 def __init__(self, parent, *args, **kwargs) -> None: super().__init__(parent, *args, **kwargs) self.setLayout(qt.QHBoxLayout()) self._activatedCB = qt.QCheckBox("rescale frames", self) self.layout().addWidget(self._activatedCB) self._minPercentileQSB = qt.QSpinBox(self) self._minPercentileQSB.setRange(0, 100) self._minPercentileQSB.setPrefix("min:") self._minPercentileQSB.setSuffix("%") self._minPercentileQSB.setValue(self.DEFAULT_MIN_PERCENTILE) self.layout().addWidget(self._minPercentileQSB) self._maxPercentileQSB = qt.QSpinBox(self) self._maxPercentileQSB.setRange(0, 100) self._maxPercentileQSB.setPrefix("max:") self._maxPercentileQSB.setSuffix("%") self._maxPercentileQSB.setValue(self.DEFAULT_MAX_PERCENTILE) self.layout().addWidget(self._maxPercentileQSB) # set up self._activatedCB.setChecked(False) self._minPercentileQSB.setEnabled(False) self._maxPercentileQSB.setEnabled(False) # connect signal / slot self._activatedCB.toggled.connect(self._activationChanged) self._activatedCB.toggled.connect(self._activationChanged) def _activationChanged(self): self._minPercentileQSB.setEnabled(self._activatedCB.isChecked()) self._maxPercentileQSB.setEnabled(self._activatedCB.isChecked()) def getConfiguration(self): return { STITCHING_SECTION: { RESCALE_FRAMES: self._activatedCB.isChecked(), RESCALE_PARAMS: ";".join( [ f"{KEY_RESCALE_MIN_PERCENTILES}={self._minPercentileQSB.value()}", f"{KEY_RESCALE_MAX_PERCENTILES}={self._maxPercentileQSB.value()}", ] ), } } def setConfiguration(self, config: dict): def cast_percentile(percentile) -> int: if isinstance(percentile, str): percentile.replace(" ", "").rstrip("%") return int(percentile) stitching_config = config.get(STITCHING_SECTION, {}) rescale_params = str_to_dict(stitching_config.get(RESCALE_PARAMS, {})) rescale_min_percentile = rescale_params.get(KEY_RESCALE_MIN_PERCENTILES, None) if rescale_min_percentile is not None: rescale_min_percentile = cast_percentile(rescale_min_percentile) self._minPercentileQSB.setValue(rescale_min_percentile) rescale_max_percentile = rescale_params.get(KEY_RESCALE_MAX_PERCENTILES, None) if rescale_max_percentile is not None: rescale_max_percentile = cast_percentile(rescale_max_percentile) self._maxPercentileQSB.setValue(rescale_max_percentile) rescale = stitching_config.get(RESCALE_FRAMES, None) if rescale is not None: self._activatedCB.setChecked(_convert_str_to_bool(rescale)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771225048.0 tomwer-1.6.17/src/tomwer/gui/stitching/StitchingWindow.py0000644000175000017500000006117015144537730022621 0ustar00paynopaynofrom __future__ import annotations import logging import os import shutil import tempfile import functools from nabu.stitching.config import StitchingType from nabu.pipeline.config import generate_nabu_configfile, parse_nabu_config_file from nabu.stitching.config import ( get_default_stitching_config, SECTIONS_COMMENTS as _SECTIONS_COMMENTS, ) from silx.gui import qt from tomwer.core.scan.nxtomoscan import NXtomoScan, NXtomoScanIdentifier from tomwer.core.volume.hdf5volume import HDF5Volume, HDF5VolumeIdentifier from tomwer.gui.qconfigfile import QConfigFileDialog from tomwer.gui.stitching.config.positionoveraxis import PosEditorOverOneAxis from tomwer.gui.stitching.config.output import StitchingOutput from tomwer.gui.stitching.StitchingOptionsWidget import StitchingOptionsWidget from tomwer.gui.configuration.action import ( BasicConfigurationAction, ExpertConfigurationAction, MinimalisticConfigurationAction, ) from tomwer.gui.configuration.level import ConfigurationLevel from tomwer.gui.stitching import action as stitching_action from tomwer.gui.stitching.preview import PreviewThread from tomwer.gui.stitching.singleaxis import SingleAxisMetaClass, _SingleAxisMixIn from tomwer.gui.stitching.SingleAxisStitchingWidget import SingleAxisStitchingWidget from .utils import concatenate_dict _logger = logging.getLogger(__name__) class _SingleAxisStitchingWindow( qt.QMainWindow, _SingleAxisMixIn, metaclass=SingleAxisMetaClass ): """ Main widget containing all the options to define the stitching to be done :param with_configuration_action: if True append the load and save stitching configuration tool button. In some cases those can also be part of Menu so we want to avoid having those twice """ sigChanged = qt.Signal() """Signal emit each time the configuration is modified""" def __init__(self, parent=None, with_configuration_action=True) -> None: super().__init__(parent) assert self._axis in (0, 1, 2) """axis along which we want to apply stitching""" self._previewFolder = None # folder to store files (volume or NXtomo) for previews self._previewThread = None # thread to compute the stitching for preview self._callbackToGetSlurmConfig = None self._callbackToSetSlurmConfig = None # convenient work around to avoid having to redefine the n=interface for slurm and the API # to load and save settings # if it is defined upper toolbar = qt.QToolBar(self) self.addToolBar(qt.Qt.TopToolBarArea, toolbar) style = qt.QApplication.instance().style() # clean option self.__cleanAction = qt.QAction(self) self.__cleanAction.setToolTip("clear") clear_icon = style.standardIcon(qt.QStyle.SP_DialogResetButton) self.__cleanAction.setIcon(clear_icon) toolbar.addAction(self.__cleanAction) self.__cleanAction.triggered.connect(self.clean) # separator toolbar.addSeparator() if with_configuration_action: # load action self.__loadAction = stitching_action.LoadConfigurationAction(self) toolbar.addAction(self.__loadAction) self.__loadAction.triggered.connect( functools.partial(self._loadSettings, file_path=None) ) # save action self.__saveAction = stitching_action.SaveConfigurationAction(self) toolbar.addAction(self.__saveAction) self.__saveAction.triggered.connect( functools.partial(self._saveSettings, file_path=None) ) # separator toolbar.addSeparator() # update preview action self.__updatePreviewAction = stitching_action.PreviewAction(self) toolbar.addAction(self.__updatePreviewAction) self.__updatePreviewAction.triggered.connect(self._trigger_update_preview) # separator toolbar.addSeparator() # configuration level / mode self.__configurationModesAction = qt.QAction(self) self.__configurationModesAction.setCheckable(False) menu = qt.QMenu(self) self.__configurationModesAction.setMenu(menu) toolbar.addAction(self.__configurationModesAction) self.__configurationModesGroup = qt.QActionGroup(self) self.__configurationModesGroup.setExclusive(True) self.__configurationModesGroup.triggered.connect(self._userModeChanged) self._minimalisticAction = MinimalisticConfigurationAction(toolbar) menu.addAction(self._minimalisticAction) self.__configurationModesGroup.addAction(self._minimalisticAction) self._basicConfigAction = BasicConfigurationAction(toolbar) menu.addAction(self._basicConfigAction) self.__configurationModesGroup.addAction(self._basicConfigAction) self._expertConfiguration = ExpertConfigurationAction(toolbar) menu.addAction(self._expertConfiguration) self.__configurationModesGroup.addAction(self._expertConfiguration) # separator toolbar.addSeparator() # create central widget self._widget = SingleAxisStitchingWidget(parent=self, axis=self.first_axis) self.setCentralWidget(self._widget) # create Dock widgets ## output self._outputWidget = StitchingOutput(parent=self) self._outputWidget.setObjectName("outputSettingsWidget") self._outputDockWidget = qt.QDockWidget(parent=self) self._outputDockWidget.setWindowTitle("output") self._outputDockWidget.layout().setContentsMargins(0, 0, 0, 0) self._outputDockWidget.setFeatures(qt.QDockWidget.DockWidgetMovable) self._outputDockWidget.setWidget(self._outputWidget) self.addDockWidget(qt.Qt.RightDockWidgetArea, self._outputDockWidget) self._outputDockWidget.setToolTip( "options to where and how to save the stitching" ) ## stitching strategies self._stitchingOptsWidget = StitchingOptionsWidget( parent=self, first_axis=self.first_axis, second_axis=self.second_axis ) self._stitchingOptsScrollArea = qt.QScrollArea(self) self._stitchingOptsScrollArea.setWidget(self._stitchingOptsWidget) self._stitchingOptsScrollArea.setWidgetResizable(True) self._stitchingOptsScrollArea.setHorizontalScrollBarPolicy( qt.Qt.ScrollBarAlwaysOff ) self._stitchingOptsDockWidget = qt.QDockWidget(parent=self) self._stitchingOptsDockWidget.layout().setContentsMargins(0, 0, 0, 0) self._stitchingOptsDockWidget.setFeatures(qt.QDockWidget.DockWidgetMovable) self._stitchingOptsDockWidget.setWidget(self._stitchingOptsScrollArea) self._stitchingOptsDockWidget.setWindowTitle("processing options") self.addDockWidget(qt.Qt.RightDockWidgetArea, self._stitchingOptsDockWidget) ## all scan z positions self._editTomoObjFirstAxisPositionsWidget = PosEditorOverOneAxis( parent=self, axis_edited=self.first_axis, axis_order=self.first_axis, lock_info=True, ) self._editTomoObjFirstAxisPositionsDockWidget = qt.QDockWidget(parent=self) self._editTomoObjFirstAxisPositionsDockWidget.layout().setContentsMargins( 0, 0, 0, 0 ) self._editTomoObjFirstAxisPositionsDockWidget.setFeatures( qt.QDockWidget.DockWidgetMovable ) self._editTomoObjFirstAxisPositionsDockWidget.setWidget( self._editTomoObjFirstAxisPositionsWidget ) self._editTomoObjFirstAxisPositionsDockWidget.setWindowTitle( f"edit positions over axis {self.first_axis} (px) - aka {self.axis_alias(self.first_axis)}" ) self._editTomoObjFirstAxisPositionsDockWidget.setToolTip( f"This allows to edit tomo objects positions along the axis {self.first_axis} (aka {self.axis_alias(self.first_axis)})" ) self.addDockWidget( qt.Qt.RightDockWidgetArea, self._editTomoObjFirstAxisPositionsDockWidget ) ### add a check box to update position from preview if asked by the user self._updateFirstAxisPosFromPreviewCalc = qt.QCheckBox( f"update position {self.first_axis} from preview calc", self, ) self._updateFirstAxisPosFromPreviewCalc.setToolTip( f"When the user trigger a preview, if some shift search refined over axis {self.first_axis} is done then will update the axis 0 positions", ) self._updateFirstAxisPosFromPreviewCalc.setChecked(True) self._editTomoObjFirstAxisPositionsWidget.layout().insertWidget( 0, self._updateFirstAxisPosFromPreviewCalc ) ## all scan axis 1 positions self._editTomoObjSecondAxisPositionsWidget = PosEditorOverOneAxis( parent=self, axis_edited=self.second_axis, axis_order=0, ) self._editTomoObjSecondAxisPositionsDockWidget = qt.QDockWidget(parent=self) self._editTomoObjSecondAxisPositionsDockWidget.layout().setContentsMargins( 0, 0, 0, 0 ) self._editTomoObjSecondAxisPositionsDockWidget.setFeatures( qt.QDockWidget.DockWidgetMovable ) self._editTomoObjSecondAxisPositionsDockWidget.setWidget( self._editTomoObjSecondAxisPositionsWidget ) self._editTomoObjSecondAxisPositionsDockWidget.setWindowTitle( f"edit positions over axis {self.second_axis} (px)" ) self._editTomoObjSecondAxisPositionsDockWidget.setToolTip( f"This allows to edit tomo objects positions along the axis {self.second_axis}" ) self.addDockWidget( qt.Qt.RightDockWidgetArea, self._editTomoObjSecondAxisPositionsDockWidget ) ### add a check box to update position from preview if asked by the user self._updateSecondAxisPosFromPreviewCalc = qt.QCheckBox( f"update position {self.second_axis} from preview calc", self ) self._updateSecondAxisPosFromPreviewCalc.setToolTip( f"When the user trigger a preview, if some position refinement can be done will update axis {self.second_axis}" ) self._updateSecondAxisPosFromPreviewCalc.setChecked(True) self._editTomoObjSecondAxisPositionsWidget.layout().insertWidget( 0, self._updateSecondAxisPosFromPreviewCalc ) self._widget.setAddTomoObjCallbacks( ( self._editTomoObjFirstAxisPositionsWidget.addTomoObj, self._editTomoObjSecondAxisPositionsWidget.addTomoObj, self.getRawDisplayPlot().addTomoObj, ) ) self._widget.setRemoveTomoObjCallbacks( ( self._editTomoObjFirstAxisPositionsWidget.removeTomoObj, self._editTomoObjSecondAxisPositionsWidget.removeTomoObj, self.getRawDisplayPlot().removeTomoObj, ) ) # update layout: for now lets tabify some widget self.tabifyDockWidget(self._outputDockWidget, self._stitchingOptsDockWidget) self.tabifyDockWidget( self._outputDockWidget, self._editTomoObjSecondAxisPositionsDockWidget ) self.tabifyDockWidget( self._outputDockWidget, self._editTomoObjFirstAxisPositionsDockWidget ) # handle raw display plot. By display avoid displaying raw data as this can be resource consuming self._widget._mainWidget._rawDisplayCB.setChecked(False) self._widget._mainWidget._rawDisplayPlot.setActive(False) # connect signal / slot self._widget._mainWidget._rawDisplayCB.toggled.connect( self._handleRawDisplayConnection ) self._outputWidget.sigChanged.connect(self._changed) self._stitchingOptsWidget.sigChanged.connect(self._changed) self._widget.sigStitchingTypeChanged.connect( self._outputWidget._updateOutputForStitchingType ) self._widget.sigStitchingTypeChanged.connect( self._stitchingOptsWidget._stitchingTypeChanged ) ## handle raw plot preview self._stitchingOptsWidget.sigFlipLRChanged.connect( self.getRawDisplayPlot().setFlipLRFrames ) self._stitchingOptsWidget.sigFlipUDChanged.connect( self.getRawDisplayPlot().setFlipUDFrames ) self._stitchingOptsWidget.sigSliceForPreviewChanged.connect( self.getRawDisplayPlot().setSliceForPreview ) ## handle tomo obj loading from settings self._widget.sigTomoObjsLoaded.connect( self._editTomoObjFirstAxisPositionsWidget.setTomoObjs ) self._widget.sigTomoObjsLoaded.connect( self._editTomoObjSecondAxisPositionsWidget.setTomoObjs ) self._widget.sigTomoObjsLoaded.connect(self.getRawDisplayPlot().setTomoObjs) # set up self._basicConfigAction.setChecked(True) self._userModeChanged(self._basicConfigAction) def setCallbackToGetSlurmConfig(self, callback): self._callbackToGetSlurmConfig = callback def setCallbackToSetSlurmConfig(self, callback): self._callbackToSetSlurmConfig = callback def close(self): # remove folder used for preview if self._previewFolder is not None: shutil.rmtree(self._previewFolder, ignore_errors=True) self._widget.close() # requested for the waiting plot update super().close() def getRawDisplayPlot(self): return self._widget._mainWidget._rawDisplayPlot def _handleRawDisplayConnection(self, toggled: bool): raw_display_plot = self.getRawDisplayPlot() raw_display_plot.setActive(toggled) def getPreviewAction(self): return self.__updatePreviewAction def getPreviewFolder(self): if self._previewFolder is None: self._previewFolder = tempfile.mkdtemp(prefix="tomwer_stitcher_preview") return self._previewFolder def getVolumeIdentifierPreview(self) -> HDF5VolumeIdentifier: folder = self.getPreviewFolder() # for now use hdf5 by default return HDF5VolumeIdentifier( object=HDF5Volume, hdf5_file=os.path.join(folder, "vol_stitching_preview.hdf5"), entry="my_volume", ) def getNXtomoIdentifierForPreview(self): folder = self.getPreviewFolder() return NXtomoScanIdentifier( object=NXtomoScan, hdf5_file=os.path.join(folder, "nxtomo_stiching_preview.hdf5"), entry="entry0000", ) def _changed(self, *args, **kwargs): self.sigChanged.emit() def _saveSettings(self, file_path=None, **kwargs): """ dump current configuration into a txt file """ # get a file if necessary if file_path is None: dialog = QConfigFileDialog(self) dialog.setAcceptMode(qt.QFileDialog.AcceptSave) if not dialog.exec(): return selected_file = dialog.selectedFiles() if len(selected_file) == 0: return file_path = selected_file[0] configuration = self.getConfiguration() if self._callbackToGetSlurmConfig is not None: slurm_config = {"slurm": self._callbackToGetSlurmConfig()} configuration = concatenate_dict(configuration, slurm_config) _, ext = os.path.splitext(file_path) if ext == "": file_path = f"{file_path}.cfg" # dump configuration generate_nabu_configfile( fname=file_path, default_config=get_default_stitching_config(self.getStitchingType()), comments=True, sections_comments=_SECTIONS_COMMENTS, options_level="advanced", prefilled_values=configuration, ) def _loadSettings(self, file_path=None, **kwargs): """ load configuration from a txt file """ # get a file if necessary if file_path is None: dialog = QConfigFileDialog(self) dialog.setAcceptMode(qt.QFileDialog.AcceptOpen) dialog.setFileMode(qt.QFileDialog.ExistingFiles) if not dialog.exec(): return selected_file = dialog.selectedFiles() if len(selected_file) == 0: return file_path = selected_file[0] # Do configuration load conf_dict = parse_nabu_config_file(file_path, allow_no_value=True) self.setConfiguration(config=conf_dict) if self._callbackToSetSlurmConfig is not None: self._callbackToSetSlurmConfig(conf_dict.get("slurm", {})) def _trigger_update_preview(self): if self._previewThread is not None: _logger.warning( "some preview is already running. Please wait before relaunching it" ) return config = self.getConfiguration() # update the output file to set if from raw... stitching_type = config.get("stitching", {}).get("type", None) if stitching_type in ("z-preproc", "y-preproc"): output_identifier = self.getNXtomoIdentifierForPreview() config["preproc"]["location"] = output_identifier.file_path config["preproc"]["data_path"] = output_identifier.data_path assert "postproc" not in config elif stitching_type == "z-postproc": config["postproc"][ "output_volume" ] = self.getVolumeIdentifierPreview().to_str() assert "preproc" not in config else: raise NotImplementedError # update the slice to avoid doing the stitching on all the frames config["inputs"]["slices"] = self.getSlicesForPreview() # update to force overwrite config["output"]["overwrite_results"] = True # avoid any recalculation of the axis position. So the preview is accurate config["output"]["axis_0_params"] = "" config["output"]["axis_1_params"] = "" config["output"]["axis_2_params"] = "" # clean current preview to notify some calculation is going on preview_plot = self._widget._mainWidget._previewPlot preview_plot._waitingOverlay.show() # start stitching on a thread self._previewThread = PreviewThread(stitching_config=config) self._previewThread.finished.connect(self._previewCalculationFinished) self._previewThread.start() def getSlicesForPreview(self): return self._stitchingOptsWidget.getSlicesForPreview() def _previewCalculationFinished(self): sender = self.sender() assert isinstance(sender, PreviewThread) composition = sender.frame_composition tomo_objs_new_axis_positions = sender.final_tomo_objs_positions assert isinstance( tomo_objs_new_axis_positions, dict ), f"final_tomo_objs_positions is expected to be a dict with obj identifier as key and the tuple of position as value. Got {type(tomo_objs_new_axis_positions)}" # expect it to be a dict with tomo obj identifier as key and a tuple of (axis_2_pos, axis_1_pos, axis_0_pos) as value output_obj_identifier = sender.output_identifier preview_plot = self._widget._mainWidget._previewPlot preview_plot._waitingOverlay.hide() self._previewThread.finished.disconnect(self._previewCalculationFinished) self._previewThread = None if output_obj_identifier is None: _logger.error("preview of stitching failed") else: preview_plot.setStitchedTomoObj( tomo_obj_id=output_obj_identifier, composition=composition, ) # update object values if requested update_requested = { self.first_axis: self._updateFirstAxisPosFromPreviewCalc.isChecked(), self.second_axis: self._updateSecondAxisPosFromPreviewCalc.isChecked(), } if update_requested[self.first_axis] or update_requested[self.second_axis]: existing_tomo_obj = { tomo_obj.get_identifier().to_str(): tomo_obj for tomo_obj in self._widget._mainWidget.getTomoObjs() } for tomo_obj_id, value in tomo_objs_new_axis_positions.items(): assert ( isinstance(value, tuple) and len(value) == 3 ), "value is expected to be (new_pos_axis_0, new_pos_axis_1, new_pos_axis_2)" new_first_axis_pos = value[self.first_axis] new_second_axis_pos = value[self.second_axis] tomo_obj = existing_tomo_obj.get(tomo_obj_id, None) if tomo_obj is None: continue if update_requested[self.first_axis]: tomo_obj.stitching_metadata.setPxPos( int(new_first_axis_pos), self.first_axis ) if update_requested[self.second_axis]: tomo_obj.stitching_metadata.setPxPos( int(new_second_axis_pos), self.second_axis ) if update_requested[self.first_axis]: self._editTomoObjFirstAxisPositionsWidget._orderedMightHaveChanged( force_sb_update=True ) if update_requested[self.second_axis]: self._editTomoObjSecondAxisPositionsWidget._orderedMightHaveChanged( force_sb_update=True ) def clean(self): self._widget.clean() self._editTomoObjFirstAxisPositionsWidget.clean() self._editTomoObjSecondAxisPositionsWidget.clean() def setSeries(self, series): self.clean() self._widget._mainWidget.setSeries(series) self._editTomoObjFirstAxisPositionsWidget.clean() self._editTomoObjSecondAxisPositionsWidget.clean() for tomo_obj in series: self._editTomoObjFirstAxisPositionsWidget.addTomoObj(tomo_obj) self._editTomoObjSecondAxisPositionsWidget.addTomoObj(tomo_obj) self.getRawDisplayPlot().setTomoObjs(tomo_objs=series[:]) def addTomoObj(self, tomo_obj): self._widget.addTomoObj(tomo_obj) self._editTomoObjFirstAxisPositionsWidget.addTomoObj(tomo_obj) self._editTomoObjSecondAxisPositionsWidget.addTomoObj(tomo_obj) self.getRawDisplayPlot().addTomoObj(tomo_obj=tomo_obj) def getTomoObjs(self) -> tuple: return self._widget.getTomoObjs() def removeTomoObj(self, tomo_obj): self._widget.removeTomoObj(tomo_obj) self.getRawDisplayPlot().removeTomoObj(tomo_obj=tomo_obj) def getConfiguration(self) -> dict: # make sure the sync is fine between the two configs = ( self._widget.getConfiguration(), self._outputWidget.getConfiguration(), self._stitchingOptsWidget.getConfiguration(), ) result = {} for config in configs: result = concatenate_dict(result, config) return result def setConfiguration(self, config: dict): self._widget.setConfiguration(config) self._outputWidget.setConfiguration(config) self._stitchingOptsWidget.setConfiguration(config) # expose API def getStitchingType(self) -> StitchingType: return self._widget.getStitchingType() def setStitchingType(self, stitching_type: StitchingType): self._widget.setStitchingType(stitching_type) def _userModeChanged(self, action): self.__configurationModesAction.setIcon(action.icon()) self.__configurationModesAction.setToolTip(action.tooltip()) if action is self._basicConfigAction: level = ConfigurationLevel.OPTIONAL elif action is self._expertConfiguration: level = ConfigurationLevel.ADVANCED else: level = ConfigurationLevel.REQUIRED self._stitchingOptsWidget.setConfigurationLevel(level) self._editTomoObjSecondAxisPositionsDockWidget.setVisible( level >= ConfigurationLevel.ADVANCED ) def setPreProcessingOutput(self, *args, **kwargs): self._outputWidget.setPreProcessingOutput(*args, **kwargs) def setPostProcessingOutput(self, *args, **kwargs): self._outputWidget.setPostProcessingOutput(*args, **kwargs) def get_available_pre_processing_stitching_mode(self): return self._widget.get_available_pre_processing_stitching_mode() def get_available_post_processing_stitching_mode(self): return self._widget.get_available_post_processing_stitching_mode() class YStitchingWindow(_SingleAxisStitchingWindow, axis=1): pass class ZStitchingWindow(_SingleAxisStitchingWindow, axis=0): pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/gui/stitching/__init__.py0000644000175000017500000000005514764622416021232 0ustar00paynopayno"""Widgets for stitching scans or volumes""" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/stitching/action.py0000644000175000017500000000317314757047403020753 0ustar00paynopaynofrom silx.gui import qt from silx.gui import icons as silx_icons from tomwer.gui import icons as tomwer_icons class LoadConfigurationAction(qt.QAction): """Action to trigger load of a stitching configuration""" def __init__(self, parent=None, text=None): super().__init__(parent) if text is not None: self.setText(text) self.setToolTip("load nabu-stitching configuration") load_icon = silx_icons.getQIcon("document-open") self.setIcon(load_icon) class SaveConfigurationAction(qt.QAction): """Action to trigger save of a stitching configuration""" def __init__(self, parent=None, text=None): super().__init__(parent) if text is not None: self.setText(text) self.setToolTip("save nabu-stitching configuration") save_icon = silx_icons.getQIcon("document-save") self.setIcon(save_icon) class AddTomoObjectAction(qt.QAction): """Action to trigger add a volume to a stitching configuration""" def __init__(self, parent=None, text=None): super().__init__(parent) if text is not None: self.setText(text) self.setToolTip( "Add a NXtomo or a (nabu) reconstructed volume to the stitching" ) add_icon = tomwer_icons.getQIcon("add") self.setIcon(add_icon) class PreviewAction(qt.QAction): def __init__(self, parent=None): super().__init__(parent) self.setToolTip("Compute preview with current settings (shortcut: F5)") update_preview_icon = tomwer_icons.getQIcon("update_stitching_preview") self.setIcon(update_preview_icon) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/gui/stitching/alignment.py0000644000175000017500000000755715115744275021466 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from nabu.stitching.alignment import AlignmentAxis1, AlignmentAxis2 class _AlignmentGroupBox(qt.QGroupBox): DEFAULT_PAD_MODE = "constant" ALIGNMENT_DOC = ( "https://tomotools.gitlab-pages.esrf.fr/nabu/stitching/alignment.html" ) DEFAULT_ALIGNMENT_AXIS_1 = AlignmentAxis1.CENTER DEFAULT_ALIGNMENT_AXIS_2 = AlignmentAxis2.CENTER _PAD_MODES = ( "constant", # Pads with a constant value. "edge", # Pads with the edge values of array. "linear_ramp", # Pads with the linear ramp between end_value and the array edge value. "maximum", # Pads with the maximum value of all or part of the vector along each axis. "mean", # Pads with the mean value of all or part of the vector along each axis. "median", # Pads with the median value of all or part of the vector along each axis. "minimum", # Pads with the minimum value of all or part of the vector along each axis. "reflect", # Pads with the reflection of the vector mirrored on the first and last values of the vector along each axis. "symmetric", # Pads with the reflection of the vector mirrored along the edge of the array. "wrap", # Pads with the wrap of the vector along the axis. The first values are used to pad the end and the end values are used to pad the beginning. ) def __init__(self, parent: qt.QWidget = None, title="alignment") -> None: super().__init__(title, parent) self.setLayout(qt.QFormLayout()) # alignment axis 1 self._alignmentAxis1CB = qt.QComboBox(self) for alignment in AlignmentAxis1: self._alignmentAxis1CB.addItem(alignment.value) self.layout().addRow("Axis 1 alignment", self._alignmentAxis1CB) self._alignmentAxis1CB.setToolTip( f"Alignment to do in case of volumes with different size over axis 1. Only possible for post-processing (reconstructed volume). See {self.ALIGNMENT_DOC} for details." ) # alignment axis 2 self._alignmentAxis2CB = qt.QComboBox(self) for alignment in AlignmentAxis2: self._alignmentAxis2CB.addItem(alignment.value) self.layout().addRow("Axis 2 alignment", self._alignmentAxis2CB) self._alignmentAxis2CB.setToolTip( f"Alignment to do in case of frames with different size over axis 2. See {self.ALIGNMENT_DOC} for details." ) # pad mode self._padModeCB = qt.QComboBox(self) for pad_mode in self._PAD_MODES: self._padModeCB.addItem(pad_mode) self.layout().addRow("pad mode", self._padModeCB) self._padModeCB.setToolTip("padding mode to apply for alignment") # set up self.setAlignmentAxis1(self.DEFAULT_ALIGNMENT_AXIS_1) self.setAlignmentAxis2(self.DEFAULT_ALIGNMENT_AXIS_2) def getAlignmentAxis1(self) -> AlignmentAxis1: return AlignmentAxis1(self._alignmentAxis1CB.currentText()) def setAlignmentAxis1(self, alignment: AlignmentAxis1): alignment = AlignmentAxis1(alignment) self._alignmentAxis1CB.setCurrentIndex( self._alignmentAxis1CB.findText(alignment.value) ) def getAlignmentAxis2(self) -> AlignmentAxis2: return AlignmentAxis2(self._alignmentAxis2CB.currentText()) def setAlignmentAxis2(self, alignment: AlignmentAxis2): alignment = AlignmentAxis2(alignment) self._alignmentAxis2CB.setCurrentIndex( self._alignmentAxis2CB.findText(alignment.value) ) def getPadMode(self) -> str: return self._padModeCB.currentText() def setPadMode(self, pad_mode: str): idx = self._padModeCB.findText(pad_mode) if idx >= 0: self._padModeCB.setCurrentIndex(idx) def setAlignmentAxis1Enabled(self, enabled: bool): self._alignmentAxis1CB.setEnabled(enabled) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/stitching/axisorderedlist.py0000644000175000017500000004430115153325210022663 0ustar00paynopayno"""widgets to perform a z-sttiching in pre processing (from projections) or post processing (from reconstructed volumes)""" from __future__ import annotations import logging from silx.gui import qt from silx.gui.utils import blockSignals from tomoscan.scanbase import TomoScanBase from tomoscan.series import Series from tomwer.io.utils.tomoobj import get_tomo_objs_instances from tomwer.core.tomwer_object import TomwerObject from tomwer.gui.stitching.metadataholder import QStitchingMetadata from tomwer.gui.utils.illustrations import _IllustrationWidget from .singleaxis import _SingleAxisMixIn _logger = logging.getLogger(__name__) class AxisOrderedTomoObjWidget(qt.QWidget, _SingleAxisMixIn): """ main widget to define configuration of a z-stitching """ sigConfigChanged = qt.Signal() """emit when the configuration changed""" sigAddTomoObjRequest = qt.Signal(TomwerObject) """request when a file is dropped or added through the 'add button'.""" sigRemoveObjRequest = qt.Signal(TomwerObject) """request when an object should be removed by calling the 'remove button'.""" def __init__(self, axis: int, parent=None): super().__init__(parent=parent) if axis not in (0, 1, 2): raise ValueError(f"axis should be in (0, 1, 2). Got {axis}") self._axis = axis # implement _SingleAxisMixIn interface self.setLayout(qt.QGridLayout()) self._addTomoObjCallbacks = tuple() self._removetomoObjCallbacks = tuple() # left panel with arrow img_flow = "flow_down" left_panel_width = 50 axis_label = self.axis_alias(axis) self._axisLabel = qt.QLabel(axis_label, parent=self) self._axisLabel.setToolTip(f"{axis_label} is also know as axis {axis}") font = self._axisLabel.font() font.setPixelSize(40) self._axisLabel.setFont(font) self._axisLabel.setAlignment(qt.Qt.AlignCenter) self._axisLabel.setFixedWidth(left_panel_width) self.layout().addWidget(self._axisLabel, 1, 0, 1, 1) self._flowIllustration = _IllustrationWidget(parent=self, img=img_flow) self._flowIllustration.setFixedWidth(left_panel_width) self._flowIllustration.setSizePolicy( qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding ) self.layout().addWidget(self._flowIllustration, 2, 0, 1, 1) self._flowIllustration.setToolTip( f"we are first ordering tomo object along axis {axis} (aka {self.axis_alias(axis)}) position to apply stitching" ) # central object list self._tomoObjsTableView = qt.QTableView(parent=self) self._tomoObjsTableView.setModel( AxisOrderedTomoObjsModel(parent=self._tomoObjsTableView, axis=axis) ) self._tomoObjsTableView.setSelectionBehavior(qt.QAbstractItemView.SelectRows) self._tomoObjsTableView.horizontalHeader().setStretchLastSection(True) self._tomoObjsTableView.setSortingEnabled(False) self._tomoObjsTableView.setColumnWidth(0, 20) self._tomoObjsTableView.setDragEnabled(True) self._tomoObjsTableView.setAcceptDrops(True) self.layout().addWidget(self._tomoObjsTableView, 2, 1, 1, 1) def addTomoObj(self, tomo_obj: TomoScanBase, trigger_callbacks=False): if tomo_obj is None: return else: self._tomoObjsTableView.model().addTomoObj(tomo_obj) # register tomo obj metadata modification to make sure we tell the z ordered list up to data tomo_obj.stitching_metadata.sigChanged.connect(self._orderMightHaveChanged) if trigger_callbacks: for callback in self._addTomoObjCallbacks: callback(tomo_obj) def removeTomoObj(self, tomo_obj, trigger_callbacks=False): self._tomoObjsTableView.model().removeTomoObj(tomo_obj) tomo_obj.stitching_metadata.sigChanged.disconnect(self._orderMightHaveChanged) if trigger_callbacks: for callback in self._removetomoObjCallbacks: callback(tomo_obj) def _orderMightHaveChanged(self): # when position over {axis} is updated from the GUI, make sure the {axis} ordered list of tomo object is still # ordered and selection is still the accurate one. # this case is not handled on this widget self._tomoObjsTableView.model().reorder_objs() def getTomoObjsAxisOrdered(self) -> tuple: return tuple(self._tomoObjsTableView.model()._axis_decreasing_ordered_objs) def clearTomoObjs(self): self._tomoObjsTableView.model().clearTomoObjs() class AxisOrderedTomoObjsModel(qt.QAbstractTableModel): def __init__(self, axis: int, parent=None) -> None: super().__init__(parent) assert axis in (0, 1, 2) self._axis = axis # either we plot the tomo_obj in the list within the full identifier or with the reduce str (in this case two scans can have identical name. Identifier is unique) self._objs = Series(name="unordered tomo obj", use_identifiers=False) self._axis_decreasing_ordered_objs = [] self._headers = ["index", "tomo obj"] self._tomoObjToIndex = {} # for each tomo object store a 'unique' id self._nextIndex = -1 def supportedDragActions(self): return qt.Qt.CopyAction def supportedDropActions(self): return qt.Qt.CopyAction def getTomoObjs(self) -> tuple: return tuple(self._objs) def pop_index(self): self._nextIndex += 1 return self._nextIndex def getTomoObjCurrentPos(self, tomo_obj): try: index = self._axis_decreasing_ordered_objs.index(tomo_obj) except ValueError: # if not in the list return -1 else: return index def clearTomoObjs(self): self._objs = Series(name="unordered tomo obj", use_identifiers=False) self._axis_decreasing_ordered_objs = [] self.layoutChanged.emit() def reorder_objs(self): def get_min_axis_or_0(tomo_obj): # expects to find a position. If cannot set the value to infinity to be sure all tomo objects without # metadata (raw or from the user) are at the specific position return ( tomo_obj.stitching_metadata.get_abs_position_px(axis=self._axis) or 0.0 ) self._axis_decreasing_ordered_objs = Series( "ordered tomo obj", sorted(self._objs[:], key=get_min_axis_or_0, reverse=True), use_identifiers=False, ) def addTomoObj(self, obj: TomwerObject): if not isinstance(obj, TomwerObject): raise TypeError( f"{obj} is expected to be an instance of {TomwerObject}. {type(obj)} provided instead" ) elif obj.stitching_metadata is None: # make sure it can contain some stitching metadata obj.stitching_metadata = QStitchingMetadata(tomo_obj=obj) elif not isinstance(obj.stitching_metadata, QStitchingMetadata): # if need to upgrade it to a QObject obj.stitching_metadata = QStitchingMetadata.from_dict( obj.stitching_metadata.to_dict(), tomo_obj=obj ) self._objs.append(obj) identifier = obj.get_identifier().to_str() if identifier not in self._tomoObjToIndex: self._tomoObjToIndex[identifier] = self.pop_index() self.reorder_objs() self.layoutChanged.emit() def removeTomoObj(self, obj: TomwerObject): if not isinstance(obj, TomwerObject): raise TypeError( f"{obj} is expected to be an instance of {TomwerObject}. {type(obj)} provided instead" ) self._objs.remove(obj) # note: we avoid removing the identifier as this is pretty small and convenient to keep # in case of wromg manipulation when removing an item self.reorder_objs() self.layoutChanged.emit() def rowCount(self, parent=None): return len(self._objs) def columnCount(self, parent=None): return len(self._headers) def headerData(self, col, orientation, role): if orientation == qt.Qt.Horizontal and role == qt.Qt.DisplayRole: if col < len(self._headers): return self._headers[col] else: return None def getTomoObj(self, qmodelindex: qt.QModelIndex): index = qmodelindex.row() if index < len(self._axis_decreasing_ordered_objs): return self._axis_decreasing_ordered_objs[index] def data(self, index, role): if not index.isValid(): return None if index.column() == 0: if role == qt.Qt.TextAlignmentRole: return qt.Qt.AlignLeft | qt.Qt.AlignVCenter elif role == qt.Qt.DisplayRole: obj = self._axis_decreasing_ordered_objs[index.row()] identifier = obj.get_identifier().to_str() return self._tomoObjToIndex.get(identifier, "???") elif role == qt.Qt.ToolTipRole: return "Index of the object along the axis" else: return None elif index.column() == 1: if role == qt.Qt.TextAlignmentRole: return qt.Qt.AlignHCenter | qt.Qt.AlignVCenter elif role == qt.Qt.ToolTipRole: obj = self._axis_decreasing_ordered_objs[index.row()] return obj.get_identifier().to_str() elif role == qt.Qt.DisplayRole: obj = self._axis_decreasing_ordered_objs[index.row()] return obj.get_identifier().short_description() elif role == qt.Qt.ToolTipRole: return "Identifier of hte object" else: return None elif index.column() == 2 and role == qt.Qt.ToolTipRole: return "Position of the object (in pixel) along the axis." elif index.column() == 3 and role == qt.Qt.ToolTipRole: return "Is this object is linked to the currently selected object any shift applied will affect both objects simultaneously." else: return None class AxisOrderedTomoObjWidgetSingleSel(AxisOrderedTomoObjWidget): """ AxisOrderedTomoObjWidget with a list that can select a single line. The idea is that it can be used to select the object to be edited on another widget """ def __init__(self, axis: int, parent=None): super().__init__(axis=axis, parent=parent) self._tomoObjsTableView.setSelectionMode(qt.QAbstractItemView.SingleSelection) def removeTomoObj(self, tomo_obj): selected = self.getSelectedTomoObj() super().removeTomoObj(tomo_obj=tomo_obj) if selected is tomo_obj: self.setSelectedTomoObj(None) else: self.setSelectedTomoObj(selected) def getSelectedTomoObj(self): selection = self._tomoObjsTableView.selectedIndexes() if len(selection) > 0: return self._tomoObjsTableView.model().getTomoObj(selection[0]) return None def setSelectedTomoObj(self, tomo_obj: TomwerObject | None): self._tomoObjsTableView.selectionModel().clearSelection() if tomo_obj is not None: model = self._tomoObjsTableView.model() tomo_obj_ordered_row = model.getTomoObjCurrentPos(tomo_obj=tomo_obj) if tomo_obj_ordered_row >= 0: for i_column in range(model.columnCount()): selection = model.createIndex( tomo_obj_ordered_row, i_column, ) self._tomoObjsTableView.selectionModel().select( selection, qt.QItemSelectionModel.Select, ) def _orderMightHavechanged(self): # when z position is updated from the GUI, make sure the z ordered list of tomo object is still # ordered and selection is still the accurate one. with blockSignals(self._tomoObjsTableView.selectionModel()): selectedTomoObj = self.getSelectedTomoObj() self._tomoObjsTableView.model().reorder_objs() self._tomoObjsTableView.model().layoutChanged.emit() self.setSelectedTomoObj(selectedTomoObj) class EditableOrderedTomoObjWidget(AxisOrderedTomoObjWidget): """ same as the ZOrderedTomoObjWidget but you can add and remove tomo obj to the list """ def __init__(self, axis: int, parent=None): super().__init__(axis=axis, parent=parent) if axis not in (0, 1, 2): raise ValueError(f"axis must be in (0, 1, 2). Got {axis}") self._axis = axis self.setAcceptDrops(True) # allow multiple selection as we might want to remove several object at the same time self._tomoObjsTableView.setSelectionMode(qt.QAbstractItemView.MultiSelection) self._buttons = qt.QWidget(self) self._buttons.setLayout(qt.QHBoxLayout()) # allow drag and drop of elmts # create buttons ## spacer self._spacer = qt.QWidget(self._buttons) self._spacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) self._buttons.layout().addWidget(self._spacer) ## add button self._addButton = qt.QPushButton("Add") self._addButton.clicked.connect(self._callbackAddTomoObj) self._buttons.layout().addWidget(self._addButton) ## rm button self._rmButton = qt.QPushButton("Remove") self._rmButton.clicked.connect(self._callbackRemoveSelectedTomoObj) self._buttons.layout().addWidget(self._rmButton) self.layout().addWidget(self._buttons, 999, 0, 1, 2) @property def axis(self) -> int: return self._axis def removeTomoObj(self, tomo_obj, trigger_callbacks=False): selected = set(self.getSelectedTomoObjs()) super().removeTomoObj(tomo_obj=tomo_obj, trigger_callbacks=trigger_callbacks) if tomo_obj in selected: selected.remove(tomo_obj) self.setSelectedTomoObjs(selected) def setSelectedTomoObjs(self, tomo_objs): self._tomoObjsTableView.clearSelection() model = self._tomoObjsTableView.model() for tomo_obj in tomo_objs: tomo_obj_ordered_row = model.getTomoObjCurrentPos(tomo_obj=tomo_obj) if tomo_obj_ordered_row >= 0: for i_column in range(model.columnCount()): selection = model.createIndex( tomo_obj_ordered_row, i_column, ) self._tomoObjsTableView.selectionModel().select( selection, qt.QItemSelectionModel.Select, ) def getSelectedTomoObjs(self): selection = self._tomoObjsTableView.selectedIndexes() return set( [self._tomoObjsTableView.model().getTomoObj(item) for item in selection] ) def _callbackAddTomoObj(self) -> tuple[TomwerObject]: dialog = qt.QFileDialog() dialog.setFileMode(qt.QFileDialog.ExistingFiles) dialog.setNameFilters( [ "Any file (*)", ] ) if not dialog.exec(): dialog.close() return () elif len(dialog.selectedFiles()) == 0: return () else: tomo_objs = [] for file in dialog.selectedFiles(): try: new_objs = get_tomo_objs_instances(tomo_objs=(file,))[0] except Exception: pass else: tomo_objs.extend(new_objs) for tomo_obj in tomo_objs: self.addTomoObj(tomo_obj=tomo_obj, trigger_callbacks=True) return tuple(tomo_objs) def _callbackRemoveSelectedTomoObj(self): obj_to_remove = self.getSelectedTomoObjs() for obj in obj_to_remove: self.removeTomoObj(tomo_obj=obj, trigger_callbacks=True) def dropEvent(self, a0) -> None: if a0.mimeData().hasFormat("text/uri-list"): paths = [url.path() for url in a0.mimeData().urls()] tomo_objs = get_tomo_objs_instances(paths)[0] for tomo_obj in tomo_objs: assert isinstance( tomo_obj, TomwerObject ), f"expected type is tomo_obj. Get {type(tomo_obj)}" self.addTomoObj(tomo_obj=tomo_obj, trigger_callbacks=True) else: return super().dropEvent(a0) def supportedDropActions(self): """Inherited method to redefine supported drop actions.""" return qt.Qt.CopyAction | qt.Qt.MoveAction def dragEnterEvent(self, event): if event.mimeData().hasFormat("text/uri-list"): event.accept() event.setDropAction(qt.Qt.CopyAction) else: qt.QListWidget.dragEnterEvent(self, event) def dragMoveEvent(self, event): if event.mimeData().hasFormat("text/uri-list"): event.setDropAction(qt.Qt.CopyAction) event.accept() else: qt.QListWidget.dragMoveEvent(self, event) def setAddTomoObjCallbacks(self, callbacks: tuple): """ To synchronize the different widget we might need to notify other widget that a tomo_obj has been added from the dedicated interface. Callbacks must take a single TomwerObject as input """ self._addTomoObjCallbacks = callbacks def setRemoveTomoObjCallbacks(self, callbacks: tuple): """ To synchronize the different widget we might need to notify other widget that a tomo_obj has been removed from the dedicated interface. Callbacks must take a single TomwerObject as input """ self._removetomoObjCallbacks = callbacks def _orderMightHavechanged(self): # when z position is updated from the GUI, make sure the z ordered list of tomo object is still # ordered and selection is still the accurate one. with blockSignals(self._tomoObjsTableView.selectionModel()): selectedTomoObjs = self.getSelectedTomoObjs() self._tomoObjsTableView.model().reorder_objs() self._tomoObjsTableView.model().layoutChanged.emit() self.setSelectedTomoObjs(selectedTomoObjs) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9451017 tomwer-1.6.17/src/tomwer/gui/stitching/config/0000755000175000017500000000000015153325403020353 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771225048.0 tomwer-1.6.17/src/tomwer/gui/stitching/config/_QSpinBox.py0000644000175000017500000000100515144537730022573 0ustar00paynopaynofrom silx.gui import qt class QSpinBoxWithEditionSignal(qt.QSpinBox): sigFocusOut = qt.Signal() sigFocusIn = qt.Signal() def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.installEventFilter(self) def eventFilter(self, obj, event): if event.type() == qt.QEvent.Type.FocusIn: self.sigFocusIn.emit() elif event.type() == qt.QEvent.Type.FocusOut: self.sigFocusOut.emit() return super().eventFilter(obj, event) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/stitching/config/__init__.py0000644000175000017500000000000014757047403022464 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771225048.0 tomwer-1.6.17/src/tomwer/gui/stitching/config/_linkInfo.py0000644000175000017500000000150515144537730022646 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from tomwer.gui import icons class LinkInfoFrame(qt.QLabel): def __init__(self, parent=None): super().__init__(parent) self._lockedIcon = icons.getQIcon("link") self._unlockedIcon = icons.getQIcon("link-slash") self._pixmapSize = qt.QSize(24, 24) lockIcon = qt.QLabel() lockIcon.setFrameShape(qt.QFrame.Shape.Box) self.setLocked(True) def setPixmapSize(self, w: int, h: int) -> None: self._pixmapSize = qt.QSize(w, h) def setLocked(self, locked: bool): icon = self._lockedIcon if locked else self._unlockedIcon pixmap = icon.pixmap(self._pixmapSize) self.setPixmap(pixmap) self._locked: bool = locked def isLocked(self) -> bool: return self._locked ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771225048.0 tomwer-1.6.17/src/tomwer/gui/stitching/config/axisparams.py0000644000175000017500000001750315144537730023113 0ustar00paynopaynofrom __future__ import annotations import logging from nabu.stitching import config as stitching_config from nabu.stitching.utils import ShiftAlgorithm as StitchShiftAlgorithm from silx.gui import qt from tomwer.gui.utils.qt_utils import block_signals from tomwer.gui.configuration.level import ConfigurationLevel from tomwer.gui.utils.scrollarea import QComboBoxIgnoreWheel as QComboBox from tomwer.gui.utils.scrollarea import QSpinBoxIgnoreWheel as QSpinBox _logger = logging.getLogger(__name__) class StitcherAxisParams(qt.QWidget): """ Widget to define settings of shift search along one axis """ sigConfigChanged = qt.Signal() """signal emit when the configuration is updated""" DEFAULT_WINDOW_SEARCH_SIZE = 400 # default window size for shift search def __init__(self, axis, parent=None) -> None: super().__init__(parent) if not isinstance(axis, int): raise TypeError("axis is expected to be an int") assert axis in (0, 1, 2) self._axis = axis self.setLayout(qt.QGridLayout()) self._shiftSearchMethodCB = QComboBox(parent=self) # shift algorithm shift_search_methods = [ StitchShiftAlgorithm.NONE, StitchShiftAlgorithm.NABU_FFT, StitchShiftAlgorithm.SKIMAGE, StitchShiftAlgorithm.ITK_IMG_REG_V4, ] for method in shift_search_methods: self._shiftSearchMethodCB.addItem(method.value) self._methodLabel = qt.QLabel("shift search method", self) self.layout().addWidget(self._methodLabel, 0, 0, 1, 1) self.layout().addWidget(self._shiftSearchMethodCB, 0, 1, 1, 1) # stitching options self._windowSizeLabel = qt.QLabel("window size", self) self.layout().addWidget(self._windowSizeLabel, 1, 0, 1, 1) self._windowSizeSB = QSpinBox(self) self._windowSizeSB.setMinimum(1) self._windowSizeSB.setMaximum(9999999) self._windowSizeSB.setValue(self.DEFAULT_WINDOW_SEARCH_SIZE) self._windowSizeSB.setSuffix("px") self.layout().addWidget(self._windowSizeSB, 1, 1, 1, 1) tooltip = "size of the window to try to refine shift" self._windowSizeLabel.setToolTip(tooltip) self._windowSizeSB.setToolTip(tooltip) # filter options self._filteringGroup = _FilteringGroupBox("filter for shift search", self) self._filteringGroup.setCheckable(True) self._filteringGroup.setChecked(False) self._filteringGroup.setLowPassValue(1) self._filteringGroup.setHighPassValue(20) self.layout().addWidget(self._filteringGroup, 2, 0, 2, 3) # set up self._methodChanged() # connect signal / slot self._shiftSearchMethodCB.currentIndexChanged.connect(self._methodChanged) self._windowSizeSB.valueChanged.connect(self._notifyConfigChanged) self._filteringGroup.sigValueChanged.connect(self._notifyConfigChanged) @property def axis(self): return self._axis def getShiftSearchMethod(self) -> StitchShiftAlgorithm: return StitchShiftAlgorithm(self._shiftSearchMethodCB.currentText()) def setShiftSearchMethod(self, method: StitchShiftAlgorithm | str) -> None: method = StitchShiftAlgorithm(method) idx = self._shiftSearchMethodCB.findText(method.value) self._shiftSearchMethodCB.setCurrentIndex(idx) def getConfiguration(self) -> dict: method = self.getShiftSearchMethod() param_opts = [ f"{stitching_config.KEY_IMG_REG_METHOD}={method.value}", f"{stitching_config.KEY_WINDOW_SIZE}={self._windowSizeSB.value()}", ] if self._filteringGroup.isChecked(): param_opts.append( f"{stitching_config.KEY_LOW_PASS_FILTER}='{self._filteringGroup.getLowPassValue()}'" ) param_opts.append( f"{stitching_config.KEY_HIGH_PASS_FILTER}='{self._filteringGroup.getHighPassValue()}'" ) param_as_str = ";".join(param_opts) return { stitching_config.STITCHING_SECTION: { f"axis_{self.axis}_params": param_as_str, }, } def setConfiguration(self, config: dict) -> None: with block_signals(self): axis_params = config.get(stitching_config.STITCHING_SECTION, {}).get( f"axis_{self.axis}_params", "" ) options = filter( lambda a: a not in (None, ""), axis_params.replace(",", ";").split(";") ) for option in options: clean_option = option.rstrip(" ").lstrip(" ") opt_name, opt_value = clean_option.split("=") if opt_value == "": continue if opt_name == stitching_config.KEY_IMG_REG_METHOD: self.setShiftSearchMethod(opt_value) elif opt_name == stitching_config.KEY_WINDOW_SIZE: self._windowSizeSB.setValue(int(opt_value)) elif opt_name == stitching_config.KEY_LOW_PASS_FILTER: self._filteringGroup.setLowPassValue(int(opt_value)) self._filteringGroup.setEnabled(True) elif opt_name == stitching_config.KEY_HIGH_PASS_FILTER: self._filteringGroup.setHighPassValue(int(opt_value)) self._filteringGroup.setEnabled(True) elif opt_name == stitching_config.KEY_OVERLAP_SIZE: pass else: _logger.error(f"option {opt_name} is not recognized") self._notifyConfigChanged() def _methodChanged(self) -> None: method = self.getShiftSearchMethod() with block_signals(self): self._windowSizeSB.setVisible(method is not StitchShiftAlgorithm.NONE) self._windowSizeLabel.setVisible(method is not StitchShiftAlgorithm.NONE) self._notifyConfigChanged() def _notifyConfigChanged(self, *args, **kwargs) -> None: self.sigConfigChanged.emit() def setConfigurationLevel(self, level: ConfigurationLevel): method = self.getShiftSearchMethod() self._windowSizeLabel.setVisible( level >= ConfigurationLevel.OPTIONAL and method is not StitchShiftAlgorithm.NONE ) self._windowSizeSB.setVisible( level >= ConfigurationLevel.OPTIONAL and method is not StitchShiftAlgorithm.NONE ) self._filteringGroup.setVisible(level >= ConfigurationLevel.ADVANCED) class _FilteringGroupBox(qt.QGroupBox): sigValueChanged = qt.Signal() """emit when one of the low or high pass value changed or when toggled""" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setLayout(qt.QFormLayout()) self._lowPassFilterSP = QSpinBox(self) self.layout().addRow("low pass filter", self._lowPassFilterSP) self._highPassFilterSP = QSpinBox(self) self.layout().addRow("high pass filter", self._highPassFilterSP) # connect signal / slot self.toggled.connect(self._updateEnability) self.toggled.connect(self._valueChanged) self._lowPassFilterSP.editingFinished.connect(self._valueChanged) self._highPassFilterSP.editingFinished.connect(self._valueChanged) def _updateEnability(self): self._lowPassFilterSP.setEnabled(self.isChecked()) self._highPassFilterSP.setEnabled(self.isChecked()) def getLowPassValue(self): return self._lowPassFilterSP.value() def setLowPassValue(self, value): self._lowPassFilterSP.setValue(value) def getHighPassValue(self): return self._highPassFilterSP.value() def setHighPassValue(self, value): self._highPassFilterSP.setValue(value) def _valueChanged(self, *args, **kwargs): self.sigValueChanged.emit() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/stitching/config/output.py0000644000175000017500000001610715143647637022311 0ustar00paynopaynoimport logging from nabu.stitching import config as stitching_config from nabu.stitching.config import StitchingType from nxtomomill.models.utils import convert_str_to_bool from silx.gui import qt from tomwer.core.scan.nxtomoscan import NXtomoScan, NXtomoScanIdentifier from tomwer.core.scan.scanfactory import ScanFactory from tomwer.gui.utils.inputwidget import OutputVolumeDefinition from tomwer.gui.qlefilesystem import QLFileSystem from silx.io.url import DataUrl _logger = logging.getLogger(__name__) class _PreProcessingOutput(qt.QWidget): """ Define output settings for the pre processing z stitching """ def __init__(self, parent=None) -> None: super().__init__(parent) self.setLayout(qt.QGridLayout()) # TODO: check if the widget with output .nx file exists somewhere # output file self._outputFile = QLFileSystem("", self) self._outputFileLabel = qt.QLabel("output nexus file") self.layout().addWidget(self._outputFileLabel, 0, 0, 1, 1) self.layout().addWidget(self._outputFile, 0, 1, 1, 1) self._selectPB = qt.QPushButton("select", self) self.layout().addWidget(self._selectPB, 0, 2, 1, 1) self._outputDataPathLabel = qt.QLabel("output data path") self.layout().addWidget(self._outputDataPathLabel, 1, 0, 2, 1) self._outputDataPath = qt.QLineEdit("", self) self._outputDataPath.setToolTip("Location of the dataset **inside** the file.") self.layout().addWidget(self._outputDataPath, 1, 1, 1, 2) # connect signal / slot self._selectPB.released.connect(self._selectNxTomoFile) def getUrl(self) -> str: return NXtomoScanIdentifier( object=NXtomoScan, hdf5_file=self._outputFile.text(), entry=self._outputDataPath.text(), ) def setUrl(self, url: str): try: identifier = NXtomoScanIdentifier.from_str(url) except Exception as e: _logger.warning(f"Fail to create an identifier from {url}. Error is {e}") else: self._outputFile.setText(identifier.file_path) self._outputDataPath.setText(identifier.data_path) def _selectNxTomoFile(self): dialog = qt.QFileDialog(self) dialog.setNameFilters( [ "Any files (*)", "HDF5 files (*.h5 *.hdf5 *.nx *.nxs *.nexus)", "Nexus files (*.nx *.nxs *.nexus)", ] ) if not dialog.exec(): dialog.close() elif len(dialog.selectedFiles()) == 0: return else: self._outputFile.setText(dialog.selectedFiles()[0]) class _PostProcessingOutput(OutputVolumeDefinition): """ Define output settings for the post processing z stitching """ def getUrl(self) -> str: return self.getOutputVolumeIdentifier().to_str() def setUrl(self, url: str): self.setOutputVolumeIdentifier(url) class StitchingOutput(qt.QWidget): """ Defines the output of the stitching """ sigChanged = qt.Signal() """emit when stithcing output change""" def __init__(self, parent=None) -> None: super().__init__(parent) self.__stitching_type = None self.setLayout(qt.QVBoxLayout()) self._preProcOutput = _PreProcessingOutput(parent=self) self.layout().addWidget(self._preProcOutput) self._postProcOutput = _PostProcessingOutput(parent=self) self.layout().addWidget(self._postProcOutput) self._overwritePB = qt.QCheckBox("Overwrite", self) self._overwritePB.setChecked(True) self.layout().addWidget(self._overwritePB) # add a vertical spacer for display spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer) self._updateOutputForStitchingType(StitchingType.Z_PREPROC) def _updateOutputForStitchingType(self, stitching_type): self.__stitching_type = StitchingType(stitching_type) self._preProcOutput.setVisible(self.__stitching_type is StitchingType.Z_PREPROC) self._postProcOutput.setVisible( self.__stitching_type is StitchingType.Z_POSTPROC ) def getConfiguration(self) -> dict: config = { stitching_config.OUTPUT_SECTION: { stitching_config.OVERWRITE_RESULTS_FIELD: self._overwritePB.isChecked() }, } if self.__stitching_type is StitchingType.Z_POSTPROC: config.update( { stitching_config.POST_PROC_SECTION: { stitching_config.OUTPUT_VOLUME: self._postProcOutput.getUrl() }, } ) return config elif self.__stitching_type is StitchingType.Z_PREPROC: url = self._preProcOutput.getUrl() try: scan = ScanFactory.create_tomo_object_from_identifier(url) except Exception: scan = None if not isinstance(scan, NXtomoScan): _logger.warning("Failed to create an HDF5Tomoscan from url") pass else: config.update( { stitching_config.PRE_PROC_SECTION: { stitching_config.DATA_FILE_FIELD: scan.master_file, stitching_config.DATA_PATH_FIELD: scan.entry, }, } ) return config else: raise NotImplementedError def setConfiguration(self, config: dict): stitching_type = config.get(stitching_config.STITCHING_SECTION, {}).get( stitching_config.STITCHING_TYPE_FIELD, None ) if stitching_type is not None: self._updateOutputForStitchingType(stitching_type) output_volume = config.get(stitching_config.POST_PROC_SECTION, {}).get( stitching_config.OUTPUT_VOLUME, None ) if output_volume: self._postProcOutput.setUrl(output_volume) location = config.get(stitching_config.PRE_PROC_SECTION, {}).get( stitching_config.DATA_FILE_FIELD, None ) data_path = config.get(stitching_config.PRE_PROC_SECTION, {}).get( stitching_config.DATA_PATH_FIELD, None ) if location is not None: identifier = NXtomoScanIdentifier( object=NXtomoScan, hdf5_file=location, entry=data_path ) self._preProcOutput.setUrl(identifier.to_str()) overwrite = config.get(stitching_config.OUTPUT_SECTION, {}).get( stitching_config.OVERWRITE_RESULTS_FIELD, None ) if overwrite is not None: overwrite = convert_str_to_bool(overwrite) self._overwritePB.setChecked(overwrite) # expose API def setPreProcessingOutput(self, identifier: str) -> None: self._preProcOutput.setUrl(identifier) def setPostProcessingOutput(self, identifier: DataUrl) -> None: self._postProcOutput.setUrl(identifier) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771225048.0 tomwer-1.6.17/src/tomwer/gui/stitching/config/positionoveraxis.py0000644000175000017500000005205615144537730024372 0ustar00paynopaynofrom __future__ import annotations import logging import functools import numpy from silx.gui import qt from enum import Enum as _Enum from tomwer.core.tomwer_object import TomwerObject from tomwer.gui import icons from tomwer.gui.stitching.axisorderedlist import AxisOrderedTomoObjsModel from tomwer.gui.utils.step import StepSizeSelectorWidget from tomwer.gui.utils.qt_utils import block_signals from ._QSpinBox import QSpinBoxWithEditionSignal from ._linkInfo import LinkInfoFrame _logger = logging.getLogger(__name__) class PosEditorOverOneAxis(qt.QWidget): """keep it ordered along one axis""" LOCK_INFO_WIDTH = 24 sigEditionAboutToStart = qt.Signal(object) sigEditionFinished = qt.Signal(object) def __init__( self, parent, axis_edited: int, axis_order=None, lock_info: bool = False, *args, **kwargs, ) -> None: assert axis_edited in (0, 1, 2) super().__init__(parent, *args, **kwargs) self._axisEdited = axis_edited # the axis we are editing self._axisOrder = axis_order if axis_order is not None else axis_edited # the axis along which the tomo obj are ordered self._tomoObjtoTomoObjPosWidget = {} # list of `_TomoObjPosition` to edit the position over the axis. Key is the tomo object, value is the `_TomoObjPosition` if lock_info: self._tomoObjToLockInfo = {} # list of `_TomoObjPosition` to know if this position is locked regarding the object currently edited. self.__tomoObjPosWidgetCallbacks = {} self.setLayout(qt.QVBoxLayout()) # widget to define step size self._stepSizeWidget = StepSizeSelectorWidget( self, fine_value=1, medium_value=5, rough_value=25, dtype=int, ) self.layout().addWidget(self._stepSizeWidget) # widget to define edition mode and reset self._editionOptionsWidget = _EditionOptions() self.layout().addWidget(self._editionOptionsWidget) # table with the different Tomo objects self._tomoObjsTableView = qt.QTableView(parent=self) model = EditableAxisOrderedTomoObjsModel(axis=axis_edited, lock_info=lock_info) self._tomoObjsTableView.setModel(model) self.layout().addWidget(self._tomoObjsTableView) # connect signal / slot self._stepSizeWidget.valueChanged.connect(self._updateStepSize) self._editionOptionsWidget.sigReset.connect(self._resetPositions) # tune table view self._tomoObjsTableView.setColumnWidth(0, 45) self._tomoObjsTableView.setColumnWidth(2, _TomoObjPosition.WIDGET_WIDTH) if self.isDisplayingLockInfo(): self._tomoObjsTableView.setColumnWidth(3, self.LOCK_INFO_WIDTH) self._tomoObjsTableView.horizontalHeader().setSectionResizeMode( 1, qt.QHeaderView.Stretch ) self.setStepSize(1) def isDisplayingLockInfo(self): return hasattr(self, "_tomoObjToLockInfo") def _updateStepSize(self): step_size = self.getStepSize() for sb in self._tomoObjtoTomoObjPosWidget.values(): sb.setSingleStep(step_size) def setStepSize(self, step_size: int): self._stepSizeWidget.setStepSize(step_size) self._updateStepSize() def getStepSize(self) -> int: return self._stepSizeWidget.getStepSize() def getTomoObjs(self) -> tuple[TomwerObject]: return self._tomoObjsTableView.model().getTomoObjs() def addTomoObj(self, tomo_obj): if tomo_obj is None: return else: self._tomoObjsTableView.model().addTomoObj(tomo_obj) # register tomo obj metadata modification to make sure we keel the z ordered list up to data tomo_obj.stitching_metadata.sigChanged.connect( self._orderedMightHaveChanged ) self._createTomoObjPosition(tomo_obj=tomo_obj) self._orderedMightHaveChanged() def _createLockInfo(self): lockInfo = LinkInfoFrame() lockInfo.setPixmapSize(self.LOCK_INFO_WIDTH, self.LOCK_INFO_WIDTH) lockInfo.setLocked(False) lockInfo.setFixedWidth(self.LOCK_INFO_WIDTH) return lockInfo def _createTomoObjPosition(self, tomo_obj, original_value: float | None = None): """ :param original_value: original_value of the tomo_obj along the edited axis. Used when the widget is delete and recreate """ identifier_as_str = tomo_obj.get_identifier().to_str() widget = _TomoObjPosition( tomo_obj=tomo_obj, axis_edited=self._axisEdited, original_value=original_value, parent=self, ) widget.setSingleStep(self.getStepSize()) self._tomoObjtoTomoObjPosWidget[identifier_as_str] = widget # connect signal / slot callback = functools.partial( self._tomoObjPosChanged, spin_box=widget, tomo_obj_to_update=tomo_obj ) self.__tomoObjPosWidgetCallbacks[identifier_as_str] = callback widget.sigValueChanged.connect(callback) if self.isDisplayingLockInfo(): self._tomoObjToLockInfo[identifier_as_str] = self._createLockInfo() widget.sigEditionAboutToStart.connect(self._editionAboutToStart) widget.sigEditionFinished.connect(self._editionFinished) return widget def _editionAboutToStart(self): if not isinstance(self.sender(), _TomoObjPosition): raise TypeError( f"sender is expected to be an instance of {_TomoObjPosition}. Got {type(self.sender)}" ) if self.sender().getValue() is None: return self._updateLockInfo(tomo_obj_pos=self.sender(), mode=self.getEditionMode()) def _editionFinished(self): if not isinstance(self.sender(), _TomoObjPosition): raise TypeError( f"sender is expected to be an instance of {_TomoObjPosition}. Got {type(self.sender)}" ) if self.sender().getValue() is None: return self._resetLockInfo() def _deleteTomoObjPosition(self, tomo_obj): identifier_as_str = tomo_obj.get_identifier().to_str() if identifier_as_str in self._tomoObjtoTomoObjPosWidget: spinBox = self._tomoObjtoTomoObjPosWidget.pop( # noqa F841 identifier_as_str ) # indeed this should be called once 'self.__tomoObjPosWidgetCallbacks' disconnected. # never the less forcing deletion triggers issue 1457 (see https://gitlab.esrf.fr/tomotools/tomwer/-/issues/1457) # spinBox.deleteLater() if identifier_as_str in self.__tomoObjPosWidgetCallbacks: del self.__tomoObjPosWidgetCallbacks[identifier_as_str] if self.isDisplayingLockInfo() and identifier_as_str in self._tomoObjToLockInfo: del self._tomoObjToLockInfo[identifier_as_str] def _resetLockInfo(self) -> None: for value in self._tomoObjToLockInfo.values(): value.setLocked(False) def _updateLockInfo( self, tomo_obj_pos: _TomoObjPosition, mode: _EditionMode, ) -> None: mode = _EditionMode(mode) if not self.isDisplayingLockInfo(): return # handle downstream widgets upstream_objs = self._get_upstream_tomo_obj_pos_widgets( position=tomo_obj_pos.getValue() ) for obj in upstream_objs: obj_id = obj.get_identifier().to_str() try: lockInfo: LinkInfoFrame = self._tomoObjToLockInfo[obj_id] except KeyError: _logger.error(f"Cannot find lock info frame for {obj_id}") else: lockInfo.setLocked(mode is _EditionMode.UPSTREAM) # handle upstream widgets downstream_objs = self._get_downstream_tomo_obj( position=tomo_obj_pos.getValue() ) for obj in downstream_objs: obj_id = obj.get_identifier().to_str() try: lockInfo: LinkInfoFrame = self._tomoObjToLockInfo[obj_id] except KeyError: _logger.error(f"Cannot find lock info frame for {obj_id}") else: lockInfo.setLocked(mode is _EditionMode.DOWNSTREAM) # handle object currently in focus iPosWidgetToTomoObj = { value: key for key, value in self._tomoObjtoTomoObjPosWidget.items() } tomo_obj = iPosWidgetToTomoObj[tomo_obj_pos] lock_icon = self._tomoObjToLockInfo.get(tomo_obj, None) if lock_icon is not None: lock_icon.setLocked(False) def removeTomoObj(self, tomo_obj): self._deleteTomoObjPosition(tomo_obj) self._tomoObjsTableView.model().removeTomoObj(tomo_obj) tomo_obj.stitching_metadata.sigChanged.disconnect(self._orderedMightHaveChanged) def _tomoObjPosChanged( self, old_pos_value: int, new_pos_value: int, tomo_obj_to_update, *args, **kwargs, ): tomo_obj_to_update.stitching_metadata.setPxPos( new_pos_value, axis=self._axisEdited ) # edit upstream or downstream nodes according to the edit mode shift = new_pos_value - old_pos_value if shift == 0: return edition_mode = self._editionOptionsWidget.getEditionMode() if edition_mode is _EditionMode.FREE: tomo_objs_to_update = () elif edition_mode is _EditionMode.DOWNSTREAM: tomo_objs_to_update = self._get_downstream_tomo_obj( position=old_pos_value, tomo_obj_to_filter=tomo_obj_to_update ) elif edition_mode is _EditionMode.UPSTREAM: tomo_objs_to_update = self._get_upstream_tomo_obj_pos_widgets( position=old_pos_value, tomo_obj_to_filter=tomo_obj_to_update ) else: raise NotImplementedError(f"edition mode ({edition_mode}) is not handled") with block_signals(self): for tomo_obj_to_update in tomo_objs_to_update: associated_widget = self._tomoObjtoTomoObjPosWidget[ tomo_obj_to_update.get_identifier().to_str() ] current_value = associated_widget.getValue() assert ( current_value == associated_widget.getValue() ), "incoherent value between tomo object and widget" new_value = current_value + shift with block_signals(associated_widget): associated_widget.setValue(new_value) with block_signals(tomo_obj_to_update.stitching_metadata): tomo_obj_to_update.stitching_metadata.setPxPos( value=new_value, axis=self._axisEdited ) self._orderedMightHaveChanged() def setTomoObjs(self, tomo_objs: tuple) -> None: """ replace current list of object by the given list """ self._tomoObjsTableView.model().clearTomoObjs() for tomo_obj in tomo_objs: self.addTomoObj(tomo_obj) def clean(self): tomo_objs = self._tomoObjsTableView.model().getTomoObjs() for tomo_obj in tomo_objs: self.removeTomoObj(tomo_obj=tomo_obj) def setSeries(self): raise NotImplementedError def _resetPositions(self): tomo_objs = self.getTomoObjs() with block_signals(self): for tomo_obj in tomo_objs: widget = self._tomoObjtoTomoObjPosWidget[ tomo_obj.get_identifier().to_str() ] with block_signals(widget): widget.resetOriginalValue() tomo_obj.stitching_metadata.setPxPos( value=widget.getOriginalValue(), axis=self._axisEdited ) self._orderedMightHaveChanged() def _get_upstream_tomo_obj_pos_widgets( self, position: float, tomo_obj_to_filter: TomwerObject | None = None ) -> tuple[TomwerObject]: return tuple( filter( lambda tomo_obj: ( tomo_obj.stitching_metadata.get_abs_position_px( axis=self._axisEdited ) >= position ) and (tomo_obj is not tomo_obj_to_filter), self.getTomoObjs(), ) ) def _get_downstream_tomo_obj( self, position: float, tomo_obj_to_filter: TomwerObject | None = None ) -> tuple[TomwerObject]: return tuple( filter( lambda tomo_obj: ( tomo_obj.stitching_metadata.get_abs_position_px( axis=self._axisEdited ) <= position ) and (tomo_obj is not tomo_obj_to_filter), self.getTomoObjs(), ) ) def _orderedMightHaveChanged(self, force_sb_update=False): # add index widget self._tomoObjsTableView.model().reorder_objs() self._tomoObjsTableView.model().layoutChanged.emit() ordered_objs = self._tomoObjsTableView.model()._axis_decreasing_ordered_objs # start update position widgets # check if we need to update one widget. Has this is designed if we need to update one then we need to update them all... needs_to_update_widget = force_sb_update for i_pos, tomo_obj in enumerate(ordered_objs): identifier_as_str = tomo_obj.get_identifier().to_str() widget = self._tomoObjtoTomoObjPosWidget[identifier_as_str] model_index = self._tomoObjsTableView.model().createIndex(i_pos, 2) if self._tomoObjsTableView.indexWidget(model_index) not in (None, widget): needs_to_update_widget = True break for i_pos, tomo_obj in enumerate(ordered_objs): identifier_as_str = tomo_obj.get_identifier().to_str() widget = self._tomoObjtoTomoObjPosWidget[identifier_as_str] model_index = self._tomoObjsTableView.model().createIndex(i_pos, 2) if needs_to_update_widget: # if items have been reordered then we must recreated `TomoObjPosWidget` otherwise if we try # to change order then Qt will end up with a seg fault which seems to come from # overwriting the cell and trying to reuse them original_value = widget.getOriginalValue() self._deleteTomoObjPosition(tomo_obj=tomo_obj) widget = self._createTomoObjPosition( tomo_obj=tomo_obj, original_value=original_value ) self._tomoObjsTableView.setIndexWidget(model_index, widget) if self.isDisplayingLockInfo(): lock_icon = self._tomoObjToLockInfo.get(identifier_as_str, None) if lock_icon is not None: self._tomoObjsTableView.setIndexWidget( self._tomoObjsTableView.model().createIndex(i_pos, 3), lock_icon ) # expose API def getEditionMode(self) -> _EditionMode: return self._editionOptionsWidget.getEditionMode() def setEditionMode(self, edition_mode: _EditionMode) -> _EditionMode: self._editionOptionsWidget.setEditionMode(edition_mode=edition_mode) class EditableAxisOrderedTomoObjsModel(AxisOrderedTomoObjsModel): def __init__(self, axis: int, parent=None, lock_info: bool = False) -> None: super().__init__(axis, parent) self._headers = ["index", "tomo obj", f"axis {axis} pos (px)"] if lock_info: self._headers.append("relative lock") class _TomoObjPosition(qt.QWidget): """ Widget used to define tomo object position over one axis (and reset if needed) :param original_value: original_value of the tomo_obj along the edited axis. Used when the widget is delete and recreate """ WIDGET_WIDTH = 120 RESET_BUTTON_WIDTH = 25 DEFAULT_VALUE_WHEN_MISSING = 0 sigValueChanged = qt.Signal(int, int) """emit when the value is changed. Parameters are (old value, new value)""" sigEditionAboutToStart = qt.Signal() """Emit when is being edited.""" sigEditionFinished = qt.Signal() """Emit when possible edition is finished.""" def __init__( self, tomo_obj, axis_edited: int, parent: qt.QWidget | None = None, original_value: float | None = None, ) -> None: super().__init__(parent) self.setLayout(qt.QHBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.layout().setSpacing(0) # create spin box object self._spinBox = QSpinBoxWithEditionSignal(self) self._spinBox.setRange( numpy.iinfo(numpy.int32).min, numpy.iinfo(numpy.int32).max ) self._spinBox.setSuffix("px") currentPos = ( tomo_obj.stitching_metadata.get_abs_position_px(axis=axis_edited) or self.DEFAULT_VALUE_WHEN_MISSING ) self.__originalValue = original_value or currentPos self.__lastValue = self.__originalValue self._spinBox.setValue(currentPos) self._spinBox.setFixedWidth(self.WIDGET_WIDTH - self.RESET_BUTTON_WIDTH) self.layout().addWidget(self._spinBox) # create option to reset value self._resetValueQPB = qt.QPushButton(parent=self) self._resetValueQPB.setFixedWidth(self.RESET_BUTTON_WIDTH) style = qt.QApplication.style() resetIcon = style.standardIcon(qt.QStyle.SP_DialogResetButton) self._resetValueQPB.setIcon(resetIcon) self.layout().addWidget(self._resetValueQPB) # connect signal / slot self._spinBox.editingFinished.connect(self._sbEditingFinished) self._spinBox.sigFocusIn.connect(self.sigEditionAboutToStart) self._spinBox.sigFocusOut.connect(self.sigEditionFinished) self._resetValueQPB.clicked.connect(self.resetOriginalValue) def _sbEditingFinished(self): sender = self.sender() assert isinstance(sender, qt.QSpinBox) new_value = sender.value() self._valueChanged(new_value=new_value) def _valueChanged(self, new_value): self.sigValueChanged.emit( self.__lastValue, new_value, ) self.__lastValue = new_value def getOriginalValue(self) -> float: return self.__originalValue def setOriginalValue(self, value: float) -> None: self.__originalValue = value def resetOriginalValue(self) -> None: self._spinBox.setValue(self.getOriginalValue()) self._positionChanged() def _positionChanged(self): self._valueChanged(self._spinBox.value()) def setValue(self, value: float, emit_editing_finished: bool = False) -> None: self._spinBox.setValue(value) if emit_editing_finished: self._spinBox.editingFinished.emit() self.__lastValue = value def getValue(self) -> float: return self._spinBox.value() # expose API def setSingleStep(self, val: int): self._spinBox.setSingleStep(val) class _EditionMode(_Enum): FREE = "free" UPSTREAM = "upstream" DOWNSTREAM = "downstream" @staticmethod def get_icon(cls): if cls == cls.UPSTREAM: return icons.getQIcon("edit_upstream") elif cls == cls.DOWNSTREAM: return icons.getQIcon("edit_downstream") elif cls == cls.FREE: return icons.getQIcon("free_edition") else: raise ValueError() class _EditionOptions(qt.QWidget): sigReset = qt.Signal() sigModeChanged = qt.Signal() def __init__(self, parent=None): super().__init__(parent) self.setLayout(qt.QHBoxLayout()) self._editionModeLabel = qt.QLabel("edition mode", self) self.layout().addWidget(self._editionModeLabel) self._editionModeCB = qt.QComboBox(self) for mode in _EditionMode: self._editionModeCB.addItem( _EditionMode.get_icon(mode), mode.value, ) self.layout().addWidget(self._editionModeCB) self._editionModeCB.setFixedHeight(30) self._spacer = qt.QSpacerItem( 20, 40, qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum ) self.layout().addItem(self._spacer) style = qt.QApplication.style() reset_icon = style.standardIcon(qt.QStyle.SP_DialogResetButton) self._resetButton = qt.QPushButton( parent=self, text="reset all positions", icon=reset_icon ) self._resetButton.setToolTip("reset all position to initial positions") self.layout().addWidget(self._resetButton) # connect signal / slot self._editionModeCB.currentIndexChanged.connect(self.sigModeChanged) self._resetButton.released.connect(self.sigReset) def getEditionMode(self) -> _EditionMode: return _EditionMode(self._editionModeCB.currentText()) def setEditionMode(self, edition_mode: _EditionMode | str): self._editionModeCB.setCurrentText(_EditionMode(edition_mode).value) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/gui/stitching/config/stitchingstrategies.py0000644000175000017500000001070715115744275025033 0ustar00paynopaynofrom __future__ import annotations from tomwer.io.utils.utils import str_to_dict from nabu.stitching import config as stitching_config from nabu.stitching.overlap import OverlapStitchingStrategy from silx.gui import qt from tomwer.gui.utils.scrollarea import QComboBoxIgnoreWheel as QComboBox from tomwer.gui.utils.scrollarea import QSpinBoxIgnoreWheel as QSpinBox from ..singleaxis import _SingleAxisMixIn class _StitchingHeightSpinBox(qt.QWidget): def __init__(self, parent=None) -> None: super().__init__(parent) self.setLayout(qt.QHBoxLayout()) self._autoCB = qt.QCheckBox("max", self) self.layout().addWidget(self._autoCB) self._stitchingHeight = QSpinBox(self) self._stitchingHeight.setMinimum(3) self._stitchingHeight.setMaximum(999999) self._stitchingHeight.setValue(40) self._stitchingHeight.setSuffix("px") self.layout().addWidget(self._stitchingHeight) self._autoCB.toggled.connect(self._stitchingHeight.setDisabled) def getStitchingHeight(self) -> int | None: if self._autoCB.isChecked(): return None else: return self._stitchingHeight.value() def setStitchingHeight(self, height: int | None) -> None: self._autoCB.setChecked(height is None) if height is not None: self._stitchingHeight.setValue(int(height)) class StitchingStrategies(qt.QWidget, _SingleAxisMixIn): """ Defines algorithm and strategies to be used """ DEFAULT_STITCHING_HEIGHT = None # max value is the default sigChanged = qt.Signal() """emit when strategy change""" def __init__(self, axis: int, parent=None) -> None: super().__init__(parent) self.setLayout(qt.QFormLayout()) self._stitchingStrategyCG = QComboBox(parent=self) for strategy in OverlapStitchingStrategy: self._stitchingStrategyCG.addItem(strategy.value) self._stitchingStrategyCG.setToolTip( "stitcher behavior is also know as stitching strategy. It define the behavior to have on overlaping areas" ) self.layout().addRow("stitcher behavior", self._stitchingStrategyCG) self._axis = axis # needed to implement the _SingleAxisMixIn interface self._stitchingHeight = _StitchingHeightSpinBox(parent=self) self._stitchingHeight.setStitchingHeight(self.DEFAULT_STITCHING_HEIGHT) self.layout().addRow("stitching height", self._stitchingHeight) # set up idx = self._stitchingStrategyCG.findText( OverlapStitchingStrategy.COSINUS_WEIGHTS.value ) self._stitchingStrategyCG.setCurrentIndex(idx) # connect signal / slot self._stitchingStrategyCG.currentIndexChanged.connect(self._changed) def _changed(self, *args, **kwargs): self.sigChanged.emit() def getStitchingStrategy(self) -> OverlapStitchingStrategy: return OverlapStitchingStrategy(self._stitchingStrategyCG.currentText()) def setStitchingStrategy(self, strategy: OverlapStitchingStrategy | str): strategy = OverlapStitchingStrategy(strategy) idx = self._stitchingStrategyCG.findText(strategy.value) if idx >= 0: self._stitchingStrategyCG.setCurrentIndex(idx) def getConfiguration(self) -> dict: overlap_size = self._stitchingHeight.getStitchingHeight() if overlap_size is None: overlap_size = "" return { stitching_config.STITCHING_SECTION: { stitching_config.STITCHING_STRATEGY_FIELD: self.getStitchingStrategy().value, f"axis_{self.first_axis}_params": f"overlap_size={overlap_size}", } } def setConfiguration(self, config: dict): strategy = config.get(stitching_config.STITCHING_SECTION, {}).get( stitching_config.STITCHING_SECTION, None ) if strategy is not None: self.setStitchingStrategy(strategy=strategy) first_axis_params_dict = str_to_dict( config.get(stitching_config.STITCHING_SECTION, {}).get( f"axis_{self._axis}_params", "" ) ) stitching_height = first_axis_params_dict.get( stitching_config.KEY_OVERLAP_SIZE, "unknown" ) if stitching_height in ("None", "", None): self._stitchingHeight.setStitchingHeight(None) elif stitching_height != "unknown": self._stitchingHeight.setStitchingHeight(stitching_height) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9451017 tomwer-1.6.17/src/tomwer/gui/stitching/config/tests/0000755000175000017500000000000015153325403021515 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771225048.0 tomwer-1.6.17/src/tomwer/gui/stitching/config/tests/test_axisparams.py0000644000175000017500000000133615144537730025311 0ustar00paynopaynoimport pytest from tomwer.gui.stitching.config.axisparams import StitcherAxisParams from tomwer.tests.conftest import qtapp # noqa F401 def test_StitcherAxisParams( qtapp, # noqa F811 ): """test the StitcherAxisParams widget""" with pytest.raises(TypeError): widget = StitcherAxisParams(axis="toto") widget = StitcherAxisParams(axis=0) assert widget.getConfiguration() == { "stitching": { "axis_0_params": "img_reg_method=None;window_size=400", } } new_config = { "stitching": { "axis_0_params": "img_reg_method=skimage;window_size=50", }, } widget.setConfiguration(new_config) assert widget.getConfiguration() == new_config ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/stitching/config/tomoobjdetails.py0000644000175000017500000003524515153325210023751 0ustar00paynopaynofrom __future__ import annotations import pint from nabu.stitching.config import StitchingType from silx.gui import qt from silx.gui.utils import blockSignals from tomoscan.scanbase import TomoScanBase from tomwer.core.process.stitching.metadataholder import StitchingMetadata from tomwer.gui.utils.qt_utils import block_signals from tomwer.gui.stitching.metadataholder import QStitchingMetadata from tomwer.gui.utils.unitsystem import MetricEntry, PixelEntry _ureg = pint.get_application_registry() class _AxisPositionGroup(qt.QGroupBox): sigUpdate = qt.Signal() """Signal emit when some data have been updated""" def __init__(self, axis: int, parent=None): assert axis in (0, 1, 2) super().__init__(title=f"axis {axis}", parent=parent) self.__axis = axis self._stitching_metadata = None self.setLayout(qt.QGridLayout()) # pixel size self._pixelSizeRaw = MetricEntry( value="unknown", name="pixel size", parent=self, default_unit=_ureg.millimeter, ) self._pixelSizeRaw.setReadOnly(True) self.layout().addWidget(self._pixelSizeRaw, 0, 0, 1, 2) self._overridePixelSizeCB = qt.QCheckBox("overwrite", self) self.layout().addWidget(self._overridePixelSizeCB, 0, 2, 1, 1) self._pixelSizeOverride = MetricEntry( name="", parent=self, default_unit=_ureg.millimeter ) self.layout().addWidget(self._pixelSizeOverride, 0, 3, 1, 2) # raw position (in meter or millimeter) self._rawPositionMetric = MetricEntry( value="unknown", name=f"axis {axis} position (metric unit)", parent=self, default_unit=_ureg.millimeter, ) self._rawPositionMetric.setReadOnly(True) self.layout().addWidget(self._rawPositionMetric, 1, 0, 1, 2) self._overrideMetricPositionCB = qt.QCheckBox("overwrite", self) self.layout().addWidget(self._overrideMetricPositionCB, 1, 2, 1, 1) self._metricPositionOverride = MetricEntry( name="", parent=self, default_unit=_ureg.millimeter ) self.layout().addWidget(self._metricPositionOverride, 1, 3, 1, 2) # raw position in pixel ... self._rawPxPosition = PixelEntry(name=f"axis {axis} position (pixel unit)") self._rawPxPosition.setReadOnly(True) self.layout().addWidget(self._rawPxPosition, 2, 0, 1, 2) self._overridePixelPositionCB = qt.QCheckBox("overwrite", self) self.layout().addWidget(self._overridePixelPositionCB, 2, 2, 1, 1) self._overridePxPosition = PixelEntry( name="", parent=self, ) self.layout().addWidget(self._overridePxPosition, 2, 3, 1, 2) # utils to filter signals self._editingWidgets = ( self._pixelSizeRaw, self._pixelSizeOverride, self._overridePixelPositionCB, self._overridePixelSizeCB, self._overrideMetricPositionCB, self._metricPositionOverride, self._rawPositionMetric, self._rawPxPosition, self._overridePxPosition, ) # set up self._metricPositionOverride.setVisible(False) self._overridePxPosition.setVisible(False) self._pixelSizeOverride.setVisible(False) # connect signal / slot self._overrideMetricPositionCB.toggled.connect( self._metricPositionOverride.setVisible ) self._overridePixelPositionCB.toggled.connect( self._overridePxPosition.setVisible ) self._overridePixelSizeCB.toggled.connect(self._pixelSizeOverride.setVisible) self._overrideMetricPositionCB.toggled.connect(self._changed) self._overridePixelPositionCB.toggled.connect(self._changed) self._overridePixelSizeCB.toggled.connect(self._changed) self._metricPositionOverride.valueChanged.connect(self._changed) self._overridePxPosition.valueChanged.connect(self._changed) self._pixelSizeOverride.valueChanged.connect(self._changed) def _changed(self, *args, **kwargs): self._updateFinalPxPosition() self._updateTomoObjMetadata() def _updateTomoObjMetadata(self): # update the tomo obj metadata if self._stitching_metadata is not None: # disconnect the metadata signal to avoid sending several update message self._stitching_metadata.sigChanged.disconnect(self._loadMetadata) with blockSignals(self._stitching_metadata): self._stitching_metadata.setPixelOrVoxelSize( value=self.getOverrridePixelSize(), axis=self.axis ) metric_quantity = self.getOverrrideMetricPosition() if isinstance(metric_quantity, pint.Quantity): metric_quantity = metric_quantity.to_base_units().magnitude self._stitching_metadata.setMetricPos(metric_quantity, axis=self.axis) self._stitching_metadata.setPxPos( self.getOverrridePxPosition(), axis=self.axis ) # make sure the signal of the tomo obj has been send (but this widget is not interested because # we did the update according to the widget.) self._stitching_metadata.sigChanged.emit() self._stitching_metadata.sigChanged.connect(self._loadMetadata) def _updateFinalPxPosition(self): # compute the final position if self._overridePixelPositionCB.isChecked(): # if the pixel size is directly edited then ignore this one return None pixel_size_m = self.get_final_pixel_size() if pixel_size_m is None: return None position_m = self.get_final_metric_position() if position_m is None: return None position_px = int(position_m / pixel_size_m) self._rawPxPosition.setValue(position_px) @property def axis(self) -> int: return self.__axis def get_final_metric_position(self): """ return the metric position to be used to compute the final pixel position """ if self._overrideMetricPositionCB.isChecked(): return self._metricPositionOverride.getValue() else: return self._overridePxPosition.getValue() def get_final_px_position(self): """ return the pixel position to be used for stitching """ if self._overridePixelPositionCB.isChecked(): return self.getOverrridePxPosition() else: return self.getRawPxPosition() def get_final_pixel_size(self): if self._overridePixelPositionCB.isChecked(): return self._pixelSizeOverride.getValue() else: return self._pixelSizeRaw.getValue() def setStitchingMetadata(self, stitching_metadata: QStitchingMetadata | None): """ load used metadata from tomo_obj """ if self._stitching_metadata is not None: self._stitching_metadata.sigChanged.disconnect(self._loadMetadata) # remove metadata because we are no more editing those self._stitching_metadata = None self.reset() self._stitching_metadata = stitching_metadata if self._stitching_metadata is not None: self._stitching_metadata.sigChanged.connect(self._loadMetadata) self._loadMetadata() def _loadMetadata(self): stitching_metadata = self._stitching_metadata tomo_obj = self._stitching_metadata.tomo_obj assert stitching_metadata is not None, "expects to have metadata" if isinstance(tomo_obj, TomoScanBase): # tODO: block all editor signal with blockSignals(*self._editingWidgets): # handle pixel size if self.axis == 0: pixel_size = tomo_obj.sample_y_pixel_size else: pixel_size = tomo_obj.sample_x_pixel_size if pixel_size is not None: self.setRawPixelSize(pixel_size) override_pixel_size = stitching_metadata._pixel_or_voxel_size[self.axis] self._overridePixelSizeCB.setChecked(override_pixel_size is not None) if override_pixel_size is not None: self.setOverrridePixelSize(override_pixel_size) # handle position in metric unit try: raw_position_m = stitching_metadata.get_raw_position_m( axis=self.axis ) except Exception: raw_position_m = None if raw_position_m is not None: self.setRawMetricPosition(position_m=raw_position_m) override_position_m = stitching_metadata._pos_as_m[self.axis] self._overrideMetricPositionCB.setChecked( override_position_m is not None ) if override_position_m is not None: self.setOverrrideMetricPosition(position_m=override_position_m) # handle position in pixel l_pixel_size = override_pixel_size or pixel_size if raw_position_m is not None: self.setRawPxPosition(int(raw_position_m / l_pixel_size)) override_position_px = stitching_metadata._pos_as_px[self.axis] self._overridePixelPositionCB.setChecked( override_position_px is not None ) if override_position_px is not None: self.setOverrridePxPosition(override_position_px) else: raise NotImplementedError( "loading volume metadata not handled for the moment" ) def reset(self): self._rawPositionMetric.setValue("unknown") self._overrideMetricPositionCB.setChecked(False) self._rawPxPosition.setValue("unknown") self._overrideMetricPositionCB.setChecked(False) self._pixelSizeRaw.setValue("unknown") self._overridePixelSizeCB.setChecked(False) def getRawPxPosition(self): return self._rawPxPosition.getValue() def setRawPxPosition(self, position_px): self._rawPxPosition.setValue(position_px) def getOverrridePxPosition(self): if self._overridePixelPositionCB.isChecked(): return self._overridePxPosition.getValue() else: return None def setOverrridePxPosition(self, position_px): if not self._overridePixelPositionCB.isChecked(): with block_signals(self._overridePixelPositionCB): # avoid updating twice the stitching metadata value self._overridePixelPositionCB.setChecked(True) self._overridePxPosition.setValue(position_px) self._overridePxPosition.valueChanged.emit() def getOverrrideMetricPosition(self) -> pint.Quantity: if self._overrideMetricPositionCB.isChecked(): return self._metricPositionOverride.getValue() else: return None def setOverrrideMetricPosition(self, position_m): if not self._overrideMetricPositionCB.isChecked(): with block_signals(self._overrideMetricPositionCB): # avoid updating twice the stitching metadata value self._overrideMetricPositionCB.setChecked(True) self._metricPositionOverride.setValue(position_m) self._metricPositionOverride.valueChanged.emit() def getRawMetricPosition(self): return self._rawPositionMetric.getValue() def setRawMetricPosition(self, position_m, displayed_unit=_ureg.millimeter): self._rawPositionMetric.setValue( value_m=position_m, displayed_unit=displayed_unit ) def getRawPixelSize(self): return self._pixelSizeRaw.getValue() def setRawPixelSize(self, pixel_size): self._pixelSizeRaw.setValue(pixel_size) def getOverrridePixelSize(self): if self._overridePixelSizeCB.isChecked(): return self._pixelSizeOverride.getValue() else: return None def setOverrridePixelSize(self, pixel_size): if not self._overridePixelSizeCB.isChecked(): with block_signals(self._overridePixelSizeCB): # avoid updating twice the stitching metadata value self._overridePixelSizeCB.setChecked(True) self._pixelSizeOverride.setValue(pixel_size) self._pixelSizeOverride.valueChanged.emit() class TomoObjectPositionInfos(qt.QWidget): """ Widget to define the TomoObject (scan or volume) position """ def __init__(self, parent=None, stitching_metadata: StitchingMetadata = None): super().__init__(parent=parent) self._stitching_metadata = None self.setLayout(qt.QGridLayout()) # axis 0 group self._axis_0_pos = _AxisPositionGroup(axis=0, parent=self) self.layout().addWidget(self._axis_0_pos, 1, 0, 1, 5) # axis 2 group self._axis_2_pos = _AxisPositionGroup(axis=2, parent=self) self.layout().addWidget(self._axis_2_pos, 2, 0, 1, 5) # spacer for style self._spacer = qt.QWidget(parent=self) self._spacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding) self.layout().addWidget(self._spacer, 99, 99, 1, 1) # set up self.setStitchingMetadata(stitching_metadata) def getStitchingMetadata(self): return self._stitching_metadata def reset(self): self._axis_0_pos.reset() self._axis_2_pos.reset() def clean(self): self.reset() self._stitching_metadata = None def setStitchingMetadata(self, stitching_metadata: StitchingMetadata | None = None): if stitching_metadata is not None and not isinstance( stitching_metadata, StitchingMetadata ): raise TypeError( "stitching_metadata is expected to be an instance of {StitchingMetadata}" ) else: self._stitching_metadata = stitching_metadata self._loadMetadata(stitching_metadata) def _loadMetadata(self, metadata: StitchingMetadata): self._axis_0_pos.setStitchingMetadata(metadata) self._axis_2_pos.setStitchingMetadata(metadata) def updateStitchingType(self, stitching_type: StitchingType): stitching_type = StitchingType(stitching_type) if stitching_type is StitchingType.Z_POSTPROC: pixel_or_voxel_label = "voxel size" elif stitching_type is StitchingType.Z_PREPROC: pixel_or_voxel_label = "pixel size" else: raise NotImplementedError self._axis_0_pos._pixelSizeRaw.setLabelText(pixel_or_voxel_label) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/stitching/metadataholder.py0000644000175000017500000000162115153325210022432 0ustar00paynopaynofrom silx.gui import qt from tomwer.core.process.stitching.metadataholder import ( StitchingMetadata as _StitchingMetadata, ) class QStitchingMetadata(qt.QObject, _StitchingMetadata): """ overload of a TomoObject to register metadata set by the user on positions """ sigChanged = qt.Signal() """ emit when some parameter changed """ def __init__(self, parent=None, tomo_obj=None) -> None: super().__init__(parent) _StitchingMetadata.__init__(self=self, tomo_obj=tomo_obj) def setPixelOrVoxelSize(self, value, axis): super().setPixelOrVoxelSize(value=value, axis=axis) self.sigChanged.emit() def setPxPos(self, value, axis): super().setPxPos(value=value, axis=axis) self.sigChanged.emit() def setMetricPos(self, value, axis): super().setMetricPos(value=value, axis=axis) self.sigChanged.emit() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/stitching/normalization.py0000644000175000017500000001060015153325210022337 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from nabu.stitching.sample_normalization import ( SampleSide as _SampleSide, Method as _SampleNormalizationMethod, ) from nabu.stitching import config as _config_stitching from tomwer.gui.utils.qt_utils import block_signals class NormalizationBySampleGroupBox(qt.QGroupBox): """ Widget to define the normalization to apply to frames""" sigConfigChanged = qt.Signal() """Emit when the configuration is changed""" def __init__(self, title: str = "normalization by sample", parent=None): # FIXME: add a way to the user for requesting a view of the region picked ??? super().__init__(title, parent) self.setCheckable(True) self.setLayout(qt.QFormLayout()) # method self._methodCB = qt.QComboBox(self) self._methodCB.addItems([item.value for item in _SampleNormalizationMethod]) self._methodCB.setCurrentText(_SampleNormalizationMethod.MEDIAN.value) self.layout().addRow("method", self._methodCB) # side self._sideCB = qt.QComboBox(self) self._sideCB.addItems([item.value for item in _SampleSide]) self._sideCB.setCurrentText(_SampleSide.LEFT.value) self.layout().addRow("sampling side", self._sideCB) # width self._widthSB = qt.QSpinBox(self) self._widthSB.setRange(1, 9999999) self._widthSB.setValue(30) self._widthSB.setSingleStep(10) self._widthSB.setSuffix("px") self.layout().addRow("sampling width", self._widthSB) # margin self._marginSB = qt.QSpinBox(self) self._marginSB.setRange(0, 999999) self._marginSB.setValue(0) self.layout().addRow("sampling margin", self._marginSB) # connect signal / slot self._methodCB.currentIndexChanged.connect(self._configChanged) self._sideCB.currentIndexChanged.connect(self._configChanged) self._widthSB.valueChanged.connect(self._configChanged) self._marginSB.valueChanged.connect(self._configChanged) def _configChanged(self, *args, **kwargs): self.sigConfigChanged.emit() def getMethod(self) -> _SampleNormalizationMethod: return _SampleNormalizationMethod(self._methodCB.currentText()) def setMethod(self, method: _SampleNormalizationMethod | str): method = _SampleNormalizationMethod(method) self._methodCB.setCurrentText(method.value) def getSide(self) -> _SampleSide: return _SampleSide(self._sideCB.currentText()) def setSide(self, side: _SampleSide): side = _SampleSide(side) self._sideCB.setCurrentText(side.value) def getMargin(self) -> int: return self._marginSB.value() def setMargin(self, margin: int): self._marginSB.setValue(int(margin)) def getWidth(self) -> int: return self._widthSB.value() def setWidth(self, width: int): self._widthSB.setValue(int(width)) def getConfiguration(self) -> dict: return { _config_stitching.NORMALIZATION_BY_SAMPLE_ACTIVE_FIELD: self.isChecked(), _config_stitching.NORMALIZATION_BY_SAMPLE_METHOD: self.getMethod().value, _config_stitching.NORMALIZATION_BY_SAMPLE_SIDE: self.getSide().value, _config_stitching.NORMALIZATION_BY_SAMPLE_MARGIN: self.getMargin(), _config_stitching.NORMALIZATION_BY_SAMPLE_WIDTH: self.getWidth(), } def setConfiguration(self, config: dict) -> None: with block_signals(self): method = config.get(_config_stitching.NORMALIZATION_BY_SAMPLE_METHOD, None) if method is not None: self.setMethod(method=method) side = config.get(_config_stitching.NORMALIZATION_BY_SAMPLE_SIDE, None) if side is not None: self.setSide(side=side) margin = config.get(_config_stitching.NORMALIZATION_BY_SAMPLE_MARGIN, None) if margin is not None: self.setMargin(margin=margin) width = config.get(_config_stitching.NORMALIZATION_BY_SAMPLE_WIDTH, None) if width is not None: self.setWidth(width=width) active = config.get( _config_stitching.NORMALIZATION_BY_SAMPLE_ACTIVE_FIELD, None ) if active is not None: self.setChecked(active in (True, 1, "1", "True")) self._configChanged() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/stitching/preview.py0000644000175000017500000000436414757047403021162 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from nabu.stitching.config import dict_to_config_obj from nabu.stitching.stitcher.z_stitcher import ( PreProcessingZStitcher, PostProcessingZStitcher, ) from nabu.stitching.stitcher.y_stitcher import PreProcessingYStitcher class PreviewThread(qt.QThread): """ Thread to compute an overview of the stitching """ def __init__(self, stitching_config: dict, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self._stitching_config = dict_to_config_obj(stitching_config) self._output_identifier = None self._frame_composition = None self._final_tomo_objs_positions = None # store position of all the tomo objects (scan, volumes) used for the final stitching (after shift refinement) @property def stitching_config(self): return self._stitching_config @property def output_identifier(self): return self._output_identifier @property def frame_composition(self): return self._frame_composition @property def final_tomo_objs_positions(self) -> dict: """ :return: dict with tomo object identifier (str) as key and a tuple of position in pixel (axis_0_pos, axis_1_pos, axis_2_pos) """ return self._final_tomo_objs_positions def run(self): stitching_type = self.stitching_config.stitching_type if stitching_type.value == "z-preproc": stitcher = PreProcessingZStitcher(configuration=self.stitching_config) elif stitching_type.value == "z-postproc": stitcher = PostProcessingZStitcher(configuration=self.stitching_config) elif stitching_type.value == "y-preproc": stitcher = PreProcessingYStitcher(configuration=self.stitching_config) else: raise NotImplementedError self._output_identifier = stitcher.stitch() if self._output_identifier is not None: self._output_identifier = self._output_identifier.to_str() # store in cache the frame composition to be able to provide them to the PreviewPlot self._frame_composition = stitcher.frame_composition self._final_tomo_objs_positions = stitcher.get_final_axis_positions_in_px() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/stitching/singleaxis.py0000644000175000017500000000321214757047403021636 0ustar00paynopayno"""Define Interface for widget handling stitching over one axis""" from __future__ import annotations from silx.gui import qt class _SingleAxisMixIn: """Common API for widget able to handle stitching over one axis (no matter if it is 0, 1, 2 (aka z, y, x))""" @property def first_axis(self) -> int: """ Axis along which stitching is done. For stitching along z will return 0... """ return self._axis @property def second_axis(self) -> int: """ second axis involved in the stitching. In case of stitching along axis 0 the axis 1can also be involved (axis present in the camera reference) """ if self._axis == 0: return 1 elif self._axis == 1: return 0 else: raise NotImplementedError @property def third_axis(self): all_axis = {(0, 1, 2)} all_axis.remove(self.first_axis) all_axis.remove(self.second_axis) return all_axis.pop() @staticmethod def axis_alias(axis: int): if axis == 0: return "z" elif axis == 1: return "y" elif axis == 2: return "z" else: raise ValueError(f"axis should be in (0, 1, 2). {axis} given") class SingleAxisMetaClass(type(qt.QMainWindow), type(_SingleAxisMixIn)): """ Metaclass for single axis stitcher in order to aggregate dumper class and axis """ def __new__(mcls, name, bases, attrs, axis: int | None = None): mcls = super().__new__(mcls, name, bases, attrs) mcls._axis = axis # used from _SingleAxisMixIn interface return mcls ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/stitching/stitchandbackground.py0000644000175000017500000001353615143647637023530 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from silx.gui.colors import Colormap from tomwer.gui import icons as tomwer_icons from tomwer.core.utils.char import ALPHA_CHAR class AlphaChannelWidget(qt.QWidget): """ Widget to select alpha level of the stiched image and of the background """ sigAlphaImgChanged = qt.Signal() """signal emit when the alpha of the stitched image changed""" sigAlphaBackgroundChanged = qt.Signal() """signal emit when the alpha of the background image changed""" def __init__(self, parent=None, *args, **kwargs) -> None: super().__init__(parent, *args, **kwargs) self.setLayout(qt.QFormLayout()) self._alphaImgSlider = qt.QSlider(qt.Qt.Horizontal, self) self._alphaImgSlider.setMinimumWidth(40) self._alphaImgSlider.setRange(0, 100) self.layout().addRow(f"{ALPHA_CHAR} image", self._alphaImgSlider) self._alphaBackgroundSlider = qt.QSlider(qt.Qt.Horizontal, self) self._alphaBackgroundSlider.setMinimumWidth(40) self._alphaBackgroundSlider.setRange(0, 100) self.layout().addRow(f"{ALPHA_CHAR} overlay", self._alphaBackgroundSlider) # connect signal / slot self._alphaImgSlider.valueChanged.connect(self._alphaImgchanged) self._alphaBackgroundSlider.valueChanged.connect(self._alphaBackgroundchanged) def _alphaImgchanged(self, *args, **kwargs): self.sigAlphaImgChanged.emit() def _alphaBackgroundchanged(self, *args, **kwargs): self.sigAlphaBackgroundChanged.emit() def setAlphaStitchedImg(self, alpha: float): self._alphaImgSlider.setValue(int(alpha * 100.0)) def getAlphaStitchedImg(self) -> float: return self._alphaImgSlider.value() / 100.0 def setAlphaBackgroundImg(self, alpha: float): self._alphaBackgroundSlider.setValue(int(alpha * 100.0)) def getAlphaBackgroundImg(self) -> float: return self._alphaBackgroundSlider.value() / 100.0 class StitchAndBackgroundAlphaMixIn: """ Mix in class for windows displaying a stitched image with or without the background """ LEGEND_STITCHED_FRAME = "stitched frame" LEGEND_BACKGROUND = "background" def __init__(self) -> None: self._stitched_image = None self._composition_background = None # background action to show / hide the backgrounds self._backGroundAction = qt.QAction("overlay", self) self._backGroundAction.setToolTip("Toggle overlay on top of image") self._backGroundAction.setCheckable(True) save_icon = tomwer_icons.getQIcon("background") self._backGroundAction.setIcon(save_icon) self.__firstPlot = True self._backgroundColormap = Colormap(name="viridis") # build self._alphaChannelWidget = AlphaChannelWidget(parent=self) # connect signal / slot self._backGroundAction.toggled.connect(self._update) self._alphaChannelWidget.sigAlphaImgChanged.connect(self._updateAlphaImg) self._alphaChannelWidget.sigAlphaBackgroundChanged.connect( self._updateAlphaBackgroundImg ) def getStitchedImgAlpha(self) -> float: """ :return: alpha value to set to the stitched image. If only the image is displayed then will be 1.0 else will be the value defined by the "alpha channel' widget """ if self._backGroundAction.isChecked(): return self._alphaChannelWidget.getAlphaStitchedImg() else: return 1.0 def getBackgroundImgAlpha(self) -> float | None: """return 0.0 if there is no background image""" if self._backGroundAction.isChecked(): return self._alphaChannelWidget.getAlphaBackgroundImg() else: return 0.0 def _updateAlphaImg(self, *args, **kwargs): alpha_img = self.getImage(self.LEGEND_STITCHED_FRAME) if alpha_img is not None: alpha_img.setAlpha(self.getStitchedImgAlpha()) def _updateAlphaBackgroundImg(self, *args, **kwargs): background_img = self.getImage(self.LEGEND_BACKGROUND) if background_img is not None: background_img.setAlpha(self.getBackgroundImgAlpha()) def _update(self): """ update display. Allow to handle modification of alpha values and to dsiplay or not the background / composition """ if self._stitched_image is None: return if self._backGroundAction.isChecked(): self.addImage( self._stitched_image, legend=self.LEGEND_STITCHED_FRAME, resetzoom=self.__firstPlot, ) image_data = self.getImage(legend=self.LEGEND_STITCHED_FRAME) image_data.setAlpha(self.getStitchedImgAlpha()) self.addImage( self._composition_background, legend=self.LEGEND_BACKGROUND, resetzoom=self.__firstPlot, colormap=self._backgroundColormap, ) background_data = self.getImage(legend=self.LEGEND_BACKGROUND) background_data.setAlpha(self.getBackgroundImgAlpha()) else: if self.getImage(self.LEGEND_BACKGROUND) is not None: self.removeImage(self.LEGEND_BACKGROUND) self.addImage( self._stitched_image, legend=self.LEGEND_STITCHED_FRAME, resetzoom=self.__firstPlot, ) background_data = self.getImage(legend=self.LEGEND_STITCHED_FRAME) background_data.setAlpha(self.getStitchedImgAlpha()) self.setActiveImage(legend=self.LEGEND_STITCHED_FRAME) self.__firstPlot = False # expose API def setAlphaBackgroundImg(self, value): self._alphaChannelWidget.setAlphaBackgroundImg(value) def setAlphaStitchedImg(self, value): self._alphaChannelWidget.setAlphaStitchedImg(value) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/stitching/stitching_preview.py0000644000175000017500000002326315153325210023217 0ustar00paynopaynofrom __future__ import annotations import logging import numpy try: # nabu 2024 from nabu.stitching.frame_composition import ZFrameComposition as FrameComposition except ImportError: from nabu.stitching.frame_composition import FrameComposition from silx.gui import qt from tomwer.gui.utils.buttons import TapeMeasureToolButton from tomoscan.esrf.scan.utils import get_data from tomoscan.identifier import BaseIdentifier from tomoscan.scanbase import TomoScanBase from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.volume.volumefactory import VolumeFactory from tomwer.gui import icons as tomwer_icons from tomwer.gui import settings from tomwer.gui.stitching.stitchandbackground import StitchAndBackgroundAlphaMixIn from silx.gui.plot import Plot2D, items from silx.gui.widgets.WaitingOverlay import WaitingOverlay _logger = logging.getLogger(__name__) class _PreviewPlot2D(Plot2D): """simple inheritance to get data from the 'stitched image' instead of the 'background / overlay' image""" def _getImageValue(self, x, y): pickedMask = None for picked in self.pickItems( *self.dataToPixel(x, y, check=False), lambda item: isinstance(item, items.ImageBase), ): if isinstance(picked.getItem(), items.MaskImageData): if pickedMask is None: # Use top-most if many masks pickedMask = picked else: # we want to avoid displaying the value of the background image. So just ignore it. # TODO: see with Thomas if there is a better way to do this. # like starting by the active image ? image = picked.getItem() if image.getLegend() == StitchAndBackgroundAlphaMixIn.LEGEND_BACKGROUND: continue indices = picked.getIndices(copy=False) if indices is not None: row, col = indices[0][0], indices[1][0] value = image.getData(copy=False)[row, col] if pickedMask is not None: # Check if masked maskItem = pickedMask.getItem() indices = pickedMask.getIndices() row, col = indices[0][0], indices[1][0] if maskItem.getData(copy=False)[row, col] != 0: return value, "Masked" return value return "-" # No image picked class PreviewStitchingPlot(Plot2D, StitchAndBackgroundAlphaMixIn): DEFAULT_STITCHED_IMG_ALPHA = 0.95 DEFAULT_BACKGROUND_IMG_ALPHA = 0.20 def __init__(self, axis: int, parent=None) -> None: super().__init__(parent=parent) # pylint: disable=E1123 self._waitingOverlay = WaitingOverlay(self) self._waitingOverlay.setIconSize(qt.QSize(30, 30)) self._stitched_image = None self._composition_background = None self._axis = axis # tune plot self.setYAxisInverted(settings.Y_AXIS_DOWNWARD) # by default we want to have a full screen display self.setAxesDisplayed(False) # add an action to plot the url-image 'full size' fullScreenIcon = tomwer_icons.getQIcon("full_screen") self._fullScreenAction = qt.QAction(fullScreenIcon, "pop up full screen") self.toolBar().addAction(self._fullScreenAction) self._fullScreenAction.triggered.connect(self._popCurrentImageFullScreen) self.setKeepDataAspectRatio(True) self.getColorBarWidget().hide() # tape measure action self._tapeMeasureButton = TapeMeasureToolButton(parent=self, plot=self) self._tapeMeasureButton.setCheckable(True) self.toolBar().addWidget(self._tapeMeasureButton) # removing some plot action to clear toolbar self.getMaskAction().setVisible(False) self.getCopyAction().setVisible(False) # background action self._backgroundToolbar = qt.QToolBar("background") self.addToolBar(self._backgroundToolbar) self._backgroundToolbar.addAction(self._backGroundAction) # alpha channel widget self._backgroundToolbar.addWidget(self._alphaChannelWidget) # set up self.setAlphaBackgroundImg(value=self.DEFAULT_BACKGROUND_IMG_ALPHA) self.setAlphaStitchedImg(value=self.DEFAULT_STITCHED_IMG_ALPHA) self._waitingOverlay.hide() # connect signal / slot self._backGroundAction.toggled.connect(self._update) @property def axis(self) -> int: return self._axis def _popCurrentImageFullScreen(self): from tomwer.gui.visualization.fullscreenplot import FullScreenStitching new_plot = FullScreenStitching( stitching_img=self._stitched_image, background_img=self._composition_background, ) # update alpha values with the current one new_plot.setAlphaBackgroundImg(self.getBackgroundImgAlpha()) new_plot.setAlphaStitchedImg(self.getStitchedImgAlpha()) new_plot.setWindowTitle("Stitching") # reuse the same colormap for convenience (user modification on it will be applied everywhere) new_plot.setDefaultColormap(self.getDefaultColormap()) new_plot.showFullScreen() def setComposition(self, composition: dict, shape: tuple, update=True): self._composition_background = self.buildCompositionBackground( composition, shape=shape, axis=self.axis, ) if update: self._updatePlot() @staticmethod def buildCompositionBackground(composition, shape: tuple, axis: int): assert axis in (0, 1, 2) if "raw_composition" not in composition: raise KeyError( "composition is expected to have a 'raw_composition' key with {FrameComposition} describing raw composition as key" ) else: raw_composition = composition["raw_composition"] assert isinstance(raw_composition, FrameComposition) if "overlap_composition" not in composition: raise KeyError( "composition is expected to have a 'overlap_composition' key with {FrameComposition} describing overlap composition as key" ) else: overlap_composition = composition["overlap_composition"] assert isinstance(overlap_composition, FrameComposition) background = numpy.zeros( shape=shape, ) assert background.ndim == 3 def get_next_color(): yellow = qt.QColor(qt.Qt.yellow) magenta = qt.QColor(qt.Qt.magenta) blue = qt.QColor(qt.Qt.blue) while True: yield yellow.red(), yellow.green(), yellow.blue(), 255 yield magenta.red(), magenta.green(), magenta.blue(), 255 yield blue.red(), blue.green(), blue.blue(), 255 # composition is always done along y (in image space). So for stitching along y (in nxtomo space) we need to flip the two axis to apply the composition colors_raw_frames = [] for _, color in zip(raw_composition.local_end, get_next_color()): colored_frame = numpy.full( shape=shape, fill_value=color, ) colors_raw_frames.append(colored_frame) overlap_composition.compose( background, colors_raw_frames, ) return background def setStitchedTomoObj(self, tomo_obj_id: BaseIdentifier | str, composition: dict): """ :param tomo_obj_id: identifier of the stitched object (scan of volume) :param composition: composition used to create the stitched object """ if not isinstance(tomo_obj_id, (BaseIdentifier, str)): raise TypeError( f"stitched_scan is expected to be an instance of {TomoScanBase}" ) scan = None volume = None try: scan = ScanFactory.create_tomo_object_from_identifier(tomo_obj_id) except Exception: try: volume = VolumeFactory.create_tomo_object_from_identifier(tomo_obj_id) except Exception: pass else: pass if scan is not None: if scan.projections is None or len(scan.projections) == 0: _logger.error( f"stitched scan {tomo_obj_id} doesn't contains any projections" ) return if not len(scan.projections) == 1: _logger.warning( f"stitched scan preview is expected to have a single project. Get {len(scan.projections)}. Will display the first one" ) first_proj_url = next(iter(scan.projections.items()))[1] self._stitched_image = get_data(first_proj_url) elif volume is not None: volume.load_data() assert volume.data.ndim == 3 self._stitched_image = volume.data[:, 0, :] else: _logger.error(f"Fail to load stitched object {tomo_obj_id}") assert self._stitched_image.ndim == 2 self._composition_background = self.buildCompositionBackground( composition=composition, shape=(self._stitched_image.shape[0], self._stitched_image.shape[1], 4), axis=self.axis, ) self._update() @property def composition_background(self): return self._composition_background @property def stitched_image(self): return self._stitched_image def setPixelSize(self, pixel_size_m: tuple | float): """set the pixel size to be used by the ruler""" self._tapeMeasureButton.setPixelSize(pixel_size=pixel_size_m) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/stitching/stitching_raw.py0000644000175000017500000005353715143647637022361 0ustar00paynopaynofrom __future__ import annotations import logging import weakref import numpy from typing import Any from contextlib import AbstractContextManager from silx.gui import qt from silx.gui.plot import PlotWindow from nxtomo.nxobject.nxdetector import ImageKey from tomwer.core.volume.volumebase import TomwerVolumeBase from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.tomwer_object import TomwerObject from tomwer.gui.stitching.metadataholder import QStitchingMetadata from tomwer.gui import icons as tomwer_icons _logger = logging.getLogger(__name__) class RawStitchingPlot(PlotWindow): """ Plot displaying the different TomwerObject (volume or scan) at the specify position. This widget is used to help users find initial positions for stitching over anspecific axis. It will display a single slice or projection. The design is that it will keep up to date with TomwerObject if the widget is "active". Else it will wait for either a manual update (calling updateImages) or to be activated. tomo objects are weakref and stitching metadata will always be connected. But ignore if not activated. Activation mecanism is here because this can be memory consuming and we want by default to avoid this mecanism Warning: for now the interface expects to have frames homogeneous space. So if a scan / volume gets invertions (y downward)... we expect all scans / volumes to have the same. This is the same at nabu level. """ class ActivateContext(AbstractContextManager): """ simple context to turn off : turn on image update """ def __init__(self, rawStitchingPlot, activate) -> None: super().__init__() self._rawStitchingPlot = rawStitchingPlot self._activate = activate def __enter__(self) -> Any: self._activateStatus = self._rawStitchingPlot.isActive() self._rawStitchingPlot.setActive(self._activate) def __exit__(self, exc_type, exc_val, exc_tb): self._rawStitchingPlot.setActive(self._activateStatus) def __init__(self, parent=None, alpha_values=False, *args, **kwargs): super().__init__(parent, *args, **kwargs) self._activated = True self._tomo_objs = dict({}) self._slice_for_preview = "middle" self._scan_reading_order = {} # for each scan store if the rotation angles are store in increasing order or decreasing. # this way we can try to know if the order is inverted between different scans. self._flipudFrames = False # should we flip up / down frame (once management of metadata is done). For scan we can get fliplr and flip ud information already # but not for volumes self._fliplrFrames = False self._firstDisplay = True # bool to know if we are currently displaying the BW mode self._blackAndWhiteCompositeMode = False # result of the B&W composite mode self._BWImage = None self._compositeOffset = None, None # add alpha values widget if alpha_values: self._alphaValuesWidget = AlphaValuesTableWidget(self, plot=self) self._alphaValuesWidgetDockWidget = qt.QDockWidget(self) self._alphaValuesWidgetDockWidget.setWidget(self._alphaValuesWidget) self.addDockWidget( qt.Qt.BottomDockWidgetArea, self._alphaValuesWidgetDockWidget ) else: self._alphaValuesWidget = None # composite B&W mode self._modeToolbar = qt.QToolBar("display mode", self) icon = tomwer_icons.getQIcon("compare_mode_a_minus_b") self._substractAction = qt.QAction(icon, "Subtract in BW mode", self) self._substractAction.setCheckable(True) self._substractAction.setChecked(False) self._substractAction.toggled.connect(self.__displayModeChanged) self._modeToolbar.addAction(self._substractAction) self._modeToolbar.setVisible( False ) # for now this mode is a proto. Complex to do to keep some performances. self.addToolBar(self._modeToolbar) def __displayModeChanged(self): self._blackAndWhiteCompositeMode = self._substractAction.isChecked() self._updateImages() def setFlipLRFrames(self, flip: bool) -> None: if flip != self._fliplrFrames: self._fliplrFrames = flip self._updateImages() def setFlipUDFrames(self, flip: bool): if flip != self._flipudFrames: self._flipudFrames = flip self._updateImages() def setSliceForPreview(self, slice_for_preview: str | int): if self._slice_for_preview != slice_for_preview: self._slice_for_preview = slice_for_preview self._updateImages() def setActive(self, active: bool): if active == self._activated: # avoid any update if not necessary return self._activated = active if active: # if has been activated update plot to be up to date self._updateImages() def isActive(self) -> bool: return self._activated @staticmethod def getMinAxisPosition(tomo_obj: TomwerObject | None, axis): if tomo_obj is None or tomo_obj.stitching_metadata is None: return 0 else: return tomo_obj.stitching_metadata.get_abs_position_px(axis=axis) or 0 @staticmethod def getRotationAngleDirection(scan: TomwerScanBase): if not isinstance(scan, TomwerScanBase): raise TypeError( f"scan is expected to be an instance of {TomwerScanBase} instead of {type(scan)}" ) rotation_angle_ref = numpy.array(scan.rotation_angle) return rotation_angle_ref[ numpy.asarray(scan.image_key_control) == ImageKey.PROJECTION.value ] def addTomoObj(self, tomo_obj: TomwerObject): if not isinstance(tomo_obj, TomwerObject): raise TypeError( f"tomo_obj is expected to be an instance of {TomwerObject}. {type(tomo_obj)} provided" ) elif tomo_obj.stitching_metadata is None: raise ValueError( "tomo obj is expected to have a stitching_metadata defined yet" ) if len(self._tomo_objs) > 0: first_tomo_obj_id = tuple(self._tomo_objs.keys())[0] first_tomo_obj = self._tomo_objs[first_tomo_obj_id]() else: first_tomo_obj_id = None first_tomo_obj = None if not isinstance(first_tomo_obj, (TomwerScanBase, type(None))) and isinstance( tomo_obj, TomwerScanBase ): # We cannot display both scan and volumes. Especially because we need to define reading order for scan # and we need to keep a reference for scans (first one over the stitching axis) _logger.error( f"get instances of both {TomwerScanBase} and {TomwerVolumeBase}. Case not handled. Skip it" ) return self._tomo_objs[tomo_obj.get_identifier().to_str()] = weakref.ref(tomo_obj) if isinstance(tomo_obj.stitching_metadata, QStitchingMetadata): tomo_obj.stitching_metadata.sigChanged.connect( self._tomoObjMetadataHasChanged ) # reorder tomo_objs to keep it axis 0 ordered self._tomo_objs = dict( sorted( self._tomo_objs.items(), key=lambda item: self.getMinAxisPosition(item[1](), axis=0), reverse=True, # scan are expected to be orderred alonx axis 0 and decreasing ) ) self._alphaValuesWidget.addTomoObj(tomo_obj) if isinstance(tomo_obj, TomwerScanBase): self._scan_reading_order[tomo_obj.get_identifier().to_str()] = ( self.getRotationAngleDirection(tomo_obj) ) if first_tomo_obj_id != tuple(self._tomo_objs.keys())[0]: # if the order of scans might have change we need to update the full stack (to handle reading order) self._updateImages() return self._updateImage(tomo_obj) def _tomoObjMetadataHasChanged(self, *args, **kwargs): sender = self.sender() if not isinstance(sender, QStitchingMetadata): _logger.error( "_tomoObjMetadataHasChanged is expected to be conencted with QStitchingMetadata only" ) else: tomo_obj = sender.tomo_obj if tomo_obj is not None: self._updateImage(tomo_obj=tomo_obj) def removeTomoObj(self, tomo_obj: TomwerObject): if not isinstance(tomo_obj, TomwerObject): raise TypeError( f"tomo_obj is expected to be an instance of {TomwerObject}. {type(tomo_obj)} provided" ) self._tomo_objs.pop(tomo_obj.get_identifier().to_str(), None) self._scan_reading_order.pop(tomo_obj.get_identifier().to_str(), None) # reorder tomo_objs to keep it axis 0 ordered self._tomo_objs = dict( sorted( self._tomo_objs.items(), key=lambda item: self.getMinAxisPosition(item[1](), axis=0), reverse=True, ) ) if len(self._tomo_objs) > 0: first_tomo_obj_id = tuple(self._tomo_objs.keys())[0] first_tomo_obj = self._tomo_objs[first_tomo_obj_id]() else: first_tomo_obj_id = None first_tomo_obj = None if first_tomo_obj is tomo_obj and isinstance(first_tomo_obj, TomwerScanBase): # if a scan has been added and if he is the first one over the axis. Then the reading order was the 'ref order' # and we need to update all images self._updateImages() else: # else we can simple remove the image it will not affect others self.removeImage(tomo_obj.get_identifier().to_str()) def _updateImage(self, tomo_obj: TomwerObject, recompute_composite=True): if not self._activated: return if not isinstance(tomo_obj, TomwerObject): raise TypeError( f"tomo_obj is expected to be an instance of {TomwerObject}. {type(tomo_obj)} provided" ) if recompute_composite: self._recomputeBlackAndWhiteCompositeImage() frame = self.getFrame(tomo_obj=tomo_obj) if frame is None: return frame_origin = ( tomo_obj.stitching_metadata.get_abs_position_px(axis=2) or 0, tomo_obj.stitching_metadata.get_abs_position_px(axis=0) or 0, ) # replace frame by the composite if needed if self._blackAndWhiteCompositeMode: frame = self._BWImage[ self._compositeOffset[0] + frame_origin[1] : frame.shape[0], self._compositeOffset[1] + frame_origin[0] : frame.shape[1], ] identifier = tomo_obj.get_identifier().to_str() self.addImage( data=frame[ ::-1 ], # for coherence with axis and keep frame ordered we need to invert this one legend=identifier, origin=frame_origin, resetzoom=self._firstDisplay, ) self._firstDisplay = False img = self.getImage(identifier) img.setAlpha(0.5) # TODO: look to be able to tune this value from interface... def clearTomoObjs(self): tomo_objs = tuple(self._tomo_objs.values()) for tomo_obj in tomo_objs: self.removeTomoObj(tomo_obj()) self._alphaValuesWidget.clearTomoObjs() def setTomoObjs(self, tomo_objs): self.clearTomoObjs() # avoid to update images each time with RawStitchingPlot.ActivateContext(self, activate=False): for tomo_obj in tomo_objs: self.addTomoObj(tomo_obj=tomo_obj) self._alphaValuesWidget.setTomoObjs(tomo_objs) self._updateImages() def _getReadingOrderRef(self): return self._scan_reading_order[tuple(self._tomo_objs.keys())[0]] def getFrame(self, tomo_obj): if isinstance(tomo_obj, TomwerVolumeBase): try: frame = tomo_obj.get_slice(index=self._slice_for_preview, axis=1) except IndexError: _logger.error( f"requested slice doesn't exist (index=={self._slice_for_preview}, axis==1)" ) return None if self._flipudFrames: frame = numpy.flipud(frame) if self._fliplrFrames: frame = numpy.fliplr(frame) return frame elif isinstance(tomo_obj, TomwerScanBase): scan = tomo_obj # compute flat field # TODO: this must be done in another thread... but sync with update might be difficult... try: reduced_darks, reduced_darks_infos = scan.load_reduced_darks( return_info=True ) except Exception: _logger.warning( f"no reduced dark found for {scan}. Please compute them to get a better display." ) else: scan.set_reduced_darks(reduced_darks, darks_infos=reduced_darks_infos) try: reduced_flats, reduced_flats_info = scan.load_reduced_flats( return_info=True ) except Exception: _logger.warning( f"no reduced flat(s) found for {scan}. Please compute them to get a better display." ) else: scan.set_reduced_flats(reduced_flats, flats_infos=reduced_flats_info) reading_order_ref = self._getReadingOrderRef() reading_order = self._scan_reading_order[scan.get_identifier().to_str()] invert_reading_order = not numpy.allclose( reading_order_ref, reading_order, atol=10e-1 ) slice_to_use = self._slice_for_preview if slice_to_use == "first": slice_to_use = 0 elif slice_to_use == "last": slice_to_use = -1 elif slice_to_use == "middle": slice_to_use = len(scan.projections) // 2 proj_idx = sorted(scan.projections.keys(), reverse=invert_reading_order)[ slice_to_use ] ff = scan.flat_field_correction( (scan.projections[proj_idx],), (slice_to_use,), )[0] if (scan.detector_is_lr_flip or False) ^ self._fliplrFrames: ff = numpy.fliplr(ff) if (scan.detector_is_ud_flip or False) ^ self._flipudFrames: ff = numpy.flipud(ff) return ff else: raise TypeError(f"tomo_obj of type {type(tomo_obj)} is not handled") def _recomputeBlackAndWhiteCompositeImage(self): def get_min_max(tomo_obj, axis): axis_pos = tomo_obj.stitching_metadata.get_abs_position_px(axis=axis) or 0 frame_axis = 0 if axis == 0 else 1 return ( axis_pos, axis_pos + self.getFrame(tomo_obj=tomo_obj).shape[frame_axis], ) import sys from math import ceil min_x = sys.float_info.max min_y = sys.float_info.max max_x = sys.float_info.min max_y = sys.float_info.min for tomo_obj in self._tomo_objs.values(): if tomo_obj() is None: continue l_min_x, l_max_x = get_min_max(tomo_obj(), axis=2) l_min_y, l_max_y = get_min_max(tomo_obj(), axis=0) min_x = min(min_x, l_min_x) max_x = max(max_x, l_max_x) min_y = min(min_y, l_min_y) max_y = max(max_y, l_max_y) self._compositeOffset = (min_y, min_x) self._BWImage = numpy.zeros( shape=( ceil(max_y - min_y), ceil(max_x - min_x), ), dtype=numpy.float32, ) # update BW image for tomo_obj in self._tomo_objs.values(): if tomo_obj() is None: continue else: frame = self.getFrame(tomo_obj=tomo_obj()) position_y = ( tomo_obj().stitching_metadata.get_abs_position_px(axis=0) or 0 ) position_x = ( tomo_obj().stitching_metadata.get_abs_position_px(axis=2) or 0 ) self._BWImage[ position_y - min_y : frame.shape[0] + position_y - min_y, position_x - min_x : position_x + frame.shape[1] - min_x, ] -= frame def _updateImages(self): self.clearImages() first_display = self._firstDisplay if self._blackAndWhiteCompositeMode: self._recomputeBlackAndWhiteCompositeImage() for tomo_obj in self._tomo_objs.values(): if tomo_obj() is None: continue else: self._updateImage( tomo_obj=tomo_obj(), recompute_composite=self._blackAndWhiteCompositeMode, ) if first_display and len(self._tomo_objs) > 0 and self._activated: # work around to handle first plotting when just activated and can get several objects self.resetZoom() self._firstDisplay = False class AlphaValuesTableWidget(qt.QTableWidget): """ Widget to define alpha values of a list of tomo object. Meant to work with the RawPlotWidget used for stitching """ COLUMNS = "legend", "alpha value" def __init__(self, parent=None, plot=None): super().__init__(parent) if plot is not None: self.__plot = weakref.ref(plot) self._sliders = {} def getPlot(self): if self.__plot is None: return None else: return self.__plot() def clear(self): for slider, label in self._sliders.items(): slider.valueChanged.disconnect(self._alphaValueChanged) self._sliders.clear() super().clear() def addTomoObj(self, tomo_obj: TomwerObject): n_objs = self.rowCount() + 1 self.setRowCount(n_objs) self.setColumnCount(len(self.COLUMNS)) self.setHorizontalHeaderLabels(self.COLUMNS) self.horizontalHeader().setSectionResizeMode(qt.QHeaderView.ResizeToContents) self.verticalHeader().hide() _item_legend = qt.QTableWidgetItem() plot_legend = tomo_obj.get_identifier().to_str() short_descrition = tomo_obj.get_identifier().short_description() _item_legend.setText(short_descrition) self.setItem(n_objs - 1, 0, _item_legend) slider = AlphaValueSlider(self) slider.valueChanged.connect(self._alphaValueChanged) self.setCellWidget(n_objs - 1, 1, slider) self._sliders[slider] = (plot_legend, short_descrition) def clearTomoObjs(self): # disconnect sliders for slider in self._sliders.keys(): slider.valueChanged.disconnect(self._alphaValueChanged) self._sliders.clear() self.setRowCount(len(self._sliders)) self.setColumnCount(len(self.COLUMNS)) self.setHorizontalHeaderLabels(self.COLUMNS) self.horizontalHeader().setSectionResizeMode(qt.QHeaderView.ResizeToContents) self.verticalHeader().hide() def setTomoObjs(self, tomo_objs: tuple): self.clearTomoObjs() self.clear() for tomo_obj in tomo_objs: self.addTomoObj(tomo_obj=tomo_obj) def _alphaValueChanged(self, *args, **kwargs): sender = self.sender() # pylint: disable=E1101 assert isinstance( sender, AlphaValueSlider ), f"sender is expected to be an instance of AlphaValueSlider. get {type(sender)}" legend = self._sliders.get(sender, (None, None))[0] if legend is not None: plot = self.getPlot() if plot is None: return else: image_item = plot.getImage(legend) if image_item is not None: image_item.setAlpha( sender.value() / 255 ) # silx define value in [0, 1.0] when AlphaValueSlider in [0, 255] class AlphaValueSlider(qt.QTableWidget): """ slider to define alpha value with a slider and top button on each side to quickly set values to boundaries """ valueChanged = qt.Signal(int) " emit when the slider value changed" def __init__(self, parent=None): super().__init__(parent) self.setLayout(qt.QHBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.layout().setSpacing(0) # `invisible` button invisibleIcon = tomwer_icons.getQIcon("invisible") self._invisibleButton = qt.QPushButton(invisibleIcon, "", self) self._invisibleButton.setFlat(True) self.layout().addWidget(self._invisibleButton) # `slider` self._slider = qt.QSlider(qt.Qt.Horizontal, self) self._slider.setRange(0, 255) self._slider.setValue(255) self.layout().addWidget(self._slider) # `visible` button visibleIcon = tomwer_icons.getQIcon("visible") self._visibleButton = qt.QPushButton(visibleIcon, "", self) self._visibleButton.setFlat(True) self.layout().addWidget(self._visibleButton) # connect signal / slot self._invisibleButton.released.connect(self._setInvisible) self._visibleButton.released.connect(self._setVisible) # expose API self._slider.valueChanged.connect(self.valueChanged) def _setInvisible(self, *args, **kwargs): self._slider.setValue(0) def _setVisible(self, *args, **kwargs): self._slider.setValue(255) def value(self) -> int: return self._slider.value() def setValue(self, value: int): self._slider.setValue(int(value)) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9451017 tomwer-1.6.17/src/tomwer/gui/stitching/tests/0000755000175000017500000000000015153325403020250 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/stitching/tests/test_ZStitchingWindow.py0000644000175000017500000000616415143647637025165 0ustar00paynopaynofrom __future__ import annotations import os import pint import tempfile from tomoscan.series import Series from tomwer.gui.stitching.StitchingWindow import ZStitchingWindow from tomwer.gui.stitching.tests.utils import create_scans_z_series from tomwer.tests.conftest import qtapp # noqa F401 _ureg = pint.get_application_registry() def test_ZStitchingWindow( qtapp, # noqa F811 tmp_path, ): """ Test ZStitchingWindow * adding tom objects * saving and loading settings (nabu-stitching configuration) * editing tomo objects positions over stitching axis * reset tomo objects positions """ window = ZStitchingWindow() axis_0_positions = (90, 0.0, -90.0) axis_2_positions = (0.0, 0.0, 0.0) pixel_size = 1.0 input_dir = os.path.join(tmp_path, "input") scans = create_scans_z_series( output_dir=input_dir, z_positions_m=axis_0_positions, x_positions_m=axis_2_positions, shifts=((0.0, 0.0), (-90.0, 0.0), (-180.0, 0.0)), sample_pixel_size=pixel_size, raw_frame_width=280, final_frame_width=100, ) series = Series("z-series", scans) window.show() for scan in scans: window.addTomoObj(scan) window.clean() window.setSeries(series) # test dumping and loading configuration to a file with tempfile.TemporaryDirectory() as dump_dir: config_file = os.path.join(dump_dir, "configuration.cfg") window._saveSettings(file_path=config_file) assert os.path.exists(config_file) window._loadSettings(config_file) # remove configuration window.clean() assert len(window._widget._mainWidget.getTomoObjs()) == 0 # reload it window._loadSettings(file_path=config_file) assert len(window._widget._mainWidget.getTomoObjs()) == len(series) assert window.getConfiguration()["stitching"]["axis_0_pos_px"] == [90, 0, -90] # test editing axis position widget_tomo_obj_0 = ( window._editTomoObjFirstAxisPositionsWidget._tomoObjtoTomoObjPosWidget[ scans[0].get_identifier().to_str() ] ) window._editTomoObjFirstAxisPositionsWidget.setEditionMode("free") widget_tomo_obj_0.setValue(10, emit_editing_finished=True) assert window.getConfiguration()["stitching"]["axis_0_pos_px"] == [10, 0, -90] window._editTomoObjFirstAxisPositionsWidget.setEditionMode("downstream") widget_tomo_obj_0.setValue(30, emit_editing_finished=True) assert window.getConfiguration()["stitching"]["axis_0_pos_px"] == [30, 20, -70] window._editTomoObjFirstAxisPositionsWidget.setEditionMode("upstream") widget_tomo_obj_2 = ( window._editTomoObjFirstAxisPositionsWidget._tomoObjtoTomoObjPosWidget[ scans[2].get_identifier().to_str() ] ) widget_tomo_obj_2.setValue(-120, emit_editing_finished=True) assert window.getConfiguration()["stitching"]["axis_0_pos_px"] == [-20, -30, -120] # test reset positions to initial positions window._editTomoObjFirstAxisPositionsWidget._resetPositions() assert window.getConfiguration()["stitching"]["axis_0_pos_px"] == [90, 0, -90] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/stitching/tests/test_axis_ordered_list.py0000644000175000017500000000127414757047403025402 0ustar00paynopaynofrom tomwer.tests.conftest import qtapp # noqa F401 from tomwer.core.volume.hdf5volume import HDF5Volume from tomwer.gui.stitching.axisorderedlist import EditableOrderedTomoObjWidget def test_axis_ordered_list_widget( qtapp, # noqa F811 ): widget = EditableOrderedTomoObjWidget(axis=0) volumes = tuple( HDF5Volume( file_path=f"my_volume{i}.hdf5", data_path="my_volume", ) for i in range(5) ) [widget.addTomoObj(volume) for volume in volumes] widget.setSelectedTomoObjs([volumes[1], volumes[-1]]) widget._callbackRemoveSelectedTomoObj() assert widget.getTomoObjsAxisOrdered() == (volumes[0], volumes[2], volumes[3]) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/stitching/tests/test_normalization.py0000644000175000017500000000120314757047403024555 0ustar00paynopaynofrom tomwer.gui.stitching.normalization import NormalizationBySampleGroupBox from tomwer.tests.conftest import qtapp # noqa F401 def test_FrameNormalizationWidget( qtapp, # noqa F811 ): widget = NormalizationBySampleGroupBox() assert widget.getConfiguration() == { "active": True, "side": "left", "method": "median", "width": 30, "margin": 0, } new_config = { "active": False, "side": "left", "method": "median", "width": 30, "margin": 0, } widget.setConfiguration(new_config) assert widget.getConfiguration() == new_config ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/gui/stitching/tests/test_preview.py0000644000175000017500000000464015115744275023360 0ustar00paynopaynofrom __future__ import annotations import os import pint import numpy import pytest from nabu.stitching.config import PreProcessedZStitchingConfiguration from nabu.stitching.z_stitching import PreProcessZStitcher from tomwer.tests.conftest import qtapp # noqa F401 from silx.image.phantomgenerator import PhantomGenerator from tomwer.gui.stitching.stitching_preview import PreviewStitchingPlot from tomwer.gui.stitching.tests.utils import create_scans_z_series _ureg = pint.get_application_registry() @pytest.mark.parametrize("flip_lr", (True, False)) @pytest.mark.parametrize("flip_ud", (True, False)) def test_preview(tmp_path, flip_lr, flip_ud, qtapp): # noqa F401 axis_0_positions = (90, 0.0, -90.0) axis_2_positions = (0.0, 0.0, 0.0) sample_pixel_size = 1.0 output_file_path = os.path.join(str(tmp_path), "output", "stitched.nx") input_dir = os.path.join(tmp_path, "input") scans = create_scans_z_series( output_dir=input_dir, z_positions_m=axis_0_positions, x_positions_m=axis_2_positions, shifts=((0.0, 0.0), (-90.0, 0.0), (-180.0, 0.0)), sample_pixel_size=sample_pixel_size, raw_frame_width=280, final_frame_width=100, flip_lr=flip_lr, flip_ud=flip_ud, ) stitching_config = PreProcessedZStitchingConfiguration( output_file_path=output_file_path, output_data_path="entry_stitched", overwrite_results=True, slurm_config=None, axis_0_pos_mm=numpy.array(axis_0_positions) * 1000, axis_2_pos_mm=numpy.array(axis_2_positions) * 1000, axis_0_pos_px=None, axis_1_pos_px=None, axis_2_pos_px=None, input_scans=scans, pixel_size=sample_pixel_size, ) widget = PreviewStitchingPlot(axis=0) widget._backGroundAction.toggle() stitcher = PreProcessZStitcher(configuration=stitching_config) stitched_id = stitcher.stitch(store_composition=True) assert stitched_id is not None composition = stitcher.frame_composition assert composition is not None widget.setStitchedTomoObj(tomo_obj_id=stitched_id.to_str(), composition=composition) assert widget.stitched_image is not None assert widget.composition_background is not None numpy.testing.assert_almost_equal( widget.stitched_image, PhantomGenerator.get2DPhantomSheppLogan(n=280).astype(numpy.float32) * 256.0, ) widget._backGroundAction.toggle() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/stitching/tests/test_stitching_raw.py0000644000175000017500000000716314757047403024547 0ustar00paynopaynoimport os import shutil import tempfile import numpy from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from tomwer.core.utils.scanutils import MockNXtomo from tomwer.core.volume.hdf5volume import HDF5Volume from tomwer.gui.stitching.metadataholder import QStitchingMetadata from tomwer.gui.stitching.stitching_raw import RawStitchingPlot, AlphaValuesTableWidget def _createVolumes(axis_0_positions: tuple, root_dir: str): volumes = [] for i_volume, axis_0_position in enumerate(axis_0_positions): data = numpy.random.random(20 * 20).reshape(1, 20, 20) volume = HDF5Volume( file_path=os.path.join(root_dir, f"volume_{i_volume}.hdf5"), data_path=f"entry_{i_volume}", data=data, ) volume.stitching_metadata = QStitchingMetadata(tomo_obj=volume) volume.stitching_metadata.setPxPos(axis=0, value=axis_0_position) volumes.append(volume) return volumes def _createScans(axis_0_positions: tuple, root_dir: str): scans = [] for i_scan, axis_0_position in enumerate(axis_0_positions): scan = MockNXtomo( scan_path=os.path.join(root_dir, f"scan_{i_scan}"), n_proj=20, n_ini_proj=20, dim=10, ).scan scan.stitching_metadata = QStitchingMetadata(tomo_obj=scan) scan.stitching_metadata.setPxPos(axis=0, value=axis_0_position) scans.append(scan) return scans class TestPlotRawStitching(TestCaseQt): """Test RawStitchingPlot widget""" def setUp(self): super().setUp() self._tmp_path = tempfile.mkdtemp() self.widget = RawStitchingPlot(alpha_values=True) def tearDown(self): self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None shutil.rmtree(self._tmp_path) def testWithVolumes(self): axis_0_positions = (0, 12, 50) volumes = _createVolumes( axis_0_positions=axis_0_positions, root_dir=self._tmp_path ) assert len(volumes) == 3 self.widget.addTomoObj(volumes[0]) images = self.widget.getAllImages() assert len(images) == 1 self.widget.setTomoObjs(volumes) images = self.widget.getAllImages() assert len(images) == len(volumes) # silx is storing origins as x, y origins = tuple([image.getOrigin()[1] for image in images]) assert tuple(sorted(origins)) == axis_0_positions def testWithScans(self): axis_0_positions = (0, 10, 20, 34) scans = _createScans(axis_0_positions=axis_0_positions, root_dir=self._tmp_path) self.widget.setActive(False) self.widget.setTomoObjs(scans) assert len(self.widget.getAllImages()) == 0 self.widget.setActive(True) self.qapp.processEvents() assert len(self.widget.getAllImages()) == len(scans) class TestAlphaValuesTableWidget(TestCaseQt): """test AlphaValuesTableWidget""" def setUp(self): super().setUp() self._tmp_path = tempfile.mkdtemp() self.widget = AlphaValuesTableWidget() def tearDown(self): self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None shutil.rmtree(self._tmp_path) def testSettingTomoObj(self): self.widget.setTomoObjs( _createVolumes(axis_0_positions=(0, 12, 50), root_dir=self._tmp_path), ) assert len(self.widget._sliders) == 3 self.widget.setTomoObjs( _createScans(axis_0_positions=(89, 78), root_dir=self._tmp_path) ) assert len(self.widget._sliders) == 2 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/stitching/tests/utils.py0000644000175000017500000001014715143647637022004 0ustar00paynopaynofrom __future__ import annotations import os import pint import numpy from nxtomo.application.nxtomo import NXtomo from scipy.ndimage import shift as shift_scipy from silx.image.phantomgenerator import PhantomGenerator from nxtomo.nxobject.nxdetector import ImageKey from tomwer.core.scan.nxtomoscan import NXtomoScan from nxtomo.utils.transformation import DetYFlipTransformation, DetZFlipTransformation _ureg = pint.get_application_registry() def create_scans_z_series( output_dir, z_positions_m: tuple[float | None] | None, x_positions_m: tuple[float | None] | None = None, sample_pixel_size: float | tuple[float, float] = 10.0e6, n_proj: int = 20, raw_frame_width: int = 100, final_frame_width: int = 100, shifts=None, z_rois=None, flip_lr: bool = False, flip_ud: bool = False, ): """ :param z_positions_m: positions along the Z axis in meter (in the ESRF coordinate system). Warning: those position will be saved under the McStas coordinate system (y axis) :param x_positions_m: positions along the x axis in meter (in the ESRF coordinate system). Warning: those position will be saved under the McStas coordinate system (z axis) :param shifts: shift to be applied on the 2D frame """ if not os.path.exists(output_dir): os.makedirs(output_dir) frame = ( PhantomGenerator.get2DPhantomSheppLogan(n=raw_frame_width).astype(numpy.float32) * 256.0 ) if x_positions_m is None: x_positions_m = [None] * len(z_positions_m) if shifts is None: shifts = [None] * len(z_positions_m) if z_rois is None: z_rois = [None] * len(z_positions_m) scans = [] for i_frame, (z_pos, x_pos, z_roi, shift) in enumerate( zip(z_positions_m, x_positions_m, z_rois, shifts) ): nx_tomo = NXtomo() if z_pos is not None: # warning: doing mapping from esrf coordinate system to McStas (used by NXtomo) nx_tomo.sample.y_translation = ([z_pos] * n_proj) * _ureg.meter if x_pos is not None: # warning: doing mapping from esrf coordinate system to McStas (used by NXtomo) nx_tomo.sample.z_translation = ([x_pos] * n_proj) * _ureg.meter nx_tomo.sample.rotation_angle = ( numpy.linspace(0, 180, num=n_proj, endpoint=False) * _ureg.degree ) nx_tomo.instrument.detector.image_key_control = [ImageKey.PROJECTION] * n_proj # sample pixel size if sample_pixel_size is not None: if isinstance(sample_pixel_size, (tuple, list)): sample_y_pix_size, sample_x_pix_size = sample_pixel_size else: sample_y_pix_size, sample_x_pix_size = ( sample_pixel_size, sample_pixel_size, ) nx_tomo.sample.x_pixel_size = sample_x_pix_size * _ureg.meter nx_tomo.sample.y_pixel_size = sample_y_pix_size * _ureg.meter nx_tomo.instrument.detector.distance = 2.3 * _ureg.meter nx_tomo.energy = 19.2 * _ureg.keV nx_tomo.instrument.detector.transformations.add_transformation( DetYFlipTransformation(flip=flip_ud) ) nx_tomo.instrument.detector.transformations.add_transformation( DetZFlipTransformation(flip=flip_lr) ) if shift is not None: sub_frame = shift_scipy( input=frame.copy(), shift=shift, order=1, mode="constant" )[:final_frame_width] else: sub_frame = frame if z_roi is not None: roi_start, roi_end = z_roi sub_frame = sub_frame[roi_start:roi_end] else: sub_frame = sub_frame if flip_lr: sub_frame = numpy.fliplr(sub_frame) if flip_ud: sub_frame = numpy.flipud(sub_frame) nx_tomo.instrument.detector.data = numpy.asarray([sub_frame] * n_proj) file_path = os.path.join(output_dir, f"nxtomo_{i_frame}.nx") entry = f"entry000{i_frame}" nx_tomo.save(file_path=file_path, data_path=entry) scans.append(NXtomoScan(scan=file_path, entry=entry)) return scans ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/stitching/utils.py0000644000175000017500000000112714757047403020633 0ustar00paynopaynodef concatenate_dict(dict_1, dict_2) -> dict: """update dict which has dict as values. And we want concatenate those values to""" res = dict_1.copy() for key in dict_2: if key in dict_1: if key in [f"axis_{axis}_params" for axis in (0, 1, 2)]: res[key] = ";".join((dict_1[key], dict_2[key])) elif isinstance(dict_1[key], dict): res[key] = concatenate_dict(dict_1=dict_1[key], dict_2=dict_2[key]) else: res[key].update(dict_2[key]) else: res[key] = dict_2[key] return res ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9451017 tomwer-1.6.17/src/tomwer/gui/stitching/z_stitching/0000755000175000017500000000000015153325403021433 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/stitching/z_stitching/__init__.py0000644000175000017500000000000014757047403023544 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/gui/stitching/z_stitching/fineestimation.py0000644000175000017500000001731715115744275025046 0ustar00paynopayno"""widgets to perform a z-sttiching in pre processing (from projections) or post processing (from reconstructed volumes)""" from __future__ import annotations import logging from nabu.stitching import config as _nabu_stitching_config from nabu.stitching.config import StitchingType from nabu.stitching.overlap import OverlapStitchingStrategy from nabu.stitching.utils import ShiftAlgorithm as _NabuShiftAlgorithm from silx.gui import qt _logger = logging.getLogger(__name__) class Axis_N_Params(qt.QGroupBox): """ widget to edit the option for image registration along a specific axe """ def __init__(self, title, parent=None) -> None: super().__init__(title, parent) self.setLayout(qt.QFormLayout()) # img registration method self._imageRegMethodCB = qt.QComboBox(self) for method in _NabuShiftAlgorithm: self._imageRegMethodCB.addItem(method.value) self._imageRegMethodCB.setToolTip( "method to use in order to affine positions provided by the user" ) self.layout().addRow("image registration method", self._imageRegMethodCB) # set up self._imageRegMethodCB.setCurrentText(_NabuShiftAlgorithm.NONE.value) def getCurrentMethod(self): return _NabuShiftAlgorithm(self._imageRegMethodCB.currentText()) def setCurrentMethod(self, method): self._imageRegMethodCB.setCurrentText(_NabuShiftAlgorithm(method).value) def getOptsLine(self) -> str: current_method = self.getCurrentMethod() line_ = f"{_nabu_stitching_config.KEY_IMG_REG_METHOD}={current_method.value}" return line_ def setOptsLine(self, opt_line: str) -> None: opt_line = opt_line.replace(",", ";") opt_line = opt_line.replace(" ", "") opts = {} for key_value in filter(None, opt_line.split(";")): key, value = key_value.split("=") opts[key] = value window_size = opts.get(_nabu_stitching_config.KEY_WINDOW_SIZE, None) if window_size is not None: try: self.setWindowSize(int(window_size)) except Exception as e: _logger.error(e) img_reg_exp_method = opts.get(_nabu_stitching_config.KEY_IMG_REG_METHOD, None) if img_reg_exp_method is not None: try: self.setCurrentMethod(img_reg_exp_method) except Exception as e: _logger.error(e) class AutoRefineWidget(qt.QWidget): """ widget grouping information not specific to objects (output file, stitching strategy...) """ def __init__(self, parent=None): super().__init__(parent=parent) self.setLayout(qt.QVBoxLayout()) self._globalOpts = qt.QWidget(self) self.layout().addWidget(self._globalOpts) self._globalOpts.setLayout(qt.QFormLayout()) # stitching strategy self._stitchingStrategyCG = qt.QComboBox(parent=self) for strategy in OverlapStitchingStrategy: self._stitchingStrategyCG.addItem(strategy.value) self._globalOpts.layout().addRow( "stitching strategy", self._stitchingStrategyCG ) # slice for cross correlation self._sliceForCorrelation = qt.QLineEdit("middle", self) self._globalOpts.layout().addRow( "slice for cross correlation", self._sliceForCorrelation ) self._overwritePB = qt.QCheckBox("overwrite", self) self._globalOpts.layout().addRow(self._overwritePB) # pre processing options self._preProcGroup = qt.QGroupBox("pre-processing option", self) self.layout().addWidget(self._preProcGroup) self._preProcGroup.setLayout(qt.QFormLayout()) # TODO: check if the widget with output .nx file exists somewhere self._outputFile = qt.QLineEdit("", self) self._preProcGroup.layout().addRow("output nexus file", self._outputFile) self._outputDataPath = qt.QLineEdit("entry0000", self) self._preProcGroup.layout().addRow("output data path", self._outputDataPath) # post processing options self._postProcGroup = qt.QGroupBox("post-processing option", self) self._postProcGroup.setLayout(qt.QFormLayout()) self.layout().addWidget(self._preProcGroup) self._outputVolumeIdentifier = qt.QLineEdit("", self) self._postProcGroup.layout().addRow( "output identifier", self._outputVolumeIdentifier ) self.layout().addWidget(self._postProcGroup) # spacer self._spacer = qt.QWidget(parent=self) self._spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(self._spacer) # set up self._stitchingStrategyCG.setCurrentText( OverlapStitchingStrategy.COSINUS_WEIGHTS.value ) def getConfiguration(self) -> dict: raise NotImplementedError def setConfiguration(self, config: dict): raise NotImplementedError def updateStitchingType(self, mode: StitchingType): mode = StitchingType(mode) self._preProcGroup.setVisible(mode is StitchingType.Z_PREPROC) self._postProcGroup.setVisible(mode is StitchingType.Z_POSTPROC) def getSliceForPreview(self) -> int | str: slice = self._sliceForPreview.text() try: return int(slice) except Exception: return slice class ManualRefineWidget(qt.QWidget): pass class _RefineEstimationTabWidget(qt.QTabWidget): def __init__(self, parent=None) -> None: super().__init__(parent) self._autoRefine = AutoRefineWidget(parent=self) self.addTab(self._autoRefine, "automatique") self._manualRefine = ManualRefineWidget(parent=self) self.addTab(self._manualRefine, "manual") class _SliceGetter(qt.QLineEdit): class Validator(qt.QIntValidator): def validate(self, a0: str, a1: int): if a0 in ("first", "middle", "last"): return (qt.QValidator.Acceptable, a0, a1) elif a0 in ( "f", "fi", "fir", "firs", "m", "mi", "mid", "midd", "middl", "l", "la", "las", ): # dummy hack to avoid letting users write non-sense. return (qt.QValidator.Intermediate, a0, a1) else: return super().validate(a0, a1) def __init__(self, contents, parent=None): super().__init__(contents, parent) self.setValidator(self.Validator(parent=self)) class RefineEstimationCtrlWidget(qt.QWidget): sigSlicePreviewChanged = qt.Signal(str) """emit when the slice preview has changed""" def __init__(self, parent=None) -> None: super().__init__(parent) # main widget self.setLayout(qt.QGridLayout()) self._widget = _RefineEstimationTabWidget(parent=self) self.layout().addWidget(self._widget, 0, 0, 3, 3) # slice to be used for preview self._previewedSliceQLE = _SliceGetter("middle", parent=self) self.layout().addWidget(self._previewedSliceQLE, 4, 1, 2, 1) # auto update preview self._updateAutoPreviewCB = qt.QCheckBox("auto update preview", self) self.layout().addWidget(self._updateAutoPreviewCB, 5, 1, 1, 2) def isPreviewAuto(self): return self._updateAutoPreviewCB.isChecked() def setPreviewAuto(self, auto: bool): self._updateAutoPreviewCB.setChecked(auto) def getSliceForPreview(self) -> str: return self._previewedSliceQLE.text() def setSliceForPreview(self, slice: str): self._previewedSliceQLE.setText(str(slice)) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9451017 tomwer-1.6.17/src/tomwer/gui/stitching/z_stitching/tests/0000755000175000017500000000000015153325403022575 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/stitching/z_stitching/tests/test_fine_estimation.py0000644000175000017500000000226714757047403027404 0ustar00paynopaynofrom nabu.stitching.utils import ShiftAlgorithm as _NabuShiftAlgorithm from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from tomwer.gui.stitching.z_stitching.fineestimation import Axis_N_Params class TestAxis_N_Params(TestCaseQt): """ Test definition of an axis shift research parameters """ def setUp(self): super().setUp() self._widget = Axis_N_Params("axis n", None) def tearDown(self): self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None while self.qapp.hasPendingEvents(): self.qapp.processEvents() def test(self): self._widget.show() assert self._widget.getCurrentMethod() == _NabuShiftAlgorithm.NONE opts1 = self._widget.getOptsLine() assert opts1 == "img_reg_method=None" self._widget.setCurrentMethod(_NabuShiftAlgorithm.NABU_FFT) opts2 = self._widget.getOptsLine() assert opts2 == "img_reg_method=nabu-fft" self._widget.setOptsLine(opts1) assert self._widget.getOptsLine() == opts1 self._widget.setOptsLine(opts2) assert self._widget.getOptsLine() == opts2 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/stitching/z_stitching/tests/test_raw_estimation.py0000644000175000017500000002060515153325210027232 0ustar00paynopaynofrom __future__ import annotations import os import shutil import tempfile import pint import numpy from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from tomwer.core.process.stitching.metadataholder import StitchingMetadata from tomwer.gui.stitching.metadataholder import QStitchingMetadata from tomwer.gui.stitching.tests.utils import create_scans_z_series from tomwer.gui.stitching.config.tomoobjdetails import TomoObjectPositionInfos from tomwer.gui.stitching.axisorderedlist import AxisOrderedTomoObjsModel _ureg = pint.get_application_registry() class TestTomoObjectPositionInfos(TestCaseQt): """ Test edition of the tomo object position information """ def setUp(self): super().setUp() self._tmp_path = tempfile.mkdtemp() self._y_pixel_size = 0.002 self._x_pixel_size = 0.001 self.scans = create_scans_z_series( self._tmp_path, z_positions_m=(0.200, 0.205, 0.210), x_positions_m=(0.0, 0.0, None), sample_pixel_size=(self._y_pixel_size, self._x_pixel_size), raw_frame_width=100, ) self.scan_0_metadata = QStitchingMetadata(tomo_obj=self.scans[0]) numpy.testing.assert_almost_equal( self.scan_0_metadata.get_raw_position_m(axis=0), 0.20 ) assert self.scan_0_metadata.get_raw_position_m(axis=2) == 0.0 self.scan_2_metadata = QStitchingMetadata(tomo_obj=self.scans[2]) numpy.testing.assert_almost_equal( self.scan_2_metadata.get_raw_position_m(axis=0), 0.21 ) self._widget = TomoObjectPositionInfos() def tearDown(self): self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None while self.qapp.hasPendingEvents(): self.qapp.processEvents() shutil.rmtree(self._tmp_path) def testEdition(self): # test QStitchingMetadata are correctly read self._widget.show() self._widget.setStitchingMetadata(self.scan_0_metadata) self.qapp.processEvents() assert self._widget._axis_0_pos.get_final_px_position() == int(0.20 / 0.002) assert self._widget._axis_2_pos.get_final_px_position() == 0 self._widget.setStitchingMetadata(self.scan_2_metadata) while self.qapp.hasPendingEvents(): self.qapp.processEvents() assert self._widget._axis_0_pos.get_final_px_position() == int(0.21 / 0.002) assert self._widget._axis_2_pos.get_final_px_position() is None # test editing some parameters from the GUI. Make sure GUI is updated as the underlying metadata object self._widget._axis_0_pos._overrideMetricPositionCB.setChecked(True) self._widget._axis_0_pos.setRawMetricPosition( position_m=0.4, displayed_unit=_ureg.nanometer ) while self.qapp.hasPendingEvents(): self.qapp.processEvents() assert self._widget._axis_0_pos.get_final_px_position() == int( 0.4 * 10e-6 / 0.002 ) self._widget._axis_0_pos._overridePixelPositionCB.setChecked(True) self._widget._axis_0_pos.setOverrridePxPosition(position_px=120) while self.qapp.hasPendingEvents(): self.qapp.processEvents() assert self._widget._axis_0_pos.get_final_px_position() == int(120) assert self.scan_2_metadata.get_abs_position_px(axis=0) == int(120) class TestAxisOrderedTomoObjsModel(TestCaseQt): """ test the behavior of the z ordered model used for stitching """ def setUp(self): super().setUp() self._tmp_path = tempfile.mkdtemp() self.scans_with_pos_and_pixel_size = create_scans_z_series( os.path.join(self._tmp_path, "case1"), z_positions_m=(0.200, 0.205, 0.210), sample_pixel_size=0.001, raw_frame_width=100, ) self.scans_with_pixel_size = create_scans_z_series( os.path.join(self._tmp_path, "case2"), z_positions_m=(None, None, None), sample_pixel_size=0.001, raw_frame_width=100, ) self.scans_without_metadata = create_scans_z_series( os.path.join(self._tmp_path, "case3"), z_positions_m=(None, None, None), sample_pixel_size=None, raw_frame_width=100, ) self._widget = qt.QTableView() self._widget.setModel(AxisOrderedTomoObjsModel(parent=self._widget, axis=0)) def tearDown(self): self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None while self.qapp.hasPendingEvents(): self.qapp.processEvents() shutil.rmtree(self._tmp_path) def testWithMetadata(self): """ make sure z ordering works in the best case scenario """ first_expected_scan = ( self.scans_with_pos_and_pixel_size[2].get_identifier().short_description() ) # try giving it ordered for scan in self.scans_with_pos_and_pixel_size[::-1]: self._widget.model().addTomoObj(scan) assert ( self._widget.model().data( self._widget.model().index(0, 1), qt.Qt.DisplayRole ) == first_expected_scan ) self._widget.model().clearTomoObjs() # try giving it ordered (but inverted) for scan in self.scans_with_pos_and_pixel_size: self._widget.model().addTomoObj(scan) assert ( self._widget.model().data( self._widget.model().index(0, 1), qt.Qt.DisplayRole ) == first_expected_scan ) def testWithPixelSizeOnly(self): """ make sure z ordering works when we are only aware about pixel size """ for scan in self.scans_with_pixel_size[::-1]: self._widget.model().addTomoObj(scan) # try adding some metadata to object scans = self._widget.model()._objs scans = self._widget.model()._objs scans[0].stitching_metadata = StitchingMetadata(tomo_obj=scans[0]) scans[1].stitching_metadata = QStitchingMetadata(tomo_obj=scans[1]) scans[0].stitching_metadata._pos_as_m = (0.1, 1, 2) scans[1].stitching_metadata._pos_as_m = (-0.03, 1, 2) scans[2].stitching_metadata._pos_as_m = (0.23, 1, 2) self._widget.model().reorder_objs() self._widget.model().layoutChanged.emit() assert ( self._widget.model().data( self._widget.model().index(0, 1), qt.Qt.DisplayRole ) == scans[2].get_identifier().short_description() ) assert ( self._widget.model().data( self._widget.model().index(1, 1), qt.Qt.DisplayRole ) == scans[0].get_identifier().short_description() ) assert ( self._widget.model().data( self._widget.model().index(2, 1), qt.Qt.DisplayRole ) == scans[1].get_identifier().short_description() ) def testWithoutMetadata(self): """ make sure tomo obj are still displayed even if there is no metadata at all """ for scan in self.scans_without_metadata[::-1]: self._widget.model().addTomoObj(scan) # try adding some metadata to object scans = self._widget.model()._objs scans[0].stitching_metadata = StitchingMetadata(tomo_obj=scans[0]) scans[1].stitching_metadata = QStitchingMetadata(tomo_obj=scans[1]) scans[0].stitching_metadata._pos_as_px = (12, None, 2) scans[1].stitching_metadata._pos_as_px = (-12, None, None) scans[2].stitching_metadata._pos_as_px = (9999, None, None) self._widget.model().reorder_objs() self._widget.model().layoutChanged.emit() assert ( self._widget.model().data( self._widget.model().index(0, 1), qt.Qt.DisplayRole ) == scans[2].get_identifier().short_description() ) assert ( self._widget.model().data( self._widget.model().index(1, 1), qt.Qt.DisplayRole ) == scans[0].get_identifier().short_description() ) assert ( self._widget.model().data( self._widget.model().index(2, 1), qt.Qt.DisplayRole ) == scans[1].get_identifier().short_description() ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/stitching/z_stitching/tests/test_stitching_window.py0000644000175000017500000000272515143647637027616 0ustar00paynopaynofrom __future__ import annotations import os import shutil import tempfile import pint from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from tomwer.gui.stitching.tests.utils import create_scans_z_series from tomwer.gui.stitching.StitchingWindow import ZStitchingWindow _ureg = pint.get_application_registry() class TestZStichingWindow(TestCaseQt): """ Test high level z stitching definition """ def setUp(self): super().setUp() self._tmp_path = tempfile.mkdtemp() self.scans = create_scans_z_series( os.path.join(self._tmp_path, "case1"), z_positions_m=(0.200, 0.205, 0.210), sample_pixel_size=0.001, raw_frame_width=100, ) self._widget = ZStitchingWindow() def tearDown(self): self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None while self.qapp.hasPendingEvents(): self.qapp.processEvents() shutil.rmtree(self._tmp_path) @staticmethod def checkNbReceivers(scan, nb_receivers): return ( scan.stitching_metadata.receivers(scan.stitching_metadata.sigChanged) == nb_receivers ) def test(self): self._widget.show() # fill the widget with scans for scan in self.scans: self._widget.addTomoObj(scan) # note: add the sigChanged to the z ordered list 'update z' slot ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9451017 tomwer-1.6.17/src/tomwer/gui/tests/0000755000175000017500000000000015153325403016254 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/tests/__init__.py0000644000175000017500000000000014757047403020365 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/tests/test_axis_gui.py0000644000175000017500000000277715153325210021506 0ustar00paynopaynoimport pytest import numpy from tomwer.gui.reconstruction.axis.AxisSettingsWidget import AxisSettingsTabWidget from tomwer.synctools.axis import QAxisRP from tomwer.tests.utils import skip_gui_test from tomwer.tests.conftest import qtapp # noqa F401 @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") def test_get_nabu_cor_opts(qtapp): # noqa F811 axis_params = QAxisRP() widget = AxisSettingsTabWidget(recons_params=axis_params) assert axis_params.get_nabu_cor_options_as_dict() == { "side": "right", "radio_angles": (0.0, numpy.pi), "slice_idx": "middle", } widget._optionsWidget._corOpts.setText("low_pass=2.0") widget._optionsWidget._corOpts.editingFinished.emit() assert axis_params.get_nabu_cor_options_as_dict() == { "side": "right", "radio_angles": (0.0, numpy.pi), "slice_idx": "middle", "low_pass": 2.0, } widget._optionsWidget._corOpts.setText("low_pass=2 ; high_pass=10") widget._optionsWidget._corOpts.editingFinished.emit() assert axis_params.get_nabu_cor_options_as_dict() == { "side": "right", "radio_angles": (0.0, numpy.pi), "slice_idx": "middle", "low_pass": 2.0, "high_pass": 10.0, } widget._calculationWidget.setEstimatedCorValue("left") assert axis_params.get_nabu_cor_options_as_dict() == { "side": "left", "radio_angles": (0.0, numpy.pi), "slice_idx": "middle", "low_pass": 2.0, "high_pass": 10.0, } ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/tests/test_qfolder_dialog.py0000644000175000017500000000054014757047403022651 0ustar00paynopaynoimport pytest from tomwer.gui.dialog.QDataDialog import QDataDialog from tomwer.tests.conftest import qtapp # noqa F401 @pytest.mark.parametrize("multi_selection", (True, False)) def test_qdata_dialog( qtapp, # noqa F401 multi_selection, ): dialog = QDataDialog(parent=None, multiSelection=multi_selection) dialog.files_selected() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9451017 tomwer-1.6.17/src/tomwer/gui/utils/0000755000175000017500000000000015153325403016252 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/gui/utils/RangeWidget.py0000644000175000017500000000257515115744275021047 0ustar00paynopaynofrom __future__ import annotations import sys from silx.gui import qt from tomwer.gui.utils.scrollarea import QDoubleSpinBoxIgnoreWheel as QDoubleSpinBox class RangeWidget(qt.QWidget): """widget to select a range of float""" sigChanged = qt.Signal() def __init__(self, parent=None): super().__init__(parent) self.setLayout(qt.QHBoxLayout()) # start self.layout().addWidget(qt.QLabel("from")) self._startQLE = QDoubleSpinBox(self) self.layout().addWidget(self._startQLE) self._startQLE.setRange(sys.float_info.min, sys.float_info.max) # stop self.layout().addWidget(qt.QLabel("to")) self._stopQLE = QDoubleSpinBox(self) self.layout().addWidget(self._stopQLE) self._stopQLE.setRange(sys.float_info.min, sys.float_info.max) # connect signal / slot self._startQLE.editingFinished.connect(self.sigChanged) self._stopQLE.editingFinished.connect(self.sigChanged) def getRange(self) -> tuple[float]: return ( self._startQLE.value(), self._stopQLE.value(), ) def setRange(self, start: float, stop: float) -> None: self._startQLE.setValue(float(start)) self._stopQLE.setValue(float(stop)) def setSuffix(self, suffix: str): self._startQLE.setSuffix(suffix) self._stopQLE.setSuffix(suffix) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/utils/__init__.py0000644000175000017500000000010214757047403020366 0ustar00paynopaynofrom .utils import has_imagej, open_url_with_image_j # noqa F403 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/utils/buttons.py0000644000175000017500000001646715153325210020334 0ustar00paynopayno""" Button of general usage. """ from __future__ import annotations import pint import numpy import logging from silx.gui import qt from silx.gui.plot.tools.roi import RegionOfInterestManager from silx.gui.plot.items.roi import LineROI from silx.gui.plot.PlotToolButtons import PlotToolButton from tomwer.gui import icons _logger = logging.getLogger(__file__) _ureg = pint.get_application_registry() class PadlockButton(qt.QPushButton): """Simple button to define a button with PadLock icons""" sigLockChanged = qt.Signal(bool) """signal emitted when the lock status change""" def __init__(self, parent): qt.QPushButton.__init__(self, parent) self._lockIcon = icons.getQIcon("locked") self._unlockIcon = icons.getQIcon("unlocked") self.setIcon(self._unlockIcon) self.setCheckable(True) # connect signals self.toggled.connect(self._updateDisplay) def setLock(self, lock: bool): self.setChecked(lock) self._updateDisplay(lock) def _updateDisplay(self, checked): _icon = self._lockIcon if checked else self._unlockIcon self.setIcon(_icon) self.sigLockChanged.emit(checked) def isLocked(self) -> bool: return self.isChecked() class TabBrowsersButtons(qt.QWidget): """Simple widget containing buttons to go to 'next' or 'previous'""" sigPreviousReleased = qt.Signal() """emitted when the previous button is released""" sigNextReleased = qt.Signal() """emitted when the next button is released""" def __init__(self, parent=None): qt.QWidget.__init__(self, parent) self.setLayout(qt.QHBoxLayout()) # define gui style = qt.QApplication.style() self._previousButton = qt.QPushButton("previous", self) previous_icon = style.standardIcon(qt.QStyle.SP_ArrowLeft) self._previousButton.setIcon(previous_icon) self.layout().addWidget(self._previousButton) self._nextButton = qt.QPushButton("next", self) next_icon = style.standardIcon(qt.QStyle.SP_ArrowRight) self._nextButton.setIcon(next_icon) self.layout().addWidget(self._nextButton) spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) self.layout().addWidget(spacer) # connect signal / slot self._previousButton.released.connect(self._previousReleased) self._nextButton.released.connect(self._nextReleased) def _previousReleased(self, *args, **kwargs): self.sigPreviousReleased.emit() def _nextReleased(self, *args, **kwargs): self.sigNextReleased.emit() class TapeMeasureToolButton(PlotToolButton): """Button to active measurement between two point of the plot""" def __init__(self, parent=None, plot=None, pixel_size: pint.Quantity | None = None): super().__init__(parent=parent, plot=plot) self._roiManager = None self._lastRoiCreated = None self._pixel_size: pint.Quantity | None = pixel_size self.setIcon(icons.getQIcon("ruler")) self.setToolTip("measure distance between two pixels") self.toggled.connect(self._callback) self._connectPlot(plot) def setPlot(self, plot): return super().setPlot(plot) def setPixelSize(self, pixel_size: tuple[pint.Quantity, pint.Quantity] | None): self._pixel_size = pixel_size def _callback(self, toggled): if not self._roiManager: return if self._lastRoiCreated is not None: self._lastRoiCreated.setVisible(self.isChecked()) if self.isChecked(): self._roiManager.start( TapeMeasureROI, self, ) self.__interactiveModeStarted(self._roiManager) else: source = self._roiManager.getInteractionSource() if source is self: self._roiManager.stop() def __interactiveModeStarted(self, roiManager): roiManager.sigInteractiveModeFinished.connect(self.__interactiveModeFinished) def __interactiveModeFinished(self): roiManager = self._roiManager if roiManager is not None: roiManager.sigInteractiveModeFinished.disconnect( self.__interactiveModeFinished ) self.setChecked(False) def _connectPlot(self, plot): """ Called when the plot is connected to the widget :param plot: :class:`.PlotWidget` instance """ if plot is None: return self._roiManager = RegionOfInterestManager(plot) self._roiManager.setColor("yellow") # Set the color of ROI self._roiManager.sigRoiAdded.connect(self._registerCurrentROI) def _disconnectPlot(self, plot): if plot and self._lastRoiCreated is not None: self._roiManager.removeRoi(self._lastRoiCreated) self._lastRoiCreated = None return super()._disconnectPlot(plot) def _registerCurrentROI(self, currentRoi): if self._lastRoiCreated is None: self._lastRoiCreated = currentRoi self._lastRoiCreated.setPixelSize(self._pixel_size) elif currentRoi != self._lastRoiCreated and self._roiManager is not None: self._roiManager.removeRoi(self._lastRoiCreated) self._lastRoiCreated = currentRoi self._lastRoiCreated.setPixelSize(self._pixel_size) class TapeMeasureROI(LineROI): """ROI dedicated to tape measure""" def __init__(self, parent=None, pixel_size: pint.Quantity | None = None): super().__init__(parent) self._pixel_size: pint.Quantity | None = None self.setPixelSize(pixel_size) def setEndPoints(self, startPoint, endPoint): distance_px = numpy.linalg.norm(endPoint - startPoint) super().setEndPoints(startPoint=startPoint, endPoint=endPoint) if self._pixel_size is None: self._updateText(f"{distance_px :.1f}px") else: distance_m = distance_px * self._pixel_size value = self.cast_metric_to_best_unit(distance_m) self._updateText(f"{value:.4f~P}") def setPixelSize(self, pixel_size: tuple[pint.Quantity]): if isinstance(pixel_size, (tuple, list)): assert ( len(pixel_size) == 2 ), "expects at most two pixel size values (x and y values)" if not numpy.isclose( pixel_size[0].to_base_units(), pixel_size[1].to_base_units() ): value = self.cast_metric_to_best_unit(pixel_size[0]) _logger.warning( f"TapeMeasure is only handling square pixels for now. Will consider the pixel is {value:.4f~P}x{value:.4f~P}" ) pixel_size = pixel_size[0] self._pixel_size = pixel_size @staticmethod def cast_metric_to_best_unit(value: pint.Quantity) -> pint.Quantity: value = value.to_base_units() if value < (1.0 * _ureg.micrometer): return value.to(_ureg.nanometer) elif value < (0.1 * _ureg.millimeter): # prefer mm to um return value.to(_ureg.micrometer) elif value < (1.0 * _ureg.centimeter): return value.to(_ureg.millimeter) elif value < (1.0 * _ureg.meter): return value.to(_ureg.centimeter) else: return value.to(_ureg.meter) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/utils/completer.py0000644000175000017500000000702614757047403020635 0ustar00paynopayno"""module defining dedicated completer""" from __future__ import annotations from silx.gui import qt class _CodeCompleter(qt.QCompleter): ConcatenationRole = qt.Qt.UserRole + 1 def __init__(self, data, parent=None): super().__init__(parent) self.create_model(data) def pathFromIndex(self, ix): return ix.data(_CodeCompleter.ConcatenationRole) def create_model(self, data): def addItems(parent, elements, t=""): for text in elements: item = qt.QStandardItem(text) data = t + "." + text if t else text item.setData(data, _CodeCompleter.ConcatenationRole) parent.appendRow(item) model = qt.QStandardItemModel(self) addItems(model, data) self.setModel(model) class _LineEditWithCompleter(qt.QLineEdit): def __init__(self, completer, parent=None, data_type="url"): super().__init__(parent) self._completer = completer def keyPressEvent(self, key_event): # add Ctr + space for completion modifiers = key_event.modifiers() if qt.Qt.KeyboardModifier.ControlModifier == modifiers: if key_event.key() == qt.Qt.Key.Key_Space: self._completer.complete(self.rect()) super().keyPressEvent(key_event) class _TextCompleterWidget(qt.QWidget): """ Simple widget to ease text research. """ sigTextSelected = qt.Signal(str) def __init__(self, texts: tuple, parent=None) -> None: if not isinstance(texts, tuple): raise TypeError("texts is expected to be a tuple.") super().__init__(parent) layout = qt.QVBoxLayout() self.setLayout(layout) self._completer = _CodeCompleter(texts, self) self._lineEdit = _LineEditWithCompleter(parent=self, completer=self._completer) self._lineEdit.setCompleter(self._completer) layout.addWidget(self._lineEdit) def setText(self, text: str) -> None: self._lineEdit.setText(text) def text(self) -> str: return self._lineEdit.text() class UrlCompleterDialog(qt.QDialog): def __init__( self, urls: tuple, parent=None, current_url: str | None = None ) -> None: super().__init__(parent) self._urls = urls self.setWindowTitle("Url research") self.setLayout(qt.QVBoxLayout()) self._completerWidget = _TextCompleterWidget(texts=urls, parent=self) self._completerWidget.setToolTip( "You can complete url. Use ctr + space to complete" ) if current_url is not None: self._completerWidget.setText(current_url) self.layout().addWidget(self._completerWidget) types = qt.QDialogButtonBox.Cancel | qt.QDialogButtonBox.Ok self._buttons = qt.QDialogButtonBox(self) self._buttons.setStandardButtons(types) self.layout().addWidget(self._buttons) # connect signal / slot self._buttons.button(qt.QDialogButtonBox.Cancel).released.connect(self.reject) self._buttons.button(qt.QDialogButtonBox.Ok).released.connect(self.accept) self._completerWidget._lineEdit.textChanged.connect( self._updateOkButtonAvailability ) def _updateOkButtonAvailability(self, *args, **kwargs): ok_enable = self._completerWidget.text() in self._urls self._buttons.button(qt.QDialogButtonBox.Ok).setEnabled(ok_enable) def selected_url(self): return self._completerWidget.text() def sizeHint(self): return qt.QSize(600, 100) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/gui/utils/flow.py0000644000175000017500000002462615115744275017617 0ustar00paynopaynofrom __future__ import annotations import functools from typing import Iterable from silx.gui import qt from enum import Enum as _Enum from tomwer.gui import icons from tomwer.utils import docstring class FlowDirection(_Enum): HORIZONTAL = "horizontal" VERTICAL = "vertical" class _ProcessDescWidget(qt.QWidget): """Widget to describe the process""" ICON_WIDTH = 16 def __init__(self, parent, process, icon, direction, locked, show_lock_state=True): assert isinstance(direction, FlowDirection) super(_ProcessDescWidget, self).__init__(parent=parent) self.__active = False if direction is FlowDirection.VERTICAL: self.setLayout(qt.QHBoxLayout()) else: self.setLayout(qt.QVBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) # lock icon self._lockIcon = qt.QLabel("", parent=self) self._lockIcon.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum) self._lockIcon.setAlignment(qt.Qt.AlignRight | qt.Qt.AlignTop) if locked: locked_icon = icons.getQIcon("locked") else: locked_icon = icons.getQIcon("unlocked") self._lockIcon.setPixmap(locked_icon.pixmap(20, 20)) self._lockIcon.setVisible(show_lock_state) # process name + process icon self.main_widget = qt.QWidget(parent=self) self.main_widget.setLayout(qt.QHBoxLayout()) self._label = qt.QLabel(str(process), self) self._label.setAlignment(qt.Qt.AlignCenter) self._label.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) self.main_widget.layout().addWidget(self._label) if icon is not None: self._frame = qt.QLabel(self) self._frame.setPixmap( icon.pixmap( qt.QSize( _ProcessDescWidget.ICON_WIDTH, _ProcessDescWidget.ICON_WIDTH ) ) ) self.main_widget.layout().addWidget(self._frame) # main_widget.layout().addWidget(icon_label) if direction is FlowDirection.VERTICAL: self.layout().addWidget(self.main_widget) self.layout().addWidget(self._lockIcon) else: self.layout().addWidget(self._lockIcon) self.layout().addWidget(self.main_widget) # expose API self.process = process def setActive(self, active: bool) -> None: """ set the widget as active or inactive. This will put or remove the focus on. :param active: """ self.__active = active if active: stylesheet = "border: 1px solid red" else: stylesheet = "" self.main_widget.setStyleSheet(stylesheet) if hasattr(self, "_frame"): self._frame.setStyleSheet("border: 0px") self._label.setStyleSheet("border: 0px") def isActive(self) -> bool: """ :return: is the widget active / focus / under edition """ return self.__active class _ProcessDescContainer(qt.QWidget): """simple docker for the process description :param parent: :param process: any object implementing the `__str__` interface :param icon: :raises: TypeError if process does not implements __str__ """ sigWidgetActivated = qt.Signal() """Signal emitted when the contained widget become the active process.""" sigWidgetDeactivated = qt.Signal() """Signal emitted when the contained widget is deactivated (not the active process anymore)""" def __init__( self, parent, process, icon, direction, draggable, show_lock_state=True ): if not hasattr(process, "__str__"): raise TypeError("name should implement `__str__`") super(_ProcessDescContainer, self).__init__(parent=parent) self._widget = _ProcessDescWidget( parent=self, process=process, icon=icon, direction=direction, locked=not draggable, show_lock_state=show_lock_state, ) self.setLayout(qt.QVBoxLayout()) self.setContentsMargins(0, 0, 0, 0) self.layout().addWidget(self._widget) # expose API self.process = self._widget.process self._draggable = draggable def event(self, QEvent): if ( QEvent.type() == qt.QEvent.MouseButtonPress and QEvent.button() == qt.Qt.LeftButton ): self._setIsOnFocus() return super(_ProcessDescContainer, self).event(QEvent) def _setIsOnFocus(self): if self._widget.isActive(): self.sigWidgetDeactivated.emit() else: self.sigWidgetActivated.emit() @docstring(_ProcessDescWidget) def setActive(self, active): self._widget.setActive(active=active) if active: self.sigWidgetActivated.emit() else: self.sigWidgetDeactivated.emit() @docstring(_ProcessDescWidget) def isActive(self): return self._widget.isActive() class FlowCanvas(qt.QWidget): """ Widget to describe a flow of process - pipeline :param direction: direction can be vertical or horizontal """ sigWidgetActivated = qt.Signal() """Signal emitted when the contained widget become the active process.""" sigWidgetDeactivated = qt.Signal() """Signal emitted when the contained widget is deactivated (not the active process anymore)""" def __init__( self, parent, direction: str | FlowDirection, show_lock_state=True ) -> None: qt.QWidget.__init__(self, parent=parent) self._direction = FlowDirection(direction) if self._direction is FlowDirection.HORIZONTAL: layout = qt.QHBoxLayout() elif self._direction is FlowDirection.VERTICAL: layout = qt.QVBoxLayout() else: raise ValueError("direction not managed") self.setLayout(layout) self.setWindowFlags(qt.Qt.Widget) self.layout().setContentsMargins(0, 0, 0, 0) self.layout().setSpacing(0) self._dockers = {} self._process_id = 0 self._show_lock_state = show_lock_state if self._direction is FlowDirection.HORIZONTAL: self._dockArea = qt.Qt.TopDockWidgetArea elif self._direction is FlowDirection.VERTICAL: self._dockArea = qt.Qt.LeftDockWidgetArea else: raise ValueError("direction not managed") def getFlow(self) -> list: """Return the list of process following the treatment flow""" widgetXPos = {} # retrieve each docker position for process_id, dockWidget in self._dockers.items(): if self._direction is FlowDirection.HORIZONTAL: widgetXPos[process_id] = dockWidget.pos().x() else: widgetXPos[process_id] = dockWidget.pos().y() # order the widget / process according to res = [] for widgetIndex, _ in sorted(widgetXPos.items(), key=lambda item: item[1]): res.append(self._dockers[widgetIndex].process) return res def addProcess(self, process, icon=None, draggable=True) -> int: """ Add a process to the flow with the name 'process' and an optional icon :param process_name: any object. Should implement the __str__ interface to define the name if no icon is given :return: process id in the process flow """ if icon is None: assert hasattr(process, "__str__") widget = _ProcessDescContainer( parent=self, process=process, icon=icon, direction=self._direction, draggable=draggable, show_lock_state=self._show_lock_state, ) self.layout().addWidget(widget) process_id = self._process_id self._dockers[self._process_id] = widget self._process_id += 1 # connect signals / slots widget.sigWidgetActivated.connect( functools.partial(self._activeProcessChanged, process_id) ) widget.sigWidgetDeactivated.connect( functools.partial(self._activeProcessChanged, None) ) return process_id def _activeProcessChanged(self, active_process): for process_id, dock in self._dockers.items(): old = dock.blockSignals(True) dock.setActive(active_process == process_id) dock.blockSignals(old) if active_process is None: self.sigWidgetDeactivated.emit() else: self.sigWidgetActivated.emit() def removeProcess(self, process_id: int) -> None: """ :param process_id: id of the process to remove from the flow """ if process_id in self._dockers: dockWidget = self._dockers[process_id] self.layout().removeWidget(dockWidget) del self._dockers[process_id] def clear(self): processes_id = self._dockers.keys() for process_id in processes_id: self.removeProcess(process_id=process_id) def setProcesses( self, processes: Iterable, icons: Iterable, draggability: Iterable ) -> None: """ :param processes: processes of the flow :param icons: icons associated to the flow :param draggability: is the process draggable or not :return: """ for process, icon, draggable in zip(processes, icons, draggability): self.addProcess(process=process, draggable=draggable, icon=icon) def clearActiveProcess(self) -> None: """ Set all process to unactive """ for dock in self._dockers.values(): old = dock.blockSignals(True) dock.setActive(False) dock.blockSignals(old) def hasProcessFocus(self) -> bool: """ :return: True if the canvas has a process active / focus ... """ return self.getProcessFocused() is not None def getProcessFocused(self) -> int | None: """ :return: id of the process focus or None if no process focus """ for process_id, dock in self._dockers.items(): if dock.isActive(): return process_id return None def _removeActiveProcess(self): process_id = self.getProcessFocused() if process_id is not None: self.removeProcess(process_id=process_id) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/utils/gpu.py0000644000175000017500000000512315143647637017437 0ustar00paynopaynofrom __future__ import annotations import logging try: from nabu.cuda.utils import collect_cuda_gpus except ImportError: raise except Exception: _has_collect_cuda_gpus = False else: # issue with cuda driver. see https://gitlab.esrf.fr/tomotools/tomwer/-/issues/1515 _has_collect_cuda_gpus = True from silx.gui import qt _logger = logging.getLogger(__name__) class SelectGPUGroupBox(qt.QGroupBox): """Interface to select a (local) GPU""" sigGPUChanged = qt.Signal() """Emit when the selected GPU changed""" def __init__(self, parent=None, title="select (local) GPU"): super().__init__(parent=parent, title=title) self.setCheckable(True) self.setLayout(qt.QFormLayout()) if _has_collect_cuda_gpus: self.__cuda_gpus = collect_cuda_gpus() or {} else: _logger.warning("Fail to found cuda devices") self.__cuda_gpus = {} # warn user if no gpu found: reconstruction will work but will take way more time if len(self.__cuda_gpus) == 0: style = qt.QApplication.style() icon = style.standardIcon(qt.QStyle.SP_MessageBoxWarning) self.__iconLabel = qt.QLabel(parent=self) self.__iconLabel.setPixmap(icon.pixmap(80, 80)) self.__noGPULabel = qt.QLabel("No cuda GPU detected") self.__noGPULabel.setToolTip( "No cuda GPU device detected. Reconstruction will be done on CPU which is much more slower" ) self.layout().addRow(self.__iconLabel, self.__noGPULabel) self._gpusCB = qt.QComboBox(self) for gpu_id, gpu_desc in self.__cuda_gpus.items(): name = gpu_desc.get("name", f"unknown gpu {gpu_id}") self._gpusCB.addItem(f"{name} (id-{gpu_id})", gpu_id) self.layout().addRow(self._gpusCB) # connect signal / slot self._gpusCB.currentIndexChanged.connect(self.__GPUChanged) @property def cuda_gpus(self) -> dict: return self.__cudaGPUs def getSelectedGPUId(self) -> int | None: if self.isChecked(): selected_gpu = self._gpusCB.currentIndex() if selected_gpu == -1: return None else: return self._gpusCB.itemData(selected_gpu, qt.Qt.UserRole) else: return None def setSelectedGPUId(self, value: int): cb_index = self._gpusCB.findData(value, role=qt.Qt.UserRole) if cb_index >= 0: self._gpusCB.setCurrentIndex(cb_index) def __GPUChanged(self, *args, **kwargs): self.sigGPUChanged.emit() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/utils/host_editor.py0000644000175000017500000001225615143647637021174 0ustar00paynopaynofrom __future__ import annotations import logging import socket from contextlib import contextmanager from multiprocessing import cpu_count from multiprocessing.pool import ThreadPool from silx.gui import qt from tomwer.core.settings import TOMO_BEAMLINES _logger = logging.getLogger(__name__) class _PingHosts(qt.QThread): def __init__(self, *args, hosts_to_ping: tuple[str], port: int, **kwargs): super().__init__(*args, **kwargs) self._hosts_to_ping = hosts_to_ping self._port = port self._accessibility: dict[str, bool] = {} @staticmethod def can_ping_host(host_name: str, port: int, timeout_s: float = 0.5) -> bool: """ Checks if a host is reachable on a specific TCP port. Returns True if reachable, False otherwise. """ sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.settimeout(timeout_s) try: sock.connect((host_name, port)) except (socket.timeout, socket.error): return False else: return True finally: sock.close() def run(self): pool = ThreadPool(processes=min(cpu_count(), 4)) result = pool.map( lambda host: self.can_ping_host(host_name=host, port=self._port), self._hosts_to_ping, ) pool.close() pool.join() self._accessibility = { host: accessibility for host, accessibility in zip(self._hosts_to_ping, result) } def getHostsAccessibility(self) -> dict[str, bool]: return self._accessibility class RightIconDelegate(qt.QStyledItemDelegate): def paint(self, painter, option, index): # Set the decorationPosition to Right option.decorationPosition = qt.QStyleOptionViewItem.Right # Call the base class's paint method to draw the item with the modified option super().paint(painter, option, index) class HostEditor(qt.QComboBox): """ An editable QCombobox that proposes some beamline in order to select an host. Use case: blissdata listener """ def __init__( self, *args, hosts: tuple[str] = TOMO_BEAMLINES, name: str | None, port: int = 25000, enable_host_pinging: bool = True, **kwargs, ): super().__init__(*args, **kwargs) if not isinstance(port, int): raise TypeError(f"port is expected to be an int. Got {type(port)}") self.__hosts = hosts self.__port = port self.__pingerThread = None # thread to check which host are accessible self.__enable_host_pinging = enable_host_pinging self.addItems(hosts) self.setPlaceholderText("id00 or 192.0.2.1") # let user use another name or an ip directly self.setEditable(True) self._updateIcons() # set up if name: self.setCurrentText(name) self.__delegate = RightIconDelegate() self.setItemDelegate(self.__delegate) def _getPingerThread(self): return self.__pingerThread def setCurrentText(self, *args, **kwargs): super().setCurrentText(*args, **kwargs) def setCurrentIndex(self, index): return super().setCurrentIndex(index) def setPort(self, port: int): """Defines the port to be used for checking host accessibility""" if port != self.__port: self.__port = port self._updateIcons() def __setAccessibleHost(self, host_accessibility: dict[str, bool]): """ Set icons of the ComBox according to the host accessibility. Red: cannot reach it, green can. """ with _keepCurrentText(self): # for some reason the current text is modified by this section... style = qt.QApplication.style() accessible_icon = style.standardIcon(qt.QStyle.SP_DialogYesButton) not_accessible_icon = style.standardIcon(qt.QStyle.SP_DialogNoButton) for host_name, can_be_access in host_accessibility.items(): idx = self.findText(host_name) if idx >= 0: icon = accessible_icon if can_be_access else not_accessible_icon self.setItemIcon(idx, icon) else: _logger.error(f"Cannot find host name {host_name}.") self.__pingerThread = None def _updateIcons(self): if not self.__enable_host_pinging: return if self.__pingerThread is not None: _logger.warning("Updating icons is already on-going") return self.__pingerThread = _PingHosts( hosts_to_ping=self.__hosts, port=self.__port, parent=self ) self.__pingerThread.finished.connect( lambda: self.__setAccessibleHost( self.__pingerThread.getHostsAccessibility() ) ) self.__pingerThread.start() def close(self): if self.__pingerThread is not None: self.__pingerThread.wait() return super().close() @contextmanager def _keepCurrentText(w: qt.QComboBox): old = w.currentText() try: yield finally: w.setCurrentText(old) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/utils/illustrations.py0000644000175000017500000000606515153325210021543 0ustar00paynopayno# coding: utf-8 """ Some utils GUI associated to illustrations """ from __future__ import annotations from silx.gui import qt from tomwer.gui import illustrations class _IllustrationWidget(qt.QWidget): """Simple widget to display an image keeping the aspect ratio""" def __init__(self, parent, img=None): super().__init__(parent) self._ratio = 1.0 self._oPixmap = None """Pixmap containing the image to display""" self.setLayout(qt.QGridLayout()) try: self._display = qt.QSvgWidget(parent=self) self._use_svg = True except Exception: self._display = qt.QLabel(parent=self) self._use_svg = False self.layout().setContentsMargins(0, 0, 0, 0) self.layout().setSpacing(0) self._display.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding) self.layout().addWidget(self._display, 0, 0) spacer1 = qt.QWidget(self) spacer1.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.MinimumExpanding) self.layout().addWidget(spacer1, 0, 1) spacer2 = qt.QWidget(self) spacer2.setSizePolicy(qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.Minimum) self.layout().addWidget(spacer2, 1, 0) if img: assert isinstance(img, str) self.setImage(img) def heightForWidth(self, width): return width * self._ratio def widthForHeight(self, height): return height / self._ratio def resizeEvent(self, event): width = event.size().width() height = self.heightForWidth(width) if height > event.size().height(): height = event.size().height() width = self.widthForHeight(height) self._display.resize(int(width), int(height)) if self.isUsingSvg() is False: self._updatePixamp() def setImage(self, image): _image = image.replace(" ", "_") self._ratio = 1.0 self._oPixmap = illustrations.getQPixmap(_image) self._ratio = self._oPixmap.height() / self._oPixmap.width() if type(self._display) is qt.QLabel: self._updatePixamp() else: self._display.load(illustrations.getResourceFileName(_image + ".svg")) def _updatePixamp(self): pixmap = self._oPixmap.scaled(self.width(), self.height()) self._display.setPixmap(pixmap) def isUsingSvg(self): return self._use_svg class _IllustrationDialog(qt.QDialog): def __init__(self, parent, title, img): qt.QDialog.__init__(self, parent) self.setWindowTitle(title) self.setLayout(qt.QVBoxLayout()) self._illustration = _IllustrationWidget(parent=self, img=img) self.layout().addWidget(self._illustration) types = qt.QDialogButtonBox.Ok self.__buttons = qt.QDialogButtonBox(parent=self) self.__buttons.setStandardButtons(types) self.layout().addWidget(self.__buttons) self.__buttons.accepted.connect(self.accept) def sizeHint(self): return qt.QSize(300, 300) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/utils/inputwidget.py0000644000175000017500000005444015153325210021172 0ustar00paynopaynofrom __future__ import annotations import logging import os import numpy from nxtomomill.models.h52nx import H52nxModel from nxtomomill.models.edf2nx import EDF2nxModel from silx.gui import qt from tomoscan.identifier import BaseIdentifier from tomwer.gui import icons from tomwer.gui.qlefilesystem import QLFileSystem from tomwer.gui.utils.qt_utils import block_signals from tomwer.io.utils import get_default_directory from tomwer.core.volume.volumefactory import VolumeFactory from tomwer.core.process.output import ProcessDataOutputDirMode from tomwer.core.volume import ( EDFVolume, HDF5Volume, JP2KVolume, RawVolume, TIFFVolume, MultiTIFFVolume, ) _logger = logging.getLogger(__name__) class SelectionLineEdit(qt.QWidget): """Line edit with several type of selection possible: * a single value * a range of value on the type min:max:step * a list of value: val1, val2, ... """ # SINGLE_MODE = 'single' RANGE_MODE = "range" LIST_MODE = "list" # SELECTION_MODES = (SINGLE_MODE, RANGE_MODE, LIST_MODE) SELECTION_MODES = (RANGE_MODE, LIST_MODE) _DEFAULT_SELECTION = LIST_MODE def __init__(self, text=None, parent=None, allow_negative_indices=False): qt.QWidget.__init__(self, parent) self.setLayout(qt.QHBoxLayout()) self._qLineEdit = qt.QLineEdit(parent=self) if allow_negative_indices: fpm = "\\-?\\d*\\.?\\d+" # float or int matching else: fpm = "\\d*\\.?\\d+" # float or int matching qRegExp = qt.QRegularExpression( "(" + fpm + "[;]?[,]?[ ]?){1,}" + "|" + ":".join((fpm, fpm, fpm)) ) self._qLineEdit.setValidator(qt.QRegularExpressionValidator(qRegExp)) self.layout().addWidget(self._qLineEdit) self._button = SelectionModeButton(parent=self) self.layout().addWidget(self._button) # QObject signal connections self._qLineEdit.textChanged.connect(self._checkIfModeChanged) self._button.sigModeChanged.connect(self._modeChanged) # expose API self.setText = self._qLineEdit.setText self.editingFinished = self._qLineEdit.editingFinished self.textChanged = self._qLineEdit.textChanged self.text = self._qLineEdit.text if text is not None: self._qLineEdit.setText(str(text)) # update place holders self._modeChanged(self._button.mode) def getMode(self): return self._button.mode @property def selection(self): if self._qLineEdit.hasAcceptableInput(): if self._button.mode == self.RANGE_MODE: _from, _to, _step = self._qLineEdit.text().split(":") _from, _to, _step = float(_from), float(_to), float(_step) if _from > _to: _logger.warning(f"to > from, invert {_from} and {_to}") tmp = _to _to = _from _from = tmp num = int((_to - _from) / _step) return tuple( numpy.linspace(start=_from, stop=_to, num=num, endpoint=True) ) else: vals = self._qLineEdit.text().replace(" ", "") vals = vals.replace(";", ",").split(",") res = [] [res.append(float(val)) for val in vals] if len(res) == 1: return res[0] else: return tuple(res) else: _logger.warning("Wrong input, invalid selection") return None def _checkIfModeChanged(self, _str): with block_signals(self._button): if _str.count(":") > 0: self._button.mode = self.RANGE_MODE else: self._button.mode = self.LIST_MODE def _modeChanged(self, mode): if mode == self.RANGE_MODE: text = "from:to:step" elif mode == self.LIST_MODE: text = "val1; val2; ..." else: raise ValueError("unknown mode") with block_signals(self._qLineEdit): self._qLineEdit.setPlaceholderText(text) class SelectionModeButton(qt.QToolButton): """Base class for Selection QAction. :param mode: the mode of selection of the action. :param text: The name of this action to be used for menu label :param tooltip: The text of the tooltip :param triggered: The callback to connect to the action's triggered signal or None for no callback. """ sigModeChanged = qt.Signal(str) """signal emit when the mode is changed""" def __init__(self, parent=None, tooltip=None, triggered=None): qt.QToolButton.__init__(self, parent) self._states = {} self._mode = None for mode in SelectionLineEdit.SELECTION_MODES: icon = icons.getQIcon("_".join([mode, "selection"])) self._states[mode] = (icon, self._getTooltip(mode)) self._rangeAction = RangeSelAction(parent=self) self._listAction = ListSelAction(parent=self) for _action in (self._rangeAction, self._listAction): _action.sigModeChanged.connect(self._modeChanged) menu = qt.QMenu(self) menu.addAction(self._rangeAction) menu.addAction(self._listAction) self.setMenu(menu) self.setPopupMode(qt.QToolButton.InstantPopup) self.mode = SelectionLineEdit.LIST_MODE def _getTooltip(self, mode): # if mode == SelectionLineEdit.SINGLE_MODE: # return 'Define only one value for this parameter' if mode == SelectionLineEdit.LIST_MODE: return ( "Define a single value or a list of values for this " "parameter (va1; val2)" ) elif mode == SelectionLineEdit.RANGE_MODE: return "Define a range of value for this parameter (from:to:step)" else: raise ValueError("unknown mode") def _modeChanged(self, mode): self.mode = mode @property def mode(self): return self._mode @mode.setter def mode(self, mode): assert mode in SelectionLineEdit.SELECTION_MODES if mode != self._mode: self._mode = mode self.setIcon(icons.getQIcon("_".join([mode, "selection"]))) self.setToolTip(self._getTooltip(mode)) self.sigModeChanged.emit(self._mode) class SelectionAction(qt.QAction): """ Base class of the several selection mode """ sigModeChanged = qt.Signal(str) """emit when the mode change""" def __init__(self, mode, parent, text): icon = icons.getQIcon("_".join([mode, "selection"])) qt.QAction.__init__(self, icon, text, parent) self.setIconVisibleInMenu(True) self._mode = mode self.triggered.connect(self._modeChanged) def _modeChanged(self, *args, **kwargs): self.sigModeChanged.emit(self._mode) class RangeSelAction(SelectionAction): """ Action to select a range of element on the scheme from:to:step """ def __init__(self, parent=None): SelectionAction.__init__( self, mode=SelectionLineEdit.RANGE_MODE, parent=parent, text="range selection", ) class ListSelAction(SelectionAction): """ Action to select a list of element on the scheme elmt1, elmt2, ... """ def __init__(self, parent=None): SelectionAction.__init__( self, mode=SelectionLineEdit.LIST_MODE, parent=parent, text="list selection" ) class NXTomomillOutputDirSelector(qt.QWidget): sigChanged = qt.Signal() """Signal emit when the output directory of the nx file change""" def __init__(self, parent=None): qt.QWidget.__init__(self, parent) self.setLayout(qt.QGridLayout()) self.__buttonGroup = qt.QButtonGroup(self) self.__buttonGroup.setExclusive(True) tooltip = """Define the output directory of the nexus (.nx) file. Options are: \n - same folder as scan: create the NXtomos at the same level as the bliss input file or spec folder \n - 'PROCESSED_DATA' folder: create NXtomos on the default 'PROCESSED_DATA' folder (bliss default folder, nearby the 'raw' folder). \n - user defined folder: users can provide their own folders using keywords for string formatting such as 'scan_dir_name', 'scan_basename' or 'scan_parent_dir_basename', 'scan_file_name' and 'scan_entry' """ # output dir is the folder containing the .nx file self._inScanFolder = qt.QRadioButton("same folder as scan", self) self._inScanFolder.setToolTip(tooltip) self.layout().addWidget(self._inScanFolder, 0, 0, 1, 1) self.__buttonGroup.addButton(self._inScanFolder) # output dir is the default 'reduced'folder self._processedDataFolderRB = qt.QRadioButton("'PROCESSED_DATA' folder", self) self._processedDataFolderRB.setToolTip(tooltip) self.layout().addWidget(self._processedDataFolderRB, 1, 0, 1, 1) self.__buttonGroup.addButton(self._processedDataFolderRB) # manual self._manualRB = qt.QRadioButton("custom output directory", self) self._manualRB.setToolTip(tooltip) self.layout().addWidget(self._manualRB, 3, 0, 1, 1) self._outputFolderQLE = QLFileSystem("", self) self.layout().addWidget(self._outputFolderQLE, 3, 1, 1, 1) self._selectButton = qt.QPushButton("", self) style = qt.QApplication.style() icon_opendir = style.standardIcon(qt.QStyle.SP_DirOpenIcon) self._selectButton.setIcon(icon_opendir) self._selectButton.setToolTip("select output directory") self.layout().addWidget(self._selectButton, 3, 2, 1, 1) self.__buttonGroup.addButton(self._manualRB) # connect signal / slot self._selectButton.released.connect(self._selectOutpuFolder) self.__buttonGroup.buttonReleased.connect(self._updateVisiblity) self._inScanFolder.toggled.connect(self.sigChanged) self._processedDataFolderRB.toggled.connect(self.sigChanged) self._manualRB.toggled.connect(self.sigChanged) self._outputFolderQLE.editingFinished.connect(self.sigChanged) # set up self._processedDataFolderRB.setChecked(True) self._updateVisiblity() def _updateVisiblity(self, *args, **kwargs): self._selectButton.setVisible(self._manualRB.isChecked()) self._outputFolderQLE.setVisible(self._manualRB.isChecked()) def _selectOutpuFolder(self): # pragma: no cover defaultDirectory = self._outputFolderQLE.text() if os.path.isdir(defaultDirectory): defaultDirectory = get_default_directory() dialog = qt.QFileDialog(self, directory=defaultDirectory) dialog.setFileMode(qt.QFileDialog.DirectoryOnly) if not dialog.exec(): dialog.close() return self._outputFolderQLE.setText(dialog.selectedFiles()[0]) self.sigChanged.emit() def getOutputFolder(self) -> str | ProcessDataOutputDirMode: if self._manualRB.isChecked(): return self._outputFolderQLE.text() elif self._processedDataFolderRB.isChecked(): return ProcessDataOutputDirMode.PROCESSED_DATA_FOLDER elif self._inScanFolder.isChecked(): return ProcessDataOutputDirMode.IN_SCAN_FOLDER else: raise RuntimeError("Use case - h52nx output dir - not handled") def setOutputFolder(self, output_folder: str): with block_signals(self): self._manualRB.setChecked(output_folder is not None) try: default_output = ProcessDataOutputDirMode.from_value(output_folder) except ValueError: self._outputFolderQLE.setText(output_folder) self._manualRB.setChecked(True) else: if default_output is ProcessDataOutputDirMode.IN_SCAN_FOLDER: self._inScanFolder.setChecked(True) elif default_output is ProcessDataOutputDirMode.PROCESSED_DATA_FOLDER: self._processedDataFolderRB.setChecked(True) else: raise ValueError(f"default output not handled ({default_output})") finally: self._updateVisiblity() class _ConfigFileSelector(qt.QWidget): """Widget used to select a configuration file. Originally used for NXtomomill""" sigConfigFileChanged = qt.Signal(str) """signal emitted when the edition of the file path is finished""" def __init__(self, parent=None, try_load_cfg: bool = True): """ :param try_load_cfg: If True then when a file path is provided will try to load the configuration using '_load_config' and display error if the file is malformed """ super().__init__(parent) self._try_load_cfg = try_load_cfg self.setLayout(qt.QHBoxLayout()) self._lineEdit = QLFileSystem("", self) self.layout().addWidget(self._lineEdit) self._selectButton = qt.QPushButton("select", self) self.layout().addWidget(self._selectButton) style = qt.QApplication.instance().style() icon = style.standardIcon(qt.QStyle.SP_DialogResetButton) self._clearButton = qt.QPushButton(self) self._clearButton.setIcon(icon) self.layout().addWidget(self._clearButton) # connect signal / slot button self._clearButton.released.connect(self._clearFilePath) self._selectButton.released.connect(self._selectCFGFile) self._lineEdit.editingFinished.connect(self._editedFinished) def _clearFilePath(self): self._lineEdit.clear() def _selectCFGFile(self): # pragma: no cover dialog = qt.QFileDialog(self) dialog.setFileMode(qt.QFileDialog.ExistingFile) if not dialog.exec(): dialog.close() return if len(dialog.selectedFiles()) > 0: file_path = dialog.selectedFiles()[0] self.setCFGFilePath(file_path) def _editedFinished(self): # try to convert the file and inform the use if this fails cfg_file = self.getCFGFilePath() if cfg_file not in (None, ""): if self._try_load_cfg: try: self._load_config_file(cfg_file) except Exception as e: mess = f"Fail to load nxtomomill configuration from {cfg_file}. Error is {e}" _logger.warning(mess) qt.QMessageBox.warning( self, "Unable to read configuration from file", mess ) else: _logger.info(f"Will use {cfg_file} as input configuration file.") self.sigConfigFileChanged.emit(cfg_file) def getCFGFilePath(self): return self._lineEdit.text() def setCFGFilePath(self, cfg_file): self._lineEdit.setText(cfg_file) self._lineEdit.editingFinished.emit() def _load_config_file(self, cfg_file: str): raise NotImplementedError("Base class") class HDF5ConfigFileSelector(_ConfigFileSelector): def _load_config_file(self, cfg_file: str): H52nxModel.from_cfg_file(cfg_file) class EDFConfigFileSelector(_ConfigFileSelector): def _load_config_file(self, cfg_file: str): EDF2nxModel.from_cfg_file(cfg_file) class OutputVolumeDefinition(qt.QWidget): DEFAULT_DATA_PATH = "stitched_volume" _OUTPUT_FILE_PATH_TXT = "output file" _OUTPUT_FOLDER_PATH_TXT = "output folder" def __init__(self, parent=None) -> None: super().__init__(parent) self.setLayout(qt.QGridLayout()) # define format self._formatLabel = qt.QLabel("format", self) self.layout().addWidget(self._formatLabel, 0, 0, 1, 1) self._outputFileFormatCB = qt.QComboBox(parent=self) self._outputFileFormatCB.addItem("hdf5") for volume in (EDFVolume, JP2KVolume, RawVolume, TIFFVolume): self._outputFileFormatCB.addItem(volume.DEFAULT_DATA_EXTENSION) self.layout().addWidget(self._outputFileFormatCB, 0, 1, 1, 2) # output file or folder self._outputFileLabel = qt.QLabel("", self) self.layout().addWidget(self._outputFileLabel, 1, 0, 1, 1) self._outputFileQLE = QLFileSystem( os.path.join( os.getcwd(), "stitched_volume.hdf5", ), parent=None, ) self.layout().addWidget(self._outputFileQLE, 1, 1, 1, 1) self._selectPB = qt.QPushButton("select", self) self.layout().addWidget(self._selectPB, 1, 2, 1, 1) # output data path self._outputDataPathLabel = qt.QLabel("HDF5 dataset path", self) self._outputDataPathLabel.setToolTip( "Location of the dataset **inside** the file." ) self.layout().addWidget(self._outputDataPathLabel, 2, 0, 1, 1) self._outputDataPathQLE = qt.QLineEdit(self.DEFAULT_DATA_PATH, self) self.layout().addWidget(self._outputDataPathQLE, 2, 1, 1, 2) # connect signal / path self._selectPB.released.connect(self._selectCurrentFileFormatOutputPath) self._outputFileFormatCB.currentIndexChanged.connect(self._fileFormatChanged) # set up self.setOuputVolumeFormat("hdf5") # force label update self._fileFormatChanged() def _fileFormatChanged(self, *args, **kwargs): extension = self.getOutputVolumeFormat() self._outputDataPathLabel.setVisible(extension == "hdf5") self._outputDataPathQLE.setVisible(extension == "hdf5") if extension == "hdf5": self._outputFileLabel.setText(self._OUTPUT_FILE_PATH_TXT) else: self._outputFileLabel.setText(self._OUTPUT_FOLDER_PATH_TXT) def _selectCurrentFileFormatOutputPath(self): extension = self.getOutputVolumeFormat() if extension == "hdf5": path = self.selectOutputFile( extensions=[ "HDF5 files (*.h5 *.hdf5 *.nx *.nxs *.nexus)", "Nexus files (*.nx *.nxs *.nexus)", "Any files (*)", ] ) else: path = self.selectOutputFolder() if path: self._outputFileQLE.setText(path) def selectOutputFile(self, extensions) -> str | None: dialog = qt.QFileDialog(self) dialog.setNameFilters(extensions) dialog.setAcceptMode(qt.QFileDialog.AcceptSave) if os.environ.get("TOMWER_DEFAULT_INPUT_DIR", None) and os.path.exists( os.environ["TOMWER_DEFAULT_INPUT_DIR"] ): dialog.setDirectory(os.environ["TOMWER_DEFAULT_INPUT_DIR"]) elif dialog.directory() != os.getcwd() or str(dialog.directory()).startswith( "/data" ): # if the directory as already been set by the user. Avoid redefining it pass elif os.path.isdir("/data"): dialog.setDirectory("/data") if not dialog.exec() or len(dialog.selectedFiles()) == 0: dialog.close() return None else: return dialog.selectedFiles()[0] def selectOutputFolder(self) -> str | None: dialog = qt.QFileDialog(self) dialog.setFileMode(qt.QFileDialog.DirectoryOnly) if os.environ.get("TOMWER_DEFAULT_INPUT_DIR", None) and os.path.exists( os.environ["TOMWER_DEFAULT_INPUT_DIR"] ): dialog.setDirectory(os.environ["TOMWER_DEFAULT_INPUT_DIR"]) elif dialog.directory() != os.getcwd() or str(dialog.directory()).startswith( "/data" ): # if the directory as already been set by the user. Avoid redefining it pass elif os.path.isdir("/data"): dialog.setDirectory("/data") if not dialog.exec(): dialog.close() return return dialog.selectedFiles() def getOutputVolumeFormat(self) -> str: return self._outputFileFormatCB.currentText() def setOuputVolumeFormat(self, file_format: str): idx = self._outputFileFormatCB.findText(file_format) if idx >= 0: self._outputFileFormatCB.setCurrentIndex(idx) def getOutputDataPath(self) -> str: return self._outputDataPathQLE.text() def setOutputDataPath(self, data_path: str): self._outputDataPathQLE.setText(data_path) def getOutputFilePath(self) -> str: return self._outputFileQLE.text() def setOutputFilePath(self, file_path: str): self._outputFileQLE.setText(file_path) def getOutputVolumeIdentifier(self) -> BaseIdentifier: volume_format = self.getOutputVolumeFormat() file_path = self.getOutputFilePath() if volume_format in ("hdf5", "h5", "hdf", "nx"): data_path = self.getOutputDataPath() if data_path == "": data_path = self.DEFAULT_DATA_PATH return HDF5Volume( file_path=file_path, data_path=data_path, ).get_identifier() elif volume_format == EDFVolume.DEFAULT_DATA_EXTENSION: return EDFVolume( folder=file_path, ).get_identifier() elif volume_format == JP2KVolume.DEFAULT_DATA_EXTENSION: return JP2KVolume( folder=file_path, ).get_identifier() elif volume_format == RawVolume.DEFAULT_DATA_EXTENSION: return RawVolume( file_path=file_path, ).get_identifier() elif volume_format == TIFFVolume.DEFAULT_DATA_EXTENSION: return TIFFVolume( folder=file_path, ).get_identifier() else: raise RuntimeError(f"format {volume_format} is not handled") def setOutputVolumeIdentifier(self, url): volume = VolumeFactory.create_tomo_object_from_identifier(url) file_format = ( "hdf5" if isinstance(volume, HDF5Volume) else volume.DEFAULT_DATA_EXTENSION ) self.setOuputVolumeFormat(file_format=file_format) if isinstance(volume, HDF5Volume): self.setOutputDataPath(volume.data_path) self.setOutputFilePath(volume.file_path) elif isinstance( volume, (EDFVolume, TIFFVolume, JP2KVolume, RawVolume, MultiTIFFVolume) ): self.setOutputFilePath(volume.data_url.file_path()) else: raise ValueError(f"volume type ({type(volume)}) is not handled") ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9451017 tomwer-1.6.17/src/tomwer/gui/utils/lineselector/0000755000175000017500000000000015153325403020742 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/utils/lineselector/__init__.py0000644000175000017500000000011314757047403023060 0ustar00paynopaynofrom .lineselector import QLineSelector, QSliceSelectorDialog # noqa F401 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/utils/lineselector/lineselector.py0000644000175000017500000001546515143647637024036 0ustar00paynopaynofrom __future__ import annotations import logging from collections import OrderedDict from typing import Iterable import numpy from silx.gui import qt from silx.gui.plot import PlotWidget logger = logging.getLogger(__name__) class QSliceSelectorDialog(qt.QDialog): """ The dialog used to select some slice indexes from a radio :param QWidget parent: parent widget :param n_required_slice: number of required slice we expect the user to select """ def __init__(self, parent, n_required_slice: int | None = None): qt.QDialog.__init__(self, parent=parent) self.setLayout(qt.QVBoxLayout()) self.setWindowTitle("select slices on radio") self.mainWidget = QLineSelector(parent=self, n_required_slice=n_required_slice) self.layout().addWidget(self.mainWidget) types = qt.QDialogButtonBox.Ok | qt.QDialogButtonBox.Cancel self._buttons = qt.QDialogButtonBox(parent=self) self._buttons.setStandardButtons(types) self.layout().addWidget(self._buttons) # connect signal / slots self._buttons.button(qt.QDialogButtonBox.Ok).clicked.connect(self.accept) self._buttons.button(qt.QDialogButtonBox.Cancel).clicked.connect(self.reject) # expose API self.setData = self.mainWidget.setData def setSelection(self, selection: Iterable): """ :param rows: define the selection """ if self.nRequiredSlice() is not None and len(selection) > self.nRequiredSlice(): raise ValueError( f"you provide a selection of {len(selection)} elements when the user should select {self._n_required_slice}" ) if type(selection) is str: selection = selection.replace("(", "") selection = selection.replace(")", "") selection = selection.replace(" ", "") selection = selection.replace(",", ";") try: selection = [int(item) for item in selection.split(";")] except Exception as e: logger.error(f"Fail to set selection. Error is {e}") self.mainWidget.setSelection(selection) def getSelection(self) -> tuple: """ :return: the selection of slices to use """ return self.mainWidget.getSelection() def exec_(self): if not self.mainWidget._has_data: mess = "no data set, can't use the selection tool" logger.warning(mess) qt.QMessageBox.warning(self, "Selection tool not available", mess) self.reject() else: return qt.QDialog.exec(self) def nRequiredSlice(self) -> int | None: return self.mainWidget.nRequiredSlice() class QLineSelector(qt.QWidget): """Widget to select a set of slices from a plot""" def __init__(self, parent=None, n_required_slice=None): self._n_required_slice = n_required_slice qt.QWidget.__init__(self, parent) self._plot = PlotWidget() # invert y axis self._plot.setYAxisInverted(True) self.__selection = OrderedDict() # dict of markers from the user selection. Keys are item legend, value # are items self._has_data = False self.setLayout(qt.QVBoxLayout()) self.layout().addWidget(self._plot) # connect signal / slot self._plot.sigPlotSignal.connect(self._plotDrawEvent) def nRequiredSlice(self) -> int | None: return self._n_required_slice def setData(self, data: numpy.ndarray): """ Define the data from which we can select slices :param data: data to plot """ self._has_data = True self._plot.addImage(data) assert self._plot.getActiveImage(just_legend=True) is not None def getSelection(self) -> tuple: """ :return: the selection of slices to use """ res = [] for _, marker in self.__selection.items(): res.append(int(marker.getPoints()[0][1])) return tuple(sorted(res)) def _clear(self): if len(self.__selection) > 0: self.removeSlice(list(self.__selection.keys())[0]) self._clear() def nSelected(self) -> int: """Return the number of slice selected""" return len(self.__selection) def setSelection(self, rows: Iterable) -> None: """ :param rows: define the selection """ assert type(rows) is not str self._clear() if rows is not None: for row in rows: self.addSlice(row) def addSlice(self, row: float | int) -> None: """ Add the requested slice to the selection :param row: """ row_n = round(float(row)) if self._plot.getActiveImage(just_legend=True) is not None: data_bounds = self._plot.getActiveImage(just_legend=False).getBounds() if not (data_bounds[0] <= row_n < data_bounds[1]): logger.warning("requested slice out of the data, ignored") return # remove the n first selected point if needed n_selected = len(self.getSelection()) n_required_slice = self.nRequiredSlice() if (n_required_slice is not None) and (n_selected >= n_required_slice): n_slice_to_rm = n_required_slice - n_selected + 1 # +1 because we are about to add a slice markers = tuple(self.__selection.values()) idx_to_rm = [ int(marker.getPoints()[0][1]) for marker in markers[0:n_slice_to_rm] ] for slice_idx in idx_to_rm: self.removeSlice(slice_idx) inf = 10000 legend = self._getLegend(row_n=row_n) self._plot.addShape( xdata=numpy.array((-inf, -inf, inf, inf)), ydata=numpy.array((row_n, row_n + 1, row_n + 1, row_n)), shape="polygon", linewidth=1, color="pink", linestyle="-", fill=True, legend=legend, ) self.__selection[legend] = self._plot._getItem(kind="item", legend=legend) def _getLegend(self, row_n) -> str: return str(round(float(row_n))) def removeSlice(self, row: float | int) -> None: """ remove the requested slice from the selection :param row: row containing the slice to be removed """ legend = self._getLegend(row_n=row) if legend in self.__selection: self._plot.remove(legend=legend, kind="item") del self.__selection[legend] def _plotDrawEvent(self, event): if "event" in event and event["event"] == "mouseClicked": row = event["y"] - 0.5 if qt.QApplication.keyboardModifiers() & qt.Qt.ControlModifier: self.removeSlice(row=row) else: self.addSlice(row=row) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/gui/utils/loadingmode.py0000644000175000017500000000554515115744275021131 0ustar00paynopaynofrom __future__ import annotations import functools from enum import Enum as _Enum from silx.gui import qt from tomwer.gui import icons class LoadingMode(_Enum): ON_SHOW_LOADING = "load when show requested" LAZY_LOADING = "lazy loading" ASAP_LOADING = "load ASAP" def icon(self): if self is self.ON_SHOW_LOADING: return icons.getQIcon("low_speed") elif self is self.LAZY_LOADING: return icons.getQIcon("medium_low_speed") elif self is self.ASAP_LOADING: return icons.getQIcon("high_speed") else: raise ValueError(f"loading mode {self} not handled") def tooltip(self): if self is self.ON_SHOW_LOADING: return "will load data only when requiring" return icons.getQIcon("medium_low_speed") elif self is self.LAZY_LOADING: return "load data with reduce prefetch" elif self is self.ASAP_LOADING: return "load data as soon as possible" else: raise ValueError(f"loading mode {self} not handled") class LoadingModeToolButton(qt.QToolButton): """Tool button to switch keep aspect ratio of a plot""" sigLoadModeChanged = qt.Signal(str) def __init__(self, parent=None): super(LoadingModeToolButton, self).__init__(parent=parent) menu = qt.QMenu(self) action_lazy_loading = LazyLoadingAction(parent=self) # by default icons are not visible from the menu. In this case we want to display it action_lazy_loading.setIconVisibleInMenu(True) fctLL = functools.partial(self.setLoadingMode, LoadingMode.LAZY_LOADING) menu.addAction(action_lazy_loading) action_asap_loading = ASAP_LoadingAction(parent=self) action_asap_loading.setIconVisibleInMenu(True) fctAL = functools.partial(self.setLoadingMode, LoadingMode.ASAP_LOADING) menu.addAction(action_asap_loading) self.setMenu(menu) # connect signal / slot action_lazy_loading.triggered.connect(fctLL) action_asap_loading.triggered.connect(fctAL) # set up self.setPopupMode(qt.QToolButton.InstantPopup) self.setLoadingMode(LoadingMode.LAZY_LOADING) def setLoadingMode(self, loadingMode: LoadingMode | str): loadingMode = LoadingMode(loadingMode) assert loadingMode in LoadingMode self.setIcon(loadingMode.icon()) self.setToolTip(loadingMode.tooltip()) self.sigLoadModeChanged.emit(loadingMode.value) class LazyLoadingAction(qt.QAction): def __init__(self, parent): super().__init__("load data with small prefetch", parent=parent) self.setIcon(LoadingMode.LAZY_LOADING.icon()) class ASAP_LoadingAction(qt.QAction): def __init__(self, parent): super().__init__("load data ASAP", parent=parent) self.setIcon(LoadingMode.ASAP_LOADING.icon()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/utils/qt_utils.py0000644000175000017500000000141615143647637020511 0ustar00paynopaynofrom contextlib import contextmanager from silx.gui import qt if qt.BINDING == "PyQt5": from PyQt5.QtTest import QSignalSpy # pylint: disable=E0401,E0611 elif qt.BINDING == "PySide6": from PySide6.QtTest import QSignalSpy # pylint: disable=E0401,E0611 elif qt.BINDING == "PyQt6": from PyQt6.QtTest import QSignalSpy # pylint: disable=E0401,E0611 else: QSignalSpy = None @contextmanager def block_signals(*objs): """Context manager blocking signals of QObjects. It restores previous state when leaving. :param qt.QObject objs: QObjects for which to block signals """ blocked = [(obj, obj.blockSignals(True)) for obj in objs] try: yield finally: for obj, previous in blocked: obj.blockSignals(previous) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/utils/sandboxes.py0000644000175000017500000001400115153325210020602 0ustar00paynopayno# coding: utf-8 """ This module is used to define the process of the reference creator. This is related to the issue #184 """ from __future__ import annotations from silx.gui import qt from tomwer.core.process.conditions.filters import RegularExpressionFilter class RegularExpressionSandBoxDialog(qt.QDialog): """ Dialog for showing the NameFilterSandBoxDialog """ def __init__(self, parent=None, pattern=None): qt.QDialog.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) self.setWindowTitle("Regular expression sand box") self.sandbox = RegularExpressionSandBox(parent=self, pattern=pattern) self.layout().addWidget(self.sandbox) types = qt.QDialogButtonBox.Close self._buttons = qt.QDialogButtonBox(parent=self) self._buttons.setStandardButtons(types) self.layout().addWidget(self._buttons) self._buttons.button(qt.QDialogButtonBox.Close).clicked.connect(self.hide) # expose API self.setPattern = self.sandbox.setPattern self.setPattern(pattern=pattern) class RegularExpressionSandBox(RegularExpressionFilter, qt.QWidget): """ Widget to see if the pattern will 'valid' the given value or not """ def __init__(self, parent=None, pattern=None): _pattern = pattern if _pattern is None: _pattern = "" qt.QWidget.__init__(self, parent) self.setLayout(qt.QVBoxLayout()) self._docLabel = qt.QLabel( ' See documentation', self, ) self._docLabel.setOpenExternalLinks(True) self.layout().addWidget(self._docLabel) self._valueLE = qt.QLineEdit("", parent=self) self._valueLE.editingFinished.connect(self.applyFilter) self._valueLE.setAlignment(qt.Qt.AlignCenter) self.layout().addWidget(self._valueLE) style = qt.QApplication.style() # down arrow self._arrowWidget = qt.QWidget(parent=self) self._arrowWidget.setLayout(qt.QHBoxLayout()) self._arrowWidget.setContentsMargins(0, 0, 0, 0) self._arrowWidget.layout().setSpacing(0) self._arrow = qt.QLabel(parent=self._arrowWidget) self._arrow.setMinimumSize(qt.QSize(55, 55)) icon = style.standardIcon(qt.QStyle.SP_ArrowDown) self._arrow.setPixmap(icon.pixmap(55, 55)) slicer1 = qt.QWidget(parent=self._arrowWidget) slicer1.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) slicer2 = qt.QWidget(parent=self._arrowWidget) slicer2.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) self._arrowWidget.layout().addWidget(slicer1) self._arrowWidget.layout().addWidget(self._arrow) self._arrowWidget.layout().addWidget(slicer2) self.layout().addWidget(self._arrowWidget) # pattern Line edit self._patternWidget = qt.QWidget(parent=self) self._patternWidget.setLayout(qt.QHBoxLayout()) slicer1 = qt.QWidget(parent=self._arrowWidget) slicer1.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) slicer2 = qt.QWidget(parent=self._arrowWidget) slicer2.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) self._patternWidget.layout().addWidget(slicer1) self._patternWidget.layout().addWidget(qt.QLabel("pattern:")) self._patternLE = qt.QLineEdit(_pattern or "", parent=self._patternWidget) self._patternWidget.layout().addWidget(self._patternLE) self._patternWidget.layout().addWidget(slicer2) self.layout().addWidget(self._patternWidget) self._patternLE.editingFinished.connect(self._updatePattern) # result label self._resultWidget = qt.QWidget(parent=self) self._resultWidget.setLayout(qt.QHBoxLayout()) self._resultWidget.setContentsMargins(0, 0, 0, 0) self._resultWidget.layout().setSpacing(0) self._resultLabel = qt.QLabel(parent=self._resultWidget) self._resultLabel.setMinimumSize(qt.QSize(40, 40)) slicer1 = qt.QWidget(parent=self._resultWidget) slicer1.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) slicer2 = qt.QWidget(parent=self._resultWidget) slicer2.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) self._resultWidget.layout().addWidget(slicer1) self._resultWidget.layout().addWidget(self._resultLabel) self._resultWidget.layout().addWidget(slicer2) self.layout().addWidget(self._resultWidget) RegularExpressionFilter.__init__(self, _pattern) def setPattern(self, pattern): self._patternLE.setText(pattern or "") RegularExpressionFilter.setPattern(self, pattern) self.applyFilter() def applyFilter(self): """ Update result label depending on the value to check and the filter """ value = self._valueLE.text() style = qt.QApplication.style() if self.isFiltered(value): icon = style.standardIcon(qt.QStyle.SP_DialogNoButton) else: icon = style.standardIcon(qt.QStyle.SP_DialogYesButton) self._resultLabel.setPixmap(icon.pixmap(40, 40)) def _updatePattern(self): """callback when the pattern is modify""" self.blockSignals(True) self.setPattern(self._patternLE.text()) self.blockSignals(False) @staticmethod def description(): return ( "A simple sand box to play with pattern definition and input " "names to make sure it will have the requested behavior." ) def unvalidPatternDefinition(self, pattern, error): """Overwrite NameFilter.unvalidPatternDefinition""" txt = 'regular expression "%s" is invalid. Error is:' % pattern mess = qt.QMessageBox(parent=self, icon=qt.QMessageBox.warning, text=txt) mess.setInformativeText(str(error)) mess.setWindowTitle("Regular expression failed") mess.setModal(False) mess.show() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/utils/scandescription.py0000644000175000017500000000373114757047403022032 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from tomwer.core.scan.scanbase import TomwerScanBase class ScanNameLabelAndShape(qt.QWidget): """Scan to display the scan name""" def __init__(self, parent): qt.QWidget.__init__(self, parent=parent) self.setLayout(qt.QHBoxLayout()) self.setContentsMargins(0, 0, 0, 0) self.layout().setSpacing(0) label = qt.QLabel("scan: ", self) label.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum) self.layout().addWidget(label) self._scanNameLabel = qt.QLabel("", self) self._scanNameLabel.setAlignment(qt.Qt.AlignLeft) self._scanNameLabel.setSizePolicy( qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum ) self.layout().addWidget(self._scanNameLabel) self._shapeLabel = qt.QLabel("", self) self._shapeLabel.setAlignment(qt.Qt.AlignLeft) self._shapeLabel.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) self.layout().addWidget(self._shapeLabel) # set up self.clear() def setScan(self, scan: TomwerScanBase | None): if scan is None or scan.path is None: self.clear() elif not isinstance(scan, TomwerScanBase): raise TypeError( f"Scan is expected to be an instance of {TomwerScanBase}. Get {type(scan)} instead" ) else: assert isinstance(scan, TomwerScanBase) self._scanNameLabel.setText(scan.get_identifier().short_description()) self._scanNameLabel.setToolTip(scan.get_identifier().to_str()) shape_x = scan.dim_1 if scan.dim_1 is not None else "?" shape_y = scan.dim_2 if scan.dim_2 is not None else "?" self._shapeLabel.setText(f"dims: x={shape_x}, y={shape_y}") def clear(self): self._scanNameLabel.setText("-") self._scanNameLabel.setToolTip("") self._shapeLabel.setText("") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/gui/utils/scrollarea.py0000644000175000017500000000074315115744275020771 0ustar00paynopayno# coding: utf-8 from __future__ import annotations from silx.gui import qt class _IgnoreWheelBase: """QWidget ignoring "wheelEvent" and forwarding it to its parent in case this is a QScrollArea""" def wheelEvent(self, *args, **kwargs): pass class QComboBoxIgnoreWheel(qt.QComboBox, _IgnoreWheelBase): pass class QDoubleSpinBoxIgnoreWheel(qt.QDoubleSpinBox, _IgnoreWheelBase): pass class QSpinBoxIgnoreWheel(qt.QSpinBox, _IgnoreWheelBase): pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/gui/utils/slider.py0000644000175000017500000000415214764622416020123 0ustar00paynopayno# coding: utf-8 """some utils relative to PyHST""" from __future__ import annotations import numpy from silx.gui import qt class LogSlider(qt.QWidget): """Slider to select a value with a QSlider displayed with log scale""" valueChanged = qt.Signal(float) """signal emitted when the value changed""" def __init__(self, parent=None): qt.QWidget.__init__(self, parent) self.setLayout(qt.QGridLayout()) # QSlider self._slider = qt.QSlider(self) self._slider.setOrientation(qt.Qt.Horizontal) self.layout().addWidget(self._slider, 0, 0, 1, 1) # Double spin box self._valueQBSB = qt.QDoubleSpinBox(self) self.layout().addWidget(self._valueQBSB, 0, 1, 1, 1) # connect signal / slot self._slider.valueChanged.connect(self._sliderValueChanged) self._valueQBSB.valueChanged.connect(self._qdsbValueChanged) # set up self.setRange(1, 100) self.setValue(5) def setSuffix(self, txt): self._valueQBSB.setSuffix(txt) def setPrefix(self, txt): self._valueQBSB.setPrefix(txt) def setRange(self, min_: float, max_: float) -> None: """ Define slider range :param min_: :param max_: """ if min_ <= 0.0 or max_ <= 0.0: raise ValueError("LogSlider can only handled positive values") self._valueQBSB.setRange(min_, max_) self._slider.setRange(int(numpy.log(min_)), int(numpy.log(max_))) def _sliderValueChanged(self, *args, **kwargs): old = self._valueQBSB.blockSignals(True) self._valueQBSB.setValue(numpy.exp(self._slider.value())) self._valueQBSB.blockSignals(old) self.valueChanged.emit(self.value()) def _qdsbValueChanged(self, *args, **kwargs): old = self._slider.blockSignals(True) self._slider.setValue(int(numpy.log(self._valueQBSB.value()))) self._slider.blockSignals(old) self.valueChanged.emit(self.value()) def value(self): return self._valueQBSB.value() def setValue(self, value): self._valueQBSB.setValue(value) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/utils/splashscreen.py0000644000175000017500000000075114757047403021333 0ustar00paynopayno# coding: utf-8 try: from silx.gui import qt except ImportError: raise ImportError("Can't found silx modules") import tomwer.version from tomwer.gui import icons def getMainSplashScreen(): pixmap = icons.getQPixmap("tomwer") splash = qt.QSplashScreen(pixmap) splash.show() splash.raise_() _version = tomwer.version.version text = "version " + str(_version) splash.showMessage(text, qt.Qt.AlignLeft | qt.Qt.AlignBottom, qt.Qt.white) return splash ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/utils/step.py0000644000175000017500000001242514757047403017615 0ustar00paynopaynofrom __future__ import annotations import functools from silx.gui import qt from tomwer.gui.utils.qt_utils import block_signals class StepSizeSelectorWidget(qt.QGroupBox): """ Widget to define some steps size (as float). Used by the Axis and the AxisOrdered widgets :param title: title to provide to the group box :param label: text for the label set at the left of the QLineEdit :param fine_value: (optional) value to provide for 'fine' step :param medium_value: (optional) value to provide for 'medium' step :param rough_value: (optional) value to provide for 'rough' step :param dtype: type of the step. Can be int or float """ valueChanged = qt.Signal() """emit when the step size change""" def __init__( self, parent=None, title="", label: str = "step size", fine_value: float | int | None = 0.1, medium_value: float | int | None = 0.5, rough_value: float | int | None = 1.0, unit: str | None = "px", dtype: int | float = float, ): assert fine_value is None or isinstance( fine_value, dtype ), f"fine_value is expected to be None or a {dtype}. Get {type(fine_value)}" assert medium_value is None or isinstance( medium_value, dtype ), f"medium_value is expected to be None or a {dtype}. Get {type(medium_value)}" assert rough_value is None or isinstance( rough_value, dtype ), f"rough_value is expected to be None or a {dtype}. Get {type(rough_value)}" super().__init__(title, parent) self._dtype = dtype if unit is None: unit = "" else: unit = f" {unit}" self.setLayout(qt.QGridLayout()) self.layout().setSpacing(2) # label self.layout().addWidget(qt.QLabel(label), 0, 0, 3, 1) # QLE manual step size default_value = medium_value or fine_value or rough_value self._manualLE = qt.QLineEdit(str(default_value), parent=self) if dtype is float: validator = qt.QDoubleValidator(parent=self._manualLE, decimals=2) validator.setBottom(0.0) elif dtype is int: validator = qt.QIntValidator(parent=self._manualLE) validator.setBottom(0) else: raise ValueError("dtype is expected to be int or float") self._manualLE.setValidator(validator) self.layout().addWidget(self._manualLE, 0, 1, 3, 1) # buttons buttons_font = self.font() buttons_font.setPixelSize(10) self._expectedValues = {} # for each button associate the expected value # fine if fine_value is not None: self._fineButton = qt.QPushButton(f"fine ({fine_value}{unit})", parent=self) self._fineButton.setCheckable(True) self._fineButton.setFont(buttons_font) self.layout().addWidget(self._fineButton, 0, 2, 1, 1) self._fineButton.released.connect( functools.partial(self.setStepSize, fine_value) ) self._expectedValues[self._fineButton] = fine_value else: self._fineButton = None # medium if medium_value is not None: self._mediumButton = qt.QPushButton( f"medium ({medium_value}{unit})", parent=self ) self._mediumButton.setCheckable(True) self._mediumButton.setFont(buttons_font) self.layout().addWidget(self._mediumButton, 1, 2, 1, 1) self._mediumButton.released.connect( functools.partial(self.setStepSize, medium_value) ) self._expectedValues[self._mediumButton] = medium_value else: self._mediumButton = None # rough if rough_value is not None: self._roughButton = qt.QPushButton( f"rough ({rough_value}{unit})", parent=self ) self._roughButton.setCheckable(True) self._roughButton.setFont(buttons_font) self.layout().addWidget(self._roughButton, 2, 2, 1, 1) self._roughButton.released.connect( functools.partial(self.setStepSize, rough_value) ) self._expectedValues[self._roughButton] = rough_value else: self._roughButton = None # connect signal / slot self._manualLE.textChanged.connect(self._updateButtonChecked) self._manualLE.textChanged.connect(self.valueChanged) # set up self._updateButtonChecked(self._manualLE.text()) def _updateButtonChecked(self, text): if text == "": return current_value = self._dtype(text) for button, activation_value in self._expectedValues.items(): with block_signals(button): button.setChecked(activation_value == current_value) def getStepSize(self) -> float | int: """ :return: displacement shift defined. Output is of same type as the 'dtype' provided during construction. """ return self._dtype(self._manualLE.text()) def setStepSize(self, value: float | int): """ :param value: shift step """ assert isinstance(value, self._dtype) self._manualLE.setText(str(value)) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9491017 tomwer-1.6.17/src/tomwer/gui/utils/tests/0000755000175000017500000000000015153325403017414 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/utils/tests/test_completer.py0000644000175000017500000000215714757047403023036 0ustar00paynopayno# coding: utf-8 """module defining dedicated completer""" from __future__ import annotations import pytest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from tomwer.gui.utils.completer import UrlCompleterDialog from tomwer.tests.utils import skip_gui_test @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestUrlCompleterDialog(TestCaseQt): def setUp(self): super().setUp() self._urls = ( "test", "test1", "test2", ) self._dialog = UrlCompleterDialog( urls=self._urls, current_url="test", ) def tearDown(self): self._dialog.setAttribute(qt.Qt.WA_DeleteOnClose) self._dialog.close() self._dialog = None super().tearDown() def test(self): """simple test on the dialog behavior""" assert self._dialog._buttons.button(qt.QDialogButtonBox.Ok).isEnabled() self._dialog._completerWidget.setText("toto") self.qapp.processEvents() assert not self._dialog._buttons.button(qt.QDialogButtonBox.Ok).isEnabled() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/utils/tests/test_host_editor.py0000644000175000017500000000055715143647637023376 0ustar00paynopaynofrom tomwer.gui.utils.host_editor import HostEditor from tomwer.tests.conftest import qtapp # noqa F401 def test_HostEditor( qtapp, # noqa F811 ): # Note: host pinging is not compliant with CI widget = HostEditor(name=None, enable_host_pinging=False) widget.setCurrentText("tata") widget.setPort(26) assert widget.currentText() == "tata" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/utils/tests/test_line_selector.py0000644000175000017500000000115214757047403023665 0ustar00paynopaynoimport numpy from tomwer.gui.utils.lineselector.lineselector import QSliceSelectorDialog from tomwer.tests.conftest import qtapp # noqa F401 def test_line_selector( qtapp, # noqa F811 ): dialog = QSliceSelectorDialog(parent=None) dialog.setData( numpy.ones((100, 100)), ) dialog.mainWidget.addSlice(2) dialog.mainWidget.addSlice(12) assert dialog.getSelection() == (2, 12) dialog.mainWidget.removeSlice(12) assert dialog.getSelection() == (2,) dialog.setSelection((12, 23)) assert dialog.getSelection() == (12, 23) assert dialog.mainWidget.nSelected() == 2 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/utils/tests/test_splashscreen.py0000644000175000017500000000037514757047403023536 0ustar00paynopaynofrom silx.gui import qt from tomwer.gui.utils.splashscreen import getMainSplashScreen from tomwer.tests.conftest import qtapp # noqa F401 def test_get_splash_screen(qtapp): # noqa F401 assert isinstance(getMainSplashScreen(), qt.QSplashScreen) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/utils/tests/test_vignettes.py0000644000175000017500000000433115153325210023032 0ustar00paynopayno""" test vignettes """ import time import numpy import pytest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from tomwer.core.process.reconstruction.scores.scores import ComputedScore, ScoreMethod from tomwer.gui.utils.vignettes import VignettesQDialog from tomwer.tests.utils import skip_gui_test @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestVignettes(TestCaseQt): def setUp(self): super().setUp() self._window = VignettesQDialog( value_name="cor", score_name="score", ) def tearDown(self): self._window.setAttribute(qt.Qt.WA_DeleteOnClose) self._window.close() self._window = None super().tearDown() def test(self): self._window.setScores( scores={ "3": (numpy.ones((100, 100)), ComputedScore(tv=2.0, std=3.2)), "7": (numpy.zeros((100, 100)), ComputedScore(tv=25, std=0.6)), }, score_method="standard deviation", ) self._window.show() self.qWaitForWindowExposed(self._window) def assert_scores_are_equal(scores_1, scores_2): assert scores_1.keys() == scores_2.keys() for key, (data_1, computed_score_1) in scores_1.items(): data_2, computed_score_2 = scores_2[key] numpy.testing.assert_array_almost_equal(data_1, data_2) assert computed_score_1 == computed_score_2 scores, score_method = self._window._vignettesWidget.getScores() assert_scores_are_equal( scores_1=scores, scores_2={ "3": (numpy.ones((100, 100)), ComputedScore(std=3.2, tv=None)), "7": (numpy.zeros((100, 100)), ComputedScore(std=0.6, tv=None)), }, ) assert score_method is ScoreMethod.STD self._window.setNbColumn(4) self._window.setNbColumn(2) with pytest.raises(ValueError): self._window.setNbColumn(20) self._window.setNbColumn("auto") self._window.resize(qt.QSize(400, 400)) self.qapp.processEvents() time.sleep(VignettesQDialog.RESIZE_MAX_TIME * 2 / 1000) self.qapp.processEvents() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/utils/unitsystem.py0000644000175000017500000001422115143647637021067 0ustar00paynopayno# coding: utf-8 """ This module is used to define the process of the reference creator. This is related to the issue #184 """ from __future__ import annotations import logging import pint from silx.gui import qt _logger = logging.getLogger(__name__) _ureg = pint.get_application_registry() class PixelEntry(qt.QWidget): valueChanged = qt.Signal() """emit when the pixel value change""" class Validator(qt.QIntValidator): def validate(self, a0: str, a1: int): if a0 == "unknow": return qt.QValidator.Acceptable else: return super().validate(a0, a1) def __init__(self, name, parent=None): qt.QWidget.__init__(self, parent) self.setLayout(qt.QHBoxLayout()) self._label = qt.QLabel(name, parent=self) self.layout().addWidget(self._label) self._qlePixelSize = qt.QLineEdit(parent=self) self._qlePixelSize.setValidator(self.Validator(self._qlePixelSize)) self._qlePixelSize.setPlaceholderText("px") self.layout().addWidget(self._qlePixelSize) # connect signal / slot self._qlePixelSize.editingFinished.connect(self.valueChanged) def getValue(self): if self._qlePixelSize.text() in ("unknown", ""): return None else: return int(self._qlePixelSize.text()) def setValue(self, value: int): self._qlePixelSize.setText(str(value)) self.valueChanged.emit() def setReadOnly(self, read_only: bool) -> None: self._qlePixelSize.setReadOnly(read_only) class MetricEntry(qt.QWidget): """ Create a simple line with a name, a QLineEdit and a combobox to define the unit in order to define a metric value. :param name: name of the metric value to define :param default_unit: Default way to present a value when set """ editingFinished = qt.Signal() """emit when editing is finished""" valueChanged = qt.Signal() """emit when the metric value change""" _ExposedUnits: set[_ureg.Unit] = { _ureg.nanometer, _ureg.micrometer, _ureg.mm, _ureg.cm, _ureg.m, } class DoubleValidator(qt.QDoubleValidator): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setNotation(qt.QDoubleValidator.ScientificNotation) def validate(self, a0: str, a1: int): if a0 == "unknown": return (qt.QDoubleValidator.Acceptable, a0, a1) else: return super().validate(a0, a1) def __init__( self, name, value=0.0, default_unit: pint.Unit = _ureg.meter, parent=None ): qt.QWidget.__init__(self, parent) if default_unit not in self._ExposedUnits: raise ValueError( f"Unable to use {default_unit} as default unit. Must be in {self._ExposedUnits}" ) self._base_unit: pint.Unit = default_unit self.setLayout(qt.QHBoxLayout()) self._label = qt.QLabel(name, parent=self) self.layout().addWidget(self._label) self._qlePixelSize = qt.QLineEdit("0.0", parent=self) self._qlePixelSize.setValidator(self.DoubleValidator(self._qlePixelSize)) self.layout().addWidget(self._qlePixelSize) self._qcbUnit = qt.QComboBox(parent=self) for unit in self._ExposedUnits: self._qcbUnit.addItem(f"{unit:.4f~P}") self.layout().addWidget(self._qcbUnit) self._resetBaseUnit() # connect signal / slot self._qcbUnit.currentIndexChanged.connect(self._editingFinished) self._qlePixelSize.editingFinished.connect(self._editingFinished) def _editingFinished(self, *args, **kwargs): self.editingFinished.emit() def setReadOnly(self, a0: bool): self._qlePixelSize.setReadOnly(a0) self._qcbUnit.setEnabled(not a0) def setLabelText(self, text: str): self._label.setText(text) def getCurrentUnit(self): return _ureg.Unit(self._qcbUnit.currentText()) def setValue(self, value_m, displayed_unit: pint.Unit = _ureg.meter): """ :param value: pixel size in international metric system (meter) """ _value = value_m if _value in (None, "unknown"): txt = "unknown" elif isinstance(_value, str): if "..." in _value: txt = _value else: try: _value = float(_value) except Exception as error: raise ValueError("Given string does not represent a float", error) else: assert isinstance(_value, float) txt = str(_value) else: txt = str(_value) self._qlePixelSize.setText(txt) self._resetBaseUnit(displayed_unit=displayed_unit) def _resetBaseUnit(self, displayed_unit: pint.Unit | None = None): """Simple reset of the combobox according to the base_unit""" if displayed_unit is not None and not isinstance(displayed_unit, pint.Unit): raise TypeError( f"'displayed_unit' should be a {pint.Unit}. Got {type(displayed_unit)}" ) displayed_unit = displayed_unit or self._base_unit index = self._qcbUnit.findText(f"{displayed_unit:.4f~P}") if index < 0: raise ValueError("unrecognized base unit") else: self._qcbUnit.setCurrentIndex(index) def getValue(self) -> pint.Quantity | None: """ :return: the value in meter """ if self._qlePixelSize.text() in ("unknown", ""): return None else: return float(self._qlePixelSize.text()) * self.getCurrentUnit() def setValidator(self, validator): self._qlePixelSize.setValidator(validator) def setUnit(self, unit: pint.Unit): assert isinstance( unit, pint.Unit ), f"unit is expected to be a pint.Unit. Got {type(unit)}" unit = f"{unit:.4f~P}" idx = self._qcbUnit.findText(unit) if idx >= 0: self._qcbUnit.setCurrentIndex(idx) else: _logger.error(f"Unhandled unit ({unit})") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/utils/utils.py0000644000175000017500000000623415153325210017765 0ustar00paynopayno""" Some utils GUI associated to illustrations """ from __future__ import annotations from silx.io.url import DataUrl import logging import os import subprocess import threading import platform _logger = logging.getLogger(__name__) __has_image_j = None __image_j_from = None _IMAGE_J_BIN_PATH = "/sware/pub/ImageJ/ImageJ" def has_imagej() -> bool: """Return if imagej command is accessible from the computer""" global __has_image_j def has_bin() -> bool: global __image_j_from if platform.machine() in ("x86_64", "AMD64") and os.path.exists( _IMAGE_J_BIN_PATH ): __image_j_from = "binary" return True return False def has_CLI() -> bool: global __image_j_from try: # use help because there is no information regarding version subprocess.call( ["imagej", "-h"], stdout=subprocess.PIPE ) # nosec B603, B607 except Exception: return False else: __image_j_from = "command" return True def has_module() -> bool: """Check if the module exists. At the moment this is the simplest way to access as utils like is-loaded seems to fail.""" global __image_j_from if os.path.exists("/cvmfs/hpc.esrf.fr/software/packages/linux/x86_64/imagej"): __image_j_from = "command" return True else: return False if __has_image_j is None: __has_image_j = has_bin() or has_CLI() or has_module() return __has_image_j def open_url_with_image_j(url: DataUrl) -> threading.Thread: """open the url in an imagej subprocess within a thread. It is up to the caller to handle thread life :param url: url we want to open in imagej """ global __image_j_from # noqa: F824 if not has_imagej(): raise OSError("ImageJ is not installed") thread = ImageJthread(url=url, image_j_from=__image_j_from) thread.start() return thread class ImageJthread(threading.Thread): def __init__(self, url, image_j_from, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self._image_j_from = image_j_from self._url = url self._process = None def run(self): if self._image_j_from == "command": # for now we only manage the simple case of an edf file try: self._process = subprocess.Popen( ["imagej", "-o", self._url.file_path()], ) except Exception as e: _logger.warning(f"Fail to open {self._url}. Reason is {e}") else: self._process.communicate() elif self._image_j_from == "binary": try: self._process = subprocess.Popen( [_IMAGE_J_BIN_PATH, self._url.file_path()], ) except Exception as e: _logger.warning(f"Fail to open {self._url}. Reason is {e}") else: self._process.communicate() def quit(self): if self._process is not None: self._process.kill() self._process.wait() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/utils/vignettes.py0000644000175000017500000004256515153325210020644 0ustar00paynopayno""" contains gui to select a slice in a volume """ from __future__ import annotations import logging from typing import Iterable import numpy from silx.gui import qt from silx.gui.plot import PlotWindow from silx.gui.plot.utils.axis import SyncAxes from silx.io.url import DataUrl from tomoscan.esrf.scan.utils import get_data from math import floor from tomwer.core.process.reconstruction.scores.scores import ComputedScore, ScoreMethod _logger = logging.getLogger(__name__) class VignettesQDialog(qt.QDialog): """ """ SIZE_HINT = qt.QSize(820, 820) AUTO_NB_COLUMN = "auto" COLUMN_VALUES = (AUTO_NB_COLUMN, 1, 2, 3, 4, 5, 6, 8, 10) RESIZE_MAX_TIME = 500 def __init__( self, value_name, score_name, parent=None, value_format=None, score_format=None, colormap=None, ): qt.QDialog.__init__(self, parent) self.setWindowFlags(qt.Qt.Widget) self._scan = None self._selectedValue = None self.setLayout(qt.QVBoxLayout()) self._nbColumnCB = qt.QComboBox(self) for nb_column in self.COLUMN_VALUES: self._nbColumnCB.addItem(str(nb_column)) self._columnWidget = qt.QWidget(self) # needed intermediary widget because the 'setWidgetResizable' fails with QFormLayout on PyQt 5.14.1 and will want to keep compatiblity for now self._columnWidget.setLayout(qt.QFormLayout()) self._columnWidget.layout().addRow("number of column", self._nbColumnCB) self.layout().addWidget(self._columnWidget) self._mainWidget = qt.QScrollArea(self) self._mainWidget.setHorizontalScrollBarPolicy(qt.Qt.ScrollBarAlwaysOff) self._mainWidget.setVerticalScrollBarPolicy(qt.Qt.ScrollBarAsNeeded) self._vignettesWidget = VignettesWidget( self, with_spacer=True, value_name=value_name, score_name=score_name, score_format=score_format, value_format=value_format, colormap=colormap, ) self._mainWidget.setWidget(self._vignettesWidget) self.layout().addWidget(self._mainWidget) self._mainWidget.setWidgetResizable(True) # buttons types = qt.QDialogButtonBox.Ok | qt.QDialogButtonBox.Cancel self._buttons = qt.QDialogButtonBox(parent=self) self._buttons.setStandardButtons(types) self._buttons.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Minimum) self.layout().addWidget(self._buttons) # connect signal slot self._buttons.button(qt.QDialogButtonBox.Ok).clicked.connect(self.accept) self._buttons.button(qt.QDialogButtonBox.Cancel).clicked.connect(self.reject) self._nbColumnCB.currentIndexChanged.connect(self._updateNbColumn) self._resizeCallback = None self._firstResizeEvent = True def sizeHint(self): """Return a reasonable default size for usage in :class:`PlotWindow`""" return self.SIZE_HINT def setScores(self, scores: dict, score_method: ScoreMethod): """ Expect a dictionary with possible values to select as key and (2D numpy.array, score) as value. Where the 2D numpy.array is the frame to display and the score if the "indicator" score to display with the frame. :param scores: with score as key and a tuple (url|numpy array, ComputedScore) as value :param ScoreMethod score_method: score kind to be display """ self._vignettesWidget.setScores(scores=scores, score_method=score_method) def selectedValue(self): if self._vignettesWidget is None: return self._selectedValue else: return self._vignettesWidget.selectedValue() def acccept(self): self._selectedValue = self._vignettesWidget.selectedValue() self._vignettesWidget.close() super().accept() def reject(self): self._selectedValue = self._vignettesWidget.selectedValue() self._vignettesWidget.close() super().reject() def getNColumn(self) -> int | None: n_column = self._nbColumnCB.currentText() if n_column == self.AUTO_NB_COLUMN: return None else: return int(n_column) def setNbColumn(self, value: int | str): if value not in self.COLUMN_VALUES: raise ValueError( f"Unhandled number of column requested ({value}). Valid values are {self.COLUMN_VALUES}" ) idx = self._nbColumnCB.findText(str(value)) self._nbColumnCB.setCurrentIndex(idx) @staticmethod def computeOptimalNColumn(window_width, vignette_width): n = floor(window_width / vignette_width) # To check with Jerome; He seems to have work on the topic. # might have some method for a smart way to do it return max(1, n) def _updateNbColumn(self, force_update=False): n_colum = self.getNColumn() if n_colum is None: n_colum = self.computeOptimalNColumn( window_width=self.width(), vignette_width=400, ) self._vignettesWidget.setNElementsPerRow(n_colum, force_update=force_update) def resizeEvent(self, event): if self._firstResizeEvent: # cheap way to filter the first resize and avoid updating it self._firstResizeEvent = False else: # print("resize event received...", event) if self._resizeCallback is not None: self._resizeCallback.timeout.disconnect(self._updateNbColumn) self._resizeCallback.stop() self._resizeCallback.deleteLater() self._resizeCallback = None self._resizeCallback = qt.QTimer(self) self._resizeCallback.setSingleShot(True) self._resizeCallback.timeout.connect(self._updateNbColumn) self._resizeCallback.start(self.RESIZE_MAX_TIME) super().resizeEvent(event) class VignettesWidget(qt.QWidget): """ Widget to display all the frames. :param parent: :param value_name: name of the values for which we are looking for the best one :param score_name: name of the score computed :param score_format: None or str that can be formatted to display the score :param value_format: None or str that can be formatted to display the value """ DEFAULT_PLOT_PER_ROW = 2 MAX_NB_COLUMN = 999999 def __init__( self, parent=None, value_name="value", score_name="score", with_spacer=True, value_format=None, score_format=None, colormap=None, ): qt.QWidget.__init__(self, parent) self._valueName = value_name self._scoreName = score_name self._nPlotPerRow = VignettesWidget.DEFAULT_PLOT_PER_ROW self._withSpacer = with_spacer self._vignettesGroup = qt.QButtonGroup() self.__constraintXAxis = None self.__constraintYAxis = None self._valueFormat = value_format self._scoreFormat = score_format self._colormap = colormap self._vignettes = [] self.__score_method = None self.setLayout(qt.QGridLayout()) def close(self): for vignette in self._vignettes: vignette.close() super().close() def selectedValue(self): sel_vignette = self._vignettesGroup.checkedButton() if sel_vignette is not None: return sel_vignette.getScoreValue() else: return None def setNElementsPerRow(self, n: int, force_update): assert isinstance(n, int), "number of column must be an int" if self._nPlotPerRow != n: self._nPlotPerRow = n self.__update() elif force_update: self.__update() def __update(self): scores, score_method = self.getScores() self.setScores(scores, score_method) # raise NotImplementedError def getNElementsPerRow(self): return self._nPlotPerRow def getScores(self) -> tuple: """ Return currently displayed scores as (scores, scores_method) """ scores = {} scores_method = self.__score_method for vignette in self._vignettes: assert isinstance(vignette, Vignette) if scores_method in (ScoreMethod.STD, ScoreMethod.STD_INVERSE): compute_score_args = { "std": vignette.getScoreValue(), "tv": None, } elif scores_method in (ScoreMethod.TV, ScoreMethod.TV_INVERSE): compute_score_args = { "std": None, "tv": vignette.getScoreValue(), } elif scores_method in (ScoreMethod.TOMO_CONSISTENCY): compute_score_args = { "std": None, "tv": None, "tomo_consitency": vignette.getScoreValue(), } else: raise ValueError(f"score method unhandled: {scores_method.value}") scores[vignette.getValue()] = ( vignette.getData(), ComputedScore(**compute_score_args), ) return scores, scores_method def clearVignettes(self): for vignette in self._vignettes: self.layout().removeWidget(vignette) vignette.setParent(None) self._vignettesGroup.removeButton(vignette) # vignette.deleteLater() self._vignettes = [] def setScores(self, scores: dict, score_method: ScoreMethod): """ Expect a dictionary with possible values to select as key and (2D numpy.array, score) as value. Where the 2D numpy.array is the frame to display and the score if the "indicator" score to display with the frame. :param scores: with score as key and a tuple (url|numpy array, ComputedScore) as value :param ScoreMethod score_method: score kind to be display """ if len(scores) < 1: return self.clearVignettes() i_row = 0 scores_values = [] for i_score, (value, (data, score_cls)) in enumerate(scores.items()): if not isinstance(score_cls, ComputedScore): raise TypeError( f"score is expected to be a dict with values as (v1: numpy.ndarray, v2: ComputedScore). v2 type Found: {type(score_cls)}" ) scores_values.append(score_cls.get(score_method)) self.__score_method = ScoreMethod(score_method) highest_score_indices = numpy.nanargmax(scores_values) self._vignettesGroup = qt.QButtonGroup(self) self._vignettesGroup.setExclusive(True) if not isinstance(highest_score_indices, Iterable): highest_score_indices = (highest_score_indices,) xAxis = [] yAxis = [] for i_score, (value, (data, score_cls)) in enumerate(scores.items()): score = score_cls.get(score_method) i_column = i_score % self.getNElementsPerRow() # TODO: instead of having a binary color we could use # colormap from green (good score) to red (bad score score) if i_score == highest_score_indices or i_score in highest_score_indices: frame_color = qt.Qt.green else: frame_color = qt.Qt.lightGray widget = Vignette( parent=self, value_name=self._valueName, score_name=self._scoreName, value=value, data=data, score=score, frame_color=frame_color, value_format=self._valueFormat, score_format=self._scoreFormat, colormap=self._colormap, ) widget.setAttribute(qt.Qt.WA_DeleteOnClose) xAxis.append(widget.getPlotWidget().getXAxis()) yAxis.append(widget.getPlotWidget().getYAxis()) self.layout().addWidget(widget, i_row, i_column) if i_column == self.getNElementsPerRow() - 1: i_row += 1 if i_score == 0: # we cannot request all widget to keep the aspect ratio widget.setKeepDataAspectRatio(True) self._vignettesGroup.addButton(widget) self._vignettes.append(widget) if self._withSpacer: spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding) # to simplify we add a spacer at the end. We do not expect to have more than 999999 column self.layout().addWidget(spacer, i_row + 1, self.MAX_NB_COLUMN) # constrain axis synchronization self.__constraintXAxis = SyncAxes( xAxis, syncLimits=False, syncScale=True, syncDirection=True, syncCenter=True, syncZoom=True, ) self.__constraintYAxis = SyncAxes( yAxis, syncLimits=False, syncScale=True, syncDirection=True, syncCenter=True, syncZoom=True, ) class _PlotForVignette(PlotWindow): def __init__(self, parent=None): PlotWindow.__init__( self, parent=parent, yInverted=True, copy=False, save=False, print_=False, control=False, mask=False, ) self.setKeepDataAspectRatio(False) self.setAxesDisplayed(False) self.toolBar().hide() self.getInteractiveModeToolBar().hide() self.getOutputToolBar().hide() self.setInteractiveMode("zoom", zoomOnWheel=False) def close(self) -> bool: super().close() class Vignette(qt.QToolButton): """Widget to display a vignette""" FRAME_WIDTH = 2 def __init__( self, parent, value, value_name: str, score_name: str, data: DataUrl | numpy.array, score: float, frame_color: qt.QColor, score_format=None, value_format=None, colormap=None, ): self._value = value self._scoreName = score_name self._valueName = value_name qt.QToolButton.__init__(self, parent) self.setCheckable(True) self.setLayout(qt.QVBoxLayout()) self._plot = _PlotForVignette(parent=self) self._plot.setDefaultColormap(colormap=colormap) self.layout().addWidget(self._plot) self._valueLabel = ValueLabel( self, value=value, score=score, score_name=self._scoreName, value_name=self._valueName, value_format=value_format, score_format=score_format, ) self.layout().addWidget(self._valueLabel) self.setFixedSize(400, 400) self._frameColor = frame_color self._selectedFrameColor = qt.Qt.black if isinstance(data, DataUrl): data = get_data(data) if data.ndim == 3 and data.shape[0] == 1: data = data.reshape(data.shape[1:]) self._plot.addImage(data) def setKeepDataAspectRatio(self, keep): self._plot.setKeepDataAspectRatio(keep) def getPlotWidget(self): return self._plot def getValue(self): return self._value def getData(self) -> numpy.ndarray: return self._plot.getImage().getData() def getScoreValue(self): return self._valueLabel.score def getScoreName(self): return self._scoreName def getValueName(self): return self._valueName def paintEvent(self, event): super().paintEvent(event) painter = qt.QPainter(self) half_h_width = self.FRAME_WIDTH // 2 rect = qt.QRect( half_h_width, half_h_width, self.width() - self.FRAME_WIDTH, self.height() - self.FRAME_WIDTH, ) pen = qt.QPen() pen.setWidth(Vignette.FRAME_WIDTH) pen.setColor(self._frameColor) painter.setPen(pen) painter.drawRect(rect) if self.isChecked(): pen.setColor(self._selectedFrameColor) pen.setStyle(qt.Qt.DashLine) pen.setDashOffset(0.2) painter.setPen(pen) painter.drawRect(rect) def close(self): self._plot.clear() self._plot.setAttribute(qt.Qt.WA_DeleteOnClose) self._plot.close() self._plot = None class ValueLabel(qt.QWidget): """Display the value and the associated score""" def __init__( self, parent, value, score, value_name, score_name, value_format, score_format ): qt.QWidget.__init__(self, parent) self._score = score self.setLayout(qt.QHBoxLayout()) if value_format is not None: str_value = value_format.format(value) else: str_value = str(value) txt = f"{value_name}: {str_value}" self._valueLabel = qt.QLabel(txt, self) self.layout().addWidget(self._valueLabel) if score_format is not None: str_score = score_format.format(score) else: str_score = str(score) txt = f"({score_name}: {str_score})" self._scoreLabel = qt.QLabel(txt, self) self.layout().addWidget(self._scoreLabel) @property def score(self): return self._score ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/utils/waiterthread.py0000644000175000017500000000075515143647637021335 0ustar00paynopayno# coding: utf-8 """ This module is used to manage observations. Initially on files. Observations are runned on a thread and run each n seconds. They are manage by thread and signals """ import time from silx.gui import qt class QWaiterThread(qt.QThread): """simple thread wich wait for waitingTime to be finished""" def __init__(self, waitingTime): qt.QThread.__init__(self) self.waitingTime = waitingTime def run(self): time.sleep(self.waitingTime) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9491017 tomwer-1.6.17/src/tomwer/gui/visualization/0000755000175000017500000000000015153325403020013 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/TomoPlot2D.py0000644000175000017500000000165615143647637022357 0ustar00paynopaynofrom __future__ import annotations from silx.gui.plot import Plot2D from tomwer.gui.utils.buttons import TapeMeasureToolButton from tomwer.gui.settings import Y_AXIS_DOWNWARD class TomoPlot2D(Plot2D): """Plot set up for tomography and to display reconstructed slices""" def __init__(self, parent=None, backend=None): super().__init__(parent, backend) self.setYAxisInverted(Y_AXIS_DOWNWARD) self.setKeepDataAspectRatio(True) self.setAxesDisplayed(False) self._tapeMeasureButton = TapeMeasureToolButton(parent=self, plot=self) self._tapeMeasureButton.setCheckable(True) self.toolBar().addWidget(self._tapeMeasureButton) def setVoxelSize(self, size: float | None): """set the pixel size to be used by the ruler""" self._tapeMeasureButton.setPixelSize(pixel_size=size) def setToolbarVisible(self, visible): self.toolBar().setVisible(visible) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/gui/visualization/__init__.py0000644000175000017500000000013714764622416022140 0ustar00paynopayno"""Widgets for displaying data (sinogram, browsing scans, display reconstructed volumes...)""" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/visualization/dataviewer.py0000644000175000017500000003222315153325210022516 0ustar00paynopaynoimport weakref from silx.gui import qt from enum import Enum as _Enum from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.volume.volumebase import TomwerVolumeBase from tomwer.core.volume.volumefactory import VolumeFactory from tomwer.gui.settings import Y_AXIS_DOWNWARD from tomwer.gui.visualization.imagestack import ImageStack class DataViewer(qt.QMainWindow): """ Widget used to browse through data and reconstructed slices """ sigConfigChanged = qt.Signal() """Signal emitted when the settings (display mode, options...) changed. """ def __init__(self, parent, show_overview=True, backend=None): super().__init__(parent) self.setWindowFlags(qt.Qt.Widget) self._scan = None # viewer self._viewer = ImageStack( parent=self, show_overview=show_overview, backend=backend ) self._viewer.getPlotWidget().getMaskAction().setVisible(False) self._viewer.getPlotWidget().setYAxisInverted(Y_AXIS_DOWNWARD) # set an UrlLoader managing .npy and .vol self._viewer.getPlotWidget().setKeepDataAspectRatio(True) self.setCentralWidget(self._viewer) # display control self._controls = DisplayControl(parent=self) self._controlsDW = qt.QDockWidget(self) self._controlsDW.setWidget(self._controls) self._controlsDW.setWindowTitle("infos") self.addDockWidget(qt.Qt.TopDockWidgetArea, self._controlsDW) self._controlsDW.setTitleBarWidget(qt.QWidget(self)) self._controlsDW.setFloating(False) # connect signal / slot self._controls.sigDisplayModeChanged.connect(self._updateDisplay) self._controls.sigDisplayModeChanged.connect(self.sigConfigChanged) # upgrade of the slider (see details in '__sliderPressed' docstring). horizontal_slider = self._viewer._slider horizontal_slider._slider.sliderReleased.connect(self.__sliderReleased) horizontal_slider._slider.sliderPressed.connect(self.__sliderPressed) def __sliderPressed(self): """ today each time the slider value is modified it will load the frame and display it but in our case we cannot afford it as it will take too much memory. So we will disconnect the callback (self._viewer.setCurrentUrlIndex) until the slider is active and reactivate it afterwards """ self._viewer._slider.sigCurrentUrlIndexChanged.disconnect( self._viewer.setCurrentUrlIndex ) def __sliderReleased(self): """ See details in '__sliderPressed' """ horizontal_slider = self._viewer._slider self._viewer._slider.sigCurrentUrlIndexChanged.connect( self._viewer.setCurrentUrlIndex ) # set the url with the latest value to display the requested frame self._viewer.setCurrentUrlIndex(horizontal_slider.value()) def getPlotWidget(self): return self._viewer.getPlotWidget() def getCurrentUrl(self): return self._viewer.getCurrentUrl() def setScanInfoVisible(self, visible: bool): self._controls.setScanInfoVisible(visible=visible) def setDisplayModeVisible(self, visible: bool): self._controls.setDisplayModeVisible(visible=visible) def setScanOverviewVisible(self, visible: bool) -> None: self._viewer.setScanOverviewVisible(visible=visible) def getUrlListDockWidget(self): return self._viewer.getUrlListDockWidget() def close(self): self.stop() self._viewer.close() self._viewer = None super().close() def getScan(self): if self._scan: return self._scan() def setScan(self, scan): if scan is not None: self._scan = weakref.ref(scan) else: self._scan = None # update scan name self._viewer.setScan(scan=scan) self._controls.setScanName(str(scan)) self._updateDisplay() # has the display is post pone we can only set expected dimensions # for the viewer self._viewer.setResetZoomOnNextIteration(True) def getDisplayMode(self): return self._controls.getDisplayMode() def setDisplayMode(self, mode): self._controls.setDisplayMode(mode) def getRadioOption(self): return self._controls.getRadioOption() def setRadioOption(self, opt): self._controls.setRadioOption(opt) def getSliceOption(self): return self._controls.getSliceOption() def setSliceOption(self, opt): self._controls.setSliceOption(opt) def _updateDisplay(self): """Update display of the viewer""" self._viewer.setSliceReconsParamsVisible( self.getDisplayMode() is _DisplayMode.SLICES ) self._viewer.setScanOverviewVisible( self.getDisplayMode() is not _DisplayMode.SLICES ) if self._scan is None or self._scan() is None: self._viewer.reset() return assert isinstance(self._scan(), TomwerScanBase) slices_metadata = {} if self.getDisplayMode() is _DisplayMode.RADIOS: # update the normalization function from the viewer if needed if self.getRadioOption() is _RadioMode.NORMALIZED: url_to_index = { v.path(): k for k, v in self._scan().projections.items() } self._viewer.setNormalizationFct( self._scan().data_flat_field_correction, url_indexes=url_to_index, ) else: self._viewer.setNormalizationFct(None) slices = self._scan().projections elif self.getDisplayMode() is _DisplayMode.SLICES: self._viewer.setNormalizationFct(None) if self.getSliceOption() is _SliceMode.LATEST: slices = self._scan().latest_reconstructions else: slices = self._scan().get_reconstructed_slices() # convert volumes identifiers to DataUrl slices_urls = [] for identifier in slices: if isinstance(identifier, TomwerVolumeBase): volume = identifier else: volume = VolumeFactory.create_tomo_object_from_identifier( identifier=identifier ) urls = list(volume.browse_data_urls()) try: metadata = volume.metadata or volume.load_metadata() except Exception: metadata = None slices_urls.extend(urls) slices_metadata.update({url.path(): metadata for url in urls}) slices = slices_urls elif self.getDisplayMode() is _DisplayMode.DARKS: self._viewer.setNormalizationFct(None) slices = self._scan().darks elif self.getDisplayMode() is _DisplayMode.FLATS: self._viewer.setNormalizationFct(None) slices = self._scan().flats elif self.getDisplayMode() is _DisplayMode.REDUCED_DARKS: self._viewer.setNormalizationFct(None) slices = self._scan().load_reduced_darks(return_as_url=True) elif self.getDisplayMode() is _DisplayMode.REDUCED_FLATS: self._viewer.setNormalizationFct(None) slices = self._scan().load_reduced_flats(return_as_url=True) else: raise ValueError("DisplayMode should be RADIOS or SLICES") if isinstance(slices, dict): slices = [ value for key, value in sorted(slices.items(), key=lambda item: item[0]) ] if slices is not None and len(slices) > 0: # warning: 'setUrls' will clean metadata so we need to first set the urls self._viewer.setUrls(slices) self._viewer.setSliceMetadata(slices_metadata) else: self._viewer.reset() self._viewer._filterUrlList() def clear(self): self._scan = None self._viewer.reset() self._viewer.setUrls(list()) self._controls.clear() def stop(self): # insure we call self._viewer._freeLoadingThreads() self._viewer.reset() class _DisplayMode(_Enum): RADIOS = "projections-radios" SLICES = "slices" DARKS = "raw darks" FLATS = "raw flats" REDUCED_DARKS = "reduced darks" REDUCED_FLATS = "reduced flats" class _RadioMode(_Enum): NORMALIZED = "normalized" RAW = "raw" class _SliceMode(_Enum): LATEST = "latest" ALL = "all" class DisplayControl(qt.QWidget): """ Widget used to define what we want to display from the viewer """ sigDisplayModeChanged = qt.Signal() """Signal emitted when the configuration of the display change""" def __init__(self, parent=None): qt.QWidget.__init__(self, parent) self._lastConfig = None, None self.setLayout(qt.QGridLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.layout().setSpacing(0) # scan information self._scanLab = qt.QLabel("scan:", self) self._scanLab.setFixedWidth(40) self._scanLab.setAlignment(qt.Qt.AlignRight | qt.Qt.AlignVCenter) self.layout().addWidget(self._scanLab, 0, 0, 1, 1) self._scanQLE = qt.QLineEdit("", self) self._scanQLE.setReadOnly(True) self.layout().addWidget(self._scanQLE, 0, 1, 1, 3) # display information self._displayLab = qt.QLabel("display:", self) self._displayLab.setAlignment(qt.Qt.AlignRight | qt.Qt.AlignVCenter) self.layout().addWidget(self._displayLab, 1, 0, 1, 1) self._displayMode = qt.QComboBox(self) for mode in _DisplayMode: self._displayMode.addItem(mode.value) self.layout().addWidget(self._displayMode, 1, 1, 1, 1) # option information self._modeLab = qt.QLabel("mode:", self) self._modeLab.setFixedWidth(60) self._modeLab.setAlignment(qt.Qt.AlignRight | qt.Qt.AlignVCenter) self.layout().addWidget(self._modeLab, 1, 2, 1, 1) self._widget_options = qt.QWidget(self) self._widget_options.setLayout(qt.QVBoxLayout()) self.layout().addWidget(self._widget_options, 1, 3, 1, 1) self._radioMode = qt.QComboBox(self) for mode in _RadioMode: self._radioMode.addItem(mode.value) self._widget_options.layout().addWidget(self._radioMode) self._sliceMode = qt.QComboBox(self) for mode in _SliceMode: self._sliceMode.addItem(mode.value) self._widget_options.layout().addWidget(self._sliceMode) # set up # by default propose slices to avoid useless processing on radios idx = self._displayMode.findText(_DisplayMode.SLICES.value) self._displayMode.setCurrentIndex(idx) self._updateOptions() # connect signal and slot self._displayMode.currentTextChanged.connect(self._updateOptions) self._radioMode.currentTextChanged.connect(self._updateOptions) self._sliceMode.currentTextChanged.connect(self._updateOptions) def setScanInfoVisible(self, visible): self._scanLab.setVisible(visible) self._scanQLE.setVisible(visible) def setDisplayModeVisible(self, visible): self._displayLab.setVisible(visible) self._displayMode.setVisible(visible) def getDisplayMode(self) -> _DisplayMode: """ :return: selected mode: display slices or radios """ return _DisplayMode(self._displayMode.currentText()) def setDisplayMode(self, mode): mode = _DisplayMode(mode) idx = self._displayMode.findText(mode.value) self._displayMode.setCurrentIndex(idx) def getRadioOption(self) -> _RadioMode: return _RadioMode(self._radioMode.currentText()) def setRadioOption(self, opt): opt = _RadioMode(opt) idx = self._radioMode.findText(opt.value) self._radioMode.setCurrentIndex(idx) def getSliceOption(self) -> _SliceMode: return _SliceMode(self._sliceMode.currentText()) def setSliceOption(self, opt): opt = _SliceMode(opt) idx = self._sliceMode.findText(opt.value) self._sliceMode.setCurrentIndex(idx) def _updateOptions(self, *args, **kwargs): mode = self.getDisplayMode() self._radioMode.setVisible(mode == _DisplayMode.RADIOS) self._sliceMode.setVisible(mode == _DisplayMode.SLICES) self._modeLab.setVisible(mode in (_DisplayMode.RADIOS, _DisplayMode.SLICES)) if mode is _DisplayMode.RADIOS: config = mode, self.getRadioOption() elif mode is _DisplayMode.SLICES: config = mode, self.getSliceOption() elif mode in ( _DisplayMode.DARKS, _DisplayMode.FLATS, _DisplayMode.REDUCED_DARKS, _DisplayMode.REDUCED_FLATS, ): config = mode, None else: raise ValueError("mode should be RADIOS or SLICES") if config != self._lastConfig: self._lastConfig = config self.sigDisplayModeChanged.emit() def setScanName(self, scan_name: str): self._scanQLE.setText(scan_name) def clear(self): self._scanQLE.clear() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9491017 tomwer-1.6.17/src/tomwer/gui/visualization/diffviewer/0000755000175000017500000000000015153325403022145 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/visualization/diffviewer/__init__.py0000644000175000017500000000004714757047403024271 0ustar00paynopaynofrom .diffviewer import * # noqa F403 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/visualization/diffviewer/diffviewer.py0000644000175000017500000005004115153325210024645 0ustar00paynopayno# coding: utf-8 """ contains gui relative frame difference display """ from __future__ import annotations import functools import logging import os from enum import Enum import numpy from processview.core.dataset import DatasetIdentifier from silx.gui import icons as silx_icons from silx.gui import qt from silx.io.url import DataUrl from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils.image import shift_img from tomwer.gui.dialog.QDataDialog import QDataDialog from tomwer.gui.reconstruction.axis.CompareImages import CompareImages as _CompareImages from tomwer.gui.settings import Y_AXIS_DOWNWARD from tomwer.gui.utils.completer import UrlCompleterDialog from tomwer.gui.visualization.diffviewer.shiftwidget import TwoFramesShiftTab from tomwer.io.utils import get_slice_data _logger = logging.getLogger(__name__) class CompareImages(_CompareImages): def __init__(self, parent=None, backend=None): super().__init__(parent=parent, backend=backend) # ignore Pan with arrow keys. This should be used by the "arrowControlWidget" self.getPlot().setPanWithArrowKeys(False) self._firstVisible = True def setVisible(self, visible): if self._firstVisible: # hack to enforce matplotlib to replot the widget. # because it looks like it is missing to find the correct viewport # when not visible self.getPlot().resetZoom() self._firstVisible = False super().setVisible(visible) class _FrameSelector(qt.QWidget): """Selector to select a frame from dark, flat, projection (normalized or not) and a reconstruction""" sigCorrectionChanged = qt.Signal() """signal emitted when the correction changed""" sigSelectedUrlChanged = qt.Signal() """signal emitted when the selected url changed""" class FrameType(Enum): DARKS = "darks" FLATS = "flats" PROJ = "projections" ALIGN_PROJ = "alignment projections" RECON_SLICES = "slices reconstructed" def __init__(self, parent=None): qt.QWidget.__init__(self, parent) self._scan = None self._currentFrameUrlsText = [] self.setLayout(qt.QGridLayout()) self.layout().addWidget(qt.QLabel("frame type", self), 0, 0, 1, 1) self._frameTypeCB = qt.QComboBox(self) for frame_type in _FrameSelector.FrameType: self._frameTypeCB.addItem(frame_type.value) self.layout().addWidget(self._frameTypeCB, 0, 1, 1, 3) self.layout().addWidget(qt.QLabel("frame", self), 1, 0, 1, 1) self._frameUrlCB = qt.QComboBox(self) self.layout().addWidget(self._frameUrlCB, 1, 1, 1, 3) search_icon = silx_icons.getQIcon("zoom") self._researchUrlButton = qt.QPushButton(parent=self, icon=search_icon) self._researchUrlButton.setToolTip("search for a specific url") self._researchUrlButton.setFixedWidth(30) self.layout().addWidget(self._researchUrlButton, 1, 4, 1, 1) self._proj_normalized = qt.QCheckBox("corrected", self) self.layout().addWidget(self._proj_normalized, 2, 1, 1, 1) # connect signal / slot self._frameTypeCB.currentIndexChanged.connect(self._typeChanged) self._frameUrlCB.currentIndexChanged.connect(self._urlChanged) self._proj_normalized.toggled.connect(self._correctionChanged) self._researchUrlButton.released.connect(self._searchUrl) # default settings self._proj_normalized.setChecked(True) index = self._frameTypeCB.findText(self.FrameType.PROJ.value) self._frameTypeCB.setCurrentIndex(index) def setScan(self, scan): self._scan = scan self._typeChanged() def getScan(self): return self._scan def getCurrentUrl(self): if self._frameUrlCB.currentText() != "": return DataUrl(path=self._frameUrlCB.currentData(qt.Qt.UserRole)) else: return None def getTypeSelected(self): return self.FrameType(self._frameTypeCB.currentText()) def _typeChanged(self, *args, **kwargs): type_selected = self.FrameType(self.getTypeSelected()) self._proj_normalized.setVisible( type_selected in (self.FrameType.PROJ, self.FrameType.ALIGN_PROJ) ) if self._scan is None: return urls = [] urls_to_angles: dict[str, float] = {} self._currentFrameUrlsText.clear() self._frameUrlCB.clear() if type_selected == self.FrameType.DARKS: if self._scan.darks is not None: urls = self._scan.darks.values() elif type_selected == self.FrameType.FLATS: if self._scan.flats is not None: urls = self._scan.flats.values() elif type_selected == self.FrameType.PROJ: if isinstance(self._scan, NXtomoScan): angles_and_urls = self._scan.get_proj_angle_url(with_alignment=False) for angle, url in angles_and_urls.items(): urls.append(url) urls_to_angles[url.path()] = angle else: urls = self._scan.projections.values() elif type_selected == self.FrameType.ALIGN_PROJ: if self._scan.alignment_projections is not None: urls = self._scan.alignment_projections.values() elif type_selected == self.FrameType.RECON_SLICES: urls = self._scan.get_reconstructed_slices() else: raise ValueError(f"Type {type_selected} not managed") urls = sorted(urls, key=lambda url: url.path()) # if there is some angles missing, avoiding setting any angle because they are probably wrong # this will probably fail with EDF but this is legacy if len(urls_to_angles) != len(urls): urls_to_angles.clear() for url in urls: if len(urls_to_angles) > 0: text = f"angle={urls_to_angles[url.path()]}&" else: text = "" if url.data_slice() is not None: text = f"?{text}slice=".join( (os.path.basename(url.file_path()), str(url.data_slice())) ) else: text = os.path.basename(url.file_path()) user_data = url.path() self._frameUrlCB.addItem(text, user_data) self._currentFrameUrlsText.append(text) def _urlChanged(self, *args, **kwargs): self.sigSelectedUrlChanged.emit() def _searchUrl(self): current_url = self._frameUrlCB.currentText() dialog = UrlCompleterDialog( current_url=current_url, urls=tuple(self._currentFrameUrlsText), ) if dialog.exec(): new_url = dialog.selected_url() idx = self._frameUrlCB.findText(new_url) if idx >= 0: self._frameUrlCB.setCurrentIndex(idx) else: _logger.warning(f"Unable to find {new_url} in the list of urls") def _correctionChanged(self, *args, **kwargs): self.sigCorrectionChanged.emit() def needToNormalize(self): """ :return: True if the data need to be treated by a dark and flat field normalization. """ return self._proj_normalized.isChecked() and self.getTypeSelected() in ( self.FrameType.PROJ, self.FrameType.ALIGN_PROJ, ) def clear(self): self._scan = None self._frameUrlCB.clear() self._currentFrameUrlsText = [] class _FramesSelector(qt.QWidget): """Selector to select a frame from dark, flat, projection (normalized or not) and a reconstruction""" sigLeftFrameUpdateReq = qt.Signal() """signal emit when a left frame update is requested""" sigRightFrameUpdateReq = qt.Signal() """signal emit when a right frame update is requested""" sigLeftScanChanged = qt.Signal() """signal emit when the scan for the left display changed""" sigRightScanChanged = qt.Signal() """signal emit when the scan for the right display changed""" def __init__(self, parent=None): qt.QWidget.__init__(self, parent) self.setLayout(qt.QGridLayout()) self.setContentsMargins(0, 0, 0, 0) self.layout().setContentsMargins(0, 0, 0, 0) self._leftScanCB = _ScanComboBox(self) self._leftScanCB.layout().setContentsMargins(0, 0, 0, 0) self.layout().addWidget(self._leftScanCB, 0, 0, 1, 4) self._rightScanCB = _ScanComboBox(self) self._rightScanCB.layout().setContentsMargins(0, 0, 0, 0) self.layout().addWidget(self._rightScanCB, 0, 4, 1, 4) self._leftSelector = _FrameSelector(parent=self) self._leftSelector.layout().setSpacing(2) self.layout().addWidget(self._leftSelector, 1, 0, 3, 4) self._leftSelector.layout().setContentsMargins(0, 0, 0, 0) self._rightSelector = _FrameSelector(parent=self) self._rightSelector.layout().setSpacing(2) self.layout().addWidget(self._rightSelector, 1, 4, 3, 4) self._rightSelector.layout().setContentsMargins(0, 0, 0, 0) # signal / slot connection self._leftSelector.sigCorrectionChanged.connect(self.sigLeftFrameUpdateReq) self._rightSelector.sigCorrectionChanged.connect(self.sigRightFrameUpdateReq) self._leftSelector.sigSelectedUrlChanged.connect(self.sigLeftFrameUpdateReq) self._rightSelector.sigSelectedUrlChanged.connect(self.sigRightFrameUpdateReq) self._leftScanCB.sigScanChanged.connect(self._leftScanChanged) self._rightScanCB.sigScanChanged.connect(self._rightScanChanged) self._leftScanCB.sigRequestScanAdd.connect(self._addScanFrmDialogLeft) self._rightScanCB.sigRequestScanAdd.connect(self._addScanFrmDialogRight) def getLeftScan(self): return self._leftSelector.getScan() def setLeftScan(self, scan): self._leftScanCB.setScan(scan.get_identifier()) self._leftSelector.setScan(scan) def getRightScan(self): return self._rightSelector.getScan() def setRightScan(self, scan): self._rightScanCB.setScan(scan.get_identifier()) self._rightSelector.setScan(scan) def addScan(self, scan): if not isinstance(scan, TomwerScanBase): raise TypeError(f"scan should be an instance of {TomwerScanBase}") self._leftScanCB.addScan(scan.get_identifier()) self._rightScanCB.addScan(scan.get_identifier()) def _leftScanChanged(self): self._leftSelector.setScan(self._leftScanCB.getCurrentScan()) def _rightScanChanged(self): self._rightSelector.setScan(self._rightScanCB.getCurrentScan()) def getLeftUrl(self): return self._leftSelector.getCurrentUrl() def needToNormalizeLeft(self): return self._leftSelector.needToNormalize() def needToNormalizeRight(self): return self._rightSelector.needToNormalize() def getRightUrl(self): return self._rightSelector.getCurrentUrl() def _addScanFrmDialogLeft(self): self._addScanFrmDialog(link_to="left") def _addScanFrmDialogRight(self): self._addScanFrmDialog(link_to="right") def _addScanFrmDialog(self, link_to: str): assert link_to in ("left", "right"), "add scan should be in " "'left', 'right'" dialog = QDataDialog(self, multiSelection=True) if not dialog.exec(): dialog.close() return foldersSelected = dialog.files_selected() scan_to_set = None for folder in foldersSelected: try: scans = ScanFactory.create_scan_objects(scan_path=folder) except Exception as e: _logger.error( f"cannot create scan instances from {folder}. Error is {e}" ) else: for scan in scans: self._leftScanCB.addScan(scan.get_identifier()) self._rightScanCB.addScan(scan.get_identifier()) scan_to_set = scan if scan_to_set is not None: if link_to == "left": self._leftScanCB.setScan(scan_id=scan_to_set.get_identifier()) else: self._rightScanCB.setScan(scan_id=scan_to_set.get_identifier()) def clear(self): self._leftScanCB.clear() self._rightScanCB.clear() self._leftSelector.clear() self._rightSelector.clear() class DiffFrameViewer(qt.QMainWindow): """ Widget used to compare two frames using the silx CompareImages widget. User can select a reconstruction, a projection (normalized or not), flat or dark. """ def __init__(self, parent=None, backend=None): qt.QMainWindow.__init__(self, parent) self.setWindowFlags(qt.Qt.Widget) # add frame selector self._framesSelector = _FramesSelector(parent=self) self._framesSelector.setContentsMargins(0, 0, 0, 0) self._framesSelector.layout().setContentsMargins(0, 0, 0, 0) self._framesSelectorDW = qt.QDockWidget(parent=self) self._framesSelectorDW.setWindowTitle("inputs") self._framesSelectorDW.setWidget(self._framesSelector) self.addDockWidget(qt.Qt.TopDockWidgetArea, self._framesSelectorDW) # add shift dock widget self._shiftsWidget = TwoFramesShiftTab(self) self._shiftsWidget.setContentsMargins(2, 2, 2, 2) self._shiftDW = qt.QDockWidget(parent=self) self._shiftDW.setWidget(self._shiftsWidget) self._shiftDW.setWindowTitle("shifts") self.addDockWidget(qt.Qt.TopDockWidgetArea, self._shiftDW) # define central widget self._mainWidget = CompareImages(parent=self, backend=backend) self._mainWidget.setVisualizationMode( CompareImages.VisualizationMode.COMPOSITE_A_MINUS_B ) self._mainWidget.getPlot().setYAxisInverted(Y_AXIS_DOWNWARD) self.setCentralWidget(self._mainWidget) # tabify the two dock widget to reduce space occupy self.tabifyDockWidget(self._shiftDW, self._framesSelectorDW) # toolbar # add toolbar toolbar = qt.QToolBar(self) toolbar.setMovable(False) toolbar.setFloatable(False) self.addToolBar(qt.Qt.TopToolBarArea, toolbar) # set up self._mainWidget.setAutoResetZoom(False) self._shiftsWidget.setFocus(qt.Qt.OtherFocusReason) # connect signal / slot self._framesSelector.sigRightFrameUpdateReq.connect(self._resetRightFrame) self._framesSelector.sigLeftFrameUpdateReq.connect(self._resetLeftFrame) self._shiftsWidget.sigShiftsChanged.connect(self._frameShiftsChanged) def getShiftsWidget(self): return self._shiftsWidget def addScan(self, scan): self._framesSelector.addScan(scan=scan) def getLeftScan(self) -> TomwerScanBase: return self._framesSelector.getLeftScan() def setLeftScan(self, scan: TomwerScanBase): return self._framesSelector.setLeftScan(scan) def getRightScan(self) -> TomwerScanBase: return self._framesSelector.getRightScan() def setRightScan(self, scan: TomwerScanBase): return self._framesSelector.setRightScan(scan) def getShiftFrameA(self) -> tuple: return self._shiftsWidget.getFrameAShift() def getShiftFrameB(self) -> tuple: return self._shiftsWidget.getFrameBShift() def isFrameALRFlip(self) -> bool: return self._shiftsWidget.isFrameALRFlip() def isFrameBLRFlip(self) -> bool: return self._shiftsWidget.isFrameBLRFlip() def _resetLeftFrame(self): scan = self.getLeftScan() if scan is None: return url = self._framesSelector.getLeftUrl() if url is None: return assert isinstance(url, DataUrl) data = self._get_data(url.path()) if self._framesSelector.needToNormalizeLeft(): data = scan.data_flat_field_correction( data=data, index=scan.get_url_proj_index(url) ) if data.ndim != 2: if data.ndim == 3 and data.shape[0] == 1: data = data.reshape((data.shape[1], data.shape[2])) else: _logger.error(f"Cannot display {url.path()}. Should be 2D") return if self.isFrameALRFlip(): data = numpy.fliplr(data) shifted_image = shift_img( data=data, dx=self.getShiftFrameA()[0], dy=self.getShiftFrameA()[1] ) self._mainWidget.setImage1(shifted_image) @functools.lru_cache(maxsize=4) def _get_data(self, url: str): if not isinstance(url, str): raise TypeError(f"url should be a str not {type(url)}") return get_slice_data(DataUrl(path=url)) def _resetRightFrame(self): scan = self.getRightScan() if scan is None: return url = self._framesSelector.getRightUrl() if url is None: return assert isinstance(url, DataUrl) data = self._get_data(url.path()) if self._framesSelector.needToNormalizeRight(): data = scan.data_flat_field_correction( data=data, index=scan.get_url_proj_index(url) ) if data.ndim != 2: if data.ndim == 3 and data.shape[0] == 1: data = data.reshape((data.shape[1], data.shape[2])) else: _logger.error(f"Cannot display {url.path()}. Should be 2D") return if self.isFrameBLRFlip(): data = numpy.fliplr(data) shifted_image = shift_img( data=data, dx=self.getShiftFrameB()[0], dy=self.getShiftFrameB()[1] ) self._mainWidget.setImage2(shifted_image) def _frameShiftsChanged(self): self._resetLeftFrame() self._resetRightFrame() class _ScanComboBox(qt.QWidget): sigScanChanged = qt.Signal() """Signal emit when the scan change""" sigRequestScanAdd = qt.Signal() """Signal emit when the user request to add a scan from a dialog""" def __init__(self, parent): qt.QWidget.__init__(self, parent) self._scans = set() self.setLayout(qt.QHBoxLayout()) self.setContentsMargins(0, 0, 0, 0) self.layout().setContentsMargins(0, 0, 0, 0) # scan combobox self._scansCB = qt.QComboBox(self) self.layout().addWidget(self._scansCB) # add scan button self._addButton = qt.QPushButton(self) self._addButton.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Minimum) self._addButton.setMaximumSize(25, 25) # self._addButton.setFixedSize(30, 30) style = qt.QApplication.instance().style() icon = style.standardIcon(qt.QStyle.SP_DirIcon) self._addButton.setIcon(icon) self.layout().addWidget(self._addButton) # connect signal / slot self._scansCB.currentIndexChanged.connect(self._scanChanged) self._addButton.released.connect(self.sigRequestScanAdd) def clear(self): self._scans = set() self._scansCB.clear() def addScan(self, scan_id: DatasetIdentifier): if not isinstance(scan_id, DatasetIdentifier): raise TypeError("scan should be the scan identifier") if scan_id not in self._scans: self._scans.add(scan_id) self._scansCB.addItem(str(scan_id), scan_id) def setScan(self, scan_id: DatasetIdentifier): if not isinstance(scan_id, DatasetIdentifier): raise TypeError("scan should be the scan identifier") idx = self._scansCB.findText(str(scan_id)) self._scansCB.setCurrentIndex(idx) def _scanChanged(self, *args, **kwargs): self.sigScanChanged.emit() def getCurrentScan(self) -> TomwerScanBase: current_idx = self._scansCB.currentIndex() dataset_id = self._scansCB.itemData(current_idx) try: scan = DatasetIdentifier.recreate_dataset(dataset_id) except Exception as e: _logger.error(f"Fail to recreate dataset from {dataset_id}. Reason is {e}.") return None else: return scan ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/visualization/diffviewer/shiftwidget.py0000644000175000017500000004611415153325210025042 0ustar00paynopayno# coding: utf-8 """ contains gui for diffviewer shift """ from __future__ import annotations from enum import Enum import sys from silx.gui import qt from tomwer.utils import docstring class _FrameShiftsBase: """dummy interface to define how to retrieve shift value""" def isFrameALRFlip(self) -> bool: """ :return: True if the frame A should be left-right shift """ raise NotImplementedError def getFrameAShift(self) -> tuple: """ :return: """ raise NotImplementedError def isFrameBLRFlip(self) -> bool: """ :return: True if the frame B should be left-right shift """ raise NotImplementedError def getFrameBShift(self) -> tuple: """ :return: """ raise NotImplementedError class TwoFramesShiftTab(qt.QTabWidget, _FrameShiftsBase): sigShiftsChanged = qt.Signal(tuple) """Signal emit when the shift changed. Tuple contains shift_imgA, shift_imgB. Both are tuple of (x, y, lrflip) x and y are shift values as float. lrflip is a boolean notifying if we should flip image or not before applying the shift """ class ShiftMode(Enum): RELATIVE = "relative shift" ABSOLUTE = "absolute shift" def __init__(self, parent=None): super().__init__(parent) # create layout self._relativeShiftWidget = Relative2FramesShift(self) self.addTab(self._relativeShiftWidget, self.ShiftMode.RELATIVE.value) self._absoluteShiftWidget = Absolute2FramesShift(self) self.addTab(self._absoluteShiftWidget, self.ShiftMode.ABSOLUTE.value) # connect signal / slot self._absoluteShiftWidget.sigShiftsChanged.connect(self.sigShiftsChanged) self._relativeShiftWidget.sigShiftsChanged.connect(self.sigShiftsChanged) # set up self.setCurrentWidget(self._relativeShiftWidget) self._relativeShiftWidget.setFocus(qt.Qt.OtherFocusReason) self._relativeShiftWidget.setFocusPolicy(qt.Qt.StrongFocus) self.setFocusProxy(self._relativeShiftWidget) def getRelativeShiftWidget(self): return self._relativeShiftWidget def getShiftMode(self): if self.currentWidget() is self._relativeShiftWidget: return self.ShiftMode.RELATIVE elif self.currentWidget() is self._absoluteShiftWidget: return self.ShiftMode.ABSOLUTE else: raise NotImplementedError("mode not handled") @docstring(_FrameShiftsBase) def isFrameALRFlip(self) -> bool: if self.getShiftMode() is self.ShiftMode.ABSOLUTE: return self._absoluteShiftWidget.isFrameALRFlip() elif self.getShiftMode() is self.ShiftMode.RELATIVE: return self._relativeShiftWidget.isFrameALRFlip() else: raise NotImplementedError("mode not handled") @docstring(_FrameShiftsBase) def getFrameAShift(self) -> tuple: if self.getShiftMode() is self.ShiftMode.ABSOLUTE: return self._absoluteShiftWidget.getFrameAShift() elif self.getShiftMode() is self.ShiftMode.RELATIVE: return self._relativeShiftWidget.getFrameAShift() else: raise NotImplementedError("mode not handled") @docstring(_FrameShiftsBase) def isFrameBLRFlip(self) -> bool: if self.getShiftMode() is self.ShiftMode.ABSOLUTE: return self._absoluteShiftWidget.isFrameBLRFlip() elif self.getShiftMode() is self.ShiftMode.RELATIVE: return self._relativeShiftWidget.isFrameBLRFlip() else: raise NotImplementedError("mode not handled") @docstring(_FrameShiftsBase) def getFrameBShift(self) -> tuple: if self.getShiftMode() is self.ShiftMode.ABSOLUTE: return self._absoluteShiftWidget.getFrameBShift() elif self.getShiftMode() is self.ShiftMode.RELATIVE: return self._relativeShiftWidget.getFrameBShift() else: raise NotImplementedError("mode not handled") class Relative2FramesShift(qt.QWidget, _FrameShiftsBase): sigShiftsChanged = qt.Signal(tuple) """Signal emit when the shift changed. Tuple contains shift_imgA, shift_imgB. Both are tuple of (x, y, lrflip) x and y are shift values as float. lrflip is a boolean notifying if we should flip image or not before applying the shift """ DEFAULT_SINGLE_STEP = 0.5 MIN_SINGLE_STEP = 0.0001 MAX_SINGLE_STEP = 1000 RANGE_MIN_VALUE = -sys.float_info.max RANGE_MAX_VALUE = sys.float_info.max def __init__(self, parent=None): super().__init__(parent) self.setLayout(qt.QHBoxLayout()) # left spacer self._lSpacer = qt.QWidget(self) self.layout().addWidget(self._lSpacer) # define shift info (x and y shift, x-y shift) self._infoWidget = qt.QWidget(self) self._infoWidget.setLayout(qt.QFormLayout()) tSpacer = qt.QWidget(self) tSpacer.setSizePolicy( qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.MinimumExpanding ) self._infoWidget.layout().addRow(tSpacer) self._shiftsWidget = qt.QWidget(self) self._shiftsWidget.setLayout(qt.QHBoxLayout()) self._shiftsWidget.layout().setContentsMargins(0, 0, 0, 0) self._infoLabel = qt.QLabel( "note: This apply x shift on frame A. Frame B will be left-right flip and a -x shit and y shift are applied", self, ) font = self._infoLabel.font() font.setPixelSize(14) font.setItalic(True) self._infoLabel.setFont(font) self._infoLabel.setAlignment(qt.Qt.AlignRight | qt.Qt.AlignVCenter) self._infoWidget.layout().addRow(self._infoLabel) self._infoWidget.layout().addRow("shift", self._shiftsWidget) self._xShiftQLE = qt.QDoubleSpinBox(self) self._xShiftQLE.setPrefix("x:") self._xShiftQLE.setSuffix(" px") self._xShiftQLE.setRange(self.RANGE_MIN_VALUE, self.RANGE_MAX_VALUE) self._yShiftQLE = qt.QDoubleSpinBox(self) self._yShiftQLE.setPrefix("y:") self._yShiftQLE.setSuffix(" px") self._yShiftQLE.setRange(self.RANGE_MIN_VALUE, self.RANGE_MAX_VALUE) self._shiftsWidget.layout().addWidget(self._xShiftQLE) self._shiftsWidget.layout().addWidget(self._yShiftQLE) self.layout().addWidget(self._infoWidget) self._shiftStepSize = qt.QDoubleSpinBox(self) self._shiftStepSize.setValue(1) self._shiftStepSize.setRange(self.MIN_SINGLE_STEP, self.MAX_SINGLE_STEP) self._infoWidget.layout().addRow("steps", self._shiftStepSize) bSpacer = qt.QWidget(self) bSpacer.setSizePolicy( qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.MinimumExpanding ) self._infoWidget.layout().addRow(bSpacer) # define control arrows self._controlWidget = _ControlArrowWidget(self) self._controlWidget.layout().setContentsMargins(0, 0, 0, 0) self.layout().addWidget(self._controlWidget) # right spacer self._rSpacer = qt.QWidget(self) self.layout().addWidget(self._rSpacer) # connect signal / slot self._controlWidget.sigMoved.connect(self.move) self._xShiftQLE.valueChanged.connect(self._emitHasMoved) self._yShiftQLE.valueChanged.connect(self._emitHasMoved) self._shiftStepSize.valueChanged.connect(self._stepSizeChanged) # set up self._controlWidget.setFocusPolicy(qt.Qt.StrongFocus) self._controlWidget.setFocus(qt.Qt.OtherFocusReason) def move(self, direction: str): direction = _ControlArrowWidget.Direction(direction) shift = self._shiftStepSize.value() if direction is _ControlArrowWidget.Direction.RIGHT: self._xShiftQLE.setValue(self._xShiftQLE.value() + shift) elif direction is _ControlArrowWidget.Direction.LEFT: self._xShiftQLE.setValue(self._xShiftQLE.value() - shift) if direction is _ControlArrowWidget.Direction.UP: self._yShiftQLE.setValue(self._yShiftQLE.value() + shift) elif direction is _ControlArrowWidget.Direction.DOWN: self._yShiftQLE.setValue(self._yShiftQLE.value() - shift) old = self.blockSignals(True) self.blockSignals(old) self._emitHasMoved() def _emitHasMoved(self): self.sigShiftsChanged.emit( ( ( self.getFrameAXShift(), self.getFrameAYShift(), self.isFrameALRFlip(), ), ( self.getFrameBXShift(), self.getFrameBYShift(), self.isFrameBLRFlip(), ), ) ) def getFrameAXShift(self): return self._xShiftQLE.value() def getFrameAYShift(self): # to me does not make sense to have a up / down flip # neither than having the same shift or an inverted one. # so shift will always be apply on frame only B return 0 def getFrameBXShift(self): return -self._xShiftQLE.value() def getFrameBYShift(self): return self._yShiftQLE.value() @docstring(_FrameShiftsBase) def isFrameALRFlip(self) -> bool: return False # lr flip by default @docstring(_FrameShiftsBase) def getFrameAShift(self) -> tuple: return ( self.getFrameAXShift(), self.getFrameAYShift(), ) @docstring(_FrameShiftsBase) def isFrameBLRFlip(self) -> bool: return True # lr flip by default @docstring(_FrameShiftsBase) def getFrameBShift(self) -> tuple: return ( self.getFrameBXShift(), self.getFrameBYShift(), ) def _stepSizeChanged(self, step): self._xShiftQLE.setSingleStep(step) self._yShiftQLE.setSingleStep(step) def keyPressEvent(self, event): self._controlWidget.keyPressEvent(event=event) def setShiftStep(self, step): self._shiftStepSize.setValue(step) class _ControlArrowWidget(qt.QWidget): """Widget with arrows""" sigMoved = qt.Signal(str) """signal emit when one direction is activated. Will contain the direction in which we want to move""" class Direction(Enum): LEFT = "left" RIGHT = "right" UP = "up" DOWN = "down" ARROW_BUTTON_SIZE = 30 QKEY_TO_DIR = { qt.Qt.Key_Left: Direction.LEFT, qt.Qt.Key_Right: Direction.RIGHT, qt.Qt.Key_Up: Direction.UP, qt.Qt.Key_Down: Direction.DOWN, } def __init__(self, parent=None): super().__init__(parent) self.setLayout(qt.QGridLayout()) self.layout().setSpacing(2) self.layout().setContentsMargins(2, 2, 2, 2) style = qt.QApplication.style() # left arrow self._leftArrow = qt.QPushButton() self._leftArrow.setIcon(style.standardIcon(qt.QStyle.SP_ArrowLeft)) self._leftArrow.setMinimumSize( qt.QSize(self.ARROW_BUTTON_SIZE, self.ARROW_BUTTON_SIZE) ) self.layout().addWidget(self._leftArrow, 1, 0, 1, 1) # right arrow self._rightArrow = qt.QPushButton() self._rightArrow.setIcon(style.standardIcon(qt.QStyle.SP_ArrowRight)) self._rightArrow.setMinimumSize( qt.QSize(self.ARROW_BUTTON_SIZE, self.ARROW_BUTTON_SIZE) ) self.layout().addWidget(self._rightArrow, 1, 3, 1, 1) # up arrow self._upArrow = qt.QPushButton() self._upArrow.setIcon(style.standardIcon(qt.QStyle.SP_ArrowUp)) self._upArrow.setMinimumSize( qt.QSize(self.ARROW_BUTTON_SIZE, self.ARROW_BUTTON_SIZE) ) self.layout().addWidget(self._upArrow, 0, 1, 1, 1) # down self._downArrow = qt.QPushButton() self._downArrow.setIcon(style.standardIcon(qt.QStyle.SP_ArrowDown)) self._downArrow.setMinimumSize( qt.QSize(self.ARROW_BUTTON_SIZE, self.ARROW_BUTTON_SIZE) ) self.layout().addWidget(self._downArrow, 3, 1, 1, 1) # connect signal / slot self._leftArrow.released.connect(self._leftActivated) self._rightArrow.released.connect(self._rightActivated) self._upArrow.released.connect(self._upActivated) self._downArrow.released.connect(self._downActivated) # add keyboard shortcut self._leftArrowShortCut = qt.QShortcut(qt.Qt.LeftArrow, self) self._leftArrowShortCut.activated.connect(self._leftActivated) def _leftActivated(self, *args, **kwargs): self.sigMoved.emit(self.Direction.LEFT.value) def _rightActivated(self, *args, **kwargs): self.sigMoved.emit(self.Direction.RIGHT.value) def _upActivated(self, *args, **kwargs): self.sigMoved.emit(self.Direction.UP.value) def _downActivated(self, *args, **kwargs): self.sigMoved.emit(self.Direction.DOWN.value) def keyPressEvent(self, event): key = event.key() if key in self.QKEY_TO_DIR: self.sigMoved.emit(self.QKEY_TO_DIR[key].value) class Absolute2FramesShift(qt.QWidget, _FrameShiftsBase): sigShiftsChanged = qt.Signal(tuple) """Signal emit when the shift changed. Tuple is (shift_imgA, shift_imgB). Both are tuple of (x, y, lrflip) x and y are shift values as float. lrflip is a boolean notifying if we should flip image or not before applying the shift """ def __init__(self, parent=None): super().__init__(parent) self.setLayout(qt.QVBoxLayout()) self._infoLabel = qt.QLabel( "note: This apply shift of images and not of the cor. Do not expect to have the same behavior as the Axis widget manual mode", self, ) font = self._infoLabel.font() font.setPixelSize(14) font.setItalic(True) self._infoLabel.setFont(font) self._infoLabel.setAlignment(qt.Qt.AlignRight | qt.Qt.AlignVCenter) self.layout().addWidget(self._infoLabel) self._frameAShiftWidget = FrameShiftWidget(title="frame A", parent=self) self.layout().addWidget(self._frameAShiftWidget) self._frameBShiftWidget = FrameShiftWidget(title="frame B", parent=self) self.layout().addWidget(self._frameBShiftWidget) spacer = qt.QWidget(self) spacer.setSizePolicy( qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.MinimumExpanding ) self.layout().addWidget(spacer) # connect signal / slot self._frameAShiftWidget.sigShiftChanged.connect(self._shiftHasChanged) self._frameBShiftWidget.sigShiftChanged.connect(self._shiftHasChanged) def _shiftHasChanged(self, *args, **kwargs): self.sigShiftsChanged.emit( ( ( self.getFrameAShift()[0], self.getFrameAShift()[1], self.isFrameALRFlip(), ), ( self.getFrameBShift()[0], self.getFrameBShift()[1], self.isFrameBLRFlip(), ), ), ) @docstring(_FrameShiftsBase) def isFrameALRFlip(self) -> bool: return self._frameAShiftWidget.isLRFlip() @docstring(_FrameShiftsBase) def getFrameAShift(self) -> tuple: return ( self._frameAShiftWidget.getXShift(), self._frameAShiftWidget.getYShift(), ) @docstring(_FrameShiftsBase) def isFrameBLRFlip(self) -> bool: return self._frameBShiftWidget.isLRFlip() @docstring(_FrameShiftsBase) def getFrameBShift(self) -> tuple: return ( self._frameBShiftWidget.getXShift(), self._frameBShiftWidget.getYShift(), ) class FrameShiftWidget(qt.QWidget): sigShiftChanged = qt.Signal(tuple) """Signal emit when the shift changed. Tuple contains (x, y, lrflip) x, y values as float and lrflip as boolean""" DEFAULT_SINGLE_STEP = 0.5 MIN_SINGLE_STEP = 0.0001 MAX_SINGLE_STEP = 1000 RANGE_MIN_VALUE = -sys.float_info.max RANGE_MAX_VALUE = sys.float_info.max def __init__(self, title, parent=None) -> None: super().__init__(parent) self.setLayout(qt.QHBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) # define label self._label = qt.QLabel(f"{title} shift", self) self._label.setAlignment(qt.Qt.AlignRight | qt.Qt.AlignVCenter) self.layout().addWidget(self._label) # define x shift self._xShiftQDSB = qt.QDoubleSpinBox(self) self._xShiftQDSB.setPrefix("x:") self._xShiftQDSB.setSuffix("px") self._xShiftQDSB.setValue(0) self._xShiftQDSB.setRange(self.RANGE_MIN_VALUE, self.RANGE_MAX_VALUE) self.layout().addWidget(self._xShiftQDSB) # define y shift self._yShiftQDSB = qt.QDoubleSpinBox(self) self._yShiftQDSB.setPrefix("y:") self._yShiftQDSB.setSuffix("px") self._yShiftQDSB.setValue(0) self._yShiftQDSB.setRange(self.RANGE_MIN_VALUE, self.RANGE_MAX_VALUE) self.layout().addWidget(self._yShiftQDSB) # reset button self._resetPB = qt.QPushButton(self) style = qt.QApplication.style() resetIcon = style.standardIcon(qt.QStyle.SP_DialogResetButton) self._resetPB.setIcon(resetIcon) self._resetPB.setSizePolicy(qt.QSizePolicy.Fixed, qt.QSizePolicy.Fixed) self.layout().addWidget(self._resetPB) # shift steps self._shiftStepsQDSB = qt.QDoubleSpinBox(self) self._shiftStepsQDSB.setPrefix("steps:") self._shiftStepsQDSB.setSuffix("px") self._shiftStepsQDSB.setValue(1.0) self._shiftStepsQDSB.setRange(self.MIN_SINGLE_STEP, self.MAX_SINGLE_STEP) self.layout().addWidget(self._shiftStepsQDSB) self._shiftStepsQDSB.setRange(0.01, 100000) self._shiftStepsQDSB.setSingleStep(0.5) # lr flip self._lrFlipQCB = qt.QCheckBox("lr flip", self) self._lrFlipQCB.setToolTip("left-right flip") self.layout().addWidget(self._lrFlipQCB) self._lrFlipQCB.setChecked(False) # connect signal / slot self._resetPB.released.connect(self.clear) self._xShiftQDSB.valueChanged.connect(self._shiftHasChanged) self._yShiftQDSB.valueChanged.connect(self._shiftHasChanged) self._shiftStepsQDSB.valueChanged.connect(self._stepsHasChanged) self._lrFlipQCB.toggled.connect(self._shiftHasChanged) def _stepsHasChanged(self, *args, **kwargs): self._xShiftQDSB.setSingleStep(self.getSingleStep()) self._yShiftQDSB.setSingleStep(self.getSingleStep()) def getSingleStep(self): return self._shiftStepsQDSB.value() def getXShift(self) -> float: return self._xShiftQDSB.value() def getYShift(self) -> float: return self._yShiftQDSB.value() def clear(self): old = self.blockSignals(True) self._xShiftQDSB.setValue(0) self._yShiftQDSB.setValue(0) self.blockSignals(old) self._shiftHasChanged() def _shiftHasChanged(self, *args, **kwargs): shift = self.getXShift(), self.getYShift() self.sigShiftChanged.emit(shift) def isLRFlip(self) -> bool: return self._lrFlipQCB.isChecked() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/fullscreenplot.py0000644000175000017500000000713715143647637023455 0ustar00paynopaynofrom __future__ import annotations import weakref from silx.gui import qt from silx.gui.plot import Plot2D from silx.gui.colors import Colormap from tomwer.gui import icons from tomwer.gui.settings import Y_AXIS_DOWNWARD from tomwer.gui.stitching.stitchandbackground import StitchAndBackgroundAlphaMixIn class FullScreenPlot2D(Plot2D): """ Window which goal is to display a single frame into full screen :param master_colormap: optional colormap that could redefine values of the current plot colormap """ def __init__(self, parent=None, backend=None, master_colormap=None): super().__init__(parent, backend) if master_colormap is None: self.__master_colormap = master_colormap else: assert isinstance(master_colormap, Colormap) self.__master_colormap = weakref.ref(master_colormap) self.getPositionInfoWidget().hide() self.setYAxisInverted(Y_AXIS_DOWNWARD) self.setKeepDataAspectRatio(True) self.setAxesDisplayed(False) self.getColorBarWidget().hide() self.setWindowIcon(icons.getQIcon("tomwer")) # add toolbar to ease exit self.exit_toolbar = qt.QToolBar("exit", self) # add a spacer for conveniance spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Preferred) self.exit_toolbar.addWidget(spacer) self.addToolBar(self.exit_toolbar) # add exit button wen displayed full screen exit_icon = icons.getQIcon("exit") self._quitAction = qt.QAction(exit_icon, "exit", self) self.exit_toolbar.addAction(self._quitAction) if self.master_colormap is not None: master_colormap.sigChanged.connect(self._updateColormapFromMaster) self._updateColormapFromMaster() # connect signal / slot self._quitAction.triggered.connect(self.close) @property def master_colormap(self) -> Colormap | None: if self.__master_colormap is None: return None else: return self.__master_colormap() def _updateColormapFromMaster(self): if self.master_colormap is not None: current_colormap = self.getDefaultColormap() current_colormap.setFromColormap(self.master_colormap) class FullScreenStitching(FullScreenPlot2D, StitchAndBackgroundAlphaMixIn): def __init__( self, stitching_img, background_img, parent=None, backend=None, master_colormap=None, ): super().__init__(parent, backend, master_colormap) self._stitched_image = stitching_img self._composition_background = background_img self._update() self._backgroundToolbar = qt.QToolBar("background") self._backgroundToolbar.addAction(self._backGroundAction) self.insertToolBar(self.toolBar(), self._backgroundToolbar) self._backgroundToolbar.addWidget(self._alphaChannelWidget) # set up self.setKeepDataAspectRatio(True) def _updateAlphaImg(self, *args, **kwargs): alpha_img = self.getImage(self.LEGEND_STITCHED_FRAME) if alpha_img is not None: alpha_img.setAlpha(self.getStitchedImgAlpha()) def _updateAlphaBackgroundImg(self, *args, **kwargs): background_img = self.getImage(self.LEGEND_BACKGROUND) if background_img is not None: background_img.setAlpha(self.getBackgroundImgAlpha()) @property def mother_plot(self) -> Plot2D | None: if self._mother_plot is None: return None else: return self._mother_plot() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/imagestack.py0000644000175000017500000003702315143647637022521 0ustar00paynopaynofrom __future__ import annotations import os import time import logging import numpy import numpy.lib.npyio from silx.gui import qt from silx.gui.dialog.ColormapDialog import DisplayMode from silx.gui.plot.ImageStack import ImageStack as _ImageStack from silx.gui.plot.ImageStack import UrlLoader from silx.io.url import DataUrl from tomwer.core.utils.ftseriesutils import get_vol_file_shape from tomwer.gui import icons from tomwer.gui.visualization.fullscreenplot import FullScreenPlot2D from tomwer.gui.visualization.reconstructionparameters import ReconstructionParameters from tomwer.gui.visualization.scanoverview import ScanOverviewWidget from tomwer.io.utils.utils import get_slice_data from tomwer.core.scan.scanbase import TomwerScanBase try: from PIL import Image except ImportError: # pragma: no cover has_PIL = False # pragma: no cover else: has_PIL = True _logger = logging.getLogger(__name__) class ImageStack(_ImageStack): """ Image stack dedicated to data display. It deal for example with data normalization... """ def __init__(self, parent, show_overview=True, backend=None): self._sliceMetadata: dict[str, dict] = {} # metadata associated to the slice. Key is the url (as str) and value is the dict containing metadata self._urlToScan: dict[str, TomwerScanBase] = {} # dict to link each slice to a scan id (in the case slices are raw projections - to set _scanOverviewDockerWidget) self._normFct = None self._url_indexes = None super().__init__(parent) self.getPlotWidget().setBackend(backend) self.getPlotWidget().setKeepDataAspectRatio(True) # tune colormap dialog to have histogram by default colormapAction = self.getPlotWidget().getColormapAction() colormapDialog = colormapAction.getColormapDialog() colormapDialog.getHistogramWidget().setDisplayMode(DisplayMode.HISTOGRAM) colormapAction.setColormapDialog(colormapDialog) self.setUrlLoaderClass(_TomwerUrlLoader) # hide axis to be display self._plot.setAxesDisplayed(False) self._loadSliceParams = False self._resetZoom = True # add dock widget for reconstruction parameters self._reconsInfoDockWidget = qt.QDockWidget(parent=self) self._reconsWidgetScrollArea = qt.QScrollArea(self) self._reconsWidgetScrollArea.setWidgetResizable(True) self._reconsWidget = ReconstructionParameters(self) self._reconsWidgetScrollArea.setWidget(self._reconsWidget) self._reconsInfoDockWidget.setWidget(self._reconsWidgetScrollArea) self._reconsInfoDockWidget.setFeatures(qt.QDockWidget.DockWidgetMovable) self.addDockWidget(qt.Qt.RightDockWidgetArea, self._reconsInfoDockWidget) # add scan overview dock widget if show_overview: self._scanOverviewDockerWidget = qt.QDockWidget(parent=self) self._scanOverviewDockerWidget.setMaximumHeight(300) self._scanOverviewWidget = ScanOverviewWidget(self) self._scanOverviewDockerWidget.setWidget(self._scanOverviewWidget) self._scanOverviewDockerWidget.setFeatures(qt.QDockWidget.DockWidgetMovable) self.addDockWidget( qt.Qt.RightDockWidgetArea, self._scanOverviewDockerWidget ) else: self._scanOverviewWidget = None self._scanOverviewDockerWidget = None # add search self._searchWidget = qt.QLineEdit(parent=self) self._searchWidget.setPlaceholderText("search") search_icon = icons.getQIcon("search") self._searchWidget.addAction(search_icon, qt.QLineEdit.LeadingPosition) # reorder urlsTable (include search QLineEdit) container = qt.QWidget() container_layout = qt.QGridLayout(container) container_layout.addWidget(self._searchWidget, 0, 1, 1, 2) container_layout.addWidget(self._urlsTable._toggleButton, 1, 2, 1, 1) container_layout.addWidget(self._urlsTable, 1, 1, 1, 2) self._urlsTable._urlsTable.model() self._tableDockWidget.setWidget(container) # for now hide the "control" self._urlsTable._toggleButton.hide() # add an action to plot the url-image 'full size' fullScreenIcon = icons.getQIcon("full_screen") self._fullScreenAction = qt.QAction(fullScreenIcon, "pop up full screen") self.getPlotWidget().toolBar().addAction(self._fullScreenAction) self._fullScreenAction.triggered.connect(self._popCurrentImageFullScreen) # set up self.setAutoResetZoom(False) # connect signal / slot self.sigCurrentUrlChanged.connect(self.updateAllMetadataDisplayed) self._searchWidget.textChanged.connect(self._filterUrlList) def _filterUrlList(self, *args, **kwargs): """Filter the url list according to the 'searchWidget'""" url_list = self._urlsTable._urlsTable filter_str = self._searchWidget.text() filter_str = filter_str.lstrip(" ").rstrip(" ") for item_index in range(url_list.count()): item = url_list.item(item_index) item.setHidden(filter_str not in item.text()) def _popCurrentImageFullScreen(self, *args, **kwargs): new_plot = FullScreenPlot2D() active_image = self.getPlotWidget().getActiveImage() if active_image is None or active_image.getData(copy=False) is None: return url = self.getCurrentUrl() window_title = f"Plot of {url.path()}" if url is not None else "Image Plot" new_plot.setWindowTitle(window_title) # reuse the same colormap for convenience (user modification on it will be applied everywhere) new_plot.setDefaultColormap(self.getPlotWidget().getDefaultColormap()) # add the current image new_plot.addImage(active_image.getData(copy=True)) new_plot.showFullScreen() def setScan(self, scan): if self._scanOverviewWidget is not None: self._scanOverviewWidget.setScan(scan=scan) def getUrlListDockWidget(self): return self._tableDockWidget def resetZoom(self): self._plot.resetZoom() def setLimits(self, x_min, x_max, y_min, y_max): self._plot.setLimits(xmin=x_min, ymin=y_min, xmax=x_max, ymax=y_max) def getLimits(self): limits = [] limits.extend(self._plot.getGraphXLimits()) limits.extend(self._plot.getGraphYLimits()) return tuple(limits) def setSliceReconsParamsVisible(self, visible): """show or not information regarding the slice reconstructed""" self._reconsInfoDockWidget.setVisible(visible) self._loadSliceParams = visible def setScanOverviewVisible(self, visible): """show or not overview of the scan""" if self._scanOverviewDockerWidget is not None: self._scanOverviewDockerWidget.setVisible(visible) def setNormalizationFct(self, fct, url_indexes=None): self._normFct = fct self._url_indexes = url_indexes def _urlLoaded(self) -> None: """ :param url: result of DataUrl.path() function :return: """ sender = self.sender() url = sender.url.path() if self._urlIndexes is not None and url in self._urlIndexes: data = sender.data if data is None: _logger.warning("no data found (is the url valid ?) " + url) return if data.ndim != 2: if data.ndim == 3: if data.shape[0] == 1: # if reconstruction along z data = data.reshape((data.shape[1], data.shape[2])) elif data.shape[1] == 1: # if reconstruction along y data = data.reshape((data.shape[0], data.shape[2])) elif data.shape[2] == 1: # if reconstruction along z data = data.reshape((data.shape[0], data.shape[1])) else: _logger.warning(f"Image Stack only manage 2D data. Url: {url}") return else: _logger.warning(f"Image Stack only manage 2D data. Url: {url}") return if self._normFct is None: self._urlData[url] = data else: norm_data = self._normFct(data, index=self._urlIndexes[url]) self._urlData[url] = norm_data if self.getCurrentUrl().path() == url: self._plot.addImage(self._urlData[url]) if hasattr(self, "getWaiterOverlay"): self.getWaiterOverlay().hide() else: self._waitingOverlay.hide() if self._resetZoom: self._resetZoom = False self._plot.resetZoom() if sender in self._loadingThreads: self._loadingThreads.remove(sender) self.sigLoaded.emit(url) def setResetZoomOnNextIteration(self, reset): self._resetZoom = reset def setCurrentUrl(self, url: DataUrl): if url in ("", None): url = None elif isinstance(url, str): url = DataUrl(path=url) elif not isinstance(url, DataUrl): raise TypeError if url is None: pass elif self._loadSliceParams: try: self.setCurrentSliceMetadata(self._metadata.get(url.path(), None)) except Exception: _logger.info(f"Failed to find any metadata for {url.path()}.") super().setCurrentUrl(url) def setUrls(self, urls: list): self.clearSliceMetadata() _ImageStack.setUrls(self, urls) listWidget = self._urlsTable._urlsTable items = [] for i in range(listWidget.count()): # TODO: do this on the fly item = listWidget.item(i) try: url = DataUrl(path=item.text()) except Exception: _logger.info( f"fail to deduce data of last modification for {item.text()}" ) else: if os.path.exists(url.file_path()): lst_m = time.ctime(os.path.getmtime(url.file_path())) item.setToolTip(f"last modification : {lst_m}") items.append(listWidget.item(i)) def updateAllMetadataDisplayed(self): # update widget related to image metadata. current_url = self.getCurrentUrl() if current_url is not None: current_url = current_url.path() self.setCurrentSliceMetadata(self._sliceMetadata.get(current_url, None)) current_scan = self._urlToScan.get(current_url, None) if self._scanOverviewWidget: self._scanOverviewWidget.setScan(current_scan) def clearSliceMetadata(self): self._sliceMetadata.clear() def setCurrentSliceMetadata(self, metadata: dict | None) -> None: self._reconsWidget.setVolumeMetadata(metadata) def setSliceMetadata(self, metadata: dict[str, dict]) -> None: self._sliceMetadata = metadata self.updateAllMetadataDisplayed() def updateSliceMetadata(self, metadata: dict[str, dict]) -> None: self._sliceMetadata.update(metadata) self.updateAllMetadataDisplayed() def updateScanToUrl(self, scan_to_url: dict): self._urlToScan.update(scan_to_url) self.updateAllMetadataDisplayed() # scan metadata loading def reset(self): super().reset() self.clearSliceMetadata() self._urlToScan.clear() def _freeLoadingThreads(self): # overwrite it because the default waiting time seems very low # and make the CI fails for thread in self._loadingThreads: thread.blockSignals(True) thread.wait(100) self._loadingThreads.clear() class _TomwerUrlLoader(UrlLoader): """ Thread use to load DataUrl """ def run(self): if self.url.file_path().endswith(".vol"): self.data = self._load_vol() elif self.url.scheme() == "tomwer": if has_PIL: self.data = numpy.array(Image.open(self.url.file_path())) if self.url.data_slice() is not None: self.data = self.data[self.url.data_slice()] else: _logger.warning( "need to install Pillow to read file " + self.url.file_path() ) self.data = None else: try: self.data = get_slice_data(self.url) except IOError: self.data = None except ValueError: self.data = None _logger.warning( f"Fail to open {self.url.path()}. Maybe the reconstruction failed." ) except Exception as e: self.data = None _logger.error( "Fail to load data from %s. Error is %s", self.url.path(), e, ) def _load_vol(self): """ load a .vol file """ if self.url.file_path().lower().endswith(".vol.info"): info_file = self.url.file_path() raw_file = self.url.file_path().replace(".vol.info", ".vol") else: assert self.url.file_path().lower().endswith(".vol") raw_file = self.url.file_path() info_file = self.url.file_path().replace(".vol", ".vol.info") if not os.path.exists(raw_file): data = None mess = f"Can't find raw data file {raw_file} associated with {info_file}" _logger.warning(mess) elif not os.path.exists(info_file): mess = f"Can't find info file {info_file} associated with {raw_file}" _logger.warning(mess) data = None else: shape = get_vol_file_shape(info_file) if None in shape: _logger.warning(f"Fail to retrieve data shape for {info_file}.") data = None else: try: numpy.zeros(shape) except MemoryError: data = None _logger.warning( f"Raw file %s is too large for being read {raw_file}" ) else: data = numpy.fromfile( raw_file, dtype=numpy.float32, count=-1, sep="" ) try: data = data.reshape(shape) except ValueError: _logger.warning( f"unable to fix shape for raw file {raw_file}. Look for information in {info_file}" ) try: sqr = int(numpy.sqrt(len(data))) shape = (1, sqr, sqr) data = data.reshape(shape) except ValueError: _logger.info( f"deduction of shape size for {raw_file} failed" ) data = None else: _logger.warning( f"try deducing shape size for {raw_file} might be an incorrect interpretation" ) if self.url.data_slice() is None: return data else: return data[self.url.data_slice()] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/visualization/nxtomometadata.py0000644000175000017500000000105714757047403023427 0ustar00paynopaynofrom silx.gui import qt from tomwer.gui.edit.nxtomoeditor import NXtomoEditor as _NXtomoEditor class NXtomoMetadataViewer(_NXtomoEditor): """ class to display metadata of a NXtomo. inherit from the `NXtomoEditor` and make sure not edition is possible """ def __init__(self, parent=None): super().__init__(parent) for widget in self.getEditableWidgets(): if isinstance(widget, (qt.QComboBox, qt.QCheckBox)): widget.setEnabled(False) else: widget.setReadOnly(True) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/gui/visualization/reconstructionparameters.py0000644000175000017500000002350215115744275025546 0ustar00paynopaynofrom __future__ import annotations import numpy import logging from silx.gui import qt from tomwer.core.utils.char import BETA_CHAR, DELTA_CHAR, MU_CHAR _logger = logging.getLogger(__name__) class ReconstructionParameters(qt.QWidget): """ display reconstruction parameters of a volume """ def __init__(self, parent=None): qt.QWidget.__init__(self, parent) self.setLayout(qt.QFormLayout()) # method self._methodQLE = qt.QLineEdit("", self) self.layout().addRow("Method", self._methodQLE) self._methodQLE.setReadOnly(True) # paganin self._paganinQLE = qt.QLineEdit("", self) self._paganinQLE.setReadOnly(True) self.layout().addRow("Phase method", self._paganinQLE) # delta beta self._deltaBetaLabel = qt.QLabel(" / ".join((DELTA_CHAR, BETA_CHAR)), self) self._deltaBetaQLE = qt.QLineEdit("", self) self._deltaBetaQLE.setReadOnly(True) self.layout().addRow(self._deltaBetaLabel, self._deltaBetaQLE) # sample_detector distance self._sampleDetectorDistanceInMeterQLE = qt.QLineEdit("", self) self._sampleDetectorDistanceInMeterQLE.setReadOnly(True) self.layout().addRow( "Sample-detector distance (m)", self._sampleDetectorDistanceInMeterQLE ) # pixel size self._voxelSizeInMicronQLE = qt.QLineEdit("", self) self._voxelSizeInMicronQLE.setReadOnly(True) self.layout().addRow(f"Voxel size ({MU_CHAR}m)", self._voxelSizeInMicronQLE) # cor self._corQLE = qt.QLineEdit("", self) self._corQLE.setReadOnly(True) self.layout().addRow("CoR (absolute)", self._corQLE) # padding type self._paddingTypeQLE = qt.QLineEdit("", self) self._paddingTypeQLE.setReadOnly(True) self.layout().addRow("Padding type", self._paddingTypeQLE) # half tomo self._halfTomoCB = qt.QCheckBox("", self) self._halfTomoCB.setEnabled(False) self.layout().addRow("Half tomo", self._halfTomoCB) # fbp filter type self._fbpFilterQLE = qt.QLineEdit("", self) self._fbpFilterQLE.setReadOnly(True) self.layout().addRow("FBP filter", self._fbpFilterQLE) # log min clip self._minLogClipQLE = qt.QLineEdit("", self) self._minLogClipQLE.setReadOnly(True) self.layout().addRow("Log min clip", self._minLogClipQLE) # log max clip self._maxLogClipQLE = qt.QLineEdit("", self) self._maxLogClipQLE.setReadOnly(True) self.layout().addRow("Log max clip", self._maxLogClipQLE) # sino normalization & normalization file self._sinonormalizationQLE = qt.QLabel("", self) self.layout().addRow("Sinogram normalization", self._sinonormalizationQLE) self._sinonormalizationFileQLE = qt.QLabel("", self) self.layout().addRow( "Sinogram normalization file", self._sinonormalizationFileQLE ) # software version self._softwareVersionQLE = qt.QLabel("", self) self.layout().addRow("Software version", self._softwareVersionQLE) # Connect signal for paganinQLE self._paganinQLE.textChanged.connect(self._updateDeltaBetaVisibility) def _updateDeltaBetaVisibility(self): phase_method = self._paganinQLE.text() display_delta_beta = phase_method in ("paganin", "CTF") self._deltaBetaLabel.setVisible(display_delta_beta) self._deltaBetaQLE.setVisible(display_delta_beta) def setVolumeMetadata(self, metadata: dict | None): if metadata is None: metadata = {} elif not isinstance(metadata, dict): raise TypeError(f"url should be a {dict}. {type(metadata)} provided") for func in ( self._setMethod, self._setPhaseMethod, self._setDeltaBeta, self._setDistance, self._setVoxelSize, self._setCor, self._setPaddingType, self._setHalfTomo, self._setFBPFilter, self._setMinLogClip, self._setMaxLogClip, self._setSinoNormalization, self._setSoftwareVersion, ): try: func(metadata) except Exception as e: _logger.warning(f"Fail update when call {func}. Error is", e) def _setMethod(self, metadata: dict): method = ( metadata.get("nabu_config", {}).get("reconstruction", {}).get("method", "") ) self._methodQLE.setText(method) def _setPhaseMethod(self, metadata: dict): phase_method = ( metadata.get("nabu_config", {}).get("phase", {}).get("method", "") ) # note: pahse method is expected to be in ("", "paganin", "CTF") self._paganinQLE.setText(phase_method) def _setDeltaBeta(self, metadata: dict): delta_beta = ( metadata.get("nabu_config", {}).get("phase", {}).get("delta_beta", "") ) self._deltaBetaQLE.setText(str(delta_beta)) def _setDistance(self, metadata: dict): distance_cm = ( metadata.get("processing_options", {}) .get("phase", {}) .get("distance_cm", None) ) or metadata.get("processing_options", {}).get("reconstruction", {}).get( "sample_detector_dist", None ) if distance_cm not in (None, "", "None"): distance_m = float(distance_cm) / 100.0 distance_m = f"{distance_m:.5}" else: distance_m = "" self._sampleDetectorDistanceInMeterQLE.setText(distance_m) def _setVoxelSize(self, metadata: dict): # voxel size can be stored as pixel size (old version) or voxel size (new version) recons_params = metadata.get("processing_options", {}).get("reconstruction", {}) voxel_size_cm = recons_params.get("voxel_size_cm", [None] * 3) # back compatibility when voxel was a scalar ( ~ nabu 2023 ?) if numpy.isscalar(voxel_size_cm): voxel_size_cm = [voxel_size_cm] * 3 # now voxel size is expected to be a tuple of three elements if voxel_size_cm is not None: def clean_voxel_value(value): if isinstance(value, str): for char_to_ignore in (" ", "(", ")", "[", "]"): value = value.replace(char_to_ignore, "") return value voxel_size_cm = [clean_voxel_value(value) for value in voxel_size_cm] else: # backward compatibility with old volume voxel_size_cm = recons_params.get("pixel_size_cm", [None] * 3) voxel_size_cm = filter(None, voxel_size_cm) def cast_voxel_value(value_cm: float): value_micron = value_cm * 10_000.0 return f"{float(value_micron):.2}" voxel_size_micron = [cast_voxel_value(value) for value in voxel_size_cm] self._voxelSizeInMicronQLE.setText("x".join(voxel_size_micron)) def _setCor(self, metadata: dict): cor = ( metadata.get("processing_options", {}) .get("reconstruction", {}) .get("rotation_axis_position", None) ) if cor not in (None, "None", "none"): cor = f"{float(cor):.2f}" else: cor = None self._corQLE.setText(cor if cor is not None else "") def _setPaddingType(self, metadata: dict): padding_type = ( metadata.get("processing_options", {}) .get("reconstruction", {}) .get("padding_type", "") ) self._paddingTypeQLE.setText(str(padding_type)) def _setHalfTomo(self, metadata: dict): enable_halftomo = ( metadata.get("processing_options", {}) .get("reconstruction", {}) .get("enable_halftomo", False) ) self._halfTomoCB.setChecked(enable_halftomo in ("True", "true", True, 1, "1")) def _setFBPFilter(self, metadata: dict): fbp_filter_type = ( metadata.get("processing_options", {}) .get("reconstruction", {}) .get("fbp_filter_type", "") ) self._fbpFilterQLE.setText(str(fbp_filter_type)) def _setMinLogClip(self, metadata: dict): log_min_clip = ( metadata.get("processing_options", {}) .get("take_log", {}) .get("log_min_clip", "") ) self._minLogClipQLE.setText(str(log_min_clip)) def _setMaxLogClip(self, metadata: dict): log_max_clip = ( metadata.get("processing_options", {}) .get("take_log", {}) .get("log_max_clip", "") ) self._maxLogClipQLE.setText(str(log_max_clip)) def _setSinoNormalization(self, metadata: dict): norm_method = ( metadata.get("processing_options", {}) .get("sino_normalization", {}) .get("method", "") ) sino_normalization_file = ( metadata.get("nabu_config", {}) .get("preproc", {}) .get("sino_normalization_file", "") ) self._sinonormalizationQLE.setText(norm_method) self._sinonormalizationFileQLE.setText(sino_normalization_file) self._sinonormalizationFileQLE.setToolTip(sino_normalization_file) self._sinonormalizationQLE.setVisible(norm_method is not None) self._sinonormalizationFileQLE.setVisible(sino_normalization_file is not None) def _setSoftwareVersion(self, metadata: dict): # for HDF5 the version is part of the metadata[version] section. For other this is part of metadata[process_info] software_version = metadata.get("version", None) or metadata.get( "process_info", {} ).get("nabu_version", None) if software_version is None: software_version = "" software = "nabu" self._softwareVersionQLE.setText(f"{software} ({software_version})") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/visualization/scanoverview.py0000644000175000017500000002321415153325210023076 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging import weakref import pint from dateutil import parser from silx.gui import qt from nxtomo.nxobject.nxdetector import FOV from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.scan.scanbase import TomwerScanBase _logger = logging.getLogger(__name__) _ureg = pint.get_application_registry() class ScanOverviewWidget(qt.QWidget): def __init__(self, parent=None): super().__init__(parent) self._scan = None self.setLayout(qt.QVBoxLayout()) self._tree = qt.QTreeWidget(self) self._tree.setColumnCount(2) self._tree.setHeaderLabels(("entry", "value")) self.layout().addWidget(self._tree) # 1: define instrument self._instrument = qt.QTreeWidgetItem(self._tree) self._instrument.setText(0, "instrument") # 1.1 define beam self._beam = qt.QTreeWidgetItem(self._instrument) self._beam.setText(0, "beam") self._energy = qt.QTreeWidgetItem(self._beam) self._energy.setText(0, "energy") # 1.1 define detector self._frames = qt.QTreeWidgetItem(self._instrument) self._frames.setText(0, "frames") self._projections = qt.QTreeWidgetItem(self._frames) self._projections.setText(0, "projections") self._darks = qt.QTreeWidgetItem(self._frames) self._darks.setText(0, "darks") self._flats = qt.QTreeWidgetItem(self._frames) self._flats.setText(0, "flats") self._alignments = qt.QTreeWidgetItem(self._frames) self._alignments.setText(0, "alignments") self._estimatedCOR = qt.QTreeWidgetItem(self._frames) self._estimatedCOR.setText(0, "estimated cor") self._detector_x_pixel_size = qt.QTreeWidgetItem(self._instrument) self._detector_x_pixel_size.setText(0, "x pixel size") self._detector_y_pixel_size = qt.QTreeWidgetItem(self._instrument) self._detector_y_pixel_size.setText(0, "y pixel size") # 2: define sample self._sample = qt.QTreeWidgetItem(self._tree) self._sample.setText(0, "sample") self._sample_name = qt.QTreeWidgetItem(self._sample) self._sample_name.setText(0, "name") self._sample_x_pixel_size = qt.QTreeWidgetItem(self._sample) self._sample_x_pixel_size.setText(0, "x pixel size") self._sample_y_pixel_size = qt.QTreeWidgetItem(self._sample) self._sample_y_pixel_size.setText(0, "y pixel size") # 3: other hight level items self._startTime = qt.QTreeWidgetItem(self._tree) self._startTime.setText(0, "start_time") self._endTime = qt.QTreeWidgetItem(self._tree) self._endTime.setText(0, "end_time") self._title = qt.QTreeWidgetItem(self._tree) self._title.setText(0, "title") self._scanRangeQLE = qt.QTreeWidgetItem(self._tree) self._scanRangeQLE.setText(0, "scan range") # set up self._instrument.setExpanded(True) self._frames.setExpanded(True) self._sample.setExpanded(True) self._beam.setExpanded(True) def setScan(self, scan): if scan is None: self._scan = scan elif not isinstance(scan, TomwerScanBase): raise TypeError(f"{scan} is expected to be an instance of {TomwerScanBase}") else: self._scan = weakref.ref(scan) if scan is not None: self.update_tree(scan=scan) def getScan(self): if self._scan is None or self._scan() is None: return None else: return self._scan() def update_tree(self, scan: TomwerScanBase): parts = { "instrument": self._updateInstrument, "times": self._updateTimes, "names": self._updateNames, "scan-range": self._updateScanRange, "sample": self._updateSample, } for part_name, fct in parts.items(): try: fct(scan=scan) except Exception: _logger.error(f"Failed to update '{part_name}'.", stack_info=True) self._tree.resizeColumnToContents(0) def _updateInstrument(self, scan: TomwerScanBase): self._updateFrames(scan=scan) self._updateEnergy(scan=scan) self._updateDetectorPixelSize(scan=scan) def _setColoredTxt( self, item, text, column=1, hightlight_red=False, hightlight_orange=False ): if text in (None, str(None)): text = "?" if hightlight_red: bkg_color = qt.QColor(220, 0, 0, 200) elif hightlight_orange: bkg_color = qt.QColor(200, 160, 0, 150) else: bkg_color = qt.QColor(0, 220, 0, 50) item.setText(column, text) item.setBackground(0, qt.QBrush(bkg_color)) def _updateSample(self, scan: TomwerScanBase): sample_x_pixel_size = scan.sample_x_pixel_size sample_y_pixel_size = scan.sample_y_pixel_size self._setColoredTxt( item=self._sample_x_pixel_size, text=self._toPintPrettyFormat( value=sample_x_pixel_size, unit=_ureg.meter, display_unit=_ureg.micrometer, ), hightlight_red=sample_x_pixel_size in (None, 0.0, 1.0), ) self._setColoredTxt( item=self._sample_y_pixel_size, text=self._toPintPrettyFormat( value=sample_y_pixel_size, unit=_ureg.meter, display_unit=_ureg.micrometer, ), hightlight_red=sample_y_pixel_size in (None, 0.0, 1.0), ) def _updateTimes(self, scan: TomwerScanBase): self._startTime.setText( 1, self._fromTimeStampToHumanReadableTime(scan.start_time) ) self._endTime.setText(1, self._fromTimeStampToHumanReadableTime(scan.end_time)) def _updateFrames(self, scan: TomwerScanBase): assert isinstance(scan, TomwerScanBase) # frames n_frames = len(scan.frames) self._setColoredTxt( item=self._frames, text=str(n_frames), hightlight_red=(n_frames in (0, None)), ) # projections n_proj = len(scan.projections) self._setColoredTxt( item=self._projections, text=str(n_proj), hightlight_red=(n_proj in (0, None)), ) # darks n_darks = len(scan.darks) self._setColoredTxt( item=self._darks, text=str(n_darks), hightlight_red=(n_darks in (0, None)), ) # flats n_flats = len(scan.flats) self._setColoredTxt( item=self._flats, text=str(n_flats), hightlight_red=(n_flats in (0, None)), ) # align n_alignment = len(scan.alignment_projections) self._setColoredTxt( item=self._alignments, text=str(n_alignment), ) if scan.field_of_view == FOV.HALF: if scan.x_rotation_axis_pixel_position is None: self._estimatedCOR.setText(1, "Unknown") else: self._estimatedCOR.setText(1, str(scan.x_rotation_axis_pixel_position)) else: self._estimatedCOR.setText(1, "only for half") def _updateEnergy(self, scan: TomwerScanBase): assert isinstance(scan, TomwerScanBase) self._setColoredTxt( item=self._energy, text=self._toPintPrettyFormat(scan.energy, _ureg.keV), hightlight_red=scan.energy in (0, None), ) def _updateNames(self, scan: TomwerScanBase): assert isinstance(scan, TomwerScanBase) sample_name = scan.sample_name sequence_name = scan.sequence_name self._title.setText(1, sequence_name) self._sample_name.setText(1, sample_name) def _updateTomoN(self, scan: TomwerScanBase): assert isinstance(scan, TomwerScanBase) tomo_n = scan.tomo_n self._setColoredTxt( item=self._tomoNQLE, text=str(tomo_n), ) def _updateScanRange(self, scan: TomwerScanBase): assert isinstance(scan, TomwerScanBase) self._setColoredTxt( item=self._scanRangeQLE, text=self._toPintPrettyFormat(scan.scan_range, _ureg.degree), ) def _updateDetectorPixelSize(self, scan: TomwerScanBase): assert isinstance(scan, TomwerScanBase) if isinstance(scan, EDFTomoScan): x_pixel_size = y_pixel_size = scan.pixel_size else: x_pixel_size = scan.detector_x_pixel_size y_pixel_size = scan.detector_y_pixel_size self._setColoredTxt( item=self._detector_x_pixel_size, text=self._toPintPrettyFormat(x_pixel_size, _ureg.meter, _ureg.micrometer), hightlight_red=x_pixel_size in (None, 0.0, 1.0), ) self._setColoredTxt( item=self._detector_y_pixel_size, text=self._toPintPrettyFormat(y_pixel_size, _ureg.meter, _ureg.micrometer), hightlight_red=y_pixel_size in (None, 0.0, 1.0), ) def clear(self): self._tree.clear() @staticmethod def _toPintPrettyFormat( value: None | float, unit: pint.Unit, display_unit: None | pint.Unit = None ) -> str: if value is None: return "Unknown" quantity = value * unit if display_unit is not None: return f"{quantity.to(display_unit):~P}" return f"{quantity:~P}" @staticmethod def _fromTimeStampToHumanReadableTime(timestamp) -> str: if timestamp is None: return "Unknown" dt = parser.parse(timestamp) return dt.strftime("%B %d, %Y, %H:%M:%S") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/visualization/sinogramviewer.py0000644000175000017500000002027515153325210023430 0ustar00paynopayno# coding: utf-8 """ contains gui relative to axis calculation using sinogram """ from __future__ import annotations import logging import weakref from silx.gui import qt from silx.gui.plot import Plot2D from silx.gui.widgets.WaitingOverlay import WaitingOverlay from tomwer.gui.settings import Y_AXIS_DOWNWARD _logger = logging.getLogger(__name__) class SinogramViewer(qt.QMainWindow): """ Widget to display a sinogram """ sigSinoLoadStarted = qt.Signal() """Signal emitted when some computation is started. For this widget some computation can be time consuming when creating the sinogram""" sigSinoLoadEnded = qt.Signal() """Signal emitted when a computation is ended""" def __init__( self, parent=None, scan=None, opts_orientation=qt.Qt.Vertical, backend=None, ): qt.QMainWindow.__init__(self, parent) self._scan = None self._sinoInfoCache = None # used to memorize sinogram properties when load it. # Contains (str(scan), line, oversampling) self._plot = Plot2D(parent=self) self._plotWaiter = WaitingOverlay(self._plot) self._plotWaiter.hide() self._plotWaiter.setIconSize(qt.QSize(30, 30)) self._plot.getMaskAction().setVisible(False) self._plot.setYAxisInverted(Y_AXIS_DOWNWARD) self._plot.getDefaultColormap().setVRange(None, None) self._plot.setAxesDisplayed(False) self._plot.setKeepDataAspectRatio(True) self._dockOpt = qt.QDockWidget(self) self._options = SinogramOpts(parent=self, orientation=opts_orientation) self._dockOpt.setWidget(self._options) self.setCentralWidget(self._plot) self._dockOpt.setFeatures(qt.QDockWidget.DockWidgetMovable) self.addDockWidget(qt.Qt.RightDockWidgetArea, self._dockOpt) # prepare processing self._loadingThread = _LoadSinoThread() # connect signal / slot self._options.sigUpdateRequested.connect(self.updateSinogram) self._loadingThread.finished.connect(self._sinogram_loaded) # expose API self.getActiveImage = self._plot.getActiveImage # set up if scan is not None: self.setScan(scan=scan) def getOptionsDockWidget(self): return self._dockOpt def setReconsParams(self, axis): self._axis_params = axis # TODO: update according to axis paramters def setScan(self, scan, update=True): if self._scan is None or self._scan() != scan: self._scan = weakref.ref(scan) self._options.setScan(scan) if update: self.updateSinogram() else: self.clear() def setLine(self, line: int): """ :param line: define the line we want to compute """ self._options.setRadioLine(line) def getLine(self): return self._options.getRadioLine() def setSubsampling(self, value): self._options.setSubsampling(value) def _updatePlot(self, sinogram): self._plot.addImage(data=sinogram) self._plot.replot() def _sinogram_loaded(self): """callback when the sinogram is loaded""" self._plotWaiter.hide() if self._scan is None or self._scan() is None: return assert self._sinoInfoCache is not None scan_id, line, subsampling = self._sinoInfoCache # if the scan changed since the load started, skip this update if scan_id != str(self._scan()): return # note: cache avoid reading data twice here. sinogram = self._scan().get_normed_sinogram(line=line, subsampling=subsampling) self._updatePlot(sinogram=sinogram) self.sigSinoLoadEnded.emit() self._options.setEnabled(True) def updateSinogram(self): if self._scan is None or self._scan() is None: return if self._loadingThread.isRunning(): _logger.warning( "a sinogram is already beeing computing, please wait until it" " ends" ) return # update scan self._plotWaiter.show() self.sigSinoLoadStarted.emit() self._sinoInfoCache = ( str(self._scan()), self._options.getRadioLine(), self._options.getSubsampling(), ) self._loadingThread.init( data=self._scan(), line=self._options.getRadioLine(), subsampling=int(self._options.getSubsampling()), ) self._loadingThread.start() def clear(self): self._plot.clear() def close(self): self._plotWaiter.hide() self._plot.close() self._plot = None super().close() class _LoadSinoThread(qt.QThread): def init(self, data, line, subsampling): self._scan = data self._line = line self._subsampling = subsampling def run(self): try: self._scan.get_normed_sinogram( line=self._line, subsampling=self._subsampling ) except ValueError as e: _logger.error(e) class SinogramOpts(qt.QDialog): """ Define the options to compute and display the sinogram """ sigUpdateRequested = qt.Signal() """signal emitted when an update of the sinogram (with different parameters) is requested""" def __init__(self, parent, orientation=qt.Qt.Vertical): qt.QDialog.__init__(self, parent) if orientation is qt.Qt.Vertical: self.setLayout(qt.QVBoxLayout()) elif orientation is qt.Qt.Horizontal: self.setLayout(qt.QHBoxLayout()) else: raise TypeError( "orientation should be either qt.Qt.Vertical or " "qt.Qt.Horizontal" ) self._scan = None # add line self._lineSelWidget = qt.QWidget(parent=self) self._lineSelWidget.setLayout(qt.QHBoxLayout()) self._lineSelWidget.layout().setContentsMargins(0, 0, 0, 0) self._lineSB = qt.QSpinBox(parent=self) self._lineSB.setMaximum(999999) self._lineSelWidget.layout().addWidget(qt.QLabel("radio line", self)) self._lineSelWidget.layout().addWidget(self._lineSB) self.layout().addWidget(self._lineSelWidget) # add subsampling option self._subsamplingWidget = qt.QWidget(parent=self) self._subsamplingWidget.setLayout(qt.QHBoxLayout()) self._subsamplingWidget.layout().setContentsMargins(0, 0, 0, 0) self._subsamplingSB = qt.QSpinBox(parent=self) self._subsamplingSB.setMinimum(1) self._subsamplingSB.setValue(4) self._subsamplingSB.setMaximum(100) self._subsamplingLabel = qt.QLabel("subsampling", self) self._subsamplingWidget.layout().addWidget(self._subsamplingLabel) self._subsamplingWidget.setToolTip( "if you like you can only take a " "subsample of the sinogram to " "speed up process" ) self._subsamplingWidget.layout().addWidget(self._subsamplingSB) self.layout().addWidget(self._subsamplingWidget) # add spacer spacer = qt.QWidget(self) spacer.setSizePolicy(qt.QSizePolicy.Minimum, qt.QSizePolicy.Expanding) self.layout().addWidget(spacer) types = qt.QDialogButtonBox.Apply self._buttons = qt.QDialogButtonBox(self) self._buttons.setStandardButtons(types) self.layout().addWidget(self._buttons) # connect signal / slot self._buttons.button(qt.QDialogButtonBox.Apply).clicked.connect( self.sigUpdateRequested ) def setLineSelectionVisible(self, visible): self._lineSelWidget.setVisible(visible) def setScan(self, scan): old = self.blockSignals(True) # update line max and value n_line = scan.dim_2 if n_line is None: n_line = 0 self._lineSB.setMaximum(n_line) self.blockSignals(old) def getRadioLine(self): return self._lineSB.value() def setRadioLine(self, line): self._lineSB.setValue(line) def getSubsampling(self): return self._subsamplingSB.value() def setSubsampling(self, value): self._subsamplingSB.setValue(value) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9491017 tomwer-1.6.17/src/tomwer/gui/visualization/test/0000755000175000017500000000000015153325403020772 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/visualization/test/__init__.py0000644000175000017500000000000014757047403023103 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/visualization/test/test_dataviewer.py0000644000175000017500000000215014757047403024546 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import unittest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from tomwer.gui.visualization.dataviewer import DataViewer, ImageStack class TestImageStack(TestCaseQt): """Test that the ImageStackWidget can be load and remove without any issue""" def setUp(self): TestCaseQt.setUp(self) self._widget = ImageStack(None) def tearDown(self): self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None self.qapp.processEvents() unittest.TestCase.tearDown(self) def test(self): pass class TestDataViewer(TestCaseQt): """Test that the data viewer can be load and remove without any issue""" def setUp(self): TestCaseQt.setUp(self) self._widget = DataViewer(None) def tearDown(self): self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None self.qapp.processEvents() unittest.TestCase.tearDown(self) def test(self): pass ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/visualization/test/test_diffviewer.py0000644000175000017500000000425214757047403024552 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging import os import shutil import tempfile import unittest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from tomwer.core.utils.scanutils import MockNXtomo from tomwer.gui.visualization.diffviewer import DiffFrameViewer logging.disable(logging.INFO) class TestDiffViewer(TestCaseQt): """unit test for the :class:_ImageStack widget""" def setUp(self): TestCaseQt.setUp(self) self._widget = DiffFrameViewer() self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.tmp_dir = tempfile.mkdtemp() self.scan1 = MockNXtomo( scan_path=os.path.join(self.tmp_dir, "myscan"), n_proj=20, n_ini_proj=20, dim=10, ).scan self.scan2 = MockNXtomo( scan_path=os.path.join(self.tmp_dir, "myscan"), n_proj=20, n_ini_proj=20, dim=10, ).scan def tearDown(self): shutil.rmtree(self.tmp_dir) self._widget.close() self._widget = None unittest.TestCase.tearDown(self) def test(self): """Make sur the addLeaf and clear functions are working""" self._widget.addScan(self.scan1) self._widget.addScan(self.scan2) self._widget.getLeftScan() # test shift shift_widgets = self._widget.getShiftsWidget() relShiftWidget = shift_widgets.getRelativeShiftWidget() relShiftWidget.setShiftStep(0.1) relShiftWidget.move("left") self.qapp.processEvents() relShiftWidget.setShiftStep(0.3) relShiftWidget.move("right") self.qapp.processEvents() relShiftWidget.setShiftStep(10) relShiftWidget.move("up") self.qapp.processEvents() relShiftWidget.setShiftStep(33) relShiftWidget.move("down") self.qapp.processEvents() # for the frame A y is expected to be always 0 assert relShiftWidget.getFrameAShift() == (0.2, 0) # for the frame B y is expected to be the shift. And x is supposed to be the opposite of the A.x shift assert relShiftWidget.getFrameBShift() == (-0.2, -23) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/test/test_nx_tomo_metadata_viewer.py0000644000175000017500000000543015143647637027330 0ustar00paynopaynoimport os import numpy import pint from nxtomo.application.nxtomo import NXtomo from silx.gui import qt from nxtomo.nxobject.nxdetector import ImageKey from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.gui.visualization.nxtomometadata import NXtomoMetadataViewer from tomwer.tests.conftest import qtapp # noqa F401 _ureg = pint.get_application_registry() def test_nx_editor( tmp_path, qtapp, # noqa F811 ): # 1.0 create nx tomo with raw data nx_tomo = NXtomo() nx_tomo.instrument.detector.x_pixel_size = 2.6e-6 * _ureg.meter nx_tomo.instrument.detector.y_pixel_size = 2.5e-6 * _ureg.meter nx_tomo.instrument.detector.field_of_view = "Half" nx_tomo.instrument.detector.distance = 59.0 * _ureg.meter nx_tomo.instrument.detector.set_transformation_from_x_flipped(True) nx_tomo.instrument.detector.set_transformation_from_y_flipped(False) nx_tomo.energy = 12.8 * _ureg.keV # warning: NXtomo uses McStas coordinate system nx_tomo.sample.z_translation = numpy.arange(12) * _ureg.meter nx_tomo.sample.y_translation = numpy.arange(2, 14) * _ureg.meter nx_tomo.instrument.detector.image_key_control = [ImageKey.PROJECTION.value] * 12 nx_tomo.instrument.detector.data = numpy.empty(shape=(12, 10, 10)) nx_tomo.sample.rotation_angle = numpy.linspace(0, 180, num=12) * _ureg.degree file_path = os.path.join(tmp_path, "nxtomo.nx") entry = "entry0000" nx_tomo.save( file_path=file_path, data_path=entry, ) scan = NXtomoScan(file_path, entry) # 2.0 create the widget and do the edition widget = NXtomoMetadataViewer() widget.setScan(scan=scan) widget.show() # 3.0 check data have been corrcetly loaded def check_metric(expected_value, current_value): if expected_value is None: return current_value is None return expected_value == current_value assert check_metric( 2.6e-6, widget._xDetectorPixelSizeMetricEntry.getValue().to(_ureg.meter).magnitude, ) assert widget._xDetectorPixelSizeMetricEntry._qcbUnit.currentText() == "m" assert check_metric( 2.5e-6, widget._yDetectorPixelSizeMetricEntry.getValue().to(_ureg.meter).magnitude, ) assert widget._yDetectorPixelSizeMetricEntry._qcbUnit.currentText() == "m" assert check_metric( 59, widget._sampleDetectorDistanceMetricEntry.getValue().to(_ureg.meter).magnitude, ) assert widget._sampleDetectorDistanceMetricEntry._qcbUnit.currentText() == "m" assert "Half" == widget._fieldOfViewCB.currentText() assert widget._lrFlippedCB.isChecked() assert not widget._udFlippedCB.isChecked() assert "12.8" == widget._energyEntry.text() # end widget.setAttribute(qt.Qt.WA_DeleteOnClose) widget.close() widget = None ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/gui/visualization/test/test_reconstruction_parameters.py0000644000175000017500000000364315115744275027727 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import pytest from tomwer.core.volume.hdf5volume import HDF5Volume from tomwer.gui.visualization.reconstructionparameters import ReconstructionParameters from tomwer.tests.conftest import qtapp # noqa F401 @pytest.mark.parametrize("phase_method", ("", "CTF", "Paganin")) def test_ReconstructionParameters(qtapp, phase_method): # noqa F401 window = ReconstructionParameters() volume = HDF5Volume( file_path="test.hdf5", data_path="data", data=None, metadata={ "nabu_config": { "reconstruction": { "method": "FBP", }, "phase": { "method": phase_method, "delta_beta": 110.0, }, }, "processing_options": { "reconstruction": { "voxel_size_cm": (0.2, 0.2, 0.2), "rotation_axis_position": 104, "enable_halftomo": True, "fbp_filter_type": "Hilbert", "sample_detector_dist": 0.4, }, "take_log": { "log_min_clip": 1.0, "log_max_clip": 10.0, }, }, }, ) window.setVolumeMetadata(metadata=volume.metadata) assert window._methodQLE.text() == "FBP" assert window._paganinQLE.text() == phase_method assert window._deltaBetaQLE.text() == "110.0" assert window._sampleDetectorDistanceInMeterQLE.text() == "0.004" assert window._voxelSizeInMicronQLE.text() == "2e+03x2e+03x2e+03" assert window._corQLE.text() == "104.00" assert window._halfTomoCB.isChecked() assert window._fbpFilterQLE.text() == "Hilbert" assert window._minLogClipQLE.text() == "1.0" assert window._maxLogClipQLE.text() == "10.0" window.setVolumeMetadata(metadata=None) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/visualization/test/test_sinogramviewer.py0000644000175000017500000000332614757047403025462 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging import os import shutil import tempfile import time import unittest from silx.gui import qt from silx.gui.utils.testutils import SignalListener, TestCaseQt from tomwer.core.utils.scanutils import MockNXtomo from tomwer.gui.visualization import sinogramviewer logging.disable(logging.INFO) class TestSinogramViewer(TestCaseQt): """unit test for the :class:_ImageStack widget""" def setUp(self): TestCaseQt.setUp(self) self._widget = sinogramviewer.SinogramViewer() self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.tmp_dir = tempfile.mkdtemp() self.scan = MockNXtomo( scan_path=os.path.join(self.tmp_dir, "myscan"), n_proj=20, n_ini_proj=20, dim=10, ).scan # listen to the 'sigSinoLoadEnded' signal from the sinogram viewer self.signalListener = SignalListener() self._widget.sigSinoLoadEnded.connect(self.signalListener) def tearDown(self): shutil.rmtree(self.tmp_dir) self._widget.close() self._widget = None unittest.TestCase.tearDown(self) def test(self): """Make sur the addLeaf and clear functions are working""" self._widget.setScan(self.scan) timeout = 10 while timeout >= 0 and self.signalListener.callCount() < 1: timeout -= 0.1 time.sleep(0.1) if timeout >= 0: raise TimeoutError("widget never emitted the sigSinogramLoaded " "signal") self._widget.show() self.qWaitForWindowExposed(self._widget) self.qapp.processEvents() self.assertTrue(self._widget.getActiveImage() is not None) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/gui/visualization/test/test_stacks.py0000644000175000017500000001410615153325210023671 0ustar00paynopaynoimport logging import os import numpy import pytest from silx.gui import qt from tomwer.core.volume.edfvolume import EDFVolume from tomwer.core.volume.hdf5volume import HDF5Volume from tomwer.core.process.reconstruction.output import ( PROCESS_FOLDER_RECONSTRUCTED_SLICES, ) from tomwer.core.utils.scanutils import MockNXtomo from tomwer.gui.stacks import RadioStack, SliceStack from tomwer.tests.utils import skip_gui_test from tomwer.tests.conftest import qtapp # noqa F401 logging.disable(logging.INFO) @pytest.mark.parametrize("use_identifiers", (True, False)) @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") def test_slice_stack( qtapp, # noqa F811 tmp_path, use_identifiers, ): """ :param use_identifiers: If true will add the different tomo object using identifiers instead of class instances. """ widget = SliceStack() widget.setAttribute(qt.Qt.WA_DeleteOnClose) url_list = widget._viewer._urlsTable._urlsTable assert url_list.count() == 0 n_scan = 5 root_dir = tmp_path / "test_slice_stack" root_dir.mkdir() def create_vol_data(n_slice=1): return numpy.random.random(10 * 10 * n_slice).reshape(n_slice, 10, 10) volume_metadata = { "nabu_config": { "reconstruction": { "method": "FBP", }, "phase": { "method": "paganin", "delta_beta": 110.0, }, }, "processing_options": { "reconstruction": { "voxel_size_cm": (0.2, 0.2, 0.2), "rotation_axis_position": 104, "enable_halftomo": True, "fbp_filter_type": "Hilbert", "sample_detector_dist": 0.4, }, "take_log": { "log_min_clip": 1.0, "log_max_clip": 10.0, }, }, } # step 1: test adding some scans for i_scan in range(n_scan): scan = MockNXtomo( scan_path=os.path.join(root_dir, f"scan{i_scan}"), n_proj=10, n_ini_proj=10, scan_range=180, dim=10, ).scan volume = EDFVolume( folder=os.path.join( scan.path, PROCESS_FOLDER_RECONSTRUCTED_SLICES, f"edf_volume_scan_{i_scan}", ), volume_basename=f"edf_volume_scan_{i_scan}", data=create_vol_data(), metadata=volume_metadata, ) volume.save() scan.set_latest_reconstructions((volume,)) assert len(scan.latest_reconstructions) == 1 if use_identifiers: widget.addTomoObj(scan.get_identifier().to_str()) else: widget.addTomoObj(scan) last_scan_added = scan assert url_list.count() == n_scan assert len(widget._volume_id_to_urls) == n_scan # step 2: test adding some volumes n_volume = 4 last_edf_volume_added = None last_hdf5_volume_added = None for i_vol in range(n_volume): volume_metadata["nabu_config"]["phase"]["delta_beta"] += i_vol volume_type = [EDFVolume, HDF5Volume][i_vol % 2] if volume_type == EDFVolume: volume = EDFVolume( folder=root_dir / PROCESS_FOLDER_RECONSTRUCTED_SLICES / f"slice_{i_vol}", volume_basename=f"slice_{i_vol}", data=create_vol_data(), metadata=volume_metadata, ) last_edf_volume_added = volume elif volume_type == HDF5Volume: volume = HDF5Volume( file_path=os.path.join( root_dir / PROCESS_FOLDER_RECONSTRUCTED_SLICES / f"my_vol_{i_vol}.hdf5" ), data_path="entry0000", data=create_vol_data(), metadata=volume_metadata, ) last_hdf5_volume_added = volume else: raise TypeError volume.save() if use_identifiers: widget.addTomoObj(volume.get_identifier().to_str()) else: widget.addTomoObj(volume) assert len(widget._volume_id_to_urls) == (n_scan + n_volume) assert len(widget._viewer.getUrls()) == (n_scan + n_volume) widget.clear() assert len(widget._volume_id_to_urls) == 0 # check adding objects from a list of string assert n_volume >= 2, "following test won't be able to be correctly executed" widget._addTomoObjectsFromStrList( [ last_hdf5_volume_added.file_path, last_edf_volume_added.url.file_path(), last_scan_added.path, ] ) # dummy check metadata are displayed widget._viewer._reconsWidget._deltaBetaQLE.text().startswith("1") assert len(widget._volume_id_to_urls) == 3 # try adding a non existing path widget._addTomoObjectsFromStrList( [ "/none/existing/path", "/none/existing/path.hdf5", ] ) widget.close() @pytest.mark.parametrize("use_identifiers", (True, False)) @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") def test_radio_stack( qtapp, # noqa F811 tmp_path, use_identifiers: bool, ): """ :param use_identifiers: If true will add the different tomo object using identifiers instead of class instances. """ widget = RadioStack() widget.setAttribute(qt.Qt.WA_DeleteOnClose) widget_urls = widget._viewer._urlsTable._urlsTable n_scan = 3 root_dir = tmp_path / "test_radio_stack" root_dir.mkdir() proj_per_scan = 10 # step 1: test adding some scans for i_scan in range(n_scan): scan = MockNXtomo( scan_path=os.path.join(root_dir, f"scan{i_scan}"), n_proj=proj_per_scan, n_ini_proj=proj_per_scan, scan_range=180, dim=10, ).scan if use_identifiers: widget.addTomoObj(scan.get_identifier().to_str()) else: widget.addTomoObj(scan) assert widget_urls.count() == n_scan * proj_per_scan widget.show() widget.close() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/gui/visualization/tomoobjoverview.py0000644000175000017500000000371314757047403023643 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.tomwer_object import TomwerObject from tomwer.core.volume.volumebase import TomwerVolumeBase from .scanoverview import ScanOverviewWidget from .volumeoverview import VolumeOverviewWidget class TomoObjOverview(qt.QWidget): """ Dummy widget to show ScanOverviewWidget if the object is a scan or VolumeOverviewWidget if the object is a Volume """ def __init__(self, parent=None) -> None: super().__init__(parent) self.setLayout(qt.QVBoxLayout()) self._scanOverview = ScanOverviewWidget(self) self.layout().addWidget(self._scanOverview) self._volumeOverview = VolumeOverviewWidget(self) self.layout().addWidget(self._volumeOverview) self._scanOverview.setVisible(False) self._volumeOverview.setVisible(False) def setTomoObj(self, tomo_obj: TomwerObject | None): """ update sub widgets according to the type of tomo_obj """ if tomo_obj is not None and not isinstance(tomo_obj, TomwerObject): raise TypeError( f"tomo_obj is expected to be an instance of {TomwerObject} and not {type(tomo_obj)}" ) # handle visibility self._volumeOverview.setVisible(isinstance(tomo_obj, TomwerVolumeBase)) self._scanOverview.setVisible(isinstance(tomo_obj, TomwerScanBase)) if isinstance(tomo_obj, TomwerVolumeBase): self._scanOverview.setScan(None) self._volumeOverview.setVolume(tomo_obj) elif isinstance(tomo_obj, TomwerScanBase): self._scanOverview.setScan(tomo_obj) self._volumeOverview.setVolume(None) elif tomo_obj is None: self._volumeOverview.setVolume(None) self._scanOverview.setScan(None) else: raise RuntimeError(f"TomwerObject of type {type(tomo_obj)} is not handled") ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9491017 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/0000755000175000017500000000000015153325403022703 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/CoordinateSystemOverlay.py0000644000175000017500000000125415143647637030134 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from tomwer.gui import icons try: from silx.gui.widgets.OverlayMixIn import OverlayMixIn as _OverlayMixIn except ImportError: from tomwer.third_part.OverlayMixIn import OverlayMixIn as _OverlayMixIn class CoordinateSystemOverlay(_OverlayMixIn, qt.QLabel): "Widget to be display an image on one of the four widget corner" def __init__(self, parent, img, img_size, *args, **kwargs): qt.QLabel.__init__(self, parent=parent) _OverlayMixIn.__init__(self, parent=parent, *args, **kwargs) self._imageQIcon = icons.getQIcon(img) self.setPixmap(self._imageQIcon.pixmap(img_size)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/GeometryOrMetadataWidget.py0000644000175000017500000000243615143647637030202 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from ._ReconstructionParameters import ReconstructionParameters from tomwer.gui.utils.illustrations import _IllustrationWidget class GeometryOrMetadataWidget(qt.QTabWidget): """Simple widget that display either esrf geometric reference or volume metadata""" def __init__(self, parent=...): super().__init__(parent) # reconstruction parameters self._metadataWidget = ReconstructionParameters() self._metadataScrollArea = qt.QScrollArea(self) self._metadataScrollArea.setWidgetResizable(True) self._metadataScrollArea.setWidget(self._metadataWidget) self.addTab(self._metadataScrollArea, "volume metadata") # coordinate system illustration self._geometricRefLabel = _IllustrationWidget(self, img="3D_coordinate_system") self.addTab(self._geometricRefLabel, "geometry") # expos API def setVolumeIdentifier(self, *args, **kwargs): self._metadataWidget.setVolumeIdentifier(*args, **kwargs) def setMetadata(self, metadata: dict): self._metadataWidget.setVolumeMetadata(metadata=metadata) def sizeHint(self) -> qt.QSize: # size hint to match the plot2D one and have equal initial size return qt.QSize(500, 534) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/VolumeViewerWidget.py0000644000175000017500000002651315143647637027100 0ustar00paynopaynofrom __future__ import annotations import logging import numpy import pint from functools import partial from silx.gui.plot.items.axis import Axis from silx.gui import qt from tomoscan.volumebase import SliceTuple from tomoscan.identifier import VolumeIdentifier from tomoscan.esrf.volume.singleframebase import VolumeSingleFrameBase from tomwer.core.volume.volumebase import TomwerVolumeBase from tomwer.core.volume import HDF5Volume from tomwer.gui.visualization.fullscreenplot import FullScreenPlot2D from tomwer.gui.visualization.TomoPlot2D import TomoPlot2D as _TomoPlot2D from .GeometryOrMetadataWidget import GeometryOrMetadataWidget from ._TomoPlot2DSlices import TomoPlot2DSlices from ._CrossHairs import CrossHairs _logger = logging.getLogger(__name__) _ureg = pint.get_application_registry() class VolumeViewerWidget(qt.QWidget): """ A window displaying slices side by side along the three direction with a 'geometric reference'. """ _HANDLE_WIDTH = 10 # px def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.setLayout(qt.QVBoxLayout()) self._verticalSplitter = qt.QSplitter(qt.Qt.Vertical) self._verticalSplitter.setHandleWidth(self._HANDLE_WIDTH) self.layout().addWidget(self._verticalSplitter) # horizontal top splitter self._horizontalTopSplitter = qt.QSplitter(qt.Qt.Horizontal) self._horizontalTopSplitter.setHandleWidth(self._HANDLE_WIDTH) self._XYPlot2D = TomoPlot2DSlices( parent=self, title="XY", color="red", image="3D_coordinate_system_XY", axis=0, ) self._horizontalTopSplitter.addWidget(self._XYPlot2D) self._YZPlot2D = TomoPlot2DSlices( parent=self, title="YZ", color="blue", image="3D_coordinate_system_YZ", axis=2, ) self._horizontalTopSplitter.addWidget(self._YZPlot2D) self._verticalSplitter.addWidget(self._horizontalTopSplitter) # vertical bottom splitter self._horizontalBottomSplitter = qt.QSplitter(qt.Qt.Horizontal) self._horizontalBottomSplitter.setHandleWidth(self._HANDLE_WIDTH) self._geometryOrMetadataWidget = GeometryOrMetadataWidget(parent=self) self._horizontalBottomSplitter.addWidget(self._geometryOrMetadataWidget) self._XZPlot2D = TomoPlot2DSlices( parent=self, title="XZ", color="green", image="3D_coordinate_system_XZ", axis=1, ) self._horizontalBottomSplitter.addWidget(self._XZPlot2D) self._verticalSplitter.addWidget(self._horizontalBottomSplitter) # define size policy self._YZPlot2D.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding) self._XZPlot2D.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding) self._XYPlot2D.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding) self._geometryOrMetadataWidget.setSizePolicy( qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding ) self._crossHairs = CrossHairs( XYPlot=self._XYPlot2D, XZPlot=self._XZPlot2D, YZPlot=self._YZPlot2D, ) # connect signal / slot for plot in ( self._YZPlot2D, self._XZPlot2D, self._XYPlot2D, ): plot.displayFullScreen.connect( partial( self._popUpImageFullScreen, plot, ) ) plot._sliceIndexSelection.valueChanged.connect(self._updateCrossHairs) def initVolumePreview(self, volume: TomwerVolumeBase, message: str | None): """ Set display for a new volume before the full volume or slices are loaded. For HDF5 and VolumeSingleFrame it will allow users to browse the dataset before the full volume or slices subset are loaded. Else we notify the user that some loading is on-going. """ self._geometryOrMetadataWidget.setVolumeIdentifier(volume.get_identifier()) if isinstance(volume, (HDF5Volume, VolumeSingleFrameBase)): # Z is the fast read axis for most file format. So we allow users to access it directly. _logger.info(f"Set {volume.get_identifier()} for preview.") self._XYPlot2D.setVolume(volume) try: vol_shape = volume.get_volume_shape() except OSError as e: _logger.warning(f"Fail to find volume shape. Error is {e}") vol_shape = None if vol_shape: self.setVolumeShape(shape=vol_shape) self._XYPlot2D.setCurrentIndex(vol_shape[0] // 2) elif isinstance(volume, TomwerVolumeBase): _logger.debug(f"No preview available for {volume.get_identifier()}.") self._XYPlot2D.setLoadingMessage(message) self._XYPlot2D.setLoading(True) else: raise TypeError(f"type not handled: {type(volume)}") for plot in (self._XZPlot2D, self._YZPlot2D): plot.setLoadingMessage(message) plot.clearActiveImage() plot.setLoading(True) def setVolume(self, volume: TomwerVolumeBase): """ Defines the volume. Expects to be loaded in memory to avoid freezing the GUI when browsing slices. """ self._XYPlot2D.setVolume(volume) self._XZPlot2D.setVolume(volume) self._YZPlot2D.setVolume(volume) def stopPreview(self): for plot in self._window.getPlots(): plot.setLoading(False) def getPlots(self) -> dict[str, _TomoPlot2D]: return { "XY": self._XYPlot2D.getPlot(), "YZ": self._YZPlot2D.getPlot(), "XZ": self._XZPlot2D.getPlot(), } def extendPlot(self, plot_name: str | None): """ Extend the requested plot to take most of the space in the widget. If None 'reset' the view to equally space the plots and metadata :param plot_name: None for reset else should be in ('XY', 'XZ', 'YZ') """ # warning: the bottom slides are using 3 values because we expect to have the # ColorbarWidget defined by the VolumeReconstructionSummaryWindow # reset splitters if plot_name is None: self._horizontalTopSplitter.setSizes([1, 1]) self._horizontalBottomSplitter.setSizes([2, 4, 6]) self._verticalSplitter.setSizes([1, 1]) elif plot_name == "XY": self._verticalSplitter.setSizes([1, 0]) self._horizontalTopSplitter.setSizes([1, 0]) elif plot_name == "YZ": self._verticalSplitter.setSizes([1, 0]) self._horizontalTopSplitter.setSizes([0, 1]) elif plot_name == "XZ": self._verticalSplitter.setSizes([0, 1]) self._horizontalBottomSplitter.setSizes([0, 0, 1]) else: raise ValueError(f"{plot_name!r} not handle.") def clear(self) -> None: self._YZPlot2D.clear() self._XZPlot2D.clear() self._XYPlot2D.clear() self.setLoading(False) def setLoading(self, loading: bool): self._YZPlot2D.setLoading(loading) self._XZPlot2D.setLoading(loading) self._XYPlot2D.setLoading(loading) def setSlices(self, slices: dict[SliceTuple, numpy.ndarray]): for axis, plot in { 0: self._XYPlot2D, 1: self._YZPlot2D, 2: self._XZPlot2D, }.items(): plot.setSlices( dict( filter( lambda item: item[0].axis == axis, slices.items(), ) ) ) def setVolumeShape(self, shape: tuple[int]) -> None: self._XYPlot2D.setSliceRange(0, shape[0] - 1) self._XZPlot2D.setSliceRange(0, shape[1] - 1) self._YZPlot2D.setSliceRange(0, shape[2] - 1) def getVolumeShape(self) -> tuple[int]: return ( self._XYPlot2D.getSliceRange()[1] + 1, self._XZPlot2D.getSliceRange()[1] + 1, self._YZPlot2D.getSliceRange()[1] + 1, ) def setVolumeMetadata(self, metadata: dict, volume_shape: tuple[int]): """ Warning: as the call might change the scale it must be called once the data is set. """ self._geometryOrMetadataWidget.setMetadata(metadata=metadata) self._updatePlotAxes(metadata=metadata, volume_shape=volume_shape) def _updatePlotAxes(self, metadata: dict, volume_shape: tuple[int]): """ Define axes limits and labels according to the volume metadata (when possible) """ reconstruction_metadata = metadata.get("processing_options", {}).get( "reconstruction", {} ) position_m = reconstruction_metadata.get("position", None) voxel_size_cm = reconstruction_metadata.get("voxel_size_cm", None) labels = ("Z", "Y", "X") if position_m is not None and voxel_size_cm is not None: voxel_size = numpy.array(voxel_size_cm) * _ureg.centimeter else: _logger.info("Missing metadata from volume. Cannot set axis values") voxel_size = [None] * 3 # Note: pixel size must be a scalar. So we arbitrarly choice one of the two values. Voxel are expected to be squares self._XYPlot2D.setVoxelSize(voxel_size[2]) self._XZPlot2D.setVoxelSize(voxel_size[2]) self._YZPlot2D.setVoxelSize(voxel_size[1]) map_silx_axis_to_index_axis: {Axis, int} = { self._XYPlot2D.getPlot().getXAxis(): 1, self._XYPlot2D.getPlot().getYAxis(): 2, self._YZPlot2D.getPlot().getXAxis(): 1, self._YZPlot2D.getPlot().getYAxis(): 0, self._XZPlot2D.getPlot().getXAxis(): 2, self._XZPlot2D.getPlot().getYAxis(): 0, } for silx_axis, axis_index in map_silx_axis_to_index_axis.items(): silx_axis.setLabel(labels[axis_index]) def _popUpImageFullScreen(self, plot: TomoPlot2DSlices): new_plot = FullScreenPlot2D() active_image = plot.getPlot().getActiveImage() if active_image is None or active_image.getData(copy=False) is None: return window_title = f"Plot of {plot.getTitle()}" new_plot.setWindowTitle(window_title) # add the current image new_plot.addImage( active_image.getData(copy=False), colormap=active_image.getColormap() ) new_plot.showFullScreen() def getMasterPlot(self) -> _TomoPlot2D: """ To apply the same colormap to the three plot we need to have a master / driver one. It has been decided arbitrarily to use the """ return self._YZPlot2D.getPlot() def getCrossHairs(self) -> CrossHairs: return self._crossHairs def resetZooms(self): for plot in self.getPlots().values(): plot.resetZoom() def setVolumeIdentifier(self, volume_identifier: VolumeIdentifier): self._geometryOrMetadataWidget.setVolumeIdentifier(volume_identifier) def _updateCrossHairs(self, *args, **kwargs): self._crossHairs.updateMarkers( XYIndex=self._XYPlot2D.getCurrentSliceIndex(), XZIndex=self._XZPlot2D.getCurrentSliceIndex(), YZIndex=self._YZPlot2D.getCurrentSliceIndex(), ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/VolumeViewerWindow.py0000644000175000017500000001507715143647637027127 0ustar00paynopaynofrom __future__ import annotations import logging import numpy from functools import partial from silx.gui import qt from silx.gui.plot.ColorBar import ColorBarWidget as _ColorBarWidget from tomoscan.volumebase import SliceTuple from tomwer.gui.utils.qt_utils import block_signals from .VolumeViewerWidget import VolumeViewerWidget from .toolbar import ToolBar from silx.gui.colors import Colormap _logger = logging.getLogger(__name__) class ColorBarWidget(_ColorBarWidget): def _activeImageChanged(self, previous, legend): # we are force to overwrite this function to avoid resetting the colormap when # image changes. Somehow just disconnection from `_disconnectPlot` is not enough pass class VolumeViewerWindow(qt.QMainWindow): """ Window dedicated to the volume reconstruction summary. It add a toolbar common to the three plots. """ sigLoadVolume = qt.Signal(bool) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._window = VolumeViewerWidget() self._slicesSet = False # main widget self.setCentralWidget(self._window) # colormap self._colormap = Colormap(name="gray", vmin=None, vmax=None) for plot in self._window.getPlots().values(): plot.setDefaultColormap(self._colormap) plot.sigActiveImageChanged.connect(self._onSliceLoaded) # colorbar self._colorbarWidget = ColorBarWidget( plot=self._window.getMasterPlot(), parent=self._window ) # Make colorbar background white self._colorbarWidget.setAutoFillBackground(True) self._colorbarWidget.layout().setSizeConstraint(qt.QLayout.SetNoConstraint) self._window._horizontalBottomSplitter.insertWidget(0, self._colorbarWidget) # window toolbar self._toolbar = ToolBar( master_plot=self._window.getMasterPlot(), parent=self._window.getMasterPlot(), colorbar=self._colorbarWidget, plots=self._window.getPlots().values(), ) self.addToolBar(self._toolbar) # set up self._toolbar.showCoordinatesSystemLabel.setChecked(False) self._toolbar.showToolbar.setChecked(False) # connect signal / slot self._toolbar._loadVolumeWidget.toggled.connect(self.sigLoadVolume) self._toolbar.getExtendXYPlotAction().triggered.connect( partial(self.extendPlot, "XY") ) self._toolbar.getExtendXZPlotAction().triggered.connect( partial(self.extendPlot, "XZ") ) self._toolbar.getExtendYZPlotAction().triggered.connect( partial(self.extendPlot, "YZ") ) self._toolbar.getResetDisplayAction().triggered.connect( partial(self.extendPlot, None) ) self._toolbar.getCrosshairsAction().sigVisibilityChanged.connect( self._updateCrosshairsVisibility ) def setSlicesAndMetadata( self, slices: dict[SliceTuple, numpy.ndarray], metadata: dict, volume_shape: tuple[int], ): self._slicesSet = len(slices) > 0 self._colorbarWidget.setColormap( self._colormap, data=numpy.concatenate(tuple(slices.values())) ) self._window.setVolumeShape(shape=volume_shape) self._window.setSlices(slices=slices) self._window.setVolumeMetadata(metadata=metadata, volume_shape=volume_shape) # required, especially because silx has known issues with it when keeping aspect ration self._window.resetZooms() self._updateCrosshairsVisibility() def _updateCrosshairsVisibility(self): plotXYMarkersVisible = ( self._toolbar.getCrosshairsAction().isChecked() and not self._window._XYPlot2D.isLoading() ) plotXZMarkersVisible = ( self._toolbar.getCrosshairsAction().isChecked() and not self._window._XZPlot2D.isLoading() ) plotYZMarkersVisible = ( self._toolbar.getCrosshairsAction().isChecked() and not self._window._YZPlot2D.isLoading() ) self._window.getCrossHairs().setVisible( plotXYMarkersVisible=plotXYMarkersVisible, plotXZMarkersVisible=plotXZMarkersVisible, plotYZMarkersVisible=plotYZMarkersVisible, ) def setLoading(self, loading: bool): """Function to interrupt loading - when finished or failed.""" self._window.setLoading(loading) self._updateCrosshairsVisibility() # expose API def getDefaultColormap(self) -> Colormap: return self._colormap def clear(self): self._slicesSet = False self._window.clear() def isLoadingVolume(self) -> bool: return self._toolbar._loadVolumeWidget.isChecked() def setLoadingVolume(self, loading_volume: bool) -> None: with block_signals(self): self._toolbar._loadVolumeWidget.setChecked(loading_volume) def setLoadingVolumeOptionVisible(self, visible) -> None: self._toolbar.getLoadVolumeAction().setVisible(visible) def initVolumePreview(self, *args, **kwargs): # reset colormap range to be able to update it when the first slice is displayed # (and before the full colormap is loaded in memory) self.reset() self._window.initVolumePreview(*args, **kwargs) self._updateCrosshairsVisibility() def reset(self): """Reset the widget: clear all plot and metadata""" self._colormap.setVRange(None, None) self._window.clear() def _onSliceLoaded(self, previous, legend): """ When a new slice is loaded and when the colormap min/max have not been set already we want to update the range from the current slice values """ if not self._slicesSet: data = self.sender().getImage(legend).getData() with block_signals(self._colormap): vMin, vMax = self._colormap._computeAutoscaleRange(data=data) self._colormap.setVRange(vMin, vMax) self._colormap.setVRange(None, None) def extendPlot(self, plot_name): # FIXME: we are force to hide / show the colorbar else # when calling the `setSizes` function this class # messup with the layout / resizing... couldn't find the origin of it. visible = self._colorbarWidget.isVisible() self._colorbarWidget.setVisible(False) self._window.extendPlot(plot_name) self._colorbarWidget.setVisible(visible) def setVolume(self, volume): self._window.setVolume(volume=volume) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/_CrossHairs.py0000644000175000017500000000627015143647637025520 0ustar00paynopaynofrom __future__ import annotations from ._TomoPlot2DSlices import _TomoPlot2D from silx.gui.plot.items import XMarker, YMarker from silx.gui import qt class CrossHairs: """ A class to manage and group markers within the VolumeViewerWidget. This class provides an API to: - Show or hide markers. - Update marker positions dynamically. """ XYColor = qt.QColor(255, 0, 0, 180) YZColor = qt.QColor(0, 0, 255, 180) XZColor = qt.QColor(0, 255, 0, 180) def __init__(self, XYPlot: _TomoPlot2D, XZPlot: _TomoPlot2D, YZPlot: _TomoPlot2D): self._XYPlot = XYPlot.getPlot() self._XZPlot = XZPlot.getPlot() self._YZPlot = YZPlot.getPlot() self._XYPlot_XMarker = YMarker() # Warning about naming: the pattern is '_XYPlot_[X|Y|Z]Marker'. In this case, the marker drawing the Y axis happens to be a XMarker. self._XYPlot_XMarker.setColor(CrossHairs.YZColor) self._XYPlot.addItem(self._XYPlot_XMarker) self._XYPlot_YMarker = XMarker() self._XYPlot_YMarker.setColor(CrossHairs.XZColor) self._XYPlot.addItem(self._XYPlot_YMarker) self._XZPlot_ZMarker = YMarker() self._XZPlot.addItem(self._XZPlot_ZMarker) self._XZPlot_ZMarker.setColor(CrossHairs.XYColor) self._XZPlot_XMarker = XMarker() self._XZPlot.addItem(self._XZPlot_XMarker) self._XZPlot_XMarker.setColor(CrossHairs.YZColor) self._YZPlot_ZMarker = YMarker() self._YZPlot.addItem(self._YZPlot_ZMarker) self._YZPlot_ZMarker.setColor(CrossHairs.XYColor) self._YZPlot_YMarker = XMarker() self._YZPlot.addItem(self._YZPlot_YMarker) self._YZPlot_YMarker.setColor(CrossHairs.XZColor) def getMarkers(self) -> dict[str, XMarker | YMarker]: return { "XYPlot": { "YMarker": self._XYPlot_YMarker, "XMarker": self._XYPlot_XMarker, }, "XZPlot": { "XMarker": self._XZPlot_XMarker, "ZMarker": self._XZPlot_ZMarker, }, "YZPlot": { "YMarker": self._YZPlot_YMarker, "ZMarker": self._YZPlot_ZMarker, }, } def setVisible( self, plotXYMarkersVisible: bool, plotXZMarkersVisible: bool, plotYZMarkersVisible: bool, ): self._XYPlot_XMarker.setVisible(plotXYMarkersVisible) self._XYPlot_YMarker.setVisible(plotXYMarkersVisible) self._XZPlot_XMarker.setVisible(plotXZMarkersVisible) self._XZPlot_ZMarker.setVisible(plotXZMarkersVisible) self._YZPlot_YMarker.setVisible(plotYZMarkersVisible) self._YZPlot_ZMarker.setVisible(plotYZMarkersVisible) def updateMarkers(self, XYIndex: int, XZIndex: int, YZIndex: int): """ Update marker positions according to the different XY, XZ, YZ positions """ self._XYPlot_YMarker.setPosition(XZIndex, 0) self._XYPlot_XMarker.setPosition(0, YZIndex) self._XZPlot_XMarker.setPosition(YZIndex, 0) self._XZPlot_ZMarker.setPosition(0, XYIndex) self._YZPlot_ZMarker.setPosition(0, XYIndex) self._YZPlot_YMarker.setPosition(XZIndex, 0) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/_HorizontalSliderWithBrowser.py0000644000175000017500000002041515143647637031131 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from silx.gui import icons from silx.gui.widgets.FrameBrowser import FrameBrowser try: from silx.gui.widgets.FrameBrowser import PlayButtonContextMenu except ImportError: from tomwer.third_part.FrameBrowser import PlayButtonContextMenu class HorizontalSliderWithBrowser(qt.QAbstractSlider): """ Slider widget combining a :class:`QSlider` and a :class:`FrameBrowser`. .. image:: img/HorizontalSliderWithBrowser.png The data model is an integer within a range. The default value is the default :class:`QSlider` value (0), and the default range is the default QSlider range (0 -- 99) The signal emitted when the value is changed is the usual QAbstractSlider signal :attr:`valueChanged`. The signal carries the value (as an integer). :param QWidget parent: Optional parent widget """ def __init__(self, parent=None): qt.QAbstractSlider.__init__(self, parent) self.setOrientation(qt.Qt.Horizontal) self.mainLayout = qt.QGridLayout(self) self.mainLayout.setContentsMargins(0, 0, 0, 0) self.mainLayout.setSpacing(2) self._slider = qt.QSlider(self) self._slider.setOrientation(qt.Qt.Horizontal) self._browser = FrameBrowser(self) # avoid focus on the on buttons that can be activated when editing the slice index (from the QLinEdit) for button in ( self._browser.firstButton, self._browser.previousButton, self._browser.nextButton, self._browser.lastButton, ): button.setFocusPolicy(qt.Qt.FocusPolicy.NoFocus) self.mainLayout.addWidget(self._slider, 0, 0, 1, 7) self.mainLayout.addWidget(self._browser, 0, 7, 1, 1) self._slider.valueChanged[int].connect(self._sliderSlot) self._browser.sigIndexChanged.connect(self._browserSlot) fontMetric = self.fontMetrics() iconSize = qt.QSize(fontMetric.height(), fontMetric.height()) self.__timer = qt.QTimer(self) self.__timer.timeout.connect(self._updateState) self._playButton = qt.QToolButton(self) self._playButton.setToolTip("Display dataset movie.") self._playButton.setIcon(icons.getQIcon("camera")) self._playButton.setIconSize(iconSize) self._playButton.setCheckable(True) self.mainLayout.addWidget(self._playButton, 0, 8, 1, 1) self._playButton.toggled.connect(self._playButtonToggled) self._menuPlaySlider = PlayButtonContextMenu(self) self._menuPlaySlider.sigFrameRateChanged.connect(self._frameRateChanged) self._frameRateChanged(self.getFrameRate()) self._playButton.setMenu(self._menuPlaySlider) self._playButton.setPopupMode(qt.QToolButton.MenuButtonPopup) # handle slice index buttons sliceButtonFont = self.font() sliceButtonFont.setPixelSize(8) # one-quarters button self.mainLayout.setColumnStretch(0, 1) self._oneQuarterButton = qt.QPushButton() self._oneQuarterButton.setFont(sliceButtonFont) self._oneQuarterButton.setFocusPolicy(qt.Qt.FocusPolicy.NoFocus) self.mainLayout.addWidget(self._oneQuarterButton, 1, 1, 1, 1) # two-quarters button self.mainLayout.setColumnStretch(2, 1) self._twoQuarterButton = qt.QPushButton() self._twoQuarterButton.setFont(sliceButtonFont) self._twoQuarterButton.setFocusPolicy(qt.Qt.FocusPolicy.NoFocus) self.mainLayout.addWidget(self._twoQuarterButton, 1, 3, 1, 1) # three-quarters button self.mainLayout.setColumnStretch(4, 1) self._threeQuarterButton = qt.QPushButton() self._threeQuarterButton.setFont(sliceButtonFont) self._threeQuarterButton.setFocusPolicy(qt.Qt.FocusPolicy.NoFocus) self.mainLayout.addWidget(self._threeQuarterButton, 1, 5, 1, 1) self.mainLayout.setColumnStretch(6, 1) self.setSliceIndices(None) self.setSliceBrowsingEnabled(False) # connect signal / slot for button in ( self._oneQuarterButton, self._twoQuarterButton, self._threeQuarterButton, ): button.pressed.connect(self.__quarterButtonPressed) def lineEdit(self): """Returns the line edit provided by this widget. :rtype: qt.QLineEdit """ return self._browser.lineEdit() def limitWidget(self): """Returns the widget displaying axes limits. :rtype: qt.QLabel """ return self._browser.limitWidget() def setMinimum(self, value): """Set minimum value :param int value: Minimum value""" self._slider.setMinimum(value) maximum = self._slider.maximum() self._browser.setRange(value, maximum) def setMaximum(self, value): """Set maximum value :param int value: Maximum value """ self._slider.setMaximum(value) minimum = self._slider.minimum() self._browser.setRange(minimum, value) def setRange(self, first, last): """Set minimum/maximum values :param int first: Minimum value :param int last: Maximum value""" self._slider.setRange(first, last) self._browser.setRange(first, last) def getRange(self) -> tuple[int, int]: return self._browser.getRange() def _sliderSlot(self, value): """Emit selected value when slider is activated""" self._browser.setValue(value) self.valueChanged.emit(value) def _browserSlot(self, ddict): """Emit selected value when browser state is changed""" self._slider.setValue(ddict["new"]) def setValue(self, value): """Set value :param int value: value""" self._slider.setValue(value) self._browser.setValue(value) def value(self): """Get selected value""" return self._slider.value() def setFrameRate(self, value: int): """Set the frame rate at which images are displayed""" self._menuPlaySlider.setFrameRate(value) def getFrameRate(self) -> int: """Get the frame rate at which images are displayed""" return self._menuPlaySlider.getFrameRate() def setPlayImageStep(self, value: int): """Set the step between displayed images when playing""" self._menuPlaySlider.setStep(value) def getPlayImageStep(self) -> int: """Returns the step between displayed images""" return self._menuPlaySlider.getStep() def _frameRateChanged(self, framerate: int): """Update the timer interval""" self.__timer.setInterval(int(1 / framerate * 1e3)) def _playButtonToggled(self, checked: bool): """Start/Stop the slider sequence.""" if checked: self.__timer.start() return self.__timer.stop() def _updateState(self): """Advance an interval number of frames in the browser sequence.""" currentIndex = self._browser.getValue() if currentIndex < self._browser.getRange()[-1]: self.setValue(currentIndex + self.getPlayImageStep()) else: self._playButton.setChecked(False) def setSliceIndices(self, slices: None | tuple[int]): if (slices is not None) and len(slices) != 3: raise TypeError("slices is not None or a tuple of three elements.") slices_buttons = ( self._oneQuarterButton, self._twoQuarterButton, self._threeQuarterButton, ) if slices is None: [button.setVisible(False) for button in slices_buttons] else: slices = sorted(slices) for button_index, button in zip(slices, slices_buttons): button.setText(str(button_index)) button.setVisible(True) def __quarterButtonPressed(self): self._slider.setValue(int(self.sender().text())) def setSliceBrowsingEnabled(self, enable): """ Slice browsing is enabled if we agree to let the user browsing the entire stack of slice (if the volume is fully load or if on the fast-reading) axis. Else he can only select a pre-defined set of slice. """ self._slider.setEnabled(enable) self._playButton.setEnabled(enable) self._browser.setEnabled(enable) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/_ProcessingOverlay.py0000644000175000017500000000206415143647637027113 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from tomwer.gui import icons try: from silx.gui.widgets.OverlayMixIn import OverlayMixIn as _OverlayMixIn except ImportError: from tomwer.third_part.OverlayMixIn import OverlayMixIn as _OverlayMixIn class ProcessingOverlay(_OverlayMixIn, qt.QLabel): """ Small widget overlay that will display a red dot when some processing are on-going. Use case: when loading a frame on the fast axis we cannot clear the plot and add a message else it will do some blinking. But in some cases loading can take some time (when loading already a full volume in hdf5 for example). And we need to notify the user that something is on-going. """ def __init__(self, parent, img_size, *args, **kwargs): qt.QLabel.__init__(self, parent=parent) _OverlayMixIn.__init__(self, parent=parent, *args, **kwargs) self.setAlignment(qt.Qt.AlignRight | qt.Qt.AlignTop) self._imageQIcon = icons.getQIcon("red_dot") self.setPixmap(self._imageQIcon.pixmap(img_size)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/_ReconstructionParameters.py0000644000175000017500000000175115143647637030504 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from tomoscan.identifier import VolumeIdentifier from tomwer.gui.visualization.reconstructionparameters import ( ReconstructionParameters as _ReconstructionParameters, ) class ReconstructionParameters(_ReconstructionParameters): """ Add the scan identifier to the list of metadata displayed. """ def __init__(self, parent=None): super().__init__(parent) self._volumeIdentifierQLE = qt.QLineEdit("", self) self._volumeIdentifierQLE.setReadOnly(True) self.layout().insertRow(0, "volume id", self._volumeIdentifierQLE) def setVolumeIdentifier(self, volume_identifier: VolumeIdentifier): # TODO: connect the volume to the scan and display scan information as well # see https://gitlab.esrf.fr/tomotools/tomwer/-/issues/1479 self._volumeIdentifierQLE.setText(volume_identifier.to_str()) self._volumeIdentifierQLE.setToolTip(volume_identifier.to_str()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/_SliceLoader.py0000644000175000017500000000153215143647637025622 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from tomwer.core.volume.volumebase import TomwerVolumeBase from weakref import ref class SliceLoader(qt.QThread): """ Thread to load a single slice from a volume. """ def __init__( self, parent, volume: TomwerVolumeBase, slice_index: int, axis: int ) -> None: super().__init__(parent) if not isinstance(volume, TomwerVolumeBase): raise TypeError() self.__volume = ref(volume) self.slice_index = slice_index self.__axis = axis self.__data = None def run(self): if self.__volume() is None: return self.__data = self.__volume().get_slice( index=self.slice_index, axis=self.__axis, ) @property def data(self): return self.__data ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/_TomoPlot2DSlices.py0000644000175000017500000002635415143647637026553 0ustar00paynopaynofrom __future__ import annotations import numpy from silx.gui import qt from silx.gui.utils import concurrent from silx.gui.widgets.WaitingOverlay import WaitingOverlay import logging from tomoscan.volumebase import SliceTuple from tomwer.gui import icons as tomwer_icons from tomwer.gui.visualization.TomoPlot2D import TomoPlot2D as _TomoPlot2D from tomwer.core.volume.volumebase import TomwerVolumeBase from ._HorizontalSliderWithBrowser import HorizontalSliderWithBrowser from .CoordinateSystemOverlay import CoordinateSystemOverlay from ._ProcessingOverlay import ProcessingOverlay from ._SliceLoader import SliceLoader _logger = logging.getLogger(__name__) class TomoPlot2DSlices(qt.QWidget): """ A composition of a TomoPlot2D, a QLabel (with a colored frame) and a set of radio buttons for the user to select the index to be displayed :param title: plot title. :param color: color associated to the plot. :param image: image to associate for the overlay coordinate system. :param axis: Axis associated to the plot (determine how to read from the raw volume). """ displayFullScreen = qt.Signal() def __init__(self, title: str, color: str, image: str, axis: int, *args, **kwargs): super().__init__(*args, **kwargs) if axis not in (0, 1, 2): raise ValueError(f"'axis' should be in (0, 1, 2). Got {type(axis)}") self._axis = axis self.__sliceLoader: SliceLoader | None = None # thread used to load a slice when not part of the 'slices' and when the volume data is not in memory. # avoid any deadlock or GUI lag. self.setLayout(qt.QVBoxLayout()) self.layout().setContentsMargins(2, 2, 2, 2) self.layout().setSpacing(2) self._slices: dict[SliceTuple, numpy.ndarray] = {} # sub set of slice easily accessible self._volume: TomwerVolumeBase | None = None # optional volume from which we can read slices. # The volume is expected to be loaded or reading is expected to be done on the 'fast' axis. self._plot = _TomoPlot2D(parent=self) self._plot.getColorBarWidget().hide() self._plot.getOutputToolBar().hide() self._plot.getColormapAction().setVisible(False) self._plot.getColorBarAction().setVisible(False) self._plot.getMaskAction().setVisible(False) self._plot.getInteractiveModeToolBar().hide() self.layout().addWidget(self._plot) self._coordinateSystemOverlay = CoordinateSystemOverlay( parent=self._plot.getWidgetHandle(), img=image, img_size=qt.QSize(50, 50), ) self._coordinateSystemOverlay.setAlignment(qt.Qt.AlignRight | qt.Qt.AlignBottom) self._coordinateSystemOverlay.setAlignmentOffsets((-10, -10)) self._title = qt.QLabel(title, parent=self) self._title.setAlignment(qt.Qt.AlignCenter) self.layout().addWidget(self._title) self._sliceIndexSelection = HorizontalSliderWithBrowser() self.layout().addWidget(self._sliceIndexSelection) # set the color to the title frame (simplest) self._title.setStyleSheet( f"border: 2px solid {color}", ) # overlay to signal some loading is on-going. self._messageOverlayWidget = WaitingOverlay(self._plot) self._messageOverlayWidget.setStyleSheet( "QPushButton { background-color: rgba(150, 150, 150, 40); border: 0px; border-radius: 10px; }" ) self._messageOverlayWidget.setIconSize(qt.QSize(30, 30)) # Overlay to notify during fast axis reading self._fastReadingIndicator = ProcessingOverlay( self._plot, img_size=qt.QSize(5, 6) ) self._fastReadingIndicator.setAlignmentOffsets((-10, 10)) self._fastReadingIndicator.setVisible(False) # create the new toolbar # full screen action self._extraToolbar = qt.QToolBar(self) self._plot.addToolBar(self._extraToolbar) fullScreenIcon = tomwer_icons.getQIcon("full_screen") self._fullScreenAction = qt.QAction(fullScreenIcon, "pop up full screen") self._extraToolbar.addAction(self._fullScreenAction) self._toolbars = ( self._plot.toolBar(), self._plot.getProfileToolbar(), self._extraToolbar, ) # set up self.setCoordinateSystemLabelVisible(False) self.setToolBarsVisible(False) self.setLoading(False) # connect signal / slot self._fullScreenAction.triggered.connect(self.displayFullScreen) self._sliceIndexSelection.valueChanged.connect(self._updatePlot) def _indicateFastReading(self, value: bool): """ At the moment the fast-reading axis can become load in the case of hdf5. At the moment we simply notify it to the user. """ self._fastReadingIndicator.setVisible(value) def setLoadingMessage(self, message: str): self._messageOverlayWidget.setText(message) def setLoading(self, loading: bool) -> None: self._messageOverlayWidget.setVisible(loading) def isLoading(self) -> bool: return self._messageOverlayWidget.isVisible() def setCoordinateSystemVisible(self, visible): self._coordinateSystemOverlay.setVisible(visible) def setCoordinateSystemLabelVisible(self, visible: bool): self._title.setVisible(visible) def setSliceSelectionVisible(self, visible: bool): self._sliceIndexSelection.setVisible(visible) def setToolBarsVisible(self, visible: bool): for toolbar in self._toolbars: toolbar.setVisible(visible) def getTitle(self) -> str: return self._title def clearActiveImage(self) -> None: """ Remove the active image from the plot. .. note:: Other items (e.g., markers) may still be present in the widget. """ img = self._plot.getImage() if img is not None: self._plot.remove(img) def setVolume(self, volume: TomwerVolumeBase | None): """ Set the volume. So user can browse through it in addition to the slices. """ if not isinstance(volume, (TomwerVolumeBase, type(None))): raise TypeError( f"'volume' is expected to be instance of {TomwerVolumeBase} or {None}. Got {type(volume)}." ) self._volume = volume if volume is not None: try: # avoid updating the range (and the slice index) when possible range = 0, self._volume.get_volume_shape()[self._axis] - 1 if range != self._sliceIndexSelection.getRange(): self._sliceIndexSelection.setRange(*range) except OSError as e: _logger.warning(f"Unable to retrieve volume shape. Error is {e}") self._sliceIndexSelection.setSliceBrowsingEnabled(self._volume is not None) @staticmethod def _determinePreferredSliceIndex(slice_indices: tuple[int]) -> int: """Return the index to display if None provided during construction""" if len(slice_indices) == 0: return -1 return slice_indices[len(slice_indices) // 2] def setSlices( self, slices: dict[SliceTuple, numpy.ndarray], update_index: bool = True ): self._slices = { slice_tuple.index: value for slice_tuple, value in slices.items() } # update to the new one slice_indices = tuple(self._slices.keys()) self._sliceIndexSelection.setSliceIndices(slices=slice_indices) if update_index: self._sliceIndexSelection.setValue( self._determinePreferredSliceIndex(slice_indices=slice_indices) ) self._updatePlot(slice_index=self._sliceIndexSelection.value()) def setSliceRange(self, first, last): self._sliceIndexSelection.setRange(first, last) def getSliceRange(self): return self._sliceIndexSelection.getRange() def _updatePlot(self, slice_index: int | None): if slice_index is None: self._plot.clear() return image = self._slices.get(slice_index, None) loading_delegated = False if image is None and self._volume is not None: if self._volume.data is None: loading_delegated = self.__delegateSliceLoading(slice_index=slice_index) else: image = self._volume.get_slice( index=slice_index, axis=self._axis, ) if loading_delegated: return if image is None: _logger.error(f"Fail to load slice index {slice_index}") return self._plot.addImage(image, resetzoom=False) def __delegateSliceLoading(self, slice_index: int) -> bool: """Delegate slice loading to a dedicated thread""" if self.__sliceLoader is not None: self.__sliceLoader.finished.disconnect(self.__delegatedSliceLoadingFinished) # TODO: fix me: avoid some segfault having several thread reading and being destroyed without owner. # wait for the previous loading to be done. # This avoid having several thread and ensure a 'clean' loading of the data. # Remember that we are on the 'fast' reading axis. # self.__sliceLoader.wait() self._indicateFastReading(True) self.__sliceLoader = SliceLoader( parent=self, volume=self._volume, slice_index=slice_index, axis=self._axis, ) self.__sliceLoader.finished.connect(self.__delegatedSliceLoadingFinished) self.__sliceLoader.start() return True def __delegatedSliceLoadingFinished(self): if self.sender() != self.__sliceLoader: # slice to be loaded has been changed return self._indicateFastReading(False) self.__sliceLoader.finished.disconnect(self.__delegatedSliceLoadingFinished) data = self.__sliceLoader.data slice_index = self.__sliceLoader.slice_index if data is not None: if slice_index == self.getCurrentSliceIndex(): concurrent.submitToQtMainThread( self._plot.addImage, data, resetzoom=False, ) else: # can happen if not being responsive enough (volume being load, user browsing the fast axis and the loading of slices along the fast axis not being so fast...) pass else: _logger.warning(f"Failed to load slice {self.__sliceLoader.slice_index}") self.__sliceLoader = None def _stopSliceLoader(self): if self.__sliceLoader is not None: self.__sliceLoader.finished.disconnect(self.__delegatedSliceLoadingFinished) self.__sliceLoader = None self._indicateFastReading(False) def clear(self): self._stopSliceLoader() self._plot.clear() # expose API def getPlot(self): return self._plot def setVoxelSize(self, size_m: float | None): self._plot.setVoxelSize(size=size_m) def setCurrentIndex(self, index: int): self._sliceIndexSelection.setValue(index) def getCurrentSliceIndex(self) -> int: return self._sliceIndexSelection.value() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/__init__.py0000644000175000017500000000024315143647637025032 0ustar00paynopayno""" This module is dedicated to the GUI to display reconstruction summary of a volume. This is a set of slice along each direction and the associated metadata """ ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9491017 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/actions/0000755000175000017500000000000015153325403024343 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/actions/_ColorBarAction.py0000644000175000017500000000250015143647637027731 0ustar00paynopaynofrom __future__ import annotations import weakref from silx.gui import qt from silx.gui import icons as silx_icons class ColorBarAction(qt.QAction): """ QAction opening the ColorBarWidget of the specified plot. It was not possible to inherit the one from silx because it inherit from a PlotAction which is not the case of this one (n plots...) """ def __init__(self, colorbar, parent=None): icon = silx_icons.getQIcon("colorbar") text = "Colorbar" super().__init__(parent=parent, icon=icon, text=text) self.setToolTip("Show/Hide the colorbar") self.setCheckable(True) self.triggered[bool].connect(self._actionTriggered) colorbar.sigVisibleChanged.connect(self._widgetVisibleChanged) self._colorBar = weakref.ref(colorbar) def _widgetVisibleChanged(self, isVisible): """Callback when the colorbar `visible` property change.""" if self.isChecked() == isVisible: return self.setChecked(isVisible) def _actionTriggered(self, checked=False): """Create a cmap dialog and update active image and default colormap.""" colorBar = self._colorBar() if colorBar is None: return if not colorBar.isHidden() == checked: return colorBar.setVisible(checked) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/actions/_ShowAxesAction.py0000644000175000017500000000204315143647637027771 0ustar00paynopaynofrom __future__ import annotations import weakref from silx.gui import qt from silx.gui import icons as silx_icons from silx.gui.plot import PlotWidget class ShowAxesAction(qt.QAction): """ QAction opening the ColorBarWidget of the specified plot. It was not possible to inherit the one from silx because it inherit from a PlotAction which is not the case of this one (n plots...) """ def __init__(self, plots: tuple[PlotWidget], parent=None): icon = silx_icons.getQIcon("axis") text = "show axis" super().__init__(parent=parent, icon=icon, text=text) self.setToolTip("Toggle axes") self.setCheckable(True) self._plots = [weakref.ref(plot) for plot in plots] self.triggered[bool].connect(self._actionTriggered) def _actionTriggered(self, checked=False): """Create a cmap dialog and update active image and default colormap.""" for ref_plot in self._plots: plot = ref_plot() if plot: plot.setAxesDisplayed(checked) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/actions/_ShowCoordinateSystemAction.py0000644000175000017500000000205715143647637032372 0ustar00paynopaynofrom __future__ import annotations import weakref from silx.gui import qt from tomwer.gui import icons class ShowCoordinateSystemAction(qt.QAction): """ QAction to show / hide the coordinate system vignette of the plots """ STATE = None """Lazy loaded states used to feed the coordinate system""" def __init__(self, plots: tuple, parent=None): icon = icons.getQIcon("show_3D_coordinate_system") text = "Toggle 3D coordinate system" super().__init__(parent=parent, icon=icon, text=text) self.setToolTip("Toggle 3D coordinate system of slice plots") self.setCheckable(True) self.setChecked(True) self._plots = [weakref.ref(plot) for plot in plots] self.triggered[bool].connect(self._updateCoordinateSystemVisibility) def _updateCoordinateSystemVisibility(self, visible): """Handle Plot set keep aspect ratio signal""" for ref_plot in self._plots: plot = ref_plot() if plot: plot.setCoordinateSystemVisible(visible) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/actions/_ShowCoordinateSystemLabelAction.py0000644000175000017500000000222315143647637033325 0ustar00paynopaynofrom __future__ import annotations import weakref from silx.gui import qt from tomwer.gui import icons from silx.gui.plot import PlotWidget class ShowCoordinateSystemLabelAction(qt.QAction): """ QAction opening the ColorBarWidget of the specified plot. It was not possible to inherit the one from silx because it inherit from a PlotAction which is not the case of this one (n plots...) """ def __init__(self, plots: tuple[PlotWidget], parent=None): icon = icons.getQIcon("show_coordinate_system_label") text = "show 3D coordinate system labels" super().__init__(parent=parent, icon=icon, text=text) self.setToolTip("Toggle coordinate system labels") self.setCheckable(True) self.setChecked(True) self._plots = [weakref.ref(plot) for plot in plots] self.triggered[bool].connect(self._actionTriggered) def _actionTriggered(self, checked=False): """Create a cmap dialog and update active image and default colormap.""" for ref_plot in self._plots: plot = ref_plot() if plot: plot.setCoordinateSystemLabelVisible(checked) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/actions/_ShowCrosshairsAction.py0000644000175000017500000000113015143647637031205 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from tomwer.gui import icons class ShowCrosshairsAction(qt.QAction): """ QAction to show / hide the plots crosshairs """ sigVisibilityChanged = qt.Signal() def __init__(self, parent=None): icon = icons.getQIcon("crosshairs") text = "Toggle Crosshairs" super().__init__(parent=parent, icon=icon, text=text) self.setToolTip("Toggle Slice Plots Crosshairs") self.setCheckable(True) self.setChecked(True) self.triggered[bool].connect(self.sigVisibilityChanged) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/actions/_ShowPlotToolBarAction.py0000644000175000017500000000213415143647637031273 0ustar00paynopaynofrom __future__ import annotations import weakref from silx.gui import qt from tomwer.gui import icons from silx.gui.plot import PlotWidget class ShowPlotToolBarAction(qt.QAction): """ QAction opening the ColorBarWidget of the specified plot. It was not possible to inherit the one from silx because it inherit from a PlotAction which is not the case of this one (n plots...) """ def __init__(self, plots: tuple[PlotWidget], parent=None): icon = icons.getQIcon("show_plot_toolbars") text = "show plot toolbars" super().__init__(parent=parent, icon=icon, text=text) self.setToolTip("Show/Hide plot toolbars") self.setCheckable(True) self.setChecked(True) self._plots = [weakref.ref(plot) for plot in plots] self.triggered[bool].connect(self._actionTriggered) def _actionTriggered(self, checked=False): """Create a cmap dialog and update active image and default colormap.""" for ref_plot in self._plots: plot = ref_plot() if plot: plot.setToolBarsVisible(checked) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/actions/__init__.py0000644000175000017500000000000015143647637026461 0ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9491017 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/tests/0000755000175000017500000000000015153325403024045 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/tests/__init__.py0000644000175000017500000000000015143647637026163 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/tests/test_VolumeViewer.py0000644000175000017500000000463315143647637030134 0ustar00paynopaynofrom __future__ import annotations import numpy from tomoscan.volumebase import SliceTuple from tomwer.tests.conftest import qtapp # noqa F401 from tomwer.gui.visualization.volume_viewer.VolumeViewerWidget import ( VolumeViewerWidget, ) def test_volumeViewerWidget(qtapp): # noqa F811 widget = VolumeViewerWidget() widget.setSlices( { SliceTuple(axis=0, index=1): numpy.ones((10, 20)), SliceTuple(axis=0, index=12): numpy.ones((10, 20)), SliceTuple(axis=0, index=25): numpy.ones((10, 20)), SliceTuple(axis=1, index=0): numpy.arange(0, 100).reshape(10, 10), SliceTuple(axis=1, index=10): numpy.arange(1000, 1100).reshape(10, 10), SliceTuple(axis=1, index=20): numpy.arange(1000, 1100).reshape(10, 10), SliceTuple(axis=2, index=20): numpy.random.random(100).reshape(10, 10), SliceTuple(axis=2, index=21): numpy.random.random(100).reshape(10, 10), SliceTuple(axis=2, index=22): numpy.random.random(100).reshape(10, 10), } ) widget.setVolumeMetadata( { "nabu_config": { "reconstruction": { "method": "FBP", }, "phase": { "method": "paganin", "delta_beta": 110.0, }, }, "processing_options": { "reconstruction": { "voxel_size_cm": (0.2, 0.2, 0.2), "rotation_axis_position": 104, "enable_halftomo": True, "fbp_filter_type": "Hilbert", "sample_detector_dist": 0.4, }, "take_log": { "log_min_clip": 1.0, "log_max_clip": 10.0, }, }, }, volume_shape=(10, 10, 10), ) # test marker: should be set to the 'middle' slice values (12, 10, 21) markers = widget.getCrossHairs().getMarkers() assert markers["XYPlot"]["YMarker"].getPosition() == (21.0, None) assert markers["XYPlot"]["XMarker"].getPosition() == (None, 10.0) assert markers["XZPlot"]["XMarker"].getPosition() == (10.0, None) assert markers["XZPlot"]["ZMarker"].getPosition() == (None, 12.0) assert markers["YZPlot"]["YMarker"].getPosition() == (21.0, None) assert markers["YZPlot"]["ZMarker"].getPosition() == (None, 12.0) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/gui/visualization/volume_viewer/toolbar.py0000644000175000017500000001027015143647637024736 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from silx.gui.plot import actions from tomwer.gui import icons as tomwer_icons from .actions._ColorBarAction import ColorBarAction from .actions._ShowAxesAction import ShowAxesAction from .actions._ShowCoordinateSystemAction import ShowCoordinateSystemAction from .actions._ShowCoordinateSystemLabelAction import ShowCoordinateSystemLabelAction from .actions._ShowCrosshairsAction import ShowCrosshairsAction from .actions._ShowPlotToolBarAction import ShowPlotToolBarAction class ToolBar(qt.QToolBar): """Specialized toolbar for the VolumeReconstructionSummaryWindow""" def __init__(self, master_plot, colorbar, plots, parent=None): super().__init__(parent=parent) # colormap action self._colormapAction = actions.control.ColormapAction( parent=self, plot=master_plot ) master_plot.sigActiveImageChanged.disconnect( self._colormapAction._updateColormap ) master_plot.sigActiveScatterChanged.disconnect( self._colormapAction._updateColormap ) self.addAction(self._colormapAction) # colorbar action self.colorbarAction = ColorBarAction(colorbar=colorbar, parent=self) self.colorbarAction.setVisible(True) self.colorbarAction.setChecked(True) self.addAction(self.colorbarAction) # show axes self.showAxesAction = ShowAxesAction(parent=self, plots=plots) self.addAction(self.showAxesAction) # Toggle coordinate system self.showCoordinateSystem = ShowCoordinateSystemAction( plots=[plot.parent() for plot in plots], parent=self ) self.addAction(self.showCoordinateSystem) # Toggle labels self.showCoordinatesSystemLabel = ShowCoordinateSystemLabelAction( plots=[plot.parent() for plot in plots], parent=self ) self.addAction(self.showCoordinatesSystemLabel) # Toggle toolbar action self.showToolbar = ShowPlotToolBarAction( plots=[plot.parent() for plot in plots], parent=self ) self.addAction(self.showToolbar) # separator self.addSeparator() self._showCrosshairsAction = ShowCrosshairsAction() self.addAction(self._showCrosshairsAction) # separator self.addSeparator() # load volume self._loadVolumeWidget = qt.QCheckBox("load volume") self._loadVolumeWidget.setToolTip( "Loading the volume in memory will allow you to browse the slices along the three dimensions. But it will consume a lot of RAM." ) self._loadVolumeAction = self.addWidget(self._loadVolumeWidget) # separator self.addSeparator() # display a single axis axis0_icon = tomwer_icons.getQIcon("extend_3D_coordinate_system_XY") self._extendXYPlotAction = qt.QAction(axis0_icon, "extend XY plot") self.addAction(self._extendXYPlotAction) axis1_icon = tomwer_icons.getQIcon("extend_3D_coordinate_system_XZ") self._extendXZPlotAction = qt.QAction(axis1_icon, "extend XZ plot") self.addAction(self._extendXZPlotAction) axis2_icon = tomwer_icons.getQIcon("extend_3D_coordinate_system_YZ") self._extendYZPlotAction = qt.QAction(axis2_icon, "extend YZ plot") self.addAction(self._extendYZPlotAction) # equally space plots reset_display_icon = tomwer_icons.getQIcon("reset_3D_coordinate_system") self._resetDisplayAction = qt.QAction( reset_display_icon, "Reset plots position." ) self.addAction(self._resetDisplayAction) # Action getters def getLoadVolumeAction(self): return self._loadVolumeAction def getExtendXYPlotAction(self) -> qt.QAction: return self._extendXYPlotAction def getExtendXZPlotAction(self) -> qt.QAction: return self._extendXZPlotAction def getExtendYZPlotAction(self) -> qt.QAction: return self._extendYZPlotAction def getResetDisplayAction(self) -> qt.QAction: return self._resetDisplayAction def getCrosshairsAction(self) -> ShowCrosshairsAction: return self._showCrosshairsAction ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1769096086.0 tomwer-1.6.17/src/tomwer/gui/visualization/volumeoverview.py0000644000175000017500000000470015134441626023471 0ustar00paynopaynofrom __future__ import annotations import logging from silx.gui import qt from tomoscan.identifier import VolumeIdentifier from tomwer.core.volume.volumebase import TomwerVolumeBase _logger = logging.getLogger(__name__) class VolumeOverviewWidget(qt.QWidget): def __init__(self, parent=None): super().__init__(parent) self._volumeIdentifier = None self.setLayout(qt.QVBoxLayout()) self._tree = qt.QTreeWidget(self) self._tree.setColumnCount(2) self._tree.setHeaderLabels(("metadata", "value")) self.layout().addWidget(self._tree) # 1: define translations self._x_position = qt.QTreeWidgetItem(self._tree) self._x_position.setText(0, "x position") self._y_position = qt.QTreeWidgetItem(self._tree) self._y_position.setText(0, "y position") self._z_position = qt.QTreeWidgetItem(self._tree) self._z_position.setText(0, "z position") # 2. define pixel size self._x_pixel_size = qt.QTreeWidgetItem(self._tree) self._x_pixel_size.setText(0, "x pixel size") self._y_pixel_size = qt.QTreeWidgetItem(self._tree) self._y_pixel_size.setText(0, "y pixel size") def setVolume(self, volume: TomwerVolumeBase | None): if volume is None: self._x_position.setText(1, "") self._y_position.setText(1, "") self._z_position.setText(1, "") self._x_pixel_size.setText(1, "") self._y_pixel_size.setText(1, "") elif not isinstance(volume, TomwerVolumeBase): raise TypeError( f"volume is expected to be a {TomwerVolumeBase} or a {VolumeIdentifier}. Not ({type(volume)}) " ) else: try: x_pos, y_pos, z_pos = volume.position() except Exception: self._x_position.setText(1, "?") self._y_position.setText(1, "?") self._z_position.setText(1, "?") else: self._x_position.setText(1, x_pos) self._y_position.setText(1, y_pos) self._z_position.setText(1, z_pos) try: x_size, y_size = volume.pixel_size except Exception: self._x_pixel_size.setText(1, "?") self._y_pixel_size.setText(1, "?") else: self._x_pixel_size.setText(1, x_size) self._y_pixel_size.setText(1, y_size) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9491017 tomwer-1.6.17/src/tomwer/io/0000755000175000017500000000000015153325403014735 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1741890830.0 tomwer-1.6.17/src/tomwer/io/__init__.py0000644000175000017500000000012114764622416017053 0ustar00paynopayno"""This package provides functionalities for inputs and outputs (read, write)""" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9531019 tomwer-1.6.17/src/tomwer/io/utils/0000755000175000017500000000000015153325403016075 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/io/utils/__init__.py0000644000175000017500000000042014757047403020214 0ustar00paynopaynofrom .utils import format_stderr_stdout # noqa F401 from .utils import get_default_directory # noqa F401 from .utils import get_linked_files_with_entry # noqa F401 from .utils import get_linked_files_with_vds # noqa F401 from .utils import get_slice_data # noqa F401 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/io/utils/h5pyutils.py0000644000175000017500000000315215143647637020435 0ustar00paynopayno# coding: utf-8 """ contains utils for inputs and outputs """ from __future__ import annotations import contextlib import h5py from silx.io.url import DataUrl from silx.io.utils import open as open_hdf5 class _BaseReader(contextlib.AbstractContextManager): def __init__(self, url: DataUrl): if not isinstance(url, DataUrl): raise TypeError("url should be an instance of DataUrl") if url.scheme() not in ("silx", "h5py"): raise ValueError("Valid scheme are silx and h5py") if url.data_slice() is not None: raise ValueError( "Data slices are not managed. Data path should " "point to a bliss node (h5py.Group)" ) self._url = url self._file_handler = None def __exit__(self, *exc): return self._file_handler.close() class EntryReader(_BaseReader): """Context manager used to read a bliss node""" def __enter__(self): self._file_handler = open_hdf5(filename=self._url.file_path()) entry = self._file_handler[self._url.data_path()] if not isinstance(entry, h5py.Group): raise ValueError("Data path should point to a bliss node (h5py.Group)") return entry class DatasetReader(_BaseReader): """Context manager used to read a bliss node""" def __enter__(self): self._file_handler = open_hdf5(filename=self._url.file_path()) entry = self._file_handler[self._url.data_path()] if not isinstance(entry, h5py.Dataset): raise ValueError("Data path should point to a dtaset (h5py.Dataset)") return entry ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/io/utils/raw_and_processed_data.py0000644000175000017500000000621014757047403023133 0ustar00paynopayno"""some utils to move a path to process_data or to raw_data""" import os from nxtomomill.converter.hdf5.utils import ( RAW_DATA_DIR_NAME, PROCESSED_DATA_DIR_NAME, ) def to_raw_data_path(file_path: str): """convert a path to 'RAW_DATA' when possible""" split_path = file_path.split(os.sep) # reverse it to find the lower level value of 'PROCESSED_DATA_DIR_NAME' if by any 'chance' has several in the path # in this case this is most likely what we want split_path = split_path[::-1] # check if already contain in a "RAW_DATA_DIR_NAME" directory try: index_raw_data = split_path.index(RAW_DATA_DIR_NAME) except ValueError: index_raw_data = None try: index_processed_data = split_path.index(PROCESSED_DATA_DIR_NAME) except ValueError: # if the value is not in the list pass else: if index_raw_data is None or index_raw_data > index_processed_data: # make sure we are not already in a 'PROCESSED_DATA' directory. Not sure it will never happen but safer split_path[index_processed_data] = RAW_DATA_DIR_NAME # reorder path to original split_path = split_path[::-1] return os.sep.join(split_path) def to_processed_data_path(file_path: str): """convert a path to 'PROCESSED_DATA' when possible""" split_path = file_path.split(os.sep) # reverse it to find the lower level value of '_RAW_DATA_DIR_NAME' if by any 'chance' has several in the path # in this case this is most likely what we want split_path = split_path[::-1] # check if already contain in a "PROCESSED_DATA" directory try: index_processed_data = split_path.index(PROCESSED_DATA_DIR_NAME) except ValueError: index_processed_data = None try: index_raw_data = split_path.index(RAW_DATA_DIR_NAME) except ValueError: # if the value is not in the list pass else: if index_processed_data is None or index_raw_data < index_processed_data: # make sure we are not already in a 'PROCESSED_DATA' directory. Not sure it will never happen but safer split_path[index_raw_data] = PROCESSED_DATA_DIR_NAME # reorder path to original split_path = split_path[::-1] return os.sep.join(split_path) def file_is_on_processed_data(file_path: str): """Util that raises an error if path is not in PROCESSED_DATA folder""" split_path = file_path.split(os.sep) # reverse it to find the lower level value of 'PROCESSED_DATA_DIR_NAME' if by any 'chance' has several in the path # in this case this is most likely what we want split_path = split_path[::-1] # check if already contain in a "RAW_DATA_DIR_NAME" directory try: index_raw_data = split_path.index(RAW_DATA_DIR_NAME) except ValueError: index_raw_data = None try: index_processed_data = split_path.index(PROCESSED_DATA_DIR_NAME) except ValueError: # if the value is not in the list index_processed_data = None else: if index_raw_data is not None and index_raw_data < index_processed_data: return False return index_processed_data is not None ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9531019 tomwer-1.6.17/src/tomwer/io/utils/test/0000755000175000017500000000000015153325403017054 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/io/utils/test/test_raw_and_processed_data.py0000644000175000017500000000105014757047403025146 0ustar00paynopaynofrom tomwer.io.utils.raw_and_processed_data import file_is_on_processed_data def test_file_is_on_processed_data(): """test file_is_on_processed_data function""" assert file_is_on_processed_data("/path/to/file") == False assert file_is_on_processed_data("/path/to/PROCESSED_DATA/file") == True assert file_is_on_processed_data("/path/to/RAW_DATA/file") == False assert file_is_on_processed_data("/path/to/RAW_DATA/PROCESSED_DATA/file") == True assert file_is_on_processed_data("/path/to/PROCESSED_DATA/RAW_DATA/file") == False ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/io/utils/test/test_utils.py0000644000175000017500000000360214757047403021640 0ustar00paynopayno# coding: utf-8 """ contains utils for inputs and outputs """ from __future__ import annotations import os import h5py import numpy from silx.io.url import DataUrl from tomoscan.io import HDF5File from tomwer.core.utils import scanutils from tomwer.io.utils import ( get_default_directory, get_linked_files_with_entry, get_slice_data, ) def test_get_linked_files_with_entry(tmp_path): """test get_linked_files_with_entry function""" dir_test = tmp_path / "sub" dir_test.mkdir() layout = h5py.VirtualLayout(shape=(4, 10, 10), dtype="i4") for i_file in range(4): file_name = os.path.join(dir_test, f"file_{i_file}.hdf5") with HDF5File(file_name, "w") as h5s: h5s.create_dataset("data", (10, 10), "i4", numpy.ones((10, 10))) vsource = h5py.VirtualSource(file_name, "data", shape=(10, 10)) layout[i_file] = vsource test_with_vds = os.path.join(dir_test, "file_with_vds") with HDF5File(test_with_vds, "w") as h5s: h5s.create_virtual_dataset("vdata", layout, fillvalue=-1) assert len(get_linked_files_with_entry(test_with_vds, "vdata")) == 4 def test_get_default_directory(): get_default_directory() def test_get_slice_data_vol(tmp_path): """test load of a .vol file""" dir_test = tmp_path / "test_vol" dir_test.mkdir() vol_file_path = os.path.join(dir_test, "volume.vol") vol_info_file_path = os.path.join(dir_test, "volume.vol.info") shape = (4, 50, 20) data = numpy.ones(shape) data.astype(numpy.float32).tofile(vol_file_path) scanutils.MockEDF._createVolInfoFile( filePath=vol_info_file_path, shape=shape, ) vol = get_slice_data(DataUrl(file_path=vol_file_path)) assert vol is not None assert vol.shape == shape vol = get_slice_data(DataUrl(file_path=vol_info_file_path)) assert vol is not None assert vol.shape == shape ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/io/utils/tomoobj.py0000644000175000017500000000541315143647637020142 0ustar00paynopaynofrom tomoscan.esrf.identifier.edfidentifier import EDFVolumeIdentifier from tomoscan.esrf.identifier.hdf5Identifier import ( HDF5VolumeIdentifier, ) from tomoscan.esrf.identifier.jp2kidentifier import JP2KVolumeIdentifier from tomoscan.esrf.identifier.rawidentifier import RawVolumeIdentifier from tomoscan.esrf.identifier.tiffidentifier import ( MultiTiffVolumeIdentifier, TIFFVolumeIdentifier, ) from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.volume.volumefactory import VolumeFactory from tomoscan.esrf.volume.utils import guess_volumes from tomwer.core.volume.edfvolume import EDFVolume from tomwer.core.volume.hdf5volume import HDF5Volume from tomwer.core.volume.jp2kvolume import JP2KVolume from tomwer.core.volume.rawvolume import RawVolume from tomwer.core.volume.tiffvolume import MultiTIFFVolume, TIFFVolume DEFAULT_SCHEME_TO_VOL = { EDFVolumeIdentifier.scheme: EDFVolume, HDF5VolumeIdentifier.scheme: HDF5Volume, TIFFVolumeIdentifier.scheme: TIFFVolume, MultiTiffVolumeIdentifier.scheme: MultiTIFFVolume, JP2KVolumeIdentifier.scheme: JP2KVolume, RawVolumeIdentifier.scheme: RawVolume, } def get_tomo_objs_instances(tomo_objs: tuple) -> tuple: """ return instances of TomoObj from a tuple of string (either from identifiers directly or from file path parsing) """ instances = [] has_scans = False has_vols = False for tomo_obj in tomo_objs: def get_scans(): try: return (ScanFactory.create_tomo_object_from_identifier(tomo_obj),) except Exception: try: return ScanFactory.create_scan_objects(tomo_obj) except Exception: return tuple() def get_volumes(): try: return (VolumeFactory.create_tomo_object_from_identifier(tomo_obj),) except Exception: try: return guess_volumes( tomo_obj, scheme_to_vol=DEFAULT_SCHEME_TO_VOL, filter_histograms=True, ) except Exception: return tuple() scans_found = get_scans() if len(scans_found) == 0: # we start by scan because they have a 'definition' as NXtomo available. # otherwise we might get some entries defined as scan AND volume... # for stitching we expect users to ask of for one or the other. volumes = get_volumes() or () if len(volumes) > 0: has_vols = True instances.extend(volumes) else: has_scans = len(scans_found) > 0 instances.extend(scans_found) return tuple(instances), (has_scans, has_vols) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/io/utils/utils.py0000644000175000017500000002211414757047403017621 0ustar00paynopayno""" contains utils for inputs and outputs """ from __future__ import annotations import logging import os import h5py import numpy.lib.npyio from PIL import Image from silx.io.utils import open as open_hdf5 from tomoscan.esrf import has_glymur from tomoscan.esrf.scan.utils import get_data as tomoscan_get_data from tomwer.core.utils import ftseriesutils try: import tifffile # noqa #F401 needed for later possible lazy loading except ImportError: has_tifffile = False else: has_tifffile = True _logger = logging.getLogger(__name__) def get_slice_data(url): """Return data from an url""" if os.path.exists(url.file_path()) and os.path.isfile(url.file_path()): if url.file_path().lower().endswith( ".vol.info" ) or url.file_path().lower().endswith(".vol"): data = _loadVol(url) elif url.scheme() == "tomwer": data = numpy.array(Image.open(url.file_path())) if url.data_slice() is not None: data = data[url.data_slice()] elif url.scheme() == ("tifffile"): if not has_tifffile: _logger.warning("tifffile must be installed to read tiff") data = None else: data = tifffile.imread(url.file_path()) if url.data_slice() is not None: data = data[url.data_slice()] elif url.scheme() in ("jp2", "jp2k", "glymur"): if not has_glymur: _logger.warning("glymur must be installed to read jpeg2000") data = None else: import glymur data = glymur.Jp2k(url.file_path())[:] else: try: data = tomoscan_get_data(url) except Exception as e: _logger.warning( f"file {url} not longer exists or is empty. Error is {e}" ) data = None else: _logger.warning("file %s not longer exists or is empty" % url) data = None return data def _loadVol(url): """Load data from a .vol file and an url""" if url.file_path().lower().endswith(".vol.info"): infoFile = url.file_path() rawFile = url.file_path().replace(".vol.info", ".vol") else: assert url.file_path().lower().endswith(".vol") rawFile = url.file_path() infoFile = url.file_path().replace(".vol", ".vol.info") if not os.path.exists(rawFile): data = None mess = f"Can't find raw data file {rawFile} associated with {infoFile}" _logger.warning(mess) elif not os.path.exists(infoFile): mess = f"Can't find info file {infoFile} associated with {rawFile}" _logger.warning(mess) data = None else: shape = ftseriesutils.get_vol_file_shape(infoFile) if None in shape: _logger.warning(f"Fail to retrieve data shape for {infoFile}.") data = None else: try: numpy.zeros(shape) except MemoryError: data = None _logger.warning(f"Raw file {rawFile} is to large for being readed") else: data = numpy.fromfile(rawFile, dtype=numpy.float32, count=-1, sep="") try: data = data.reshape(shape) except ValueError: _logger.warning( f"unable to fix shape for raw file {rawFile}. Look for information in {infoFile}" ) try: sqr = int(numpy.sqrt(len(data))) shape = (1, sqr, sqr) data = data.reshape(shape) except ValueError: _logger.info(f"deduction of shape size for {rawFile} failed") data = None else: _logger.warning( f"try deducing shape size for {rawFile} might be an incorrect interpretation" ) if url.data_slice() is None: return data else: return data[url.data_slice()] def get_default_directory() -> str: """ :return: default directory where to open a QFolder dialdg for example """ if "TOMWER_DEFAULT_INPUT_DIR" in os.environ and os.path.exists( os.environ["TOMWER_DEFAULT_INPUT_DIR"] ): return os.environ["TOMWER_DEFAULT_INPUT_DIR"] else: try: return os.getcwd() except FileNotFoundError: return os.sep def format_stderr_stdout(stdout, stderr, config=None): s_out = stdout.decode("utf-8") if stdout is not None else "" s_err = stderr.decode("utf-8") if stderr is not None else "" if config is None: config = "" else: assert isinstance(config, dict) return ( f"############# nabu ############## \nconfig: {config}\n" f"------------- stderr -------------\n{s_err}\n" f"------------- stdout -------------\n{s_out}\n" ) def get_linked_files_with_entry(hdf5_file: str, entry: str) -> set: """ parse all datasets under the entry and look for connections with external files (vds or ExternalLink) """ items_to_treat = set() # abs_file_path, file_path, data_path final_datasets = set() # file_path, dataset_path treated_items = set() # abs_file_path, data_path abs_hdf5_file = os.path.abspath(hdf5_file) items_to_treat.add((abs_hdf5_file, hdf5_file, entry)) while len(items_to_treat) > 0: to_treat = list(items_to_treat) items_to_treat.clear() for abs_file_path, file_path, data_path in to_treat: item = abs_file_path, data_path if item in treated_items: continue dirname = os.path.dirname(abs_file_path) with open_hdf5(abs_file_path) as h5f: node = h5f.get(data_path, getlink=True) if isinstance(node, h5py.ExternalLink): ext_file_path = node.filename if not os.path.isabs(ext_file_path): ext_file_path = os.path.join(dirname, ext_file_path) items_to_treat.add( (os.path.abspath(ext_file_path), node.filename, node.path) ) node = h5f.get(data_path, getlink=False) if isinstance(node, h5py.Dataset) and node.is_virtual: final_datasets.update( get_linked_files_with_vds(abs_file_path, data_path) ) elif abs_file_path != abs_hdf5_file: final_datasets.add((file_path, data_path)) treated_items.add(item) if isinstance(node, h5py.Group): for key in node.keys(): data_sub_path = "/".join((data_path, key)) if ( abs_file_path, data_sub_path, ) not in treated_items: items_to_treat.add( (abs_file_path, file_path, data_sub_path) ) return final_datasets def get_linked_files_with_vds(hdf5_file: str, dataset_path: str) -> set: """ parse all virtual sources of a virtual dataset and return a set of files / dataset connected to it """ items_to_treat = set() # abs_file_path, file_path, dataset_path final_datasets = set() # file_path, dataset_path treated_items = set() # abs_file_path, dataset_path abs_hdf5_file = os.path.abspath(hdf5_file) items_to_treat.add((abs_hdf5_file, hdf5_file, dataset_path)) while len(items_to_treat) > 0: to_treat = list(items_to_treat) items_to_treat.clear() for abs_file_path, file_path, dataset_path in to_treat: item = abs_file_path, dataset_path if item in treated_items: continue dirname = os.path.dirname(abs_file_path) with open_hdf5(abs_file_path) as h5f: dataset = h5f[dataset_path] if dataset.is_virtual: for vs_info in dataset.virtual_sources(): vs_file_path = vs_info.file_name if not os.path.isabs(vs_file_path): vs_file_path = os.path.join(dirname, vs_file_path) items_to_treat.add( ( os.path.abspath(vs_file_path), vs_info.file_name, vs_info.dset_name, ) ) else: final_datasets.add((file_path, dataset_path)) treated_items.add(item) return final_datasets def str_to_dict(my_str: str | dict): """convert a string as key_1=value_2;key_2=value_2 to a dict""" if isinstance(my_str, dict): return my_str res = {} for key_value in filter(None, my_str.split(";")): key, value = key_value.split("=") res[key] = value return res ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9531019 tomwer-1.6.17/src/tomwer/model/0000755000175000017500000000000015153325403015426 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/model/volume_viewer.py0000644000175000017500000000110715153325210020663 0ustar00paynopaynofrom __future__ import annotations from pydantic import field_validator from ewokscore.model import BaseInputModel from tomwer.core.volume.volumebase import TomwerVolumeBase from tomwer.core.volume.volumefactory import VolumeFactory class VolumeViewerModel(BaseInputModel): volume: TomwerVolumeBase | str load_volume: bool @field_validator("volume", mode="before") @classmethod def cast_volume(cls, value) -> TomwerVolumeBase: if isinstance(value, str): value = VolumeFactory.create_tomo_object_from_identifier(value) return value ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9531019 tomwer-1.6.17/src/tomwer/resources/0000755000175000017500000000000015153325403016340 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/resources/__init__.py0000644000175000017500000001055015153325210020446 0ustar00paynopayno""" project resources (icons... ) """ from __future__ import annotations import os import sys import contextlib import atexit from typing import NamedTuple import importlib import functools # For packaging purpose, patch this variable to use an alternative directory # E.g., replace with _RESOURCES_DIR = '/usr/share/silx/data' _RESOURCES_DIR = None # For packaging purpose, patch this variable to use an alternative directory # E.g., replace with _RESOURCES_DIR = '/usr/share/silx/doc' # Not in use, uncomment when functionality is needed # _RESOURCES_DOC_DIR = None # cx_Freeze frozen support # See http://cx-freeze.readthedocs.io/en/latest/faq.html#using-data-files if getattr(sys, "frozen", False): # Running in a frozen application: # We expect resources to be located either in a silx/resources/ dir # relative to the executable or within this package. _dir = os.path.join(os.path.dirname(sys.executable), "tomwer", "resources") if os.path.isdir(_dir): _RESOURCES_DIR = _dir # Manage resource files life-cycle _file_manager = contextlib.ExitStack() atexit.register(_file_manager.close) class _ResourceDirectory(NamedTuple): """Store a source of resources""" package_name: str forced_path: str | None = None _TOMWER_DIRECTORY = _ResourceDirectory( package_name=__name__, forced_path=_RESOURCES_DIR, ) _RESOURCE_DIRECTORIES = {} _RESOURCE_DIRECTORIES["tomwer"] = _TOMWER_DIRECTORY def _get_package_and_resource( resource, default_directory=None ) -> tuple[_ResourceDirectory, str]: """ Return the resource directory class and a cleaned resource name without prefix. :param resource: Name of the resource with resource prefix. :param default_directory: If the resource is not prefixed, the resource will be searched on this default directory of the silx resource directory. :raises ValueError: If the resource name uses an unregistered resource directory name """ if ":" in resource: prefix, resource = resource.split(":", 1) else: prefix = "tomwer" if default_directory is not None: resource = f"{default_directory}/{resource}" if prefix not in _RESOURCE_DIRECTORIES: raise ValueError("Resource '%s' uses an unregistred prefix", resource) resource_directory = _RESOURCE_DIRECTORIES[prefix] return resource_directory, resource # Manage resource files life-cycle _file_manager = contextlib.ExitStack() atexit.register(_file_manager.close) @functools.lru_cache(maxsize=None) def _get_resource_filename(package: str, resource: str) -> str: """Returns path to requested resource in package :param package: Name of the package in which to look for the resource :param resource: Resource path relative to package using '/' path separator :return: Abolute resource path in the file system """ # Caching prevents extracting the resource twice file_context = importlib.resources.as_file( importlib.resources.files(package) / resource ) path = _file_manager.enter_context(file_context) return str(path.absolute()) def _resource_filename(resource: str, default_directory: str | None = None) -> str: """Return filename corresponding to resource. The existence of the resource is not checked. The resource name can be prefixed by the name of a resource directory. For example "silx:foo.png" identify the resource "foo.png" from the resource directory "silx". See also :func:`register_resource_directory`. :param resource: Resource path relative to resource directory using '/' path separator. It can be either a file or a directory. :param default_directory: If the resource is not prefixed, the resource will be searched on this default directory of the silx resource directory. It should only be used internally by silx. :return: Absolute resource path in the file system """ resource_directory, resource_name = _get_package_and_resource( resource, default_directory=default_directory ) if resource_directory.forced_path is not None: # if set, use this directory base_dir = resource_directory.forced_path resource_path = os.path.join(base_dir, *resource_name.split("/")) return resource_path return _get_resource_filename(resource_directory.package_name, resource_name) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8771002 tomwer-1.6.17/src/tomwer/resources/gui/0000755000175000017500000000000015153325403017124 5ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9771023 tomwer-1.6.17/src/tomwer/resources/gui/icons/0000755000175000017500000000000015153325403020237 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/3D_coordinate_system_XY.png0000644000175000017500000016676315143647637025510 0ustar00paynopayno‰PNG  IHDRùô>(T:ÇzTXtRaw profile type exifxÚmP[à ûç;yÉqèJ¥Ý`Ç_ ©ÔV³„í&Ô@Òø~Žôš@àÄ¥IÕZ³�•»É޾2/^84Üëéà°hJ¦ä ©®pÖã‡S¡›+— yGc»7”]QAqÍ¡™=‚4‚½ÐýY¹ª´ë¶‘ï_iÒ{¬ì qÚó››Mo/V$ÄAV6&b¿ÍUu3ÍHlc&1�¤Æ¾| ÿæt"ýì‰ZU´0}³„iCCPICC profilexœ}‘=HÃ@Å_[µ"UA;ˆ(d¨NvQÇZ…"TµB«&—~A“†$ÅÅQp-8ø±XupqÖÕÁU?@Ü'E)ñI¡EŒÇýxwïq÷ð×ËL5;b€ªYF*2ÙU!øŠ Ð…QôIÌÔçD1 Ïñu_ï¢<ËûÜŸ£WÉ™ ð Ä1¦ññ̦¥sÞ'³¢¤ŸOtAâG®Ë.¿q.8ìç™a#�š' …6–Û˜ •xš8¢¨åû3.+œ·8«å*kÞ“¿0”ÓV–¹Ns ,b "Ȩ¢„2,DiÕH1‘¢ý¸‡Øñ‹ä’ÉU#Ç*P!9~ð?øÝ­™Ÿšt“Bq óŶ?Æ€à.ШÙö÷±m7N€À3p¥µü•:0ûIz­¥EŽ€þmà⺥É{Àå0ô¤K†äHšþ|x?£oʃ·@ÏšÛ[s§@šºJÞ‡Àx�²×=ÞÝÝÞÛ¿gšýýYJrœhu¯ xiTXtXML:com.adobe.xmp Ã�­QbKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEé"›.ò¤ IDATxÚìÝ{œ¤W]ïûÏo­ç©ª§»«g¦'3C‚!„p�ÊÍp‚ä"âÖ£Á#GÎV¹lQdëFظñÐÙç G¼·zPÅ ;¨ A."w�-÷„{! ™ÉLÏtuwUw=UϳÖúí?ž§3�qd’éžßûõªtOW¥/««ë»~ëY0Æœ ä÷¿òÇd�gQÝ¢âkcv¶ÌšÀ˜�ïy��“x¢�àñïÿð+Þ„Š¢X̳£9kcvEX\t *(]t�çtáéQ<á zùhbŒ±�7Æl‹,ry[£_ú~ò �=̃rVDöiÎï/²hoŒ1Æl«B^7+ø×ä rÅxå ÿ·ðª·B¼Wý%s�ç <‹j�|c¬’7Æl"¨?Æó —ýú^—ÕÈ÷:OÊ<ë—¼oÂÔ&ßc!oŒÙ.¥¼pÅåí{oú1òŽïè ÷W Nxü5/FøÂåj fŒ…¼1fû”òŠ ²ˆ‚ÂÞ¤t2ý$àpR¨<êÏ?yÏlñý‹ö÷oŒ…¼1fûTò‹Ž7]áXDdñráý‹nw·zÊ¡P¨!åèü öÜôðÅKIÖ`Æìl¶NÞ˜�”ñ,ª\F; ÿ ø@q�©»¤"Qãðí8Ýïû("ÁZÍ«ä�1Û@3ñNaQ…Eä�—¸·âîã ‚’@çÈÇ¡7ؤ;c,ä�1Û*è›"^xú'ýÒ�qÄ^®ˆGD›Ž€âC_ûö?îÛìzc,ä�1Û‰^.¼éM,>ümQké-5> ð‚ ‚?ë¢Ã<Ģ�ͮɳ£Y¼|@ÉSóÙ£2¦ê’T5ÓŽ(‘Ü¡Àã�Z£c!oŒÙ�¼é�Èe|Â]ñ›@o#??©“¤¤–JóäȈdÈ%úpÉê“}®‹à‚YxÌÖ�M ú"ükic,ä�1wCÎ_v�úŇ£+³<ðÞÔ¾È4�ˆÓA5ŠJO¹ÿMŸ¤ Nö‰Îu<åщ_Øü÷>aÿ’²d!oÌöa×ä�ÙAàa—ÇÅÅËÓ®�¹«�лnC}„ZµN�j‰êºú🩠ÞÖçz_âÕ¯„û¿îÿqø/•¯òü¦µ²1Æs·ÔñêYt‹JÆ"î#Püý9<é�ޝ¾§ïÀé_Óyç¿txпCqGN”¿î÷J¸ö2øÿ¬��±JÞs7Æ<‹‹Í{¯PyôZÝ4çÉU< Ñ€~é±yÍ5—}T+¸ýíëï Å“„?þšðå+àÅÖ¼ÆXÈcîN¯€E!ª�¸LÒ ¯}XŠDu$”Dpµ¾ïmÏWô�¨¹þxVYø�ò\nghßc!oŒ9ÕDôÒlz×Öõ· Ç'‡Bʸ¯x…¶ûãœÔSá¹O†g~ VŸèøíŸs¼áÞÌZC³=ØìzcÌIUpó?Á Û£l&àÁ¶1ÆBÞ³­½ÞFs3ÆlS6\oŒ1ÆXÈcŒ1ÆBÞcŒ1òÆcŒ±�7ÆcŒ…¼1Æc,ä�1Æ ycŒ1ÆXÈcŒ1ÆBÞcŒ1òÆcŒ±�7ÆcŒ…¼1Æc!oŒ1Æ ycŒ1ÆXÈcŒ1ÆBÞcŒ1òÆcŒ±�7Æc,ä�1Æc!oŒ1Æ ycŒ1ÆXÈc¾%ˆµ�1òƘé:µ60ÆBÞcŒ1òÆcŒ±�7ÆcŒ…¼1Æc,ä�1Æc!oŒ1ÆXÈcŒ1ÆBÞcŒ1òÆcŒ±�7ÆcŒ…¼1Æc,ä�1Æ ycŒ1ÆXÈcŒ1ÆBÞcŒ1òÆcŒ±�7ÆcŒ…¼1Æc!oŒ1Æ ycŒ1ÆXÈcŒ1ÆBÞcŒ1òÆcŒ±�7Æc,ä�1Æc!oŒ1Æ ycŒ1ÆXÈcŒ1ÆBÞcŒ1òƘmF¶¼•-ÿ6ÆXÈcvPШ½1òƘ�ã,àW�…6àÕšÄ ycÌö­Ü7o À_ÏîkoŒ…¼1fgè\ˆ Ñc!oŒÙ1ö|'ðg@mMbŒ…¼1f{:qˆþ÷�ï^ÜlÍcŒ…¼1fûÒ-üfÀ¿øœ5�1òƘí_Éw�ßü5ðYkc,ä�1wا۶Í!úðÀhfÓü$U¾1ÆBÞsÛ®;Ó¯žü%ð1û=sçˬ Œ1wQõ¾õuç—�§qBoŒ±JÞ³MyàÅÀs€+¬‚7ÆBÞ³s^ož ü4ðVàÃØ†7ÆXÈc¶¥O‘{ðRàíÀ?[óc!oŒÙ^¼ ø ð^kcî6ñÎsª ‰ç·üû€¿¢5‹1òƘíGNxÿ™ÀK€Oo¶€7æ®ïecÌ�IÛ€ÿq࿟¦Ùì&XÓc!oŒÙþÕüSÚ€ÿ,Íf7v¢œ1w®7ÆÜ¡¾Õ£hö£¿º­à-à�±JÞ³<Šæ¨Ø¯YÀc!oŒÙ9.^ \ü™¼1òƘíéÄ�n¾øS`™æLø©5‘1òƘíﻀ×Ð̪ÿs xc,ä�1;ÃwÒüï+Ö$ÆXÈc¶§Í!zîM34ŸÑ\‹Xóc!oŒÙþ.ÞÐüG­IŒ±�7ÆlgÑ,�ë´;2Ö yc̶·øC`nKÀc,ä�1ÛÜÍ,úÒL²;bMbŒ…¼9}lNšr^•Þ¿­·'¾oógÎs†¶rÿ­6à_m¼1Ûƒí]æyðŸ�%àë4Û�Þܾh߬ÒzbПø¾ZSž´ øW—¿ ÜhÍbŒ…¼9=½(€ à1ÀÓ€Ý@�æ(Ъ û€ƒ[ÞŽÑÌ¢.­ÏsÀ�¦ÙªÖÞ ysWe¸ x=Ͱ}tÛ�¿°ØœÝVnOúíýÓlxr}Û¸©}á?Ô~|X;I¥¿¹¶ZÛ¯«'|_b£§æ�ÿ¾%௲f1ÆBÞœþ/ޛͤS`H3„¢˜mo»ÛŽÀ>àðˆv$ ×ŽÄ6àWÚŠÿkím¹}»ÔŽ ŒÛ¯¹î²å},ìO ðÓ\Þùkà3Ö$ÆXÈ›�§n«óUšaûÏŸ¤ÓPÐ̼ÞìÎi;žÔ~Ü·�ŠušaÿÍK7µï_G3/`•æ’Ahoîz=à×€go>bMbŒ…¼93i[™�ÛÀ>™nþ{Û€³Ú÷/j+Å=mGaósÝ@³Eê!þíÜ€Cm@ng¤BOò=Ú(Á7¶ÙF—? üàCÖ,ÆXÈs{¦4CõKÀo#\f¹õ¥€ýÀwkG v·�‹mØoÿ1àÚ¶ƒ±B³R`å6ÂËþ{1ð£4CôVÁc!oÌ�2°Þ†õµ'yŽzš!äyàžm'`Íþé�fÚû:m‡b•ã—®k«ÿ›Û·GiæØq¨Ç;@›“! ø9ào��ZÓc!oÌ©ÚÛ”fRß×O¸ß·áÞ£ö?«½�Ývîßvúm MÚÛQàšv$àFà«íû+m‡cýv:$r’�mK‹,Ê"‹xvðWÄF=Œ±�7æ4iÖí—m@_w’Çt8¾ÀYÀ¹_)ðšK]š•e[é/Ó\øzÛ 8Öv 47Ú¯½­-²(ÀO/޼˞RÆXȳ�T_x#ð©îwmµ¿‹æúÿ>ŽÏx,Í%‚Ù¶‚¯Û…C4—µ·¯µŸ{©í$Äö¶YŸ8!Pnç¾S¬]´ "mÿ«À'�²§Š1òÆì4©ØÜäçdfh.ìoGö·‚ïáø�nû¹íÀJûöZŽ_Ø\9p¢Û; àNí8—7AÿSmÿqš‰vÑž ÆXÈs&Ú\&xð$á,4svÓì°‹fNÀÙÀÅÀ÷µ„Ù6H«öólÝ-ðzš}Ž´£§lëàDbq‘k+øÏXÀc!oŒ¹í*[Û þh{;±�··‚[/Ü|piÛè·a;åø>_ãÖsVÛQ� š ‰·òWäòËEUY¼\`‘kŸºèâ;QUU|YÒãœÊ¿WÜÕ^‰ðÆXÈc¾ÅN@ÅñÉzÇø·{d4“gÚÑ€ýí(À^š‰��k;3ß5p½­ú¯k;7_£Çòoå áÑ£E>:]¼|‘µóðíxOðºìª‹Šè>8ññ/‰LìWdŒ…¼1æÔ [‚{‰fÿV®íìnÃ~¡í,÷¾—ær@‡ 7žÊ�ìÓkÿÏå,;ýo_ýÁË/#.ì'j ²7qÄ×ã©­†7ÆBÞsêÝÞ ûÄñ9·÷·¼à•ÝŠì¡ãÏöö«êùãÈc?B¶ûÓ¸õ§PïWÎÆŒ¼œ© h– åøÁBƒök&l½¼1òƘoÛ·¦XаÔ»ÙY$Œú©òÃóß“Mí��ý݈<�î—??ž|<’�5%�¥èE4ÇÉî>adáXø+íÃ2ÍòÁÍ¥cŒ…¼1æ.S y¨ÉJ´>§£t~™õ^1O=‰=ä‡tÆ+Wuß»1„±&ޝèÐ\Ø\&¸›f¢à}�ïnïër|…ÀRøšù›§®£¶³`Œ±�7ÆÜ)BôeM*Žq^馿¤®.Þÿ̭ê3T]“æ�©cÚMíÊ9åøöÁã6°·òíkEN3ùïÍ€=4KϧY*8ÛvBÛ XÛ2°Ù!X¦ÙVx�;¶Lps‰â�9êaŒ…¼1fûÉJÔ#燚—AÔ…Œ×=x%ÿé>E*bô(1ÜѰÜܽoÊñÉ�'êÐ,ìѬ Xàø9÷¢Y*¸yÆÀæƒõ¶#p˜ã—޵£³'„ºØo× ycÎhu�ÎÐ9{Lz± =¸+1ØEìI§B³ÚÆwêÔújKõ~ä$÷ož$¸¹}ð<Í¥€ý4g \Ü~Ì·�€Ðv ^B³äðÍRÁÍC…6O VÙc!oÌ™â@I|™ŸOðZ$;ꨲš¤Ñ#Tk’v§ª¡‰^‰ñ. ÉH3Yoƒf“Ÿ“)Ú ïÓ\øßh–~'p^{_·}ìÍæ@k4»jÿýõ¶3p„[6é¿ÕÏ·uó nããÊ]~ž€1òƘ۷K„—«¦Yèü‰wܼ¹¾Cæ:!�2œô#rŒ¨ÄÓ*È6O<Ò†÷o>¿%t7÷ØC37à,àA4 �̵ŸkJ³AÐ�mè/_i?v”fKá­É ï[À ycÌicø%…Y‡¾.…xÈ{„5�N�‚¢�ƒŒ}Tº]Çxš¶ÉÏ·º›³ù9!”}{›¡¹p¯6ô€û—´#3íë^ÅñㄛݛÖ8~~ÀˆæÔÁ;Â:ÆBÞsJÌ¿ \€w¯Í\:\Å(•÷x¢à��:†¼� ÔÇ.Ä©ú»n¸þ[ õ;úØÍÕSN~š`Fs�¿K31pûöðŸÐß2ª0m;×µ¡}Û8ÚŽ4 ¹õ �Û»ð­þlÆXÈsë/.^‡“ƒU…z¼ÄˆF"«ž4€�øóiWMÒH?#q:NgH;m]"¸Bsüï‰ ŽŸ°�fyà^àžÀCÛQ�.Í"†qôË4Cÿ7´‚Ãm§`­íŒ9>7À ycÌ7ð?G³QÍk�ˆMÕØÁSÁ{Y‰¤OçñƒU�=:Á.Eu/¸ÎØë;cv‹rKe~ým¼^ÎÓÌØ ܃ã]D3W GsÙ`ó$Á¥6øoÜòök4+ÆÍÀ ‘[/¼­JÿÝoŒ…¼1;Døyà{€+ÚJr‹ :^¨¢Òñ²43KZ�ªqxY�‰ŒàöwÃ7' 8Ùœ€­æÚês>ÀæhÀãÚ÷çÛ×Ý)Í~7µŸï†6üoXÝê›×üÝm|][`,ä�ÙAÿ"àámÀê–{bÔvÂôrGE,*(sÔQT;d.v¢X JlÐlòsÃI*ðÍÑ—ù-á  ¸x:ͤÁnÖã6ì¯çÖK··£Ÿho,ä�Ù<Í5øGo>}«{;ˆwHŒ^‰ ï‘2F¥BBqD¦#"ÝÊv‘»óé7øØÖe‚œÐÈÛ×ä¹6ü77 ºGûûþwma–ã“ �µáCû9¯k;£¶°ÁÉ÷ 0òƘÓLü ͉qW»­î ”ILm·@:£It̸Ĉtc—8�j8}gן‰�ƒÍ]ÇÜöÖÁÝ6äwµ£÷ ™ð0š¹³4iG6OüðêöëØïÛBÞsšàÙÀ�·9é‹uôÄ"ÍF7^æ}7C·ªBÊpRJHEFöb¿ÝlvF4ÃõלðÈÚNÀ<Í|€=[F~´ ü¿±f´�7Æœ~ÿ àû�·¾ÍGƨ�÷Q|ìPu7ø‡®úg„óIs)AcwF�my×ö®þ·Ú\&¸A³ÁÏÖçÏ+�XæqÖÆœÖáÍö®ÏÞ|èöÿ߼Ɉà;2ãp{ˆÔ¥Y’PíãÅ�íß ycÌÝY©= ¸ xðÁ;ò?yzÇ'ÔõzÎy$C„„úä´F"ÑO­…�±�7ÆÜMž<‡fÒÔ?sG†Z=’w6¤y×Ãd˜¦qsvµ EGóAéfÒõvN»1;™]“7æô#À÷Ï> ¼‡;º5jŒš"ÄN»“]Œê7ïB5¡¢5©C†�ÞÛ ycÌÝðŸþ–orçYOb¤òÇÿÏ„'#ˆI*:ò›�5Æìd6\oÌéå’6àoÞÈ?êôx1�‡ÍetÞ3]F¯)‘ ¨ Ï"jkä�±�7ÆÜ5¾x!ÍæÁ·xvLåãfÚ+x9‰ŸíÅ·dð2DÎò¸>3ö÷oŒ…¼1æ.ðÝÀ¢Ù–ôõ4[–~ó¼ò(½ŽBŒZ‚~õ .âus–Ý4ƒQßÛ¤;cv8»&oÌÝï>mÿUà ÀäÛùd¾ŽZôs_TuO9EÒì]�Œ¦¤ã§ªc¬’7Æœª€°|g<1*íD£:TDí,¥àh*÷„j–!6íÎ ycÌ©sOà—iùËo;à7s¾©çñ±CéÑè‘jÖ»)š0!¦"´cÌŽfÃõÆÜõ´ ø—Ñ\{ÿSš“Çî/eÕ®�ïå~¶Žô©N!t£ÇìHyc¬’7ÆÜÉÎþ+У9l|g~r#ÍBº(ÄZwGä¡�§uဠ’«—1hìFñ¶ã�1òƘ;ÍfŸ¯ŽÝÙ_Àoncç#LHàèCPYPÐ Ó ÕÛ:ùo¬˜Çí¹9,ôñórξˆ.y!EŽ9Ìöšj,ä�9Cí~˜þX:5_ƃïˆëá:ô$:¤C½Y±‹¶;äúÐ>ÖÜ®rX¤õÏEQºÑè@*AûûëìØ5óu©e}_²}øþBéê’<·Ñc!oÌ™æ,š!úàuÀáS“ï[Ö¾Ç&Â=Xê|ò¼”~ÿzʽZGÈ Üh©5óÒ_øŠ*B^åu�Ûèˆ9mØÄ;cN½>Íý>àO€ƒ§ò‹E¢Áç^lrÝ�PÍ Z³¬”@9ŸPºº¨”!QP8·;({ó2¬­ÁŒ…¼1gˆÍF7ûh®Á<Õ_Ðã%5‰¨µGc»úþ­©ë\kÈó#’õpY1äÈèB(Ÿ:‹Ûõ0&÷~t�Ý—LfÞý¢bøéµ�×R×ÖÚÆBÞ˜�LÚ€ÿÏÀýÛ€¿é®þ&*Uɦ¶½Ý·óäiÚsô¸=åè‰�.¸Té\,i_¡ƒ5ö~ð`1,dT—ÉÚÌXȳóÿ¶žßüë�¯ß%_5F­ÚÕï“ 6XRÿUÎ<¦Î^ªZ_äp’ù(Óè[)+ýýd“¥½1Ë—¡Î)©•bÞÕþÿxº¬Ÿ÷4OX(‰\• ˜ùú§9<®KJŽP£pÞѧ?ýØÛᓟÀ=ñIèîG¡où=«ÖâæT³‰wÆÜù:À €‡·ÿ•»ûu:5–èßÐd¥i£43ér¨¶7[?ûyJqqȘ ™JdMÕÝ$¸ÃÎ�h¾rQÈ9>TÿõOÁ®Ý¸Ÿýe˜_€ ï‹<÷EHçf xc!oÌöÔþ#ð½À?œoî¸æúûX³ ©)`¾ï²xÿK¡¿qBèEÎÖæ×, V�cŸËË(ê­ úê_ÀÿôKqÏ} éŸ!ýÍk­¥�…¼1ÛƒœPÁ?x<ð÷À§¬y¶]Ì�¬@¨g”:�Ñdp5^åÝòÅÂ']„èT9<$._[ˉî†ÇHô;ðäGBÞCÿì×±)�ÆBÞ˜mcóÛ?ÕüÛ€µ¦Ù~òÉóZFƒ<Â2”erÌ}U†»˜ýèáò¼7üš2œ�br¨$Ž^…|¨ž+p5ó'y•=ÿbôh‰Ü÷ð�‡X+ yc¶ü4ðDà�À‡îæïFÚoê–ãdgóÊE¢ ‚Õg¶?ÎÉôöàë:ׂZúxòsݘckh±®ôz~ð]¿Ï‘Çþ°š¦�™ñ›ç9ÂdpnjF¶zô÷"?~üÅï‘Þõ¯¸¾œm-m,ä�Ù>ž < xðîÆáXïŸ7áÞó½žëtp�­xTŽÎ€à<®Ð3;äó)Š[¿þn²BÌ™—:�Jýâg{.ý5áÜ9e7‰Ù©ú?™ˆ$’kñØHusr+Ÿ¨%¾/—C±Øƒ-í�ë‡êÃö³ *âË^ _¿ªù÷dƒô’—Âî{ÒÌß°½ Œ…¼1§±à¾ÀûO—€oN•óRyˆ x¤—¨têa. §c¶¢îÖB@“<1½ñdŸ[Ͼü«y8ûå‘z6u¿ð::ïzK]í{ »>³Æè@ÊË�fÃ{Rg7éÜ9ËÙäPŽØ��4·­FGš›1òÆœîžÜ x §ÑŒé’¨ä=ñÐV«¯*Šj i¬Zá%øhÇÍ6¿;©ë\çë‚’¡† ü¿71¿p0ž÷F�>ñ]ÿ0?ZJ5ë–f€ý…ÒÃM, Š@>Ÿ †üÛëòÆXȳíæ9—DÕQ=M€'PG&.Õª9ˆ÷È”38àóÉ2¤,Ñœy…B†3Ïz�Ï]ïfþ7¿Â¨TøÂU1ûüÕýâ% ä%å�ÔßO¶´T„‚ 93R3„¢J["g,ä�ÙIä´ z�x"±­&=ç‘qŒUð8©"Š�x�œ‰•üžsÈ×�By@Ͼבüæ•s"Óz“‡¾$1[ø¸ò#Ñ_øc꥕#¼û3„2M&MµO(„¼”шHžKÖ+aYë’TÖ¹Z%o,ä�1§(ä=ÄD"¼¯dº AÔáP*R‚t3a:=#«Î•C{k³Ð?â�ÝXÔ—>6ã¡ÏšâºêVдž³q^¿ä³ò½P—ívµ5ÔuÓfuóŸQ½urƒ¼9½Ø:cv˜ÑNôшgÕ“V]z}Bn¨Î„qHgêõøœZÊl0*b¯_ºG¿89ð?«î«oôi¬‰ëßNï_næó,Û“ÊXÈcN‡„o ú㉯xýPÆÍd ˆx"}fÜ™ºX»ßº”…ûd#9Wëüï–‹#_Ü@>÷–ÈWßÁî¿ûÝ|˜+½¾ë÷mM»Ù¾l¸Þ˜�šö=ï˜�¨¢ÆÙY—U•8� /ãÝÁ�@9CÏB„.rÝï4σš²FËjc,ä�9•Y�ƒ(õÚ-jÈ)¥¤ &(y&Ô¥R×Jް€#@IeFI[³gAòP“ï0`‡Ï”ŽQ%zð43ìŸÀ#"¢¢š4UDȘ‰¡™Œ¿C\8ì˵ܔòaß9Y]þÐ=õèÚMÿfÊ¡–ò�«Ôßï�yüÛ›ú}üÀ®¿ ycŒæËRë…Òÿà`×ìY«î#Ö9‰�)“ ´ÃïY�³0è”ÔZ´¦„<Ôu®PȈ¢ ÷ÁޝÖ" ‚ŽwĘ"PⓨâAÏx� ÆqÇL¼»a~Ióá©Õu‹ãÅ�¹§ÕùuŸÄñ«s ïX_üT>ÿŽñ¾9²‘­}7òÆÜmµ<<0è?o‰ͲþˆR†£²š‘V=²�ºÙqóá‡�úè{ǃÍ èƒË2MêæØÏ¼†¢–,J�K;¿z«¨”›éèȈ*¥¾r ÷H°àf¦S%vï Ÿ».çRî'/ÿ¯Svý;˜ õ9óõýŸphão.ö_]†¥½ztØu^b[Õ ycîß×98ó™û•³˜>n=«¥Nè†Ó{¦Qrn‚ó'¨›¢ÿ^ݺÂÒ¸t‡èá1þà˜êpÝ«‡.qt4̆Kõ2¤Ï0ÚùW]{Þuê¨UÕ,§[†øþY>ÿî°¢ ‘ÂãV£ßQÕìÞÖ¹¤?u‡? éœs`ô8< ,}xa�l°RÄý ˾dYë�+¶É�±�7æÔÉçq{2Üd0‡ •|^žQ�gž: /žõë�­¢£ NAÓl¢K¢ I�ZÑ©"IQ²´;SöxM÷;+¡ž¤ Ê”TꚸYtáð�çÑÄrPn^NºV¾ÖcíꙬ,Ê 4ÔhF!%¥RäBÙNÖËs¡È„}øühãÐ $”Øé®’[–°%”èÁWà¢Üòoš#`}¯r1¡Tͦ5t¢øØË­?»ƒÞ ©R<¬w~Htr`¡£×­"m®•‚Æ/Œ·_Ðõ÷“�–ò0_ÔŽ²PX�2?¨Ãl(ýþ•kÝ•+ß;ì>ãKYù]¯ÙòG®8:4?çÒ ÈçkgS쌅¼1§P=ÌÓÒ9}W ä9r®öž–ø¥³'î‰�üš$(ã^ƇKUÝ;»KØ#èŒG{ 3 Þu‰D©©Qçqêò )S¡ppV‚‹zµCA#)�áB¤îN\­Y�È�CÑ¥uÇ‘ WÞ¼!,­•õÊzÆh 6Öu]×0.„2Ïé¤rcØã³Îr¬¡ÐÍMe]'ŠÏ‘zâ̶AZ„Ió±H¢¢¤Ó‰.F”j–H­Á7Ÿ#Ö(wt™[ŒJ„Jî|‡ðRLs:.Qá@¦%TÛòy3s eyPϺ×r~ó`Á~ðºÄÁ蟿’××&êìXàã¿Eþ…SÖÚz¹å¹g×ä�…¼1§:æ)I,‹!—(Ås¦üâ~õO©I”xV‰¥ä\¹¹*Gº•æŠÌ$ò.ôrè%eÎ+»U™ح‚À\zª©ë•¼£x@HI(©ùw^9íŽˆŠÆÝåž]E E$@Ç$†Œj8,R�rä°Ã?õœûUOþëq®Äoœ¯JòJ쨯œF6´ÓÙhªöˆn®I÷³ Ö$¢—ªòÉã¥Ã¤¢ öè;mǧx GG66êX‰@gâIˆ PífÈ8øí9\]ΓWKæõæêžõç¼ÐsÎ餉þk²â7߸k×ß»c‡÷~ˆrlCòÆBÞ˜»CA.%C}„ÖÅOþÓ~ÍŸ©eä`-Å ¯þÊQ?3ÍpÓ$€VPUŽ*$֙ഇ“�žâ” šÑS˜u‰®O~—Ãïuøy'ån”]Üœ YRÍ’à¤vH­ *$DPÅ¡=z¢ìïÂ…^D‰•¤ÑÑô1ÿ¿º„!#Õ°¶îâ±µŒ¥UÏÊŠ04�„8ŠÔHÐ{JJŠC *¾’vü-™ÞéUȤù™ï°ØñRWž^ªN„XQÍâÊa÷S‰if Ó¶°ÝôûC7‘bœå‡ø™°ï‡j?vhÕ‘4ûà2ÊrYæÔE醥UíÆBÞ˜»¾ Ë3ögeþìÀsî:?8¡J%"몓Üså0ÊU�‚J©:Iˆb@µ ~ $ÝÝIYEÒ 0 ¤<Ám€Û€@"~]³(ÑAž€ ç\Ê:�Ù™Êõ{êw9ÒžŽ²+‘úŠÎU¢ N¥ãÕ;Pê%:u âQ×Õnb]W„yuº»¹2 ìŠ* QT]3ˆ0ÈÚquƒ´¬°´6©×Y©‘£…ê(Ä•ù~»ÕôD«˜¨b¥Ô|Ó;ÖTTêé9npŸ*v !šy Odº-«ÜÁˆ¸ÿœ2ú�ÎzöOo…þÀ…Î/ šEVÞ[d¥„ò€ö÷ñ劭…7òÆÜ-¨eþ¼ÀÏÞ+pYM¤BÜa§Ó,Íþýz,?;.‚„:h2ò˜‰Ì!Þ%�X3œ@S’%Ñ�T*ñí G\R𒦫. Bž¨k’fÁÍ$¤#¸(ZT)Î'ØÓ�9Aö¦ÄœÇÏ‹ kœO~6:Í’¤H�µ6'¼9‰â„YQf{pÎŒ"á\"*h­„isaÕ£«ncuµN,¯)ÇVÈŽ.ÓYýºrõúiSäD™€v¨(cÔ…ˆ?·*^(”$=íøQéãºctºÝ¶µÍçeéP]Ÿ³ð�ù˜û¼ÿÓ¯.Þ;²|3Å_¼·_à–q°r æ¶LÎXÈsêõ.¦»ëêõ‘âˆRôÝwF<+¸?ߧ˼výŠLãš'¹À[—)¯ö.᧨’ �ÐŽK·Ú£>¶»×‰£ øÍ h÷/o†Ã·ùˆDhÞS€.Э7ј:tÚÔÎëѱîáÐp(2΂t+Üõ’.�Fîw÷Þaf.c!%æœ2“ E=…\8/¸ä�äT&‰¤(™ ÊÒ=z6Q…ŸÐ|/e@Ö¦px„;¶�®î¤#!1š k‰�¡£ZõhÕCèõ¤ÜH‰„úu·”¹::Q¥R?ƒ£ò)t£x¶î_ßÌèŸéD€8&mî„ß¼ZD˜63ÿ=�Ñ•iw !FõÉ"„ÐÌ?èâoù�MùæÄq—\.{öÕùäÐ|È)æó�ÿôÃIû.9¯¾Þz}ñÕ:xÞónÏ5_ªËaZ (õ‘fëcûÓ3òÆœz»®>·>R t¾,èí¹Ÿ û¡ûHøi¢È5Cõ1…xe™ñÒés uë"¶ö»ÒÙ ÍÉ4âÄQ ×W·ZgQ@¤‹tº¸ÜSwER_aΩŸs*}M:[�fté8¤™¨J@SD©Q'›ß‚ÒÑ/\°—È~àÂÊ%EB„É&1ê µ ªIg5 Ë뤥��ëýY¦ó’w¢'‚—½ceLÆ Sõt¥"2%hs•Þ3ýDŒÚÅKFl¾‰xËÈ·ÄnßA`Œ3|ÛeòÇ÷ÄïNeúmœt§©™|¸rt>@AyníXù…ÈÆý%E»nmîûëîèYåô†ÿó‹y¨¡n#²¿8c,äÍ]¨dI ûŠ¡Þ¡Þ\Hõóª’�Q:�¥ò¡R³�U!i‡$é4>yꀔ4(!Eu\JU$‹�ƒŽa:rL51J‰£8ÄK¤›�.N†Nsº‚v2¥ðIæôgEûNe>S7çT}B3Í8M�jœT�¨�œææ¼°O�9J¼Â蹑¤�q×i4 3Äû=yÚ$«ŸóÜ»’õWC\ŸGgÏê/°1 µÖ6ÁÎ ys÷}¡ÈOÜ¥2ýù ×IÒu•4ýz| MYʤÍHrºþ,›I⧂lj‰YSÐ1©¹�œxœDÂ-‹à&�¦¤¤lê`Úì%4 ¸ 9œâÑÏ$×ÍÈf½†�Îd0ïEw9‰sꘛIôÐöÛPÑvy 4Ëk�¸ˆˆfs5¡é�8|¦zßý*HîD@ꊴ:]©\\ °º2ö7)²2&-¯ã�.#“/§Ë3ýfAâLåðHŒc�uSóÓ…fm·é ŒoêÿV9b=«±)c^J~û ìzüϰvÙ ]Ô§EFo£÷æëÃ…½À²ý¡c!oîç—~jÊ÷] /\o䢮)i‚~$ ïŽ]èv’+SHzš×cÝ]� Q©5©tqš’æŠäIj—¨}Mà\B¥ýÙB kNxŸšÞCt‰N3äŸÊ,M*Ÿ&Ô•”Q4¤—�^rN\Ê’£ï•^GuÖ!{R̪Î{²ybÑÃu!áðEêø<J�$•‡aÔ$Š÷Â>û{ÍÜEˆ$HIAêè`ã©Ê€ñêZ€c¥gi”±\ +ó㯯G¿¾a»:w`†Š 䛽KÄ»äê4Qæ3©ëRóroU¯}p çÿ�Ðuô®þÿ´”@®e{ð 1ÆBÞœJ …Ï!ÖE-”(EáBÉs…§<¸âÅ í–(«JJÚûDÙ›üóú„ª wã0�¤HHu×—’FiöËÉA: b�iS±'\j*yBSÕ»&Ã%’´íÔî–�H;ÞC¤&jH)ùà—Dò ^QMÍÄÀqJ¡“\R8–H¸ E¥Ù¹6K�˜Ð]0ïðsÞÅ{ש¾8:�‰Â(‹²Bðó"¡ëÞ%´é[ Q” ·ùM©W%SG¯Vð �‰Ž~ÌpˆÞG¦1¹,�‡§L—kaéz8œ%V+�<+Ï二¸ÚñЙq›-}˘:sS?³ÜMÑO‰À4æ%AçGç‡OþQEŽÖ~ÿï(�eøùµØûÜ«ŠÎz†¹RÔBQ ·®Ï!4/oyQJVm-Ê„¡.µ[~§yьեR6§b}c!oÌ£�úýÚFy¤(d1t¿0è=ñ¢lòŸéÖ¨ T‰�)Õ;ꊪëp‰)�&39�~3°› l$µ&…pËcšÂ<�´‚õ iKÉ-ÿÔ›+Ú»©Ù?Ýz2™o; ·|½pËý·šU¾B\Öbâ`DÎÎ’ÞË ×¬:}¯s!Ï�è˜ žÝYÒ¹L™óêæ •]í Òs�K¯D ¢’ ’Z�"^%WÕLáÎ)æTØ‹›m ¦!J¥1�²Še7NƒÈøX‰. áX‰}qº{õ T«ãÝ3Ž ÍGHD¤S]ôLØß6$;ò䣞¥¿òÉe:}WÖó” uäÀh¤e=O ” 5Ïk)²Z²ƒa‘šö@MNÝA\¢� däuNQ¢u>Üì$HI­ÍyÃÚ®÷ ycrjFdäeÍ‹àQ÷aú‹Ý E ¬àÓ$ñ‰Ð‰ï¤Tuí¥ó.ÑÉ"5šVµdÄÜFŒi�à¦$wˆ'IÞ¥ãyÈœ2“ô»èlGe—*»s˜¤í†f¥£óàœ""x•R›K3^tV…=’8OrT=ªs�u}?†“˲T…e7Pôðµ¸õwÄNg†kSd/Æ)r�ì*nò÷Ø�;¼:Ã’D1/ƒþG¯'ÅÑ/Ƕú–ÐaÈÛŽO€<¨)2$²PkINI­µ”’Èë\‡ u^dMµ_oÝõÞ ys&«ç©©•¼”—Öù#/,ÝË{>íGâª@IüTþ±ª:uæ*k¯»ê×âašbL ªh2!i–¤® 9¨2(Acé¦À´H+â6§(Þ!Y‡vU(³$æRdVa—S™ ªý,gWžð>JîÕyUq5!%—œ‚SE£à2!!"n¿H¸ÿyõLå,®åÍZÓAÐ×R“®ê”CÁq,”Ãëåðh£7‘ oÎBò\) iÊú2ýÚ‡PkвÌS™RÔ4_BŽ„²ÔQu¿ç(E)ëT€„¦çjcöÆBÞ˜æ URÏîE¡|ÐCêpù,Ùü$’ÖÙ�ø9™á]õzV—T);>âmN1§ín¾h3a°9µO]Ȥ"¤I{‰¤SA'Uv«!p®¹h_'4$Ô“Mr²é×c5H.á3Ä;$O*½ݺÈ7¨;É…9ïc?æ\Å|7廄4—¡shê‰#‹ UÄ9²ö¯ì£ç®kb�¨ÓèoÐN|ûzÅxJ¤—�*ƒ™æ€kËSè‰fëß^†Ÿí�§˜TÔ%²yÖ®§í¬¾[Uª‡4¿×,¦$  ¨@e³ºofjh>Ž«m§í$‘„Èæ�Ms8²±+e¬iÌß¡ Ä嫪ýëåg7‘¸Ž®»äGƇù�êùÿbïÍ£$˪óÞß>çÞCN5w TOt3T5QÝb0¸«°Ðˆd )SF³ÖÒƒ%ôd/Öz~èyYª›öó ?¯‡ý,!Ó^z–m!ìŒ'Ë’ T‰A7 D• Çê®®)«*‡ˆŒ¸÷ž³÷ûãFVU£Æ–hºénb¯•+3oDFDžsîùöÞgïïÓß9`Ú³Àœ™ ¸YCçcÎ!ӉɌ@S 7.Dt®Žó]¨ÄˆŠˆX"Øo²'!Û¥8Pbf^‡è¨ôl¾4²Ò\Jáü€je�qyઋŸ«XYŸ¦ÿxƒÑÚ�˜v1RHš¸ÐCëä?T³3’4W% P¬ŽÅqf[ޤ’�°«•þI:®OÜŽ«`iZ]í(*¬~�b«~ðÚ|¥©PU–Hª”‚º«…¢;¹¹&6ù‰}•{·Ð™×*f9›ÂŠû™¤ºñµEò‹M⾞˜mô„Ǥ—%8$3Ç' n²=½`ï¨PAbÉ_c›b&q¡Æ qON:¤W½e Ðmœ ør;§ñýø/¯ÎêVÅ¿^çA ±ÄmHpH?¸XM©[ïO›rhÿ^º+�ÙæŽH·±�Ïm”Äl=2l9.º„‹N!Ó€Ö¤C¢N“ KJ[qs-a‡ÓÀ6H¶gæÚ˜µ•Ø4Ã*&æÔ᪘w5EE°f¥•®úÿZ ÍÒÙ.¨^ŠEÛpeDÖúhׅ˃*=ªæÙ‹ ¯¬dÕÆ¦°™uWvwÄ -fSG’½B[Uj-fe•B[ -‚ÌVPÁZÌH2ú…uSh-«H)ÒéÓ´’V7Ø ³€‚ŠîÖ°ÁZ)RTXEÔ�“bÁ‰M@~b_µU³©[¥E«Â(à'µ:ð×£üŸS„[KÁõ1»0ÊÊßÔ@o2bϬi ºu%¹Á¶à¶g0[�A[Ç€ýL4§ nØÂeº‡,éUCÝÅÀæøø·6?òÐ ß>Ëaþhù²~{Rg,ŒÓ¥ƒ¨jžDR¥ P�öC¢—×à!I1UÓJ ˜BØ‘À,Êl%lS‰3©ÑH�¦«u�¤ób¢®2ÜÀP!¶a›3n™Ra– GÅM`”2¨�Í€m”¬]L°×]\‡Õ =3€õ‡)§fâæý;Z±›ìÖD «Tɪ$ÕUa%f�¢jY•¦ÐJ„¤’ª¨´¢¢ÛjAUXZÔu]°¢µC˜Iaht»Ú¦štLlò{*(�A—6;ù~¹rà Æ?ic·V8·!Ê@¹à ¿Ù-ë¸k=ð{æLÀ¯*¨h]Êë*ú”«$=Ϙ•%1”.ŽHl•Ò•åmÓM®Û¦Ö¤2ì5|úãÊgGîR ®& Òñg­¥t”ÔàïWbµN ”(% Ž•áªc=U$;ÑÁ´"-KÒHÈ*Ç”ÃZ#˜ËT¶yó³Ùå‰3‚¶Í‘�‡Î™àp80E42>×›BlZ„}Mã%æÌl'b†SÐò7¿³'ki¯Z«¸|y“p~Dv®Ëô…‡(.�JâÆ¹Àh–Û=Ó%kZt‰Ð"!•Puµ¢.ö¯9*fIe¦H€M°+À•Y„îD¨gb�ŸØWi³¡’™yCveßÑŠ´nâlo]å<-]:§º²mä\_QÜdÌži €¡†ƒ‘ªFgN°¯sp#Á·Uí1Ý“~‚Ÿù�KºiŽGÎí/¾o–�²ÍçÏ4Ú#]ÒÆ„(ö€w •»ºyÉÖø1Ó ^sr$sÈ´C*GMÝC]‡°ŠjåBlÂ(S6¯&Šl¬HêLÈ”’ùÈtæ˜IÔÏ5-ÙaØ\…M ºÍa³@’šxgæEðfÃP§.b.¢&ÍD­U:Û#¨•‡�¦ m—‰½ôÛ‚ë+º’^ïrÏŸ8ÛwquØà¢ºâ‚Z±qzHù¹„pvÏŒÐÚ#œÆ.+VÍt]1LZB•BUM~b�ŸØWo]fíÕEwûÝ ÿðFó/Þ@´‡Ê†«Î{xß h]NÙ¨U8_áœb“øgÞÆ”øxD|-#c•`iÀÈžùìJ_‰—ô�ÏðÓ?tÉ¿ä ±Ò.Û¬r×�Ó|ø�¬9ŠªH¢-IÓ"I#¤[(Ï5€÷ÔUÿueÛXÏ©\ïLõã›�˜‚4®f“Tj–ÅúOuK 8d�(‰"í�ŒkÊÑÈ1hreè‚Å4ŠwH«‚)EŠ‹ÐaÛÇSHÜáLæR•™Ù&h[Ä|SÃ‰Š€H0³0À‡³Ys.Ââ&*0r6$† T·ÁÊ›—ý¹ÞJAo%4¹xeèΟ+¦/ý9ËÒ*Ð’ÙëNšû'¶ò¹‘›E A,7ÜÝàŽÖ•7&f,!î�þ„œ÷Û1y«¶Êq„Ijèyk‡š§†%³;Ül·°dOá_¹ÑÝþà þéxƒ7),½T9}oW¹Œ+H@Õrr€fl,æ.��0󉺨¼IRÕ“šHŠIéxÚ,–ÕIímƒ9Y§™z- 3!‘ÞŽ/ã3\ÄÝwõhÝò辀ϟo:\UŽ—Š+(A…'|Èë‹þÄmEòÿãÕÕr[%„q¨ÐñkŽ[9ý¸X0ºÀô\  2ÆM3êÔøf-AÐ]}Yñ˜êÓ;½îа]ÔfS³™ ™U˜ŽÐÄÈœáÆEŽ®tˆ˜˜QÄH0<· �›k6!±Æö‹êÍlêÝ&ñg ×Ò½Îõ[\*z­³§]ñø’Ðj;Z¿<ÍßJ±ö­ØÛ²ëÙµËñ’G"�¯FŽå�£GqËË(˜--‰[`v¿½v�.5æ NJNÇŽ/ tr“¥\˜?*°¬9püº‘“Er8žÛgs]ÉyÔò"fˆm‘9O°äkiãªYsµºÅÕ{(šb†]eÑ6`Qdé�ä óvÎÄ¿Gb8È É'ûøsÃ> œ~ã/û·q“_�y”¢7«Ål"oÐÕö�oú´ÿªµµ$H7øËæâ{»­$>Ÿ°rÐ ð¯…c]¸í˜%¿›$áZ5ù×ÙœCœb#0— s�¨pìÛ*yé4–\îý¤¹ÿ®‰>mÞ—�ûì-Ãi§1Qh5HÖŠ¤tíà/Žìü4ß¶ðj~ë·ö¹û/^ÿQ†0{ÚøÁ;„ßÚgž«kåšwáÐ0¨p(Þ©8‡o8šÓŽŒH[+f�ـߖbÛfL%HËaM‡øÔb†u¯ fRK #µÚ¡3ÈHÄ\ ¡Î~ [{>þ$¡›"f±Ów8Û@OŸ%½8ƒ¿téÖáÚ¯-EfZÊ/}Ï– sÊæ9):uHÈñ1(/8NÍ{Vv«;aQÈs下clɯBw}s¹Ð9$¶0Ï"X¾u׈L0äéŠäÅÄ–:ó0B&‹,äÌ ¶‹‡-_8e‡–D�Hž ¤n¡™ØóÓl �áNcöмf@ã'Cúó³TG6|´2z®«Í4¾ï|ÅÙ™aâF.Líëh:&¯q®®¢‚Î9þP���˜UXC¯µ¯Í£‡8‡”%š(´Ãþô$·ïÛÚ·ñÁGf§iÊàl¸›ÿö¡ƒ3÷¯õûOf?G�]kŠàëðTiRÈuÑ• h\6�U�â"D*æAœ£éMÚâ˜j»U™sFÛ";ÚËÄh˜‘PK :)] ¶ŠE¼%‰†¶™Û‘Û7°× Šl Ö¤ªR ÝÛ–�ûŽýКâ™d IDAT^‡Çºü­3{ÑÇÊ)=’±ú¢vÞµæÅòyÊ\Ð<»Â''€K‡ŒS¹!Âü’ì8Õ†àbíhÈõØø\Þè#‘0¸ÚFä*”~YT!q0h?E\…5jZA+¯s à¥BY:zkp!¨SoN||‚T ÍAéÞ\‰¦Ì_Q‰ÓfÖPh+¾­˜¯0) ©@*Ì)H®_LÖN�ÛR¸]T˜¦¢ÃÁ›Œ¦ Öæ6äügòxþá9Ã~ŒöC3$çVäg>±�_y×Ñ#gÐ{ïƒ#k(SÉÅÌ&ÁÁÓòw잺“]ý?�}TþD;@)·ðŠGnáN¹AÌn»Ü´ˆÛÈðô�Ðßtæ>øMÙ¯2·ñ0'H8ŠZ��¹v¯ÖGW'oȹŽESÄlì¼ÕÏîwæ„äøVû˸(öܾë®Mì)Úž–OWÐ$-(€Y!TfUáßäoïC¾  W¹5•"f±3 |1¢d´¤È i;Üèy~&ÿ\ åm|ƒ—8×3‰¸hæpõ1Û× šOšø8p!ŒÓÍê ÉHL*å\öþÃòÇ(Ï=Èëþf‹GF‡¸÷OêdÔV'ƒL§šeR>ÏÖÌ“}QKà2ÜÕ£’ª¦ã%©iž …FHD#˜8¤;n™ÖG0¦˜ÕRȸU?S,CÅ%êÄ!” ]eDßSÈÈŒÐLâ¹fð±Æ� ¡ŒVTš-EZ%ÒP$¡­(–ÁGâCMÄÐjî€X“Oõ„ö†±ß©!˜aSSľxÖÙ÷¿‹bþ]öh)öøC �4½œ;Ÿr¡lp>{Wì6ºËÿ†xìè{Þ`Q&5_Oäùm~o0Í I¥�D‡šƒeͤåq†ù A´á|v¶|qù#ÃÓ̲£§NÑaÞNŠ–góQã¾·ï¿'’c9¹œä¤ÌƒfÑŽ“†,"r²ƒ ãÜ�Ô•–6.Þàxíb®NélU±^õeìLÃWkkèöVáÖÚ*f)öWî5+EúãÆÏí%ùÞà+7ˆ¢=MGåLõ�~ŸSudQ@@G“Qüºš¹D¸O=lWWnó¿Ìï�=K¼üðr™œýCíœf'¥k¬¸)º£ô± þÖ®‚ùË£üdY@8z”ÎÛO’ŸÊ�ÜX¿:‘bŽC§�xÝìZ�õV'õjÏÇç“Yý*­UÁJ+5Â,-à•ƒnã-ð³7Fÿ7G6#º� 3ôýe�ÏLnž Ѽš²?•q!5¤‰sAõk²iFŦçh„"„àÊŒOó¦—ô¸u÷ͽ��|Ÿ¼Ò.á>÷áÏ/Ôoꈥª8Ä%¸/w6&»ù×ßD0"QŒ€PáègÂ*œÇ‰�S“h11ÅEG+m�¤ÑhÜT¨Å³ ’ KI‚àÌ�Î�ˆ€Hi& ÌìQ7³‡r—JùÒ†ñšƒçyYg¾sqa2Oä[‡~(±S¯Òóêä�dz€ •º-ÃáÄ!G=±Ñ¥BYEY'1t?«vÉèNh‚r­2"-)ÜææE[Û\³„Ó¼Ð�æ“\bnùL«Í…äå�Ëök›wçÝ#ÇŽÄûòûtžyéÐQYîÎ…»—ayÙ/æ¢K‡p»—‘�æ¢�|IæåTÝÉÁq0òÅÉ™ÎSBùB°›„¤ÇtsÕ¿¥ËOTùÞÊG_(¶nR¨·÷_ðñ³V6TMÆûYì[æÆ‘_ÃáÓ!w¤¸9Á¨Ä,Z° äk‘#ÚGƒh%Úsði~êµçxÃÝJ&—8xx–/ýëÝn åÏÎok’ŽZG›Î@ñ.–OÄõÉÂzvØÈ�;5êk|¬×0¦R¬µ*|týôº…(¨à< …4BÕšÁhVHS±V€V…dj.§ÚªNñ2�讘›kÚ:ÜÉ­#ùÄï{* ?ÿk§zoïä9vòÐ N¿uߌ®Û@xkt¼ó-bŒÎáTDŒªªhJJeJEEC2ê“u+q1�ççÔéöš\Ú^Í@MôG7¸ -Òõ>£6u^P’ñÉoÀ4 _þ&¨ÿì°¨5xjµ£']oÎêvMõˆ&u—„xÃDÁ|tŒÙ e\€‚$Áil÷¼Ôã|\AYuü‡ßþ�ð´°]™›,t&sñ”@þ=wZ¼ÇÄ0qó‚ÎwLï7ñËËüÙÒ±¥Ïÿüï/ü£‡öFyœ—¯5cÚœ÷Äô?ýoÿ|xÏÉåï³wòN÷Kówêò¯ÐrJ{MØ[>ÂÞæªÞúì%qr#™Ü¶G„mæLÎ<àˆSc,g’1„]d¶‰¯ AˆBtÎ6{Zõïc´jl˜“ L¹Ç¹ß­PÅG‰rž~|¼±‡Ç²’+½wQܼ=}ŽÈ·¢KÀ»O!»ᶯao9�å8äù‰Ž£Uä¸]­é_ÞôÏÃÖ|¾cÇëŠsäÐqd¾îïïM¹%wG�«tÁãbÜa°ã[ý _‡bçJ-%¡Òm«ü�ÈwÄýTåT‚Šlba#á¿• þ$ë;”†N6ágµ�ï‡n‘ˆ âm\Íí!lÍá_ÅOkáuTóÀã�ˆRÍ�´7Ú±Ÿ ,QØÏ™aƒßùÄ 7®âÓŸV‡Xß…&êÒº‚üú¾“tý³ÈÆì…[ºè_|sà sñúÖ©±‚`†o^+¼ Á¶^0¦¸*¤ûzTßœ¢i�À¼^ÞwÇN~ná”…wÞ+þÎ#KŠLNåŸÈKÝ_Ã[m,‚‰E踎-ðã‹ôò<þç—ý)\9ËM†þÛ›ƒê[¶OÅÿ”/çšç9wæ�ŠÐa“šÁiøü°î�ÞtÄS^Lx¼ŸÒ¦%3ÉÌh¯­ð"›åf…Å$™¥éR¹Òp7YÊ>¤¸…J·ãjR<)†w±þ'$àlhuyˆc&ˆÌ"väe ©�Wˆ\¶€c`é +ëü=VMÜYÐÇñàÂ}<Ì..´ÎÐÛw+Ãp˜áÜ�PÉmæ;Ð9– Ü-ùòG5ßÒdÊ…»©9|‘ºÿ,öðŒfs½4ºÁ y0mÅ¿Gñº;pÏœN‚ÛŒ{ؽ!ã¿ÇÒE?¡xîEô[uµþºPD®ÊÔ‰>1ŠŸØ7‚UV¦ˆ´üFRì)#ß’¢�MAÖ ;Gö{ûÊŸþ[ÿÒÖ옌9ë³ÒE“ éÙÓò5뜌¡ñª `~·$(œ0XDèö_ûòIÁ¬>eb¬aOü-ŸÇXÌeéЂÐ�ùù1’9,Ÿ4–ÛIî<�ÿn~�„?æw¸çêÕ~…7ø/q÷/þ²åÇ©ãmäø"h–ŸŸ=Bdñ{¢ä÷=i$/‹"9Àñ-:Ûq2nLg{]kó×eĶ~ìH�%è\U0bëtp�wc=ŒuŽcóàÞz+™‚�.?’çÿ¸Ûíã~1rÄ…ÏZ'yðô¶Þv&÷nì }öÐJ÷»nu‹9Z+ÙO#Ü.‘Yƒo‚_"DJ­»F 6ƒ Û$á¥æÐEƒÇ(qt‰údœ%ã"Ÿ‘‹ÿ ÍÏ+<Æ¥ìQíÇÙ½ý4öÚu¤ŸIè…–ýbwôú;ð¿à�MŠõzIü¬†äwÊàJi© g~rþþœFüÊag=ÃjÄÀãÄœâ£uˆý6ÏŠZ-)� ¿¡Ã ç^È<êé~øüi:×Í\�28§T%Ã9‡X‰ªŽ� þgÅdæž?V3Þ0Jlתò×YÅì òÈ~â§Ö»K,È�GNU:&²ÀQgbãÂå‰ë÷Õ˜ð¿ð«²›WÙ?æ. ò×8&?ÊïÚ¯ó½ü 'ž×)ML®¼]£Æu¼Ÿ ¡‘­ó‚Xp«5x-nÔ¦Üʈ]8Û%Ê Ó–IŠ�ª]¿ %¢[yø«o⨹-=fI-%EF$u=„ó~ JÅÃÒætÕð+ ³sìðhÜ`X¬¿õ“”÷¿¿¼Œ½‡{u;GtÁ`¹#ìÁQ`ó¿„¾ó�¸÷ÁŽK®’/;ò£ÊR.Gw#;–~(4ùÒÏ7«^¹Þ<Þ”áôP�UÝ„{›‰}pFU z)Qó™º$Ô‘ÜÈ�¨³ 'ú *)ûlÖ“7€竚5Œ}y› þÍ}~`îÆ È§>íâï�2på_üÌ>«Ec¼C¶Í·ns@%»iœ¾ôm»?Åw}¯c6~ð‡‡g~㡪_×—ø­·ûØóEOþëiA1Iù¿%Ì�áþ…çÁôiZ¥£iDD}Í~S9M|2`ª�ûë†6 D.bvÿñǦâÂÿþQ»bï—¸ÏÍžÉ"äoŒHþ^~�·ó£¼‘~Ÿ÷¹—ó“ö0Ÿx¾üØ3´ë~Ù*�W#Ëp³±'· ßÊvwÏ[ï�·0ÕPæ|d{(ìFíÚ�ûÔ¸õÉÜN› û 6ƒáÇŒÕ" V¡VÂØ¿ð©xmìŽÂËI06† qTPØ€($É…{î²3ÜÅ*‰=þ¶©W=–¬Ç‹Ó_àü&œç»Þvú;­Ca�ùÝzôHGò¥\8u”{"Ï~ê؉ÛߥñÏýuó›îZwó3T³Ù>öà³ÎÅ\ ‡n|¤ëÑ!”‰ÖŠG§R&*É„ÄäÙ¹®íZwœ9U’õx D�RGÓnÌ<÷å‘u]‚f³�5‡Ä)‡èÒ±]Ÿãæ#§‡¾o_Œw|ó�ŽÓª 'ò›Á0Á¼«‹=£GR�æ koHù*3m–à.áì2úqwküÑü—ó;CrŒü8-º¯9È–{í‹,só<À »�o³ó‹ßØ›d~50Zêàæ�î�:GóîÏ/æÝÎä9Ÿ8¹„|vž¤OôçOÅæ¶Ï3[•̆]Ü0ZçÌÝlSþR^Lv 6#0#ÐÒˆŒ)B„€PëôX{üµKœ¾Pµ<�ÖjˆBÙOéË]þ?6É>xÁNÇ^òðòŸøÓÉËâY¿mùòOAÁ·w_w ã`j{FÉËÄf‹kÁ1ÀÊÿºæšC’€%$â5¯˜c$£D‘€55€*„ À?+W Ô5×&¨>n©À¦¨•ç*W«†O–wHp¶m Ȱ‰ JâšÛRúg6Ùx¡‹k~?o#ª ÀOlœá²$@ÄYŠB‚#ÒîR½ª2?WJtkWÔ|´i?þŽwÚyÞ-vôD–Iœì*OÈ|Žß’yþ¹�bë|�_ÿF˜8Â<:5àߪÈë'R{ž PÖq” ×O.lÌ·:þ.¾�/*œT9Ò9âÿ÷÷eofÖÖØkŽ}®Å ´g/ ²Pn’È~Á¶éŒìÄ‘"5©ŠX”­fhof Dš¬ÉÄL½½ÜœHP‹hP!ÌÚßèãã£+ �ß=[Ý~î5ȇf1½‚¸Â.H«üHóQ˜>‹45AÀ�\°’`qÌ`e€&ÐAÁaŠ5ÜD¢æY øîšÜ¬95$b¡Yùä mâT¤¥É¦¡aà¢+Qì•Í~éÃß?õüôw Ùþ;ø/:YƒZý°ô€)i­\׺lÉ]a{ Ò5±‹ØÃsè›ßñÁ�Û1‰N„ǯéŠNJ2ž�ÿ¿Áëy‡¾™äcüríôC‡ò–³ÕxÝ’»ªo{í÷š8_¤î{¯%ñLÄ$‡pÈÉáø!¡÷Íw”έC˜Ò™¿‹úÍœóG€µù{ô³K$^&kSýOÎäJœ#­v£åÍbÜlm»Qn5cÎeDoqÞœ ªb*ÂÐ ë(il¥q4uËEnøÇïâ®Û»Èÿ»—ð¯Þ†k•Êœ M¦#úÉfèÍnÐ�;ÏúÎÇXÛ}ŽÍ�÷±:ÝC½CŠHT™®  “Þºg£�;âë¶#…¤ä¦&ÖªK–=RFÕ gOvä¢ ÖOBꆌšê® ¿yn;¬M•›¶IÂËøð™åÇvr¹ðàúêâý×Ê&»üsÏÔ�¯ë�\t4׃ûGÜÕ¸lز’LÙ÷°yâ.]²ÃuÈ ;.&cÐÉÔ?M ANóaÛÍ�ò ~õ}P®ÊØ^‡ú×·Úu�]]›"v-Ò‡|ýϱãã×�܄ËÀùa8té€ÞÓ�¼ƒ-‰U@)° — ÃÑÈî£Xg9twj ÇYcNwÇÇ8(Æ-¶ƒ}2ä– ¹Ñ›m×Q<ˆ0��î[AÿÙ»È^y?6PxÝÇðÿåõ 6v�´«Œ©Ê¡ÚÂÑB.ìBÜmD稼´AÌìÏZ²Áê¶U6v®Óo]d}n•böƒ™ÇìƒVSÆN‚b¢ �pµÇ¿�“*Q©ŸtmƒŽûºŸ*àÙòŒsHC+1_c?Þ!±Dã°©m7tΩ Šz?@/q{ûcüØ›7xñ>•>k¶÷¶^u`›ûèã D+aä6ÉzħéœØ³6S4Þœ¸ë„kÚ¥3õ:ÕqgJØQádC° &gü®øßyéS0oY㱫QÒ8 :™÷§ ä_Ïßàv^Ë{ùþÉ�<7-·s³¹ÈÉ¥â, ÅÇÿWn¾a%ù¹&¶«�h]„€ ÏÅ—~)»|ËCåZÕæ\¿I»Û$íOÑL1S nG�ÇÜ�îêÙC·0ûø.šçvÓ:³›¹õmÌT®ïˆeƒFLiG‡Œ2¬×®?�ßK´;ò�T8ªÄ—ecTí.kÓ¹²ý<«»/Л=Íút—òbU†©>Ê¥~¥Sg ôj¤]j}þ›9Ä7p‰ "U°AÙP«%­‡X‚ˆÇ¥1ÐXpP‚ T-+¯Û¥ÆÏO¾�×ÍÔÌ0[í3JA’íd͵v(P6hÏäs�ˬ IDATìxCצ÷îáä…|áâäN›˜ÔÙL‹2VŸH"ÄL›ƒÒÝå±Ý‘+¢vÖ8ÓÀÿÈæ»Ã§eþÝKªÚgä½ggüCþ)ãÓ!yŽFpbÈ’—°üÔ‚}û¿àÆ�ë¼/!|s…Ð3ѵMGU•”JE$¤]º3]ëÞ�à5‘(F°ZU/ƒâ5'é&Á›G¤7÷ïãÅÝíÌœßNry¿:G²6…õÛô6§mÝ6ÙÆ4ioš–¦LWy¤7ÃÍf1^ŒJ‚‰G]dذ™t››¬·zt[›Úß¹Jö½Ù³lîY¡œù³¤Û¤! TAÇ9â ?3JâÕ€¢Î¤L1Ð ')Šh¤�’Ô\N®*1ás½»çÏ|­RBk1!¾2c¼õ’0=v{|?IJ9�ªDoOþô‚OÿÔûþ¹÷opç÷½š÷ÿ^Ê•r²7Ol¼ ,Á‹€h‘„Æ äH…îD®8• *çcË~øSÅßÿDÎ!¡³€-Œ IÆÊ{†@>.³4Šç¶-Ž“^‹’ë›xÏŽW~³)å�#ÖÄžõ;Bò©?ŽrH¨$zÃE¼T˜4Fo⢩·Äe>8Kp1%ˆz¼+(£ïS¼ü>?x�#QG:LiTžtfÄ(-Xï§hošäÊYwštu†ì3ßÄË7ÚdW¶áV¶!«³¸2õ$Áðƒ„©Í{™öžƒf˜YZÓ �D6ŒQà -C1µÆúÌy.Ï�euÇ9z{?Ëj±lˆ6KÕ,Œ�j,¼¦X¥u?8šHŸç_.ÿ|+wWA½þéT¹žÝV&®$h¯Ìì¾ãæ”nqcyï…f²)‡x ×çìoOóØå2ù« ÚLìyÉ+$xWa�’x²µ‘¼Rpû‘ grAÝú:ú�bé“ù’ŸZ°<7[¬óÎ: '£ù �üÄžûv\rò<×7Þ�ïj^Lÿã4Õ«F†m✙l ü‰&a“ DëZC¶¥é£'Jt•4Cb>fVˆ”Œ|i.!±qܬˆ¾”Ò“yˆ½Š`Y�%wiˆ´‡„\&* îús>¿ÞfÊRš–Ц4Ö§I¯L1Ò)Î�ÝNúð~f.Þ§† I/%4ÉBJƒémQ²ï&‘ý˜¼ u%#$£F�õéU®4»lÌ®°¾ý½mÓ—´.1Ì6BոȨ1ÂÒ1Ó[«¨�žokb‹ÃÞ¾²:(Ó—dÁ�)Ûñcü�ïïñ-/Q*{)¿û�ׇ߸³¤y¹<kÝ×H(Ÿ™�yRbý,ŽäTDERí�ÜaûK‰²iÂyuë‰?øÓä'¸wÍçw¾-æfXb‹@®²0™â ÈOì+í~Žb ¦[e*–#ò¦sþ½ofzÇÅä½sTGGÀ0�¸q[§c¤�˜N ®ëvÔ(u$ëÔ0S«‹Ò‘HÐHŒ11ç !¢I̬+0«›´‚SJ�bD�ÎbôQ˜Æð5é¿‹˜Ýr‘Ë —¢!Ã�Ä<΄¬½I1[âȼƒd#¬î£ù¹ì½7GÛht·áW¶!Ý6²6�®N6›X•‚&$Áht¶uwr³Û‹p"4ÑÏJ6[ʨ1b£]PL¯²Þ¼ÄúÎ3lì¼HÿÆé7tý¢¡Le$›�˜DHS\2B£b¦Îš$.6JñaÆ2ˆPK°„qR»AR*š�œÑRß…8[¤¨«(Ášêd8¥Î�P¯àÔÁ"JH \V9:µ¤KÕýOâñ'š^ý®x�a@û-þØŠì�0ÚI% Ž�©³m4VVö•_àû¾sÈ‘—§ =ÛÄv†’˜’È0 ¢C§Öœ(£Y”º„ØÉ5ª‡à‰ÇmD^îà…}”Øe\9ðñm?ý ù ËAÞÿ¶˜[-w&[Š$b&uGÒÄ& ?±/Gy³ŽÈò ñ5òeAŽÿé¿¿§ý²ÇÒwÍÀ6ÖÍ!hÿ°ñ©–²1ð©9uŒˆmqöãâuñ“a×8Ø ]/| ¼ús¼Þë0pOè·¶ZÐ�¨O¢%#b2ºz¥((€"XHØ{&}¼xø•Óœ3OsÐ lg®ïH+E¶—\jllzxàF¦9@ëÂ^f;ÀÜê ;†M\‘ ES£Œ™*+¬LaìÁì¥(uŽHJL*Ýœ]ãò\�Aë2—§â⮋ f6¥]F­M 3ƒRg¦¨è#‰º*bU3¸F…:uháb—vÑJªª§–â\·Y�%(í¾Ó¡S«<‚Wœ!°D#:µ«õÞÍãDѯzCŒ`«#ÎfɨtÁS‰#°XªÊJRtú|`ù~6z@¿åÍÓ¬„Ûxä‹Þ!#Å’I£—X,Ëg,Y?9®}v˜·:=|}gꈨ¦ž¤P�»­Â¹°öÿ³÷îឥU}çg½ïÞûw;·º_ºúÞ M Ò�€±C÷qÐ&&>T�ÑQ¢I Š$&^Ü}ÔIÔd˜$880‚ N4u¢£“ êxé¢tÓØPÕÐ]]]U]×sê\×½÷û®5ìß©êÉЂv[>íOòŽ)ì;{IpUð(qx=üYâX+íêÍ{Ö§ÏN‚.¨ÛzŒ¢1˜C$»ÜZ.)5ú Ií HðÈ –Xo|Ô¯âš1ýÔNn¹¼�™Í9Z²+3èÚ2lR®·X]é�lLÓêuhlLÓ([¤±Î6¦V:ì_ê8e¿¯gšT”Ùˆ¾±ÙP†Í Öf7´»þk\7zwù¦wx\zF7çú^÷&d u+[8†•úBŠh‚³a#zUÐhдn~sš2 jêpæ‘4@üü5zŸ4�ʈFfi^’�Ô¶¹ËýÌáÒðäg=þøu\:}£ûèE\,Cð‚™ÖÓ“‡ðù•º%‰«Pœ'/Â䎀I�h§aT¦á‡¾æ5¼ïÜïX‹;¿MéuðÝ–i ޤHØSvl&8fàÉ›Q>âz\ÐxüoñmUe”ŽªÁ´QÉ©ðä×�G¦†héTD±l\IÒ¡Ó UšàUHqbT4žJdD¿ F@ŠZ™Ñ*!-ƒn’ć9|h“mÓ·êÇŽ_ï>Ñ�£�ÜÎþó9zç´fñÚJð®lSe·¥‹?yŸOœ kF'#ðždXºF쎀ȦS¹¤Ž…ÿZñ‹oü  H²Ýnºé<.´*†)R:Ó~½u‰µdˆf .t3 L2Íœ¿tëå[Ï¿�—ÔY›¨TV¦�2ë³ñâßçCsëº1ˆ„íšúH…sˆ~‰E˜è-Ò §¹qÿy^Ú.\Ëa›VÙjkĨ±­IYŒY2pí_ªÚ´¢=rn@ÌH¤paò>�0òf>zqeXº[ îDz8–$Æ+ææ3Êý–ü o ·yQ0©å;'§;“ ?ÁÄ=FrlÁ”ƒG,'çƒâ¿f‘ÆÝ4~j–âÊ? ŽM±âøä¬�ç @1C%Žg§üSBij},Ü0{jkŸ³keŒq·àÕwS7¤ fX¨{ëà) ƒn, ãžf¨cÁO·ÌõZ:帨0F��RŸ"2ÜŽ5B[�l�õë—?r3L‡�lv˜-Íæ Q§HBÄ|H¥SF³–ÊÙ�—]ØÛY%FÑÑ‘•ŽÌGÂŽsô7Ú©œ+ƉÌ4¾„Ý¿÷�¼¡Ó£ÛZg�!½íCF�³¬v.±¹o‰~¶™† ª8›�ø~¥Ÿs.xÕ­™bo{ÝœíFNžû~äŽé)I¼Œûÿ`�;_tGYÌš¥�e­úD¥Ä—ˆsHA0’ÚÀV�9LkJDuàb½º.Ái†¸c\Yœ€NÎõŸ…(}­Z×P‘Ê×*Ò*Xh“6»>n˜Þ°—F1ÙpÈ%ÕQaÓ?õ?¾ûïüÞònÛvº:Àˆ‘OŽv&A~‚ÿ&މE;,nalr#÷ßã>x×9·‡S?>GùÖ€÷!ë.”·(ŸÜ.œ/ 5u�ŠzD&Í_V8 )QGæÅ*³Òªf�õlÀFúDr¶>Q$ÅÅ«ìÛ1r•5¶û¢+_v\Ol\áÖ���ªAV5HÒEZ||ú=›IIþl{|�én#™íîûH�e‡È!tß ¸å·ø¸aL;|f ÝsàϽœÝ¾Y¤/|ˆ»×‘� „Þ]ßÚÌîûpƒtß~d3C|£LÓ€M¢u ³d~àj NFhÄ™–˜¡Ä&Î¥øuÒ� #k4Ëċʨ"�؉ƒ€5ë³ÔlìuÿÿŸèMð•Dcì;Z9³j|¤—©“Ù®ÅUâ� /‹b²iÎÖ"qþýlÞý·\|wÄQ›8M‚üÏ÷ã—±üècéñ#·‡£o=æöÁÏà8`ɺ‹2Pª5ùdLJ'KÃâøÜÚÁØ…vrÿ*}]E 3)œ¦‰:k*"š`•†úlLZï *2ýØðøìc·”¤j’Å6Í*¥©¯¯`µ$-Š%CdßE*m†d� ƒ´¾Ï#GÜ÷iÎö”Ør�¨‰‘lˆ®»-øO~ßPM3{åÏX½…;Ò’G{ÿá'퉻ÃãíßÞcóÑGÙ5{‰Q£KU(⧃K7 ÝAMÍ\5R­p–‚x”ˆš•¨ŽˆJæJ·I„’ØÅš8“ )HT¨-ƒÓ%{ö“žw�èxÿÈðâ@F>Ú &{‚ _c†ß»ŒÅeü¿ûƒ›Âüû±²NÈŽÔ~Ûµ�ÜDÅnä'øba÷19zŽ<9Ì�?±ø�·!obÖ#•U¸Þq|Fõ4Ñ¡¨ Ž­­'WñË�˜à4”jµÌ«¨*ªX ( ">õÚ�Z1 $s8S¬O“^RY}rP5`è�n^ýÝÔyFí'`Y…:ŹuÇG�£5JiÏTéi„i¦¶�&Ñ#Þ§•++©†©¢)Ó£G_Ýú´û‘ßÎË´ÜÿŽw¾kŽ6¯äFÕ•HQ ´J*¿ÁJ³K·Ù£7µJ¿µ^ögWu®0J.ÓŸ¹ÀhÇ Ñ3�V`Þ!!ZB‚ŒœÒ,3+QKnõŠcøEŒNáW•€Çá0b¦Bž€½Â”´¶Aʪ÷÷î óïÀjƒ…Ìd±‰èñ$ÈOðŒ°h‹ ‡ì±·åéæ;ùÖ펱¬kªTá&M�Oûê1/*Î<•ãjK¶Cên­ gú²Ccm©íÆçâS¬A*„¨YН|a멆a$šbS¨ó #§V+Ý�ª³kä6\Õž0ÓZÌÆ¯°¶m¹±æI¤O_³)Ré�XB—è螺,S*èà]Ú)’nEìý!çXúþƒ~ô5I`Ëû²—=¨Ýr/ÓK-ŠÁ,ͬíiõ�ÄšÜØÛ�Ø>‡sÍ!b¨ �ÒOŒ"­(’�²;»ÄæÔ*ƒ¹O±4{žÁÌ“ u“*Z¯�W)Ñà ×Áû¨ÆhÂöžu„"b~k zUvõÍ݅ĬoŽ'EcaéïÞBõÿû`>Êæ%¯Û`ç­n—™tÑO‚ü_è Ë�IncÑGrDrÌŽ¼ç.Çuó�|ëNá—L]kÓ)fº×äÑmT�ŽÀÔ0ï¢ µ¹“z0›°ø¿*8É 5‹Á‰J‘V.VD ˜«Ð,Å›ƒ*`¦ ŠZp*ƒ²Š±+˜StlœCpvµ?p¬k­aI5Ò Jpˆï\� Le£+£©~2[!XL*Iû�ØìWÕþçõ^�–RÚ öù¾ê·Ê;™3Ní¸È“Cgoaêì ²¼�© ˜¹<ÃÌú�6±^ú-’AÊt̘V‡• „]°²I„˜üwDIP3*W0hvÙLtÛ—Ym^¡?s�^û2ƒö:åÔ*ÕìeÊÝžLF”Ú£Òa§tŒß§±Ä1ªSŸ¶¶\J&]F ªÎÄs­=3©šhª™T¨© ˜C´�l]k­ÐX¢– .Å%&·f¢-õ� 3½êoÀsJÏW±­¦\ -\6tq¨²s`þUÍúÀ2Xß’?¼ãï ÞtèmÄâ¢(Ì#†«�+�z“zvg²CL‚üŸƒœŽâLP¹Ëð¹óû§í1¿øÍ>ú_Pb»¶©¢;àÑbŸ¹š¨{‡0Ö–žœÁe6I5Ce¬?–þdHô\ŠÕµò¥êA>Å|Q3ø§—>%k©{ù¬"PÕgÞu}=A:¡OY¡½‚¢ípQFaTà ñeîû£ä{�àW»÷ñçm¹È¥Â8[EbC�íËÆËÃÖµAÒí0»²Ÿ}+ÒÍišÝ)ÒÍn詪ŒÕ+8·‹æå]´{Òái’h4"L ²‡¦ic7>zÔ £ô%CQF.2LFýA6èg—Øœ;Ãzç$kû?CoÏ“Írˆ³À(&˜ [æÖ[C_eCI{`}âÔ°cMLj #Jó˜¨+­ W®ü^ÁúN=‰DÄ„H†ŠW¢ÇЩ¥ |Ë©+ûpãH¥Œ…¤ž[œÂ×U[}ðVgKV:µTÓ=k¢¯v³šaËØìÜþî¡÷²Æ{Ssá꼉“#–I�Ÿà `^Ì {O’‹ÅÄä~qÇ_Ë7§1yo”°mhb¢¶×ÜãûD)…`Ñ(1Á9›œc>ßÐòøaH‚hI;Á— �Ç‹¯ßs’òÚ’¯Ù©R¸}öÙêyï£wó‘—V”�e1±¤v‘zŸ÷b˜bœÝdun••2œ>q$eB2JH3jA�*A*�þ,ÙÅÌž¸™[Πµ´ÍÜf íÎb1Ã=Ò’aÊ,MÙI†Ðv°#Ú•ëQùZJKâبh L-Q„OÓ\Üx¡K2÷$ÝÎ&Åö+ºý*ëÚÄ´Lh’Š'§ÐÏJ¤�Ë lT7jǩ˴ÖA®m �JS<ÞÒlàŠ í…$*uÄs¼««c§çF �ˆ…±²Qª^b4•èݳ)Õ«²�C–½Ló÷gÿÆèÜû÷/sø¨˜ˆMØú$ÈOð̉aÍè%�ó÷‹“wµO¾óÈßlFÞcv–°N´]Ž3»£}ºpu€ÀãÄTÍdãŸo("J$Åùjúz’×Ýpœïüï+wpõ챓ñ‡ø…îIŽmúд¢ª,�ÐÀ9OåâÓŽuD$zÅá%)£ŽK •Çl/) ¯@¤´(A£ƒ=~xÃR¬�¤*›´Õ‘øn‡fwšÆFB·—±reÍõÖ^�&]›‹Í�ZKÓ47›$ƒ‰yœóø�‡Á^L÷I¼’ÙëIP„Ъ%#úÙ�ÍÆˆ�N�ÞÔjèÎ,‡�vw8Úq’Í© çN1˜ Ó®MðÓ ]ÈpÁŒiÀl¨êÆ.€ 1Oíúç]!ÞÕ}¬hD-{ŽäÐ xÃ’ÚtF†i´¬‡í\söJ”¬2Ç ØŠèÎí}ïßøz.qøèx¯ªOß'çï“ ?Á3ªŸ&"wYî÷=Ç�¼®Aö$TÛûf6 ÈN8;y Âi=Wë¸%ˆÅ®V'xÞ z¤TVX6Õͺ½íáIÞðòŠ¿ÖA3<Î[xÏ£¯•?\“àEd$f‚J`d>ºÄ¼\Õ¢�O_?H /u2‰‰ü@%bÎ!NpD#Ñ’‘ÛG~t%$A¢Çíòˆz’d@5;"D*ŠX`V4pƒYÒ“×qãÊ^v ¦H×ÚØ•9Üê,~i®´Íon#D•'Ñ„ÙAÊ\¯Í~›Ø#p»™7ÓÔ¨0ú)”Id””Ýnë +3—Xßuš+»ÎÐÝù›�Uª"C²šIÌu ”N›$’áÜHí)Z¡æ�JËáZWês£sÜ��– ¬½t³è͘Ýî•NµY‰ÉŠyVÔßÁ›¾í —,7d¾>¬]g1&l~ä'xfd~ãÁcb¯~¯Èpÿ!£œ�°*�mŽ3{”±ÔH*�¢1©G²‚š™[“N®ãó ¾pÒÂ9Ãú½´|„×íØàîë tNñü§ó‡¹ÿœóø¼FS1I-C¥ÄEìéF[îÃBe¨GÔj;p/ÞÔ¢æÍÑp)»E\³@p¤U¥bÒó}I¢�Ñp-‚ù2XºÄèÎ%>¦8;hÑiѤU9Òtƒ¸y…Ý·©ÿt÷º8zr?�S×Ñ>½‹ôÔö¯í°Æ1ȰQ†ŒÒàÙ6, jÇ~¼Ü€ÙÝDç1ï‰iÉ(Û`µ±ÎJ{�ÕÙ‹¬m» ›S]µ”8·N˜Z¦èœcÔÜHbTµ~¢–>GÖŒÖ�¹â¢§Ä´]2·yeíôÄ䊉^$<üñ—Ú›~î…G—8zØ! fä&b�#ä“Çoä'ø »¹Ô3'ä’““?x—ÏyCüø½Ó¯Ìè-6ÑÙ�À Á¦MÎìÅÂ\T_‘‚DAœ� ²Åà'þ¹ 7GV¬St:dE¿Q%IáÄ#ÒÖ¤ìQµÂ�ä£|Û-ù®o,�o¶õTø{üÖùoçýŸ‰bÑ…†ó”XbN"&DD,#ásHª`x‡m�òɵs/J4³hHãµ u�»>~JA„(N0%¨QaZR(bââ"$d®Ù£œëQ)Žˆ[�H™]ñ쮲(×­RXfí?.«)™ßèkw±uŠæ•YZ+Ó4ºMdc;,o6©ÎÏ’>¹�æÊ©MÓ.«7ôL÷SÙÆnuû ÷2Ä<ø@$0l¬7"ôdÐÜëíuÖ§WéÏ\dãÖO³Þ:I·1 v W¤@�&¥³PkˆÏðÁC³Ÿ¨§!ݤ¯•b‰:¬£Þ)$tÜÑŸàRœ�À$Qi8Ü,UH]ݬSÖÂgæÊZ*¸Èp’"I�ùP_P,´pí¡³!ÞÔq±gIÒmÅaÖkl–rg7ÝK"Ýàì2�‡–^1üÛ?ûñßøG8 *f ¹�ËôqÞ�I�Ÿù þ"º.ØÑ£¹ãh.GÄt,Å.9y|¨ýà��AãhÛÛVM¬��»]ìá ÄàW+º+×¶Õ žéútÔY?„&… @³¢!­" ØÛú8?ø†ß°ßh’éeý^~ã3oæ·/Ä)K’^›„@ FðZ»ÖA>Pª òÔðþ4Ö÷¹,°–ì­g£ù Ú¯ž²*ëŸÕkS&W§0�ZºW"•] VO­R˜—$˜5ƒjc<)0Ehô“õ›ú¬_O°�à5ÅGG2t¤í!½$H°Ì\Ù¡=‚=v#3ïç…ÐYÚi¬MÃf4±"ÁÒKH»)» ‰´ñqµë$âDÁB’˜ŠC³@¯½ÁJg…µÙu6·/éæÌ6š—èuÖ):·Š™ ��à\JÃ)ÚTTVPêVå-)kg¦Iœ©T` ×G $Vn�n¦õ G0Pš i™@é¬"ØÖ(fâ�µû`A47Þ3|A´ÂÅBzí¢äëÁ¶­K´~„óðxsçð;ÞúqνÕ rÔĸæ"7Ö¥™”ê'A~‚/ˆ#'̘�Ïs1™7Érû¯9·%ƒä=ÓRì˜cE”Yóo"<¡TC}ôõÎ89{Þ¡¤«­I©h¿Jb3‰˜=ÎîÖ'øÇsÀëö‚Ðæ²|7øÌ÷òëOZc�4{YP"QJ‹/ÄZgW·œbp|zD‚™GI"êê‚C˜ƒ"DÑhÄÚëŒê¡9ìå=«^ðÇ5£]¦dUBkТµšáÊŒAÒaår wyŽÆò é…m47g™ZŸ³™ÍŽ5Ö¦H«UÂ0=h±ùzŒ[¨‡ðMEcHÏ)ƒFAoz Ý© ºÍ•ázkuØÝy–Þö3tw†þܰEEeµÊ)e \)J)֬꺉Cq€×Avãÿ IDAT†“€ZJ%íD}‘°BûAc]yÑ«Ú ¥bY€jì¥àbÝNY�µ°ÖÈÜ+ ¶ Dé\¤qzêºâ»^wž“ä6n¬›Ÿ<|“ ?Á3�aB¾€äóá5÷¿Å³ ú�ÿŠÛ¶ã޶ /¬cÖ4Y½! Ÿ¨Œ¢¦;îš{º<Å•m‚çɺ�õHpÀ48ZøjX†5îÙ7âw‘8—†3úF~kíM¼÷t£Î b�¨ˆóx �v-À lÙÐ'¥¶‡ÿª+ yD¶‚–CÐàl$¥z Ã9‰ˆá¡™>FljƒM�¬«¡!ÁYŠó&0bBâQ"¦Ã.N“}ú:n¸4îbšÆz×›!=·½4ƒ­Ï2ØhãÊŒtÔ ��§3v“:YšqÆ~ UÁ ¥O¨¼Q4‡ÃA{ƒµ©Vç.²¶ëkÛN³Ù^£È†„ÆKK5 bYêIpY�Ry*!±ê$ ¢ãµB@=‰ J™©D‚à0ixët�¯‹j»"^z&œGδÓâXû_ù„ÁÈAÌ\¾ –ËDªvä'ø¢!WË™9ˋ؉Ÿc�é¯ÌQ½´ë�u a¶¶ßä£ê( ã-Ø©0‘¨}^?¦�HI%M+ßÎpßöÏòÿºbI;,Ûù/½àWn{D¢ÇˆdˆøfH)�25oS^11Ö"‚ÃÉWcÓ¸‰ëèn•»vjà=ÞÔ¬$‚G\ŒfA4–ÉØòÆ "f–�PoP æARœ<“éÂSåèUkñd¯ÉéàI‡-ƒ):Á“É»q•‹É€Ñ¥9üé}4Î]ÏÔ…Ý´ŸØÇìò¬îín׬ׄ~† 2ÒaF£".q=/޹JÙ�¹ƒ¤˜ÑUŒÚºéW:}6·¯±ÙYbcj�A³Fí‹ôgN3˜;“Œæèø}"J°‚Ä *I luê˜b³6Ò\7îr*»K1Y#rÑÒåARýÝ_¯Ž~âè‘&vÌo]¤ùyÜü<6)ÏO‚üψ“‰A.»ÞšïŠùO»¯XØP´Aºy ÕŸ˜³‘¯íd,#µ%ÀUkœ»‰£ãó žTÒ¹�U›U¹ZeÕ ¾çŽ ¼éîR¶Í&¶Ì·ðËg߯�î$ëE ‰c÷vÕ¨Yµ¹ƒ(jb5)|4÷Õ¨Sfbã3}\¬»Á,ZFbëqk޵ö‚¥V²›0ùç“w)ÔiBCZéлªa*]æöìÞqß’{Á͢뼊ößÎ/ÿùN­gxWá¬ÊJi”Juõu¸š$I…\/ÈA´�;°•ˆYϽO˜üWb³Mjª§H�ùÕè_ïB¨M«pWµ0©{)ê^«Åƒ¢i‹tÐ$+2Ru¤eF'6ho?KgGÁþ®Ã�¢Ø‡¯·øöŸ#®vH¶ŽÿÄ�³@Äy‡„P9«]‹HŒ5!’ÒÇ»õd¨cÆEk$OPÈ“Lë³r‘–w ûodóá{ï)Þ|ìïÈ ‡9Ì Nر§³ëgU¦Þ•bJÝ— &µ8ìzшó£÷.qßËK¿Ýù¸awòGW~–ó‰Y®h±àK'ÁItД~6°VYoôuø°±ªœZ F¨õè-GˆŸÛ“6Á_!´ðÁÅk×\@R"êÕ‡“Ú-O°«I¿ F™Dïƒ#  †B©è¬‰«ÄP‡HLïðèm¥EÖP½(¦0YûÍËîÔ�ÃÍßÃ)bžcÜ£>¾ Ám¾:¶´É¾Þ 72kבÙuVù[Åâ~ v[`/ é˜sÁiÝ\b¨ÑoÞvº;L¸ÕzÁc$éX´Ðd–Îì²ßÃ9ûÑgôg8Ÿ¬ç]›åÔ¸2Ýï“|8ϼ“ÑZÍ11Ü#p 8ì`±²kóÉvM�që2/µÚ¾ŽÖùÓ–�žaÈÓnH]n‘$¿ú½5×�ˆœ€«†‰ðì�B˜0ù/Ç5´ÜÛB® ó[Þðb‡9ì_»o±q÷Åæ¿m2úu$›êlˆ7c:åY õãsÑ¯Ô ü„É?;˜¼‘àÁ;@‹$*�¤�j:#ãÛ_ºÄwߨ.ÆÐ^ɱÑOòž�ì—φÚd8¥ü¢ÿžŠÑ°š�•¨e8©ˆölÝž?Lþ$ 5»·ç@‰b6ÎÌã�J$­˜¼ÈÄüت¹ø°Ów厯]wɇùçÿâ_�ñLù¶Çh¬_&»"´Ø“íæÝϺírÍxƒô¹)6¸ži{‰L‰áM¨O¬žoê9G“Z½Hdìhg(!•ZíKÝ�Òz`fmI:,›¸Ë´ÓUŠpœQr).ÒàIþþ�áM’ØvÄ[¸E 8¹7á¡KÆâbÌÕ¢>9p˜ÃRæC6?žv’|ká/`y^‡zL`Q�#z-E+ú"†™˜È˜~�Æž$ÏâÆÁ “ÿR‰<ÆÂ‚¨Ìç°0Ïkîχr=ð‹yö —x{‡ê{*G²®èÈiy“òàœ°\æp˜›T¦žŸ™¡’4ð½Í¬h&¥sÁY(¶4Ú·§%÷ÝR¹ý>ÑwñÑòyÿ#×eŸEÁÅÒbF�-³˜ÏýÝc‘›§}] ‹:•Eœðù�`Ùàf›²›dŠÛÃ(î5Ivm†hs8:–¨Ç!8WÇÊÒj:¬±é„–�éöÙ �˜Ç—³R|¬,¡ sCÞy©{:³åÓƒ³'?¥ži>Ài<çG7r¥ù“lü/Ót»ó ápX\XÔC9䇓/Ö�ùðqdÛ�áäàQE›�-pbœÔ“õ™‰pü¡Zµ?n¥†É¸£p«Ò0 òÏÉÍÚŽÔÇh óBº>ú{ycÇ9÷öû§Fô}M1B¸Ýì¡–p¡”zFVêI¹‰MìóYª~¸éŠ $ 5×.H¬¢íÿ”ŸyÝ^r³×M;ÄGËÄ/|æ ?q%”“ÌÅË(‹âË¿xC>ÿsñ$"8Ôl<¤Í$À•бIPí>)¦XeAœnÉ,¾päñƒ(\2«OíW²â}Ý4Õ¤ÃU6î~ÿ¢‘ç"óóu 1ÿ1/,LM¤ `c!GæçyB„�Œ—¡À=²ï�cY£ËÌ• ¶‡Ýì«6¹ÁºìÅë^ \o#9@S¶YKvEѶ€ÃãkG‰à�F2LZNuVœîWÏ&|CY(¥!ÕhÝÖËˬÊã\´Îoœâ›’¥üˆ\¦yäqÞÎ Ó¬,αΛ¼mñmòÞe9GDì°pì�À=À1XÆX#Çav�E$?"ä9äùSÏž½EñI¹þKôÄŽþÞô±ÒÍwº·ïÂýhIHzCsaòÐ,ñ ÆçrÞ@ÆRµ_É ?)×éør”ë Š’%ê2�»P$Õãyñe¾óå=î6¹�­ÿ+~þ‘Û9ßú* NBÛ2‚Œ(õ =¾Oeòuw½C-Š‘ÔÅJ `^"ñY)ˆ3)×>”š^ú-�¬—� AnT8(�tÁ.@|ÜÙþ¥¶~im÷ÐZK»mI–~Švö€õ‹öLÎ�Ͷ‚5,Ç~Š`Ð �ç˜ÙØ¥.Ï� ,rÿ äC ó¹ÙÈqå'äøáÜ�Þ–p±ïY¾8ÅÛö0¬vÐngh·�ÉÍ´ãõ 9€w{qÒkâH1Ԕĥ&ªê´î[0q§8øq]=©-J2Ö,cÕVép™nò¸ á\sгn†Ó½“¬Ò¥ ¢â=»ÐcB9ްˆåäd^N@]Ѩþ'åúçrv p/¨�&{èýî'vã~l$Á�Ì14â¾DÞü™ÊÕ#+q’ZMà‚x‡XHíJ�êoºó2o¼»â6�t¹Ý콓Ÿy`OûY‰hð‚h$˜÷e⣗/4þ¦¨]S�óÎpÓ T&83ªÄÛå2ƉeñWÓ’3Oˆ¨ L\àú ^ä1ß;�èìÿSƒ÷u‡„átww“d C�bÏLþH¶˜êXÞÖÆõé«­ÿ"WåçÇ´±N r[X€ã‘{6N"¯'ÿL8b‡ÈeñPN.ó¹TûøÉµÕãùQ[ÌOó¹!8¸ÓÝÆnwòÿz¤E6šcic­áu̹P%7ˆV{l”°BvEÓ22Ö¼F1¢Õ¢Ç¢H#“�µ1ö!µ¨$YLÔ‰*"˜fÄlr…ÒŸCåü1Â)î §ü·°ÿ]z9oçkÓƒ¼Û…Á›/P퇘3 òÏ‘ˆ¾eÁø”‡À$ãÞGK¬šÑ‘²*¢5‚óF¢’õ‰vECØàÛoÚäÓ‰ e7'Â?ãŸ\ÞÅl¼2*ªzÂR,¢_¬0˜ÖZj(AAMð1c<Ù4Á³Y„Ô¼Œ$šQß9ÁHœµ¤òÃ]…rÈc¾R¸,èI“ßøåö l¡;„ ƒ †u7xx #ÿâ™üS¦Ëä©£ò¹û¢}áßñ¹#ÿùÕ¬€­D>?ù <ÔÿÙŠ‡\{Mqü}¨Ö¡ œ� 9 rüh.‹·àö¬Äìòrô�’F5Åö0âÖ˜Ø Øã®cÃn¢ð{L˜µwâd;))"µ¯w…QrM©(ø† MÛ„H=-`jTxbº>LÅ�RòªËOR¦OPØùÅ?“'¿UÎÒw«ì]ù¹ŒõŸ-=ö¼¾äØ0æ‹»rHçù~÷¨ExôAá-w©‘ãÊÜBÇ�S÷0óõÅ]@äàQä°˜^íú_ÁI�ÿRˆ=&òÁÛ“Oó©ïk«ü´ý†‰õ0Ý ŸÚOF0sÈø¾wÓ{…ì) 4:Ñn~N"qZŒ5ÊAHÅK`Ô)¤Õ¿Î}Füågxý«ºn'�—?Æû¿[þø´Ô�u%u`ž¬�ç׿"6"𦏤ª'qbT£¢Ú•F÷Šà4ë¶Žãq“?ü±]ñç×VZå�ÉÐCU›Î>?7fr™7Žä–çØÁƒŒÈàÈIzÀ 9�åèï�à„ãKù1wâ¯Ñf™µ=¾ËÞ¸Î>¢¿�`ûA¯w ö™c'Iœ6%­§çÅÙV+8)ñˆfW%ù“¸ÇwâÆFF^ ±È%ÙD6Â2+ÿïy~6žýé6WBºxög"|d™]\Ú÷Ó¿x'ȰÃÅ£,Ôoñž×än×rn‡Æ¥”±X0¹Úû/OË•&xÆœ~äù ék_Dòk©Œv LltGbÇ÷�EP5ÔëVóÓ»—çÇ—_ÉÎúIãÝ—ŽgÒxç$ñ¸!qšÄoâ¼î¦'øG÷t¹e‡£’äˆ +�mÀaó†…qà%Š-DŠ>ˆýÀo`ßø7û}9x¤ÖAaý¤/ûK†Ay¥Nº¶Ñÿ¬M '{ØkS7[=rnž‡·#tí¶5áæ5nÕñ¬�¯oû26^ù§7×_wó{8z»ð5§„—ls¶|óäì%ã s5#s�J®Æê2[Ü€ K8í„®Ì!ýA!î¾5*º 9–$‚á Չê’üO�Š9æ9Mí�QüÙ§Ìko;–5§:KG‘N¾µæLY, xôU£$òO“¹À5ëh¯D¥Q£…—â4þ99ˆ¨`2¯M¥ƒQJ £ÝpÈÐy-3a+MÍ]x³ž!Ó-�}Å@O„{Œ¯þâšgV‘yÖïá§>ù >p6tçF®1Ô„Ÿa©°ügߘpª"ªØ©Æ†mÔ§é¹t-y«â=ÞÇN4tKŸ½$§.6%èY�Oªùëߟk~ü¶¬Ù’G2� J­�õºœä u×±­-“2v;Æ»ìÔ¿�øR•£*mØDâ&÷k‡ÛwiÛOU×^Ùz¾Önãð!¸õ詸íî—xöÍ�á•·�¼™µ;6xDnà/äÕúá}˜_¼f¥Cµ¹À½f©÷ÀÖÁ:g�¢ûeÌ5õ ×c²ëÉý�Ðh«¦uïÆ°™oŒÅ´« F`üA±ú"i–0²Âh  Œ]—îú#dGO'wýÓä÷û|ׯ@~zÉÆÔjŒl®Ð#—Uã…&Fâ5†SpF!�PšYšn`˪ 3Ø,ÐÍ`);�Q¡”F¨½âkƒz»ÕÑFcÄ}!L6ðmÔ¾´?ß«¼¼¯œ}V°÷í´}ò:uÑo—I1GŸÅ<&’#lW|¼"-…'u×gÁTž0×!•ÔM†˜Ú©ö›¬?˜ [�-æ;dï¼ùÆ;ùÆW©Ù’•ð�|/¿pü«ø£OtP ¶âsóÝȕ⮯l ²³ˆÔVÉ<Ôš“—.šÐV†j^ª&C� ï¸ùØï-Ö?øÎbé<§Ö} ²û´\QîúËÓ÷€:JvÿY–« žÕ¬p€sžë!¬Ø+ û1,áÈ¥C¶}¿žÜ‡c3¡€«VQ%$Kþi²o‰_ÛØ»ïE®ïÚ°Ï4öÙ#äÚ=4‹ r•Aæí¤BbÌ!¥!&,û6‡#ÈñäJÈ]0­«µãc\hcT›Bõ”­¬6£æèBi-•�±�&XP *±i¤ØÊÄå@Û6Ç‚€V¹7S%ów· ml NžÓ¸©~9ÚO íRÀ×&:4MâK5d“fƒZ·Æ ò‰ñw^s7_{³22ËáÁæ»ùõG_ûîÌܘºo}Jg»Òèx‘ #>ø"Æ«vÊ<äRIóê^jMÓ›½[š�ýá,?úîMΛëJ]PR¦Á¼ÌUþŽ[ð�®Á‰C•;¸Uo9 ð!::fÛ™ghV͹ò n²Ç<7�Ë>2]" ûq¦ƒ4ˆ˜q¨’È?M^ôè`míÈ»ÖÞq»pËQT¾Õüï6'®»§86sýÀÒõ#öœuž�«»a–­}öZCØg‘¹s#B× Æª�q#aD£J !¥°ÈbŒÓˆE¬â»Þ† _w ê`Ë 3Ý´è0³~Ë µSj¨c‘kÄÕm%�ØçÑn¼ê”àÓV¼ŽQ#;¹,=Éêl±&ˆ†R«Úy¥Æup”Ögy˜îùßþå/_ X¸¿ù~þÃG¿œ?<ÝÚ`0�ŒÎT”iL¯¤[»(#|ð2o±X Ô@E 3¨|‘‘¦;Ây„OÂG~o”“Yõ IDAT)¼é·íÜ™b#×rI ͆2H+îËš˜†8©n¥‚*kk2I7\{)£ÃPÂמîž÷~ÞqH¸åVž}´³q/Ýò4óƒž]´u}À�åÙ¡ÛÙŸDþérXX;|‹Àë…#Ï p¸y­Ž®YcÑ5¿çö[ÇrôÕ¿`X\”׿áÖü%§è+‹KËlìÝrÍ�•×½…èÁQ75°Ò³,ç ݦp*&Ó6-ŠbÄ«âQ3ˆM,3z¿èÔk®1?2ó‹x‹Ž�ñ,ÚéBw .ƒ2£•â›uˆå±·#BÛà­èP¯Û’R0דàéöÈÆW©©¹;¼`án¾ãk*¾x1`È8¦ß̯Üþu¼k=€(^¥²Át«l4®Ús‰+�Ü[±XQµˆdÌëȾ¤ ÌmëXýÜõ'¶yÓ»Î'úä:(ÎPlJ—¥¼Ü{Šp´Ý‰¿%v<¬ÅzH¢kªm&6¬Éóäð­·„¶ÞÕš�Ýbÿ­ëúÊúS(>r[�µScM"ÿôWâ­ÒÑ£ïXÑÛe�£ºvø�pøÖ0•â¼½ùÈëdåu„Sï üÖ;®qöÑ~èwrö†?àu/õ æ(˜k?š³2 aåzạçà0pͼp­¨½ÖÀ¾ŒÆ¨h.`lTBI[+ö}v&†ÌE‡ÂÌ9a¯ ¨UÔzB©3d”cÆY¦ˆŽrËÈ*Cu„Ø<M|KÀ �Óf�Õd#kÌÖø+®ò¼¨ï tà þ7~ý‘oæ�Ç™ªvÚCE FpÞXƒX�›[xAB†�šxlÛÿ?©bÁ ˆßÉŸŽvç:~²Î½Û/êN‚ìÓÁ[¤ã…×½þÏ`æK¿;[à|�Ï2l¨ ®GöñÁ7ÎÝÇwý£{g3ÕÊo¬oûH�Æ78õn,¹"â;jPQùg²ÌìäÚ2hLÀp Am‹ó\ª{»1ðnÒˆ*ÄIÀ°^âŒb,ÝQã^j¤Yòjä�û°�þî‚Ãs h`}²õ½êÐôK©Ÿq*SàÝå`0¶�n¦ïPÛ5ÒDT™N `;[@µíCÿ¯"Š®™6‰0±Û.�#¯Ä~õys·ÿ.VÞ;fÿ pU¯âÚ�`ß°£ÏBGaµƒÎ‚º5¾m§ëšÇŠ1Å b&nûX¨Ob‡G&Ýr}U�{ȨƒŒaS,##ÔuÓÙ²P�i¼¯V‘X;2�e~£|ª™Ôvk#ý&+$ÓžeØv‹@0QÔ­:™”}œÜéGxÙîàA,aR ˆÏVÜ+¤1*"HSãÇy”ôÏò5û …XŽó5üÞÆëùíæc1Ôùš-:!§ºà´>ƺW$ kjüd1˜þ"â /Äj%*™Å/¶Â¾¸KsÕè†c�³&y[‡¥#£fP”¤tøDù+Õ’ßî.Øš­íNôÊZ´¡€ÁEk¶v¡Éâæ¦ ô)BI£uV“e�Õl×Ätý�iJ´>YxŠ%s¢Ø`à6¼sl.•lJヌ{ʬѲΔþ’Á ¥_nè—”vñ¹Ì]uƒ;·ì‚^Õ º/'¬(¬Ôª¢ó]×U“e`�"Ü`$n U!W££`‹NEœª:„N4Ö½E+«Zæ�‘@™ Ã\uè𥃱@]#A™"úǺ!€1b¼h@…y³®ë~Š7ÜØÓw<Àk¸mó»ù…¿^`sTcÕ¯íȦŒ}׌íŬl·€M,Ž»�ŠÏ0¡j’»þ¢ˆ[I9ÆŒð!ä˜n�`^dñW•9çчqçïʪ7½µæý€¡¬µÌ2Ê•Ú.?‚?“†2‘DþJµä·÷ä‰Ut'Qg¢ªÈ¤ÿ³8Ä(bm)u�Öë±æõ%�A�QfNègB]+ PfJ]j‘•BSjY¢%…Ùè9Ú~K°ßS”'È@Õ!Yø³ïåÜÙK°2kY°†s[¡ÿàÉæyŠ}QŸ~g¤K³•[]À®Ø—ÉhµgÙ;Ó°’!{2$ŨA‰�ûh�‘4&àk• ÊvS§v@‚´£ÔVt«£T]dœ‰n¨£(m`Ó@>F1Š4¢,b=dí*~ç·Ä;‹Õ¦c>Î-Ï?Ã×¾pÃÜ°š‡‡ørÞóÀ¿æ-ÎRo–¶ÑLìPçéŒx485XCf½¢jãḚ̂Úö¬Ýñ¹·ÿ®©Üƒ'·E�¤âÅ䄺uÌKLº�ç=%‰ û½ŒSg•Æ"E’c �œWû5~¯ †Ò«Çl¼ÏT?üsð!2„2 HFIyªögú…\ÁMgIäÛÂþ„ÃS�—¢ŸVÃvÁ›é(ïö÷ºVêé›Iô–�‰ì­¡¬Ãã݇e|è>šuxp=ð`|6>Fæ�8w?¬³4wåz¸Öaûè q„¹Æ]�“?kƒ……Êìýòk{Èr†ßŸI³GŒ.U°”yzŠqŠƒÆV�*¬hL3AUº¢Úµmô¹UÔÕ�#j1j d±FÀ–³:ʼle�-¡Ù uÊ <[ÒX23Ûz“çìÛà[þ>°Y8ÍËùЉïãgïX¶¥ ^È|L ð(�4*>NF·ÉăÖUT V¬�Ö­ZaÏÔŠlïæ²ýß�,û'Zíj¢«"&( •`‚`4 <¶Á`%¤¢…ÖÃÖzŒ¬�¾¦Ð ^ÖÁ﯂ᔠœ 2üÌ‘·Ï„�4hÝ~�jj-'ߥ: |"‰|â2¢Ìàþ¹®@aiÍÊ>›”þ,Pã(7düPV�?›ŽðpYÌ~„•YˬwßCÍß-»�ë0½½Åp¡‡…<°w³êÔí·R­vŒ_)<ód4—¶<”¶©y#&•Œ¬·V±6� 2'^Õ Ôªm¬Peè¨+åð ÇÝȆ½–?µÇ8ÀAîÞ8Ì¿ÿÄŒ;o¶š¼É]ei$†Spºc�l??&°›X`(¶˜žèwôF„6pÎ<&?à3ùØÅK›/ê1Ò'Ü]áDÏ—JÈS�Œ NhGØ€¼„t÷œ<Ⱦ e]烾¿Þò³£Þ{MI¤¦N‚žH"Ÿ¸¼ÉêZ—6jmê‘Ö8jà µR YVKVN ™Ö@֬㎯o·ä½­•dÅö®S¨àÉFëáÚa%‹M!âÕv4»ÏêÌu K³Á]µ,Íþ\uµÀî·„UƒÎè५ˆ•‰›¿F¶{+JÇbçž ^¥„y~RÆä~Ž­N&/w�©Õ–4ŒU´Ì¼-!ŒZ+ÚXAƒ—íÈ·0IŽˆÂÜŠ‚âÛØ�øßÖ(ˆ¡ñV¯Oï1Ka«*�3†p‹J£¢FrÄ4’-ÿ ;ÔÚ Û¯,¨Å¸Jo Â�ªÈ&†Ó*õß8ÿïj”½«GÉÞrNN°ž¦$‘D>qùS'Š«¡¬•,ŠÂ0(ƒkÚn}5J•¯vàè×™8u£uÙ(¬“á´Ê¥UsϪΞòKM¤fý}žõì#R‡>%Í /+ûì’Ùk;#~y],0st_Ylàj‹]$Ï¡“ƒ³ÀIÓø‡ƒáAUóS³I 1CŒÛR›[¬õ’C$WUÁ«€:¨­PÙØMthadÑÒ ã̶���­k‚¯Ûf'quáÅG§Ch“ã>­¥0­ î»b+S0¨z•¶^à’)a1ÇÞy#Þ»ë”êÆF1C”ûÐêÙú­Âÿ~)µ”ƒ"�•°è,'›”ŸH"ŸØ”ÙŽXÕµR£d})Ûç�L6÷›VøOôÝc÷û3'å  Y†de˜Û@J`�B¡Q g˜sfpv`@¿Î$+á,ø÷ù�áÎ2d±°8`T†þFÉMйº{í æúG$¼ö<¼â~¥÷�ݧ„¿g¼ÌÕœ Ô¢R¯.€Ýu1øJ:Fé `E—[«\­ ¦A-Zçâ«\wbëà4CEJÔ––0ò±b°ÖÛÂýDôIl{�Wµ* b|P‡•˜a�dþ™f²?)²d1r=8Ku(€ÝxT]x„ìWÞ²Xþ惛ÔE]Pö3³·pb£ñJO$’È'v…=ÿ¸çõÎ~d úÄ·<.©Œï¯ÛÀÀõm�+'¯?&@p𸬩ãß8Y6;ï�¿‚Õ¿‚_á‹Pzñ®=á‰Ôÿ»ê'o üÜõ˜Õë³°| 6KËÁ˜¥™3¢‹æ-ô •¬kÚšñµ´ÿÐ ȽJ–Á¬qm �CÉŒS[d(h©†N)-261Ep ZWøP ÚÄ î¸ `•I €G©¥Q×Fðë¶@Õl/t’ŽÙn_ˆ¨hÌõŽíóÚn„д¦}ڒ«2©îw)×Êÿ\˜vÇ?Fä{d2t�ºFÄ`ªJ¯›‘p¨3TÇ1Uòo)Ê·?x¶¨¡Œýफ़ˆ×wº-$’È'˜9à瀫ÛçÛ&¯õQô?c sÆ2ÜðË[Þòs�ýØn�Ñü<ÍbAXvú{s®Éƒ.ÌÕ9f1WÍ;mUþ€P#Zµ"¯¨T-Cè¡#°˜Åò¾"±ÿt°±ÞJÓÆ]eÔÃT¶~è|Ö(f¼É¸´ ™Zñ{KtÿÇ-+;„=¨7ªÎ ÎÛ¶Á‘´- ¶­nX‚ÖX5¼oã b:Ÿoëêï– d»ýã��ñ†ž„fCCGŸe�›¼Š)�G¥ñ¿ù¦yÿKÇ}拲”2%J$‘O$.:_ x²¼‚–`î¥f¯×\TÁæ[b·~DðXÎxëÿÜn4v†ÒÃY<÷[�Ú ãéâÍ u¶€ï.Àì‚aáº.ûf+ݳäuy^eÉJè£ ‡d.´©t»èQ‹‡UȃJa Äí£ x‡ø */~d#S»-C(-49¦1„Æ«!€†xˆõ 4ÚØF\Ì�(à�†öF’·­‚mƒ:o5z v¼»í"y²¾UãªAPÏõn,7y¼ÙB8Žõ÷šæ·eŽ_>wv¹¦_K†‹V|"‘D>‘¸¨|#;UgK¼±Ÿ4èÃüŠ©œzP<šcÅzO‰Wk‘Ü[üÀ?Ó5d™x_+z’AÈ-!ó4BésÎÕž‡ìpæã• �•,µó�_«Ì¬µ·ŠÎÏ®ZP髲܅U‡Îõ`f)!sQð‘v—c´ÓaÏT ’èZ¥ojpx1ÑMO†4­ R+¾Ìaä`d…±³Œµ¡ô^šm¼h˜Œ… xb Bk²# � �iÔFüïöÐñ|h½5þZUy^…ÊÀ"ëžæ>ä·~*ãÏŸÛ[C ³ÎÔõ P&K>‘D>‘¸Øö=Ù 6V¾ûë`B €·t»ÖÛ)«:<ø@îÁã©ðZlm…¸'í[Á³R{ØÊ-˜L…�ƒx»ÅŒ·X?#cðcËŒF°•VY.äÙ'¨¼æ#Ñk(í¬ÅÎfUgó3�…«ÑÕ%²½sè²Ñf¹³]èt°VQ‚zÀ!2Ž+UŒjd] Ñú§¨mDxuŽT™ÊX¥* ²eÐRБ *“¾Ô � AE'nûÝʤ-r@ø`Ÿ�x[*<¨O ¿÷‹³õ/ß�Ï5ä%€|á#µ~¼ŸAY§o["‰|"qïÕ |xéãì÷6° ¯™yÈ D½t@êÑ(tíHB…z •GK Ç ø@˜#Qú^d�A¡O >M$’È' %FÔß”L½†ÂG©Ã�ç+è( ‚nM„a*ùšnåZMðNž?Y›×6ü½ý¬jûßP=æ½Þ£Pá�rúox¯Ý3Í«\�QÕÝ,p}-šÄÇ,wþ¨·¿LîÍó*kçÁ­ØÐŸUöö¬.å°´¯vû;0ß#ì™Qö䄞ULˆ{ñR£ZI\X¬"1 Öb:F!ÖÐI¯¤`•�#¡UŽ”9ŒgÆ—Ö»QÀ�kѱ·¾ Šh@âѼí¤ãEq1p¿IAbañ�Ń‚Š7’!"i¦bú§Ê̶KÓ±[að˜Çåyò½÷¼F ¹ŒÑ`&ó²§"¼ÔÉKTOªÑcÈ»ßv•ÿ™;-*ÊRc«ØÖñm­Úô�K$‘O$."/~˜yœðO8¼“K8‘Yª˜/7Y`ØÖÌU„˜°a½Òéñ�jXYl…·C‡;Ñ„FHné�ô½u>ëb;×ãW¯6ºw1°¼Œ¬Î©\å`Þf™Íynpy‹ÐàÚ}Å£FP ¨ à ôH.ˆ ¨¥Q !W\cjõ5Ð�ñz]@Îy| :eäÀ[P‰Mƒµ¯cƒ:Û¶à‰ž¯¶Íá ±üŸ¶Å�° :½@ÂcÕÊŽ´ÇE�ù46}Ý8ßA�w•d ý^ÖížSN‰rLÍGþ�kÞzWŸìg©¹L"‰|"ñyæðV`–·ýû€_žü5ð)`ëR> O}«ÏÆON)(ÚñÈ܆ÕÓÄÛ9çib],:¤CÐÓÖW*ð[ ë�çÎhAç­RZ{s5ž½ííÃ.Ì–:èÞŒ°ØuÍÞ¬aO3×Aæä5Ñv À¨Í¡o³øŒŒ•�¹¶“à1¸ÞwBÈ”Z‘ÚbF…ê–ƒq®Œæ¼– CEkoiºS2N0â ™"×6 jÔ;d»Qaˆâ¯êCü×E·ÄgÂØÆ4™­d¾D_bÐÎY•p†ÀIí~ä×Üè‡ÈØÚXïû $Ùì‰$ò‰Äç�ç?ô§¬÷¿ÀG/—©¨ï!Ï�làÃqS½³TVç”ãEmGå´õ0D-^�ElÛ2؃ŽÛº?1tpr·Èg…¦RüP{)røóÞ3y”¢gð(ç†þ š¹,gHÏVÝÅóóžÞ²gi®auVöÀj�^•Á‚ƒ43ˆ5¢ ªã¶šÌÊ£HÇ:?§ÂŠ(Kø "r¨;^j‡ŽÛ®�Ã3tè(C·*×4ÁàMEm«íE0¨ñsƒ ŸIè�'øÀüyI�=‡è•‡‘Oü÷…Ñ�ýa΀³ý@³4¨9‘òáIä‰Ï›Àÿ°ÊÎ~ìÇ�#­À_>X+dVòÚkUyËðÚçSß4�S +`™µ�‡ÍÄF{¢íìr�ŠÃØoÞÅ96'Ôóq/¼ÆcÂxÜQßCìx¬â®@¯gîÌ}àœ÷ÖÛÚÙèàÄ2&ïaÊÖ‡oÇP@ö’ŒÅeá`ÐÅ•à÷Ø«Eÿî5pL…9+:ÛSÍ ×èÁ¨Ù.ˆ¨ˆŠÝŠÉAf'þŽ€¢yƒï`j¥¢e†-Z:Ǩ#ŒºµŒð45ê¾M|r}¶ �êK»„Ùs ë(÷·¿;ÓùÃÉ¥“t½LöúœÈž¤rc"‘D>‘¸àÜü4°<%ðŸþ%pî²<£P)a.³ö\íõó3Î †ŠÙôm4ZÇ‹Çc›öÜÇÃ0ì 4Æ>€ÅŽ;âñúÄP„F¢ŽŽ8ØØ¶M ð‹x�b;2Ž�Ḡ<¥¥ù£ÚžÀº“t­Pä‘U6¶ž¿w\ýÄßQw×µÚÌÍÁŠG—‹œ}}e_Q‡•dOŽ9�!ËŠ�Í|ÓH\ ¨wˆQ„ 8ƒw¢“mK ij ­3¨zÂ(êLY§¥�‘Ë XæÞÕ ÍÌHüKg•ÙMàŒ 'µû·¢õþZåOë…À†Pg:XÖ‹ÔY.‘D>‘¸ÈÜü °Ä޹v;ðýÀùËòŒ¼×ÖÚV2$�§”§¶jKn” 2n¢ð2Oê×<–ñt&€Ç3üŒ®æñc"ü§?crl¬�}ÿô¿¹ý[Þ+C”á0Мÿ;4p¦}€öe©ž“UjYw'éïñùrEþÜuú{é\Áï_Ôf¹‹\í�ר… ]�ÉQëP‰5 ¢q=ÆH�§Š:‡º�ÚYÓﯚ³ò:Þ‡œ&l½ rß)ü¾MìÒ1š»Žýà9ÍIšBʺԒR)¡,ñ¤ªv‰$ò‰ÄEåà'[�Ÿð7ÀÿuÙ |‹ºä²µUûªÝS·#‹o[ÅÔøÐqȰݓ¾ÌÜ€Ò x¤$ ôäùlô@Iù—Y}¾¨Ç7 õ꜅Œì䆾l¶î]_ÒÙ‹}Ïž³2ƒ¬ \Ý�=³èr—°œ!=N�† ¡õÔ+0VaDÐëëq^�ßåü¯Ž,{{ãÎ-ÿm¶ù¿ÿËùìD¿t HQô‰$ò‰Äç“«‰.úì¸èï~X¿ÜOÎçVF•ל\ªÜc©ÄgH¹Uûe`,ªsãhŸ�/¿ÓSšLJê°m7m¶y‘™Øµ°&;¹á 2xŸ)†ïóå&ýì,]wM£ý²f±FAæ²Ì:4ÙÞÝ»@¸j ®žUödHÏ¡½¡<Œ˜¹ã_ïÿ’ÏîÚ­½]ŠÅ…†‚BÊ$ô‰$ò‰ÄE¶£Q¶ü(pp[4bZÜ¿NìŽSõxlÜóÎ0ýnªü\OÈQE=–1ãËSˆj”¬/d@]jQÇ&/ýA_ë¨ù¸¬–ÚÕÒdÀ€PPH9hbõ›d™ æl4ž¦núd£'ÌÊãM�Öd4 s®¶¯ÊYºq˜Ï÷Lµ´hX<Ý”¦ã°o¯³»öRjJýB²A™ößI䉋nÆô¸·/˜ýSÄ »ã»á$-��Œðj©°Þë’Çîó½×Áðz5Phn‡xeÓ¢cy¥vY-PS:Èêö6VR6ê"pRÔ(�ŠRhj²ê¡ÀIV¢ К¸[>(`�P7ZP“Õ5dHY GÅ©ŒÞiÝsæ‚}—[QIDAT¾f´WqNhN*Y!'æ`•Òžlöú‚4±q"‘D>‘¸xÚ¼xá”èŸk-øã»å$½µâ+ÖŠf•±£™Pg[ìõÃ\‡*�ZǨÚ!Œ½Õ' »»¤)'ZO ÃÆ· ®[ ¾®•z:ì­¦¤Öò‰ª”õ¶0—í£ý eü;'ñ�uøÔ°Žž„'vþm‰Ä%‚IC�¸è¶ÿ²©cg�ïîJÓH$’È'—'3À�¿ÃN�Ý€XÉîÎÝxÂö Ö}º‰$ò‰Äîc¶ó/mŸ+1=î0ðÁ]yÆÞ«ÅJl_ÛJ×A"‘D>‘ØeäÀM <ĵ‡�÷_)ƒà ;Í׉DùDâ2f1ïˆEm^9%oÃVô?p%H;@¨Ç3„uÇ ¨lýh²ó‰$ò‰Äå‚¶ü�¯�:V·ÿÁ+abyOU âl…G7ÿ`QbçUÛЦ+&‘Øå¤ºÄn³ä¿xÍÔ±ðc\A.úD"‘H"ŸØm˜Và¿…½'Ö§ÿã4<‰DâJ½1&»á:þ'Àÿ9uM{à—€?HÓH$’È'—'|=ðíõ< ¾û%à?©Žx"‘H"ŸH\¦|ð½@Ö>WàíÀ¯]‰o-b»°t-†¼rä¦ÙªSK­ƒZ/E'}÷‰+�´'Ÿ¸œ¹øî©ëx"ð?E[ð5šcÅâÁ{-æù'ì·ÌÀÕÅÔ6éâI$’%ŸH\º|=ð=S€ßþÕ,ðÞ£¹Ïñd“r¶º ˜«0KßÔrÎ¥ùD"‰|"qé!À«‰.z;%ð¿Õ ü¯\^}ne=bTÔ¡rˆ*B`Œ¦,ùD"‰|"q©ñjà‡�ÎÔ±ßk>9¡'«œÇ}³sœéøÇ¢·—z¡ÛkÚ³H­[‰$ò‰+„/~€Ø:vZà2 |ÄÚ¶FÀ¨¹‡ÜCðh…¨o³ƒ1ÃŽÇ÷:—ê÷ÿ¹À7|2Íj"‘D>±ûy>ðSÀÜÔ±Û€ª4<­o-yî y%U–‹É+1)ñ>Óí¿š�{ØñX·—7¯>EôÎÔiV‰$ò‰ÝͳZk}~êØG�7% þI„Þ£T(#¨"œ³„3è} vl�† cõ½ž‰Mj.ëܼ%-Þ‰$ò‰ÝÏõÀÏKSÇ> ük`+ Ï“‹|A»çn­œó„»­¾Ó#÷  :‡—ÞÆ%•…ðÄŠ…oNs›H$‘Oì~ž ü4°ÊNÖ�Äžðƒ41MΣèÓÜ&ˆÔ &q©0 üpí”Uÿð/’|T^'ygUX×ϰÏßä8ªUEÕ©8üÅ_ôà»yàÛ€8œ$M\"‘,ùÄîeŽ˜6õâ©c§�IL©J;r¬`­˜¬µŽ=šY” ¨ ¢%zöb~ÿg�o®"U~*ÍV"‘D>±»é?|ÉÔ± bý‡Óð|öTTj©¨=š“ x‚G-"ª¨bèZì�Fñ­¬m|'1]î­Àߤ™J$’È'v7ÝÖ‚ÍÔ±QkÁ, ÏçŽ|˜Ä5x|�*ªmµ; ˆÅÑ_” œ.1Èîj¢‹þãi†‰‹G ¼K|¾þ0ðÊ©cCàG�÷¥áyš"ïsÀoÞžñV�Hð6h<ö½õ€Nì=ðSÀ_¥ÙI$’%ŸØÝäÄ~ðÓ¿ÙZõ‘†çéã±à½b¬ezÎTHT„Ž• Ø Æ_ß üÏL3“H$‘Oì~�ÿ^àÕ�ø7–†ç™¡¢j…Û¹œƒð@Öügà~ßÖ®_h¼,Œ{ÊŠ·À­Àÿð�4+‰DùÄîÆß|Ãcô(îÓ&�ÆäÕ ]kº9f’?ð„¿Zž« [ØæÜ\~!D^Ú9þàmÀûÓ¤$I仟ÿøGSÏb½òÿ‘†æ¦®tÊj7Ë}E�² J­EPÎ ñ 7ŸéÚõ|5q+æ?”&#‘H"ŸØýüSb”iÞüašgïÕz´¨,œ5–X'h«ÊÈÍdÞ¹g<àδÿ5À¯ïN“‘H$‘Oì~þ1±ŠmŸ+ðŸ€ßOCs�t‹­rJÐÊBÕÍeŒŒñ!o€g.èζÿUÀ;�ÿ–f!‘H"ŸØÝL\·ß3%ðøUà—™ôAM<óäVJ¼Z€™ÌæÖËŒ­L#• èyKç™IŸ“VÜ¿øÿ€·§¹M$.Rž|âB üW?dSüï$�¿ðXïñ€§R°,+æy[îÅ=Ó,(ˆSaŒcÜÇF¯Oož_ |ð'Ià‰dÉ'® �ÿ*biÚ|êøïÛÈú4DXä'?­¶*ß °û ²_r¬)ikŸ®%ÿJàâþû/uýD"‰|b÷Š;À—·|gêØ;�KŒ¨O\P…·Ry«Ø\L†É™o�ÆF^¼Ú±×�%ÁgÍó�ü1ð Ià‰$ò‰Ý�7?΂WàhkÁ7€¦aºøxûŒä ˆÙÐZð>Ím"‘D>qéXÛâs¿ŒXš¶˜:þûÀÏ& þâ’³ã†æõ�çßJìø+Ss+iä‰$ò‰ÝÉs€"6ž™XðBl+šþ¢ší±ÊÝägÅ3ñbÙ�¥Å["‘D>qi¢@˜!ºÕŸî5p±ÃXêØ»�7ñtc·ÏATžvÔû�Dý#Äí—4·‰Äe@J¡»ò¸‡Øìf`8 œÎ§ÚçÇ€³Äö¯Ÿ‰ëZ�_™:vðÓÄÞð‰Ï“5uMðTœ¯i>hùõ/mÜw õAƒðxoõ)ÚùϾ£½NÞ’>‘H"Ÿ¸tùbëÏÀõíÏýíãÀ;‘ñ›ÀíàŸloò§ÛÅ@üØãþÀ¿Î·C Èú¼ÛÈzJ�~t&˜F7·ËÚZžj›Ùë€ïjçÿ0H#›H$‘O\ºÔÀ'ÛÇm­K+Èy{M,ݳ+À5ÀÕíãùÀb»˜o´ÿM ÆznëØÖ“ÕwYs°µà׉̈́’À'Iä—0úŽ{ lŸo÷O½>‰œîÿ ð»Ä »ÉçÝ ÜÛ ü‹‰ûý®úA+'�ãíÏõÖ;°Ù.>—.I^‚ Ê5ÀëÛ9|c;o‰D"‰|b³�Ø#|Ï”À~ø‡í¢ Ìƒðö·ö·®!Fg/´‹ß ȨýÛÁqbp× ]tTíã©.XOŸàŸµóóæ$ð‰DùÄîçð¢ŸÇ ü}­e=ngÚcÓ‚<ñÌ´Ÿ5ßþ|q[àZà Úc“ërHÜß?CŒx´œsÄX�Mb­ôTŒåŠÌSIfïohÇõÍí˜'¯I"‘D>±Ë˜ÖƒýÄö¡/œì‰Qú÷?EËzòú&ð·ŸáïeÀê”'`ë Ø¼¸¡](hkéŸo­ÿÉBà4;Ûç¹Òb,b3Ä�l˜±Þle}r¼¢ãŸ£C/¢ɽ™wØ“Ã'l“Àw·ãûÆVà“×$‘H"ŸØ…LÄ|–Øö…SBü±óؽàïÕľcÀ_=ÉBÀ¶Öæ�)ñ?\5å è·‹ßZýÇÛŸ�·ε‹�3­·`׈˜l�Zr�F[a9ÃݰžCŽ¿É£PáKÿ„¼ùq¾n=%‰D"‰|b[ò³Äö¡¯š:~’ØFöî ¸¸x¼'aúµ†¸‡øø“\ÏÝÖ"]i“­€ˆ1¯ ftˆ{ý#bJàÉöqjjQ0 !^6ÍW¼Gsr)A±ÞÒ ^º4¦6AL<–�0ôؘJ7|1n⇒À'Iä»[ÜiEðmÀk§^;|ÑÝ~!¬_ý4¿?•÷ÓŠqÝ óIàöÇ�—i.3Äà²íà@ë xðÅÀÜÔ" œ²ü�O-N°S§ßðä}Ôåq‹–‹â1(ñJ·k**°q>=AT‚ö†ªÿ{÷lgUÞqüûî}î!!`T$IèHp Åvz¡¶Øz¡-¥PÅ‘ÊMV¥¼2ÔÖœ¶^zZj/Å©ðRkÁŠÖ:¢UEQ‘*B89¹œäÜÞ½údzÞî7›ä$dï|?3gÎ9{ïœ$ï{öû[ëYë]+�cD¬E¿ø ð#ß’!¯Þ•ˆ’íG€3kµ x-ðÚ¥õn+s·r:Åׯ&ÖX N¬°"}L­0DTDZXÌ–Ü#æl$æLçêC¹¯ÿ§Í²LeI¢ ýô7úË™”(èƒbŠíÍæ­ru®xü9p»¿þ’!¯Þ6 \œ_ ò àBà–ŽÞ~·5^vÕË®ÿŸvОðƒ]¼g&æ¼x ±”ï’\ 817ªÞýVÚeÿÇrU`œnØD ¤]Tž¶(¿—‰éÉPT»Ðmaf¶¤‘ ZE?Í¢Õ,hq‰£�«‰…Œ$òêAUà ×çÔ‚q;QÎýÔ.²›+Oöý®Ìæ€~œ(ÙoËǦÕñ¾ZJŒý/&Ö Xœ«òãý´ï¨zÿUð�åFÁãùñúyj=Y#«l6iR%%es€f9]Ì@jƒEƒŒQc}Í‹˜JÏoÀU-øŠoÉ�Wï<9tþ¦ðä€?¯ðÚý†ÀúüÑy¬ùcQîý?‡öÐÀaDéübÈ$±óƒ*ü7æ¯'ò÷íÍ€Êjò]³˜.I%0>@ëÇeãsÐ:|¶`Éæ4ðff7öµ>Òší¿µÕ=ó %òzšá^üsÀµæ9à½Ozþªeþ¨ª�ç¤ILú!&Å‘‹suà˜\qÊ�…ª�‡Ò8ðh¶BÚJ³¹uKYN}³ÙºãürjÃ,™d¶µ°5|Õ삉¯5¶bÄK†¼züwàýÄä±j׸)âžéOxxöy#`6Lcø÷Íq¾†òGÕXœ+?A+-Ff˜¦Q4([ÀÌÄPßÖ‡Êæ’ƒ‹)úSk-ômÚ1Ý\ 3“¹AçFB’!¯ìÍ¿¸¤2SÀ;€òðì—f‰yÛˆ²ýýµsWÐHE†úI Ë¡�ELLÒOcÉÌìì)Ÿ¤ì_Ù*ÊÛ†Óª­“Ûÿ°˜*ûRÁ4‰±v%€u¹q±‰˜s0Nûî€ÒÃ/òÚ¿C½î"à/kßÏo#&ßY¢ïÆs;Ø, œšÜ>¸ƒÄFlÍ0óʃ†9lÕÖÆÀAÐxÍŽòÚo,=òÏúÆï_Öšáð2†Ž%Ö xQþ|Hþ¹“µÀ#´oÜH,m\-ìï‹dÈk? ƒ¬>Üñ;ð!àïÕ;�ãŠVzU£à¦ò——^ºî–ÿžýòÁE3Q¦&�"‘RƒD1zcb4¥}¸Bq½B°£Ú÷_�ãõÕA‹‰Ýñ–çÁ‘ÀOå A~íDûꎀGiO\Ÿÿ¾êçÈ�WÏôÞ+/#&Ô Ó.Û_—{𓪞ñRku7•ÏåÒtË#“E*ŠTœÄ}|ûÿ×Ã-è+³‰½�ñé>GìMùëoÌñüpîýWÃËr%à¹À/æFÁ í½ÆrðWÃ�çFÆ#Ä„A«2äÕ•*ðqbÓ”ê¹�7;¤©7 ¼¹Qpk+qëF§ºr¡Ý7I,tÿ®jÄAËhß°’ØGà„\Xœß39èÎU€1ÚwlÈÏm÷WL†¼ö7Ç“êÕzOŸ!6œ±Dß;V‹ÝÚjqñ(£;F{ÿÿœ:>_—9 ¾U{¼È×½�Üð=ŒöPÀò\ Xœ’ß7}¹0‘^õQ T“·á�)2äµ�zïä Õgso¦ºø}x�½’žò“9àï.&1±¦XÃ(qÃÄ#íæ×‰¨`Mç`^ÜÑñ>jæÀ0p(í¡€#sƒêxb‹áƒrc¡šø·)WÉ_?œSùïšÆ92䵇¹"÷HnʦÊw‰p øÞ±¸0‡ÊêÜÛÔž+sH�çFÀ�s¼f!p0q›`5°œ˜ø¢\!Èeîí�×Óž'°%7¦ñ6Aòêèu¤ŽžüŠÜƒ_V{î»Àoå ËÞŸn¥}a±,ñ£À¹TÛÚžÛ½Tè|ßmÉæÇþ³ãý8H”ûë“�ÊçíhàäÜHèË�€jáÇi/ôíI‚Õ:åS\$C¾Ç.HÕ<¥ÛÏÇÕÞô÷gˎε²™‡îsxîÁo&Jõëçø�оoÔ¿žÊ!ýðýކxeAýç+›+Ë�Ÿ'& 6ók7å°ßH{®ÁúÜÐx87$C¾‡ƒþhbRÝ kÏ­~›(Nw„ÁqÄ8á® øKrOï<ž¸­öÿ÷je;sÄÝÕÒÁÕ‚AK€crƒàùDµn$÷î«U¤½F@5Ip³×zC^Ý©º`,>Ýðw%ú€÷å Å[ò›ÿg€?Í�?ð?»^-`«ûÆÂZþb!õF þ^J9¸gó9¾øZíõÕþ#´ ªV <2WŽËÏ�Ô~昇ß�W÷üaÀ ÄlúÊ=Ào?Êßÿ=±Ú݈elßü�Xd¤sW ^Cû£WeÃU¹Áñ�§eÞ ¥ùC�ó‰ L²7¦9zú»û!C^]pá¿øõZ¯þ!à7€ïìâÏ–{ðĤ�ªŠóJàcÄf5'äÁWs°OKàÀeÄ6µÕ}ÁŸ'&•Æ·r#ÙÝóÛ�[MLºº€ö,í§i¥çD2äÕ%‰ñõß©=¶ ø=bå®bŽþ ðNb�ïwåÆÀ+òó?È�þ¢Ô_Ÿ Ó¼ø%àöüºÍù︃˜Í{.ðÓÀ-öæ=à/$&S]ÂΫ²=M÷zN¤”còÝðWeò*Ì'€³�›w°M¢Ä~1»þ{ÄÌÛ? Éy�(ÃÃ'å,̽þ¿&J÷o"Æ…Äxþ—�·ÿ‹cñó}žß@Ü7ýæZJ’ìÉ÷¨j"ÜEµó6I”qoz’Xü*±QÍíÄm9"Õ8cŽ^ÿôWñþ#÷Ö¯&nÃ[Kl] ð¥üoù.Æ1Ÿ61âݼ${òFÀ_™¾êmï.>ùv<÷Ú·Õzÿ‰R0<ñ~÷Øyoí÷KrB,±¹ ö\ILà»Çâçë<ŸMT]þ˜˜ )I†|�*ˆqñ+ˆåK«Pž"Jï×îæÏŸã±¹63©u3ì| Îæüùrãá6àìm΋Ӏ�?þÙÃ!É�ïmM`”—­Bt’˜dwý³ôoªn»#Ù¹•X2W{ætbûÒËhÏ‘�$C¾‡ÏÍ{‰ÙðUÀϓ߮–{Î ¸+÷àµg âVÈ—Ë ßÀ—–$C¾‡.ú¥ðwÒ^¤f&ÿ±ýèâoíù¹þâvÆ÷•‘䱕dÈ÷®D¬.÷'´·™,‰™Ööâß39àÏþø¨çV’!ßû=»WëÌ÷çï[¹‡w¥!Ðs=ø3�Oṕ´·zÚ.ü§ëÑÔzõ׿O”ëÕN!V,¼�˜h繕dÈ÷¸3ˆñöµ^ÝõÄŠr³žžñs¹ÿ9`�çV’!ßû%V¦ûBí±�·ÎMc)·ÀÏçä€;±&�çVÒ^ã˜üþaŒØîFà‹À}ÄêvšžñÂð7ïðÜJ2ä¬^ÄJvW{¿ïð°ôŒc‰½à¿¼�XÐH’ ùDU²m“±œˆÕ;–U™ïkØx“´Ï8&¿ÿ…½ß;žG,Aü=bëX^’!/õHÀ_LìÒw!±  $íS–ë¥ùwqgÄFb�ƒ-Iöä¥îw$±‰Ðfà\àÇI†¼Ôý–«‰»$Vë<$’žM–ë¥ù±„(ÑÄýðnÃ+Éž¼Ô†�7·@¾Î€—dÈKÝ«¨}=HŒÁC,x³—ª•´Ÿ°\/=ó /ˆ}f� €»<,’ìÉK½a-pðzà;Iöä¥î—r/þ:bc!Ëó’ìÉK=ôð’ yI’dÈK’$C^’$ò’$ò’$É�—$I†¼$I2ä%I’!/I’ yI’ yI’dÈKê+ ��dÈKêI÷º‰ŽdÈK’$C^’$ò’$É�—$I†¼$I2ä%I2ä%I’!/I’ yI’dÈK’$C^’$ò’$ò’$É�—$I†¼$I2ä%I’!/I’ yI’ yI’dÈK’$C^’$ò’$É�—$I†¼$I†¼$I2ä%I’!/I’ yI’dÈK’$C^’$C^’$ò’$É�—$I†¼$I2ä%I’!/I’!/I’ yI’dÈK’$C^’$ò’$É�—$É�—$I†¼$I2ä%I’!/I’ yI’dÈK’dÈK’$C^’$ò’$É�—$I†¼$I2ä%I2ä%I’!/I’ yI’dÈK’$C^’$òÒîÛùs"¥úã‰Âƒ#ò’ºÏh0 œÄÊ  èLuS^2ä%u“‚"ÁhêLó¢þŠQÒå*É�—ÔER*p9wÞHñÃÚ“ñ\™r_?yÀ$C^RZéFàN ,b ¾U@ `tÔR½tø?Uq¢[æ´$%IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/3D_coordinate_system_XZ.png0000644000175000017500000014007715143647637025477 0ustar00paynopayno‰PNG  IHDRùô>(T:ÇzTXtRaw profile type exifxÚmPÛ Ã ügŠŽ€€=iˆÔ :~ v¤$êIøã4¾Ÿ#½&8qiRµÖl`eÅnB²£¯™W\84Üóéà�hLÆä©ÎpæãÂÉÐM•‹‘¼£°Ý ÊÎ(£xˆfGhb# #B/@tÿV®*íú…mä;ÄWšá=–w†xí¹çfÓÛ‹% q�¥-±7@s•DÝD³$v0“˜FÒ•?;±�ü›Ó‰ôì ZRµ¢äPƒiCCPICC profilexœ}‘=HÃ@Å_[µ"A;ˆtÈP�ì¢"kŠP!Ô ­:˜\úM’GÁµààÇbÕÁÅYWWAüqœ]¤Äÿ%…1÷ãݽÇÝ;À߬2ÕìIªf™TRÈåW…à+‚F"ˆKÌÔçD1 Ïñu_ïb<ËûÜŸcP)˜ ð Ä ¦ññ즥sÞ'³²¤ŸOtAâG®Ë.¿q.9ìç™a#›™' ¥.–»˜• •x†8ª¨åûs.+œ·8«Õ:kß“¿0TÐV–¹N3‚±dÔQAb´j¤˜ÈÐ~ÒÃ?æøErÉ䪀‘c5¨�?øüîÖ,NO¹I¡$ÐûbÛã@ph5lûûض['@à¸Ò:þZˆ’ÞèhÑ#`h¸¸îhòp¹Œ>é’!9R€¦¿XÞÏè›òÀÈ-0°æöÖÞÇé�¥®Ò7ÀÁ!0Q¢ìu�w÷w÷öï™v?¿MrÅÃi?Ö xiTXtXML:com.adobe.xmp ƒ”ЩbKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEéI#wY IDATxÚìÝy|]g}ïûÏïYkmiIÖ¶%Ç’§ÌsÂPpmRˆCÆ-½6èejKÊz€ÒâmNoK'è«”K��èm�ÕáöÒ8CR¸”ö�$@F;±%kÚ’ö–´´÷ZÏó;¬%[16$�Ø’ý{÷µ�¼¥HêÚÒþ>Ïï™ÀsnPu)8T�ÝcÎ~±ÝcÎûáK¿ÍµS0 FEµ›cÌÙÉZóÆœ+¢f¼ —èŒâ vSŒ±�7ÆœvCtžòœAôY\r‡Û7ŠˆªöÆXÈcÖEhàTPÚp?ûL¶F*O*7î¹îº°ÿnÔ:ôÆXÈcÖKÆC�•ôE�†n½—«=²¥@®m°eKãš=–îÆXÈcÖt_C�E倛m²;!¸�Ð{Ù 0 ¨ˆ`�7Ƭ› ÝÃëZFùûù帋|T¶DÝÂ�·Ïâ8€Ø˜¼1òƘõBUh ö—ñ= læá)<É @{”Æ$ܽßzñÆXÈcÖO7^”}¢û÷Uÿ¾m]Û ›‚ NúTžúùñ¾��ÛÎVÒc!oŒY7=y„Ñ®! �ýÂØ‡¢�éÒó: }Aè@ˆÑž«7.=«±»°!ycÎZ¶ã�1g]O…½€Æ>Þx™¸�Åß(èâH@æÝ�Àߨà­/oŒõä�1ë¦3¯Ð(×È¿h–‹½$ ‚Hz�ï{~£Y¹ÞëÉcÖUgØ7*ܶEü»”0ƒ(åÄ;¤ÐpÅË7²]æ8x²œ¿ž÷bøµÕ�Í É•çGí.c!oŒ9#]y�Ñ4öþsX"º¹—PÅx@p‚xD£� Åu ‡8É!5|åóðQ€Ü‘\xcªfì³>X¹Þ˜³.à‘=£8îÞ«ÛøDÔ%ùþ€jpà�"D8EcT¦•Ýœâº{àÈ?Ãÿ>¸#𔋠|^ äv“�±�7Æœ‘Œ‡=w�¾þ;® ¿(F„GÆ£R î{Ƕ“~«¯÷BÇ®^r+üǯÀv‡�Y?¬\oÌYFå®»¢[÷^îà‚-ø$w@IèªR� RS·Ã�3,�ìkÝÏzvà]ÿ ï¹þÑî®1òƘ3Û•-nVøkI¿8AøTOðÏÜ@±É^ (A5jzüßNÃâɾ̰ã&øà'áàL> ~`þþ!˜µmÌÚgåzcΔG AÃýXãmc×î꼤vuqÓ|Ì—Nj*²@í“=øëûŸ7=M™?ÙW†ð߃/€w¾ÞùCð+uxªÝccŒ1æŒd¼ Ü%B5¢¡îµ�ü ñûGýbý3jÛ½›˜[5FÕûÆXOÞ³.ˆh‚ ¡�ðrvkW HA×uí»�›ÅW{ãc,ä�1ëÁ¾†êÊ–ô�}0À" ¡°Ç…®AQÛ·Þ ycÌÙgÔn�1òƘ³Ó»ÆXÈc¬'oŒ±�7ÆXOÞc!oŒ±ž¼1ÆBÞc=ycŒ…¼1Æc,ä�1Æ ycÌÙÉÆä�±�7Æœ¥lLÞ ycŒõä�1òÆëÉc,ä�1Ö“7ÆXÈc¬'oŒ±�7ÆcŒ…¼1Æc!oŒ1Æ ycŒ1ÆXÈcŒ1ÆBÞcŒ1òÆcŒ±�7Æc,ä�1g)ÛñÎ ycÌYÊv¼3ÆBÞcŒ1òƘõÄÊõÆXÈcÎRV®7ÆBÞcŒ1òÆcŒ±�7ÆcŒ…¼1æ‰a�7Æœ¥lâ�1òÆcŒ±�7ÆcŒ…¼1Æc,ä�1Æc!oŒ1Æ ycŒ1ÆBÞs–²uòÆXÈcÎR¶NÞ ycŒõä�1òÆcŒ±�7ÆcŒ…¼1æ‰acòÆXÈcÎR6&oŒ…¼1ÆzòÆ ycŒ1ÆXÈcŒ1ÆBÞcŒ1òÆcŒ±�7ÆØìzc,ä�1g)›]oŒ…¼1Æc,ä�1뉕ë�±�7Æœ¥¬\oŒ…¼1Æœ—ÝKO\Üî[‰ÛÖw]“'�ÜIÿ‡øP¢4œ6p4Ô¡*vÇŒ±�7Ƭ÷^®Å>öÈ]�¯ïäŠgNŒÿÝÂ,ŸQþâÀ]¯»\Ü%4ÐÆ>qº_,ä�yb»Æœ£FYS%ûÑÂѧÿÿ — {þk6Ì5qé$¼ðà=ü3ð�ý4¤!ûü>°œ7ÆBÞ³ÈÝw#u ;‡êü%)W…t2¼Ÿ'Š v5¶ŒÊ¶ÛG�—}XÆó(X¹Þ˜sÕÚšx§Ÿ|;e&¸¶(pa¦ 2Eá»èØòÚ�Æ>²Ïž?c,ä�1kMCq¨Š*¢ �î)w²³™ðqéåzíàÂÞ7Q·@‘zŠÿ=ºw*›wgŒ…¼1f †|Uhß¿�î#/cÐÇüA­�B4C}›$Ÿ_ ±í¾  (øªv'�ùölLÞ˜sÕšx×Ý'ûET£;^$„F›x‘ïâç�¢èNõlµ®ˆ1Ö“7ÆÙ°8É{`o䉳%¼Îáü !'r�Èn•1Ö“7Æ|gÎÐÞõ—5X*ø-·�× $ÝE mù9¤{‘<ŠöDc!oŒy¬žèr½"»•X•¤œI¯nÓ,›z&ø éçUÁ#,¢¾MT̺ãÊ]nT+×óݰr½1æ‰!èm¨öLJß%ãü®ï㕪$š| ñMÈ'�°€ˆ¢8J�òkH÷ÆëÉcÖ Uäv•XË¢AïWæØ—ðÞQ ˨Ÿƒb†Ð™?‡ŠZ˜c!oŒY7þ^þæ¥çßàÝ.å._¢(ZP4¡3�ø6‚·±wcžV®7Æ(ÐONìÚ$aºGQšU¢'ÄRN´SUT-ä�±�7Æ<Çuòz�z @¹­Ñp÷åìYÞÄ{´Àé2ó¨ŸA»G‘¢…mscŒ…¼1f½Øß¨FÓ¯Ù+ó?Î+rÇ{]Ì�vq¡�Óhw Š9p…M²3æt±1ycÌãâµ/jDŸ©³§›ð>'ÔÃ2ÚPÌBwŠYœØvÆXÈcNƒÇqÇ»{ˆ¥‡—º˜÷;¡º8m#~†�O£Eç Wž!o7ߘÓÃÊõƘGO÷D ¢Š ¨ì¾•¸ÖÇ Tù]WcP»ˆoü4¡˜D‹i"É Á6¼1ÆBÞs|Gï®U"û90Š£±_Ú#<×þ0îa˜e$,…Y\wɧp®q8¬oŒ…¼1æ´øÊõJm( mðÔ—7®[ìáÚÃfŸùÈ›hgíÎàPdeYœs8q–ñÆXÈcÖ¦ý :*ì‡ß}2ßã>žô°ƒ.±.!E­JôN:ø 6ÑΘ3É&Þc5Ù‡îÙ»Wn}—eKü¹Ô¸4ä8mŠ9¤˜D»S8r‚±x;2ÖëÉcN§ïdL~?rßïsåÈ2w}\é»P´)ò&šO¢�I„.ârÓ›ÕAƒM¾3ÆBÞóÄúVcòª‚6œ6p ²ç‘r ºî5<µÛäÃQ/»ò•%\w—OQt§qâA@ˆPŽÃ?¢ ˆ�Ëc!oŒ9ƒT€Ñ»Dh ×îmèsï}RÑæ#Q?×ùÉÛxßD£ B>MM»@5ËNœ~s˜[ÙÞ˜ÓËÆä�9W�žº7/ˆê^è^m¸¯Ý׸Hù°Ôyz袲€Êqwß�ÀQ€(ªÕŽvÕj9cŒõäÍi&@ ’U�ɪ÷W?öí.³^}›%t{Ù#ÌNr¡*ä6°«èâC5ÉŽèE¼/�ާk_ x;QÎëÉ›3ãG€·óÀ8ð@õv x˜��¯úïô„`·ñ³•ªŒòÇÉðWeãÄmàÆÐ—áŠ6äÓøbœH—ð‘#AÔ!+o­?c,äÍ™óz`ª ÷aàû�­À&ÊêN¨‚~˜Gªë0ðÐ|õ¹ög½ñïH–/âëÜ Ëx]Btž¨˜Äû#8 DkÄ¡ 8œ®jü‰VcûÆ ysúúhÕÛû€ÿç$¿[€óªk;°Ø<¿z¿·ú ÀÃU`%øÇV]ãU#àÑQý·Z5&ô$Uk0œf{î¢ví(ž†òºÛ%º§�.]ÎÆÖ ï/6óâxt™(oãŠ1–—'I¤À‰¢QùLºê \)×—O¨¼1òfM)ªp?!x¥ åØl«[«FÁ÷TÕ€ó(Çú=Ц)ËÿW½?¶ªJЮ*²*à儯ˆy¢Tï\«Å~Gcøð{ÂnFÓ¥A~;œÇ�9¨±@‘·‘n“PÌÐC�°2ÉNÊÿ³<7ÆBÞ¬?«×WW³ºNö»Ô¤Àƪ 0 O®}ÕÙª°?L9ð`ÕÀ˜ª®…ª±`ž�.|ùf¯ŠŒî'44äškI'zyOÔÃ+Å˾hùY(£aï"¢c³èÅfÑc!oΕ*@A9ao¸ÿ$¿k½UÈq|H` p9ð̪ �V�‹°Ä#笞°òñì�“³Çª§pímÈž†òÆ;¥×9~]S^«ž8,Rø6‘Ÿ‡ü(H†8Á©R('�l c,ä͹ÝX¨®ÉS|NOU¨W €áªp!p]õXRUÚÀ\õµ¦)ç<\UVo»Õå-àO¢*×b¹íVéÝÜÇohÊë\††œP,’øy´8‚úª‡C\Õ\²p7ÆBޘǢS…ödÚ'Š€þ*üÏ«çWÿ¾¡\! U8ÊñI�ã”CUßc�ãOeõ\ý6Õ‚5-Dùˆ@ ÃèKQÙ/?ú ýßè£õñz)ˆŠ s¨ÌPøIâ0_�$'@@U¤êÑc,ä�y\xÊ2}kU#àİí§\°™r‚àʼ€Ë)ç ¬Þh¸‡rnÀÃÕל¦œ#0QUV—ùå$ ÖK… ñ1…F 1Aö7F£ÿöó£=ó“¼Uûx�(,£:�ø9¤;‰írz©–Ä•“ì,à�±�7æ481\«ë!à‹'rB¹J`SU¨W �-À�À «ÇRÊá…ŒGî 0]5 ŽV �q`yýôî}¹ BµcÍØ.âù&o— ¼Ebzd�àç‘|†Ð9Šh wl‚�CŽ�gÌc!oÌl ¬ÌÔ?Z]'öÊk”óú9¾Dp¸j|?åð@Z}|eŽA“ã{¬ ¬l"4G990ç›çœêßOXU "–\rb…N_}ñ"~Ö÷ñæÈã\›"¯fÑç㈴ x)ÞâTmNƒ1òƬÏF@§ºVzé_9ásÊÕÀ`U¢xðÊ}zªFÀJÈ�s|(à`Õ˜®>¶T}Ïß®bñü?èˆUH¨É‘›;7ý¼ÄA­(�°ˆúyÈ�B›H'8•UsìÊ5ñÆ ycÎJ9å8þ…Ó¨+'Øi((´·Ü®VD (Š �˜|§å7õnÕöˆzìn¨�ßc!o̹¤àøŽ~'#”%ÿ-ß>x„r¯€]ÕãýÕßn^ýƒU`¸?–xú<þøhÆc�ÛŸ·@ûåú�ÖÍ=S¯Aã‚0ÔTíÉnçpÅ38ðT`S!ÅÀ¤JÜC¹\÷_9øÜ·Ñ½ð\ÛëéÖ¾¤¾Û"^x¯dMP.Æ…ï"ίšdW…¹RþU%ûªGOˆª¼–%}BµÄÎzòÆXÈcUø¯œ°L9žè„Ïq@o¤¤QMºÝ¾ó´·Ø>øÒîsû_ÁÕäš¡á˜ÿÿXš;’/1÷ µ­ôÈ0QTGâÍD²‰jˆ$—à$&"Â!AÑ•Þz5NâP®£‡› gŒ…¼1æq€%K®»¹IÚ:tÉïåµ�Ý\X ÐW[D} Éga$#*vÜýKóä$þAdy†.‹d‘"EB É&·‘(ªã£�ˆ«ã¢ xׇÄ}$RÃù"Ž(¿Ò÷ž¼1òƘÇSФŠÃïâiµÝ¼-là<Ÿ:‹¨Ì"OýŸ0øÏô~êéYn@é�<^s|®$xz¤SNÌ K¨oR³tò‡ðºš#$DÔˆ\JGjø¨Ž‹ðѱl&ªm&‰Àõ‘”Ûå±r ðc }[—oŒ…¼1ç® ã8=”øx sÉ2šÅ�‰öý_ùÕ_ÈÛ£~¶t»ÚàÛDW’…ÿú?s)a¹†«åxêˆè!ZÙï—~ˆ‡Ž-õëyD¹À£¾EáçÉC ‹Ä,¢~‚Z÷AK„°Ìbèâ]êÐÚ0=µa’h. ¤ŽD}q.ê¡&q‘ qY Е¡ ¨”�Ý6u�Û/{C£±Ý'¶­®1òÆœÝFõ… 2M– I¾C²üHØö«ùõçó66±#÷87Oðó8=Šîþ$’¬ ö\‘€øGß[ÖrO�†ˆã!’•óä«ÉvA»t)t™D;ô ¿„ómüâýtÃ">´ Ú){ùÑN6�G)‹²â­m¡m&Š6i?…l"vÀ®KîV´áT�}8‡½Œ±�7ƬYͤ¥ H¾e{Ôâç¿’‹7ìá—ãA.ËssÌå³°4�]BD�§æ‘®-CÿQÄ9ÜÊyWžá§U+Ái�šÖ¨é@Ù èqD(ª� ¨÷ß!„ET[ßÂkFÔy˜¼›!KBðríPÄI¨±XdñåétñÞ;ÒÚXcËÆû¤‡Ù•íƒ)—c,ä�9{䃱™¼F'¾†ö²½þ¼�ó¸*tÀ/¡2Mè¶IºãøÐÈá”rþ{T<¡(ψT1ï´ ê hÈ•�·²ý­‘rŸ{|({Û*”ûüň@œ¤ˆnDÙ^6TÊC\UºD–H¢^¢|‘8+6“r%‹ÝëÝâl½ƒn¨zòó”« VZ9LèHu­lN´üÍE‰Sn|ªã…�±�7ÆœFEÊÒЗeÛ�±uð�48�k¢ŒÐYÆiºmb?äH!¤Ü¸r„U;Ô= +ÉçA�íÏ+Õæ8* _~• ˆ*ãeåã¡\s¯Õáö*Šú„ÈE¨$DÒKO4Œ$Äވx ÅÁCw^¸?8(½“½½¾¶0H—Ê=Vºxå1ÃqÕ¬X9Dhšr¢{ª†À$pÕHèV•€‚S+lŒ…¼1æ 2GL>IÊðÉIÚ¹*múžÇðÆ7òn¶p­d„åe�4L£ÅQ^"\îÐPv°qâÕ¤¶Çä„oR¿VÛãIõÊâ_ŽA}5¡NuD"bâ²ñ�€h @ËŸS@¼ á(éA’6º0ä²4#+›(Ü’qå ¡Ê„)7 ®®õ*ÈW7¢<3à(åRî(¸T}/ý6=üÕ�?šÏ1ÆBÞõɾÐ^ŠòIñC »Œ#RÏw�ì=²}ÃØ×³‘+Ã!ïàdŠYtyç–Qçˆ|u¸ ‚ˆŠJ-wªSù.z®+ÛÙ>â TgÏ«+¬ìw_6ªOVEWÇ¢á\Ù»'R�€äJH ÈH4mæÉ·ü‘V$tâ�ª·U�ˆrûà­ÕûWVÿ®W•­‚þ�êí¡êý)ÊဣU�“TN } zc!oŒùf™¦“IÈÈh2Òf]ú~éÈ}/ã­~˜kŠeD:U‰~’¼3A¤A«~g¤H¤ç| zõ8üÊÖÁO^W…»«;ªJÀ0å¹7/6Qn/\PNü«+C÷Qž.8[5ºðÆBÞsò®i’жÜpŒ[*:?9±¥ïe¼%lcWÜ�bŠiòî<‘Ÿ"v+ÓÌ"$TgÓU{ÏÛXó©T=ýP½?V]'Vzª«¿ ÿ‘ª°xvUè§œK˜W�€éªp”rà`Õ˜©‹” å$?Ó‰ ƒ“5l² ±�7f½Jh‘O&¾M6îšè;ÿx‹leWœãÂÁÏ#®I$G@»hTn(+A *Õ{åÜËÕ5’F@�rN@UØF90 \üPõñޝX¢œð@þ‡ªkŠò8áÅUÕNÑX³œ±�7f½JI%ûáVÿÅïæ­ÉvžUx\¾D¡-�ÂgGq¡§¨‡à)§ºÜc›Do¾Ë åBs”ãö_=áãQò›(�YU xFõ¶¾êõy®êñOU �CXY&˜W—md,ä�Y³A^ÇÅ1Òn�„ù€›¬ß§9 [ˆò¼Ååïà ²“ô®è@hçSÝ1D:ˆSÔGˆ ÕIq”ãñ"HaeÜÓÙÛÿV<Çç|íÕ€AÊ!€ÍU#`¸ xVUX™~تzÿcÀøª*ÀåÐ@sU@±ß ycÌÒJ´�  äniÓ}Qü@’ç ýy¼ùÏx}íR^ ‘%¼Î‚Îá:G‰É®ÚTÆyTV�þ&vðëzÔ­Bzâ[|ÎÆ*øWVl£Ü+`Wõø†ªjСœðyà­Õ¿-è-ä�1§[F®I¾YâlF—ÛäYCÏÏ7¿‰Ÿ‰.ãG"¥—%ðMÔ·pÝ£(‹å¦2ÁÛuÎ&Ø�]N5™ne™à½'|®«zù)å�À¶ªðýÀ;�wÙ-µ�7Æœ©?ÊtF†²!&)`x)Úò‹üt|/U¡Öí"LSäóHç(„Vµ…�ÃiÙ{qåF4次�ñs}u-SÎܰúØe”›Y/ÞBÞsF$HQ ­áf”oÂ]öAÞ�\ÉWàt _´ oºÓ$ZŽèª“r&½/w³Ój’�½�c¬ÅoÌËóä$%õ<Ñ4¿HŠ^ä’÷ñʾKy©(qÞEŠ¢béÎ’è,J¨v‹Eñ<Á¦Ñc,ä�9Ãò ˆê’ÕS\Êf!Aܓֶ¿�—õ>•W«£'d¨Î#�Y´{˜©&ÓE8çÊ^» 8‡sWþbŒ1òÆœ)C÷_äc2’ææÐJêÄ3.IsúUžŸ<“×JÀI: �YB~ -"  ñÇvf3Æ ycÖTO~à ÔiÕsI[¹fÈâéõ¼>òD®ƒë,–_Å…9¨‚]ÄálÜÝc!o̵¼LȇZB MH¸è½<7¹ž×KÂ&éu�ЄbÑY_†ºD8›EoŒù6lv½1gª'OJ½‰æ—¶â¡wrcr·QÈéà´Ësà§q~Ž(Hu>»PΤE-å�1Ö“7æ “ÉÍ!MgÊu–êŽ<•#´Bš#ÃÉŸÕ¿›·ÓË&Ê€ùRLA1M$Š:]é¹;ÄÂÝc=ycÖˆ”%², Y¶S/lÅmr%Meøw¸qãðNzÙûÖpÓ�÷Vž’>ŸwÒË·ŒHFÜ™'0�×&±¬œ¾2‹Pƒ7ÆXȳö4Ó”¡Þ,JÚ©öÿ|ë’¡¡A/›CŽøyh‘ÈQÈæˆã]ÉxY9I.T[ÕZoÞóY¹Þ˜Ç­ËŽ�$’&Hšâ’á"Ç\SRM~¶µ}pï’~†CŽ“6ämâü(Åò4‘Ë!8DªóàËYô‚X7þ ?µ 2x 5H©§¸¡�rÅÄùWÓKš–Ï9‰@CC©5ÈŒ…¼1g—<Ñ”œz^—,’�ü2im?èÚ™nú©l{Ï-ì¯mäò¢Ìá}ütgˆ%/WÀ—gÅ~s@ˆ­‹?³OmžèòO/’$“,Û©Ívâ†óøè×F:i‘‘å×Àö<Ê£‘vSëØóe,ä�9Ëz{¹�'L ©P´µHï#›Å×^ÉÖ­?ÃÛkÃ\ÛíB´ˆ+ÚÄÝ)|w'T=ÁRam?·[¶ý{L¾™¸~X††óxy2)bš�of`àn—�%…dh–×5Ëê ½}pÙ°±~ü+ŵo~Ì ycÖ…Œ\i×ÂpžK’ÕuãÏqþ–×òËñ¾'^$¸¡;Å,t§ˆ$¯Î€�‰4*Ï…·»¸{òèø4yNK‹ Í&ë~ˆÔ¥I.Ôg¤Í3€—·²çÚ] Û IDATomÕs!m¸—¿÷ÖßäÕÿ ÷ú_ƒ$µ»jN›xgÌã–‰1à2f´� þ'ZÛ.þiÞ™ ñ·ŒËDË-Ÿ&dSÄE!ì.®MíIŠœ\³�r)èUÉâΟ ÔÎ÷‰:ÈTå(¸# |²üeø’/€,;öü:ä ïD&|ù>Üëß±�Ç ycÖ²,9¨é†–»pì2�d2d±´®Î{®ú�âmñ0×…Y\&H›Z˜�îQ„%ÔUánKâÖtÈH¤ÝÆ“¦®V<ý¦ÀÀf!ò8�‹�* €Ä‚´Ô1£ÐþY®$ùªWØ—ý"îê ñ}ú±ß‚‘!¢W½Ýî±±�7f KóÍd I8Ä×}<Ôr›ú‹ä’�ò&w>Ï%ÁÏ¡EõG‰XªÎ‚qçÄþöÖ®ȉcê@[c6^í£e~�4ÿI¡ù-w!ôN•‰ 7sÏðq9W#ú†ÑzúÑ÷Âø8ü0á#ï#ô/Áà¥vŸÍé`còÆ|ZÃK.�¬‡,Y’ž«³Þ­¿Á-z/�(dˆ6A扳ÃÉVº+w¯“rV½Y«}ùɲ$$IK( Â}Š¿XÈûáÞóó‹þ‰<øÜgáÙáˆ$Èü¿ãþq±hHR�ò¥Iô#ïyäôÌÏ|ýÌgìëɳ† Ç™Hò>6ý:¯ö—ð<ñIJˆ„iм ÝÃ˸°²,îø$;³†ÂüÄǶ\B-ÏSÈ£4Fr½*ZÄmEÓV –(»d??ûmPlDs¯ôÎþÙXQä›ÕúOÆzòƬs“ uŸÏÄçÿ¯H‡yV‘#~™àˆÃ<Ú�Í@ôøøûªqxµ½è×FÀÇñ#—B¦)nê�¤›P—fO}ÈÑyãOÀö×”;ÕΣÌÕ\ÁÍJG…B#þäçë)®•Í„mÓ3~»ÃÆBÞ˜u*ÍZZo%þ¡wçuán>ë�߬ °£h⻓8]BÄ6¶YÓò=q¯€mäµñ‡Òœú„s­}‘càET¡@µ9£ÑÔ_Ö|ïs=Ÿ�gïðÚýˇ¼‘%Lß3Ô…&娾1òƬ;›Î£6Û›KñðöÎb2ö£ñר]ˆÏgpÚFð›E¿Þ:>žäÔ'dËyÄK­üÖÅÚþ½Ö½ú× Â¥¡v÷ŸÐû×Ý]êíÝþ°úñ‘œbBë~‡SŽ0¸=O–§& r‹xc!o̺5þ”žž/îÜRscs¡�Ò.Ì…6ð"8ÅŽ#[_½ûTSòºÎeYšÓ›.Ý? ôî$üÝßÔ[MÍɺ<”’ÐÔÁ!b8Âd3-H6ò‰ª:`1o,ä�Y—6ÌvBÏ Wè—'ÍÁ³àDp¨”%{­Î„·»¶ö¬ŒËšç©&Ô]Öóêï‹:õJ¾á¶bàÿƒ¬„{ïóé�Ÿˆ'É—¡ #ÏM‡òh²=âS&HH$g‚$ÉådÃÆXȳND¢� qÕb8yÀÌÊVµðkÒàv’åeBѼ(l»à`òЕ!_ø?žOqÙ[<ý=ŽÅÝDÏ:2’ÿë×&’ÿþ ²\ÛÇZ©�’µ �AŒ@KÉÑœÄzñÆBÞ˜uOËÙóeŽƒY½W­%ûÚ¶0¶³ÈiéÐðÁxü¡4¯±k·ãŠ›ºäI�YE—„¥ y‹¶’ÇúˆàγU=õÙ#zîðfí°uòƘsÔaÞÞJš“õ¢w(sŽû?·¼ýÕïñ}ïŽtQ÷�ýÓY}H†²Èî—±ž¼1Ƭ—¿7»€gpwÒfJá¶n} iÅŸû\àÉÿ/ƒ>�ÌÖ|N,öJi,ä�1fÉH”î-W%ËOùÕ‚™M.ü0üå]QþåÏç/™=¿×Z#Úf§Âa»ifݱr½1欷zûÚòý²W_‘,_ÿ›¹ºXeû.òë_ÔJS|ºÔÜ‘´s8¬ôâRZ n?l"c!oŒ1kNŠäƒ¸ 9’«Ý†m$ÄW¥W|oAwŒ�©è¸#‹ d™É 9-²IŠ™NŽÙl:c!oŒ1kO†ÒÞ¡EÒäâ˾V[x(íîH¾ÒÝ8üæ?×m¸%æÁ»„¾JíÞ�¥­Mˆma„9kX Êstæ�Ð�8übÛ/YüÇ“±«BÊÁ<ç®O‡žÎÿLü'I‘<#Ø3òƳ.$E®yü‹ÕÚOÞ§¤ÎŽ]öqÒ·~,ÍR)âO~š0ÛÊóDã8·^¼9«X¹ÞsÖËÃËwºì{ÞãÙqeîâ^Gï��?©NšA!­$¯SçB—à µf,ä�1f­¸„ZšâÒI¤žâˆãŸŒ„Þ‰? Lw‘60w¹¿•©¦õ ˜qpŸ¶gñPØ�4g +×cÎí’nÊ…® Mž¶ˆÉ¨Eh%q{}iõþr,˵W†èÁÿL^(äd9šëòûc¬'oŒ1kÉ… FErŸ’LÀÀp”%oÚÕâÇûIS7@,tÿÇ!�þO‰ÿÓñ¡�ܶª5Ö“7f�(Ïx{ü>Ïœ…Æê“š·6+7lH'­áÙtC7>þ…úÔáàùÌç•#ó¬©c2È3Í,à�…¼1gÌà�”Kß>P¼íZgމ' ¤©´â+ŵ^ñdñêÿ(HwŽÜЭÝüŠV÷Ï‘~å En[ϳŠíxgΤ�À¯R–ÂßK5sÝÞ¬¢ÞS,uXN{›ŽÉ]Wõ²é‡T¢5ñ´Ÿ&CD ¹-‹3ÆBÞ¬¡ü¯T¿ƒÿ7ж[bNšò‚ô÷ÓŸ- yâ¿ýúRü‹·Í òmõ´ÿ’Ú‡�6�¬n7˘X¹ÞœÉ€�€ß¥œÙnÌɈK]:ô\'ÜQlWÜ!ÿ•O‡"ÛΆ/~8]Hrò$R!Ϭ7oŒõäͲ…r ¾øÊ�gŒA]5Nx ª‚½sç…ÑÔ«ß�/ÿä%‡Út?�kï'ÞOç‹Ë“'@Ú;¶À ysæ ¿L¹ñÌïPî&gL•òž€:�("Ö@PE)¶úhãMI÷Â瓦.)&Z,OuÈ!£šAßÊyn½xc,äÍp°¯ úßÚ-1«EÕ@�˜(8èæt’ˆ¸¦™7´&Ò$#§eanŒ…¼Y#Ràç(OŒ{¯¼9™¸jA Óa9I¨ŠªÃ±8™ãÿý«ytÛ¿h—$¡nó(ØÄ;óDë~ ¸xð ÝsÒ�¯Æä�'4fjäB†óõŽZ²4UÏ‹5!ûíŽwË.nµ)8JyŠà4Ç�^(÷[ðvW�…¼1Oœààjà÷�ì–˜SRp?þ…§ÏòÕ×üÏv¼ø³=€n½Š/=|¨{`S' .¶ãM…„`#pmõ¶Hª`oUA? ¡´ ãȪFÀÁ>'¡œdÚSõö·UU�Í”[8_ ü åJ“¨ú:Ë”eÿÉꚨªSÕÇYOG.›uòŠ( òÈfUäÄÇP±póˆ€ÿiàÀà“”eMcV’RDA�"Þ!ÓS4ù_ïØÂìEÎÑ$§·jôW½ÿÍŸ#ð½UU ® ÝU=þ9ࡪ0[5fW}ÏÇ:9Ðö8WC¾qS¨*QцâQEEP€ûì}Ä¿ÏíaT¯“=B^þ b=·s´_Æó€UÿOÖƒ7P¦ºW|�e�¢'¡&BŒ`CJÿ\ïÔ¢°sc¨ß’ ¿.Ϋ¢*àjÔ‚§ëâ³bÓ®åêš>E# ¦,÷¯Ì¨S l®ãøœ©zøíª0¹*ø§ªÁ|õ½ÂIþõAo³g{Èï»Yƒ(ÀmQùt«ß'¨¨¨–A/ˆ*ÀÞ£ÅfvicQTDEØßP ûE9÷¼ø©*àÿÁn‡9ÖúS�‚ 5’"uHžÓ-2ò$¡§·�8ºé}‹þÓ¯)ØõÇ“ƒÃŒœÃ·« œ´×úŸÓO¹2`e…ÀNŽï°µj$U`·('¶8¾4p¸j l©þ}bðÛë÷Ùò¢¢*À�ê‰ÞƒÛß@Uì× öºW`T‘/º]¢›vÉ�Ñ �Q±:Ð9ç«€ÿð�v;̉’„Z§ ›(Ž?s8šáÐ µþ«?Ûéa�rÝ_Î_™�8!²;ö--V׉Ë…r‹rW…ÿÊPÀʰÀU_&˜_ œ0 Ü ®*÷VU�•¥ƒ 'k»}›F�5ÖjÈÃ'z@�Àñ¸–FöìE?7*wM¡£ Üz›\÷V”ÛvynÿM·Gn7ë^±ÑžsÊnàÕÀ§)'ÚÙ¶ù&yÀ»˜( ¸‡ïãÿë]ÛeâúxqyÃbïüS~Þ nG»7B$vžÆw@9¾yÏDu�¼5à5UoÿcÀUèo¦œ°±ªôT_¯Sÿáªð å0ÃdÕ8XY&x²!wŠ×«œÉ�WFûÅÓ€›D÷½šd¹—xúáßé}Éè鹈Z±½�Û._ú 1ÿµáäàÒÔèÉ«¸c—‡;쎞ýxåZø/To“ìÌÉÓG 5¨MÏÓä®[¶2uE,L£s#‘8„‰/ð.!vÞ~�žÀF@‡rH M¹9Õ‰TÕ(—¦Uðo«ª#ÀS(7¶¨>¾²upVU¬Sî 8Æñ3º'¼v˜Óò Ïc»Ü•lëyI¾¥ólwEØÁ�n+A/¢¾¸•Í2$N\Ô©…¥Ǽ@{I a–ó¹€î8Èí»’=»î ˆ( ö @CÚXõ_²—†Â¾²E'åÜ>Q¡šzsüwã¸=«Â¤š(Çš‡6Ûÿtü/_þÛúÓP®y/rri DqP‚Ѐï¯3�]ñ73Lœ¿%‹�«>Õîq ìï÷ ëV×|Õs¿ë$Ÿ³�ri`þÛªjÀ“€ œ0˜T¯íªÇ?UUUá?Ny†E›ru@÷„ž½õö÷�¿¦÷Bu¿€q'¥�ˆ‡!ˆ²$€Šª¨/·…�È«º 1¢iÔÍûËýg‡Žr÷L÷®ßDöÜz³4¦&ÿ=UöïÖFcw(C}¿@hР!û(Ãzÿ~‘»®A‚¢eé_E­{ŽÏúGÝW®É)›¨Û¹JD,xž ϬþëÀV¤Æà=…9"/�çt£„$×íÐIúè¹âðÐÄä�§gÉo¼t?èn{@RŽÊ-L[zÆyí7Zð¡%~q¼ÓmD·Ah@hÐ(mûFÝã ª Ü�r²²QÕjÆÀ~„òßN@…†À5Uï¯=³�¿ë€7÷°€7«@õ…8\R£¶Ø¢Ýú— Þ»¼å™wõÄQtÙíþ¼í ÆqžÓŃ+ç®w9Ç7÷á=ò•GªÁŽ*üŸ\=6@¹ïF·j¼ø¼ÝÚï&ä_AhìçoWíø‡Zqøòî^JÂ�Wĉ/. ¢âqN¼‹„¼PZêPíeF†‰;[‰r”D”9 7ÕYÔ0ÞÖóvw¸ñŽwO¹4¬yÆB—ñâ&ù#–¹û.el—ãÀAØ7]+p[ê·…}ûAoj8îjè~Y©4T@4ä³÷æqr]g�÷÷9çܺÕU½·ºµÚ²/A"8±C’ÈCH óÎ o+ Ì�!aÂ2lÃ2À¨”!@x!, äu`^`ØÞ¨Èâ$¯q”Í&‹L,…x‘7I­îV/Õ]ÕuoÝsÎóþq«eyfÀV|þ|ÜåºUåîSçžß³þžVõ½>Ùøjà‡ÿNÊ\\… �$+é—ž¹ôWh¯ü †{ÿÕ(éãK»¾oazSÓ»˜Ô[L’�Ä@”ZQü—ž(:³Õ&xÏÏmulM¼ø©�íx¶ZÆ*É z\1Gäkú™;Îgoúýè;F›/Úèé÷häz„i„£é{ωÍ!� êF-kÙOK…’Ú[­T,ÿdâ2ʉr÷RN”«oTx¤è“»:iT´}ï ”ÓƄ堲iš)©q¸èñ&b�A(0û¹µ8[…íŸÉÆÀVw@ ø·Gâ{(C÷þI$Ì ñägç×ÏÆ#2™ÝXûÍ7ó¡�Ã|ø®—å¿‘®$1ûÅ…aŒz‰¢† ŸœØ®¿´ÚN®ˆAg0²“M½Œà§¤¦Z #XF0b„ hØ Ë© 4A S,£$þZÅ D,±ŸÐcEÖÈXäž;N3tì~󣜱ÿ…¥Œ2ÿ�Œ%2–�U®­HèIÄ^àga³wñÄ}³*Щ£ ¹úÓfcyjMï½a”kÿ¨=4NCaP˜78ÙU"X‹Ã”ÊšÕJ>£Ñþ#eÿÛ�»ª%y’H^õ¨€Î ¢:;¢b8zà~½áÀ¯Ëm­›Èà ͯӄW)2­‰…h~ÿO[ÅÍ7-b©~+qŸ’œ€š®0ΙHWØ»º»(ØKÍ^Žc7ÄK‰:�•�bIÊ@¿”ö\�¡‡ T‡q:†a¯X^ }ˆÆ»1Kx1lbe�Ô¬ð–ééýôã›óP²ƒûÔs6?N‡�älÒß·‡b‹°´„LOc&&Ð×ïBo€È¡Yiž“Ö7Ý$\KDŽ”‰Ö@<`çM–‰["碇AhÁ¾CÈlq,ªÃ-9ðò–9pö�nu òŽÒ=zäÙà§v~�²È®"ø ˆA‚ǃ�J°>8¤è‘ûˆOš4›# o\óÁ%j=7sý_§Q0$r¾#¦¬›5ˆ¥òà+Ð~ˆ27ÿ-ÀßTKòd‘ü~^/×ó× _ø×ʵòõ:*z; ‡ULë0ù¾Ö‘�¿í¦ƒŸììgú‹«ÉÂWNŽ„÷ßp õ@ iI8!çÛ1:À©|Ë"k!}©áê a×1á% �ˆnß8ËeŒs ÞìH|¼2f¢g§ªÙ�“q4*¡¬´‰¢ÞQœŠŽ!q.gÙˆ�ÍæQ,Ê¥tA¢aΞ8ǃ'~\î§�FÌ<»ó³àYD§78º”ͶZfgë˜^Ï�æzŽŠp ðò�>z˜7ò&VçÊAQ…Çiµq¢UެÜRñoµZºaVaN¹�ü¿ÿ¡©*ç10�ž.ÝÊœXø%Êv— �`Ì@™NAc9Ӣ谹ö±WzüžÚè+þ[·žPê™xÁQ5Žóêó±œ*‡ˆÞTä^�2ÿŸ([ñ~ølµ$O&É¿ŠG`–;ø7\É´|¿«·òóòynô¨ël …|#zý1–>òš[ŽGnà@P°ï¸§eiýý£õÌí;ª³ÓÀâaØh‰®·à^8Ì!öÉa¦¥5û›ºçísµõÑ8¤}¶õ޲ËoÚ�Ù‰×+pìÖ»1qÄ1T"† Bˆ¢bD¿�¢ &ŽbõZ$\+´@q Ñ.Rä�ŽI––dìèéç|þèB C§©ÿÎl˜‡�úYö´Oí¼›Î'æñC7bfgaáÄË‘£iqt m�ZD¡ÕBô80+°Ý*�#¥÷ÏV`yMŸ&µÅ[| ¼¥"ø b‹œ�ÁÄ€�/ Ý�ÿŸ‘{^;IÈâzóÄFú²ÛuÇ%LO¡c-¶_Я9j!VmQEð? \C)°õájIžl’ÿ"¯åWôy\Ë縓çñ}l²ÉçømD”ƒ*/õ*­ ÀGõ[¶¿Ý ssèÊU­â‰*ÞT‘Ãð´ Êì…–{Ùüv`ai-QNÑS{È@²ÖaÖöç¾éýAx9üñäÖ{1÷ž"ánêŒ ‘²‡®^AÝ^Š‘]ØÎô™&Lbià$£çKÃÚrœlµšÏh¤”];_3 ø#Á?U$^ïå}ìã }1wÆI.�ïáuç=íC-hàPÉÓ*­–Ð:AëåbZ>rC ¥áïÒ²hµ�V‹2p�>ÂÖaQþû� p€V8o ²Öp8¨-P¥ÅÀ�sKÈÜzâÚ:T~èì¾£Ì�8ÙG輄¥ÿùÜqöÝ³Ä ¹š3ònÞ®W챿Ù^c4ŽÔn_ï cŒ§Û9—_ŽåRn7©¶æZJ8Š F C!h©DS$aØŽÈÕ¡O FJ �R~7ñÂm.;±*w²pÔ}�uóÀAïNq°vß—I63ÆÈ®ÿ‡£}‰{È–”ïÖºÅA¸DʨËÖÊ©l5?"ÿ«[V×à�á•à �GAô×1îxÁ_pÓ9W~ ÷Õ�ø óÜ/©QEc$ ȹ–§¦� ã»z#k×ß´6zåÆ5íçô­Ã îUâ ¢ÞXlðÖ\8«Â3ÍV¤T,{ ðÓÀ{ª%yêPÞ¼Wp©üÇøì"k“‡|j–(ÒÙ¦K˜¸DÖ_¼ì6:î èó˜5³Ì Ôƒ¼ñæÖ1̽}ôÀñ—!oƒ¸_Zzô@ËL=¢sGàÈÜA^?çn ©ÜEä(Š1A~Øá�_®‘Üå$‹œ\/°»…Ü©ÃcG±ð›ÄÜ?3­ï‘ë™úA~^&¹:‰HB<�‰ùÓ÷wîôGÞÏù‚˜[ž£ñÈ Do‘Ç9”Oô#¾ÁX\)ꎴïéO\Ø™:ð—M)PŒµˆŒ fRþc<öAJ@M‚µMúÆaŠEn={“{;¹W\*)9ÏÔ½÷OÀ÷P μ埙s^ükÊüîV_ËSïÉÃIÒ¿åCr#³ö×ù‘ª*´¼ºUÀ¡Ó‡át €9¹‰U3Ï›BK±3 Ô:K ÷O²K—t»$ì*"{Á^JÝíÒáþÕôt H°X5X1*ˆ@.eîŠbC•KÔpiaÐ2¿©‚f�¶DÓ£fV¸VøkÖîMþôôœüÉI»ϸcÜÿî™ÆI~¡¹Î‰%tzÏ?:ß8rÔŸmÅ£³-Ão�½j‡=îõ2l¼ÉrWóðý*ºg~¹¨™“êsI‚GS—">G󜘒 4É7³˜©¯Sγ¨ðeèÂk,IÙ×Þ0Ô‚¢Æaï|ΟúþmÒR}ðe�˜ÿea ÖÚG{üÕ"Vx¤ÌÆþ,ðGÕr|©H0ý,Ÿã/ªe9tD8tBÑ}s˜#”msoš›�ìh……í­#ãK­´ŽÌ ³'Í>ŽÉ‰›ƒìü46y>éÂn¶å_t—Ó×½:"Û±r EÜ.&lÏv`<:N‘²ÉÈjãÖ,èX“œ1Ùà2ÔaUDƒÁKA4ÅfÐoßÌl¢ú„Þ‰ûÞí̓ö§ãéúzk~Ï&ërnÏ+§6êMj²>–Zú?*ÈÕ(o/Šâ^§Q|Šx›–‹�£ù:ÑQ—¶ ¹×@®¤Ö€#Ç+¾Ú+_¦!>$y´ðôU0ê°yFŸöÞA½JÛ1zWßÕH�`Ö„é+=ú àÿ�ü/Pδ¯ð%#ùLÇgój>ƯTKR¢ÅÁ-ODfg‰" Æáéj1tª‡ZÊ¡ƒe­@™;W3ß?»I¾ÿ¹´y®¿¯u¸ P½‘›ì»[oý†ÉºÆ•|mŠ¢¿Ã®èîP°ÝÀØ�a[‘Ë€aD1**B�UQDEœªXÐ$XÇòQû1†¾,ñþ¶f¬Î¯Q$óÙ þªì’öÕÆ‘ê×&¹ß^îï¦ÍacrÉ…œ\½ó�bpy©9™<g½rõU¸ôËb.M¨ûH!ÀP�ZúÒ÷™Ei÷xàºZíkçŠ(¤æ Œ­ ©* |HàÕÀ€_~‹jo|‰IþJÞÈÌóW¼»Z’ÉŠÞZzÞ5)%ﶺä?Eõ@Ë"*GfenvNç¶6ô¡–¼»õ¦@«E«UŽnlÍ?ËÉ“_ÇŽ)³èóŽ`Ž�ÂѤƟ�MÐuF{“6øË.§¡{5árvcÌ™©#ÚÄŠÕR¡¤ì]è¡«'.Æ0Œè°„b—~³LbcÍX„¯ÇÄ<7ôLBl®h·M.K,ÛÎÙyÖYá„Yâœôhkæ×BáÎ\—X9ò_¾° yAnº|†q0³‡*ÓÇ{ïX�šf‡Z„�(Îã¢*‚‡o¾øcÊ –±Z–/5É‚·ò ÞZ-Ç#¤Ÿ?¤ä1í�záµGJÙã ÊY �œï¼r`¨ÀaZ´h‚Öa´µŸÀ1h͵8$‡àEÉøÀÁÌqàÍÈô>ÅAXšCŽ‚ðv/Œ#ëq¦ðì0Û˜ k\Þ/Ì%hÜf:áYj™Ðº‘ÃÚÆó§Dþ†L¾�UöFűM‡d K-BÄ*F1êÔèDLáqQåeªVÉbd-ö8ç{²ˆ˜u·αÎr\gÍžd­¸Í®¹õÞ(Mqää´U›˜�"ÝíØt•È*!Nñ^ÇF·>àÓ6]çp o4Eª tÓè@<]Å!XH²•oêº 6t> ›ñƒç|—Ž”Trºê\ùþ*Qö»ÇH´‹”ùtUÔ º]—¾xy›Û~tÃK,½¢µ8¶�É]WoŽÆ!´þ½©WxŒ�Ç7<ø?¡Ùªü‚’¯ðD»Sù{ôä­5ÿÄ=î-$–?³í/x}«õØ÷”ÿ<òÚRìèÜü~˜èuÊùÍwméí@nÂÆMÚF6ÿ6ŽŒž`÷ڻ俚/ð¬€ëë/†¿´Ï�0/â‹)™¥ë<ÖˆÖ£s #¬Dë­©•ÄG3ŠÑ1œ^.CŠ&Aü°¦µ‡1>¾0f|«v½ívVµ»®=»ÄòÐî×Ó<Ä9>¤óy&°ˆSÖÓØíýfªŒ:CÞV—»8™§&t'cd�Eµ£Þå > ®ë"r¬‚#´ö5s�¹z<Î!¾ëbŠàr!õ⬗|�à=ç‰þoÐ|ð Ö`󜬖R/ ,ßß\å3?6#›Ó°ƒ_¸Ò&;ïu±ìÀT#”m¥*<ú”Sà唃fn¹€à«0}EòþñÑ„#'ÐÃo"´æÙÜÜ7Û»þàÉsÇÌ�ÿÂÞïB‹ÁÄúmlæ·q„kÒ±+ßÁž8ňÌ0Âî �%·õþgü+û·\mF‡ž×ßÕÛfÌ8ÓqÔ=WöùØ>‰QC5F°q€ ‘m™²S"/3ð±/1nXÏ9ßó‹lèYÙˆçj‹ÝÅþŠYc3vFÚô»·ùõæÉ±"Ð`”ÔäëݸIPFSã'W,¹/[ùì  Gë>Õ4ÊõiSH‘<Ï4÷¡,´`·¼|ÜÀ‹¯ H,‰ø~N–¦ÔÔ(‚ø@óxW;_=Ìä]qø’{+¥º ÿ"ð àû�QžÉcT¨H¾Âÿ¾ù¬©@ %Újµä8Ø÷òg?‰„×Õ‚þQ?{½È¾>¤kä]Üñ^›;Yk2,�Œ&MY¨;ŠÑÂŒ¥Þ´OºõÞÝÍu×ힸÜ_j—¾î¡çÏößVL°«h0NÃn3Ih¢âÁÝA(ÎPÓ)ênõ8MªãH¨«�(4¼2ƒ„¯`Š�« ±¯Jo5J‡ogÙÇ3«6²ru�{‹É)ÖŠO² xß%–!øTÀ±¾Kž«Ë½6=âò6Þ‚³ˆ÷�ƒúÜ)X�XR[ꤥ±ðLÜ7!§ojƒôGJ#!N0ÓWäÛ—ôÝ |z)áh7'˜¬î´ ÿ®üÍ”ƒg²ŠØ+’¯ð¤°¼Dma8„UÌ÷l™ÂOá;qî=C¡6×olÚ^ÉLc˜6]Më˜îXjÚ¶&¬ûÐÌ€¬ëíú1¦È%GÔ⸇3žÛêëîŽì7üx#±ù¦g¹:L¹íº-Îñ¤}�Ž+HsÃ8u;I- '�øÊð†˜¦Ž£¦¥4°QÔ ô‰ CÔð'£Á"4b”Ëñþ*ú’Pð¤ºAÆmæóN¾Èj~Ž;9C�Ü·éùE›±æËÁ»¶�'ÎJð@žÐµjq@þŒÞ6iBJÝD¬Âüƒ²Èò³ÓÆ_0Cã ÏôÇ6_üžµñ½l3‚ÕXØþNì~â‚߬–¤"ù O´ÌÉ+-Õ�rXîá­ÿVðoˆFþÛø“m¢’Ö‚íºe nêÝ”®‘tSÈ2íÔR íºú¦—åM';¶³X÷41ä¨ë«õ�"wŽáå˜uV]§îýƒ¾K¬1$žL}Óò´–ý&>¬¥;ã¯äCæ2a‰Ûp:jnŒžoׯù³¸Šñ3ìb\v qà uviʤ81Ê.¶c¹†QÆ5r‘PñôiÓ Kø¸Jßœó™Yñ]¿ÆªYæT¾jæÙL�Ó ËäyÈ}©êçÂ37påUÆùûå ··¦eáúdsí××Gnü°MFh4R£Uî½Âß}ü þ'�;+‚¯H¾ÂS„Ã-¤Uv꽑CX9‚�s�M¯ EĨäò©{i»ìQèÝŒˆG22u'7_!€§Þõ �Wß&ÔqÚ>B]<_Ï ó¸.±ÞuƒŽô·§>?Œÿ|—®úf¦qé¸w¹Ú4·nsq¸¨3i,pfj¬Þ°ñ ìŽß¦ý4Ò(†Š)–ˆP�² xTR­á4U±Û©ÇÝ$¨Œ£ &”˜ëód³Hµ¯F:.èºæ,²ž,qNlÛ/§'XʾH›.><œö™È çÒÐìõ@ÞL%íæœghÐ6&@aP«˜p”ñE-mÁ赈åc‚Ó£ßîÒãÓ?1Íò¾Ô°C–8ЂµX#ˆ�„­q³*\€g?Þ8 ø*âS‘|…'e#?øfàçP½¯G€¸¹eTç­î™×G{°~ë‡Âc[Ì<�.VËÈôq�³Á{�Î×/|L¥KßC¦ÚthÓ n¦˜2�·mûà™Ý‹·æ×ºé¡‰|¼7TÛÆv¿Ëæ±iNëíú NøB­~]²Çl/ƇgÂÎþ6öæ–¯Ó¦mñÑNê8¢€ªGJ¿tÌ+Ä\lÌ_ $1c“3I‘o˜MŠv~6_c™+¬º5Ÿ_ãÅšCê‚AlQê–Í}OcW+eÐb#•Ðß$¯Ñh&˜ìÚ?Xåã�éDØ}Ǻ C"ˆ$**U›\…ÇãrÊA3 ÀwÕ’T$_á© ™½ø9ÊœØo]¬ˆkÚ¿¬@$™ô|x塚o>\«w Ù°¦4őѩ·ñJûýâ~ÏvM°¶?yFù7vƒíæR†‹Ó`‡:" }惵GÜõ0íš~*ÖØ]lȦ5ŒìH‘Faâ^E¢F4Ëb¤«†� ²j;z‰¢ Æ(ˆ>½UÞŒÁˆ€A£‚AD1C)©/g-›™kžZ|èÃm¦–üޝœßqå[4D‚±Xªœ|…Gü!`ø÷À:•REòž\þ‚ǯþ/àà¿]ÌT½Û�øa<™¦n%t}]s×%ÍÆ¤˜iÛ¢Ñ1ùRÝ“+céÖÁO¨ëž > ÈØ‡?Ðéàì(Éz�v¸¦×ä;)w[8žãÀ!µ!l>JÂö‘¦>¯û*û¬ðZu�XÇ¡¨E#¦ʦ«©lÃ錨Æ`06Ô`b¹ˆæi|À ¦!¨R#H&1—ΰïzÝ0;>º±ûÚù�íŒ ®º=L_êÇ4)ç¾û€-��çÓ÷*\vÁpú‚­V¡"ù OâÙ-À¿~ø<ðN.réÈR¬¦#Þ!¾[�à Þ�‘T§‚'“c+9‘å¦zºJ{1ÖiÊròöp¤kû)õBXˆLeûvÑ%âœàƒl:<)}N¯÷Èìä÷†a& fRFãNµ2®Y’h“›éú%†“êùˆm°³ØÉ ‰cT#Q & 墧«5h¶Ä’r h{‘•xûOLÈÃ/¬éÃ×5Îìø±…Élk\î¢à ŠÄ’¨¢*¨5ðRåä+ÀNÊ"» xpªZ’Šä+fö?<FµŠHÀ›„$*1D‚ X0"ˆ "ƒÜü`¶2¶ôø ¥A€ôç¶40¥W¿åÙWdQ¢I¢¯ÿî1_¡"ù O’÷¾e-?›rlãÃÀ­¾Ây‚W”Hô‘`-ÎX’àñ�M6?yÿ%‹†0ý™o=Ó<{ �ýË ¢ln¢õœè $Ï[�ØœPSL.(Q•ˆ"Ø’¯#eÛ¦‹ÈÀsW)ó÷xSzð6@4jÙnX�Ÿ½hQ~Š2Tÿúʃ¯H¾ÂSKô×PVÏŸ~¡"ø �…äáUÀBÖf½óÁÿdo–ïÜ{óÎ÷÷yÖ[„d#e·Ö|+t�Šúâ Ht“�äº]$Ù»‰X�Á‰ˆÔŒáü\y�‘¨€±Øè €¯"ù‹“àØ|ð…ŠÜ+’¯ðÔaÏ€àû”¹øõjI*<Ê $@ °¹ÊêÆ¿ÏrÇw�¦šK^Ô-ˆ›ÐaÒO$˜DmÅy) 5ŒˆJí�аC¢Z 1¼æDÓÃ�ëkH’‘°‰º Q1@tãQ 4 ªïç"Cøà:àµÀ±jI*’¯ðä{î[óNà÷(‹ÏßJÙŸZá -<…³$2 x_ȉ‚Æœ|ã–7;îøá1B�ÈÃñê¥÷- kO|ñ2úCëhͪë;Š"ñjlQ‡b4’�‰A4bUp5Æy'‚‰eòMDFÐõ¨“]�¾ÍHL¯ŒHL’q}0EY  ¦¬ß/#A(sù¥2Ÿ,)MÉ=Êtž8PO %ϵi‘Ü•òÌiÞ�w&Rë6×cjM„›DR„ñ]âÖBç?á,uë>z�âR!Eèæñ¶½Àžü ¥þFå½W$_á)"úÝÀïãÀ�ËÕ²TPE�%± ¼±X„‚BñìÍß¾ÉgÞ%Ç©Çk$õ޼[êIx—‹Ãc�Ñ¥´œá€'ÁçàÑgXN¬> øë)Cõï­î¶Šä+ð`ã®.þøu¤¹Åc7hoÛª|·€˜‘såóQ(uþ ŠÁXŘ@Œ�¤Ìµ×jÔòº²1I^ §©uj¢:�·¨1åTá ˆ&ÆaÕ ¨¡‹˜IÔ×Hº–¢4Ø ql�Ñ5öô¯æzFVXꮳ0Ôão»=w2/v2cVÈc;M— iW¥¨R;w±™zã< ©´ñÚ%¨'œ‡Á�÷cønª�kî2H‘Ü:!ÄÓñÂ�¯^ÝiÉWxò=÷­CeÇ€àw þÁjy*l!z|ÍQ |gõ„ùO|]›Û~bÝP÷D^ñSg'.h䶯 ûHêÁQÌÙ"{#ƒ¢¹éG%Š/¥{ %8c±N#HèãMÍ>âm ÆÆ€@ž 8H&í“h‚„Z 8 †ºš0DôÕšq˜2 ˆzñ‚2ŒÄ¯’=ì—ëŠ`™/²U,Ë^iŸÊ×d“ץͽÌÛûY哬Œ>Ø,ºxòf0]Û\éº�âÒÜkX'zŸjêa$§­ÞA°HÐfÎm¹³‚÷Ï¢wÀ÷S¶ç¶€ßß QuFT$_áI'úiàÿxð¿ô;èÕMl|>rõû7š/ùÝþÐ(c›}2[#é¢$É)|‚“A?ûÅaŸH•Nƒ Ÿ‹òˆ‘°Å ‘Áìy-söPªçDPc±©-v‚–3î¤O¨)¤[¿P ¡QZFñÜÊb=g!õc÷v^™=®6÷ÒÐi6;Iu†$4ˆ�ôùP‘1gj»¨…íÔã´Iu"ª IMÇÕ™&ª IôMS Ê šyÛÏž£„MRúI?ž‹9KºÆRܬ-sÒŸª�+²FÖk7útB 9›Ñõ3âH%§«ñ«VÒÞߌeMRÉhkÍ ë3‘æb)ä)»†�/‹Ô•§²¤ L×9èú˜‚¸éæDB“tG×å«hB×Gʇeº¥KLI<9¹þoœ=ßL)róvà*¯½"ù ORà—!³·Ç«%©J-z‰��XlŒ%9&y)9»|ìÚ5þì�3dMCrVyþ¯.î~ñ'ÇrƒÓˆ%¤ˆ&”3äs¥ðy NíߟkÝ"é¿Ë*ý;ŸÛ"÷ÇD Êq·â‚k2п×Ç|ž1 §Oæº:ü¡úéôCÍÿw™vtMo“8ãH×®±“ʼnt™3±“Nfε‘®#˜n]‡¾5ÛÕÝŸþ"ãÅ8CbµŽ€‘˜ D6ñZ`´FCÇI˜¢o¤s%ª�)T¦ûªW£Ù«%é$ýÍ¥"ãܺZ%ËÏ­¯..ÙU–c›vñE»J»: cî Ó뙜¢�連;ð�Ôà<°™GçËK*uß”t½‰ãáhiJ§]ºŠó’†®6O�…æ`}r¼äxÍÁyÇ¢Cò kÉQòÉÿ—ê^ ÞA©¢Y¡"ù O¨Q Ü|eþ.ªb— ƒÍa#¥¿&±”® b�ùϼp…?ÿ�íd#‚l(Ï˶r¸ï@K yÍûäõõ1BÎ1ÃØlÆ@§î"Bæ2:Î+©µÞ§¬¯øí÷Ó] �ó’,ºÐqupñc™ðÎp£ÿa†âL½ÉD1ÅŽP3.aÒ�ã,MÞG�F_‰ãLÙá0‡™q£<'³7X›^�ªC˜,¬La“öD›gÀ#A2¹1ôÔɺ º¼¢ók+}Yugâ)¿lÎqÊ®ð©î9w¾–¾ÇvV‚œ£«‹¬…Ó,ûEΰÌëy´‹ôç¹Ü�çvÝÅ€×`,íë�šÁlZt�42šÚ<äêÖ}´µ8ùÂõ[#ª¿ø”,©ˆ½"ù O�“¶Eð¯Þ |¦Z– bK^@­'œ¹ãY‹¼ÿ�;“͆-j ÊÈÑ/yëÂè8;l—bÁ‘�G "©-£=�MHj`4^|V¨g~ëž�£é›’ÏŸôÖ!Ýt�´�iB\[¦™#Ë\7‹Žap)âW\®ÍTwŠIfìÃõûcž‰ºx‡»9îáÖÚNßè7C�½Ì¸a¦Y£¦'õ¯‡oß¾ØíÕô+¥ÁÕù“ýq3/‹ÛìwK=$ôCÄZÁ’xo…Í�ˆ„ºÆTØ�ÝŽ²•ç¢(…¡‹ÚúfÔeñÅ’+|[2¿&½|­}jx‘]›ÏÚ5>Ÿu›äë±›£Þ7Rñ.‡Q,]ÿD=þ2ˆnüÏyå½W$_á©AB)8ñZJE»£Õ’<í¾'ÈeGÊ^uU¢äÌ�ÏZâ¿·“�[$ Ê¥¿s޽§Ø¾‡é`1‚øf�!<š:’š" Q %xOŒ¬œ×Á¹h�yW|¦ÎuÄÓ�ñk`ó•áP²Ð)Ø íÓšã¦.�ºO‡Ìו¼8êÀ³Ü\fylwfL³1o†Û.cÞºSõ~vŠÜ9/õ£õÅ”¦´éÆPÏ$o.ˆ 'kÜÆJ�ᇲfç8ß¡ª “ŒÇݵ”}'ÃÆ†¡¸ÎßjÝ}B½Œ2éw1¦;±la˘&$*f›Øþ´žëø¢a c Q½\ÚééËd“ïÐM"Ý «tìkaÁÍwådwÑžd=lÒ·]|8EŸ.�¸àLD¾)ÞˆrkÜÃÏðöÙ>Ìf/¨–u“åO•ÇÕI\ðZz*ƒ×ë ˆòÂwHù¼<úcP-Çó¸7T¨Hþâ‡\°þ-à[(‡Î¼·²¤ŸÙˆZö˜»X€�ÁèÖH¨ V•xæ¾m‹üo›¡½ÓbÏ*×½meç+Þ7ÜóäIBª� Ä:j¾ÌÝ6ôé{T¬ .¡Öë³iÉŶNu‡d>S(Uí(9ZÚ:k¶ô£<Ð!Óò¹óý¨‹Ò%zÚÐ&tÚ„­Wx�vÈÊÏ)ߨÙcîÙŒŽÒÅóñ/¶žë4ÕÅ×¶³ wÊ/»6ÑyG§îÁ×Ñgg ^ÃwÉ¥ü McªI™nA¬beS¢ßTGS‡1vŒ¨¢!�Ê¥b /#ª²A ú²â2=ç‹äï ׄ?Ä4/1}þ&|óä!’ÉxåÁŽ»ŠW±Èb<Ʊ¨ �ˆ;ðÕ˜çXGуKèþƒ-ÝÇq9œ`N�Ï"s”݇["ì›5Â\Éù"J«<çenNŒžoº@¢ 2;‡ì?�¶¶xËH¨H¿"ù/‡,¥²Ô·ïÞW|¡œÏL™†Oã[ #ÈéSÃKÌýþ®´†EâÿÏúޝ}_-X$1Ôhñ‰yü½-�h#ZÇ9 ï#Þ•ýì¢ÕÞ{êÑÅ×?ÞŸ÷™‹P—¬ŒyC»·û)ÉîZèµýÝÞOÊ8ãfZÆâv;5#HÂ{õøÈºÌ¬�Ë�‹SnJGü¦å:ÓˆWiO‚Å"¢Œ¢Œj¢—x&)ˆov}E"cá+¨­|XFV–îûܽ+÷:ó !>Àº}X¦Òûh4çù=:_Þt½Ÿã �;Ò®Àpìz˜o©îk)Gm=8§Ì"Ì" JKT‘CbZ ¢[[ì°GÑý­óñ)£U9REòëù½Õl�¾w@ðT|…�#ƒ�¢¡Oß9 &çîIæù¿³ƒ…«¬°Jœ¸½àkþûzQcR”HDƒâk–ä‰ÚÞDµXO­Áô Ô¤¼©vß—YV�� %˨g>â< Í÷¹z§þ¹¡N§Þ¡N„ üàÛ©ãÄÒ—.Ãói³ãrç£ë‹WÄ÷†Ø7“ê6ŒŒQ× M¥®ܱÄú¼8Å¥r«Ÿ6ßIJF=F†433ºÁÕb"HD ¨ Á,oÆ¸Þ ¼Úlò/Ýi~èØI±‡â$9§Üþc‹þ_[•‘¯\‚b“c_Ìö'YšCg玔[¹Ì˜¥Åœè¬”~ú,Ê\Ká#Pi¡­C"û™ÝRT¨8¾"ù‹˜è¾øàðÇÕ[á1d¬ ˆs$b0¹§îÌð2ïÇN³p}-Ê:yKÎ�_[žÙ[ÌÁ„‚Â’X’¾§�yD‹þBœÚ�É,æäåôëQsñåã/f4›™Íó,zç¤$}§/õ®×”)ÉéÒqêÙ0K§éºâêH ËYpSر6q¥;3Û?“i–þtþŸ‡v²{£Ëž€¹ÜŒÄK�åY>2ƒJÿÿ³÷æq’�u½ÿûû<çTuõ6ÓݳÏd2YH`�P” ÊÕ+^Å—/?Qñç¯ ¨?¼êuj@vv%z_W\Ò"([1‚ K a›l3™Ét÷ôV½ÔrÎó|$ÉÅSw Îð¡·ìâØ“+hC¹ø¯–«?ü¦öØ [KG�bðøÜ’[Áx�wÛÞž‰Áè UoÑšb�A\ìJ›¼ù‡†’aʲ¥Ýï|YR¶ðŽa(“¬ \l92¤ÕÊ<倸2lKi·[:|Ì•+ÙQXÄ-l†dÓl¦.[QÍ�vøEÚ¤¹'[Ò_cÀ7³Ö¦×hmñ…í…¢õ³OæöknÓ[ùiQ&½ø7 þ:„?"Ûz…nš¹›mŒûm Ú4ô"J¿GÚ~‡vØË€LhnF1T±E¾6± 0ÐÆcÔ�é�i1ˆ2®BŽ`£Úä„é"množßœ·ži?uÌ]täG'OØ 'ÌNZaf¤ÅÜÌÚoä�æÝ̹ëÀC]Q 7^iXºQ¹ê‡,|°PQuDë±^¿Ž*‡…G®³ôÚðª5Ž[P¿Ú-êñÔ ƒ p­bo‰�ëŒéîê‚$òç·ÿ}„nv# žqéÔœß8‡Ë ¶t”êÐJF… ö¥fØ“ÇÌïyÃ6Ž}w]„M_TûÔ7�d« šeT�£”8é �m`åì¡úJ�//ÚPÄQ²âýYÛÔ'•_V€µŠü²+þ-e¥¥­uk@¡„rY{+ÿã �ðïJ¦ ‹ÝçZ�nì÷"@iñÊ’Å%–é€/¯yÅYýŠ—PÌ@8?¡áæZ¬‚å1älÒQnÊÇ™ñ›ìf¿W¹ÐWÙ«cþ-Ù'Ž1mRõ�aÈ1bðF(�—‚`U°­ª0¢^ö–‚¡ƒa P WJË E9âí‹|Næuà7æ(Ë/Ó�;©Ø»¸Íáæç¸Ç?~±Í Vô°r †7\©õknôuAëu‘›oí’'A¯¢îq($êÝ“Pu)ÔUT�­†CuzjRÃá¥'óÒîSîNjH"Þò¬7¹yiºS‚ئV¡bÉ}\*çÎ{üì³¼çM[åè÷Wa­|ÕñäWÎLìagî¡­8ã(M\Ì|_~_\¥Ä[È\ë*a¬|âÜbð’x�9 Lݯg»Z}x.)€U¥35y98©×KP=ÃæÒ*æÈ3±{ÙÊM\èGØã‡õb]u8—mWeÝ�脯j…L-™P Szœ·™èˆ‚úS «ÊN2,YÇ"ü˜d8mãi‰çrióX]¤y÷‘ÜsÌ^_?æ*-^À‰üw™yýÓlfq�K›È‘òmü’ýûýaS§®ì?(W^SWnAëRç0É~½º~5u=hà°†©¼Ý@ØÆŒ‡¥(݃{^ŸI(rû ð:`uƒ¼¾Txw?y ï4æÞ½¬…nËö ÍÙ¨ùìOª, {Þ»ÊS^=;qÑê˜L&˜–E+†\K 1=y±XçpºL9àW!+ šmT³ó,¼{�Ùü&aÐÕ«�ÛÎxüÅ„öµÏûÖDþ4��Éx};HÌȇpÁÚ1ëùëèåÖ£O\ê± ‡nNµ7"ÜMÎ�#5F³!¶-�1ï/Ę}Œº}¬Ê^ŒìÂÈ¥GÆhŽ*ä’cTÅ«Šv‡#ˆÇt_‹ > kúÕàÈikƪXšŒ2§Ëù wÔTý�y…;ýwT—¸dlŽÅ²…=Õás”¯>ÀµÊ$èÕH÷”ÂõçßEÈÁß üñøÄA JcÉÐPp·:Ocñ_^ZáóÏRV`û[•ú½…¡ ÆŒ ÝÏE0RÒð¥„z¦ûJéq¾„ßóutqÕ/~J:–a’Áßç ¿ö þ~x,Q»D¢¨Çf5]½–Ó ÎÅÅBªÂaàæCH}ò õƒ”Ck}nêpàu9¤õºð¶g;—Šç?�y®½ö8Ϲú&prW™�±|Þû„] ÓÚœ�µÆ‹ûhT÷ee{GYØ]Ú‘]J¹�*›Éu CÍ‹>vá)@Á M,Ê€‚2-»©W ¨oãÛžŒS4ùúÜ,è4bïâBwÛ»>79ííIÑ÷L³zõ9³{–hü¿ЮדȟOüwrï'åéÔœÇb.ëEvÝÆ3ÎQjŽ‘6o1EI±øáŸý¹a|[©|žøúé±Ýì*Ú´Õ‡ÐzÇSØXh'Üû¬÷³b�+¾ˆ>ò6[¹>w®Tp‘Tx×ï /F�W·?°Wµ3«ÆcŽZÄ÷ºûë‡Kwö‚®{·“qcÝ8ˆA9tPž/R¬=ÉÕWw+ÖýUz7s�ÆßÒ½ø|¼æj¬œË7ÁàâI6ñÝœ-°­lè^”}l¶ûð²-·‹aT‘Û½j‹�âï0ªb­`‹Í.Å(´Ÿ ̹B PË2³pWfëÿ�Y~Ä•?M•;ÙÅbÅ6yDu•Ê|çÊ=”?r=ñ>äàªôã×…f@ìG¸áiWÁU×y­×ž†©Ï l­ WíW¸EëÔÙ?‰\}K=œÛC‡tý=ê`ëÖYù^à/þ„� {%°@J‹œ×x�7 ZâJÅeyfÉ ‡Ãb‹­Ù÷¿Øsà Ç�[U_¹]¸âOæ¶8¹Åw(­`²ŒÌ9\o¿Ïoµ÷§7ˆ-ñ¾{Å4`RKÛ¾¦Fèœy ð²\à¿©{o†À}3ä´K癿"×]¦vú‘q�Ûé´ƒ0*e|à൘ۦœ¹ànDËH¥ÅngõB·“Ýfž½¾QÙ£Æo¡ã÷bÙA•!ŒÏ�8CÇ‹P¨bJkT¥ŠÑŒß&RŠœ/<ƒ§#Ê”¼ðŒ—sœhßAign<&wÞø,Žñ_ÍÛýÝ7TÊ“ÛZÌ2´u™ß}vû�×<ÚT©úË8d®â*•ýÀÈ�Â'Þ�ÖëžžNA“Üþîú¡5ké0È~D®F}÷+*IäX�¿ø«ð!ã0aJFøók0¾ Ì ™lì2§VÑfIgî}¿Zrý GEWÔ~¹ä1o�ßòŒOªÁâpY…jÑ¡mÝ}wä{¢ =ܤð}Kø�‹£CñõtJz¢ ñÚ{àôàþ`(\}7Z¿‰ùCu�¾t˜Opûyº~äÌ5W’³Âw2ÁçØ fFvâüEvP÷z£{EÜ`XQ/¨„1{Ñ�6q©½‰e§ZÙ‰¦ 9¶eã–Õ´–…ÕÙi~ñš»^ü"æ\aîÈ�?¦†c#›8*«L�.Ò”\êÙvļRüÐúÕpÕ�I³u]©‡¿¯N�kUÌ-ŠÖcÈ$‰üÇ^à/ãý—±6+q¾£„VµÖ„)sNñZâŠ6í¹÷ÿšçÓ¿¼I´PÝ|cÁ3~ofââã#y΀kÒ̪TWÚ¬Tí7)NãÕ(õ¬ï{�>ðØ(ð_N§¤ç3®È$˜[@ëÝi¸‡�CWK�I­ŠÉ.ÁQ¿J8øÊ·¡¥ M`¦^çk;w:ùÈ/á''ÁÕ.ÍX®äºrK6°‡ÑÖ]\l+ºW7q!öøœ½êd N'Te dXT/‚[ÿ²ï­ Ã*2Īìó'o ŒÇj±´DC§ñ\æEŽÜ!mN¼çzn›¬q„_fæSCœ²»™ûç§°ÄϲÊ,¸úiòVù8/ä*ê±5Pù†!Âò¸AB!iÊÁ'Öñ¨µdJè0ç;Râæ>ô 7üê¸ñËê‡ovüàKg¶\rj AŒÃKNîÎ6QîþàPu²6Ò35¯ïO�ÿ%àqÀŸB7v›è%VÿsY_P×Ó?íÝÚA ‡aVžJ½îŸO]ù%ЃGŠI(¯¾î*iÁ2w^u—«×õ Í 3²•­f²>™ñ†Éu ËnìN–í…Ttœ¦^ŠÑÝTe“·åv,ƒ‚JÌ›5@K0ê PQÈp £Z1—bÂ(­Xò¶ïv4O$NøŸ"´bûKà锜{Ô©–ëÂ2¾øô~n€«¯�DŠœ…ÍzDÇ9º81¸ÀÎÖ»¥ä"Ÿ±�ªÙj²â€G†Qc´Ä$‘àé÷®è6€›âþOör÷¶…~oý-Àå1"ð¨h ÄcWc4` ¸»'p2Þ.E£ã[2| ív“Gw?q%ÎŒUE3‹õ@îàøõ?0Çû^¹…2‡ÑÏzžöÛwO<òŽQ©0R²•‚•|.ßR�›ÄùÁOD�ÿ àýétœ£âqX<±Rpm•bý0uêÔ¯®s:Pïp�%9À«û¯^íNbÆæÕÌßíäúýػƇ+fiGç—&‘`Åýl÷{¾·ÛpGÜz£CÝ!�`,FvÅÀ…¬×l#ÿ !Ô?O-DCàxO„`þ,¯ÑÇß•"÷×ݲX§AàsKV ~ê†'ÌóþWn“rT4;O|Ë©�Wܱ]ÃxY§©VPŸf$îÁ³€ï�ü?¥Óq®»ó‡Bi@(+èö ¨Ç®Àõpý¨s�C¡3‘CÕÃaáÆ÷©¾æÆ®eþºëøjù îF.€BÿLªQà+ÀNàRÂ�Š uOF) ´âñ£1bp*nÓ1âÐ$,ÿ+{ Ž$þ÷‘ÒO>³Ø² 0âÆ+çùàë·šÕñr.}Ïê–ïüÔP§ cc¼² ]Í©%-±É“O¬ñƒÀ�Kѧïâ9Œº6:x·(Ô5"h÷š k½'ëh½ŽZóÚ„Ãa<®;ŒrHЧ«¸$ò7* gñ¸{·ûx‹ž×èµöŒç²Qä7EQßM�TÆ}—ÃÑH°1ª°·YB`. ÑhÇþz�•õÔ†'äÞ½€ZÄ9%j�ã7W#ŠÿÉhLÅ­Ñcœ³%çQ1ˆqŠ0¾ÄY°T2ÌñÏ\1Ãÿh+Ë[�VŽÁ#ÿ|‰ÇýíüÀ&&$ü{ЭœW}p{Èàâ#ø‰idu�üK�¢4á÷‹OâFã©„iqþ&yðç‹e'g¶ê�÷{[ßó˜Óçô>€&‘Ot£­(Òr�ÂÄhÀ6`"»âíãâþÑø!+£øÏòÿÝ"ÁnZ`6þ®¾fuÙ:‘nKT}èk•)¶%èÔM—œâ}×l“åMF+·zžð‡§Æ¿ç#CdlÍ=’åT GñP¾æÂQ>î ÈÅ·c>»Ÿâ —á¬`5O>âã{�ŸnÞ™>qH"Ÿ"g úÙŽï�Ü›“Ø­ Ø·íq»¤'Е“eBø¿+ú§z¢Ý¦AúÂf­[˜©orl–‘·;¸©›/šáÝoßn—7Ïœò¨¿]Úú½‹±Áó/K #^Ò8¹ F!/3´(K/Úi'6 W?|x<´†`"‰|"q6|ôÎoçžS°L÷�šÝ\ üàKÀëãg8‘H"Ÿè{”PÑ߉"}W¼Ð�¦©1 0Dûï!n�Áw°¾ŒP£1±=ÿ™x;× (X_!ðí1€1k=´„¤š– IDATÒ9Ú|à5ãœ|l¦Ù)ô1o™—ïlNìfs šY2ŒÇ Á@Àb•ЇZ/ëë&ï^Â<C…Ì4-‚ZƒE“È?Ì\N˜(wsø•tJIäçŽõF>wqö©[CQø7Å(À � Â8Î Ö#ÓÍáo°Þ9°hpúê€{ˆàê]´·:(À�WAhîÈŒÎâ/zçÒØ÷¼Sí›3K®Š–.FL�p1ãB$@cȺ£_�p"êñdXh–sƒhÓSøƒ1©ýÃÅ>à…À×€?à(JM$‘O$ VXot6# '¬Ø#›£1°“Ð4h‚�è>×ë«îf}¥ÀI á*£bòF^DʸôÍ-y¿ã­¡|s3eÔ¬w8 b ™ÆV·ÝÑ0%xbåŠ[7%¬ypBù"ðÉ'áþã105N![µ˜B’/ÿ0 üK¢�ùš$ð‰$ò‰Ä·OÑ#Ú§iëËG£0#DcàJNoìí±F«yŠÍµdUñ¦ƒ ×\ô¯ °©XbÅVÉóA‹’B4á¥ûÅHßn¤^�èq?(®<œÜ‰àÈ;žR)AÄ'‰ØüOª’W%�O$‘O$ºM$|�pæê¶ŒÐ>ØF#`«mòøæGù¡…:ÛŸCÖº“®ü•ç‹ /~o‡¨VF0Í*K~_ÙDn†(ÍÆŒ�™ "U¬D=jÖ_ îA œ[‡aÒ´Ó’23d>tÙ3iÜìCÊNà× «D^o‰$ò‰ÄCÄ™‚WÆ}{�ïžRtä‘sïgÔîÖB~µÁįPÑ%Œ]DWf(Ý)Úv iÞ�kµQ<ÖŒ1x1x­Ò”!4Û„µØ| k1RCÄâÉ@LÈ™k\ÓM’0¥J¹×yz¶?$ÃVë/`²ŒÜ�¥Û�vgÌ¤Ç ¿3šü÷WàÞHè™H$‘O$&.'´} ¡Ï@�ªu9ÕK‹Òç d€l%÷£ÀîPý×eÔ£®Àë2e¹@[àWÈÝ"Ö­b]éÜE¹²D¡-œqxDó1ªf “mDì0J g†jd¦‚•,~‡C®?ÔîEî†(´;³Òb|�/=Îåñ8<^LHœÙ7Óh°#ÐÐÑ/<õší 1Ü S$ྠüK©¡—¦C&I䉇‰ÍÀëùøÓc Z:ø0\•üÞdÎÄVɨ�UÆPPE�"ZPøu-¬o“·–éè2™?…ãeq-qåªñb*XÉ)ÅÐÌG02ˆ“͈� 7£3„·52D‚¤ìà\�S°Æá¨DãÀ‰ßõàË’BBcbH?æ5”`¬OQJžý7cø5B]Çï%�O$‘O$~ž}V�DE|µÔü˜è˽©œ÷¨‚'„܃w,H ‹+¬©�eÃá9*JÖ-ÎÃãUñêQJ�.!å<¥›Ç¸e²bçV©ø£HûfÄ·Â<5´dŸ�“åcdvÂ0T+Èx‰©ÌŽÓ1TŠŒÌƒJh`¬êp¢�ÉÚ:~U�]¯T<�äÇ#&¢?=ø;Ó)I$‘O$6†ÈŸU¾ Ýî|uN„ª”xѳ·�ƒ Á ðŠ71°Vð—Ñi0”è-wŒØ83²†äÛɬïyÐO§m m’¹Uª4P¿Œéœ¢,fè4o£ô-#›`™Ü-åíby+ÖÐÆfƒ¨Ù„µÃdR;°þ·ÇÁ—"&'^Qºåu/$©xïìÔ€–o¾¸5�’DùDbcð9àÏö€¢T/Ç™*Õµ‚¸o€t‡Átòx·ÖôF¬`¹qõ±ð­×cöŠ®O�$¸Þ .L°b1R#“Máh,ÓP2uh»ôúó�ÝöÕ¶~d'ÅgvS¶–1ºˆ–sXÆ—q Ÿ§¤Bajx;Š1›0fµ£X;Œ‹Ú J†ˆ`I6�nFUôGÒ)I$‘O$~º²}êÚuWsï¯`Å6›ð/îUæÖàÈš}¢fÝówÝF9¬Åýu­’�0ó]{^„!¬Étí¾é9DÅbÅ‚©âÆ=ò('vjTíMOB« �j çWpÚB|‹ªo൅i/áÝxm¢¾I!޶T1Ù™DìE¶…ÜÔ@j8D@$G¤F.ño2€úðw¹ž¿oí%Ç@4¼žhåˆÐ— •fhvB³-«冮¨¿LÀôrBG»D"‰|"±PàéÀ�sÏÕh `GùÊÈ£ÉÆŒGJðë¾öÙ½øÓLˆ{Þ]¯P—{ZßèX½73…õêw1X‰Íxœ Æ£¥�‹ak‡ÖŸÂ‡ê{­y<§%BAÕ·À­àÝ"®là‹&Ò¼�V,™ÉBzÁd^Y1ÈÃØ1r…l±UŒ7øµ€ÁH4…º¯ÑZ2«HQPA±íÙ•b¸¬²L©÷gôÀC ð?KX™ñê$ð‰$ò‰ÄÆâ{�ÃñbÍi¾qà«f„wŠðÓçr�ÚZ25kËñÔDÓ!ë9!*¡(Ï Ã”À*®lPú%¼_%Ó9 À–3˜ö¨vPߢÀQÚa¤2F%#³5¼lÆÊ žU¼7xïñRÁ2HÕ5pº©eXÄg”UâsàyÀwÅÏЗÒ×)‘D>‘Ø8<xE¼XwÃöÞ <&^´gj0¢ÂsÏÕ…c êJJ ËéÄÄex*!µ —ÐùØ”GQ1Ãä•Q*ݵöÞ„%†¾MG;¨¶ömðËP,P ”ÍiÔަz,ƒ3@™�àò1¼_bÛê ߇e¦¤h¸’6^§¸ ðó„†Iš>‘D>‘ØX<‰�?Í{œÕ!ôo_;²Ñs×��<#�pÔ êg=b‚[/ð‚b�LÃPV øµµô.g,V©™¡pμâUÑ UªÞ£FKTW(uÕV”²8IQ.2N)Ï´eeÜI»"¯ŽNŸ"8Lj)–ãÖ~ˆþ‰À5ÀÇÒ×)‘D>‘Ø8<™^e=ýý¯ÀkB¡ØP”Öï!y0hlôÎךátCø¾Ûõ.îËXóî×"BX~§ñص^a®=âQ0Rc@·‚æH¾Üó|ºñwú‡í¯9[ÓÚhÛ4ÇÕ±•0èe¸„мh¸çºÖŠB‚0UðaJáR4Vã1÷w �ž�Äw…Ô(‘D>‘ØHüËÎø‹¢¿|¾žk°ÝІ—¿v'–õÙØö¶[{íËZ¨£·#žö´Ä]{ÀbÔã1€G�C�`¬"¥Çùc,—5Ѽ™/XšGý=…4‹ïá`üîÁmÀàŠøX%X%Œž!Œž&ô’¿;þì¢P~“kèOßþ“À'’È'‡Çrðìçà¯þw�ó–ûÒªví¹ïÿVÎÒ`¨»ÂPO7B×! ýÂÀàð¿³XŸ$x÷̉ aÍú(0Å ¡§üàqÑ(èv1lF±_ˆÛL4æYO < xføHŸH"ŸHl.'„ã‡{ö]üv¼À'ú—³µ(RB˜¾�€³Q�†@7 0 €]„Eã1 Ñë_ø÷¤SžH"ŸHl.Þ=·® |8”þÜD|›ÿ®·Sg1º·›�íÑ8ü"!¤ŸH$‘O$6ÈÅP�ëî¾Ïÿ+zy‰Ä½ ÊzJ ‘Øð˜t ç» ãc/îÙw;ð;„\k"‘H$‘O$ú�qà÷�K{ö^J(°J$‰sŠ®Oœ/ŒŠìö÷ì; ¼8–NO"‘Hž|"ÑŸlþx4ëT³ÑƒOŸH$’È'}Ê8ðÀ�ø³šžüðÕtz‰DùD¢?!äàݳo ø-àËéô$‰$ò‰DÑ]ó>BhKûxÖCô3QàoI§)‘Hœ¤Â»Ä¹†:’½œ0t¦»o™°L.yð‰D"yò‰D{ò¿J:Óeøÿ€›ÒéI$É“O$úK(¨{vϾø]àF8wç¿'‰DùĹ.ð/‘Hœ�¤p}â\ø_žÂØÑ×ÿDÿ™H$’È'}-ð?Óóy.�·&�ï/¼EÄ`|›Ž÷xÍ0¢(ñŠØ‘ZaFÉ¥`4�°D"‰|â<øüvÞvµ" üßÄû‰~y3‹ð~INf FÔápxSâi¡Ks¸’†R+Rú%‘H"Ÿ8ÇùYàyQà¥Gàß™<øþC<@ FUŸ“y�Ì`sF)h¦–H$‘Oœ«zü$ð|Ö ê à-À;ÒééO4#Apx bÆ(ì6œ"’a@¨ÕLN )J“H$‘Oœ«$¬…ï⣸ÿM:5ý‹ðrñv'~`EVÃT*¸N›UNÔùMÈGS¸>‘H"Ÿ8yðNÏÁÿ%ðg¤|_q¦J«Ç£¨�@káL…A_�±„zÏçÇÙmF SÔbÐ>‘H$‘Oœ;|/ð{@­« À{£À»tzú5Q�T "‚¨€ÝŽ©=‚B iàÊJ?͇¦þ~à_—8â—–pesBG³fòä‰$ò‰sˆ+€CÀPϾ�¯Oßg‡j‰+Å`2Áxðù0~ä2<`Û«”�ž»ø§;þ"ûƒüö-íb“7Ñ häy:‘‰Ä} u¼Kô�%4¶f½jþã@�ÐÕ.ÑOž<(±`((�Ų©>-ŠÖ,¢Ìð‰™÷ó¦Ú±²Ãø]¦ÙÌývFLICišêë‰äÉ'úŸÇ¾ËæÄ'�ïC¼„er™`ðÃøÁKi»(©˜ø)>Þú^Õúòö•f Ê9ÜöæˆL�.1»mÄ4‹ZZ"™H$‘Oô9O^lZw¹ž�—_I§§o/:¢ïÀ3N>ø:f�ª41n–¢sŸ™û(¯+n_�9jÍ `BJ–”lDÈ2©å)'ŸHÜR¸>±‘ÖÃñ€—E�×øØ¿òò�tª6> ¨El‰ªâÕ„¶µâðÔ�ÁË(ì5×F\ñÓ|~é^Ýù ˵¢F^›•fž³Ú,”¹¦Ëi22‚m©#‘Hž|¢ßtà‘À+�ññïzðIàûÈb�kß»ïCÑ�Žb÷SdUŒ_Å ¸ò_h}‰WæÚ>]Ô�‚ š£H£‰§Qøf�B“˜^JŸH$‘Oô#—ìèÙ÷eàw€¥tzúKäMAéÔbLÐ|‚ÁËiË ™k!�%”“|­s#¯y×#O4ij6†�Õt‰$ò‰sˆ BÅüD�W ð"R¾ïð ^�<#3%Þ•:Œ©ÀçdÒ„ÕTf¹cù˼œë9v"ÿŠ/v5lm Ý͸ÉÍÔà(‘¸¤œ|b£°ø£èÉwsóÇ€_ÒééKO^¼EŒ¤ÄÖ.aµ2È€[Å·8;ÇÇ?Äo ÝÀÉ5…A˜)\YäÜÉŶšeº™Bó‰DùD3¼xDϾÀoóéôô/F¡,éèùð#h›MTˣ˨ŸæÈÊM¼¬òN6š£ M…5j’×f%«!Åtž>‘H"Ÿès�ÿ}B5}—“Ào·¦ÓÓ'XŒz<o£6´©5 e†]FiÇÈ]Ê&”ÓÜÙù4¯ø@íèâ(„þuäH³(´,�%4õ¨O$’È'ú—MÀ+ oºÌŠì’À÷êðx¼ŒZ OA¡dC;†h�ÕyŠÎ·­LñÚ¥�Þ6Jƒl;�5µ\"VÐCQ�šÝ$Iä}Ì0ðàq=û„ü-éôôQàEB£¥JV¹ ò­d~_6ÑbžE(o¯}iœ™ËÊ|î–š5…&ÉsO$XRu}âá F(²ëø9B}ø~¼�‹QEéÐÑ ¦z9>ÛŠw`ÛžæÔÊ�¼ªùA¾TÔšÒ?.µ¢Æh3‹ö]øD"yò‰~g�ÐÉî±=ûNŠì’À÷)jƒ¨S­]D§²[¶Q¿H©Ë´ÛGyíÊŸÖþ=c�æ¶ECK4'g`¼a³ æ¦)Ó™L$’'Ÿèoþ0ðÔž}�(ú_J§§�DT„µþñ^@ :^Ð�K(+Û±¾ÄºV´VŽðºÆßòï5rš4´6_†.v MÐ¥é >‰D"‰|¢É€ßÓ³oøßÀgÒééTÂxUÔ+N± T©dSV¶c´ Å 0ÃRû$ošý»ÚGó¹Ü7ó�Ñ\+¬k°4‡+˜�9ùD"‘D>Ñ�Ÿ³_~¢gŸ't·ût:=ýƒw8Q0S–xT}(´«îà ï¥Z´qnt†ÅâožúØÎOÌ•¾6R˜"˩՚麓H<„ÞU"ñ`ó‹ÀÕÁ\ø×ŸJ§¦Ï¬5ƒ(K c±Ö’9ÅW.ÄW÷"ÒÂK“¬X`¹s‚7M¿}äCswûŒí2Õjø¼Ö”fƒÔª6‘Hž|âù|ýð¼�/�×ï�´º/½y�3‚É2ò"Cò]¸�]8ZÐl!:K»¸�?Yz'ÿ\›kyÁLåsÊXaŠfMs¶§Yð‰Dòä}Ž~&zñ½ÿgÀ{ÓééOT Æ*âAó-tö¡Þc´…a†•æI®™ÿ?¼·Ö̵™Ì•¹Ïk…ó5ŸƒÀT2î‰äÉ'ú\àŸüBüŒ à¢ÀÿUòàûËk_»ê ‚â�AíÊÁ qb¨v:X·€“S\;ý¶ñwg%ÚÈ¡(jZ£�¢�Ï‹Q f5«¥ëN"‘D>ѯðB˜ÞÆŸKààA+}â¶«ÍB´Ï;JŒÃK&[ñùeøÌ0P.ãeŽÂÏòÞ£ÿœ½ƒrÎ7³œÑ¢š4›á=/¢ßý9‘H$‘Oô?üÖSAþ¯¢7Ÿè }GU@ Æ{œ!„èE™ ¾1�¯.SØYS¼÷®ÉìÍÛ?7Ø&Ï…&J�”{O$fRNþüô´¬ç}6¡÷¼éøwoO§½ï>$ÐnÓ²‚• ë °?p *Ë*˜²åÞ7õ'#oÎò%7EÃO4�Yr)-“H$O>qÎðdàW{>Søà­éÔô'^qV°™%+ è8¾¶�Ž1T: :~ mOóO³ïæ ÛdÉ—­í 0KMÙ¦v”äÉ'É“O<Ôt½«]À>`XZ÷ã9¿ x90гïï�·�rð}‹5dxÔy\e.¡�œš[Áû&¶u‚lüoÊ¿BsššŽ×¦Ì9Œ6 Ó¸&Û¦Ò‰L$’È'Bø7B÷¹+£è¯æ¸Ï3q;A˜ ׈†@‡³çÔOèG?Ô³ï:àm¤|| FÔãYïG¯Î"t(² ²Ê#)½`¥�”KøÎ >8} ”·)3j@ÉRO*ék9Ò,æR¸>‘H"Ÿxx!Œ>ìŽÛÎèÝ_<ªQ¨¢ÐÏ' SãNÆÇ_ Œô<÷¿F¯~%�æ>Á£Ì?Á‘Yç6a²ÇBÅc‹6¦5OËOq}ù>ÞÈE‘å0Úh{Ò‡Þôitl"‘D>ñpàqÔià+Ñ›?3: \ � ¢!p°7zïÅÇzÿ]½ÿgÄç^îêüäÙmD�÷xc0*€Ç ˆ:Š G¨¨ïxl9ÍŠŸç?;áµK7±Ì(¦Ö¨i­9Â\m.TÔ'‰$ò‰‡½÷ãÖ¥WÌŸ ¼ÿŒ}Ÿ¾#O�·›8=ÐMÌĨÀTŒ ,íoão‘d8<˜èÁ{<§+ƒHu?¥­2ÐiPÐÀë GÞÇ+Z_a¹»$IäçO$´¥ëÙ÷1šyBu½�Ûë©€}À…À6B-À.BßÄÈB8oïŽÆÀB|ÎF4¾‘Á’ø6‘õ[Á’1‚©]B3 Ò\¤i—Èʾ¼øIê­[k+ÔJ�«é¶æ6¹cבåT\™H$‘Oœ <¸ØÒ³ï£„wsQ/|Ü à8!\ßõ¸»·`8Þî.¶F#`W4¾��ë¯D/%zýSq[ŒFÁ"ayƒÐY/ñÍÔüt+IUQqx1aàRšl¦Z.ƒ,“ó|}ùf^ÖúÈèÉ9PФ¡wæ /3�¡ð®H9øD"‰|¢oeáÑ„Éq{{ûà§ ¡÷oäYë·�h@(àûÜ¿ÏF#`�Ñ€}ñ¶ #,Ù«ÆçkDÏÿTÜîŽÏ½£Íhxøûð7ë¹únª¢!fൎ ÀÛªº‚øeð³Ü¾z ¯X¼–cРˆ"¬Ù4Ó7%‘H"ŸèCºb¾ ø‹(´]!þðc<° ¡»¿Ï±^pŒ�ë?“Z4¶;E�;b4àð´h(Ø è®˜&¤æãk?Ñ(9—×õ{�WÔª€ ¨ALA)ƒd�¦45¬¶‚À—ÓÜÖ¸ƒ—×þºvk-oJYŒ¢»¶<‘"&‰DùĹâÉoÞ\Ñ#ðG�ŽžòƒÑÕLïÅ»–žÇ›„TÀ]g¼†îq°Ø½þ +v�Œ‰qº>i0f{"ÇãÏÓq»G³ TúìÍTAÅxT J1ä “W÷SØ!Œï`Ü·Èñ•/s¸öÎÚ‘Õ½M[;ºÏÍq‡¯�À%…O$’È'ú_Ü!„Ëÿ‘°n¾+ '€gE�?› ?Ð߻ᆴ Ð(ÜÝÆ>gþ]ÝûUNOì‰ÆÀBJ`¡&BÈ¿›˜Y=ÊÊæU†ÙtÖå‡3,#€Áhðê@«ÈУ(Ì øR.ãËEŽr‡–ßU»-˛Ԏ^êŠmGLmmÖjB£™ ‰$ò‰>g ø;àI=¢xøoÀÍgxÕýˆFïüÖ¸õb�< üD�!°3F¶i‹+]“ÑL�¾9 x|èq§Â•Ê%td£Æ5pÅÇÛ·òêæ»Fo+ò&EQÓ&G´6�63 Y&�O$’È'úÔsïJÁazÜ3X•OÏnêcq¿·4À™ûJB]@“PpðÉÞcü>»–Æø'VlD¯]DQ<ºÖÅÎ"ª¨Å Æa/¡UÝJ¥,1,R³Lù#¼¢ùöÑ››£ |¶­ióy|3ËCh§Èh¤*úD"‰|¢ïÄOzþÀôì›þ;¡ç}?{ïßLô{÷}£¿Qw|/Íå›q>NoB´A)ñÖbªƒcøÁT}Ï*Z,±Úù¯8õÁìò&y³Ð(§c¾ž>‘H"Ÿè_O~0 ü3{„nŽ0ÌæßÒiê£7ÔáÕ j‚À‹GÕ xP2Ó¬tĵÑÎ*âîæ”?ÎÚŸàæÚô&«”yóD"‰|â\wkÎßü—~��ƒ¿žÔ]®ßÞÙ^ÞÅ=|ù©Û–;8Å™yÄ,±º2ÍëWÿŽOd@6>kdn‡•ïiý{"‘D>q.ý!ÿ£=¿=ø§OªÇgˆ<@ÆÇ–˜ÑGSþçcþóEhùÏÓŸB›‹üKûí�ls£ùôÄBQ[˜Õ‘ìR‘F'IäýŽ%̃ÿÑø³ŠÍ~øxø¾Eq(Šj;x9�lhëW±Kó4þNîÊ;\i±ßíf|Û1¿š5ÍbYáøÊ’= ®Û0hšÐHh™oo�P"‘H"Ÿx=÷Þ÷ÿeÀ‹zö­Ï#L™K!ú�®ä±Š^}ðØ%üŒïl[½Œbðlá°¾�7')ŸrœO|¬£Ïo޳©9Çf¬ÝJé/ó”»è°Ýã/!,$,%ì®6˜%bÎÅÛc¬·^!´Nk‰$ò‰‡Yèømà7 “à ,û�(ð‰~ +îaå»( ¡Ð­]ŒË.i#•9¼N#?ñfìcUn¦59©ËÔå.JðašàºùZo&4Eº nÛMƒ.'L$!¤{Ê(ö«Ñ󟉷Ýq§ Š:Ñ`H$Iä"¿½+ð ¼xkòàûÉ•GD»Ev-A½…Á½0¼Ó.0n SÎQü·?Å?þ£TNxÜ�õr2Øœñžw£=Í¸Ý |…³§nÆ͂Ƣ°›Ð5pO4¶õ<ÿbŒÌEƒàhÿ9BáV�6n[b`'apÐÅ„¦LOŠû†YŸNØõúç óNÆ}‹¬OL$IäÏK^=v/šEøW$~ãsæ$�ò,_zœdØ|7:úHZÀ™Ç»%òÍ«üÙÀõ¼2sÙ{ZxP¤ƒñ?ýÒ·&ŸïÂîûgê™Çãv&90D(üÛÅ{¼!°‰P7`ùþB=ÀÝœž XŒ�-‘jIäç�÷N¼þ\ôÖmÏÅõUÀ+ãýÄÆKl`àðF0*Aä]†äÁÇìA7?-•*KH±ˆä üùàcxéž}eë r£Ž©1*ŠQ�¾æù^TAÔU’úm>FíN¼?Üx#`8 ýDÿ½„º€�=FÀ`<¶EXØ]8oïFã7EµIä}ÃÏo$ŒVíò–èÕ'�ïkÍ£¢„Q±Ý½Áä-Jr²�=˜á+P<†“ЪIDATeÄŸ¢,WyÏ„ò[.§õþƒ7ÊÞÉ3„ë`ߟ–nEÿp'ðÙ³>†¢°…PØ ø`+au@ Š…h,ÄÀ!%0£.)ò•H"ŸxX.Š‹ïŽ3`Kœã âÆ`óc)¼!/W œÅ+|d5çÅï©Ñ8€h Wãêu‘­uüR†I šo9 ð�¾eܺ}·�ñ}²„tÀ0¡YPר#» )�1B´ÍG�_b½àë+£Á±Ê·ŸwIV^ùDŸzîÝ Ë“�Éxéîû$¡øn‘³w6KB¿Ñt^ãb0 j=JNV(^6![® Ã •¢‰øS¸l��—{øÅ»?ÀÂþÁÇÕuîJý�pCý—DËkR±Øƒoô~�ºýþ›„¼ý×S{É Í‚†£ðˆxÛM<:ëñ{ÚÔÛ:x>³„º�&÷^o“¾çIä},ôß ü}ø.Ÿ~ x|ô4¾Þ#ìO�Н¦S¸�pxZŠg?òdD«dn ü,N|¶6Às_ö:æ˜T¤~­§Ó¸Á¿«] B¸~ ¸ø�³; �­¬¯ØGX5ð}q·÷EwˆP·uð¡Ñ!eÐIoAùDÿÐ{±x4!¿£gßÏŽü¯¢G?<8¼ôX÷r/ѹ— ÖÙŽM|;ï«ÁH·U­ …¢Ù0fô»oè¸&~‘7ãÿoïÞcä:Ï:Žß3³»öz7qܺ¥†^œ¤{i“PSBÁ õ‚¥á²Û6(*ˆ 74 T$DÕÀŽ+D(á¢*•PÛÐJE³«Jýƒ¨€£Ú¥´Ué…†*N\ÜPBQÇkg/¾ìΜóðÇ{ÆÙøR;MíÝ™|?’íì®Ídæwžç}Þ÷ÜrããÞü[¤ñéÉ€™ 5峸ö«þs½·»ï£îDÿ�³üìºú" {߀¨;[ë ÿîÑÁKÀ‡}òê=/î;%à?ÜP<À]Àß’o+{ù5ÿ|ù ߥä‰âѺ*˜%o)ºŠ¼>ø­º"ØRw:õÇrëУEŸ�‚ùת¢ QŒ�†¯£LÃ�†ŽÏ‡øÊÖ—ðëW?Â#3“­˜¦´¦‰–âÏ‘ �®îÑÁß9åý¼r9n´~>äSû\û8Q¯Wñ? üS}åÞõ5à—xúü·�¿Þ¼Ÿ<¼s7g^»»™Üöÿ°¸øXݸ xo]=üðæúw6Õ?ÿ _šg©>ø&AŠšå(±áZŽ6×ÕQbiž”²`;ß½cÏC3ûrw>Ð"fâ<�°›ñ©îó‹ƒîÑÁUýY`À[ɫǼø¹E×õ¹Eð oþûɇ‚\ÜFÞ¿ yø§{XÎ"y�oð6à‹uÈ¿øgàWê.@E^C¼¡Ž‹kêÿŸN�0ÖÙ¯ÒR@DA¾ÙLÊ­z:�4†H—ý%Y×^¤,��ªYþkã·\ùÚ‰¯�ÇxE"Z´ˆú~5ç;y=ákЧï{OVò}`s®¯^QÕïnâôÓ½º®ªï ò¾ºÁ~¹•O]¹WävÿçêJÿ uÇà/€·’[Ï#·ûŸO¾uèëëŸ;äKsÞŸÈAîEx"¨¢¢j4Š!Òèõ¤t)ÍÎ%s4ãHL¾ý¿y`†±Xys™”Nþ}~ÈK2ä{Ø%À4ðS+{œÜN”3Ã�@^³ûmàgê €ÞG>ßþáúçêï­ÞC>Øãȃ;Ýuþ‡êïÛȃ»yªE¨s¨¢eH)7UsUߤ ¢ÜôjbàRy”N9G£:Ä#£oùð°oçýÓÕÄt+E<‹}϶ë%C^kJw€æÞ:¤»ðO¿|é,!;ì$æýy]�x{]…Ï{�Ϭ÷®!òÐÝëÁ5ä-=äí?»É�ߊ§ß Dç_ÒGýnLQŸN?´ƒN<Ê|>Z³˜å±¥ÄÍ¿øÆÖãSÄ“L<Ûv»ízÉ�ך2Bˆ{ÝŠ€?ÜH^‹?›aòvš÷‘·áù.t_%o¥K§Týû�¯×_ϑϻŸî$OÎï^[ÿ³ä!¾ûÈ{tu¾Wlݳ胈Q�Ò Å†W²4ôRÚˤö,Uç �o¾iÿ À.bzfOšLTvæ%}7ÞõŽ�À߯á©Á¶CäIø?ÇïÎï¬+ïnGà(ùNtpú)xŸ<å±»ëîu¥?°âÂàò–ºÝxdæ3LyR”TAED“Ɔ+X\÷RÖ·�S³ÄÒ,GŠà7¾ñw|aÿL+ÜNJñ؉”<ÅN’!ßÓQ�ƒô£ä–<+þWÉóçcé”j�¡Ï)ßëœá±¹_wOÍúyàVò¾Gp-þœºSôäsgóÝåJÊ¢9º�Îàå w–Iñíslò;ã�ñÙÓT)å�g Uÿ‘¤³³]¿ö “·¯½aE¥<[Wð÷¯âW�[ÿw�ö¼õÉy^±E•·¸‘*¢lR¬ßNgè Õ)ÍBgŽöºÄ;®yÃĽÜÙ*/H�ÄÁ;ÉJ^«—äÉöoYñ½À›€O¯rÀCnÓÿ�/×yTïäµ÷“Cv‰´\Q6š46m'š—“–�S¦#�Ã�’w½h”{'¦gÛ7CšÊ»à¿¯¼“¬äµªA犀Oä–û›€=k,ÃlÓ·²°Kõ³” ŠH¤�&�âGé4_Õ2Íö´â±;É›¡KlÓ÷¬H¤ªAâaäjÚÕ2ÕÒ1Rù$)ç®W\ÉŸ0 19Q¥H($É�ïC‡ÉûÞßYÿóàݸÿ¼ç5·�6퀢d š£ˆÇé¤E>²u+­é±¨"E¾ƒ<­‹w1ç>yÉ�×Å/üÈgÌOY½÷Á‹[(/½–’6ÕñE¢3�#Ü]�ð{—þ1'Æ÷$RŒ‰ u1O±sŸ¼Ô÷\“_{_ŸÂ5øžSÐ.ˆ¡’´”ƒ‰F±…ºŽ¢\"Xž$U³||ø%Üþàõ1ŸHÁ4)ßó'EëbŽÑÏô’!¯Õz+øT”Dc‰NÕ ÙhÐH›©6\K»¹D³½@tŽ@9Ï'¶]ÅïŽÜÁÜÉ;÷ÇIºPŸK>Ò÷I>ä¦( ¸ŒjÃOäG;'h,ÏS,æ\ÆÎO˜8<6f°K²’—zF$ A£¦3r=DE´Û Æa¢q˜On{·Þ÷Ó­ùz¸.Å)­fo«^2ä%=ƒb~„ÝÁ2ë;‹DãÛœ8±Èîã¶é±éù“'»ô«¼Þ5yÉ�—tºbS>‘0ÒÉ#kS1 £¯¤SŒ0\.@ù$TGÙ;òBn›áà.öѪoHWï‡OXÉK2䥵å`””UE•‚¢€jhŒ*�0sTË‹4ªÇùô†°óë?ÿ—HuÄ·HÐ=®V’ yi�y�v*h�Ó›¨†ˆ£Dy„*æxxäùÜö“x,Å®\¿KÒEæt½ô=c 3Hc ¬�­ ª´@U�r�onÜÀÄ/Ã�ìˆ2Ò”“ô’ y©Wt¾IY$P¥6íFƒÁåEèæ[— ñk7~Žý­qÊõÝä%É�—zBü�j�‡«e޶�±È2ÿ[γý:nþòëøÒÞ)Š­D+­Ý;Îxv½Ô÷\“—¾ÿ¶9Ž]±;ýæÆråºY–f¥:FµïVLA*S´òýÔ�y§ë%C^Òé©ä5Ì_áécu‰nùžHáÐ�¤Õb»^z®²]/YÉK:§Þœž·]/YÉK’$C^’$ò’V�kò’!/I’ yI½ÄÁ;É�—$I†¼$I2ä%­:ï$C^RŸrM^2ä%I’!/©—Ø®— yI}Êv½dÈK’$C^’$ò’$É�—$I†¼$I2ä%I2ä%õ)÷ÉK†¼$I2ä%I’!/iÕyâ�dÈK’$C^R/qðN2ä%õ)Ûõ’!/I’ yI½Äv½dÈK’$C^R/qM^2ä%I’!/©—¸&/ò’ú”ízÉ�—$I†¼$I2ä%I’!/éÂpðN2ä%õ)ï$C^’$ò’z‰ízÉ�—Ô§l×K†¼$+yI†¼$+yI†¼$I2ä%]¶ë%C^RŸ²]/ò’$É�—$I†¼$I2ä%I’!/I’ yIn¡“ yI}Ê-t’!/ÉJ^’!/ÉJ^’!/I’ yI’dÈKz\“— yI}Ê5yÉ�—d%/É�—$I†¼$I2ä%]®ÉK†¼$I2ä%I’!/I’ yI’dÈK’$C^’$C^’$ò’$É�—tÑ%ˆ•_Ï@�|^$C^Rïi%€V÷Ë8ý oÄK†¼¤^+Ú Û!½ª~³§úOEÁ®™§ö’úÏÿŠÎ د¡ÃIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/3D_coordinate_system_YZ.png0000644000175000017500000017251015143647637025475 0ustar00paynopayno‰PNG  IHDRùô>(T:ÆzTXtRaw profile type exifxÚmP[Ä ü÷{y¨xÛÚ¤7Øã/ &m³“8Œ £ú÷:Ãg�§"¹æ\¹bS!ÑÐ&CäÉguÏ|8Ù%j$�dÉaåýŠÐT¥›‘ì^Øž…ÊQ^Fþ�¡ŠÃ�ªZÜ Y[1W)÷¶Ÿ[aÐÞ§wí½ç¢Ó;’& ±“¦•‰Ø>@c¥@MEQ=ITãd¦ÕªäßœÂì­ZVƒKT„iCCPICC profilexœ}‘=HÃ@Å_Sµ"A;ˆtˆP�ì¢"޵ E¨j…VL.ý‚& I‹‹£àZpðc±êà⬫ƒ« ~€¸ NŠ.Râÿ’B‹ŽûñîÞãî 4ÊL³ºb€¦WÍT".f²«bà ¢aŒÊÌ2æ$) Ïñu_ï¢<ËûÜŸ£_ÍY ð‰Ä1f˜Uâ â™ÍªÁyŸ8ÄŠ²J|N¼ŸÑ7e�¡[ oÍí­µ�Ó M]%o€ƒC`¼@Ùëïîíìíß3­þ~†r®�®iú xiTXtXML:com.adobe.xmp 1άbKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEé-ŠÞt IDATxÚìÝ{œ�Y]çûÏo­õìKíªTU’JÒét74¤¹ÊE®’vt<=ãkÏÑðÈ8=ê8Çì¨ó�ãmFG•ˆÑˆ€ØÝ Lô%éÜ/•¤’ÚUµ÷~žµÖïüñìJÒt#·NÒ•þ½_¯êT*U»ªŸ§öþ>¿õüÖZ`Œ¹ªÝEëIÿùø{aºÛÅ¡ªbGƘ«Ÿ³C`ÌÕíp<íäÙ÷Ü@´þ°…¼1òƘUC·¥ë„»4tï" ê‡ þU 77Ví—sNDÑY±�7ÆcVMÆwq¨:º8t—×mø]»ðï‚¿{äwÑžå�?XtéÖCöÆcŒY%!� ]uè6? qù­Oz/nñ=�ß…{p×MLv] c®zöD7æ*!ŠhW´Ë¬êNÝS´¼8“Û*ùšòOí‚2;k•¼1òƘÕf‡ŒzëvŸÌã¸o@‡H­©Ê½ˆ»ïìÝ®v¤Œ±�7Ƭ;‘."Ý®ìÞwûøD~ ÕB¥Ë/á½ÏW¶l³JÞ˜'{¢sµÐ®SÑ-‚lÓ¿lÈ­çJ¹×‹6ÆÔ¹!è²Ë¾ñi'*qdq@ÉR;·ÖÀàŸ|¸S°û”3l ’hc,ä�1—?å½"*{»zó×çßûwc9î«×´T¿ÕeçŠ(1v-N•³þìàý¼áŸ~´»à/¨ßŒ1Æse3^Eï" xT…=»¿0ÁKÞ�ü9^߉ïý�Û¸[ èZ?Ž1OöD7檱S˜C2ܶ½ôÖd�Š‚‚2¹¡ ÝçKB·ØÌcžl¸Þ˜«¥�§«lW­ã¼î¤EH8󤮪Öëãc¬’7ÆcŒ…¼1Æc,ä�1—‰Ý|7ÆBÞcŒ1òƘÕDíc!oŒ1Æ ycŒ1ÆXÈcŒ1ÆBÞcŒ1òÆcŒ±�7Æc,ä�1W'[ Ç ycŒ1ÆXÈcŒ1ÆBÞsÅÙŠwÆXÈcŒ1ÆBÞcŒ1òƘ+κë�±�7ÆcŒ…¼1f5±Æ;c,ä�1Æc!oŒ1Æ ycŒ1ÆXÈcŒ1ÆBÞcŒ1òÆcŒ…¼1Æc,ä�1«‰­xgŒ…¼1Æc,ä�1«‰­xgŒ…¼1Æc,ä�1«‰Ý“7ÆBÞcŒ1òƘÕÄîÉc!oŒ1Æ ycŒ1ÆXÈcŒ1ÆBÞcŒ1òƘ¯€M¡3ÆBÞs•²îzc,ä�1Æc!oŒ1Æ ycŒ1ÆXÈc. k¼3ÆBÞs•²Æ;c,ä�1Æc!oŒYMl¸Þ ycÌUʆë�±�7ÆcŒ…¼1Æc,ä�1Æc!oŒ1Æ ycŒ1ÆXÈcl �1òƘ«Ô*šBg×#Æ<Æ‚cÌã8èmš¿1VÉc®"O±ªÞ ycÌÕQ¹_è?ü%ð$;4Æ|íl¸Þóx)8^¼nôºÔĆê�±JÞsU¼½øÀ_[¸c!oŒù2ÉãóGZysÀ÷SÓÿÍèÍBÞ ycÌ*¥_PÁÿ$ðQàOìÐc!oŒù*õqXÍ×(à? ÌÙΖ1�-k¼3Æ\îpøv`p/ð xc¬’7Æ\ÿ¯€_üï•c¬’7Ƭþ€ÿzà€¿þˆvhŒ±JÞ³zÃ}%à_ ¼øì(à­‚7ÆBÞóX”ÐW�Ï~8¼ÝÞ ycÌê¾®XùóÙÀÿæ€ß†vˆŒ±�7Æ2ÛɨԅßÎúëu~çN´ÛUíj]ŠŒš¯ôQú¶Eò(ì= Š�íL\9�Qw½~Ø>ªà?nGÖ ys¥_àW2[ÉtEîÜ© >ò¤M<¸8d¼Üþ‹Û—O¾Ÿf¾ݸŸÄ,ÛÈ;G£¼{¶Á¬Ôq¾ñ·ÒvTu§ÀQêA‚Ñh€¨yTÈ ŠWHç/Ìj¬àøà�£ ~tÒ�1òæŠÖq³*Ž�dí‚ð¶iÏØ]s\7�y¹çÞ‡6lÈGpù(náP3ž¼XÜ|�ëŽå¿ù¶Å—¼eQölOì$ßõ ¸mþÐMH—îèJ¢+(]¤«"[@¶]("³ü•#_û—~ðàÏ��|íkŒ±�7�Í ¼Â6`WWåù¼©Éµ‹ÏJG×_� ZŽÁ¹kÁAöJö å¨TeÿýÐ/Ý}ú¯~‰‡„“§è`” ˆGƒOŽ)ta –ž�:Ð¥´µäÙ ¯ä?w÷~é!Ü™`ì2õ òù£�çJü xÍ»È{1�[šøœÑ}ùƒ×QíÙ^¡·ÍÖ-¯èvÝVÈ÷Ü�^¡�ò^;FÅêNdv ²}y+øÝ£ÿ‘î(©Ù òaÈ[F¸ÛѬˆ¼YUTP¹J¿ÂJ~åÂÿ{�Ÿüìe xcŒ…¼ùê_çÝùw]vd×þÅØì}†ÜÞDê_GìOK»Æ1ؤ0c¨›T|ªŒ*}M�“^¨ö½ @„*ÀbÚNÓÄÆSaê•õçeàÖTRöa¸øëÓi{8ò2Æeú‡iµ ƒ‡Ë'ÊM›æ¶~û7ô_z¦ëC$ݾgë€¹× ïÝž¶mA^?ƒÌí@¶SÇxw‡°£þéܨùo4sðÂqØ l­��¢"Š¢I]™(OìÜ1 øOQ7ÚE{ c!oV•¡B¹@õÐ ˜>AqîÓ!Njl/HÒŽÚ�"�ù9Å�MTq#©=ãµ±I)7gBÊ1Èm¤œ€§žNïë‘}J�!ä:{Ñ D'øøNtl"7·(±ÎÕÁ�D¡‰ C9Þ9³û7?±¸û·ä(â®Éû&Öî²ûÀ,:8K^„éÅmÛ~|ðú×web¡=ªDï’ÌÖúÿtçh:`·[�M¬«£³£žê'+zUåËÒ^©ýü/S¯b÷6 ²çŠ1òf•ÉB[<ÃuBôJ»Gdªe…e Jg 8SÑ?Cñ) �©åBºiŒ*MÝ´«¦¦¡wm¦Úˆgyñr^çè4•fCñ‰‚$�†Ô ²* ë\4(¨CzmdþZTÔiãVÑ 2¥hh ÜAæ…Á©wÏ~ðä»f‹ãÙñ9|y˜öÚc,¿æÏ1sý27üØðПÞ^ýBòîݤ‰ äyï%Ñí²ƒ.»ïÂøÃ䢺DÙ tõ Ö°"ÔËÔþ2õ½ð·XÀc!oVqÌ“+¥˜ƒød`£æ•vú � Ш+ÜD§Ð�~ThRð`ú=àPŸ%… BSh_'T× ƒñVöq’tl*Ö‰ê Ð\ŸU7*Ü~Zñm¥r¸Tõ°¿zÐ@²d`Az Y  3Š›ÉO¯ÿ—<ä1¤!Ã� ÌuN¸¹ÿqêúëå Ãïó8\5«ƒ¬}î~^ø‰¹î­ß=àÃ7'îxOêî� hWFw&®’¾Ô/s8âë€_üïYÀc!oVuÙæÑ~‘a!Ã~èw2qô…u$Yzab(ê ƒ*Ž2#Û �Ö( g€1+ýe…û”P-C±LàXl;!¤�Û;J¡èAžœf8¾>ärCfl“Çoª^qƒPmd�БL%ƒdATF«ô ’A CÀ×ý‚’@�‡¥iXšNˆ¢òÒ,N²Nf6…cóêŽÝœøäS�:–K÷¹ÇJÖ݇ GðëIkþÏÕC|7‹üàlV¶7€ðiÈ?ƒY4¯´!ÔC¢»ÀÝnÜ9Èû ïíŽúº_pñ°ƒúÖA—m³Êh-AU��;tåöÁ¨1ÐÕƒ_uïÀÊí ž ¼˜³ Þ ys5Tw’ê—øvÛQu4Dˆí¡P• ¿ ¥j^¨ü)/z„ý•6ü/¦¸ðn?�šà£ª|%JæÏæÏD¸oå»ÐwT7‹2�6Î�Qõ×Q�¾_l¢ÊëÉéÚ‚‰ 7ƒºIpÍú©ÀU$S÷ˆ¢éB¦Irõ°D–DvànLÈ�ÐA4CŽÀa•¥‡Ô}t˜õ£í3Üù”ý�{Ž$Zûš 5¸ï@›?9Ñ?¹ï3{^W¥5¨¾‰¥�w’¶ÑÕÝìÖçAše·îݺcW×ížéÊV€ßD¹ ¥[7ò�ÖD¹�z¦š :Úw`§°£‹ž¿4¨;AÞí~~Ÿ�/³p×z’�·¿= ø7~ÁI6ÆXÈóëÏgâ>äø"�E˜>ÐîG*œB›Šž#¤@løæZÒòµÐØk6ÀòµÖC¹N4N Ú�– …æzI}¹PË®dâ•Å:ý(P¼d¼‡rŽÍÔyX0T²I…�ÜâuñÙ7ÞÛ™+8¾7Sî†ÆŠ—¢½p�ôs'מë�êò/–Ø»S}·qªEø£]”o`[dèNÐ-»`v[·®çAtØ‹J·ž¸Rs«Œ†ôüpÀÊŠúe'<çÁ­À[�>ð¦ W_Æ yc.•"gê‘€*+},Óo� UŠ%¨"±YÑÏK„xˆb(„A=D0Þñ 76µÚÐÔa³Cì_ K3�fÐx­(D[ë?©¸ %8hŠÖÕ~=R!^FÃuG¾µž50p*Éi.¢m¤ÚPjç6´­Ä‰@¼ÊþYR_øÐ1í~˾ëös0} ‘—?8p"òþò¤8}÷Çž[¶޽”{g‰ÒE»]ä;pÛ¶ ·íE»£˜¯3¶lG¶Ý†î¡‹Žø¿H ?ò# ¸µ¬ÞSÕ÷íÏ yc.ƒI¡í„˜•*("èAQÔ¿¶Ñ)4!daº/ ²Ry ý�Ðk$�e8¶ÜçÜ™‡ ¡hƒ®ÔW-b¿�£CôÓTrm�¿Îéšµ‰ÞõQëmAW¤)x©WTUu+õ³B¨@ªú.z�ÇEýÖX#äM°ðÉaž’¬°I¡µÈ�ª÷üë>yévéØ¾Ì¹øÉÝÿ<|ˆî½§`}o–ê{þ&Ò½MßxG×ã$î)·l‹Ûfg…m°k ¬°mï—º}2Òl<­¢ú½º»‘_]Qc,ä�¹ ªR©ª:¬b»þ5 h×ÿF†XˆÄPi½VKýy‘@¤€öY`P�Ð],e8.pjôØÅ2±µ ÅiBu�vþtE„Ö!!Bè œrK'ÑZƒklPçfÐÁ²^ å5P­Ehè@h êp£yøêFãçIu´>OÝ3 @$ œ]¬!ûÍB¸Mñë!5дF…;†°< §õ�·ã]íýwþü÷#ëN <8ë¿÷ß÷ÐÂìš8vÏ Ûí®¬ì÷0§þ'7�ªŸP´ü*pÚ~ጱ�7æ2+.ú �ŸÑßC5úhLŒ>'B�:W(çÏW.ÚõÒ½1Ž.€Ð»ðøtêÏë52…“¦űª¥sÀ!ŠU¾ l€8)�æ˜c8S6TiY¯4g„æ¦HÜ NgêÒÔyÄ�ê™ V– VÉà*A£EúTT]B ›ÑðLT�<†Pg³Æ¢døŒ–ÆŽ+¯:Öý…o=þ |p?2pšO>ÈM'Ž�æµã ©�/–ÐâcÉý*Žª@]¦9“žMËä&c'–%%)¨÷CI eèub*…”ÐT¢4 QƼ;º†IýÊû¸T¢$ÔG Õ­�4WîxŽVO4ÆXÈ›'²øO_ï+¾ÄãÄ/ø­/.|M•õ|sy5*€«•‹¾`bYBO#,K¤†Ð¬ŸR1ô…àê ŠªYÐoM¹”7ÚëE«kJâF¥?#ä�hÚ,4›hËkj3ZQW”¬J®^—¥¾ÑŸQ�há µ`©¥ôf@žÉ II\“s9¾MúgüÚð¼¶èË1¶„“lÝŒ¶>�t|]ët%žþé’{"þ^:×ôŠpŽ\SJ)Q2¦àI”ôήOžˆJCi/ž!IKCêé•Sg'4‘()2T|½9@sX_xŸ�x�œ--é�±�7æñþDŠíz�ú@¬×¨/p<†¥c%C�HˆD¦ÑÖ Ž0æ4„)âÁkˆ§6ôFw­'lr4×gÜ5ä´FQѺ€ºòÔŒrI\.U@ªPˆ:ïŽävûwyMZÃ\z¯Ô3<£òªÌàÛûdꡉo9Crsg޵N“Ïž%œ;BqøúЊ8�ì’zš†I!’RRDUç2ºˆ€³¾RRRÄG$>y0$)É+¾)$–í—Ç ycçã  ï�Ä‚ó·Úy4D=&+# ‘R‰ìË���SÀ©âg #„@ I!;ÂqGjŽS�¯'êFb˜¸Aµ½N(×ÃòfA&4k…¨ëZ�5)¹`ÎòÞøà9ÏË;°¹�œ¦Ð@%•¨OBvMÔ_ãT®‘T¢´¡C«k²ð ªÃïK{žjN)OgÎWwühò§æÑSóTåiò©EÒžØd?“S)4Ë®_’û}Ò2^S˜B‚ár®›ùÁ�êw+ã�±�7æñ¯s]ÉÆ²®æÃh6@ÕW¢Ó@Gêào'œƒ ú1Gú£ö€Hˆ�ÈR8!¢1�‰g`ñ ís÷Óî£1@µ¬Ê˜‡�M�ëƒgÍŒrz#yy ½–74⹪ø®é‚{b‡»³¤,Š«d¨8'Ä¢žˆ“úR$×Ó5Ù©.©�ÈÚ(ÍuuÁ&%_�”BŠŽ²‚å!¤“%éÄɳÅiÏÙãJu:sà ÅgÎá>µ@8Qјò”ýìã2cÍe×ðÈÙeRJ¨ýc!oÌãØCZ7÷­<¥V7 íJb¿ÔóÁßùB [ÛIÎ7ý�Äó †&Î ôëM„ª¡R5 ±EÄh¥Èâ2œ"µ‡=¦z…c�Ëi§šeãÍÿÞ—Gžûô¯æ÷_s”÷¦?áÛßw_q£k–�uC‘µ§QG] $ˆ6 ÑѶÀ*¡Þ/H/¶£€d$dqêÛPLAë©$Ö�–Üœ¨^6 r!Ÿ æ2ùęc½Á¡SøÓspd™ÆR�òÄ2UÏ $6]Oñ+ûðÛG+û­ì <:hªç× ¼°›`·^ÔøgF/Z)@.¼£�úI}üü7©WK�z¯B± c!oÌÏÄ£|,ç”ê Ÿi_ÐLXy}ä²Á£Ïë�Vì%³Ò Ã&ÔÅÞ ‡1TP9eq"lju®Ó{°¹$oº_½ð:Úþìb±ýäê�›a_y˜±�ÜçŸxÈÉ„ë8üú&i}‡´nÌ¡ks±| ’דÃZ¢n-¦„b,ÓiA*FKᎠZYh7q~é`¨—Õ¯§ÈÈ„ŠŸ©(nASh~ŠJ y ©ß†çicüûÖÜþÛ·n—É1¦Îg“öä™×/ßµ÷°gŒÈ[‰;»Ý¼eWWæoÂÑC÷Ì¡lG»]‘-[�›nª—ùÝ·�̶ú§ÐîÎ:¸wŒ.Uv‚ì™EnÛYNWåàa—+û&c!oŒ¹Tz’ëË€•¿½ ��!o»SôÜ‹45Þ¾�âÜ“ªæOCRÕ“ Kæ?ú^dù›Ô¹?Ó¼þc.U êñÙQ!8`¼/ºØh �,¤†@’()+© ʬx¨ƒ_%µûBé”R´QmЖ’œK–Á÷i]Êø£à!Íg\!°V2›…4Ý X^ƒ¯fHq†ÔY+¹3�Mc3H9…Ò¬(PuõÒÀRi}K`´ÌŽ2Z0h8Ú½O�äTÂFÔoDÆž)Ú€\ 4ÈÌéò}Œ/|žöñë_z÷ADŽ�ýCøûHËGh½pëcîîOþª¼úÕ¤ÙYâöíšéîTÝÕu¼_È@Ú)]vÐÕ®ýú ycÌ%.å¡pB?h OŒö*a៩´þ”<öñº±o€ÐŸ£me• J×gIÁ ýœñ*¤åzõ¹Æ2¤1H¾^½.Õÿ©»ßG ùLI¢$)¾h�~ T¿¥�ÒÆ“š�’âç Bš£ªN’DñN”•/„ô`F7 Ü4¡¡qƒª»�|ÿwz}Å'E; H”þºÌpÚ‚†QS •\·ÿe§�EuˆRŽu4Þ.SПuO«{é<¤5 308£røÕÃo~õœ2x03·vâç¾þ€´Þ~Œ‰ë–�Ã'¶±Ewv�®UòÆBÞóX(’@ý†>lµ¾â”P]¯p†Èo~œþ—JñžFšüDÙrΖs’�:•‡œT}] “Æq~±ÊÉ3ªàG÷ÐSQ€z8É×�V¢+5Þ >AY�ýŽ^J<>µaq2'ú@O¡Wßÿ'kýuxð} ¯4nv”¢p¸Gìï�#§�=ÿ:ux3�g º%7yª±6N7¢K›‰ÌlvZmR k3å”ÖC# \4+êëˆÔZŽ–Ó�ˆ.¡”¨äVåš7 �ÐéÛ¡€ìai2ÉRª@*xáü,k??û³÷œt´Êô‚ÑX{”Éɹ?{÷ —¶<i-S=ðÕÖÛ»™n×í܆c ™�ä[êÛù»g�[¶¢Û!ëè&ÿÃgÔÚI½ë`ØqÑÔÙrèPTAvÖg)oÙ6Ú®˜õ¿Û“ÉBÞóøKyè;­Ÿ¬±n´+šBµ^CDË ËihVÇK˜^ªˆ§#ýûˆaLôœVk½Vk›ÄÉŽO2MÃo@6�ò 9]'äSJs\B¨w ̸Ѥx%+’GÁ_ß–PINµl­ìtuסþEä1dX sM–xA Õ"‡×žeç ~6ìº�í ‘§Àí?Žžfì¹gßöOIŸ=KÚ8éF ïÝ‹În©ÿÜAÝÈvE¶×—z¡¼D»tGsw\ø°UñòƘÇç´Þ]/RQ¯~W§òÆW Gç>AÚx¤z†÷¨èNz~9ü 4�“* é7\=¿ŠÄöÊÒÀ¨–úDÐØž©wà õEPŒgêõæ7ç9†Ãrx1…ö Êø9B® n�h˜ I>;Ò&º !769ÊkJÚ›Ý(Ê´h@ì(U@2š_§8ÔAö£ê¾Dqõmz 4 X'ÚX‡ÊÍNÓK4‡Ñ�Éi%�GªéEóg¾ç›?~{=»wðyýý]šGhï:EãÆån÷Þ¥.·EØ¡Ý]¶¼wÏiÒì>òömÝzŽŸt¡ Ý.ÚºtEÙ!bsû-ä�1�Ã` Poz€‚À)Éñ÷·f}?*Ÿ�uïƒÆh÷¼DU‡=´œóƒ*§†—©²ã ι>ÄS,Ä~#AéVá‹~‡ÄF}Á€þÉ\O#lPô…‰D¨¢žÿ÷ö°¾UúÇ�sCbyœªÍb óB˜‡ØªwúUèwƺGk]Kýú¨Ã2²!k5£”3*iRu¬Æ @�œ IªÖçO}­{V ʪS‚NyèÂ×e Õü¤Ñ�ƒþkûÒ×9xöÉ® �àïÚßÝþîƒ Æ�zfrì=¹_?÷o}@™yWB.TgeRZdhM8zƒ´ÔqŽª‘]ê‹’FûÔO�Jʲ=Úw5ŽlÀù)}uÀ_t!P¿3º‚ ½‹¾v´œpˆ¬,-ëÇm•[ŒF"0?úªÞž(èùÂ졆 Â9B=,µ,ÆÏª†Ž6Ta£KÕÆ¬aF‹Î&bÜŒúÑÁFXšQõ-a\”6ˆ¢@ÖzµÀ$õ-™Áhj *"N5("Ml‚£›Há¢�LKsgæ›ïþ oº‡zNáè«D.îª4òƘK¬ ƒ ¥ï”pÑöó7fÂúî¿¿Ý÷âáAÇÚ?NhùE*WJJJ•òT)!ˆ DDIª4†‚íþv^a× ôAöUŒ¹#™ÆQúíªCÄpN¡í|¼Í·¸9,¶ÓZ�Ç6"g7RúµwäMÉu¦P݈úq¡5Î+z~–„ºúå\2B ô–uÃSï{þ�ÝÄZÆyÃŽÅQˆ�s ycÌeW9%WÊ¿:ôc Qß}<ðB~@YûO³L %ÜÑ4ªnà¥,³Î×­÷KOÒP„DÖF_´ôVÈ]ž¡€ ˆk�J!*âÄ„«û²Æöþ¼éwŽB8 =}R±^¨Ö ±ãéo‘—;'§]•¯Qï¯GŠ DfDÝFÐ)¨Æ•¢™%�‚Cûß(<¥!g†÷æ.ÿ·ÖëóZÈ[Èc®H„þ…ª>¶�Ê<™ô¿~Ï>dí.R–¾©xäC$O½8MªÃ'Oƒ‰-©x�HœúØ@¥lt„4¸PšKø ;ºíB{´–Q„X�†üÛ@A{´8O/]´€ªS Ç50LÅR§êÓîÁ™ã>‹ êsÚ(kèT›Ônšë|µô- }•‹­oÎ4TÝÂ^2:še/ç·Îµ©uòƘ˭8ððžÍIîþ)´š‡±w� ^¼Æ=úPû¨— ‰¤´ ?¶´,U¨D"€ê¢¾MãÉÑ·û²—þÚmú‘…}»Qá‡zá R÷„qaà”b ªe­›û&ˆíŽ‹�Qï@¤Q¡ƒ° §{D½Á\æúkaý«¨'óI¾p–õp½…»…¼1æÒéו]=?úX hÔ�Vô€^ƒûäO¢å9h¿ŠAýâ¡}´*¼¬?\4¤À“Š (@½¨íÞ%߇Å*Õ+ß™K_ɯ\¿¹Ñ ˆ •Wª¼ò\oûRÁSA¸hêC•–FkŒFpbg4úSB?ç@C §£c)8R”œõzxM.Þ Wm%< ycÌ%~ÚÅÖE!ê€/"ôø¿ØLúèO�Ët~ šƒ‡ezJ�^‰5’øÒkj´Ä–”Ê©#HòˆDÈ(-‚0©~üL3/’­¢»#3çÃåƒ'ñ¢_‹<¢×">òqÎîÊû®^€1«+ÉYQAEq$�é•o.Ö]ÿÄaó'�¹ÜVV®»ø…:–J5Tü_oF?ñS¸å6ŒÿŽgbøe?n)êi eÒY rIÖÑz �°LÊôÉv7Þ«ä�1—äY7àÂüë6+ÛµúøÑ™$õ‘å´Úg¾²æ8ÇÊ¢¶©¡B鵇¦EBtĆà¥$+ ïú>+}»7kŒUòƘÇXÅùaØØ‚8>²6³û'`©… oA6œÆ'Iþ+«¹ËQ�C Á)ü‘eäíÄLÖ6•4Îåäm¸öê}Q»çn,ä�¹bâ¦ÉÍ�­#|à§•ùI§­·§Ž�RÝ-Ÿ¾‚,nx¡¡âÉõ xïäxçOöyêµê ¥l8I kº»Zå‹6¦3ÆBÞ˜K^µsÑz¬Lœ˜€À=Mþõë‰ k`ò­™Î‘•šü+~Š:'”M­¦£U¸NZ×��ëk}G)qŠ/ñeeA`̀ݓ7æ’uE‡‹º¤cN)oEþìßÃÙ';f~7ѯ­„Ëê�4¨2Ù xÈèµy]gDMÁI>YÈc•¼1æ±¹†^©è' sˆ§ø?øaÜü3p�?G¾æo—êû÷ ¼Pz]Â+ÎÉ.+Y…\o¹ZŠw6\Õ¾¨Û=yc!oÌe¥¢ï˜kDÞòZòégBã-äξ䗾öoç!5¼”Ô÷ãé8ßTÚc>�9Ó!Q6TU³{òÆBÞ˜Ë]ÑÇ0ªæ*2x'œú¤¹‹¼þA|tç·FýZ”-nã3ø’kÉ�¢[œà/‰¾–¾„²iA`Œ…¼1æ«V ëaÓ•.úx¤@ßñºÌÉ—8&ÞéóøHBjëÊPû×XÈ×ûÊ“ê¡ûA•§ˆ3øí£Uíqd˜tÞÛÙùÒÚg…¢1úî_¸Pkú„•fÊ¢!õ’µÆXÈóĪà‹4ê¢?êo¿“tüÅÐyw¦}ïʶ°u'}ñ5·ä�xõT:€Ô¡A”†”NF+™ á\3%ß·Óó%=I·{œ€pr´þ|„b�Ä0)´ÏÖ¯l‰`c!oÌ'Üa´ ‰W8à"o{Mvó/ut>÷p)v»¸ �K¶G�u×›‡ýÛ!0æ±pñ¢7Ð÷G߬ùèk\öïˬùhpa%»Ëñ#y¦œÛˆæ«Ò®q.SÍ8ôæ)áT4ù\¥3¥ „ÿ‰Þ\nÓ”Gv9tnÿEŸô«ÀÏÀKnFw¿¹ù£vp�UòƬ*½ ×Ì1+ñ�_†ø^Å43ý‘z+ïK¼Ák‰–ÔsàI©z�Ρ‡´ñ‡ ñBÒÛF³ׯ;äVó8¡]v\ÿ)ßácç}:ñ‡®ü?èô7*a –Ž”¤õŸ dù¢mŒòäcð�7#ßõ"ä�}¸›ßfÇÛXȳÚĉ:,b~ïåpèN§c�‰ÂùNúKí¢ï‘’žÅç4ïÑú oS½)qtÏÔN$q'§¾]ðoHÞ¿$¹ÆD–Aîá¤CJQÂ>šŸ?[ÐBû‹�Ažt;ù£‡‘l!ßÿuv¼�…¼1«L›I ±€ð[߀;ð:ðŸÆ?H=TnÃå�k£)p‚z×·ý–„(yt�Š®T΀žÊBãSð ö|ñ­ó¾×¢O²ç?’þþà%?Š\oÇÜXȳŠT,iäM/'íÿADöÂøÿ—|e{¶¯ uE`ªi(ú‘[2ùZàÒŸ6µ±;0E…E²‹ÿH�LH-šsñÃ~òvxοÄ}äw�§ìÇ-ü2²˜aé' ²×^sYXã�1��Ìï¼ÙÿïÐð€O�w&KR »ÿ½ZBbm¨NkæiÇ”¹sПB‡×-ü ‡Ýÿ‹N<¿þšÅ%š­}¡?Ô&F÷ó¿ ©2Üø Øó�pË"rí8øƒÐ*ì˜ ycVAý^'ü_>'»ÿõÃäö~Oã £€¿Â¼Ÿ*½0½Ï†îU‘„Vz­¼Ò@™ÂÑ%˜ø”‹áv‰Õ÷¥íY΢C  ^ÿ–°p¬ÍÍ®Wôë¹ôÕ>ðÆGéÇ›ÔoÆXÈó8Ô‡8=š*wß÷¬Ì?þÒ<Œo¼=¥æèü Tð WHc0Ì¥/„‰õáÆ³ûÛ×5O–aS"e.cÎ÷Ïæô„\Á¾âKWËJuÄ£X'qâ†u¡7ý_#­§fYR4�Ó¿ƒ*Ñ î=ô¹ŽC ñFàœ==Œ…¼1«ZlCè�Þÿûë³ì{�h8¦®ý6�!dåJu°—Y!«£HÐ[Œk`íÍÃÖ÷8ªà�Q­Y’ü{"–í�úÔÓí.Žõ&d¡ýŸ¢tn…ˆS•Lïž Í[a2ò¹ìô#c{I‡x3ô£Â’=7Œ…¼1«_ гBµ,pÿ `¹§´ÞatCöÊMQó8ž¥Rxçíà\–ðdÍxI�M§£€¢)LœÂçiÌ=gºtËoY}ŽrøS4öÎŽÓ\‚æd�Á©7Ø>ê˜_›[¾Þ<Ù-:c¾ÒË⪩Ä�>N=á�Ð.IÒ•}:%€†Z…£U¸ä""ˆSA0¾ß¶€�ÐÐw:1¿^™›L%‡¢ù¹=±Îsð�¶6ü4g?Uµ“ž£ž ó.ÓïåÈ?fbñ&`‚HiÓ$�UòƬ~ƒÑþðK-dp¹¨ Íù-c}¥í•ü )C9Ìd§$¯à(r½Ž¢L]Ÿ�â !UOÐ`ª.Tñ±MlM·{Ñ¿ˆ8Õ %» ‡*–OÅÊç.²÷�@Gúá³J¼‘>«´§|è53LãP ç€Â.šŒ…¼1«^‘„ØTÈImÉ$Î7Ú]És '¾,55œø²ÒD8J9éù�éÒxr~1åôDì»kzÏRÂQ(:Âôú Î4œtÝí•”îßÈ`á­pö,í�§éKŽ¡/Ä›¡½$T-%Ni Ç�£Pµµ¾È«GMŒy¼±ázc¾¢"0ë…'ŽH½ÚMyQº»+÷´r^ Š–óBY¦Ð~’Êã$“µ‡dü¹ê|¡Ð 1+U³Ý˜›þ~—¦_Ëd”¸tC`�Z‘Ê+Á æ¡*ëUñªÓõŸ ÷ÇOÀÛV³ÆBÞ˜«Ù Ê ”¢%sÈñá�Zß²§)œ“Tw×?ñ„Þ|¦:­'ÍØpeçóoÎ�¹;=Çpâ,.½;¶¦@ˆÕªü´­f�…¼1WíÓÙãSÒ„‡ä8†ë¹?“£Cd ïÆ)„Æs£š‚ƒÐwL<ÃÃéÅöÒp�ágöyäýº¦ì’ÒŠ´—$rÚÂÒXÈc/%\ÖŠTSË9?¨rjn _ nùgãb#Aéž�ÖŸ¾Å»Þ3þw?ßúyXwGŸ6íØ‘ÒîO(Û÷*ˆËÚîÝ aÒ†½Íªg�wÆ\-’RÝÐò®5¨t©æL_Y ™$9(i$OùDl¼›¿ñ;…u?�D�‹þëòع�÷µš~ÚßN÷ÑŸÉ>ÌuRÅi¬‘ÎX%oŒyü(’@†VDZ\¥¥‚oI$«âq¨(B£’ÿŸ½7“ë¼ë|?¿÷=§¶Þ»Õ’Z‹mÉkä`Obgßä°%�&К!š ™ sŸI€`݇Üp'°NrYÃ@ !�lL Y‰cÅIŒdË–e[k«[½TWWÕ©sÞ÷ýÝ?Nµ,/ Xv[>Ÿçé§·êîê·NÕ÷·ÿ2ê—÷YÔÏ À˜Ûa 'L.ÛØ]wkDí†@æ #Êè|DDuºQ KUï"‡‹J�/)=ù’’’õHÈ•Ì+Ïpæ¥FÕ™‡(^Û½¼ÏÀ]Ôe‰Ïy\ gw¨rçÝä†;inµÍÒwø(¼—|h®î:t×F—””"_RR²>ÅõÀSÁJ–� ŠZÕÅ(�´Þí^î¡ú¼£Ð„±m–lÇ ´m³:4ß-Ò;•s¿Cmð¯X�ÕœrókI)ò%%%ëo)¦¹y Ö˨ÏFor•g$‹ŒZWG¥[2d�pYïºw Õ-­¯¶nðMÂÀœ–÷¸•ŽÁÀj�þ’^×¥ýÌ{)ô%—'eN¾¤ä²y[<«=^©Å¦†e‚¨¶­t5P÷—÷s?‘¨µýÕ±Ûüvo¶x7³ÚyY7ªÃP¥Åj=¯w7~N\VÑ—”"_RR²îÉ ç\ÿsc-CÜ"r¸žB\:î˜[Éeñ‹ÐRaÐcĦ˜vß§9–}ð%—=e¸¾¤är¡âÅfV}mÀجÈ�B„·ˆ8( bÈÚÁÅ8¬Úpˆ\ ó[C„ˆ‹b:kXJC�öB—èSŒŸý¢Y¨üV0úEÂöÏ’Ñb ñÆþjØz?_RRŠ|IIɺväE-5ñ™×” äip€õ¨CŠ*«„Ëéßž¤cVY nL fËqms·6|­;< ç{†ÚÂxåo¢ó§‚#§Ì¿—”"_RRò4¤k _Q!CÛHH5ò‡ÁJ¨[³Z J—˃�kAZ–·ßPÍ7¿3§:Âݨmù?‡Ò¦¶°CÀ�Âh™/yƽ*””¬SºúÕmèÑ�°P‡¼¼^ÿ)gž ¤iÀ Pa9ÓFþ"P —J3x»ê/o~i8`*×DùØÿ�QÛXµ‘ !ßâ0JtÚ“nVx™)ýš’Ò“/)Yô,áƒ?Œ.}ˆ³ ¶ v©��úYX@Fça¬‰Œt`¸UÿŒ=²ŠPlÔË,’}ÕËáW`” ¹d°±àóËÀ“�€EHoXt�_–¶ùIX¼ÚÉùOc¶ž…;À�At¢––¡ú’RäKJžrrCøÀ� Kß…lø ;ÝQènD³ ´s ¬¼Â ªU €Y…h ©�€Jg‘Ñ9ØtJ¡æ`(ƒpy†l�Ò4øZÕPñR[i‡´V3-]Ò,’�RqB7*ÚížN Í ­ë‰Ü¬ÆÔÉ™7tjc†¥/.P©^Ý.5½óÿ6 V“îQߥªD­�¡œE_RŠ|Iɺðàÿò‡Ð¥× “мðãˆ<ÒãTDíTa~š@g:!›@»×@kÎM k׸Y» Ñy$^†ú)˜C—àÊSÈx¢P¼Ù¯ãá�ušËA-àÓ<¬X,t{˜ˆ•e‘ˆª`#Áú§ŸŸî7¢ƒ;jHŸ½•ö¦[ÉôNîdéH°,ÏzK‚ë,�ƒÈH)î%¥È—”¬ ¼>øtñ{‘ û1/úØc„@l€ H£Wžækùåê,œCWÆ`udÃhw+šm„îµpn Õ|5€tÀ.A´ˆTÎBíÔ�‘s05‹liB}}«E?QQŒ´EÛX0jR"UT… kf­ þiÖB× JôeàZÁëU¶;ò®@}«éuñÑÿwþÓ¾þÐñ¨{=t]¿E®¤¤ù’’u@nú>tá_#c�¼è#�øö#¼ùo0Ü.‘‡Íç‘Íç�û 4Ñ¥ X‡Î&H7¡ùDaœß€>4_í{ïvâÓPY 4k€1ø«®RD ¤×ÿà úx÷ñÒF¬Ç[+>+òñÔ0•vXt«=T+YЬÂÓ/e�¶€›ßP[Ùü†œ°E¥#^[J¨o¦¾Ñ��áXÐò…­¤¤ù’õDøÐëѹƒŒ}yé_<&DÿD#¢EX~|_x¬ЋÁ[ôüXÙÝqH7£~Üf po(tA@–@Á,‚YY»RÔ \B² Eñ`XÇVBýù„�"U<«šÙ ²ºb³§×5?KÈOé /h®ŽÎþ7zñ'M7M„ôœÉÿŽ¥e¨gè¶7T>§JJJ‘/yjñV {9:ÿýÈØG‘ýå%øoØhž¹ �NºÅ¸º‘¨;î\ô…OQ¿îs´6¼5¢õZÿáSiÔ� œ`WRRŠ|ɺøÏAïù¨>€yé{�j^Ê?O ûï2°‹`1>VHñX¨ÚáÎìV�wÔU‰ïCŒ-Z»Ï‚0¡Ž¢ÅïŠÎÓã¤2ÕEh,CƒFšùK*ðdøŠûòŠl)¾—ãîñ˜©Ï¸ ÿµ¶©#¢ÈÅ7ËU±%%¥È—<õ~égw¡Gßñ,æ¥ï�zVÊHŽr.„áó^˜¥zú„†�ÜHþ:ÝÆäç¿d®> N!ÍjE‹`6 ½ñbN@>‰¦×‚(ŒÜ…�AÄsHÔ*v4¡ÚFÆ úÍ=¦•Tȶç´È<Ä`j†ìšŸ‘¬{-ŒœÐÁê>üæ“{Œzs•Üö~ êèÚò±/))E¾ä©øÏÝ@¸ëg!:‹yÞ/¦Õ•\ZÑÏu�ØCCþèO¸3¡ßÚo˜€D«ÐX}tŒ\>Bó tÆ ƒÞê!›*Œ€•zQ3 •¬¿Hh âE¤rj P]†F\�z·hâïc�PY‚Ì*öd5°#bØtc0£‘„öõ¬Ú]Ô9IÔi‘÷=r@�Ëe]nII)ò%Oc�¿ýÂ]?Ñ<æy¿ŽL4ËCyZ¼<8ˆRMapxè‘F€·àâÂèF@6Šf ߀ö¶Cs ¨ô¹&$ IDATŠBÃhâsH¼L'š'Œ�ÛÄ7º†ÚD�e�ÖQÚ»„…®�ë÷“w¸ÐdPRRRŠ|Ézø{6¾òÓ`0·þF)ð—Öƒõ§i¨@^)åÕþÄÀ h> nڻʨ æbŒÆh= ’õp.ó¿z„„ÏáÏ5�êŒw�ÉÆÒòìKJJ‘/yJñ‚›$|úÅÜúëȆåò\žIˆB¥‡TÖR3gi€øÌR·#øknÆG[±Ÿ]ÁÛ-a%SóÉ£„êÕFõ™ã³Ü¯ h"µSÐ8õedÃ,²yª9T}yþ%%¥È—\2Î>ý_@#Ìsß] üSGÀ­£¼õ#Ûï|l½Wßdõ?$Ô#çÇï"zŸHØõ‡êY¶‹¯q1ÈZ£„ît7£½�hë&Xš„0‚Þ+ýÁC­Â¨œC*sEwÀà<2u™lÂp¯X'‡òÊ()E¾¤äŸÅ©aüÇÿ+„:æÖ_F6.–gò$#˜XL/ ÁÄÂ਽råtmK£3%�ª8²TŒm/{oŸÄªô¸'ä} 30¯µt#)_…«~Ð1`‘¶ZÞê5"ئGÆÔ3¯äWµ€PŒýyŒÝÐjÀâÚ…î´·¢nmï‚å)8;„ÞÛ­³KÏ‚]Fªç 6ƒç�±ydÛl^-/¤’RäKJ¾¦£öÐ(á¿n ²ë—ar©<”'‰Ü+�‰¥GPºYÁŽßЩ½Ñ’GÉ#Œà{êíE­vO6­j�e1~\Za)P«Ø´vÆâGîtÕ£ï”εoA6{{ß ó¼oê—ËP†:§y-®m˜›@›°:YÔd“hç:h=fÇQ­ÁíZ, ²‹P9ÝŸp†Î"à °aÙ´CeëgI)ò%ÏD�?>N8ðŸÁmFnx7fçCå¡#™½UŸûãÂ6A€©ydj¸ç‘F@�³°:€®ŒAsª˜ЛD»WÃê¿‚ù4Ô(å}#àlaT`èL1,h| ÙØ„‰ny5–”"_r™1;H8øȶ!×½sÍñòLž\ŠÖw#ıPUC” ¨Alq¨ ´EÛ¶ò$G$à;øÚ Á½ô:ë¶Þ’Û¹c¹ÿÜíäçCÄ©c.^úîü¸®õó_jDªyñ6�"›€c�4\³:5èUÑ•Qhm‚îÈÇÑt;¬Þç‡PíoÉ‘^1+ >ƒÄ‹P›ƒÆ9ddFšÈx &ÛßXM€Ñ‡#%%¥È—<•ï?övÈ®Dvü6æú£å™<øBê{i ¡À``o2zЉ„ðääYžüÍ7·ë-ž�uÂè+‰ŽÏ¢ñ Çé36OñfM¯S•b¯BeXí÷?ò6Þ@«i mõ#ý¡AÙ&èì‚óƒE:)Ò¦ Ñ| ¨�…j™8 ãKPï!W¡îJ�/yâE^1ûA¦!ˆô'I©Ê~ÄLƒ"hñNôÍJü>Á¡ �²–K>׺d}Ñ� �ï]‡\õ;˜gµ<“§ˆØŠÉs ±ÓËCÀ†,B‚SµÅV;ò¡`hÉRòµ%¡=¥–OªÄãÆ×šBwÇQ>øJ‡5˜e‘еê&êÔîÞ5Ö‡¸É7ðZ&6Àhßà<�Ý$Ø/ \(Œ€î0¬n�Þ$ê†aq„!ôT ˜~‡Àr1³wmÀàžCÆ‹HÀPjî1Ñ€Ø|ísŠdƒÀ~¥4ž©"¯‚B‚è^P  ýë! zA¾÷Ï`gfŠFïG,‰d’ ‰"H9fòòæâbnx3ô®-~=<4Fb½jÕØÜûP ÒëEš:r‹Ä=‚¶±,–À%k$oO)6Å›ª�×°yª>µ¡÷�ã¡_%y©É+?ì©Ï`ŽÜO)D`sPW¨ÑåÄÃ…�k›¿üH# ­@k]�Õ‰"��¡½Íhz5,­-²ýÂÀ%°íbj`ýL1:xx–lãft¶=6B›»ýTaf¦ÿj_:dÏ<‘P4˜öô•]@ÅL3û�NT÷°�}àÁý*¨D•ÒH¼Ì¹Xà÷ÿ;tå6dç¯an¼«<›uB/ Y œ_¥òQ�{½ÅwBÇo=—¬ºÞ¦àcˆ—ÁFÆûH©4¬o·Ü+Ò®4?oó×ó•?"øgöBUAjÔ2dr xðño·<ˆ.LBw:“Ŭ€|m>6ÂÉ!8,¤xXÈë/ØJ‰�üRõ•$½“[¦8ùÚ×’Ã>½ü¬©’Rä‹jSP‘@2#3{1·©ÈÁ=ªìÛ§Ó»™Þ•ˆ$‰²k¿0)r"aŸ…DT÷"Rzó—9¹!|à hó•È•¿] üz¡m“õðVf �/À‘W ¯3ˆ bÌ€�¤]s�ÛKó<5‘à[�t*7l&á÷I.ÛÔÿ“vøØ—iŽçñ‰?µyš_RcãiáåƒÞ´Œ®"£_»‡_;U8?�mnÅ‹P^ ka؇ž�÷€�=‹þîï²û¤ØE0O‘b8 ÌQŒ&þzm¯}¯ïÂ{¾ÆÇ¥¬G‘ŸFLaùiЦtš}:ÃŒLμÂÌ3­{Ì {Vohí©¿«ÉxòàÔ0ˉ¾WÎÜõ'0{¡'yYâ¥hGêYÂ]x=rÅocn¾£<›õdñš÷+ÓCÕÓËC^�M½×01+fñK¬úv EˆüÒ0”iÅ‘¡ò¢-¶ý¬·†§…Ðx%µÆWñ«‹Ô:ÆS•¢8°ä_n,4zpÅ¢ü¬dW� ¼îᓽñ“Øñ_³:7 lQaŠ`‡Ám®^ ŒQìúuÀ 0ÛüúïgûFÀI  \�‘ÇùøbÑ/Y/"¿¿_\'“b Ugs¯ÅF¶Ö·õ&É”�«Â즣Þo£ÆÕ¹�(ǽåïÞwC·œAî  Ù_–^âšÀ¿]ø^dÃ_`þÕí幬';¬¯õU1µÚÉÓ©!¢�è©õ‰èV&j´ç7לò-*ÅäçmškLMR�¼£Øxí—<‘èÃε ^%t½£Ì6˜Ž«„þF?Ó×�6\ô¶x10 LU ë üÙ¾øŸNgúÀ°tÊa=‰üûy¾å%òçÑÑÇÝUưã¼È8^« È «iƒQŒŠ/jQi¢šq"ùÀ9}֕ߺó¬Ürk4}ˆ°ŸDeÿaaéx1uã͇tôÆ}( ìšFöÌ$ {µ¸& AØ›€$¡Ÿ>@Dv­Uþ�Hñ³Œ"ªZ¦ . küâë�‰"/úpy&댡畸!¬æ¾{0 “÷Úª *BC¨ãóØ?Òûg`V 2bðCà{J”X…Úy±­‰ÔsøËnèä=Òú=»Aüâ‡<5¼í(y\ôÕ=“CõO¢ŸÿØ/]xìC_¸3 ÝëÇ^Y0T€�}`sÿãçßÑÿ~­oj®öÅ~ŽbîÀŠtÀƒý(@³oäyûeˆÿ’ŠüFC;~5±{ŽËe ‰ !W"„@1 ‡€)ÚrD%ø`"`“H;3?väî^K?88'i2Ï,ñºoûØÛè½å–°Ä·iÂÝ}›Ìcø¹¿VŽ'�iTúp’$$É^Uö Áì>„ÌÜB˜í›ü¢è^´¸,äá¯õ"¥{ðºˆBøÈë ~ôÈ ÿúÎ%–<A±H£×Ó*¦x Gr§O„¶ÚüZñœVœZÔÛ xV�Þ÷ŒúêšôF;¤ÝL9þ9L~Jùl«¯¶¯%O6yþM‹i¬-˜:÷8Fƒí‹ü`?0lë7¯¢H4úF@‹"%p–‡ë>ôÊGèˆüô>¹m8ÿô{¾Äµ´£7šZþ¯ƒ° U@1êT FMÑOj㌅<Ó q°|?§ýë!x0)‘®�êyy'Íßü~cN³è�ß=KÃÞpÐ>Èl¶<2{¨»õFrŽ�ÙUÄŽKBáÒ#ª·…Lï9¢b�°ÌLÑ­T Ñ~ ÿEVk™2x‚^ áïEgù[äÅû‹Þà’õ‡%(ÆÎɽ×I®Ä«ƒšÇÚÇZ*š>¡·'•PÁú<]¡võ„i?ç§„¡k /¹/¯}âWH³ÔrïÝÞ¦9²ö7MùP]VQ|_´W¾F$@ú"?Ö76SÀ&`ðý‹â€Ï•G| D~æF<à9À‘ä{~ñç“ÿþ»Ðó¯ˆ]çߺÀ·‡£x ÞcÕƒø ÅôÉØØà¼’E‚Xõ±B¬Ê 6e“‚‰‘ÈY J†×–wì o™æ2ssŠÛy€Ï‡S ~`.™œ8�È{æñÉÊt®ß²;Ûó^™â®£evs›?rË´™ž¦…#¢ºHM %OˆSø7¯DÏþ02ò ä%†Dea庵ÇPúOåÂ[2D6úü¼úSVz‘×ÈW±&0¤©ÿçÂý@ñ.î æ†Qiïú÷��W#NPwaóUÄ+G}¾Ô#T_{Ø‹·kâÒ› áùµ<ýÅ1¿³ïíÿwàóåQ]"‘ט}»ÑÃ{ÐDá`Ò:pÛ+>ü‡Üöñ÷cGÔâÕNõ‰äÙÁA<©ÑT3,±MiG.|¶™>’Í(5,õ`0 ¶ð$TèªíG,V®Ãr6(=ƒj敹…L””ˆù³ Ξ»óà¹OÅçÞ'æAºr;tšë7�`>]Ø}dFëãèÜaÏaF ¥ÿD üßÝŠž| 2ú¿ �/=øõýxõV<^©E¶ÖéH°=ÑŠj q›�×òi´©ØªNØ £ÑÔŸáNý´vuàÜY*K'Y­+vQð#¢ …À?¹[ðJÖ%/Þ¼xeNþÒ‰¼ìÖ "ìK`Fû÷'fw‚Þ¶ƒÞþiîÝóÖÝ÷m›?ø;ç3nMë~š.ßÇ 1bÄûÊG^xsú“Ÿ=;¡Ÿ®gŒû¹ºbÙêF¸ Â6ÂŽ�³A=Ue”˜X"UUš‹ª^ˆ´×4ha˜6;ƒP ‘ r‰[Ž/¶r½’Ö§®àœg¼çø¡(~€£ÑiósŒÙs5¡ÝBè*öZiñr(ì3ß?½ôh"„"¥&B©  HBbà°ÂLÑ«taXÐcãYÓý¸ä� {AEPUdÈÞþO¬Û"Áð‰ ÇÞŽ ~¦ø§�+OÄXéE‘ĈĤùLjä¤Jž~^ôEÑ“ y½ˆتàsÅ�ÍøØfÇÿ°ášŸ÷õù÷Ð;Ù±Dà‡‹Â›ö…}-TVÖ?ƒyð6àw�ÿ«øK,òˆòš½gÏýî{fðÉÌA³7¡GÂgäþaÔð+þ8ßÚÊ+¯²[ë&ýÿþã û;ßžìѤ—·€/]ÓX~‚c“C˜t”•|“Î…mêÃÖMI®×È€nEØ,“ýŽW¨Ò¢HXSj"4h3T¶ ú¬ÖÁª‡3¡cs·ªÚëH�s|‰36’å`x€ÈžaÅ?T¹‹ÓY“sü,)óׄƒÇFò쟶{» ¨ïD_{+>4!‘Ãì’L2Ï.¦Ù/¢¢¨f¦aߌêÞ¢ °¨ DHöGöª…�" °_öÊ´¢B¢˜5à©¿\ÿÁúû›Ðûß·#/û£RàŸ&Ä^Ln5TëÆæÝ€3 †a$ñmP1Œ›h`±æÛöÝö¡ù¸+Ø!!¬ön4Æ<÷Ù0˜Qùäݤ Þ„ªñ,ý&úÐï"Q·�z_^VÏ@x9ðÓÀ'�_)þÉù‚$I8¸71oÝ…ê­„}'wNþøˆËþlÛFNÞÄù=É=ð º¶ÈæQ̘¡£Ìw˜f¸�tpðæà¶k¬²X宬¶qqu(�dC{Ywh�+CÕo'—«ðº /# c CX "„ 8DPQ¥á�i€@K¯d XQ�1yÖ¥CL—ßЕÈ;9N…Œ²êÌi8íÒÁ%b¿|èŽZ‹‰ÛzɃ»·¡óÉm< ܘÞúLñÏÍìšÙw#�P!= {ÌnHTûKŠeŸ{.¸ü‰¢‰\<0ê)¾Â'nFï~;Ôc^úûeþi„G-U yЯä½àãŠWÁJFPZ¹ÿ¦Cå6…�«Í-¾¦»ª’^÷Øù2A•´û{¡ö™ÏæÎc�Í‘EJ>†·íþ}«ð/nÙ+¹xy߃ÿ;àí@ZÉ¥~U E�Ïó缋5éùAþ‚Óâ ï쫼ØK�=Edÿ~Ì‘B’Ð9y`w�]“ªÉ.™™Fu÷cåj-D�¬íÀ�ðˆ¶HŸè±°k79Iç¶±‹Ìï~�7ÈíìC¦#ó3*"^ªôt‚h²Ì•ôÌ&œÙ‰‘-Z1“X?‚qC ´õ+F<  DªÔŠ‘ülu7úb°w '¸Ŷ»´XÆuçèþý,ÃO˜/1wÐpŠ7q&Î’³ñQæg®§¹ë—Èo9>£‡ÍL²W8<ƒÜvè½·À-Ǧ‹N~HöJ‚($Bòpå©ñ�à‚âÜŒÞýŸ >ƒ¹å‹5›%O‚e-LÓAB¦Q08 B¨Ùv;÷ß”#m"±y¦°¨ø�q5¿îuŽí/ TŒ2‡ÚÚsÈåsÖ;ç­¿Ö-•O÷²'¾ž×øÏ÷~µ<’'Cä7pŸ\Í›ôÏù ãż^^·êïñK©´‘¾0‹^iÙ¿ ³ç¶ƒ>Aef¿ÈžéÝ¢|ÌAeïÅ_ƒ ©oíg¾Ù³V[¡xZˆß¾¤è³Ø n÷"ËìaQÐû`Ÿ$$æ`˜Ü‹™9DÄè¦A¾Ü¡µ2Ê€Ná¸1;`³®#cR 5TX* ‡ªˆ�õ7é"`d îÀ*tDƒh@ œWŸVó˜&5šG~V©š“¤œ²ÝðÀ/Ý˽õ8߸ï-Íh€ÞÀ‡IÏN‘ïQ3Ó0s˜„}J‚ 1»w%E(ÿ© ÙçFnÂÝÓøçÿÆ×�“]²nÉñJÈ¡f �8,’Î-Âÿvðݨ’‹]î9à››x‚z§ØÓÒ3_ù8Á•|ë[¡åñG>jÉÕÓTëGÄÛ´ï¤5À׋¥i%Ïdnê û!à?–ÿdŠü?ð^žÏ�òÞćù¹•=z8Ä—.h¼HX›:“ ²äàAd÷ž$$ I"0�(ûPI>V¨D’þ§{ ]¿ j²Vq§ìcÿL"û¦Ñ¤(.¦ÞíÛ§ ‰Þ6�®YìÛK’$¡ “xÜ›_s.?´ÀÒ!n��C_JîE“$È-·`š‡®1ÇÞÑŠøÞs#œŒ®bÐl·Ù˜°3ä²…žn–œ�jÍ854–ªŒª‚Äô{}-Ê8ža”mK„U|Œg–°¡º�Œ,®t8M×›ùœždËN‘øs¼gæ,éøâmwùUnÜÚ†Ãá) Ùë®Vî~DK˜[ k•O�§!ý}â&Ï5ÀX9‹¤‡ƒùÊ·"¯V F.Ówª¿QW¾»8llH7gØÓæôWc^q0‹—ŽÂ‰Ès°S¿ªø�~=X<Þ§Š­•}/ÏL®~ø E5ýJy$O¦ÈßýzË ¼žãàj¾��ò¶GxâÅÌÙ�!)ÜoA…ý`@UE… Jþˆ_PxòŇ¢~¾/j5µ«�è4ku€¢ÐU›KpI@׊ß÷¢3{1GŠœ7"„÷&ª�¼ïÀ^ÑC$:MމÁŽJ~¶(o•X¡ ~”Cñ–Дq–ý–õ"3…Õ­4äzŒ`5""ÂaÁ…@¶6uÏa Ñ ‰¸žÈ¿RûÑT3�2Kd±IÌC+sÜÍrÄœ6Íp¼îxP¶óЪc�/Ñáž<àÞ|û¾ayhWØŸö{  û,3‡•éãfzÏ¡°8¸ùû}„ƒ¯ÀÈ>Ð)ˆÈÉ© ¢`=±ËÈ«÷ï4ÝÛÿkˆd¥â^ò«Y4²þ¢¢¬J^œw+ÖÞhÃÕ¥µÊ‚™õ„±Bžk¨Ö ±—j/ ½jÕ,öš¾?Ö–UjjH%&ÁÌíÂyí-ʇª1p~*:ÏU¢l·5½Ê{• LªÊœlÂÒ`@êbÔh@%GÈŠ´|¢¨V&��,ë.¢PŒð³ø¶E9I 6ž­ö;ô,™œDåøû†ôÂ<Ï=rnÏÿ!s[Gh^û í{Þ샛äÍìa,L³GîÅœ™Ö�>&’únOÝ[ò\p‘gÔ’n`ùÎÿàˆ—Ñç¾;klná»ÅYXó°Ðg±V]µ°2*)TsÓq¹’•ÏÕuEðjBÐÐ J0ÒwÖu#•@«o‰Ö„X„ükxñv›!œ ø¦Â¨!î€ßd%}Õ÷ÖW« ‘»þ9nèöŸ°­ÁÜÛt©hÛ“GFìZ‘]™‡³ ØG±¸æGx8D_:O¶ÈçŸâ/ååÜ%oä»ôCüeo û´oìöÂAPØn¹ã  ÝB÷à>޹„ûŠÖºÃ2 Ìž±[ÓúRGk08^=µzE8Ç`Êeì¹’†LË8Àh„ "ˆæêûAÓ/J´ 1Öív ªSL5‹@›ÆqGhžVf9-_~ß,¹j�S½¶}pæ‹C§™h�¢u`é»þ€Œ4tÿ“‹°8A<^ÿö'ó¸wŠðªwã£fÔéñðÈÑ¢æÎE€UéY…^_ô�Q²rvýº£ßc$ÏÑ ã©èš½kˆŠ5³Æ)�ùÈ5®4i˜`¥Âø�x‡M ,8òkhæeëEÉ×`ðsóé‚2ÿÔŠ< ú ŸbŒ-|žß.�à°°·z³W.¤úm…;£‰ºUö¡@‹DšÐšë!GI #ŽiÄ)�¹‡“ŒD”¦ìÃU:ÈŽÐÓ)õŒtR”a 5ªTUúi‡HÚA¨ÆÀ„ŠŒû.Wa!�DÄ{L+ÕœÏ^èq‹™§'÷óÑ;orwŒr+i‡äŒ°÷4 òæä}Ÿ½—?Q¤¾{ô8µ³Guȯ0šÕÇÙ)³âw0ÄRekpìÔHÆE}]„F *б7Üžë'N´üè®:ßý1O¯US•mDù•˜®·«Æ�Qœéñ¼h•H:(]°-:µ9–sœžu ƒK|u㫵ŒÕ8g©žs®î¢N]+Ô%#SG®DA°* yCG™Ql\äû]q FýÞn¹‡‹üˆ¸�p}!‰Ìãx¨éÏM¥¨#ˆÀæ‚f¥ zýd{ž+¡§ã˜ÍãÄ?HèYAœ!ƒqÙEœ_;¿‹ÆËævQ1ãBö‚çEí�ßgËYüÙÿ‘Ö\FŒ Ùß|?ˆ��W´U[RÀ$ð‹}�ÿ¹ˆ¦ä©ù0DÊßó³|‰(�dÍa/¼ïoà6ð8E|Å÷’þ×’GÕ$>,>Ir±Z­ý¶H Aß·öê{[!wû–›À©µ»à�ib˜I„|tPÛ��j{[*[˜Êšö N¹gU?wû÷ödkN{§å׿Óðª/ΘoM˜ôCä8S#òˆ³ª*ÞhÆpºAÑ€µE¶,™ÂkË÷â´�#D+¸ÚíÊœëÅK®[]¢5°Ì©‰yîžhrl´;|ïõÙÁdä:ïz�FÏÐX�Qk]§èÔ•N5àÐ*õþqõ¤GW‰\a(4¬¹P Ø Š­ºA±.“©Çã¢P¤°D.ÆEÞÐÅÅÁú¢IÜ_^^h0VLˆ5ľ~ÃReQÒ‹EEaPX¬8w…|P‹þõ†gB¾¨�Û¸ýò[rvü¸“zu›È·½†pﯗý IDATÁéE¨Eua°ø’‹¦h“î üÝ呬#‘çc|¤<ŠË ø@beÏ{W�Õ}Lߟ°F’iòû=;Þÿ¾jÝãRå�ëw…WÞýe¦²­Tt,eŠ�l«�íyôE¾ÌÇ×-«÷ÛÐI­›­ZuÛéH@¼`Ýø)L ÃE3!†@�œ%åÕQ‡ŠtVBuq%�štªó,ÏqߨY��å+cMê±`›�ª…–†žP¼—+Xp£‚Öi,-…Œ PÅQ"zÕ.T›BOÀÇ9¨¸*�F™¾]$ÅÄ5À£ø˜Ë2Õ`y¸d6Š _{s»¬ræ!Åo/F϶£OSbº÷;�v ³b_YŠ[òOü/ö=ù7w–G²ÞD¾äòˆ> �i@÷‘ìK �›øŽú½¿ã©Þ¬þ»;®ð¨bœ˜vä§*_ÁM~™öˆ2n ‹'=W]QÁ-––s¢­àD‰ÚŒ7'eñEÇyáìO›�z£V©È�«9`f ñ2è†bmP͇ÉBoV U l� ìDùn<¥h´‚¯.Óṉ4xšÙø�j“Öd“Ó+œt]æªyõèuy•žxzôhO‡�BÝq‘Qçr�:1 Åáétº!rÅ�G®VÀâ¢Þew „¾Àøú=2°-­ù+Mîmð¶¥ÐSˆWBíî;Bz÷„o{§ròñƒ‡è•ϯ’Ç¥JÑ¿ø¡¾À—u¥È—\O¾Øt32³ f®ßÐàØ§~o_06Ø{÷RºãUX³“Ìzœ*šƒ!bP¥gt„g™æì™jL¤WÊ‹a‚aÓ¦¦+ÌŽÄ-–¯xwئ4ºƒZË60&©ä£œªÍr|üvmØž7Ø�m`ÈM…!vå?J$#X�X…UÄH-Ñ,Äv·RYþ6¢lErRrÛBÍ2‘YYÒÚ Î.³48ËÙÑ9N�-rç¦óüãH‹Š2Slúq¢.2²²Öò×Ȭó±¹}/.3Zˆ~Ôï¸|Âö1Fòþ‹l0�ÕÇýçBEÉž{ÕÇ ¡zuƒÎö+‘wcOhL„çþ4pî¹–~|ÉãQ¡Q»øáÒƒ/E¾ä’»òEÍß4è [οË‹MfÞÕçÎhÕ|§8õŽ4ZÏ ÝˆªÒ¤©´£ÐæÒª´]ˆ"`D¡Æ€¸k¨vMtwè¹ûÚ)ã͉¹Í'¢9e¸kèõ”Zs[p·û®«fË È}D*¼ñ¡˜Áð,ja Í12B�ÍÍiª�Ot€ Ù•Ôt#Ajˆ%Ò¿ è ±L,À¦Sž[$ãõ’c¤‹‹š´*gXtÿ~¢#÷˜_^…i¼{£‡ÎÎvBQÃ^CcEyð.¨­ÒtjU!­©«­Šs ¹u5¢TÒ´©µö´�‡ ŽšÔæð� 8j‹CÁÑP7�›”¶âDéE.êU$~õÙIáÃíꪰy©Êß`œ„îypâø– À‘JóÚf•Ò!vÏý8#ÙKqšÉ Ö´"– j¾‡b1ÔQ·Ó½žÉ¦`¬r£WrrœiÓ‹VÐh‰–Iã󴪋´8;ºÄƒãKÜ¿q5úìöWÍe¸7(+ÃKÅ�Úô2e¨ai‰'‹•!µ›–F9‹Añ¨©�È¡i}5z¬*q,Ô#K/Ó¯x· ‰§£aÌDä^éI /Ö$#�÷GÊR|ž“aÏÍûë\‹°}/ÌQ™�5Ù�}üíJ2°^ÀBm£¡{ã–Èíü±ÀÆ‘ +]ÞFug#·óÝ8ÍBžU¥ýpñ}IÉšnüX_à×¶Ê•!úRäK.5{„@QRõóÞü66|¡Cˆ ôrŇJn5 Ž8¥†“4�u­Ðߤ¢P Å÷ŸÈ\±c,¥§8!]KÚ¶/ž#àp8u@ºö"ÐCyh¤ËCtáá™ Ï˸/ëLÜweºðU÷[ÜÜþ cÑ&on mfÔoeAWÿŽ6V[åJ¹‚ñ|cùSñׄº^ÁªJŒÑ1l>�é�A¨K !#�kÉy…t1’ºªÉHíÙ•fýËCóœžå7Í2W]%w<¨°Ð×ÓÕ%O�¸¶\7i5˜ÁUQˆu•\{ oè44ÎÁäø˜X:䄱jrUVñK uäÚ¢£!Fð©âQÂÚ„Óþ9ÊzÑÏä¹ÎSË¿êÃí¯¤ûJ¨Ñ�¢øÐiQœwBÝP÷X ¯7®ƒå£h–ÚTCn×>²ò¥¢äbÍø `7ð€O–GRŠ|É“‡é[ÖoÞ àé¸ b`Ø,øÊùÑ¿õ(íÎÝ5w5iÔ$r#XÔxV‚£§õ³n¼}7‹;|•NÔûž¹¹¹ó&*:,ÃaTkÔ¨š'"÷ª9Q˜ ¢ƒTýU?]/WQëW,(Wà¹M„@¯Ð‰Ïã*Kx»ÄâèYþúÿgïÝã-˪úÞï˜s­µŸç}N½«úA7hïnâŒT+´òð&N¡Q@Œ¡ƒ1Ñë'1êÙ£7šs5ŠŠ"QÅ:¨( (ÕÒ@·Ý4]ÕM?ª»ž§Î©óÚ¯µ×kΑ?Ö>UÕ<”îP]û÷ùìÚû¬½öÚ»æZkþÆó7ÆèÌ&ïs†ýÅt/0ˆ•Äú ;Lj �†J˜†ÂFQøp !²¦¡¯K˜CŽ‹!‰Ã¶âBB’—†‰ÿ‡zI†²�âð0aÅà7}è¼wgœß0Ôƒ?¤?ñ*_9ý[dKÞQSècsQ7 ×�p‰àoþ#ð¡ËÞ“‘7?"ùžÈeÏo¡ÂüÆçÜ€Wú±ßÆuÖÑÑ6ß`B Ö4(&(®½q Õ•9Іš"(Àmƒmý@VÆžÝËJôãDi¨L‘¦Ì A¼�M½‡;£3\o"Âj… cG6ÃŽ|§ÙÝ}“6µ¢¡‰1ˆ@×+PAòmùN¾P&V•gÒãc(/ô¯g›:4éI–·5³í´{vƒ¿ î0]ÒPóÐ y¹Ó¼î,.ñ˜Pò­¨Hû�ª$à1Ö�;ÿ•íÚæ#�kNî öϘÁ­Ï˃Á‚O}š¾Wx0öF~‰bµc]Gì”�jHÕ¨qeˆþe”e¿~‹Ñ"ΈäGxR‰þ‡†�ßÞe_• YaÉ3n �šmwÚŽvM'Lû±��ž$œÐ‰~ƒ* ¦¨›‚ ER­ããvâãOO —¤Ä�$ÆÅ’zôƒÒÓ8ÇÜ  ¿AÜákùç°#ßGÎ$f°n ¥FT»#Pa’Éb�›Ä›íœÍŒõL;Š&©1XfÕŠJÝ¡iÿ1.Ì}ØI^A�Lä�:šôžßÙÇžt7iÚ§§º¶K?ˆÓ,õôÅsF’�Pò° ¹åîÅoÁâqt90k7¦÷š¢ªžÎ/bï»Ûºø$>Â1¸ro—*N´Ì¶ÍçWy„ð;�W?7$ø‘×>"ùžD‚ÿ×À¿~wHòWöŒôh$UX|]]À„thO´¡-ZíWH˜¤XÚ�Š,W&V®3í¢ëI´hWïlCfúÓ’KžNÅ5Š éOobç'’i}¥¢f¦¿�âÎ ž¾ó¦œæ¡b‚ºYÛuÒ0¦†§‡S,Õó™;Ç6+Ìš ¢ëÜGûé“çNÜì‚äß§fŠ/FÔ«gÜ4¡Ë+©4ÓqzÍÜt{>÷ucyZò¾&{© ¨§ � ' m–ùØØ;Ã3ÍÔ4±´]úªääÿ  Õ� cõ`“koUæöxi º„•ë4ܼÛ!`2¡{ºiqþœbÁ¹úè.ü«�ÿüÒe? Ñ�H~„'�Ø·ž_üà=À‘§„Ë•„ÚÇqI˜–I»õ%[Niw@›ËJ¬&Mt�   Ú§£¬ÀЦ£E8ÜÚ\ðkt<ç¦Ê1ü,Ëå¶8å T¨ƒiº"Hcþ¢ñNæÔúÙl†¿�P'ذ…¿!­™‡ëƒ”:iáñ0+!ÕìôÕ ñ¢Fª¸ Ë£Q7'UC¶ÈgŠ€§§×ðêÞè‡+¬é&LXc…»ÁÖ*÷5×Ò¦34�5ç}æÂT`F¶çƒê6[L[‡F„nšwÿ®šJEü×ü¤°v:â�? óíÒµKjóqu�„U±.!wõ¡êݪŒQ�°lWk3 çq=ã�¦‹€¶/l”kù¡5¸Bñ£öÄW þÉ�àÿà>ç½Ñù‘üO0Ñ¿øIÊðüÛa´tú„¢%¨BЊU¤Àé’¹@G»•;çðXO¡Ç×»âãгÚà”$œ¬~Œ§�M›B] ÝÌ…ùH¼w¥á%Àw Éý¿ç ˈäGxâ¡À·?|�Rh7"ø'%Ê Ž‚B!È*j3ërÒ²1LÅRïëù„¸<Ö’ßCñ•\êi�øîLó�[*iĤ«3Ž“…Õ­rú.©êkS�~“ö ‘IßÔÂ*Þ©sà•¿ªßÏ\öêéz&U\®¼ } _›~煮îêñ«K~åÙòç?ö±W¹Á™eNß9`�m,�UYª è´ê…ts1ÎnV]µ_½–M&»†®uÕ¤8›*FÅ…œ+‰Þ£¶è…éµ€næÉ�'©@Jî½rÑÚá À-ÀmCçár‚yï#’á ôÜ·ðÍÀÏP*èƒQc÷' UT  19**…–ƒúºØÈñ9‰ÆÍØàs¸NŽWBgâ¼í*cš+HÕ„ót€óX+#!¡ä¤Jh,©saÇù=áQ®q'uÃO�E jÙ,ê«ÒôMí®Ò‰ÈIÔ‡¡Ðl´Û9SÌѵÏ÷Íü·™1œt¿é6ÏØ§žÏäie/PñŒGIHi3¨mЫ­“ÛŽëDm×­uX©·9×ìr÷Ô&•°HÖMæUª®. ±‚ ¹ñX/„*®ZëAQ¥!`M‚ò¯P*àOþðFà÷€ÿ:$øÑ¹‘üO‚÷n€ÿ‹2|vÏÐÊü“éÈ“j•@ð!H¡H¡—Ö—ó¡³Bl<>V ó{žÔä¥j¢R7„FÈÑ05Þ‘šËv¢`É1§9c>];['KA{W7ÀѦm”ß‘âMÎDÞ”ö†Ô�¡ksàÁ74‘ˆ¾váô ²©…J´ià âkWwVꄃ=ÌöË |»UËŠ¿&úÄ8“™vÞ©­æ›Q›3c+<Ú¸ÀÃÓ]N6crñŒyËT¦I;*èÖ=y€%Á‘+6…z¿úñàG€?¦Ì…Í/#’áIÄó�·÷¿È(þùÀ•¯H’jˆD5AÕ+¹÷øƒ!$ääŠ1Bhïµ’WÉÉÕ‡¼Á¤©S$'×¼–ôS<ø’‡^oHHö„¼®=R½qO*¾y¦¹Ù WÄ“B¥fÚé†7y¨Ä{ð÷íx˜ÞO¦6ŸgÎëœ~FÇ?õþ³§ç8“|¼ö§ùê®5¦Š:ûVÇÜ53L÷§˜ë]ô¼˜ª–‹ìãCŒLeSø¡í1ÑfŒrÃùœ[½Ç‡šq¸N?Ú Ý\%Övƒõ©¶»ö87sïxwîÂ5êqTY§í’FO0ê¹ÅfÐÅ2À`U¦Ò1©P11}㵘J,6½4uÅÖ“‰RÏ qäëEM^Sʸ– €Ø–"Ê(Ã¥…,¼dPE*Ô�a3pAQEå©Õ¸èË øî Ì…/FüˆäGxâ!—ü;€”©,#‚ÿ?âʧZ–.”­2¿Þ yÙ“r1x¯ ;á¥[§+/ÿö@ á�܇oo¥Ë ëÖç¤Jâ/?Ý�¬ š˜oòof…xÕá'ð¡öô¦¬ÿпvìô¬è.ÿÅ·ðÇùõ§ÂÙ�üêÔo|`¼¶<ÕQÝ8ï6í}»6]Ã�±}#îµ ž³ÙgÆÏ2æwR÷SÑÀªêft/ë<ÈÝMÄÓÅ."3޵!¢ŒkB1Ge ìì¬W”>C5'°„þ b’¨Ãjõ<ËÍUNÖ×ø³�gxd2¶ÔIµÅÃF%…í±¡–,ùøÆœ¯JAAJ®eUÁ¨3©q=1ñLbÀÂfÃ{Oá¶Z » AZS(‹-Sw†(ˆÕ1EàJnK%¸ªjlü'(CõƒÁ�H~„'7ÿ8O¹F6"ø«iâ=ÃÎ1~U !>Ô�â /3ýo¿Õ›Z`ý&ÿø×òÛ÷ïä±ýÇàžè:É´nL­›ÚFÍ ¢PJ»¢é9ÞÞäá©? ¡ì_P7Vç|�©|os>1~žÝqH·æh ,kRð­ñNžÛÿ^®ãFª&ë%ÈUÅ(V�ÉrÕ MuŃä`bež8¾Þ ÿüXŽHáœévW+mîNvÅßLòÀ –&/°4Ñ¡=wέ'œkdõ³3nŠ)ct#X÷…íNéâp\:\0‘PJQhD(ŽÍR8™¥žØk…šT¨IŒhQñBE…ÔhPX-ãÔWE´ú™”i¸÷oü#’á öÞ·¬èçR®½¯Q®‘uGÃ3‚¼© ¾§†*ÞŒ…6Ý·Ã-ß蘳è*žïJì»õ/8—ýÛ?d�SG�(ëËT–ûåÈ á@ÆûV;è×|­ß0›+Q&$êyH:ÖÙN#}j¸Í1G¿ëÈ늳Ê]ÁV*og®¿�ÉlšŠkê”ì¤Lƒíø�ð\_›¦’Ž1ífiSÌêv&õÙb½ÑžwXŠ¥ªH“(ÝÁ7ˆ�³¯&nÂáLB&]Šp“ ܈‹ Ç•5ºõ ´«mŽï\æÁím>²·=çfäëåïÇ×7…ZYy¿ØÌukI«J\÷H ¤õL ¡SñAjµRŠÙ¾½¸ðC"ù¥‡Ïþp?ð/�Îȃ‘üOÑï~èÿiDð#lÁS…0òD=]¨ܦ½?ÛË´]#Їã<ü“ÿEpoQì7»¢®=ŸMíV7Ú9 Ðï8¢�@(ƒlC±Ö3lMëjÎtŒeg¿a—úk…¥&nÐóÑÙfž�o,a§ÎàD±¨Vêjíù^ê>jÏÛ¬¡.ªå xÑÆ­z]ü*2�‘P#5T%B%gE+ì3KD"RG|…ÐÍaÝyZæè�#Œ£ì69Ïy(%$CìàBn7‰£e:õe–êK<6sžG¦7)¢œH ŽOŬՊz›å³ÇoxïêÞµ²§§W˜Ì¦Ømvs*ùÃü…!ûZùþdƒëâ1öé»óYvô¾CjÅõj�@ÀªA\q!*ÜVwaûÏbzSÙŽçæ‡=�8r3 ¶«•uŠh=î×Vâvcƒ~e“v½Ã‰‰6�ÍôxpzPt#_Tb!5¥Ñò”Dº ø1àAàû¹Ôöy” ?"ùž@Ï}‹àwP–‘̇üʈà¯RTº‚Ÿ€<×�ª”žX¢¸T1MɃ¯Û¯¹…âkþ‘šM‰üÒ£YåÃï�Òß»#³ ±X\£bÖ{2Käªdý —Eã†Ì–UõÈ`€K?ê”ÛœVåq”7W^£6™Ï¬œÓK5˜,‹`ÁnT\yäL©YãÜ@;ôgÁ"«vͳjNGŒK•Æi°÷ؘÍeóEye ÎŽõ91Ù«&�¥ i¿ú¡UÝ–<‡F±�q¿“ÈÍR¡JìSŠÆoaýSù6ªº�ªßŽH“€q*ÚA1A”>],* `7Æ+9…ð�aŸªfv“"Ú`£²D>ÖæÌøYî™[âl£Ï ‘“7=ýÀ±¸`£êêDR�ïn[V'\�z�%ïIЩû"Ø ãÊp˜r)‡§V­CK�zvéƒaÛÖ¾ß(�‘�fô‡ÇóŠ $‘' ‡½ bb­¾kûñ„þ1ÖX¡b ’F<§=Ç'¶Ÿ¦@I­P„J#Ãm+¯àºÁë Ô0F ¬ÓPE•oÛ(–ÈW©gÛp˜2„�*ã]�½ ì¾Q•”4X% ÖȪëäÑzÑ[ë¬O®Òžlszl“;67‹¼âЇ¯Ë¦:s²a�`¨„‚5âš'öJ�BPò;E…¨ˆ mør<PO ©× ­))j±TˆÄ[ÇqêÒÊ@ŠÙ¾-èÃfàê�I�ëë_äJ*µºAÀ¤+ø÷`:à¾g4¿ŒH~„' ŒQ¦Éí¦ÌSÝ€W9Ë:yåýôÌB'ÊÆ˜ ¶3é¶ÑH÷ÈŒûÇR!ð ŠZE¥NP\‹Í¯%( ŒÌ.£×â(L x}ØÇ™5LÐÛ(ª]Î��äÔÄçÆÖùÌöUŽOõ¨ˆPAJÏÞ•ÚýÔh‘¢TBAjuŒqÓ÷i“Nö 6 Ë‘¯§5H+>#×"(ˆ+�¿k¶Ÿ* Œ¡©¸—SfëŒ"„#’á Äå!úqÊ5ø]À�çFÃ3a.¸Ýâ}ªeF~3]ëØb:‚;ã<ý3Üí+V­»^2»¤tvú9˜{E�ýø´ô¨ÆÅàÿý 3gjËàJkwô†lï|5­ ï�‚•ê’‡ÀL³×¬4N+ÀÌʘ_#ÖàtTp:|¬˜¾ÖN¬×4 ò±µÆà¨ö'4 ˜ök¤¾Únj$ð²ö.}NÇjÅÍâe‚cLø^S*æQªá2?®ÂA1N MB§’N“²�0¬íZ7³š³K•å»Ä£¦O^]e] WYb£¶ÂòÄ*íFW�95ÙåþÙ¸r|{VO›Ä dƒ¾§’K�V4Z­ùŒL‹ …zfâ"Qâª[Ó¸ý[D‚y>�ð“Àd½Îwözº<œ~FaúÉ�ð{ï“À¯ÏþýˆàG¸7>.+Ý™¦øñ‘lþÐ-Ê ß$ôP·Üù�‚÷½7µž±ƒŽ:ØŒ1Z- —W|(Îa¨‚EQvÅyòA2±5eIP)„@¥Ú}‘à;t á-+RôA¨L™Â9¥bMuÝ{Xc�PÁ°$AŸF0±2§+Ôµ !(ï™9Ç{ŠŸâÆv•Zn¹¶7ÎT¶��V8S½pÝ_?ï±sœ7é×ö§ v擌 fÙ“½ÅŒ¥3>*ÔYœ 4ð™ñŠªÁè2˜&<ƒ)¯Ìå(Š£0 Ûé×Ò4Ü ®lЫ¬±4µZ<2±V|r÷:MP#Ø¡Ç_Q W†6ÈB½TÙïòIfsI~‹"¾ë7“9ð#’áÉÂe©ÚçSŠìNŒ†äªdó²w{–„¾µÍ§jðxê¾àzº¯?(ì¿É“•S+ÈûÕßñ lá­ÛP—5‹u \#4>«‘˜È#9ž§‘³dwÅ•s+è(@•ŠE@Rd ’jGHjPÖ#G£0‰k+IêLHZLhÒhKÌ ý�Ç%Jâ´ACú¤ÚŸ>ëu¥Ú•‰dFÚÕ¶Î$²öh5¡Òî­÷&_J)H…<Ú8N îóêýÍÄ–ÊôGúß}?Î6Æ£]DƒY™iÂbœU{‚¨þrm²=ÝÅT± Î :NäwSóUÄ�!nÉvà©c¨«0#ŽkmÂ?6ßK‚§‡¯lÒ®�§WYeµ±ÌÙÉUÖê=ŠJÊ™‰¸øDbd Z2¿xìfÔŸn{aÊý‹Ç±( -|Ø©l…Eä°"-P†[ Ç@Á#¨¢"ˆª"€”�Š@‘‹Û‘Ò¸‘­m‡)�;ü2UEDF‘„É?5±eF�¿Ü ü4ð™ÑÐ\¥0uÁÁ¤àÝÐs¯ 6Ç»‚¼èY’~Ûk•M�N\@ßÿs‘~à\eà"\¤e�5B3ÞÏ|Ç%j€ç Ga1Ò'ó%š1dý+ŒèËé*¥ÅÑ IDATárUI åöX)€B†yà!}œB ýPK19PÐ'- f=rP@RÓ6±’„¬]yбxT9„.2oæ�‹Ú],C�r¸%CrŸPZ-Z-�¤>Œ,´PE ‚^Œ.-E‘á8"úÉ?•Ñ~–²­ã>=’«>W“¢Þä`ªBhï5Ì Žë¶[^þš‚ç6‘Tàt�½ã|l¶GàŒZ×(…[Þi‚Sò\=`°ªR¥a°¡\yEÚòʇd5  T¤hXC%R§!åÞ<&Þù¦’wÑpM¶s:Ñ›c\wÐ¥ ?õ>jdŒwjÌSìN§™ñ;tGöRjÙ5 1**ˆ«ã¥Nïdz)ÃX‘"W½æ³Ž…vlþ¤$ÿvõëèq'«ÇÃ?x„.§ïzÝOŸd6x˜•êãa�—ísòëcîÌŠCÝEå0@KöϵTç™ÇsŽCæ/ÊÑ…E9ØÂÑB„#æQYØâíÃ"u, ­d‹àeiÿF$ÿTòÞ·"`uàÿ^BÙ6ö££á¹Ú‘â�_5)j %7¡b¿y›Ï¿¶Žäbô„÷rï_¢ÿãKNF¢ ÈB,µ-’Ì:phïÅ8C@0ÈŠ¸BM Äâ®4ÙÝŠ&E`K㫟ùjßI�ÓåÆº�Bx Œ«4Iµ·$Õ°½4€+¥”nz³ 9ÏÞžátTðŠÍ{yvûåݦ‘NÑðcÔiJ¤ª¾ù^â¥Ô~çfÍo°|÷_íªék]fuC<"Hà*x¢\YÅcû+mr–í¶�/‘sFÇ8)ÿ™³®ÙZ=45y†´¶Îcƒ6û7ãã-üáE8Ö:¢·s\Z­¼¸e`�Öâ".Ì£,¶>l/ˆ¶Ùf^Ä�8~DòO5¢Jq݈àG¸S¨”-Üé©¥)¹ !|í“~ëë=AÕèRl¸ç“^?𻑛À�Pk nj«’e™ZWƒl DÖ0°~�èÂg}ý�vgÁÎ3 N>H¸VsŽÁT%`#õ ±YZ]AC¨TL’VËe€¾óì2)mI‰Ð¯y°R4T €}ï©öd&™`mɹ*Û¥ñ§s­}ôÜ/`+¬Ø–7©'Su>5v’�ä;ÂüöAÜ0Ή½Ês�å£äÞ+V�¼ N =qŒÎª•íΚç�¨Ç ¯Ä¨]ÚL5Üìú*«\gÏ·þÆ�§jÎÑû®SbóSÓ×òèôzkeû_µ’dî®7’~[˵[Jë¨9øâo~+ÒZ,gÀyð‚WèG,ÿD“ÎOîXÿà{(+Ú}ì¢ëõD�‹°.yL›P…^€]/QãÅø�÷fµøwÞ]0 �JµØZïá‹#šÀ©¯ƒîm0ñË`ÚŸWæïËõ8¼ñPáz¯y…å7;AI1w¿Þu®“Z2œµ‚NxØ%Ô C¨u=u‘² ,muµš™:t4«Í ®C3«i�ì«ð\çsÐýQ˜üqhžy*\/VD lyŸ�÷ 1¾šL’=ªE“¤‘ã5ËÒfPLŒYŠT)fh¤©ö«§h$3ô«m RÖðw(eËÜ"‘ëßéÐWd¼e›çVкR{ì7ùÕŸøùz¸vcÞ`OîÙg„k¼·;IݹÌJ�Š�$$,Ñe¸x®U«xï¢J` ƒUO€'ÂhjÚF9-�axLËûœãÚð<Ûä®G\pÿrÊA|)ëk�–ŽFžüSˆà�ï£TÓldl]¥˜È-Ý)o|[}JÙcÞA¥j|Þö·î�Þ÷¼ ž»£¬/·”9ýè/cÿð.\¢Ø>ÎpVa˸82ÊÞt®$ÿ04µ,óƒZÍ0–Úþ (²©IËÆF= .�‹'|†��¢p …@Q¤Z¥!ÉzͱÆ/jš}ñô ?Á6S�jÑÏ|Px…%úÕDHfµß¨\¡$©L)ÐW‹ RVæûÑàeè¡{É¿á%Æ{¼x!¯e¼ö]ÅÜò€JKŽ‚ã•ò³GnöG¿‰ÚÕFèlöÙ`¯^нFÝNßÑëˆØK=Ø¡^çÀ�cÔ`1 8õ¨ZI1t1 ¡i:ÃB}¡„ˆ¨çDžðÈf(›Zëžs3f™9c\ë´|‚³¦Ê© Ê™Á‡hó?qìÁqd?zh˜ºÉpð × ó*­¡’oþr`m‰*-Ãþ–œGÞ :º%î.È<(Êa�¡.ðÒ¾f'Ø)ð‡>'³`Dò#|¾ƒ· Iþ­ÀGCr#žRãWÔ2! ÌÅä^Ã4×4|z$Ù«^"Øî%EtÏÝw`ÿèN2¯Ô2 fÉè]œhÜÖ¿�dÖ‚7‚ °äƒhÊDÉ�Ö3pƒQÄæÉ@Qªï‹Ë¦Ü‹ŠüÂiB<Üo˜ëNA›Ž¾~.€¤©P@¿ãË‚xR…€€0Hytò[ñ»~»Z¼|�˜â¥êK³y Ç-eˆN[z¼HËs€ÐË`Šc å¢}ë ášÇú�… Æ¢ÊuÝ™t��Ö²O§ô ×iÎŒdF3�Å0IH�‹‚ä(y0ŠêÞÙ¨0Ì�é�t=(Î{Sà]ÍçyŒãf‰ù†`“8¿�Œ3‡BsÆþÿ°ëz�IÓ�ÖæŽÑkí?�ñ¶oÐ7ÞöFÞxè�ÜÄ{ݱ#bç�›D¾í8ÚõFI[[ŽT¹T Ã8…aaQÔ+e™Ñaò%Ù«ãb:¡pXEôÒ#’á"Á¿ø€ßü&ïù� ñLg� UêÆá}Í5 žå Äè Ê='µù¾wÒ(›Â ¾ð�‡JºÈA6ð>!Ȉ@2ÛÑ”©yQX¦Ú�ª�]áÆCD¦0�Ì£é­Fwý¾çµï�úK¾x@ñï >– å-)}õÙâþn|謃>ô–cXäÂAäØ/kµÿ0ãE� coqJ÷: ¶©È.2¿—@÷ùºÎ¢:Eà+ /à ¨J ¾¢êc¬ª(cä»1ìGPÍU]†Ç:ÇF“f«ÂO?ën:¾ô¶ûÍù·Go;öXöKlcù®Û‰ïjᘑÀÂáè!Ù¿ s|€¶NÌ{=tD_fq«J-™§%‹Š9�Ò&¸2#®#’ÿÊãòRµvHð?ü ð£áÁH1`W0¹QOJlvGT¾å:3ø¶7x©NˆžÏážÔÜþvÇ7!*½oWÃѪ_�å3k‰œk%«cûÎ9"¥Jdú�†D}ï³ñÐÐé�öW,zL›Â<úJˆ_Šìzo¤ÿê= ^=©‚E @í—eÉ•…lÄpYÑšCC†¡% ã*ØO_Ð]ù,ÌK«µ(û0ïóW'¨,-Óô÷Ót5�.ªv]¹žºßMÕÞPxö!¾�0ŽÑ¨•o,Æ �ƒxŒ #�ˆ+9Äò×yÒo7ºó=‘þÐï'XG0Æ0„â1ÃiÈã)¾¼e¹œð·¶•vƒÈV8èÑ´†åpU¤ÒÚz¸øúp Ž£´Z~±¥BKxÉféè]z×…#wokka?|˜£æ=•»˜÷Ì/ríÏæ!�³'ØÎYf™!«]¯.Ýmþ:B¹d/††µ ˆàñN‡¥�* T0º[·O ª¼·@&°:( °Áçù¿¹pôŸ]%áÄb¼xá$aõ$³Óë-Ö37~ñ‹ò.–öÝòúþŽ5ü‹•ÿ†e€G$ÿÕMî ~¸�²ñL>š«õÜ�×µ’CæP ½Ôåã5k:¨aÊä�gï•þ‹ç¼„ m”;OQ}÷£$Ã1!޶2ˆ:dC*ÿB�ÕlÙtÆ"Ö9u4©³& \£Ž<Ã0H ã’ÙÚPxgGçè«Þ SÁV$H«Z°®žõ›½tÿ%²ë½Æ¿ù� _6¦Ÿj+ÐTüP]È—¶¹Œd.’Óå…éDi=>Ã}Hb_„œZ—¶·ÊcßÖÚº†·bå-†Ÿn_„ExlG™·ºvéx¥&¥ôš”ƒÖàSÇ™í좦×2k¯càwÚ€}Î1­1×ȉ0*jUÕC*ŠÊ°��Œ!:\CYùXLˆ¨EÕˆâ2O;ís§H8¿¨æ4“þ!î—¥ÙXeçô#ødƒÙ¸wóÛH~ê¶·˜··ñ×^y#ÂmŽ;o²7¬ÜeÞv“Ÿ¿é.¿(øÈ¡CÈ<°xè´ZÚZh±dã.Ìm'Ž”c2?_FXJƒbË8Ø2Ɔ§¢e‘§[v™ŒHþ+Mð/,#[üå�à ¾ì ÙO ä%¯¨§*„ËBn4¤*¦³V¤4I7Œ™þwÿSebÚè:žÏ,kãø¯�œ‰ƒ2×ÝÕ†¹Ð_œû[‰»ôíÌ(]óJB!JÑтۤà¡çBüýèÎ�ú/~7dí¡Ñ~âêm|ãèAõÜÎ -YnÁ=[9 Ç8"‹zHæ Ú[שè¤noßmwa+;нØâšþiâu·Z¦Q"ÀJÉ�BfÔL�Å`¼oÆ ë…5Àæh’;ÎǼ$Ôåü]Ï7Ë/¿ç­ËÔÝ™°àôoõo;MžaæÁ“É[ˆo¸ù.NÜóóÐ:rÞv½�Ÿõz`QiQZ öƒo!º° Qäða‘#û‘CóêeèõëE»ì°/ü¢™ç‹:"ù'‚àßN™ÿk\ÊœüUIò¹B›«r#«Í–îX“þmGÉŽßrhÉ¡Ö1=Ð:À Új ;ý fèÃëV·À >îŽC82"ù¯Øu<xe'¹·1 Ñ�@XÒn qè1m|xCHñ]¯Á¿ô…0f…u-便 øùÿE~>޲†ÀGuè™yRŽR˜çJÃÓÁ•…r‡¿Ž„!W‚¢. Ÿ}–±�ð~ö~Ëë½Ƀ^kÅU:�_Ôº—­ð¶Ð☰pXPD¼.–5qn¹E—JêúùEdþ@/;¾Ÿ àA¤Å1ŽÉ"‹7aø)j4˜ Æ ì¤Í^0;p\£ªû¨± #Ó�º0+í,‘£9Á€ P[õÈ$A±W„aQR‹W!åÓôzžÍ^ÀÙÿ8Æiþæè•£§$bé�Ú‹K­™Ö ÖoøAÒ‰ŸÅ��¡GçË86G‘CBQ†ô[ÔŒHþ+ƒð_†dÿçÀ,£²bW-<˜1!O4¤"9‘•ü•·Â‹¿êFÍ&è±cè[ß�ï:h”¹ëÖ ÎR®=:øREr[ îœnýå¹>Õ?Ì·E—®?Ï#ÏF:oòÅÔÃ�¾á—Š`‡ûüé’«rŒ_¼Î[p¸5Ô h©:¼dˆ´� 2,pƒ.‡ÅCCkIAµ%‡AYD™÷|ò@�ÖB·…œ=ŸY!öm‰<úÓlzÃ)É8CÊ j<òÅ7±ü‹?Ã*7ÎQ5[ñ�¾2.[Øüh龑SV“ZV(…#+ÀiÊ®½á,žóD†óÃBrˆÝÖU\Š?M …§ü)�%).{—=�ú˜ü�0]ðÓ�gÛzÏàš˜4õ!ÛL^¹¾ißú,ϸUX¬ï¸ûÝD�ºZÖ,åDQ&¸ °™à:Zv$þýoçÔ]´)-¸\×WNQý³54È�ÁÕõQ¢ÇW3¥Ã{.ÞyËÏTÓù~üÔ£ßùߊ`G¯œ2Æ.Ý—”!û’§¶–f®´¿p¹º]µÔ@Éã„¥JmQZ—Y¿ªhkøiVÃGÍ<‹”; ß;z´üÜQmùÎb«Íóè¼}}ùÍ“èñ‡øØ±cÈâ„£ˆÿ5BžÖó›ýY¦‚ÝäÍÝ�½º¦»¤`†„̈eBê(eó œXƒ“¡N Ð>uï Êͪê%DÉðy`½±…¼¡ý o¡¥HË«"#’ÿÊ ÌSV(™>öû†Ä¿xöÐÃo �‚ XúÀù¡1p¸,�†|øø{ß³u�v\÷„b¨ o~Q¨P% !I±EN½‘í÷÷rÚ·—§ÊÄå8ú1ˆ§|y+ÄÍ(zÿî; ¶]+¤X>Ûqöo~ûžãdM óàɬ–ç€áåôå²}üÞÎé ý4Þý9Æ#eýW!‚Š&Pú¬^ýÛTšKðÒ_(xF¯ô ÂË ‚-‚ßò5®¾5ù’Ã/'ô/’‚ö·l¿˜ïöøƒê¡­°õžøRs�£ÃÇçá6rèÇ\,¼ ­–a¡…'  Ô‰ú8w3¬gcTÙc n”*ûˆt· ¸†Lf*@ +*B. ^Õyƒb¬ó†™öýNÈ/ÏzÍæ_9èÐ3�‡d}_Xé:;$þCC`ïиøf`|ø¹ØFÖ¾€°1ü>½ìñyˆc|=Œ%ÎQðÃL‹ªˆªÄÃÏT X×*ã’0¬‘ý8ïb„¿Û“o—½à}Lo8ª^rªâÃùçÐéK”kŸ†¬èñOåÕ÷þþã÷GY„cØ)ŽÎ(„~U;òÓe›Y{ê|÷‡1ÕUÜKþsÀ×µ‹-"/‚‘~¥cÿ‚ ¾œç%§Â^ oç-ZÐ:&¼ û5µií¤°½·ÂßÐ]"ì,<7:‚í¤ºƒÌìq…“`7Ÿg;ŽFû+JòŸûZ?Ï6,Iúpì‹§l®v £×Ÿ_LM}?Œ , €µ¡p~!¸t!$'‡°..÷Š8�£ˆ+¢ÒÚô¤H†‡Gäþå#š%ÙSLHj�±ùw|³Íÿ髜̉Ò¸÷Þ<|Ç[ÉKq}uD☢UÈFj®nT)è(¬L£½D›«�ûÖÿTð‚NA CòA>ôÚG¸bÉb^Åp¥\kУèÅ´—…¡Ä€ý Ç[£«­…ðÐa�c, ,r€E=¦T7]…lûtñ×é:lêˆä¿: �/†>ðèðñ¹‚ÞݳÀuÃHÀNàšáó³‡Q‚ÆÐH¿”Á­®;¹s‡è�…ѺÀ@!W¨BÅ Å®á׬ë¥TÑÑåñ%Ão¾ÈÁ^+˜UÁ¿òkà¥/÷l3È&VOw½ýuòG’òT6p ”ÁÕ­•_ío%áä 2ø|£ ¯ú)xQ�` ¥Ñ=JØyª@¤LtQ€…RŒxX*`+I懴Tta¸ä Ð:­EŽpD„CÉ‘’ͳܕyõŸ@Íâ_ýFÁÖóÿ JñÞ™Ï1„R†Q†üŸlªn_1¨í%+v‹~zNí}…Ó ™6¸î¿²$+. ÖpµO²‰©.áÃ5P[‡Ê(;àK�‰Á‡¥ fÚàçŒÍ¿éÏîH(þLžW>úû¤~– q 2¢¬TG�úêFNgIþ5TÄòòÿ"<¿Wp^¡Q g‹±òú º£ÁºÒqdÑpü¸^hm%ýéèa�J}àÂa µè…#( [%Õ ˆ,ÇPaÞ#è!mýoöÞ<^²«¬ûý>k­½«ȩ̂OÏéÌ dBHDQ2$ " (( ê}_/W¼Þœ„¸8\}_Ä�¯$rQAÔW�(“h@’¹‡Ó}Æ:uªvÕÞk­çýc×ésºÓ!!tÒ�îõý|êsj>U{¯Z¿õ<ë™ÕcUCJ"ò[üæúúíþð²:\à{*Z¯­•_¯†ìj¨3á_?øÇ6¦9Mèí‰b�M¤7>¬¾\ ÒAã"¸E0s†|ܲ�·ƒ¥C°}�¸Ñ­? ÈwÔ÷9#â]û¾CÏ6íÿ¯?7—ÚeéÙxÏõaº¶éöú}›�?¿ ¾³ãVÀG+Н×T#}kÖÖBŒ“Ð8«I瞸໑�qzW;òO7FÿÁ�ÕÖº­-x,%Ç©8MÛ”¼¨´´F§ì9«û\—®5Œ�¡œü ÍN“ɸjE k)à„0ÌXiã£úA¡œ öÐëa,#|Ï[O[¨Sâòáœ� Sä8Mît‹®TrÍ5`vö>1}:{_»SEá£çýõFu # ,‰üiàÚ¨k<©ˆVGiIƒó¾xò¿x3ãô)´maoCY‡Å© K3ÐÛ «» ÜþÂH9Ž ZÐE‚é� ]0Ø +‘ì ~dü t8í{*üÖMÊEر‘"VO`Þy­#Œ7-îà�ºî¨Û£ÀÓ†5ÑMêÙÚd¬&œ³«ßûxY}Î í TïÞïóO¼ >|k^V¨íø Žc”{‰BT‹B©ôûq’¸ó‰¯Vz‚4JÊw~f&[°‹ƒ*¤&5'_�ë> “@{ 9ôztdrùµŽo?ä.”Ý7žÂz:F×'¾þ’2qÚxÌðš@ݾB½[Æ3)–côL{hz¸¸ ̹£†‡§+°¯‰îŸ„µå+Û ƒÝJ9%ì1“Pdu7(íè€i–�™�Ø…Œ±ùHsb?¸ÕoJFq¾1´äûǢǺ¾Ù¢ä~2‘¨‚?,Ò�eíêÇD^ðCÂùc0@¹}¿šýuìï°EK¡)�‡oïÝb�\%´rc‹J'À8éOÎÀ¶.ôÆt§m-Žú"VžÀYWï–¥ÉÈÂP·]õ²·;®º×ã6 Û¤HúDùăâÆMݤÄH¥2#8#7*ø–Ö¼}<Å&ñt€Q8¯¨/€¿úŽa_S°¾þëç]ƒ{§<§•¥éh:;a°-jü•àwT²”×ê ¼Y–…ƒmÅî�È<&_%¶æ ¹ Y€V¬·º÷3liÁAIVh\1– žó}ž Ç" wĘ}úïq7ÎQlU€Òæ�{CñðôrCÇ@È2#¡ j‚Ç©“ÊzµA$'“"ϤÎÉOUïN£4¨Zöý,˜3š<õÿísÕWF1ˆ–1 ¶­ØÊüaÖ¡‡ ¬÷øm€º¯x$Fb¥Ô•ˆÍ (•ä®?1øL¡Ý(™{äg.üµ>/¼ï7¹éiO>‘Dþ4䦫ï‘Ð:MÎGu€¯Z‹úºe\lˆ·wõýnóýëdG¥zQ<}êTý(¾*‡)yNá ü•ÈG Ǻf»Çí#÷nphV·F:gÀ`:Ò¿ü.„ ˆv˜|°ÛFì!° D{X�Æ’c¬ë— Uñ ŽQº·M+õÂfÓBÁ†ŸY‡)…F£¡ë¢#Šô[2xÖS¥ÿý/µ”Ös÷î_?…¿ñF‚¯ 'ÐVBŽ c„:EqÓ±;ΕçB±Ѽö IDATo ´ÚrT&ê–hmUˆØ"jΘ”É’D„MpVðÝáxêŒ`ç^¯Q/0zɯ^ñ¥ØÂPUŠ[_`·6^îÒÖJ"‰|â_÷ÓëzZž׋ôU�z²ÏF…jóÄŸmLTîhQ?¶u{_2¨Ð:â}ÓsÝ0øhÃþ0CgÁE=ÏE÷÷1X}e<‹íܱ³¼�ØÝnèo�¬mC{bÊ'aª)¢dÐñžÅ~-øì÷ØÈ—À„lê*@0Q¹~+ža÷7·¾ 47²ÜÇÙbX3hºðòÿÓóŒqlßæzðÏïÀÿÕíÐ�¬—ªZÌ�µ¡õ\Cà�lû�hå¦U-&¦l¾Ú E^P–VMJ ÑkKsl«^¦…”´÷Ȉ¼¯Ç€k¾c1_ æBäÒ_‰úâ/F‡P=\®v³¨?„:Þ%’È'¥Óå–[b]ñëâýÀ~bA¤«Ž†@¢Ï=ݾ2 ‹[`á Lo+ô·¡å…¢å8è„¢„”ÂÜJ@æ]4¸%sׯO¯Â ýÁ°é'´Ûуää#ÄÜD.ÅxcÂBô�OüwÌûn§X–&¶”�®,7ùq ÆëBÀ‚mÉqùôÃçëèãþãfzKX/”ýäÑ}DfØÝ÷(¬©óãYdéåQÍ·Ã%¿îâ ¿èÙ*øj}›ŽW"‰|ât­KGy\í£ %¾.ù©`õåi|<�[‰ëîzÜ›+ #°Ò ,NVwGæ·Â`Ês"ár$ŽAÙ„ÑÕ5Ôˆ4–£‰‹Ä›ÂÖ=˜Õ`Ãm_3Ñ=VùÔÇ0ø¼- …=f£½½a<çÙ^{×\Ÿºš]*U›H"Ÿ8­Ù´O¹~�b˜�omº¿n=¡Øx»JØZ+Ð?áÖz¡à†Ïëì�qüâ(ay]Ü k[ Ý­QŠÝØøËioïG$Tü|wÎ2:ה¿ÂR0‹mâè!  ÑC6€"K��/†0lXX¶T(ªXäVŠÐUš »@ŒyåhfònˆÉYÿH°4Mdå…Š>C9ó÷•—}7Y[ð‡#éÝq)ð.‘D>ñ¨Äoµ›­úMiFëÿ¾ Þßw”oÎ8ÌRÝôÃl øííZ Ûû`ô+u9’ÿl¢ÿö[üŽÀ�gdÒ]´>ƒ?ÐCÖ¶ÜL$\Œ†q1m#±I¤ÓYdU1+YŽÆ-Ýdm0ä¾ÎÇû&SÚÊX§ê”föŠJ‹h…–m@Ù²b»k¡Ä’ÚÍ>"æÎi”ç ;ÿ§ºW~‚lÆÔ±/ëõè]½@MîúDùD®$þG‰ýÑ.Ðu«sÐ_f„b—âîß’ZÔ;àîláo~‚gï3aí)Pm‰¨U „(¦ùI¤X"lV²ëƒšLµt£ÓD¦�ÝE/D‹qМºÜpf™º�Ý"¸ù:mÐ-€[²˜5°ÃVÂù02ßJ8Ö‚ 7BÑ�Œ6m-%„¨ÅÌ¢>HÁZMCÑßÛ ÷·…Žò>Øxþé64×ê^ðn‹ÔéŸkàFïyqÔüyÊ7(/ûëÚk4 Æs›Æçqœ‰Sà]"‰|âÑmÉ?(²oì~·T7qËà§�w¿ˆ°ÿ'? ~XôF†© "ж1F` „Í‚—Q›gv%Wˆîn@±VëÒ\ è(Ä`t+è6Ð gÓB9¢ b€ ˜E�°‹ ‹ +˜l¡ R3%¦Œ(]4° ’/Îù«äfµée¬ãšm !×#Eúì$îGͱ¡p/½H¢pç bpχ™¿€¾·µ~NUé}Ça²âI䉇‡*]§ãÀ2ž›Ç1{_ý�Mv‘€F­þd·¡qOíe¿¿…^0„Me…É´6õwÜ9lƒA¬Š¢ ÔOAœQd 3À4ø�À$Ɖ…Q�5…yÅJmS¸ƒ]*�+ˆÚ)&¶ùjæ» Ìö®·]²*hyD½ƒp”E4ɵÿõ'Òñô¿¢ø.†ÕgGªÎý›Èsopœ�÷Í�rµ‰DùDâ‘¢~ËКßüɳÑrºÞòI‹°¢j4¿€¬íy�ÿàAºO `”€bc�˜‚�8¼°ÞΆà”8V{⌠ãQý¶€ß®Ø'@E¤Ñ xí·ãÄ6.ÁçäûüØX—µj�Ð –\Âz�€ûä퇣þ®?žÄ¿¶Ã{ÃÂRcÀÞï�èK [ÿÖðÊ?1Œ«?Üpéëy™‰$ò‰ÄñÿøæÐYê×'àì°å~”F××ìL@׆O9…lŽ&¬{ìÆû‡ä(C½¡ÞÕ c‚UgBÈ£­&w†xþ“JýÁœ®ÞkCl‡Æ…Þ¸KÌZ{4Jt %h´D]Çàc'°d°}Áô¦ÜXˆ�þ2ÃÒ•y Lý}ä¥ÝxÜüx"‘D>‘xÄim…–à:äþ’O—Üýj$4�´ÁÍPæóÏ:FëH¶ã™«dãPÜ9ÊZ~ Äð5ÖCd™ÆP0º¶ Í.skùe×cý�ò¸÷üñØcÊê¾f¦¾¡¬l‰´§#½¤Ü ÅYJyyó1}�50«‰nX©ƒ]nP§'H¸ÿÀÑßáX „áw@G6Gâ·OôÔé�º½÷ÊHù°åc¸W¼—ì,¥Zoª´žÿHwML$‘O$N+†ÕÅ6¹L½+€Vm¶û½¶äS?ÚE@×wå#ˆ+1Oº!†¹]‡õõx ýÏCð £åó\Fû•tí¸ÉXœÉèQ1 ##Þ®ž»RÖ:{ðé X�ÅqLgú“ÄöÄoAüYhíYT=HLì è!LÞ&Ê2d `:àJP��2ê@E{?�jè.±Ô©Žþ¨iÊcúò÷cY¯?ÇmZX Ž‹Å3Ð1„ƒŠÏ³÷b4¼Ý~3¼ôOag/)À.‘D>‘xÄ9jâ=œ£ÜµÈ{þ ,?EA°õ" ýñ;îŠÜ°‹Ã%GN’HóÕÒ’P­ˆJ:üÔ±Þk7”¨2ïýFJ¢Þ×–¶ÀHÀ6:°½ƒýQK.(„úE+cuJéŽGV§"kÛ‘b ”»‰ýË€qè ›±&¸!ë2,ƒ,ƒYŠÄ¥Ú`C½1lƒkGÉëëôëóÓÏ”Ã{ÛÆýí�aý³SÞ°ÎBsM ©ø–ö]£¾¦?Ïú]ØVRt&Iä‰'ðP ˆòÛo€ùç"QµŒý>äçÁÈØóì•_uþ,"Ç×S|D>~¿@iô«Ø�Ñ©%ˆÁÈ>2–Ù•"Äc®Mì¦;ƒ¦€ áðývh�Ž3Ø„¨X#6XK¡0p�CÓЙ2”ÓѬì v&Tâ6CØ1ƒ¨ ½a­€6JQC¸ëÈG,ãsÂDÛùIéÓ«“`;ìQ�×iÈFc¡ãh=;+Ø\ð¹âW³ô�ƒŸƒ‰½¸«þÀùÇxOKR÷¸DùD⤠ßÌïýºøâõpz%ëc=æª>ìòÍBnÃéÍ1öÒO0±RšÆÐÍã"ƒùø„GŸ¡ M‚Øv áp´þ}mù Á·Y0çˆÕÀÆó­•zM†kƒ !b'Á/Æõ·-›Š Ô.óX�4anº3‘Þ$”Û¡Ü…–N(¯�þH a® °Š°“-¢v™(ó˜Æ¼�ù4W¡98Ò‚¯]/Ç}ŠóÅwÕ±E¼Y¹]ýyeüÇ‹Þæýùƒ: “Z�>•µM$‘O$Öž¾ƒ?úQâÒˇº � çüFŒ?ôÏÄq×ǯ¢BEE¯Ö5ÃI|ÀFÔù $·R†€-+ C!Þ‡Y»óѧa¾SQZ dC¤Ã×½àÏæ‡CkÓåPðð¼îú^øÈÆÿ±ëy�áe¼9«�å®ú9• ó;Ð[¯7zÉ,l™˜‚ùÊÚ.´»•0˜�ê<ðÓhwéZQñ�'0>•µM$‘Oœ¦dPC!é æŒ¸ðÂZ%ª’{8ã×àeÆ­×ߌ?êoZlÍ“ãëŨ6 Ö ¥ÕŒH‰a7ã.ÒCP" °"õó8¶Õþ€Ø°ü¿�EOØœ¶é ÔV÷‘béïqo °u}Öî­Ïƒ¯ëúT¥à—š–µV =Ž,nCÛ;0ƒmèêv‰á ŠCz#�˜C,ñ¦‡°‚ÊÁ:CÀ®Ýœõ�vÀv-­^À  ³ÑŸCÇ:ð´·Á•KuêeÚO$‘O$N<~h æ¼�9£uљʰã× ¯ý?,o{Dw»GC}ÎK(‰±Â 1hƘQº*€#‚#ä*G ì£ùœ­oç çv ¨–ˆÜ ¥�´˜‘ŠžÂÁ†×»Gaq–§K»¢v*½IÅ?žè§…ª8¨B€UpmÈïÝrH¹âŽ'/yFå¾V|"‘D>‘8bP*æ÷^†îý)‹ˆ€ Fwÿ¾á5‚ñaTtëQøúÎ+Xʦúý¸�n¥ÔûäTm¡1ä‡Ëù�³ØzÄ}¿zÜF­·>ŵï)ÜÞas˜‰,ŒãOÊÉû�5>*͆ ýiC^Ê}µOd0b ÖGª@¡PB™ëÆÞù)³‚;òœ¹cÌv~wýœu÷º«…Ýg ©ãF‡OÜBq~Š6Æß˜ ¼Û´m°þÿN®q’öäIä§!FáÏž w½E‡DT� 3ï¶ñÿx¯wàY6ª)¨·z]Ö¼B¿ª�¸*(U?Î��3Iþó&ö X1 ;£Ëçš¡¤|ÝðÞË£|ùÍhÌ´6ä§þÒðš÷z·nµgC€G£»>äF(­’#”•bGe„e£Ÿƒ! Œ óM_ÚÕShûF,éc”™uè!Ð�çd_罉“мI‡ qjr6¸�˜žùê[Q"HÝeêðCïðn´:Õë‰×ß9‘H$‘O$N|Xżï ô‹o©&DÕ(L~ÄñÒ߆‹*ZMCfN| Þo‰D"‰|"q ÐSâŸ^�~îz4NªZUQ…ñ�8^þ6Ïc¸> ¥2§L ’Å®/XôTZ¼$‰‡FÚ“Oœ¢¼ïâ-׋ø)ÅË™¶þ ®y«wçÈŒP¡Ð;u"‘×Íö2þN)•*‘H–|"ñ(¦ Îm^_¯V º>ÿ6!N¡†º%lþOèk®‡Kd©÷á›uÑS¥ÎxˆGÌ!жi,®¨½Y“Þ'Iä‰Gë‘ñE]ùÌä<â§ÂVÅ«¢ŠŽß W_�;c€óP5´n6Ó×�S'JÚ¹_–ú5«ŸgäC Aƒ‘´SŸH$‘O$øqêt· ì'f��_‡–S "ÂÄg?øK¸Ë†|"‘H$‘O$%†üòЂÿò6â_ýÐ?OPPF¾¢<çMž Öê ´V:^‰Ó`R—´˜MlL‘é$ý|r >øV´w>ب�æ]اþ2re*¡êjùÄé@*k›H"Ÿ8uÐÿœ†¿¹:‹ ª Ò¼}î/ — Ë…j|W¡«õ|"‘Hœ$w}âQBE]ª¶Y×÷ü§' 7^‡t.PPÈZýî_Â}çhAUÅp§xÞxŽÐÌŒ%ÖUqÆ·¸3)ó‰‘Î(8!f­cC ¾K$’È'' ­ºƒ˜›Þþ÷ ø_oAOD#`;dyò <õö#KÕ®w ;Åk�—Qéǘ‘ T>Nv]Ôkþ¸C3,F(+­»Ñ%NÍI=íÉ'’È'uøÚ÷»�;sä}oƒÎÖ·…‘yÓÿkàª;Ny‹ý~°ÀR ô»q±c”SžJ3¬éPZÖ`S5¼S•´'ŸH"ŸxRmuh ïz+Z\ŠH Oþ/�§ßŽÙäi)`À ¹š™Á"àØ(ëK¡ŠŒ¼-FÒ�J$NRà]âQB|ÕyyßCÛß6lÅ"ªv ¾å—Ͼ½¶à«á>üéiÃÕ‡%@@ AÁÐ à°¦$ê(•䨔6ƒP�„ÇéÀY•Æ|"‘D>qÊZíÕì*`ÑßÿÓhç)vk¶d¸â#/¸gj ¾ˆºÑþ4Ãe¿®`[FµÃÀ@ŒªG�µ±¾P„“¬Ì­ ú¥g¢ËÏCÎø#äâéw�H|ó$w}âäzï†Ñôû,þO^‡.¼¤~L@Üséõѽä?pÀºª}ú <@–™&Sc.ÇHÈûx¢AP”‚LÁaOªàúu�_x12õ·˜çý-Ø´¯œH$‘Oœ’øqð-p}àcøÀ+`éÔŠH0ô±ożòæäŒ:½A YS°+ݘý‹‚*ª«”NÃI£òÁ þEÈäßa^ôž$ðß줞¢ëIä'3®´p¾0ðîWDö¿ ¼�€ª­àœ·À�}„lœÔ3ýh,¶ @ sÈò—Ðÿˆ•Ed†ÌŽ•òx7ôËO«~â&ÌKþ)�ÿ›$E×'’È'Nr–pÜ+Ê»_ó?*àìßr¼î£8 ¹"GæÃ§Ÿóaû8GèW±›[z´Ô€xDWX kTJiN¼èWžŒÎ¿Æ>…yÁ$�O$’È'Nü8‘w½2È�¯†hU�•ѳßéxÍû=MȂБHe’ÕrØ„‹Z44‡ûó&ÀD"( åÅ{‚þ?/Cç^£ÿ‚}áoÃx™N`"qüIš‰HxðÓЊuð»/‰|5ên±ê*îwF÷ÓÿÞ§Ž¾OkÔ£–ì’a ÍLèW±O¥”í:”^-"MZ‚�l®p‚tUï¾Ýû*û$öEÿFSº\"‘,ùÄ©Ç0MÎy(Œ:_Šá�^(̽|½g¬RÁöw^û�#×Q7ÊÕ&È�XX+yY[ó£XÙ¸SœŠ!B_OXíz½ûôŽŸ†ÑÏbŸÿ»Ià‰$ò‰SWGÒãqtˆüùs#wýœRY@ÀFî?†×ü¥gkrË?%Ú%” –I|ÖË—k}EµƒÆV‘iÈõ‘¼Ó}g¢w¾Z_Æ>÷w`r�NZ"‘D>qÊRÔ‘ô"ïû¶È×~ZL匉€ØþdžŸúS˜QÜR:\D¿Š�±RK.”;¿­Ì_'TÖ€ä)Z#fXï‘ø³Ð¯½wb_ð«0S¤–H<"¦T"qñ ~ŠrÛ,”cª‚ª(Lÿ¼ê=žíŠKzð`ÈÉ¥l¡êÇrXöwœ`3SΆµ¤Ò¼0±´� —¼øŸÓÁ<ó7aºŸÎV"‘,ùÄ)O†á“�ƒ¯ü?*ý±ú> Lý¼ü°ghÁ´üΔÿ ±ìÐRoÅF�hŒ€%G[=2ÇsCà×0ßõfäì•t†‰$ò‰SÎbïj]¢v¼N£ã¥Q>ñ6(Ô…º&oÂýÄ[pgùº(Ndn1íÉ?e^`û!†Ñ)Û¤²†‡fXƒ‘@Ô víŒÊåeöðO�߆~í'A*ÌÓÞ‚\°�ÎR"‘D>qJ2#¸>¸®h(þ¯/†Ïÿ*Êôáyû$zõ›aw ™(„XïŇa®|UÅHdˆ'(ªÌ•Õg¥@ÑZào}ˆÇ<åz䢃é%Iä§*®.£ê|…rÃ%ÂLŠD¡ûüÐ,<.í×>d‘·ÔžèÛJéW±ªÁF b0ÒÆGÆ2»’?œder(ð±øÇíK''‘H"Ÿ8¥i+”�œøìÛUúµ])ŠNÿ³ãGß W8¤@»oêç+¥i ä´±K+˜ÏzÑ M‚°!>LîúîñK¯ ˜§¼9 |"‘D>qz˜òÀ_žøäÛ¡?- uýä§àš·xÎë®Ù­[£‰o�ÜJi¶¬” Ë^h߃|¯DmQ‰ ðð”µ]%~þ'ÁoÃ|Û[’À'Iä§ÕðÒvˆ«j�÷7í„Ïý ôwŠ u=ú‰ÏcŸûxL·¶à×íRfçCû5�H°Fhf&'HÙlš;ð•`D<^CK%äÇ{O¾h¿ôJ¨vb®¼yüÞtBNÔ¤žZÍ&’È'v|-ôxðß¿ì6ÂTÿ"<÷‘'¶74}|Ók‰P*ÖBi5#†�´\ J¤6Š-«ãè®/šÄÏ¿çb®¸¹òŽt"N©Õl"‰|âa¤5´Æ=¥âo�‚¿};—BP122gyÉ/ãßIÇë8REµ@^ý+,Ĩ-&Œ¢* Ž\ ŽŸ%_4‰Ÿô/EÎÿä[oO'"‘H"Ÿ8UÉFðÇF„ÍBïb1QDT4ŽìG¿ïg—,¦½÷ãnÆS·�±€¥l!îeµR¢‚ªGÕ�Ïÿë76þ‚ßÀ<ë_Ò9H$’È'Nqk _ñÜðveõJP4ŠjlÌÁ÷ý\µ—š���J33%¡Ž®obvÌãé6ŒÁ*¢%ƒºÅlé¾I—n刟�CÎùí$ð‰DùÄé€Ïòo…îå"4ç-ßö&Ü“÷áö“¬øã�èWT}¥× [©ÎØBóõ&bÀŠ¡ ì—“}îzo‰Ÿ{9—!gýæ{?žŽ~"‘D>qR�ù¹�qضbýx�颭¦!3Bê Uí‚Ï‚��HÝ lî W ãåþeùÓëѵ+Eêv¦ªÍƒØ§½)¸çßV‹{+ÿ‡Ã�ÏëÚôäVQ MÆØqúã Fˆ£Â|æKÛ}ˆ–¼ úïWCïJäÌßÇ|ÿGÀ¦@¯Dâ$%å*�®2l(â}–‹3­�t˜S ´Ny«SÙàý… Ü!êT·øÝà:µ¸ÓïÀ}±…ÿë7¢Ý'ÕÝËÈç-�ûŠϼ-õGAPý&×õ*èž�®=9ó÷0ßÿÑ$ð‰DùÄIHD5f"�j´õ1o¼Û¦x«P@V€ xŒPì‹Îƒ÷C Üù¡À»z!àÁóå&þýoD:ß%Ôq]Jk sùÿÂsnKîùƒçxU¶SA¿ð}èòs‘ÝïÂ<ï#éè&Iä'­…gQc�ßoèܘ÷-¬uä�ÑÂa(háñ€ß1ÞÕbï›À=þüç‘γPQ­íÇ.rÉÿMøñÛj×~Ê}$ȱRÖ1öJfÌ0Üþ8ü-OC—ŸƒlÿsÌ ÿb*¸’H$‘Oœ¬¨É ÕÔÏRþÈÕ`at®0�yã‹ý>?ÀøÝ+>,—ô%ÒÊÍa ß—JÕÕ::¾îv|üÓ×WŸƒFƒÐè©^ð Ø«¿ˆ)’À?R¬ zÔb$Ç%WNoyzè¥Èö0/~øD"‰|âdsÅ}ö³È‡:¨¥¯Ê8*@D‘ÞH÷ JÌ F�Òʨ²xN)œÝްOú ó†™J6M˜Gü~dÙoõ}–~õ5ÄÅ—Õû½Ñ«ÙþfßøE�5dF8lÍWåpÏßÕ£/듲17×®_O³ÞnvŸ+¾UݪWÇ dQóUëîéb8¼×ƒüNƒ…Fˆ(7ô>ŠvpËk*·(\öÐÐ<½øÉ�`®zúE%Iä'Bø³Âì,ÕÔØ›èîïSíx%xЀ¨A1@DP£¬VmªhìÕ†Fz¢8E½¢ÁAÞÛQ™ÛjQAUÆ}é?h¼zÞ7ÊÌ—–¨JuÞàÝ®¡ðvÅù�z¬:Ÿ‹Ï&ë>ó¾«0Z ²óàÔÁµ@ûb»â ð}u‡§ILV*xœ¯€ ï6/N—hþ£¼óe©_edåfäÆ'Ñý–:ìÎÖ‡_ ü5Èä?b~à@#¤T"‘D>qq�"ÏcÖ΀�åûïáö›�åÞ…d;”ÛU˜@s )ŠUQ+ ( (ˆGt€�¡x-œÊ3§jy¼AÑ DX•—=ÉžEéJÑ�=K^Â=Æ÷Bk1:3çGW"�Ž×¬Í`¹@ �»À-)d0Þ4Ь­}ÕW…âKm�TÞãÝ@|f„¦|[ñm¥š?Žo�xZÅ�íza�ÿ¾A þ+W¢‡®�±Ï`ž÷Ç0šª%Iä'׊ª ^•¨³Êgo–/¿çßó[oú@‹Îò8K�IºÍóñ‹g€ìQqçÀŃÖ IDATÚÙ„Ö6ttZ4›ç¢ôUÔa´>$Qÿ /ƒÚ5nF…ðü <Ë(Œj¦ØL%Ž ² m<61¨x~ÊCÕ‡¢p´ÔoŸóì^À؃˜é{³åörÄ/7߯}¥}u4¥håBå´Ô¨gZÓBÖ‡¬vUS9 ÷¯Z§ö�ƒo SÿNào»=ðJû öªß‚ÉA:(‰DùÄIˆ ªJ¨@ôŠ+Ð+®£zço¼0k̳Ÿó¸íÖrË-pÍ�7˜‚›¶µð_Ø¢ÝC¸KÏ"tÏ’AçÜÈ¿¾BÍßî4Ñ£jTp¸ð�\e£ QUAA ªB¯Î™7*uº¶d¢.;^‰Ù½KPQbñ^­ˆ Í~÷*aw“òNQíß‹™8DÓ@–}lôHá <æÔa$cœb|R`DðcJµŽ ¨’Eÿ€ÇEèþWÂÈg±/xgøD"‰|âdž³ë ÷²|T!p-RoÌ*ŠpÈö[‘Ë/Gn>ï󡸔Þ%·P\})û¯›åVf1³³öU[Шˆ *^Móú<>éæ’ÞNepv”± `p&ÒÝM´[�‘Åå¨1D£B]O%° gë‚lŠ"ÑÔ1áÕ8¬�¡Á\Xï»×ûï°g²k+�°ˆ<ö ùy¼ØyofÐéÀùŠæÒ€æÝ}". ü×,÷œ‡Þóc0òïØýŒ—é $Iä'³%/DEehѯ§>i]M@ÑÀ0K¸¢~áÕ7 W_]—I{ó,?"„ßBÉêÝz‰{Ý3>²úö×=ã§õj�›€ï‚ ¢\£˜¿ƒ©�~y—a~K¿yè¸ç1Üüç¢æ|ð[Áf€EÔ"¶¶´%*ˆ€~À¨Aú‚®ªÓ@íDv NP�AKë+mUVJüèk;`÷v°ˆ-`ý>²|�XÎQÝݦ_UL¯�÷VñQqaº0øqè7”ÊÔ[ÙŠà·h4c‚º:d±Ùb³^¬ Ùz× b_¡ !«oÛ² „Q££Bè*¡9<=qXˆ>Ôï÷`«Ôå&ÛÄ` Œlqgtæéäôr"^3€Öˆ±k+1X»Iàï=½ã'!¿ûIà‰$ò‰G�Ð×Ò�úõÞ8Ì�פ¾çû�ßò �þ*Ñ¿õ¦ï‚›8ò}ke&‹Ã Ú¿á“p&×q�Þr52)rÓ»ßå&ïšÙø�³JÝrfÉYgA÷\«ÙÁïVχl$2¢ÐÑ1” P¼"T­w”(* jš ¡jÀü ØÇšà 8„\e‚Èã{QÂþlÙ®(ƒCÞäwBg™¬9‡´�Í7úÌWðEõÜÞxv+㇠݃ÑÊ@œŽÉ ßÒZ.K [<,ÐÄ2%u ØJ3¬F‰¥Õ@W÷*,b™‘’þÆq ð — -£BÔl˜#Oåã$áÌ‹{Í·ÑÊb„²Ò@©ÐªÏ¶ÎíBïøqÈïÅ^õ6KŸH$‘OœëøNànøü ðKG=ïë–O½&rݬÌ^[‡îßÄ�–íkŸq/7ÞtÏÍWcfîžã�ëþˆjvÿï ÷žiøâ…ÛXý÷s¨¾vŽö÷ì4,œ¯4÷[w‰š³ N¶Þ•ÐáC@z(j%P­/`¤^xP7‚¶Î¯$%‚ЉªÊjè±à•ñyåi±ß9ç­´)Ýtæ¾¼'pO ¦­† ÕR$4!LkŽ‘@_ƒ­£Æ*%X©»½è÷kS=Ÿ2õ XÅ–õ ¦ö |%ë,õk*‚búý8�šIªí�€Ã™5|¤e AuCào{=Ø%ìUo…m½4ì‰$ò‰S[Øuø÷)À_ã›ðæu‹þÁ¾©rílݳf¶¾ïZ€Ù›(שè-ço.T^S¿÷¬ìçéÌÝø;|úš«o Þú3Ê%×ïZszÇ9�7Na&v³x÷Y ¦Î7qêLCÜ4Û©gal2”\ÀI]¨Q+ªé Í�V?kUpÐ>mï!8$äbˆ@•s ìξ /{#Ý-+Bw)a×J·ÒÆ®µ©Êe»Zô‡",(¶¿®Ùj±J› ÖBÈ !”Jˆ`#ßhIÚ`Mý~Mc(Ë`‰Òwõµ‡¥�¨mK4ÀØ�~õgÀ˜§ýjøD"‰|âÔg]à¯n&6 ÿû€×ý‡¼‚JhmU‹R‡ðq­¨²¾m0‹ ²¾q`¹zùXç}(×™¥ºîÉTÌþX÷Zf÷ÁµÿvÓÇÄœsÎ9äÌ_~•ò�Õ~³ÉâùÛs¹¢ûÎ l=W©ÎŠZœ¥22ƒ6·uãuœA¬­g‰‚xêÒ€2Ü(QúuŠé‰Ñ‚'fƒmøj›è¸”ö ¯ø¾RÚúm,˜ÁÚ¼P¬Â½˜ïÚ‚B·®âׯâ7jɱ—¿ÉÕßòà°¦Duœ -TÖ²Å]øÃÿf䱇ÒÐO$’È'NKþ[�÷»6 ÿ�Ÿ Ž{¨ï¬ hö'‡•H% |™E™E¸¶îŠ2T,�+†‹ƒg€^[¯žòO×Â5Ìê�\Âu×/¹™}÷9z-oÜxæ¼ó849É­{òÕEÂk?4˜�5èÛÆ›ïOž»ÿ˜í”w\LÕ<Ãê¶=ªæÂ(aÂ8*£`ó:²”C Ä~$¶*Qñ: |¨·üëêA˜1°ÛÑæ„$Q&ˆ˜ zQŸ „!ÌÃÊ¢à"+ °²„éô‘µøôë½ÐUl 6JêâA èr„²ªƒéG;ÜsXЀZT•¬�ÜF÷¶×ÖgáIoG.:X¿Aµ)h0–>Ü‘è'´ÞïH©‰‰DùÄÉ-ìëbþ­À_gl²àÿøÑ¡À?¤Ö¥›ƒþ†×ïó>³u‰=fY÷èË1>âákáè¯ ß˜­ßãÂ}Ÿ;;4{q¹Ë´¹gøÀß~cUá¢7Žqwš¸eŠpå™hç|mô÷PlÙÙûXÍsm¿Ó 2ÓmdU5Ö5D©÷þ‡©‚b,ª(¡îø3 2*ÈV…s1Ó¢šƒž©RWH¬ ¡£ôÛæ„Á"!®ÆÐ�Ǭ®b÷•pW‰í¦2757Vì°™M GMOBÈTè"ý-ôn~¾¨:Õï¸÷¸{ëæ‚M2&¥È†â]• ç‹Zâ[£R÷ØÔº6kn\(ˆõ{ÔŸf•D"‰|â¤C�'-øÍÿ�ÀíÓkÙ#ªWÓãñô¸”ý<�[oÝŽ¹ô×ÌjÆû®òƒðNǧCÕ†ØÜ9M•m'LÌdLm7±±=â¶)Ù¨ T.2PA$ÒŠ~‰èp}b‚( €(Š‚Æ¦bšŠÝŽŒâP1BDEûQ¢+%>iMÑŽTn)Ìõæ#�5dá~n0 �;ã èW዆µ'Èí^Ö^eb£G¯üoŒ<~¾aðÞ·Õ»®ãbFC*\]X°5´ì«¶©à`”ÊëúLâ3#õÁjú9%Iä'Þzß<?¸a“À|x1u¹¸£MëSÿ]ªë1Qnœ%Þp r5³:2Ž)»¢wû ¦»HßÞ €uR­»Ï].˜©üŽª=S–­; Û «ÛP™t—h¶Å0b"ÎD¬Ö S»ýE‰B J Q´©CdFMÙ„^d†èÎAœttZ‘íÖÅoQ¥Š±«É­íoå=q�=n?ß=íÿžþãFÝ‘‰Àòšg%À½ …úÆ7�ÐoÔùýU6ìØ( 9²^í)(*u>ÃSÕ3I…n¸û‰ÄÉ2Ñ'Ò¹¿€Ú%î&áÿ8pÕPàOOˬΨ­z=œ€Š8ÇU!ð›Í&×Wýé×XïÑp8GÞKÀYÄ60XÈsÌÊÆ¿ÂL†™Defl>ŸÆ·[FwZò™HsJ¡‡a *¢Ã4?ÃÆ‚ €ÆºL€(V�€!ôVå©”›ø»—˰T(:ôØ^¤uk!£ ÆûýÐ=~!Z�ݾˆì T-ð`Õá Dõ­{˯ÿö L}N­�˜ÎÙÏŒ2~½¨AE1Úû�¨/ýÝì§b:XÉ’OœB?ETwÎ&1ÿ põ& þ4Ôwİ®^ÃÀÿ¡Ò« 5D�ŠÆÈ²! Ö!Á1lå¨EßÖÂß#@ ¡ÑÀX::ê¹³$pÈáæq Ð@±x‹ñƒmZtÛ~ûvØ=…ŸÜ†êneÛô¶ aÌ(š *¹HT &€fíé�rKw¿>wl g€¶‰hÝQPTG¡{Á] ´‰ˆ j£„,7žÔ6tö)å\ ò9È1£+ÐZÂt úƒ€_RïÛz›D"‰|â¤öu1Ÿþ’ÚU¿Î§©]ô‡NgoÏ08p#`¯6êe´§ä‰%Úï7#¶ë*w°aÅCy~߸ÁÀ­¨€mq`¬ Òè`0æÁ5´®’Ó„»Â×Z ù8¶³ÒôÌ<ãì–¡¹u�»#ƒñmžÉ­¥TÛ‘î6 _o˜«ÆÂwŒyEƒé ±Tœ1ÄõÏ*@Du©BGà B¦ª£Qò3 «‹ •)'£ÁW°\*¡£4ïQÙ±ˆ¹`Ó½ )VP»ˆôWŸoÓj+ÍmŸk½0<>Ͷl´¶Z³õ®¶ÙÆ4U%kKÝM° >Þg„­]‹7Jß(}[g8.8èÛa“"ÓƒQ|®¨;V¹~Y¡‰DùÄI%ð›-øOÝôø�À�7-R›3f‡ò¼îîìë†ÀyÀÜö�Çà ÷9ÆBO�õªP—ïc°‚¯#è¿ZU|µ ,ÐÚõµ‘AƼÏ(›¯ž`í‰?[vðnûŸ|´úëøÝø5.ŠøÉ „j§!Ì(ýi�Q%7‘F}êÅÕßUD †Ÿ§®x ÿw{w×YÞqüûܹ3ÒØ–å%¶#ï[X–@rBC�8…á„R 8ì[¡å`N)K�|Õ…½@)Í) -k7 Ú҆О¶ÄšH IˆKBh¯’-k±f»÷>ýã½’ÆŽ‰�ôûœ£ck4’Çwfô{×çÅK`Ý/†lM8yhšÙdC¥á,¬cÏšˆÆº�VÆ&ŽBã`“æ±<Êî$>^Þ0Q¦2š2Ò„¥�sRšƒ(РJÒդĴ(Ö0Fš6ò•w/£EL�¦×âÊX˜âǨŒŽ±hhb¬òÃ&�ƒiäÔUât%U*ÑÑj­5)V÷3Fº´�ÅYX@˜.ð¸ÖíÕZN�:-ROªq”Rò°hPD!/܃?=àŸÛöµ#À‹€›u©:W×DÃ}•¬Öx¾G<Ñò®äâ±l_ ³Ó"3õEΞ1ß{¹M\õŒ¯?agô¸‹ ·—èûï&½lÀsÇÌùBní£<¾„ÖÖ¾ˆÆæR^_g¬Ü’³x]N¶²n'ëò;Ç’Ì�a}îŽõ*:dX˜úߺÜ+(Ýùaâ;“Ô÷’÷_B¾š„;’|Ðÿ¦L\s=7í%zärº÷�иdMØa°s©—o]ãå«imØ@6¶…¼´¦äÕuK¶@k9DåðϵÂN/…—£™á%#·X¼í5êT Ô¥>·²A™œ�"b„–N×…¼tfÂ1±W´<„ÕóÏ-…{Ç{&yþLËKï©'ïý"–8nY(b;Ö"²îÊa£á˜ÙÔföö2çž.Eœr�âõ É@ñ×âÏ .˜Zߘ¾ß00D‹!ZÜØþ2ܶ%VÞ·ç³×Þº6n°µÂòu©¯ÚÔ,u­'ÏVCÜ­ÕF´È©¿²¢éGj¹au»"‡›<õÀÌÜ£-ÇO,‡ásîÈ|ä½9Ù*7âq'= Í£à?…èÑØ1Ê£C”ú“û(Œ6±›�¨Q_AX¥ßtÒ*°Zu(·Ú.×I'n„i�x�MýÊM�⨃驂zjá,‡4.îWTŒ3#-ù©Ó ªE y º€Ï—µÝv‚0ÿ=õÞç„_žCÄ'ŸŸ?ÿKIâî“1X&¬DŸ•íPß—ÐJ’ר¶�ܱbwþÝ áa¿d ¿¤?¡oÏù•2C]u6.;îã›Ý®uz6AºÞH78=ËÜ—­�úRˆC9`²ð²vk"�1O +ø Ç ‹"÷h1f½àç„ïëròe”Ësh5a"u–u.=@ÍŽU†íHFëPÎØá˜êH“Ÿ QÝW§\†ÚB‡1UÊœmµHs�iyM+ã@‹1šSáÞ"sÜ3¼€:Ãy‹:)£îÑk“›9ThHòÒ.ú�—¶Ý6 ¼ Ø;C�_:Ï/#2Ÿài\>°gà•Ìfs Î Gzñ0·ýáÂ(ÙžäIh¡ÔvÃèæØ?v%~IBF’„S ¯ÙÜÅ�ÿ¸�Úš^&.: ÿñVËJ›"V­…|cî¾�–AÚ µngátÙà°EhÃû“E €“™EUèÆh>¾/Ó0Âý­äMÏDç4¬öÈ‘ñá”ÑC”šGÓ2GÓJã0'kÇ)-MËÍÚpu8%†´áÔ£Pö8ž~††ãÃFš;)5Ë«iOÔ"ò´šqqôrw9ü9žåZ0( ùù§=°KÀ»�·2=/x¡„m'd€Ü÷sýK„Ã>ü9W“»yQœ¯CÚn~� í G fÛÛ^ÇŽyÞïæÛÎÇ|‰cž�M°›:û"ávƒkßçDÞNù±ÝDëÖ]¼²§‹VO™µkÇËÍÍd#+É­7j�2²н,·îή$ë‡á[8±swm‡ïö÷ãÛ¶aûV`®¥ôì'ï,3xéò*?Yƒ¯]]cÉ#ß c}îÇ6G”W9==NWëŠñ,5¢däádÁX}zàÂJ†GàÖµ.8±<�J¡t9,S­EØp4vÂ?––I½û<ò y6Œ¥û‰ÇF°Z‹òí-–ÜD~²òÜ!6,'÷ÈÛÞåz¿+ä¥Ãíþ„©îï)>ïœßýr/¼ø6ðN¦—Y‡€´ûHÑÙØBµSÞôç6ù =¥0Ó«×Nû/Ú}ý—/›±æ°ÃÔ&�Ó¥py.¯Á]IB”�À¶[ŒË-¿õ£½Ë¨]¹ŽŒ54—ôÅ>±%Ê|m‹õ[ÍÓµ-1ÊE­ÀÔñ<Œ˜­›’‡ÇÅÚóâÈÁÇzÁz!ß@ž‚§Õâ©oæQVi@Ïõ͇Êc¿q¬ÉàbÁ-oyÄÉP€SÈ+ä¥Ã{ô¿|„é“=òÐÁáKEïï:¦ §/C8RV:Ãã g | x#0¡Kò0H qO``'ìÛwA}äbï�ï âûöáÛnÁ6¿“®+ÿ�4yÿ ¸íªsÈÆÎ¦Ñ·.bÁf¼¹ÖX´1÷FÔûÜ*%l�áÝE#' Aîétð‡} š˜çî唫FºÀ?»A¾Ïš�—‰è ‹”‡9…¼B^: ÐO£¾¾-à­hæ'„ùÚóŠÞýÇ�Ý„Â8"L ~ë>þ�™:„íÓ3ý}¶w;ÕzàU„]o",¢”‡ƒ'¡(_^çîýØÀ ÎØžX8ÒϬ~>ø®dÓ(pƒí¯ÞCiãvbî„M ãª�Ž?}D÷ˆ÷¬…[ÖCkcä«VF?×éêËXz–­Å+U< #Ì-¶° uŸšÂ(fç<2,-¶R¦N‚y☙Vì)ä¥~Íœ¸/.|²ß"l�û`qß› ´v?žD8^öõ÷òšX^Œ,"\³ØTüܻۚ–Îçl�cYñw…Ï™ ø7 ²·ãº$÷;pjÕßÔM;§9À®ðåÈH’©7¬›ÓŸX¾w;Íd“{ø1oM�:ŒîYÁÿìÝKž�Ànbz¾ÑíG«U·/§Õ\Gãäê8_¹5&ßå•õNsV-›G”ðFÚuàmžvï÷jëºðЬíá‡Z‚z"çG�P:÷¹3BQ›¿&½¡ç½ø¬­—½ø+`1°ø3àogèy?øt1ðß„©ÊÁÒMØgÿNà•„íM)nÿTÑ�ø—yrý ø$a:äøüwV¶Aþx0ro£%aN>l¡+¦çí�lñ…�ato Ê-¢“Ç+ùE¯kø-˜éüÎù©÷à)#k¡D°‡ÃxÌBú‡¯÷÷ÙeÅ<Ÿ\Wˆ_ÞOÜv¶´Š­8J¾w/ù®[°ÉõûÎÅà–ÄGíÝÉ;’˜ÁÞž.¢E�®-Ê�ñ-ÆÝ}Ím'?º;Ijû.ÃÇwíØA^ Û+äòÒÏÛS€¯½êÉ€ÿa|s†ûÿ:aOõwŠŽÇd�pAqŸ&aa×W��ë�\D(‹û¨¢ð²¢gÿö"ìÖ¦ÞÜÊü®(B~U1úrðÚ¢�uß¡£�Ÿ] �°-Ðïë9;=lOÿž¶ÆD 0|z$ÚŸËâ¾¥ðˌ̧w'(Øç) ×wêïxrÑË^ÒÖ“øð.˜ª!Þðp!áPš³€­À€¾¢ƒ±ŠP$çààË„¡÷‹àpa(%a_£øÚÃú·ë©yÐ~¼øº$�Ø¿ïÆÔL¡{ú÷´Ÿ-0S°Ïpßt¦Ÿ¯€ŸŸ"]‚ŽôDàŸ€m¡eÄ)3/‚ûUà鄹ݛŠÞ~Oúü)¡PNJXµÝ*¾÷ Å÷î-îs øyƒ„Ãm^SŒ(üÓÓòà|“°ØN/" ùyâ±m?æ_'ÌÍ�3s±›ÍÀÛ€¿þ“0ÇÞWH³è½ÿðî¹r}qû÷ óõ}„ù/O/n»FO̓bYÑ3BÉÚ;gxNEDòs4à¯"Ì�Oú&a~ýÞŽsàÑ„a÷Ï=õÛ€?Î',Èkw„p:ÝäÏû"°š°Po aŠà’âk×C„UßGôô<`K‹|^4ÀîÒ%‘Bsò�ð_Ö´Ýv5áÙ î»’ÕUE¯;këýÿ[Ñ«o�vß» ‹É&÷Ó^GXh·+¾¿T|mIòÿІê¬€/ ÞüðÁúÁZ]+¢�—Ù˫گ֞ð/&Ì©ó36çÔ’¶“Z÷Òó?½ôg“éÕúV|ýÑ„p¾GîWÀÿ⺀—ïÇ×ÖL*Àow¯F•©"¢�é\í!^n/‚þ¤.�ˆÌ6®¹ÿ=yç ¼ˆP~xX—EDò"s§'? ìÕå‘ÙLÃõ"sœ¶Ð‰(äEDDD!/"�DËýEò"""¢�…¼ˆˆˆ(äEDDD!/""" yÑ>y…¼ˆˆˆ(äE¤“hŸ¼ˆB^DDDò"""¢�…¼ˆˆˆ(äEä~Ð:…¼ˆˆˆ(äE¤“h �ˆB^Dæ( ׋(äED=yQÈ‹ˆzò"¢�õäED!/""" y¹4\/¢�…¼ˆtÍÉ‹(äEDDD!/""" yQȋș¡Õõ" yQÈ‹H'Ñêz…¼ˆˆˆ(äE¤“hN^D!/"s”†ëEò"¢ž¼ˆ(äED=yQÈ‹ˆˆˆB^DΠ׋(äEDDD!/"�Dsò" yQÈ‹ˆˆˆB^DDDò"rfhu½ˆB^DDDò"ÒI´º^D!/""" yé$š“Qȋȥáz…¼ˆ¨'/" yQO^Dò"¢ž¼ˆ(äEDDD!/"÷ƒ†ëEò"""¢�…¼ˆˆˆ(äEDDD!/"÷ƒ¶Ð‰(äEDDD!/"�D[èDò"""¢�…¼ˆˆˆ(äEDDD!/""" yÑ>y…¼ˆÌQÚB'¢�…¼ˆˆˆ(äEäaa÷ú‰ˆ(äEdNsWô‹Ì±.�È꽫ìèŸlÉûtg>ojžˆzò"Ò¡Ioî?éh1ñ§ÿ)" yéÌ^ý¶–“ºãî9îTÜ”ó" yéd;žA+ÅÈ3pƒV ò©q|™ ~™[Ü1Ãù±�S¹¹ëö§p?Þ¹;^ÅÍýÔë†in^DD¤ãÿjbßM)IŠ‘»0k/"""s@±oª›¯�™s½zÜ…¼È|já‹Èöé7¼æâEæÃ™ó)2Þ Ÿª7…½ˆˆˆˆHÇú‹¡ô[©pIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/Imagej_icon.png0000644000175000017500000613202014757047403023167 0ustar00paynopayno‰PNG  IHDR²§Ó0 pHYs  šœA™iTXtXML:com.adobe.xmp Adobe Photoshop CC (Macintosh) 2011-10-14T10:58:26-04:00 2015-08-25T09:34:41-05:00 2015-08-25T09:34:41-05:00 image/png xmp.iid:a6d7fb4d-2b7d-4581-9c4c-1900c6c0a5e1 xmp.did:01801174072068118F62A1B29312462A xmp.did:01801174072068118F62A1B29312462A created xmp.iid:01801174072068118F62A1B29312462A 2011-10-14T10:58:26-04:00 Adobe Photoshop CS5 Macintosh saved xmp.iid:02801174072068118F62A1B29312462A 2011-10-14T11:06:40-04:00 Adobe Photoshop CS5 Macintosh / saved xmp.iid:485da348-9989-4f98-bb73-f848dff38bc9 2015-08-25T09:34:41-05:00 Adobe Photoshop CC (Macintosh) / converted from application/vnd.adobe.photoshop to image/png derived converted from application/vnd.adobe.photoshop to image/png saved xmp.iid:a6d7fb4d-2b7d-4581-9c4c-1900c6c0a5e1 2015-08-25T09:34:41-05:00 Adobe Photoshop CC (Macintosh) / xmp.iid:485da348-9989-4f98-bb73-f848dff38bc9 xmp.did:01801174072068118F62A1B29312462A xmp.did:01801174072068118F62A1B29312462A 3 xmp.did:0180117407206811871FA91756CF7EB0 1 720000/10000 720000/10000 2 65535 2048 2048 _–ו cHRMz%€ƒùÿ€éu0ê`:˜o’_ÅFqñIDATxÚìý{¬u[šßõýžg®½ß÷œîºœªîꪮîê[¹»új·«c0bcìØ\:‰ @‘„(2�¹H‰¢È ('$ #…�…@…€“(2!�/m7î‹í¾”»ÜÕ]U]—sÞËÞkŽ'Ì1çsÌ1æZû=§Îûîý~?Ö®µÖ\sŽ9昫_�éçϰˆ¸ßœ!àþ#€€xHà €€xHà €€xHà €€xHà €€xHà80ÀûçÉŸüm/éÌ–_L«<`·ü�ç]L&ËûÍûÚéÏL÷ÿèJ××Wúð‡> oý–oÕ·~ì[õ‘·>¢G�ßÐ1�zçíwôõ¯}MOž<Ñxs«Á]�?Öã7®u¸ºRJ¡§Ïžé7¿ú}éK_Ò×ß~[o~Ó›ú¾ïý>ýà~FýèGôüÙSýʯ|Nå/ÿýƯÿ†Æ1é[>ú-ú®ïún}ücSXÒ—¿ü›öë_üuûú×¾fÏž=—${üè‘>øÁé­¿¥ozóM™¹¾þäm}ñË_Ôo|ñKzûí·Mæúð[oéû¾û»õ£?ôCñC?ð=zt­ÿø§~Jÿ×ûOèOÿ¹ŸÖó›}âã×�ýè�èGä‡õ©ïø¤s}á×~M?÷ó?¯Ÿù¹ŸÕ/}îsúúÛïÄõõ#}â×g¾ÿ·è¾ÿ·è“Ÿøv)�úü¯~^?÷ ?¯_üÅ_Öo~åk’¹Þzë-}×w}—¾÷{¿Gßþ‰OèÑõ•¾ôå/éñ/ëgþâª_ü¥_ÑÓ§Oõá}H¿åÓŸÖgüÇõ[ôGõñoû6½ýö;ú¹Ÿû9ýÙŸþóúù¿ô—ô•¯~UÃpÐG?òûîO}§>ýéïÓ§¾ã;ôø�7ô…_û5ýô_ø ú™ÿô/êK_þ’®½¡ïúîïÒg>óúÎïø{ãÑ#}ý+_Ñ/ÿÒ/Ç/þò/ëK_þ²lô‘�|DßþÉOê;>ùízëÖ$=ú4~ó«_Õ¯}á úk_øu}ýë_�7ÞxCŸúÎïŒOÏ÷è£y+ÞyúTŸÿüçõ+õWô¹_ýkúúÛoë­X?òÃ?¬ïù®ïÒáêJOÞy¢·ßy[ÏŸ=Óx{«!7›~vº½=ê�gOõΓ'ºII×××zãÍÇzã�7t¥ãQOž<Ñ;o¿­çÏžkGý³ÿð•!iT(¤HËg)IŠé5å÷‘¦Ï!IIå>Zï£Èmź­ÜßX¾×éû4Žâøù³ôæïú³ü#¾¡H^[V½NáÿK޲ù]Þ=cTJIc5Ž£ÒqÔ˜’ÜLR’ÉäîòÁô(]éÑ£Gº¾~¤G�nt}x¤«Ã•\®HR:†Ò˜”Ƥ1¿FÊAU—Lfæffæa²�Öçû´ú¬êûæûØÙ§#:û¤îüSÞ7$¯{šÈ�f3™ r³ÐMJãQãqÔíñ¨ÛqTÇà–ÜüJ榸ÖüüH77·:®ä–ƒÏÇ£noot{s«ãíqJ$ˆ¤¤¤9”œù¦)ðï‘ÂS �”,ÆdJaSÔ{)}°ê·L9 ?êæö(3�Û1M±]“ÜLƒ»] ƒ¾÷;ßxô�߸>Ø7ý–O}äÑßðŸ}4û›R\__]}óp8 �=þàa¸r?\}ÐÍ\r¥¿îŠøJI&ׇmNGp— ƒ]åJ Ÿ¾Óïx;R(E’•’žùpxæƒ'³ákÃ`Ç·ÞùþOëÍïû½?ñäéÓgO¿ø¥/½ýåßüÚ;ï¼ýäéŸþsù37ŸÆÚÆ1i<í˜("Bë+=~ãM}Ó›oèöÙ³) ãѵ®®¯”¦¬‰HãQ·77q{s’âææ&no�1§€ü_¦Ä‡rNÀ¼¯þ<ÿM¦}¦à’é‚OqJÂp·é˜k0×Á�)é`®AÓ_ØzvýIZoïæ£<.µÚ9§w~€—‡àua­à¿uÞ—ŸOåÿ§à»Ëm�ù0Í’·ÓŒõi6ý˜gïç×!d¦ãÜ5\IÒõÕ•®W: W: ¹Šo�:Þu¼¹Õñ8ê8ŽS,9�º"wÉlšá)Å�Rò1…GÈbš@nÓÌrI!}×'¿ùú·ýÀ'>ú‰oûæ�½õ�7?öÆ›o|ËãGï|ÌáÃæö¡ßÿ;Žú}?ñ·|Hö{>h6|ȇáCf×Ô0\O­™×’Mã —,/‘`ƒ$Ÿú•;éV,ŸPÔ#Ð2ãß–ã‡asŸ:«!§é½’ éðXo¼q-éƒúŽO~Ër§þö?ô7I¡¯'¥'‘ÒW?ûÛ>þÕ?ô~ì«ãñækÇñö«)¥¯zè+6 _†Ã—úò;ßþ-_úÐŽ_úåÏ}ÕŽãQf¦”RŒ··q“nonÓíñVÇ©@D¬êÞçòúÓý¿½=êx{”BSâÇ\ ßÀ9Q åª &Ɇ\ æŸéüŸª# :ø Á\–“Ü|©¤0ià3üW:³þ—}bý¾{õ¿ Àû�àµw·ª¶ÌþŸÿ|ùnžÙSM€Ü¸Más“™›Ü:dKðÿ0h˜Ö Ðxãöæ¨ÛçÏ5•Ú?*�cä`x‘�& Ïå¿ÿìcŸøÖGßõÆ£«ïxã�ëOWß1\?aæ7½ñQ·O}«¤·¦éý>= ™Kô^¼i�“|ÖKÂÃÄ‹×%RýÂcèºk2Fï¾ëÒ+> éæú6%Óá0èp¸Ö£8LûÌi“¡G�úÈ�~\ŸýÑ¿ã6"¾|o¿¿qü‚’þZ }áxÿÚíÍíç¿ðůÿêÿîßø�_K‘N×>'~h Þ§1cØì—YÈr}KyÖŒaÓIiZ"|ŽÏ+…I2÷py\ºò!à+t´�åD€u@5›ÿÜŒü%žÿ� Ðü/ Àƒ× &{g—%ðÝR»ûTÆÞ§ý6L3¶Ë˜g^³Ýb0Ó “ÏïÍlp÷pss î6rÓxÔñöV7.ÝÜÜÆøüFã8FJÃoÿ ýWþð¾óÍ7¾üi¾òý’ŸÌ¿Wzü=²O~�doÈ�÷i ð÷ª,›“æöyÉ€í $—|þr~-g÷$?ä÷W§ã,O럹_N™òyWð§™òsŸb<}—r�?æí·Û㓤8Neñ#IqÌæ÷×9à=H>Lû˜ç{–®Ì†o;(¾M‡ë›óy¯%½azëCÔý'~÷³Pú«)ŽŸó”>—"~YÒ_–¾ö—\é/ýó¿¿ ‹‹�S„Åc²1…ÝŽSðÿ8&E•Ìä1„›Bò°aH‡ñ*Ü,ÃU\_âj¸Òà®’†ü›“û´¬@Ì+hz]~ƒuþÝ”ë�ÍqÑ<K€—�àµb�ש¨}ÿ‚ç™òîÓ«tš¯<‘Þ]îƒdÉw7Ï¥Â\ —ÂBaI²0Y(4ŽIo½ù›W¿õ{¿ø}o\Ý|æð;Ó¸ô3îßòsû^—_·û×Xº`©J0ìs ¿(Ñ/ R:È'Ø Ù ó!ï?ïcy&ÿ�gò—íÁpI¾”O¨—P$>ü�–˜‚öu0zžÙй:AÕ–s¦bÿ\æI>¨ƒÛsÂA’lJ8µWì›’·ŠãXô1)b^F`ÌÇÕ3ðõ¦¤Ìèzx¤GþXüÀc}æƒ×OÆßH¡_=Žú‹ÏŸ§?ó…/Ýü'îW>þK¿ôåï|æ’ÉÌ|Fsw7K‡Ã`> æ—ÉBr…Ÿ†úôG¿ ?ó4Ùð«1êgÇñøg#énÓág~é+ÿ‹ú¯ýîçæfÒ¨Q)%óÿ›/¸Ýç‹–híEBƹ¶ÎÝs€÷ Àkíª¤$¥4­ó>†¥4ZJai•"ÂÌâ¿ø;åñÇ?üä¯lüÛ7¿GJ?¬Ðc¥$§Yï)åuì-—Ïw—ì�ƒü¹D¿—AykôyÚîe¢ÂR¾N\(�wm—ð�‹ö"‰Â´JØô©=“úªœyÞ ºWkÚ+:Ûr�:r;s…€òûU@ý�Š™ï­Ùð­d…¹Š@ë:{:û”Iãñ ×ñÓ’>=xüa¹ôHGýÈÇ~iü‘�ýË?Ÿd.bøÿ=;^ý'ê—¾û§ÿäÏ~üf”""BŠ1Îô‹ó…¶÷A;Û^Áðò�ž¿öêRZ‰ùøeyùb»·’.±.ÊöG9Ã쫘á_·Ùª& Õ±iÒǹïõšöe°|oöû»­öºí’~Ð?(ÿKßt=êoù-?ûô?ûéŸýÿ<¿þÝ/|ýÑ¿%}æ§÷¯Qïò:¢±%vÚ&ø^.€×†u^Ë wkÿµ9`™¦o1üÁø÷~ø‘¾ôoè˜,– ¯M%ú‹¶r �ÚeöCŠ¢o–ÛPžÕß�Í_÷¹u�>ó—ælg_i�(Кjk%0Lï“Rží?/kÒÙ r“ø;eê÷Ž-«ä ÛÀõiV|ÔÕš7¾>îÌþ§Ì»üÙZy{ß¿÷Íëãïýž�ÿèø•ÿä?’ô¯HúßúìiLÕø¼³äAk¼Ë먋<ô à}å ð:°÷¨™2i@nn.Ùð­o|ñ¯”¬½¯]Ø¿ _‚Ìë ½©(ïoçø½d�b¶¿ÍÛ¼êƒuÆÍ/|¬*KöŸ“�ôjÙ€MYÿ^y~©Ÿ,P, FB7H×íï»ß)é-é/§¯ýô¬úÖYª Z×ÿUxÙH:;7»ß:ß•ñ"�n&™™Ìlp÷¿ýGêÓŸ}ßéøh·i­ö×ûØj¶oߢ^ô󢄀r›I;3ÿ­øÞM^' ”×]Òwg¿Gþ߀^fûG±G±$@*×±¯æmeÛ½2þ�j›ë8Íô�—Yâ¾7ó~í’þ�ó3ÿ«ëLÚŽÙÙ%ÎTÀËCðÚ²wuä”àúŽ}éŸjGf­xꨃåe©ÿ^‚Â^ð~nØäerÁ\! Y `Ùa½Í¤Màµ4�7ªøƱXN½Yç½@}Ü_fó§mÛ{Uæý[³ã ¯L€Uõ‚Þ�Ò²ÙLjó]~Ï‚öÿÀËEð`ÙÝžÌúÇT{óAæ.w—Çóßy·d‚:˜nUŸÊmu‰þF6• ¼ª"P^x§¢€7úè½%ö´Jù«Ú–_£´§"þ¾Wò¿øœŠÀxHiuœ´?¾7{½·Ä@ì¬wÿ~8\�ø�¸ýÊ·ô¯·¼Æ;_t4.èÀû€àµÐ)�oSáýí¾ý@÷4ó_r÷øÛëÏ~«Òí›Ë—Ñ?·­fû[#áÀÔ¬`g®aõhSÍôŸg÷»�òvª Xwy‚ÕTcØX DR:•îo-° ò—÷:€ß*Ií}’:eó«ýò¬úèV ¨?žÙç¥ Éÿ“.ÝßÝýeÒN_^€ϾMZ˜¤ïù–ßüÃÓ†¸Ãy;%ÿ» *¾k-Ðzím+gû7Jù›u“üÂGª^D¸*ῼ­ƒïsIU%ù;ÁþͶ⻈%ù öfþGo逖ª¬þ«÷Kÿ/Kz«¹Ä�ZÉ—^wg^1$™u‚íýŠW[Þ˶"¤ˆ8øø#ëã£Úw™vöœ¶™íoÅù;/úäõ~—&Ì/õ÷®mõ�b7ùªÒ@5ë?ª@ün�¼U¦?V1'„r ¿^ <¦•`P´јÅß üo¯#îW©ûÇRü=Û±n\{jÜ“è%\¨ÝƦ ÀËEðZº Ô}ï¸XÜqðñ­?¯mËéK�JÕû|œ/IsRÀ^B@ùäE ßç÷÷ð‘©.Ñ 0/ÁõTîW“ªÍéôÚ�ÍÞ bçý[•RçøûО~ë& c7ãE«ôî3ÀËCð ÙÝžÌ.osšý¯ˆP’ÞhŸ×ŠóÕAùê½×Ç×eúëÒÿsÃUu‚U³ç– ¨gþW}ðzù�ò8ïŒs£”ÿ*�vÆ6‡—³ú;³ùçD‚Ðò9u«tfúïj$¤K�}é�¸?²îg½ä‹‰n‚À«ƒàÁ³ögkígýý³ˆPÊ ’}õ’s[=Û߬sn©œß+ëïÕþùÕêGŸNeŸ{¸·\B� П* œZ�âT¢ëD�y[yLk6=S?¿OÚ.EÐÜ¿¬@P&)ì•¿¿?õƒ$}Ë�K÷7÷oTè ‰àÕ@ð õJéÏ[ì]µÉ?wþ¼ôÇZ³õíÂÙüÒn�[Ñ\ÙŽ«]úÿÕV ëÀ}Z>ç×hÍÂo•ÝW»LÿÙD€²�S…€èí»©8лÉÕ>ïYÉü÷ú§~�Ü¥¤GÕÖsÙu/»u’ Ò$ÕÙÙêg¾³ªÄþ²Ùä2Éž�×jÓ†5‚ø»ç¬+¬ù6·áÖIè½Öï­ˆïw¾o^‡çÿ­«�Sq—Yó9±ݖƒÒ1'„r�z9é¢Ês2@´ö�Ftæ:^Ýà¶ ×sÿ~sÛßX'B¤ÆuEgÖÿ¥ãþÀËGðÚÚ›¥ßIÈOán2³ÿןÿÞ_îÑ_V u¾:© (¿ß ðïÍ–²ýí`~ã\«m^%K ˜U�Ió2{Ë"ìƒû‰Kùý¤Î¾K)€bsÒ:Y@ºlÉ€s e¿O3ýã>-àoÌ}ý¹Õ=Øëz\ð¸H;ó_ÿ­™þwhӦཙÙ_ù�o¹Möè Í}ç ý™eú}o•þŸ6y™H0W�í,àÚVðýÇ¥ºšA+9@Ò:X|šÉ?}UÎ>?=¤)v!%™F™ÿÄ/ü½ÿ¾ùÏLûÁw;w^›‚ü›ÙþžV]—KçzûxõÝœ `�ñ;%øæ¸YlËîïƒ#ÿoÈ?½�rI€”+,ËÔÁþ3K,/­Ùï; —Ux%~ë.»ú€$}NŠiuš×®â>Ý5 âŒx­‘<(væ¿ü[�îKÚ<í—RRJ)RD ¥£¤[s;þÔ~ïï—?þ’$ihóËÄ;së\׬÷%¹ ¿zë\Õr§µòWUàßÊÊÞ8¿ŸçE#ÀŸÁæe¶yÜüZMU�X'¬Ø­`}™$Ue�úü� ù}øÅ>4ß�ÿ®¤gͱx3ô£{îçx€‡�àÁ² 7×ó½ãM¡1Fh”tt³ão<ùžgŸò}³ìúùéðì·2Ø^”ä¯ÏµÌî÷3ý*+äýWUÊGžVRA'Á[m_ìŸ%mÏéô]Ô�ãTì§m­rþóçë�«ãê>õ* ¨êc/°E³¯` Û®dבÿIÿ‡»ÏÜ�ÆçÆ8Å]ÚxyH¤V°ÛŠ-öÂ-§Š)"ÂGI£¦0qú�~ùw}þמ|òï� I’ÌŠ@º¹äƒdÃ:Ð^>ž˜Kv5í³ï£èÿ¼�KÔœéo6}çƒäÓ¾¶<úm¹I:È,÷IC±OTýªÎe�¥’|Š—'�ú½YúEU�0�ÿi½¿ùš‡ò.ÃR²S?ͧë–Mû¤¤%ŠÓõÄ|_VO„©èŸCP^kðžÛ±�D‰Kö9û[ÞgW‘Ó÷IÃõ¯Iú¯¶zË\¸�Î1©{ÿ쀗îÀ¯;ëoo•êO‘ƒÊ«YçÓ¼t³øáwü¹ÿü�ßþ�ßzóÙÿp H›Ìš‚òsÐ{(bÊ–ƒÜ�¤áÑ4«[.E\‡$;HÃAòÇÓ«r�_ÊmÙ´�ÉÓ£ÎòyÐimû£ÖÜœL£d!�c>ß ƒ¤kIW’�ZöÉ$¿-Dëå 4]gŠœ¨p�4JƒOAå²!'¤QÒítþñ(Å�dÇiÿEä±¥ô\J·Òø|:&F¹¥éú#Mý‹£4Þ*é™ìx+Å­ïhUU!�’ŽÓëx3õAã¶ÀrÒtÏc,¾÷õµÆ­¦!Ò’Cpªþ " ^&#T%öË {ëgSÃþøÛ¥áMIñyiüI)~­Ú±x×Zò`Ó°ú|ûàþ xh¬SÞ¾ù¾Þ§3SÛ‹ã"V¡$…k^ ì¯~åê#~’dÕ¦@½k ‡4�Ó4cÝß”†o’û!jÇ) Ç\5àZKv�ûEÀØŠ`{žÑ_Ìê�’FÙ2«>¿Ú0͆—çàú�–õx-ù#™]) W¹ß¹ü~*Êã»MU 4LÉ ‘« ƒ.Ÿ¯wIZðœœ�?›r ]Ó¹ÓX ¿ïs0>Ý*é˜ÏŸò×ÅTþœ,àqœ’¢¨`Ã××4Ò­4¦éUÇ%À¾n+)bÌmó~Åoféÿí”Ä ÛârE†ˆ)y Ýž’r?“ÊÏ!�·:äí´='D%�qs›þåëCüc’¾’;{ú}ž. ý¾¬Êw©Ð[BàÕÀÀƒagþ«¿úÞìÂ6«ä�ÈkÙÇ43~ лäsùþažÁŸÛs“ûAf�dÃ#ɯŠÒñZª˜ SÙþy +®mYZÀedîÓr^$/,™2;È쪘©~<͸—rÅ�9¡àp:×RZ?ãåyè]Kàþ¢ñ�Æmì•ÎOíýÌ«ýÇ"ÁÀrù/=Šd†åã§}æö–UŠÙòó}0—Ò0%HÔ�õ°Ó’ ^öm»r9ˆX/`*–|p…BÇQ¿ø—ÿšÿ]ÿ½?þø×ü/Ư~û.ôÑ­ÐzðòQx�ìÂÍeðõÜñÅ:ð6ÍüŸÿÒ˜I:ŽÇ8Ç)ä:ï>¬« ¤9œæròsézå™ûWùlIq*�»à¹¤¿K:®+å/ûÎëÛOì�NA`›û¯h¦Dƒ4ÏΟƒ×©H�˜ös¹ÒzÙƒÓù¤©Ä¿|™e¿¸ÍO³Ø­óa}]‘/fé«·aN*ÈçNq ê›7îÑœð�Ô*oo ÅÑ/KûåýçvbÌ×ä:U=PÕwIžïGš“'|»i¿Èm”IÅrÍßÝ\-"ò图ôuûWþ…óú§B£õƒñ—æ[3ÿKÄÞþ¯*Z–¦ñ/ܜɊÊ!iL£ÆqÔ1¿¦5Εée§rù9|=YS .ûZßç÷ó9GEJS»V:–½,c_^@´ƒVU:AiS±´@½_Ò*™Â­qž½Šõ=‰â[å^¤MB:%xëÞ—ûF~g§]ú”Ö÷Yž'ãûÔR*;‘V¿'[ýÌ¢ÑÎü«³Õ>©³Ó9BSňåÿå1�Ðí­n-äíÀ|ë}èÎɽª©{ÿÔ€W ÀƒcïM½%æífŠ”+DLIã´$@5ÙT^Òjûj�÷VWYN2æèu ½ Ö'5¾/ÂÅ9S¯úÁœì0÷Á·û¹5ú¸n£ÿøeÕìýúZö6¥3÷ߊ¼‚²,~™X;c¤åš£µLÁf<£h›L°*ñß\Š"�¯çÊ6œÆË]²$ÏmG=O¹öÄrÞÎp¬Jø§ÎØîŠþ=x‘<$¶Wº¿~_~.fa×ûxë¸I(”Jã¨Ç©¬ĺʀ[óÈSð¶ æ[£›éÈŽâØr-úÍ5NɱÚÖ+3_<¹vöÑz¬ZÛWÁîÆ~QÀc{æ™ü›û9yÿ¢ÚÂzû¸OÕã™´®л_ó½WI±œclŒë”lK倨ÊêWI^ö¡H°ÈCôìhï䑌MÑ·: ¢þ ]2Ö­Ä À«…àµ`/xÌ:°nyVü*O`D�æ‹»Ï Þω~: Í3ð¥%¨j§3¬·rv}™4�?GïÓRì^6÷«5©q|±Ÿ�‚õi)›ß ×Çxž±¾wvî‰õ–ˆ îW•|©h%å&R§Z~]Í NÈ(g÷ï#5†5I1j]1 Uóï'UcS•‡"y$å~ÜíétC­_!Êßæ7 Áðê!xìüñ¯bϽµçuvÛ”�ÿ|.“/¥¹ÊmUà_&ù°n¿þ~Uú¿«—ußÊYõ1µaQÄêËŠõÌõè_o™¤ÐݯLZÖ‹˜_x¿ân�l�ë·â�èœ#uÎÕiSu¾ñtÞˆvûQV ˜¶E¤)ñ` ø«ºWEð?E~EA‚õòÇ£=•Y£ï¦\ÿ¶¹ØT*x·çøÆ#xp¬óªÎ,ø «´–˜«³¦áàrtp—Í�ýyù;·$@cöý&1 Úß<ÿUÇXž©űIë¥ âT`JH�>”¡ü2ù ü®³ìã[?–E{x6›Ç|�±î²¬ó¨·WßÖ'I{}Þþ­yŸŠ”çM’F¥rÆ„4¦Ó5)¤HJ©NB0=퉙…™E? �k–Îð£_5 ]:/ ÀƒbïQ3vÑ™L&—ÉÍ5Ø áà†ÃRÀ– z¡¶fKëÇ”ò¸ü�—³íëã:K̯Þ£ÔD2/’%¢]ß{×3ïg/0Æ­`õ|Ý*‚æõEùÒ_�[@OU»å8¥æPD7°^޹W})ÊøÏË ”I{MnúY- ¤wžú;&‹¹òÄ©ë�ü*/ïEõøÀýAðPØ]ל¯é­e|ÛFD(òDi3ÉÍänÜ5¸ËÝ—eÖÇÅû�²ûÞÚlùx›ÜO 婾kŒA´ÇÅ´sŒ$¥·§f _UhµÑ»?EÕ�nU„sm¨_)à%"xðì�YÁçñ‘îaå~SÐßÌrÀpJH°½Ç޹ñ—rÛý°AÒ�+ Ì ½kœËü+ï¿·Ì€o‘Ü^` #·r.ãÒG±r¿´sÎÔ8&ŠÙôR¤ÔÙ?·U>Å¿'›’.¬8oÊí�©96ë «¾+ö]ŠåBúúêfaëu¶â´'ø^M$÷ž�ÿ¯ýU̶1Ó·­ª€êð§OËhÐàƒÜ‡)YÀ«™ønÛfç o$ù*è[©OåæmÕ÷Þ’åÇ"¸ïu{;ãwéã”­+L½Ž�fëǰtæöƺ¿).;®yŽrvÿ¨uà¿ü~€�ÕR±$g¬îE*Ú^šÜþZÖU¢9†Ë±‘“bN ‘~áW}m{×{³ø/�-±Ó6Áðê"xP¬óªbMûÖþ—K ¥EŠ%l›¦ìâSļÃj½ø2P]\‹UõµlfíE�ÒþÖ˜ù¿,UP/‹0ìÑøÎ£NÄŸªLýt­g�ŸJçÛfÙ�V9…jzz·�Z�ˆsÌ[öû­6Š÷©ô¶õ~ËM=æs�§56¿µÞ,ùØU”ÿâ~D}oZ¿‹rLâ¹Êõ"RëºçüuÿÞ›ê¯2€‡ÀΗîo—ƒ­ÝemÄ:˜º•æêy&yZeT{{u^ÏÇŒëc<¶ýˆ*À›Š¶çqp©9ãÙo~gëãºãfr÷Ó²væQ*zc½w¿f©ÕH¯qÕåýSJÅ=*<KA”ýšgÁ§¢C4^£èÉœ”P~—ÿ,ø­Õõhü ‹{Q~.ŒÉž(R.QÐK,©ÿ©Þ'Te¯èÎU‚Äðj"xÐìÅ�óòÓ:Šk1U`÷"†’bL:¦Qã8N»¦iÿ%àjÕŒo³uÛ®*¸š�]*ÜG:—¥ë[�9§à±uÇcgll� áeÒ媀 ?{ç=Pn%SÌ×íYúé”?M•¯?6}:�'¢<6uúSÝßÐæ¾X·ÿ½kjõo§'E¡þÓ £³À�ÆøRÿÀ«‹à^³»ý—¾Yÿ˜ÖLõU ÖV[lÕ¦K1ÍþÇ”+ÎÁÝeçœ0Øi6½\¾”Ùw­g“oÓûåÜˬ…ªD¿©s}ªÎU:sž2¡¡\ŽÀ¬Ó„]Øþ¬Z Êćèì^ÌÖ�òuƒKÉÝ(âêŠu{©ªIŠqz]% xÿú¢¨ò° Ü·ªEÌcónÏ—Œ«Ç°^ÊàÑØÒ[Úà’ûðr‘<Ö~µzÿü�½Ð9luŠ)�JJJS(�é€õrVx+±ÀO u– öeÀY§åçS,öyY5®ÍÕ .oNhj%¤‹†æ‚Ç«h=Žùö,ј]¿‹í¦ý tÚžÜz¿Û–Ë�¢ƒF­*hüG4�êþZÕï´½ÁsòÀªÍâØ8-'¡g2¹:SþÏ”îïn‹uÒ@\róI¯€Á¾�M[uŠb­ölŽÇG„R3°­Óçb–÷2c¿ª°Ä¨«˜¯Ÿ koŸcæ^6vê¯ET÷Õî'X®�„ƒÕe¾h5Æ àÕEpoÙÝþ+ß^4@]m�Í\ïÅ`&÷ºÂ@ÔÏ%þ«~¸ÊÒÿåÌ~+NR¯-?¬÷);·)ùnÕòª‚ÜåùZc”Ôœ]oÛý}u®zL[AþÖ¹zßÇ÷.Š1·FÓåLû½À¹å%Š/S�ßt«¸¯‘4þSÕ|kYˆÎýËËDY B)é›R ÂdÑLlx3ô£9ûŸ ?¸?H„�õî7Û­¿ÿçÅ´$|¤é/%ÉBɗ™ç§�|.÷Æù·É¶ÚgVÌ\¦éO6hUÊ¿u-Özüi,°ÙÞ8n  —¯ù{÷uwOtºVŸ#µ÷�U}…ÆömPÝË“™r`>—Z&)‰iàÛzÌSë<)ß/ßVL˜«Doù†¢ @*‡¸:&%iLÅ~¡�žD("æì€ê¼Í÷½m­díÄûI¯>€{¯WÞbï¢ém"Á”púK‘¦ªîƒ†aÈûÏM�ú9tß þo+Ìåý½Ûøª~y£¬üP.ÚµrY‚òo â¯ÆÊz:^hæy¬+4ÚH?¸ùò?eõ„ùs¯�~¬^§ùõëûÓú}”Õæ&æd†ãÀ�Ó=J«öòýu«rêJs5)¥xžRLƈó�þ KÿG§ÚBÚ¹o¯ €û¬YÖ/hm�ãË xk¿:(JJJ1*ÆìµÐà®apù0È|¨úw:‡ÏAüÕ¬öùüy{yÜ_^—þ·^5�9 ½k/Ï}:ÖÊe4l��ƒÕgǸ~Ü**XoÙ‚½{U/WPn›å©Äöí9bº'Ö:¿O ±ÍËýŠJV& Øé)4•þÏeû—D€Sß¼ÿÍ2 urB•Ì¡¤”ìi¤qL‘ÆT­aPˆFð¾S• {/û�ðj#xÐlg{'yÀËO½¤€iöÿI)�‚ífÓn½@ù<£>×<|þÚ¶ûvÊüÇÒvÐ�â¶Ó÷â³WŸ[ ¶ì�3ã¬F »ìk9Ó½Ü~î1n.“ßh§ÎlöU¬:oh›h�ñ³mÛQ�/Eq}c5åùr"À¼ÀêžnÝŽz{LcŒ)Å˜Š¤‡½¸|\ð¸ÿHî%;ó_ø­™þwm³Ä·ey÷ˆP¤éoÞÍÌò©Ê rê–Ó÷Må�ù"lç³´­#Š€wTÝ m×Û™ÿ§A‹ª�¢R@=óß:×ÒÓaÝGÕë uz�ǶPZõÇbF|Ù#“"�{4;³î�7~K•…ñt�•¤43ÿ£˜1ŸÚ‰ ­!Kùw¶úýMýIIOSD#éã6úÿ.fèGsöÿ™Š¯€{Ï.ÜÜ(—ß=ÞöÏÓºí‘F¥1i,ªL1ùrfü4c} NÏøAíYåQm*öVêS¹oV[5c½Y„ 5©>óú‰Éz�OùK«—HØëù»tþ¶Æ¹õíS£ý¤´àUThÝÓ¨† U㚇µL°9_&MŒS"@Œ� ™Óòo Êä€âF¬“7<Ÿ3�ÆsLz>FÄq®Ð—sãVüfº çŽx5‘Ük­ º[ì]4ÝkÛdyöJ¡1¥é}Y  °ÆX{“Ö�W×i=ørŸù»9ˆ¾^Ï>”rÀ9M_ Û1±¢@%è]eÚR°÷ª—Ü ¿°ÚÂéZN×» 2§Ö²Ý@{9æ�@ûœT±TiˆÎñ©s}ó_þ¾<Ïr®Ó2 Ëq©® Ðè§•c0þM&ù)ÙàùÑÞSRÚ$¨1†{¥ÿËÝ:K&¤½{ðj"xPìŽßͳë{k¼—3émýmðO)”"iŒ¤4¦ð-MAÓ) œKÐï.cPY½,Õ_µo•øï}W/ �ªíEðy :ÏmÎ�ýÞòe…‚r<‹þ”c<—ÐßÌDo—ÓÎwóWU5„VbAZ·g«öG)åÄ ­“5b3nZ’(bÙo¬ú—gî›Ubçºu¦|ÿtþcÒSIŠX›Š­1ÚK 8ØÿàÕGp_��in;Û­}|¯V/)`=ƒ{JHŠ”òìÿ´ ËN%ûëàouΘΚ“ê%:×”ZÛ­èûœhÛ6ìÜ8鲉ÿWÐzf}DãBZeí[3ÔSQÞžYŸ¶³ë—ïÛ íóSe…S2@1{u=åyŠ6怿¯PSFm’”ÆFß¶ý½=Ú³Í�(Z×QŽqè²e.ýàÕEpïØ™ÿº¯gk_ ¶3ç°Î7±üoHSªbÅóëRï¾9gYÆ¿œÁ^žµžE__ÂN%ƒº,ýª¡(* ô®?÷ÉË뙇Þvư\Þ@›c·Ò ü&ê`9;¿°Mì¿Lˆ��ÓíHѸÝÕ¶T•öß$n´3›v–.VUò˜?¿žlïé¼Û‹í£™@ÐI*x…‘ÜkváæV€ºwü^ ÜV­ížÜª½l.ý/­g”—�Ü\Z>ê~ïõÙ¥¡ØÏ‡©ÿ&¿`ü�½1ìŽËàÖ ­²ÿÍG°Ôh·:&b®©°„n®Ð:¦Ü^6EQ¡ ®ÄP¾úiÿMe€ê¾Y=¾uuIóyçJëãÞy6¼ãÓ�Œö]»d¦§*@wx þ€ûƒàÞêÍ6ŸßÙ»hz§í¼zÀéϦWw™Y#ž^Íæî÷O•¦5æëþÔm{cÖ¾¯¿·Þð¬g�{3É l«WB¿~´j$4g¦{uíÛYÿIãö°”ÔOX誋RþsÐ>z³ÞµΧ±Ñÿ±ñûkÝë¼�ûöÉ3åe!6¥ÿcۇ“gþÌda²8ýD÷–J8#:Çt‹0� ^m$¯ëoß["` œŸ"è6îÝdnÜäà w×à®Á‡bæ÷NÉþec±_UÕ}Jµ«XÐ÷õw’¤!ÿ©q�óɪ㼱ŸåyçÝG¨^%…Ô8·í Hc|g]å4ÚIUI€tZ" V3àSq¦�VI£¶K ¤Ëž,çÀzØR3ÂW—\-GP' œ.¤xMúú“ÃSw…»…›U}/éUˆÝq¸ïHî#»kéþr»mËó/Os¸¶ü~½_Èyú¿›ÉÍuðéo à óa§oEpº9‹»Ïªe –$_�Ç–Ä€AÝó!©Ò7ÇØÎ ioœÓ™}Ò™G³NY}×”�ýöª/,»Žê—îwm*6l’Êïs¿SîSÌIã©DÄf‰‡NÿV÷ÈšcñK¿þæÛùçæ­DŠV%ƒèÏôoj|$€û�à^±3ÿe_}ova›ç’N�ó(�1—¹És€Á]î®u¢�7š™Íóöù_R¶}±; MчM[¾}²2H}·¥¼ùXåg�ê—Ð?w}� Þk¥ ’§©2@s"ü'ä_Á*�!×½Þ¯ÐÏßWÁõr6� é™lÊ?‘O9(§¼‚ÐG·ZÀ÷àCpoÙ…›ë@øÞñ{÷éó’=fO5L.×`ÓÒ«sº¯“Bj'”û-Óô‹ƒêý‡ª›Å’«e¼º¦bF{H)z3Ôó¶°dîŒeóVÄö‘˪™ÿç4ât?¿S%uöKÛ wTãõ½¨›ndX•@åý(* DÙ—¨ö/¶GqŸ¦ Ï#"Ö¿Äsz¢³Û]*¼zHî½íly»ã,öus¶Û¶Ô_M}ŠÎÖ³ï½Ó^}žÃ´¯¹ŒÿÈ÷âÐÈGZ£Ÿu ß:—`ÕU´ ¼¸ òMtÆi>®µ|A£Ýf›9xžBII›Yós’BôÊ÷·~Qô«*Å?WXõcªê ³bIˆb¼bT{Y÷j�¸õu¤¼LÀ|Q¼OQ”î_ÿ²ÆÐ³P("¦C6}¿ã¬ý^Õ€Ô=€jÀ+�à^²÷¦�½èK༎ Ç´}~;½†bK0·îc=s>ÖÛm�Üdæ’ÉÅúñ­@»U�5¾}ÔqÛyä©bgŠ€ÿTþé“û™kÜÏmU  L"(’Ü$ §ý¬Üo¸ã•�yÌj½oÚOè•ÆÏߥ â솥o¶J¸°öõEîkJE9þâ¾nª<ìŸS²õlþ*Q"BÏ#"Ïþ·Uõ‰o‚ÿà~!¸7ìüÕ¯bù½®.ضSEÀ$3—YNˆ¤H£b<êx{«ãñ¶ˆ›¦pouº, _V&Š |]ª¿å¬ö”?WÝõ͇êšìü�Ïý_úTµã~áý·7-vÕÒiÆzj–ÏÏV’¶ '­f¿§jÿTê-´Jœðú*"/ñШ&�êªVü‹ëòƸ'IëK¬Æð·Ë¾ß=î¿M ˆ¥r�´­@ðÜ?$÷’u^Õ˜Á¿þ~¿Ùó˘Ùò7ï1-�ÆQé8æ é­õá£Ô—�Ö"YÁæ »Ë¬Û w­JØÏíxçZ›eÿ‹ó¬¶ ç™Üï8¾uл3c?EuÎzVý¨~`ÚÇ–ç›?—�ú"a Bý$�Ð~@—ýŠ�ýÔ¿Ab¸_H{ÁcÖ�ë%xñ9B2“™Ë‹„„ÒaJ!Yõ¨ÑZ÷]šïK|6�®qæÓv³•%ð}ÈŸËóÖ%íë'"¿ÓØùfÿ<û>Êöìm›vËÖ§ho�¤ÍÀ4Kê§Æz÷ÅûyI€hT ˆê˜ùsDÕfTcÛsµû«¥ bsì˜ìinÿt`|#ƒöÿÀýCp/Øùÿ¢_Åò3ýwÛº´ŠÀ¶ {¸sߦÏËþÕlz× íZõÒ)p<³Ë’÷EPx5¡¼œÙ]\«UUVAåöŒï´Ì|ï�‹·ûíÖh3cØ[\>´ œŸ:´îƒ·Žm½–w*Ÿ7:c¾2ªœéi,úP$ÌÉK¹ýTÝ7íüîêñˆÓ©—ޤêúŠÊÏ"/ß�Æ–¸h,î€{Ç:¯jÌà_ÿâç8m�”¦?Í!Úi=vs7s— ž#ÿ9h¾$#øôg�q”åùq¥×÷:9À¤áÜ#N/É¡ ¶¯b¿�@°u–5ˆ: œûhC}¡íîEk†|žµ_&5x9ѹÌVå�bÿhÝÛ¨îA~�Ô¨>0Wދܦ­ïÐé:ªe¢Z!5ª?Ä) ?&{–yÑ�3¥û»Ûb=ÎÑøI]ÔÀ«‰à^±÷¨ëo³zŸõ¾)’Æ””Ò˜c¶&7×àƒ?˜û•�Ö˜ƒø�D•�ñ(Λ:}µÓ¾Í ìü}®2`jì_'KÌ}óÎãQkæ¼Ýí^l Rë‹il;}]öâ5uN4ÏžO�ïªwÑëx^ÎÁËû0Ò‹ë‰2°^%yDyZK´>•rÛ·c¼3W8�®U}á®ð€‡ƒྰwSºßv–°Î1í¶RŽÂFô57;¸†+×áÊsW½zô°FÌÜûýjn/ªÄü¹H$0¯ÿEßý‚qób‰¿ËãRc_s5Ëû¯ú¶'ú�le°½— {ß÷çuË$‚ú7˜— ¨+„¶m­*”I Ö¹U€¤4Ú³Sô¿JcHÚ^ODãÚöÆ 7Æ÷ À½g/~œ—Ÿ:A_Ž””RL9pjƒi;6¸¯#ýÖID°ºÄ¿i æ§“Ú<Øö­(uo�G›Xý�3Ï綇åxï.�`�!±¼ÿ™DŠM¼9íÜ¿9Ð^–Öß{pËãi}ÞMòC¹½ïf2Ihµ¤Âr`uŸRÞ7•IÑø)ÎÁ÷¤%Y`µýtq¡˜V�(û¾tc·1é™b]k`{ ïUОà?¸ŸH^yv·ÿš7ëÓ�q}~æÿì´’|,ý07 ‡A>¸ ‡Á$·S@·ì®M3ëÍNÁ}+– èþ•}˜ËõÛ)°½z�µfÛ™ÁKÛk·F\*ÖÞ¹W©Ñ¦ÖmYÙ·¹«±sûÏ-ƒP_½[¹ÔÁü¾jkž9ïS‚ˆm&Ð[uýÑø¹ÍåþSNRˆöµ¥F›Å˜XÑÞÍ­¿£ŠÌGcKköt÷¸/Hîk¿Zo¿½çPós63™™™›Ì{Ë4ýVÌϽòÿs²€—í©ø¬Ó¤óU/[}òꡨ?Vn’/I wy”ªÛ,‚Ëå5nf®çj)]Ðf§ý¥�yûé|¶Œ]:mOy&ÿò[òÎ)‹ÒýÖJÔHÕ¾ù:¢(ÍU~®&�ʱ™O<}wýÉ´É‹ïã‚1˜·Uç�Æ0]ÔÀ«‹àÞ°o`Óvá)Šýr@ÜdË„~s3³%НvÁ é Uàx(i>±çõ¹�<ƒ}Uö>Œ=Š8u4®¢¨h`žã¿—̪ï$`\tŸöלOgƒÙu¥�tÚVÔ7e¢ÈpjÊZ]iò«�]š7Ì|ÓFŠ)¨Ÿ¢XÖ@)úë¿ÖØGõºý™ÌÂ,"ÿÖ×|WøÀÃBpØ]Íåw�õÖ›¡_cÕñÅ÷î.w“»mVÅi²÷ª]/^uš±oõZóZŸwµÎüðŸæÏúˉÓÜ¡â|½’ýs€zž¯b¼¥ÿ7�Q�vmg [_ÏZY¾ “�zAë˜ÊíGä&ê x>gY-¡•,°I&H¹™Ær QTr0ÏŸçñŸ«Lm®Ó ’úIsùÿuõ†›£?›~sž+NÌãчVÛõ8«?ÎAb¸ŸHîµ½™ègŽ[Ux·3O § ·›ç$ÏqòP(MÿoL1ŽÇ9’<- ¿™ÄžÆÞI>Ø¢‹ïÊÙÿóõó›qˆþxYqžæþqf¼÷¾jì¡ËJ÷W «’ù©Ñæ˜÷étL4gÙã?'6DëZ“bÜ/3öÇjXæÀ™€ÑJh�q¬ö™úÝèk5.oß\¿íƒÉ‡j€Õx¼�{‚ÿàþ"x¥� Ì×»ÛÛÜÎðß?U0ùâŸfýG(")bz/‹ª»õ:ñóE¬Êh={»ü"Neç­\. ¬ZÐHX½î=þÔ³îç¥6QæC·Î˜zu}q札 ~OtŽ‹N»ÅÌýØk³ø2m«LÉ©ÚO’År ¬Ù^ìÿ–WU æJ)ÿ•C1½yzsõlõ;yÁ@}4=ú€‡�àÞè�­µŸõ÷¿øÖ<—›Oë¯çµßS Ó¨ÛcÒq•RÊÁÛ¹ÑþK�ÓÏåcÔ¶|}ù¶øì©ó¨Ó*á?TíÍýqµ;4IaJòNœx½^ý©ŸõøuJúÇØh¯Œ€�º¬"A�rö~‘Ü0/�ª¯>Ÿÿ¡±¨@л'¦v�’2lN©w)>VeûG­LOŸ_=×’Í�ª@¾ÚçïUØMˆ¸¿Hî…þŒüi‹½‹¦[‰¶Ó‡9à;Íø�£ÒqTo•ŽI1Æ6À¼R•÷7Ë3ÊSQº~>>ª~V æøp*ýV´»$ øòô³++Ûk<¥(fœ×³îý²ûfÕ~‘´.í/%í$<ÌgN�²þ±ÏçJGIcÞ\ÌæO­ãæòýcîëXܳ´Ý7Ö}Jó>QÞ¯|=níßY‰ óy«võ7?ðöé’­ªpAà>:Ë tó>H÷ À«Îö‚ñ:ÿ]8· ÊüÛ™%–˜­+bTD(ÆP:ÆT `ŒS­úQÇS=©9c;RÞZÄ[ý©g¹×I^|öª¤±½ül®ÝYíËöT;¿mlÛ-;_&ô¤elúê€v+à}ÔiöüXõ%W"˜Kñ/³ð«6¼Hï–æ�Æ}±Æß6ùcþ„Ò3ÉÂæô‰ú¶¯~?�Yÿ»÷¢ÜDàÜ_$÷žílï$xùi¯º@g†ü2“Ü‹‰à¡4&)¦ ótXе9b[ïKe¸1ƒ|Ù%ª¾{£ï^]Ò\!`Èßùi÷ ‘¼êã…÷"RçúzcP�Oj•°OÚÌ¥%ˆß<_ÙFyüX_ïÛJİU5�h�ë©Se¥†Æ¸ÍUž›EÈ,ßéz<. øh5Ó¿YÝ ul½=Ôü—ûÌIƒä9áÀ÷*)Ì�*’6ÕŠ@yë‚ÍÕLŒØœÃФ€¼mþ˜¤¥”ÿ²ÄBª®õÐŽœKÿª º§¢S©þÓ¦uÿ¢\.@Ûk�uû©N„˜‡aþlÊÉëvBº1y˜)ܦ*ÞZ :³þW÷cGø÷ À«ìl¹ù3kÛ·Ž÷r¯½@¿uÌ$7ÓàƒÃA‡Ã ÃÕ•†á*'ÌæßsÀ×××µšý]–öŸñVÌZ_÷Õ6¥êë¾—3âmú˜z�Eqfˆ/¨Ðëh•é�ª��öæñŠ”O9Y o«×­�éu}åùlg¬ZãQÍȯû7Ÿ/_Ÿ-ÿÛ¨>°åó ˆbi€$u«#Ø©Àööé®{Ì4XYÉ`o‰‚‚ýàá!x%Ù™ÿ‚¿ øÜlÓΜÃvÎS$ØTÀÝå×p8èêp¥ÃÕAÃá T6óÿDÕ¯Þ—%ú«„€Up¼7N^móí>óŒþU‰ùÆ,öÆxúî}Ú ¬7ãÌ©}mÝÛÑJpsÑý9Y`®6�Nö¨;q[+O°JT°\l¿¾s…�2“¢µä@ëÂë~Fî{*Þ÷Ži´ç) ³SÊ]D�4±é# àþ#xåÙ…›ëÀùÞñ—Ìü·þ.1m´\Š}p×p–ßëƒÕAs?­5ßíC±LÁ<£}ÕLcùî5Áê˜ÊÒ§%Ý+ÇŸÞæ;qâzfgf{‘ðp:tîÓØxd«÷÷ê5U½˜¯m<]kª�-!–eæJ±k[ª8hµ”ÀÔ¦i[y ï?­qºßåLý”¤”ß�E…€›c7)"./íßIJ8{ïî7€WÚ^P¼.áצ÷Û>}¶âlvªà1•£ÉmÐÕá «áJ‡Ã¡X  .mšç’öƒÖËØô”’Š`º·‚ò±íï\ªß=?ể¾ô}ûÔ Ò·t×è´yþ©õ)�鼿—•VÊJõ9RãœQì_V`hÝ÷èA]â_’RRZ3ò=³Ü~”ç*ó1ž–3ˆb©€T.0µ?†ÞŽ¥ˆH‘4½O—Ý·èÜ�téý¸?H ëo·óeæev¦�É MkÀG,“ð‡ƒë0 9_ŸÄŠáÅëP|áõE«íúÏæD€€öz<Ê ö\ßëG= ?´MÐØ+ƒßÉ:ˆ;oÕõ¥:Øßjc>Gª.£µô€iµ$B><Êý«Óäë¯sâ4Ž>'zØÐúi™õ?/_©ºŒ©Ñö,Išþ’"Òί³7Þ À«ÊîZº¿Ün�²úóÀ¼ú{]2¿užV¹zå‰Ú¡”B‘¦Jó|þƒÍu |¿›gƒþÑÝÏb︼z½ïÍr¯KÙw$IUYhDlKB^”€×¶ä¼µÆ©HR˜Ëίª”׿ç“üÝ}nœ×Êk^“=åj9–:x|ó`·ú¶­Æoõö÷y‡ò¦"ÍûÞ£Ž©]޾^* <]½mÐþ’½d€:JuUƾ”îæÌPí`y{T�,³ùçà~ÙǺZ€ßEg{±)%mËòçþ˜i³¼ƒÍým�g(ž›-;4k´‡¦³×îXÜ_$¯,{oÚØ["`5»ÿœ–ƒµf’™É¬\`Z“=Ò4³ÜWÁõC~ôŠYçó×õZò­µå5Í_f‹§êŠ w*+ XÑó¢?V'x1ëßÏ�ck<[•”Ô¯°è_%'xuL¾¶¥b@Z�×Vǯï霬1µ1Wk¨gþ×ýÉ•bÓü}tJêÏ�•ûÇjé‚Mÿ¬µýô[“¤c²'ƒÂÍC²¥xÂåöÆàá xÙ»)Ýo«rýëÿú¿tæÿüê�®¹ÜLn&Læ&¹i”4F^ÀsàÛ\Í`o]Ž=BÛÊcãÌxl·Më×ï�ñ iè-R°óÈäê' xu}R» @ ÷*"ÍËÔË”3í‹vcohÊý£ÖåüÇÜNkVãóR9 V-#0·s•�â|sMíÄ“M…)Åá7³Aæò9eN0h-eÐÓø.H  À½b/xÌ:ðo½ ¿·ÎS[T˜ò úåÏsûEßÊ™ÝEÐ6¤m”ÞÎ\ºk„/góà¤Ó¹ê%üò1õÍŒúÞø\òxU¨í\?<7›ªV:Eð#ÖôY*a>oä}Šm1ýF€eÙ€Õ>eP¿u}ÊË$)nuJ:(÷±Ó½Ù ±­vMÉŸ»2³˜{föýßÁðp�¼Rìü¹¯bÏ­àô^[—V¨7�ÎáEÖÜeƒËܧYÿà Ê™ûsb�i?Ð>—ý÷m_|¯o­™ä­µìÏ­oûãi½1ójŸ:™¡5û¿Ó˜Û8Ì®—hµiE¡…¢â‚EUq!K&T÷"ÅúÜålûֹݗP,P${Ä<.Õµ¯E’Rògîî&3_~{íßQT[b[q‚%ÀEðʲΫ3ø×ßï7{—eª÷¶mÊÍ4 Ò0 rw¹{»´{o&ýÈ÷j÷ƱªþÅûV�>´Ó�ÓNi{@µŒ‚]ðøT�a\vo­’K:³nAÿ6?âûŒšÊðGÆGyãT%f̉ÕøX½nÃéÕ–€~qßÊî/UÒ)Ù ª% béh£ÿôùùxøºšY½1Ž~Yÿîð’ î?€WÒ{TÞ|¯LºÕûô“¬ —%Ø-zk¸V”韗 �÷ûæCq¾yßÖŽƒÚIÊ%ð§€¶­féçý– p(Ù¹ ºÝqŒmšu¿47nIï&ØÜLˆÝǼX•à/ï™uîC�01ßÃbÙ€¤â>šyŸÇx»žÀ´i® 0'ä…rɆUB7Ç«›SwOUî8pü³<€W�½›ÒýÖ.cï½6.X`Ó=›fùKK ;�RC)…"…Ù¼¶ûª”ÿü~¨º7ä–�ÿ9¸ï§ ðry€ÆRK’�4{½qÍ9ì¶Ý&ubÄ—<6Y±oŸ{³úË%ªöSÒOÅlùT´1'7äãÒ4f¶ú Ì�Í�ÿò¯±ÿJ×RÖáï]{n×êã«WoV÷Mj-5p›O‡Áb°:å#ª6Z71´{ƒƒÄðp�Üö‚ǬƒàÖ ú{}žV}Jˆ4M)4“ÆqÔ8Þêx¼µc•B¶…—%ò q“– ÿ&Ù!ŸÓ­s5URÁ¦ìÝ÷z†ûPµ»�K®ÖÚövá=é}—:d� ÷Š)! ÍËD±`AÒ:*_'C¤vŸ,N÷¢Ü^.—°^—ÒO§~Z4~ci}^}o±‡¨îÅÇ?Uxûæo›2·0…,Ò{¸'ø€W†�ÿ¯öUì¹Sþ¾ÛÖ¥UêMë û\þZÎ=4¦QÇãQ··GoŽJÇ£µN¯¶ýlCãñÄŠÙüi™é¾Œ‰©jË;—s®ªÁÜfo<{3äïš�1®ÛˆPй~OÊËÌ�øTõ¡èch�8aeÉþù˜¨ÆUÕþi™Q¿‰ùX¿üw[TXÿÅvƒ(ÚY�xúðäöƒÏ\6åÄ´d@êÜ—rKköt÷¸ïH^IÖyUcÿúû?G«-ko)")”RÒx{´ãÍ��Ç[�·G¹¥7æýN׳ï‡t.Ëù·‚ðyFû*èßë[¹t@Q`“Eq&øk^=-ù™±¶þûÕ¸Õ3ês`=µ– (·Íû•ŸUíkÛM›všY/Ëã?÷±¨�;4õ'ÛVçJÕ=‹¨º?W05+¦·éÙñ›n¦Bšgÿ7+”É�qØ]Æàþ#xåØ{ÔŒõ·Y½O? Àª€¼I2›­)BiLÓ¨”F¥ñhãx4I‡æuÌKXä·z«~Ùƒ¡è¦5sÌ]¦¢²€¹úÁûÞ£Ñð÷¦ð—Ç3ú/ :Ç-OsÔ<ÆÆyZ3Úçåâ¦�r|¼ÓßÓØÇrlñ©ü4ÞÏML×íó½²2Écn¯h+Ú÷#ïùÄÂ䲘6ÇNÀ%÷àá"x•Ø»)Ýo;ËôÊñë‚íêŸ?¦ pDRL%íM¶ p[kÈçïWÕŠ%V¼hGÕšóV(úíEe·Æå�Y* ™¸°§|N;_×UÔ® IáëFRX�ò³ë-i;¾JJHUçâ‚K*¿°<¶^' DçoîÛÔÆê6„žN;…4æŸÜ|TÔmìu´Ñé 1<,$÷‚½øq^~êý½>O=[¾x?G`M’…BiI?ò÷1`Å1ÍÂ.ºVl«ûn�ÇšSe›ƒü«Rþu’A씄7ùR9 —²½z<Ó×W_ëü>­ƒþó)Š uœ vçv"µÇÛêó§êµº_�ûÒ»ŽùžUK:äÙÿiuì¸ýMØ”ôQWœÙ�4þ�X%¼+ÿÀÃCðJ°»ý»™î4S}S²ýÜþåyŠý¼^ @òÁå.¹›ÌMff§uæUÄÄ;Aé¥ @½Ý*ðÞêw¹®ý^õƒ^ð|\ûú˜ÍReŸÕh·§úþ¢™ç§jn¦Mr�ÍûXþ*–0ù) óÛ¨üËñ­Ðzï¾Õ‰å8 QìsŸZ"æ‚u"B’ž¦ˆHcD )¬ÕËhô.vî;Áð0‘¼r¬ýj½üöœC›s­ƒêå.S�ýüw ƒkL>¸�2ª0m]Òß:Køþr±�CíJó{ë�¥¤v©|ëÕ÷ÆìÜcU§ @ê�{Ai?³ÿºBBhÔ”�4j ÎçµÞrŠÎ¥öÆ­® 0'Ô÷k¾�suƒœdP&)ç·ù÷UÞÛГ1"RDŒsmƒ9û¤u-ÑúÍi§8Éàá x¥Ø7°i»ðå,ÿF€Þ,¿LÁÿéoÐ04ø¼�%k`ÊÍzì\²�o<¶4Ö®·8?–sRÁ2û\�¸o¹q¸Ã=é•Ì_K­Ùò›>[»?«ŠÖŒö9 ž"夀yØZmÇÎxTûÆzF}šÛ®¯9ÕË7ô–=HEZsúÓü[zž"bŒ‘¯Âdvéÿ­à¯€WE3 ¹ä¬Jà—3æëÒý­c¬SBÿLB&“ËÜånÜäùÏÌ”,òÄîø÷Î,ó弩øìšö®u0¹z„‰¢ï^·Ý˜)?”ctáÌýÍXïÝ/}ížSûþ-ŸÇ3KDuíéÔæ¼@ä™õ‘Û[Ú�N¢ªú0 �Ùœ4ÑX¢¡œÅŸZ×»Wñ i»„@¨•Ø¡gSùÿ){ÃÌäî9 uLëü�¾‰àá!xåíçÏçå';óT`�Ç„íù溹ˇA~pÙ -+¯{Ä OE;Ñ*û_”ëŸO]×O}OÓþóšõ-ó,[—ÈoìTHÅf»Ã=)›L�¶ëw=¾E7³àSµm¯ÚÁ||YR¿Ž×K&¤;üÞª’ý©—ÔÑ8oŒJ»ÉUõ„*0Ÿ’Þ>ƨ§o†\yâÅü ÀKw.0_ï~×uo†¿íô¡QEÀOmœŠô*g°‡Ù)­Öšð­~Z¿ï«Yé�’þ«*i þÇ|þˆÕùæy­5ô¶3Îõö´+"UÇæ$ÙiH›mž‚é)¢1^íÒý±êUì7®?®–0mKü+ù¥~2AÙŽ­ÛŽœ$0æÁ�ª›kn,ii*. »SŠˆ$“ÂÍå’;ÿwÍÙÿýÀÃGðJéíµß™àùEç°Î¹Ê¥ZÇžf훙̦ÏsØÚ]uOŸÊd‚âZ¬õx’ƒÍóÌwk]H6Meô‹ã/züñ “+ö©Ê |pNQ�'É-Š]:Áé¤vû›RgST‡VýØ­ŽP&´JöÏmxõÛHRŒ§ýc<-I�Ô¸Wee‚uU�PÒñ<ŽŠXê3X^nb}LìÕù/î=€WÆÞŒü�þ5ÝJ$°Ý>X/¹ ÊÏS…MËÏ'S„ÉL�WûXÞ¯>¿µú”ƒ¹©5&Ãé8÷üDS—ú�Ü÷ÜŽçs_øÝ¹ÇŽScKꜧuêYü©Ñ‰¨¾‹j ë>·fÂÛö¼eü_IÒ(¥uà?ù¼Ä‚�^çYûqj ÅQ§ ©:­µû»T˜Î™F{LIcRXHnn&o%kDkIíi <,$¯ÛÆŸýΊÙðvA™;·$@o›)")¢,Q/­fã[‘`{íõ–)(Õ3ΧÄ›Û_‘‹@r´Ö¼Ÿ÷¦>ZÝÆÞ£Rh•Dм5—“Ïí“Aìz<´[9À|ºîX}?—௓ êñ�e{ÌÇÄØOÒXî;ä?/’,æfŠYÿ«ßJªî½÷"ï‘òò)žGŒ‘Ç%–߀ÛÎxÆþ˜�ð0‘Ü {ëÑw÷^~Ú ô—møÙóG®Æ1­M?lCɧ@®™ÉËrþ^Ÿ#Úç^•¨ŸƒÇó·s0.9Ÿ+̯^õÓò1eé}vÆ-7à{�H©ÿU´έYûª¶å¿(ñsC¹­¼?ubC]¦¿¾×uÛ9ðŸb{�ç{QìsÔ”<0®û³T˜Üì4îeùÿù>Ô—R&ªD�¸±úêÙ”€0%0DNMØŽ%H^*;ó_ê­™þwmsg¶¿wŽ·zfýéü‘’"�JcRŠ˜B²ÓÂì’y±6{ô¯ƒ»®fb@N(�—3ÈËãù8›ƒÿóE ëvÒ¹G!ÏÇzõÍ^%„».Ã�ºÛRoÿ&^ÏÒ/+ÔMÌß¹VË)ä�"Í�üTt%mbÌ÷\þ?ÆSR@nßåË=oVRÈÉ)Í eG}ûÛ*¯1�~/Çäïä2ň…"µƒþÑœý¦"ÀAðʰ 7åöÏÉ2E[Ö9ÖOû¤””RRhÌ¥Ú%Å~?x1û¿×oo•þæf$KE5kÄÞ[ ^<âØǼ±t‚_ò¨ä:¶w·Ê@uÊ3âs,;-ÿ[ê7… Ê`~©Ü®¾_åV´Ž¯*&ìþ%­Ëø—Í”÷ ŠöŠä…hœ{ùY­E¢�”ìiÕ‘¢©VbÉÎ�ü À+¡U¢ßŠ-ö.šÞo»õ�5f±ú_3ÉÝäfr7 Cœ·VC¾})— Pä8óܭט×:! xµMrDñ9U×k½q)Npq̸UúÞ’:û§�¶rà?Z¿‘¤vçª6Ïå'x´ #Ÿ#m—h]ÝTE ©WÑáÔ§9èošÊFô¤åØ1ô<Sø7·%: éÜýx8H^IvÇï³Øë øfíu» ÍªýòTÒô7Ó`¦ÁMf–—°Õ„ðõ›¢ü»·JÁŸ›ÅßšQn�GœVµ?­]Ÿÿ|3uÇ«@±µ£RõºÓï=«åÊn™de@;´ŽîǺÒÀ”_ˆþù—ñ¨güçv£HOs`?RcÙ5ÚLÛóæå¦X>c÷çªÿÇdÓf1-9`gFóÌ8�ðp‘¼lvnv¿íl·öñ^îµè· lÓÝ9Ð?˜k0“.÷é½mêx£�²t™°ÞÇd�ïêYéÑh³�ÖZó¶œÛÍtÙò¶}�Þšó½YúZ®Ã¥*p_R�YÚ´±~mÍ‚�ν¶õ½)gä·VX�’t,f÷�Õ5[çºCue‹(~ÃeqÿéýíÑß‘>ýÔ÷Kwûàá!xiìÌ¥×3ÁíÂ6/œÙß<�U¬:ÿéÏæ`¿¹\.Ë Úò¿^µÓZ we@¾~li•Ú/«Øù1^U(‡Þ§ê³;–õÑ¿¹«X|�œÐK(˜ß�Åå3ô½Ñ‘r[�h�†öò eBƒ÷ËÕèçqª�æà¬Æ-êkðùÞOco«ßõ¼LCZ�Áíñð\!™<$‹S•‰ÖÐ÷ÆN�÷ À+Á.ÜÜš)ß;þ’™ÿÖÙ¥øà�D;õÅr,8RRDÁΑt/öµFÀêÉÄÖ±û<å[6Ÿçp²U�ÞÖx'`­íµ¬ª¨J èòM²tþ¶–Áôh”Á¿ôw° fׯž›6)y1¦Qu?¶OƒQ´eõocP9[ÿtИÿãô~µÀ¼oñ>汮dzñ[^%P„nFªPXX Óï!d&óÎÒÝ?Áðð‘¼t­@½[ì]4½ßöé³g³öngD^³]r·o’\²A«»—ei) oVU(ƒðÅ^¬'ÛÞ¶œ«¼®òBRã�¨¬zàÚ¿øèÍòŸæà�iŠÿ¦1iLIcÊsómÐ*˜ïu0>Šòú­µé瀕° è–ÁåâñÆ[ã‘Ëþ‡ÝáºókAíE*úpN:[Áê4ææÇbÌÚU æä‡pUÉÕ2S{©ÇN•™r£§1^û©j?Çû4Þ›ß\ìüúêŠ ¡çÇóUçv— °^o$/“ݵt¹½.«_þW¾å½ê²û­óØÎ£A㘘fzǘ1þ�cÒx•Æ)Hîe»s€²¤ÿbJo¬Y @EŒw¯”ü\ÅÀW3Ø_̼®½U§õjæyk{ì´™ŠYýµ¤m‚Aj÷k.ÝïV-iPö)i)Û¿ª P~Þ{l´¢�Tõ¥QÖßÊ{âEùÿùˆ1¿é�ÕéýÛO?“[˜™ävJ0;Óï^倇‹॰3ÿ…^}ova›ç’lç<ýYÿe¢ÁTå?”"”Æ£ÆqÔ8Ž6¦¤1Òœ™ Uùx¯KóKRH©˜yõ©[åüµóª)࿹žÆys<Í3êCrÙ…÷©œõ®vÆ*hŸ.¸wå8”�òzfþœŒ�Š�åùÉZªÌÛS:Íü_R>¾ø.Fmçe\ýeÖ¥þCQ% œ®hzW$8,õ«ÏýæG¿ffan¡SŠü§fË­ûÐê/ÀÃCðÒÙ…›[kÚ÷ŽßKhÎçת}ß&L¹S@xŒ¤c:êvÜÛã¹|Líó½èÓÓE3Ïëj¡MŇæ¬þrŒÇœ@�îi®²�4UÎ_'QDt‚ù>ÿ�5–„¨fþ/³÷‹¯—Ê c.÷_S.9°¹1Û{ÒÓ©ž„M5%¼=¤Ñ¬æÀ’àõCðRYçU�5í/ ~Û]–¨ÞŸ9E„ä1'øTúß]æƒ"4­óU`ÙíTî¿|Êû~zoål{;õió;×Ó«PîægÆ÷Üç^p¹5C>­Jõ§ò«ÍSZ«ïÖh3ß�¥Ä~’Æt�õ˜ZÙ^cY…ù—gëj›‰÷9ð¿l�´n'Åv8RcÉ€UbÃÜçr»Ýº™Ü$7…L±Z�¡—\‘tá}xXH^{�š±ó§°óIÖXF U?b ^Oµþ¹¹›ÓBc²b6xkÝv«žFæsMI¶J¨úÑX9 ¬\P?æ¤Æõ›N‰<ykŒãÔŸÆLötv�úN{²)€nÊüÞ~!é˜_G…ÆdŸ—HUYýº�<{nÏò=±œ¬aƒªpûéž–V×�sH²P,I V\—å±�Ó�§ãRØ;ŠÅrd¿Ææü¯€—ÁÞMé~k/ à½6.X`·/ëÏ)N+¼O3³óŒñ\Ù}\ÍôÎS±Sï‹?/Ö»÷úûâ"W›LݵÌßw‹¬<¶¨<Ð (G]Ž¿5“~GšöOªgÅG5êu%€jߤ©ôÿÒ�QKP)½ßZ^ ¾®ü9ùö¶{µÏj\Rõ]4ž4#_Il#ø~ú¾ÕNDܦˆHŠÈ™��mâÁÞýx¸H^)ö‚ǬëÖ à{}×nâA�¨àš&dç¿¥¬h ²ŽIqœg•×Aݺ¿U€?Ç•MÚI�¤aû8c­1ì/¯P^Ÿë®ÉóeíýCí©êE€~™EŸŠ×ùè(F® ¶ÏK ¨Ûâ5Š6UíUùýý–V3ü7¿…Ó½õÆ1±|öâ¸âÏ,›K©Uuâ´¬À˜ô|G¥”bL¡4æ¥îô&ÿÀëƒà}eçÿË|mÍ‚ßkëÒ*õ&[ïU;Å÷)¢(_ÌÆNI1•¦é×ësG§¿ž¯ÝyQ7h»$ÀÜnj\r}­Cq�Cþ+“Z%ò[c¸Ln̬O—Ÿ;³ñç’ Ò)­c¢Ú^|×*Ïã)A`uß« sBBšïAhS}¢>¼º·¦² Cqÿ<ßw/“Ul]m`Êcxçx#�cLIãT`uõÑ»³÷ àá!xiú3Ôíâ€ÿ]ÏÑjË:§ØéC®0F(¥<ó?¥)V¡Á毂ÌÅ£Hs„�<�–šov§X* y}Öi¿J °jY…îøæRû½@yÝÑfyúr†ÿ™rõ‹´mcIx(ø�¶ Ó±§¬ñXEÒ@u.Ù””±šÇ,ZIeßòq–ÕÖª2a«sÍÿÒ1%Ři”"|*p¡ÑÆîJ $€‡�॰÷¨ëo³zŸ~€©Uн~t(¶-ˤ) å€ìü7ÏožÎ÷Ç"Ue›Ï]ìçOuù„Ö‰çmiçºZ�GQõ+5Ú‰ÍyR}l¯ÍîyŠís€}5.óz &y4 ´‚ÿçú’¦$…4*b^n  ²7–m¨ïŸ•í– V$¬«+Ħ¯é4‚aïÔe"B‘ògÇàõBð~³wSºßv–°Î1º`ûÞ>ëv-_‚iŽOUÒŠ”:íõfØ×ÁózíúÆ,}ë=ÒÁ|ëíß»Ü: `8uÏLûô¹ß—XÖKЪÄÿê»ü>ê z4Î[ö½5s?:w׊ŸašÎ•bÝFs¹5Æ;ªß´u®·5Õ5ã’RÄ�™…›‡¹�jD™p&Ñ!H ¯€W†½øqeeû^ÐßëóT³úÕ*;}zXBù¡©€BÉRrmþ¾>Ǫé2ðìE·Ø×Zɹÿvnÿ|Žíã�7ï�ïß“8ìßKˆöñ«ÀwU]`•TѪ”k¯›ç„÷º›.y§Û~J*°ê\Vž«N¨aÊë‹�¾·º0Ï`/Kìï áÙ{0ç[%øÇ"ÈÛÇ0kõ¹îW#‘`ø/"ãQž¿w9þùº¢l#´]>ÀÝ«d‚8]ç¦oÕkR5F©qïB’Ý„¤H‘bªŽ`SðÓüæ¼­>èúúJ××צ4Žº¾ºÖàéÍmûC‘À07êËŒoÓ ó¥ö«²ÿ»IylRÙfèò%Z‰uÂ@*ÚœÛo‰õéåò|L÷ŽU¹d¿ø˜êiwŒLR¸Icg¿(–Wð!�Qk¬]ÒQ¾ŽÁk]Â¥·c_.á`åÒsE€y<Ê{«!LòwWR “Él�ƒ†4¬MöÆà5Bð2õjrÙ%êÎì|�« P|®è^­ _õÃeƒ®®ºÊ�ÿëëk=º¾ÖÕÕ Åõ£«�n}ÕN½Œ€Ò8æö1=šX´_úç§*>䦼X2Þó,þz)�rÖäó¤UŸÊ4Æ´ H÷–,(ûXÌ®_öK—Ý7—46î‹Oc7 ÿи&ç,û4LçNÅ8,—”K÷Ïk7„Ëd ™dƒ¤qÛžY>¶x]ø9a#üô[1UËPÌ ~ºßó>aÕ¸¿ãœìpLWï\®"¥‘BÇÃQÇ«ƒ"B)•cÜ[.àõBð¾ë”Û·Ö~ÖßÿâsXç\åRçúwÚv8 ºººÒõáZW‡+]]]éêêZ×WW1&éúê‘LcqHÙ¾ËäS˜v�”r`Þ§²åsM¡á9à½ÈOAki<®ú:ž5Nï“WÛ_d,O×1Ì‹}"Šå Šàt”Áé²oõòªö+'ª% Ær×”øó÷ž“$¼Ñ÷by‚ù7°ôÙOíûœüZÏÌ·Îï)N×¹ìçEÂÅ\­aÐ6Q¥-E¦-×7WWW1¦1B¡ÛñV‡ñjJÓN¼ŸDðzr†x?íÍÈß)áQÓ­DÛíƒ�M.ØÎx73¹¹Ü=—í”ä’ üJÃáZæöÍK{«&bš0.1r/¾]ö’OT÷ÛN÷@*Ö(È×Åom³A©ºÏ§ßÏ)á¡j»œÕoÒ1O†«AW‡+ ÃAæ>ý Õ² é‚1x਼Tvùwe€×.(óoç–èmëͪŸ¶�ã¨ãx«ÛqÔíxÔíí­Ž··º‘éæfÔíMžÂ]¯ënQÄ…‹ÙâV�cxžg¸Ï³Èóë`ïé;¥8UÌ_õ¿\7­ài½ï&@-­fý·föoÚ/בòy½˜/ù\ÂßóµG,ÇÄrÞ”Gâ8=Ö¥˜ÆÑªàû*hŸ¤4JvÔiª}Ò& rÿü¨y9ƒ£–Ä�§¾­®9¦åR:�e%»*ÆkžµŸùº"B6–·dÚ/RèÙíð<"�~‘4ŽGÝÞ;K¨q^$¯ ÛÙÞ Ü—ËµïúË6üÂó[s÷gÏžép8èé“'zçí'zã�·eæº:\ëæö¨wÞ~[²x,)Œ}šÍã))a üOAZK¡) ’Æ¿NÓû˜ßç2óówK€¾¬{Þ9='¤2(~8µ§”×¢·u~~TŠ4õ3•eð˶F)<_ËÜ�2¨§ëHéTW2“ÆXOÅ~1NeùÓ¨°$Óˆ¥t”tÌ×§ ºÝ*d²Èã›Æi�ž9Y`¼•|�4*b”Æ£¤Û|Þ<6ꔼqœ¾KÇÜæ| Ãi"ßߘ¯á(�¡ð[™S›q”â8�sÙ/-?‡©ßÓ}µÜç§7º}öô™BŠ›Û=yöLOŸ>Óó›ç:Gþɨ�¼,K`½5ÓÿœÞ¬ýF€wŽ·j úÕù­ÑÝiû“§Oeîúú;oë�¯}M‡«+�cèêp¥çÏnô•¯|Å,Þ|4Eus�8�9F_´s9z× ž‚ÒJs0~œÜVξ¯þ1â‹ïs¢AÊÁx·<+=–d×�ƒûEõ)Ôçmee¯‚îåߨ%© lʨKã§rö|H:žb ªGØŸí1Hc¾Wi¬‚ì¹RÀpÌ]$Ýjš+;ìËùn’1·•¤¸]øÝ%ÝHéJi•p<íÇSRǘ$—R:*Òqj/ÝN}Wä¤�ÛéÜã­"n§¤‡9ñ \ÂcY òØþæ×Æ›¯½ý5IfÏonõö;ïèí·ßÖ³gÏ4ŽÇÓ=_½Öï^$ï+»póºìþþñ—,#P´e�c½—°nÿ�wžH&=zû‘=~$ ®Û›[ ‡+»y~ã7Ͼ~åþƧRõ‡iFyÊ�þy™ù¹,}Hò<ÞRÔ¯JÙ§$ s¢@Ù­yÿœh`§YôòÓös¥þ4Ãs�UkÉ+i½ŽÀ©äþR6?Êòù:Í®·œ 0—ÌWП;=—ÇO§}Œ¹Ÿc•Ôp;ìçë×ñ¼O£’BÃt ãq¥„Ÿ‚õ)FÉBž’Nµö=ôo¦ ý8ïMÒ•4äÊ –Æ›ü:ã’J6ÊË1I¹ª@:ʆ�bP„Ë’¯æD†1Wr“Æù~ÌUL�‡¯|ø+_ý�Kf··7zç�'zç�wôìÙs�c¯Áðú"x)¶3öMö.š³Ý¶[ßY3! ä�c§ rÓ£ÇOôÆ“·5 ƒÒ˜lðÁožß?þ÷Ÿf²KÓLöÜG¿Òjf|ÌAoåõé‹ uä÷‘Ïmi©pêrœÚž?§qšÉ>ÒÍOßÍRLAîùÇÃO§‹²¼ûÜH±Iy&è]]FÚ~¿ÌÄÏ –öëñ‹" e®ËÏ×KÌmÌ�ù”KúûÔOåRI‘û1æøqêWšû{\ú�–ëš—,OýHs©þñ´$ÂR™`¾Ôq©@�bJTH2ù¼d‚[U• ÷/%…Bæ±$dIJÃi_%;%ÌË(IiJrˆ9Q"¢îù70݃�|ó³ïyöìÙ0%Üø³gÏÇçÏŸëöö6't�ðz"x%ØÎö:èŸy¹×^ ßÚíž¿¿TA¤¤4†Æ”4ŽIi5Ž£…iÇñú;>~ýûNåÿçzÿ©:,_Û*K ì_ô·òsï¬:¶jcu]Q4WñcEp}µ,Á¼{h)ë¿ä‹JQ~öé5µúZ]gäó™i ®WÉóìù%±"NAûUÒC>YŠSS‘”PW4ÐXŒ[×�Šk˜>§8ÝÓ2¨¿,ç�ê6rÂ@Qq!B²ò\Ù[oŒ?6ŽÇƒÉãqÆqL)E¤””V• õÿÿ¼/ÿ%^´í’eê™ú;3û›ç±ªB@=óÝ6ýôr?3™MK˜›lp ƒ·ë¿ñ³o}êC¼þ›O3Ów®a(ÏÕº¯>[gœ¼ÿxcÃæXß­„pÇG$O/pó· bS] V/Šyì«e ,NÝv+Ê‚¨Æ0ŠÓwÎ{IµˆÕ®ùÛßÙÜ·ò€({ÖýÝàÍô7^†k·áÊÝf6ØDfe›Ñ¸€× ÀËf­ ½rü{÷ö·Î.e ¿—°msðAî&w×0 :WWW‡G‡«Ãã¿íoüèqÙÕéX_¿ºçÀѯ^­Øß­ìÂAôê}döb™�fB§�Ö~)íô©µÄB9&ëŠs%›«&¬š°œàRª’#’cX]“ižbŸO=ï[öe:Ö[ÁøÐzüÂrÿ¬¸2Ë…¬8½�^«ßôªêƒÍíùtŽâ·wuˆOüÝ¿ë‹?q8 �Ãp}†Ãàn¡1æÿÀë�à}· $›ì]4g»mŸ>[q6kïÖ}T8? &7“›ûa®ÃÕã¿ë÷|ô³ùÐÕONA\¯’ªÏ6¿=¿/ýæEª µŠàó|Ý›$oŒ�k€Ô®2P�a±lÁòj«s%5’ÊuèçÀö2Ñï9`ž“Õ V}2Ÿ¬¾æzf½k“ˆQÞ/öqW’I>h•”‘/Û,Ÿ×­XMa.Û_ÞÏò/·áUUŠü±ùº­]à¿óéßëÃpí‡Ã•ƒ‡Á†a˜ú2 ~ÉàõCðÊٙ德DÀ·¶3í´ÎÓ«8КŸñf3{lfßô=ß~ý±ÿ¡7þiI.«Ü9Ðîe�zèôÇŠcZ�.UPÙ|{üjf»´_I¡Qú¿9ÆéÌcÕ…�V©”ŽªŒý²KQºß´ÚgTh�ˆÐ(å_–ã_Êô×Ëäe¬w‰ù^Zµ„@ûâŠ>VÉEùÿ¥ €$‹è´wÚöá7�ðoú¡/~ÚÌ™ÙU^ /€’E0+x¿<ùB§ õi¶óiF~£l¾5fÑÇ› ZÍö.g}/û Ó_žanó,íy_¯>[´7ùj¦þ<Ã>Ç`’ÿ_döw®Ž­g‚{>~9‡Ë4äØùpÚ߬ø\ÌF×t¼•–þZϯÆd^~@’—}Ø$ Û`÷¤žƒçeÐ:I‘r€ÈþX¶OÇ�§cÒÜNÊÛ%ERhóçÔšu_&7ì]cTŸvú£Öùµ^ár¯¤ßçÎAÙðš#x™¬µ¡WŽïàÞþÖØTúÏ$¬úµñOIúÇ.ë³U›|½tý^ß»c°ó˜³™å_^ß%�Gw &§¸à˜^@=.Ü^7Õ.½%bç-gö�ª�Ñjó®�ùèôa^4@ÿIßÚ>× Ü/€ˆà}µ n›ÞÅZæÍÙð{ÁûFBÀE}Ý´9Hö¿’Û?¹í�mú¾Sy ™¤°÷ÈR{Ác�Û…êý;eå#rùÿj߈ê¸KÄþë*èžÎþÏ%#ÔßOŸSãúV ê$‡8—X�ë»crÀtþOJú?Iz¼¹-ݱx½�Ü ¶¿DÀjv¹¡µk+oÕcB+è¿lÿ°¤SÒ9õ­÷ˆá�ŽZçÑÄvŽ™¶[¹�YgŒlçúÏ,Ð㙽~á¾Á’«}{ Õ¾íÓŸ ¬÷ˆÝãW}Ow7IŠß-éß�âš¶HÞw—–î·v9~ïµ±×–_З�ϧÍ?(éOÉôŸ;uæÜrÖèÙ@ü¼Í÷ö™ÇÃt¾œ�½ØwÑ›Á~N9s>ÿ¥ò¸ÔxÅæÐ¶êÀvÆþösª¶¥~÷š×Ñ›�I¹ýÆ ÿU…€Î¬ÿrŒ6Ë4ÇúIú?Jñhÿ~¼~H^ {ÁcÖ�sëì›�ó�Yÿu¢�Ï/«öÿ>™ý)ɾÿ|âÀÎ5Ú©÷íez¯ê,ypéÃÏ%Ë \ª³$ÀY± RGïøMü;�Û¡ýõês�„0‘:¤ÝFã.eü—î¾gúŸ”ôïkZàïÀÃs`€÷Qwü^éúsÛöfþ¯ß¦¯ýô©žgå›É–’ú~ú3SÒ Ã[?ñaÉþyI_û¢ÎUÈÛ¬3v¦ïÝ1ØàåZªãºË(ÔÉw &§Kö¿$ˆŸvúUqÚ%uÊþofÔKí%êþìÌø�jߨée§±=×_'ÅOIú{Çÿ€\¨¼V¼»ÃÌùÍnwY ×î^ðÞtxë³PÒŸÓ*øß ðÏËTÛ½Sy ^Ê`s —ÌØ¿à‘ÆíŽ�Aõþ½2ú�YóËöt‡ßDì¿_ÝSoõ#.<×iÿTo�ª�:É Î%ô¶ßeY…èW ˜†÷ã’þ=ÙðÏÊü›ù·¼îHîÛI °zŸKËó[÷{ÿÈO|Âßúíÿš¤?!Ù§N³éËeZÿ½Ç�Kfß÷�±îRå6Û9�½Àï—¹OÍòù{Zôsñ½%öËôŸ¶õª4¾Ú4gƤZ!µû²ê{’^¼d´~@ÿ¨¤Ÿ—ì’ô)þÁ¯+€÷Õ¥¥û­Ðö^,Ðü¼þÎ?üY÷ö–ô%û»÷›ðÆã…5úWÎÔ· úoUóõLÿ⽟ úŸ»;ÇÅ]fª÷ŽÏ©Wæ?5Þ^’pÉç:’ŸŠ¦.Iˆ;\û%3ÿµ³Ok¹‚s‰›ñþ„¤^Ò/Kú�%ýMü{^7†x¿Ù ³’[/2ïõy\{åÿ-'Øßñuüú?#?ü�ÒtL2ÏÇ{ÞÝ%ÏŸÓ¼}ȯ.—K~ú<í'IÔÐ`ƒ¤A6·S;óù¸AŠùBÊö†é¸Èí%?}ï®édsŸÓtL¦¯4æ}Ë}÷$æàù<» N'�Zëi.÷Ÿ·Å¸i”t”"­¿Kãô>BÒ¨ˆqêSJyÿâ¸e[’bn+Ié8UˆêûT¼×||>oä~æ¾Ný›·ßNûE(–ë-¯/Ÿ7Êå BÅØ¬ò ö–˜•K¼`õ„ó~BÒ é_”ôßʃðà‘¼ «XþÞ,ösÛ.˜ùoõy´š�o�>îŠçÿ÷xúù¿5æÙöfš‚ös`Þe6œ‚ú6œ4LŸmPZŽŠàþAòA>§Aaò}9�ò1‡é8?µk:(<ï®%Q`>^ƒ,†¢oéo ¥4LëÊý�Nå¡*ÿ?'̳ÑÇÓëX�ò5NÁý%)`Ä�Eð}”â¨X÷Çió÷åþÇé|qÚ7­Ú=žú‘¦¾Äªeç ~ŸæÄ†"`Nzˆ)¢¿ùS™q×%^ºÿ¦¤ï—ôûEx °ð¾ê¬ißøþîmî•ûß9Wzògâö+ë‹õ㔼`­$ë- P%(ÔI>—ýÏÛê¥L«ý—±4ÛŽ‰•mª öï�Q]޾øNeÉý¢ôþ²Î}ª^U”á/þ¢:wê•ö�Æ~Úo{þ"ΔÑ_¾y�%^]¿GÒ¿þ‚ÿÇp¯�¼êÌúÛ¬Þ§Ÿ`«D�8¿úÈÿ9n¿öc­ý×ÁûÖöV¿´ýΫG�M»�¾/my£íb{ä_mo=]ò—}× ¦G8ß›-U ¾>¦æGÕVRÕvT%õË6Z e_/I xÉ?)éáðБ¼{¥ûm'Èn�ctÁöj¯GûÏÄñ«?¹Ù·5kÕŸº¾Þæ� }kY‚r¿M€¿Þϵ 𗟽8¿3ý_lœ$))3íKÅŒÿÕ¶Fð=N­-¯u›Ñšõ¯í¶ˆÍ÷Ñœõ¯N€¿õzî¼÷ÞÿLÓr ÀûÊ^ü8/?u‚Ù^ŸÇÕ-ÿ?>ÿ_Z„5+ 4gæ·fî[¤Ÿß®ƒïÞ:Ö­ß7u–°öx´ƒù½„�Þ}ˆíl{©  «¤?í›à{Õþ²,@ùEcÖ¿ÊýÊj͆Ï{¡8~/éàÞº’ôÇø7WÞ¿´.õ¿I(÷Û, Õ¾©žÝÕŒÿ:@_%Äj i;û¿h#:—ÿ+üm’~œxÀCEð~³Þ ~{±ÆV¯Õvëí¿Gq¶íèý8øM{³ù×ûž] ÀËrÿs²A}L}n�üâuÞÖ] wÍ�þ-©¸Oå窜~”mÖ³þó‡Ô*Éߨ–ε]|¡KJûÇÃ,ÿ_úGøGUˤí÷«ãçÿ)ÿZûh½=ig¿²�^CU= â̵?èd€·ù—ü/ôûhíYû›@}Uj¿hÇ[Éõ~›¤Û‰Í[uiÖiw¯¢A£ä´fá÷‚ôÚì›à}Õþ²,@™8PÎØ×ö˜M0¾µÁ™@}Üù mâÁ%üŒ¤þ- ÀË`—,pAYþ%øÞ9Þ�o;õ!n¾üÙõ[ÿÏMÛË„}[—à÷ÖuÔU ¬}¾Vå€�ÄÛ$\:fÞyܹËãOê|®’ºbUê?šÁûÓ÷§÷Û¤€TÏî�jÆ Oëvcµ„€Ô®RP%!¤V?Œ�€ÀCEðÒÔëÚ—ÛuÁ¶ú»Vнþ°m'n¾òìÑGÿ§²ëñîW`gúÛ ôw—p­“ êc¬8ó|­�ñ³ÖÒ eC^U7XFCûåò³ÔÙo ¾§í�DÙ~gÖº°$ª¶oÚî-%ÐäÇëQþÿk’þEþí ÀûÈ.šÅÞ;¸Èß¾ÛE ¦xþ¥ÿŽ=úÈGìú£ÿŒ†GO7ûu—PµM;ùêø:ïå÷^t¡>_+pïí±p“_ôØ;Û{Ëä@ÿjù€´ý~u|Ùf9Ý>])ª¤êój¿Få€Mß«êg®ýÁ&üI¿Î¿Dà¡"xizÁ{ëûóû¢„óû‹ÎSm7S<ûõ¯Åí—ÿÛvøà§e×ÏVý©ûWÜ[³ù½ÞW�$¯Ž³Î>V=”3ø]ÛD…º?ºÃ˜œ$¥b¦}©5ÿ¶Ï�öSkˇTßãܬýys4ÎU�ou|ù½Ô®hpÉ~Â(é—ô¯òïxÈH^ºVÐû_ì¶è· þ3ßíl÷‰ç_ü¼"ýÓýYÿVýUÌÞ¯ûSõÙÏ-`�Ø|ô{ç~ÉØtJþGk¦~+øÞÈÇ&ø^µ¿, P&ôfóKíeÚ‰ñBÁú¸ð»ØŽÃýôïHúë%ýÏù·gÊü[Ðo´g²ku¼k¿ [Ú½•(°š±oÝë²MBÀ¥cVT¸ÓcO꼯]SŽUyþèΨ¯ƒ÷{%þ{¢qQt#:—Ôh#—÷²À3Iÿ ÿЀ× Àû®5C^Ú ô7¿oTX-Pl÷^À½ëß•_ýÌùë8××êZ7³þ½x4)“ êk:µ·T1°Æù­•ìP6äíj ÝÙôs`>UûVû¥ú¸^ÉýN@=mKò§zÿViÿhµÝº–þ¹ãÎU^i_’tÿ1àuEðª³^`]Õö�„€m£�ýW¯1|ó~ή?ªV0ßZÁ~kT.°Fþ:H¿*áïE“½¥êGšÆEºÉ/z܉�í;ËlÊù«ú\loÍæ�rßz¿j{ù9ÕIõ¾õìþjÿ¸´Ìÿ½Mø¤¤?%éGø‡¼ŽH^¶¿DÀjv¹¡µë^ð¼Lh•ð—†}ö�Ê®þ€¿ñÝ>ø#²7>%»zK²GZÏæ/�ójIot³,Õ¿Wêß;ÇÌ}öÆuèì¸\R!í.Pö;AúÕ2©ú<+ôQm«OW÷»±ù^€ÿ\àÿ|•€{æ3š’þAݱìÀ}w`€÷[kF|=+^ê—ÔïµågÎw¾O‡ýÄcÉþ’þÁå0¿–û·J×ó9BŸKqTŠ)F­gÂ7’ê%6KXµ­¼&+.Í×ß»í\�uú#uËõ×3ý£QN?ï«Òûu`>ŠeòLýÔ˜±_Ó,ç¯Mߣ¹ï9—$<oJúã’þ ’þ’þ*ÿî€× À+e<·^Ðß«ÏÍ÷Õ,y«fÞÇÞúí?$é_“Ù�´ƒæó üƒt¸–Ìs™ýüçspþ˜ƒÝ£,B±Ì¨7M�æVÛåµöªì�™«�±Sô,æ€üloæÿ%ò¨>õ‚óõöj�Ö’õçV¥€"© æ÷©wîÆùR±!^F5€N2Ìê>§ª"ÂY@Ò_�ôOHú—ÎÜd€{�à}Õ~ïoÛ›ù_oªÎá{AUéðÖo¿–üŸ”ì¿/éQ¿ßç®Ã$󩉃çÇ “ù¼}�ä¹C>f[5ÀÌóÖ"© —ý·¥ oœ»êÏfY/Æf¯ þļýýªàû6À¿7S?r²Ä:П6AúÆìýhµÝªÐ9wÄ)QàEƒýV.çà�ßÚt_¬ù›�|?bÝŸ¨–UHï²�Ò‡$ý‹’þk’þ!Iš‡ÀCEðR\¸4¹Ýe€ê½í�{úÒßúìïÎ%ÿ¤·Ïj›ÕåúóvïTðNŸlþrÈû•l˜{'Yø{Y`Ð)ÙÀU.10�.ÿÿgïߣìÙ¶»>ì;gUíWwÿÞçÜ÷•tõÂÁE—X Ü8À°†Ø†x0‚†ñ`„€c @â †Çx$1c$ø;±ÅS2Oacˆ0$"�€+p_ººï{î9ç÷ìîýªª5óÇz¯ªÚ½ûw^¿Ö™Ÿq~§{×®ZkÕªªµ»û;çw‚‡ç!�HaX¡9 JHÆmŒ3-`[ê€kÀtnÿÞíÛ»}»üYÃu¶Áª²Çô]înÀ^7€é©]Û=@= �GT}(¹@nì`ãâŒý‡ÁmAÜ>Ƹ€ ÿš@i†7§ÆÎ ùs'§½»9ócö� ¾}ç âûöeLâ¶�º $ådBÜŸÌ×®`€ïð÷ügþOtREQEQEQåç (Š¢(Š¢(/ t (€Ê}¦ƒh¤Œ@<Àw>ö-`þOüú¸}D0ç1Á?…'Ç1½_1öóA„iÀŠøc¥ÆÚ¤DÜŽ›‚@Íã_{Á›­ mÅó>´Å øðï[1ÞfÙwÅ>…z/Ž»×b^;áb|$â~ö¾ß?C²ÍícBV}y¬@0Ùk }x±¾Ç¸k�E¦œ®Í[V~ ðoø ~€?‰·¿Ö�¢(Š¢(Š¢(Š¢(Ê[ë(Š¢(Š¢(ÊÛI*ÄÓ¸ ]fÍ_™ùOGôçš¾ý]wøÎÇþ/þ)€_ÞŸŒ'à‘_!¦ ¸x}hœT4_ŠöÉ÷|•èÌ\O0f­=8ÿËò#ߌô!ÛŽy]¦È›¤©‰’û>tîSûÈ�s*ú•±’˜8N®¸^oˆ÷ø~ÿ=€Ÿ¯ë’¢(Š¢(Š¢(Š¢(?WÐEQEQEya ç4¥Ìsñ:óåvÿ’jØúçŸð{Á˜��€ƒ˜î£ØL#Îù÷#ï]ÝþD§<úëÍó¶ç‘Û'öD¤–ƒ‚¶I6™#û7㛽àoÆÞ0˜}Écw¯ý¹=ÿ­íß’Dý_à§ü1t REQEQEQ妣Š¢(Š¢(Šò¶BϱíˆÌÿ¬D@Z‡žÀoðÓý1=H�c“]?ÖÿÈ6šøUƒÆŽ£çœ?NΓ1èpä¯>W‰É…8nŽŸ§õg€Ñæ¤p�¢ÿ^&¶OfÿãŠ÷Ê·�x.a^F¶<¯3Á&ŽÁDpŒ¢(Š¢(Š¢(Š¢(Ê @EQEQåm‡ÞÀ1t ­, €üÏü@À·מß6&ðOlç ·žh´¼ÀÔxŽø•…¯{L¹ÿDö½Ld͇íæ9¯*jôe»£VþS¢ÿ¡þ¦ØåP�� ³ûcŸêÿŠƒò†¥Ž N¸ªÿC®Í¨}þ‘íɱíq›Œàà‡#Âz~RÅáW‰ù&ßnÆÇ"SãxC×äá[üyÀÏ×ÅIQEQEQEQ”›„(Š¢(Š¢(ÊÛŽÖ§ì÷Dzú�(|/€ðC~ñpŸ‰Lý²ÝI�ŸGŽ;æõÄ9ñÔ¯&É÷LÅ|]gŽ‹~ÿ¼VóNä6S©ëIÁ¨p> Åñcï—JþDy®xãˆs¿*ó¿Ÿ™£à8ðœ.ò¶üj?à?ð>]·EQEQEQE¹ h€¢(Š¢(Š¢¼0Pö:M‰þ\¼ÿ+ý€¿à»Â~)|O%áOYüOfâO7JS¥ hÿð¼ñè¯6W´w¥ ,¶OdØ'Ûä  m&¾Ç‘Ç”»•Ai�ÀUÁÃÃc—ü\Æ ¼Y¢ý;æ Pø�> àXê:¥(Š¢(Š¢(Š¢(Ê‹Œ(Š¢(Š¢(Ê;ÊUÙù“™ÿà×øIÿ-€ïè\¼.Ç8Œ�÷Àþ™Íê&pU@À5~}¡‰’DGþÚs•˜\íæñyLhŸhw4^ ‡)ú—¢é4£¾<·©2Gœ»L½8"óÿh±_F¶[.áãÀÿÀ'üý]ZQEQEQEQ”ý£…¢(Š¢(Š¢¼­Ð8&¨ë¿ÀOô|ÌnNö¡Cý .(ßO^O¹ø *Ú㩾Ç~™Ï¿®0½ÁùŸÊª¼M²ÝÙß1ÂùÄxdêøëZ÷�ì/¥e¿Œ¿/WŒ}ðZŽ˜ƒd\21æØù|Ûù0€ÿ6ðæ—ëz¦(Š¢(Š¢(Š¢(Ê‹†(Š¢(Š¢(Ê‹¥Â:kEþ[ü3Àw–;Е™ü#Yó˜È¦g/ü_Ñäà� ŸŸ��×” çøç°pmŽùGÚ�c2Ú%û>dÁË1ã�Ú6^žÀøýL±¯Œ•80?f¼_=öyÄz¹)Oè/ð7üy?_,EQEQEQEQ^4@QEQEQÞVÊŒúÒšðý ß¢ÏøÿôíWgð�½ž*1PìK‡~u ‘ׇÚ-ûNÚàrûȯ(LãóuÔçL‡Ž“ç|ϽoŽ8ÞjoJt÷e®Öƒòƒæ®r ˜:‡´´ÁnY)ƒd[(Wðœ.òÂüz?à�x ë›¢(Š¢(Š¢(Š¢(ï4 (Š¢(Š¢(/”ýtN Ûþ€ÏøøÆü'ø©Œ÷+Rí'wŸr 8TB`¼QÂT@ÃÄyú§ëÍÛóì#×âË}RA»lÓ¸½Q~ÐVºÝL÷1zLñú`™sÄöa€�!W¹`|Žž‹Þ ð¿ð¿ÀR×3EQEQEQEQÞ)4@QEQEQÞq2ñûe€þ#_t__Ùgx|) s*¬Ó@àgŒeÔ_•a?�~ËɘÊ}¦¾^ãW¢Á¯1  `˜ �¸JL.DssŒølpuð@‘¡/Sc*DsS¼ö‚À`Óîrܹ�ŽiªÍâ€7�¡/�Ãmßîø#> àûpý:Š¢(Š¢(Š¢(Š¢(o PEQEQ”wŒLüFØLÿÏÃfþßî3ò=¥ÛK ÿc²÷�ØŸ®(5@Åk>Ô6¹�¯ž;¦72ßϾLj˜í²æÃvsdÇçi“¦Ø~ŒmÿUÙú#ÇHiÙ/ãïËc¼–#ç`Ì=áØ9¼|ÀŸðwüR]çEQEQEQEy;ÑEQEQEygù¾Ö>üwXÁý ˜Ÿo£C™ù£?úû`€‘íì…ÿbû ÉC}&m4þ%èª …·â×›¡ÈlŽùGÚ�Cíc™õrh(Æ:!® ÆïgŠ}å€óÀØ÷æÐ µ5u*Áæøëô‚óKaƒþ+ïÓ¥NQEQEQEQ”· PEQEQ”·iŸ@ÚÇè»úK úÇ~3€z2۟Ʋä¯ÈÊŸ|MÓÛéЯ 4òšŠvq`L|Äö‰ ¢#ûFF Ž“åê÷�\}ü¹ Dó±²SvüæŠáã$0F:†i7I÷1#ƒ�©±�õ?²�ÈM~ä ÀÿÀ§üÁõ�~t¦« ¢(Š¢(Š¢(Š¢(o%$7û�)Š¢(Š¢(Šr£XÿØÇ¾•ªÙ¿ Ôÿ2@Äí,ó�ý6!®z»™€—q?Î÷'÷:dï3€j¢y|ßïàôªÃv Z€xf�©Àé±\¹6Ü?ªì{Dê¤]÷ÚŽÁ�ÉퟶG€ Äi›~_7&Tv\TóÄn¼F�TE€¤½¸í³æ{÷é]Ö¼øûdĸí&ŠÛÒ!¨ß¦‡À¸ãŒÓ´ €ÎÆØ‡±ˆïGŒ;Æ}5&ö¶»ãü>èíxÂ{&›�ñÇ“ŒUŠ>ük�”cðÿŒóàÆžµ…¬­lŽÂ?ƒÔ�@ÂIÞÒ¶Òm7šÏø]«�â¯ëj¨(Š¢(Š¢(Š¢(Ê[�(Š¢(Š¢(ÊÛÄúG?J~ÀÇÞæû‹+ŠSØî„úT˜g¨Ѿr•ç©¡¶â:×. ¸v‚|ÜÏ׸`�Ɖùuv±;îý¤?¢Æõ[Å J 8ö‚#á_¼ˆï…çÞŠâ&̽€oz'p÷éìû¦Köéi!¦·¯¥·ÇÀ}�Ö~œ?¶u}Úãm�}Oü±âÚ1ÉxÄ@Ä�•±µï%¿¼Û½¨2wn"Ü#î=®övòFö�¼€©M¶»ˆ�Á1~Òó>ìWŽÇ Ïޗ̺ OÚt7H>¢‰“ñÍ’~MBº}QóVðŸøÝ«�b«+£¢(Š¢(Š¢(Š¢(o&µN�¢(Š¢(Š¢¼müf¼íâÉTYÿ2Zè“ßžYðSxwx|Y&Àoc·Û°�(Ø#ý®:­Cû]'èy,kȳ×Ë6S'I2þý>fd,Å1å6÷2+ Ð÷‹èàݼð'€,ÿšôÝ‘ûéÃü¬ìÝ÷ÿ€cý£ý3«�âwêÔ(Š¢(Š¢(Š¢(ŠòfÁ:Š¢(Š¢(ŠòÖ³þÑ�ÖþÃw¤s éìô”bþà·„òxŠ_˜ a¤½¸s1 ß—�SöMtàךMYðóDC6SŸA…�?0`ÿÑ ° d¥Ø¿Ï,ÿ‹íRŠî€µä·ï$õçã¶CÙ÷Fpµxï¶vÿ3p@¾Ÿ �äœ5 àñ­:Š¢(Š¢(Š¢(Š¢¼Yh€¢(Š¢(Š¢¼Å¬ô£·aÞ!(ùéÿXa…–î¶ ·€qQD±DÀUý—ÿC™ÿ#%² �±À„á^F2ÿeÌb?)�eû§ï™¢ù#$–�ÉÒå0e´íC¹a¼_§@QEQEQEQ”7 PEQEQ”·žÿ1€úÅV‘áOQX§Ai€¸/*�ýšá³õÇÛ“9Œ¹L�Æ¡ý®#ˆ;Q_Ê üÒ¾,{ß ûƒ@€1·�â˜ò= �©²*øÿ`©S (Š¢(Š¢(Š¢(Ê›…(Š¢(Š¢(Ê[Ï/yg»Ïwòúƒ÷hä7„RˆOܘFJL9p¡çsÜ>ê:0‘ùÆÍÓçISÁIVÿUY÷s @’�Lfùï Wô'É—‘qÈX)€‰ 36n冰Ð)PEQEQEQåÍBEQEQå­çïL·¥ÐOÃ÷�Á¼õyb{züÑ娠û‘ï“ sÂ⟠œ¹ LýŠ3!òK’Õoâ>ÁV?³Þ÷ŽŒö‡ìþ3p(�+0˜0rj*úßtžé(Š¢(Š¢(Š¢(Šòf¡Š¢(Š¢(ŠòÖsÿ… ]gÇñ~´!›©Ï ÂƘ°ÿ†å¢ ¥ûs"ðOZþÛ¥ÝãÄ~`�å/¥�n0™}/p팉÷n3±û/Ž ßoôøblrdà€ò"ñT§@QEQEQEQ”7 PEQEQ”·ž{ï\×iÿ”0ŸîK#»ßŽÂ-`\ÔQ,pU @pùŸ 0à«û=nD¸—1[ÿ1‹ý¤T@x»Ìâ7EóGH, “öþå0ÇÊHt*À¡ÀåðD§@QEQEQEQ”7 PEQEQ”·žÇ/Þ� 1=)@±?î;ÌØ†n~O¶3}L26:®€èMš'îK™�ŸÚôãÖÿNØ”–ÿÅ1Ù{y;Yp€L•P~Žðy�EQEQEQEQÞ,4@QEQEQÞz¾öÎu� îTˆýñ+�üv� öÉþ>»Ÿ¦Dý‘ÒTþBÉWJ¡â½¤o¢¿ÆŒŒ³´øÇ˜¸ÀN?=.$ÿ_‘åo¼k€\Ñ_402™ ƒ·rƒø¤N�¢(Š¢(Š¢(Š¢(o (Š¢(Š¢(o=ÿìíï²úÇlýQXú§ûRñÃT0]Q^ `*š*Û,~E¡ ‹&ðà×q˜ù%±ó7qŸ`«ŸYï‹{gJüŸ²ûÌ t@yÌXé€#…|Õû.ðõÕÇ?ñe�EQEQEQEQÞ,4@QEQEQÞzþÎ 1 ºÎŽ#â}ö^ú+�}ÿQ�Så¢ ¥ûs’ù?jù?à ¥è'öƒ,)ÕtƒÑìû ç ÆÅ{`4C_ÆúMŽ1å¶b¿Ñã‹6DËÜ@~L§@QEQEQEQ”7 PEQEQ”·žOøÂÛßmšÅ?%̧ûÒˆÀžZô� ù™€OK\\þ'²üÇÆQö7zܘm~ŠSÛeÌb?)Þ–â=S4d €$%FÇ)#ÃiOJ7‚©óTn]§@QEQEQEQ”7 PEQEQ”·˜ÕÇ?!þ_/Έ 1=)@±ÿŠ7¿�´“~ÏE;i 㶇9rŸ1¿´ï²L}‘‘@€ÃÇÈ�vd2«_3üŽÑøK: Š¢(Š¢(Š¢(Š¢¼™h€¢(Š¢(Š¢¼=üqÛ··Ë\¤§Bì�_iâ7ƒ\øÁL…°?Ò^øž Ÿ“¯©»@z,úŽãNJSNÀÀâcâ~ú½™>.¼}E–¿ÏîÏ &Ž A#¢¾L”ÀÈ FÆ­Ü~xõñO¼¢Ó (Š¢(Š¢(Š¢(Ê›‰(Š¢(Š¢(ÊÛÀêãŸxÀúöôFâ8òmD#ï'Â>—ÛFŽ?X^ `J„~Œ´YüzBÿLàÁ¯2y?i©àßÇm’¾N÷Åp›$%@ÈÈ0GÚ‰N8tžÊ Îïýþôï”Yóupͺ¾Ã~·…1û¶Fo:pÌçs,–KÌê *ž¡k{ f³9ÎNÏpëömtÝóù Ì„““Ü¿wïÝýû÷°Z�À˜^g]QEQEQEQÞh€¢(Š¢(Š¢¼½ü-ÿ>Þ¶rž‰ €¤Ty±ŸF|šrð¤.\´3QB D”„"BàšçW SùH¶}ðb}jßoŠãœ°/¥#@ÙGÞ—ðiØNxOŠq»öŹЛ$øËóMçqhP¾ÿO}éü�Ù|ƒz6CUU Lߣíöh÷-hÏè»LÀl>Ãl>CM ¤#T<ƒ¡ïz4u…Õj‰[·nØËÅUÍ8==Ž{÷pÿÁ}ܽ{‹Åm×êÌ+Š¢(Š¢(Š¢(Ê» PEQEQ”·Ÿ? àÃþ½·®‹\¤§ ¬�î (tÀ¥Ð^%}�<,0Ö‡±ûSiñ÷çÁàx¤|Á„Â�fë÷=¼…¿ø’ž«¸÷ƬýÓŒÿ>iÛŠÞ&”%’ñ™²=ô’œ6�Ì¿ 8\‰×eŠ)Ñlî¤øŠòR�þúšdŸÐ†$Ûèˆ €‘`;ºò°+›?v®Þíü5¿æ�ÿÓçÙé™ !T¨ª Ì*®0zÓ£ë{1Ønjl6[lÖ,[4Õ@… mkе-ú¾…ˆ€ˆÀÌ`®@Äèz`¿ï±ÝîÑ÷‚¶Ý몫(Š¢(Š¢(Š¢(ï4@QEQEQÞ9þ €ŸðÇ̯}ôˆ®Ef/È:q6襉8?È OjÔ§"s*ô;}Þ‹Æl`“»©0[�ˆ-µÈÈ7î«�#`|Ûâ2ãL™Í3ðMø»¸ìûÌ% ´òOhqýhÙoÓŸ¼ß»cɱYÀAz^Åœd×õ@©™ÚžÌœ–{ rn]¿ÆŽÝø18·%¸8λI”Á €�ØÛÈŒ‘ø ÉÏÁ”L¶K¢¤Ý8¯&©àÀÞ½B0ôP\±çoüq™Åsñ¿ö?þ‘ïûìÝ»-Úí]»G»km L fQeGŒÀé"‚}Ÿ‰b´h»=¶»=6›5Ö›-º®µnB¡LÀf³FU50¦ÓWQEQEQEQÞh€¢(Š¢(Š¢¼³üç~ÀŸð�G%^{Ñ´L”—Ä®=ìŸX±Ÿ ’ˆ+WUÑ–L÷!/„§û%°PyÁØ#>š¡®½�!H3Ù})PÅmád};’ð¥;A2I"YûpöÿÒ‡1Ć$(@L.<§Â}°ý—(0ûs %$οÁ™Ü0’  Nƒ/ ñ߈sØ»‹fÒ …¡k@ðC7ì¦/î­‹‚·‰rsfLv�„ð ò®\8¸ó R0Æv3,YP�–˜ðs“–KHîiC ®(;mw½$ί16C>ùÎFœ;„÷šÀ•»ïž/à¯øm¿ÿÏýªWîÝl7ì·[ìö{<{zŽõÅí¾ƒ¡®ÌfsTÌ &Ìš9fÍ M3Çl¾Àb±DÓ, ìÛ]ßc»Ý`½¾ÄÅå%ú¶EU×h÷Ú¶Ãv³Å³ÙÌ ÑÕVQEQEQEQÞh€¢(Š¢(Š¢¼óücßàß�u¸wpïD6p¢£Îш×éA’ˆŸI64�ÜEV:IÐÖíq@Ü{'p“uè©Öƒ&L‰ìé"8-#p¾aÆÐ¢?Ï|lg½‰±iЙDÔwB0z  BAiï_–@ˆôâÇœÚárï%n^èNRñßÛý‡ yV|p?0’»E~`Ö³Ü lƒ Dl¼qíEñß;¤âö5R¸¿0êÞŸ»SPr¸û%4-öºùFª$!¹×¸÷æ îX@Ø>/UÚO2‰ÞµÀ¸ùïÝÍA cLrÜÑ|Àð_ýÖÿû/”—ßc°Ûl°ÛlÐî÷¸\oqqqŽóósl7k#˜Íç6ØÀYú/sÌç+,æsÌš9êf†fV£ïmiŠ®k±Ýn±Ýì°ßï!Æ€ˆ`jƒ¶íìÑY‹t�:(Š¢(Š¢(Š¢(Ê» PEQEQ”ƒÀÿÀð;ü[~ÞäÞ^¤7V6F/Qõ¢&‘ € ^zAx" zÄz�‚3€·¥wïq«F»€/´Â�ƒ&jȧv×–qíJêB�bªcŸcïzäÂý˜½ÿ”½¾ÄCÊAïö¾Ô%ÑÃ}{Ù—Aܼۂ®Ó~CÀ@á*`z˜ÞïK`ÊdmóQ”Nð×Ô:mž@Ä!VÄ.$q/ Dü'Îç+|?VÒ [ùmb³ ü}ÌÖ¡yWþPN¾³]¹Ó'sæîM1Ö9¡µ,â=ï\˜­[€ B(>®Öÿ÷~À÷øÁ_þ{Nw·n�áÎÝÛÍ}×b·ÛáÙ³s\œŸãâr�®mAL¨êËåóù³Ù L" iæhêˆbzôÆ ëztí»ý]×¢7=*"ðl†Åb‰åÒ:pUADжº®×UVQEQEQEQÞh€¢(Š¢(Š¢¼XœÃüßüß àc¾ÝwÄàôlÓŸt­T"‚GOzgïM0ì껃­èOD=ˆÞ>ŸBÍ÷ʉŸ ¦Ê‰½ ãÅX©"0WÖ‚ß½o3À•m�f ®AÕ ˜*®àEVA PeÇAuÈfb@B ¶Õé¹WsÏPU €�Ÿ®mö¼P’‡ï� jûâæÁŠþqO[Ö€œØ-ÒB:›-} cLÆ�+@Î@ÌÒïÑKç¬ð{°†,Æô@¿‡À–¨H@Ì»­ïÐ÷;˜®¤sbGM6ÈA¤‡ô=ŒéñðéÎŽÝg “�ˆ€\Ð��€é!�Ao LÛÉ€˜P×>Äb 0�d©Ž-ˆm¶¹½¬ÖN?­ Æ wÁ VŸ·Â4*q ,‘è]Íz#€ô6À8ßé�ǽ»bU2Ǹ‚upã5FÐîí®G»3è:±ÓC@]3š†QÏÈfè F Æ–>è;qç vúNl'T ¡ª8˜ Øi˜^Ðwvƒðß¼øäÞÓ¼ÚÔÒè=ÍC¦0›[ÏÜ¿/ø€Ÿþ�ÿÉ·_>zøm·Ç|>WŒ¶kqy¹ ¸¼¸ÄãÇ�ñäéc¬×Ëå·oßÁb±ÄK/½„[·n�™°Ûíѵ{0U!ÛŸ»mÛâr}‰Ýv‹Þt¨¸B½\b±\àôôNOOÐÌf`Ú¶Ãåå%ŒQEQEQEQEy7 Š¢(Š¢(Šòb"~ÂýÃoúO^Aóc?ö#ßtrrvöèá«ÿ…1æ;Fëz{w"xCwÿºØÅ¿ÊÞ‰üT6™fÈG ‰î”Õ‘��Á Ù”÷ë¶CÄH8žÈÕkϲÚíþé)ÛDqÊÎYœ}z%e#ça-â%i+ŽOX!NÀ.f˶aÜ»IŸ>s]Œq‰úyé?Fß‘q. ~?Iíî½:ž´a Ä�Cl'v¤m„ï%™Ã´¿x™ò9Šó�~Í·Jw‡±ûñ˜ÚóשO_^ÿçiãJܳCD8=»õWªŠÿö~·ß žýͪ¢þý|?~é÷|þ'¿æ×àcû%˜Õs|öSŸÁ?ü‰ˆ—^þ§èúÛÍÆS£ë{l·ˆl6k\^^âüÙ96› ¨bTεc¹\áþýxðà>ˆ———xúì v›=¶»Ú®1£m;œ_\`»[CŒÁl>Ã|ÞàÖ­[¸{÷În�aÖÌl64 £7­®ªŠ¢(Š¢(Š¢(Šò.@EQEQåmdõñO<×qôG¿`°1rÚuíJÄfÿû^ õâ·•½(>Ñ&q&–Çícnç©Ànƃ \wz|ê Ÿ ñ™&M©x+ r¦î> ƒ¸`r_™ëøâ$±]&ÊÒÞKaÛ8Ĺ°Â¹ˆ0HÇÅ}‚„w-ŒˆÿY±� Ý{1?4:Ò£“kx(â§Aãâ~´ù—0aó‘ây.²_-þÚ~½¾¦öy‹To`ç´"âJ ŒÈz»Á«¯¾ŠŸýÜÏâ ?ûy|Ë7} >üáoÀûßÿ~|ýƒ_ÇÃ×_Ãn¿ÃÓ'OÐ÷]xF�‚aW b ׂ¨*Æ|1ÃÙé)îܹ†²Ùl°Ýl±ßí`œ³Á¾m±Ù¬±ßm‹NNNqïÞ]Ü¿§§g˜Íô¦EÓTèû›íN`EQEQEQEy Š¢(Š¢(Šr0bˆ‰É˜~&bÈ‹á>‹Þ#A¼ô"·Ýî…y„×½{ÿêÂæ”Õj��g!éîŒê´!ãßÚÌÇÌxbÎÜ Â!EcƸ}˜PTlÏèóF\à2Ý;¤Éí!+ÃJö±ÿtŸö�fêOÌ*†b½³ªG2Žä"Jy�C;nþ Š€Šì´C[‡Äÿ$žã—í8áÿò–)÷χNavˆík‰7U-ë®Å³'Oñ¥/~Ÿþä'ñ‘oúîÞ¹‡åb‰^ƒ—^ÂùÅzc°Ý®Ñu˜ MÓ€¹1cßZ;ÿÞ@uÝ ®k4uƒùbŽÅbbÆv»E]Õ1XoÖØmwèºí~�}»G×0f³g·Npûö-œÝ:ÅéÉ\Õh[F×vX,æ8YÍu!UEQEQEQ”w (Š¢(Š¢(7€®ïQA"•±ÞøH²ÈýŽ.£¿X‰ÈÚÅ'›½Àl­Î‡}ŽèÏ®±$ ÞXµØæ6‹—´“Fò€�±NüX�äʾ85žˆ2¡:Í´qAF`ƛ٠Aä–âÄB ø2Òf™å/ŵ8Œäç\díçæSVü°õÒÈŽ¬I)O}0+SA˜šÏ,hâÀÙ½…"ÿÛ@`EØŸh=› Œ ÝnñÚ«¯â³Ÿý >ùÉŽ»wîá¥ûV'+œžžb¿ß‚+B»·‹Å M3Cozû<ö\9�~¹À¬iPUœ=³\3¸±Ûº®Åf³Á~¿Ån·Gßu³ùUUa>›aÖÌÐÔ ˜+g`à0˜Ð4úë¿¢(Š¢(Š¢(Š¢¼п(Š¢(Š¢(Ê `¿Û�ë&Ô¥·øŒuJ7Œ"Ó‰è£ø<þ¼à:e{Äþ(ÿJ§€4oÞ1¾ÃÁD?M?§â|| IÒoâìOβ=+Q 1`Àf\°B®!G1;¤g:,Š`Ï¡ØO²3ã²ËGŠä¯eL¸`0í¯hœQœ]h“4'ÅÙ_uO•– oDô¦?c2QzÁ—š 0fÍÄ é:\ž?Ãç?÷9ü£ø“˜Õ5>ô¡o@×ìv;4MƒÅr€ÐÏ;TU…Åb‰år °\¬ÐÌæX,çØ¬·¨ê óÅÆl6\®×˜Íf€šªÆl6GSÏPUkˆô]‹}ׂ‰Qõ5ŒéÑ÷ö_Ûµ¨ZZ`·Ûa»ßaß¶èû^REQEQEQEy Š¢(Š¢(ŠrØì÷hL/¶T¼˜Ã{§õà=Ñ€ñ<ØÖF,÷ƒ,?0 Œˆ°D( ÀgÕ§YûÞ$)!PôÞ‘øÊõÊ P)ªsøÞïCp�ØEL”"y:ì¬$6|q)úlÝá­‚x7„8Ö2l =/J\Ò A âÊ3¸rIP†HoP‘©ò¡îƒÛ#�rÈ.…²×cZØ÷÷GîŸðb2î(஌�pÍÂ̦™Ï¨ª1]‹~ßâk_þ2~R .ÏÏñÍù6ܹsÕèúÞ ¸y­ë óù«Õ MÝ`µ\a6k°\Ìqþì]ß¡it}�gÏž¢nj¬V'`",—Kܽ{ÇŽ‘ˆAßô¦G×tm‹Ýn‹õzƒõf�Ù|Æ¿ßí°Ûl±Ýn±Ýíu!UEQEQEQ”w (Š¢(Š¢(7€¶ë`Dã¤lYÑYŠ”m¢¡”ŸÄýÙã…r“–š/³òC›>=(Ù«VÌ‚uáh„í°-=•"Cßgð‚8Ù"1 e³w°Ó'c™éäÊçímˆ‘ˆ qA ^¤Áqü¥S yˆ�‚qAþ$ùè`¹I$Njh;·‡Èö9,ßFÅ츔p,”õõø{e:úÁȚ®+™Íæ˜Íèö[ˆé±ßîð•/| OŸ<Á+_}ßôMߊ—^zËÕ)šºAS5ÖÊ¿"Ęóùgg·`DPU6›­ËÞïðìü Bßõ8½u 'ggX.WX-O0ŸÏÐ0Â0Æ [¯±ÛïA—ÌfçX­–X.V˜53p]�ˆí½Ô[gEQEQEQEQ~¢(Š¢(Šr#°âá@ý†Àéˆã‰‡‚8ÍÙO³õ}Fx‘)Îy–�ÐGÚM•ÊAcp"BòÉɇ”æýþ¬�d%J—ƒ(ô³ßý\$™ü¡ü+"À*œ⬔}Qz"’zHq¨„Râ&7^ ×)84HOø>Ì)eóà3Òóû"/ÓP:Äò ©KÀ¸¯�?~ò.|ƒ®²= €*’ª®d±\b±Za»>Go¬¥~ßuxúð1>»ïÑu‚¶íðÒKïÁÉÉ šºWÓÚv�ýv�ÍvãŽëaŒqŒ®ëÐíZ\{�š¦ÁÉÙ ‹%V‹n��a6kPÁt@×µØl¶Øì¶0Æ`Ö48;ÝÂÜíQÕ3,— ôÍc½ÙBŒÑeTQEQEQEQÞh€¢(Š¢(Š¢Üf³† BÌÌãyúåoß/¹NN4°Í÷ß1éÛíJ6Û›$*ÜI&?%=Å:öŽõÔ”ØPðiâü(e‰�ާ<(„.$.øi‰zÊ\(Ët�%¢³��3ã2ý£ÖE÷TäöLJS&ÎbÂ,ˆ„qŠä3H4 äð¼¤�ƒ@„¹¥Ä!#s¬û :"ã?_Ü'­¡p3 "03¸bœ�ža{çv›5.ž=\\žŸã+_ú泘+Óc1Ÿƒ+ûý~¿Ç¾m“€�8Ïí¾Eßw#èL ®óËÎv[³Å‹ÅB»ë°Yïq~~àöûÚý³Ù Ûí"‚Ål†Û·nAÌæ3ìö;<|ôPREQEQEQEy Š¢(Š¢(Šr8Y�Àô=1WR×UHºÏ]ò ‹÷`ƒOÉW' /{¿;åmøã c�õHñÕ†Vò⚢< ÍJOÝ÷½|?%ügã,öqßÊ>G–ÏL0Æ» ¸P �;F&XÉ�ÁÎa dòKvRYDND!²‡ˆI,ö-Öp!šÿûë.Qˆ¼°"½PùíPƒ4IXÑ`ر<ÂøüKYÇ i+-08”Ý2­ñBA`TU�Š{ypÿ>fM…¦f|õ+„§�Ò‡ûýò⯾úuÌ ‚Ó³3ÔU…¶mqyy�õúëµÍدë‹Å³Ùu]Çëc€Íz�º®0Ô`6›�¬f ˜^À\¡ªj„¾3ØïöæÛ-Ú} 0ŸÏqzr†¦i°X,°Ûíððáëº�*Š¢(Š¢(Š¢(Ê» PEQEQ”ÀÙÙ-tÝU]QUUA‰�‚6Å"ô�Ô“€Ë['ò©ì…ð+¶ "[3> ]b6»oGÄ9êà»/�1bëŸûwô”eí§�1Á? ;Hìø“ó†@HP&š³ z°ÙÜVp7Æ€•\ä"Äø¦%kèSbCšïGc$u_Èü,I z[×�˜œ£Br]€•§,> À]« ܳÌKû}*î�0ø¢€HyMc‰ˆ1Ê`ƒC¤åäErH琢ÐT LÝã}ï{<¸�{÷ïáÖ­Ûøâ¿€Ç_Ãv½`Ðu-ž>}ŠÓ‡1k@Í|†®mqqyŽ'Ožàüü]ס©¬NNpëì–‹ªºvA)‚¾ïažôÆ`»ÝáÙÓg8[�BŒàÙ³ \^^`»ÛbßîÑõ ‚¾ë`Loï;bÔuƒù|pëìîܾ§ ©¢(Š¢(Š¢(Š¢¼ ÐEQEQE¹œœ,Ñv5ªª’ª®d˜›-#¯s {�€½HÌök°m'‚ˆAê8Ÿ[ºSöuhm�¢,< ÇSΓ þ$ÞËF¢+€7¡/ËsVÎ@$æÃ0ˆ+˜33ŒˆËà�çB.À81\ÂÜI7c0™ŸCf /»| %¼C‚Ø@ _^�’´Nƒø¹ÈŸlJÝDÊ;#÷‹  òÚù[CFÅùa©€ä2{WÂA»yAK¤÷J]Uhf�éå=/¿Œª®ñÞîýxïûß�/¿ŸÿÜÏâ«_ù.ž=A×·hÛ.Οau²BÓÔŒ10èZƒv¿Ç~¿‡izÔU…ýlŽÙ¬Keï #0}�®m±ÛmqqnN–+TÄØí[ðÁáSŸþ$~æSŸÆ£×¿Ž¾ï±Þnqyy�““S,–+Ìš–ËV«öû�»¿*€|p€qý1ªŠ Æ`ßîÑn:œŸ_àÉ“§X4sTucÛÝëí%Äô`¶mÕu 0Ðv{<{öÄŒºi ج/!�Ñ…TQEQEQEQÞh€¢(Š¢(Тܬ�<�ˆ$*Ò@)'�Iöe†~™ÓëÈ&|/.Ë�FG“ÚÑ{8fÆ#äÍ#K^‡âí…üÌÚ¥â쌑,+;spm’iÜÑ À7öÏ�’퉘ml€HÛðsÈAp+ÒÃgÌ»9($ì,!)yàK6;�@$É\KêA`¯Å €XFa$bB|[~NS‚±Lþ±@€÷f›ûI‚>ÒþÛC÷ê‹P1cVÏÐÕæó%V'§¸uû6Vg'ø†o2øà?Œ[wï€|ÊtxúøÚv‡õz�Ýn X­VXÌW`wõ//˜Þ ©kp¸ï UU�`�%°o±ßî±Ýn` ¨ëÆî_1zÓ£íö ê¦ASWhæ5ˆ€Ý~‹‡Oár³�my€ÞÀ˜^REQEQEQEy Š¢(Š¢(Šrèº]×""ÆHé«.‰¢¯ ‰5Xþ™âî qYÿâëÀ»}Ë”ôÔÝŸ’4uâ,^jNEàôuì»(H¶{ÝÚi¤CW²ÙýÙyƒ N<�¢|r|–îŸ�˜( ävN$l ç‘Z-8§ ìlómÿ¶{êÝL3"Öû±ÇÂ^'”Hv¸w¤¸'Rø…tÆ’ ‚4*"¹Žù”SÒÝTAq� =Ÿ®¸ß_¤@Ÿ]ßÔ5ÚÖ íp�ÕÉ)NNOqzû:éñèõ×ñðµW±]_b¿ßa·Ûa·ÝBŒÁr±Är±ÂjµÄ¬™áÙ³'Øl¶0b¬èïÜ%ªªFÅ5ˆ*ôm� ¶è{Aßw0ÆZ>ÔT$¨Fc0ÛÀ�¦®A$Ønw0òB»ï`Œa¡%EQEQEQå]�(Š¢(Š¢(Ê àòr�®Ý£ïzé¸ÏÌßÇ4Ò�ø�(ð† ýÜ“?ÏVÏŽOìö½�ý‚´Ì;…v‚5@f�ÊÍcûŠœ‰ÆÁH?Êô®Mµ<ˆ™ú<裠M#ûJtPÌ0 ŸÉÄ|÷�`|�+9Pfþs· pvþÌ6 $ç‡9 ³œÅ_ˆ³7 ,p€‚HNóíº5H¤|ç ÁD€0ò‘ÍÝðŠó˜‹ôÉ„ŽеDý"€ƒ™éáÃ'Øï[t}oKMÀ̸}v†îãÞý{xôðuô}cŒÝwߢ®Ü¿ÿ/W ^ºÿ2=z„×¾†‹‹gØï÷ÖBLfó9‹%˜¬}?Q…Þ´¨š ³Õ MS0Ø·;l7kìw{�ªº‚ˆ`·ß`»Û`·Ýa»ÝÙöœ¬Vº�*Š¢(Š¢(Š¢(Ê» PEQEQ”Àùù3tû]ßêØØLó(lOYª[2e¿PÂSœ¢N”}Äš÷Y@ž ><@ÞôÞ7Š\½§aÍûÌt 79—�âk΋—ãsWiصNEA[†@¢hΉ#€H, iö½·ä÷­pr®Ǧ¥DàÄ]×¾H´äG"´'—)– èNàÎIB‚ÒëÀݳ³ÿ}Y€t é¤NIîDTdú§÷Aœ`O}ÊAàú�cí½ÕYõŸ«š¾öµ¯Ê£ÇsCUڮŭÓSܹsÛÍ›õûv�gÏžâñ“'ØíZœ�ÝÂË/½Œ—¼"Âf»ÆåúûË-º¾EÛ¶€Åb�¦šáìô  n*,OWX,kH-Øn×xýõ×aÚ»]‹¾í!Æß_ &ã‚_]ßb·Ýb³YëBª¼!Ö?ö1ÄU�íg €*8e„ïÉ}Ïl·“ÿW¹í•}M•ÛÇm'ÐØýÙ¿_ƒý¾\Çý}{I» ÚõÏ °oÇÆkÇG¾w^öX·¢Š� "=` €Þ-}ü^:»�±_íCÙÆï“|•Þîc:@zéØïaz×o ã^»ýݱ‚>oWLkŸIƘ|/1’œ—?OÑ›ü«�B'AQEQE¹1h€¢(Š¢(Š¢ÜúÞÀô ‡¿Ò[q51ÕB}æm¾�bµÏx�ýÌ> €bþw"Šs÷)ºVWp"2Qtã ûÆÀ‚°à¾ógË/…­�«‘N~Œì³è�Í·'/ŽS aµ ŠYîî½4p!�Ë´ç˜E/b�ˆc`„$Á~¼Èƒ-H|FžUïÇ!ÎÊ_Âü$Î !‚Áeóû ¼�j4é9gÒMæÊïJ"„ùw.¾&2õC3EYƒ$¢,!Œ•HŒ(º)Ĺç²û'<º™¤b¦Z6›g€l*Æzý ›ÍΟ�aµœƒX¬¸{ç.Ïϱßï±ÛoñøÉc|ýÕWðêk¯`³ûfÌ–3ÔÍ-œÞ:Ã|91¡ï{´}‡Š·ØîvèL‹ù|†Y=GSϰZ-qzk…ù²A'—3¬/רêŒ!t½±)„Ð43@Ð4¨ëU]áüÙ9¶»­.¤ÊQü‡ÿ‡?æ U×B#c~5D$üó˜^Ðõ=zÓÌê«å«“%fMp¹Ùàüüç#X®V8;=Åb1 °Ûí°Ùm±ÛîÐ÷¸–‹‹ùÄŒ}Ûb¿Û ë{MSc1[`>oÀÌØµ;\®×´Ûw fžÏjšUuMb m6k\œ_`³Ù‚‰qëì÷îÝÅéÉ º¾Ç³gçxüøÎ/.!"¸uë úÐñÒýûè{ƒ'ÏžâÉ“'xúô™l·;4uƒ³³3œÝ>£åbAƾ¼¸¤gçç|yyI}ߣª*šÏçrrr‚ÓÓSœ®V ›m‹Ç�ãµ×ââüͼÁK/½ŒoøÐ‡ð�¼§§§xúì>ûÙÏâ _ü6›5êºÁéé nß¾�³Ó3Ìf DÛíëõëõû} bB3›a¹\àää‹ù"‚‹ó <|ôÏž]HUUòÒýæ=ï}YÎÎÎŒé ž�?“Ç�ãé“§hûžNNOqûN6› .ÎϱÙl`úMc×¥Õr…ºªÑv-¶Û-¶›-ú¾æJfó™Ìgs©êÊ€ô"ÆûCƒ ©0½]ÿÚ½1±ŸéM3Ãl>ÃÌ9—l6¬×tmª‹Å·NNpzvŠÙl†Ýn‡'OŸa½YÛŸ ¸BÓT¨«W½±ýt]fFU1*f0W`ŽöBF$þ\å~öáŠQýÝÿÀïýýH EQEQå…GEQEQåÐ45 @UURWu–0O1%< ïH¼pj·Çzïcš§ó£þNQØgʲÐÅ Ì””  Ü¾ß øÌQ±b6%o‹ÓmÞ~ k@Œ d~|ìEqW" )Q $I”Ùé°Yù¦l—ÃøÅFNüòeíÅŸ†‘ Óûö¼ë¹Œ#Nœ/ÜK’5O±8‚s))Úr'ïû/NA¡0ÿˆÿ‰Kàœ$5` XöÁ¨!\ƒÐ7 Š1$íú{$–Òûk˜ÜŸŒ” ‰²oS¾Ì,³Y-bˆ=zéÑwÀ~Ûá¦kÑžX!l±XâÞ½{¸8?ÇùÅ3\^žc»Ý‚+Âí;wðÞ¼·ïÞÁb6îÛˆ�¶Í¾Ç®Ýa³9Çåå  ‹Ù‹Ë^6Vxí:´Û»u‹Íå»õ»mÌmóbµÂ­Ó[¨› »íççxôúC<|ôHRåùž Ê¢ÇÂâ× ëf’=þ6` ô•¸uÏÀ�À„ç>h²�&†´ùÏ0' #ú£�ˆ+sªˆ¨cQEÖXÆ¥ùƒa×Oba1bì]0ƒcÜ÷¦Ï>'+¶"pþ™iÏË~J¨¶ýSm-(‰èŠsPÖ±1ˆ�éуÎôèûFL²:EG?Gc«¤‰–:¾ÜLv¿è vü”†ˆ±�ö"0FÐW@ODFX ÂþÌ‚Oú©b!"¡ÁÏ&î€äœìu4îüb`�$?Ï÷3ÂXPZZÉÜ1q¥è]QEQEQn (Š¢(Š¢(7€ù|�Š;ÔU-uÓȘ\™fÝ» A·Â5ì@,�‹·þïäB©@­ÿÓ?Û‡ý²ö|yi HGMÛ îâñÖô6û>žWš)çH€Ð¾uàLƒ&_ç>›ª„`�üþVh§(-eu˜ƈ³ï� Ù¯à¼õ±¯^7‰÷1´ÂÍ’ëBÉ!Þ†Únqµ¬ÈSsØÝ8y„ë*áZ†` JmÒíÎÝÀ÷#ÃÌþr6Ó{é˜1-èÓx<î� ª˜fMM"Õ³ }/0ÆZmwíÛ�½?³V‹îܺƒó»ÏððñkxôX°Ý^âµ×:|ög>�Ûwoc±˜ãÞýûxzñ�ôà†Q7�»ºûn‹‹Ës:ôˈZÔ  ÞÚn†Ýv‹§�žâéç8z�Ë‹-vm‹ŠkV‹^~ù=¸uû6`³¹Ä׿þ¾ü¥/êBª\“ÔÄD‰J¿øõϹ™¤Þ.V<é!R[ Ö µ& ÞFÎÅJ¢ÄeDÒ3," Öïß…1�ˆ™ˆ‚Š@µ hÔn©'{ " %~,™³�Ø"P2cbø�­¼z 13bšÑÌ¢vúY ùÇ‘ø 10}Ó÷è�›+™=Ž·g¹„F�>Ý×@Œˆˆ1"Ò¨%âuBÔ“¸Ò1îcZ&ÆðãÁ0”±Ñ½­ =€–ˆz÷ÏôD{ÏÄ‚=ä;vâ?£q Ë?Ac a` ¦·Aá\ýœ"üÒk�nOïtßK$ (Š¢(Š¢(7 PEQEQ”Àl6S…ºiÐÔ�”bl™©�¾Ÿé ‰>•å5å(TÛôÎ IK´ñ—ð'y‰Yÿi6}RûÝ Ôq˜œ— H,w­ØâÅa›„�Ò&Ÿl6±û IúMÆ&ipCzÒ‘ÉÎ…8O•Ë4G}ʺ$0D (3ËO0‰5 `+Úç‚dòÓy‚¤RZã1°åËx'B,Oà-$½¸Á©  ­yOÑó!H|.˜C¤¸W0"Ú;ç[® ï�„Ÿ<È‹�^Ÿª®ëf>ŸÁiæºNÐõ°A.s_Œ¨ë''îܽ‹³³[˜Í渼¸Àfs‰W^ù>ýéOâäd…÷¿ÿƒèM�`¹Zb¿ß¡ÛWÖ‚ ÆìÑõŒ®gô¦B×î°ßÕÀv‡‹‹ ž<|‚'�Ÿâò|�Ýv‹Nz¸Áæ³%ÎnÝÆK^Â|>Çf»E]Ͱ¹\ã¶ x;yúô©.à7²Kµ}†�—H‚Þ„µŽ�z¥â„YÓ—¶ ¶‘DŒ�K=`#RhDdfDiˆPQ°|!°�™ˆ•ˆÌ ÒÀ[¹´{ jRêñI@‚鱘5Õßwõ�÷Þá|àÎJ`@:;ÝlîðÁ•ô×5ËÙéò¬™5U 9éûýr·ß5ûí¦ž5fqͲœ×‹YÓpå¢Ö¤¯Ð¶’åªk7 #¨ç3Ì-æ³WÁU ÓnñK?²Åv]¡¦Ùªb�¡}<ÞVüÔfêKé[ôݦßCú€ÐIµ®+¶ Ò¡m[\^ì¶í~×ULýbùµv¶øÌÓù¬ê�®ßnûËÍf߯·½¬w´nf5˜W[jNÚ^êîü’6�–²{ü´o¿òh~�AÕ`\”�ˆéÄH +à·DÔ2Q/@ïYW ÇÝfDÁ}†ˆzØý:mò¯sÛƒº/tF² ÿ9(F¬ÿƒ½�“z{­Ùß Ræ‘7µ(?wÒºDŠ¢(Š¢(Šòb£Š¢(Š¢(Šr¨š™’)fœ2îøLîÄá=87K¨W¡Ä«?XÜ{cw‰A’d‚Ún$Ôž÷†ÌöÛ<À~EbKï Pbן¦öûýŒ×¨%q2ÈÒäÃØ9ͳô=�„ìô (y5Ë�ß0 ÆfwyÓé´mB4=`+ò†Iíá3PÓ ‡ Ýû¤zIaû§,í0 {Xç¤×רëéK˜¢›�Š1³fVß⊄Zêû®ïŒ ¯˜­}6ªŠÁ³''§¸sç.nß¹�Ëõºõ›õ^y嫸™ÏݾÝãdu 0p²Z¢bÂ~¿óyɨ› uͨF5«@5¡ï{ìwÎÏ/ðôÙ9..l=î¶mA¹šÖ5ª¦FSÕ˜Ífhšº¶CUU¨*ýõ_y>b Rüc¿°ûWÁ®( r/>óž B!c3ÅɘžŒéIŒ!±­»nÜǃý„ë>_à ÿÌ`3ûÙZaf<¸ßœ�ΫÛLÍ-f9™5õÙr9?[Ìg§óÙlUWÕ’ ®ä¤"š7M3ofóù|¾:áºi*憉SÕ5ŸØÏ‰ à:ž½±Z´˜0^Ÿ®ÜZ À—ð¾‡ô[û!Ë ZÅX›zô½m§·�D†j bW‹^Ü^r‹œd.·³bÌbö@ߺ1º>ÃÏ6@̸½do?ßyª/]�V`:D 3ˆ«ä3Ó•ac»`2õFÀ�ì:á]oLß¶¸”]Úê-¯õegª§�¡‹¶£Ë}Ç›]ל¯÷óó'ëÅÅkOW—_ytv‘|H¸M¨%PG žÂIÚ™2ÆØz"b¬ÃÈTÒ³ÃçocÜä HzçN`ô WEQEQ~.¢PEQEQ”›@¬¹îÜoea7G»ø¬²° ûE¢%¼ÕÓ´nʺ‰¦Å4’í– ».! ßI@Ø)êFTŒÑ‹ûBÑlZ`OFœÕ~à@™ó=ˆò¸�¸UÝ D;g·�10³Qm³^— ž0©lv¢2‚Þ ùìûàxÎÞ~8™Sã&üüP2—âÛ°Çq"–±7ÜvÎu )áÀÞ¶Ÿ ÆXÎY€­›ìÎ�)`¦`óoå6›@¾‘Dø—äŒAö›4A’Ò ö˜Xâ@d: s­(Kxï­æë¯|í_|ÏË/éþýû«¦y™º¾xÏÔoØÖu³kšÊÇ’‹Å÷î?À{..°Ûïa^{ûýÏž>×¾øE˜Þà½ï{îܾ�“ÓSÜ:;Cß÷èÚ=º¾…ˆ`6¯qr²ÂÉÉ æó9¤v»=Öë5./α^¯±ßï bPSƒ¦©ÑÔ5*º¾Ãf½Æn·ÇÅÅž=y†ËË ]G•#?n¬…�€ èɯýD©I¨aF$5j5€Ô TäþAÀ0`ØXD*c„{c*é #ØÀpU¡þÈ}sçåû|÷Þ-º²’[Ë…¹Ý4ÕíºšßšU‹[³¦:k泓º©O›fqR7õ иú/N”''ÞS¢1¡GˆW¨j3€·ÞÅR+q"|lƒ E0ýp²\ð�]x�­8Àlû2°Ò3k!ã#Ê*Ø©¢þL`ªªA\CЃ‰Ñ{=\lÐù=r¶0̶Cõ—|3Y÷rŽ ½»†•û<¬*�ÓÄÑQ�ßÇWåÖ^Ãî|Ü\¸"9±Á„F:û9Ú˜ø‰Lm¦CúŒû\ˆ? ؉ï:Út†/ºž/Z©Îû¾>ï¤~ÚšêéfÃ�Ÿ\У§ëúÑ«OO^{}ýàaO';ô`g<ÐKoÄ–9 PÏbzîE¤РЉ P Á^ ö¨d/�VÒ 9i½{Sx Ô@QEQE¹)h€¢(Š¢(Т܂Þ[)["Óû)©:…W°ÄŒt’\(?ð·ì´@HÌüöý^gæ$ƒÞˆ�hPS8u㧤î=¥j>™õ~Dœ—8=k í¾%1’ÃlåicœuÌä÷sÇì*>;±ßø ²ï‰wÈÄþ½�.@ti°:ˆs¢†„ë*ˆws@R¿€gSLd›zŽåLÇHbýn$�ì„z7GÆ×¼¦$øƒ­`D|Hðkös ä. ¥°ïï‘pJ$a¬‡ˆ� ãïõÌLvB8¦ ßÏ“'O>ú£?úw~ÑééÙ§îÞ»{ö‹¿ëð·fÍü¢çîBÀ\U5ªªÚ@€¶ë1cÂl¾ÀÝ»÷°ß·¶–wßãõ×_Çv³Á«¯|Âr¾ÀÙé)V‹NN–Ö¶»Ýc»Û¢m÷hf5NNNp²:£Â¦Ûaß¶¸Ül°Þ¬±Ý®Ñ÷-ˆ�ºa4³MÓö»ž={†®7¸8?Çǯã™Zñ+GBNÔfŽk11�{bÔV]7s!Y@° ¢¹ý‡9@3bª™¨a¢†jˆð­åîì\¼ïÖâòåÛ'¸ëlÿÖÉþÁrÑÜY4|§®qÖÔæ`"b€��Oµ Äbç1Pƒ¨²Ϊ¬Èou X ÜZëL Vœ¿†ÚÏpíìÞ�ýðñ"Å`¸þÑÂ0L€0À.� ”E¨\=F¼QÜ{•³«aÛ¥%üg$»À÷/|p÷ñ³8\'¬û *æúp•ëP×.€¬rÇWvžÝ\qôƒ!7ïÀÆ�›Cr�•w`PŸ”¢ñAļÆ}ÀueȸQScÕ _ýË  6Þ€b ¦Oæô3è¥^w¦yºï›GÛ?zº¦‡O.«×Ÿ\4¯}íÙ­¯}åÑK_©v"ÒØ‹È�=H6lE°‘�ˆÙŠð6­Æ~Žb÷ó*®TþWEQEQn  (Š¢(Š¢(7c Lß9/wñš,€Ä¦_(ÔˆÏÓ´%FþÅü{ ~ý±H|ÌŠ§$ÉРД õÄI]ygÿ.iÁydVù” 7s \@¡4¸!;“˜¥n»ÏËø` m¸$F¶ÙšÒDfáåÆåƒ¶ž5±/™àÄ'gu >Ó^`�†)KpH°6Ï&Xü› z‡ôáoü3ùÖoÿ‘Ôuýnßî{bBÓ48== çÑî[lw{zçÏt!UŽ¢¢d­²Ï3A¤0°p_—V ,E° `ùÒííƒoxéâß{oÿ¡{g惧K~Ïr޳FîUÜŸÆÕ(a«‡sÔÖnÞfà³ JòîTE¡9˾NÄi®‚ÔLª€û68¾Ÿ ò°í»à+’ûÒ.IPWø;;¾Röc´‘a@_Œ@PíC{N7~l&õ9Ž Œ¸Ï^AñáW,‹TlLæ@‚K2V §ŠmL„êËè(Ø'&ý §p<È‹ˆ1±àC˜;צwÞ µeÒH¼äç�²ö Q<à‚9üÏ4D¨YVõ¬[-нïÖxù¬DìX˜`̧úmß<Ü´õkëýì+O.çŸåñÉg>õÕ—>ýx½zdD.DäRDÖ½˜5 ¶D´ÙP ‚»4�‰Áĺ8(Š¢(Š¢(7 PEQEQ”@ßu0}1r¹=¾v»{™eþS²�² ø\à†KôÖÂ1ó?dŽ¡æ=õîÓ?Œ‡àB– ˜‰½©#0 Ý$:øÛÍEi�±ÒÁ‘ ,{[krYùƈ³HöFÄéyGIMýaE p� \A¾¯ƒ˜C@‚��-Hl Ž Öí™Â¼ ÈÒ&È{„KŸ^xÊÊBQ¦dK°ãϯ‹ã<¸$hþ„ôNˆag|PÊèƒ;Ï/èS,ÏpľÃâW¸^ŒÜOÉ� "‚1æþùùùoýgÿôÿ–OúŸÿÿVË“?õÑïú%?tÿÁKk#Ò T±Ì›¹©osB¿ÝnûËõe·Ûî°>¿Àæb�×^ ÷îÝÇý»w±Z­P�0*®±\¬°Àõ¼Á|¾ж[ì÷=6»6»-v»º®T c¾˜a¹X`9›�™ÐõÚn�‹‹Kœ_œãââÛíFRå¸'‡Tqú°4Vn¹§ßöÞW¾é›<úEwOwß~ºì?²œwž×r°ûTG‹}»8ØÌqaq¢¯[G½e?$ ïéÃÊœˆØ’ÛÛ‡'ÕþôÅû–í’¼ï…æøæÛK¿O�pddÕ¨lßWYÄ -nÂâ‰ø™›9ªä� éùNôGɹ V¶äS�È®¦ì\úìˆÜE€Èžf‡Üe��_ œUŽÝ©*\¢ AúC‡íËPn (Þ+Æ÷í*8)gdB6�PU¨Nêîå“yÿ²`ûº |ç_Å÷þ‚Ïɶ­¿z¾mþÙÓÍò§¿ôèÞßÿ‡_üÖÖ­´°'¢1µLd*ªÀ•æÿ+Š¢(Š¢(7 PEQEQ”€1½¯ý.VàMRå2˜¢}:ÅL¸ãs0@…cöÇ‹ò©{ŸSñŸ‚½}æ@‰ ždÀ{kaJ›¤\Ð'ŠöTˆÍÖº> 00¾ggÏœõgìjZ»sN®$Ã$¢:ql'WªYP°‘çðÚc.›5诋·¢f—Uë%"ÀÛdC'Ä�ë„Bð„Äq��ê_H…+3?^‘ÜnYŠÀ€¬ßìœc`‰1EÀ%×"óR äþ¼ÓÀÉ'Ö~ä}åã?Žò\ž‹äΤ4;&jÛö{žîŸ|Ïßþ‘þÃóùâ/¾ÿýü�ñ—}ü‹\U}Ó4mUÏö''§Û÷ìÎÏŸa}±îú¶C×¶8ò ¯|íkX.0½Á½{wqr²Â|1G3Ÿa9Ÿ¡ª+´m�Ý~�õvƒË­ÿ÷}ãæ¾®jÌ›æó9f³êªA]UèúxílðK¥ ©rÌÖq÷Y0ƒÁ­ïüàÏ~ìcßð…ßs2ë¾£©å.¨²"¯©@•é)Š´>_ÈŠûIö7¥5ê³LùcK eTb0��+b$åS¢¸M¡ïÊíf`Ž]/ŒŒ 5=YH®˜sŸn.È[ݧÿ(]ØFÆtݱÞ�›áo$.Îþ3ipÀðøPîÇ9ÔX7‡>ýà?0rÕâ{Ť! Š(Ú$d�Á-ÈÅÉ-šî‹Yÿ�—nm¿÷[ÞóÿÃoýü«O×Ë¿÷ÅG÷~øoæ;ÿƒž�ð„@D´KƒEQEQå& Š¢(Š¢(ŠrcÿºODRKt¦"2·ã/Ìñcí÷”ðÇqŸÉo-™Å˜$»Ý‰LQŒæ\̓\±€$Ž#-zp¢ q¤£�°ÏàÏ� Ö–ßg÷‡Fƒ;=eâ­µüô‰LUæ˜À…x2ú�°N4 ú¾X¨ük–Ú>ˆÁÆ,$B”ïß^„rö¾d�$™ËA4E(�_»ä‚[ñ,3„]»!p„ b�ªõvÞ(&\"Ù 3aïŸÞ’œ§o7ï00€â�9¨¥� 4ÃÉçÌ_ãTèdKyDp»ÝüöÏ}î3ÿæ—¾ü…O¼ôÒËåW~ï¿ò×ï?xðD—‹åòâÎí»ôàÁƒÍ~¿ëŸ=}†ín‡W_ý:`»Ùâòò=¸ÿnß½ƒ[|†®©Ð‹XÛÿÍëí»í]X UÝ ©Ôu�ŠÌªºF3kPK A×vØllà€¢1§ÏÁZþßýEþÒï¼s²û¸U^9”"~šy^°!8 œµ°äãHÈ6/v¬^Ðç$h"´�T`ë›$Ø€²x;Ê+*ø“×PÂ|‡£}£ 40…ÐC”W‰HÅ|ñ%%„’’Ì¥K@¬ íË5± @*âêN$FþcAÈÿX–-°ö?^„Š% ò�e`K)àI2í¾ýÅ_ûêW~ñŸùÿï÷ääô¿ûðG>ògÑG?ö�W'+zpÿµm·5Æ´ççxòä ¶Û.×—¸¸<ÇÅå{ñþ¾sצ׌ín�õfƒýno‰¯*4õ ý¬ƒˆAU[³7}ßÁô1¸®lÉ‚Þ`ßî±ÛmuUž`!�Û·W»ïŽÂn)ü§ÏÚ˜ý~ZBÅÿ/ Hß+‹qL ó^$ŸÊ§é'�0ÑÇÔpÚ§ÿZXÛO'i&¿ÁX@4�Áñ>0.Zæ0ƃ†aÓç%±œŠsü¹"º*žfj:“EÛQ´êt'É<^�³ó÷®ƒÏ‘ñ&ŠRåµ–ü³+:¼Ä² ‹Yÿ�¿ðC_ü-Ÿúú7~À3çGø(Š¢(Š¢(Ê …(Š¢(Š¢(Ê AŒÀˆX�Õ)Žå¥½0m³¬ý¹s¹_’�Ó¿•‹Mü÷±® 8ûfoûΙ ]þ!žRË]ò™î’¤™óE¦}œ€X2À °dÿPÏNH/¼C²²Ú’2 "¨ÕÞÆžœe>‡>Èøyq匱ý†mÃ`���Ý¿(Ú2ù;Iä—Ä €c¶÷B2C’Ì“³k–Þ»)¸ûd�™ï¤îÂ¥9u“ˆ ø±>6‘Ä(ƒ £né½FDõ|ß²yë4*Ÿ§‘ ¾7Oâb@bpCß÷gÏž=û ?ý‰ô>ùÓÿä«ÕêÏ~ûÏÿŽ?÷Þ÷¾ü¤ë÷í~¿Ç³gOd·ÝšívÛo7k³Ûî:@úŠHú¾EÕ4Ø÷-ö»ˆóå«ö¡ij´û½1Øl7¸X¯1_®1ŸÏ°<9AÓ̰Z­°Ûmqyr¢‹¨rÜ#àÖÀ^„¨DdþÍ/}å# ›[6 :µúŸz>ŽyÈÒ`‚CÇ[k€l•�ñ¾‡"m)ÞËÄÒ¾ògü�p?}~cûÊ‘Mx€T0gWU¾^@²#Úô#©â˜ˆFÖ³B”7ÄCçB<½¯L•D ÃSb, ×*Ú;ç¤,‘�D@cí%A,®ýû§ë�Cp ÁœÁ�z†:(Š¢(Š¢(7 PEQEQ”qåLàID|*·qÞ¾tb/Y‘:ý;¹ÿ÷ˆ ë’8'„Zñº—½øOÉÌc=w„o’ÚÑIOi'™üd­Ç1ÇZÔ©S€µ¨bƺ7ÿ÷AyŸéù¤¬DÑu:Øö§ý20Æ‹»¹UiÇïÄ3ßNê– A°�Æ øñl¼å½ó HæÑ¿/$A ú³ù1ø¹�¾Hi¹Ÿ‹ïá•Ä‹Aáâ&iŸ4!è `­ ¥(ï¯\øÇÈ>È\ÕÓ¾~IæÜ)`¬}*Æ“öw—QWJ¯+¯¦µm÷ÑgÏž}ô'ÿÞ�ÿ¡f6û¡“Ó³8;;ûç—çf¿ßu›u·µïvÆ`ÛÌšÝl>o[鱘Ím@‡Ìs0Õ˜×s,K\Ìϱ¾8Çv³AÛîqyA¨ø1šºAS7¨f fÍ ³ù‹å«åRRå(˜ÈÞ¹"‘ZŒÌßwûѷغ+ˆyº|Pö”$�!ŠÊa�HKŒeø�عû2-a÷ýº™a@Z|Íäz0½ˆøzñ‡Äñ±“tÇ?^u¾¢ÀäZæ-gØÎȵÓ]µÔåó96µ™À~E†þ˜;€ÿÙ!ûá•'@*¨Kî`’i{Ã?�¹E÷Óó4|=¯û»ßöÞ/|ëg_ûÈWÔL0 ·2òLQEQEQÞ\4@QEQEQnUU`0±Ø0³ôý°pªWPdâ'ÑèßÞ3QÖ ÊA/§ §Ùì4P$�Ã6LœXî¦ÁVäôí¥¾§,MÝgÓ{[dÛ%J”Ï|Ïôm?I[iÐAåÆ+é¼9á…À`¶J‰w�D€ÊÏ�\™`J8 €ŒÉ¥àœL©ºŒÜ€B€@Ø ™3²6c‘v þúKzyóã¥ÜžÞC‡”�2í?£Ä6'›‹ŠÝ4Þôôýv<ôF<œÅcÄÑH6çå“X<6xät¿Û}ßn»ý>}ª©«¿ÜUõkúîñ~·½’<‹ì³µ�\€«¯ß7½ôêÇ>ûúG~À„ž€N (Š¢(Š¢(7 PEQEQ”q&1 ÑujLG¶§¢mØâ³ÿ“LÍà( šò‚¼/ 2l'Ô€Olý½–îm{Ó\ê< !¯S349Ÿ)…YJÊýƾŘ˜œˆ iFb>Â$Ršø'ãó. ¥õ¾$ƒ ”e¼‹šŸÔEéòCA&¸0€Â‰ñs. .J $'�u°;¿$0¬S�߉CRhJ2¼ÿF3ü“V§»y›ï¿1MÈjið‰ß�ß1¡«ªª_ΫåM½@×÷¨›}·Ç³§5‚}ۘĄåb…ÍÙ»Ýæ‹3ž�¹BÝè¯ÿÊqç<"",F©W³ö¥Ã;^˜M\QüzÈ ô“Bþ¨î•p�éÏ5ælíˆÎôüëÀÁv�]¨$=Ö$võ.Ó•ËøO<Ú,™þc'™¸- N~$Ø";¯#'Š 02>'éG“™€8Âô¼>8½üN"Ya.‚-€j (Š¢(Š¢Üô/Š¢(Š¢(Šr`fTUÛÓluk«�i�%¨Ø˜ ¾1ã>·5Ï$æDÝ â?Sf¾K!s= àL<°åçÐ_ùþ$@™Êê„t “½¥{*ÔKZ ò¶ »Â ’øé !‰²“¤ò¸ ‘€›¯R¬+UœZó‡¬}‰vúÄâì«óñ F,ò€A>ÀÇ@„JiF¤�€Äµ'Ñš_\°�:a&“�Ÿ8�¤ìc|’>‘s¼ü%ÿ9,ºdå Ê]iZÆ åæ¥)üûå•)Œÿ‹Ó•A9‹üž eÌükúµèÛÏ<~ýÕ?ÛÔügW«ùkͼnWË•©ê ‹Å¢_.V}߉! »¼XôÌ,¦7Øï[˜¾s…ín‡ív‡Ý~‡®íl9€šÑÔúë¿rVü‰‘™�4³¦½÷\�Qåt/ÎRòPXÔ�>¼U\,FÅ×$ŒŽ¨-½™H¾Žõ=œ`pœc�I?Ý94 T®0p(K ε\‹¯94ùâªÅw| |y�òÚ‰\mÇâïSfÿ'ÇúÏr&ë êù”"„Á‡Òv0§óÝ7°° `  =p3(Š¢(Š¢(Ê ë(Š¢(Š¢(Ê øÁ�\Ù,Þ¦™¥é•H¿ç�­>ñÇÿÌN??–h˜)ŸÖ²·¶äEÚ‘$/º?´3Qž¹èÚ«8ŠÑDA’‡W®ÓÀ€ üñ?Öö‘P.À—5çë2´½8oËÐÈ|Ä6 í[ÄøÌWˆ‘$ã?™ÃPû˜�y3‡My!x‰ÖñEAz~¾2BzÝb‰„ÔÅÁÚBlàDú~Á]�SÌAYÀÇTÎh^:š“}3飢Êà®Jæb$2å‰iPªÑY! èˆûJþOäjµfJS£x¶ñþC.Ét{ƒÝÂX(cD§@D¾µmÛÿÝW¿üåŸü‰ÿûüüýŸü5}ß½‚—™ùA]Õwë¦9mêfYWUÍ̘¾C×µhÛûv�¶Û£k;ô}AÅŒªÒåÚT©ÔóÊÜ9âi-jÁsÌÌæ*–‘™üóMü™ê:B6z˜G0Å׉÷ß4ɷǸ†lçˆÀv®PãðŸì8¬÷aÞè:órÅ>IéŸ+/3ûM¹°¾z¹_7¹,sðN¿`Ñtï½½¼¼` `&¾Z�¢(Š¢(Š¢Üô/Š¢(Š¢(Šr êºFÓ4ÒÔ3 b¶Óð ýÑÊ#‡Óh£©p￵ä4T½ãP¼x:Òä@–<;:Í;÷Mùm¥€emúr¶´€dn¹h,AüÏò<�±…6’À%µŒHp+  àÆ2.ò 7Ówõ JëxJû%ïV`­ ­-?esƒ,Æe9Š?'I2_]І ™ûÎ- ÖYœ#‚ør×$Ø�5uv�ðR�¶] $Úd×ipá��|pFÈoס€$“–fë_[˹ò ÁÕï&�/’7[Þ»ã�¤ÖÓ>`‡‚?…$÷ª@æ]×ýk¯¿úÚ¿ö_ÿÙüâ½{÷~è_ú¿ò‡~Ñ/ü®WDpÙ¶íE×÷{Ñ:r" ŸWcl KZ®‚Hãÿ•k=4Þ‹¾¤ª«þÌÞ´#¥_À.¼°¤¿ò)~ž,þ¤mb'Ž³Ë 7#Ï{YÏþ:êyÂ}*ˆA’¬ø‘a„f)Ž›®  ÁÇôh=~’üa#AoSÇøÏ‘ãŒ|{<Õ7Å7™û�L˜0ø@†ôåùÓq·RúCJp°W÷#/}å[ÿÉWî|IˆfFLãÞíu}PEQEQ^t4@QEQEQn‚ºnÐ4s™ÍfB©˜›XµH²¼=Ù6Ö¶ˆÍˆ÷vºQÏÅl�IÂû^çDTϤ‡Ì%€£¥¾`0*ÿŸ” ŽY†¼ûú·~Œ·´w‚`>MÑ{4.*ˆ'þÛ}ƒù»qÓ@ ¯—Øllr%ÄYë‡À ×sz¬Þ­?"`Fâp€Xn€""ê3¨àÎÛYúç%ìäÄ9gç�àK ¸@$÷TrýS�>Æd4m^’aS,i@Ï'Ü祚§ ÷�{~ãÙÇÃêýü¬Ä  Dƒ(!eФ¡%#í%6hbÄ}×øõ×^ÿ]áðwüµÿæ¿ù;ï}ßþë_þ+~õßÜ®·lŒPUÕ›ÙlÖrŘÍfÖòŸ*ßzc‚³…¢õ´¸°1*Ì ªfsîT«Iï-Û%såGy—ûŒuž8þ(ëü´ÙRUOßœxº¤X.*ŒI½÷`LÍXÉã²åûáÂÖ|kýOTÛÏ& çdàÇÌ]=wcëA0HÉ\(A3²€‡›ÂÙ ¼4Ùñ”Ïè¥ø<zecMþ <õÑ¢Ñëvïäü›ú»ÌY¤6À^WEQEQå& Š¢(Š¢(ŠrC°6Þ„º®á3ëCöyb­L£Öü(“—ái¢,O>sýõ{¬iîEcñ¦÷ƒqÆ }BôK/s?‚D¤N%hß1»÷Ç�ïy|TYû~Û«I¸LUuI„þ´ÿ(q8I9ø ÅQ@ÏkÊçã '–›¤ê†ê ’vãø„( d¬Dâ8`ñ>�€Á0þ]מ«×LpίØH)ðO„¡J:à1ƒŠaƿߞfþ_JRr%·\˜”Äh<�7¹öñxTBRÀ:&@(Ó‘Êç*½øm4Ù×°Èݤ¹¸¼ü•?óÙOÿÊŸýÜÏ|y±XüÀËïyÿŸ¼÷à=_‚1mÛµ¨ë³¦6DÜK/}×v}»ß÷"bÚNu+å8l°È-LDTW²Jˈ”÷ìøªJÈ ®îäkÂ�ÔvŸ�[�úaW¥hÍ(,áý?.Æ—ŠÕ¦Ø>f[s¨hÊ¥ ÌQ©ñ®ŸÊ îSóT–ûT£ç¾þ4œ(ƒ)¤ø�‘$#~©óÀˆ;�”îÓs%ƒµô7‰©Ï“Lø¿ngóí2ÈÌ€jQ+EQEQåF Š¢(Š¢(Šr ØÌñª®¥®kÉœqýÿèÀÁ@^Ç<¼¶ßó”¨#^ÆÀM×n„šñA¸ö"½U•â_üSûs”‹ÖõI�CÐ@! žC€™ñÁ ’ŠªˆÛ¡‚Ä쩸Ílu$Îë¿NÇI-­SÇâ,;Ò7Ä ;~_«Ù�Ã$ç#0bl¦¿˜�9�à<ˆ°•ýÓ¹‘¼¯è�yHtRˆ$&)'€˜æOið‚„ÀÛž{/+3‘¸ •{JKf9î†\ï˜Ñ6¼õ‚ \¡7ðü…’!7_®ÕМ É]J܃m³±%Þ#ô}ÿÁËËËßó³ŸûÌÿæK_üüß<99ùÁoù¶áǘ¹««¦ƒ˜vßîv›Ýf+$;1²__nÔ@9 c‚Ÿ y³¯‰¤ÉRûG„Óôseð$L µ’¦‰ÆBTž¶?Ùóðés_}ö¹_ãÄ Ñ¥¨ë1à–´upÍ:–±`Îʪ„re0ãÀ|ï ¨’á·œ¬GDNÏÛÑØ|†v(_‹GÈRø¿b¥6°F Wͽ”AW8 pñµ–³ö}�©²*EQEQåFEQEQåÀD ÊÕ¯ç<Û?¯¹ž¾GîeFaHúb~Ì>—$3? *D¦"øÀÖÈ3§…`¤š‹ÝÝç›.T”˜Ý{â Ä{7™íÇçúòžøH‚‚% ¡Äå˜ÀììñÙoçt n.ÒâiÌ¥By‰�Â~!è€Ó õhÉÌ Ã�b¢­²¤uã}Ÿƒ¢Ž‚ã¢DCKv ¥¼À %�B†»$V”Šô.C � 9>HdÒ‚¾bHN#y;ÏŽ?†¨9%õŽ–nÊ€˜8g2j}~EÃþ¹L0l€Š"Ü{¾ì„wÄð™ÏA£´A!Ìá9¬û¾ûÞgÏž|ï?úïÕÕjõW>ðÁÿåÕêäK›ÍöÀÅ~»ç¾ïp~q±Ó•T9†4¸ˆ˜èl±]Œ?#…òzèQ}nVÍ5I[E#”î;&˜— 3�ºÐŒ–ðk¹/çNˆ×ׄçžYŒgîû9˜ò¤Ëð—ü˜c]SÒé9â�$è¡*±m˜P6&턆Æ|E¤ÄQ�’Øã\ç„Óc‘|.P¼ œG;Λý{ÌD¤ Š¢(Š¢(Ê�AEQEQåàÅæJ*æ£PûwíÄŸÆ2’!>;Ð}›XøçN¾:²LÐ�e>ÅÌv8Ký«ô¡h“OI}fJ2ÿsñŸGj÷’àƒ‰@bçï{“RŒñ �d…&Tı潫£nŒ‰Y¤ÎE@й#I²ü‰@!�!ºê'ÞHf•ﯳŸé% øå… ‰�¾¾;eål­zwÎâ/àDh Á!çœâuñÉM3%¼Sö¿h�O±.ŒÈà*gÂM¶\wÍçiÀ5ûþÊ�×ù³®‡ëˆbÔàY‚-Íá¼vfãrÈV´ðAö$_¾¼¼ø7?õÉúÛ>÷¹ÏüÄ­[wþüw~çwýÕÅrÉ]ßòúò’ÿ…ïøèþââ¢ïº³¦Ájy‚Õj‰Y3ˆÐK‹Ín‹Ý~‹®ïÀDhš‹Õ ËÅ«å ‹å‹fŽº®a`Ðî[l6l6[ì¶;ìö;ô}�ºa¬NVøM¿ý·áƒüþÈþu!¿A9©!ËÙâruì�ã�³\}Žt³šò‡ögL‘Ïû3b3ÉEB¡“üé%¼9ÂÿÕsaÄ€³÷ú‰}ÓÀ —y´¢äÂë\¼Åÿô_•7ˆœ¢7<ƒ45¥o²Ïɼî^и;¥¢7ÿ†PEQEQ”· PEQEQ”Aj‘›ÿ!�)už/ÄÈÄ¡?k+hì‰-½Ï ¾¹…}´}�™ÛâEy'rz�ÆÈÐ^X’ÒÆ4iÛœŽ�[i'2‹­QO„Ä¡@‚s�˜(®¦A L»,z�ˆI�Xí»}�âʉíÄüFî b „cØæå»¾ÒŒíp<�¡4¾!&ÞeÀ;ãÌÁ HRZÚí'È] œØEY€„;',gúŒ¤z¹„ñ+MBiG@Vâ!õrˆå|?Å=LéXG,¢�ÈP¥)�O0'‡Š«Z΢/BmôdÇ:�ïK1¶ì)ö2x,Sp @¼W .P…âs Æ"Üî÷ßýðõW¿ûoýÈ_ÿ}³ÙìÏß¹{ïOÞðžÏœ_œ·»Í¶çŠ¥®fu²èOONMS7]oú~³5¦Û·¸¼¸Äv· hf3œ´L/`bT̨Éúo÷b°Ýîq¹^c}¹Æúrƒífƒ}»1°X.°^o®€¡¼£çÞnWüeÓÎGo̱‡5[�¬È.Ïå�øž±Þ'Nü¦ë¶�ÚÕËCàbÃuÎçØ’ñùg¥ˆI>Øie&š/ÑèZB~Mטȵ¯AXd1Q «D\ ÒR E×¾thü‘”—X8x΄šÍêîòÉí'Û»_³st1SEQEQn (Š¢(Š¢(7ˆªª„«áߟ9&ÜD5׋÷A â¿ö»ûD ¢£ë�|9%rf"牪f:ˆã(ÿ 3¢s gŸ§.W 9 âYÙ‚ÄÚ׊ðQ�Oor~x dE%-‡@ù~œß»÷�³B(%P%åd¢ìrù�·å'‚ñöûÄN·p�Æž¿?WJ„t/P1L0ºÎ® R×$×6©âMìó³ÝâZ JMĈ÷2†ˆDwˆÐSÙVâˆ0°ñú¹ò1éÈc$3£vuH(“"Ñ5z¦³£‡�0þ¾$W@FŽôp÷ƒwsð÷„À<Øí¶¿ãë¯|õßzíÕWþWõ®NOÿ¿Ëåj_5U7_,ÚåÉjß4Ív¿ßïöÝ~+´]‡vßÚvˆÐµú®w™¾Éóaìõê{ƒý¾Ãv»Ãåz�ÝvA�Ízƒvߢ®ôO7 ‰*à¦îæö»‘Û^ŠçJ®¸µËgfPÏ>ý0cû/«u#ÔµOY®y¦1J.DR¥æGʼaÊ`¾±rÅv¿ËÏ’îÙ稗F®XÓ,´2²&–™þ‰; ®u¾×òS–‰ýŽé@Šz3˜ü˜§_z²¹ó°h EQEQ冠¿…+Š¢(Š¢(Ê Àf´;«wïç�Dp¢<•Y‚I†¼­^èòY‚a™‚—g;SÒV0žOìÍK÷ß”, €bÝøØ–ïR@ì3ö£„*ggÀX�Ü¥×;-GÂ??Zf³�fŽå ˜ }2U>+Þõi\–¤×»�Ä€ˆÊµÃɉöz#`gɃ(žwp$ ,~EÆüP�)]Ü5æ%ŠÆQh’°¤%!Š;‚cb§I„sIˆïıQ¶v}%†h ®}z?MÞíþ‹û=weîÁÁt´øÇ*Öý¡È4�åÂ-[h’×r¤—¾ç®÷uWh)düöbó^C’Ÿ×¡²2œürÅyº÷n¯Îß#bj€+ÑŠ¢(Š¢(Ê AEQEQå`\]] ‹¯-ïIkµgÙ’ËýÈx“?Œûl:ôwo·¿…:åS{{ë|vâNÐãMž™ÎÄ£Âh:<‚d¶ñÆZ ±;HID ¶öå¾Cc$düQ°bY¸úëAøOEý KqHdDB¶l¿D²t¼’e¿G�Ù'¼“w˜7f;¦ÞÖ‡Žó�Upâ¿ËÖv‹³›÷A bL88fÞ{€q‡d?[H*f“”)ÀH‚Ä×§méxÆŽÇ•R %cz^D¬‡BH2mRV’�(–c÷*�ÄÉ Ÿ³ôIN.bØ1†S þžDfâre)üu¤PvÁ~1wº¶ý�_ÿêWÿç�>ü'÷îÝû ßó?ú—þòbµ¤ín/Í|†ºiö³nâ ‹ÙËÅ Vó¬§X-VX.hf5Œ±ó²[ì1›oPÕ˜k0*êÀV§m�.â7ÈTÙ[¸Z4»“ünŽåFÆ3³GÄáìÉ�Ï´üÙ�À½öÑZƒòÔçÝ 2#Öð× ý Ž_#öòcm�£ã�åbIƒ>µåë˜[C\ìˆ@ HOùç›_£�Ÿ¿ÄR?œ—¤V- ,Þƒƒü^¡«Ê-HR~`̦ø)¤t‘ »n<™mïAÀ°)íEQEQåEEQEQå`…m##eAÜëÿ=šl”˜:ßJ¬ôSn×+2#$URj?\ÔbOeÔ ÀKüÃ=e¢¬9ÒºõÑÊ_\�„„Zépi5åõîã¨äm'ŒHh× æÂfÿW™£ƒ ã²AiX&Á ¶”8'&ÌÙy˜lTùäI1$öð”Ì�ûMšñï3É¥¼l’ÛïÇ"õƒ ßOp£Èª4Ø@ Y™.#J.OÝœ#÷ŸÕÁäm{î2Ùr¬¾vŒ‘¼1h$Þ[’dGçy¿Ñ†#Ü·I°�MÄ6I“î^7&)C¯Q>_eP�7�hÛö¾öê«¿ð/ÿù?÷ïÍ—Ë¿|ïî½ïÿà7|ä§f³ÙÎAUÕ8Y�ÈéÉ™9=½ÕŸžžu§'«~±\ôͼFo @Œý¾Åúr�ù|�ý|ÓcÐ45VË%–«•.â7 {‘ˆ0 H�,Z™ê/ÅsAãm•¶÷"û—Ÿ„��½ýDtŸ’ ìÈìõ£Þ?~} ,Ðà�•¾w50ÓÙìpÂöZŸÇW/ ”¬÷þQA&6Œ.|לWÛez±Ÿ<§‰}ŒØŠ ¦øìJÝÊfòå4ýÁg4ÐbYïîHå¬4@QEQE¹h€¢(Š¢(Š¢Üú®õuĈˆ,'wv¶ß#ÆúV4¤ÔPÁÒ=Ô–÷„Ãûy«CNIð@0%/ÚH3Ô£O©³€S¥…’zÁ}ˆ�U�÷âg´:Ï4 b›ýHœ-øqXÑÛµ[ØK*"øˆŠ]kOMÌnNãnLƒ\p‘Äú_ñ7Õ®ŒÄÔ"‰È‹X«Y$êiD.+Ö��È�§í[Œ 5ÜÉeŸK"FûX‹LÇ/J„ë ¶õi°DºyX^Àžsi¯-¹.XÜv€»F¬òñ6éÿW•ðÁ+!`$¹ùhôŒƒUü³ˆä¹ "ì…bOVÿg7�×·œÃDRŽ‚ÈæB»ûB|²rrí‹ðˆÈ­ízý›¿ryù›¿úÕ¯|b6›ÿÀËïýà_=;»µ½uz«¿}ûN{çöíÝÙ­Óír¹ÜΗó}SW½fƾí°ÝìÐîZÀóùWX,—8;=ÅÝû÷u¿Aˆ€ †ŒØ•N Ø.R°ê!¸gêéEDd¿öȲ¶qàXïp¥ÖJÇ6|æ¤ÙõôVŸ!_’¸¤ôW�ñ*ŒÍ3·uYÌs®PH¢ð(·‡¹ê8ƒì3';ÝÉS’s7RîÀ$—9ûÁE0 8âÚ‹8Ç›¤�CeFÝ ¦=‹fM[b—¢(Š¢(Š¢¼Ðh€¢(Š¢(Š¢ÜŒ16Û×H?ñ|ï0^Ú4�ï Àf/z1Ò‡ d;¥uì9±<÷ÚB1Ÿým�Š£…ø³ H‚ H|´_H3›óqy±š˜Àdm÷Y¦7¶IHdÎ<Ã=)q`u|òA±~}H ´c©\Me�¶D€·×¬ ˉåµ×]�¸šÕ.s5È#>à!?²¬{ ±ÖOz7©œ”`ŒQ–rNcÁˆó)IFoÈä‡ ³÷Ó:É�Ë÷Å"Î"Eöð°áÁ5Þ6Ýd$Åù ûä:ÙÿI’MJÃÛ7^‡ä¥aCÎíÀ·áò�§ ÿ Ùzßì‚(¹oŒ«Åî³´pÁà:Lßt»Yô‹?ûé?4_,øƒøÆú¦oüÈ?¹uvº^�¬Îç‹9Ïç5ªºÚöƦÝî¶{ìNOÑî÷¨ê b«Õ ·ïÜÆý{ðॗt¿aÈà¿Æ““9Ÿ˜â ¾N¦>0ôØ÷%•¥y„ø£Û=0l“vÍîTÆ Ò ÈŒ” ¹ö¸( "zÓO›®Ù€$åÞìûÔ,-ÓjìÕǬîïÀþý”EEQEQ”‚(Š¢(Š¢(Ê À˜ÞŠÛ`!÷@OëÁ1A3Ø÷—õííÆÔÛ9Ñ]Ö1¼Ö{ â½�Ó¿ˆKV" ׯ\�zÊó¦ ãf�ca°·Üwgàk�ûÄ}öâxRÀj§Î^?iÅgÄ{1>éNøwÁY–=Ò²’¸G[øX{]B`eDž¹hŒ(Èß�’�„1Û¬ð ó+™(2m%MLÉMÃ.0Dâí’ÎFb­,& t�G*SP¸A8™ûÁp=ÁëíÁkýQ<yèJ—ˆ‘›6˽͂nÊ#bÀ¹{Ú–l�˜Ñï®kz�p(sá¤Qû`@Œ$Ï …~é ðÎõd·ÝþëŸûܧþõ/}ésŸ}ðàå¿øËÅ¿ü¾åÛ¾í«LLÄÄ,´¯˜»¦id6›a¹Z¢ª*4³nߺ�—_~ ï}ï{ñÞ÷½_ñ…X2ÍëýIvÃËÄ}Ãåýœ<Óæê>ǵլÆÈÈsHoÒ“>2žà$€a¿![Ž]Q�)Ò’¼'‰ã@Yßž&Æ8¶n–�s™!Oê2õ¹ Œl¤—ê�25Gɽ!׿Gã½zeÇCøª{2ÞkuÝŸR‰ PEQEQ”�(Š¢(Š¢(Ê @ŒÄ„ªÇ‘2?ÍÈ.²Üpæà#‰×1H€2»`„L|J­ûaEð0/kQÁ†> ýÑú¤L(ë7 J€x±Úfí ®ØŠ¡Æ@˜ƒÝ~HÒº±6øEéÒ@‚€ˆíù8ÑŸ˜CàƒÍ¬– ìKꥬÅ{AR/Þ•;�<�•\x?ZïŠà®g&>Q^‚zJC ÖÎùNLãFÍ2%òyëPÞ#WQ¼«ƒ¸€™²‹žÞöŽŠ.áÞ/¦%ï’QÒU™¥c17SÝáÚ�æNKz÷$¢Ýh0K|NGE¿`å@Hwíºö[^yå+ÿþŸùÓßÿ»V«å_{Ï{ß÷'¾ï7ý–‘ý¾Ýw}Û‹1Ö³œ˜úºæ¾™×f±X˜Õɉœž�©nv“>o�µÈ¯ÝhFõ�›ÜLXèûÚíÈï¹ÃpºZãMÉnÏÚ6W¬K× Rq°9ˆ¤w+ª)εl·´á‘+Æ�|Ö§k°ÚèÇNU\Û«Ê+Ÿ(c·Az/]Y¡€Æ/Mù™›~ö¹¾ª„[ÁÎoÃý ìÝÊa]!EQEQ”›€(Š¢(Š¢(Ê ÀgéWu-U]I¦,þâBX#SbYÅw±ÙÞ@´÷OÅN/$ÞäÑ€C;i295™B0¹Œã0¤ƒ¥ÔÚÞ½–Là3™3jqN|fç@d3¤_ë<Ñ|§ÄŒýèn@!'Åp±ò°Â³š&'n§‰›^Üö–ûÖ™Ý�Ëed‡q@bM÷Ôš¿¾ÈÜ\¼ Yà!#s$«<9&5í/ój]ªùh¶f‡‘Ì Hlé†$ˆ!›J×ÙÄ%å†È ÷ì¹ÀIDøDt�gHiÉá³).k^s›²r’•BˆA Þ ½g¼;€oÕߦ,Io Ø†Hq�ÜÊ“9e›åz}ùë~ösŸýuÿñô‡?{vvöû%ßý—Þ÷þ=ÝlÖÝv³ÙïÛý¾m÷{&ÚÏ›Y;›Ï»ùb¡7�qµ›ý=ž”Á`(vKþ¯|Þ™žãIŒe9òþÏ`®1råøkï±»ûg\¼èßÒ�\‚4ªmäTäÈE4±÷!° Ž#:òœ¤\´†ã{®Uœ†/9™ ±ãròC°B)þåtrånuÕŸ‰ ¢ç¿ÑEQEQåmGEQEQåÀ•­Ìƒª*y‡&ËØFA?)@k…ûÊé1iʼ ÏôAH×£ÔêÑòŸ¼U>ݹÌmµâGƒléA "ˆ½ ÑX£S³·î÷ç+Êe$!Ò* âE*ß­I*`SÌ<õû¥6»ÝcÒ¤ÄywŽ «™׊ße³ã-çÅ‹Ì& .aŒÁAÑ%@$ÈúþÚ”÷2z—k¢�DœJ¯ &¹Or™…öà»2Ú®J“ËHêXP,ÕJ;øëâ“ê“à•‰ B62÷I ‡ˆd•!|Y ‘â¹eNÌ1(‘P*¡T@º( oÊðšç—D²ð’¾ë¾åÉãÇð¿ÿá¿ö{góùߺwÿÁ_úÆoúÖßn·—›õz³Ùl×ëÍÆìw;£«ø�BllˆÀ²ëëËñ˜+–÷PŒLØÁ åÇäu6�ùÙ3]=¦G[<ßzq�µu\X—˜Ñ.ƒE8ÃeÖ~Yî%Ù–9•P\“�atÅñ"´Fô?KŒÅ k]Ì"HqdÜ|Ä8ÆÆ>Ø�›�TЊ¢(Š¢(Ê BEQEQåÐ4 Dóù õ¬‘ÜòŸ†zc¦R}PqœÈê(D`vµí…’ìt[c^‚�}^ç�’Œp¶Î q«OÄk�ÏŠ�VÿY xN’Âè1NÁŽ×‹Ñ"^˜�ýQb�n�b@DȬN³èQèþü|f¿éámíÇk#K 7¾; ` LŸçöûë`'Çg�Û”N!²% \{1ó\rñ6½æi6¤ÈtÍBröža²Ž©ðŸ�WBà…®SJR7z‰ó#cã xÈÄœ¿Õ;Œo~�,(-ç‘ÎYêÓà¯tœ×PF#8r¸+âŒX-Mr÷€¼ìFq¿fsM…# ‚<œGDæÛÍæW}õË_úU_ûêW¾4›ÍÿÒíÛ÷~ðÎý{_Øl¶Ýv·mM¯úÿÍ"ÜIQúdQ,×�ƒÙÔ¥˜�kó”‚=»ˆí÷©®Ûî!®Ó¦÷ŒŸr�kÌ»Œ|_Œ‰ç�r7_ZÁŒŸBnã£ÝøŠûyÀ�A,ßpð4éèårüs`¸V�ßbîCƸ}žû£ƒ@dê†û¦“šŠLŠ¢(Š¢(Šò¢µ«EQEQå0kf¨ë\3*þŸÈ®R›’ á1Y"6 C§~¯¦›$Û\¢¦,E^pl@!ƒÙˆ&%ÏH$'4sT ‰ˆ."sùclÛ"Åy%mù~ªªBUU`fTÕTö¨Ï¢§`îîíúí˜ Ä˜Øg‘.] á±Eë¶ÀÌá±sN&>*Çò!cÛ«éyY¢¼ÿ0ob0•÷_xÁÅ=“ ËÇJaÁœ@&²{ýNÏ¥Æ\'›öÍBÒ»)ïÊ‹g”‰ ÌŽzÌ™šÝ3Êü__:"–vˆÿJ1Ÿ™P1ƒ¹Êaì³fìsáîÙÑÙKƒUÊ>$Óp�_yLßh³^ÿòåþܧÿùÿêÙ³§³'�ŸT�?ÖEüæñ¼êÕ�nV2`ÄU}°FÈ›ÿè›ë¬-cÙëô­;~�7q�£åøŠñ /ž÷rÒÄy¾%AY× æ�罯7îÓÅåjÿ¯(Š¢(Š¢Ü Ô@QEQEQn³Ù ­éPqU:ç'åÆ]æ6¥vøÑ®½$ˆÿ$ÎE×ftç%Ì ŒOú7†$�8ÇÚï!oÙ¤B4å¢skc/\Û{ìô!çí‚ \f¼ø#0.X�çh@Nð¯À\…dUczkeüÕÝ<�XˉôÑNE¦;f�éã\‡,GçhÀq; L ã®yc 6ðÖ:Áž4‘D÷ùô»ó“¢’yÏÒðQ\.—m™æu—Þ Ö ¼¾¹Í˜ÿð/Oä¤ÄÁ”=Æ”Ò2žJáþ˜èé¹±.æ2(Ó�õŸE`¤§–ªçyŽ�~Õœ‚ Ïwîá‚Z8TF�ɵHG9¦áÉ e¿Dw‡Ãׄ²{ÇøûOÐc¾¥mÛÙ~¿çÝn«‹ø Br7ú7ö0e7™Ä¥1d‘0açXê4öä—ÿ­$tÄÍqëFiç~“–—².ÈçÂÏQü0LÆP”K�cÆ�ŒP’ç˜ÙõgÈ ßº£d RQ ìWèš7[²Èò 17îâP.N´ˆ¯8™­O¯o‘–PEQEQn  (Š¢(Š¢(7€¦i€hf�xÑ/äÝú‹4•¶ÿQœ÷‚Œ1‚�Tl뇃B¦¿íB¬«0ÛýÅ×­—Ôò˜m �RÌ~vYȉ°cmì%hA N³žë“Û¿ÿÇ’Ñœ º€1½1Á.”ôC6ã¾®+„@WÚÀ9DñßgàÇ V,0F\ÿ…�ëÎÓÛâ�Ü©ù”FTûw 6ûVÜ·c�r.¢VA¾d�d™åñòR8§¼>½äRRB£ã¶û™#„Ýz,!¿Þ>ã<ÿã§J7ÓáÌÒ±€²š�SûXœU¿ ) �˜ù_¸TGÃþ4#ÙÏÝËþ~KçË®d²ÙDù"ëœaç˜b0 ¬ @h˜ÆŠŒ�¦+šA1`0Ɉ%!²8$ÿLçc¬4*•Íny�øÍ~¶.ï¿çkoä¦1�Þ/ =†%Þ¬Ìû´ºx |®Nö“ Ø¥ãAzþ.ø�{D'€±`F¶ ŠÅ@ ÊÚ)®!abÅø™]M;ÇŒ¬'!8€ðÆnŸòg.ÎY®úY¨˜ŸëT$a{.gû¥û UEQEQåF Š¢(Š¢(Šrvô"�ÞŠy�îR6t¦äR&ÇLpã?†�€`Œ bÄN¯7ˆk$jd.<;+~¶µêi�µ™×ÏF4 ÉÊD¡NÐOÌ-νõ¹?’(þcgÿÏ•³I�PXÖ§¢{Q®Ùøc8Á9JL ±>9T\{ì |UwЧ—µ¸~…c¿5 0””O@žLK.ÐÀþÏqž±Ÿ•tðc¡0WÙÝ&(ú“"ë�2‰jôtÆîu÷?9ÚñŸ†Fе\¬“ó•<ûÞv¤ÞßÂ&KqñÙŒ¥’©Ã€ˆ‹� <Ù×íÊvû ÷|ôWeðº§6+"ÉA|æ¸ ÉÜÑÄ<ʈþFÜ4M=ŸÏ¹ifºˆß $M4wNcÏÆøyõC&véÉÖÐ˽¥·b‰ßh™,Fªø·})v, –»ìp¤m„~’ò壟±òm¥b2&‡]kÆ T¡Þ=2‘ƒØŠÜL6럙Qq¦ ùˆìñ>»?tœÎ�­9à¦/·N¦��-Î�9F[ømƉ¶ìö‹çGbŸ¿�˜;N.s3ŠÀ©ý|´�NgI�Vò9L÷ ÷L:B1k]$ë2Ý.M. $žëA†g‘Ü’W“~üþǹ¿k\ƒàHž)‘Äha*‚�’g�Â$ œ’ý‡ç[>kI …k›É?ó# »”„$öß>)® eçI…¨–:…¤ÓÈL|rrÊggg¸}û–.â7oA¡ýøƒB” ÄhÏ!bƒ2…{¼¸mf$SÎÇòRîXWœœ£˜Có˜�›pÅØezì*€;À¸×  ÷õmÄZêwƒÔ&Ž%¿É9™rá§7o^§š2Ç^üLpØb 21Sב~îpÕëßOEQEQ”…þ«(Š¢(Š¢(7€Íz‹¶Ûc¿ß›s¢a^qùr«÷™$«—Š,àdw"¤nõÖÑž‚Û.�£ž‚AvB9„ ÉŸòlm²Âˆ@L ¯SYÚeíŽ4sß¿î‹ãН¾ * 2ÿ™Š:ôrý³ÆØób®xl߉9¡Ô²_FÚk7ý@äø•$™ƒ  ’Œ�‹‘9 Š®’ç™Ó«VÙâÞ™®Ãp·º ¬ìÊôe»"šŒbp–½¤„š¤Á¯;¡(Š¢(Š¢(o (Š¢(Š¢(7€õú½i!bDd¬Ü6%õé)þ\rQ׋“’Ô²÷r»lô´Ö®aéöìkÖgÂ}ZƒWœ¨K>BÁ[4S"hºÃ¬–Y (á„lÖ<Û âTp¯±\±ÿ¹BUYñŸ¸�`Ä*ó}o ÒÃô}8žˆ¶êp� dBÞÝJéLq\^ô60!›>žQâlàÂ!ö“‰ÿð™øåùRÊ'3ëÕ]?’¤m/L‹u�˜ÔrJñ_F¯NråýÕr‚w N B\ñe 2Ô逘EôØfÌ`½ ÖåGŠVƒ]éÀwö~H+� ê(‚£u F솳–f çÕb0âÀ°�­$eâ5: ˆýÙÕNÊÄçÁõnèÖyƒ7 a¹Zbur‚Õj¥‹øÍÃ+Úr¹[\õüàØÇÍ}êpåDí±"!ãî£íŒ¬aGõDð72KΩ N îr O.ö4¦„ûÏxïž0r¥•ŽY ýaæˆ;á*ë|–è@€‰u:i�DË ±c¯ÑåÏ� §“+oÞéÏ—¦êfÐEQEQ塊¢(Š¢(ŠrØí¶ ú΀+*œà)s8õ‡¾–w$£à?bKLVà¤Êg “ Hùâ›î…à ŒJؽpê§g‚¹«{œBtøOî>#Þ�ÉfûW¨ëÚŠÿd³ÿÉeâw]clö¿qB“ÍÀ扵¿w< z“æµ'CpçÈ`2HÍû%×Vx÷€+Q¶âvZç2Ô*Ò tÀEv¹LÌKâŸj8E5ø:bsñrR"®#Þˆ’ØÃCº%� "âJ'à a¦8¹­�Þ$I&hñƒni²s?”ØdZ½»&5Jf+çyÕIÙŽÔy@ÿ†¬"„¿ª ÅBdò|ý3nÝȹ ƒ>²1QZ A ²™gÍ\šYƒªªt¿IصO@ìe×ŠŠ¹&i§ >�% ìHD†îWL&9›�Ý~§‹ø "qyæÙfÄ ³“¸ÎÃXÞljý?Qñ©5vlPó<¶ôcvùǦÂ�­ áS:<“&ÖöÃG,Þ45Wp® i €Ôbg,`Ц…î7 —ËRâTÂGö3ÿ‹h*:ö~ÊŸdΓåìÃlâÚÊ0˜�˜˜†Š¢(Š¢(Šò¢Š¢(Š¢(ŠrC`¶ööUÝÄ�D“J¨ßœÿ}>fÕE‘ÐÛë H¨,jHí÷á2ý%)ÀTV˜÷ÙÊ0Î5À‰LlÝ@LŸ»‹ØäS1©(¯›N¶y*3{K~®lÆœ�k¿/bÐ÷&dþG›ÿ<£šÂ¸÷d<2ã %þñ\G¥ˆ Ê0ªÊ·eOÔ „óÄ…€�Á¼![«u u哚ÉcH(’�;+cZ ÷A"ðþÈ*Ý'}ûýÓöÇ ÒRò>p$ÏJOìä}@À!íXñùM;<^+ÿ¼‘DÛ�t޲a»R’v\dÖû9‘R4t7žâM.%Ò6ÂÌ!IÐÎí@¢#AÒ¿ŒÔ÷ÁAäÏ'-w`�±ÇÙ ”ÄßSª˜1FvÛ-ÎI“foD$‹{æår·ÜÆ›]l-v–‘ŠÆ]ùÇ{)¾;p,Ú(}ð’mFžãO‚ŽÕÿ‡w¹{ Ƨ܇0MÈH{~\t¤³³½&Ùó<6—Å‹8K~_/Hžæx[É8Y\]¼ä¶º(ÙÔH €°–ÑÕ—²Ÿ˜ŸkGšÉà¾`25Ñ YSEQEQ”· PEQEQ”sfK…º²ÖÀä2Áˬå GS"K'Â¥O&ûsºdu˜íò…ÒN`›Š¬ÏD÷Tõ”¼¼Ï,ev¡¾&pb ^y—UPÕ¡�iÌlÅNJ ˆf¬@ÌB§´”��y”œ§e8™V$fÞ§šÉÈèJÅÀÌÆ[Eûí"Ö¡ÁElPRFÀÒë³�ˆ5©¸.a·�ú³Õ…›Bi¨p/eÖm1G‡²p½”dtRR[þæÿÅMþvÏFŽœ¾äS"ú�-ÐRœ�LœÓˆþ¸”ÄX�ƒ8Ë‘�R\ñª«(VQEQEQ” PEQEQ”WÎ2¿7Îþ.»ÿ*у‚5Z7xX3©æ*²+Ågü»ÚϾ~;%Ü¡T€¯O/‰BÝ‹ÞÄi`@š¹œls¶þ™€Œeì'ç™ä­[¡Rbzh3S½”$©ˆáÒàK™:?P|Bv{"˜¦n ʱf ï½í¿Á?+Ï@#}§çR >� Ù7 ÆpçSJ4’'ç~̹xM®µAÙ4p@vñ}ʰ¶üÈ®ù÷£BQ™}øö#zMˆ³†îz{Q}ê8‘�lý)‹v9x.>8dïžÌ”N‚ ( ¡ÔÙA’R¾Ô':ml׊ÿŸa`œ�Èîá!Dg€±Kµßï}ßë"~ƒp.$—EA/¼«�eØÉ êØù‘È\%‚m:]ñäËÔHUnB&úgαáDS.¾±Þ�˜\c• ãO©ÕgšØ/}¾'Üš®Ã¤¢�d±÷4˜o»ª\åp…ŸÚôÇú=Vö©m2y�Be:L2å^$ÑÒ?+Q0þ¹2þùAáŽˆŽø™KQEQEQ^ 4@QEQEQnÂîMŽMT˜“ìü¸AŠdí2k8«F_j (’3ßfÛ2œdöSÈO3GSW`­† Ø kã/¹z—³ØçØ6D`Œ 7bŒÛ�c?1˜Ý Yõ&Ø—[ñˆØ[÷Çq‰¦ŒË~$+pb(CX­CÂøÆ­ÿMÔ2(Vj™€0“˪NÚH!„2‹wI¬ØÇ�˜5Òý¢ì‘Ô³§kí’òz¦~óÃÝÊQÜ’•8F3Jß;Z‡yQ2|®²yKÇØY§OS 9è…ˆAb\½�¤à‡¤÷C\€º¶EßuØîvºˆß ’G>(Ã]�]]a9þìQÔèeLئ#E™Ìà8)¤rPÇÔ!ùð+08Îà¸Iõ�]|ÀÚÌ`jâäËßD© oÑ/Ï¿D†0² ºza¥kœ“ `»èzóñœ´ýlG=ë¡(Š¢(Š¢Ü4@QEQEQn\U�Þ€«J8š»ÇÌxò™Ü¹,M4̤ ø}ÂC18Š�²Þ³òËY°A¿ož*îmô�1®;�1©Ÿìƒ*+èÅ?¸‹Äc\V½³"›•L‰Ð,ÿ�€i«Pȱ'ìÓÛö’ Hqû^ä$¤Šõ�Ùø€>ÅRS­qþÿÿìýi°n[vŽ9×þNs»×fŸ©.e)A¨±:P¨3 Ô€ldcUÆ&ÂPeST8ì"ʦ0Ævvv˜v„ËØU¦0 BHH4ê�,¡¾ÉT›Êæ½wß{·9ͷלõcus­½÷wν樂æÈ¸ïœó}»YÝ^ßÉ3ÆCKõ´Ž2‚Œ2&~@uÈn/cÒM™aƒµ¹1Ôubæ¤V±÷Öôݵ€%ñfd ס\rŽ8Æ‹–|,°P̼¡ë(õƒO=éjZÕ†vª¶51f°('fp%éͺª×h¸!ª ®¥²Æ‘Å8ƒ0HÍóß4A$»€™]£ÙK”çPTçˆó³3ßÄoÚž[xQ¥Ë7ã¥Å^R*ú‘6mK¯nl[Ùöo°Q¿ÎîtU{‹u?å!¡+v¢<^büò=Õîcz»ùðŠ©ˆ_-X¦1¼€Ý"3¶´2¤)n\‹~ã`צ¹[BYp¨f·ºy—ö�VÿŠŽÔ¤BÞÖq£.²ÃqC@&RI³/©(.»Eu%ij£èðsÞmpƒ¥¾Âp¯k÷ØÚ,¶¾7�ç1À�,CxÚ oZï˜ÒS\g;ê£�0?×�á¸Î±E—Ãp-2ý@[³©�Ê“ì¸tàú«¾;ë`¬˜%õÒÚ¦®Ûi Wà<=&"¹z¼‡Ãáp8Ž�¸Àáp8‡Ãá¸Ób„IT¢.LÆÉT}ÛŠ_Ê$_ÁÂþå‡îïé¹J¼ŽdˆÊžø·d š° “Î’IèBfÇ¡Ìà+_¦/À<äŒKr �˜É*vååÞ)"“w^ˆH¦€00s¦P#tžSû²+�H®†fH@Êé[8{¯‘@ëy"ýEªÒUë[ÛýE…f7#%¯Ý¸¡Cîû2#™�ª·3%l²—«ÃTew0•ÝZekUúj–•­7Ççv—jq"®qkÕÿë1ÌK’i•3\áøÞ”¢þ+@V`rHµP×+Z^€Ž 5b›†ž�ŸÙ¼Îƒ‡m‚ÿ``iú¥²`òž:%Â�2_³$áèèLŒ˜EKŽ›��¢ ˆ$ÊTbä3 ®®Ç«WÞ¡Š€ùTSͤÿVÑ5™üyƆeÀMÚj¼Oød-Ÿ2ëâÒ÷/Wmíƒoú´ò¼"›lBÌ÷Ò> D–LÎëpcC}mÍÓ¡�eSFtýq|¢�|MT°±3êV|Ö{˜½>ÎÓ­ÚS8‡Ãáp8Ÿp€Ãáp8‡Ãq~qŸ&Äy‚D4BG«1¸+HDtùÃ~&ˆéÐ_½ m� \E¥b½ci N"çL`‚ò÷’¹Ðb÷Ÿ˜%ÕDö7r²V*X‡JÙ²Æh1v}ÃꚥܣEjËÌ 2¶Ùõ¢šûÖ�kË×^!íi˜mZõhóE„´üyá Rô -ÆíØÁ‚�¬�ahC[GAnß¾ƒyÞ#ÿÓÃMBž^UEÌ»€ÌÊç €Åu+«;rYa]~…ðÈËŽÎ%… g»à²¸êIÁ×û ½nßt¹�“˜K/ú°²ïÑèb¬}²˜@‡}»~ÖS¿÷äÿp»ÇW½ÊmA—<8e·ŸœOòÔé+;v�Oéû{-/—öü¤§½{íüî:¨‡Ãáp8Ž�[øÿ w8‡Ãáp8nÂ/îaBœŽZE;t×ó OúížÔIþ®Ž.³óå{ʤyûÞd€«Ê�ð0vô¥"¿Ý@�uÁ²í¢ tõéZ  fs@œÈg*’«åÑ*ÓIQ ö‹`€AX#„R¥¦æ~ˆ0˜Ó}yQQXÄ ‰PŽ’ªÿ³m+¨Jµâ·dŒ%ì‹ �å0¥S ¤ôvíòáSdÃZuw㤠i¤%zaË·™ÒÔtdû éS"€uÚÉéâ>ã·‡Ü⟘yÑ';Kw!#2é%Õp¡ÄVB­[ëužëëu[EÿŠe5‘Åä8��Á©:œ"X°sYd¢\c*hÈtH†vŽºÛ…³»wï`žg�ø&~“Ð> „€PÜÏüpóá…ÞZøëðÙ4Þ+²$¦'xf¯Io‚×úü®WözÒMêª º©‹Ï’§?d'1ûcCÌ¡[WXÏ+¡­£G'›ÃSCÐÜ>û9DWÌ~]òu®%L[kg½ž¼zöìëiƒô<‡Ãáp8ÇÍ€ ‡Ãáp8Ž#L„£d��'2Öí1yµ¶Ûæžw¤4ŒM=uöþãå ˆ@˜+)Z*“[3W c"Îÿ �Z”ˆ|¢d….ͤ¾‘±ÆÄ!ÙÎ#E¨JŽ? (qgÕ_Èïâ0MSºþ4e‘§xX‚¿ïd:Î8ÀT&ÀLÉ A´F4÷€®5™œ·UŠm.zÒ5Ç�‚ÁµÞÖµr“Z5wsPhM©èï¨8Cd—V6ß5E­dx²�.¯ã4–ç+tcµ.ˆãE£¬Ý;}h{çÉs¹k¿k5)u´ÃÀC9ææù2ë¸GmS·Þ›»ÂªXh‚]ŽeÝ1ˆ@…Ôï„5e=RuG¯ûÀbô�GpëömHÄS�¸QŸ7LÈÛh4ˆ³„מ$‹�à ?é]Hø@È’}ýšŸ†2^ïi opd·öu ÛÖÝÞ¨Ëïñ$}\»k‰ tý>Œƒ×Þ8®sb£ui zÍ6ã‰o~1O¯«b&B¼¾PÄáp8‡Ãáøß.p8‡Ãáp8nb&†9$÷þLˆŒ…j6yÌõE_›Y^ÈyÏ«×î‹Ï©#­ƒpçvoHß’ŸN·‘ âf™^Ï’}žªø%ÿŒZÍJ‘DŒ� ¡¢¹º¹´W«;JŒ€*HÊɽ 0»)‰2‘#™Ø„¾ò2‘çȑڲޑ� @ N.…Ø/ò…Ña�•óØhWÅ_^Óâß\ fÎþÃT„ÚˆzÍUâ¤&n@­ð¡¹P®&oýé&pQ Ï5ÞŽÅH`+F2[uu%µÎ.H=,¬öWO»â¥žL¿Æºu¶FHAíÙ²‘Öèb –ÔÕcͣеÜF#¤g†›°@‘+ÝXQN�hí„=ù,Ä¿±Kq†¨wgX÷ƒÕ½a˜d£]¨´àñÑq>V|¿a T ®PDó~Ÿ¡ ûû+! „!ŒBôp.û5Ÿåå.¢×;eÞøþ‰?Å‘ØêR’.Cåz}8k3Dq¥àâãb1­nvׂþ4¸âÌ>læ© Àå^°Ï“è›™Ãáp8‡ãFÀ‡Ãáp8Ç À<ï3ù¨†ì ~ I^ J5…’å[‘œ_:ôçñÊ% õ6¶õ¶ :“ÎF`@F¡PµI…ÐnÉT9›Düs²ü'æúÚØæî*¤¬ š Eæ�3Ñ!L¦:BEAœªù[eµ¡©ªÿ;Zî;—JíB°J&Y˘q¶T§,F°RG“ºR”iç×�Zw£ÐZгvèŠ�ÎoÚªrãL0Œh!­¡¬ËHæîûuÒfs½é•§n®Ñ­k½9°®ÏÔ;%l�ã˙ӫÝÙ'ÇD\kØ€Fç…æØ5/·ø�öžÛkUM‘eÅ–g’³ãEgó¯PH³cd�–È5Žhâ’,J),~BKtÇLj`DVš…HÎöÓkž¸áéÖ¢.¿>ÑCOWß¾=U;ÎõÖ#wUò|àÜë 4*ØöÙ&êÊy¯i¨8vsrŸb¼bŽdeóåql(‰dËrŸúë38V'Á‡>P¬KÀuȺâDqvyü!f¸Àáp8‡ÃqCà‡Ãáp8‡ã`ÞÏà@(Ü¿E%õÆœ`2d¥�Þc˜WrØc…t_˨D¸‰,`D‰\‡­R?�…^‾’Þ’ðåXs3×ãJå¾äX"AÉU/•Ö�C®ŒOœ�RŒAs2hÕò�¬%æJ½'⟉¹’¶Ì]š�$ "6 dç/"ùú%ú`9òš«ñÇúõhâB¨…'j6ð†�*.´¨vÇ5c�׳¼××Xבk-½�¥lEvíÁCÝЕ¹ÑæzöõÏdíóº_ÀÚPi÷ìG½ š»dç‹ê�…õmçPåèÌjœ>hÑÕæx0¬W\ΗØa‚ˆÇfß$ Q+3k˜Ï.Oîwvï@OÜÓ@Ôꋸ³Ù²°_¦×±dª€D€@‚Æ×®ñ¶2ì;k–û\…a6ÓÃ}­c$ý¾b/­×\�iOcuÅÞ+æû²q‚l]ÂôQ†v« Â)´tÙv•ìPq�sÙ1OFÝ jŸ^?;þ€ Ιè.p8‡ÃápܸÀáp8‡Ãá¸(Õë$èªæ+·úE< ±¹^1OÍ;6ËÜ’‰Ô™³÷{åÚ4¸ ”Jw(€Àéïðœ,å)'\UR5;D%Õ©Sæ92©žlÿaZƒDhKóB±f…D«ž¦J^¨¦‹ªÄUÌܬð é8@ UÀ¹ºš²…>QÉ´Oÿ’Æ Ç™È/´ªhéœ »¸…2å1K××b ÖAWùðžBi„JÌ_Á±Pµú'¤ö-Ý^»H‚^WB9Ò�L…ùJ£F‘É�=‰�õuIÿ‘Äò‹Œ#¬ëÏœ–1¶Äå))Eú� ÓeßÉzûÓ°4·‡~‚ºÏvÞº Lx¬ÊµÏ�62 CÜs>¯K›ÔºHä>FU\œŸ#Cæè›ø BZ³ªê¼æ§/m?@y¡�Ÿ/DW<„–ÔÖkî e� ï‹.>©*1-‡8Û±¤|l?÷›a~*\�‘•¶oý_Ø{šò÷N¨pÅî9: èðBŽ©ö#õ9. ímdmÕ:â}’‰É‹!êOTò�f±À¡xkÔEͬ aSé6¶m}�–k,÷ÿƒ÷_üaU9ñ%¾™9‡Ãáp8n\àp8‡ÃápÜP¤¿IóÚÛ=H´Îsn9!›?¢Û,óÚHt¨É´¯è}Î=JÅ}L”·T›ü|s-§®™öDÕJH„:uÕ͆Ø$mUŠàLØ·ãK‘¾ÚX�ÌõpŒˆªPåJz΢¸�DÕ&@…¡¤õ~M(�H†,'Ò&HÈCÃÌ9{½ÐV�N)ÄÃ*ùOK·èÆùÚ €" Èú�"ù�<çªÔªÆ “_\ Õ¬™”©3’+:- ´øÎ�å« �.–FC‹§xdž: `! Pk�Ý"ºqø²–Ak4}ë¨êúãHèlùaÉö.‘ '=‹KD‹ (öþå•D†³bŒéˆ\‚ŇœùT‘lÛ—H)ä!HÁ•`Í"p².*éA…¢�XE‹h.Z‡A¾'‰´U„«!P«0 _OÂ;&‰§ˆda„ØšqÁ@™ÀÕ6ðã: ·ˆ&Œ; ¹-Jabº�‰01x rªùCƒƒÞHÓç‚ÜÍi>ï͉ž’»0ÀsúÓq[ƒÊÉ)§ø€‰Î1ðH×�,zé ¢º‚”£1(íóŒ,†Hù¹¡`@„9ý¬FL@\Û'Á:C£:÷b?ÍŸ=,åéÊÄ}l{CÊåϧfV› H}¦%¹à”6Gô¢¶|?ŠZ?K»=^5}"E­{TªãOúLÌ® ‘za¡!ÿÕþÝ%ùs;—ÇB”.E±'%(Q¦‹<§2Ït®1ª*æ¨8hVåGâ,üHUeù±:ÏáѬáb?O�.ãôø|?=>»YÆáp8‡Ãáø5… ‡Ãáp8Ž€ÝÑqÊh×óîô} xΑ/vÞ¸E2Uö°×ȯ©.ÌFñ@­üx½Jd̹fâÅœÒ Cä7Ëi+&°ý+N…Ȩ‰ÌD)*Àž£Å8€@H•Íéõ&nÈÔT¹ …À¨çk|êIíí¤ÕæSBKƒgMÜz®¦Ž1VQ`„lìöcë¿ôãm&pV¢›G¤>ÛLèro*ßmýo×êÄ�Ö † \= OЮ@&! <\uà—š ûl.°ÞÀ£‰Iª(eíº9jƒ²{QpT{TIÂÊ(¡Šª §ºRô„H³ëƒu˜Èb9R‰(˜//Á|¿APQ(7€—}MUÎUõå_}íÞ/}èµ{D5:Bçˆ9&2z GÇG8>>ÁnÚ„ér¿?züøñÑÅÅÅ1 ÓññI8=9åi Eôââ’ÎÏ/pyy¡#¦Ý%nßžpzÊxöŽœ0íw1 ¾ô³â—}ê»ä�AŠë@^£"€–mnë‘ÅŸKoÊë´B€Ò˜g@z™?vÀî9ˆÐx�(��ù*sæäˆ¸~.ˆÎP™¡²b„ä=ŠChæ“ô(3t>CŒçÐyN.Ì i»Ü�=dÝ_ Êœ³;·gYQ*:GˆHûÜá"XT#$*ös„Ƙº?qzÞ9 >ö‚9 tVÌ9v&Lp0‹"îó^êÇ;åóeöQ1ÏIø¦Y�$‚êL’ÜD’Â^qŸÚËñ ì£ JøÙùÞWü‘Ý´ÃÑÑÓ´ÃýG·Îî?�ùÑ£G8?¿Ü¾}÷îÞÅ­Û·ˆ™1ïg:¿¸Ð‹‹ó÷qáœ_0ñfÉŸ»óœ×(38ð3T÷½¨ÉVâR�½ŠÎ¢óë.p8‡ÃápܸÀáp8‡Ãá¸è«ÜGWÛZN6<Óÿ�`ëÚíj•�©Öä´vZŽ%NU�b­‚Ñû‰GTĘòÅ‹å`lE~¶Ø�©Â>­Åh,þsE½Ì(b€I”l™�¸ä"ÛÓ80”ÓçšÎ�3TbÒÔ]1×ã«B£@Uc‹<¨ú©üŒ˜¸��}L¾!0%÷Eˆí“S̼01‹nTÇ'Æ4VsTHÌ¥²ÁäÏR‘t\`ž¥n\ÒÞ ÄY# s*ŸGÖ…´§Ä¨�˜\ùKrC-ÐG2D˜# ¢f¯«^íc ¢ŠÊ4jÞoÒLÆð¡—Ÿù‰ãã#œŸ`ÚMùsò¬® *ÝgJù͈"Í.tàÀœ<Ú§–¤QÌã¥Ë=8ëHŠ(0µÙ÷2‡Ãáp8ÇÍ� ‡Ãáp8Ž€Ë‹KÌó%ö1"JñõÕ.ÿ]Çtw-ù߉�¨VÝÃmqø’0ÍoÚØK´[’Z"¢š b4"�”ºJýBôªHË(g$+sec7_rÌ1´•@ÄÌ!ý#â£óÉ7¶ÿLñIš�εU<«%V©9 t|«¡�F¬Žû7’Ž!‘:ÉÌ ¿Û>¬ðk± ©]Ò·'“¢Æ> ÍF›)ÕNh1”Ú/šËõºØŒÚëijø_¡çÇñE–×!ÊÆõÖVõú±…°£¶f2IÔIZlƒ1K0‚‘|¤!™R}ëÆé[T»N×çåy¥n~›…wyn©s¨÷ªó­uBlL¦Dæ SAy_!3d#GÌœÍq�ãáØÇÇjÜŠ&”jsÿÐ(ˆªI°%€rvÉäû*Y( €ò `ð˜ˆv¦D-¢f&Ó6!Ø( ûÜ>s©d¼S¾—hžiåïE ŠÁÊ5g^¥ÆÅ€šZFâ �9Þ$÷G¤ß[lÕ}uº1B°"³�§ñÉŸy¹Z>Š‚D«Õ¾Æ$“,&ˆ9zFŠ‹fÓjYºR¾WîGÔJ¾§êûüœfr;F­ÃÅ´? õDÌgcÙ.¤üL%YÀÄý4ò_ÊÏ0‚´×¬v£ûØQ=U’—T4 ó²àD{qˆ·©[#"hÎZ¸A¨Ä ]G·ù± P�ðmÌáp8‡Ãq“à‡Ãáp8‡ãàñÙc(Q"âœþ ]*ÿ�\íß…§�vï-$`$?»\w,Ù“/Í…€‰‡ÜöDbg8@„j+NÄÕÁ@D[¥šj|Bc–qæÍÖŸéÏa˜§V¸nHæFܸ‹¨£B¹Ú^û²~¢/ÀY ™#J„gsJ°D´&åžÔª¸Mä@!­R¥?š{ “¿Î¥‰T�,�R§]-ÿ¬&Ï›VÝò‹à¡#‘¡¦pÝY ³§/ý‚m×Hü·5Yc†¶ØŠv +¹_ ¸f¥þÓs�ú~sÓ6-ëZ©¤S·uÒæ¼…@è"Ûš:}‡ÕA´s´Ë`¯q&&£\¤ùÚ�Y›o2��çP»®¨í l´��–¥^ç–ò^ƒR–WçF¡ØÇ=ÎÏ.p~qî›ø B"ïÊZR¢ýÚlÒ¹¢ZG’6—«ðµ1¾{{PFZmÚËh€ÑM¤¬ÒÓ#�»Í™äG˪oïËðÕ¼¿”"%ZÞ²ÓuOPYq9²Ð ß;¥|/mìTÅ|¨åëÎ’8üâx#vû z›bª!Öu&“Ó‚ö9¨š>_Šõ¾Ý–U²@P³€ 3îÙZD@#”¡È.RÈ}i"°Zͯö:F`·yíFî¨ê#ŒkI†}±­IÒò5ß‚òoFÍÜŸ¿Û`ñ»Íög†�‹Ãáp8‡ÃqSà‡Ãáp8‡ãàòâ2gú*D:V ‘ØgÞl0Õó×39j�Mõ¿½„[ûb^ÈþÀ!‹zréÈúF4XÏt….¢’¨ ‰3˜'„r[¤'f€! °”Ù,¸TŸ²¦ u´Vj·È…DÔˆ‘ònv& v,©Š 1lCg㮦]ÙB› fZu}a{Lµ-Q#~tiãßU“w‹að‚/Çt¬ˆ� ‹Hm]~à‡Ãáp8‡ã@U@Ý_´3 íK‰Œ$®ewk�å×3Ý×�MmC³HÎb…VR›9ÕáQvP!Å$ZXØ›_´"W6¥ŒfNúÌl*Ì·:I‰ÄÏ·(¤ƒáDÍ0ƒD–ãXkù³h@Ǫî”�,àÓ¼pTIGþ42—ÁY@�ƆÚ{†e±|™*ýfÍ\œZ.{j_‰N f÷>Ô9n¯“õEÓS�Àu}”é:GwÖßëç¿) +ÞSZZcŒ0d±®ÖóZó±00c´¼ÍèóaãVï‘c ÷2½àa}zˆJp)²µ–‚}œqyy雸 Ÿøêã²]?õGMµ¾Á Škï«yå½é/�@_鯴e-æ¤6Cáë"¢îµ„¾‘êÕYCfHÓ&,çvíÞè@V¶†(+I+C•þ‚üf@1TümÑ­íP׿þ™ÿô¿ð‡Ðáp8‡Ãáxƒ`‡Ãáp8‡ãã!ä¼{¼U²6Vº�¯%<] Û¡Šm]P·¥ “l9eCÞÂuS PÞï ÔØ«éO!ÎëùÍ=ÌŒNU£Ö¦ŸLœW1ƒ ™ŒÏý*²îùÚ” 80B`©è°Ž“vÇ33(põÞÖF^GËaí-ýaÜleg¦vëÚ°²ZÊ{„­Uß"¿»ñ5gÖÆ¬1ØO zâc—!�7k³…º6û(Z{�–óŸî9¢µ6ÓæY×¢u­°Ï©Y;�º€––!ý3×·¯=×ßP¢[g;>f0kKתüתþ­Õ¿�xòOǵÊÿm7€õ÷ûø•ínŽÄºØo´¹3ëZ Ñ@†÷ôŠáí÷+ó‚>ñLüÍâ?û£ï¾ëëÚáp8‡Ãáxcp‡Ãáp8‡ãàx7ÄÙr×bY­MýЕö?ƒ:¸ñ÷/ E‹í.ÅÊž 1L¹By8ºTTçcR<d²%$µk­dÁâ!’k0 |t?f­.T*?­}?âÖ j—“ ‘³ F)�<6�©›WB¦‘ú"j~ç¢år[b·'} ,�ä¼PJ8‰ºAª?jž�<>Åê½MuË�̵r<» ÔË�uêªO@¯Îd~¢Ë(õëåšwE·ž©+ìïIüæ�`I·mó�5_çõ�p?–•0ì–|šmE¯)üoërÑíÎ+/Õ'˜Rlmu”�Å5ôæº88À@ö�Jköÿk笸 öÜó½+Àòýñµ­c—¯ç‰nîbŸáŸÛµ9²ÜAÛNöã­«,â ¶`‘ öŸ"/Vr8‡Ãáp8Þ \àp8‡ÃápÜ„_ÜÃQæÌ—äÃLR}ý)ñº:´ý9‹«Ä!›—…‰$eb“#^Nê¯ÜWœ7F¾º`°œ×EÇ0©ößÖˆÔøh7‚šgnÖ:vÔ±¥”‰ÏÒ_í\¨2ä}5mA‰D`6Äijµ€L•§v$Éb¦22T3ëI …PŽ8ØZ'†u®Ým�Æ’n^®’Э:%Ê<œâÚ™m9½¡Øåf�ÿô¨FJ£î£Ëˆ^Þd@ÐÖ#1’ÿ”Å*0c‹î>M¸ÑÖs´�뎩UÆCcÍ3gß·kp‰BþëâY´×M€€‰ƒoâŽ7ŽdÏoù°]ÇþT²È°ŸÊJ$À6®cÿ/Wl^[ïרÝÞyíGã©o_—­ó7ìÿÅšáàýõÀþ½fÌо=öÅîp8‡Ãáp¼1¸Àáp8‡ÃḠ¿¸OG‰R�3fÚ.Ž+`OnhO"ZK}{‘ÃÄ_³Ä¯§%Ë{"pµúï‰üDjÐðo¨B6$©æ{½v‹ÖØ—&æÀƤhG[KúF •ƒ®³‹ëÔüù2h‰ÝÈ_+oFº\s£_@<}عఱµ-˜_ж,ð-ñ­J[+ÀoˆîL„«%÷-¡¿Õ“£ÐbÚÜ ý4nÔ‰f0TïSÖr¬Èa¨‘ÿd'MÒ- z±@íðPý_½hM Ý˜ +D@à a·ÃîÈ zo6ZYåàs½¬î—áûõ=ê*ûÿõ=gyŒh¿¿Ž{”ªnÛÿK9¥wÒ÷f´ÿ?VÅlïŸÀÊÖ»°Ü¹þµ®üõÅáp8‡Ãáp¼!¸Àáp8‡ÃḠÈîjò¿×Ø+‘ÏQ¬å¢o%–SwH"¬!J`ãpn}Î "™DÌÕÆT|Õ ¹jsÍ™z‡‚Po›Ž…’ ÕŽÚ‘ª‹¶”ï39«¹Ê…¬Ï¯uDêP-]O5ÇÇLü« T�(Ò“E¦9"fnþfõœ Zë„P�ús•yê†ÖœûjË\׈dâ¨\k‘U'�ÑâÚ0T}«fò_†åw€|W½á¤×{U«:dÙ¯ØÝ_‹úÊ$=5¡És¥å^ÝÜÉ0‘ÐA¼ ýóEæa$ ̼YUÆâ¹¶ó�� ÊÚ­BûÜS?w•üǪ[ºG°� ÒþzYhDaB˜ÜÀñfA°°ïŸk�uïëÎÁòÙKŽO"ãgÉÆ1[b�C"‚Ñþ{õÚŽ¦+Ç®¾¯kí]ž'[3 WÅí êË×7Ì ÊÔÝóµîp8‡Ãáp¼1¸Àáp8‡ÃḠ&�–@róÆÖ_à©U)Ê^¼4�Íå›ez³%nÄ=8a™ëj�o’à�±Ö*õDTŠ0˜“h€L.@kç3QÒÝ¿¨�~é*hŽ’íÔÅØîke7©"“Y[uu¾GŠ Pˆ$¢F$f7Í"mÄq©ø7ÙŠ$é®Ðê`RÝ 9܆‘R}5´ÚFÛ81íÐÅìõ ÁVþW­¬"U#2°öÿèªÿ«£B½è¯T¡C5ûS^¨'¨¤ÊV3ÿX©Ä¯Nj³À·� ìyåzëùëO±½\�'¨D¼öçR3ù_ÕlòßüwØJêI6²c\Mí%ˆ±;:Ân¿Çñ‰ø&îxó!#¹/ýœŒUþåm<ýK4ÀõíÿûfèæwH p`«çêŠýÛo°"8ê%Ð û}Y!ãuÝA`Ceöúå÷]·~ÿÐ+~�q8‡Ãáp8O 8‡Ãáp87aJ,°ÀPÕ[íÝfÇ¿ZùÆÚx·H€úÒâ\Z+†¥K R5ºšwžíï`Éùä�e½µ‰ €8e‰gÇ€ÖžL_ Dp.¢.-ËCÔ×¶”ÖÕDÂwÌh9J²¡zÞ—çìÆÐìþ§”«þ qžmÿ+™¯€d‚µˆªø@4Uêo¸tão„…ÿo" Sõo«ºË<æn4Ò§ô͒æֻ¸˜õÖ­>a1u´Úß*ÂÈ“£Šµ…út/c´’„ �(ç´ êÔ=íº=òª­¦*YjF7‘$D`fcž÷ ¸Àñ¦![§\eÿo¾Ö°û5ç¹ö.cEëVþ[dÿúûMtuàþÒ?š]e¾µÿ?�²2~¼ÊSl—WÙÿ‚\s¿7Ã{Ë—¹Ãáp8‡ÃñÆà‡Ãáp8‡ã&üâ¾ +Œ)2€Ìxgòu32×ÚæR0çVô~;m;ƒ~y¿B\J&Hᘖè†d=]G±ÌE¦üe+~be1ÀØU$Uógú3ÛŸÛ¸›s�ÚžBõ—ªç4>­R_”ÀPèš*Ba¯"ˆQZ•}&æ™sºÔÈ�FÆW(‹d¥¤Ó -tœZ[um+`·ÈÜr_s]#oè­Þm¦|'œÐ^`ËM+ö:¶ @í iµej¸Ö¯ÅeB[ÄA`¨)y%¢êÑ–Õõ×Gè8Ñmž;⽟ »¾E‘DÌ Aä±p(í&ZNÆbh¨>´¶*‡€ú2GÇöûÂÎ7qÇ›•»›Æ÷«öÿk \°JKoôã÷×ym´ùß~=·Hts_’ä¾íÝX½¯[ïo]eO ¥9¼É[�kþû†áp8‡Ãáp¼A¸Àáp8‡Ãá¸S©ö&„™úÒ|=LŸv¤.¸ØÑ“µË‡-DJ˜-áO)L&’À†,* Kµº*$ç×Ò}=^ ?�ê?[ž¸uÝ:m5ÕÚÔù­ŸdóØÑ�IB&òE’u±s&"01˜±)’F@²õ¿v2 ¬ÈãˆôD»™Ë—Œ…æß侎æðõºªã¥ê‚±ó[®›ìæ‹ßCµ1·~¹&‡VèõçnµÓãëv1_ë:²íK³²xc}uÆÅ! ­£º0 yŽŽ@_‹EèÉÄ¡�Cõ½¢=÷V< °H¯ð94~[ _ÙWhmW¡ÅC¥F`Ðo9>ƒÉ7qÇ›€î›öÿÃŽ§ƒ·}gÿ5Fëþ5û¹¢²Ëþ_ó"z@Beíö7aûºl�¯ËÏÆ5«ûZèÊýuãœÍ)ÔõYT7 q8‡Ãáp8Þ¸Àáp8‡Ãá¸à@Ì‚€ÑÖ»¼Ò3v™k!“ç…HgêíÄ ‰Üý�Þòv•„l×L…2Vª–ÍÏíµ2�ì—r°!áU™XIú"^0Uöõ>Éâ |_£ê ®ÆJ�ÌÈU‹w"Î×[ÜÈ_É¢MÈÀÄꕃ£Ää�PˆâMry1%f ÆW›GCâæµŠ 1sRbÊYJÚ¹ôcq eUAµÏª+o£y"# Ð7‹^®óîz�ói[s�Ö‰UW,éo]¬».PÝà  9 hwkZÌù AXHÃ¥‚g•�[�) €ºë¬¿î1®màòK‚Ë‹sìç=â¼_‰/p8ž ç?ñ‡ów2”œë_¥g–eË¿^jKwèb¹?¹ýÿÖñz@ Yvt•ùÃ×ä s`XÊù&V`õîOIÂ놓ÀÁÏ6]'wp8‡Ãáp8Þ \àp8‡ÃápÜ$K{Q"E¨Õ剰ãÑ·�ÆsË7¹ú?“ÿ©Ø;‹×o‹Í9B>“ꥢ—À�µŽà¥Š^[õ>²}I=’9¦ÚŸQ*eë€|M27ODkj_é§BLA´{‹½§˜Û¸,Æ«VÿK®ØÏôÌÌS@œÉñD&©JÎiÎn¥:ÚTêS¶M'ÍuÔª-fy,Û7¬p/äHâ…ÑÞO•šyFU³`Ì«o¢Š®–_W"ªÓ€LõÚ°Î †.¦¡¢uá@öõC þ €X!ñ›¦§=®ÃE§.RuuX<*Ùµ¢&&Bë:dãZAU8ÓÏçz�¯® %¬&FÛz¯�1k`}èôàC4LF]¯£Xá€Ó‚¹GŒ�>ÄþòQ¼¬×ñfa\s…ÍŽÃqÒ¿?¾^¿_/‰íÿ·,ý¯zmkµ·¼Êþ­Ê¾tCÆGOÖï±EöË5¶‹ÕÏ +*¸âñ~’(�|ù[¾Î‡Ãáp8Ž78‡Ãáp873¡ 6<é’Rß`6M9™Lo%rÖp{jþ¸_‹½»ëPç(Ð*ñ󆘶÷k"‚\™¾B*Ûh�Z½nò „œ©íêhPm–õö:ª CJ=b� jyÀH¤qs0mbî©MR­ßKÅ;�#„ä€|œ igÒ—jœi¯ �R&à¯AšPÇ€§ëq;ŒÙå0ÑѺ¿Œ•‘äcZ¥©.âê´90ˆ=Æ�Õ‹hÅpÿ5rù:ýß~]ß„ç.­[³‰‡0+A5¹)¤h­¯•ntÏ@uЉıµ½Gµ²³F%]«DZX� ­Ôé¯0pVÔ‰6Êó;ÌùòšÃ+jÚA„#>|€#ÔŽ7åƒp\G+¬·n9 qúä;„ ñí1ºÁªo½óy¸€mÛü•cWß?Ðå€õªý5ûÿÍv®Üo1¬‰ÁÜþßáp8‡Ãáxóà‡Ãáp8‡ã`ž÷ˆ"ˆQôÊjÚ5.qcl_Ë’ÛÉ:œ^Üšö€ÌU¨‹ý®Öù&€ˆÀ̰d£L]~s KgbµXñ3 +b5´ZªÝÕTÅS%L™‰pë!Åš¨¶›˜ÊýДû,f,(¹âê²P2áÓð&ZŪ €9·?_[0Ȃʖì�#nUïTúVÆ4«5*]DYÐâéjE•h^3‚Þ‘¸7"€ P†27¤FèÆ:Ìvû}"ÅÕDÛÕxsdV8ƒE%¿æêÞÜÏÌ`YWKþo·‘4;WwOezdOËúîàòp�X„•T�~ì)ﺱå˜rã#>x° .?@W욎�oìRÉù*…Ü>\*q€ŒBÉÇ\ÏþߢTî?Y$À!@;WA«‹²’ûº">@ÿQ¾j¿/+d¼n —ÞwíuF=ô»‰úSçp8‡Ãáp|¬á‡Ãáp8‡ãàìì""J1f«ãeˆ7zßÔøf’R¡©º»T!kŸo_« ã—ˆÍLÔç÷”’�|»VÈjóFiOQt6Ú*á{/�D´6�€€ôOHru¿öÕü4^VMÖr¥®ú^ªÑЪZ‡¶ºØ.ä¿J%å©d dG�J #EˆJ"~ QN8‹Éy qé b$ÑéDéž}´;u‹ÒtÕ”?™Ãê€âŒÀhlÏ õoØÅŠ]½åÿ먚E™ß,kG‹;„Ž�2q ÕÑ~Ùž¥«¿•�,zŠƒ)O‰&l±k(9ARˆÒŠP5ò¡0wZ�Ñ!Æ ­¿:"9#¢×ìØøŒ5‡X':  2m¨>¦�­ Ë…ª÷(gA¢Ä³Gg}DÅ÷¯áû±¸—Ó›“!•[f3^nóU·bJ�ûõ¦ÈŠô 6ÑõsÊsuðZ‚îs««Ì·öÿºMÔ�n>2¾wÝE|Àþÿ`ÿ¯ùPÈ¡¸‡Ãáp8‡ÃñTp€Ãáp8‡Ãqpvv¡˜\ÉmCº¶ÿµH·©¬€”"’¬â¹Q}…Œhê%/>Wg#Ó­*­¸’,…‘TBúK~!'3[ÚÈÌd¿*öòÒâÎU¡Zµ¸D*‰8¯Õ銤 XšÐ{6Q@+d¸�ïµ \½ òdCÒW±´Ú´‹´êÿ2n�{€J"�%BU³kCL"€üZSpu(}aa(+ÂDÔ òDô6±C¡¾·Š)­ÃA}1z'ÿ0dÑá¼øñn‹WȬ½ÚîÆ�[MÈê²Úa)~^ÁXæU x¾·D=P¹�¬”VQíWy{ò]MÅîàˆP&¤_(¡‰qš€…˜ÁÕ¯bp 0že2êz6³YüN£aFDÍ‚iÂÍOQõ|ã,Qû œí÷Ì«Mÿ lÛ×é£S�O ËǺÿ&ÈÆ Vié‚~íûë¼6Úüo½^[´úzŽTÑÕæmÛÿËúû[d¿¬\Wðd©MC"Óö-û‡Ãáp8‡Ãñ±ƒ ‡Ãáp8Ž€G�Ρ*$9FáBŽR£æ²�}Ës¯ÇP@é'")Óšìðk ·ô„1�«ÏÉš”ù}�ÄD‚J±á¯UÁÉa€¨É$·æÖUw5.¹m�H§Z5/¹Ú¾V° @ÒLf¬÷ ³ffD$÷+�s(ˆ|œB�b˜©±©�šÛ)‰kÊŽ¤  æ+ S:6“ÿ1Α*à‘@¦FÅ7�4öÔ'@¹)!Èʪ�€!}Évô¦ŠŸVl¥+i­t�ø§ Kê5+êÆpÓp¾^«2¿F˜–’9õ©®¢üúBPŸ ]oò•ìl[Qb¬÷ã,‹^ ÷‘@·Ä™¾A„A}ÓÑ;¤Å+Ì`3—è/Ñ�½¶ñ©ë›ò,ª�d‘qŽP4ñAP[‡D`c‡@]KìÀRýÜÏüøÿž„ÿÓÜ[?Úæ<鵆Fú×DVŽÑÞ@3ÕmìÿGŒäøhÝŸÜiÖ�yRûÿòœ‹êöIJí‡}nûQYœ¿âN²æ `_+¢…ù§+£|(2`Í Á¾Ý7øØ×¸Ãáp8‡ÃñÆà‡Ãáp8‡ãàrAªÊ�9ÄóïñÑ ­Ç*ALXb&ó �ÙW+'M€e5˵*ɪžªÕ}±íoD(@ĵŠ’*ˆ![ŠÙ™A D¨«BWÑžLÉ̃ˆ€ˆ3AY¡ÔhQdáB!ÑQ‰•BÞ¬œ+“K7Š;€¦˜hI‚Mê¨0ˆ¹fDK9§U;ƒr›tN ª ‘ˆ(‰1 ™mÎ3ƒÑÜdQ±ŸHZ3¿ù`5q¨D’´{”÷†ìøÚèéÊ÷nÿKRªŽÛ°Î,ËÝÄ“ò™U›¢eNÇÂ~S³^ õUK¬†Ö_I gQ…Ä Ö„½1A`eÄCQúB4”â_ݤ&ȱvþºôöß$iùnyîk…¿®×—[0ÑÐÿ,”�F´3ŸœàMâ±­O{?ý·áŸqQ€ %çzÅWé™eÙö¯/{ûÁɽ¦@½Õ�kè1d)¶ª•ù²ì¦ê@ø¯”Ú L"‚nŒ‚<å¢ßp¸Îâ]ÝãNü·>‡Ãáp8‡ã�Á‡Ãáp8ÇM�TA¢Ä¢àþÍVM4Rʦ&×Vì‘! W*¿i廯fÒ×�)w¾ÜwîN™(ô¤G][7t±:—lÔ–záÇ«jçf¥ýÕõ‚ ÿ¿¼QW}¿Úkèßž„*l1QÅ!¢ë‰šç¿=7i=—�Á(À´­*¨=DíY¨j˜gÚ ˆÒ± @¨ Y3nß¾ b¾þ.÷fì”;è›pýôïŸ5QÀIÞxsïãðvy]Ö_¯ß¯—Ä/M²ýþ¡×lî}µ²þ ûÿZ�¿rTé�êJ÷`*öõšÄ;–öÿ ÝÖð± W¶\ >V‡Ãáp8‡Ãáhp€Ãáp8‡Ãq~qßí Äh‹G.¨Ê•ô»‚€£$°¹à­ÊÙZ•w7é+¡;sÿVM]¹¹Í7çç¶RÍ27ä,�íáܦQÑÌÌÓUÔt¨”ÏW—h#á­Í®YÁD�»1QÓ/A¶OO™\I÷éí’i1$‚6}cD‰¦Íå\²ÝaÈÿæ–�œrd‚ésÉPHü­š(©mkŽ Z‰£J´W'�|l¶u¨æèˆZVnµqU7ú–¯å\lSçv¶¹×Þ¿-ïõÝXÛÃ=G1BÁ”{*åü-QÁÒy¡þ7F¿¾¦æi"ÎNÔžw�†X�„‘P™‡…Al|Bé\õb›&Èß¶ÜãÖíÛ8ÚíÖäú �“mø |žøú&¶ëŸrU�» ÿúò–3À [õéÛ�$¾=fËAà�³@Ùë®kÿ�@×Ãçož£Û‡²ÿß]¾®š¤‡Ãáp8‡Ãñ&ÇÃáp8Ç ÀñÉ TF@àÐ>†¬ïÆF,Vj�ÖÈôÑ>œ:‚²'æQÉ.Ä%S$ò`ª„‘¢Æ*§÷ÌÜD‰ñl÷ÎÈ£í:3Úñùude1µ~XÛü‘¡(l UöÅq`�Ѱ¤(©©–VSÍÞ²/ÆÏLSi–¢^"bŒ9_º�U­?Öæ?�›ªý !Ÿ¤ ˜æWÒ·³ü7¤¾Ô{Q=¯U³êzV@퓆<71@7š( €VÅ^^³NÖMbé E «Nøí\]s' …`<ª Pt|äšb†Vn·˜lZ™þg‹ò-羑ڪ#È©rßD< ä|4oÝÈé¦~?P’îß­W¤ÚÆ=7¦ GÌC` !®&ÏŸ„ä§�³íYŸ }ú}zZ"ŸÞ„k||bÕþß|/c•y[–%ï*ùYTú_‘P+÷Ÿ,à�ÀžK›‚%´íqiïo†BVf^eIÆ«n —ª×[ø:�ýzõªt‡Ãáp8‡ãÍ� ‡Ãáp8Ž€[Ç· B`&ì§€Æ:fB°ØØ ájƒ�ö^!·ÉVéz‚úCIfÔžSü&hUÕI\PÞÏ×ÊžÆ QÀÌU,ÀÌ™&W[*ßµ� F<@M<@]�¹DADÒ}ÔŒ S (ª¥;3 RÄšûÂf\9�wzOIÀšÂ Úq‰�@f®ÜTsL°Vþ‰QJ @ìÈvÊD00Øù—Æg«}¬ÅP»W‚fœ­ ÞQ,™«K€E¶¡†ujqMœ@Xf”«ëJ)é€^ yНÏëAƒ�¶Æ–wµã?¼gcèªÖPï®_¯O5 #çóÿêž@}»—ƒ4ô™ÚØ÷ûAk·UÑŽšùÑbsaÄ5-⣖„iÂ�ÁÛ”7ç˜�%ôšíÐ+Ú|]QÀÓp£ÿtºlVû—5ºPªÿõZû–¨^èD×Ï)Ž.Û×¢–` }‹ëÖm~Þ"ê�.£ßÁu»q•ýÿÁþ¯Üçªý§gu:‡Ãáp8p€Ãáp8‡Ãqprr()ñ„))ÈTé# èÉ»Jê5�ï–#ž«çS%}É_‹¶êX͹‰ØOܹ d²š“X¡1ÕÊôD¬\‰ÿ–§ÞÄ@«¶¶ïL Å= G°¡°�†€R 9TRUS›ÓùÆŠ’ô•‰¡œÈš ̵}’­ß«Í:ç61çÑlã¢æ(/,àKÕ´ˆ@4�áÊ ô$îf„½Ö5Q Ⱥ%Chi­$mÄîŠWsW*j*ÇÕ8"ØJð-¿}ØÛÚœúôß±æuÌáNݹ&ß»É$¶;¸…´ÖC`,˜|íçpõ^ËâÿnøV›g,üÕ¸,Å:y=c«fx¸4µ£ÈªuМ>º{è¡øï`c)2ÁI”ª¤//÷øü�]Õì+'èãW ½¯×èëÜPºU[þ‹Æüµì—[‚UÛÝÞw°µî7^mþ·^¯-ªq++ïéú>±¹sÉ�÷uûú@/x�Cg¶p]û½Ù Ïáp8‡Ãá¸Qp€Ãáp8‡Ãqp4í0�8`tí IS®†äC"¢ ùßW— eºÝ’þùZ}¥ð M}•{"ZÄ•lÌ„9s;®ÜÉZ¢—ΊÀªˆ8ùœÄ¥b3‘“ÚZFY8ÀIê²>‘»©§šI°ÀL•Ä/ä?2ITsÑ9ç´qŽlɾD³ôÔ·–ŠÐ\=�«ÿGÒ„ì Ó˜F¯«sô"€’ñ.\D帡„Ô2Ä¥‡*ä õ\¦%³¿ {Þ�\×åF+°J&­é®Ò,”CìXéY¾3ƒC0uúíÜVÍ«Ë+­ÜC×HÏÚš¨C»åû˜e ÷®Î ´l1 ãЖ™}`c4µI²8ÁL|‹‹ÐÚU¡ËË‹,žèo¿Õ¬7ñ½�glÿ‡œ®ü3"P¸›¾—¾éb6ßëÈTËÂþßbäëGëþ´O¯ó´öÿbãZÖž;ݰí7=.:$9pŸñç-÷€òz(Ì?]_0Okÿ¯Wë2‡Ãáp8ÇSÀ‡Ãáp8Ç��‰8`YN»FØÕàðÎ~‹3kUÄ…ák—èˆd#<(¹ód…”möµÙƒ« ÉMP]hÍÝðcµ³¦âè¬ü9„œs®H¬P〄"à�Ïk=¤Ësv/!€8‰ ’͹!@nC&PC˜.‰xRÕDŠ—è…Ü¿J›J"OתA—ämvHPÊŽmîÕfÉ›¼úæª�È)…$ÅìU²�´[Q�”¦Ì)«é�vV÷ZIg­Ç§6ÂÌØ÷NýËêüæ\`ÖÂ1¤›ÏÁúc¡õvëç´�$ ÌuKûM.ø*Ib‰ø¼þ‹åwçžPf6oÜ:qA¶³ ãÈ�á*Æ’ ŠÔ~æÞí»ïûô÷¼õ=ï|î…矹sûî�ÓÛ÷îÞº}÷ÎéíÓ““»§'Óí££pº; Ç�yÚMaÇGG;Ê…�œçyÞGŠ€âòr¾B¼Ø_œ_\Ì�Ï/æ‡�ÎÎ=xpöèÁ£³G^ü𣯼úÚûþ#/ÿôû?øÒÅåå9³ª^ªâÀ¹ŠìEô\U.ÒkºWÅeœç‹ËýåÙ+/¿tö‹?ÿsÃBÒ'Z˜Ã²Æv•þUÕûOUÝ?=ÿ[êy_÷»ÿe aqˆ c„Ä1kDòÏQADv1)Q/D”ETªðKPHˆFˆ¦k”==p9‡›ÀKßò§ŸË½Ú°ÿ_””ËúÐêáØ‘-Kÿ«^«ç¯_öíí)³öÿ«Ä9úJü-ûÿ­_dƒ´_ÁèÆŠDoÿÕÐ^Çö߉‡Ãáp8‡ã͇ ‡Ãáp8Ž€¸�@ \].ëå¢ÚÈÈ„ÑÓªPð¦9y%j5`a9 ÈVõ™ ÌîÌŠˆdÍ�\UßY‘wŽ}«m9¬­¼äÊõLº®Ø¡Ã\·¯ÆšÝ�¤6�ˆAÜlÏi´K'€˜À!UþƒJLA4qÒ­½‰ü9΀ $P& R:xÍ’À2#T*üAO!T‚,g2m˜J"DâT…nªïÛÛ}:wçÅgîÝzáÙgo?{ûôø4-2“ÛΡµQ°­2—”gÒA0MÓ4M4ÀéñÑq:ÿøÀz)–ð¬Ÿ=¼ÿák¯>8{åå—|ôC½ÿ¡ŸþÙþÂ÷ÿÐÏ~àâbÿ@ \ѹâøâh>ytrzëѽgž}øòK>ûÕ_ùåËk.ÈëâiD¸æû«ø–¿òÿ%øÆoúæ* êÄ'£¨kÅ›fÑ )³›�Cý%ó9¼p&ÀÆ�èÐUiöÿO9@âÛc¶TtÓþ¿÷yŸý)Ÿðžw½ðIo{ñλ_|þî;NO¦Ûé(I…ÜA�½9R ¤d·+€`7EP„5©b<-ÎìhQ ¼fòLMn,k²÷ ‘нۧwïÝ>¾û‰ï¶Öñ"�û¯>|éC/=øÕ_ýÈý_þ…_~ù¾ÿî§~á—?òayprzòðù^|ðÞO}ß%DTfU�šçyŽûýE¼¸¸ˆgçûW_»?¿ô‘ÏxRÕÊúkO*¸¶à/ÿ�ÿ]½æ7üKÿªªqŸ(•üöª”#`:ò˜z u3k¥îF˜ÅÔ.éA¹½è¢X|Ã*«,KÞµKdQé/«D¶y_¶mü9ól;Ø÷iuRÔì:(l¯×Jí‹ý¿Á:h#°öú r<ö�€á:6}ÛôŽÿÖçp8‡Ãáp¼1¸Àáp8‡Ãá¸HÙó ìçjYÅØ Œ+‰Ï�V©Ë¥™jÜw&H8ûë[[q`6ÄNª,Æ&Þf—“±ÿ7_ T©T“ÿÞHrÊÖÐ-Û¾õD[•²b�.­UÒ1J­t‰ÕîTˆê>ï=�[²¹®¶ì¦Áƒ©}ý^Dk%(“1:S« Idš4Asx ÖÞC dðÍWsï2Ädb¨/ê7[g Ô$…—¢êt0Ê–(^´qI�­;\ [Ïj~X°£ú&>wQ:[ýu›ýíÆR~¨hµ@z=F¡�phsn#ª@í�-nCæDÌ�y¶«ÖþvmÖ+Ñ(ž)·í#D˜ïxÇÛðë>ý½øÿ‡ßñ›¾ì‹>÷·Þ¾{z:ì>õûâô‘HÈBØ�ûÂr½4”‹�¬ßæŸKT[7�ò3 ³9—Í&ÂE0¿ðü½·¾ðâ3oýŒ÷½û³!„?ðM_†W^{pÿW>ôÚ/üÔû?ô3?ü£¿ð?ô#?÷óÄtA KΡ8WàBæùüâòâüâüüìö�;™øñG>ü«û']–+[ú“ŠžÊàþŸþÀ×þîß«Ðhó�F®=ÉÉ}Ê #¬éž‰âÀR"@ieûw¬•ýN·bŠˆC¯õÌoUô_Ñõý¬<3Û"jVþÚ·¸®SóóUU÷‡*û¯³¸°’¶Ó>Ïô×ÈUq‡Ãáp8‡ã ÇÃáp8Ç @*rU€R^2°A’.Îêù/[AXˆ@*Ùáù¸zÍì&ÕThˆ–£Fè%›üô¾©.Ä]=¶Ï¯/äw!ì[Ur# ÿŸ On¹Ð¹º×VZç ×*wZ©­U¤0{E)ÍÕöjÈP¥ZÝ*hmR1UÝ"õÉî=˜Jξ䲈.IKÑ2ÜÉd»#ÛåçˆJäf‹L€UûìjÏ.Æý •~—*M"]V…Óf}ǃ-b»Zᣱnz ¶ºMäo™�—¹u�ú¢è£*ãÌ`Ä3´êX�Ÿµ‚Û¸FÖKYcjžEÒfñÎÎ Z…jJ½«@†€O|Ï»ñùŸÿøê¯ø|üö/ÿçq÷î)yÎÏ‚'˜Uœ –¸•aø #Ÿ y+S?У�Æhç/HÑdý:¸ù>S®8¢‹€¢*v¢ö´ºhŽH/>ÿÜÝçžîÎsŸùë>ás¾ñ_üB\œ]ž¿ÿ—?úÁŸü™þÌ÷üÐûÿÉÏ}àC¿¢¢�c)„×§0=`÷ßùîðjáÁ¯~ð—/ðt4è›)¸öýÿÚ_ùÿü‹_û»³5ÌÆ³fZSöoÎÿ’É ª¥õÇÜöùÀ¡ ¼ê•?Ñ/ݬ Dô°iyøvÅÿ(Øz½¶Htó~¢«ÍætJ¼¯Û×/÷¨²ˆ§$à·4] Ç�']`‡Ãáp8‡ã ÇÃáp8ÇMQª>'ÁÙÙc^ÿCzŸ_¾á°ß“�Í{|q)t‹ AA•ÌdÎÄ&v*y]¯K&§|�´Ü ¶.Öd ÇsåË¡NVÂ¥š•µÕÍý A¯†ÜE+€¬óªU(¢HGœn[5½Wúš¤UXcIX’—Šx‚Šè@ Ê`�¨\|Ét7F ªÒYm/�—„#ùŽj3t•8RHƒšñMõþ[•§õ ÆR¾¯ó^ɹ®ãØ[ç÷¾ Å®þ©™",ÒËûõ×Ö”hrbØ$ �È¡8°�_bãzÑb.tÌPêìÒ«ˆXqÍ(ë¿q2Ïž¨&UŠXc|¾Ë3fœ4¯k"qzz‚ÏúÌ÷᫾ì ñ¯üî/Ç{Þó–lÙÑ'8�� OzY 6Õ=p@Šý6¤?#3–’ùxâ% @| ‘s ^äŸ/“0J/‰éOað)8œ€è˜náÄÇŸd�Aþ“Ȥ-·๧ѦEm&6>`XUÇÇG'¿î½ïü”_÷ϽûS¾ák¾ð·¿rÿÑ«?õs~ÿÿø/üøßû‡?ú#â#€Þpû]ïù„ûÏ<ó̃×^}íü•û/]\œŸ Æ´–ëq§O*xîßú×þ Àoÿš¯Õ¶Sg²¾8ŠT—±ô7‹ˆ@\«ÿ«$?ÏÒ7QìÏæ{½íå‰ìÿexÞq¿~Ì6¡( ½_œ]V·Sݰíï·øbè±|_VÄÜÊëE æ‰Iýî¼Cìû¯›º — 8‡Ãáp8o\àp8‡ÃápÜbòå—>rkY×I�t_!Ù^tALS#á©YìÚU!3'�C#7+IR¯ÛW¹�Ußå5›ù^yê½ò;ëóÒv[ÍßÝ3Û“·þ/K*k²º)».UÓ©jˆ±À0„¥Ý’;/¢=£TD mHê¸X‘ƒ%}­pBó¹jPI·è29ì:tv� ¬ì» Tm‚Uso]Ó•µµj'�á¸F굉¡�+]¥NiqM]9AvÞ¶¾¹YØuTg¡�zfMU²SWÎk'&±õÎDK™Œvs§�b'Ê÷Ö- Ï£ f?tkÉtFós^µ²ÜêW﻾×Ú·µ>=ù¥6Çi£m_ù•_™ž"nÏÑ·}Û·ù/‚‡Ãáp8Ç5á‡Ãáp8‡ã† ÙËoc­H¸Öhù`Eµ%6mù¡É'Z‰(_µU óH\Ö÷(èSëS³ò×zWòÔ’ ©*\IZu©%uƒ°,]¤jÏNPZ£³Û9…hUÙêî ¢‰$¤$�\á�¸FJùÕjxaŒ„fsWˆCt™)MÍB[`‚V*7©Vwênˆe5±6–e‡žXâÜ,Ÿ«QBçWÇåªW.ÕÉ+k{mÞWVDŸônÅœ<±xº:¥ÖÚ‘Ž0®7cã_Ÿ—1‚AÛwÓ¿Ñq£’±Ú¾v�w©’&†*á™çžÁoûª/Å7~Ý—áË¿ôs12›VR%0ã›®È<¥?70'ò$BæW!ç¿9ûE`~­µŒJ˜ó„$€†ôœ+÷Ç5aD/¡T‰‡¾ãöÙª¤âÀ…«"`†Æ‡ÐøEš�$:àcßvÏá4 B³¤'nÏ ¯P¢Q°›hú´O~ǧÚ'¿íÓï×ÿ¦oú™ŸûÐOÿ£ü“ßÿ-ßú}?ððáã—úÀcy¼ŸçGqÞ?ºsëÎ#æðèÕû¯Ì¸¾#ÀU›Ìš Æ|Ûßü_¾ò·}µRu`¡Õõ+ÿ#¥�Â%V†L!=]å<�·S‹û,íÿ×öômûÿÑ`|ÿÐk0ŸaË×s‹d;;ÄÚÿë�ÉSº½õþÙ íU·v¼•ãå@Ã6®¥W,Æ5<¼8zÀ{<´¯åW~%¾ýÛ¿ý¾ÿ6èp8‡Ãáp\ 8‡Ãáp87…T˜¦‰8„Ê|õ’€±ò_M~»B‰°N¤ŽÄó ª-yùo»V%Æ­qù‘ŠŸ@¶‘¯íÍô³6âMmE{q0D}íUbÛ!ùµÄåµãÇž-»bÉõl¹åú_5Öøõ{SeÝ5§TXg‘@ŠDœ\újÿ6¯Æâ?×¹VËüR5[ÄÚìô« ÁTprE-’pB²ÈBW9<[安#r﵉2 0ô~�•5µ$® =oý$ÞÿB�ºS¿Ê¯&¦š|€¹Ùã37!@‰ HÿØ8Eôã—*¢›Õw�XóãΘz@;´{Û®ë8)IQ@« Ö’?ý¼›&|ñoú\ü›à÷àkþ…/Æ4Q"·UZ5µÎè$ T,÷�ᯠ@ ñððç1Ÿý,°ÜOtGÈ[2¾|/¦lÞ¶ä¾µ6(ÏLÈí éX×<›kZ63@0'ÉÀ JŽ9š@f¨¼Èëù�ìF@·@Ó³@¸�S "Zœ� %JßrT;Ó¯ÿôwÿúßðéïúõßü{~ë7ÿÀÿöþûÿ{~òWøÇ~á‡pÁ_¢Ë)„ "ºœ¦p@mU4Ñ©%Ö)³ïå8k¹OD·‰hG9Ãy÷T•ï ºx-ŸÿÜxŒnð嫈€™IDž];÷zx÷íÏ^feŒ`Æå¾<H„ªrrn@òZ+JeóÜQg—\nN.ÅB?ïx¢¹ ?ï¿ÆíæÑ¥ ÕöbýúžDs�ó=cŽT÷k»/9Í@m܇¶GRìgÆ^¨ûV($¦½+FÅhcu]{!Ì‘€­cÌ#TõÖ­@ûH}l�3šn¾‡}6Fͱ-±û�OÿÿÁÚšûʯüÊOr&"篾úꃗ^zéýÒ/ýÒ·úoЇÃáp8Gƒ ‡Ãáp8Ž€b—OÕÞûªÒ—äø�éÌÂ6[ØJæ‘?ïÅBöQ ¢«Œ/ÕÈëäÒíš ÑÞ6Ÿ W—­£Ë %G�«î²Ò‡!XE"q“Õ´‚¡*ˆ€–lhé…CÆœõV€,ÍÁœEL%Oa`ˢ%2KŠP¢°0e¸‹SAµâxã"¨¢‰$'Åšå>޾ޢ,Ë7×*ùÁÁëYzK~²H3¸î¿îB8ÔÄÚ‰2¦ ædQ^„–ÔU°äy:"¢`Ö*D€êb}Y̓ ÿo¥Øb$ªø Ía{h®¨ÎÏ$*­ä_­dˆÒÏo{ë‹øº¯ùüßþí߇·¾åm­’]4—ýÆVåŽlyO;0Ÿ´H ûG�‡?‡ùõŸôQæ×¥ºŸRu¾ qvµ°Éx/¤{¿Y »XÕ¨¤; ¡@Ý$¤ß× )5 ©yÌfA­ýõg´×T}½|œîG@§ £»Àt �˜Ig8¦ñä|oQp¦{�&ð—þÆO{á‹ã§¿ð‘—^ÃwýƒŸÀßÿ¾ŸÁÃÇç æ*BaæÎYeBÃs4TÞÇo>yïx#Ÿ[å³ëÍŸû–;æÙ¨÷ tÏL_�¿&P«õ½.¹ô}ápÍk\uÎuÄW '¶Þ·sxȹ`íû72çãÚ|Òk\cã>=;;;½ÿþs€ ‡Ãáp88‡Ãáp87‰€ÈÖÈÖ]üµ�ÓÚ*Œm¥-QµÿN?÷™æÕÖ¿Ö¤7r­pþL£…½´˜e˜[RÛXò7®œúvå¶wLo±…¦–]É“J²&1„kv+NH<«.}®³µtY�+4E"@Œ‰±Rã©ú×’ÛÔ� sÐwHMe»æ¶r¶v/õî6öÀ|�®À…½/UÏTcÒ˜P®uVDb§¨Øúó~él”ç/-ëuë„%Ö*ü­¿YGu©�„­"Îÿy^J׸á•öû3߇?úo}¾î«¿(U²+R•{¶àOæ÷µ˜v`œ òèý˜ý8ô⣟‚x—[²³?eûü<謨yh.(Æ&¢@h¤{þÇ£ `xæÈ:]”óÙ,À"ÀÔ©Ÿ´ò Sîè"¶c­-¥Ò\} ½8.Ðn»{Y”؆¤‰�¤˜INo}ñ.¾ñw}>~÷ïú�øÇ?ò|çwÿ~úýD`…° „�×#FIâ4Bß’¿íYØ~m|ݾÿF áñ>Ç›�³³3¼òÊ+xüø1DäË^|ñÅç_zé¥W|d‡Ãáp8Ž8‡Ãáp87"Ša aêˆú–Bžˆ=é]T/IyCþ¶p­ìššS@ÉHöÄ�$"æ®*¾^˜Lt'’:Uõ�™ò¦²µÛÍ\»˜‚07š¯Xå™\õ�9®ÙÓ©:±JD1ΈQjå*‡d©ß�ªC4õÍ_Ó!P ÅfÂÞìà¨Vò*ÒY5/‘Æ”ˆ†ÑËïÙùæLĩͮ߂vw@®v'sÖU”uá:´/¿K€*U—Š2.Ú{Ý_‰ÅQ›•®d—@•g|óïz/¾é«ß¨€)´ TJó>M¦Ý1¦£#P˜Re«Î�y†‹|p"{A�Y ²Ç|y�/1ËPI�3QŸùef„i‡0ƒ�ŽÓú•ˆùòög�°ßŸC÷B8OGïÀÈ~ÆÃó ºSW òÚPÚÃ: ŽRÅ9/qùðÇ ÷ÿ!dÿN¹=ÝMGŠ¿¡ì<œ«æÍêdÊ$|ž§…3€!ï«HhÏš×ëÈnƒz?^ì/‹½­å-´¹�ïìWŠâŠM›Çöpr™óƒ$l SÐt+‰‚äµ#€Ì¨Â‚˜\8_ð9ŸŠ/øœ÷âW>ø þÖßûüãÿíç1Ï’E[!0DP£Gˆ¨V¬§®÷1kB€C¯_õÞuqD�£‡ÃC®×q¯ýF®ªâ_{_Š£Í¯�@{è _k\Ë———xõÕWñÚk¯•÷€¯ð—ý·E‡Ãáp8‡#Á‡Ãáp8Ç €ª€°›ív»ôb-Ï^œ¾µÊº/~Ö^@}e|=w•œ§Bã£�ëZsëÉÔÅ&2²òÿ(•üܲê3ù[›bT ÖξuËVMÛÚàÒJW�Üh9éyÜ$FÄYe†*ªÕ6 VÖjÇÞXû—~µjûb½ÞòØk„@ßÖ¯>‚@?ØODOxnrr&‚À¬%5Å×}|äöjë/µ<ûÒV{;8YíÖ�ñP 'p]’ˆ6ú‡'°Ð*(küo9Å7ýŽ·ƒ9$—„À NêLœ×jT1ï÷àý%.ãœû sÀîø¦“cðt ˆbÞ?Øë D�j"u£L¹²9†bšøø»£S0M݃I€¸ë³d!B8BØ#LÆ~qo7áö�˜8w¦Ô~â*pШ8>½ƒ·¿÷Kð–wn&…¹‘ÞÕ"]ø'�W¿zörμß�Â)€]úžZÕ½æ�LØOSz¯ˆ$ÑÛþÈùx2î�Іz—²;55P=ÞDŒ6Ú´o .%\Ž ýš¬1bÚ ´øÓN‰Bã„�ÀÓÝ|ý]º»dA…,Š˜¼ëíÏà_ÿ½¿ßø5_ˆ¿ñwßñÝ?†Çç— B ìв´úmÙ·¢¬``$ˆG1AÿñsØ>ÿºVöªŠãæ¹[äøu¾_ë—%Éô×yo‹°ßºÇuÆâº–ÿ[ãs]ÀÇ ÖÖey}¿ßãþýûu}d|!\àp8‡ÃápT¸Àáp8‡Ãá¸!HÕð‰ìi¯hsÑzÖp]D=™¾ü»z!ÖÚO\œ²iA…UtuâÅI€¸Þ¯¹´JõjK.£³ñ'SŸªÖQ­Ë±¸§ý4£{CxèÒ¾Ä$ôUŸš£’å¹§6²2YëZÂ!YI V¨P­˜o\·vÑ•H«öá6¾aœ!ãŸO¥_Ô^G¶xÏ×]ÉR.Qðdìámv¼™Ô1u`�®k¶v¥(h:pE±¦˜„ƒ„þذƒërí®ZÇ~ÿ× D#!çO!Wv% x�^žã2î//°¿¸$‚)`::Æ´;SÀnw ˜±—šÏ_= hb„¼~hbPŽô >B˜vàéOe¨^Bæ$îÀÁ4!a::ïŽR܃„B"Â4ï\ˆx�ÌŠÓ{Ïá]Ÿò[ðü;>#‘ð±lsžPÎ$;À|ðÈâk?…ùÕï‚<|^4š®­¡Uå‡  ù¯©úŸç”so…ÄùûL’K¾wzÈP‰õÀé+±ù¹îHÙ]ÀŠ_a�ìÏý Ö®_R«ˆHq¯-ød5_…WbKÆM¶>$Ù­€Œ8`X¼i¿Ør ¹|=�+ÝO÷À| ‘�¢^D[Z�F‚{wŽñM_÷Eøº¯þü/óûñWÿÆ?ÂË/?3�9í%À’ýÕ%äÙ_»kγÄñXÕ}¨ê¼¼¶Eâ_õÀªxà*r¼|_ÈöCç­]ç:äûÖñO#TxÒ1¹®પþ­÷oJ\Ê3Àçøo‰‡Ãáp8Gƒ ‡Ãáp8Ž€\Ћ'r`®¤{«Ä_9¨È4:ØŸNcá,ˆ´U»ûýò�Ì5£üî:¶N¦:¾#Z-òÕX§£#ý¹s8hbSi^ˆïâY  �öyí¦-�3A7��.×QR$cwª®šÇ‹XûÖãrIAòù �p!;QöìBÞÛÂzúßþ™3«¢ÄF ä¿�3k¯®­·&ê t_Ò«Éú1nÂÄV$2jP´¼!ò¿?èÓ>åYüæÏ½�xq!'«~�-6 H„îgì÷{Ä}"ÿåâs;d EªôˆˆPÌP„‰Á™æRÅ<�'ÐÒûD`Ò¬¼¡,˜Â3ˆv˜¦ ’[H��Pp‹ïØšøj�Á¹°~j]°>é¸ò'Œ˜ß/4òߊ²� ùš³.ÊýmÕ?Ùo‰û`¢¬Í?FQ‹Žú·òØ'ò_rÛr³ !óC€vÀt ÀQJO�d‘B½3NOŽð/}ýãë¾æ‹ð?ë?Â_þ–�›Ã r| 5'“ô˜ö.[åëÁ<:"�Ÿ†ø/?_·~‹Xwü3…Oó!p8‡Ãáp8\àp8‡ÃápÜp%ÊRloMu{¥p yÎs#,y]HŸ!³^{Û€j_*÷AÃ1h|p (äm%grÔ¶%k9öÅ6¿�ø¶ih¢ƒò};ÍB_ѹ�ÖNdb׸ gÌ­B8�#wUöuœŒÀ ¹å+È ª¡õçÙ1Ñ67¥" æt=‘ÜFÒÓΙ”S‘d¥oÚ£�9¯}W=�mý�6ÆV °ÚîµkØåEªôµ_ºæ~£óÁÚw›ì¿QX\W#ÃLøCÿò'Açô徃HB/�ýBgP>E˜Ž¡2! eþ„@GG¿÷¾ßð5_ˆÿé¯ÿCüÿþêwãìüJILTœLŠ+@zÌ–ýkvëeÿß»ÉîD¼ãc…�Š÷¼ð »—_~yï#äp8‡Ãáp¸Àáp8‡Ãá¸Hüf"ÿ¥Ë½mÙ×%˺û”É[í™ËWœ �Ü*¸—Û¬û+q^3ëM•¿©’¯4–Öë@&•Š»ª©ä§ús%ò5åh~�ˆ@l*W«÷=*‘_Éðâ º´NÐôº°,‘ý¥¢»t D.P04ëÿä` ™ôÎs †d,BTª³Þ?UÛYN4#REáfQ^. J Ui£�÷Y åÒ" Ë™Èö­Hß:dÉ•U.oi)¾í% ÝjE»¡š·ÿÏâú›Ï®4Xà7}ö[ðë>éàäÁpñð>.qÿ(ñÇ H$hâÀ/©8±Cr·î¤ Âüˆ2¹Ì‚yȬ˜÷ŠiGØíóa:¢æ“æ¨�Ö¾Ù§sÓ½ÂÄ N.ý ¼×T<.„£“»øÔ/ú—ð®Oÿ=‰ÄG®ÆGn0 Ö`š óæW¿òÊw'2L'ií&€Ž@¡4,y=d+ì@…¸Md4$Ý+ÎI°"4ļ#”EVÔ.*ù_*þF)‘!É» ûKP²-Êj îÖ¨¤Q®{`Ý*ù¯yì×&Ì>SÛ2TþsymÊq Üú™Ÿ~B@#ýûg¨=àÈBNm‹¯#Æ)‰.¦Û`„´7'¦·p´›ðû¾á7ã~Çà¿ÿËß�où[ÿó>‚ˆÀHb¢±ÚÿI„kï­‰ÖÎ¥'²®q8påšZx;€_òr8‡Ãáp8\àp8‡ÃápÜ(ñ¿Ÿ/1ÏûRO?UÈþô}!ÿ¹óÿ§E•¾ku¢fo­¢-¦ZÊ÷ÑF5>ÀÈZÈ¢Á¾^�=?5ðfÿO�ƒ+$~!õa«ñ©E€ºk7hC2«�H×U°RÓ! Uÿ3[�D"={‡�Vm¯ÍS?ô7²»Ö-—ÌwãP#T²Ø 9td<”ßSÃr×ø…:æÍå`(¯_Sb,Ö Ù*üÒO:ì@£Í¹qûoB‰á<;P#(Aßæá¥kñ‡5AÇF¶•™ß:Ú1þÐïý¤<½ bB¼8ǼÝ_ ˜@ˆ4Ñ �0MÉ¡Äp LS¥pH®²$*d®±íØí!»#F(6"ÑÄÕ‹&S A&D`bNœ2•H{J4ræÜI>ñs¾ŸüyÓñI®ø·&0ï=hÑ×!ý̯~@ÄÇBΡ�‡� ðDP�J&ø@aê'…$‹j�U’^+ Q³FÙ,Îdw¹i÷L¯,\æþ}µÖÒÍùÊ&Úâ4hd¼6á…]~]õm€ØŸ ù_úC†üïÃEÀœIûr+ âæ¢!$�Qö¨Š´r�•ø¯÷”EŸm{EÄð…T#Ä8 0S%ûÛõµ'ÿ»!Ê"Úœ‚^D`Êó+Ù_c qz Ëí'ZQ‰<]TÎwL9µq]Ó¯§j坯%Á\{lÛ2n`e�ìÒ¾ºQ?Óõû¼ä~ûo~ÞöüTЧ¡û \ž½ŠËÇ óœÈü"(PJ\6 „ÀI|ÂS"ã9‚q¦(Åܤ„@@ ÀÄÞ%w€!x"01D˜³pE‘+së¾ ±×¬ð»6q&Ç)ÛÝkµû׎ä˯Ո±<ý†ºHòÖ°s`ßiÎ ¹ÛÍ¡Ä1è0`ºì‹Úêý®Jß°ëƒgújÕÿuÈÿ?Ðÿxj«ð¥À°DTñ¶&Äóû¸ �*ä ¸xü*.?„Ä eaûÿ<„…, e-i‹o`GÁ�"’}{îeZã‰ø§¡Á”„�¯ÕeOªMXRœÂÞõ™¿ïüŒ5“ÈÆf?O:Ó $>€¼ò}ˆ¯|oû¿ÿœ­þ+q^òæó3®hßæ—5;åsžCn°CÍ&¨þ”Ú¥E�ß·¤>™Z0öùU<�1Vä×Ê{´c¹ÍY»~¨�ª&_'-i6ñVlP7©a£µbCþs¾£Úä•,0°ÏNÕÈЗáYëÚúöËœxÐqdÌùâ$’È…ˆñµ¿ýsðe_ü©øÏÿâ߯wÿ£Ÿ€æeÂB÷Œ”çÏ>ÃOBÜ_7À#oú¼ã#âp8‡ÃápÔÿgîp8‡Ãáp8>Þ%eÖ«®×¸[âS¡•˓⒭͂%úªPµ¦ß<ÔœÒqY6rhUò-â>ÙQ“í U‘3š ©Ö’÷ÖB‘ˆ€T¥mc©Šhµ#­X_ÉÞÙk£–ÛTlºKÕ¬­ò·çf‘a€HŠ#ÀPEÄ–m€"0@í[šçË�øéV¢o�Ôˆ ÖœÚzZ¯‰#ª”¡9`éX0^Õ®Cœº%Ô¹"èÁeg¹ÓCþ*‚ùâ1DJvºâòâ.Ï/0fͤkrg &¨ä*üÜvQBHŽø�LyM1S*ô@ ±�Û•M 1™3@’DÓ3Ëí±ƒd‡�”ñì;> ŸøÿŽŸyG⌥ x±îàé"g�û߃øòwgõ‚±©/俵Û/Dšè¤#ö ÉÚz`Î}*þÇëuöv×+û‡µ,i�Fþs¿Swë’˜Œhi¨¸]lÔ@]Ì’ãPÉn hä¹IS>U'€a×®Û^MÌçÈÀ9 Y�1óyºmà {Ü»s„ÿÿò;ñý?ðiøýÅïÀ+¯>B!æý‚ó<rج>k×xß…Ž7G>‡Ãáp8G‚ ‡Ãáp8Ž›"3(„ñ�®êš`ªyke¯!—ŒU~©å§Æ�wYé=!]Þç̱Q­P6M1ä­©RWɹÓÙV;ß4¼´äã)e¨'›› 7¨ÞFßY²P+AO…PEOrëZ}­þo÷Е9©·)â‚vò¢RŸ³]¼€k…wãYÛ±õŽ´ñ>F 8 X‹òt9ªý%Î&R@µs¥rÔ(<lN5±F¯¡Vý\2¬½�!ùׄ×oz÷†ÝJŠ W &Ñ…ª@fiÑì…Ï•ÄÃj&üK·–ãȬ`%`—<¡Ä( ³T! D¡û4‘21,�æ"ˆjÖ vǧø¤/ú&¼øÞß“ÉrÛá,< G@̯ý âËßDYZæ/rí©h±+¯YÓSylŠˆ ÿU°ö,–ê~Τx}Ð"аT¹ °¨¼%za†Æ‡ÐË— ç/AÎ? Ù?piÚ4Â>`·» 9ytòÐÑ[vÏá¤õËMKñÁ8VãXÅ%*A†k[„,´€±íïV©íOxاj̉é5¹LçÅ|¯é4�Ýe;7^â >ûñßüÙß�ÿú¿ÿûø_¿ý‡%&/ŽüX†üc úCn‡œ;®ãేÃáp8‡ÃñæÂ‡Ãáp8Ç 3ƒ8 í0qèx¢TñO­z�YôëÂÀ¿ÄîFÑìâSF½±"ç¢_sH„¶ „˜X±‚…!�$`H=J„< ©_Û‡Žç � ]#ž†/TíË™[Í~!¢;[~×�VUoî{Ü— k&é�–œˆ9YÅ'[°*¢2ˆû.ü º|­$¾®t݆wµøÅAB¤«Íï]%ÖëþK¬ÃØÓþÞ-Æ¡ÆèPñoÖX±þoëvm¯I ÒÐX]6t¬¯.ý&ÍQ 2ê=ÈœHm�j{ntÎ#É”Üõ !‰!äÿG®1 ^°¤~ǼøÞOÂ{ËÃÑé;‘­L³Åý´ƒ<þÈýýr#èíbà"Êd2ó°à-éÑôÅÖ> ³ÂWB¶¯ûü[ò? ¯šÈýJü_B/>„ùÕŸ€¼ú æ}Ó00±™vEÑŽIB£€‚â8ÿ(ôü£8§تzMýžòþpï³@'Ÿ žîš¶›± ÑŽ¿�ÿí¸ô߬ü q�êÊ¢Õåz_DØMÆA@s „Yå"|„Ñ�ÛÍœ"4µkw2áÿ¿_õ¥Ÿ‚?ýçÿ>ò‘iѢҿ¶ºtx¥¿ãc�g|‡Ãáp8Ž8‡Ãáp87»ibÆ­“SÚŸØ0ö®º»¯Â¥¾b¾½5ÞRVÔÛ¯«& s•zQ¨þÌŒ�I%êlæ�7<UIÄ* «@™Á¤ÉGÀFkweè…pgh®†V¨U)Œ=EÍ“/0"ÎßS/Q(Õð¶š>ŸDºeŽ?ø(úñ5ÿé¾yÀH~ï,Ù÷]5ÙÉ ucѪoÍuµý´é¨oŸ}T Å @‡TŪ’ÀÆØ1ëÿÓÅ9”q+ã¼8¶®Kí5 «m¸~U0­ž¡‡îú_Ü!Ú©µàº fzáŒfÞ•3ŸNY“bÛù”¡H¤$4€BcqÜo±él“€�ŽðÞßøUxëû¾9G@Äd½Ÿ<ÝS;óÌ/ÿèýïÉ­*Vñ¡ud´ç§±š�°NL'!ƒõÕèìî‰ ùLæO +ä?q¯ûW ¯ý(æW´½¯Ô¢ ÊõJ»³K  käHÑÄHêŠÐï‰j£ò �¸ö_^ýQÿ±ŽcŠ,/üf„ãw'kýÑŽŸíõÆ®EY{ˆ–ÏÓÆS7�ÿv~ósÝyoÈ ÈƒäJë%'%»{|ú{_Äýÿ+ø ÿÝ?Àßú»?¢ÜÖÀykZþkÄÿub®cùïB‡Ãáp8‡Ãáxãp€Ãáp8‡Ãq~qŸvà0M;L! æH¸d2œ[Ev©ðÕ®¬�z»T-£ù�dÎùØùØ”uÎ-3º^/'Âw ³&›u¤<{’E€r#·‰4Wù+@ÚÑì6f \UT„ Œà0WeÔýt-,‹þÕ¬9ªÎ ‡Î{²ZaÍn茠„Dð3§tBeª•xðôZ±÷!äyc(¦‰Àçj~-ËAH1MEœÃ�v©"?„€àmŸú%xû¯ÿ7¡˜Ì ÇÔ8>NÕÜ—÷1ßÿ.Èë?š8Ùï²ßZû3u1 •œï*É Á_Á @ã$›‘/Ïöl´DíO úøçpù�ïhdÿBû9dBžØ´Á¸äüù¤@àüW Ón„dÙ¯6êcªk5hZØ”¯«Å¹€¹Ý¿f‹ä¸Í|@¯Ô©E›P >þ%Ä·@˜@GÏcº÷9Àî^n·ñÿÐ5ŸV¾çnq 6ú 6n˜§ÎíÁäYHtNmãìÒ gí¾ÌøüÏ~;þë?óMøÓÿÅßÁ�üä¡Aë>6FXr_¯!X>êW;8‡Ãáp8‡ã)ÿŽèCàp8‡Ãáp|üƒsåú”˜b²µ¥ ”Š~û3P ã’Iß½}€E¥* ë‘­”ÈïraÕf}­¢© šCŒå~_3Û·] �žÇD4þl¹f#¯ëTD–£[ºçŠð:¶‰T/'½¸ ”l"ªÕÒª€D�2*É_Iý’³žsàEcs(€Ô{�â`ƒ(S+ ÐÅ|j�ÍdÇ_¼¤T¼S"þt£_·Xyºšüï"´?½¿‡nœ¿qÞ5•†(À¬ˆ¦P¾DÎ37Eri˜�°›8 B0#WœSãÛÅp¹L˜£&åベ0í(øø6>éóþn½øyPÄ´xb¶½ÇàÓ4?¯~/æ—¾3=c!äŠo+lɦ�†,y*–õ´Øˆƒ�PsZ~NïËþ5Ä_ù^È«¿šn Í¿’ÿY�PÈge3q$y`€Â.€h*ç„6ÉåbyI®Zìî�…{FÀ” oNÖý!€°Kמ¨í šÜQ Zã RnID³~@óõJl%·…‚/ï#¾ôY\„{Ÿ :yGš»Õ �‘ü'ãz`3�FGþçï YÔ¥è@ž/±¢©K ^¦~(tšú®i ™ðì½cüé÷kðÿþ+?ˆÿá¯ý $ Bàä˜aDÀa7€_rXpp¯ð8ÇëcÀk>*‡Ãáp8GùÚ‡Ãáp8‡ãã ¨DÌ÷s÷úȘ—Âþ‘¬ëHgÉüF.ÿ¨N°6ùJ©š_ÈXá[U�‰Pš*èIŒ5|;§V¸uŽåž…@N\/‡ fÊgbªA›*ÿÎ^¿ô©UÍëh‹žíúK»¬£}TäöR6õ'I‰9æÀFb¾¥ÆB j–áµ½v\3q¯•À켪CÀ¸2l¸W1@Biµðï­#®·HÕĬ.b;?o?ñƒQztÍó)ç¶33”%Ûús�M JÄynb®ü'Æ€°#L#L‡d÷rżÄBæõ#15j €‚Á�ƒˆ�‰púÜ'â�Ÿ÷ǰ;}Kš¡ôÕ§²¦nó+Ø¿ôíг_Ìæ+dqµÑ'cAoÖR©'jßæ‰ü·Ïkïh9WeÈÅK˜ñï#>¼�BD3eò¿\r‡¬¦hÏErì/MÜ3,©ý„DÚÓD`ž©ÎÖDÖÔ& ‘˜Æû2­ÝÈéžñ" ôùò¯}ýûð¾÷ÞÃÿóÏ}ÎÎgLShá†Ø¿.Áÿ´d¾8ý^Nîáp8‡ÃáplÀ‡Ãáp8Ç @!·X”=|ýÈðÛL{gut„S%’3M혞Z1yó†�&c® �Hæö©ìFs�¾§V|´N‘˜4ëQ^ÜÂKdC)„&²Âˆ1Ë|¹FÔº èá~ÐêA¹„+öè­» påZ©rŸs?tŠÝ%ʺ ÉlR<1À¥ú—,Ñ9ä€LDN$jvþsL'’=¯÷ç?éKðâgüaðÄ&>çÚã…<øaÌù›‰°Åä¶$ò¸�Ŧú›V¶ZÍo÷näq!šK¼Hµ×É:̱ÿÅ¿‡ùµ›=Æ�ÿ;?°ËVûr¡|q&ÝU ‘sSs„Á¤ @Hk! n°# ”1Ëç@Ò¼Š@£4CUÁªH«ˆÎÃ"iœ'ׄìÂ�Æè2»shìcr*Ñ €Ãdº ÙÝÓ. vÙ塉gJ´@8p]Pñõðãá™Ï½5ÏeY¯<¬n P×åHþÛ§€Ëƒ›] Ä|pò_ÑoÞtŸþÑQB0'U{‚ÏÿÌ·à¿üS_ƒïÏ|'~åÃÒbH*°­ÏÏÁ!—€-2ß#OŠ•5á‹Äáp8‡ÃáÈp€Ãáp8‡ÃqãŒ8 æyÆùùã£ú­‘ÿX©îמˆ½™Rãbû\‹Òª%NäÅN<Ñj„5žlKе±R‰ùœ«†)[í7f>Å2Sk$@ª<¯¼uŽ à* Èäv&EëyjÌFKyë`e6•·­úPÛ5¨õŽÈ²ûÖf���8 Fî‹ÖÁM¼CrêÏíh Îi¢ ¶/mœH©Š ˆškB§Ø\>½ÁÈA��‘¬/b„ñz‹¥¹©Ð^ÎBÔÏ)€ã£L°Kk�H›7Q`âŸÎ�˜À“�zHãµT±·f35'fFÈ6øGÓ^üŒ÷>á«“C†÷˜n†[€<ÆüÊ?€Üÿ>€v¹òJÄø–­|yÕ>º2ç¶Ú¸÷ä?¸¸äÊ !à(Ó˜NÀÓˆ�MŽ‚$BS|'ž¹‘ñ¥’^côí']7�€é𬼾ú8Ss@ …’¬ÆYD«Ó@µËˆç`ý0hÿÀ ácÐîùüï-Ð2Ž’û ùkG좼ö}€pû} “w|Ò7\·ž#°ûz�HHhÉJ©×%#“²3r ­ëÁDH˜Žüßú¼ï½Ïã/þ¥„¨¤Ï…+Hýñµëø×x€cg>‡Ãáp8G‚ ‡Ãáp8Ž€}Œˆ1¦(€?Rȱõúÿõ£ÉžYa]õ‰\¾o„“*@*P )Yž¨3!P]³�§Z½^*¨‰ œ+}Ù ÊuÄ8ˆ K.°­ÖDvI±óF"ÏS›ôÀHh«¨_dÓS­€·6ýªc9½½DjƒJý3R$ Æ­Àp}”c¬€™ ÀÒ*�ûþST$¡C‹(mÅÁ FbmüûîPqs¨Ö+cÞ ã`Ðñòºz­|g&b˜§ñ:OÄÿ›ã©F<@[L„d®—Ës‘û¦Â“S-–§\õŸŠ×*’xj&h@Ž 7�4ï˜ÒJ¸ýìÛñö/ücØ�¾57jhÈv;}ðc˜?ô-ù!™òÿm§D®Wòßâv-C‘üóÁ›;}˜“õ~ g8û .ú¯¶¨¥.*$9"¤çS�úZEDG'àÓ Ü¦]ôäjñº'D1ω9] FÖS!¦y)¤�yf:µÈ“�Áæxk#ÁÔ9ç×ýÇ<×dó=B©‚Ÿ�ù£Ðù£ÐÇ?šž¿Ý½=�kT”‹ï²+ªõ|ü3Àã÷ƒ�ß¾ý©Ÿæc£iã2H£=ähÇ‹¦È†üàçÕ½xÈÉÆdQé �ç).!–õXÚŸD_ÿŸŒw¿ýþäŸû¸8Ÿë:¯Ï z7€µH€7îàØX}d‡Ãáp8Ž8‡Ãáp87³DˆfK›ol!}½�@�” ã\yoQܵ{Ëð•ä£uQÍMKž*µ…³£@½d&ß¹TLç¯ÕR?Wýk¶þWmõl¸<µ™ ÍàÚ·²å¡+¨f�k%ˆU��¸^�¸2ÒˆL²z»Tô�4eÏKÇiÓŠT"‹"¨yªºB¥÷Dÿ�ƒvwr#"€œSO; F̯þÈËß•“ÉzP³Xûý®G”Yt¥¦$¥{pù¿ýlþŽô½¼þcØ¿ÿ;óSb¨V¾sQ×*{ž&€w £#ÐÑ-àxì&O Ý”Ž m�iöóeo*9 d6Ÿ¼hdÅJc OÃWU5Á‰è° ª!ÞÍMÉ…�[Û+¥.•W¡�ïúÓÝv/€voIó‹*I|„.†�rù!Èå‡Ááøöo¦Û:=ʶJ›ç´_Bòp†Lð[…%ùß®#€Ì@8ä2¯¿= — 0À>ÿ7¼ ößû ü»ÿÉwáåWÏ’bl¡‰°_W{ó”d¾;8VðÀ‡Àáp8‡ÃáHp€Ãáp8‡Ãq ³´œò¡ú¼ñà+dˆ®•ÑÈXkW"Y©›EîFÐR¨«Ü/½k â@}»­ø@ ¥Š#bTˆhï|PuK@—ªnû½–*þl‹_‹þ‹% �GµL'Sî_*è‰ZÍlsú7 ‡JäS{)�³FQ¶x'Û¦vìÆ`™é¦3�§kóœA¿±V%¯¦#ZÉÎf®Ðë“«ÔŒÅ[mñ5¬¾kÕ¬Õ§!ô–JÛ"Q Š@$ KRé?HZ¡<çH{âSaЍgQè>_(¯Ê.Š@Ì•T¦<û)Ÿ�·ö¿�, ñ_ïØ¿„ý¯þ5èŇR¶�μö¢'ÿ‹í?ÌÓ§ÙAÀZÿ7‹ òêO`ÿóß‘^„9¿CR60ª !=8½„ãN�Àåùž8õ!S¥.°* ¢‡‘�1ºE!XÛø†C{šnìqK…ûÝK‹‰aDKò¿Ûm‰�€ÙŘšË�_.^†ÄŸøÂíw€�ßìN“E?T[ ã � ß æ~æs€é.Ú&e:Ñ?͵}Š$hB»ÉØç¤'ÿ±M€\|œ¯±ä!€¹®éOzçüÙÿûoſ󧾿üÁ×Óò©Ñ-ís!M×Ò ŸN#(2ïÛ×íkOûþÚ}Çãwèûë¶í:×\Ý+s±Å¡vmûñ޵¹‚ ‡Ãáp8Ž 8‡Ãáp87å�ÝaÚ3ÌæH¢V|/ÍÔ ù_¬›‹}>*!¤…&�çæû” õVµO‘Í ãý%Ûè5M9÷¥ˆ<‚#D4G¬‹AqX(¬pä-:€²#9uî’ûM*‰“Ì–àÌÆ ËZ²½;=FŠ3(£DÕž½Åh©äGoçO]¹!hD[åç€`:e‰ú‘Ââ’‹ XBŪÝNXS˜fkýÏUè'HÍ• O) °q D�«µQ M&@yf‡|¶$tä Äd/Q"ê‰ÓQ@Ø„ƒ'Îñï�/~Úà­Ÿõ‡±`²ùÀ=ÿ%ìùÌÃL Âho?Týƒz—ŽnŒiPðôçÊë?ƒùßÑ#™0&v™ð?ʯ3G§ éÀ;¨c¤H"CwSKpÝ,MvSËÕ�aù½Z²_,ù§OæP\`\ ÄÜoÌXÉ$?WÕÕˆŽª¤Òæ*’xw#|�ìï#^ÜGäŸß~øÎ§€NÞÞG3€}Û%žC^ù‡àéøÞg»Û+ãbÚ*i.ÕîÚùoöPKþÓ†Û�œ|Ј§ä �£"€·>{ þÿñ•ø#âoáG~òC)Â…©Æ»Ø$üÇ×m%ÿuÈóñµñúö3óªó¯"ñî‡D‡„W½~�s¯:vkLþ)Àýßõ ߈££#Ÿœàäø§§§8==Æ´K‘ó~�Ç�áµ×_Ç+/¿Œû¯ÜÇ믿†‡a¿ßƒˆpzzŠ»÷îáùçŸÇ3Ï<ƒ“ÓËqyq�³³3œ��áüì "·nÝÂÝ»wñì³ÏâÎÝ»¸uz‚Ýî(9ÁhÙ^Ò>cÄÙù9?|ˆ¯?Äã³G¸¼¼„ÄX¯õ̽gðìsÏáÞ½gprz!Êó~�y‰}œósÃØMÌ!Ï£`?ϸ¼¸ÀÅÅ%ÎÏÏðèñcbL»Ð$*ÞþY_…Þû�HÕÓ¹*œˆULÐó÷cÿ¡¿ž«ÁˈK%�‰ AÐ tP7;{p&¸yPôñ/áü'þBig!ª9“ÿ `Ênœràùô°» )×Iòi¤<› ‘ }¬Té‘‚µâ_™àüÌ´ÍË^+·A¯X×ÞcµqàÙ}€Š�i±½q¿HmÔ‡*ZÒö½äÁ/CÎ~áôyÐÝ÷�N?!Íoœ³NƒÙžçSæW!¯|'øè­à{Ÿ„Û¨Õý ÓõLþS^+ªÉ¶¿®›ÑVˆñFÜ'k ή¸HÏŒ "·NáO~%þÏâÛñ½?ô‹ ¦çBô÷d31›éÔÎ-ÀwÕ÷Ë)ì‰rÙ<çIü§©ª¿Š�·Bˆ'3ls�¶^õÚMÄðûÇËeLã1‡=./8Pý]âòr�³³sœ=~ŒÇ�ÏpvöççØï÷ˆ1b·Û!L'''¸}û6îÝ»‡ããcˆˆó»D7™Ø> P>“*’1Jú(�ÉфÄÝÑŽEÓç53´Ã4MÙmIüÿ+8‡Ãáp¸Àáp8‡Ãá¸1 „(P¸FItª\×ZéY¼ï¹‹ (¼QŸóÞG �åÿMÅÿ’ìiT.gõÌñÙ?Ò7â¼�ÖD¨6ëµ^Uù¯•ö6UöÌ Î‡µèÏd‰!ïÓ8p"]€®ò¹ñ”Ú“‹ÍÕÍð_+‘/I1�ÿ�¯9¼‘•…àVÕ\užÌ¹ÕF9¬'JÅ:OsÛMõ¿µëïªø ñ¥jlùËܨ_hGöS»n‹¸YTÜÚ=í\¯ttx_û·†±9d`Z`V,Ð[& /'€C^L¹ê?Ûÿƒ 1õGöŠŠIÌ1…DŽóŽ0ív;ïÓ'¢G€w|Þ7à¹÷|Ub6"š|’ÖâÃÇþå¿‹FØKú'ÍR>!´Jóº6¬#Fu›¨¤zñºÏ„K<ÃùÏ| ôá}„)ôãòú ÚqªöÞ�Ožvw€LÖ†²v‰AOŽT`Iê UMÏs}@jÉ¢ä¾`… šÖ/�ä´.×Î:�}}ŒK[×îe+ÿ™Ì^Öœºø€˜&*�˜œ:×0èü:ðà‡ �|çÓÁÓ»’È¢ìjå5¹ü(ä忇púnЭ÷á(ͳ&"M“uIÉ€>ˆÅˆT°ö`õ jbPŠ Óäì/�40ï1íþÂøUø¿þÇ߉oÿî@rÜ Ã~"¨±O#›²O® ¡TeU\¶µ¬IV·4]É­•«· �ÛßnZ‹Ÿ¾ø·|ù…æÏægìgó%Á>„T!¿¿ÄãÇ�ðøñ...°Ÿcê1v»€ÓÓܽ{Ï>ûlrxöYL!à2 .¦ aJD4ãÎ�;¸{çNªN?½•*Ò˜£¤]]$EǨV’žàLÆ«*bŽQ"Jb…ËË œ_œ!LŒã££Gv;Øêù,í"Iìg+�CÀŽ»ÝŽ�ޱÛíÀS‹ˆ‰’¶3ÍbÓ$.HŸkIT‘ªÿ™a ˜BH±7Ã~Ò*úÛï‡É-ŠÁ<%ÑÁ$õ3ʶY%� !}”¢¦ø§öû#ÌûqŽ)ÆG**œâyöÑÿo‚Ãáp8‡� ‡Ãáp8Ž‚f-?¼Ñ9mgª¼Úö ô%Ûhĺ¿tB—c¿ÈQ7äùƒ4Ðd#8 €8Ô˜€Bø•ªü®BØôÒöW)³šù¦Ú¾"@`sùuî©(²¢DLN8�_î.¹ò¬«ìWcUßYãçëäª>Y¢ê�—˜¿jµÚ·}"UóŒòÝVã¯p7«ô–ÌÌÎåš–ponË5bï»^•½Xzæe1ëaX{öW/ö�o¿ÐEPW+¿LŠàT͘£‚C®•ÎEî:'W.1¦nML �ˆ�鈱ˤ?B  ! PÀ;?û÷áÞ;¿ˆÐLð‡d§òê÷a~í£V÷S> °fÍ‚!õ»É%4r7´ªq[Q_�cì?ø�˜õÇ%„›ËPâ‰g.›�ãÛà[Ï»[™øç>Z„˜5�# ÌRº\=šÖ9‹…Õòy2ÙÈ]më—°¡ `íZ•2nà «Ý…ÚøÚL6�Ã<�’Ø´¤úé˜æN8r´. � B? Ú}èè]‡Pˆ|å*òˆg¿œý<³Ÿ o¸Ð�åz1gV>¶~JÄÒ À¬+F ¨´=<Ÿ¯:'ñŠìÓµõD›k=LW¹ß¬ÿ›¡ Db®X×J(*'‚“sT@¹õù_È1ÛRB”T5k‰Ë"*à"Èd¾ª$UúLé k_,±©jÉòæ:Ð�—±ð—R}VÈ=á\ùÊ HªrÎ×�(mÇç`…• ií­NÈ ï¼Ú|w^W¼œlÙk?ÔTåë’ØW[©»¾ºÖQó��»€šêÿk.íʇQ ² Ã÷½êz«‹½M;…dL $t „yH “3Q"G9ÂQ"ÒybP@Î=OU›S8ÂÛ?û÷ãîÛ¿8Ù§—‡‰�º`†|ôïc~ü³häa£µŽÅP‚>ô¡ÌR Ô*m¹œA^ù!\|à{ë5ÂŽZUy‰�ç, 8>ß~!ÿ!YTS+ÜQ,ñ !‘ÛD=Í(šˆo•L°kv3ú’Ç’„Rsh´¨·+qˆ¸jAÈ5SMc(íg…t俌‹“©1Yݼ s#IÕ\ý¯Fã“×s߀)€è¨ *tþE`þÐî]Àîí‰Ð—d±ÝÈütýøÒ÷€�_ßûl`ºÓ�jõ½)sÏä ‘õ礰àÔ|UTóþ«g@8¢€% bŸ^G Ìø“ìËç‹ý_þÖf’œÂ!š] ²üDJÄ"MÓT¶}­F' ;‘8è;´ ɆÇEW>[švªJ¸ÆîÒö2é6b;ûEPF G·ïÜþ‚FUÝ•ÓKôA˱¨©ê±Äh?5=²5ÿIKU€“ �Z’«Fn×TÆDm_Vãº'‡Tu²sdEÌ”žóñ¨}8QkûÞ~\PÚ)TÀ%€KCõ²]JËWÁ5->Tõg...²ÍýÉüÌ\«Ù‰RäË4ípt|ŒÛÁL8>NM Ó„Û·oáÙgŸÃ½{wqœ«üçy�y?W�c¡’éwîÜÁé­[8ɤú&‚(‚y?'—�ýû9Ö•c"ͦݔE Å?Exìçt~‘&b˜Â¦&tˆ@”¹º-õ¥r?`šv8==ÁÉÉ Žv;1DsŒ¹J¿úé÷·0í  ÄlÏÄYøY?ÝóïBqN¶ýs¶àgUÅ$¨c6œãòïwU�žw®I6ýï-i?Ýï/qvžSI '‚iÚ�ì]àp8‡ÃÑÁ‡Ãáp8Ç @±Ñ+U³%­½ÃôÿgïÏ£­Y²»0ð·wDæ9÷~êT¥*•J¥*$$!„ `A‹Á€qCÛÀrƒ±ÝЫ¦³lVw{yÂvw/pÛí¦¯ö«1Ì`ƒ !„0H ¡4T•T¯†7~ß='3bïþcï2Ϲß{ü¡×Ä~ë¾{ï¹çdFFFFä—¿éªèv Vm¿7ðû ¿‚ñ×¶GØÀ´"¦v+e{ »‰¡†aoºjÄ‚ªî·­vD…-�X\ìá6AEÝ’v¯ìtÜSôBÞÇÔî+–¶�ýµÜß9˜¢ßm½Áö»´EퟥSþwœŒæŒÐvwA<¨§­e¸k.ÆÂ¦¿vçú–Œ²¯×¥~_¯üúŒì÷þ�êyìÕÑ×Ûîe}+Ë}m7,7†Š¹‚2Åzž Y¡Ië{¦Ù€�0¦C@ŒŒÈ�Þ Š@Ÿõsþy<øÌ¯ò㮲ŸÌ>]NHÿ �å'Û‘“Ô20ˆŠúzŽi×5½Õ¿#Ó…ÄŠåïý)äO~¸~ Äv „&q=|øøˆLsªñõzb1‹yR(éF6}mªMÎ ¸¨M^(Q¤P Ey¾;Y›è�Ý jÌ¥¾\o5çé-ÉÁé�j¿Ä€-J�:"@!/(Ü¿#+”,m?—Õ…ƒ�ý� žÝ"X„ˆÚÄ©éc@ú0½ ßi ×ÕŽà …œ^Âzús·@xøE/±éD?¾ü—æ  5ÆÀ\zR×–€É_>™Š’EG ÄP9áßþÝ_:½ô‰Wð§¾éïÔî© Þ•¸’2—[1ˆÞâ\´‹ Øöïݺt—Q÷KY»îÙho SÿÏ›yK¢ïºýŒ¯«0¾ÂKô��‡hç>ƒj^Æx¹~ xe�ǰõDT<ß]g£{¿RPWUª2½ô‰î²Šú;’€]ÜŽ´¸þ\yïžäQÉ S7O·X~išâwonþâ|áþ¹ç^xáµÛÛÛ»ÇÏ=wzþ¹ç×G�§y>@EqwwÆ+¯¾Œ�¿ô>þñ�ãÕW_Ãù|ÂétÂ4Mvÿ ÁÇ»S#û²Ý}<Þ¸Kaš&�7xøðæÃªjŠóó§Ó çeAιnïp<âp8à0ψ!R6µÿù¼`9Ÿq:Ÿ°.«åÙ»²Þ¦»_1G‚ê^U¯XÖÕ§vrå@ˆÁÇ¢dïsÊ1¾¹8׉‹SRÄñxÀñxƒÃñ€i: 0CD‘ÖlÏø àY+8ÙïG©D ØbûëÕÿpàÿ~œ«Áô­ö§ÖÔ¹{2E¥�”>¹Bv¸:¾ü½ÏÂØÛß b „í­²ßtLSSþ½y »ý?Kâ}µ_©;u ÞÿÁÎÈY±.j\U¨X4@�' �Œé"U@�ØÈHŠ÷}ٯǃwÿÂŽ@z‚ô±ÿª¯ºus—{ õì�ÞÚŸ�‹<úή;"�ƒ(éë�þµM�…Èð“31‚nžŽ€}Lš…<?q·í!�`Tc=Øã5T@ï¢ö&µ WÍ¡ ‚êL@¦]–Dwìze^s°\‹“@™›ä­e�oˆ,Ò]Ï ìÒCÚİ™w?÷í–ŽH°™+ÙÕÿÑœbx²sA•"%¾C�å%ÈòIÐô<( {£²³òÓ†ž?�ðâW€ÂsÀž„Sæ QT ¿TïÓ-N\),ŠnÞ¬�“‚o@H¶=4?ä”ðßüüÏWÅ7}Ë÷77rÀYär¾Û»2ØÅ¼ØN Ñvf ènÍê§ó¶n#üïteîÒëcfŸÆ‘Ej rÎSDΡP3 q·šjyB{ÈB›¢5À�Ü©¤¬Ídã�˜ ¹#Çy¿‘;í[uu"š9huèÙ8¨^zo¨n^§ÝÜZãsÔö+�Kµ`*Ž8Õ§‘P¿ë»–eùÕ§óùW×w|Ç«‡ãñ¿üüŸùÿéÏÿŠ_ðQæÀªJëšÒº¬úäÉxååWñ©O½ŒW_}o¼ñrÄhóSùOÓ„ù0ãx˜ãä࿸>àp˜ˆ7U¿}fÆŠú°€æ�Á]{ Ë¡V¯dêÖÎÛHõLq•¨P‰X(¾}ŸÖŽN-zß÷nn9€H êï݈ÄwªÔgE£÷ùÛ WäÓw­zÇxkPëýEtÏXz³Ïá’ ×F)a"nÈ(%?9›r;¯ Y€¬ fÌ?ñÀˆ�¢�á BrGö|é?‰?û$³lçÄÉÙé5¬û3P}ÔÛa”kSÝ:œµÙ¯àP ÆòîÀºí8Øwúþÿz÷6öÜlü „càácÐüЯó¦vW2À¥‚úÅþ_0« 7ðf ;a@:Ûiqà_2(»¬¿Æpme…²EfôóÔ•Ú¶ËýõHÝçè^’ÓEñ• @= ºHŒÞ^î÷õ¬9Ñ·çž÷…ñäilƒ)°ƒþ'š $ÎdnšÝ.?š O? ŽˆÏ�ä@@¦Ü”ùY!ò)èKß¾ý£/¶Ø‰ […Œ­£z»rTªAyí»f|�—h;!@~jûP†æ7€ü*�l¼ñt‹ÿü?øø ÿËßö�?Œ‚Ø“¡ Õ¹Ï6¶öyØ<Èw=¼¿–i;7bÒ•‰äºó@« M¯ÏKªrýsªr^Ua"ÛûÉIXôƒ6×)¤¶²v•õÃ×AÉbª ss¹‘:—mAúv ;E €fÚ¨ô«Í~iP<Óp¿¸.l�Ö­/ÌÞ™aß­•'S¨dݶ¤ž;ÝÝýŽïûÞïùÍÿG~øßú�ÿÜoù/8ð�d,w§»õÕW^•O|âãj€×°œO †«éæÃ77·¸¹1…þ|˜Ì¶ŸlÄfý?M¦Â�SÄ'ħ ªŠóé„uYðÆ“'¸{ú˲@Dª�=u÷ 9gÜÝÝUà~]ΖW¿&ˆd¨(8ÄÁL-òF>(Žìd�u]-B@Òš±ðŠé¼`ž ¸/÷ k�&H~ÿCɦ˜‹!�l×J !DL1vÛ°X$]ÕÆZP°DÆf¨Jÿ´"»‹u„Pñ‹°8fBàdç$Y�CÉ@5v %å}Eç�Y”9*)Òš°œÏ˜â„ó´ØñŒ,3jÔ¨Q£F�5ªÕ Œ5jÔ¨Q£F�õv¸qgÆ€Ì�Á’vÎýhäîG¡éU„çˆ\9ft�ì—�dRPÄg‹üÏ]߈ýM@GPœ¡kè ð@D ø÷ÿ*üºå�ã»ÿÆ�U›Ò~ÑÎ_ÆLˆšÂ].IÍE¦L_´;í5…º­!¢Ú1åÞ‚KÄFe|95‹BN«Æþžsò6ÙšÇL©û½¸äô|Ýl'ƒ b^ �C³ÓG#B4“ ºá½ûŒ»õ´}é.Hû%r·nîúÇAÛÞI` ´ûäþºÐmÀÇ=Ä�ç^ýõÿàÿõÿøOñ×|í×ý®Ïýà‡>þÆOè•W^]_yåSùõ×_ÓÓÝrN˜3bˆ8xðà>|€››ì­eåÜhQàÇ€yš0v#ÒºbuÀ],Ë‚uY ª•dPÚœsÂéd xJ ˲à|>#¥T�m怨fû½‡Ý&5²„ &#pÀîoÒš�RBN¾íuA±Þ¿¤uuÕ½ÔÞäœü{O†¤ªê/?)ÄJ`!°(B´µ‰ ѤDåT] DòÄ×ê2Òœ rVd65¿ˆ Ev(ôîF KY‘Sö¨€F1"(=Þ Ìy T²'!†ˆ0�GÜ£F�5jÔ¨Q›çˆ£ F�5jÔ¨Q£F�úé_‰{p³Ç$öìlªÚ}c.ïŠhl”ò ü§†úoœ,ëž´©‹‹}­º�xpÅЩïÕ-øwöæRìÃ!¼·ä‡a\Ò�ªö Û±pÛŽ‚�n\ªË``›²[½7H‹‰kV·4꘤=¤¶ØqÛ†©øš¹´½¿u>©@Á¦å jýÍèìš�à@¤�š¶¿‚Xê¹ÐníLÍ›8;©‚P ˜ ÔÔ°d C LP!s è\Z«´‘A¤'´A¦Ú¿·s®`W­ø¬8�Mä©Àæ?¬o@_zq�\ûùâS h2ed:'¬çŒåN°.Öþi"pæ™1ß2曀x$„à`}£þ™_øËðîÏÿ h`*Ù?³iÒkX>úÇYLõ\ü¨ïª€OµÆGËŽßØ³#:ÐËžÏXüÏ!}òGš:½³ç�‹9@ŒàÛ÷@â % ­n%ßÔõ’²e=³€”Û¹Ú¨Þ]Õ\\+Ô•ʼ!ªàâ@Þ¦â4QØ+�@Êþ;~- +Ö#ÞA/®e‹`(ISÏß;�n-û�d·Ÿ Pv“ÎŽTñì�ÕG  MdEý#@ÑTàÄ ¸õe/“y1‹w¨® Émz‘3âú:dzdD“\šÕlúuýÒÇþ,âs?t|¯mï("íµl@vvÿÙö ôʵ§€>1Àô S×¶BÆ‘ºž÷¤¾ ›þf!PN‹»5U?]ó��#A÷sq|ÐëÑ ý{u{`›9]U‘rþâïû¿ç¿Z–õ×O‡Ã'N§$§…ˆò4Mz<ñðáC<÷Üsxî¹çðèÑc�G„h® 9­¦`— Z ©-CÄI>®8L€ÅL3â4m”ÏX×ÕlóÅõÓÝîîî°, RJЇ€yš�yF f[» á& #”u“Ù,úý¾ažRíßï²VgÉ9§eDÌNŒÌHÔÀÀøœRNàäêýÝú“¥\ÓèÈÙÀy±6G&sB˜¦"ÆÊ+Ð$’lI'e½›bÀ4MàÎEÁƹ·/%d&‹m`Fˆˆ�D�0áx¸ÁñpÄñxÄíÍ æãqü[aÔ¨Q£F�5ª«A5jÔ¨Q£F�5êmP¦(S¤,fs�Nô¹yRŽË0ãî[o7 `c÷[-\¥©Ã–L؈.Ýž\•;\�ª`�µ=Ð=àǼ�ƒðÝþµ�+¨¥°ß— ª;uþÆ…º¿�t³òl/ôjJq-_¾Ÿü¶?WÐÚÇ{T€vý&ÊÐM][|B³· $çj§ßGAv!€m-ö»Ö©{Ëtsp½SâÄ\ÇSïÓ­nîDU©»Å½ôhëXSû±;ŽºÖ]™h+h{ßš\Ú§¸pQØ�îYZ¬€G7”»‡œ¿ä‡þîßù}Ÿÿ…_ü;‡ �XnonôÑÇxôè1>z„G�žÃÃGp8À\=@çr X¸‘÷¿¨ÏŸ7à~ž'ÌÓ„è±Fšòø!'äl¶õwOŸâéÝ–匜2B`̇¦+qψ\¯%ÕF0×$FѧVźNudD9g0¯mÔws8œÜekš�s °{SØ'¤5!0ˆ 5×�2ÀUÙmÿÙïg²ˆÝvñGÌ1FÌÓŒé0é,0ì|)X©¶»Œ1NÕi¡¸ ”ñ,"N\p’³�wB„DŬ%.aÆÍÍMûº½ÁqF�5jÔ¨Q£65£F�5jÔ¨Q£F½ j]N�¡9“–ÀûÆ€ýÔ,þU÷€H§(º¿ùCðò¾ÄhyÛ¸jmÏù�P‹*Hs�¿öm"m˜NÿrÆ+¡†©‰t‚OÚ‚2Ýg¨Xªð­|¦´©(ùD¥ºvoꪞÔjG[p î”ÿ½=~SÇ¡³w•·P/ÖìúPÑ@Ä,w³)îjžøN¨¹O6è­ª‹«mÐ|2‡t±×‰Åñ‡>K›ßkÀúv|íO.6¤Žm—£[´ëMëÓ¥ xžø•ÏgUHîÀx"„hÊà0®&w‚(y̰·SV>Ô¾â\$�D d'¨&ûŠ·Fà@¢÷HZ_¹­>8[Œ24/È?õg€w}øðîÝüß+ÿÝÁ *ÿüW(c e£�ÿåŒéë?M z~Ùþ–3øÌ'ü¡ßÿËñkûŸÄëoœê|Öɼ;Þ‡X HýZ„‚Àñ1׿Ý€ú Ü­|¹J,é¥'çôûðsÞ÷ØZ”Õ@§�§íZ[®q®ï— Sö¡K÷�}{]í­lŽ âD%*km§ü7ÂU�ä&Ò‘ép üë6H+x¯mÞï;óââ±¶KOVk=q©ìÇÞ‘h{mo]äâ ¯)ýÚ¿ÿ#?øÍŸû¡ŸùßLÓœCàtûàV>zˆG�âÁƒ8�˜çb˜À� ÙÀí(1͈ӂ5ehØJŠ33#N‡£©Ë‡Öum€»ˆ«ü©Úÿ/ëŠeY°® "€Ï±e{�Ál„r'˜=Q­¨ÝƒÇ)M“ �R}�ˆ ©äCêÉ–÷ž"­êúu]*èãÔYÛ9“’(�“‘Êq˜•¿$nnŽ˜æÄ„œ2(X̆ªº€Ìß!ð?OSµì/ǘE‘R‰Añû¨,0ÔLByÜÈœ¦8a>0�˜çqšÂxÄ=jÔ¨Q£F�µù§èè‚Q£F�5jÔ¨Q£~ú×é|F KZ�Vu§!‡:ìëûêö¾[{�ü¥.¯Uż*逺íë.Sùš­9mTïl�‰�Ä 6?1›°×í¿K<@m3¹ö0˜]ÍgÿXêîyx#PË ve¼˜E¹ãÞ* 8QÈVLå~#=l„*®ÀÄÆf¹ª «]sŒtÇ(’ý»6å£Ò›�Žx ´Ú‘ /‚AÈ;âÈ–rŠ€+™Õo%Ïù:2¡%2}ú…6§½¯Á×^EN~²™'F<” Óldî¸3¢üCÓáy|Á×þkˆáÆÆ ¢�ŸP@úä7Cï~ÂÀêTãÚ)¥% C=2‚–ï¶ø(–ç¡nçîüƒrñ‰=:Þ˜" Ÿ_4 $°+ƹ‘:ƒb4%±*dÕFJðñÇ’ B vð¡@âjxe'¨ó2¤'1ˆ@ˆÀjjTR}öðp›|éí*JŸI±ÕW»N{»ò‹¨“ûˆ»*"ÜŠ£k»Ö÷p!Ô¸‚÷{ý\¼z5<š]?ˆˆý‹"€ÉÏë%ø¯9;1)Û¶™|Ÿˆ&#žÐ·À‰¶¾…¬¯éUW+KwL ù¥?}ð„G_ÄÛÖ ºÏ?�-ø�Ôæ˜²l2å y€Ì `zʺ¾ìo9!á ?÷!þ¯ÿǯÁoùß|³ãÚº [7•î\1m™Z÷]í•Äöfӽɜ… ¬öïÌ);x¿Å›y…¯¿D¦<%`3‹Š6w :uôÇ$Æ0³5b×'A©¸½˜!C˨oóº^]3Œ ×ímÓ%[Bu߯wYó#Ð.v;€½7tP‘OkÊ/[º{úô÷†þÂsÏ=^8ðr<ÓãÇ�q¼¹Á<¨-Y!A€Lõþ!†€É•ë9e,îx$"È)#§„œ²ÛÿO8̦2?ŸÏX–Å,õ=öAÝ€ˆ�Sr¢…vNf‘ÏÁ¿³ÙÙ_s2*àzÖ¶Ч´V‹�‹…~³Ò/ÑæD¾O©QkJ늢‘ÊtÈÜÝË� Ò\‰s@Œ`·ß?88øNLHk¶û¦,ÈÙ¢'(ÛÚc°>�æù€Ã|@Œœ9 Ö°xاül$²£Ljè‘Ñ]æÃ1Zߢ;þQ£F�5jÔ¨QVƒ0jÔ¨Q£F�5jÔÛ –e‡€u]‘J@—a_!”ÂuRó^M¸5q·ïÔ#æ÷ÖÿoVM½X%ˆö Ò¡š__q þ°ÖM†©ý½äí²fˆ6Gƒ Æ��pxó~ÚdÑï Á©F™WÀ‰Òж¸q{nQ mßŶ¹W šòü+Ÿ½|ÆOÕ纷DoÀ��ˆêêáă xäàŽ0�I¯ä:{Ì@[›ÓÃ7 QãšÿžÒ“GvonJÚýXèļÔïùêÀ¹ï—O¿Þ" ´›I‘É�ó9`Îlp~$phöà¢$³ñžÂ_øuÿ*¦›çª*×7ÄäSßyýM¡ w=ª¡’DÍÖ]rkOþƒÁDËÉ þ{ÆÝßü¿�¦+,Jo_ø h2[x„à¶É®…2@ ±W¬+hU¨$¨fP"eT²çÎ_äZFƒ€”¡� Ô—Lxì vÙŸ¨®\™JmÛÛæ‘�­~!÷`ÑÞ�Sª ôæ#B›^6ã•Ñ‚š Ã6À ÚûvÑI‚ƒYý»òŸ&?·Ð¥dW¤§Òl¤ŒbA¯þ#D šAáààÿÑ~Ÿ‚À‚‚y†„ z÷‘JШvýä•�.¯#¾øÕÀôÀ hcÐ�«Ai¹½n3Þ•ø�³7¬óÓ 8<ÒM¯º98ã—þÂÏÀ¿þ;¾ÿæô½uNv¯‡2™UÐqC¦(Î>¨*ïu3ß+¶Ñ3Ô)ݯªß+Ÿ„·9´]GjÌJYÑ|-)VýÚm·¬Ï5n¦�–)ÛS…@l[ª—3`·æTò•¨ÅmP1ý .¡Å÷ˆÇ|èf<^§æõÿWw °ÝÊæ:TÚ¶Sw¤žCCÛkroù¯zýõýk»ûê_'z÷�üÐüæ¯ÿ%¿ô?&¦8OórssÔ)Fd,ëâ‘I–sGØã§ a]ÁiEV³�§uq‚ ã ³Oïfu?Mæy6}G¬PÝÅ*°Ùø1¦yÂ4M˜¦Ó<›Š½Œ‡¾ßJ<@°¯ ä–= "FÛg! „*^úDE±J2奂 äÀ`áJI늅1FÄ)ÖýßNöc³�Üâ#œÅD�&oWˆ~Æ`¶x û22¦@š#(B´(€ÀªÉ�»sÛñ»/LÀÁ1Öë”™¸õgZWœ‰�Ò:þ±0jÔ¨Q£F�ÕÕ Œ5jÔ¨Q£F�õ6¨”‚ÛëèÍ¿§Ú›®Â«Ô,þ«•±’çÄ7páÊ««ùÆ‚¸Ûg¹\c°É�Ã’NÚÔ‡`'j`þÆÂû³©ÛØ3bÛA‘K¶] w‘M¿í—Íë�}¹öù;`ŠÊï}DÂî蛣±îz­FvÉÊ]l¸v KïðPÈ,0ÈÑ©m�o‹ „Õî�ïux¸&„-±  ‚@#\Í ð}î-ø¯£O÷¿ µ¸<³ou;E3A# �¢�äYÆ›`çëó¾ú_Àƒ>äyíe§ˆGèëéå¿nÙìôWPÃúÑAŽª<ï�ì>²¢Sþëú2Îçøß+—‰ ®”‡½×íå]¡ÏP>S”õ�A]xž]¹ßNFUm¦�F> PbwÝðœpf�hPûÎÙÁñì Ô.$€¬ŒÖ}Fþ+™Ê¿TÍpE©Ú Vz“Á³Áþ¯ v‘¸O%í×–‘)h›?ï¤ÕrŒN€6ÂwaˆîÑ}/Ö jÊv•ìÇ— ˆ-Î*�4À€Ž6Æx2å?ÍÏN"!’å?n€|÷£î¬O…€”&èÓ—�ä›Á/|øðÂöªR³ßn¤�½ÒÿÊ*} © =â FX?à ˜ÂWð/ÿšñÝßû^üÙ¿üQ³QHLèÎÌv.õqµóã'_oÚ)kó�| c¯×~Í+ó)i7§úÏÞv&îÖ-é.B�èv‘Œ³µÛßEØ\€ò›x TâCëª Ùþ¸Š³N  »ímã‰îqoéàîÉÓß<χÿgŒ!„ÀÌ$KÖå¼ gA2‡À:{@qPQ¤,HëÅB„5%ä”°¬fÏ£'’p#�tm®À`Lî>ÀL˜çæy6{ú Ö«GI�hCŽÜN?͵ˆ]ѧˆyšLÅï/SÝ'°rÝVûb�0RcN)'oƒÖ÷FŒ4G"spÉ…ŒX0k²í.„l7‹Þo ÖuÁº¬H)ù~Œð§„”²;-dh(÷³bN)×þ_×´é_€m M‚0 6CÜÝâr®D…Q£F�5jÔ¨QVƒ0jÔ¨Q£F�5jÔÛ <.x‡»ÒVÑOôL$´ÿw¶Æ½2Þž»³[ ½·@}øÛ) uþ_B³MÞr¾m»dØsˆ¨�ÿý‘QUP’7§€Ð@p·ÿ/€]JÔ»ƒmœug…_îÁþ.ÕXŠš”îëp½jõ»íÕ.�ûªš¹ß–=èV&ˆŠd 01ÒmcÊÏݹ¹Àí½¯ôªEÿuÀ]/^Á½}ü¬ÇñŸ&þÿ–Óð&ûd¢ª8$e¸8íû›”¢Î@àƒ_úKñâû¾²Ø=nÉŽx½û¬/}k�‡hþöºhc”w™÷�ºðÏäSËO|§½¥Øð‹�¤Èö¹øø] ÛǦ¼— EpN�Û±óÖéC‰ˆg@£.H)Ù?ÇpÊàû— wóŒoÁÀåÀ`¦Î½_ ŒT-Ð�;D¿¿¨œ·ÿߣ®¬º-u‰ë¸> éMGÖæ/ân%b OI¡*³nÊâÖ§üé"´‘0ˆ ü�Sý)ú8‰­�¶M’ds^(*{ŽÖ_ñ 7F0&3À„²Í:H°¹ßцž_7ðŸÈp}ÎÐÓ'!/ýà3¾||Wë�²�ììàÝ~?g?…Íí¡ôIpG�â¬òˆ�¡ée`½ƒ¦'öùñŸükïÇ/û±7ð#?öºí»Xzj^ñ… ¢6ß+]I.gàíÈ(àm]Zz7“BDÛ;ts7¬ ¡ ƒã®¬ehãá’àÎ8›¥E›ê¿\ìke<÷Î>N¨!td¾ Éü¾?¨9 ì÷…€¶½þ°y½µA;‹‹k ºÂ%ëõØõ’pí í#9�| ΟóW¿í/}Å×þâoøóªRJ*"º.©‚òÌŒæƒÙùÇi X—)­X—3N§Öd¶þñî§Ãó|#X¬Ë‚Åß_-öw€½©è¦ ˆ1‚™0M3ŽÇ¦yªÖÿê1+Y’Ýa!”{ B‚ÁÆaÀîu‚%‘Ä€ÉíôC¦²÷nÉÒ÷_#Ì”¶Šo7焜-î@‹ûG·V©j%dÿ9'qWs7b^CÄiŽˆÑ#Üyá|:ã|:á¼.È—§ÔîUˆ¡¢ˆSDNçåŒór®Ä�5­X×PµÏ‹"gÁšW¬ný¿N+â:aŠîB�“SÿX5jÔ¨Q£F�êjF�5jÔ¨Q£F�zQ@@Àgâ®ý[èŒ.þÖ컩h ½}S€\t— tñ;áäÔËývÙn4Ëor‹ú^L_•šní öÆb} ·š-o5…ä}9°ØÐ�KÝŸM?©Í⺦ÌSß ]®²²G¶ BîQ¡–½Þ‹»ÑõIºHí0½H©•®Œd5×ù.ë–˜ ÙÈÐÞA ³Ž®?û™®üipõí›Aòà?]ü±õeó̾oTƒH¯Æ\l¯õþ?‚‹ 5>"D‚e>õÞòTñÜw¾ï ð�/ùç\…nÊGР#ôî£Xò›Ìž½~–ëuÑp=·G/vî5gžìŸåºñ¤—¾뇿g‹ßïlªðéÑgZÜÀºÐΔ ì$ÏŽï¼€Òdê|õ\j)à¶züDvB�$ »Â8n•×Ûù+Ìæ °QÃÁõ¢àß+íýšvÛ&‚€69ð•8 h–öô&êÅõ1º"›Ä|ÿÕ(9ƒ*øß”Î(ê'`ØUÉ.i�ü3&<€�-‘ H’ÍA%cˆ3ˆo€p „�'Wþ;è_æBˆ;M(@žãM >|6rþqÈòI1À‰"Èù5à¥?¼ëëÁÇ÷zî7¡� Øá%⡼GÐí¿o"h€;ðüäÓO§×,!qs8âý{_‚_úÛÿ^c­KK%ʨÔõ@7î#Ú­Y>qç~ÒMñ…¨ÖõÙô]´Œªn¶‰º‘ãÿÚµÃçˆ:m¸}¹ÏçÌÔï¾fÔsŠíøîÆ{qØ ÎF_°uÀ©À¿ƒ³#Ñé•[§¹Û'ÜáFwmh§W;ƒÍ4¼#•m¶¡›ð�«ëE%õ½n×ã�ö¿·ê�yÿ3¯¼òÊ?‘sþK9#Ã¥Dø8Ñ‹!�o "¤uÁ²®X–Å늜m¼�N'Ló\û<çŒuYp>Ÿ‘;Gøñ(× ®XC ¦üŸ&Ä`¯ŠÇû¬)#­©’ zÀ_D�SB°¬ rN�ìs''5D0›»AÙ€d©.)§�sA¿m’úw‘æ ˜š_D/>—srÒDÆš³ +&##D##X_ ÖuÁù¼bõö«*ÂÂÈ«)ÿ%Ù{BˆÉ8/ ΧîN'œÏg,ëjä(Ø�!IÆš#–„i^0ÏæiFˆ#kŒ5jÔ¨Q£F�j5£F�5jÔ¨Q£F½ jžfÄ)bŠçóévoOÜÐÿ-Ò¼Á`‰À½ÿÅ6¨êý•éÂ/¸Û z€Œ61»L\tªý¾­p;}j Ïš%­Õ{ î¥{`^,û«]r*t—sOW@†îÈzÀ¼¼©�$¨ïÇj¯/5 :0@™À–ò¾UXê¶Ÿ{¹&)ùK¦ê&·|f2pÚ>o΢"3í¹n»MûX½ÇbºõOÏCØ’îÛ¯$Ô—? |~¿?Ýþ¯6@ÿ °ÿõÄëb§l–î¨`w®Ùq³ùÑsøY_÷¿…dª ‘@Ó'°~ô¿µ¿9ûB;ð¿—±  ¨ûÍæÞÕÿìÞ)é§¾ëG¾ßÖ¡¿¾->€GÄï1z^M%œ¬d`| P¶ñ¥õmת’)ö¡ ŠÑ”ÿ¢fÕŽ‚+$e‹9[€�[Ú—ˆñHÈ•¹½^€t1B�E x4GèIDnçOþÙ àL•Â#ª`õíT•}ï" Ï8÷Ô ®`Ý�cŠ¥ÿfB-íb4€šÙ®@v`·Êo›S@ˆàÙ"hÂÁ�ûè-È~ý  f‡�bÿââ#|ÅG#œ úØ¡6‹å@†èàè•<¿#Òk?iÍLu&D^ÏÀOýEà]_?`ç¯�AJ,‘ã}Ö Ú ýgà¶5Là›Ï�œÿ‹rP9ã³?ãˆÿËÿö‹ð/þ¾×]U)­�ÈQü D;�¦ÆQ›ûêl³Ù¯þº)Ú­f—ÃE6#§=l q€s`€�U¼îdê~}ýC‰ÌðmsÉt‘�-×Z81‰ëz[âu˜Ý€÷ÚuÄFí¯["‚^¸ýPÛN·ö^tÕ¼÷6êÅ ¸î£úÖ=a@Z×_˜rŽ¢ˆ$É"9'ímûcŒ�£Ïi]M Ÿ³ÙÕ§U ¥„óùìDÄsÎWΟÉî9XÅÉ’TÏ!‡€'ÿ27€¢¼·È�²/õƒk~ÙØëb$…k¹ö¦Îw{þ”±® N'Sѧ´â¼®�ä„€ddƒ,FíH¤”±¬!dèT¶kmñ¨1Òáº&œ–ËéŒu5+ˆ1`Švob°Ë3Kí×Ö¿„”3²$$É8/3Bî§„e]q>�Ìe!¥æÂ� p"Bâ„ÜÁ@Ì`’ D ÑŒeF�5jÔ¨Q£65£F�5jÔ¨Q£F½ êxs‹iŠ˜0#ýmõŠü¤ßïÔË÷Q•Ú�Ñÿ— T=zdàøÞàªS>]Â"Z‚ëÕ@7pØPD PD¦ë¶!UÅHWÚrÿ¾w-¶c¥Ývà�á…ðÞwä}×ÐîçšÚìê¥ÎƹþL;A`vçñ²#ëô=ÀNt™7P�°·¦‹s{ÙYMQKú¦—ƒvƒ)v1´ Û1ÿl­S…v`8t`%o3;þIø²âwa:<²?†©SÔG¬qðŸãf|ø(¬í¨صÁ¡ÉÔÙê«bù‰ÿù¥¿o-¼BEùæ9ÄŸe ÉâÀP(„¼®fó¿¹î©mJž½’�cêª}f†0ƒ¤; e(­¨'WÄ¥±‘>¸‚ãL°9SY� T H:}r"†r#`ç jýPÈà7a%YaMnâìõr_]±_DÝy*Û4gWðK.û)àÿÐÁ\Âlª}šü1ŒE'PrW: –Ü ºÒ?�x 7`ºµíÑä¶ÿÜ‘~@‚èÈg@h^d£‚Äw`zþùµõþt$ y¹Ãú“ ó{¾tü¬vnÔ�[û1]Èåx3j@%²pu"0@M/€úôÀ,À’!!á—åCü¶_û>üÁ?ö›t¦æ|ÒDìÔ­Eň‚;];µ<1 ²ˆtÇâ“ÖJŠ+.›Áäc¥ÚîxÅz^ ‹ÈÁLªî mìS·.ocn¼ �ڽ̶F¾Š€Õ#;¸‘ˆÝ­�Ín]Ü×A÷àç0WþÓî^¡8lÖíú²�ñé~߬<׬þ{†:§Ó6gã@›m€”ÒÏ|ù“Ÿ<>÷ OsÊœÒJ)eÍ9U�>F›Ÿc X“ò¦†×j�_¾ Ð\â s®JyÝ8Øð3wfBðsÀî¬RœŠDLu¿.)­H9�S60~Y@LÀÃ^_³Ñ'wu0s�Œœ’�˜°¬g,gû:;8ŸÖâ ¹tª~;Ns Xׄ¸,`P1›ªÄ#˜/Hkƺ&,ËR­ösf�28Z_6'„kŒ€Š‘4�4p¶¾XP $‹Å1¬k=g-â‰ë…Þ Öì„�CG˜=Râ>„3ôµ�@õd± 9ãÿ/¼€¿öw^Åßü�×*¡Jû‹¾‰É‰AêÄ ÚÙ„T7-kÂ=³Æ…»ÌµI²;ÎÂáÙ­sm˜t³¼gУ�Ó:·›ÍlÐ]KÔ“°u¨ïa‰»xøZ'Y,¯^, �üº"X”�²9‡ˆæ–NÓ�ôž@³9†ý¤[Hª—ñ5"@ï<£º_Š[mù_åwû¡~”6tï0ýÈÿà¿ìçý‚WU…U•,ßÞ@köyK/½ÏÌÑòë§y® rÎR·�sv"bî€ÿæPã XÍŒišbìî#Zÿ™•þŠuM»ÏÁ@°r¨q å}!ð/9 ±@u…ŠbYVœ—N§3–³©ÿ“»à¿PPf‹HkʈkÑI`ò):×sgÇê„éSSºsK6îÂ0GWã‹`ž"ÎËŠu9cMk%+D2ÈÉå>®œ!ÆŽ`DÙMÐvâaÂ!NÈN‚5jÔ¨Q£F�ÕjF�5jÔ¨Q£F�zÔíÍ!FLqF|°Ø‹ÂïÅF;µdÛ+= ¦ö^! ´�Õ¿«ýÒ´Läú½´¯{Ï^ YþBÅZ[᪻­Ý°áme?|ŠÉ–ݲ¿mŒ¸¨)¹‰¼©E[Õ}aTõ=¨Ú÷j±«ïTñ-ßXj6u±Íݨ7Qý±öý‰�År�Ïw€PßV?‡ð‡üåa¼ï ýõ­xé7¯è]ž@·åkmßÌÝHÔ­mx96º—¤ðÖüŸ†Ó@7ö©Ãq«óuÿ;+ÞýþáC_úŒô�3 ÁsØ@_ÿÛH¯þ Pœ`H[gG¯ ì&*DGò©ü¹ ü–ó¾þè…ôÊKå×ú�™€‰Ÿ?èð.;fh ðÙšÔl ²E@9É»K‚=*ýX7%ºqŒà„¤d1ï (SëK€Ó s �2l€0·kVÔ³œÅcX ÖñD b.¡¨Î¥Ž,@µSíoÚ§We“;'ï´m±hhÿ; Û1žaû…€ä:½ˆ/§O9QD€)âÿýo|6~ñ¿òCxåµÅUÀ>­xÙϲ9�¤]¬SºY—Ú9//mMý WÍéõrÆ©ïì”úTÚçiv×�¼[Û6Jæ­{Lþ™»ùšZ€»ƒGQW«GnPp�‚NA-eœ—u¯äÕwß·cûº[Oµö'ÚÄßô$�ÒÃÚE&\Ÿƒ·t¸m?êÆÅaós?ïwëëÓ'OÞGŒïEVV[¤Ií¦¡Ž#æ€L•B¨$Éêf,‹EŠ”2ˆ ¶®IwÏ$¦®ÏR•òÌ„'0s½§"*ç—|_¦§”\Aß«òOPd‰`'Ò”¾ ì‘5ÅÓGkNÈkÆù|“»;œO'�90B�Í›� iq(Ö¶Ë*H!�@Ⱥ['íÆˆ)ï�|É΢–šâŠâqœ˜ç#â�@±&Ìë‚ÓiÂùtÂy9!ks$`Î~ì\ÇAŒ±ªû�Ta}aÄ©í þOÓ7Ç[æÁ:¯ã £F�5jÔ¨Q] À¨Q£F�5jÔ¨Qoƒšfþçy¢ÂŠr`‚°1›×kjþ­o¿V`¤<,îþÖ[£¿î½ìu§tî,u»5Õú._à"I@Ûƒv•ž�ÀÕ-½m[;[X€´?6v§kusë±¢Î#Ïc'1Ë4{ÀÏ?×YÜëÆ ¹Ùì÷*ÁvpT•�ÕM —Þ—læ ¸®5;y_DM)Z•¥êêemªÐ= Õ[<o8¿'ë{ç0 ½ŒÿŠ¢v¿•¦tɽªþþ\=£™÷±ü|é•-'’“ Ð]‰`:ÜàË¿ñw�èèàZrz‚ž>Œõ¥ou€¶Ë„g�;sÃ€Ô ¨ðTÐLTo 0–ÿÿ"¿ú’JlÿR�€) ¾ððÍ»J.T”mœ�*«�…”AX! pÁ%cS%+IwA3,’€têœ.` m‘|¦dÛãän²u( 1Ôí˜Å�£Öçâ$–ÎÒ�ji0U3¹@¯´¯òk½çäÓnéÅ›ñ®m“:ûñJ¶ÙÍRê¿«[Ý3ÀF€`ÂÁÜ!øðÄGwpÐ^ÈÈ%¢—6ï!ÁñðWÀíÅÆšè ds ¤Öÿ<Ï Üt š&Ä¿ þ øü)hZ½ a}é/cz×/ÍïéúT.m;4·¾Qñc`ŠõÂrÒ 3(ß·Ÿ ½{Ù“@Áx׋·ø÷ÿWÂoÿ·¾¿*²©K{0w ÞÙüûN¨ÌÏÛ9¥™ØÇÅ!@¯ÌW•Jà ûfœ‹�Ñ£âN[{‘¹*lHu[ЛvQ=Ú¯7´q7hëW™GEQAy8ðßöÁ ¸òU˜ ¢rÓsmR½×é¥#TèõâM®³ð�v ǃ� ÂõÉ>¥õÉÂ9 ‹©º"�¦iÂ<ϸ¹9âx¼ÁÍñÇã°¬Áø,*µ¯ŠÛPˆ‚°®î @àœAdn1ªÉש.ª ¦\ÛÌb#lŽ Õ )ÎFN"4‡€h;ØM@LÁ#:7�¬HiÅyYp>�q:��ÓZ íLR=6föxŠP]‘D9eËöôu„ä‡ÙâbˆÈ9ÙÔóŒ›ã7Ç[oŽˆÓ ELqB Œ5-È9Õ5 ¶«»n˜âd�²B àeE–\÷bÀ4GÜ�¸½½Ʋ À¨Q£F�5jT_ƒ0jÔ¨Q£F�5jÔÛ  K0•f�œ÷ØVÁ•®Àžt©ä×î�M²¤àº¬è±8o:˜êž7*zmvò®–-ÀN¯ÄߘW@×|”ئ†+dk§6ëÿîØIÂþ÷¢ª(T›hÓtI8U î­ÝýNÍ�P¾DZÞ3PˆTˆ�òÞ:ùŠ'>ö'ºAJ»?tÖü›H†ªE�/Ø}Û­kg WÆ pÙÀ‹f¾IAo¾³¥GÓãî )ŸvißTw1uª˜Y‘¥à¥„Ÿ÷ ÿ nnßá×Âèäï[±~ôO�79ãþ W¬ýÚ_ƒ±½×�ÿ þÿäŸD~ùÃL^ @ÀßñAðá3€ØœˆÉUëÑlûÕ¬ñ5%ëÒJ(Bv‚F€r±èúˆ¹£äêR†˜ËFGÀ¡œMe.*$ v]ÖŽ ì6þvjí·ÿWP–d÷ƒuw†Rv…|wE/GUGЩd’’° ŸÎ8Á•뀮ì õ$ÙÛ”ç\N±«ÿ#(Ì ÎO`š`v� ŸÏ”³�H¦¢$�qÂñxÀíí->z„G�âööóצ¸cCdÂ<Ìó„ãñˆ8G�yücaÔ¨Q£F�5ª«A5jÔ¨Q£F�5êmPYrQðÑ}ºi80MJÍ`g·»4êg¨æïjïï 9Ü2Œ·Jï n£W�íÚÕYl+dèaýl{¯ÿ¯Ès|ͺהd�¸Â49 XrÞ÷ªE-VÅ Sp"CCSÐÒÆBº©ì´·lÞöÃvò�êžxA}îú,é«uÉШÇp)ƒ÷÷µ¿=ûYÀ—^4ýrÿê=H=¯ÏÚ\ë‡á©Þú÷¼ÿbßT-®}$>[ù�ë|‰7;øÒ¼´Š+ÏÍŠ,‚œ�ÏûÙ_ŒÏú¿ŠÐB´üöùä•ïn9÷µ’«¹ÍŠ»]}óÿ‘g¿³}ÖO| ò'ÈðÓ‚Ö“Y>›òÿƒàÃ;üüÛ{‰# œc·É·æ$k‹$PBíÏb'N¥QÄÍ�€ »U0©+˜áà=Y )�8´üù¢e³þ§ ŒõH�øŠ*8‹Éä9¢“uÛ÷Àîà@n.ª`´8ц7wÖèϘqý÷e£ ‘ª³ÃNýO%ÛÞT¿ç“Çøß9šêž&Sîã¦@Á‰V««ÿÐ�l€A„à Рoí;ϰ8€f‰­¤öYÍ=ùÈXÎuŒ'€8ÜÚ¶ø(¾1Š˜uÿüâ×cyõ/O~ÒI¤ ÕW±¾ôW0}Æ—ƒn>»›Ó¨ö¼=Û„Çtc2»“Ë ¸yH3ô�Ÿ–3@wþÏ¿ó]ø?´à£;¡ÀÞ ,gT—“²žàYôÊUi!m2ªtŸ¯ —ìGåùQçÞIñÙ¨�WÏÞU§ *á€6Ž4 ­Ÿ£Ýz•s¶À2Çœ²¾2suÇQwá(´ˆTнÞÛº©¨îþÜÖÿŽÀ ›ùmýÔîÖcçÊpßZ WæyÝT!9ãtwGªJD„#MÓ¤7··xøà?~Œçž�=ÂápŠóy�ˆàt^ÜæÞã{TB@Œä`þ 9˜:?å„´®8ŸÏˆçB8ŸÏÖçÌ88�¸½}€··8ÞÜ`ž,cY“̓’‘ÒŠu±¨„œÍE „Ü98øN@ FtbÁaŠqnñY0ÅqŠ …ÁÊP…ƒþæÙÈÓ<#†àqFnºÂ½òžüø³÷AÑ9ĉ1M3ÇŽÿÓÈÅí NÑÈ‘�adMf²{¶9â¸&¤¼Ök™ˆ@�Ü µ å &ëιñ¸\„bAˆÖÿ*ƒ0jÔ¨Q£F�Õ× Œ5jÔ¨Q£F�õ6¨e=[>óš�ÌVº@(™-øÆ»¯.ï·zP¬H{e¢v@Å,GgKOûðlT³÷î�?U,Ü~í³¶è‚=vÐ?Ïòå 0!gTµrµßåЋÄê$r “.úE;À£�)6 F÷vÝ%šƒxßuåÁ3>_^¡.ŸýRÇÚžC&B.„ "ßw‹sP镸ü/€;9°¸4oB,h¯‘ÑÙdoö²m]޾ Âé³A´kGRIÏ`ˆˆj*v…¬ÀÍãÇøÒoøm¦ªæ¢lŸ�x€¾ñýHŸú¦r/çZe3¾6*h2%wÉ_7åýäà?C^ùn¤�ýupÁ¹§®“b@|ñƒ ã‹•p@ž±NNÄA`#' 8Ðk³Î…ÂHC\Ì-È"Ñq[€ÈcX¡QðÏ€�ƒ„p0�E °K¾ˆ4 î@Ñξ¿D 'Õí¿9½Ž<ð€øý¿ë}øgþõö!£�âZ=n ZŠ�[Ëfš.6ÿúæ,!ºgPìUê}„K‰)(×`…´‹ˆJ7—úšâstO0Û:Àt­ØMÁ%Þ w—Ñ6+xÔ�X"XÑ€Tî¢`”sí)qeíƒGçÀ]m|N•k¹B(4£âÖPOA�\èo¨_2ÚùébäbÍÝz—Ðé|6帿½¹Á£G�ð‹/âÅ^ÄÃG� Зªo€è‰9¬«ÝW¹­=cšŒl8ϱ»'0€óùŒ»» 1ž0ň”3˜‡ã<ÀÇpûànnn0E#ý0/�làÿ90Þ@w#V˜â½�“YÜ{Œ@œ `/Öø*6¥|ÀšRN ³�‡L¸9â0p˜'ÄÍhEr½'àª+CΊœW¤”�³ÍÓ€�Ã!bš"â4#tëšøX)ä&r7s-h‰&‡ƒÅÈœëg Q@¡�,È)aMÉ" įeÑÍý˜:qJ²"ç„”Vä´@5�4o¹y£F�5jÔ¨Q£`Ô¨Q£F�5jÔ¨·C�—³ƒ ¦T{fU˜*ÀH=Ž}ñV ßÞá?õ™Ë  ¹nw ÅKÇd ÀFÕ/¾P»üZæjiË�-­7@ÈT€JéØÞ6wÏ¿-y½|©4÷÷ª«û[,¸^ôa9:íëÚÛ’—w\Au®™f×ÞtP•»í5Çlð6Ëtf0‹‘h*¤ Ý6vw¨ºÃ™ á¡Å;Ü  ]‚¶ÆTê;º‡¡o:¼»l?K÷&l>/4O@JФÀ/úå¿ óáyhN¨(21tyëKßZÁÿ¶aéˆ+ýÕºcqµ}(nº|ëGþr×»œsp@|ôÐô<ª½(ÜË„ënÈEئ�4¥ªBa™ %�¤ ¦äŠe‚Foi¬án骢R9€9C˜AÕŠ_š `’6—¶j0â %ë/mê}!#4ð_›%Y;�ѲÌË¡îý 2À[‹‰ Л¿•¨õs!%0¨Î!ímÜ(ûÿÙ€{ŽF (ñE]›€äó�)ñ Á•ÿGûnÍúŸgtÃ~ùgt5"€.`] ºúUÀÿ[Wû>‚zð¿�7–}óã¯Å²|3òú‘Žô%Ð7ÞÀš¿Ó{!èð?gå$8�cBa�Ô¿—a� @lÇ…ÈŠððó€tBÏWüÂ-ø§¿î!þë¿ô˜ºµ¦#¬iñ_Ð6@D»]÷.;wòã«Öõ›éD7S‘^›küov¨º›»tCÍE§_´Ç›ƒÊVÕO¼°6Ý4Û}ªó?9ÉMÁ,PqP6°ÏñÜf)"0Êì‘8�‹àD"TÒOÿ½Dô÷->ǧ—ûï W‚®Ç `kˆÐø\zÏf†è`ù<ϸ¹9âöÁ+CIm‚šZ{Ó…$ÀÊšê³S°µµ|Úºýw§»Ž¬?·Pp¢ýû·)Ù»º4x‹u?ø¿=;?‹ÍkCÿAUñy?ë‹ñ®|)4­þæÙ{¾Aúø·®‡¶ÍÉ.ΆS€ñàŽ\Ÿþî¶u–Ws4eÄç> ˜µk˜ »Þ” P�Fh” �S1¥xNàµ�IŠÀ¼‡‚(@C$Q°AGÅ-ýE bÑ��b7‘Bâóý™3¯moSlº±(àn-¾bðéõÜ[tN>±E-ðd >‚ÿå\; C�äañDöt@q€ƒ*ÝbÛÜ4—±ÃFˆ³)öãCðƒGÛ9× ‹�0ÐyëÈk‘¡wÊÿ£[î߀xöcè�{íˆ pÄôί�üÔ7ù6Cˆªž~ ôñ¿Žø_š_ì'Æí˜¯'ªLÁöe“»,„f“30½�òúCO/CÒ0ðïþ‹Ÿ�ïüþ„lÙ:ÚtsN9¥ÚMÚ• ´[3`7$vóV™wÕçBÝeۣ˻—2çk¾Ñq¨Æì”ÉǶÙbq´³É¿:™õÛøïÛÜŸ‰ Ðw×”âF `ßÞhMØéíý ä·XwÐ^}} —ÃOH]{÷Ñ Ý6*¡W»W”g^ÞÇÃqšp8ðàáC³áwþáp@Á÷$X–3N§îîÎ8Ÿ¤´"­>[º‰�ìSœã¡(ÕUŒ|XO–‚Hk!Ü`žgÌÓ„)Fpð¸màµYÜ $gWãÛ©ÌnÍo$†þ›½¾�íYC%Q Wû�sò©ÞÈYÜ^ŸÄÇ�@Ô¢nÊz§€9ÎÑâ�Ò*8ŸÏX§ )/vy#t¥5�E±J² \ÙɘŒÀT£¶%Ý=™ƒ‰·°¶ªc9Ÿq^œO''4t¤S¨E`ùWñiɺ"k6"GÎ�ìñ4£F�5jÔ¨Q£j À¨Q£F�5jÔ¨QoƒÊ)•¼mÚšÛ_ú?�* þ^-I~« œ«t�_Ð) ëçªÊ±ÀÖ%³ž*(o �\À˨µe[¨ÖÏ*ºq °œã†›ªÒ¦‰‚ì°ã /”»Ìb\¡oñÞº�fCíÀ_Õ9Vå$ëιW5zã vegÂÀ3qU: ¬@Uæd°÷èñzq {RBu<Ølb§ºÜyõW¨L·Ï‚mè~ ˆ´U”²¸/€��Eq8>Ä—|Í? $WeSp¦ç�^ûèéeñ½³z4Rû1ºþ]±mVýö·»ïû4h„×DˆÏ½Ì�œM­/ìÆÀ=W§3�ÄI ¥U@:UHV°Nä¶É”!ÓÛ礡9@�Yƒk`�F€XÅÚš�V bYÌ&eèdÄDW§6ÎPb0‘G³À_�¬@(N=´ßG`  ï†É5RÄ›ÏpWmGTïDfÛOEÍŒ vÎQæ Cíü3  Ä“©ÿ+àÎ�ækÞö›mr©¶‘øˆ·àøÐÕûÝvÊñç‘,g@ ¯ˆ¯ ̇ü?º£Àlû¨£O[˜½8yŠЀÃg| Îýï�Ó 9gé•�øNLïú`zØõ/oÖîcˆœÐæ• bŒ@n?xúa‹Eˆ!<füû¿ó³ðï�`¨öêý6Ö+¼;Ǧ„¿˜…ï_%7É$º}Ù'äÎO¥ŸD›Í?µ9¼RåœLÇpbNq 雼oábýD7]oõì×tµÊèæßà­Æ!ê.!*‚,b–êþµ×ád€‹6 Ùøúã.®Ø,(…“²¹'莡’ pén#[›ÿ{× b �?Æ4Í88�xðàÇÃÑÁm`YV¤$Hë‚'OŸàµ×_ÇÝÓ'8�î°¦ñK™cÄ4OˆqFœ‚$Q@ƒ³Bˆ˜¢€È€ðiЦª/ïÏö/ëŠÓù„óé„ÓùŒeY�rFÎRÝ•˜ ¡îû€yžc‡èë”Í»ª 2G»³Â0窊5õ yºšêu¢[q@""Ì`LóÇã"†ˆà°Ì8�NXR„æFXXÓ  ¯âÓÛñÏ“;X¬Ó>¤�ã”­ŸEŦ'D,ë‚å¼`Yœ—iMkÃF2°¾tõ¿v,šÊ‘ËIH’�§7jÔ¨Q£F�5ªÖ Œ5jÔ¨Q£F�õ6¨ò0ž ļG™7>ÿ¸Š$xm5üÝGûÐzeÏ·~k¤‚4®ºr-öÊ 1Q-»¥?UÕaÉŒ× ¶M te£d©@LypNÔ~.ŽÃLM [A%Hî\ pOŠ^²IA�Iw¹ôýA·ãlKu•[0°a oÞ)à{ÃèOª}FÛ˜ºçœl°Rj )UÌšZLÁ.7»F´÷™Ú×ö�JOðíPý®µ}Š+Îÿõ³í|õªÝæñfd€û¸ô&ïÝAô¦V…&ÅÏù%¿Óá9ˆ(2VÍÖ_§Ÿ‚|ò¯š*»J›=^¢POx^WàÃ-ß¹ý~÷·ÿö™†‰o_…G�5�á7›ª“2�L)\äÍ•@U©®±œ;‰¤«eT¡È ÕwÏÁÀ`v ŸK[½ÝÄ×eR��ÍM€, *Êìi­Û¡¢V§ÎFßÏ”¨‚Õ@Gq2öžâõ!ô–TÀ÷�ï¯ûìÿeûþ*^®ü“�úTlø]ÅOT­öËy'ž@Á?Sœ :GëC ùµâd š ¨ç#8Þ:€k¯WCù h4�5Y€&Hu`N>³Â�mƒ§Íy€š\Q«ûY ÀôޝÀòô›-b¬æ–¢iA~òwžû9M;༿Ò]n‰G; Ëæp@Ë ðã/ºœü Ê€.øªÏ?ã¿òö;îìZÓ+K]çXÒÇÙ4¬½©ÞËgèÓšaʶé~%¼^êððŠž æ.-Ý"Eèã Úb°ý²š­W °@3™Ç~m†¿ÙœÈcùêFè­þ«êÿê"Óú¢»6"Zí{麳õi S9o„.¶èÚb{Ïuí[!ÐíóÏ?oÊùiÆá0cšg›•ý², +°.g¼ñä Þxý <}úëº"'kkˆÑÔûólêÿ øŸ·6ôê>+d*|föXÏ)g g¤uÅyYp÷ô)îN'œîNHë‚”’«ÿ Ä1NˆÓŒyžq˜gLÓ\É v>2–Õâé ¸-0BB–Œœ3r¶yArª…ø9‰1€AF�`Æ<0Å °L‹Ç)`]ÏXàœV¬K²$¬kBÎvžbˆ˜¦ éxÄá0[TAˆs Ü&‡”iMÈ9UÂ…dAÎ+ÖuÅyY±.+ÖuAÎ~¯ë}ZîLýïW73"G°÷CΊ¼&À¨Q£F�5jT_ƒ0jÔ¨Q£F�5jÔÛ¢ìÁ&s ª ïk˜×—Þbíäüõ¡=.òæ÷Yï„kÍôÞ·»L;0»üY€ÔØUÛbEÎ ‹)îÈUÿ)/Ÿ/Àt×Zv›î€ÐVfÙ@Ü™ Àïõì{P¦%¸)ç¥Û·è.ïYûxjDÕ–ÝÛGS#%`ŸQ][Ôgu#~¦ ¾“6;üæPÐøn/êÀ—7¾’Tû.ß|f‡ùl±Ýn¼]8oZ£õ-Rè@&� Ñ¡x÷û?€÷|àçÈïS@¦ 1˜¢?L¸ÍÒ¹=(©‚¢)öùààxD%‚h‚Ùÿ'€3(eÃd�eøhá ³þ§pƒJ:‘Õû~ôÈ �3D€²_è˜gßÖ³þ縣ðõ8‡ÕÀþ|²íó„é3¿ùÇ¿8—ø‹¤3äô*øðQÐíçvóEq¾èÎ1¹ó…êîm±&æJ0Ùû¦Gà}íû�××�ó@ÿöo¹Å_ý¾¯½‘7Êsí®g0UKû�ûE浳ߧ71ιL oÓ]yÏvîéßÖ¯ w•ÊP£íz´7©¨Î5¸r} 9xtJ|êÖ…jòâó�ŠV¶Ô–æ¬S×QwM¸þ‹}5œïHöáA=à¯�|§ì¯íÉè#D·×ø>€™ððÑ#˳ïâ�rÊX×µ¾&b÷Ož<ÁÓ»§U‰!0¦h@ü'õ !"'«sN®dÏw#f'°Ï©NX\×Õ”ÿ§Nwwf±Ÿ²ƒÜvŸ£Å ̳9̳,5C-ž@²ÍߤÈAB3mú×ø¶®IÎ�U°–^–æ60M�#r6âs@œ¦zÿ"â–ú’±"™S„øËyí,úÓ4#焜˜3¦IœŒ îŽ#*È)#¥çóâ ¿RΕ�Rª¯€Wg†ž8hÄs[S0—Q$)n&£F�5jÔ¨Q£J À¨Q£F�5jÔ¨QÿYtõç^e¸%tH1uÀÇNs~UïÀpS”ïÀB¿Wô@I§lû¢K¥»¨6%§ r6»ýÀ왽]µƒ}TQ.C¦‚ëíþ¯d®ŽÙZ•üÒ©õ;ûÒú𜺶çÎ ¡`Ä=`¦}/¡6© ´°CÊ·6ý}´�l¢ýIÓÍÖ\¨•ðLÙÿ•Q´où³6qu›]´üµí¼©”v§ñÍwÕ}–¨ øâ_ð+Q•Ù@qzéÉß…¦×àó{Ð=tVÿa×Cn…ï?˧¾ ù¥¿·ýW¸¿5Ì·àÇïr2ðÂA9Ò¦é&hU÷#(xçâQ6Æ LÞ¯böý*@RS�[¸7D28¥.BÀIØ“04FۃضPÀ•äÛá $� ÈÄv k±Ågx™ÂT�ç!j‘%@š�~ý|uØ[V8�§'tgØ/ÝbµÑõO±Ù^7Ö'¾ýÀ€kK˜Àa¶ó·fÃÁó2JÕÇí}áâ£)ðL5³[s¶È¸Àdt‚©õ9ø6Èmû‰œ<°‚`àÈ' ŸaŒ’ìQÌSgýïÄÖŽ jjà¿êj’ŒP�N€Ü©@hz‡÷|>Îþ~„p€‚�ϯ#èŠ$+"EÐÍçXŸ”Án·_|F´¯B¤a;Yî²$ÐÍgAŸþ pºƒENÏ…þ¥o ø}$ƒY·s´9þGR±eHzûy­€û&Ÿ^·—noPoµ‘6hc[r•mGY�ˆ:ÒU™=wÄ„Ý$ØGÇl¬Y¨ûý"C@.Úa ª»èô–ÿÅî}¬ *øOÌÍ]çÚPmlÜÉ ;–þ@ 7­�ÍÙ®Sz±£‹¸Ï¤Æ 0ãææi]k”�ÙÈÛš˜Öv,çóçÓ ËÙâ-TÌ„8™š}>Ì®Æ�`2ë}#,¦\Ï 9/®„÷ù‹ìþ£Øÿ““QRZ±,+–eÁÝ�‘Òº"{4`®Ó4aš'�78Ž˜GLÑb3$e;† `a¨Ìvß^—Öß’¤Ïñ Õ>ßþ‡ÃZ•øê$¿èŽ1EÄsÀ .·=õ:±x ë;s(*þc:`>�À-"�˜ Y�òŠe]±,g¬«ýlçÈúP¤'Sp«F°v‡@î²mÓŒ)Î`š  ¤´âÓȆ5jÔ¨Q£F�úÇ¢`Ô¨Q£F�5jÔ¨·AQ±ÔîêêóÿÍÏ„kðèug€*�lài¿á>›{÷Ò+mÙ©%]I¤é·O½â½ÿì^u_°Aõhê¢ÞæÈ]œ:ð†ÈÔd +÷HŠ’‘:«eî«%4Ùö›Å€iƒUs—fÚ¸ØçÊq_‡¹›r¾½¿(� TÁí›ü×NůWÏ{ëWmr–/Æ °‰@Ð�ývY ;×€-²¦÷n÷*màJÛ÷Û×¶ôV+C ø¼Ÿõ¥xðð�bÅ`>Bòë�OþTõöFá,¾¨»©�🹳A—Ë�ûö_à.Œ§éˆðÜçÙÔ¹ œU(R³ì·g š¢‘(lAòÞyB#, ‘B@qëýä¶Ð>§(­f€Øp��ß*�Å”æ%ç<‹©÷³!ûïZÛCÞ7JN†(yó�â^EŒ<@¼UnŸLÑ*]¦¸ËY��°É³¸owýÓ0)Nê.¡’¨¨÷Ù­ÿy6 ý,€ž76ðTbhvàÝíûù`îÚ  MN4Q›[ˆm<SëƒoLýÏ·ì÷qWTݲð/ €"«OÀŒê"ÖÞJ@ˆÝ…�q"�.@^yjÎrrð­ób¼ýðîë'ÿ> gë½õ)ôɇ!$àp š?ÃÏ­t$=í¤ ÍnC.fÝ­ s. 0;@Á�6ôô,O>Í ºfüÖÿÉŒ?üm?þS ©ÇT¬ö7‘05DE7N$ý|£Òš¸uWé§ÈÎÔÞ#f˜`êrU¸ÞMâ»y—®/¹öM-r„Ú÷^ù_׎B Óæ(P¢]ö@y›åÛ{¤ƒ³‚dãbÓ¢Y*ø_�¡­ùe- jJ~sØ^�EůÛó*髬cæð Û‰ÿ¾û�2]t qrp�RBL9eLó„àjþ´¦øvEy ˆ!¸?ºõ€9v(RZ°¬ Òº8àm{›Ïb`¨›3‘dëç”,`]¤u­í À�;p8p<p8q˜#8DH6ÂŒ×Ñš(C$qÀ›% ok£¤ìk€"FbÆšÒjê{q"„ʵÉ6ˆÍ) 9¥”‘R®ý‘RÆm¶y]›ý„�°™i-vÿ Öe©ý`|1#Ò… uÛª+rÊ•ÀBdý§É¢ŽGÄ8›û I‚ìd«Q£F�5jÔ¨QíñèQ£F�5jÔ¨Q£~ÚWÍ'ÚH÷¯!o¾¥+>½hªBÚäòn<íÑ�ÿ¸èÞF 0ÙÄÇcÕji^€öÚj–ÿûôvSÎS¸+à¬æ‚¬ŒPÀ¡²­j ,�ú³m[;P”혀 ÏÁZKj€üÎ6¼€ÿ[îûŸh³‘vì-eÅh¥ýg:¥{� è EU)÷ƒé[a+uÅ2š6o¦Ú'×ü¶[¬ç¸7#û¬æ8&´óqÏø¿Ú%æ|ÞÏùe6ÒÙÆLœÁáX?ùM-ß]ÙÕü®ô§Ð¬ÿ©xVp;>æÍõz÷} z´M0ˆñ…Ÿ„”S1zAÉ-û5ƒV³sfèÔ,ë‰ÕÛÕe­ö`qMÉè+Q®®ä´6‹oJ�Rž „‚B°¬ê`*W¡[!ªÖ.@³ú0ö¢¨i.~œ\bœ¼²w#1 r àïÕÎfþ✗cè#=vƒTpW)¸ ½��‚µ›gS¥ó‰¬öùì$¦¿�hŠG³ñÇÜåÛgózû{³þ§bÙÏÀáÆmû§­}>eåe±6èâyØì‡?ƒÃd$š�¸àêâÝ<ŸÍQ@ ™àdŽr‚ÈÙÝ  Öp@|Ç—!ë}õÇí¼9Ù+?}xù{Þù•vÌ ÙÇE!|”ye�hFÉÁî|üJ·^^¦Ï€®4Ó�gü¿1à_ú?½l0x�ÿÛynÆ*äyòTçôˉ YÏô}ÓV™ +_ —S"=sµÕæ|Óg¯PÓêëNoPÑÀ逸ö360¸wÚ-4ÑzýT~tË¡ÅïøÞ˜©�÷Î ÐÓG×lï#Tw“¯v.ò&‘¯ºì¼…Z—§ÓËrö±ÅˆqÂñh–ñ4mc Z„�ÍÝå÷ò¥j 9e,kº,Hi1 ;gädNÄls:3WåÛl^ÆTu^Ðæct;þ q2ûÿyžq˜'Äiö϶ˆ“JòSÚ�뢠߇Ô~kç–:Òž}^²"g#C,늸,�˜M­¿¦ ¢Âá|Fš2ÎKÄr65Î ëºvD•vmÖ8ÉÕqA²lÎAœ,2€)€È"XÎFBÊ)wcÍúy.ý5͵¯Dš)Éø§Â¨Q£F�5jTWƒ0jÔ¨Q£F�5jÔÛ žm‹NÏÂ@Ÿ±Á~«Ý®YÈ_¸ 4Õ`S}Úû*ˆÐ[ðûg*nÝg$ï1æ§ÁpWðsg% �‡@ÄaõÀÕ& K5(`Yïuì`‘:ªSU�µþà\ê:äkâEÃNpJ” $â€Q³Œ¾OÄN%º@5I»XãvYÃb€7¤½GŸqº·yÐýñ7T‹í8+FÙ€›g«¨Ñ-9 ‚ô¶ÿýñïÇà[¿ àò=Wc Ô@¨/øy¿qš0 ˜œ w?}ò£ž›M¡\•þìà?;@SÜJõNŒåÇþ‹ö'�9ç 0â æv ÌP&ðj;%8¨.P52€�æVªB£¸ÒF:èíî‰A¡±HLùï r†€ÀH¦Òw× �È-ùýwÏi'ÐZ”à™ô¤lnœÛ<Àˆ ˜;4Ëq%¿¾wÖÿ…PÔ;…kÉF¸Ç>œôʼµ›+Ðd;)â r¦¾ç¹êÆ+2€�‡ƒøo ç£�€%· sŸ]õNÑ”ú¡|îÆÔÿõ1�X�¼@óèеÚe[Íà8WÛÿÚf´hŠnÿ’Ìú?-€ÞU€ÈÉ£Œ˜À˜ŒÔ@3Œé]_‡œÿ4äü $«Çd€gèòqÐñýhйS’+ÿ.ªlí"wÐ ]_=ølÄA^h^�å)¾þ üÜ/ ü?°%�T¢R5t¡Úçäó‹ö³�n3űÐ+7Š®OÖ›ué+[€3_5 ]kŒ„ôʾNH›³«ÀÎÀ¢ƒ†/¬ô·KnDE›3B±ùçJ´é# |e¦ÝDÛÍ®´‹&èö·úŒŒ™Kg—ËYûÍÖÉŠ'OžàÉ“7p:™KEœ"nŽŠižÀ�1ÅÉIzd€õ²‚yu?ªÝüšâš ÕÆ?§„uMÕ¶^$Õœzæ€y²�LÍB4§€hÀv»9U ÆJ˜¢ÛÙÏLhOqr{}THO„`&07'¡é`Ñ©F3°Ç#m@µú¬Ë‚»»§1Dd¬çiY‘ræŠ̺Æ\ËyÅétÂÓ§w8ŸŸÖXƒu]ÀÁâ rΈÞï"­¿¦yòÕy¡Xû“ŸŸS8wNv�Æ­�â„i> N³;5Àˆî1jÔ¨Q£F�5ªÕ Œ5jÔ¨Q£F�õ6(U@?]õ=VÿZì‘•v*÷++ µÏ€Q”ãÚ�ø—zqݨ ¯X-wÖÿº± XáVþ5sYªºÓ¬Ò šç,† –üq½¦.[Þ*ü @®€‰)ýëgáÖÌ×6Ô÷‘Gq€¸Ú�='ÜÁû{7Á…NÁfy«7\Æ€^€RÚÉ8˜Ò�ýi«JýKëtêþ§ÐÝ ¸*£¿øË¥­?mÇÂ}Ct)°! ôÛ¼ʾ²q}“xïyï»ñ9Ÿÿµ(Yè6¦nÀÓC,ÿSÞ²ç¯wf÷Îm,c«öoêÆú©oG~õ§6ø3G�Àß :¾«÷žÑ 'åÕÅØNÈ€@›ò×Áòø ¢»¬{0Èÿ¹¯]K¥�T�œìšar�ž@‰ Ñ¬›ác—ˆ¡ ÀÌ�B˜ ¼ds �däjýÕ“˜µªJ�¹ã@®ô›+ˆ­?½ ›l ¨2H´‹[À…µ w¯5Cwrhž –Ÿíäpt}l.Íu¼uÑ`s„@˜:ûÿ[p8ø\ç¶ø%ú 8�Iˆ·®þ„æPÓèbÖüzèS@Ö!P~ÿ:tpõì/|@€M®ú×ÞößÁó~S¡#�`˜:¿ûqþØŸßÝAãt|Á"N?iŽ7ï5?W­úq·Œṟä&ÉȪÐüÔH Óó�? ùã?yúº÷!à÷ý¦ˆ_þo®H¥¹�Êšº ½8Ó4k—Ëõu ¤ÎÖÞ]fö;Ï40¡+k¬Vâusª­`»ùQKˆtüºWÙß¶3Ývâ,ïÓýD¯n™_\6.Tç%¦æ Ú¼ÿ{¥·vcL;Òõٷ\~Ú·�®ßëôkW=�÷²OŸ>Áo¼�eYÀÌ8è‡y® ûñxƲ¬)!ÄàÀ´@rSç¯Ë‚BÞ“gÜi !¥9¯>�¦©´�b@œ&ý™RBˆ1¸ ¬&WÂ3³ÛÙO˜§ˆyž0ÅfFÎâ)Z¿ŒH`Vüì±æ.à6ü9#'©–ùÁÝz¢  NF°ûŒó² Þ��SFˆ*ê.+$g s ¡ÀȬ‡dä '#œÏ§ ò§u±ë_)%0‡z�•~¨¤ˆSé#[¥Ö$€ß‰d¬ÁV=sI°þŠ!Øú¢F€Ìî‚�Ó:þ±0jÔ¨Q£F�ÕÕ Œ5jÔ¨Q£F�õv({& b&æêuEäzµ´ƒ!$€Í&.@a«]ñ3÷×Áþ½>Ñ•LdÝÉën÷ľ- Ûw©û×¢��2?®Æ&S¹WóVÐ_Ñ%H×&?ƒ|á’ƒ·D®ß'WQKT:å.sº÷NÐb“žsýKÔmŒŠ:xgsÎtÓÅâ·µéïT¨(`ro6½==ýÿ/lž/Îýý¿¾™ÒÿÓ ¨&úVö¡øÝÿ‹_Ĥ` àðéé�˜2:ûöf¯O6ãºeœ{7å?˜�>üí›u3`ß`žÜ¡À÷Ž B^¨àrÄò´«å¿žvÊÿ\‰ LÖ6¡`>¢:%Þ‰é�_�üò_ø’Î�»�O>>¼ ¦h~dÇÜNö¤®JÀ(.4ê±ù Èg`}tûN?dn °|ö»VüÊ/þÄw¬ù’lT|Ò>ܤ‘žNÐ>ƤÅ`×ÚòË>œæþ)®ìG®NG‰ÂkR�–<÷n—( ªÍßÎÝÔ©÷+G†šå¿ôŒ(˜¸ä€åÆ.ì }i×·W¦YÝ.øÍ„NäQºé·f£›ût—7îY×E‹çËçNBÀ<͘�ÇzR€xŒ³©ü3w {@1ÙHkF΂5%¤´zÖýê ;#FöŸ™!LÓ&ÂÂü/À·0w1–iø§M_KýÚŒµÊEÔjÿŸ=–@Dýï¥=±’J`Vú"ë²à)Ö¸Ö~QTÜÕ 2bˆÁÚ 9"pª§ˆˆÀ�‘ÖäãC�“@eqFð~˜¦€g#&F %†!¶{(¦È<á��¦u†ªbš¦iFŠAvÒA…ä„œÓø·Â¨Q£F�5j6�"F�5jÔ¨Q£F�õÓ½´KÄ.‰Ÿ…¿?Ñ衃 ø…Ip�ÿ««+û\ãýþh›PÚËt5ky¯ø+jÃ�«yÍ\‡[YSÌkz°¼¤Ôe-wG�IЧ}.Ú¡öÿ%/£�šúŸº(mÙËpk¶ÌÌ–û¬ùrp—j®ÿöp¿�岟iP„Ó0û{­ñ»£]Fõ~s~J.q¼Ï …è›üþ¬q¬ÿ¨®!¾è ?_ùå_äd@m8¸C>ñ­�껨Ä4»zA¸å?÷2Âùþ@“܇îû4#>ÿ3 (�Öר …†àÖÚêa jqEA­®ºOkݼÖ1E@$(›RÝ,øc²)XÅAÁ„Ì��LÐÕó¯‰Ìõ¾$��ø`1E¿*°;w•XTÜJ¿�ȈÄ <³ƒ«Ç¹^~UPžk[@�ö¾·ï•ÚÜú² f'öi2ðjDõØe' Ä üƒg0D q¢8B�ÚaSßMùO¿ÐW»kîÔïF Sìó-nü¿që~'–hôM'íÓ¹åàæ`ï/êÿP”ÿSÇX2‡ •Å g ß@Îq"ìX˜"„=B L`š¼O&;Bà›B5C^ÿ[ÀúIèªÖuó#èë?zþgY?Ã#|«“¹[E=™©µÁÛHz(C•ßõÈr‚œî�ïN@~Ï?-øóßÃxzœ»®€üÌ›±‹ A�èÇV[RÌk´ ^ÙØÚÓ…M½îV6î6½«Ž¶õÎÚß]Ï´�ï/'Nª`}YcŒgD“6ïkGñÒJXSR°¨ÅÔuñzœ @ã€F"ëÖ�·:‡oœfT/ÖK½öé=1àžÅ¥¨ÊC0›ùy>`>Ì8�8€Õâ’)ø¿®kȉ1F±¡`·ï¦´7u¾�B¤G`F(¶û£¹ÄbÄTmú»Ï8) 'úû9ÙEb‘­ã’"æ ~­ð?Næ(PÈâQÒms]mNÉY ˜w—�"æ)"NÌ�²ÅE NG9Teÿº®X“Å#H9ÎìdTÍêÿp˜6 u”èˆ1DŽ„@Hi†ª€™c±½7­«¹×øgDÞ|,Ž5jÔ¨Q£FýãVƒ0jÔ¨Q£F�5jÔÛ¢ÔŸáþ ùÍïßdï)ôf6ðpkå p—»/ûÉ•ñHÝŠÿ;#á>Gžš²±Ú»:bÙä„Ü6QÙá,E�érp¥d*7н*67êÏuÐ[ðo�êbËwä†�Ÿºí\­þó½Ú¿  `®í•¦tÕ�lt×í¤=È¿Ïû¸½°j@%$trÔ+VÕ×vy?Ôÿé“ô¾.Æ¿û{þ)ß Y¢CàÃc¤×¾Ç­ë ü§�Ò¿Toù_Àÿ²?û}ýÄ·CNw-9 €~ôAW‹SD×ÞÀÖ¬ØËŒ�lÌûø#5µ#j€·‡¹:Yàôâ ~’Ûµg1+ÿ”¶¸gDk@:ÙÑ–mä ˆ@’€9 œm,R±ðg�p@¶ˆ4k €ö~õX´800{æ|‡:³Û¢@·Nuü±ú“)î1!°Vò„‘aÔ f @tp2Èìcbé&6?÷ÁÔÿ`¾q2·9Lª ž`ý²í†nÀ| bÿ‰Øç—ÈwÐ|ä)�î]­¿9˜JŸî `ûmíõþ@r‚êÈþË�;,�¼¢Ä©0ÁÀ>8ø°À¡Îsà ª+ÂÍçBÞø^@V#L³Å Ä=}tó™ü—ã‡[·øE!jçŽÄ¯Ãìd„žò h‚æ|ûY ùG¡o¼jc“'<ž¿ú+ø[¦Ëx—.  €è°îMXÐ;½t“Y]»ºµN;@¿ŸwSß¾uÚ¥]Ü ]YgÊûÙÖ%u ~{É]<œ,¤©Q†ªëA&mî�k íÚ@ h°íi;SísÅ ‡zÀÕI¨¶Ù×Rý4fç è ØZ¼¿; Fê»—àçuЇÃ9'LÓŒ›ãÇã¡‚ÿqŠUý®ªÈÙ€ê䀵Ùîçl¿~4íomÜ®1�ˆ@ˆ–kBÀ£»ú F”}ådÄ‚5%¤œADÈõï[’cùL9‘‘\ ʽVœ"æiÂ4EÄ8™«A‰ HÉ÷o†u5ç�B `qÂažq8ÌÑæ;ÉêÀ»µÕ\ ‡y3cZ¬ëŠeY±¬ rʵ¿¤˜"s%ØÜÃH®¤;3¬ý1 Ò‚8ñAÔˆ"N*%æî>qÔ¨Q£F�5jT©A5jÔ¨Q£F�5êmPEYFdéÞ—uÀ¯Oý·6àtåY{}aÿš¸@v÷@œºÿ:¤Ü@ÒÚÍüj÷¿Qñw–¿õ}5HÀ6ïÖÛÄ2›rº6›;_eWÏu*ø¦ZgíTø$ÚÛksmäQ¥÷­6*>t*¾]Vò^ù¸�¢Z–sÃÕ[&³�=M1Hn'®RòÉû$èûAŒ«U íØû?¶¾ê•ˆMM»i/zwmÝm£·‹þtÖÓ39 Û}^•ËâK~ö‡ð _ýE[rÈùeȧþšƒóÅúß¾]ÙlU:%sŸéÃe(–b&Ðí;æÇÕ)¢›Ê €¡±)ñ™X ’2ÈUžª@`*|ƒ|©¥X3ªià@aQH@Ö³Ùìsî.Ñ:öÌŠŸbl©âYÀ”!%ë>[ €WÈÔ¼{s®œ—Nõ_œ JÒæˆ�âµ»Nj|@6a}¹ÞEªÛ<ƒ!ÄNî‰��tQ†0ÛkvQÇ‘Ûê‡âÍR?g(ù¸(`;Ž®ÄŸl»b ¿¸¿]úì¤� à[P¸uõþìǹ8p¿ù)�ÏÉ'Q߸íþ£F;øï¶ÿù) w�´ÀÜ ÄUç“©üÉ ¸lfAe¢¶Ù Âôøk±æo7âGZ‘—;�(B^�AÓó¨NRNL±þ�ögjìXY� °ÚñëSÄw¾ùéËд)ƒð»5ðgþšâµ§¾.8eFû‰MÔ‹«ìÑ�ͳ¨^N¦²yl› e�Ú»Ëì×Ó¢&ÇÕi¨¾.5òF›3�°Í…Tb*-ÈÈkº™oicÛÏÄæ<ÑÊö³úÆâŸ*bÑ#Ú“ñtóqí�ÿ�¥¿VPÿš{ÿÚ~­(„<¸cMéºüÄ=s?áp8€ˆ�rÆZ'ƈ)F·¨F|`w ×{\%‡uí!ªn!ߦYè7òCqÈ9p~>cž¦Ú�Ú�úõü©zÌ�÷Su0·fQ¨Êÿ&Dß& m·¹(ˆÔÕó"³û?ÌÍ9!D2’@^‘Ö§³}/qÌó0ÍÄÛy\œè`ýAõþÕî�Ȉ bN ð+8b0sQDTEÎ+RÎÈÉší¼e¶þ�!º“˨Q£F�5jÔ¨Rƒ0jÔ¨Q£F�5jÔÛ ‚?¥· ‡6õlSo€ˆ{ãÙ Ð[›¥0U@³>öv°¿=œÞ©Õ¸àîÁ¯§�Wì· ×ÚW ì¢µ$íÛHæôÍÍ›¹<Ä'WçVÀºÚ+;xQÜǹƒÙ+1 ³Þ­Q$:+Þ�À¶TRÈ"MÙV@’g$H÷íîˆLMñ©*fßå¤o h„®ÅN˜ ]n³vmht…= ½~uäÕ­nGéξ½ž–Þ�âÞº÷òÊØ:ü{¿÷Ÿ¢+�E�ÀáÒ+ߎú³hG0Û{C”Ä쎧ü­ì‡Ë�üì¥Øï–>"Þ¾uº•¿º|ú°g·á‡[à—ñîvëeLQQ��PÏ�‚«çP üTS2à*~q’ƒ“@P^[´EìH!Úø1p[İi·ÈæœÍY €½€ �Nѯ޷"ÛëVÔ,­}W\#* ùyÐôhz ЭöÌ@:›Ý½*‚.vÝ[$Bg@ï WEÉh°ëwA˜Ð,xcQ´í…¹F˜S@‰�Hí@Û^•®»£®(ÿÉãÿ]ñ/O�t‚¨�ë€@ÅÆ±»$Ð3˜f#=P4ÂUƒ%A‘¬�Á·Ÿ yõ!ËÈ+4/ÈÌO?z|ëýUúÁ΄ñ³’“»h2—]aQ 68ˆ#âà ?þ(Ö�ÿ„í:àA8ã×5á?ûæ¢üݪÝ;麯‡  g"õ$€‹¼zt<%½g>¼ŒÒA1Ó;\®’Ø�]ìú¨ò†¤T­Ò]FÝÇ\¬��ãŽ9<��ë½zŸè"§�¤s8¨q9ºòwó<ÑfޝÛÑ}omšZ÷Ýö{­Ÿ×–íˆÇ›„«Àaž1O³©í]ñ¿¦˲ ¥µ*èKd@Œ±æÃSŒ°xt÷¾³;³Ôׯ´uw?ÆNСëZÛ_òeY1M+–uµ}›—8¿¢.z'ûrÔÖêl~±ñfÇT¾ ù²?Ž‹»?²y-†ˆ8͘æC� �|Æ¢¦¼_—;œN ªŠ¦(ÀŒ12TmŽÉÈcÚ}NÎævЈÅÍÉŽ7 '‘jw…�|µfˆS¬„Q£F�5jÔ¨QVƒ0jÔ¨Q£F�5jÔÛáÆ=DËg L*6¼ªè¿¢N£fGß|àÒGÙþ§�a9å¶‘ú0¼J˜·»+ô ±� P€ÏÁ™’ l,Ë©·G®à?o”ñ˜rçB€L߸ T¤¤?\õÌîb5Ûµ©€F€þX©ËY´díúƒê�{õÕ}Ÿk¦D*Ù•ýbºÍ-qàÇÙp¿¢ü¯mÅî¸ Ö‰°;¥g�9èÇ:¥z§ÌÜÂ5oÀߪº{!þµw]»oZ×¹ |Å—>¾öË?¿ý�7�õÈ“4Àš£‘(€8î6Bò•kË&Ÿønä×^Ú‚ÿJÐÌàçÞMÙ ~Î\IÎÜc{†}çza¾Üv�0É”Ñ=·o$€F�©Î®â§¨Nvý¼³ª ´{€]GJÙ,ÉÙA|bÇô#8›Š´Þ)CC$€ÔID¦ÎH0•fq±>WgD¤â,!`~ }ø"b|èøN„ùÝ@¸© mÅ›Ê^4ójùñ¹äÏ÷¦J…f�®P9ƒÒS@O¦,Gr[úà`z4¥º*¤;?oá®ä6þa6¾¨ÿUÌ�AW?F`ž>ú×�}§Ù\T Ï'h>zòbJnøçij¤ƒ0›OÖ^…³,P=ù‰Yþ'#<ˆ¸®…ML]km8‚áÅ'À(PóÆsp†ÈÉÈ zÂ#0!ëËOñà o‚ž_?Ãÿb9“áçÝ@Áœ²m_rþÕœêÇö·øÂç"½öqèù$#üŽoLøãßñÊ„æ ÒÏ1t99¨:Y`«ð׋µÍ@ûÉýž9çÊL'"›ˆ�g�“u r%¼ª@;¯Ÿê2Ó©äû,ž‹4–âÜ¡–×®]î<:๮£›I¶#ƒI£Uls¶óuqW]Ê×rb.»ÑÏK%Dèv5è]¶30áæxƒRΈ! Æ©WZWäœp:�°œÏX“�×ÌŒy> ÄPï7778ÞÜ€™]�.Nb좌ªÊ�Ô¶ýˆêÆÊ¾½‡+ˆO² �‡”˜¬ë„uYœ|°ý,3o]…œÉH¤ÞFt׋Íþ˜p_ÄO½Ä˜#D®êÿÃá€Ãá€iž!’AË‚ìî çeÁù|†ª"æèî%±.¾ä÷+F °3d?o�GFNk�^(%üøl.P퉙Òñ:ýþ’aš0MÄÆ?F�5jÔ¨Q£ú爣 F�5jÔ¨Q£F�úé_\³êwwOoÚ_:0¼«üÑþ54ÕZµÖ6ªïMÆ{Q_E¥qgM|Ÿ“;íwÞÙð£ÍŠ.FಠÐ&· î”ôþ3±§f?ï"`€Ä£‚ý�x!B¸ÅòÆ Yú\ߦY,بù7�mŸðíÀ©@Š‚Kf9ÕçJj¨ŸËNp°Š@å ò®ËÿíphÛªÙÖ›PÆ‹«® –¬‚Mƒ¾¨O÷bÿúfŸëm¯w@Ö?ÒròÈ¿ó{~�¿àVñ<�ÃC¬¯}[³Š'WƒWkÿ’§^YÕj¿æÎ3%,?ñ—·/F´7ψ�t«ç¤ÍŸ$�«­¼7E´NÙÝ|œ2„È@nS¤ê (À€ŠÞËQA!6 FX¦®Ó‹…¾Ú¶©´ƒ¡œ:§ †FA2µ1–íÚÊàlœ=€ê¶ˆÊäöûÝ•—€Þe@“·Éöks7w¤�#(Ü= ø<¸ùÎÀ{)E ïàq7 ¾±íÕ¬ 1ð_îÌî_žéÈ'ˆ.Pu¶œrkÇ ð̳»(‰:¹Bý³ ’î} ¤'ÐôXŸ€oÞ œOõ:áõ ³ïOOž@ጌQ/ š¥][ê}¥~A‘Ï s<È ¾ýlÄÇ?†å¥…¦|8à†ÏøŸ}õ ÿ÷?wëŽ7´�ï´ÌoÍf¦ºâèÞ_71-UúOµw»5­Èîñ¿ikœÇÖ÷ ¥í\€ÜíÜׯ¸vkxµúw7AO0ÀÖó‡vK±Ç‡´h› æS÷Ý®Õí@%ÔQwé’;s4'�Þ=§­R*ÛøUTExÃPâú÷aﺠÛûbÂá0ƒ˜R6y PU¤5U"ÃétÂét®¯…0ó„yžq¼¹ÁƒÛ¸¹¹Á4Û¼¸œW¤)ãÌg0±,6£ÝGõ¶öZ×ÿzßæ>”±9ÔïJ á|>cš&Ló\�bˆ�Iªj¾¸ˆ1Á€vr‚@‹¦¨®b÷Mõ¾Âɉ­Ë­]qŠ˜§ˆiž0ÏÖ'Ó|À4MXת„´®X–3–ó‚eY*á�Ð •4aQåV±‘Bäúzi‡HnÇUþ–3RG\PU‹ È�QÚ<¶aŽæÃó4q�5jÔ¨Q£Fõ5îŽF�5jÔ¨Q£F�z”=XÍ�œºœÞd§^H\€l²�á8QË,6zìÞ)¸Ë–-ÛiV²¾µ H\�¢{uhF÷óÍ‚¹×^€;P ¹4”¡WÕUì¢îKÚ®zÅ#Që+ÝKÝ·Š¹ë t±IÖæL Ô0­bU[Õn*Rs›èbbèB�.Û—+Ù¡9Ww;Ùµ;ÀÅ¥™Ãד^,Õûó®Í=`¿Ý‹®¢kÈ¿v]êË.>Z}¶÷RÜO¿zÀÈ�©Ÿû³?ˆ¯ø9ï·×²{ßDz| úäï¡Y·;¡¤�(lH =ø�‹±~ôOÛKM±2’ÁáE ¯&ÎçPÁAb5€E)ÏÛH0œÔ¦dS2@Ê {J ¦¾p1…PAx €d2Ì5 XÄ£9’÷›@„À)9ùÀÛ2q 1ÛçK6µdhÎ@ÈöYvåµÚø.ÃWÓ#Ðs_ˆðüÏßï m6YR‹è¡VAÉhöô*Øyõ—™ÓUùNÈf×|úšu.Ń*�§ |xãRar€ÙôB)-Ù  ¨6)4Áìú‰oº1p°~×N¹Ÿï9CTŒ0Ô¹ €ošò¿<ÎÑøŸœ�Ÿ"ËŠÞ¹‚(z;šòŸ ™ � ÄûÊø’ï€üšŸëSkc>Ae!çW€õu? Ât ¬¯ÓsvÍAÚ)t× ¿ Û¹+1Û\V@N/|ôòG¡ù²œÀAð[¿~Áù­G<¹ã�ú7{¹5z%MŒx䀶ê–�²]Îz‚š{Nu·ØLrmmëQø2ʼnZÄÇ3ç°Î½¥(ŸIÉ"uB Ú¬/Z׊ºî³­m­/¤8­ëéf)¨Í×ýºÐ¯Á>O©êñ®-´Y+�Ž|­*î«+ë3×�]{DŽqšš£P͸Ï8ŸÏàÄÈ)㼜q:Ÿ�³ÍsSŒ˜¦ 7··xðànoo�'_Ÿ",¡#*Pç€z/ÑléY¶ë}QñW5?µ{0-QARJÈ9!'�DEŒ!“F›“P¬ïµŽÛ²ÝrY‰H]»Êý�8ÙJ$×ûŠòe&4ž?bŠqš0ňc=?YkÊX‹QXÓ 0™Lw¿¥º%„6}QȬYº{ÐâÀD‚œW7¯hÑÖnïs�@ !"†€iš1ͳE8 À¨Q£F�5jÔ¦ÆÝѨQ£F�5jÔ¨QoƒJ9™}3±+¯W³£¿b•ëNÞ-»ÞÿP˜·¹&»®´ß[ùÓÿv…B” t·¡úØ¿�ÀûÏiOè툛º¾Ø� �Tå«–Â¥ Ø�!¨Ïïu¤¨$îÝÞ•ãUmÀÆÆÂ¸ü½SfVw†œõ »@º>FëtŠQ½$MìÁSˆïÎuo{°?½bÏßáó•\Ò\Õ‹@;’ée4Dù|wþ¯=÷X ¼IÀUãiUüï~Ç7º~±žÀáëkߺݨö¤…½uòü/VÝéUä�ý@bv‘e >|·m¶žªv`X#uW„ŽÐGY„à$ªÄ v�:Œàà %¸…ÿÚ®¤âXÊ  Á� Ð `QH„�ønÍoj~‹1H¨ˆ#À Ù®õêàªûdª{v@Y<ë™@�ïøùÀí¸ÃH¯ÚÎþçíEìD PË8vG¥:ǼµQR®S�¢Äd›[”å²|ÊÀøpÍϹ…¿�òÜñ…h�3¸DTr ýèjûÐ× È©ÿÐÅ�ãüG3öÊèÙ¬ùü—t‚ê‚ þ  $ðºéÀÿ€íid ‘Ŷ-'�JxbÊþõ)TÏ@2Ë~"‚®O@)‡8>²95��óÇAÓ;ºöj§z—neÎe'#ø\§u+p:¼áá; oü}0 $p3güÊ_pÂùÖ›«S„¢©ÔÛ Ù\dŠ«K%l²\ÊÇ:DÜ q´#ÖíÇ—¢ûÑ~ÁèˆX]¬JuÚ±ý‹*ØBè›ÓƵØ�n�éõºÞPêѯ ' DmúÒí=Áž(vߌ«ÝgJ\ mb„1B»>n$ݬñûý©Þ¿Ä‹jTÙ»åÊ+ˆ2tQä”±® ÖeEÎvmÅp8q{{[¿ŽÇİ,+bˆû•u{+Ð�ת‚œrÊÈIÀ¡‘ ¸žsFY¶k¸ª‚Ü å ñy�˜¸]7ÄŒœÜÉæ$À�A@$ÈÉ“Qr9ÇïR"#öàÿ¾88',puHkFZÖ%#¥ÕÕø¹¾·�ú¶Ö¥dï+€K@ÚOÑ]¨*ú×5Y$@Nµí!pm4 †É/Fà€gLÓŒyšq˜"æÃaücaÔ¨Q£F�5ª«A5jÔ¨Q£F�5êmP)¥ò€�”.¡Ð‹´cj(ÁF±¿ÿk*¯và|·Å^YO{_aíM“{ Õ”mÂl @Ö ¸·le˜:QÍYŠš°î÷>Ä—$„“ #ÐÎ’¾*—Œ6õݶ¿´ó2&¨eŸs—#[ìñYèMý±kÃI/ωãXåøÙíÐÙÁ§j\¢Tª*ÐN¶ÙH—~RêU¥Å"·÷=øU¿ä º-0o!ËkÐ7>Ò”öLÛ,ì=¶ÏRöf®?ø‡wà¿ýnŸÍ TÎpà-»E´õ«@s¢ð¬æ ð%€$TðníÜ–AreØu¡ ä - ÕÉ"ØIÕ \¡àÕé%…�Œ'C–”bo[t@¾Œ#1;w.3TVPŠoÃá…¯Fxñ€èÖòí7~]Kæ+ç„»×Ù/°Æ ˜A¡ôxþùÕ�´Á5]¥žÄ…ðk…"ƒ$AÓèÝÇAóÐÍû€ðuB©$�ÔÀÿ:Ù4û~ sSÜS±þ?™¥¾œ,Ò@íØ,Þd±�ÿ4»õ?`Ä�dêÿüÄÀ} É's0Û €(LæX@Gp¼1|æf4`~…èÈø¿ƒf'¬O¹ƒ¦Å" $#K6`ïö��|³O×t2LJu=ÿœÇ9ôÀc#`T÷ ”<.¡œ[²ëÂgÄ?yõ§ ëÉ Àoûš;ü±o;"åŽÒÏÚ¬ÄQWÂΞßÇs‹½)sóf]+ŠyéÈL›I³'O]‹‰¹~e»%" ,¢ŠPìäÉM´±×/›ÔNm¨Wö_Õ³"?ܬsá¿_@𺷴6Ô[k·+·ö²ÛõRËjԑzÅâå1—ý7{’Îz{‡Ý�!ú€d.jϲ]âAP‹Î:·Ï„®Gª¨x¢õ„pШßo�_¶Ê×¦ÖÇî´S×°MŸÞÄ(T嬦)=¯]üí~aé3Ô¦JÏm›m¿õ7}%DïÀÉÛf(ß"¿ö]h`r!ŶGüû‘-»« �ײ>m;Þ¾Ÿ/�B RöþrE³”,ê�Y Ð� î*€<š v8t)ßädË¥¶H' ‰åÖ LÙ¯Sw¦Ã ¸=81¢ÓçZì;`࿪)=�p`ÙñÉ>ÃFd¡üÏ`É�ä×BÊ–;Î+hzñ�¿ôÜ—`�&·½7"BË1å¹)¾µ}sÞÍ î´PI�€ÌÍÁÎî·»(×O‰è¾w¹ç]¼�õåuèú·�øÀ£Ÿ >¼Ç]²�÷\ãnýÏ®þ/êûàà¢f ŸÍº_ÌRº–ƒó˜�#@7 òYvÖ†zœ�ÞAó �'�ü†‘ tu÷µqDÑÀ>šêŸ�H@õqPqA8C²�þ�§¶ÝtjmKg'¬fINjn` LŸ±i1We`:B××@Çw@ó6¾�›¢†wðß,c iW6€™<#üáûÁÏÿÝÿ{ÿÖkÛ²�‡a_kU}Œ¹öýÜÈs¡ER¤hÒ¢(Y–eA—(’ ‰)±# y°Ø/¹8ò”ÿ�§Aä!!p�<$°�-Y¹(±$+Š+âU$¥ÃÃsöÞkÍÑ{Ukyh­ªZõ1æZûØA  VæšcÎ9Fï½.½j¬ñÝ ¿þ‹–à� _{¥ø—öí?}êcj{Ó[dãa½ î0c@µœÜMV|‚¹ÙÄ=ñ.B§ÅçD{ó°nžcQúêèè|[ÞEä¹ê}/V�×`̱:q¡E(uÂ…ÜŸæØAm¿”ÙÿÄHH¾žÄ¼ �û¯>x2[àß…üè ÜŸ"^ØAÞ²î«J-¨µ¢–ÚAäN�TqÛï ?Ò¾«[÷7кWô›�½“ô‚Û `ö÷êv÷ÅÁsQË8vÊ ¹$T�)H)õ¯Ê"N{¦+æSHbTáÖ7—b‚ŠöX»¶Ú9Dê„�Q ý¹æ,P«)ð˱ãØs_ŸŸox~¾á(F`Èî:p¹\ðêÕ+<½zfF9vìýXP¼/‰¸“;sJ¸lRÎý÷µ ª“ jmÎ 2Eä”�Rs%#6'P··ÒõŸ…U«V­ZµjÕªP‹°jÕªU«V­ZµjÕ— ¦³üÓÇnç /¢’ÖðYû9##»¸cÜGW:ÚÇßäÍçJtÏÙñB‹0èN°¯À}¬@€=»µ<‚OÝ$šÌ&œHýÃ}t»Ä6kk‚õxtç�Âþ~,N w)Çg\ƒÄÒÛÌ¥0”ÿNˆ¨?û/`¨$[S»óÂlÕ ~±awG SA1Ÿ±Sü8ú`0+þò´Iß-0‚Cƒ¾{qöFñè ÷IsLøêW>¿ó—þUT½þ�+Hß@ßüÞ9N)(ÿ[;D;® Žù߃<³ÿÃÿÃtff2#ø£ íɬñ«†¥ÒÜ 4"5g ¨€kr†f‹Ðìà\Jà °û'ùtæQÍYbRï+€R!I» �T¡›÷—J¹ßwç@S—M"2œ�HÊÕ¬ÙÍE‰®àùÓÈ_ùÓþ\Ï•WwÁè$öÆÀ·Îî¡D-^@à$„ä“"¨np¾+=cþœíNÖ ÷�ƒ·¦È–»; Ù”SùmÔïýÇÐËÇHü^`û*€â�—�¸‘\�|ñ¬ÿ‹éͺ_Ÿ�áÖÿ´0âåFpk|•þ¿�”7€¸:¿îvìCÍöÿâ–ÿ¯øïÄ hä"Ï@m*ÿ7@}m±å• ´4k~Gk1€´ÙüæW€0TPùÔˆôäWÖþ¡¿ €¦Þ7$ŒÓ´>AÞ üÏ¡ü“_4ˆbÑÿý?ñíï\OÓ5åÃã´*jØûl Ñ •Ÿ÷ןÈi÷QÜS^ð³™HjÚHj™çêju�1Íá@ur]i{•ª¶÷ ãü±í=R@ú.¢îÀö'» s�hûQ\«Ç¾ßÞœîŒýh‹¸—èDøaK”£'¯kÞ<ÚG- g#ä é„ DLNFŠIȚͨì\G©œ#�Ä÷$øØÞÏúP« ”‚ý8ü: œOE:àØH•@JH¸\Ÿp¹\qÙ6‘í‰=š #y7¤œ&ǃAÀxEÜ£Ì�zŸä”�sg#%ŠQMèd™ã(ˆ«V­ZµjÕªU¿³kV­ZµjÕªU«V­ú”}8špÙ.àÄ]W×>8×^„éô�×û‡îd@ù$¨JùnÑß•‰£4„¼»©¬Ü/¥/wÐWÍÅ9¦&G¤Öž„Ç™ÉsQ…ZέCÖ"�z%îÏ5¼†;Šß�æžô£�üâø ÜàD»vŠ9í!'ZâÕzÖAëO³Y6 @´Ù7ðÿP¶“½ ?Û*ûK:¸:e9ÏÆ�ùùáî :TöfÓ�¡}vúI§ ~¡oùøDUcqw,»ÎÿÖ_øÃÈœÊH8\�ÿ>êgÿÀI@ TH�``#9øßH. œ%È?ý¿„Ë" øO× èƒo¦]4p1à\¤‚Ju€Ï@2Û|·Ég(8GìÏádjýn)oyîÚã=Øîk¸€Tïˆ@¨‚K oP£s_\, Âåž !— ¥bmFV{sôH Sbn_ÿ‘¿õoüº½ïæôæúè ~S#÷‹0r€Ê©�×w &;ž½4Ôã úDk§òN7É4ŸìúÅçBµÇU ¤�çßDyóHׯ�?ú}`þ=ã$]LÉO›ü’ìZ¤ü¿9ÙAÜ Ÿ]µÿäÿÕ£dôµ¼6�^^Åû?@”ÝyÀ¾˜ÝöŸ6§m©_Ãaà?γ+ÿ�pÜ òl„)c�KÁi%‡È \-vaÿÔF@v >ò)ïùå³ø'ò¾™Ii#¾!¬oü.ä¯}·ßøÕ—ò³_~æ[7ü¿íÚãMè3·:‘å¢YнœtíŽ6~½t¿Ç^_Þ)ø³Ðã'�j÷ê 3 21MK¿hh3"‰Î�|¢û½­íÍS_ZT�5¶2Dò•N›éœ¤1LgôþýC=M{I÷xèôŽÍAÍv¾)ú™SϘ—æ–pÌÇ1Л÷ÏüRǾ#»…|)žŸoØoæ UÂÞâ ^r,𘕬 I)W¤š�² •äŠöúwWNƒ¼Ø¿¸¿�@²Õ^ ]i_E;YD¤výDä À)ÀÞ{4çf2׃”‘ò¢.vŽÛíæÎ @J©ƒó[Îø‡¥œ6w:'lÛ†írAJ ªŠçç›+ÿÜœdÑÞãn›µ5%FÊy(ÿSòyimj1:ªÕÛ¸Û¼º‹£XµjÕªU«V­ú�]‹°jÕªU«V­ZµjÕ—á�{JHyCâa¥®lhÿH�üù–eSÐV›ü†ƒ:°CSþï` LÑ·_7Û“ ëÈ nèʈPD)à\gêÁýß©g7Å.ž�<B]yæÊñú‡øô¡uµï=\N¡ÏîH4"Š}ÉskÔ,…U]±ç'"¿�Ñ÷mìBþûÈ0€ÎÔýÚíœÚó¥Û³ugÿ•Nü :�áKcÔ-=µqJK¾Ñw�ñÛë-ÎrNøŸþ÷þŒaÊ¢¦TÎO ~òý¿eJúž¥ÎÝ~œ0ÝÇ+æ`+åýWÿêÿ™,–��ôñ�ƒòÅΛ¨ p…&—!¤‚Üb¿«É�¨Å¨» C“Ý·DÉUïÔI‚nv)™j… ¨*+€ZM0_tŒeV6–c¼€¿�‰ b~n%2òqÏ'èýŸÄöcÿmðÓ7­ûÜrlô{»ývé£NZÆë¨9$DCWÃ÷qâ1Vbz¼À¹ �¨BÔŽÛsêkÈ;·ÈéJö  ¢~þk¨Ÿÿò‡¿é£ßï}›luÐæ”ƒÿZo€Ü€z³8€ædÀ›©öù jJv9�ÿÜú¯�úT÷`s8|ÒLOö˜žJUpºõÑ7@ùÜ¢ʳ©þ�g‹¨7ÿQí>R8øÏ Üˆ m^*¨V@ ˆ�µ¾¿Q€7PþÝB¤£Å~œ>$ h•yMí‚ß ðÁ·�ßøUÀ/¯À_ø½7üÏ~í‚æ‘3öÁ; ôM|ƒi�;¦&‚ÓÉ}åá˜nc¿˜�ûÉ©€ÂZ­§ën™íã�“ú¹_h³ü�q3ý}Á„(�À¹óÞ È l$Å ²�|y?pêá™ø‡ÓƒØ'£�÷kù º’l>°Šå¦g?NV�&SÚ7ä)%St;0¤Í>M<H °,J¶¸8’’@yv `ñ° w¬àRœˆ­ûà ø[ÿ:òÇÄάŠ›%Ña}Ûú›ýg©ÞçuFûŒ}à$‹´@j2eWÃSp Ñó¸³!ûIÚ‰A1`�T«+JèW·¿¯u|'okp,(?øû(o~ Û×ÿ(øú¿Öä/ŠöMýo¿³>Éîðb³îïp«˜ZõsHy Èg@}cD=­F¡Ìo`º@òŒìëÆî×û"Íæÿ-Ÿå 7h³ü/»!ë­ý TöûDÙIÌ£aî Z¸¼*oPž­úô òþ 8úYÕ>’Š®}Ø"ø¯§õ§‚?üq¤íÿy-�+ò_ÿ…ŠÿÕ¨øì Bì˼ÐÄ} ®‡�$FmÀ@ñ¨öV¿Î¨€×°÷õ÷L,£Ù¿�ý‘l5­²Ái&ZÑØWˆb>Mߢ…|;ɡٕñ£‹hz§0�õ´¿Ík¼ŽUÜu��û ö÷vè9ŠH¿x–{‹¾)µšKR ~mD‘ „�ïŸÌ:þ°ç�(�®¤o«�øÐ÷rÖõÄ©÷+¿Ã‚¾…z¼–ø^¢µKTÍå„9è´¿ T+ªÔNhs\@H� Ðìõ�t8Î=b âuÚÚ[=¢¨]cÊ›m;Ì� Rjû{,fÆeÛ€mså¾Á`ßñæÍ\Vїℜ‰¨ÕŽPDµv¨»”íñ±îÀÞÉ#xˆ^ô34D„ûå–O+.¨ p5Ýx-Ûv"(œ•‡úR¯xL@)‚Õp°n¦÷<„‹nÕ3€ã˜Ð쀠žâ#JZ¥)×*j9Ïm|[DÓ½³?Qs {²Á‹XICèÁäÀ�õ ‘D"À ¾µ¼ã‡ó-œNO˜]ËN^Ñú¶ÉüöÙ=Æ÷ žAñ?ú·þËSu•;êwÿCyº•{÷…ƒÓÝj?�€H›Çû/ýU?›yá3 ½ÿ»8ŸØ:°3ˆJ®uÄT™ ŒwIˆ&0   šH7h6•8¥Ô¼ä,M½Ä€Y`«˜r]Ü à8¦X9= Øxq1€¬e-s­PG=ôê'‘¿õo‚ó'æl—“Šä® ÝnÃz¤«2ÈE(PqT(}>>LúZ=Ÿ^ Ô@zøË`Yó‰.­Èø_ÃãæL௠Öà½ÓAÐãsì¿þW�¿òû±}ü‡€Tº‚^uêáêÿÝæ!àªý ЈŸ,:€-AÅ@{”Ï!õ³þØÀ³ò'Êü_<:à I¸“†·ü¿™åù�×ÐÃãÊÈn¶ý¥øqe€Ì‰ŒlÂ츽‘(y¿*)ÛZZ-¢€¶ ”>hC­7ðñ[àíïÓ4P{ô4_˜|:5ew¶�>úßÿuã™\€M€å÷<ã¯ü­W@H•oóø¼µ àÿ]˧Óh¸·Ä½õ¼ þ^©Ygó�žv·G.)�WÌ$GÙ bEr@ßù‰z—ÇStš7!¾uÜ'÷à³õÏ©�N}Šóû ÌûÄWŠZ*Ä-æEõ!ßUøþ¼6þ� ØîùÏR« ¸ý'Í‹ ìVøÜ¿8º ¡-¦Joà|üŠ[p'Tù:'âDAqb˜Çž°/K¢Š*Å€ÿjÀ÷ 4EýpâÆm�…ƒ#�Ùé“{Ú×pš’>œ�ðÀÑ�ÂÝ4ôwJ)[D@ÊÙ"-\é¿Þ¼yƒÏ?ÿÇq@U‘sv×{.'Æ–²1ª‘ÂJ­Ø�‚ºÙ¡ë#s H®üW(VÀªU«V­ZµjU¬EXµjÕªU«V­ZµêKPnñJPez d:9öOôä´ŽUùw'>ƒÿ À Ð#ä yŸ.ªƒÛ1Â@ýÃ÷ˆ¾c€ü‘¦TTÒ»ã6k戞û þÒ?è?õÕþ*¢¨"P©y̳BîG�Û9hT‡:¯Šzžø9ã7Øö³uõhp »åûaÃ�³ž3–+ÿ0]‹ë×Ý-¶'Ÿfš¬®%ŽçiZ¾tî/psá øÖ7¿Š?ýÇ�™¶×�òGÐúÚ‡©�» wöÓg52Ô 9ä{s ”ƒAHzõ1hû`D/qrÀ´”Ø2Ò¥¥€¥¥"€Ï»Dí>W�f;0±÷_òhD6µÛïúñh.ÕbŽH€!O@H/8Àâ Ä@) ›Ûé›ùë»BÞ· Hñ9ì9Ím O“Ä2é[¾<ÍkV{žê<© T°*‡SdíŽnq¬µ­65¶D8¯Ž¶4òP÷Lw׎+ è!D�¦`& þöß‚Þ~Û×ÿ (hU½€_ï3u ü Àï�Rÿ•bÖüò)¤|'Ôg³ñïgß¾BÓ“EP6ðµ“Pˆ|”×Ðò9ôx ”PŸ�˜Pܹ¡’Í«¡É×ïì–ÿæOî0Hf�fðõk€(êþ9°¿iµ8ƒíLŒ±N¼ �ëÀ؈Ü)Æ•÷ CAåÛ�ünßýM#Í€øK`Çÿùo¿ç€åˆN¹ÎàÕ§EÑ9 4ø(�œp^*mû jî¦8?ÏL q8a�]1ïу¹ÐgeŸaýöˆ€~Îáý4÷ãùÄCôD`�º}}뺻³zŒ�’=ü0rG�¸w]x°Aà�‡Î&‡ÕZPjB*µÇ¡œñ:H& {ô½ºEô ðßÀéÇÀlàó–³�Þ‰ýý�÷Cþk)(µv ¼Ài+$�*�$@”bEõ¹¬Õ¬û‹OªïÚç98"üîFJ )mØÜ‚?¥ÍöMeÔðþ$–ˆE~ÜÅC0!§„¼m#R¡âØw<ßnx~~ƾï€*¶ËÌŒ²mw}"Þ�{9p{¾¡ÇQQŽÚ Û%CQAÉæõªU«V­ZµjÕªQ‹°jÕªU«V­ZµjÕ— j)U­PUžþøÒgž�xÎYÅþÀŸe½Ç<á·œ²g 5$†Å½VšT‰x È@ÎÈ*ŽÈdЛ/…Œáwl/8 ´kiŠÁáh,h­Ýj·¿üŽsžcgôã´ÌÞfÛ 5pŽiÒm÷Œi=Yè«ëYu¶’ŽnŠÔÇ�º4ƒÖÏ Nã|ti|Ý0ýîÜÛyìP@&¨¾uú¾+zGî_ýö¨G?cýÞÿ-̯¨¸Ô�%ÐH$94b(Ã÷_üËáþ!Ãh™�ßÿN¿U1 sj0Q€ `‡V€³�»TÀṟêjs"С»Ý*OcWR3�{4[Vs?þQœ`ஸ½�ÖJÊäì)t"˜†�à‚ô»þò‡°­P>õ4br²„ˆcéDŒw«YÞ?{ vëjdÕ¡RwU‹0qfƒ%Ø^aÙ4ò¼îÁïùè�èD¿^iîÔ $Ô.òæ7qûÇÿ[l_û/�/?ê¶ÿ7Œƒ Ф (mPº˜ºpÛÿ×€~)Ÿå€¼�–gô¡æ\‘2”7P~2'fp»fuÿz@Üê_ê§fù_nÐã ‡G„u@»¹{ —AÏ�Çi}×·-Á§ˆ˜¸GP$öœ�¥óëOëù¹A9 ’ƒÚmk-Nâ³¹”Oqí¼êvû-ïÞÀô‘Mß¿�@¬DÏÛÅsë·®vgÂp R#ÖZ§¯FL8[ïwÇ#5%©V²x#h�8µcÔC<¢@_x¨cíêãoD#C؜ٶ ÛeÃv¹à²]�rîÇàT@uŒeÕ9rŠùñ|ˆî ­Ÿ[ À¾ïÝrÎ8J1‚D)¨9�‰PkE)e?pnÏŽcÇqHµÈ‘‹µ'Ý�¯ÿ,¬ZµjÕªU«V…Z€U«V­ZµjÕªU«¾Uj…¨IMl €ÎrŒÇßf%røë9röÏ ÇÑÛ²´{ñ[>’d�ñáù)ÇÖ‘òh� ÀšÜ™Ót0›Š˜˜2®ØÀqí"âv¾˜»{vÉWTüuþ�擟;¯Û,›jÕ>tמӫãCÿw0Àˆ¼5‚À9»A"†éc,åÁxt+9T¥g7åh<Ê#ðîœû³Lăw`õvÚ» ƒ/Xô°•êƒËLøŸü[Ô�Z{nâ÷ÌZýøÍÐÖèaÀвú=�›>Z6=� Ÿÿƒùµn÷ί>ø•)÷«g¹÷3‚S¢I�¨¢j%0‡½«á§ª«ÿ,RÁÅ šÕæµ*ˆu€±D@ÎfM ˆ¹d*~À@YUϰ‡¹t^Í¬Þ ”m¾BÔ|ù .?õ?=}“>Éd×?Ö 9�,-� ¾Îû¿¿~³Úsé1kì;53À`ÔÓb7fÆ9>ÀÛªb x�7à5-K37è«bwpЖ|ýÀñŒã×ÿ=äO~齟¨º ¾{sóÐu4Rž�òÚ�ûå3h} bÑÊÀO ¾‘€¬ÐÑI0"7·ù-o€ú8ž-B fùïm·#g†EY´X‹Ìü3·•¸`z߉B«‚䆊+Òö�õ Ô åÝÖɾˆ?®nkk—;qB€˜a[«Båùƒo€è»ÖUlSð¿ò³;þ¿qÅCßÿNä¯óÌhêvr‡�G\¬´ñqŸd´É9兕γ`xL§YQ�à<Ðö½i#“þ|=íÌ Û½ÃF² mjùów}ôÂŽÿ°zG ¸ï”û?ѽ`Š¢Q…HÅQJ�hn?MUžr2Ð>¥®~¯Ô >×èf`¯˸‚(!o —möeSΧ„”3˜3ˆÍö¾_ûÞ;Ãc% �gp�ðÕI(ÅiÒ×'"�ߣèˆ~è.°þ¨ÕöD‘ V»‰ ¬ É =)el— —íŠËvEÊ9å~ŒFDQµ¨õxˆ¦¶OgW!"Ô”PÝ��ýýÐpYnJÆÈÀþ‚R ¸8 �Cš+C$QT�H €oŒ”)­�¸W­ZµjÕªU«b­wG«V­ZµjÕªU«V} ªJ`Ò]N) ýwYÆísú4t•ú'ˆ(ÿ£ €þ�qgGÿ¨\�ß­�Ý̾˜š­vwh–Ò‡ìÚñ·a«=ËðG¶q˯�#BF1iŒr й½�0Ð^Ûªi²z~h@˜â¡CÕT¢œ"A“bS£Š¾5\éN|:A”Aly—РYÇãÉgP @°Ö{¼¿!d˜Q¥û9s~*Ñ£Iú–º·”x|~òïùÝ߯?÷­Ú ü xþU�Ëìöÿƒ• �6ÿ9d�sDpû‡ÿ.f 7—1e}S�‹çk7@ž¹ƒ¦ÿÙŸKÁu@‰mî»Ý>ê@‰/Ãö^3”«©Ç9š@)p6%³ò6°™Ø¿L†eºÚ[DÀÇÑ#Ø�œ²Ac+ÀeFúð'pù‰ÿ�)¸¡ïÃ6Ø�ð@�)gp�¬-ífå{»pþ…ÜUùòàšÚï"è_=nÁ³¿›Ò_ƒr¶�ÚÝÀ"Ð]^hW¸_!fµ ìßý›Øžÿ òW~'„˜7� Õ"ê �×�ã@ý8>‡Êk@Š�J@ùÐÕ�MWýk}ü?Ûq�T‹ÿZˆÍ ¸z=�“9´ï)»cIðïБ`ÎÚȵ@k§+„.Àþ¨u$ÞìÒÅLw| ¿vŽs‡Ü-EœD@îaã‘>ù¤þä#Eà¿öû þ×U°Wî`%-áL=BF'5ø½—R¦%?ZýG²�ʃuÒw\јèî–áèbû:¦×6â×äcBtGOiûˆb8¶LÑ7~`öžüö’¸Þ‹Çë�¿=xwÙ/V!ºFu¢€=Ú‹^Ú.†ºÜÔìMYÕýÌÉ€u·êgNlÜšÞ�ÿáà‘ÍοVBe‚÷¡MìÇÜ.ÈÛ9oæ�2RNvmbäÄÄàoÔøv®|ÙpÙ6ä¼!åÍÈîHPk…h…B|+a;¿O•�ò†T*˜ˆª“Ôîñ°®¦gpÊàdװ匜7\.¶‹‘ˆÙÜ^0b ÊQQÊÞÉ�Ì š7Hâéþiñ"‚‹lFc“< =¿9'@)·Û…õ[#0RbäKîïç*×¾Ôz`?ˆß¬ÿ,¬ZµjÕªU«V…Z€U«V­ZµjÕªU«¾¥ÀL”˜9ç3BþŒ'Ð1“¸YäS°r—^Ñ/_;¡@ÑÙàtΘƒÜztíž©îÀDTLF+} ²J ¿Q`âùZÔÀƒëéYãït`ö¸ojP“`Î]~jtÀ4LÝ×­þ]¡çÍè€ 9K� Û£'Õæð=*}Õ—-öÏjlaËhnóaƘfEôéÅÓMJØféãî™ûº?ìA�Nu/øÂúæ"ûíÏÿÙßkãZkx� þÖ_ƒÐZ-±wš"[ Ìg(lìrüS·í÷—�ôÊÀøcwdÈAsbSÞ'ýÛÀùÖ‹nÙ¯Ùɉ=g=�k¸hReØ�;�QSŠÖ M $tSg '€„J®Úv2‚Öd$:úq|4õ»Ï�´‰ _.�?ùƒØ¾ý—\¥­/�Xkì¸Ï³©§3܉"�ØB‘�’�cœ¥.óV¶1kƒ¨bq€�ŸÿÜÀmhu’†Ç=bA*´}ûûÏpW€F pð_c„E ôàÊu4%2áøì¡õékÿ2Àœ7ûh¦�÷õf¾|)Ÿǧ@}m±bd ¤  +�¯ ºtqð_-€<£ÖgSú×7fó_Ÿ�c‡ª+þ[9èÎðùKl Ê ìó‰� eÒæÕæa±>V©@©FdÙ¿æ+j=l­;žQ‰‘(ƒÒ×FßNíaò{Í,` û’å÷AïüàÓ~i¯2ðs?¶ã?ùG×� Nð´ØèK‹Î#ÖyAâßÛ¤ý¬c}[kd¢aríévˆ#h6RGÆ}|^‹¼QщË7×§=%Dþ0¢b|'oƒôý]_ oÍ[Sl_ÈSx«Ã0þï¤Lq34ö0&ä¼áv{ÆqмmR¾âz¹âr½ôˆ€R‹ÔÏcË4ƒ/Œ$F(µ€ ûš�nÿŸrBÎW#\6¤|AÚ6l9ùt%3aqg‚Z+jJHþÕFis"ÁvÙp½>aËæâQ‹àvÛQŽU,.$%Æå’‘¶"îSˆÔRq¶^6¡ˆšR^ÛÊHЮòÏyCÞüñfVsD�j±/¥V·Þß!b{kJ ªŠ S�P "”ÃÛ[ RÎ�d“RÂÓÓTeÛ j6þ9g·óìû ªÕH þ2oFÈyC½TìGE9¬Í¢FvØo;DëúϪU«V­ZµjU¨EXµjÕªU«V­ZµêKPœ˜RÊØ¶ 9åÉ‘—p0DÒÑòŸÎ–ÿÔlñ)ñ þ`R“?@N’Dv>�TƒÍN¿YÞÓ &4Ç€ù‚)ØÕ›"3¶}Ð 0þH„³�ÿÜOSÞÁèê�+175�ÐA–fW«Ò”Å:µ£üû9øþ>†Bïž{Vè«êä¢@t²è¤ n�‡éËþœÕ¶þm1 o©sÆNsJï�á;ÙÜÑ0Ð+gÆÿð¿ûÇ0œ*ÌÄ»CýßÔÆMIN=_¹«Äi úñËÿî¸>ñ¾¨~ïcˆÛò3‘; 4À¤ šÔ,ÿaYæ âd€ž²[ã' 4p©€ScŠ©¬ÍŽ¿˜b[\ë ndŸéÙÔå�d°™­:Js p9 $ÃYà€«ŒÈ5R�(ø£?Šü£ÿF°éÿ"‹Í÷¸´âÑÑö•Þz.³ù¯u¨øüwõ~ÿY[Æw ´ç‰Î×¥Ci:n�Fp‚ˆ8ÀÌî@÷‹®YØM¡<ÿ&êwÿ:._ÿ!)A`Öþ7@ß@ŽOÍöÿø *7s+ ±�ÿ”ŸÌòßÃ@…èÈn1ÇgÐbêsØÍî_j3‡G‹Í0ò )›“Dâ úg»v À¸G‰@*´à¯Õ¤@ŠÍ+•µ‹ü´eogÅ£ÅKMn JiäÞ·¨UͧA�œ¡õ5òW~û?þÛ}Úæ§wü­_¼žÖúGÖóà åî¯qsxä8â{Ã#\<‚þ­åÃZØ78ìspp¹ý¬b$ ‹#0E¾FÂ5R�ý¡™2`€ÿ}½?7oZKÍÑDDm@z[wEÇ>0�™LÕd@ó‚ÃL؆wˆNÎ D—ˆçç7¸í;Êq€ˆq¹^z_šÅýœLÙ^eG-¥(µvµ;±�ÔL³«�lýÍ#ñ†”3R2ûÿœZ Àæû»í#5›ª¾æŒR+R)Càûÿ¶elÛOOO¸<=!q†AÕÊaŠø£Tp‚ÀÆàtÁ–6ûT—G©È{1Â"Åö  £‚IÀ,H ÈNޏ\6¤tAj$4¥Úë¤ j=ȯ¨µ ¸#A›aF@Øþ^JõE*ª¶ZÃ8\ð$‚”’;h_Ë[×ZÌ  r6·€ëå\Øe7B¾ï¸7#H�<—õŸ…U«V­ZµjÕªP‹°jÕªU«V­ZµjÕ—á�{ÎH9‘vÇz„j�ûôq=ÑIà¨ýCí» ÷ kŽèë P>“qBž<5М0>+!‡²‘ƒ3€>pëÇ9s9\Jèi¨Ì0ÒÚ•ñC1 µš4—wAÒA¨Dƒ*4eõÆþœÎ=õ[´Xĉ;Ò@øF�¢0ú@Á©§<ë3?¿îüú¦Àg"ƒBßBx äǃtPÿn½�81žó ?÷ãøÚW_ù¯\ ¸=A>û{÷7‡hPó»Ý?)T+ˆ2Îööòùo"R?ÌB:üäjj@˜M`@“Ù¾'!DÙ@!b#€;HN”Ì1€$ àjÇHÕTû¥å€ÀÔÖÞBD{S4,$€œô@” L <·ŒK1ˆÝI+Ür«@6€ üáEþÑ¿èç,/GÜ�lê÷E�à—Æ¯YŸ“ëøAƒŒ¡ãÅ<Æ÷…¹ÐAO©ö\iŠÿ¦6¯¸ËÒÀPüð¬§/q»ôzz ™+A�:8Q±‚Uy�•P@Ÿ¿‡úÝ¿þúŸ“_€ú"¯�ò)P>ƒÔ7ª¹( ™åÚ€”Á´Á\=n Ü ò8^›êÿx ÔôØ!RŒ@¢b—˜Ùíþ�óÉîßÕþÄ®¢wǃükøø_k�¯@‰¤‰Þ®PvKüºåúü=Ðõ«Þg)Œ…»›ˆÌö�ÜØaZ§„üäÇ‘_ýmÔ7þKþÕ¾âùW�}G±Û:JÝÕæäòDâ÷V é¼&†Ê¾ÛÊ?Þ1ç=*®qDs¤3Ø�T´®éÉh Pï{†ÞÓ¹:1ám6û�ô†ø /Gþ£�>¢Â‰‘Ax{ôú£á Yó#;¹5zNsžÆ\g~§RÐüÚ¨úÔÿ¢“ý‘Øö ¼ä¿ù¯ý¾p¦°dΨŸþ=·­v<:œ„9¨}H­}ÎÖßúˆÀ_Ê ZôþÇ>ŸÝ6_\ Î \$$ðÉ$ò's J@b(ÛcSY's%àdçO( à%€™Ì¦»¹®FÁ¬àO ÊÊÙÀ\Ï›VÎFhó€\)~íª?‚²‚?ùCÈßü×½íõÑúQî?}—V/Ÿ£‰�šÂšñ҈ǯpüòë 7ÊDªyØkP§;èݰ†¦�Úh—ªP¡àp&`V’+Poß¾ûaûÚ6 ŠÙöË3ôø *Ï€Š9òð(_�t5â í6.r¨^]í¸ýÿ±£–ÃPñêý’œ\•Øÿysà2÷øˆ¾ž6 _NÀS‹»õ?J…¨xlƒÚ¹ €„„ ©F0©·g$r…>5GŽà#Nþè¿ð±%¶ûUhŒ/½}tÞì.U®ðóß¾áoþ£§ioøá§°²QØ,éå™yÞCÎñ Lä7ºŸ�Þ^)ÍE‡€Tãä)ý!–VíÄ<�¶‚Rصíâ4 Éýqg*ž6ðÿQ€Ž>¥ù¶ t€—ÛrîßR«)ÕkE)Cž·ŒývÃ~17s ÑNÐ`f)˜Ç1¥ŠЪ¦*ñ´�HºàyÄÈ'f�>"�ô‘>"MI_±‡·˜Àœ,†@=2È;C£�¿Hµjµßy‚ ˜)1ò–q½^LAZ¤+òÛ¼›ßÞ4íþG1Gõ~²×¶-�hs€ß¢¶ËÕÜ DPÊUÅÑHdÝö?#'#9ôøƒË¸†R J5KÿR†‹€T…$éΉÛåÒ×Û”R¤ä�£–EXµjÕªU«V­š>G\]°jÕªU«V­ZµjÕ—à�û–H ·âh¯a´{5}´ä½§Ì6ó÷ŽÔ¡ž9`VÞ½d¶î×ÿ?ß)1þÒ_üCž_À¨}èöüt?¯;(å9÷ÄãK†àÛ—÷_þ˽�‰ÙÆ33èÕǪžsśźª¹4E)W{\Í^]ٔτMdÎä8HteË`1´ì`*ˆ�ƒ²j6þTsh@7 H3�³å¸CÓæªM©µ‡¹ 8�…µ‚?ù=ؾõoú`–æÊƒûªÅOÄúY¨@}ä�)嵸yÈÐÊ m©Å7@,2 ¼†ŸC�›Ûýß ÇÈîsÔmØrÍÑ@ÿ´[2Û6•rDyUÄç˜[ý7à¿6' q 䈠çÖÅbq)銔.oÖÆü�ß{Ö¹zÞÑÚC&sÇ�ÃÇ×ÇToÈ_ÿðoþ`Ã÷gfÇÿã_�Tÿ¢Hô¼£öy`î ‘äôÐö?Ä HUoRXµ›züd© Y  ‡ÈAN:щlwºc(ß­¡âù5LS#û@g§€vY¤ãºl«s0šÌÔkâZúȘ(úÖ<Ügú;��~˜R …ª‰}p•øí†›Ûô‹[ÏÛ%›r=ûÏ"lïK'T©N€˜˜e>�ž@ýöebt…TsØ�û~Ãmß±ßnæ¸âÇbfì%#¥ Èd‘2¬ß¥“Žt@5»?áryò¨†„”n¦È÷ã$æiöšê¾@Õ\š½9ˆª¸a‰*81.ü„œm-á”pÙ2rÎ JfÇOƒ0$R ü¯P%;-™“�»'èàÿÍ盈8Ac�bŒ±9l²¡^ܹ!1®åŠâq<«V­ZµjÕªU«üsÄÕ«V­ZµjÕªU«Vý³_[Þpb9¬®Ÿð/ªæ½(€s>µN©÷/¤®z#&ûj¿¡s®|Sç« %›Â¯)­OêGâþÓ èàø½z0:˜­:&àÎú#dÜG<ämªB?o³>~›A·ô¾Þ[v|È?ò ¢„N„�œøÖν/Gî³ �-#z1k°§Žë¦àÔ¦þ�ÔŸšø“%¿ôãS£y–½äðE!ý!ž½ŸÿÙÃW¿ú> Õ}%HÍþ¿Þ7é`CiýÕ¸ q»u�î¿í'sð¿ÍÓëÇF6H>εÎ�pÐU¨Ù¾ðÂÌNç5Ü¿nÇÞî‡d¯%f(±�‡eSôs­�âÙõ 0*’¬n¿, È¿e€Ø�èæ÷cs¶ 7"ÁÓ×°ýØ¿í]RðÀ»´Êaüë|O÷±’FÓíó‰‡òŸ(8PÜϵÚþ tŒuœÄ¬>¶f ‡¶¸ ó=Þìÿ©¹Bèh›žnƒàBúÐ#>,bm ‚|þëÈòÓ�¸ÕTûöòÍÀù¼¹Þ� ´úlÊÿÛçÐã5t7—Ãç…ÏKb '0»Ýÿ–Î ·ÿGŸÔ]ÿíÍâß¾KwU'œÁJîs8©»VlOvü T$Ù¡rÑǶϰƒ¦q­œ¢ìº8%T->ŽH~üà÷ŒÐšð'ºâþïWì…§94«ägrP$—½´“ê;Ö;mN"JÆ:¡‚™'"@ô©;ãhß3ãþÛÎd€üãµµ�ö¶'P'à45#±a�êô´ö’ŸN¤;òXžîH¢G‘ dN$箺Û.è~ë÷·k”rtëyËŸ—nIÿü|¡Ö‚œ7pbl9#ç 9oN0ËŽ£gÙå@©Õ—%Bb '4¥æàÐ#©ÏݪçØwû »ƒÿ‡ƒìM™ŸSBÞwdÎÐF¢$›3Û–Ñ"šËC­·ýf€ùEº»AÞ2žð„Äæpì;j#èø4`]ºZž¨vÛ}s®œQ‚(ÙRÄvž¦ì·fËÉe@=J }é!`Ñ ©ÿÜ^Ó#ÜÅ@w&(µ€§ÜïN Ûå‚”’ó�–ÀªU«V­ZµjU¬EXµjÕªU«V­ZµêKP[¾èqT…2¤ ¡YëbÑ�˜ÿ~ª5ð{ @ý»â®úgWÍÑ”… `ˆÀdg¯®h{Msu>ƒÿN*Ðà‹>^ÇÎhnCû¥úc!qÄ:†´¥÷ô- íVÇ:‘ÎÞÐŒ¨Ï'“Z|»ÒîFœ0,~59Ú«®¯ƒ%þ„¾ }€EI´Tî–Î NSÐÀ Ilx–ÆÎ€X',¼kžqß·ÄD�øÉÁöÛ&ªÑ£ÃCXÐ` nE55pMeÐ5¡»9à’�Ÿùæ�¿ó+×­ñGD�Þ/º­ÿà øÎ&;E²Ü‡§t2™M 10Üâzr&ˆ¤>œœºÂ~2aêüɆB(#ðÊtðϦ8­Ù­OÈIª6åÛyD‚ƒŠï=^îÖïèÞÓ=Ø\ßaðÂvA"B}ÿåÑÇPkÁ~þ¸bÛ6S «˜LÕd¸J·ÅT·³Oš¶1àFà`�a‹]Q {ºßG©(GéÖö1ª@ýÞTÔ*(µ‚¨v7�œ2.ÛÖ2ùû ‘Šc?Ì @*rÞ°]6$Nà‹ÅÔ¤d–ûÇ~ ”"ƒRE�¤‚êìp”‚rT'SX§lï×Rb¤œ‘ã²e¤¼!1£ÔŠ£pJ½_HyLy?M®D f §I9UÔ”ÐHÌî"¢ŠZÄúFLÜ=]RJØr~' vÕªU«V­Zµêwb-ÀªU«V­ZµjÕªU_‚Ú¶ ðü ±¬X„þéí઎̀‰(³ƒûé΀ñ¥@í¿UÒ9Ûp €Ø³ Ìþ•ÌÆ›†S@D"TД‘ €_¼�þZ†n�Юü§`/MÑ÷ùd›ïG­Ö3Ôão¹ß4@*r;y¦@`LG•›èÈ��ÔU…äª?U<ßÖmöÔ-s¤ ­¥î–À ¨úOܱ¿ ¸:Ï¡¹_&Øï-ªY}áñÛêÝÏ;_âç¿ñûP*Pm„9Íq(çë%5%?§`AMP@òƒ_3¥"9Ï \_�ž>èU7{tª¦�­!Gî* p Y!É:�U U{¶:åM`¥¬ÑaÊm1÷ÊT 4ØË|®‚5÷j� �›úÒíÜ)mÐÖ&‚�Á>ŸuSl?öoƒ®_]P`wBpOÐÇ?·sû}‰i…‰¯qÒÀ™©Ó íûÉ� 9�ù¾_3“óšÃ@SMMM$á~]¤³›@·Ðû[;½¼mþ6€ó‘´ùt/õ8Åþú7påoƒ¶+”’�3gPb ÷kê3äxêè~Ê)»�ô€“LìÀ6bIÎ6‡;8ï7SwŒh.>�¤BK±¹]ª)l�h¢!´�ü|àN HvíàäCçs�Õœ-PT |¤ â�0=T¨†þ¼XÒˆìÈ_ûÝÀoüƒ‘öà_ùñûW®“n_}]dê+(¦¬š»…†:øO¤!žâñó÷—H4îàtØTô‰`ºKhx¿ô^ |&ž�ó;0œ<žç$µtó ~Uŧ‰BÝ¥ƒN ðà>pìydëÒÉsÓ/^\ßß¶U4•-g’íBNŠw˜]> '†ö÷¦¾oŽ?"§I•>"^ܺ>Ù7‡¶Ÿ;è_üþ�RÝÀ¾j­¨¥vw‚G{¬4¢¨+íUœØ|uF…jE­Œ’*žžì9‰rÎH‘Ïâ÷3Q™Ï%‚íbv×Z ƒDl-á„”.Û†Ëe³X*"`râ‰xñŒïï}DQ»[CXýý)ç~Ý=NAµN01R1Ù8pBÎ.—Ëú�ªU«V­ZµjÕ©`ÕªU«V­ZµjÕª/A¥ÍTNœ¥Ä'ïýÇ€D»ï,íéüß½n~|†§_¾PÔmç©+›UmÌèøWPÂG <~ `Š  ž7n k£ ˆ8Å�ÍöþQ~ò£6ë‹m¹Kš*?  0\Í# T'e“ƒøÆ’È£ Ä9A‰z8RÃ":š± ScxtX5€‡ip8 `’ý‡ˆ„Y¯Ýûgüs?�îÅžï¬/è€ý‘Oðs?õU0ö¡Rå òúïØ0,Û+îS¼Í’ÔÀì„Ѱÿúô\b6Fzÿë m„ 2´š‹—jJÿžŸ®Ý£7¬˜,H`òŒu.ÐÚÚ p†'›ZÛã,ÜI º0œôHàbJíN¨bºùc70W«©Èsöcw&¤oüyÐû?�; :�èËqV2þ&¡á]Äÿ–;ޤ };0®‡›ÄyR;€Ö,†B·íê$Nö³ô§Ùÿ·çP@ý6æçv4 Ã‘âvûM\ó·m|(�’t8ðƒÔp¼�7 Þ€£0¯í|ì üd䎴ùxû|¢@–p _µZ_9Eųøqg‹ZÇôu<¨þ³�ÃÈ>—�VèQXR »·{RŠõÕð¦÷þ¨î¸Ð,õë<>4÷aúø§ÁÛ?€óƒ?ù3ÿ›ÿh:PØ›&l÷m« ¹Í(tzÕ ›ÍwIÿÀÑNžƒ¾s�H+‘ ×cÁýÞ>Aëô¢²þ~ýî2tJ¯ßgÛsyÆ eîÞƒÌ=Lã|ö²GT}qçs—fÊ9S5`Ÿj`77Jé¥Î |{NJyKàÈ,ìû%2u=3˜38§žaonu|Uî¿«-PÛšÜÏÇ~¾äÇ¥Óþh€m3»ûvÕjŽÕ¾›éI HiÃeËÝÕØ ªØê�Z"÷n -6¡“jSé‹�w£&Á#qrb¤œ�Ý¥¦z¿�¯;Ì MéΉa�Ìu¥>xCÀÌȉQÉöí�B©m­²þɉÝ�¯ œxV­ZµjÕªU«VõZ€U«V­ZµjÕªU«¾ELH›}¨z%kà·¼(Zúú }HÚPùŽ‘¹u«FÅÿ€GÏÑÄøï ?ðþì_ƒ“t°Éï ù~Pç �ÙÍ¢�ì#‹›ÔiþÁ3+»’1\ש^ø­‹çôÁ£Ê>âô"Ò>^“‡3†žtòW0¥`®$s‹çé×s@Г‚R_6€càØ½º¿“1poÏüÈ!B_ìй¥_´mçü�ß÷ãàújíŽúÙ?tå~ê trKý~Ħ„F³‹uüÒÿ±çw`u#ÐÓW�–Ë X6zïÿjó¾¦2ì³›Â:‚˜µZ\Ä¡`ª@b(S?óQµöÍ ù}¤ÚÕÞFHÐÄàÃcü¼˜S€(4»ãg‹›‹Áù+lV¿·ê q”=.ámw‘>úå�M8†òµCˆÍÊ£�«Oy|ÎZíBõ€è• Øœh9dú®(Þ8û�¶çisQ�`ûî9¿cÁu´EŸÈp,èÑ&zj�4 ç3û÷pyõ ·ÔkÙ¡ÅÁÿºÇaó§/ì¾¾f#‡PÞ&ËÿãÒ‰A®æ×黃þZq€9ÎÝFÜâæLAƒlà€6O§ùÚÐó" í=h5`|ø½ÞÍ¡$A9.Á¢DÌ®P–ÐïÛ+ð“uÜøá(¾ùIÁ¯ÿv>͵Æi¡°°è +[pjÐy¡Gëi#ü¸Ìy#y¼þ¹^ÿLÔ ÷Ðôû¶‹@˜œ$fïè.’cn·Mtˆûx{¡j{¸ ½ö©ÐÏ×:ÑN÷ÿý%Ýõ²¾å5aP�w(¥L`æ4nÒD'*õ¦xOGé±=­ÿ¶¼aÛ®S}N [6u='ÿÉúR¤¢HE©Õ-ü­‹˜@ÿ‰ÉŽÁì¼™ŒírÁ¶mÈ)#ùï™ÙbZ îX�,& ”z ú¹j•I°]6\jFª)§ì߃ýg Ñ<_Ü9@¤@„QkA†T#PÔ(߇Íswrr3R ´cÖZ§sD‚õI‘Ûÿû5Ùë,*¡µ§!¢â±jÕªU«V­Zõ;¡`ÕªU«V­ZµjÕª/A©*RJÈ9T/ D×;Uøéuí_=ÙÉw€*TP›+͙Ģj Á?˜Ö;PCƒÕps°×ííÃ܇Â? øŠ>RÈ»¢ŸÌ†Ýà¶½â–ü3ÄA'‚½Í)á‘MqlÛÝoæ±!šu¤öcð6�ùÕÉÔÝ ÆÁ‡æø¤ÂîÂ^ë©Iúâ9'vȃy¿¿}¶½s�óá-]qÂŒõÄ8ÐÿçþËM±Þ2Û?èét@�®~~&Ñ2ÐÓ]ËèùŸ6» {ÞàòÀ›¡lmJ B†¢¸*Ú\ $5¥zS£»#€DPÕ•ÐXV=U014W@üš¥i4[4€òP_çd™ËäN•¡œÁÇá ¯8Hl SŒjPÍÐD ô1ò×ÿº{Iè?vühúÂXÎ íxŠw0?�îÆFÈh×á® ˆÄ�6ÚñëC=ì±T@w �F¨Ü'¨ÿ­˜h–× „Bõat�RÜ} �¿NQöá~r KH©r|̯ R¡µåÙ€ÿÇÕ§¼«ðíËìþ)›ƒÒˆ‘èó²Š$JûîýÐæŠêýšèŠ_f8€;ùd8TPw.èç%¶�žH 0g¨JŸƒ¨¼Þ>n¨vèÈàæ ª;:‰C$<—€ã@þè}?øÜf‘¥xàç¾½ã; uT|ÿ›É[3´<¢´-“¾Ý/—cá"q;±#Î÷Ý»uu¤ïÌJw Î+:¯}Ýþ_Ð�Xù´Ïµµw$°¶¯4À>’Z{‰É:‘48 h'Õ‰FŸŽ{'!=¯ ôxîû¶êùmA†Þ‘5Æ_·Ëf+M­Ô€îø§”Tž��Êa.")ek+€œ7¼zR¤l`}-Õ£6¤”;¹@Õ­ì�·t¤Ô�ž”“å?3cs«zfÆ–3¶-#ç y»˜ËSS΃Œ€¦  –" ŠÛö‹ ìû胜±o'ü«õ" } ˆ×Ãþ| @2CdD$4à{Ž}89a+¥Œm$©a�3RÎî0æo­v=Íò¿EØ=ÃØ6§Ü�Tå°ÇˆÂIFN©¥â†Û"¬ZµjÕªU«V�jV­ZµjÕªU«V­úÔqûÈ›MIÿ’ñ¥¨kÿÐÞòâ›ÚÜ?þïX²vÛä^©Ø›R°ïâ:ÙÏÊJ qíÀ5�Ôð]©Þ•ÿ�À58˜è…,‚“wˆP�OÓhk�{¬‹Î}«ïîàM®ÿÝ¢¼[ëGG ×ro»ÿ^ŒW¡ÝY}ü†õt#e(4ø+ëCòÀ„©>œ+Ñòÿ‹Ì/ŃI©o›‹÷5l´õî:£“CŸ Ìø‹ÿÕŸCEÎ8þ©½.õ'zžøæz² ‚ì�iDÿ4ÌëäÇaÐöQpwöî‰A”¡là6©u²êÈL× T»ÅºÐd¸ŠGö¸Vhª€d³î—jŽ)�8Y)‘�šL#"ÔpµóÕfe/ýLî.!HßüóvL9¼ÓÄ�ë8j�Ðï]yËjÓoÙY©­°_´\­§±–ÓÍè}­f¨¶ëˆÿû÷¦üoà¿pÀL‚@»„Ÿ©¹Tj'n ûyzpï%$>ü¹j_UPJuK|SÆ—š,¦)»;ÃÀêRºÚhŠ{nnNØ.›“8¼÷D»¥B¬C�­ôk-(Å€ýý8pì;Žœ\ÆsN.S%FNÉH¡Am/U Züuâ¼´Ö†aõÏNh Rfl9غc•�ÿ¶f¨;ª¨Ú{OñȦv-Ö fêàÿÅÉPª¢#Ôêk¹˜«Í~ìØo7Ü‚#ªU«V­ZµjÕªEXµjÕªU«V­ZµêKQû~ §l©Í«1°wÖêô =½ƒ]YHáÃô(ÈùÑòuX"7X„âáOø_¾Å€w�0{€€NYÀmîÚÓ]ãÏmh–Àè]f™Ø�’çÃRY%€AÜÛ²|O/Ä™~Û1þH [½'8øÿö:;þ5 Ã9»Zã)&;iX§žðåš»BOs�ðv„t`wzë‰ç¿ý ?÷€Ô V€éböÿåûèàþ4H0p´÷}6µ®ƒ–fï,ÐOÕþžI@~ϱLSLw”ï¤Ü�-òÑ5@jRA•¡\ k'Sú ¹Ze�DHQ0;¸ÇîÀdaµÅ„{‡ˆ¡&ho Þ~\k/¥÷‘¿ñg­ÍZ}~�Bîk[g¢=ÿ£ñP<ž8!¿ÝNަ·\ùóqDjªðúXýߎÕmý¥ÝxF–èd‚ö½�èm.ȸ/Cý®nÛ_ƒâÿL¨Ñ‚ÆÒ‡2Ä>èÌ–ÑN¶.Z+ŠwyŠmîÊ~ öû)<‹‘XŽw‹ êÿá<1Á¯Ä=²ÅŽïN‰ÜU �Ç œ]ùïóB˜–9â|4%¨r˜K è-Ÿ�’ù}{�_ß¾aÅEH\)Là÷|Šn"ðêüØW ~ù»Ù·.á}kØ×pïз[ß—"Gì¡ûIÜÇâºK:/›tÞMµ®íOqÅ8Œ]Ün%hŸK3©€†C�Ž=pÌç·l?}Ëqòa�†kÏL|égŒ·öKÕVvzG°Ñ)àvÛé8v‡)Ä“«Ü9  9ìø°õ­ÖŠâŽ+m/L‰‘Ò¤dnM-¿ìr@j5×€ýÀ~ØÏ àú´!åŒË怷¥)ï ªÿÍ? å½(Ô×:K–qk|´¨ Öþ2€p‘ŠRÈw,ð2÷™Ú8ìöÛr’�Ú{ ß'ªH'/ÍÖP"râAí.)g3rb””ú˜¦d)%Sé ûõ‹-ñ=Kt%pâEö膼m—ÐRTÜ ÔbÖÿ·à(Ç"¬ZµjÕªU«VMµ«V­ZµjÕªU«V} ª ~KŽü uϘ??בçÛ�gý�z2c÷—ºÅ¼ÿDgþxVCâGئjTÏhÀ æŒynÄ„(ôZEHà 2 ç{v+ôAÀdÛÜ>ˆnßÇuŒs5 gã±3uÂ};qâ%ì3@Û:¡%ÍÖÿQ‚2fü1ºÎ#XFëÛ€öÓ¸¸ @IŽ“Àßæ;{~ Ç‚ù«ãöé÷§µäg¾¹ã—¿›§8˜Fr{8eïH)mÑ·ƒåæEíûyNô5‚æ…üïÄ‘¶×2…¬y;N©¸›�:ñ­í¼t·¿© â6ÞqDôâM=釂]<<Ëý¼ç Àû¥þ:“½^ä ¼p§µ÷-ªÀ›7¯õ(å°µ…¶hsâÞ_]¹ÔR+¸{Á– D3¼ÙG¦R8€ãØq»Ýðúõìû‘Š”(×rt«}˼§aB4õ#uÕ|Ü{EÌÙ¤ÅRXŠûÚˆð^JÁ^†+Áà¯Ø¹k©Sûâyãï")!åÆKû±¸0DjXþÄøGo4›‚_G¼§ÞßD‘ òµ'‘º#‚í[þó4·Z¥¶Þùy¤`ßw”Z@;ݵwÕªU«V­ZµjÕ"¬ZµjÕªU«V­Zõå(±=õmXÔ£Æ[]Š_®ŽYÕ`Òý Ô×û8ä‡ç ×dvô@ÓžÒäU@Ý6Z¶Oöÿj†ý€º›@ëx$B7ÛÜG.å] kÀɰ%w°†G¶lä9è©_Ïý�Ý^zŠaÐiìÚØ´vÏ�Õzj²°o§¬^œl�õô¬:9´ï_>ƒ’ñBOÁSTßê·~QQPNŸ9w“ø îÏüthP1pòö«ÓÜ1@�G9Èûr˜ì`Kùþßu𓇀<3¯ ¥YAÅÀOm,¤-& ‘<Ø5� N€“eœ7€Ûþ·X€FQ€*XÄ�â ¥dNœìqòk!Wh#�ËHd¶Ë¢ ô¤�~Á�Û:E"¨«ã-JÃÿ`$,JüÒ� Øoj}Ÿ“u÷Ù î~ÐòÊ=ç�Õ^î7c'F4²€´0@æk?žÆÔ ±8˜÷õ~=ßo/¿áQU¼~ýµ'#p´_*f³àW_[[ÖZz4€Š‚��ìØ¥T²áw•~ë§) a’uöîk›»ÛúaÝ/¾›ü«¾Ýa#d è”±ËÁø¢&×ùæÌ¡#ÑEB/2Pª‘šRæÌSSí·œuÕnëmÿÍv››4¹Yù»ÕÿPø³ƒþiC¨�}É,m­«4lùÕ×:ÏûîJwP2²UJ‚r(HÜïCôsRm}V±¶Ø*(㔓õŠ‚ž¾1ºÝ§óÏÿ¨Ü­(m{‰ ¼žˆO¶= ­úC‡ÿGs¿ïŸa×kçxp§P”ɇõ]Ïçi€ª܈µóEÄ •êä5W_÷{tAŒ@P„CDíÄ&� @ɉD}ùP<¢Œõ>£0G§6žÞ™ÐÃ_ßçÜ n�zm`|³Øoöñ³¢|Þ)'dÉ®J·¹Ñ@ôR+j)�ÄHšÂ¹U,àØÇÑ�01RÎHn{OÌȵ€÷tÀ7•}­Š ³Ú¯¥:(OФȺM®F°Ø‚ê÷8ylMJ )åéøÃi€œ_¦(»ö냭V”¼¡¤µ¶þ1UJ9oÈ)�Û8™@Ý…¢Ý€œŒ«À";ìõ©;`º¾ZÆUV¤<ƳŠص%l—Ëú�ªU«V­ZµjÕ©`ÕªU«V­ZµjÕª/A]óQEbš²Ûã·aÛÿÈ÷“U¹)ݹ½,fÄ䠽ƌbÈn|g5+ì¡æoÙâÍ–¿)U‡Ò’©sWá“ÛÛÓ£Õ7º�3£¹cÓ)Ey3Z&q�8è"U�‚MÈ�`Ñ ±:AÀC\¹ „~ýk  û‡ás…ˆù¯««¾)€}÷`)Ø?þ^žÖ~Ûú'kíKû!ªgà úìºî¡xŒØ¼\wVØÓukP•Ž'¶üé³½ïÏýì·gn@Î=õføµ$¨+©‘›Ò?ÚÿÛÏv´±ý/Y#2�@|1Œ¼VWæ;x*lJצƖF¬ñß·É©<Ì!% ‘ì÷Ê®”®Îna50•›+@í€x3ªgUSyOÖÎ2|:ùŸ¼Í Ðõ[ §ï˜k‚TwáoùóFN}Ôú¾‚Ì—Ú;¼¾4º¡štÜ»‚�±wð]ÄÀ­D;~ܹa„¿é8‡ÆyNîŸ48˜íǵˆŽ9¨?/Þg/¹ª4÷†èj ±-<î£@ÒéÖôDm�Q*!m'Ò\ñïÀû¤úo„€À¾À? WŒ´�’»Epý›C:ÁJ¡Eû¢£ã¼S|ˆNð~ìq(]@|“Åph½Aé3[›ó˜ÔÿRº[ @!(ʈy�à! m×í‡Ð |õ•âãWßNw”0mûÝièD‡õK�ƒ¡Ù·Ôó2ÛòkÎê9ßãQKu(çL1…GÛôCI�•l[¢3ÁL;m¬û}U=Íã0ÇÛ_ñ"îÞa¨ž–p�]r(F¿ÐLl;íS Ñ©OîÛ0Ž£—â·Üy«“ïoÒI`»\�ªtÕ|Ü E ŒO2^§í D‹Yä³�GÊyÛ°åŒKÞ�rF¥%mÈiGJirPUHµsŠh·ö?ª€‰ÌÑ¡Ž•²_ƒGX;)™}ÿ¶mà3÷çQýÕ¢ýŒ`6A»uj®È[B:Reß¶yËØ¼­yÛúù̸FQ« ÔÚD. D‚ÜÇÞÞ§A’G3´x€ä·Z$T�4P¤r ñaÏåFfPH5R'ÆÅ¯gÕªU«V­ZµjÕ¨EXµjÕªU«V­ZµêKPÛ–PŠ|¡ÈíOÓlcÜ”S šWí£ýý÷4ˆüï MtõêÈ Ðxs è¯åq Ãmà”oì@>“€¨gž?1ÐO´þ§ŽÁ°eïàÝ?·9 ôübHÙ„ÖЖ”Þ³Ô–KÁ]¡�Öíïý\øßÝt—ýç1&:s>ÜÚ¿RæÆ½nò�uùd =žó"¦œz?wÄÕGã¡/\ >zÑܦY"ˆéç¿�®"w›r¤kÿ{0u6� ؤŒ‘Y.–À => S´];p+ÍvÙíøM‘ls\)Xÿ»B›hUÏK7{þ ÀóÒÖÜÐFÕ$v5@[DÀI#,€)Ø›òÞɤã<ðÿâÿ!æ¦ß£7ÜÒ�ÚzÓT°# ÍÝœ{À¸²^´„9 óšãàS}˜‹«ó¢­m2¢ ¦x��pBF{}w÷Ê` jy!p²\yhÿo 0ˆ&G€x#LŽ'šW5Òø>W¤» µ�c  ”�€ñÈ5'ç‚N:qL¶û€˜øg e£SÑÃÉ_�C‰ö9Ö\X&RCwuqòŒ[ý7b”Ý›]Cr"M@Ÿ˜Dr‰LDžæ¤HµSKœ‚ôP¿¦€ï|¥àû¿–î¢h2ý]®c�Óh}Òú"ëÃe(ì»ã\gð²»qÍ�*î¶Ïø�:‚˜@Õ÷Úô†÷wK/ÝOoêÆ:;Êø<$½Ôlþ£¥$=´}Q£mŒ¾s‡ O ÿÒy˘£6ˆ}Ù6\.\.R'ßj³õç„-cô�G5Û¨UPK…¤‚æ¢2Oñ“R–7\..OOxzzBÊ ÇÁ(U°Žb„�Hi.¥T¥ sq`JÕ`¡o*øܳ»lÛ†ËõŠKs û÷3í{{½ˆ@ê¸br%¾=7׌­ØßžÛ@öírÅe»Á‚ªTWì ŽRQËU†¤û7%" ms•LýÏœ{ì„Vÿkè+¢Ú ‰̳›‚ÅKX!!­ÿ,¬ZµjÕªU«V…Z€U«V­ZµjÕªU«¾e|Ê;žä¸ûà8¹�?Jooâ«BÁ]}M `|·Á¶ô-¸Hµ¡®aN7»d öÉñšæéÔ¦ ÿŽLb jÄѦîpðÍl ½ÎÊumçmþ˜ì›M)ˆöéK¶öÍ^ú|m'°FgûóG„€ žOñȃ/„YßO¥óåŽÇݱâåw�hÚ)4¸Ó–¾ÐK÷—£ ü‘é'-Ð9=¡«ø¹Yß7Å?` aGˆÙé>õÿpŒgj'f [QAÀLV3ÎQ4€‚e«‹ÇpËo' ÞÀ6_ ¸×FªQvÔ8ä¼'=‰ãÍAc¨Å€âLæ*=}tù@qõxõ{;[ûXCÇ‚ÈdÿO`”àÉvëö)מuß^ý~œFPP üzØßÚ‰ ¬7ëy³¦1©"±À¾ª+õ«‘ªÿ¾B€;ÇŽ9!¨pùƒ ¾û5ðÝ ©„"¹¥48A¤;<þÑ”þ~Op¶yŸ<ÃäË~/p'h��wËp H¨DdtX�·q§¾8û½–$+�+Cp³>ö¹Êió€Ölé1;C ÄÖ\jc·:AþÊÇØûû=@üØ'ÿé¯]g²•ÉêíµJ§4èé£-ÿ™Ø”þDƒð6³À ÑÇæ'aM?¯ÐmÜ_ ! æ `e¿W´“Ä^Øíç|—»ùœ™eªƒ,Öø.}+jˆî¶=Gùè[n€øÜÐÝ9÷ä£þ_¯þ_¯Ø¶ ¶œCÀÏSÊ=JAÅñRW¯Û}+RQª ×¥`cÏžeŸ’©ïÛ9¯×+.×+r6[ûrTìùæà5OîM ˆ¯bªùr(Õ¢$gw&ýÔbjˆ)±ßºvîëå2�ÿæ0 S»cû —%ÿÎÉö£ŒŒìVÿö%`$flÛ—킼]±msLŒH…T1¢ª¯ÁUIØ\�€î``®&dÊÿÓ ¡ï�P RNq<3!¥&‹& ˜ªU«V­ZµjÕªQ‹°jÕªU«V­ZµjÕ—¢NØ_äéç€w¾D‡õ¯?P Â8•à8gúœ_;h,ªÇ>+/ÛºÜòº1>ÄîÂË;VnNSšz6æE²N$§ÞÐê­ÊUÄ„§W¯�R«§'<½z…§ë®× rÞ¼¯".¸[Ð+5R@êà³�óŠZ*4¹“Ä„œ3¶Ë®Œœ3®×W¸^¯¸^.¸nlÛfBNr²¹g0{FØÞ›3€)í+”¥VH-Ъæ㕘°å Õ+˜"Û°m—Þ>‘ŠZ˼…(ƒó�€ &B¥Š”SÿÚdƒjsBÞ²Ål )]`6üÒçc#5Ø6^QKBe#D‚3yóî}œXÿ7‚D/J�€Ñˆ)Û¸mØÖV­ZµjÕªU«Nµ«V­ZµjÕªU«V} J´BñBuÌ�Ïö¾MÈK® <²S´ƒ÷t»bÏ¡vÎ1Šz–éE·ä.€%‹·€C®2ƺÍÞy¨t]7ì Sk?Ý7¼ƒÍÍ&—˜<ê`¨æÈÁKu •=�]"Þ‰äk'9PWt3ŒíívürŸbú•wð¿�7çÀ¿¾%pœ48ÄhσnvÐÁ ¡%=?º.ôg=FlÌú8¥ú þ¼0_OÂé.µkÕÞ�—a¡¯}å|ý«ZÀœ ÅUéo~ ÍÁÏŒîÿiWé‚ÀˆÊgÇëZÚÅ1Òå•“ ´Ï±>&rÐ徇ÄB×ÁEͺ?±_BíÊl Ja2¬½Gnð@HØTŽW&³õ©Bø)jÿËo¶JSÜñûH—qÐÝÜì}•ñÀŽé6r�âv’…àEð¿ f"@òÛqZv<xWÿצìä�è²Q¿cÄÔÉ…cΕoÄñ¾(hQ"uÝñ\/.ÎþÖÓ}&‰èËÝõßÈŒ‰“Cüˆm„Z*Ê®ÀÅ9*çH QÌfóŸˆüOìÊwˆ$w°˜‚ÖY Ã¹�d¬IÚÖÕ¶¹4—¯çÔÁ~�ÞH›ÝŸí²ËkÛpÚhcN u'2r eç·ø\##0U šó‰€¶oŒ)écô3_ocjvêmë6÷'™¸�ªÒ¤Þ¿_�é´ÞÃí Šæ×ê´çÒø7 Š[³¯Eâªr'“¹7T�°[×w'€3ñ‹ÆÒ€ÐÁq§÷öÏä¬.‰wǠІöûFȃ/í7wö.o!¦�î‰öèƒ÷ßGÎ.×Kÿ·Ë¥g—£8ݬå�ÀÚíç™KP´ j= ”"U$f\. llù‚÷^=áéÉ”ÿiËÈéí*tsÛk�Zm_�å”R±—£«Ú™9o¸B‘s¶Ÿ�ÀD¨"8ö£“ "ØÁ Ž)'ÿ9™KAb À­ù9%H²ø¥”-ê }¥ÌÔgQê‘̃B|ÿþ ¦'w HlïÕãD!îpBì»Q'HwqXµjÕªU«V­Z5×"¬ZµjÕªU«V­Zõ%¨l;ã¿ß˜×ŸDêA•ÝTÖþáê¬~œY]±ØÁBÏ5¿³‡s P§†’+‰Ãµ†¯p=fÉÛù£§Ï�È>”ÿ"F`%'–ŽhÕ¡På®’ àGËxWE¢¬Ýù Øq„<þ½)Öjdâ‹è%0›î•Ãs{„~„\é&Âfõ zt ÆÀÿ&¬§5ÄäqhÆ<¢ÐïqTý½°N‡ò¼ÙóO"‡gÛâ›-¿C‡Dá¼ÅvüÙr»_ÅÉIØÝÚ¹hVøGø·äÍ7|Pº IC>:Í–=€$jÇ�PE³ÊS&”ùÀí²›m29’Ý�á#Ž~Rœv'ò Zž¬zÛ1zTAG1À#¡2  ˜‚bòÎS ØQÃçÏ ÌêÎx¢³ÙsŒŒIìÙæàcLÕ�ÁsŒw'ÐJ0å¶©ù#ˆ~�W¥÷»ã‰)­™É”ÿ}-wç ÊY�™ ž&PEìÓ®=LÕ|ãÊ_þ.‡}mÜÿ˜þî‚âd!&íI }=�{ÛÝ~«=7^ÃÞH!ê„NsDÃ?m�lD‰‰°Ð‰7ú�$F0KwÑ`»Þ÷ Bßýª;Ï`8ïÈ fÝùºPïÇ9Ô;ˆÔSÂû…»ý;œP1@ý{Ră{ÎôWï½g v·©OœzN¼MgSˆ—Z±ßn¨Ž7U}SÂsXÓz€VH° Ê)#g{Ÿ•sÆõéŠäªA9*J=p»Ýp»íØo7ìû�ZGž}Œ ð³õسÐ/ö:w¸\/Hœ�ó†�7pbïóbB-R¥ŽRpì{w0ÀC¾äÞX�ò @ˆ(ªÌnÍE�9!sî‘ÉïuÉ‚ëõŠcßQké9ÙõæÍú6^Ë|ÿÙZÒRw�N¤*¨É|쇄ÔÇa›kÀ#=¬ZµjÕªU«V­ò� V¬ZµjÕªU«V­Zõ%¯èU‹NJ@"ä0tù÷$€»Ÿèt¼·LåÉ¥w�ßr€þŸÿ ¬nãtµÿÞÒ† ¸ú¸g¨Kÿa€~Šì„úƒÿ§?fÿ ›³@Ú0¹@¨šŠ¿kAyÏCÕ>H§yÌN•~Þì TZ„…Øõè’Z¦aåÞ~—èdIîöò¢ Ë7P‘­HÑÎ_` êd®à'oCÁð®'�ˆçÜådHØOཿ†(º °œX#:ôÅôcU…v@ßmü5ºøu£éŒí8¶N€ž‚f9ØÈ‡éaJT¦ý`uA5‚G7Nˆî =#eÌå4ˆçL;vQê÷†ñ%à;Wüòw·y ËÍL@‹n$ P��Sf·;÷ÌWϾYÒøOÝYQnÃÖ4$MÓ°<ävB�«÷p-Àþ²i™n…±¿QXÃ:- ÞÇ:|rÚ{ƒy_|a�׳“Êéü½ŸGŽ ]íßìüÍJßb,ªTÔZPŽÇ~`ßwÜöÝTꜰm²ƒé Sï—©f1oªx' ¤fÁoJx&‹b(GE-‚Rw(U2Rˆo!1²ÓgðØ1iÕªU«V­Zµêwv-ÀªU«V­ZµjÕªU_‚jØ ƒ‰OÁªQejˆG`sÖëu¼C‡-|?Jtð´ã!¢0€®Ž÷ ¢‡¦Å³­°+äýƒ|ƒˆÅéM…Î rµµ„k j؟苲ó¦‚yÈM¡ØH@¢Ã}b$¶ký˜‰Ü® ½OîcšãÀDp…³BO–ÔÃò»/ š¥öɆ™îfº25 ÇsF;Xx/çWÌ×ód PóßnpW|÷Dë—Ÿÿéo f¼ %$uUpSwUÀ}n8šØíAº[¿ûwÂy XçíjêjW:�lÏ#n:‚ü-çøÎ)@FÚzQ‚«„Ðʪë¦îðP-Û[«ßw<òÖÐKÞv�Y¨KS÷;Ð}ù¦[å+ª[º§î> ö·xO?B¥õYä#8Ü^Â×ÙúŸèÞ/÷tt„?lQ uô_­Þ8Ù"8/ÈDm$*¤À¯N�ÃÇÄí¥Ul¼¢ÕÄÛ@¥F†hãH˜nª»lx²5Óe�—ùp®‹ê¼nÆ{àð{_�|1%|r�½þ�UB!]¡-\Þ'±oûMÍ£]–Ûb¢²?õßoãžiÏí- €ƒ3G�Àøºo&hç:À¼‚N´ æneï‹îýmZ£AÈ^°o·îÈ߀o~,aÍ”0Äc?ˆ‘)ý¹¾òê™gׇ|Ò‰d»Á²i#½óø€N º£sC/í¬}¦Å¬wD' ±/hp·ÐNh;›^Z~õaÌ8Cs ÂÉÍ`vÍ|%ì¾µ�÷âžw_ÍJŸxØÁK5Eü~Ø÷žo7ÜžŸ; ” ×ëeÜÖlÀ´HEuÿ*@bFN„D¦~çœ\Eo¶ÿ¥ìeû oÞ¼Áíùûí†ã8:ñ2öCSü›ýÿÇEµ J©æBPÅx3LH‰‘rBNF®¦Ìo`¸ˆ Öj®D)u—‚”.— �K°öÚõ×Rq#IXœ@íï»K€Jî1 e;¦ˆ¸3îÜ€Jé¯í_¢ôçÄ}¸·ŽZêp`ê.9D=,ÀªU«V­ZµjÕ\‹°jÕªU«V­ZµjÕ—¢Úå2}€ÕånÙÕgŒiþŸ& ã–wÜUU]]5”ª:)üfe& ¦n7l×á ƒªY£wÅ{ƒ©** lÇõœsb«}@-\µ<ãa<÷EÉœíjbé`NYÆÍ…€ºÌwöç—pÞ¨Zë`�3R·ó™º±�çŽ6ÿýúÐÁ€!3 ÖÿÁ¢'Èÿee§N×?~=È"3æ©Áuá¥Üæû?µùÓ4šüÈ‘â?ýÌO}Íê]ªÙ}×ã»Ã¦]j?_‚º¢¸å—w¹=&&€á½î}’¯‚²YŸßá^ øOÞ·nŸN1S¾Í uÃXýtì!¾'ðˆŸˆ*PÙI' ªÍ‰€†òÉ@E·‚·qÌv}×O àt§‚ªb—p—¹¤Í >Ûb$¿¾:_3دÑ@¦›ªãÍ穎cHíkîÇý©`»&Þaûš¡\üu®6÷9-"Añn1ým@Êî2°ØÎfç߸Ý;izôJp è÷�镹vhñ~)@½�øøi$%T †8Ç$ÌÙè.¡à¿ ¢_²ÛMmj|ó}y`E¯!ê¤ØÈ&±$ªÔ#c¢%¿ºsÊ0®%' µ}´ŸÜ:¼;®¶Á¥@éžÐÔé „ƒ¸…‘íF>¹ÿã G­@Ißõ¢_�ü;—!ìc˜¯ë]˜mwŠä¿£ ‚Û~ëàzrœœ()RQŽûí†Û¾(ïöø9›‚>å„, Ø&W¨+¤V”jÙóH@b§º�¿)î­EUªý‚íÿoþÅ\HrJÃéNXÐS”a(ۙ浠/Qí}÷5Ê i"´¾odNŒœ3¶ËÛõ‚¼e¯fÊÿ}/¸í7³ó—A–áðNÄ܈€ÄÙ— s–‡»3#§ÜçhAé¯7ò€õ-s²¹©ƒ¼oÑGÑ}¬ÝÅ Ç­ÿ*¬ZµjÕªU«V…Z€U«V­ZµjÕªU«¾eÙ¬¢ñs½÷,n¦ÂÍnþ�Ÿ®‡‡ôŽ'`†¦´ƒQ]Ú-¦£Ú�z°z^º°ø×F#%°TƒyFÄ€~z‡>÷s¡6»Úq­âŸ›ËÀ�ýÚ˜LÙ©wè ug·çUxp 0¹B¼lÄ š²‹ÏžüÁBqlOþ`Mô`œó NçB¢;ñ"�FDê½e3�r úÍ¡ οYÕÿ_ìCú÷ß¿â“�Ÿ rرØ]Ž_wE}õ9(CÙÞê<©£…š@?€Z½SÀ' €™á†á>Á¬Ô²Ë dï³£†¸•Y¼Üú^o‚ݼ“ˆ£} Õ‰Õˆ Ê®Z> ºw‘0ôôm ý’q?ü–ÿÖ'Q™ê^j{Ks`ôÕ8,ÝôH(ßÝh¾iö‡éq:¿¤sŸ5"Uô—ÁÝNŒ`ïd3 Ñtç £§€î мwÂZMÔˆ';�S!58œ�+zîN¸ª)‚ç-wœÞYÑŒ6¿~ýºƒß)e³ÌwP¸¦þ?<à8ä©òH-"¨ªs Ç)’‡'˜“ Ýq ”‚Zk?iG$ãfÕº�þ¦ÖÏ)as«~êƒÚ1Jñói½™-Ž`Û.ÈÛ iOs2!§„|Ù°]6\¶ RJ¶þÁ¾x~~Æóí†r?¦Å©„ÊðmW�ÍæŒ„…¬“Ô®°†ZœP!Ò ÍÑŠ`dOîïûª»0ˆ4™ÑWɉ�h@÷ÖA«V­ZµjÕªU¿ãkV­ZµjÕªU«V­úTWNÉ ŸqFü€ˆ`¯~áé³IµNJC …½ötøúŠ 3‘.ÕžÍ<ëžCkÞJ:y¿NÕjØPvÓÉêþAã|�j{˪¥IÖ.ªžs+–aËŒD`§qŽ~Wâ·¡Å-Â[<“)ßú¹´ùÚ�fñÏwƒ:¢ z'ßµo¸1L.ÓÜh}ŽwìU/cV¤h¥8Ù¨OǪØÉR:L6º;m˜/§æý°îÏ^?òµ Ø�ÄŠª@yOªªÕÀ°ÒÀòätq.°<û¤ èD.Þi3°0Úñ)X§ëˆ¸0‰B|Â7%q¯¨ŸÜ(g°¶¦æj`ƨ Mb@7]<`ܵÂïÁÔóVq«v 5¸«ÙM©î××,ö#HÍMaß›0ðtšå ÄW €ÜÇК¤níùèõC§ P²<ùt…ðLO tA'è”gTÝAõà5à×D�r‚Ö‚ P†|±µX"aÜ;=†¤E8ø¯ˆ"·@>egryw îÀó ÷´¿•c·9§Òwç�:æK$òP³Z¸„9Ë.†( d ùw2õ?÷ŸèßTÿéÁÊv¶æ—é[Ï·è(óv²ZÈ@þ*·ë¡Ìßû¸ù1e´7]?î·eëúo$a�›/3&?Ì‹ôcòÌ¢°Óa›S‹D‹ýŒ‹ ·º?@wÀ8�œiztLàÝh#Vè¼vϱ2­á}ç¤y!oQ==b†6÷€þƒèƒ‡ïBôáÑÞùô°÷©*>ûôS\.ämÃepe°gÛÇÞmø�cG­Ã)!猼mžUŸÀœ:ANO{p¿Êiú8Ù{ &ƒP'—ý¶ôÝÆ_ÉTúÛ—ËÛes€ÛŒõ°÷‚\*.Û†”íÞeflÜß°ç 98T;PžrÂeÛp½\�³%´*Žzà¶ßðæù nÏ7Wæ3¶œÁ‰ lï±j©�$�] Y‘4!Q2 ¾T”ZÌ‘§¿Ÿ(¾V�aØq쪔@Ä=V€9MïD*ªÊadŠæ^ ìNŒ$iýgaÕªU«V­ZµjþŸÕªU«V­ZµjÕªU«þY/‘ µ¼f"Ò—%Ô„}k BÍ®MÔñÁ¿%:‚�ÿÀ=i¨ë›jRZv=È-hxÍŒÊÔóoµÇ À‰ö¡°‚$8K·&žò�øÎ$a¢“‹ËÄ-jè¸.$SÌ ‚Z^*R�„�j¬s²Üáê–ï®v–ðË£�™Ð„Ù!`XOÓ,ºÆÜ. Dµê##ñáPЀ)Næ˜Iñõ„ý0¬áç×5bÀ;ëOy\òµ¯½?,Ã4eªÝ._õ¹Üúÿ¤@aiŠzoeýìH†ä€›«šsb(º•ÇùiŽ ¾þ?kS×ÓèãÀöëð8À¬UNyà é#âJjÌ«8ð_í¿úZe¨g´³†“r;øsVÛðV… "Q¸¥�óÞ^'øÌd€8ŠÎÖ0"d°‹ÂËÔ€|ñ>a”Áœ�ôä÷þœžÂbç6ÿ5¡f;e»ÔâÊxÇÀ¹›¡7{ìŽÈlú4Ûø=à ÈÃçúeñ 7ŵ7ÜÑb$ªGÌ,³gkw9Þ §W!ò‚ò“ŠŒ¹ìsrû€Ï†ò¿Ùú7B€ÿ�àOú›Û€;H´˜�‰À! ß;·ºKC#d¤‹ïɸ Äfÿ_à.’¥‚‰mµ9+>‡œœ%ÑývÙÍäëâ’{yisl«j´Á?�]t5éV'¸[Ãi²Ö§iË£uD¦µBïfI µM*õñ :­ôHžþS� ïñYùßC£McêÍ{�žYzΈï'Ú÷{r@Ìxûêÿ˜/fûß§Ÿ~ŠW¯^ár¹@ª o‰ížØwË´¿Ýv”âû?3¶mÃårÅÓõjä�¼ù.}Ïfm„ÂÖ.�òëÛþÌ)ƒSFf»Êløcwq'MÆVQw!`6ƒËvÅÓÓ׫}¥”•î( ‡�ú"‚‹däíNŒ-o¸^®Ø/7l—Ç‘;�™‘™±¥Í¬ó� QjÁ¾ïx~¾áÍ›g<¿yUõçTó úû!©æj°Õ 5Y ÏQ”cGqeªÃ…á(e7†ý¸¡ÖŠÄÜ ‹›dÔº�ÓØ—UàqÞî³SB�€¿o¤�U«V­ZµjÕªUV‹°jÕªU«V­ZµjÕ— jSŸCqÆÌœ½ù¦4™Éã^Çß^êÙ·þzœ-ƒ»ú°�ÿh¯i@4Aí‹üp5apÛÉ�1PÔ�õI1ïy°HaìñÐsrÉx§Æ¢ƒÓpûWèsˆ`}ËRn×`Ž æR ž¹ÛÁ´Ü[™»ìYËB†q5ÔÉ…©ÔÔœ½rºÞ`�Ðí =Ý ƒ{ðø®“Õò}Mæ×Ñõ!ô‘"‚ýñ"Ïmˆ¸M€”ôe*À„k>º¶——½~äk`ÿt0– àWMž!O6–DÁ%@O@Ä9`¥Ú7âkçÕ0«á¬"nSï�áD‚·ˆroîâ׌l�ÙÉ N’°fðèG&¥ÇzØkUeŠGHíš9Að2 Êÿ2¹Kˆ”y. Ä`ÈœçN°�óÐûàíCHzÌÿ8£]ÃèMŠT *‘ÃÕg©P-æ�Ð KFô¹·UiJòP]ÍÝ^˜á_ó`ýb‚V³î–ó):Ï•¶ÆÁÉÝ:Ù߯’wC5;ˆ>VÉsÐÙ�{ñ) OÙÿ¦äßl>R³ýw ç1O‰}àÙ-¤E( YóÇ8…è®}œ3¨=·E ÷ûMÚù´¢38&‚‰„s„¨17†û8åãWÿäÓ4¯j4¯qóÈÍcHÌ –�Ž»4�Ób7ƒ”3F¾qj,Šì¤Ç |þ�ÖÕæ 0»¼l#Ôúc²òk = €9'x»{†ÉMs B‹€;£tBÅg £ªxóæ�ucϩߺšÿ8vÜö½“ÿ,& áz}Â{ï½ÂÓÓ+l— DÔóéÕã–ƒôØÚ!ê–ô5Û°É¿\2rbp!H­Èû )ñDÜU¤yzLï!w&¸d\/<]/ØrˆP«áûq˜€èD„¼¡Ûà_ê×ã ûnέMä,†öþ¦J�d üó ·çgÜžŸ±ï{Ÿ#U¶Õä„{UÇ]­ßʱc?ÌæRN�`äËS U'�*JÎȹôçGG£ó}�¸9.X[ªˆ;þ$H'B­ZµjÕªU«V­`ÕªU«V­ZµjÕª/IͲÓG�xßíCöGz9·‘o`¢ÒÕ$‹ô@ý=�‘€;,Zg%:üüÔrb Ú#n*·ðWˆŸ?º œÈ M=€Oû`˜ W½³v˜J¤»–s³ÚeSð·sˆšªMTP«x<�Œn6üþø!ÄM®”ÑÇâ®"sD‘æÈS''ZôD¦ý¼À ÄÇP#Nºûøx}]t|‚òƒõ±ÎÈ/̺ùå_à—ï~Nh@WŠžê;ßüÀ;£)Ž“}“õ7…~³�hêzïO U€ Ÿþ²ÿއuº$hõóHÌ77HR9¨àÁ@upßc0’:y �k ‘·N<€U‹»7ذò�”#3SÂÉ4ö}€ÆPn)?Yš*ž‚Wг·[|ašÇ"ÄÄävýâªêì}Þú´žV$AÕêD yîþú¨ŽŠnaoÅìþ‘?òÇ¿gÊÿÞŸ®&÷èÕÝŽ-èè UŸÍN¾¾ä¨;TJ' Iá>#½WÿùÑÊ|vgðù[»ÿ;‚ÍÆìv^Û¦{�NK7C9D"¨Ç€®þt÷ésÏUþHŸ�ÑTýœÚc'€œ�ÆÁïìýÕ5¦ÅØaw¨Qquÿ‰È1�ó~,iÓ-£ê[ßÐÙ-"öI=-r"¸Ç1ôé4ñ>r@äSÐ Ë“ž9W4Áä8?TœRú½øBTÍ뻞÷_êpŠ$Òèèÿ¢Í|#´ս̷w»<š·ùÇBg+¡³Ỵ̗́ØþÞ>êï5èÔ/í/ñTõýR Žã°{Ä#{l‰”Z±ßn(¥@~¹àr¹â½÷^áÕ«÷p½^ºš¾ªZÔO5•û´©ö¬{æ‚$FK\/^½z¶e”£€ìûޔߨVâ׃œ;xODHÉŽ!Ù€p� 1#'FÞ,ž mFd(EqÔÚc ˜œW4BFÒÁ±¸].¸\¯Ý:_ÅÞ×Üö·ç›“�€cßMùÿ|þï8J!%w bE<¿U@Š­~µÜnnûsïû”’Eprâˆ�öíýM©‚ZkKJÈizÔ˜Ò–�œ¸ÑH¤mÚ•Rq6¶µ–õ_…U«V­ZµjÕªP‹°jÕªU«V­ZµjÕ— ´[ÂG+àûœh˜È?X7‹Ù 2÷ëé£þ³µ«ƒŽÎqåí þ�ÿxél¬A­Øó‡]'bªÒa�{:O‡ýßp‰S_i·¹Ÿ3xÛ‡ÇÉ?lnJE…¸½n­RKï¿Þwœ´Nª¢R$¥þA71�*ƒ”Ó`›¬w…¹ÿ4X=‡ç˜ïæÌé;Q‹'w{`q çE @žq�ñoÄŸ‡=ôKÎ…xðào÷ÏýÎ�¾ïÛ¬åÈE»eyÝÉÁrb.®¾wÅt èþ©=Ÿ“»2èÂÀQ�Þ´×�+õÛýÀ<·[Wf€3H¸“º�=Ô¯M¨ìt dÀA\Ÿž?&AÔ(G²Ç )ØãWË©Kýº$¨‚YIˆ¤ ïàA˜@ÅÚ+'½úkI£=–FÜ"Ô/BæT æbàÿÇÀö ˜_é�.N ʼn‡ ÏËÔg@oî—7ÐòP>·Çz²z@Êàp§ˆv¿½‹¸ò–ü ya:ÎÁãû¸E“Ø ;Öï?d‘g€2(o}.ž«ý©e„o# ý½_cZlWò›› @â^¡]u¯€¯>¶2\&ô¬�W?·ŒùÊ@+ˆ’½V€žÍ­�R˜?-Oa�HÌ¡¥b"èˆÓ +€×Æ ’Ãn�÷7 )çõh¶¸Á8˜Üs¢}½FF9I'ù/‰í>Ž@žëN:äœ` <×ÑOä×Úˆí¼":\�¨ù9ЩGÂʯ�–õ°vܹÀ´uM�̤ó{šC:#1ÏW2uÝüç-€PeJ#3—ôtÍêI�ÅîꔪôÌcrËXrÕ¿†=­Š vðäÍ�¶MÍZ¼9 Ê20bšó¼;�‡ªë$µ|gÃu[¦vT̶ìou½ˆ£O˜ŒÏ‹S ´ãÑq`düžرæƒE—m<.éÑq¦ |÷lÛS¾õ£ï·ÁP=#Þ£줔 Èf ¥{Já>à¿ ù›bÚÏÏ$AX‚8‰#pSF3 �y:?˜hZ““$9"(–ÇN©ãšÊaŒÐ®1ç�DjíFpRPC4]l.R¼ÝÅ@tòh ó2æÏ7 U‚D˜ý†jà>Ÿ¨+mâ�Ü­+M�-Ñž] ŽyYCxU'§$$NP~òG@þ¼½ÐÀ0»õ¿*dÿÊçÿ/àÍ/C�¿�Ä|u2G#,jŠX»i+ˆLÒÓï†õÿq°s`Ñ�ÿè<>勜 ì�ÛZ5#*Á¹AOŠ~ÑáìÐ¥äõñúƒ(7÷9ÎQ`íR€wsj€ÇHŒhq,~| „Ò;Â_|ßx"ê|†÷®Í?Pí÷Ä»èI:­³t²î÷yá®74ÅñL»ùDÀš×âæö\ßOÇvÙ�×MBˆ �£Ú{†Þ¶Õ]O˜¾Ž!<“cî¨'•ÿ°8Í´FrÓÈ ³{Eûþ1“+t:î}mÛÖÁöR j5 ¿–Òûàr½"ç O×+^½÷.Û†”²¿P·¨/ ¡§ÀˆÀbü>`NÈ[ÆõzAJŒÛífŠvb»KA)ۦتôkjîG"~Svù"ªŠ ÕjÑõ@­¥V¤džÄ¡’:ÒO¦¤ìjnñ9®CèLd'çäF@—/öZ.ì`=s°C�=W»  í0úEwˆ€XÿH“1K;oÁ@Okh$ÚÚU­ -€=Z»G…ÇÏ“6 ™í¿�ÿï�ùÚmìeÿM”ßú ¯ ³Í<Æw9 hL¯@|�È?A=¾ˆ˜C„ÖÞΆ{Ó}ˆ»«ïïQ\‰380Df`ÓÚI“ƒIT�ëè�þ‡~e§¾µ€ò929´ùI6Žœâ‹[‹ô³]�­ûûÅ ½“j"a ýþ³ßŸ£ x|· ¿‡6€^òÚU~tuBGp¡hã,Þþ�Lr?:”ð߆⓫Œ½Í× 1*qS�Ä2 Kà½=þ9Ne˜q4BTÔ»·ÛçnV5ò”U=ÑZ_HL{f‹˜¡G¯³}©gËw‡žHÔ{ùÑæÅë8E4‚CŒ=¸{jg¾ø.pµ9uµ)å8Pj±%Ýÿž7Å·œøïÎ?ž«*ˆÉoû_¤}û%Ÿ3¦d¯(R ¤¯e¼‰ðO90Ÿ3ˆ¥èÄ‹¤š•¿Â"‰ NP”Š£Ô"8¸ö˜Sþûc(ˆrÞpyºvKþr@ e/�C¬]Œ~îFa¶ëkD+©aé·ûŠúû0@z¿‹Ç 0„Å×Bîmß6E©¹däRQ©B|ÜlépWË9©!wRBP b‘ožoxóúõ"¬ZµjÕªU«V�jV­ZµjÕªU«V­ú“�º&~ YÂ-«¾Õƒ—œ�'ºûéœ=üèÅQÉœºÒ0X”‹t ÄTùøÆˆèLWŒ 5œ¶)&EÔ°]5û\Šöýh„„v\ûdÙì£ÕÁ#hPþ›:¯Å&xTùÇÞÍî8à¬N>àsôì”о P‰† Y©Ûß�­»´vÇa¡®.ùÐÓªG~@Ì|Ö‰2&ÞÖ÷±8Ù6A‘ÿîúÑo|2ð €®ÈZQ‘l5•x²|vÒæy�BrwH¦¬÷ìárƒÀtvâSìF˜|‰Âï¸4úì« JÍöžÝ1¿Y”Ûu¨É,Ö¹9d5ÏOé æv•sr»üàHà÷8›÷94²Dí7#5BIŸ«Újmg{s �…âÂä€/õù;©É› �†\÷ð6p/ŸtËzV~È‚ó@ï›òý¿ŽúÝ¿†{Ïý˜Q͘nÚÀï}ty·ïÿRÏ«§~ j#¢µÀ'àý…õöñã±Fvwl=-£Ýa�¦¦HWx·Øwyaä²fà?o6oÈæ>ubÈy�h`¾5#htÏz‰3ùEââE}\¢Ý¢6àÁžâ,”ѱ”€ô!Pw·:ðˆ~‚ÖÛ¸.Ëy%ñq H´@· ôØmºë²�¯ŠsØý3ÅÉ41‚SÌiO¥8Æt·üŸX|”î€t½#\�¯ó!þÞÓ<ÆzEL#º£EÌD;ÿSìÎ[KgrX#¼�‰oSŸ¢ÎŽíÞÔ¹‹îÛBÎm®ϼoÄÀ¶,Z~|Ñ?t?Ü) =÷ÒÞ+0÷Ø$»wì^i—Z¥â¸íx~~ƒ×Ÿ¿¶nÅívÃáñºåÿõzÁõrq;ûl/Fª¥ôÈ‚m˽/™ZJŠ+õ=¦ÀÈf{˜¹“@¾d¼Ò'01¶mñ(¥â8Š“J'b¸ž°u‚Ä9Û}*Upà@‘bnœú{ UsN©o�}«ð¸‚’ ¶­¢J…î j„~xã¹ë‡ºˆ9I)8|ìŽý†}ßqìÇúϪU«V­ZµjU¨EXµjÕªU«V­ZµêKP³ZþQ¹m®[íO¹ºwvÃ&‡£w•ð; ÿ¢ê�& *\løU;WPX6  ŸóD"@p`Äì�åÎf^{µŠ+±ƒírk;eu°BÝæ·Víq­ŸÚ‡ÿ=�{’ä‡ï“›öÈ:ÖIÙ›7ÄÎhëÔAŒ;J‡!µáró3ô º·�Þ].uüê­Ò»¹öb¢´�;E•3^|þý_^fÌqÖáø'äçǾùᘓnUŒòÚÐpº¸ šÀf…Ñâ–ê |÷¯Ä„6 uÌ í:¬Ïïäá›TÎþ8€¹æ‡Å0ˆ*ì jqýäèê9èªûgÑðŸ’Ûý{¦º¨�ÿ“Z�|Mhv÷­ív/ˆU8wwˆ³¥Ç�23�•Ü-ë�q‡pv±Øóàç¯Ç<ÒMMÎ#>¡ò|yìŠv#ùqËoþïP?ý»ÞÆôÂy# ÇF€ü.ÿn¿õ÷Qk§õË0;oœ@ÇwYÿ�}̺š×Û0áå…ûE<($Mw°G Œ/PÊçÞ-ÖÄçiX1¬ôµ‘bèÝÚúÑ}î½-‘¸‚ü˜¸Ð¼s‚ND™ö<õØ>Ê÷§X ¤ p”À˜ðù(0r‚V›_â..}l|=× Îå»îÀa_¿ÒN^š"SÚ�ö´iì¢2þÑîH=>cJ x´v¼eáT�ÁþÓêgÉÿ�lÖS´¯íÍ�‡|O�®cZnõ­ëú‹�$Šý9z+^{¼¶G(ÿD4;�¤-SœØû$!%ñüù¡jÏÛÖAxf¶««õK5%½Hu0Üž—ó†¼e#$) *9P=b@a ýmßñúó×Èœ�H Š7o^ãÍ›7¨ÅìðMQÏxzzÂõzÅå²MŽ Ä?ŽÃoUkkêNC}o¶ùDJ)8ö·çç¡¢w²Å–ÒÓ¶í‚r}Âmßq{ó à�‘Üm 9Yßx»/rN JÖî" J(î¢Ä‰�ˆmewç8©3qˆ€"$Á]à 9!ˆ‹T0€Rêx_”(j´GìeïñEûóî±�ô!/:`¬ZµjÕªU«VýN­EXµjÕªU«V­ZµêËUD/IÄIO¨zxZ‡?Z¾}°ù�™÷SPò ì¥/  œ€k=ˆ€5‚ q<§Ÿ�Df‚*fۮϫžh ÌÞ¬aO-JîàyËþÁys `¦ üwœNq@]�l�ûÝ0Uõ¬jÑ“¢&cÐ�ÂÒÉ-ZƒJŸ‚ÈÒUþá°ýç–MM˜]4†1«›ç“r³]eŽâyâ\›í¯_˜ˆ�æÄyfS�†gçÌøðƒf ÞúœQë³çÃoÀ#9 ð:‘ÉìôE>³×$Œ×€t ¬¾» ñ†‹€qS`�'4j� wy£G4ÕµŸ“`°ÕÀ[MP*ƒ8C´Ž¬÷êài�ùÙM)-nãßúÁUàf) ((Ǩˆ@Äe#DÅG±Ïäˆh_}¼™¢«ÊÝ_�”2˜žÌ>eD²Aù­õÓ¿�¡0?OÊÓï&нOˆ.¸~ôxý½ÿÌ챫E�$ÌEÐóÄÃBÚûB^Xxå¥ù¡q‘áú–Lsí®r/‹erßÀpÙ?óC T““L8�ÿ>�Ã�¿úx®ÙX÷ýËç1`Ìíw��Á‘83,î)¿‚R pˆŠès)ŽÃø›hˆ@p/(´}=¾;,Å øê{ú3ûwO­—øÔ ct2˜Ex÷zÙú}š{Ô÷‡&¸×3ÁìÅû!ÞÎÂ�…#|ÚÜ{qÉ�ÏÄ­FÚ;(B&§èÝ^@ösÇy›OCÊ©Gýäœ;À½m.×+¶m'Fu·ŸfýßÈíµÛå‚-glÛœœP J´**ªÓ ÒÞ°9íÇØo7ÜžŸ; Ÿ· ¶œp½^ñôô„œ³«ù ø¿=?›kÀ±#qrÒ@ÂeÛp}º¢”ŠËó-XóÿÙû›_K–-? û­™{ïSuïûèO‘i$E[²à� Ë€Ë#�<ÐØ€þDO<’ËË6AC¶DRÙün²ÝÝì÷yoÕ9;3b- ÖŠˆ¹sŸª×Ö€ŽõP¯Ní“;32"22oþ¾v¨Š}wÛ�Ò‚"â®IõY&aáË”%ƒ‰¡¢Ø÷D›Ÿ“õ�²6¢ÂzYq½\‘’1¡ŠXÿ‘N¦$xŒ’‘ž,jA,:öÜ•ûðY?g‚ƒôŠ”Ø\ôbî K1ò”† R¨šÒŸö Š‚�¬?sÉØîw¼½½bßvw€²1Ÿ5kÖ¬Y³fÍšÕk>Íš5kÖ¬Y³fÍšõ¨txTŠ_Ø·œùè€1N·½(®Û�–ü§ ùšÖÆz<ñ„§Çs@5j–mÂZûˆA¬F*h çHÍ�ºUM/nÓ/áû¶nê5¶àߪ*eh“å=³A»ìªOu ÑÄIÝež¸��F%gvô˜¿=vÒ#PÒ|¬í_zphK´gÇc˜õ;Ã=R B ƒ~�Ùÿ1ÿ\0úüÈæiýúËËÕmí+è¼Xî9¤z¾8|òÕÜù6Z¾MB&ów®ü¯à¥Ë ”^¥] Y]8ñé1và¤ôk2›¿2×ùì0Dg{m±¢ÚÆdp�Ð/7)îëzY,Ã\ ˆèÍW4TRÐÀls|°Ï8…Ž È®æ_£æÛÛ�'`]�õJÉ3Õã �_�ä ­nÇ_¿“êv®º—j¥ÎA}°¬§º’;ºú^ÂØ ôäÔ/\JªghÞ©_÷z˜ƒDÁÀû‰}¤(`ûw»nÙ‰7§2`/#_Øñs@®½=� ˆ6Û�n@6¢6”ýýMVËq2y,Š‘J³�_/�Öòö†œ€¤W²pµ_ÇÃì—‡ôy}¶T¶D†à@!m ÝåAƸꌥþ¹æXÈizÿ¸ý´GI45|�Sé0> ƒSFèë|l„ÿ># ǼÈ–6¯ˆÎ>ØÔú¼|„CY:ZßÈ;2’È4'«SéÄ$ZúMöõÛõ°üºezýy¸¦Ñ©Z“@O¦<�g:Jë�kšžßÜU­Ï‚@¼Ks™yrï=‹ ÒýÞnŠÔ¨‚/¸QÄ z\®õá1ä�«²ߺ@LÑч…N*¨1G㚣P”’A¼b @µÛ}šÉ×ýjû_Ji€zÜ�–Ôì÷U D,. gÿ7G¤58¢äb.y7{~‹±g”-PÏ;;€ýöö†ûÝTëº8‘aÅõzÃËí²ZTÀÛ}ÃýíŽ=”lÇ*¥`ßv¨*–”ÀÂPw›!Z,Ò¤¹Õg“@bd2ðÜãt–eÅe½`] L§�Í) [lB);J‘ø³Ç%ÙRN->‰—Ôú[U¢Á"ÒBÐÄÈ…A9## �0 ¥4Ç…ÝûÛîFŠ(¢ öX�Ëz™ÿ±0kÖ¬Y³fÍšjfÍš5kÖ¬Y³fÍú”régúÅç]uˆ¾·àµ¢(„ïÚ‡}j¿‘@Áaß3€5('Õ�N×üXâµî;€ôõ¥:ˆZf»Ô—Ç"P·ûUÑŽªÝ¿)÷™è¬ÑƒÇ~UOÏ–ˆÝA€Ú¹ôíáüÔísƒº]‹ëØ'}ÔA‘]û›ÎæHÞƒ¥ÿé’>ü*2#@õL ÛÏbhHÝ�“¢�à@g,†§aØý?`S�tX}¾\ì'ƒ%*ÁN¿ÊD}œ9Ùg 8ó¯ �¯jÿËN/î°š"½ú¶cl¶j�} Ø¥w0B€¶ï;p›bFz°Fo.ýç!Ê¡zªŸ»úø|í©`>@-b 4DßrAœ (u‹ƒ¢_0R·ÿ¯Šn‰¶îa¸E�$ý| 0RCôýüÀþÝócÑ™+A�.1ð_ü¯àp�JÆË‡oñË×ׯÅH,ÈÎ9J ˆ<2¼ƒÿ¬í�´srú5Å�NÈ1p�ÏVò0Wê50\r8U¨¼QeOƒbÿHHQÝÏx Ÿ4 ·åGzÒÏc»‰â1«[ãQÏîL2€J/ãýMÄb) Ö0?ÈÈ9* F(ml‘�ìA‹™.ÃÇ‹†$”ÑB_Ï–¹px"MáM�ÀˆÀÿ!#=ðúDb\‘L=:¸ª;Z±£Äê×±3ª‚(¯èJÙaÐ�*ã’‚#‡~!ÂÇAüתèŽ1¸­ûU@wˆ,¿Ê(ßÿC<Ô'Ž qâ�ÌÝ•AÚ¹þC3–e#ç‚uŠiA bœ€¢»æ= 4Ä©8©£Ú[¤ž¶÷NÂ:;§˜ЈCÕ±E6ÉçnµÞkXûsˆyƒKAü«»ÊˆìÏ}p·¨Ñǯº,Ÿ.îZQzç×ÅEj§Û¶œ‚ªÙ] *¸ÉT|wõ`ö¥À%lüྒྷ¼žñד�gÁƒZ_Ã=µÏ…`�ÔèÇÃj»7�€S·?�íâÍŠ<*åèØò칡=;èp_øÆÉ\ ÄÁ3'ƒ/RÃß)¥X„OJX/f�YWWðw�|ÏÙ’%‚ú?JÉÈ¥ åŒ ¶í¶½5«þ××Wl›Ý3–%a!nœ¤(ˆd»JF¬¤€}Û°ùŸœ{ !qÂe]-2àzÁõjî6ªê„�Í·7`Ÿ†¹B?W‘…bÏûÝŽõúvÇöv7ÂK2·„õ²"­âÛe,FBX„²ìØ÷÷míT\ÑÏFwZØÉŒääÊþ¼éÎÖJ{Qj± •Œa„ ±¸'_ U�’ ¶mÇöf$€mÛU¤%ùv=^aÖ¬Y³fÍš5k–Õ$Ìš5kÖ¬Y³fÍšõ("Â’H�ÎÍïUˆòÀŽÁŠ_^¦!Ÿ7~I ò ‰<±½v�¼æ 7ÛûØfr UÇløÃ9™jOüøÔUzÕ±ÔìgÙ �:\RÁÿú�”\^·EKŸuÀŸ¸xï Fhª¿C¦sûjëýçFæ`³�'ðÉ^þ“ƒˆäRÕšªÐq¯h ®-Ž Žs8LÇüŽÒA¹L†I¥ŠƒÂ_Ã\ –è8ªÿï€N¼ š7îsÜ(9 Æ.‚ÕúŠB'ôPhWœBëA!€ôòê`z0 „Ý.Ýz„‡íºá7`\¢˜=b ´@lµLw?»° ö`å>œ d qÀ�¢í¼|Àë˶û†’û~w2dÞ™EyÏØvs,øü鳓 ¬=‰˲âz½âz½àr¹`I¦ž/E�÷½p2ÅMoØ÷Œmß°ïwð0ØuÎÖ1`îÑ"Ò£‘ÄÆ|' y¿dìyCöþ€ÄõZ'ˆöýìyÇýí ÷í(l .k;¯Y³fÍš5kÖ¬Y½&`Ö¬Y³fÍš5kÖ¬@13T©Ø# 3æèùÅzTôÅ—ùÕ’·Û“ƒ�:¹Ó`�ü.ï`V¢ýÿî˜?¾Î�€9<«b'¢n î xâÅ@ ê–ÿâ'`ý@xê/¦»ØÙ­�ëKjo�‘\!ùucu=,Z@ ªmέ2ÚHµ—‰,ÿYÉÆ‡Qšs~þÞBYÉ2•cTEÂòÒñ¾FÔÑŠNl©D±Ãœ©cHg‘ Ç ñõÔ„ý ð«j|"tÆÂ#‰ÊÖ¨ú—bÜ’a‘‹ñ(æä@‰¡d¬ ¡0/›[€“R‰› t.HÛ�¶ÿ­(“p¸6�gö¾ø!�Gû‡5Y›s zÒýJGÀ“kR¿âr­ ?i'â y/ïì*� H-]€•¼† g—ø©Ù5 Ü�RÛ·åÈ‹ÛîoØ\ ÿv7KüæÊAÕ„ÍŸŒœÀÈÙ¬ú__M}¿ï;TË’�RÂårÁËË n//`"ìÙl 1•P�U‰)%,i�^€e\Ö///¸ÞnX—œÆ^àÄXÒ‚´˜í¾HòçCk˺$¨yß°moøþÓg|úþ{|þü û–Öu_oX× n·n·+–eõóìûN Ë=aM«Å¤ÕœÖ Öõ‚‹G(´<™Í Àž¯ÌM :h#*)J.ÃØ‹#D컑"Jy,S}bb‹GP@жí­Í¥¡fÍš5kÖ¬Y³fõš€Y³fÍš5kÖ¬Y³~e/¤�”øŒÿÔA<t‚Dï{ú¶í|'áå?¹•|Àív5W‚RPrÁÛ~G.5ª$áö"Àæxp½^PJyÜRrò³õ}ª€Ô”5ŒKic^Ǩ:1ä¼Û]-%HêýUãâ\TÑa-e ÏW³fÍš5kÖ¬Y³PßzÌš5kÖ¬Y³fÍš5ëßðêÇÀ£�¨ˆ'Eeá#buß5`ÿÁ°·+ê\×O` }ͳRœt€�+x^_à6ëüpNÚ4¨ŠC!)J‘†·Œ®œvK\bŽ© `¨ê@s�ÖH:E\ž“ºÉ@wh9À>t\óç+Æ>€éÚ”øƒ�XÉ,å#®ú5ðly= ¹Ðm¿Ô#*3¸G4€‘ Ðá™G @ü=Ì?}hãÓiåe‚  W0´ 2ðecöÌû³ë†€¼¡¡mU½¬€�è’¹ƒæ#/®ä÷ö(Û÷ˆƒj¸º¸¹ª)þ«·;B�’àûªƒ’B‡Ös„�»ç tð#ü¾Þ2ö!�|Bª¸Ï nQ 1W]CLÂ3€/ºU´¨ Wf«t>ÔÚ¯;´ì |¶~"ùìŸ~“U@�"žs·Ÿ- u-@)ߦ¨}R˜Ú¹ÚÅŸEŸß*¦5ȉò Óq�oä¦p‰ÅkŸÙ×BçuÒGJx ‰<´?Œ_g!œ_y r²ªÄŸåË‹ÐÓ•I¼Swï+›÷)nÓºÐmÇ•1Išò¿Òf‚À–2�ì2¶û M‹”É:Zåû9ŸÝYéØeg¹ Qtµ¤ÔÿpÉôµøxDôDÐÁÉå7év=Ä<þNc, ½DO¨hú›?ݼû­ª–7lˡ¸^¯¸\V›’=ï‚"‚}ÛñvÃÛë+î÷;î÷ ÷û¶mC)¥‘ïÌÈÿ\–öosBS¹«2˜�tP‰ë²àr¹zâ‡}§”Œâ6ÿõ˜˺ŽÓ&%ìÞ–ÅI �KÁÛÛàdÉûý ß÷ ¯¯¯Ø¶»)åÉÀÿëåŠÛí "†½}Û6¼½Z €ŠX$®—+>¾¼àãÇ�¸Þ®F‚Øv”ì. ÛÝÚ^ rþ€Ëõb/�× n/fžÝá@ÔûÌXRBJæN°¤ä´~¬s*ç‘â–þ%[,C)ÅÆœªÿknF4P¨Å$~¸VfÍš5kÖ¬Y³fMÀ¬Y³fÍš5kÖ¬Y?ˆjJq3<å”Ï,‚©ÿ€åJ?sÖŽ8é;¢Æ¨7�SæCÄêêcW‚‘¢Qr…<*ø·>f2üî¨@„e Ķm1ã¶S à‰YÇZ>n2E¾VÐß-ƵºˆÛš jÃ*¨¦îxàíåþ‚ÚT¼Q±:ð(Þ>8kߣÊ4æSc¦›Úò7›MCN<ûiê®ÝÀµZ¶?)ûj°%jÑSÇq=�PσÕã¾[ž¼ÿŒ‚ÚÃö&Óãd¯yéõ¼’9/ˆXv8Ùé g#8Ð/Áz½9pP*3ÀäsJ´ª™ (5j" ÆîÊnÝ_ Œ@€}ÔmïQ-Ö+ÐNÁÆ�q¶9û�¸’Ÿ£Âýd`õ1NÀùA¥­ÙöUY£7€?ÁTù  @óз“…ŠÎ'ZÄ÷£Rcªú_ü×â Ç]ŸâILݦþPÅÁR>SÛ?�·à Öã&úüâj=0²ŽlÄ<Æ3Äëü8õ�ª~>ùÜç"ñ Ã5úì"~oU:� >V@�ÖHmÁ«k­ªBIüÍ>Åæ�tµû ÷u3w“�}ÿªŠø=5ÂÚã�“ôƒ»£�î–}‹Çèžg`>a$„�Òžâ”ã Z;ulÇÙ>ôèð ú8�ãÌ>þþËw¢aã³ ‰gd 8ª·o¿ù·Û—Ë)¥é“÷Œ·û^?ƶm¸ß ÜΘà¼Ö9æÏªê$FZ©$¨.ŠÙÝsê‘B)!%nôKÎXÖ˺6«zfFZÆy x03ò¾ƒœ`µçŒ··W|ÿ]Âý¾ADðö¶áóçOøüù÷·7s ¸\pq×€ëífë�ˆ©óU ¹8 ÁHrÌ K²í?|xÁ‡°^V”\Úz´ï;¶}Ǿ _JÁù€õzÁ²®àD¸\.�Rx/¢P)öœÅc @åŒe.ƒ;Þ3r8N{ÃÉ­¼-¿FMœ�–DÀeY±¦e Ìš5kÖ¬Y³fͲš€Y³fÍš5kÖ¬Y³~UÕR¢2¾°Ï…ûøû�ßXD£êÜ¿C‡Œc¢1Ã<*Ãe=L•¯jùÑ WjRPd«¶cPUçSUÍ#X »Zý ¨4å¡»a,שéDNè±PE!—Ø­þݪ8k/ëýom.ÔþÛA}?~A;y�`ñÈŒŒžà…£³²öc~#DAŸ¯!÷ú‰�sÜ fXÛБ»¼?GU¿Fûoõéu€¶Ï%Ù¦¨n}_'fTØw£PP¾³»Ôÿ võo¼b’cãzPñÃ{N¦ô¯VýÔ²8ìg2G Ï’èZ}ÇCÜ@¯ê ¹G$HppKuÃøåñêŽë÷V”BmÎk›T‘Ûj¤Qj̆úñªr[=†á´E#ì@~…îwÐÇ}rÕþ>ÊõÕ#(´Yë1r�(»©þµø<¼n2ìÇŒ²Õ®õh‡^€3vÕ30ÿÔúÿÝÙ�¾<[h‡|�0�iésò�¾àÑ&ÇÏNWóx�œ_·ä €qŠ÷·ó¹I¾®6ÒKZ!J}n;ø�z�K±hŽ’¡ºv†SH ÐW›ö> ÀV€SÖ×±™‡|ûçIô‘PS×L:_Œ›µ¾žªýéᇩ‘ö-éÀ¾û×IÚ}mŽ“o0¸9!¼oîfKs²•»ï Î08ÿùðÅ9ñ$J†ß|ûMÿÅæÁžsïk¿ï§´˜¢?•.4îíÇøš‡Ÿc_ë`Ëó”NóñãG$ϛ߳[îïÝfYìÕ§úß"‚\Š©ÜKH5:¨Úû%ŸÑâJt;“R2Š“3KÎÐuõÈÞ׫˜Í€S¶+‰ÀÛ’Í© æÜ3',ë‚’ ¶mw'»wY¬�yñã%�ù`YVÿÛÈRÄÉ LX×`»Ï̸,Ô×¥E!l»Ì €‰;Ù" DE2JÙ!5ƨõ�ØpÌ“�Ø ¸9-Të•”’µ}I-. ”J²0‚„ªØ¸0°® .— –e� “0kÖ¬Y³fÍš5Ô$Ìš5kÖ¬Y³fÍšõ¨œïض É«YôGp€£#õè@ C¤yüÜAîÿnââª\$ q¨¿Žˆs$&T¢AûÛÀìóæˆvÌÒvÕ�Sê@¸{¹®ê¸µ@Y[T'€%%�‘’½Œ¯ NU.Éî<Ú¢V�Jq+_W V¥`Å–ÅbÚQhTZq$å˜w€  ÑA¿<dÈ£¨$€CÔ@mU) ewŸÐ 9˵~8~Š6»ù#p}âpš¤¤Ù½[[R³õ'Ê%0QH HL¾½Û1uú&ü2bMÝ®¶/úlˆRèëvP/Žp‚Üt°Ð8&=÷ˆPØ=EIÛhŒ$ F8Gå£{A„߉vÑ€\®ç88Pß›Öõ¡íøoÑCÃ<·Zrxx6Óâ§·Û‹ÅEø¾J65~JŽ«®®l箸/¸ß· yÏ �çF(d°Ö"ðûzévý¢Ø³ {–}.ö̑Ƣ ëb.ÙI•tÏ[DLݾ;¸¿ï~» ¤eźîî8àÛŠ‘÷ˆûs ³)ø—´ � ­FX×ëeÅå²6‚Cu!hÇÍ¥¹0Uõýº^p½‰B²ËAîŽ �p`Ć�¨9 IsI°EŠˆ�nD…J0‡¿ü Hiñ(�H€«ÿ÷ê²�¡âý“Œˆ°®N F)yþǬY³fÍš5kV¨I˜5kÖ¬Y³fÍš5ëP"êà²E.¤ÈF§ÿooèë–ªz NŒ‡­*R3r�Áe€¢r0ìãü‚½?Œ;¬íXDñ¡~ƒ‡vQÃl´‘ hȘoY²Þ&bv^ƒ‚¹‚ᮊS·œ7ɸ�  ¯?“°!h/Öû‹o‡\€ÍAô:L e°Û—‹R·ü¯à|e5pUŸëy¶4u‡ùääÒþkàÛ¾â0ܲ¸Æ2t²”üjÂÿ´~ý:¸v‚/í{ðòFø'þ Và☣t0O€tñ‡Ôw0ŸhA`n ƒìu;w¯hŸ%Üë¿ÙçNŒ”¨€¦“8�‘TÇí³ªmŸW`­#^ÇÖæÞƒý![~£Ïl˽¿¥î÷̽¯êç~îRÕÝÑò_\�_ýÙˆo Eyƒ” ÍE~†åÃï�–+Ž2iÕ þ‡?RÌe }Á1ÀØÏéWßIÃ׉­ý¬>M%0êÙè{^ýñ Ô»1öW‰8<Šgöñú`Íß�[xq€³Ðzzn^?GNÚþ윎k÷;Û§‡»Yؾ®‘w ]üUhñ¥]‹mB|~d‹‰�lƒUâÂEÁZÜAê¦ øT(zÞT(ûœºÔ8ýúºXÏFúIþôpç|$Â)i‹Ày0UÀ±õ�Y8^·¢çD­ê/ÓÈ?CL€ÿ¾ÞOH¿êd�«Î{àÿŸ·óÉ|D#ùURÁ’FeùÛÛ½m—÷ ‘ò0þuß˲BÄ£˜®‚óu?Ì ZW¬"Xsn¹ôñ\ÑO´E”Rb 8°vç‹Ð7¨Ñ#Ó#JÜ¥»L R•ÿÌ3ÌÙA–ï.RîFzÒÝ î¿üç¸ýÎ¿í ¨nÿsÿÝê¿Ãª€ÉŸßŸ>ðb×!‰D©¡�uó™¨]Îç¶>Ä�Xëà”ÿ7 ¬}ü”ãåsÌn�k®» Ü~Ü]&8\p¸ÏWyr×Ñ'¿Òñø§û} oN×'téÑd×srâ—ÏŸ,ü›;*b ¤"�kzsJùÜÒè`²ñÐFzÔÆ·ûÓ`ÆÐìòUßïŸÐïôx°aÞ0�¤8[Ó� £_êéD²ÉW-W]G§ýææÑ/k=‹ÝQ wœÇ‰ø¿>›;¹Oºè+ëœ`a;Úv‹…‘"Øö {Þ-ŠÇÁâ:¯æÀDض¢êÊò‚B]•¿ç‚e)m|3$%ϧOHË *ù¡EœR‹‘æ "à@¹4Ðß *þœ l±fÝ¿âr½áz¹ØüáìÊÝÉ@Ážwì[ƾîæxÀ ëeÅízÃ‡Û ¶·;öm‡ìD÷û¯¯«9,‹$*¿¬X/WÜŠYø3SëÃ,[ÞqßßÀw²þaÏrÙ‘‹Åä"`2¢Wb{öK !j€Üêߣ–Ô£ ¼‰E²õSÎØ÷ eß�h¡jãÉ —ÕúiY—æÐ0kÖ¬Y³fÍš5«×$Ìš5kÖ¬Y³fÍšõ¨ËõŠœs³L�¶ðM�M]Áw,„µ‰L[8˜´+±@­·1®¦tf²��^ÖÍ6ž¸(X&ìepDÕ� ¨VÔ­ÃñWÉ3°»"MV³eÉ_¨3�RúPµÜø`½ßʕ⪀�1¡¤©íì˜�$ÁA-Yû€=`PgW`ÝÏÙUÞâ.Õ \J çì�££çƒD!'¾e—k†,­@Bl€b¤R`Øïé$zòÏctyŒxœ’4SÍzÈá>¯û¶�ÿ«nN«ïHįãöâ£î¦.æõ'¦Ä¯À2± ôoU ªŠýªÐ§eT÷ 'Æ„qø¼ šÊ=F€€2dÇ<‡£ÂÔI´6›ýVÂý;R¯}ééaèY¾„*<ìŸ8Š·qPWü«z^»tê®ò¦¦mÑEZÛ÷O?ßþ—oþbkƒ¢«ÂMˆÁÿâó¾´ãæ]ñ'?ÏHÜym½âΩˆç.ЧklGˆ?Øó;¸®Š"ul®°X=f “c‹��Å åæð§‡uâ=›ù‰~?£ôÞ:ð¥ìz²žøö>öíßË T�, ÖÈ- )×Nîa¿' »¨@ïßuNJpèÃÝT‚£Î‘@'S<ØÚ?$ Г…Gõ<�Ç¢^$• ÷¬öwð‡ˆÙ5�½Õ§ý®:ÜÚWp�È\§ù ‡;�ÒiGœ›¾š  îct2™_?¿rÉÈ{Æ}3Ð;çÅUõ Uåùâ–ô‚´³» ©«û³«ù yI¦vO ©>Gð‚” ÖE°Cƒ úŽÜ!†Ü¿º¨Ûüž¨àÿâ¶÷)%Ü^^p»½àåvÃåzu0>·}ï»Mò}˸¿½aI+Ò¸^NŒëõŠ/p{ÃëÛ+^__±oŠ=g?&šÝÿ²¬`6å}WÖ_Ü…€PJ¶‚"Øïw¼2AU°/ ˆ 9ìÛûvÇ}Û ¥€Èˆ;Õ¬¦ºU'NŒÅ£,Ê€‘ÖÕÝlžÞ·iêÿ ÙdžÐûkYŒÈ°,©?“Íš5kÖ¬Y³fÍj5 ³fÍš5kÖ¬Y³fýêåzCÎb/L™�Š¿¤•éIJZfë.¤†ˆ©Îº6½ª W`UhP¼?+¢G'êÁ옺½‚éÀdV°ê@`�8À öíœX€¦Ú3e¾hAL«åÂVÛ_Q9Xô‹e}7<ÎÅIT·Gí{! h9É� Qí#Ë6°[q´º_h$ƒä$‹â¤ R‰ "kû Î DêøuÈ…@]×H�øpÖªÔM$Ýpœ‡Àf §¬'!àéq^ßrï]Iè z“lg€Û$o’Uæ üwÐ�×å?‹÷érµïÓðjßq%?‡ï7åu#vD%<‡q>’(È’+1&j¾é� _¿ïç4 ÿ!AºM¥«õC ׿JIcÃ�{> ë™Í{Œ8Îç ú—¬ÿ«¼ØgEÅÚZ¤½ÜwF‚øôgÿÄ+Ö—ß±kR"à/®þà?Ì @"A ÷¯~¾C‹"%K�`˜=õr¸ž�ý C_Õ± ×…@s•@Ò�qz©Dÿ}bH%o¹¯ík–£kiýiXlù7º¯Ð»¦õñw|øXN¯ÿñ{An¼i¨Û-ø:lÝ·ÉúÃ7v-3";H X3DvŸO¶Þ1„’¾t……¾}îä+oÎ÷;�Ìfí¦:ª�¨]=Yí*íxe(ܺŸôÌ»åñJ¾f‡ëO5\bz˜Šu.ª“ÙŽàg]Ë«ãNXû¥~G¬ßýŸÍƒ/ÙýŸ;üÓ–…ÇmÚ½à`�ß\‚Îî1áZ«w¤_ýúW6ì"çŒ}Û›Â>¥Åìñ—ÔœJ.ØsFÎFضûží`Ï 9ïÃw ¬§î[{³+ÕM­îÎÈ%cÛwlÛ{Î-©¿îsY×vî˺6à½\pY/­{DVä½ gA)‚m{3÷b,«‘–uÁõzEÉoo/¸~¾"%È÷}Çîó]WÜnW\®—þ3s#-TÒƒC5#çwæf°¬FŒÈ"ÈÛŽû¶a»ß�ÀÈ ‘ÒT—‹@È{�j% x,ÀÂXx±~æä}³ùúXÜ¡!û³�‚Ý%`I –´bI .Ëâ1�”À¢æêeò ›“¸™´» ø4Rz(v^È¿G� ÍÐjô‘À�÷ã§õô”éa‹³ßœõ“âç¿zÃoýôƒãû$Uˆ¬úSeؘ¨g0W]ƒZŸ à4{ý¤Yæ2c5[òåbWquˆJþv� x·ó�2z”7òIhSWèànD”=´>4T`¹ÐîêS�5=|xÄq�“ãé8ÓH&(QýïñÅyéÑ ÔæfUtKkWð�ªâ×üxùé+^~ô»néˆƒÿÒ�ç„ F(Šm/ø£ŸíØ7ź +Ò¤DX’]ÃvÝ>Ú—‹žŸ³¶8€~ ÝKG#xÅb ´øùE@LNÊ2ÎUdQq�gLí�éú{þ}ŸuSÆ3ðúÉÅ5Ìã‘ _ÿý:?‰ŸG¹s‡Å2�–LïóÚÇ·¨ äž�^ÝS‰+Þ�X o‡æ)ðýÖ¯:±À�üŠ˜rÑHtªcD ÆûÃp5& ĨTúîÜ£'ÜšHN#%LìóZ[@%¥ wã6÷~/Šíü^óÅ1ÖÙóåMmløgÍÃÓ„>’tH¿©1FüûÅÏÑî³¥ÙëÀë²`ß/ØsÆêý{Îx{}ÅëÛî÷7l®^ø hÏH{i® Ç䜱Ýïx}}ò®Èþlñöö†ÏŸ?ãÓ§Ox{}E)Å]Ü Yâs³â`öÿ—‰ÝÈ£ úA)Ûnq&¦Ðg\®Ün7¬Åo·n·\Ö+8%[~³éÌäd#?”\ Éž�ölÎ {ëG‹S R¹ìX.Ò–�¸ ¬¶mk€eï3…È€lRœ€ p2Ç‹gX@ÌFLÉvÞµ-ʼncLŒ5%¬®ü¿x¿-Ë bn¤‚Y³fÍš5kÖ¬YVóéhÖ¬Y³fÍš5kÖ¬@­— ¤–eA"æÇ—Ñ1ë7Ú?)Wˆ+Ýu ö �•‚:1€ª•«Eš%‚ŠX~s;”ºã€vpt©�úò 0TåoWM3§d¸/±µÇm£-RÀri ’+ö#UHH (i#4àÇQ ™¨þ r®YbwdpE ª+,­E  fîd‚3´µfQw°�â±iüL�êIPÏz>ÕîÛL [·`g­Î}üõÄÞÿ0ô±ñgˆÎWÎtýâ¯ÿø_‡ßúÑ ðØS_Áœ!M¯�Q�ª²ˆœô ¬®Jþ Ú/¡+8]ºš9UŸøúŸÑÉMõ~vâ®îæØw«¢!¾#š²ß?¯Yôo@¾ Û3½ ÈŽžû}Pøë3÷£�øÉø¸«@kOü#pu·+•K·ßÈ("¡ßÃéÓ`U#«(ßÿÙâõ»ŸãG¿ý°¬—þë ø/² ~ñÝŽŸ—Á¬«�‚©O�Š%FSøFûѳ‰ý¸æ¶.¢³ñ˜_AÔcÚê®…OÔÁt¼›HÁ×ßq'ÿEáßðîÈÕñ'À}ýŒßß¡Œs½Èž|QEüÜ}~�øÏ»�ÿº²£E|TÂŽw„úî¬ ¿Ír¢Æw¯ýz�RÐbYú¾|Û"!íâü?Ž­“´tò†ªŽñ(Ò×(¥@×òê(Ñ�@jŒ‹º’ߦXw¤#m4ÄD‡„ïÆk,’ÁôqUn<•þ]"mc`n2§‹o�>¹w<‹9º ÷¡>Wõë_7°¹ä2�TµÙÝ_ÞÞ ”‚û}kàÿ¾mP(’2 ð½ç)m~/g”’QJiyóR2¤(RºãÓçOP¬—‹YØ;àííÍ­ñiIXÝ꿺TR@}10ÜömCɘçlí5à~Çvß,¶ ¤´àþvCÞ3è#- ‹,X/æÐÈ*(2öO%Dîy‡Šbß7¼½Ý±oö=c—ÜÖí”\E²?û$@Õbö{Þ!¢~>ÚÇÄcDRvwxb/ã}PR2¶œ±¹£À¾ï(î“7Û‹/X�Òj/ ÕùŠ{Ö¬Y³fÍš5+Ö|:š5kÖ¬Y³fÍš5ëPë²@®\Ö•rÉ7û”õöQyè[ m{®F'oúÔˆ;"¥t'€z1nˆû}Á‪Þß÷Ý”ÿ:º\0nÀ;`Ä Ë¥/¼—R@¤x»Û|0küµ^ßÞp{Cv'‚¥,PÕF`f¤” ù3ATpßîP¤X[s.xsP<ç"æx”sögq‹}#Jš�?µç†‡[”ª÷Wív~¯¯w¼½½â¾mØ·"ÙÍr)1ÒêT•ÄîÖ¤�@Pr�WR䂿VUÜ &º/%w<ÈN†¨ Û÷ ÷×W|~}kä‰=ïHH 6‚„:ìoëCnû›5kÖ¬Y³fÍšÕkfÍš5kÖ¬Y³fÍúÁ^˜ÚËájÞ3§C·‹ìG@Š¢•ôYÅÍ«ÊÜßêSU¼G‡óç»q@YL ˆ’}V¡�¢TÐ…ƒº}ÔJÒ�«]3jMÁ®áåy´Rw•£X^-8¡H�È”Ž@u’w@µî¯` µ>˜í%{³åoß]UÙA8j+5üžIZÿÅÔ�ãè�M�øß÷ÝÂ>¼­­©t¢^ÞË­í‡pˆÐuèjÚ#!áÏSç¾Vÿô_þ€¿`÷O.&á–7t°ôl¶èQ©^ÕÈÅ�)ºѬùL ÝA Zös‹Ї1¨2YØ1¢‡u9ÕõÎu>HU@kwe@Öë¹áÄ¿þŽ §åºziû¶òU`±`˜”ÐÂÚ§â[VÔ\»�ÿ£Â÷�±>ºÿ7~ArœV  bCP-Ô··Ï¸¿½âçÀÂXÈ ×"‚= ”iõdùd`^b`]É×Ö ã�;.jŠó'‹ è{î+G�vB€ï¾âÙ†™Û<ãØ¸ÒB±|ø ¾ðÈþ¿ ZÕãZR¯÷@ˆé7<·a4`¾Pˆœ0â 8œ¤Ï³s¿C‰ÍÉ íO ²÷UãÃ4ðŸýò®çÞêx±š!‚ ZÂįߨÅÞ]ƒªÂ½Ñ1èé¢ñK¾þ’*§‹€€×pÓ¥“aÑø»Þ˜ðw¼ks!é¿ ­¥w*´FÿÝôq©Ðó9Tï‡ñBõ蔡ƒSÊ1EàìnñõwEÎ;–%�(=œ°øZ¤ûn@õ¾;yC ¢w ¨$>âÔù%ìl±¶îˆ«î³“ DzGsâmƒªbÛ÷¦`¯@}%jÿw}bf,«Å;-)9oÊìù ø·ãå"fÙ/•0Ä�HÀÌ`bŸ&b‡ÑÒ#�Ús–­jlAÁ¶mx»ßÍm`Û R@ ¤e�@i±ç9%{¶sP_¤™ÔÒ¢PŠ@ýšߖȬÿ«AN i1rÄvçϟñùÓ'¼: @‹ P]mq²9i  #kÖ¬Y³fÍš5k&`Ö¬Y³fÍš5kÖ¬D‰ÝV0è¨ð¯Õ­ý©£Õö«ö�Nx•*@IþûÃ|Gü؇€x…LjBÙµ¾ÚuÙíX@{‰ ÝFö `Cp¨ß%³¾5dÛ´�eÐ%p´ç;€c pŽîùù«Ží=Nžê ¿0€…œg`j~(ùåîÀ¼–v=­ËANü@¬X’ƒÿ‹¯-êÜÞ?%¦DP�hÖígQ'®-ö$þ¾*Ù†Ï×» ôçÂOߚן€Ò@þÒÕUï$ãgrØì½ô€�@gäó)ÜB̅ƃHë)ß;ø_çÌ ”7ÿ³G; G$p‹ªì�Õùá ¥·q+� ôË·4^–ÇKÃírpÙé¿£Ár¿ªÂÝ5F8»JÏïÞuœç¢Áù¥îá^ɨ»×¨¯çm•i·m v’ vbƒÛ¦¡-úœÔUŸ+*cçàŒð¸6=R�1úyØæIì\¾¶±)%‚ç¥ÅlD0ª ì‘úRUå3D òNžko­Q't�8Ñpo¾6RAU©3»}ý²ôç«zÙqò,ûæÅž#v×÷}Ƕ›º¾‚ìDÀ²¬`N¸ÜV\o/X/{þ ¥¸»Anê{s,2·�´$sPò릸Ë��HFÙ3ò¾aÛ6@ xa›³9‰€kä‘*ŠD¢A¿L‹˜#@EÞ rÞšÀ²,X–˺cñv©*^_ïøüú=>}ú„ÏŸ>á¾m6 ՜ģ�ZrŠ(Š”áYjÖ¬Y³fÍš5k–Õ$Ìš5kÖ¬Y³fÍšõ¨=ïöBÚ_ìó!2÷QÜûh"A ÀÅXÔ�Í�Bqì‰ûñê;`ÒÀªÚÍëdDE»©ïx€èh³Ë&ÏWÖf§\­t›ê² âÒ>ãÄA)©MEgÄ çå\H�6s妬jJq—�–Ñ�­�z öáä5UuyóM>S�MèƒXUÑZ_�‹$‰8¬¹ô`û<ΖYê…�ˆÛ£tÀÿ÷ó,uþ«J�ò/Y$aO<ŠüÝ®_‘ÑPAŽ€,™JºþôÓ:Àl±Z^í{n�ŒC¼ròeôxomòäåÞNñvq$ ðc? âzéç6ü’nèK%*èú»�ô ÑnÖë-,<´í #SqÛ¤–·‡Œa᧪@Åýü{�}?ÖçÀ¯p¸Øìú¸O*ãÜ=¤Ö“ƒèÞÞÄöoN•€-ÒO‘‡ë‚À¤(ª8_u)Ø›ŸJõÇÄ�JRr Pë ³Î¯ä*&:%qÁ3Ü——¿€ÎÀ¡q ¢¥9н5P;JÆ«RÎæÀ×^­gwœêœ�ƒ¿~Pòï¿ìí’ p�ÞÿÐ •â_e‹öpR…<Ò£ªþK' (ì˜-2¨ËÀ¯_—¹äÞ/ãx…QªÑ£k4dÜWï“�<×VvU÷„á>KÙ®Þ§��VçJsÐö³µ5…øõ[WWyñŸüžo¤½>Þ @§ÏU‰Má;ú¥%ý|&ˆï8Ë|XÖ×Û —uEJ‹ß¶ r)¸¿½yŽ|Hqõov ú þÓA!_JFqç‘ÊQˆF¶fhÏE„ÕÿNø'f,ný_�O�SÊ¥ åõ_…ã&Ÿ+ɹ8NÉžÝ.¹;¨ï·†p;ðë;‡«-¸éXR î�UßÈpÚ¿Ôâa`>…±S'V•üÛÖ#RåMP�aó´­©u®«úÇcv~E»þv®u­§Ã} “ôƒI°~$1˜ˆNÜâ´‰UÄÃzÿmmx˜]év{¡�>âr¹âr±×œÕ.ÿ²®x»ß±Ýï à–f¡OM�ŸÒâä@ë¿’ME_Õþªä@?5RF—”ÒÂX—e´/ª‡ã¸B_J#$ ]!¥8'ÐHêî3œ¬——õ‚Ûí†nøðñ#®·+'?ä=ã¾mÈ› H)a]ˆ˜úÞž•èüê¥þüX×á”,¦`õ?D„œw”ê¾"9™"qw )jNL¥d”œ±í»G*Øóc%`ؘeÜïÞ^?ãm»cßv{Ž[Qw(pwƒ¼ƒw‚¨€ÅÖ:‘2ÿcaÖ¬Y³fÍš5+Ô$Ìš5kÖ¬Y³fÍšõ¨ûýÅžw·P��íàÃ*Îæwè£ÿžNƒS äðÏ`IÜ„µÔì…+HB³÷75+ÐÜ€Lb¸¶ÉÌ�kN­ÙëcÎŒ¸NLPñ¬Þ¢®ˆ�`J²Ä]ïZd8ߨ¢ ˆ[ΊƒêÁZ¿) Òø¦|¯ÛW�hPók=šúØÏÛ2Á�!O¢"/2b+N¿H‡l·?×Ó/œé÷ǼÝh}>ƒh ãæOí¢ŸWð³Ÿ}(�S$¹ì0¡ÎD`¸tÀZÕ±å*ÑæáZôò€å¿F%„"o`Ýí{݆¼)yAo~è1ê<€ö+êGn™éðs ñOÍLûïÝZ‹ÿ]Aÿä ÔxQŠÛÕðËïù!ñZ<wõÙ?"8´©™özéÐEÈAíìR{•Šð×k‡‚Õ¶ÛóW%óB¶æÀF)ý´k²Ð�¬{í§Ä�ÔÄÉÆ‡ØÚ\õ;µ¡ëÊ?wQ%BÁÿäúyj¬`Œ_mͤ”ÜŠ<î+¨·ëù©�ÿúíÿø‘ÑEÉ×NïË_#�hÿ‰ yLn“¶9Aµï£§~9‰vˆQÇíú+VjíÒü½#Ÿ¶Õ Dßûw£K„;µÈQÅÕ ÿ mÐí»‡Ø˜¬À÷wF§�<[n´_«‘§×¼à ¢CÿGò=ÜCµ9·PËlï÷‚x�E#¤Uãâ××k‡×[ýU»ë ã$" Úûâ[Z¬‹·KµÒôlq®ûkßÑ LO—ö÷Šˆ:q �$„o>~Ä·ß~‹ëí†u±×œ{ÎØî÷ ðgÃå@HnÏŸRSñgߎm[#?8I1%°t2OZ¬KÇÍŠ?ñèPÛ¡ªØöû¶5@Þ÷ñ°`Ï9ä">Ö )-¸^/¸\.¸\^ðòrÅõå†ËõjígÁ÷œQö‚R2Ô#Ò²`#$V ÿrYÜŠßÉÅœ”›C@âUömox¹Þp{yÁe]PÔŸ�°›Ê¿d°V'nçKD(î´ÓâJ¢¦êçû¾cÛ6ìÛ†\²÷mÂ’, ·ñÈûŽ;¿¡”ÝŽúvÖ¬Y³fÍš5kV¯I˜5kÖ¬Y³fÍš5ëP¯¯oÈûŽ}ß쥮VðÞ7¨/Ü›µw€±Æ¸àP'oâõ°�žå•ãQ2NÝÔ?q°® ý`c\w­'wR‚ Ù^²k Ûu ¤ZÙ×€ÅU|R ö ¨f††öpÈ›)]‰ý–]+®:+®¬íŒ Ëj½ÿh¥ßa–º}·Ç× $P�ª¥~í‰ð‚œžÌ1"´0•´H�PÀÃÐ@º‡ù?xb~ê.0ªü §˜(éxlÏ“�ÿôßtuàºî.ãLYª�VÔ8÷{GÊÝ’Ÿ® ¨ö7ßoUË�yÑû‚]=ŽÖ·˜÷É?û‘€àÀ~ï+hÝ Ž ?3 ì‚ï°?··–IgZàáöý8äqÿ¦Õç…*�štÐû€~ëè`)ÛþÌÉ� ûæ`ïçÊÚÕñÅUÑÜ”û�æÌ37Í·ÿun²v¡ùÉÉ”Ás϶×6Ô4ŽCPÅö]�;b‚µ=u Ä0‘0�ýWy)Á¦=}ø=Ý|›@dª|˜SB·w�DîÀ/Œ$MôgäÛ¾KgVPu ¨îâ»QR¯?v9ô+yÇ1yõkÊ•èD@º´¨•êŠAÌ=¶¤µIºÓ‡”NvS~ýÇ݈Â9sü™Â�Ðc@kÙòÖl%‚s@s¾‰<€ÁŽåÉ­–‚y5�áþÔ×L „¸Ãµ¢gëepØQ:¸’ô¸‚¸¼Ÿ®òÚ×gŠ-¦pÍŸ®:´£GŒñïWt»xB £‘pGüèG?¢o¾ù–.× ˜¢¼Ù³C.kYÍÖž-·^ªýç#É")¡T¢PØÆ¬÷¹�ûu?KZp¹\p½]q½\°¬kÛ_½¶“ƒÔ�Pà6ûN2H¤e‡ˆ`»oض;JÎ௸^.¸^¯¸^o¸\n¸\V,¼€@(Ea­ä þ›5~b#(¡„-:àåÖöµ. ˆ…3òž�Ö„eI(eãåå†�_ðáã7x¹Ý�VƾíØhCÎÛý޼¤”p¥¤Å#™)YålG‡¥Úyß±í¶}‡äfÆårÁz¹`]/X—ÕI@);^_÷F$#'$æù ³fÍš5kÖ¬Y¡&`Ö¬Y³fÍš5kÖ¬@½¾½š2*ï”KWñª“*p£Ê£Ñ;€·/«¥t­"Þ@.L ·^å5ÁŒ ”ŒP…—û± õÅ<Ÿ´¥A®\©z2õ.&vå]‚T€¿”Š[ 'Ð@Ð`•ýý¥¼YèyÄÍÿ¾÷ô3¬¼F¨ƒõµ/j PtKáØÙýsî'€n$`ή«6Kj#èAvï3&‰Í�ØË'Àþhåß·¦Ã}!E�}Ùüÿ¸Å/ñÛ®¸]—nA/¹Ûý“ÅÁz ý³ÿôŠS8@·p¶qÛ?ùTø Y _õÙ*±åKøš"»«ø €#øïWà¿*) u6�Ö¯Õv¹zÅÈ2"®ŒÞÝ€å·,NCŸk_Áøs‹+õÉÀ7|QÁÙ–ÿ„äsÞa5$5,»·F‹pS¢w@µ‚ÿÕáãxÎ�¨zÙW±|T|Ç“|v*D õ5‹„ tŽ–èmÒ�ý0„ë�ÿšŸu ©ÔùR JÐ8ošÓ ‡~ ¨Fb õ¸X9DPpàcœÁAÆI ¢ûuQ^A>`q7‹Kw—ˆÙ ð9ŽbnZÀ"ÈZz\€ñ!ÿÙ[[ ÉIøk~¸³Ð3={½G'ˆ<ÈY }Ïm_w?Dꀞ\~îôJ�N  Øq Ö>Â:Üëuth ¾íŸ9šŸ8yŽ(ãùÐ7=¿MÏá½Å¦{›?~üH///”–DªJe3ëþ’¥HÝ+(ÏÁšß>?Fvôùoä ¥˺`]’ï§Ç¤´`]/¸¬«ÖËòà¬Äœœœ(XV³±ÐpØ÷Ì„Ôð*nß¿,¸\®¸^_p½Ü�V»—ä\ º¡ÁêñYJsZ±ç¢ªòOH´àr½àÃË ^>|ÀízCZŒ™wƶìep�ªÅ|øð>~ƒ�?âv½6B’Šbß6Üßî(¹˜3[TÀX¼˜¹lÛ)î7‚¥r1çÉö|»®+>|üˆ?à²^Ì�@eÏÈ%`}(vÌeÅå²ÎÿX˜5kÖ¬Y³fÍ 5 ³fÍš5kÖ¬Y³fýê¾mØ] V-íØ:Îõ|ghî{Gª�Hšeq<ÁÄŸ$ „ÙIõ4ZÀ;æ®kûT·'…zHq䵧맦 ”d2[oEµ…õHWAvœC;0ïÁÈÒ”ý='¸þ•“Ô,í JÞ[1ã[ºê¤M°X�ÔÑ ~@KŽí!¢¡D!*ío´öQëcu@*ÂQ–í¬çèK#4%ÜÒ¢î.§Ø ¦!. žêŸ·DðÏ~Žïoþ¾ƒª0´*]Å€O"@#¨n€£€À"&w §)Ó}{°ä ”OPº¡ôê ŠGp&é ìw2@ó àúï ʦ ê�Œæµxtõ3ÕTгfDð/ü— è�‚´þåþ‹1’@ÎÇküàLñ«5‹å¸¹¾37,fãÑ">xïRøX¹Ý4Å_‡è à=79ïxl_ D� #~‰¬uKrŠÑ 4æ¯�J Ô-�A”Ï—©í(ý«ÊäSCqùñÿÄößÜ?ÎdáÔÁN¾F$ü˜M8Í>ç¨;¢´õ!yžŠ࿺a�ôÏ©ÎOŸ£Ã÷¨Ï{¹ÛZ/BøJ—~>CP\õOZìçêDPÕþÊ£sÜ(àŸ}wpùÀ8�ÏR·ã¯`{�×QŸ4Ì#ö£ÏìPÆëŠâ]RoÚZ×óö�QÙ_×{Œäºz¯í$7}ø]»v?ÑÍÇNCGâ@%$i½Oôû �?…ü9KOî#d¶ûži/¥ ïÛ¾ûsÓ†œ�Õü�À �Dçàö¼úJî0P;á²:�î÷�¿“R2«úe5 ß�Ú:S¯!°=§„Ü{1à»Å™ãPÞÍ q²\̆½âz¹bu »äNXÖâî\ êLµÈ Ââ1·—¼Ü^p»Ý,ÉÁe5õþzY‘RÂå²àåå^^Œ,°¬K{þ0PÇvß�KÁº,Ø——R  ˺€ó‚ËZp½^MíŸ3T Š¢ŽªÓ¡üøÇ?nÑP`{{ÃëçWìyÇvÃÛýÕæ„ëõú$ÎjÖ¬Y³fÍš5ëÿkfÍš5kÖ¬Y³fÍú”AÎâïÓÇ—œQ@ø4M=àSÏêôÝiÍŒ� Æ dP·‘VqÖ"BÛIÇ}‹÷f½OF&€’ƒî=4ýmÕ—¼äYÙÕ:?‚p¡°«ÜÕ…¨â@»¿|V�TE} h×›£Á}¼!C 4u¯íÛ·@H³.xT³ìwÕïßj‹ßNôA`Máeºár�-Ò€nÛ¢Å<›=áã–Ãìý©a^´s9NŸ÷€þf§þ›³þî÷Gø÷þæï²ªë¬€T�|P� �ªf 'I×߃¾ýÌ­ÓÕ°Éü=hù€‘(…Lõ`¶clþ9ùñ Å~æÔÕü¨×P´�ççëòz,Ä­ÏÅ@dSþËnÔ�d­?>ÿ¼½�wÇL÷Ãø¼KØÐwÇÿl¡Upq@¸ ‡åH#i~þÁxAÛ…GgÁìí9ôÝ ¹`t³O°‚Æ…±Ó�T;¨~fó®‘D3°B<)XÉçáó~ÕÒ�</Í!%½ü.xù&¹Žp.µ>7‹ÍU­Î>ɉ2ÚæµôyÝŽ›«q\ÛÅ/+tAÈÇUÿµ/(�#Ù|¿>WÓ”ÏãBY*¹@lý.,Eø¯ó¤ õAÉhf$v‰þÉçóëJéQ~OÔ‘ÿßBú°^1SKG¨mî<�G§<ÞÂw®ÇKêè´RÑw=dntÒ^o§4ç™ø}´üH3�ÄF‡›Aå�®šfùH8wzg­¨·«cÑûî2D*D ¡\2JÉÈûŽ’3J)=2ˆ:øÞ\tü9@j¦½”¼#çÒœ†Rº ±Ç - Ò²4‡!ñø!'»Í¿ª¶è JhnÃùzÌPÉ(bì•R Š; ÎX=`½\°¦"Y3rÞH/îìa1ïûž±ï;öm7…>3èBX–Åbn7Ün7QkëâD†ëÅæÉårŇ/¸]/H«ÅÐHVä¼cß²# JSö�ä+"FZëºâz»5"†ònä‰T°¤]/ÐEq»Ýðãÿ?ýí߯O~ô#\.W”=ãSJ(ûŽÏPä’±ïw?®­c×ëeþǬY³fÍš5kV¨I˜5kÖ¬Y³fÍš5ë‡Púe{là¨d|naõðªö鱫‚Q‰÷”�+è©�ücP±Ów [àcl�}!øoLQG5¿#X€š7K]Aª…šÚ±«ýµÅ ´—×›àHhÖÙT-õ« R!âíDMu¯ÞŽjÐäUËl¯ùÕÀi›¸CýBßÕˆh׬Dî>œhœ+úî€ú\ë>�pDdŽ18Ì.„y6ØB·cèW;ü�¿û/ñ¿ÿßýÏ:X™ ‹ÙÝ# {T¹˜]9Á¶SH�Áéã_E¾ÿP±ÿP¦*­ ~î€~Š€}$×bSþ{N| ßù’b1(ªa@¿"Wÿeà/f‡ŽìŠÿbà? ø‡€ hý-(ÿ3ÿîWÄ<Èv�:i'T¿Ç38# Ÿ|>,ç+€¿ZóØkÄBËg¯@mWcwu=Ôÿõú­WƒÉ\N×XU‹šàõAx˜×—ÅÁÿ!Ðr¯éà¢Q±rØy±TÁÿ~u)È­úo?ùŸún¥÷•µý37€)!6µÍUs  FBIîÂB�ã;‚–Ç)ÒPàèRqX0¤Îé=h,®C>ýAßV üW¸ÚYŒ)ÐR£d˜:ÂÚ "ÏãO¾_çàù�l5›RZW­®Ó—¯‘IÇõ°Ç»hßíp_¡ƒkÎ8ÿtø>õû÷1F%(ùµ:ˆ>¹21~ÿ,’åhôñ°èn‡»Ì—l_NˆFZ¯Ïƒ+ÍÉI”\¨¤L¦Ê#†Mm•üõÙ¡ª÷m*ú÷ònä�œQÊnæ$œÜ]ÀÆ1- –”ìy‡TÄÝHz¿©û3è²¶vTRÂ8ÌÁÍa ,$å,ëŠuYÁÄm>Šjˆ²ãæ’ñvÅë÷Ÿñé»Ïøôù{ˆˆ¹\®~Ni°¬fÓO¹ ¤„%­¸,‹L!àz½àr½bYVs{Á–7Ü·ÝmøKkK�iK “,#ʬˊr½@U‘ (Rœà� î¬�–ß|ó?ùí߯oÿöoáÇßþKJ¸ßïÉxý´"y$ˆŠ´þµÈ&ŬY³fÍš5kÖ¬^“0kÖ¬Y³fÍš5kÖ 8Y~ì™Å©*À\òψƒB¶�åõ Çàï%W»÷—î [«EÏã­ÊHÕ ô½ô÷÷ö¹H´îKop?1�9Þž¹ÜIÝNך¨PH�@Æ©©�a–Ù~Ü"êyé,Á‡Žëf® þcþBó‡®öÈ1癡b˸~è~u`¿ïF%ô�ö? Üi�ß=šœ4)”vÎÚòh´ªŽ?4@ŠšKAý.©O¦=™b8±½"Ø:Ù�ê8YÿîûÇfm�%ìÁ3Å�¥@°‚H Õ¦_ÂX1 -e0ôã_~þ_aù)“é5«œÿ“Üú?¹•øÑn=¹E}êíãÔÇ‘ô”Ü3ÕÍÒß”þUá_}Í‹Ùý‹ÿ,âŸÈÚ¿tù ôí8Uü?ÊÿO*Øüóñ;Ú°^ÑPÁr¢ÃÚs”÷ê�[â$�øUAÈž§@½Wí2ŽD¨¥>CÕ‰"L~ã¹5#‰á<èqŽ6uÚªÃzqÄÛ¶i‘"Ô­ãµ÷ –ë�ÿí Ô×@ŠÀ8†q }$1º¢Fa°;,-ž‚êçOQò>Œýáî\;@é9S°ù{(¹SY<¥òùOš…‰©|7à_Prñëã`vPd‡R?ÍŸ½¦Á%_˜ñÝ,¥ß?UT¯ o�ÈñûÎ`lRçAø›|~¼á>P�@ý¤áryvo–ûNÈ‹êþè1Ðb~NîÃsD èÐ;nMµ�¦zçGГ;Æ3Š€>¹Œ¿ºo›�å A]µOÌÍN¾wk ’˜{ƒ˜€â„ÀR rÎnS¯à$X–„"¾OH1ª¡ü‚ê?{F}®U¨.à”Ì9  91’¦ö\!î"`î)@-6 š˜‰˜)-`¶keß6|þü¿þþ{üú׿ÂÛÛ[»‡¿¼ÈÐföï ‘Áìÿ�XdÀº^±¤€¹䜱ÝwìÛf× €”l?Éãêš\J¦z�e1—†JƪîÌŒ—Û ßþèGøé�ŒýøÇøæãÇö·¾]±\.Ýq�˜µAgÀ¬Y³fÍš5kÖP“0kÖ¬Y³fÍš5kÖáÁ}]qU/þ2øðžS#ØVÁê ô¸ýQùª}׋ öŒ†ÙÝ[ŸÎñ‹ÿº~û?2u®ÊÁ”!‚ïÛýh5 íŠèÝ\ó–�Ø¢%®—Jpq7 ¨G ¤xshëÐߨ·¾Î�rï„-@ºË�º�?Ã-� -ÅâO$�V/RI®èþµTz“?eàû{Âh)ƒwrs|ÝŽn4¤ÃÚM}±�(w˜²R÷€}:ÞoÃßt˜XÝ Ÿc#è…x›žê¡Cü€Fæh$Ýà„.¢Úãû¦ƒòÿ8“# ÄãŒ×›~¡¿é)�GßašíÛf¢©Ž˜Ì:¿0C¤Ûò×( Ñ6Fèd—J«êõR J)ã#Æ‹ÄI{¶(‚>Š$Ò”úN£Tmv;2e|u)ÊEÚ‹\bre¾"­ Ö´`/ p¿ßñùó'|úü ÷·7pJX×¥»!$û@'&pZ°ׄz^‚=oÈû†RJ#(,i`îÌv�Õß÷8 ;o¦G÷"‹X—·ðñ›oðáÃÜn7¬—‹ñžö—eÁÕ] ®×öœ‘²Åè\Ö¥95Ìš5kÖ¬Y³fÍò÷ˆ³ fÍš5kÖ¬Y³fÍú7¿®×‹½àv'€±"Ð­à«Ø•ˆ¾¤�Åé[÷`'d Ôýr|¨�Ó È@5Cڈ͒øˆÿÒyþq݆ܒ–ˆ‡îUmV_¨W%¿4¥<�X¡Bøw¢€O¬ž·sl@ªtàC›cÀh¯ü]SE(3Ô3ÏM­8*œE`¶îâ�Bö8¹J_»BptQ‘ÜP4Š?ÏìûÛÈ=Àxq¸ê1O³žŸÕ™Êÿ )ϱþõϾÃÛÛ†�·>÷K “7ðRX\É-Œ„‚R­ÏbŸ%b”õ ‡©¢«Âx¹9�¿:À4€ú~]6;õœR¼f£%z”ûúïø €=(ú]9 µt{u`Ì›gäMφg€–¤õÊþÙÚû5$€g¿U…GV?·�/"­jj×Óï‘>¶Å'›h'æ)`´øoßzvz>Tlœ`™Ô°ëQM|È@?ë¡à´¢#Ù©¹!Ðy? Ô�ÑcÜX—ˆž€ÛOÿ]Ͻ/= ¡ýY¼?|l‰Ã\£Ð°0€Öþvç‹Ú·Õ €(m®¦N-€.}=8Þ0|ß5‚E}õEÏÛÂ/Àò#�ÂÈ1¢îr!”H ¡^Gþ£ïŒ@@v* àÿ’#uêaŠR$yÅõœ¢ }5‡ˆn(ý>ï&VµGŽÓhÿOÇy{œÉÁ-"ºœG˜zP‹ØÑ@ˆ«øãÚ¹+ú¥Ç);ý§JB$I†[»ú5s | ÿÿÒmeÛ7w=ZÁ‰,L‡ \‰Ej¶øÕ æšTÇ~I ª+D RJ(%µõQ¦Úi÷Õ ŽÇ{žú=[DP¤4€xœÎéûX–i ¨[ÚKpìû€¡Õ¶ŸËš�˜±,¤Äw!ØöÛýŽûÛîÛ˲´g$jî<ôCœžÑ¢H�BPD Y êjþ%áz½´sJ)µëÈœì<˜;¦¹ÃÚ‰=sÖË×ë ·ëëåb俲æ2p¹\p»ÝðòòQÁ¾mì»ë:_qÏš5kÖ¬Y³fÅšOG³fÍš5kÖ¬Y³fýê²^@Änóz·�@C·n ÃgoÑ£*qÈp{£¸_å={¤4�ž¿µº©Ü;* ‡cÄsRŒêŸ%=(oë± D" )E¥iÏ¥%–fß,¢AñN·„®z«ý¦¡�yÀ•ù£;=õè`Ü«=³uukö�­0GÅ" Ú9RpjüÁ�›zÆ8Ž¯Ùµ9„Œ¦”6» ± ïU|Y¯_ë  Ú|ö5뮎(‰*þÎýÇøßüû½©õ�*÷åñ?yiwBJé+HYcúüçòéŸâÊçËÁæ@ ˆ×fU^ç~ÏU‡•ö;8Zü»½¿·ëÏ]é�ìŽÑòßAâ¦ü®„Ÿj+ÎÃH˜]½ƒÄ’› �.?•WWG»LZßœQNrÜãéŒÇ¶vŒ 6²Ž;c“�z�ì( fuKý3 —Næóc›U¤“A$gˆðáZ<~ŸÐк<ë×ç÷�óè¸Ñ‘ŒVrAI…«E½FíÚÉ9ã¾m({iVó˲`I 8™Š=¥J¾¹4ð½[HtÒŸ)ó—0?è¡Å"% Dªk€=»¤’Q˜Â´ ¤Ä�×ç»Ï)È%·ù^JƶmUˆ\Œ º$³ÔO‹ñ„âÎR¹ìÈÅâ ˆ¸�{ZRþÅUù5v¨/OÒ8jP@–þ ÀdÎ×ËRdxV3c2AŠE(Ù ¯eª"—ª“@r—vG‹(�Éœ°¬¼ÜnØ?~ìë #,Ë:ÿcaÖ¬Y³fÍš5k|2kÖ¬Y³fÍš5kÖ¬Ó+­É^¼²©Ó­ŠÁƒÍ;š‚ÝdÀ€ŒE0xÉ]mï«:˜¨�FJãwšÃs‡ÆzÀ»`·—öõê–Û¬<`BT@Ò#šb3÷Ä `i~Wé‘+Bµ©vÅb详£ äT·'w`·æ?÷3VBpè÷gZû¾�¶¸„ÖŸñ4‚œýql* AcÞ]‘|$ÛÙÚ2ì}'â‡ÇhT‹>žó—¯^Åù÷~†ÿõ¿ÿ7ü· p=ø­×Na$$¥µ#¹B�¼’¾ù›�Oh¸åJfJÑjöäXœPÑq^—1½ùáG…~ä•ÒÿØýš‹VÿÕ =€ìƒ•}mj]Û à«=7Õ JNbàÝÔÓ´ŽŽì y>‚¾ŸÐðìr›”˜)®½ÿí; ” T»Í½�¤¢ªh'W»×ïk°‚�dÏl×:N`Ÿ'5?Ä~fŠP25�g:�ªJŽ%qŽ «õ/£;¤8YCšC€ƒÿ¢�aì­Nüùø[À6ö’»°ÏÀ÷F–JNbâ âŸ]oU./Áæ@©³.8]0�qÅ"0Œ°@+1€� èD›~O ì¹÷¹®;@ ùåßG‹³P³wOö>?‰MP¿ •!�DAÜO1ûáþÙ/ÓÈÓiÄ™óõ‡‰F·“¸ö5¿{qE;õ{Õð>ÚúSˆ—9»BôÉÂJÏÖÛ‡Ó(Ý~z-ç1¬éï/Ä:Ü»ý>¢:ð 5dÛnL£CÀŸçAèI7˜âÞób„)‚,¦üß¶÷×7ìûîŠô„ËeÅõvÃ…W¤”ìÙÊ×t ‹­ªe»;Ÿˆ6S û {½-µEÔÁ ÎDÕÕ§»L4²¡_ciMýwb•µ:äï@/fÓŸi1P¿Zû'îöýõ8ÖVvëìÿÇ1®QÙTýlÏ< ”œ‹.D¯m¼sÞ›CB)ÕÝãxx(¨}RçK{žmNŠR2Jޱ߷f€"¥€°® n·r¶ˆ�mÛšSÂŒ˜5kÖ¬Y³fÍkfÍš5kÖ¬Y³fÍú×Ì{JôÅ�pöGo€aÛAœê õÇzÈs@=8a÷ƒË~7ø¹VhNª]”¬ÒŽfYÙõÅ9Fá0±½Ü¦ÔÔŒÕV¶©íÕ|bĬó5ä)Gð¿â(Mñ¯ê@”¸OšJ®ÙlG@Gc sí1=ÿC¿4‡þÓ p‹?@S[ZZ@ž¨¢JMÛJ[2C·`~€Bf/ðH\8 ®a·”÷p6!¿öѳ8÷!3øoþñϾÀTõÅ”þ´t„O\9ßæ²©ö™«‚´á†tý‹á‚X,Ðý;ûOgåfýß­×+Ø_Эýsp±p•u$Tų–ø¯¤€JÐÄJCÏx¼` ��An±¬PÊèÐ ªo@ÙÉH|E.û0?!œÕ\0²cªZ_ú¹7²Á ø_[Vž�1ðTÁ0Ô�úwPÛ†¯EŒ�eÒspÆ€«ü½�RHl¤�Õ¶ý-èz¦R_µˆãw¯‹Ö ¾=8o´¨’¸Nžu�!`ë7¿‹åå÷ä÷ù¦lãúZRSêS‹½ˆ6óì¶öø³÷#çÞ¿8º=ø(’“ ¾z4@òèjÑà¢ÈÉ3ÖÓZ~m fÛw‚bEùô3âί6à’‘ îv` lî{¸Ø:'@®Ø³ø«ÃòÞ=óä~×à³U\õl:�y)àŸèþÒŽpµèó60„!‚§ÝB,Œž8í|Õ£„R æô½h�F ßðyåä×\“ëNDZî¼ȹ ìû¶c»¿á~Ãvß *Hœ *Íú€»+¡�㤛➙�–µWTÁª¾¤0žåëžéœ¨# œ�ÑF¶g©ñFÚ.Kƒ‰Á)aEŒEb0›+Àå²b]/¸\®€uY‘ø /bÎÕ HƾÝ™±\Wº`YßBZ1TÌî¿xtNiŽÔ\*)Pä}o.ÄÜîÌ ³ô¿¿½™#*æ àyNH)ár¹âÃ'srhû#¬Y³fÍš5kÖ¬^“0kÖ¬Y³fÍš5kÖ Ž8ýoT:Úê�–þt4Ò6{l ÀÑnÙÇ�!îÝÂ^±\7kÙX¾>{µG~Á_Û‹`4?™}· ZUò‰Så«2C`Hu:h࿽T'î*zU;¶qK~·`}IOGHŸüLƒˆ›¼3*%ÛÖUõûÀ×7ê• ƒeyðß�ƒÀàx~F Ãæ'Ó-Œi×O?Ýèø}ísˆB>÷¸ áïþƒ?òÿ¤ÝÜ>p1 4Z›×ùRç4Eð¿‚•°ÏÓâ¶æ®Z&…æï}ßn-]3ç›Bß@~­þR?‘€ü�»^Jÿ¬Z±£`ä]Ù È-Õ)ªá óÉk„€lÖf½r‡ÊZîöy~ƒri�­€©ÐCÿò0§O&IPØG¼x„µF/g;`^JU°)ˆÉÜ7žGøFýÒü/äÌ>“|×lj Fz°Ä¯€Ö{¨¦Öq¡Ñ]¢ñ †ÌðÞG†r uõx"|ü�× ,Â+Îmj?Ø\fåöóëbªåNãH69!…�¥­7æ…ÏïÂcTB’“ê¼õÏÙf¬ìß¹¥mÒG }¨å�ÃIVíú!#×h�Ô *f+Bùå¿°1ônÔxàO¿K ãúCôd1;‚[Àˆ‡†H—ó=Ô5yøs2—UÇût%™´À‹³kh À‰mÔî¡1нƒÿ0׉:ïUñ``ðÞÓHÀ߉ýÂ~3Ã<Ö«Ç }åó�>9>€¤j–÷;çæÄ�KAÉ¥äR�sÆžwä\šR<¥„\ VHKÒSJX—Åü‰Ùõ�ÒJœx0þ§ˆâìðÌ û7~©>*J�ûù*«é‡FÐi{ÿá?þSl"¸,ÉQqÐ[^]í "'&«%qPþG [2èã_‚¾þ‰9N@‹¢ì¿@J¿ï6äž¿î$mvý®è×ì¿óðdÄÜr Šæz2¥Ÿ°V7‰Ñ@N¨À?ú5ÏÛ�©ç/®ø/oþ—7@ÞÌ @6¨n@)HäjË|65ÆýH¨Öö›ýâ›–8j@z{T”üûjÃEUeO>~LžÐQÎWÏAY}V¢ÀC.Jœ“B8ÒG¯ãd�ñ>†9Î¥ºÔ#”ú‚d®#ðéH­‘Lm6R2p¼;¥TÌžqûñ_Dzùý¢7âHNÑ%¡ï „À«¹£�;X´u±]ª‚¿@4�S%¯’ ÅȆH^)£Õˆ’Mý› Ác´| Î ”¾…–7ÿ£šÜïA¼€Rhuj€9ek�$Åö‡ßC“§iìöÕ¿ÿgŒ,Ôø!Ë=Y¨z²Tþ¼ãä-ï¥mv4ð»¯á‘  Çuvˆ•±û‘¶«Æö,Hl$ ñÌ{N ”K³ágf/F2ôøˆöLâH*_Š ç‚=ˆ¨]BšìyÇ�È_J.(©´7¼ëbñ/>`ß÷Fx`fHl÷;¶ËKrGbÆñ?ÅÜrÎÍ !ËŠ‹ÂT÷iAá‚¥¤�PÛ]%¨ñ± üÏyG){‹UèÑ jŽ ¥4‡U5߆–c�ÀI°®þüÇÔ¶¯q ³fÍš5kÖ¬Y³¬&`Ö¬Y³fÍš5kÖ¬@)IµÞWdw°ºYœ7Õ-€ßpzÞ•÷;xT+úªÚz.r´Yw%"ÑÑ9œ…}» ?< b‡C–²ö÷úõÅzò9€iÕ*šY L`a(™r“¨’ÄläŠzAÈ6®€=i°ê%î`hÍ@hVûÔÏ4¨D;Äw®úom&v%gµ÷À5E»ò0lÚa–ÔŸtt?Ghãá ÁbýÄAàI錊›O£bô+­£÷=ãïüþ%þƒ¿õ¶—ÿŒª^¾øA9 ÑÜõþ§qv3cùÑ¿ƒýíÏjb€ÍçüK@~ËÔ×J>¿¥ƒþ ð/Á@ºÝU4·ILÃuØ®ª¤†›s½†’[×Wx±î×ÈR‰ òf yäÍÀÿ¼ºy @J$7S5ÙhË{çÇ…äiÉ ïý¯‡ù¨ÎHúø%®™ñf³-E¼„µ÷ø”2 œ0<•A_=g¡ÁÂýqGîPòàRP£âü ü‘ »*L % çÂ�|øéÿÜÜM˜›r»GExl„" Rw±º@è¤ ˜ÐõàÀí»ÌÔÜ3ÌqÀç™Ìêó¸æ0ÀI/ÎÞhñ®9�'à¥5¢ 9ªð˯þ«Çqt🗡¼¬òÜôâd‚-¸œ°}‡nà§÷÷~¶`ì�È¿öµ(,~™R¿6!§“ûü‡Ü×U¯‹êè2¬Ù#E†€ž¯ãÿü9!ì?fòˆø÷µ]*Ú‰qC›¿ò™„ú5l·¶1FûIx_þæ`ÿÃõˆs�RJ'Õ Ûé3',ËŠëíÅlâUzlÄUé¹ð¾[æ}ZÂó;Ài‹aBu â”ü_< @ATšòŸ™¡Ú uŸH••\`i5ÚÎÇlõ Jv˜dê÷e]íOZÜyÀ-öEœdsæ²®øðò‚¼g·à/lÛ¯¯ Rꯃ#ß®�êA¥4FŽ÷pâ4DÀûY<^ çÛ¶A¥€˜±,Œu]›õ?Ûùz;™—û—uÃe]ÁTÀ)·æ!†˜ÃÛsÞ-;Ã[t¥ªgÜáh½~ðë¡4@Ú¢ÔÁm:t£k²)#° ~$ Ô<ãšWMUQoiîÙÁüu¾g8÷¬Üó?�4P�§ öØRv\‹šÃ2@€¦InÝìßUµïˆ÷YÄD*h ¨w ºyœ@iúÔ0Þ8#Ä™1FU7‹ríY×g ®>AåõDÛ¯1n€ÎÜ÷M‡mZÀ`êÿôŸÿ·øþÖïø)bêååf±Ô¬Ù’ÁÿÐÏd¦Ë_¶íE�ä€Çö3èË_6ð¼�‚Aå¯nz_ÁѪŒð/�£@ìóÙTØR3Ô“‘:ƒ׷ÖcˆlÍêÍêÿsÿw@v¨îNXÈ »M #ïÞþFø2ø›Á,Ql±F닦’öè�qÅ�’BJȱÖ†1r£ãù'Ž'Ú¯ÏæðhÏ/áÚ{‰ §QO® Ã^ª ¿|œÔÀd®äóöå'¼|pÞ‡‚!æöÐFBºJ¿N²O¿êp(ºAèæ Õþ¢VŸÛ®n§Á�äGeíoÓÁ6¡’X:ÁEJ8–‹¿>yEùþ�ÂÍÇïKÉÜ;4­`^!ÉÏIÝî$1÷ V{Ë%f¬ÁÉÒ6þÁÏ–¢Ÿ2’ 9×{R¿—º‡)¦ÃåHOØ~Ÿê÷=î¸ ÿ¶tõµ/*üñlš÷«f 1q›|ÑZ½]‹q艾B˜,ü ßÔÇþl±@�‹>¾Þ 1O¾¡V$ì üð‡‹«òSz³¼z'Šš -aYÌFža&¨¦6×ûó7[Nõ¹¢~ŸŒ4€y 1H~¬RAëñy­:ì9C¤ - –´`]¯x¹]q¹Ü�Fb¶Uä}·kß§–eÅíö‚œ3JÉx{{CÉŸ?n@y%m\®,iid „ú��”쑹¹Héß1ÂC߯ˆºå¿`ß7ä¼ \c]\o/X<†�7‹ÈyGQ±È†mÞ3¶}7êP!@ŒìPriñÕe�ˆ0kÖ¬Y³fÍš5«×$Ìš5kÖ¬Y³fÍšõ© hs@¾ôº³‚̃ÜÁèöò=¼P¯`vÿ_8I¶¿#`kØ^D=hD›<òÑÈ„®È·¦€Bmt‹ã`±Íí…5ëñÐf¥ šg•¦ÀíÖú#@=Aœ\£Ú½CÆwìBnw¤U˜æ5¸¨åxw‚Æ£z>Z�Ÿ�ñT˜‚*¯ZðRs,8™C;ë¸upÕA§£ûÂÓ9†ƒá€ž$¬ŸOèªrýâ\~r.ÿ·¿ý��ò†Na€/öï–¥^UÇÜÈü¯dpHðõ÷!ûŸ6�–O�ý—àôò/"øªá³jÉé+ªÈãŬ5¯Ý€&‰øOÝÁ e3ÛwÉü#å³ûGq€Ü�²™Ü\w(ª+AiêùêâΫ»E^ Q ,Œ#"ï¬KOçH7•CôA¤çjô éóP*ñGÎx»v$Œ÷ÉŒ«bu!?™lÍþ_»;·RŸÇÃJhêq)¤G"€ÝJfF!èÖD�£À9ÀË\ôW!ØÁX%«BÚ¼J=–ŒæBShö�º¼AÄL«Åe�GL ³}·®±Á%@¸Æk°Ç(T ß:цâ@xQ±v*¡äÍ~¯FN å|ù‰�™$�`Õ®c^A)A¹’$º�´£|ÿßÁ#ËírsnË¿øåŠ«êÉ îx5�ݶ_…A$x!‡½ái#¤�l|;@1¾åÁ�?Æ`àù VÁfS`Êÿî_@áëï.û'÷ñꌣqþëï_yŒ÷÷ÓH{>g˜K2 UÅeµìzNŒÏ¼`Ûï–CO —½ûª¨X�’h?)¡[Ã$Wõ§FTUw"JH\PjôÌ:Ÿ›ëFÈ«í~_àá0kÖ¬Y³fÍš5kfÍš5kÖ¬Y³fÍúAÔ×¼°ÿ)šRYúö'Àíßê`|k¯<ï˜x¼6ñ’[ž$HÖ"ËiÇÁ�€Êhõ^6Hµô/P*øoN*›YüËæà¿˜ š‹“_¸X�„ ’m>J˜ÎìèmõÏÖ ®*èo¿§6åHàVóþ«r²¬Ep§fy«Âf �Qy,Ñ ã –] 3Ø�ä£ãt©±'xº®a ¨BË£Úþ€WI˜;¢„oûoÚ|. I;ïdoŸPò1Ùô¬Ä µ}ÞIMý/¼bÊz³èOaÎòáë<�£H„©«ûÉH&ÌuÕ9W¶‰Dkúd.¼Ë� û÷6?ë|«l/f;øàxH˜ÁýŸüÊεÑÿà—Œ×�YJã0Öµ¹FDÃݯAó'�ÿGOzÔ×-m\1ñàPï·îJ�Kz«2Þ-Çþ|Xui˜’çOøªç:¬ÇHƒ/?¿hh½ßï®4��]×€�™eË3–´6õ¿ˆ©ïEÜÑ…àÊtm$´b’|$f¨Š%ÉP Ý˃ûU‚Öé™UrÎ?>Ÿ©‘J‰.Š\%‹ ,f`]V\Ö ®×+.W;ß’s#hà ± –eEòh‘R ö=[ÔÁ²à~ßp½n¸\V¨®�Tx\­?<*aÛ!«@²`Û7”’=�±¬‹“6ì²;xǶí(%ƒ�°.¸\.¸\®(/p¹^qß¶‹ Ò1€(Äc*»¥RJó?fÍš5kÖ¬Y³BMÀ¬Y³fÍš5kÖ¬Y?¨Räœ/íŸ'/îm+©ª…zš¥ö`¨N#øO „/ƒßËÀ;ê¢Mv%7U?€°©¸õð{™òz’+¬úÛç¼W³&Wûr½�nØ_WìGKäñ…:1ƒ+ F]]Ù‘¤A¾üpDÚ•¾áµ ªmî@èÆþ­ïÚxK m9:÷�”«AÏ ýb­ï‹/#x5¤Gc‡–ô�)¦#œÎ¡±Q� ÐðëÏŸ7üçûŸâ?ú_ý à˜!²€© #¬Q{Pþ?8XƒÓ‡¿�òë¿×­þ¡ÐígÀõ·øœMÑæ"�9Ü5«B*ˆ¹8hé‘èJÑ›PÁ[ÿÝê_ªÍ¿ÀÙ bîMàà¿ ÀâÅH)´µÀKbìâùæ‰ðÿk”²p(Nîà”P‡àÄN¿¿M¾ÏnlÁÙÂëååÃ�aÏ)Y$P%r05¥~J iI2»c…»±?¯ôu,6H@T£1è»y �KÁõ箫;—4u}°å)Íɇ˜±, i]�Vwðv”“vÆŸ£ÃQ|ëÎr8ÇpgÓþ¼VŠ@²G%0AÔø¼�ˆ°¸CG!Ûçžw¨dì»øR2Ò’l™b6ä4Ä/¥”°,Ks(€’ÍAbnL")ÅHî|´, ëºÎÿ<˜5kÖ¬Y³fÍ:Ô$Ìš5kÖ¬Y³fÍšõ(Qq ™�ónÏñgòB„wåÚáRzG‚wÔ|ÑÑbÿIþúˆâ€g'w[~ oþ›ZM£m}µWWÞÕ_i'2´ê£Z?n+ ¬Ý¬À÷ãZ»†q;ïd’œÔlÞf=KÜó {ËGpâ(&õ覙í} ~^qD(€J=Wád´O¬Ë­ÆÁWï챩ÚY8Ç4ŽUB˜L?ü Læ‡÷¡¥HŒGp⸃ÿÃúßá?ú_þ5ǹ¥›Ù‹SW“¢ºDðŸ+A ~Ïÿ^~ºýeèë¿èvôû¤¼ºRºg×óè:PIÉQÿà߀Lwà#q ’ H ÄòQvˆ¾AË ¯@ÙýoWù—¶Å.€Ä©ƒÿäR1Ç÷Ì 8Yƒ%¿8þ„ˆ1TµØ/qŽêãè=:­CÔÕìG ¾*áãG5ꂟ¨n#ð_“7†Ç…PË8߀yâ&] a̬Hb¶<ï'i?z„Ëáš”ÆR0rÔrý/ßþ[éÐÖ³ÂW-æxÁK'‹Maµ±mÊâݯWéŽ`sऋÏÑRc$�«+'@ÇæSh»|Î0Š‘T ÈÞ =¡  âdŽº Az­?�n¿û¸1Æ®O‰Ì$·v°y&aJ tÿUãhàªý½?]NVM}pŸÝ#wKO4òq]ì×nÜ? ؉õþLên0�Ü¥’‰èà ô¥•T‡¿ëþê=´Þ'èàÄ2�Z¾¢Nýn(€÷��ÁupæÑßè(}1ùæ›oÀœ�Kn–ôv·E ”âôÕ6žìJ$‘Ùø§%auuzµÅ�Ž u]P%Hû¼»†¨Öõ)ÚÒ÷õ=1µùÝïËFX,"ú×5Àƒ-8�—4Ä Q³¾Wýêa mb¤Ô‰Ì ˜S0 Sü»Í¿dA� ƒ³9‰pâU`ê‘õY)¢Þ8Ddˆ�D‚¸ÏÜÈÖOÜ•ü>ÅÁ‚EäÝ¢Š?ë圈 ³fÍš5kÖ¬Y³&`Ö¬Y³fÍš5kÖ¬Dq-ZMãŸÕ£ÄŽÆÿëE�ê~쀩½³¹Ã¾¨ÚñÛËí†RÏåm÷n}\ÁÿQDhà”[ö¼V HˆLñ�`²º'´BP`^mòBDm&…ÃCA®[+ÆÛ¯÷0P¸�[`û“å Uè­'ëœ�C¸¨ ƒ3;ò‡5†h\!õdB‡�Ú|Á£SIûû,mÁsÏó¸G’€ªñ5RÂ7?ù+~Ò¥ç!™ _¡œ@Xí•Nrgp·ïç$jS¹xVRQ0%;�îÐ’lÓj§D ¤8Ñ ÆÀ·A cÖ -6ßm½cM@R@ ¤l΋__ Jàå¨îNê`7¡ �:aŸŠî( ²‘ê?Û”ü£ÿvovþÙ/Ö®|§Ó%{ò×[–ÄéüÌ–¿’ÊY«w1Ó7C�7b÷®G«€ÊÝ æýîppxrY©>Ð[æNCrOW„ŸÜGTÃJ}¶ðê0}56¾º7<ÜãÎmÆß(Þ'�?úñ·`NØî;î÷»YÓgW©ç¹ìÛŽ}ß�÷ÉîV4ðY–ÕUa_•ø#@‚-¾÷Tl`+Á ®+LÏÓI‹Ç0¢~7T5p{˜Â®¬gî„17ÀAs .æ‚t¢·=ªì×uÅe]±^œôÀ ¸/E 4+6ŸÐ¢‚”’ßbíÞÅ\I¹PJÛ¬S`·9Û÷¶ïX¶­¹ìûÞIN`f¿ŸÖóJä²y ;Á·Ÿ³fÍš5kÖ¬YcMÀ¬Y³fÍš5kÖ¬Y?€jv§‚�O@‰“¥tGáñtŽëg ž‰þ¨ÚV³w°¦¾è®jŽ ›Â_>Ÿ+äC+! ­�ùð\Ú v�ªüJ°—ó)1ˆ»  'å¶Íþšèè1Zþj;'E°'hÊÇŠ â¶Ç:œë±/†#¾‹›Òi7fË�Nг˜ 4Rå.<ôYsÐq„ ÕHú¼MÇó£ÿG«í–�~Ðqz=‡{†ýûvÿðÿ)~õiÃ�¿ý¦©î‹f$(·x¡�ýƒòŸOhAúø×Q~õß ÌËþ–�‹í“*�Z-ÚÍæØôð~œû[¸/Þ6Ý äG1Å¿د²ð+oNØ ì/Õ<ºøµIäyìlà?µ(Ÿ!"vÁ©�À�œ%9Bt¢€÷9#}õŒXTU¯b×S_“lžHušH„ŽHRtxoÇ*qíxfåïß“Jð 6AžÎ£áW•õp2k�qd Õcp˜ûîŠQ[yà) `8Wwˇáâßüô/�—@î6ÕÕ„(�åÄ«)òS�sk?ÿ´´vA * ðnóB”ÃüÃÐÝ=ô”ÖNh¡%]‘äâ$�à Àèê×O%x‚l¿Ä`P $¾ ÉêQ~�üêÿ=ªÝqŒ›ñ9žm?P'zt4÷ö0Uñÿú“„,ŒÇe}$‚œ Ì 'ÆSœ: ´û�ĵ�BÊÌÁ6¾-Ñ£Œ{؆èѢ狥ó¼Ý¯Úf'…�Ž6Ý Fœw’ê³Îs Üp#;Ú÷¿×öç^Ï<¾ýæÇàÄxM¯¶n”Œ¬û¾á~ß°ïö}ǶgämG‘l*uw)ZRº¬X× –eñuKQv‚boÑ$#ð/(¹¸2_ì–ætSAÿÄ}\­ßm>3�QF*úhߟ)Ø÷K³Ö¯.#À}êNô�Vÿ�8�VÂåzÅíöb®7\.+RZQœYÝ ¬/-ÐMÝ¡I�R¿ŸR"¤´ - " ¥¬ë N«“ R7Á¶m úŒ¼ïHiñÏ‹ŒâÚœ FbsQQ�»(˜«ƒGä €°,3`Ö¬Y³fÍš5+Ö$Ìš5kÖ¬Y³fÍšõ¨’wÇþjñö×ÀFø ð·ßW•ßI†-;öíTª�wÏ8®æÇ=™šc@E°»Í}x©@Š`08Ð`«îJk"ÎÄϯvÉá|D:f L ¡*[P¬�2x+ ¾°§€÷¶c¬›í´ªu´ÞcSûµeu·×âáÚb½Í¢9ôptX¨.ô€E²FèSé$Š8rˆZ€s05ŒQ¦>‚ä¿AeOÁ£^_2ôm ˆþ�ÿ—„ÿä?þ[®.>WRØ‘ö†¥þ‡A=†S/?ø+�Ïÿ5@¹^kØ�+°‰`JîÄ®¦MÁ¥^C†y6à_璉–7 ¼ºA+à/»ýÑÝÀ`uÉ/%ÅíþÅlâÀÑÀ+”U¤í+Z],kÂVœhDp9ûü9ܤýj €–I·«"˜!�î¥ÞúŸz4AÝ-«ót¿¶_ gªÛú$)Žßó1U5ËþÏÐA*u(íä£3é7�»¯M'‹4x¶ýYrAuB€*>üèwpyù‘­»D!_ÀÁòRI>¯ÈÀ*W',fßO vµ¾,˜“,€^ ew·ˆÍö‡ hékC�»EÔù¼tÊJº´‚ÒÐ+#T7¢�À°Ëú!ÑÕk?ó”^ ŸÿQ˜«|Xˆ´)ÿ¥J«å> äÜ#¸üßÿÕ¥­½_²Ì\€ª�?k[DÿÍã–S8ÿzO òà‡uF‡;ú!އFÒ˜†Uù@XyÐç÷ì•v-UòÅ”"ÿYf­×Ï;®4ÇÆëyw¾ÛÝOú'Wõñþóáã7|‹bÛï6-dǶmx{{Ã}»cßv䜛m=Ðê$W®/KÂe]Íí@ál@ÆÞâG*ð¿7Õ½E$Ü–C³ÉO ðW%,P”Å”ó{Îþ¹4Ç¥D‹‘ Ø\0ªå>�%ªþ�¹,+ØÙy·(„=ïØ¶;òÞ•òëå‚>âÛo¿ÁÇ�ðòò‚õ²‚9·§H"Ñà&PPÊ^ ¡¡ø5òÉ€û×ëÛvEq•~λ-/¥àõõ Û¶;A¢O#=˜_.H˂˲`]V$bˆä� Y°Óf„ˆ’ínÂŒ}Ÿ€Y³fÍš5kÖ¬X“0kÖ¬Y³fÍš5kÖ Ì&@Cý�8®è`S¼ƒñàÒý…Š®¾Zf}5 W¥ äÖ®ži�uj >‚%nh°b95[ûnùßK¡/ƒ(Ðm]ßg“yh¥¨eÊB E†6Gu&�õ<‚(õ3ЈYRo‡>hŽ ŒºÆ¡ÐÕ˜8¸æÜöCÁk¹5[uÈ„”ÿ¡¯4oïcôÞß>øuÏý|àPòÉãK“ï7ÈôýOÿ³¿�ÿä?þ_ òX EðbWm6ã#rF=C½ªéëe¶þ€?´ï¥£”OHן¸5qªùúWû§Û™2Lå_çW1«ÝyƒÈP^yäÍo€Þ�²¹€)ô è± TÅ5q%ã0ÌÖ}AìŠt¥hÉ�€šYí 1ã²$ä²¢î/Þ5Þ?Qm¯t†ÌY1¿�Äû+ ´õz`jó¾ 8œGîãÕ§é{ Zó%,ÛX‰ Ú¢14΋³s¢h¡—<·~ÜÓx5ñAÕÜÖ—opûðSý¹X(m6~6oJ „ …L­ÏвéZºR¿L­_ )Ù>J‚ÒÝú°d�Ö8‰êôà�.lN´²t…Êà D¯F  ˜¯'„‰è`@@ú‹·Ø!ZÀËG‹·¨^ Ê}} u—û·}ŠÚu­…ö?ú/ÝÉÍ ƒðwÿä‚N˜Šd¬“Ùâì©Hj‹V6 êÆCb‰ŽKU˜Ct²îGW›óupŒá‰w¼áÞ4ÜéaÍm./zâ0@½ üPØŸDè{·…w—rÅ»¾zþÁ3NAlçåbD�´ØºWD±çbÛ÷·7ìûnùôíy„Á,�Ô×´- D�¥€˜pßyÛý9ÌbTK{f€^ ‹Ï4ös#râA¡Od‘yIH;#ÃìõÕ�SÀ…Án½¯âÏ)bí`6ÒBZRZ°¬+˜È2J)¸¿Ýñv¿cß7Wî'Ün/øæ›�øæ›oðñã7øðáÒ’ ¢(9�Ó°Þ:P’æ~ÀÂNHˢ!6ÆH7¨ ˆ Ûv7g†œ±7ëÿ>D„´,¸^.¸\ üç”°®\/+/�"H¼AU±mÓà®æòp™ÿ±0kÖ¬Y³fÍšjfÍš5kÖ¬Y³fÍú”ˆ„ü樕 ¶ö±"f”‡t°ìî¹¶Ô¬ê+`þ d}ÿUI·¸Š•,-9€ .¼ vù¸¥‹Ô±Y:´Y®Û#ê9SìËc®Ø¯ ˜"ñ{(Õ ]Œ*µ¨¤GÃ0éDAß]Î[’³Û¿Óp¾}º›Àìv×̧v¶g¹Ò-£Ú\u€¡ƒBð'Pó78²@°Ñà.ñ` ­êsèÑ’úK €¯—z›þóÿÇ?‚(ƒyiëäâêòëá;q²ðÉÉw+…åãßÄþù¡ò+ç ¼@ótcUÝ& "pgçé 'Ü•ÙP_-¦ŠÖ|ÿÝò¿Ü�P Å‘b'h±)u¼•Å'È3ÖÛØ»Í6Â�æìà¯eUGw $ñb@2¯XKÁ¾¿BKöy%Aâ£ÃÇÉF¯®'0bWe¿‡ 8ª‚ž ŒQE® Z#ÝŒè >�D¡g‹ã8·õÌHt:]Û|–“IK4r з­îªÁ²\ðñÛŸX¤Ca€2�ÔÆRàÅè¹®»»�«Š¯¥Àw¨, eƒÊ²\¾¼‚Óâó‚À²´ARe†–À+jÏAÄפìÎ%i3º»íÿ 4¿é¢+¤ƒ_ëyœ‡ËG ÝœYð– ð”_þí‡kPCX|Íjw¶D‹'�ô蘷?è‡X3þÉŸ1~ñyA%ÎèÉ:‡Y¡)ƒ�5¦aFËmèsQåñ±ÿN~ d�ƒÃKµ9�ñ_ôd9[ÃOŒ Nãà˜îóþªOïþ^ŠøsR�”`Ñ_ ÄAÿš5ï¹RÌâ>KÁÚ¬òÉè¼@Øríí™C!ûÖ¾#b…ˆ°`/ÜŸIØ×~"™ª½ÆÔmD˺bÙ3¶}oÏz=²(\B¢(5P»‚™‘8!- KJ¶Ïœíœ\ý{Ãý~o¤�õ²âr¹âz½áz»áz½‚ˆPD@ÌÍÉ©’ D¿—IxþØî±¨¶þ»“º3ϲ&ÜðâQ À¶9gä’‘÷¹ˆÒºúù3Ö‹ ¬+.˨b#F)˲4ǃR ˆ9fÍš5kÖ¬Y³fMÀ¬Y³fÍš5kÖ¬Y?„jª°§Âc:ný©ªÎ`:MwIÕíÊá`_pôÉ»³BŠ5úI.0õxŠPš¯öòœ‰›­ì`i�ö* îûkû¡4ÔžÉmsãÏð>W‰j ^´lãÃ÷[Ÿh°¨n{bíªµþØUÔ”ÂÄŒ¬ ‚Xë*øEòÐ;^€w3Ëñ•– \Á Ùê&ÏÃnMú€¿<’Nèq® û­UÕý}{ŸÇ�;3¼$‡"CI„é@±,˜‘;J$Y‘)A� ±Gù;È ÈÃ��8H p†á8¶K‘dY²ÌP ”DR|S|s4ã!E‘ÔpîÌÜ™¹sï9{ÝUkå�µêÑýõ>çÜøØµûî}öºººª§/ÀÝó{,ëâJyŸ9#Æ©îÒ­‰p‡¢œ2Ö5�Â)Z–ý̰ìúä8#gAN Y ¡ ­Ó̤®Ø¯d0Þ×ñ»®ÉŸí,jÎ$uÙ²>^×ë²`]–!PH Ó¤4!Ä !X¬BvUŨQ£F�5jÔ¨îuÆè‚Q£F�5jÔ¨Q£^—¢¾¿ÂG6¥Í:{'%Wóz5¬ô�—©¼jünÕóò�+�Ë‹o:-Z<“¿wkXkug!ï ¿ݨ,±s8hNÎÍŒ½F 0Uµ›¡Žä$ˆ½º²Ó}ªš+z'ñ^ùïŽű¡öÙ5Þl/ÓµsaØÇlÕ~°P´º-xßPëq…žB=ÚÀ-³ ü×k ¥�ªä‚Û@ÓVáß9DЮŸ^hÝßq>^6l_ü*ÿú¯æ/~þùæk½½¦df£%ÏÝš\I²ÑDõ(s Ì?ù�Çv$³ÊwÂqâEð {‘@)TGB¹ÞvÍ)' ¬€®Ð°€ò �'�ž!áh“; Ì Š>žL­¬™N 7àžúêc ¤6¾°XôEŽßûýe÷�f'€AÀñ±�mvrŒ‚â-tý °q-Ù^«ú;v+uf'C¨÷ aùôOÙô­Ý®øžx®ëT»´ ÚÅ”Ðα…6Àz)S×\mÕƒ‰¾žV™k:н†Å´1MÝÁš‚¿¥ûˆ‚WÎóñõOé–¿z6è¶¹ô·6?8OëCtšm>OqªIzMØöñÖ½£,5_xç `&¼/HɈ31Fœô„"²dû)¥ h‹(Öu©ý8"pcžf0Y$@L)D$¤E”œƒ4ƒK¼ íη{!óäÊèÕq7ð¨àLoûߟCçyg�¿<½Y¿ˆ¢Ð6 öPOµd�›’à¿@Ô-þÓ= ÷þ}ò E2Û÷z]µ·ÚÝ—kÃÞ.€ä7�p\$òYªÚ_ÓêÀ¿8ðïÊt& €)qrõÿ (à?&(9Q" x~Ó#ÂúåϸCˆ¶¾"Ô×9¥ëRéºÔeýRÍ#‚ÀÁu5Ào7HX5ÉAZÉ8ýýX9,P1ûv¼2fä÷lÖñ¸ÖÈ“>2 Ž$ÝÎ å:‡)âÉ“7+iÃNF Ê3&¨[‘ƒHĈ(I�d{¤J«�æÓ ä“�¹é ³EPûÿ„Ôâ0““dœŒ ì®�HTÄǼ]|¥ÈÁ ä.@â Å 2߀ÕÉ*²Ö>MŸÿ�¿|‰ÿ®dÕ³�W07޵d (–Ÿk×¢tñÏ~ŽñÙ÷BÝ5uþfnÁÎ>¿s©`=u++:Ç–=qŠ*  þ[¯.{Ç j·rµŽkGv»š\3AÝg;÷ê+Œã+ÿë|Ÿâ3^–Þ¢/˜óm.Ö+×�âr@/=Âá3�ï¼óBPUäœ,wžLùÏ ’+è�cƲ¤´ú¶Ö'y͸À€øÀÁ@vŽö,â 8nÆý}Ý•zB‹öë>µþ 1#¸ ¿²ˆåÚ/@Š+D,מÙÛ@¡kËÎyNâ¬äK®À¸ˆ`Mدëb䀜<öÀžãT¥�²6–DÛGFûÜ’Mõ¹¿ÇûÏžáÙûïcM…pBzd×�™q∠ӡzBœ¦6ÎÔˆŠYÄÉ +T˲ 0cš"&ï÷óéTÇ y¿ÄèÎD5jÔ¨Q£F�ÕjF�5jÔ¨Q£F�z *„ @+âà¹ÒÌÕ÷UåÉdºà îÒÛ>ckÅ«- `aEõX�ú>¢Ô4Ǫ-§¹Žv±í¸få¯5gZ;g…ÚF…+]ÙX^è‹>¤Óî…95eµ6à†Ø…¿Ô©Pµ«i æ\�³þ·Wí+ 8ºÞ_|÷9¾ýoàwýFH ˆl¹ã°A2ª5¹¢·)ߌŸ®ð túj`ý"�> ð Y/à<X ¼%¸¢¿�.�|È=�ŸÙ÷tÍæ (îElŠéâV ½[†ƒýä©�<%ZÀ@à­Ý¿}™E»NLbtÕÿLgËŠ‡�¶ªìie~ÄÓ‡ÁOg\¾üK<éÕþûùÄÏ©ä´w÷Ì•ËÂîã‚.N½÷ïÊ»ÁÔæ WÇwÎÖvg#�„^�PÀfôwím¿ßº Èþ&ð[,Î3=~ÓsšŘ²#e€ŒBÓÉ®G ŸvƒQ(€²º‚Ö÷!É›B M@X a6BJœ@ùÄÂL““² ÐÉ@E�vìœ îPAgw7Ñ´»Pd¤š€°€p²1#8¾a¯ŸäÎ>Ï�ìûú~YP‰¦NÕöÁ¾—þei×wý"8ø§²¯W üõOMè¹Jº7ùÐí|´›¤ç®65_¶ ÑlÃÿ n®?p–©Ç®ë¬¶UKw@9õ´5ÚF,ƒæŽ`'ÞGÛtxû~õ¹>OÝŽw\§ú<ðÁë¹½õÑÄÿà³åt }÷ÝwcDœ‚ Ý2>´9¿­ãŒ Á—è[ÍÄ l§´bM1LÞnÛw"Dâ÷ï^}ïÏB »CLH>Ãq]Šˆ Àf² estY—é”;⟻ø¶Y2ˆëj¤vÒäÓ<átš1Ïs�Ñ ²¯ë‚´&¤œÀ,Þ eHÎö]²íÁÏÕM‰3U²Å²®¸\î±, ÒººJŸ°.Öyº®3@Ö¾yžk?2iµ6Ýß߃™q¹\ ’±¬+îž?÷Ï› 3Wg#v—#%Ñ Œ5jÔ¨Q£FíjF�5jÔ¨Q£F�z *”—œ{Èô04·©û×Ó}N¯î܃ÕßÌ7#¼ØIS—·¼=Iu`Lº–4â�ÊO¼R3œ‹#ÀU¾²5�o½¼­–ߢ}äsC†´º#l¿oܵ7Î [¥rOt¨jòHß 8sW˜ªª=”´Á€õL»øÕËíýwÿü�àü³¿@¶|sÏEg Dl%é};vJs mdAxôMÐü>€ç¦—Õg¦˜–䣫ñu…Èâjÿòý¹�þùèb }õ�'W`»m:€˜ÍÙ¢Xüà_VX„Àj lɦüÏü;@Š};Ðhš ž"(ØÏ³�µ›3…Û[ûu€Á�ÞÂy~ŒûwHÉE6½Z1®ø¿š °GþK€Ùë0xLNý$äî´Ÿá¶óEu @øúÊoÿqMG‘kivÝFúí÷ä%dh#ly?)¦Ó�Ÿ<¸¸Q(ˆdÍ'`MF®`€5Aué �&&�n(·/C9ˆF(Ibçªbn9²"äÈhš€éä gH˜€;"i Ñ``»,v?5[úœ�„býKµ£Ü┄èæMõšÝþÿ ò{?ÓE9X�¶±#ÝhrmxN…ì~àòsŸ*]hÝLv«|ÿ/ž»q@¹Îýè×tµ% Wz%>&7)%º…ºÙ†¼�È•áè+¶n-ÔÍÝÕ!Æ­Û6Û/kƒ^)î·10úÀsŦX™ÿ û@Y_ÊZPÁñ£­_mЃMŸ=†Ó§¹nên:ÙmÙnz :}úü}�ÞC§[($߃ó½Ý�‹©ÿeµŸ«#À•Å@Zõkã㉈žLá]@XWL‚¤�Ô9ÃTÿ+�þ³å±§dD„$þå¿&ƒ91‚æ ˜&³þgÿ¢d³Ÿ6'ìÜJ�pñ-èö£¸9}î¿ð÷ ébã^ÔH�¶\Yö²Ê^1ëã@öƒæE“—{O¸Ÿú•‰@QE+‚¿!(t®ûÃ¨ßØ¢#¯ˆ¦ø/ݼLê–õÝçIq>�psëà4I%(ºz, 2$ $'°h^A2C§ÁÆ“ÏxF ¢;ç«áã9ûuIÈ”€Àì$”0�ãÅÜ-â™fp˜:¹•?›Ð áDhŽ7çŽB$€"C¹ôµ‚Tl,AÀÓGýò§6æâSÈ»?ÚMH]·L Hþ6—#g‡ ùœ_Ô܆×Ï|ŽñÎ³ÐÆ^Gòê‡ä&…¤NA{÷œ-a �Ôíº¬ 5 ¬uU\¶i@ï èÀy'p¸õŽ:èÖ¼zk€>pÏP�öÑÎàê^ÛLø;H¿8Ù<ÒëÁÚàçLT@ú~ÿÊH_Û�¶5ãrqzB›W‹µ|J .— .—Å2ç}Í/öø!FD·à·¯P×ô”’»Ù�¦8·ç ñGžâVêõÔ �ÈæÞãjõÀ�I@Sîž»¨>÷äBЉæìb >e®T2²8é‹€˜Ì!ŠCÀišq:�A�ëEÍÉ@úûû;¨*RZÍá`Y‘æÕƒ²`]ÖeŲ®X“¹ Ä b® xOî’Pö˜1ŸN~ Ó4ãt:ùù–¾@UìO1bžgœÎgÄ�² †QÅš¬9Ùó�ØqÖeÁ}0€#"3rJPQ01b ÈÉ£F�5jÔ¨Q£J À¨Q£F�5jÔ¨Q¯Ãƒû4AUÒ«¼Þ‡órèÖÿ¡ûèÕ/TãBØ‚XZÀên{Ãô¸*þ‰MíÏÔlm[<¸:6Ù)�N=Ù¶+ùõöË.›™�Émd¹i·›ü¿ƒÅ»ßU€®åÅnc� 8"•ŒÐœØÁlÚS*Ï%ÚÕŽ TÁ®öÖýL 0H¶q7ðŒœ=»½³q§ú½WC·kn¤®¶ÒÚE³S#÷Ní¿ÇgíÍzÜP7ÎtÊl°q¬Ú,ûÐÌ€žpñüî‚?ÿ?‹?þGÿiG• È:£!Pý}ã„€ è¿‘îÚ9ä|úZäËÛ€,ˆfæ Ö¢Ù@ù|çß³•Ö¨6ÿe,ˆbn`?Ü^ZÙ-¢‰M ýe5w�tò Í«Ùý§È’r³�/ÌI€'ÿà š¢9ĦҠìùÑÙÀ¦&Ê& L@8�â-Ÿ€ùpþnNoáòùïE~þL 4ÏÚE[¥ôµR_�7q5´wØþÚvå*xæÍu"sðÏÖÞ`Ôhx$ zu¾oC0ðŽ{k“êp°³ù×#ëolöÕ&?ÂííŒ90DV2@“áÚ¤f8‹LPõ1šÈFâ¼B5ƒ4AuéeWÙ†âèl¼5ÅÎ79./æ !L@ZÀq‚„ / =ƒ� z2Àž Á€z(X$0HªÁ@`*+ì1�4Ï5× ž¾Êˆ-pi¾*ˆŸBï~~»¶ÔhŸ+ÉÚËø±ù�HŸÿÑÍZW¸%ÿñ'O‚v÷+Ôæ-¢£ylg+ó€µ8m&±í²¬}”Н9ýr}­Þ÷Y¸�ŽÑ2¿Q#p#4‚-ø[PN·¸ê&™%ƒÀ–àͨ­7ÜfÊì¾+mNxsô�Cm¨_Á|þ—ŸSZ!2÷« T À_–ÏŸßãþþ"¹ÿó<ƒ9bž&Ä«%}¿æ¥œÁ"®^§ªØG,îB®|'sX)¤"‹í1+ÿ¼逈b# 4'‡6݉¯Ë"ZŸ‰t?-B!’‘’)ðU1dæéš óiÆ$¨(–eÁ²\°.‹¬_.ËÓ2a’ "ëº`]�°¬9„) ŠõM–Œœ’EÀ\¦ù„i†�ûSD ÑÝš €]¶46°>†ˆˆ2+æeÁ4Ϙ#k¬ëj¤ÍX–¤@ÌÙ‰˜…�Ãüûp5jÔ¨Q£F�Ú¼G]0jÔ¨Q£F�5jÔö+„@É^N3í¥«¥:`aÿ»ö—î%üF‘]²Ùh@µìAƒ�’›`ª/{n/×{ucµ.C“÷XlY8xÞ@ùþ[û,;öE™¯×àœª´L^j@ j$ê ÷šo¾‹5PÝ+#›Årk˜À`¨ù™Ûy�X;©;$ÀcÒ;°>; RÔZñX.}Þ[Ýn8 –\�÷ö—¿vñ6Ȥ/ª?öî £6mHÐ&&�öù*õ�6ß"wøþÒã�ÿÑo°¸üt�âË tÄ7:0�„0½³Ã.û ŠÍ_ ¾ÿ4�î�éÆ@~U =ƒæ;³ûÏ‹¡È0`T©XC3ˆƒÙüƒý{þÕìþ³7ÇjŸ#h^ÌQ ­Ð”šÝZMé�ó–‚å_Ǹ³ü÷ï˜LužÍjûs�Æ,Ö àÙ”ÿñ1ƒÃ Þ4�YpóÖïÅå‹ß�åKŸ²S­C„¶À?ŠªhV!„¼I4Ù“š°¹F¢éîwÀa£r…¨Gˆƒd Ø/ªöþS/ánÇh�ìݽEÆßyÁ= ²sL!6}°ûõfžêõThŒ±ÀjöúäCQ£ÏyFqsHa0–æ–¢fp¡0q&2‹|??Íž ž’ÏáÉÉ€hrK2' ]­ma�3,+šý„9ØÉ ÙIM¡þ… PËo¿ÞJðŒß }þ¯5‡UËgPؘ§g<6÷³i3€U€ïÿ¥›ŽÐÓÍÓ]ʇvSÇ~*yp)é×´~•í±žÈ†.@Ý@»OjÏ0Û¯'»Û§�ËèÊ¡Àÿ./œM7íÔ>¡D (9˜¯WŸ¤Žø¢xqÆúCtDãHPcðìâèáåzZ8 ( û@à` zZ–å‚çÏïñìÙûX–‹ƒåÓld�iŠ˜¦ Ó4#Ä¢üoñ@’2”<" ’ȉAv +ù‘¸¹©"'#!¨Ø¸6 Übh�rFöcšëÇÖ=…¨¸س�Ímæ°.‹¹ÅŒ¸䜠BˆˆÑzuYœNgÄ8ƒˆ°¬ èîïO'#>0#Ï'@Êî6$Õâåew‡ÝÙg)wÇ®ê{äjÝ|݇]{€ Æw™•„П;\áfBfîÈZ$À¤Òn_=¦Y¯­`§¨%ñ ð_~VÝX4àz >Žâ!ï+׿óé&<Ì{Ѷ~à‡ÿ>ýÙ÷ñ±¯š  ^• à ÿ*àJ³«¿ã-(>âàé1ÀO€p¶íd…FàôÑoE8î>ýC ,ML;›ÿ.“[ä%cf�pÓ”ü¸Sì§*‡Ûs¯ü/s Z¦½>�Šâ2íwMÍö�·LªÀv¦)â<±;C¸#…(�Äâ   LîaÊb"«Í±,2Š©~±.à:W(ˆ‘ È%†N+‘ à%§ÕÚ^ÆJÊ@Çš¡02 â Ä È2OÕqÅî•òͯg&(‹Yþgö¾` 'tû5@|ì÷N¶öÅ7 Ë«kŒ1ØúßcKt£üGc„uó§®ïYFoÊÀÀwþÜ„ËJ�$Ñ“ ´Ím Èô/+ Qq¾é€ÿnÊ==½%¿*5½|N%­‘0Ú¢ÆëtöÿÇÐÿ~I9¸�´S˜K§êßݦ�‹Ìì×€¼>x»|°§�6þ•þ ª3!†`Ž@dÀûº^p�çÏŸáþþëšÌòŸB˜\ùã„8™ „¾ òØ uñþìç)b² {˜�>`ókÎE-�ê�â 6¥5!§„Õçó²æ1³‘æÓ4cŠ˜ÙHAd`xÊ©‚ñkNH9A5ÛÜBN’ b›!³d,ËŠ”2ˆKÎ7ÌŒœ²;HŽYÛØÉŠÅÁ1 DÔH1â|ºÁÍÍÓdq)%\–zw�ìëKùÊ¢H)ãr¹€C€GƒlŽ!ÄݵÅܤ¸s{QFãòœÆü5jÔ¨Q£F�:ªA5jÔ¨Q£F�5êõ("C˜»7�Ô½Á?ÿ7XÊöåyŸy�à®Ù÷»I|U´Ë˜/&ÕcE—êV‰nä®=í¥mÍß%25k1¦ï•ì»ÓÛËUÖ[û‹ Âà 5Ô œ.1¸@}]†tQÂBC=/TÑm»][z+æ^ýYr’ó5€T•ûEY wVhN µ¯Å�½óCö”ÿ©�PøÀöûEÅÚ÷Uã©vJχ®þ¾¹‡xS±[ÆC¼t½¨âßü³ß…åö{,Nœ"€aFÐ €GNèÀÿÀÞ¦€*“ø_þ{úpþZhzÇ�ðf¨°ǽs‹ÔX›í™·ÔÚ‘TW§žU"ÍØÌÇ-:`ÏÓŸ£îÎÇkB÷hò€3ÌU0[U‘sº.¸¿¿Ãr¹`] (�1 NN§3N§“«ÕÃn]i¬ŠþHÅ;Òj"Ö§�4¨ÝcÁX2²ßß¶ÎîCŠ“E ¬+@„%­X×iI¦àwÕ{œŒ@tš'L§ Ól„RBÎì$EVKFNÙ\Öa HËŠËå‚e½`].X–Ërq‡!Ÿn¼ÏæùdÇ�'�-Å] ˆŒ<ÁD� ‘‚Ý¿!N¸9Ÿq>ß`š'ˆ–‹Ç ¬ÙIä}Í5†À¢," ç„å²Bs‰Kˆ¾½ßIþ|È…4‡¹@Å}Aòø £F�5jÔ¨Q] À¨Q£F�5jÔ¨Q¯A‰D¤@Ê=¦|­  {±€s4üŸÚÊ‹ü¨0A5?™êöâÊTíÔµVìV­è�rÿn{‘Ø�'p…¤^eÝkŸ3^;aºgikk=ßo€ÎM ×Œ­¥·v¶Éž¶¨î¨’È@»Ï,WµëïЄfÛõU[ ,UÁETÛòÀìÑ®& ûµè©;Y¬z„@£ IwêÿÆá ¹%P[÷Ó.ó[üo€ÿÄGõ€°s& úÏüþåÿéïCpÐPhò ¹Þýó�wíìlæ=Äÿ€Û¯Þ{וú„[»ë—ž °È%b€ަÀ§Î‚žÄÉ&fû/rqÕÿMwÀº˜•{Þ)þûì¶™ÙÀÚ@q6Ç�hÊrSm34“ÉY¡©�éªôæ�Â`z Žoá‘ýžØ�@õö6 OoâÑ7ü¤ç?�ûÏ}4]Àª�’c]„ùÊ?|Õ›*ß\:²‡ÀÆžC èßmRmû SގξZzû|5Á¶톋PM7ˆsÄù<ƒb ™'fhNL0E?Š*¸'˜¸š_'ÚP"j·ùõ¸V^¤“Ý“½â15,CC!æø|Á ¦Ô¬ÈkäƒÍAP§†²��02Ù¸�³ÅFPD%»‘©ǸýF€žÂ5 æ€ñšÞÒ»>nË5`ß]O™b·_o!uN[ÞÞ #~þ Œÿô³§º u ]yÿccÑÿ�xØšHµ… mj@{ïÓ¶Flp— âzü-‰ ÛhŠÎ@¯á~×ÏÓþ»¶¶ìZ]yPÈ[ØeuD€M¶ÁC†ôÚ½ÃéÛvêõ\�Íþ‚:f¬ø_l÷3RZ°,+ÖuÅšVˆB8Í'ÜÞÞâæÆ1N`Ÿÿ³s<Úþ*¨À,ú��e5÷4pfÌÚHÌ´}.£þIÂÉjªxS¾'±8—b•ÏÄÌ‘1Å€LkN! B�’PÉÈyÁ²\j'.—ÏŸ=ÃýÝ�–ë²"‹ãî. ÆqŠî80#ƸéîuM &ÄM•ïÏ"1ä�¤Øœ¦àN ÓB@œDŒ`ÏyæÚ’³ g#Ee¤uEö[–ÝQÊ£qŠ;T¥Rö.Uä0jhÔ¨Q£F�5ê?ï5£F�5jÔ¨Q£F½eö¨¹D4÷û+ðÿÄ?¶T¶6~ûH³(ömšÕ²n^ºØd´Šçت檒%l_Ô¶¬VÚ4ûR@™:Ì¡™6oìé7€ù6V `1L„3¯TEY9?TÝ”ËJMXq“’…«Û~(m¿êDÀT²¹;V�©öÿþjô·¿uE3Šý?5Þ„>�¤¼Ë î3Ÿ{Ëór/pàß�)ū췹J PÅ«ØEF¼¸šU÷çÞyþ;~ÿâïÿþU€ÈNÑîW¥~ß6lÀÿ«vÅ7�ÓG¡ë—ý7M†¦/�Ø¥•Ú€~"ÜÀ –êo/X<ƒ}�¦ �/ÐÕ¬ÿÍ è+Ùmä½7à?¸B;NnµÞÀÕ�Üå 4[Ô�Ás–ÍNÑÁÿøˆOÀñ©�ÿ�ò5Ç^º®‰þùÓ‡~+¦} –Ïÿî¿ðà”*(£\Ó> ru¡myÙ8ÚR•Ä é¶“ÇÈ”\¯c›(‹S½ßèv”BPè•ÊýÜÈM¸_ïˆ?‹9!PnÎ!Éû•�@ÐÌ 6åpµ(P'$¿Ï‰@ÂÐÀfåH'o±'ˆ‘<&¤òŽ¢B54†1(„¦„wОS²u"€Ç‰±)XÀÂPÎ@Læ"�ldwpbKU¹;@ÏŒðô›�4"«m& ¾�üÙ¿ì+v! %±ë!ÁOVÐ;5”9mù‡ß‡Nn�rØ¿øÓgs=h²sué¢Qöö�»Lý™öÛ}\ÏfݹímuQµù½€îÝgi¿¶Òn-—í"SˆÚV�¨é×-ݬT gÛD_8!_=)´u½ã�i}ˆÐm[¯æòÝ�âeê¼LÇpÝ4v’�ê’ÿëâ ²uXŒ§ó···8ŸÏ˜¦¹Úð7§!9XV hd5ÇžÜYï«„ësQðçœfª_Šh<¾¤\Q›ß³fd1~Qsûh±E %1¾L`Ä)"çXûU¡XsÆýýÅâ²à²\ðüÙ3<þ뺘[PíuEJbÏ–kBž3B�êˆPâœB `P�N!zÜ#Q2wƒBÄA&ñg�1ˆ±3ʘV-„ »è}ô±=·5¢&�ƒ94;éAê3Tv�Q£F�5jÔ¨Q­`Ô¨Q£F�5jԨנRÎ”× Éʇ/©½¨Ã€©SF?2О [xº’ôµ:6Jy‘ìv®RA'vུ�9\e 7Õd±HÞ¶•h«P¯ ¶öJ;ÚL˜ÛœÈA{v¢AÓ¹*èj9»íH¥SÐwç_Nˆ:EpAÕ�¨@( [÷ÕmÖ¬‘K{Z›Àb@ Ûä60ˆ¶àþ&㺻æ‰Ùˆ/µ*%¢¡ôecêòZd:uŽØ‚ë/£¼Àë/ÍùmŸûüÛÿâïûMÈr±kŸ€ À N[ðlVê(䀴Qó ï†&Ðü1h^YÊæpók�ßnÛrU“¡”ê ˆÉÀÅ€t¬€&¨^€´8ør‚¦äªÿ¼µûÌꟃ‘ØlÚ)˜…?qp²�·Wƒ�‹ÈÆòß.�“ø Ä[`z Ä7Àñ1;øÜÍf±,ÞþKs…à€Ï Š8½õ»1=ýÜ}æo"ùØ#{ÈÆ“ç<44ÈÉÄ[+tu[Êlêé\'Èb<°Sà5´ÿ ¤l·ø'‰ƒxîß®­ùÃÏ0“Øhrg­*ùzzìÇt Hд�"Qv«ì)ÊB#9CÌÆ;­m sšlc ’"â|†RçÜbÔ� 4{Ô@³í³g4&Ghˆ6îÀNºP33øö·üÄÁãIˆŸ@—ÏË?²Ø†Ãàg¥ìómæ� êí÷Ø„š[\~æ:àRž_€¿öÉ¿”×óËv½9 ¼ífvrØîÓ»¢]´M·^B�cì¼’ZžÄΙ¿#³Õãõî.tÀ®Ú®R Ø> ]Ñ&ÜäpN¦ã©u·æ¼l*ÞÒÔ®H6úâ«a—Ì)z¼ê„T Ð^VSÿW5y˜â„y>ažģ¦+ø¯ £NóäQ)NÒƒ´ÈÉÈY�$Õu4Æ9¯P�h«Ù¾Š•}Ó<™Ò~ŠÈ)ƒy­×È\�2 ¦¼_Ò‚u]ÜÉ ùyÂùyš|~²¶§Õp]’2–å‚çwwX³ãç0Ï3Š'L1€™ë±->¡2²9OUÕ~yNab›£8ƒœH–%ƒ×´�<";÷ º!æ×Û—gs&ɉ�³Ôsj�ª íÙQÅ®KÎ)g¤”�Ó Œ5jÔ¨Q£Fõ5£F�5jÔ¨Q£F½•WAN+T]Òôîþ›WæååjyÏNðW *mÓãË^пŒ¯*~퇭‚ÐUíöò6»E=U0Î@l·úïÕðÕNÙri•ÝÂyZìAíö±ë�Ò®.¢ ·ÿ·oÍB–‰; ÐP%&v‚�î Ê© _‹ZŸ°� Õm @7°ïZû5{TUЇ˜ R"d×®ìÄÄ'í Å:U�_y Å’¸Ý{«ý:¦Ž,øw£¦4Ui«fU'a¼ŒGpm9ÝrèÜ3?ñÓ¿„¿û÷>…æŸüZ'Qx_!£yhô2b ÛV4‹ïŽ, ˆ…§P}×så'¨Ì Ó×é³]h¸ž$p†©è/¶Ÿ|�ÊbÙëùH«ÿ’M‘í¹ï›kSÀÿ ì�Üö?LÕ ]�hŸÍ¦–Ü‚ÿNàÙÀÿøߨ*ÿK½fs P'-~DÏ�:�èl€°$Ðù«pû_úïàôü—pyûoay÷¼}v/"ª\‰Plƒ·A�+d-óGÄYûQ_í婉º¥ÿµâÁî½ê‰ƒÐ¢Ýó Üv^‘³)ÒsÊU5_¬ãK¦¼ÙÐs§r÷˜ nœˆ*T2 ) h@ÍÈ€ïœÍÆ¿¨÷M¯®þg_Lµ?OÓÃ"B\s¯@�{¯+ÖË‚ûûçó‚išQ\ ‘rr ~ Uær±sO9c]¬ËR#æ“YüÓ�1�#;øŸ* `ug�1�…!b7ž²§H� *$E¦PŸ˜-Ê@Cªƒ�9Øõh“qÎ+3°Ø“sÞ�ÈXYæE#ú¯ëŠu1‚D€Q£F�5jÔ¨M À¨Q£F�5jÔ¨Q¯Aå,H)CTìå4Š™õÖö½·x§kûA;•�S틘;ƒ[Íó“ßnÇ ¢þg ž¡Ë¯ë?jÖÿPs7qu?9à,åš÷÷cá³ãþ“jo±ÔȺyþÂOßú4ù �I•LÛYL{³ˆƒÅ°¦ë• ΠîÇëFÊ¿Qó£s›¡ž`R=l- º¬íû†è+|šØ:ôÏ­ôМûÒO¾ÄAæ`Ǻ»/Éï©~Œ„\=/H9A$¹‰#Æ&˨çÀu;ñˆv¢MOÈ9AÙâŒé‚jÔ€�U»¢j ô5¹ßœDí!ˆ)€#Ä€)ÄiÂ'w X‚ Пg$g¤œªÀ²®®¨7 þBd±œ{ªäÿlJ1LjÈH#�1MæyÆ4ÍÕ !gõ‹ƒBJ+T´öoé»òÌTÔ÷ê$¤êaÐ=¯™º¿Æ>±"ÿ§i²ë*¦æçåâîHF&Uµß[lF®äÖìàÿ²,XÖÕrÿgaÔ¨Q£F�5ª«A5jÔ¨Q£F�5ê5(QÑ,R3a¯@jÂÉö»cõüKkó†kõ_‰®BÛ$t>ÞDÚìö½ùtèZ/*õåÆÁ»(ùi¤×Ða³é¶ˆkn$tqØWÎòÔ9ós‹èð¦øsõhmƒn2¥ë÷ÖœCûÚGdî¡aÌèòâËèîÏV´*š+a…x`qJz@~`·Oîb T�˜ûþÝÊp:tçoÀÎ5GhXÍV½Ùó;²v&Ò Ä~�á[¶ÿ¾ü9üâ§ßÅ×죔1xÚ¥Éw*dYwŽ{�Ï{+>ø @¾€Aa6 ôó7@îþ¾”›W9ÿåM÷Ð|1åÿzÒêvÿÒ€ÿþöu%7»êßÀÿî{ˆÖƒ°7Ù»f5�Y,oÞ.�;„30=2åÿô!0w¶ÿ4Ù¾²X¡’¬ýÈîÚN üg Ì žübº‹‚š½}énÞÂͯùC8ç Ò»?ƒûw ¸¼c÷R.ا¶tÚMIäÀuþ!y7.Š*œÂFÖa=šß¯÷�2I™vˆ„óyBˆnSOj�ìvû"ú[ÿkÎm6«À~€F'ÈA€äÑYJSe7@% D`jÞ[€Xª„*¸ÎCÐhÎà’Á¢¸ñ·œÈãTæx”L.nþEw�Ðh/ Ðô&£ß`c]²“šÎ@üäí¿€�òŸÈÀÿÝýîY8˜Ä Ï~ÔÏú;_l³¿ús>÷~Øp“zR‘¨Î±[⮚±�Mºµæ 5çzÑló'íÔüý¢çóõ±ÿŽîVBý ŸŒºUr×7Mé8º™ë®¹wé×ÝÓèQ'ê¯ÂÓ�žS¿,ô€tN;Ù'�g×G¹Eë²30ù pàê¼Sã~² Q#±ö‚˜ÃÆš���$»ó‘)Ò+ KuãVç�\ŸWP@GEëšÓ1¸®>@;ù¿à8×ë„!ÝŸlY3�ŽÐwÒ ˆ^ÇQ `/jô’oÏ0å?3bœ|MÈ`^�Ï€&ÃÆp ÁÖ|V›S+ñ0˜j=Ú\«0ÛÄQÌ} ƒý&–,[�òLÄ|£ÃlQ!o¿ýÛž§¸{Þ_sõåŒÍ10Øíô­/NPŽW 9‘Á VÿL6rEH1Të~*÷~‰v9zŽëYÈ !„0až&̧٧e‹XÜ•‰9€9{j� 9ȯð˜)#^ˆÍQÁ‰£F�5jÔ¨Q£Z À¨Q£F�5jÔ¨Q¯A‘EB#P 5¥sûC·QŸ�ÜÇ,wªKÚ½˜-0S¯xÖm¸€ßÔiÍÂÝ÷ {«x6LZíõ™ÛDìåuË÷QÔÚk¢xÞE tÇ•¢�w»j!PŒ­Í\³e¯�ƒk´£� V³,ç¶*Ø àákSÜŠŸ“çˆp®¶SkLTª½7€JŠh¶ÿ��ƒ4;l#H#<”=P##T Â> šzX_wWP,jÔÒ/zè^p�7¨nR ¨+}ikÓ~üâ�H€~ÇÔþÕ¿ùSøòûÿÞxã)�ä ¦ª 7Ž€¦VïŠû}16Ô†rÒñ0½ \ÞAñ ÄáÑ7#½ó‹pk €rSü§{ ]LùŸd]�$F èmìQÀÿÄ ˜"¨#ؽœ¤àý,0˃‘³¹p¹ß"f`~Ä7@ÓSpü��ÿáÜ”áWà¿ß3(œºâÉÈ‹ šÍø_Ü¢õ¡R;7Âí×!ܼ…³þ¤çŸFzïXßÿy¬ïÖUöܨ½í·–û@ºß›­~um'òä†#9sQÇêÖv=Dœ¦ Ó9@Å=æËµÉ€RpëöÄ3 0 ]SG(Q&ÊìçÍ@00O£‘ Tìà–hV³ÓVŸ‰ œ'”#(vñpÒ¤ä�X,�´9à ֘¸‹ ²�e†rR‹9²‘ l2ôù…Aª�`.L zã›@ó‡,Ú‚&#…ø5ÏŸû�º{Ì'�B°ÑÝ Q¢&ª«‹÷áÝ�Ù.<Ñ yÀ~:âSŸŸÑ»°Ñ éesEÖëÀîæskDÞ-G„=äΞ-¸oŽCͨg·¹îWb�J0——C‚ësõI¶8©¶®;�à /ì¥#è¾=nèáöý_þOxÊé•Ò‡UÉ{Y* (ë™!Dsîðg�”’¯]TÁæÍi# A,nì„8ELSs„"ƒÉÈ9K}Wê²@�ݳ@E,îB¢õ÷5ÈùÓ1ŸN8�Ϙ¦XU÷v¹s(ºî5#�vkXDV›¨‹jîEU/5F çŒ,î:åáJ§c@œ"O fDwظ4iOJlëïXÏÕˆ—T®Tœ¹^Û”3Öuõ>Ï›k§ÉÈ ƒ0jÔ¨Q£F�µ©A5jÔ¨Q£F�5ê5(€Ï~-ïXwæÁ´Í2®Ð:5­*2tñÂZuÚGŠÅ†ÉÓ.•U�^0Èb%Û[Ó6Õ¾4{ ìÅwË÷n+U;]ª,P”îÚeb‹¨¿tWDÞ¾To=RÀîÎÚz£Ð+@·q˜e_ŲÙÁð88”¨ŠW«‹ø&ÓW…¢­/âÝÁ½ )ߥ�(™º†‘B„«r\knüNÓß紋Юo…@FïbПԶ^Øëq‚îüÕqŠÞ�×B4¹¿OøWþõ¿…?ù¿ÿV Duqovúá )éˆ0¼W+ <À½� 4½é~äì‘+ÀÂù7@î~ÜÀI¦§‹ŠåN‡à?ñü“¹7e½aDU�ä÷ZêÀ dûá4=âÐôáÆ@|šüŒü×ÕÎE€ì}@<tBÿ'FÅ@ÿB¨Þû|S:tÐÏYM½o>Šxú0ÎùmÈù½|éîm¤åsÐûw�Ö/ûuèl&ÊÄì¢kÚfJ�»_P<’�k�ãdàà4câ #@böô9wjæÎE @RU򠯿FB²Ç'ÈÆÞ2’’‚Š¢Ì2ß­ö� Œ¤RÜT@МÀ m~sø–}7ÈÉœ Ë)g8÷“�7«�ÓâÉœdPˆÍÅ�œ!¥£u@¯¢í^ 3âG~§�9;÷x:½ ùÒ�Úy«ñ}ÖB½ïe7i–IÁîÅ»Ÿ}׌)Šk�«®ÿ�¼í€önŽ}(¨þ@9®nˆ¢¿Ü�LpR>Ñ9¿ì¦3¢êiQÿ°�8‚éWæS[µ³è§}F†_\½Ù¥¶5ÅuàHõß'ôÙ,W9-Zm~ïÚCûµG;ÂW³ñ‚uãÁßÐá“«M~H]åž]¥Ÿ² ñiœ ”N�¥{æ@¬#à-DÕ2ëí™l…–i©Vôz}¬€œ‘S†�`M+rN•DHDˆÑ§Ó··�ðèö§óó4Õç™bó_>×íÌl×—BÎu—‘œrµÔïÑÁ:^Û[\:¬ÜŽ£@„)Äê´@LÂgéÏÀ…˜Ñb”T¥º ¤”°. rN�PÙ©úÕ‰i]Í-…Œˆp>Ÿ,ΠëŸQ£F�5jÔ¨QVƒ0jÔ¨Q£F�5jÔëP p ‘‰z5åþeø&÷¾W –WñºUáÕ·–Ã/z�ºwl'ÕjK],^+øï(Ê.‘Ì—Ü{>T¤Ug‚Î!` 4ìäè�'~Ÿoíõ—ÍÄ®.Ý+ÔQ s*wë|w©NLÍY Xw°@Õ\”¬_zŒ‹¼Í…v—aSZµ™æ°Í‹¶Lb8(P¡@øuȹ²×n}ã©ØÃWÍqè»tùðÀÙ8](½†ÕðÂ1G×¹ÞG.ÙÐ •eðüÅ¿ü¿ø½xúô‘©î5�!Ð@á@nœ ÞÓ\özÖ�åw¸�¿º|ÈÏÍêŸôè7wŸ€¬Ÿ7Ÿè|ïªÿì–ÿnÏ_øgWþ—œõè ˆ;ðß;BÜ"Zòàs†šÙ@{žAñÀO@ñ ˜üg€Bÿ5!!;ø¯þS0«ÿpkŸá³½RààêðdÊ]`‘N¤ þ'…± mÿRŽc™ÓNÀí7">úµ~#^�×çÐûÏBÖ/ ¯ïAÓ °Eˆ$hZ œÐÐ[6 �MµËD`Dp°ãÛèK¾×ëž ì7~°¡@ÐÜ¢=šã›U8±“¤Á#NÄw²€Jv� 2'�@0‹}'‰� �iíî“ ÊæüfPŒ6ïÂ8¼ÏÃâ´ ‚ˆ* ­¤PˆNF®¢H@f(eP&(esbÉ ‚¤lDŠâNëêð±ß„7ìk²ë‚Þý Òçÿ€`ûûõÁÎlÃç¦~¾(ŽP¤/üàæÖ+?û™ˆýG·�£Û{²7‹ØâØû÷€ô¦­MF"âŽ(E ÿ¯kM›©û¹‚¶4¼~f½^·®æ±ƒ_T#ºúœösv×Wõ¸ÔÖƒ²½ZC·óf%tküž J/l~sÐ]¯?ðÒcH·9¿‹Ið’ª\Ïu=g˜æ SŒ�!~¥5¹[×õ؀戔ÌZ .ÄC0…y Ì•ÛSŸMvñ;•Ôç±D¥²ƒð - "¬ËŠÅUí…¸CDˆ�=“'�qûèΧs=ÏœV·èod?ïíúü¤ õŸüOkÂr¹ IF €”r¾Áé,˜JL@çPÖz©Ï?ìk@'Ìä Œ�haN Í‘!%#”Á#Êy¬ËÅÜxAÅbÖuEJÙÜT»ç7Vóç-U{>�N¸½}„ÛÛGˆÓx½=jÔ¨Q£F�µ¯ñ„4jÔ¨Q£F�5jÔkPGWÄïqÉŒJGଃº±à- ÷îß»c_�´ðWŠ}Ë­¥ Ä—˜{�»qYVybÕëÕ)軯Çâ–¬dÄ ñVðZ^;å¡ü`½†ë¯�_06üz\Aå[FÀæ"éW|Oàªo÷£»üüìù‚ÿÃÿý¯ãÿò¿ùƒ€Ü L`¹@Ó—Áá1ÌAf«ôm.¥íb §$ œLå�/6ÆÂ @ü¡ß ùôŸ…JQý¯þ÷À?Ðÿ̈fó_ìþë÷²]¹·×“ÛÔ˜’�õâb$‹j×…êdX=‚ñ2 !tì2�28$ÀO¨D(<ùÂãÿ²“=Ð ˜#(|ë§ÿ´ýžÌ= ~î辪w,mÀfÂåã+hò!R’2ðoý­Gż߿> ßë´ÛHÛ¹¬û¿Š®«mn•nŽí‡÷UC6‡~À@q¥ž¯‰(ëj\ u눢sjÙߢökÖ fô üû%éÜ&®] öæ¯ý¡[Èÿð"®F»õGQI/ýE¤ºñ”u:„€)FLÓfFÎkJDo:`1Èœ–´¸±‘ì8°}̦>§ŒäVô-¨ÖÌ;+|iÀwJk�û—uÅr¹à²,K`mŸ¦ 777¸¹½ÅÍÍ æi²ã] ü_.¤”®ŽgßÙçQ5ž ÁHËŠ»Ë벂ˆqö5‚ˆ “"†°Þ‹ú?çìJã�E6µ щUvÌæÙ¬øÍEÄ®AZíz¥”±¦ì1 Í© ’«ÿËÒØ“FËš|Þ;ŸÏ¸¹¹Áã'Oðèö!„ÿ0jÔ¨Q£F�5ÊjF�5jÔ¨Q£F�z-J@ˆUCÛªW|w6¿M¦Ø2Ýw„�m #쬅+&­]N=*È\­ìÑ^èö"ý¢<-.vœ­òŸ]ÑÜ,·»8Ý[X @ÉÒ.–ú@¯®WWå‘ÇO€ÛãV%où²û l”‘U±¦}‚²vjPÏpv0¾Wൈ…Öxò“¬ª{ß[ù½º£»+ U79Ùt#P�­´v¨öu³ùo¹Í=`´Sû·ì‚NÝÚךýü?Ú¤#Y|PÐ_¯uÕ&êÿ¨×‰ÕÿþŸÿü¯ÿÇ¿ ~ó é‚L ¢.†¬†©;´€ê½XÿÞ÷ñô& w¨*w½€â Û_ýÒOBRR2e~‘1W»>þÁÑ”ÚUù ³û¯Vø Mž±šr¼Ž_b‹ àþ?¦'üˆEù}œ �)ÐÎÆ_ü>#‹Ýñ 'ËzG@Sò¯öfÞQ€ó®ýµÿ²÷Aé‹þwDÞÍvê$½XÆ=�üzónžr2�¬]Þ¼‚4A]ù¯}<‚@]íßÝ6_D%S±×v¨©V��áçŒè@ œÁ9'«Å‰$êY¬¿‹’Ñ¢4¢z‰gû.)£3$·ÓŒðþ4WL l,Ð.§ÂÁpûî”VÃéµåË+Ôœ%¨�ØÉîÀÙb 8@3œÁ"�œ�0áô5¿Ç®1“G¦€ŸBÞÿIèó_D!m©#÷šÝm`ãJâ�±é{°|æ{à‰Æ¿¶ÙOýbÄ÷ýâmR·Ô5=œ'ööàÂX¹‡;Buëbû¹'S5,_Kl‹Rsè”ôWó'5âÂ[ª;Ö~•.dw{ÙÛñì=¨6ËÜÝ¿Uç´²¤\ø:¿}ÖÐÙsáÈ�åÎùG1ÝsG}:ê²ëkOqSö3³k|ñ\ûLä§”À‹¹mL:Ù¸*œ"�šz='›_×uÁ²¬¦ÄÏ a¦vÌ8Mæ"àŽAõÙ§ko1ðÿrÁåþÞòíSªÏ•Àà®/ª©)ù—ÅAtÛ®)HDÝÑÅ÷yÁårÁ²\À`@‘Íـݵɞ… ôÏÒÅÝ)ƈùtÂ|š=�7ĘÂd® ðX†°$ÜCÝÚ?!çŒ%%'aµ>ZªV©v]s�`.8!ÜÞÞâñã'xüèÎ77€uYÆÿU5jÔ¨Q£F�êjF�5jÔ¨Q£F�z ª(ȶ¿Ä5º@Û6/Ñ·rº– PÀqÀ•õ»ƒhe¿¶y0÷‡QW“õ ú²5WðŸMe×瀩«ousšU9»ÿPѨÚZÕfÚ":�_UŒ°³W¦î¤Ô‘”¯PÉÊügj@þFéÚ +ËñÕIÅR»×뛥ú>šv׸ý–v䂺aŸ!­¥ݾ{§hu¸êËz`=°Þ§z�ö)ÍÚû_Ç oÆÐá‘�}ìÎÛ”�®ž=_ð¿ûS߉ã_ýƒ@¾Àˆ|ôä÷þ�oÉØDfÔô w¶%2€oAÓWC×w, À??ô;±~ùçyÇîãüg6Õ8Rý•+8ëó€…¸ï*g™snוØöN xãàÿS„ø†+ÿü‡ƒÿšM5¯ f×ìÀq ÿÃäàÿ Îþûçí³‹E”ÏÖ~q�šBÉüpÕ½ƒþR¶ï”ÿ ²pûJ0R‚hnº 2²�Dç줄ä×Ή~¬êR ÙÿæŽ ™€BààW>x¦6™ò_´µIÚ‚ˆ¸Ùô¶¨“< ¹+Bµ%)×ÊAœ¢ÁÏA `,Ž©š&�",ÁrØc,¼ªš³ÎpC†2Þľ}ÅMêôº8oW Ÿ3Ô,ü½­š“Q;Þú¯�æ¯óñVî… Ï‘ÞþÿV6×FÝq·­Fm¢ÐFTʶíån@‘üíÕj܈?ùWŸ@r HéÁýÆ>»ŠŒ¹Z$[œKYW¤Ø¦÷Šî:Äh‡gïæ#ÅFe-ýßø[·‘²‹-]lc³S¦-¶þúë¥íÅá‚”J/^ÍÙu\×ëX ïžÔaàማMeôOf÷ì#º}Æèû�¶+qûK1œP³åOdv9%û™+@ðq,Y ¬9;p‡ûË’2B´¹°€ÿ“ÿ;e'³÷—âØéÀ�ü»»{æ/¬)y\�[*ž-:`]±®Ku2`fð™B¬Ï!voÛÜ$þ –³ §I%5�_è— Vöí2rJHɈ’ÅìýcÄétÆÍÍ-æól®(·y¹ßL¡8Úó�?ûŰxÔHNËrAJ«Ÿ§Å p%l¡Ak»Í¥%0ƒO3˜Ó<ãñãÇxôè§óSŒFrÿWaÔ¨Q£F�5jSƒ0jÔ¨Q£F�5jÔkP" ¦cÛöú.¼ÿ¯ñ¤ý{¥xý]ý¤;hg‘N;U>u¶äå«þ³HÄ\•ršÀ•:E¾òD®uedþ©~Ö^ä³µÏ# ñAüE8õŽèãá›S€:°ZT�àG—‹Ûí† xWOŸ²´á<…4P®iw|]c!â ]‚÷Å�…òæôÎ.gš®AzÀˆÖ í"ô±xO½ñÚöózyíò¤AG<ÚjÛöƒìnìU©×.î?úaükÿ«ÿÞx<³^€|�Î ˆo 0,ûäÖO%Î8ñH_´_R´ Nˆ_óû‘ÿáŸîrµÉÀÿÁ1˜§F(~Ë´³Ki@"Ï¢7Åx%pþŸ�é±)ÿ£Ûþ³ÙþWë~ð‹å?ÔXb{e@ GþÓ@Qÿ»ôYWWÿ»í|¯þG4ð›\ 8Ñ@Õ¾WÇ W¶#˜T]Ð¶Ñ ©ÖþÜò1г‡"öwðÙ*�©s^¨_bŽ®¼W&³è�eŸ~­Õñul‹Y¡$ Év½:ÄàR㎰á~ÜJH9ŽŸoŒFýÑ K@ù¼“hÝ*²‰ ì*Pý[9ár,•Á‰ ¢€®Ø1쮳ø�BB@‰8!òë¡–eî†ø¤ ºýõOÿ)çÁÝ!fÐô&ÒÛßný¦½½¿^)Ü7ÑeBô|qbÅý§¾¯ÞVJ�+òÝ?7áÇ?=µ}«4Ëún!4 Ô ú÷ä7¢ã Œ¶Ò~¢â¿Àm+ÚÍLûys§è·¾õ6±Û΃6«kë£nÝ¥£%�šý¿¶ðÝÍ’Ô5K¯¦ÂÆà«}DGÀ~G t*íƒ5æÔËbeŽ×‡ë¿i×Wf/�{�G©¹}T !Û³G@œ `ž’©Ó‰í¹"„ˆ¨˜¼ŸD‘%c]W,‹Ûö/‹)í}œfå';Nä�̾?ed¤JˆLiµ€å‚uYÜ_1MSu3HÙ ÌŽ?!­«�òNlÖûÓ<#†P×t©$¥aÔÛBQ#^zßHVˆŠ»˜ú¿B`L1ât:áææŒù4ƒ˜Œ¡y£ÑÇ%i�o·÷šE!dä´º+‹¹pˆQ!Â~]ÝÕ¡8„€yžq:�ðèÑ#œÏ7ˆÙ� Y`Ô¨Q£F�5jT­A5jÔ¨Q£F�5ê5(É‚ìÖ-å´Ùø6xû“vÿèõ}[»ü¢þ§Ý^{åf÷/mÐ v¶ûT|û—ÁEQYmÿ‹Â®ªÿýPêj>)À;FÅà»èbv¡1A„šJ¼‚Ö_DܹÐÖ.Y,»»©KûJÃ.[¹Jù]Ajö¸•Àq<±‡e¼ß‰®ÈºWÉV JúnFS-RýlÕ©×ÿÄ& d8£SS%kôÖüv”>_ºû©G‚°·ž®=³ÿÕ+Ö1éàp?{ÅÿöD_x”eMøËßùSøãäŸB�;dQ„àw”Ü9 Cð¤Só®�=ˆØ9ÕÓüQW”k͘§óG?ú-HoÿxsbˆÁÀÿͪ¿¨þ£)æ h)$ÿ¥¨ÿ³ƒÿê–ÕjŸ£øƒâcsà[ œPH ¤âÊ·þÏ´.`p >YŸ„“}–ÏöÖ럜<àjûBâ¢roꂵ¹ZäþKʃŸ¨ëûd÷qNöYïoß—ß'R-ý};Uû¾”vMHÊ `GNMiÍ¡Ý?uŽ4…¼n&ª‚LÛO4—›k<2 0�Ä�>,ɈÄÞ+5;ÿ`¤±Ý—’*ÉC2À #)WˆªØg�/`€›ÿˆR#�[iC”’‘(%ñ€0  :xp^4ñ­Á‰p§„Šo@ÞÿôùOÚ8†ºé@¾F³\ûãÄÐõ X>Ýø/G\àÿü]�6 c¹ÌWÚu'N•Y�Y€ŽHÅѶy®ÆÇp³íprÛÈÌœN½Kùwè¿tÆÜê×5øô‚I³[_H·º|‚nœ¶!2z=ß•è*¼n–­W*}Õâƒ� t· ˆ)ûUT@Zf5³‰L5Ï‘<~(k†dW̘cöé€ l=#ˆO iÍÈY–''„Ðüª’öïìJ{�X“û9#ÙïËßW›Šê¿úÅ>�0OB°×»9'$$ä]›ÌÂ2 Ýlüƒ“0�tXlÿ É€ý\bœ0Mâ1M3ˆ€L ¹ñoŒ<�r½|’ÅH 9×ç¿¢ð/ŽOF €¯=Ë`Ü7ªçYbŠ Áù|Â4Mà`í6G…uF�5jÔ¨Q£v5£F�5jÔ¨Q£F½•=ÃYU›¨rÿÊ}ï¡®ØZâR{9Ý“¨SÆ×ùã]/}÷c†3h~ zù¼«ã@ñÍÿ&äîó�ç¿bÀE±ú(6Õ?y6|»+zð?Éâ5(»¥´±fì3L©O@| „' ø›ò?œ«bÞòθ—l_Ócr0ëž:|22Ï®´7 ]ÕÃÙ±ÖÏÁÀ{v÷„ëxiÁîjòvÛþʰ»Xö'ûR·öG,aÞž=ïn…PÎ É`Ír�I,V@;â„”˜Ù‚$h„–8ôØ]Àv¯S‘H„M=¿–»·% ÊÉA|û¢Bàe¢€s€p‰aI ”Á‰ Ä†Ñ³Í‹œ ¶ná: @+ @%ƒÖrœpMØÜDá«þ00}¨soŸ ù9òçÿ²«ÿÉ•½ê]«��ýV©¿]y,¢äþã·m¸Ìçvéÿý>á¿W oïùkW�ž`3-7 ¿ü~ïv£­}t°Ø4•ù¾í�i7㔌óFØ(ûõ�tC¸žfÈI ÒÏ¡…èP�ùâ¬áÿ¢ƒé·¨ÿ=îa;ëñsÆÆ àƒÖ¬ÇA¬ÌKb_ö{”F¶Pꉇ¹ªÉÕ#0(bˆˆ!€ƒ‰\õî.){܃ Ä•X× fÚ©svØUЯ~ïî,7À½ýŽÝ=©ý=ÕýÕ%"L1bš&ÌÓ„ùtB Ù·aÉ-MÅüišq:)bŒ!à|>ãt:ašæj¹¯»(ß­¯b4¾¹.fwÏwYëº %sLHbdçÅyNÁ]2T-n gº{î)Ç2BÄ'¬aæ�\=ojzx[&"LÓ„iž1ŸN8Í'kCN�(șݩœë„Óé„âRCÄé|ÂétFˆæä‘“µ¥w1":ÑÀ¶#'+d_«ÚÉH+�RªNPY2TÅ#ü%tÐy®÷e +D²ß—\Õþ=ø_ Ó´‰m_«›Â Œ5jÔ¨Q£FmjF�5jÔ¨Q£F�z êZuhÕÛâ|øª®+/Ö‚´*ÍÛ õæPpæ-äQ]zðºƒzëþmÍ¢Y¯ÝÚ«¼ËïE!dó�öž%oZÉc¢ÆÝI4§¦–\@–�z½�¹dÑJe J*Ø‘ô!v«s5Œ±8ùS§àï­—¯Pm¤‰­aó¨`<3¾ã@7Uu<gï�mJui·ÒVÔ¿ªcþ%UºÚöáÏô×=às_xŽOýâðë¿þ 7 p²‹•îܲþ)-Bsèm×ý÷|€¸‰Ç]Lo@ósÛ–#æ7?öG‘Þþ @$Ï]7н*°Ìvuðßmÿ5Ù¸§TþæÇ,àÿtcàÿôˆOAÓ`~Ä€§ÚJ°ší}ãÝð€¦â3@·@<t2ð?8ø/ÐÕ¬ÿQœ DÁûi²crpÒIQ"°}m¾î¼¯ýÊ­O BW'¬~ƒpwÅ ˆ‡‚æfP�!ìùòø+¤™lJü˜Å% ŸhÁÆîuÎb!õ쟩2¹Á�G6§uÕ}N¾O¶ÏC¹ðk€·?g�+ðs]ÛÜ»Â=Ü,ø»¿û�j$€µ#(ù)ïÅßR²ë}~ºùfÐÓßæ×.ÁÂÑO øô½Ÿ„Þýdÿk D·~he´»c»{ˆw?}g¿1±>²_ª?õ=7x¶ÔÛk3ƒþü) Sì=0W¸cŒ¶|÷:íøG¨†néõõ>çªF7ð?Õö‹ÈÈ/ÿ.ÄÅþ™ˆÙ]@j¬…V€â0P€pUSòÏÓ„Ódvø¥ûØÛÃLN\˜æ ªâç LaÂ|ž1OSkg�hD "2Åý4ÙgE-¦ Q%OTç"U'6x»sF®MB`ªíšb¬†*!pGp¥ þ7Û³3¢Ç*h%Ù †À¨Q£F�5jÔ¶`Ô¨Q£F�5jԨנJÞ½YÓÕJ´sÍÞÇÀƒ ý=5`™è�­uûƒî,”‹“@q  ]fq!�¿¨/`§½D‡‘\¥YšÎL@¾¶Ë­ö‹‡±©ÕìC¡Wx–¿W˜B�fÀ[^CÏHðý7à¼ól>Àg $Qw7ûÿ¬({S³aÊlŽ_ÚÃ]Û¶�_¯W»v¨@•kI¦ÎSÉÝŸÍ*º^—Îâ·´C;Ú:W†>à纗v ØQŸ½bíÞô‚ >Á††â‡~ì—ðk?öÛ¦3€Íï�ò{öýæ „lÁn¹çüß\ºŸÃ èüµÐôž+ìMkM·ß„ø‘ß�ôîß2�”ü/«ÿ5' 4+�- ÞþVŽžLù]ùßpðÿ±ÅÐ æénà=a5å½®0°\ÜF<€i6«ÿàÀ?ß‚x6@¿5°}VÞ�Dõ,{rRõ`¾ù²Wÿçæ&QëëÅ.Oì£Wì;�â �]ù/®Ì/$võyÉé¿Ëv¸\Õ•øÂ[{B—½áÀ|‰ં'e(#Wó;b,b6Ýš”»±E�ŒÀ(QNÈbyæ)5›"'”8A¥´ÑÆLt§U°‚Bðv‹¹TZ…ªñ6‚퇦¯Føè·©CN.ÖWR†R²Û½\«À �@ôž- &ûEN–ü�Š ›JÍÊÝçNAC´™µ;&@’SE š�Xe«@'€(|F|ë�|¶õ‡Ë,eç±¾ýou™1;¯{¶ó-„¤±ÐÏ.÷×åW°~ÚÞRQÙ½_Úÿã_}Ò"Xz6—g7¯”vöD'ˈ¯¿ëJUñ»P*q…:ª¨ÙµÆ³ÐÕœFÛÿ<8oQ´ësÛCé~~åz8¯[w¥CÀ˼ >(»�£¡+°ÿÊ¥ ­×�¨¯DÙýÖº,ÙæÃ–i³ðikì^�1`ŠþŸOg()Âj •¦˜×ú•Ò UÅR–ÙªÒ{’3#D˵�qòÏ›zŸ:G‘Œb{–bsðíÈÁöT·/ ;“Ħ¨Õí§<‹ˆ˜MÿšZ<�ý�Á‘§ ó<#ÆÙÉ4fñŸs?�@ÍH¥.ƒ{?‹] tMÌæ0Pœ y¡»¶µMÕê#«/F�5jÔ¨Q£FY À¨Q£F�5jÔ¨Q¯Ãƒ{ŒˆÓŒÌL[ådWÍC~ûû�;A-»Ú½ç; @Û~‡JhÏ(Lƒbéï/n-/W7"Ï ½TµÛNÉUàÏÌ Û¦f/[T‹ÒÓIþÒ˜;‡„ÒD‹•æ ÂôÆ&ã¹ï>5µ­ˆ˜š­¨ðºÏmÙÍT~²¿: Ul„‰vɿРhÐ[X7«‡»µ‰�áNäO`Näî êû¦*Lû‹w ×´¬åÖÏU¹{µåqî³n¬¾�B@Çü€W8ÒñYô°ã‹€'�U]Nø±Ÿü%|ã×½�7O‚�Èòº2(œ�é)*  ·6HQ¸mÉbNù9”î�1²Þüg‘ô°þSûÈþ››„)ÿs%@BE-:ƒÃ 0=â-0=…Ç?2ðŸü/–’ H@^,þü�>|ãä�€Ù‰äàÿâÊz�� Õýz› ½ô�$�°Ï©¬þ³ðàyel1:s0×�€ÛíW{sWñ»«z’A±•&j‹Å~©‚ªoeíTýþ½ÎfÑ]Ï­ÜSÙíÿ9CÅÝP¸¸›×‚8°®'ˆˆ¹¤B,(ŸõcDÚˆ¹YÔÉFNœH œaíÊS‚Í)¥3™„jç®~¯[€wesPPR˜”'Ìoý÷AÓG Ö¿êX‘w¸»ìZ¨“Ÿê$\ædfhC;"‹»·<ÿñO6‰s0��ÿä'gü½_9ÕX”¶Û~½¢zMjN}�_ÙFµ°+™‹cʵòžê:×¼V‚º_@L¢¶V:L °h}eä¼™)èÕï6"|-®<»ÓÛÍZZæ}ÝçTÖ˜c›ùo³ÅW*Æ.ׯkeQØ?8¿û³@ˆ,–S_¯›Ø:¦°H ‘bÍï‘âÖü%.ÂI{Ó4Ù×ò,û™¾Ê�GS5Ssb¨Ï �¹À@ìÉ�ÏñÃ߆ô¹?äÏäÙôY ’¡É~.࿨Tu8Âì…GÀôŸñ1À�ÁÕ¾?ÀÔø®š×bû¿’ ð"v’Ì @þó�»L­÷Š_V³þ/D€:'0ÀN¨ùïå~;wY vÅyí¦Ð_T’s‰ pâ@!ÔkᱸTÜ·ÕâP]œ6£TAêúE›ü'8ø_€.t@6±õ¿7»ûY²End6|ñ¨€ªæî€À@*(¶“;ˆ¡9Õ{ÚúÑæx�¨Î߬Y›ãR†€À´n\<”‹/½ï7¶ˆ³T§êBP'ÿXü�(púèÝþ:'g�}' úÞO#靸%ô¹¬ößÁ�w8¹YDÃúößÞnëÃåKÏÿ×ïzâD$wWé,¢ã¹H«ÁŒÖxšJ2ÓymÞÖŽ¼DØFèØü+]$ö1ô@]Ã^pê„Ýìåô‚ް9_§Ò˜v[B€O‡Dצ‚�nœi®çÙ—LÚ_)€ú¾Ø¶UA[ÿï®9ñ†ýyÁ†¥6¢¡˜³«é \N);a„ƒÙðŸN3¦ù„yš§h`·¶è"íž©Šò¾Õ"‚œ2²+ó‹eæBsëïœSu (ûÍÙ”ùå3ý˜É@.XŒHÄìýÍ‘@º>+€úr¹à²,±�ê³HÎÙH@%(„`ÄÍm;ð3,Ö7Á ˜Á ˜ "æ`.+.‹Ã !X,‡;ÄiÂ䀜3Vº®5F¡¬1¬G�-`Ô¨Q£F�5jT÷qtÁ¨Q£F�5jÔ¨QÿÙ¯¢gÃcÇÆ¨EQÖç¹—Üa…Y>‡"•Ü 6Ñÿúb}ÛËzê¬ä;ÀC=³;P…¡{{{”Ý\×Bå¾tØÄ 0àÊÙ‚¹ µÄ hƒE àÒ (²?µ‚+Ë]Œ·gŠ®OëÏ@œö×Þßö¢:×>6Çs݈)zxE«Û°‰ Þ*_[ÿî-Ì›„ÿ¼QÇjí'l®Íî?„ÿï~¦ÇÈ?F¹[¤)G�;ÑÆ\ˆŸ~û=|üS¿‚ßük]í&~aÑñæàZæm›Ê�5_]sûSÅCÓ;íÿŠ«?ú‡±þÊ¿Â3‹çÐ MîV心Ÿ .¶ÿñÆ”ÿñ‰=ÓÉlÿ)˜å=—Ìô¢¾_€l P‹þ0�Âl¤�prð¿·þ/ÙçÙ”ûü—¤Õ%Á㨂v®þ×TíùMÕßð$€‚ñ�ú_$á *ü훲ڜAü/çèûuw‚ë´qsÈp:´v3Ñi7Oh˳gW賑{¤œcç`ý^,ðÉ"ÜÒ_YÁì÷¿[îsJÎ0bsñÁ�z ™ð~rgÿRª÷+Rò«éó|èî=³ ©ˆ%@c;åJŸ…�¸0}ä[ÁOK·x F˜�»_FzçÏÕy½F&X&Š_Ÿí<ÙȽÕ:C×Ïbù…nîsþ­Àÿé;oñÅç›’ÞZ¼´«»÷[>}›+^4m\Ít¤v/“j#‹™ïôf+P®ü4[zº¢Ç5‚í¬Q*'†õÑ“û¶KSÛ/ª+ÌfyÚØßwOWîÿþ;–À�Àƒ @3j15G�ªxñ¿Û¬àÎ9HœÀ#›n'" kq ªyõ’¥ÆͧN§Nó !ŸÝÎY,ë‚u]�ÖÕ¬ó»(ÉF*èAý›…qjÿVULól¼õEý¾\.uîŽì³)jÖùÌìäI]Éا”pÁ³çÏq‡´J{v*F!þCq èíøË9‰ä:Î Ybž'Äjû ø�uDâÏ;NŒÈÙ"G`$‡”3rö¸%wKÈ"ÈîªP®Mí/jĉâ�s®Û�5jÔ¨Q£F�j5£F�5jÔ¨Q£F½UìU÷µÙëÆ[Y{UCv¨Aa%›8ðS÷±µöEÉ:Ö>ÇÖ·Püµ÷#h-Ô.J@E�)¨À;)>uÄ4…�H÷â×mf¹4•G¾ÊÕ†ê¤íÈêŠKr€¥PÌ^_8˜0™‹Õ¾[e×þ{Ê.¤†¢?.Ä…Þ²¹‚ü�w}ÙVD¯°{ôý¾-[sJ~|±~ñ ºšìãÚå"ï" 8×CF½à¸ª¿ ÷ÄÑoô¥ÙÛ¦5””Å®ówÿèÏã>öÛðèödŸ“ ½|Éqí ˆOý÷ü//Ý '›v\9ð Šo@幃Ó0õ7?Büª?„ôéÿ7€d‘9ƒr†:ð! 0ÏÀtãà¿YÿS¸øLnûnÖÿ%D½(÷%¡‘ŠÝüä¤�[k#Ïþïhûq÷€jý¯n߯�Ú’‚©ÿÁ€ªv>šëñUSk`ƒ‹ÉÀózÉlžhþ%É�ûfËß<áÍå@uñ¾-Çð�˜³)÷�H¥kÀmÿÔV'rw`zµ�Ô]È\X\_OÜ©;®¸{€ù�_@’Gx»áîÁa}ï_�2¸xŽô$€œÍ¶ŸhKÀéæF‚C% À¶/d˜Þü-ˆý=¶V?�h×øò9¬Ÿù7Ñ@ý.2¡�7P¦Càm¬íA‘ò>ûÁ�[ÊÐx* ø®ÿ4âÛöQ›sÑ«ô s•ºÒõòUÉbòûe®~†¶c»êÙ¬Ø7¼‘ÎV†ÐÖžÝåjÿýZ嫆j7§·õŠúEñð9@¯æâ ©`›Ð‘Ìêr±ÛÇþ™C_ð¯ý3 Ñ˶| !Lõ¥Ÿ/•S6ÚAhR+!ƒ�(ÕÈ�¦‹d¬´ÔU!D„ps>ã|sƒivEzÊXdÁº¬¸¿Üãîî÷wwX–˺^ÅHÂA]o! Nó4Õ¿åœ0ÅˆÕ žâÑCpé¬íC¦²'Ú8”ý”ýß�°X$ÁeYpwÿwÏŸãù³çX×ÕŒW#†öÏ™*¿õ‹jqGÈP‘J¤aˆÓ„››æÓŒ8M6÷¨;?QwSÊv¹·ö“G$¤5a «]ÇÝ!W×€Ôõ/ !w þ¯)Õ†Q£F�5jÔ¨Q­`Ô¨Q£F�5jԨס:áa³üGÅЩ³³¯Âà–j¦±¢ÑT^$—,ä.Zਠ¨@46À‹Ëlé´çyvlH:�åµÝoUl®�íìu‹8@q:4H{Òj\BÉ8Vôî®òíÀrËì@eÏ®4S…dò—ûW�¨UÛÃ5›¢^é¢W&w®ZIRj0C!tª‚Iëû²ïMæs§¸­æ(Pîs(—X�Ò@‹2N ëVãã_‡øuÿ”fPFXÐÕ®múÖ_ù7l슶¾ÚÄ‹8)FÊ~�HG¨èœîáïÚå-ÃÌù!ïßâ¯?ÙØ˜rT‹`Ù†Ù7ÎÏ�i½öŽ1�óJY{kºžnª[Bo¡¯-tg9C/˜ž¨Ï޶+k vÎê„ÕæPV…^±¿%ì4û½ AçŠP/_ï8£̵=ŸéDÒ¬G|™£Kÿ¹Ž›ÒjJýâ’D�H‘7ÖùÒEðh³ <7eþùtÂÍí-Nó 1³òO®ü¿\p¹àr�Ëå‚5%»wÄÈ^¥o?3xÏþ‚Ùæ›²?ø)ºB^²“×Í>4N�Àð»XùBõ¼‚G(™»Aº,X——Ë—Ë‚5-€À2)f Zö35’�ê¹{Þ1«ÿ'œO'œÎ·¸9Ÿ,ž ‚”ÅÔû’¡Y«‚9¢U²h΂e¹Ø5Ì1°'›ä¡Plý‰, eÝÄ.’@ê¶5jÔ¨Q£F�e5£F�5jÔ¨Q£F½eøz—ÍîoÚugc¼@xÝ©ì{˜@TŠêtc5| ÚkØ¢p4E£f[à¿)æR‚K³ ߸ p°Ølq-jJ`ñ/UiÊJ´,xê˜=.ßâ¡Ý}À;²'0¨‹+¨¾ÿí™ÁªHdŠl0 [`Ê€ªG2 Þ-ÿëÄ�åqc´�ÿ…ðÐkU½ÙlD3ÊK~Ù: èõ•Ó#Â…öAYLwãp?,T�3§q0t´oËCìŸ;ׯ¶Ÿ l QA"�•Àð~ùKøøÏ¿�ßüõ72µzÐdÊëü>ˆb»7´S—#£�îH]«ÛVW· VH~ Íà›o>ú{�å;ŠˆÚ÷Ã`š üŸÓ# >ñ-@�€pÆ øW9¬v¶û«)Õµä€'¹Ú?÷Wñ"�˜»–}À�4·s*Êp'TLÞ�àª|-öÿqû¢M6º6 �ÅÕÿ¹)K©Sÿkï4�;¢@‘ŸºrZ¸%´›ª lïÈ¢žeß߃l¿ l€>gòÍBÈ\�ÈÈÜMDLþ³Á·©rpuW€l„ É –7ï@^!@£ÍÞ Ë9©er#H×6)’ð$…èÀN`h1'È%WFgA8=â×ý�ÌæŸ&(‚)Ói”�>û�”¡­Ÿ¥_/v?çý= ÕEcýô"ý‚9þË0ûãŸ}?ncî�{PSãw.%Zþ±›2´Ûˆ°%Í7TcB¸®–ýÒó¶»y ¢gßE{¢Âž€PÖ(%w’‘ Pˆ|®ì×£cÔÝëÕ´¼�Ú›+ÎÞÒW þëÿ/[å>=4?Eï¼`*×Lô)%„5#„èI@íY…CÄÜPLuîÀr¶y;N1N!bЧÓç“©ÿ`M+ÒºV࿨þM™ÞÔ÷ÑÕóª )¤5ÙšãùÌ¡F÷´%TÑQš>ÀW„…Þö¾(ò¯F]/¾/öøGPž£ ç±Zö‡€cu(öýåøèÀ{fsI˜æ óiÂ4Í‘�ˆ´Øù¯‚,i… ¢S*ÉQD�’õQÎ+V¶‰©µ;×ø#8T¹d²*$%høãá¨Q£F�5jÔ¨®`Ô¨Q£F�5jԨנ L(ßøÆ{žmgŸTÅAØÍ‹;%¹ë»ïå¨[¡«Ùˆ CÜÅ( ôÓ>S¸ªmQ-i…‹=r±c÷üÚ¢žsÛd{il–¸ZApö—úÍæY!°Lðj9]¬”{µc;@‹ùuQd–¶B(1ê ¡FTÝûó>%Þm›¨�^Ū}_’»ô6ÌÚ®õ�S@‰@=NÈ®MUAŠæàÙç“zUl“èa€LK�ápÚuñÕçv$€ƒ�>0pÛ'ñº—Ä ô`�ª«5�`ø°�½€ïþ‘€¯ùè7áÍÛè ø#¼×wlgá 40s�ØÒµ®Þq†/+€N ]¡zgÊzß–o=ðUÿuäÏþ0"Ž˜nÀÓ#`zŠO¬]ñ #P±ü/=Tlð]±ŸY% ¸ä¹ÃÜ,aBóc/@zF³â÷ýõQý£� Ø€æ=�¼ïÕÿ² ©çÀ¦þw҂襩úÕÛ¡�+_éÚ™›}6¾^Å3pw³^G˜Š¾È£¥ª¼íãÜ\ˆ¶^óYìï>W'¸"?¸{@¹ÑÄÕÿ9»@†2ƒ²M,æVÀ ·Î-Ååpw@$ƒs²í½_Au">ï�;²¸š^5€N_�ékÿ‡@8Ùg´8½œ�0C¾øýÐû_°û¿(ùe?ö�Pd) 6ß̾ßÜ :dà;.â;>~ë×®ë{í²aÈ}b[+Üߡͯä®*ý\Im»6mks¨ûÞÎY{s“IG´UÛ_O„…×+ùw õ„4غ¦n6¡¾jS!¿  ¸ûôÄ�«õûá™ùø„:²Ø(¯OÓW³¢;x=žÖ|àÑ£eçÁZ×Õ€éP”ö´±ÞgÞº˜b<×g”â0MÎç³ÙÚFÊËå‚»» .—;¬ë‚Õ 0],ýçy®àvÎ !%fd�¨Ê}ûI©’û¯~85k~ÝûsÒîA�™1ÅÜ"D»ø$qò€µ—ˆA�0Ç Ó<ãtš1M3bŒ»­m @ÄO1"† ‘í9LT!)#ål–þiAJ‘Œ¼9¾·]ÙbŽÜ@u…W7•PÚA½3Æn ÇŠª»É¨Q£F�5jÔ(«A5jÔ¨Q£F�5ê5©#Çåön½7ö:Ȧ âï4ìÕQ@¯‚u+j?@ÎìÌTë޾HÞřƒ˜@Ìm_Wëk³^¦àdr¹5?@*ävÇÅnys<Ù@Kº[J†µjâaw_(ŽEÝ_l¥¹W‹å�×ýv`Nu*蜊‰}JKƵ6‹ææn ¦6î�žÞê¿\ß t1P]¼=D-ò@dGöð}p”p•ÃLËi}¡*óW£þÿ¢èS@Û¬ý FN‚¿ñ}ÿäŸÿp˜M•½|ÖÆÂò%ð£ßäé%ô=Ô�ö*óBðka×5ñ”Vh±~÷ÏðÓo†b…|þGÀS ÏÀô4=€O¦ü/€=·ì/u~±þ_�DC"˜fP<tcçC'S›Pĥۚ̊Z\½_üznîÀÖB¨|TûÿÔ9”ù�±ÉP­þë±’©Íób.å�l),•€ì`¸“PÀqu’‚ÀH 1(3”ÄÚœÛH˜Â¾‚øÐf¥r!´¶ˆš•¾ª‚TÌu xÃÝœ+éD˜€\>+`ñØ!P"hŒWÊ}b…F# °‹FÉ®¬g’@(ƒiu1¼ÏúÑ�zòÙ¸¥ùc˜¾æ_‚†¹0 üʘ»ƒ~éG�¿ðí¨à¿Ê ‚Ý÷Ðñþ+¾ü·~pÃ(úÂ3Ÿø®§nüÔ¬óu&2Ü›ÎTçñ¢âG*uÓZw�]»˜PeÓi%¯ÕùÖ¯7íÖP¢=�G¶)°74¹Š$@%‘‰8)ÅÉhàŠb·Æ·ùy „£uø`þ¦2£WfŸ^Ï×ú�¿.l"n^PiMaAJŒÅ6ÇûÜ܃ÚY2R²¾¨ö‰ 1N˜O'ÌÓdöòËÏžÝãîîîï/neïÞ,0Ϧi2×€ó !D¨ –uź¬`^ªÂÝÆ`úsµ¯Ïnw߃ÿ!0bˆ˜çÓ4aš'Äêó[u¢¨vð>Ô‹�u…:À^HþpB(íŸ1ÏþÇ89èŸ;Ç­ÄL&Bˆ¡’ Ì®?A’"¥„´¬F’XW¤|MN$ Ái”ªPw/)„�î^ÕF``æê€Õ†]‰WˆÐ ˆxµ4‰Q£F�5jÔ¨ÿ"Õ Œ5jÔ¨Q£F�õZTÿf³KùU{ij/û�í­umŽi®ìœå;`¢·ê>ØÁ”vØfÁïÅö¦òo/૊‘›â¿Äô�ä@~¼àûâ¢Æ/ÉŽ±²YT f @U5YÕ³å;Çee­ùÓ­j4qKÚöB» #èÀÉòrü N© ¾¢Ä5@^¼ó-/áÍYÁUÉÒu°n²–{FH¯så–Y�°ÍŠÞî…`â¶éª[p¬8Sê·-Ý�çm±´NîÛQ^ˆ¸{E‰™`"$0Û5P!|ö wø‘Ÿù ~û7 X¿ÈŠLŠ òìN¸1‹v`¹ÿû6ñ�}¶ Ù}\)O`Fx㿊�‘ßý10Ÿ€x Š·@|lêÿ0ƒ1»bßUôhàýÖ²_ï%f;øOfýOÅò¿FhSü£Sþ‹}:õ?Es¨1E™ïŸ‘œ‡+¸y;^íXrñc/(þ𪺹ÏÚp ¿€sÚ€ÿ6ÊÅŽ×�¿âÏÝ¿·ƒ¼gáÔû\É�8ØÏ5Äij�kº¸�À@ ÖÎUZŒ� �2@i£Ø×'V0¨ß �fGqÇqG‹ JeT:¨’œHПçô�˜¾ú¿ð $ɉdl¤ž¡ïýÒ;©#íÁŸ_zù}Õ°¹ùwÿ>»¤ÔÝ6>­ý/¿ó1¾tǬW üló{‹‚©ùD‡SK�«Ù/§{œÚ<Ø®¿“µvvùm­£Ý>xãÞòòÕ}P޶�ó´:ÐôÇë£ ¾Â‰ôjN&¼Ú\Ý®î+ÎçD¯L БðE•%!­„5D„�Lé~µ QgÚAÝúé0f·íY%ç„ËrÁýýs<{öëziÛ…`ÊÿyÆétÆÍͧóÁÉ!D„N�.À—ñ›ü9"­+RJ›¬û�ƒ+óO8�Ϙ§©*ó‹3¹sA°vGCT‘SFªÙw 1˜SB!.œN'‹AÁûR°.k³ÿ¯}gÇ N€5% ÁŽ—Œì°:¡aQà‘J!(ˆÌÊŸ™wÇ@íßÞy ÎÚ4J{‚}£†À¨Q£F�5jÔ¦`Ô¨Q£F�5jԨץ^„lV?º¬àã}TMIu­Ò×Luí·nVü.`µ3zuZÉ|-6ÿZqå<Áôkë@ž�¿ì \] ̱h€‚ǰvþòåM› <ÜVÙ0B©6ø…|`æRNU)Y>·8øÕì¥;/Ýçðº²tçx°é·r. /‹Ë¹B…¡”ëñD› _qu¨¶?� øËÖ=I£ƒ ;‡…Fhäk–GLHSÿW|M÷³ËÇÞýt "^zh?GC¾*ë9[ŸK‘+LÅ-&…(áG~ü—ðk>Âøš�à@N Ó ªÝ¢�å¡¿)v­à…*2sBS«àÇ ye—ò*ÌàGßLo@¿ü3 ž ü§0ÏÜSôcྻQ”ó ‚äà¬[ÿólñtÄ Ù>OÑÉ"ÞN]¡²4ð¿WÿМC×6B€¦vmDŒŒPÈȨ$·Å''íhî3D ‹$·¼yt`¹�r)ê„ßβµ,nË_¯]�”jÏ ÔÁ/   Æ•¸ Ô3¤lO�-V({v{%0 Nà æ`D#'H 8%w»÷¸bkµóWw!` F'dx,€+ìU”’‘J¬ %PåA˜ Í¿ñ­?ê×¾ÂÞî(q‚¼ÿqäÏþ9�e)ýÜwÜüÇü÷±î@ëúË߇õ—»Û¡s;ùwø„ú¥ÔÉ™ÈçTêÜS€ÞÂÈoz½†m”ÀuÝé�Rvà0íÖÇ+&‘î¢_´³¨“àSG�Sz�ë¾z¬L™ݵT×ѽ©~‰€�ÇÕ ’ÏJÓ[´€’n.ÉÃ6»>8Š5觥͂ƒÍ:}Hx¾r'}كЖ”–³�Ý)­9ø=�ÝrŸP�ïÈ«ªYÙÇØçœqÑ –ËŠû»ç¸»»Ãår‡œsáCˆ89ø{{‹››3æÓ �R¶ùOD§ ‘æ4P\ D’ÅóÔz�"bŒ8�N¸¹¹Á<ÏÍÖ�|W€ÿÉ•ûÌF:ÉiE‚‘ .÷ .÷¬—ÅÀzbdÌ󌛛ÜÜÞâ|:!Æ©öDz\LuŸ¸‚ôÁI!p0âVÊ+492¥Bd�­'N`d�aH¹EÕä¬õ™(xÜÁÄ—,Õé Œñz¿2%…J5jÔ¨Q£F�ÕjF�5jÔ¨Q£F�z JEQmU{ÿòëm+àÙ�禽§kQú+5`»aÁ³*t P§ãör—‹*²·«G³²7‹WlÐåÒ^öˆ€¦«ÖªDo*ym vlq  �ïÍ;š6§g}ש\AÈ*nÿŸkÀ¾_RIZZ@:PSöÿòìw&¨6õµj@@¶K­¹ë§Ü�^¬¾|o¤wØ|HK �P/¯Ö¨�#Ð^j„¾¸�¯'ðâ4éì[ûÀ ƒ!,Qpè(jcM”ð7è3øÃ¿çëp3GpÀô* tù¼ÁÓ›è3®�åØJ—ÍMöï¼õ\?é*Éñ|Cjùü ¾ž€z:™êÅž½ÝœÙ¢$Ä-óu1ð¿þ=‚é ¾·þ'žÄ/}XÀÿÕ.Nö ø/ ?{dÆ\/vÙêcx-^æ¾­�÷ ”:ȯ~\Yü_ ’l“àŠùªÜõØÍ-c¾ØÿCñòÑù¢Œt¢¥û™:^™[$@ïø æÂ5óÞ QªãQ€Ä@wV‡æ� ž¢ ln¤*lÝ ³¹Wasmæ€ÂlJ°Ÿ·(RbVJ{PfÄÓ·€ßúCp{Û9;‰ƒn ïùí?ÓÝ?û¾“ã{Nm±’fa²<Ãý'¶—®L ?ñÙ€ýûžVð½ºÅ055>¨°êx�,)ä(êìÁ7,%'~uôMN¯K Ñö¾ö9}ïNÓÚ²u!ÁÁ1^µ¨¸°±vl„¦‚ÖŽ•ÍËÕ)‚èxî|%Á>u»íö£úÀÝTÖ„àÈòuÎõÁ‹j_µ(ÞD ­|˜1ž1MRZ+=M6ÿ¥uÅóçÏËå‚çwÏq¹Ü#¥dŽ1n·¢ ÎçÎgSéOÓä‘DÒˆ~®š·[Ëtn$€bÿ_žÙ¦iBÁ•ù3N'³æ'¿ùÕ‰Pw pð?Ä&20^ëeÁÝý=ž?†gÏžáîî9áèt:ašÌ¥à|:áæöS´ó_–Õ ­ê9‡ŽÁï!AZ˺`Y.H)A$›óB ˆqBœ"¦Á×ösJ• •RsGh$ÏОט6nK¥ï²J]JÄIž�†úÔ¨Q£F�5j_ƒ0jÔ¨Q£F�5jÔkPf§jê÷uM3u®ó®Þ²÷6Áõ¿ûlf3®ÄÒŠ:y åмοÊknÇ#bpàª~³üùÑΡ^¡GLƒòƒ*¤@æn»qØw‘ãütµ;³·×ý)Ô ¤æÏf(ÔÅÚÚïÚ�»­_¤Ëwo1nÏÜá"UˆÞ™&÷8~Q±™±¸‰Y¨büEJ�Ú¶·4®öüîlЛ 7äK°èïU²×¶ØeÀÙyië¾�Põ%*ÿøؾ¢xÔµíÕ…¦ÊO¼N©™¶iª ðì^ðÝ?òEü¾ßñ�ÀùÖÀàôEhzÐgÀ>Þ1MúN1'‰²ßzŽ Ïaïû!úD÷¼Ã¬à5€O_„G�ç?ßTÓ›cúqD rôˆ�æ ñÍNàÞúŸÏO žPÕûµ øï*|,Ä»­=³GxEûüœ+9ñÉ€ü+PÞ�Å´½vêdY¶®*íº—Í�ª0—ö½8‰dW¬2µ|À6«äpl¡Ö=Ê+ „®Íân!Ù#º¨ »Ùm÷3({7   Íõ@HÞö” PðJÖÇœ�p¡Û(#]�NPQ°ïŠà$€lŽ”ÌI@ƒÏ�ˆ7ÿ4ø«~s}¨Ä¨äýO!¿ý§ÑüF¨õƒŸŸ±eº1]Û¶›_T€,xÿïü¸]Î~ðÎ3Âÿü?~kjóbÑÐ¥¸-?êý¯ä$€@»µ‹®×’íRâs¦nÚÝ«ò+ËÍÉR#YŠ@Ñ<´[ó%зÂUú´5  ¶/v÷Ý�ŒɬSµï ÎŒ€‡÷õ`™Å?íˆÚš»I¡qg�\ v[‹�ãêLÛý=†Xù8FX]eoàzpEý|2Å{9gWß›+‹¨àþþ—Ë=Á²&\î/È9Õlú¢þ�! „É€î8Uà¾<“d‘ªü/Ÿ)j}f¶c£·µ‡¹„€ùtÂiž1Mb n™¯uÔ…6±Kbãsõ6?{þïù}¼÷å÷ðþûïáîþ’!äœ0MqãLÀ! „(yÔz›¹©ó#å~Æ’ÜßÝáþr�œÌ eš&LSÀñeüÖß4AÒûôàåiÿF€nwwE¥™tãÈÿ]¯Üg›ãøÆÆˆÜ¡'P| ~ò›�»Ø®"ww�+å¡ ¯f�ïùfý ô7fÿÏ“)ÿ6÷ �\A^Tÿ+�›­¾ý±SÿïUÿnû_mß‹­ÿZX7Æ·1l÷Œ�Ä„X͉@rößoØ»íJ=`#Ñ.÷…o/ºImÀáìFÝ!ŽÔÌ&a%"(s‹(÷›(�Ê”©ÙÙS#Fi6Š€söÏ›ÓeX¶uZ�@)ûÜÈíž%¶ÝFa²\pUHÒ™àÎ*¢N ¥ŒðÆïä÷¢Å&”H†  òþßGþÌŸöqÑ�å:Œ;"‡ìÆa%tJpÞû;×€z馒ÿ“ïx‚Ï>ãö9Ÿ?¹‹ nbÖ. ú®TW’6+•ù Í ×1$…LVÉ}@÷³ôkB7&ÀÔ¥ÝÚ¸ÏxU‚SY'¨qú±çý¤dÀïÞUG¯&ËþÐ_áælç�SF Áæ¤B|ÌöœT/ ÙÂi䓌$‚u¹Ç²^°.¤l1F„ˆ8�fœoÎ8Í'Ló "BN+/vU�PaÏ8¡.ûµ<0#Û8WE1R‡“+ʽÍ`b÷E5jÔ¨Q£F�Õ× Œ5jÔ¨Q£F�õZÔÞnyZÜÛÙwÀý.ˆŽAUí^òR�©Ì8Ä-¶×m½n…Šþ3mvõÿ4ek3ˆ½ŠÂþP¯X^ ;G}¿\�fËO6Ч“+î\¨ö·üindR@Y Y7*>¥­�tQÎ_ACG€Ì�•?íM´UÈ:ÙB‹C�6¢ƒîUÌõZ+®ÄûÕ¢·±Þ:TZ†êÔy€{‚£aó`ïäWÝB€#‚‘ˆ��rFàD…d»Æ%ƒ�‰ñcÿ|äCÀ¯yë\Ǿ¨‚—ÏAžMàGßðiÛR·%n—ùE r[}\ÂÉî^¹³>W, œ€›_½ü €lÀ|(ªlË‘� ”ýàÀÌ7 x ÐÙ£&rË›N×b§·ì/vüEu_ÀŽþsìFQ‰Î0%¾fw€ƒóîþać~ö(¥+gsjÇ­ÙóŽÄr6$¹Î‰þsnjú–W¯Öœ�Ðí¸ë<ì’”xU�º�½ýŒ$Rc˜8^$›ú^ $ì.æF@€Gs�lÎ(d‹)C)xÞ«\Ý€ •TÅ>>7t¿—§·þ øÍ߉­C…ؘà òÞÏ ¿ýÿAƒÖ¥Ÿòqèâ ýuýó³ý~àÒ.GÏø×¾÷ŒŸøô\÷Mð¿EÈÀÝTD¥ZâwbhÂÉÌʪT2Â\‘~m�©jö2Ëéõ˜ÙDÖ”?¨)Ñ‹->/4˜xáô·C· ÑKUºt�2ÿ4+~í¾—þ£-«lëp5ìõ¥óó¿wÚÇÓô1 WTµ—G¶T²=à:´«ÇOž@D°\.¸\.¸, îž?Ç“Θ§ª‚8M¸¹9–‹«ñׄ´.X–9÷–ü¦ô! D·ç)š:? ªÿkZ±¬ ÖeÁšrj*{ûìT#–uqõ=ƒ³‘‰B u¬Ð�*è]…‡æf¢¨NEYyÍH)!¥„uIX——ÅÎKD$ †ÉÚ·®ÖF'*ùy䌜-ž ¥&'k¹Û�ÓŠeY±®‹Å#89Œ™§ Ó4ã4ϸ¹9!„X]…r&„hqGËÀP�µÏsζ¶U‡f¶g64§¥rOÃÉŸÄô«ÿ 0jÔ¨Q£F�õŸƒ€Q£F�5jÔ¨Q£^ƒ¢Nõxõ· _êA}œêN¨›ªR_`­î0‹ƒM5ï{·…ýO j–tQnÕµÅÈ¿·¡-¶ÐÒ#>`wðßÕ¸`ÚZ›?³âRÀ¼Ô®K ‚_€vÏàŠ¼² ç–{°é#Fa*)¡ËØ�òÚ372AsHØ_ëÚ¶þ;™ ’œìÊ�Âݵ—íW.6Ú¹Ž"ë|6öÿØÇ\„PÝ-Ž§ÂžˆPî ìÀSëÓ^&ÎîhP\RpÿÉ¢ª?:û¹3@(³ù'':(ŒÐ�2”“)ÿ+ð¶¹!!X‹c1ŒwUê¢â Ó×ÿÀOÿÉí9S´‹ÁòîO î?ÐGÃèÖk\ºŸg¸‰ý{ù¹€¼Ó†u¿ùò© î'Ÿt¬€íu 6°�¼T ®+ ]­6ÌŠƒLƒs5Ÿy߉v£BÕúùjé´ýˆ» ÐvQÞŒíÉ0WÇîÕ쬦ºu„)„¼>†A ‰í ïµ®ãíü•ph¥¯O =CèÁóGOkî3#B¸¯¸¼ÊôÿôÉS¬ëâyñϰ, îïïp¹Øì›7··fU_×rÔç†,‚uMX– $ ˆÓM‘¾ÁìÊö˜#âB4óœ,Xa±-ë²`]V,îB "íX�Ál®“� ¿¬•/Ï+kNebNGSˆÈ—¹§>4"¢t?wLI7 áÚõ˜‘„”mí*dƒœW#¬+,!C�œEˆd¤´Br‚8Y"Fô˜ƒB–`&ß^*¹ ¸"03Ü̪F2rλljŽÌTŸ!øÔk}�œ)*ãÿ,Œ5jÔ¨Q£Fu5£F�5jÔ¨Q£F½Åü%q¯|½ò÷ÇF/ç9ÃÕ 6@i§&G§~߃©´‹ùV):Kæ¶Ç–í­Ú@‹Ò°änJövüê{\•úorðÌÊKtf·Ïo/*½²Ä§]¿� u×sð¨o‹¨B%@)ÕîoßÜ)ÿ©æ:+µìdìˆê fÉúKßaÅ=^áZ¼©[§„]Žò^Ùÿ•Öq2óqT½d›«=m¦ªôÂH€d¯íûe" NÎHq†êÅl’‹�;üV „e¾ëÇÞÇû[!�½&@èò9€#hú°#eE]]ª—>÷ j80¾s°áä¶ø‹óð ‚æ¯ƒ®ï@Ö/�‘*ø.E½O Ž3À7þ›úŸx‚IÐCw•,/Þ@l·Ñ—Nù/êÀ?£Æ”îóáTWh^Ü=À‰Úõb®*`Üûy”cÓ6«½µ[ìt ØÉÌi?jÏ»¸”6�jͰ˜®½';Û¼PcØ ®àeIv*LÉ�Ο½/%�Áÿ?öþbå<Ð}§üç’+„ž„‘>ý³X>vaºQà#¯þ­÷¾tfû]ÿäs{‹<° ¶X‡‹µT´ÎƒZãÚ"SÊk}$@?_ôæ9 4/]DŽÛ¾H¨n«­q;}º>gz½”kß5IÉIý²ÞíAʹé\ 6Êÿí"�ýêV×Õþ»ê;u¿žƒÿªxþÖ°9š¯xênF=z„Û»[,KüM¿,+ ŠÀŒeY*¨½. ˆ€5­HiENÉlå=ë!³³¿ººÂÕÕ¦ù€)F�æX �9'ˆX[RÎÈ9uJúlêÿ5Af9ïì€ìÚ0C±ÜwÇ€²½B(*~ròNÍ•¶ˆGHqHè,õ7n}âs×oªÛŒúš\©f®W–“vç¤Ä ¨88Ëm!öå÷Ž”À~ØìÎÚ^/NʱEh•xoN¶í”¬}廡xr{Û�8ðÒ�$©+i;…ù¹?ÿk·ø®÷˜5²aв|¼>0½»&o•±ÒÚE©Ø[ðo^ÈÙ�|8ðøl¯ € €3@p¼2Ëÿ` pÏ[U¼fhUû»ýµÞ÷6°]æ}%`8Cáê,àzSº�kZßôÎ&FPY;Gí,ð©ë#Øñ^ׇ̥�å<¸r}s9t§¤ˆH2�©™;0@ÊPb ;q¢‚G¸Ì}Üåmìùw�À1XhAJÕý@Rò]:i`2â|î$l#¤FÒP |ý¿ŠøÎ?ÛTqpˆ@8@×/ ÿÞ ½û8ÎÀÿÍuT]€þlœz÷y<ùÙÏlÉcþöÓøïÿg/á÷žÄfq¯¨óp[¨ªàÍäà€i�9¨4‹(óS}¿¬A‚3‘Šß«)¦ëz×9ÔµDÐ}Ú­•DuCÛùö¡¡GçsúfÍ¥‹k;iߥ-ކàd…Žx† y¯_'°EÛ•v+�nyaûï ‹ïÙ9Ô|EUâèáù�.ü!„ 1FÄbAb ÈâäB¥ïN§J*Y×µªÒ‰ó{ÿîåOm�© H× ùûKÛ¸ªN ÔV( WÀ0+ˆ‘C@ÈšÔÜïíBj×2Œ"ãW„oû&jÿI�Ñ7 _úEÄw~§;„î˜:�Z»ŒcM]P½ÂUœž„�þÞŠªªG¦¯ãU?ÀtÂ5(^taÐ\jgi¶hM¾½äÿzµ·[ý“®À§ê\ º:� yµèí¬ük|@l}#¾I¨}O’YlÔýKsÿÝÙ§î{â5O÷½ "ë>ò¤ ʼÀÞ¦BR5_È ¥\ç«:˜ƒ4@){ €w¥øy'2à?ˆç¼kE‡-£Ýœ(D¨ˆ�’�1€Ç»Ó€£Ú*�Q¤ Ðô ¦?ðßÿ9Tð^²»LÏлO!}æoù®õAOVÙ\˜²ïÀݼÛPi]^Ç“ŸþXã tü QàßøáGøèæí5L»Ù½캙-Ì¢Î�(뜯ªú¹ºª˨®unêú°'ÚMFÞ—´sÓ×.ƒ|?ßQ??µµÖ" :²€^š²Ìöß–§­AýnÕãŸOvêí%_Kˆ»¬fûLøí:I§nmq ý^µß÷æŽä÷¡ôÜmh7úê,PîMº¨"æ€išÈ?Ôìù8EÀ]…NwwwØ1…»�ç1ÌóŒëëk̇Cµ˜*ÅMµo{·&‡ ±:6­k³½¿»»ÅÝÝ©©ï|'·Ñ§lÇaÖû+–Ó )­æ0¤„Ü gÄœk唑r2—ƒœkŒüC  k¿Ló„ŒàV‰†ªÈ"Í™ÉÇ:3!Æ<Í8®ps}…8ˆ Öù`1 PLÑÌÁ”û9cYÜÞ�pwû §Ó©oŒÑ>SÎf$¿þL f‹?éI¦¶lsUþ‡‚E« ÿþÅ�5jÔ¨Q£Fý©`Ô¨Q£F�5jÔ¨·AéæÅ*`ŠnUèM+fcÛá¬ûøkÝAî‹ðR”’Zl¦¤4¥£�oî‰ÛXní`}všCq~;N×W±6öütÚÙÄSÉ�¦4¤:øƒú’™Í07uŸ ¸ nÍ-ˆt?šëA¯Z-*ýJpÚõiSܵ“HhN—p·B@�¢�SAÏÕ  ¤íÚ…ÎñÝû¤f®^Ïÿî‡îÁAº æ/yÝç-ÀtíUÃý˜([·¹nø<°Û¶¢ñ Ütç�  V# C 0iÍÛVhV‚Œ ò ¿ Ü\3¾þkÔ`ehz†ôÚ/ ¾ëO�Â+M¥Ýwäæ÷fýmíÎØ°-êÇï`þSÿ/ö9aˇÓ»Ày²ßãâkSþÓž÷^€|WçÛQ«þµÙï«#*¢v ›ý?‘¹ÔoŽÍHš@OÍú_R;»Ê©ÐG°4 ¼‚÷+4Á–é´Sú“]ûõ÷rÑÆ~?Njø‰�_f “ÏÝ~ÄXì<)›rŸíŸfüؤw(VÖ V10¸Fz°©ø‹‹Y¤“Y}³BÈUùb a‡âÖÀÛ8',ÅGüÊ_²ó%É�¹D7LGèÓ� }öožuˆÖ>¼4^eÃÒ˜íšNwxúÓj<¤ÞÔÀÿæ'®ñÓ¿}ÜGÔ7°‹§)J|ª>Ô‘ÜPÁ›È8ðH¤m$ z¥Ïvu|ÝsÖU@ Ü]ó0(» ?olØÍÆÚÛ£�èÛÕê,aûdhì�sqå~ö×(œ Ìçè–ÿâ§ö Ó»ÿ5ÐõuREê®ïÐ @ ¯ý òþþîüaRŸU.†�`CbÑ„'ïû;u½�„äßÿÅçW¯¨ß+ÛË\Ò¹•”׫ê]t=©÷—üÄ\‰ L Q1ŽK§Ô&ê]W:‡�69�¨ŸÁlèAŽ6?©w¤¸ÐMÚÏĄ͇´c`mÜ}tÅSþh¸Ô?²ëù>wy�¨¸G�:Ƚuƒ({R¢{÷·‰�y+Bl}Á�è6ƒ@[V>ûÙÏÞñÎwØCÎ)âêú ª¦ê_W·ÑŸf'?–˜ûzÓ4ãx<ú?SÈ«[ã/ë Éåó…8È~Ï@þP5˜&�*È^bž={ UÅétp°^��W˜æ ¡Æ5ò`ó1>ûy7•~ƺšsLJ ë²`M«�êþ³évl‡#‡Ù÷ ªF&p‡„üÔTÿ1â Ä€«ëk<~ü�?ÆõÍ5æ)zlCÕúÉ"™Âf|§l¤„œ³» øµ˜3Öu5¢M|Sq‚ !ر{Ÿ‡âÈÀ>ëçYëšüxòø�…Q£F�5jÔ¨®`Ô¨Q£F�5jÔ¨·Am”€¥èùßk*õ;SÐÙæª~°!÷1å!4t:Wy÷SÈ:‹eí°�Mó=gÂÛþþÁ°^è-9ÛD Q)˜u&� Ð-=µÙØÔÄbX®)ý34i=î­3µî¶A¨mÖÿªào þÝö‘º¢Û*– ar<øÅP­QÝ ¦mìÂæ­âH@çÀüe½h÷zïÑß}ða›þ{œ%TïÛévÌë’Ã=—Ä¥ÈfB(yá®–-ÊA†+¹=ÇX³"*{|=…¢Û‰GüÔ‡øî~Á£ëìçO\Èþ%¤×?€øŽtxi{|›ÖõJêòr¯bìPÔ% j€®žü§Û÷Á\G(M ��ˆS�ñ*9Fþáöû8¯×ûNý¿¹rÕ-š��Sò- (ø @hd‚ÍcïuÐZ=Š\ìòµšé…þ)nå8±�ØŒÚZC˜§'@Vs>0§�„¼®] ȨQ£F�5jÔ(`F�5jÔ¨Q£F�zÛ]<Ÿó…öc#¿´•.7øbnvÿ‡ž°¿7™vÍuîl¹©Šª³*¢àcª8í²•»ÖÀÄÁñŠ]ˆïCðã†í°¾WhU_!9ˆ˜u·øÃjœ´>¤&´Ö ‚¸_5›€·¨÷Ÿ‡Ý×än K‹�u¯ÐÛƒùL€ˆ}G±sKØÙ9w/ï•ùT”ž¤˜º4L¶`V‰ Žlò°}ó=ƒkóºêó ¤é…/Ýí÷jžÀ1@”LUÝ1%ˆí|J�â¢B’ ëêöLeŽŒ$?ùáö�¼ŽGW'`mnX¿€üäçð� éÞ˜ß�«}_lú·Øeìld�Òì/M€,íó8˜mмn\ê¹Ðªþ'”8ÝZÿw €fßO]ó;°X ¡À# YÈìl;…Xø 4‚äªqà»ß…6Uþf¿õLïbîÜ®9CõȈG{“aû ¾ßò{wÍnˆ5þ� ™FÎcHš+BÝžON�Íi svàPUï›aOW˜Þý_½ãO¡FänLñÑNÁÓ_Çú;ÿa±Tñø‚6SoÁáø×Îö7;4øÉOüdËàî†-øÿýú„ÿãO¿d×Z7o°ønukŠyÏŸ§Îî‘Z´Kç@cÝgc’Qú¿w60"ÕéÓUÕÔÃõ´!3mhRz!þäÌ  ‡Ìw^0J÷O]ÕÂK ¨ŸÝTP%”¿»<Ÿ#ÐáAk B0PêÉcÝ5E—ÉTͼª—æ·ßÊ6‰âá4%²C˜P ¨_£�ãäŠòB0B@Ä<È=ˆ1‚˜�]ùo–ý ’b0Ð?³€ÙÜ&r^!rˆS¬jõt¯´‡p:Mê‡ nS ##O0͘æ1F0…JH)aÍ+–eA.Écˆ~œ±·ƒÿ)%#,§jÇ߀÷ˆ&0G1ŽÇÇ㮎Gë£)¶{wB*÷FÌBðû(;ŽØÅ/¨³tŠš¿l£z@�¨DÐPçoñc_œø±.þF�5jÔ¨Q£Fu5£F�5jÔ¨Q£F½ ªWmA¿d¥îßò ÷ *øðܧ¨ 8)`DÛˆépYu“é^�ýÍó½çXýx…Áldyì{õ/:Ar³Ý6¬Ê+ªêçvdÒ**t•�J� 0'¦ˆUsïv+ov¶¨ëƒlxTƒ+uKïö ô`QŸùÜ �U|‰èíý›³©ŽévÃL.Tös¡û~Ó‹£èT gÐæ{{§Ë¬ÖÞægu�Íyèô¿À›{·‰·Vóaö£ÏÑv»wÏüfâºûœÕI(8€9‚)"Lˆ#˜rfü䯿ßýžÏàjr@›“õééóÈéýïøS ùåÝa0î; 8¼@šWŽËÉ/–É€z¬0ždïh‰©ã™ÂZKž{cÉ�ø´‹pg¿Í_Â~—ËýVÜ è¡ùŒÎ†ã&æRÃ6+W™ó}�ò¨ÍMYÍ…HFûx‚pižÕýÞHk“èË Ú½¤­!½‹Ì—YÙ‰/l¾™”êlë°_^! „ˆ8ÙÜ=ObŒ˜¦1¨iMXSrðÅšòE&ñ94­ÀÖ´"fSþ›}}¬üSœŒüû{%dÉ•¨Vö8€'»·ˆÓ„yš§ì19ˆBNROS@öâH°,+Vw (î76„¹:#p0ÿp°Hîh°®œîî°ÜÝaYÖPî…80¢ÆÍ=PŒ±Ûu$ŒpÖÖF†èb‚;qÔx¦Œ”2Ö¥¸Ènm5jÔ¨Q£F�5£F�5jÔ¨Q£F½ ªZÃZ†vÛê^q]±¼Õ�á!.Aû�ÙÉWsäòº¾í€‘(„Í(]½éܱ dÞXÑk§ôòÏSt0s'B­ÀϦf^ R5¥%=¹áqÅÚ_]±† R QölÙÞºÞ•jD:¸#�D$*fý_œT@Ôbší?j_öݬªµ(E¨┸R8°�],†ÅI-u¤½7—Þš��ÿfxuÖÅý€+ÙÏ2éE,§wxÈá…ô¡ÏùÀîP[Þwý>›•òšÁ *vðvØß6>0ƒˆÁ1"r(€C€(ã´ïûðWáÏ}û§qŒ HVk@Î�t‚¾ö³ˆïú.Ðô.œ©Ö P¿É˜�÷nÎ6þ:¥²&@W‹àÐ UNîxQl:ðÙt ØD ‹{ˆ7‡�L±¨*øKI½†Z|‚¨¸Åz4”ÑY仓A‰!@†è -$éÜ´›#6óý˜* u6»ý .÷�-WŸS“Zsá„8áBHÍz;b¨2ˆ;›Ê¿^*dSÞ«6ûþm&ŠË[ƒy pŒ�Jbb„›¯ÅôõÿmÐõ·Ù¹Ù�ï›fèíg�>ûw Ï> ŸDÑ&º|ÁìÈ Ûëµ{=04¿�§?ûËmSÎaP¶ßÿáoEü›?þN$Ù‚xÛõ¦›´©©ý¹N>�A´¥o•ÏÒ.ʆ|>`3;`s`¨ë:0¼³Ðïç¿ &M�ÒÖ˜½{A™ËqÒNí®ÏŸÓöà?�Ox=?�™!YšM¿ŽÐnÏzÿL©Š‹ór]·šUÌŽ öbu9¾fGŒ£N¸yà‰�`B› uWžBì aÂ<™%~±ÖçÀ%HJn�¿âtZ‘ÜÚÞÔìMÕ߃ꀓ–Sœ¢‘C 8^]áúú˲€C3٠ƪÔ/÷E‰!‘`žgÌó‡y;6Á²d¨FĘ�ó„y6B@‰:ˆ1´íXSBÊ’Mi¿® Öµ·þçêˆ#Ä€"bð>bBN‚»»[œ¤´àöîÏž>µxULÑÈÅ)Áb ‚»,ÅÐßC˜SA¨î ¥½•(ñóJ€dPï˜à÷8…D¡"ã?F�5jÔ¨Q£65£F�5jÔ¨Q£F½ ʲǻ.a Tòß÷Zóx@ß߃)�« ªfÜ©f�”Ðç‚[{*`ÖÖè·]¶çöÇ•PP"¸ÝâÙ~HÚÃü�*Œ{à|«®«ÝR@jÎÕªb eQÖ“Bˆòý³‚Ôsgë÷ iÀÛÀ@ dWj‰!؆TšZ–Ú¬°·À\´û6ÊñrÜÚ�/¬? D-?€jC¯â§Öô|ÔEÏþ:Gø ¹bÿ íÎÇ=<ÛÎ¥!~éý‡ìfâÔõYÔ•¶!Ú˦Pg€ L*b1,®äæzGGPœìwµüù§KÄ?úð×໿õc8Æ;oK0A—Ï!}ñ½ˆïü3 ã×t -@v ¬ßõW§ÔÏæô`U|¶ßõ`ñìã49¤ —Œi^Ì^ßs•ûNÕMv}h–ýdÿÈûÇ/ðÚ~-À¿¸ @.kÍo®N…@Pìõ{×Y�¤ îÐ…ÊSÇc0”GÐâ¤#1ì@ì¾[kŒ@ßÕ�¿º]ÐÝ\åvÕî¾wØ�Jªó¡RS®6ôÖMjs¢dë»ì™ñB€{…63ˆ4*@ž®0ÕôÎ?ﮡ»ýJá @‚¼ö~¤ÏüíïpábÒ�½cû(,À»WK¿vÑ»Oáé/|Å(ƒ¨¾üì§þç?øN¬Ùç;mÊçÍ*PUóÔýtæ@Uµ¯›Õ«\ÓTgŸvÞˆÔÕÀŠ, r—í�_�£�ãG·@y”ŠzòÄÞÍ¥sÒ9sNA�çr¯ùD�7 »ø4§…{gI'2”¬¹®U»;€2ªîÖ˜~4lxINÄyt�>g…8Iÿ‰ß1uÑ$nsoùò ëš�ÖÕ×j1¹êBœæêJ!"È©€ã–/oÖøSŒ˜&³Æ'w¤ÈyEÎÙ-õW¤´bMk=ÿó4áêxÄÍÍ $gœcÀ<0M- [ŒŸ¦ Ç«+3b˜öãJ~�¡‚'á�ƒ)ó¹Øï;‰@$c9åj³_þÛÿÐOÓŒižªm¿#Œ�E-.à$1w„»»[ÜÞÞ"§âºâJ@!`òøƒ)F¬)aZ–z^Îî;{ò£*$ûý™“3Ua ¾ž ƒ;nŠú4«5jÔ¨Q£F�ÕjF�5jÔ¨Q£F�zÛÕstÒ{|–è¿Ý+©‚S"°Ò9^�­åpUÒ‹@¸-á¹å\Õìi͵ï¢=�A/9íÏ\kÜÝž¶Â¨bàÀÖÝ€6½}|@é[vа‚L…$°ÉÉÛ�ÎÝEÑYˆN(íÜ[ðwDlú¬@9Ôâ¨õÛ¦*Dgiéz¦ ņø°mÌþ÷{†jí3úOð!ýÖк#Y\h’õS± ðdñÂ!¢ «$dâJâà@@˜ ìˆF[N±¨¹ ¼ù4à‡åëð=ßñ1\ó­«àÀº.H¯ýâ+ß š¿v× G¤5c›—íà¿HÀ™/ô;²Beø`#�® H dÛ¾fw T p§hqÁvU\h2@ÙÕÿþ»¾Rv9ñš={Þ€{©j|1I8¡©ãÙ�UJü€ø¢ýwÜþ_vöÿî̱í8¹«SÀyl@‰$9¿-‚Þ,nA—"¤]¢”—S§’å'À¥ÏѾ_\H@™5@x뜡e3¦wý9Äwÿ%`¾ªÆ•»¹×ÇlzéÕŸ‚|áG}¿²›r{òNaDuÇZ”*˜O�6Òˆ o~·¿ò´ða7Â7û3¿ñ?ýþ—q2³ sbÙƒÿ•ÍÑ‘¹6«C7¿Ó–ÀÖ¿NÀeòZž=È@_o3é ¸OÝù-V6Ýñ(•!Õ‘š¨Ÿi©ºÔì\vÐ׌çéæwÚ,­÷̶&5¢ 5—›³�Юƒ/º³ì¶Þ®ž¯çý÷ÏÄ/vçr_ãž_Åú]Ý1'çl6þË‚´.XS“)Ü%—HîÖ ENÙ�|ÿE Ÿâ„yž0fÄ`�P³°4[}U5…}gqã„ÃÁªŠét€ ¸—8‚þ~¢Ü?„0Í3އó|D`s¦Iº: Óœ‡¢N`¶íåyFÎùì¾¥þ)%HÎîf‹è\æyªíbŽu}`ÄÉXÓ‚u=áîî§Ó–u˜¦isì!D„èÊþÖÌŒœ2rNÝ=Ñv4BEÎI²ÇÙ &0› @q¨ÿr@®‘6£F�5jÔ¨Q£J À¨Q£F�5jÔ¨Qo“êܰïÍåÝäþî¿�íhó8~”º¥¨c*;øO¼Ý%Q{­´ñ鯹·Ôe.7U?³ƒáHÅÐѨÛ[¿o" vqE�/Þ©f]òÕ›÷}ŸG«Ð{lð‹õ4áÎj fÂÞ­ ©sµªMýŸƒŸ–3¼·ÑnˆÎPiØ>mìþõ°Ò ˆ·ýhJꋊçóMµßô�O<ì½WBÒïÏUãª×nÇ@êªk6 $SKª ¤�Âb@"yVq˜¤…‚Y�CÀ³ÛküÈ¿ ßóž_Ããc†Ð –Ä]3Òç~Ìâß—3ú9Í]uãc“;.ÝÉ þ{p@Ý{LNö‹‘`7Æû ÔØ;N?Ÿøkl*ýÖDõÒ¹ ä´I¹Øÿ—Ô\ !6%@ƒÇ€së Ÿ“è¥?ƒé•ïÅ—»þïL®)Øø“ yýç�>ûŸ´‡Íd€ ,oºd@ådI#S”yGëg~§�l›€b ÀO|"âßø{/ã”›>ÓnŸhŽ2Ô;àäﻵ€Ð5ªãÒSc¸fÞ[”ƒ]ç"ÜÆA7�+û».qÒWµ±¯ka+÷RH·¶þ›_[äUkýgÓ¼8è9s,íH1tqðo\¨­7—ï!|¬TcrâÖ¥Yý­:È€0t€"·~• ‚"C³XAˆ pÕ¢ÈÝ›#wsSë«®æ, «Ûÿû{¼ýè@ãîß^G ‹ÐB†ØE‹4ɹ{Ô‹´6�þÒÀÐÞU¡S|k§â?§LÖê&—¢þßýS:wb b(Y4ˆ([ŸÔÓgj3e (ePv•«øÑw!¼ü@‡W N èÇ[0‡"èío#½úÃÐ7~½ŸTÛ`Ð&I×�\¿»Îà“;¸‹‹È5î�2p÷›?‹å3ö±ÊAÒfRñžð×ÿó—‘r£&m¯F:ÏœØåÕo‰b•ÃT�B=s¨9;�›ÉÝ®Ëâ&cN%žå|f ÕM‘BÅׅΠ’ÊТú…Íßt™˜Ö¯´5Ú€vΛdÝ&1tÝ3 çY}àÑ:çÔ0l]ê°Û ^|n~øÓ[_ûOïs ÎÓÚi'Ú¨ÇW·ä/à°H†*!¥„Óiq²—"çꊜ­“›[À4M88ÌÄ)V€ZUÁ9#Æ "!DÌÓ„)FÄ©©ú§iÆ|8Te¾ˆÔÜ{SÚ³)Ü»û …‚É-üCHîN°. N§„”·ð�1ðÄuÙã Tëº"'�BHÉǯÛÕõ5Ý<ÂõõæùàDƒvO""Hº"ùïæ$PˆÒÈJC@?P‰ ~lÄì'ì�u#H»¯*næÄ�7€ØŽ—˜!i®Î "F�5jÔ¨Q£F�ÕjF�5jÔ¨Q£F�z[Õ}òÖmÑ8ó_ Èo¶û{LfO°ÿ×Í/%`oÀ‹bÍÏÅØÑ’¿ÞmS{kƒ½0;ç�ǽ}àà?wˆ•è%ÍüöˆD´t@@r®y´›3¡¦Ð/õ+–HeöhfA¯ÊÔ¯¼*T¥Ã([4A9íT¼=ñAE;¾s'è6¾Ô÷$8«vÆéº³…¦{‡¢vjÒ…„*xxÏ9k›1 é^Ò�×ùç]Å® ƒ'%»#˜@`€™ÜX˜cð±ÇîžnêQ¨"†˜B€N"ÀÝ"ø¡_ýcø‹ßþA|Í㙈=,]ë—~²¾Žé]ÀKn)ßË«3Pâ çc¶W¯ÃUäRõb9¿B)Á,á‰PœP2ãê âßG67b(ÂÖ>¾ �b³j� à–Åã rísV­Êõ¿=c…D PÙµ=�¶ ùšQ�îûvíTúC¤ ø5(Ò9iènÜìœE\M.ª`”c�JF»H·•p5€rMŠ@XKj€õŒ”ø¥?�ðŽÉ�­sP; ÁUÿ�'�×~ù‹ßA/mýYÚÑ}U/®~Å“¹PTV<2‰CO~ñ§ OÜÌÀ�$¨³ÇÿÿþÒŒûÇßÕæ(Ý!ßÕ._±Ñ¶Wì¼Ss‹0é�Ìœ`O‚êpéâ,ÐÿtGR57 ¥Aìà~›;‰h‹«×áD,u ¾ì�è¹ë¯v³Ø}>è×aݯ»´?�Õ¹¦~î œ?ÇÍÛï´iC·Ó.N¤»]P»&w#‰ðåÐÞÒÌ~�;p¬ äœ�VšUÄy1¶Ve0�À�ÎfQÏ�XGäöSÄ|hà 67çÄWU°²ÿBˆˆ!BTL妱¸ÚŸ}<ëú'SÝKsÍ p�8’lÎ˲âtw²,D7ÁÉlŽìï§äDÉ´�ÑìýçyÆÕñˆG�áææÓ¥‡»äË�ãêjQEJ©*ßMÞÅ︃„ˆ`M ¸»3àxZ£Yí°>ƈi:`>Lü/VýÒ9ö¦bÌf§?M˜fÛK‹è¿SÈ•àû4µ@Î/•@�xÃÀù³q¶ ¾[­½ê.%dó=:cì˜k€V’ ‰šcÃ>"ƒÈÚªÁc¼½Jí|q¾ñ«þ,ø�Úû½l"wÄû,è@ OùÕ€¦/º»Ã…à�z�ïG½ÔˆEÒ«uLëÿÞÝGðôç?ÙN™Âø!>¬2€¿þ#7ø�߸ñëÿÛųØ~¸-´Æ4bØÆò¿[g˜p¾×Î÷.!uþëTwóg›ßÍ€�Á@MÙ¿]MÝå¡�íöòö.n£O¥(凿`¼…és³ÎëÂ]XB»(™ zü3â‚EH­—z"À帟û0û wò9#aÝ¿•/·$gÆsªVõªbÆ'0‹ÇXS–u¥„œâ” ’1ëSŒ!`>L8Ž8f·±/ÊôŒ´–hñ{)Æ4O˜æó<0M¬ÍÒ~]WœN Öuašæz_gûŒî0c÷<œN‹Ƚ®8�îpwwçÛY�#rNõZ8`nNKèÈ Tó|Àõõ n®¯qssƒ««+w0P�™«Ë‘t²±B@X)'¨huL Â&:  ²ÿnÑ ë²X¿0#‹˜�¿·¹¼_âÊq·#MDp`Û·Ç<`°1jÔ¨Q£F�õÏt À¨Q£F�5jÔ¨Qoƒ n7»áKÑ)@qIÌ¢ª6+­Dr„•ZV{ÇèUýL ·¯u¹ñdªd³’fáŠûm¬§«bÔ€ÃÕÔ>·‡Éª ‰áÐ9Úc ü£?d5G� °µ±®5øPU lmèE±¸ =@¦�:UÍÞV wPŒë‰ ƒ;‹£×ÚÎF”Ø4í¬¶ÄŠ‚³ì¿ý©ÛXA¿E�E/�+w]èTÅoI™ß¶qÙ;€.|í £ÅNåûb‡ã×Ò„iš!†›}=€ì1 J6W"Wp˜ìº©?#˜"˜™A�!!ŠÙªg1»q"üãßýq’ßÂÿÚOÌ1ÀíÖU¤Ïý øåÿ2Âõ7Cyr�±„Ñäär×Uýßg¿fÏ8 OÐõð �[ÐÅÔëJÜÖ_2@Ñœ2ÀfÙ¯üSñ…V�  höÿäÑপ¸ 3… »šÝâ4÷D'[ìíMª;»l¯ƒ{�Ù;¿(”ûë¹C�Øû}~“zÍî¶áÑ$ûÑW"OÄÜ%ü¬‰0˜g„wþq„—ÿ<èêü�°%¨˜*Ÿ'SýÐgEþÒû §�´Ñ.»+…Í®Zàg©N&Î&Ao‹¯š­í! D.”nHŸù1œ>êÍr3$ 'ÛÍ'àü㟽<åAµÍÃä}E��!v9÷»ß¨'tN  ìßÓç¶Ö7LÜ)üË:UˆoíüŸÞ[e}‰y93Ù)N • ]Û¾r�[ûy½'ìÒǶ´DЇÍý-Öàñÿ[hc£¢éù™ }Tž?pß>.—)û·¬—Úÿ¡ªÌ*¬§œ�\]n–ûRÇÖ|œÁ0Oól–þ�³ØË‚e]‘“�ãq2å{ ó4#†"ªmÈɾsww³gO±œNF˜g‹`Æ4Ϙ&w †‚‘¤Ü­Öæ%ã´,¸;�pº½Ã²,Q„ ˆ÷ö«*æijNpÕˆ`„q}}�›ÿ‹Ã;¬�5Ê’íþ‰à.ÄÇ) Í“�õ)A³‚˜6À¿dAöy¾ôE!”(‚B2H!4’…“%rÎOC¿0Oî4`$&BFÛ_�`¨ÿG�5jÔ¨Q£ö5£F�5jÔ¨Q£F½-Ê-Xi› |Öu1%d µƒÿè3—wýÛ}Eµá¶ˆk®Š{"®OñkÒ°¨ Ä`2¥¥a–}†sùo@�;0µ‡Én‰KžUÝAûƒþæŸÀ‰¿ßùu¿ŒPÉÚr€¼þ~ÈÝï�ßù/€ã•½%š&µ–rÄ=ø/çç—.8wh¯Ô]¡éUP8á1À†*”Ü^*0ží5U(x†æÜ=Z`Û†²Å¨]¯`W¼vÇTå¿"�´cª@-|®âíõÎÚ¶ž«Þ4QÜ )Ò®²›WêÜ® ny$zÀ�¾ Óã?~ô'=z¡;ŒIàÛMöôÉÇ�¾ô>àîc¶]ÞÎË}sµôo&g0˜å½8ºö3¡’J(´±C6o?ðã�'n ЫÿÕ6ÿ[¯þÿà%ü`ÞH$%¦¤·µ¿õ—•`3LË‘õ&[BÀ–ðUö¥ê ¤hê÷“u‘Ä0Dq@?·›ÙEñ ÂXu;¦T¹Î�wÚZôœ¯cG\·ììü�{A™•{^;¦í\¾�7/©ùõrÙ½mÔÎ;ˆÎ·JoâÅê�xSÍ7¥y³­/êtûb˜ Öœ�6‡ˆ5¤” "¶æ3Õ1UÁü”�Ö„”Ö¶ï)ïÆƒ³gÙ§„e9áîöw§`ZM_¬ûcƒp–æ¤PˆdHNn¡¿à´œ�S†ˆ]ÏÜ'¹„+ècDp8p}sƒëëÌóÁ×4ëQENfÓ¿¦iM�œ=VÀ€÷IRë £‰™“MÊÑUþÁ�§o3×x‚B (¿ï#öŽ)NˆÓdne*΂äç#§lÇ«5jÔ¨Q£F�Õ?û]0jÔ¨Q£F�5jÔ?ýUòT@rŽ÷ì -mòÕ¾)+/�=ݰ`S ‚¹Ú7S±Å'l�’ˆ)©QÈîÐòŸ©þN�qàÀ¢µµÚÀj§ô&ÿRw¤MziŽÆÞ–ª”?�ý·jM|ž0·qÖ\…Ët‚¾�ã®ù»ÒY”w–èª[¿ÿ=èR€œ�®Ø¬`�ÖÏ¨ÈæçüÞóߣ ­€.ãùhÙþ}Ö“½ò“v›Cë–‹N{¶C—ëð¼(ÕKíëλ?ÚÙ,„ ê¹ÂDg€�&#���û ! † @‰Ð5'0CÅ2Ècˆà)âó·ß„ŸþÔ»ð§¾æ'q²�å˜Í@~öQäÓ'1½ò½àéo´#°BþYÞ�}lÆX³ îo¹päȯBà ð@Ð`A“€Gû¾$w€É#äŠ'àU Tå¯PÚªàDM®ú¨H¨ ¶ñ„ VG¼wÀ¸¬Þ~KUåé´ÛíÞ�¡;Œ YÆ?&Ðõw \ÿQÐÍ·tèÎ�?†)‘ P³ùÇlª,Ð'¿ŠôÅ]?ÛE�tó”tÑEIMÍÕ¡Í%²›Ð7>öÝÌs÷q<ý…O65¸«þ©ã9üÄoGü/~ä1ž,ýDKô:^]øl©à¿¶Ïí ùÃ#a*• ·Üu…‰v�»6‡ÂE·€F$(z6»I*Ò=‹îž0§un§.GAoÕŸ¼�zÕ¿^Zç/ÌÔt¾­ÆÐ{gðK—�^8ÒÍëªÏ¿Þúˆtn;Ͻ ÑÆú—uq2ÒJ®Óêt˜ç Tëºàøî„Ó²¸½FZVœnïp:qZLó„§Ýºb`|©‰Ë1­ ÂRbšÈóëM!ŸRrPÝìíEëªkF¿Ep˜æLl,ðûH#…$AN YìûS¼Ãr˜0MˆØ]ìû…BÀñx…«£EýuY±bEÖŒ´f,Ëb6ü)UbMÁ¨�_¤Š”,z@Šë‚(RHë ™&HV„È•„a@~Ä4]êSÙ8¨*Ø£BˆˆS@Œ,’'‹ ¥ÕÒŠ´.�œþ?jÔ¨Q£F�µ«A5jÔ¨Q£F�5êmP)¥ú8IÞÞÇ_ãK¥ß(Þï2væñÑ6_½û~±ÿ¿ Ÿ;p!n-Í ö\å-`.„„öÝbC[þYk§Ö˜uÅ'Õ¯4rE»¾xÕe4DdP1„Ñ9ìÕ¡Ô¶÷Ÿø¯Õ’YM[±Ë­ú¿Ç3Ëwú,_ÿ¥ËTvÕ¿«]ÝEúáÑBª]>ô¥¬æ 1Bï%ý9¿—Ppql<¯×ñÑ—ß×ç‚¿ Q�4C“å?‹€!(Xî=OGD Žž7nvÅ¡"•öwQg³�gf5@ÈH#¦0CÁxš^Áû>ý½øÎ¯ú‡xåðªÙì+�ÐD¾Ãò™¿�xó-ˆ/ÿi€n‰zµÿ/q}€2 Õín?_ä�ïì…p°ìyލàw]o1(\Cù*O�¼xÖ}§·êwoyÉ$TÕ¿tVõRo_*ú¾q x‘ÑU€}ÚýŽ !'Y0Û`(]xK¾¨Q �®þèú= ë?dý—»>«Q;á ³úg Ÿ ¯ÿ<Òç„ÅçC?w¤M/¾{éû’%�ÇT?¥ók¸¬ÕQ@°~ò}8}¢ÛšƒÿÚuñø‹ü{?ý ¨G7‡—NRótÙdyT�Ó›^UøµI´i[?Æ °kë„–…5À|>g(ÄIjÀ+×’$ÑW� Li¹cB%#Õ¹·�·¨g<4»Yÿõ䮎ŽGÏ1¥@wi^xSψ>�›G·ÚoÈ[ÖWwžúH�í\r6…ÞÇûº/ FñÜ5èÁËTÛpP¼Øb6÷2g'f¿�0GŠ<3$0Í3nCˆ°,'äœq'wÁUù“+ÏC ˆˆSFL+·¼úB6L‘ž�!H¬nu߯á"‚e]Á99(oã[JÄÀaE˜˜C�Ò`&¶¨SѺtŒºž÷‘û€mÇÚã„ÃaÆ<êµ³® Öu�xBZ²ëkv À‘}aw�&X“9*¤”B2ËþÍ Z¼M`†N¦yÆì}Æ�=º`ßGåÚ,¤�yŠˆ!šO‰\Ái]°, –»S� `ã?F�5jÔ¨Q£º€Q£F�5jÔ¨Q£Þµ¦„h8í* ¯E‰¾³\v挼|Ó»ÿeðün¥Ï·ì~Vä8#èΑ»]„.Ðå)€ âˆ/˜}.q'ݪâÍ‚þ`@u>‚f$ƒõ�o!zÒ�‘tX ÀÖÕAo+“�Î @Š Bpð»Ÿñ.¨þ+y`;ÌëÁ,èÄï rÕ†•»ºlxdUÁOßm�¨6àåû�,u¶t§¬¹4w"º—jTÌ7êçÊAqÂY©3“Q°Ï�Ú¹¯¨OÝ‹àï£HÚ\§{²ÁÞ,ál^í‰Wt]oà½ÅÔlŽdk%ÝCÒÒn§;>ÁÙîŸi7mù')»¦Ü|à€iž�òê6þ �«Éý䌩˜­ÿº ;ù”b4 üp<`š#˜'¨»­)aaSòŸrFrÛú¢úŸæÙæîu­‘›ûUä$XyÁÝ]S³ÅO)aš&„)"rìÖLx,�ÿ‹ÁÉ/s< † 1F¿¶Ú½™Yî“O;!·ÚOГ`%†Öø‹9È’!Y¡j€zP#¹MçTøœ3’ƒðÉmÿCX§Ù¶s�%0—‚ˆ4Í•„¹¦PûŒˆÀo„Ÿ¸n³’?E‘‘‘ÖËÉŠ»‚¹ðø�…Q£F�5jÔ¨®`Ô¨Q£F�5jÔ¨·Aå5“©›î{ ^³ � ÀÀ´%˜»v@�)ô^H¬·çÚCg%5ðngo_P†âo³Ÿ÷;lZÄŽÀ@�%t}_¡nIK̆�ö€“¶W–7ˆ¥ñõçNàÜŽ³©XIiC&P¥ú™ÒæÞK¡Æ�š2/0ö.×ý kÛ- •6enázôćò¹>.aó |k¥¬Ï•UR³‰î@9Ýü²ï¿K¦Ô»¬ij. ¶iºL¸8Ö^ܵáò6Û÷[ư:øÑÀÊ Zr0MlÖÃDf}®AÛf˦Wåñ-¡«çs‹z®³m“ÈH’ìÕ€|ö»ð{W�ñ]_ó‹˜èDrSîë³ÏaùÝ¿…é«ÿ+×ß ðìjþÒŽh.6ðû¼él·{å0]<_Žô@ÓÀéó@˜AÓ»�éÝ€.nWOm<ñ ³í!xÜC`�>â;Í1_Wh¾3—z I/°QK˜ZÞ+ Ùþ[¾EwŒv�l’ ")—οÿwxЭuŠæ6¿Ø>ðgÞ ¾ùУïß|húzÇíDKð󒻯øûÌæ¨@�úô7�_/ôî3þuî&ìî`jžI YA7”°JæÊÔ,ÖýDmàÛï½§�v<޲»ÜŒ$>öEÆÿìトß~mêœüi3÷·…Ç~p¯ü,§�i·h@7jÿ I þRlüu7[i%pŸy^Ž˜[þ¹­ý\|a^ªnÖ&Í{WŸéHŒ€n ¢Kœ¥þ ^�-¯­oU_—Sº+@e^íz¬ºì£^ÀºÿÞYö�¤�ŽŒx¹ñ}X=ÿ`_ ‰Ì±RìîɯsSÖ ’jN�„ꚰ,',‹M¥!F\_]áÑ£Àã[tV$I˜ÖX¿·. Vimjö9%Ī{‘µ�«3L!ÃÀM ¼®`¾ƒª å„)MÈ“¹Î$w©QÕJì @3!„ˆãራë+Ìóó4#F[³ÀîBÔX(PrNXNTÇE‰5Ð ‘°»!kFI_HÎÈîZ�s†äìý˜�òŠu]ÀÕÝ ûÕ" ì<°¥¡t®Eý=A±ÿ/÷2*‚, ’Í}!­FØÈb8»ç5jÔ¨Q£F�5£F�5jÔ¨Q£F½ J$ƒ…›óó…ê·7o€œnŸÈ3•[Œu±F§,ØY ï0à þwˆv Ý=LÖí¶h ùg fú]ÀS¼yh‘?@Fh ¦P×,/`|G¨.zú_²¨?jšL”‰ Ы]¬ô…¡¬` �ƒR%† wÊ~ÝÅØñöb9�°¾Eì´¡÷—?è§já€3[ì­âóþçg®—¬¡µ‰¸7£†¶€ÛV-Ü�‰ç^ü?‹JxèZÊ•ì˜9P ì�>Þ¢�ÓA‰\ÑO5Ã@}nŽD¢Ð!°Q±ˆn)oî\•�Ÿ|òíøâí+ø—þÀ{ñ ?¨ -˜AÄH_ü1èíÇ_þ^ ­ §Åœ ’³Õ˜B˜p˜¸¹¾Âõõ ŽWטæ©8E!+ ”-ŠÄ÷‘\)¿Ròeد…r·‹àØ'˽£îÜvšß‘¹Öu3YŒ€ÇÚdwXȹ#sfèï]J b§ü¬’‘“Öè‚”rN›m�5jÔ¨Q£F�ÚÖ Œ5jÔ¨Q£F�õ6(ª–ÕÖd¿·'®æýö½ VÃõám^vèm¯ß<Œïeè}Û:&h«ô²ðZß#&0µlï†g)�R¬º™@N(γ?´ïZHÒ#´Që·üh³DÞ‚ÄT©÷gÞwjOÝâhPõÜ\“€Ä?ï`-1 6E³j‰[ M¿Q=Sª D©Ú×Nrå³Ö~îΗgc37|¥¹4òÆúÓ9Aï õ,W™ké‘K�Ìe€¦'1ìuæ{µð–ÚÐ~¾�òÿ-ŠþTBÈ—j§mÐy¾º)(9Š`°�IS—3‘Û›Eq@@¹6’‹´ÈÁÀÊÐ�U+ˆØÕ¢wéÝxïgþ›ø£ïúI|Ç+u@ÚÁyŠTß~ëgÿ#„w~/ÂÕ·€8ìÈûÎ8·Cî�/ ¨îçÙ¯¶G´î€nFåz÷iä»OƒùÄwÓÁ�p(8(ŸJÎl‰öÝb­WÂÒ#ß�pøÆfSŸo¡ù©ÅÈ @$ÁÏÌIϾ…f�M@v€^]½0B<|L7 ø >…ÇàpLïÍïø% ¾Ãû,×ñÉå"ó6Ç2Ót=*FD`0Ùg"UÐ?¿ñè›ØÌßm•íy£ž¹!�<\:¤¾Ì5{HX�\bö 2aùÔÏbù¸s¸»ÔÄ9oÞÿæ=Æ�ìªM‹Š H¿‰Ÿ¡æL@] @7»V@�¥ ! ‹tiùmέ³´vÖÿ½íÌnT›ëÛúÓø_—âJÛÉN;üߎ¢Ä¼œOl–Œ °¼Ïkº‹J¸�”wy¦ÛÎàg×|<Š.LòÚÅþÔO{|N‰ºD1¸g’¥ ×¢Þ{´mÞ7Yë‹Må/:·—´Õ6>uF"9øRr~ŽÝ—þSµ´÷€»Ó ww·8�Vwk1€_Ü£F�5jÔ¨Q£º€Q£F�5jÔ¨Q£Þ5Í“=�¥Þï¹ôüŸÖ r½� =6êÆ>{¾å"7`ªXô7�ˆ™íáº�™G4•^±‘.ä€Ò¿~¾ëÝÿ×Ó3“)Û¾³˜�_ÿaÈÓ_E|ç÷ñ1zæfz ûÎOöØG‚ëBíšF€–S®}PÕÛH~ä7�Ó§¾^¶¨ 0G#.X$}îÎk‹8¨î!´a�âKÁÁõf5�þ5WØf.u?ÚÛñÓÔŽ�ûý÷dní+Àv(ï4•~g×OÑ?SúO+ù%£6N|²“§ŸÁÓŸþmP€Û‚w‰ΛмÿÿËz>ÿ4´ëiçöÒ¯L»¹¨çži¯!¾dõOh%Y­€Ö�¹A#l�Œô´¡#Tž<Û|sÙwN#Ôáâ6»s�GØÝ[ˆ�.nƧ¦b«^]Èáÿªw ø–ü<„v÷ó¦êþ|àROßCx¸oû]´�¾˜ À9}AAÔE‘îâw^à¥ûí¢[Í=õÚk¯>úÆ?ôMÕ^ž™ÁÒÖÅš2šêZg`;jlB½'I‚¼&,ËŠuY�×\ï5B 5ÀÁÖí¢àWSµ‹j½ªã¼o“Gâ4cžgLÓÜåÜ+r6½µQ�S²,XN+RNP("G\_?ÂãÇ/áæÑ#̇Ù.é$Hi�êâ‘PäˆÕÛ×ÚB@Ô ˆÀT …8Iæ¸DL�¸Rî¥:‡%f†0›;Sq�ÔX„\#úøŸò]ò{B»ž¸ÝU‡�A×T]Ê©:?w(Õ�þ�5jÔ¨Q£FíkF�5jÔ¨Q£F�zÔ<Ïöð¶êNØäÙÓYx}¿íÀ8žÑl�·HÏe+ÞúšèZAãö}êÀ�ò³æÈrþ£Úó6k|ƒÕ5sચk@mA?ì`ì%Ÿš@…n;­€šv áa„Ûb.¡;-Þ@¡"P&„ Ø÷M22�2¤¥›¶Z{Øj3ÈÝ Z¦s=âÖ¿h Ro´·ôW‹-8€©#uÔ3Ü�ì}‘>à´‡õ]ö¶¶qG]Ÿµñ±³¦èø–Ÿçë½mÛü ÙAY våÿ„à6òL�Bí¡�Ü‘‚‚ƒ®àEŒT1©&ÂM#aûK! NS=âÎBŒ7Ò·à}_øüñwý¾îÑÇ›7»€W %èú[XoÿðÕ·‚ÞùgÁáªìtþ÷Ý#Eyž¡B>ö®+hW þ{ß‘Vc~q6ëp÷»ÐÛϺÿ4¿„GfÁŸ“m˜C·“lÛ.Ä•"1'Ÿú tíýÖÕg }¿Ú¸Ÿ­²¿^>+Ýç÷ó^ßG…PPr�cÀ rWkã Ëç!oþ2ò›ÿКQWis% ¸¥u“Áîþ9•Ön�3K¸s}qÀ‘34—¼Á݇ëïØ0´Ûœ[þ§ð~ßþã_zQºxI5c‚Îí¥Ë±/.+µW7¯7>Q`Ÿá?SXÚÛúwß··.Õ32Q›Ú<Ö¡ó¢ïÉmº�L Ú8¤Â“*Ôñ×;À…{6MõN8[NÛ˜®Çº[ï›Wkço¯áKbgº°Úoat=Ÿúiø­ÿÛÇv1JgÒ³qü¦ï·àì¢"$"¾vš@é‘B Tråº^…0O3æùPÕÿeXå”±, Nw'¬WÉÖæ¬Nôs‚¢» bœp˜gŽGæC% Ä5"„1FsÄà€ÃaÂ<0MBMÙ^ìíÝ•@² ­ÉTðS3ù~®¯¯q}sƒ››L1BT°òZUø€©ç—å„%­P¿afÄi²û«`ÎÓ4!ÆÉï'º%6€½Ücˆ T¤3›“A°mLóäN„$ÉâV‹007(xßi F‹m wy*ç^ Èª`ɶ/æzÍ‹–(Û·-iò–Ý€F�5jÔ¨Q£þ‹^ƒ0jÔ¨Q£F�5jÔÛáÆ}ŠÈ"57|[ý}ÚÝïÅ™zUãÞ=€Î¾w_ÙÃ`×NºŠ�Z³Ïˆ¦�uª{•æ¼f�Y­ï­³»lÛ>CwˆH³û?Ï.DÝ»!ìZÊ1ùw¥³¯mVû¢=Ü�øÃmbP ` ÕÒZ“Yýãî RÇæ¨Ž 0xˆ¹²|t®Ù¯f‹P’×{¢íò¨7Q—ÎuÍÆîÆ’Þ¯W>'(t$˜KBž¼9?çßùJjïnѵw�6ŒÀD28N …A!: ?#†ÙTþÌPb‡ÆÛµÂ¥Sˆ«C>‚Åt Œ¤ †¶xøûn >M�Á!"¥Œ”2BùOô@P\ã¯}>{÷aüÑwþ8æp2'€ì®Š+o|xãƒÐwÿ%„ëoÂέ¶÷³Âþý²MÞögpþEhÆuu"€84Ý 4M@þòÓ×× ùÝ éeo# êaô¢-Ф�èÂyí 4â�4˜�àí¬‡EnÍ_Àóüßo×�Ÿà$‡B‰]ñmÀ÷)ä'¿=ý*�!»‡~o©¡ÞHU€T³ƒkyo½Ñ.na÷3.»Hy½Í÷•iÒ¡Ãëïþ#ÜýÃ4/m‚P~å3ÿëzŒ�~qi³ìï-ÿ÷kCïIJuQáºÆ4»?ü 1c þ›zU…¿É#¥?˜w®"IW“�!Øð;ôÌÑ º�ô‘åP‰ý(”¤»þ©’.Ï� ¸¯Îe-mÈ—RY.ÏjÔ™¢ìjÎØkúÀš}?¯ª?ö-ßKüBÏ‘¸ï+/6»¿U@;fÑŒ5Øl{³à/J÷ƘcÄáx¬Å#NwwÈ’b„ªàîö„'Ož"LÇã%Ë€ñÓl |˜p}s…›Ç�ðèæ¦8™ ÿíÖeu7#s�1 =àx¼Âáp@“m7¯É8- N§“)öE6c(„ˆišq<p}}…«ë#æãŒ8Ú<À¹p¬ì~%ç˺à´Üau„i N^ˆ8Ì3ŽÇ+Ló„ì–n=g*GФ‚œ)e¬13¦iÂñxÄ<ÏK¤¯¶V$?/9§Jä ˆÕ­A©D*iQU¡âk ›3S¨QäN;Ñ?§oe �5jÔ¨Q£Fý³óqtÁ¨Q£F�5jÔ¨Qÿô‡Pî2’wØ¿ÜÚ[±wrÌ&6íI½’¯©·ÏA­ þ¶Í–ÿl¶¬¦Î/€RH¹ð´¶6Ukn³JÞkð ›äJPhoÄĤXHoÕñ ír»ûý7+g=û½ì cpµ„VHnäŽ v»oS *22b*Ý@ Bê¨6öZÛPÜÄ ÈpÄojW½ç=9¸sŸZÞ?»3›(Qw�^ º#CÔßô²Ó@³\~¿žÚ7ëémœÅž0ã’382TVpœAJ˜æ#B˜y2B€_¹3KsD:pPˆÿǶä !î”ÁŒ€LŠfA– ¢ ®®â`;e|îî�àÕßûCxÏ;Þ‹o¸þU@V@}Œ;(ð…€ð?@øê|üº�Ïyª½\Õ‚-*ÜekT»Ee˜ú:´k¦Øí£\j®­`u—Y¯ä§ÐÛ[èéwë #¾ŠK@8˜¥~ñ¤G×4À�óâàQÃö0¶EÝn/ê yyPbœÜ@¡‹(ôY€Óç o~ùô ßa£x†´¸)Tà¹�¸„ôJu2è•ÚUŸ½}"[ä^¨9�»#¸kØúEÞx?ž}àKÐźRPBSýkÖ³ ü{ï»Æßúà£:× ·ÜÇÎò[ 5«—ÍßõºF—ß9¬ÐV ïsw±ðn:ú2#R ß{º«ûþ9Ð÷WªïB—æ�­ P¶¹×†Vhó_¿®Ò…õËI3Ôs…ÿ7N ;о[z7i ÝeL›y·�JÙÏ»û^¡Ýœ¯/±ò啾…L–YÕî¹Ù©¼ EZOõÞ¢€åÌ�m�vq‡"Ä0O¦\Ÿç§ÃŒÓ²Ô�ß�nñæ“7Ökòs6²“)ç™ ó4ãÑ£Çxüø1ß³ù¾ïÂh®´Qø^þ.‡Éíì „âD'Ä0!ð„"Â4Yö<È]*¸9³›P»Ò6›%và0"²eq|«ÙûO[‘ï¯ÈÔ�evuxO¸èmî�hq–y®ýµ'ç×&wã½òüÅÓ'p÷¿ ¹uC4Úáko|��÷ýNÀ¿õ£ïÀgߌU_¦­ý5´øë:PÚå×(Q3À¯×m!Ô„÷©€ô>¾7q1hÛªœ ‡¯;rêÜвpˆ=¤£ÛØ�7Òœžq .NM}¯÷ûF¨¨›�~Ž¥Î<…š‹š£Á& Íš_ÑÇøÐ™1�nF¤vm¤sBƒ^¸Ä/¸ÿï?Ø;õ?K¾x3¤š‘sv…|¶8"Äq˜xôè×7�pu}mû´ýš ®�(û�²T/€×—ÿrÕki»ˆÙõ_@ (nýÝú Ž€š¼5_Ïlö{€ncAÝ2»÷vŠh§jÕ `OË–î_Øï ª:ŸâÓfÌl¿÷<¼ï€ƒ‡¨ Ûê4öœhbpd3B/4Û¹b�9Àn],“ØÉÄLŒœ x¦ÈÈY ðe6‡žÄ¬‰9C£B“�ùY Ì‘Ëd&¤eƇŸüe|ìÍ?‰?öøûñ�¿ÕìâËዟ³Óo`ýôÿtøVÄWþ (>6@�ˆ/$‘Þ&ßAù2 šð’±õÛ·b…éC«:>¡»H�ªõ.`zh»)¯Õ‰§ËXPéÿÝ{ºˆàPÀ|éݨS<ón|R:»}mû�@™‹\‘ª=º.[�ÉÚÈ0‡€�¢¿ÊáÑÔéåÚ¥-§®©�BÞÿÔüyœ~ãýÐÛî0J“sG°Qà´ãç�ø›¿øO—e¡Ûmg¾2Ô!÷m�ة½Wþ�@o@²�(ß-|Œz–¨Pm�OÄm^,Õ6ã^5qýÒÎ@!b�Í—h~ S­&/¨;²Ô¸‘“£Íç¡!jq!>v7 ¶¢’ÖP£i¨‘a¨µ½®sýòTOà �z»|è6 DÏçcl—ÔJVؼ½ÿ{?ÅnˆVQ½p®.LÔªôÜ{™œ3–å„u]Ad1/F lëªøœ@DÈ�ãäYõŠ”W¤”ÌÅ'gd1…{9 ö¹›˜1O¸*÷©ÚÛ¯ë‚Óé®îãîî·Ïžáîî§ÓÖuÁºð�RFJ !š{‰�çR Ž,ëþp8àæú�?ÆK/½„ãñ ‡Ã!0T�5{›Ób3Ià:ÛR˜§ i>`=¬PULSD 777xtsƒ››\]]cš£õϤ´`9-Hɬ.bœ !‚‚Û@ÌÐì‘ËŠ”¬SΘ�$BÀaž±H9ùùq7ˆÓ„è ªŠ,¾Bº£ SsO€,‚´šëÃ’Vd?w/ä4jÔ¨Q£F�õÏP À¨Q£F�5jÔ¨QoƒRU�\¶ï¦ vÙɰXrìí-<÷áÉUnèÕ¶è�dC˜¢²ÉŠ/Ý-ßµ·B ðß;´cmmW%5 `cS¬ZA’Í‘vñƪ]¶ö= Ç®lµ’­o‰‹_ºíë®O¨úQû´¸%”ß+XU01›Þ¬(µQø7 P7¢í>ÛåÒwç�ÜJz#ã$Ýbœ»1vžWþVé¾ ´Ë­F>¶ýèHjãó­<Ìï’¿qæå½/']¨ÀÂî†ÁÑ•ÿÁ Êþ;Øü‡¦’)m‘€E=(Ì�È %$EHΘxOs0 #ЇCŒ` €mç“ZÄ��” 1B¸[¾?ýůð/á;ßõcx×ñuHÎ`v°ŽÉÐù,ÐÛaýä‡@Wÿâ+ÿhz`5•¿ ]ËE‘ß?xZŸŸsAØ×AP\èl¾´#ÊøwTºßû¿ÅmöÅTýeÞ*Öÿ›8‹ìÍè\ÚÒ� ÚåÊ‹÷ºöKç+­]›Šµ¶(ô x°>¢]_qç¥Ý�ŽöZhÇH{«FQpÃUõº~wþ ° }VšIœA'@Wà½�øw~ü1~÷�©]'ÒEktÖÿå|QÒk[#66ÚÍÔYÜ—¹®Ÿ¸úY`)P_xÝÁí½+àíb¢óáäçS6‹Ç.š¦S•ïÝ`ö›ÛOf5  _3‰@¬PÙ)ìU¡ÔÅÌô3›6¢€b—îÛҹר‚;àºÌûý¹êÝnÎ@õNá_ú°_Ÿûä{æú¶ýûÁÿ‹½Vl´¹'ܳȷõ[õÅ– /©N§ÒºÖ�‘³ßƒ¸}S�ÙàÀ��´çË‚ÓÝÖÓb÷9ùõÁÈ)#9Ð�ˆ©*æà÷:ü,€œ–ªŠÓÝž‹äd×ù¸bpŒ6¤D� &|~ùcøÁϾøñûð'^~?®ÓL0`<‹Y÷{ä€ÞýÖOý¾öš¾¦ó]h`ìÉ!²;�è^½åí{Î-n²! ôáÍþ/·üêö~k ©Ø£Œþ“š;€´?î€h¾0X{ð¿JONègÆBHð9J³ý‡µ£HÅ¥�£zû~Þ�tÿ‹[@½´[qEÉ·Àݯ}ÒÞOhîÙ’�Í�²ÿþ=Æ¿ý£�ñ�?}ØžÉ�JK—¡KëÅ>¿h€?¶<Š~Â*¤šKà?`êe3n0µ¿zÿU× Ÿ; ègÙæûÉFëÚ¸³&ß¹½\¶ºïHmD�Wˆl>ÄlMÐ-i��r¦r?#S52C!�í翳o(�^¨ÚW]�Ú1êùªéF =eà‚ËMçfPÏqýX‹×!ô®÷¯ ›zhžÆ—ýÒW‰ Ê9›™‡èæÞÂ"YÖÍ[Σª)Ê%›UÿR³í¥Î�Õ e¬!�•¡š±¦„œÈÁøqº³¬ûeÁÓgÏp{û ËrBr¥º2#¥€´žp"µÈ¤œ!yÜ]`š8fŽ̇‡yÆ4Ï5^(“·H®qIAm.*¤ÍÀŒ#æyT�üïÃ4!®÷=šÄëŠuY�Ö„uM1Ö{‰)zÌAPQ¬ëŠÓéÎrƲ¬¸½½EŒÑÈpßXDƒ9ELQœ@5 ¿4„2?±ÝÇpð{QöuSœ€!N°ï0`Ô¨Q£F�5ª¯A5jÔ¨Q£F�5êmP’³+ÆóîIû}òÅ>€™:;yæfí¿à· E± /Ó›ÍñVÕÎÌÉ®n*Euu�Ro³ßÇø^ØÃìf#^2Ó‹ºžÎ@ýb�̦ÆT†ð;5ÿYl2U°éL8ß�úTÕ‚=ж,x1p® K!€AWG7±Ö¦-„ ³6‹øûL”ûxæ¢} ·Ëò¦jÝ]Êúölµ©èÁŸ²?êÐ3Ú�2´#\nÿæ;½z¥ç%Øè+¡ìA-­ã·o‡ˆõ¼JëUsµìdqW h PLj8™Â‘9€BDà€bt˜�á¶æ™‘!˜8Ä1º’‘!J"¨$0GNÝ(,ÊI† È2�3!ÆEƬ3Š”€ßzòÝøä³?�ïxé½øö—>€9œ Ü10¸÷>/X÷ßH¾ê¯!\}+ ÑÁp°µ‡†éBžDi#´O¨`8Wнÿ£(õ›E7³[íW‚�[ð×@±k—o‡ �kÛrÀ�ºx cNàÜG½#ˆlÛ¶!!ìÚÚYáƒ�PBäÝu½¨«K€ÇP·?'k�a#¿ú¸û¸G¢8àÏh›” è� üΫ„÷½7øÑ�\¨K-^cc•O—ðÙv·d*l¾×å]?õ?Ð.�’üœÕè1ýìÚ¸!ú¶Í˜›~Ó¿´ù¹uJÁûÖa¥Ö. Ç"(Ê:ŒÄV¯NÚð:lÎܯ�;º”Ú|¼õEñ~¤æâÒÎB_Jza¶Óê  ÛÜž²Ø4­ËÞ.}¾|üaõ}‰)¨Ž2ý˜(¿kGH(D;¢�;ËnËzñˆ°wxhehM²{¨V…x!s%Z›3ÑÆ­¨ÏY¤ÞW�ǶG AJ‹Ýs0ùß+²äªÈ_Ö„è*ôuM¸»}f€z2€?‹Å¬+×m˜õ½`u{€Ìf?F„ã„À¡#Ðh¾Óš=N`…ˆ‘ BˆˆîPˆ61äÝe€!¢H9cY#. pZÜÝYŒBòûÍÀŒ)Î8�8LH¡*8�&Sî“‘ºrZq:-ˆ“‘$gs ®ñð¾³y’ü÷víš»;T05 ëö½‘~Ò®ÑÛÃxþã~í2¤ 23ðÇÚCd9Ã$l`<à ÄþC ¸28LÈi{dfd!eLa²v²‘]b@$«Ù18T]mZfµõ«@Ü€Ü.Y»ÿœ÷ãÐÉzã_ÅGŸþ9¼çæGðÍ�sÌÐPœŒQ­�ü…ÿ'²üø¿„𮿠Š×íünâ>Êî¶Š|È‹ø^q_�z†èüï¶Óƒó•·�4_h�+(øÕi£·úïeGD vØ8Ôã*nýïjä„ íré©Ï¥…D÷ŒØ®Ÿ6íÕF 8}§�¿ò&6ÀiFŸÒ Nøìk„ÿûû®ñwí k.ó”9‹7’عÝÿþzlD¦æ†±=½´‹L¡:FÊǵ›g HÇÝ÷ëæ*Ù‹šÒ½H:»Š#€ì&²®Ý€{0Ÿ;œÏ3Õ1ÅO¹{Ü€•;Úð8š¶þ>rKœÙÄð€vsêCsœîVà-¡�”¶k\!‚Ý'³×‹Í;O�édûõª�GêÖîíFm yÁx™BÐ˽wßDÏ€¨ ÜîTšÉãCTÍ ÀýJ«H[­œÉ`� ˆ�+ql]Ýnß•ó97Ð>%FÎ+›ý}–Œu]} Ø(rJX\9Ï~a¤dª â°éÃrcÛ"Hw*°X�5­�,àÅ#�(x»Û=™m#aYWœîNˆ!Vuþº,XîNæ~Ç€išp<puÕËš�S²õ/„zoiÇ»àtôb2Ò�óZïÉú3ÚÚfNÉûKÜ †,ÍÆÝÊwR vn˜ÀòÖcƒF�5jÔ¨Q£þY¨A5jÔ¨Q£F�5êmPë)µíµhþ·ê�‡›y¼}¸$KSgO݃Ú\'ø[·²tƒÏÉó°½ Ì�ÒË¢!WÛqË|ªAèµÅ½Š4ˆ§OyV„¡� ˜«U¬©º]íWc”½��¢^*ÐYPss` ¨ïiï[ܵшT„¢ A®€ˆ)ê47!×~j{µÍU…ä¼SÍwÿiÅvÜó|g�ÝËø{�§k*”Ô=X—‹šÎ¦¶·ñ°�kØ Ê‹P×®¨·‘ÇN]»·¼¾h@�‹Ý¡À£›«ªÜe¡Š­–¶[dªu<‡ˆ&pœ¦‘a2"m. ¸+vÒ �Aà0�):ïãZLj¯; _T¡Y•„œÝ™€æJ-•3Ea²øIH¤y ¿ôÚ÷áCoþE¼çñ�ãÛó”€H d€ܘœ aÖ§¿ˆôôç‘WAüÚ¿†püvÏ¡oçwÛÏ‚j1a¬…êÀÔgÝûoš±�hµ{_á'€”ë¥8d„ÎÅ¿³Õw)¼r‰:è¶SÁÿ¶Íê™_•þy;0µûëëÒ ¸>€¼-\ Cæißí£¸bƒ“ ê÷ë>mÛò…Âéc¹#5x³ÀÚ"xÓT€Ï¾NøüÄ5þÞ¯_cIÝõ¥NúÚÌ�íÚ"½tNw Z§þ?›‡]U]‰Hýç/\{}´JyÙH+¦N/Îv™ HÙ ´#TCSÄ÷~õý˜º¬¾wrÐM @í_'Z@t�[{l]¨;-´7·ù-ÍMa×WÕ]¥±3Èÿzμ$åßÞtGH5êdC*Û\Ûg½òàöË>ÎbjʘØ9½=pJŠƒ5סí\ÿð¹d"Ìó¬"±ºDqw?P¬ü¹Jr6×¢b9Fà€À1L×¢™¡"Hšj.PñùšŠ DÐ�\e/u- �‘ƒ¥©ás^!ÒœÔcÜøÞ@päd‘˺ÖãÍÙ,û×uÅâ¶ýª Îì~+pSû¯)a]W¬ëZÁö‰íqðš’Ùø'ð‹uÿüR2·ƒ=5£F�5jÔ¨Q›€Q£F�5jÔ¨Q£Þµ®'³!GïënvHÍ…‡û@mWà‚z-a¡µs¨`(ëeüO’ ˆ+fËÃv…™P�¨å4 L¡X¬¨U¹ÆðÑÍ!îðÛmÊ75Á1ùÃþb—«JËÉfSžñf_ÚÁ,ê‘›‚²üoo�Žbø1ùëÔüxe‹1(ÄŒèŸUWæ‰4×€>’�Ñ�)ݹ«Æì¬¥›ì,Ñ]•»ÅÃQÎÞÓ¶½­ÿ gg§M�âs‡Í5Ñ÷ïCðós0Ú�Ú|\=Î�£P=,£ÞݘM‰ÉgÄ8#ð„'°ƒÿDìä~ÝIƒÛ‚ç P`Šà@–‹¿ÎFpç}u°È#H�À`(4¥NŒBs€‰Q3 ÖUÁ”�pJ�ð�×þ ~íKß‹oçOá=ïz?| Dب½}AX�>óÿªŠ_Bøºÿxþƒp¤ÖjîìävÿõBÄþÄK×/:ìSÆæ:¬n¥eô&é¨.y§èöÏÕÃsªGö¶ôˆúžœ°i¤tÛ�vmy?ßwâ~±mÖAæˆ>²_›Ö6½ý(î>ôa`A3L¨}æ»;m¹ ªÀÇ^eüû?y…þÈ5’îWÔØƒNkÞ¹Àôjíîú®ßÆÀc'oð5rF%Cus„¢Ä?t1*°ù™`×U‰"é£_2ÄNPm+0¾…}Õ‹¶ò—§�níÜ^îý®nÝ [$pÐ.B¥õC½.+aÉ]´[y;·�Flc·ç×­@%7< fӦ͗>]©ZÔÜb¤�îßuËÊe—þ~luq/îH¢-/õ\t4Ú*¸›+„ž}OY`&lŒ¨˜ÊˆA‘3›m>'äl€<ˆ øŸ"æ8!NñRÜ\½Ÿ%¹;„» ‘¹Ä„§ SœBt€Zü~hÛ’SýC!FðÊFD� `BÎÈp¿œN•™“íÉÔøæfÐî%‚®D„å´àt:a]NU¤d“I†¸ �ÍGâsé#‡#®¯¯q}}�›«+p`w? ÆÕ{.&€Cp'(ª± ejqçéV¶’³»äF%6)‚g¬ñ>% ¡ìkàÿ£F�5jÔ¨QÛ€Q£F�5jÔ¨Q£Þu:�0ÇÙþèT•æâ¢·‡ï´îRíñ‹EmfÖ¸&ñ"iVÌ ÷q½+Á¬]ìvÏf�Î,ÈJ¦¦4¾f®+•é]4Aµûn*ð½ °)0Õ÷׊£€æÎ&Y›³€35ü¸\'µÊCÿ`èÏË/ZC…ÝzW<[:8˜ed€B” ×�nóêûümÚÿ-—]!6S<Á ?D«s€B{¸t;@. ;-»S�R{�ŠÝsŸ-~©6è{ç6 º³áîBTïßÖ[à \jSoÓ­j@,# ³Ù3·ãw›ˆ'„ÉÀ�&p˜Œhâêò,b½÷=ÈÁÏ`ÿ©ˆ=ï˜�4`¤f[8B‘¡‘͈ëuh€(  Œ¦¢äÚ9.YL€*ÖDæKoÊN½Á‡ÞøËøÈ“ïÅ~ü~|ÛK?‰GÓ«�à0{ip“˜I¯A~çÿÿQð+ÿðôUMi_ÏoçÇ¿9a®”-Šø3àu…n;Ñ~†ð˹m¾tÀz½.÷m)ßí@í@(íûØMz¾Ot„÷]%?l¶ÝùôçF~Ðå3¸ûØ¡_ò=f7ÈEû™Ð ùOoâOþvÄßüù+¼ÿ“W¶u©³6ÌÝÄ[>ÕñJä³B÷>aï^H[¢FµM¯q$t‹�$!ðÙu©‰¹úza玹Å�X–<Ÿôüõ}@ÿK›Û:Ø€ûÞÙÅÿþKÌŒ�3£ºu‹)ÛPf@ÔÑÔ™ Ðvͦ.‚�m¾;ê�Òsñÿ} À‹Ì“P/c@õbP.\¡JÔE�ܾRâg”Œ¥sg™KÇA{Ç„fÇP×¾çÆBŒtuuEmœÛüTäbI¯Z€óÉíù˹ 1 ÎæiÆgÛoVÿ¬Ùó÷ÅÌàȘç‡Ã‡ÃŒišªM½E¬8�Ü®ý¾®ì@û6î¤�+*.ÙõkJ˜\©O šw®@­�l;¹n¯�Òºà´,�Á ³ñ'BŒ±®¿æ,q8̸ººÂñêˆ8OnãŸÜ•À@ú“0ù­é4M˜¦â1ÅàĪêÿ”�°Ð»lœ¢:@Ðê†d÷Fþ‡1 û|q/5jÔ¨Q£F�ÕjF�5jÔ¨Q£F�zÔi±¼V ‡_°UÔÒN‰�îQ}6* .Pa€¥ZÂV"@Ý‚CΪøÛ,úÕs̉^ 0­DB`~²ˆ£;PÖTžâV¯n÷z¶€­HµeL;è@´BÚCtm¶³Zl÷;©Å=AÑõ‡©—¥Ë©mjÒÎ-ÀÉ%o¾¨Z¾¤·â›vJqaÈ0u·Ö÷6}P@ ï4wP«6ªn­˜ è.gÙΗÇ[ÙÇ94cà¡=€×³œæóümÚøj_RÿŸÛ†Óóñþç]Uuà4€"!è„À–ŸlÙË ¢¦€#8̦ÞçhÄ ”~4uwê€éBìr׃çJ(13 „LjÛ B„È$„&K\)¬ ))’ ðg.û„2X ¢�ë)عó\hš‚‘XH!˜ð±'úçñµ‡_Å7ßü¾îê¦X¯J÷Ò±à•�üƇ�Ÿüu¼ÏïBxå¯�Ã×udš¼qñ(×N °¯W>*y@¹l½éyðÍ$ÿlöÏú¶*‡Dºþ·ªŽ;ë~)òÛm[´#ôE½ˆ€3§ …“ ¤}5”_­w{pä¨@o?†»ßø(ò;Dî� ÊæÙ×D¼i'àÙ ø»¿<ãÿýË×øÄ—&pG9¨öõJ-¾ZÊ£±ö×Eý]+�ª³úß]ü›?wÐ3¹BÞ·¸Ìɼµ½/䤎0TAË2~Ôœ_DÕH5"P�sAçlSÛëãç–$]?tQ-íxõÃÞX¥tî8ÚTÿ¸Zµ[[›z�`-qe-êI]Û>¥n.½<{ê†d²uý6°ÿîšÓ~®ÝŸµÒfjëôœ<²Ÿh+Qá­:ô\¯{mtóó²IÈöï[BÀáp4‡ å�ͪ¾Ñ€Hª¶ù97¥yˆÓá€Ã4!#b¥5Y¦=NF¦Ê…tHˆ1`š'\__ãx<âpuÄÍ9@U‘sÂé´ ÆÛî^ÄŽ!gªdK1¯wÚ0ÞÕîDgëY�æq·˜8M¾j*ù:ÇÞì¿€æõ_qãð{("‹½‰!tqJÉŠ5'䔑ÝÅ †€y6ÀŸ)8ðo¶ü…äh„[wKœ�È–lµ'´9Ê�“É�Ñ`ÊsŠX—€u¥Ú®Q£F�5jÔ¨QVƒ0jÔ¨Q£F�5jÔÛ Öu��®ä.Ø[¾—ªÏá+ÞÑ€ee†@@Ò)ÇvûÜBê¸ø-QÔ� h“©©ÑŽ;‹íþ�/3m] ªõ}o'm¯yÂ9¨ �H†div²nón}×õEoéë[)YÏ�HP?WúçÌq›Úv;”J„¿òé€ÿÏÏñ£½Â³ÄÕ*^;P»º™°“Ü&¢]B7O¡S¿×˜�ͧzy�c«¿Sh¦øï·GÅ‘‚ΧÞ8øq0U2Y™å,iB+ÙŒv§‚˜íü—8•ݹڬ5DF„Ø9×´±t¾&í�ë:$¨P­j|߃‡?LaÚ̧ZWÒÍnuã3 ç›G!Q8Á®æúè–ø·¡tíÚ­´ûü–—@gç]/Çž°Ö¯9z1šˆ¶_ÁÜCà8ˆØþ!DÈãŒ8 m¶ñë²b] @*˜>M¦yöhÅr:Ùz¼&�ö„q8L8�¸¾¹ÆÕõ®®®Ìþ„œ3Öe³‘F¦yE8�#ˆ¹Ç¨ruPR„�³‘K8Ìól±Ó„)Ú±Öë|éc …àd+rÒwdE”"RŠˆ9AÄÿ¦ÖŸ1OÂTâÄI vϓҊ»»;dí—å„»Ó )Û|Ç̘³Ç1¢ƒÿ!4G�â°�BhëÁö>ª¨þ™¹s¨dº÷Á"düǨQ£F�5jTŸ<º`Ô¨Q£F�5jÔ¨úkM+êw‰ð\hÞj+rl€z±ío@Ìuhtîݲnì�›B¾µ§dĵ®B+ |JELù™©‚߀ƒ<WrM7âÈHÙæõjÍÕ-Ùʬ€(�´36öþê@•´öÕ(„öÙÎ9úbo—lë¢î+Hhc¿¬]L€x¼‚d©æd_îù�qs§X¥ÍP f‰]OŒÞ?Rh[iGÑâàÐÛôû| �̯¬è+Ø®Yz³[uG0qRWOFëÅf0Ù?„€‚ûƒ��U!D°ï ¢Øuk!“pgá¬�D·1.¶ÎÆï àä ` ¬ ŠPV0²¡ÄÑò’) vðŸ5 à<H&°º¢œa6ÿbêjËŽ^ñ…å¾ðìûðK_øËøƒ×Ä7ßü"¾þ¥On¢á+à¸Âðz…�ÿ~‚×ßþ~¬ôýF`úÆ¿ š¿àÙÕøEò.ÝÜV^Å?aÀu`}5ŠÏ!¨¿W�_wd€Bp7’FèQ7÷©» l!MÔ ˆÕù�\Ÿ D€¼Bnß�ÓG? ,€®&þ¯5í„Îp…êºW�' ð÷>tÀßþÀ5>úù [¨ƒƒµYöwç¦ìJ»y±0°�BéIDÛ¹¿³Èï®ç6Óá¨n³XþÓ™¼ä�~%¨TÄ(¤×ÚPuRÄ.^»µ©'Et�yšÍ^¿\^¢³áŒH׳#´›Jm [K:M¿\;ß¾MÚHäQƒYzg‰~ ¢½Àʼn�Ú˜r…j P�îck¨­ÔOÝm ì§ó2ÏWr[‰�©k15—™þŒï×€}¿Ò[š´^ˆ *$¢È Áê#އ#¦yF`Ë�_—˺ ­«“î,¢ež&Lq1±Ê£^ˆS4·fÐçÃ××׸¾¾ÂÕõއ#8qജ˲V¼ýS›Šü¾ÈÜ~âÆö¿Øðæ‡Ãóá€iš£Å nqFZ ˆÑ\ÈÉåúQD�.¨DOQLó„››GxôèÇ«+„²$¬‹Mìëšp{{‡,‚À �"­ ËrBZTÕ ÎÇ8U¢E!fŸwsNîfÀN¶èB´»mý§ˆyšíØã„ÀìDI7t»Ï«ý§ƒ0jÔ¨Q£F�Õ× Œ5jÔ¨Q£F�õ6¨5­f[ä/¨+û:{¶^T’�Ý«½Ü‹feoÅ Mýëìèû}‰ Xݺ³ž6ët2E»è½ÙoQ�QgQÌþ]åmŽ2´ZúCl@~í¥íMᦙxlßÛÕžÛsÐegÿ&‡×Ë…65© A¹§öïy[¡@&¶ywEèÛÞƒP¾ùܯ]Ó™O_æëXèF ÁÕÅ[÷… y0=ÄìAŸÝN¿<À^õ+R†n7UÇel:ÀXœØ6 “eC 29v-(Á  �BEvÛæBðw‹bÜmùÉ2—ÈîÂX2Ô•ÿš9˜­�¡jmQ�ˆFšÉµ_’)¦Õl’ ŠT2<åšIŒ¤«Û˜¯Ð¼’¡,P|âÉŸÄo?ýN<úÒS|ãõÏã=ú%¼<¿ÚÔÄÎ/ .ºŠîë$Ü~ä?ݰ4¦w}5⻿4}ÝvÆÊ>™pï'´8ŸšQb  ”�•¿ng@é”ÿY–n¾Ø›Œ‡æ.@¡ 1 €ë©š¡·Åú™ß@~ÕN1Eç �Ãì»ÉýT%'È» ð£�ðý>àý¿}Ä’�0EÚYäMyN8ç€â”nœRÚŽwŽ»ßöñe�¨sõFåïVݼgÝÊPâXj.y[wØ�/¨f ˜í9{>{ïbQÒÙ"À®Ý-rݤGD¿Ò¦¶ŸêPÕÆ_¨Ó·n8Å  'ÃÑnRSõm’n)Yd×�OáMèÆ�§�àóuD/Ú¡o×k-st=(Úúý÷6&�›Ã&G~ãÐâm|ttK‹ž­1—ÀÿçÎÏÀY¿Ô_ŸÃøR-§9gZ¦½9ºP’9¢lïÈÇWp˜ dÏ,8øøb'j�€ÀóÁœ®®®puuÄÕñ ó<ƒXS!§Œu]p:Ýátw‡åt‡Ó² ¥ä$6§™À(6øY2T�È3Í3æÙú!€Wò €J`fLm¸ûglld¤µE¹°G Ìó�ßàÑ£G8^]!FvÇU -fÕÿìÙ3œ–““8 `ÏkrU¿‚Üm` 3âlàQÿ‹ÛœHȶ.z4A<îÈÖCâF¨ÎQÕQ ˜«ÀtÀTÝ|íÝE¨*F�5jÔ¨Q£FmkF�5jÔ¨Q£F�z”ˆ@ÄJë:_‚Dϵü»ê¬’‹¢³Ï±WÚf½Ûy¢¬ï~ë�%Bßs6€ˆ¸'&!f]®²³�ÞÚÇ÷¢òúÀwç™Ü@w…rÈtàT³ƒ6`C lÝ„ÜÓÖ@Ÿ´âöà»)k´m;8׎v€ ¡¾ëç ªj[öµÙœk§äÜ–÷Wé�m{¶Øà…|gUl$ªEÕ¹jx@É_­²w¿_x_Ùàÿ}~°O „À¦þ�“�ƒÐÀ ô­DvÐ&R¶qMâÉ š( Éfñlý}¿þ“[Q‡�A4�‘MÏ΂FÖ¦2gULSt2 [Œ9g°Û©Ë~ŽPžŒ   ¡€Ìg^³B…!A™V¨ƒN–]UÜ®7ø�§ß‹ß|ö¯à}ððsøÆ›áåÃk–Uß;糧_Ö©€eè­¯}ëkkCпþ›ÁïüN`z7ˆ�ömwþ±OÉ(Ƚw~è{ÀßßWwØÌŠNÈØçÂ÷ì™ë]>�üú/`ýD²q{úÂípã€ÊS)|�î_!K¨s@Àš€ûHÄþ›3~öwŽx¶Äj›_®ûË×O.¹'I €ô�:¿:t`ç2M‰  ÎU ÌQD„2]w /n9ï£Ôoÿ=·Ü�zsB‘óõ©Ë°™X ೬> )D·d°êÄ¢tÿ\AôeY†X¿ôn ;°b³®’�@?`Þé…\•ž¥µ#\š«îWÿïœô<Î`¿fl¢¨9 4²WoÝß­Ñݵr–ޱ#l^»çe¿:P½?yÎù8[üÊWÅé´PÉ€ÏÙˆDSœ�\çß7‚ˆ¸Ú>[>}jy A‚«þc P™ª£Dnñ\•ö‚”W¦ú¿»»Ãíí-ž>}†'OžáéÓ§xúìËéª0’A`[oŠ2ÞÏB©ªúbùß+ê7$M¿ÖŒpYÈ–åÚb°d01rv’¡»]¸ºnÑÌì÷mŠ%%$˜;LJ­í>Q±Û9p�?xâ[›òæ>'†€\È£Tâ ÂÀ\JÀäÄ‚àN9¶èhÿsníñ~5jÔ¨Q£F�e5£F�5jÔ¨Q£F½ÊUâ@D�DßGè¼�ë&=ç{óД6?¶/÷iÏ嫃×ÂæŠM å`çOOݶØ?s‹í¬ê… $Puõ­#PЩۉˆØCtbØÏ Z*«ƒTZ›ëxyÝÕ÷nã¼wj>§Bô Îfá܄̴Ù”êƒúÀEç©Õ¾¶³Ý‡î”m� _Ÿ§z«0žÛ4·þ×n¤Ð.„W÷ÀNßÏ;�I/�?Ï­m†øW|i÷Q.“�ÿ!NUéOš]|OÌ€Ù_«›r›„æhàˆ`Šàpd²¶ÜzbÇÉI-‚œ#B¨ƒkÜ"ßø@ràŸ Àuœ2òº"!r„FC¡ª‚Ì Ö ’2ÄHŠœ�Œœ !A®x×’Á^Í)##ã }>túKøµ7þ®ãkøƒÇâ_;¡[|讹ÂmhomêË5è˜ÛÝ'?|òcÖ?n”6>ß}~üG€ã·á€¾±É7¾úØÌ@.€Aßا•W9ñ º~zûQä7>Žô9 ¯¨dF×–Î@ `Oa€tD€)Ÿ}?Æ5YàÕg„ú͈ûøŒ_úÔž­ T%(D©¼[õsùs¤E›Ë¨wfÙÎá÷’Â:°­�½ª*_uC^êÁÿFjû3ç rŒ¦0—Îú¿^]]óˆ  ƒ!P·ýoóµÝõójg��.Za3Wmæê·ˆÿ<&†·ÝÕƒâÕÙÍeáA¿þ~¥¤çŒðÖlòï9ÈæB°wØ“½úõeg)Ó�­r.°ã•�93ô¿R[ÓJxÐæÞæ——é‚’OŸ’’ÙúOóŠ«,�\”âÀšœîîp{{‡e9Y, €˜4{¤Ã 0‡º^DH’=F-ßc±#Ï*XóŠ)˜ÿt:áÙ³gxóÍ7ñæ“7ñæ›oàÙ³'¸½½Åê‘3&Èï%åì×SË·Ï�œ»ñÈàÀn¹�D­á {²õ¢Øï¸ TçæPcšµ#ÉÒÝ ”û# q%4f$¬ÉÜ7¤s/J9#§ÐпÜ÷Y B¨$t÷#\ü3Fœëã ‰£Âøo…Q£F�5jÔ¨®`Ô¨Q£F�5jÔ¨·A1ÈÆŠPµÑ§sسY;÷¯î?¥^kjÿ^wH("HÚ€ö½‚@—Áª  °åÆëÆ¢Ÿ|gàëSçŽ*zi4§Kn+Uå"£=äVf�d�xÖ´£DJÅÚšãiº|·®1â�.�YnS§ŽÔf›ìû ÊžOäÀ3{†¼Ùᆪð·lFUðê>Ø€3ýÿSgëŒÒ¦jëïýDz$ª9Ú~LgYβͩުþñ¹»ÝNiÿÊeÔê-Ò Þڵēƒ$fW¬y‡¤šœ±¶Ïˆ!‚X’ÔÁp«c&Si’YG3ñ¤l+¹²™B¬ŠIBôsä¬&$/d+”Ì&:'±ÔñAfÁA#DXS`d6’!I�ceSŽFƒ)Ò��ƒm¸¨gKt†H6pGÚù}¶¾„ßLß�ß|úçô¯L¿†??‚¯�?‰—â3G~ñoÜö]ÈOüï¢ê9/¯€H äOßü‹Pü¢½ºó-í;"r—î�]DïæÎàlXú?ÎÝ{ Ø÷ŸZÜ8!»Ø¿;¦î˜�xÿ'~ìã~î“|ìó¤±E"_•íÚ_͵u&�j~ÐG}P‡öo =u‚Þ(üË›ÑÍÀÙP£z€Î}€<Þ…K¼¡Î7�Ϻu£}¯ì—ÊA©´Œyt¤1Ýiê©Íq–±~i^hG*º1�yx’qð_ËTÐmOjChKÎØ èzæcO´�_êùõ8ݘøœM´±ì¿è�Æî &éï>§µõÒÐG‚€³/ïfXª$1Ýñ {'�}Ÿ’7k»\ršyîl¡/–u™VϧWæYâ‚´®HÉþ�;“ËÉÀÿÛÛg¸»;!å‹ 8¦\£~bœLQ^œ9T‘R6‡ØõÀ·Œ0GÌSDŒFX—ÏžÝøÿÆ›¦þúwww�¬fåLq¯hൊ`ž3„!%ä”6÷ÚEÕ{œiêìñÍ^_³�#©Û4Kÿ´šKÁ–uÅœâšÁQü³Š,ê÷am¿Æ·”êžPãš<!„à?c½GTUäœìxz�žÌT‰Ü/Qm�&'(puæ)ëSAJ+Ö”�ÒŠœ³�€Q£F�5jÔ¨¾àÿÏÞÿõh®;i‚ØAêͬ:¿žéíYÀûöÆð­¿ÿ�/ Öë5 ;˜õοƌ§§ûœª|%2Â$ƒ’Þ¬:= xËÃ8¨“Y™z%Š")•ž«V­ZµjÕªU«VýÅœP«XF¬è”ÏÛ�¤OÂrô Ô÷ßÑ�Õñ”Çí  ]Ðð¡® °ý�H‘Ò°žÕ¦�§ñ2ج£ajKQT¥ >× oD *Ô`%ímcâŽCØ i� ZÞyÃÝØ0WÇuëcWã ¤ºóAS«}Ž9b�pæáŠÿf—­ °2RN)D¹Fî7[Vn8÷Ø'“J0Æ4PPG"®6ÜD/ìª5S‡êsºê£­:i:éfðQȧþ¼ôÏ€Aÿˆx�´%¤´ ' ôðf&Sýª¨µaYUAU!I‘9É ‰ŒÄv{…�'q6•x2›c¦a×l~ŒDIdJqB J µ2»�r#)¸ô›5ƒ©bK À†B0­µ¤(¨ È@éDÈ 8mHÌPM¨RP� ÉÉT¦RP©úx´¯Dì‡Ï ˆEø7ßÿø_ëÿµx§¿Ã÷å_â¿ûíÅÿîë¿Åßä?à‘怜wÀž*º3tÇ*‹ãè °Gw¤]&WÝ×0F¹}®büÓŒõ÷� úT­§¡$îHàÇlSRZÛ= îï{þ‡�ðúŸ7üŸÿÕ†ÿéß?ðý8©÷ûº‹ÇÒˆM·öÕ—h’�œ*©ÛÍ[û˜)~¬±±Î± �#ÔÛ7Ûwcï›c̘}Ô‡¥­¡ÃM`Dø¹ñDŽ·/&¶ˆ¥/@�ÎÖ�L0Ü[È¥ÿzÜoÕäÚ]ZîÍéOq� Á~·÷'öùÔ=î¨uŠWËáëÕÌû«“š#‡ß3hXØxñuWt½8艠/¦Çå$(ªÿéüDq=÷~f-ÝãæO¬ÞŸ;+Ïý½”‚ã°¸fB-›ßûQ  T>v|||ÁKµ+ï‹$€*ʱ£Õªh'\J³ÿw‹“6F*ù­Ö æc²ò·¶7¨‡’°^àvÙCŒ;1×Z¬oŽÝ®oë—ó:³jÕªU«V­Zõ_{-ÀªU«V­ZµjÕªU¿@qJöâÙað¡ÔƘT♕—M%JÔ^ÂrØÞq Ë9ï û«üh;j7îà45�˜‚ã{Œ`S�öãË̃PðU šÍS×w “MsWƹ\—ÜÓ{dÖúyêøŒŠ{3�—õ"Ð/ŽhŸíûi�Êø�-½ƒõÌö²^5  Í¯+H!¢`f¿Þ'«æ•U½�ð€3'¤]`š­—Ûþ484ô¸‰g0�Ǹ†³KÁiÜ5бÛ—„mÿ±IwŸýüõ¿õHâä™Ë©[­òD“®³¼¼02‚„JlÊDb€”²Ô©Û¨sbHˆÏnñß²šÙqeiè',VÀǯ…$+ŠÄØw@TÊ&PG߃•°e¶k&„šªÈ„|0ê& š dV󪊜" U*ˆV”¨‡Bµ@ÈÀxx»˜S·[ïQÜ.>ã©ÿ þ߃]þ� ¿Ox¤'þÛ·‰‘ÿþ:ý;ü5ýðíSŠï«Ïü?ÿCÂÿôoþïÿ~Ãÿíßoø—ÿá�£Æ uÊù8ý÷tvQ�žÖT_S˜\‘>æÚÈäÖýªÚ×îöy¦°MPÏs¹r<ß&ú¼€¼4'�î¬Àm5·54´¿+•I Îa!š– Š™pu1ˆÌû¡óƒ,u]WÎÈüÀZ°àèÙ!‡&û€é^¨WðÿÏF ôµzüoflµ5^o´ù:ˆ ýÞ¢�ÈQÑ¥à¼^ë (>uE˜Ÿ2nœ^|pZ§Ýíát¹®ŸÎcaºdŠZ+Ô ~ x6P½¢ÅüGÅÇǾ}û†ïß¿‡‚¸ ³©éUÙìžX�‚}ßñ±ïØ?ž8Ž'J-fJ’yÛ�ï¢"x~<±ïúWñg6_<ñÐâ2¸·_TL¥_JWÔßFˆ)à�À%¦ˆ/È!¦Aíù¡–‚çsÇ÷w<øþ¢Çq@¤¢JE)y3ò±Ø÷§ÿþáMªn½¯�ôWAG³ôO¿D“SÄxÖ$$ ¾ª¹w¨*H"1€ÑÄüÜׂêæôðÜwÇDZ£–âDŪU«V­ZµjÕªQ‹°jÕªU«V­ZµjÕ/P©‚¥*;8MŸ¢¨4@tš¢]eEÁú¿ƒ@ã%î+ð8Ýä@Uø]tLžÀ ¦Ÿöw±¨§)™ÝØrd­Íf%Ë= Yýi°¬mdõLoêÙÍ ŠÎÆìÛ*7b…+ñºs5¹ª›Ç n�® ­¬—DLÞLª³j²Yf·üu?.APÇu>4…3ŸœôF‡9È1KÜN]ûêÀƒêé³áBº%ðÙ.¼¹ëW'ëkquâ5¢â”FýÓ5@†Ë.o¶5Õ*Söœz;�†ÿrjNÝ3^”»ç{Î[G…‰ ”²YœcX÷#¹Ëƒ˜%º8 ¦Ù+ÔH@k·8gjƒYÙíè9A¥7XVvöI€LlmÍ„Z’ * ˆÅÕÈ€3C$ÛyU�&‚VEÂ@Š«�“ 2!k¥djsB?g¡–‚D¦Ò/=6ÃÆF‘ŒóÇ�Mÿ=¤TÇ\þ#þ9þ-þúññ7�¿Ã¿Èÿ€¿Þ¾áK>pï@¤ÀÝêß.E\#sF¹ 'æ<ÁÍ0ü4�¼Éökw*ªÿËß1þ_ËøüëŒÿño7üÏÿ1áßýç µG£„uëdO>-›Ä÷Ã3ª±y‡Nã¹÷{TáÏ€û”MOÃ¥Ïrw9i¼FÌÉôäc͈ÁÆ_}†Ó¼¶žÁÞ±ÖÌ^$áOëágºrê$€°nã¼$ÒÔ1¯ë˜âMƺ×Aâ@, Ù–üÑ0¯g/¿ý ÚOâê�TuAîhíq27–ùÓš­áótb—¥µ];�“^µøñ¶y¡VÁQ ä¨ Øs%nDNNsþ¡X´Lw&ÒvŸÏdçg4»Ç67(sfBŒ–Bs ±ˆ€”œDÙΩTGÅÇóéÎ Ø÷'J?ÎrXµjÕªU«V­Šµ«V­ZµjÕªU«Vý•ò†ç·'¤uÍŸ+¨&ûwàêßKlï ¿}5{lGáçÄÜíô; ̘íX³ù{WpµÿÈ_ò6©’+‰aYò1£¸CE:§´ÏÇÙæÐ@•:I25€þÑ~ÚN¡9*´,^�ÚÉl mù²C™7«Cûù1ƒ¤šºßã”È4œðÕ­€Ãåjæ$îA2Ut»Ñç<æîè‹(vÄ6¼¸G°$î}ˆkŸÇé@†s8�? ‘çˆ*×Ó~yãŽT0ZrsNâ�'1¸½¿$b‘ öûñOäÖL�"ÁÔþ¦ÚL%’¹8´>L­}ê4ûu�( "‹oÆ®è˜c¹Z\J‚$û¾6;p”É@1ª@"ò(;¦’B‰‘D! kNb@+8³]‰íÄR6%)U�(T+ЏŠ[m§œ�ŒÕàív9Ú�o[Ïzf©�JPXæôáq%"fÕ,eÇQ€ÿ\þ[ü+ý]1ʉ±m�þ¿ñÆþ_ñ;¾Ê7¼ã_yÇ—Tð5Uø’4gY4‚Àwwú�ã!ZÿË<%>àßÿáo'üí?0þöwÆ¿ú;¿ýû„ÿð;ãoÿHøOä‰t0ÆšŒ¹ñ=ž%ZoLk/ÆX‹.€|¯"Y¯cnö4ýÝf#w¥dëJwÿQ[ã¢}>§„œRŽ“gÓ«*öçõ0g#>[æ|©j5¶’FÄŸ•Æ3IÎo�‡»!q�È[Æûû� 9;°�¡ŠQ$?Ÿ¼elÛ†ÇÛ#$¸ÚÂfççvûN ­áës?ðñýß¿}Ç·oßñýÛØ�‰“ÇTûŽ·ÇÃbÚÜP ¥Œ ›+ýÜÚý­=‡  v—"W%#e&¤Ä“2_•P$F´�šSJ ÕúÑÎñ°HƒZ±ûóOûŽ}7RìÂþW­ZµjÕªU«®µ«V­ZµjÕªU«VýÅÙ»R+¤š=;7ÀTç|\u•äl ?þB4Ô©êXVˆ`WêŸÕú#ëž@�ÉZ™Cnñˆˆêvyì¶úBCUÖÚ¥îF€ð»øò¾µ™™‘˜ tuõ›Š‹Ú¶-9Y ý@˵mÖûÚò´�P`ûµÏp?þŸìX¥vªìÀ®BHºèTÔÀVŽè j·Âm×.–ÛèvÊu°„&ÄO'pç¶ôläUÜ_ˆzìÚ‡c?£êôó¸!\¶¼�þ ßî7_ôDãïè~ólÿÓîA@‹ §lîlà}j×Xœ2D ÉÕÞªb„¨ƒ"È‘×j4ÔÚæƒSUBe !C¥@„Q­ä¦ ¥â}oûß6‹‹6Å;?ÎG@Ô´·>Î�“)ÿ! UFÏ�Þ²·ÓΣٻWÆF¤TxFA„ %¡Òn R„c‰€PA$È P&�1Ä11 5á?Ö¿ÁăZL[k…x†·ªBª ó��žØŸßP�ü ü¶ þî?}Ãÿåüøòn ÔBøý ” |Œïø¾3>v6ÂÑ)^|6tŸH0ç$:ç\Pt˜ëó½Ó‰ÙÖêÙè u m� xZ»iì¹1jè¼×@@hmœ>�Ù¥`Öv‡íl¬2ÄwÙH+c¢‘jZ�f¹]‹Ab ~ŸÒq3¹™â÷Nwó!ÈÀ"NZó¨RþábÙÈM~=˜/8�”èØ¯Þ>»T\ÎMO^ ÷g§Pä£ó fk�óˆk­}*í{êÑ1JtŠwA߆îšíŸ¡N>Ä0·yÕ‰—ÀLdƒÁšyá Ð�yÚËÝA�<’sî_SÊ]M>æ,cËúå ˜Û¶µ~{> s¨;J­¨Gµçˆ‘ÆÜv¿9G <›¨Ï ö{‰ú5I)¡Ë"I)á±mضÍ\6¤öû]¼çqJز�ÿo�‡·‘ûšcÏ"ö0#2@ÿöç(Õòûqà8vìÇnNR~ï`¿'©RÎ�0a÷:�&»N‰�V¨9éT‹h�s!&‰Ùî�ªç{¸˜ÝÕÞÞË9;i€™¼=Éžï¼J”Ã" j­î@`Î °ïûúǪU«V­ZµjU¨EXµjÕªU«V­Zµê¨”óPf¿Lb�á,ŸïêÔùåøK ÕM@wˆoYñ@!Ý3\™†8ö”Élç"¨ì_ NœFõžöLj½±¯îVÓž¥Û^Fk³•…gU{þn‚Zö®ÔfŸ:ÊÁüîdc0Ú$* {S>@A&°x~» ‚Ú@÷f_íç6å’¿ª„0»b[!·ëå€ËkÛñxQÂ×v-þ$æ~íûÚ‰i(tüç“cMëÿ4ù¾¦Òf�8'ˆVÀµî³ º€(�Ó†Dž×Ì´L)ÎÍà½E ö“º­xŸuä& ]NH‰P ÷Ÿ#1’‚êã×F›E¿ D $J\¯N¸¸„h’ЖH³å�|ìž×§ûéõvrö éû‡š‰ó�òºF’ê‰,Ð|¹o¦NDŒŸ¸/ëç÷oè™Üñr˹‚‚¿˜ä쬢§5•BT�ê¼î†{Ê0T¹gªÌ¯ïKsãgWõÏîÚ Vnɟܨ?�˜3˜�”�ÇõýÝm÷í¦ÝÏK)ØŸO<ŸOS™¥ÛͲŸ™�]1r`¾�÷f}o.mýLì ;'¤œNîÒŸëÈ ö'cËÙâg|ÛÊ ÌÜ€p þ×R|õ{; îç’³ÿapòsëMÜû/õïí¶"ÛeTŠˆq x´ßlüí« K…H NÕ�B¤’/•ÚÉä K#ÚU'iR¸ÆöœUk]ÿXXµjÕªU«V­ µ«V­ZµjÕªU«Vý îÛb—c݈#°rvï0ÌzNŸö¯Zià’ãq§PjSÁC´¿`.ÄfwÛcøz.êùñªÜAúä9³úråhÎĦÎt>XŒŒJOœT²#– mÓ”ÿª‚Z¥«¾�ìütB‡æ¾²óoîÔÏÁìØµ«o픂Y:²Ãm'jjNûð ¢è¥³õgö§Aå¯#/œî¤Ë˜ISütü€ê9vûrÌyL\7úG¹gëçÝÙAu×PòÜeð`6CòN Í ¹eLs- ¢H Ýí¢e?;ÜãŸGWv‹ ŒÄ jc J@u€Ö€i�ˆût‹º½¿KPªQ jS/ç`î5W€Ö³…A¹bÓÒl,ŠÂ6^íö( T2AÐæ™ ¢À¢ p¯P(;èÎ AÔÖÍ‚�`S£‘i`î Õ3)±º¢’¹�øðDΖ)��ÒIÇN’ôµ‘â1«âÛànJõ!�¿@Ã=F„NÙÕ@tEÑ)f¥‡è ìŽiÅ×#Mn,]Ñß8t¨ï•‚ë¼î'�qPve;_ŒöçÉ3Yò“™JŒè€æ @Þ†y~G”—£ ÂÉaþ“Ä’é\4ìò5 <¯Òí/ÜÖ ë�t6$¹j×gBõ}ú¹åÿÝêî?· Ýíó¦ãBÀY9O …ÝÛO˜bl'Ü]¯Å ÏÅ_´ç‚8ß>ón¸›?p…Á)žà| ý~ÅLÀn rÂöÈN ø2ÝÃZ޽Yü?ñññ�cßq”ß¾ý�}?@¶í�íñÀ[ÞðØ6P2ç±Åœ_.Šþ9 Üö|5͉hD5û|èUµOu<Ã4ƒ�ÿÅ]¢j?nÎ �í�úÅ~V˜ooïøúõ ¾|ýŠÇöÀöØÌá 9"Ð *XŸ ‘aóO”ÀÄ(T‚“wà?ç )s'bèÏ¡íNÔlýÄÜÏ©õŸõ‡‚9;9"�h¦63 8ŽcýCaÕªU«V­ZµêüquÁªU«V­ZµjÕªU¿Àƒûöç :«ö�)Ó^nT Mv�®˜‚ã4A¹ q ×+ùöª4…‹kþ¦âwüÀ�´Ûø7`XD6¥¹íä�¦öR2±È°Ê'"ç•ÀMå¯<±çó÷¯Ä ¼3à±Ç¸}{{oÛË8WЭx?EºrmYú+MsKõ&NCOÔ ý§‰v1_5"!‚ë…«Äóæ¶û�w¼=Ã¥E´ƒæÇ~à¹3J5K~©æp˜)U0rÊØoH9y4I1�‰@ªL÷Éf�›’N‘óý4�0¸oÇÑɹèz?nLD©;1 ÷£”jUl™ðöþ_ûŠß¾þ†mÛœ”`ç,µÚÛ¸àO5º•§ƒF†9O!þYOý@¨”í®Ýzn3}v([ÙþhE…8¤» ?�0Y–4¥lÊKp¿¾ð}07b€ƒ`$ ðÞr°Ú¢ªÕç‘4Ã@-ŽÝÛª6ÙÝ.ˆCÂ9ÀJ( äĨ¢ -‡ Ÿln”jxqÏÄ™€b_j2€—¶-e J…V†B Zm^8èlÑõ6N¥Š)òC•�*AY¡Éæ„Óìvä JÉÝÿM}+U ©¢JB*nOïDCÈÜBH¬/‹€Uj³R³©“�ºr}L0_øßÕñcqŒ1D×Üúi�óù2þŠ9våòÙvü0ß)dÝGe<<ݾe¶Gи[u�¹Å£œ³V†ÃG‘Ý^~;º±ÅÌp_ó�¸¢�'D1Æ}v`ñseà&úÃÕâ®· t$G„˜ĵ’æ÷Œ{‘Ân�è€q³´N›¨©ÔïÎìåد Ím¹ÛêìêrrÐxßsš“4[ßöÜöÉ5@ADcÆ=¤ƒÕ:÷ñK³œ¸ÀßÞ nîoto¦ 7Nªpå}žžk†�~ÆöxàË—w¼=Þ�2Õ!ÐáD¾ÒHˆ¾ðP»·€”7lÛà €*;¤Û}�@úæøb`ºRšžÕèô¼ÔȈ¥xî;žÏg_£J-®î¿'Á1ÀÉÉSö³$Rʽý"Š-g|ùú¿ýå«9d‹¶©"8žŽc7‚fˆaÌ6²£BñÀ†ƒ©»5qbþ3rN-ÀôRÓ¹_L9T!Rýû„”œ�mCÎD "µ ¤–îÆ´jÕªU«V­Zµ*¼G\]°jÕªU«V­ZµjÕ¯P„-?ÔlPy€­7ÀgÌ¥î@øÙÖYõòâ™.`«@jËf$‚ÝÖœÓãq¯¶Ø t«×®~ï@It)ð—äòèq¯Â×NT0ž ™íYÀÖ¦Yh˜…@šòxFRæ}‹@¹A3÷/–;è£'ûév¼˜3Ž@-üéï1�¥)¥g¥»ÿNfõ Åþ‚NýßÀz¥Ð^�¤‰èÆž??¾Çð³vv÷Jè™ Ð@]TŒóØ»AÜÎsIî¸1gå©mãÊAèf��ü÷œæ®0÷� ©�[’�Fl;\go¶ãRÝ–º‘#ªç]CÅÀsˆ©t‚JB£E†” ô6µ?‘BÙå«�ì³Â—jöø‰»*ŒÌŠ‚³Åˆ#êÌP@N¦Ü߀"T¥Šª0å?"Ñ"õþ¬* $”T�Å¢4›’_ÕIP$b°ƒA‰ ¸IÂ.(daTª›H5rCU‚Vµˆ©2¾çÞ Hµ_¿ÁL iÚ÷<� ¢Yå¯2ÇóëÇü�C²ÏoÿXÿ|ëamk{#šÁom´;LjïÓ(V ±"vž,¨¯‰�äÓ B12$¢ÐDîô1qw˳Չ¦Hƒë¼Ó“ûJŰ{ï}uZ{u‰gr‚žÈKwóÛÀc¿îã{_moœæµh�³ôp¾º©Ä­üÚëD׸8h ðL»ÌÎ gòZÿÜl ñ ö$&[¯Â¸QàšÁÒèwûÑò¿“<òoc�^ô.?ÿ3ÏE5Õfñüàü“+Õ™¤Y¬H È}Ì´Pf# ¨ðˆQ #œô¹Æ EEBB•bª|‚WbŠ}ò(Ô6-²‚! ANa k"ê ]4;|!‚$9Øá¾T$U ÈÁ'F…RBUÅV’ µ*¤Tbä2b„°”�PÊ�¬d†j$�Ð|íH ‰³[8“ç?ï(Â`…Ù7s©*Ä*¬P$²)Ï‚6…*‚Z*¢@D©x²?ü9å<¬ºò=¬5-ºý.ó�¦ÿi°ž�n$7Öðý÷ÜçEMXXúÚÉ�ç öo$€v ñ=jTÇÒ䀀 \¶w àÐöõ>Þ*"øï?çéG¾q¿èÍÌ?¯ z†·or=:! ÝÝ~nÀì +@}^[ŒJ¿Æ~ï ¨ÅXÜ­ƒ7jzžùW—öš{îsJB\D¼Ï]î Á¶�ÎdwàËý•nRóà%�I�€¡¡p³ Gǘë�lbSœ§ÍË¢O~~Gʨµ"e{ÅÉlYñÉ\“�·„”í{(µpüñ�oß¾á¹ïØŸO”R°—F¸Üðåý�ücÛ²?ƒ™­=Ø~ €Ô‚}?ð|>qj)h‘/)g<½!'tW‚ì.Mížk5à[MÑþñýÃîRªØ÷wämCJ LÍš?!%[W UîÏ71rÄÈQ¦îÉF¢r€Þ"n28ûÚCi"œ¨*Äç”x„‡¨¨vA’ǃ|aÑi81d�}ŽnÞÙÉ ã:–ãè_«€µnPnË�J=PŽl×69᎗ÀªU«V­ZµjU¬EXµjÕªU«V­Zµê(UÅÛÛ;¶ü ö·•ˆ‚XÜîßLn9D�sÎl°ºnDZƒõcÂsš•ÔsaƒJn)®C]ÖMÙھƸå6ph#a(TÍr|¼ÜOÌn‰>“ h‰$oCCäÛùû‰5€ÈÈâä‰Ö&“�§B]m<õʨ’k8.Ï$‹üþ1ê1âý|QéÒÈOއÖ~0^æÛXHnÿ;¬›ïT«q,]©…°¾Fý‰®Öûç±Ô®á00ò‹çíîÆ;0[|ªì#ús/ý‰íŸÁ�çnuÎ)ƒ)£¥QH£¦°#�ÝN¿�Á1Ϩ…±[胓qø±¼dTÿ4�˜P— ˆ‡*„̈øx1…xJMñªPV°ú× '(+ª)3X"¦Žl‰H…!%‡EÌQK†ä‚ZÙ8 Üâ**Èû„á'DFI ͨô£h3ðGI�@p@.�89hV!mPÄ�QR6F)ÕÕª„Ú‘oFJìÖŒÌÀ!-ŠÆ7…9ß�Z¶;O4R@Ÿw~6ÐnXܳ«ì}ŽG vX:Ð}�1aJ¼»¶68I¨}Hç¹tÞgëlÌEµ¿¯o!Z@b¯îa}YÌÄDäQíý­å"®�örÙ˜ðÚ (ï÷9iÚ¯÷¿³S ќޮ¿8ÉÌ(LdcUpo2Á¥`¶ÚDŽ×kOw:¸9  � p÷š¯�Åô&JGïûõšâ3¶Œn4/æKm~´uгkÁü©WQ97øÿ]·¿¸$úê4ñ D�`»ÿ›U¿ƒÜH·ñr”‚ãØññý;~ÿýwüñÇØ÷ûqX‰ß�‡­ÕU;X�³E1Åø##ã¥`>ññ|¢Ö¨‚9a{lö ³=@„¾§”û\©(‡©üÅŽ]ð‡ÚÚ¿ï�¶Í¢ ÞäœÍ¥ gsMÒÍûñ|T¨¥šÛ ›+€‘9õ>N'EUêèW  …¹'}¬Çg²ùÞÛl»Ü öûêÑK¥”Ñ¿JÝ5Ê®;‘CÁœû¬!¢qO^µjÕªU«V­Z`V­ZµjÕªU«V­ú%Š™ðøò¶m£ÔsŸaæêî¬Ä\S·“=ã±:!ñ1À·á9Áž:¨Ù�d°TS’!äÌöZ˜9Xj{ÄÀ nÆY%ÊÌ=·åSPsv.è’—�NDà˜ €AlÀXC \(¯‚üï`¾)�©å€3ÝbFwÇJÌAymñ"2`F4è¯bÎ QmÉ ( üŒ}¨gepìß“5tøÃùF€ÊvîÔ<}®í¶yQwÕ[BäÀÿp‚˜÷‹Û3‰côŸüLĬjˆï'ök™Àœ‘h(åízÊFÌH‰gˇ ImÀ!3�ëîc�’ï5 ˜ ”–ÞwÌ®hfjµ~ìöc¡&›·’Œ ŠëBÉc<ª“RÄÝ *T@éóD(«)[aVþRÈc(¸«Â‰P2ˆµ0(S�6ÀæöÓ�ØæÙ'qBcUTb°Êd"ˆÙ  6w!°ô‚6 ¶pb@<ÀU¤1%¤¢à¤ –5ML†ñ3XmMàþ}‹pÐîÞájèó€o„•“"»¯3ýGÚ× z9ž5(«¯Îžã6æüapf¯ý¦�޽M§]Õó¸Q¤·�K<Ìä ÖÑàF¢sNÇ:çÎ T‹DÙzÅl¤¾ôà‰_qêYêmÝ›5çm\iP/·(—Wm�0�ðFsTQ‹àãã;þøöþøýwüþûï8Ž£gÊsÊÈœðööÀãñÞ *ðù¦p·QˆH£Ùˆ˜ý9p”F1êCœ ™°m¶Ç›ƒØ­¯k5°]<*©Š`ßwˆöÇŽ÷ÇooxWÛçãñ@ò˜N>£{€E dUf”R ˆ”N®*e3•ýãèÝ/µ –ŠR J)8Žê÷L»?0ØÜ0 ÞËÙ¢­)‚Z©pœ[#BŒXû|u7£#YŒ+_Öçû$ÞßR�€a„Ï´þ±°jÕªU«V­ZjV­ZµjÕªU«V­új{løòøB)eRW³Ù{gq� fÉ3„½´ËÁµíí礖ˆ–í]ÝÞ^¼Švq%mº+³_u€¬½à$ öðÔQ³‡m1Ü�®že«n?Mèo€^{ÝÜA=¼8ßy �0˜*j“•7 ìуä`e$N …Ûœ7Œ'.î D¥ƒDͺh� ž]~ÂÓÚyÊÉzè��mÊ íJåÖÍêÿ8’‰ À5@þ˜§­�<ð¹U´õ¾38ïâG Î§Eÿ¸O¶ñ¢àÅl��”RÚ�(Á&5,µƒˆ6ˆøât � ÒÆ @uìHÁêÀ9šRÕmò$¦É¾]"c¬¤àÖ.í‰ ”/bÄ—ð+ȹU|œ±Ïð–¡R€b9”¸·ü(*¤l`H@‰}þš2^”ÁY-ßìÿes4HZkz™“`­ŒR)p(8û|ð1.�´ãêeæ J U )¸›•°Ì ¡»yrEÿY=®c·ˆÃr8zŒ˜ €®�´fƒÝ—=#¬§ô÷Ö–•6MŒÿÒÕüÍuÀ^a�Çái\“£ÈçœöI}¯ä˜ó@òŒHeÄ¥æƒ?“²¨“»ÎóiôŸvKú>G§i¢ý>tÿoW— ?ý>ô}!û­!�Á,ßOý@#ËádM?‘¢óChçgħæVჷ76˜š ®”4ݑ㾢ÓÂc}Í z»÷YÄ‹tBÞÔHÅtïœ×èêþL¨ú�â€+@×<˜óÇ'Ë—ØгÍõgÆÛû¼¿½ãýý Þßßݪß@öcZÔ‹Žràû·oøý�?ðí�?ðüø@­ŠsÊxgð¶aÛ¦öPª J©)=j¢y"$"°» ¹j&Ü5À;oÛöÀcË`·ÍOY ºáíM�ÄIx>3öçûQð|î(¥ Õï÷9½AÕÜ‘ò¶aóèƒHô3À¿Bõ³õC)û¾£Ö‚”,šà¨µ?—”*¨ü/ÈÛZMœúО?« ç�Ü @µ¢Ös0úƒú3`J9$‹X[Rbä-£Š¹áXlŒö£@D±ï£oÄû…bDɪU«V­ZµjÕªEXµjÕªU«V­ZµêW¨·ÇF_¿~¡”˜S Úü~ÂÖë І‹Ä—à � qpûi,êJýnå®�`WÈS{ÙÛIQi 'QËF_S1O6÷ P •+aûŸ¦´e'„¶w÷4œ;€ö4„,s\HÜ.÷œ_=¢@§ª%ìÀWJ1‚Àz@x©n Ü€"Öãl„ ëÿfû\–YÚ·éÙó²Á0Ôõ=g;Ø_RªÇ¹Ëšl÷Ïñz«CžÇ˜‘ ÆH:ïzÒ“ª«Z/£î¤Ì�ÖÜ¢&p¬¬@•âøŸf,›>H�g*©*4¦¼uÀð � #Ù¸oÙÛÄgPh�ZF¸©áUŠÛ‰¡"� R}\4'ø´J 5ò8CµBª�qr’ ›ÙÊs(3 ‚ÊŒ ŒDU­©c–çÃ^È0ƒ7�!ðèJvn ˆQí7¨Ä¤$TöF L�TS¤"gvRA«@Ȉ/ÒNwc@”‰˜ Gel)!�p�Â0º+Ñ3Ô‡S h]³ö^/Vüµ8…ý*Æš7'•}$M`²^´×Ä�yíãCcN yECÌTÅœBÔÇü#>†DâC´˜'%h_oNÑ%4ÏÛ¾N¸2ù|÷“qòr†ÞÞyN+ÆÙÌŸ× 0^—ÄI>ãy Ä@ã­mºî* ·ï3‘*nì{dt�ËI`|ÚÍ)"#½bŠqÐyÑÅÕŸ@/Ñ/:ÅÐä$r·^êŸ^hOÏt³¦»£ô'öÿ*÷å!!¥„ß¾~Åûû³mf‘0Ž"�út`ûÀsßñýÛ7|ÿþûþ4µ> L8ÐÌ)aÛ2rÞ¼±Ê¡9PªE˜�={¾}ÆÛÛ†c·lzõ{?''FN9%<ämëÄ;FÊ0r6w€œ?Àœ¡úžû�rT˜wl9£¾`$NH� #.Ôòa`–ù°h�c‡Ô„}{¢Ö/¦ OŸáªúâ1Uª?³¸ÓqwP±È—ö¼×Àü„œˆ’Å̈‘Š» ´çÆìÛåÌ7Ï%Œ”7lÛˆ°kI¨µâãã„„rìøøxâ8ŠÏ»„œ`ÕªU«V­Zµ*Ö"¬ZµjÕªU«V­Zõ Ôã±áË×7Ê™qá˜}­³Ò¯+ŠñJ §=Û”å@xLÍ5ìÁ»=vÜ.€ÆUjȹ&�$p…?Ó)‚Ã9†úÎ�t O)¡ž³NFÚ¹ÕkëÖÙ]˜Ø4Ê‚²#/:¶ï@3Í9¶µç$çj᫨“Lq=@>pG+¡ºbí¥þm–n8¸Nâ9ØÐ@cN“åÙk4GüB¬AÎ:©Z�1HÍ<ŽÅجOœ£ç.@#…`•>±�¾s+èóÀǨ4R'))oÝ–¸ âÁ¡d�æ¤.l°›þfuèØ†•�äù, ¸õ3ó´7�ýœX¡Â¦^ç–Ù Ï3·\s‹³°ñ/�” ì$ƒÚ¢.Z‡™-ePHΦz²Ÿ¯[¨Wˆ*X3URpˆËhk)’9g!¡’€ëP›S2›nP6àZµ$ÐC EP @1Ûl�BÀ ,@3(5 ‹X ¤HLÈìDœ¾�.Ó üïߢufÑlÇa¤�0ï<•Éú]�ÉtŽ>?Ûù7[þ›õmj°În¸Š¡íâ’Í]QéX«Æ=a„z`ꛑ™2©ÌÉ”¾#I&ËwàŽŽð†˜�áHr/˜½™óƒñss_Ð{~‹‰âu[—Åœ*¦•“¥ÿ©Ÿ;þÜmúqZ ÏüÁEÆ£9„ôó5îâ>IV7çüâøÝ1DÇÎÚï%vF{Nñ5Š@ÌÒ@¢8EøÐ�—ê¹M�±ðŠUqsOý/¨”ÞÞ¿àíí�ms²eÏUÿ¥<÷Çþ�çsǾï8Ž¥ÔÇÁîH”NJvñ$A©DZa‹�$À=ðØ6¼½?PÅÜj1«þ-oH9#å 9oÈ~�±ý‰ß· iËxãÞô ÞïÈé›?­|ÃQûŒŽ{t�\š9w^Ÿ±$Îý�Ü ‘I-æïòè{Œ‚^¯Z¬Æ„úÿÄrrr—ùL~ókÅ•$ gÕÿU¦¿ëÓþ£Â?žùì0 SÚã.D½8ÿ$X¯:“¾®}EòÞpÓµÂsbW�W¨¨6 ø‰}7»ør(uØÆwËù¼ù>2R³»})ZQk±($UH$É”3� ¥X&Iå "³èÏ9;y‰ *(ELe_ªÏc–¶î\ oïØò›»¦0ž;‚ÇãáD‚RJý9Ì@p³Ù'Jæø’Œ°å �íÑÉ çç;k¿;Ôaß?õ/ÙþÌñÈcGDN¤³óÏ)w2R)~¯tg�NŸnüzcf¶�o³]üåå¸gÁZf¬vП˜º¢€¿ž´£=Ãrÿ‚ ˆ¢r0·?åÈSÌþ ÓxÕÙfyŽvwÕ«�_³ö�ýy9‡ÛCX+›Ò¯ÙÞ%ÿ lÓ3é'ñò8>™E;`àÿY]IC‰«=£Qéã ~þ#¸>ãJz!L]yVéŸNãgÁ£[ðóþGEôïDØÁ !í ˆS ’L”Ït½ •“ 0{^»ÙðkûœÀAGóQkPþ‹3 Ä�LáJen U#ØE¶ ×vaˆ-‚VÃïS"ÔÈá�!q‚²@ ÁwÀ0Aë°t3Jblx@PëñªPXÊ ¥ŠÊ›÷53p4Y ;¿‚Øìû•AQF9*ˆÅ|-Ì¡CÌA„‰À9CÕܪ*�P�à$6úÀo¸z×] BPº­%¶ÑXSg™~WÂÓ°Ï7»{ß´±2ôÎÅÝç¸Kñ5κλ®4;²°Ï]ÑY/¯F‡êÇ›bhš$# Z7qÿ}Ummx0¢j\±©õñD®²µãÞÞcZ‡^­›‘t†¨Ôod*9­#�š ˜0üóšÔ‰j€oí‹~\ûnõ|þÁÈÒît·àÄn�kÿg‹YÎ;Oú¬Ý?[Hi8Û\a"Q£ý½9¿œi½^»Þ q_/Öãvÿ¤xR·÷³s?ÿcF*)‡)Â�h8Ôÿ¥8pïj~«íÙ)¥N 9gäœÝ¥$Fµû¤Ù"�Z€¤ 2;%%6"�JË­7b@»·ˆì{ÇÔZ¡¶œ±as'ƒwsÈ�>W·ü¨"m_¾~Áûû¶Íò¢ Ô‚RÅ£ *¶œüþfÛcÃãñÖ‰)¥þ\–ðçDÈu¨üÍEAû88þØÜäæ�Òb™SDÑp+°ŸÍû<_ËNÌbê´-èˆám“ÄÚ«~­–ÀªU«V­ZµjÕ\‹°jÕªU«V­ZµjÕ/Pg2W¢aM�¡èj¹Ì“¦;f=ûïµ�ÎCÉO�00»QÇ—à”¢ˆ£éPÈK5³�Nþ¢7*¹Q@EQµb>ƒÓPÞÆcôüvUóС>�í¥“z–Û~âö]�¯ *ù“újmn€ÞÓÝ•!4¾Ù) (M£í-Y·�$°‘¨pExyÚ®Õ-‰#ü.öÇœu=Hzc_>‘¦¼ïW!Î- b>ð…@pþTË,ƽ[ôLNÀËœê«#þ, ÁÅ)Z â&§U·¹®”ØŒ ˜}„>Pè¬ÉÆfsup·4\]¤ Ê„ª­ Êê„;áÌ ÊÉÇA €P%dQ#%¨ÚZ @âÍrîA‹`s|Ž“"6Bâ›A‡ÖgÁ …F„7@Ê­ìc0.�ôb.5йxz^»^†ßølã:úÀä8‡™¸¯gÉÀ¸v™¡;“Dé8�$Þ X£«ÃA`ˆ‘�©Iõ/Ú3ÜÇí‚oçx_*ÂÙœãD"#É@´QÒ8Vï–Cm®ì`¼65³Š$I! s ¡>O @R�ì- bT>Œê à WpÝPµ@©B* 0€Ü¯µ{ÉWµ¾b#-Ô*Ф€TÖ˜�™ÎPTM€²ÅbTBuÂCAŒžëÌÌÖ£™�@È›"A7é*ÖN†‰Ãüºd °ÝéÔÍ�`Xi„½w Y'|>hVäI!bíªÙOÀLóôiNXÿ!!0xT§Lz 1Ìc¤¹îÜVÎ&í�ˆÔ”ÿ—ûÝ|jô³bíï Dgð¶ýo=¬gëÿÔ™<6ÖË3Mn¾þ]©¯”OjõF¦Ã™Â0ÆÀX‡k…õûÔÊëùÜ�O.ÀûÔ†Ÿ|ޏY“õ'>£!b�œDvþðõ,ôv�žX1úú ^yÐÜn+êyóúÏž©ýþ‘sBN�·7<ä¼u•z)Xàk½Ç½ËììK­ýÞ(þ½ûúöìÜÌmƒµŠÿ©�jdäÜŸØUôìNo� ˆ ålN0‰ñöö†Ç›µŸ“;+±xäþŒe÷ Ä’[6p¿ÝK«?ž·ä„äý$Iܦõ…t’CsEjÏ/iê¯vÿ�Ç$<¶Íœ@H‰{¿t÷·¸!ŽâÏk»µ0%»6`Pfˆµ”B¨ÕîÁÌ„U«V­ZµjÕªU£`ÕªU«V­ZµjÕª_ T*Êq@T)‚×ö^>ùßãpÅh€,³•¿ý]Ä�̨‚o/“Io,õ¨nà¿v‹jê8VW‡1"ã3Ž�°2ªˆÉ-š5`o<£héÝ^´+#8×”½¦D à›šJZj5!©Hß_‹Bh¨�8ˆ6Ü dÉ›Ê?BA©ÎܬpcŽuËK¯®xkp™NÊØa­<>ׯ]ƒÒt¸´—ùTÅ—:�‹¨Æ�­°ÇÆžg-€ëzR®Þ�7o'nö~®>‚~ü·AÇRU£‰5¬N†I<°>vrŒ²ÞAmr âÖ&Q‹‹·ÿ¯ŠÊŠD  BÅ 1¨ qТÙwHQnÖ|YL]ß”˜¬]ªL¤P©þ™êJnû¾¥©à“� ”̱A¥ØnXŒ¢ JŒ”<¶¢Å°Å%¨&w>hcÙAfJ¨å€:É…HÀü�l’ldd@2°ínwŽnÓ­�ÉÂ* BÈÌØF2 FÊc]›bD&Ž]ÔÆää‡8ˆ\ç>� –§¨’vÙšƒÈÀŠ)|çkiˆƒèžAÉýÊ;ÚìOk‚^�öé¤>§°ÎÌŸoÖ†æ�•iÄ£ ËïNÄz5ßt¢Í–ý—…jŽWˆ6üD=ÉÓï¢Kü³�@EýzŽÏ4M1(3c$ªÝ·g\³«gƒžn¾§pR¼ã|nt³^O?v"�ȼ¾Þ¶ãö²Œq¯ƒœvûÉÉ�Â`¤Ã¹GâùåtýUÿËŸ‰Îî�êG©8Ž£ß¿ LÏüÿúõ7¼¿;üþY‘S4‘N÷Üv ð¯U ¥¢”‚”²ƒÏˆ§„”LœLéÎN6ÿ|�ðfŸßz•‰°åŒúx8QM,ª`Ë® Äu¢¢j $›ýH´ØÅq8Žû~àñxœ°°åŒ²=z\B  ¿‘­´9 øEQAVêq1)e¨)":J5°^U,zFÆÏ›ãTsœ�0à„°Ä‰mŸ¥z¿€j½qZµjÕªU«V­ú¯»`ÕªU«V­ZµjÕª_ ö}7åz©ØŸÏ·;u©žLzµ‡ÿá;Ò€ivùâèÖ ~뜥쟟TíŠ ¤V߉ʲ¬9¡^°Ÿ¾…ˆ©Å첕1ò¹ƒm³ào.Õ­üÍh€\yæÀ†PÈB–áT0w¬ƒ~AEm¡�xÐ@·³�-ù ô;KýîÁÂä+ݦ¼í¯âkœEûuÕÈ5`>*q5Øik DìªÝ+õÏ/æ§ýœœ^ŽÊØÝƒæ}P´Æ>mköÿFJiù𪠸-~w° ¢amÛV3 wÙ>¬f™,ZAB¦Z�t>€ØæÜz»xÒ@þàVá#ÆþÕ}2B�Té™å* …²“ºeºj18›mÛ·”7ÅjõA\Á*Ts㨪jöÕ cIøz¢€’“#ØI= ’e ‹Ï!0Œèà à¬HìŠÎDb@7P~Z„ÀF(%‚¢f§P‚$@±asi�‚E±¥‘gßÁ£`g?ÐešW9:ý$±ÍDád¢›Ïq·¨Îûçðø“º<ì¡çf·Áæçu§�ýF:¡À«Rs¯.Ú# N4ˆÉ¶ Ò#ô:O8y'Ln g§=©þõz¯¡»ÓIý¯Ã§i¢Ñ1Eïöït†fîÒÈ_ý�Üרû |²Š"8%ÌW}¾æzZ•_E¶Ð¬Ò'ºŽQ ¢&â׋5ñü›@f{ÕæÉç<ŠéÌ:¹!1ÜöÂzÿýÍô.-b¨ìÌ'"l›�ÿ_¾|Åo¿}Åûûä-ƒ‰PEPŽ‚R”R&׈»w8й dI`*È[và?#'‹Èyó$ªùx¿u²'ädîêd4øÐäÄPIR�-hOcŸã\™ “Åpb°ß„D*ŽRŒ´À O¼¿ï(å@ÊF$M)#oµzŒ�¶~U�GÕÄ~�a"¢Í jŒSÛï)H%<‡À£nØ£ xж1-%'sp6BÊÑöQ!Uè´jÕªU«V­Zõ_[-ÀªU«V­ZµjÕªU¿@=?v<÷¥$ 6$À=Àª†BX¬ÐÁ›äÓÛw¾_â-ÚÕ«:€ HJÔü ±b¼¦ ™¬ïŠ9ž(È]8Ûã€.ØA�bEjÔÑŸ.<1NÐ�ýLäR÷‚¿·ÑΘS¯OÞQåß⼡­]·Ö¹©!\©éú�A½ýøD:˜ŽH'}«ÎªfÅ @ò³^ÔD!¦ûLøàÍU´/Òg€9›ÜíÞ“KÇaÀi–/lc—ز‰¹“xùÆÉö_aÅ”Š^Õs&íJGt8JíŽg¶›º^�Z‡‰ºV‹€x_Å®ÛZ@>?Œ(`ŽJ³}N¨Å`w« xX:ÀÏl:õ¤ä ÐjŸK ä÷ ˜LL €$ÕÏ¢¢H‘"3 îxÁÉ̈‰«Í¿œ@J M€$0 ,³ hA œØ@$"s;Q5;ï7•ŒãPlyÄšÄ xÂÈ»GXŸ(ø±wÓ|Š|:�Æ0¼Áhšß]ÕqV„wH}"ùÚâ?çñ—¾VФÚûoî�NЈgk÷‰@ÁŒ#¸L6³²›è¤Yï™ôüW¥™4¡¥¸€èË9M'œàþ¸>ĘñÛI¼Ý÷K£M+OÒ°³ƒ�äq&tàe;®÷¯äí„?ç×OAW}=r#—é<è.C¯�-jã\O÷S•‰$Õ÷‰i°…ïÑ]:pGÆxq6z{Cú§k;pì÷tÝíš>�7¼¿¿ãË—w¼½½ãýý ÛãáÑ¥?wDâ€=by5c'ªYø;ñ.å4Àw¶õjÛ6lÛ9'lýV{{S2@;g$÷Q[—UÔ¢ŸYOÅ\PÈ8[}P$Í™‰Ù€ÿ‘eí®û¾cߟÖ7ooøòåï_¾ �iIŒœ%e�!ìÖpW—A‚1‘T,æ¨+þAP7çýÝL˜g‡X"íäÊ”R'+@D©2¤Öõ…U«V­ZµjÕªS-ÀªU«V­ZµjÕªU¿@íÇ®¥8Jéy³- 8ÜÒŸÌ&˜Á´50$(R§(Õne€Žô}wÈŒ†µ43u@¹í«)ål·lyàpQ£ƒFœ’+æ‡â–"°@ƒèToº[‹@™x.Ò��.‹«þEƒE.�\_ꙹCAØ€‘~ެÁ‹á0új'ÛD³"v:O @Œ÷wÃÔhŠøL‰)+»ƒhÑr?´±»1èv§c1xØ�ëùðŸÍÿ»Ïèþìó'bÈyÌÿ¨sŒ¬avÍ&È×Àiƒ=V‚•`ç ˜Ýܬá� ý÷P ðeuÒû1Ü:_寂,?YKõ}a`Ĉ¨—3R@c®¨T›Ç Tu°^$Ôó»…Ä�AC<ÀûXBên °µ…ª‚2»ò<�x(ƒU,7]*ˆÍ¹ g…–!5WJÎp'�F˜Èä}ȨĠ#õ¶°28;PNÉæa­ÈaÛ*Šœ)·^ðmšóí;éèŽIŸïÀ%ƒ}Œ±ð'þŠÛø�öûgõtÈŒ·4Û'SpܘÅÿ´¥n1¢N¤BWˆw§'”4^I[׫‰¸¹Â ñ0ÛÚ(U§Ží£‰B?‚ï„ûk1ÿ]AJj§4¥+ w Ž4º¢Úh=3P¯„ÆÍé ëëöd⢗{ÔÍè±9¢?ß7×õîg>¬A=O§ã†žHz›ÖØHÄû3n#⟤þ„›{ýUÒÔìœ�· ïïr?¹}±'&�ðmôF·ËWAqË~ÕÙù¨E ±rO„œ3�¶í­ƒÕt´ç"'Û6çŒmÛðxlÈÛæä| �ˆÚqKA­‡)‰À•!úÀ–R˜“[üØŸ²¹p6¡Ô‚ý8ðññ���ïØ÷ÂÇÛ>>žøò|âíñ†„FœàÞUµÓ Eßä”Nã”Æ¼ª½tQhD„ÑŸÓМzl�·¡EpxÜ¢Ó0¤¦å°jÕªU«V­ZkV­ZµjÕªU«V­úêÛ·oØ�'j)Ú³^uÀ¯¦�Š IS13ìî°Æ¿�µ¨©ð›Â›;@ßlæõdùOÔS¤ýE­}^T»º[ª û.·¬z1x¾Ù^G°Î~oQãÖ®@‘)¨½ò¼sN®Þ&dÎÈö}6@¾JŽ:¿èÏб—ý]AœÒPýNæü�(` ¤�t0 –nm{Œ|p¢ÊáJ0ó0 4‚Kw.'€nuíï„húï%Œ¡ó¨ˆíñ�´«?6 ÑÇó'G;>+ ?ªSˆ>v_mÿ HdÊr;ws€ƒ€®U†ÔrâqJ��Êi W€­Ð®2ÐÇ÷”Ró.›;À»Pç\sF'/«Ï÷O @Ü=€Z‰@5n@B„\í3B ¢‰E¥Éç§‹$(ÄqËsÎ Ú@” ¨¨T UÁr Qµþ|8!‚D›Ÿd. Ab6Ãæ¯'4š@"F¶ÉdŽI{ôFÊ îŠ[ÛŽ.9ò üåyœÐý¬ä5kéWå'³ŠFhþ ˆn§#Í)­½äÊVA(aÎqh÷p*¸siK­ô(4£¾f½Æ’#qá¤9'½pš*ݱâ2ù~\ôª{yIÇÆdãü5÷—ùûÏÐc�ûvÿ`f»1Ý[ÜŸÉ`W·…ë *ôOá“ôï|Žé0Ý™œ˜Åh;v¿k#¢áÂý†Bÿ6…w%šh/ pBŸÚwSçL ø“Ü‚ß|.æœ|m²5*» ÿÛÛÛ¶!Sµˆ91ªÑIrK­8ög¬ÛXI)UÑ„ÀìvþØgNý^ZkéŸ%"l� �·7lÛ[~ 3÷ç§Mp”Çq JH‘“=óèã�·76@â¾6ly³8N}ͬ¥âùñ�çþ���û&Æ~8޽Ÿk[Ó˜©GÄÔRQë጗ fF%ê÷ˆF¼R·þo‘2WW*ô>(CPýd'o £“ÌI! Nh$žÙ¥Aúb˜[ªU«V­ZµjÕª^‹°jÕªU«V­ZµjÕ/Pÿo/�ku`7*ÿ‡µ|ùUÄm¿Ý.š€ÔÞÀw'lw †+DÓöÔóMµ�’¿ýn¹°$€€î"É^(€Oªù´ŠŽö7Ëöa_=L¡ûy’ÇTE•`>%À¯ì&5ð^‚¿HE) t{z„,pqXMÔ]Ô¥X:wÅžTA)ÕT†â?î=jÀ­ÿÑú®©{ÅQÙÆ«^1¤hû­À‹ÖÖ“[AGtäV¯ËL}‚à^à›¶‹Û¿ªÏp»\ë‘K�0ö¯mþa1�Ah†ÁÌ –ê*q‘fã�Ô¨. êuÅ¿À ü¯0�üÆû€iòaóÈGSþsŸ0˜¿NçmÀ|Ÿ£êÇòÝ0Èm�èh)0�JËk¨¸Ò AñÎldƒê`\õ¶ÁÇ™PW 3�‰ŒÜ§  dk‚âŠäq)3@@v{kîýE`(WpI|b z´@²yË-BÅÏ «åBW(´Ö œ'âN2\é;Këç1HôÅ1 E5½Þ|²›¿\Z_Éäk®hìöêM+�˜ ñsa¯Ò¶œ{CÈ×~Qæ5Pÿ² Üy´s×÷ÀÛˆ +þ$ªêiîÞœh¸¢è‰ˆ3TòÆŠÐÌÏÑ;:F$´ù=B|Mù/'0{�Pf%¸óÉœ@4:HÂåÏ(æõz>:éx�¼\ŽùҲ݉pÜãõ&N⮽#´�0w�Òì6¡ŠÃÅ'cÚ÷§=S ff‹ÉyÛ°5{ý”Ü!À@õr”‹Ú¿Ý÷Ûý³T{&8ö‚RìÙ«9 lÛâ]’­ïÉíüSJþ5›»SôãŸF"ÈiöYÀœ šƒŒ‘%X¾ïv|� º£3!o2àÎF4�úºQKÅ~ìög7Àÿ(6á{L±+ûYŸ–ZQÊ�r”þ –Rq‹,±>äÞ‡ "ñµ:Mר=“ÔZ°Ç~@¤ØœÍy¬ÓÞgÖ?Éçgs1¨H±qZkñX‹JPYÿVXµjÕªU«V­Šµ«V­ZµjÕªU«Výõýûw·M=¿áÃ$ž‰Þ«¹B*u%}kÛP§$®A¤¹ý³ê]ÏþØ®Þä ˜‚¹—ÄÁyv® én¥Vw¨“Ò§ÞQ ÿÆ!bÖÚyPë9Kø ’‡8€F(�hqàŽ¸�è€{¬­ šCË ¦¦Ì ŠZ�ö{¢Îàt'8«lÏÛÎc‘^·5\ŸÓ/oçÁg¤‚8®1~á´¡èpõn ‹ú¸kÞS�­ŠeÕó)B*”“ÃZm µß;A@�@LµÙƒËsîÅÞ{€_"éÇkDW÷×â$ÿ»Å;;QÁ@%T<þ ªc@ ТHL¨E�zøÜJþP¢Î çQ¡TAY, e€˜²¹NœÎ“ÈFeÃ^i#¨ØÉÖÊ`‚|“TÙ-S[+Pj_§NÈt¿¶L7ªvÜ­ѱ$~ÄÄ‚¾45¼’_›þ >D� ·‚V“Á[ÃÊ rg€Kû§ýPw5Q¿–š$„*Ò‰>Ô,º©Áè?ŸK?“æ…j 1ÜÎ[êýwçÀ :÷•¾lÔy]·ë:Ösn(îÍþ>\³žé þF¼"ò9Cܸo„5î×"]ùyÓ4žèÕ õ|úˆ �q‡ÒßrFùãZ{Y õæöOñZiw~¹½ÆmK ñ3Š ëîÊÄMô¼gR\ ^¹lÜœóëõÞæQ•Šcß wðÿíaªÿœ·Nf0 Ÿÿ0Ñ�xìÇñtb  Û)%ÔÇczVÈ9ãá`>ó°ûà.Õ‰��`ø*3âÌÜè$L PRÁC¶~&ŽLm[©ÍÁÀÀöÃÏÍâŸíÜ›#�}Ÿ R}œ DŒüp”ÒÝ~ˆ* Â:-�Ós‚ÊiˆÑèSÿ�ã ‘êý`s/%†¦ÔçMQ�d¶™É+`ÕªU«V­ZµjªEXµjÕªU«V­Zµê¨}?†U?0ÔûSÑ­OºÎX"€tþ3Y@wðÝÊ? fãþÏÚÍ‹#4)8@CÑŽpõãóLT¸žå+üEu âæ@Q]êv±p‡2€{žÔþŠ×úØsß'�A,cƒ†18Îû(ÎmÿGÐþÆö{&м‹§³Ò—‡èçuëÆÞÁ>º�¦óÒ(«&z·Ÿ1›å5çîbæ0iÚÿ01uúì‰É0îÐ4dêIÔ ¤@*©~9ü¸Ã¾¸�ä1S^;±Á"qÀ”ÿ ‹‰ñÕAÎH¬!k�*‡«–Åh'Ĩ RíâaÙ!¥ls´�ÿ$P= @•FEÕêÖÔNp2·­Ækè�hQ…J1$)D�±.q‚‘ŸD€úªÙGK-PüñÑÜ (�:Ðû¬«�›2¶«»[?7žºÝ~SóGŸ§}ÿ#n¤Ï«þ9=­YÍÞ:Ì‹€œvÝ3 Õ##ˆ¯%L'ð?Þ \5+®¶lrémÑ}B¯&ÛË¢™$q»úÐ�vq¤ÃÝè´b¸­}�k‰ûlE�8‚ƒÖ/\V»¦Ôã!Ô]&P�ýÞØ�ix�,¯ìFQÜ~{®/ÖüÑeää�`ãÀT9qZâ}ó–uâüõˆæëknEÜ�œz¯Ã§‰(Ø!bg\÷˜ñÊB7Ø¿âó»'¡–ŠïxWEÎ*ên¦¬€ýùÄ¾ïøøxâ8v#Ëø6ÛcCN#>jì»mkN+§„푽OÇó<:"»ã Up¨B*Pë�çsG)Åvï»Z J5R@|îØ# 6ÔZQ¤ñP¥M�`§$ª�`PÉ.¢ãð󵈀DŒÇã oo'4dpæÆgêŽâNFµV°»âTf0×q«trŒ%\!øF¨ÍQ¡ G…F ¸Ôœ‘ju' ‚S»ê¢ª}l×Zí> Ò]žV­ZµjÕªU«V�Z€U«V­ZµjÕªU«~‘JÝR–»ÁýíGñg¹þƒU>1ÆûV ‡Œ÷vÖ§:Ùþ¶wÔÜ¿6ؾ©<ç—µ¢èª¹3¹€&,�&µÞxc}jÊ«†ª†X¹g¬Äˆƒ°§¦8km‰ËfÓS¶íïHòöMÝOìÇxx ÈÓ0¡>ç^‡þøéºណ}ä?'Ì€Uì£I¯Lç> {œ>ûÐ3o7Ôš±W@Ün�AhXA)�¸˜í¼yˆ»S}³¬od€Ö� ³ß“T( €�”\U_Â@ö¶  Ìa?f;Þæ‹¨¸ ùPÿOÑ"ž‰\ÍP G (–-ZHØ\ T=ø@Pôðk$Άðæ9€jÆö•`~­Õ,ý›×¹wcÕ "k³BP‘Ù÷á–Ù SÙV�MP)FšÐŠD‚ŠE²ÓƒÁ™Pîð¡Þ';À@AÒ%¶�ÒpëÑbT?bÄD‹P9­�trÓy]¹NÒN°b¾´è ™Ý¸bpw  ÛùÑß··è€Y  z[‰.÷·uvÐÓg¢“^¯¹çþ¢ßQ¦¾ <Ä|qnq~m˜ "ìŠbêN ñtŒÐ¥ 4sEX¸Dœàm )÷µœ¦öùFçoRÄÇ–sØER–ŽöÚ}FÌ ƒb¤�¾ê,'!Pw<†(í^¥{�wæHkF3Ñët…hœ™*á– H'ÚôÉsÄ�n7ã«JÅÇ÷ï ˜-þÛ›Ls¯‹÷ùøxâ�?~DZ o³Ó»-"ÌÜùR Êq@T�SBÎ ooäíácM!'ð¾ý©Ðª(~ìcßm¿*Ó},¥Œœ)™*ÿAæ À´�Þ̩œ=ÌIdNöÜF#"¨( R!2 @=Œd�mÃûû;Dïïïx<Þðx<�·ÜA÷H†Œ×^|¬7%¿m;H–L)f`L±G,yDR‹”jj%0[ìBªµ6õ{bkƒYK©D«ˆ»œ¬¬ZµjÕªU«VÝÕ"¬ZµjÕªU«V­Zõ ÔãñÀöp¥³ƒåW[訟œUðCõÈ-ï—8¼°æŽ…QðAŸTè'0»ƒ«1e¾BC­ÊlÇœ æÓ [ Ç&ºžUÿ;�œÛ&[”`ýNä9²˜3¿-�MyìçÔTµ=éÀ?Ë:ÐÄfÜ᪆gH´˜p陸 £z­� œ±?ˆ2"-£;J­c›"õ¬— õñƒ³½8�²»)d‡‡ÜæS…/íƒóµ ÀÏ™pÏ> õ‰ÃÀùz¿øùÅû3[Þ‡òWA`ÀÁmb*E÷4•œlà´°h $gŸp³ýoªW’Óé+W›v)±A,¢BT¤��¹ PÈ%ÙåÕšÙTÊ ° –Ã*¤â� bEªn¯qDJ À²¦•Zœˆ€I�€³«CA)·a`çš•P]U[ õpâ‚@!ÈÄ@"”Ö›�PIj±Ú¥)oããÛ.@þ0·çÓ8–A*’ZŽ9wg*ÔUt›üæpÁ}–ê,¾§×íÐ×›ùL7¶[ëCO >Mw¨?_ãÞp+'ø×þõ~Øœ³é›«ˆ†u€ÔAõ�q¯"wm® m§k4›/„öÒX£1€ù~_Q‚¨GvÜÝ7)ž‚�Rÿ>ªñ1ÔÑ:ˆ tºÑvÂBtsAŒ¬AüÃÒF³‰F$;Щёðºôòÿ•Šà(ù8PK1õzpëiÑ>DZãØw|<Ÿ� ÂÌØ¶:ÝOìwN¨N°J ÌÛã _Þß±mê1DMÍÞ¶—jñ*µ:ø”Z\?ÚóÜ µ0ÞR1ƒhÃö6h0D@ŠÄÉ×»[P�Ú�y›ÿ P J�Š}æñxÇûû¨(¾|yÇÛÛrÎHÄÆ]«Ò—jn³Áà”F\Ü 6Öl�´�Ô'�Ü!nÈ$7%¢¨U_Nø¢(¨dš;ÿ¨eeÕªU«V­Zµêÿ�kV­ZµjÕªU«V­úê/õÏðþþÅóeSPþàñ%¨Îø ÎØßCý?^Ú6`ˆ/óÔ Êiâ«*Õ>òe£Û€ïM‰Ûßrh ûW�@¨oÃìm殊å“*µ½LgÚ|*Wjÿ ¨4Ô­žó¼/Õa1 À�HšzÆú7*uOÖ÷QÉÚ÷¥ üµ¶ xJe%š®‹}3#B‘ÐÁ9ß­òzÖZnÇW¾ÀÓ ,�ÆQA�ï'@éÜ–YØÿ„¥ª—ctëö›Ø…áâ HHS{¬Ÿhc�xœ‡�mÅ@×+$ìÿ¬&Èø'6Õ>æA2<Â+€T-" µË=¾]õèS@Êáø/~üfwî}�p‘Ô�ǨžMoJ•âýR U}[ü€­ 6î$H @rEt‚ˆŽS'«D HAÂ�Љ”!±XÀÏ¥Ú7R!(€@@wËsÖ vUsQq‚ãYp{(+ªÿ¬€283oÜýnÇÆhyU¼=1wÞ È?¡�w,Œë“Õü´(¶kÌÚ€4ĶßCäSt¨4¬ï‘Àä2䳓‰ótò›Ÿpò`d@��J~Xòsût?ãÜ_š¨—ÌyæAh™cGqˆÚ=ò΃¥‘„ÚØiùçˆ-?pbi:g·“ÙF`¾1ÈEm|‰xè§¢'’ â‚/ÒÒîsÑ �p%È!†Æ?‡OÛi,z$FpRèT†KTÝÚÄߎ}M¸õÌq•y•a©/RÁÂ� ýùüˆýמ=hº‡� %³ÐÏx<x› ½V”Ãþ|ì(¨uØß£; 2…ˆ¢Ô<Ÿ}‰ƒÌ 9elÕßðmôørb¢�w;ÏÛ91I÷¯QrJض¾¼¿CUñööŽ-?ÀÄÖ–£ºSÂ�Zj_iÐ)¥éÀœ6üž Éï èÏ DÝrší®ý|œ‹º;€?Ÿ(^ÄZœ„t^W­ZµjÕªU«V‹°jÕªU«V­ZµjÕ/Qó7ƒ÷÷/x<=˜nW?Úß›è;ZÒ0ÂÓÏ(8äêYô—®®Iµ—´Í¹» ‹âör˜SBbSr+[ê/Ûk³ívå` kr€÷Üóë¡Ô휹ÿ4¶µgLNÌã{¸ŠQDp ©€t¸¨ãïÄ eî eª(¤Kw#4ðÐŽiçcΑð0,�ÝÔßÛÔ¬}GƒºÔ^‚Ïî Ñúºí/F´qÀÄÎ%0åêEíé%ªf.<²å1Ô™"´«=ïÔ›­/Ïí½‚ðª'PåÓ¢SÄg`‚êû‹iÛѰãw ]k…4 Ôâž«Ž4ÅYØGÅûÆ!U€œPÀM})ƒ9ì~þRÛ¡W{ jËšWhQü¯ð©€(¤€š§>“BTlß-FÀ绊‚š‡¾8¥Åçµ¥!´s‘üi5ËgT- :@\Aä4ÌÁ„X*P°VT9ÙAr@µ¸c™’”€”³Â† ´ X2€œ)ÙœK™‘ò†¯oœø ÆÌôN ˆ9 /Ò¾&2Πïˆ èÅ6½‘8Df�è £S¢ÍüË1Ü>Ù÷Ã=Â@ãù©§YHûË|þg0X§ó9�âèÿµ†è�3�ú5þGÀtÝÉä‘ w¶úÁ±%žOüd ÆÙec'ðÌQ5ý¢hÆ0êÖè„s4A›'7ÌŽ ýtwu£«ŽJÏ gºíç°jzÄNscÐS C$ùéeœ6‚Z›6Qî7Ô6îŒÓ;Ca­4èÎF?¿|v—„''qngÍoŠ{vBaBJ yÛ�RBrË’”j�\jdIömÛöÛ¶�Svà½àHŒc?  ”*§{.Mù� PhGϯWpöýç ÛãÑŸ“ÚRk ± >Þªºû@…”æ$"Ö'hŽLŒ-ox<Þ  <oH){D‚àà'ÂÑc)g@ )ɸuºÛA$P¨HpRâàF2ú>1A3Ⱦ�œ!BJFZ…»éȺq cÀ •°jÕªU«V­Z5Õ"¬ZµjÕªU«V­Zõ Ô_ÿóŽÇÛ{� ÙÞ¾›,�‡]¾ýކåÿù°ÊŽ˜^Чð’}ÚŒÀ°ÿ·—êä*¶5F$SùÞêÖúñLۦƦáÀÜ£É~.Ö*Uq•;�RBku ³mE£ýÞW)qïQ€JE%�ª¹˜šPû6�ôÀ {°ù-Ó�B,€†¬f©ÀÀ‘ 0mÚ=ŠÛU'·…¯.C•æ#OÙÛ!ŠÀÁ�s«ÿ ˆ[RË£@SFk§â ÚGµàÔ Ì?�Ûú./˜âÈôÆígÆþïáÅþYbwm?ï  jÿTnà}jÇiÒÍ axT„Y8P6ã~">‚2Ò;Ó:Ññ¨,žýÁm?u÷ ´8ÀQëê¤@'tç‚Ô¸åˆwÛi ÀjùâPJhqÊÚAdÔÃÖ —ý‹ŒkÆî"`Jé…€UmÎ&BÒ¶.XÖ:èð¿,. QAÕ ±¶³"�@9ÄÈ)uêŠ@rBÚˆ3[BÊ ¼%¼¿ÙZ3ƯÛâ7H(ȶE‰ÐíÜ9(ÙGD€�e½ZKwˆ3Xï÷�ÜŒÏî6Ü'h?Û¥Sp6™ïi¹×“ƾgͱ£ÙÆ÷¸o“_Q°¡÷ÕÐ<ÎÕ„ÿéGõg€»'A�‹J\§uŠ–�¾¡1 “kˆÁ$Ð>~(Ä;ŒèíÖú#CŸ4.×qtRÿéïîІ)ÿ:û¤»ßuŠ2Û‹Ù ®…‘ðâ:vÌŠ cS'¯ŸË¨Rz½û{¾×L ë‘%)áíí݈�w´ '朑rÆ&²ï· [Îþ»#'rr¢€»�i ò@ÎÈ)Ùó�»§ˆ(¸Ï&ÌHs#`…hu«{WíËÞíìsÎxloÐ7Wà§ É‚­&§`}OÓ}TU!ÅöG¡oÚu6âdFΛ÷™=Kª*J)ýZ•rØsš™¶·ì¤E#BªV”Ã×1i¤íÑž+í¾CÓ33¹¹= §àj®=ŸÜ®:Yµ¯ î~’Ö¿V­ZµjÕªU«Îµ«V­ZµjÕªU«Výõåý�·-Øõ�":)·Ôù®úGw¸šÓSÌ�'îàG{©UUCùÏèÞ€ðF H)¹"—pë/©U:DÀ“*/Ä@\->§ ÷³Ÿ‹v³­-#Çx|ª)ÐD“Ù¡÷|Y Θ‚l^ÒPö¾à¬¯@è;î9ß-k:Ú*GÕ'5¥nSHº» T;(è]³ý%˜›‚Vꤹ8L ž;%`‚îkA)H4/ŠÝVGgÒ¶›ü‘Å}Fx� b»UïÆèÏÔÏ8 Ð|þݲZm<ø¥MN�`¥>o¸ƒnBn…1õ~“ur+Nv,LŽß­ÀÅ”ý¬ÝÅ?q 'ÜÀïs)þã2®IË(?…ý4[»†õ2S‚è>ܺ@ eSŠƒ¡r” §êYÙèÖÙq 1ˆV ('ÔÀ׆Ø2= ¢¨)SÉÎ1g@K#F�¿¹-(4' P™A9#=3¶a{Û@9!goŸY‹c²]8j@1é´¶´Ë/úÏ´Û¿pŠÖÄ–¸A'…uðÇú‰›8•Ùbý<Š{¶»“;ÄÉV6ʆ­v[ggý½Ÿø)úÀÎ_çyy;×þ\uý¿;“ÐO쇦 ïsÚÏ¿ïœÇ}aº»ÑX[:˜Þ\BÔ¢[„¨Ç¢t�" T0o‹ÇÉi!®™¸é;úlÝŠ÷„H 1<Íò¿ÝS‚5ˉÚÑOXu¸�P_XgœvòÐÙª]§G7Wó²òF»˜ØŽyæÝŽ�x¸Üg{OÏ �/ïïï BwŠÕÀÿíñÀã8úùo›©ì·mCJ)%(+¸´¨¡„” Oî2pÙ7¹¹Æ‰üÖæµ=ˆR© (Õâ `‡‚ˆñÜ6ìïï¦ô÷1‘9á ýÄ}�¹%šÛ ÁK)@ØIŠÚ#’Ä T!¡vÂXÎLÖ øïj?védÕ×3?Æ$&$F'D2SŒµf×£àÎÑæ›ZôMmsu¬ZµjÕªU«VMµ«V­ZµjÕªU«Vý"¥µÂ@t JÇ®Oœ¶¥`ÕQ]ûÿšâp¤¾Ïqí%¬Ôóþ)äZ;cjvÿ“6­¿ô®R]ùV»²Ü@ÿYº¥Á2?j E ì 7}Ø‹n"�rŒ›5~³©Ñ`÷¯Ó±&•#1´›|e]ÿ¯d(Ç¡`ñ<án% ;ßê¹ÄUÆua:YéŸÉ *Ìp™†mt‡{´µe8ЂÍWpøsÌ:«nOD š^àPIõøé r¥­Ž(àç`F�Gõ©šDU§6õ¾‘8Þ"À¯KSü&@ *)¸�j�Œc`7»ò–¸Ê¼Ÿ*AÆÜ”à<¶—6z4ôME°ïju³ÆvTÛœ=ªBÆ>Zs«gRƒº„3_œ D¹TÔÖŠZÀ¬�JNr©~Lô‘QBÊ f‘àѤ�ÀLìû© º52I#ºÄªf�Á€�„S 9¶´aË Ê4"Qˆfkü0ñ†.ËX_÷r+Ú<ëíê«Åú÷9pR¦ÓX£ƒ´�ç�5i6ɤbžÇ½oc:ÚZiŽ+: l@™’NÄ‘»ù¥gïúÓ*2¯œ³[ÂÔ¯Ú€ìÏæn­éõ:Dí^¤—4ðÑæ4O1€„F„Æ~E'"°�Õîfâ{’¾¸ 7€¦†ndâ¸4j¸öèz]§„©�§ë£®ÂÆÉá¬Ã]Û Rha·„…žáýx,—+6®—SÏ™ç¥$µÐ§x£©ñ¾mâ”ÿò—¿ ÖfÝ?ŠMÉ¿é_Þmu=öÝÀèœðöxÐ�æ9ÆK”s@Èy›ÈR+Š_©G)¨¥@¤¢ø}¿ÅæäÌ="ˆÈTúÌ >ì0`½ÑŽü|â¹ïØkÁ)Hl¯mÝå~\¯ÉàÇÝ R�ù:#�v�Séà}£ýGÚó™Ç&ˆö~ËiCÎæÎT�°@ ¨U«G#Ñ'kɘ“ÌcÔ¥„‰z&V\?ÏÓ³æy ¡s1V­ZµjÕªU«b-ÀªU«V­ZµjÕªU¿@ûêA¨-3ÖÁ¤$ÓY]w÷R¶e ‡Dß °À‘ö±ð—¾×®Ô¦KŽt¦ ­H”ZPJqÅ›‚9™r�¸+ÈÈÕ�bî²CÔåvæÕ‚ÚQjq¥vrµ1Ovß"ö2Xª;4 ˆÑ­jáíìݰ( BÒU¼"öò¼Š@´šêVe(û(¥Ú íRzµÿþ9'03H(8)�íãvüÊ"P櫵x¿žöò^d\ÃŽ/F`Qãïb~ø‹æþ¡š�¬�»òïµ u<ö "Ozû¹)«ŸâÕ6Ý¢š&PÏ·o3¡�wàÀ6” `ˆ(I·R·ÜkS; "‚[×T‡¤Ž«íOlo6⋳ ” äÊýnñÜ ß§> À (TªgA”)â¢Y–Oiè$ž6P�|’åGØùúd"R¨ ´ª«4)A=Ú\1*1� 8Ld ~&që}²ñÌÙ\„¡Rx5ÇR1Â�:b1˜”%%Pb¤Là _/Š©V;e :)ô;9*¨ÿ»ËF'ØÌkiGÔ”×ОU­�ôÒ ã�ÒÜD �5¡}�³"†˜=²¢+†ÂœSjœUÁi }GNO1bתË8‡Ë䙿šžp×àbÝšW¿Î³<ó<·§ûMÄÄ['it3à'Í€þU¯—£ `;Ì¥F¸ê®,.¡¿û½—ƽPþ¤ü8r¢( ô]çLt£º÷ÝǹöÓ‹kýœþBÓ×óÞ ð´.Ç1G/V÷³ÓN›#w~!!Ñôtn·cðþ·aÖ!RÎøË_ýöçÓÕúÙb‚Ü%(àžˆPw5ñX€”»M-F¦c2›üæž°m䔌`àjx³ï¥àØ”rà8ÔRúïÚ1Sr—� Ô¢È9áÙˆ'J)(µâØwìÏÇsÇñVAÙØjkÛò�è¾”ªvžRÌiE´˜{‘«úŸÏ¥©NF–úaqQTÕNúH)aÛ¬�TG=ü¹Åž‡Ž@zë¤K©Óe×)‚‚yU_Ëöãs.0\§ì¹fDø�¸+’´ûæªU«V­ZµjÕªV‹°jÕªU«V­ZµjÕ/Pß¾ÿ&‚T¡þâô”ÛluV“ TGtWíÑlàÛ,…EäŠßþóÓ ZuËø¦Ê£  mx�¨€ðW—•rà(ÔíÇ@˜‘Ôþͺc5Ž3Ðh”ïÚìú‰ºz\¤WŒdÐû©Bí¼tô‰¶ 2|ÓB¹¡"¨NPq…\o¯ƒ¢öYˆ)³eXé–Rú¶"ž-ì/³ýÒLL# Gˆ§¢ t«ÛÅ àhF.CSÖ}»¶Q¼|ý=æV5±ŸÿøÌd7>Qö½¨^ì¼ÏgpýÙÕÖúÐ>{ËÐ×ÀEˆ_3�+”ÚO †– i9‹áüݶ¿´Į́cõÒÁùž%NÕ6˜¯½Ç Œîm´pxCšÒ^çÐ좪å>ƒ Tª+ƒ¹ÿn ™þ½ƒÿܬd‚BÔÈZ}\‹Ø¼lÎÕ˜Èb;e´ ¤jÑjÄ"ˆ2 H¢ÃÁçv~âÛHwù s¬ÕAoAbç-(¡ÔŠý£ ¦�E yÑ-£û$BsÄ0åJ÷í<þ¢£®�\s°ÈP3~n€•D9l�Zb„ÆÛÏî]eM'@[Õ3ác”ÊÔ@SæC/÷ š³<.ß6BÑahÌ� Maodýix|DŒ4K~ê± ¸™ÞgCý×®~ÎL'Ž1~ÚØ­í¼Ã-–¢d�8¬|óUý¨—>{º¬SÃ`–Ó÷ô_ G@@aÇñ)�WN7ñá^q£ÌG$¼Z_¯Rþ1f/)a,éíâ¯×ÁŠxW¹[íÛñÞ�î¸s�Rî.:fy¯—9'µ¢#î‰Çž )e<›E¸#€=_ðJ1€rì8ŽÇѬôÁ'eBN 9ɉW¢ÒÝ#j­(õÀ¾?±ï;ŽcÎ ìdµD®ú§¬ûº¤2=ƒ¥`ߟ8Ž"î>À [Îæ~ÀvÓ«u456ˆíXÍQÁâk*ŠT¨s•!ôç2#Ðér&4õgRŸsÝê?<ËFç&`bÜ‚PÜ/aÕªU«V­ZµjÕ¨EXµjÕªU«V­Zµê¨��0³Ù´Šö ë˜#³‚[ue,“ýõKRu[ó‘‡ÞöÐE¯a[4këá¨aÖ(ª:x^ ŽZÜÁ@,Ï^f” 8-O èRÏF×j¶þ,(C™‘3C‰h£áT·Ãÿ8œFüQ¾]Gfs.íEº¶ú2>F4åw7;Ýñ"܀ͦNfÃsŒpRjžs·ÉLò‡î ³ÄÓN9)ôCÇj ¨ÎäŽéïÑÖYõÔ/¨¾SýGEìt=ÎàD:ùGöÆñþyEåo¢Œs†us0l!�^jAeBjq Ô>/ ÚZ|=º+‡TH‚)ÿ])Îuš7 „ Ü\š‚Ñ”ÍÙa$ ØXèî-›¼89u‹fÔÙ�Û÷Í@W¦ÂB§„NHèk‚�AÔHíª @Ôý¥‘XQ A…§ˆ¦«vYL@ʨ�ˆÓæ:ûük�DêÔ õ>€]ztgjŠÑàyèݽ�ää¡þ;`€þ]­ncCƒ|ùb‡ßÈ@§qNͤ�� MT­(nók Ü�´5)Óï@Ùá(òj*Œ–bÄÆt.I�;Xî"Ô}Üõ'î�Îý×Ö%EÈ´ÿ$jä%p[^»ùÎëö5{ýó$ÞO÷m„6 2Ù8÷{`�qÀ�qèS î�æÖè{ ñˆ†7ûÑû Û¯á#+>^kûvDßh¶N·ˆé>öód­@ˆ1Ï3× o®{#蕚]�>TøÌfû?¶ÿ¾ú#ì•RPs!b°«à·í�-g¤”º3Ðqìx>wìûÓ­ü+ŽÃ€tsþ!HÖáäñæ$€œ xóukô•ˆbßw<÷'Žr`«pNÖnÝœ`(àdî9ùù�ôë(nùøyÇŽ}ßQJé}‘·ŒÇã�÷/_�˜!ª(G²vF>k–ÿ"$QS–7Ô·‚·²AjŠÝs¤;?ÉeœÌ ÿ<^îüæ -®ÛñAø¿jÕªU«V­ZuS‹°jÕªU«V­ZµjÕ/Pû¾›kƒØõÎ!½©újPU,w5Hó¾0«ßüó€f\�•ŸJgw€¨)ÚLÕVPk�T�›ìœ‚Ú”â·&J&êÙCüì LˆIž-  d¤„Ù2{ˆ,»r’²`‡" p4…¾ f[.ê`‚å}è{ÍÖÏŠ[[û³öaœ”l¾ñX©Í5¡z^õh?{D€°œòȃ²<ØõkÌ´>§?·8ÜÙ%`"™Lê½ÏÆAD_ê§‹^âE뽯9€ß<Ð%ÿÊ€V±]'1°Ë÷ pØØTòüPq!üÏ;Y€ã\ {¤>_CG5ßç³ @õöø¯²û@W�²ÛPòmÅ ]-~¾âíBŠÙþ—Ö'�Ü€¡µ(HQím—áOïà1�`ªT2‰.;O‰€ãìgFœÐ>q‹$€*PÍU"PÏÜn3Œ?MŽàWà.¹í]aNmöb²›�¬8òâÿ‡]uȆwðNçïi�£h§ÐgðŸ®î]»}ƒ�Æ(½™"Jlñ# ?ˆFÀ'Pxìϱí þžÁ||¾¨èíE×ýÄh„Ÿ_P¨[Ô“6_ ë]î…Ö]:]nªþF฻æEP;»�í#mcœ9õköòTÂMU‚ÃK´Wn“ÍO®Î/,üç�ù±…#Á¯\[è´út|ŒTEñtÅüq]á~dí  j-ÃÉçôg€æ¦–ÏÙ¸;9gäm(æñhß|ÿþÝíõµ J©æ&P+T®âêzUï'°å }{C# ŠZü€ÔŠýcÇþ<ðþ&ØèÊ„œ©æNH~žâ®/Õí÷9¡¥;/•R Õˆ^ÌŒ7ÿûí7‹PÅóãÙmü[\Ó±ïHlŸÙ,SÉÝŽ-#—¢ˆšCÒ¸Zãù€g'"h_98 ˜Ã‚¯Uûù\G…ç)¸#ƒbÕªU«V­ZµjÕ¨EXµjÕªU«V­Zµê¨ýØ‘!üw(#§êª¾‘y.âjvnÖ4åáÒ¤^Ê-bž•Y¨ŠÇ‹€îlû Sÿ‹˜5¯+÷mó™JÐ"ÆÁàA6pÒ"ÐíçIµ«ñÕ3Â(d°©šX¸+C<‘ƒ]M¹©“RVÕ”ŸÍò^tά%&Ï–´Ú�s—ÍR]ƒ=žwë>‚Y«H áLŠZ hWË÷7è†!‡ðI­OÍ„þíi¢?]g zsÀw¼MBg=ÇqOðÖ°âþó5Å‘rBÞ˜éPÍv•³ òÈùŸÒª¦‚w’@“(+ÄAÜùC=?¾X›½x² gÇEñæ9èÎjìÙ¶ÃF8ƒÿfËá©¿)¨œ•e8 H5"N# p5 ~)¶ŸÚâ@dômkKsWÞÓ™áêY8Y š{Qp9hq$ õ]ûœ© mqRAT. ­ =€zØzR­íújÀÑý_»{Ç9Rþ¼—éRé'[õN® ±D+�VH(Ñ4—¦]\ÿK†)|h9IñÇ'fÈyšhwy]§óipk¹îƒÎQŒÜ÷»XŽŸh†ÞlÖÀñ§««Ãõ3ütÝð+ Euß½¬-Ô®½:Í�æ±v¹!)a˜‡„h=“6N$š�Mæí‘�&Bƒv"ÓˆniÛ‡[Ÿêm"À=Í#€ú§ Cz3ú&·€ÓüÁÆÑ«cµ•¤|ûãìû©Õ\=˜q”Íp° ÝÀýsL�ªÐü$�í±AU‘PÍÔ Ž¦þß{¬€º3ISá—Z¡B8ò�G-}]L_¿ ¥„7²±VªÅ$Õz`?v|(þ²ZÌ.?ì3‚ûñExØYp@Ü~R²#+8¨û€wPaˆyGîvûÃgÕéÈÞ6àÅsgY ¼ 9õsV=qè–ë CÜšvô•½ÄŽ€ºÐÈ`Ñnißlý[&®�ŒœRÏ¥µÐè M/¦£ÊŸNhfË?—Š[îÎ -Ýñ@QH¼Å�GDœX�DèH¢ÏG• ªîrn‚YNƒÝ½@@¨vÍÈæ˜H�VE%�츼}Ì3�S¢$¨9beá×ÔÀË@~Ò°ë¤É§Þ'DFPQ‹=.$ذ÷c´Lû’êXáD›ZX{,G;uœ?NÆìü»2ŸNÛ(:¨®¿Ï”ï$ÌÙó­á~ ŠóÐÈðådù¢÷\í×’.S¿�ß³³À`è+;ÂD”_=ƃô>ÌÞ¯» ý}p†d¢Wœ½!hLàzK�öÑH4îuä–Î+é÷(‹Ùðm\­Ý®¥¨ G‚0?¦»ø¹ï'WäHfx½ÅÝz}cóÿÙÇoªVÁ÷oß ´VÅcÛLñîŠôF@,åÀóùÄ~nÏï-` ÏZfã_ÊqûûmË(o¥V¤Z@B8JÁ¾ïØ÷Ç3õXòµ[DP�‚r [ðo�Œ/ò†´mHÙl÷ËvàÉìê{ÁÇǾÿÀ_þjðÌ�œñ µT<ëå(Ø�Ý Öf�žÝâó3#çÍb¶GoC-[Þúç¤ U¤RÀû"Â#£ lÍa¿w4¢�’ͽD æÀu7¥ý¨(ÇîD3 ¥Œ·7u'é1 ýyÔ×¼v.ªíYîšP�@±«V­ZµjÕªU±`ÕªU«V­ZµjÕª_ [fl³·Uw*lÊò”¦<Õó§Ue|.*ô:Hvµå…ŽœVÂ=l` }5�žÀ^–÷Öp8 ê"SÛƒ fý¯Ã>¶µ+‚y‘ÔÀ®Þï9Ö'…xÛ” cuÕýl•À¶î¾ÀH)!¥<©ÕELe†TõàÉœú1¸ÓÑ0'“@À4g+´ç–ƒHîÔ’qlœµUÏùÑè/Ø»ªô"Ámà÷ë¬7ñ1üò»3>ùSuž#?ù¬¸Õ»ñÚTçÌC ß2ßU Dþï;å`í_Ý¡Á‘v#…ðØ¯ &Y²º8¼Í­F¤0ðÄÐá2>'Shw(¹*ÿÕû‚æw+wîàWÝ‹ µ6²ºª»@ª )€vŒ@þ°ïÍ1€àvü¨ ®öY?BÔS (¹Ô®F†*µÇ ô�Ñ=B(ØÍe€°*€h5‹mŽÕÜ>��EÈÃ_äf þÌøƒÜAá³¹;E…µÔœX´!a-ûÄmý¡»bÌY3'úÔ'çù}¿þœmÞçÙ¯—{Ëøà5æçv8�¡»�¼Ä¢g·—yµÐ—î =‡ÎÇĽþeoH/uôL– aá4ÎO�Jt³FvNÝÚèßÅtÞ«›ÈùJÇ ÷?3›~â#ªŸÏQ©ÏÝ”ø àn x›?ªŠã8l»ç³ÊÌÜïáí¹AÄÖ—£àZñÌ �·¶gS¨+>>¾ãûÇ7<ŸO”ã�óÙ-ì‰�tQŽ‚]*j±($NŒ··wT¤Äà”5—'k·¹|á�·ßñWßÿ‚ã·ßð…�8�²k)ø¨îV°ãùñ�ã8º²ž˜Àj@ЫŸo'ôç¥H.›Ÿ j©(\À…�(¡HÌýÛÆ¶h)‡ î×£]sY0w#l䜡ZÁÄ`ÎNH@'`4RC{v¢0 EÄÜJE-ÇúǪU«V­ZµjU¨EXµjÕªU«V­Zµê¨íñÀ¶ml½â'ˆeÕ,ôEF6wü8ê¨\�A©”œÁ¦³J“˜»urÎÙTǘx²ŽÇé»nSÜŽ×^Xw" x�>Û¬ø)€ ö’['Yfhw$TPû=¼g3OÞųÝ7Eg„YéÛ÷©C7y˜@ÿ¸ÿö;fCÉØÞ'UÄ ýè"²¿ŒŒvì³âwÞ¨;Ô›Å=]@ûFX㣠ý!ŽÚIúOœÕ;IHà)îÂv�œ:¡B‘ÂÌ2-A±EJ EµˆS³³C×zrPãLýM¦l‡;l˜íé}c‰JÿxN­­%(ÿ TŽ ÐOæ@9øŒ“;`8 ¨[ó ©Z[ýŠ@wÛV‹wZÛ‡» ôެF2jÊr°ŸN`¥T'ìx,€´tuõ˜¡¸´^ˆ‘ ´Ø\@µ€jD Ö¦pE«y‡bìDS¶G@Û­ü¯+Îívµ�Ðù/nÛ>�a¢l‚võª‚Xz›è¼ãs~|pèëE$>�F_œp%Œõ¢«à£’?¬�,Õ}�6•"€Ï/fà´âÿ$X¬Qd?­5mosr=4:à;,D‡’8K;Ù¡áóõŽ÷ÄÞã:ß[§oÂ}"bõÃ�åðÿÔ[=>‘+£áë܈ûØ�ÃiQî¡·Á ×§‰ËOéfýŽîA�ø¢¯nH·ç>“@~€ùŸ–tÅóùD-Åî›Ûâ~P\{À¾ïnÅOÈÙÀÿ”æ×£µ ŽÃÖæïÈ9!±¹ü(ß?>ðýûw<�LðÈ9g¼½½ùþT€c·µï¨\ {z¢|9|îgl� ðØ73J­x>Ÿ8JÁã±á÷?þ õ—¿þbDÎÇö1a÷þÞ÷OìûŽÃtÐÝîárÓÏTkí×Î"JÛ{_ˆ˜µqç¶§º*ÅÝ¥\¤*T“ß�¨÷E¿ÿ«¢ÖÇqàØ?Ìý ›«Ž¹l¨%�U�,Px¨R6¥:³Ÿw´�¡¡ýºƒÉ”ØIBZÑ�õÞ1¼œ Ù"*lzãÐL¶ÿ:·YGÛÕ�£ �2f"gðø,ÁtõæÕ1^Õ#:ñ@`$ƒÚÝ0òƒ˜ä^ªGxdÁìÆ!c_âýá@(· wr¢…_0uG†ÔA"s'0 ÖNžH¤Ìàdl%U…-Ôa!½gÚ4@�Ñ>gU÷çu±í6g»]»¶¤€øºÈ³[Gs€NáבTÕsˆÖ·nï�?ŠÙÍÀÕCMvŽ 8­kãÆcK.PYC_ßÏÌùôèÕBusí@¤Wëµâ'À m 3ù�F¿Ü\ò™ 2öÙÝÂQtþ,Ýg¬ðtïÒ“úZdºu÷î™h7Hýùà2ô´�ÍY•ÿ"æAçûÓÏ\‰ÏI#‚<†5�SBJÏÃÁ~%Zß›KÏ™0x}N0‚¡‘Žý@JOs��bî˜ffpJÈ9ãñx€9ƒˆq<lyCòçA-¥Thm€vÆ–Ì!)%Ík1üÛ·oøã�?ðíÛøx~˜+@5ǘZ öçŽý¹÷Xæd±D�À‘h© |7þÇó)'ä’ êçt”Nè÷ó*8`jû¾oŸµŠß~Ü-‡D©ƒþwƒòlão}3ÿöÇ¿·ˆ™½ÃáÖlÄ ó"¬ZµjÕªU«VÅZ€U«V­ZµjÕªU«~�Ú$Oº®µæhõß4|Ú­ší3dgr+ó³ª00Ñ­ó'"ººTÀ ì„nðý…sÃh¨åœb&¨ºšŸ©bgU�ÇÖ®ê"ÀrÙ]u6ŽeÀM{ÉO‘Míù…ÁzI†vȘÕû¾¯+*;ÿש@„-§¦üD°A¾„Ü Aw˜�}§šŒú× ÚIé4�ã šýó r6à§ýήÒWël€Àt¯“Ž€ÁøÏdþÉ ü1þßÁ©K|ùOUP¿«Œ,c®Pa³�<ªPeP½#¨ÿ óŠV0 HkϳWg¤ôiÀ»ePœT0Ž!˜�ô—ÿ/@ º][ÆäÇÞñÉ8Gô�¶Ø�˜ûÑÇ�Ž–ñ1‹ íÍû.@mçàÑâý½Üu¾ÖÖlîNèëM sÄ׋”À[BÞróˆÙO9uÚ˜ŸÆâ ”"š­÷Cl‡ö‹w’'OÎ*'5»ldšb  ÄcþöX�¶–ß þ›8�¾û j€öÑÉ dÌÑæô1M“CÁˆf@�5C"Œ£6ÞÂ:k×Ãú_^ÎÉÙÅfêSÕ§®=ºD1·ã2ÿõÇQ$úr›ó½áG4®“î½í~˜iq˜ÁýË‘õ´ Ò "Ói;}ͨè1:È>çq1�ÿxo£é ÃH$'ý¤møñ>�ßÍ}ïgÝL„ÇÛR­È9c˦ÆO�ДñE4+ÊûsŽ2S|^i¿Qˆ¯¹­mÌN6 qrR¥ý,oRÚÀ)[4Uˆ ¤Ž\{õ}ä´á±=�·RJ(¥à¹ïøý÷oøûø{üÕïÿ ïoï€ÄŒïß¿ãÛ·oøøøŽýùD)) e‹‘©ø—RPK1Ë}ß÷ã㉹Ç<÷'ŽÃ‰ u(ê±»N[gx\oí1 fÑÏcMPس±xl»ÍcT*8%lÛÖ :EJ´h)íãRu¬�ɘò&ë «V­ZµjÕªU¡`ÕªU«V­ZµjÕª_ ±Kæö—©ˆªK𑼍z3;î m/X‰Ô\yàrŒiŸ€½èænßÝ>kÒóGôcBIN�eŸÑnçÚ ©Ý–¥Âkk¿z?tiñÉêš(¨.õê”@׆6 ¤çÌÝE“ùd3­z±Õ¥¯j°·¾« Ø{Mrè€(~FÒ€éO|ŽáöÅHÔÀûÔ �T"�¦ Ü÷¶W2{L‚¸Š�ÑõU ú%´• É,‹!ê IõvTÕÒák‹°¨'tM‚]¿@ÅmüµÚø$êÔQôÆÎ`Ç;N¿Üv[Çþ‰ƒ�zŒÄð�…1ˆ#B@,3•i‹Œ°è‘™h1=Ú|í& ì 7 ¶ÿ6 I[®x{30NE‘SS„ÒiÐ`úŠa ’Çt2Iô¹Nnq� _Nóº!^=b@ÕIAâÝhŽ+Ö$¢0±1BõFm�QáºÜΆ¦9X¬¤~®c-’“b}b»Fœ‰]BňsñŸu‡ÜÞ;~è°Ð¡A2ÐóyÆÅõt(š×ÄAÌh ÿ»õâ¬j§¸Šž6ê{õ1ÓÀñF˜RÑiÍí®:×0†pÞa"zQ臈Ûó¸?Ýt¬Íðq¨8GD$£ÀÏ#ð`úXŒ÷=SÀn€üîÄ1Ù�‡¦þx<Ü�£³g 3Þ(Ll„É”¦g¦Ð{³eÑUîQùß@ïT �sFÊ™3Ø£aRVäbë5ƒ(A¨UûÜoäSå'T2â—9X¶½Ö b#4½½½ãËû;o卑BU±ïøöÇø‡¿ÿ{¼=Þ *H9áããß¿›õ NíÜÌÇŽçó‰ýùÄQ#_ ûó‰ýñ@Jy³ó>öµVo›¹œoå#^*<¿µx&"05‚'{4Csȱc03oyÛ Þîœòöf128%HLVÔ-‹ˆØL—€ŽU«V­ZµjÕªU‹°jÕªU«V­ZµjÕ/QªÍFú«Ç­ºR*FtEeš“„›ÝѬh ˆÏd¡k/½Äwm@Gu@:¬·£½q·éu¥—6EvØ“60M¤µ+ÎæˆƒÓá'Eûg/‡Hcݬýx±KÚ íIJìµo€rh£+A#-Ü_Ç¡ÀU�t¹ ¨?ŸMÀ[ú;t½ÓÞë”käi Ñ$öM1©wãHÿ„±3ý¤ûÏííe½ý �‚ÕÁ”®f‡8@® T�$ unM³ê€ÓÕ2[š}~ËÿVhéTÝ–¿�ÿâ–÷QÝ?€� ü³Û7µ>”Я ‚ؾ)¹‹€�oSu ½öŽîã¯:)A«�Œ18®Åë¶_°zjÄ$ qaD?Çù‰uŸˆñöþÞAðœÍ‚¿Š)íãóÐcÛÌf?¨Üéd“oS”±möÊ4§ ïoïx{{GÞ6SžïHÌ;µX"%H5¥¿Võgœ„”28 ˜Ø‰´K$2‚ÀÛã�÷÷/øíëWh©8ª)öŸûüþ oooíÉDZã8öé8XÿK5åÿŸûî. );~5Âp@–ûR; aôs|䟔2˜ÙcÚzÖ]´šcâ�Û–ÝåI§gA‹w2•1ƒÌÇÈy�èFà{Àî¾°jÕªU«V­ZµjÔ"¬ZµjÕªU«V­Zõ T)Ų–Oøsûª“j˜NÎÁÀ�U¤¸±iêÓ +}7Ä'3�OM ;q쮩ƒ5rÏ®6åÖ°ÆÈ3GC(ØrlEšêÔ5÷ì/�A@¢—M¹¯plœDê:«Nix¬î)38€[D'…h³�ö¢}"H×À‰5’CJ¶ž5ð¿:•�®–R¶=¦ãitÏ€Ø3£¨9%ˆB«ï ƒlã>>Þ–bêω«V­ZµjÕªU«¬`ÕªU«V­ZµjÕª_ j­`n ÄP“Ò<üà¦ZŽ|ÿ;Í@pRIê ( ðß^´Õ*µcĵeÊn¶ÃöåÚΡ¼—~RìÔî¢CÆJàW‡E™)Í1í‘:IxÏÆÆÝvò Õ�·û”.vÔ­Ì‘áȇO•��€p&úµŠ<‡°¿Öžf�ÝrÀøO]Ý;òy)8nÐ_üå»L¨ßL°¸8èÝx›­'é'ºëÂ:åb“F €+ êñI‘(Hás‚;Èàc !� ÝUÀ Â�‘ÔAZ¨€R³Ï'Sós¸Î½y<ˆ4gu»à˜�8i¾ó/áçOÐæ#S7èñÂfu@ÃÞ|´ÏI>DË@]U0E…›ÑAw,¡1®Î6÷H¦F÷''$ wfíÊdIääÿ'Çp] 10OCàg€¡Ó‰Oƒs¶noi_#ˆ¦| N,×ñ®Ý&Þ†‹‚X;ج7„¬±t5½?M€y$láF Ž® o§£žçNÓšxNOiç¢Ðyù k�ÆÎêä©;fÐ+Ý}´£§O¶Ôi‰<5hìO¤„ór@aI‹ÌŠvûS_Ž»\SüÏÃzÆúZѾ¹aßœÓL*|•àFÓ¯ïÍîô4Vôf1&¼òéºþŽüu}¹V¿ÜY8ÅûTüz7ÆUéâÏ­ð“›Ì>ÁÌØ‰ƒÒL|d·�g�¹ÞHêGsHxÿò¿}ý _¿þ†Çã ÂqìHœ�9áyœÒ°Æ‡Ùâ§”ñØ2ÊãÍ»EÝMHq”‚rSΓ9|ýúÕž÷R¾?¡ªx8`^jÅóù�TF¼ÁcÛ°åìÊþääÁÁ‡?7º¿ª[úW'D·bU¾¸!|Ó áÙ ;xD‚¨@µÚ-—‹CÈÈÛ†-žª V±þ(Õ#dZ;›“Ãxƪ Â�d�-Û>„—ÀªU«V­ZµjU¬EXµjÕªU«V­Zµê({ùùƒ—›4{U¿²CmŠOŽöù{t^‚z°åéöí»ýô\W¼G§(�"tœ;«ËÙ �fM jfÚþš0d¡vÇòŽ/JQ:�QÁª“M¿^�ò­ÏîüÀ†UnцøúR=º.ÌúËÓÅ\�O†@³6'Ò)ºçº‡ŒéÉnNÂÐ`ï®'øRãñOÐÚ VÃU�z0¬ÿ…¾èNþbTv€Æ.*{¼ƒúdÄ b¥ä0˜¼?ञ7oÀ9¥6ê! öwjà?(O¡¡m;%L9 ü‡Bµøç+PIa2¥=³ÙþOÄŸ:HÁGW³ý�ý"0&Dp)"›mî`/wÀ ÈÈó$dI±x�~,oñ ú´ŸGKŒˆt*^úî›RTÜ»åÒÓL'@›&7”q-šò>v%]V‹°®œ”ö uE<ÍGkùØPÈ Ü¶yæ¿SÓ³6ðŸÂiëÕÌc^_£cÉÌvBwÀ¹­Ô»GCßœÇç­Í;Kû¾f ¢‡Þâš/1Z�¦H˜¸ˆ4S Ò{*Àˆ: q0ÑDïÇ‘2Ñïa]švŽA€ðÆôä•Ð?”SÅ-œý‰¬½�-3Ô�Ó½áºà)Ѽë•!ÐéqôI´‚Õ¿ê‹Õó'A¯NŒz¿Ñ‰´¦çkÚœþÔºo„µxï¿Û&Zͧ”�· 95 y�„q µ"ç ï�7|ùò¿ýöÞï`"çÑ\‰>PUl_n�¯ŒnýŸrÆöȽ�‰Tå¨F$H )g¤ÌøòåDÀÛûŽý@)`Ûö™RFlÛf z6g¨Å€ÿ*‚ãØ‘sêýÞ,þÛ³sÂÿ—½Û²ǵDÁ PZf‘u^zT÷ÿb�½3Ül‰ú JZæ™»ºËÏ&bx¸]–$Š")¹æ­lÖníþ”Ÿ»nÆ]EÓ¾ìÞ ¸É�Ûø÷X2RÄæÄîn"‹MhÕœ6Zk¨GEkÕ‰c¢Ùó‹@"² 6È^Àù9uÕªU«V­ZµjÕ"¬ZµjÕªU«V­Zõ;Tm  ªz1£>+gkUû¡fI©ƒ×aç?¬éÕ•a2ƒN¯½ƒqA×ãó ÈèÀVBKB<+"#.@#3ܳeýe4ÙË^ |2»¨ƒ¬]Yëç¢"]Í>úíd=+9k:»¨;šÛ÷L³R6¬¸s7LQ§l$�¤ÈLÍÇO»�Iè ×¥½@Ïæ=ãö鯈‡Þ®2Ý€@yW„¾¢f�)g>ãœàÂßeÐõ$1Æû+ ©PŸ7k±ÄŒVë¤Z7ÿ:ÎOÔëÑBS&7£ [ïø¯j?*v�L!\Nçä@V³a¥ïÇ’°é‡Ç l@VÚC ä'Wö3A¥aÖ“M?G(<|ÌÈ0P102–r“;ω Ðá‘#îÅ5ðÝÚ_ýtÛØŸDd�ÎmÐÈ]°þhG5e¨4Ô&I=¬÷#%ÏßþÑu>ub6é ;þ_M÷•Ùºù.A=摘z•N]ß5Ôô…ª_eV†O¤‡“n»ßŒ0|üOÓ‰h:NvP9#²SÊøOÙ³HÿnFŸÜhz<Æ%ƒr’ˉùó öõFôÅ­lÚ:ùæPXýcZËè´m^_Aórx9ÙË5}*ˆ5"NnÖ´±^w³Œ+g&µíÚ+šî]é:½Xã£Ï¯†ô²çÏ1'–Ü4Ï._£DÅb’è>ÖH\A®"™ ý¶m 2"Àî‘[ë; NÍ-Æ@ë û¶ãñx 80¾mOSý_–‹±Æ©ŒÝ"_ú³�Š 5sh›ÇÂãí û¾ãOQÔVQ�µVT·ã¯­Ak3»òÃãí�·Ç['jšƒ€==?ŸØÊÖ�ýñœ@(l®û¶wW‚RŠ;¬pÿYÞæË?Ó³•LÏ'¯è2¯š9ˆ IEkÍŸIó DN&’DšTðÿŸã…V­ZµjÕªU«þO«EXµjÕªU«V­Zµê7(í€`†ÛG½½`'>›UÛªèQWÂKÜ)ãY“ªt²TÖžElïÑy&6ÙV‡h9C¥¼�8pö7>“ ã¨0@NHàÁBÆËbi®–AF¸÷äU SŽ.ÖÞg½_q™n§$ôÜæq¸¡ÂL�ƒ™|�š5ƒIH„IÇ8!YÌl ÁiÿÑ·”S¾‘Uüøs�)Güö§¸8èßx¯zÑ�~]IÁ­76ãAµ¸Û“äx ©§�X&{@�}|I²úVˆ˜=zB¹G)„‚ÕÔ¤˜K3 [p�FI9)fÓõšÀß®[ûcð²åqØù‡k€úÚ’]¿0w™­ÚE®€–~Ž r ßÁÒîR iÒ ÐÛê6T€ÒŒ„ÀîH�3Òóµj€ýÏû¥!�k"=¨Ú¾q˜ñÂñ„´í¨�ÃçxVý»À„ä›9kýbñ/ØUý§Qt±a1S‚bã„m�¹uþ q¾Ê“2ÿ<Çúå{�ž ¥W† ¸KI!M¹% ø×[;ù+h¯·2ˆÿNuýz¶Hq I⺪Ü5´ÿŠî?…á‘í ãæˆè'œ\Î,¥—N}ÈC!*�Ñ~ÿ˜ ú�µS_ Ýi?=7ü‰“½ÁyBüb^XÀpê8;èe}ÿù¨‡�è®îÀ;Ôò*‚ÚªeÛ×vï�  ”Í£ 3D�ÇÅó Â.ß[º¢¾âA«ÍH�EÁLãùFÚü<ä—ODPë�çóÀ¶?�d°íögß°•QÅñ<ðóã'~þõ~~|àxh­‚¹ïÀã!äïäèçY÷Šý±£læÐjíבü߇{€‘,R ÕÖ‰“Ù1àúÇIs‰”ˆp‘’fÄ _ûZc´ÚPKó±´�˜ M;a ƲNNOcü1qw+|R�(‚éªU«V­ZµjÕ*‹°jÕªU«V­ZµjÕoSö²3p‡Y>`WIi²,þv�N™©d–Anÿ�½L„\q*±‹¹ÿh’-}n²&õë¹:Ðû‹—ÍJ=¯7Ü&+¨ƒÿ’²º'Ãc3¨ÕA�®R˶ÂNP>�6ÔÁ·÷T"ÃF¿H» ²÷æ+S… ïüIÉMïùd�)£áµ‚tR&U«&rEWp^.TNol£'+é/Õÿ¯èü�~KÑm-h39@\ŒÜ@‰¡Ê °®€¤9¸+Ú1÷F br]¾�Ý–àà¶4w©pP¼hQPü“\‡‚�ÿ :(ˆ`'ªÍÉm� @«¶�;trHŒc€Þ.ߟ„k·و­\ Jæ2@c :È2ŽP6'FÀh;7ö"Hm•ÑŽ8?¡!Ö‡4@�†vx~¨Ï © ­ ¥tž1t£°¦3 ÆUô L`0nAÿß�$Õwÿ¨‘•ˆ 4©ªSÃ’cˆ’˜åüùhç¹¥c½>»}®9ꯢ&M¨Í'¢Âü§´Îh&†a&¤åõ¡· 4\ èº]Ž„†LÚ¸‰žé¶ñ9fC¯9ÃEi&‡èW×ö,u§»¨oKÝ!†¦Ó¿]t»=@ï ¡ö�ûÃMœÀ=‰å‹¡yGw éIùŸwÖ�ûôL0�ʃ’~ÕŒ™(qŽÃ øç�ûéÚ‹Põ@á8Ø$€°Í¯ÌЪf'O v+ý9ŽfÜc�G|'çI®bÖµ}ßnÏMè»xFOR¶t8š “K@´1vÁö<¶tÂÁùšœaM qÑŒÊô¬lÊÀ�·¡GN„zs²p>åQ÷ãëßÁèÿžßº¾ÞÍ݇µVT9¬�MPëRŸ¨ hoÀÖ€Zbps¼‡€E ,Pe´&`RTläjñ²dýªÕÀNÏ6fTs®hŠRÌž_¹²õ«�R\ð_«ƒã 8hž\ 4þnw�ä< Í÷åä‚ ésÐ6€œpÄ{ZLøÿä èÓö©øá�D`hµTš;4‹&€·Gküƒ¤„–Ú@ªµ>Q?+D*Z5°.O0=[Ìgàš†z”Î �ÄÙ¯ØI¢?ßtZƒ¹¯iî;Ñãæ4Í}9Ô§ø€“åþWÊéAìÑ”€ c˜ Ûõ�û‹­sç ¥oZ¾rä{Qre û9ª—3ý¨)F¦¯9Úݵ%â3™äL§ÒÙqê틪¿,†{Î‹Ü‚Ž„_AH'Kܸާòõ^ç¶tž@8ö|±L¾$x GÅ´T�o:¡cv ‰˜ øøÍ�úÚˆ¿#ݹ¦Ÿˆˆ~óÎQF™s ÔÚ€ (Ø\ݾƒËÄ-Sþ@ÕvœÅ•ú¤œ×&�VQkCí ÿó8°=Ÿ€çç'ŽÏ'>�'>?¢µ†RÊD<q¼5T'ØZe×t+G}â¨<œl°o;Þßßñç¢lÛÖi‚ã8ðùùaþ¥à8ÞQ[3²ã¦—çÆhSü çƒügÛv”­à!�NØ÷­«÷ÏÑ Ì¥�ÉÂÌFÌìCÀûTÅνI…2 T¶g•xž ò@ôÍD8€)þA„Â89;ôç ±çQfÆVÊúǪU«V­ZµjUªEXµjÕªU«V­Zµê7¨Â%lX‡Ë) )ëøiªïã‘Ce¨);c )ÉÿU ôuU¦ª‚6{ÙΔ­·“ÂRÍ"v¨xS/”ÓËe J¼D¾(»BÊIe™y [ì-oè�w…舸Ž:pÈ +àüm/½¥çÓÆ~‡bîþúv%dïCL*Þ10"t‚<»Ý�¤£H Y?ïØ¯Ìvßq5ˆ»‚–(ÛœA¸ Í$=)„¿[ßÁÿçŒô»Pz¹]mOÔúÕ‚Ú÷í@˜u=ª¦~ÇV ”�4HϬ� À†e“l¶Óì࿊€P� ¦ÜWñ±P „+˜ Ò€²mö÷®~—Ž7îî�¯@ØñWhñ Œ7r‹}?ù~¨“´%ˆ·€·Á£ð/O@? ¼`_áí+¾¿jíA›µ¥Y¿t²@w-Ðy�P'?tP×T´Ú*¤VÔv@«¸ÃÕårí5æ îPþ—ã%–Žy‚¼°C§›¤zJŠæìŽ‚Y…n±è óEM?5ê5¡†^üÔœp‰5˜h;É ]ÕïŽJ –ÉJà ³ŸÎ>¯aÐ[ü¼Ÿ?�IP³ ©Þvˆ&·f7…Ó±nA¦ 0–MºDˆHZgO×wº§¦k~“Š�Étwq/®|Nƒ¡¼O4� ¼ŠÐ|OB·ÞŸˆ'隟ƒè‹n{ÿðwK}? W©"¨µvà�ˆ°íûÞUê"ži÷ÓVÚf=u°ÿ8*ª¯g­VÏ'žŸ°þüüÀç瞦Èo­`í uÜ÷Zm¨­â8<ÏÞ�~âûQQ�:Üwˆ°³äߊ�Þªî8p<ñññýõ³Ûá?ox{{³su |¸ g€ÂÛ¶u›ÿ7ÇÒ]±ïìûÃÚªŠzpßWì¯ÿa–É<ÈlÔ†“Š‘3iƒx!Òü3× ÑOZ¶ø—b±æÀ#®ªG3X¤ÁªU«V­ZµjÕªQëéhÕªU«V­ZµjÕªßáÁ½ìhZ1CýV“*=�;”m¯O z¨ú.J;X,9ðûllݘ“+Gó Ø‘ËªÝš‚»þΑ 2•CA0ÈÑ8÷+¾‡HßÕõ]%‡[¹çès èÀÍ”  ˆtJd Õ®¹åÖ‹äÿW•oŽR½ýJïOv&\zê4½ZšOûxÕáª�Ö µAဲ6ÈqnM,RP�f¨? ¸È©(b8v±ÌanbQ¨ÚÁ  �ý "²%&N¨ú €'@›aà�(“ý¤üoY%/³µGN‰5½6@‚'"†ÀT÷ QŸßp%¾VH¸„ººì6ð‰a¼‡ ´' Ÿ€þ„¶§¹@]ÑϾK±sÓiž;Íæz0üè�€æäççóG$»8xÔŒT¡M,fCMÎó�’„}Íøåøx5¤éô³lMŽÌ�¹;ÆX7pg˜˜�} ÂRR©¿" Es²Ý?�ãÝm$€³ý€ôõ`›†€ß;˜å,¾ënÀbJvõŠËÚ{Y1”.ëÛ|ZLŒûÌ•”¿rˆÓ=n¬Ï7nv­É‰X–.ñ‰ð¡)àLSº_¦rÄáD#èàÐt{I¬«ËuÉë|ô‹þ ¤§WÇ9GRèËuöné‹}~¹¯W÷ŽyÕCkfµ÷•â€p(ò @?Ъ­9¶Ö Z«¨më$¼g=PëÑÕïçc‚ ¢OÀççÇñÄqØç�ÃÖ*æùY«5îÍH°©Ùß?v‹h­¡98ÞÄýF<ø|~âóó?þÄÏŸöwŒ‹ýñÀÛû¶mïྷ¢Õæ$JFÙ6<œPùþþŽ÷÷7<;¶²uÂ<;ÞÞý9î`îíêÏ)þwaF)û¾;qÀ^1Gƒ*�çÃÆ—’HŸä÷ßÙa€‰»šß®oA!ÆÆÖFæ¦â×¥uâD¸>¬ZµjÕªU«V­JïW¬ZµjÕªU«V­Zõ<¸— P'àŠP·êï@wVk�yVÚÍÙòÝß_^GÞj‘ÝÂ'|7¯ì'Ê�”LqG†ñ™�Þ^ô–b´”UŽ˜s›³’¼« N ¾/;�‘³;úbDtGhσ¹ã%²+ß©™’Ÿ‚Tq‰*P|%j�—Üä äyÛ—ÀД±–Û:YÏ*üÓö gçõq0À¬ü'PÊþáÛ(NùË'pè«|ô[�hV®þËõ¯ûLá!,ãÅQY˜b0 ½ÑDTA� Ûˆ¼;oêÛÒphP* �‚9ÔõšŽÙ Ÿ§ÃæGSÚ‡Í=ØA.³L]õ1 ñ»j'[öÜçn¡/Éö¿K½c‡“ÑŒ˜–Ê“Ï7¨Í"äéàÿ_�° Z@ä=Tãœ"Go«¶ T>ìè‹A¸¨ â‚GhtG€<§ƒ$ q^e€Nt™GÇ¿˜ÐÓ°Þè3¤ÛôëËýÌëð÷Fä<òÙUå³s0\„ëÎGìËí1_6d& €8€ëo?·áïOÙ—>¹}ÜŸèP¤�èL`÷kÈ>—iXÓM@Ãi-Ò)Òàõ 2}·¦ÅúDp&Ìë:Ý\kêÏc$[úk'Ðø|ÿ�,7¹ÜÐ|¾Þ/Ù½!ÆRÜ?5ÅÚ\ÆM¾ïd§˜;"@¸ü�¼u½!(àï%½Üÿ™!Nè¶þA([·½Ïöñê8_{Õãè`7»¢žÈÀè&â®0Ûý¾_„§bíàn !±ýkçÑnûÃb4 †Nt¤ïÒ”øÉÖ_žnÿì MiñÍÁ�@ØÆW#±šGÌA‚1Åc¢�µ<‘Pô¤Òvg€¸y>žæ×üÓAšŠÑOéܧhŒ>Abmù>EOàçÀ¤@^Ǽºkb=ÓÓ©ÜñpoZðEãúzm�õ D¼:ÝZëe+æy?-Yzmon¸^ \^ú¿ëÝ7ì½<Û»tPïId4¥k#5JTÓzJÝ¡ß8鋯ô±IaO§¶%Òíò?G9ÌÀmþû²¦ªNçpéZük}<7ñîøb|Üô¯-¿ \«Ûí»�¿[ÂÀ.=–g"€’P dÀø¶ovŸp¢a<¿”bøV6ÔҦآ‰Èèç,Nãi€êÕ-þŸŸŸ "ÔÃb[þùÏÿÄüßÿ7þúëŸx>Ý™À æjPñ|>ñù|bÛŒLY¶ÒI0ñý¾?PJC)ÞÞضA�&hdÏ:\L}/û#©ëZ«#*ÉÇ� x{¼áýý ûþ1AvÁþذo>ˆgýô{�6Ùžûè–D"ý‡³S)ãY/žt¬?-`ÕªU«V­ZµêôquÁªU«V­ZµjÕªU¿CiϺ§l tp÷.S8;UÏÀÎ*ÖŽG Dð¾AŒùYr£oW}1^“A~&€`ã=Ÿôä4Íz©¤§ô±¼þŒ5h“ÃI!�Ч˜r2†&‚B¿JøÚç#ÍVÍàÝéþA737‰TðÕ‚ðòøÔï¯ÓìŠurгW€úZ�›ƒžV2�¯[¾»Nq©g‡õÞ�N ¬ý覗ODè|oAºÇ�$¿Ïž‰gõþ/@Ö3±kpÝôË5þަȯ_¥ß�£âóã£ï¯lÒÄÔ󟟨€Òx‹H÷tvõ=— Û¶áí±cÛ®”wú®x<x{Gmâ$š³U~w]ˆïžߦyE}ÛŸ??pT#$ÏýõOü¯ÿõ¿ðññµá«8±!îcá1ÄóŒ8Õâ6úfÏ_ë�Ÿ?¢¥”îdм_ˆ,¢ÉÎ�{|Á¸fÌ—RPʆ}ßQ¸@7EÙ Û±ø`H5烜be ~&e4'sÙºNñŒD?¾ª VsT8j…øÏ¹ðú§ÂªU«V­ZµjUªEXµjÕªU«V­Zµê7¨¦­ƒ_:ᄡ楓ò5ÿ]%ÿJ•x¶Ì2²„§;x#5Û&·Ï$'252 Ý€y™À‹Y)?g#Ùß[œºrl4•†²ÛÁó bó€Ùm±-3 ³$.¢÷À˜\pOsK g4øŠ³eû|Í^-̤ ¿€]í™öM Ð�/ón‡p•’²>úñŠ �íŸõ$MàïìT<%»zëóëù²Nã;öûr°±e ¦¾Ñ9 ¸J!Sz"T.“ø¸ßŒ$Pl_TŠ‘Y0Üà8¾ÁÕâqÓwvðßí¦ÜhÝΔùþÜ õƒ®›£Ä $WöÜöÒÉ,êÇlݞݠÈ-üÙwÐæ¬1å«÷ý, bh·¹ ˜¡­ŒcF  +ðpÌPhñÚÈœ¤A´%ôÛ×0xc”bcÊŽ”H/ ØÇ92ƒá©“t²CM€§"«Ü©Žè[vÒI~^›_B �ä1|¾òÆdJð?} ÎÞ8ŽÜN¸Øgv„q7š,gà’ë¼í€/…¥üý�¥+ÕOóúüŸšKóú?;�øõ�ƃι'}åÒi!Ϥ§q0H!éçáºkÚÅFå~EÏ_ ’ÁXGû¹œ×\ÊçLZ›óÎ÷Žù&O' ÷K@'ÛÍ}õÂTå—¥óÿð‹T†t?Л±D/‰_ìŠ|µ+>ŸO¨*Žãè??žO<�Çq¤cåç�Á\üyÃìêû†R6¹Ù~ODØ �öŽöÃ@÷çãï8F\¿Vy¸)ükî™÷%Úy<ñ|~¢µ†¿þú‰Ÿ?ÿÂÏŸáãã³GÄsÓ¾?: @DüOƒ´ñ³³m?`„�Ïψ4|||vÕ~ƪ­Ašt‡„ œ ÌŒZ´¶£É–"œtê1R$�|(ÌyD´¢Uéû­à×EEö¬fcý 1·„gõãV´f¤‹RÊúǪU«V­ZµjUªEXµjÕªU«V­Zµê7¨ZkοÕ䎭® PÆ…pù~;3t¯]ÅÀ€ádYYO“AÔ‡ÚÕ� •®|ë²ûˆ™«¾+Þ5#©Ñg[ïI 9"¼“ùʺu´%~éÀ_� ¡ºWL:æøYØè�Ò̳ímÙÎ�:~;„÷ÉbüŒËQ†º4K(§xƒqÚ7t M˜©+ˆµ·=_êß©ÞÕó€Ò—ßÆÐ˜ÿÀÈ%fúßtñýU45sAÙ †Bþsr£p,½°9](ÜÑÀâ ÿb ÈRÀ´�9úPN rû}j]ÏÄ@Q@·Óõð_FG0;ð¸¾w´v'û>I¢e€ ¤è™¾­(.0P^ÆEÔøœÙ÷£=>&ÅÉ œz†jñ­˜ëGôƒ¨ƒÿÉ [&l¶o €Ÿ}D ”AŽ0Wsr é‚ŸÐbJn#·%)­OŸ èÜ…§¡™•ÉS"»t†ä‡SÀÝ:E|Ðü¿×sïË1>" â\p9¿éˆ1ë;˜ßÉYn»M‰ Ð'YDôed8Š`¶mbºqå@â=|1õ _,/Ý~ŽÉ+e'[é)Ú! ÂLFÊ z»Æ r�N2}üÚ6%ÛôC'âÞËçuøBtÓó)Œá¤°tïΦý~wnn8YÜ´÷z}~m·p‰|832AÇÁ[3èzCè$››ãa+›à­áóóµV”çDäÎGWü³«Ýã¸ö‡'ÖÅõB¢j>+d6öeß°×�·χîi²31Šm3e=·Š"v쮜ߌ`�]ŽãÀÇÇ'þúëŸøøøÙ­ÿ`+;°Á#ŠÙãŸÜ P—Ú×� |úí…»Òßóþ¢Mâ ñGDF�q¿k"Ø·ÝžY[Åñ<ðùüÄóó‰Ú»c_ÏZÑŽÚ Ÿñì}ÿMÐj5õÿQÑjõèõmÖ+îU«V­ZµjÕª\ëéhÕªU«V­Zµjժߠžõè¶á¡$�C“3P n{oŸ/˜ —Ié{˜"|;Á¤zev°,^gð OÇ D‹6Ëií–þaò—À ­˜T'X&µHêÇ2èn/ãís£à{Qwe|·ûÏ—5”—IÝÑßu%]þ{@öÔU¯ý°šrÇÏyÍA8PSFÞ¶Šö?¹‘9 <ޤ~�ÕãæüÜU|‚Ä¢D­¡’ŒN‘ú÷0øL²èç�,ÕÏØ#vâ¬ö¤y~ÐWâçìí­ŽØz8.W%0ÏïÄ0¹y) 4S«C�,P@ÌÈaé øš[I˜­½ªÍsÛ/ˆ°r¾†í±!õ­ÃÆû¼É¾Êù¼‹Ÿ‡»V#i—DèŠ8ñ@ÅÛò™Úð´vª€¨xŸ P†ˆºõ´Ø”þ|Œ�ér#GÀúƒÈ ®ƒÐ£=?šŸOÏÃ-þ-b I ¾Jo›¹!ðV,šÇ£¡¬Í‚VÍm¡USþ+ÔÉ|!r­ZµjÕªU«Výw¯EXµjÕªU«V­Zµê7¨£VÀ_‚f%c¯¬¨DÂ×ìl§lÚ®˜Ï B5 žxË=Ïö¯/ËA{ÙÛ†r ö‚7€õVxýL‰,ÝÈ\gËTO¶ç¦tTWG`€Q ¤ ø6e �ñÒ­w©0 [ ¼fK+ Òª¿h6À5@yÍ*Wï«9Ÿ{Ý ì‡[ÞB'" Dð‰þƒ&ÂÇ)û9”¡)çœNÊÈ ïÓ||#OLŽ1†Ø‘¿AÈÇÕWQzÃ>®'‘þ*^ú ™Õ¥ËmŒþ4 ‰“PØ­†*â!ƒÆµ¹‡V(hbªù�2±«ÿ›ƒÿâ@»©æmÜm~mJÞ“R_�ôí;_m¿Ð÷eWÜ�y×Ñýp©8 D}¬Ã•ÿÈž}­á6ÐT@;¶ˆƒtŠø!¨ØÏŸF4A1‚µjûè¤ '&`³ã[ÿF›ºúÓINîa"”bÎ TýW¿RοZª0Ï_¸Ó‡`Z/VéWŽu· :“ZN๩çñÂ=Qè«XŒäòåÔ<…| ëê{Ðä B§lò3ø-"�ï=}¨uç—±^é«yÙWnís“ô_¸n¹¯Àã¡*ýüAQ½®¥NŸ¢rúÊ=±2r 5¹@èMà@^ µKæ•fË~œ†K§:DlÄù鈀é÷lÕö„;9|s�Ÿ\7èWñÊ€†»@"kÄ÷��{Ž@¬wwÑBÖ Æãñ@­àÖðvÏ�g&‚+îÙ@÷Íæ-øLNʳg UEEŒº™þ¶5ì­¢–½; Ôút0ºiPeº·!�ê[Ù ›=g.Nªœ�w�Æy†âŸÝ9€)”ûÅŸ©Lé?; T<ŸŸ8<ú H�Mš�éÉÖ?ŽÙ: ½ß8ÅävÇŸŸO¼}~¢ø3b« ŸÏÏçžÏOÔã@Ó¸ßJ�M�Vû|³g¸‚mßñØwȶƒ�P N¨µâ8Z«PIN …'·€U«V­ZµjÕªU‹°jÕªU«V­ZµjÕoQµ[§b('Õá ( Ëßná@:n_ö"o‡¡$ë¤�Y–áJ52ÀPˆ+Ðt€ÿ­µ$�4ࣶ V†¨&ëuî¹åºš83cÛLiÝ#ÖÕ^ÔÇ ì°ðe&Þ)î‚Z÷UÁL¦.Ãæ€¤µÝÜ øo5Àƒ°cO S �k�¾‰Äð®Â“áÐA± LÞ¤*NÔ‘ÿœ€5ô+Ñ鳺:W"ˆ»ÄшGTAÖ«^!²óÏfÈgúÉÙžw‚S?ÁÛ­cØþ ¼XAãuŽùíö ŠmÕ­�Z! 4a\h¸Õk³”hÌ3HÜ-ÄáD’†®üÇ%Y¨0ŠVÿg¸pŸ#,$À9ú# ùþP͹!Ô­ ÈÕýš¶…GÄ;l{1"Ak5©™KW¬�ÎwÒAûP]ÅíQÄæ,ÀÖpíQOhS$dä-ÞFž3Òý€ã¢ ² ÝÀ„\ÁoyÙz&u¸âþ%øÿ‹±4”븬£4ùÓÓëôöh�ÏÈ“bˆÞÏpü ¼Ü{`Ðé+�"èϾã¥qŽU‰6�œí‰Àdù8`¿Ý) È„©ÙA¥_çè§/Ü nöy�cÜf™N0/÷=Âî�3\ yi(qUë÷ߤ5wŒ±ùâ©“¤4Ǿܲ¦Æ™ƒn浯û:èˆ@ŠlÈc‰nÖì{Ûÿ¼ÄÞ,ÖÝóÿz�˜H©ÁùæüÎ÷}±®33Þ‹Ú³‰Wº¥…í?£¸òßwlÛÞÁ.CýoÛ·É’~ÛÔz`ßÞðxT”rôg•çñ4€»Öþ¼CD�€H~e¶5Ì@ê9&†˜z¬€ª+~æÀ›Å=w…<% >žÙZmã™ñ¨¦Ê>�ðôg:íà{KÏO¹/;)Á×Ý JlÛ Ä1‹¨2`þ‰ÂŠV+ŽÃžÇ‡;ˆ4#L9Ô¯`‘ ›l�°BLý¥µˆ 6{6«µB[ëî6ÑÛ¾¯,¬ZµjÕªU«V¥Z€U«V­ZµjÕªU«~ƒ2UÕö¶èYÖHÊn CG¡8ÇPð?TÛn#K×0êØ®`ƒ;šv¡³YE˜Ë r‹Y·zUWú÷¬{"SÈ9V)"`SÀ ܰß/Å^šs)=¿8Î)ܘ�˜ ¡´ô¬Y¨ µŠÚTª·…ÑzyÊ— Ú7Ìåš]ßã €ãšPÚEš“ |ÿ†Ä=çŒOE™x€®ÔŸ„¸·ªâD ›p�<øužø}ûn7Q½ØmwGO9º; üÍVLVÐWðê,Rh@*®ˆl "x+U�m³,7Å,ú•` öÍ÷á’@ÖI´€ E¤Ú¹K3P›üŸâ½É<”¹ìûUwhêøïêü|<.˜”Æâ —èwhà„#Axœ�†R?/Ahðk…B̹ ˆ\ Ø$?¨Ÿ³ÅK¨)PÀÝ €† òê×#;ø( ð…O‹Ÿ…õ9ü7F�]i„‹Ð#ø?ÝÇ�11†©~_”;°Ž4E5�}�Aë‘KÒŒSJ›È)0·M£ëÂrþ-a²å§—‰Ü㋵)ÇäXóSqr-Á»G?Ó ÜyæãëpÁл롔\’ÕrÈÚu½äÍŸ»�>=:D$O&sh§²d›ÿpEˆ]²‚�ô1æ1¯ÑyýǨ”ÆÄùšNÉé¾1áóùÞ@s—C_н.„z=°ôëÑíX¤¯ï‘/HDæþ³‰ –f 8�Ȥ³·}Ããí o�ÞßßñööŽmßÒ3ÒÇÍEÀõV7õÀ¾UÔcGÙöNR0õû'Žã‰çqø³ˆ­(‰òº$ž7‚l¨Ò•þ¥è.msç™Àÿ³õ¿‘Ceßp‡Å4³ËR§ˆt‡ˆ³›}à ¢KýÙµöö(áPšÜ¸ øM® ×RJöÿ#š!»¨ÚϪýy1\Œº›ƒ÷תU«V­ZµjÕªQëéhÕªU«V­Zµjժߠ�7{‘Íüâø°r¾*ûíÕ{ÏŸOþDŒRæ|dõÏŠªƒ÷67tÑ•ª½èÕ¡f#WŒ¢à]µî� µ¦ˆôœÜ§©�[ÁúKmÐÍ’ÙòÄUê6¸�E8Ï6Èaÿ/# cfÈnë¤2Ò‹†å|û³.7Ž%¶Ø’€vïsdû~}¤X£n!¢aõú„vÀHnÇňø%°šIý°O×€â'w•ŽybÜþg\ÁÈYµû¯Õ×`ÑÝoE[·U·¶7ЭAØ”¾Ý¢>Æ·¶�_ì¾áŸ30Û2í¢Í7©öQñì覠²»š>ú÷4Â4öÙø¯CÝ�‰/™�Vìw·à¿)ÿÍâßÛÚ4 xœ‡¶192(¯êc‡�äŽÊþûæÎ€Fd@{t>K¡xÌœdp­úׇà1DÅ£ÐÛ¡UÑ2Èž{0åZ_GŒN\ FŒýkzJP1åñv–/5>¹«€é”Iaké<·ôäh�¹É!„æt‡ùT¿Ï„¸# d2…žÖSíàtÚød?Oa‰"©×³{M:ȼf'@^£'ƒ 7�‘mŸWäÉ+§ïÛ“‘¼ÞØ÷Ocê¢)gZrãÜD‡kȉ³¢j÷ÆÞß´} ¤ó¸I}•ãSò9èÝÚ‘³ï@jØ™�ºþtߢ·…/—ãoY»œ>{v ¸¿“ômJ)h“gÂK+4ß;~üøþñ~üñÞÞÞñxìý>` ¼+ÿ; ÀW­ J+�*¨¥¢”gŸõ8ÜÀ€öˆP-À†‹Z¾ ¤u…üççŽâIJPûoû†ÇãaÏFÇáãf~æˆg¹L^ˆßµfJûÿ5æ¥`ßoÁþó¥b¦Éu È "bN/€÷wéŽ  Eíš´{«ÉM �Öz Aõ~�çÑm+xì;ö·‡95”mÄ=ÕŠV*¶Í"ÈûkÛŒØñx¼­,¬ZµjÕªU«V¥Z€U«V­ZµjÕªU«~‡÷ýaê°é|ب8j³°h%€Y(ÕC-j­ÿUÄ- ·Ð÷,äˆg\DÄ`?׳:ž$Ù{â±µ-”¡trkÖɆ›È´¼¢CuoÇP#xî.QéD‡b»é/¡ãÜ)e‡�,K1Ûðn¯ë}—r°9b„Á¬9CþÉ~¹g;£ŸoØ®e>Mçr�Í]Óºó¯Ì�ÛÝ•ÜU£&æÎÃFˆµÏ ™•PÒQW²N4‰>>æï�³zöNEÛ•°IÙÙ³®1@Œ±;ý·æÉewvÝae5KoÖ�@ð9æ’g$3bÌ„"ƒãž3í6ü˜ß�sR °m0ë}·Â�ƒË<·Á¦Æ×ä›tëý3 ß7“Èú˜•ÿÒ>Ñ#ЀFf$ bê|áÑ?Úz‡8µÕù €p"C4 :Q:ìÿ9_˜°‚—žOn¤�j$‰¯ _HU1u©¯e#¢ÃÁs¥Dp‰AŸ³®Í'M&êªuý:¿£ÿ¼ˆ'Ç‹ÔOW™,{<1u’{¥lxÛB§Œùù˜ô¥ ‚~ë¼z—‰©+‹âû\Mõtê“°³�a©d¤ŒõE`fÄFÁ È§éÃâLÖÒ+°�ÛkÌ�Ƽ7*èSc_³"É•a\‡ù¼/V‘Ð2�o=P�<íî®ðÓÝð‰ß�¬øXKûšzû5õÕåëWö¼~ëÔï¹Ï{·æc|ðßú•“ÌÅÁàÕ��Rf½´bæ#ömÇû�øñãþüóOüñÇض­?O ç�¸8E(™©Â,󙸃ìÇQqÔÍAns1Ê–úÔ÷¡¡Ào2¢ Üý(Ê¢ [)ض}Dy$�-Ñ2÷#ÄÏ!œ††Ú_øÏØÊfn ÛÖÁsæ2 Ä£ $çÎq ¥<á÷Ýúþ¼énN¶'.I"(x4@ôY´i{à±o`2â§4±¾>ÇÑc¥Ì1€±ï<Þë «V­ZµjÕªUù=âê‚U«V­ZµjÕªU«þϯ°œ‡G­× ÓìÌ4�ÎÚÁ�l�<¢Ú‡e¾^Ú“‘ÏÞœ”gឯŒbBœš8©&¬7kWï=^š®ªšBØÉ°š:;!`v?ˆ˜�‚@Yq…ËØ�Œ‘ïÌÌÖ”-o]]Í ‰AÉÊ;$­*ÝÖ;ˆA `vLä”/}U“¦ æ®M4[�««Ä¥yû$Ùl«»2ôÏ“ã©<Æ�Ÿ€¤‰9{Y'(.gyë™Ë�âΤ…õÙÄSý¯p8·aš87YÞ¦.'³ƒ"pa_]Ù³ÿµt²Ì÷‹oQÜÊ „ U·ý‡$àÜ f`À|Ùý8£wÏà®É   îŠÝæàø™ñ0æ»)ì+¤}v+;Œßs(ýÓ€†;#DL†’#¶®ÄçN…ðö§mâ{!(W�–¤ü÷ß©ô1d„ƒj±ü—1æ‘\OT€ŒœÈB‘4ЯwŸ©˜ó1R/u»}M@2’·þø»‹¿õ~Í�tÛ³™ŠÈš¼ý#Ÿ]e¡ïÀÎ9œ…GÎêîWYñ§‰ðRœ}÷©ÓyŒóÓibå\÷¼Gê�I „ÙbNN,¢dã9ÀEIç→Áè¯Î—îcE&"E2€ÑóE£1�:1#XXéܧCÜ9²x|Ä©¯5(g}<Љ¨ä�D±,öDTCŽ£™Ç_ôñÝu¾á¿úþÅPšŽ~õ™_­Õ¯ÆíÙÉ'ÝéåáÒJOdÏÅ,åßßßðÇâÏ?ÿ�?þø�Çãæ‚Öê…ÜfdAöØ¡½æ lšGÇ ýDuð?ŠIÒ=0æžyOˆ(·ìÏÑ9*ŠÝc ây†™; ¸#ä™K’#⇤÷]¨ø·R,áí ï?~àýí ooï(Û ´ÚpÏ…К̓|¬ˆpåþVv<Þx{„jOAÐaB!Š=«Hõh¦DBĶm([ÁdµÏ×z V�6h Òls±>zìûúǪU«V­ZµjUªEXµjÕªU«V­Zµê7¨ãxBjE…4¹yõ>[Ãâ.ÿ<Ôƒ@è[ô—ººŽú6jzϸ�¢s³m˘�N(Åh¦Hû”M�ªP8°î/³9ìÅ•ºê¿N sê„UšÂØÇdÃÌ s4uƒ’ãw#Ç›Òy�4Yþ³+ªÙ�‹¤þ·£Ëè®Sæ\éÃê��¬dADM=ÈV±ÙOëÉ:Üì ;íéäÎÐÃvÎO¸‚s/pý1ƒ‰7˜ý߉rŸ¶›¾Öiè#@nËhs¿gwëg øœ!æðÚ¤%u"·Øw@‘TB…ê.ÕÖ¯Õ 8©€Mí^üp}d @]¥�N¨úÇàDP¹‚?]$1%¿Èáû ðÿ°®'VºbÛg¾£é»+ÿËPög@_Â]@O ’›ø\d½;) ì¡5Úâ'¨êJ]­ÐÚŒ‘H:¨ h¥3 M~ìJÿ0'øæLFþ§q8"E‚:$ p¢U™–0�÷“i:©ØóDš•ÙsÂÀüyÕ/N6�µ¿~A º€ß)þEóI ö{Uú��éÉ%E_ÜŠ‡Nî#®¥Èšdï?]ŽäìC'¢@'RåX›‘'}Òý@8�õ3aŠ.û�u›n¢^îVã/n Þžp·¡»ë•1^íGL^�c²»gf<³þÿóøóÏ?ðþþe+=ž'ßÿ™ûcwEùn¤F¤û´š3F«TO�(Û–ž—®$€£š“ÞLM þÛÛ»ÇèäüæÛ±ÞÁßOk-¹°l›"öÝÜþüãüùçŸxÿñû¶wÀóùÄóù���'žÏO°ô-»813:Ç"Ì�‰¹Ø˜eê„Db#×mÌ`.¶4=¬ÍÕ� ‚d@Åúp+Ö�±i‚Ú*jm¨ÏjŽ :»”RÖ?V­ZµjÕªU«R-ÀªU«V­ZµjÕªU¿Aýüø‰ö¬hÒ&Õý]e€ÀP7w;mé¶³+WíÐtÎOfW¾@é¶ù<‘ì˜ôY¡è û©tÅ(u ~ˤÝÀ¥ tû\ñ¯Ø,¶³z-ÅTa¥”Nt0%ڥɟÈ�y’²{è‡ j–»l.C…ÝÄ®F¶í9©íÃNºZ� ½BLÀ ñ ü„›@8dǤkj×A]·ÜõóÅlŒ®pÉÆ�a­ ¼ïmÈ„€Óp‚'ǘ‹¿¿ðmî± °»Æ8@{Qž¢»Ì?ûŽðt¸r;MN&éƒ!ÀÏfÀ“ƒ–TÎ@m(š‹Øl< €àX91âó-‡~}šzÊ€Åmô;øbD ˆšÂÔP'´PÉË´�h¤úÜlÎk ÎÁö5èôø:ïÇOD…�²9ø_lM ´“Ƥ!ñ�ƹŠ+ýc°t–‹õ™žÆÇ° b@³9& ha¡¯' u…êÉQƒð~5¿RÏ¿lw¡:­îˆÂ HëÀ×)7dŒÝäÒñr%’Uviy¥Œ¾ PWèå¸_ÇÌ;è¤ ¿.C?Tû� ›Diú¨öøÀÖ²¾VÅ:p»ð¤{I:‘‰bô ˜ÖƆjz^üæk®~�È®*yM¼ÄžàÑ£q?ñ1ã¤[»g& ¦\·uï÷Ø4¾{ûÓXËà¿ }zéÙüàr]õÅ"Káòpú]'€äqÿÅt¹=Vúù+1­Õô’Ø€Ó¨¬Ç�§ÛËå™5ý¾ãýýüñooïØv³þkýN( âÅÏ �¸¨ ©f]ÿ|~Ÿì1I~OgÛ϶ïØ÷ÌÔiSÓS'6¶ÖP[—[­“3S<¿lN"Èd†ÞÞÓó dí±}J'7X4“ˆvbÉV öýa¶ùû£÷‰E«4àI�°pè™úµ {~»m g€h³Åؽ¤ld/ØÊ“P˜;ϬÇ:±CÝ™ìÇ%wà F©¢Ò]ÎÏH«V­ZµjÕªU«`ÕªU«V­Zµjժߢþúç_�ã€ÔšÔ‡gófê/‡É³h'€'^rwÿée©fÀ Œ† -uà?òbÃ’>% LîÌ€ƒ,€“[€+ð ü/ýk"î/Ô¹Œ¨�²W™™}¿½\wÀè ‚ˆ+mUí3¡%L “�$mä©wÉü ip�\‘Yˆ{ß�4Ô÷ùet¼èf.\§a·N ÏÊv03C+ÉÒY;€„~�â:˜^=‘Z3G÷l!à s´¿ƒ¤ ¢v%eqD&`ö~œFjv(:ǸšÇÙk@'ƒxt'³#ˆç}:¥>KŸ “ŒfÿL–fâz´p«·’â–ùJ�′BjEaóW@Wv‡}¾oçûí¨©¨·´Ï þK’*³¤Ï‘‰ïKõ6…òQ:P.Z‡å?jä0€ÄÇ[¶JŸÀÿ˜ÌáP B@yJ¡täXî_Œ·Uç€zK6ÿñ9N¨f|ŽÉ ®$s4€ƒQ êó#cfz™1¯évÔLCìÖ_»ì›5ÛyÃ.›[þ7 ˆ“óÅÙ~<–‚ 3Öu‡qÂUw§§óÅV§ ´þUdÀ:뫊9J!¾ï«@âd¤8™î‰0úAÄÖ^&[g ÷¹»¦qù‚Ô¦/â®=€~]Dd¸›\Ö�Éå?z¯·3£î í|_Ô”‘¢Nz‹1ÎDåtÜÔk”rí3+ b|$b|ôfÌ:É ‘Iôjár¿6ŸÉ!iÉÝž¡ÀnAj ;iœ[ÒÎ�Ó†ÚRm7kþªU«V­ZµjÕªEXµjÕªU«V­Zµê7¨��Ÿ�£úw÷iÑã…¬‹t›€˜Ád?`fÇUóË\žöÔu²aV9f”­˜’?ìrÙ šYÖ4î/ˆK±ÏoesÂ�îè gÞº:2ƒ�@:Úvï*)BH�&µ©÷™«7yHÉÁʦ™&³ÎÀ”:Hñ ‰Ä1Ùvg°+»Ÿ$Õdmî {¼j@¡1A�<ÀŽðOƒØ²JõU®ó=ø`¿Ë6÷)<ˆ·8Ó¯_ÖŸ ôhŸúü¡ÙM@Xw‡VédCÕªáÕ"`h!ÔØ§Ê®|šƒаìw ¸yDbWÎC“zÞÕù°h�mÿ;À•ÿÑßá€j¹ i‡ï?€yŸ×›XÙÖ�’õû!t¸¨Â•ÿ‚;PŸ)v­@“qÀ ²û±¸ïOEº3+å”>Áy™æÜùLŠP©Xß–ëx¹ÀȺýI©~"ÁÜŒðûõë¬ü×E �”¢NÀð¾ÏQ”]ºòy\›X[EL9?)¥¸º™«ëˆ?¸öÈߨSªÂè“@€Õ“k N‘9.ÁI ZRÜŠ“|ç 0]·¾¾î¨E¢á†¢Óý)¯ŸxŸQïùGÃùÎ¥ÏëO&Ñ�«@þð›�^v­†ò?QAFøŠÌêùó~ì–u"ØÈD±:­x½¾�¾®ê|Í/÷¯ÛûÈwê ¿*j­hžYjñR,àýí ûÛJ)I©>ìã»ò¼lÛŽm7•91!@E;˜žNZ‘î"@dó’™°o;¶}ǶoÈ>ŸhÒðYìg…•ÅY{áÆ”ÇK´'®›ˆtrd<_Å\"Ø[œøÉÌhÚ 2ž�ò l"8ŽŸÇg¶²8›†Ïç'>??ðóã?ÍQÁ÷[JAaA)ÔIÝ 1‰»"(Zõ@k‡‘ cÛ6ì�͈\üù0;JÙ׺±³Y쓹 Z3F¾~ªñ÷ÿW­ZµjÕªU«Îµ«V­ZµjÕªU«Vý¥"úðÕP4S(r,…Ь#GØ”‡œÔˆ×¢žU<Àÿø{DŒ6À ¦ÄÂlmÍ]£o@u�àñ§ðLã¤@'²ÖºòläÌZ:éAĬð•C:;Ëg5ÿè¾§_|ŠF€ —ƒ°@ ˆ X­[WkŠèÖW{ôSÎz,…^zÙAÙfç-e8PcCÅŽÕ�€þÛg5Ík ƒ³”¦±Ø�*:~Ä!Ë`VˆDf�I¿ ¯2,¦˜GfÍ·#¬Gv$× ¿Ö6çÌaB�õj=¸î3í[†‚}po˜Þò¯æ M™îÔψºº^ÓÏ3ðúË´wq ÷ „5Ì7i�Û×{šfòFÿß�w½êì.óå¶¿3÷q”‹~¥ëh Å«ûÎptÁìOKéy©{1TÏı—9(_Žñ›{ž¦õ^õ×ûÊø?1í€tÓ/¢~ÕüË©ž'á/Úk9õ­»-fìûo?Ìúÿ±ï®†o�Ú,CÞ�ãˆ"Ú¶ûcÇVxŠ7Š{Ö NÚþ9²€(@ò û¾cß]ÁO Ôڰ¶]Ü€ñØw<ö7s+x{àñö†ïàñ¶ƒÈÈõ¨¨µ™Å~RäÇ3(­þ ØJ³£ó|>âú ¨[55>ù¬Ö??>ðü|Go§lÚß"] 7 …( ÍösOÔz 9)£lû±aß·Nü B'¥çÂZ Ì‚Ÿ*nøGwÍÏÇ«V­ZµjÕªU«¢`ÕªU«V­Zµjժߠþøó€(¶m§R u}Ê5(�¬ü½(©Ì:i#·º éj«Ož»jJµlsÜ÷Î9× YmnY…º¡ •æ/tÅñ£ Ø‹öÑr;lË�U4GãXê·@bÔ-f9©%{/Äy¸}r‡ïÎèÅ8òc¨ƒ_ª–<@ö‘çʸ{�䤶ôŸ0³å¸ŸUì:ÛÝfÐË¢ÌBATL9ë×wÚ&g6Ð i@ÕEÛb1`ï.cü[ŒŠì.@§ö¢_"½Ù1z›2‘âï§üÎ 4ìä“_¥ÌvÞ!ý…zŽ= ðO`¾î`ˆ* 1ˆìni|µ·Çü}œSÇÛÅz…KõÜw�™0¯‰’úS»Ú_¤ú4@^Ÿ]%lÝà |Èü£cõ,Áðô€J³Mt³ýaCºÃ@k#B•â,™­öªrÊ W§Fû$Ë«‡íùDæqöMÁˆ0©‚‘d¢Ó<ÑœN°þyøRR0gÕ÷7e\Ü)º €«ØY (,V¤·cýr²å¼ªgjë˜C§X�ëЋ|ÌCý†š{´îÎ’½ß4îÝ4Å$�~R�OkÍùöSIš÷tßOy=9¯­šÈX³ê?9— ñLäfÕˆ{¦*$³òö—Σqn#ð@Ï…#š†úXÈ6ÉûÁèh=�V:º¿¦q/ 2¥ï,øt{Ìo1â:MëZZ3¿Qñ©BŒ}ßñöö†÷·7<Þß°m»9�hEÓÖÕûA.ÜŸ•‚T ¢�¦hMÐ<‚äî>N¶—²aìØ·­Ï�£VÇ'ž;ö}ï#£l�ÇÞßà�?~àÇ�?ð�?ÿþüó¼½½GÅóù���OO1™Î­cl�g�ÔÔ8�ßp¦hUñÄ�ZkRßÛˆ�€ãxº£Bõxƒ‚­jv�꤈ÒÝ¢O{Qs{‰}€©Œ¶U´¶£”ŠmÛЊôhª2E,=æBš¢Š 5�: `r~¢WkóªU«V­ZµjÕïZ€U«V­ZµjÕªU«~ƒúŸÿóÿƒBŒ···“%?�”j 2ÙíÓ” â_ ’,ëƒ ÀÈ$šìþC¥©žÑÜîí +öû˜öµMÔÕ×è/ ¥i»B)<ÛºS�°¶ËÈŸÅh»kûK徨BÄA áޞط;)Žñœ¥ñB�Á@TÑܸµ6#‡ÉŠ9Tk7“R µçõ³+ÀçÊyÔã{t¥ÛfÏN¢ž€µÈPWX¿ Lo„3ácì9Ï“œóJFA²6ÇmÄ3�È+ö3½u&ø ˜ÊãÜ£ BõNZ¨©=CX\ç´g¶¹v«eöø`³Ï2#©'ŽxŸ‘ÊðHu?£[õÇQÌ` |ì#&@99£¹òß[Çä„…HÔÕøúi(L'_lúB(’¤Üû�F"~@�è èm‡eØ“·«5ë;iî(àÄ„Pþw²Er0 ˆ`@Ïnž~Ÿ—Èä€Ò|ÞÙü,”ù ”Ô×èÖÝ}üÐÏÓ[¢Þù(YtN8Õº;‘ ^ºtÀ_~½MëÑì CôBšž?ŸˆDÉâ>D_ôO;Ði¬‰ qW«GÌMD:dö‰fkøÈ=÷ë=EÃürMÎÔŠ×àWò¿Ýϱgó�ËÏ~Ex»CýÓ߀t�hJsSá?o¦Æßvp!4ÖýAÔËEâAQÔ&¨G¸¸ý|µ¢µa=ßÿø¹±[ÙGl‘ªbn¦vß6lÛÖã„öÇŽÇÛ;~üxÇ�àÏ?ÿ�ü�?ñ�üoï?ÏÏ'þùOBk‚Z´VûTÀœoå\¶ Os9 ž]DäÙz?ççH]µoÏ ˜Ï1HŒªþÊÛÒw”úÅ•9~µÏR ö²Ax<ü?6¥U •PÛ�vTÔ£â¨u¿Ãb¾±8qIѤÙ6µøÞÚÑpÕìí[õØ� x&½¶A´£ëé—ÍïÛ†··wüø˜ ÀàÏ?ÿÄÛûöâ¶ü…Ú<ŸO0?!ª�®ÌgðcÇcßñFì� Û1I8ŽšÈ‚âÏu<Ï`ôQé>Ý’_íÙ)H œã ˜Lù¿�PØúuUìRÑÚÖŸ=â6ÎáÂ0\¨ €x”A­vÍZ­FU£pAÙŠ+ Ã)cÕªU«V­Zµê¿W-ÀªU«V­ZµjÕªU¿AýñÇ?ðØw0oÃþÀ@í{†Bˆ'@ivÔÕYéI3øž7 nßo`„º*<€Ý“õlÅÚÎæ:—a€bÙØÈbfêñÀ+Íle•{A,'ešˆ‚0²ÜUO€£m€H*ÞÕM™‰èí`®*%Uœj§ãk(öiÎ߆@6ˆžqîa>lûgð/úwg6Ùhdkr}¸j¼R–s¸Lx½8pj”ÃûéCwVçz•“â Úg#ò®hþ%Ã_ ûzJÊ\XÕsî[ Ðè`¼–žC.¢Ø¸ÌçE€¶lä€öÈ�‘È‘QE�*�Ë>ìí££%‘94Àÿd—ˆ2€«ðƒ|rFŸ4)ì½M¸›#•lɾƒ¨:±ÂÝÚ ®á §m£Ý\R溹ÂÛe1mŽ ô“� #zÁH d2ĺâÀ“»™€*Ht2 ˜Áñ<ö¯S FoÏ�UÝ�R�"t8i(Œœ`¦ §˜‰óðsc±sº0’KÇþÓÔŽðÓ‰Pt}Îôù¬ %$ºðóÚp&ÜÎ;¢[ýÈ;®Õ�; ðSÌ猤P¦I>G´Œ.Ó¼`¹Ò?ú+­NúÂ�áîlRZJ^£â~7]C�71þµ»$䌉)jFÏî:úµ½y'á2NîTúÐo&¸ÜãtÍòóƒ~A é?{åT‘î;w÷”¯×tà±àí ðæ"‚´†çad¥ã8ðùù�ã8P� ‘"ö¸!íãÛ·ô|e“YDP�ÃíñG…´Ã]L†k�z¼@«� "ŒçñÄQÔV!­9)ÏI {Á¶Y,À¶aa+[ÙñØ7€ Òxìlûóˆ9™º_ñŽÇcÇþxÃý�ïoØ÷â?ÿ“ü…çóp׃ŠÖ*ˆ¶î"�V²5„ÍÁf˜Ó Tóÿa6•?¹Å†?sr¥ò˜¦2G?•R:Q 4‘’´;1„kÈL`âw­5ÔÚ¼ÿdœpÆñ ë÷ªU«V­ZµjU®õt´jÕªU«V­ZµjÕoP¥ãò°åé~€© †`Àsî:‘+,…M…Lç¼uº! «åP5P» gÝ,2`ÎÜžÁmy¤G€JÖ&#pZˆgûü¦m³+Ä|ûÈí%ÏÃMÀÍíp(~�"\¡*ª'¼a²0à6D Ìî* Wç{WkÓ ˜=ÙÙ;ˆЩ ’³úwÆs'7kÍ$ßg�0€ø 3„R¸“ &çUç¨îi¬�]³_}“Mô+Üçd£=ûsF6æ&áö‡7æç´w&‹•€4HW÷Û$£î]î€:ÚZ˜5>€RŒ$ ÛΫ8P=‰+Ô¨>Aò ÁaŸ( < éàø§9•sWM‹+‡ÅÇýBøv«ýHèƒE‡Å¾ºò_+ºrhwKéT›�ÓôÒ§óü´m²‹@{Úæ1qÝ_µ­AµèoN°ˆù8þ:)ÍcßîÆ ž0ŠÍq�Nƒ�NÊøN šc$(;P å°�vJ«(Î`u: õµDë×á+@,çq<Òû‘Mç šAùW1ôy®Ð¼÷!FDÓx�½ÃÊŸ.kÏÔÌ/xA(΄™´¶Ø¡ ÚÄUÔè–ê“@Þf˜�t5zc(œÇZ>/œaÃú_oï*Ã~`&ÆaŠ(˜–�3;‚0;Ç`v(˜ûð~aŒ>y•ÍЉaªÓ§WãÇÏ—& —7c×PóÝît=Ýù'y(ÌN49¼„í5¹'œû?;îüÝ—›Ûæ$B l; 3´ ŽçÓž7TÑjÅçñD}>Qk3ç"4á,Û=ÂÔù›[øC�ÚšÙÑ·Š£ àÏEùùBDL­D” áùüÀóóŸÏ'ŽVÑZ³mòXWéqF"­æ SÚsÄ4‹<*ÂP4lû†?ÿü¼1ŽÏ70šT<Ÿmh‡‘¶­`ÛL9¿ï[Wχ}¾îG+(CÛÖ ¥l âTµ¹ÒŸÏ‚ °0J�_Ú7ƾï¨íè¶ÿÃ-áþZš@È£o"Þ!\�<6ƒ˜í:íöÇ[)ë «V­ZµjÕªUùyuÁªU«V­ZµjÕªUÿç×ççZ5µÙ ýe¨è­â³W·böm£(@"ÞaËÒ¦³írÏfQz¶S,3ó¬–•l…¬jN”¨ ]­k`>Oà½8¢rå>L Ìl`|)¤Ü·+\P‘üàúÿÒâÜVÖî,@Þp�¡Ÿ—hí–þ“k€bV›_fÖÿ¿2CO÷�S_ÑMû1õ‘&PŸº1»{ƒ"g†t,ü ˆs²§NÊÈ8½~ËŽ~>·|ÎW×’Ô—¹e¸©¼Tô;£`ŠÒѳËK^«sÍiG™}ÕÉ*4îáøæ‚®÷cžº{Á8Ô<'^8ͤqyéÎt"úM2°o´˜…=_©�Ÿ ÔÃTj´fJüêöó €…;ñƒ™±— ~`ß�&Q[ë±Kaõþ(l1"ÙÚþ8ž1ÒÀqø<>Q�ÜZ3£Is°ß¢êñıïx><ë{ݱIqrBÄþÓfw�‰á�ñþ¾cILm ŒqLóüˆÅN³­¿[{M6è¦üÏkÅWc'�8½AN½�1Ædq½‘ôb8ÞŒá3ðß׽Α”1ßÁëžìp²‚ @³‡ËõtèD:ÐL8¡³–=éá)â^ÐcI褗פˆ§`ሂ˜; šÕô¢ÎŽ&æóù\®{�Ö»D”æ=.÷±N‚ÓO7}}›Ö³Påk㔬øéNÿOéçDÓZ� AŠ™¸¿²{–v e‚;'=�;½ã|o½>1à«�ÝN™sw„S͉K Ù­Ã§“HûsÛJzr’êdퟋ|2ãÉ4åÚž”5¿pasòã¶Úp¤Uw(ih~™Ä�ÿ²ox@¡²AqÛPÜ~?G ‰4µâY�4Ôç'>>>qO#xüÀEN PéJùè#‹}ÕÈ[DÀã±ã8þ4ç„ÇŽ·}ð$ÂV�gBÀιƒìJÓó 4ÏváXXج�Edrv<Š€(�óq¶âÇV1ð_3øOÜöeÕh2ñÈæT±âç£2òĉ¡ì.‚qñô*'r‰ÉyÉ>:®Þnçp•,Z]B):9šÓiÔ’ÒK¡=òJ3@ÝIC}­IWEÏÑ óï(Ÿ' à}ìjVxߘ�œº�¦X�bX´ìñmn³b¾%�¦¶¤X—’IX�Æä™¯ XîëÇéúúÛךÎ%ÿdŽ4Jlç&-Üãn˜W5÷¨;0Mn4ävìý>)A�›–¾É]a�ÎQ ’—»ùæA¸¹§†3�Î}3¹·Ü/n瘆Pó~ìV¤�”�]z(ÖîÞØyöÑqއÉÜ€S\A’UÏã¸L¼$ á›ñ /*ÆÎˆ­®.ƒHHL�Ü'ÏšhfÇ�`šýüfî,P4ih­�@F¼T[“JÙ°ï°m¶}O#F€)þe0„m7÷€­l®”'”Âì&¢4­íµ6@|>Ÿx>?ðùùÄóxâðø‚8— ËÇ�²m�ÚP[sU¾“ jE­ ௿~⟟î&àÏM\Ôë\MÏ/1§šªˆ»±Øx`^š ± €o¯'3w«~f†¹üÎTýÅoe ª‚ý!¾�9+t²%­ ø¿jÕªU«V­Zu®EXµjÕªU«V­Zµê7¨çó -Ûœó›@í®N¤3ìŽSfü¼ßì ÊÑó }=™ýæøà�,üÚ7d¢ËáTdz!_Ü*Ÿ˜úK_{ Î8ëQ§ìkNùÏ]™J=Ó=òjg×oíÀU¹- 0K � ªfãîŒôí¸çØk·('wH _´!�lô›+As�'_„l_L hê]¡PûŽè @Lô6ÇÚöÇ :Ç Ìt rÒÈ"(å­«š½0ݨˆ;²ÚÇc¾nô"güªÙŸí®ÿ à~Jvèçýˆˆ_¢æêùÄ+AIlôi¸T„ÊÞ³ÇuŒsiÞBº@kÇ¥ ë7m¢Ýø"lvÍ «í_�8ñѦæýjûn*–ò5®à!‰•èßÿ´�‰Tl ±Übì;W@¶±fx A?80ò¿©´uw (]y()Àe8p3Î]* $IÖëÚBÒ ¨B„Žë<�²J˜ŒÛÉ�Ê®ï£øõ°¢ËdJkÉ÷ni,A�!6¢GÎÉÆ]DËÐÆë¯Æz²Õ©îFô=¦Ã~J'ç}�ñðß�ϾÿSûDgk|v3 Ò€œÀ¡Ì'·Rïë¯÷�eÌXTLø­èh€Ê ^� P£I?÷� cê$,ÐÙîœ×t/Êç–ÇCŠ]è+œÎ.5ý~éí�< ¦HwrŸ¾\ê�¢Rò)(t®ÙI@çx™ûUY¿ƒÔ¯¥Þ�}ô4u~ExIι?[Üͺ)¤H öܯñ¼Áìd� $‘ÝÿØ#ƒS«·jk^­ÍˆGºïÛ†²mx{<°m;ÅÛºÚZƒ$Ò ¹Ã@á{àþˆ…à[¾žª ÕŠ& ÏÏ||>ñùù�vÔî T˜'µ|«ŸŸ%P�®¸�1%Mð|~âùa„sØÀdjþ&ó3h¹Œ}Ƶˆç£óŸÿãœT�„·• ²Û3–9/¡GؽxŽXµjÕªU«V­Zµ«V­ZµjÕªU«VýU�fêH�mˆ_¾3Ox/½þ¯ŠÍpMùÑИ¤=œ^ÜŠpTòKçÀÆé/æÙUÿþ›ý·çWµvDT@±ö2óȱN'ÀJXÿû �± DS �·ƒ‡mØûCY@ò]'pM$ šú=o¸š;¨â Q�!À°ƒ¦¹:»‰½”@%Åô¨š3¾ý‚Œ�„=µŽkvØ&¬5Ħƒ IØ%cjùdé‹“ŠY_YD§ÏŸQÏ3ÊW'™ë “@j7¾'n–`Ü )šѤ€8&dÊzNçF—û€Ý¬Ð=&DÁ…¡m¸€ØÜÈ‹¦öwØï''³6NÀ~ }šÈý÷Í€ýà¿çÄm}Úç cD´æ–:hß] ’íƒÂˆTÞ@¼ûµk)c„��T @ñ£ŸD|ž î4ðª–íƒÐÆ¡ˆ‘T—’´­+ùg‹sL™ëèÄJQHêœð›IBSU“óÇem=)º�“úú:#º›Ëi…ÎÛÂCÄÚÝûp|!�“êíûGpž`>ï†À=q?ÎS8Öç˜ß±n.'�pÀèq5V*¤8Å"ø­`„¹_Û¡·>gÐLâŠ{ކ)I^2¸M§~Öa'Ÿv¾J16hžîÑÓýFGüJ( q?x¹¾…cM�Vœ q·|Òd‰3æöäûÓ+¢T_zG&™¬w¦>=;}¼0 ºì¯GÁ¤-³ÃÀù<' ÿ~ÓH­EmH¸·wðtÔgWÿ—‚Â؆ê>þ.nuo±j º*êó0ë}±“.ûŽ·ÇŽ÷·wì�·îlS[O Ž{'Ážk¨×ä„$®ä‡¦{ºƒëF>8ÐjÃç矟8Ž£¯…E°aßw<öÄÅÚ|F8ˆèp=(ÌFª©GÅÇçýõüñÓ˜Ûæñ2¢'á„}¿µÿh© *Í�ýä4 ‚VÛtíÄ?wwmƒø9ÜJ'jœ£•ö¢h$P”MñX«V­ZµjÕªU§Z€U«V­ZµjÕªU«~ƒ2E]²—Ïu`²+süŒ³ò­Êùò3Ê‘m–ó>ÇËÛaÕßAçäúÈq%ÏÔåñ˜¹7*öR9N€µ—øCù/nç>$òAèU!œGAÏ GÊ¿8( Ŧýšg׃_–N ΰ½Î@@€vgU#yºaíå¶ŸW�’ÊqŽF˜áËþò=@ĤÆÓ“u7Á\:$×ôpÑìñÝÿîªpÕ�§$Š»ºÁÿÿ 늶‰Š=✪õ­®V€\èÖÁRÖ 51†ªƒ”LlvTÚÜ îäàû$' p3ž€8h/®Šz‚ƒ� ~ˆñ®~¶Îuÿ ˆ»èaûŒÀ¬ú€ý5€@Ÿ™ŽmÁÞB¦v�Çh)üçÍ]ÉêÜÎòñ?ÀlvÕa×l¨ m °iÐH�V(´5Hh`p‹¤W³à“.Î(ácAdž“ã �gR"Ñ�g@^�} ÂÝŽg½Y#TÏ£_Gd€¸s©Í¯‹:Ù×w@ÿž@s ×…ß°sšo É®^³ƒJ¦ �—ø¬ÀÏ@:õœ…s\o¦®;$–P›Da�2Éâä×ß#VÂ8¦ËÖÇÝ..»N$½:ýË‹çÅM¯| [Wé².¿^µNn+§>Q ×›áÀ‚+×Jï‰'ç3Ðt}ç;õWWI/@ü¯ôõ½ò»«úù°ª8Ž:)Â#¯>Œp"ǾðÞ ïk{'¸"|W­hMpT#4�$a.ض�·w¼¿½y$�âãùÙ•ë¹²µ=´ÖŒPà6ýÒ€¢ÀAŒ­mã÷"¨õÀó8P½ â.…ÙÀÿ·7ìûÞ�+ÒpÔŠæä"²¨‚RÐJ±%WÏçøøø@Ùvì"€«øÏ}+ÝñÄž·º€Èä¶Ï4á(“IÓ3dº€Ù €¹€Ëp€Êm±ç¾â�D¨�¢Õf·F^«V­ZµjÕªU¹`ÕªU«V­Zµjժߠt¼˜%MïgÏÙÔ¼8ÙãcÆûsQ¦—çù÷˜\Œ;NÉ ÿ8áPMÖ¯¥SãS}x¦@¯(…Nö½4€6¹æq÷>É6Ýþ÷—ÖH$ŠPk&5óˆÀ`W¿Óé%ö)q\µ¿¼V''ddŠ|;âÔ�™ù:«ì§,ïüÒ]®N9[¼« )IV‘Ô»="% ð¢ÀTf»•µj¾ÒI?ûe¢ùÝHôËöw·»ì· êÞ~³Ü"°(´ T@+jp!° а•µ#€bã>†Ô™R€m …* ìੀPÀÜ@}|¸žÂŽŸû¹‹+øm\Ö¡t ƒøl'‡¸í¿8Y bÂö¿OPÐF AÕ\ §xøgã8q}(PÜÖ_C…/˜ˆr"Q ;W¤ÏŠÔ>ßÐÚP¹ÁÁ,' énÓö3j}c4æ �\0ê±ošTÏË|¿ÇÒÙiÞb7ò‰èˆc¡°ûï“Sqs„“�%‚“Л0åùû¶L#V&÷ÅÕ6þr‚玘>ÜMto.÷®ûþ1¾ÏJôÔ_×­¹*[`çy»nè B@“Å}vL8ÝHgÇ“qÔi§±í™0A7÷b`r”™bZü^Êîúa7¥K¯}•Óº@)P&Gadr�¢/N,ú«Õöoð²ÆsÁß's©~…©ê‰¤ß£-K°°ˆSÖüDÚóu(b5Øcxôn­¹À�Ö‹;Ú¶þl²oªÀVJ¦ûSIZ‡òPUHk¨­á8ßmÛí8p<í8[Q4ÐÍò¿ôõyßwSö; aß7pÙú3BÝ ¶RzDÀûû;ˆ€Ú¤¯Ùµøøù�}³—ýñ°g�m›ú'܆ú³ÉV@-TÖ¶Ý#ˆ¯¾NëÆüœpþÓ‹çÛC�‚ò(#�±L6AÙ,faÕªU«V­ZµjÕ¨õt´jÕªU«V­ZµjÕoP·¢Òô;:ëÎ" þ´Ÿ ÌH ù ºR¸íýuRŸªÎ�øÕ‹ý®ú4[ù‚¡0+Ìàl§¯âª1tÕXW„ë]q†dNªDõ<á®ü1À<¿ˆöóã”mxQ¸HRMÒˆ:¾³þ§ÜÀSj«a~4åGgµhÿã¸êS¿Fa vŽó`Ê CºL‘A|Å»÷Ž&�-Ñ»½v€tÉ¥@`ŠÅxIOß”í9×ù‹mþUé¾|?Bn¡o™ò~òv>òktGŸ)µCB.Ü ·â‹Žo€6û–P†4€É~nç.SŠ&%=*Ъ}-mnƒª9 ô‹ž€ü ü� vð´Ývð?ÔýýŠ�H>D@ª9¨B©€4· €Vh³¶ªÖNXB#s@”‰¤7 §8qBhÐx@°ýäó•.ÃÉBCÍp”HQó0ÐAèöì7À·Ê8­m!p^ é~)§J�àô�áªy-?E Ùß“Îõ:&mßç{hN§ögnP¬I×è�¼¯ÔÞSŒvòäßû¤+Œ5­]c ›0O©?úÂ64ÿ·�ØÁõ±¾ÛÔ£i(1dº²”Ï\§5>4 ßù_Ý×OEó… rJš–Àpß�ÛÕçϨà6¢ŸhŒ‘ y"È&3‰+@qÿûÌ«õû{kúËø÷ÇÚš‘ÖˆÁL±~båJ´hbk ùš‰%Dþ\ÀP…�ôÏÇñD­‡“74'w�±g×pèªxSÿ›«€Š@<¢ ÖŠZ”mëÏHÛ¾ØDÌÚÛ ¶}C)ö,U¶û¶õ>­­b{n=ª <ÞÞÐZEõ(ƒZ~þüÙã J12s¬QöÜ1ˆkãkQ46+…±oFHàp9ðóËÞÙ�ý{·ýï® qÍÊÔc¥²üÙˆKAaí„*Z]«V­ZµjÕªU¹`ÕªU«V­ZµjժߠÀÆ®ž;íœhÝ=–ýó³ÿ©4¿æ ~GÉ\ÅESWüÎBïÑöPnAxV—SÔGñÑ×®ª·_Û63ô2Îg(ÖMš‘ DLQ� ™�¿˜íøgV^ª¦Ï£‘f#-2²ƒ½ ¾«‘ÁÝ3³=[¸ŸÒP�Ûi;øßÁ,J`�÷A¨ðtäVçéÐP�kjï�¨—øO³µ¿v쫪u€Úóç33í缇)BOöÓ¿Cßµ‚~5{f#íL&ˆÛÒÛï ;ñ¢ƒÊÍpîÍ þ>X;ž8”î–KŽy[­ãx��¤�÷ù§‘{ŸÛÜ â ½„jß[! ·âÏ›Ä@&2bÁ·wÂC(E®Öo£�îx`,6ò�ÃÅœàÖ˺¹KÁ�ö‰"ßW1Kö³ <*g Î]2�²~k|&;ülNrr\O_$U.®®(ä¹õÝ¥äní¼™KDóÚƒËz”6WÐtv(ÐWcö~Í>› ÐyNCgOú˜–Ýö#b çÒŸ@a‚X‡"ÿÔ¥Ó½æÎ�:#¦9¢[)Ö8�œXòn(®;]>nMBNÑ'F¬±¿³0˜ î× º[È~ex?9=„"¿Á.àÿpÖPß`âœdHŽ£I ½Ò ë~dƒAø„&Y5­®ñ6ß9ã9_Bï–ß_Ö ‚ü×— ñ)”5ÙÔcv‘@Ü#ÇrVõÙ"žÂàùüÄóù„´ Ú¥•îR¤* *Óó3ûsš3èmý¬Óº�ŸbÁñYÀ\ÑÚA)ìÇ%w (ØöÝÆ¹(ê¶9 ÿÀÛ[C)ÅSTžŸŸø|>ÑZÃçç§E¼½ãííÍŸÕ(•2ª Òf&TZÌÀ޲?oE«2?ÀùäþlP±PăДA¶�6“ˆÁEýž½�¹@xV­ZµjÕªU«r-ÀªU«V­ZµjÕªU¿A1‘ÛåK9‹xÂ&† þ\ øê™Ó˜ìÏÂÀa>­'¥8 ˆ@1KE»QÀœ7Ma OÚ_°ÇÞâeÿd‹D`pC*–Ýn`]€û½¿xn‘†ÖŒÐA¢2Tó�„@ˆª*X-[_'ð=+^•¹«h/åÝ!ªÝ^Îýèû w‚»Ê9ÞS¶Òÿ)l½6í47£;ïÁG�•·™ý€Œí\�+L.z�}ùÁ9~úW~ëÿ àÈ [„Û‰Ô³ê‡sw‹lÄá«;¡Žb ZÊ9wà_(2(ÄÄï,Œ$Ûÿ,9oû“M(ùsî1³3O¢a Íî kO]]Á ÉûÕA@Úh…´8œ€¥BE†¢›7#(Ȫ‡µ·ù96�LZêGï×6”ûçËl}ÑÜý9òãAê9îƒ\t–œë™@·ÚþXam ¸úw¶ÿ¿: LS(pY½ ßÐ×ãŗd¾¨êižÃ:™ßSw{é î[ x¸’hœ)R ãÈóœÑë$ÞÌzš”챯A8Êàÿ ô>®:ÉêÂ̈~›lÁ,ˆ&i=öuœˆ½‡î²í/¡w v_£'ÂÅ;ææK¶™oîÑßJ÷ËšŽ;¼Þq:Z€þÝ ¢h&Ôdü$¬¿þÿk,¯–£“úÎÊû°­¶>Þ:IPµ“ƒZ)b*ùãùÄQŸfõ¯ŒcÛP�ŠçÑð¨=ÐZ�ˆ\Ì`Û6·ëßûµí$·²? Rþ½ºÊ¾0¡6F=ÚXÆEP› ‰bÓˆ-*`.(ÅìÿEûþ1¡Õ "FÁÏŸhíóOìûïooØö%ˆe·±þ1»âÞÉ #€Qv‹à˜CÜ€'F ‚ª·�A\ŒHП¡¨“º˜"B¨`Aµu׃&ÍŸ§àÏt¼ågß'´eÕªU«V­Zµêÿyµ«V­ZµjÕªU«Výî¼ùËÕ„~U'§ëüç­OvÑH/jïLþõ´Ãc$`¢;ÓàDN?Áþ:¬ïÖAw¥c¨ôÆù:¨:¿ôÍ*yËu»¿`vŒ‰x>@‚æ¹ö#‡Z,J À� 6¨ºbóµÓBWÃK¨ig{jÕ9||2›Zt�#ÔUsösëšÔ»”¬®/–¾ Ó( ÄÑ>Ì×&9FŒ!tYn¤þm5è'ðÝ�n~&~Ä�Œæ £°†KŒs�LpÄP»�äÒÄþuÝxØÝÇÄâ$y&„ýg™ Àm(]ͯ#ÿXšW]ͯbà?çëýknÀº6ÕÓÜ ûÿî�crÄ�´@; z˜º QS_*³ƒ…Õö%Õ¶kšÚç!èƒÜÑ ù ð?œd}…ö7ä'ãÅ<Ð å4Ës¤(”á@J³óÑ Lmk§¾\`;ìïî“ÇÅI€’²>ÈC|M¾…e ãê.Ã0_n¤ñÉmÅo ƒ»E/ÉÒÏ®1æ®$€ûEoìñó 7‘€ôUÒ¿òsdJì‘“[À¸» ƒ‰X§fCŠg™ÜäÔ?ç{×Ùjb¬µ™Ò£WÒñº%ꃋϊ_¿s{ÇŸ"ü¾89Ö`v9�¼þÁ‰‚þýˆz¹_«¿µß®ñúï/å¿8èæö÷aÉOÄ®’Ï÷&#†Óލ ‰ýQq¢ vöšj­8žÕ-ÿ¢;¶²áóó‰ÏÏ·Ý~þüÀççµÖþ¬RJÁ¾ïØ÷¶}ë÷G‹(ضâK£²:>¢™ØmðmæÒÐÈžoZm8ŽŠççÏÇáà|ñã0¸�à±?:¢m;ðùñ¨Ç�Ÿ¶òÞÞÞ±m[ïCU#T«`Û¸“€˜ßêýon È&`->¦uН„TíwXºå?±Ý Ù£DÇQ�¼¡ ÞØŸïêöÆ”/²jÕªU«V­ZµjV­ZµjÕªU«V­ú-Ü·‚mÛALtÇ~±Zþê½gÊ�¾|4IùEskúnCœ‰±Ãx¡Ý_ú½"€NJÆœ3?çÂŽìô¡æSä$ƒP»õƒ0`ÊÝL@·Ë·—Ãb*|·Ôͱ aóKnŸÏLP!·V†E¹d¢‚yïŸìªS¾¼b"mÕË…è † ôPìfÛ[ é¤VF¶ç¿0PºQ�¾hó•€K_SB¹î5³+¤ëî‡ëß5žþ›edL[w/å!³  ¯Pÿ¾–¾ E°ª‚Š€_›ñÚýø ë $GRhk@Ù1”øcÌŒpÅ|Ù¬=¢æЉ~½º¢ßAy´A&HîŽV�_¸u3ˆGÔ…V‹ hÉÖ_Œh ¢àÆÖ€âÙÓñû|Åš˜�´V��ÔhÝ…Àгw�'3×ÁÁúˆŒ.…Ý%!Ï©15ò@‡ž²ƒ¥lù“ñH�œÆÐuM9õ9°úìTBëܯ¼ t,É _oÛ zrðˆN¸±²§9áfÎéÍÙÒk‹ù›­^Ñ€2ˆN'›ÿyÁ@'stg›tA/N ¤óÞ‰º  §�t˜$ÂϷľéèÆPÊc8}Ü1­‚uqKÉĸ붚£N:Ÿ¸ÎîšÇ‰~gå$'ºÉpè9ò}]_ì#ç;ü®ÿzðàÂx{{ëjsk÷ˆø ¢aü>ˆ™ Ò ÍÀqE«Íöò졶4°ï>>âŸ?w# ªâ¯Ÿ?ñÏÿüO|~|B¤u ¿”‚²™:¾¶Ö�xfÆV앬H¨ßí¹¢µ†zTåHcY; ¬ü[³qÂü‰Rþ²gE'ˆ4_‹/Cìk¢µ)Tü¢ ÇÓÚÿøçâñx8yb÷{ƒ ¾-÷ö�çòX€›ÇP=ýñA¢"æ‰$Axk“ëÁ¶••Q Òõ¨¨õ@“>RjkØ·jÏŒÿÆÖªU«V­ZµjÕoýquÁªU«V­ZµjÕªU¿Áƒûþ@Ù· üèå‘+ $ þ¡æÖËJŠì¨”PMIö÷Ýf˜f;ç®DÔÑ&`ùý3:` é@¥BQ8äQ4¶1n�ìÇ'÷jÏêÆ°Ý X—t’ÎöÙ³÷@R×S>²÷MïÈ›)’²-}6zš’ªƒ0¡ªÝ‰`²ññ÷dÙ�l…ANXR^ùß©)®¹Ç_©ù“5¹*9€®çÄ$9ö¯�¡;×ñÜÖÿÂ7ûf¯­ 0Öò“»*˜=qôoRño°“VÀP—øÛ¾MAÏýwœúŽL%1€�Â_ÌÆŸÎùz²ê—ÈgO³Žˆu>Úøì´»Ó¾Q|Ŷ÷9oŒ•f 4Wù»R_ ¨ J‡�E–þÝé?¹ tWís§©­Mã¯%(-rlòzJ¸6±w[ž:`œ‡UŠ ¡1g…ØæûÈ1û5#“"Ÿý´–¾ã·sh´mزßo£:ÑWb—¹«d�úá2¡~1íìg'‚åžLqa? óà9îýž…NBN<£ˆhQ��Û2®™ ßhvvP¼vÝ÷Q ÉÀ¹Žñõj›ÜMÇ™?%K�v䨚æq¨¿¾ |¡˜ÖéÞ{ÍèùƒxNøW�^.3ßÛ Ø{"À eÇ£ÛÇOSƒØ§þÇìô |ïàm}Û ¦Šã¨øüøÄVþÂñq@Uñññ?â¨DÀN»ŸwÅ<Ò8.¥ µ†¢eú]«OÎ?pQÀÚNG­ €'�ž%�ÌdŸ;avKÛ‡&¾ù£†Åüüùoo�ˆñx¨©ÿ{›Ôì¸õmˆç¼"[ 2¨µóxV4ìã9)G�/oD´m7E?,®¡5‹9±kÑjC#é�ƒ«»­+¬ZµjÕªU«VMïW¬ZµjÕªU«V­Zõ~ío�F¤n•:”‚“|uö-ÎyÊ|l0€X.¶þ:eQ_wN f†C€ˆ8 :lwC¡ÊL±Ýì–ÆDÅì×™; cà²tü®8NZâ‹Ü<Ìß^C ̢ܰPž Ñ?H9ÂLF8ÀÙš:~2^ا³ìŠrbªóȰ 0ºÌðWñuP ܤ� Çø7·c(ƒLÃ:Z§>ºnzErp©�„ rÓñ_4âjq}úØ·¬ÿN5hSІ>²%:3�Šõ5ýoP '* *„’€$@>¾Î×ÛÆ*û<i` ;~RlÛŽ ‰ÍnMÀz—&; †j5[}­þóêcÜ€|‚à’Ç¡°8ò×jKû¾ƒÔ�H4ì“O ( ÍíjÆÌ.I`­[]äàvì±+IÊÿlg¤¶6Äõ™ABz1¢òhƒp¸iÌîyͧ@8ˆþ^ìÈ!¡þïd›ôhÓ‰n}l¹½~3@mu"TÂãˆj=ðó¯Ÿ þ@k ÇñÄççªjª.÷kPÂÙ�„8â�ÔÇøS»Á£>pl;˜Kþqw#ÿ£É¸¥Ö¶mïíÌŠýÖ‡êÚŸ¹Æï>?+~þü fsØ÷­;0'š_Õè/ÌŒ²sðù×ZE­ G­¶ÝäÂ4”ýÙI ”‚m/Ø·[Ù­ Þ^�žËŒ¤æ×©UwEX €U«V­ZµjÕª\‹°jÕªU«V­ZµjÕoPûû;žÇq²e—þÖ7^NS¶8ÎàÆÉ yD)SÊHÆÈ¨—n¿¶‹>¡,É_ÝÆœˆ’¢> ìÈß5»{fv¢£t…½eø†2[]ñ™3¥YÄΑ Jd€w%w•°e�§~é@=À¢–nóo/¦5)Û(¹pï‡ÈÎjcMÖϪÚíùÍW jÚAÿƒ`0ð‹L�;PIÏý"ò ³®š¬ÔG9ø2 E¦‹¬ö?Û¢;µDa%�פ=#›À¯Á�Éû¿¾´[Ô{êp3ż‚ M¡… `là>í4ZoœÊa9ê’qNà¿»46vËù¸ŽäãÍüŽd6Ày(þd$BAÿõð>‡«ô “Z¤MgL�Šï{ëíR¨«òÛ|Qh8ú€À¥\@¥øD³�Rah?‡´QsBP2ÛÿÖ\¦› »[B elß'¿µ©wòÕ`šÇýXΤÕ+Ð)1§9€NczîÎïÔ8þÙŽ @·jK€;°/€@ÀA€¢ë�f0üÆ®žf*C7I8·)“·²"ÿ«íÒ1(¯Í�„¢éž“?;@ÉkvX™ï5Ù-%­2Ã'úD]–÷È.ý/Ì â¼hj'I'‘"�×U'>ifZxǶ™DAií�=Ò¿’k~“¡Bä† €¦>MÌ:*ò3ÁÉXã~Fœ°¢_ÇÄxÑ¿‘ñD!¿×7�²X#t+û˜3}HRò@æÛDì3ƒ »µ¿�áO|š"¾6<ŸO´ZíÌ÷ûþë×­fÏo«­º:ßÖuª¥¨Ç�m`Û¶®È×0„ñs¬õ>*öܰï-=»øò)‚Z+Žç'j}BÔl÷ ‹ Bk>??À\ Ú úŽ­l>M…ߎ†ZŸhîš@ pa”mGÙJ'Ÿšr¿™e¿ú£ˆG/¨ÊX×Éö³ï;ömǾ¿aßÍÍÀ"{Å#˜ivwh‚Öš;"¬ZµjÕªU«V­ŠZ€U«V­ZµjÕªU«~ƒ¢­@ŽÏ… ä¼ø,6Ññ¾žéu~ïÈtE€sN½ß4Û `²wï˜Î9vζm ÀÄã4”誳Ú1Ôñæ³î¤‚N€€=þ¼YÞ/ ðß„ÖÃSC=ê'g/®ÙÁ1宄«ÿâ\™¥ð%G<@�ž3í}&H6ÿpd•ŒŠxȹ©ÿ;x§'p+‘z&6� ìœÍÜmÕqá޾߉NÈqùz��;@ÖÁ3àµtjçIM �­µñBÓ:íê_µ�þV5dˆ ”«J<Ôæ[A¨Þ D&FŠ X®=:øoÀˆÙï  Î=@T‡…ì‡ÐSDGM�± u{ñyA\ùßÁCMç—”öþÖv÷¿Wbë“p!`�*à¢ã<¹…A¼ù~¢ÃÈ>?�ž¢”rœA�eŸ×êä ¤˜M¹ÝöÝA/Ÿ+tÉ]ÏÄ X·–îNZpZspB*éûšúÞ'opÚî¢I©=ƒðÖWì„a€¢Ý_ûëÿ¢�ãÞ¡¢¸Çòg2QO‰éà8݆ò�bt¸c÷ƒ‰ÔUÚ—æiÞ,}=\WètOÔ‰‘àñ/:¢o†òÿ…cJ^OD‰H?�÷§Ìˆ”0"PNkÚõN=Š4sîYÂwÜ'r‹§˜€é†¬Ó·vg–|«dÍİ×uánýëø÷c´ û\Ñ¡�—P�SŒp˜`ˆNŽ?f/„#I•­`Û Ê¾¹¨ÕTîõ8ð<ž¶ÌžÚ×_t:^E‚°ÐI„ÌhM°7�® ›À¾Ø÷ÞÞìwÛcCa‹Q ÝH #t4whMœpP×?V­ZµjÕªU«R-ÀªU«V­ZµjÕªU¿A5ϰU§;èâÇC¼í/éO@]}Œg‹{Q,9o>û’‘òNYËì(‡° T“p(y�€¤|ô—âñB>[ãÓżªA �28@fÓm,ß[¤ ju¨X@prL•f`¢LW¨è´«ngudÏŠvbA¶´E²ù… ¸0´�x€3—�Ó»[BÎ�§;2‚8>:ÛGû�÷©3ð“IãŠ�ëšó�ÿvÝlò/íæl‚ðo•«ºãlÙïBŠRìú³(”7@ ˆƒ³!ÃÆXЖæJ÷dõ/Ð1,ô©¡ƒàäÖËHêÿ˜(œAñëØÇ6  ÜltÈ1Ô÷êVùñÙ„¡“¦}· ¡ÉW?wéøâ œuŒƒÿlàožÃÁiðfw»/4ÜÜC‚€á±#ÝEAàd�ø]|®õ¹Ö´cûÆ'ÐÉížf}ú5÷<ì º•uäÀ_ŒòR÷ÕÐ:9­¼úÌeDвLÿsÀÑž‚ĘŒ¶�Ì0:iØïC/–øÓ'É`ô¯Ný˜Õ«qÜPÉ™R�ˆÒ5Ô Ãê/êh©id¸çöµøpþ-E¶ž·¹ûôp¸@M—áöeék0뿤³Ò–:ŽæyôèÙëPSY¶&(eL�®ö×äÍï*vSiºº?Έ¡`BÅ $›ÿÀÝÉÃÆ;˜�F %+  ÒÐóÃu·IhŒ‘>íŸûÍ¢‰åRmÛVA%~ìkK µ}3€÷)»*7¡õ üoO �$vBBÌO¦eÀêq¡`·>è×ÂÁ}�×ÝÀÜ6Òü‘Av!¹ñübôñd NƒŽ*æè®SÔGº:x5•î~B§ñ¯yyîóßÉ?ñè›óEÔÆ„w£öeðžôÓ»!-¾úÅÜÓä(£¯¬ß³ú>ó8ˆ&[þ¾N=nåVÕŸûàü’ҋܽ8œ×>MÇÓÔùzd@[ÃÆ†QlŠ3E6È÷Ÿ¼~Ó䬀nûÞÖ ôß\`®wÞéþ£z{kN÷$­;‚ ùçµ³8�IM¾¹OõÖÿŸ¾±äk' |1pKdô=ŸŸf�õA<£D(Ìò¡ rR€Ñ´BýwqE)Ø€�wlÛŽý±cÛÜ&˜šž�4o­J)x{øÿöö†ÇÛ£ƒöwçlÏ>É€ûî ;¨+ßm;¶½øóû²žú?,ý}›p ÈQ?ñv >ú:Z­hÒFBzž)…€mëKGsÒBöýa�@·å/í¸¸…]ÿQÔÚFÛ ã±=ðx<ðx{ÇûûÞÞÞñxà±mý™ÈÖMÁ³îv ¯(4«V­ZµjÕªUÿmkV­ZµjÕªU«V­ú êxXë¤ÿ*�7 ä€ü ?™D€”ÿ¤÷œ¬vO‚L˺ï2ßawá g×+:9˜‰ì@2ÇÃŽºˆ)m�B±êY'1hlë6¸ùZ¼D oì©­© �è¼M‚|¾�.6ʸWã‹æ}õêþ¿öµ¾š*¿{͇ݽ(­pU?™RT pélˉ0ÐÚTÌ‚„lß*Iw 0å?:Bkßë Ä€�h�IoYÕ:lðƒ¹ÑŠ»8ðïyÕ.aN½ûô/½MÚ.>~š›ˆ+îý÷8[Š”¹­Ý¢ÞÎ×”ÿOHm¶=1˜7Áê#v€Õ¹~NL”œOi\Étž†ˆŽY­êñ"z'w^Mêè~ÈiÿzyôÝ‘H÷s†æ«šêÕ£<î¦É°½&�®Èd�ã1T¡N|¸]´‘Ôü™�uãpùÌ—³“yƒú¸X$ h€Æ’œKKŒ§{ôO2ˆ-ôbY¡ÛKÔÕÝÀªv�þ<ÕºE<´ÛþSîàÉEÀ•ò4_ "C’ ‚æ` M.4ã^4îôzÁœÜp®ëµ¸Zûnø~{Õ�{­Tt¸öL×Zgg�é~qݧq%¾ô‘ùV��鏯ŸÏ§åÂKK!Ñ»Zc,¨aS/bÑ?@±7Þðx{ÇÛÛûþ0ð�,Ž©µƒæ[‹â€9˜ÀöÇ[@üõ:ÏÏ?Aˆ¯KÙ üOûè¤GÜ;*ôg)"°«û[«Ù`Û6ÛKoO|î8Í-ù-À~_ÈâF6.½Mñ9bÛ×ã±'#_ÔZQÛîñ"Ü+j=PkE96´šÚW ûoï?ðãÇ;ÞßàíÝe+½=±Þ6²{ÝT‡ªìö½šlÃuvàÕmWTâÞ·ƒ‘Ãv~râÖtÎäqÞ“­³¦ññr§¿OcV/Xíÿ¾¹ä*x#¥˜Ê]Z‡Å~錳Ì'¶Æ €2ú¿ÓE„ì'˺r�»hQCáïŠÏ,�ï9÷ãRmþ¾¡¡úh¥CRGDAw@³}|ÿ*Õ‚„Â'û~=]ËÜR{_Zt€ôùhçUnÆAZ»’ƒ‡9)ÀY82Gde5Ïêf#FÐPúç(Ç�tÓ�WÙêÙf_gו—cztÇí~nWc=ox³zc² Pð4nºº>/Ðîfðê~jyÂu²ê+äøKvÍmH÷¤{L¬#rʪ±KÂS>‚ÞÉ9È:ßÓˆ’ûÁXõûÿ“ÅûõƘœØåZý<ÎŽ4šÉsHÖþ¾n»]:è<.²V™N‘§³v0žfíý¸�bXó÷óÓë…»ƒÝÇ=hº¹§¸êã?ÆÙ…œ ÷s!… Mqq¸½Oü›îíâ¹ò­¶æFÔâÏ&(¶X‘&ŠÚ*j«�ÖÐ<@¶ Æccl[Á¶=°í;¶’IxCM_¶b®`·ég@øô¼¤æcÌ’?H)Ä„­˜ÛÀ¾of{ÿx¤çê÷“&mÒ‡ž)ã�8ÀN¶lj |‘ñܲï;Ja••d·ŽâD(¥˜ê>[û—R°o¤©»ç�;˜ÛAì³Õ†Z�qŽ>¦ŒlðÀQ+Žç�ãxŽXw0åÿÞÞxÛßÀÏýéÏ„…Øþ$cŽN«V­ZµjÕªU«F-ÀªU«V­ZµjÕªU¿C¡l›å¯&àÚ~‡ìýNésîÐû\yº•Å %JÜ�ÊÛMÁ_=-%�é4ðú¥•©oâ{›;Í;(P}t@Ÿ9rÖO#‘iß÷‹¼°Ù|- .–Qͯ°j:}“Àÿiy¬ç¬õ[Ð{&¯œ‡÷»qC¨JcÎfïó&;,Œõa|ëiÝîÎá~@ƒ(ñ¹W·¸GŽ ¸¿ï 2.k_?�œ�×6ôœõ �Ìo'8uØ^m¨Î ³úùÓÙ "·ï… ]Òš¯çóÉ뺆¯ �šè4Þ£MÒ‰oã~fGÌŽ6ÖöSüN&¦LQ>¯òómYû5$¥AK„0š,'hä?Ü ¼H]Q ÷=çÅ(�öwÝ9Ñ<þ¯§[‡¾zü¡/ó݉ \ØÔîYöPXÝ=ˆÙ€´†ê¶÷UDœ6¨@ãm~A…ƒÚíp`Û”ëÄìÏŒRxz.¨¡’OVüµ5ÔÃð'ldàùcßñþÃð�·7l[q‚êqàhBÍ*[1òAa{Å+" V;°n`yAyãËõU‰Gµðq¢l¥; 8¡…ç1ŽûcïÛF4€m× *ýÙÕÚ×°ÕÚã‚tûÙ÷ ûf± ä1­µDé‘ec ^«V­ZµjÕªU¹`ÕªU«V­Zµjժߠˆûcw�š’(Õ-ÅC}Ÿs…ÏûðÿÏ–þSh3:ÀD˜²eq )D-SW\=Ç �–Þæ¬êWÁ«¿&·ÔuZÑ«$I.8 ‘õÖµ=;—|ßaåëm±6pWīʬÆCr¸îd‚¡¶ ð_Ó5NäŽí®žwr�_€Œ¡ü ½³v'„B[É¿gÐWäÓž�¿ŽG‹E2t@‹`Àr\B\ÿÜ LÚÈŸ¸Qÿ�/ ¢ï‘þøÞ^Õb˜¤¢ZëPþC!(TN ·\à¶ùÉ2A {?r»ÒÄ d‹Ûà+à>ÿ£»óD³¦÷}·ÞfÄqÅNî8!â14Ôþ€�þÒ Ð×4³õ×LÄð ë×ZÆ6âN¹��PäÙè„qn  %âK&ØÄy¹%·'�•òÅR<Û @T\&sMÀzô ÍkQß½ .<‡s¾ÂLµ¸ŒçlÞ}Jê÷!‰GŽD!à… {ê?š‰%ç1}I-ŸŽD­ëxË÷ø¼O$šï_g€ž¦y:-zqP¿§Ñ­£8Ç�þròÄ~Â-HuÊÎùFÜÄ}11Þ‹ðuNšŒñ§ƒhQ&2Ñtc€B!~ß5…~­D Änî`D�±•íDTˆ¨Çpõ™GÅq8êamt°¶m([±(�ǶÇf€Úð<ž�&àVÑ<æ@æŸ-2 nW�ýdza·ôgî¤ÄÖÒj߆¹ŒYQ\ÊÉ(Ã\Øür|Y6òží'׃ )ìç=È>ĕҟµj)¨É%`ß¶î8s¬µ†&µÇ;NTxìæÎ°o)¾cÕªU«V­ZµjUÔ"¬ZµjÕªU«V­Zõ;Á^ðrVöÓ°;¦9«zE¾°d7À@ú‡í%¬ë_Ù#lõ—Ìn�+¦ò2›Ü¬À'±nÖµ­F¾8¡öM±f/�Ñx`�PW w×W-»ê¬,¢+Þì¥}t ¯³r]Õˆ\¤«ç�Aè/ôOÖÜäÖÎ\’6p#sc滑lù+] ª¿²åv@oðþwW…K&öeˆ$¬.rr¯G‹üŠ“s€Oç�t-ßypÍÅ~yîø ÿÿå þ{ÓˆD–Yߤ¡@ õ Õà ì§ïrþr»õºT(«÷^u0‹ÔéŸ×6ƒéá*ø¢`@F@v¨~Üf€¹ƒÅ±�tà€ üçÙÚßП6ö©Í”ýÙàÝ&ÑìØ¹í¡ÆTv ?{�;øëFÚâž‹�{¥Dq¢�Ðòk‚œ„þñ�œ†ƒ Ég0Ûº1 Óâ7RnÌè[fÌã þŒ]¥8Õaq?�ªä¼Ž–>ÈR º?©ÂÝ“Ä1Ö hŸgcMÆ´îÎû*z(¾5u:¦^ך;w€œ³.ùïµãô8‡~AÄog##jÎf  _�‰îâ|•s‡Mñ9�ùAsõu1b‰§¢>üu6‚˜˜Ã꜉±¶�ÛNðÏcUéäÒs�³™iÃ2AƒL¢šz$oqæ„è8º±ÖЩaiÆ·Ü l_ÞôU|çQˆN¦!ŠR ~üøÃÖ '¶êVûn›?bØ€íR°ÇPhŒFP¸ôg„V+ޤZ¯µº‹�è½›e=3w{ÿx¶èqqÿf@ª VWÿF&ŒÀçÑÚ;¤5'¸Ìçi`xíÎ"eFå˜k·ß—fDKIN¥l[»»A­‡E h|ÞÖ8b'ªõ禈{ÒÓÓ§°}~",¥ˆ„»¡Àd÷BÕ2­ýød ‹ihrtׄÖë{&èã ecvleCñ>\µjÕªU«V­Z5jV­ZµjÕªU«V­ú ÊTb4eeÀw¼Q˜×5 õVÇ?e½_á-Û×üý9ìk˜…,¢æ/o³úu€ ¦x³—Óĵ–› ‚º(™:Ð.5 bʳ¬g«kt Q4¬Î¹+Ô†M¶}TDSió8Éâû‹õxƒMé÷³z˜fPµkêu’SjÕ‡áA1þw舨½Oó~ô‹‹¬/ò™§ïnƒ˜ç±4¾_õð÷ ëj¼úøy[ú7ç NãvÔþ0ðCÚH…A¤BµB¥˜[ý ØŒþP1 4…–f%Ú^:_`†Öš�ñ¬n…?FΊ-qíÅ”úŦ¹‹@–B'�Žà¤îƒÛ?ßø¯‰vżêÝ>y¹;p)©3Š#©=HVWŸ´­�Ž Øü÷ê6‚Pëvïù²ót±²Ê>óÃrzÈøÝöŸ‡bž™&ܨèèûÝ¡Ž°Üyœ•ítûiøø¯p…;&PÏæ`�±j¤ˆƒ›ék “B‚9$ÌÑ/ õmó)çÑ_ï5ÑÀÑ…ç¨�Ó¶éòu«}ñ•?G†ÐKkš»e WýúWëÌ”Ћ f°ÈXÙ蔑÷ ýÆØ‰PýÅG·k,}ÑÌîÜ“;áD¨È„ RUŠÖ~Ñwb;½èD%莯ó/^žv?û¿yø—ê¦iÌŒÿëÿú¿HVµ‚¨u¼Eºåü¶p)l²ATPkƒHóX"S¸‡E¿Š ©9 )[)ØÊ†··7üøñ˜UŽOÏ´÷u;€s_Ì:9@DLÕîÏCäàõQŸØ÷ Û¾ƒ CÔ"bŽZñüüÄçó‰ç窌@iC»“·Ä�ÚQ!M|Š«ôCUÿ»T Š’=s‘Ýûlì‘Ý'‰ îÂDäÎ&€¹"ˆïÛÏ¯Öæ÷VXƒ@¬SüGáá´£ýÖÐ*õ¾¯ÕZ«(öÍ F¾({iY€U«V­ZµjÕªS-ÀªU«V­ZµjÕªU¿AI Õü÷^pšrÓ^úÏÂó{¥ä@ë3²0Ér;H¢+ìå³YÌgkju…4&9|RžUù¢.86Ð�ÙÀÓÔ HÈâ Pw`ð�SA&§|í©wì%³Â_0�òÿ_öþåך¦Ë„~kEäÞçùªŠ†Æ¦%ªmK\ z@««±lcSX Ä€Ë&ˆL¸þ&0f‚ĉ!3FÍ %¤FB}¡Û²i÷€jÔ´m.– íúª¾÷9{gÄZ ÖŠˆ™¹Ï9ïWE«žþb½:Ï9gŸ½3###"óÍßí£Ò ¦îêùg>ãÿcýA°’?ÓO´ÛfOžü8ƒûŠtã¶â…ÇFôÝà¤EvÄõ޾pü'N˜Fß�¯-!f†:8‰ä¤³î>©úzùë±X=™€à2àz5rÂË�u1èôKÛþlÞ�Ȉu¿ýÛ¿…Z+Þ¿Ç÷ïßñ=}ïkiUQ�h…@Ál€Ûý†”Í]§Ö4‹«ëKj}¸¥8%ÜßÞðí¿…ßþ­_€)á;¿cîNઃ ÙJˆ¡š@4Àóx�PŠØß$òE[¶Ç¶¥TìûŽÇó‰ýñD-µÏûçÎØöRNHîþ‰,["hrƒ�"¨¥bß Ê¾cß‹G8Ùª&Tí^HuPPÆ:ÃŒ”Ì )%¤ÄÝ�A¤v€êŸO9A5Ûå#¥~RÅœ¤ŠE´sJ6W‹ˆ‘Ê¢µ¯qæ&edbs�âÄëV­ZµjÕªU«B-ÀªU«V­ZµjÕªU?BiÌøFéè©ÅDù®úÕÉØ}Xdcšiþ'¼n|ÍNŸ†Â]åŒ(fuáq{d·ïö3wP¿£ï ~à ³a¨ž)ΞeÞì}uH‡â9ôÅ©ký{°²³EÈǦ Àþ´¢4]Yw7ÑusÌÕADPݦ®fk}C�B�Ló9Ô50úì�™}áØß 3 „Óo“ ÀO¢°ÿЖcG·ã x RNý¨/ßósôÿ[­0´Ü­—!`Ò ü¨d˜=ØlÿÙ�ÁæÀöîØ]³·—Tï®ÐwÄ[ÈŽ$KÿeXû«T ek£ÕrcÓ8hÄ‘jRx³™°í‘¸‘>_ظ7RM‘ðØ Wžö¯ÚÖ�:@ß®Üoñ2�d&@ v‡…ÿvágŸ‹/rݹ±Žy:ÙÌ£åP§«4æÑPyS�'¡—ãi`›4-cý¨éb>uå½öÌy: rãxÈìå¢À�B;éÅdì #‚pX·)„X\ô1°¹“ºpœw4¢&zäD$1ŒóÑÀóH¢�W3ÊÈ''¦HP?|>F"耺%‘¡Kˆ‚Í?�õßx+zà8h�ˆÑàè2]Ç"Y'~Óù˜æ,ôsyÁ°oä¤�v.¡î�éúÛŽ±»¸¼"¼XJÛOÚTó‘Èqq\Ÿ‘Gâ{.RkN·.}Ÿ‡×¿~ûs°9t1�ó†mËfŸŸÙi¦¾Ö¶{ˆ6&RflÛ†|3G–* ~î€]�*»)äK 6Ûvï÷¾½½áÛÛ·û!íÏ~¯ÒݘA°{›ä‹ß¦7›/"ÈÎ'@©*Ä­þ‹ ÈÙ@sAÝ«Ùáï;jñ¸#¼3ö½ ¥ä"'sàR\½Ï(ûŽïïïxÿþÏÇÓìûUý*"÷vH­#ÁÉS9g¤¼a»el9wÒB)ÅAû½WSɱcOÒFº(µš£�ˆÎ`玜LYëŽâmd¦™0 Þ¦°æ­ZµjÕªU«V­²Z€U«V­ZµjÕªU«~„÷Ô®þº‹9û*ØÏ]:,€)è1 ®FómÑ pGü~V¹·g­là)"èBЩYCõM̽mœR`Í)�9…˜ßõ@n€)é vÕ—«·mDX‹øÀ­%¾æúS·`nûw¨ß@îv¼Öê�S4Ëfr«nï/';t›ìÉxVép཭C+�Ô Ô•°ý§Œøp’tdîÆ8RåqŒñ_ù®½°T€Îk£è�~ŸêçŠD¯Ý·O›tê üw0™1±@u·Ø‡ÈæwÚ Ñ2¦nÏvN2k“-šÄ’’ÏlO1ìØlÿ]*€¡U@I‡T“ʰܯ!Òb ž·í€7û+T\ò9¡îI+P Ôg��uª|C�Ü� Øþ7D�ã Ç$Ft�h·îsm^<ÂƘc0-2‡qqbØ``?Ç÷û׿—1ùOÌëÂBç||£.‚/‚³bŠ �ÖM¨~-£:Î;½fÊ4'�)!“g€NÑ$³}?MÑÉà¨?�Â…fØÅ7Ð\ø¯}'Ç0ƒÐ^¿èõ¼ï® m}N%v>ehØCÌÊÜe4 šãˆžuîͽ@z–9‡¼ÍJZ…aØü§”À99‰€„aªm %§Êè#?üÁ;÷°Ñmðž9.®Âë@�*'0·íYÿY$õýµãgb˾U5q·Çˆ+O»µ3ÍÎ ¦˜×€¿jÈ÷v0G Ä �ÜÄ£Ó„Ÿ ±Ô®å�ÆŠFÀRÃ8 cxùkP§ëu£[}âòÿ™òÿ“¢WÕãÈfIU*´š#€�"éÝø”áNt"Ls¥pNs`LŒ®“W�bæ$vR€ªƒÿ�$ð´ï“¯: «þ+ $ît— Õôðx�] Rúg JM±Í£íÖ¸Yúˇõ>Q´@ŠÇtЕ�ƒ@¡Ý!bÞŒžã˜æèö௻u_7ˆOc!šÖG`¿Ã­>÷.%*‚çÁ!ßæw_s‘hÞŒ^Ý/†üÈs¹×¬4ÚÖëáÜLÇp©Û�{d‹žl.4á‘`vÿ§­Ï$=åËë¹y±SšŠŸ1!û,€¨¯�êN q»!מ]2iÉ;ÁLz$C[épýk*ªÍÉDçkëñ¸qæ«t"Eו¶þºsD' ÷F¤Êè¿æÐÏÑüuµÇ9Ë5yàc•ÞŸ¤8Ÿù«wÿ|ðÿ³ë@»F‰~úþÏç£ÎÌ„”ÛÆP%¤”�3ƒÙúSjÁ^vTwûQ”b@t-eÔjä;â„mÛp¿ßñöö†oooÈiƒŠàùþÄûó�ï?ý„ï?}ÇóùD-ÅÔôÌÐÍÈ)e$‚Ý»$v°>¡¤lvökH#Õ*F@è÷OFb0\¼¹¯Tˆrb&0‰_áÅHm¢uPð|îx>¦Ð‡‚‰°å„¼%ÜïoøÅ·o¸Ýî bìûµV|ÿ.x–ßß±ï;@„ív³%:1ò-#!õs&ZQňªmĨɔûû¾cߟCPKOJò–�g–(1Í×ïRe¯ØŸOì9náÿ«V­ZµjÕªUS-ÀªU«V­ZµjÕªU?@Ýno`ÎÄ.J>£\(` ÀÔ+¨cJ“å}ßÌU¾û$c=nÙ”½ˆQÔ-´çmSW7ç�Äà§”‘RJ~1]„™:²YÞ眑·Íè§òèö\lÖdÚPW/wå!Åk'»ºŽ&e¼) ¥[ù¶‡ëÒA—øøïÀ>48D “ºã€ÉEà³ ñá œ ܇½v³èoÐpŽ#"ºCtüߣ+ÀåhœÑQÕë÷Ñé‡Ë__”~é-GUöW>dÇܲÒj`Šuªn@Ì-v”œ`“Kq=+{•lsU¦=2Bhµ4P’›ú¾jõìh#q éÿëÐ'QÌ˼}4‚ž>Þ{º:pOgREµye,—:gÊs@´à�:�Ùò|Ä È^qWÖ†Üâœù 8Ó@t²gçJ=ú8ÇY%|^»¹Ã”½>Ìíé“qx^»JuŠT 1W“E_�ÿÙ>~¾Ðä*UýsÎú‹iÿ3“ô‹ÓÏm÷›’_GÜC³ï¦ƒ-7’@ä|§Ñ ?VŒ–_Oãz¢ê¶ö�,ÑÜ)HcŠÄL�ГÖF½:ŸaZ(0«Úi¸1( W¹r¬P# {§(ƒ!€r'O̦C{C¼Á+pxå‹¡)aüvg™Þ:{Æ(½º4üÿµâñ×Zñ«_ýïïïØŸˆV€€”Y³‘õÜqˆ˜ *(¥BðôSÓ×ZQ1 ŠÇJØýɶeäí†Ûv·¨!Ïe¯xÿŽ?ú£Ÿðýûwì�'DÅTcŠÛšÔóí ÐOœ!Rý^Š;ùJ¤™A´;<4Â"W(±yÇ4¾»£Û=‰E ¸*¿îÝr>ðÜíwb2µ}N¸ÝoøÅ/Þð‹ßþÞîoß¿“E�õÏsâñxØu@·-ã.oÖ3›Mf`·]Ä B#ˆš«À¾?ñ|>°ï{)P$6ÕRÑ 9g'V5²¤€)ù±ìx> r*ØnŸ³`V­ZµjÕªU«~£kV­ZµjÕªU«V­úÊìM " ‹ðz((¾úÙCþã Ç,øÙÆúJ´Ú¡é`™¯„ó¬†í©ý�5§‘]«]ÙWíÛÁa ÛwN_0ìÍ!ÀòÙaWxKÈ„æAT É�ÚÛÜÌ¡Úm„›¥0xÎAV�vÊ!Ã脉jønuþ–~ ^8¢e#çzŠkh‚¸yj÷ÞØÑwç�SFó‹|ö õ?^¼�.þÇÅ5^ôUÉÀ'ýYŸq`˜=ÊÀ¥íªb–ýI ðRP€ hŒ%ªÃ)?(v!Q*¯ð�bg]ØØ”‰0Àþ~ÿ|}Båam©:þ&ê~5Ð=T¨ÍR?º @X,ÆÀ[1“¿�aT!î@"ä׎+8;H³þ¯@­ÖŸÊ@;^º„ó(ùVtpgŒ·@^øèôÃb=Æx»2¿€’q™Ñ€åi‹¯ÐÚÉ4mímñÇ9ÚuÚúµqÝÞjµtíD!Ú@Ãò}=+"q ›,²Q?CD/§”¶ãP±aáêùè ÐÉeLÓÚ5ÜLáèàp[ÏŒ�HOê„5Ûp=¬I=$ถéÙßF_ŒŠúSSîcX�%>îd¬“Í~Ø—/=Ño§­Ï}Ý&õ¨—‹5÷âÄR#vFì©OÃucr±ÉÍ€íú@z¦ý\®×YhÌŠÖëÅP¥â�~õ‡({Ás¢Š€H‰mMTx^}2òž_‹¥ì ´VQTwPˆØêbêý„Ĺ_óEÏçú0«þŸ~úŽïßÂãñD)»] ˆ}M]Ôæ†r²{žæ �œÄ˜ì~HUP‹µ³èˆh±ûî÷Zí>AÄÈcÃQ©m¿‘�Rk¿ðË��’¹#l÷ oß¾áþö†ooßðöf¶þR ~Ê©»D4‚„µ—Pj…EêRN}<ï)õõSD!T�Dé.Jê$KÿjD˶†¤”�oÛmCN Õ ZG¼SÝ+öçŽ=?-î`áÿ«V­ZµjÕªUS-ÀªU«V­ZµjÕªU?@IUˆ¨‡tÇ"è8#<7§hÅŒY%~ð––ð°½›âÓ ‘pÁ¶¾©{VsW\Ûìö°˜Ü¼[+ûöìuÅ¿:`dJûø¼‡x lÀ6»U4Êõëœ_-Âj³á£7òŒ ¤pDÓšJWãùè¸þÉxnÊr –ׂ∠üÇt˜#IB|í È+"š÷ñwÏèn»²s=¦ ÒØåu#¨ß; à�ÇUwa�»¢qí#³9W²AÐHSÝ?¬µª¯ÎM *!VË0v¦Ö̸tÇí§ÎZ¡×¶üíZwrÉ îÃ%@ãȸÞh¬µzA,8ö¿ïŸT à=/äGRp" 诳JÓ‘Ðò'p¤‚ïß¿“4�ØcMxo×ZÄ™QEáš-b_ê&ò÷3'wh!H<ž;ö}‡¨àù0EüþÜ=Ç^{ÌÀ©ü@¤N÷fýOHÞ^UWù‹‚Y\Œ9epG�”RBÊ ‰i"ÔZQJuƒíOD̾Û°m¶œ‘7ûj`~ÊÙã xŒ*ñû�Ú\’‰Í�‰]ÁŸË†ôÄ ó¡‘˜ÍJ’Èîð”p»Ýp¿ßík»Yœ‚(*3 U‹Ey*J­ÈUP‰°jÕªU«V­ZµjÔ"¬ZµjÕªU«V­ZõÔ^ 8=I¡|þk°ñïêËéÏsfuÈŒ¶ïÁÈ[5ØàøÐÙ7qtôÖú,ŠEÅÀ† à7‹X€}š¢¶i\_Fûû«Du"tÓ}“èt«n«ÞòŠÕˆ³Rß¿3MÇ…@D ƒËµÎë*7ñâ3`×¶.3€š/õ~‹™ÞG«òé»^i|)¨:@Ó%÷]¤Ç±O"ËW°Î5Šùiîó¸Ý¡n:ªÀÿ]*BS…ºbÝÛE¨ˆ5Xm;øï–öªâ¶Ê‡ã1ž¤ÐEµã ê÷qìÒöß|ÊpFŒ¿³BQ�²`OîL@ ³Tn*~Ñv0Õ½¶“ÚHÄ­öÕ¬ú»3€ºsF¯Jw¨P‹Ùè¶þŸëã]æ“ZH¦„e‘Á[h«˜Äv…vÀß# M@D‰UÌ�£ÊÈ.o&BÃp�N‹ÔÅ:òjœ8i Ó<Ƥ@oqJ4ßÓNÂ,½ ‹�ïkba9¸tÐÇ�ÖÉK_/�ZâTÀµ¯·n©?Öcêø½¨ @ß•„¨‰WT%ŸïDG¢uÙþH0Ðkr†Š÷o=ª ÜfšrÞç™ͺ �ÍÜ„•Wn(¶~Û�=Ðe›‚ß^RL×eŠ�C3x=.þ4xoI$™¯v~µð~‚ê�H4Åë%�^ ýøêñåRQÚŸ;TA¢®HGpBsþA°ãgÀïG ªF\fW£SW¢�è³Ò×§Uô—äa€Á”:hnÄ�êÅ^v<÷'ÊnVøÍQˆ™‘`?o9b¡»KïÇØÀvÍP�Å4@²¿5Ì^Õâcªö}CÊÒóµë=V‰“ÇŒ"'A$äœ�³öœØ�k´0SJØn7p²�îÛŽÇ–‘ŒÊwÐÚ�Róp¾á”Œ\äO÷·;Þ¾}ÃÛýŽ-o N¨ÕîõH ÃAýZ*"à«ÛãU«V­ZµjÕªßàZ€U«V­ZµjÕªU«~€z<ÞM¨©’j­ A 6;„Ÿ'@!d3;xÙ2íã;š�ÔbÏ??ª9'‘ù c@E Ä ÈxXÝà2¥ZÇ�Ô�P"�[·‡è"2@z—Ã6›^© ’`´ïLÉ2rHÏLaS¸#¨ó¬ïGÐb�zD›L ´v›ç´¡ ©'kTTu8k;ˆØp-€@à” Ò¬ÄuŽ@peê°¯ÖÁ‹vþzÈÏ>ø4kèKuöÀL° ÑŸ+`¸Ökt(.-ÿÔÇS6À¿нÑnsoÈv‹+š0ÝýFúpk}²9PE‘8txæ*vñ¼šb¿)ìµyu‹ðÏPt „¬ñM ®¾/þEmþ»²^›â^ú¡Úr¢Û˜‘þÞ¶]-%üîÀh‚ÿî­ŒíK0üo¶ÝÏÁ¾^ ês¼}n ¡�*Ü“ ŒTƒ¦TV5èjn�øCDZ<~¦OÇGlŽNã§•/f¿û"Æä}sºë¼±Y‘íÄ�IO= d,š3Q'¬±mgð¶à?ƒÓëPðk@­»í½g‚FÖ:‚ÿtè&sVAá”Ì. s$€Àžéãdš�±ð÷G¾R'/œ#ˆâZG`TÑ)ÕÐ)fâ°¢Œñz$ð:Þ€�˜"t.Îê9ºe\ûK‚q1gW‹‹U’>PQëÇËëËÏcj:yàÂâ_¯.Ÿ•‚ªTÈœ’”¦X¢‰x§:ÔòÙÀsE)¶ö‰ŒåŽ]MÏý^K[d YQNɯë�ºw;"6›ûZ!µ¢ÖêÔZ»cÀ–o]YßÈ[JЬ¨•†+A;®F`vëÿ¬;á"rEª §lïeB©OΙûy©ÞÆRŠßÏ)8%ämCÎ7l·;¶RQ°ƒ8õXunÀm¿!ç œ2¸ÖÞì} $kwN�*=JjË7Üßnþo7pNý|0 „Ðß"¤ú}“(V­ZµjÕªU«V�Z€U«V­ZµjÕªU«~€zÿþ05™*‹ÔDà:@€ãSøI(Õë4å@Á€nóÛ¬�™.T¤læç0wu;o‚€„†ŸÐ•ôà ÝÀðPO]i§=_Ú�$UTÏn ­|I)Adäßö® �í*8A©âöéM…ï¶üÄþ`™L . ±¢îRÐ Ý #Õžå®*㵦×ãÀ›J­õ{ëJGG�@¶ë‹ YTØÏŠúñÙf×kÀsSí…!€vÊǦŠN"©ë‡æóßõ$ƒý øÿº¹ôéð镨•N¥V�À-òÅÅ÷°sßÕÐ"ì5ð_´¹ßˆ ÕÌxw{~�J�à –Ýº¿yµñ,O TŸ®®’x@16Àíûk5åª@Wþ[ˆj³ùo“>…~n·Ånª ê:³¡ãõFh9Í~�c›ÒÀoq€^:N-.a–3ã ÅÅð=!É‘4àä�N^’Ž»��Ò +þ«‘f"Ûv�Íâ54©s„…R÷¶À!ö"~Mùè„8;FWâè>¢zi.~ éçUê+"�×!˜™QŒHdй³'n}y ÛëOQ5þN984òÀèÑÓßcšCÔãƒ(˜ù_ƒÝ³ŽÿLÐ`¢Þqé á8V‰^,L¯×: :ýz­_ôИéüΣZõzdP‹¾¡ðžÏšÖ®GD—±3xqˆ1¢á#ŸõŸÉ S(¤ ó¸# óF¡ !SágkUbƶ™ºÜ¦}ÁäÄC_Î8!³ÙágÿJ‰Íê>%¿&(Ò³€9aß¹+Õ»s€÷y©°ï;žÏ'öýéd@s¥!"äš¡Y1g܈°îà65ÀŸÙÛäŠþÄÝòîLíã~_�–ÐìF¾E)ûã‰GÎQ¤œ *H‰pÛÌ–ߟ¨µ†(ß�’=fÞ¶¶mCε”)N�™‘ˆ� ˆný>.sBNÛmÃv¿aK  ”z^ih5_‘gV­ZµjÕªU«~ÓkV­ZµjÕªU«V­úª”©uòö¿TššM&}þÑnÿð!�ì"€ Ñþ Úr  |0x¶'nj;G•Í2Ýs_™M›¬n/í@‹Ð�fO‚>kµXràd¥/µº•l§Ü³¬mgÆWDºÊmB(’[BKS+ê„Y6«qé áÀD(¯ž½Þ-²á™ËÚF¦s³Ã¥¢�¨Ö“Ž´ƒ+Ñ €Žç€w=�Ah¼‡�D-& Ú3ЈèÙÑ¡=Gkç<¤1£úuÒõ#±$È‹:iudtß8^ªÐZ!ú„j�VqE¾Ù“ƒ1Ö—µˆAH�dz`I 6 €TZÄ´€´@PÀ$nÛïyõ²»¡x¤‡ *úˆ Ôž3`ÛrÇ sÜwð_kwÑÐÀ ð³T g‚Þ1ÜÉ>` B~…ÀÁÿ~®"ñÄþ&Õ·×ìâ™p—�ŠdùxdštÅ|šŽn×ÀéjmÃUšFçcÐ+žIÌ\WÂÏE$£kF—58ਲó¼ÙÒÓ‘¼E¡áa~æÂ4ú‹ÉpaPàߘ+t}ˆ�„t"¼pThq)±':ð¬}ý˜¢ÚõE1¼èÜ�á´ *ÛÇ�zØ^üôÜ3ÖÛ+u}ìjboN°¶^­{4½x=ÌCoŠkâl³ÿÙˆ{1ð#¬E# ­:>ž�­/€¾âÊãà M›ú畯CdÖÐçûÀ ¦æˆÀ’9ÁÖ2êJ}fvU{Fuµ¿¨BJ…°]ƒ3RθÝì}Û–±mìÀ¶)ØUû­àý‘ðxgìûUíVüD© ÕŠZ*žÏžÏ'ʾ[LDÙ]�¤¯¦âwg"N!fÀ”þ)y»n¶¼yÔ�v;ü*ÝAh *ÛfÍàTÀ‰Q«‘¤àAHœœ¡Øjî}µmÞÞ¾aßws:jK0GG ò� y۱匜3JnÛñf'GP'k2ûqå„-Ûw¦Ñ "¹š-:!Ѳþ_µjÕªU«V­ºªEXµjÕªU«V­Zµê)ä/ü–£"<ä¬3†Û ÆW¡­þÛt±¹àaÉ:a¶-Y·$0)XJìÏøe²Ý Yçš"{´5‚ç Ëp�°3ƒ�d®žÃëD…jÄ;øïÓ­G¨ÛúZs‡ìÒ€2{0/¢P© 7\mÄ ™Ê»V÷/wMÁú?Zì3˜u:> ÙØÊ ÿ5jÌÑ}ß­ÍÕsÚÇùSkGG�çm#ôͧ£rXwÇæMí!z4Ù€äµñ#ÓÚÖD”ݭJxÉy©"Hy(P±\f¤¡&´A#¨Zpu ^`1Ê�Ì~ü ö“%¬! – èOP-ÝMBµ€d‡Â¬ø©9 Žcm zSg{›À4,¿]©ßmü9’x움ˆªyp’�2]ùζ­ÚºÓ#@˜8XEèÿ¥8IÀÛ˜ŒÑq¡†ÍˆBú ×ò`'Ô>4 q 4ðÇQ âsD‰�èÁ­è1 q_pmÊõsÕ—ãþúçG´¯sÑæø�èºÑçæË®q^†¼s@¡�ëirô˜ c…‘p …û×Ŷ#&¡¯÷�Xÿ“�_ý¡]ò¬ûfbœ6 ÿH” ÄŠ�këdŸßIo¾ŒÓD¾Š—· •»¶kî_º\³xìñKçùØSî²ÐûC�«1Nd èLHÑʧ`ÉoÃ@çHŒð;.Ý.:ÄÉ€ôâô~i@ë§®0äÂnI?YÃw‹~v 17RJ`ØxÈ{ÁÓIHD@â¦ü¿áþ¶á~Ûp»Ýp»o¸mÙ�yÅãùècŠˆQkqp;õ#­EPÊPÿ›ý¿ ç|q_``¸mCÀlîÚUö¶ÍÛr»aÛì½¥”½±­ÅøÚ,l7…Hõ8%qRdíI=ºÀÛ“ü÷œ3ÞÞîØ÷7H­=. ùu#t�¿}5òBs‚š]F4@NæjÀ™C¤�“‘Ñç¦e\ñUç U«V­ZµjժߔZ€U«V­ZµjÕªU«~„÷œÛƒÒ Ⱦ�íð|Ûd4iC'xhÄ„÷×üß`Ñ¥&ïd˜Ý}B‚²vÌd&¨[Ï”¢ LÃ>\£Û»²¹©‘[»©‹Þ§6 [æp™½%FbS­5W�f.�À :e7‡�! Tϵºr^Äâ  #°Á¿‰»�¿(À¨Ö÷=w“ú~œ6NêA¨� ލ>«\é�¡Üµâ]ñ_8pÐóüÏ9ÔÍ*z¶/þc ¼”ýÏÎ3 ©á;Nm~Uþ¹æhì’ðZTÁ�ȈZ D ªT;WÒÔöŽ «ÔÆ€æ(mt@P!‰,U†€Àl±]­X0å QAR¨@*�ñtwE|Ë(@aà ÷¤OVæ0'£?»w€+âÍ–9¢Š4權µ­Ûþ“ÿ<Ÿ{†vwGÛ�ÀT€*P­îö‘�›€M"°R[¨ I=z„Û¾0€\#/xV¼ÏmΧèZO#žÄϵ0ƒè"ûýôÃqÔ(ôÅ8ŽƒrÂm»kÎÑŽM8`hšß�Xºž(t•û>ÖÓä#Ä|t0>Æz„£ŸÜæu¬EqŽM׉—Äœ ´ïkB ;ùþqê×àpînŸÎÍî׊׵c»¨{�œœšk…'Áô6NãÃ×u ¸yPÑ«œrÐ�”ðaŽ}TæOÖ:ާ�£À¹^=õ:"À Ì?œ'=nµ¹ø`Ž�P|pLúv\ë^ÂúGBÇ'ø#¼)˜ØIyêùðp'‹|©µ@tã/–‚žkÏ)›úý~Ãýþ†·7˨¿m70;ØÏ„}/ØŸOT®¡‰|Ð®É ô'6²B¿Ó–�p�‘· &#,pá ãv»áþvÇývGÞœDðj)”}G);DÌF…9uW‰Z+öRPËŽ²—þ(�ö‚šwÔʨ’̶ŸÛí±Ïùq쥜¶™K턬æ²�öÝâž}׫Hâê1GÒîa*D ¤98…mMkÎÂÿW­ZµjÕªU«æçˆ« V­ZµjÕªU«V­úÓ_÷Û 9mA9ÿN¹ðžií €(9ð{šÎ˜ðþù¨ˆTÏg¦zhÏßf"(ÛkŒ�S�ñÀ¾Ûâû¾µV( ‹u�Ä�ý{S°vÀ�†owÏIVk‡LåW ÑI©ƒ˜°éXcïÝ6Mí@˜£}¿ôî³clf€Ixåi JÖμ¹š»ãî?ç-cË70’(*”*îD¦”Ï·mÃvÛ�0î zA­¥ì(¥ØÊÉíöÉ\�öÚ#‘‚„ bI"­{ÃÌØˆ ÷;~!!Êèû÷þó^ ž�GWþ‹_S²¶¶>QU”Zûš©ªær ì‘ þZe(ŒX`d†â¤s/€¢; ´qN?#ªeÕªU«V­Zµê7¡`ÕªU«V­ZµjÕªáÆ}ÛšBJOVÕÕ@ª-Ó]YÚpÙ¥nó߀íÊÄag?vÛI®´È&kÈøÕ)“Ùro[Fu´„%nŠü±ývP,eWB‰¬þ»EQµ 0b. nÃÞ”ÿÆjVý~�Ôþ£f'¬ƒÈ¸m; †{Á^èÊ÷DCàé 0lüƒÃöɱ!ÖdEÎ3E¤%€îà |´�c›?­A icÓУé\¹.¥�?{+½¿¾¢þ3'üjŠþ ¢o QÕ ) dB ÇJÜñ;v�{s‘pËzw~–ªàÍ?«qÁBª€¨ßOj³ô'h'’°DU?ÁHÚ00<ÖƒN²A´†ð÷úë̈dí`~˜äLƒrg‚ä N—°8a�@ò T¦&BBÛi#3°L›† (�õÂb´«cO¨#ŒçE£½ˆA9©Dƒ€4ÔG•~p)™œ=ˆÇëdÿ÷3Íø±NL�<çg4‚ÑüùAhë�Ž( Ìmº˜¨cM¢@ö’à@¯¦ø¡C_îÇǽp ˜Y¯óÚù‡X›q¬c­jÙóÒ®�~½#ωgŠú~˜—æê2­‹× ’]­©s~”FB<·Óêìú;F¯HLáÚsp ãøÕæ¨3�‚ó:ûÂÚÿK«qp 8:¹Ûœ×PàçÈ·�vóîGZ,ƒû=ŽîÞc–÷µT”RPÊ\l]ªÅAo“'Þ’vAS£×b'è¹ïØ÷'žÏž�'žÏ'D¤gÛÍy÷Sî}JØ6#ä-wåÿ–RÊHÙ®!ªb‡n£p-ËF#,Ú½PísDgR\�2âîÊCà@î¡ÞÇÌöèøîdËZ+öý‰RÊä8ð|>Áœ�·ÜIÉã Ú¾E*PæóÙܘ«9¤ NÜã›öRú¾ª!Ùá#ŒU«V­ZµjÕªßÔ爫 V­ZµjÕªU«V­únÜ3'ã–©ÛÔ‰Áâ¿Y»O$`+˜f«ã¶á¦ õ &™U� ?t»qf6Ó]6@·¬ï`�[û‡LvBúy<¬ï*zøC{t¨ã®€£`‘m �t¨�È�€SËÒu(WŠÚíþAMý¬GБ¥žÜÕ„®Œf SïÜ)'yXþ�®Û Iãòm© Õ1Q�L;ÿFknÄï£(œb‹B�íþx"Aã¯ÑNß©Æ�¸Ó/zNÆ~©ËÓ/¿Ž?(e/Þó%"€ˆÅÜ{_ “ãÈ *”Õçi€LŒ@vÐ…A-¿8q5S2 ¨]Õ¬ó)ù fPÏE/�Xñ‚|ï`¶ºµ>À¹¿}²ÑG°~wRA“I·yë“Ë¢@ÈǤ u3dt¤°ùž ­`Û>E…÷ƒN.ïƒÃóš¸sE˜ +ãkRÂúªýZW?R:œ`�·=ŽèÔVs pë% S²_lލžVe\<ÍðÃlü-Ú F“—¼q ðÀÐÀ2ÖéIe?My:¬½q1_Aãùq uÚI?Ÿ“¾è +{$ ö3§ú³® ͱ¡“‰¦ßÇ¥ÚrïK)æ°ï w7©µZ¶½]í/ŠZûþ°ß¤¢”9gà‰ï?ý„_ýê'üôÓ¯°?Ÿ¶|9èŸóf¿ó¸iÇ—s_i(ô�Nm‘’ÞîZ«°ˆ€ ýH¨R»š¿›Ð�9™Zž™‘ØlýídIùö7‹èãà 3FòÌÈ·Š[¹áv¿£ìï¾Ï}ßñþx€ˆPköí°ŸrrÅPþ×R»€ÝGŽØ€”Š“&u²Fqwéד¶H¸[µjÕªU«V­Zž#®.XµjÕªU«V­ZµêO1³CB=Ú¹�]Ä{´wŠ>�ˆFPkÌtÆPfª†‡˜Ü¡úgB¢Ô³k‰Û#ø,7¸E[®9¹è˜‘\œ<§·�« ªÿŽÓÓ<üïÝz·<ê¯U3™åmJÙ‰Ô­ÁEx: u«ÿæŒÐUÚ42„ T“Yâ²L–Üýá¼Ê°ÎÕH°pÀ˜‡+€Š€ RH…“¸T‘çQ‡…õµ!ÏQ7ð_úq¡·º�ÿø6Km½bL»Ó¡8�ršCæ·ž•¥ 4:‹D¿öÐ^OH+.6v†£®l�-W›‘ eSÍ3\5Ù@‚TBÎÔÁ~NŒDx>Ÿý¸žÏ ûnªøûÝHûnÄucý!¥dÑGˆoª|…'s6€ª¢VÁþ¬v‹2 #åŒûí†ýöìàü¾ïxÿþRÅÜ œÙITÉêp¸8��‘R‚BQJE-ãþÊúÒ¢ ´GLô±U«V­ZµjÕªUX€U«V­ZµjÕªU«~˜rKðfò:\ø�ªøéÓÊÃòw{a:¨JCÖpƒ&×ÀqNMMÆT ‰ž½lŠãò]íOdxcLøl`Œ º¦¡j÷6XS©«ÄØ÷aJ}ö/k_�&´v e»hŸfS-`Ÿz»«œ¢ TäÙó"Iõ¬x•™@°¶F…@¢X,Û]üv'Bt¿€¦Â?�/Ìn'÷h” ª£�‡‹€tòBN#åÊ)6ÞŽÖÑeDù¥ôÕ–^¼éKyÒW/2[³ÉÿÝ!¢Í5;¹Z±©1[4EÊ Ê6%fg'ňaåÝ–¿z繪ž d®`—È@ª½…Ú{‡"^m'" ¹-¾6 ¶�vêá ©ø«o¯“ Ô\Ä�71à®fëß”Õþ£Â¬ü™}›<ÍM4÷_–("êÍx¨ä$¥d$X@×7™5³‘˜/ÎäÁzbvÏ!4�Žêþ‹�«4¯ií¼šKÍpo!9j3ÒHA ™ÜÐ�Ræ½uŠÕA‚mV×_�•—#éì¼�FnÒ‰Ô‰%=ë cÔÁÅ9F+Ða}9í(€¦JFv W¦ö@´c™à^ýhûתÿ0QNsox²œö6ÏÚ‰JmínFp û¾Fà/œ®±ÝkÀ·[ú£ñ@ô°€Ås8â`Œev}ÝR:ýľˆ}Ù�~Â�~6rú¯ç´¾k˜žWç“p>D¯dz?tŸŽ×xOÑi莱­“Ã1J‚>!œP·ƒÿÔüŸ.üXÝðe€1ü>~ %f"fšÜ�ˆ@‰À)�ÅâáËÀw�b×z?¾ît‚AŽSªÎM"SÃ{,L­€·¯ DDH)™>gSÿûý€þþæ<Ð,î·íæ¯ß‘RF­�Çïß¿ãû÷ïx>'ìsøÅó‰Ûí6Ü—tvJj.ì×um}ÓÈ”ÊÓÜqµ}µ6oyÇV ”'v(N¸o7ìÛiO(û©æH`QÚ#ºëŒTÖœ Âb ´“4k¿wá”ðÊEÛý—_7°bV­ZµjÕªU«¦Z€U«V­ZµjÕªU«~”"2åp€øÿÁ8)Ym3Íj8ØS‡ü]:DGå_Wã3Ûƒ`·D?Gæ±ÏöÚw{ï° ¹é¤<¬ý1\æš ÄlÖL]€Øú)êˆéŽ б}ÐaŸ•Ön¡÷¨“ Ôh7¨Âµvs›u¤9÷ý»SO²ú˜wOÖ�ï‘ùÐäp+@¤]éª*ü™è à  ST7PXÝõ`�+†€ÕÈA«“j»)mqVGæ@ÈuÆœvñiqè7;× �›ÑÎÄÕò¾a†‚\�ß" ÈvÄ�ÜS ãZÔ”ôZì½UÌŠB¨ÅÔöZ†”Ýóë;(ݬÿÁÁ»»½W`h}5G}æ!]v' ˆí×ý7¬ˆ |°þV´†±öG`xX«½·úñàÚ¶¸j:‚3l¯EYþi>ûgÑþv,ã=¤ž†@Nc×:¦�Ï=š³Ô5ø»ëÕL90^Öµ¥ûXó\Á­ìŵ^^{;çõûb>þ‡>Ô‹öéño=b$Á®94ouÌ5í1 ×íù�zË'2�Nd×™©…}ù51j¡·‘ë�GÚ"ùÚKîÀÒ¹3Í«`"ÀW Ÿ“¤|"™¬‘K0úÚHzXÞ.ÿû"¸3àG…~MA Øþ#ì>ªûÃÏWá*?¿ô¿ À¡¯>öù¾J©ÿ$313ûI¼ÛýFÎÙ×62r  u’a£,ºSƒxœI#N÷0î°ÿ¦ü'6‡£fe?G à¯f»_k12dJ(ž·{¦œ¥G”RPö½» 0‘�ôª©¸ßïf߸Ïb_Uµ; ÕRÝŠ_ºE;n(PEPv#$¨*ž)ãv¿á.‚mËH)÷ˆ�m»á™žF†(‚¢µÏÆu ±’" "™É“~ÜæØ¤Ó `°&�@À~�Ö�í’ȪU«V­ZµjÕob-ÀªU«V­ZµjÕªU?@)™Â¸«1c¶u{Oüç¨j¤¡¢ bS_b(�Cþü)s8€jG¡/QƒŽÊB ×Wó3€‘7Ðl˜'q³|ƒ-뻵]i(î@¦Në*jL$€ÎþÐQ)×ê·›µì]%¤si·PÇÁ¡õÓ¸ävuXLìxQéŽÁÌh š}sðä�†äÁ)[`S›úÎ~¾Èø@¹}6˜q¼q½°!#7L”½”†ªNÁ×cizý#)öÕ+¡?še°9ö›8þ�w^­&°¶<ôfu¡Uë‹Zm¨–�¡üW*T ¨<��  ún¯ÉÔâ6ü u¥?QrÆ À:´É”ùª(5·‡)}.˜€ÛþS‹°„óN&ˆÌ„°p�0Ës�ZÌÆ_Lõjó ÝÚhV�ÈȇÁÛÀ�FhÎ%Dà ly8}PU¸%* ð”í=útÞ÷+Èž©Ç97Ûñ^SsFikÏÔy•)pÿ¿bùÿñä‚`„ ž‘ç£G|0òï̪Ãz¯Ó…éú<¾èW½X)ˆÁ‹†‹�Ǿ´žš×§¸ÖËUûúlkS3uéûÓ+ëý¢Ó…“Âp6i× mV3SÿÌ'�pÈ”Àµ§ ÞÒÛˆ9’&W ñ�¼…9.À?4øeô9‘ÅòåÑg¢Å|?sµ²Óä PöýŸbNÜf°2ÀzÆÛï `ö¾ÔîjA¤`JNðk©B bŸK‰±mwl· [Î žlà|N�nsŸ’ú)™ú?¥¬ëR+J-}ŒI¤XŸRênGÒc»k'²pWÔ7Ûüä–ûcŸ6ÄA÷RöN6(�pÀy!UQKÁó¹Cjó¥šÅÿ·owÜn+�SÂmËxn) î®’RBÎ�sî÷KêD„W—m ÌV"'Õ%BÂè“F²@Û¦è˸ U«V­ZµjÕªßÔZ€U«V­ZµjÕªU«~€jV­LÑÐÀMå®byº1óÖÀ+›JÐ)Þ(*†²¿m«Ÿ‹Š7ÌÖÁGËêÖ ¸À �  *�Ô°·¦8õô ,Ì WÇu4ªüÑU¾]¡@jõœñW�_PñÓÙ>úú¡ûPAÏgñמ?+ÃýÕ Ê–Ø­ÄAûÄ`ˆ+ü‚¬âbúâ?'ˆZ„ ¤ª™@ $ÔaÓ_H¬×Ð*j¶ðõ Ô ;´î6È•¢‰àlSákWßCw¨ÿTû ˆ•êã©‘WüçF¦a'ûýpÞÜ l°©©ö+‘þ—jñ”Ҙۘ㠤ŠYpW¥£#@8¿>'Ÿ·- èANaB"à~óHÕkJ[g¦q©øtDšØ£hVÁÿ-Ëæ*9h¬tš[ýXCKÏÃ9F½|ÔÔÙÙáÀ :o“^­Ÿz „œ.Jó6éUœË'zñÃ2ôšÏCÓµ,ž@³³Jp{™]næê$-Õáþr$Ÿ�P ûX‡AÇ´6ë‡ë}B<¹ZÏ ,Ÿ(U/ÆK¿»{æ1véÙÓG ‘ÑòÜ›úzV‡5E0Á²�Sx@ß6Bm fÍG–²+F½SÆa‡œp ÀD�H'øÉ.: Ê)þù�ôLÑ ýÚ¦¹õO$D"ôµÜtLgKè1öÎ î& ìxíÈø 9š¦}¢�츷«�]NŸ(¹Õô–¬µB!`�©.`RpW( ´*”Ô’jSÆ2´ZT€ªB+{Þ{Pü²o£ ÀªÉ-óÕPw¨<�6ØíþIÏ`ªºR_ÅÀÿî ƒ-">a¥øûÄ tMµZÝÅ@tVrs'qxˆè_îD@Î#ÇAÈN�ê ¯Œ÷pX/¸E+L'­h´jŸÓ}} Ñ9#Ú¨«F!4½â�ÏÇÕi¾þÞÑ_êæ�HåA.¬ÿH ¯—¦ø%GãiÌ9ôçíŸçÓÕlé×”fAW4õF>3ºõdó¯ì�À ›kVÓ:+|ã¸8Œ¹žYÚÖ,öO«ê8º?²Ÿ¦ÉÞº‘Oˆ>VÛ»ÄôÅÝï‹�ÒL€ƒ ìbé'NTÁPhM¨{Ÿø–“ Fû�ÔôФÓ?‡5r<àz“ ‡ÈGt& ÅM žÉX¬ôŘŸsg€cse¢”\��ÑÚ‰2qÙωg¸ü¦˜cgN?‡¾Vœ4ðóìÑÇ’LN³hD‚#€&CНÙ:Ô.Mñ|^õ}X/ô5ôYsÿ_ÿ�ÿçïý…¿ðçÿî©7‰�SBÊ [Þ�r†¨b/¥XƽJâä×kk·ÔÁÄÕéÌFN§÷4eSõ3“ॎ{ Z$@Jưa¶û�¼m¸ßïxûö o÷oøöírÞ *¸Ýï¸Ýn¸{Ããûw<žO¿ÿ2rgN9oHÙ•ñLSJû*µ –‚ZK剌H�Rî„KU ”©‚âó¸ÖŠRvì%có{¿¼m¸Ýooßð|>Qì€*Õ¢¼>tHhn›Ç&d¿/›ú^§>ìÇë†ãùZµjÕªU«V­úM¯EXµjÕªU«V­Zµê¨(…±'CidÔ_dÇM¿å�7`ž˜ÝJ5Ä;w/ã³ò;nÓòµ Ÿm¡ G’aØÁöí� ÒPÝ›x^ý+|v"ЏÅ$˜+�F ÙFXˆä·þ¹Ò“¿ïŒÈ­gÑÚ†ÉjZüý nkÛ6Ë`v%�+FUfW:Iá�…Û@ž‘Uî®ý{nuVvW€É¢¿½E'µs§ˆP°FïÇ¢À· Ääˆlãç¬à?¢\1ÃúH™»†M�@(EÀ'sÉú½˜ Zw¨V(Òk<Ç7¨*Pº)T3D  I ’°Ï«Þ-À‰ÐN2-`(È )ÊdÖú†ä<wi¤…jáÕ>Ûã!”Ýâß�ö)*ÀuÒU!0rCêÅÛÔë/�ïÓ9`(�5¥9ŒL¶ým ©á ®!2@ClAsÖ .�?œ±6UuÔ""PRÛ¤F òÑnuÞÚzÑæÃ €ñ3˜tš¼[ƒljޣ罆hö³›þq,¾H: ó¤˜~¼âû.}½í´INzÞMq m¢G´Ÿ Ÿ¥¾= 'GÐ;ì­ÎL¾œÕ†0!þi¿=Æ%®A׋ÉÁÆ$p#hÆíõ¸ã Påëáìú[8�"0»�èËF’½Î×ÝW£5^ÓfË9žâDjyÍrXËi\CÛØÑ«{˜;íu}ÿKDôÏ�ˆ‡Èœ~„œ3n÷;rތ̕ ˆvÔ*>&í~ÄêdÄ&Ð�<' ì— ©Š}bߟ(eÇóù„8¾å¥ì¨¥ ç­“sθÝn= ¥Ô톷·;ÞÞÞpÿvÇÛ·7ܶˆßê�ooøöø†Çû;�ž{éû#°+ãÓÁÕhÜ7HˆBRgÒœrÎÈÛ[NØ”�ÒÖ)Oê„�Z+Ê^;ØžSÂÛ·7ÔZð|>z{Ú¾j)Nئ{¾F4ˆ÷€­ò6\âPLœÀäêÿ܈ Läç”×ÿ,¬ZµjÕªU«V…Z€U«V­ZµjÕªU«~ˆRˆìžGÖF[Ùö;´WuhB¡â`]ÿ©ƒÿ}#2¬dgÄè Òm-Ѩú *ÉÉ>&`&t8€SÍ6_µYÎ*D*jÏêÖžõ:Ôìt¡n©Ûȇe4PØŽ1`ö œ 4bÄ3x{v�G@'@�Úò|¥:�oïmêqSÖqó… ¨%°¶�Ï™lÁ˜1©ö7‹s$…éoˆŠÍq|½#4êJ]µH:Û+®%Æ_, ç¡·ýêy†sh晄mª~}ÿ_y/…^ðÑ1ÀAÎ<™3¼Õmì5Yd¹©{% »ï~ö& ôø|3‚×fT®"°²m›aûVõÍr_«Ù0£ŽíºÛ�ÜiÃI@ˆ h qß¿Ôày?gÅÇ¡€ªƒ$p,&›Äl´Ÿ–!=N¼Æ ÖÁ)¨«ÿkE á¤èNîÌå=؈¯žO]ÌY! áý1£’Ýmœú,ãlu“Ê|¸Ñ�B¯ÕëçÑmºïY%­³þâ“gŽ“€[lËø×sv»¾˜[aÉð¸øI1" îï�æ�Aä)[ÏÚ‡£êX�ˆæ‰8ÙêŸ[1÷/a&?èÇCeþqʰ?Ú÷6rÖtý �ÎÕXxhºVÒi@ŽF„(ŠnqÒlòM/ÐCo5놦Â× òá�º™œ¬²Î'ð^Çø…ÍcR|n7‡q€Ù²\ÂØ!êÑÍ…<›Dx›#|‘eßNãhûWÆõ€¯ìG>þäŠOÀÿ åÿXÑý âŒæ°áãòåÈŽ%úb>Ñ¿ÿ¤‚“ê[Î!ÔH¾+dZ“$�¥¯Q<Ûþ£9£tÀûµ‹ÇшFñ³ùˆŸ…é�$áëj«Ý"A‰ÑRÕårÁ¹¶iDëÌ$¨@Ä£#`¯ó1Eçð ú¢¢›‚RàhM1¨Àަ!^RG>¸*\¬ÉÍ%çÕ8¤k'˜¸?�ÏÔ—î‘Dä?úoýßþïÿ¡ÿø_ü�ý�B˜j§ÖG8Ø­RÎHµ¢ŠœRŽˆ,R(‘¹»4B‚HÁ^v_þ,Ûþùxb>Íþ~/¨ŒoûŽ}ßñÜ ¶[í`·ë[óìQGÙUû µâ¹?ì>I[ÍýoLdq’!·­ßˆÙœL÷qÇSÖúÀ®;F\K)™²ž-&Á ,¡Þ+îû û~7àß fÒî�Jî70gÜïŠoßÞ°ï;J),@TPJÁ¾?»BŸˆ:X?"R·óOîŽ`d?.ïM)!mÉÜÈH_޹U«V­ZµjÕªßÔZ€U«V­ZµjÕªU«~€zÿþnŠxi K/™œÂ4Û2÷жÌö¸©3@Ð²ŠˆÝÀ67ëf~ÂÃèˆá*t8ÚÓ°n6»ß�·¦7¦a4ª›½n¶ wu›«ëÛs@Ü«r°Í7ËZ äœÓlp›5±IãDdÝßÀTñŒ_õÜöî’Ð@Ìc첃2ìJlï‡{¿ÆsLýKŽÑ2À•··«[¢³;Ûe=€œ—¥ËéðbT"_Ú@Oàÿeëæñùö»xéœýºÂÿ'Ãl䃶6t¶ŒœïPU³ÕwàŒä&ê¹É—þ¾HæÏœ0•)të }�¥É©ìë zuðß­üJÅJlàÚ:PŒ @wb›í?0bœ_ÐíÁÁuž>¼iå?ì¤ÛXjªMå g$ iªÂÝhÊŸ`&T±|ö¸7L˜æ\H!™,ÚõÂ`¾ÙËkˆ !}uœŸLÐdí>�ÿW¤Æ°‹žíôÙ¸>Zn|0×躠2GsŸ4§ê¿M3j'I©G\´Ñ2É»[DË$è@¸gúh% ø!?9âhŒ ù(®bĉvîidÝ·ss´Ð j=��SzEüÛ%$’¨húl».ÒIÁ¯‡µø#ðsÜ_��d\úaÌÝ\âš|r[xµŠ¸j['ËŽËYõUþûÿïÿþâ?ùÿ-Í̤D$ªî�"©É!ò$ž¿W€«ÿm½'0RS"в×~ž¥ Jy¢T³â·Xsˆ©Õ~6é~b†æäË÷ @o)ûó‰G~GÎf‰¿e#(Ù}À^w‹AÛÇP¿3ºù?…˜'Ÿû‰Ø2j±ýZ»xº/iÇË)!¥ŒmË(’PŠv®VA'в‘4o·;ÞÞžÝ!{»'4€èN �ÌÊ×®.ë@’Š;˜Rb¤äЏ”Lxì‚nÒ¡|Ô% ¬û¥ã�…V–áÁ²=ª-=÷W:™@ ¢Sä„á}!Sstä‹ÏAøU”•=à˜Ç¬sÆò\trS>æe÷}âØ6ÛâwÕiPùŽ¶È A¥»¯ôó—¦?N$€/>ü¯¨}Ì�¼ó6T³ïqj¦áþ>f‚ƒF#È Í­û *ñÜ‹ SÊ»øÒ­ô¨2+Ûõþ¹çF`Sþ§ä’B«ôó"mÿÄ=Z€'G†¦ofÌ1t 8¿Âõù"/<~,ºPô·îÍÄÉ &fÕ¡„oc7 ˆXúù§xX‡‘µæ§A³Ö‡D•ÿˆ?M.úHÇé�ªì#øs¹ÇìÓ){>îõEŠF ]¤Ñ_½¯‘·0œI¢{:Å=cD;yeݶ>BÛz=ÀÿÖ2n.-\cXèâ:Љf¯(óýÆÕ:}œGmÇX‡©{Ãg¿R�Çã¯qæÿ Ul"â·ªÕíú˾Ûä„Rw”jöùµJw3Q˜R�ïI)P[ÿÑÔï¾‚Š Vqu¼œ¢%ÈÝîº3†w”jë£øº7®³vOÇüŽœy3u~[§DÄÚ_ŠÙíW駉œ¤FÉÈ ÉUóäú�HiÑJÜû¼–ŠÊcI"‹%¸m(r›î�Ä-÷÷RM…O@Ê ÷û½G¨·±Ö 8€;  ßÇØ½dtMÂp™æ?y»kÆ}ÕªU«V­ZµjÕªQ‹°jÕªU«V­ZµjÕPïï�þð¸U·Ó‡©¸Ž*Í©®¬§PãŠÌö–ê®»Ez:ÉTÿœ¸“ @ vK[í¹¯ÃЃ8à(¤8(M‰í(žöæîP¢µB) T-›9÷íŠ X"¬2@…I•ê`¾ªB�@:©,)nIMéפwðÈÜåÐ×#Ä>l±õëáöÇóv¿ú3y®aŒôÑà(�Jõ£2ö$ ŽQ/›sÐäð²b šÚ—¦}L»¤Ï ÚãôE³èúí–o¸Ÿ;©P°�9s§WW}æ<2ï)pïƒÅ¾Ã3m6�s�Ej@¾M&»G[f Í]:0ÎÍks�S·ü‡¨e3KÙ�2È•õ±‡Ž‘‡ÅâJ..=þ2ózÔ2Ô\ÕÙl üäÔvœÃöyÞž“0¨YÉIž?Ú!imt8/Ž‚®Ç¼F…ül¼~ݪýîˆ,ņ±]î7ÂÆ�È3ëð¯ß×X Aõ@ž.&�ÀÏá‹96E¿Äù<ëí5ËõF)„TÄm¨Ò°½?®ÔýéD\�¼ù�³¤c–†í¿Z?†B\r‚>Ø×S!²ôÔ¹Ÿ®ô‘,Ò"[ôâ}çmÆk�È9—n)Nv ÃqŽ�Ÿ{¥:þ¢_pÒŽÓ¢}ŠŠ¹nLÙË_ÙŸû·ûýö(&çUU‘êŽûˆš“K­¦J/{Á^šªŸ‘‹€SFÎ)eɪ-Ù‘Äsì™ Xë­ªT©ví­Rj�ŠdMRšs}DEa—¶Ÿqí¬P”½@jq·##"4 3#±‹�ù‰Ù ŸlÄ�voâN¥îý^(,ž gl·ÍïÝJ�[ª¥¢ìÅ÷c×™œ7ܶ û¶¡”ÒïåP ž®ü$꤀qº[ÜRäÒ ±µ+¬*P‹93¹A­²þgaÕªU«V­Zµ*Ô"¬ZµjÕªU«V­ZõCƒÙ-÷Ñ0à? úÕ#vÚ¨[òÇ åfƒÝHü?R=Ùý;õ‡ÑÒʦ\>³AzP'•¦~*üny/ß¡†•Ššíw$ªê‰ì}uÀtã5 ªØÛñq'Q\gé•YSÙs·¶n™è­qÃbÿøùpR€CË}ÖßfYñQ¥8g‡ã¥›u[ù8$¨iM­´û£½À 4ýJ®SÖ6&E^ÜÈd?0ï ¨¼¨·ða`Àa¨�¿)T‹÷eí¯ŠTÓ“šºSu`:¥a;ŸÆ]ï;Ü+ØÉ4=‹Y¦ùµŒÍ¢Ù?õ—†yèd€äÛnûnöùÍ5ÀÀb +Øö£ “Ú%ò§ÀÚœI!¾/Û·“Ncäµe@^Sùs<”n·áD'Ï$iÞLƒ·œÐ:V'œ“0©êÛ:Gt¯íǃÅýÇõY¤E˜ólJv— §ã€¥Ïöÿ…V¶üì ¥z?«Daî€üI�Ý®/:Üû¯Ú�ñÛzCƒB¡Tçq?@1e�F›ñ‚_¡S C”Ûõ¯»Ðp ˜ñó먈i]9�úð§�êänph…ú52^¯§ñ÷‰ëÿñHÎVÿ:-ÃSDŒêa�®G2D¼¶èiÕˆ1}?WŸ�2(N ÿÆ»þcëoþí¿üûã¯ÿ e/;EEj³Ö‡˜j�ˆM½¾ìµ¢”j†)DÈIpÛÔ ‡Ùòæ³­£”ì=Éב*‚­Vä¼!orɨ¥º;ŒÝ“Ô¤ )¥ÔZlù=”¹ xLs»áN:bVø èW�«iÇF(hÇÙ㈑S…ªt Ÿˆíš†AÂ4"€€¨b�îìÎæ°m7'k¥�95ùþöýiçsÛŒÓÆŒmÛ°Ýnv¬¥ ŠÅ#èndÌšÌÍ :´ñQ}¬5ò9ɲ}5ò�ˆµÛâJwcXµjÕªU«V­Z5jV­ZµjÕªU«V­úêíí Û–‘8wÕÑ«éZA¹íè»Õv·�žòà1²G€º» ÐL0ðmDõ–Š@_B:†í?‘묘C¼Š‘¤BKs¨%"¤œ:Ñà~»¡ì;žÏ'Pv”RTÔ$È)Aržî)Œ“ka„‹Ö÷vß«î໑ œÈ±jÕªU«V­ZµjÔ"¬ZµjÕªU«V­ZõÔoÿöïàÛ·7üò�~¹µüVæˆÌÆ\é–«;«¾©gÓÁþYÃC÷�cì.L0Õÿ¥ ¼YàHµ|ר…�ë~rWt5PÄl-Ç–TÀ<Ð òö'fß–}¥Ä� ßiŽH°ÈqSÖU0Él!�q¼D„ÔЮ¦T€ÉíÖa¼“Y3«û²“{w¡vHsnP…¸•9€€èP'/p"„‚¥u³¢ŸoÏl»jZh�gvŒˆ1¢´“¤�Hr¹Ÿ°U:Hxõ×Bz¾^sƶí¨î»;(‘•bc6* Aõã"@‚š¿«q‹¿'‡4‹ýC®2ƒùð¥1N©)ûk“Á;|b2‡€©�ª 7+�ä $Ä™ØwÛŽTÀé ¤Ð¥ö­Wt&úè)Ëa€‘�W"ª�”ð’wÂaNv«g?˜ªWûˆ8¡¡€5È ­¿c»Ä�´"(‡ÈwÁÔÃzíŒb0ºœèlT�í üo‘_Ë4­Rt&ù1Ÿ?zj�xÀzéeS4f¾¿œ7z>©íÔûrÁmŒ¹†’^˜¸Ÿ“}~ë×É©äúø�ûl3�§µN� @¾9ñÑñ ®™�.׎àÑÕ×/˜çÎî9÷sòÆXH»£f¾OWªsäË|]�q±éƒnm×dÏ�=Ø�e$D¹è‹1JôáXçBg¢!"iJÏcûtA›.:ŸÖóùü/ÔRÿ§Ìô ¢§ªr-Ejì\‘Jõc7)¥ ¤j¿?·»eާ̸m9oH~ЈŒFÎ#”çŽÇöŽç¶›’‡¨¢”Ò•ëµVì¥@ª]_ðÏäJû ÛvÃívö݌¨Pw¼¿?€÷ŸÜ©ÀcˆüغÚSš2^ü¼Ù±HsÐá&£jÀ‘ )íü3˜jMH‰A™<: Aê†*\ 0¡éþ ¸ùý�©ûó¶!çŒç“<¢ÀÈ æ@¨µ"ç<­MRG;‰¼ ì_N@;ÎZPö�g#”õ? «V­ZµjÕªU¡`ÕªU«V­ZµjÕª ~çw~¿øÅ/ Ò°Äɪ‡Lf –Ï:”ö̩ڃþž;{Î›Ú í¡w$t”e´Å¾f)Ûâ FVn³o5ßîävàCõØ”Òmi¸4å4èÀáõRô4ï®üÊü–4N`°Æ‡á⦑±ËÉö„ð'q‚ÔaÍÏže ø¨$� Ø£¡�k¹¼4”�ì¼ý­ö­e 7ËlÛ+– %†4 k²!L#BAǘ˜Q}6ä¤MÓ/¢ðã]­¡ jÀ²U鬞�ûá£-êÇ;ý“áÏ hU�¢‚D!0ÐY¤:ÞÌ ©Ð¦L¬dÖþJÖON”$³w lÊö�yðDþÁí¢!Î UéUºJS C#¿ThRK9g2å|-¦¤ožúÎ1˜¶ºsEø[ì”V�ìrië¯?NÎÑ�™Ãqw°TÝE ŸWþ»ªUæGpSÅ­¯}ÝjF zx/]ªÿé íGaMÓN¸’G�5öPÒ׆+}môÎ?Í w´�ï£�æc;„~C=p{ZÃ<§Þ'µЈeh„an!æˆ;=’+.èg§žhöãÝQtôÌüië—ɪ?€Ö¤ã‹®‡75VWü¿¼ùù9`öó�œÉxÓµ0Ä/Ä£iïmS´‘®æËi|÷}Óe"‹Â�„ã~å­pE<9Úûwåÿ©QúùL Ÿ‘?ûú—ÿÕæŸýËÿ쿤Š$¢TEQju§”A‚|&#¬˜›¡rSé Ø�~rÎÈÙˆ�)±]L„½üôý†üžQk�Hí`v-;ž~(µV”j€Fˆ’d„ÉÌŒœ7ÜïoøÅ/¾áv3@);`/Opf`§àØ“úý•²‘o˜ØÜ"üúÌG—€Z¡ ”R±—e¯Q_Â2j*PÉPɧÓaÛP?ކ+U‹3HÉ ¶mCNOÚ;A¡‘FSÍݹ€ü¾ÊîÍì:eqOîkÄÈvñÑÿS�¨Å ¬ZµjÕªU«V­µ«V­ZµjÕªU«Vý7î9!çíðj°ÒuÈ£C:Àu¦¡â¦àpÊÜ ?Ä 0uárpĬЛs@ÿ4 ¬BÉÁ{ž]èèc>×#¸gÄ;þY�8À�ö WŠ5ÂA§/d€•Leà'ûì°™m³-SÝU®ìpâÎ''Xv­mý;îyˆh`w«[ 9Ë#na؆cØócD2Àóv‘ÀÈb‚ê)·9hY)4ê ò�ÊZÕá ÑÈ3ˆx¥ �vÐGËèÏÇø 乊oàÒd‚)ªàj?ý­~þkªB“Ÿo"˜ŸEqƒß¤fþ f.=ªØ“–aŒ¡¬Yô“†»:¿«ÐLq𸀿#0†~VEEÒ+‚¬}€ï=þüu^D‡]<Æ£SÀ jŽoÙòG—š3æÏºöcsæ”ö†ÁŸÌ?¦­è ›†1ú²é§VÌÙå×£öuWþîÊGšíTÉ=ÓýÒÖ?þtèÃWîó«�êîNMà°tÒX›\ì ÈIÝA%�+”®†Ê‘²p)qè#ze¯^£¢@ ês…ŽN>&ådi½î½ÌÎÐõ¢p¨6}˜9qžB_«ÙÙæj°Ñ‘ÜÒ®ñ{è \)þ'+šâm^ÿŸÌÂpMøêl9Ž“øÿ?ÿUTüM(e²‹²M° 8g0'' 2dëg­€Vs…i‰€Ä\§Ü�àþ|Ð�χ+ÙKÁî÷[Ùû¢Jí*þv�#´7‡£Û¶á¶mx»Ýú¹Ë¾?j„µãiªø¶-‚ß7y”R‹KÊn·/ªx>Ÿ¨ªØŸÅ#*™ª¤ \7µ}E­O‹"xîx>w”ºƒ@HI v{“Ü9 ãv¿ãù|b+{w°¯„Z,¡�¿) ub@eK…ˆ‘ØÚ¾Œp��rêä‚U«V­ZµjÕªUá9âê‚U«V­ZµjÕªU«þôWÝ žïÏþ€SÜêšÈr\�€©GP\ Ê<”ŒöΗPÀqfwcm 4õ\ûf9;ÄÆ:ÙKÃõö0˜#�âŠ.%5\¦ÎGx¨Ëž…KšTÏŽ… =h—+ü°ƒTpuÜ èôüjr’Bsp𫹨¶µ!ØÎEwMèèXïÙÄt¼„ý3n•}ƒªSÑ£É>—¢åCƒîMtRÚÔUs'í}¾¸'C†C\ÑWêù|þùË?üŸ1ѯLLÜûœÀßn›è€}/`<ñTôÕâks…j…J…uÕ='ÞuÛ̺?e»o1›{ªÝµHÅ"]¤ J-~?Á�ê}£Ò�›  5W�ºCj1×ÑÀ·h.HŒÄÙ � 9å~Ál€vŸ""xîûþľï(¥zÛ9›í?p×h-¨"ú?žxàñøŽçó�Z+˜8(úÓ ,dí÷q·mÃívs²�ô{ØZ«"Ê œv]¶{Üvîsˆ701ò¶�ÙîŸé¹þGaÕªU«V­ZµêP‹°jÕªU«V­ZµjÕP�÷wÔª–åª+ 7T{b²‡5(Y‡YxE³•·ßbvúpÐ$r€\à,HVXÆ=zœ&@EÖ÷'€Ñr^Mqßâm;8 ™@‹'Ã@A] �(þ¢[£ƒB–8�W½ÙêRŠ_ƒ ÓTü3ab ˆò•µ}# PQu’5{ŸÃûXÔqbíˈ‚0;x—êY½|Äj»õ±Ù]©Û6ñ]YW˜Ì)~À�®÷ÊA> ˆ?V½Rþ3Ìš޽ Y³@‘¸™X0¸�ò¬yGµÀœØ>Ï© (÷>g'ʸ¥´uDõŽS˜r*AµåÝ›ÒÑó!@]-Ý,Þ-ìÞ2ùÞ‡ eÀ™Í‘ƒÝÅàkà¿ÿ‘/:ôhÏÐ|á%®gÞ¢ÂçS³(` Š©p¥:@ØÛ¼Txòµ½×“NÂqŠAA Ý#¨ÛÖŸB×1Àñ™hBçõõø—+ðòraVèÅØä€sýXÃõKÇ�O¾® ‘¯Áaáj„2wL[µ}66ø@åiãþ`û~š|8`å8ªÌqRÈÊѼ® Ëû¦ljët=nqn»êõ{7A}LÓÅ1õ�*^LšÁ‰×—Ï×°ƒMB�!\  1>^�Š×{UàúO§…è£ÆÅ¯•Ûrúd³­Ÿfa'^}¼}ù÷ÿ�¿óoüçþéÿô?ýÏA‘¬7“î8aÛ6ÜowlyÈ™ ØîjKšgÌïûyOv)� É›“‰[NØrBföõM¡UP ì §Ý'0s�›ikŒÙßHõ û²£ì<}|> ž®žo×hvg#f#�ýâÕ•÷)u§‚FĨµâñ|¢”�Çûþìêÿœ2Ô��R‹ b ª ëƒ÷Ç�Ç;ž�žûÓïC ÔÔüµØwf'o0ŸsÆýí ¥Xô�ˆøý”¢VÛ~_Íñ©ÇPˆxL�„uÅšœoض €°IFz¤>¿V­ZµjÕªU«VY-ÀªU«V­ZµjÕªU?@½?¾#—ê*øæê=«®¸¤ íx“ƒ—h`5Ðú¥´säÌFcw¹ÈÚÞÀ$…xì³HªX#«»D0<ñ°…N~#Ñ ÅåXè„z5YPFo{w )j ©øöÝÌ×Ò­ÇíÙ{òó  ÏVoߨC2µ¿ë…£ô1ËÙûµ‘T†z;ñš5•~·îö÷èÌŒ ÿ¦þ?v ^èÀ˺t8¢g§m(Dir•8ׯ—ûüõj™Û p‹�6ì`2�’c{ìýGv~e'è¦8Г œ$èÍ+\Ñ)ÄlþYûï*Õ@~ÈPþ«Âåòö;”Ô‘XïNþ×ã|õÎs$€B­Mr°ô§ÏIýÛx#ƒ M™ßÔýñ-íõW>û¢æ~@­Ã½�$@-�{-ÿ£Ï?1@ÔÙâ®ÇÕëjÙ92еqÈ<¯‚Üú۷ypôhp$ÂÕütvÉèëEpZ¹ÏÑ.q‡z°Òëup í¤á2úÈ·£t0W°×ˆ4�‡BëÛ¥ã ×�.´+á©ÏÏ‹5â¶þ¼Ú~8š;ÁJ^¬½Wô±™iÓÔþ/ÂO€CxÊGQS[œdÖVÐqhчkïÅ%}:n×¼ ú �Ç}µëã<ùô ð3WëŸw¢Cýá/ù_“ªÿ¼Td$ÕV~Æ–ŒðööfFÙwäÆ6t7ÕŠRv<Ÿï êV‘RFÞ T‰ [N`�eÝßrPÁ�˜…9@ ÈV©~?“ô/x>Ÿfeï |-Õ µ¤Ø=Ï–"7 æ<)üáàÎ)YlTSþïûÏ}ï®FµVˆ(R2@½ÅL5'€æ‚$"(Õ,ÿK)(µ 8AÙ‰bÇ&U yvI)á~»¡¾}믿c¸+•Z¦û“Fè—Œ¶mÔšû|dN`Ê~Œ7ls°jÕªU«V­ZµjÔ"¬ZµjÕªU«V­ZõT­†ˆ+ŒiŠfá8Ñu>vì�.ÓÝ–XaJPÕvÔX‘@з'â`µø6R'PК‹xhUÿÞAkQ*Àœ‘�½¸«ùh¦ÃÎí‹ SÑ�šŠ †)A°÷þh*µRv”Z!ÕÚÄÔà_k±¨ƒòËp¶ÕŽG9òÎç¼eLÚÞ ÌôÜâæ® «#AÔ·µÇ ç‹–ô±Ð†äMÉÀçøuñé•ãû‹š�%=Û{czà ³ý%P;µo�ØA0˜]Étà^ªš"’”ÈD¥¬ˆ`»7†ŒÅE¨ƒÿ¡E‰,N€›mÿ1ïœÊáN"!Tjó6Øþ#Ìe²c@°cGÿWé'Ö€zÝÑ¢ûýf��rG«þŽ®·Ï%òçÐwbr²¿U�ÁØwë×jòÚ·%.l˜ã ®Ò3€ 07¬oí5¢ŒÚan�I3 �}©>VÐ6Æ4¨ÓöùÊõþâdôõ3ÀLmÕj$¨óÊÑבىãã¹qÿr<:÷ÉÔO�íd˯ŒÄÜÚP!òH—>ÎýÛ çkÅWW=�®6ó¾Ä�¡ì×y*LmŒÖ2øPO ¿ÒÇ‹�óË2âfDÄÉÇs9ï_¿º Ç÷·c¤|ÐN=,夑h2®(—¤•_gUÿ™Û÷ý¯ÿ½¿÷oÿÿø?þgþPD’TQ2‹ e&lÛ†··7äœ!®B¯µ¢ìvÝW”²ãýý;J©Èù�œ2¶ÛT·[†ÑŒœ²[Ý[@)»yê$DÁ³UÍ ÅH†DÏ^‹TÔ[A­w߇mgËösJ{•~ýæ)v!8±91ˆ µšc…˜%"ANyËØ¶ŒÛmCÎyKH̨m?zvú1?ô~\6lÂjæ×›í¶AäÞ?»—âD°{›Ù‰i\Šœ¬PjAå q"]JŒí–±ñ yËH9}2¯V­ZµjÕªU«~ójV­ZµjÕªU«V­úJ!€‹øEYdPoRT;²T'€”fà·íÏA:€?GàAQ*®&oêJ“eâ*™ý.Á€G&¸å¬v`y$rûö„žÕã¨ÛÔ¦” ‡t@SFª«ªEò6E弪O]ýÝ\üoU¥T”RQK1ûrjæãÈnã[Í¡/m Ñ‘¨–g+N˜�‹îáÔ-sÄ€^Ø>7°EZ80Iû/LŽà�~ÙÎjýz†rçß�G?þF/»æÃ"ú¸ü|‡™Ãl÷É•ÿŒ”Jª‚` …:ˆ_«Go€¡¤Í`QPFKÖ©xŽôÔ·ýGWúGòf1Í=ÛÑj†ÒˆÕv�@CÀ ‹haËÞ]±9ƒŸ ˜¼ZH^Ø_m߬ã³e„S@“µ“��l  Ða 6Íiû,½œ^¬µí¯v¦á¨òÁ¶úºëÇØ”ñÑ�å<9>Yõ@8ƒÿ4_�€%"Ýõer1»cò¨‰Þž•ðáõhüÐMç;oEÏsžBüÎP._x,h¸Ä}e˜œ^Ð÷ãJ‘µïgu½â¨ŽŸmwæ%úœñ D}]&ºvÙ °æ5‡‹ö»‘(Ì5á0Õú¹¥èu\|^­Œ4yˆ×�ÃÇe?ÒÉ�GÂÕ¢nôƒ1õåuüÓÚþÞßÿ{ÿõß?öø_”RoUªqU;ùšsÆívöm�œQUñx>°=¨b*÷ïßßü/H)aË7ÜE‘2cß¿¡Š %SÛoÛ†ûýŽûýfêúÚ®/ÁYH%äÙ‹�ý¥ 2áùd¿ŽW'ý)ˆÞ�· yK f¤´¡n‚Í­ôk³Ô¯µÁ±’ ° ‘r Ë1¹Êï½Þúáþö†ûý†ÛÝÔôF%éqL‰ÓøJÕ�’ÌÆ_j}M|ô±¾å ¼½�ˆmmzÿŽ}·û "B•ŠìQ yÛ¼½Üc˜¤VªßÛ¡÷ùívÁˆ‹°jÕªU«V­Z5×"¬ZµjÕªU«V­ZõTÊ ÛýfªÙf÷ì9°ÍÎ;*ìÑ@¡uýÂx˜j]ìcäf[Ý¿D Dà4™@³–7 ’\µÈ&³v‚‚ùÊ,bowˆ5Àßèþ�={—Ù2nÙU¥ö°Ý2ss#è„éVØD1‡Ü�·EÔêç+j³hO–1Ë®oÇÚDF_OàŽ€¨Ç%ˆõŸ˜²· mé(gW¨¶³¤t2eÌÛ�©Ç7Ì8”«@ ÝU¡¹B|´�û «oÿ€~ê mèÕk¯aŸ£ùû'å¤ ·PvàœÀ©Kàê~˜‚ßí Í}ƒüR ±aÒ=OÞ-¤Ef€_ˆÝûå@`ší³kSÙ*ÔÀÿcoH³¬F“T{T€¾w�Lda¿ÈÃ~>� °öqôÀ?.)nVpTÙ]Èú_µ•1£É88 `쫽¥ê%1†\9þ:�mfd÷g×qÞ›Åý¯³M}5ÒDg_»‰¹E:îÚ'ªkvWã‚òOôLü¢zþŽÄÁöóUeö(°õAM<ÿ`÷SFBpAù¤O)ºkÌÂ~?mÔ�ñjžŽŸ.ÖžFÆ êì¸jj‹´!ºlY_7!.F"œy6ÞÖæ rÊ¢øxLpª§ýúu5Ò:ºÛL°‹Q™ÝL캤_^É;Kæƒ!ðsi`Ïçó¿!"ÿ+yˆŠ$»ï(M•nj÷$Ul¥ ç œúPw*(ûŽ´Q@UÁ)¡'ÙU…úSUf³Ð¿m7”[5×& NÔôñ¨üš.µ¢ìè„ "FÎ œ36"ð–¡›¹@¤jE´?±ïÀ—²£Ö "¾3¶í†û­ of�߀vfƶmÝqÀwܶr¾!§l÷–¡�‰­-Û–QeóûEõc=«ÿÛïbˆš‹A­Ö·Ñ5 }ÖîïüþP´ÿܶUKÅN;ž�ÏÛŽ·½Bo‘´«V­ZµjÕªUs-ÀªU«V­ZµjÕªU?@Ýßîøöí¶”‰€Þìeé¯ÐÑêÓøJÓ.ÇÌc{¥}˜Ž1žMßòÊu²©n[ˆ0˜²Ÿ“¢µ?j(cµ=(¯AO`e¤Äý(™‡R›hMdjî&ªˆèßTòª &îYï$îFpÈÇmj3"îăF`€ ŠšZ¯VóÛÃêäÇ×%–û�ØcéÛ˜b1 Û÷KWÒ÷1.aœwp[ ¤Zͱà DÛO"s©pЛc}ö–Ñû2ƾ4«† à{/EÂÁÁUBãk>;‰Ð“Î&/:0?B ÍÖÿÇϳÚ„Þ‡#îàÅþŽíaUt³ÖÀ£"Ä£µµ²”tv¼ ¯Œ¡¸r ¢N## ×íöõô³¡K'^5RT  <&æ¼f~Ép ÌŠóNX¸ 8pM&ô§h�9a"EcŠ hX1aØtJÚ�¡)¨õÿüûQÏ?GŸ×% ëÓ•ãÊ!†@/ˆ7X0"&ˆôüž¸8†õ÷¨æÇܳÃ�æÈ`8­�ñ}4�KÄ~˜ÑHfš›x^gõòzö‹¾à,ñ'øù�ü›ÿæÿõ¯ýîïþ¹ÿ`·! ªœ’7U=LÝzÞêŠ}¢Vcs+ü”²E�U¿Ô‚Z+ª;ÊpJضäKú üÕŠ üç”�RFΜ“òJ=àÁl[FJ23R¾9IƒAd.6U2°ïþ™û¾w°=ç'žÏ ·Û›“Æß"`óý¤þÚ¸k—FN u»u÷ûšAþéQϳ¸„äûÜÜ9`ÓD#ª@sB®¹;´íÙ=š‘öZ°í¥» ­ZµjÕªU«V­µ«V­ZµjÕªU«Výu¿ßðíí ÌfçÚmÊÀ—žÝmœgd+* ©)9bÃR¾›Ó9÷Ú�4•º]Öß)5pÓr³f¢a­è ¼�ã#÷µ5+ç‘·kê{tuz·Æ÷Œnáë>4Ò‚˜*VÅT“nÉÏ< Úƒí$îNC‰FÝì}<àw%›Š‚Òh›E™ƒ_Ѱˤœ¦–=>ß*CH!ÕÉ ~üêqzmº ¨ŸÇÉyž‚t™ÃXÀÅKMô‰Øu€‘Ž*õhÖ~Ì©þ5³ CEìL_¨^OŠX�2°þHDÐÑ Þå¡0d6¢F]PjínÝ õ?ûØa[­˜OŠL¬‰!œ࿨xŠAœ¤B�™áí8J¹u>§ý½¢~û¡SépîÔÍ£Ãq Ì „1~yBÄ׋Zimý%s>E'.4°u(¥)ù«5öOQ�ÆêswÐôÃ~:¶IÇS=uW³=Ÿ³Ý?Ý_tˆë¯ª^€ë l Î “=Ms„š{ ¢aôE�°tà‘›qt0!ºî×€Jˆ�9ž%)MÛ‰Öþ4÷òÕÖ%ªo>ž‹  =…Ù¿2Ö×éØº‚þþóÜÓ@Ø;€ò/Éå3Ÿ¼Ë.it½Éžl줤֋€Wݸ'ŸŒlýäÜýÉÔO?ýê¿à_a¢�‰wf&vàŸü~" ºò H<Ÿ¨3D9'˜>cËœнV<ËîŠv©™ Ïw…|™�“™�RÆíf@xöí5W R žLxßÀ9û}O§ì*ùæjüM”²ãñxÒ�#§ÊÛŽm»aÛn _ë‰ ‰ìq0'žTö¢ ’ê䆶38eäM!²¡Šxt�ô{»oªð?ÏÛ±6¤œ�sFɹ“G£ò¿;4¨N’h÷„m=ªiß±ç'T6ˆÖõ? «V­ZµjÕªU¡`ÕªU«V­ZµjÕªáÆ}»!m›¡•—¥s0óQçªMá­ÃÒÀPëÐu6• �°Aêªg…X d²7¡Û÷÷&‰�ïÂ`ˆ·%�:viªöZUÌÀÚ¦PdS¬õÌæ(ЀBqRA# }N‚ÂT´ƒåD¦Þ'nŸãñ•þ €Ç ¤Þ—ím�¤‡ toݶ¬ë+`0ª2±¡«þ‰A-Œ¡¹.$5wƒ)`2vòÜ fé}S›NîÑx9¦t™~ïô?>ì£úYŒ=]“Pò�d 2“‘7¸ av²s˜ˆÁÉÇ„g"`'”Tò¨ 1pÞ p•=7»ödQ¨¥xÜ…B‡mÿEÍ9€°(nyoàÿI!/-6ÀÉîEp Ÿxd€`Î&ð7ÆdŒ¶�ê ½$µG8øŸ‚¥@uð¿ÚÜÌ�cº*Í»^Å�§ácš¤¢JÔs©Ù¶›pŠ—˜¿†\T¶Ó+àÿüó°²>¿§©»U稌×ãžN€ò± Š™Äpmo=Ø”“›†½;¯¸‚¸eÊãÀ/ [Õ3êþöz¾�è%^m¤)n( p;Nv‰b<'úõ•$f–DAXÇH�D�öD>Ô¡¯×°ÉY 9`°¾ŽcíjÅlãëH&Á¯³²ªGzMÇ#ÌïAì™`‚Ñ µ{ˆ“ºÝqçË-ns(8A¼š¦ôr_»~”ZÿÚ?ü‡ÿà/þÙ?ûOü_râGN™¢ÚŸq4AT±ïÏý "{¯¥™}þ¶Ý�“Ý”ý‰ÇûÏçû¾޶N°ßKÌmJÉðÛ¶áíí ›gÞ7%'<HïÖN%¶)È•ü"P«Çìx<ž(Åãm8áv�¼±µ+çmŠ'jÇÞý-B@S#6Ö>Š™ìš—·Œ\ ö”|ýF ª’»!Åusãvÿ–œô€ðûD¢"‹[jýû¯½¯ÖнTßÿªU«V­ZµjÕªðquÁªU«V­ZµjÕªUú‹È@£:^lŸUCF»£9í!+ñ„èí¢n1±žÍ<«_‰¢•³0:D˜u«ƒ8Ä j€’= eÕ<ß¶vKuSä‹?´± ë{,\±Wˆ€–�Íê·¾�®Ôï¥êä³Ô·$„öµ˜�<¹%®î#)X¦3õ‡Ý©+éfнE@ÉA9ƒI¥Ç¾wEf´‚îà= ÁÀUf#04�Ÿ-–ÀÔ³ðv�}ÐOnG;þƒ|SPÔ�»ÖISé…ÝùõÏ‹»~N¥¯i _ÒÖ×vÐ?%˜[C±¹C„�×îÞ}ÉmûSJ �À9+¤º’ÞAÿ&Ýo8T$7g%Wÿ72FRËÒhl㸌NmÎPpSËCÂX4à[ø¢êN@'HVüpÛd"É,8 ñxBb§2†j?Ži¸ðó–0>kM$˜Ä(v¥TWõ«�/·÷TëêFç�Õã<<.Àx:8kÃ\?.£'æcúȧb"ØàêÇ™_'D Lz"è'Òt snÓ¬HokÆ££)SÊÔÍ …§õ#fØ7°S_!éŽ5}>ÇæëŠ‘tÔÇ�–µ+­§µ‘, Mzy*ãZuÝ¥g[y�®6ázÚÖ±;¨D!Ö&^ûü†ºÛClOŒ‘iSqº8ÌÙb(íÃÉ#Žh"Võ±�ñÒ�€®ÓXúgâÚ®£t`÷.ìVˆ®gÓÔâ)U�hŽhßC?öH#¢©Ç§“{Äy8Øvö}ÿ¯¼¿ÿŸÿ™?ó;?Ýî÷´ÝnÈ9#'»? s¨ÇÙzœ`@õý~Ç·ooøÅ/¾áÛ·_`Û6¼¿¿ãñxàW¿ú•ÞQÜn÷ñ\·9GÌÈ9áv»á·~ë¸Ýn€çóÙÕÿûóiÀ¶ßkÜ‹àþV�óN p0].\4Úï=ÎHf«~û[�öÖV#§å¾^ ²G¸?StÒ!±]3[»Ë¾wûþVÕ Rµ–Þ–¦ì$€UEÙ $ �F\HÉïŸc˹Ú±”²«V­ZµjÕªU±`ÕªU«V­ZµjÕª ¤ ž2ìVcnø,n ¹ÕžqO/¬°ÕzÓ”;LÁ^‡ ý  %(1jÕ®šžœ˜è¤@Ý @]µ«g ‘ígbBRîŸåè«BàYènéßÀ7ÿ üÌ4ÛÏ<Ù#{L@pÌî0à*AiΫ©âjuÛwmÑî©?À¦©¨'‹~¶ŒkfùÚ™4àȤý  ª�e&‚ú3(”¤L!IúB±þ�z»õ#݈­ŸÏ¦åä ÚÇ ý™ˆ€)<ŽØëv÷ÚÆÝ‹C¤Ã{h!Mžo„MÔì5�´3Ô\òP)r°9Ww„hVøæðàîæãm:ü¦°&±Ï2�*Íj×¾ ;ÿÖib6üÝV:1@ ÎÙøràèõÎÓÊ;mä Ðïäueø¡sO²û 9ðßbà]½5ò9‰IŒ$€G¶É×ç¹E1„9%€Vµ�Èâ8®‡Æ‹Ñ7Ø}´ÑXWðß×£lßíïòsLtýõÔœÏIÍ’ƒ.¶÷â�¦6ÑDØbweêæÚ�j½øì«.Ôf ½ðg§ë)7 >$°N‹ëbƒ/\AøëŠïS×ëèxÕó)|¹*Áê~˜ÔçŠú¿' `€¤pN³ÛÄÛ2ƒþ§¶u@v&î)ôg⇵[yDUω4“ð"‚O/ÏõkñŘú0ÌÁûM# ??hÆßÿÛ÷ïþÛÿÍÿðïþ“ÿËÛí–¶[¦”X‰y0Ïš; ŠØÖ"r�ú~¿áíÛ7ÜßÞp¿m~í<÷'Þßßñ|>PŠ©ðÙmú¹;"…H¢%ÂØ¶n7shóõù|àñ`"”ºCKˆÌPÅý ÈíPtr²klä6¦áI™}Ĺr¿õq©ŒÄÊl÷4¶e_xc´µ}Œ Js"�"¨4î?j­Ø="¡Ö¡þß¶ )epÄÉZª“xšÌÜ�¶œ‘8Y OèÛ°jÕªU«V­Z5×"¬ZµjÕªU«V­Zõ”ìE*D•íAxSâôþäÎ<ý0gZŸTtþÐVUÿ ÀE·|5qXe‹¿%ªV m<ÐTGçUu«c Qä»HýxØƧè#X·ŒÛ ™+ºv�Ãþ™j²û¡Šc ÂÙÕ¨áÁºHW¶·ýD²¹0Rj}Ò¯FNÀA9ßÔùÌF8P2ù  �]¡G�JIÁ©t!wŽÖÏáw=Yck„ê¦6ŸGØŽÐ=pƒ¯ë/ºPô­ þvµƒÿâîª"v¾…Ä­¡-¢g_sPÁ‡üÙŸ<2”:Xî‹@ª %Ëñ˜‚ë "¤œÿ¥YäC&° ÿS€:ƒõò²scä•âûXt­®GU IýEª“|^7Çj}©~\�Ó€ÿF°àäÇ]M¦ëò­bÆ °~M=@Š/‚èmi3�=Z­Ïï#"åzÄybšc0fW€¯ VŸãS÷^Œ~r—_C8h\D£}ª}­¾ÿ¯�hè¯�€P߯)pÚéA�Nn‰~ á ¥|&­)~& €Úú‰/>]­9Çø{=âÿ§¨”ÆÈ1jâŠà¤®ò?›«¨1 ˜.ç«Å·s\ÎcåÓÕqÎ�¸öã§fûƒëùw\R>[°�Ì�èÔÐIôÑc&”„Ï>�ÿ–@ÿ×)§Ì)%0W°ß,´ë=[ôDÎÉ-þ·mÃvß�rÆ–2rJæ<äD–ZŠ�Þ2Ðí~)‚î üïÎNöüÉ¿§¶éöþ¥f»GñõÞ¢—2rʨÙH‰$b2—ƒéëN ©2[€±jÓáúsµQA»"ú%ÆŠŒãmÇØÈ’âíߟO<s5p‚n7#äd}J„âä»/«�D1Èw‰¹÷Sû›êË'hÕªU«V­Zµêß³µ«V­ZµjÕªU«VýUkE) QÓ­SP6�jÂåhüÐÁøŽåÐlLg�ê�¯mÛÔ·ÇÄà €*4®5ÂÌê»Û�åÊ*€­Ýf‘?r¬9(܈‘À”¤ fÅ'í …Çˆv@¿)ÖlâVÔâJÿw�PàIÿªˆf|8sÇãÅlã 8™ÁÁeÕ“ 0š2y¨öøK¯¬º1[Fÿ¬Gæ×˜Nß/ESŠ�˜�ÚÔ¹ W8Ñtî^5‚æÿJÃuV'7Kz%U@¥°L h‚ô#@ –‰l^ïP2ÀZAÝ5€½iìÊQˆƒ7ClþI"�CѦ9qe pp \Ç¡³ƒî ù1"̯/Ÿí#òwP>óTì'Ô�¯ s hêc­8øOãË7ÐþO@¬1p¶X V@škƒø¼/îºÀ2E€„úó|£ë±4bØg›õãüÖ0p#Î�ÛÙ¬ý´ãË¿è¼4'U²MÝ××õ¾¤Ÿ÷¡1Ç^›ø§>úˆ´ ç¿ MÕKä]UÜÖ,ÆìÐÑÜd˜ÝÜ"ÚÈ»cA$°c.ˆ¾èÙha¯1Öä Ãý|/äëÑ£_/–.ÕÃÔä >:`Ní™SCN\ƒ£�“?ôÑê•©¹§I#‚\^Çèõø¼è’–'¢ªáÿŸž†qé¸îýèbôÑEË�GDþÜ¿ñ¯ÿŸÿËý÷ÿóÿ[›Ý*Y†À Þ2RÞ�o7Üîw$"äÛ )o]Õ_ª`ß 4D5¥wáqGžö™ËÖP¿EÕZýÐÍ}(ëf×—œ»M¿T�p)w×’”9o�*~™0À–rތİÝp»m`&4bPÕÑ=ÄL0“�¸•¸�ý˜�Ѐh5·$U”²ãù|âùxàñ|BU‘s§Ô Ñ� EƒˆÇ°þÌ ©ÿn¤‰1–ÛyXµjÕªU«V­Z5jV­ZµjÕªU«V­úª<+Šˆ…M+L�߬]ƒj~S¨ƒþ JêЀÚöZxß³ç]fz°¡BAQŠŽU4пÛàz „$…T𔤠Üh•‰ÌnÝ,bMýÕ€G« ‚€êvù¬32w(îí±‡ÛÐ�ØÃw yå® ÷çéA¹«:)–]§Ýfùýh58…íH“âR›*Ö졎ÐÙYûÇWÎMñÀOÁ08ZHh\ýÐz«_9–ܺӃ“ZF²©ÏÅÑê�uïÀ½¶ó É„¤ä:,£@NÌg³«Ýyœ7íc“A÷ÿzÁ@a'³”¼œLÒȧs|E¢8û=íåȺõ3ÐÀ{'á@m¼Št{ÿ~èÄ¡­‘ì@8“BvrŒuY%ËÜD„¹0תC‰O§åàx¼t­hóS_�±_lã�ü”ëhšø;Gñ³NïP(ØIU¾öû�Å,ûãùŽJøî¾ò•yoL³¹¿Ú¼¦ãZ¢nâ ³m¼Î®0ä@!Äã/‚­{‰i0™ë´n†&ülð§¾ù!’f:ÕtúlŒqéĘ@z;*ÿ§™­:ÇMГC‹6W^#’ƒLpÀùÒáÎWá³…6Rß�ù?zW§ˆL'ø“•}Œ£Wcá�þðÿ{"ò¿Ûk}ÞjÕ*¢œ¸6‚aN ÛmÃý~Ç^vfp²¬yQÁsßñxGr«}))elÛ†œ·q�ÿà[™]~Á¾ïÜß÷'öÝ¢žRÊxNÉ,ù; ¡z<ȸGK)!ç#™QppW�ÜTó�Á@c°]5i^œ¼èÔï »{�ó"‡ð|>ñxÇûã�RJ߯–kw`š×I{mßwH­v^r3#kžâM&RärXµjÕªU«V­:Õ"¬ZµjÕªU«V­ZõT©¥Û£Lg—X’ ð\XÖûžOÞ@#Õ8\Ä8^ à@gû¹!Ô¥QÈ8ˆNpÌZÑÀÁóCæøp7ùCïÉúMM ÏÝ®NDpëÙãÃàè~àífvý¬%Àý¡´Š)â$X t“mGÀ&`MÅó»á}ýñgßP|ÄÞ� ´óãuµn�ÐaßÝÀ¼Þ®cDÀËtüóÂj?ެ;jxEÆßilŸ<—údÕdBÄX‚õ@õ¤ò5`‹BŸ«@Š€Ùä (wvÀY�+Ε‚@3C+™Rµ²ý_5‡Ó,ÆO�šSu€œF~·Û\Ì€+MƒSô@w€‘:o!Á‰!öâü9Í_òyŸ€gKÓ ²ºÚ_¤“L¥/8…ÄöÅ!3€Ù¾¤)ýÇ�T5Ö¥ñ1¦ÕpÛ ²�1äèÅšöº[>‘"`œèk†S„‡ý>hpÎDïm6ü>ê58EøÚÚ']K†Å7Žó´óÔ)4“œ s=H®#þ!ô ]íÚg»ô°ŽÎÃ_‡±_¼“^¿ot…óÓŽåð”Aùh`Ð�'ö!ë"¢Í};ëÔUõv=¥~=²u÷šÓ¢¢_FûOÊ{`ZK¾òùÓÒñ³ÎÒGóL¿t_¡‰u –Èê_ýWþå¿ñŸýý¿ñ¿ß÷½æ¼ÕÄIRsŸHHyÃm»á~»wW (¥àýñ@þé'À–·®f¿ÝïØ÷PÅ@î¦poç¶ylóù|ö÷<žO<Ÿ¨’ß)o} UTe/§sDd„LvÒTÛŸ½–Œ´\ æXé¥V$w$},cœG'©0os6"DJ¹¯7¥³ÿ>±?Ÿ}슫ÿÅ£q Wä”úzÐî¿J- w˜Ú¶mº¦ÄöGÇ€U«V­ZµjÕªU£`ÕªU«V­ZµjÕª J-¦²MÃÎÿ¬˜´Òh�íY± ˆ`¹ÐÀ!ù½�•h*tYØþo6š €ˆYõK³bÕî`Ým£aû5Ñ÷%tR…·êmõ<Þþ°—ædfreqb¶ìôÞ‹š¢ Úc `U{p® a©B ¾�`e!1A«­êªçêýÝxG;ê#ø�®`6Us�Go$„˜ƒ*Ð>ƒìlÃc\v°’¦£zöðûñ4Làióýv— ëLMí:xpŸ¢žwíN S³^Ù|GÀƒ¾Ž=yŒElG³“?q…¡áÕ¹=¥ÐÂuì×­éêúS¦aOµöó0HsŸ-UôrïaMoƒmJÑqœÀEÌÅa©o„•ódhcPõËàÿGêiñ3ëòžk¾Þ¯þøË?øƒÿáóñø·m+yÛ çTÉ'ý¸ïHÈۭߨû^ñþþ½ßCé]zýývÃ~»¡”–ŠRêLŠñŸSJý{â÷½ôküóù0"0lûï7w( VìRP¥ôû ¾ýxOˆ8Ãõ…ñЉp"; ~ìµdÔTý$¸/„{Ÿî:ÕºÙíÿSÊàÄ�ŒYkÅ^vìûŽRÝÙ€úU·» D0¿}ïq%P$–~oÁ‘ŠRŠ}9 `ÕªU«V­ZµjÕ¨EXµjÕªU«V­Zµê¨êV¨ãñ.ºŸ»Õð!�›^¨RiÖyOÏx�ŠG:‚óW¹Øã÷†3 ©ïá¬Ø"¢�ó³³qÊo„bÎݱ¼©Ù(«ô‡Ï¦ä�ª°~ *-âÝZ€¹˜U©–© ëêhg퇠¢ v³csžÄLèÜÄHsN0êà?[¿KPé!XópôhÅݎ圜@”B}Dðp‚þÛ 9Ûª÷MutiÞ-®šžý |è`p�‘mþõOYÿ T«“6„Ðêöþ:ô£Õû*™Ñ}ÿ;`Û7î²ÿ*ˆ�±7Y†“š€�îIÝoþèæ0m[ƒe¿ç€@�Zm>¹Ru>—AA�ÿözÿ�„óÕ÷¹Cƒp�’G%4WmÏ0Âxkmr° !}´�íX´Yƒ´}Wœ'NàðÆàÍæˆˆ†M+|h ó˜ÅÕàÔîâAÐsÖ=%~TýÇ û ]´b€ð“’œñ*’¬ÔÁq‚|0þÛÜo$š¦ÈÕÏç<Á鋎�Àý@ΛÖyJ¶0ƒ×#ç�ü3«ÏUåš ¤SªÀü‡I…ßæ.æÄ×KuöL9%ct»ÿ`½ßœRúÑêqx^‘êð7i×b¥@R JÛA-á˜pyžÛ5'�mè ëð+òÞ—úô³Õ:íÚïŸ ÔË�Ñé\‚€Zëïýí¿ù¯ýÕ¿ôWþêÿ1§¼3¥�S‘j÷ [æ�A$?ÒÀ¤B>³†Ðê!Ü÷ úÄ@T�²}n@<#V8ãc³s{pPíÖ�ƒíóéLœÝôòCã ÀÖl�>¿WD€?Nµõ‹–×P�Š€wµÏôtø UèãÅ+LÙè0»# #pw?Я®”Sü Ó9�å¬ÓtñÒ�Fïóðýø­Ÿ¿›‚ËWc^&/؇k­¿÷wþößúËÿ™¿üWÿ…´å¬²‘ªès7+ù#�,jk{т {ÞQëîÁqbÅAiSôÛúÏLHÈ�P üß°m’çÞ7»üRL�Ÿ’¹Ù2êQH“ò‡¨/0].aÒ—5:%Џúß¿T-&©Å8!©ß[÷¦ÄÜ×Û~Ѿ_õx�?àJlüe&{8‘ ¥„ÄÉ"œ˜gÒ�÷™¹&<ðxØW­uý�ªU«V­ZµjU¨EXµjÕªU«V­Zµê(&`»mP­<©žE†Î/dAOŽßí½Jp�ú8š+ h:¦ºù»o}(â›�·H³š-èiëþ0¿mŸ[@ÓÖFUYSÇÇŽxñ ™š×s6u´A6ešá›1ƒ}@oÌC‘8K˜Eˆ2€OmÄ%@À®×ÉRÚt›zŠtW5Kú°íñ ßÜb6¯Ò p\�Áùƒ²¹ÂEJÀ„Á"¦}>pèÛ¯[4�qxüܧâP�ç‘àõ§âz»%Pfèn„#|8¨×�!\@_MíIPwü'ˆºÃCWÔ£»U¸�êèëÚ D¬fï¯u�:i �Þ6ä ¾ÛäOH¡G0Ï€ê+Ÿo“é�÷¬±Nx�4âÎüHç\ Tëw€µ1�AÅY0ín<ÈL8D+àB-�`špØÔixÒqÕ Ç@ÇãŸ÷ÑWºXuFZ8ä}GwŠÉú¿¯%îMÙŠèÒ1ç½kk£ìõÝþøŒ!žkÑáÈåHàù5*ªú[î8…³@¸ˆ P|,3§‰Œ6ÏûÏ =Âæ|8¬ù$€æ3¶{í‚¡}­’ᦂa$DÁ4}W¯SPbýþÅžHM×:tJ´8�hhX±Ý-PäHöèÀzp­™·ñႌ‰¢¯Êq‹ôeW˜ pµƒk×�϶«ªøGÿèßù=ω9åz«YEëóù�}ßQdXø±™�ÀÔðí§V·¶gF­‚òÜ{½‘ªï‹‘ØДrÊØ6³÷gN]É{ÔÆ¨ £HLiü¤]QÏœ<¡…Q+C4ù˜rU>§îÔ¶)Õ¿Ü {ùg2¥~lŸxŒ@¬N`Ø °å�äÄ„œìÑsÞ6äœÀ4\›"¸ÏÉœ%’$äœ è¯)ç~Þð_JÁûûïïï� ‹°jÕªU«V­Z5Õ"¬ZµjÕªU«V­ZõTJŒ·Û ðh÷ð“µë°×§RûÙmºÉ•õœ.̘[î4Euþì±>Ù_+MvÕô¶×¢„*4”ÛLì ·\çƒB\#È{:ˆ¨+ŠÛmÃ*$¦ìv·Ýúÿ@&hVÜ­ßT‡B’‰ `ädj·àHЍ˜oWMÒPã…8‚M!¡y¨›�Á˜Íù´‘¹øÏT! 8~²õÜò½Žmø›x©ÔèPh+ˆp�cð óQÀø9[»èb×q_° >XÓC |W)�ʨ `#ÖGš 0)Tš AÊ?o¼Šµ»»O´A5üH*T¨VHsà¶À-Ý-wÀ¾ð:Ä ðŸN™ëgŒl–þJ_pm6ýaõC aÓß·íN#P­îR¬úɾ8±õÕì ?�©àÒÑÞÉá>Þ4"£á|‹(jm1NÀ8Ì„y¨Í fúµó(¨¼¼˜Úºx Ç޾~´n%öëì‹.ºKwã=Da«c F#*�ûaþù¸N\ÍæË×h8#´sN�è¥aÛ'RZhÑÅœž,0Õ®úBL®ªŸÙgb…èšvíPë7‚ ÏUšC[ËTÔˆ^¯áÿó‹H|púèÇ :®1Ó«·W5Ì%¼XGýúÕˆAt�ÙÚw:Åÿ·{í¡‡û}¹dÏ˽~ÃÇg7\ƒ½ kýgþõ¿õ¯ýþïý¥¿òÏ—ZžªŠ}ßµì»Öj�$œ’YÒûNd`4™s̾(€}/x<(ûŽZ«Ç§Ì�4U;ƒÝ  ƒÞœ@\]ñÎÝŽ_N2Ø¡�>öš ŸáJù¼!§„Ä„*n©¯Õ¸fªfåŸÍ9 Ô*¨»JA-Õ.U;`Ÿ‘“E4@¼×¼Z[«T”R°ïÏ)n€˜‘sp‡ª"gÛvòm§”|?)'ä”N}Vkí}%Uðx>e/øþý'<ïx>Ÿ(ûÞ��V­ZµjÕªU«VY-ÀªU«V­ZµjÕoX}ûöíOt{ô ’BDÿžëCýD2©¿¶¤òuýwÿûÿÜî·]5¢)>lRÉÁü°t@F ÿ?öþ4Ø–å:¿µ²jïsî½of $1�G@D‚ LSi%ÑTÈVˆn†Újª%·Õ²:lýPG¸Ãá�ÜþÓÑ­þÑŠîh[ÑaK¶HM4%Jâ$š"À$8A"Ä@ÄôÞ»çì]•¹VÿÈ•™+«jŸ{IEøIµ€óî¹çÔ®!+3«n~“†ü»Þ8%§×.„£®Óe›¸)îóùI²L[Í e0Ÿ]¾lɼ’¿žeP«ØÂ²W̺<Üb'Ûò¶áðX­xRUÖ—¼f²¬[ô©*éË~Ä\4ÛŽSªj×âp^¬r«bΩUWŠgm¶åTÒ­©�og®àÎQ)ƒ* ²ÔtêÆYî;�ƒ(5 qÐÙM—ó ZÁè+õÿ¦tónûðÇTŸ ¾Á^À°ºµeŒ2Û×g0\ Ñd%h*˜¼€�ý?˜@Êõ\ÉÚ‹:ûxSþ²ª? Älý9Ù v.ÝŸ>².2`a›O´×ûŽƒ%2˜Á©?S–³Øµ±ó¼äÐÍr¤©ÇS&Hµ)àXÖQ}'s¶ùÅ­ +Ü6š] 4%è,¸Š‚$Š´…ÿëF,Å%ÀØ“ :”š:E½·Â.D(Õ5ñDDû±ãÉL6—ߢGõcÅ�Òq4GŒv Ô3Œp´j ‡�~¯U]N—¨FZ§úþ¯(°¼ýüRÔÔ­=/~¸¶ƒ:wR²Î!Á�•�|“3�èùnü_F8¨=O/±%Ú)Äú> wy2ÕA ÞO\[«¯›ë‹ Xºc•°×uÆúü/ÏþGж°GqÇ'.u ªO¾Ç{’tû¢ÇØxëËíŸ{öSq:Ÿ¾Ð䪚b”$ITU3ÎÙò¾¸uØø !@E0Ï昕ÿçiBŒ.> ZÙ÷ ÿÖ;2¥~0;~ Ïm);ˆ¹7ÒPàC‡!«öa ¤$ÎÅÀÀÍófŒqž1Í3RŠ â¼#rC#”± ’î|çM1bš&ˆ؈ ÌŒqktÛóÁƒÿÃ0bóuøˆƒJzäXÇpŒ3æ9cžgœÏ'Ęª+A °ÿ#o¯½öÚk¯½öÚËÕNØk¯½öÚk¯½öÚë×] þ¿Ž€ÿ£®qeïí\—È×Ç#ŽÇc§ÔímÔËÁ·?ßIOªX€ËQ¯öê-Û›\Þl¿ß@UkÚÖMðNšA1Ê*:õ;çÅo ”Ý D¥apU%ÇÕN6[Úr/D¥)– B»«v±æíg\ö]@΀lSôsÝ>[Ü DX"À`b×F\ •İP�ZËf¬´‚ñ„Ý-¦No7®5dРìè^($‘�KÒ˜s@ø[ºzïT�#è›ûƒvYØí;ZàòéT«kÜe;çyµÝFœýJÍßw—±Õj}ŸeQ¹ç+î ‘®8éÀ{ŽÓ.¢—g¯‘¾;ºº�¡((VáH1!%…ÆÜž±œ[�&Y¶ÝŠtÝ„œûusàRµ­]3ËÿÎÆM¡žOeC½ïæbíÚÊ7õ£žºRïS1˜`ªÎ~NhýÓçÖkË~']Ó%è un*[ã¸~¼¸‹�^˜Û# ¾6ªvƒZ!=ÙâÒî,nj»:ËsÕ�ÏldÙo~fÃ`ËJ½>ÓÝ|¿á.QÚµ;$$#G�Ø"ß«þ €>ϱfÙ�ã˜UöƲ,ÇL>aA/Y’o¤½g\"Ñdu~‚jÏçyÆt>ã|ž0Mgˆ(† ã¸pP¨Dòµ¥”*_õ½ÀÞs% ¢{W²sSÙ7Ug„‡Ã˜Û×bÊùÆ8¢µiJ)ÛüÇÓÔÈeß™L0àp8îÿXÛk¯½öÚk¯½örµöÚk¯½öÚk¯½öº³.îÿ*@ÿUD‚ÇÙïïIàqÈ¿�cÆÑ2Ã�Õ4н(py²¼Rí/ÕÛ‹_ušïÎ%˜:‹û¦îתˆ+yÖ¸ÚçK*ZëE;Õ¯íñýùð¿ªÛˆ;`O´)Z €¯NHI�}9ªr°Xÿ‡’ÁKÔ©Þ‹n�E®6ü ƒM�)Üò¯;�MZAÒd"im×GèQÅÝ&Ê¥CùöËêW¢þ¶zÒC;gŸ›ì«>J[ É‹sÑF1”H«å4걚âõÑÒn@t6å5 šèbÞ¸.~w÷ØÞþ�h¾k× ¯ÈÖŠ«‹o; Q›dœYÜå³EɯH fÃí u'dgJµßÔ?+Èh–øÖgŠkïû±Úq€¦Î/ƒK /Ö“±©›í\ŠÃ†YKC%;hs¶¨´¶kÓ ðŽ�c¸»—X/m®,×ZÆ–$Ytƒ]ž¦fµÎP7.bÚhîÜ ™FW–îÔÝþ úëåþF…tTÃäÆ�÷ÈWj�Ç2ªýÆ�Ó‰à_»9¼úŒ”˜çV¡Uõmg¸ᾊàX:´ùD/(âk¼Œê…1J‡0•v-%ç«éÑñÝjÓQÄ?‚:RÅF¤Æ‚«�Åãxù‹„ëjîºû_¶b ÿïpâÎYïš•VIçÛ;žA�´Õ亘X7éqúû+€%§C>;~ yÝ»ú'¿í+ÞþÕ]D&�N’ap8p¼:â00†¦ìzr"Ê6úqÆù"Åã8š­ý�@@ŒZÁì˜íóуªmßœBÈù0 HÅÞSŒ Ò‘!ótlïfÕŸRB’F>H’ )Ù;E›“‡;†àTý’ шöÙ ô3C\ìÀ¥÷Ú-2@!vcð‡qÌûœçº¯SþOÓ) T¤ºB À`d�ÃqwØk¯½öÚk¯½öêÖ÷&Øk¯½öÚk¯½özqÖŸøÿ·J®¨æiÆ<�1ÏsÎ!%ÂáxÄÕõ‡ˆ*‚où¾�T„*ÈXÇa@à eÑO ØS±.ê²ÂKæé<Í8ŸO˜lÁ®,ZfÕÔî¯q8\aók§¤¼p(I,Ï4f{t³­€©ä,ø þf5TN¹S(‰¤œoš´fзϔ|øbe*�”/( ŒÃxÀ8Ž8Ž8FS')Îç3N§[ÜÜÜÚbcÌ 23®®®pïþ=Ü»wWÇ#†q„JV(�Nö¹Û[œO'Ìólyª¹M˜m!y³íéñàòOǺ€:ÍnonððæçÓÉòT(qšV`Q±ÝP3ŸÝoÑ-ÂSS¿®meõÂÒ½ïøÎ€¤Š‚I‘–‹½œhýÆ+í¢MÙ [TV˜ =·q Fv Jðq%Ã\Ù_»Sw¹í=öYÀÁꌮbêb©}¾ôÛNÙ¹��ªhÎÈ5Ë\‘d.Ö†!d‚‚µ‰TÂ��Çþ^”± b¤‚ŠDVBÂ^®º€¨³àn‘A8^þz&‹¾ÝVÕ©‘±Få6¼BÐ;üá/Dtñ —EäkºVÑ;-Z¹g¼Zp#Ï)sÉwÐ ¢P#2° þ�Â@°ÍÙús…êÙ�qgZAmj|‹ÁÈQöó«û>s%e%¾‚Eòï—à?ÑÁ‘ ØIô €—TÀÙdµkš‰90‹ö:šƒWØm+—û’ý•l°è+{ûz\û¹A¾•¤ÐÅÕÛŸÚ ¶ºîeð¿9{¸ñDN¿(õâ0¢~¦¹0zRO±šWÑl.A•£Ñº‡¹wûFCÒ�VƒÈÏ1•Ö£.ŠfS�íŸEýM¤nüÑ¡.�æ5€­Ôâ`Ê~tËþŸÊm¥®õêéìí«zßõ·µJÈ__ÀÙÚoKUG�@Ku)jv-(�‰ ø×ºh^”t…jª•ŠÓµð¤€0’r&°DÛOFà†aȵñèU®êû±‹V(D—J”éoT§.]ª?[öêÎ"ºTÍÒ»:+TÀ@;p¬‚Çä6Ýë{…î¾QŸ›}qÍÞƒTzi»å|pm ^_`°ûj?O€²B Ê'Íø{ €‚�-ο+ [î´Y•©¢ *ÿÄB’m�‰ÙÙù»Ó¥þz #¢¯¨óa'�Ðß×2ÖC@×ÑaÑ ,F@»QN”¨·þ/’ 1fËO @vçh–ô "Ž‘ÄÈ 9�À¢™±Är7î­ØÃDêC…j›r`„�÷ÏñŽ>ô˜¥ºš Ð©µW±ý*é‰<¥Ä ÒÞ%ã‚®„U¦UC-ÏÁÇSd”»¸s4òÏ–ß�»æ€Ò?,.[Á¯3çËn¶œ ¶\¨Å‡¨Ÿ µ�„q¶.Þ`£)µ{†52-ǵ\?·Ód‹u`{a"çfÒ÷ýEˆ–@¿ÿÄ2î„ìü”îˆCpß,Ép*ýócu«ï²Ôw7¡ªôuÁ¶Q­„þ»0ô$�d3ëŽOwEFÜõñË �³—Óíí·ÿ‹_üùÿþs¿ð qžÓ¬*Q“¦”2Ã4aF F¦‡±’/K1Â�3é‰) €9»”${/H)¿†”ß猩¤P$(" I¹E‡!`�8p~?I1ň8Çê( â \Q&¿jí+ù¸ã ‡)0ŽÇŽW׸º¾Æñx@ÆL~UAœslAJ©ºwîò¾[H,.NÉ[þûwãöê÷! à�÷ !všp:Ÿ1�ÏfûoïïÃ`n ƒÝ‡|¼8Çý‡{íµ×^{íµ×^®vÀ^{íµ×^{íµ×‹´–𕨩ýB昕CcV×p[He#šU�ᤄ ëüwâ*¼ýc¿ðÏpÊìšU½°1/ª/RÚR —ÅUT°YÄŸY’År½3ù€3ñaj—‚`ö£L\3àUK³ ÏÔ öÀÉm˜”À< ƒ”)«—bBJ„³{Á•H¶@=1#øÀÇb={‹³ê<�1�OH"T@m2•\¶\¾ä}ÛN¾†8Õ<\n»WÙf¼¨ ½XçÔ›Ò•IŒ`aà�d;î ‚Iûœ×ZgA: [E��-ÛŸK@Û÷1«#\Ey ²ßGÒ©d\Óö%Ô”rY¹¯H)/Ò‹*©ê›=~Ÿ››)²ò.“<2ñDUcJk޶Tà¦åž+IRµõ­×á¢rï �SBè·´œK²A'¿-6ö.ß]—`�ª;®ß×]¶ä­+«x/ô\9tàùž6-Ú»càQ„�<Z‚rVµK”:¸ô{ÃÉ¡Ä8‰±Æ €!’PXGÈ xB>KÓ‡Ák7‡a݆.`q¹-f€óýÊx¾s à†�:÷êÝÈÜÈ ʾ%Aæ ˆ±�;…Ä`ºq2r §‚Ð…¬ °æsQÍ„ƒ&síñ®aZŸ¬‘–µF #AªãK�Ê;çý­þ(Ú?\úÁÑ=Çh hR?Š í¾®C)È�V¸©_•wÃ~)[§�máAàâ²ýl­„œ>w—JîŒïòä@¯í¼¶jÛj¯‡t#¡)éF,͆UüºË´èÖgÕ͵0ÀtAl°1Ëð„@Yg£tsP}à¹vz‰ð²´äybí_J„±å3wÙ1<ñ¡ïïhÀ¿'Ðmžè…Ø g¥ADwF ¬~E�ñÎùÛ¨ŽÀ†Ëªzõ¾÷þò_úü7¿å;ˆ%J”sJ‚)“Ì Š˜q8DŒã˜UìLÕŸÍJŸ9äéO³sPJ‚”buê»ië‹åý7;ReÒU±ÉÆDŒ$Ù`ž&œ§ ó4!!Uç,-N[Ò¢…ªs¼BŸ *Ì8�¸¾º‡ë«+ŒÇcþ7ƒᱸ ˜û‹wƒjïTT‰«e|×ÏÔ÷n#FP~?ÎíÄ+¢0€ìj#¦iÂÙÀ ƒÿÙ­à�ß—Ý>RJ¦ý‡{íµ×^{íµ×^®vÀ^{íµ×^{íµ×‹´xò—*™‚†bÖ�´â ¾#ë.ª:ª*kR$I*1MÓù,ŸúØGðÄSOÐSO>‰ûîá0”¨å™ç…y¯Æ#(()&œN'Üžopº½Eœ'Ë�qšSäºè˜T#æ8W[õ .iÍGSçÛ‚a°kõ Œ0u}à¡f�ScÍ)a:Ÿqž'Ìç ’²Dt h¿:²E+e þt>áæö·§[<|ø779àt:!Æ Â0pïþ=<8=‰ ôÔS¸wu…'<‰ëëkŒãÅ4ϸ½½Å³Ï~ ŸøÄ'ñÉg?…ç>õ,noo0MSVö�îÝ»Æq|€ãx…ëãê@¼BÀ@8�···8ßžpžNЪ ˆÁÀâbmLXæÉ7kߊ':ÕþJ¡]¿o¹ñ Ãk I5 Íàwg�¶hܧ5«¶‚0 (ªU¤ªÎ´[ïó±)°ì”œêíá{%*qA+èžjÞ3Sk¹r^* Ä—” ÝàÁ[Òf!]ŽWÝÙ]X¯ºí»Zº™o(RËf;Ùç?ÃÙ–÷æôiX¿:ëk¿�'„¸´gõ}«9~ô–Òí<ÙÁ|º7ÕïK~Áfõ˜×e2À]àYq}0"R°Ø†B>Ñb»wp02�)×¥L|ÉwZ@‰™¦8W0És°¹Tê•ëÀ¯‚òKð’î¼¾îL–‰¡m?ÔöÍ1PÉ %b@"dž¡sRÌýê„6Èta‡ªjDN]²¾'êŸMŽdEΩBW™ ÇÕŽ|å›<ÿœ*J}ÔA}Áè‰)ªwMî�X»¬ÜîPÿ_|ˆlÔt>Ã�üà÷Õ—~åWý�ˆ¨ª Ç(I’йÅd÷‘ü^Z¾’ˆ9K lS%¦1ǘ㪌XÈ…@éTðd÷W4!IùòVû!¿ëJ~ˆ¨1 "E¨Æì\dŽEùØÉödä…ÜnÌ  IbïÜŒ‡1Ûês)Tg©Òwš—û·sý³1SJ�”*pO Hy�çÐìÿ‡¢ò™$`šfÄ9b:O˜ÍõЉ†�cÍŽGŽGŒãhÿ¦HÖÎé…9Fìµ×^{íµ×^{ýP;`¯½öÚk¯½öÚëEZEEDÕ"ÜþÌZžû@xVÕQT3 *'I˜§ΧÓ0ͧtbæÀ�iÆñI¢1%‘$J UQ�’TÓ,”T�˜¢¤”’ˆŠ.VàŠ*-«s2 ‚«†ˆ5+}v ä"™,�,ƒ©ò¹W!ï—C€|­dœ2C‡ DÇ×Çk\Â�³R-×=ƈóyÆ4ÍHvÌah$„Ãá€ãõ5ŽÇkð�­¶ç”pž'1bL ¦9âööÓ4C$�„ÀÙþ.3Õîá<Ï8Ogû™æ,SÒ²;€q:�%¢O….FQðw¦Æ ²„��üc8—íªb’’TżXƒ.ƒØ�ÊU}FìHÚ©›}‹S¨§%ÚÀ#˜ØœÊ©?(K쳄önÕ¶ µ¾Y&‹m(Ä ìÓK¹ÆÚ·­êZÌI & h'#¬p!$¨©}{�‰r{CV†Jjä„Ò÷›S?VòßÕý[žŸ®¶€¤»«ç¼°÷^yàI/¾''¡ôÑÍ®¦@îÀäíÖöé¥�9”/�áÜd0â�¹˜Ô±Uâ,ºÁFõÞqÉ Ŧ8¼‚õë a„œZ¿»jN>!ÿNªÚ^³š¹¨ùëE•É@M�9ÑÀ•6vÙÉ”-þy[¿-m/Ÿ_t:]|DÛ‡8ÿ¤ë9áR\luF“%)hjЙ>Ð]ó�:¦­LJ#4ƒ5€^ÛIšÛFS£úï†.Õö&¬].�tï–ƒRî&.»yzYœÞPºfw'£ùOÔ)ÿ�IC}÷cgí¾â·¡îxä"&üó•º÷‡Ç*ç\Cw=–ô®¾ø;.ú­�þæÿù|{ó“'@£°DIŠ˜Éæ²KÓxÀa¡J£YÿÙZKsÌàÿ<Ï ¤6¥1Â0˜²?G?Áb¢rÜS2üŒaL¡9‰wݱw™(æ:-V Þ4‹ýÁ,ö)“º¥úûì:`‘H5Z‰1„„´ÍC5© B¶�ü>S>÷d‘dÇãã8 vÌ ¾9¤˜�bBŒ3noOxþùçp{{ƒ”†qÄñxÀÕÕ5®®®p83�wŽP=×s‡¶×^{íµ×^{íµ×NØk¯½öÚk¯½öz±Öÿó?÷/yæ%ã,¢I“Ц8O’’F FÍIdN)NPÌ�ÃŒA•EPŸ¥f’J[0f,,@©Ë1- zª q¨Ÿ) dEP�†¥¬Re5£UÍæt¦Ú"Bv¯Î¶«I4ãD p8Œ5kôp8bG#˜qŽ8ÝÞ"Å„Ûñ) æ8cšÎHI@F<°{bd†Q�JgLç3‚‘Æ1ï_$S%s ÌSÿ×úÓv«ù~M_ÍöVÉE> °²vU�dpZ Tõ6þÄev—óUKÿv.²IéÍž6‘Ë7FÓš…V°…!Ç\,SW4þTâ Øg2´�.*Å@¤ þ©ÆA°ÙÂ[;ä<4óýÖ°™ðAapíëÁ2kq㡵K!¨-¤çµx‚f;mÀµø¬oÀ1)º r­P;O-ŠR4 ¾r dIÑG€,-ØL€vÖÐ~¿®'ÐÒ&@m§[XÛ¯Ù—ÏÐ,�³“Ûñ8·UÛú¹�ÿìVí31+B5)Ê È:x#Ÿ€� o³¿Å\ØTÐ/·iÊL.`~QÙ/2&°0:T»‚ÿìntî×S¶ý—ÔÎ�‹êc"é&wMÞf¿ÄP·+|ÜÈâ¸%Þ@à÷eùì¬\$ŽBmîâ2æm>à2æ´…š –.ÅM`û§ýYî+kð¿›Â/Œ¦Å&–ã]mˆ6Ç^Žk‹=q¦;Ú–{¿¢Ë‹¦þRìç7‡kwDunëöQôêò2xÛGÝýªäµBÀ"Öf=uô¶ù]wî!~oÖ‘ fîÛJ@º;ßËöó-âÂùÐå©¶*û (ÛžkÚ9ônÔ¦¢ö„:ç—õ5ÜÝ;½¥‰#Z,烋ý¡}¶‘c¥#7è ¢�5—�Ç£ ¤”>ï�?òÃÿÁ—½õíÿ-M&RvJHÈïŽ Æ00ŒWÍÕ €ˆ�DSÌnW)ƒáÉ܆ÈÞo2`Äx0€H1»�h~G˜¦ˆÓù â��†B¶ÈŸæ qα)%¤(Õu@EÚ³“ÌÍI PÄ0·w�”ó4cSŽ1à ã0ŽtNÛDî¥Ê{~~·M˜¦ 1εÅH)��;C}OJ)f÷¬›<ÿð!>ÿÜ¥›¢¹ô/.jwRSé’Å9°sI�œ¡®ì´¸ ³�‡Á,t3!„’ QVʱH%”& ;\Íêe¥ †°‚ÿ”‰$ä"D�$T*˜ÖÚ´)á ‘ÈkñÙWjßq¶Ó 0r¾:9¢ì#%sPuØj&;”¾¯ºa+mÈí y§4tØi&KpŽ—€ÙK¹ˆUy0èn+ç^ ^éëmºí›cÃ�uç¡ý/%g" Sv•/€²SúÈðjvo€Eo0xmqBÕ‰D�$ˆÉËO$+ñK¶†8À;£Ü—§Àè{›ÿrcKŸ²ëÎÿe›Å½rQPÉŸM ˆ)ƒÿÀޱšZûX¿äª°®'œÿ_ˆ ¼öò`rç]ίܣLˆ‚‘+ kˆ5º¡›o¬¯j%ò(´ÆÐ�#Hû E¬°Ç> çEWæ>ã‘Ó+1¾ Ô{º”j»—l/tó8„Kôw�ÙÿV?Ø6"Ùü¡–û‚žTÑÈ?=©¤µ'5'„ò<ÑöÜíˆ('à n��»°5Ho¤ÄÎ^aëÚ¶<ïѹ?¸lBüž/´ì#Þâ�2‰°ô‘­ü r3íò’ôÎi{ü¿ØtñlÁblü]õòHX9 ÝqN]ÇyœgÄæ;кžî¹ÿä·>òßóŠW½úÌÄ€(I5&�jBJ „ãáPvœÊÄÎìX4ð?F$³þW×UÈÞIó×h÷%?kEš ÀÙ¢£¢‚¹O©½¿ÎqÂ<§/=©Pë½g æJÄöƒJdL1G HÔú¬'"ŒÃ!¿ ‡�ß}™‘‚ bB’XßÉòÔœ­ýsÅ:¾$%ĘÀÜ[ô3 ÃXcæqóð!ž{îy<ûì§p:�0Ï3B8Œ#îÝ¿�àêê Ci+=÷ñŽ„°×^{íµ×^{íµW®�°×^{íµ×^{íõ"­Élã½U~ÉÝD y†ƒªÞp�@÷ðñx¸žçx3 2ÄãétúÚe†ª)¥ôê›››WßÜÜ|ÕoýÖÇðž÷üÒ|8~ñÁƒ'~ìU¯~Í�¼å‹¿üÝÌ|Ë��ø–'&ªIK±ýgf(0;È”|^nJ0¸ÙŒrµˆ¥ À£‚wDðìņ^‘•Yª‚éqž§¼ˆZiÉ'ŽWW¸¾¾ÆÕñ a ªÙeaž²ú(Z{Û•„²I\mì³Ý錔)Å–˜CÀŒy6;å8P.y® 1ÍE@!hO”°v0¤Ý ÿ›â·[øÖšmiѾ«Šùm«u³Ño9wi¯ì%»§ÀR»ŸÌF°œ[6p#÷iBÊ`=³E3 5Z!÷‘ ΃”@Ê9ï"'_,{°\D2hi_‘—sE‹l P¨Í. í&+f&ËnDX®o9–jÉÎß×dòÐ@À꜡@à¬|öÎ ,€0™@oI^aµªluÊLôÀgÝ¢ØÎWwlu9ãÚcD�Žl~t½À}¬2Ÿ—]Ô�ë#\U¿�„D¡'ƒ w™ÅhQΖ¾4E¿æþVÕø5ÿA+i©nè‘0]¨dÙ[Ô9 ùËvÜUqñûZ¨¥·ÕÝÅ^#êW½tÎÖûœýÿ]“†VÞ€or†ÿmŽkîh×ä$ë +?�”û'Yõèç:²üx"#Ô›/ ˜Nd)×÷]8{³^M\â9V9çê¬Ö/6WSדfPÍ´3�0›´:…td¹6VÏÅîtÑ7J¤‰ºóÁV_éNz­Ú§Fè†÷ÂE ‚ÖäîÓ‚@ ԗϪ{âåñ'æ4äßYÊÜÞþ´£¬€ÿ5±h©þo¶�Lå‰&zq*kçîûmL€Å}eËßgÝŸ—Ñ%³À8_yî¿kl\œŠ·æ{ø8€5íä¢�„bq�ŽŒvçäï¨zw¼�{ºcFz¼Ÿ÷É úÌ{~ñçÿì+_õšÿ‚À'L)ÅçÌ,…<Æc%¬¤$H’-é§yÂ4Ϙcls¢Íjsµ¨@ ”£�Û;‰¹³DœçQ²£TqÁPA~?ŒÕ¼hqE•të.Z’æ÷ИçLŽs¼˜x�ÌQRN„QEÔ˜�ò¾]ˆ·ƒ öŽÆàJ\™½ !G[•w±”"ΧÞÜàÙg?…çž{çÓ p}ï^¶ÿ¿ºÂñxÄ8291É*†`Æ}‰{¯½öÚk¯½öÚË×þv´×^{íµ×^{íõ"­d*b Yn�ݬ`™ˆF"ºGDO©ê®D/yêÉÿ º÷¡ßøÈÿ“9DõÕËLmÈì3tŒçiú¢óÇ>öEûøÇþ£_úÅ_ø­«««w>ùä“?üy_ô–úÌ׽uªN¢:g7UNbN$"kÑγdòrqÍ. l1»Ó£Øå¼V°º�Њœoª”UH)&ÌóŒóùŒiš²Ué!–WZ2ZÇqÄñêˆk)ª®”ç j™­Å‚7pŽÈJþ|^Ùö5·cŒ"É@›rI†I¡8#PΉ�1âp}‡q@p`|q$èô„Ús¤TÉP)½™wÓ‹-Æ©)q‰¼jØ®_Î& YÑk¸:êùï‰À,–×mVû�+x®h{ a0¶v5õ—©é ˜›Ðl¾Ë½É}„ªZ´ØØJJÕz—‰›#ó*o[UÁJeSá7+vïPÀL•¤ƒÄP¤ê¢ vï ø!eg…ÕÞ>º6¸�ÏJ½}ó† ÿ%dÄc¿Ë>*où…Ô¦þÖ¹ ›6A²Ç©•�õÖo—BxÖ¬w}¤6´¢JbÊL‹ï1‚²PŸŠÒ²\†˜^3‘G�jÞ”è/bVûb$Ún!±è¹¶’ÇqIp³…šò??D Uõ_H0ùâˆ)_Ö èˆ Þ%ac¬×Ï–k,qêw�•âÈ¢UýÏh |Zôç¢4¿�/§¿ao¤4,ˆ%½çÇšt¢ýÛJ^îÔ;3\BXýeyBœËd‡¿%Ý™Ñë9Öûºšðø_KË«ïÁô¼4ÿ}·S-. ­�<Á…4å÷€2÷j‹„À üט�å¿vä4r]”àBî[ÜÇÂξòܵ`W7ú]$jàâ XTÿ¢A ÕÅÆ“}<€Oþøô(¢V$±­ ÂKÿÇ�wÛo¦ÍÀâ·ý4YÌ{�æ7øÛçÆË½ŸÏ§?ù‹?÷³ÿã½åK~*Å4§už£�Vrç0`>²âš0�gHŠH“�ó"ÙM†C�kÍà}Š1ƒñaÀÀù½†˜ÍU¤y7Äd¶þî‚¥ôå¤õ}�™¡B�Œã§OÉdƒ8'ÌsÌç;OˆQêXB@ŠÙyj ®€zŠˆgHŠùÝ. bŠFÀ¡ øÁlýC}¯ÊäÎü4Žcun*ÇK1eëÿÛ[<|þy<|ø771O9Ráhû/ïxùñª•H["Ê6‡qÜÿq¸×^{íµ×^{íåj'ìµ×^{íµ×^{ýkR|µÅµaxÆãÀáA`~JT_ÂD×<†'Æ!übºzÅË^zû¡ßøÍïR‘#ÑÚ"~éPâu±š*"/»½½ù¦ÛÛ›oúÈ?ýÞùêêê'žzêéï{óïý’ïÿ´×¾öc€Nf"ž)`bÂDDgañ *M‚$’ù”�Ø`jüÁÀ}eTœpŒ à•c’…@s‚/ÔÔ×ç9/€žÏE©5C%“¤ª›ØÚ3@…¡ƒ@†±‘.RÈyî)eE€�S[´4Ex Å@4õ·-`J‹«5ª©¨8 Ð8C%Ç<8�àæI˜¬ä*.9=WÕ³-·‚u¤w#pQ‘Á¹P£ 0Sù«ÒÌ@CrJئÎ,§Ö2áQÀ. ½\ÀÊ\ÏÈ€¬,3🸞;vâh΀­;ÁúIÍG‚0#Rv ÐBå˜+€¨Ö׈,ÇWÂåø¨NÌ¡*ø³JM;‚Žx©Èߣ(¨Ø1Ég!ë" û2”³²iîƒÉ;ûrßÞ[k)Û\ò÷¾l¹í„³[§º@r7½À– ÀŠÑƒ `ʳCS3ÛU‹Íœmý‹µ|p kÆÈ¹S÷«d6Ð!©¿Ùq >€ ¤p²~Ð)œÛyf±Ï¸¬�ˆ> õDP�w1Ò A›¢6Šòß.’QÏÝèÑþÚ[7� ,‹sg’‹G0™ºˆ³nWç8p‘á€×…¶aþ™”Ã0]ã›ÀÖ¦ê›}»Ö–ù5ž¤þµ)‰lÞîzAm\ÏÚ�ÃÚüÜ3søw”ò$3êØnœëöTE´q{¶î—0µE¥”y¼›&–L(ˆ¸üÚ®omùïš“h=] Å9¬ºÙæMVgþáH“ c9Çm\ºË©õ<2²Ú4uí鿊Sª$ËåÑÝö¿Ñ`³{w�ãÂâñ+b‚sŒªï¤ª/`Ð�åÎ?üáüŸÿ…oþã1Íó4³ó¬J‰+Œ¸9 óˆ1âöö6ÇC™ËT9vàŠå^åwÀ9FŒ1"„˜Õñã€Á»PˆYé« éÝ3‚m~`êÜ/4iýL�òíÝCˆqBŒù}wž£Yôçw˜h兩†…Ã)Ïÿɰsœ‡JÇ#F”wçìÚ¥Â`ŽMþÛõßÞÜàææ§Û[œO'ÌÓŒ$ ACUù—¯Ü®jÇÏDÚüÞÇCØ#öÚk¯½öÚk¯½µöÚk¯½öÚk¯½^¤UT4@¯„/†aÆá8 Ã}áiMé¥DôàÁýë¯p%"8üåϼ4†aøTŠñÉÎ%xK &’áN5I `<ŸNoýÍÓo¼õŸ~ï÷ü¥ãÕÕ»ž~ÉK~èó>ÿ ¿ÿU¯þ´�‚pËÄ·ø†™oº0IÉ/ûµë![††8`éc\?¹‚³.3\“-hfõ5™ú;ŠËawßCŒ&à~Wm×cÄèÜ2€r†å©j&$Q¤¡: ƒìÅ®XU1ϳ¹ fŸ�ÄÀa³‚*‘©­ÆñˆãxQFFˆœâ¸äZwµm),¦®dSÏ ë"#¸YbSi`Êü›jÍPx-NµéACìJªk-îm‰È÷,í… Põ«M†ÙŒpvÿõZò΂�úœ!ã•­ã­Éiýqˆ³úØâ �0’EÛðOˆQ㜠.]¾±Ôvªí"|ßóæâêÓ‘Õ«‰ÖÙ(¢i­®ŸZæf7 PšJV»¦À6ð»u²Žx,¦([‚§+pïwX>WÛpe- øjÿYe©šCH‘Áy& äv@mŒ€M%Omªêì/t»}D2CI]N@oÛ±Mú #”‰€É€ùæHQס–P•"YîYdD+s8@!xõ>ëÂq`#¼ÜŠ»M–Ÿ+ç}^j'Í$� ƦÜt>½G©×ŠkòùîX­§!i„'l�ÕäF€êÅñùˆnˆÞÌ^Üs”:g—J(¡nP\pUÙ>‡Íydaó^žíÚŸÜj?êÎúr-®ÒåÔë²kÓbˆ�Ÿ‡tGàiÕ…CËʤ ïv¯üï‘öå»S=R™'<`®ý3`uråyQ¢‡àÜìºØžêãŽÜ>Šˆvûj}µ’8,'%rÇ?ùk䇋Zð ~i‹î�nÁ䜔V}àñ«w  ÇÚ‰öÿY½‹.÷®�uvÞcñêz¡RJ_þ#ÿË~ëÛÞþ5S•¬™Uœ‹’ª Æ çÓ çé„”’¹R‘½¿fËûÈ”£Ÿ Ü�1"ÅtÈç7¤ ‚$ ¤Þ±"wu{âL–ÌNš]"„Züáÿãñxõ®§_úÒï}óïýâüŠW¾ú£"2B1Šè­ˆL)Ťš¨™œªš�ÌÀ+1+ðO5¹œkAŒ )Έ)ÕÅSRn"ÕÀfÕO ¡f‡*QrNªFQ„1€˜0r¥Ãlñ7·¿Ä„( Ú¢°Å_…‚9°m%!ÅT­Ró=Í*¦!ÉÿcJ–™:�s§Íçp×â·I;<‘ì^kg©ë,ÿ™,º›-ÎÀ-°UbÍaeÃGɲnóÿ‚6 ÛÞSUþ×[©Ù¶VDͲ¿å7Wû~j÷ND+E�,wëLg¦æ8Plu•úßç{Ÿ•Ö%oZ5[.�$%szpòu"B(Ž®ÿ‰d7‹ þ§ºø®�…ɺÎ@N² _²ð‚‚”•LúÚŠDÕ¡BWvãRíTÿüm¹Ó g“]wÒ€²ãÍ�Õ¶áùúûîïÕï›ûX~J•¶œ¨/víGUk;çb_JÔr¶eȉN V�– L�¨ÚÓw 7©‹Îpó—m+*Æ«o•Ÿ0J½,d2�}†9Ôyaó&X4G&䯚S^€~†þ­ñò©,òD˜rÎF÷Üh®ž ”ª2ñÈv'¡E(IF9óxJN�^T±I‘9aF¾©¤!Z+|ÉÅ¡¸¹®§¤n.5ðw²o‘”T/öý-½Þú®S·˜•¥K�ºˆz$hºtÈ-¢‹®@vŸTd}.ÈlÜ2µy»o€µf»ˆ¾©Óéû–©$‡>¦Æ0PyÖtWÛ{vÐ<¤¥’½¦U8ðù™<I5ÈhV;w?mµ_O¤"­D¢Fykä'×SíYºRá;Ç?þšŠ_/LÞéáÒìÝHJŽ�ày<¾G‹�§øí�.î—òá}É?ýÈoü§Çãñ‡Ÿ~ÉK¾ûËßúöïÃð\Jé,*2”›†!$eNPMHQ¾ã’¹Lª@îç)Û„&ÉŠÜ(ÌÀqHH‡1€f�7_SɆ·|ø¢p Ì!`©bJˆÓÜÛ囂iIš ^,‚ ‰äœðJ,Chn)ED9þxãÐ"“ÚPr¯bÍ ÷"OÞ�’åïÚ�GtÏÖöT”i¥ñK>ô¦³-*W»ýö‹HV¯‘Mqž¨ºŽ—6¬ Þ €¥Ú‚z>ä@³å"°:?êBX(À‡,l¡Õƒâ>7Zj‹æŠrÏØb¨’TÚ"{Œ3R’œl@Sj9/˜s³ƒWàS�ýVˆ·.†3ô²í~û£ÙÙ{À¿^¯·Év·p¹ÿÎ{�Ÿl~�;‘]Dƒ:8þâ_èr?@Ñb!D!E±O™H#jbt¢Š‰à©)‡I³ö’nyÁVè¥ÉuÜuD€îª¢¹CQ+™Æ@yAŽ+è@!‚�&g ïÆh¹‡…h`Öÿü<‚¹|TÂA>Nö&P·ow’*�ðÀÚΛiÝ+T·‘òÕ¦ÞÞÉ®½‡Ø¢êاµõy¡t@3]ʦÈЧ�XCÖÔÅdž\ ¥3zÐëÔïjâðÕ°ÑG1½h¿™®~Çøj÷PI«“K7Rþÿ[jâf"•pÒ]W.µ/ô Äêb`¹÷>ì½øº²Çoò €Ø$túp•Më]ö“¬Õ: ·ç .gMêû_½sP¨$û….úPç„€žÜ ‹‹R%Ðå2,£.cþÞ¸ÃÍK@»Ýn|`1]¾ ¯ÝcV½ùñS¶{»êËßóK¿ðŸyæYD'UœU: ˆ1Ûü”²š?ͱ>O€aÈÖøÌ„1ˆ ˜²»£'U6g’býßüJú 9Jžª»sÂÊB?Ç2¢½ëÖý‡¥b “AþòÎê#J[gÐg•ÏöÞ'ãˆaž†Ž\ß‹¦ó„yÊXÓ4á|>ç8a0Œc�8Œcµõ÷c“9·]97vn{íµ×^{íµ×^{µÚ {íµ×^{íµ×^/Ò:˜—XÈ] ÃpÍÌ÷˜ùÀ5?q<Ž_ªfÛ-¶R ¯ÿúoÄ?üGÿ3>ô�ÖcôŠÿµ@[`îsØ;°°ZѶŠÈÕííí×ÞžN_û÷ÿÎßþØÕÕÕ?|ÙË_þÝŸõ9ŸûóÌ|a˜ŽÇñÌL“¤p–&‘I¹ÇÉÿ™ê"ª¦Äš0�'Ä pBÈ‹œc� fiO 0ÎaÂ<çí 6§ˆ8Ïkïa°ÅIÜÛ>æ…Ì)³~ < Ø"f° bd÷YÄÝ¢&�²â^*`›Áç4'‚‚“4?^]âfäs¢��|ÁÑ܈½ZÝ¿ÊçÊ6-‹Ìxt¹ÄJYíÛ4¹ˆ«â1/HÐTAs€ÁÜ2zU›¥­p£|}¬AgÝìTø¥“�pEÚ>�õPH ¹­39@¤ÉÅ€}uÙ�š;A%w˜R-Æ9Ûû¦hj™4À"@™’¤‚\«ÜæÒèŽ�Ð�(T‹iÒ Cçb^¬±Û/±»Ïº›ÝH–JQ©öªBx‡ß·|^´=Ö Ô6�µK"¢`›ª²‚þ—®16NÔ¶ ÎõÄH�w=©àF`#à/ ÑÔ¹@› D=VQ“2W—EÐ?1¼JÕƒ¢^][öËý5*9׃¶Ïì.ÀØ@G’Jߢ€Íç6j¿¤ ¼6ã Úžë6z’êÂycùÝ3¾#n é¯ã”¶c¶:2m€¬ýóvã*tù ½û0wȳû´÷Z5†>ò,i±_rÿ]ž 1¹?¯È]¨ó{Ç Tu\íL&tyƒ\ÅrþÜRüoàæZÇüƃ´ëWm,-õ÷\ˆFޤ·œª3oI;7”wwô¨ÛºtÀEXýˆÑõ˜� ×îìÚ·ìý_@7\4JŽ]ªðÛs(·jžÎÿþÏÿÜ»þöç}þ[Þ`P•Ye”Èžó IŠÓ”9ˆ(B¨1VC„@HF®C¨Ùõd5g†BdÍàz²izhïbL+à{IÒU‹!R?ߣ¹_p=Øù5õ¿@RD´†N):ç ~œe¢l²s�H2"0×í%BdU²@J )F{GÏïGÇã1·Ë0‚˜1Žc�h.Üýû£võÿ^{íµ×^{íµ×ºvÀ^{íµ×^{íµ×‹õEn\¶§©jp$¢{Ì|Ÿˆï¸p¼wuøb"º'@Sk ÀÁÞqÀ×ý7â{ÿÑ÷àCü ;RYP¦�Er—ßÞ-†Ó"¶º ÿ.»Í¹Îšž¹¹yø'ßÿkÿä?ø�_¾ïþßýßø?¿êU¯þMn¸èVR:Ñ^ËW€WS¨EfŒçiÆ<�kVhA³zÿp8â` Óq¸NÆÎÓ„yŠæ@U­/"`³ôÆÁÔ¸Œ9Fð‰›âß{‡ã8â0–{Úç“J•0n_*ˆËg�s[c¢yž¤ªÅÕ+]-Á;wWÛejù×f›Z€³­œ_tw¸ý·(ù‹r¬,.‹¤€¤ ¢rçÛ>¼�¼Â^ˆÕì̪ܲí«MºëKÝæcyûïÒ?ÚÏÛgý"¶¸s í•‘•\#’ïG9fSˆ/ŸvßÚ·¸ûÔ,v™ÂÈ ìbÙ^Ǻ r¯dm6Ákð?«³  tY5gJÛ™©æ§W઴-ƪ·†è¬Ú½èµw_P³y/׳è�ëýÂh°Œ{¶íÉ—¶ñ›�ØŽŸ•™\*v®E­ç%P0²Ëƒð;$ÙOdý±LùÎJ¦Roc¯£Å`„ü=A�Í>й”¿3ší~åÐv[X{´ˆ�2÷÷`U—�òåöQIöÙ-œÞ—h‚RB½‰Å…@ëßňLvìÅ3¦Ž³:†Ý¬Wš0lõ uýñÂI/"lºçSá�Z±0)@‹_QÅ:ãÛ´†ÎàÀý¦f¼ß¥Ä¾ø;í´HT îNîÂÏV÷nЋên}ÔnÑïV;ךæ$”ÝpDh›DPÉ.º£FœèEøzu õÿÅ9æRyüŸÚ¼¯ ÊA¿GN°8r$•ØP]ÚüL¾Ÿ‹ÝÄZ¯@6)X<ƒhùšÖ· éº)ôîn¤ ÒÀVbÑ]ó>îîZwÜ�;úÝãZä9€?þ±�þ_ÎçÓ!âÛ™0©Š†@šb‚šRž‡€ y2B0•~{7TeŒ0ª‚cB¶º‡–woÎ,…@X•õLuNæúîÛ÷ß­¯U«0!pÆæðU¢ªÊ9HDä÷`:;ÿBà@ Dõݤ�çiFbÆ4�qž&œÏ'œÏgÄ8;g'5ÂD#ß”¶ÀaÚq8“$Ø*˜CuÇZº#ìµ×^{íµ×^{íåÖ�÷&Øk¯½öÚk¯½öz‘¾È cÍU%\Ѫú€û®\�ãðeÅÎsYt‡_÷u߈ïÿ¾Œ÷¿ÿ×Ы{°ê y¿h\3ÇZÊæÐ¬‰ @œç7>ûì§þÓŸ}×Oÿ¹_:þ¼ì¥Ï|ç—}Ù—ÿˆ$9Än‰hpÖ �I݉CµƒV"¤yÆl_1%pµã†WÇ+\ß¿‡1$I¸½=câáÃÌ·NÀ4!¥¼ �? a€r¥«¢ÍþBÀ8p<qu[·ØçjŠbÑJ@ÉÛ•–„¹ås;2€Šv–Ô" �€…� Y+¶by²u±Ø�*D ä+0‡:µ¡´Ó7ðdamï@€¶ßU 6ÆT´‚',eÊYöZ®§eÞz§¢l×›ÇXÈ ï�ò ¤œÏ-Ç p‘ÛYìïÉ�y}ayô©2Š›ÕrùûJ˜q©ÔÏö�Õ@g†®ž$Ð�éúë#!Ò°ÈË6ÿwÿ�Àæ6¾k»× Mœ+¦.gØ÷°¸t×+ª*9¸$´œëz3ª�>µ¾—¤‹`�€±räÐþ:5ƒ?âQkrª@2 ]¤õ¿¬'„ þ‡ PUë�æÏ^ŠPMZ)ïZس4ò˜m‘æz�w¤S㛸¿käI®?r�OÙ¾÷mEmL“Þ‰s÷ž´îïžÁºáH@ñë^è@Юߪgltê-à_�Ëåþ¯+"À£ÆÈãÖ2Û@Ÿ·{äþ\Æ ©=»t3öD;WšB&(Öÿþ3Ë÷o›~iÎÙšjê­Øl;ZÅïÜiqo¡Oc¹µ+é6i*ƒùkO?¾Éϯ�zrI}Ú…­žàß j£aå³þÓ�4µ¹½45Uò�ïöë~Kýƒš°z¸è…Þüh�¾þCþÐ×ÿƒïþ{ï¿wïþw¾þ oø®×½îõ`Ð „™ˆ"1'fNÌ)�H@H hŒ1RÊ–îÌ‘d�‡îÝ¿‡'<�ãñÕ„›«SÍQ•$9—T)Í �cËç!/Bª("b>ߘ*ð†WW\]]áx¼ÂñhÙ¯1/¢ç¬ØTíOàMŸóÆÚ4qšmÀðÄýã÷Œ€<èS1¥uáÞÔ¢p$lçZ«ÒÅqŸcíÕï0ÕxɵgÖªv•N½¯ËøcXLQn‹ÊUAͯ´@ÙYà—˜2§@’Ù×;`¯F ÞæW×KéAˆr½ O ß*½Û»À£`#‚$ùˆbJ™€åri#Ù¸Øézž�L“s}‰šÜœÈ¬t“ºëÔMµª.ÄèÝhÃXd3"ÃÚê^�`r·Íøåêa´-«ôßÉr}á?þ^šó|CBÕœ8›:Z4äþ† Vq�#ªqøW´ˆ…Ò‡hjvwžš$¾8 4˜•ø�²½Ø} öêd†Ô+öËX´œçjù_z‰WØ;G&^÷™ò»â)a1eK©çaQâïƒ4‡(:&κkÔ¿ˆ*¸‚ í:(jä¨B2°69�môÚøïHG P¿�ÀRïÝ,Üáá2ât¹óÒã�‹Gíú¨^ÀÓ}Î}kÀG�ÿ]sÓïpЭžï¸0’/g¬·Tç´`$"¬BŠÕýƳ«ºÅx峋/á‚Bx�!ß›ŸX©Ãž· -r›¬%Úœ©»¯ê”þ#|Õg›ûTqpl«önFÕF� Aíß…x‡B�ñO¾Þ§¿ø(¨ ª–ÞÑWºvéæë…µ ]Lθ»Ëns.<3è�Ä]W'àööæÿôþ_û•ï}Ý>çWTUTTSJ ÈÀúx8d‡§HO’@1Çda „@ÙÚ¾ØÛ[“*S!¦¼/Öòž#æ ¤‹÷°dÎQ[¤ZõB•¼Y€øêB�4j%\r`„!?³8pu a†7òÁq¶ãœ ø?ŸÏ8�Nõ}×ÛõS!DPŽË:8^]!0#‰ αÏ´âòŽ4:kG*Øk¯½öÚk¯½öÚ«ÕNØk¯½öÚk¯½öz±¾È…€D�e+8¨ê=OxBUï«Êý!ðÛs½æüÓG¶ÈV®½#�‹UÙÀŸ±R…;SÿzÄ ÌCÎwÀ gŠÚÔ�ô¢b7÷›Gµö=r¤#í *p)žÐ¥îýÌßÓ¥kÅÊ–Â1t{†Õ�ޏr; O¨Ð­W�G÷^ºôlxQ[’=nÜ6O|ðïÿ/?ûM_ð§³1O²LfÆ2èŸXQg¨4²Ÿ¡édÏ‹ò~•ÍZ´¾“S°÷¶w.ï‚$¨qLbïFü÷ä�ü˜(ûéßeŠk™MuJ™„�D g;¢üžÂÀÜÚ?¥š3rš¦ìj#’½ïæW 5â0Uw®²;×0އDÙ5¡¸œ‰ªÅ)d"Dbé@ÿ»"öÚk¯½öÚk¯½þ�^7Þ›`¯½öÚk¯½öÚëÅYÞ"ܾB9ŠÈ}Ox‚™ï�ãðežR1uQ¨&S‘¹àd€ÁD£oýÊ·áþýûøéŸþ)¨š%öb!¶� yGÚ-¬«Sf×O,lÛÕ,hˉ´òNã"2œÏ§¯ùÈG>ò5ß÷}ÿäC<ñ÷ßô¦Ïý;ŸþéŸþaf¾Qè�$ 1ÆÛiš§iž )e@ͦ>«Æ³ÒšƒÁ5_°ìÓ” ¬‚³YBÒªöžcYà̪ï`¹®Ùþ5+»RÊY¥…T i`Îê©yžk[þµ¿ö×ßþíß~à¥!„W0óËC/ÑÓ¿õñßz�ÛF«"R™3àFÙb^­hö»"bpB¾® jàekë~U]Ä„¢ê@o“x0\î·[´†·†·Åß�ݘµåÙ¢,*Û½¡U@@‹[(ýÊnL]HfÔ¾A(QÅžÜÃl ÉÅbZ¨ˆeñJ]d¿›]A'f0-Á SìK.)©©ÀrYX/êð꺑ÉXÝ®OT¡U@Ö¶bêëŠßpž�mæásäì¦Ñ {U™â½–t…ÉåõÒ ºW’³Ýî3š/-Þ—¹á®Ør?©Þ­O-¤�Îy.Ú ØzOfÿϦέh¥q)²] Ê A‹pGTdk~±_… äe0›òÙ°¤B�lå/¤æ�QF¢æfÿ“4»îz³òøå¾Ä"-Z¢’t2i¶‹p2d °Ä�<¿T¿pˆLàõMeÛQ'øáq <ÙóL€D«ßuý„z‹ò%]GÒtÊñE‡»lþÒzÝî�ý>ÖcAŠóm¶®®ÿ¾Q,S .Ž bªÅø{‘ 5¯ö×CpÁ.w�ïšeïç)ôq&Šª'v*h#ïÔ¹t‹˜´¸’ÿw*›s•Së‹.Þ}œ+…¹0‘‹­ñ™4ª%4‚Øb^cq£ZŸ•~ ‘{>鲟2‡=(ЉIÿ°kÎ[Žm¼<ºï+=ºëÓ¥ñD—ûäݪþµ‡À uXVŒó×þÄ�ýÈ7¿õ«¾æïÄyŠ1¿ü Ùû kV¯‹fk|MÙÖ?¿có;{´÷Šò,Nê¦Æ0ŽCµå$Éï¦)Juò ÿ>~ˆÉИ¸›cÄúwùìˆSþm‘_3$÷~—ÁxæTdŠJ 1Æú~,*Ž¼Ù«ÿƒÅÏ C¾Vì‹$Ìó ¢XŸÛäˆÏ"ù8)¥üßk¯½öÚk¯½öÚ¨�°×^{íµ×^{íõ"-Ÿó™Úâ�bºRÕ{Dô ±<’îÆðöjª‹oZ.(Jò‚®�â‹ÞüÜ¿?úŽžALBÕû\Ûæ0@‹0dZÉåÊ`Ù¬-<®j H)½æÙg?õg~üÇßù§ÞýîŸý¡×¼æ5ÿ×ý¾/§$EdHq>MÓ4I’Är:ç6BŒ3ÎÓçiªù¬Ó4å…Ê” Q”ZY™4 îGcŠ˜¦ˆóùŒÉ¢DS·Ôœ-Q"Šišqš²+A!ˆ(D4 Îç³µSÞÃw|Çwð<Ï÷Uõ¥oû}ûSÒ矓>%î=ù’�~ÚÛ¿ì50ä¼ø ´„�ÑJ®Ö³¦öBQš1†Àà! 0!p¨QI`¹³EAΆÃ@aÀÀaÈÇaµ“æöƒælol "¶v ù½}=ŠS9›‚1¡ UkÙüYf˵Ã-SÂ�@Èyd÷ñœ%aVáü§…Ô~ ···™PÔyj+ð*HÍöÜ€ÙìoÎÅM#V¥Zý,kÖo 4Ø]È‹ãy¿1EĘL‚ZT|&2äëѽ FDÈ·»")ƒ *Ù:XSUÖŒtç2‘A) FÆ#´EÍý@µ‹SP)æ¶s=Èã–õ�è!Öneû*îE—ÓÂå½ì·‚EnNð¢Ý2VªÃ>Õ[†(VÁÖß’*^þ’OÜØ—ÏݘÃEhÈ€ ò Àª¤–¼¢ÖÀM"�&SÁÛýoÖÿNFî2ÉmÍ ûëR‘�æÏ%³×7Ý®”¼ûJxq�“$7‚HkL-Ê#‘Tr‰í#¡�ú¢vîXãµ;FÛ7HÁÊ�¤vFdÐL``åvãk†Œ©SÛ^ÛaÖ†I!D%aàb"»û�ëtžð¢½àEîNAkvÙ�å·ë‚ ³õá‹å>ÙáýêÅ×ý¾ç_ùÁ<®�x7¶Ï`1UW=ÿA—1˽ ðÆÂ9žœk‹s¡©1ýFu‰Y^«–þçšb¶ B7jÓe®‡ë­Omv%s¤Û`´ºñ«‹Ø�Õ½éÆkkÇm@Tè¯×GtÄíç„GÙó+ÝqÜ»úá¦5€^èP¸{çú»‘}ÑêSŸüø_þøG?ò#ϼìåóy¶wrÛâxûõVp0d’†üZOYŠ›RÍc6û2¢ÉCÞŽˆÊg3Ù€ÅÐĶ ƒíÏŽAc>¦Æì8dçòŸ(çPÈüsb#X)û´ÏvùæVà. ¼Z»Ø"3 óÓ-ÛŠ@4v¿+¹ Ä$c€ªš&Ôõ}Û¿&÷»Ô}‹išS(* ›�ís ª±í×bºÎ/@öë¹îú%ïO&û]´}ŠÔÉÚ+Úþ£k—T�£HUm±ë�ò™´Fî:Ðǃb=Á“¢7Ðÿúë MïÞ&ƒn†ÈÀ³®¼(ƒãhªúvýì{�é¡¶¾UÀiP¢d’›³Fi^2r %X!‚•⦽š©4°QàÔì.b£8£$1@>‡Ì= ¾ÍŠšß© [�³1ñ'åW ‹'/àBÌ»¢ÿm¿’Z›«ä.fÑùœ `yë”Ö}@–w?/K97ýQêÏe–¼êªc­.Ôƒ´KkúšYoûë|QîEW?×ÖÇÖÛzð_{7÷ù²q‘UG¿iÙ¾u½ "Ér8^ˆ  Bš2"W%Þq+t«SÕ¶ìóì}¬È%_½cêð1ë^ Ë+½Ü<Þ £ø›h—xÓ·¡c%j©8@©‹W©@ÿݽÄG=-ߪj?]m³h]ºVŠz·ŸÎ9Ä;B¿èñè.rqúÛù]Àÿ/wàâ¾EäïúéÿÏ¿îë¿ù?#¢3 ³¨&Ñü• I«“TsyÈÏÏ”Ru5*ÑFP˜¢~À׸¾w!„ªpŸ¦ )©¹He`<„üM44×¥bÑoäKÞÿ—sfû7‚‹H2‡%Z‘t¥¾‹ûý&I@B&8¦X Œ@~6�Úòß‹òÿ’;CqpJ1aæX÷SBœc=çö%î½öÚk¯½öÚk/_ûÛÑ^{íµ×^{íµ×‹´¦éŒ”RV O3§G9"çÆ_‹ðõñxx{SЪÙÿ_Øá·*ÒÚ�!Í×¾öµøCø[ð½ÿð»q{{Ûoç2nµêP­Ýó÷ù@[vÿ5Éž´ÚÑõj£åùùÅG‘ôYŸúä§þòO¼óáx<~ÏKžyæo½âU¯ú%U�ˆé<Íóts{{f泪N1Nñp<‚™ç·§3¦yª–§Ã0‚˜1#B *˜æ);.¤„išq{sÊŠ¬9AbVZŸ1UÒ0 `b¤1Ï3Dò‚í0dkW5@ðææ”k8×éÛÂ×ö§¥¿Ö§b„97Db(0’$ˬ�™ÀH ät œ­ÃÕ@: ùç2fõf8dY"@ ¨/û ¢à3 Κ® èÐ@|Î×Iäã¬Â' ù3ê{ŸAŸÿª¢ÙΙ×Xÿcô¢¨öm?j™é uEË+¢(ë¾_ˆݯ¤ß¨f!/IoßüäíïÉÛšr›ÂÚPS;Vù¾¨¹3¹ÒÆU!1@ tݲÿΠ¾ª»æBˆ¨çŸÏ«D4´k°öqMЮ­W*òŽI—ŽºÈw¿wǸË&]ïø�›çº¥Íš ü/ínÛ¿ìIÅ'?±Ø«˜#ÀÀfï¿×CؼZÁB ,HPj„&í†ÀfI÷©øiý°’P�.à›=ð_Æ?z+†â*±‘½Þµm!°ˆë[–ýD9½@´×™ a„ö×$ýýu‘w±9Qx÷ˆ `.aã¨/­Ò»«.tDŠ%üÙPñQaàÿ†]{í.¢+…Ç2ì×õI*ÑÖ£û1Ú­’åÒ´fÑ÷‡Pç¼Aݰ­P¸æÏ«ôÀ´];,I�•ŠB'£­Rw䜨sáÀ&©eé¼O[Ïœ�âÛé"‡‚êÐç�ùTI\«Ø�æÄïú¦¶x&m¬I©Æ¨ôÀ¿”ç­‹øèÈA~¾÷ò~Ý y¸¾¿5=÷�Š>fÀMK�²à> ô¨¶Îâq«‹�yüOÕ?O§Ûo}ç�þ³¿÷oþâï4ŠÈ$"Q%i¶¼s8*ü+¸K$“¶¯2e öjÅ0FGŒÃ€iž0Mƒ½[§žTIµYYŸ šÝ?[ÔÕð_ªÍ¾¹ iëKÿbsŽbÎÇnÁlŽ'´ˆ‘T)FÌsv»*}6G;eð?CLýÏ�µ>6cõç~›dçç¹À°×^{íµ×^{íµ¨�°×^{íµ×^{íõ"­išªú%¥8¤”FU=ÑQU�î_¿™™žñjF¯ú)&àå{ ¬Ÿ·e&2œ)/¾ä%OãË·â~÷wãSŸú`Ù½) ôà_™´ù^)›Áb²}©Ä�.“yÃU üÜŒJ¡ û§Óù�}èƒüÖ�~ä#?ýàÉ'þÇ׿á³~0Æøüùtzà6¥t{>O§á0Ìc*"˜cÂÛÞÚûøÓzCíÚ¡ÙôcME©×I´$O\>Íê]ÿF($×_ÕH} ´û|‰b ç0A�šJÜý©1ŽÄ¨þ´Ê[ÎÇéòÅ–÷/#J29µ©®KSõ;ïœT7ºM{ŸkïGÚîí~j7ƒÖ(×'¶ÍȽ#öµ@/‡vë6œ%Ü+¡zbÅ]$°UWqD‰ ½0®è1nß݃L€?úÑßü/ŸýÔ'j8Œ©€òª:çWi›ó˜† ÐÍõÜDšR½÷‰"Іü5@ó>jäS#‘ˆèú]'”Ø%ê”õUIojúK� ]@þ-k´s·9( ØbePc’ÔöcÂ<ψsvÌ*÷#€©þ½ú¿;fŒÃ€ÀŒ˜†.Bv¼S�ÔÚ {íµ×^{íµ×^ÛµöÚk¯½öÚk¯½^¤u>OeñŽEdTÕ#€#€€ñúúú­½{²¢þO¶LÁµ8€¬ cÊÖÖ@¶-½¾¾Â·|뿇ïýGÿúà½ä¿©Ñ¨,Æ£³C&Z¨ÕˆÜz»-ð1A•ëâæÝÀÈJ/לEižç/þÄÇ>ñÅïúäO|øúÞýïúŒ×½þzæeÏ|dž¦Ãx8�CàSa"â@“[ˆŠ}*3Dæ ˜1ר…9FLççéœÕý)çv'&Ä9bžŒÃ€a1 à02Ìf‹ª‡Ãˆiš‹•køÃo¯üüÏ ÿ—J:•˜DA‚fe¾0˜J赘b߀v΀¾ â ÔS0ðØî+g¢@^–Mùïl6ö2€0 !€XÍ&°–-€¶À"RùÌlm]ˆåòÊuŬÄSÍ u„i笅Pb°ùeAˆ€t™õ]ûÊâ^÷C‰6…ò>¬Zý~:<~ÉÐ…[½LY× �zÙô­ïºEÉ�?„'ïÜ>—ó— ùOM €Æ v fRPwš ‘|°_T•{×=Õ@k‹Z œ�z“ «H‹)p€ 8oWc=à€{Ýð€gò;äÓH²éýüZ€Gö×UbÄõjÉžØQ"3 TIÀ˜yA°h ->�b¬¯4LæöAÕ�T8¶PÈ·]­;iÇQÓíSYíG7º,µµú.Ûï³ñ¤./,óìuiY¾8f?†óƹúãéF ‡vQêÄï�à@Ýèõ­«›c¯=›½S‡ÊZïm×,ª ý¹º¡¯‹v j«~‰wä/´‹W –wND«a¾�©›Ëî¬ç9œ@šIh�àà­û��À~}l-@ÿÏEuÑZâòÛÍâ}+QN^i1¯r€²eq…hq½ÛÆ’Øy‡“KÇu ‹Á1wÖEü¿íøW„ ‹¤×ÿì»~òÏÿÞ/ûò¿ª¹D43÷rªg¥û8bG„!¿óPy‡ÒAh ‘ß»˜’Sóç×�´ç/L É"DÊŸÒ„™¸òÎB`ŒU¥Ÿc®4ä貉P ±Àö•�ù)‰©÷ó3 €ÿÃ8¹ ¬ ª{AÈOÔ£;÷òçyšê¹§” ÉÞ?Eöîµ×^{íµ×^{¹Ú {íµ×^{íµ×^/Òšç‰T•D$¨êÀ�ˆD4<ñàþÃÀ¯l[/—FMí…&íß Ùx¦t­nÑ©-CÀ7|ã7áŸÿóŽ_üùwç ¨Ù�R‡”Pm™Éë)áÔu~ñÝTRÑËëŸÅUT3†Å¡.ï‹ê«>|þÏýÒÏ¿ûO‡ôÌË_ñÿûŒ×½î˜é–9œBsHÄ”ˆ81s ̉ZìQEΘæÓ9þy�3AR2+U© ñD@œâ8âpHP=âxqF\]_á¾ÜÃ4M8�N8�oqΑ á›ßþ3&}…Z¶¸ˆ�Òh) Rp~.™ä U®ÅD€ �ðl*ïì  ']�ŒykÒÛ~Iâ¢Ö75¦€(Ú?-œŠÁNVMÉ®àB Rï]¹¾ 0f`�BSþguÛ£tzÞÖß�Cö#Çš$à¬ùÅóÑ)ð“µilqêúòwqä]8ˆ}VÍ! œWŠm›Ô“ÚùĈ_to�ŠbÜ€þ "K&t$ˆÐ6…¨ôQ ~ÿþó—ªÜ;¾ lÑGÜÁG)ÿñhe¨ÜqžÚGT~^þÒ~ヱ�…d|KAY!à±D Ø9n*ð_nÔ—L „�É<õܤ�ç^vÌœÁÿ"ñ,NdöqÙf9Ï 4tc¾sv@Sç/AùBJQé·-È?;âN9—J`ð2¶-s‹GÐÿ«ót]¡´§‹;(n­Ã¼#%Øwt÷üá 6`Xl%Ð7Ç™þ2ÊÖEõÜÙ£ÓâzÉ=��Ò»î㢓†;§-ð_ב J[1!α¥�ûç­Ö6¤ÚßÄ»E£5ÂÒæ¾t#c^Ž$Z¹7ô$U]E4t#�.Ï=KRñލýv£´˜;œ+tM*‘ àüæ÷wÄAøù,uî «s²{©ÚÇ·è]ó³Ò�㣟)eåÍD €�Ñã㣗ÕÛ�£Tíd¨;B¤Âz´(üqã¶·9ŸOÿѯüË_úÞ×~Æë„™3%p&~²eÝ!8Ëԙߕ¹:�”wØüÞ#+Pž(G‡qÀ0¨k>Þì·¾ïl�ÿEù¿EÈ®NhÈn`Èew" %Ñ _Ôø)æ˜,±ýfòWQûg2Äh€ö3�{Ï«ÎCsÈç�ã´JÌV�0HiÛ}h¯½öÚk¯½öÚëßðÚ {íµ×^{íµ×^/Ò2¥ è àʾ<¸÷6¦–E«ºÎ®V¿ø¾…3,½sÕH’Á³1o}ë[ñôÓOáÇÞñެfvy¤MÕ¿¥´¤JèÜ Qì—Ñò•Ë}2ðò¬3>E‹…oT³¨^ŸÎç?úÁüúùÍßøðO>ñä“ë ŸõÙ?07!„)„pf泆ᬪ§$ÙÊ5+ú'œÏgLç 1͈ÑÛtÃelg$*†J3a0qu}�«ã BŒ ·§ÜÜðÑóô«‡§ž¼Gßvž3À+š­ìùþU½lŸÕÚÀsÕd-“íú3øN¾[›$Íík ¾ˆT`/+þ%ÛÝk#s¨hV« Àië œXªð ÈßÀ~Ñ”mýëM¿$Í܃�µ{r«*ßrÞ]<€ˆ€;RÂÒÞß�ö€ÕˆBP@f»¶èxgÍï#  ôïâò~VÖÿêÎKŠ¥ÿœÛ%-�œ‹@òVþN} §ÔÖ…šßßõŸUg¡Ž~yÐ_ž„¼•xux˜²…ÆÐBâÍt÷:¾\˜¸µÿ•j?_ãËžó!¥‘l({dC„¹ØL^Ã^òŠK7õHªZ·Ìó&?‡ì`±ªjÍ®nÞ3Ëv€¾.n.ä²í% H�Ÿ¹#O±Ÿë¥Œ+߯Ѐl:´R˵JîJ�ðP¤¤XZ”cøwöÔE7Pn²âTP/M¥`–w`2ᢀïŽÄÕ͆nýÅzžjŸ£5_•èZðnT;ýÇÅ©:…ó…{«è@`r zo�¿^ɯýíÐåXRm.FÐE›’1àTË3äòEe%9y—ü¿�ºö®Ï -BÁÖþ7Ž^ÛÄ¢mt‹½ñ¨[qg¢Dÿ^Òü.Äß'Ý"f¸›¯èwÄ9oý¿1ýé*êkBÉÅkXplÐ 6(*®Ç“zo‰�²½A•h¤�-çˆKëæõÇÅñ·î-ÑïÄ>~øØG?úW^ýšßóG‡q<¢I 6DŠú4 ‰s˜Êd°òH+dÇ9&Lç Óá\Ý!˜†aÄÕñÕëLx­Š÷ˆ«*$‰Y´šcÌ?O 1ΕdPðÛo¡:M CÈd4ʽª"Î3ÎàL.˜gLó„æ8çgžµŠúÿ0p8Œºö/sy!¹„!à`ÛÒ1ÍùXC˜ ¬xv€½öÚk¯½öÚk¯Å‹êÞ{íµ×^{íµ×^/Úb"‰èÈ® àêêði‡ÃáM^G¤`"tP^ÉýÊ¿¨°¬ÈÛÜJ^¨ŒÀ¬Š!¼éMŸ‹'Ÿz?ð}ÿqŽuWL”UýªõúÝÒÂA·Ù¨ÛÚ¢rÞïŽa‹Í53—ÝbzÉ5- En(Æø¥ŸøøÇ¿ô§~âÇ?üàÁƒïzý?ëï>ñä“WÕçEô†ˆ‚*nSJ§iš0�Ï8OSŽ^H±ábÌà@¦ö*ùݪ’Û<åV!àêêˆ÷ï#Œ#$EnGÿ­€¯û}ÿK¤÷D20Y ªli³Á�hÊ€bmñ®u_R@BûÊê=2 þòå€+’‰Z@upÇP(@E@Ìæ€Mëþ¥Eþ, hÈÞz{1p¯åÜ^Z¨÷@÷è�ºWÉð’÷½�ð伿ngN\~¦n;YDPß_ ÐÚÈ�¤àÁøv�êÝœËAS{öN ÜT™ûfÞºsðp'ß-?ÚlyÏwÞ®6€{å¶\Jh¾dýÿû/ªV+ür\†âé§Žøø'OÍÚz…öm°¤”ú6Yž¶�$1…+e•#Q³Ü/òi](âó Ÿ Mhà¿èÂå€îÿÕ�³Šã;ð{9×›ê_<É p~<˜¿TóÛuvp!ÃÎÉ[ÿ£¿F]ÊáiKJŒ6ó�eíúË\Y.±{ÌÐà`Ãè½�É|äÀB_ìÛ•Ö¡ §Î.Ñö,%¥M y}š-s~�IPHÔÙ§ûh€%ÍA9ÎßõÕËcV›CFqöi¥‹ö^KÞì]:6T¢ÅÂq¡ØõëDëœ4²†'— ½‰Ój oO+èc –ï$ÝôæÔÝDþç´ê—�¯²M�k|“Å„£=1ÀßÏmbÀšJ¹"µx§Še…n!ïÔ·X%`“×·ÕÔ�Æ{ý-ëûõ8ûSüöH¥™DäMïù…Ÿû³oùÒß÷ß0Ó ªê\ú¬ª"Æ„DŠ fÆa8dr(…jýŸL‰ççó­‘G9«þÇ€£óóœ€ÀŒyަæ/î1‚”Úµ$ÊϽhù¯.ê'Ij. Dê;ì€ñ0‚™�d(G‘Áˆsœ1O掕ò¿‚�üC0ŽÇ#®®®ó~̱Kì©¢j¤„ÑîÉ0•H "˜kןÿ {íµ×^{íµ×^ÿÚÖNØk¯½öÚk¯½öz‘3sC¨àÿ=U=>ñàÞ×äµfj8®R¡üŽŽYÀ±ÁBxÍ+_…?ø‡þ¾ÿûþ1ž{öÙfýï2u»Å}¿\³�©ZñÖø‡f4ËߥÊÎrimᘘZ¬€æ½1ŒJ:sn�$¯~öÙgÿÜÏüÔO~û½¾çÓ~Ïkÿ‡W¾êÕ¿,"CŒi˜§)œÎçóù<Åy>#ÆdçmÖ¥àz̬:ÏyÞª@`BJ3DŠÀ„Ãါ뫼РÁy:áx<âþµ~9`Âo0”4öÔ@üÀ€1Ð@{÷¥”ÁxäœØ ªd§‚�ø–'N4‚‰!<ض ÐB(o€>-�IÝŸ*uèþ÷ÖÞŠÞn|É7áÇí£�'÷i¶ä¹e@ÚêÙùØÒ‚Ы®ÚǶ’ [(z P7¥&e×0‰�ÔÖ¶5w††|lyè{PÕ¢$)Æ.ê`©Ðì”׺k2æÈúËÿ‹.ˆz°¯7zE9Ýqï)éqûL¸¿âeWøøÇOæ"a ç¹£É0y 25»ø“†B¤Y›°p5a®¿× Àw׆²A°œéJ*¨žæÚ«ùa€ö%—€ªâ×î³µƒç¹#ÐZÍ_Щ÷Á\AôÕ�YƒiûÚC“Ò_· Ç× ú8ÂO?risq±[|¯|w™êE�_#pœ´~I(ôتsêÝl.]m+ááxvTþ£ ív÷Hõ–›Ìƒ.³ÜJš¢[;{ø-îP7ºü€•žø²ŒZh믩ŠûÕ)å•Vx߆Ôö»œ7Lì·'½s"ïPAˆ¸®fýÇ G±g«´lù�··­»Iwî»vîÍÏéê¤ÕÉÝÕÇ¿Ž‹ýν/êSûrŠ¬× ��o#P)šûýù|þ3¿ú+¿üßôyŸ÷S¢ªh‰YqçüÞ!‡#†0€Ž„qÌjx€SÂ|ž3�>O8ŸPCÀpücÿò=¿ô-¿ö¾÷þÐK^úÌßxÍïyí��§éáétº�¦iNýOBBHaÒx8X6*!%�˜Ý·Š`Žfå:O˜ç)F$ËkWˆWŠãñˆ!œ^�’m{¾´`@GÈ€$ d·Eg› Ô@ú0˜�kACþ@?T'pV å6s¿72@Ý–‹¹ý©´p ¸ðEŽP<ÐiMØ^¹½Ô/ýÜÇØ÷T~¶ïÙÀzᢰˆ1 KfÈ)�)mbê†F&û¹ý.s>^% XlK‹ ;g*êûdû@Í-1ïCœ«Ù¿.•ý »HàAãr}iᤰãWvê¥}–è œú.ø .ÇÞý`k>’…[@·;ZV|$EùšË€©S_ñÌ=ü¢áùÌuþ(¶Ìª¹™Å÷ØwŠx§¢¯*áÚ5©?W7Ž–N)¢ îlù—K;~T7—æ ‹1YƇ�TÙ¾:Ml“­Úy³ë7� v<î3¥sŸñí£ùTõîÜuÊçG@[Òx¬sÙ{Ûo5íiÔÝÔr>w�]lPŸ±þü²€>rjSÙ²n_:Ð�Ùñ�”àòßi›@ã³Ýi¡˜¯]«Ä½X<ŒÔK¦>Χ­µÊÞÿÐ ùåm^ªÎÚËõõªÿ5a¡·Íw. ”½Šn.Ñž à¯Çé†km�É\B¦»½,Ü h‹håÆH�rH×½Z—g+w�®Q#ЪU=Ñ 7sÐ;öþ¸Ì— ÂÐûô.(jpêûÜÝ ñ߆z\W÷cüèo~ä¯~Λ>ç[WW1Æ("")‰Lç Ó4A5ƒÞã8à(Wà!àp8dËû˜ ¢˜ãŒ”1fu¿ª‚™B@ì8\d ~ Ω÷ɽ×)Ö©þëû1“‘"QIMy? Õ„`çPHDŒ0°2†aFàöîí÷ "bŒãˆãါ«#®¯¯qïÞ5®¯ïaH’EPÜ T)E¤ØÈ 1¥zÿâk»ˆw+ …ýßk¯½öÚk¯½öZÖNØk¯½öÚk¯½öz±¾È�C°€+÷ÜâþõÛ@t]c�Š^=øi Ý-ÿºP=h' S øš¯ùwð®wý4~îÝ?Ó3Ù²Ó>F\Qÿjö_V°—  Y1WË}è@š-µéQJe­€–¿L.'šÈG„iš~ÿG>ü¡ßÿ[¿ù›ï>^_ÿ÷ϼüß«ª7Ä<…À§q<œ‡Ãy<Œçq8D¢‚yš PÌ)/䦔0O3¦aÂéö„››[Œ‡›¬ÆRÅÍÍ çÛ3®®®xz ˆ�´€ÿJœ |¯ÙÛ쬩3ù ô ÐØ”ú�!8ÀÏFç �?“=#\äã ¢Uù�b‹ÄYE\šÐ�OÍg¨�’Í `©œ÷ ÿÒ-`ùóV"ºðûZÿðŠüò'ÎÜqR¨bm.æÀ¶�°åZG#XøÎCûš?GP¢jÀh¿³hÐøÉE$êb÷‹�?h´Ÿû}•ÈûbuŸ�m§ýyvQ%º �›jÇÏKà†Ô6tœÓB¾aÚ{²¯‘À~ŸLwîÈ]ru·Z*έèÇb¤ _R¯O=9âáá�¥†Æ«©— %–";FPu;¡µÍ½h?¯ñ"£v]û�,#L•±ñ¹¶©ïÚ¶ü½€ÿ^ ÜÍõ´ÁÕÐõûl'z,Ç41.Ën½Í¿}_&óÍ‹(çÙçŠÛM°¬èfW¾rôïÚé²÷�:uz ž¡j¢@ À¶’×Tê)©ßÄNŠÌ)béìÐàä X×_²Ô7aôxóèÇ7õ0)ÔŸ‰kŸÒ\Ö§}ÜA÷½ÖÑžÛG²Ë uQÔœ{zOøÎ _«*_·ß1–î‹Ø€â4PˆÛ6õ]±;Õÿ^ Ý>´ö‹~7z¹ÁÑx4ˆ]ÜâBIP»†ÒfÍÅÈq岨‡sÑ­¶ò÷b÷°èomûíFS]ÿ]»1²½î˜–mN/0E‹.ý»!¤�ÀŸAD¾èÇìǾ㫾ú«ÿD$ HŒqš¦YOçs´‡ñ€ë«{9:‰²R?°‘T•*/’ªê�˜A¬1h¢©Î4ïoke|pµÑÏó°ˆ Ag­nVYqo–üRã³Ü}·ÈiQAÄ„�òûä0ŒÇW×׸ººÆõ½{¸¾¾ÂÕÕÃ0𳀂hÊöÿ’I0Ï1˜æçólùO9j ažÎˆ1Ö±Âö®I;`¯½öÚk¯½öÚ«_7Þ›`¯½öÚk¯½öÚëÅYã0°ª’ȵªÞ“$÷ãøv‘œ×®ÔT|G¡@Y`\À*SÍTå›í{µØêp›šw\•é@R5,'òÍo~ ^ò’—à?ú£˜æ³SìÑBe×K§€­=*êJmBK¾pX^U°¿å{�_^(%()Å/|øÜsåæùçþüáxõ�/{Å«þÎýû>z<^]]=8h<oA”âq>ŸÀ··€*æs_cŠ˜§ 7··8<|b6%˜âæöÏ=ÿOÜ»¦$�1��çJ¢ æ![ús¨–ïÙ‚Úì]Ùw*ªý²]0€~€`A ü\>“•ùÊÛP9>ÐíÀý¢þ·¯kñ€{¿ QO¢3¿®NI¶¨>]s„��ß“Ê6v §ä왆fÝ/åóö'sŽB�Õp2°24p]Ò@ *ß‹©õ) �ˆÚ3EÙ5"ÿ\À¤ç"}�µ½*ÈÏÐh ¶�G($ç Pþ^äçåw¢@0‚CuàvÎTÄH'nÑeȱ‚SåÙ.,ûW*^zä1ÖÇñ¿`·-@kE'|u¤ *Šgž¹‡Ûó³Æ�ɪËïÑšŠ�kIî—îÙÌ!ƒ"½·ÅV„„s$ðH_±;a­D«»ZÃjHûÊ)`ë3m{y”:öÎã»,øŠà¹Æ`ÿ³ò0VïP3€«ÝuÖÜê�¾t'¤ m¸.­!Õêîo÷ß©járêuåInvâdpñ]vån®«Ïãåéne¨oÞþ¢D÷·£å¸¯›Qû^¹v¡¯Ïäªä¯Ñ‹>aVÄ%À¹ ”ègÕßÏíZs€–€³V—½`ûN³¾ÛQ�Ô?5Öª|²—$òó�C«k®§½©bÑ ÅúžÊõ”˜—öSnê}OðïA½±~é;·6ZëÝ"’$¥ÓãS„Šât:á<�0OâáˆBï£v@~¶î�¦È›Úóó*úMÕß”ôk@Ð+¹¤DXÙÏ  �þkG•ê'£’ÕûsÂtž0›"B0#Ç®¯Ž¸º:âx8`<äÈ ªçT³¥} –(„ìýµ¤êHUÿ—ûBÀNØk¯½öÚk¯½öZ×NØk¯½öÚk¯½öz‘Ö8Ž!¥4ŠêUœãõñ0¼�˜>S¡%]æaVoëªc#â¬v­ ‰å _8&Y¦yµ6Å.“[ÈS€IðÚ×~:^úÒgðÏ~èðÉO~2oW\ˆ:CZ"Ã˼:qek\TI¨ 6€ûigú[~V[a™IMdU[T¨'+ðªÓéöÏ}è×õÛ¯ïÝûîOÿÌ×ÿ�×¼æ5ï‡aÆA·Ó<ÍÃ8YN4Tç`ާÓÏ?÷á|ž¡PÜžNxþ¹‡xêÁ}V¥çJfÀ¯e[ 6!Ûª n5u>™S@%pq`�àoJÿ€¢™%4k‡fËŸÛ˜AN•Ÿñ¼µ²_E­?¸ûP•Ãwiéxñ:ßUíXÙ•€ ß;¦Ùå‹äï ^�U"ìûªô/ Î’ Pй-4«õ©Úý«©ñ‘��¢Ø'wl‰ ¤¦ÞOÉȆ˜ƒƒ³Þ—h—98åq ŒT`÷½w(¿+í¢-Ö`A˜P“z×X·�\PènÝ&¡•ꛊ³œ—pÇþWЗg£+yK}O0(„„ÿAPå Ô žzÉ5>ü‘gmš¤–^á«yô(wZ8ð*-ÈÑ+k^ÃcZb_€7P[Q# x€v9þ´¡ß…hðÈ{‚¿@ë\t¦<7`˪\ZLÀlÂÚ‘ünímQ£{A3.~FU!jŠzRºãN¨–ẽÄdÕNh®]“ëª9t58hý ÝºGyÜ,ûA}Žvä„’ ¯×.–óh¥% Ý3U²x‘<¾ý>JsˆRålÔóò± vz¢_!8בÒNÚ¬ÅA½ýÿ£g4*„Þ¹Õgâ…¡¹p*ð Ï‚þ¬q²Úôk¯ÈÆâÝÇ»‹Ÿwê{Yß{ô¼O9G¸ðû¦zߨ#ÕPéÛzi®ÚðDÐ>d;™A+¹fÃ÷cuÍÛà=Ý=�.Ü"J{!$€T�xzüÐ>ðW^ûŸùï«ê`&P,§‘’ Î3Χ §Ó Ãp‡I‚iž1ϳYá'Ì1!ÎÙIŠH@¤H1ažÏ˜¦ó1Ljh±Rù¥eðß¿Ëg@v J (D‚-8ä÷öƒ# )1͘¦3Îç|ш! ã€q*@òjxv§-Ö¦0e³ÿ`pjû,ÃÈ‹ý©ÛfÕÌ µ5\κH“©Kç•vY©ä·;õu™+õ}Bï†Ô.‚ó¼hséGá�÷t¹Oºã~ó¥ÓÛÿ±Ó ©XWÉçúà‰{åWu‡þ¯jùí €�šùÄ(T"•hP3ūÆ›ü|Øl"íÛcj©SÙ_(uÛê’Uât}eyÀ‚dúx›�˜,U�,¶Àâ ÷¢Ì[)”‰,¼¼\}ìÑï•Èë\*ǽ|M ¡Õ|� ªª»ýÍï²ÇgçS¶ÏŸÖ§¶¼u… °°Y_÷éþVW€{†å{�ª®éõÖyéÒpª×ió§±jÞ¼¢Ø—­¡Ëø„»;ª„ýý#l¶?¾š3}¬ÃÊ­ayÁÛ†Í5ýôÞóN´ï3ö.ÔÅAè6x¯Š Òc­ ¤]Ÿ»b9ßm÷éò¤�ÁÑr™dRúý2Æ¡¼“Õq±8Ýš–S�V²€nÅtÜÑUj;Ðå{¿E.hŸÕ 3É¥Gë7奔ÞòÓ?þcúÍ_ò¥ÿwaã|âü"§PÌó„ÛÓm}—SUÌsÂ<ÏÌ ó”0M38œ�RQBL ó4ašÎ8�'Lç )%¤dúJåç4!€¯åÀ‚�÷ÉÀûÓ錛Û[œìkžçüžÌŒ!Œ8Ç€0dà¿DÌÓTÏcžÎ˜¦3æiBJÑÅXÄ•‘“‹Ó�HýCvþDTÿÜ {íµ×^{íµ×^‹uã½ öÚk¯½öÚk¯½^œB ”8Uõj_ÜmP³l‹í:JXlÙ`e—\7�Ø"1ºëΚ6PÍÊ.Ë 9½_èBÀÛßþoá5¯~ ~ìÇÞ�dŠäºW?§V]Y›€¤·dæþ³Y½úíÊÙT;c4`c™[lª*X¤Yàv¸ Óéü ÿâþëí}¿òÎW½úÓþ»·}Õ¿õ#Hz–+9IJçÓ ¢çyŽgUU Ƭð$ Îç S^ ŸxžßûÌÉìO¥ÚOƒ#¨XõwÒ<ÊVöJY‘Oˌ޻ЀyÍ6æT¤ùEùÕÚª�7º–“rÏm›Ò™8�É£wUÑã)ì²íxB ¢~ïQÌl�lJûþ7›ûãêòî²î»ïÝÏL +*P˜B¿€ùEIßÙæ§ú;­Û�*–ûàqŸ/¶ÿE•ï÷WTûÚŸSwŽTöãmýËçÊþÛÏ´§Äh´S݈€IܱÝþÅµ× 4n—߃µäÔn àÀä»:„»¿|׿úˆw&æm¬˜�s5Ðv¾WÇcˆ±�Û¢TÅë~T”HæÞº_ÕR†)˜²:0(p%\µîèÛ[ûù»ìûØiýM |g2a=™ã‡v¹@l;GdIbã®èú áÝWü¯ËÄ!.B¤Œc ¸+ãl‘óÉ}F¥çò,eàñîMÆi[ÂÝÁ ›(î–åy€ ­ (ÛßRZÙ¢»#ù)ö²z9Á©õÑ?·|³©Vð_©"óÕ6¼Z룑SŠÀ¥£Sç…$åœT„ÕþQêŸÓ»rUú7rB{ŽÝ f.ÉŠ5â¦b_šc »Ùì/-ÂĮψ[wyT¨›_ Q‚´å()zð¿Ýƒ%ªM«¨êÈ Îø~ÓL…¼UÁe±¼s³ðc‹:ò‹ïãþ¸—cë~Qλ]©n]*Ü£‹Ÿés‡QºÙƒ7yU‹ñ£z÷ó©ã�xŽ•¹âööö?~ß/ÿËú™oxãOƒ(<ÌçiŠ"¢LŒ”N·'¤˜2 ÇŸ’(œ0ϧó0OE„¤ˆyžÌ`ÂWí”/yk±ÞZª'§*\xÜö Ûm!½)Ìœ4ûÌ_tÙ·�ÂÜG8›äçhžæ¯xÿ¯¾ï+>ô�_ÿåg^öò¿ùæ7ñ÷\ŸŠ‡Ãó’ÒóA’œÉ‚�U )å{‘bBŒ )¥ð3¿rx÷_}SU� �(7Ýx(,ÀaÍ ZA0æö/yâP(ˆlIA<ÄÍqà€dì—È€{�h¶Ãgò¶Ì…,P�KŸß­Ý÷ªbªR]lã%Ï´º×1m6Ó‹ß,þ4[<ÐïAïd›&»ÎÔ€nMДAu"i`¼Äúû ‚$ %±ÞE9ÐDÄ ÊkD³ä·ýKþ–ÊÜ“Tó6œ·}‹í«� ´ì8ÚÈ ù\Õµ�#(h!¨#He­.­¯ë8ÄR Ïö1¹0z[‹‹µøe¦{É]¹øCÚø© ”ì~%\]<÷œ Ä@%í¸5¯�óS›$)¸�¨Å®€ósâÍ–Í,¹ÏŠª£ú¯±"«¬y4_q¿Á'G(íÏÀaw{¤#A ¹‹t–ãhpuXÈk;ƒ2‚H›ÛE¬.§¹D˜ˆôåòúV ›eµ×ü÷ì` x l"¤H÷ µ‚<¶ºè3 ,Õô˜Š.áPdÞ�„­›Îý—ŠFàSˆS€vO©‚ÔK¼¿˜J(gÒÓæÖZ hë9›ú¦€v6ø=øïmÿ{«÷þ�C××þ(6Åà³¥µáŒîŽÓw5Fù³FM�)ÞIÝk™ ,rs†ÿ¾Zà“V'&HvSÒEG¥Õ Mõ>û¶õ×·¼G•hÒ‘l q^ 嬼3]$jöíæÞA5¿—Ý9î <ÊK‚.ö So‹ÿHCí‡Z¯ûÎÊ×vüèoþæÿõuoxã·<¸w?Åã�ç3æišÅäìÓ9ƒçuÌ(�xò½•¤ˆSÂIO R¨&Ä8#Ƴý™Ìö_;[|È¿Œ—Ÿs`Œ¦ðN©nBvCÀá0Ömâ1Ïg<¼¹ÅÍÍCÜÞÞ`ž'¨ ˜ aÀ8ŽÂ�‰› ¤˜� D" Ã8BUça� bJþã8`dÄ„4G#åÎH�kªúßGìµ×^{íµ×^{íÕj'ìµ×^{íµ×^{½x‹°ª†«ãáKª(3‚ev’_ø/ŸÒ­E_ÔÅX­Û¯A? ½ýpŒ†I4}©"%+@”ðàÁø¦oúƒxÇ;Þ�_ûÕ_½c±®_¨öªÂµÍSºW@ß¾w—VläœÊÂu·€íŠËAks7fQ¹—ÏÌq~ão|øƒù7?òá?}ÿþóu¯{Ã߆ÃG4`P–b>Çá !Pv¿æ¼Ècäü™ñCßðeø¨Š¼PSÙ3”$bôð` ­Ùú³S�C `�fG.:h€8ÿ •9“@#ƒkW†ˆœdY•œÂ?+èÙG•)I½Weqw­ò÷ R^Ü&ºìe®Ž Ñïcmk^ÉKE?|{%z;å<«êcÛÎ>“Á¯Øƒøâ•ÿjJð²ÏÙ�õ� õÚlÕ½¿VçjÇ_’ 4A  �ľ/À¥øýçëÔ¥û€ÿ^€hc”¢*ʉ´ùá“®oÏÒWûQõ‚Öò�ýöB%ZÆ-Èçkä“#´5åö  :C" ¬àÔ€WsºÏ Ê`@ 7 \D«£B&•åL–âÅÑ[n4‹v?1Û~¹Cü5öyì½»‹:7pV÷û¶BýY©i�öÞu²å�¡Ö5 µ¬ò‹VÜÚ†ùf†÷‚h€F¸èÈ .žœã‹Ø¼^x´ùpÃ&XH->+|^iDÓ…¹7«ýKêS]Äètz{zü}ÿ—î9'E!ë�LÝóTÕ°¯óî—‰ Ô=ÙÕº…‘7lÞÒE—¨ýŸ–íZù…Vu ŽdAÞ™a ü_½54nÌâ³Ëû²Í_¡FÂóGÓÕÛÏÝ“–X´Ð’s³t`PÕ>ÆÉõ2S "Z9Ø÷vÿTkþ/^ù6z6ûkçô¢¾_6×€5—S³_Ôé÷{ÒGŒ‘K¿cêˆ>«�S G¤¼7Êã<Ñ/ü™ŸúÉ?ûÕàkÿoPÕë9Êt:§ÓtNóyBŒÓ9æg¼2x8Œùý=„€aæ²D�”Áÿ9fÕ|JÑœ&Ê;/Wu¿ÿêÇ~!då¶øº¾§ƒB’€a Ã`±ÙiàææÏ?÷,noo‘âœAøaÄñêˆãÕã8T×&UEŠ9ž¨�Â<çë1R,†$„€ap<^á0Ž`{?>óTç7‘ònVxu�Ì@欵×^{íµ×^{íµW«�°×^{íµ×^{íõ"-U%aIÂã8~€ ÄzÛOµu½ äxRUxºEÈÀK�à»H¥ÎÒUËqI œÉçxë[߆W¼â•øÉŸø‰ªþQ- ÿR±0-ªêy^€Æ=°R¯ò‚©w(¶EêæÜ£Þ–¶L-Ï”•¸]ªÙ²Ú镟üä'þü»Þõ“êêêø?½êU¿çÿûÌË^ù�aN‡Ãñ|8ŠqžÒ0MiB²}߇äg^r}þM H¡¬Ö B°üx5q!|h$@( Е!ƒœ•Ìr”4Y9P%‰F€Tm;Jì�øG4äý!�‚Y÷‡²ûs¢Xì}äÄöÇ `.E†p{é²X¿õÏo“Ÿ\6 >ÕQè{€Þ©ã;E¾ójvý,�…¾Ve½í#&3 U§Æ'§¨×äþØÛýKX3è\�}ëIñ�[Bõ�b¿Zÿ;�Ô«øÅÅ tJþÞIB*ÐZ¶z‡ø¬Êƒty!¾Ú´÷V7æü_¤¶á€æ;Šû}T€ü"RD Ûyt|… Î ól1 ¨´Y°ÛG(*vTº5ƒœ'KÔy9��Û Yó¸Ð¶EÙÏŮߕmàáMñËĆS­»›HÅœáRø¼f'Fœµ$¾ÿ¶Ú£` êK&”(‡üœP½pÏ|t�ôíQÛÓ:UWöGW}–¸gûçHk¿Î¼MÙ�ÁÖG£÷KÞKQp²]å£\ÂŽi ^/TUwOókV÷Ô+Ù›ùZë22}{Ðê¼ômÿYs? Ú&l¾‹hu%j ½ºÙ"N=[m|áïëóqm±Ñ}}ÓE´D3½‡á€K£'gèÒ­ÃmUˆ«ÈíÛͤheç®I²¹WlF;øþ\îzq¨Î=›Ãf£kX4€ýYç}ï@qa_” ãi©êîÈë�Cε ¾^è;mûFnÙŒؘ"™¨9²ÐåGÜÞÞþ¹÷üüÏýÀW¼í«~ZDãétžŸø|zøüCÜ<ÿ³Ìˆ¦¾åŒãáˆ{÷îãÁƒ{‡@jVùsÕ“T°› ÐÏ_f¡o?+ªxUAŒ ÅA#ø? MÝd‡˜`Q5�³"¿ñÓ4áææ!žþ9<ÿüs˜¦8Ü;Œ8¯pïÞ5ŽÇ#8@5þ1"¦„$’÷#‚að>ýÓ_÷ß~Ög¿éW‡Ã™çóħ8ϧÓi<ŸÏç ý7køÛŸñÔíáó^}óæ×<õüS¯ŸÃgÒ@ 0f¶Xu2o(6á Ér¶4„l0°yù++gDsÙ €`€aÓÐF€ŽˆaÌÿt €�¿çáÐA&�@|•·ç�`Œ pÌD @s8ˆŽò19@Êù÷µ×xPÂû¤Î‰p~RtnßË Bd2%¾ýN¦ öË`†¤9¯g°F3 D&hœòçÊgÔþžRŽP§Æ‡Ø9Äì PUØf½ž2Ÿª"ß«ÿ]g4Ò‚uGph§®•™¿ãºk?´±�³Å—¦2mïSu}˜zÝ ËúKçµ ¼9%ý¥ó^‚Ê<à„Ÿ¸MøÈGŸÃ§žŸÁ|T˜]�oÅbn)‡‘†�'µëï&%¬r½m !†³™=ÎMq'Uö_œ|{2gwŽj³ï›Íæk QGøÈ¾!¹‰Œ€´jHqó�|Ü1 •§wå(„’ì$R/òdÜ_.g€ª1�;BÃïµ’.T²ëº©“}—mš^‡òu.'ú`uÏ’¤¥n‚®ø.= Àvp1˜žÖŽ—Ò4t±‹åãבÿ¶RjT€' ªÙÎ+9r¡öÔ?¯µB‚×Ü.ï"Ò‘–ΞÀHXÞЗ/ç¿:�¸Øo}_¬í¥»=ëý]öSqG•؈ZÏ5…œhNŶ߯‘Gó± ulD'Ô„à¶Q/¥_ZŸTlYþ'ý]{NøªVM]ß�åšçËóµÞ9ïc1^7RwߣÅíz$ `ësh_d´›txÿûßÿ_ÅÛô[žzÉÓçû1N‡Ã!’’Æ9bšg�d1ápp}ïO<ùO<ùãI §”�$!¦Ù\†PÁ|æ¬æÏ{¶�$H)�9ßû¢˜†ƒÙí'°Ç€|=bcRD‘RÄÃçŸÇ³Ï~Ï>÷,Îçàúúî?Àƒ'žÀÕõ5˜)&œ§s&)ñ IS&)„ ‡|žÄÃ� ƇaÄÀGÁÄP(˜"˜ó—Zt9r€•÷îµ×^{íµ×^{¹Ú {íµ×^{íµ×^/ÒŠYYCOÜ¿ú¢‚RñДÿD|Y˜Tð:^.ÎK§ÐK‹ÅY®(Ê‹e4ð?«›íx !/trxê©§ñ ßø ø±wþÞ÷¾÷‚Y!Ò²�ý_¶ÐnŠŸJV‹Ù¾ šËtó&PQËÛ·þ¬† .ˆ �k¹·+n6Áb™ßºP¾qVç]�ϧ?ö+¿òžoùЇ~ýûßøYŸõß}þçÑ/úüù0=?Œ‡ð©O=—îÝ»šœÞõ«×¿úî_ð4Ñ+ß@D÷_õô„·¿ñø‚W~Oñ³ÕN»C „Á”èbêÿX6 œ A`e¨�²¢_ƒk¦}€Jó /1V‰fïª�ÁÌ €!çª#�(ô£œ­z…ÿF¥ üÛ#n9|«öPRï—»&C*+DdX¤¹TE¨˜Â¿WÜWU>Ì5€Å}ê…ÚjÖëh}„–(]¹™I @_¶]'Y÷ÎÜîó¿ õ¨ýt“Í’%�lM[d……‚uúøçõv¦k³.VÆúx›ÇÍ�O1~îwÿÝ¿ûÿ©ïø3ÿµŠž5¥ù|:ÇÛÓ Î§Ñìí�qp<q}� O?õ$Æñ‘„ñ&Gë¨&ˆÌµ�BÇÃp@²µ¿'çDägPKk`÷ŽÜ»…õý@‘Rv2:ŸÏxøðy<ûì³xøð9ˆJ>Ç÷ðÒg^ЧŸ~ÇãbL¸=ÝBTçÙÞÁË\ËF0 ãˆÀa<€#ð˜ß…¡ÄöL `2rC õÝ›ƒ�éyаÿãp¯½öÚk¯½öÚËÕNØk¯½öÚk¯½öz‘Ö4ÏH1aã›êºe9ØʨVéÄ ÊèQ¨ Í�M¬6wÜe‰*Â*ÜYWç€Ø'8cçÀT²;Þú¶·áÕ¯y ~âÇ çó "èìuó"!0wöÿ>WúÒ",s[$®ØX’¨·.®è2uj; €cžÐg*÷.ÚeôÚ~Âétóµ?÷îŸù¿ü/ÿÅ�¾êÕŸöÿùìÏ~Ó;ã0>÷Üí-щ‡ñFU?©ªŸ`æOùÔñê;êÕøN¼×Å×~ÁoáK_ó[xÏöJÍn¸(LsCr½6Éà=©i|aA@*¬d(!`TÀR€Äb�®(rå$9+¶[Ù…¹$c‡­M3ˆ^òœ ЏDíZÄe!/~W¿¯ Ã’°a¨ié+L•Ñ ¨ß“ýž ”p=¥l»üœÙºÇÒ=¢æ¾‚ ª˜?Srå¨f÷NÐ#�jÛY¸‹SÊ/°È®‰ôŽfûíÖ²R›±—[ÞmÅ�nn€þ8Ë¿—òòÞÃØE[!œé ÿâSŸ†xïçCâ-ÞöÚµñicW.œ/;ŸžÇ½il©Ùœç®Ã&ÆÏ™Ìµ_&A*¤-@ó¹S—J.n>Z[÷w2döêuÚ¸üg:ù7¹>åªD åñZXKzhÿyö÷ÔÛ¸sô¶ .–¢Ä@°Ò6¢Ä,º#!Al¸5P~ùl#òoêN§õ�³92Gu›)¶úê@ÇÎÞ}mÏNº À»Ñ¬….¢Vyï«v¹0Þ].¼vçW¨7Óð$Ýb#(|<Íö€n`ºWð·çc⥾+Ô3+ï/øÏ®ïé#sàý©Åš(Qý}œ‰›WÊìÝ9®$êž\ѳ´#ïøkذw ÿ6fa ¢Ö—tuýØ&1¥Eöíá]�ÊÐ-ÏØÚßµå:¨v÷mÙ]u“@p!Ïb�ÿ¯Z¯œ3|Ðõø§ÖW–ýçò�£.vàÒv� æûû¥wž{î¹ÿÝ÷üƒ¿÷�¿é›¿ùabƒ)Ùæ¸ÂÃ8âêêˆë«l«}}Ib~‘ þÇëû'sÀ0p<BVÖ—k)d›ˆÔ¢µl쥔�bêߟ›ÙG%ó¦9â|¾Åét‹Óù„yžÀ�1ŽîÝ¿�§Ÿ~ O¿ô%8 œç çq‡˜c8`FŽW¸ºº‡ãÕã8 pŽœ"¢#%¤TL-þÿìýi¸5Ùu¾kíqνß�“2óËA™’eK©Ñ,#<[ÆÆ6a(åCµ¡ º <”�ê6E™Á@›~º ©®‚‡á)†*p¹° ¸ ØÂ¶<È–3¥LI©!3¥œçü¦{ωØ{­þ±×Þ±#Nœ{¿”ý#�cåsò»÷Üwì)öû®÷Mï*εð.@›5ˆ ª1©4 šÆÁ{g–‹ÀK,±ÄK,±D `‰%–Xb‰%–Xâ7htÛ10Ómõ÷%ûß�« F;"H%]�¿ûü�Á‰Ç«eÅ‹Œå}ÓÉ0b2ðïÍkªø‚×½7ß|+~îç~Ï=ûtɦπ?3—…Í!#0/òË `Qg5ͦ„•…üœc‰ZVTá[ÃÒ{ZëÀ‘Ê_ ÅÊgœ›KA–ýúXb³)qÕö"I޼(;Øs¦L°eu ©ˆG@‘éßy¶Ùk€¦Ï²fqénù�È*Zˆƒý‚T˜&�mFÏz‚Ënu˜¯/»}yãŽiS—>…3¹lO•z™Á &ÉÚë„G£Ÿvo�*©õT›�þI3ÌßU¾ìã{Öª¾íWF™õsßÓBÒQÆä6ªHR@_�ƒ3b‡Ì—Çqª¥ÞëÇ;š¸¶Ë¨äçGVs\•’-ÀjµFÓ$Û¦~ÕbÛµXu ü'b¨ß`½>ÄÁáVíÚ¤ÿÙ¸ª‰‰¤bD²*H ~¶ h±{‚†J9Bã=ßÀ»d��ÎK,±ÄK,±ÄKäXK,±ÄK,±Ä¿A£ë¶PUtÝö¾v½¾'gýÓ h1Hè‚°Ä•ôçI¸Âta;{ëxaT‘,D*qœ¼krðE• «˜ €ªÂáÜùsøº¯{¸ÿ£øØÇHÒúHžÜlÙÿÌ\.‹lqU•v²òhï¢t’L2¾Jæát—@²^@®3Jk‚BÎê*„Œ²¨Ÿþíûþ�Ï?ÿÜÿçÅ_xðìÙsÿë]w½æ¹Ò4ô ³;pŽ=;×0Ñõ¸VxöòüÿÓkÐø»ð­ïzï¾ó)0u©<È2¡8ƒÿU*3ÉüÀ9�¡p¦ÁEêäJöUB@]"”tšþîLm �èªD>IŽgÀ�3`°È?§sq…˜å,û—Ø?ª¨¨Žg Æ AbD ]ߣë:lû-š®±ö*‰À)Ëßy‘�ˆ·Q ùth’€uÄØ#„P®)}CÄj ¹63ÈÊ^¢ ëzl·[„¾”à|ƒ¦mÑøì9Õ»(—Ê’™S¶Û𢔔à}‹õz�Õj�¶YÁ5i|}"pF‰I9 &F_ã[4žà<ÁÃIá}CE#ˆLýÀy°s`Ç øë僴ÄK,±ÄK,ñŸG,€%–Xb‰%–Xb‰ß Ñ÷½Q¼|õøƒ¯Z¯ÿ ®Ñ†:*ÀÝé€hq&@§§PѼk¸+QÄ€´8^à7Úòó8÷6}Í ‚w Æ›ßüÜzá6|èC¿€+—¯Øâ)�%�s6å|G“Y6pkW¡w’ÕEd¾ºƒä´V8$UÙèdàMZ¤N`ï(ó�²½A9:€ Ðiµ%ïmPºB£¼á¥—^üo/]ºôÄùóç?ðº×½î!çxÕ4ÍÚ9@„ÀÙúúk•…ùðíøñ�ÜŽoýÒ—ðÎ;ƒC—n öífü”çfˆù±&‚'ðÞ9(y7y(Úô3œ 2ÀŸ²û5ïG¾�R~»‡jòg!p&°ê)M$ÌÇO(•’hæ�Œþ¦‘Aƒzûág�q®g½Í$ã@$VY�.=kµíá0Ãû¤ÀP7²ÖéDbñ‰/ÕҲà p>ÀJÎx–а'{V*pˆOL¢¯½âk©ö¹íéeØ �á‘ |iJ:æžp�ÓFLû!A%ÆÇ/Þ‰¹ÿ�8Ú:Ë<œœMª�X'Pý¿iVÿlŽ«Ð=ûÀÿŠac6¤4q¿0ð²Ø T÷1²9˜ÞPgÿ×d*J.’Èu˜Ëúž" ë;o6¸zå .­ÀÎ!v=\ã!±ÇvÛ!Ä4Ç–(IÆ? b˜@Þúø¶]‡ífƒ®ëÐ÷ad«Ó÷‰B@»jÐxoók-s̾ïÐm7Øl·èCLJ7ÎÃ7 ˜$(ºÍÇí�dÂ�‚ÈÁ{ß$Ë1$’s©£"*@Œ]¿Å¶ è»1$"ƒ4 ä'nàÁyÖ ‚HRÇæá~ÙÚCK,±ÄK,±Äÿ¹ÇBXb‰%–Xb‰%–ø 1FqÎ…Ë—¯|æ†ëÎ=çÚöUT2J)#6ᬠ¦äWí ¦V^ÉäÓ|®Ž©ìmV@%\ü«_ºåæ[>|Ï=÷<»ZùfZ!¡ÑT•ùHùñ{oÇOâ6ü¾/{ ¯9ÿè$s—‹¼,˜Á%³ŸAè+1ˆ2🾣ü³��ü~ùÙh �`ÀyÎø (g|Ò+P!Ш,÷ª'£¦ù>WI)ƒô–IçÀ™œÏ®��Œ<�•È.Ñ¥Lm—Ž¡ÁÈSßå¬PÙLhÀœÈ0pX,U8€:H‡ìúXí3ª†¹>ëH�}·ïú`30Wöy±c×@†ë—éy©QµkH°ÅÎÓ­Ž)‰ÝPò[‰ðÉKwà_Ý÷\ݶ%óqZ_r›ë¥¢@ÈÔbçU“«ƒ˜[ÃNµª2cG·.:�…L¡$�ÒÙ;ÃàHÍ>ÝÉ÷^E!¬`©x‰ v59ÔáQÑ ÓCˆqØ<øeÈ.ÆÎ\ÝÄ€ðI]fT)Œ¤ÿ�Y"sÏ�&Þã%�Zn>ßD4õ &ŒØ1œ³e+e ­ìJ¿lEìr=d4gÀq<þT`c>¦êhì£5¯ê&ä&”ÁWU�U›©³¨wdùOõ±ßUsPÒÜ­¶*N4Œµ:±°Éd€]•z�‘…à—@ÐDEÙ•Lg²[1’�úU5Ùÿ¤D‘I³·_)bp¾ vC­*³}ÈêN j�|�@dÚ;ÍÑJQaú,0h©¬ƒTMí¡\‹Ë �‹æÇ¹(Û¢Œòã­W¥Ý9Øhl+]Ôó…2¡AÅhäg_÷á3n"Z�ö#QL9:*ÛQ¹êðìòñ¦¤Œˆß#±ÓžöpF×´Ÿ8 …šYÛWŒö×=d§ÊZCgU£Ê³uÏ>óÌ^ÃMߢоëºC ™àzttçÞBb"‡ív‹®ëÐ4 ˆ!„àw�eÖ‡ñË ‰Ñ@û]¯á]RQú€ífƒ£ãclŽ�C’ÿ÷¾³]_×ãèè B»ZÃ1!F³¨æá"1ծΦ2 ¹ï;l¶[t]R=!)´a•”’èL䆲ÕÜ·ˆ"Š‚‰Á$§Û-±ÄK,±ÄKü&‹…°ÄK,±Ä¯àø®ïú®"{dÉÆˆ¾ïc,™Yâ1/81sù8çF¿¾ªT$óßê¨ÁEÝ“±5 U-×mQ)/xå�÷Þ<*ÝèSŸ?ïBÀv»-Y*Yš’™Sf‰}ê…ß| ÑÀ�úÜuyL¯¹.Ï|íùz�s³ç›Þ{>_>O½_.ë¼ÍܾӲϟoÿöoŸ>ƒ€æ¹BŒ+ó /¼ôñÛn»õˇeh“9O'Ê‚“/y^ÜÌÙï4Õj­ãD{µäå´¸?H��tÕ˜2‹°HP$ÿ ƒ§ö;ÞñÜ~Û¸÷Þc»=NÏv”‰;‡E Ð I•ü8YwçIÆ*ð ~.©>$¹ÑT§Q-ê×§¥â“LT-ŠWe«2ÉËÙ±”ɼPãõO>õä×<ûì3Ç.\xø�o|Óó‡‡pžˆVZUå¢JPÕóm ü/?{7¾ðŽ ø=ïü<® €¹œ=Ãyø—Ê)›ŸØAKV¿KýÊ œ¹O¦`êIÀAٲ瑲q1ú  ¾êàNŽ'•l *ãå»ÌTÜÁ;{Z‘ëë«®³€‘¨*VÞ&Ú¢õàS=°fLyB1ø([�’R·jÿr¤TV™~/(éó¹MIrH.ÆóUß<\a¶¸Æp®ÀŽ:Á¼fs¾nšÿ¾(` ¸ŸyÚ}¦2×ÑhâaØþ\£KZR¶ñb<�ô+ïÆÓ—ÎY¿÷ŽMÖ3Åml:Õx 1�;ˆ YØá„®o t©Z¶~%¡O.ÙdÀ1 ±dV¥²‘ + �¤G*2–$J¹ቭƒö",j)Ñ4§HÿM�%qYhÊI’5bœÆÁá¬×k4�‘¢=ºíÛí›Í1¶Û-DÞ{l6 ߦ6#’dõC,ï5Ó÷"ñƒ5C;Fèƒ ŽpõêlŽ7€*|ãLÁ‹!ªØn· º‚ëU@Ó6`0b4ë� ¡Gߨv`ft¾ƒo|Ãèû¤Ðm;tö¾ÇìÛ “ÔÀ!½»D ˆ2¼kªÍ;çÞe—Xb‰%–Xb‰%~³ÇBXb‰%–Xb‰Wp8—Ð5_õ PgÀ> }ðŒ~êO�u4>OŠj1«¦„„špP¼÷£k›»Ï|¯yÿé=Õ$…úÜuÌ�ÿyû)ðŸ‰yû¦iÊuN¯wZV5™¢&6ÔÛOIså^ƒÿùzªó´ÎÑÁùsgnØvý9Q<ûôS»ýö _Î\e=;+¨ .ÜgùM;Šù©\F^¹§G^-Å[TÁ:d¯tâ!3pº†-À­nÁWíûpß}¿Š'{tphaV|:~2’8ÆŽlt•Š>"1亖eÅUÙûÚÇ *=ʺÓÚמ½æìÕaV Œ1<þøãozòÉ'Ã… ž{ýÞðâùsç˜é¼ªPÉ8£²ËCOà‡þÝ[ðí¿í¼úÜ#Ã5X†å ïí0ÊÆ÷ ìV8³;H²ªI%`ì$)çFMã>bøuÚ“|«+ÏåóMܪ咳šÂÜÓÁÔxÂêä{´:ÉI @4šŠ€(X�cdû‘�À%±‘„ ü©²¼k¿ã‘´W1–‰¯I5‚±UÀL_|Í)3}vŠg>¦þ2n`:²+˜øVÇ==ÈaŠC'$9™Q&¨Ç�}æ øÙϼ֮;Ìö³;÷§z,—·½k<õ>%ã'ÀPWÉlìqYýœ‚Ȩò튂}’òwD&#¿¸rP†š¤2Ì B¢˜¾TiÖV¿ˆGU‚Ç�ôC¥ÞEŽ0e# ämB€FIq§ó¤~"æ㊘Rû›—G©Õß'ÛQEL#*ýþˆÁ%±€ªæœëS‘~7¢�Œûtì<¢ZS}¬nC{F0º¦Ê?Þ^�Ø1ÍvÐY:YYçô.wÜ• ÀÌ5h}õ:’ŒÏÇ9Uå§¹+òWj©»åŠW$«�l‘IZÍEOB‘mÏ\ݸnÏ5IƒmÜÍd†�Ô¡J{Ç|Õý™@”R52Då¯ù2еÎ]çÆÆ“ˆ´g¿“ö ]÷]O?ùø¿»îú? ƒõY�%ƈ®ë°Ùl°>ºŠÃƒ´«•Éû ú¾Çv»ÁfsŒã£-BìÁÄð�Gã°sC=-sËAY£~_•òî•H®Œ:lŽ�qõèÇGÇØn;°Kä€<ä„ zˆ$&åšQ8ÇF®Žé8Û-ºn‹¾±z FÇÍ® ëbéº$€Há\#/‰ˆ±G,„íÔ/8×”÷æ%–Xb‰%–Xb‰%R,€%–Xb‰%–x…G�k¯Æ:K}º°3Éë¬ÿúçi&|>Wþ·ïç2Ô3È^2¹'àŽéùêë›j0¾ÎúÏ‹oT¯Á�º òuL³ñçÀÿ\†ù<Ñ<5ó>uÆÓ4;@þôþòÏõýÍ]ïIÏyZ–3 ‡-€ˆè"º®mšˆøº÷½õ‰ßzÖ¿ðMÿð§Åݯ¹;åÈäLb˘¹† ÀÌÍ�€Q9A†µì‚Ú~»*©æS¬•€ Ö*K¢Œ¯AÍÃÖ;Æ—¼ë]xìÖ[qÿG?‚m×IùiÎ�Îý¤C*MàÓaxøE*@C‰ï, [ê\Êð–ÙÉ3®ëN:-�Úšˆ€˜ Që:î{ìñ O>ù¤Üzë­—ÞøÆ7Ÿ;wŽT±Î$„\ÿò>Ð ð�ê¼ã ð�oùP�’³Œï\vu–þ ý>(wQ“HwPa€O ^pª‡*ŠÈb Ö3ÊX:¹�œÜ”,CR#1òH®³ˆ1£‰}šü…•x1!ƒ¼æe®:ÎìÉ¡WYÌu;‰u}µ}â z¥Õ÷ó%õy)'(tÆã}*Á� ’^F?Ry„ïí=t&#Z5?VR‰9ÿúY™Tó`ªž%ú9yASBI öŠdýS_’쨲«˜6°Z~…̨Ýn¨ü^5g�‘IjB›Ž@~…Bã �Ž™Lôb“Ÿ a† dçC��N×VÍ 6J;ÛéÔ}’ ½¯]LîC÷ôJS)øñ˜<(ÐIýƹ€*1-¨ªJ"$¾ÇT¶=—·Wi�ê†Î�¨ƒ•ÇÎØX�Âée´ïï3 €R,Q…ªî§\ƒR‘4×Sº^¥*?ϼjªG“ƒêÊWæÞ#)!ì¼Æà4UõvÕy}›ƒÑ®} MƸºì€Š ±Ã1ÕÑÐU„*yÔõh4¦S!\Ñ^RêžÑ£Vm:eôjGšoÈ'Ìp³RÖµœgtÝû+ oŽ�þú™³ç¾‘] J íb*¢ú€Ðõè»-ú¾ÃÁÁmÓ€˜ 1šd~�®K–à²j™3Â2ïD;Àæ‹Þ;8Û6Í#Bè±Ýnqõè*Ž®^Áv»E”h QC›ŽA� ôèÙ¡m[ˆØ”¬bt]�ÍæW¯a³ÝBUáœCÛ´hÚÎ¥w«¬xCz'#SÔðÞÁmD±÷%€`Û…¡FðÎÃûfY8Xb‰%–Xb‰%–¨b!,±ÄK,±Ä+82<Åkð¿Ž)ð?Ù§D€iì“üŸž'ƒ‹SÐøž?uýT¶¿ÎÆïºnG®²Ôëë¨3å§Ä…9²Cÿ§ ªZ®3gý×v'eÕeš·= ôßWöSð¿:—p†ˆ®ð*"ºåΛ®¼æw¾ësðö›úwyöëç^<ƒÿÞÇðš×ÜmÞ˜v\Ä�=·òvÍ š§ðÜDætgÔ†K ÌD͇ÚLP;”x²ò›@2ú‚”{Šª¸íŽ;pãM7â#÷}Ï<óT¨‰Æˆ�ñMéÈ£•F`OíÛZyTgùnÛ–mu»ëC➎2Ûv3Mw|Љ ð˜3ù\e¼Êh{á§žzúú§Ÿ~7ß|óöõ¯ýöüùë‘ȹML2T¿ðñ�?÷Eø#_õY0ŽS6¯2@©¾ Þ© O eJ}V(Ô…TÎÞ¥¿“iô“$ùrV[ß  6»rHÇ…:ƒm#P_¡³#·�t®Vf€)T EB¥ÆM‹rÅ�d»O¡¿$q=k“C¤l©AÅ6` VV #NC-ƒ_eóËžìÍ�,Ï%È€WxnɶžÞׯIwšÙ¿OÞ]÷íQa½»ŠZ÷ª{žÉ¸Ê�TÁø‘O¾?ù‰»­Íô;ê6ûú["º Ð󞊪O_Þøƒë¼\/"©ïQ€ü�áŒJ”ÁL½‘K8o#cÉõ|;Q4Y@ºSŒ¢é%\p g_Dñ£O™ÓÙ²DVóX2z‘-5rJ¦Œû æ§.Í%²Jþ[‘ÿà’\Þ%“Ŧ P~ÎÙ½`Ù_oæjL±ÑÈ$€� £#@tB˜É|-AÉt­sÑU'ÞõdŠ/Y¥®{À™FýS=~bâ >–¨qU­5øI÷ßþìØ«§6ӚĠs€}“N;Þ´YRõGBRäÐìF2ukÐô ÔúmÑܦtVQ*�¿;àoU0DùYfûô,î *Nç¶ãÛV{45½ j;#[$©ØÍR•±>-ȺÍïQ™˜dÿgŒŸíع…�·Õ‘]S=çú"~§A5¡(ÔÊù8…XBµxÀp<#o &@þÞÖ]«VTí£îÒˆ†¶9;dìÖÕ9‰ý1�O¸–ü~ª<Fm‡ê;›WÈ*D½v�“HªúÚ_xîûn¿óîÿ6F…D‘Ä“E±…˜rJ~œR2ìc”Ò/%>W,6Zi±×ƒÉ�ÙÞQLÙÈٻͪM |ýn–•®^½Š+W.c³Ù@4Í+½óðìÁì¬NQ9wzrÅò å}ëøx‹ËW.cs¼AŒìVí «õÚ¬ §QY€¤ñI$"†}H PÊVx�ÒÜ’Ù!ºXÚüK,±ÄK,±Ä°9áK,±ÄK,ñŠ ) õ>ðŸ&RŽ'jpzNÆ~@F@®žšõÚuäãÔûÔD‡9KƒLÈûO¦àÿ4ó?ï—‰]סïûríyÛ úgÀÐ?‰0U[8Í‹rªZ`D§ª-R¶cÿÑ97}ó»ù¦w¼öÒwœ]ó­ GàÆ«^E¸|é9\¼xçÏ_g€¹-kõœ HbËœ9#Ÿ¤¼“˜=^��džUeÁ–9+9KLÊÕ8V²6Oj5„Š×.cÈÀg8C gË™´’þmWk|É—þ<öèçð‰�}Ì2†‚B¢t$Oàê2 `öNKyQncy 7Ô£¼x®š|V'‰q€\ÚQÔ[rØ~L•�.íØD ò­éY<óÌ3«§žz 7ÝtS÷Ýw‡ë®»Žxb†«ê_®[Ÿüðÿòv|ï·>�3|Êš¨%LIn� àÞ~$"ùÛ‚7‰�‰&ˆz#L3úr*Àİ3£;L»žð"š\ ®)ÒBó(FB54Ŷ½L6Î•Ž€èÊÏg™ïl ‡R)ár `óÇÖJ¢{*r0BúZ8ôà ¸‰d;ØÒÐío¤éVóqs¶õôVfÚêË:Å“¼"�ÚPV !J™N9Ç\f>¾mr¤+üõ¼Ï\:jî»gúæ °!¢ =àiO… O¿xen[w÷¨&ˆ9IuCr±«"Š€•Aš@}�j¾àµ$xz ®* r �Fމ‰c‚!õºÁ" ©eXß){ŠMu7™œíh¨Ë:ªÚ”lE˜Áð²l~)Òÿ©|pÝ\ „Aˆ‰ “y?ÄÈ…ÅŽ ¶,@!Tp< æ�C2ÊNÕ2¬�¥ÈÃ’ó"©L#ÓŒ¬²ºUóÜ$©<€ØÚ�VMRUÁ4j@'dí*N ¿ Pr–‹· ò1qnLÛw¬™SÛVìä‘××PSÏ´|7O¨HAs�6“älw¶1V‹UEUï4]_IU*0}GàíЧ¨š�é¨Ï$Hºc¤3$ =ñ×LV‰Ž¯m§ëN$4:©kÌ7©2/H1Õ¦/ä ]SM”Ò2©ÉNTŠFe˜ç,#ÂU&)•,ö2Ùþ©åˆ¸Ïê:ßm3N{õ*ì]�v…Bt¸.š¶Ã™ÿùŒüÙ±FÇ…^ˆ ´+…�¬ö=c&*„¤kR÷÷)1Ä?øâsÏüä-·ÝñS1h!…DÕI½Yd8g |ãHÓìM ¶Èï'‰Œíж+¬V+¬Vë‘rÔfsŒÍæW¯^Áv³�H„7;´¶]cÕ6ðM ç}u Úf…õz…õúìBßc³ídµ‚-Ž��’Í€cHLΦqhoo{�âÔäw0.¤±±¨�¸C@è“;Á¨¼–Xb‰%–Xb‰%–°–Xb‰%–XâÛívþ×Ùáy!@®ç¼çk`À,øR¶ýý4;½áç¤þë먯w zçßCåXyAªþ§™þÓ¬ÿ|Sùýú}ßð¿ïûr®:ã¿mÛÙëßWFS€ú÷)ÔåY•#«ê!€sÎÑ9f>×6ñ†ïü­Ÿþƒ¯»íø}�w‡€|Û)¡JD„/¼ëÜ?¾ìË~kZ ´ìôé³– ¦Y–7P.cß{˜L*°ã�‹êoõßÒ‚q&H ±dð›€>”’·4qΖ¥’Ý–¡‹¤$ `a$b�0'ðʶyõ]wá–[oÁGî½Ï?ÿ\EP(€‘Ì,#@~ü\uLˆ±ö‘] 6ð1]މ9ÇÂØ«y æ—×q–n®ý†©ÊBËÛ;f³%Hmä¹çžkž}öYœ={6Þyç�rýõ×sÎÆb&s!\½ªøþré÷Gú+éQz³¸WÁ§pNÌ Q>š4¥l[ËØ%ßìg`��ìYC]$Y%X²¼jQÓ§a2´*@n.v3q³BÀxØ€Ž•*§6 ŸŽ£™à äPËì·ïInéì¼M¾F�ó€åͯ=fE;–«dí3“Ádû{&p\ÛPIõKĤˆ¸fµð¯qšÊÅï”=F\…²�eH3Ñ ªhdóÇÒ‰¿´)wñæGÞ|óÃïÏJûcDDS;1ÎOúm($f’æYE xfý‡�ÿT|ÃÓcôU±Øx•ÈF<ªŒD6ÐJ B*djZv\÷Â:’ØújÛì*Rú¶þ;NýÑèÙ#Ù³hª�é91ÔY†2Wi›dŠSŒ¹V ˜kÇu�-Ê:dsV}v!_°‘L¨"¢hê; 2éãu”:ŒÉ4ô±T»tȬ @G�S¬}ªÈÏôÈèd’ÎÌ<,ƒù”½ç5[OÐŽsǸvä,ì:sþd%€’%^2ÿi^©€xlõ Ù”ã±lßíi]Wµ�cJðnE÷ùÈÎ`qÅ+šÌ}&Oaܪu€Ñ5ÏAt7û\+äÿóË3žÓÓPý'ß!+èbUilªQúШ”h§;§B�L÷£ ñL»f4Ij¯ \`ÇÚeÀðu\®¬˜æŸM” †¶¬§€ñe¿ÑsÐAµdR–Óáo~x<ý¼×´O*>:ºúWcìÇÁÁÙ®±W‘ ªJœö¦mÑ´+´­‡s¾êÛR_Ö4 $&û¨ô>“‰Ìö.„aëí=gµZcµjM-C°Ùl-cƒÍfƒ(ï=V«5ЮÖéxÌ JïìmÓb½>ÄÁú ÏÀ9‡¾Û¢ë:ø¦I€¾*¢DÄ ʈ¾)$åD0HÊmVª€gß6h|çí=EìÝ¥’ P+K,±ÄK,±ÄK,1ÄBXb‰%–Xb‰WpÔ@u�1_Ê5ð_ÿ;'I?ÍbŸfΘ•h�Êô×ÿæëÉÿ8÷ÞŸœÏà9æT ¦„)aJx¨Õò9ræ×%éHEò¿þÔex-€|Íù\§yQ×åžUbŒÀY"ºIæÿæ;_uü¿÷=�ü‘ÛoìßJܸ$Àø_É�øÒ7ŸÇ?ø‘Ïàï|Öëµ]ìàO]{ñª¤L×”x¬;¾Áåš«ÿ§{¨÷è£øÄÇ?†Ð'©úÇÚÉjœ<¢bka* 9ûHŒ/‘à/HY,u_@%/úNësµüN@¡Uöóœ}3Wí�¡qéÒ%wÿý÷ãàà·ß~n¼ñ†’ME£~…ð}ÿð,þê 8l7)«Üee¹ÉŒÐ£"BAnÈŽcGPq ¬%2Ø'5Õ"onö?¯3ty�ĶçH3ÿùYð)8ÙîŸ3ŠH{>¹Ý À'“301hl5YÆ€kN‹æ&^´5eÈŒ†��œòy nL5!KÏ›}B"#äïíü>Ë´Ûïb€W¤”0¾Ï�¦(Q—ÕN›�ËòÝ÷Ťsˆã,PÊÅ:J%ŸÝí¨ ÏÈ¢ÙûT¶¿øÔ]øg¿ò&�S´×¨ ¡ªW<à)OÑãDô(€'Cˆ/Ä7O]�6üÀºéß"½ Æ!+œc|¨ë`�Ѝƒ™0D–Ä'SåOÏ…µòHÊøWÎjI]‚0�@™8U‘E2p(ÖgÔ 2Í€É:Éb®û™ 4=ëÇÒåZH5óÄÚe&Ê䱤®ŽÕ¼"%r'ƒ�I�YŒdJ˜Ní ¬–ÉüĪ™Ê`§áC(I&‰‰tQI|×5YDM•Fá�/Î%~Ÿ¢~‘süeF*G1"�ÌWPŒÕÅih�;„½éCª4ÿ•0dÉëžk®¿Î$»bD«¶ÐèÇZ%¨ÔÁœ©ž‰K6D‹h©Wu¿2ª†lÕ™.E¡JÕÜ(É÷纮ӇTu5š§Ž´«P+î\Xk¤¢}T•jSÝF�‰nÿê¤X« us$‹?€ûežIØ�wfu‹⇖6<¶S¨l¦ÎZÛ& e=.Æ))´Ü4®�¡•êÁ.©ƒ&Yý¥¡qÙÖÅIŸ `gDËäÎïá”{œ\Û‰ÝÆä=`´OºþW?ùØ£ß÷¦·¾óϵ1v¢Ú˜š¶Åj•>mÛò[Œ ¼X­Z#D£¨pE Ÿ¶‹¦iÑ®Z¬W+8ç ªö^Ôc³9ÂÑѺ®�ppx€óç¯Ã™3g°Z­l¾™ûÒ¤ÀÓ¶+®qppˆƒƒÃò¸ÞvX¯ÖX­VhšD¬–‡÷*GÉŽ m°Z¯Ñx…‘»¡IÉÀ'ÂqRˆÑŒÁTà�<œÔ`’²»_+óq‰%–Xb‰%–Xâ?¯XK,±ÄK,ñ Ž TO%ÿkp_æ��’çü¾¨Mk𿾞¼ ºç,ú)á &dà2ƒòùïûì êýòöu™äØgo�AöL¦ˆ1–s´m»þ×eIŠWARJ¡ª:HˆáÇ|>ð©/@Óœ®Pcë\QÕ þÀ#Dô°ýüt×ÅË}´ïÃê©+íÿvÇ™ã·ô!© ¨*Zo uö6®ŠHTÁJ��*5'ˆ9S}0€FÀ6Sý¸¬Ÿp\DYFDÌÀÚ½y-'eŽâŽLKÄ÷×:ìO¦¦ •ºÉÈ3{”\ÕeÛN£"øh!¾‚ŽbŒ0œ9}ÌUÒpE|‘É“ÀäÓã@�J¯?ÂD`8ËúW@^>éd|NþêÜ«Bè­ß,c:Æ$-ªÊ‡ªïk~„î͂ƞ†S¹"ÐäZ§6º¯Íä/ïJš�¤;Þë'Gí ?›¯s:©SƒOÞ&)+”±vç™ä6™s�Rúµ²Ðî£>7Fs×<î\€F©ÄSEúêÙWsÖ¹’Ô¡ eÙý"PIѰ£0� YpDª Ý±³®7d}Înß;”O&�VûF “µ>owu­ïätBƈP=ÏLb9­…ͨ¾G­È û9:¡]Uc$*Û^Žýˆ7 ïûïxøÓþÛ7¼é-?¡J½cV盘²õW¦NæÍ"ICD=BHä±ôÖÀy#1WVy\€¦ñöîÓ‚™Ñ÷ú°ÙlpõÊUlŽ�CÀúàçÎ�ÃM7݈óç¯CÓ´PUô}ÀvÛ‘Zágçuf= ªI9`½J$€õëíAé‡}c*mo÷×´éÝQŒ ç<Ã;6Å(…ˆCÓœJŒ(ÄE1Ê9_Ôã–Xb‰%–Xb‰%–H±–Xb‰%–XâY¬3í§^÷SÙÿ¹¸–ÅÐt¯?9êk©%ôësOeþŒ²øëû«�W/×*Ó}r¹ÔŸ¼O.ÃL\È?ç¬ÿ9Éÿi¦uýó\ùL?uÙ(åUäãÓ}¯B«ã*„pFDθþ¯}á-¿û=OýéÎàµISÝ!I—ó�"]²þ³W¹O �:ü–·]�UËøä§Ä[Þú¬×(‹ñ–ÅGš2ƒëìÅœû]~™‰}Ui'ë‰Æž³DHÞœ‘ äJö|ò¨OÙ:Yª>]j‰…Ólå Кz€$ùl˾V¬×-Þóž÷âñÇŸÀýº¾+ò¯ÃZpí¬ĘËL•’­–ܵò5&BÉʧI�Õ¾½5Ù¥Ú`�®*×(;lj1A•œí !nËÚ¶}||Œ‡~O>y€ nÅM7ÝTÚãÒUàÿù#7à¿yÿKEù~0²Œ_Ê-­V‹L–À*©8ÀgO1Éäç|Bû¹¶Høõè= ª ÁŒÓTL¶To—.�<€h²ÿÞ<�+é}’ G‰�ù™��-ŸŠ„5R@ÉäWÛÁ�S.Ï]TF‡Lé$iîIצ¬ƒÁ¾nüå"Ó( yœš<—Y\ɲC&§Ý“‰>y60ƒKv}EÚr„ÿý�/Ƈy5¼ß«&¿‘äþŸð8€ÏxDU¶ßŸ{þÅg6GÇÛÆ{wæ¿ã_}Û=ø?«êmª@„M›È/¾x¹¿ Q¡=Á?¹ $š ú¢¦’ac¾UŒ ÂTõ±”Îe€78‘¨4«0Ùù¤J‹®@ÐÒÙË$Í—Ìâ£j¨2$“ Ê¿dßE!Îl*¬sLúF±›ÍŽ ×T5%g• Uê89d€L=mÌÌxóëoøÕûÙã7Au5WÿjÙþ4GÄÖ™úK3ê1' ”Ÿwwu-íf_W�#s_ï\¹þú]ÿ‰dÒ)xÊ¹çÆ¹“æ¯×Bd˜4í�Š ¡d° ÒõûцRÇ0Îò�\P¦™ûT± 1w¨Ñ£ú«¦8S¬!ª+©- H+ƒ…êš’µÐ„1¢U9ë)å¢s¶ U]0å‚rZT×]é.è¯Øeì3š �¹ØtÒõò &Ÿ–cÝÏ|>íÈyùòÅ¿vñÅåæ[/Ï^›ÕJW«µ¬Ö-Ú¦³³²,Ó_LŠ?™½�”÷e.u%«µQ!GoŽ�qttGGÇèú-˜«U‹sçÎáúëoÀu×]ït}Àæxàxx'@$ Æô®ÆÎjÊpMÊî?88D×m�«ÉÒ 1Õ¸šÄNFŒƒÚû —:O’ÆNu-Äç9&¥ñ’žÝIÖ@K,±ÄK,±Ä¿)c!,±ÄK,±Ä+8¦™ñ5ðŸÿL8 ô?@Ù{ÞüÏ =9ê¬çÜNýô°|î:ês×ûçýöò>5ðŸ<Ûãl·#õ?'û__çÜ‚÷T¥¡¾ÏL:€cc¼.ÆxCŒñzU½é®W]~ÝùU�þÉ›¯“/$ÊÿÎä¡�y¢ —üÕ3 €Ù@˴ݪõømïºÿþƒOáÞ_½ïý²/ËW¾×‹×nh”•¶´¿êY ™“cßzf‚€KF¸ËõÕ1;8ÇP�À¨˜A$`³ŒÈÀDfÃX3q€À’ÀÚ;ï¼.ÜŠ�|ä^<þØãÈÃ4‘öÕœµ ʳ4Ωܑԭ Eæ?ÉÚsµÈªYÒw6±Ì²Q¡E†7“2ƮĴ¨€Á%“�ÍG|PÍ�Š˜�Êm³9Æ#�<‚'Ÿ|·Ýv;n¹õ–RÇ~’ñ/~áf|û—¿huΩÄAá,óÊzÞDv\ÊV7w3ëk@?Õf¶l­”J<Ÿ­¥¢ã¤fkc§­íŠ©öƒ` Ó´ã=NëÆÈ5™ÙŠ®²Ø`bFûM-�(óœQOr�¤’ÌÞc>®�²$†ˆ*Xé?kòÑ*Aê)ì:¬~ 瀘àãA dÊÈç rMŒ¨i¢€¡îĄҹR×[ší/ÆçÔòŒ„þÅGÞ��>v;®a_\ð¢}žð €'<�ú?®ª�xö�O|úªÔ¶ œs›€Õ¥Ï]¾á¯ßqæ…¿#è@A±� ò€_�»ÈØ 4 ðD<ð4î#à¿4EòES†¿$“˜ýCŒÐ!}(Ö.�+4·bÓˆÕYfJ’Ö¬É> HéWO£¨ ä€tB¬úçDR©úG•BüÉ<©Zª|ú|S+¡¡_å±E�ª¦ºN@f€h¾^Ñ¢6($ êîPY’�B% O ( îºýÌcoyë;þÉ÷ßû߈È-õeÑ@M~Ô ¸’I¿°o^òk�Àu&S~ÏœìT°ž*ã�o†÷™ã_Ãý�>ÿž¥dZ“!às>è3jö{­s €K×Îe8)ëüåø¹gÐ?[Låëµ~nDãùíŽEùï<¹ÇaNEã9Gõð´".2B™Sh‘ÐÏO~D„žXvy¡#ë…)­a*ç_Ñ ö|—H “g '>£Ó”æ˜/Õø~Âpuz…îwúS©_ö{^õsê îxè¡O~ÿ­nû^öNšÆK»júUÛjÛ®ì]Bc@&xEJ¤ÚDjnἃDA2¼KY_DZZ5eñopõêU]=Âf»…ˆ Y5X­Ö8sæ,Î�?‹³gÏ€Ùƒ7BA´McbLvjÝ–qì�Ó;VŒPÞ¹š¦ÅÁÁ}Xæ€�÷h¼·q>Ù è0aO¬é01<+Ô;xñ…p"V¯;0/ K,±ÄK,±Äu,€%–Xb‰%–x…G-AŸ³6ò¿SE€©L}Ž}€} žs€¹,ýú3ÍüÏÇ©Áû¹ìý¹ìæL4¨÷¯÷ÍÛí“鯯»d¿¨ŽÀÿõz ïýN™Ío ¾¦é}Õd‰ŠàEäúã…ã綯ùcï{è¿~õ�Ý=pލdûgPßc�wö}ú9³ÞVÈ2I€ð-_}ÿþƒOáÓŸùÞü–·àüùó%MIˆûŽ õ¨ÐT:6ßÿð³=Ù²$œ³¶8MÙ¼€í àK )«'�ÿnÈ8³Åæh²Ó)óÙþ0’6'0Âi2+$¤±“TwDÓ´ø’w})î¸ãI|äÞ{±ÝnÊ6õ-’ˆt°:FµT\¼kóºÕMÙmCÄ%�.ãšEnW'«¼ €(êËýÖkì5øUÀ.kÙ‚@+û¹f™ëÚÊc»Ýⳟ}O>ùî¼óNÜ~ûí`vøÀ}„÷}ÉM¸éÌe€šTÏÈŽÇ$³�(êVç vï•:~~ÚuvÿpSy�—g�þzxª– ¢¸¶ü®œ±Ÿ²°iï6õÏSðoŠ e”~Lr(ÿf5�l%`.YV&„ ËVð±`”-[ç�2Šf~9#?åÒ-+¼ÎÞ¾†¦Hº—z_AÏ!¹?¨ v”þ¸'[šhÏuQ)ξÿíøØ“¯јl¶çá]BüŸ@ýŸ$¢üó3žð‚ª¾øé‡»zxx©s‰hKÀчžùŠ¿áÎó�Ýo�š²ñûl%�*‚³ ´-ƒ‚&;“`® (k± ÐI7©ùYG*@· Y®¨ b¤dç` ·†„X²ÿ‚xË„$Co¦‘Õ"’2€Ϥʜ/þCÑ€Ëí‹°p§yHÕhlA�ÉQe¨{¹<Êþ‰Ä"Èum @hèû¬`ÞÒˆb„ƒZÁ`ª,(¥û'Äîu¯Ãý¾i¾û#÷þÊcx»Î̧ùiÆum­1#;¯ѹþääÞæ×3öå\Ó\›³ct=ý$3__Ë}•SƒF^õ{¶œ�“Žç#Ÿ_F?Mù=;½Ð³¬zžßѨ?´Q{bóÀS }EMF†«­t Öéäz2‘3Í0"<õžñÓßUЍæ;ÓŠ;\Û^é™��²‡èq2ë`Re+UݳÿTy`_Â?�ª]uïùO&иµÙ¼·rvú<ê$Æ* „¾ÿ½÷ýê/ÿÄ»ÞýÞ @ˆH˜]pÎÁyWΟÞ3$¦9½³÷,„á=(YŸ êgÎ;põ޵Ùlqõê\½zÇ&ýÏœìÑÖ88Xc½:D»ZƒˆÑ)e£ ïú>@$@4) ¬ÖÉZ šŠ�s«Õ‡‡Î9ÄÒ;­Ùʼn BìA= ÎÙ³z¶/2éÔ;†x_Úqz§Isaúõ‘�Zb‰%–Xb‰%–øÏ&ÀK,±ÄK¼‚£ºkà¿VØ—­¾ä?iq³–æ¯%ÿk ‚iæ­@0Í|Ÿ‚ÿ5°RÖÿôû²þç€ÿ©jA–àw.-h­×k¬V«rÝse>=n}ͧ‘&æTìX+7ˆÈU½ë�|ͧ¿ç-¯>úzvÄD¾dú'1« >Ïé{“üGÿ;µŒçßþe°^;üÒ/þ¾î}_?”¥ $ Dâ KÍIV“œ9Ó¡,€!K±^×" ]Žƒz‘ZCÅul«?þ³c[2¶ëS)࿊¾Ìù|- †0ÀbÖ¶:žêCµáÖ[oÁW}Í×à�û?ŠÇ{¬d‰Ñ€J¤k$1ÊZs È�.g‹…êuœb>ò=ÎçÏ¿€œÕ!û¯ö™=›¬ŽáßL¤PQˆ(ˆæ½�U]×ᡇÂO<�W¿ú.Üyç�økÿÌáÿ«C@’ÂàðOŠ6ù›SªsìjJcu5ÕEA¶ºªB GÆ !ÙnǦ"�n@UÌâ!߀$vm²‚@εÚÑH)¶Í�û.‚õAƒËÓãÙå�³ÜIvÁ Â�1]ꊑˆ­,G½¬ÕµT?Ä®O"LÑ¡J¯êEºG{ð4Îf,ýR®$™X°O|ϯ¹nk)è„o’ùŽ]iüí DbüèƒoÅ}�ÝUÆš¹±Ðbà2ÀŸ¥þ? àQ"z‚ˆžFR¸`£ªÛõúÀHr€¨ª*"‰ñê/?÷Þ¿ðΛ~îÕÌáM”¹ \Ù ºíÁÚ <-€–�UKhAvÆŒìUÒÅ�AqIL,8�Ié$ŠRßGU™Š(œù�P9Rpé¬âj"©Ù ŠŒæ2Äëï²Ý µµN½T5N Yv­–ÛbQ�©@h°Tg—G…Ú“¼¬ì*ù]ð_G²à¹KÕJ–\TÁHTHâæx{õì¹ëžýò¯üºïúùŸû鿸ÙfU‘¤�¹všaÒ÷ì”N ?±¹aÖ„}÷ø'�¦58:ië:qó˜»ÖQÆõ‰JµýО÷’I3ð¼Gžýsªñ­Íü­dxï-}d{0ŸÝâ3=… ;åŸ;ݽ[aNã?ý¨#ÒÔ´¾Í]CžƒiuÌq^~=Y°ñ3C�5(ÂÎ¥�žz›Uw»ö} è×ðÎ3Ì1­WvGÕj´¥~NçT;¨âŽÎÕ…±*G™ó]ƒÀ0Å¥_“­ÆôºTA—/_ü+O>ùø‡_óÚ×õzfv ï8õ},å¹$»8)ÇÊvT]ߣÛv¡¯¢ÉÆÈ1#ÄˆÍæÇÇGØlŽÑ÷= i<Öë5Öë¬×k´í Þ7&“Ê(Š"„}×A4"ô.‘®ûÝ Îû4= Ž«Õ "ì!$õç�YBÒœ,Æ4$‚:†¨ƒc2ë¶÷Bã}¹_‘lUÅ ,€%–Xb‰%–Xb‰:ÀK,±ÄK¼‚#ƒÜÓlûx¯c ô]KÔ üøìfýOÎ×Q¼†' ÿ>º;ÍüŸî3ýëóæíëÌÿÚï²i¬V+¬V«‘UÁÜÂðܵÕ×W—q}�3¿{U]Ñšˆ®pó7½ó³ßòåo|áO¶žÎ$_zþKÖå�NŠÚ¿Ä&Ñ—|Ÿ31€]ɼõ©OâÑG?‡×¼æµøÀý¯ÅW¾érÉîUu ö 0ˆ[#x ‰ˆBð7ÕßE ²[†=Ë(‰ r r­2´‡ú[�*äŒÿAÞ<Ù%hyfRÀq€)ƒ 29†Bãp¼Ðd‰r"¤ tø°NäûQ€�QïbÚ¨2£5VÙûu²¶huO˜€ §ÀŽ¢'ƒyûÖǧ�eWc¢˜Ýï­É^Ô—Aû‰?õÈð¡G¾` @E½}:½ªvHÀþKžðøÿ9ûù)$+€«¶`µ^¡müày‚ hO ãc\xöþËïýî{ÎþÂÿ Þ™91—:A¸hOè{E˄֚–p°b¬ZÁáÂú\Àá!ЮÞ% R$Å€(ÈÄï"ïÀm´6A (ˆQS_lŠžS?ç1�\„sɃ(Y¨8yô r’Ú„ DÄêe*sGØ©ëåg“é�Ö'Ž<2j+�Š dµ3fÒ��ÿÑ€|©5RÈÞ, ¨32—‘ É!¢Œ­$*§ë/1& ‚£vݦïûîhuöìöý¿÷;þÜ�ÿë~ðÒ¥‹€×2ÎL{v‰~uw{ªÀËa̵\dJ§HªŸvÔŠk0¦^“@ño×ý§-£ý‰73Ã×bEPßÕŽyÞ�nùôsØ­¶µÝNÞ‡&þ}¢>MÊvÚ9�m�³iÒÝôü‘å…Í-®Ù܉滈ѣ9¥)Ì•ái>M†‰]>ÉôYì>[¦©ÕM†4Úû\ÇYÿ4�2TOhWC/A…�¡/«ÝÏ·q#õ¨ÞúéO}üÿq×]¯ù“c§ª�‘™’€P’Õ²¹}?¸£$‹&Qô}‡¾ï ‘»~ÇŠÌ¡Çf³Áf³Eß§w&ßx¬W+žÁáá!Vë5¼w‰^YúM{WAˆ¡ï¢#´ëžÓ¬�£mWi®íbèÓ�Œìg×B°w@‰Ó{€˜ä?h¤zÇœöí�ì� iNµÄK,±ÄK,±DŽ…°ÄK,±Ä¯à¨³íç²ÿ§žôû$è玛·™ík¹þ|þ¹¬ÿ,Ÿfý‡FÇŸÿGžŸ“ýçlæêýëÌÿ¼_¶'¨Áÿ©ô§)ìûnªZ€Uõ¬ªÞÈÌ7Ýt¾{ÍŸøúOþw7�—{R à¿�¬ ØŠ÷8`äeö)À0“­ôþÑo{-~ô§üò‡~.üNƲubˆU¦—{ÖÈPÒ1øŸ³í+@žg¼Çw”£@kT=‹Â³=O‰”›¼Ÿ¥2P¨`ƒrsfaQ N –9­š,òµ¹$¶Ÿê<^uãMøŠ¯üj|êSŸÂC}e°z Ù²¨=uó]é^ € ”hu”•YgZN3OËw:Ø íe´&Ù@Î|C`gIÇÌ2IüvE`áq„£”1ϤÅáÁ1¡m®e8o਀& &‹C÷e¤,’ñŽÒð↾¹ô+¢ƒ|xnD©wC>TX…5Yê<Œœg°'¸Æ�]ú=ñ\Ò'ð?� b Ȇ@2‰gža³„NM™ˆQIE£H܆>5¾ÕoùÖoûø©Ÿ|ø‰Çû›¢z}Q¨æG;¼—=$€éa’±‹_ à4ÀŽÔû5T‹" U*£cN8K§ÛÌ“®Ùÿ<—ë©¢¶¸–›Q˜Ûµž£íSʺÖgTÊiò,T+Õ�Ý4ú‘Í�fŸz™!d[ª´Tw¯d¯:@u–b P•Ñi÷M/×^�0ë[tê“yL!:ÄÌZq‚‰E�=õ4½SÔï:sEµ«æ5›Å¯ûîGçontM4¿íI• c"‚Y|ë/|ð?ý›¯øª÷ýH!„>ôÞ¹ÈìÄUäk1©ÿôaæÑ;Qýþ•‰Ý1]×a»Ý ô=ˆ€¦màœÇ™3‡8{öΜ9ƒÆ7É)HCúˆÉM‹€JRlQ³¸³áò>©SùÆ´†gF=¢˜Ý�Ù6¤q$¿K™r…$ò AÉÙ+�½?fµ¨B‰ n!,±ÄK,±ÄKŒÖB–"Xb‰%–Xb‰WnL�÷9ð?Ç\Ö|Ž}í92`?•Ꟃþ™„0'�_ƒßùXû²þçö¯Õjj9��M£ë­I ùÚ™MÓ m[´m[®ÿ´˜+Û9’žû·ë?GD7¸ãÛë#à=o¸ô_:ç|þ}É�ÎýI2 å� šÀUeÀåí̃�]’\¶Ìd* ²ÇÛßø*¼áµ×ãÁ‡_Â¥K—ðá_ý0Þòæ·ŽžKy´øo’ŠY ;�ˆl¾õTIãgß{˜O;ž³š%� `IrÆ:qVËüÔ¨ ˜³Ì¢Q:>'è–j 9÷*A[‰D�À'5ylU‚3’D^`tÌxã=oÄ«ï|5î»ï^¼ðâó¶�i �ÐX *1¢\ôPOŠU¸d IåQ]ü‚÷eN×ÚþF‹áUí,eV_®…Éꡚ\ªL"/Ž�3âÔ§Ûíõzá�¾º€%Ë^Ù2 Mu"ÛVäŸ1̻ؔêö&Z…È ¢`—ÿdPÊ¸ŽŒËa_AVщ‘qE0 ¢!¾»_öE¶:Qi9Ø3ŠFº öo~Æf¾;Ê4®•œå­öœ%#’¥  >_öL/ÂZ,*åèÝBv¦cŸgݹí©{sÅyºrù‘&éÙ»©ÆURe–�'<¿=‹þ¡/=g�ˆ.xIU_DúŸ·Ï "ò<€TõEU} I àE"ºc¼R«ÃLÛ�DA·í°Ý#Æ(ì¸k 7²‰gºOÄßõ—os?ÿãçðØÿMCxOß)bL| &‚kç ¾ÚÃ7€k€…t‚®D±Wô={ l}P¨¤&Óx¹tœAb?Û¤¤:ë!ùV$¦ëÆiñ`Ïh‚kÞ§þ-J²”ˆA¹@‹ ˜ÒˆJò1à¥�‡)³Ø3S…Dµ®iP{axlj¿6ÜFª²AÃÐþˆ×0ږЬÚU:Ÿª"ôŠØ+B/éç¨ã®Ÿ©Œ;ÄÉ?�)Ù00)|“šžÄ”½ºZ­#;î|ë{ŽŒ¯þÚoø÷þå_ü}~â�¿Bø¢Ýq\G°lU1oðùÎèN¶ä˜rkt~rò².  –7“³O@÷SñÿSîîó‰kʲ/cîË-cìíûNÊþ×™ò&Œ90ck#X³ ºi&Eûï�&–(JÁ²R î5ÑÖt¤º¢ÈÇžQ¸VqÂ^Ò×lVþLñU„ú;Ëú.×Dð[ðA;6\+ ”�g$ýOi6ºgî‰fJE¯±ÆÑµ÷´»Ç´\/_¾øŸù̃¿ø†{Þü˜÷ž|㻆H‰HÓÏ|mB@”ˆ¾ïÀÄ;jTÙ´…BÀv»A× ö�o°Z¯qîÜœ;w‡`vöÞÐ!„XìÈ¥wTÇ àO�ˆ¾Ç˜@†Mãá˜AmR_s1@¤GˆFH.„Ô2¡õ·jœÐ)|D°Z#²–Xb‰%–Xb‰%êXK,±ÄK,ñ ޼ÈQg½ïËü¯3ßsœúO%óëL‘ ºçŒù:뿎øÎ KÓ,þ)PY_ÿ>?o7%?䬚`P¦vøÏ×?wM/7¦™ÿòBc<àU7œ‹¯ý¾ßýÐÿpÃY}8!9DÞ€?dñ“3}^[øÊ²¼” <ü›�Ö ü£Ê"¶¬1°ÃýŽ7âÏü•Ÿ|âãÇ­·Þ†óçÎ[vh>TµÐ˜WØF‹×™�³ÑYËšÌ/Z p…ÔÁI®ˆ.SV'Lþ™ŠIé ɸ§mÅäÿ3ø¯QQ‹âªÉ芚�ôNöœýQl�’¤¢&òª1;ç®;�/ÿŠ/Ç#Ÿý,¸ÿ£¡G‘#í<ÊZTÕ´×$€ô½e³ƒTJ®]äèU�²ÿW ú–…;Z¬¯•N¬¿)ã³<Ê€8S—Ç Îÿò'Ÿÿcod“¬€´Àë ÎˆR®§#÷+jÊ@è Ò“žK�4©þÚ : �¥²~£~œ ?óK áLþ¦KÓ®À|¡Óß4ýž@ÿL@{#d%€ô @¬ö Õ÷¶ªÍ•Í`Q0™]5Kû=á9Cùë$”†TÂ]…ª]ŸšÉŒí¦‚2\s'•˜v�GYÖx8€ÇßûÙ÷šCU#€c—¼ˆø?‹$ëÿ€gDäU}VU_RÕ+ªº°ÍŸÜ.Dd‡dƒ ï;l6Ç8::†H;ûº&Æè˜{ÝgâÿÜv{χoåñY~ñý Â×z�=à øO`¯h<%–¨ ðAÅHA!ˆ–�/U_Ål€¿Ci/Î�ôò÷ŒƒPzþZeïjv� A`N6ĉ'–IDœdÿ5¦ŠQUÍJbŸ�@|aB Vs´H*ÑÀuÑ È'‚‚4‰T•Ÿ§H%(zò3ãÁEATFDDP†w©>ô}ÊäAºD8¨Õù™ÕˆdÄ™”½êp¸&¬#Á;@U¤iÚà›F è½s]LcR|Ç»¾ô�n¼ñÛ~áƒ?ó·¶Ûí×íŒ •Dþ´=èžf4érOAÎé„�1#²1êôçN6;/©/’F×_gÇÓ®Ôû ˆÿéê´WÕ'”§~L Uœr.=é*g›#ÐèÞx÷QL‘å¡�RiÀ3™þ»² %cË AhÔõR9g�-ŸÇÊj&3Ü�Îͦ7MƒÝÈ)CÆn‘œb��ë& 9T)�ÎA4Óþ&e>'é�}$€ýö4ºþk«SÓkº€k«Ûtb–2¹ùS~ü¿¿û5_ðǛƫ÷�8f(2sÖ­ž„0|½w…ÀFÏccŒ]·MÒÿ]…Â;�vµÂááΜ9‹ÃÔµ ë{B"ĪgYý¾ñhÄÛüNl(ˆ’,ÇÄ1DŒD`b°#ˆ08D¨Æ1Q²*™4oåÄœËVhD²@¶C0² /€%–Xb‰%–Xb‰:ÀK,±ÄK¼‚£V˜zÞÏû²Ó÷yÙgà:ÆX<"ëózïÑ4M!Ô•sÀû\} sY™õ5Le*™¹÷Óó××PßsÎ sŠ ™@P_Û\ÌÉû×ç¬î×Ç[U]‹È97}ó»Ÿyß7½ó…ï÷ŽÖ`8&8Pc+®9½Ó°l~ËÜ�Mæ?飄%3<#¸@ƒoû†/ÄßúûÅ“O_�ŠàWåCøª¯þÚ”y…`S&˜){<À¤<©S‰Àd¦þç}EŲPCy5hAJ†�°Kñ©4~½â,’²?!‚ˆ¬8À†�EóŒˆÝ¤TüE‡ÅA6ð-¡â Åk^óÜvë|ô£÷á‰'žHÉØ¤Õs˜oKÓ¬Ä$0,?+¦ ¥™Œ2"dò‡›É6©�“^…ÜFö%‰Ž€žU݉Eð¿ÿ‡'ðm_}à0C‡¤�È"0%B@©àT¯  Ÿ@tµúJP¨€9e£B¡dÊ #µz5ÿðâf¶MÖOAÔ|ÏGYzRß´}=@¢£W²Ä%ïŸÁ}Ñð#˜¬~0›R�µƒÆ.4€2„>É›k&ðÌ H4Ic;W± 0‹«ƒb¤¦,] cœy_ÃøÁïü-+wè¾´Èz™�U8#¾ˆ³ wòU6üo÷¾e{eÓlˆ´‘À†™¯ eþ?�”ùÿ¬ˆ<…$õÿ´ª>£ªÏ«êeUÝê¤ÓØ? BPl·6>Bv„¦mbúè½ï‰¸‘mèûãO½îç�ŽŽîíûþ¯~Ñ«žzÛÍg»·Ÿ_É=«&¾¤·2äzJ>ôBˆRYÉZT1pݧoG{Ñ›$oŸš- ä–:[›.�! § SLÄ;¡ÊHD¶Ÿ)HP¢9EH´¡Æú™œÉÏ.�“(Ù¡&ö7”®ÞúF€EI,ˆFV(¾výjí5�@�}�肼½&ž¬~å,f÷m]Ÿíb«Hï¿m›&8çT�à)“‹ê5Üu÷kûWÝrá»ïûÕ}¯˜�¿ñ¦›®¤9‚3+ “q¦)3Ãyç<§yFAŒ‚z„`ó¨,kmc»1!‘*5‘lѠŶ!í¯eŒ®�j›…|¾¾eþ–ç]Î3¼sp®AãØæPMÓbµ^¡i4Î'P0gKD´ìÞÍf‹®Ûb»Ý&‰ð®Cè{¨$B�Haì<¼Os-ǾϷæ$Èó|îºë®ïn¹õÂF£ ‹=BŒ¸gs2v€¤}û®ÇvÛ!šÏ9Ã7 Ö«V«‡X¯pxpˆÕª…ª¢ë:\¼xO?ýžxò ¼øÒ‹ˆ1âàÌÜpà ¸þ†qxæ DD„®ÛÒ•«Wh{|LÇÇGÜ÷‘û¾gq‚Sè ³/½øÂo»øÒ "×÷¬SÈ=yî[YÕsªÔ êh±ÛuëÈ2ÈŒ ~Žúu©I’ñ®dÑ�ú‰�(9¶&¢Ñ5ϹÜOžïïSߥûÆ ÝÕ*5ºð$f2ú1?—™ÚrèžýF÷SÛœ2d¾\~ʩļÜã ×Bÿ-?÷3?õÿûò¯üÚÅÌ‘ˆzßx²ÍY‹Îwp1 F)ŠO¥ß²v™Ú¶Û Ž�7Øn7…€×4-Ú6Ù¥µ«¼·~.ˆD›ºbHDIÇï=ÚU›~wdíÓÞ ¬v‹DÄÀ b8#z2ØeR¶ßµÅªmÃå]öžP „�æÖIv‰%–Xb‰%–Xb‰ `‰%–Xb‰%^Á1§0õ¼Ÿ“þ?Mò¿–êϋLj¬ÁóDÏç®ÉSòÁ ¯³£ç,¦ÙÿùžkË�©òÀ>U�¼Í>ð¿Î ­cJN8MâFî߉șãõªz½ªÞüg~×Cß{Ï�Ý7IÇ™\rÞüÓ3àï HãA € ˜­%»óßÉç‹1ð6û”ç¿»„,Q°‡§ßýoÃ_þÛᥗ.âc{o}ëÛª¬Lv Çä> ° *Å’ÙŸÕò‚[Ê2Ê¿›D«$PU4 Ä‘B!Bd†S7Zhffˆ*œ*"›RA^ E¤Ü’˜d³¡DÙs´–Ü× â£–ó�,öªFhÖx×»¾wÞùîÿèGpõø*”’oy–Ò%¢AN[³L�®R›í^T’\µ)VËf*—“@¶¬V�îŠG b+s×Å\òqrv[n§Z{åŽk|y¦ß`Ü·ü½þ ¼ÿ}_Ç €2$P²` dG!MÀA£¤ç! ñ�1˜€Š˜-2øÀhÏÎäö‘áõDE@×`Ù!f11ï¤=Íø¯íœ Ò³@ë%eôk4B5�ù >�ÿ1Zæ&@‚A¦ƒ €h&ÔÊ&y�¦`×CœuÚPRÂÈE$¬`\C¦-ïh5—º4úNªêóD}ÏÁi@»x_™Ó`iÀcBQú³â¾§îèï{ô¶gˆpEU/¸JDWDä%/2ó ^‘<¯ªÏ!Éþ¿ ª5ÅÞ>{Q‘ˆ®ëÑ÷º®C×w úжMãÕ;ßQ48çúUÛöÞ¹íG_ð‹—ÜÙ_×^ß\wx½?X:ïbÓôŸ»¡Û¾xÐm.ž‹Ý¶!íÏ8k&m€èIã:a¹ñ,h=£%:ßCØ¡õºVEc`ºCÔCÑL>Ò3*`ÉjØ"- ká„!šL ÕV… ½)Z"´Ck'Ïeå�öéÙ‰šHD->“«�jQ™Iä ±¿:©õ2�$&��4žÚ|¢êg²@�AP˜äÌî%ýÍ9«îµ*z®›¨ew²‘ ¢GÇ‚�-ÂÖ;wÔ4M×4m 1¢ñ.2³4��"Åw¿û½ÄVAÄk¦½«cÖ4ÿÈs�Î;4>ýì›�÷Ń:ÏÁúУÛöØn·¡7ÀLLŒ‡á}ƒ¦õh¼‡s¾Œ‘bwAß%ïî‚Éb+¼cØ=š¶…/Y¼Š>DtÐo¶BßÙ<.Y&$àÏ€y—²tÛv…ƒÃ¬qxpˆõªEÓ4i¬‚"öÛíGW�põê\¹z—¯\ÁÑÕ«èºt|˜Ê�÷mÛbµ^c½Z%²hÛš$xšs‰ú*‚i"B$"ŶÛB‚ Ätß±š²©Õ$RŸ‘Õˆ"’ˆed*ló¾Ð4ã¬gv‰äàL™Hó\š‹ÂNãë«°¦ÐrΑˆ’»$täX¢´ìøê™óç~áâÅ¿P.mKÕ,„†™@ þ>j#¸]u�ÅŒÕJýåùS-Sv¦÷Ök¸¶±ª€îþUi÷(¸:@{m;€{…Úפ…ü(PlÈÆéÓŽ¿o(Ü}¿Þ$€Z åò¥‹ßÿÉ?öó÷¼ñ­�‘_ëA š¦ÁÁÁ"©Í„¾Þ¥ì=.“£E¡ïqttŒã£#ô¡Q:FêWÙú7†ˆ"ôÑYÆ–V¢‰Ú´J+8G½KïWV™Ù%‘�Ä�t çv;k½bŠ%ûUœôÎiï2Pê»ý¯IÝm‰%–Xb‰%–Xâ?ÇXK,±ÄK,ñ Žü¯åëk¾þ7Ç ‘H;Ày�uŸåú§rû5ø_ã5è_KðO�˜kɨŸÊþO¥ûçÀÿéýÖÀ}¾‡)ia ˆÖ×\ƒÿu9L¯wß½Ø=œ‰1¾*ÆxÁ±ÞñW¾ó3å¦ëäu€ƒ¸yp‹ò»a –�ÿœÃL ½ÑâAnˆ ¸’bÍéð4€ÿpɈšZ€}Ràßõþ·áü'Á3/\3ðéO}wÜq'n¹å–ÎÃy®ü:‡œ©¡ŒLf6gÖä9϶¸^²ÿÍ_Ú2Ó“vò&u9;Èy°ËÞÎêe—£Rî2R!רôjõé ˜ïz­[ *Âeá¹’€„åæLÕ[n½€¯ºùUxðÁñÈC!Š?l2¾FÎÐÔñêö`X�ë'ÈJ\È y!3×!’Af¸øõR¾æ’ÒdÙ—Z½ôlvÁ× ”¤mbeQ=’—†uó|O>{ŒKWçW ÄFqБቇÌ^EÒ8gNÙǹ�’y@Ê.s)Ë]5&Ù×øŸ"– 9Å®Õ2äÇjÉóßÕÈuˆNÕ ¤° \¨‚G*µ¼²“H™�Éà<�æè‹¥Vçí)¢HZÔÇÔŠdP²gÈF2<§ÁWÁ®9'—²Žd�‡*8üÏ~G4h¿gP&gòñÔÒAÙ®uÇ[wÉÌßò>lÙªL8 kùg¿ô¶G}NUŸ'¢ç¼à%"ÊÀÿEWªÏeU½à ™öÔãxŸ Nþ[ ¡ïÑ÷iì ]€’‚-k[um�÷☻UÛˆ÷.ŠÈÖ9׺ÕzåˆÈõ}Ç›�ÒÑñMO]¼èqñâŠŽŽ®TѶ-šÖƒ(eV«Tœó8X¯pöÜ9œ?g›sX¯WðÜ ÆÇG½rõ ®\¹‚ÍfC�“•YUYbä \§><)õ´íª�ºÚÆc•�Ù¦Iú}�ãã#\¹|—/_Âv»AŒïçÏ’¿õ9<<<ÀÊ­Û¾KÛ^9Ë¥ƒ†¤iZ�ÕºÅÁ:›ˆ†,í¾Gì#Z¿9§R¡€xæD6sα�ÛäwgrSI}¸X_—~* Ž)�Y.œ…‚U£¨ªªÄˆ.†�|„+ÄÔyï¤ï;5ðìÕ9L œcqìú®ßnÐ÷®‘ú.dðL‰¸½ZµÕ<Œà*Ò»›fçDR—ªhηŽÐd` ö €VUPLõ·¯l˜º¾G "€4\ÈaÌ¡":2O£9PhÍ7ÛDØp ûÄ1³ eç8ö€x['Az~«¶A<8€H$`KÌL!@Ìì¡zyÝ®�ßÜß÷ÝÛÈäé¥ôAFLœÊýL‡›¡PEØ ¹Õ ó€\ï0ˆo ݵê,´^ËÞ�²ÿs=!-ó$ͪGó—>nöÏŽ‡ëœÚìì‰kƒü1k ÙVbbÅ�¶§ÊUëdÅ€±f®a[�½œDx™ÒùºÓ3§›þ̧ÿÊÝw¿î;ç:fîÛv½opp0´Ñív;"t{ŸÚrŒ!)|l·8>>Æf³IíÝyxߌޣ‚ù¶[Ó{G­Dâ=ƒ¹Al$®ÒûÈj€êާ9É éïÈã�o|3îºû5xàþ�à¹gž©d… ¶@ØY$Må¤%s3ÉBóh@^L΋ÇC;È7Jd–¼•T}eò;{9S“2ÐÉ%ãe²q�òý%uƒM¢]"4Mc2òGh¼å"9là”ä ®Èõðîz4íYÀ¦»‚‹ýóxéè­ëu"0ðy¸CÀv»Á•+Wq||„¾ï ’Y�ÇÞ²ß�K@¹/s�v4ÖG�1eçìñDRd"4mƒU»BÓ´™´§!íúN¶]'PĦըªQ�ØuÛÔßµ OÎùÐ0 3™"ÄDLêû1&™uï}¥ØBpâÊ&ÌI5¤ Çq �Ä ÒXqrxk™àˆò�ÚT!WÆ€ú4ö…T..&«¶þ2—éš Ñ'u€”eÐ[y%2€@¢"J²&ˆ1–Ì÷$ÙoDKõ ö‰ À¦šdc�c:žüN„]"ÂôDùX…$i¶#µÙ£•u׆`GmÀæúò•^®J@Ù^1†¯ÿ…~àwÿ¶¯üÚî¼÷ÛÕz%¾ñÙÆÎyĪ÷š4ï !$k�Í]—ÔJTmÊB0‹’4’(ˆÓG›’äHÆpf¥•ß½Z욊µ\H„ƒhDóüax4ˆ,XO;óÐú½�mÞ$ŒH*ˆ¡C±�²T¡�–Xb‰%–Xb‰%–H±–Xb‰%–Xâûdó§Jõ¶ûÀÿü©AüéK½Ð›fò9jÅ€}ÿLŸêŸçH 5ø?d¬Ìß{ŽZÞ¿¾‡}ªsÀP¾ž�,· ¡¡˜bŒ,"MŒ±�1Þ("·¿õ®—Þó=ßðäxÇ Ã¾ûUÊÊçÈÂÝăl?Ü��mæÆÜÍ ¦Z¦r–×%àþ; È%€5™3§¿Ûy¿ë÷¾ÿã?ý<ùô%ÀÑÑU|ðƒ?‡¯ûº÷¥S`p¡Õœ=¯Š¨:’ìvòQe[ ½¦ä^2¹^++Ëè—ÿ¤Ž—­þ M×d’ÿR®toK©ÿ”%*¤)eá_E†ç�®¼zU�pöð ~Ë{Þ‹'Ÿxà~l6Ç“ö9nIñ Níî²µÁ ïOƒò}–ßÏR¹œ 1CìJ 9¯À××�¯iH@¤±wwJçžHD€A ø±<ŽÿúÜ Ñê# Ð;û¹æ^ˆYRH’SðbÄWtDœ=¿E,c”vjAÝæ‡ÛbÌך�€1€!’žeÒÐÇœ<}ÉLTóšÖ`çÈw•‰5ÄäoKÜ&K€¼ S:�Ô%ù�!&¶�Éñ4’Úqdûžðo ê#Õ�¢ö! X)UN#ªe¡y¦!Ñ®ä®_¨Š„§en}« ărÁ`!²JåhBf¶}äâ�/}ú™›ïe¦§ˆè)…`àÿKÌ|À†L6ã$0qnŒ¨=ÇsÜxn :ÜrÝèûÚÞ†g€Ë¿ñ7þFD’rXâ?�àô¿—85~Ë{¿d` ‚C²Aèºmêï™Ñ®VX¯×88XcÕ®áÌW¼öøfÔ§'{ï³eB¯zôØl’uG ‰`èœÃáá^wgÎÂ5-޶=®^} W¯^<ÎUqýõ7 i¬×hÚ^¾xO=�ãã#l·]éÖë5qppÞ{\wýMø§ÿø¦w}é{ú¶mû›n¾õyú‰Ç¾X�oa‘¶îÁ“7Gš¿(Òœ¨ÎPŸfªgrÃ0ŸÒJÍ%Ϲ†}ó<ñiÈÎ]µè©™ü£/g¼tßÞJ§zÑd]�©Ñ,øŸËf–P0¾¿¹Üûº\òØ”U“Jv~å 5%?bÏuÌ÷EM ºs¹³Ûþ/ƒ6‡®^½ò—>ýÉOüì›ßúöGâJ„ˆûÆ·â«w¨Ív‹¾K¤ D ê±ÝlR›èºDÈE²(qÞ¡mZ4ÍøÝ/Š˜‚W"ee%ï¤Ií´e»d3âØÛدˆ! ë:l;B@º.{D¡jÄ&ïÊ;•™b~GÆælhr[ÒˆÄ3SDS8¡L¤vL‹ÀK,±ÄK,±D `‰%–Xb‰%~Ä\ÖüD¯£–@œn/•Ïê _öµ\ör­�Œ�e»)à?%LÁÿzj.K¦ù§™ÿsàÿ´ó¿ûˆY6³.¿ºDd%"gcŒçcŒ·¿÷ /~åw}ÍÓßÏÄŽÙƒ|jZÀ·I’¿dýk¸¦ß ‚š,mZ1uƒ¸Ö‰Y–õï2À2ýÙ%ÉÊDûÒvÞ3þ¯äËñçþÊ�—{zâñÇð‘ûîÅÛÞöv¹ÿTEÒvšfe"Æ$�ýÂN`+E“5·cˆ$Éô Žˆ% y\öT&Û3Éöñվɺ _#!:�S!IÙ~2³AºæJò¶xŸWÆææQšnWqûí·áæ›_…O|âøìÀ=!Ü$„¾dÛ©Öwfd„b]`í„ÆÞ¾ü¯$Q‹r|±�aQ;ÛX¦f¾G‚)˜o71ƒ-[1�g�Ö*£;gЫ žxæ*®^éqöÜ(5·V<+07iÙ–»Ä.9#\ Ęy�)äóŠp’Þ'ËjÍä'� ‚ë1-€â™|�ÂÆ'Ñ‹”¨m7À0IiíD€ ù: 1÷i/ ô€Þ+b‹É nR½Ñ`„�$i_†�'Ú±bgûE8¤ýðŸ�›þ†Ø™"ƒ™¨G#Q Z¶dúÞkú„Lˆµd@ÕPó'ÖA %÷'ZªûÐÙ¥ß%ÿRÌÝ5õàQüß§JƒN5Æ$!¬ÿô—ßõÃÞûÏxÀsÌü<=GD/Ñ%—‰HO"cÍ�yã C.?ïOWê>k‰%–89ÄäÁEmnGƒòÊœ@“ÍB¬×¢Î’Hs*šúr[Ù1¼oÓœŒ9ß¶‹’ç£ ÜÌj5±µžNç!LÉVSÎ#¸hÑ‚zt]f‡’ŠÆûïwjßw!„nséòÅ‹·¿úÕß{åò¥¿qùâ¥ßbü�ã] B×ã1 òü:��V6ƒÀ`§”’Ûµü>t·b6 •b”*û{3ÌO²µB�ÿO£!åDúå)í'©Þgµ©ÓeñwI“Qoö›b«4:RE¶Í³Á ä�ø3ûÀz»Ûž¤�ð²Uè0q»ñ‘‡?ó¯¿çML$ª*Ô9×·«F›¦MJD¦´‘H9ÛíW¯™²Ì6hLímµZ¡]­�Tf’j q*£(RYDÄ ‡â o`~Ûx8Ÿ–—cˆÅ$Š `¯å}Š“Ê'¶ð@Ð�#eŸ4'õÎ�œ,ņ÷ÔÁž ŠÀÅqË÷K,±ÄK,±DËìh‰%–Xb‰%^á1â÷e²þ°ûUjßû©|þôž’¦™•ùs༃ ®Ì[s?âlÎIDˆq…B #›«¾ïÀĈ>Z?"QÕpæààÐpž¯;><{îïˆÈ?¸|ñ¥/Þÿ�¾ï¿Dmü9uŸeÔŸô—@·•' *ôŠ ÿl㣚ç=ÃlΡ%÷ó…�‰l84VP¡Êzfnþ·×ó~ôÓ~ÙûÙ¿Æ>8i"¸LŸyW®Ÿæ]k²:AiÎáfŽ0w'pª?ŽJ—p2³bÏ}ª1†ßñs?óS¿û}ßðÍÿJb"HÛ´A}:`è˜7ˆ1¢ë¶É¢åè�eâ³µÕ¶m±Z­±ZµhÚ�oàØUªgË8ÍsY�3’/ÁH¦ÎÁ7­l¢*|èÑ8‡Þ”–rv?qD”�ˆÄfQ¥ªÉ–&ŠÁ{;‚s\æzѬdØY¿PæÉ™y‰%–Xb‰%–Xb‰ `‰%–Xb‰%^Á±OÂ~ `LÁ‹Ó¤ï§Yóû2Þó¢Ïô8S`¦îçΛ�Yƒ5ùÓ4ÍŽòÀœÂA ú×çžÞ÷œÕÀYbŽ1Í›’ bŒë¾ï¯‘Ûn¿qóÖÿêžÀ¿6ðeà»�£šWsQ€7*ò®l[\eýK•IΖéß$ðŸ[-à ü/ç©þe# dò`f|ÿŸùFüþ?þ«º!ø™ŸùOøúßþ 8wþœy¤W€^´Z-ÐF(Ä)œŽ=ÄkÐÚNPŽ3”±�à<•E�CP±"¨–ò†„櫆 èk–ˈ2bå‘+šˆ ŽRËPÔ‰ß.J‚+÷ÔÔ4Hœ9sïz÷»ñÄc�á3ŸùtíÖwên‘‚åŠÿA¨Ÿ-0&4ŒŠ1•G!UdiYè ¨@•"T¸€dIbeBRÆZ•ÓEŠèÈþ |ð#/âÛ¾ùuPñ€¶I ë¤à<˜[ëP’~z®FPq-@+«·+dò€À+¸�"‘A@ªè2 Í|>�þSjÏäÜVò÷È AF¬ém[K‹7°â@”Àz¦D4`DHt"ÈyhìÓ}PoÙÿ ’ �)HÄ ` PÍj™­}˜AoþE0€ 4#ÃLt!7œ¡>ÔÛPMJ—†\P5FÀ ­ ¡ŒdÙá&æÐ£ã¤ƒüÇO¼æŸ]íÏ~È9<®ªÏ¸  #¢üésæn''‘ËæÆÉ¹±ð´}O",d€%–8a!ÉûÂqšß„èÌÀA4eöz× i<¼Oòþ”ŸÔ�@ ©MYà  SïHã”C’5÷P(šØ ó=¸· g&CŸTœó…ô3(Dy0‡òkž·úÆ'Û+v JÛ…Alác„óÞ2ñEˆ ’õz®„ЭWþX�+‡‡·ýLÛ®~ñÊ¥K·=óôÓ¿¿Ûn_¹�ÜV(e6Œ¿¡?¥OC�ÉË u@Sf8aJ8¬ºzÂÉÙæ{�èk…Rçeôókiæˆ9 &»Ÿ;”„}™óÕ�4̳ê÷¤ù;JŠGã÷©—“™?KFÇÂüõèLñê5Îpj‚Ë—.~ÿ§üøÏ¿ý�ïþ¬Šö YÒ?·ƒ¾ïqttŒ£«W±Ùn VŸ}ãSæ»ÂÁÁm»Jí™-û_û®rnž¼+Q•…/i©"‰äË™˜jÄßšµí%©X{œZ…eÂüó D$¦Á.+…–q{‰%–Xb‰%–XbòÞ¶ÁK,±ÄK¼rcø? üŸÛ7o ŒÁwïýØ�Aÿú“ÿž÷ŸªÔ ùa ¾æiÆZtâ½ÞÎÓÛ9©æ|ÞzßÓÊkj%ÀUVXÞ?g¾ØÇ…E䆃U¼ëû~Ï£?à�kœó ׫5À«üiÎv«ÀKRƒc)åÑç¬$bËÖ’i›8T�ÿ Àë¢�$ÿë¬ì�PPÔ2ÀÈéß/Ï=øŠ÷Þƒ|ðã¥<ú¾Ã~ú§ð¾¯ÿíhšæ’�ó.—%T%�ÐY� V>›„vi¿"e[”cP, †¥ŒmÁP)IGËtÏöRIŽçäQ�çtü!Ù8e 2/{�&�o÷Vóõq•´ÜKþ s¶ Hv ª!&Ùá ní·^ÀÃ�<ŒÇ}4e- !b ñReÕ)AM–Õ¦ª¦Ç¦„¬šLuÙ ¹:ZÉ®qÔþ(ùÄg‹€ìCŒBfI+Ù\T-Êj¶H×qÿ§_‚çJ-¢® ´xuëà»fh·ž†úÆ+#¢Xýå�Œ’ê­‡ '°\ ¢Ž�I×Ûɉ=ãêž5ËÑW}ÅþõÞª]¤’È@t&“KÈí&•AÌy"f¹ˆ0<(H´ã Dƒµ¹>µmç�È>)P¶pI€z»³†²Ô Sê(ÄT¬­³]{&HU‘yzßõ�C�¾F”!nå­<m’²* €=5rÉCÏ^û'ý4€§¼ô7ÿæßÜäÍþìŸý³³»×v5ûþ¶o¼Ëȵ€9scϯZb‰ß Ñ®’ï·³9\ÊÈï°í:Ä�,_¼÷hÛ$5î}SÚe Ò›M” 4Úü4ˆøJé†JÖ~'ÇsÅ,sÞõ½Í)}É��¡ª³m<û¦³‘`UÑ.>�h¤M}§I†Íkâ¹³çz&"×4®mÛcUi¯»î†Í«ïºû‡Bÿã{àw]¹téÇ_£6RÈÐuæû*¤x Žúð“3ªcá®JÓè÷B(«ÿ9I¶¾&”aâyì“ê/cK„矊vIm<áKÔóGÔûOn’j’)¦EP½xœ¾¿¿ï§½GÏË´\ÑΪØÇ¸¸v@™³Ýô±>òýo|Ó[¿§;XwmlzO�‘æ6Öw¶Û ¶Ý]×%Õ*çp°>ÀÁá!Vm ß4hš¡mJ”êrdí˜pÎÃû¾qh¼‡#E×õ�h”¤Ø„D¤QUÄ èWuµ dnŒ&›ÃÚ4' úà˜Œˆ›3ý™=OI}„ø¦…¯íK,±ÄK,±ÄK,€%–Xb‰%–xEǾløû2ÿë}ëíì€öy›Zæ±–îÏ@K šïÌ烴è ûŸ?yÑiN= _k}î|Îú^÷ æ,겘ª Ô*•ä’‡ Áõ}¿Ž1žpË_ü¶GÿÛ3‡î q“²þýjÿÙ§…ÉñªŸÁÈä%PÏdÙsŠzÎâRÇv¬,÷¿N$´`“ÿO+Èn0õ6`u ø „u?ð}ïÇ×üžD×õåÊ._¾ŒŸù™ÿ„¯ùš¯³l¾œÙS•EY°‹ÅŸ³Ž²@ó5`ç¢v D�xv&€?Jò�Ye!ÌÓ³:‹ÉíÃ<†iB(P(ReÆ'„[±Dõ| hñn-jO­ì  é^¢$é{„$UÊÎá‹^ÿz¼úÕwác{Ï?ûl¹V-ƒÄ¾J,ÙM™è`g­H <ä^Û¢:Cy¨÷ýÛÞUUï«ú>YUvŽŒ�ª‡dé‡ (eòøSWƒ‚¼OÙÿ´‚ÐDky8^Y’<™%E"(|ù9­àÚ\ª³bÄ­- tWÈUÀ¢©Ž ²½2"IhöªÏ Àà™ [ÄžfÊx$P†*²@þ6�îH»µL}6kk{,¶]¥\ÁÆFA,Ï)[€¤ïM}€‘½F}@¶[;$¥²û‹GÙ£i ÑåoUv?�ÿɘŸnàÞÕä�z\ž'“Õêsדov>‹.ãô¨ÇÃÚN–?�¬&‡˜V›�/µèÿÓäØ4yP:[îûœhçzO·1عXݵ!Pú¾ÿæŸø·ÿúÿø]ïÿ/þ�¶]õDDbŒ1J=úÐ#„ˆBÊÎw.eýâððpô–ÚGjcÌÃû;†GRËhW-¼ÏªmÎÞ“ºÐ£G�¾óðM"†ŠB !µÅ¬`A™Ï*‰0Ë‘AÞÚqšó�ÂY"ÐwŠŠBè‚@ÀdïFLhLÍc‰%–Xb‰%–Xb‰!ÀK,±ÄK¼‚cðŸã$°cN¹íkÉÅÂHò?{¦NÏSƒ÷ÓLüé1N:þìË´™Ê@Oåù3:%Ì]sýóèOÐ;Z$IV6„@]×µþßôǾþ©ï¼íUøâÔ¬€f ¢¶È‰k,Àþ5™ÑüGþKbZäVà|:7€[§5`jÒ98gW2éd@? üçüsSüw�×Þ}+þèüZü�¿ÿïªrž}æüü_ñ•_•ʇÛµ‰¶ŸúaÿBÔ`ó%N—$@$G¥œ…mYÿ¶8OÉñ¼dÝ¥ <ÿG>®u’\BÔÇØöË4TZŠ=® Jƒ²�B¡¬£ú—ê]ÚÕ®ðÎw½ O>ñ>ùàDZÙlÊ• ’Æ9‘?JR|ÈF ˜t2�2ëD¬­&¦œ´½ŠŽP–ìÉ<„Œª@ÎNË™�"©¬¹Î×, ù»h÷fß©9 [Q¼œg|ªVšÅ²×‚¹j‡š#óÅÞ²bG Þ-ªr%3$. À/~úæŸ}ôÿ�êæyÿîßý»azšÍf3 N’ãŸæöÉÊ6scf;Љ%~mÑ´)sxµ^¡mDûn‹�3ú™à¼+Ûyç ¢Ø% ?�…ª¦þ’:“¾ô]‡ÈŒúÐClnZæsÄ`P™·å1"†1©5ÆæŒhsÁšÐX¶ FA“ûV´pÎæšÕ‡œ<œk•™{€5FȪ] ²mWëã{ÞôÖÑuÛýÔƒûºË—.ÿÑÛÒüU J?d¿O{5M§wë´ÓŸ�6 í°Å0aLæDÃãËËí�¡sÚu†¡4�›3�¡ïnè×EÆJ^Ø9í?¾Îp0´" ÐÎ1w&�ôÙåúú3Ñ íwk+ÂA}œš 0w¬}à¿eü£ï{ô}�®ëšãYU½éµâ¾ç�›ßGÜ‚Úà× ^YF¾V™È¨¤>“€|Z©tƒt¿Ö¨^Êxgð¿MÀ¿_X Yÿ…D�3ÓsV±ý-ƒÿµƒÀ÷~Ï7ãGþ͇ðø“ÏWe |îÑÏáC¿ôKxÏ{ß›žƒ$ËÕZ9—:"Cj›¿<2àË)»”dõɇ:'ÙûS,Y%û¯<Ǫ(íf!…÷`õ³¬£ž´ØKÈT�Á—”f[u°nïnbû)ëÏYwÓ£aÛNn¹å¼êU¯ÂC}�~î³ ¬à#F²³ FÊú·‹´ØËP€ÙÊÅê’Òˆ|‘�æiÖYv?�€ïÁó}Øž9+˜5E•§ Üû±ð¶7¿€CDÊ´2È …×A!¥´ë,“og–``³€8‘>XÕ'’ÚôDp?IÒmv~±WNéIut¼ÂÌ@¤(gù“@4šEG€HL’þé;É? €~ H°k�´½f²@Ÿdþ%¤�,`Ú¹ö»ÕµýE&ê2<£¢Þ0¹¯¢µ;É6Ü“éOqHm+BIþ!»PÅ`Q‘€ÿt�W·îø_ÿÒ…ŸÜt›\ùûÿïoçžÆñññ¬²ÍtL׃]k™ü‘…šé¾s¿Om–Xb‰ý‘eýóÜ*#BLó§Ô.3À¡mxï‹ �è0ç‘bë“=ëcŒèº-ˆ(ýÜ÷¥�Öó9çš2¶%e!Ù±±Ê}B­>D{Õ46 X18f„ÒœJ ˜Ôämî8�mÛä¹dQQE8sölwtõø˜Zò*²úÂ׿é_ýÄgþÔ7ÿ ¾FuÈñÏ™õ¢jó�F·9í›í £üÔa2â•­EwF‚êH{²è'ÄËAÖ}¼-1«�ÎT©°Í¥f^vNr³mæ‡Àý„ÐAc &ÖsáÀ\¦?Mm0Q ÐÀ°-cd~°‡Ý·sÿ³ç¹õ¾{ù/½é-oûSL@ßéû^BšçHÎ{8ëƒ5°>8ÀjµNj}7"d]¶ÔhZ�U»ÂjµFÓ¶h| @Ñk²»êú€¾�Å7Súˆöއw"!æ9(91\“æÖlóÒAÑ!úû€�dhã~cIa„—Žy‰%–Xb‰%–Xb `‰%–Xb‰%^Á1—Åør²F~é“cUòö;à½oR²”k½À’|ò1¦™ÿµÝ@-³R†ÎT1`ª4�Ï[¦Šµœ­:0U@˜³/˜€ÿ>„pÀ�ÞûÛþÄ7=þ'ß:ò  'n-ÛcŸöìÑ]géëÈ£æ$ùW‚9eýS•ù�5˜M  dûçUK[0&Èlrÿdžëp ¶Ìm"€<Öë?ðÿ þOÿ—ÿ×xáÀ'?ù œ9sˆ·¾í‹¤Á#BècÊä‰yùtx&¶p?Ö ¨–Ûâ œ" e1ùõú*td[^KàªhR›×,U/I½œr ”ý QÂeéÞjõZ§«ÇÙWó’øøê@T� ’p[ćƒ_ôE¯Ç]wÝ�O}òA<ýÔ“V ’hÀ=¹~f,({Þbˆ#X�ƒ"C]o‡E×Á:C$î�luªæ“Zç4ó\}->üñ—ð‡ÊA*!í( pB49}rlJ\)ÁëȘDgÀuÉÒ¯¥ú� &óO™P=%Ñ�£§+ —“ÕFuÎÁÌ>YüP1m¯úK~FŸÀ À‰Pím;I×®}ø‡m%¢� I VÛÕ‹ö@â@$ÈJZh¨¿EfX¦€‹Œ\Æ �-ƃwD” 1fÔ÷eÕ{Ö¿ô©ë~áâyè.8Þ÷\¶ÛíŽMM=Ö�D¨Ç�) ÿ»oœ™g1`‰%–˜YHòæEzl7]Å•+WÑuÛÒöÚ¶-íºišaÞcÉÚOÀà0_!’ÿQ’§¹ªÂ™U0Ì+�¯H¥š|Ãkùÿ}íÙ1ƒÙí�SEŠŠ°˜ÁÑÜw¸4—`vp>Ù8ç "*"ªšH‡gAtÈrNŽ_zé¥U·Ývn{õÿ‡çž}úÛºnóÝ¢zËà¤<÷EÖÓîÜMf<æuOßYdýuw>4K’¬†Œ=Ýk[«}i^HZ…˜+„ùsíÜH¾ö²ƒ–²•U´Ek ¤ù‰ÔÃÞèllRÕ ÁlÐW$€Ñó JµÀ‡òïÓ žwŽÒ�¯µë¶ïÿ7?öÃÿú¿éwýdŒ1t]bŒÉ(Ì;4ÒÀ;�ÃÃ3888ÄÁÁ!V«¶R|ëËÏy,õÞÃ7ëÕ m»Nòÿ®�6ú®Ãv»Eߥ÷kQC•vXˆC4ÂgšF%²o~2®qðå]"‘#²²HìE�Ä�uà¬àøÆ�HâK,±ÄK,±ÄKØ{ÛRK,±ÄK,ñÊ�}²ÿS¯û¹m¦Ÿza¤ýkð¾Þ¿þ½÷hÛ¶ÈEæl‘zßXI³NAÿ9ŽØ0U ¨3ôó½N³ÑkâA½ýÔ² öºœÿù^jðßüd[çÜ9f¾ù=÷ý–›o /"n·2àß2ÿS:[ZÄŒR€U3Çx…6&ð7�œäûØÙðŸù ‘¸’ñ/�ÚUàN‹÷&ùŸ•<(€‘EÀû¾æ�ø†¯ýüÛÿ¡�ºó«¿úa°s¸çž7"ˆ XY„�$y£jÒkEJŸ¼°'¶˜*"�X�òbYüöóð𹸯 §rsÄ‘Çx.?OøŠ—B6Î�ޱ] {ÿ+àÏ€Ëñ’í$ßkŸöú$Y×t̃Ã5Þù®wâÒ¥Ëxàþ�â¥_8B…ÀÎAMÅ •!MêæêR‘Fe((å¾Qí?YÀ×JmbP0à^Óó„ˆeU ™{�?s*ª@*H¾Í�@Å`ŸÔ% B ÄTÒsÉLƒª'õ 7ü ®~V¨–ÙåyˆPÑRµwåý“Œ¬Î>7IûŽ2ä-³Þ$ý5ýdé†lÿ ºMV… `ÛdUMªŠô;!B!åûa»ä×@ÆHV(êcÃçººêØ¯X�7öUgU ñ…ìÀR);TÈθ�ŒA mOÛý•[ÿ�ˆ<£ª/ØœÜv†q �E§eóMǾz Ë}N=œd 0=žî¤–Xb ›…xWÚk¿ípåÊ\¾rW¯\Aß÷pžÁDˆ«BHK 9�9¢ñÁ7ÔÏãW&iƼ§ùBi™]:Žsð.�ÀÌ”Nœs5'æÉ\†˜�d8Ì4“�Ü–É ÌÞyø¦5{ƒV†¢l¡¢Ò…^˜YÏÄ+W®Db7ÜôªÒuÝ�_¾øâw÷}÷�ZYnœQ¯c՟ᆆn»Þ`ìïïÃÊfõÜ2㱺�0& `þ—ïiBŸÜI­¶Í™òT %4µ“Óêî÷¦œ0ÎâŸÃÔiô�âÜäËÏD6o�ryÐŒÄÿ¨ GÏ/©9 S•…IåEM™{œÏ?÷ì<üЧùæ[oëºnÛ‹H`f4¾¡iZàààëõ Î9„ƶVFPïÁìÐx�¶]�Àÿ®ïÑm;l7oÐuDbQi¼7e©D˜Q;n¶ æŠ� ìÅCµ�¶ L=DÓq‚©†ÕïzÄ vÁÛ»tÍ5Iv‰%–Xb‰%–Xb‰…°ÄK,±Ä¯è˜‚Õûb*¡?—õŸNjà¾öG­ÏYgüçsV}-•?À× ûœóì©�ÿ9@½ßü!L¼ËSÔYÿù^¦Ç¬³þ»®+€üç\Û4Íù¶m_õ­_öøw“['yþ´va¹’î‡J‚®¿_ù•_�Ï~îsøø÷ãhs„˜” ˜†ŒÂé2»ý]Ô�(ZF3S²µ 9Ó?•]YP¶ëI?�Û‡–’h\‘T²lî^xi“ꮨ§ó;†` h"¦`U""If®©Þ©ÀaXDÏ×”$Žª¢ÁÊ�¡q÷�öã×YÙÕ¤s+9}ËþWdúY@=sÆ•¤@”•:#ôF0™ÿ؈‰ PƒûÑ~òEÍv o#±ü &I]Äž¤JÁè§!ØÍVÜvŒ‹iÌ! 2E€¬€±7ôN½Õþ<øø¹{�¶Í£ÌxND.Øî{™$67î�¤x37&æq¢þyj³oLšf /€%–Ø�÷ˆ"]Àf³ÁÑÑޝáèèQ"|ðhš¡&NÚ•ó@[ƱÔ>]"pEÙ‰<¢”Õl2åÓ9ݾ>cŸ"–óy®˜Àÿ|Ón2íƒ|d†÷¾qðÎÁ{S] P@½ù¤tý›Í&n6Ç�oZoŽƒˆn}Ó\}Õ-þÚæøè½té¥?CüºAúßúòš0äü9“ŒÆHu_½_Ù¤lQo:àÙ•ÍÒ\yæùÓL>h¼ofMÌy•\~5¬ŒÎ=U4˜!²Õ¶…ÎY Us×?©ûúü|Ê×YÿÚ9M†ÍÝûÆX‰!�{{t�½�ˆÜùK¿øÁ?ûu_ÿM±Oºþ=ŦmáµÁz½ÂÁÁ!Öhš¦XkäyŸÄˆ(±c²@Ó6h› þtÛÇÇG8>Ú`Ûm£€™à˜Ð6ÞŽ�dÂõ»›Yi:~D„I€ÆˆÐxx ðâ!¾�kœ)ù¤¶�Á’‹¸¨g3Èçv‹ýv‰%–Xb‰%–Xâ7i,€%–Xb‰%–xGíOŸ•öÉ™Îy(×™S™û üO%û‹ô£eýûj‘u*ù_ƒÿ5èž SòÁÜ5Oò§Ž|­µD}î|þš€�ï!_ËTI ¶@ÈYÿ}ß�ˆ MÓøÕjuxÓyÜróõî.p8oªøŸ2Ša™-öØ%TÍí��€½ à³eO;Ëü§Ìk€W¶Ÿ�¨9-‹`’è~ØŸ€ü$ÿÍn ƒ°Ù’€<7ÝxþÒŸÿ.ü©?÷ÿÞ©wªŠ_þÐ/ADp×]w[ªê qñMeëÀ.•o”:û?¤,¾ŒÞ3¹]牀í; û‘ë�p"EqXŸb kp©�2-:çRvŸ•§¨ƒhœO¨ÒôL•ê´Ü¿Š Š”LDU�•dU�u¢ EÜ}÷ݸãöÛðÀÇÀßùŒÉ�ÛA‘q/˼Ft ªMƒJâ·h¬|�«DûÒh!8Lû�¤A¡E­"Õ{2·(I;?÷⢂(=Ñ„(FÀ9"XV0é†ô/ªÞ2üšt-.ƒÖ&ó¯"š2½²‡tøwöéÖõT*BGmPØ7£:=äÕ ²…$ZÝŠÕ'�í ü/Yý„`R÷‚-Érû™0`–²4$ÛÖÁ@2ÀŸöIY¢é˜D22AAªŸkÒ‚&˜_h¦Žo~ü¯©Ì•o/Ø<©þ(M%9Í™è„Á6"gíý§OÞôDô €—œsÇV°ó/¤Þ�Æ«k%LÇÁzlÌÀF fÌ�-ÓýjòÀBXb‰ýáœ+òÜ}—2‚7›�ÍÏÐf ðš¼Jû, žààßoTш‡1ͱ ásœ¥ûÙÔ0j¿TYÍÎ�yè ¦}Cù^êö?ˆÁ3g°ß£i<ÚÆÃ³»LbÍŠŒ "Šº®Ãv»Áf³�}ßuÞ7!†¸qì<]½î†¯Þ|ëmßóô�}í•+—þBy5ʼKëÉÅ�-¯¦>µÃ "-?ŨÇd‚1m³ûL»dÂêàÄ™Ù\Vþ QgîNßwîûÝ¡qFÏ ¾×}‘ æf'á “:wH'�dûÝyoWëØn6èágÿõ[ÞúŽŸ‘ào™qÎaµZãðð Vm oÊ£÷+Iú5‘Æ9.™õ"‚ú>eþoŽÐw]jo¦°–Þ=sLÓUˆÊ@Í(ï§önØ:¸Î¡i„¶A+-œ÷‰|uö¡.PÿK,±ÄK,±Äé±–Xb‰%–Xâû$‰Oÿëmj@íëïò>Ãâ�+ÿN³«jÀ½¾ž©]@Þ7ï7§b0'ùŸÏWßOM:¨-fý\OÿkD–ùÏÀmaÐ4Mþ¸õzݾÿ=~ ¨¡"£J8œù¦'¹ì,ki@{ÞN6ðûL_ød'àV`n´¦0`2é”åÑQ¥bù!ÓŸ\Êüh’ä?œÉÀ’ÿézLm K³³Ãï}ÿûðÃ?úsøÀÏ~xR’ þ•_þe„p÷ݯ�s fï¨ôF.�óª*BHs‚(±��ãèçvC’Ñ/öRFJ#ú®œ<ê¦_FLAZ¦]å©z[fJà¿ÍÛÕÊÔ¥êYH pŠ(yž’¥R QEãúà oÛ®^½ä›¦Ý¶MÛ½î‹Þð!„}òÁ¾gs|ü‰°*`¯V²ú4ÛccPô·lz¨eÖWó—ZÆ&PTæ}yª9ú§%2ëŒT[œ°ïð=»�Ù@ë¡r$×oó$²q¾:#9B “´ûA}júxóïr‚cB:un¦Ù!yްo´Õ¹š%#dB§=/�ÎSÀ/<÷ì_½xñÅoÄpùo–Xdz‰‡ÅöY�W”c:6_ˬ±Ø�6WþÕR$ŒMòïÓïÓn‰ ¥dž9<Ä;ßù%øÒßòe8{î|Z´M*ô9›ˆÀT¤Tw ØÛ?d"Jmq�>õú2 ÕÌÊ2çK—ÌѲزŒ¿F)«óRP�XµÏ¡¥”…`¦"m?ûÀòíUÖ$Y�b®oý.òÆLßsÒ>»×â%�Ò6]"ê°‡R“>ðPjA´¹DYÕceŸDîjפß)µEæä[�7…çSe;·ó©½çWêÄPpº>N¦ÝORÉ* Ùžaßgn»T1˜²j î$ȧNÏîÓOŸ¹À Dô"]%¢þ¤ñmü91·ï>@ÿ¤Ï>‚ÛK,±ÓùUݨïÀΕ~!9û Oó.—Ê<’�3ÿpŒæ€Å2Šug¼Vüú´W*s Ú½§2¿lÑ6 |ãÓ\ÙÎf;Õ®³¶ß•¼ç¹÷mî7ß|ËÑ™3g®4m{y}pðÜ›Þü¶¿uË-~¿sþ#Ó™‰ªœr§dóÌ€Èzˆ›³×1&°�V^˜R×Ìv餹•Vs«Ñ¾SB^¶£™¹Nؘ3È(ç/�p;…› ��î–TUN4dýÓ‰%}r�«î|¸¨9¦ ïs戼á��Þû§œaæµOJftp°N€zãÅ®l#b4¥«�N+ºª=‚oªóC{ÞÛF`—ÁÿæÿÏÞ‡Û–]õ�èo̹ÖÚçÜÊ9+V •J*•r– B aË€±ˆÆÆ‡'l‚ÝÏ›î–íϦÛ6múaË¡C·ýŒ „„‰¤ÊU•²J*•¤ªÎÙkÍ9Fÿ1Æ kíµÏ½EðWïyŽún�sö^y¯5çÜó—Ðõ=¼ïáœ7Ñd1G8:wŒãã-¦q´ï­“¹ˆ­EMè}£ÔúíV­ZµjÕªU«Ýj€V­ZµjÕê\û@Šó­³´ÌOÊù™Ú©²ú¯'^ÓïI�_+æk€`ž'n+Õ¾‰˜5õÿü/¹‘å–k±5‰a þ�ãˆqqlVµÇÇÇ!äsI±Õ9EçÜø ïzܵ«[ì1¥²üOªz¸*�;ëÔ˰Ë?ÀüwÉÊex–”Æd±n0ð¿¹äÀõPWû—�ËD½�ÿ®ÿõ½ë®½?ð}yÏg¤Ì…w½ó�øà}ß¡³ëJD _‘5’8žÅÀl³5‡F¸Î£ëzô½W[OßÁ“›©å”§ÙþÓDöŒ0‚2AOõ,ïúÝPýgÛxCaÉÖ °WçwÙ»¬H—Íj5=Ãvo_qÅåxîóž�;îx úa€ÄŽb“�µÚ[昀üR‰ X³BWÜ¿û«c¨ŽvF`X›µ~ðóÇÈyôi–Ôê]'®�áBÉdßå Ë‚³ ™L‘÷ŸÖ‘m=1fÜ »HV²»×›À?ï¿Ò4ÞN™ØÎ÷‘«‘ƒôl+¡F¤3‚MoÏq÷7€ ´Ü!àAîÔ‚ü!\w ÎjÄm@�ýó¨à\gÿzýçÓ?U˜’ó §ä;�w Îkþ­så8�;vðå§óNÁ8¯n‰,·BH$_ýKöùÞa¿k�þûõß½ò׉èAؾöµ¯�}áÖD#´juþ¢ªÿî|‡¾ë±9PâäÁÁõgßõ9. DÍß+°¹Q]‡Þ¿IuLI!^EðDS Çígгª<,;q"¥�™â™m}Þ£®Ç«JTÐ=º.Ec bˆGUùG#?.×÷ÞÙ¨Çf°Ù`³’£€\~å•ÛƒÍÁ¹Í°yˆÈ}îšëozÛ£{ë7l6ÿˆˆŽª ®ôßõx(–zù b¯Læë?í!HÊü‹±�Èëlp»)@õ8¢œ£¡Ù„fv‚˜#üõø0�!WÛû4¶ßÝCr�j›³}à„Ó•Õ_÷ô9ȱóS–½£˜ä°–ø3n·áwßÿÞ§€èÐ{¿éºÞ{þô�H]6bŒ  WÏ„ðI»cñŠÝœ¾«és0b´(�äPÕy�ͰÁá©C¨Áaþ® 10bˆqR7‘-B¬Œ›aí@r-ˆ‘�ˆ�b 8;‹´jÕªU«V­ZµÒj­ZµjÕªÕ#¼–vý©ö©óN /�ÿà&�¼¶t¯ü¥¿Vþ'ÅV ⟯hîî*ÿSÕQKð¿Ž-H$…5"CÚn:þþOÓ„ív;Ë Më'ð†´í "gïÐò¡sÝ'.9%7g©®’÷pÈ@JX× N•¢ß”»n¸ÎmÌÂßÜ™Z?©~ÐjÎT©~¡`?¹F¦×Èïò±àß~&UsV4þØ+^ŠŸùù7ã§ÿë/->¯bcúžw¿a xê]wÙéºùLr¶¨�o [~v½æåv½ÅTñzóÚ|p±Û_Íy­îWûs·©‚,m>¯ˆý¢yÚ›’~nía¬]Q•S jAïWŸQG�€�,¸þúpà 7à#ýî½çn4DŒKbà�Ùÿ'E·çë�¬p…Ìs�»Lžò ¨Y]cJ'(õ%œ9;V™õéÊ8�ü5’‰ Ùý)b ³"f°Ñì ·ûsi3ìògPVç½�mí|mNn7÷ÏÌâD} RÿmÏ D:�òп;ÑV‹%À>p‰d <q´g/Úsª. “]C±¼sW@Ôk-ÖdÄ‹DZàôá°òëÅõ©$0v:ûnìúaYy‰ IùµøÜÙþs÷|úŠ�ÉYGÂ…ö «Ÿáï¡¿|¸ï¯E4@«V'Wá¼ïÐõ=O�‚ˆ ï6À‹.:…ÍÁA¶ñžÆ Û­/Óm³tÖwèûÑ+À×û£÷š?N«¡™ÃÌ�ªvÀòÎÆ>Ã`1ŽÚ7õ}‡aP·©ÍÁú®ãSW]µýô§î‹‡§NmEäx‡ñ¦[ûCŸ}àþ7<ôàçþGŽüT;‘ ØW»{¡lâ_:oR¢jz¯¶ŒHJôÐlà—ÆÙt'ÐÜžÿä%!¤û�Qe±9듞Ö:# �NN¼àΕý´³^ŠZÂî5ϲîö¨îK÷ô+²3`´ëMk}RY6LjÅ8T‡»jpµ– G?Üÿ§ÿÇ'Š|�s.øÎOD€#R÷8Ù÷«˜I4é{‚$²«‹—Ògªó‰dÝCDݘ!L8>öð]€HÔˆ€)(É}ïqxxˆÃS§°LA㬔4`NlFΩ‰³™°+ÈJý¾@DˆÑƒc&q­ßnÕªU«V­ZµZV#´jÕªU«V�àªíúkà»®¥Õ~¬sS¶¬5XŸ€ª2Ýkà?Ùµ¦í”‰QÊÊÿ%a >žú˜hÅNu©ü¯—¯•ÿKÛÿåúKç‚þ§mMÓ4ÿÇqœ9$åZ7­1Ɖ™ÏÆøôéþ�—œo$TjÛ…²JgUµ®‰Îø ’Âõü÷Ŧ?ƒó ôOМ�i?ä³êÔ+øŸUÿIÙŸ�SWYþ×à¿ ÿ¨«ˆ JøÇÿóßÀ[ßön|êÓì܇éóù�ßy?¦0âÙÏ~žžnŒùø$&«�àuÎkR�sð]�a°IÃN•ÿ%¬]ò„Û„º:ÄìEe‡X€ì€¥òKQ‰¢œˆ êV~ ìæ¹º,o×N„•Cò„®HÜ™°VG*öÿ+DšYÛëvbŒ–ÃÚ÷=ó˜ÇâÑ�~ î½ûn|è#²Ißä¨ÀåÜ+bF>RPÃQ¥¾—šè~wm÷u¢[Šã®”Éë4¹|´�&@Ò=&åÞ!²¸ —É(ÈÏ¥ ˜ç£,*äÀ|&¥h”€»@ûáÙ¹0NùV°óeY1ÖHÕMe“ÞT+ÚÉ#ñ‰PÝ»ú»3‚€�,Þ–�Õ‘�ý©ýäì'k¤S9œ|hKºŠ]wGʱT»Q¹™g§Z".ð?©vÎFT>þ¹Ã�ÑÀ`úWÿê_]ðlüù¢.dý¸_þηÞ2 U«VëM¡›ú¯ƒÍF}÷‡¾Çæà›Í¾ó6Ó±X ÎH¤ÙÍ©sJ¤ˆ�ã†zø. Æ M]EHcÕ®×H¢e¬ÔZ4VzÞÓ¸ZÂŒ8[Ú�…RÛ�®ïÑu=ÈQ^šT©œœ ú¾›9hyï±Ù y›¾ëcÌÄÕaô ƒ�?{¾áÆ›ÇqÜâ�>3 }A×\}ýû.¿üÊoþä'>òçÆíöÏèæà¸ä68¹îd*ª­ô+ÄØPå²Ù#UßG›|ø½ÈŒì9ÛúÜñhnr´gÿ32ZEH :Í�N–RöÚa±‹z”³zni(¤æÚÕhyÄé}ÁZL€¬öÊÅÝ�ð°rl_Ìñ®·üÆ›¿ùE_ø’‘cq1‰BÀv1Ž[ÄÌúŸ+ׄt‰j'+€œ>£}?`BŽ–Jdm¢.Di[ŸSç6› O�Â%_ŒÍÁ¤ëo·Ö&Ä€‚‘wÊwTï\Ž €0$’3#0£·ç—–Ÿs«V­ZµjÕªU«FhÕªU«V­É•&9S�´×Àÿ,{½šH©.ÿQž4*Ѝ5Õ –פ�}ÊÉåäëšÝ}>õþC;±é– ý`¨i›ulÁ8ŽØn·;ñ‰È�È}ßçuíXBŒñ\Œñ�Ï|Þ¿íÖëÜ—#ƒ× Q´©>1ࢎýäøïà?ÀyËþNÊ·Ôˆ'Õom§êtè5[Üõø˜ïje¿³«Ê;¦ þñÀÁãòK/Ã?ÿÁ¿‡?ñ�%ŸÿüÞÓs½÷ž{0nG<ÿ/„#Ž\ÀFÈyxSH‘ƒª;Ÿ¬Ìs&½Núª“>k´¼‘ÔÒ�Kéâ@¨š™­î <)�ÁAÑ��©š$kÞ€¥û|Ùx=P@ûÚæ?M`ÏŸAþI(G€°]JVùœVËUǘqT¡<ùÎ;qëm·á½ï{>ö‘� çþà?‹>°ý1ëkLUþ°©¨Š’KfJ²œÅ›l–ë ñYYÜAdÀä8;ø’ÝW,=¼Ý‹) €Ða‘Ãe@šA”HNÉRÖ�M‘—ŒE4:€�P ×¬¤™¥ùˆT¤�Ù3Šú¹µÈ ^ZØ;dU?dþ¾-?s.Îd%Hô¦êÈõú:‡y{1S’�—XÔç} ªãË`‡�K:vÑ3Uó‘ ®p³%«#×k7qÂ2\>GmŸæÓG>sѽDt `ü‘ù‘ òâ]’ØÖú¸µåOªÚmfß¾f­n¥þ­hZµjµ^ã8"L"¬c²¾LùïªH¥~à�Ã8NfÛb@gÏ]ê_=')߸שâ8úˆ A›ä6¢º¡³x’d7ΞÁìWIAÂÚåqnŒ ‚2Ïœ©º®Çf3`6u*D°�O“9!xˆl*W­Îþù|.£¹OéxºC?hÀ`ÑiÞwn½õ á]ïü­£«¯¼š�·[v“‹�zÔãðþû?ùæ‡üüˆÈ£çÿNÃ1¡ŠèH¹Û <^)°;AT_åÙÏÆ[0HÛ ”G<©×\ü_ìÿwû\`�mûÝJ»-çmÿçßE\>ûÒŸ °ó÷¾Þpñþ,ª`÷°æ¤€õå º@¶tZ!þåH‡ èÉm_çÎ�ýÎ{îþ�Ÿ~ÒO=Š1N‚ˆð8M2Úw¢hDÛùw4gãFAˆ ïÓwJ�sŸÆô>v_�pN]›ÔU@ÏÇ{‡aØàðà§N�Âfs€Ð„iÂñ¹#Œã±FX¤Ñ0 èú½}Ï9‹ê â°%¬Ïmdsˆpâ3é U«V­ZµjÕªÕr¬U«V­Zµjõˆ«uUv”ŠK°<©öëÜÒ¥J¾þ—óib5m'ýËŽiBwa³ŸŽiŸjrMñ_ÿ¾^jÀÚùÔç2 6›ÍLuÅÌ3àÿøø8ŸS²ý¯ÁÿZõŸ\¶Û-ÆqŒÓ4� !|îÞû†_Sàž*%tB'í@~cñƒm³/¿©° �*²]Wmß2ø¯Ä—ÜÈá…Ï6¾ãÏ}ÓþÉXû,?þñ�áõ¿ð:o�T÷'tb°ë{tC�Á&ðœó%£ÕìèYQ,Ë3¦üΠvºfEªËˆe¿§€|Éóõ–f$—zËtÞ9ðe~l½§X�3‡ˆS§NáÙÏz¾ð‹¾W^yU¶òÏWÚ¢ŠÚ_vâ:$‘ ¸\‡™Óoú[€“0ÕƒÁÛn”˜Ä™ú»ÄDÔQ‚ìþ“DT°g…óÿëHWðô…Å<óâ3áß‹ºKY!|Ì¿ò‚pýþZ 2Ïã/Vó��’@²›À’l@y×)³:ÝÇ‘Å&¶e ÀâÂï~Ãs Ù?F1˜°Œð’ò¼Ýâ_M6©ï_û›Eÿ¥¿?ôÀ¥!¢l7ü{­e7Ë'>Á¢ÿBUÀËý,oÕªÕÉu|¼Å4�™¨Z+Úpppˆ~Œ¯Ç«+zy–5�<€«÷;çÑu»îL)ÿ›«üo@‰N pW5þ�׫cªDĬÐCî/ëñ«w^ËC=�‹1PËñˆíñ1Î�;‹³gÏàèÜ9l��ÍÆ|š�—7-óüà‡‡888TBÁf˜�ÿ)¡ë;ôÛáwÞù´xÅU×lû¾?Âi}þÊ«¯yóõ7ÝüǺ®ûÉÝnÀú�ü³ VŠú:= ¯W¹/ÍUkC}aa7þéäîø|¥ÒUû&‚õI'oDê™võö˾€è„±[Ýgv|øig|·óêÞå—/Ö—w_µ|ù®ù%÷ÞýÁ¿+"‡!ƃB¿G7nÕ-Ú÷+}v\«§g%„ˆiq¼=Æñv‹i ™,@FØ!çJü‚<çì;[rjÌ=`@7˜“ÀfƒÍæ{>ì÷ÍÃf£Ï„÷õ%e\˜¾G¤ïæzЈ{­ZµjÕªU«V»ÓC­ZµjÕªU«Gj�dCœTÿK ¼Vì×àÿòßR½ŸÀÿ´�5õÿù”ÿ˺0¦Ž.¨IKåÿ¾óYø ü_*ÿÓ$W}.Y™UÇC[f~èWß{øwZ3Ï hŸó;©R)àîÀmàüœßÛÿ¬à§ÝìUª{g.4€¼�þ®+`¾å¯§¿‰Ô’]·�b¼)ÿ}þ;¸š @üüÞïùK¸ë©wœH>ûÙðº×ý<zè´9¾È:çÐ{�¾SõÍH"±LØÇ4qgŸXÔDžØ3à:Êì_LyöÌêÅ&¸ öž-“�¹2T,G]Õýq*¦‰pUJ>Ö˜@©¨‰üàêûÛ­³Ó<¼å ç Wsåœ�áº?Á¥—]†ç¿à…xÚÓž�S§.* þj2?9'Ô“¯1òQa]Ѷïï2™}íÕ‡Èn®œŒªð‚‘”aŸÀs—ï¯%¨_žýô“wÚ¶Y;(õ¤�å™×sÝy§MÒè…�$CÆ·‹JtÖ¶-r‚ÓI°(q…c@!ˆgR¦86Є!Ñ~·è†ªR™enÓ¼<^»(¦È£´�óÃ\G=,r—/ÄÃY'ôË¿z»‘I>|ÿåŸ$¢@DŒÑï©\ÆÊ,cn–n7kD€Ú) þ—ÖoÕªÕzm·ÇfÝg ·’3t}—Ÿ!ã…ŠÈI³È©#¤¶äÛqÄ´ó6�w³qk£Dĸ âQÓé±tæ>ävƬµÓ•’ ‘Ñ™uÿÁÁ! ´ïz5ÏŒ1(±ôèGGç Ëñªƒït´688P�s3 äÏãXÿ»^“¼‡ó.“)û¡�—\vÙ(1ž q:}¼Ý>(‚O^ã-¯ÞþmŽw‰¹ÌçqPÅþ›‘jÇ„ºkXŽUÈõyýcä‚õŒ³§ì÷Y;¿è¬Œ{€ù]€% `~삽ýÀ¼#¤â¸äÎêkr�„ÿÏß ÚgŠv÷NëÄ™çÎJœÂr­¦¯xÓ/¿þËŒ0Ä}ŒÁ2]êÛ]õ}HÇëS˜p||çÎê¿íöÛqB sG¶9aÃer@ý}Íw>¾#G� #B×ë÷±ÁH‡‡úÌm0ô=ÈâÄÒxŒó¸jý{q«V­ZµjÕªU«yµ€V­ZµjÕê\ËIª4!Z«"Ó¤ãÒæ´ìkõT­t¯Uû5� ½––OJû5Õ½­}ç°ð,•—õùLÓ´P‘¸ÙùÔ–ýé|ÒDn þ�ã¸s.ÉA þëø�EŒ‚D÷%®Àÿl�n–ãf½¯$ WËò€;0KÿA_w€O�ñ|u µõ:LÉçá²#Í,ÿõµtS”ëþ²¯|1¾í[¾?òÚŸOfî|ƪœ~ë[~§zÏ~ÎsŒ¡ªìX‡¯Áç‰Lì‹.H÷¥Ù±‹Ò$k•’í>A…lg1�WmY«ç˜íXÓö—ó˳M³u ©¶;Ï�;™ìÅúßW@fW©,Ç94 ø8o¯:×Á{3P¢ 8FD¶{:ÕÕãn¸áFÜ{ï½øÄÇ?ªïlB9ß=æUêêš“²«Æ{ê\¸�‹ Žz¡|gÄ€Híÿ)FÀ�ºÈmòýÍÂðp™ÁY‘Ov>ÞÀûJéNl¤‡¹U¿qU{R ޹@õðfr€Ùóó"¢ÞÈ'E·ÜH"”m±€÷I½/“þC8Øßs…?ׄa=oŽöüIù‰ P‚¹óMø .8Œ™v�¡%÷)ýíV 8+°»­¹¥D\øQÌÚÙeNwz¿Vý×µävs’òÿB�jVÚüV­Z�ðÜ ó, g9îÄ�À;ÎÀz=KË E•Ÿ”ÁfÿïÈkÖ¸5=lc çœÆéäþnwœ+\²ÁkÂiCˆ³±u"ÿÕcjUòGøYœõµ;WÌ?S6y s5N9!¹Ž„ÑÙñŽã„íöGÇÇ8>w„ããco�4n�#žú´gÉo¿ã-ü¸[¿`ë;'©‹.šžúôgþ™wýöÛ¿gÜnÿŒÌ¸r2ûmÙËËRe¾"Q—èž·ï!ú¥¨ß÷ßÓš~}ÇA@B!Ì¾Žš*ò@ÍsÈËØúJ&)Z}�xž'�‡Q3+§‡¹«NKïŽ>Öº$¹ ð¾á££sßú¶ßüÕÿüŒg?ÿ­Î¹­s.xïEûq®H/É]ÍÛ ÎÜâò(Ûìþ�óè:�®ï°ú!�Ö­¿�%§�ü½-ļëÐõƒÆ^À9;Ê4•ȰÈ6f,1Ë~¿õá­ZµjÕªU«Vój€V­ZµjÕê\;*ªWíþkåM¨mï÷ÙÜ× $™4�Àÿ%`žŽg©ZZ«}ŠÎµK‚Z±_ƒÿ}ßçc©ÝB3�zkYÐËó¨�q @bæþÓŸwÔµ€*êͦœ ü7•¾÷µjßþ9ÛQÙüg%> üï  }¯ñÞ"ÜPÅ`Ÿr @­Èöæ�þNàÿ’|PG”Ø™jZ€¿û·þ2ÞöŽwã·ßù¾ó~Öð�¼Ÿðóø#ä‹ÐuBLŠè2©.¾Cç% ÍëìP¤½ �Ø�ÑAÀR”4!&6�½ÌòupNÈ9tõömÒTR>.°C PpZJìÀb¢5eÒ’'tÕ=åœyuà�0KEƒ«Iè"S#òYx–gM %%#˜M1›²jpÛm_€›nº ÷Þs7î¿ÿþLHÿæ÷·î´XßšË>¡Â�D.oç‹_üàEAë(‹œ[6@ûÎmôåhŠy?(Xï”ö@ä Fü`!81òG²!ðQO^³ “ÿ¬.š%è³G{"ÚçNõë ¢;C‘ÊrË ãšP>ùô¡±@�×¢Üõÿ¾>gÙ–-Ý–¿·jÕjÏøô|ŽO¾§ñ]=&«]œˆ™Ä)Í6_§«ú.©ŒÕõˆ(j´‹ó o÷Ù¯®êñ³¾0M6n ±ŠXžgiwº®8k¥E»®%Gª¨nVnT«sçœ9\M§ Ó¸ÍNSèÐ…©ZY0Ž[ãì™38:wÇÛєғ’:�g=÷ò–_s¼ýÉOû®‹Î¹)"†;žòÔøÝ÷¿÷ýgΜùû^H F �~þ·‘.¥ÕOþijü^‰RùòŸ¸V^v‡�€õ>-he‚cݦ¯�ÖÖ_!”e«ˆ®åþk´~õøöóIK­2Ì—*çJ¨I´¶ÍÖî>öÑ�üý§=ó¹Ô9w콟º® uÔŽ~ÇÐ�}ob „0a×� üïÐ=6l6º¾ƒwF2�a Ù�-Ähß 8ƒÔÉþsv þw}GSíœ V Gd_½’ûV"7ÏžV­ZµjÕªU«Ýj€V­ZµjÕê\µ:¾þ—ªC–ªÿ”ÓÂf´þ×âjà?�,éýóÀkï/—ˆY’ê,æ25·ýOÇQÿég:§“ì¡ëã:Éf:33{f>üÈ}8ýÌ/ �(̶ý½©ô»Jùß0À̲ß¹UV¬õÙ€0~ÐõÐøï�Áÿlù_¹Hò¡ßUý«�iù©ÿ»™åÿ+…³0œ'ü«ú~¼äåŸýìç/èøÔ}ŸÄOýäOàù/z1.¿ìRÄÈÙrÝ9�NˆDp¾÷<Á›þ;Miо�Ų?�Ñ`G pÞ<:D­H�Ëö£ CËΚ&¼ÉSVÖ“àõ}”2†;ØóâTØõÞìZ`gD%?°(��}þнøìg02D}¿›un9ãB~fϸˆàŠKð·_ý|¼ä…OÄ8º|Ì ºW3Á€ŒypPÇÅÖVÂäz$ÛeJ™ÍIʉXîC,H(àr'ÇŠÚž‹b–J :�`»ÖêÔ�Ç@܉Ø_®BÒÀÿY\€)ø!±¼Çõq�owT¬Xº"üô6'¼·'ÕÙÍϹóâ�fÌ2†ÏW‰°<—% Vú×d®º�Zë{–‘.Ëëµ´énÕªÕù«~ffDG«cØ:^ª¨êiÌ’Ÿ™ál;ÞyˆïÔšßi?æØÀÁw>Ç”±�ÿô§1¢$€p!�†`ýl‰(X#©¦÷|—ÆÛ}Õ<»ÙØtœ¦™k‰ˆ¨KÕ¨$€DˆpÎç õ D�ãíçΞÅÙ³gpöì9Œã6BDç=º¡Ç0 xÉ—}¹üÂÏýl¿àö'…+®ºZ|èø1·~ÁüäÇ?ú¡Ï~æþ‘k÷6ó;öû¥i¯õö$Åà¼ýÄ l§Õ ûìöTï9�ë ©ôXs&’½b÷ôvv>WÚËŒ€<K뻬z§ó: œµð{ÊJ¬–Èâc¬ó$GAÍ>ìD¨°{3„p×ë~ö§¾ù˾òÿ’¹›DDœs,"¢ß#{l6ú¾�sB'7Ä(•ã‚=Ç�ÇÐØl68<<0õ¾Ž…ðu£q< ! 9‚¤ïkÞwp�C×÷èûÝ ÓÔ‘Ý*ÁcÖ¡yÿ·jÕªU«V­Zí¯FhÕªU«V­ÁUOŒÖ€y j'à¿ÿk d©²¯PûÀÿÚf Н©äOr¨_O¬5𿦶Jç�ÔÿÉ ‘ÒÄíd©51"MZ-U¡Ë\Ú}µr^½ˆÆ/{ÿGâ±û¤À$™%¿ëàÝ�EtPËÿìW€ä�¬ÿ}¯?уÈÖ™Yþ/Uÿd¿›š_*"@~ÝÎ) ™_/êi=¾|†{Àÿh@¹àºë¯Ä¿üÁ¿ƒW}Û÷`šÂÝ·çÎ�Åë_÷s¸ë©OÃcûXˆ¨j 8—Ž…—``¢«‹}R}›BÜ„“*ÜH,'y‚”¡ƒƒ8½ï]²µ�²˜"ÑO„h—Æ[*¹¹kƒÐõAŸÝ˜-Ø{t½NâƒH1]�ÉîqŽâ©‚D¥Ä Øy€<YIvmdfÍ®J{Žl6÷ Žw½N¶F.½ür<åΧáÌ™q÷ÝÄç?÷yÀH,� )îóç\ëÝ$'_þâ›ñ7ÿò‹péÅcšD/Á¡CA|r!Äl`;A¢º0€„;�gHˆ@çVãDB^¨€é$峇©Haœ–Ù&Ì €ª¿Y27G˜w§…—òB2R€p¾ÿV׃=³ù�Bªa)Ǻ¬“Ó‚-ŸF*’`Q7HÐnÑR9äí,ÿ½@k±z yÊßí_»w2�–HíË|¾½žÐ6× ÚùH]§_½Ð> U«V{Ÿ¤ÙøQ•Àú.�wÖ×V$€�(&Gàȳç²àÈúzÛ‡wÚÏvd+€³×S¿&bñC6NŒfï¯cŰ›–$‚¼}˜oãÌ­(�Q¥“§1vܘb �mþ§²ÓA8Ç�®›à¼GÆv{„³gÏâÌ™s8>:Bäï<†Í€ÃS‡88Ø`Ølà;�—ÿÑ?.ÇGGø…Ÿû~ôãnÝ^~ùåtpp@7ÜtË[O�úºO|ì£?Ä1Þ^7ñ4³=Z·èÏPøœ�×›Yå –üìÿWo¡5{ x×ے媯§KcE ØÁJ?—Íîó÷¨ä0ï¿�Ê… ‘³«Ò>ø¿~}¾L} h™°Ó÷_X__/qî왿ö»ïÏO=þ ·Ho?™„®ï0ô½}çÚ ïu`bTâʸÅ8é3Å,F`)ÄXß9x¯ÛPRŸ¹> ,þb&ìÄÎ¥¾½KñÀ¾ó!–�ìÔéN�£\5–�ßC­ZµjÕªU«V­æÕ­ZµjÕªÕ#¸–¶ÿµº=M¸ÖÀQVÍ3²—vÿK¿Ük»ü%R[EÖµOù¿F 8øïœ›Ùýo6›YVì<¿µX˦õ÷�þûŽ÷¤eDÄ‹È3_B¸æó_.tˆ ö‘NxíÉ4èË%;þdÑŸ ¿»:Õ7€|oëèïzœhù_¶C•êßÜ\M `þï±ü·é3–€Y9G<ÿyOÆ÷þÕoÁßÿŸäaÝ»o{Û[pÿgîÇÓŸþt³¯1KR+_gžó€XÆ(Y>)yPëÿL?.‡ÊòÞS™&ªrL“¢>‚cÝ-f"+“¢ØÏ”ŒŽ�”6å±:t¼wpöÌIeÏ.YÓfnTgªržDœDUAÁÃy7»7á FFˆA‰Þ¹@U[~£*ý)F\rÉe¸ó©wásŸ}÷Ü}Μ9S¬`E£²ŽJ†®#Á_úÖ;𭯼‘�ãã-„"FL‚'Òۭ¼Å,üÉG€;H Î™(Ã�á\„{ œF<82‚ )È¢ŸWEÑ£´{S¯ª{mm[LåƒQ‚ 9»Ï ˆ—¹ êMêלm¼ËÇ,M¥ïÔ­Cœ‘  ¨§¯_•CËl?“ Õ Ø‡çlÎ+îžon×éÂ3‚«çn÷<ϵ½ægË*Aä’Ãp‰÷Þ/¸ Ý­sî<‡µè¿�š% W“Ñ–}Á¾8�V­ZÍ+FÖ¬÷Dl†!�?��ÏÖÆƒ:|Z‰÷°±gjÈ‘ö¯.�Q“Óïnö<§|ñi3ø¯DÚÒ6,ÇÃ;m‡”ø‚#œ+íFÎw’â«bÌ„€}í³ÆùLS@ ˜�R»#"˜Æ-Ξ=‡ãã#ŒÓ"`ž:…K.¹§N]„ƒÃ @À¹³çpttÏ|Îóå­¿ñ«ìn½m|×Å믻áƒW\~å«ÞÿÞwýóišž22 *â­PÆfh|�îkߟºÆÄ -àûó;þWཔ?0'$ΓDǃ‹ÞIÈœ†V©vs�}i¯¿t´JïWg‹àτǼžT |«­mŸÖ¯À^eûù©²÷<ÖÈÇÊÌ—½ÿýïýn{â¯F§CT"â¾ë¸ï{ Ã6CŽÛ Û±Gw|Œqœ0…ˆÖžíùqy·î ’Î=Ûø{uÓrÎY´–~ÇñNI?ξ£FNDVš�s”�Û(­ZµjÕªU«VkÕ­ZµjÕªÕ#¸êL{«à Ú/s¿—à­ú¯í““å�g¾¯–Îu-�•5 eg¸rHÇQÛþ×àRr¥ëRogŸâi)}!U9&t1ÆSÓ4]c¼ñåÏzð«!W^uO�Zö£SŸz{¯3`>9˜JßÀdJ§–ÿdà? ÙM@×MY¶,©ˆIc˸üš«Ì¥å¿IÑë`Wa0¸¼—-Ë€ˆ¿ð§¿oÿ­÷â§öW/è&…ØG>ü!|þsŸÃ³žý\~ù:qž?À“Û?×iøêù�82"�_9�dŽUI.\MÒKB褣ódÇT&-ÕÆ^Aß÷RÛ_çI!�ö<Ûw:‚ù4»NX2Ǭ~ds-è¼€\¯ÇUÙ§g7Æ æø‘Ñ¡ËËxï²!ÄÖ”�§N]Œ'Ýñd|ö�ÏâcÿŽÎé9U–èl6ôD‚¿ùçïÀË¿äÑØn�™!ˆõ NàÄÏ㜪ÑkCuj˜çÙ È+Ù„%À‰"©•G0ýÕÌÖÕ7Òìce‘™ûü®ò?MÞ«­º‘„òÎîë2q/™ ñe?*'M±Tì«ÍënØ"ÜdNÅi�ȯXø[»€X™ppJÌ@åÐan à=Ï…#¬Ü„»ÅÕs¶÷¤e°wÓ—œŠ—ö.‘lþ úÀ}Ï~"Ãí[§îgʳ÷ÆÎÔ}[#´juþJÖù½Ÿ+x»®·çjœIÓ3˜Æ¯ø÷^:t]Ÿ +Á®ïmœÛwèº�9Œ"t]º]©êX-þõÙ—Õñ`yÞçÄØìÀ#¼�7ËxzÞ–ðÂð$)"r¿ Í ÊvBØnÓuÒsRw«-8F8sù:88ÄE]„K.½§ÑX"ÆqÒýqÄï¸S>õÉ�GGn; }àS§â•W__ô…_òm¿ú+¿ôšíöø²2>Âr¨’®¨Ð<Å1Ô®óY9¿t­9¹AWÒvÁÿÅAûzÚW½mrtÀûýZ™Ÿõå;¿B–£=}ÉÎïùRÉNF ê_HlÖI—êäö‚pâ—šùÉ�Ûí+íMoü±ç½ð ß €½sÑ9ljtãðî4ž‡;s·ð½¹x%gód_AÈîA×w¹�aD˜BväPl#ºùÝS“ u—!ÙÝ‹Œ Yà˜ÁL¿¯ëݪU«V­Zµjõÿ¯Õ­ZµjÕªÕ#¸jk{`®ÔOÿ–Öȉ,ÌóWë×Ó: l¯ uíêÓÏådjM0¨÷½o›i;õy%Õ"6¤ë�ÀÿD(J¬uK襕ÿ²NR”V׬›¦éâã5W\<ÝúŒÇ¿^uO½ZøSUî›å?Š|ª3Â;ê;õÀwfùŸ"L©ïˆ 0ÌJ—¥å?ôïlùŸ”þ(ûÏÇÌÁAg–ÿ1ÝxPõ¶EyKðÏ^óxÿ>„»ïýÄÝ¿é?øàƒxã/¾OÆ3që­·éçE¤`,I±òÌ“Ë{&„‘Ϋü–DщPPüàËv8&Z øŸC^‹¥¯óÎbæ A":UÀ‡tÙ¨(øëJ/¥Én*R6I„Ø}&z‡�}ìc8>>2�=Ýï¯þ–Ûð²_‰xtA˜€Îýü»Ä^Õ鉘µç'»ï$ßoÞìríL%ê:T‘X ”>¯·9<˜Ø@%>ã‚+YÌ�òóã<’Z‘²’Q?ÞB `¾—àwj#œ];yo@¼9z8Ö¿Ó}È�>Kˆ ÇE}–YŸ/'Œ`çkÏG Ó È”÷TžÝ|^µS@ißO¬´¬¿ ‡«�vŸO"q·ßôÀÞó±kGD.úÎïüÎ €ñŸü“ò6#_·å˾eß²‰,¶æ‚³Ï ¦Zµ:¹¶ãh¹ôÅÊÛû¾ë¬Ýgt•#•°F±÷J¾S·ßyC—2³‘S; ›�æ’wœëK4O_ZtMM: 1ÎrÆ9�ô2�»Y7“£ƒRÿ‹×Æíã8bG„fíPnZ¹Û�ØJcuk<Ã4eâå×S¼Q×wfý¿Á%—\‚‹.ºè½NqR·&G½ïÀÀG=öñüÛoûM_ôE_—¸ô²Ëä˾òåíçÿëOŸ>::÷ ³f»ÆõŠ|±¸€Ü&bž “]„VÇ} ÿÿµ±©ý~±Þ/n7TÞŠò?÷K;ü™"ùgíž�:nfÇ} Þ¾›­¬ç[}ïI¯Wc½ìP]‚Ë.Kõñ)ñòaõÔ®M+Ù´Òw¯½fÇæ>uß'¿/†øŠaèGcŒA/‹Þ1N6¶bT¢ŠÆŒ·#ÆqÌñtÞ{l��°Ýé=ÚÙ1M#¶Û1¯Ÿúcu“³ïw!"ø`ŽÏ€ L1w(�‹Ó=¦Cy6G­¹Ó@«V­ZµjÕªU+­FhÕªU«V­ÁUO &�|©Œ¯ÁžùD¤ì€òf1KA½Ïåïé8ö),j�²þ{Ÿ£Î�­ÿ À¾ïóñ$•Ô8&+×8;§ Um®Ç’ô°Œ!l˜ù2×Ý OÿñƒwèA€Û˜R¿ÓßÑ+°ŸøºSRë;] ’óö§È€Á¬ÿ•§6·p ¼OŸqåP�šÅòß-,ÿÓñ$5M"�¤ÉC6ðŸg–ÿ B&7€ðHÀ¦÷øw?ü]xÙ×þ¿ñ¹ÏŸ¾ {X?gáÞò›¿�Ï>ð<ïù/@šîN¹ºzTvœ‚J©gÖ¢:§[œÊçîVUbiâUdA@qEM××�fà­æbè¡EfÄ” Ì„èØ{p>±Is")x(yÄA8æ ÿô<%µ¹ƒò°ãV¥a„HQN RmÚ†Y [T‚óL:9®sºzo_~Åå¸êª«qÿýŸÆÇ>öQC„ñå/º¯úòk1�ù$&&0:<È÷`ÒvS¡è¼ýFH!@Ð�œÞ·ìz ÞÔÃw€ô` Ùäõõ8iü;09x{\å@Eñžîë8ÍBŸ!1Ú«z‹˜E5¢Þël c™@¥Íƒ>ÈϪÞ®ú[æ7< û](þfË,-›/é¹®$P$mã‰7qý¯‰ÈU"òyg�¯�Xk¯×H\K‡›}íüÒ‰fù¯U«V¿¿ÚŽ[xSþ—qYMÌœ�¯˜Yûøqœ�Ýè6éÐÛrŽH]†}׫úß9kûœHÚu.ŸñEÜ Ìv´mc„3b•óÞH{e™Á‘1M |ŽÛ-¶ZQëò6ÆMJêaØ ë�á¶[@1“31Á;t¾ÃÁpˆƒƒ 6¦þ?<<0W�€qŒªnAŽpxê‹Ëú²¯ü*ù¹ŸùIú•_|}øÊWü±cºà…_ô%ç—ßðºsÇÇÇß¾TÙïÚñWàqµ€”k?ïT– ÿN×CÒÍÌa~Wø²pEáŸÛ}#, º/jÂŒ�ÏEãÅBÈ.3ò‚¹°Ô�ÎNß4w:æÄ†ÚÙGß©v/ÔšIÂîç�vY“Ö¯oÚ_ŒñIoxÝÏ|Ó—}å+~x§-³LÌê믑.ódUéÏaBa‘Ñ\¬†ÁãìÙƒLpŽÀ,¡·ó½žÆî„ê£gÿúɃHÇÛS˜À1ÎÜJû¢ŸEq ÀÃñ£hÕªU«V­ZµúU«V­Zµz„ךåÿh¿¦lœM€VñjÓºüß’,­•kUeÍ—ÀK½núIfkº$5ÔÄYõ_ƒÿõù¬m7ÕI×a_<Àâ\<3_àª'Ü<>ù™·mŸ© ýEªüOŠ}×AÕø¾Ü© uÙò?+ÿý`ëôU„€EÀà3m/©–ˆæûØÿkç�%ø_YˆgË1 y þWêž™ ¢àå£o¼?ô�ÿ¾ù/üSŒc¸ {¸þ\î¹÷|ö³ŸÅ~Ñãšk¯- 3Ë’eÿ™•�l{yf š2‚Uä¨èµ“-«Øv�sÞ JZÞ¦T]}™ÂHU€ašô_ˆv�ÅØq‘ƒï< ò jÃŽâ$J¾ß ‰z¼Lºß!2Bˆ„Ð[ƒ ›NÀA’Cæ9³À{É@É5×^‡«¯½ŸüÄÇqîô§ð7ÿôc�ÀœH$ÙHB,*ÂÀéä¨OætA â:)I€Äå«(1ª›…ÓûLxÄ`÷¾Ý®DJjÐ ˆ ²Ãtœnoý„Çé^Ž&°âl`{r¯�f– �-$"„G} “ýŒ¶œ�õ²Id Äz9ØAÀ™<A¶~0g�`DdÖh6B�¶nê*a„‘tßêvj jL‚¹'°, ¶\eç_ëâÝ Ø ÂœàºÁ',]§ pÛ Ÿ»ã —[¶Á}FDθÿ»¿û»ùþø=©}X#›­å AmI|[[nÙþŸ¯�j­Z�\aš Îaê{L F³Ë×ÈœyŸ9"„çâ 4÷�¹½÷3ü“ix×Á»Ϋz^€`Ûå]g�ÈlÎ4EéŸ\–ãÝR:ç2yU—Ÿ;JÍÜB@ˆjiB˜m·&xßѶÏN!l6UR�#(Lˆv�¡ÏwÝÐ㢋N©êÿÔ)l%ÅÆ ÎÇÛ-¶Û#ŒÓr§N�Ê߆aÈŸÑ�7Þ8Ø+ãvËOzòSÿÇ÷¼óg¶Ûí«óà²FçË ê¼Öþóöq þ/Àé_',1o*ëR þS±ëO™ï¹}¯î•DÈ)5´vÌÖ¥‰ÌÌs꣫ÁxYï„°”îÞUÎöƒPõéJˆ‘)b-F`ñ‘`ù}Jv®ÿÜkþöÚµ?sæô«?ð¾÷ü—o~Ôv§¦S˜bŒJr�q76N�¦ŠÃT "@×{oqpp„¾ë•8 :v !Î\=¡N—Ñgo´±v47. Ù6rÐÏȯ(‘uíóЬ1N®¹´jÕªU«V­Z-ªZµjÕªU«Gp-­úh¾ÌU]Ú§Z*“–Û©Áö%¨¿Þ_øŸ^¯×­ÿ¥ýÖà²üOˤmj>êÓ4ÍâN²j^#1œ¤øLÛ\9�K\ID×½ê Ï|]×wž¨üŠb?�ÿ MªhS 'b€)ª‘b`Êÿü»È–™ÙŸÏ�Øòš3Ey¶H§øŸ~¯lýk€°©þ�ÀF0tüOêe^ôì/À÷}ï×áøû?zÁjÚz2öÁ?�Ÿú©ÿ‚g=ëٸ뮧•sª{�d”lß[Ý�.�ß6éîªkÎiÝ8·ç¯€ˆz[ÉB4BÄÔø%�l“‹1Æ Ä‡1†)“ºnÂÄ=•ÜvUâ{µ‹7ŸyOšyO€øñÆ8S éñP¾c˜c0°#êùÎî}š_çDÔA™xN×Ó{Ê ×]wâUWáÿ|݈—Þ5â’Sqò„Ω…÷—-�‘Äb ü‡ôÞ¦^ÁzRýLôMäj‡K}‹Ïàâz]Çy½þkªp¶[¾úlÖæz™y0‹°gDí~©žYÑkɰ¶É|†ºp²æg÷Óï ì‹D³÷J.@,ÏT¶e[Ååaô>³:¶çç[}ö~ý�Û±÷³–Ë”c‘Ï«GlÇÂŒS>xÕóëÿ훟ñ9fíù{¾ç{|Ík^³]oöOØïk_NÿOÚ~­Ð]öç�NhÕªÕ¬m`– Žã}ßåñiŒ1÷�1í7MýŸÈœ”úŠ�CO�ó(¦*dYßjÑŸ2Ç…%òt¼&\ÜP؈ƒé™&çàØ�º²=%($2"Åì öâš7¾¯=XŽgÓ~tLëàÝ|Œë;oñ1l6Fj à€fuï!Gè|‡Í0ààà‡�Âáædën§ãñ1ŽŽ�0�[ˆ¾ë²êºzô]‡?óçÿ¢TZAD8Æ(!FÜô¨Çþ/ûȽgÇíöo¢È•çW·í’,ÿeæýŸS–D0ƒÊ…ð{_Ÿþׄ™YÛÈžq&íéE«~d¾N¶o¡bÓŸlþ ¸/ýJÃ/ûš4Æšo[ª}Ñ5EÈž(©»áŠ�qAýf"ÐÞ‡6_'òeï{ß{þúU×\÷�ÛíqØn'·Ç²Ýny …t­¤Vïz#º’ư€9äcLßY•¸«ßá’úú®‡s§ÐwéÙœ²c áL¦å<6×ÏEÛ–Dp…ÿ‘X ÿoÕªU«V­ZµšU#´jÕªU«V�äŽÚTúIï«á§qüëé�zTªz£ÙˆÒ^®—)ÿ¯Úðäs“#$ƒõ»=TŠ5Z2°ÒÎï9èYlæ}â¬oAwÎ2¨"„ÌûƒÕ4¢•~:>¶(€â�¸QóÝ/ã N2�œg”¤5�Û?þÛïxË�>þ¶Û5Lc§‰§iäD¼èxèA½(!”tŒã!p¤jÿ®ï1 #B‹ÍÐç^�MÇAÎî×â*P® ÛVŸýÜ.ØwHG>ÒóYŸ{rkÕªU«V­Zµje¸B»­ZµjÕªÕ#·–€½·lÒX/Uø5@`üOªÿZÝ´tXsX%KÛÕµý×ëªj—�c†Ù¹¥Iâq³ê¿vHÛúƒ¬øÿ/p9€›s}¼óKž:~5¨¼u—*Øé’ê?©ôÝxëóO¢¡¨��9T`¨‚ÿK06Cèç3œÎkæ89Ìmþiaù_ÿf­ŸUÿµí?× fS5gÕ¿)—ÙÔÿËM/–ðÿ{ÿ(îùð}øå_ûÀïõÀÇ>öQüØ�ý(þÈ‹¿�~ÌcÀIU&Ea¶œËô¦`ÏöÿN­?yÍ«ü¤½Gy›Äe `@Ýòræ*07\¥BÊÈW[抯êÜŽ"» úL3�Á‹ås)9ƒÕÞ˜½¯ûàê9Œy�|-³Z3€Å™zKãÔ¦•ñ¦wzüú{Ï}’àå/\wEÔû¶"^ä‰îLTIÑêˆ!B~»ò^~.ìš%÷ 7@¤Äe²@Ò±0œZ$²½Ÿš û|S„C™LvY2Æ9cgº˜õ ³Ýëzè1¢¬oçÆ3¹c¶¾³ 侮Nh‘³¼È¹Ÿµ›XŸ¾ç ‘qûú:»r½e­Ýt‰hR�ùNfíL&Ñ áÍ27‰ÍoˆqÓUg÷m/þÍïù¿ßò”þé‡.#q¢§¿ç{¾çÜk^óùƒjÃW¯ß è_[tŸþŸ´ÝV­ZÙDRß›‚]0Mœ;6å@? LӘǪ‚Õâ;"¸Zˆ?Ì ÞhvxRagne ª‹ö ‘céO¡¹àª‚ž“FÁÒ{G#¹äxøÁ ®¬æM•##:6G¼Ç0là½Ç0 «cnmk|+G†x=—¾ïppp˜—í:Uû‡ª×zlà»"jµ>…€ãã#cÜnb²T÷«DØô/EèX»Þ;rư¸þ¦Gýð§>ñÑnÜn¿»œwè‹¥éÇ¥ v0üP!Uêg0{94Ú_eœ±“eÀö,O ­O¨lùíýêžRÀÜ 3}!”Ì$úT¬çë× Ëè™´ dµ:µåyÈìTê’ü¶$=ìëŸå®Uéñ?ÿ¹Ï~ÿ4M_ !:ïƒgçÙÔÿ�ÐõÇA‰¸“ˆˆÞa³é±6è‡"Œív‹#Ü4V}ªäû~6èúÎÒÇôYV‡®˜—Í×ÓÆúÎ;ôÞg�_D`ÑDæÞÑ­ZµjÕªU«V³ïmí´jÕªU«V�ÜJyɳâAd€O••– Zoc99R[î_˜+0€¾Viµ“A²üOç–­b ü?>>Æ8Žü¯�¡.9¯òÿ¤uês !¤sé‰è"ºÎ;zÔ·¾ôôŸÝl耜Ú÷S‰)ž}¥ú‡©þ°ÏäÂPÙü'ð?98[Æ›j¶õ“êŸ*ðÔ–qÔað?Áò_ÒOÕÄC’M®å‘‹Ùú'å?Oj_.“þŽ¨Ë‘9òï ŽFüïÿø›ðŠoúgøÀÝ÷=Ì»[ò¤ëñÑ~îç~�¿õV¼à/€÷ýnb,:)åfà]¶_œNÛ’dµ6‰)ñ¡ÿib•£˜zïÝýññÑ«K·R�³Ò•—eÛØ£&²Ù�ü ´tÈÏ›9xOI{¿ÞRÇeF* E{?'$‚²4™»„Ž‹D:Í× ­kÇ£nJF,æˆ*÷™}îé ŠŠß¢˜ ×wžP³#Ò8žö¼oãæÅ˜hF&XaZ¬qг�™ïøÀ{ßù'oò]¯D‚÷~â�ƒsï:t}oÊ~ßË5. 0 BŒ8wö¬Ž9Ä"XÞ;t�’g6uKmF`�¹ ‹ð�ÅØÛ‘ºZ$w‹ôÝ5Ur¾èº¾5έZµjÕªU«VU5@«V­Zµjõ®$_*¥öÙî×VûIù_ÿ½¦JÛ[sXSSÔI},u¥ÉØ¥Ýú×u: afLÓ„ív‹q-uš‘ –jÎôó¤¸�“À›úº-Žß8EDW}Ó—žy壮æÇ“3›rr@¹*�É”ÌiîÍ j@=ÑÀÀ*×€Nwaªuý=¨®d‘g7Z±üOC¸…å?�3ÅgàÒÅ'•?›ú_bÎ.,Û\&ˆ˜â?�ÿÉ1@¢æ¥;†p€™uâ¢CÂ�þ‹oÄ˾é‡ñÉO?ô0ïp›ä#�Ö½ûƒ¿‹O~âxá‹^Œëo¸^?OÌçF]R†�¹î»E Ë­§",CQæc` æ|û2¹šcÒ|®7àÐ;t¢“ ÞÍ3…Ìâ8ƒÑ#zΨ0ÇxÝ>—kÌ�z·(í�©Ågðcm_›×Ñ¿=€H€8˳‡e Ã�ìª0 »ÜO¾z¶òk:xË$�–oœŸÏ´OO6Ôßinòò9väÀøÊ^n[®ú31•ŒŒ\tˆe.'0¡žD.®ózLld�dcë|§×Ù©}±Þ2‘~éí[üÊ;Žñü§]„W¼èr\wÕèœ]£Êž n éÞLÑ ¸tßf€}v" D°<ðŸßX¬ôíŽöMî’%_Ľ@T€cµy¶m9Øò}óÕI8L L Í%c*v¾8sÐuíYŽ h!2È%W€˜‚«Á‰Œ 溑‰:e›¨îï|fóì ø¡Rè;*ñ© ‰kÊúµýÖþËße¼Ì ³íåÈ‘òjïdów~ðÏv4nÞô�Çü¤µ¿òêW¿ú!SÁ.Æ n´òï#¿¥g2bË>ãB«vÚiÕªÕþf‚YbGA0åêËœsêöÔõ8 ÂÁfƒaØàܹs·Ç`–cÄDêè2WK' ?=÷ºO¤ñgêUœGßëøÄw�õau$¨µOuJP·œ4æ-íœæ�§u#b CÀ únƒÍF•ÐÞ»Ù<ñÌ�IAüt]èÐu=œ7`¾óF’òqê˜Fûñm3øÂ³c÷:†ôÞ ì\C˜@ÑÆ$ÞÏòÑë1¹÷^¼ó¼÷Ôõ½{Öó^ø�óWßtõ8�_·â3?oú—ãë5°^Ý U/WÄMZ•ðÏû« �W×xæ ±<„*Ù&�›¯�QH€: ó娗\‡²LÅ,�õu2‰Ð’SÒp¿&ÐÉfý…�Qù0ÈüúÔ×¥Û…vz WÝûÁßùK�úâ—~ß0lއÍ0l6rpp(ƒVBŒ˜Æ QmãˆiœŒàÐw^ï½¾GgnéüûnÀ8�zv˜#¶Û äØÜô^eæYzYv»2ǪN:î:ß«— :ïôùj­ZµjÕªU«Vs\¡]‚V­ZµjÕê‘[5X_ÖK€Zݸ¦ü¯ Kõ{ ú‡JµœªžØLàJ°êÓ2µê þ è�ãˆív‹ããcµ7�¦UµçÒ± Þ_½ ]€öÚkÕ6Å9'gŽ»ñôvxàŠÞ_ R[®hSúHj~µžïU:å ül™>+øiŸå?––ÿ0åÿ‚,0³üÇÜÖ_ àÈ |Ô…*ËÿXHÿ…“ê?Ø2•ê?§Û'ÐÒÀ™l»J¸ý¶+ñϾÿåøsßû{"!Î_åžú�¼ÿØÇðœç>7ÝtS�¥Ìf…_TKÖÙg9sHÛN�°ª˜æ¤VO–¶‘è`&¨…{qžÐ,Ô+ÀAŽ,ÞBŸ1½4%ë8Z®¯Ú•¦�×° *üôS 1Û!'YôAšä´“ÌjÉ<¢#pôQ "²b©Ù�Ö¨Ìöª•ò§gà @e°tv_èùüò[¯¼õA<÷®ËðŠ/¼7_w ä]ÑEÊq’œ«îa²°zkÐËÌ9vÒA$€È¾¦0À$p0`ˆ%Ÿ“˜µ?Íf¹“µB²‡æ¬f×Xãê:ÎôƒÒsd„ˆ>$Sy’r0?«¸£RøWÛ*ñl§ž–—jùê…ÀѾ§ÂŽx†Â # QÊ=“ÏkmœSSvÄ,(sæ²³ìÞçÕèa.ÐŒ;eø/½ãCßÊÜßó¨ÿbÏià €##N ÔŸ�°äálÙïÕ¤¹Ôï,‰b­ZµZ¯i aBœ À.ÒÁ‡NÉTÎasp€S‡‡è:u¨9:>Ææôia;ލ¹?;c?¨:[û«Ô_*yMX%æ¨zï¼öW©õñ%*$rDˆ[$ÚŸ:#ì%€\dî·R�qC Ñ¡¦iÄfal6@ºìþS·/ Ø+0cÄ4ô}‡®›ò˜ÜûNIäà¡$SŽFF`íK5Ò‡Uñí<¼wFvÐ߉\¾>eŒ.6Њ+D]û¼÷c×u4 ù#/yéßú¥_øùk¦iü¢™gLR”£(ô3g³_fàûÒæîyë÷hî‘é›”,ûQHÉ__°B˜¡ìéåù–�)Ù3©¯«¢Ì«›ï¨&"èBilE•ƒ?¥›ÚOÓrHšIºïz#;ùORuÅU¼Á쾕Ågv¾¢B°Ím·Ûo¾çƒø÷Ï{Á‹ß}ñÅ�‡§N…ÃÃCúADã4âܹ#œ;wþÜ9œÆöx4@v: C‡~pÑEÃ{�a8ÀññbŒ "LÓdÏþü»QÕ‡£"kƒA`ÑyAgn\ýÐeÕç‹F«V­ZµjÕªU«R�ЪU«V­Z=‚+[Š/¬ù×&ójÅý>à¿Þn­ü�•rk9 »¬zb4ÕÒn¹ïû þäß¡!ƈqqtt”ÁÿѲdëm.sŸh³,ZæÁ¯\Ãúï}™ÑD$DÄιø¡O|àŠKâµpªèw§SÙòWýâUñœlþ]% P°¾¨Sݹ£…åÿà×ÉĹê?ÅfSõw:™ü à˜À©lüMÕŸ~òH0Ëÿ )û<;H!è$y¬–1õ?ÇŠ(Àø²=ÿà{¾ã~½ªô~Ÿuöì¼áõ¿€Ç=þñxÖ³žƒ¾ï De‚“++wR�yz ¦ÑÞ5R'SQÙgîæ8ìŒXPÙ¬’äÞ¤ëÔJØ|×Ï-@ÿkw RÅ;qÞsDˆ-ÙÈ N”YY2mx¶F6²B$U † “þ ®'£-ߨÎ['¼Ós¤WÆ{§€Ã,fDUqÎ)B1tÆ¿üÖÏáWÞöy<çÎ+ðG_ò(<þ–Á®“]Hrš§Ë�Z£+Öô^—“8)'ÆÔñQÐ&äS†ëºâ_XWtðÂ9eeYrTÅ-ˆ¹÷ëu»� F‚Éq ü‹D°„rgÙ.¢@@8‚¹&�ú–\rr�@å| a§n\-¤Áí·ìOwD¾—Êüà«�ŠîjÁÑ©ÿv´Øÿ΄º¬£8jÔ WøîËžü‘oq2úŸý­Gý§Ò¨¡²D˜÷)kíø>@jË™y朑@‡Úú?õEËþ±Zµº°�·˜Æ S˜2€cTw›¬ îpppˆƒƒ D€aØd':w„iÚæ¸§¤Ö&ªóÛ•ˆ§„<%ɉDfĘHTñ @0u|—âYDǶ1¤ãJÄWµȤ.¢jŒ,¬ þ!L“’Z9¤q3[޹ŽÏ‚í'„ Ó4U€|@Œ¦Ée€.»cmÊ8=ýbÕýqi“ÉyøÎÖí{³:Lc0€¬ºtŦ ã4!„ù¸„�ˆÐõ�\tê^ú/û‹?ÿ_úßLÓø¬ÔÃ(Îlצ²­·�T 6e»šý-ç_ßU'7Û¾ÐÒXFïÚ‰�¢Ù½´3ö«Žnùý¢rè¯þ'Ùy)k牨ܥ”¢„lìf±GsÂòž¨ûeRÃâ焃úɾî=Ÿ*GƒNlµ`YO†èž¿ñE/yé·N_t1Ný0°ˆÈ0Næð$ˆ!âøøÌ¦)`šÆBʤSèû›LHï‡GçÎå¨7¶çŠ�¢µæß[gç$‚ˆBÐq� E › :¯‘#S˜ZãܪU«V­ZµjUU#´jÕªU«V�àªUÿk–û5ȱ´ü_Ë8®×¯ iRp _ÏZ¥åj÷�üOné|øtt”Áÿù$0íÍg^;¾ ÍjÞwüi²‰ˆÈ®¿ëCï{Ú­Û�<¨¿ [Ø^:Uô;û]`PÛsï D€n®Š⪿kð?Yþê`?áN°üPY‹ó ø7\Md¡úŸT©+àq±l…0›·aëÍܤr`Á7¼âv¿Vÿ¶Ÿ³V–Íd�:>  ýs'€’ ŸˆR�ÞÍ×_BòL*%«šÔö_íÑ»l±œÀÿããã¬üßnç °óU­îüýÖ2+’ˆÈé,¬Ûï Ÿüº/šÆçt—Û ¾â;PVü{%Pg¿›#¼�ÿ%* þ ÔŠòŸ*ðßÈ«àRõ#ÿεE6£©�)@Á‘˜Ëdñž-ýu'¦úÀqÀE%�C:Ó¾lÊÒ þÂ7<¿ï!ü›ÿøž|ÿý~ëèèo|ãð¨G?Ï~ösppp€0ûg^³‚bá*Õìm&­TW 0̺Îb̲ä“2Œ@ ï,똱éRìöE'î¥ÊRW;ãhùÀœ'ø‰‘'•þü¼0‘&C1b8gŸ%4q¨(Ìô¤A8S± ¼w•}³*¸9; pþ�ÙX¤š(~ó·îÇoüÖý¸ý¶Ëñu_ñd<õÉ׫ý-ÃÜ1ô>Ög7.Dëi[»jZ·±O×ÙîÑõ–ÀÙ}_‹Ìg-‰æMs ‚à¼Mf‚ƒ×çYlu0sß«uj²AºÎú¬'—�`7ï‚ä „ìž¬ºF,ˆP<7ÙsuvÀˆ•EʯTök—río¦Ý�Õ2Ê:'¹ZÎù—>å_ò³¿}ÓCDtÀç¡Q³v½þ½n«—6¿kŽ.5°j€?¨ö©U«ÿÞjœF„”ðæžœ�'•T:nGaè{ê<ÆñGÇÇØnGÄ0"²Úø;§6þ¾+*àôlƨÊߺïU€6"ZÓ[+÷¥Ê©wpð�äi¯4ÖtÎⲺ�í/Åýˆ9´Ä³à×¾0Áq@ ¡ëÐ…ˆà¦ÜŒÆÜ�v]*¢. õᎺ~Ä4�† º^�#å¬o�·8Þa·YÑìÙg‚C'ÑÜM PM‹ØªãODÓ8©ãÖv«± !‚� Óãåíñ1}¿%"Ý 7ÞwûOùö÷¾û]ÿ‘™¯D¿eŽ€Sÿs(=ë¿f$Q§ E?•¢JOkî ¹36‡¹Í”-’ (�ÝTˆ/³í®íöaUŸ’ûˆÕ~‡æ}�̱~JN2',ÇŒûjë³èˆ××›KþigŒ,«û�òÑýŸ¾ïoßÿéOýæ%—]Ï�;ÃÁÁ�t}çjû?ã¸úB@˜B&¼èò]ß�E0MŽ�Ž”,±$ñå踮ëáH£Ö8*Q–ÍÍ,ƈqš2ÑÝ›òŸHÉ1¹5έZµjÕªU«VU5@«V­Zµjõ®%` `$ÀÝ9—®©â—ÙÇIõ_» ìQNªZ­‘Ž¥ï{l6›¬üOÌ!¨b#�þÛí6Û¤Öǹ<öe-Ïqß²²Gi³ï< 3‹.piˆrñ=Ÿ>sÇcp£ë6€ë ÔWPÔék0@²üwà<�É^+»ÿøŸrÑǾ,W;d"@šÝ^ZþWà¿,,ÿ“J?• à?qÒ÷r¹�ûÀ’ÁS(�`þ‡Jå[O´™ê›uß÷êçâ¾OŸÁÏýʇw"(~?õ‘÷}òxÚÓŸ�Ûžð„òyWæèdªýø¯Øy@bŠ?¬m äj±ÚCm;Ž4I-;„ÚÁx–2on "%ÖCg6õ�„3I@çl«ªÄŒ*C>>gÜ;r*„€ùá9x§¹À³ìs–’²•EÁþ¬¾ªÔâ’I"E…ùî÷Ý�w½ïñ„Ç]�¯ùª§áÙw=äYã/À€$ºEÊn3œHÀzÕ Â\ø1ç)©ìæók�|ƒ’K/\ )`†D#¹°ÅH8Æ`iJÈðQÁ|a#ÖpJ�Ýs±²û•lq›í*lßý\‹Ý‘Èë¬wu>n%Údf½\ÝÔRÁ&Ƀö^¸º¬vw>rU}¬²¾½ùŽòýš¢n»yû¤_ùàE¿à~‡ü˜?©�™ÃÏú‡åº5 &,-³ëí¶€V­Î×ðÚóB)"Çâ4XíÁÇiÄÙ³gÁÌèûaš¶æú´Å4©ó”÷"_)‡ûJÉÎ6NÔx5FÒ¶–œƒ�.çÝÏûkUÞNž´­�QûIï•üÖùÞ@Jgjm%ÆÑÔúsqdÊ{?k+‚uL4Uþ‡,ß<µCœ V):€ˆÐÅ�ã·úÐg SÕÑ#Æí[SìÕÓÅ€:x¯‘º_C¾r»Ñkëó5Ím+L!8v˜ÆÛq„?>†sn 1nûíÖ=ê1�ýà÷ú/ò“Ÿx-€>õ—Rî’-ïçm¿ UK.ú�™rXò Ê낹.¾c!ãªû…Å=Ñ¢[¢ù~dÞ=UÀÿü>ªÉ›i{s;þ�Ì#¥y²øßç¬fÛ¨VZöW3‡�4®]±ý'ªû6Ú³OÉQ1Æ;~ú§þ¿_ÿÅ/ùʻ٠ãÁÁÁxñÅã’K.ÅááˆúaÀáÁ!6çpÔ;m©?ï|q‚¾ëÍý£ƒ3ÒM"©xç �|³Á°hÆ) &uÚwûë¼óÙÝ¢U«V­ZµjÕª•V#´jÕªU«V�àªÁÿZMTî ø_æ&®m#ç�šåÿÒY`9y³6ÙTÿL1Kð? “©Ó4a´‰ÌôSm ãÌjùBéßÔù½6Õy^ à W¸æeÏ /zâÍr½.Ô™ ?©Äz•¬Qoÿô×Ùé¾Xþ'û~,@òy–Ô±+D�L0õqªrÁr[õýݪU«ÅóÜy ‘’漩èɈe“¡t!LpäÀ"™&­�wñ•‹”Ži}§ý‡h}�Žï|VU«óN$ÙsšTüD©ý ³Õ75<380k¿ì:uÎê²ã@‰áH™ÔàÉÁùäPУë{t¾Ëëˆ08²EDÄ8ÓÖci®¹ý²ßûžs»3e"�:03¢#„ØÁûï‹ó�÷87ÄŽ&o¥1ö4Ž˜, �'à€ÈêÊå½²¹B£}—à[Ÿø¤_yèôéï;sæôßÏMºT6÷yH± ^`´vœ2A@¥@°†Kϼf,Êc—9ò¿ë&€¬À/ýÓÚxPÌ…©ógËå¾q Ú v~©þ_®ñ0ÆÂ³¸ƒ¬è_»uÿ·KØw�³C…^¥3§Oç=wÿÎO]{Ý ÇÛiš2²~p $ßuèûÃ0€9 ïᜯâ*�Õú%ÄÙën¦æïí{m׫ €Ž›G|-òb‹iR’Ì8MØn�qppˆaè[ÃܪU«V­Zµjµ¨FhÕªU«V­ÁµTÿ×ÙÅ)7t©ü_‚#Gù¬[(§×�¹š²&#,Á1»Ç¤úOÀ"¬ÿ')ú×@ÿúœ÷moYõ9Ûû€K Àÿ�—^$�û3/ão{Â͸-ƒöÂ:UeËÿÎ@úü÷J`_�ù@ÞNþøŸA_œ2ø¿fùŸÉò¿úÇKË6Ëÿ`èS&è¶BÉcg6À3Úä ½.R­“À°DF¨lÕ €D%#P‘syrøWÿÓ‹ñõßùz¼ã=Ÿ�ÝŸõéO} ?õ“?�'Ýñd<õ©wUÖàœ¯]­ÚÏŸùšc-ÍïgŸŸNàÚ„½Mô§g)�ì0€ƒ«{•Йùµ'‹b1u}º¤ÉQ€@ª”6€ÈÕñˆ�·ƒj‚{qJÉÒ_8)ÎÅœ+ô]=OÙQ32×*7^X§{Ë@¶ e;‡L"ªmp¸÷ßÁkþÙÏà_ÿè¥ø£_ù,|å—<‡ƒ>Ä ø;Hœç PGƒ¥½}ï-_W‚«·ãØÎ¿^]‰"ÂQo{‹ P5¡7ËY²¼es,îᢺ`�/ÏdŽÈ˜ èª8ª”v–S Q£ˆ]{sð² ñ9á!Ñ;j(Ú¯øÿç5ÜùÑ~÷0 ´°pÞÙkíb�HûœYXÛªƒwp饗^DD‡P€[îëBÚñ uzÙP¯Óÿ­Z]x"Æ�ÁCç(“ç’==óÛ­Yù‡ˆ`.3ÂqÓõÎmì4"k@2Sö‘Yƒ'[â˜û?“!ÁÅ´-%ÀzD³÷Þ£ó]&²ÎÛ%xçu7tNö½�“ÞeëtVÝb¼î½CßõÙc=�R³ rÅ’c^G•ñ�’%$ò¡›/[5ÍéX’»ÀZÌWq7H. D[Ęœ‰ˆ‰È=é)Oý?~ûmoù‚qÜ~Ójû(b�øÓñæë)TÅ7 RâË,žIÊ@(�‘)»,¶�}†3T�fP ôw�T༅:é8I*‡*Ç™†_,ÀEßõý¯#ê#“bÀ…õÁ»/Ôc&Yq@ØýnWÎAö�ògJ€È5xß{¾ãÒË.ÿþÈñØ9?õ}/Îùò=ÓÜ,|§îDÃ`þÎ)  rÛqÎå˜_mggŒbÎÞ{‹Ê˜#F"ý9Ž`{†Î�;‡s› O�Â�¹ÏµjÕªU«V­Zµ*Õ­ZµjÕªÕ#¸ÖTD ôßþ×ÿjà?�ÿ5ð¿Ïö ò×µ|¯Vÿ§÷ê Çqgêÿ ‰X8i‚vylõ5z¸„ˆhƒ ü¿ëñòü¯‰üÅË/ÂUÙ®ßD½ý�Yþ§ß øG‡,[v�GΫ"z Po#[»/,ÿE L*m.6ý’±ÿC‰HïKœEHø Õv`ÛMàð¦cJ`¿e©» `B!'8<þͼ_÷ê_Äûï}hö™ýATŒïzçoãÞ{îÁ³žýÜrË-éŽR…üŽE?j±]&@J„˜ÛÀQl ?Í4漎óE�Oæ¹êÈÍÔýTMЩb’ÉÃ{É„‚úúˆðX·C–·¯€‘ò“²j’�¼ wTTÊ$5A­’%„²ïzR¼_yŠÄ”&‰ó¶rÜ@ž(W•ü§îÿþ·×þ<þí�ý"¾â%OÇ×|ÕspÕå—fE¡f5¯Ë³…}¨õI*mZY¦€ âDÊK8TžùNòæš‘Ü<”ü™ì¼kG°z …¢ ’€{-«ôeþù9†*æj~ƒ›� åjÔŸy~çïÅ ¨>œ‡SnÏv—j¢¹és½^Š4pzœšÓØè�JuÿÐ Û×þ¬­CDmÒªÕžºø’‹Õ.¥H–äè“e·À13 á;¹aåyLã'%%²ðÂíÃ[®Œ÷’«NRå+™ ÙŠ÷y\:M#œ‹¹ã2HI,Bæêjç”4ç�WàßwèºA ¸Úd!JÌd;Înºnßõè‡ι ŒçBpX´aµ-:û�gp'�PH:.˜“rÓOçŒ ¬¶w €¥¨îŽÜŒ(Šs°sÎyçýíw<åÞýÎßz|ˆáù€ŽgÕæË¬{•lß_Ôõæ $3y}þ!FRÜE¦�@Æ—«QsW˜ª£K6þÅ´Ç&?aS=¥)Ê1TYø Ö¬ú©KÙ¸Š\vMÒ1=l°¿>÷™—Õ™Ó2�NÿÌF ˜³,vû<)�(Æqû­¾÷ž×>îñ·�ãv<::ŠÎyaŽBä0…Ó4Bp®|/õ�Fz(¡Ç)QÀ¢µœ}�]~oÕ6#æH�ü‘ c)÷åÓ4b»Õï“D„¾ï±ÝnqêÔ)¶Æ¹U«V­ZµjÕªªFhÕªU«V­Áµ$$¥}Rÿ/Áÿ¥­­6ZÆ œ¾/Áöµå–1ÞÛdh²5µrH“ŸËIɹÂxÝy`ŸêyÞ<³‚Ý üCD—ŠÈåDt�ˆÜøÊó+_òtúï©+Š}R€?Nô'Ës€ÈœàŒ �&¯}æÚH1ºD pȪ—Ï ý›�ÿø‹¨ÊžП*[›/'[¦ó%âÉšiNi?þsmó_O|Îͺl(ÛÌÄ.ÛàÒK:üûø<¼ò¯¼ ùÄÙÙç÷UgΜÆ/¾ápãM7ã9Ïy.¾ø¢úó>1=kÌ*T]¹IRe‚?‘ê$aU f;~"DG¦&“ì$Sø+¸@p�B š}²îWªˆ€ Y§Å¼.íÞß9cž#ëþŒ4àlû‹ Úêy«àòì çåŒÃç�4âÌ!/œ7§ÇM…| ÀéÓGøÿñMø¿ÿó›ñ¢çÞ�oýÆ/Å£u#HœÚÜ;»ÿ÷ØùÎNzÏû¬rLÛ-^gÔÓ£x³¨v–E­ªØ3jÏtÜ`ˆ8pñ᜷ç� ï8bDõðÎY�nƒ¼FV�Óöƒ‰*üŸÍZ¸þ1w'™�שꛉ(¡‰dF *¾‡0�ƒZö»½àyÿñšåö'>þ1ü—ŸøO¸ýIwàÉwÞ9³K_¦É¯?uæ«©Á²�\þµÒO×qÆûà¬sä ”,òç yrªÐ'rè<t6¥š3K×�ç%M€Û,.Ñúùèó&ˆ¢d…dëïÈ© ½m‚gv¸”'›�sz|n~%È&šKÄ�ƒ÷D&›T.Ç•â$ÛüržŸžBÄ/üòoáõoúm<ý®'âÛ¿åå¸ë®Û!L*´*|9Æ”Í"ó€l�Àú䨫�ñâÓW›hD�€gÏ,ðod'æ`w‘Ä ‹C$p9Kźߑ^=U³Á+y"µ 伯XLˆòMDU®Äs Í.Î|w õ¼TªûüÜ?œ2Ý& Š9ÂÊ„þò9Ù‹-˜_6H!ËNÉ,Š ®ôü­õiËvIŽ[#ÀÕëÖ \«V­ÖëÒË.C˜b æö"HŸ¦);AuqB :f$1u¾YãwÙ¦Ÿ²úX˜Á䲋Mé×’£ ò?¶>yç9&U·'u=Þ¨ÛƒÚµ*B@ä˜IÞ9xÕ½÷ÚoÔƒ‰J1�ÆäÞytFÖ† |çCgQÑGSM¼+cûäV�¢Òu‰ìÕ¡ÀÆŽœFƤ1²‘ – knçD4ŽÀœºÒ¹"q㫱M°%"ºæú>úЃŸÿÎxàß©ÝU•K_wEBÅõ¨î¿ÅFSTÀíÙ/²úe “;òye¬{nñ¿ö½)(¨êK¬Í#2 ÀÖ™�OK\RÂëë>¾�âJ_èl<•œÒ9ä1 $2§[�Ù¨|m@¥ÈŸ�beå÷ºð• Lùʬ�á‡izåÞÿ®ÿýéÏ|ÞÛEÇÇÛñøx+1FÖïx!;j@è{Lã„©Ÿ2�&E€¨z?˜#Ü„ív aÆèÂwzé»\¦‚’Š‚9‹LÓ˜£79 C�¦Ö8·jÕªU«V­Z-&À[µjÕªU«V�ÐZSÛ'ð} „§É˼¯)ëÉ®¥•þòï´Üò8Ò±ÔD³}/•ÿißûß“ÜöÏÉ!U�ùZÿ µ›¾Àun¾ýÑü¬où2|ÇU—ùk ðoà¡S ß¹N-¿ Èà¿�þEùŸìü“ª?©þa³_Uþ§ß±bùŠåÛÀ.óµùŽ�@" )ú“忦‘gpTªßÀOÕ {FWQ\G „9€,Q�!ïKpóµüø?¾ ¯|õÛqÿgÇ?4@Œïz×;qï½÷àÏx&n¹åQÕ2å dˆ V–÷.Y˜;É“üªà/€k�÷[ÔÎâ=¼wÙ>6ÛÈšªlO! Æ‹ÓIà.MD/­ÚQÔŒ¨Ÿ�ÊÜ6MbëDiRKF�5õ?³ÕÑASêÙµs†MŒÙ±;̬}ëÏ*OÊ;�D¨òÌ ´K4k÷ÛK hpN¯Õ[ßö¼õmïÁŸøxü©W}^ò’çk”‹ªãYǦ´wsÒBn–80+‰ÆÍâH�~!8Sà«ûEg¹ ¼°èg¼>/ÎQ¯ Ç*ØnyJÏ4yˆLµ @?CÌ–YÌæºmI¤mĶ¡Ÿ·^3k]íøKð?>n®Èßy®¸ÖšÊSGëN;×6¹%$„ÕX†š(„]Â�SWRÒ�ÉÓwO�Ô6Ô}_Ýî¯)—®8ûj%nÝß´jÕj·.»ô2LaD˜Bœ"gÐ?)ÊcdÄ0!tœÛ*ǽ*ë“£•ó¨j�,ÞÁq!œ*)€-‚§�r¤€¯¬ð}ùW·õ¸q6&Ms÷IïeÂk帕Ô˰±@”˜û{ço±XðÁf3 ë:¯câ­ßÎ@xÊãê.»,•ÔÑâ æº.aðOÇŸ,ÒAJ4@� ø;çªënãaÄHY­NDÁ9wÜu=éλÞôÖßøÕz|tô]ÄÖï×úÌòZw[lK!ufJ}UM/ÈqH"y$³FlNã³ü^:ªÔòFnt3ãý¹›€ pÊñˆõñX%q¦åˆê1–nÇÍÆŒóXŠ2>¬~—*:l~™VIr³1ÚùË}æþOýæÿæiœäøxäišâ4Ž˜Âf½v]ç1M“‘N1 › úN Û툳gÏàܹ³ùßöx‹ÈÚ^l·Æñ!*'Ä Ã°Ñï{‘1Ž[�‘㸠ès¸ÒªU«V­ZµjÕ h€V­ZµjÕê]µÚ¾¶ýæH ¾¯Ùí×µÏR x_³æß®¤ý&ëÿµcX³„<ø¿fý_ïoMѹ8obæPåÿ5nzù äå_ùlúÆÍà6E±ïŠêŸ<œ Àï�pØ\¢ªÐN¬+–ÿ¦òWÕþS–xÿ+™Ô–þ¸/Áÿ5Õ²üÏà@ÿ“²ŸMýì’Ý=›(º&D‹vlþg¿«ÓKœ98.ǯà7PÅ<ê†üèkžŒ?ñÝþÐHàÌ™3ø¥7¾7Ý|žóÜçáÒK/Ašõ³ŠHR;"†lF™w¬×uÝ(ŽÑlá‘'©«äÙ¬ªCµv™Ì&xS*Î'.‹k@¶4vIˆbM?s Ð\`æެêÿXˆ1iºXU�Μ j‚P!,8!— ™¡ÄöVÖÅu»AB Ü@bQÿ‘Fä¹fµ@€sªÞô^É<ï{ß=øî¿õOpóýüɯÿj|Ý+¿Ã�Á#›â/>‡ù§�ò:ØÛÎ\y®œWû~Òx oxºEb *©��.‚�ž Gš9=£é³bû¼æ6ûb9Ôê&�Ú½>5P��+m‰ºI�=ž®b9œ³}áDÁ¼(ê{nU 8³]Þó ®d2ÏÜÖ–=ÛLùϪâ•qO0 ��ûmß2ûú’eUÿ\ëkOêçZµj5¯K.¹ã4b{JÕǥÚuu6–ëþEW(y[<;Ë0ÏÈ#³ì¯û3Ù±9¨Ëß=ñ Ãê󽿬išþÈ›ù /~Ƴž÷†qÜNÇÇÇãññVøvìy1b·Øn·888Àæà ÆqÂÙ³gpæÌiœ=sçÎ�øÝ"2áëzg¥çq èúã|&wŽÔ{¯mG¤¨‘4wÆkÕªU«V­Zµj¥Õ­ZµjÕªÕ#¸à¿fû_«wkà}Måx>p½®50>½¾œ\I1Éú?�òû€ù´�å¾êß÷©8ësN€%°³´zµ:‘ˉè*× ¸åÏ~•ü™§ÞêžO΢VþüwSþ“×á �ð èàfSúv•mÿK¸��©þ�bù_;˜Í´…|™�SÐ�‹z?ƒÿIÍ_[þ³YþÛ¿¤Ê_üÂÉ =Yý× ~Äø‡¾NIåÏ`žÊ1HÚ�¨Ý¿° |•Œ0� ˆú»‘n½yƒÿ·ãë¿û}xðÌ. |âãÇù‰ÿŒ;ŸòÜy×]–•ËÅn˜#`0³8*—¥³{3©ñ|¹'€NPpØ™+…fñ’�ÿs•Rž˜&ì�ZÊrÅâØ‘CDš/@{¤t€»ùæÉ†ž#WÀ½N‹;”Éi½õ*KôJ!žï‚j–˜Õ:‰œ€=ä¢lq›ÎO$)Œz¡d�*KWßgÿä}xÍ?ú—øáÿÏÿ‰W}ý+ñ'¾ö•¸òškŒK@˜»Å×Vÿ^c+€J §¶ûzÔ`V÷b’{ïÒö¼Ä©Ú?¹Àüôü&I~\»Óµöj,Q³¡|„t D1—ªï)ƒ ”�pŽô±$}Ž£ {W‘ ’•1KŽ_Ø™ÝYùÛÚÔ˜b’jÿ<•«œ2VJ–.õ5’Ò¾H¢¢L¬�“Ým @lMÑw’“LÝWÕýFýŒ,·±ìƒ–¿·jÕj·ú~‹ öŒ�:À8#�¥æ"Yñ“<ÑG? è:¯ïá ,OÎRD:½;:ŸÆ¼JÖ 6¾dwÞÈ•³¸,SÓ;#¡-ŸëäP�­ÿcÌd@Ê@=rŸ^÷·�Ý6DÕø Ò+ ·céÊøÖï”’÷à�!ÐÆ¸º}ç®SB@×ùìxÀÖGÇ,I²œÎmÙ&¯Å¥0›“Aá#%l»¾;÷„Ûïø®÷½ûÝ?!¯—¤Ž·˜¨d-¯ñAK»ÿºß Ô¬À¬Š¯ÖÒ¨ƒBê°¦¸UĆ<ÆJßÒ–¨ ÎID”�ôïõ1MZ¯Ð õ·L¨AýÂrÔóZF-Õ„‹JšÖúN,ÆÈûûûÇ¥¹”ŽQùa=ï|æþïžÂô«aš¶Ó|˜¦¦�û×à‚‚¶Ž�·Ølô½º_@Ûí1Î�=‡£ã#ŒÛ-¶ÛÑb“”™ž#Øxº›Æ�H ýnÌÜaØ(1À{kW|—É6­ZµjÕªU«V­´Úè¨U«V­Zµz×Òniû¿´Ý¯AñTK0ÿ$€½ž˜<) M.Ö J þŸÏ†qÍY`­ÖÀ ˜'ùBÔÿ]àF¹ùÑ×ã)ßþUø³7]E7e~וŸ®Vý+Ô)8ÈÇ DCYdËÚÏJATÀÿ®"t•kæj{ÐÏ•b¾(ïÊÿlùo |ÜZ,@ÿÓÁ˜]&%ÿÏÔý¦Ü.'«åƒZª³Ùúkøn9Û'G€ÚQ“K¨¢·?fƒ÷nÅ7üÍßÅé3áýYŠ!àïxî¾ûn<óYÏÆ-·Ü²¸ïLEoŸ GÎâu¦Üw Tˆ\IÄ Ê%Ñ—¤º“O@ª²³û�¨dÃ&ËäZ Vö¿ŒÃ�l{êÅecr˜ý¬­‰i.ήŸ�´l~}ö,I¥â7ðcænP=sv¼ÌQómhyyö=Öc"€ØC’-2 NŸ>‹ù¿ÿ;üëócøãü�á^õ5¸å–G/ ÊÏË8=Ek0bnNs¥)=�b ±:¶iu‹Ðaý0b¹_Šò_Áx‚œÝãœöÁ`8�8@<,(A�HLަ®wÉ9ÁnÞ«AI4‡�(Ê?WíNýáÆò!×ÅU.óˆ2&î‘:.HI#¨¬ˆ¹ÚþN4C¹n‘‰cŒ[m ™‹eAÝÇ­‘È.„° ÈÅÐ,·ÕªU«õ 1Bbê÷åÄq¬³q’ÏÊxÈ»ÎXî0ï¼’¼‡s�:8BdëCð1ØX•f¢n眪�û¾€ïiì*öž;t×½þ\u_�yõšü'±{î›Ý,žLÍÜõÝlì^�£90q!Í¡!„*+ÞýJ¨ÓãéÌM¡³ãÓa#cÊdà97†0‹5HîC‚¯È½ùü»N�zsGÈ‘ÌÌGŽîøºnüħï»ï¯æþOÿ+Ò £Y;¿ ¤ ÿe»šMalQ[õ÷ÊÊy©Æ?³(¤üiVí9Öº¡ÅwrF~ÌÞ‰I�·‘~g¶1RîÇæê{YôO™@9³ïŸ/» æ/û¥ IW�…ÁÏŠ·ÿÁ6ÆxçoþÚ›¿âλžöŸˆ¨sÞ�ž�Þ�î?.÷^˜&týˆ®ë,rJ0Ž#Æi´û’ Q–ª>ÚÜ9B¥ö_û.; ˜»¥±Ù è‡!Gø´jÕªU«V­Zµ²!~»­ZµjÕªÕ#·jå�Ó™øÚn?M–ÈŠÒ©þ{MÝ¿´D> YS/sUëe÷mgI(X6kû\‚þû"ìçÀUnðØ/~^úÊÉ«.:pªøOª}¸p�f™S ××Éþ6‡™>:¸ÙŸ ™&*]Ó{ûÀÿ|æ–ÿEuŸxÖm9Ö…À£)ë' À¥÷ÓµM¿Ö6þÉI€ «~qœô’êŸQìÿógŠ$Hhå€`j)©,ÔwÞ¶Á¿ÿþÇàÿÖ½xè¿ zè4Þðú×ãºë¯Ã3Ÿù,\rÙev�˜W•|º—�'ëÓÏ h.°d gª¢¨”êû—°|/–e™«M04༅j̳“O–ÅeÛIYNy4˶'æ«ãÕLZÖíe΢€ÿ’ñÝü�|Ì»F™ò ð¿ú¬«›l§û­£öuºì8NÍ—¥šâ°ºÙ5•ïéï3§|udþ™aèÏ‘ïº.¤{%Ä`® Øù~˜î¡ìÐÑuè,n"ø]§÷·ïæß{k‡·B¦!{^\Þf×i܆ó- U«V­ZµjÕª®FhÕªU«V­ÁUOʘíµú¿žðKëÈ#õ_=±òpl×— |=©¸¦Æ_Ë3­kŸòÍ¢¹ÞÞÚïõf8ç\."7t�ùS/“?ýœ;è =zÊvÝä2ðô Ëÿ¤ÚïŸH^cp °ï+E‘3·ÿD²å?uÅÿ=Û†VvûΔÿ3Õ¿í0¾Dˆ$ËÿYõŸÀ³d•ÐKÛ”ìºm =g‹ñB0' øß*¹ gO{Í:µurŒ€ÙýƒíX«Ø�D>Ð@zÜyë€÷÷nÆ7ýí�⡳ñ¿ÁS¥÷˧î»?ó3?�Ç=îñxêÓîÂ0là’R>gÐ&ûY™©ð!À;¯ÒFªDÑ{îÓ4¡©÷~ÞfEùüY"3f ÅDVK_Çn¦b̙Ŧ.Ìì³ðb×[«òè_Àõ Ò1+ÜìÀåX±Ôáe"ƒE„g’@ÖÙ;gˆ‘ŒðPÍ “#HTÝ(‚ŸûùŸÃÏ¿îçñä'?ßú§þ^øÜçbØtÕ3T=W‰Ô´p(Hj?Îd#Àe"‹’m8GV¤çÌÜ6x‚Ä ê„·•¬Öàr^Ÿ1òù³MA,Ü åA¤ç¶ëÌ„@­$’ÆQP¢%ô¶‰:Ù­íqóórRŸÿìÃYyªk$˜[øW‡ÒÄ¢ÜSúÈQ pŽ·ÝÙã眑#a ôßG*Ûô×®5k¯_h-Iq­Zµš×Ù3g¬í/ä5"À;R :zľC ¨€ÿ€a0 ÔwÞí¸S©º¿¸\M•˜œ‚ó]×!Úò]§Ä€®ëÐõ=zsXŽ7½÷�^À<` Ó8bì:LÓ”ÕòbQ*9>qÖÌ Þ‘ƒwFbØ 80«s"Bä .3Dðc „h†®ëM½Ì;ãôº/N}³wNÓä(�ˆbP狇Ýè­J‰^¿îÌiGªý/IÆdÇ;#$èO"âˆÈÝqçÓþáo¿ý-/Š‘Ÿ Ë€�sT‡Å$¢@J  B Lý‰Ð>hšÖ†q‹wKüPé+hÖm•!ñâûE'Ie¨SŽ/Å è�!}“&_�ï3²>Ùéƒ×lý g@òaßwµµ—e¹2¢EE`Ùï°¼Ô‰€‘†ì|ë;ßþÖ¯yöó^ôÚ®ëGaæÈQBˆRÇ¿e@ß»ç!½‡íšÂŽê•\3†aƒÁbBÒx9„8{Žk»wJ¨éû¾Ùÿ·jÕªU«V­Z­T!µjÕªU«V�àªAú†$Åük¥O]k ÿ¹�ªAÌôß™l¬–¿�ó:ŸBs Vi­8Ñ•"r5Ýp˵ô¤o¹üÅG]ç« œ+à¾ëgÀ¶éïêËûHQ^_— §AýÕEõoÿÔò©úOû[QýguSÔ|õúŸ˜ýþ ¬7ˉfñ_ƒÿ¦þ§â¥šÁáòºÔ }T ½Ìã$ø5^€ƒDÄa®Àf;^ y{’ÏE2q¡8 pŽxêã;¼öï\�où¾Oâô¹ÿvÀ›0ãîþ.>ú‘ãŽ;žŒ'Ýq‡N„'»WYצÄsŽÈùõÙþ—²ÐYPO¸sŽ�Xsá�Þ/ÑÀm LÒgRMRRqÉu§`Ñ”ŠÂ„н/ˆìuÉŠ¸ýÖçJÐßˤwä‚@OÞ¶-)7‚ví�å3«çÀÕsí)à�”Ã[ȪüO÷¦º8˳s ¼ó�ïÄ_}õwâŠ+®À7~ã7âå/{)®»îj»Ölç�HJH‘DL±{\8€Èœ5„Á<Á!êßëMâ,‚máÒâ'@Ô¨A„3aÿŠäѸœùNöy¦{ ªTåŶÒë˜,‚O?xð±ãý>ଈLk$³}n/k€úµB²Ù¸êþç$ç™V­Zí¯sGG¦N§b—o–øÈ,ì-³;¨]¿ó¾ÿ ½_ÿú¬ë87`œ&Lãˆ"Bˆêà ç<ú¾ÄSu�‚äk®Yi<¼ŒœêcÄè=œ9 Ô„ÚŒžJ?Nç‚©�‡› Ob3l2 Æ¢z&‹ ª�£ë; <'8ç�d‡%¢×Ó{�®÷è;R+ð?Ĉ&„fd)%$έ÷ç`¾Ì\œóÙ© ¸éZ¤ãdfaæHD#Q? ^qÕÕßû™Oêÿ‚è¼"Õrñ}㨢Ÿ„í1ÿWˆ‡ V»¹¯ët©dæ=P©ÿNRŽMxÝÙlæ£/¨Ö/ˤ~•g(;± ÛA-¬ûëȢ䶴$ ÔüÌ¥3°€Q ¬º $Ÿ¨ÜÖ4çù壼žÜ¹sçþr˜ÆÿëÔE�"ÂÌ4!"JÇ‘ô__aÂv»ÅñfÀññãv‹È1j»¾Ç0ôú΀÷Ój¼�#§n¶/"B ±5έZµjÕªU«VU5@«V­Zµjõ¯~œü/mÿ—“�5ø¿œÝ·ÏZES«1÷ÿkÛXn«>ƵªÏe_,Á>;h"ÚÑDt€G?ÿ)øÂ¯ÿ"|ó%§üEjåŸ,ÿ“òßùÞÀù¤ü¯ÀÿL°õ,@ á:äœqÖÉÓ¢4ºË›àUËÿ$O*}SÛgp½ÿ“ú˜ÕŽ\Ê œ¯òIó dÿ+‹þÖ‹P?»0O¦æ�x¬Ûç´~¥BvqåT�~ÖcÍJì8{O�SVCœ ÂxÚmÿúï\ƒ?õ÷îÿoJ€qñŽw¼¼ûƒxÆ3Ÿ‰Ç=îqvauV´¶½Q€“\Ñ ÍU|”A|1@WXÀ5è^gËŠ ¦LÚ ‡¨vœ¬j3¯ƒïíyp ’2/ëv¹IåX½R€á¼‘ª}²[!(BŸ¯ƒ˜Â¿NÇ�‘‚P‘Rà(ªî׋·tIkX“‚4�*vnŸýìøÁüAü¯ÿìÅ‹_ô|ó7=žùô;«gGf÷\v×H*ŽvÿN€Lˆb¤V»· ˆŒÙ@ é³Ïz~À„�>‚ÞAX D^A$gÄ 2�ß1˜çìÃfÛ®Yû×ùâfU¾ÉÀ� –$Âô|í¾ïk«×”�(Xž‡†çvÌ€’F ;1ËÚT˜+Iª÷~âª_ðiˆÈ ûb^Î×׬õ'kàÿ¸$¤>eé<ЪU«y©þ¦Ã`*~J$SéU% Töòª îÐy—�uÒó—Æ´ÛíˆqÜb»ÝbÇl­Ÿòä�¤š·ˆò;Ïrm=^· Î%’€/*âÎcÜn󳣯¼ˆp&ãÄ€:t]�M¿Áæ`“Ía §±œOê%*u´ºÈN{T“¯Ä\p\²ý7rb­ü!¨sAF¶�„ÏŽ¿Eû›^u5PPÚª“z Z}WŠj³,K Fš~ë#�~³søÔà\"${ê¼»PðÙÖqµøZ_˜ú¸ô{:ŽV­Z­×8�è-ïžío¼ÈÉyf؈Êó¤n]&Ìé¸ÏTÕ"#L#Ž�·8>:‡£ã-ÆíXø¾3«o"µO}F§NÞ5ZGc))Ë"Ò8ÛwEñ.K4ÀQ2™Ï‹ººß�e²þÐ;?‹ÖbfÄ�HºqF �¹x·K\ˆ…è`nD©Ï6 š™1…€0M˜¦€âlŒœÎUD ÎÁC÷_Úºˆ8zçñaÞ{spàÙØ|A9Æí-�~ÜÿrÏï¾ÿKEøqõ0WHvÆD‚=Ñ^" Ì^­ç)üTzYöA4ɳ'@ÿ3ÃëIvªã)f9’ÇS"uDN—¥ø©ŽNêÍRé›d ¯Ä,ՄϽ´$̶kÿŸ9?Èâ U&dn;™R'äù¬õòçÎ�ýKaÿïK/»,BG>‘…™,F+E]hÄG!ÍLaB×õðÖG÷}Ÿ¿W& ¿ï{ ›M&£„‹{Ý8Îc€ˆ²Ë@z–c ­qnÕªU«V­ZµªªZµjÕªU«Gp¥ Ú°˜ˆ[=æÀ�ËJŠºjÀc Po¿ÞçÒ‚q­Ö2™Wí6Çñpˆ¶½ÀÀ!€+ˆèúë®Àÿü+ä¯>ú÷DJ¶þYÁ¯À?ЩíRþSEpæõNfû/ø.¿O¤ª ÷Ã÷W¢µÿ»"� ‹¥òy1s5|¶ýŸ©ô§üº`¢YÿÃÔøù}³Û§*O>Ϥ²!o•êg_C�]& šÕ¹%H4»~Ìñd¤™H€ZùçQ"�|ì±buD¸óñþÃ÷_�oþ¾Ïà�yç~ùoQ÷úÓø/?ñŸñ¸Ç=ÏyîópêÔ!¤ºG9ªâ=2›’Îxy’ž�ˆA˜«ÀÈlÐ9?Wœ3Ò‹*Ù)°àb“öÙÆ?áÐöq3³Yè«rŸ4\åÇ2/&¬ËÌõì¹ã:>¥}Qå¡7+ã êõÊš7²,,“Ëm¸ûÙU3ã)'×Ù¤´ÌívË}¬wŸª»’¾v8(‹»ï¾ïû_ƒúƒÿ¾æk^Ž?ùÊ/Çõ×]©â-ôYJ÷]4‚›Úßž-™Pˆ8éÙ²¶A=„õifXt€\˜ôY± 1’‘ÏI ëDA Ù…£Ê# >Íò{}!EP±óO×’°ˆn�«ÐùG±Zs á‚Jö¼`. ä}÷]ù3›Íæpš™�Ä}Êÿ‡+³$Á¥þmÍg­Ï{¸ûmÕê¿×â(_yÓ8g}ƒÚ¡'û{ç•8™”û" Žð×ç/"šÿ4MØáÜÑ1ŽŽŽLM¯6õ=˜ÙÂȱ€I*>ª"ØÍÝ>:¯vÿÞÇ9Xo@}oOc@œÔ)†M5ï�÷Úx§¶üÝЫRßló�ŽŽ°Ýcš&„u¼PÅ›p²<÷�‚®· tg‹È ÐÌU%pDŒÓ8bš&LÓ„tœé»n6¦wÎ��¸‡¥"Xyïà¦I[{ß9uý©‰Æl×¥joYDBä¸%ç:¼èâ¿{öôé£Ì6_Ì€ó¬Ð/=­t3õ>~ÝQWQæ®w :((6þK/‚¼PõWq1H€|5 ©\Šö÷�º[‹¨{Šš€yÙÝŒ?P?'ûQu-dÞ§§sœ‘âfýY÷Ÿÿv4³�� ã¾ùM¿ò†W½â�}í¿0‰ÈÈæµK>÷…X’É6 rèº0sÆèúsÈŽs¯}í�áßþÛÇ Ÿ÷ |íûR¼àO†ƒ²B>VÑÑ€™:~#]_˜²Î¾³çˆà(9 €Ÿs‹ Âæ àÒ½�,œY?;—òƒ#‹„’Zž$ýbŸ‡¹Š8I§Ï±’ q³ËàLå:ûÜ¡÷X²€ÖtZ,±^î| äö|ÁP= fÈG?wÅ{_÷î;þ�Ï]öÎa û<à(5&Ë>à÷CHyÀVûÅe-û¡FhÕê%‘V“J½<_˜,U_hêø0…ˆíöÛcµÿO arŒŽÕ1FXà»h„ƒ¢ð1bGl·[úý¬ (¤ØÎk;ƒêã8bÜn1N#¶ã¨Ç#X8s­“ï1MJXHãòíÁ1œóa¹£#aLÛ`Îý¤³Èƒ:·ÜqB„³S@±êW¢À4"/ #Æ)ƒÿ!ŒAÝ(`$€º­Ë`~ŒÑÆT;Ñ…4ƒ©Ó4©Ë@˜2‘0}ö"̼�1º+¯ºæ—�Ï�û‰Èñ�f2Ÿ©óIj×~šu«-,•1Ù8"�=‹éOWlêëÈ$Rs� þS¥ ·¾¥ÿ-ã#‚«Hi/jÜ´ø®R�­ rq��\@y¨HE±o_Zˆv¯YÞ$-ÇZÉ]aw¬Lk ƒ=>6ÐI9€Ó§Oÿù‡zèÇ/¹äÒ㣠! ÚwDïºnB7u˜º>ß[ê$7Íâ0Ò”tŠ H$�µï”éu"Bß÷888Ä©S‡†ô™ U«V­ZµjÕª®FhÕªU«V­Áµø°×ê ”?_-�öå0»êý“€þe¾i]çSþŸ@( —¸šˆn ¢›ÿä—Ê×}ñ]ôU}×ù¢ú÷¦ø÷š3îzCT;ÌÁ_¹ÈF]ÿÕIÀÈé=2~è¯DV× RÿÓ §ÚŽsRËëE†àEeœlú'=ïlùŸÔÿSQÖ“M*Sq(ÁðuÞy,Š6Xm÷Á…� ¡(ŸMõ1ÊŒi¬æ“ê_Œ °´ü7òÛ¶9ª¥z>¶üaëµrd“¾„ÇÝìñcÿÓ5ø¦¿ý|ôSaÇÎ÷³ò}-‚Þõîwáx?nÒ“ð¸Ç=^'{YÀAðàÈ ØºzR{æÑŠlÅZ�ç, ަÆsçNlòÞ%°Ýg`˜[ÃÂb²ÒNêíŠY+¸Ÿ&–‹ˆ1E°9ð¬- ȹlã›&ÅÅälRe Ïï}ËþMê6)™¾Y XMÀ§‹L¨s€“2gàu¹K%{•ëno±~éMoÁßô›¸þÚ«ðµ¯ü2üñ¯~®ºì"� »wÙÛ9ÀD±l“̲:G{ˆ>/DúL«2ÑÀn»bNIk¤0A4C+Ô¼ƒóuP+ébv^ðz $“QjR† Þç§káí¢�=¼O7#-Üöô°&n¯+~¸¢EDnï{ðâ÷þú=OøOþì-ïvÎÝwp@÷ÑÎØÌ÷×Zô˾gtÙ_,]ojÜIýâ’èv¡n7­Zý÷\é9bL1@L�Ï‘1â <[U[¢©ÙË8·¨ÍCTå}nþöþ<Þ¶¬ªÅ¿cιö>÷Þꨢú(úFzQÁE±�ØáóÙ%6‰`›Ÿ?“˜Ä$vùŨÁD›hT°‰&&O‰y/ÆD%ˆˆQ:E¥( @ úºuÏÙkÍ9ÆûcŒÙ¬µ×9÷BüÅ«ÌQŸSwŸ}öêךsîù협Êï>%#:Õý™œƒ+*o„º ÓŒä¬�È û4�Øí”0ŨVâ¹�kˆiDJ08::Än7âhw„ƒƒxï1MŽqxtdë™�`ÞyË90„ÞÈJÕaHI%º€<œ¯ÝFŠSœìüŠ*«ýþØ»KëùÖþ>ùÚßçs“ô|LFˆP"@¥`Ä f扙‰…ý%—_þ�ï»çî�‘ËKŸ�#sh1>€,„æ9Ÿ¾éñ2!2Xö€oÙë¶Úq ³±†4÷B³KÆTÓ1ËŠŠ>;7‰„ö¾›þÒ: ÙU½~yæî‹#™�Z'å1C~©ËÊž»Â2` ÿ¯„RiÖ4ß}ÚûÞ˜nøõÿþ+_ð©ŸþYÿz·ÛùqÜQŒQZ;ÿ¬èùÞuÎRÒMšßSÁï�ÿ)%sç0b�ý=„€íö§OŸÂé3g0„Ááá†ÍØç^½zõêÕ«W¯¦: W¯^½zõºˆk þgsܪ›þ,ëÏ i'ÓZ7�µ8ƒµeógˆh€‚ÿW¸áòKè‘/xž|õcâŸDÈ"¿gïïœÓ×hìý‹ò¿ù¨!8Pù,Q 4ë Ý„++€]âQ—¯3Ðnªãlc. hÎÌg»ý¬À‡)çS¬ŸÍ {v h§ê$;ÈÊúk¬gâ�p%HZ(ÿí3„…ϪN¯ê~ÔcT`?õ¿äž€˜�$r„æ�SUþ;oêh�Y€·\»Å¿û®kñ…ßò>¼íöé;  ­qñº×¾oüã7â�|$®¿áF ‰Z³fìª�û,oŒ ÀŒÆyx «6LH¯iVjeµÙ«›»ƒ³s‘½Ý²’Ÿ›¼áœïë  n›í³æD`Ê=‹V5@}nõßjSÜh�æ<ÒRMV³z ðŸÓ šûŒÀrÞ_ﮟ”9'¯[¤’ ÞóÞ;ð?ô3ø¡ûwøÄg¾àùŸŒ§=åÑ"h`›í¿¹r‰L™Ì#5âB(ßï¼+Ï/•¿çgnN ™ê_ã”sHrâC&Gç{‚X¦®R 4„(‚°ÓvDšçß‘’53`,ï;„á\›´lº%N�úç#Yíf8ÿ¯Z(¿ÿþKÿøµï|è¿{ã{ñ*"ºsè"ºÀ¡sîÀø�ßø�ò¢½èvùXöKKð¿U .×Û¾^ºÚôêÕëÂ++zAœœõ'Y™ž ¹¬m™•¤fó¸Ã4�ša_TïÚǪ$Fðª>oÔÝ)F�m±ö«a]rpdãâ& $?çUY_2à=M#¦qBLqæ„£kw`û>Mær0awtr„Žqtt¤qB²ãr¤–åÃf@Ó¸Á`VçÙM!÷ÍíØ˜ÈÁ{ýqÎaJ\Ò`núbõ?;þfìM¸q¬d#03¦qÄ8MDZD äsÙœ—‘€?uú’wž=û¢q¿mž3/È~ýB˜�W3/T?S††ÅqÈÍH}J.<¿]½³e2a1[ë/¡ì¥=>‹�Ü(�5²A«5?ò­ª÷ØÞj?˜×Ûp#1ƒÿ uCÍø(ÿQòx§¸¸²²Ùiž ’êø¨%,¿WÍßDQ€Ù¸í¸QÁÙûïûëïß{zØlÎíRŠ©u®È.µ?®NRưú-ÒŽ›=«y¬Zûö€Ívƒƒí§ÏœÁ©ƒSðÁ«kEJBŸâîÕ«W¯^½zõj«�ŽzõêÕ«W¯‹¸–6ýË,ã% ­%ÈÑN‚®�'íûkÀÿ…Z"·“¦Ç©ÿ[ð­V@›­ý\–-ÿŸü|ø_ýTùÚ«.óWÈÐ`ØPÔþ.+ü…êûâmä ( ?ªí?‘‘à�(Àò´Ïÿk@9pµãçü·& €ú@¦±Zös¬€~Ž@þ7ö¡jÞ®ßÒhÛP`Ÿ96`}ìcqPKrÛ—™¥)ôÜÀÜʾØqåuI‚ð¤ÀhLH<™åÞoÒ<ó,]ö–œ•b™À‚k¯ ø…z ¾ô¾oxëø¿•°V‡‡‡xÝk_‹·¼ùÍxÄ#‰ë®½Áìp¥�2²b]X×}Sàë/ Üs£Æ"4ê¾&kVrL@«tjŸAŽb¥ÏÈDËN¶ Ú’…Ðç ÕÙ¿°¨ó@N˜­±ù™T+`#~à_³ y™MÎ×Iå NKûŒ7ùeR{Öt4' ­#IÁ°Kž2+ÓyeùZinpœ&ü—_}9þË{9öЛð¹Ÿõ|ö§4.=lr^ʽ©�vVÊ%jdÏlês’IfŸA–²¯¬n!ÂÖe1!l$$!$IððåxTì'åSnO²uH=ÞìFBÍ9³cââüaàˆkô–ùš°,a…e æL¶�lÞ_¢@ÁŸÞs韼ú¶‡þÒßsóïxïßE$*"wxà›¿ù›÷äy©äƒc�Ävœ{L©Ö¤É²^‹´Y:Úd‹ñÖv;«‚{õêµ^Ó8¤}B°SRküh6öùv΀içgÏ]¶ÝÏ.€ª|‡aP…~ 8ñ¥ÿ“™ÛKÿ `LMÿ% [xëGós�Ì@] Ô?ńĺïÎöÛ;Sè³ ™C�Xü 'Uâ�6Ï„€˜”DPúaÄ©M&($Ÿ@¬‹¸Ù¸f>Ï„Yç]9ÞY¬€#%”h�¡\§cÑׯ乭‹)�¦©bÄ4MÅ©�ˆÔV_f1Arёۉ“áªk¯ÿ™÷½û]ŸÃà' <ÍÛô=­(õ©'´QAÕA`õÃbmó÷f‡K é G5C±¾1ƒøÙ‡ˆó`¶¾ d¯»¬I�)j�qaS0�qš}«öæüCÍŸ\sÏÌFHk.ÿÍ©‘c΢Ô|ûýä(f¾ñU¯ü_ðŒ�ú؉qØ2€œs‚†è]ï=Y%îùкvÌ#13dØ”>}¶Û-¶Ûl7[l6ˆ8ñ±c†^½zõêÕ«W¯åê€^½zõêÕë"®¨hUþÇZ°£]G¶ölß[ng¹Í%H²FXþN3%­*0×,ÿ×lš›Ú¸œˆ®$¢«‰è†ÏþXúôOûHú‚íà‡jÏï ü÷¦úÏŠü  ,ÃÛ”ÿx6Õ?à ü7à ¡€<àÉ\œîƒs—Ú®¦ªüÜÊyO&Ö7`¾d�'€§ ºscù/fùoªz)„�QÄÜòŸeêgðßÖÏ9  ¸ ˆ 2°ØÄ ïo“¯ŽXÁÞþÇNJŽH#£ªþSª!98Ÿ¥Unüog{ÍrüA—xüÜ?¾_ñ�ïÇï¼a÷çJPe<á�Îâu¯} Þñ ·ã±�}<®¹öÚ&¿ÕrŠ�”AŽ@\Õð V¸äs΄W½·Ù £äÞÏ\@Ъ�=¼wÍ3fäšl#ÌÉ,mÉò{Õ  ‚¤ji›�Û¼�©I—O‘ ß–B0H©æÞ£¨ÔU%‡œœ•ý-‘)+ò›Ü6J  :XÂÐh,„i"ƒA²lÏÊÆM宯ßö¶wâ{¿ï'ñ?øoñIÏy:žÿW>Oyâ­õÙj•y” ô^ŽJÚ‘Jž�Drô…>»"y�( À#DFv> žÎ²0‚XÛ‘è�ìaÇéÀ`ès•ÛgQbî%`¶k¢î#Ö&pÓ9“"’ ˜Óu1NœBgg�LtÁ�gO¿ûo~Ø/ýÑí7¼ÀŸ:7¾ÀûÜùíßþí·ºÝn7ëãÎ×'¬õKKwœ¬€ÍýáÒufIv[ºÑô€^½N®sçÎY+¬me…=!ƒ{Ã0À;o€;€I lÌ(àsVô{ïAÎaÎ[+c®3<³Bw“BU³ ž.�±rßµt¤©}+AÍ�<•LòͰÑý©[NR’xçág g* =‘Cð)÷ä›aƒ0hÀ|<ßìkŽñIé3#8d‡³ÈÏŽ8C°Ùl°1P4Ÿ«"‚]ƒ”’^7(yÀ5öìzíZ2Tùœ�çe;í½¢c7Ñá™K/ýÇgï»÷çrXÊWÇT¹¯W¡ö·Ds€)ô²¢þ¯D½ ð·öÿUE_?£×ŸgîB²·¯Tîqrfå”ã‚Öûl#о¿Ç©›/Sݨ±ý×gDJ#-ÌÉ"ÍÎ7ËÑ9@Ú�-€1D6þ‘œÎ�;÷Õwß}×Ïž9sftΉw>úxÉŠýy¼\CfµgÀ7ê~ßÄdâŠ÷~ö ÃàÄuØÐ¨‘Óq¾W¯^½zõêÕëC½: W¯^½zõºÈkÍö¿9–ÉqªÈ“~_þm�ÐîOûïò½µ×Ëuç¿·ŒÇ|θÀun¼ä´{ØW=�¾ìÉ·º§“7pÞ &GÍ Vý;]\Bù‹í¿�ý92À)˜OÙÞö¹¬þÏà0ðßiЩfâNÁ6ÿ� öW 5«ù!jõ/0@/e‹þ U‘¯€£Ì¬þS³­F…/­ª?U5²Làboëû­jl–ÿª¯Žå"gSõ& ¯C3Ñ%» ð™&�HFL� øSUù»ð&®¬gN;¼ø[Œ¯ÿž»ð«¿søçL ¢.¾çž{ðÊW¾×^{÷øÇãòË/¯€º)ìÕH¡Â×€4“ý"Õ6«ñ3hÍÌæK™¨Îyï X<;œÌ©�T^Á΢ ¶è�æ\çω€…@Ä%ûXz.Â’…ö�j ùnå1PTvåQ&²¥YïR5‡òû‚p„ýà‰aN4Ÿ�§B²¸‘Çå5᥿ü›xé/ÿ&öÐkñ¼O}&>ïy…+.;S¨‹‚ㆤˆ*÷‘ˆ€DpJ&8´D%Q¸ñ‘ÔÂ?íÀfýÏñÈžÙQ­ú•�n,’Ù”¢9{0’8À%8v%Ày$%ž”¨1RÀp” ä/ºÌ,§ù„²s­Ô Áiúí·\ÿÒÿö·þßÌøSàì=ι»Ü àÞ½èEœ´º³gÏÎú¸µ¾d­ÿZë›ÖT®-ПÉ4Ç:ðׅ߫ÕÙÎÂüUе|b."GafçO¦ìߨ86"¦ˆ£#7SD;§ŸÛnl¶Fä¤TŸÓܦ;r+cc%­Edw‚Ä )ÍA”R‰PGÀ{‡Íö%¸ D„K.y‹7ÎY¡<Žc! ä6¥% T/¡J��‡Rbˆ9ä¾ß9*ŠÿÖߑǰppp ÛíÁ2ÑRŠ…˜!¤ìsP¿£g"ÕŒ МSÉÑ :çv7Ýò�ß{Ë›þø?Åqz^ásÎä¹:¿¼»™3TD¾˜Q-cšþ_!©ÇÓ¬³ušõu�»D‰o¢–ŠØlˆ͓±šýžG�@~ Ö)I€E´�4P•nPÇ/Ë®j檴p ø€Æ¸yH—Ýš×+ßoø£7¼þ‹>ü#žù£ÞÙl6ú³ÝJXXúO H_" Ü‚¸cQ"R^§ë54Ò‹ ÆIRÂ4j¤È8N½qîÕ«W¯^½zõjªzõêÕ«W¯‹¼– ~Ý‚ÿKÛþ 0޳O^#œîGX[ïÚç—Çaå<ÀõDô�GÜìžöÂçÉ ®½Ò_K0ž‚*W³@�¨ªù Èß‚úÅÊß›ò•@eùsÙA@·C.¿é€€–CµüWé¶F¶äo�ú BÒÀìñe´ÏM�K€E Ûù·ž¶УÍoÀdð¬àjÔÊ�ý¿ •܇啣‡” Ö!Ð*ÿ' î€!<�c,Ä]—7å?Xé윺“îP% °Nôn7?øÍÆßý—wã~íìŸ;  ½Çßÿþ÷áe¿ñ>\à xÌc‹Ó§Ï˜}õášx –¢êË“�ziU¥ŸÕûœs~S2Û})Ô:c^'¹sÞ}3%ç›—àÙ žr³oE±îÙ^®ú5+� €_Ôvù¶hÔü@VkÊÂæVZwþ²-̬�ggzþºöIö'¶©öÏ&ùÛ[¤u$Ø'Þú¶÷àû~è?â_ýØKñQñ8|Ñç= õ´‡k23“’\Øž_I@uÇ@e÷$8©1Ì #œDïÀéNF¤¸Sõ2ç »o\PBŒ0¤Oê¶!³VŽÀ”‰Ž�œyçà¨9¿ö“Œ@¼9†Äøæ~¶ëä ëI Àp÷›{~öÿ‘·½ï²WÞà9°#"µ48O�;wnosR_r\ßuÜs¹ìÛŸµ~³ƒÿ½z]XÅ)¢0¦TEÏ…ÜæÁ‡[õ¸Õ®Þ‡bñïCÀö`‹ƒS§°ÝÀy§ º7â™4Q2m$T‰N9O<„™CVî»bL¥?*Á.qÂ4YÎ}rüpp°ÁÁö§Na3l« €‘”@7w×Úbß �ËyÙoÓµÖýF µ›�)ašF¤hc4gñAF ç@ xç†Û­º-_®GÎbçÍŽX†BÚhÛÒ嘞HÁýüêx?»idàœKÞùɇptà 7}ïíï¼í¹,r ¥ÇYoÏ©¸aÏ»^Ú¿Ï:mY J˜Mo˜Ú¿ÆBý?°kR—W¢ª«Pv@›¨³O:“†x°ytÒØ¶ý´ÌG<íØIš(£²Ÿ9¶gv¬Í V.ŽÿH3‚BK¹¬ÁU²LP‡€wG/833xdìXŸÅ#ÆiBœ"¦iì�s¯^½zõêÕ«WS�ЫW¯^½z]ĵfk¼¦ú?ˆqœ‚ríõIêÿå>-׿¾·­]ê‚,°p À×Ñ-Ÿñ,úôç}4}ÑéípUìS0Ëÿ��Ä:1ªà¿ýPCÈD &Ç1ò@±üÏŽ¡~ÎÈg'€Í" À¦ëLõŸ¶Í$ ´¿/ÀQµ|~OÕù¬À;à[,ÿ3�gÛã¥ê?» ˜�R€žÙbd4—�LÐ%Gd^šˆ�ÖÕ 8˜ê¿!HŠï€iBâiaùOeÒznùO˜¬æóÅ´ ØLíå=ðÝ_ÿ \}¥ÃýÂ}®$€µzÏ»ß�÷¼û=¸ùæ›ñˆG>a³�$� A¢¬<Ò¯e>4—·µéÏÖ·9W^X•nY”Æl€„°)ðõÑXœä’}Û’Ú6¤\÷¥`Ȩ Q¶ÖÍsß-¹ g.7íH±æmû% àÂÚÄö8€=À|òšš´ Á\�¸oÝË9¾ƒÄ‚Ýñ²—¿/{ùëqÍ5Wà¯|ò“ñåɸöê3€ì )»\d²�î�£ìx H"ê>€Âð8éówˆ<‚x´ö€ATÛŠO)‘ŽY FÙM€S%D‰@^qåY+G+Éšó ñF„«áJ0YÊ õ÷{�†sßûÒ[_rßáöõDã[Eäîyñ‹_ü=Œã8îõ+ÇåUg0¯­¥åoNê×*¡¥¾îÖÁ½z]x CP’‘äþ#•¾DǬÁë¸5À=l†bí?ì6ØlŒc°)1¦¨®/™PÐîϼ½I{䣔cœî÷ Ãa0¸fÆ4E8G˜ÜdŽª˜Öï®ä¥{t9[GÂéyQ÷…Áê¥D eDÛ(ß5Üâ;‡”ˆ!Ö¾ºOÞÇ!ìn~ÈCßqÇûßûGGG_]bw¤ ªÿ�ÿ2#蘯ü}-×~±®çù1?+"#9"J­ú?5*}�‘JåùæÆ%Cûâ0s˜Çþèó“×1ަi´õtŸ^½zõêÕ«W¯eu@¯^½zõêuW«`ZÚtæj'F²%iþ}9i·¬5+åãÔÿ¹ÖTû'�þË:Ž<`ÛÚBUÿW¸:x<äk>_þôǸ�õ˜wý!W\¶–¨�ÿÌò?«ýÍÊ?G0<|y/è²y½@.ÇlQÈÅÀ\œ‡ËÛK#PTD­ê߀sI¨àÿTÁŽ&Ö[ð6h€:p¦üØ:ís-‰@XF[÷¤¶ây[Å!€Mlàžd,–ÿ9 žEQÿÙö9ƒÿcþ·ª|κ'À{ÿ�”ÿ™Ð>ùDäUþÖ_Žëìñ­?r·©Ð.¦¼ó�ïÀí·¿ 7Ýt3ú°[‚o~SrQcµÚXñWå~�ìp±Xf6‹åb—î ôOsE•¨:¯(mcYõ•-úóÔ¶f,«Òe»¦Ò_ZÚÚ¥’¥;.*I²hwfJ>ÁñFµ‹ö$G`%@¤ºÏè4[žœ3²‹´78Ú¹öò¾íwÅ"ï{ßÝø±ŸúuüøO¿ ö¸ñYŸòh|æ³o…óI�$–GŸà\P= ¶˜�DsËH;#äÄ9I¨QïQ«Ü›MµÁÆå6<»K0 dÏô,òWµŒ©�ì׋ åMy8¿Àò'Ë‹¡WáÞÂ}÷<°yÀw8çîxñ‹_|÷õ´4÷È2@¬¾î ó^?¸F �ó( [p!ogm=½zõZ¯K.¹äkŽºZëGHRÁ‡€å=† @´s„£a@ JË pްÝnqúÔ)œ9sÛƒpLÓNû¢€m¯Œ`�E—š�~  Ç`ž)Eì¦ »Ã##Ô18Ô1ñ2b@³Ç·p¦ O‰¦Ó4b𬭠JvÐct³±yJiO¥œš¶Î{‡° ØïÕÆÜ�2€ œ÷ð^A4~ x�[!À§$ðlœíœÓÏûòªŠ�Ó„cùiÛØU0 ¼óÅ (¥„‰òðSou0x††aç½§‡?âQ?ôGoøƒ/ð•°¾”dÿ»ÂÜÎ_Ž -–ºCÍÊw‹L0Ð8 9é°Ý*•¼ûLh¶Û:N$žRÒ+`ïØdn�4]�‘@³^YëW×ö e\×n¬#dÃj°Õ$~ŸÛýÇaŽâ�|ÓŸÆqt´ÃÑÑ!v»bœ�RÒçʇ†ˆ¢÷Wvð8ÎÍ'?K»£#]ß4!qÒ ·Þ�÷êÕ«W¯^½zͪzõêÕ«W¯‹¸–Àÿr2dieœß[ÖùDtA6Èk@ÿŸádKp€ëÜò�ëÜã_øÁø¿bùïuÈQncë öžfÚÂ9ÿ• àüÏYðvë`ª|N�¢Ä7ûp΀hsj¦¸.ïF�1€_Å¿)�‘íÃ#X«mê9eðf�6Û—‰%£]÷#“ò@V>§¤X•ÿ0tnnù_”ÿ�êÿ¼¸ý2àÞö-éÄç—|ò\y áÿù]'\tÊfÆmï¸ ïz×;qãM7á–[‚0 @�@ž²~}‹qm~.U.8ï„á¸Zsp;GÈÖ¼•´Óžó†8dQ9rÙAMÜ@¾çš Ý™m,뽚�4þ€gÖ½Õ†·M³XZù®ß:Ù¿OP› pÒ�T¤�­[A‘(OzׯÎ4Ë)ff¼ö ïÄëþà�øžÜàÉO¸_øÅG<ñšÔ;&°‹g J©NDlB²h†||¾<�äô_—�ÐÚòÎR1ìäY¡‡åªÝÞ²¤órð^ )-ÝvG„Y@Âê3å@,rã0 ÷ÑY‡ìs²Ùlö²¥—öÿ{¶Ñ'ĈB«ïŸ´ÌBdëÕëC½.¹äøà‹¢œ��¦ˆ˜L­NšÙ­`r(D"Aê�ûDç=¶Û-¶°-ãÙiŠHN ˆÎ¢ƒfï¤æîÎÔð>øb§¼n?»h9n§ᎎŠB?ÆÇ$Nû7'”5½SB’ó¹ÏKÅâ›Í›ÍÃÊ>&fŒ»Þï0ù©ô%…dëÔ1aÈJý¬¿p6ÎOE-î œCÐcó^I! l8ræ T1ÃP–#"$0Ž4­EG‘J¤È„uðA�9E�$Ècu¼¡3 F@ð^®¿ñ¦;Þþö·þй³üýó ö2Ù.«õW£ÚžŸš‘Á¾©ÒLÕž?Sx¹´/ÎW+]– ¦n�x³—•˜[ûŒL�”BƬ[ž™ó£zì÷GÒ.Å͘V•û뿟¿ÚñÏò/Ù¹@Zÿå¶d}­)ñ£ÿu¿÷ O{Æ3ÿÓ4Ž�@cJzqŠØíŽ°wÇ©M†�÷Üy¼�pÞ¢ï„sAŠ ã¸Ãáá!v»#ŒãTÈ‚ÃЧ¸{õêÕ«W¯^½–í½zõêÕ«W¯‹´–¹Z°ÿ8Ûþ¥:å87€¹µâñk?ËõžïXÖʶ·ð ¹ÀÞýzî<_ræ œvÎÏÁtãÈÀÿ (g"@kùïk$@QùgËÿ¬à_‚ÿPŽð¶­úû9ø_b ÃàÈ F$�Q�sÉ.ÙŽ¿NÔðI×/¦$ΖÿbÀ£Ä/1òÃrÊë¶FÍ ÏË•™PÛÏ¢²—F…,•` �hVâv,1!I¢í�˜[@pe’Ωýk>o«™âù&™Ý1ö»kDÇ܈žtÿ>í#·¸ò\‰¿ñ]wãì9Þ»¿ÿÜŸa{NßqÛ;pûí·ãÆoÄÍ7ߢöºÎ™’{‘q‹z-²ÚJ“ÌžŸÕ @˜ N'Dõ”ð,ÓÖ¹Œ»þÏÖgH|¶ý³ï—²_åQ�$/*J €R¶Ÿ÷­qXM^'ËÂe–N>‘˦” úepíòv¶å�[ šß‹"µ½¬ÛñM$†Å!Y$Åááˆßú�·â¿óV\óàKðqO¿_üYÅÍ×�Dåô¢rUãÕ’x8 ì Éé½ ÑMBÔ½Áe'#Ò$m+ØŽ*9¨è÷ˆ 9ïØ9°Åøì‰lÏ3erC!_¸†4e¤&O…Б/¢k/–87LGι  auúôé½~å8"ÀIýÉI@ÿ…ôEìçzõúP¬3—\¢€zpEYœbBŒ#¦)Gà|&©Iùk‹fjs�7ÀaT •Œr¶u)æOM~8ÌÀäe5ƒÿJ:�¼>ž ü7ËIºLVðfEr«úŸMbžg21_N›å�YÄrÍ>Í÷ÖG>~ƒ_ø'Wã˾ã¼çŽtÞ{òÏ£ˆN ï¸í6¼ûöÛqÃ�7âæ[nÁð«²>›&$±çn†TÃv�ªV'[Æ>æ¼³,æV9…¢Ø›Mð¢¸UCƒÀ`�o@Uþ·0Ñ<Ÿ•[ïÚœ·[Nšxy9¤�üoþ6ÿÍ>#ËÈZZX7·ûÞö�1–º’âÆà\½(�70eb 3‚÷ßñþýùcü¯¼�¾õ*<ï9Åç|ÒCpp*” °¹…°x8?(w‡&À;ˆÞ‰=–q¬¤Ÿø§¤7…„’»¬„ΞzF20‘£QœWç2{aÀ{]§¹6À[›:¨ƒŠž=>ßÞ7¨±Arg/½ì2GDAÛÿÏßúÛîû¾ç»?àÙ÷–°ìWÚ¾pÙ§�Ô×GXsÒ9èï€^½N˜Hà‚)Ê�Ÿ)%ÄiÂ8FLq4pNAÀÝ8‚™SÄ4MøµÏ¸¹´äq¨�êÃLù›#n\§ÀÚˆ´“¢D(!Ž1H;–5À¼WUq ˆ¸BxcfŒÓtDH1ÁåH�Yâ3@=à}À`Vüê�ãyT)�FQN¶ @•Há�¹Ù1HRÒŸ$ºWvoi JiO¹]% §ãdýº !(6Ç«d{åš8çJLÐd± w0©…{LÚ%_eDD"‹ %ÑtæÌ¥œ9sæGï¿ÿ¾°7´EëºB3G  ¹-F%'.IÍ5–┤ã¶¾ÐQã30g 4i8‹h´flDŽt%ì/N‹þIV­ûÉÆrmTÓÜ�h�81KG($ðæŒ4¬ˆ“¢ fVYÏ!ÈƵsÍÌOÿƒ×¿æéO~ꇿLo//$�”XØX§ùû¥:jäh%æäï—ÙÝ®í×½¹V”1ª9UdÅÿZ;‚ÀÂSͰΟ­Šñ"P;‘½¼v ÈUü>»d›ý°d÷ýP&I5“(÷5ˆ|\ã�Æ¡¢.#Eñ¿r^‹ë{ĵÏçÄη*ÿÊÅS§‘’�÷Ôä¿ñ­wá»ßzþåOÿ>žù´ëñ9ŸôP<óé×ûº¬$±ˆ ð„(¢yÐ.?ŸÀðê@�ëGá)äÈ1`^ŸU²6‘‰à‚‡P0Ŭ=C>*òa¶ÒæÓ †ƒóârïšskÛ±çÂxç�”NŸ>=°È)f9�)n¿ùüÃÝw}Ç·@$€Ó§O—g㤾píYZ{¾×ÈK@»¾“Üizõêµ^)&pÊðÁ8§vå)Lð~ŽDŽ㤊]N½GJ GGG˜b,NVÌ£D�É”ðú¬n·[mÓC‡ªT‰YY$o€> Ð�±ÅæhƒœÚï;ïÔ‰ YÜMiJ³ÃàHIT"@#8�ÃŽtlÓ*ѽ0l†b±ïýPù�Ø\˜Á<ØŒ€:rða€oÀËÄ ‰#bŒˆ9�¹¨¿Õ]Á!‘ƒçªÔ&˜k^‹¨úzœÌMFJ,‘+±"‚a£Ž Ó4Î\ƦÝX®Ï8Ž˜Æ 1éuËí){)d8qä"‘÷aOþwÿó·_ñÌé .zf™}Wºãò¢P[«……Ô š¦¶�'íׇ¶±µs®^—¼Î‚ 7®\Ç%Ç™åû'O RziÜ„tpÕô3û1D‹©Æ ‰‘¤º)ȪCu.jÓ–dI‚f¶ÿ ]`ep•‰ ´wÑÀÙûï{¡ˆ¼’Y6ÎŽ(yïx/€•¨»Ù Øl¶Øl6Ù¡ÓÓ™°Òò8 òëa”L#Ø\EzõêÕ«W¯^½zÕê€^½zõêÕë"®¤h'IÏg×ßÖI ÆRñß’ZÀ¤u"Xb–J�“^[�aæ+\GD7Äcåc¾ð¹òå—ÐeÎ{â)ðo?YÑ ÒI41"_læõVýg{"Sý OªôŸ«þMùO„jýŸ•ÿTrÄô§º®¬¬&î÷ØUð_&@väI ùa1ÑgJ] ËÀ,R ƒû“½V2‹ÿ ü›+k¼›AIöž…·;©ÉWEUü[¤€í�å?gg©û|ÍåÍ$€¥êÿ¼� ‘(g×/"+„�$¶OÒ>$6)J¸úA„Ÿÿ'×âoþ³;ñ__uxñ’ì)E¼ýíoûnn¾éfÜxÓ�åXª]¬MZgu¢½ (ÃDf³áEY˜�B ‚TžQ½ ¤UÔg‹aèİ#%dJK»ßâ2Cjl…¹äg@dœmò}«%Û-§ªj›MN£%;ÉbqÓÚI“»KË¿ØÆÞÆiî@v¶›Éu*ó䙤"6ÁîKhàð(â×ëvüÆ+oÇ•:…O}ö øäg=O|ôÈPçˆ�Ä:)ïLòúì;°x€.èç…LíOölç(‘äts¤©2×…Mn­Áìá}§Ø§Å¦8†y2‰÷ ¤1ÂÁüä«?ìwÜö™Ÿþ™Ï{Ïf»½Ôy÷@ðžþÑw|çá·ýƒo¹à‡îÔ©SÇöO'UëTÓöKלe_vœÓÀq.9½zõÚ¯q·ÓxÞè°Ç98·ÑìnáÃ�0Mf1@f¨…÷8ŽH1ªsbLÇÃn‡!8(© „ ™õ,à2,jÆ«à©DÂH$$#U%wu 8ö &™y©«å¸¶Þyh°DLÏRä!l6À°Ñ|?ëØZãRŠHS´×JtPB™‡÷d1 üÄ”0¥¤D ‘Y„ް£�9÷°Ìâ´ýbåRŒHÉà�S’‚«Škï=¶›MÙ÷§BÈàdÓ„qšc2õ¿À—§ÄpÎÆN 'ÉšN�9{æ’K~üìý÷}ËŒà:ëŠ�Üg14sï¡}E>ÖÀ÷f°ˆø¡æ{ 5 ¶s@b3¬oGµVɱ<΢´V¨ˆ™Øh y5 hÝ,I¨öËlì/Å¡©zB‘݃9– |i�Z¢}Ò·4Èû~ë0°?TšÇ,,Oz^g%´öN@Jéþø�þàqO|òÓ_ç½ïƒ8râý$%Þ‚õþßl6Øn°Ùn0äg<5q ø/v�¼zß9G„iŠFrÙ"@¯^½zõêÕ«W¯Z�ЫW¯^½zý¨™Bª!Xí—µd,#Ú:Nù¿Œ"h×µFHXÙ®pFD®‘ë<äK>™¿èÙOƧyç¼Ë–ÿ3ðS•ÿºwúOA'©kÈ×�ùsËߨúuýTTËÿlïo `ÛÏ v¨/;’š,Îï.CŠwi§à9Zð?Õ©Jj  ÈÃ&t„7Õ¿ä�©¨û™'‹È„ý¼  HX\\T¿xU¾Q™tä9 bë1rAŒH ü7Õ?9Sý0 àr<{3¶Ç�iùzÒþÌ&r^,›{»L‰p°~èï^�ò“wãÇ~ñþŸ�‹¥â4ámo{+n¿ý]¸ñÆ›pÃ�7ê$iArYU‡Î G Ë�¯‰±û¡´bªüÄ©±ZnUrÙŠ5g­²MŽær²¢Q“ŵ4ªÿÆÞŸUž©ø‹.Àëìÿm>°Nž+i€ìžl¶.˜©çP²ƒ[Z±µ¿-äˆrBRE“LQ–�Yùf«}T·"ÂÝ÷îðo_úvüÜKoõWàÓ>á|ÒG\‡GÞ| L”@¡ NÝ5}ÁHÞYö4ëýî ñ^É1ä#$Ž @%ÿ9qÄ{MøÁ¹GÌðŽ€ÖuÃA\Vÿ+ dÇ@O‚ÝŽñ»o8ç�Î~ò�þð=î1�}Ü·Ü'<çe‚#rô­ßùÿÛ}ë·ü½ š‰!œØ?å>pù÷5ð¿U¶Jÿã"Ž‹ Y*{õêµè·R,*z‚òÚ0(ÙÈ9oî5€(è£*á-& ¦©*É“fy§8aœF„�|Î…ú<ÛP ±€‹«ÍbŪì®cR ùlù®†LŠÓ(µï÷H>ûÿÒÄçu±z²@æ16!„Õö#o?ƈ1N˜â„”"8%°¹‘Å ˆ&f F8VÇ‚”RY�¶U®FÕ˜â;ïÛOL ‘É@Ñ„iŒˆö:š:?Ĉa‘†Pl×[w/ït\'�pH)aGìFÍoOæÚPœf¼Fåö’�Œ N$z‡ññOxÒÏÿÎo¿â«Døêµá_üå˜qΧê^tÚ+‘A¥ß¦^íÅb,²!üŠãe~¯ŽÙõ> cǵ3},b‹\sœ…,ÙŽ/ܺ³ ö�‰¨ìØ ìÏN_4£�`¯¿œõ©D ¾dKâl�3ç‚™€~ÌÝuç/ GßèœKaì�ç0xÍ}ƒá½Çf³ÅÁ�:dÇŒ'$s“hûïBP·�Í0RÐv˘¦©Dt@¯^½zõêÕ«×b¾¥Ÿ‚^½zõêÕëâ®Öò¿%|°uð`6¸Tÿ·•Õ$kÀÌÊú€g\ ຫ.§‡ÍgË×?âú0�Øt€ßU~ùNm÷Cô¨è=˜à8j.ªì'õ3øŸ þ8ð?4 yVýgðß,» øO3[î þƒØ%�;™î0AÒTþž`æÚíœ( [ýÒ# /f¿/ ôsš qS±þ—L H àë$¦4@eý›°xË/Ÿ)þó6³›+™ IÔug…³s�åþ¯IµV+Ç42ô&ï¾€ªb3þ–{ßÚ½Rq} ÀSU`1ð÷¾ìAxÈ ßö#÷`ЧÀ²ÆqÄÛÞþ6%Üt®½ö:´Þ­Î©@V÷9>PÀ€¬2cV!¦d@‚¶#®›Z¾m#¤§¥¡E‰( "FÛˆL “§GU)OQ÷7¥dî/ ä'8�‚S:“ëXÊ{�œ>Eð³¶M¬¯'³î'Rõh·Ãd :�B؈Iϯ3 uã{UWbtJf‹Ó„ÄêØ0�cùN✇KÂC9ß-1‹È‰s.ÁûÝ™K.½ïÔ©Ó?yîÜÙ¿5w•iût™�ýΫø_ï´g–÷)¯äÆ(Øt�RÞUBWäô¾*œÆvC9Zk�üçq@u¨Û«à?7À>Í÷{¹ÜÉ#êyBù_›-¿s,œ�öGS+gýxÒC{%â4=ï­ò¦ï{ìãžøVï|B˜Àá”™á¼Çv»1û½³kFðÑýœ}ÿ a(Ÿßl¶C( ¿Ž�wÚÅ©7̽zõêÕ«W¯^Mu@¯^½zõêuWžPËnK«ý<Ѷ´5ΟY‚(Ë÷Ûjÿ5«ävùåþ­šíx—уˆèÁDtýS%ÏøkŸ‚¯ºâw•ZœSìÀ‡Ô»О�x`À?S�›Ý¿Ûèg Üw…  à´®—\K0°e²K@Ø\³ýüÏÖÿz2 à¿�â’À2U°Þmò�ø€*ô™ÁSÄ•3ŸÏfÿÙlügÊÿÑÀÿ€m#Mf‰Ÿ]Ø|™«”3`˜‰Y-n*â¼-µû7à?G 0«í¿0à`l²ÎÞ�œoHù˜¤±ý_™Tt­+C´-ø/@²c)¶ÿMF)5„ƒLlй|{ r­Ç×|÷�¸ÿ��).ž2�ämo{n×»píu×ãê««hÎñ"À#F®ÌP°€ æ”�XA‰ª$Ì“©6¡,nv¶qÂÔØüÃþ¥Ì4(×KœÔ(zÍÐgÿ˜0ßÖܶ¹Ú+·ÉÂÍ yQ÷Gön+Ìî$€fo·™¾ê,�'Øee5²bU\�Sæ9º"z»Ïb'¨�Xjîsm;€ÛnÿêgÀþì;ðø[/Á§<ç*|â3®Â�Wä”âæYÖçÛ{ÿü|äÃåzQô`³#®Ï^°È#‹�®ÛYƱŠ!¹QÕ=#& EŒcÄwýØû ¦ÜÍíüý÷ß÷%?û’ÌžøÄoùÄç~ò«ó"|àÜ ¿îë�~辕pîܹվé¤>l­/\ö]k®8k5çé¿zõêµRÞ{µ‡gÆ8E€ŽÌV^ �J8sõ=k+¦1�˜U‘î]m©[°=«y£¹z�ËöüÕ>=1cšFÄ4麼·ñ•‚ž¹ïË¿g]ˆÜ& xl·År_ÁyU'V§#%'á±Í=oÚšÜvLÂ'ïA®TùÏàd@y~_¸Žá]„›ò:¼�G¨ŒÝ*ç+÷rIØŒ£ô2é`wt„iš”D#Ú¹Q‡�ˆ˜ÌN]¼·±Åb‚sJ4ÜíÆéÀœÀÉÚ^ªýMáfâ1DÑòHD;"r�|ôc~ê÷_÷ê0ó¥ûMk«ü¯®=ÙÊŸÖ"}ÎÓ>ÓÂö§8 aN¬nu/вÞHÇRúÙjç/s;¤ûŸ¦Œ5@ÇîsæKK°h¡óàízÿ�p.Z…þ,¶ qÀ ®GèøÕNüð®ÛnûŠÇ=îIßîœ;rN©Œð>0(ѱ}tÛŸgR€÷AïKsC°ÈWÿÜfLSwèÕ«W¯^½zõj«zõêÕ«W¯‹¸N$ÚÉ“å$ÊI€ÿ…¬g©ž\Û¯“À“…‚òR"ºÀ nú¼gãyŸþQø¬à(脪ÙõSê üw®‚ñYö €‰LÑߨöMÅOetËÿýàÀÀÿ€¨_@ì þûFõO ð?cYÂq£*òð� áJ Þ‹ÄçTlgÞŽ 5X\Ø–·<ïþÇ þ³Ò‘¤Ñ>ËU�]¬ÏÅÎQ£þÏh-›êß²ÃERÝ6O¦ú·÷ Ìð—•ö6Á­çÈŽ§Uô[TÜÅQ2Ô[ WŠâÿDÕ?5N-!ƒçÛúè'�Âü§×à+¿ãN¼ýO§rÏ_ì$§ ï|Ç;ðžw¿W_s5®ºêÁ DAH�|ÉÅyêš5úAU~–=ܸˆî‡7«úV±Ö¸é—g]›ûe^«ÞŸ�ÒE,µ$¢ªÂ—ù$<šPíeÝðá¯KËÀ_ÐLW2�E­n‹ªÕm`åð—„lªKÕxåòUW ÖYü|>÷šV"üáÛÀýØø¾óN<úa§ñ™Ÿø |üÓ/ÇMWz†X@^@)ÕûÜ)QFr{{frûYE”¬$I#KÊ`5fš’C,ëšC£� �’„¿û/Þ…Ûnßíõ5c|èë^óšŸ|ç;Þù“ŸóùŸÿcCw;"ï¼Ç ¾öëŽ~ø_þÀ àìÙ³{ëZü'¹´}YþwI`;n=mµÖ¯õêÕ똉¤ €SÄ4Þa‚:ž¸õçQD Qbêv²Bðyl‘Çš)AÈ)€Kûû'DspÞkpsÐâTÚpç6› Rb ö{ �6Ø ¦0atcÓØ0Ê)@N™�jov€)ÆÆQ$Kóâ&°ˆÏIö¾° JÌ�sùœŽP}0'˜Ò)—¾<÷÷¸€Æœ)M§¯‚:W¬ïG‰H)ÁÛ+ØñpP·…”¦r>OÒÍ|ö›Ã$B"ÂHDîÁW_{×°Ùþ‡ÝÑÑ_›õ©MTO3üÁr�û–õË[NÜGi|ö à™9Qδ/j~â^VÑçQtGÚçæQF‹�åÑHãÀÔ| ýµ …Ž'…’¿0s,X»\²¿ü ›>þ�¶ß»££Ï¹ç®÷ÿ‹ëo¼éœf±aZ˜²óÙý·t•ËÏ�÷Ú.äçÍ›cÅ’€ž¢:môêÕ«W¯^½zõj¾·õSЫW¯^½z]¼Õf€.Aû¥Ê±µF^Öq€5À¤Ímk Èä÷òúÚ}µ Àe®!¢›/?ãõ5Ÿ‹¿þÄ[ñ�W[ @ è;ëuBÕ5–ÿ,ç¬ê/ ½©ùáMõŸc\£ê ïlkÔ|Uøð@ã ò˜-ÿ}sBó“H¦ì�ªÈ‡©ÿÓ¤@›«áv慠õbÔõˆ?x˺˜w üçe‚°¹pR;S)3•%£³Dx›ÎÎîfùŸ2i!•³ûW9œ‡�S¨êŸ–ÿ3µðìîÛ¿±KÞøü#A$‹#˜ÅKÐ8pJpÞÙSic�sLjÍfBŠÁy�©ãuìKÆ�¢2TÉîÞ‡Y5äàĘH›¶ÓÓŽ±É””òøº‰*ñyÕh{Q§ç�Ÿ®’E™’Ùþ+ø/,H"#0s!f<ô|:oJr˜&L.jì@‰Òñ9oaÔ¬uçÖÁµßÍ8õâH¹‘Á»ën¸éÅ·½í-_J WýøK¼ß—æ±ß  DñTZàz'ŒùP![øK¹ö—_tm¨æST"—ÊsO©_ÇÒü½8 ´î@K硯´p fà´GXÛѵ!7U7§6î ýòAÊÿeþ¿ö/W¼îµ¿÷™×ßxÓ�£°¨�ŠhÌTæJúiûxjÈDå»13(EýîYb5¢Žu{Þ«W¯^½zõê5«NèÕ«W¯^½.âZ�¹@•þÐ8IùŸ'5�[çqëXæ&ÛO‘SNx°sî¦ÇÝêžþ‚Ϥ¯½æ ºŽÈ›eüPTùEÍ/Ž@žì}rjW^À_‰€ ð¿ù à Ð�E dðßþ˜êŸªb¾\c(0o¿`^Áÿ¸ÿÍNßoAÃU�é.Ì�ЋüXýEš,L)á}ïýSÜñþ÷ãŠ+®ÀåW\a9Ãù”bÑË­ýq9GÔ(çÞÜtâÔži0¸m?–ê²¢ §ò9Î$„2 ]ÕÿÙjÖÍ&²±Àýen.Ðr”Iõ™#ÿ Y€–!ö(d˜@]äpÍ$ø‰R·Å=ŒýGøBž‚Yûk¶ÀûÎõœ°è3zÇÝ„—þÆ„ÿô÷`\~)áñ·nð q vë}ËÇ5À,ŸÉ' yˆgp2R“«qù‘/ƒD×!‰Õ@D©‰ð˯:‹ïø±÷ãíï›ý¥ùYYÄŒãøØßyå+ò­oyË¿úÌÏùÜD^ðµ_w†7Ã&½è»ÿ©û,^è{k}ÕÚçÏ3°$ÇõêÕk½†a@Œ£U…'€cP Ó4 Î9xO¦Ü­dSï†0l¶JØ „P¬ü©æ�”v–#žão„œ¦ ž=8¼©þ•—£r=¦iÄ4 † bJ³±lE�¼©ÿu¿Âé¶mK¸4Û±tŽîñÞÃ;;G ܘ²gP;¿‘c¼×8€Ü_ÃÜì0«ÓO*N\(Êç6ulïlK–µ㤟óÞÔ9. (®½«ã˦O&š_‹¶Í${ß9§LLÂäÈM¿õ‘oÏ»Þñòi?NÏY˜#wCÖË×ÂÑ¢÷¥æ|¬uÓÔ€Ûí`Ã{–{ì¶ùŸ òا½öRǙˑm9O9BioWÉHx­è¾oy #X�nc‘ãd\±ò©Õehmè#Ç.¶:LzàìÙ/&ÐOA$àD˜%±s11�øà½/ãÜÄë@~!·ÆTž¹§&ê£÷ݽzõêÕ«W¯^Ëê€^½zõêÕë"®5ð¿�<Íïçϧb\³J>é§]î$°¤UüÛ�cæK\ED&¢?ãYîSžÿl÷ÅÛÁ¨õhhü¦J%þ]ºgå}þ g¢€©þ½ºx˜@&À^SP›zÑÀ6¶}#8Xÿ­à? ü÷õß Pcn§Íf»­@¿)òÅ,ó3øO¢“œár@Ž€xÔ^™ªú›½ÿXb˜wªÎGþ§�nKXUúÙò¿µMwÅc߬r dÿ3ØŸ÷UbµÛ7å¿ËÊ£l%ž]!\£ú?ñæ-w[}o6—ߪÎEü9Æ@æ9¥3·�F ‡<‘+¨×ga³[Ï‹Àƒð�¾âr<ñ‘þÞ¿ºG;žÙÿÅiîºëNÜ}÷]¸ôÒËpùW¨m/³’DA1W€œ ﲊŽòä2ž7ÿ¢ÚÊ.}ý—@¹,É0"@s —°X¥deZŽÜE½Ÿ©hÕb·Ú£‚k÷æÂ†—ÂA5˜[ñ–ì^9á~_LŒë2˜ß‹s.Kô5n³¶·œ1|žë9‚à®{/õ/ÍN'¾cÄ%g€ë®ô¸îꀛ¯ðˆ[ÿÐ-n¾vƒk®Ù@\ÒóâH#Tr;–Ž*ñFyÿ] ¯xÃ!~íÕ‡xùkqÇ=tÜõ\¾ÛÜ#,rê}ï{ß7ýÌOþÄ3>æã?þ^{íuïp¯ˆœ#r;Ó8Žf±¹Ïä™{NìÓÖ^w¡W¯“«%�Šˆ©r'LS(`ž ®š¯ä1,)Âà1l¶Øn·Ø  µœ×6²þ‡ü;e ¸ÿ2£3‰YŠ›]~V‹9ãL1bšÆ²�'Ä‹e>ˆà�7Õ|µ_#ÉžÏ9$“¼S2V æ€àÕ�À“F±è8T#~év<¹òZWV•ß’LýŸ¦Ã—mfÒB„ÁƒÈ�%�cÂÇâ˜Ó@H)ƒ”¾—ÊX¯%ÕÕqD9«€Š"ˆähºìò+^|ç�ïÿ¸Ú9Z>½âftÛO.:Û¹ò~ÙQ%Jµïßs‰Z Kè˜AÃ?Pªb?QÚå1×|([ÝV‰ ‹¸ ÚµDWG.2w�Å"4ƒªÙ¨G°~æÝw‹Ñ"ÁàÄnz¡ÔOéÑ¿ñkÿõ#ŸóIŸúß!"E„EXDLbÏúðåóĉ)k&ˆÔȹLÈç+·=½zõêÕ«W¯^½´: W¯^½zõºˆ+OF¶*"ïý±�çÿ—tç³ý_[þýõÿ¥®pËf ‡¼à³ý_}ÖècN-YiÓ(óCþ‡ þ³«ŽTAxöA3! À't=DF*0`ß��*øOù3d¤˜"6ÿ@!¬�ÿìŒ`$ê »Ú«C€éÈss69密¤÷˜Ê¿ÿ%bàŠ€ìTý›F#ŒÜïŠU±~'Aq) WHÕ`ÔÖ_Àÿv¿³õ¿ø/e_uæ¯Úí«ߟŒûó s{w•9ˆ’2ðÏEþ¦癀`àe™€ä†ŒaÀõÚÄdUYW ù³?î<òæ ¾êŸÜ‰÷¼?ÖIÜ¿`Ö¡"‚ûî»÷Ýw/.¹äR\zé¥óç>çÍ£È+¨>o7L]Õf¡ËqY²T" WÀ–݈Ùy%šƒ{ظ¬LÀ7íœÌåÿ  Qm hq¡†¶Ëí&CÀ\ö¶½…7 žnß_n~\«àÿlŸDêìP 3R¨�ì!`LÀÛÞñæwî0Mgg÷ò<.½ÄãA—z\u¹GÀ©­Çv l‚CŒŒûH8{(¸óžˆ;ï‰8{.ÍûŒóâ´Œh’‡‡‡ûßåW~ö�zô·<ù©Oým">û7¿é›äÞ;ïŒk}Ïù@ø5§š¶Oº�ezõêõAw@MW^£ â4a2γŽbŠE•îœCj½¿Ù*ø¿Ý`»Ýb†’û­$˜9T¹ìjdcã6Z ÷5k!{‘V‰1ÅIp�9D$³wÞ™êœÌßÍÚ˜µ±õš£–3A¹„à=Ø3|ð@ìtü•Œp�mÏÛc’¬€.ÿ¦b£žûm×8l6Øl„ çtœF›cÛØ/o7»/ï³›�ëI�·ÏÏäC®–ù Ñø¸{ò+^ùò_{KJé’Iˆ¨Ö÷{ÒóÖ9è|{Ó—–¸ 8?‰¨qÌúò2ލðM÷íû©¸AdNLÌã ãö½¸ œ°{uH°·rzÿ´©i+Ì…ö•¬ ©Êo´wnduÌ4¿VËóx÷]w~™sîå̼©#vû6eDvª¤ÁٳƜŠÓU~?¥4s ¨÷}Àf3ô¶¹W¯^½zõêÕ«©NèÕ«W¯^½þÔ¤Ï-ÿ¿²îãlÿOúYHD.p €[n¾Ö=ù>ß}ÝC®¡[@¡Zþû¡±õ'Sþ[&<<à €SkùŸAûÁTþnaùïì3fýïPvð[{?Ç ªÕæT�~jÀÿP3ê³Â¾QýC¸‚ÿ˜ O#Ôò?»höj�G¹ÚßS¸²{Ÿ~VL}/£®+�ªúç¼^‹`ûLRr�f¯×麬 ÒŒïü·˜‚™ ‰Í=À` Iu@²y?‡2ëœMD/ÊÙÝr¡w[¾¹ôß þkp=fS�Ôü€Tð?+–[Ûù†<°¾ŸF"á ?À/ßuøÚᆵ|ýÑ_X@®ûï¿÷ß?NŸ>…Óg.�sÂŽª²€'náz`ñÕ …çç°”ë'¦®d[¶Æ,ÜrgJÀìË� óÜÚ™À1j¼úù½ k¢=L~I0¨@ú±wçyïèµ'a}bœšçtÑÞ¶VÖí3Èß8+%!Yî±p±¦ÖáÁlœÇf³³ ¥ˆ˜bJ¸û^ÁÝ÷E¼íö †Õs#Íu­Ä�ö8Î ›gðcq3v# ²Ýð¦?þ£yÿûÞûý÷œOüI�³÷îÊk®=·=8ˆï¾ííü�‚þë»"ç]G ÒŒ¤Ò«W¯ ©)F�›A«ÞU°»Ñ@:%ªm·*ì�÷DƒÇÁv‹Íæ† œ÷֯ɑt¬VÀôæñΤØaÌm@ ȇà1„Cã00ňÓ àÁn~ÎÓÜs¾øSü .9p—Pð³m¿)û�óÅ~LÅ äÁ0õŽ 0P_‡.~þçu*1 €ÿ4˜S@¨ÊÈá`–ÿüÏ·oÀÿ~Öø‚8NÅ6Þ“¹ðÒÍHP@Y 6›0s/ˆ1awt„ÃÃCb·Û"ð!`›û36CÔh„U‘]ø˜T@ï ü/b²›PÒŸ˜R¾,¢Þ[ñ¨ÿð¯û½o‘K‰t<.¥ Y*Ö _¤[›}š�÷2  ²óÑlL±ß·�4¾Z’ÇÚWˆzTÇEµ/' 0¨Æ Û ¯õ§º�ì$$�‹@‰!*¤ Yý.¸w�­¸Éüåâ-?’òoyóÿÚŸô”ï ”.� ¯¤Ô|Ÿ–ÌÝæt ›Àìá9@X�:ÊW#âôêÕ«W¯^½zõšW!õêÕ«W¯^qeпÍP5K»ã“ÀÿY¦ê1ªÿvK«ÓÖêß^¹TD®‘«Üø‚ϾäãŸJŸáÉ9¢ä7�òÞ@zrp. ª±=àœâÈì‡o€}#À�Š“€kÀýlùïA°0”¸€þCsV1³¶n-ÿy¡ü€–ÉyV \_ÿ[€\P”õ`óý)`ò€œ+jæ£bÿÞœ 2Úß¹*�ˆLT,v®$Ï*!½`I·™&#Y��¬0ÿ3PFê¾À)@ùtíÝ Ë¬™}uÀÌB½|¾9—Ù¶Uî ðßD ¸æ:¡5]€ÿ²«Yj\ÀüϤ ›)õ`|ó_½O~ôûûïÄÙpì³t±5Þ÷»£v»¶8sÉ æù f²°}à³ý£®�œkT~ê� ügN3 ÊñÈj¶ÖQ OèËñ–¸ùr/åøŸ×v)Y@N2�%ØŠâïÕæ§çä›þ¤ZW$žþ£Qý æàÁòza¾  D !¨;ÀbY!…©²½3@mºÍò:«fçý*É¡/²žäóLà`µ;:üø_ÿo¿úõ¬�þ¦G>æqo‹1ÝŸ’<À,»ÄiŒSL^v»GVý‡¿óvÀé�~môêõç\Ó4‚S2ûrÍ«gs†‰ ¸nÆ�֓°Ýlppp€íöÁ{$pT@>FU«(@ÍÔþ)q!4éx¦|¯j}ä†0 ¶Û­‘ ¶AÝ¢9,I®Ëñ1›Â~GDk/Sb¶h?B8–ˆËÌæÜ‚bwß:òˆ“ÑKDûÖĶ-Nú=À OõX™="ÅÚëÙqûàgßRJ8:ÚáðÜ!�pîð¦IǬ!éµr9êÉ"† ×$§÷Þy$âjӾ蚄ë9Ì® )ªsƒ×“2Ø]zÙå÷ Ãæ—Çqü?×:·¦Ë±¾­:ÌÇš÷³Û€rÈý"@¨ö�3{|Ù5ïµ?k zÙ3g@~cƒ$3æ "å´Ÿ³—+^V�Þ©¤¬;ž0Äø Ç@Í^ØŠ�ŽŸ÷Ýwý‹Óg.™@˜È¬œS%¾·ò~13’sÈC“%¡¯<£nı$Ê÷êÕ«W¯^½z}¨W'ôêÕ«W¯^qµ™œ@Í>Ìÿ—sÜÖšJr þ/',—§+.ž™/eækÜtåeôÈoúÂðu�¾ �œÛþ@A|g€>©ºÞÁ@kdÛΑ%óÝ@û€žŠ=¿Ëø"ÀÞwݦ۠€ÿ Ày;(ÛŸƒÿ'Yþ›úYùŸ-ÿ#Àiç�\cY.jÅ/°e$á pt�ÿ2igQ„w¦ÜW›~áTìð©ÌjæÈ7×åJÔ}ä¨ yå?ë~¶Ç©7E±Í'Oûyß²’ËZþ†õüïòÇöHÜ·výÙiÀ-€ÿ¼[&Iu ÈŠóY�…J*ü üÏå0ôì}ÊGœÂ£¾û¼à»îÄ›ß1�¨¾˜k)ß펰Ûa³ÙâÌ™3Øl·³ç¼¼3UÏWRÕÛå4³/Ä1 á|ÝhåšAï­jOlÊ›÷YkIoJà ¡Ô{¯dòŠ% KûD,Àô•º +|¡·�w]¨rQˆÚ¹q´I²`#ä°ÔÞ„^   `ÿþÎ�åK;T‡B0E, ¨‰“‚nÓÍ^¸½ÅÃ`v]ö�] Ç�Tð8�™¦é1¯xùÿø7÷Ýwÿßùð�ü¨W‹0™e4§Œ°ÝÒ·W¯‹°¢µª:¸‹)ÍÔòÉújàC@pƒ÷6l¶[l† ]_œ&Œãˆi!,àM€'‡)�€cJ±¨÷™SɱwÖ÷kŽ}À°Ù`»ÝâôéÓJ688À`€££]é§i,öþ-ðŸ‰Ó8bœÆB>˜©À‘ɱI Aöɹ0"(2!Làm_u¤)5'>iŒTd=F%x` xñpÁ!¸xq*û¤ß†øŸ�õððŽŽqtxˆiœÌZ`Gà”##Žvä,Úg£¤Î„!ÀÇ€ÀŒDÜ|Ÿ˜G©ä±€: €D…åè²Ë¯ø¹;ïxßÿ™‡mû™ôRÍâÉ`t¡Ù¸tLo#mÔ�Ô~”lc™‡:Sç·$€<¸�Ž—Æ—GÇâÅž¿ŽÌs'_i­+@£ú¯–>RÆbQ "6èXUô/¬‰ ¥`™‹Ôžø5û¤Eo~�»…ù‚ÀÌW½â7ã³?鹟ñÓvjLä9‚w þg 縒`’·ïYË¡ÆÂ±ŽåD¼^½zõêÕ«W¯åê€^½zõêÕë"®¬ºÉ“<­ý~þi?{\�@9Îþ¿ý½Ùö†™/3ÕÿÍþX÷¬¿ñWÜ×^y] òp´üFÁwW�À+øïZ»}±³êÛmP¤ç´ü÷IíÿËgŠåÿCþ% d§˜Ú*ƒÊ¤*÷jùO Õ¿)ãE ü7E=O s�I­Póég[_¾6U…ŸÉfÉ �î3ðgä‚QA{ލ§�3€ÛÙñ—iÆlù¯ÿ²§ú×Ixi�XFo±N�åxËúë5ò¬þ_·ÿ ܯ¨þ�]‡|�%;Àü7Êÿ=ÝY¹Ñ1s Èdzþ¯¬ãÖ¼ô{¯ÆßýÁ{ñ‹¿ñ@yvþ2L(Žãã8b³pêÔil¶Û’áËÙr¾¨ë«Ï½ÀÔ‹È*uèu”u·€‹ÛfªKë¦�=Õž.£“áóøY©± K²÷YÞ¿¹>pÅz÷ÂUê¦Ul‰iÿ1É ‰okÜèë9lâ ªº-D¯d¡Ê·±bfb1"Þy¸�Cl¶¬`PbpŠ–5Í•\s¾’ã󀩹ùª$æk_ÿÚWÿàÙ³÷ÓÇ>û=%™ÓÈÌDDpÞÍÜozõêuqT:ï•c)“BÝ72±H ðä±0l¸0 #¸f}2°ýhÜAX°áï��EûOÒ#°?PÿÍ@?CVû5*úY—Ý�1%®Gt\ªkqçÓå/Œ¬Ÿ§µ}kÇ\ŽÌÉ©ºÍðÿ&ªb=•éü¤Êµºÿ¾û¿�…ÿƒ~ù”Ÿ‡ÜÇëxÛ�™¼G´÷Z;·x¯~GMÅí¢W¯^½zõêÕ«W­NèÕ«W¯^½.æŽ:„½,Ĭüos—6ÿùókµ6q²¬¥ý¿mkÃÌ ø×~ªþ§}„ûÂ!Ð@n¹ @[ÀÞ”þäU•ÅΰתºçägU¿¯‘ÐjwÃÌò¿þÝæ“r,€LF& ÿ[Bÿ3RÍt–F4‹ù¤?ü7Õÿr*�óyUkU¬-" MjM;œ;ïx„¤�~–ór\få¨8PÄöëz9øm_wÀˆ Rσ«÷„¾hA6Yü ¬Âz… Т~6‰k±gÀ•Xl�¹3x×84­`%.d�ð* [vÄÕX¢–LÐþ4 jnbìýí@ø¾o¸OìßùoîÁÑø—IM$§ Ót/¼88ÐìeÉyÆÔLÀ£*ðM\ƒ ØÿP»q’ öž‘V�?›Óop6i.Ôü¸Þ[WÞæâ²ÚþÎñƒ…Ó@±ó¥ÕIò <…âÇ{Á«Bc -ó0ã`È­K€4× �hKëṦ® l󛉆@@f±KšçÌÑTyª¸=ö¨RÂJcѼÒm²Èé?yó›_4�ã×}ôÇ=ç×D8�sì¼çœw]Ö׫×EÕ›d+ûl7/HNAòÉPPNl*}†gcxçüßä’¤€ùqŠ–„iB'pÊX·UØgpž™�4KpæžB&((†€ÁÖ“·ÛŠãQu| þ3×±¶÷ÞˆIÞ‡ÑÕŽÕÛ1t_9_é‡"3åy¦¤f7œúŸ¶ï.ƒ¤F8†¡DÊ$NÆ«d„°6% !ñ„i1M¦8•s´ÙlôÚ]Wõ˜2¹OXÀ¤.ÞòÕ‡ ÙëdcÅaЈ…aÊ9X’“Ä!¢Dž&"7Ûí/¦sñ›³P&æŽ\û)YðÏhfí¯àµì÷A�ûiG•ØHp{$CÁþ¸Œ“‡€Šê×ÏÒ^Ÿ×DÐb¹ÙέEhSDMÜØqü·¡üˆÆ‘Nïç�’S\%þå{9?«úãç®+Ï]¯^½zõêÕ«W/­NèÕ«W¯^½.âj';[à¿ÿÿW«%,�ÿæg+"—1óƒ\{æö�ÿGøª'=Ï<ü4ÛÞ›í> ¨Ê{8›I“Ù÷Ã5Àþ¦(ý=¼E8U»çX7nÁˆ”•þ¡ºÀဠüÏHw¶ÿo-ÿóD%"KTå|þ‘g“©aÙ>¾œÀK6;–Lù?5ªÿ à]%ðˆÀ¹iº·¨õ‹ÊÝëzyÌMÁ‘)ŒòÌœl’Ýx2B€Yþ·–£ž*XÛäµ7wÅBý�“%½ûÖíœIkà¿WËçï+XoËŠœþóŠŒÜ5¶óÕgv´ïlÀÜø™ÎUðEÏ=�§=zÀë]wÝyO¼ò/ͤ¢)¿bŒ8{ö,œs6†0X@ž æª¾7 çÖþµØÛª$s6žÁe)綘gR´êj!³û¬u€˜o¯®¢±F½î{À“�9´†þ¯^Þ @ö�aÈÉ®ôšF-YŽßŽ)ßÏ­“AÿçS???/eýÇ>Æd)qÙæ¸^D8Bðæ´¢+×þ(™%¶fVÊ%Ö�°²[5S9ƒ"ï¸ííß÷»¿ý[ÏÊ3žñzGn ‡ä�cçg…j¯^½.ŽrÞÁ‘SðØ ’Wà>Ä £W’¥°ÚÔSR%´fØ{8fÀyM ’ò/³¨­>7î4MŒ•°Ž�§i*øÃö¢®²¥8'†x‡06ú˪ÿdNÓ„h yŒ©¨ý³»@#T 2; ´í®C¤î‹s>·w¥�\Ï ÞCÄ#‘3'#yÒÁ»Púnˆ`0gç¨Ä´ªh%EdÒÁu B‚0hXÌ"6œY ùaÄ[`6›LðÅAá¤ï4DÄbð~ºñ¦›_ú–7½ño�Ä·Vù…‡X™juübà%õµÖôó>h¯³¦ùØ"; IY§´n9Òô£4?ެà×9#¸¦Ï•‚õS €ê”„å6›ÏÏc“æcYc'|c]½‘ÐÆœoœÛ2Nv'Xûó{ßûžç Ëï‚à¤ÍjÚÛ?ÿƒGàaö]5“ÈÑÞ÷ØÔ«W¯^½zõêµ_�ЫW¯^½z]ÄÕÿË×'-³|}ÜÄH ö/ÿmV€+Dä7<úzò×}®ûúk„@DÈŸÜð¦Ä§ÁÀwË_7›Mý7+ÿMý�ÕûYéïø¬ø§ì �•ýªò×c”0PÀ×ükàü¡ÛŒ`ªù ´—#¬6úˆUíŸZ˵П۟ÀédŠòÁ¨ëåQùlÉ/æ"À;üÓ¡’!@UÌï °ÏÊÿl÷¿þ П lN<™‹ƒÁpb(ž ¨í©ØýÓ>*'M¢.«ÖíEùÏëà¿·ëïÝ:øŸ—)¶ÿ+ûáåV?·¼ù¸f䙓ŒT Km¹}þa7ÜûñŸøYŸýÒ—¾ôËv»Ý_ð—dv±/sÂî(a‡†AÁ�VOW@aYkOªÅù´&RÃÜÅ‚N¼u×êj†°6OýÜ ´¾HigË£VAˆ–�wäÄðjîy¹°{@òõ��(0™ÓDç�¤Xó‡lõ^Jš��Xm¢³%o¶o²ãC˽™�—¼å-oüg�y‡}Ö%—^rDä&ï!>xòÞœð°W¯^ÿÿ˜H2ðÛ{o}9±Ãf`¤)b Γɸ¶ÞÅò»!éå÷‰žX×Ú1/냇‹Ùæ^´íaÞsL1Âû ntðÎà0ƒù¼alÓ)EŒÓšTÅžŒà$¢„�†aƒa°ÙlB€óNIM;ÆÇ(‘ËØÂy%~r*Öþí¤¨ýC@ ÀyVsY€}çtHG[3ÒRp��»ªB:ï·JØ …PÒeJ¼˜Æ8°�ß2 û àHccBÐíÿ•¤�?[¯CÄe V¼sÑ9oyÈ­ï¾ímòªiŠÏÔqÃÁ�…œo�aÍ"¶Ê†æ3÷"ì™WQ“OÓªø[o¨2æh¡ü—ùvKàP6xU°_Ö-üµŸa;¼È»ÝÆÌÞÇb[hâ›–1Çm`I^>f;À1㫼ÆÝøé÷Ý{÷·]zùågEÈ‹HœÝ,30?xt‹%Ñ8m4Ñk™Ðã‚zõêÕ«W¯^½V¾·õSЫW¯^½z]¼µ´û?Ÿ½áø!µ\n¡ü€kEäæÏx&}Êç<}ÅÁDDÀgËê�ªë«òžÌÚÈ‘ØÈÀ+�ïK,€)ûK,€3ðßTþ~ÐÏdeü{/»ì²Ý—|É—|ËK^ò’ÿgÇpÕ_ÎÖFÔ&xšLÙê$yQe*1¥�&"8˜]‰RX*Öˤ<©Õn¹vÍÙ'2@+)¼²Èó•y¦r½/±°Ö]»I›ýßsÜm�{¥l&gÌwLêìøÞC´Ü2­¶·b÷}žô.ç¨õÏ/ÇkÉfû¼Ì! ÿÞ/wQž²©ÿYZ•mû\TH~Ö¨9 Y©X챃¯×Õ™%tÒõs›±½ÒG1ó­¯ùÝW=ñÙŸøÜß$ÀC$§À]¯^½.¢‰$‹¨òÁÔðÎ!±ƒÈSœ0LÁøLMn~¶û¶¶5·9d »‚YÕ“£b÷íœÚßçö+…ò.·Hœà%ÌÆËYù~´›aS@Fµò¦ºÏªyUÎg’Ã0lppp€íöÛíÆÈr:NŸb<Éö~]™lN;mÆ|�dM�Ÿ-õs @>&�kȓΎA¯‰sÒ^Ìx” Šê>o·Øl±1Û~WÇ1"N#¢¨cCâJvë#ô|Öè=ozýµà½~.‡!b8v Ô›]–s.ž¹ä²_¾ïÞ»Ÿ©ÛÙ·ÓÏýO>g”IsME®’¤qÔ™þÕÞŸ2`oý¼Pã0'´kbûFù}èzXΧ¶¯ªþõ¿ÍM}-ø/Çvâ²\ÑÊXä$È~=à_�B8X‹Ž[çrÎ?׿ö5¿ó©ÏúØçü €�¢KÉ'© }˜m+Ûÿ·c¦™ËFÃ-ÖÏr�èÕ«W¯^½zõZ~oë§ W¯^½zõºx«Uüþ/-GOªã\2àÿ”ˆ\."×x�›¿þóè+?â±ødQù àNþ@Áv³þwY�±¡†³ä�>ûà=Ô'ÌæÞÿä«ê?»xû<ŠÛ€Y寃ÿ ex¶—G2°¬ÿ3 nöùh�¸‚ÿ ø_ÝD*ð¿Óu§�©þ“ªóaqiÿ%�h¸ "÷"§Àª#Bk}�AXVG˜êŸ“E èk1gW&;Íö¿d§ÓФG*€»PÜ+pK ð¿Y×|ø¢ª¶÷�t@fù¿þK¶û—Æî¿ìØÚ�<þ�ýZìÛòX—ŸkAc¼ûÞ3¯Ím{­÷þˆˆÒ—ù—¿ô‡ø‡ÀOø˜¿ìíNJ äôy¦¬ØöƽõgA»ÎyÔ/ød²·]Ÿ‰ìÔ‰‡)&p’â VþÁÙùÉÎ 0KQ™9„àppp€3gÎàÔ©Ó6zì)2Æñ,‚”œò$ÍÉ…Y‰¤z+ë-ÚË-Î[{ì-X›Ï#³^÷D$Þ{&¢ôðG<꿽öÕÿóÛDxÈV1$´èÿ¥›´>~iÛCsÿžJ^œ‘æ}<9Ò1âBéžûÇe?ïùA™²èÈH–@tüw²J(pe¬+çùÞVÜQëÛ8~ÌR¾•�DCÚü_.#pÐÉþHW�tCU-6Sý§fÝH¢à?3@\=S‹›n&bìÝ5 ðŽœÒÜ“{ì�ð߀™ÎHÎH^ ™@D�!qu ÈýyݶÇZþü_|/‘uí´Þ7ºï1¹ÝOýÖG½È{§sî,€‘ˆøù_ø%ïø÷?ûSÏð·|;Ô‚â/m 3Hª0¤yžÛ׎ïŸïroÙÇ)çÁ뚤õäÅšÿ1¾úÍß…VTjùï­Š°Qýµ{(•(2w�¶V�ôꪀò¼Ô%¥¶1²t»�â¢áÀóÃom¤uÝfõ^hÁúVÝY@‚Y<í6hqÌ ÖÈì~¨¯kD„4¤ =÷äHpЧ$¦«c<|Ìxxø‰W]õàßöÞ‘0àØIOõíÕëâ«Üpb¤¶å%R%ÿ°Ù ˆSÙµÉÀ’ëßrüŒ›Í�Ùï3¼×õ¨3�7Õ¾ ùˆ A]‚AG[`ž¦LFš0NÎùbßã„§™Šß9s4ñ®¨ë³*¿µ"¯Àã~KՎ߉¨ZÍ79K —ˆà¡ã¶$–„$@LRäfHè°Ùl°Ù`x#C0Kq/Põ}ŽØàÔ©Ó8sæ4¼÷�=hl‹F$$Žˆ1"f"2³ Å<<±­?‚™Š“@J l.­z>ÿˆøì Ã⃯¾öîÂ+ÇqüXGjÿŸy,âgæ*y)Ñj~³ÏÀ«½¡S²ä¹qà±1a&P8š»î ¹–ËÂ*$ߪú$"µ³Ïc´K5Žh¯ÃŸ�v” 'ëÀ?¡þ[Æ�´!GrüÐí|cŲ³s…õïµñ™oü£?¸å±�â›D$¦˜�œKu5õYò>À9ž}g�SÔ˜ #9sñðÀLÑ÷ƹW¯^½zõêÕ«©NèÕ«W¯^½.âÊ“—mÑ ‹'9œ´lc¯8ø£ˆÜô¬'à£ÿÚ§Ñ_¿ô_ª ý5ð0ðß@ùŠd¥PK³û'o¹öAUÿÐÏà!Ss Ë×ü ÿÉÿì°þgËÿ‚`‚³�>xþ#ƒÿ`�8Õ¥EÛ `—Á¨Ë¦�ªü3ð� ú+ÈÏ<ÖõJ‚p þ€y=7’ôÎÑ Ò8pTåŽ`†p>©áåä üÏ ü1ÖýÒ*ø?�;´‚ÿ¼W›xØöŠòß~Š:'ƒÿQI %.`f÷¾WÅ7󙿏ì:ÏßÀbYÚ{ÿê=ü‡ï$¢÷ÑývDÄÛÍ_ù¯åͰù®üþý*Ô à1m‘Y)S£Þlß¼´…�1ªÁ>-~ÇÌfŸþ+÷Zþ-»RdµÿŒÌa�ÁÒz�/n«UÙý…>+Jûüoló=ccSlQÉnÁòùtäÀÄFXiÛpÞ'KT·ã½gEl™lÅ_#š§‹òdüÞ“SWß‚ÿk*ÄŠì¾P�«u(ÛÖéK.ýÕ'>ù©ïpÎAÀl8�ü™‰{õêõg8F�üRQ k»§êô! ›Mé^‡!”qhµ†Wà~(Yò®ÎÌÚ>yïæcYçà¼Ç0(~�b jÕ†BXªÓs–}Š ;Ú€z'ŒãˆqT@ÞïÞy Ã0[—Úð"©´�ލu$ŸYàGhtmXûÅÉ©CË4M˜ÆI�Dà\€cØlÔ xxçÁç©òÞ{O¸“?Üð[€¯ ¾#R”¬ê&çÛ9ó)TàÞ)˜¯yð jþ¡Dº~ÿ3èï›(‚ƒ)å%ÿK¶� 8™Ý¿,t†�Áà9øÏÔò߬ÿ%šÊ9Yn|K$€øÅò?rØ€ÿ“’ =ûÿQÁòL2(ù¯$Õ%Aœ�>kûœ•þ ò ·ÛØ2_®ÉJÕÉBß(�W}N1·ý¿œ­™„S†q�Ĭ–ÿ¦ú§¥å¿X$‚R2åP{¯o™ZD“hþÁ™§nüÏÖÛ€ÿD{˽ë®K_÷Úw<â×�£÷Ñû‰(ß|úôil¶[l·[üí¿ÿï»ÿñ·? À÷xÎ3ãù—¦MbF‚€\™W`àØÛ¦ª$WÏP#Q#Á¾u?;ÚËj`ÁZ¬Ã±Ne�s1\V·Ëv%çQ-Ñ¡‚ÿ³{6;lžÌbÈžQ‘ €ìÅ 8RÌ€¤=¤¹?ª•ÿ<&�Ê6gù¯-ÂÀ:ÆÓw +‰ TžûÒ-ˆFEÅ©ÿMOzÒ“žˆX5d$ÉÚê^½z],•â„#g•´Úä;çÁ’,·Þ!ø´�ñ>X¤Œ:DA¤DO< Š~ç˜Eéi²ìy8o¹÷ްÙl‹ú<Ûâë~¸¢ÖÏy0³ÓgV°|š°ÇâàœB€™¹ pbÄ-‡ËØ©X‘/Æß+ãìù8Þâ ܬ�¬m*çxŒH¬ÛŽ1"^0ðO¤D‹04ÛS’CJÑ\” á}=z>Å>—L¹¯dNBuY""×è–9ØÏ\Ù­ãÂqßSdž“œóÓÃn}ø¯¼î5¿ûm Db„…æ|,òí5ÿÝ)çWæ}ŽsÎõŒ½è!¢ý±G;¶,$€Ê£-ˆ>U¢\C>” ã[¿JëãèE¼è7[Ë#ZíK훂q$I¯SíΫiPC>¨D#O«Ôïk ·n¾�¾"œ0ŽÚ�»ÏcIßïà&%�HÎŽ%z#è½JLðÑÃ;‡ •<”ŸM%l”ã»@¯^½zõêÕ«W[�ЫW¯^½z]ÄU2™�Qý¯®[DÀÀ)—¸þÊËð¨¿ùyøÆGÞDORËôÉè¿Üð\V몸ÏÖîÎ@ø ÎS£ð·÷‰Líï=€¬úw Ëÿ¬ú_‚ÿÎ,ÿiþƒÌY $0ÙÌò¨à¿€�ì NR¢Úu$›L�l»/HGP"ÀÈHQAdG#¤¨Ë PÁµAíFË1 [ˆ< 9 øÏdГ¤ÆÝØ&¨âÞsRÄð8Ûÿ\+æÒ+D'Z™+àž·ï<œ]ç&{½µüŸ�ÿy×íïÃ…ßÕ�ÃÃ\4<'¸ ®¹­»Ñ=ðÓ¿ýÑßÈ»Üà¾öy¹çÞûpß½÷â®»îÂ}÷݇‡Þúès"òÕ·½íMÿÀ¿pÇHˤUê`6 o`þª,³ŒÞ ºãB§¡ë, ȽŒ&@¤„ `/`¢•ÄQ½Ç?èt܆€0‹ª˜MûŸï>6ÝæøæÏeC)J¿™2o/¹þ­üÕõƒš§¦!¬Ä ì‰óg‚J†8hh³™/½ìÒß¾îºëßOš©…™™“äÉþ^½z]<5Nâ4™Ý;@Î#¥ï½ò+’�€È œ'ð³?çÈ[Þ·w†-Â0 ÄiÂèìÀ.G‰ñVÕ&¿FLÕ>J\‰ pê 0[¶dÄì«/ëQA¹ÿ’Ʀ¿/]ôiÒ.s~`=Vý¸Y®®ëÂFÂÔW YÝtUîÿÙ×ÞÑžgØ.Ì7þÞÿ|ÕÇ~ä3?öW‰h´Ÿ=âz¶÷g"D_I=í3äíy÷AŸ‘nÔ«W¯^½zõêÕV'ôêÕ«W¯^j9ÁÌÉíëóÕbBòÀ,ÿ¯pÝS)ÏøŠÏ o¸ò¾â@NwUþoígø�ªþ3/9ƒÝ€ß8»ü<¡:x#”€¬ú÷æ.°±uåè€ÆòŸm[ÒlkÍò¿J]Íò?¿g Êà¿�êˆfGmv./Ÿ ,›Ô~�H£YñiR‚�ŒlOúÚü"©®'§rÛ9ª6¤”É Ž@ÉAø‚TɬǑ2q¡± -X›M~ï�ÿÍù˜«—÷xjnÌDÝ ³ëO.Tðß;�Q`¶s’�# ¬‘Šm:ª“ÃúÍ<ò[BC{Xy}­å?pRo†üÒkŸð�nk¬ÿgÏKŠ ã8aGLÓ„˜"¼óxÔcŸøŸßôG¯€ïðÅ­’`™ÞË‹/×�Vx³¢p—•{q&Õ_YO&¬'ýîMPÏâÚ7©P*whnñß‚áT„ PÞ‡nÝüi=5s÷€¹o¿Ì¢G$£üð϶È'“Ôþ—šU5$�ÆYxF^8a]³¦£Ý¬€$´¹f®zåÖ‡?â—™yÇÌ£°DN‘SJˆ¦PíÕ«×ÅSã8"N"' 9¤ ü%03¦4ռò~>CˆH<x‹š¸¨ÑFÌbÌÙò5ÂÄ{pª*ñ‰ñj'>l²»€‚Ó»qL(6÷Ó4šº_¤ÛY�Rœ�É3 @�Éöµ�ÓYÇYªŒçbûNäà¼+Šå‚ºê4ã{N “Sp~³Ù¨ý? ܤ¤Êív‹ÓgÎàÔéÓ88u ÛÍ)EŒ~š�çj¾¤ÛOœ�¢am¤`«F´‘ÌŒiŠH1"ñœá½Ú®‡0 „`çEÇšÉW@!]xo1…Œ!aia"¢ñÔ©ƒ_}à�³Ï "¸ÜO”\y9ãš.Æ D®‰Ú)½jé‹2ÀŸmúóŸ3…�digì}¿ªßÇ*×VfÃ_Ò(¤1r}$ÒlköF'}—[¤Dì�oÈ:t‘½Q@M´Âbܵv¬8ïQ,bŠˆp¡&J÷Ý{ÏóC/#GÞ;Gù¹ÉÏk~–ó¾µNÙÅ#„ÁH%~æ€Ñ«W¯^½zõêÕ«V'ôêÕ«W¯^yÍrOˤ£ìÙúïORï`J¦��ÿ7ˆÈ-Ÿûl<ïyÏÄ A6 Ëj§òÛÆö x³ü§CšÈgXKs›~Ê–ÿ^ÁýbëŸ_ ÀŒ‹åvpÍ¿0Û³—'5Ŭ–ÿªÚ7ë~SýC`àVýgðÒÏ!ˆŸ4S4ƒÿÒ(ÿ‹u¿Ù÷óNÿlÁb.Ìê`nü�¶>o6¸z\¯À?êþIYV'‘•L0Y€˜k�cù«lÈ-Àÿ¥JIª ?ŽŸ¤¬j´™ìwNhÁ¯“ÒǃÿÑöÝâDöÁÿ¬ÌoœÚ}:¾Zå?ö¢hü‡Í}ë²ox÷U¿ð'ï»þ€¼‹ˆî°Ë«È¶¶Ó4b·;Â8�e]íG=žòô�º{³Ù|É«~ëeÿÀ¸ö/ët’r.ÃÀR&…Û¥h�oÔé G¹ÐÝ!3•_›…n –+•}g€½û½Q«¯Úâ7qóS´r\³ÏP-h ·J}ižÛbß¿t¹hïûJE°µÔŒ…, æúÕeêu¢*˜lÚUdrCDÀ‰¹Â SèÆü˜pppðú_{ý›§”ÎÅCG9±´6Ó½zõºxjwˆSBd9òHIUà$‹hD€YæÓ¬½1Â&”Pm¿ÕÊ»ç=‚`IjgŸ1&ŒÓdÑLÚæ8ï H'·UÀ°*ƒÕ"< ŽÈrîv¢©à³ ~î×Ûñw›9Äòþ ~ðf¯o€¾ó‘£Hq´q³9&YŸè‡€à=|fuî«RŸ‘"@@6† Ûƒ­þ-è9ÞnNáô©Ó8}ú4¶›l6ãIÝê5kÛS=WïÕaØpù.‘#”؃5Š!_/ï•0�‰­e{KvœÙ9 (»Ã Ci6�×]Ãý“·¼éï—ȪbÈC °œcpöç'ÚëzkÖ쵯Ûûždt?Zôûȼƒ ÆËâ»X³-ÁÉ`xöB•nX�ý Ñm�<ÞZ|©� Xl3|0Gõ¸eý¨÷Þ¡ý�Ý4�ÏyûÊ[òÐBNï�†à]yöÚ½¯ôÞ4' C(÷]véÕ«W¯^½zõê¥Õ ½zõêÕ«×E^KKÄü€õLÑó”�™Ìü ¹a;È#¾þsñµO}ž…29« |ÿ7Ò{¸l×SÛ;0íƒÿd€|Vþ·à¿ÌöÞ—Ï”¿Ûçç–ÿPàŸ³Â?[¸·à?LÁߨáƒIj‰Éª"S ßÀsÄBIÍgЬÇ,ÿ9B]F⓽NXF]W¶è—±(õE¦º]àtBQ�z�7nƒ’$Ų~)ñ¤Ç3‘@óMÝr"Ô»b·k7ÅÜ¢½±~Uð¾)ר~ÓB�œŸ-Û,¼WçGþ' Úq¥¸‚îæ}Åø_GW«ÛÅ|÷êúæ¶â•±lYŠzù޳›7ÿâï=õGœ“wÑvÌ,ùËÖ·»Ý»ÝÓÁÂ3{Û<±ýÏü¸_|Õo½ì7üKÿLJn»•/5ͯ×ò²­XÖÏ籩De”lÝófÏf€x€“�:A½gg¿B]¨÷Y^ÔîË’7€jß¿ÄÍ­Js“„%Á ÜÀÿžÞŸiÇ IAO‰ÌÌÿ—ûQT�K÷�º‚™j¿LÈ£ÿgŸÇüšÒÊ©l^^yÕƒÿSœÒ]ÁÅû"èÐ;7qbI̪Xí€^½.ªšÆˆ˜¢ò01ˆ D6â_â ª“�1²ÂWÇ£)åÜøÚX°8 C³§�qJHQ�û ÒŠ�Ø�­¾£¢ öÁaÕvÞÈî$Ú’_ßdØ·jãüYfHi*6ýDn¦NV[òPÇëì Âæ `–CDy¹<¾w–Ž€DIIìà< S��#�ívƒa á íf=œígþSdÈvžÂÀFÄsf�b½ž•Ö̦8 N±::8_-Z¡œS‹‚‘ÚkÞ|¯"JDÉÑô¤§|ø[ßö¶?y+3ßÚÑ”q„’ôÚaa—¿GÒƒ:bIÃ’Jn“- ­çOÓçÎIõ»×JÖàüy,@äfÑ3·¤U ?áDþÅß×Àw2Ç ¢fl° W¶Q"íªÏG8ކ¹OHnQ˘åÿÀF�z?´�ó�ê_|Qš«€3Ä«!d…;<(ƒýn0èßÈ)ð�Aßw^ÿªÛÉ.ŽàØ›hÌ7@±}~ÚWå?g¥?Kã �ßKsð?/ ×K„€D±>2Å¿©ñÓNsS9 ¼·õ‹äX�¼Þª~‹+ g“Uydâ¨Ë&[^¢f• À¶_ªú';Ϩ üže?»ÿðÞ–µ;nþÏ@º þ/&×lòYÁÿ2ÕØüŸ€hñlw"™c øo@üùDgñz/·ûRojåYX³ oc¦É�ûñÿñÑÀíîpvH�8?<EFJ‚aªóÎ4"NÑô4T§˜0!xÀ¹ì ¥Ž)±Òv‘½ÀyRU{Ju¸'ªÎOœTin sV!/Çß)1˜GˆøÙXdȶû¾YÎiÔKÆq“ J‚‡€9Áq9ýÁ¶>ˆ,t¼áœƒ źԢ?NãîÑyŒÓˆqš�ÒT DªcBLb„ Q(Öýz ÚM1!G8äcÏ„ªºªÄösòC~?Cý¾$Ãì» s©ƒ#;磈ÄÍfû›G‡‡·®Ž#Š£M3ŠXpEsoßöHK´,$Xw�c¿_5ø²ˆa›uð(Drvá-¾»ñÞPç|µ*Z•dO9Iæßôý-A@Ž'œÄ�\7ŒTx¾zàìÙOuÎýtƒ÷Á“wN¸Qû+áG£7¦iÂc%e—s�X#Æ÷êÕ«W¯^½zõê€^½zõêÕ뢮5ðÿ©ÅDÈ€ËEä*¹áS?Ïýü�§ rZÁhòUýc0›þ œËà¿YóS0°Ö€üb÷Ÿ�}u lïO¤Ê~ ö™p›Fõ?ذĖG˜eÀ+øßl¯% `aÕoÿrùËû©þSq(àù,è.¢)ÿccù?²óh€öhÀÒõ")+õëä!»&8Í5-6ôÉ¢&]wš,j : ’ïätR:O\fÀܱ`fûÚ€ÿ²ï[éO³‡KërYFð-ʧà&ì)ÿõ9‰v þ[d­—ǦK¶Ç¿f P P sþ…ß}ìwì&w›÷®€ÿÀÜ*7ÿLÓX”�a@Dj=jêÿü̱ÙýÞúÈÇý_o}óþ:€ à¯ã¢Qÿrµa͵˜‰ÁeqYò½ZjK—|ÚSåí¯�޹Udÿ~^Y¦ÞU²Ç99†™€ýYñln¿ž-LBMþðÊZ–¤Y±ûoÔ†Ë8:æ–×sxÜ5ª9É󀎿cWsæçjþßÿ<¸òÁWÿ8€{Ü#ÀY;mm¬ÍYF…ôêÕëϽ xé\yÆ91GÄ)ªÍ~R‚€ÂJpN³à9iCƬÊ~UûoFû‡�<«ú×Ôÿ€‚éS£›²Ýyë�9%ÄH ‘ªÚ=õÅö1"YÝöõB\¨Ö¶>…Ô)€�¸0aòSŒØ †Í€8làMAïe2 É,Keã°l}¾ŒüÊË) ÇÓëøjœ¦ò™1ŽpÎ#¦ˆ£Ã#îÔ9!&pR°=%.ç2&Æ0œwLm­1 SLH1"6 ß°ì}?9ÿ÷—:.cs„PPW÷ÅûÀιIDâ©S§^~txîK�uJÌÞ_ö’­¤ãÙbC ý^ óî(;‘leÿ80KhÏA3œFæAS!½ÌÇ4‚J«Ê—eÍ·ÑnLV†8Ǹ è_Qüøñ í,V®PIØrÇ œö·ãô‘ozã=ø‰O~êýÁ{OD‰D$·ù‰1b7Ž˜Æ 1N3gŽòãÈÚ‚Ôç^½zõêÕ«W¯¦: W¯^½zõºˆëƒýÛ’jsz À•"r­#ÜòÂÏÂW~ÔäSICÛ <Îà¿‚ó ܇ü�²Ä¥µk,ÿ³}PBÈOaþoì}#d'GÞ–Šå?¹šm/1,²r¿‚ÿ\c²ò�1À\YMO�b5à?ÛþóNRÃ\xÔíð�Å ×õ‚¡S’ÙµÀAr|�€'ˆÄªòO„Gêyªû˜,>€O„ò±ä €_õ&]€ÿíäa•/�ï&šÿ^²q³å¿:5ð?™£Bÿ£žsÔ‡+DÀ|{�Í«E›Êž'žÝÌ33‹`î7š?X¼Ë[²ˆào¾ñ'ßô§×¾Ê9¼Àýyɨ!­ °ß’â„df;$ÅçÇÆÎÒFðœßQm9T˜ìEœÈ!�…S@Z·ùk¶þ+c4Ž\Íw¾�ã,û÷‡?Ç÷1«°l¬½efnDҼƉ»þøÿÓžô”§ý DNDRâĈq*÷ën7bwæ:’ŸÇúLäç"¦9Ò«W¯^½zõêÕË\ýôêÕ«W¯^o]àØÉ*}ß‹È)W¸îú«ä±_÷9üÍ·\ƒÇ(Hoªz¿Q›~— ø;74Šü`*~§ùõªå¿#€]±ýWp_íÿ øŸßsÃ1àvSý;{Ëÿþ£þh^KRU¢/iügµ½DýŒcÿ3X¯’ãR0iT°?íÀøÏëãÑ>›�®˜Yéÿ‰êv2q@’ÿbŽ)¹ éDeÿÁÕV@œƒÿF˜8Vù/r¾ùÀææYÏ…£ Ø;�~P¢GV¿ñ"&H´sœR±ïv¾¹_œo" –ÖöÜ� •—4wDÈÅ2_§Mò€7¿ïŠ_ûooxìÏ;G·Ñ=Ì<–ÅšIíç¹£a0rMUÎ3„s<@~†óø'ÿ�?~ÃkŸàø&›ùö ûj~Z»¾Ù±÷| ´½µÿ±Öý–>ˆý>þ(dE¹ØB´ßN¯>o €¿° (® K€vëRM‚—ä�v)û8 ô˜GsH¹'´)çãbBx÷£û¸ß9wÖ9Î;ÇÎ9&�à7ˆ^½z] ãSUÚÜ3˜MD… äLÙî· v\+"�$ˆ1aŠ“Úð'¶üødÊ^ÝŽóïWøLÌ˹õ &€8©Âš"$%ks À8ïJü@ $Šº€sr¶ª÷œMÎÙ½@ �»a‡ÝnÀ°Ùb ÁÃ"¥„˜’*™§ cœ4v �1lÜ0 ¶†€ÁŠ@ƒY�)Ưà|=§)™‚?ſܯq‡Ãà™éŽp [sˆà¤c˜Ó4a·‘b¬ÇÝ(®€õ`À‰áƒ¯€T£|ð…!§ ãnä¹€E$ è"ü~b~Z²Éœ�²@ËÉ¢  áRª½¹÷<}dï»ÓŒd²ô¶—yÔÆïH+ýçùÚóP…š1‹ÌH�ó¾r>´i#ˆh¶O²:<�Ì�™š°ÇúÇvâÇe5�¸^Á>ù¶]l¡8÷éœø'Øñ@$)¦$1Fž¦ ã4a'LÓˆq !7ßã4a3NÅicÜéçzõêÕ«W¯^½zÕê€^½zõêÕë"®5‹Íy~¤¬þÍúø-€3"r€ëžõD<ëK?I¾é’SteÉ¢§ ªÿ Ð;ýQà_•ü Ðþ¨O~n÷OÞbW� ŠÀPÁ}?€òº|€âŸFhìñáÇf�ߢ]-A Û– 0XâÂò¿QÿgÕ?,•3!@"7à¿ÙïKµü‡6àÿT|¨Z_r|2å¿’'ZËÿlim ¿D î 2ÍUÿ�TÝ2€-Y(ïÉÎ3 üG³~  †:k|Ò ÖÞ=ÀBUµ§×uTݼ/9´vó-Àµž…M⺖,’—Í®³ ÃP,À;—Ÿ‹ÆMÀ抣æ žŸ;ؼõ%/Ê?÷·¸ À¡>>ÒXøó,׆a(ùÅ€)³¢.éñæÉ|¢š«Ë|䳞}tÅWüýÿòŸñ§ü+ŸÐÛ8ƒý×@îæ÷“æ©W×»üeæ|AûŸ›)Õdßf¸É ®mNÀËr4SìÏÚkA!ê‹™gq 56ÈY¨ —`þ>?a==cÅ•€ªEC“½\ß[',“E°àu¹ûöðG~Û™K.}Ýï¼?ç¼›|V£šê5+bÿWÝpzõêõg<‘Bâ™ÁºaP"€µE‡a3`»Ý–þ�%;KuÜ ˜Rr RU?±h›c}¾Ëm_¶þOµŸÎ@ºH4ðp‡££Ó4ÂðÛ †Íð1Ò›j¸k�¶É, ^�<¼gëçDbQË�ÀÃsðÞÃya%(LqÂn§6ýSœ�Zâ`8ØnA"pt ¾� ”€É¬JúqÜ!Næ" ŒÅ–¦_Ñ}t1Ú�JÌR}‡S[s6�¢¸VâcÒhƒ)ÎH�™Øè½ÃÄÍÃὟ��r{í½/N"R�ܱ€°0§”ÈýŽðTÒöu‹ˆœBа¨œ¶órúµ4χŸ[î ¾^ãEºˆ5Qkˆ<ªsM^F‰sRœ,d±\ùJ³¬¬ ìíx¡nceg‹³Š›íuÉû°|=²; Òîÿr[ù¹\¡93€)Ågüîï¼òú§>ý#ŽÄ§4MíÆQ2øŸÇÙ™` %©íàˆJ,À4M8<<ê�s¯^½zõêÕ«Wû½­Ÿ‚^½zõêÕëâ­ÿ ÿêo†á9?ýâûBß àúév®Þj'‚ËñŠõù}‚zOØrXnke»eú=Oöcno[“'h¶€,@€ÖªŸÍ>ŸUùÙBº,[ìŽó³—�´ ¬YøS~öŽ¢±Cžö1@ýy®Áq¢¿%t’÷&»–´âJrnwËCúm×]Ãë˜ù.":°|@pÁ9ˆh~±+ù¾®zõºˆj¡f×£‚ÃðÑ6' Ú&8S´o7A�âX€åXûXr€xçìGûNíPÙ†T!ËF±¯Q¹�38Mw#ŽŽÎaÜíÀÂðaDŠ[l%�9™K̆_‡7"•L(ÐñCâ'Ž‚r-�GdC F¤„”Â)! „ q0M“¹8"°¹¤ €Í)IÇ ¼#l†`cm É;ø N #L¦i‡)&Héiô<:ç Þƒ™0M »Ý‡‡gñÀÙÃfƒÍ&Ç&¸âg}J Ó8b7ŽeýÎ;l†�Žiâ„! pFì@ƒD 8ï Q$»5ÄiÂ'sŒ¨c-NIbŠ Ð«Dä…RÈx¢ÑY‹ŽHª÷}�Ê‘ÚG:0„ÜÌ ÛñÛ0Ù† RÙ³èoúêÅXzæ´Oóïg³±µÅd>]îïeÏÍè8É}/�vÖ–XÈÿeñ=±äø­.ÖO”‡êkNæE@8�íÀ^¹?yË›þÊžøäfæiœ¦8�“LÓ(­ —p%ãpb`„ÝSQ-Œ°ÛízãÜ«W¯^½zõêÕT'ôêÕ«W¯^qíY¥6?íûm‰È% à†ƒ ò Ÿ'/|âÃ噊Âxy��òªì7å?¼)ÿ Ü'W‰Î^k²8€­›€Ò¡ªú),,ÿ øGÝ&S‚3²¥=£¸�o.æƒDVìWðŸ–ÿYɯ`¿dà?ÛáÛò@£úomý9«ÿ'‹ØUWdå.�"^$«òó>ʤûcäI“îO5–@r~eUGIVâ8ÂZÅF( øÏ5ëžJàùÍÕÞ5e¢R ­ÂžNþ3‰"q!@²í?i®¬süçû´ß›mö¿�pÍ»›�Ô¬¦vn”*¢î ’T¥UTf‚1ù£ø¯Oý[ Í;œsï#¢ûì–ªÿVñ–ŽÃ0à’3!¨unœ¸8j¦ï‹=nj�\ò|í§ZÞ:|é—}ÕϾä'~ä?øv_ÝÇæçk›˜ÜU4š·zÓ—‘´kø7�Uÿ ˆMdÏÁ²6�Š@1ëÍÄ„fÝz?Tûä6¯¸¼O2 Ê4ȱ+†sòÁq}K~XiÚsrìÜþÊ«µHëVÐ ‚œ¥MçnyÈÃþáCþÈ—¥ïpxïÏyï¢.¨�¸Àô7"@¯^½.žò>X p&þh´¼ó…眪ÅÃ0˜R\Uû)M%Þ{€àÍ9'`6𘠲w�<î U·;çà�d 9öPE¼è¿1ELi‚$m¤RðH1"yWö1£�w3PW�]FJDÞ+øï]Ð!QÞ?Ø•  ÜžA­Å9©’¡‰°~A²úÚ‘3}(cÿ8L“Gô΀~ÛG‹"pì Þ)y,ÛÓÛ11³ù(á‡ÛmÀfØ`³ÝÚ…̱À+ÙQ,�}Šå‰¹èØIàóy·ã®6íœR!T5fišSDœ"Ç“�{ €Û¶�¢¶·ã’%p.ë}ÜRú®ÃL6ÜßY9˘Ùòg°]‡¨²Ù3ÊξŸi˜]¸YO ä7´ƒõîµùÞ·&öo÷s‰¿K«·Ì÷|qT»°þõüNLò95å:<<÷Ó4ýDLiœÆ)Žã.)¡–WÉîùýÄzÿäñ•Žß§Þ8÷êÕ«W¯^½z5Õ'{õêÕ«W¯¿@µFÈe“ˆ—Ñ5nºõz~ò ?ßxý•¸YUÿ Î~2@ÿƒYÖ‡ ôg�žZu¨Q° x&µöÏò“Ùÿë°#²ò_•çŽa¤4Êÿü´ÿ¦6ÏÊÿþÇB P€:+û ô—X–0€¤À¼DéG€� øŸÀ ¸¯öÿRât6‘¨‰1È€£c›³›åš Å@·©–ÿ™´1fZZú@ß»+ªÚ]جI3 ß(çe1[yBÕÌoøL¡ªÚ窾CJz>ðlãŽð߉`‘…^f+ÛìÒcf]C°È¤„ìP€seH©ºE!2M?ñ²Çý½³»3o Áý©sî^"š�ÿ)¥ò£›«àÿv»ÅiQ{cÁ!ȓؚǛR*?�-ŸÈQc“«ùÆ_ô¥_qï8Nßðïî%?àŸø”ÞÒw_š9Éÿmž�%¢O´.ôŸ}ŒöðYá å}Hß®K*y€š }jí›ó¾£±^Η[¬G�רóõ'¨å¸s†½vc%Á~“½ÏJmÑZc’F}Ù@BM^²Tçxçîø£óozÈC3Žãû¸D“s~ ÞK�ˆÜ<úC¤ßü½z]tí1�a6þœy%<ùM€#7ë�³qì®¶òj?R{ý°Ùlªu< bš€¨ªw™ à„�a³)î<Ì ò®¨á½s`ø !Ï;_sí¡Êyˆ3^ª“µ])e’()QÁ«º>øçœóp´ƒs¤q) rn²½ÿ0là¼Cƒ�rûJ@JJ*t^û ]¿Ç<†íÁÁAT-©*þÃ0è¹)c)š‘ÈÚvÍ"G¸‘¢GÜÚ²[ C˜YýS1‹·ã`*l�M2r…�¶í÷v ':vs-¢!?$sÒèÈý! ?e¯�j0úâŒ*ý¢Pí×`íºí62@ɵŸ['ÌVÊ‹Þq¾X½Gi騶¾~:F‰OíÈØ>¼F(ëiíûQÇ1{cjY�0ø@£–þL¾×ê}óäßýkoyÔ£÷æ”âÈÌND’� Ę@ĈT‰·™ЫW¯^½zõêÕ«V'ôêÕ«W¯^ ús":p ÀÕnø¤—Oú¼gãkÎlp¦L”¹Asã]c¿ï²êßé{ ìÏ ÿ Ã…øo¶®ù}gêßĸ‚¹ x‹(Vþ¾ÐÎWËÀöÃUËÿbÍÉõ5,qaùÏõßþ§ þ/DD­]2Õÿ%ÌÁˆ¹Ȥû‘ ü/yžš«ûM§ÄBCL@v˜ <ÖíqTg‚d¤‚-×Lz@‰TÀÁâ†Ê�ÍgVÊ,Tg¥.XAÛ€ëÞ¾±_-à¿Ep«üg½52À#Ÿdw[Oö`eû%ÿž'/™µR]Ÿªµ\cû�ù²œLIÇe•…øg_ùèôλüêü{ˆèG""-øcµ#®Jþ€ív‹ív‹µÆwšI:N¦išMzç fo`Gž”Ì@†*Þâì³äŸóü/z-súÔ_ü?÷)þ€Çõ¦í˜ÛXÔÒžf†ó §5[É/Àÿö†lïM,ÞÏü1ÖMÔ@ÁÐ Y !­H6¯ bͯë”BZ˜‡ÔT�FŠ;A¿Ÿç[ÞXUü7ç-¡¬}Õ­}ñ¾r}·> w=æq�ÿG×ßtóï�»ñ®Ä|gA$ù9qF” ¢�‚usä^½zýù–@�ñ£Zr›ú?µ”÷¦ ¯®7dMŽYÄ;U“�üp>¨Ú}3luHÌp“. A�H�ôÍæ›ƒ 6FP{ý„aØl¦ikÛ%l6`»=(j÷ì²²´d¯®@JpL…O©ã<‚66Û-6›†£CìvGÇQ‡o^Ç9a»Ý`³Ù¦ÿ—½?�¶-9ïðßWU{ïsßëyÐИ �¢(€–L‘”¥%†² \±d'Y‘hɉã•,g%Ëɲdk)qdY”D‰ER Gs°(Kg‘1óÐÝhôÜï½ûî=gWÕ÷å�úªví}ö¹ï¾FÃ~jÔ¯×í{ß9{>çìúNý†oìõ| œ5½Gd.×Ð9‡®ËÛV™R €®ëp¤) S2e¼3úÍ¢¤j©3Óêã²OççôŸ2æ–±\ ý•2¤>~“S"ªÖ@zfur]ÛÈRô+‡…箿P¥$�cT(—°wžæóŸýôw¿æµ¯ÿÎZ¦ZÌ“ÛRÌSdÖ¢‹T€äl›ânhhhhhhh¨Ñª£†††††† °tÛT 7¸À�Dtß_ü.þ3ßòµòÇ-Á$N)9ø‰zuô»Šü¯\ÿ™°ÏŽþëŸI{c 1OY`PµXFþwÓþŠ›ßNn�üGåú§©Å@Mþ—8øXEþWÎ~I„ÿµ¯Î~‰E 0‘ÿi™Ò æh~%éÅq›œÿJÚ§Èÿ´®T„`"Φã˜B¥åcì’Ó?ŽJþ³Š ô˜Õ,e‚P É�4±•vUÙ�«ÈÿDÆ×" \›ð_:k”ô/dýò_D“"kâ@Ôk¨ûÏä¿1€:ì&ò??O “EI‰ûµ¤ÒãYÛVJ>(±ÿùøt5ñϼçeíã_¼ç·­µcž$¢«B=¹Õ=—�zÙùŸú¾Ç#ÆqÄv»ÅÉÉUœ\½ ?Ž`–Br8%0ò„wq©iÿÛÝ8BDÐÅ©ïîä¶³ø¾?ýçÿÅOüø?þ×þ#ÿw$QOÃâ­š3æ©òìá@_ûÒ':OË•‰|Ôù9’Wdù[ö›·3›±_ÞŽ×&Å«ipÝe~PTA�T‚¢擺`¹ÄDÞ×ÉsQ­ô@¨› °Ü‡ÔZˆÉó/+‡˜»sPºö}ÿé7¼éÍÿ�[o¿ãc»íö©Â%9!‚XëÔ©«DavœFÑÏ%Nihhø_´.eŽˆÁ‚N4B?�‡‰Hž'‚HiŸb�œƒX«åG"ô]ç0t¬s…Ð'ˆ¤š)‹�Œ!8gÑ =6}r®ç{E"Ö;ôýaÀ÷Œ1úðÁ0 %‘€µ•ÓMîwNÇÛ9X%�6œœô8=í°ÝnÁ1ªRk‰¾+âk üèaœ)×ÊlOb€1©†p]§bˆtÁÐ$ 5ÆBDª„…Dì{ïqzºÅn—~¶Û-ˆ¢&$Q‘A >øâÞŸZ̉Uk-ú®+ŽýÎ%QÂ0ô©Í‘’úQÐ.2kýÐ÷½¶u˜ZzeAä8îÐ÷;ô}'Ûí.ïC·¿+g­{&aÜ| ›õ’jŒ¤õñÌPúÞ‘Ú%¤ä ©·Y Ò°*0Ì©��ÊÑ,™Tª”�<ƲŠxIêëŠ<ð§ã4TR´fÄv®ÿË6¥sz0¹ýË:"Õþ0 ´•­èôV€•vóºÆMé>׈ ¸–Р~~»=ýήs×Xc­µ”„+aæê}#'8äó/©#Æ–6# š ¡¡¡¡¡áFéùXMÊ-È�›ˆè./¹í&¼ò¾—ÿ¯¼OÞ�É©ä–Îä½­\ýMÈ‘üdtJ®æÇ”¼/ëeVú3ò?þTD}Zv)ò¿°þFÝý9ò_�Ã/ñð‰læì ¯ÝüÙõÑH}Qò?(I^/ÏV2Jüg€ŒºÎà8j;xÝF„d—7 ×(“ÐbLq·%áAHûª�ÿù¸ò1qD«®¢ŠüÏÛ¤,”È3é™<çtL¬‰³ù:™èÓ»êä¿Æpgò¿¸þã;ÿk×Mî»4a?hïb�qÜáêÕc\¹r'W¯bô¾š„OÞÉe7µYâý¨„IJ p.&±€up�ƒÓ˜ä?ûýÿQˆ1ü÷?þOþá�ø?øO�„> Õ[öp�}ywÌßö‹¦½T9ÞóûoºÇNýyÓöÕUWÇÚcN’¯Òÿù­N‹ø~JidH;‰L±Í‡&Íg{¤Š¼Ÿõ)Æâó4}–rjë×ÛZï2"³fY½Ê9Õ€*Çæ…‹7½ë¿õüucìƒ~ôOxï�cWkmÒ–•Ì(áV tZ¬oCÃ�ÇŽA†RUiˆ`,ÁÚäÚçª×xº&ÂZŒ�­œÙÆtÖ–[9y3¼Iu ëvTtgµÍ€sIŒΪ``�!ô,pÎa3l0l6èœKÇÆ ¯ãq ¹µÓ4Xap%â“È`ËI· ‚µ½áÞûDä[ÒV¹6 $lÈǤD¸1Q¸$1G�O‚ k§4«i@:AÇÜ 0&ÕÃÐë9uaìv#Ž��q||% "AD† .\¸ç˜#v»]I1‚’öËï)™Á•ß}ßaèôÃç\qô‡�’�˜’PÖ�)í†aƒÍ&-_ÈõRyl·;l·§Òw§¼w‘Ù¿ï™§¼ˆÍǪe!0•¾óD�ù ,¥-BîdeŠÐOJ-JZr}OšlÕR‘ ’pÊÑúTÇþè±.ê�Y½R·)2Ì¢"ßLä§Ú"­DjÀ4òN5ÍÃ{JKRáâœÚ?T3í3t °¡ª]='"½ãë?þ±�Þÿú¯þšcîØø0î¨tQ¾%ý¥¼— ™"4i€††††††††9š ¡¡¡¡¡áÆ’ø_n&¢xñ^.oý ßÍùŽ›q7ÄL“MäYoºâæ7ŽŸûÕw“H9Æ_ ÿâúOÏQYަer‚@&ÿM—¶‰ê¹ÚõϹ_ �þÍyïyùsÿæÛL9‡z0Âüxæ'�Ä Ù9 ‚1Fîºëî_ü–oûö™¿pºÝ>‚Ê{ï™ÙgÒŸôsgªhfΟp gnCCà S£Bý™Sí`RŸwgSD¾ˆ‘+�@ÈÉU»’¡ÆØ"2ºÏÆÑ:­‡«±;×�µ{½SG0¡ï t}c,˜¼÷�/2ÝgX¦QC*×µäÚ«n`S ~&Ïc ˆ!‚È€9”t£¤®| 23ñ“1d¸,o5ÅØô<0Ä calBç6GG¸pá†a€° ¶I‚ÃívW]W‹¾ïqt”D�"‚ÍfÀv»Ã8޳H%¦_¸\KãºÎa68::Â0l`¬ljü¯ïÓ¤-”RC"gûa€Ó×#×H>ôý}߉sŽí© �ë»ôôS¸œ§½–6y(”Ï_ðY@P‰bóøÉFÇb&7>MÏç„!É¢­µëýMç­‚ Êm Ìþ¸5ûSE¬nöÒQL‰ü2¤)Y¬SÒJ:A¾9 ©ò?Ÿ¶Y¯·Õ4U {©×l°ÒÓà¥Üg>ýÉïøº7Ã'™ÙXë‹pVdú~S³Ö"¤i]MÐÐÐÐÐÐÐаD444444ÜÀÈ“pú·‘À ?w¸ÿ�ÿùãßóVü‡CG¤šµ9v?ÇÿÛDþg¢ ^É ›Hý,H>'ÔQþ¶,GH-`Ýv&ÿëÈ“òs£MR© ûél ÓÄ*â?9ñ÷Éÿ ¦øP‘á‰ì—ô<ë¿yT¢?N±ÿ<µ`]·r•cšˆKçÀuçL}¿Óþu[q—\ÿâ5öß—‚4“›»ŠRÿ‰ü/QŸfAþÇL /ÈYºcuÚ®fë–-Ók“ß+9ö?Ûör,Œ:é­îz^DõâRÆ®“ÿ"S‚@Þöò j•&¤k ‰åý!åË9LˆBá§ßýÊÿׇºÿ7¬5Ñ"RÈÿL"d"ÈñÃnê»Û÷êB´eBñt{ŠÓÓœœ\ÅV�sÙùï\ ÔÎŨäeÞOMb¤—„à¬-“Æ©§°AŒiŸÌŒoù¶·?~rõêúþ÷¾óoø?ø�\lwÈó¡ô ®kk÷Z©èž5ýì³³¿“¹0@hz«ªû•ë¼™3úÙµ¸æÿß;¢Åy¬güÖ‡_w;Ø;Öz'+§(«G3q$“p!“W/\üðúŽ?ò£žýø€g˜ù˜õÞÅ9£`d!–ï å³S}Nn ³ b 0vG�µˆ@œ=0¬ÖÀi‹€œbô’î4»7GæîÇ�5Á9Dpä’õ~á\§±õêDW÷?Œ#ÁûD\Ç0¯R• xH¹uWâ*¦žå¡´1˜㱺ŸŒÞÃ1#0#h�À¼h}”“`ÎH„Éûî\W~Ò~bªKª¢ú8“¸q27vJ¢3Έü)™€U hÑw=†aÀÑ… Ø ˆ¨2»¼¯O¢ÊC?hZC:>AçCN?"bÑŒµŽ1Ü�¥fuѲ4# 7ÍU²$¥ífŠ« —ªªÞK÷~‰Ø¯’-’p­.¿×“¦9Ú”H]þ¥& )A€ ³$`1Ì«àNXön¡I` ¯'U‚_)̾¬–2kï3‘éD–ˆ…×uòÿÀéÉÕ·m6Ãß�Ì[�³£Ôß…© 9çf€ü^«ÛL4444444444@CCCCCà �ÊñoDd@Š¿ À†pÿ_ú“ò¾áuøw³ùœ²›Þš*Ò¿&ÿÕÍŸSJÔù_;ÿ•†Óú*€ `z%Œ{ݶ¶  Ü"@' �I® 1Õ í“ÿyBJ2a‹»?‰xAþ§8}É„iPEí³‡ "üyœˆzŒ@L„?gw>F€"Œ"xòá–8Z½¶R9ô%VB‚G%ÿõø‹€AÝ_y�L"Á«¨þ’$�Ë©Œ›¿Oþ/(B©ˆÎC}ù_Üú˜bú%·[ˆ¼¯¿œmM3ÿiÒ4 hrëò? ö[Y³èðº‘xýž)ùæzîÕûEOtdÚþð¯}ÍÿõágîxŸ1ô€'DärŽý¯�øÙñ•&·]ùÉävòçuNONJoÝqÁ1M´;ë0 †a×ÍÝÿyÒ2ž¹Ú¯µV{ s5�é`DàMŠ9©€#¾ê«ßôˆ1ôŸ~øƒïû¯ü€ÿ=€;Ú�ò Ð4a-Ëøür£EŒ}‡ûÞ_Õ#•ë¿öËɃ¾ ίX�kòff;:sÁëd¦tƒ3·½<í|Î 0Et7Ý|óïo6ÃÓÌütˆá2€‘I¼D¥�uÕ›¦c(ïý" ‰í½ÜÐpÁ�I¾!�dç¿)ýë�5ψe˜V2mÔ�o*í_�òÃ3±^&ÿGŸœÁÖZk1îF }_Æj®Rú‰üúÖ:Ä@&”Z ¯ÛPD˜¢äný2Ý®e¥�ÑtL‰&ÓµJ­¬÷#0GŒãˆÝÎ#?Õ$B3¢[�Ä…”�Tló1¢$"„BDÐû¦T *‰èO©ÖˆÄØ¡ï÷S8Æ"®(õ‰ù]©�L-RÞ«ëaKeŸi�ë ykM"l#³Ä؇cŒÑ9÷!Žá�È,9Ÿ&qh-FËNüÙ¯5´°ÌÆÚLìS•°CÕøw–Î/Ÿ Ïr:¾—4‘iÌžªÛÔž€rMN¥ÎžÜü2Â)' ä´Ÿê³#u’×Úà?+êâa!(¡*éœb€kÖôìËïÃ×æÓŸ¼å¯|Íå`ƒ!¢XÞ[z�s²G×¥$�ü¼1š@BÔnÎ š ¡¡¡¡¡á†�$"=€›ÜED÷Þq+½ò¯|¯üÀ+î“×& &�$÷HWržºô“ÉÛ!÷]I(Ñÿ4ÂÆ’Ÿˆ”اI ��û¦‘Ó}äm»‰ü‡.–S ù_'`rõ—Ù"ÖÈ™“ÿ’œþ5ù/% Vät,�%׿þdç?{@ÆôXL}–˜Äð0J&³(� 1^\è”Hy mGrÜ¿þf€u»Yà�'‰5¦´8’ë˜O,Üú™üÇœˆ_uþ׫ɾ¨{uç›LØ›ÒãÂUÜL ²âˆ®ÒȈêÏëä¸~,\ûËãÒãH®ƒyä¿TÛÀ$(Ð¥N½{æoÿë¯ÿ+—NŽ>AD�Ñ3"rÌÌ>ONבÿÀäü¯£ÿó¿—Dþ8ŽÇ]é—+�ù¤xßÁê¤vˆ±ˆ ꞷ饑â¬ËÛÏáÉE8M¨sœ§|Ý[ÞúÄM7Ýü_üú¯üO ÀŸðW¼ªÝ1÷AÕçiæ ÇâãQ}gsêe*¿Ó»›jÝÎÔ§7“ Õ{,FK“~EM”Å‹Ý.Îä¹�ÁÏêÅɈ¹HÀjïßôkÝäúL÷…{ï½ï7»ax:Œãe"s¢0ÛJÕ»7flùœ,ÚgT© 7¬s°1$N b¸Ntº2~Æâ*רt R{ÊâPLBÁ4N§G 9?ŽØívØîvwi N}é Ã0 „M„Á‘§öÖÂZ‡NÓyÈ$bH¢‚q§ø*È.c¢šÔNÄ¢­Ò ¢Š”Æq„HCàG�FD­OE¢þb0ØÑä²1Â�㸃Q�ô¹ ³€CDð>]Ÿ(éZ„Pz¢‡h0úvç’`*x\½zŒË—/áøø*¶ÛmÚvdXÃEèÐùt®Ü‹'!–™š¸U踿¬�}W‰1"†€È±Œ—Q_‹¥0cu„#"b"Š„ι�»ªüC"ëó�CD³œ™¾·³ÖE�YÛ_+á§ÖЖD«œ~cÒ¾‰Öt¶4k1ux8?ߨ¾ÈÝJß“–©<2ã¤( V¿b`+å1ºÎc<\Üë û÷üÎo¿íU¯þª#"+"ÂÌœE,d¦‹®ëÓg™§ú€##´[sCCCCCCCà MÐÐÐÐÐÐpƒCcÿ/¸À=_ýrù¦ÿí¿'?pÇ͸ R÷�¦äR/ä¿Õ(rÀiä¿Æ½›™ÈOÿvS¼?l"÷�:ô3ñO¦¤P,ÉÿÊõ=61•#¼&ÿ¡¤¸T™� W®ù8‘ú…PWò?§°Fë‹GŽÿOÑý!‘ýQIJSâ_ÝþÂ�0yß"JhͲB'g;ôYŬb!¼KÿŽaz.Gþk·\ æãë)·zbtIžç(þœn€òŸÖÞ<•SŠöÉÿ%aŸ‘Ïn3@•+ßÝÎ ù¿JÚË �ãVi± ³ !‘ÿéßOo>õwÞñ�ÿY`÷Ycð€K¶ÙùŸ‰ÿLºÏ"CuB1»þsœož¼eN=nCåÞ7ê>ì:W¢H³ó(“ûµ›ÐjÔÿÞdðÒ1§nÊÀ«m¥ã0U¬ïwý±?yu³9ú;?ý?úw|7€¿ à¶»æÊ'ã®°:Ò6;Ëk…:޹J§8ÿ]¼Êà¯?Õça!®’ý]ì�Ã"º@ön+åä4o–< @¨âŠ©jBî,º�…·°y}×}ö�o~Ë{ Ñ%"s•ˆ¼É侎 …D²ÓoÊq¾ˆyìCiÀÒÞÈ 7rû›L'G~rÿw]Š£�Ì©·=¥˜õZÔCËÛh.8ÕKiÜ�Øí<Æq„÷#FpŒpÑu]›Ë«®j2‰°/‘óÖ•žõ%ŽLÛw;ø�ZIY X±‰àÖ–&¹–5UÛŽ ïw‰Øí,šR<üèÁ*þÌ¢&f†=<ÒØc„÷Á‡4Ök“‘äê�ÌðÁÃŒV€êαˆ·‚¶»S`Œ»._¾ŒK—.ãøø ¶ÛSŒ£!Z“–ÝîôZ sa›©ê—á}˜‰"Pß·µÉç‘…¹¥éX™ÅS;�ˆ’@ÀŠU±d¨k&æÈÌÂáÂÅ›ïêÕã�_¨íEëœ<>&‘WÍ|¦ñoj@S-¾(ŸW[ßTšW9¨Å“Å�\D𲓽÷“P J *{Ÿú¼Hþ»¸ÿYV‡yÙûk¿5­Åÿ­m䬇æç;;§ªÜy–÷•ËW®ü;~BDºÈÌ1FfýþA¥fw°.¥DH”’DÑ´›sCCCCCCCC…&hhhhhh¸�!"À€[¼à;¿ ßñ§Þ†ŽRÌe¥o­þ�H~2U¤�U²_…üï§ÈÿLæ dÇ¿ŠÊó¶«¶mΓú¹BBÙÉ]Gþƒ+òH®û:.?»ûÕA¯¤»O®t®„¢„»@Pçù�ðN£ÿÃÙ¯- ù_.|a¿è=oHÓbo!Q·ã,… �ÿ…Tä²-:лÕ2"eV|9;õ¦Ú*ò_Å"…´¯‰–’¢ Ì•ó¿žHTbž ÈÚô>ÁÒõ¯Ó•\ý]X¹ÇnåZ\ÿ¦j€*B¦È,RøÐÃwüÒO¾ëkÿ{"ú0‘ÿyR¹îe[N£8mqÿg×?-ˆüó>¥ù1k\JN@îsa£� ꔀU€ïý÷ÿ?þün·ûù_úÅŸ}3€¿àûôÞÑpíOÇÔc’D�…c/'9äu“æE¬ƒÙü»h/à)Æxj°zÏ×mÐËÌã²ëCÐÿQÌLÇ^D õš!4#+¹!§?–½’�»_ð‘KÌ|…9nD[‰m¤ÐÔ}¢­uÊrÌ=|,Ün0îÍ{pOŸs{}è—ãX-4ª“q2YìCD#¼÷‰�Ž1x˜ÙøX�í%n¾vÿ;;»§g@„*ÈÀ¨àÓ˜)•$Eû'1CJç GÆ8&ái:s(Ç“ÆþÔJ+' "\#öEÛXR" i]}J€hºB@‹ºß MD|ð1\½z—/_Á•+—qrr’Ò ˜AÆÀ9;�øç˜ôõËír»‚t½Ó½ØÕÎ;Õ3u›¢ºe€1&µ'Pñj¾Ö‘;M/`›„¹^Š! 3‹ˆD‰o¾õÉÇÿâc"ü‚=ѨÆá/ǧœ¤C ™iqëëëžÓh™´èUïÛúý:ñ2‹ô_P³?OšXóYRöÉÈ"ú¾ ·�užʾ*�#êšdúêS•×™;´Ÿbtð˜Ï€÷þ[N·§ƒˆœŠ”žo\§i¥úÙÌ^ŸœŠ´vA 5š ¡¡¡¡¡áÆFà&wþÙ?Bâ;¿™’ý>MfÕ®¸âÔ'Ó-Hþ߯NÿüT @•«Vã׫8ÿLþ“ÐUÎÿjß5ùOfùŸ·—ݪꊯÈaFœGþ׿”ð ã¯nx%öAŽÜרÿ¼|‰üÏ-T$€ ûçiökFþgçTò_2q—œÿa«ä¿Š jCéÝ)e‚pr$×M½iFjK™Ï«¸Ÿ1zÆÛ§"ñÔ}[\ÿT9ìyJ˜' ÔqýºŽÉ‘ÿvžÀ‹Xÿ:ú_æÐçÄÿŠã?¯/<>̜҄�ÿç|Ùßzϧ_ò¯<("�x€ŸOtï“ÿ5ñ˜ üzR»&#BÇÎZ ›5ì}_úŽ:×¥eG�äÖ ñ,2 í•,"°V]J”ö�SæûŒ¥_òµ ÙE®®ÊoýƒßñÞ“““ïß»ë¯ø~ÀkÛ­ôl”iëü±¯g‰öRêt€B¼c"á§÷íæ'Ô�ŒE'â©þ|Hîc|è Ïø¼—�Hu Jøe€™n¥ÿA1þËB pøŠe'&Uv¿¾ï?ú oý–_ ~¼BÑœ„G‰ihHŸ¹ìdL$ÖüwêþA󄌕ÞÒ ÿËb�ÌWmk$²¿ìTÌ"åøîJpK¤|M.ÇYzUnôÚ•."à:áÇÙ’êc•˜žÆ{3ýåD­4vOÛ�îG9Ú>€cœ\áY¬‰‰øÏâ×98­2¹N>ë:“8”Ø$×Xc“G=2FïSyE<�3é¹8 §ç%"ðZ§l·§Øí¶Øívˆ1‰æqÿézäuméÐ29ö5 )Ù¥)º¾´RØ{œƒ*ÎB€ùõÖMD"І(Xc>‘02ÉMÕšjµýñj™²4�¯¥«ÀÏ êO³¾@D©¦*c£îkÖ]k1öÎkÙsÆc%ýë¬]f{ªêy™$‚r¨8TèÈòï|¬Èz©¾kˆ¬ìCV¿v<ëû óíÿâüù7¿ýßùÎ_O_Ð !"©E(Óò¢5s«ÖÐ 76z"ºYDî~ýËèí²eRËØôCF]ÿ‰¬&ãã`à’³ßX”ë&1€±(¢Xéö )…°7Jþ«Ûߪp ‹ FþCŸË.qèäÑ’ü�ùŸ¯#ÿõ‡D¢Fëk¬¾„i9Va@!ô½º×ý$ÈËç€ËŸûh*)-Tˆ3CVS"`DɯDÿÂ;HØ¥e»Jz“žkåþMó‹j뙑|¤‚�ÀÚ‹ú_vþ„ /®�ÚõoLŠxÍ®`AÒk›�B¸£šì«É›\뙼7 w~EÖ °.X˜‘ÿêÊ«?ÉâŽ(“(!Ç”« âé“áóÿø7ßô_>}õÂ'ˆð¨ˆ<©®ãYäÿrR0önæþ¯'ø—íR¼mr Ã�z�:‡qôÕ>1òÔ;7$Q‰±v�›"vÝìX¬M“ÈŒèC9†}ÁÍD "RZ°×ËÍ›Þò€¿Ù÷Ãß|Ï»~ó[ü‡¾IPÔ°öqYìY°g›có'²½rÿÏâü1}Öhùñœ·�*A@V&Õ)·ØË×��2K!�*ú_ûZƒªFÁT‰®q¸u 2E7eN^ùš¯ú¯„ùÒnôWÉšSŽb ‰HA"[b-²YNÚöÞã 7BH±ôõç79Â!0ˆPRqöî/,‹T*â· }ãÓ˜êu?™Œ¶°.U }סërËžilÌI>y|¥Åý&?ç\—ÈyçƒÓq7•«µ@0‘äK÷~"ÈK—%Â,�ÈÀ:‡~èõ8û"肇/­†¾:ß]OÄç÷@vü/“–ÛÖIýLRÈYìŒ0¹Ï³ ™2†…Θ —j›Bó€„é´Ã}÷¿øÿùâ—<ð‘àÃUl)P !” zV�MŠ~^#¸™á8&!Zõ™ÅâþÐÐÐpc †€b‰¥/c¦�6$@‰ÕŸÆ`Á3Ÿc¼S铯ûb!ÙsD¿@`Œ…u¬&öô}�¾ëK»�2îæ„%ƃ ëÒxëéM®súasTÖ 1Vi/™ä–" cês?ŽAÉõ4†w�…S2@³;‡®ëÐ÷ C_Zx_ �øKrÐT¿äë)ˆ,©Ã¨$8ÍxIIã¸CðaV2´GtÎÁ¹FS‰ê¤¤|�ºÎ•¶1}×ãèÂ]¸€Í0À¹n&ª˜×Y(u‡9£¶ò!ÌêÞB~NÈ;g9Æ.:×}Ì¿Ò'ËÐdE»`âkc?OâT’J4@Õ˜ƒº%Î\§;Kè!Ì–­ÇZÖú¿Žø¯¹ø™Ÿ—1¤_ 4 Z”4/1¨Ä÷`Ö¨zMf\Ùçjsvqqý•Ô5—YNìvÛoóÞÿ �1Þ9œ¾o�¾7×ßTî MÐÐÐÐÐÐpƒ’íþÀ-·Ýlo�\üJÜÃt€±°drJúiü&ÿm?ÅýSùo@0*0Júg€Qò?m7¹þ5 ‹ŒK¯!˜Lö“Ü,R€T„w,B–PÿY zxMJû}òŸÓr"£ûY -¢ŸÒʾ0©Õk?Lh«|厭49UÀCx ‰»Ô^  Wö_�„”šè/zU¤¾L±þ"Yd "8Ö“tÅf6'-YÊ9Ùž£l‹ã>ã�ã¿lƒ¦mÔ­TL0KÆSÇÝSïüĽï|çÇ_ðû§; ¯¾çÉ—|ã+{Óëï»ô*Cb´y®nÃVä¿©œÿ¬ˆXÄùŸyôòæã?òoÞø×¯œ^ø8‘<""O‰ÈfÞûÕ¨ÿyb[EóZt]Wˆ‚z’ºŽþ¯.Ü|kÙ~^‡$ðck 5r¼½}k-¬ô9V>»ã˜>êûR'7�1…D!¤ÁfÞ: ÃÔ‘ÇÖ‚�³ß÷§ÿüñÐ?jŒùÑüðnßà?ðVô©‡µµšR0ÿì¶D€††AIãL8çq&¬Š|¸Œ‹Óç8�w 6¬å—o®\½1FuÚ§ñ°ï“f­ÙêF�‘M,ǰlã“"û}ßÁ¹´ g-†aPò[ÅžÞ—èûDú«(!F0Ž»ÝÞ�ˆ1Sc6pÅeoaŒƒ3i¼w�SÑ �1+i" ¿ßz(mkºvIØ—¨pŽœš]©ˆjwØ�c©K¬MIG¹¶\Šs]CÔ×+”h~c-zkÑ÷(ç—Éÿ®ëg K÷uI<Òºf™®ÄÌ)Ô½:÷ôøì½$ƸØuûÍð©íöË®õçøò”~ÉDÏË¢ì®G4’I7¥äès™0—iÙüü”½3í6‰ ¦1}FÀï'f1ü{fxÚûNXÎ#U¤þ¾—~qMrÛŸe±±Ô Èú!ÈÙßWq} ütPÛc|ýG>üÁ½ä�—Öc�sä\WÚ^,sqo44444444Ôh€††††††@˺µëlŸcþ“?÷–\rç—d�æ'�ë§^ ÿìòWò_'RוÇs{€4i7,"ÿU|`Œ’ÿJ0Î"ÿ+òŸ2¹Ï3˜'B^òïË””Ž�BæGÝN˜È| ‰ü'2>GðsD@F%�ëmð1Ÿ'Âr¼6ëCa:Ƙ#ÿ·I |j=M'Ðn àt9&!¦èÌšâ¢DþgÒ?ÿfí=ZMx,ú”REÒO'’þª]³µ•(ïs–4P?—Öc�¤´ðù?#Þ›ñ]Ÿzá/ÿÒï¾ìÛ]x†™wÌ‘>ô¹[?ù¡ÏÝú®{ï¸úâ?ù ŸÿîW¾èê«Á(ÔA¥Çw,®ÿDþOÄÿ¥mÿØÏ½÷åï�Þó>"z„�0ó“Ì|<õ¬�;Ø–NÀ:îù“—­'´½÷ÅùŸÌ]ç’CpL“�iâ}ÄnÜ'dž€4d`²[ßLý†MÛ[Þu:1."`íO,œ¶Õ9ï:ô}D¬ÎÅXS�g¤^½é‡£�39f×C„?õ¿þþÇýèÿö8îþö/þÜO½ÀŸð'|=šàY�êÏ›Æ5ï=?ûücúl–ÛЙSøûýˆiÿ ¨J¡ÊÉ:ïp�Sj…”ØØ;*YoI ÇÑ9÷Ù—¼ôåÿå}/yàƒ,rɈ\‰,[ †|-bœZd„b(çï­-äSà†xºëiŒ4Á4@Cà Ö¶M5ù–ÉÜàƒóa/ Õ=1 $ðÌ*aMÕIQûÖˆÒØ™ˆõÖÚ2B´"K’‘Žãl6êÐw†Íä Îë ÌÞ—có!bGŒã¯)Âg;tÖ¥R©j+´lÓSÕ½ÍZW9˜Ìk FÓõµ…Ä 1‚Lj“`·KäŒ1 ­wSÄ~N2&'X½7§{²¯ZåIÎ¥ëÛ÷ú¾G×õ3÷õ¡6KË{u-lˆ1€™öŸ“©•Á:Ë"·Ývǧ®\zF—]I¾¬²SLÿ>ã¿Ï±g²^``c]Rõ�Ü!6¿ŠÅ¡¤¼œ´¾Y ¸Xuæþ×õóµ*ZÉZ=ÄrÑÖ“†¦Xÿó�·ë² Z=ÏÃÑÌg?ó©o»÷¾—)0¥#ã O_üØO½ëÕ?üð“›O‡ž !3sЉ¾Žˆ†Gž¾éÓ?øŽ¯ùà7½úÑ·üÑ7>ôg/Z¾%�/%�ˆpº±?€!1�ÿ3'ÝþÕ‡_ò�Þ÷™{ßcŒyÒ< àiyFDŽ�©ßg&–î¿å$uM¶G0[nù|þûÁÜ{œ™18 ·¦Äñr ÃÛ“K«Û9k?éešo??¶ü°·Ýå²ùßõãùï·¿ýí`f¼ímoû,€¿NDýïxÇýþ€?àÛôíN|�÷í½?–XŸ ¯]ƒ7PÅÿÏ&êë~Âu‹�*)¤ô^Cfª_•!T¡(dh{ñæ›ÿé«¿êõ?ºÙl‘ËNœ²c!þWÿãϼF�>úh{£44<°t•ׄ7ç~òUÛ›”�ÆúZ¼7õ“ˆRü= —m¤¾òÆ:87í)­'9ߥ8D�ÿÏÎvçºB0mà:‹#wTÚÄ’ü“E…)• „D’�ãX¶'Q@6õº·Î¡s‰œtÎrŒIHAjr<§8'Úú@J ¬�A�‚"‚ÈÞûû¿áýX"ô³¡†²Î8úÙõ7Æ¢s�Š3X“Y|::çÐ÷†¡‡s)�ÈZëlI!ˆUÒ’¯¼u™a4Õ`­%À¼fÄÆ¾ýŽ<óÐç?û¤ß9�O+c×lˆœœüÅ_×ßD•œvúKDæŽÿå ¾`º—‚“:ާHî J¬¿¬mN’x3§…"ÿîW“L¹:'Y¯(¦sHk]»[Øòœeõâ.—›}­¹žzç ämžžž¾5„ð“ÖZk�¥¾ïKû‰œ�!"àÈ`Nêk"‚±¦Ý”*4@CCCCCà J0·Ýâ.¦(~ ‚FýÛÉJ­‘þ9Âßú˜­„.õ5ù_âþ•´7(ÿÛviÐu)Gÿ§É[ì“ÿ4‰&"�ÕÃ`QÒ¿�ÿ¡ d¢>NävíK˜D·�Bö'rŸÅO-„Œ`a˜JhÀ¥Y}fÅæ“XTÚ@�Q·%#8ŽIhPÈÿœJ ­´]€˜Ü°³ÊÑ”©çèl‡�Düt�N ¦ëkæ±ÿ{ÿ Ò¿ì+�÷a×?J{€O?qñƒ?þ[¯ùûÇ»›rÎm?÷Ôïxù .½â­¯ùÜ÷¼ì®g¾Ñ#|àswÿÌÏüÎkÂ{ÿÅüÓ1Æã㪮0 γ±ÖÞúþϽäáO>vÿ{þÄ[~ÿÏ¿öÞ§ÿ $±‡Tm|Àî±K~÷gÞóŠðÐS·~ÎZûŒ1¸DDWœŠÈVDv³S¬'$¤wþ{�<¯Iôk-wx²ÉöµçÎÚÎy·uÖ~a¹Ÿê3û÷Ûßþö‡ˆèoø[¿õ[¿uÇ8Ž”™¿“™¿À Ú]ùË„ÊeO{MÏpÊäé«×!ªhš“þ2ÿßÞʵ~@DûèocÌ壣£_ºçÞÿÿn½ýöÏc. ó1Y{•ˆF" DÄN¼´µ¡áù^£ZCpÍ]ÇçÛÏÈlªZ•D�ܾGêvÐíÌiSc-ºÎ'p™¿ßJ¼½n¿ë"Ⱥ®°AçÜÌ1Ì*Çv;N„U�¶%QÉyCpÖ¡ï; C�~Ð÷CÙ–°Àû€"Fï˵ÉÇ�Zhš�¡j Ÿ„¹=PNù) !`7Žw#¶ÛSxm[`�C&Ikb:„8ï³H # %óï$b0èºN=Œ5°æú“X²$†¸�,Z5,ê"‘c ÆÐçEèÎi Ì£ÙJ=Sµ¸™ oE`7�©¥ûT&È`ˆ6.[¯•5Á‰HfãRvÓ®\Sæ]ö“w²°Aö+ùýë;))g{ý¯=„_;{àY”zÎÁûo Þ»¾ï�³–œëÐ} ø1 ¬³z=LkÔÐÐÐÐÐÐа‚&hhhhhh¸�¡Ž!Ú ]Ov``L§qìêØ'%ûm¯$ñ2 ÓI¥ïO“X6­c:�˜Í®ÿ>=g²û?O*ù£¬ù"òêb§û@‚ºþyzQþÀW‘þ±ü]"ûËcãÔ GþKPòT·þXÚLNŽú‘ÿYX@Ú?»L‚Qé©]“ÿK÷?X¦ç ù/Õë¾âæ_qþSI0û³xÉ_\ÿõ~õõÆhÆ_ÿØ ö_~èÿƒµö¡¾ïž´Ön­µG_zÁã?õî~â–£«÷üÁWäÛ?ùÅÛÞÿîOÝóÞq !<B¸¢¤| EzcL×uÝÓÆ˜gF.ÿä»ßüß¾úžÇý�½éÃù¨ ·%aÉvGW?>úÌ»>õ¢_xϧîy€§ˆèkÍ%":pÀŽJLíšC>ÿ½|¬\–sóËÇÖÖ»‘ÀµˆûkK½ÿúß×;¬­·¶Lz›ÑÞßßüÍß|9Æøs!„µÛínù–WìÿòÌåí÷¿ë÷">þ¹€Ì+´ ×çUаþ{å_}¬Ó ¹º•:�€ô?}á«H¹¢ÒÍR 0dOûaøÈMoúå»ï¹÷7Œ1O¸c¸BÀX{ `Ga9Œs ®k/hCÃó¼>Ö&2ܺìrOÄÿ|XH©QÆPEî§Høƒºí÷{Éç[Qnqãœ-.{"ÌÒÀÚ@[ì˜)ª>ªàÐ9WÜÃÎ¥hûa`ˆàCÀn·Ãéiš" Ác·óˆ!Lm«ÇÑuèûGG\¼x.\¸×9‚à“X ±%”ìwèú}סë}ߣïSâVjg`ô¼ ¼¶4˜âÎ"©%�÷~ôð~œÎ«ë0 .\¼ˆ¾ëÊã!Xkã$Äp].„hÐuý¬MÇ8kdLJ6"3¯ì¬}Òaa@ÝV‰™ mÃJ)\Õ"4'Ó�%ˆÉÚùMË7ÇòÏÐ3Ø©EÈQi§Sˆpa°Ž™R×ïË@ÍóÏ¢€’�GÍ™àeÑ ÞÍ,Fh‘V~×�þUë€ÒB€°PT"ƒk‘ÿ×@ï9Ïjב~ì÷?òÊ7½ù-ï7Æ�ëz}¿m-Â\%ˆDnµhCCCCCCCÃ š ¡¡¡¡¡á†ªæÂÆ 09†?“ù6 çÆ©S¿O¤íܪ"ÿÕ©ONÿNÑþDº�eä?LEþ#%dG(r[�ÊQ/œˆ÷2qÆù¯Ä|võg‚Ÿ9ÅþÃ'׿p%Hä¿È˜–•ð®$0ç¶!µ`M SöŸE ‡|1ÂLÇš¶£b �¸SçÿN‰ÿšüfN$Sm—dJ¨Éÿ%/2Ïñ̘Åù—7 ùŸ�tµ8 V6dQÁ’ü_Ixìxó…Ÿx×ËÿÞCOÝõ�aè±Ö>š\÷fg­�È÷+O]žüÉw½á÷C§ã8>í½*„ð 3¥p&ÿ5×[kŸ6ƌƘÀø±/Üuõ¿~øÛ>ú¶×}ä}ê‹·?òñGîø"3Ÿ0óeÏá"ºlŒ¹¢äÿiºTR&úrÔí26ÿzIy`îþ?Ï:‡Dçqö¯íç¬í:®µå—û¹Ö¾êçk¢aáà4"Ò1ó¹õ½¥ë_{š`GÂ;Þ+øÍßõøÐ'>õ GˆížýìïõÉmOUžîþ\¶>_‘%5@€å ”ï ³‡W1•Èྼü~›^ ‡{Þõðå7ýäévû¹ËW�w»«1ÄcW…p+§ì É<ó,œ¢ ÿvÁÚDè;káº]g ÌœÇ&TÎo¨€Š³_4â?ª ³‚Y(@4‰ ¬³%úß[Hù:À˜”D`­E BPç=ó¼ö1Æ¢ï{\¸pdÒ=ˇ€q»ÃÕî*ŒI.nŽ!¥IQrÄwÖ¡ë{l6l6G¸pá"†£½KÓj£`1zï„c9N«qú›ÍŽŽ]ßù>‘÷†~@?ìàÜ NNwˆ!€Y0Ž>pVädêøw6\8:ÂæèÆì¶;ø@'éZÇS�{kйÃfƒ)%a»=ÅöôÂŒÑ{%Wc † 6›ôÛl œ™D ®c8ïJ+U‰´W§‚6 êz‡§ºZWHg탑Âzí‚Ðô÷T Ëž3�² Žhö% ‘ð•ø®ªÉSÉ®­j1Ýâ{ÄRxg@`á"Þ+­ò±ÍcV¾û•š­rëÏ„½ÓÅPÁÈ %ÿŸÿ‡ýÞ‡‰ûóxù‰ö·q¾ š7R\zæÉ·ŠÈˆÈtÎÁu®¼¿D1DXàT\",{Ÿõ††††††††¯t4@CCCCCà ŒÜ`³qc6긯âþá¦8êët[’ˆHI|£öN7mÇ$÷QŠü×(úBþ§G&òU”?*ò?‚+Ò[ }è¤ÈÿXÅýבÿ™üÈŽüâüg.)£ T €0Áó^×y‚1ŸC!èU´Àz|â“Ó*jä?ï !' DeÚ´µ�’¥°Sk"Y$k¯�ÿ³þegPý]ÇýçÇ–±ÿ×"ÿc,OûJë°àó·ÿòO¼ó5ÿfóÐ0ô�9çž6Æ\2Æœ؉H!œÆŸñÞïýB¸c¼ÊÌ¡Ž÷ÍÄŽŽÍîJB`æ«1Æ'~éý¯ø|ŒÑŠ„Ô³!ýW‰èÄsJD§|zKÉž“¬ÆYävþ{M�Iƒk¹æÏ“ð\¹ÿ—Ëœuü‡ÎùPK�µý×Ä=i¯¤‰‘ž™o‘;;Ã@"$l:ƒïúf‹ïúÖ°»èðžüÖG¼ï÷wøÈ'OqrÚ×w¿¯?Ë{ÏÎÚLÜ>³ßò^B´ÿw~í­î¸xñ‹oy5ðÆW/½—ð’{ Ü`cø¬¥ÿ�ͱ@ž<==ýB$³cÄ�@v¶øÛn¹(!„ö64|Á�$W{ßù4Þ'"?&Ý'æ)3uÇ"¢yÏñº]@*ÖÒòÖ¸ýßi|=iç ž�ãÆšƒo­GÔXû¼c’ À:‹®ïpáâX}lô#NOOÑIìZΓҲ.âh³Áæènºx/^Ä0l`;‚ÑïBÔØýäÐ÷>€9–Ô¢®séxØlc°6°Î€£ {Xc!B8>¾šâþw[=?.µ–1„®ë1l\¼p7ß| .^¼˜„!à.Á�$ñnN@ÈÉ]ßáèèœMÑéÛÝ'§§¸z|ŒqÁ1b»ÝáääM¸õÖ[a­EW®ºž1Dôý.'>MDùB–Dvñþ!ĺŽaLBÚjUk»‡�j‚š¦¾6•[ sqirV!Ø%ç DO‡R%zå-ÑtnÅõI"‘YzOÖW_öSú©’)д¯Y*@Ýv@uuù;•õ²ÇüÛDØgeâ^ÃêÆ„1•( Gþ;Piàt»Y4`*òŸ``4• ‰­®x@19_²ó??_D\‘ÿ\¢üK[€Bþû$@âNJþ§e¦�ìä0ˆ 0ÕÌ–N,¦žÎI�%‘ú;uþ×äÿNÏ#·6} ôüm¾&ºÝb³©^Èù_»\8ÿMý»^$O¬Öä?¦m)ù/¬b…=×Ê÷>ÞºKÿüƒ÷ÿл?}ÿ/ÃðH×uO:ç.[kwD´Àê¸çãIŒÑ�ãxÕ{O!„cô’”…øïº®ÿ™ü7ÆÔDû)3ÇãI¡gæªo¢1&Xky" ’^üÒó6'ÔÎýgC¼_Oüþy�ýçy>ÿ}­ÇÎ:¾Cû\n³Þîr½µ¯ÅÿçŠÈ "7‹È]7Å$`8aØôò Nð­oÞà|ýÍ€ Æá£ŸñÞß;Áû?|‚�|êŸ}è>¬OÎÖb„†Õ+TEùîÝô®µcPͯ¸ŸðÆ×ü�¯¾í�@߈\)ÝÚ�rï¹ë–ã{œ5|4ôWýÅ‹—Â8žF¢("ÁñÞ½@bŒ+„O›„ohx^×§–J_û®K-Bªû˜ÌRNòcL•d€H“H‰¨îUoЍ°ï;8×¥huúÆÁ9Þ¾'tΡïô}RJPðaëìD:›¶Û¹Ô®d»ÝbètY¼h’`D† .^¸€‹7Ý„›ôçÂ… èû,Œq·Cä¢]"!•°gŽ!,ˆ! „Ô‚ÀXƒ GxŸêVgÈÈϰv `ww;„è!Â0&9ø7GôC‡›oº ·Ý~;n»õ6ADp|õ*ìñ•R'%@˜µHשDžx/žàøÊ�1àqzzŠÈ† †Í€È]×£ï{ÁXg"§íîv=ú~@Œ�&1L‰P¦¤PIg(ï!pDâù˜UÊu’®ïÆÕEÉ\س9,SKYŽ‘TÒJۃȉW—ÿ¼.›"ü‹û¿¤šŸÊ÷ 3EôWŽÿÊv_¶•Z�MŸ‡©Ã~›žŠÐßç¶e~]d1ö׬R#Ðì{GþÚ"S0@u™'À$tž„çuøŸ]Ú,�=ï)Æøõ"âLc…ˆÒ÷;hKŽÜŽb‘æÕÐÐÐÐÐÐÐÐ�Ð 70Êäªë0T~7'ûëvB uñ£J Ð߯�HÝþ¶C"ÿs[W‘Δ8s YD€ùŸ‰ÿàB:÷RÍcÄn7BD0Ž#®^½Šíé)Æq‡Ãlüñ>=|åTjÀZWê·$°¼÷`aœžžâôô»q„W¨uÖ ý€aè1ô=‚UK!«âc rÿö®ëá:WZ,D}-� ³:(‘ü|Ç]w=ú…/|žI`$Gõ½,ÍÓ[²j‹…,ð¨ÈÿÂà ¨ˆ’0…£Ì†M’©uÖÁqXÉt£":¡Ñ^÷دü÷Ú”õêÖ]š�WJD¿Lš3ʱ”80ûÒ0¯Mfëž�¯ŸV ¾t\zæéo4Ƽ€�YD$ø€Ñ�>̾#�¡߯¾rÑ 70tòRÈX�ÑxþLüSŽêŸ’ˆìäxÏD?™´^!ÿ»Dþ“ Û2™øË·Õ¬üôØDþC‰�aÉñþ3ò_�ÿe¹ù/)Ò_¼>'2àqzžGœ£ýã8oP\ùA¹ïuÚ”É:£ Y¼§ã]_FˆxHÔd�òùŸ[€ÀF`rŒ¦ºé©�›Õ‹–‰ÖCÎÿÅýofä ,À~ €=VO8Mˆ–Èÿ˜&0óD,¿¼yè'ßóŠ¿ûàS/øÀfÓÑ9÷¤sî)cÌeÒF¼Ìœ&|•¬ÏÄMÜç÷díü†¡�ÿY°’‰å:I`IRrÿ×â�Úõ_¯cŒ)Ë>bŸQ¡×Cú×Çy�À¡ýÚÎÚòg‘ýõòkÛ= g €›Üö†—¿¡¤Ñ m*k³ã©·.M"!D€]ÕÙ"½ï¹{ƒ{ÞvþèÛL2€68Þ|ê3ÇøÔç.áÓ>‰Oú <ôÈSøâ£—ðÄS—á}˜½7]�³È÷/•¼>k¿_ æÇÜz á…·î»›ðŠû�WܼæÂ+ï×(ÖûžÍ½µ—÷Ž*Dd/n¨ÚË|ý¯¾ÿ‘·¼ç“¯úOˆë9ŸQ\Kï`æòmhhx~"�Ïvr¿«ã›ÈÀ:†É­{B@ˆ Ž©É{"Ó;XW J1†T‡: ×¹Éyß÷ 2©>‰\H÷"8)î?‰¸$Ô?1F“j›ín‹ív‹Ýn"ƒà=üèá•TŒ<%›8—ëT#íÀqzºKI6'Mu[纋,BL-ÆÝ§''`fìvÞïp|5Ý7cdœn·è»äêß�W�¯Â�ãLt9‰§”¦qqrr’®™!Œ~Äññ1NNO1Ž#bÔÔ$­ß“@à—.õ`f8ç0ú1M æVÖÁX Lj|/øÑ'�„¤×2½æ©ö³®Šö7¦8îsìß èú�s©µ€hÆÑ«"Ìê=IÌ» ›#OÀÓÜYÆ\MÄšºÏK©MJú*â>ך˜×Õ„Eø–Ð:ÿ½R'œU9俉�–ê(碅ùÒóìý%ùŸOŽûiÁ\gQ®–Â?Ô.þý !7&Àþù—¯‚4�¬\�=ÁrÝÖàÙ‹ Æqü"r"âbˆ1Æ(£¥|^C@¬¿'˜&Hlhhhhhhh¨Ñ 70Œ1bŒáí§ Y¬.êò’JþkozIi‰Pv è²ÖaŠüWAA!j¦¸Ý§|Í¡/!S[D%é¥�ϳèÿBþë„¡m D!ôÕ}/à˜w= cÚF&ù3ùO#ŒÖé³EZ1F'Ûr*€î/@vàèK{ä¿CL HÑæ !�6_Âd3‘))A”ô\uþcÅ™¢Ûš‘ÿ4Eýû�2íWD´‡wº.ÌœmA*.0üþÏßñ«?ý;¯ýaØ£Ïl6Ý£}ß?c­ÝÑVDXãùÓ$š:õF�xÎÿ®]ÿ9âÍùËí-·±ñž'}Åòçåó¾�1³‰âri®áНÅgÅð×Ûz6±þ׊ø?OrÁµŽï<ǹÜÖÚ5ª¯{yW¦×ƸÀíÆÈÝozùÕ×UïZ$ý¡Ž9V¡Œhú‡Ø)ŸwÙ ·Ää2ÀFÅ:7_8Â×½á6|Ý_1%œäœ_²xäÑ«øÌCOáÁ‡ŸÆÃ�<�ÇŸ¸ŒÇ�=qO?sϙÃÕ­ÇÓO>…§ž¹„§žz �?þž~úi\ºt—�OÀ‘±Û�ØíÒ„ò•ãÓÔ;‚“Óm"Žª Í€QýÔ­{0RïæÎ1úŽ0l€ÛoépËM·Üdqë-„[Ž€›/ î¼)âŽ[Ž�ÎWˆ© N÷<½wXo/2¿Öùµ]!øg/EydaÝÓûV¾WÙ•‰sœe÷ö7|ø»~ò·¿éQ¹JDÇ®,?×3Ò µhhx~ƒRäw*_¨ÔyL½�ˆóÜBÈZ[ˆi"‚5ì6ÆDÂ*a)œâí9FÝ•�1ΑnÇ¥zg b«[b"¹�1)æß{%¸ñ."°v—Èþ݈Ýnk,"ÇB„{ŸÈy‰”Ó† fI¿“hN`ŒEŒMU±ÁZ)Îxê6 ¼:öSr ©Ë›Àg×$“éD„®K®üTÿ”’\ÿ†˜ÄÌ¢â�ín‡ÃLH‘ïËQÛlw;Ý~_Ä!¤×Ë�Iûˆéµ´ZseqèéijÍc­ƒ÷§WOpzº…õ8 ©@ÂÎ"FѦÌÒeæ"Â"äÐñˆ‰Q$f�y ௺ÖG4Óãª`ŽRiAÕc‹U ”^kM¯Éç[¶Cg�i˳šøo*ï_>ô1ÚwÔ ®™¥PpX�—”qž¦’�ò;šö…”„2ÛÊ>{hß�ÏŽÿ×D‡»íWÿÕË¿ýmø÷„ÅÆCþœúf¢֠¡¡¡¡¡¡¡a‰&hhhhhh¸�¡ñì|éJ¼\ÜþÆNnØÜ€I‡u;Eþ£l—§.­k´Ð *C¦r‘äÈüÌR‹’ç29uY*ò_É+„*ê;“ûAœœÿe¹ìúW#©€Çäü�£’_£Æÿûi¿™x“<Ç“‰ÿÊ‘olrÚPžÒVœS<$ªà f‘�¦dò?Ï—Õc&_‹úw…ì¾Ï‡U‹%òÂ{Ä¿™µY(I‡&K{�8% DK5QG„Ï<~ñÃ?úÛ¯ùáËÇ7›ÍÃ}ß?ÒuÝÆ_Gôgò·Û• úºŸ¦¾g‘ÿ¹ooä¨ïÚñŸyzÝ_Gür¶¯‘‹õÏYûYîÿCÏO—øÚm–û][æzZœG¤P?·ÿ¶8,xX;ÖåsÕ�‘#f¾)n÷�Ü~òUßõ �;´ÝUÓÜ_ É»ô•Éá÷ýY«îgõbž2À¸xaÀÅÍ‹pÿ}w!ÐÄPiG’ïeA?ËÈ®…X×bº¯1ƒ$¥ˆŒ�¸ø1ž¼8À`c`H·½Þçvéˆ8?ú¢*’y�íe´ïú B-,†×^cýRVxÃK¾øæ÷~ê‹ïÿôc/º$"Oxr­…PGU744<_aµ¿»±ÖXXkà:§d§”–@É…‘bæÁ�®›¥ú¤Ú@ÀÂ@œ’„| è…S¤`ÜlC€5h|~c´w¼Lm�œu0U½eL:Týê™áý¨ä2Í—²hÀZ[þ-H­ÆÝ£i1Æ"~‹1aF§¯Oß÷pΩ`4`»=ÕV Þ�8¹z‚“Ó=Ž$а6$·HIy\ðÞÂW%?xmå�…§±¢bˆB=93öÏÚÜš{½þ�!@Ôcž¨+?‹XXµÐF‡Ýªƒ€J{´ÚÛÆ�K¹¾Aõ=ëZC³¬>B«‹¥ýó¢¯OêÌâý¥t˜®‡.¶æŠ†/ã÷Ý¥æaj+ðØù&?ú�‰ðc4!ö!H q5)¬¡¡¡¡¡¡¡¡aB444444ÜØ`ñéËãåä·H,²’ÿp)2ۨ럲û¿Q&þÕíO�&L“#&Çi— ­ù_"ÿkò?‚¡1üe™€©Çw&IJë^ 6ŽÕ¿G%à|"üá'ç?�)ö?êóåP&¡xZ t6‹H =RѧtÉäð(-¢¶$Èç @²KÙTÄ:Ç/QEÐÉâß{¨s2Mý¯$Zþ™9�Ó6gqÿ’®{v(åíy¶ã¯~ø®Ÿú¥¾üç†axt³Ù<Þ÷ýÓ]×=c­õé°Òĺ×IðäHó3×MÜ×äýS»¤JÝ•ô€¼�µ>ì̼?ù¿ÜFþ}-B~í±ë�ò?kËçÎú÷yŽoyž×#X.sèù•mõ"r €Ñ‹_yïÓßøç¾ýá¦!åŽ%à†¹=æƒbÔ]vçŸÏ•¶¬b%³´ÏÓáÏø2‘À½mdáªÏ>cò«÷¨` XŸL—é^ÂÕ2f1ù¾jœ¶šâ�iº…�…µ~Ç }†µ0ßûÖ÷ý?ø/¿íóÏ_xÀ£.­m®‘ÿ Ï›nk¦Ö@�ÖÌ §É@1Fí/èªVCËt º."�ðÖ£=bá8ÂXË}×!ôbŒ©¤”X„�QSb>§ÄÈa„`áGŸ~‚‡‰ÜŽ!¦¶Z—”e1Ör�˜#Tý�Úµæ ©þ±)1ÇY‹¾6A“HS lMDuþ›ÒކaƒÍÑCßÃZ£Ç¢O׉¯$(@éØXfµsUÓ!_£€q406"ø€qÜ!x¯×H`¬AO}úÝzŒI0°Ýí°Gpøq‡ÓÓSìÆ]i±`mÚo°Î:¸˜„µ†Ta-:`:JJC(­a–ƒ„Åz*÷¡ÏcÒ2ø~i¬�ü")Å¡d†­‰NÓÿ mû•_çiŒÌ"Š:½he”OÃ3ø «ÿ˜„­RKdVŭk™ž•õ¬–ÓÑOG¼çèÏb…|�«–çú¨÷Ú©óÖù_»Ýî뼌™3ÛcŒ!Jº�ÔÚ´öC 4@CCCCCÃ� ‘øØ“§—|´¡sÆœÎTÙäôÏÿ&X ‚ºüm OÏ›©¹eÎíΑÿ¶š2Uä?O‘ÿUÌ??*’«ZŽ#í;*AI|Vç}~ÞC$‹ÛŸ‘ÉÿíËŸ#û™g¢…Y8Ù|™ô±X9ƒâäì—UtF ²:p¥Ä‚Jé…ÀÓ¶yLç^¿Jú?9ËE³èJP±%1ÇŒüŸ½ÒW‰ûÏÄ5ÝH„ÇŽû‡~ò]/ýï>óøÝïßlúG6›ÍÓÃ0;ç¶ÖÚ0Eôgâ?“ÿÞû=Ò>÷›­�ÿù÷’ügíµ»Fþ/ÉûLú紀岳«¶B$ÖË�‡˜_ö¹6b€zùå6Îzî,ÁyÖ;´Ì7‹ëšü¬ ]oàv÷}Ï7|òõ¶7|á{±Ó^g;ÖÎåP? {�tŸÅºõ2ߟÖÜ`²XCžÅ~3¡OI„%Õ})·žîÕ¼v¡k_‚|ý—Ÿ© pÚcó—z¾%YN‹¯åøeQò,«�ƒBu&"ý\ÌÄå0¿¼Îÿƒ_™ªzï¿Ö{ßEf+"–#S#ú·&hhhhhh¸�Á‰µ "â/]‰—ï¾c¸¢d’QÇ?(9û­‘ÐÖaŸüÏ$”FþH³RÙõ¿BþçßS¼dvãK&þyúá¨ñÚq©/¡j Ðí8¼‹x—~⸠på|­Ò ÊÔ ¹ÆJü›iˆÚ†` ÎQÿù7{HŒe=щá½\ÿŠ Ã"â_ÿ8Ï$TMìסù_•RfÒE8¥”¸ž‘­#ïýìm¿öÏ~û•?Lfóéaè¿8 ÃÃ0\uÎùÜÿ5OHgâ?Çþgò?»æ2é_“ÿÙñ?�êåÙDm&ÿ3Ñ^','Òë¤�å$ÞYÄaÞÖ²ÀYúe«�kEï/ÚþÚ6Ïãö_{n¹ÿúß×jSpÖyŸ×ýO ÀEw¼á�ÇÞü‡¿æÉïs82^®jÚ­œIÏ?„Y_S?¿tÓÏ^}ìµÃ¸.bþ:–Í¡y½g5Ç��Ï b0K¤{ˆÅ5ν¾WÔgSØõ’ê¼òš‰œÿ<—¹Æ†ð¢[üñm¿ûûk?÷MÀSºÄÔ?åŸã†††ûa­ÌDx‡1zŸ¢ÞǾjd¬-µAÌäñn,1ö1“õ¤½Ø³p/2FïávÖØt[µIÌÚ9‡Øwˆ1¤ú”‘>FØjܳÖÂvL4EØhrZ'Ò½.¥®¸¦†J<¾!)× ë:t9ÊßNõNd.­fòyì¶Ûâ”wÎbØ è\WãèAdc€s}ç0l:m6°ÎÀ…4}c@ñ`_ù\/åãOiÃ0`³9Â0ô0Æ ÄïGm%à•ˆP—^ ç,\×i+@ ÚÚ!¨p! Li• ˆUß½I- Rý„ í!BÄÎïàw)�!¥50˜#8F‰Ì"E€§¥®»A%¸lâ½Sè}y«v8úÝ t¶×þ">Õ¨|¢ü/%à‰Àà$¦ã¡¨²NTÈãr-JàJ@0}¨Ë ª’óW5:Ï å|×Éÿ\/ï•82­I"ûßo¤ ‡«ë“CÉC máêðZ'Këß…_õ…‡¼ù®»_t*"FÒ‹¨ï';ÿÎa[ €††††††††MÐÐÐÐÐÐpC3�—�Ã¥»ïrw€µç=¹4”“l"ÀV±ÿ.µ0Ópo2�^MŠ¥ö™¼ÊqþÙÏQ“¨•ôIĺ©ÜÿtÂ/T®û”QÂ]’û?Eò'>‹âVI�þuý#b6¥F4/ÒñO^žüÊbƒ Ûòà0N©ì!œÛ ¨LH[f‹•U gž¼›MŒ-Iý{Ïl<¹óg³Zùß{Îÿj{y5æ ÎñÿeóW¶îÊÿðž{佟½÷Wû¾x³Ù<Ò÷ý“}ß_qÎMÑê¶_’ÿ¡Šã°çô_Æý×®ÿš_:ø–Ä~<G\Ng‘p–0 ‹òr׊ǯ[>žØ³s=�³¹Ïµc»ÁÁ!¡Àsá‚+"Gn6$wï[?ñ¿épÑ„^nKJéæuC}õž§3ž+×R{âW–1(¤úYû{Ö½^§ÏàÞckà’Ç¿8וvT³æÓL:K¢ Rû”sÄàR}?©¦îkáBÝ[Ђ§°¼cÉõ^±„î¼(¯øî7â�þÂ{^ùO)}0¯ØéౚæÑÐÐðü‚16UQ ŒcÑXn,Þ{Œ»˜£:ÑMqË3§6DD»rŸ1$�™1%¦>ß“SÔüˆ-ˆl—"ó‰d’¸€BªA³k<‹ŒIä5Ž ‚³¶�„ÌŒÀ\’ ¬µèúC?LfÖ¥øzJm_Š ŽRL×u°®‡ë\9Ïœ�Å~LN÷ív‹Cj�` ÞuÆ8"@Iý¢4†‰–‰JpRj` ÁŠ­†)™Õc¹®3z­º®Ãfs„ Ž0 Æq?úéZ¨ Ô\N&QD×'Ñ…D}Ý&XX›’²#�HÊuKŠhgŽš5b7¦vPÑCjÅ�#!Ä�1FI£'ž¨•Ú}"Ò¥¤ûè{ˆŠ\ åžÕÁYºÌÔ ?§ã—°¾Ï’:ŸÏ¤- ò~-¾"ä:u[‚*íªˆHËúº®¾d1þ×¥EEàï�×´¨%ry²XZô½,‹u³À¡ ÖBÏö+Éô}êËt»ùøÇ>ú5·ßq÷¯0*Z-÷�,¼!ý|744444444Lh€††††††1ƨ€íS—üc¯€{YqþeˆŒ’ÿÔ+Ù¯m²ó_‰é’l_,Kò?;W«^öÌêüÏ�/È%êÓ¤˜Æýs˜\üȤûô7ÀìÓ2q›ÄÑØ)ÙJŸl�’ä¹d¡ôÛä‰aTD>4e€À[ˆxHSä¿x€$äTˆ§`æÍ²yŠýYÿῊ⿎ÿ7““l¯-j׿CŒ“ë¿,JøÌã?ô�~íe?xe¼å“›Mÿèf³yj†gú¾?®#úkâ?ÿÔÄvÄåIÞ<¡mŒ)ä¹* ×ÿ!?o³zÏ¢ÿ—IyKÁ@qYUî¼:…à<.ûy´ðÙŽúå¾Ï"ê×–9¯û¹ÌYË-q­ã?ë<×¶¥©=Ý àŽ?òuŸ~Û]·à^0•IfƒØif}3ÊižÓ-Ô¥7Ó4ÿŒUýsËg¡jS²o}ûR§–iåß׊ÿ—ëÛ¿ÌÛ…LÉ)Tµî�Çsè˜åK8G½UñŠpéÀ)¤V2#=’ ,¿>Iõ�/ì/ýâ{_õkÕ"RZM¸¾�ÜÞy\÷=J|¼×öB‰„'Xçôï4vÇ�j·D6’Ö8šýR¼SL c<ÈtHÛa¥†‹ã¼ŒM„½qœK-¬D$9ø3ÍŒ"D÷™êž]ß'¹–,Y�Y´h"RQ€þXg’h’ ip#pDðJþŸžâäô1ÆTkuQ±e"ôEÖy„Ę\ñãn„³�ôéü8êK¡•ôüƒ’é¹õ´¾†›Í6›¡¬¿ÇR¯13¼&€]ìÑO]§ipåxS‘Æ5Oί·¶Š2V…dJ]B(´5g·!×,!$áDäˆ]¨ãÊ:æüÀÒ?sæëÿõµ‘É_Ò š:ˆ‰üž…ûˆù”×ã”r`ª½p>»\‡e‚]Òþ³`À¨HDHŠŽOÊÿ§÷™TüüÕ'—B€BìË>±/kµO¾Î´¨% &ᎬW‡×Y½L¸z|üu~ ™Dúçïε)††††††­:jhhhhh¸�cdEd÷ùGŽzËÝ7–8cA°ÿ¯Žt)€,Š‹Ö�NNÕîS-SEþ—xsØ�ü/NØѯ=ÜsÄ?âäæg Ž{ÄäøÏGuûó˜D2"ø“ÃX ¥ó£¤ùDþ³¡Dô—cŽ…äoÕõ?Á<¦ÖX��:U˜SâôsžèœÀÓ£™ˆ»5âæÔÅ5Éÿ™Ù˜*‚oIþKë„z^Ö³å#wýÔ/¼ï¥?Õ÷ýCÃÐ?¾Ùl.o6›mß÷;çœd¢=ƈÝn§}Z·©¿ë Ÿ'k³ ïû" ¨Iô,X’Í3'Ž1³uED�_a&¨ÅknáCû¨[œ—´¶?õþ¯Eö_kç9¾åùŸg_׺nçù> "¹À�o}Í£ßm¹ŸÞ÷D3Ë8ÁÁ¢K÷r Óä 9úؤxfÑ÷uÌ-BfÎxm­a—ä{þ|\Ï´ñ¢uÆ*ªV‘ÖŸÛ¿’Øý±ÑY×uÁIl„ëM+È7‰™ð\«,eé¾½\Ôb¢F©}ŒE&ü-HrL±ì­½éÌ­øk?ý=¿ô¾~Éýrè½ÜÐÐð|éíQÀxÄ�S‡¦Z!×¹}ŽÞÏåV™Ê£ìâÍ"?dªRr@Ô6©VŠ!&B\ï;”Ýï‘A�!õ²OëK"a«Ú&Æa�Jlc,ˆ«úfÖž…f1îùß©E€S绤ÒXFŸ˜ã¬�‘µ6¥ØtN»Ñ”ºi{z «‚Μ’µ–hO ™užœôšåT8™„ÉÍO*€è»n.ö³€ —õɬKé†�uþS+ɦ´†ÃN0Hµ q)íÀX3 �õ˜D( (×:½½ˆR8=seöΣ©l?¨e£z„›êòTšHݯ¦ŒóIÜ({QùšZo©è$iu¼[Ô,Tyíåc6©kžj¢½ÚÍ\õ+IÕH> ¨j‡½b¥¦8 K\É9Ú_MêåöE•ÏEE0úñkŒ16}Í0Dfþ�`úÓµ[sCCCCCCCC=á×.ACCCCCÃ� ffñ¶ŸþÜÓŸ¹áoœ:ã;À*ñŸI}r(ùÑ)¶´&þAù_ÇÛgg»$g}NX’ÿ&V‘ÿ÷ä]ï†þs}ß?ºÙl.m6›1“öú¾�÷»Ý®räÿÒyo­-?ÙýŸÛÔ„^-X#䳈 &ôëõ–ëÂ’Ü^î#ÿüìÏþl»A|é0"ÒÑE·¿ùU�|Í·Œ/&¾iýí^zÙçµ§È~ƒ dÓohK’ôž´i¢˜w Û§Ç‘?{Y$àÊgþL<Ûˆù’HpñÏ‹¿«ßŒEZÈrãkÛÔ(òœ䚪AºŸYäÔ p&ª’̈Ñ{|Cåã¢i|ȑŤNDY\;#¾á�ýû¿ô¾~À3žÎ÷–†††¯Ô$¸Šô7oda­ÌÄ{1rÊ›ÊĽ¡Bt[e1“Sßh]aªô€$6eáÒ7ž9 W� #Æ,†Ìä gI‚""‚µ-’OÛ–â¾I÷ÅIÆ&`S°ã)&¾2Eæ©ïtO$K@´0´L=ÐV-úš™r5óû×k²VcŽÞKçäe®²º�àÖ�¼àå/¼ôê�=tá)¶»ã¬HCCÃó%ù'�ë©°‚°LŠâ¯kƒ2Î ÀꔲΆ 8ë`­+¶oK¨ê’(Y/4µJå›�,[F�C…Ág±âˆ­ &£º kHCl&Á�’�Џ¸î#3¬¶UÒú]ë™yÚ’çRMÓ÷ºnÀ0t1"F; bD 1uÔÑöÎí·NÊ×uy}™¥>£�D˜ñ ¡VbX0¥zÜmq`R”¿«D€€E0ÄŽ!% ÄÂÔª)Õ”N”®e݉žëÖNºŒ5°ÁÁÅ"Ä€/_¹\Æ*AŽÿŸþ��úµÿ¼ˆˆ¦0£¼ìJd~ý5@0µ—kLÒñ‘ì™Üs •ÏÁPú¦T‹F~†DªŠ«N!P1ƒLÞú©ö©¿‡Lí4fåÑʾözöëE¹.]ÿÛíã8>“÷3G–ë™ü7•3+ÇÈÖþšÀ¯cˉè¼üšó¿ äå×âîëHÏœJ�÷Ùðœ~¸ "·‰È�÷ßyüzƒ3!‹\c&¸nq1¢ú Í#qç=0j˜•ÏYN,!²€50lÓç+ß $G½ÏŒ€ä$zOãÑ{x ȘJµ IÓDwŸñÌéþF“úþ&aOEªË ðÛt_ * Ò>Ô)�¥¾”‹¼Ý2o”«'ÓIŦ3,_)÷Ëåc«—9Òt3Œ´¿ Ëìõ«_GLÆB¼ý«?÷=øuïcæ~IB544<Ÿ!¥·5Æ‘FÂ'"Y8 �bî)¯÷†Ü  N[áÈév#Ø:P�”C¬íà:«ŽpIÎöÈ*ȵ�Ò¦º}f•D#Æ:IÈ€„J+aFÔuvãˆQ£ 'Óðg5MËî�t94Š¥Jñ#$¦Z.“ÿ¹?yç:t]JmJ七�µSJ÷ÿ¨u�µ#¬KÉ_Yli­ÓZ-~…êT€áC@ðéǃ˜Iö™8”@bÓkjmríÓ”“{<‘ûÖÂuXÖØ¡o�M‰6‘ûÐ×HòëE£ï‰´^ä×EpìÀÌ9J7 WŸ|ô‹ �’‚[¥ÃDÆ“’ÿ5ѽÖ. _ó’ÓSÜ÷-_×­‰Ò—²,f"ÀX«õ|Lf|QZñuaÊ:\kÑy‰sšDëÿrh¬ >÷�i-M`-ÒàË!Ó}øÁϽá5¯}Ýçk@ý™khhhhhhhhXŸôkhhhhhh¸AAD9àêM7ß¼ÝÚ;Ø+˜ˆM(Qö†3ñ–É"TmÔå  �ÿHnªâ”ýÍêv…ºV³{–«eī˞Œ)š´�ÿõw*ð“ëº?3EO§žÔfù¯¾‰ÈW7?û´~ôÞjÌÿ4Y êq•ɶ,"˜j{$\‰þ×egÑÿuÄ?�Í^4Ôä%á ò_8];VFNSÐí|òÑ£ßû¡_~ñß¾¼½ùãÃ0 S¢SéW�”(–ó‰ÌˆœÓœ�Ò \¬s0ÖÌS“¸¾�S©Ù…“›_X·£‘üukfÖˆ}ý±|uíS:Tð!xŒ~„5»ÝJ{(“ddÖ¥HucŒ¶‚Ùoq@¨¢×­@ŒŠ*â).�Õ{$³ÚҀťdfáÈYð!�€ä¦B<¯�14ePEÆ£Jn¨�øË±ª�ù¹F×G‹ð­|o ôºªˆDÔý^§S‘~>HÅ|¢ïL� @õþtÌ]mO°Ð7œ§ Ñþ8¼Ì ¨¥T…eQ€ÌÃawÿ^^ÔsUáøêÕ×c~©Ì^?™R/tÒ¯]‚††††††DÄD4Zk¯¾á›¾ùîãxÑ[$òßT¿¡­ìsä|ÿ¼GþW$·Äùω”W·vçW$¿äÇ%“ÔÁÏ)6[D�¶¼KäŽþ‡Æiçm€©Éÿ*©À¦cÍç‘"ÿõXbrô&Aj3 AÅa—Ü·Kò?Ç…#÷.'˜2a+ó>ž˜ñ_þÞ?÷³ïº÷gû¾ÿü0 o6›'6›Íñf³�s®LþfçMþ×ÄvÛÕ®ý%ù_»šjò¿vïëûq¶­z²3¯W¯»Úc5_…“vDTޝï{ô}¿Gþ· ¾ç"âDäÀÍo|Ù£_›z'§º� ¥(},ßÃõ€û¦T"�ò^àËaóö«ô‘µ¶…u?xFÕo¹Æ´¬žËJCbÔNÕ"(NüeDþþµ`L=ë_ß_–Ëköêñ²v±�Ùñ‹îë,QCvþë-~-�¤ÜŸdñZ.¶C‚ ]¼ÿÎã{>þ ù(3w"2‘´ÏhCÃó¾BAìÖ¹T[�¥®ë`vã¬>(ui-¦­Y˜ ‚À1¥Sy‹¾O5„u�KbÇL  Š`N5¬�Y­'fÑ’ÐÖb¯•3#†XR8FDf"°ÀMd7D…�4îDS bTÒž÷ö™L¯ë§óOà!ÂS/÷êÞœ5“íÖ¦(~ H`¶©Ö³f–ð#O×$FxŸ»aŒÁn·-"€ì¤ÎçfUБ8k #pqNȱõéµ,ÇC§uæ$X¶ˆ ³×('I¤²Ü¥‘Œ‘YLt}c(ä~¥äÍ*>Ѽ6—Lx/D™|×mJ]?ÐT¿N¤ºòž«ñ<‹2sžŽÃhë¡\–HiA {:cÚo;¶2|×冬ý÷RËdVN•õöœæ ?³çª4(™¹h_6Œ»ÝëˆÈPõáÍíÏ’&"†Ö ¡¡¡¡¡¡¡¡F444444ÜÀ0ưµvGDÇ÷½ô¥w‡ÌÉ9”c±a=Ÿ)w�ÌÑÙÐ ¥ìüÏäXC{ÎgòŸsl¾þ–ìúÏ}³³ |z^Fý÷Ì£-»Yk€Ò_ÛÔ‘û4ÅýS—Rþuî†ùÏš*Ç´?xuÿ�)ê¿"ÔNÓÜ¡Ÿv™ÝºÕ…®gÐÖb2k’l�[$˜ÅŒZ1ëN‰ )EA 9ú_�¸�>3<ò�~ýE?ô‰Gn}ÿ0 _†á‹›Í扣££«Kò?íã˜kKò?;ÞêøÙZP»þÁ€÷¾ü­ïC8ÓÍ•d‡ˆZéœ�k3˜Í½qûÙñÖÇ×ÜÅÏ DÄŠÈÀÅûî<} §†hWŽÙgbšä^sÞ-‰ý5¬ìu�z¬ðû•(¶nü{“ç,Õ6W=Þ|Õú¹¼fµ;žE…L+nùó¿ P†åЋTfëSØ!œ½ÏÒy%o8; 3 `h!€Zi}R·I)­dÒïo}íÃßú±ÏßÿÛ"2ˆH‘Ø ÏouY“öXÏd8öHqÖšGªºÀSú¬ÃÚS^X`(h[m£¢‘ò,\j–ò@¨rm/Ä…kµˆ­Œò½JŠÃ]ŠÓ](7ÔJu9g"Xc á>«‰xjCP×,DÉ ^×AIpàUâ\p™ö¡­–ì$8°ÎÂæ:€‰DÎZXcaÌÔ¾‰%Õg£÷åxSí¸ƒ÷#bH×<ïÛè¹æ¾í‘10 1@©ž·mÊõ¢1u«©)í@4áa}È5ÙnRš€¦0ŒÂh»ß«žf¯sÝkž*�byÏ踗PZ,¿è6¨JÐ!’D’ó?¿ïrmKtí2E¦zBΨò]5Ø«FÖKŠI¨pV¥PrÓ„¦²áú’}Ö–ÿR+÷Ãk+Àž³ „öÑ 70¬µlŒñƘã[ï¼óp‰�p» Hdó•¯Û@¥è¤NÄÔ4³&ÿ5b›•hGåì§HžZ$_ŹŸ6X#ÿw˜œú¹—và«õi–ü;U?kJý` 2µ @,=¹…õ·¤Ääø—81N)”²…»Ë Tò´æfÆ"úûýÍË?Ïïw‘ÚɬQÿ©\ÿ%dTÞó©›å‡Þqß�0úû¾{|†§�ŽŽž©ÉkíÌ¥ŸÉÿe䵟'�óú]×Í&¬¬:ÿkW~ù_§äÉíìþ¯×ËëÖ¿Ó[r¿WxÞ~&ÿsôÝb  ž[¨ '¢ ÷ܺ½—ÄÎ�`5xö!AõOˈä�ÿ´Øhu R}¹/9ïnþY>׺™È®~³xUÜ~eÙ£õ\“[޼OÔ‚£©MI~œ«0%P9® YÙþ�ó5Y$%•H‚´zØK2™žxÙÝÇopÀ‘ˆìD$¶ÏhCÃWÄ(’¢éu,/±ùc@ŒAkƒ#ŒI‘ÿ¹?{rh;°Hr€,‰ 1DpÐVBÆTZ³ª��úÁ錺lV Y£"È\1¬�0fªoȘԽFûÒ§u'¢rÈ[8×ÁºÊÑÏJ¸sœÕ,µ³œ™|€÷#¶[ ×¥u‚¥~sÎ¥h݇«ê/«$;%ɧÍu.8çàx.È,ûÕºj»Í©Q!†rìuºI®1„2\‰0"‡½z,‰Aò57*œ˜ˆú|M®Õ" e?§$¢íl«ãö ê÷€!5׋j€ç¤~m–”9é¸h*@~�rì?‹€DfqþEXêÝüý¢J¨Ö)‚õ l¿”©j€½§i �Ïò5€ÐL¸ J×kÁ_†;Êay&3ßÿàƒŸ»éÅ/~àJ�üúçÏXŒ¡Ý–*4@CCCCCà cŒc‚1æ´6¸äÜÞÇäügªÈÿÚQŸõ)òŸËD çØþü¼$'Z@ûêü“Û_|"ÚU êúçõ/!óB�— Áª©7“mÉuœÚ„éØâ€‡pâ.¹þÅ!$òŸ³È ·,€º•ç®Zs(¶Èö”•Ÿ3âªÚnqü%Èy"¯l»Ë?ó®»~è×>rç/[k¿Ð÷ý“Ã0\Ùl6ÛÍf³†¡¸õóäiÛíÞ{Œã8ëáZ÷†5U_Øì¦_�¿½ù_o#;פšô¯Û,aKòéÊË“Ý]×a†Bþ/�±ž&§®{眶Ðã•¶Þ'!Æ8îôgD±JgRñCIH¯IŒ±¤ð¤ãˆú3 3YRRMIQ`SÒ6B©7CÕv §2L¯§¶! „úe¢•Aé`kAÝ`õ�Š”Ç”v3½~ë�ƒêß"a†ÌR*TÒ·¨‹KÅ¢¬û™CæjjÁJ™¢ik•—!:[`PˆÿCm†¾´rKž›Í|ü÷?òÊûî{ñ4 €ç÷¤–ÐÐÐÐÐÐÐаD444444ÜÀÐÉ0À®ëž¸haaWfÀÖÈ®&ÂX öü¸õ%ö_£ý%@ "ÖØxý;­#S‚@+aÀˆ’ !µDmIÀ0H»Tœ¦Sü·ƒAi?à$HПù?&§?4æŸUÀ•È@ι›yîʪ>BΈý?4+U+/Œ,špÖà…k¹"þÁi»ÞßǹðÑúåû~ðÉ+›ßë:÷ð0 Oô}ùèèÈÀCäŽûÇq»¿æü¯ÉûÚù¿tïŸEþw[5¡¼üI—fùy`b³&–®ÿœP��±äŸÏüô=Ïúsuá[÷+ú¾rò›oü©¿.FDÜ‹î8¹ÓÙh�Mzoêµ/Nöú}L¬}æ1Ÿ_óï´ÅgÝ,ö\ñÿV{V;¤yzÁ³u»ÍHùž!k)8pº¾ÃƳ=ß뺈ÓƒÅQïø¦ÝN.ˆH/"§øÑGm"€††ç)b6#�9 ÄDà†qÄéé)N³Ã| imM•âC “I‘ó&•t"‚èFï±Ûíà\‡¡Míƒrk Sz¦ï;ÈëZÈZ ëlô]kXIû!Œý�Ä ´Fu§_×.Óˆf q]œîJ–3›’x°¬�r=CD°“ë?ƈã$h`mä}33üè«m×ÉH¹•R:_7K„Ê5U{g�ÿ�S]f Öm?@å;„HD H¯€,>Í/ƒ™µR¨¯YJ†HëxMx(¥³³³ÚP„áC€GñÞ‹šÔg}ìi6ɼÍÍêp:�¥'Д #ØPy­l'?‡yÖÐì¼™Õä?½o÷K'©¾†È¼=Ï�㞎^ösŽVÆkª×Y´¨Ž¼"þoÜ¡ûʕ˯‘ßS§,ßs MÐÐÐÐÐÐp£ž,"CHfòg|‡;TQöUœ~vì'K"àù¯ä³„¡Ÿ#ÿ‘"û%r"ôÁU:@~>Bă‘ÛŒé7ûÉý_ÿRÚX#ùiÊ™žMRqn1d„D¯Â‚´ma�ù—Lþ×éiÖ‘ËÄ_¶ý UÄÿžó¿úCÄšŸ‡L›µ Xlk�øG™0÷ÑŒÿÓoÿÅŸ~ç‹~ÎZûùaèîûþ±Ífsy³ÙH&ÿór™4õ~ö;V“¶µÛ-‹òdp=¡¼tîçm,ÝdkIk½mM¸z¼>®¾ï‹ë¿ëºr¬õq.Éÿ6Á÷Ü@$ î¹ýä®K;û d� gÇ;ö'ˆEô3·ì¯-/RÀ¦áú‡ñ`÷ÙÕ´�C1çùÀ®Mp/sm+_Ÿ! žo»3�@=�o[åÅ›‘J•ðâÌó;ës “ùtÆ}‹ÇJ×°,.ûÔåU÷\yÉ{?1|VÀØ>a Ï_0'‡¶ 9ÆCÈ5†`Gìv;ì¶Û”à=D†캪Πäî[•@faxï±Ûma­Kë[*õ޵©e G.NîU×}!Ä]‰ÑÏd½±©%€ˆ t=ú¡‡÷=82#2#ŠœÄ Dˆ6Bàfm r›+“hÀ“®—:Ü3AODE$Q…ðÔ)Ÿ‹pªƒ€$¬ϳ®Ý–iéX,ˆi!üL‰ 1„DàËRô™®—ué5É"fƒ5É*ªˆ�%¢ÇËÑóÍõkÒ"ObÓcJZ¨òo§¿Ó21 ]½‰\å½Ñ‡fmkRJ*×¼®!cô{Êôl «ÆÂLî×­Àh­ZÑmÊ,•AëuägÂ]ÊV0{ýfÝvˆVDûåíÕ2DÕc¥Ž“ýBpFMò쿳δՋ¯ZçÙþµª­q7¾–™-R¿»�ù½MDíæÜÐÐÐÐÐÐÐP¡ n`Ô®ocÌÓùñ'¶wnñŸ'óŒP&Ò5BÚ‘UÀ©�XûÂÓßåqŽÈ䔊ì—Q‰íÝDþ3—e3³d Ä7É�yÒe5i€}j-À#sA˜bþÅCJ‚|>2‘e™ð7€Émˆðfó~�åx®Eþ쫹ÒJ ÿ Âú±Ëý~øW_ôw?öð-ïwÎ~±ïû'û¾j†+.\�£££B†ç×Ô(Ý�'lNýåÏÔ·vîà¯'Š—Äzý¾[ ®Eþ/#w—ίzR.Çñö}_~º®›ío-™`™PÐð¥�™ û‚[¶wê+,ÛeÌ8}NB£3âñgB€ì¼Ž¶sGßüÑso@Ç>{0Ãê=°>|Þ¿Ô¾æÄ2­¯wèøóîÌ�L-"x¶“Ú_ê$¿\ãtSï¼ö¾Ë¯~ï'îþƒ~Çô¸‘m„ _Z}*“ |)óÞc»ÝÁ_bâ3ñ™ùºä®6 ¬sè‘k«}¼“#~ôf·…€S�` ŒI®xÄhX÷óz¨®�2™� ×¼¼°$²Þ:t}‡M&a%¬5 ƒX{½SJ,‘¹K¤½Á^ •S—ÖÚ%r}ªÏ˜9Å´[3«ŸrË¥cY6 Šè³jVnó\keÑ@9ÿ,þä8‘–¶*–p9IÀØÔ Tÿψœê2HFH4`;?þToLBÓÜN ÒyEp4ˆÚ€™¢‡Áû®•"îëˆþônš¹èˈ?�Û4’ ¤j�V"úi1jÓ c.Ø#ìÓE@ù+—Ögé3ƒª»@åê/õ í3û­h:VIŸ!™ÚTü'ÕfÓ:³³Y&=‹àÌ•hÉùËÚ"×�Ã+™ÙŠˆ`8EÈÞëÑÐÐÐÐÐÐÐР nhä‰9�$»¤I“gv„]t\ž¦Ê‘ÿêøÀ&N®ÿLæsvÛk¬?ü‚ü×i]öˆ%%@EˆJþG�ê¥}@v'ò_�8ÊD*’Y_[hÒ@"ÿ5ò?ï'Nm $ 0‰ ¸žFÒ}˜âv9Ä:fò_�p Zô=ä`©]Ѻ]Ž<h›Ïwú–_ÿ¡wÜû¢tŸqÎ~q†gú¾ßö}¿=::âÍf3#ÿC¥‡nvþçIÓtˆ´JØ×àË(Ö%‰¿Œ�­Iø<©^§,]ø³ž¦ÕãK§~#t]‡|ž}ß—Iò¼NÞožôΟƒB‹ø|!"ÀÜ|äo*oÒÃKW¿—¹ÊIR‰öㇶ»æÊÏ÷6s�gU¥Œœ«Ñþ‹´‚g;¡L繞Ëk@€ÑûÒÌÁOÕå8O^9@^L¯#—Ö‡–Ç7õ‡^âî[¶÷ètú³ÍÂ74<�a�ƒ !õ³%;Ybéó^ÜúÆ‚Œ�uƺä~·NIyëÒö:Û! ã5’>¹ÎCaL"¾9Xë`lŸˆyï$¬¦eçMþ‡fË9tibÌZt]�¡÷ð~L5ˆÝ'Á#�`j@ˆˆ]L�… ²‹Q2¾jÔkž\÷Á¯HI%HµPœ .뤧tŽn&òœ¶7O‚ÊÇSZ_Õuœ5Î¥ÖN_+c,ÈR!ݳ£�•È–’Z�Ÿ›ÿ$`ýصDœ,i›!I)*^©ý¨bígš^Z_‰0ƒQ*ÝuL›´vµ¸`J�Zß—Û hàRi²ýAõúêš³Ȥ¤оfz)Œ,[^ ñåp)% ɳl�´Z"]ïff¥¢ì•'‹ ¸sƒc|ud¶Ìl…ÅHzƒIþœ9kÛ͹¡¡¡¡¡¡¡¡B444444ÜÀȱï:I÷Y ÏÛ^|“:è%`"Ÿ#À#±r×#“÷ŒDþ'‚_�]ý<¹ÿÙ̈<¦õ4š?=îµ=€Ÿ‚©uÀ’ü_!÷¦G51 ˆL±ÿ’DÀ)@rk%¯¸ší3™ú[qÌ.cIþ˜pg¥u¯’ÏÓöXD�³z„˧öøŸþ›üØo}ìöwt]÷Ù®s÷}ÿä0 »¾ï±ÙlÐ÷ý«„{íúÏÎÿtzóѵ àÁ `Fä×"€³âû'çÖtÌú©‘Q!•’þDóǬÝÁ’m�•ýàŒÙí³¯­�©btB¹A†¬8W^ Y¼.ŒggíË÷Ošoóæ£x'9"r¬ŠKž§èº~Þ›>Ê,ºÜ˜Dü;×@ßuéß6ÅÌ�Úœe"Gø1 Œ!†B.×Äzrí[1�(`“béó²u”½±¦Ô>pdëK-±Ù ‘ÜêÊwÎÁÙÞøÔb@£î³ÀÀ6õw/„dDh½㬷}>jýcUQîáe;“#ž5ö)†\‹ø‘"¨ë¯em¸$àÓÏT§•¶4¥Íp9Êž³pL"S)$3À´Î�ÏU˪¹`5½VE€Š$ȵ`Ѫî6“>Ž”4_©G$�Û2-€„@$ê„ÇÜiOóúD²p YëvȘ$\˜¨”Ò@t'”UÕ¾H4ö&ø[µÑÏK‹J¹0¹ÿežv ×®äΪåç¥ÄyІ%­/ç[ì|OAD^ð™O}òÖ¿ä¥'"bE¤|ØŒ¤‰††††††††† MÐÐÐÐÐÐp£v@øhýÜã'‚û. Ôù_ÈIäðäÚG&þ= ÏSä¿@<"¡üÂí¯‰ùïó/�È`£ÓM ”É�.†Q"ücLÎÿè“€}rýg!‚°:ÿ'1C!ÿ³SÖœÓh T1ߊixÙ}1qµ[È�¶iëc_8úèßù×÷üç�7ŸtÎ=äœûÂ0 O Ã0•ü<™»ÛíʤgMü¯‘ïõï½SÖôˆ%™™¾>I”>%&Ñ�jDÏF�iIÜ/IzÍHk%•8�V*0,†ò3‰ÿÅ=ß²t \yqÎñ•mmë?ø¹WÜÿ⣵fÅVz44444444Ôh€††††††5 àcˆ‰À áÉ­àîMv›G0kOëLÊ#V‘ÿJ¨#¤ ¿ì¸Ï 1‰D<¸¸üljì�AÿÍÓ6Åë~”üguÏ&– µSVÈÒž89ù% ¢‡ä4�X¥DF2wĹóJþ‰(;5¾$ðÿ®ã´s»€'Hóÿ¼ÍL¢•],ÉÏ´Ìø/>pÛÏþ³ß¼ûçŒ1�t�}Â9÷Tß÷OÃ0æü®ëJükóï½ß‹~]’ý‡â÷ë/ ôó�ÿ³>± ç3Ïluœl¹ÄùŸÉÿÍf—ÀLè�÷UŸwÛz{~yÐYqÕâÈ™ÏüÏû*WmTÊ5ˆ×8|žîù˜Y¾Äc¸Þk·L0Á5^ÂÅ}kí~x]ǰ'40h±ÿ _1è»lm T¡£�Ad†1¶¤ýç§Uê'oR?y�÷g8JÛëºÖv`ŽØ #N®žàÔl‚/äï¬vÉ]¯êÚ2wÀWµ†÷ÛÓSˆÈ¢ÎÐõ}d7|f�YRÂ@-)›ò*¬„ †ïS˦)) \%„ÈéÌ —*l=f¢ToÙ*©$6åøø* ÷¦ª©bU/š½–N"2K/8Ôþ)ÕeÖmy g‹NvÖ ÚÆ™#ݬ=ƒƒ1R„ÎÚÔ²À¤kš]û%•«8ø¡ß)”˜/î|¹fQøz%ë³`ë/Ui/ú^•yû}¬&Äs:å×(·JÌ¿dI@%ªKkȬ(ï³ê¼Ö4Éu AYx ´¸³¯%“žóÌzDÎ]³]ëõ>K0pÍ‚AÖW:9½ú "úFDJÑvžö _ih€††††††µ[ç¯ý'?0þçÿŸÿöC¼);M¾xÜ=Àœ�ü`ý�büÓ¼H(d¿×¾¦H(ñúÂ#¸´ð•0 rú«+? ²ó?G¯ H¸Š—Î.�Jí_µˆãtLQ[HH®ÿù¯Î[fÖ†›Kòeºï¼.•:æ›ÎZJ2àšð¯W¹›�^êþ¡wÜý·?òàÅ÷cqÎ=éœ;îû~Û÷ý®ëºÔcÕ˜™Ë+ êÈýt˜´ú{:Ü}òÿéVìíö¯ßyŸ‡Ú Ô˜zÓÚBþa†=òß{¿×â nu°Œ²];÷†g�$bâòOÉ©ó¾¹ó¸ÏÙ®«¿ëqþÏêô^Üê o ±¾?œ}üyb?]»j;„ók*híþE“Ðiåt&'ÿâ4Í÷Àe”ïõŠ´Gñ²­ƒ!)?×Zu44<ß‘ûË[±àØ¥hwC0œR D,§ˆø…�YÇÿˆQ’�Œ1è†C?€@pݘ䤜îE`(+áL˜ˆ&N­ª…XÁ{ŒãˆÓí1F8ç5•�5VãàbËjX2¤©™°Ö11¹øSýæÇ±¤"K¦¤‘~VÇÍcð�ÖP¼*øÌõ•Õ}§$%7kõT F—õR&d“û¿T&¢SýÇÁ‘ƒ ƒ4Í M¹¾„³šêúÑÙ”(�_÷Lþc&¾¿Ô™´wHc÷3+.*(9»äHc*Õ„¾ÆòË¢î—üÝ¥ªïi1N-‚‹ˆ¤TŠü�AâûŸûÒgg¬”¦—›™“Ò1J>Öè!<¥äd 9™ »þ£k’ô J¬™%Q¹Š½FßÕŸ•ëŸj‡?kïÓµèì…È;?yó¯ÿýõÂ4ókͬµOv]weŸãþsäž°=D€Ïöp ò¿žÐ[,—_n£dò?Ç’ü_ –N}§ýn‡a@ns�Éÿ¥Ø¡N=X êó­'µž3ˆdº›°i2ß0-Èëë¹î‡"ô±—¦‘Â;;ï{}§pà³~h9³ü`éý‰Ò=Ahv«SÜËý|Ȇ�r©Ï{�œs! Vzé ÿ hÞÎDVZ•¬]§üѵç}ÃÈÞíÒ3m‰ˆ°ˆ°4@CÃó|àкBhæì6d@Ú›ÞH¤\©'DùÏ C„D›a“nC�…%—\ú]k·SÔ}(FF4™ÌÖIÚϼ/Ë5Ç8î°ÛnჇ5vùïœ9*÷RcLI(ç•�÷dRŒ½.Sï#„€C,Xž! ˆ!‚]‘Ñèþý¶L‡êœ´_«b‚$¨´ÎN¯‡—Õût®5—5›¬Ô™ù¹Â^ýIY„iæ„—áf­]ÕìTð‘ϱ4”óIשí€�9Ü-¾Zk¢¸üœý4ë^C ŒéyÑmկǼ MdNÈ5M ™HþÜB ÊB`p¨ò)ÅÇT…쉖]r€d!g§-/Ïs3HE¾¿Å^ À˜“aPzß%aQCCCCCCCCÄ&hhhhhh¸�Á‹Þœþ€¿Lq“�8ÜzË J”?+auë#¦hþ, Èîý8¦çdL&âñ�P‘ÿ#5U Äðç‹Õ?‘ÿU;ä(ÍBþ� c †$FàìúO‹Ä’F�D)¶ô ×èΔD@óÿ‚9鵇B�™j6o­Ÿ6í¹üKû�ZP2A�+§öÊ�ÿ›»ä7?zë¯xØZóˆ’ÿ—ú¾Gý“'d³ >Çßפ{: :·ÛÿÑW÷n½–ó?;´ÖÚLÎ5SÈÿÍfƒaf±ÿyû5ñŸÿÎÄ-:¨º ÏD$"Âc0cyCÏ’,ê…«ÏÚêå§•ÏѲ·|%¢šŒ~.&�åŒ}ý°^fM´¶Ÿ?|ˆå'h¯äÅu©[ãÖ÷:pÁ+§àüTd!@¨7Nç»NR'¬ˆ¨–­PêûÝÊ.vÁ�Q$¢,h°††ç1¶ÛX8õ¼�©ŽÌuQ=nißùbÄ8ŽˆÁCt]ŽÎY¸®Cßu g¦2‹µw½Öd 6ú¤ÕBr³ X¸­K÷ÿÔj(b7Žð~„5Ö9 }�±ï1h]VH~c 1mmŠÿOŽþäê7Æ€ì¾r"Й[ Œ£ÃnKË'c 8ò¬æá½íäsIb£ÂÊ ŽŽ63QeQ÷9O0{5ßL €º§¼’Ò̈KQ‚¡"v°0åx³ £®%³ƒY`Ì~Z‹I³À¨ CX—mxÒ5¾)“ê³á8ÿ‘¾í9àë󦕊#ý­iÈaS¾7N§±Ù€4õ"µ7ý.@úý'Õ&]K2 °¯@dÚß|Еù)/Îçй­—Ä烟Uë%:°›)áìcxVe|:ÒãKÉ�%"C  ¨¢i€††††††††MÐÐÐÐÐÐpƒ™—Žë_ð4€Ûó2§Áà‰­Å]ÃN#ÿCúQ!€°þEà'a€ŒàìÀ—]¤eÆ×Êqü™ð�º]Ä“ó_£ú¥ÄCÇjH×ç‘ìúi? 1ÎÓ"+Ñ¥û̹šJPÝÝ^D6×VÕ3w¬™»þM5AÊ"ȳaFþy2ð“_¼ðÁ¿ó/_ô÷¿ÔÒz”ˆž2Æ<ÓuÝqŽûÏ?y–™ÓDxEþ¯õc͸Vtþû<äÛR Õ$ù?õš�÷‰ÍÏ—8`�ýÏ‘ÿÃ0¨ {ä��¯Á¡v‡Ú4|I"âË'î89×ÏzßœAþÏšÊ.\ít†@g6û Çü�}œkb»=HuÉnþÕD™�crZöŒƒY¶ ‘Åù.E×o{¨i°\cRþZŸ¯•—úéãˆ„–ÐÐðüÇÕããDþŠ %õ¨7„½qš™¼Çn1îvØn·Ç¶ëàý2¶ë`­Ã08&º¾�MŽûTo( '7»°‡yý“‰ö8FøÑ#šˆ®ïàƒŠC(ä¼µ®sèc¯É‚€°_“@ÿ6©—|N ¨ÏB0ðÞcÜí0v]©›jáe]÷‰BŒET‘EµS}µÁÑÑt}—ŽmÑ6©Þž1²šu-ahùAvéDka �È�¨ŽVµ›µ6ÕzÌ0‹6µ0!×”iÛnJRàœD•οԙ¨Ìð«ã™L…ºòIŸOcó”J6küC“”/ŸoÞZ-ò£ª¤™´ÃT¾ó2é=˜—5ˆIjé bô{© FISöÇî’~±WGdéÂ5J,(/0//du׮ƖçÞ¼)R™ñå8¹÷Ý{µ±ÖŠ˜;¾o~SÐGqÀÈ€”™Ÿ…2–ˆ³Eš‰B3ÿ�Dð«h åS¦~rHäÚ¿¸XRÀA�‰õÑj?: d²IÇÌYŒä>Kñ不:›5“\±Þw‰D„jÜžÊx<¥ ntðÜÿįÞù¶ï{Çýÿžˆ1†ž&¢«Æ˜ 3oW«•$â¿®ÓšHð’ü/¯ùœÕþRVÿ’ݺ�êekâ¿Î6Kë¥ì¬2Ë?×P-–Kõh­µ888ÀÁÁAv:HÖ¸'‘ÿûîý¥ò Ï JDþúÆ^�íb뇇8 À©Ò¶(Î’/¹ö¢ÎþÇé·Òåü´´smá¿´2Ñ €«ý”³÷á\IJ|2�¾·íöŸ‡œªÌAö>Ųº|K‚D´f �\<÷õ¢Š MÐÐð"ÆÑÑQȾÇèºB‚)ìóÀ;�Á¹Lþc»ÝÀ{c-D]·B·Z¡³]$Ý‘³õƒÀ�%Øï;ÚÅ':e�×Ä)¸Im-êÜûL —Ùö«® ¢†¸.� *à( M% mÞÙ0¬é`­ƒs¾ÈŠOËzÚ!ÅRÞû@ô{™”7¸‰3ÒguÁIj½Bgm•í? -S•,Ñ믎) ÙJ�§jIÈ�Dá÷€—K¨*Œ*3Œ¢ ŽÎ–n*Å¥ÆX°‰±±—¼Í¡ñ¡hN¨£ÅaE'÷ɲ?GªHùÿZÆ)¨ˆñĈ'³/Ò‚ �íS�”µÐ (@> ÅF3±$°(©}ÒYÍdåPœWpß�,HC8åïv~*�€)KB)DhxÎý‹¨ª{üÒÁÓá9�±w¾Ê»N¸ÿ“ˆjÁ.éŸ;–½Û S w“øYé€`½¬2ÓOLú% îÉ9`6ûþfiéãSlè¹$áߤˆá¿|àÞ÷î8 ,%#ØÐÐðbÄ&ø‰z$Žä¿aÀ°ò)í¼Cc€ä~d¼‡5Ç›cãx}„DµöÛ-†ÁÁû˜e-ÿ˘!9$jvJ`'+z?�kÈŒç…X v5Zu]v"P¯±2•Bœ‡�‰ÁÆ„ìÿ"Cß9WÕ¹'PáŠ�ö㼇ÜNü œ "0jfâ¤q ,c¹RPî3» ”ÛЩð€’Ð3þ?ÅaLÚX§m&Þ‡ë#XÀÄý{ïŠ!rZÆÉ3[º*ÅÆƒs7 YHA„�û¯DÍÃ]¦Á'CX¬ÙýñgEŽ›cœSÒûc¢=�¢Æ2fI:¹´]*„w…k�8\;b%Ñrsˆ—²ÑD(öuv~*=¤Q(%PÆh'eÝ—2O=‰bßhjÄ=kŽþ· L,Fáujâ'Ÿx앟øI¯4]&æ©0¨¡¡¡¡¡¡¡¡!  ^ÀkcNìTÀ¯ø”ôxbs÷˜‹8`´G˜©L¶ûÑ@T€¡ ÿã{éCÙõqÙ2‰3d ”Êè˜ÕÎÓXqq?Zé«@½Œ–ÿIˆàã±$‡‚LþIP€´Í"ó?vþ±duMU-î\–va’h’ý¯¯‹Ñð’w¼ïŽŸýö·?ðo¼Ø‡™ù#Ìü3_bfIäwI^gÏÊjRßu!óÀdÂ{ '¹¤÷u}Ùz»5é^Ûÿ—Û5ù¿^¯±Z­òr)ë»Ýîdü—"Åd9OîýR„Ð&÷nˆH¸‡ž¸ð8(Éï[WÌ�yþ–÷2ÏÝפþž y7t’Å-Ïf3 ;ÿzÃ:ö[©€Ž%¨iU² ´ðg�û¨Ú,—(ÒûUwû¨Ùdû¢ï‘ªŸ«„N ¥Nöµáâ`“^hùž½^u8î»+€;°à[ €††7¼÷ð·ºõISÉ�Ä(¾˜Ô™ÏÙßlω :fã÷C»]†a€øPÊJ5Ú§'¢[%“¡c÷O;}žøÑ]ÉZ‹®ëò¿»«¥ØÈ{?Æ:±Ô€±Æ8vc,†¸M„Ìc Èlgóñ13¬q1cžJAuè¢(Ô{_¸$«ûû‡(Ÿ]¢èÝ“F%¦P‡~$þ]^o:<†mÏ 8ËSo…0™a A§µà‚`UQ8/pqŸé<%ÆuÎ1T–ݲNiá½f÷Ë=ôÛ-ú~‹>þ;˜oéª:àq|RTç–ˆîq-EÉ(3zºj¸Û-êC%ÿ2øãu(Ë ”ã&¥öÕpÎ¥3E>>èŽPB ßÊÛ ÎYÅ0‰„â6³±UÖ'„€oºí¸ýÓ Ý·_º°ÅźÀÑÑ�Wªê/ŠŒ��50Í ¡¡¡¡¡¡¡¡D444444¼�êh_Âßðå[¿ä«ÿá×øv`´ „Úއׯ?³W%fõG+Â]dˆŸ÷B€�MÎȉÿ1“EòÁi[ÉûÙCYÃ>¡.9TªñßÞ�ÎÞGòßífþOŠ\/OÕD‘î¯]Ιü§)aWgÿgÑ ¶¬Ù!fÚ\=²W¾÷÷|û~Ï]ÿÙó83_4ÆgÕ›»h§P]ƒˆà˜31žlûW«ºn…aè³à@„ª¯ŒÓb›8ÃÁI©zØÞÆp5çI\-ù˸ Jñš ÊdÇl f¢¨!”[袳�æØ¶* Ùÿ©LAY&`,]0w“àÂDG©Ð>€Hp…ê‡Û~‹m¿ÁvÛ“"bR`UÇ"ãØ¥;Cn=FN‡Ê‚ü¦¤õÓ±|€êtñÞ¬æÚo'®E R «c¹CU²´X•æC�ìP�x å N•ù?º9äsNa ��磫ٛ•î6 �B…¡ï_é¼ga³ë”×ÐÐÐÐÐÐÐÐÑ /`Ô“E¶ö÷øû^ ŒV‹×Ý<Íp¯}*–b¶þIþ�mü®�™ÿñs�$8Kec‰±”)�T²^9MÜÄu%dük*? >—3ÿàÙ–&�3RªÊ,f2`ëÓ8ÑÉ©y®KÎÅNŠíIaó_’ÿ:Vý�ÇõŸÿèÿââ�õû˜ùqf¾h­=¶ÖnŒ1Ã\¶|uÝfÉÿ2#ª\¦œL�#˧§¾,Xr˜ÛV-\˜s&HŸw]‡®ërÖ×u`fxïÑ÷ý„øwnZ϶l�ÚiÀ“¥ƒÂIçÙps "OD==}õàñ;Î ¯eŠ‚Ÿ7•b2œ—žJéRMùçýLNx-—;A\�my÷‰Œè„ãˆË—%¸ÜdñSåT2ö9‰dº9Á°#(Èš=ź´ß†ALj@@ÀSW×ï'¢£ø×«j44¼èãSb<à%Øð+€�«1fÄoÝ�@c ¼s`¶ùÝjܳ˜Å'+y�ŠÌÇ€¹×Šq^ᥢðäC vDÁb×á€_uö w¨i/ ïáÅg!ãÄ!©0ƒÉ±P,�ÄŸuœ’ÆØ˜ýßÁvvR*ÄAÁå Øú‡õذwyYŸHòmkìXJÀ9xÅ•¥p€C;2 IÔ ¹�5fžk¯8‘óÆ ³+kÐÙ.Š4‚ Y¡±ÄÀ�…iåöD4 €Qœ#Ås$8o`Œ…H ¤²Pýv‹aÛcs¼¥aÛÃyc˜ 8Ø7üâ˜TeŒ"�_�³‰pŽÄºÄ±uBAgÑðÉ#n¹îR†<1A%¼’PÖ¦q=‘ú£Q_LMõ):œéì'T{s'žÁMŠ–ûóySµÜüÑÎýtνÜ;ÏDDj”l¼o›P¸¡¡¡¡¡¡¡aŠ&hhhhhhx£&ÿqúuóoô_ú�þñ×ø†¼@L‚ùHÿ œãK8ÄqÌÀï!¹@…ñµh$ùY²æ5rT2’ãˆ%4NȦšá‰4ËI«1ó_}$ÿáïâç�ü—Tk›Òö ï¥Iœ%«TëdŸÆžs™&9ë?þù`-›ÿ-@/ÜÿЯÜùýßÿ ÷þf~˜™µÖ>c­½ž&EK·†°ûÝ:´%J"�«Ú°µ`aŸÖ)_Oú®|_gËÔ†òûòxKò¿ë:¬V!9+eþo·[l·ÛLþ×vÿõþkËSL¨×Î · žˆ¶Ì|üØ•3¿æÁK¯½-[�dfêBVúR§Gc†ß$›>m¤¾ÊÌÁ.ùŸÖ)ŸÞ�gÖÚ¸êÓòªiúb39kŸ–¸Ãx˜)ç�ëþ(“FU™€9дôÏY7È }(—ÛZš8/Ò ©{EQÁÏ¿ÿÁ·Ñ13o™Ù·ç´¡áÅc ¼x ’�ª¢Eª2ñoã+ƒhmõ-ܰ‚ˆ@°]„V�dVÍÖöÉ~N—E1›=«Ó:2)K�5ö²LX­WèV4ÚÒSŽ9 烕}Ú†ˆÄ:ô>[´6†L¶Æ7fêúTÇueüd¬�5&º¤þÒ‹L\›²@ —jãB7„LùÔ/ÞAÄñbªÒ¥§ö_ÇáF³(f+„̃®[aÕ­`ºpÌÌᘶʤ†Òb¸œÆ±ÉÁJò—ª³ƒÈ* Òrƒ Û¾�ezˆ©§ÃßäÞ-œÖù˜3ßÓ:¥¸ãg¥Ý¿î½gÃÕ:ºysÿ›/0�[nv�imïýËE„˜™T”„Íü¿¡¡¡¡¡¡¡aMÐÐÐÐÐÐð1€Ú®=N4ý À'c)QÆCÛ߆×uÿ5ÚùGÂÛ@ÄK¢?(Yúûlc�’<³u?4ÿ�ˆSñ�üb†ÿø^Óþ¼ Û” 2PïÂöâ~%ÏJ1û#Ëäÿ©¤óé%L\�ÿ±…¸šÊ›ÔúŽä¿¤òa‘G¯¬}ëOÜûmxüð]ÆÐcÌüD$ÿo¤Œ÷¹¬ÿtÝÊ×ñðv3êëë-yÒWv¬hç¶y3™ñÙât¦�—Ž­üwª£»Z­òû4Y�2ÿÓk�ù?·Ÿ2ó¿´ÿß×> ·À–ˆ®ðñ;Þû{_ÿìç(=âµbTµíg ˜�–À’¢`ÞJ6ûæ2EB|~ZÒ§ä{l®$@œµN÷%ÓtY©H %HÌ–g¡©�ÿ‚e?§ÈÖ‘É.¶ ìZÿŸ®ƒ(ÚP§ÇYi)œŠׇ_ñ¢í&ºI´ ¼††—ÂD’±ðFÀìúÅâÜ x¥˜H‚¥<X˹�M¤zèBCvþjª‚Aï#1^ô=4uŒÑ9 g C@ž¢U?ƒ Úl9˶Ҳ*áÏ;‡±¦|²²÷ÞCEB\i"†56Ç@¥X±.·”Hõ$~ 1N˜†ëV!¾ãB �úÏ.–)HÛI®‰´ú* 6³ÿ%êy$¡"Ã_%mE)ˆcL&Þ9NÓY¬ºÑ�É‹‡U…÷e¹«èDåøšÚ¶v±òðÖÄýJ»¡”€óÙ5jpƒ(š �Û±Œ/E­sC¦"¦X. cÅ€‘¬/ÄÂ�d�ŸKLÊýè¸_U$Ó›Lô×ÖüZöeNÔg!‚¨aJ—§rQ2Qœ¹Ö‡5mÅT,±l¡0›…Ÿ½tŸÂé*Ýâ$D»™pEDîñ¬*DÔMœÅŠßm­ ^¸(-DKò_UñÕ_òÅ×Ã7þu?œ–O“]Gzw¯ÂƒüÞ˜}ßGëÿ�M´âO‰Yø †Â§ú�Å�Hþû873ÿ¥¬™�8¹Iÿ´mu€sAP¸H\~ÌÜGEüW™¬z‚v•ù?!ÿyÁ@²$ÿ5ÿq§€üÜ{ÏýÔ7ÿÄ}ßí„aæ§�1—¬µ—­µ7RÆÿRÍÉ%B¾&¾kÁ@iû¿Ïú¿Îè/-õËåê÷õ¿ËåëÌÿšü/Éùô—&…ù¿Ùlòë0 ;äÿÜù—Äÿœ›BÙž;–¼ ÏÀ1€ë¿ø¾ßõç~ÿ‡7¶ó»Œôéff÷L-?ÿØ9Dšù’–û�“;ãj� ºØ¹.µLìßD§…ŠZeî§.U÷ìû£ ©úÎâó‹×í£nØÄ£ ^0ÖÂx0Gó$E*Jî‰ÀÞ‡×XSž‹ØaÇ„¾9ÄR‘dö!ó_´ µ)ùD� %În¡wIíDà—q‡a‹nÕaµêBŒ­{2ü]ï²KQ"þS~:Vƒ8�ÿ�íÐu+t�…a³SòIdÜVˆ‘ü¤üt¶›Ê)ÅM9¾ëû<„RÁ€ÅN ãØGTºR�NE]YàP—˜ØÞ”ÚŒÑñèÈDL€¬œ±¡DAtQHçÁDàRlKùêä�#¸„W‰q·�÷nˆ±¬�d•Îí‹;æÇ^*Gj$ÑH`²Ã=§e™¯‚¨÷ˈ͘ëh—&G‰ÒX_±+.‹4üV!Ý2Tcæ¿(”Ír ³×HC�Ýïõä(O5 '48Pµœ§gîiyo7AþǽWD˜ˆHDˆ•³‹FCCCCCCCCÈ&hhhhhhx£Î¯Iå¯þ’/þ‘/ÿ†oüQ¤\�“ÿ\Ùþ'!ÀÄò€zˆ�¥"®óåïþÙ{¾ågÞ}þgˆè1c̳Ƙk]×m¬µÛ%òÿf&žæ,ÿËŒ³šüß—Y;±q-–¯Iôr¿iÂvîûÚ¾¶$컮˓øi¹dû¿Ùl²õÿv»Å0 “Iízû¥ ÊLº¥öi|· ÀÀ5çùÙÇ.~àîë?XU½ÉB{‹Z�‘Îì÷�¾µaî8ô&ÖŸû¬Ìê«·[ÿ¥>Š ãÿ·™k“¹c§ùCô§îI¦Õ€yÛÿÓwL§\0û/|ðþŸp@ODR—@ihhx±"½É†¿ìÊ1ó= ÃçÆ˜CD× ¼ta˜â} ‡'~Ì2sŒRü³«’kÙç¬wŒ¤kp/2Xu+Ø.”pnqEÌFW¯c¹"ïáŇŒìø_0’¢‰‰ �‚è@ÆxLeê�D’¥°3ÇTQ1c‚à cF±¥ˆ@¼ÏûÛr£Ý¿j®|5×g·L t�0Îë.]“G‡\Ê ÄoIèPÆ‹¥#¥Ø›8î?”Û ç pƒÃ08xq©ÝI OtN—ÆÛjlM&úi<›˜GÄßZŒÏùË ùHü�F?4Õ. í™,Gþ�Q¶w9™b¥¤ <`ÃEÖ¢Q,Û³>o­c”Ó�Õevÿ¢X“°c�Ï ñx•NMúÓMáÉñÜt U½ëêÕË.ÜÅ@(w¡¤ðí÷ACCCCCCCÃMÐÐÐÐÐÐðÆ\ øòóMÞàN`,@ªø�|:^�§°–ù�Õ/1K_ �Ñ$«èHþkÌú‡mý³§tao�Éÿ¸=‰Ä¿8Àñs¤ ¦”y“¼$³ïc<ò¹©ÓÖÁNYGÄȳ Éö_tJü§í©ò¿`ÌþûGþû¿ø±û¾ù™«æ×‰ð¨1æcÌUkí�ìîY==L�9ô)!Ÿ^—2Ûk€r½¹÷59>·¿òßû\ÊeæþJò?•>H“ÚÞûLú'@ÊþOÝ%±Ÿ²ýKÒ?½Ÿk×9@Ãs‡ªz"Ú¸FD—~ý‘»ÞñêûžøÔÙ…gIé*“,‘þæ9LÀJ¨E|Š£Ÿ<·'ÏOëCï¯w/EŸ“ w«¶e €™ƒ�“Ä ûýtwû¿“Ö™Ñ:ÈB¦_å\5í~È€Hr*ÐÜD[/ÛwüÆk~ð׈¨Ÿ544¼XÇŸIgfÀÄëT ¤Ê˜¦ÈhgfØ"ޏÙòD€1æäd`: k‚ûPÊä'ò“ÒFÞûX}E'<)aÜ–’‚½0Œ±…JÎú‰µc^f�Ñ2<Ä(Vl&òwDŠ‘<8ï£]¿�¥’õ>åÑ,¼"Šn“rH”2Ì¢ &?éá )¿0ãOYø9† c5�‚{ �]�@2ò{gÀìãqÄc䩳CŠß˜) 3¬M1¢™Ä¸i¹ \ ×Z¼¢ï·†Þ±±!†NYå¼ÖN>Dán=l! �¡"Ð,Ö­{T'÷GYi" ‰œw—ãnšŽÍYÀQ‰’Ue!û=‡Ÿ(Á…�T²�Å(G±c7ü Ý2`å^â¯ØµàÏá͇:µÐÎ-Â�.·/þšÀs)ööØ#¹ÿŽ;î|ZU) y¦h€††††††0æ iâô|ñ_{ø+¾ñŸþ5ß•¿Cˆvx?~/>YFŽˆÿ8iF¡n´¨$9C?gï«Ä¿xdr�¦äy¨uÅ3ý½¤$ÿc�Ï(8˜Ô˜œ›1*3K–Èÿ‚ôh‘è'Ú%ÿQmOÅ :Šô÷?ø_.üà¼óîQÕ‡™éQf~*’ÿÚu]&ÿkËÿÚjvî:ÕXÊl¯ëÀÖ¨kÌÎ9”¶¸µµÿÒ¶Ò¿k€:K¿Ü–ªÂ9—-ÿ“ý¿sÁ¾µ1¤m¦íÌeýϵMùï¥g¡áÖ ª¢ª[×<ûö_}õÏüÁO{ü/­:9ȳÑ=`(„f|p¡3Ät™­Vô0&i£Š…åªíA°«XZO0!þun{KNÉ©D*’A§ë¥~gRôWË4µiŸ…SúòE»ÉÒ ÛX\V1Na¹éß÷ä™wx&Þ?ýI}^CCËÞ'‡…a†`$x'ä¾s`f Ãâ€ÁÁÔe~Dà‡Þ»¸í(°ÁVÞ°…‰Ä®ë`Ø‚ ±K°ÝÛ ÙÀ)ıkŽÙùá5Úô{)lô)Ï1CÞÃyŸmޙР/`$b·F�ÉýÕ_òÅßýåßð�ÀŸÉŸÇ×wàƒôûñ‰ø¿AB�ì'«ÆéB|²ü—HÚ;¨¤¬)2aItMĘH @Bö ÿ}$ÿË,Ý”õ¯a¬€ ð€Ý—õ_�ü¹Î(e/ÖÝÌÿ‰Ý$þuêðøåÕÃoý‰û¾åý�ü* Ocž%¢‹ÖÚkÖZM£uæÿ¾ìû%Ëþ²=æˆîúúÖ¨—/ÉÿR8Pöufî�^gç—¯5q_ÚÙö}�¾ïq||Œ¾ï'™ÿi»)«,ý¥òe{îÔJ-2ýçÚ¸á¶@ôªz]UíÑÆ>ùÐSçù·¿|û{ ŠgS§ŽñNZ&ø©àì|Ylf:+¼W0YêV± TÈÛMN(•õ¿èɛՂh*û±Ý‡xw¿ZômZø /eëÏ]I è*óenúùYö<öªò}ïøŒïð,€kªÚ·Ç©¡á¥ç$gésîËÊØ'Xò�S”ÿa\„úïQ8˜þ4ŠO­a°±èlc;Xc`mf3ò¯»¨øª¤’HÔb$þ½@œîâGÛyçB ä.‘�šHw* ^1È\ dŒÓŒµX»UŽÃV«õD€™–KñK:·¡FÂßï }E|Œ«6èS9%ï PRÀÐd¼*ÿ› ¯qL¡´] .ÎùÑ�‰ƒ«B ÿí$.“(’ðÎÃ1Eƒ­ ¶Br<‚5 O>ØæÁ‚µŒµ°&ÅŸŠÁ…vrQèáœ×ÁEgñ`&ØÎ‚™ Âo¼»‹ü /ÇG¦ z†èÔÒ_e„ß;ÆäD¸K1WcñXß!•ž BäG:ð4)a†I鄹ñt¬&0®Ã`€¹žl¨†’ËF9$OB2Ýý}˜KÌ…>ºo¬ŸòÿTÇt'†f: "•ö‡[§Š=öc»Ù>°sšÜô %š ¡¡¡¡¡áŒ¥:ð vîÀ§xCñH7ÌËñ>Ÿ€C1 1i(•³ÿÕ» Èþ){Ÿ"ù]DÆõ�ƒ" _ðåŒVäËì|ÁM�ÿ<Íøß±ãŽ¯;ä°Íb$?÷žóoÿÖŸ¼÷;œ§x‚™/[k7Ƙ�µVRÖMV×ÙéågµC@�¹õëk<·Îiö]Ûö×€r_¥` ÌÄ/ÉúÚ Ý—Î9 Àív›E}߇Ì2I€9A).˜;§¹²ûÊ4Ü4À«êFU¯©êÅŸ|×Çÿðë>Ûà�¦v»:%ôµ&¸u$ýoéú”©réý-Ú¹æÝÏÖ-ˆ—Ìv­öw²êö¹Ð̾wû&Úeaò›2?u¦| ,¡Súìf!GQÜš±[f8.òð³ö—zgô¢ªÞPUW>«ímhx±�’k¼3L]f¥ŒO¼Ç0 ;± V«‰ 089ˆwðÑyÅDëÿP‚(1ÙPÊÐW…ú`™¿Ó_I´WWÂÙ’>l�sp}Ȳ÷nܦ¸G9Öc�sÑ_’è°ÞíÄ^ÖvP• ¥’@ßo±Ùva"ÎÙÅRN"‚í¶Gßo£°2ÄV¡A$¼…ý'™âyP&DCÓDÇ(ïáEÂ÷Q”Ùu6 +xö·F:®ðïÐYðÁATJˆ8 ÖšÉyþÔþéxDƒcOŒŠxò^HDh»9ºk:ÆR1R§Ð_ÇÂ=E# ¾u<œHoÒÚå¨ÀU&?EÝ€q=JäTá�Ãj!>@á(�«1�•’ùLD±´$ùÁÎ଺?Ž(v|šQšbɉA@ÝR…^1\ïñ�³f·†á¾`ÿ/˜Ð†'üþjhhhhhhhx©¡ ^À8mV9üƒ/þkW¾âÿéçx€{�±©âŠy ÆçàÕà 伓¬ø"óßa$ÿKB^ù/2)ï Ë@¬+Æ a “ÿœŽl„`š‘?%à B1N*†šœñÏ\dé–ná<Ä Êɤ+7º+ßù3/û®ŸïÙŸð!�2ó³Æ˜m"ýKËÿšü¯3Ö—®[ýÙÒkIħ×�ŸÕ$qž®ÖK¨y’}µX ­ÓuÝŽ@yþ>Næ'Ëÿ’ü/·;gùŸêIå´î\¶#ÿŸ¿þ%–U=põ}�Þ÷ž=ý¡÷¼î>ÿ)¬2C ´*9?Ÿíö�îýé¹-+ƒ´“ùO'nQ«w·tî§»€¹ÿ ׄvŽblKÝ{´§n/œŠÿö·¿ñ-ªú4€«Q@âKç�†††7JmØ‹ò@¡&·ãç0$òBœâ%Ûø§ØÂ;ç|$›M´™·� $µ1B]tmõ½&1DÊÈ÷ÎÛûÃXÛÁY—³ñÉ>ôq}�bk`¬Éĺz�7oQBc�s€aç,\,o�ÚÃ{�¡ïÑ=D9®"aÑœm_ǃª —Öí‡P2`pðâ3ËÌð†ABy9ö2 £”¯Q*A ^â¶œ‚ Ö0 +˜8üq_ˆáLÌääjJ<¼†,~ñBé EÕ}¬þkÖ×N¾(eØd1A…xˆ÷ä¼§ëªwŽN4Í¢Oï5�ïݾD) ÂX))s�jw†Â˜‘¿‡R¶”áÁ4ѽˆ¢Xa”ÖEG†É�ZŠ-bI û׸¶b\nä÷5—)˜ZøÓT �ö££„²¬‘NsPpY˜+ǦSq¥¶Ë‚„™­ŸÊå‰NˆŒ"rWý›Æ4@CCCCCCCÃMÐÐÐÐÐÐðÆ9\N®ÖY,_õW¿èçŸ}ÓŸðãV@!pÑüv¼²ÿ è²úáÆl~h¶ð8MiúÞÇuà!ñSÂv|Ê\IŽÈ™/ -ûD£õÿ)ÈÿDfïfüó‘W[þÇÅÿûGÎüê[ü�ï¸x�À#Dô3?cŒéK»ÿš@³Ÿæ±ÏòŽÐ®—¯Eå6æ2Äj×�Dþ'Àœíyï”¶ÿi½z8M.S΂3ÿSöÿ0 “Ò¥¡v('«K!C-˜k«Fþ?¯èj¹?ý“¿úêï{íúÀß387¦Ùé¾Ü¯ç½#Ä~â�rV`ì,€‰D!yâóþíhå>pSd6G×ìw8Í¹Ê ë?ÏÑ m‘Á»9óc7¶æQfyÀuéEDùßÐðÒAg ¼PAð†~�™&E…F¦y†s«®+2›iÒ¥A À‹C�âGkRLHô 2ôÃï\ÌŠûÖ(,°2h øÎÁE"Ý‹Dr}À0ô9†±°“ |çaÅA´ƒŠ@­Bd—„óÔœùï½ÇàôQ\�bwÎe”V0vtBb"ˆŽç„!ÓÞû@º'ƒÑÑ1�9Ô�/…—iÌ ‘�� E" À‰Ù÷cübµ.ÄqÖÀD+|…ÂDziÿ3ÿU“³C¸ž* ED”E ¡½x7ÄcxRÊ€ðÞ“s< DDw–c}Îâ§é½£‘Œ%°øP Ž_y„‹¢€ò÷Ô8pk‘HiìXÛé· —�B„7ÙQ,Pôìûí�ËÐ(Àô7”btvÃ Š¡™æÒI:ÝLÞýŒøxRR¢Ìè&ªb·²ÎÀ¾ ãˆ¸»U5ü"Œäshhhhhhhh˜¢ >Q¡%iúUõ‹þÓßùgßôgü[P8²áYûFÀ+�$Ûþ« Ä¿-ÿ3&R³#@ x_dýûH´§åÒ�†6POÊļêŽív&ÿ‰ÀÄ€á±F6�¬ví^'HKÒ­ïÍæ‡~åÂÛ¾ÿîùQU}À3Dt‘™/•ä"¯ë6®Ûú4×¥&êÓr%Ù?7aµd ;·½Dà—¢…Ú^gB¯°á-Ë”vý%D$OÜ–¶ÿÃ0L2ÿë¬ÿ$*(]ʶIä)˜kˆçªzÀ3¿þðƒïüàS¿ó“îÅÿL‘�æé³]ÔÆäq?�HÞ}jNø^˜bŸ˜y¿´�t,ºðy¹-™ž“*nJÜ�'´«mß iŸ–eþfÈô8É>qW!€ÄTÛW`ªŠ �‹ þú¿ü©Oý—Æè3ªzÀFD|ÝWµç·¡áÅ�Õz�¡ï‹˜d¹[Kßk¿¬19»=-ï}´Ðç�5>vWÁ^>çE Aî©­ˆP�H�;�DbÞpˆ3Ä Â:â%Ûú{/9öðÞÃø‚œg†ak"ˆ¡¶ë`­Éìc(Z”5p.ogÕ…ì÷2&E{ ߈@hc"Å·Ñqž˜è �r°‰ê’n)§ŸvO3‰%uºŸ¥Èj>Ö¹©Èrç7á킨Þuû·ÚÐÐÐÐÐÐÐðâB“G644444¼€1W‡³Æ\ ø¯þ’/þ~UìDM=k߈‡þDX/ÿ�,ÈÙÿR’ÿ�!” ðCÈü×!íÉv)ˆ³0sÅyÏ“£Ž™?ù/‘¬’¸|"ÿ ÆŒä?ó<ùŸ·‡Ñò¿(aðèÅõ‡ÿáÿõò¿÷ï|Ù¿ðë>ÀÌ�c.Zk7]×eò‰�¯_—J4¤ š41žìhKn�¹2ÓÚ¸~²~ÚFÊÞ/³îk²½¾GÒßiÈï}&ý7›ÍlæZ7G¨×;%ÿKQBrHä-nXÊüoN·Õ}ܸ àÑÿó¯û'ÏÜÀûƒ¿o"xœ}—›%¨O¶˜Ål_Q¯?cg_®Â3$<ⱟj²û~Ofû$³/9“ÌÝŸZ9�Lú®ê8¤Zon[§AbY€¹ <:1#±vZQVü»w<øyRD.‹È‘ˆ¸%‘SCCËèV«hÉOÙò}>n’8î�ã:3£³ÖtÖ˜±4P²ïw.Ó^| [͇šêÁfÞ‹‡ó½¢Å|¨s?%75o{Œ9dk9ï g€°­äþ”JC­V+¬Öëð·ê°êV°]—ãc‚e~ÛMã=³öS xæ�ÅlF!'‡eAÓsÑé´^Úf)ÍùÅ:"I%¼ÏïEÆ2YÌ Ž™ÿ!Ž³ã¶˜Ó‘3ñÇ8otßQxï0ôäTÔÐpÞ�÷§¶Ãj½Âª[¡³l×3±Æ²f™·OmFSáaWb;�×!–BHí3q "žFZŠVâ_tK÷prg€¦±o|¥ÉÅÑ|ßMâú´�âþCK`zÏŽiñ›Ù.'Ä!É=a!.н±Y¹+ZŽÁòQŸí݆AC €l44444444ìAshhhhhhx�cI°/£ÜZ‹üe_ú¶¿ñµ_g|ÆÚŒ+öSñ�3k¼úè;`y xg½ñŸkwf7€˜ñï)æïW%‚Qk@1Û†f'…DF’>‹J2‘+òŸÌhñ¿”õ_fB%ò¹4–Ÿýõó?õ¯Þ~ÿw;�xŒˆž%¢kÌ<”„ui}_·ñ\›—Ÿ•צ$³kÂ>‘óû„åúÉNvޝ3íËíÕ¤\í8PÛó§ãJ5lËã÷ÞO2þSýÖÒ&·´ø¯é¸Êr¥°aœ|ž'üçž…†çŽ:S›ˆ]'"óØÅ»ßó¯~Ú|Å_ÿ#}'=3X5rÓ…Z»û {ž2Íla¥8#¼se“sú‡îÓ/óîF©NW;éÞáQL„Óº$��`LàdܪoL§(©o¼ K}®Y€›µã�eZ¦ÇS� |ðIóŽŸïýÿÙZy–ˆ®Êçyns×�hìSˆx{kr�{‘@Þ³Ž.A£À ’½L0^“e»�ÄréD’b¥Ñz?Å6~‡¦ Û 4„ÒÄ;1ˆµª\l;Ä�áoð>Xì{çáŒëÜÇãÈqR$Ùk×&€à�ç8Š ´$`KeÌ¡/N¥êñ/4—Y ¢�Í.ÓØ–™`8+G‚\ Pepü>ÅŠµëË8üDaFÌþwÎÁ Cpˆ¥ Í÷�í,:kÀlbYñUï ¼·Ž,7%¡ZyŽ1[?‘àJÕφòebC¯å¸—íôg|õséŠèLA+žI5šba¤ÒcJ¿Ær¤…å~ý›ép4–Ðgž0lÇRª;ÞFå‚sÑ�ÎîPgºÉÔ-Ê1-íûÖbØ»÷¹²5444444444@CCCCCà 5é_×g,É–2ëǃoüŠ/ÿÞ/þ_}À÷8›×A˜˜¹a?8ûExõõoÁžŽYþÉÚ¿"ÿ}$ù5:ø`­Èÿ4ñULÐR"¥ÊäIµ*뿜¸1²qˆÀÆ„÷Lñ_M%Ò)§ìHü(,s娻ü�?sïw¾ó}ç~À£�äÿ•2›«´ÏOí\¾žöú¤uÊìýr™’ _u,eü—d{�õŸ®y9¶ÏöŸ=½ÿ4ÁŸë¶vý©½æJ¡ÃÜqÕ"‰ú~ÞŸ9×ÈÅÛ…ê[W‰H>üôî½�Ÿyëë_¾ù+†äŒ’‚¡�l7?¹»0OôÏéEù ª²óyΞ?MŽSERŸxv·«•ªó™ýùUm®�àØx¿}üY~ßÏþú½ßÿ³¿~ÿÏá1U½¬ª›º Iý¼644¼x±ê:ôÖNÄ�"ÑL߯»cA/̹ ‰ T):%ˆG½¤jP1û›Ì„©»Pꛘ6Æ:I$2®1ëÆ”Öï{‘+jÚ�FËR138n;‘ÿ«UpÞŒû€äuWQ(°Z­±^¯&ÂËÚÊpP‘yOÐ|<Áa€Ç¶¨û^­Âã*¥8#Çheœ5#5H¢fˆ13ÊÃÒ˜/‰Nñ}øŽg¸N\'@YEîNtül±â‰@„Ò²0ñÎP˜ìñ3Q_…'yOZÄùsã)�Ã%¥· Ìsû¤,~•,Ž(w¸[¤ˆò§ÙÚ_)êe+$ÑŸæÈC“˜O‘5A<±PIâ›úœ÷0öTœ÷ä�FûøÜâ× i龿&hhhhhhhh˜  >ưd;_×gfˆ¾áËÿö}ÉWÿÃÏð^ž×E˜°ÙÚñÁ ¯¼ú­¸£Ož°ƒºHö+à«ÉòÑ1 e}U“=‰Ø’’ô/³þµšlB™ù_�ÿÕ„fØø4ë„…Þý‘3¿òÏì�o¿|Ã|�O¸HD—™ùz™=_fþ§ö],‘Z%É=G¼—ÇsÝûÈ÷9r<‰²Õì‚ÝÿœåIþ—åÊuR¶VÊöOÄ™©_[û—î 5X¶gÊä›s(Xú+¿Ÿ». ·Þ—ÌÜÓÀqxàá¾á‡?þŸn·Ûïzë®~ú¶Ÿõ»>éÚ}íÇm_ tØ}(wö€)�¯³~ÌDΤ§Ûú!…}þÍÞ#4ncl Óo'„ì^(æ¼g6<‘ÿɃ8-?q@X(¤›üto¹Ý¶•xôð^õÑKçÞûs¿ñªy×C¯ø•ívûlß÷—¡DÄ5UÊ ÛÔ'ÔÙ  /N”q,ÑuâB¤…‘I‘¹Ÿ-ã“k�ಥ»Fq¨ŠBiÞ-(eæ§õ»Î \Ž-Øp(/°Zaµ¶ò&®JÁyÀ†¸“†!Æ;…í?Åø&Ä[£`�'±T‡Õ*�ûD+‚‘1U0—„nµÂjµŽõîm!~à"Ž”Ð¶69ØpŒqÌÎÙù<�ùËXªÌ(Ïñ–Ht—IãE1~ðÔÆ?\ VýÙÙ!\gb‚¥ ¦pL � ‡†:Ư91ƒ$9`"4âƒ[@¸gÎ{rÎÓõk×ïR ›ð椣 P§f;sæóD3ìufê ºÇ5'»éçòGã¹eš^‹q¸8PMÿIñZˆ÷Âï°HÍg±@u:n‹PŠNˆu¨`ä÷Æhû?ã³â3¦‰kD¹0í‰wn6*¨·P_EU\ˆÏ¥Ò S4@CCCCCÃÇ(ríÐ"‹ªÎäNJÿøË¾ô¿ü�¯ýºÏðÝ>7o#¾z:‡‡.¼÷ßøÜwíG2ý%�ìâf¼á,üÇ£´|Í“d…~"Ñry�L�å£Hô3¶ÿÌØÉL•r{œ ¢n3ðæG~å®÷ƒï¼ç?¨êc€>à2m˜yË̲Dþç½<‚yŽü¯I²}™ÿ©Þl]: v,(] J[Û}÷JmÏ?ÍÜ'×Kâß9—Å5¹_ng.‹/m»Ìú¯K,‘þsíÔðQë[À€‹¯Wùý׆Á<òï8|ïÿþùyó>áÚ'x0à,Ø®AzÒРk­]¥Ê¼·ño"³=÷QµÖÃHÆßÊiÍ[ߎö Å>¿ ||•˜AÈxä™;ù‰ÿþ†ûÈÅWþ�ý3®1óVD¶zë�ëçJ"ª¡¡áÅ‹2³<ÅDÁªžvH(Ûþç˜ÕF™ $4Ù¦D 4¹H%ñ wŽB\˜ˆlt32D}Ž-Bö¿ÅÁÁÁ†CýùXˆc}{k-TÃ0€©�[ ý­êݪƒˆ`µZEòŸs¿Î¥t@²ñX‰@üjl‘·•±Uer¼EÖx¶ ˆq&†)â¿°�Ò`kšÙ²îËRKôi©í ò?oKÃàà%Š$¢í?q8÷à€`2™?Š;Óx€âÜÒ´c¼–±¼C8OοWDGQ¼ì1ô=œw´Ýlî+‡ý躟�ð)ŽóÓá3ZæSñC)gµBH¢²4ÖÆrDe\šöÆa_÷C;¾=ºcv†âÚÄF(N)×<ñ>ýmQéO:ó€VqÅI#ó¼<³hÂ…c[Œ…háýMÇruÃä#à§ž|üìƒ÷Š‹"á7JêKš ¡¡¡¡¡áŒ4±Z[{–Ä)(׫‰×¯ÿ[óñ¿õõÿèøëþOëéÞOžù“¸n_‹W\z+V¸²ý)÷ª�(Ò<õ5%ÿ§G^8JÆ7¾X·Ì–Iä?‡IE˜ÊöŸŠíHéPdýÇ�}äÙÕG¾õ'ø¶ß|bý+€> ੘õ¿)3Õk½n·[½N“Ö\ Å÷‘ÿµåiûÏ̹Îì¾cŸËª¯ï“rÝÒ†?‘ý‰øOÿ®…sÿ¥  >žruI`*Š˜s˜ÛnÃíé_ö8W(Ñ;¸-ß�ªžû¦¾ÿm_÷¿>òÅçÏâ0̰{(z@Gä6P2á€Adêsæ3`„JlVA4@€9ƒà8Bœž)SÒ|w3ýÇ\-{Ù³�22Š�|Iâ¢#ÚiÄTxf³t "?0B33øR¼r}Ž£cA8» ÊRJ}l úÛs1Û/nê—~óž÷~ßÏöw¯×‡ïé:ü&=Q÷Ÿu?W÷wímhx‰�¢ð^áEb?LÙ )”b/Ý�BöºÉuï£hU—»Kà\ˆM ± kb #¢�%oÌDw•ˆòõú‡‡a~ŒµB)¥]´í1pÞáøpÞÁ .ÖªÛóÞØÚщûÄ}åžÆ~RbFüt;Lk,¼5ðÞoUSÇ™b=?[‚JEƒ¿ÊŽUÿ$>¤Ò@ᜃ..C°�Ū3 ;Æ¶Þ ¼s�”ÍÙíEbI:xÏ $Hnx/„"Î pÎÑ0 $ý4\)¤!'^‹±8ÙÝ~ù·3MŒîI#�nÐð>ˆüó³ ‚ˆ³ "Q@À±¼eûÿ[{�vc—ä-�ö©…�:=W Î?ò;€êä÷—ÎìB+á¶ÎŠhäÙ)�ß~ÚŸf> =ïƒ.átR‚}¸zåò~Ü+(ßó®õÍ %š ¡¡¡¡¡áŒ2“ ÀbÆM×™Öi¢îÙ— 3ÿ£7ÿïù�þ5€7¦õ’å�Õð¾û¾^úVÜsãç�ûœãBÑf›(g±dPU£:½Ê("ØY>‘ÿ&fþ'a@:ª”½2±ü÷$†L”äÿ÷îó?õ¯ú¾·y¡G<à —˜Ù•핲è9O>OÛzޏª³³êzöKË—¤vý}m·_’ã%1^f©�Öö¿ÔÛ( öò^I„Iü—äÚÆ4ël÷Üêcª­{Ëö[Êø?i›�\¼ý}Lyߥ÷Õ=uÀ³ªúäÅ«ö¡Ÿz×ù_úãŸõìïcV(3ÌÜÆ3q]�ðÒC€w`ˆ'€l€:xDA`Qø7º °k0>ØB)þ¬aI„D0€?8íÛÇ Ñ-@+@7m¬í· }PÊâ—HN â6\Øfò&ÿXI‚& ý¤¡ðšI â”Ý�e48¯¨H_ ¾±•�¾•;†‘Ö‡R[ÉŽ?´a*•®ñ¢ÙîƒUU…#1Ç <cS¿4;Nc@ZOb¿o ã5§ìÔù|~D OeÉ‚Tþ „ùD çÞ …?÷àD×WT£Â_Ëò9)~É÷E›ƒs@+{xïŸÌGGñBx7Žoª€1±Ö¼@…ƒî! ›ã†]jÔ7S8/hl­ªŸ¥c£T�`<Õxì¹4€jqŠ26•c~ýÛD§ÎŽ¢Ó¯'qÁ]¤87ÁÕS!Í(Þg'…:‘ÿô× Ç´Ùlî ðà�ˆWUi�sCCCCCCCC�&hhhhhhx£$šKr´ÌâNˆ‰¬M�%y[7ÌŒoú»çW¿èÿøªÏð¾ ÀƒÀ(PœÅ£w¿—Ïü^¼âÒ· ëŸ a¢,ÏéÜWïµHë*g¼I³Êö?•H$™Y»:–‡í]ºaŸýžŸ½÷Ûþ½gAUô=KDWù_ÚÔ[kw2ÌËv¾™kRf¶O'r—3¿ÊíÔäxMÞ—e j¿<–¹uÓk))�§$ÿKËÿr’'¨ç­ki1;¿ÔÄýœ;A½Írù=™ê ·ˆtßÎ×îÕ¹v?RÕKDôÔ÷ÿì½?ù9Ÿqüƾv~PÓ€»5˜×€]�É€Rêzêh�-$ûó3?e4B9À(à<”Sö½Ì:®k †AXÄ ÎÜ�Û”`{u Ð!öS}|?ÒC1ºûð¹—- ˆ¨{XâÌû—ãSfÒ§ŸH�ÛB@%?mT¡^8dŒç2~H¹�³: ŸËáŸòùÖƒ½jýÛFó5PTâÀ2ÑŸJv¾¨¹p"hlæHø�Î ·ÿ�aÎ33©Y@û}ÐÐÐÐÐÐÐÐ0E444444¼€Q,u ÷d¹œ²µë ¤¹uþ/þÞWŠˆ|ûý_õ}¾À¸'‰H�£ƒÏÄûø4¼ìê¿Á½W~l¶1é~®àdD&þQ” H'ÿG£Íÿ$óŸjâÓI/Ѹûðý»9ûKÿüGïû–K×ùƒªò8]pLDcL¿”?gW3Èõh+{ü’d¯÷Q®[ 5R¶}I¸—„�u_ï\Æyï”瞎§$æKËÿ$˜;–ò~›³è¯Ï-\BÙ!íËã+··DþÏm»žÄo¸}˜kó À Ï žýåœÿ•?ð†á÷Ã…ø!šƒ @23‰ŒbW0vâ°‡0äÓ�Ø‚aAfOB·p½K—ü“{Z”¦Á'­˜­v'b†tŒRü•Û/·[¤0Ö…‚ ãEÄ™åù õ´Yï5ë׌‚ë©«¿AD�xJU¯ªj_�Cûž»Z(°T* ¡¡áÅ�ívê´;)û/ÕXŠ$õ–1µ6mcWжïÁÞß»1C�¢­?!YÌ~‡s¹«tä`»]ç3Á?&ÅAË�.K;ÂØ­WcE¬Ã3[¬¯]C·ê༠¸1`cÐu6î³C×­rYr�´õÞ£ï{ôý6Š$\>®Î¯Â:>’êÀl|F¨g®â ±Ú?" 6šÉû¡dAŒç?Œ™åå’TÁÁæÞ9c`L"¡Ã>æÊ\×cé8þÅ„íP ÂAD*+�®Ï0˜�Õ­úô”ƒz•Qž Àh©¯»r‚2§Ðî>!ÆÃoB(}¡3gšj 0óXž@)?#“І’�?À”ÊP6½JR?•ñáâJ‚2,¬¯;D¿NC ,¶pʤýÉݵ{_�rCKW=}æÝp¾ëVä½g/í÷ACCCCCCCÃMÐÐÐÐÐÐðGI×õÛÓdf"sËŒt`Ì"/Éÿ’DVU¼åoÿo×½÷ïo~Ý× €¿àͼ>ÛSc…g.|.žûãxàò·âΫ?‚TÙ!ˆœ—¤i9�2„�³þAÉgrRÊŒj]´² ÿ›ÁlþÃ/ßý¶úÅ»~TDôQϸ^פ¯3Ìӹ筟@jÕË¥ «’(/ ÿ}dv™uŸÖ/­ñÓµ^¯×èºn1ã¿<¦%ò¿n‡rùt¿”ib¹\¿¾çN:–ú\—\ êë2·Ý%@#ona¢Tl\ðäOüò]?ý¹Ÿqã÷aØÐ¾U¼ Ü  È)Ä Y ˜ CXÓö,ˆÆ8 èr�h"�Âj@6ôœì^³©@®;0sè“§{á3ÿ.–!Ú³mE‘>9³�šÑùmÉX:l+¸$«b¤I}‰›3Ñ>¸" >Úr§C�¤L}j„‡ž:ÿNU}FU/Åk¬sýaYÆ£&­æ^œèûλq<ޱ[")ׂçhýosö?s(�b؇ ð> ü¢ý¿É™áœ-Ð%g’‡ºö"c8gác&ñšs›í* çH% ã¶ÕªÃzµÂj½Æjµqµ—HRNâÌ«õ L„¾à½ËûÏñÕú¾‡Š€Í´Pž8ŒNU¶(û¥)~,å=ÄGfØè*P ’Wó8? (Žc„R¼6 g§Öbý tHÇ¡–sùzDÛ|šq©òI$ƤQÀ°¶ƒí,:ÇN; `2¤ªÔƒV™‘OQ„\xê¡<é4ÒÿSE‘9OÁÄ@f~=*~Ÿ${|¢: êˆ5‹+² ýæ‰G©ñg•Rr+PPJs‡æ{U= .Þxò³,'ì'Ñ‚.Ä-eé„âóäÒóê§«ëÌ–jw…*ü¡zÕÓ(ÊR4/Õ ÆRUÒZtÞÐÐÐÐÐÐÐÐÐ /d”ä}™}]gC§ ǒЫ…KYàéý×þ�¿~¤ªß à›ÿ·ò–ß àOðy z�ó2ømzrõnUy Àž!¢sVª'eüß Z÷À<Ù^’_µ~™‰–&¿ËòX­V±€Yý´ýZpP—‹(¯yš¼--ÿçÊEÔ® e逴Ï:Ë¿>®%Ëÿº½ö•(?kÏ/J—‰¥GÀ1‚àìcϬ>øøåƒGî={üÊ%Q†ž6Í+?ëüéá jb�úPJ@Mp!cBßc-àØX Z5 ñHÿ3‚e¿é‹2$>”€vÿê‚?€-à¨n�dûï�@èßC±d-|}(o@Q¼ �-ÔÝ€ôW¡r õÛ°/·…W¨‰‡ÄRªÁæŸ|$øcÍf¨B¥¬7]<‘ÄW+&p,É0Ší…õ1ZÇõ~ý#wÿ €Ë®…†hhxa �U›Í›ÍÛí›ÍGGGØn·8>>ÎïË¿4¾Õxó›ßÜõ6À;ç|°)�VîZÙ„sí^ãQâ”)ïའïÝHnG‚˜³€•³`�@¢F‘”s.öq&Ç%¥…¾ªbúH> ú¾Ÿ}ÌÄOåpÒz]Êò·9Ž1xáÎÔY›÷YÆ&ÞûÐ6¥8"n×šà‚°Z¯°^­fJG1+ȇó4œJÄ{ >6™P„ìy”BOX%ÿ;”i�½ãqyÆŒ¥c4–PUxç1ð(ç-ÙU DyÌQ…÷"ZÄš f3:CØ.ÿV‰ñ ý–Œ1„X¢lò›":†•Že ‘äÏvýD™û¦¹eõùÇí•¿]2Q¯q �ãÒi¬tÏ Âi�v*i.„cÌñl$Ú 4º$q‚qùP"ÓuÓ8?g³Ÿl7ƒšý_K&õж¿Ózƒõn'ÑÝ +,Ä„ã[ʶÿ“ŸŒÞŸ1Ìä‰(ü–hâÆ†††††††MÐÐÐÐÐÐðFIà×öïµÝ��žÖM5äkRz©ö<|Í_ó/Ñ/3óW¼éï~åÇ»aø=`óÙÖš×CÏßsåàKîZüù;î»öo^vüγŽâÆ‹Ú�Ù›ùO�,ãô¾Nç(í°cv«ÓQòïø� ?ö¯~ê�ç�ò4y9‘ÿs™å5©Y“ËûêU×ôœíI˜Ï JÇ€’ü/‰lc º®ÃÁÁÖë5Vqb¸Þçù½/·¬ï^’ÿÉˆ´ÞÒ½W;!, Êc*ÿj@ÝÞûÜnz<ßÝ»÷>š�Ñ–ˆ®ѳDôì{9üµû?õú+eÛŸrï3÷ Ó‰ëèÍyúï>ÇÉÿ�Éÿ�PÑ£`Ý@äð[Ào 8¤àC>a¬U­ÁEÔA‡kÙ@}ˆ‡zÈþ("…h,p³%HD÷6çÍ ÷ï}äÞYKG6ªª‰[z&—J{´gµát^à^à>âß™¸ÌY„R#pιa®n6›Ë›Íæ™ívûÄf³yôèèè7·ÛíÕ›%ÿn©K„lq>ÖšOñ`ʰ7°…�U%�ï^<Üà1 =7ÀKE¦8ÆÄ.’¹*!CZIŠXÄÃSªÙN0f*XLñŽˆÀ;)Èì ÊÐáø|áÆdm,å�ˆhbW¿ÔG–±ƒÕªÃj½ÆÁÁ!°Z­ ¤N†6£@"ÖK©apPѼ\Š#—â¨éߘõN…3M"þ‰ K÷P(b‘Põ>¹ øÂ ˆ1¤8çòwŠæòµè•(�#‡Ò vÛÙ8ÞƒºõšèÆ�ªNí÷‘�<ýŒHÙÿ™ìŸ ;¢›B¤ŸáÇ«Õ"E.˜Ô¶×T®§Œw'òÙõ:Y"Õ°.€¢£Oth #I, ! 5&º@ð¤í‘#%šl«&§[%ÿ+M—I¥Æ7•AÛôŒç£´™�Ý’•FÁÇ4¾[«j”C.]Ɇ†††††††—.š ¡¡¡¡¡á…¢>½¯3Üæ„õ¹ÖÄb=¡Þp{P;F,ÝOÕÓê\®¸ú_ßö¿ý�O¿ôGA§¨¢*z ^N[&n"Ksº7{?Ì¥ÊG"~gÿ3ëÇLÀŠ„§™ãMÝê ·*`˜ÓT°¯it~ýL¢p8§ãÞ<ƒ`û¿UU?çS—ߘë;Û3ÚPá€ß à³|€7xõiç N‘ùÿÔÑÑѯo·Û_Ûn·¿¼Ýn~»Ý¾¯‘ÿHîCúÐÅ $‘Ì3Ú“…>³É„·÷â#ß÷ðÃX Ç D02ï !‚ÕÝ~ND&1`Ά�O}—Žq‹�ÙûÞ…˜ˆˆ!Öæ„â~�1Ðøïù!Mgc—û“bs`µZãààgÎâð̬º.ZÞ‡ zçgÜ�´lÓÃ97„XÒˆ‰n µí~ª7Hêp|ËÊÐ cŒa8�ÇD®•ÆgJÞ—BÙ‚�1]pxð~txû ÖÄß,««ÎÆk¥´ê;>¾qýãæú‹�Â=I$�…â=¥0 •›ŒY ¥àÀÃY(0H‹ªY�Š Lv¦ãøŸÑÒö¨” œ¨iLžñb)fÑPRB|(y¤Yp½{îcÖ|éF0Št!v­ÿ©¸Ÿ°«¨«Ä: Z·¿NK Ü2ªv‘³><$â›CXCCCCCCCC…&hhhhhhx£ëºÉ¤Þ]“ÉeæM~×äÿÙZ "UTõz\Çzï½÷g/÷úäw½ýÂãß©wüØ+îq¯þƒŸ~ý÷þöWn>ã•/^Ýê­ak~.’ÿ’(¸q"K¼û#gÿë¿üéW~ëµ#óªòh¬S}UU‡:ã½>öònvR¨$½J²;a‰ü¦"‹”e?Gþc2ù¿^¯w®wy�j±F}¤óOØ'B(mÿkò?‰Ej@Ý&å±”ÇT‹æ®Ãœíÿ>²±D½ý†çŽ9W†âÕSë«êÑ»:ûá£MwÔ�Ù»sSx¸9m@ 1íß•*@¾øÙ’ú‘“@ŠsYI3×K}Á˜‘¯“¢¿c–d}¼y⽨»<îÿ6\#.êǶœ¤vÎu¸ug;“uŠÃ»r´z!ãÚ•}X*óQ‹ÎæÄ"õ=Õð’Åëü‰ø÷Y¸E?æSÚþß·ÝnïÛn· ÈüÂ{ÿc~$þ·Kòü Œe‚õ¿@Å… e„Ìõ�ýÏ`¦Lú&2P½Â¹a"Jï³Ý|“’“…íx"h¬>UÚÌgÑ!U¥®4ż»FÎ ØöA¼æ½ËeÊÒJ˜‰UÜàÀDÁÅ Zý×ñ�a,úc­×kœ9s&:ÂØ_%‘FBwô¼ " ïcIïá��øÑAʈp´…Oí’Î}*"-Çÿ˜Ç¾ÛP"ç)g�MíâÕ±®br Dü$^ e|8öø�‰× Õ¶ c‚ÀÏ�µÜ÷ÛW…c,=€h~ˆ%앎ïNJ§‰P1óÕ¤ùIB1W.@s80’ÿ¢ÁÒ_iÌ«§‘Wc`¶¾e  ¨‚•!^B| º³J9§#¤ 1¯ñ™ÕSåÌïê!¦…Nmè_‘ÿ£0â¦zžìÂB/±ý¶'ç,•¢jhhhhhhhx)£ ^Èu´MDpYƒ>aÉò?Õ~¦dvªÿ>7a¹DœÏ�ÉÎ{MDnˆÈÂ$ûõÇ.­.ÿ›Ÿ½÷¡®ë~èÜ¡½ð?|òµO~ÍÛ×~ÜÝ›WÝs~¸ïü¡»À†j1«¦#ñްøø‡åÞ·ýø»÷§DäáHþ?…�y¬¥«AM.—¯û0—¹žÚ¶$¥ç²öK’¼i$«ýôW_³äÐpxx˜‰ü/Ååu?É© <§Z¼�¶™Ž«<—Dþ—€$)Û¤<·R˜0wï¤m/Ùÿ§÷e[×í=w®É’ü¤ëÚp:ì»>§ÀA°yøéÃÇ>áž+¯=Y7 7áû:’é¢u•€DÄó)èŹÙmšÙO, ûk$OöOã¶+cÜ=çTí–æ¿>ñ¬xºb&Àö´/ž>GaÃå£õpMU·u7'ÌYzË{©eὤp/€ÿÀxÝsÝØ)Éÿ%Ûÿâq|€ëþ=€àÛeºýYýc�yï�ä¬ùŸäÿhg?–$òÎÁE‚¸$ßM!lef@DuaOU<Œ‘´'"`¦TQĦ’HýIgQ…vc¶§xïÐ÷}!ŽK;•mR÷‹AìyÅžÁêÞHý$u¾÷"1Ž‚@¢[@IVý2q¨@àE Nàœ‡÷ݵ‚ƒK,Ķ�û  Ê0ª€ cÎxžqðŠ×QeêUÇŸR‰hw�e<¼L¸oˆ‰˜ˆXÜðjD! ¢«DÎ0/ÇO]Þ?3ê¾�OC«RÊœ×ýcvIþ§ûo·±^*›�ñP½¥²sôÅï½TÀg"|‰ÐΙ' :–kÃu†Ei…QA»1ÌM`>F VJ· ™Œî^äìÑÑ�YG»†††††††††&hhhhhhxÁ£$EKÒ¾$þùŸìãëš÷sÙàK“%%�S³3é‚`Åï™yc­½j­=Óuݲ‡¿òá ï}×#fÍÌ+]gÜêµ÷_|àîsÇw]8ÜÞ½î†CˆÃjGæçÍå#{í‰K«§?øäÙ‡¯™g½¤ªÏªêEU½†bi_vùœÍ|Ù&iýòßs¤WMr'Ò¼´Ç/—MYÿ‰l/랦åkòµZM²mk’}iR«<Þ¹2å¶j‚tϤs)eÛÕmQ—#HmS;!,Ë¥0cŸ}nú~ibºáö nÓ}å2ªÏ[G?µ~ø“?μVãD.0êO·SÚùÏÝÓe) YûµKÓîDþ¾©ã½�âdì¡Ð§ûJ.ÙöS~®Ðî¾µ%‚hêu\]Q€Ë,F•hl&w¶¿ùä¹ÿð]?ýÉßàJ¼¦;}âœ#G}_Ô׺=£/ ¼ ÀWx€ÃÛ±ÁçHþ×›;à/Ç¿ÿàðŽvÙnÂ8®¹“ ¤¢s²p[Žq‰wC!–ãE~c ›È›z¨»U…RÑGÆrS±»éxïu'^s.t{-ø“+�¨LúÁ$¤d 1Ÿ1Ã$Þ Ÿ�JÓÒTkXÛÁÛ!�þ¡€aèáœ+ºj‚¨Â‹£eWU ã!SaÏ+êÞ·€Oúì˜Àœ¬�±ïŠÊã`" ;1„qD Ü8Ÿ¿‰ûB¿Ê\UƒðÃûìª@Dì¼7ªj¼È+ÃEMû G+žêÿÓîçÈ5䣯@J„�„CH«1æØZ뺮»±Z­ºƒƒÛu�5Æf6ªjD„7=Ñ»>t'{žâöHUYuœ‹Ûöz@{Ù doé³}6ó)ÛjÊÉÍò\æ2þÓòsÄí�È‹2ó¿lgc Öëõ„üO.¥x`ŸCCý¾-”Ûšs� "t]·“õŸÎoΚ¿3Ôm“Úb®Mv&’ QA}ŸÕDãÜùž$ìh¸yzð~|.@fÌ,�ù˜P!SÎ&b‚¢vo|"1Ì2âù�oiâ¸Øþĺ?ÚðНìüwmZ¾„¢sÀLÖ�>ÖýÛ¼¹‹6pÊd¡œÛ'…ÆÄzÎ ÷kßõcßõÓ¿ýÛŽ6ü°ª>‰¢À¾LÍ¥g»¾§Z&Þ‹ŸàŸ"ˆn n3ù_ãøÏ¾ý-oyË›ßüæ7_o—ð¹� R„l_ _6 b̺J%rÚy/>g=búDü[k;°a¨�’/cÿª€ˆ‚y,/S; ‘O±GŠkj{|ŸëÙ—ÂÍɨ¡ ïŽ]Ž�R_—â» Ä q]ri!"Øè¬dŒ ÛqNÃÐc»í1 }(…Áù ÄóL¶Iìⶇ ˆ8–c+/Îùà._½Ô‡÷KrYÚÕZ “b[3Š3ƒ/¸l,å0–ôŠb/±ÝÆò õxÀƲZ¦ ©œÂ`³˜‚ˆˆ¼wÆyg¼—�Ÿêî(×§' : �‡�¨ÖdšcÜ¡8Ñý¾–.øüP¹š.—]Æ5 ýÂ�äð`ÁY€¦o‚ƒ(º <†Òê¿<Ý‚ô§( Í­UŠ(4[èäœ�—-×)Ëè-pùôœ &©Èz»íóóÞB�††††††††)š ¡¡¡¡¡áŒ%â5Ù´§¬ÿ2ë¨&þ]’¹K�5ñ³”‘ŒºQ€ «Õj{pp°]­VùØÒäh9¡Ze£§BÝå_bɲ÷R6ò1œÚ`)3uéœæ²íKò¿dÙ‚¸Ÿ#ÿ�Q¬±Dþ—®e[×NK¤[�¥Ÿ'׫í$÷�®ë°Z­òùÔåjûÖ¹û°nó´�Ó�È'‘‹eÛ××!í«áöbI3·\±ìàÚ¯=töWPb�Oœ#ÀPñ† d(d̓[M`mñkà˜±GPbdLx_Öh6õ7{Öéaúø&Ã�"Ó>fÙ#~Žx?UÄ2Ñ4ó½xÕbl�7÷(¦+ïݘå¿Ó­$•�jå:0¾/%�K”÷¢x®`óO±Œ�¦sK5âQ¶Ößïj”Z`ê’ “Su@IJ£ˆ –Ø×ûΨ'ö†'”5šû­ÆÜⓆ†††††††MÐÐÐÐÐÐðÆ÷~ï÷Î~¾ùo€´ôT=âì �Þ«„×ô§ �¯�4ñzÚš×ÏxN‡™B¼‰õ]*B�Ñ.>dÌÑhûµ`lò¾ƒ Nì9»”ŽQÙa@AO3å¤Yn�ÎII¨`m‡ƒƒu,ÅŽÁ{7q`†>–6 Ÿ÷ýÛ¾‡w…PÓ$1Á!Ö+ bÆà\¶ý÷>º%¸Ð^A(`ÊÑ$@ÅÃ{ ļê(ˆm”Î!Ùÿ§Ë¢ªÁEÀû\�ÙÀ(ˆlg¡PqÁýAâ\1 k¾’h–cö>$æDV;<Ã=ÄbÃp3l·D>~V¬<ÞP�üÏc1v3ßk!@]p^oðÑ­eõžDÒkõ4Äg •ÐXžA•^¨ñ(æÅ@N Ùÿ…»ÏnxUŒ×ö?+ÐSœlYû@OÑ>ùy*þ�½{˜ªˆN³ô~ŸίV+²±L7�pCCCCCCCÃMÐÐÐÐÐÐð1 -§}$ÿ#©Ÿ.^]rF«–äWJ°¿]–Ô s¨]2J'‰ôY¹\í®AD["ºÀ|Ó}ÂÿçÏü�§ÿÖýwm>=šEöêÝ—ƒ6›­57 ]âæú­1³3N¤3bÀxÀ3ŒI,:…Éò¨‹Ê ƒÉ�@¹?– ‘«—¨­š�ü­”ƒ `°4'O”êèNšo™É¿Šìÿ·½ã5?¾ø)"½HD—\SÕþVï�¼—ÊÑ£ü¬áE…Oð•·5’ùè“ÿ€Ífó†7n|€¿ß.ësG]zœˆ«Âø2º'…e(Zݧ„yU öÿÌÑž~…u×Á° NI¼x ®Ç¦ß .T•1 "»3^%}ÀÏ:¥elgaâøæ}cú1+ˆ ù“•¿�™ð©TA¹¬írè\pRJdz×YXÈ|çBÖ¿\.'ÀÌèŒE×­pp°ÆúàÌŒ• ùƒsè‡Îõðâó9P<Îä|�®JÊæGa×lü9gKOb/p@Bø\Á…ˆÉW˜)�{ÑÕ :8çÃ6 �‘JKX»Š×( \r# ­x�Šž‚í�Â<óô¯ÀzßM§ÕHï:Ç¿"ÁiÌæí3þ»Ì8üúè°À�"ò(IùÒò2H‚²ÀFâÙËñ³ª§$~é{0}Ö’.0¸p($‹ ÊöQÔ�-†V„¹ncF=¥\~f|Â%Y0ÆPükÁGCCCCCCCC�&hhhhhhøXDIþ§lþ$HuÖ?;4ò¿¡¡á¤lï:ë»D"§pÀðžŸÛþýï<ÿ7|™ÿÔ¿ð‡žú+¯}ðÚ§d?X�V‘�9db>½Ré]/xìǦ�á­žýRçZäVipºG� ì©çŽINØåÌ¡Ñ$Ûï&àë >R¨êuU½à:€c}i9\;Ì•ê˜ËþOËÕ’†þ€îvmì·‚ü?>>Æõë×q||ŒívûgÑ·†ª‚$ÓÌP™îÇZòª’‡ŽÙä¹_!@|È7ÆæLsk»˜ÕO rP¯pÎcè‡`ÏŒŽ-lÌægKd búsñQ'kÚ—%TŒ�‰Yüªš xò!ƒüùè6 &]_c;t«6µ�*œ .Þ;ˆ‡U�Š2¬"fstôZä±'dÕ8I3Ô8Fíañ¢pïA)þ.B$ÿeènŒ@ÑŸˆ£ÐZ§YéyÝRhQ#E££djE‘E:aî±{бÒ@y ,ø‰‚¸‚ÔOùõxpU±‹éQ§2O³ës·Â�iï©þ³T‚‹±��õzM£#Gshhhhhhhh(Ñ ƒ8xã¶FhhhxN¨ê‰Ð�[' <ÑVUòij–ÿÑ¿{ù?»ÿ®áwü­Ïì/ž_mÊÚµ»dv$(ˆg¾KìŠ1-?}~;Hæ…ý•€Y«_‚NjÓÇ©ºû9c·Ð E›ÿr²;gÇM3÷gùÿ}½¢³§É¤[UÝ!‘ö4-t™ŸÈ»Z,pR™€†�I|ÜíÚÐG“üßn·¸rå ž}öYܸq#¯¯ª÷¶KzëÐBôžû8^èØé¨¦å$¡>=Q$»è˜ÁDðìÁÄðÈyc,:c±²:ÛÁ €Àfä´¼„¬zV¬ Ùóv…õj�Õj ÅN\$¹}°ÿ-fc©‚$p³‘€Ïe"±žìñóò†C©‚ìj¶íÄA¼Gß÷Øl¶Ø£¨Hp è\¤Ìÿ\Z‡©"HÃ2Î œOD{þ*ÆìtâXÎ@¡bamXΈ8”=˜ŒùH`‘Hþ;—¯)s ‘5•J ¤ð^b†ÿ�ÅÛ~‹¡ïá_À�Ë 01¬±XuAБÚ)‰È1¼s TÖ ÖØQÀˆÈkÂ8™¿)'às6C˜P¥Ïƒ¤dâX6 áz‚ zÜ*�uvJQ‚ ´h¤UÊRY¼ Õö÷Œõ© HwNo¬œT–(røuN&¡9*ÓdM sÇB;ÇÍF_ui†Ù섲 cxT‰@ˆÈCÌL̆r9‹††††††††MÐÐÐÐÐÐÐÐÐÐð’uŽqë½Ï¶Çuæw&) @\Nˆè*£ªg\xâ¢}è©kçž9ÿò3¯€÷ •È ¥ÉÙ91@„(ÀZ}­Õßs-¼ŸÄŒ;-Uöµñ¸$:®äãD°3®³ÕöÎð/Í-;¿Vh·BQ°³€:éO¦§6Öº.¯}ý~öèJF4¼èð«píÚ5<õÔS¸zõ*àÌ™3¸ÿþûqîÜ9X{òôÂG‹üwÎáèèO>ù${ì1\¹r›Í‡‡‡°Ö‚ˆþ{»¤·Ÿ³¡S§³ ºIÀ^!¤¡‹bÙòõè={82 Dtpè¢ À*æX6![Ã>il€˜ý¿Z­pxpëƒ,ö·Î98ïàœ‡Š‚xki$â:ØúÛ( ¨ß{ñ`ïà¼�ñÆ(1$º°pÌèW ÎaÉÿÍæýà "°�…w¶³“ñ4$´UüóÞ¡ï·}Ÿ¶µEß÷œ ¿ B ®„Ö;xoÃu�>öÍLHÿ©$Ë—Å b%;äœmî½`ˆBâ r8ÞcÛ÷pÞÁû 0Œ¼Ã&8ÄR D&Ž„NŽB!†ˆ�ª�¨¨ïåµ¥—ÿ8œQvŒ ‚øW(” kþ\‰G³B`äÒã5‡ÎÎYY€q›å¸ZÚþç2…"…‹PÁ|Sl¤Ì�ñ.(ŸMcjÍ¿§±µ“£€²0‘F/#�Dº•‚„¢ðÀœ:AOi0ch/•{%] of·žê² 1%ß�†††††††† MÐÐÐÐÐÐÐÐÐÐаCôÞB=÷c×\VÕˆi“¼6LN3Üæ ;ù\Áñߦâ€hÿÿQi€?Ø×x¡4 Òk±¾ì-èí³×½‰³¼)Åilý›íÿ‹ׯ_ÿ·/^üÊË—/¿òèè(“ôÎ9<üðÃxðÁñÀàÂ… èºùJ ò¿ï{ãòåËxöÙgñôÓOãÒ¥KYÈ´Ýnqtt"zK»ª·Ž@øNËÆLˈ s "€pÌÖÏÙáÌÁ�Ùç~?ÔœvúÉrßrÏ’‰îZEÉæÎb½^aÕ­rmúdoï¢U}¸8—.n–(N Š$x"Ô¹ë=�ÙÃDüñ~$€5“ÞÁê¿Ï÷öññÃ0@UÐÉ*w¿ÏųÓE‹8 nÈõ›ÍÇ› ¶› †~‹apÙ=@u…ýë}/FŠP¡yc™ *0ñ3Kÿ €w”K=8ï°ÝôpÛ!Øÿ{ÉÜ4b©¢$&`LÞw(0–"pD`QRQöÞ¨ZUy]9.¦2 ©É‰ÒÚ…qN. P•©úq¼Ò�:93ÿ.åV#� M®…Ä >»ò>ÚÔñ@Þ÷ ë^¬—\´v)H"—\2:Á‹“–œáîi!~ÊñÁT0uû×ÓB¥€ŠžWU@­QCCCCCCCÃ.š ¡¡¡¡¡¡¡¡¡á%ˆ¥LíL TYàåzõvâ÷BD=‚à“F†$¾-l—ÉÆè"Y`Z¼q?·q‚˜cf{Õ£«#N3݉DJÞús„á\¦ý)'äQ–1`L“èã1äšÉº»æñsADè¸.�gºm…„,NJûX€ìÉÔXU ™²÷eëߌ ¤,Ð^|8wîÜõ÷¿ÿýn³Ùüøf³9“¬õaÿØc�á®»îÂý÷ß�;ï¼÷Þ{/Ο?Ÿ²íŸ7ò_U1 Ž��qýúu\½z—/_Æ•+WpíÚ58ç&÷ì0 ðÏÞùÎwþ@»ª·78ˆj¨ /Èbæ|½©&úŠn‘ˆaˆal膼£`Ï­ú�Ñ‚¾{’[  çz÷l8 Bð±¶| §ƒE½D¢4ÖaW…óÖ[ã€X 2 ŠR&5Ó�EÞ�n9‰�N÷c¿Ý¢z ÀÁõy»ÆãafúÈt¾Î9Жá9÷f{¶ôCp4‘  (ú\cLøÜÃ0l ìÁÑ�‡®B‘0¾(PXÄ,~Ûº,”„Aä0 CÈþw~ši®ã¹x å@¬&ã„  CÁiA”T•‰É¨ªU‘×N†×Â1�©+i$„sµ B äë0!�_Y@{ˆðÑ>?ÿÙýZü[¢P«ý&üQÁ€)S®»Ùÿ:£ÏÓÂy@—Ž–(Ÿû„ï&亂ò÷snyƒEÉ…åÄüJhAËžJ(Ûb÷°æ6¾?~­ž‰bŸ†††††††††)š ¡¡¡¡¡¡¡¡¡á%ˆi¶f1){Jë÷¹M"Ìà:Ûƒ…4à ±}’ý~Ê¢+Òþ&D½™_'ä0ê àPëWLXžWãt¾(”º 6€0¼É!€  ¬ö÷ðp0º ¤ˆñâ:ª}ô!¬V+ÜsÏ=¸páΞ=‹3gÎàðð0g)'’óøøøÔäZÇ9‡¾Ö)Ûÿèè×®]Ã�7òvi[Ö„öÞ+}�1æ+ÚÕ|npÃ'¥­>aÕu`fX»›Ù^våD€£P@ ƒ=îæ‘�µï†`;/â�O€µ kÃðbØ÷•‡ó.À^à‡Þ‡Š'D€1L²Ï ðâá½Ã0ô l¬SÏ0†3=<‹„P¾ž‚í $B›L#„{/®ÁÁ¡ iºF1ÁB»zûÏ />Øì;ïE-â9ªm&7‚é8È|c ¬±ÅwÈn (2øÙ¡…áä`ò8”ö—Ê'ˆH(7ÀJhp]†L�ô·>:>$ÃycÃ`@U™ˆø™§ÿx€Î€4fµ�ÑMn(Œšªô&zG&8a²£Çn3Æ„ñÞb _�‚±×Òis;µƒòµHB…©å¾ÛÛ;ê.îyø§BˆWYìçã.cˆiòRØ�æN8žI!¥Eù~ƒ. -÷œåL‹c�sN“ÃGCCCCCCCCÈ&hhhhhhhhhhx bNPg|×KÙÿ…µ°ðDä 51]:ÔSºsÎôenÜž)`‘]ÀI“ÀÅ1±‰¼ Î!W>n<À€$Š`t.aìëˆüÛ8!|ŠkÄU#Ó¢ @,™Knnß•@y?Ô÷F¼x±Ùl~öêÕ«Ÿ±ÙlþIß÷Ÿß÷=¬µÙ^=‘ñO=õT^çàà]×ÁZ km|lG{ö$$†!dOGÂs†ÂÂ}$ÿ‡aÈ€Íf“—ŸË/î×0óÿ÷ñÿc»ŠÏN ý¯Q¨GÏ t´†5»b-âÔõ{L§¢$÷ÿÁ–ßùý`` Áû�Ñ?¸ Ãv6»Ë1+}€Á �ó£€ÄZÇ)ŒðÑqÀ{ïLp0 $0`“Hë(JPïÎ8¨Óì" d(œg¡ðP¬AÌïÁl'‚”dÛNÑ2?;ø`Ù/$¨×If¹D§/¯> |b©H âEà¼À{ Âft�E]¼HvZ ˜)Úó›ðÇÚÀ0¬5“’Á� _Ððœ‰Àûð¼29ôÄ€Þ[ Æä8�£ �->@Ç}r¥•h‡ô‡;šT­B ‚Fá@:„ïã5W©BŠh q—Ÿ3´ŸËÀŸÒé™J'Íù(Hÿñ\²b;~ÿ¨B­-t>ÎÉÙÿ²ûuÜ�ÎÄV:q8eø”·8îä(p:€Iý›Y˜ˆxçT´¹44444444”h€††††††††††— R=å}B€ZP~—P¬«Å6BAåÉd1UýÀ´Ön)¸IÒ\»¥Píçv :ÆäVÝ R�ÃÍîw&íN"1–j ïIø–bõ�&î!åëïNr˜»šýÿK‘p¢ïû?Û÷ý?vÎý]ùc8Úëg$bÿêÕ«™¸÷Þc»ÝæŒþ$ð±®z²7OYÆ1»Þû‰ÍsÝ/Õ÷^úÜ9÷_ÇÌÿZUûvoSO˜qq£m¿¢Ù†é̘…Ž‘d& $¿Š‡�—+\[QÕà‚BúPÅ /‚¡ßBŸÖ2ÝÎíý0`p® †Ã~ÙtD9ÓYóý‘ê·BÝ0ÃX6ï}¿E?0hH% !ÜN²À­Uµ`“lþ¹ Ô9·ŒåI-ûº_MN*;b¦ì˜�ÛTÞ)¼óðé9òÞÁ ||žˆB{­º«õ:/+.§?U5œSðN�D ‡Ä×”•¿0ý»˜ù¿$˜Û–;ñ€ÇW©ˆ~�#þoE °gŸ@53OE©…ñ£}ךöÔ ž¿D:ûZn»áÅ�ÍfA×uð_Däîûþ·©ên·ÛÏWÕOLYû‰ÐOÄ™íŸ>Oä~ú, æJ‘œDî¤ïE亪þ_DôÝÆ˜ŸPU1Æ4rè6ÂÎ ɦ'�8æhË_÷+�,U Ùù$®yÒ:Xýž€mÈã�qžJ@ PDÖØœÑ/J®$GŽæÆ�¶÷"‰÷™¤²�Åz½ÂÁá!„ÎË"3@|(Ë¢*³Â8 åÖ ³«ØFØ0¨ç@Ä«€(” (Åv�(2 Vö‘�f“Ö˨(„^<$>?DÊx�apœƒó¡�YCV¿í:¬ €3ã3Î!Xþ# ÃÌÖ{o™å`wâöù˜œ½Yrýc�Ô”ù/ÏÏõoh8-IŸHC"Âjµzh»Ý~%3¥sî Þû?¬ªÿ£÷þw{ï徭%Ù_ÿÝ,Iï_§ªïð3~Œ™À&}?Öpo¸]X€-ƒ-Ã.ÞŒ ¶ýÌÈv÷)[=]Ú”¡."ÕhY/£Ë ¼OöC »}°—¨†m[ÛÅÒAÜÑœK|NYól`Ìh½œ'BÙ‚t@Æ0Ö¸ãŽ;pîÜy03ŽŽŽ l·l¶[ôQ8�Ü‚æŠA²­ ›l�ŸÊ�¡Lê; e <¤û3}æÁ e˜iJy å1ÖžW Bç]‡��ÏVü?nÛƒ.:03¼ó`îáü¸\ /ÈîÁ²Ÿ¥TÖ¦ëmÀĤ}¥¿ð†b¦c„ìÿU®]gW ¦Ôì½7Þû×MFö¢n}"âsÖý8H†–]é ·„$C€”->fÖðT4zÁh“êX’ Z¢Ý?¨ªö£{BŸñø'ßUdyI¦�‹Òİ_çv$¢N¡êS«mç6 í—Ö™ t_øD4ÝÍ• Ø™ÑÂû* 0M"ÞëÕÐÐÐÐÐÐÐðÒC4444444444¼QÿsöÙå¿—Èÿé?‰Jé–Ë{O[Æn€›A¹|�ùRY€}ÛšÉàÍ6Áá{÷!ñý¾ã'ÌN€çÀui„¸�™‰ûKÜÄõ¿YŒÙª2©e=·\ËÉÆ;Yù§ëé;¿¦ª¿6 Ã×yïy†Oü¼Ïû¼÷ôÓOúã�?ŽÇO?ý4.]º4dxº®ÃÁÁÎ�;‡‹/~×ÑÑÑÏø5ïpc$¾v-Ô½uênΞ=/+ôý€¡òõé¬)JËpìªB©ÿ�\ÊÁ»ÝëÖMýˆÀ÷Î{¸´,‚}°ÅgtÖÂv6Ö¼WH¼—’õ{*À&ØÖ‡r�åL$©1+âŽ;.àÎ;×0 =®^¹ï'�W+ç\pk Á k- [ðՂw‡¥s+¯íë_ÿz<ñĆ!·çv»ÍþÁÎ=dw÷}/Ã0üÆç~îçþ€O/Kl6<ýôÓ¸|ù2®\¹‚+W®äm”¥R­÷õz�¯AÄßüæoþæ§Ëc[ºgÓõLÛhxî8{ölȺïûPk> ,l×ÅŒ{ƒÚŠï×`U/ùz2S¶Æ'b#’ô’KG~† "†z»93rŸ�Ê 6Q„À“þ«ìG‰‚mÿÁz…3gqöÜ9¬V+W®ÂvaȨ̂g‹!ÎÄÑ.?dÌcC?e¸êbÝ{cƱI^$òY÷�¹ñ9”qÌ¡h'?öÕ EpSð>”/áOkåäÌ|mlXá ƒ$õwÛ+88¤çjö¸ A�1!³ŸDÀ†óu`S¸"ØLg`ÙÀîÃ0±ŸuÞ¾tñ™7ŒZ‡Ý±f´æG‘¦>^O­ÄÉ?ÙˆJp£�àl Hw" ~$Ó©ôï§jkšHÿ$6ë’žèüп³ŸPO æT“ø©ò@ù©Ö¥¢ AëÌ}ª¶80u—ºÏÜà4ÙýUCî,O§ ívãP>Îcxt¦hhhhhhhhhÑ /aÌ·²n,�ØCY‡Ù‰á:ûlŽL×Åuvç‚oV(°„SZ…§u)΍©‡”…zâÜxé@Zžo¶z(V?áz•b�’üŸ[>݉¨["ÿÓû\Kº‘ÿ/:ò~çïü�xâ‰'ðÐCáñÇǵk×&÷Èf³É6ÿéÀ•úÞ2Æàî»ïÆÙ³gqï½÷b³Ù ï{ô}?yß÷}.0 C¹‰+K÷xéÀÌ8<<Ä™3gpÏ=÷´ÿ6áðìY0€ív›¯@!Û>f„ç,îâþ‰åâût­(f‹s$”Séfàâ=-PŒ* ÖývªgÝ =Œ¶ÿï¦Ç�t$D#Ao�A×…lukmÕÿ…2jKK}› ðTj ·æý&[õp|œ$ñ@�Û>`Å¡#ù ÍŽDŽ‚*¼îË~ .}‘Hu/ $ˆ&ä0…íÆ„ëÃÆÙþS%3ò…µÁy�ãú†Ç~;•`H�4T«(ú“¨!ZõOXìtJÑ7«NH ÄÁÿ>¹<Ì�´•!ÿ©lî5;ÐLV~–ÈèB^ý¼6¤"ò—�tGoHÉ¿ —.Å[:�yævpZþ¿<=Ù=@uúíÜYah¤CCCCCCCÃ2š ¡¡¡¡¡¡¡¡¡¡!ã9Z¨f€µÚ-ÙËÿ}öÿ‚éìr½ÜsMퟳÞ_XŽ ðõçez�žr»7;S>³:�b¹…­í»¾%>—‘zRˆZÐÈÿÉÿ»NIþ_ðÞó-’ÿ$"w.�ÿ—5`ù `“®ë÷|Ï÷\�™xk-Î�;wÒíwù6wSÇ_ø…_Øá~aë°‹pxp 9ú¡‡\®NdH&Î!>�½>Ô¬÷Ù¦?fþs ßM´ŠOÏcº�s0†á]øÌù´¯�å„òÉî~tÀ„ל!õ’àU|$ùy C,Oá|Ϊ÷2wÚ�µc6{ê;Dãsäu’EoŒ‰öú‰ƒ§p,ŠÒ…¥pAÁO:�p7Ö‚U‹ý›˜…îã1ïçèCée…wÎ “sbfØÎÆòa¸apÎìcCØG—¶V Db¿ÍÓåëqÄ{¢Ð…°0�s97ðà†OÍ£$Õ¶÷»Ãk=&J;‹Ò‰SY" hSÑ—û±ôBv “Æ×Q4PøT£}º&uL3Ý Ê7C®/ŒÕÎ}& »EªcËŽëN01A(©ü¹2©¦ÂÌÎo!ªÚjhÐfÿßÐÐÐÐÐÐÐ0ƒ&hhhhhhhhhhx ¢$4×CÞµ‚¯3¼Ëõç2„±È~ïq(2ùÆ q€(`æjÖ2NO⟄¤]8u "yó뢀a¹Öîs»xÅ!cæýÌqœTwéš×÷HyÝ—¶™î¥—0ùÏ"òÛDäSUõS¼÷¯SÕ�‘—‹È"r‡ªÚ�¥ÌÿxWãûë"�«ñïÀ âÿÆ�þè�¾ñþûïG×u°±þwy�n—[þ[‹ÎÚô°Çç½ QáHsÉ÷m¬¿žúfØ®ƒµ]q_LÝh‚“„ÉõÛ�wÀ¶Ìò×ɳ<é·rÖ·Lîõr¹Á9l·[l6°aáøø}¿ €Dêçšë4ºX39‘d3¯Põ±O‰}3X~(«ÉhÑ'‹~Ž™òšžY ã!3ÁÚ@t@ˆÙõ@äsJ"€ü|�ÏÿÐ b87ÄþB&ýdg;¬Ö«`Ï…I,¡šúD8Ýìž`!œD<ë,”öŸú×àðÀPUòÞq? ,ÞÊ´Är»äR÷Ù]gÎ h^¤–Û"/©ÅˆŸQ çs†>)H)¿æØBè<õ??€ëÉ!É©c—=ßåãÒI™-J)ФtB¼w¢aô.8iozâgtÑí wŠkÛ‹xm. óh€††††††††††—(Nš4=‰4NÛ(–¹6/;kô¯×E»[�à¶‘è·¯±[¶ °þŸ”8Í”÷Lš´ ~a5¦“7{ºë7!eOKΖË+p¼ÔÈÿ ªú{EäPÕß-"Ÿ)"ç_,¶ÿ 0îŠïïÚ·à‡?üa|øÃ†÷W¯^Å•+WpãÆ l6l·[c2¸^¯ÁÌ8sæL¶î?þ<Ο?_nòJë½k‘žÕѪÛfû~Î÷ãûU…x—³è‰�µ°]‡®[ëýnUô9£ÈH¢U}º%CÉ…À~;ŽQ&eçc“Òò_vúªôÞ;�ífƒëׯÇ2¸zý*n\¿Ž¾ï!Þëì¶C°·§Qäà\~¦B÷lñ9–€hD>‰'@bíñ:qL}g÷cƒ@D@ž¦Ïó$;|îœsȾO¨‚ kk-Ö‡Xw]tS@t@8ç!½D'†pMŒ1ÐèÀ0 1JAÄØ‡%8f›JE€½sæÙgžxPDî/ ß±Bjû}¶ñ‰ìÖìSËÑUG’žvÃp�%ÝÞŒ-¾Æõ5ŠvèíRȘÅ;;ÆA:3dëò ]쎲SÁ\œAQ9±›¡?-c 3›/Ë�€q¹­öÅúÜÅ™4=e·lã}§MÐÐÐÐÐÐÐа‹&hhhhhhhhhhhØ‹›ÈÒͰ–av¿-ˆrÑ“‰ë›?ÒÉËÍ!dó?¨ké>OsÕ;ånï~ö•¨K¼ˆÉVÕߥªÈ{ÿÿTÕÏ{JÛÿùj<ù䓸ð‡?Œ§žz —/_žÔ%ŸÛÏÒýÅ̸páî¿ÿ~¼êU¯Â_þËÙ|Çw|‡o½óo ²�¼÷p>³˜9º<¬ÃÐQ�sá™R…s€fÂÿÌ™3X­×Xuv"¢€íÖøÌ‘Üàòý""ðâÁjvïm/ð1 Ÿ)�ðé9OýÖ0ô¸~ãÅ�£0ÄØlŽpýúu¸aÁÄñÊúôû�B…Q°ïuŽ©ßQ‚2 ,6Ù!Ÿ��% ¼ÂyçB9Ín3é™ �}ÚhmŸz‚&aA<×P‚!lÏ \!Ø€õÚƒ‰q°ZãÌ™3°�…xAïzl7œ ë;çàU‰‡±<@Ø]q\œÆþ&úí„>˜jEÄ\»rå³ÊŒüDâO‡uZÌÏÿf¢†|îåÚ %€XÀGâÊ¥'�CÐ`haï_,«»|{²ÄÏïI÷¿Z†Óðiæ¬v•‰_§2›²�HQ“öZ–.ŠÅ$UÈ÷añ ‡ç$Ýw…þ€¦%f�šn9x™œÉ\;Eçÿ�ˆ(ÁZ‹¦hhhhhhhh˜¢ ^Â(Éæ] ü%Kø%‘2³“eÆYö<™r¢ÑuÿV‰ê2cž^÷ž=ž A®§Y_‹e¤8ÿE»\=õÞ•LÁ- hÖDÊ,]¿›)°÷Фú‹Œü_«êçˆÈŸTÕÿIU¬lÿù_àÑGÅ/ýÒ/áÊ•+·¥�òÞãâÅ‹¸xñ"Þóž÷¼þî»ï¾öE_ôEo{ÃÞð·ßô¦7=Þzò�ö¸1 ¼ó06d¹w«¬ƒ exÎÅL~d x¦àöpæÌ¬V«HÞ!g‰{ïÁ„œáάè%ÚÙÓ³þ�…µ6[á‡ç8Ýסd `2°«PfÀC ð>ôÅÎ9ݸ×÷°ë, nÀv»�¨ÀIJ …éìdœ$Þí+ŇLû\SÝÆÄL{„>ÇKh—ñŒb ñy;Ã0Àù!?ç¡¿*žeè¤ô@Ù2`ÃÙ5 µ­x�~0 ClGàœƒ ÄݪÃjµ‚w*ŠA00 6›-†aB †ÍHÔ§RÄ 8+Š~H‚”Á‹¬ªFDìàÜgæˆ!eð— €bÔ_'c¾&ÑC$ȉJ–°Qѱ~À„fÖ@õ§ÿÒ?í± Ò1 -Ê‘xB|k: éáÎQõõ=D¥�`fq-¢ÍÿõµÛŠ3˜ëã‹r Z)’ "í‘h7,Û`¶=öF-ËÄÿþÏõ.ZŽç MÐÐÐÐÐÐÐÐÐÐÐ0AYã=½ÖŸ¥åæêÁ—VÆ ®ãg¢!c@ÈÀŸ3Ã- Üþd¢—Nx=õ™‡daB}(ñ¼ta]Ý_÷wb¦«Km’>×�·uLÚÐ,”HÇ<ãâ0w�Ó$zi׌٦˜ ¤÷/òŸTõ÷©êŸWÕÿ·ˆÜUØþ7ò�=öÞþö·?¯Ù˜/^<¼xñâ_Z­Vá­o}ëøš7½éM¿Øzï�.F¾™Àl±êVX­AÈyU Ûö0Æ¢¬Ã̰‘X_­Ö`ßîÅqü â`›Bç�÷ð⳸ ³«ÕÖZ fá;²ïE µ5X¯VXÂ0ËG¿í1ôœ í}¿…í»°m%ˆ(Œ1X­ºÜ7XkÁ†&–ùÓ>U&ÏhÊ’.›˜Z¢ÉV?³inppCç=¼s�æ1%Þ:‚’D1F(w …?XcC¹còq§r.’øûÌ®ľsCÜ–ÂKÌú Û-6›-¶› œó ¥ؘà„À &Ž–ý#Y," 0¢P pøq̦9zÛ5ÒÛ§‰:Dto  K¥�ö´M)þ@)@€N2÷çNat/˜S$”¶QÐ2žFú˜.Ý~Àž¶ ²‡\#"íº•šÎd'‹†††††††††€&hhhhhhhhhhh€‰=wÂ\=øš0®¿›§{9fý—NKÓþ×åÝDÿSAO^G¢è žûxì2!çÖY4,XÊà—\38,¥ËàK¤©àäD9M’•idçxÌT½R6Såõ-k\Ï^¹�mòÿõ"òçUõ/ªê«j¼‘ÿûq||üQ³b>::bŸàó¢àMozÓ›žl½ùó‹I¹f6`6°¶Cg‰nØÀ{A¿^‡Ì{¶ nÁº>ØþS¬Oœˆo-»®À•}EgWè¬Âvppxk †Áas|”kÛ{ç!ª™°ïì‡ë5Œ±Üq¶ðÞA¼‡°Î¡[­²£@×­r&ˆTÃ#É(^fÕ*©”|~þEƒ5³Áj½†x…÷Ç›cop¼Ù`s|Œíf¯ ÇæŽÄ&Þ ŠŽ3ù5düC}Øgì×X¼ï¼ÝlŽ.¨êëOÎ À$‚¨ò'z·ä MLÉã%M¶�XF! RIƒ,JÙ²$¡_™¶Ÿ·K“ëb`AYlp+ýèØD´ø öÄ5÷¯uˆFZXìõa8md¶÷x´¾¸sq†17ذv«NW«Ö´)††††††-:jhhhhhhhhhhXÄR†w�D®æ¬Ý®)lÊV/Ùìr6�þ€e»{F ìýž3+ÝÒûâßY ±4ù\;ì› O5šK,‰ J_b­ñ¦‡Eûö˜ €g[b± …¢&þëõt93ïc�ü¿OUÿ¬ªþùÌ%¼‘ÿ'ã5¯y nܸ�w¿ûÝÙbüvƒ™ñº×½ŸöiŸV~ü'üŽ·¾õ­¿çMozÓ#­÷~þêÖ#d{‚µ¶ Ä¿í ¬é‚“ˆúaÀj}€nu ç]$Ò£5¼*�WŸ¶þ’“Œ* é~UD }ÆááYÜqÇyœ9{†GGGpƒƒÈ1†˜Ý.¢°ÖBVbÇLøDx‹W8ïàŽEÌÖ ºØg˜ (mÏs™ÍB±ñ¼4w‘9çà�ƒŸû&3ôØßMZzޱ³ßì ¡�}(0:AôeŒ ® «ºUx‚ !eK«„sèÑcÛ÷8>>Â�×Á†Ñ¯¶l6[ßÀñÑ6› 6ý"€µA`˜¡ÆîÚ ‡2AÜúÚ.ž—B!¢48Ç®,¹~utýêgØIß]svüúcÝú1“>µ9å,õj�Lõî),D\F»}�÷šÔåšþWÛú‹NGëÒB#]>q(E4iµT <¿¹$nt*6 i¬µì U3i-æÔØB1ªÐ]«z>:š†&cÍ‘µ�vÖjg;˜&hhhhhhhh˜ EG æÏý¯/™s-ëŠR²­ì½ÅK¶mU3£ê§öÇ8:º�ãGغ- „U·Âz}‡‡°v 6&Ö kÒNlC YIÌ cÀlaL<¦hµ™“™É€ÈÄIð”m¶'Þù}¿AßoC6˜x@Âmg‚Ýîª[…‰21#�ÄÁÆ5ú‰Æì³ÞPÌú¥œ%%êác&™x ¯h¥5tWqx櫃„¡ï±Ýn1l‡hÿ#³–SmÛñ:Pœ¼µ1£­ëV0�ç±íû0I½=Æf³…¶9»Î˜`)l�[mqCö"�õM‹kÎ6’ˆÑ-ÞÇ{$n› Òu]°-Ž3©'ØE>Ý å 'š5’)C.Yʦí®V+t�ÀÑØc<\¬ÑËl`¬…1kîúxŒÌ ÛYüøÛ?V]sHèû7Ž{xLå�±èº5V«ÖÖ†¡P nYÛ-†¡‡—*�xë¬pï]gòµ 6Åuò|œð&4ÚË“É÷R~¥‚ø/êÎÞÆ§?¾2�ÝIp�ÿ“=vý:#$PÏGë}—ïõ¦�Qˆ²%t.Î6Ï˶ÿ«3wæû9}¾ñŠã#/‰`R( ;sˆ53 Œ „�s׎¶Øö×cÝhÓØ'ý‹oûבÀÛb&Xk#´!Î;¸~€ŠF߆Ìáh'íE0 C ÎRßSð¢¡_HÇ¡Öux–‰*BÑÞ›¼ó$⡪DDDÌ|ÏËî1_ÿµÿàÞuáÂZkÿ¨ª®k‚üVÉ/ñ ·—ØOŸÃú­ãcô}�~Ðo{x·Àyú¸H †ºêRd¨ŽwdP"à2‘‰DX›óE‡ ÉÿË5¤÷?Sã÷Ÿò)Ÿ‚ßö Ÿ€‡~ó7ñ‘�|/^Œ÷Ô¸ìØÎãã>­7=%ЈwÝu>þU¯Âk_óœ;w>o§ÀÇ_½zõ;ÿç?ù§ÿODžˆ4�• )=7Lœ-ÌËg%�Ï4¶£ªbÂØµÝl0 �Ô¶Æ`½Zcµ.,éÓùiès8öå¶³èl ÉUÎû`õî ÃÎõy\I6ù‡gp°>@gC;›øì&òqBï^¯Îî9t«ÖÀ`½*n\¹tW.]ßYþÂù»qáüÝó=¨^Bûtö�=œßé¹ñíGy]×áðÌœ?LQ…¹~* 78 ý�ŸÇÕªËÎDñïRÌ¢!^Q@Xó}Êjا'ËÅg/[Ï«@ÄAÄ‚ ëñ²Žª†}qÊæ÷°ÆÆþŽa¬�÷ä]U„Ñm€s»H(]�Üd!f/Áž?’ÿ^<(Æ Ä!–ZÅøaµZCUᜃµ¡4€£P6@|èoûíGGG0ÆäÛíÇÇ)®ÜFÁ„‚ÈB|(` C„ÀÊAÁÈÏLˆWm?¨*Ù¡7=“ÅV¼û¬º'I·pà¬Ë|öé;‰d½f!@h<*lés�?Ã Ž �hæA™­jŸzäk1v�:y«ˆñuëéoOE¦=ìø“;Á‚BÑ2Å.Ç£§™>¢:˜‘ü¯úvÕêúèoéo¹Ît7Œ1ÊÌZÆ7 ñw[k‚†††††††7è––žfòTV˜‘ð–Hr{õ/ %xk±2G²!{ :µÛÑñ³h¹IZŸ‰îgUG{ÐL˜Çʼnæk}—ÉÔLmZ)N‚ÆIO¦hÛk¸ q !ðˆ�*¥\gTU!é°tÌ–|^2ffåz§‰€³Â¨¨™ªŠIÛpž ,ë’N³º2™# 0U$.ÆåÉa�j ÈUJÛ^ËJ§YÜ ª“IÓò¾8ÝME“zµ˜dóÅï&ç–§ö#�;%¢EÆÍi¾?çòÄfˆóŠ[¿¹§Cs{¨H¬a« ’œ­¯Åž”5Äû9V±Ù¾…ç•"‰}»Eóç·“‘¯šŽ·nv{³ýÐm˜À.ìŽçxÛ\_˜êc ç‹â–­™<}Tˆ”dæ™Ë$DM „§Œ4ÔbVøå¶Ð"oR§wãȰÔ}€A0 ²¬†ìRÀþ±?öGîûSŸ÷ÿús/»çÞ?g-üRv¼ ›øH$†Jßa†üOu¸ENâ|&xè!¢8>>ÂÕk×pñâE\¹rW¯^ŵk×B}íí&yÞÁE¡�x—‰dBÿ Äö“ 6“ p*I/…TÁŽ;¸+Œ® ƈ1£}w†$Rœó¾˜©p]0Ùæ�Í($ID,°1øÄOz^÷º×C¡¸té®^¹†+W¯âÚõk8ºqÇÇÇÙ!�Èn6¡^ûj½ÂÁÁgΜŹógq×…»€(z8ÞlÑ;…¬ò¸�¾ïq¼Ý|Î=wÝñšg/]}(öýž©º9ËÄ`U%S‘è©o-z�”õ Óô꣈ETò�c™®H¼–bB½{Žâ;¥½‘&F“¦ã�fr¸30A3÷â#Åœ‹q1,G»~ca£=¿HÈì÷>ÄÛí€Íf k:t«Qlúu”ÌLC¨²–=ÇìþHªŽâ¾,‹Ã4)¹¢QìéeQæç�ƒQ¬ÏÙüel“HfÕ(®Ÿû£  ýQ(ž…ðÌ5ñ¹ "k-lg!"0ÆÀ6!T '®Qh4 úèÞ¡ªè‡Îõ¡M%ÄÀ¡ï£¸oöDC;¬ 0ÊÑi ¸˜.-U•e1^Äz‘ϤsÈÐׂµ!/dþœýM¤ÅÑM“hngyб/8 A,Yœ©9? ˆ$þ$[¿ kמ¢Œ@híêS�¿“q·v(ÉzRœ¡Ö›ªbÕ¢ &¢D��?ˆ&&ÿ¹;¢b¸U]¼'‡9zª¨IÇÿÍ.±Z¯®kTUÕGa]CCCCCCCCÈ&hhhhhhhx‘ã”öÝ',=®³öcF·î­]©ÕVÇÌL2ÀGÛÒ4ÑO{$Ì÷—´9¦=•­(#MTN¦.1¦@éÞSNDýÜ��î¶ÀH׎B†2ërb==™l¤‘˜ždi¦-Êd'³™œ Dzx‘fÐÅEi$‡™»Ú6'ó_4�l¥¥>…!xBþ¤ s/.dK¨á}ùòe\¼tÏ^¼„§Ÿ~ Ï<ó,.]¾‚ׯåÌÿ’0ÒŠ¤I.1c›%‡ „caé_·Ôî)ñ:šHfA@ü)>ö+œjCÓØßR‘3¹ˆXï{LQ¶P7Ñ™$¼ïpöìyb¸Ðc¸˜éÄñ‹¤æ0 ¸rõ*.^º„ÉÃÑèáÑ÷¡æyp"18pxxæ†!RÑÁûèÔÐÐÐÐÐÐÐÐ�Ð >Ö2Ån� Ì_ó|*T)O°çLJ50ãD3‡ *k»öI1_‹e)ÞIì!ª9Ë{—tH"§Ø'�ìXb§û0»–$b4hE_˜J‚d§‰DŽèÎÞI�*Öª8 ÂYçïºóÂËþÒ_øóÿÓ§Ú§þÉ»ï¾ëÕùüS­øøLÈŽ eñ§¬]�¤²u¿¯!óß‹À �”T/¸rå.]¹„G{�>ò(ž|òI\º|7®_öï¡^!�Bc2Ú¹«mÀèÝ6BÑIªJ¨ñ-Ñ�Fut›1D e¼ȹÜÏdG˜t¢QèP˜uŒÀÅÝ#Rd®§¾$”d°QÀ1CÛ{‡m?À £-;åšèiÖx =Î5Ö™c š‚T½qãz(u³ZÿÄÝ/ûÿ³÷g?·mÙ}öcε÷wι÷V_Åb‘ŦXU®b±HQ¤$Rf#–IŒiÊVcHQ:ø%Ò¼é9ÈKþ‹Hƒ°Ç ,ÈM'F’Ì"‹uû¾9í×ìµæ#cŒ9çÚ{çÜjhÞ"× ¿:ç~gïµW3»=ÝçÞ¦Ó®Þ¥Sâœç5ÅõqÜ8iw¬�ZÔ qñȉ ɉ˜¥{›»£ª—ÀÝc)¯ Ëò!f ü}ðìs¿ÏƒÃ_í õŸ£:,æçpsƒå°€÷Éš�«ê¥f—R[„”içñvσÈßË©=ë× ÈU÷ÁD«µ@$A%›awr 1ƒjïÔÆTN ª«uhd˜§”°ÛM×”-2¥Ö‚y9àà.!ó<ƒp@)¥Ï×Þg…=®àh �Àc}2·×©ª9´{×ßÇ™Á ·{•7¾šªøXSPÜe‰}­Ą̂oÀLÈš-€„&½÷öÛ¿ `××\k€B�ðÌ�¶Þ;Ç9­öƒpdÁÏ � Уy 'sÐxð‘ü;‚åa ÃìÃOòkåÿûÄwÛ‚@DqJFÆÉ"÷§1ˆªÔ]Vú̑ڸ´"(öËýøÇ?ñJ­ZsÍÙj«­¶Új«­¶Úª×FØj«­¶Új«­þŒÖ- °P»~Õ‘ž]ÀlvùÐjWcaòw§œQ‹Ù3'6B@Î;Ï–7�cŒ´ÍA¬7»¢Ì ÆŠ *"y,�h¨)a(�„ ”ZA3!MdB"jj8uÍZŠeæ–ì0‰ LɶbpSÀi(B«—C}æä‡Z ô -¿ZUl£œÑˆã³Îú4œ94�“ÄßúÑO{™¶4 QïéýÌ~Ë™ì¿#à–«©‰që&¾>“W1<§•1�{›v)æp‹zW#¦Ú¶b*(÷S ° höï³Ìâ?CqÅ=(î}ó¿ñ³¿ÿ¯ýîßûÊ—¿ü7÷ûÝó£J4ügUÿ#ø_¤Y]KU)îâ. X €ZBù¿àúæ€÷ßo¾ñ&^yí5¼þúxë­·pyùóaöq[Wð˨ð4ÀÝþ‹À…€×‡ƒˆ¦O+Ã☾¦ÓØ×¹Í5F°�‚&ŠÕõ\†•ÛKײª(ª jU¨Ô5PY+æRQÊâã’ÍFn¨=€a¸þ› Cƒ!QJ�óþâÿð±�úAD×þS: ?ŒÇƒ› µ6%£Ÿ¨hÕçÝ5Ц̧” " N˜¦ 9›òYAP dždcùnÂ.›ú:ÄQâ‹ãs¨�¹/˜r;#SB"ÃÆ_�„Ó„ÇãF—:?¢ ™ãÏ†Ž†ÍQ ¾î臷rÝÊo™ëçÃŒùpƒ««Ü;l=Q«EäŒÝ.cY&ÔRÝ�£b^fàš E‘&'Ö‘õÜ'�¶è„Dx[ëàuÇ EFÎÌ™'Ÿ'S‹ÑˆË‰ 6B‘ÍïcU#±Lö» \\ì±ÛïAL¨¥âúp�›éª�£¨ •¥Å6�»WgŸ“ÏÝ%Õ6î圭mrnÿ϶ä 9Ô’QsEAÇëE�Les‹¬O3ò”�0Ë(Ki. ªÊªšon®ýxÙ¾VêS`áû·ÿѧ€p�.FÔ?+tùÔ3¶zRòȨï§q³×ÎÛ�r´ÅቓښUV>ŒÁ~õqAµ&˶vDãék3ü‰;2­x!G÷“?õ³Oªª–¥`YÌQf«­¶Új«­¶Új«^`«­¶Új«­¶j%"ç³Îo­ïÇÐñ‡]§Ÿ«Oµç¦¶IH³2UPĽöJ+·M².ö‰�bFÎ;쥸í¤!‘�LÌ+À…V÷Ú@Z©°pâ¦úî@t8^ªjS¨›š>>îS=o¸ÖÅ7— t#bP¸„ ŠÛ ­)WP2Àh) ê²`™,ó˼@T,;ÚÕbpÈ‘‘N Nˆ4oUER2úædC*ʲ4€+”ìÌÊ'¤?L‰—6#ˆ"åÈ.¿·,JÁÆCT�²Ó0R�¤l>³¹ª"çdmEÔÔç‰Áœ�±2¤ÄÈÓ„ýn‡)ï� à1 #âH FžIH ±Ö’S6ÂZ2"±ÙÛ‹T,³©Áó ñlùœss†ù0Q9O_ÇÍyº†#ã©ü°îÜ¥ÜÜ̸¾¾Âå“'Œ¤CÄØ_\`)‹+õ <³9Iˆ¢”ÂŽwþ m~ —#7†3�‘4ÃÙB´ż’2˜Œ(”³ž¶¥ˆ�>fV­˜TŒÆáí³�ïî0±Ûíq÷î]ܹ{w.ÀDX–œ�H)FÒÌs¸P[VáÕZE›cIA©Ù× þÙ)!çÔ^;M¹¹uìw;ì÷¶ÆH¬ŠVÔÚ•Ö2L;â¬" øØ®N˜ bEÎA .uI¥–\Êòkçˆ £ýíÍ«Gk�€ûçWç�‘VtäÜ4¸„Ð-óu�?G’B¬Û¡äêºålÝ÷©K€öÝyœ@k²ÀŠLvk´ˆž~º;Ôè¸Õ]ÑteаºzÖ÷Dý¡­²†ºœ¦\—ÅÈÊó<£”Í`«­¶Új«­¶Új¬�°ÕV[mµÕV[µR•?#×ÑþœÙtS¥´2»¨Q2¡ê.@ .‘w‹T2kPN &Wæúf\X¼¶¡l²ù®¤Œj‚„ .µ »kPòLßÚÚ'ˆcc߯'²aË¢F•¨*�\=/jv¸�rA'‚jÁ¼,¸¾ºÄÍÕ5×׸¹±œÙšw»v;ìvØí;ÝdÏÛ Å\ØiS³®î9º"¥L¤YCç‰�(H’8;â(ñ¼BMMëxŒ‚:¨ŒC‡Ú”ù®îËÓ„i·Ã4íZ^t4”·Íî55„ £Y: C,)­ò,�@`hJìÁ š]=V;µ]ƒo°2àJXƔͩ€Ž>Û ÄÙ�5³Ú-%Ú£´WÉÂV%Hµ—HÕ1Å!œØ=½Áˆ%¢Ý ¹�wûÉÝ*XÊ yq2‹€£zàØªVoùݹ÷~?öÿ‚³�òg�L·œï³êÀ—cõŸZbu V�t5pÀ­r|ßÃfŠâ÷LEP—ê`¹êå®’>32ÛØG‘Ð#›éã[˜2À <™Úµ¹Èó*Ë Dô½ðÜsÏêý[ÿ[¿ú—~ùo}æSŸúâ)r þ‡�÷þ‡…u•o °¿:ÀÁC©®¶n™ØFœzÿ½xóÍ7ñÒË/ã;üÇxåÕ—ñøÑ#”RÌÅ#e'Π“�ŒðÿœÒÿÄÿ•¨>Qû*Ĭ™X¦)×iÚ—ýn'9gIi"攈9+4«h²ˆDÊbãm¨ AÔÆXv€îUåy@/ˆéÀ=ÿ¹€êóªzOUïˆÈ½RëÝ«ÊU½tRàŽªÞ!`2†î‰hŠ'ºvV×Ú ˜¹ß—•¦ÖáeNšïv¸{q�‹;xøðÑ?©ÿ"çé�öwþ9q~ЀKO@tIDs«ØyYî~¢=½»»êP'¡¬Ü)|X$#„½;ˆ[¡çZ!ÅçÝÔsÔÕcÈ] vS2€u²ñ\ªØ�Ð,ü4RBöhšU{ÎÙ­å©î6q¸ÆÕ“KÜn,ZÇÕã-fºôY£UØ¢w·¤�J,Tœ[› TQ–WW—Ø=ÙP$W«ï÷;ˆÜs”'{æC­ã(ìnÓn”w˜¦Ü"5¤šR³î¯Õ�:yHH}ÍÐã8»›@î< ©‘¦jE-Õ]édœ6òŸ­Uöûöû]#†.e¶˜‰¶éë!v2eb[Û¦”a4ÎÛˆÒ`A Œ�A‹±Ê?°Ûc¿ß�™±#),µØ¸²�‘Q�ˆÖ¸+1º�ûþ™¥P1›�RJzÿÝ÷>%U¾ @ð!óýØùýés­©ÚW š±ÓhÛ¤O›,ÇÙc„È´rÚ;üd‰ÎÙk …A»©J#ñéjùDª‘ Á�”ž²<¡§^+¹aP_K÷s¢� FD«È�õ·«c@ßóX¢ç–ZCZ3?™çË2ã0°ÌssçØj«­¶Új«­¶ÚÊ×÷Û-Øj«­¶Új«­¢šúøÏL”ì©uÇ^bÃŒ[P(³©½N±«ÓüÌØd·J·CJ­@5ellä¦lV³D…LùßÁÙÈsõ¿Ûë‹�§’mZsJ®ðr»b676uk­ÐjyÀÔ,÷íB…©ÕÎQTÀBÈêyôR1˜onp¸¾ÂõÕ5‡Rpex�YÑnSÌ슗¸F&sWýûÝóÍo³ê\ "HÄæçM I jÁòö¶�ÍvH=S|Ø� …�o®·'/´6Uf+›Úog Ó´;!-„Ã@�axÌd&p\…Šg4�FÞ® &H³äV#¸u{·éî6®ê.�„C©µ�Þ µ)ü£˜RöízÙÛ^¨nÕÁ'´Ë„ @ÈÉqÍáJ‘PRqKeqÀLü^D†µ‘ÂÍÀ”–í‰óówåÎ>  óôß—ÖTôÏÒàöUäK•v¯uEâ$YðÚÆ-ugSÂKË�70wpÝÕb´½€ýÛóàɇka�Šõ;<¯ž�˜HUwPº“½@‚O(§O|åË?÷³¿ÿ{¿ûoüÂÏí·öû;ÏsíñÏ�ÿr;øï†òßÈ ÒÀÿZR‹;bž\]ã½wßÃ[o¾�_z üâKxï�wððá}ݥ üók(àß&Nÿ÷”vÿ4qþ6€' \¸!Ò…Õ2—ÉÓEH™Y ¬L$D¤þC`�BYEITXTMn¼bõÀÇëȨÙÌÇüÀý‘¥”›/yVÑ]­eWjÉ˲dËX®$*ÚÉR3kf–”²¦œAÀ^ªÚ›*Ç{Õ}£°«Aše³ë&´I Ä+bÙSRÅD¤;˜RrRÕ¤ ê ‡‚�PκÂɬ¢Å�úä–Ø¶A*"Ðb€})‹Ù„ºm¯ÙÏf·DfS™ !ð^f³�çÄ-CÚTÚ¥)ËÀÂWÏæ²l´À”ƒL ¥Œ¬æPËq ¥6 K Dp‹Z© )5ù5ÔŠ”ªø®©¦Â „æV×]P� Ç¹Ö¾áštjª5ÈÄ�|q ªÄëBiwBˆ ~bÆ”vy×b ȱ¨�±%õó2%~·öW…e)ÌÚ•håB µ6%—�“rn£j¸¶G8˜Ø@… KÐhK^�Ò¯1À&‚š‡°)® "lçN a]í‘�ú6s#JØõsˆ˜³gô"öáF*!W4Ú?¸/`÷|­òY‚|öæ ï²2¿Ÿ¢Í]À$‘F.iÙì÷J«}M¡Š¶{,jÿNñï2txÁZ&¤éï_�m�ÆïÅ")âïæùlcÇèÌ@³˜# š'îø3|–JûÌÖb ¡á‰Ž %¬ïß™ÁN�.· rgH ò ”§OCèÒà~A=C\Y›ãDDEPÛãï9÷ÞøHoëP¤dä³?·g*RŠ89iؘg‡Ki¯‰ØH5¤î°¢  cb"¢Aïã…¿þ·þÚ_ù«¿ö—þÍ/|áÇÿ²Ùü›“ ßþ×§Øþ�?Åÿ·VécJ-(µàíwÞÃ믿ŽW^~¯¾úÞxëMP³Û…£9»ˆ(Eœ 3‘+~S#98(ªJvOí|µ‹Ê×N IÓÆ¶j3¥[C ÀÈ™qç|9˜2'LÓ„išœì– €Ç"µ89mþìg?óèçþëͦù°,8ÜÜàææóaÆÕõ5nnnpusƒùfÆ<ϨªHU $ Œ«'—Wq1ÞF2s Ÿ»ãœo7A½]º^9@-'Äý; õˬDT‰¸ØU(ÅšQ³œhÂÚ©3îP]Ÿ÷¥¯‚¼7�Ö‰€"ž%Æp²¨"õ÷-eÁ<p8pss€TkµŠâLÆûq{�yâú[ò�€,`êvA)óလmkk·›€Í̘¦ŒÝ®`·Ûašn°,¦nsƒ†ˆ”pZR_H-´×bÑD«ø"Z©ßuýƒq.÷ç] Êb—[«¯‰2 81æ› W©¿æææO®žàòò ž6=)”óŒ®þ÷ó Ð.6cU‚ÚƒqÇxUTÿ[ ”¼WØydû|=²Ù‰jÊ^ˆ@¥Ú5ˆ@º’oø º%:T %"DŒðÐÔwj÷QVÏÀ^Ë*@Ma±~Næß ©Óg(M_L‰'!|¢V¹óìI:tÑú+Ô]FJ)î>Ñ æ0Wy®â=fAo–ú †’e"[¢ÇÉHk¿`'ªtbݹ{÷â÷ïoÿö7áë¿÷‰�üg£ÿì„ïüw°³Öºâ…T …6puy…wß}/½ü2þðÛßÁ|ûpÿþ7 àJ)ÖIÂR Dð0OÓN»‹IÄ�ˆðÀ Ì”¼c˜ïñ ÍÌ\ˆí‹hDºÐâSÄŠh- !¨ª:@¨íÚ1o�+,‰Â·�ï�Ùä‘ ˜\IŸ¡`(HUÉPo£Ê19OØM;™v;M9‘3Ø’HÚÕ{Då…G�/Wh#ǹ°Å°ô1ŠÍù!ÙOªŒÊáŒSQ¥@ô D{f~!¥¼ä”U•HD@RUVU7�ïÙö™Nô#nmZa½Ai.6`&ƬŠk7P\)ôZE®«êÍR«Åa469€\'”ŠÅŸK´Óž¥J‹—-M�L´z†6÷Z´ÃØÇj­HIQ�ܨÊG.2ècÍ�NÏ! ô.)éûX~ž±3?†{Sš@Nð¬R üƒ‘Žò4!gS¿1e·›0M;̳9MTÏâ}Ö,n¡[ŸÛ³)¾®‘Fˆã§œ;ÈŽ®p‰} ôuŸ*¶F:ˆúDš"_U1ÏÉœGªà°ÌÈ9CjÅÍá—×—xòø1®®.q8°,ýÙC-¦ÇÖ•æ„�röµ(­Á}ÿ�É äî77�TÁÉâD‡s_çèL´r§ ÷� _æ)cÊæ&`¤0€$"»Zë_]�N+�Ó|úq9ÑÛÆzOgר×u_höûèºòvêkÑæÜ4|ö0¶N Ö_+½?­�8ŽL †õ"­ÆðgöE½%*áûRà‡Äñ߇eíñë�N”Ž×)ß4 ü¤ÖªF„š1χgºœlµÕV[mµÕV[ýy«�°ÕV[mµÕV[ýÈÕm)àþ½âBY6ÙU­b` «â. Sȧ øì”ô¬*¿Ñèju'uÁ6 w‚šRO­78ÜÏ®¢�º€´ ³g“«u�ÖŠ*©�Ê* rYhØ0t÷TL Hû·r¥!“56T“eï'‚ÈÎÞß²jÑ»�ܦ¦›]47e ¾Ü,fͱ fv+4ûüp"PÝA/d¥"ë–ÔnsL’Ålš�v éHµÎz WSÛ´MDМí<m@xb0USe©)fYC%ªÝúØ@æ®eU$R34yÒ¢ëx‚#5øjÓ×ÛQÊnÉ?æÄž­bÌê8©+„›³¬E ²4E¿º²žIW–ßL0°D@u[iE¦ ÖaóV+àB=_8ÁJ!ÂZ]GØG”Â{\›Ò½ÉÓ5RACY•í3“«õ%¼ø{Œcèt� œo.TûkÄI|4:„€÷ýþSü'@'èâä»W²#_³¾%œÊí+P+T .v¬Zª� °Ü×DÆv¿j ÏîxÀ· bAj`Z˱u�ÔëÚåµ7ŸüÇ—sÙ¥ã= šœ˜Ñ0ASÂw•l8Pô6Ùú:º²©Zk‹1aÈÇæ~Ž+à±�žvñÏ?ÿ¾õ­oá÷~ïwñÙÏ|f m%n1·Ùþ? üWo7U×ÏÑ#-ðèá#¼úÚkxùåWñGßùcüñï½ûó•Åo$ÏÜö8 ãŠÈ€CéLJ›_½¹¹úÕ¸W¦˜¥¨;:´¬é°…V9†`VvÐkê²Òu®s¥xtèä½ãÀÚÌêk8AȘá#nO¿ê{á¶c¤»öÏþüÆ_ýµu[&'Q-Ô×ÄHÄHlÑ0Ií9r!<~ôdÿÆk¯ü¯bŒ]ÁNÀÀ8É# þfß­Ð3×<¼r¾¸s÷ÿõÉO}æ?øä§?óTñX…)ôQ­òH¤pYêU­µÁŽ“ in./ýþém¡ÅûÚÑ� øƒ±îÔý9T57˜êÏBDú|Ïшâ¦J§a¢¢ÒÑÐr?¾ú˱¬÷i@}¿+´§_‡Ã^\ì±,)1T�x3Ïf‰ŸË‚i·Ç~·k@tΖm¿,;\]]áúúÚ2ÃË2ŒCŠýÅSΫ¹­�aðc%ä4°=ÙqSJn¤-&Ä\ú½'&€É w*ÕFqg$w‚ f‹È¸9`Úí@L¨¥à0ßàúê —×W¸¹¾FYŠ�[D‰ÝŸ‘“�ÿÓ4!…ƒ“¯éthcµ.©R±Ì3nÒµÙþ—ÒÜ«‡77Uj'u�ˆ¸+þó”±›&¿÷SÄp-5©jzëµW~ŠškÀª i·í§“T�3dýP«ÿy4¼Gu èÉšMbÛÚ1@W ùÖ••†kÐ#¬þ¬³ÕÕ˜¼1¨›�þ«¹A›^ÿhŒÃ»ÿã€Fî´ÿø"½ÍÉ-}Véü•þ`ðüÊŠÌô8b|J1’Šn1O[mµÕV[mµÕV«Ú[mµÕV[mµÕŸíjû{ëÄ�íÏ ÀYUîªÊÇUõÓLøY&ý'¥ê/¨+�úýdÑ®ŽU0•2t2‹ý°•Z0/¥tËVÛ ÎȪH†ƒôM”GjÏU1ÐÕle ¸¯ž jÖ´Òòˆ�°¹¯(eFY*fƒ›Øb › uÅ”ÙËËhKîè´Y~—¦œ¯EPËbÖÙr· ذÝ�Mk³^§UNlZR#D¦8uoln§M5i©q²Ì}cS«¸&TVY(öBGíÙPO0g¯s¥ŸƒS²Ú¡öß¶qªMÑ‘v £ça³µ«Áõdsv>ÝæŸ)5BÄÔÌfî7ijŽMЛÀá¨kϵŠGVT(¤ƒºƒã�ßp#O €ÛÑ"VW÷Ͳۋ£Çƒ?rgÃÎ h²�l�²÷'gÔˆG0(¾Dt€T0×®”?Ù,6ÄǦÐt¶²¨¯Önšý~¸8@íòÜpe*ñ ÜÜD+P T@™¡u´¸›‚¬\$Ôþd*zˆ]¯J…–î<`¶º32l·7Ó µ1¡’§(‡ã‚_»öìdfWÖ“»X†¾mè¸ýµƒÿm">Æ1�ÚxÄÞŽipÔè ˜��îVóNö‰'ÒZºþ~â‹ø;ÿúïá¯ë[ØïwÍ%¤ý=ü—’óà¿7%ñØo§777xÿƒðæÛoã¥_ÆüËoã�·ÞÀƒ÷qs}AÎSG+RÜB�&ûš]IÌ� )LBV{ˆšŽÚ5£"}î´g=¸ˆøu†¹)ÿÑÁaÀ¯SïK©¢ œl±,É’$9¨Ù‰ë@ãã'Ož:USsŸ¡ ‘(£&A’ä1 ËlQ*N’b6b‰n&êçÜâו�*u¼L°ßÉ!ì®®.óêêò7ÞyëÍ?záãû?û¹/üSï‹È^¤LµÖ\«\©j±6çÕ»¢‘ *DJŸÛ5&mÉ�À²:+…B”ÜQcA%}«Ø•8a·› ªHU�°®7�pjˆ~–€Ûì»�ß{þýë—Ògñvü[oS»i‡œgŸG�VK�Tq¢ š;G(љͩCT»kB±(…(f>+~çk¥®ç��ÿSž�Òäd>XL’¯Åzßr—NÈáÂäÏÑ]–¥ˆ H ¥À"ªµÌËÜc3–¥9�ˆ‘2)!ÎoÊH)#¥XsIóo½ãÞ 76ÖͳÙö«*–eÁ²,¶w%bÕ®|ñ6œØH§»ýÙ]ª ÉDDÓÍõõïÛ=6ÑÑÔ¨�MôáÚǪ Ò™w‘~t\kéIoXµóÆXt×!�nÛô¤o蘰"ßœù3LÔA}ZÑyV±Ý=GoéZGYBCŒR#ׯÔ~|ƒupNÀ i@�Úš§~ªÌü€(†|ÝÀÿ­¶Új«­¶Új«3µ¶Új«­¶Új«V?jΉúÌk¡AÙj¢ÈmíêsUÍ€N€ÜÑ�©Ê§™ñ+Ìø'"øœÈ(À‰µšut€ÆÕÐpà8{f·Ü7v•Š¥Xîvõ¬wòj‚$íY¿ !þTŨP-‹:ÀÁh¨� äöý^Ëâ6»à¹Ì¦4ƒ©,çfßJœ�yšÉòº¥ºumOÉjå¾)(¶I-®† %[Jæìñ®-Tý¾ª�¸@Ç–²`$EÎ1[õMw·ê…+J ¤tÀK UŸ)Ú³tü…È"à” °�ôÐf°¨ƒ½¸g‡7W@)���Ñ�´¦¢f‹YA;`4dyû1ÃÆŸ”¡•Pý^YÁ¾!‹6³eJsï1�¼Êîцžòl÷qS•ˆ�ˆÛsAS‰‹EO¨´¾W$þÛ#Dœí0Xõ·^<ü]0X= x µÂ:…ÜíøÝ z-™?NUûÇ£Çñ¶}|N‰ï„#)€S'(€\õŠÿê­íc9ÀñØ4×á¤B«þLËi†”�ÎS†3ÖA‡ãÐÞè#þïK±9/ª÷•UÎoòc ûûâ@Uœ¤;K€�K1|¼Â^k}Lšj’UÃÑß.=2Êýu`Æ7~þøûïïâ/þò_hÑ´RÍ{¿OÏÿ5È0·€ÿM©k}çÑ£ÇxÿƒûxõÕ×ðâ‹/áÅ—^Æ;ï¼�GxF<™Ýw^\-+Îu0—œì“ÍýÁ�Ä14ÔþM™98pHm@u³š#bH "Í8ÏÉ Ì!Ï- ¢Rü{¨Ä[;àž >Š^;ä%�HÐbf‚hfl8;Ž[žˆX>@ B��1ªxøàᇟÄ#Ê$²04gˆ(R͘‹¥aH�( þ·aÂÝ šòº¬¹Qs[àcÄÑOˆ¨·ùšJ‡ÃÍWÞ}çæ+ï¿÷Þ?¾sçÎøÉO}æßÛíï¼Õ‡DtID7Ì\™¹0ÓÂÌ…€E¡*,�l²,‹iˆÀœšœð†31+h–áK€ÃN¶+Õ‚œ3öû;H<¹¢¼k‡»ËÄ÷ÆÓ3|Æ× ð‡»¨£ÛÆãÓ…êÝ»w1ÏUꚘé÷ ”‚4/˜W`ªôÝno€vYŒDé@ü<ZtQ¬á˜3rvמ”�'³ÕŸò„¼›Ì©õÙ¾žP'ž¤d®Ón‡ý~�œ�Ðk¶˜¿aJZJO5âTfÌó‚¥Ì(eñ6Jà¤`Ím\a'¤Ä�ääÃæ¸Ä�ä¿R…ˆ¢ik•¥'ˆ±¡$ #×Ú8hm³V#>23²¡âs<>„E$‹H®µü¦�IÔÚõ0õôéMO}:b¼?ñïø°í]Ÿñß…e ÝÚÀuÚ+öŸþ©4ÜË­ `‰iø$Ù'ƒËgõÄiáøõ"g–TO»{ú'óý.>ž™$ΤœÊõã×V[mµÕV[mµÕŸ¿Ú[mµÕV[mµU«)€~˜—è:‚Ýw® Hj`@ï¨êóªø¸ˆ~:'ü.‘þ;µêE‡Ú&@S»MºÙZW°p;bº¢rm5ˆM•>䎊+ÃSêħÃí›85•v(.eÈoí¶È …O7FUyC(d‚쬥¦Ò¥P ‹¢òb,¹r¶¹Ð*³‘ß܈ø¯¿ñ^|ée¼øâKxã�7ðÞ{ïa>Úy‹TSU§d1-Å2ß«ší»2yJ€Ì>ô2Ùí‰k‰ Ãø '%tÀ™úœ<þÛjîÓ³ùÊEbØAH}<1ðŸ%�µjíJeUm篣Às@ªHÝ{uB6®"æ'"õç}ì 㟃ëFžƒÒ’*„-f¡Öe¥4(±Gù` Mi#SQõ1Ú›6;ù‚|ˆç!ã˜ÎN(hD;ãŠú©eYþñå“Çÿ`·¿øÏ?þ‰Oþ?ñÉOý æ|ML×DtÍÌ—Dt àJUoÈ»v­ì5æ_:]Ë�uÑÆÜvÀSI˜¦ 9MÐ��³U,Â'î'Yw7`§¶â¸EÁ<楟3X ǺÎMÿÞŠÎà·t–ñÜóÏáæú€¥Ì¨¥ ÔŠZk{­„âý°´yvšvÍ`ÚM˜æ µ”N(‹�=I2 ðgä)²ë”zœ€)ìMÙ…)ø%@r›k™œ²ƒÿû;˜Ò¡ÔÚ=Â�Hµ´¸�ZãºÜÙ@ÊŠ4æ-¦‡ÙÇ)1ûÔæ#u¢SÄE$$¤”Ûú#µµ˜øgÛOªµ“,}]6Æ7™;AgMåïk†dd‹”2T•¤JªµäRÊôÚË/}©Š|µ=a?/Õnýn0 òuÑQ› ›yÔæ:ÄÑ<³µõ¿ézu|‹’͹ÓÕØåçªëãÆ\·^{Ø�Fs~¢~}¼Ütp4¡õœ·êŽ2öy=‹Ó�+m]Y8�@;™¥/¯ôüw/Šhƒ3ÂJFã¡O³Ññlž:ޤœïçœuš&äizÊq·Új«­¶Új«­þüÖFØj«­¶Új«­Z™ÂðÏFéJan¿‹|a¦®†V•»"ú ù”ª|vÊüoCõïÕªdÊË#Ü.¬¯•lsJÄ2ä=cÕ6ܵ+ÏÕ6r`§v N PvÅ¢´Lذ·“ ÀÊ6{…L5ò³C1%ƒÅ3ÐwjÛµ2!'¤¶ÃÊn�ÿyê`}r ~›ôŠ@�„²´ßßäïkö® Klÿ0R”o¶Xs`þ7ŽÞ@ÖÀ®ì‰½"©»�\@¢€–AÃWц¨ƒ8g*Xíü•ܰ GŒ·ªUN$ƒ Ÿß[^_w�‹è—jÉ ®^¯µfÐ�ød¦>†Â�Xyþøê ÿ`û®Åmôo;Æd2Púó?þüîßþ›øÖ·~wöûæ.Á£:5Qs¾U…øéàm‡óàÿååÜ¿ÿ^{ý |ç;ßÅ·¿ý‡xãÍ7ñèÑߤšcI÷F)˲8ØXë}ï~ýÙc9b\çpÑqÈó1OZep†ÀÊŽÿ”s4Jœ‘’†ëˆ¶öDÍÛ=ÀJböùňO¨5´ò'°ñ0îô¹­g;z»SW¾Æ<#ÑxHÛ˜|uu =ÆÂæ/iN;#1"nZD�,¥‚A(Í *õãB¥¹â^4 Pâä%æ5P±-Jpâžÿ¢ƒ£¥«VÚ]__ýÎáææ¯Ýÿàý?üø'>ùýÄê?%¢zÂCYEI…®á@‘ÚüJây0¥¹2ØÆ»:Ú�\Û�D°±:ï2’¿·”ŠyYÀu6°Xtå@Ç2_:‚*Wè»ý±V(½êä¿¿oFé9"ÂU÷½»÷À̸¹a̸iCN€ãÖ´¥.à…;°ï wXñsJ`WµW©à » ÌŒiÊvÒ“¯“’©bTñw…<»ƒÀnÚaq�;û ä<�üyaPè77)®ø/˜ç¥.î¾Òû”¹Gxt ¥6wÑŠ@$¢ ’Úë)wõ¿`aù:�šëÏ0î�k—Zk#\X;,F&Þ7M©j*¥LµÖÝÇ~ǼpwBwÓ ûùûäØÀ oáò±¶Ç¿D>Z/ØšCËSšg¬½Zé8ÿj·.À™ÖŒûBmtj^í丳‰ÔÇþõ½_°Ž8ÕchpIéc5Ãñ¿¯Oc\«ž%ü ‡UÂ÷@ÇNöä&¬HSÎ÷Í‘cR‹ :¿žÞj«­¶Új«­¶úó\`«­¶Új«­¶j%ògŒ°ŽÏlê/ôžª~Bµ~VUzÊô?W‘_©ÖþÔD®¢Vj€%¶¡]9h›x@8iŠúØ5u¦JWpw¹¥DU: ÉŒÄêyâÜ/Ã?9쟹ٻyÌâ¨Ó‰  +Øä ý°ÛÆà2Ð>‡±€Ô¬úÝɸ)J äA±NxàcKrŒÊ~¸ÊS[[Ô#�Ö»»‚8pÛ³¯˜ÍfWßÔän]ÝÖ6”tMmÖŸP·PuB�}8™wä:ǽ Ì¾ùÜaáF 6%�¤ Lm3~¥–ö«ì@^êÀgÜ“ôÂZe?~Žh‰ÐD "ƒœÄ-é[ÿÀ†>˜@Â]Ú�©€jbd'^ŒBxrpŸ`}Äœ¬oÏÀþ”û߀ðˆÞ­´ÁÊÃ(÷÷¬ §úÓñHpôçúÐöÌMáÏí\ œ©MMÏÃÊp¼8×zú,8¹Ï[Et×Z u¬qþ¥’ƒf â÷´+áÀÚSâ^¥c74ç€fá>(øø—ZVà¿›¨‘›¬�ô˜,£Í¢žV €½]ºCB˺wyhô›ðË¿üñ¯ýî߯/|ãçW6Ô§àï|dYçvü¯ƒÕ¿tûûà�7ÞÄË/½ŠW^}/½ü ^ýu<¹|b1.n'nco5Kk”Zš½|#=5u¾ �H̆Å3ÝÑsW™w`ЉO-~¤GȬUsŽaŠ>vÜ8Ñp“xVNêhó‚õ¥Th­íÙ‰*u�¸FHc\fЃ[s”ªÎ0)@¬¸¾¾:;Q÷™³“(â¾¶cI'•Ü\_75ìH¾Àx_W¾XcK¡öWË&w•i냎:é0ïtõ½©�9!LTÊòÕ÷ß}û«÷ï¿ÿ�Ÿ{þùÿø _ø©ïî½»¯Ø)é¤ÐË”ôz7M3Aµ¦ä`å`MOýÜÛÙ+77!j–ë6ö°“÷2'” àTœfF;D�Öúà(Q>¿æ;ôÖÍnýž3ÐæùxÖšíCþWv±÷H¢ŠZ'#º‚<œK"ÆBDPjEj¶úÎ @jŸ7Ô]oRJ­ÿ¥q=5:l §¦x¯¥ �J Ò"rΘ¦ ûÝ»ýÓ´³!|©m­cß<ÏùPÈÝ ÊR|ÜaäÄN\p‚§Œã4Z  †—AÍM1…ò °¯" ¡n¯Dd0÷n$ƒ G‰PsPÔÂÍ Æþ<-ÄD©ŠLªº«eù›'¹¹ѰÎyzuýAi®ôÔ7Б=}ÿ�p@j­ÔÆÑΛÑ�„9|éÀ�k fõ(¥AÝNýº�€ Íaé¼u¿¯·|êó%sGu`Õîuåܲ^ÿ¶ñXÛ�´2�¡(ÜÔºs×)ñÇîåšpl£ð½ q¬ƒoýõoáoüõoáùçî!§äQDƒœ‚üü¯®ŒŽì÷®ö7àùÁƒxó­·ð‡ßùc|ûÛˆwßyÜÿóÍ ŠÔæ42Un­¥©Yã.Øùp{äî!2d}kJnpÀCþúÑÁò_W±#@ã¶3dùöÂ1Ö:"ÃGjÉfná„"w’èczØkgDÔj€]d¨3SÑh$�¨ ¢ÇFÄÇjL¬Ô™v2ºl„ûyápssË<.}|>&ˆ4Ç‘ÁõÍÍÊ6{T©öÙRÛˆÔ"V†{Õî½?Ìp@!o‡¯'ó­‰ÔR>ùðþý¿ÿèÁýß¿¸¸óŸ}ê3ŸýßîÇ~üÿGÌ�“êd\û›”dQ Q�ÏÛ, î3’ÛÈÕÍ+ã9õ�4ëÅe`á½a9"ï½"Ø+ÀÏ3�]~Î(ÿqìð½-êN(['€bD9ñ�co¶÷)¥æd³J7 £PJéÎLq Ü#$â˜"N¢s:L áã µ6ç s )¨Ešãs²È€iò?3¦lózMœ�’rBž,R@U1ÏK;¾T[«¤œ�Ó„ýÅy7yd¡¿fP×w§&j'gGkÝ|ã $€‘㤷\hô¨·û‰ql»Òú^êI²’Ó;ôÄ: ÿnµ>ˆIÁƘÓ�9¢ k˜5ÇA?üw?öû‹û4b:h#lµÕV[mµÕV[�ÔFØj«­¶Új«­ZýY ŒV›mcoµöÑ{*xN /úi&üýOj­÷,ïÜlòePÊø-RÔT{ê ÕN*¹RÜÞµ#°-K>rì#÷ œao=O•ÅtÉb ¡íkñ¨ î{|£ý+¯ÕJq3ÈU¤Ô{t²\e ìz–t¯l&RlPj·Ù';^W# ›£ ì[±Ì4=”Ä&l…eVÛëÙ7°�=�™©)íS �°ƒƒ4¸HØS‹ƒvjîaeÏÉ@ôn×ßÛq(™±P”zŽ<©öLô~†æ²àžî-WÚÝD ZU¥ TÄTy‰�Šáï9¥®ÂµH‡•7ƒ67‡„ÊTre Ã@J(®Jm0!”(«-CÖï€Xbª‡>§®ZV @M ã¡6ðŸ‹ÿP£þ«©Î…�Ä0+O!œÁ`H¸ À>±Ñ? ‹þ[‡¹PKSSÒCÆ(ë ‹;€, P�ÀlçÂÙ·£Jø‰[?m1ì¿' ¥#«ÿð³–q0;‰«ìíîBaœ¢ Þ’“K]©?Z¾c$ýèZI:ºnhsWbä2í&üÂ/þ"þÖßøëøæ7¿�äŸ@�õ_j„—pðÁ=s&¡æ4ý»ƒÿõÄæ¿VÅýûðλoãµ×^Ç˯¾†—_~o¾õ|pß»êXzB¥b”ŽR1χfi±&”ºc �¤:AËsÙÛ°6Ø-Åi(þuPÌcx�‚y†ê(`�¨9¯D–ÉKûrQ5;qІHS8[¦x…F.= ¶Õ¡ÌpES,â… EWêtïîN,c'ŒG€[Ó ¤]š¨ÍÉU*J±¿ß\_9ÁÏ‘‡x…Ŭ î&hnÔÀÆpˆ¨UÌ-6—¤lñ"¿²Â¦ˆ½¦Šš‡®ÖR»«ËËo]^¾ø;o½þú¿üØÇ?ñüäOýôÿ•™?@¦‡¬üÀ5ˆªZEŒ$î´ P0Ĭä.-Ã8¤í)·†íNôÌØ7ªÂ#iD?ä&·;4’ËŠѬaN‡czÊzîCœO¼B‚2ZÛ§`÷H©uÕNk1Bɲ,(eik=j ÷Š‹ˆ»Ai{.}}¡(EÚ|ñ;ÍjC©ýÐocηdä…䤨²;±ñ­Hmç”RÂn�;w.�8¡Ô‚yž±f,e1û}Ï�§ÄÈ)#匉r6瀜�Œ×*jÊÿ“Y¡Å&¤öžñ}ªŠeYœ0ásÃ<»›‰"óãå,)¥4=züðoGcŽud·¦�ö<þN;I«Í=8 ¥èÍ+R»Ú0ÜÈÇÑ�á2Œ Ú\¿Z[¦õûôÌ{E¡§LÙ£[ÉÊ©D Ã=¸m¥¢� Ž#b-=¤ŽÆ…p Pwm:ú*ÕúöÊlåd]ut^þÓ¹~¬Çä§­×NN÷ì¢ç¹ç_ø@´*i8SlµÕV[mµÕV[mµ®�°ÕV[mµÕV[}ôêiÊþ£¿m“ Xá¾g¯€¾ ŠÏølNøoCõVWÛ�*̰\7UàhSL¥–•MꦵÚ8�Œl1“^Ü~Ÿ\íÎ+€MT‘â*';bcfjCt”ûÝòÂ�HÐóÞc#850®¸ÍüÌI„iPSS‹CH�€סp°%NG#gœœŒÐ-ö+)Hë IŽMyWçÓ¨þï6ûLä$†ÔìIÛ6òLE®t€s¶…jjÁĹmÄǽ+Tšc‚D‚8³zÏÚ}ݯ¥[·}gé9»ª¾Ì4Üoêþz�êìeb(1ˆ�¤Ú,´ÃÎ׈cþ3A…¸ íf÷ ãMN@l‡… TS'ß�¶ëšx¼ ¦èo›Ö8Vô©ÿÅtMªß¤°*`³ÿWs{ÆX» D áÙ Ô€*Ìê9Út€ïãëÄû Z¡c†Ž2§áý²F¢qÐ@,`÷’NÔ6í¡ RAK¸¨çÇ¡dP…íŽþqÆCˆrjØ>äPñf=ÞP¸ŸxÌÃqN÷1òÉO} ¿ùÿ*¾õ;¿��}ìWû[ßjÒÉún³ùGz¼oçv+ø/²ÿŸÔièú¥ �¢U,ö Qœ@zG¡'ÂOäÄÿ3Uùõžk 4Õ9iËD�Ûø+h´Ë»Î°DVîpf� ¶û謕ÔÀF%wp»ztõµ –³ªƒ©t»äPê†Í6åqÂ�­på5 Ù̽Î={[PíVm�©¹¹&41jËïöB#Ô*n : &<(ÀZh¥%%³ª�Œò¡m„b?²lÝßàí¶ÚÛóaÛ“˜@ê–¶œÀ)»½m¸Dæ³®"VÑ è·Fµ[ºíH]*©Ã–±„­> ;·iƒ€ÒÝ Ämj#kÞï}JH~/Íš_P…Àª¨µø‡ˆÒÖ®R#ok¢&¤€Xä²lbäÔˆö�‡P$ ¡íÇvö4�“ÖÉäjj×XSÏ›ïVý€ÛQØ?c­¦6côcy©®>ó$fàhìX—8 z/¬Ä%ˆñï‚U¤€gõš½²n#èt|‹_3¹ Èé8¨Ö.¤žfƒN•„Þ¨üY5tÀ²©…Û¸˜7ëúG‚aÌ BP3 ]™>ÚwðÍ_ú%üÖoþU|í«_m@jVÿ¦°&òþÜþÍž+1[ì8Ûñ>QkÅ;#W^}¯½ú*^}ýM¼ûî»xðà!?y©ê*ïnÑl6ø‡ÃŒR ¤0c{4âƒvûèsG Ç ¢)n!Ñ:ðJ0Ä})bt~P•dÍx�ÕÉ#„†g#’0#ÓØòû\)ž^«)ÿÅ3Îi Yß�üow:€ó+uËì1c~ÈÊnÑ,Ü�M@ñèáC¼ðÂÇž:§ƒ¸�Ϙh Ë|8j ÖvW$€èF©÷,nd*4ÐL5R5’�3™;Š;Ô-öÑ¢ÂÞÛˆ´ÊoùçhF¥|úÑãGÿÝ'—OþÆ7¾ùÿAÊI˜È– Y¡*áB¤⟑2!!Ú !©¢&´l÷ ÁTˆ�õ²4 ÑÆ†¸‚zÒž|æúë{ÀÕÎ�¡Ï\×�É-$ЫëK\]_ã0i'©©ÔáÑFyÊ]É_+æÃeYPÜåcžçf�O0!3#çÜ"âþ–²4â\�c=%Z›cÚ%„iŽˆÿËl ¼ºeÝí�¥"1ÄœNhªµØO±enîá:’8�sÌûË<ã€C‹7€œrÀ™mÍÃCt‚/À:QPõh}ÓLJ”¦ÝÎ# ¸ß?fÎS6’Eu7„Ɉ™9?~xÿ'«È/Ñè\Ób[dˆ2ÁàZr‘‚p÷âõÚÿ¨�ŒÑ+¤ñn$ð¬Ø0Úÿ}XrŒý‡œ¨¹šrG°šô´ÙR› V¿Pùpªú¤œºû ½ï öx¹¤«ˆ´q^Wñçè_ánïë÷4Ь³o�UÿïNIÔ3Úø³n+NŽBîÔ€~83�Y¾ÜR¤£CN,ùãˆú þ0?µÿ銸 ·¬ƒè´_Ž wW‰µ„âÃÑ,uCõ{&œ¿œ‰ìö{]–ÙúvÑFlÛj«­¶Új«­¶Úª×FØj«­¶Új«­Zýhp¤ðw%9Ðò<B€²B&wHñü.ÓÿTTN‡|fvÁl9â*à„šÚ'Ànnàú>;€aÊAe~¸ždãP”|ãÖ2k'€É7iÍ.š\…yØì;ÌüÛæªm²ÛØ µ.‰ÒÊ–_“m@—º`© ‘ÅïU�b‡)å–�KW~+¸’:hE=v ¬ù“«â̾þ(#Ùsá+iìSJHy²Ï!;7ªç f (Q*Ä1��n€YzÃÏÙTÿµE; r«9µUpj¤‡~ÞMéË T„\ALè ÎÌ V6+€ ´º-p5KgòxDSÂó”�9µ…R{ξ�ÏÌölã2¢ïZ›m¹�ß•€T}¯7ø+UWØZ]ìä·{�6ø»â–˜Ý&=,Ækdz¥Kž5È쥫¯mG7,û€�Ùü#ù×nVööP   EUÓ¨Ú»­ÆÝîÔ>�ZÎâj÷ Ô ɤ†ÿ~…±Sü ™,ª@ ìÔ°ü�kÙ$k�a‹Ñ#6†ÿ:œCBÑ'=&clw«KlL¤þ»c+¢&Ìå‚ÏïÖè”Êà.rtèA1ú™û ~ñ›¿€¿üWþ2>÷™Ïä” râ#ð?*¼Rþ³÷1¦µýiàÿažqÿƒ‡xëí·ñÒ+/ã»/¾ˆ¿û"^{íU\]=aÚï±S·ìvàLTpss�««+®Nr<$t˜O†œbu[ …Σ1Š]Ã:AyP`FŒŒ¬Ò«‡ë¥æ¾`Ž36æJo,ö'ü@9‚8ë!SÏrãxçmÊRXØUúÜüJðëí$4OôâP@6¾EÄu“gð4—U<|ô¸¿XÐ|6‚$aÑÞ˜ÅÇ<†ƒR²”ž1Zƒý­í‹ÿŽýþÛ|N *vŸ˜ÏÐ k >ŸrP×-Cg\9p«;é`=îïÅ£‡þaÕúËœo˜èFXnÈl�Lu® V�Töö;Xm³=çÀã´zD‚W�÷uFÊ Ìò”lÍá¤ÎÿÌÂê©cé‡[›}ߥÏ:˜½àÁÉ'¡’`) ø`cŠŠ"¥lÎ,böÿËÁ£>–ÅmêÑ�ð3'rÜG{ìŽGî°‚ÄD:X}tþ� ¨Ú8Ä„Z3JN(µ ”âD)#°Ô¥bYf\_û8å¶þpŸˆeÁ¼p¸Ùájwm ¼�§9gLSÆn7¡úñc_K2j‹þ˜&)ùûš1Æ�Z f䴠䌴,¶öˆdÙÉ\)'# ”j±!æj`Òÿ<¥Ý~—KYþ[]µ¯gTø8åþQ�øèhÒ�ËÎZèx,™®§æq%DÇo:ŠGYuz"7ãѳ§ÑÕùÇÍxXGŽçDgÆñ ï K�æv¶oº}Õðw:sÁÇD=òð t ޝW:pÊXÐU\ }¸±åLeæwïÞ¹£7Ì*r ̶VÙ[mµÕV[mµÕVcm€­¶Új«­¶Úª/ ò�ØÒ€Ö±�«@Ž�Ïg"¾Âó‰ôó ý‹M‹°ÞO¶M•ÌâWˆQ©@K‚¦ŠìTBdœ28eä”�sj–ñvJ$±ltH ëýÿSFÊ »i´›�sVsˆÍ¶È·O®„g†U,çµ,@�[ÇzNläD'8 ÀÁ¶Z+ªÕsm+*³ÌÓÓ”PgvßɳAG÷{˜jƒEjÜ §B€ 1ïdV¶³ƒÿ»)7™´8èâÊ<æQmw¬Jrl¹ð‘1ÖÌ s�~1XÉíχtT{Ʊ1Íƹ¾¶©ßìÀ³çÁ™Úp0�=¸�ºèÓ6k«:–$³îÏiBJ¶¹�™=ò 9(°à0/®Td{FÙìþƒ ®Ð«R;Úñ Íü9™Ñ÷`±\#ã�Ö¹ôDéŒÂ×TŽì/'·ü5;wjଦÿê`½+¸ÙM[ÇÔõÞ¦À{À;€& ˆÈÒÈÖO2ºÿ9Y\�²XÇø1h. híÿÝØÚ¼ÂNhŸ™A¤ëw¨q6— ºÅ²À•å�Ú6ßíVUxPôpÌs�¹çvÃɯ‰:q`ÌÆÚ®ŸÐÍ=8Têe"-Ûùù^À/ÿ…_ƯüÊ/ã§¾ø“ÞOÜu¾Ýb“mŒô¨bW»ÛG…òŸÐõœQÜ¿�·Þzo¾ýÞxýM¼úúkxû�wpÿƒû˜—Â�;÷, œ $.UPJÁr84›pq"N# ©»*XS£#¶Dµ6ðÓLb' 8h ’膙:^l&@Qq™ºr5H�¹ÙÀál i´gæ“Óuˆ’Å›4À ¤¤Ö.JY>ÿÊ‹ßýÝ/}ù+ÿ;=aæKb^šã@»këž—1´×0@5æ\im+#ïvØM{LÓ„œ¦åbÏY†œtüÉšü ÔÛo¿Q"€)3PU,˂ĉŒ2Ï æù€e^P¤´)aùm¼1g�xn ÷õG®D�•’ÍG�v*©‚R»r_(L2!ëä}¬€f;·R� 0Ï3æÃ77ט—ÃàÒÑã;–ù€+Îàì×M„Ýn" gsÈÓâd}j­X梂R¦É®/¥ÔH¬”€iš "«±¨,¥4ð?W[;¦”ZßK±öË:©“ªJD4唦wÞ|ýk¢ò•èSëá©OZk§w¬"ºšÊžÎ5Ú5‰€”N—:‡t ËV|»a\œ@Ú²"Ö�‚£8žG‡þãh°£1E×kjÖü´vüÂ×p `ˆ)Â*8i´ú§§:,­SÖq'ñ}ê›Èž=ÅÒA?ìW½“J)¿q÷®‚HK­8ÜÌ«6»ÕV[mµÕV[mµ•ïóo·`«­¶Új«­¶ŠJùGÇ ,7G‹à* ­ž¡jz&èD {Ìéc™ë_ƒÊÎÝGí8”zF.†Hm·UNˆ°]'äÿ3rÎHž ¬•-œÂÚÝH¡ªfJHS”'äÝ„œ³Ûÿ;ù@êÑuºvÙUVÉó©«Dî§4A1HˆŠì6úÂ1ÀÅv)K-X–ň¢ØùyOSFN[„€©ÕiÀ ƒÀßcÒÕ•vHì1¨{��0MfžR2ƒö¦‚Öun©Ùñ�+»|6¼´�AE ŠÏDº*�’Y"³Û]‹(êRÍ9¡.P5µ%'in*kkZjÙîÔ”ÿöü „¤¾1Ï®‘ufJ ¤� ¦Œ”¨�e9[û,ö<—eA-Äæ¡).©ƒ`âÀ˜H5À %$$Ïæ `ßóæ“ U\UìÔ‰vù$Ü#»%¶=»œ’hÐÕBf=~gïl¿6 ”ÿý9¯,ú9<€&ɽéŠÅî¹(D'GmŠ}•áp8g}Ëý9V ¤%wÜAû{u'‰lŠAQg࿽–œŒ Éc,ÆcÉñy�öÿù@Õâ6ìP¤Q9HOÙ�GÏ6^}”hCçu3´Ûù7· NÙÛôÅÅ|íë_Ã_úÕ_Å×¾þULÓÎ(04@ï ˜°�©<¸—ÀI¶ÿÜdÞÝb}ˆaf<|üï¿÷^yåu¼øÒ‹xñ¥—ðÞ{ïãñåo»FÆÚóì§=n7 %aYf×8(¥4;ÎA™Ýía²Ý ƒFä\ðk©uxô`Ø®¥ßôæÄ¡Ý@¢í;IˆÈM¸�½âÝC[¼K£ÉáJûýiŠRW„s³ž¦µê¡PÞî±õƒ6K…�= €œm¼4’7»g›wT©Kv ña‰ÍñÅÝâž>|øà™s{ £ð~kó¦Ý«D„ZK;¦FÄÂêÅÞÎÝ}AÙâKˆÙÕÛqï"ã�ˆì=�ÔV‡ˆ ‘/�xA HBsX‰þFjn cdÂýûü]"üÇDt?'~PsºJ%#gëˆ¶Ž°˜Џˆf»n`(«¹"‹ÜÀ¨`6¢Ø~Úaqûݦ¼sµ¹Éæ�#k"Ë ?ÐâîCÕažíYev÷"8ð_Që�‘ ØÈ�ªÆ/‹©„›‘KpŽâF÷f†ú}ok¦ÊØI¡]5_JÅ‚$¦Þ/K�„û�·¯Ê- Us"XÊ‚Ãá€ù0c^f,ËŒR‹Yá8¾ø:W°,3n®ÝE*ù1œ "^ň�d«•Z±À×Ån‘ž³�÷LÑ®lnl.1�¥Ímª,‹YüûÚ±¯½�Pम¸¯jV[ @N)M�=þýöŒÇé¶­3hXi®Vû�pl?j�aÓO´n˜Úȶ16?¥ýMÛŠ#²ú:)\ÄÆµñÈד3Î:øu}�à­wÞÅË/¿Œ?þÎwñÊ«¯áíwÞÂápfÆnÚ�sÂŽ/Üé„0—‚e^p}u‰«ëk”eFwŸHM 2�à87Y�¡bJx¦Pï9롆¥®¼µ~ÏÃ3Ò–C/ÚõX©Ã5M�®NúP1à?¬æÇ~)*`!Å�ø\¨\�€Ñ�90Ø6ë- � ªåªRÅî¹Û‰§Y‘HU >¨ ¨%Z8˜FF”"0$Ø�yðàá£gÍö½ýz_¨n‰ÿ˲ ÊzëÆP†°€%A©6 ®=_u²B¸] .Ôº¿“¸GÄ£ÅqÌvWÞRŸƒÝ±„TÙjFðhs‘ƒq¥,?þÊ‹/þöÏ~ù+oÑÅN•uÚIŸ9'LÓÎÜ‚ò„”§víâä´Z*R-˜—‚ÿ83v9c·Ûc¿¿ÀÅîyÚ™�*¤D\€þÈ®WK)Øív=RˆÄ 4Ë"-â¡EœigÔýc Šÿ´5Ws0òd›Gȱí”v`&¤”[®µ Íbk—ÄÈ�½gë¸*FÆ<8Ü\›À¼øºBÚú ÍIþ÷¥̇7ù`D–”<Ö@›K‡qUŒ”ÃüfKê#)!O¹õÁZ+r2w¦² $�B‰(™Zjk?â¤Í Ñx�¿J;U½XÊüwFBÒqï×s7+ ûd!†§ý¦sôøuÒ”ÿ1®¬â:°&„5€np*j?ÇÛø0L÷8!ײ¦ãÜà.* èbTHÜÕ­‰G¥·´{I¦LCUE‘êöù†¾fÓ9�¤®§‹¸Bz±68/R‹hQ�CÐæÐè1¡¬Å68a‰=¦‚}Â¥ÑZ¾¹:ho?ÐF|Á…Ò’¯[[AsN5,{ûxï½wþͯ~ýÿ§Zê(ít ”tñq6a7%ìv;ìö{ä”ýœ¸eÌ/KEYffT.v^ÌH)#¥ ‰³E¶Dñ¨†mµ¬J·±o÷Åç,q Ü¡ú6¢·vàÏ›ÃY�¹=¿ÑB.ÂÇ÷p¤ÊízK)FP ¿œf¸7B@û{]ýÛ”óþOvßý£oÿŽª~Žïõè4t^ξæ³Ýôd9ð4uùHŠêqE#4>¸š ÇV½Ý^þ”WìUÏAëÔÆà§èíÛ¡bYHƒÃ+ŽÉb§nÇweM$ìDºåÚÎ×zô»dídØ!zàÔö¡��¸•p»MÀn·C-#Cm|›Ìù¢¦íËüV[mµÕV[mµÕP`«­¶Új«­¶ê%=5˜V+“ÊÈ»_Û6gT0¥LL{@ŸKÀo€x×Ķê.Š•ítß…T¢¦@,aPUHª`±Ͱy®ž;½ÚÄeÏö\l› ª(jSòsxÉUÊam›ý¦ô(DM}UEP‹oö:’K®“"X¤¸5¼ NfëÊĦ$L¹9²×:ØN‹ Êbšæš ÓÔ•º±A®}cY†¼ñê„ ­ƒ‚ŽÉlí9�SnçP탈Ñ&io¹Y…„ ‡¥XQ‹ƒÙŒ¦À#¶Ø›3¢­8è&FŠßP¯þÜÌ"¼"‰+[‘º»kZÜ€ºK¼MÝNÝÛl c#thb½õ¸ä ¾Ûk‘ ûÝ„DÜ5çjm ”½¬=ˆôs±ö‚ SÇRµççêôž[KÍšØ5‰áššãB8YRB'ݨ@«=”ªbmäyݵ9dt¿Y`¥Ä•úº’�”ŒäF·ö/ö§ºrƒ�5ŽÂtÏÿ»ÈºŸ�‘èQƒ—wôQ]ÜÞ;@þ¥“Ö~úÝAÀ‰=æB0¸�º#ƒQq—°GÄ[ú†:c¸�«]ÿaƒŸ„O}“½ÖŠOâÓøò—¿‚o~óçñÓ?ùSH™›�?¥äê}ö Ä7€KÑÛ@¤)™SHNVqÌOÞ‡xÿÇ6<ºÿ4B›ªG'Ô²øÐ¾CNŒ:%¤œ­�ÓHs²�Rå)a±ÇÅþ¢uo³Óï¤ ר Q%wjãºÈ³WŠ;0p™,e�iýµÇ˜ãAÎv¾£»D\{J©ÿä ªd.Ùœ`"î â5j­­-1¤’PóNÌÌœó”RÚ__]þ³Äïã±F·NÕ1?Æêx$Äñ´Ûú:õ“cIªuM>+îÿøË `PW^ÿ:¬Â1À\#ÙFÏ_"… ¿®W«í¼]W¯+o€ãþ0,·Ð�ÄÆƒŽdŽcðþäûÔɹ†UµVk�§Ö9jB�%Z¹<%&àÎÝ;oæƒÔZTU5å„iš€aW“­¶Új«­¶Új«?‰Ú[mµÕV[mµU+ùˆÆÌN+Ö 6Uãß›¢Gü‡5Cp‡A÷ýõ°à¥ÁþS|÷1òNGÅ=55¥80Öw·šÒ�/õÏî�qœ°Ä&ß;Ã¥«aö¬ßäõ¦@´0£¤)½ÅíàµF–/�.g”‚*Œ$• Í;äÙ†yÊ®¨ÊR±SY3ªƒ ¦†¬®ööLW¸itûœPS…:.jÌ Ö õ¬xN œ¸«¯Ä�!–{ÞÀˆAí¾’(�j%©j2g!íŠL[8ñ úó�JE;÷Z«Y^oŽßè1 m1R «ûÚž5œ¤ÐÌçÉrx{d�D&L ` 1¸�ÙŸSqÐRœ`VádŒCxmí€  ©X¬ ›í­]¢aÞö÷kÑÁç¶G^ô¸‹*n…¯‚Z»"�ˆpg˧öõí΄§mjrt¼2¾ùØÞÿXµ¬ãÛ+Xx`´Šåöãšß¸ á_«ƒýÕÚ¢0*¤–ü^ßbÐï LÚÜDLîÏCw×î~À T¿ #‡ëññ¨A¦i‡Ÿþé/áË?÷%|å«_Ƨ?ù Ø3¯òá9eW £�=ìÉ•ÿRý,™º¶ƒÿ¡ú¿¹ºÁ£'�ñöÛoãõ×ÞÄk¯¿†×^ï¾ó.?yÒTµ¦Ê5‚D�ŽJ­8ÜÜXNö<[sHG‘5µ¸’îž ä§U/av�EmΈ1º·€N܉ yJvÕRc�FäˆûÄCÿ‰{ûí·þÁ—¿òóÿ—Äé1SªšPA(P“Gj ]lî!0(9Ö&”näCWÀK T€$µ‘¢ýÚ#ÆAåÓ¡ô#Ê ˆöÚ"r²5\8Œ`ÚÉpµr‡“ ¿�î X¯Û¶žx{œç–Å *ÈSB^&¤\ä�TánÞG³G2ܹswï^ØØ™S‹ð™[#‰iÆAøœ³GB—Lª“ý´»U”Z Åb<–eF­}.¶6”0MÓ4aÚMæ(±›�=Þ…ˆl©�DHäœ�l.»i‡i·³ó g é„W©Õ�'r.`fN)eæ´òøáçK©íül5Rjn±¶×1§ž°&Î oÐþ;½<>ÿu Š?«¹ÓÀT�Ž{fnJÎZŠÑ¤¡Òú¾N:†ÉEåìqÇëjþüG'¡«ÿ9w…„§“&�^Ùâ0°ôô¼ô(¶èvk‚öüôC:“¼ð±�½vuyiSµ ¦i·}‘ßj«­¶Új«­¶:ª�°ÕV[mµÕV[µú(çÁž;5íj"BMoH‰ˆöþ¸ªþB€ÃJ=�úxÓË´zaìÊ)W Žn´ÊÎîöÐÝî>ÔËž™žxÀT¤)Ùíº¸¥f&v§Ûǹ¸^JAq€¨ŒAœvÎæójŸ"‘)`ŸÀTÉ`ÎMÍ%„½¾›]-+\Ü©À¬Ÿ�@y¿_*QÛ˜®RÛ³0•>|C’›¯ºõºYk[æt·N¦uæ)†œeç{TtP¯ÖÚÀ,‘jêcÊçqÛ[u W·G'5ÀQÉl�'sl¸eÒžKo9JT;¿ÈdÖÈW¬²ª£MÅãj ¤v�·±äù¿Ü6²«(X‚ÚÕnd×@ÌRrkäfÃ�¦4 Y;!�8e;QŽH.qΣ"®[}W'�ˆ?Ãn�;í<6�ÝÞ~…*ѪÇy¸°2º§•û€}°s‚Œ@X±Ö#Dëo'¿òV„ÖªÙG� `Aw*>_u}¾R@Í•@´»¬rŽW„¶&£ogAdN".Uµã ä&¦¡Ÿ�m38G„’Æ8i·†ð?úþ÷€é'»JnDs‘MȸBœ0LHc’B)ÍÉè…­µ‘J¸�ÿ××7xôäï½÷.Þ~û¼úÚëxý�7ñÎ;ïâáƒG˜çkTwô æøaŸÄŒÃ|Àáp�ëëk”enJL&2 ‚J¦Žuš�µÃÞ�ˆkà›kÃÐßbÔ7Ûp5ëcNâv³\夜fƒÏòÁ¸7KhXdIŸ;ÂØ �¡Ï�àÖÚ Ø€';Ñ,@­fø/ÒÔþšr_T€ên‘kîó¹4‡–¹¹�ê1.Mu>Ì¢ð¹AAÐdãÔ“Ç�Öãis_ Õ\ßpiS-M£âêêÊæ&±8„$£*v}.T¥Ýõ¤aü8vøP²¹IA6¶� 1ßQ�½1²ždš…ù ´U‹ø¶s1W¬žýáfþò·¿ý/~ûË_ùú¿à@L Y.‘RB‹§(RHÌà* ¸%˜ÇÓŠ,"R ¦ÒlÝ“»“Å((ù섇rìŽsÿõQ¨Ñ‚¾E%#M†¹´­+Œddf^‘º#ò’õÓêQE"©¥¸û Ã"|í1%£ÓÈ„lü~¿Ã�;¸÷Ü]­RKÁ<0ív˜–¥Í3qžSÎÈÓäçKF¶ó~öûa÷¿”¥9Š)‹‘¦ Ó”±Û€?M Ó´3u?S»îR fwˆëMÞfv»=öû½ƒÿi¸Nk[Ë2£”ÚâbjÉà”ȼûà½wÿ®ªNëñmˆ Á¹©{­w§ÑïãÏ)Ø�Û‡üïQ'¯Tºõý8éã3’Áè¤ïèØ¯(x Ô× 4~×ÑÓx–©ÖqO» ò[×­ý¾O?ÔHUç�ÎÓ•èv¥þSb†3ª?ñ?õöåÕ•ä””‰°Ø2#‘nµÕV[mµÕV[mµ¶Új«­¶Új«V·íÇÜ&ØxVvå‡-ºí`ÔÝà1¨kb#_•Zneäì²[ÍbNÌiÏ$Ê{l�"À õ|ÓÑò³++í3`\È7š�m= NЬHr³-åd?aÑ|ºñx¬l60�Ûu÷�çØì•êªÎQmæ÷,ÔÚa) æV0¨_„”©Úf³T6Å¡ðÙLNr@×T½¦F‹¦DS¿ÑQ‹xòu¤ê�¿ÚîmÜÏD8páÕ@¨R3r»žìq�ô8þ&Oñv@ 9�bÓ?ƒ“)Y�·xÔ´u º @Kß5%¿B™Ö9Ó«¾æŠy9UµÅG}í?�]θ¾™ñèÑCG*DZcÓ*Ê “^Ì�ÁúM­ÕÛ¥9R°+Á{ «“Ú ”A…«X»i€�,ÎÙTÿ䀱׸bŸ3Ö· nñ³ý#Ð(CÙU÷Ô£ÔNˆ8­X+ÿÏmºß'¬ÍÔAÍ& �à÷0ªHgTê—rg·ÇBá¡ͮºuÈf+ Lˆ8‡”Œl‘’õää‘´™“AæÜrί?Á£Ç�ñðá#¼ýÞ{xç�·ñÎ;à½ÞÇã‡q¸9 TwM`vëyÙ’s9`YLe[–¥©oû�Sˆš“‹x?&¦æ0æ_·{àn ŒDð,tô|vQU4À_B�JQmhŒ„p2S#¿ pËŒ÷(�îkçî. ‚07[™ûim6°¯ brJ�V³”÷c¬BlÄ:T�*C ðÐ#> 7"Üš¿�Fs{}¢>Äë9ˆU­2dc}1BÛ£‡Ï´Õn‹ßfÄ#´Ìg\_ÝøØSQ•ᆠ�˜§„Õ„ç¯Ê°¾J±C«±QU-–#ikå´³Ø]MˆÌÝ¥EøúBœ”í P�'„# !ðö[oýã/ýÜ×þn 8(é ¦‚:Œlî(`n<§É@}f'$H±uF•ênæÒ6î9ï (KÉ×(êk)YÛ�� é#XµŠÿTTUësrnœö~OÜõ Posqϰ§½05g€”R� Xµ‰ ÷Ø\nN½ŸÙ°dí,§„Ý~�‹‹î\\8áX–‡ÃnnXæAœ¡lë̔ٔû9\›Œ×^–‹.C|‡ÇM±¿o·sðÂ.g¤lP&†ˆ`^¨*–yÆì?¥,F÷¶ƒÝ&iÑÚq¾8Hœ€ ¨,‰ˆ§ÌÓ‘ü•P¢ˆ”<˜ÛЦuëjXèä�–�ªLW51gð˜†Í5EØæŸÖñYD;�à€©ý«e®ü�lö£ E Ò‚Ômc¨ˆû$žÝJ¡Fd' Ar4CH Ôp°ÏÀÀ>잘]ý˜¯'aỷ’[‰´ˆ»ëAé×?*ñbWŸ Ýú˜Šøý) æ Év;%S_ꪨßG´ge¶Í@Rîj¹œ ÌLÔT¨AÀh¹Àí>xް&‹)º"~�V;F@¦v08"ƒè&*¸ººÂg¿øE¼àsŸûLkguYðèÉ%?|ŒGOãÉã'¸ººDõ øè:Çqð] ÉëÌíUK<Ú §Á5`Õ5 4‰HŠêÄ enΔj’ht�uvûüAy`4FÈM€2¨é˜éw�ÉȘ¤Õ6~¿ zòßi®br2 š°Vÿë8f ú¡`#FC œPpn´È ñoÿ Ž"KHe5#ƒ=F¿1'ù¸1ù bÊ턜’÷1#‰ˆÒž™6+1Õ¿ƒüÉ O)§¦¤…çÙ×ZñÞ}úßûà>îp<Ä£ËK<~ü×W—nGng¼Ûep–…°ˆ�ŽuYpssÀ< ô÷qŒ=fÀZyL…Eà a,f<ïÝRªÛ¢fù�ˆ$ˆ§Ç®â4”´ ³BJjSÙŽãë D�|üòv®§®È­ÿu2‡“üÜ,*€zŠÇI�¢LDÚŒ"MyK²¶è7R– .#xQ hĶÇÃ@5¢A 'ôq/\J¨4Ö}ÍQ³ŠòÀýO@3‰á#0ªƒ™™Œ Á F(0)H«9:8 ¤Çø³`rm9î`wMh ƒ�÷‘$ÙŽ1�G`*þ×Ñ𹾆"¬ü>ú½íóå°Ú0€ë¯¾øÇßþ�/þÌ—þ#.AtEéJi…Ô©öC^óû½YºSb$�E÷2›"œÔ,å§Ý„ Ä»Y0´.hÕ³k“�äzÕíçk)(u1W�ˆ] ƒ›C”ÍõF˜v;ä)·u‰ÔÈh/¾æp¢À”Áv§š›%rVö1ª;„2^œý#9�Ÿ§„¼›�§3Dö˜÷{SØïv˜w;'Ö•Fµ÷�À¢QfÞ!«(EF†&µ8–)cšvØïíØÉ­ü-Ò…ÚZ¢(PCý?Ϙ˂êjþ)ï0M“E\\ù 0ËÿÎÎí ÄhRÕéáïý«¢ò3ˆuôÀÑ9^�4ó{êÄU¸C Ѹª7ƒŽôT�ùõøî3Ǹ^Z­•V._ãI: `øüæÎ²^¯æ‹Õj"Ö‰3|T¼'â�N�Êô|À0/�NÇuÉ“ƒÛÝß´¯ žòúNÊœZA·‡àLôÆú³é„ˆlK"zKTž‰¨rÊæãÄõ‘k«­¶Új«­¶Úê¿ÙÚ[mµÕV[mµU«�rÀmUkmv¿M± ‘d"Þ'NÏò‹=^¾oЙÛ6A×1±4ãâe¦f!Û‘a»�›:œ9µE³J­ž±¯UWÓûÓøù-UÙ?Õ·{¦ÂF"€2›ŠÌÏž•–ýµ ÀfûlöÙ@b‚$³�gW‹rr?ˆ ñtg� ¨¥§û³H)uËa» f‘;Zó™è„D„ëL�ökL¸ˆb qm‘îž_OÕ7ìšÄÀ+Ñ•z–Ü�4�§ÔíƒÙ-„“=k©žï›»Õm¼Iûý­UöÒºAZH­Ý1@GKípð�s&ÔÀÖ”ðGø‡¸¼¼Ä>ÿy<ÿ±Žy·Ç'?¹Ç'?ùÉvLp¸¹ÁãÇOðøÑc<¹|‚ËËK\]_¡,ó°ÃM§P¿ÿEDÁ¬ǯĨŒ®îHQ«»S8±�¨2t&eÏop€stRó¾7U$eÿšVºÇ.àäí!õ÷z+ìøã]îøŸÑQ€Žl×ÏŽŒ.Ït>¡9@u‚‚Ôã»õ˜ÑwÔƒ�þžU�+Àî¶1&#ŒA?ý•zÿøá5²GJ %gÅE­o™Ëø{#R1'stÈ4Xb›’øpsÀ£‡ñî»ïáíwÞÅ+¯¼Š×_ �ž�hÝ»D�‡Fû‰ù«»0D;‰Ïa>jsÚï�@礓G�Ü-‰ÿ�s”>7�Gb3X77‡ç"¡š¥êc¦Ûñ d޵7ëþ� HÚŸQ#© ]—‰mTrµ{lA¿ÞpAÐxv2DP`õšJ{ˆr7£7ßxýßúÂOþÔÿ[ Aô˜7½æRÌš½*81&É€*89[tM<�Ø ±÷¨(’&uJHšÝ¥¢“ETô(Sœ~$Ö¬µVÔRP9µ.ÃÌÐÌ jÏ›#çŒiʘv£š^Pü8�lÄl$%N­½D{O‰‘w°‘“½.Ö‚¶&-‡¤m>d6¢‡ë’R6G‚Ý~Ân¿Ã~ÙA¤ú°$�<ñlQ,ê P’ %AN¹Ý"BÎSþw» ìö“;¸‰“ƒê¢-Zj™g,KÁâêÿ ¤”°ß›‹@J¹µ‘Z«“}íä3#'+NiZ–ùw œN¿Æé—Î ©m®$:i‘»ÑNì:Z²¬Àõp¹ •ëÒvÌPpZÍ㈽õýø$Z{�‡‹±iåBë`‰zBBÓõц›¨+ò×H8~oüó©!�Þò]ðéß »+Œñ»´Å¢M'ï½�®zº®IÌoL9‹•j­ ˜ª;¡l[Ü[mµÕV[mµÕVcm«£­¶Új«­¶Úª×Ó$êzËïÿ´NuÜ Å‹mÔ11sÚtÁ,I� À÷–ˆN}k�Ž6˜Æ ´Ø˜££ ïÙ«ž!Í ¤„ì`2q7 ‰ 7iÇkÝèÌm;R+T\éÛ6æ-s6)AÌŠ_eÄví” ”Ñ#ËtªThQˆ¤L‡ûCN æ¾É;ã”’«ÝÌÞ™\ñJúC)g›ÂÔ©Š+1ùè9Ž�ë(5tPu¼ÊdZg2‡:ZEað½ÇˆK†'¥–Ÿlæa�šR¸*PÕò”A ®!Û î¶®­=6u¿ÿžL©¼AˆœàØ4ÖAÊ‘àµW_ÁR<ÿà|ú“ŸÆsÏÝu°ÎI¿dpqçw.ð™Ï~Ún�“ ËŒ'�žàÉå%.//qyy�Ãá ‡ÃR " ,y�ÏÛ”}b÷3@×ѹªºåz‚ªâbîÙ²‘Nd=ˆp³óó¸ã}§æµÉÃëÝ�‚‚0fùCÛY NU˧â—ÀÎ>I@Ɇ|jê;é«s?7©º©@ÿüþ7ÀS:°ÚIÚïW1®~gÑÁ úAsHöߘ5tòìkœ|aÀWj˜Ü²´ ²>ûèñc#Ÿƒ„‡Ã¡ÍWív ÆqË Wâµ²]�Ö   ”ì9éê|u °9á(A™ÌÉehkäl5Q¥´ö^ª´Ïí IWci›×”ÌÉ€×7W_{ååå ?ùÅ÷@´�ˆYcmƒa<5‹°ü¦çf?ß"ˆA$½ý·{bsP¨e�{¡íÐ9õ‡‹[?}ÏŸ¯Ôb~Ü�ÆIhĶîH9YÛLî˜Àl6øû=vy²„8Eï‹`§ìä'�ÔhN+ÌÈ)c·Û9qT=RÀ^„8©ÅAõZeåtãáR ¦œ¡b}(§„œ¦œQ¦Üçß¶Ö4Bœü=rIÉ6öˆ�svÀ~�ý~�ÝîÓ.¬û�,¡Õüþ/(ÅϹ:ÉîÞc ÷Ø c“_ûdÄŠœ£kPN™ò4¥iš¦'�þ”VùÍ�0€øà®6%}Ã×u ™Ò-h>ÖSýú0tþ»Ê®ÇªKqär¤« {m#1õõÈ |´^-¸‹O{:td€¾¶lcÄ@¯ãzWÇÐ�Óï@OýR6.ôôÏS6ųûª>¥“w2ÄY ZôC<ÙáµvŸè;8íñkÑ÷Szóî½{²,‹nntž]ÄHû9\\\˜[@k©z¦kZ[žò„O|òøÄ'?1lLÛßnfSaß\ßàêú€y9àæ0ãpsÀáæ 77×�|â ª»hëŸ …»Òò‰{^=÷‡]�;þ– ÌF_+ÌŽÙÚ�¡$fõÏvŸà<2‘FÆûA· X£õ'E¾¶ý½bM<°kD‹”p°]';žf ·ó °ÓkakX:8¨v¥s\ŸÔ#  KAFžBX€÷ã ÛÇ@ÈýwÎ+%5ãîÎÉr2€4gN¦)!qÆR|ðà>xÿ}¼ÿÁ¸ÿÁ}¼ûþûfñÿø1®ž<1�KLyÇû½“…2˜–eF­ó|ƒÃá€2ÏXjq‘�S@B Õm•Á@dÊm ;z#9ôÌõÃ%H(ª«Ç¯dÿFÕœR'ÀNÕð½†ÈÇN—WmI:f¼r0‰–Ån ÏkûøX$R›+IïüömÌíîôÍ $bhrkdWœC†vwÒä{F½’ň·="ê6ö)9€¯­yª „ˆñß|î5RA;q©�çv�XƒP./Ÿ´ñT%žYí¤­ˆdÐêÊ|iMšÁ˜ÝÍdÄ¢)HÆ1h€7€¦jïÏ&ˆ zjcíϢ͛¤ŽÛ+ •Õ%hÐïS­µ©è‡еÛ!"èÜ¢§Š¶&ðÖ¯ÿýûÂOügDt'¥´#ÐÌD "L)#£r¨Ê�°¡Úò×cmB L)AwRM±8hļFp ^ÚpÆ>ð¯ùþM¥v{sÏÓîKÆ”ip2{7í°› üO)Aª¬Hä}69Ñ(Æ ÆNŒ )õx[ωÈÈN‚RsÚC¸þ”eAYfoï¥õÅpMÊ9CUPjÌ»]µ�ZÝ=Â\ªÔfùNþl÷ûöû‹þï÷S³î×Emfós±ŸS÷‡FH="WÅ¿±Ç „ƒA12qJ”sNÓ4í¦i·{û�×þ‘çÍ «^u²N�(Èí󻔞ù~jÿce9­�ö‡-Wœ cÔ–ž¾ÿ¬@» í„®{|›.F*âÀÇ\¥©Êil€nÎщ·´�«¿§…´¶NgŽ@úỲ>íΟèY¾¡9Ä´ÃÐ3¾súA¦i÷ƽ»ÏÉáp-µ=X–„âDÔ­¶Új«­¶Új«­¢6ÀV[mµÕV[mÕŠ¾GU¿ê÷¿Ñ²zð°‡$O9¿AmÓÔž2l\ 1§DDwˆô9fú8D~µ‡{º²¾æ1£^µY™#²£ÃeÜ>ئÕlôÍb×Uéld„ÈN) þÈlê-MƒòG×ã)×6ŸÞ3Ë/&q½aw&âp"WLö¦jYɆ7ú=ðgW™ÝâŸ�Ù,Ø ðwå¨BÕ’4ûú _0R2kpÛ\gáR-[WTP‹Ûœ'·‹ÕõæòjÓ ÍJ;°²Õ&5cJlØÚ¨ÝTSá5…©•™,¿7g¤)5Ë_^'*@íêöhwD&U‹%"T't´Íô!?VÜzÚSúFº(J©Ö~D‹pS WÆÊÆ;ÚÝ›¯¿�ÏþÇ(^~ùeܹsŸû±Ïa—§!÷Ú[IDÑc´ UiÜóý´Ç~ÚC_Ц<Áµ*W——¸º¾Äaž1Ï3–Rp8̘3‡k̇n ¢ TQ—j¹÷Áªˆ~Àdx~ÜsZ+õª‹])H;Q»FbϯÀ4¦[Æ zÚèÓÆ…@ à°!Gu-¾ßH&C•@HÖ�95Aá}¼vB¿¦°  �ïÚ>Þ舫g”ÃTÕܼ…á¡Ïþߣ‹Ö»æ1Å¥gßø¯Îî®N ‚Ù�+̱ƒ‰P«àÁã¸ÿ>>zˆ‡âþƒxÿ½ðèñ#\^^bY–n‡N„©£{pþNtÒõí7íé÷°Ÿóþââ�;w.„r˜gÁå•V'Ö}ôƒK¶Új«­¶Új«­þ›­�°ÕV[mµÕV[ý)UWTÒj§.P´þºÛˆ £:Û7J™ˆvÐzàç å׸k@ŠT¬žIyÓh*î mêe­¶9W‰Àê 9…]¾)Wt°I‡H*¤jä¡úŽy¾¹á ]yn €¬hU7ö0‚²zz•7¢æ00fÎÃÕV Zs�%Èêv·œÃÞ�‘\Hl1*‚¥T”¥öŒ[íöºœÓ�­ëªÄZ›22Ôfñ¼]Gµ²“žÕèþªÀ‰B�  ”ÙAø¯~í2lê27 _Q!5™êš©0(þDëI¦«8ê,›À{DƒèêÖ¦,ì^cÓ~d<Ù®)†- |Ì_–o¼ñ:>ÿã_ÀnšðøñC„Jq”¤Çù*Véñ”l ñ{fJKG !ÔäHy§-È!h =1á0ðäÑì݃DÄþºñΊ Hç`MŠÈ�A)ÚÔˆ#úó¤Ö6Õ—h � *`!T„u|¶]!n©°¼?Gy\ 9àŽ-NMjõþw­ Ff§1¢%\k:h~¬ðU¶õAu%íÄìÇkç1òДxNÑ7VQaJ«±týÝC×ýéˆß'P‹s°”Ða à«>—žÚœ€á«9$z¬®"†%ËÑx:">«ô¬íÀÓßO·ºœúŠ<�00>çñ{xþ…^Û_\T@åúzRk­¿2}D¬­¶Új«­¶Új«?¥Ú[mµÕV[mµU+ÕùK`@w€Þð¾00Ä)‰"žoÿìÚ—¥À¤) $…ë0ä'8øÛÔ®$J–òY9W�·=Æâ`¥5‚ŠÒê|×ÚW€Z=;9¦1E1—ÇÜjlsI̸¾¾þ‹¯¿úò/}õ«_¼ßïD¼( µT­çHpdN-Å]‰Jqëy&d6û÷ýÅÎæfØgÖZš»�œQ?œsäô4˨ÛÞ:~W4»ïá˜Ï¿ðj5×$‹aääYõœ�Rö{äã�ù#Ȉ¥,Kñy¾¶¾œ3©‚e™1/3jñˆ—Á)ž_u\)¦ü¯¥´9“�Ö×µ –R�–ÙÆ3Àc¤bý˜ÌÊ¿ª‘UÑ]ÂéÃRcu .°�1}J,þ�ÐP¤ .¥ý^ÕH@êî Bvâ�Š´qf¼_qÝÇí ^›RJ)§=€»ó|ø4’ÎÚÐÈ—#±.6ý…n0w[«€•wÔ‘ÿ9“®Ú`¸ÒØ—m4cîÀ¨ZÃ?Î}wZ­Máë7Y“ót ïÅoD{ä ÚxÖI¯z‹¥þj%£áÝ¡Pú0_ê¨]¿Î�¨nû¼ù%1ìDŽ3`Îf<ë°ÃSô÷ñ'¿øú”³Ôľð¿^nŠøUOoäþ7ûìR*”áQ7Ôã(üÙV•&…�ã­Ü”Aj$©ÑOµ?—‰@¤oý±÷Úq²±y$Ç¥ ñ1˜G�`�!ž‡ÐcŒ¤ H�ÈFœèÍ×_ûï|ã¿øÏ§iwCLs-R„bR‡Ùø±ËÇ‚˜oæe03.ˆ±¿ L».öFvÁRÔ">?®�CG c¸=Mi{Û{Àë‚õë¾—c>ÿÜó(µØ¼ê¶B#§Éòé=ÀxWó"Í¢ž,ËÜÆfm¥ṪJ™ÝaÊÈ Ì�Ó]}¥TÔR�䎤ф)ÅIݹE„=MQw�⇤Õ]ª¤ÚœBdc¡jíQ¥´çmŽ#ÅÝYì55ÔÖ0)­¢µ0ŒIæ.Q À¦KY¹Xˆ‰H–*»—^ùÎß’*?óØ*–fh}mëêýñYÓñ³Gs|‰¡‚ŽÔÿÏò²§ÁµÇúf÷ÚÒÑ–kuŽÛàj%ªGk§ÁN_×ÿÓþY‡õÔ:Ù ; 0qwR9¤cü^×�uÐÉ÷(=¹ßS)ðt´žÚXÚô„ÂëQ4ß㧯-ý›¿ø~©µªŠ0³æ”5s†$ýž£ì¶Új«­¶Új«­þ¬×FØj«­¶Új«­Z�·{<Ùö>ú½ÿ×´é"Ïü·Õ~ô�mIÍö`æœr¾H)Ý#È_VâçÆÓkØ”r …h®&Å6<¥V�l?”ÀœÁ)ûf°[ªJAS‘™rßíg›J³ÛR·÷Mbu»ù ¨vU¬ “:x!æ„1…³{ß0„eÑ–R;@Á©Ý#Rt Éð«v¼PÏpr[cßV2­Ô‚RÌsA­êùØ •�ŸgjÏÊ©a'L ` ezWåvT³íc2è4F4¬lWÛm¿_£lŠšë‚²™«ª,f¿;/¦èó óý®ºC²[kuøßò¦=ÛÔAdSjÊŠ”Ô7Ø»:WJu U]%mÜ4M˜v»•ÚZÔÞÏ•‘H ÀëyžñîÛoãsŸý<4ÙfëR æë–²àÁýxî¹{xþ…çññ^ÝaÃÐà dÂò šª5Üh•cndˆY~� [€ÿ]é ”ÖžaH±2þ К ƒ®c䨰 †„f¿�á‡Âv?Àý EÅy�êQÝÿ4KØ3 �ÊÑq��k@g@ößHF8¡là¡*˜+j�ÑÔÉK± öF.G§E'Cñ¹sÖA HGVÈÿüŸÿs¼{?CD0Ï,Ò�3·qjyä*ŠëËK<¾|‚«ËK\]]5rÒêsˆÔãZ\Š(ÔIM ½ö]�` @k·üg·RÖ•M+ü<ÖAú2§�8Y°±’s2šÿJÂÆ[lÜ1bI¢Ås´k·ò&j mÄmˆ`•±]E�*F\ ‚ø½É99ñ'ùg'0Õ…0(›õ½ö¾DÞ‡MaΖYïÄ*�žmd <ÊH&6O$î¡böø†Z�¢ ô�“g»lµ±Y¨K¨sy8fLæÜÀm’†gÅÃG�:5&¸IÞ×ý ›½?7H±Ì‡ÖNcN�»R˜œ ÂFq¬æ_…hªEIt×´vjàˆK¡À®ìº/Œ„Õº,�4RÝ$,é�*µžÓ‡y“Xq}}õk/½ôÝo~å«_¿p%"‡Rk­ÅÉ8™‘)u5³ƒÂf/ƒe®–U?%hµ5IÎSήš'TŠ5Ë0àŒD˧(‚£~¯ëÉ“÷è÷à€c¨b©e)¨e±õFÄc$FN 9eŸÃ‹G(”¥àææ€y>4§¢8^´‡Z+–yÁa>`Yì5)34\¹�"�tãQ¨±8%äl¿”R³Õ—xÖÔ‡n í­}cM$ãOw7!!'�J#€V© º€5yw‡‚ZÍ•(Æf$'Oô5K'M…½z×î¶bkŠRw��¤ªí¯¯.ÿû}½F§³ì0~b?8ÂŒàwsÌPs5ˆóå�DpþÛ‹®À Ày#�Ñé’ ÑÅŽ#¢¿žûÎt‹ûE�=úµŸ:\5.¢?úÙŸö'=Ãÿkϲst–Žð!¿3®ž«ž=ŸãgÝè¶�¥wqÇ�‘ŠÊœ^}ò䉨H• ¨NÓ„Ý~×c„¶Új«­¶Új«­¶jµ¶Új«­¶Új«Vß[ÞãùÍ(úÿ³÷çÁ¶uÛ]öcε÷¹÷~íkôô¤÷B5H$°À¡@YCDc“˜TR‰Á�Â$&ŽC…$Ž!€ˆ�˜©¤0vª·’¢*aT¸LÅ1D „P÷ÞÓëÛ¯¹Í9{¯5çùcŒ1ç\kïsß÷Izz/É_�ïœ{ÎnV3»=Ý\Êþ°5þ™Ÿnv½€rÊ)Ò1qz¤åôkG¥bX·ƒl½þü&q×°a?ßNs€É”R!TS©¨P 3pß4¥`o³„›Õ¿»Ô–ß,nž¼zÿQ¸ú)Tº&§·ÍÝ*�æd�Ûèm "”<¾`sÓÔ�o©‚J¦®-µ6`,ìcÕ7–›-ªÛÍŠˆYß‹:&é Ôß+2žëê^ eÒRµ|d¬í[›õ¹Œzª¡] H B•*¦�,ËŒe)m£1§áÚll£ášåx/&vpËðZ×f#†°ƒI)AjBM…—•Õ@5^ó4!O¦œ‘rFWæwëy…)£Iz_b&”¹âsŸý,ÞõeïAÎ T�ñôÙS<~ó ð§^~é¼úê+xÇ;_ÅK/¾„t<”,—\�JuȦÕf·ªš¾“EàDsÑHÖÆbVÈ ­‚DäjãÁÖ+}_Ûy†U½¨«ûÛãó1.í}18 Ð 0°�à-øO­·÷A�ö°ñgâîÅ€=ÛÏPG E À{0:}hÅ¥]±vÕÉ2£ŠÐ,ŠMI.2†ënwÿ=F¡^£íúÔZÁ|°ø�ö m„»Û[<}úOž¼‰'Ož¢,3¶wï^kïPró:¼#r¶Õªàˆa‡‚5æ-°¹¶¤”¬0™“BRˆ0’Zü‹’vË{Z÷¦>BñÐezÛp¦·+jN6?~ü¤=»Aâlîb±®Ú]œ·¹è¸Ã u’˜€À4¶9z‹Ÿ5ºÊ¿Åˆ`í¾3’Ú|˜ÛW÷£9\y÷fÁ¥ý½Öc=oë0Kêzí¿m8£KØo�‹^¼&Fàú»}/Âe¤À=¦ v<öÙã~S½çޏÃH�’ùCo¼þF]æY¦)«ˆhž2nnŽÈ‰y{íµ×^{íµ×^{E퀽öÚk¯½öÚ«ÕçU�¼¥×¸ï?}I/"uEvÏz¦Pa3#¥Œé0ñ”ó�¿x–ù—SXLWAq¥[¢5OÈ%c:SJB§”‘sõ¼hW\R(;À”�ênåãX)lÜ®XW…ÔeÓcy r÷ ñ¾¥¹9u ZĹúk³nÛa‘›�€íç$œšs*“ƒBnmkêDñ×®Ƀ6%+§°éTÙ«XNº6Ç�äÂns<€È7Ô9,˜XNv­·€·uk耷vKÛP¦‹ƒîÑÆcÓ>2¿Ò¢.÷�{P ïVS·,àÔÀ: :àÄLH)C«1€(§ŒépÀaš0Mþ§l×Bª8.0¸áˆÃæ´¿v•Š×>÷Y¼üê+%�8Þ*8׊ežñ™Ï|o¼ñ>õéðÒK/á…^À �^Ä£Gqs<šš¸ ëëØìV(+ª;W'N=‘ü±l¾PAÍ ^RSpOdÖì�wõc‹`GÖÔ¥ë4|E_·¹6è �o73¡G`ø}DT,Å®35,ÝLß V¨Å#J³7%Ü 6êF)¨n4ŠãñXB1íÀ#ÃHjùð2p&À¸kÆüâíq˜:ÕΊS‚Šà|¾ÃÓ'Oq{ûO=` ¶Í}c¸xßN�6óŠö�,þÁþ¾r_ׄÝÞî«í+å¡^m"ã˜JâÅ‹‰ëÞvÔ…�5,¥ÝZ]´¹<ð (ª:ùJ;áêB(¹!ÎÄø×]o¸‘tTÇŠ�iã93õvöÿ݆ûq™•Á�YïÊàÕåèäM6öÕ²NbjM±‘-Ðeðæã7ý¥Ö}‘ÈÆf¹f0Up‹{QÅy>¯Ö«n,p12Œ>¿áêಠþs¼h'—4´<Ü+¢ýÆyºƒŽí=lÑÃ"æ„AdÎao¢z""çéÓ§¿ê'âÇ¿þ˾ü½Ÿ+¥–RHª¨Í! Ó”ýÞ�Ûw'ÜÝÝâ<ßàŸ¨Ë Yh)�RQ¸BJÁ\fÔ¥z,uW…dqDYp©j#Zì„Óc ~?�¼²™Oýô>0vajO*Ÿç5¹3¥–•½ÖÚ�¹p#7°÷½y^p>Ÿq:Ýá|>7`Ÿ6¹öµV,eÁT šŒÈ¥Óȃ)ÛŒ‘¸¦œq8Œ009§Å™ˆ®¬ô»¥þFé¯Ãhìc@#Ÿ)/Ö$îîAC ¼x ÒR”RÝ©‡�‹Ožv¼Ó4Ä•ôh …�ØZRe)þ/ ÍËÂ¥”LD‡»Ûg¿¯ÝçaÌŠ6¡W”ïÏ¥k�^ÒÑ='þF³ø<i#Y„.' ›)¸M4X�i}¬ãô¤£3ÆÈª>„ŒStgL¹“Ä•&Îod³èó.ØF�Ä®ÍmÇ?ÿü,>û=?x�Vs÷õ9öò±äm\U/ÏD~üæužOõÁÇr˜23Ž7pë×{íµ×^{íµ×^{Y퀽öÚk¯½öÚ«ÕÏà-¾ÓÏèØTu­J‹MEÏQŸ¦)åépÔrþV"z‘ˆ!00zY˜}®‚ÓŒiš�—Šãt@JìÀšÙ³gNМÀlï7µ-µÚ61m»Z] êßöJžáêdû.¢mãÚl§¥à hÏ/v p²�Æ”„Õ '1oÙ+’2�(À�°…6€¹½wB£Š±¸ZÑÕvÌŒiJ’Ûìš ÑaA-®< q3¥Õ†'„ ZAläRQ˜üç:É&£˜6ê`ËV¶ëoc(§Ðìû5uų«ÛFb³²÷¬^fä‚|€á¾$?b2§Ï¢U±ûÈ€ò :Ùr›ªm ’ƒyÊÈÓÁÀ®Èÿf˜ê¶½G>ºý½a3ìÖÓŠg�ãpsÄ”&äD�ÃÁž?Ï(¥`Y ž<~O¿�œ'ÜÜ<ÀÃ^ăãÑ"rÆáxÀñæÇà ŽÇއ )M°[—ÝR;ÈÖ6¢mºF–2 –L8LðÌÛ›ûÓšp¿Iýƒ€ø5ð?nzZ�#+‰Üª•øC¨gh\U˜5Þƒ3Po;âqN´�è�bàIu— Ê«×ëcœ+ÿëFµ?‡†ôÿŠÒ¯�áâÔÅ}î °28ìéIe•&(B]*ž_9¤90¹‹…¡¨PN«Ø›«»5zô�æ– ¾ $b D†;çÔQ#Š“˜]µÞçz¨¢”Â?ñãÿèwß<|ôÃUäFjM€&FIE 1DË2ãtºÃ|ºÅ|žÛ\SKA-–ý¾Ì3TÄâbÎw8/ ¤ÈpO‡ˆ—ap¥ô¾÷Ï€úy?f©^a¸]yª¾�óÖJW^î9†r:Ì�Ï«SÇcN|òô©ÌË,¥T}ôènn˜¦ PÎiÿ0¿×^{íµ×^{í5ÔNØk¯½öÚk¯½Z©~q¬‰žãÐŽm£�§•%¤) rÊ9ç›yyö�LÔ€ùR ŠoWµüÛ”3rZ°˜¦ƒÙ»«€É²^�lQð0ëú‘.´©¶Qì_ ¥#1 WêJ-u¡ω²åas4ìyi½QJ®˜�ß)xÖv¾M%ÞdL!‡2΀kŒ9ÇMõeÀrÏÜÉ89çVÓ�±kÚÕsŒ-O»o¤†òÔ=�ûª!.M=—˜@œ ˆÌ–¡£šu½ù«#X ŽêÚø=Tl­�dLª`¦)#³)õ’Ÿ€HÂp[_ÐåQ³µU·9%éÇH Ïûu…lM¦¾&FÎ ™Mià?15% YþÚ½‹¶EÀŠhõ6èmK 0q§ ràgÏž|çG>ò¡¯yéåW>ED7)¥ÛÄIT+D“ÍwEpžO˜OgœÏ',sqÅv²õɲà|ž‘cI K�qwºÅy¶(œºÔÍ¡6°ÐØîé~�ñz@G •×ìÈéž'øÓèúȺ~ýùÁ,çK™›íwJ "ÙîW0/ �?9Ý™úqb\<¾¹\ ŠãѨ –a÷�•ÄV2Â_{|�¦ Õ»6÷‹ "R­0п j©¨RPª¸C”N±.T»³NòX�irW¡ÃÁˆ}®ä‡Ån1Rà4ŸÏµÖZAÖ‡SΘ&sÁÐôóEdßk¯½öÚk¯½öúÿŽÚ {íµ×^{íµ×P_œ�“·o<0ª²9²‚3‰ôA•ú+DM‘n½E,Å3P`^�ó‚ZgL‡#9»²¹¸'p%ÄòÞÉÁµ.fa¯d–çꊭmÝÊš¹+N¸1[WAõ¯n#ì9Ó³[b�Ù§#6Ca7¬]1§™çðLor[Qm–ΙÇÉ2à�ØÀ®¼¤–©oD›Ë�R{6l€5ö~qNƒ¢ƒ•ðÊZž­.§äÑ üsœ?Å&¼Ù!�6¸Ü²±7@ðÊÁíÎ%®ÎÌ)As†Xܵà |·Í½ˆhp;ÎPbÓ¨iWuú}!˜ €‚‘Ý._5µ,nËNU`^#†8xdçjJòëD¾YýÚg>ƒÛ»;;s/81ž={ &ÂñÁC<¼yàÏcÔ²(* šÜÔhF‘eÁR<{úÌßC�¨(»KCN–?žsBΦCîmŠ¥ ¾ö•ÇÀûàª×�¢©±•ãZ ¡õ”Ü% 4<˜°UÿópƒìÞóð±&lÈ]Ñï.uP¯Œ'îf€dÏgU¬?�cg@2À¬@eh,H±sTËX†DäÀ€†õx¨þºX©Ù`ÃÍÚe´üçQžúç tæDžR ¤Œ,i =hcÖW—êÿ1Þ¤Ù쯲¤ý˜WvôDkìo«Ú÷gÝ@‹„5 21k€>ÀX jìÑaeˆI|l "Æöª ç³Á-/܆£¡QµÌ>øhÎ5ƒ=8®€A)g¼úÊ«˜ŽG‹¡‰#P³ÍW5R;ˆn–ç£E½19½Jkãu 0Žš‚\Ñó¨;©Ä•Æ¡—øà?¶.ˆƒmNíî.à æ hPsaÀ Bé“ûè?›§ÃÓ DÇÂÌ'#tp¿, Χ;œOg”ÅTþ¦0·ÇÌËçÓ­¹—0a© îf³ÁŸçÅÝ‘ÂùáÂö㋸6|^=,¯`žgH-u¾‚A(˜c=R¥˜ýÿùt2k¤äýÒc¤lxZ«Ó©Å±ŒdL�€X9'08�†ý>TýX*R*(2á@sÑܤ|}SœZª8@¢]eí�Ùçá)#O“«ÿ�\HÄP'G¨ª½~)XŠÙ÷«(8¹BÍW•æÖëæß‚Z+I­¬ªU<¨eþV¨~·¶¸™8Îø™úÏCÚ� ÷Åè•öw­]j#0\Î`}-Þâ8Â9„ü˜üz_{×qd‹{s[ŸÚÿÉç ^ct3‹ñøÊ¸OÏù ¤ºfDèpaÇc¹¸¢ª¶.×ûÌûïq¸úþ—DzÞXAW‰>ÿCÃ8üê;Þñ“D¤R«F¬Ç4M­ï^sÙk¯½öÚk¯½öúÿçÚ {íµ×^{íµ×½Faãs5üL Ì!"b&&¢#€›óùÙ/¯U^ªUPK�Hmv¿ °/­� W¬ D+´�§ì*t³ýç4Z�Û†Ú"pÜϲ`µÙíØ-tÃRai­]Ñ%Ú6CqÅÌÈ‘Ýab6Âö>vÞÄ<$6Ûÿe7ºý²= ŠšÍ·KÚþ"8çF ­^»rKzÞq¨ôݺ¶ç;ó@~Ðg!¬ Ô€üØ„%J²Û ³“Âv¹oÿV”Ål×ã½Y‚©½— a\oÛ„µãÈ)Aò„ƒ[õh¹¹A¢Zúfblèª)–˜‡¡+eèb)¡½veÌ�û¬ŠÚòy#[X U»j·© ]õॗ_Fš&”ùŒ¥Fïêw·Ïðäñ¨Š�œÀnELf9q´>ëuŸ3à«”jN5@m‡£©ƒ&qÍ‹T|êëÐÜÕ‰Ô-æðï7'1Ì•âàà8|Tq6Sã7=”ýý¹=¶ [†ôÅ `¼ X»^Ž- '#´ÞN4 `Be¦¥½Œ 8 ìêTt™½öCà·2ÎuWl^®VJB„Sì²4wî×ÀÆŸ5X½²×[UˆŠ•3 vÙ—zuS¿ F«ýa Ç:¿�Æ8}Nf±¿>¯}h @ÛÁñ~œÝª8Ž<ÄQÚlÈqi”ÅoO§H D¢NÖâPÿ7g“·ÇcÓ‹ …^Á¡F;þ~êãëàÞHKÌðÑòè×6ÿ4ÜÛø¯AWbôr^í. k²Èz\UÎçóçu£pÞýîw·90w&²Ðš¿“ËøË FrDO€±öÀèàÒèRb©²î™ªÝÔæ$ŸâlÎÖáy>6Åü6  ŠDl) CƒR(J)îZ@P•_ÿøõ×¾æ�_öî'Ì4çœ*@ETµŠ`Y Îççó R+R"W˜+T –医;F©3”€E æùŒy™±Ì ÊR,¾)Î[úýK°/…â ó2P$ÎÀ#%B ÊvNU°,3–y¶sž‹ ðõ ““ñ˜‡vç)+ÌPa‹� w$3E¥¹µþâmQ�`í¨.‚äï9ÖO‰ò•õ�*ê$€³;EXûG€qüíJ©“ ™WkP[£Iw§hTêñh¯aÑæR¸ƒ�ˆ:áÑÛKp`¦ZËÊ«@°C¨µÏp Y“ÈVÖÿº™ûVsÊÖùc;gõ.k5‘NÊ 2çø²ºç$ž”â6¯Þ·�§C¤†�FÉmºòÛY­?ût¼>(Uý<�Q·—os/×y#�áÞÃ[ü 7| sºÿiEÆŠXšûè«£&~ã}Í×½v{w'˲¨Š:¹çdË¢tÀÿïµ×^{íµ×^{­k'ìµ×^{íµ×^­Tõ‹øÞöýjL7Ö`‘9‚˜ˆˆ)Ñà¡Èòh>Ÿ~]-ÕlÿëbJ\˜Z}ÊÃæ©Øm-• •fÍŒ„Ô6E»jP©¨Å@Zuuº6…£çûæk– -78Èâ[]ì¼)±´±qk¯Œê ¾Z«[¯ˆ”‚Á l °){v«BÜb=¡È°3évø¡Fç¦.ïm@ÂbÚjùÀ)#QÀEÕ3ÇÍú8<^›ŠÔP×]s<Í�?Å�÷胥 ÄAÕ )Å€Wâ[Aj‚få:`¦É� A˜�2CÕÐS#"Xl‚FåziEë˜8œ ´mk³)èVÒLåp2 ˆò� ŽžyŽ�hÑr‡u`ÖíŸàD ?ÀヘŽÇŽõ›BÖU~"ww§–{üÌm�sÎ8�¸yð77fõŸxPËÓ ˜õ~bD�°$®®níªjŽûf`¤ ;À_Ê B Á±-ޱÉmÿ�@<ôÿÅ]Qñ�d×—ïË7з_Ò_�£}²;Ä0”: Ã;È_ü»´®£®¨¤WãÛ¥o1T"·Ýï�;°ÂÒÄiå/¾+›3­ÇØð_ëÜ/mé¯+éhà РôÖÐŽ|êO5[v¢ç„?o]V×HÀb¥æïêAÌi ·ÂÁ†1cüÚqè)mˆf®×¤ïvùÒ{-¡ƒÿD— Óˆ×\0 ìÓpžŒº�;íœã™íºD?&sÝhn2o�) 6|�jˆa®1ºÞÆö¶RÎÞk”Þ•þî²rq Qu½~æéî®w�è²8Ÿƒ«Çð¶ Ñ8 —‹q”ŒˆV+™ÛÇ@8P?'nü8^7Sê¤6ˆÚØýž‚Üf0þ.m”‰Û×ð0EËž�s%&�ÐôƯýsïþ²/ûpÎùœó´(èµÔ®Äq7îÈ"*XÊ …b.fw_UP¤˜ÓŒ“#Z_Qù¢®ßNÍ‹úaš0�û¯”˲`Yfs;pëÿÌ)e¤)#OL|Ùâ ìîÜ,+Ûöö7UÔª�„D€©ì™1ŸgÜoºâÛ×zýú£)Ù‰2:/Áœ%P¬}à,@xÈû !öEªöy;‘>2�”,Ž(eL‡ŽÇ#¦ÃÌ쎊eYV‘U°q–‰(§DÇÓ³Ó¯Õï‰þ ùU¦ÊÕþu­ïKܰt‰Cëßpï0Ž ÍÉÃ^ŸcŒÔÑEÇû¾tBÄ®W'ôbåä¢X¯›bŒ¢ql¬ûÛh}ARfºöœK€^ù §+ÅÛéÏú–@ÿ·Ê×VºþÜuØMDyéÚ±æJ¥Ä|ô BÌz>ŸµV#¦,ól.ÙÉ@{íµ×^{íµ×^{µÚWG{íµ×^{íµ×—T]S¡lÁ²P~3'bæD„Uy¡,õÅ:ÏÿX©K1U›z�¤ ¢lV±L= ÀAêZ  Û$O®LSï‹» lŽ'%³DOÙþ ¶¬jî±{HDH¼ÿÍu *®Òb lOÍöÝŽöz~”˜¢Œ„a°U¤=ŽÈßÓKLÝžálP±ÆôØÏ @Ë›ß7»7]yä-¢ [>§KìJz�€ž¥­˜h'T�¸¢6CQ‰�ÈlµÃnuÜKµ¬W4L7%Sõ‰°eUÃr›A\¹åÓ6 d³ÉKkiSÛhA+œí†hnDµïÐ ‰ƒÂè½e ±A‡Mj‚Úu„¦ir…?1D>²,˜ç¹oà»âͲ� ËR0«µ ŽëVò^ÅÆ¹´È‹ºÊ—‘¼¡F™ØÈ+ðØ ã mvë)™Å~šÌþù ê*=JÏQóH Àæ5⹡ÔÕòx8<(÷ ÐëÛâQ $þS{ì…«@-â1›ã�Ýþèƒ:¨¼=ÇÞÃ…Û)D ‚Ü»Ïkï %öðûQ‘7([ߌühÒKØœœ3Êþ°v?�Ÿ^ŒS×…ß×M‹ixÞ*ÄþʤÑðÛÌöÕa] ¢îÕ°¥CŽy'¡5°Fµ):G+~ÅxÌŒ‘øRÇ6ó²·Íb“¿àJÙñ@‡˜Us@'rÍ|íç…ô5B€–¬ßóÀÍñŽVÓ‰LÔ¤÷ê4RgäœÜž<!.1TŸýÜç�Òí[^ˆnoïp<úi“Y°‡Û3™%wXø£“1ðk÷ÝÖ��ì Ê+5S®`«¢ŒtPc¸öãøsÃb*Ò2Tª]�/UZ4PV,óüOwwÿÞK/¿|—R:ƒh&2ÆÚ4¨˜U{Îl×>à¯ÐZÀÆ(òó‘«äk‘1ŽáKTR[‹ – "Buûÿ2OžÒ¤�DŠwfFÊŒœÂ2ÿàÃXµ6@ݽˆ¼]5òJô)1b �¶î1L‹v"‡»LÙúްÌÇ>¢Gs?³Û÷S…HAPTdîóqôiQ_G5ç)iŽ#$Åù�q8�xó<@Îy %8©°–n³om&1Ó”4Ý”²ü°¢ÌšÂ¿‘2q-Bf½¾×‹ùZ7Þ(4„i!@W\JÖ£"òS'>I‹“ÒÁ`ÑŽÞIý¯EŸ gA4ÜÏÍ1øç€Os�F÷}ÂÕÜ4ÝüCqõÃT;vzׯîó®Åókg±"ÜKÎò4ýÔK/½$)%Í9c>ŸQjÁRˆ(òTq8÷Ò{íµ×^{íµ×^ãj¿{íµ×^{íµ×—j­•.ã¦:Ǧ5'¢ k)/Õ²üJ©õÕ¥”eq«OØfj"˜•� È«®Ò6€55 Fª)›ü�m*í ä˜òd¶© D*ÒlaÍzÖ6;`Ïœ®dw™¥" f1-lCÄ+'�”²m6û–�@AlСb£°w¥ÔÒÏí]=ÙcD¶ÊÎÁb_Lé&µBJDhS³o�*\ÛšwûŽø€PÊU(¹º_á6æ]AK TNl`.9¸D‰ `�˜Wi# ô{–S‚0™³<<Â�ÀA‹jïC —:@kàQä<3àß-ÆAºÚà� iréÇÝ^#4HêÖóAH±È‚@çBM=D!ZL‘ôœkÏA ²þÀ‰¼­°ƒþAê�ŽŽp‰ ˜«)—PB­¥e§¹Ã%§UUÀݬº%¿ ¼àŸ&€ ø'd¿. àÕ¯Àº¹v<€ÿC?Zøø_g �÷bTþ@ V¬Ü P�T eÜk<ˆò°ƒ®Û! �N Ž‡ï÷uôBÞÈÓ€0†˜ \QCn¬ì1D}�¹Æ«Ë%-ÎãíÖ\ ·Ywe½£p�›1mÿµÉÖ{È£’òZÌpg†X“Õ›~^ £%@;V·Q}ê8nЊ³ðù'»KÀ¦G-¡žÓ`àš’si¨�¶-Î…""Ía…†ÈQ�Vq­Í‡iÂt8hŸ²�# ©®‡\\2› ¤ÙP‹, ¢Y‡çˆ§»[sT¹Îö»z3noŸáp˜Uð:Îa»f¸æI ]òëàjW“è æ—úûbM®è÷dMVÙøXû FooNB«eà}LƒX58õŒÂf=|úSŸøg¾ü=ïù_±è3ÊéO8ÇžSÆñ0C¥Ø¼Ä‘ÏÍñ@›CcT0 ¶Hï¿|Þ^ \_Ôš‹;ó¸[‚H€nÈ*Üâ‹ü?LŽýeˆê•±ŒZ‚â_ùN®ŠËê$©æD¥RÁR±0£”¹ýŽ8wП¸ÇA¥d‘EN%&s3 B­‚²X«UÀÊ(l}³æ NFd´˜$·ð÷ 6â_>Œ[�ü™ÜÜqssƒ›78�ÈyB­¥©þƒÐ`k;§DÌœ•èøæ¯}—ŠüªÐíî8-fåêܰöÝ×+î+Çš˜Çâ~h¬ÂǨ’+Ít t™#š“ˆ‚Àbë†k­ZtPÒ“Â6±ýsÊ{08 0:Æ ÆqãrÎnÍ]B/V3tñYiøyœbWK†þÌ …èösǽŸÅîyÈÅ�}äÚÌ>¥®ž“ w<?ððÑ šsÂt˜ðìéSœîîpžg,˹wÃÙk¯½öÚk¯½öÚ+j'ìµ×^{íµ×^_²¥[é¶ñ‡È��1Að J}QêüݵšU|•Úò‚™aÀ,Jl@ðˆ¤ª[åØX�BÔm8m³µoГÕœ�rFÎ9€w¶ÌتÅò€}C:ÜÚÔû‰É7§yT VV¼= Þ­2ɳ�…AI{Î41˜�ä€UÌn‰)ÔÆcÜ© 2´µª;!TjWI+ëj€ê �¨©ðj�ÐXâä·­:&ÚÁ³P‹ µë$W¿ƒ=‡7ù¾mVÃm¬Íb߯˜MœíJ‘U*ƒ.€{ˆNC«¢’Ûâ¶ ÌÁ–º}§AŒÞÑ¡$U�›Òw�àòU:b¦aBmJ1&†¦Á U:˜%Ú©M´í”¨xö´€A赻녅Mëü‚x¾p'<�¿A¨VÒHÖÑnÿ]–µ–!ûó‚°E”ΧS³åßr[aI/•ëAê2ŽGÇ YBDV²~. %YÍ¿—Ñ Ã{PŸhy1Øv“„ÙÚb€˜‰�|¡pÂ�®+hCÞ€ÛgϾçé“Çÿþ+/§×RâÔ(gÜ�‡±8I£–âÑG­M Kñ±Ïçl»‚˜� ˜V -z‘¹ñÅ-âUE)Åíþ+ʼ §ls<¬ï“G#U›Ÿ2cš8ops4Ò¦‘\d5ǯ²Ë¯M#Ò&N¬ÁM›SHÍ¥B†˜• ’ ˜ªQÉØâ rž ªÉCŒœcmTw„Šhä‹E Ʋ,H95×2+o;Š”Óaaš&”z@YŒt™sÆ40MÓ„Ãáˆ_ƒíêŽV1ŽD?ÒÍ2`KJ BEÔîáLés?DÝ÷‡�ãµG<§ï]‹X¸J¸vûížo¾ål\e^xñÅŸzps”<±AÍÖ¡óRP«Å\퀽öÚk¯½öÚk¯u퀽öÚk¯½öÚ«Õ—ZökÛ4�MqˇJ*zPÕ‡"ò¢Šþêv§ÒÉ"bj~“¡öØl"õ<ñ–Ôî ¾4e‰ÃWÌüÏÙÔeCî®TËÙ•ª¾Wÿh°cÓÝþŽ,�ê{b#-pË1sÔGu”)ò]ç>CîàçÆ‰\�Iƒu­6ð?®aCÜîœI›%¿Hqkx}®à§ÙCð8]¤ Ô!@ªG2�Ûó£G%$†J†´Ø«RÊmã›»S|ãÝ@ŽêîêDÚòêÙóîYØIF‚ºSw;úQÌÅkY/9p�D+ÂFÿ;$F ‘®^nʯÑzŸ-#=JH�Ä¢£l¾µ•ÎY0ëx…�yÞxòæzàvän:0D Ï„�óhýOò2YŒ˜}ú�[¶�ã®×1Ž1ìÃãÚIă0bsÒŽ‘+ÐÆqÅ«úýcæFÀè®*Ö˜bέ¥“àÏ �ZÃÁk `\ÄE¬0&ÅÓ§Oûuh÷g3t8Ÿg< euƒÑ»n;¨&ä¢]šJ¬@¹‘¿†ªk¯‘~£‘ŠÀ-fª6O¹BYTAZ}Îa[s`Å`/ê®06W d›so~úCúí�¾áÑ(Ñ�ÒMšRªy:‚8A¡(¥bYÎn‰=:–¸-ý²@ĔݑW}ƒ�èJùqmÒ"¾„*¥ Å�(–eÆìãj�§éÐÖgz§œj„¸4áp´˜ »»‹�/â¤F'øØ=HWüSÆÙ^W´f#ÚØÉžÝ�¡¶6ǰqé0M6%%Fnî ŠÂ'ÀÜI\oPRA©3–%ˆ�îîqB"€�1Môh± TKiD§ÖëÂ="ñª-8Ñ…8qN)MÓ”ŽŸúÄÇÿIù¦‘Ã6Nk#+oË%‹ñ»ƒÚCŒèãÜÒu ¤¹ “µÇ;ñkÔ£¯óuˆÏRèàžs�e>†`ÅŠ°Ðœ&¶ÑOèca�×êªû Ð`$ш®m£HVÎzÅJçÒÂMøžó¦çþõòѽÎçµÃ�#Éãóp‹Þ÷þ_ðcÌILJ°¨«²,sµÌ3¤ÔýÃü^{íµ×^{íµ×P;`¯½öÚk¯½öjõÅÜà½ôB‰Eͺ¹‰“ª x©ß*¢ïÔœkS?ÆF+ ]*W ·Y7ZI@kuõVÃ-‘8!§d9²ž»8ø_ J-ìV¡×ƒ•,Vüb xSß cF‚5> (i1Ü 1ð�F¥=¹óA2ðƒx}ê͘Tš%€ZpÕ½Ù¬HM=[¯\GßÝRMì` ‡:/³+£ 5Ew|äç@Éd»ž¯k pXúæîiPçwr„mè÷k™˜�27‚’‚ÈηÂÀ/Â`Éê¹ÍÔTèƒ$rÓgFuõÚÚAªvEÀp (¹Cƒ3ªBh°iõ|á°×î�- Û ´Û¬#¬ÀyØî}d•a EÃØ< ’+í.îuX³«ò°a÷àуn•O”Í ©ûÅ"‚ Â+F#±@ŠÅt ¿ P1`¾ �+€bmDÍ%b °²��¶+½é2;šÝÉ8 EÕPtÆ{˜³AS²£çâ$W\:Ô}^GIÖ‡«Š6êïç@‚½ßø‰nxp€ª£ Ÿ�)'LSîduà#ñ¸ÒTñÒÁ »:>¦ð *0UÖ™â£rPZ&[àà¨Aý«ÛÛ¨ïA÷(M±²ÿ×Þ︓ (€oozñ2Ä”ø�) ¤]�wº�3…P_áÝÈo®ÁZQ®Mé]usÞC/í-†ðOÕI^T·Žc‰Œ Úm 7y\Š")�’} =®@‹¢`¢Õù¤ˆD?12B#‰\™ÛEÓãîîίëV9½ý¹_um>Ÿp8œ7  ”D(×A㱺ýK›Ñ •ñÞJ�Ù¬ÜC�Ü[«)}®6d@+˜|ìtÀßI1Ðn5^IÁ¬Þ‡ºÇHñaá`ñ¹ºÍý˜9ïN;)uB£�詹Q4¢ÂsîÖÏûz5[tÏRÌgE‘€"{’©Þ�8L2Y4S‹ª ¸ ˆ_‡jwI|³ñoŒˆêkŠÎ•ò¶°éûÉ ›Bä1CF<&wQ[Së‡LÊÉ �jk¶qVkiêð1¢G}E(¥ ¤„œŒØ1å~ÜN$ÙÈD9{ÜAYpww‹ÛÛ;o'@)ó²à0Ï+÷ f#¸ªd�RâCÊ|SKyù|:ý#ÕÐ* EI}=Óë |!eïccÿÚ<†Ö~2k5¹¯�‡¦˜ûÛ:Ù£Nµ�µ�Ø0¶h]�ó÷Éã£o‘χ$¶N¼È¶ß¨üWHFã)ês®=g\Á­Žt|74ã}¹XN\{^¿1ë÷ú<Ÿ xË:£3„®H¬÷>tüŒøøÛ~åw|B�Ê”p˜€zsƒ‡ËŒù|ƒó<ã|:ã¼Ìû‡ù½öÚk¯½öÚk/l¶‹öÚk¯½öÚk¯½¾Øµ²|¾Èº\g¤_I7ªòH!¿N/¬Dáö«2XU¯ÁP,¬có�™Án»)ù²NpUVbFN–%oŠhu§€Šª¥š €)™DNžEK„DkulSªt…ì}”ÜÒTÓX ¶ËäÛ‹`iÊ2#)¤œm3œlCœÀ+{ÿžK�¡ÙÔ«ÙÔJì·²Ûœ·‰™º¨™£­MûÕî®hÍ©«¡«ßé #|êÀ 3’*(w š)Tµpb€[㺚R]Vk¿že@Dæ‚êžÿJ*¦Ü-ÀC½KëÍVñx ÐÆV;®‹ê…úЉÛ9ÖFfQ;·°È'¬¥ ðTl¥Æ†³YëG¿©®Z)¾éŸÚæ»¶ó¶s•Am¤4§ �ìp¿–Hèñ5€X;©kvµ4ö¨ âþ»ízsI^õg [îÏh'¬vƒ«}it±MtΞϋ�p_�öÿƒêŸa.íãc%¸ô¿ < àRÚÿ=¨ò¥ßC°®¯GC±öü•Ái>”‚Œ�ÛÂþ_c;mì”›3Q;4ŒÌäöúW tx®X-*`0ñ×±� @}SP¢YÏ3Qwáj\¸ÜÎS]Q‹ñ5}œ×Áå$TÚ1ø÷ñÆÆ«æÄõ§®ú4'©1àq«ó¯ûðóèª2¶~#ü¤~%kØìwûé^ày�Åá´±#È<[¥e»ÝîÌÀds‹™a´:™Hd¦6ï‘ÏAA•nûÒ@ÉQQO ²I€b>/(µ¬®Ëè˜Ð~1ÆMhDßÀìÈÛ‰÷6í�”z4{¸( Ù¿ äwm€nlþÕUߺZ‚è8Ù©@›³….|=�f�‘ ˆ!1«¸cú\äöÕ4·è`åt¤Í2žPk}ø¡èû¾áÑ7~0OõáAk03Ò”Áš|mÁ¨©X¼€G=@Nu ¡fÏÉÖ 9eä|ð؉î oÅÿ繈µ,çs^ ³@« ,u*�:�A˜’YÜs²QÉîqm?‹T)(uA­ÕïY8ˆG{ß ·‘ Ñå"ƯhÏ”ÀªÐˆó BNÏ$µ ,‹»5…ˆøš��dãý�B€Tq?kcs3UTØú§_)Ö‘ZmýÄ„ÃÁìýSN(‹Ù–¥ ûš}ÌÌî8©N"™�˜ùÈD?þÉOüwTõ+Çþ¡ã ¿"×^Ž{[øyµ†Ø¶µ˜3âšoâ2E†ñÇÈtmìd·ùÚÆòFnò9(æ±v75D~Œ¢QCDAcsg }®Ûœs�HWŽ<ãç¡ËŒ^ÿy°×YðÖL.ȼïõ|tŒ"(ô­wàþ9FõÊšbÝnRÊ?VEJb(1)§ŒãAPnnpóà··· ¢æ^³×^{íµ×^{íµ—ÕNØk¯½öÚk¯½¾„J7Fªì§°æ3ŽU“B*ú"ß¾Rë©o“ì ‡b(¬Â©oø�Ð](!nÕ\ä.1¹�´oKØ'7åm9숬z�1 ÿw'HSx‡ 1»�{S0‰4ð}µ­×²œ J)(žek ¸<¸aWß»•«*¤TÈ`KjÇ€v½E×6£"§­åŸ£[DXôÇE#ò«åc̲,8LGl‚#ìÚù¸ÜH€~Mx¸'ê÷W¥Ç[ŒNÍ�…úuî2ÝÍš„Ì…¡³áê£ 9y®]“J0ã�­X‰›»âº;‘GQØýäÙ³gÿäííí_<ÜÜ<.¥Îe)r8ÔJÈÊd`íäÎ u!ÔZZ4^„ÍÅ ”Ø�ÿŒœ'ûžzž<°v&/û[þ~�ªÖŠ”ÇhEN6ßÅw4g´5 ñãa„ÍyY°Ì J1ý¨ê6‚¢Å…—<‡^£ß­ŽŠqpeÖ™ZQ–§!ï} ‰‰3ˆÐÖ–A¡a,êQMêÌNTÔZ;ÙÆ�"¥dë ÄHjŽq U*tŽÇ™Dεi˜ÀL¬ª 7Oß|ó}ËùüÏ_Ý«~²™+F'U ‹ÀûÛ�_˜H ±¥…÷Úß]¯ÈmUßþá˜Â`È* àÂ+@{\È8=̉«!h›ì³é«cÔNT>šëG›t5·®\pÝþ?”ÿ„ÎÕ{^é±n ?ËêîÚG<\åzÝsïu âå)ÿx"–œXÒ”5ܪ¦eA>LHî\¢øÒŠ*Ùk¯½öÚk¯½öúb×NØk¯½öÚk¯½zý\)ºôgöÞ4„­·v"0\9Ü6¤)ö To€ò ¢úNñLæ8„8ûfÍ>•ºbØŸ+Í¡uévîk÷ˆèQ£Mt8Ý“�c«WüŠ �h*C’ƒ—MUìS”a ö‹€\Øò÷ dñ AumnFc2¨ç–0?Ž pðt$×4¥>œ¼ÐU³=R Ç!ôW¹2Àq¿‘|ßù††2¾L»a!…±qK&¸¨¼=>ºÞÕÙù°ôcôciIÑ�|0º* Eq Ì`¨E™°�;‘e¨“›°v!LmÜQÍ%B‡{g¼ò–Nز,lãÉ(i«V“¸@„Àl„1vÐÛ‘ô"ž\Ñ/^wJ›t`>Ï bwù 8m·á^«ôu¼Oè®*óyÆ4œå<¡pÐhyÒaÕÎþ6ÔÆzb#¢A¨[§qh#m¹¢Ÿz»Z)ܦ½»Åy±�÷~Sl¼U$ƒ/[‹i`õµÓ!£6§±Dä¥�|äÿ녗^ùsçó<ƒSQ¢óTK;F�ÖŸ‹—‚Ùn…:È›™1ìÿSNi”V¹ðÍþ>élÙøvëîöª‚œxð€ps”æ$•Rjk§eY P#P̱¥X|@䇗²@¥vp×ïµÍ×h÷‘8­ïÙÐ]”ôê¸`ó®€È”÷¥”>Ö‘µUvr¨fu"@jäɈs²(E-NøœF†HÅRÌ9 TFvb‡›‘è x®UP!«¨�ãñ`¯U%&°¤ŠIDn^ýµ?,ª/lÇìõ‚z¤Fmrëõ’£׀ãÆÄ!wùFÀèï÷}ž NªˆyF‰Ádk<Þc\sG—Ó ¡n;6¾%küñüÛðØýz�ò½¯­ôâ3•^]/¬çÏ-L;Û�¹s$°¥%~¾t×8C2ÃÕ«2*û;â>:@,ì€ãñæÇr>Ôép�œ³†CÆ9ed6Â;qi¯½öÚk¯½öÚk¯^;`¯½öÚk¯½öú¹/úÙ?©Y«ºJ­mŒÛ¦=+i-�†þÚê è¦Òn¯Ä2ŒçDY˜ê) •š{€ˆn”˜hŠ{b†–¥)õã}™šrS>Qäú¦PýwðߪººÿòrèhÄF0ÆXiE­Å²pÏ3æåŒå¼Ø«&&NXfñ‹¬ƒE²öÍ7àŽæ Pqð¢á¦ncÖÇ®°Lˆ ¤!bï’ ðhç"ˆmæÖZ¡µ>ô¦‚··ÀÕ–‹Ì ¥3})¥)àá øf)=ŠÌ|“„«¹1€©!±y*‘¡[ˆªeñjwg€Tbƒ2a Þ¨ 7À^† xr _!,à”�XQG¢D¼‚úµkáâÎ¥zûwuœ)©Ó�Õ.m?¹º]ºxŸˆ{çŽÒËÈ ‚ ƒ\Þ` ÒNõ@;XOµ‘  Å¾Èœ $1PÉúÄöÅl`¶ûÕÁ{^]ã~]Ç~ϘÏg”R[½=&7ÐÌœ‰âØ©©ÍÛ8/c={†iÊHiÂÃÃCpJ¡!Cbƒ`>ÀOLîúcs•”Š¥.X–µI¢:�|¼S¡ÕÚÅ\?ôÞü…Ú$ÆQ±ÍÕê`¬ÏÁ¡°÷quʶ=gj}wÍçXwí.‰“¹6Läœ-Úæò¤è¢X˜�4Pµ‘‹æÅ#DVߣo—RÌ¡H*D4©ê$¢7OÞ|íW,ËòÛ¡÷´†qI#x›ZupèLA"e‚ 7ÂØÕ^ <Ì :¶Q¢¡Ò:^'ŽNÐ5ñ ϱ”úD[BV2}nêý%\Âäû:x„¥R{ðU }´ ¸òYªëjX¥ÀÒç|oïª÷¸\;⟃á€èyoeGõò+¯ü£”Yòá ‡œÕ]jk]'7N9aš¦ý3ø^{íµ×^{íµ×P;`¯½öÚk¯½öúù¯íFÏÊ[W.Ùͪx�•xÎ{R•£ª<˜2{-¥:�î¯ÃàæÞdùbx¿Ø˜Eeki�i`’ƒK1®€«¨«Œvζ՘dÑÔÁ1ø{+©ëó’oÄ™ m„‰›%²"¢¤)Γ«öºy¬§ ªÔj–ú@ P8á<ÍH§À$ˆ’�ïŠÌa0ÙµMD`©KSWYKµ Ô°¤å4ä›»JN<3D®œ+¨˜�àù©6ªT�JÐuîsÄ´¬n5 ™S϶övPJ�”Š*Å—®œC—#mÅ¢(U@TQ ƒì±ävÕc3õ�f^xh4º²» ÛþñŽŒ¸R?/éÏ�ÇR¨c@YÀ"¨œz¦÷�iÞl„Å3€kE­b×ÀÉ/PE%¶ë¹°Jâ@(›- lläw(Ð!Ý;k¨™Õ³o;9"îãÍѯ‡(ˆ«¿°+ñµHÎFhØÔꤦöÙïE.|'…ù¹©¾/Pð‹\o˜ñ\Ùþm;&m",;� ¤ oÐVuñ§8  †+ÁàL0X†7 z•Žè2º²1.  ²$6¥gØ'Y´´»>¯6nÆÖ•¢ì$€Ö+&EÚ¢K¤‘mÆìxÆ`ÔbÍ̹…0ªß Õ]4Œ(µ!�¬\âra;nÇÎ;ei˜Ì„‰�’9d°“}d9t°‡ Í€.ZSXÄ7œ¬f{ßTÙž!^KAÀ¼UÕ•»17È@jHÉ’4ÂR˜:(­�T¤veoÄpà¥n!¢ÕºŒ©~«�‡lct‹­a¬JF’„½qSPö¨�»£ !ÅØ4Õ,eË`emcÄyž;ð/ÙÐæÜFÖħÀZm\2`³,9g›—¨-œ \·!$uûq�´]§~ c¶=6yöºÝgu‘q6ÜÖ%­o„²Ue¥ÃItáríVS·÷ïÛ1s20"Q¬Eªè«üÐO}ß/üE_÷¤ÜݪÔ;N|¾9ñàÑCF¢:Ïww'ÌóŒZ+˜ŽÇ#¦Ã‡ij€±µ­N6¼ê¾¡ø’#ܸyH8¦#nnX« #Å•¥ ”Åœv‚Hèî+":¸çX”ŽâJd˪�Dœ|,â9üÒtŽ®¢”4BI8àn¦6»•5+LcÖ�Øãk�œÓÇã‡éÐ\”̹ 6âc-µ�Ìl×¥VMmd ^•R‘sXD§Zå(µ<<ÝÞþ1UÝfXÜ»Ö߆+éµ)Øç Rw,Qîc܆ˆBN ¢-ø¿Zt·Ž>¡æÊ166•n¢S°íq©Ú×½ WQìÑæ3é­ÎëzŒÁõ¿«¾•>8¬‡F‡ÚÜZƒøz-Jèž�n?ãÏôüãmkÒ>$–oüæoù­‰Xó”•(•ÁœÚº4çŒÃá¸ÆÞk¯½öÚk¯½öj'ìµ×^{íµ×^½ôçã-¶Y×ñ‡a“0@|ŠÍ³Õ^#)”TêAEŽ)ñ×¥w/Ëb*pø=¡)þxÈRW¹GKó¶Gš…dUúߺGZ&¬Õáf¤œ�RrûYnYðªÅ7{NŠip°Fªg¬Ý Ö߫ІnqÍ)uëù1¿ž)T&S&mʲ`Ng¨ J9 §Ü,e�ž§íÚL»G PU·¡îÉfy®l5«¨@ªËŠžS(ÈÿûÖ{¾yZ�¨DÑÂ5˜Ämƒ[«�ÿu°¸U «Xø¥:ÀÔÀ7m¢s%0¸u·–)n˜«: ƒPÁ†Åö°9KƒÚ:ç¶1L¦ãJD¸¨\É€»PP×êŠ] åÔÚs¿L¶Öžýן:óÀÀ\ZÅIX3aˆT7=°{ .�±²×˜:Ž}¶¸qêyØ"Љãù27·IÈÎÃÏ›¶À¡õ¸Ø-nÿäÍ/ýžoeöíl¶»Î£oþ6Ö …ˆƒ”¡”èwu?ªGÐ~襅¿¿‡Å˜Ì% .° „„M¶¯n¬ic#Ürü�¤]q>^öÕ†¿ýÛÜ/¸?(UT·ë�|k&‚ÿªA¬Úò­GXGWEÄKD6=ˆÀ¨làq%4б�Œ1W´ko k€’ç_‹zF}ª¹{V¶»$·tW%‡jEÕÑqCWvÝáÆÒt¢Ã­±HSÝ€&' ‰´ö[ޤ 0CR2‰ƒã+[pQh2[÷;±ÉXU$ѦÆÑÝ¡°2*Ø€¼*XjmÎL>V»²MrŠ\wïDæÓ@j #¤�Í Ä r2y4 ¤ ê1 Ôi/P˲²f¶ø›³Ø# úø¨C{»T˜.Ëbn6AñwÛ#)y¤Œ]3"]Š*}îäÆ8t—„°AY‘Üu¥¥ŠS�R IF`¶‘N€Nè£îlÄA ŒQÆçvý0ùœ#~-Õýt„O^ý·.óù¯,eyc9Ïo0)Ê|„ÔåÁ À²˜À²¨*r¶±;”²9O H'ƒ…|´±‹(“/�:ÝÝAÔ\sŽÇ%L€K.˜#=Ô"ös©ÍÍ$Æ¥Ö‹¸ó†·¤�”8FSEôH�¨Æ¨ÑÞ¦D×c"Ñ帬›ÇÄÚ%Tí:ôâõºò:p8q8q8Úº³øšØ‚�l`í Û½.¥¯SWî!N�(™SNÀQ¥>xãõÏýž*ò�[ë}Ô÷×ÀÝ¿n»ª£?š+†¹æ„ûEœô8ljfET¦Iºz ºŠ€±—]åƒ]áÒ‘;vPî/ˆ1[€�.q´qL¸j}ßÈ?õÖ�V1º!3¯ûÃ?¶ «¸Ò¶d¤ŸÁÇ@½¶,Ãç#(¬c.–pC;‰(Nü½pWÊR*D¤‰É\L¼2'Ly‚{íµ×^{íµ×^{õÚ {íµ×^{íµW+©?_›½÷d>@;‚šƒå³[ד@¦ZåA-åᣇ¾kYó²Øf0'·ÚO d…jL™®—Nß^ƒÔõˆÊëқěñ¤ÜìXÉí�Õ­ZM¥=›ýneˆdäÉâjT·G’$AÇ%³á·!Fs>ÕžmØ21r¶ld9H϶ö÷?�N®ð*ÈÓS6"€R *p%¡o¸Ž~Ùk öõ涪K»—êbn¨YhSËWíÙô=[Wñ2*ŸZ.¹Ãhns­áÓ0l“oЋrl§+™òtÈÇø×á‹�€‘ØÞÁ”ï|‘�¬+{[ÚüÞráÕ ‰7b9…k v]õaëc 9u…rubV­ÆPW”SžÀìc/–b×NEPª@¤ Tï‡ TåF0À@Thãf·è—ÕÇv „ ÀYWûº{‰;İÉ@8"FúFL`eëKämR""ÄÆYò9'ú²T�„“Ù8ÁB¨!`Ïíª_õÀR¡œWͦʠ°À;‰ Ã<)"H TR"O‡ñ޼�ð8��jŽ:œ*Éìñ½FD.rïµõZ­œ!„êŽ'1ž‰xÌÏF­MÃÖN5Õ·DdC#0�o?Ì#ÊmŽ\9Äø.ã\×þÒÍ<‚À=°"ú›nuÂ`Üor—… Ñ‘ÿM<¿žT©ïü؇?ô›ßýž÷þ[R–cUa‚Jòõ 1Yû¯Åç �!råº]³ô‹˜|q«x½D5¿¤ê<ŸQµ"'Æáx㛀ŽH)�ÙbŒRNÀÙ€î¥ÌN±±bEHÑÍ*ppÁ‰ßEì§ä_ã<$�Ôb8ðŸ‚4Àö:J U^=®�ó2½Çbn$¦$Å4M8Nsv˜&¨ªÅ8à/"Þg:igüÛè(ÒI…v0:iRÕ#œNw_¹ÌóêÑJrÃ4¿žê¾]p�_0¢¤r1ŒDÕ"[073çx#ƒTpñ¶ÃÚQ†µ‘õ±õÚ“¼kÓ86]ùÀ ãp�(³:ãtó™g ·Çjøæzðֺ㵘£‘:QO}Œ¤ËõÓûÿ Ý8ÐÛHÓÏ÷øõ»1Ñ?¼»½­w§s}¡±k’z„Œ»¥)ãø3Ë Ûk¯½öÚk¯½öúÿÙÚ {íµ×^{íµW«ØÜÖµ�¼ŸÙ˘ zM&ä›òŠà!Ë�¨dQ¹)¥¼P—òÂÛãwÎË‚y^ ¦‰‘’YÓsÊvìÕìì›­ª«neØÜítlŒ÷U¥µKý`›<:µ&Û1ôMbv#pÛ|]æK© ‡ •ƒå=W³ 5 $Hª- »†²TÒ¬Ö„"k[šåÿñ0�ŽD6¦HÁRË2£”궸G Ä ‰†L{xÞ³šÐtí”+Ù}£›‰ \Q�€WÚ;Ç¢öLf…@(!A€0¸<Œ¦kU63µc �ߪá£��€Ì=Ÿ™E!ÊÈÔ sPðêΰ󯱙+±QLÍâ—ˆ›³'ê縌–ˆû¢þÞÌ£…¾6‹i»ÞŽH‚J¦/w…±:8Mƒ±ÅxH¡®öuëöZ+´ ªJS6‡EjJaŠ*Ê"˜'t"FH=ë½Ü¡’� X~­îbÀ„ÄÕ� ô)É ÉvП³}Ñ €    öÜ4Ùs‰<"` Ý3*€l_ÙÛñâ ÷H$�Íø„öLj˜ú_û¢eå@`0„§¾ëh½kÖ÷ëïhÓ² ÞU²#®ñ±˜¼Kê•�¹„H㥵ñ'J­¨RÁbñ:#}‰‰¡y=nä”PŽk¾É¯‚�´ˆ¿7(— àÚÜ4š+K³·î€›*Gh‚µEŸ7j…Übq Émí3(çî˜/b6àK©œº[ 0I©›)èÚU¥“ÁºfQTV Ïíê…@Ĉ/ÄTÃ1� ®°'¡v5y¼^#VØ/«(Õ�ÄÆYæ!!>žˆçyCÝùDUT5ÆÛ•½¶_ó˜ëœx*\(­ÁA#Óï“YÁô¹�L½­ÄµXJ±|vQ¨.z«FP½›–ôH„ö!€ªdöä)áÁÃGxïW|Þû•ïÃ×|Í/ÂW½ïýxÏ—Þóž÷à�ïx/½ü2Ó/¼ð¨eC/Ë‚'OžbYf|öµ×ðúç^Ã'>ñI|ⓟÆÇ?þ |üãÃÇ?þ1|ò“dzÛgƒSZ›ÚÒ�:˜Ø‚XAäã%1jò T2‚Z´ws’`�@ æ„C@¸½ö“7ßø­_þÞ¯øSâµè„ªç²”ö:A #�¥È)xÒbcj­(¥b)e)¨¥ÇgzTHµª—óï½uO‹pMü¶×«"‚[ºEÊg�nn€™�ó„)/Hκ±È ÀÜRRâF ²q@D Tîá•<ö(s6§''��*£í¾8™V‡¹Ô¬úsž�Rò{bq'ÌçdŠþ”3RÊ>Ž¡©÷E Ä‘9ȇ Óá`.þ=”å¦à/X˜!D�Z±,æÄ‘} û¢Ñ2?Þ³00Ó£Û'�ÿ¨ª¾|?ù¬÷ýˆì¢AJ¯Ôía ±!4aº ±NžÙªîGâ�b£†Wµ1D‚¸+�@æ¯1šƒúœIã9P³ÚqŒ<½hÚ÷~vŠÈ«Ë 2ÅÊaE’¦´Ý€mLÀó­ûãó׿QcöÛý{(WûwÌUo‹€+®LÛ+ç„—”øÙÓgåööY½½}X§)+;©Î83 )e�4Iû‡ù½öÚk¯½öÚk¯¡vÀ^{íµ×^{íÕª,ËÏËû.A;u Yü'ñ=n7&IE³Š<�Z^<ß•¯¨µ J,e¾áÞÖ¿®Ö61¯�ÿ£«wDȘçk»^¶�—<[›™P«�C•‚ó2£–žoM`°„JÕ6²‰J¥½CXÝ7 Mr›Þ–GêçCÈm}§t0ûß² �Ï€ZO(R g qE™*ijV‹ë q¾£�¸}ˆZn8'‚¬´ókýlϺ/¨pKû~K«áP·àÀk°mØm %1�„M®?-ˆ{À&)’¡àH”À™Ûûµ*´æYšµeT§¦úKlÊ¿NZ ¾+ëŽ Årr…¨¸5¹v»Ù†„¹¢�ùµÆF¬+ß(,¬Ñú Á2ÏÍUÀÀÀøZ T+JíïeÃåéàÊY¡@‘ ¨íúsb·J¶k™U¯ž]E|r0ù…G¦‚�Ȱý ?ÏâOH`Ld€@:8˜ìg 'ò�.Ö«ÂESÖûïiüÓð=F5¢Aí`„@À4_p.Z™í zlAÇYÅ |žÒ� I…ûH‹»‹[@φLc‹[p`HŠ¯ÝØ`©¥ÌS“ÒR¥–¦fB±Î+Òlâá1)�C¥�¹L aSûË ×,–æX±RL‹¬ˆ&á:Ùõ$¥«8#&FL’“Ũ$n£Žõ…êćpÜÕ¥9A [ôá6n óUDÐæö9©‡+y4JŒ A5[üahuZ”Ý£â*~^+Ñ;ˆ>Uˆ¸Í¸ÜÓœô"š!+­Õ¯e³ÍvP,ìN’°]ŒQ%v�Lí¯ÝþZ­íÐõANZ Â9ØTkõ1 "BÓF\«*í½¶ØÐÍüïý¿_ÿõ¿¿æ;¿ßýë¾ök¿æm¯?¦iÂ;Þñ*J)xñ¥—ð_þåøš¯ùZœÏ'Ü�N¸}v‹ÓéŒÓéýØ'ð�~úéáƒü>ñÑ�â<ÏÍ bµ"Úf¾‚�6Úý‡ÃÆè®3.7š§Š÷ßíý6œÒÞ¯H}Ï'?þ±ï}ï{¿âß®T´¨j­UZFº®®³Íµ¥ÈmÀÿŒy.(%a`nÄÈ9iŒùB‰üֲȟ»ü™?•KY€;°l2âäñh9àœ t?&Ô2£Ö GŠÇ �»Q·”×ÁÕ(:q[×1(¹ƒ€º³Ð*§“éŒx—�§ ‡éˆœ��R²te~Î ‡Ã„Ô1ådKU#g,‹Å88ã”ÝÁeJy2âs†¹õk·k-˜‚C�jµóX�ÿÌȱ=H"Ϊ8ªâá³7ßø¯ÔZËŠÀ¡¸TÚ�ëoÂÆê�:;Í�wjñQ>þ†l,]E \óÂAj3불¯8žÝqfŒ„ÑõÈåó¨ß?¬cIFâ’^iÿo2oÏÓ+nks4ÖYƒ!]Úÿ_t¦F¤^›<ªa Ô7BÃ}To]}ºz®ÛÌ´·\CLÁÆcŒuÉSþûOž>-�Þ|³ÞÜÜè4emÄ(U#ØLiI}�½×^{íµ×^{íµ—­¥öK°×^{íµ×^{EÝpMWò–·X.¥&ƒ™î`sÙ&]5�p0óöÀ`"ˆè½øàxüžÈ]íVÁãAH%®ÚWf�cžoÚÚ‘æjÏSOЍAæ)T¨±™,ݶU=ÛYª©ü¹TÔdyÑZµYü[ÞuSÕjôAƒÄFºu~¨›•tN– kÄɳ°KªmÑܰMU¶¶qZkÛÒk¡ý÷¦x p¬¶ÝÒAqägÇFîø:öNaǬ`ŸBýn[œmšIÃ_âÎŒÁ†VR¤)ûA»�oæh4Å®*à® ¦>sõ£[Ùç);øŸü�Šu' ííÉ®:8àD‹€ßH¦Œ¯`êi#°T€TL@ï"'sçðÍëè‘‘}ž�œ``AA­ÞæÕ”œìm:¥îŽ�<Î@ÈÞ0j¥vèábùèc6±´ ]'=¸åq)‹ÇLT¼þxrõ4¨ˆ3`÷ÌABü÷Ì®ì× â €}\ËZ‰?–•~G×VýÓ•5úF '#T³SPËNÍÞ=†˜äºX�ý9e3Àµ Š‹çÛæ{E' llüÍ3ƒoøõ–Çq) ÙÅÚ?=�ô ÔRÍq„Í"^ü¾V·Œï@㦯¶È ¿ßÛñ`5‡jSÍi€:x@´V|¯'“5°ÒÆ·û+'ŒpK¨D`”RMQëJÜÑÃ{¬€"êÚD޹!Æ$3®ˆ¾0Œ`Á¿pp[Âåa$-na�·:šOÊ�À¡h€¡ê�öÆ—1†…šÝþVÕ–.F@¥þ–2ØøqVò>’œpAî“UBñßoßj.-º©gØG12!†ˆŸ•²5Þ¦ßñÎwâ»ÃoÄ?õ[¾ßó=¿Sþ¹Ù¾XJÁ2ÏôŸpšgœü¿»;áîîw§;¼øâ ø¦oú|í/þZÜ>»Ã“§�ñ�~ôGñ“?ù“øðOÿ4înŸÙU'Zµ! gá•­xCƸŒÞ¥'„6> NE 'i�€ðäÉãßùU¿à«þ“Êüª3ˆÎ Ô–|M­Ô–oÎCÅ”–ó‚¥!JHœ�r‚ª�ÅD«µÁ5óm×Ï‚À)eÁRfÐ�“Ü\aR›ã HSÆT&,ÓÅ×=m ŽA>/ ‘¹Õr‘2*¼éÊQÅÉFÕœÈ× 1aJÓ„œ'ÿ»ÍE# ¥ )O-¾Jª98Íó‚¥”¶b5t¸Ç*Á+ç 9ä´ ¤4¸V…{TŸPRZE"YGÎDt¬µ¼s^æ?¦[Ó}¢ç~^hK>º6êSw­ÕïN@û”à+v¢‹™gt#b¦E2žŠtÇZ_¿,’ÿ�m, ¢æ¤aÏ 6�Í7€(0;Nu¸�QáÚ¢âí–=÷Ý€m4UÕ@A' hyę̈E 4Gæ«ó•j·@1,�w\v¢6vC i$m®GØÁöQ1.Ã\At-&,œChC0h.!>V+É@VrŠŠ¬T‚qÀ®¢Tfev z0˜ÌñE‡cjq14:{Û/æQêbêìpFÚn(S•¢ ‡”ð¿ú;ñûß¿á××2ØÏ®–¥`YfþO'œN3ÎçžÞÞâîöw·'ÜÞÞ¢ÔÅÆ3©(ó‚RH¼ÿýïÇ{Þóüê_õ«ðÁ|?þ?ŽOê“=bh¸ùá,Ôã$<æ`\ýèwç !"Cªº&üÔRÞ÷Ñ�}ôŸø…_õÕÿ¡¨Ì†ËëYUk8tØÜ®b,ÔZ0ÏgÌg�)ò#¿M˜Ä€ÿ”D¨ÓMñŽ5€¹öSÞ‚�® ho¯ÓÁc�©8ÏgÜÝÞ"g#�“ßîp€JÅÂFд5w¤;å(Ì ƒ A…ÌÈInöÅò(#—ªH›sK1@â!N¼ËF&wЈ(%¸�9³¯GØ^–bà¿“4Jq²) dm³‰cYf¤ÌH)·uœ­_2r®–dãŠéÃ#ÞÈ‚Ü툉‰9©êAE�¯}æõIDÞ‹·ðù`MôÄ@Ê¥s³"èÑöEtåD¨8m-þÃÅDõ9ŸRø[éJrÁF¶®ƒ½<[tc¶Y³m_é>&:iR7$…mÿÇjmØïYÿ÷uàÿ*I[ßú§·m„ÀU7Åç%íèsVZ÷è¤ác­bµ˜Ó��ðìöÏžÝbžg‹ÌqK÷â6ù"ÅÆîb@ù/øïÇWõWáÙÓ;üÝ¿ûwð¡}ÐlÌãÚpÄiŒãcöº#AÙölrUcÛX¤QïKÚœ�Þ|ó�ßsóðáß‘³ˆ‘Z‹HE©4¼¿ª¿®b) æó‚ó|Ær6€YªÅeu²MÍ÷+ý·¿¿.1¾öÄŸõ½<�’sçÏóù.™J="&øcš\y¿°‘ ”ço@-ލº³Ž#…‰ ¸…�÷—ÚÖ]ñUÚ¼’RZ)æ£Ï2:þ--"IW×UmÎ]|>7RŠ;ñ$€ÆœfäTÂáЧZ"[/ØúTaAÀÔ¶ÞN)aš8ÿ£‡˜¦c�¸PsâØk¯½öÚk¯½öÚ«×NØk¯½öÚk¯½Zý\+í®¿Éðó&Z2@"âò„2É-AôÈ¢/äCú.Ë~ÌP%XW¯%¡°—ÚlÉÑ@¡ä±á}“²U«ƒmuö=;6¹¥zoXœ7²A¨ÌÙ€(Uín赡¶&W�5@n´ŠŽÍ=’ wP‚+u]•m›Ô`BžrÂj€íDž];¨ó]ݾ•åÙæm6 µçekÏšàßb�»=+É"žÏ“¸GnÙ�ÜŠ=%°&ò�AÀWÙLÍWkWÃ7´Íæßp:…®@5…Rm¤�h¤Ôï‰[Š2Û†½88`¸JiŽð–£nåË)APÝÖP™9ð"ÕI‘¿+ÔH±‰�òÅÈ+u©­H” tÛÿì›û±Á-ÅÁªÙÂŒÄCÎoع P¤¢”çyÆù<£.3–¥üv®ÚŽWª6—‰Uw¥ŸdøŸŠà�üŸÃ_ù7áxîü¨ˆ‡‚̧Þþívü è¯0å6àd Ðߦë¶ò T|×/¡íVµ¹IШʿ6p‰ß°é|Í whlAp-ØJw†‹ýƒÕ.Å=eÇ®F_ tqÜKYp>[žtJ `Bbj¹Ùä™ïœ’�k ¹¤•K…–<©|¥V× »­J·.Û_»–ÔÀ�E±ŠR0;‚*­Æô³·SôöÖØMùÏÎ*Ê W½’g™�·Ì@÷–ÖM„’»eÐ�S] iýmö ¤oó¡cŽá°ðgP­è‰;Áøu ÈÝFðÆÆöÔ\RÂ5@ VóSÐÁ!¡ú{/e˜¬�ªD)õv:’lN`T¬(;*KD7h¬�coÚ||Ã7ý2|ÿ÷ÿ)|ã/ý%_°¥ÇøwÂÝéÎlÿÏg<{v‹ÛgÏpw>£œÏNL“–ÃnN5Ò#k´÷ÿW^}¿é7ý&|ú³ŸÃþÍ¿�×>÷™UY*ÚçµhO€ÅWP¸¾H‹Ý'UŒ£.obrÊR¾ú§?ô�ßøu¿äÿŠT9ÕZïR-çšjÇ %[O�‘Ò–âöõâñ3Ý1†®¬Ù.WI?ÿuss3c^²ƒî¶®˜—|ºƒ¨àP+¦ÃÑ×_F†´±ÄUÖo͵G{LŽ Ö_Š hðUŒx8¹ÔæçîÄ€ÒMS€‹ûÌ)'Ö±%f”Z᜞æ€"Ué®zì¹…?ÏÔîk�I-f ž3$Ù¸ÝÜAŽ¿�zðða~pssH)?xãõϽót÷ìO̽�>¼7ˆöŸ{Hêk¾�ê&ÛÅ«®,öEäºr}X€6âÄ=dz�‚ÛXøýÀZñêsÝøåÛaêó[»^#â5æÍeDÁx-t<´¹tœCDÖÎýȆkÑO/czt k¬œ6O¾ÏÖßrE.‰ „ �ç–êý Çzá…þ΋/½Xž>Ѳ”EΧ“>K©õ§‡ª»vyôUÝ {íµ×^{íµ×^c퀽öÚk¯½öÚ«UÊü}ý•r{´ÂlîÞÔ€jSm¥¾amÏI‚zÕ‡Dü«T«?'–´¶�v¬Õ h–ÐŒÌp€zef�k›eXPÏm Ž�dq¬”È­õ;hZ0 �oºç&¢O ¤rKnŽMýnG Ô w0À6°UÄ€‘Φ£…¡JÈÉɉ Ì„Rj-¶ñÇ�ôa·f%ƒZ]�Pïu¥}(ÈWÊ"²ÜoU¶ã â€(Ä�ôñš›u¼}KçSñ†Z‡„k·í%�©ë‚¥TÌç3ʲ0Õ–eÍ,C�3j…ú5¦¦¢Û(šZ·©šÝÚS1ë{wˆëcÄSü%fK�[pò@€c¦´W¤ämk;bÛK·ó�\f%�bhä!TQJ f÷+¢H)ˆÎç3ªˆÙ Ï'œçÙ¬Ÿ‹[\7`‹;¸ØÎÿCagÚà ì*×ü„áO|þö•–kP#}@ÅÜ0XÍÊŸ„Åî·ˆ]3NhÆu=Úëú`ç`çJ§ŸÃª+Ö½®·²=’€#n€iþøk©/œ `¡Ãà�ˆD …fòÇøï’ƒ;¤v½nåxÏ1AÜ¥b‡bjðøÆÝ ‘!T¥¢K»ÇAV3‘�-nsÏ)aš&¤œ`ûïäVóº¶Ñ�Wme-l6b‘g?;`¼WRk·»�‘{WüEœ a*9 i$¨»³„*^�ðÑŽQ�LaQ%Ò\@’»Å4ÒÓÜ'¿‡‰Ò„a¨«­áÊá鬸ýw€QÍÉ&ú­€ ̹Åw„•¾˘�> ”M ©~½m,¶ø"Ý$-wg�M ÕÝkF¥ª¶±$GC¤O8FùÍlÍù¢«Žçó}ß÷;ð'þø¿ ËuþÂT)øß¾:øw{‹;ÿOww8ŸÏ¨eqB“�ë⩈É`Ž(•lk•œñ¾¯|/~÷ïþgðƒ?ø7ñ£?ú‡˜ÝZôŠ7�;×è�kª^OùÐm3üÝa`|úÓŸþ�ßôË~ùßÕÇRåÍ"‚Z¤ÇaP+ ¢‚e>a.ŬáÝö'%儜8Ž82Rš¼ÍêÙ#=ôEX¯N‡RÎ8”©­ób>^Üý&†£œbõí1Æ¥”’9/‘‘YÖ„»7÷CÎ=\›€F°Ð!ØaçD=òȘ6ÿ›­ÿìk‚f³ö·µ Ùú ¢ˆÏðõžßƒ "…ëSqòŸ�_¬­ûº7qj$‡1Z%ܬrÎôðÁƒüðÑ£ã”óÃýáúŸð¾æÞ2ºÍ [µ“Ï÷ÍÀ/Œ�G=_¾uÿÑ6¦­ÿRÂþ÷ÔjkP¬ceÛ¿JªÖ(ã ЬûXÓk_ßv@_ÿªŽîUkw—‹U…èf¾$ \~ÆXÿF6Ÿ‹úûèú“ÊÆmã­ºý÷ë3Þ½ïp®¿ä[ˆø9*ýE¿ø—ü—/¼ðB­µÝÞ©ˆà|>ƒÍ ë0°Ô { öÚk¯½öÚk¯½öêµöÚk¯½öÚk¯¾0˜¾ðKƒQÏ¡�²\fj6øAàd€¨–’DôÒ¯‘÷‰ôüu{Œ¶ Öªs)P©¾¹=¨ )°÷À`çÙ}›Zï{Rûoíƒí€Oµ\û–°aóKNÐÑŸš“‡ 7Q»ön0k`‰ J˸øž0w{ÓØÔ«bàž�PAœMÙˈgw èêÿ†v‘Âó‚WÊÃA5@š ›”�K¶MæášÈ6„™Zö¸®”Óýj7hn°°&ØF}N ” v�K5ðÿ|ºÃ²PtÄ”È#§ÜZn¬o¤7{TKª9õLXAE¿¯¦•n�o7i½«ÚÀÂÍÙ9°&×ñš¢ŒšòTœqÕ“¤}3ßJª; ˆxl‚W¥šzp^Ðà@°Ì3–2ªý‡¸8ˆ¸ÚµßÜ£–Y>Üà ûÙÿì¿|¿ÿ_#üïÿ§_5øÅW@  ‹ÿ:¡#Ú¡îw »2@kŸô¼ÝíÚÐ?®*ò‡ëÜÞ—²ß>YÝC{HøÈÑìÿ5ìÿëðrñZɉæf�Z-„ºn$ç«Û=�ÈTðHÝî¸p¢¥èàEŒá±�Dôä ü‹vB•N蘆œe <„]qZ°ÈhïyÒÙ¾¦&‡ Z†S‹ë(-º€IÖ/2øºpï·C MeJ®¢iwâ BN ejêZ"¬ˆ@š’ÞþcbdJ-oÛ,ù tVW[�Î>î«…Ĩç‡JF&èÆ'ëç¨Gãh³ã×õ¡ð@B=Æ¥ÂòËUº MÌ7Cä…ˆ‚X¡RP´ÇêTQ¿gÒÆ³‡²1±ö¿ï[@5bþkß÷»ð§ÿÔŸø‚®9J)˜—§ÓÙ¿N8�θ½uðÿî·ww8Ï3Ê|Ʋœq^Î(ólÄ+Ϥºb^L È 9YæzÊò”�8c:~óoþ^Ü<¸Áßÿ¡ê@à†£Ô#'bÌ_+©Eepß!¤ÐgŽ( „…bžÏ_ó?þ�¾óëé7~™¦IÃ(Ýç Ž8 # ÞÞ=ü0�@œ‘ H)ã0M8np8œ”ŽÕb¨¡Þ¶ðœaö µ^Í Ìo¯âøŒRK#ÞP8ˆ¹ EìF¿©æÝu‰mHçê¶ò­Bé"¾¾rÒgDD±“¦l Ñ£CŒ<'Í©¤”b± Ë‚Z‹¯EŒ—S‚Ôlä-�øh‘L+ëûÕTõc«¨•ÐÄCs2r ‰Å¦ ckJ)圧›ãáæGþþßûÞR–ï3²å¥Òž¨ûžŒ@¸³%Ôÿmq½•ŒŽVèæ8ê.-×h~º²ß—a”®Ñ[÷µ×Kõÿð ŒàýøÞÛõÜÅ…Õ�ÔAöáØF7€ÕeŠî¿q R½òo~7(úU·×nxZ¯á.»ëók_úÙ}lkŽû*¥ô¡oúæoyíÍÇoʲ,óyö1L±ÌgœS‚TEuRËÇ�d¯½öÚk¯½öÚëKxŸ¿{íµ×^{íµWTÊ?Kƒ¦¤®œ"ôLãþMÆIPU•©–ò O饇¹Q§u²À ¸ dª}N¦Ö£ÄF�gãPÐlY›ÕõÆ·ý»@ µ:;84;Ôáõ<‡š™M}œFZ)ˆX,‡V`nßä ëZSï¹µžMNèjQ&@ܱ€¥»¨¾IÖÀÍÒ›ÂAV›�±áÈ®L -@huð nuÏ@ödz7X 5r¼î*\Þs|9e$6‹}U˜úžqšÏ�j¶ûš�¤œòäJi#$4~”`ºúÑ”pvÇE`–ôµoJÏú5KüÚÚU|£M›ˆë`í©ƒ�4è&G7³0WÝ�cB¨N=£«óíqµTÌËŒ»;S³žç3j)]i»>H#Pˆ4Ç " x°«ÞvÚFû�k]‹cui*L�ÍXRü_ÿúc¼ü®÷àOþ�WLÝ/nó_*ÀÕTòä µ2 ܯ-e4`Õ¿Kï�´9ϸ½½Åù|Æùî§Ó�» Ì˜—KYP—ÙÇЊ"Ô¡Ï&BžLQÍ9!'ï9!9Á�ðë~ݯÇ'>þq|ö³ŸÔü]Nlf(AŠºŒiùìàF„ >KW ÛRÅÂK>ú‘ß/ýÆ_öLé3OiJó”²ã”1å "à|>ƒ˜qw{Â)Ý¡NÖnŽG£ÖâNVæðPjÁ¤ŠìDŸnñŸ[?'•fFÎ 9g#˜6ç�ê*⯴ÅT±÷éÒÏ…LÌtóéO}ò+_ýµä£èf@Y]; ñPÑ Û-ò1~ø;Ý{sõº2~ Ù®(t>>ê°¦†�ï«÷ÚÚö‡CÑÆ¥ØÄDµÎÕÏqe޵ù0™¯úã��u<¢ ÀFíEŽ¿&\ ëp} �îÂõl{÷�.ŽÏ J›X¯·¢÷ün{Ótø!‘ZSJr<D¤˜»–ˆ-E±,K»þ¥–ýƒü^{íµ×^{íµ×¦vÀ^{íµ×^{íÕ?ŸÀ6ð|ãFB2Št Ü2=U‘C…ÜL”¾£T/+€¤ìJêáµ1úD �S¶üô°unÊPr{ÕAŒ ¤vE#·ìå° ¨ê6¨¢`W¿ðL`n Os= Ôca1KÃÆº�»øµ2›jÔ«ñž}S»_ç®C�8â$~6Jl»sAµ d³£ÞÜ»¦Œ ¥u€„ bˆ¿¯Y}›Ú–Ýê^…� ‰‘9¡ ÛѶ{ãwË&'öè„Ô@ûP’B Lcé6ÛSÊÈS(ÞÜÍ ÚE«à±Ej³ƒuÈX|‹œÈA:�ÖAa™ÝN^iÕ~ßMÁÜïC‡­µí$f¦P²(ukUmÖÏvߌ‘œ fÔZ1/ –ó Oooñìé3Ü�N8Ï'”eqâ‚‘,rÊži¼Þbí$`äÀŒ–ÕÖ6Êb‘"Ñ>:˜JTŒvÀÔíÌÿÏÿÑÿÿÔ?÷ðm/ÿßð€?bÀWàü"/€&“`r5âªãÕÀoî@Æ�¢ë¿óñCù^ëÝë5ØûWõWoßÈg(Š‚lk†ÉU÷@òã(¦„ ‡ ¹‡ûÁNˆSŠv…þ»îíÑz™V0Œ;?ôŠßÿýg|æsN ŠØ’l± Ãmj‡íÕ\ý»»H#¶´lj#|ðpŸÙÏ•¤<™"z²vmÊúõû„R7r…“˜‚øÅª(ÞGB-¤-.#RY"¦ƒ2µõ5­ŠêYÚ 5âGêjàP­Á@lêä‘*ê9ÜÒ€ðÐEÌ�CY¡ coM;~!k:jcʨ¿©›b4Èb!�ñ"Ú„êp<þ÷FƒÄ°Ä V‹Ô�id$Ÿïx æ¨V•‚hd×a´¹VR{ûUƒÜ*Ä4Vü ÿ½ß×Úá¢ü?�Θç3æÓçóìjÿîîθ=Ýá|2°ö¯¥,ß³ÔŠº,mžM̘(#ål)�r6r–Ïë`²,(eÆ7ý²oÆú?pö L8¦çm¢y×ö3SÌ0 ôRÑ¢�Ðþ¼óéôK~ìýÈ·ó7Û§RN7‡é°L‡¬áØaŽ86ÇÎç3ÇÇ£Ï >‹/¾€‡�áæx„ˆà|wgCMôSÀI8ÜÖz­Íß3¯|P~�‚8áp°X˜Î3Îç–e¢ dˆšâÎc?:ñÎ\rTÔ‰;�XÉÉî/{â‹%ŽpŸËUûxÊäë•8v�æQ--RböxŽp$È6·ª€Il­ÆŒ”ÙhØâWˆÌŒœ'�LÓ„/®|-ÕGOm.ú:D3Ä-¬”Z!³�Õm¯GÉjÛ7,ë‡"`p× f�þçþì€ÿáÿŸã]ó_ŗ׿ŠÄÕ·á“ì4„Û�Ì”FŸ�6f„Ò"f±ß6ó‹ƒð[€þï~W€â1Û­ï8çÒ,í�î‘::p,þÜâíŒõìfRÈ‘ßzóbP‘ÇUï�˜µ}V ‡èúý²1ª&ü±??ãßûk%qR¡(X†#jYלÌNÛ#6ŒsO䂃9Z��É]¤G¸2?¥ŒépÀñxM© .µ Hänè�>x„*[-‡´Øk%ç{AÆÉIµšKÊ€È@k©Únë¾÷zWkï[›Õq�[1€µ›BSkÊ)bS§AÑÛZ}D®¬l뵓 ýÁÇ5!¨�Ù¤Œ!ò~ ÓÅmJU"Â?ñ›~ãl}±ÿO§3NóŒÛ»–yÁ|šq:Ýá|:ãît‡Óù„óéŒe™1;à¯Î¦{)%s2ð?#9àJ>«>~òÏnïPë‚»»;0±EF äˆáéàD3Fí´9�©Í«€ÍEUÅ#97í6æýéŸþgůøŽ¿Éœ¥Äg€ŠªŠ”¢‹øe±Ø—)eG0%ä)ãá£GxøÐ¾‡ Rl-p,e©íž/Ö+„·žAþsUK�›zßâUL9#å„Óã¤6OÎsA)6ú¥d¤NŒiZÏ"â.6FrS_?†sRÚ®Ý�õ5E•pïðu#SwR�+k#Ñùû0ƒÈ 7žh/î b,ê3&§„ãñˆ‡àææÇã¢ÔÖpµVsçi.TÔbˆŒ0!µrIP¹)¥>üÑðÃÿ|)åݱ¶E’i�§l�J›u‚·Ê”¦Ï�k jm\ÓÁî~³D]Å ¬ÅÿmmÛÖh1ö¶7¤NÀŒ×߬Wï¥hQY2:XÚú}uŒžýѨ/iôbm`ÏŽñ<ÖŽÛ«§£í˰溌1×7—ïuÅl ÝÃçÝ(½šîðyî±Þó Hˆ¼òê;ÿÎÝí�€H‰n ‡�Ñ0�eYP–2ÄÁí[Ü{íµ×^{íµ×^«}þýìµ×^{íµ×^QüœM¿/l™Ò4TÅa1¬¶KD4¸ð`šòwA…81Tzr¨•4À$äd€f(ì-C>ƒ)9xN8ÛNÔÁB›Øl®·™ëͰt°Áå+#ÃiîÊMnûŠD' ;×ÜTÿžÛß:¨oÇ+5XUC#9ˆ®ÚPä_»J�ÜÊÚËŠ—ªP-è9¿Ýö¶o¶vKjƒAÙ¯³“\Y “ˆçž+�êÈ×f+.®Ô÷ re è~K¥Ê Ä¶EÙÚë4eL‡#nTQJANdDBÝâÊI(½4ìæõ2¿kãa£·�BaÞï¤ ~»�­ 8w·É¯(Õ7ýEWÎHNxáQ¹eGY –ùŒÅ7=Ã¥¡Jä +´®Jj÷ lÀE®µ`™·ï7° n¥Þ#Æ-^¦µºzl›]þˆ–‹W÷?ÿü5üÄïýo |ÝŸÌ¿ï½ûKxOý/p0ÿdM@zð�ƒ}Ti²dWó@p²ûýú‰U¿CñQgTôƒÇ£˜º}~kʉ9H�†ÔŸ'Qöþñœâ„�¢*�y´£•ô:§–ÆqÐÁ$FTA‰#êÿî-–cØ`œð¹Gߊßñ~ úжÊ=ÚlüP,s�­+NÜÜXõ p·à÷¸ é Ø°ë¯"àê ÜZQê‚C9`:‘Cb ‘?€@i{¼ñ¦�–€¡ H$ `‡Œñ,bîMuOzUÝjd'¿äD±Z›«ŒrËŠÛm‹($‹Í®Àm`¢ªµ£ ¤ÄC¼Gѧۇ´s ’‘¹mø¼ @Unã‹V#¬“�ô¤D+gmpõF·:Ñ*ê*g�â�9‡E¥n¢4<>…ØÚBŒ¤�ŒE«9€n$q µÖŸÑÀÿ‚ÓyÿO¦üŸÏ'Ü�ìwË<ã|:áööw·'œ—RkK %ä ¨g®3r6•õ”Ì€�°qw:᳟ý>ñ‰OâéÓ'FAYfÔZÜgP37ÊçÞíxÀÝÆ<Ö7Ä²ø“q„âîtû-ÿà‡èÛ¿å[¿ýi­u.¥ÞžµžhôçZ Îçá0‘Ó„é0áÁñˆiÊÈN|9p8Ü Vs†¢:Y‘Ú½ýbÎOO(uAªŒ,ÙlðsÂ4)r¶µU­‚yžQJÁ<Ÿ¡}¯"%F) )‘»Hi䵑OÛÚÆœtºsãè7ʹSB[ ¤>´h*ñžîÞÑ×-"e;Ã:€8aÊ>ă‡ñðÁŽˆX.ú²,¨¥`)ÅãúºÑŽ?9ˆZ²¨k•GŸùä'¿ãtw÷ßç”`¯WÖŸÛu(£Rm„ÐKGùª¿F&Æž Ç,o÷kŽajX;Ðj\#¥M\ÆÚ-EÕ¢Q/H¨�~;œóúuÖêûX¢8Ù‚;S˜Fb™êÚ�kt¢Ú`æ}ˆœHÛšc�çÇ?~ÿ<¥ÏÃè7Ä‚ënÆXy,\‰"xûÎ@¯õ×~ýO>»}VsN2MG<¸9bš&Ù8{w‡ZŸ`–ŠRÌåâ¸öÚk¯½öÚk¯½Vµ¯ŽöÚk¯½öÚk¯Vª?‡»·W30û^Ëv+ÙkŠ%UM ‰è!½�ˆ� âÂu Ãk§È–g4�œÄgKW/»:]}pŸÔSÊ Ä+›X¨B6öžäv½MµÓ¾Ø²sÛC»*Ó6ã |‚Œç‚ÁZµ+þˆúyÖbˆˆë)Ïa�Ípém³~·¨òë�¦j"Ò�à™×ÍÉÀ+©B)Yî9³|W8WSŒ6V·É�v#V³¶¬QQyîzJŒépÀ··­uQw²¨Å6ò™ÖÁÙ Å„ÜÒ_ûf+]ô‰~�ú¦* vÙÔ]0´  W ÍÈÏe°*jÅ8'W?ÛS–eÁù|ò/˧ÖRQTVâìÈ6Åi°>h´Q5�ßÿ‚Z*ºªzl›÷»Ò6;žZîúŽKM™½‰�‚ý_ùãÏþûÿ�ß��=ü½ø„þ6|yùøŠúw�“tÐÈœX¯ÑÁsÑîðÜAhë0üž †n�úÕc=ŽÀI2Ö€î³îVì"æ !Å{²å*�àÕXÅðÂc¬‹�£ Z[QGÓ­ljaUæ�ëÀO':D4€øœÀ`TT¿EŠŠYÎÆBƒ)¯Õ²èI7ÀŠüÁ¿…ßðÝß…§OŸáÍÇoâÉã§È9ãÝï~'^}õ8cÎç«ÿÏçæóìàÿ··Ïp>Ÿ»íÿ<ã<ϸ;Ÿqûì„Óé¥.>‰ 0W!£L lóbÅÓ'�ñ‰O|ùÈGñäñc,ei@ç³Û§(uˆJñ˜Œ±Cº‡9PuTKëJ ÝÆ o‡„‘lúàOýäïý¥ßø-OJ™—ZUj©"2�C€ˆ.ód}qòy¢p•°cdNȇn”0M‹�gmJÕ!ƒ�.|›ŸèÞÅáv4ºç/ÃCêã ,ÞV=B)OÓ!ƒ“‘8–yÁùtADQÊ©F„LîxBd@D„ˆ�y—¢0gSÿûÚÒׇmá‹URöÈ¡a�Öˆ†QSþoÏC¡¡_ÆÚG´¢Ë:/¥ÚâùöfýŸp8q<ñðáC¼ðè!rÎ(¥ úX[jÅ<ŸQ�ÀÌ>޲‘¼8%f>¨âáù|zïí³§ÿé0šl€îkëûF.`´x�­²õ }ø{8µÐ•¡�ëÕ1@¶N›ÒÆZw{ ¢V›¤ T7kÕù×Ûj_ò d �QÆ~Üc¡Üiu¾AÎl„µÑ9@GÁ@Þôk)+Û3 vkp]ßÊçο Ÿ¤ï’ˆwÓ�â%úÀG{ßZý9ÀÑÊ3x†­wßkHÏ{ï�­þ{qµy8aˆ''p×j…i´Ù‰Eq¿e}-ÃÝÔ|abÐÜk5$\Z´²ŸãÝÍWâs/}/¿ü» ô*þêüŸà?ÿ�¿Öú¯^dÓ…«È*׸=v£Ö&‚HÁ‰×_{Íõ p…êkŸý\shT‚¸mGïfW2À#‚LÅ,Uz~xÌT7cy_o<}úôÛôGþþ/ßû¿êoÏe9•¥œDd޵PJÛcdʧc똊¥ÌHj–òL„C62†Ôìã\°–´“ùŠòW®¬—øú½¼öØç•ÔN¤ŒH“ó„œ2rʘ¦#ǦÃäŽ6Ö”Z@ 0óÉ•ðŠ’Sw;qUxÊ8�„P{�5‚ÕX’d?'#M•¼Ëä¤IÖF„�ë U°h�HŲ,¾°uqˆ‘§ ‡ÃÇ›�7H‰sHª?ož±”bQyjäXÕÀ�мðìÉ“?£RßOl¤Ji˜Ö.I¤Ôíó}�ÑTíÑnµ�&L¶.ò@ÞÆ‹a­3¬_ÆØ U½èCÛYåv2ŒŸŒ¾~ ‡�Ë �õké6[`¸6±§Õ\¨<Š-a äºZËÓ@PÐñCß×ѵ€¢ê–ÿ¸™éWë¶U4V÷ÞýüQÛëÿvj:þöRj±Q“Ä"tyÊ8�N(\ðt:€FØA.Ëþa~¯½öÚk¯½öÚk¨�°×^{íµ×^{µZ–Ÿƒ�¿­3еûnÚ_}#ZÄìùCÑž|ó±jMUëÕªúbJô=ªJCJd×ÕJWžÆÆ”©0©¹Êww]m+�ûc‰á¯h೟ȠÆïçVÕ6§Ä7B«ˆ¤UVê"BUS«¶,jtP†»N¡àVôØÚijSaüTÑr»ms ¨[ÈËà,›Û«û7Ø›†JœÐs€‡Çµ‚$@ìbîn�o×ÑÔP•¸Y`ov!‡¬m;z³¨7©©þr¶ãaa»æR”KZA’vW©ç¯¶+¨X“Èš¿T;Q€6¾QOý‚Úf¤„SV›¿í.m<’›òpeþìyÅfO]«)ÿ¨ Ö»SDÛT ëu´šÒ:ìK­~ŸhíV°jùt ðÜ]µ¯Q)·±âÕ{‡‚Í/ ûoüuü;ö‹ÿæü-.!1ãM| nÓ·âÀ·x ÅKø0^ÀÇ`Šz±�.”€«jS ç’aöŒëªµ°ý‹¿PPQQÀ÷ÿò¤ºúƒÒΕèâq®ì´h‡x�ÔŸÆ*€Á£†²]»1n3PÂíƒ÷áñ£ïÀ“G¿ Ëá#^ñïþí¿�?ÿý²)®u¸Û:êÃ?â+¢ãµ­p#<ˆƒS}Ã_¤b>WœÏgvÿ8™ò6Ì íÏ@;´¨’î†Q !å ƒ“+Ö‘$âÑ#A,âØáªÝeñ>Á²jsÌqݳƒàÜÛQ³åŠXôL�Jmcrô{R…ÐèêËvPŸQQk€ïX÷ºœ sÕ•K\õO:Žôºnî@H²–¦ˆ§Äl›1¹6×ÒµÓÀ¶‹è8¿èf¾ _¢8D‹û8§¬`Ù8û ÊV"ÂOþÄ�áßø_ÿ›øí¿íŸÆã§Ï nãüÆ›oàcË'ð¡}¯¼ü2Þñ®Wð_þåxõÕW�s¾J0ð1ÛÿóŒó¼à<ϸ}jöþOŸ=ÁÓg·˜Ï3–ZP—‚s�«Jm‘@)eÏ�Ÿ�S‚H5A“ݯó|ƳgÏðäñ›xí�×ñ¹Ï~o¾ñîNw�j}6¢Tž={Šyž‡v‹0ÑËþ×\&F€TM ΄Á�›ÿúÜ«Pú‰Ÿø±ßóò«ïüGµ–ǵÖÇU{b¨LÐìNÔI'E˜gHU¤I0å˜RN DFL©5H¾¦Éƒþª)]#LÞCæx»TêdsØ€¯²}Ÿ ðŸrÆápÀÍq² µ6BƼÐÝj-˜¦ ‰S#2&ÎàÉ[m˜uußH×@é8¿�ç2: 0c5—2ó*ë^�pXJ¡¢T#«Ìç3æe†ˆ"å~³™9˜œÚ5YŠ­'æÙȉ e™PK!aeU=BñðÉoüA©å»'%ÂÜ‘âx.×ËÚ€çæ5FŒèF…rצËõ�nÚ4F§š•Œ>ȱ—‘%F^í’ñý kr¬ê†Ðàd�þ–z‘a ãÔ¹±ýß®é¬}øú9>+ ÷xuAuC`PÝ8 qÚBFÌ~Eè —]¾z[¾²$»rŸ7©`�ÿ_®¦/–’oÛYÎ^åÕw¼ëoå”J­µŠŠŠîö ÓaÂáx@N€;Ô²à|þbEÙíµ×^{íµ×^{}iÖNØk¯½öÚk¯½Z•åçV9±ÞXÒ¦x��:SØ›Íê4MH)¯ìäÙP‘CU}AU_"¯ѵIwdN‡ú:6FÁt ¥Ö ²TÈ íêà?¹š- :W¢º…od«ëu� áœây²q¾Ò¬ËÑÁ"êêÈ�ïãÌ"¾QÑ]°ÊÝÕÑÒÔ7 /÷1ϳV»^°nzx¾ÍCn-TWaòù?önéÊ ŽMb¹ú´«î;4)D Á@^Àݰë˘0Yö®Å(0$D¨5"Bí&�òÎKPX¥[_Ø MЉûÏܼzÍ=A«_ËN‘µÀ�;®¥%BY,ÕÀ¨RfÔÅ_KÅ�A JÃÖÐâ’C¤Z<À|FY–Õ^kkÓWÁûµCÁÊZ–qa©;ªUû«ê½&ÏñØñ}›˜ÿ—¿ø ¥â¿ý‡ÿPs¸`�ôP~ Où›ðßÒêGðÅ ø,ޏs@Òæ~Æ¿äeôÝòp�&�“Õ5ÑnmjÅÀ†è ½=-Úµ;@€Ê~2\¶ãæñ=Ö. ñ³2ùaî¦wàÉï³Gß…g‡ï†äw›ý´áÿõƒÿþôÿè�@ÊZß‚–!߯€¡Ž[÷=Ü+ûvoH«ø‹þZ6Έzl@)~9gxâ�•±VZž}£Z T*j¶ øÌÉÇÊ8Nn‹õ-a3ˆöÜn À¾GY01”ªÀyn·»‚¨(J€úÕ îä�•cB¸ ÎØƒ}u\—*µeưWN°žUC9«n$­¿ù ¬ª`Q(É0ÇòÕ(" Õââ~é� (yv9ß§lÅÊŽ<HK�Ñ®N‡“¶ÚqP‹ñ¼W£bp� •C @øËù/áñ“ÇøÍßû½¸ypƒ¥ÌË‚Óí¯¿þ:~ê§>€›ãï|×;ðÎw¾¯¼òÞùŽwà•W^Å‹/>Âáp@­æLq:�pžgùçÏnoq:ßáé³gxüø1noO8—3j±1¶8QЉ€”ÁD˜¦Éläù…¢Ì nŸ=ÃÓ§OðôÖ¾¿ùÆë¸}ö¬Å ”Z ®Îl~öìNnMÝú­I9—€è`aÿ´Î„§‹9’Æ1×wûôÉw|ä§?øõ¯¾ó]Ÿá�ìO„õæÇ Q·Ÿ'$d(ˆNàL`$(uñN¯nëN–òÏ=¿/Hù<¿,óɈ D9´v—ó„ÃñˆµGb¤GÁyž!bD»Ã4Ù:4çѤ†ˆ”î2�:é0fE[ßbc ßûÇØ¿š?3dÓ«(°�ªÙøŸÍ¡¢”‚ê„?Næ TJÁRì;‹`)³Ç¬,¥`)ÅbˆíçZ¹”2¥”µÖ‡¯î3¿¡”å¶9`8öqÞ¦‹8£pà«.ùëóW›'YWüU]9éŸÛIlñ¾k'ݬ8à$¥5‘UEWçBnH¸X»´CºÆÇ_8'Q'.4C¤ˆ~2ñ0ŽÄè×Ô—kƒ®/ 6Dë{\œTï×àwÆÚ­­Gܯò§íŸ¯vù·3t· fþø·~Û·ÿÔé|Zæó\ÍhB0—Ë\P¦Ì r–�±,çýÃü^{íµ×^{íµ×P;`¯½öÚk¯½öjµÔ·Iø<{;[eIW|†!sjÖȱ!šRÀLYUoDõ¾J_§±��•ª[ÁÖAaHÍ–vhnn#˜Eäà’[ÚÓ`õ.ZÛæ¾8€�ˆ]Õ£k´ý̶é¨ÂØ{…rªI—9¢˜ !BU‘�  ƒ}u¨ÐüÚ¶œìØ|ì®ÛM@ÅÚ�M)NëM|„Åv o´Þ0my÷:b~,èjÏL÷ޝ‘g~;@?l»ºo¾ÖZ›¦Z™š�¾Y7ÛóEä÷xt> ¿î*¨ø·ÒW©è§k¯™xÇõ›å•[¬+'6å7¿?Ÿj1ÐêîöN§J­ÐjªJƺݶMkߪ Îw·8Ï3Ê2·c]q4¢ G>ïeïDohÔÖ#…!·‘!V-þ÷:Cw܇Ö!E`<’¿ôïþñÑ~ÿÊ¿þgp˜¦"n=ÓÉrÄ]þ:<Å×â³Îxoà!?Á Ÿ0ñ ÜF’Gö7M›K¡N H·²õÝlúíd.]L¥ß­°ÛEáQžG@u¢‹9 Œ Õì–W?OïÀíƒ/óôµxzø&Ü¿B/9ˆm�kŠûšìJþßÿ£¿ŒÿÃ÷ÿñ{Ý[húsWÀÔ…KÀ}Î ¼ºó­¬Ú“Âjàj)LwÈÓÇÇÃÁ ²z€î(R+æRQ²Ù­AKÉÉ1Æ<ÌA¢ êä”ÂÖ ¢ JC"µ«H«„B8œ †k(‚:ô‡x´¾‚ÕëibÏhï@MÀ…-œ‚P²&kõ¦DcwŒäøøk‹¶±È‚V¨B5™U{õ9(Z£;¡´.ª7ïC¡ô¯"«T›f[=\b{LÎvžÕuÑq~¦Æ+ùOÿÆàƒø¾ïû~'^xáê2#%kµT<^žàÍÇ�ñc?ö㘦 /¿ü^yùe¼ôò‹¸¹y€iš0M Sž($Rp:Ï8ÝÝâÍÇ�ñìÙSÜÝ�0Ï ŠHJ]P–ŠÓ|†”ň#N*RæyÆÓ'Oðøñ›xòô1înoq>ŸPHvJã@>”Rp÷ì™ÙÌ;©I•/ò¼/\6m¶§ ® n�n¹ækz]­±4ˆ+ü±�~øw¼øòË/Où˜RÊÓ”KΜ“©h�í×"TåÿÃÞŸÛš]÷aØo­ý�sï}ïõܘA€#Áy†¢I ©�¢ÄAdi¢K‰œŠ+Uq%J\)•œ8–c[E’¥ÈåX£¥(’"zPÉÖÀI´DŠ$8€ ’h ݯ»ßtß�Îù¾½VþXkï½öwÎ}CTRªo‘�wß}ç|çötöoBa€Í«9ÐÁ¢z“‘KX j„½:çÏ"ohî"ñËFzÈõªYú³Elˆ`GœŸéâ`=™-x¶ëX­V888°÷mØÆ§á×´·ØœŸãüì›íÆilª´ò§Ú³K`ýT-Óúâã´­qE@­{Ñ[ŠbÛJ°�Þõ¡k#Žáçùkj‚ÀžÏéïˆÚ£%øéÿQü»ßó}ø“þÏáõ¯{=(‘ç"û¹— ·Vጮ`K~&˜F¥s`Î[$Fd¬B+)±ñüs¼W“‘¹CDA¦“ÿi*-jW‚ÚxãîZôù,M`w�tˆm:Â=Ž-¿«7a“ÞŒ‹á}~ÙUæŒH”d%$�È`Ó$ø3ÿÁÿÿø‡ÿn°Œ§½coø§©ãr"u×Ag äê\<MŠƒŠ|GLãˆÓÓS¬Ö+¬Vk CªãbyÞ=x£c¡ô ƒYtÇø€�¸¤¤6nqœ¼Ý�±˜2¸¨ï½]ip%°ñXê|¯½€4}̉ÅNpJ­åû¢NJ܈LÒ,Ëçã-Âú«‘B[,J|­Z¢²“oT’3ÆiÂÅÅ…–ˆ,*`rð_Zd“�õDd-9_9?;}Íñ�;ÿQ}¢4«}ãÎ^{ø¸NÔÝ5e›GIý rO¥¸õ~t&1«ÿ^ý¿?£@;âcçÌ ÆÇ# ßâ©Ó¡�_…dXŸW{[}\•G¡ß¢sHØ%EÉìòug�¥*mÎ¾ì —"äµì™7°Ï@…Yéá8@瀣÷øé>øßÇ�Ž®üÈz½Euɲ QY›íLú‹¦œm�àbŒž¥–Zj©¥–Zj©¥¼ÀRK-µÔRK-UKåóG¨›\ªÝFvž£ì³(פZœ ”†auèhþÚi”ºé³7 [p€½äVW`Gg[ºçç†tªšâQ=[v'·^µ{ÃlPPJÌ·�Â,SµÂ/à 1#¥N\,¹µÊeO¿[Àv`?OaÅ0©‘˜Ý°€@‰ Ô–²ùïØ|ù†ž Á˜¬M]^n…D•UêÕÀÀŽ_·9Í÷?ä£Ù{ûm®Ñ@#i0ŒÃ¡®¸W€$(Ö‹eªJPÐÁÀ2 Z©ö ÷˜IË *ª½yüj³^•à `.¡mˆ@ØÔá¢xJhãª�Ú-n:wà»Z®ïfsŽ‹‹ \œ›’TD<¬"Úìš²”„°Í[l6BéÎ&1wöÕ¶1nÜ~ˆq �é;[[ÅÒ¼ñ …áRÿYq›_Ãç4ˆ ;'"|æ7ì÷|þè¿÷¿ÃÇ~çwø?õ™·>M0 kî6Œ°Å!FA_‘� Óe°Ž Ý€d Å¢-€  [@6F?CR±ñ·Ìx áÎ )%…b°‚Є� C†`… ®bJWº†Œ«˜pް¥GqÎOa¢G¼�uz»Ïä×§’:599µðø�_ý5ü©?þÇñÜoþz»•Ô'ÚŸ9hm«ºŸÇIŽª÷ Qx TU£„H:Ù…íŒÄ²¹Ø€™-›ûè<”Ø�îwçðϲ±ÒÖ¸›ƒHiÛbœ - [8àÕˆMD¦­ZNv—äPKÒÆæFòDU †VÍääŒbî ÍœpBN¾©çR�?sCÂ<`è'ÒE”p¡Ø]iœìÀB-ªDàöãq֦ͪb·ûÀ�àäTcu(Žãmœ. ~çê˜?“´ÅIxLŽÂlÎUS~ögþ%>þñŸÃ[ßú6¼ç½ïÛßôf€‹qãä-›‹$Û=·#¶ãùV†88$’q~~޳óÓªÚßN#$gË«VX¯€“¹pø³`f É"¸Z–T >ržš³�Y€ífãD®mµD/ n}’±ýÀcbBââª3ëzeîíÚO߉ÚZ§°2ˆÈuA(Ò‹/<ÿ½o}û;~éèèðêj5LšDU‰Y™'± 8ÆÉÔæPE΂ԺYðOdç�[«Q¶ÏuW¨qœ°áMm—Ó8bGs‰(Ñ DDC"N¼Rà`Êùêí¯üiÉòL#ªî*ôû¹…*ɤ ÔáÆ�DÛq[WRXÅùi?pl t§lמ0ŸÛè"�ÚÈÖm‚Þ©~_Ø7OÆgQ¿gDòqœ K¤@ ;»�xÊw¢HP½¿Ê¾'Ò�Kȉ`Ï3è~¼,j�öä^ç5{ýüuÏš _[Z3~×{ß÷O4œò0¬DUµ�iÆí¨bHææ3�Ía$€’K-µÔRK-µÔRKµZK-µÔRK-µT-ú†á yÌï¨êiVÂvÂìïï”�RáìrföÞˆtÛ|QS[à±oÞfË]-.ã;ûc»öýEå# ÒjÀ�LE¬"`ž�³tçTíæÜÊš¡jêD‘ ¤4 +h(VØN(¸à›�,DçYìò̉}¶î!ö6á*¨Çe“hwD͹^ÿ>öš…7!!7³õ ¸¥`Qc#˜ ™ HãœÝòy÷ãÈRz+(¨­þµW½ªV%ç\ñ[ˆz»¤ Òö9HÈÖÔËå¨ÝK)öħ§8¿87es·ˆæžÐâŸ3M[l.6˜¦16ÒvFU…ÖTáÕÙ"Š/ü÷‹NËÏ-º#€ï36„sè}Ê�ÚÙþßc lÎ…BZÎGq~zŠÿìÿøïãGþÁ�ÿõÿá�7á[g»ØÔ¢=æ'Æý�‘0 XcÀtdVé à÷@Ù•¼™^,½·µh sŽÈÈJ˜h°¦Ÿ#2²9ÙÇVs ˜´œ€®ojBäPt1 ʳGBF 8;9Å_û‹ ÿÝßúëÁò?Ä�t–Ãd� @Þ÷l÷8�7B•;jP·=.àG§ß%Õ±9KÆÅŶÛ-qtå4¬<�� Bž§-X™rmGà€°bîˆF SE“[Òõ±E‰ªbà3ÙÇsÖíßÌf» äöB½-{¼º –X57›œ)`@"sc’+lŠñó®Õ½ÄT肢⵶fÏ€£ƒƒÊÞÏ8DkDà> Ê"€´9¬Dëò —âˆ;ð¨ƒým>‹=>\G!O05¢€“×,b§(}3~ã“¿Šßøõ_ÃÕ«Wñ_ð¼öõoÂ_ÿz3d2e¶³“­¶ÛÛíÛíçg8??ÇùÅ…Û½»Ut!БN`L–’ï-œI@ cZ!ÅIÆ4el7ÇÛíÖç#�sˆjñy–Â1ªÒZœDfÄròKyÖR×-Ú±ÈædQ[TùÜBÜS…äH±÷žŸŸ}ËÉÝ;ñ‰Ç»Ë)�*¸ É[âAÓj@JTÓ8‚iƒÍ¸µH%)Ñ6æÂck#nˆçÎ�ãˆ,¹ÝƒYŸ#ú­[¯&wÝ`ïY<"¨r÷)õ–û¦Ð_9Ùc°5^PÝ3³�ã¶® øŸ§ÉåÞ–—6Âm�g± #J0³Ÿ“•(HƒåáZ¬‡EM•D‰‘s#’Á8M5Öjš&äœmm‘òVÏi5¤t@À•;7nüorÎß\ã‹‚S—Ю蓂ÚÉï® Cu­.ÖÆ5éǰ®¬Ž$aþêˆ;ß;´›O¸oä(t÷ºÅ�E‹#�Co8n[?ÅÏS�Q¨·K$—êl|—ùçèÞûÞ}§ºk×Ù7ê^i˜x@þ-IïILˆ÷¤^Æ^ËÔ爢S¢fcbJ?ó¶w¼óæ4�cÉD¤¥ÍF͘ü³¬ŠEÊ­VËù¥–Zj©¥–Zj©Y-€¥–Zj©¥–ZªÖ«&Ðþ¿Ô­¡Šù¹uþ`›Îì€x²MÕ„º‰›Dt@Š1§¤uý(, ¶ÃEeï`§8°a¶ÎÔÔñ@µ§.àL§¬ »…®ä¢Ö‹±Ô¬�‹m=•Íy¸¥t³ØMœ0¬¿fÛ°V&P&“‰ É?ƒ¹ÚXÀ8NМ¡˜�=Ûy%©iªÓPÁNN YÅ2§ËÍŸ)qµ¨05ؘRH5Õ`Û®Ò@â9ñÁ�fugQñ7)u�ÉÜÜÕ (Sa¶ÃvçrUäSÕ£9êâ± ®´+H– àfÞ½Íÿ¾TrmÿW"$Ð")ªCEgÛ@M ¿Ë0ip3`$Òšõ\-|µ�F›‹ œ��áüì Ó˜ë³QQp⪠Qsp’@×Vƒ—l¯ Í]~ïžÍø˜… AóG»êÿ> Ø·Ö|p\¢ø¢> e—3àJîöÙÿ?‰?ò{¾ þ�ß…úwÿ\½öHŸ¹¾Ÿ÷Œ;V …çI{+D›!…GLðÚ@¥rºI¡9ƒ‚¥n<~ßÖ=;:3ÈL›ëøš¶Ë è5÷E¥Ø��ïoýMü­ÿâ/âî�ãÎ…a†ÙwãnïÌÐ@~½dìÞ °ý@;½,?¨ÛЧýSU8ŠÒæ/ppx€+GW°Z­* Í¥±9ˆ”%› TiXí!ë´Œè¦Po™Í;ŠE) X³«Wm6êEIOݼÖk^«ÙJÍQßmï kàã‚@;G��×E¹œ$ÏZâP¢6f„YÉ£g �A¡nƒžf¹ÞÚƒQáy‹ æ±�Äc·S:ÒD<ÿ� X‹<@ˆOAç ¥³¨âää¿üËŸÀ/ÿò'0 +<þØxüñ'ðØã�ãío;¶[1ë÷íˆikyèÛÍç› 6Û ¦íˆIr%cpJ8Õ¹¸îfk¯ÀL4!ÁÖÛígg§8;?Ãùé6Û��ïðæþW 3¬3ÐÀù¶Ã H!d8xLÜÜ8jI$Â`ôä;®sr{#ru8ù«ÿêßñÌ»þ#ã4f!'fY+¬WcZÕãMã¶:´>QÖöQ9 Æí„qÚš5~GÊZ‰ù!Ö‘{ÅÀ—C–…{«;S¨_o‰‚"f à %­˜ù0­†+ç'wï4M?´£¦GO@ˆT˜ï 1èø—Ý?�4‰ä�™cÍ>pºD ¨Î"fæ™Daœ¡=MŠâ˜wÙ¹wQHAÆó~,ß‹‹×x­d°æBF{×VõÜG=¿ÓUf\o-÷=à�ï§‚ËÈt߯‚ºó<éÒ¥âü— `X­~ôüübdâPQU%J¶î.ë¤ìD�0Öë!ŒíK-µÔRK-µÔRK `©¥–Zj©¥– Ex•r-…©%û_ùŸ®:�8aH iµÆjµFRP7Áj&{"VÌ|’¯¥¨t+ÙëšÝæ{° Ó”�ŠRDŒÜþSº$ëV¸*Õ7õD’ ˆk$³ñ/ZNp"‡#&$�ç+k%6X6tQ[“åÆRr”²Ù¾ˆ`À—�<FwF(~ÛÅö¾œ='Ûêg$N0ö(—Ðìi}“ÙÀêfAªl+Õ’ÁNB!Ç´¨�±wóN]Z!3 ªQæjw�HSãŠ�è7þ[äƒÔ$÷T>Ç!�ºÁÊÑú¾³«õ¶%ÅZYš €ÎìÎ J5Ža¾ÙkÔ~s°=.�3D`ªÿósœžž`sq�iœì=ÞP-ÏÛíggg˜òˆ�MÖ(ÁFîÚ-¦z¹äD”x©ËbàTßõÛùx@séýŽ|߀B—ü3u$šY8ŒÛ-~øoýuü?ü÷ð-ßþ�ø#ÿËÿòÉÒâïëVÐëï¿iÝÝ™¢â†"£}”ÐÒN�š�1Eo…:X!H%ì@‰ýxâ$ ÚÙ�—6mGüðßù;øoÿÆßÀõžG8=WSÏ®[{@%vÀ�*…13µx» -ÿgÄŸ~T/œ”˜[>‡î¨YøÉ7@O°x€ ¬Ök\9ºêóƒßg´óÎ*PÝ"gAJÜZªŽÂvo•’Ú‘� ÖÆ|u¢FQ³G°¢m<ŒÏŠc´îmf…TÐ†Õ a¦ví\I¤k™ª™Ì¡ ÜK�  ì�1Ì•ôVÈɦ&hÏýñÃï~¾=Sªð"(™ÜÞÞI\Åö_Kl�H�N!WÛî¬)èÔ�%LádN nñßÀ©vâÓ¸Å+7^Â�/ |Ó7}#þàúA|æÙOãÙO?‡çŸÏ=÷^|ée¼øâ‹8¾c„B΂iÁDX­ «®\¹RÕÎJNŽ�ðèc�áÉ'ŸÀ'~éø•_þÄ•ðY²GC´y»�‹°móyäVY…è˜Á3cÃ4Q¯Ž¡ZAuŽÑ ¡}41±­1„-ê‚ýîßùèÝã;ÿõ“O>µQÕ-Mؤ!�«4à`½'FF ”°ªk‚d[q*q$ˆF�Ru·Ùn/ÜßÛ‰¯Åº±¸·#ÀC®=òH‹š¹ÄÿŒ4Úÿ>%[k¥Á¶ÃŒD²ÅÅÅ&o/ÛíÙm ­‘<œüÅ„ääÓa°ˆ�¢ÌgfŒãhç(�€åÿÅh€±üç!%'ˆ” R²ˆ’ìÄ%ì¾R �V+¸—ÌŠ@‡Ä|esvú-Ó4ýŸ J2'!”Uï*Yçò™UÛºdf©OuÌ÷þAaü#nX~g›¿;×ÌÉj¤Ín¿QëzF |F ¥5ÞK›ãI™O]üg§ê€ãc™ÒP¯˜‘–¢ ?,£SXw}×K•³ùDöv›z·*@ï±Èé{YãPèÎÜõ ßçÁ‵³ö»ßRL�=öÄ?Ü\œgæ”™YÌŽÀÉúªÈTgŠ+‹J�±ëáaXGK-µÔRK-µÔRÿæ×BXj©¥–Zj©¥jÑçôÞ¸DÚ¾·fª&WJ¥„Õj…ÕjUgSyg/”Tu¥ªªúZygU 挿ý24†¢’Œx§�1V"´�. :ÚïÚÂÓ̦<ŽAåñŸ�žâ‡ÿæ_Ç?ø»_ñu_�?ôïü1¼ÿ‹¿ôó0ªÍ¤òx0ñ]‰ª(w¤¤¶Í ”tbŠ‹‹w6Á)¼~¾YÿÊ+/ã¿ùÿ/üã¿ÿ÷p|çv{&ª¸Ø ¬M"Õ‰0_Õ�Å^½E jgõ\ëM¡ñVj÷˜Ñu¥Î8æQ4õfoA]T l7[l7[àÊ•«N¢j¹ÀÎ2"gB˜ «w;àΛ €?Õ0Äwqp=Za3ÒGsx�ªîjQ@¦8Nu¥JìJw5®DT¡ Æ±’BS@w” :¢ÕQ§Tëó¬1Ÿ a…L:³�¨µ»Û ¸Ž»îQ¡ÍUEÚÝlàÍG‹0ÞûøGÕ%�Ái«BY¡j.*jD�Ð’zûpÂ�;wðø£�â‘÷½ï|ç;1M–~±Ýb{±ÁÅ…¹l.¶ØN#ÆiôøÁ”ãv‹‹ó3œžŸcs±Á˜m N‰ð³?ó3˜¦±’ÎÊÇ–Ø€âÄøŸêÈ ûÀlŸëm@hóGsç(k �æêÒœ‡ØH[4³ÙÖúlÚø@ÞŽÉíÍEõègæ§ïG>òVUOFšîà:¥ebðs ±�W‰/!²5Ð0 5¶ID0�#6Ûm¾‡•Åy~ë2Òã�›Í>Y¬PY0'¤ÔôÀ.aŽ™±Zà`m€}Μ’_ËdÊzHžÌ©‡�Àè‘Cäk„Úû}ñë ‹@Y‰¤)ÿ ¡ÿ‰ˆ iHµ}‰*’¯mR×Ýy£�EÑ9€˜ˆVP(ôÊùÉݯ·Û? [W7·“€Z3íN“q>®cZYë».>v1À¥ý¶`�HxѺr BûÙ�J˜©çëj#¸§PGd@ˆ‘JPÏò©Pª;- ÍµÝÚ*®mçHuÌŽ“s$+ Þ@TƦ¶õÖ¾UˆêîD??–ê|£{W<ºs êæÔù4u¯ê]î¿òR}°o˜Äü©÷~ñ—þÊ8Ž™Ytð~�R!Sá�Š;Gx¦ÄŒ4 X K ÀRK-µÔRK-µT¬…°ÔRK-µÔRKÕú|5a¨e3QÍâåÁTz" ›\vÅ!€#•éC"Ê¢‚iÊÈ’!’ë&ÂÈ’�TL劘 4]žicf’fš�˜(1º UågÛ 5°Eˆa›ÿÁš°“"kFõ÷û¤prØT\… =2ûW­1 MÙ”íz¥)ÓŠ‚]Ä´›R@›X… ecTg›šä¶Ö M9!bféYT šQP uÖÑmÓµ’"˜Y¦)oÕÕ¡iêÎ_Ô9¥ˆ±Ø3àrN¥-�Ö[Úo0Ï�jràÓ¶d™81˜ÌÅAT@¾é>€ÌyÂŽ´ÝlqzzwïÞÅÅÅEÛÄŽ°"8=;Åf³ií8X7D†žíéoñôÛ!z{èð�ào'’Ÿ››£Z–Ó¾þÞmLvÜßiÖËhŸ"¬Ïßm�b»Žq»Á?ÿÑÁ?ÿ±Å|áÛðáïüN|Ï÷~/êɳ¢Éÿ};½ÿK¤?R„þQ¢ë5Èìx³x„Ò;óvÄ?ùÿÿä¿ùûø•_øxÍÜîlùg~ÜS�¼>²aÆ’NQûχÁªDÖFð�Þî!’ Êi‘îš8ÇF´‹4×ä^Q© °Ýnptt‡‡í4µû*„LÞ±坨…Ôˆ�J2! jþ“ºX[Lµ1‡êœÐ»VHUð‡”yCòˆ“ŽÏ£Í5F<ê¤XŽÛËxgžŠ ÖâH‘«Â<<›jß:pF6ò�j×»{‚0 AÙ,Õ”Z¨ fÖý´‡P¤]pâ•£ZLê19™c1( yš�IÀuž@çjRnî�ã;;Wøbêì„40e¨$LÉ"Ç+I„Ü¢ƒ==9±q¾DUTK®Jð þW’ÔŽWøŒ¼¥•üÓ,ÓÈ^¢¤ÍÙµ¥ÇŽIÅ ©80Ôè‡~Ì-}üå—®ôìüôÿ}xxtCy>ŠVBVr0{X%HNü;©E†a5­°Z­1¬6N¼i6ú… Ç!Î(ò�>_ÅÅ‘¢^«µ¥4A!¥žü&Nö) ÷FêL5N OÆqÄj\a·3‘KC «ÏÞ‰ ÜÆ�rLRE&jëŒc6BA�£àº¦¬DŒTÈ öœE4Ä(¢Ùˆ4Q[C&Æ�¤ÄLÌ€U½rzròÌæââ/AõZ?ÐÖÐLT‰ºƒf®4  m3-®+AB*‘+¦’xCªëgÕúw‹˜ì·eOà%:¨Ä¹ŒÚYÉ3î�Šî.?‚’¿�AØ¿º¹Œ@°´Ç­FõÞ¿tEô€šî÷�v½ëõúQ†q»ÍDÉ 1C‰×HŒœ¹Þw�TRÏ ëÃåËüRK-µÔRK-µT¨…°ÔRK-µÔRKÕúühµ´m÷г˃,�‚¨H6u3'U@q•×Tò‡4lÞj֚٠̨›ßYš|¶#­QÉ£-½\ ‘× ×~®p%«Ôø‡.uW=R¡¾­YÂw‰¸‘t#ÆØÑY†l²žÿô§ð_þßÿ þòþçðÎ÷¾¿í›;¾ãw|ÞòÖ·^>¨Eü_fÏX°tÉÛïeÓß�|ÞÏÊagÍJ£b‚Ó“üø?ùÇøgÿã?Æ'~î_ââì¼Ý›]öIˆèH!ó òòÙ9Ï r`Qç9ÐÜ‚R´C‰@~h@õ½4k‹ºÇzÁŸ<âʼn¨Ehl6¸zíRJMåÈ?P@W•8Í­ü³rQèÏ ælO!¢ºHPßÏ©Ïl•ç`Œ¶!+¼LãM�š³iaÝ5B«¿MP¬dóÑ0Ô9„™qtxÔ”×·\/�/O“µ2UËvq÷—Õ0ÄÕÞ¿�ßÈíÈ3ÈÐæõâz�'A6KÊý9�ãØÆ~LyÂ4M<ò>¯–+O`œ09ø ŸK ÈS@ñ;ÇÇ{û+ר»‡!!‹ eñkuÐ.»wG2ð4åÁàü⒠ܩșšU:E-š‚«…Êýø9Ox)q Å‘ÑABCœNœ€,ÅQAkÕ.>¡¾„œóÕŸøñùÎë[?ú,3Q!‹óÒîM¿.3Ò†­­3ÈIÐõSž0N[œ¯ÖHÞ֊ꚢ•<îcýÿ9¬XUƒi�Ï�) NNë4¿†ºeO;nñÑ– O½·k•v®áû@M&à¸Vê&gôç¶öâaúo3…XÖ­�#¹’лìøþh7mÚ1egi¢;Ñ^Úâî×[A”ö®(ðÞ«`ñ\ç1s!z≧þájµÊ¤‘sÊw¯T×Ê™sxlþ}ˆ«ÕëåËüRK-µÔRK-µT¨…°ÔRK-µÔRKµâýÐÖ®Âdwû¨SÌ8xÃasP‰j~½ˆ çÉÀoÀTT(¶ª´R¡C…> ÈTõ‹ £6 + CžínV«û6§ú�I;ߎǜS@‰]÷n¯e'¤a@R²MÚòSŠ+Ãßeٻʶ™®®Î+΀ )341’& XØ£êyÁ©©™ÉÁ³L67‚öÜØ‘¸L9oy÷v‘bÆL¨{ýR�¹)Ú‰Ùî;ÈS}Ý>ÀŒ`À‘øæo‹…eP ðˆ4X]7{d?ź7ìÊ´Ô+M»Ú¥B@³C˜Ë91:ÿòè"1SF‹Ú¦j!°¤äyÒLNFÑõ­H/Î.pvzŠíæÂ-šº_ò„‹ ‹ÐrÏ©ïGÝsô‹ìlj÷ùµ†ÍcÚé¥!{š¸) géŠ`©»�_€~÷¸‹sP×!RG©ñÛ¯5O·™ pêíu%ºBhË&G°´v;lůüâ/âW~áð—þo¯yýëñÌ»ß�}ã7ãÃþV¼é�oÜÏhÚ;Ä z‚Rï@®eŒJB„Hš8ºèìsÏOÎðóÿâ§ñ³ÿâ§ð+?ÿsxö“¿†<�í~ì`ƒÚ2’»á—B3Þg·@˜÷ŒfºÜ«àÉUéÖF‰Tà\“#ÎOÎS9 ›Çb\K$9h#(éÜ–Eg<ǃÎ)*¬¯êº§©ÿU´K�л5èl �D¶ÎœGfVýÓO±7ÂH÷Ͼtéw¹Ùm¾¨¦=ËÒ‡êÆ´w]{¯—&æÏ~Í>ôs@Kcc�Ö¨Õ]„ëØÈ<Õè‘Õz…Õz!,µÔRK-µÔRKÅZK-µÔRK-µT­”曵q )þL³�¤™ 8à£aƒ ·²�¾²y[-Cí€ ÐªGªr�4³ª¦Î¶¾Á¨ócš³nÔ–³õ wšÛy’:x6׉Á3’» 03ÒÀ¾eöÿ(dW ««ä‰êQ´ªl:@Ë…AðK‚² 9i )7«ïªe$³¾¤bgÚ²ªÅsåIU“Õ'"í> ÁÊ>ƒg(ªÁ’wŸ˜ @ñÜí,- ¨¬ êÂÕ.“¸€d!q”MÖrNìÇW®ZiݹšJætÒ:PT«}|&€¤©óæ¶è5·;îüú)VGÔ@_Ù­ s›Pv`¨%Ø–û{qqŽ““cœ�ŸC²ß+Gòó4áìì ›‹‹ÐŽ�}»ª;@é^ÛÿYmŒ°èÐäN‚†¨îl´§ºœäà`]sÑ[.ƒ�¸Ä\”$Û`æK÷�ÕãÐUÿf'nˆr˜º(!Ë5é…pý…ðÏ~äGðÿÉ?�7¼éMxÇ;ß�/zß{ñÅ_ü¥ø’/y?Þô–/Ø3êÉžßÍï­E{Dq|´_ÞgÀ{|ë~áç?Ž_ùùOàS¿ökøìsŸÂ‹ÏƬý1³:Æ ²¯¤šy`‰=cíÚ.… áòÜtÖïúcè¾kî\võz­½DÂÁ,¿Cw­Œ)ô×@3 ÷Uvîü%ÞÓPUãÚµGppxÐ5��ù 3á’ƒ©n"%‚„”�äyÞ±’˜ H¦Íê–Þìë»ëF4ÐîÂËóPWi–O¾¾à-_€w¾ë=xß{߃/ùâ/Á3ïx‡EaÌâ D€,rÖJ.ð˜l÷3»Ê–“»ˆˆ(š3¦i4ðšª}µ³Ê|š�¿¤˜ ¦‚.ýŸ�D¢T³ÐIí³T[ ŽÑY?òÁdf²R­âJà+WMéÉŒ�W¯aÚl0Éä ü’Y¿ÂÀ ?ù“ÿÌÛãìü·��qqv�q42àÁá!T«aåëöéë\¹z„kW¯â‘k×Ìi'1’„ívˆ(îSÔøŒJDêÜ ª³�Î" ´EÛèÎ@XUÙ�-{p—¡êœ>ëÌ€äÐÞµWJ;©Üúæ8Êc?ñ£ÿôw|Ë·}ø9�ÜQáѵ暧¬9O§ Ó4bÌF`e¤”}ÝAà4€Å!"Ûñ›Í!²L&Ëì®jvâ½ÑŸ�Êc†d?{w’ŸQÖŠvË›+M„‰&L¹�_‰vZ «Õ냓äNI^�<Ê3“¶–Í9#%s¨ñAœÜ‘`…œ§JÎhöÿÜäF”ÉFfÝnGŒãˆiÛ5Ub“[a.fâ”Ò°V«aue³¹xú•W^þ "òþ&fïc—ê4íø1··�Ä–Ùˆ\§{�S ü¾ËìkBŒÒ@§šÇžeus–v±Dì÷+ü¯ý9—Uby~ݤб²Úú¸¬ÿÊZ»ûÖCÁÞ�;�ά4Dt±`ág#¼É|ì æàĹ0˜ìqßÙ=ÜÔ~¾ôEVëõÿ¸Z¯&Uõ!_Ûïµ`¦”�U‘˜±¬–€¥–Zj©¥–Zj©X `©¥–Zj©¥–ª•\YÙjN(µ«™ç|c¦¼‰j j;,fÏ¡7p€Uu-*WrÎ�&’ÅÍtbª }Bvçjv "X—KÜ�(»oØhïÕT~¤n] ˆÊ639�ÄEfo6ž @3:etM90[YU�djÖŸÙUO $J¶QªP‘ ä7‹>W2ƒH†f­YéFN„U ÅÒÔr Ü:Y:;Ó¢”øìÜÖ9±_gbwgP°J€è¢ò¨(¾ËsmjúSS+ª�\͆zN¶¡g–ÊÜ™ÏWÌ”ïäà†©t›â $MÍNý‘f•«þºrêêàZUo›‚(”¤kµ‚Zn¹+Øržpzrg§§˜¦±ãÆä<áììÄ"j›»lWuX¥{ÖÇÜï¶1Þ«ÛL€¶Çƒ°§·kŒQDý˜Ðì�Ý>™Ý ¡;BÈÀ 0Zmy ê@›j3„Ÿçe7>@ Œ‹¿ö¥^ÀËׯãŸÿø�Õ½òõÁž~êi<ýÚ×ãõox=^ÿ†7â‰'žÀ“O>‰×¾îi<ùš×àÑ«�àÊÕ«PV9½ áèðQ¾J0`MÅ�QÀŽÕü2|–ÁŒ’>$$b‹HQ±@ÅÆ}S×çz³)äY«îÆx¨h%M4ƒ ýŸxâ)|ÅW~%>ðu_‡þ¶ß†'žxÜ,ÖE1åÉÀLŸRÊý��ŸjÓìãU–ÖÄÆj͹º`šáijÄÇœ1‰`Gµ9˜È¡�e#@É�ÓÍ¥&3!%'pÉÏN ÎM°*¨d·”¢0…~Yo¸¢wÊ#Æ1!%#ÉÀPTùDب"�ÙÅŒ´JHYðüË/ãæÍ¸ñÊ ß¹‹Íæc‰�õM…®"ÈyÄv;i‚€aµÂz}€Ç} O<õ4ž~íkðæ7¾ãv öåbÜÄJ|cï£èÍ:·%G I n=>×Äìð:º«­ND¡±úÿ25ˆµ¬Ut�e»uI­ç|ýú ¿óôôôo\½zõX ™!ç":æiÒívÄ8�Ç­9Eˆ8øfn €Â–@ ]'¬ó‡GG¸6^`8\)uîDŸïº8Ý`š&äÉ"%JoFJ«êìcŽ1FÝá@;çž$‚U‰Ôp2ˆ©òM�¯ÙÈ‘ë¤j¤€‰@O—±væFÒúË]^âzº�Sjcx?Äk7¶}�‚b>øß@EÂ9ERk ÜtNNå¯�¨l Â\iv…P¥’»9©#¥Qs©ÙuF‹÷ª‘^ã„ ¥mþ s]·V�«¼ËkŸëÙÜtà²×>´�ÿCÛÿßÿõå4Ÿxò©0¤4bF(Öÿõ?ÿžÃÜÜÙ@â„a5`=,[ÜK-µÔRK-µÔR±–ÕÑRK-µÔRK-Uk}x„‡Jƒ xp­ƒâE¢½p@O€ºk™©ìø…9O‡9çkªò:‚¾_ò:•1hBÕø�)¥°Ï×61I\ù T…|ÁÇ[<9‡�@1U±jÅCz W)ÎúP™j.+üÈf;lç§ÌÕºÕ lÿœ{ÍjÞ—Wí'ÊLf¡¯¦t®JÎTCLŪ„!5ÅiQÿk°¶MËr}\ L†0”¼Mö\fUjª°˜m­3@8ºytGË`¦½/)àY9ˆ†gÕ>ƒzåqÉIî[t;<}5 i€J'é/¿/@{¸/§'w±^ X­*á� ybeãF‰1)odήЦîþǦjO“QÏ“ªÝ;Kêû¢KGç‘‚{ˆozË[ñ ú>öÑ�â½ïy��ß…e¯Éî,Â2¡[Ä]kÔÔý ñ?D>¹ÌÇ¥ “¹âø.Y0Ndš0m·˜Ü9ÀX#ÔýL p.K�½|&k©:7Ë(_Z\h¼}ˆL˜U$NHl[ #|MyÂéé)¶Û-8™]?Ôìç‰[_Ï"󈋳süÜÏÿ;kÀÀÿÖ©Éãr¶ñz„ÔÛ�§y2@vûòìsk#<Ø%$ O Dfpã÷¾yjîU±»ì9@S-Öùf{>x´Jž2¦íˆ‹‹ 'l$ ë±¹€ˆ‘’û…ç_ÄOüÄ�CU°^àààÀÝG àlsßdì¼u#l�\T�%C²+ÆÉÒ `“8 ‚«�<‚Üñ†÷¾L ¿ök¿‚³ÓS#…±åü�xs˜eqkÈ».ª•°£]SÞ¥xu‹;¦Óuœ.c©»Ú(4)DØÙ�:÷t·Ø ª_ºþâïÝœ]ü÷tåh“XÇ,²™¦<æÉ"d4ë{‚õ�B²äi‚:ÁEp2@Z5uûÀiüÿ|¦<¹õ¾ ç©·?¤4Õ1!g‹60Rª»¥Ž! v<ï f·ÏFޔ죔“1U«G!Ÿ5×(®÷#%Æj5€™j„S!†XŒ�“SÆÉüþæjbç@m a21­@tàÊ4M�½ðÂóFD¾¡*g6Íqdw1_ßéœ?8S²ھ ·# ”v§}¦}üE{ÇŠê¢5;f9é}ÚEÏhÄö;…¿ž�  \E+y8Þs1 ë�IA{­D©�éØu ;çOÝkµ¬B:Ûš™÷€ÎŽGÔ­�ûÕÿº÷kÝl‘¶ç3^MÝëÝëõú8X¯.TuÑìì[Xí½§ B ц1”8�a!,µÔRK-µÔRKÅZK-µÔRK-µT­Ã+n©ü€¥]ºÛu¸R]0� ”&ÐŒcöÍRírE›¨°ª¨êUˆ~Àr]MMKÅ'€È¼ƒgV£àÏ�ï€5ψWWT¥‚%DVÐ)djQQƒ,9 Ä•øâvËœ iHP.ª÷rjÄ7@J5A9—ÓvÅ£)9‹>€ \5‡WÏ#D*ø½³˜ßl@àžµ©€}õw5•oZºP?ËŸ­Ó”1�D¦jÍ &¤‚ODgU\âdàNÙÁÿJ©¶ÜØÉ�U¨‘'àŸ~]mÛ“‚º�šj)AÕ,¿}ã*HhòÅ%@•ší¬?sŽm)7ëÿÁ?_˜ë·‹#¶Û­© aïgWfžœÞí¬Ø�^A^3h&ö§Ø ŒÞ‘í××pÝÀ¦Ü¥.·=ÞÉþS³Ko¦Í.¾ôïÒ–8*<«5¶¸ÒÚ]ÙÀ¯DÒ×ùþZ¬Oˆ?/©xm$´“Çv4bõ¤šÒ� G Ÿ ‡sè‰ öC$çDÙ^éŸ1^8fwW,¹¨¾±¬ûN×�”vFÝpŸ«†gà âÓö{DAÐ�h°ý¢y›èlÿÛ§—ñ´öá€85às×¹@÷À¡DÎUè³—sžp÷ä.žxâ‰N¥Y»Ä\ý%:�xÖf#0‘Ö—“LN8)W¡!š†ƒ#¼ù­ø–oûV|×ïúxë[Þj‘-þ�”ÕìÇ#-Iq#�“¶ü€9�’r6>ËTã]êØ†Àö¹=�¬˜TM•¯eŽhm&ö³s &���*ÙÏQ=E d7De.Ü\cÀTÉXL6®Ò€aµ Ø`‹qs�óósäi3a½>À0 X­†Ö3ÜVýé—ãì¨�i×½eGY­ýÚJ{Ϻ‡q&¸p”ù$8 Dh4z Œãö ?ýSÿü£_ûuüÛ™ùT!Ç*Í�" ÉÜuÜeaV ¯§i X4|6bÜš×F¦q5n™K²ÛªÇ¹tß4ö°U¬ÿsÎ�É€”± .T9%Ï 'dw~ÈÒÉc1rÎÈyp$)@d;Ô�Oq+˜ÝgT�!‘eÝQþ+ÏFœ@:eþÇm!54÷¢aXÙ}e®.ʪ:Ñ]™òôä+¯¼üçDåûóÔ{M4´ ­.ª˜ÍN—A·Ú¨ú8"3@]4†ÎA|mP:QŒ‰¡dËÌ~üЮãgîºç„õªwžâBUûa�°¥¿NíÇWè®Â?:ô&!–)ô÷Ë1ÝsŠŽ9ªØãpÉs™Ý—ÝïoûÆ¢Ùû>Oœ�ûæ±Çÿû"²Í¢£ˆV[.¢°N šÀjóz$áqˆXj©¥–Zj©¥–Zª¯…°ÔRK-µÔRKÕJéá–:Ûepý}ÝðÜòT×th“í¯!«�À3=©*ï'�[¼#“zr¥±©ÁÁ› l܉٠gÉPßaME=ª½½·Ùoš*ŠT Ùí®`ÊaãXý|t´ëNI-¦:”ìO·gè4!›%€Ãf¨Ü%KÙ”ÏpqÇ;·É@FiÖúšÈl—‹½8Ám¢ÅÁnª¤Û¼%Áaš2¦iÄ4eäœý<Ù5T ¢¶Éß]Š2ÎïÓìÚ‹Àˆ ¦0��xÝ@ßÝdÕ`·mÇPWÚ  ¸ízꦱ¨ÙÀMe“»(wÍn §ÄÝõDB„¨I>¹Ø+»"vš²µ)˜³\ÍÅfƒiœ:@¹í%k§lêñ#ê�5ÐÕ!À‹©Ó¶7ý›»”|ópƒ{UÌ~§™â¼œgŒv¬H%ˆêß’sOÈA�W^ìvÕ!ô:˜·#†Ù³$gËšŽ*Á¹°�%6 ¸­¹µ�H$�»ìhÕgñZŸí<ËØ—wá=&ŠJ)ƒv$†Ëôï}ŒYÅ»µ ü7ÈOƒE}‘²·×uq¤?ƒW"(³× @;0ó¶1»ßJ­ŸvÑΩ…1$|þÙÙ)}ô1 ùs­ªë>ÞÃìË%Ä‘¸->’�ãâÔB%ˆ5CƒðÜ¥‘aÊé<òÈ£øíßò­ø}ßý»ñe_ö¥]üM ‹"_ÄBpŠúREmnpàÌæûrnÀ—÷F8«.0’=ß=Wâ˜Hù÷Økùlw? Jgs[)í Ì7Ô»0ŒPg„ƒ�Õ�Š›A(ƒ<®CÝ�g`†€½©…‘¬Ž×©Äþ`³Ù`Ün"l¶#V+X¶³‰-êá�ï~7~æ§Ž=¶!ÕÁ4K†Ú0kó�æªê%%w» W!‚8AÄ€Uª ’—‡§_ó\½v<$|í×|5¾è}_„¿÷ÿù»øÍ_ÿ¤«rµï:ºßõBËø¤³ì•0&—y²Ì-ûä¹®ÐÆ¢ ˜ŽãLQ]›ù�ϱÚ'l¼ðÙO×v{ñ�RJ7AX™zž±^­¡+s+†„”VX¯WHÌ�œ±-võî‚$ÅE‚mRgNR2‡ˆ‘ƒëA¿ˆ_ýzÕbŽJ””Å ¦àÀ’$×X Á”'û³¯E³9¥Éi0€Â¬¢Íµª{^åY•î“Å�‚B–¤Î®_ƒ=~!£dɦøŸ&Lãˆi²±ˆ@RBâ„Õ0`X H©ôqeDäÀ•qܾöôôä/I–¯¶¡“ª„jo/_Èï¬MúÁ¾×uóz¥¶^CSÕk±—/©cÿ=‚Š›‰GÀÇghë#š;ÈÂõäIíÖ= ÷ØÌ£ÎæD  |»þÊ€¡«J¯ÒÇ<¶ ¡uϬÞhØ=½ÝŸuF"º‡k½¾áíRñ�ßïÑ~ÊZ“ù¹|ã·üä”óFD'É"úõ_.8q ÌIN²,_ä—Zj©¥–Zj©¥fµ–Zj©¥–Zj©Z¯Î¢µl2‘�ôv š‹]í)�ÙZ½â´b~`¦�™ ô�iÂP6ØH¬ "âdÙ€mÒ¸¢ò¡xFKw­JôÉ­ÝÕ8eWÃuÚ $ŸDvíl}ó»lp  }ã¹`lPËÎÙ-k‹¥²V�¹5©«¨Õ6>ÅÂO+ØÄìÖò‰1À`€šC�¢ê´sªø‚úf*àÞÞ'nïOš Y´(øµKwÞZÁa ±íIš°TërvÀHƒòÕrÈ-oÛ¤L6@{1eçÇÚçà–cp‰B ¨NN¸�*̺:‚ˆÕÆÛAj`¦N¬ù°ö¤…ÂF­*r!H ·#ßn/:¥uW; ÿ`ãTBJxyÀEûìéúÌ´9qhîÒÎÁ*í^vÎ ˜BtÅŒ,Ð)"Ñlà™°G|ÖÈÕÝ¢Ë#ð¶Ä CI;‹\»ø²ÓϤ�ÔKùûÑI꨺ ¼#4º=IQ%©5¿¡Ý¥öoå¹F…EG”s¡@|™}´jGÈ™¨TDPÚí棵p¸îï¹FÅ¿ö»ôºW�?“W†gÑGF4 ¹�OVvYé‘VÒÙa´~*Ä…�Ãgg§¸ví³ÿ 2È #3Ù¸$®¬ À¸$–i¯YPeð;O½·D.ýàK¾ôËð}ßû=øØÇ>ŠÕ0ô ÿ¬3ðßIqžÑ=à}®£©¬-F§Ì;“d›ÇT¼_4Û{upø¯‘wƒÄ È"¨…Y8”¢ln–Ý´ÊÆJ¨èŒš³í�í¾ú3,Ä…üiU†**˜Ü]¬¤d9óà|Ù—| žzê)|ügw�ï� Ó2ÚW ›õñ=e¦¡ÄH’jŸInUOkS¢6Žðž÷¾_üþ/v7k�>ö~à~å¯þUüæ'­s‚hÓ!Í`³¨Ât·Ò_ hï䎲¦èÇ�y¤êZ`ã,»Ãˆ«:{]!�• {›íöÍ?û³?õ _öe_õ"1­ÓÀ€'ð`4³©ù ˆkÊøiòh wõawÝX‰Ö¶ÍL3BM餓Ïm½**aÝ`ÎÈ“ϯª¶î„ƒÉÕ1 €F¬TÌ1€z—Ç!ĵ�jHZPwH˜ê �PÖ8e‘sÆ”3Æq´8ŒiB�H˜»Ÿ«Ö+¬Vkw2圇œ§ÃœéÊf{ñÆÓ»wÿKQý’]I÷ TÖ¾-† ØãøÞ†ø}Ùq8§êpÐ}|!~HTÙ �v¦…zÎ;D²b»ß¹7µH¥ ѫíÎoõ8ª³>Õ>»9 ôîTÿ†BÈé%ÿáãöy.òC 0\"¶×êÊ a¯žþ-ÒhiߓϵfÛð0Np÷øV¸ÿãg§·Z¯Àfó(’§œ'Ÿè-2cX‡~XÈäe %lób‰„Yj©¥–Zj©¥–ZªÕBXj©¥–Zj©¥j�¾qùpµk¡]3@#‰¢*Ž ^õ±ˆˆˆV‰Ó�Hþº¢iŸ£UÄ;—“›J‘Ìä€MµìùŒIL!&˜É»Q6öÈ6fÝÖVÜb¹XŸ›6ÝUýЙ©ÂÈÈf�›üÄ}ÓYÔ2fk>}K7˜ ®M•É HVË%öMÚÄì88�€�cÑ¢Ûö ¹â‚ì $Z`)ÑE([2®}#;µœ•<#ªÉª½«êŽYl±ÝdÍ6àΔÿhTûrñšæ@wSßÚI°ä.÷h¾ _ÉE„™s�]I»ý{ï'úߘE"ähŸ½ÑTÅõÚ{òKûô”/ ŠÎÛÊÎ{⽡³^6/P°¤ž¿èì|5€–¢{\¤'LãÊPû³Ñ.7'–ì ñÞžÙ‡mfšå³S5–TñÈã�áÛ?öíø?øxë[ßÚŽÀÿ¬j*tUÿ<ŸS:®úÿ»Ú?ºäŽH êÄW g'+Ui y²á0¡`š2¶ãÖ€Ú.NtsF 9°mí5MŒ4ŽVvŒ”¨é£É‚• ø¹f쓵—õHY÷¹k@ßþ-WÂå †Úߨ·‹fÃoJt�&5uíÚb‰¸’é´ŽÕ¹›,ÚXÑå¾rR�9aXø¿^¯ÁÆXMÓtàÊùùÝ·œÞ½û_‰È{ÂÒo¶4ïh.óŽéZ¨ÿ­“è:|;Fº@«{UÏ5�›â€ªª½QÏzÛ±ú¯¯ï‡ý@FCç@°O³ÞP÷¬!z7ŸnÊ®×9�ëPm"1hž�Õ]ÿÌ ¡Îˆ²kï×�4¤`oÍ,(áòn³×a`÷oØ3On�5þµÝó×¼öõgÜŽ[‘Þµ±o½¯"Uf7*¾�ýEá:gT;acÍÜŽ6ºás ¨j€�Uޏ ̦®í‡ÏÁ=¶žƒýð޳lG¦ÐÀ… x#QÐ{êý‚[žx'ö'3!dïØMõ#¨{Ð Ur[îð¼�¡Ó9ˆíÊèŠ{T×ë ÙýrÚ„†¾@LÌÛÅ¡¹š¿ ˜èÀøBÐ~+3‘ß~rÁΦ3‡ rþF´ oŠH!g1µ±—|¬E‡ŠÒA…_Ô`? 2×O¾ï‹Þ�ïÿþïÃïüŽÿ†aèÀ©þ·œy­1¹s@1Õz9Q½ø_~ž¦ÜÈÆF‚8Ñàâì ·ïÜÁÉÉ ÎÏÎpqq�í8a;n!ÙÔÈ“x �æðüÙAP ç ã˜!:Up™¢]Ä Ìäàn²|òÄx@JfSž<û¼9äØ\³V88\ãp=�Ó€i�ÐÇ \òÒË|â;u®N„TÁ|ÁSO?…' SVäiÂÍ[·pëÖ-Ÿœ`šFsAˆùÞjĽ)2¬áÑk×ðôSOã©§žÆáÑ!H£L8;9Åf;¹ÃáìâÃjØœŸãøî yôQܺy³º!Ž]!¯èÃ/¤zñ·© ò.=Œàµ§UqM9é˜G—(º<ô2ö·˜íæâí¿ôó?ûõ_ö•_s�91³‘(‘' À‰n9[[šZ{FÔmLGs¶6²^aHƒ ˜1Ãuβzå±^þëJÞSílÃã}�JD€‘)}Ì š'Î]„I.Î1>Fuæ>üo}(.Ogöÿ×!-ʡ٘üþ%FJ‰†a`f^©ê�ª^9¾sç§'wÿЍ~áÞ;Ðø%ݳÂ>õ� .'Ô;”5…ΚYœ: Y¬¶‹¶èDÇ@Þǵi™WÄc4\ÈÎÜú[u èÚ†î\»RpBa Sk Ç1Ì%J÷Ïcz éµuÔ}žüÍ]¬V÷8ö莀¿­y–2£{{Ô>¢=t?{ð>ªûÿA <¤�éW|å¿ÊyšrÎyš&ÍS†Hö¥6»ûÛš:I�*+sÌ8Mõ9îæ±ÔRK-µÔRK-µT«…°ÔRK-µÔRKÕÚl7¯ê}º'Ç’}Ã×þ³ ™zϲ.IUVªtHDG*ÓAX«GÛe«¹½åý-‡ÓÀ. ‡eáJ³ë/À·� ©¼Ø”Ó ß.¹õY�=ÓØ6d Ô-@8Ámún…Ìu™kn) °Íñ¬¹‘$¢åjÉD&W×…¥“XÉÎC“¿Žªš¿(É °Ê” Ô2í““à*v v¹Íò�ë†w%e¸Ñn}B‚ox'*"¸V�Ûr€µlš»ò®ª°ƒÝqü|tV¯Í¹TÝ£¥–I[Ÿ¹“)bÕüײ‘bŠ¥ú>ëýaw¤’2ÀjHÀP,�É#˜-»—‰‘1õv±3¥5]f9^Ϲ¼UƒEúÌ│âŒhÇv¾ñeeü�^�Õo‘õö1•¸ÕwØÐ&Hg‹ÿHÜ2 4)Tìfì4s ¨n»FÚ!*~wúƵ‡h(U’…ã`¯>…ø<¢+Cùqæ°niç_.£{¤–OOÐänEñÇí™�?çÂeRH÷¬(ŠÃ9TÀ �´ÑÙ £ ªÛÅÌR¼SUÎ*;¶þ�$#5¡²ú–cΕŸŽÓ)¨¦çvÓ»vÐî&ã/K)�8UrDªJ­ ½·!Ï  ìm4Îì:®^½†oûÈGð‡ÿðÄ»žy*Ø_ûÿ ü/ ·T€vìËgÕøýÀÿò§dSÿŸŸŸãöñ1n¼ü nß¹�7oâö�cœŸž`»±Ùl1NcS,ÏæçÄC»÷j}mÜŽš§ ãp §ð¬ì~1à¿J+³�½ÉÀÐBÂ5‹lNŒ£ÃC¬1¤²fl6[\\l°Ýní3cµ^ãh}€ƒ£#¸z…ÄfÙoüs3È9c;Z´Î#�=‚ÇŸxëõ€õúëÕ€´ZYl L}>M#¶› 6›Ó´Å”3nݾ�›7nA<g'Œã›Íççg8??Åv3âà`�ƒÃ#€€! ØŽc�«� æ,Q¾ªË�»˜ì¨ÂQÉPÑV�#±.¬¯zå|?FJì«!zC÷Ì4å]Ï=ÿÜ÷~õ×àÑ1É"[ÙZSŒý©·�·u�­S¦iÂ8eH6Ò'ë—ùëõ!Ö>Φª(¹g2ý}«DNYtCÙãUâ|‡à*CU[�*K# …{ÉNP†ÁjNiš�9y|‹‚Ýu†ØÖ¦Ì©’càão²“)-��Œ3SR�*$ û˜_ÎÃÏ{ Њˆ\¹sûÖ{��oÿ?Eä�ó¹hŽk·žÒ�¥F™3ö‘UêhM³€âº¥ŠÔ­iÐâ=ÊZNvÒ烥ý,Ö¢SüS±§Êº#ªú)�ÝA%Äh›ãZ¸Sí%?ÍgùhlÓ­ ˆhÆŽnD—Î `î(€F8Ô~mXˆ*q.Ÿkþ/ÃÙ{’Åì)‡Åá¾Ðz=ôžç3kGW®üíi’É•ÿ’'‹ºÉ¹Æ”2†Áæ'v«±�íèn2)­°Z/[ÜK-µÔRK-µÔR±–ÕÑRK-µÔRK-Uk³ùÜ ´q…àjX�V\UëѶ÷–Tu­ªW‰èšjþPS¡º¥úüïv¥4(ΆvM]ù˜UjØìÿ¥.¨\ °ÏÙûÜ6ÞÔ�d€9 ñôa‰›úpçqÏ=v ¾›fëÏ)!¥¦ŒS-Õì`jÖH $Œ^:G;d™ôÌ (¥  íí³;ëOCg«?*¯¢cÜM fÙªm¾«HÍ|6õ=#i¯FÞµ\¥F€›É%#¸Óü‡�{�TÁÿ޲¸lwªyª:Ëîšë;{åUÔw-b¥H4ä«NÊ&3q!s$ Ã`Š×Õ SžÂIH½Æ‰)¬ÀŽ =X:“·ã‰8^…ìsÙrjgÖ¹¥8Í€ÿ î¯ñÁyÚìý#ø‡�¾Ø�¯~0#θҚ¹’)Þž#Ô‚•ƒm±Ä°ŒÎ‡xnõ[�Šb“ïFäHåiˆ|`b'#\2Æ�dn£\Z8u ¿ÆûHò£ˆ Ð ÔyùF˜½:�T§áò¼´ë_åBKÖ·0 ÊM¹#hvî‘н¢(&#È3÷¨$‹Ð;g‡ÐÔC[�*óèøP,Ü ¹ dÀìReÜAdµ^U"vT1¥½âWh*IÈU¾M�l¿{û;žÁ÷}ß÷ỿëwáðð°Ž"m ¿ ü·ñ¾ùÑÁìâø_É^ô»=z–Üýîâbƒ[·nã•/ã…ë×ñÒõë¸uã&Ž��qv~ŽqÜúüèêûèêÆ Vò%:C³Ö±&‹ZT€“J´<C‰ZœÁ”=SÝb Ø�O¦TÉ…Q@z•\]R˜ ) •š{Ïdë†4$¬Öþó€Ä©ª;‰P�;NÖ‹d(ÈÈëààà«a¨ã‡Š`œ¿gãvƒÍ¸Á8fLã¶Æ”¦Ç”ªØl/Àg§Pl·[œžÜuð¿ cIÛív…kˆþȦpD2Ò   1&4›§¨�¥t×Ó¦ÎÙ;öìÁ.<µZOWlÎÏßÿK?ÿñ¯û’¯øÊ¤":å|l‚\™D¤öeâˆ�TÉ‹™ÌŽ[‘±7˜¦ €¹,ˆª)w×+¬Ø¢T\áM—õì/"'‹•JRƛߊKEJÖ7ú9ÐîAFöcXÛJþ¯V+$�rÆä¤•\ï“VV+ ƒ½žC…j¼…Ewd‹�’MÀJȃ˜‹“Ÿ*I+¸R‰9烜ó¡B¯¼ôÒõ¯?9¹ûçEô Õ^M^æì½‘ðu‚ÐDt£+€׈B” .M5Fw¢Àæ§Qcœf1:¡-|�öÇÛk|�êÞï @q‚ÑpüH&ä€û‡X²J‘þ�´ÿºv¯Ù½�æçµïzÐ;™©ôm4¦%Ì?[÷-3¨Þ·oÍcæ=rßù¾Š€³w½çý?,¢£ˆHžS¶¨4©ß+æÎZ‰uY¬_NS!°ÁÝ–ïòK-µÔRK-µÔR±ÀRK-µÔRK-Ukû*€²ÕΔRU;±47ÛŒëH‡P<¢*O©ê—¨À)ØÐ¥QÜøk{|å °ÌÁúßÀDS|&~¨ÚÿKÝœ-™È= í»J®öª�Ûí›Mµô›’’ Ä®Ëh‰ª½kU�N“´ÜÔb¥®fwi1ÕM5O¬`„ ˜Yf:íø‘úÝpëèøo€’ç7ÈÔ€¿rC+ ®êTµ|isÄÏŦÙ?MÝ% Ùõ·L۪КM}Õ{5•)Àšlóšeæ°*øÝÉPGoO‹™ýow—fÀ@´ì-ç,®h3é€S³§6…jÉO~äÑGp~~ÞÚcý4Û|nBõYþ+µmö*"«›Êä9åÈ ùÛ]þsE¼Û•¨WÚ‡û�™qaØlÓ‘Ä@ÞÇú"pU4ša†¸*_AÉ€…º™n�׈Ï(ä×¡È-{ &�UËåØ Ñ„©¡;°÷g¶¶Jº›¦LŸmkÑ0ÊìN%¨Ï�ÊX„þ9Qg—�iÃR/foU]80‹Iw¨o7¨dˆ]fÈ/ Hj–ü³¸æpoPÝ: 0AÑŽ¹Œk¡Oγ ç7¼(ö�Ž®6"Bé§h€úNCq‹mbBòø…aµÂ7}óoÇþþïÇ×~ÍW×{Ü�ÿJd·Î¯*×@�! Œ£YÕ±{¶FN°k›r†ˆ“Åܺ~3nq÷ø.^zù¼øâu|ö…ðÒõë¸yë&ÎNO«ú”‰]+NþþÛn5ý¢W¿–û[Æ6Í‚œ§z†�«œ¨°úýQ€Ä', î(n_ÉoªÈPda¯ÙžÄ 0,¶sÍ9ãB.¡\%·|u#Œ˜dª”ë´Âj½ÆjXY=¥Ö•D1ºÊtGŒãÖÁY#ðYÜ€Ç,u\�óeÂéÉ)nÞ¸Ñqb\ô߯Š2¢ò¢ •œ(SwB›'wб4~œ«ä’¶='þ]Ǩ@¿ñÉOþÀ—åW}|„N9OÛqš¶Ó4M¦\‡ã0¢!ˆk w'QŒržjHœ ÅZßÕ÷¤PM ÊŸÓz•¹œÜÂþ ­k«”Ì•‚’µ–„Ä#˜ c±ùaŒ¸—†ðÂzµÆp°aʺðµ�EDÕ;è™ã«ƒ5ÖNX)Îã$àiÄ4•1,Ûäk!&#  »{Ûz«¨¿EdÈY¦i<"¢+7_|ù;ÏÏÏÿ”*÷�ÿ—UGŒ+úþQ=ü܃ÇÑ8‚�ö%®Ê.±W€Î�6v˜ê~{¶"êç ×°C2ßf㿆åR9^3Ð~¯s¡·ìk[Ý3Gé,"¨}'èÏ3Îue^ÔH¤ ÞëËW¼‹�L³óØYÛí_KõÇyˆï�ð›rôÕjýž~Íën©ê¤f­±çõí»#Qùbä[›“3²;¨˜eù"¿ÔRK-µÔRK-5«…°ÔRK-µÔRKÕš¦W¿!«³Lu"³ .ன¬|Q¬ UMVrUsþ�ªÔƒ[è& •λäC«*èl¾ PÛT�äIÀ=ÿŠmy,5€�Ë{´äTwAÕ’Kƨ+A³©*µÚ‰ÅZ±Žå¬˜>Ï-³›u© ñ? fißâƒÛµûÏ—=©*û¢n4`¤�±GuEª*’/†d›ÜLQöÚ(BH6 |AÓÐgoáße¶–ç]^QºÿU±G-”Ë­–Ý„ðû¹RÛÍÏ8I]K±[.³ÍGö{£`㨚ÛC¼¯Å›“)XÝÙa¼æ5¯Ç+/¿R]ÊI×Üö|SËzŽ®óÍiõ |¥ænPÁÛ>@û¢ä‹ÖnÏžK°ñE´{×=@{PŒ‡Mÿj³Œ ¯®þgµÉ6àÃÞ× ‡¸‘m¤ŽÉ `òþdÛ ¸×׫ÿŒÄA)Kp‹mïÛì–Û¼'–�šâÛ”ÓÒàæ@è;�µ R$¬»iQTvö¼Òhq¡…øäׯÕ^º�W÷®D%·’Fs?h�†*Ї¨ôŸç/ïÍ&ë—Aw3à˜�]Ï­=»¦ðë�íÏû€ „¸ƒÕz�ãȤÍ�ìQ[…„¾ÅuÌ ®=ú(¾ë÷|7~ð÷ÞôÆ7vNså?°Gõïã_ý]µþ—–õݰ Œ_K=2 +D&œ��ãæí[xéúËxþùÏâ3Ï=�[·nâÎ�Û7›Î©DU Þï•Ìb0—`š¶yšl>Ab*MËïv‡ÇiÄ4eH+ ¥Ö„ÕŠÍŸ©*¬kŒä–â‚F˜Ð@ŠCp QHp"\uJ܆2U'›Ð# °]p�ÏZ¼‚õõJ_Qu'�âÜÆPñsËR•Ùã4"çÜìâ3cH ’†Ú¯ó4áôìg''˜¦±N›š¸Zãb!ê>"±õcë(âs˜vq-Í–"öª5Ö%¶ÿè–‚=sÿŒüÕ»o ®ËH'§'_þ‰_ü…¯xæ=ïù U=…êiYW$Š$žùzËŸ¸­i<ûÀF«Tçk³ÖˆŒM~Ø�¬4@ÈúORnä(R2ê�¤a…a5€S‡ˆpŽ€”�Ò€a0¬VX{ 3#OF)C¨j¶ÛË6J·�èpE$Þœ ã®%*GT{G»5 hR‘ƒišŽ˜éêÍ›/üÛãvü÷åËÀÿÿªdßÍ|§ùÜTÖ Þ&µ´ºi�‚µ};˜s[ºX‘¸âèçŽÖ £‹fk™ÉW]§×”Ý÷×¹J{‚çŽßSŽb¤Eq ›Ç%èœ×­«U1‹4ë ¤ýš‰f÷]Ãùß%Vþú –ÿñé >Åk½äø|¨ÿ÷]��ÕO>ý—‰h P&R!'‹+ÛÉ›CÛ Ãj…Õj�a54Ò¶:±ÌÉÕêóS‰¤Yj©¥–Zj©¥–Z*|oZnÁRK-µÔRK-UJäsQO¨+pw°«šÛóëu` ´‚ˆ°ÙÿË"~DdüF�™�D®›UY€„ìq‡~¥ÙäS±º¯nÛ®LÏ�V´زMËn9÷D¼³)jÿÎ:� b齊‹�) ¸(ïÃn^Ëb¥žÚ?UÛUÉ Ï (qûTE%AE=£¸åÐ&Aç¶™þ�Üå¹'° 3$ùÏB˜ü=ªn}˺‡P¬òiçs€¶mjÊæ¦h5ë^rBÇÔ„Ñê8*JÜòiÙIòÞíûœÚ¢7/ÉìÄ̦ڵÝe#<¨òDÀ0$VR³Y?õôÓxù¥ë-¯v'ž�*†ÕòëÛl O×£ÐýŠæíñµW3êªÈ®:y¿ªÑŠ^Õ^b6((û4Dø1U:[w%5�ž¯ê6÷`Ç,,�Âß�£’‡êRêë:Â@ÿþÖ“M)Nžô¡ÅRº<·`åOPwë ÙÙšýüZÔϯ¨ÊEÍI�Ü­Ï ZYÏÈ*‰+@ãw×ÒBbªà Ïîõ@ S�ä@}zÚ›SPp¨dª ´µ�^ùO}~ìÉRÏT¡:³à@zì±Ç!“ KvëàÜÍ ö–Ô+ü}_ø…_ˆïûþïÇ÷þÞïÆáá¡Û™ïÿç?ëLõ_ˆüGŒ’ÖÒ4K›ò”!š1M‚[·oà…^Âg?û>ûâ ¸ñòËxåÆ l.6 ü"•¨1P{Ê#.ÎÎq±¹0[ûqBžFsf¡™•3Ť�B€s‡‚hůÒ+î”À®–f¦’Ÿ`mÎã3Ìš¿9iЬØý“Yù+� �V%¨¹ñð�j„#ó1Dwƒàg#�jC*ǯüò'¾ç™÷¼û—˜èÖ0¤Ôúê<\/òÓ9@ ¬‡ôÀbD‰˜²¾“*á«€¯‘Àµâä4€(CY‘4Y,Q!¸ Ï0 õ?"BJAÀ_]©ÊëÙÛxu¬ñg¦ºvÊ’!ÓXïs^Oö;±v'bîyš0MÅ¢|òþ.}dˆd'”sG°&` à(çüØ­›wþdÎò{:z\ˆÝ¡{"½aÌ–²ÎОÐeÏS]W5²†¯S {ÇGf.¢ün|$*] c!vä²BT)ãÓ^bè4tÖý±­÷¯ì£.4F*QsºéÁõÙšTï··ÔŸ‘´�ôØyP1Z ý\X®»#qÎÿÜýºÕ}îîC¿‡­wKõÿ'ß5Ó�þå—}Õ×ý 6D¶¦ïÏFHküËju€Õz…Õ0¸@k›•\î࿹w¬–/óK-µÔRK-µÔR¡ÀRK-µÔRK-U‹^uxb±tFR˜“o¨¦¦4/ d.ïA2]ô)UýвÿfYŽ–‘JMîÞ”ýuŸ®Àx˜š7ؼ¢nšòÒ6âÕ7•È-Ü=ï˜I¹Ü³xç¶i(³ÜÏ–eXù c®›òž)u¹õâÈðèB2$lÔI–™kž|ù2EOÉ«÷×µ¼êÚ¬· ; + 4h• @”~Êj™æHFÝ&q}ò3ð¿æ�ºªÝ:¹¨ªº�âšáîêçª2oD±sGVHê€>WU³%D¸µ{yÖ ³n®–ÐŽ£©¼”`~O†ArFJ4apÞôæ·àîÝc\œ_ôJûpüc«#@#6ìöϰÆls�ú¼ß˜Q?ïß5y-‹]5Ø¿×mÏ«þ,dD�@^¨Ÿ™¸v‚-¶d çîêÿ‚ü•€`’B�³è"úûaªÊlj^¨ƒ«-ühU{kârjó>#*h®[¤KB 7�Tû—x�x¾3µasy(¢® o÷NHÁâÀ¼�…Ô‘+ÐH‹æßÆ$k[ŒEý9¤XøÇ>Kdý§²«,ë¹´. /,ŒL†¶ÈùçÔÚ‘–18f>òŽR;Ês«Œ¾Í^¹z�l¹ôã”!2µèæŽØÁÄøò¯úü‘?ôñÍßô �Tòà?v2ˆåžD€Ú·µ„bh½Ÿ*ŠI&œŸŸãæ­›xþ…ð©ßüM|êSÏâæ­[8¹{RÉ4ÌÜ\>T�E°Ùlq||ŒÓÓ»¸¸8ïú?;¦®�•›ÉD:ëäÎ=q¥�‘™¤S·Ú“ ÊœäD‚:þ`ÛŸÃܦ¨§)% ƒ©°)Œ`fC¯¨¥ð¬ÞøÆ7á˾üË�Ep÷î] €¿5RÁûꔃ¯M@Œœy2»úaHX¬ðȵkø›ÿõ_Ç­[·ŒøP«8ðÞúš�Šm©h2g�,6eÍqyd1ÞÏ-œª¢~>.Û=.. ÍѦæ£ÓŒ Ô”ÙºlÿßÊšJÛð‹ããã¯ø�O~ò=oÇ;^V«53c(ŽIª§ ÓÖœ"JL„õ™¬Ök À|ph. ̦Ü]¯À)Õ6tY6úÃVD¨® È!̉ÇÚTÿ“»9”¹Ud€ LSûâ´(ÚƒÙ…@)Y,2bšjœÆŒq;!ñD SÖ/±ÝŽ·[L9×h„Ò÷Ôã�ê"H¬¸ð‘ÈôÆÍùæÏ¨ÊWwÏ0Ù ½Sãì7Nar· š�¨èÚ9)±�ÌDÂ1ª¢¸qõ xtVú�<ÐãøSÈ-¤Ô‘æ‰�5ÿÞhšxܸ¶i‘:¤…è0örOUz"hÄà qa§ÑÛú‡³‘èГ êÈL}—݉Øs}:ûÞ1_G^²TÚûœïþëcÞÊfïØ«ýg]ý¯RJ怉(K�#„Áªµÿ®Vê‰Ç¾c ¢£ û2¬ìõK-µÔRK-µÔRKµZK-µÔRK-µT­^–ÒKìEçÿ6·þg¶Mü’Áº[•,�¸*yüz¨x`¯2€öš¾É+YõD˜£@êŠ�{±&·Œã¦ú&H̓nØ50µ‚YDUìÉßg™ ¦X)@²�ÿE/3|“*p¬"S‹*(» M¥ mÕb¶�9ì*öªçë÷8qÍg®÷ Ä**IvP•ƒz»lêSÍ{Î"-ûÚN%…8`R2à{—€>¢žW�@ÚPWø:8Vs§ˆà ‘€œX ÂV¤9ø âö͌ö|í¶KkjVwŒjŠCrS²¥µ�v¦Êo{Û;ð«¿ú+È]ÄFï×v{ ZæyP«Ç¶WïÏg*û % ³ЃnYÓóöé6UkN*@¶‰±>W¯­ÄiÌB³+IhvÔ–›�³)&Çq´¼î)C‹Ê[¥�¬¯ª:iô¬- ÷ÑhÒÚWõIsr@â„Tì¦W+˧&'iؘßÉpoä�vª�ÐæÀ Ug?Ï.½´‘B²*�æV€‘á ”=+^ �Ñ…ìÕuµ=cdûYU£ßÄŽª“`ăƒƒ5{ì1ˆ¦û,>óÜóxùå—pvvjÞ'žuLlã/!çwŽ�qçÎmœžž@<ÚFBºƒ»öÁ($�> [Ü¥¢kÕŽ`°FNpp·€‚”‚#º9—ª]}8r Ptó(磮–ÆÛH¼ñH…,ZÁð¹•ùÛÞö6üGÿ—ÿÐÆ‰iÂv1nGl§ 6[l¶[l..p~q�ÍŶÛ-¦I°Ù\àâbƒ““3Ü=;Áùé9¦Ñܶîö�ÔÇ»‡Q×ìN(#S6»™Bp ãT!¾0¨[³t®Á1§€ÐRâ@B/0íu†)Ǭsù½¨Jì ÊŸøÅ_üîw<óÌÏ0óÑÁz=¬Vëi`†fÁÅæyÌÙ"çÜÆZa=¬°Z¯<&HË€T£,»¨¹s»(®øziÿÐ<í�ÄI‚1?]¡4[þœ’×b©Ê¸¬Ì¾ÎDèëN�ÌÙÇ—ì¾Í?9g'–<1ÆiÂj±ÙØ3�&Á8ŽØn'wå°¶YÖ.ó‹ Êÿ1øê”§/ÏÓöϨê›d:Û7¿µ).xF×çPÖÖsÎH™«U{×¢ÞF¿��ÒšƒÓ3òaX—Ipªý*´äŽ\ qléí+jÿê€u[£Íæ$„hÝ_ÇÈ@ª©DÔq­’WUƒ`_g»ß ªÇ^G€Ý;»Ê‡_ë@ïó›}ãBM$y¨OÚùœ�ˆ^øª¯ùúfæ-�D$̬"âñ@ö½(¥„Õj�õÁ«ÕÊI<@ΊœÛ:Ø\:Ã`.ð–Zj©¥–Zj©¥b-€¥–Zj©¥–Zª- †‡[Ì•?Õ*ŸM¹aêªÊbqP7¼‡‰èÀU‘üAQ Vþ€)µìϢ쪆U6–ªZҳؙ;ûp‘ì™ÉͺØC“+ôÅÿ�Ej¾{b³¢Ÿíiî­–Îë›®\Àx®›þÙíŒ pq[e»�fˆ«dÎM¥éŠ+f®6ñvŸÄ³0=U°X•—5´ØgSÛK5à~² z‘\ø3"Œˆ¤a¨VÏ òŸtD ¾Y®’«fÑmC¾¾�f›®n%N;)v}Å&׎ÿÉ€Š�ö4ßÚ yÅ"äyÆ\76«Â¬ª,�T6 g–µœw`ŽÅÕÊþÜà*$(Œ@"Šb}p€·½í|ê7?‰iÊ{”åÚˆ'³ÖT?WR÷í­éë0sňà?÷�ëU%>×�Í¢Ø�¾Öú‰Mê&;›‚‹")¨7îï@�)OÊ�cJrΟƒB”îÓC±«Z¾|„óìýÌÝ#J!ÄÌAÅÙ¸kÙÓ œ†J€«Ö©Ža® –™šRçdšf²L!&a¾ñ_­Ö-W¥æ‹Ð2ªŽPLýg;é£*ò¸¹?¨¦³Kžß¾8£áC{u�ªX¯Vxìñ'̹Ãﯩ7¥‚IÂÞðF|ß÷~¾ç{®]¹Z•‚þ·Ïk ?îO€“·€’;…`»q||/¿ô ~óÙgñ«¿ú¯ðü /âÎ�[7[‰“Ý{"¨dŒyÄùùwOŽqz÷Ó4uÙÒ‘À¡0�BÊ1kzé»yGm¢ö˜ÇÍ D<BQçãR³™ÝI"‚ø•ˆH#n« Ù$–sÔœ—IÒ®àäät�Ö×%"Gµ< k¾É¢Ìbš10�2ƒD‘§ÉuþeM�ÝÆ¨ÞS´Qg¤rÏ�—Ýe&‚ö6ON¯ývÏhÔ¤ÉæâÄG à?Í'³ÙÚì^#UϬŽoßþÚ_ÿµO¾ýï|çu=pÁÄYZ F>‹*R²Ì탣5ÁÞ†eS¢óH§•ì× fCÍükÑN[Ô†öò6Yÿ$w!Ê´÷N¨Gaä\ñÛT õE÷)[–ciÇ1h÷!œ}è›m-Þέ;KÕ{.Œ2Ù_W×3Ê2dFéWûV4´g-‡û®­ÚúìÁ—9ì�8<:ü›�<öÄ3o‰i""1ò ‘œÅÛSJ «uQÿ¯�R!û$M= ‹mZ­VVË÷RK-µÔRK-µT·ß´Ü‚¥–Zj©¥–Zª. ˜+³:;v{E³‡çäàJ‚*9È*˜9k›ê‰ð˜Š|iýmê]°�éâ+;0äŸKNhðªj±<¥êIN§4x†¶mBem1qï“Rn•‚ªRcZ;ÏÌM~O¨m&Ã3ç3L]Ëœ@H¬—îhS¤�ÔIjª¦h¡ÀSž'p⪶�•š^HTÉœð sà+Ú`û³0pÒÉ)YTƒØŸE�1�Íî¶lÎE5dJ©�¿ns…Y^wA–óÌ‚¤ t* 3žÅ>«@rh`_Ó©6@Å3Ò+ø§Áz—jÖqm‡ ³´eÀ•«GxÛÛŸÁ³Ÿú�J¨ˆÙïLóMÔ�k�žPôrT¾öxÚf·6kôQ Íî½k¨†ô³Hû£Sp9ç�;n@ Š 9<ÎÂÉã8b;n±Ýn0nGLÓøP@ÿn¼w�ºäÅŸK5+Ì7ØwO„Ú1`ò¬èÍ&´} ÚW¯×kâà`mí–Kä‰Ä§ž›¢‹xíPô.“èàm˜¨Ã›p™�aªf³ÿKw�9PÝÆG�YËÐŒôSúaq´ m­zµpí±Çœ`dÇÌY\=j ÷»ÞýüÐý|ûG?Òòç™»lõ{‚ÿm˜˜Ùûk%'‰ ÕíßÎE¥^îéÙŽïãå¯à¹ç>‹g?õ)<ûì³xéåëÈ’=s>UpCLÓˆ;wîàøÎl6¡£æÜ >î°€¤<«-9Å#(jw-Qô lGs[謲‹K‡Ruq0��3™úñ¸µj1þ¼bÛ‹@VS·Ïnm%�ϤC÷ŽªÀÉÉI÷÷Ò˜÷�+D%Æ@ ¤q»è”VX¥ ’ÂÉÜ`˜ëZ¦¸¦hqÃPìä2ŸÙZaœ-mL!�Ùá‚, B®ÎCèHR3€umÔi˜ áýÚ»—ÌîWO;ÓËÆØô‰_øùß÷–·|á/Bé”TWºµa*kTþs"¤•�ÿGG‡8:ºbBÞNi‹<ù:ºk!Uúx°='ºÿÚóaËú«@²Ísâý³­)Úýeac ÀnÎÙmü¥�¹ì±N\È¥Z¦Ñœ( ±mr'�9QÖŒ®At@æ„õÈf³ù÷Uõâ=iä.ªŠs¢}7…p:+‘?³¹¬¬74�cÒ`ÜÑgá©M:ÌïZ7…0€ÖZ5Œsä^Ç„®u÷`=ÂgÊ à�]": Ž»qívû2sˆîÚ�s»í‘fÇk±;;˹Žô´d¿WÈí9‡û­Jú×Ïý.omtŸå“6#­ÍÛŸy÷_eæ‘OÌ,…˜œÅˆº’­�™SÒPÝä8±Ç I D²ÿ=¸-1/_æ—Zj©¥–Zj©¥â>ÿr –Zj©¥–Zj©º0¸—@P«îÚ­—• ³^M�-u̶Íq Ä8Ìãö«QÕN}6¼ÔcuçˆJ@ÑL–ÛÀÑ.çµnptåϼëÝøÌg>�S®¨;Ï,œ¹eG�o?7œ¾ |¡¯¡@°¥š¬ŽZ’;öSÈ„¯.ˆ`oP¡’Å1ѲfÅ=n1n·ØŽãçhÛ�H÷¨ÝÃèö¹Ú`¹ï�#höOØ·ÍÿåAˈ›ÍwïÞYîÁ�©âÖëÚNI›5A4 ×k ¹Ãâ$Ñʸ½ØÆ{aËãui¦:Â3îžµ_Érž "ù¤´m¢ÝgF@*`ÓÁúGW¯A³eÑG{ùÃ#|ý×ÿ6üÑ?úCxÿ½D )Qÿ[¬‹>˜òmç…þ^\h4Ÿ:0vÏFŽ þ§ˆæÂRþ®e>"!‰¨‹°!®ÂížÛ¸.~%ÌóaàÆ^¼ÀÙÙißÇd×XÞˆ ”RóVöÙÃjÀz=`š†–ÇžsX卑Ë�»}Ï>O¹Ž]êÏÞÆ<ôX†*ĉ�"ÙâeÜÆßæö2wg°&‰‘êsÏÈ“�ûP 1<€™l­ÉN�ñ˜€`ÇžÿN ckU:áªäüŒdùOTõËã5—þW ¤Ñ!eͯ÷¾³MAeg$Ãæ ÓÚL# Ìõ}�Suï¤o¹VFZÿ>·ýŸ¯w »Z÷.÷óÝ,.dÖu"�WçkÕç –4Y©’ û¨Ìxº þïJó»~Š=ÇÓËîûŽ½Ï½•þ-Bï¿æ¢Ïù%õ9­×ÿí3ïzßKþçTÝ9,~&‡5e!‘—ñÔ ¸*é*„Õù»:.-µÔRK-µÔRK-Õöù—[°ÔRK-µÔRK•Jn[»¯æ¹ãè’¦òd&ß´Iýæ%t–õ®¤J+fÉÀ,+R©W£¶“ˆ¹¤ €àÍäJ‘Áy†H�”ëÆ&àjЪþ7ðß±b)�«�´5÷W•º¬XÕ¨\o�–CíÀH¼þ,®"lÊ}&­ûÞ½�{È×z:ÐÕînåÎ(–áÍþ6nP gVÏÉ6³]4Ch«BsÆÔlm&�¡o-®äe—¡RS-©³$+”¥Ú#ÇÏ“z?µ•%?»X8Û3wÙØ íc]+Î¥h*ý–5 'V40,´e!Lpݧ•0S1÷tY³íÎ8JDÀzµÆ;ÞñN¼üÒu\¿þb 80bðû¥àUéÁ�’OKñ\À Šü¢~. `Ý,§þ=è,ã58!D· ÿ÷™Ø]År¢7Œãös°ñ�ò¾A—)Ôî�£»WÙö *Ó=ûæz¯×–Ò`~NªŠív‹ív[ŸÇj½ÆÁz�ã#¿ʯûip'_A—âóÜC8d—·{ê6ð²{sDûË(àß–âûŠsFy­€SÂÕ£##¨©@<Ýž�ðôkŸÆïøÎß…øý߃'žxÒÇ5¶(�0ƼõËÁÿÎ÷ éÀÿèø‚âZ¢%9E°9¿ÀË7nà³Ï?�g?ý>û‹8¾sŒ;Çw@¶› lÇÓ8b;ަ0&`ÜžâîÝ»8;;õ(—Ü�1dã›rqK (±�ʉC¶uß¾va@m–ìÝX¡}†÷L¶¯Š™MÓ�¦Ù…Þ @–‘AÝ3�3ËFo1‘ˆSεžw”úBqQl3Bq7+q‚�ü¾)”Œ 8 i°Z›ûÑf³q’\ T™Ã¨ÆÔ{ 9 €ÖÞŠ¢¹Ì—’Í çµq&âê¡8)€À¤js¼Æ‘¹Žù÷Rη¾ÔæŸ(œ3ÕÕ/ÿâ/|ßk_û†ÿ‚I²LÌ<‰J.±1LŒ´JX¬0¬ÍžÛ—|. ^iÜ�¼Íù …uÞ=è\{¸eÔŵµ1×>;ރû"ÒH¡’#”ñ+F,Pž‰üš�@ZÖƒ’¥:”gÇwâ¬UôPI¯�Ûí·K–ÿPUëçéþQ’ö¤·Ýéd¿Ú»[µwCy#×Tí�FhŸܸú/³¬wíæ= !°È]¯dç³Pû™^v±QÀßúzG�J†ˆã�ìé%T6ÂÜåíÖÄÆÄ~­ŒnF÷úÝç°ãÒÿ=F%èý×ú  ’ùÚ‚vcar�òË&}ÝÞø—9ñHD™ˆ¤'ãYßwBãkd®Tçáè$Wç‘lQÓ8-_æ—Zj©¥–Zj©¥B-€¥–Zj©¥–ZªÖ½¬÷"hꯪêÊ”¸*†�5 X©â€H¯h–/mJÔèÀÞ}¶|g¦vl·þ7»Þ¦°ª–ž®üo×èöÿná^@ U k6°GÛæ!àâF’�|Ѹ!§Òl@«*>Ü/ ×PÍ÷PW`xoÄoT.�È�W£±«î ÀS°‰ÛÇ:RÎÕÕan%_®I* Q@zÉ a„BÖ³Ÿ [ŽõÀ 2س2%]C@æ`9¯žÏ›¦ !n*·b#+v£H+KÂA=�Ó`3Jm Úò°[«3ÀÉ6æE›p±÷/œâêÄ VÉå¹Ê ST“–öÉ3å=w€Þk^ûZ<òè£xþ¹çpvvÚõºx‹¨¶Ž°ugç_³Ü#¡)g#Ú:'ïfù_Ðãº5À&¨þa ÈÅù9ÎÏÏ=ù·®öåÙîÈÏ.‘£íÆ@P⯹_éÎýÑèópÍ÷úxUl7lÝ!`áÊÕ«U1^-«)`‹¡�I?š“@â«uǚω4Ѝ( %s7`ɘ[v[»DÒ¾ƒUTÌ©¡<ßàb,¶–A^Nˆ÷¥ØïÌá— \ªû ¼‘ìøøÎGnݺù·ž|âÉsU=eæÓ²îJNŒVo·*Šœ§ºæ!6¥?iq›)ñ=ìÄ¢FŠ„Î‰7ÛM­Ô>‚Éœ¨$g_•—J%yÊŽƒ•�ƒa÷�˜(Õ[Þ£6‰Û:·Ž…Á‰®œLDÄDÄÌœ¬Uõ`§'6ç\UPT¨ô)¦Htq‡�q3¦–¦àIª½^÷ÝÓøtYÄí_ª`ÖY›û fÄ]Õ°.£Î¢ƒ¯_•ö峌ù÷�°Ž.„¢êL¤ ¼WD°=DžÔñ_ûuCo†.VÉSܹtÇÆ_;RÕþ,¢èP¿£ìéÃû\0sRÀ½–Ø?°/¡¸IQYs_ârtÙ§Ð¥«–þ†ÕêǾêë>øóªºEÐñ·çš”÷=V�È„iR°pëÃÁU£ü.g‹ÞHi³|™_j©¥–Zj©¥–Šë°å,µÔRK-µÔR¥î—�HÝþ�Yga¾éî›Âñ=ªüÑaž6_­ªWç±e3/‚Ü»‰§jr—Û†aUô»}fÛ\bß`5å=…Í<Ífÿ«ñ n°Ç´�wQi¯íRB³¦ì}…�Ú@*ÊyK°£'b0 š@ªY×�`„,vb¤T}Ë£Îj™´cÎÐlàÄ0 àÁ�8íä¯öæ©})LiC–`ìŠ6¿t2ÛäÕjUU:"\cØ# DàÑ5P^fºlòÌÞ–wŽJ&Hµ�µíFéP]‹Ì¦!òaÑœrÎÊ ºñXâL¡VÌk 0ÈÚçÚ� �&—ª ¿8¬Wxë¾ ÇÇwðòõ±Ùnw•Ñsð?¨PíŸÛ|tŠM»i­Ú«çê¿TßÞ þ7â@#(€Íæ§§§Øº÷á ›Ï¥æ µ=[Ð*`ûœ_§÷yõgü âº½L‡û×4M¸{÷.îžœ`½^ãÊ•+8<8B�,çq$  ¤p‚e¼¥ ¶Ïp{©ˆ¹z8¸'ê„!´vYºA÷æ*pouÚ–ÒW‡a…££C§ "àüþíú#xï»ß bFâTmþK$@ˆ˜éæ¬û‚ÿÞ!âxm?ËŽCÀv;âöñ1nÞ¼‰ç>ýþÕ'Ï?ÿn¼ü2Æiª„šBÀÚl6Øl7¸yãܾ} çggvŽ)a5¤F°#Tµw!¡™ M†¸-¿cäC™? ‰‰DÐYÊ×±ÄA8USÂûXXÆ¿ ”C Ê P#�I$xP#�ÀAý�Þ¡Q9@Éh¥­=XŽ2G×±®uýJ ðÏÝŽ›™S¸·[c®“a$»û‹ÔöGÌHÃæd$®JŽ $ˆ0_Ìã5ê½1T«’4ÈÀ[ þ ¸: •ùœ‚œµú¾Ppª¶åNÔ«sB‹_é,¿gÄ$›‡ã=Ü?ŒÅáI$}âî»>ðÁoú³Yòm…&f'ÆÀh ƒÍÁ »ê6Aà”0¨bbCú$g'GZM•$ÖW3Üa³ÙtDM2 $¤šˆa� ¢]>ºÝKÞQ_><f/vç ­} ¬QŒüA‰™×̼b浪žÞ=ù²‹Íæ?UÕgêxãÇ¢pøH¾«ñˆÑ‘Zã³T/Ÿ'=öÇÈ”ôÀŸÖµ‹vëÑè²"Æ–íç/mÎKê½õËXÓ„tï1ÚšeK%�, :‹�ÒJŠê®eo|A·Zó±N»˜œFªë]vïÙͧ{ÆmµˆÎmë²óÙ»ÞÐ_Èèý܇æÑ6ô¹¬Ïö¯Õž~Íëþ<€ UU5Ûwk3Å¥£ÿŽ)µ?ÙÏÉÇE�›AÄÖ?Ì Û4._æ—Zj©¥–Zj©¥B-€¥–Zj©¥–ZêóP Ô‰û¢U‰ÉEFPU°p…WEò7jب†š"Ì^m¶½—l³D6ëÙ AQ{)²äÞN”Ú{c¦±TP@wu9¤)!í·ý=ðë-ªÃ� ½”·ûEˆñÛñÅv,†²ìÙÐ�€‰uäß ‹"Èã„qš0�£«ËšRSÈúæ­H6õzTŠ»Â?ZÒVU•[? óŽÃB¬Ð”Ý"¹€‰ i0Ë\ö\OuÌ^ÝR·GUŠûu†HÉ-yÎ~Œrÿ@´'Z7Åç™ÝZc ²Hÿ£ -e']Ð,ƒÌiŸz„ƒì*½È¤ŽÕv¹�h·íÚµGqõÊUܾs7o¼²WIOÔÀËÚö)*à2Ñ¥ÌQ]ÀfïþÖ õ‡jÀ]ì¨ý8gg'899EÎS|L¿¥ãJ÷)¢ëçùó_åñ$÷’OÕW½o�¡8¤tŒ+W®àÊ•«ÁòÙmÊI„\1îã‡WÍI v·ºîráÀ…”ìRíçˆz…�`À’€yÀááRj–÷SO?�ïøÎïÄøÁÀc�>Z‰?œ’G¿›wÛ0ð¿}æýÁ×yFð¿ü~w|÷.nß¹ƒ—®¿Œ^¼Ž_|/¾ø®_ ã¸õ1ÂîÛ4N˜ò„‹‹s¼òÒ˸uë&.6›:&R¤;Eb1À ’6V Ô#=l *6ñÅÉ#ÚèïÌ!ÔË|™ ¤Õ,áOis ÔÛC´êÇLùKÁÛˆO»½v>—ÿ1¨´·2/EÀrÞÙ-Ñ¡¸uë®]{d§×FµxÈ+ÙŸ©Èd€?`¦qê>»�ZDb~¹µí9)d*~R)F÷õ>ÁIT�W42ÃÐoó¬Ý&s –:.P\˜€.Ð/űµK]¯màîÍ›7?|qqñ·¯\¹ú kf>KiÀ°b·¿w¢á8a#Š”3†”�|}‘†¡ÅdÁ/§¨€¡·µ×·yœœ„YÖUæ¤ÉˆˆªN®$�i§9«[³EÐÖèì1^Ý=CÀU½�I&s@`â! |Àœ™è�Wo¼rã>ŽãSèJç}¬åšåPÚ\ÎÌF aT²Ó.þ¬³X„¶~± ä}§š¸hi¬Ñú,‹Q;�¨…60ŠJ¢¡hCOfñ^ÿlFL$éûHYgÕy¨Èöµ™–¨ô}�öx™Íî¿îùœ2~웫ç1L—®Jb´V÷÷8fê=×zù¿îacêžï;7ã!#Št/ës¿ûAJÃOÃ7ëOl¶Û‹<å‘ÈZu&Âà‘`¥-ÄïMS ÛœšX*±¼ô]N®.29O·¼|%_j©¥–Zj©¥– µ–Zj©¥–Zj©Z"ò*Þ¥—üN+øO¾êhcRÕ½裒å«ë»|ªW�¶MÎ9€JngOÔÔöÐ�Íìà¾å±6Õ�íÕ5%‰©ÁÅÕæå39HaìõmìºË[Aœz]ÞirØF~2,BÕݸ§Y�9Ašh‚–3Z L/jxr•~Ƙ3¶ãˆ±äM;X­( Õ÷€J f©j}ªB±ü®¨él¿¶åU—geN ¤d±^ÉI )E{i·Sê7æ ”o÷º#•p³„n¸‰mNgmÄÝ—‚­{Ò[}§_vøFháÑê€KqN€ë׈¥æþ*5W�åÀVÙ¢˜ Ù²�=ú}ôQœÜ½‹;·ïàââ¼ô€vííV—&hw�KÛS@“µ·Ò>™{,‘“&Êf|°óE¸ßD8;;ÃÉÉ]oGÿk¶©>ó/Àþ”ûÏá~ < ´àü´ê2fÊ;ÿ¬œ3îÞ½‹ÓÓS\½zW¯]ëž11ƒƒºµ·¢™ö±ÕO]J‡v*I å{‡Ds€H (¤QÁ@öÕze6ìÁ…æÝïý"|ÿ÷~/>üáoÅjê˜B)ÙX2ÿ[ž0uãÅ�ÿ"�R½(ºEÛí/߸‰ë/¾ˆç_xׯ_Ç­[ǸyëlÎ/0åÉÈaáÚT''wñÒõqëÖmŒÓÖ¢Ê=¡FÖ*C@˜n@ð•0ê«¥Š"4Ä&˜ey‰�Äʼn{À0ØyKQZͦ4weo³œ,G�¢r¯YÛAÙ¾‡ÂÒ츛íl¿Üaªª¸ëC}ô@ùÇ;Ç'xä‘GŒ†ÈBäšIßÖ8@ž²“â9k—}¾ÙŒÕ½¦¶•j®•p×Ç­E¯šz¿�iÞÖäq;\¸:«„ˆ…د՜€D]É^û\ÿüëh¦»cIŠ;è_÷äªû?JÎ�üÂÇÿå·ý¿ñÙ4¤ÃÕzMëÕ iêñD&ŒyDÖ 3V«Ž1¬×F6d@X‘ÒŸ§üùr »ÒfñpkÐÎ Ii¨£SŒG‚jŠk¢J8²�@ˆŒãw%½BÏï5R&�N|�R:bæ+ç§gï:99ùS9ç/oÍyO¦MÀÙËøZˆ{â$Î{uQ,Îjûâ8H{˜HÄØ7¥ô`o±”Ø%ŒÎŸ uý›Âôää�J|¢’µµëàë–˜U¿cÁ/áY×ïmX\—"A�º1ißúAÁ²~~‘BüU�[jOî5º¸€Ë°vº§óăö„8{ÈÃT¹Ÿñ9iûŸ\Ó”9„f»ïâ‰'ÿô8Mçãv܈䉈5); ŸvÚa*QÙ~'ƒõ×ÄäÑ:¶P ¤ }µßc—Zj©¥–Zj©¥þÍ­…°ÔRK-µÔRKÕÚîig‹Ù6ðb>o{m¤– O”0$‘*9Ì$ׯÍù׉ê#*qƒ¶8ÍòÜŽ™E 9÷ÛKÔ”Q5û]yœ�- ´©€Ý-f Ù†yp¸x8$)47À„Èr’�¬À�PÔ²ÅMVêfŠZÎz³ç®ÖÎÄ€²[ËJµnŽn%oÞ¬¡mÃSD�%cš&äþûÀ ùÙþEfùÝÝãcܸqŸzöYüúoü&>ý™ÏàÎ�Û8==GZ €*Æq‚äÓ4AUpûömܸqwïÜAÎÙ]Fú9®ª˜BS�p7ßAl¦ìw�rþœ  Íbî/uNc›Ô²ŸnOW0—1·€&Êä³_Ksu(„ô+ÃíÊáJtNíÂ8Zµó%‚ d>GÌžÜvŸjüD”ˆ#fJÔ7ß¹so~ÓlnI šJ{ €�ŒÆq�"˜Æ2?æ.^æäüÔçÐÖ…Ô'Ž2nrëÆ’H„(ÀòÞ`¥æFñòK×?¦*mµZ¬×냃ƒqHI³ŠNãˆ,ŠÍvĸÝPX?p0¬’�3²[ïÉþ½¸Ú´8†²öz0oX­@™-¶©Øqè[—¸GQX3rJáµ $Ri`w \´u„B•Ó.1%aJ­™é�AWnݸùýÛíö«ªWÛì¦;ññwm­ÒH¬ %Ñi„£0gÎâ»@~p~�ÔÌwÚ™Mhg½QI_´ûj̾ ô$Ï>ª(ŽÇ5îkþW({ö»9H^׌‘ÜY]Z¬V%::`ôûx’Fd*ß=˜,Σ®Ÿj»°×Hp‡@ü±‹æÐÙs×Ý¥í®zÓ…ý û=«²~�¾çßu'pëÁHº'š`ßHR*¥ôÓ¿ýÃßþOÎÎÎ7Ó4Ž"’‰H�’h·îˆª*$k››4aX•µª§ÈÇ—”�§ü9(–Zj©¥–Zj©¥þM¬…°ÔRK-µÔRKÕÚ§œ¸€:{ñøñ·�šÄž‡ÊÄP³ÿÕGrž¾©‚²h xÍÿe@ª‚ê`UÈ+F°Ò‡ƒÿ’‘]ßÔ‰mƒˆqA9Zò‚ÝY ^¬Y¨éE�N,@b ìÖ÷² šZ²�+÷VÕ¬­$é DHðLSß�Õùf5…Z·ìº§Éñø‚gµ&¶ì^·ÉMÌ'…x&lJ`¨PS)Âê½QËFè"Ä yƒ™g Ä­•´ŸÄ³yKæµ�5å 9›{�‘'�*¶ñFµ^픀�hµß§Îüß#"²ý'îíL³Ã©>÷üD�†�[9Ì @Œ<©)EC[D ?4�gÌѦ¢¥nŠC5%éÁÁ^ûº×#çŒÓ“œÜ=ÆT­÷Æzé�5ʽٸSq³h8“ù5+áŽXBÀùùŽ�ï\º©Úq~«F¥ÝÏþœñÿÙ‰þ Ì/ÙÃÏyÂË/¿‚G}W¯]õÞÁUý*=”ÔÚqÛ£ [à ¬.vI*ñwÃj…õz�Õ0 «õûgÞõ ¾ëwÿn|ì#ÆÀ²†ŽxÄþG¢Á«ÿÇqÄ­Û·ñÒË/ãÙO¿ùŸÂ³Ï~×_ºŽq«ÅyéCçÖ?OOpãÆ+¸}ëÆqÂŽÿHñR2òUMOq·Êdî#E‘ÌÉÀfiîÝŒK!Ù\�¬no¯RÁz.ƒÎàñhêXQEÎÙœoêÍV�Ç»Ô93ª¨+4G xÕ¹;‡ÆCˆ,0✸ƒOƒ(曇֧¨YîF+ïkk•Ó“‹®($·0us8vr’ ‚Y§pÝöŒNON`7 邻щU ¬P‰‘—[«SÀ”•fóSP˜ÇnL¾†(Ä­úZ™Ù½Ó.¨C�Û¸GköÖ¡«CÒ4MOý‹ÿé'?úmþèg®œ1óÈyqû„‰‹‹ œžœàôôÄîUè:¬첃ÂQAÖ6Ûâ Š­*@8==ÁÝ»wï?hônÜÿÚŠþÿä—œ^åÙ¼J›>Ì)Ž�ï ç �=öxç=ÏRTÌîH†pjùïÚ”ÿ(×�¸©÷ø�3'¬×üs2ø±ÇÃ>øA|÷ïþ]ø‚7���ÒÀ†CJÖ/“Çœøxw/ð¿œÎC�ÿ ܽ{Œ[wîà…^Àgž{Ï}æ9¼pýe¼|ý%ŒÓyÊuÜL)!�[l¶#nݺ…¯¼„ã;wÜž›zW?!JÅŽÞ�W\ý/Y\9Æ~Ù"O8>ÜBÚ’¢Þu†€¨©ú³4"‡Orw|l1‚œbV 4`�YwP²ë`ˆoúЇL…ë}À^Ï•¤Äœ�*XÈåÿï þ\ðñû‚ÿÛ툛7oàúK/áÓÏ=‡>ûY¼ôÒ˸që&ÎNÏ!"HCèCRd1`áüü /½t¯¼ò .ÎÏZìMwómü.D.¶ïlä"ª' wPÑs"È áêºÂJ抔ªŠYùk‹b�9S¤åí\ 8Ø/®f57/ €²�gÚlú•šm¿tÿqkr0#«šsLyV NêéN_Ùq›0¯q3ØI(M=ÛƒlÇÇÇ—w]o‡)ˆ(Q™òë,Ê”lm '§'�+@S sŒFp#0RTl�õRn‚+¾5<möå>OTàMÃyÄÁ]ãÐßs ؇[¸ÏÎ&D ÍYÓ8¾éGþé?úÈǾý;ÿvžò”Rd"–”Ãz…Už+¸2·ª­Ê~r{æléíýe#¶mì*tàjžÆo(ÇÙ�jð|´”Ù¬3Ð\ˆªútžõJí�V£P¥ËæX*ÖÀ)dÁºò¿\¥jg‹^sê�ÕA=rÝ,e9gWÉÚÆsYp‰Ál�ciÈ -÷³}j&­¸ >€™U²]œYÚOþgÐä “Ùj—¨ƒòÙE¥^@1‘`MÍ•€ªtªäBKØLtQS´ÙËWIú~‹Ðº \€ !š2Ý<»š3E'£ªýÚf±'„ƒ28d¼úF$�Ó€4ðßÀ �p+Çß`¦èŽÁáÚu¨ôQqãXAP"°†¼Ùè�~Dàº!U‰€ëƒ<±^ãñ'€ífƒ‹³3œo.0�cñjf6Q‡Q$¬ÛQPà*Žïw¶·±�výlo_ý­­û�6Ð=èçè«8X'Ëýü�Çx°×Þ½{W®\ŰbÄ@:5Gí ætdP�™°æ@ÿ!aHF6¢àÅþ†7¼ßôÍߌ�}ô#xÍk^SÏ0Uß•ñÀ”ìý‘˜;=ðü¯m5¼¾î2ðÿöí;¸}û>ý™çðì§?�Ï<÷\¿þNNNê1‡�=jØŽ6¸sû&nÞ¸‰Û·obš¤GYJ {qsÖp§è@ΡjÝÝ„ÅZmŽS¹·,ž1Žn|i8NF5ÂmãS�GB ΠʘšS/@c 5²Uå|âÚ¸ŸN™í¼ÔæFâ-ÒÏåuEÖ¯N¸S'™@N¦ëÀ=ÿÛÿ—½‹µ¤ÉÒðo­ÈÜçTýõßû>}™é¹ô°gz.Ý==·æh†-�lٔє)’É/& �a[6ü ÃlH†`À¯–|‘^ ÖmÂ7@DŠá’êÎt÷­ªSunûì�kùa­ˆX‘;OU5/OÌÕ¨þ«ÎÙ;wfdDdìønÏž?‡8)@p –gXr{xøsÞà}“œdu¸»C CèGg©ªcƒ÷Á—›*ªÐ|OõÒþÛÇZÔÞþ+'°ÅCÄ\ö†çµö+×Ë+)qü0x9Wt =Õóýþ÷¾÷_?�)«Ü )í‰ø.10îFœ«€‰0 |ã4 gÁt˜�“Ùò3gÏâÏ×DNu2f²Ï3®Ñ‹ç®ÒTççgs1g‹Ñ€ÑÃã‡ruš1A¡³9nd'5åàè×@þoÏÄ3q"f"f¦`‘QDÎnno?}s}óßÍ9ÿ9(8Ô¾Xí¢€QðÝ»[ûBq†BäUßgNÂ[‚Õ¿Å‚´µˆž<Ÿ´ùy„Ê¥¿¶¾­�œR»IoøÝbTiöü%Ф)åµÞE[ü#  BD$`Arh 'krX_"D# £›ÓÚó�•mÏÅšsu%Ñ,ÚO)Lf1r ¶iüý«¯$ôUÖ̧W_GÝwð"�õ¡qÿoßøåoÿåyž�"2Çw‹Š�Ë”0O3¦a®d¾ò=(1#'gî˹€3ÛñRòÈ j¤¥Óú*BUTAÀS…–xôIJqŠ}¶�Y®K9;âD{@v<ÏðÕ âU$f<|ô=‚¨àx8âx[T€Õi©bÍì䟻ý�×þÝÌ)þáØXÕ—L±ç¾ºrÿ[ó/=½ü'ð gïóôþöo¼õV�Ï›/)þ<@±:÷sb6{ö4 6‡†øð!¾ùÍoâ·ûŸÀÏÿüÏk~µRPï§ds1S2WrâRhãŽ�æ#†¼ƒVBÖÁÿý~�§øàƒñGôGxï½÷ñþïããÇ�q{}c×΄ó³3 ±‡>|ÿ}|ðÁû¸½¹ ä'òõQÑÚÐ1’ŠªÛò¡Í 3Er-(°›Dä ¥„qÞ€°8i½ŠÒž�XC\ˆ2B‰r›'Ñl¾«ŒC*XU@Ijs5â\̧jÞΫ�øÄ='Xm>Ta¹ÌÛÁ™§ÆÏž¹‹,}hÁÖ0äÙóÜcɉXá„Ãáîd”•Û[@ÔB¨jçÁ  ¨ ¹ÙlëÐ @*ÁóÒëý ¯+ f½ Äž¡5E�ØœfºFyñœ°†)öD‰r� “ÆÖ‡»ý—ÿßÿ¯¿ô¿úëßþ¿ Ãx5îÆë!ñ4#ˆC1�Sp‘R'#ÝÈÉÛÞ‰–)'[/&î�œèD9]±K÷JÔ"7T!b÷ ¨‡EQתŠyfˆª$U�ÙÖVI†Z›ëPÎR× %šdH iRJ<ÑŽ€Q²ì¦yzxñøé_˜çù/ªê[Q•^ú~€OxQ¡Þ°Ó0n¨¯wµ�ÿÖßhÅíªEDH]gjs¦(ƒ<® ‘7>j !Àk¥-:[yjÇcâ ²Û×ûwÕµ'HÙ:Fúöн²¸‘„6YâôaDœ¸ hϰKtõ¹\ÜÚßÛI‰¶9¶¬ëT[DšŽåS]ù¬°Î_] hOÊ9uxÑXoNj§V+óÝ¿„ •–j‡^!µ¾3æsŸÿŸÍó|§*G"f[·G€œ3æyÂ<Á (Õù"¥IÕÔæºØÞZœë¨{¦mµÕV[mµÕV[mÕj#lµÕV[mµÕVµÞ~çMt*˜±(Šyž0'fÈ[]ÿ‰�Æ8¦ Ä4»w0 :2óù4~À›L a³ ŽjïòÞe6$в�# ©ih±¡¦Íè¼�W¯Rµ|'æµØênMÄ•ø®òapçŽP*;@ Y|ÓP ”!™‘=ײ*Vê6¨Vkz�ƒÆÄè#åïP°ø‰+ÕΆš\ KRÜx/J~UäyîÜy@šZ}ûK±¢/í …áÏì.ÖRÀ iÜ4T­„‚z—Êë\õ£nƒ�l÷iÎv-Ã�0¤¡:”¤< ÕõņtëóÄŒŸúé¯àOýÉ¿ù�üWà_¦¢JX§éµþ¥­;Ö™¥Dö�®vù˜íNþLé/]Fy¬ËçÏ[»¯ 932‡'<$bË .ç£öyÓ4×ç”.ÀZ•µ u¾I”ê=b$#¹)¡Ð‰T‚Ø •Œãt(¬\šªŸs3—çr{y¿iŠì{šæd*jsw/(‡ùƒï~çÏþâ׿ñŸœ�ÉSN<)Ý ãˆ‘v��)z§Y0Oyž0çÙÀ¾,v dŽC0 †qÄ#Ò0€(õ„Ñõüi‰ˆ[ý‹�ѬFF-Ž"þÜjVâ¶Ž›¦ "D 2&$‘6 ¶†“°þôupÆqÆ]Jé„sU9ûèÃ÷csó?TÕ—øÌ§HÚŠëƒþù³pf¯$€:GkX;y´ÂD`Ĩ_›ˆtsHŸ5šmÍsÕ*q®•@‡8g¶ÿ–<úß‚6æµL <˜ƒˆ)ôã|aãäG¾ðüò/} ÿØéOᓟüˆã0øœ€ þWõjQü‚ÁC#S1ËÁÚåuØ‹Àÿëëk<½¸À‡~ˆ?ü£ïá»çðáàâÙ3ä9ƒÉû¹ëîp€dÁq:ââÉ\\\`wWçöÒ÷ „k@‰ÛÓCš²U¨ÍO¡ÃÖTwŸ$ÄIqE¯®ž¡þŠØ³VƒRÖ/¶#;,¬ššÁªe&sc`w± ûäÀjïzÒÞƒÎN‹y»HÙI×úo±º>ÙEi­Ñ½@—#CWg…ËËË—¹Ž8Q"$(�HZìæyòû» e„ìòò‡É)*lî¡~®êž·Ñ»¿�Ѹ*ïõž±¬þü,óy©Ý˜ŽH)XØÌ‡—ÇçGubÒFBË@ßßÞ~å¯ýÕÿüë¿ðõ¯4Œã��_�CÂ0îŒ@’ÇÄ;>âN2M˜�æyr²¨€“¹Œg;œ‹¸£Sªq>um\/î«ãñNìÎT³‘(9A‡„„æ"’«Ã‘��3rÎ Ê�›H`öî…°bë©”˜NiÇ)�sJž>~üÓ—Ï.þ{ó<ÿVqã‘eUÖ3±£.ûcY·!7ÑÔõøTÆ--޵Jq-‚Þ€Z´Å5gŒÐwC¼Dò(wä64“j¢×ÃIqˆë~4ב>K¾)òQ"úÇ©Ö>MmîÐÓç:Q\,žùÁV€Ð;Qr…jqäZ¨ÿã²­ûž‚ä/@üÞ¥ÀæEþ‡á¼Ò‡Âßi凋eÐrŠˆé*±Liñ{Z�ƒWÖÏâ+ìßJi¸cæ3Ïv™Š”ŒèG3W2p§RÇ«�Ç„”;oKw‘ëÈ<À\ïC [mµÕV[mµÕV[µÚ[mµÕV[mµU­ñ|¬»: –�În�+YÀw„,SžÀž÷j©„œ¢£©ÎË&r©È ª;@Ï%Ï_¯›½Á¶¿5+Ú(¤Š*Û¼GXdv%ôé—í—¶Mz"vù°S{áj™Lpõ£À¬'Í^˜ß^_JTÍ Z{`ÕþSø)7c³o/* v­z‹×üð#\]]bšÅÝPÌmÀì‡ÓñˆÇ�ãÉÇ�ñüù³ê‹A䊘” {k.3Na¯uŠn›ÇªKÈåvð¿>÷²tŽKèO!üï�ºBcY¸àke,PQÀæb§l„& þõË¡»p›éÜ0èT)izÇ7 Â|œà"ªní¯'ý[Cøå³«•1VìÑ-n"þ†Ëtœ$Œ”|®Æñx@b‚(‡Ï(Ï9˜èþÉáTqÜÔËQ9ÜѽƒI— êDàà­6_1 …¼ˆü›µûò^ÔЙår :||ç;ÿÅŸù™¯}íÿ3çù �! C>;Ûé�Fˆž ª8î•qœ&Ló•Ù‰Arž5ÂènŒH¥ÀÁmH¡ýûžç#0ðÐÝ‘(A2C’Íc"ö,›çsž 8ñH�§²ø»?¬ª yOU1ªâìêòò³ÏŸ]üÅùxüo(0F5}kgº¿st±èÈj�ãΉ*I«ÄvÔ÷ø<µ>#ÀÜæ|êÆHŒWquKè€jèÂV¿çJ’[䳻Ȩ»d•¨ sÈhXÅa©{tjñáN!kq`kk¿ }½ØùGB€¯±â<ÛÍ¡u±ÓÆ¥ßkXÆø¥~€qùö¼®+«‚9ö/-ý—‹ÿ§–ý/Z­�ïýœý®'k¼öÚkÿÎOüÔW?p ¦™ˆ¤ô»$¶¦ÏÙH8X<Óu•¿KJ ¼2qX‡n€ÿV[mµÕV[mµÕ‹j#lµÕV[mµÕVµºÍKèS\)ª‡ìÀ¬¡ *‚9g)xò¹É8XUw’å<�_Õw- wé‚\Ũa32b\rßcNª«�s8JÔáQU9rSh18ÒÅ (Ë‹u©oäWÐßr„SB§`)6Ê@´TLõfVò:ÈRN�ÔUá°\è寱m€¹Š�ƒÅrPå«+ŒÀÍ"6U@ÍTE�á6Æ9CŠÒ‰´¶u S!,ðv ›·F0`³íæ„4$�š{ôÔ¡ÈôVT2B|â WThÕ\`â®ýÕ¤�ÉŠ,v=ê*-e‹—èÀySß‹[�ÊÀXÈû[>iFØA‘`ïLÃ6�¥~V�–@T|˜Šuz`qßÃf2õ@Cÿ¢æmq \¬‚=ë:±÷?„m_wZ/ŠètÎ’õ™ýþÖ²’¥E+H–šß*÷(4{€0ºôĘ5ð<’+ÖLlËï×�À{`âå$€û]^-g÷_×ߦõŸp¿sÁ EÀA½68 �ØWò—ñL Ç‘F8;;ÃçàÔr°¡@–Üî5 ò³Ÿû,~å— ßþõ_Ãç>÷™�ãœA`dUŒÜâV˜ ©!‚üv>)•*A ü;V÷€ÿÓ4áéÅüøG„÷Þ{|d@þ~oN5yÎ>6¤Ží9 îö·xÿ½÷ñÁûïÛkC_Îóop(±źç‹Veªú¼j~IÕ®}ú]Õ°*u^«bÏÆQgôÆõªÝÓ±çj@œ�RÙæ,í`ÅÚ7ìQÄÕ�$^Wi³“!KqòA G NT¢� 5ؤ”‡ìùöÿLîÌ/!-#½ÔåÕóÐ ìd¿2oÃHÎg�ºÊIH¥�•ˆ G#À¢œOÚxåæ®j–ä•'aŠmØÏm´˜K4ü]sPÔßq&)$€Gõ¶ž�ÈŸ<Ò'ŠîØ‘´²¾ú×ìon~á÷þ¿÷Õ¯ÿÒ7?ÕsÝ )å³³35ç%Æx<‚œ´'¾Fœ§ Y&„y2’±�ÿj]¯pòç¶26õsî<Ï�¢ê÷˜¦dï_(‹çiÆ<ç :Ú\S ¬=’ªŽ¶OF#vvwwwŸxúäã%Ïó_ðK;ôH0Et¥ÖSÞ=Ã}ÿæ ö´[8Å42Ô+®ç— ;NaÆ/l÷ï#ÄÈ Ò÷ àÞ)ý+a0¨å¥õk]!¶k?…²µ#ÎÆ,…ÖÈ%öB׿PÕÞÚ?ü=0ÚÏ‹«K=C­$®éÇ´Ô9µÿË¡E뜸v Ì'8i�­PôþE‡öÏ,¦îeÏÔÙïÅ{ÿ!¥ô7ÿ±ÿÊ?õï���D䨪¹ô¥â§” 2"Ϲ‘d}ÌF7Ÿü3R�óÜÈ>e�.ý¼zò�e«­¶Új«­¶Új«�°ÕV[mµÕV[µ*j~PV @3’²g¢K§vÌÈP™‘ÝútæyÄ8f0JÎ=ˆ€Ї€>œçé7 0¡Á^T|»Ú`\A1Ûl—jÁ ª’¥Å¦€’èÎbHŽñüD¢ÊÍâ͹·ü�$—ZTø„!%S؃ ¨Jü¦r"؆Ö@4ÕÍÜj)�°_¯ ]{Ô*¹Ù —éHyperÀ—Àfà�³ @¥nH*[~qJ„ĨJ\¸ ¸©A¹ZV7õmb»_öwwFÐd!Ý È`a½�›ÆÞ‹Ê†jÉ®-EÙXԘŠSõgy`jjwÕØ–ÊÊ)&šý:¬Éj'!4Úu‡{Pó¼Ó©¿l‡WÕ:3Hrë�äQU�íªÃj¯ŒüSXLĺn 4ŒVÃÉÁ¾j©®F0 (‘Å&¸Õ;üÞÌ ddƒÊTö·¨Šðãñ軿¥�³;𥶿´¬ñô¯¹ç‘öþ-@è Ú&\ª{ ü+9ü]Õ«/fÇMé…êÒ_ÔË'Nè@pÔÿ†,hm Q®@:#¥¢¶ç@¦²?) 8;;CóQÚÚÇ(ƒðù/|¿ø‹_Ç·ýÛøÂ>NM·, à3ÑPû-…ÍøPÜ=Úï|¾OÉ +|r—Ÿ§ Ï//ññGãƒ>Ä{g?üÞðøÉǸz~ ,c¼ÄÐ0·Ìïé8áââ)?~ŒËçÏ  d·!q¢—.\d AAK<�ÚøFG)rrŒ��¤ x•(#¡ÅüÜ.â»ûoý³¿ø�oþåœåRfQQ=2'67…èÞDdG%¥¨èpÀ0 ˜sîæpN~Ÿ9’‘¸µ/å9dêþ\ç@æF¸Tˆ?§Ô\#§Â×,)Ùiºs?ó?çó<½ssùü_”œÿ¯Ÿ’Î|m·tâϯþVFšmq>bEG:±¬ï˜†'7M£µF%vœFeQ#Ç ?.ѺƒL÷L@#"F÷+P!ÀÆ®§'ë‚&óoó‘ÂWø�ºmkãEôP!éFÅ>º5æ)Ñ%’ZP5ÇEû¹€%€¾¦Ä§JØŒN% o·êüï¤ÿúC¯8N “¢þ¿¹�4?½p墯ô¹'dý‘/|ñßøÔ§>};ÍÓ4OsÎ9«†õ6³}/RUÈ('‘…8]ÿž ÉÚo"Ã-'½`±cÌ`«­¶Új«­¶Ú*ÖFØj«­¶Új«­jÉI<35!1#«`:LÕFµn´¡e«••dZ}÷3tÐkz¤’ààA;[`õ�*°‡jÕ™%Û1QãÑ�¬®îå1ª‚•}QÛ¹°ZáR°UEØ+³Aib*• ¡�-ìêIjùÀ� š"Ámx)doG;dSÁÀ¤„H°u`�]!ÀO¸as“Û81wŠ[#] ‡£mÊ9�âÜP�¨ª¼ `k!Ù­ÿ+ äm˜T¡ÉI š!®rËnOœ¨åÈG‚ªð.®ÛäÞ^¹‚+f7ËVuUØ¥m‘̰E•›ó¶hUñ<#'ÆL„¤v¾‚fýZÁU¶è‡ÒŸ Z7O²UU›Z˜\)Ú�WMaKQžH(õPˆ›ý©5òÁA!Fo5^6ÅÙv«wÀ,‘YÍîXëhØè¶?Ã` ªŠÔ>Ú2l�„PÁäºWn¶êy¶ Új·ìÄ…Fd–±G‘´‘¢êwÞ>[:2I«µ­é‰kûà�\�¨X�ÖûØÅâGõ?7eq9 ˦¢wRQË‹÷1Ãuüùc¸º‡„œížb4ˆfªí.ãÇ~ìËøú׿Žo}ë[øä'?Q]˜QÔ\âðSý)±[÷r�óhNÉ î“d‘«€ÈÍ ÍOŸ>Å{ïˆ?üïð¾ÿÞ{xöô9.//q<í<ƒipÒKÂ4O8øø£�ðÑGâéã'˜óäÄ€òùa¾¨¶ÕÅI£L6%âDÌUÄ×7RITŒ Uc^ü1-lÜ+0Hýý'®ñTT¬~OµÎ'Ô÷‘è�³ruwœ‚ʦ8žË P@;íÇÑÉpÐfœ�nø,ìkŸÕêJSžÄU‰/ÅU§EB”?Dô§6þýpù¼ÊŸ]ÅŸË98qª7ùó¹¬cʳíî Ž+els¹ÌlϪçÉoélb·ÁZ^:ðÿ4¨Œ;êÆ‹®ºp¯ÙsWëu”HïB)ë¤ íH)Áœ¾»Ó77×ßþÛ¿ÿ{_ùù_üúõáxÈ»Ã�§Ì‰5ËÔÖ@cìdW'³VÂŒjG*]Þ§S×€vž´ü»60½�ºcÜ3ßÕ%\�ü—¶:}¯Þ³(¡WŠGZï ´~<4âA›"h»_{'^r>½‡ÒƒþÃ?÷çÿÅÿïq:Ò1ÍG>ÊtœŒ$îkqݨ®‹ßÕ±9¤0–*NFF6BzÎÈssL+®Fš6ÀV[mµÕV[mµU¬�°ÕV[mµÕV[ÕRÉh(jk¡Œ¦d;ÎG³oq‹^Å5¨ÛEëæ.ˆHUG¨ž3Ñ£y>þ‚*>Q#ç;IŒš2‘JîûPA`SØ,;«]i¹ñðcR2Àƒ�¨°5ÅW_*jJCuÜ€Nm‰«êïtƒ©XÍÖM|¢U°hå ¼Rè[þ2³žw@�Cö4Šêª(¬Û™U%¼�³[ú3jvµº‚u©6uä¨Z.Wr2¢ƒæ¨„lÊÏÒníüQÂ+&ª…ìmCD q'|ï/Y2ÔÁâ²Ñ_€ÐÙ%•ÞŠ TU†Ì¤p›ßº ¯jAÙUôA9)N\€œS¯Öj&±9P—Èl}ßIÐ΢!^a  45œ¶�Yî­y5dN‹ÚF¿m‚6²ƒ;r�Å�›­°E@Å_pƒI¡,(1ßvì¶Yom™Tì~$î‰ ÐîÿIÉQߘÍ%ù‘¤´½„ÏS1Àµ^€ý»Ë ^µÊ˜SÏ…­¯+ \°ÆoYÄQÂ̵¿/�-‹ûz[ )ÏÈç•j� ön‰m¾ZQº×OX‰ÆhÄîTö@³ÒRlóf8s³ÒÍyDxôÚ#|õg?ÿó?‡ŸûÙ¯á�7^¯Šçr)1œ¿ãÙÜRf #¤aÀ�‹ž¨.$… ÐÇô–¿Ñ±Dqu}�§Ïðá‡à;ßù.¾û€�?Æ~À<ÏÒ€!�UÑ›Rª®.W——xï½ïãý÷ÞÃÍõ•d…Ï#îÖÏÉ•¨ÔÔâþì`ˆ÷·B (s‘'–K"€�=ʼn]Àúnñˆ„ÏR·ïàÁB )„1´sG°z—Îã®4õD& ™ÕF®ÒήH¤ª«ä˜.ÇÞÙeÑݦ}ù:A1[nD�7šAÀFp?™÷?QàúúzqVv'ÛùD4øÂÆ Q¬æ†Sò¼o÷w�؈SP}AN£2£T L˜âȧˆ;AOTÖ]›–g¹ÿÝH^:¨ôó“Æ£…3Dù‹®Îc§–ßzr ”ÿÆïþõþg¾ö³ß9Ò�2 CÊó$˜ò%Å8 г3¤”0Ž Ó4âîpÄt<,lºK/5‚âœ'÷æÐ–äã|1k[oJ}QŸk3Q¥”xNl ©Ê¨„ÝÝ~ÿéýíÍSrþçUõí<mìÎ…¸Ò“Ψ9VUü{I™)Ï Å=¸uø¨2ÇG7�ð~™û{%»R°ûo÷ŸèðX¥ýÞc!êZ¯RÏz­xTû·¶k}}ùyœ}ÊØ[OÛüÓ÷ØjëÂ9«Ä¬ô}z1¾*!Ø�;b$@¸©¤§¦¨·T™B€(×wß:¡?þpÃû^Û�ù/9¢.çÌWÅÇ_�Œ õ1ÆÏ¾õ«üß ¢»! “ŽšsÎÈ©ÅntçbÍb´Dÿm aóëìÊÿòúB8/®e­NDæ8¶ÕV[mµÕV[mµU­�°ÕV[mµÕV[ÕZ8¬B<Úr\ó<#ÏHœã0؆RÊ`bŒãˆävõ* ;"z˜ˆÞ™ÿ…¬Ô¨fd¨+•›j–SòÜ[òœx¹ú£€‰uå»Ù]'2i0;¸,•”P7Ù7ð9!_ÛcH8gs“‹¯lÑŽUëÆóInj�WE$7ëàb¡� Ò²{ èÒGµ?hËzGT±‚ª²l|3gÌN’‘`?ípcX=DWÛ–ÁöN& ¡ìaB–ì�¹YÅ›Ï3€Má»›DÎÍ:‘xV²í™À 8IËx ý…É7aEf yª~nÞ_²[ï—{%¢îj!-2�Ä#¹ÃƒX{üº)„–!Í’!ì"Ðêî•‹®ØS…ÎÙû³5sòóäHªjVË1·Úo÷Ù®�#šÜ…tÒG³ö6�ÚN ª³Á «hnÊÖÒ�#`Ýâ,š½Š+ŸE‘ÒhÄ-½T‚‹H®n@�n"ÖÚ%'=ô½ r«ŠÕB.(.Þ_L!_L�›cvÜDÑæº¢+Am<�–w^^è„2¢HTN–ãU—Š–ç¢N¨·/‘î\¢‚®ÍCÁ6ß#<¸Xÿ—¹ÎHSÁ~ö3ŸÁWægðõ¯ÿ~ò'ÒTûîPǸ«ðSu°ã1kìÍFÛÎaØí�ÈÈià:ž)!ZÙ7²U`þÙå ®¯¯qñìÞÿ}|ÿ?Àþ�¿ƒ÷>ø7WW`bœ�=À0X{§„jcwØãÉGãñã�ñìÙS﹑¿*ˆEfI¯¼¸¡¨}[ ¯TûOv—¦X2·­Ö4…ìP”âåù±ö¼ÕᤑiÊ쯄«*ð2çK‹`Ð8Ž"é$¸Û �ç…¶F¨Dð_—ja]…šzpTO>‹ÊšÀcMˆúø„Œaª=—YâÀ]¸¾¾ k–ÒÛã‹ ©DÌÜe…ø³êúúª©·Ãt'ŠÔ®9�I#múhŸNî-� Q>_uUÌÚY¨ÙÀë=iàÔ÷'뎽J½>Š8’;¹¢ô—ò÷n½êêòùŸøƒï~÷ûc_þò^‘oæé¸OÃ�U�ù8ƒ@w#R *Èy‡ÃáfÆÉÆ\f¤4‚Ó yTÇŒÃá€Ãñ\‡ÈæUPh·î×¾×qÙ¹Â0‘r"¢!¥a�0ѨŠñúòúó7××ÿ²äüϨêk‘Ô÷ñÖ´zÖ¨=\Onp‹B Iõªá�~}W†Æãö×¹ƒÕjÍAë¹òQ_bHšC@s%AëÎuþl1]Á²ŸÂuhï�‰F…¤S�(ÚúórŒTBEs/Š‘æ‹~}Ñ†Ž„9_+¸oß3–Dƒ6?µõÄÈXK² "!¯º÷œL˜'óȲ笒B° Yëê—(/œ_^RzßûýãßxãÍÿé/~óW~ "{éâʘ½Ý–¤™%ø_ȃªöݰ|'�]ùŸó\ÝlŽ(ngiû2¿ÕV[mµÕV[mj#lµÕV[mµÕVµŠRˆö©‚iš üÏfß FJàÝCªÀà7Ôì3“ªžCõ½™óük5‰”‚N Äl®EUNÉÝ ˆ`à®YŒÏ¶¡<—ÍÏ‚O Â<_:èu–›`q³‰�,М;ÕArÅ_e‰ƒUmÝÔtU¦j¿\6¤Ü¨ú˜ýglm¡Ìä ’ÑâHÃÖ[TŸU•n€U²%N p…6¢š˜ýýhN~ueMÝøw`,nhÔ@J†(×¶C|ͪSl³NÅ•·jA Lìyƒ­-ÔÕAÔTÚê«6Å0»œ‰¬£`HvŒ�‡ 4Kdm*ϲñ˜RSnæyF&Knêê”,Aà`‘P"\±˜š1/jýÓU�k(YµÌÏFº˜§ì›†b&³êvÐ,‹÷!éAôèÛ‡{PàÆÀnÅ"š#‚5ÿ9qæX�ú}Ûæ²yfié¯N´XàW¢h×§Ú ¤õp¸ÃñhÑ �·¿IþÞÄ s{æ9c–Ïž?_¨–Ñæ Bç&D dôc•èü�sEŸç k­c4²"9³>¡{õµÆ¹ 5 Kp±:Ÿ„æ�9)K°žI®:þçù?ûs?ò…ÏþÏg™.ïÒᚉ'sÌIHÃ`ѱ¨|g ÜlÝ“sÆn·ÃÙî Ã8‚ÙHcÇãŒýþ··×¸½½ƒÈ\Ÿ-iH�m=³­˼çÖH°¥¥D42ó.%>KðK)íž_<ùÙ›«›!çù¿¬ÀØ t�òRÁgQ­ûÂ42ÂZÛ¡ÆE¨¾àµÅ¢# éés…'taÕÞf¯5{ s=êúÔ— 0ß!þÍêÿTe_I TžÉÁ|?Œ«r®Ržu®Â¯~<]¢U÷ƒ2X<ÏW¢Æº1E>wP7þU¥[£”%_ãQì$B{‡€HèBûkõ àÿê¸ÄßÀÿÒCÇvZôù”ÒòÛÿäŸùno¯oÏvgGbš%‹dÉÕ¹ª�oyóPªÄkSÿÓ�*y{v°¿ü)Ïöò§´ç {«­¶Új«­¶Új«�°ÕV[mµÕV[µbW9ÇšE ³Ù«JΦ|�m¢ÌÀˆºÉ­¬Å衎ÇãϪâS\ð¢’4P�Sr't£ À3pII›ª•‹úÈÎi³.IJc)1X „+Ñ×Ä Hƒå¨Y¤ƒÍ0²mÊ=m¤A­¸úû 4÷ê`E¸^7¢¥·Ÿœ˜ýú\¢ œÌÅÊ–Zx‹2(6ÐR�hs h HSÊòA9¯T�…¿ŸJuØ RUžyxÉ–Niˆ Èmƒ;k©+0…\a¸Øü¦h˜l›ÍÖ\ Éš¦Þ+#˜Z¿:K( ¬�̘³ÛZ{žpÙX6…û¢Œ9[_…fˆ˜Å2‚ýØŠŒyòüÑlùåH€[.B´ZvÙœ÷ ÷‚¯~íkø™¯~Óñh`ç³ç¸ººÄíÍ-nonpssk*‑UKriàÉ‘\Õx!¦¡¶�ÖX #gYŶ!¯âÄ 0G NætáýT‹£ –­ŠQp*€jTbIÍðmм•СRõÏm¬`)¹Ù­¿0µ yøÆ¼ŠT2ƒŒÌ�´µØ­ÏCN´j§ÚÕªZ„Y;”¬o,¬ÒSqá pn*Hªm…€¢%UÕ0QgÙ]6ᙢ÷FŸÙm±#´>zô_üÒ�âÇ¿üãøêOŸùÌg|Þ0Žƒƒqþi%çÞc]T•âD�Pï<6"Õ0Œ! ‘–‘ ÌÀ4͸º¸ÀG}Œ�?Æû|ˆ÷?x××78LGÈÅÓ'O‘%wÜèøarFÔ¤:hæÐz÷Áú¤Å 7÷oà}hƒ.z¦í^¼ùK‡ÕâÎÀ‹&û°çà¸H—sÞYƇ(Œ̃ú§—–8ôjþÐöH ÷ÑwRu€Sæµ³ÿ'62‘Å1ˆÄU´Aa ­×ªÕM9¡Z®œ€ëO/žâÝwÞ©d%~,Üì±æqvFš—Ï/+�„<!²â4(›µsÞiîAËUAqaX¦‡ õµ.=G(5¶ÿŠ ¸ö÷«w.QܧN.ëà~÷žèdëÙÅÅŸüðýþƒ·Þy÷©;ݦ4àììç`Œç#ÒP¡FèS�l-0ÏwgæÀÅ4ø}}‹ëëkì÷·ný )!Kps`ˆŒ•69 ès¨€”420ÓŽ˜w)¥3½öôã�~ûx<þs’ó7Ë5·g¨F¼sa¡NAÙ½ˆ\ êÚ¯÷Ãè›]ÿÆJû†õôH¬Ú‘Ö":jQØ[£Õ{N�ÝI´@z>7õ¿êb|ÆvC#4Pi©wÿˆŸÿ\´�ò H\òóm.eœ‹4€ò\­ÎMÐ~.îFc$%.Ö¿ñ:y³ÅÜ ½÷1§whõÖvk\¼ð5ý¹ •À|yLÀKëžì"\á‹?ö¯Ý·éúú�ä)¥¤ª:¿®ÿsFºèŸò}pmq] YDÄH”ÓtÄ4Ï5²ªë¯°9?~Ýj«­¶Új«­¶ÚÊj#lµÕV[mµÕVµši¶m”‹ÖÒÙÈ+@]i-Þ××PVÁ™¯MÇ»ß(›Úe{†)Ue¤}fsèí!”I ”™ RÕ ª2ÌSBâäöØ LÒlŸi©¡Ü h̪l ¤m$ ^`¥U,ç^«Ò´Ú¦v¼Ôlä©åÙ |Q–vçvóì×YžÕì´‹”žšò4‘¤" …¥ßU ´d˜NB5õ›ºñÿË%w7b: ’ ü JT�4dsššÚ8ªç#ÝïKŠDJT:^µâ�6«@¸sD³¸ˆe™]WQÿÛÏQA¢†ÖÂ� 2r±Œ•DÉíÎ3˜S§ö6@¯Ï«UíUfàoýþïãG¿øEœŸ?À;o¿ƒwß}) SBhÎxþü Ïžâã�>Ƈ}„'�Ÿ`¿¿« "³�GÉ�– $,ia…l£ fñ|töÓ�7Úmr Í"7Ú&wçQÔÚìÇëÿ(~Nû¬ªZ><´‹ºhÎAY W§ú8l ÜE”“Ó"Ì«¨VìÕæ)iÉ+ âR»Ç´P?S˜³ x©ø£Ø¢Ý3N,�»ÑghF—1MËs\D¼ó‰OàK_þqüäOü$¾ü¥ŧ>ùn%Kp”†�«e«ÀTðßMN ^/Àhs Hø7"@êìýÙ,p¸Ûãòù%>|ò¼ÿ>øà|ÿûßÇÅÅs\]ß@ò»³MÚܤ¾”Û‹|mrR(’&¢%{„¸['e(ÄUìíu¨ã™Bn·µþRA¬"MÅ]£E›¢ê-nD`W¯ÁN¥g’ÿ¤ÚÎÝDB!Ò¤‚â%Ã]µˆ…®B Au}!]<‹Ëgd”Ìx¸ ûógÏñî;Ÿ8y&«ÅryJ8a-ÞW®¯¯ÓÍ#ßS–ùâîðà..=h«]{FEO3ÝÃB¬Î£ˆ‘ á^w˜b C—z¦÷­ñjŒÖÿèóØëÜ:pyðWþ³¿ò§ãOüÖw�9ŸÄc„ÀÓ‘Áò¸�œhÍ2 ¥DŒÝ8"q‚˜§ ‡ã·û=öû[ì÷{ÜÞî‘óìsÖˆa”@0RÒ8ޤª,"DÎYXDI„íï9'0�‰i§óô™«g7^rþgøLT«Ÿ‚éÌŽë‹eKâŠãvÝ幊EŒD¼ÿ¤¸ �@'Î=à_Ý9(\L|ž‡g::{| D]0jìGqè² Ô¢µˆœ0±X'6 Íi"LÏüÎ+X¬?bŒë',Ü ¨Fg‘“´ i4®ÅÚl[žõ�ŸI8µÝ_¸QÕvnk#û.A÷“gºè/¿² Šÿ;ºôþ‡(¿Ú¡èÕ¾ýé ÿÙ‘:¼:k{¨î+2²«þ%�L}jêÕ,†™C›¥vѳrŠçÃ<Ëž ê›p�’-€Nålí:Ìò6K®ÿ-\=ÌPÿìäÝ:¸3AÈ£�–ÔÌU Á¦p59RA`®\�z¾Ñ>6WÄÀœ°�ëN ĦLTD¸¾F8±ÖÌY‚%·9S É”�Åò¼õ…âºààcì¾’ßÍwøKÿ�¿„¯þìÏâÓŸú=|X¯CæŒað‰O¼ƒwß}?ö£_Æ<Ϙ¦××WxòäWWW¸¹½1€äæÓt´¶"²NA½;¾Öüí,ze9¸3m„ÍÚ¦„ð¹¨óÊõ.Âl»\âzQ‰[ú¬� )‘®SHïP'·�vBO¹_ªÚúCµf/Jp±,w¦’ a4 iVÁ­À¶{‡ù eë$ÓPj³÷%MÝ\hÆ�|¤Í5¢D[Dëÿ’7Õ�Ö_[¤áüüŸùÌgð¹Ï?ò¹Á�ýø—ñÆëo ñ€4 ʃ@jNreZÔEPê§”¡Á-y¡š3øÆ†øÞÁÆ S�K H·ßïÝÊÿ >üðC¼ÿá‡øþ~€�?~ŒËgÏpww†ãÈ8€1 Pý–>þøc|ôÁøøñc‡â Y ›­¿vÏqbXvBIí—¤î¼úÜÂŽ¾F£¸CAœ¤Q"œ¨j)fvC+A§{Æú€ðÙ/¸i$0J\�§ÈFðFP s|�݉Þõ�`Öü\ÕÜeÃ[×ã:æHc&y�ш0Z­­ãÃ];Vª\œ—¹†+ùby®ý´ó &T?É�†· ãòòÚS%xEbßæã=8ÁçúB&àöv_Ǻ=H=fÆãfDAõ~,ÔÈ`§K—–7.¼ïO²^?uk„ìÀéåû;§�'£ÜW'Lð¿‚°ÑF¤CùÚ=¯}&DñMH1«gbŒcÆ #TI‰©ÏJö1 97Õ|Ø:½¾ºÆßüýßÇ@Œ›óøÌg>]7µsÖj„Pˆ%£Goà­·ÞBJ#ÆÝ€!�†„išðìÙs\\\àéÅS<}ú—ÏŸáùóKLóòèˆfßnߨwe}�äp7‹ÄÚï};ÙEJ?QKz–·h³¡EÉ*/®åxð#q³ü±œWHIÁ4†ˆ‡�TÀ“JY„¼Ý2ÎeÖ.7¼³òŽ*úÅÆ±jr—°]뇮šVnIr›´¹ªP˜Q iªØì/-â‘Ä¿° ;|ꓟ¿ôEüØ�þ>ÿ…ÏãSŸüd…E6†Ô#Õvx@s`N`‚o°k·1Áÿ²!ßœ5 �Ýò¶M•;8Peàÿá0áææ �?Ƴg—xüäc<½¸À“'OñüÙ3\^]ápwÀñx´û+F®Éª!ŒIp#ŠýþO?ÆÓ‹ ‡ŽVæ  âvÌ¥JÈ®àb&µGåèÂñ\Uš³†Ç4QwßÒõ•‚r1+ÖÝÍd„˜JÍe½’Èhf¤™Çn¯ô×S-Éåä!ö¢ÖïzàŸZ\€yöW§ªóŸ×ú}s¶o1$õd‹O8/À}�²W *fêb –yßKM;U§p³¿õþ¼à"Ä7±=ËÂÀ´¾<$°‡CÇc¢ŽŒ`ñ0’=ü¸L¨Q'îsN("Ña&Žõå9¶§:N"Σ²è2ïO”úÚ“ÊóŸEü¤kžH.¡ÅM§.E;rRÎùõ¿ú—ÿÊŸþ¥_ù•?RÅkB¬’å8O“ à9Ç!)9 œsÆáãqÂ|œëx‹¹à‰Jœ„Ÿ?¿ÆÝ0Ñȉ‡qw™y$ægÞÝíŸñîöæŸÎ9ÿ×Tõ3ÑR¦›nÑõ�³Ââ.['Ï U9õ*õe_Ôº®“¥’gZTCT‰k7®W•D5ŽžÂs­NYÁÅ¡Œ·j±O}¿«$€x 1®æ|ëC‹ë༢HºèâüH˜'ü9×$>3Ä…øL�‰âTÛ0\u÷1¾I¸ÐE' °!ç„HV,%p þ¯¶ã=¿¹¡¿ÞsZ?2­¿•œü·6Iѳ/|ñËÿƒ! ·Ä|$¢¹ŽsÉ„/ßù~k~É“sÆñpÄápgêÿ9WoY£”v'š!⮜¶/ó[mµÕV[mµÕV¡6ÀV[mµÕV[mUKª½É,ï— ”õW”ÿ/Jøh•Mæÿ;8›Ž‡o—M p‰àê0rß‚‹€¢äÞ“Ûη�R&¶lèäÌY Y dÊ®0K–]L@"‚¦Ô²¡ÕÕÁ5‡8ùæ@B-ÿ×Ï©(”R¢;ÕMw ¶¨¨*_5dâ Ëf]ŽÐ.Ã33ÿ–/¯¨öÒqcX$ƒ2!×¶u¨œ 8©!žÞ@f8‡°AìÿÔI1.UE+øŸ³gqÖ·i%Zp“›�ÕlÅSµTõ6Ób•NÈ¿Ð6á™®ä€K7®Z¸;GDü©EW7öÅú{ܬ‹2qˆlp‹WÌX«(æiB~­j´eç’™-àcÎ�ò­‹¥ºçÄ_]^á»ßý|ík_Ó'xðàÞxóu0²«3¨È©³ã˜0¤Ã�üßÎ>À§?ý däY!2CDp}}ƒçÏŸáâ⮯opu}…ý݇»nno :ƒ“}FŽ}SÅ|Lk%·è‰M²ø¦~n]¯ÂÈ,uªPÏÛn,ž�-OÖ/ó<[ìBÎÈ9DK”Ø}S)ïEí¼Šk„6€LƒÒ°t¬³QîÀpºa­ ó (Þ‡™Á�`“­‹¾Å�}xD `ôæ›Fôxû�·ðÀg?÷|úÓŸÃn±Ûí°Ûíšý¾~.ç" $›1’š» ‘"�@)µ,æ2¸ù ;øÏP @hD0Uõ¹Ï•ÿÀ°ßßâòò Ož<Ň~ˆ�>þ|ð®.¯°ßïqœ�H>·ç¬`WÉ5ß[Dpûü———¸¾ºÄ<ÏuÖ? shÖIðç„�6-Ñ æ%øT§*@Š8¯£ÿæÈâô =ÏXª:©‹´ˆ$‚fsM�xos”Àw×— ÛV"T:Åxk5÷ '¾Á\ãSØŸ5”÷DþL¢H¤p.ÌF¤€ØŸxâ„"“f�ÈQú™9÷D‚uVì�JSç�ãá®ýÎc'ºh&PFuÎ%*AJÿu;ùÄ #ˆó4˜ Ë÷öïÝ88áÔH<Ì„?üƒ?¤aÒn7»³³�cJi`—RÚîöï<{òø?�ÿ¤Hþ†* ÂB%¡Pß>÷:¯¿ªƒz}}±¶Æn‘#¾þZŒ® ièëïÍJg Ñ6'ݦmþiñ<„£ÞYm­îo“¥/€Æõt³Êˆ�Fb#ä´¾oŸûH¯Øï^ú¢âöÊ|µzŽ´˜¯xíõ7þÇ_þÉŸþ;î˜yJ)i%ÎÖØ)ZD¢¹ë”ÄçUbªªböÈU­Öÿ‡ãÑ×ß!žÊ àÝz´<×6€­¶Új«­¶Új«®6ÀV[mµÕV[mUKd¶Í^Ñ¿ÀgLlâÔ[ÒªR§&"RÕÀŽˆÎEò/Q±w…’¨)Uí“Ð[…˜%`O¶gÚlë‰I”M©R”É"3æ™@˜AC85À]ÍÆW¦Q"¨*ý`Öú’«‚G=ã½€Dœ 4i`˜bÓ² 8” ;É‚ æ…RT]%§"+%b¤„‚xÖ¨Z0�sFR†&îÕÆöâ {µ0Øü[°3(¹M¿+C ¼£îJ s†Êìíå]ÁóÄ Ø^`](S5`2žû.æÄ�E°“[Ô¦®Õ «Ç>¨“.Ø7¶³_Õ‘!–©Ð¨© Õû4ššÈþn„„9XxÛ¦&»ºØ€ê”Šä´mìK¶?ªÅ{ ÜbÎ�„¿õ·þ6¾ò•¯àêêWW—xøÚC¼ýöÛ!#�Ìà¶ÀnÓP( –é]GR³ã>?€ÝnÄ»ï~¢†Ó€a4ûÔÃqÂåå%ž=»À³ç—¸¼ºÄáî€ÃÝÓ4áîîÇÃÁs[—$ñ£ß±çp¿$�‰DúÌ_j¶Ê4l›Í…Bu<ˆ$¤Ô€ôÚ7Jo7Ø7à‹ó€»r”h†r�ƒ%?![{3‡ÜåvîÍÑ  ¥�Ÿ$Ùæ1гIBü„“NÎÆxý�×ñöÛoãÓŸü4>õéOãŸø$Þ}÷-W‡ G–CÛÅXB˜«! w¿Ð,P2µ2“¥(@}þE±tvÇËJLJ³±�9ÉÅUe¿ßc·Ç³‹g¸¼¼Âų (ržqùü9ž?Ž››Ûú—.ÏÍÒdÎ@ˆDi䟥"Vƒ=¾l—�mÒøªÎ !/Û…ñÕòž*pXL6§V"5juùáX�ü5�ÈU4ðT•¦eNn¶íq>3°‰š ;’pÆ£�Ò)ù\HÕ@UÁj¤ Çò+ॴž¡Åkt¤Šìc…¤¶m?Cô€jg#hlÎ21¨ª•é„ r8Z|…ç*Q�‰ÀWqñaJæp4w·÷´™t×YÜ~ yŽ¡¨¼4µ9™°P…/ûh$fèÒv^ë}ï@ßà¿W™÷.4èßG-b¨OsÑ…o¹5&ý1ûÌóüî_ÿ«íOã[ßúw¸p‘ˆ½†“)ímS³¨Ð…„0KF z°¢^7�Û§3ª=uPöž÷Þû>z Ÿý̧%\]^ãúú¯=|ˆ·ß~«ßަf?-lò1’ ð[�y;Û|m*ý�ÈÈ-Äxpv޳OŒx÷í·0Ï‚¬3T ILK8¸½½ÁíÍ5n®o±ßßâú懻;Ü9Y`š&ÌyFÎsíûèM껪Î*ìˆê1u¾ÔZ] ò²}á_[Ák#”HžÍ9Ä#5À„äs‘Joƒ õœ{¦nó¿8hÈî/¦Ì�‚”<|€×=Âo¾‰·Þz�^¯¿þ=z„×_äöµ6®S0Ž;Wë;`#ÚgM¥ fˆ˜m6¥Žvήð/’M™3�lÞãÌ ÔX¦¬R1#`ë£e¾‰ ûýž]>Çã�>“§¸¾ºÆÍÍ .¯¯q·77‰Ûý-òl® „’éëaÍD˜g‹e¹½½ÁÓ§OñìÙ3ÜÜ\W— ŒóФ*6Ë0 C�TŲ€…½ïœ  q0–ä¤ëÙǺíxavÞ7'íy$r ¤GÇ”"RhKeTÂþª®5ÕÎ\´MY⤳|2dª¨Ÿ©µUï`»' (qOChí{8+É¢’ôJL1’;ÍPÿt%Â0X–ôtÀG~„›Ûk1†”°;;Ç0XE±ˆ®ÑL°¿¼|Ž�?þÏž]àöö¶ÎË%þ¡µ³ ®v¿‰ƒãŠÝ¹yÎX©ªrDò‚zƒ•%vQȰød.h“bͪÆâxAå_È#uîÕ^yY•»Ú´Õ*¹::¸ð¹öå DÐ2þFU»UºTp.1' vG’–OEAÉ £WSjˆ¼ ì„¯Jªè#€ YoáXÑ\Ÿ÷ˆd ”’?O8¨aªì2jƒŠy©~××·u½Rî;��܃hƒ‘]ÈIŒýþ¶ïP�šÍy‰1)k‘Ú.!ž ö›Ž(TÜ$T=ÒgÙ k¬�¨’®Ç¡Ð¿ý8šD•¿¾‚•x#ß¡Ðo$Nñê’Ïóü¹¿ñ×ç·ùWõÿÀÌ7D´0G‰®-b'ç¾Ë¢’R⤊¤P΂Ö�•b†aÜ1x÷ìé“/^__þÖ4þ„Š~ݦZG]à­Ÿdç:QîéßCEðºd¥wÓLh0 ý4ÕÑU¦¿à^ErFXC%½†­º6ˆý²¸GõWÒ]Oûµ„¾æ3ŠNá»Bt-*ñAÞ2'à¿J×KçÕØV‹˜‘ŽœÜÛøë’�@‹f ÇÔÐ÷—ßÖ{:‚c€6NM¸é�»J× ¨9ЋÇáêÏâx¿Ç�ãU{®w„Óö[ r=!áî‹?úcñÓŸý‘§wwǃªN8å\Å¿/ewü‘M£*u¾%2g´\#B‚cÀ4cž'_ó5Ut¡È9cšgä9cž'[›3o€­¶Új«­¶Új«Em€­¶Új«­¶ÚªÖáp×+Õ{*öØD ]QÀ'sSQ"¦3"z��ò4ýjo4dÛfœ PéÕE¶%œÓ¥¢):£³éç•ÊävÝXä•‹[»�5×lðJ`P"Hœ|O¾ä »vª¨ S²öàdçænœ¢ vuGʦ·’ç”0²Ø`ª[—}Ëb™ËjŸÅªÖ YÌyÆ<çvøàÏáÿNÄÏ™Óî Ø—’à½ï¿Oiœá‚aGV‘”sD%eѪI„ÆI§×¯ž?ûå<ÏÿH–üÇóœ¿THnR\n…¼¶;7ƒä«÷v2~o– yl𰿍n=%N[HƒãÕ2r¡c нf� ÇÃCáïµ-˜«óYÿ±IÚµ�÷s)Ã[;•;P×ò‹¨‰ñ°oýu-£4™„uŽj?&ª²ËþÜTÿ1F§³X\´'Æ6ÐI”E}¬�ÿeØ­ýý‡ª»aø÷àÖ•¡rwIo¼ùÖ¿ùë¿ñ[¿³¿;Üåœ�"s¶Ç©Çoù³"çŒyš}ý=w€òœ[W“²]6ÒÀ)¹Ý4êF'®š’V‹òi:bš¦º�jm—� XOlà õ[ß4%w% 4åXçNQò¨ÅÚÈì}³)ñý4`»Œù‚%W ÿµ…)‘©zU–,ƒ›‚ÕHk>!€·ÔÆL9BÄ{ Ì.¤‚6–‹Ã ;(Xl¶#T[IT‘D¢Í Û@òyT¼m²OÔàAáœOz;ø6N œ¬†þ œ§f—_ÞXœ0¢ó‹HߦŒPî€?,�äðEU2¬·�\�’GÚ¢…‚•Ö� ¢zÞÁ–´l¯ lW&J]Ö¤©¦Î—, ™ª�³HËKŽùÄ¢do€(\é>;˜©ú¡µ�›%õ8˜-ø8î0Œ˜9϶‘5ÏÈ"˜òlÖçáúÔUÇó4ãp8ÚFÙ<»B“0©æ‹¿–U‘4A¹dr+Ø7E 쑪–ÂðLiË|޹³!CšŠêÜU<9çªú®–þþV#�ç3rN`6Å)!¹}zÉïs>ƒÊ¬(ñ©ÙRkÉcŸg##ø{ˆ œåv�pÁsªýþ2Y^z±(O×1w‘'ž³‚%ÞNÅ2ºÚ�›è +Y‚åÛ 2~÷w_ý™ŸÅÛo¿ JŒQGçÙåsÜÜ^ãáƒxðà5Œƒ+¢£—�Ôlñ©_–‘0 F@)öYL¥•ç Y²Û„ss àdDœdn I'Ü(à9Á&Ðï-ŒmÓ]DŠÞZÜBB€(@[l+ £å)Îÿyž‘ÕZ¶€ff¢aÑæ>`Íyä”=«Þœ4Û,”³‚X0ç Î#Ò0ÌÈN�*}1‹B³�«D€Ûô×Åœ;R2—””ØÇ&�qëuÆÀ ămŒ':Ù䆟3§Ô2ωÌ}ƒœ4àÑ Éh:ÏØßÜâv‡ýá—WרßÞàââOž<ÁÅÅîn÷˜&Ë’Ø�;0vãÎçL‹÷$I@VŒãˆ”ûýï½÷ž=»Àååem—XÍCësÄo[˜ŸiˆÒn¬Ô�&0YbŽ3öüÚÛ3s%0ÄÏióE³n6ÍílI,€Ÿtòì+Ž%\ç­ò *N3m./Ÿ­ \‹ê}W5—kNL õl;¯ž8Eí¢ËgX,�“+|.`ˬ'O |&›“¼ýkn³ÙâøTÈͽ!ÚÎwmtÄ»êTÔºrF$ it¾¨³ÁDô bí0¯Ñðþû–EŒ“ÐÙï™,Î/« Ëlsß,ö_ìoo;쯸lôˆ/¨^^¸=Tíù¨\^¦¥ÊÙÛÅ;¬Ý)d~SGµ]Z�¤`¾ö†µP˧×úÁŒ¡ë™Ó£¹ØD"I!£ÇA«¥?}ï{ßû3_ý¹ŸÿO§)ï3eÊl®¦2Qº¹ºüôÍõÕ7çyúFžó7Då+P¤ÎÞ ¬^~ni‰{b ^¦®n‘P�èÐ}Â+ º´È"�äŠS•y»9ѽÓ1ÊÜ`.:­[·‰6žªkF\«°0›ô“õó i Î1Z = 8nU¢P!†AWÚG«ëBUÎÇc/ÀÿÚuÑ\[ ñ>Ý{ÏåÔïvêö¯«ÿ\#—uc.¶ñ˾g­RhDºGõ¯/:Ø«~ß[ëŸ+ÅÌßùú/ýò¿v<oÇùnšŽÓ4Í’ç¹>ëÆà÷ȾÙw]¬Û‘søcé›ólèâ€FJÕmŽ=~މŒ´%bk×õ¥Š€¤Í`«­¶Új«­¶Ú*ÖFØj«­¶Új«­j¥�Ínžƒ­¹Ê€¶|ój+sb=6�蜉^SàõýÝþ׉Š;¹4…aU„ÃÀA6•µe«»j�)) ;Ì’!sg2Õžg|¶ÑNu#:Ú7—c–<,W¼nz‹œX»R§ä“r—�SUäiFv`kšg¼sØ�s5'3vcÛiRÂnØaLƒµ³“ æl*åyš s†@AÒ,± Ô�¦ãÓ�“Y®«± �%ƒfÂ�Àc˜ àWQdf {…“ ÈÏNváB¨À°_‘åb_�@©+¨¾a�¹yõþ Ãhq>oÎÓŒ›ÛÜÞîquu�Ë›kìo÷Øïï°?Üáîn�ÛÛ[îî°¿Ýãî°Ç4Y{3quP]#;þþv�gÏŸãæú777îJ°ŒçhÖÏ�\*BâÈb¾†±¹ ÄÕÊÔ¢�CdKk‹j¯'‚�b-zY´…VÔÏìþª§?íRí×ÈÊñÊ��s?ðBœm#ªätKØ5â6ÇP±ÉàzÌÃ.s3av—r¦â“m±ZïÀnâÔÖ ½µxoROî@ My�f�.-P�&‰8iŸa'¶øÀÓ'�ã�õyÝ Ò@í/$d'ˆeQHVì÷ûKøî¦…’¥ƒFR3r]¸÷®Ô&•>ÔÁ™¡¿ýà%ÀHëà‹žé@k‰Ö Z¼”´ºùt1þ¼î¨'u¨öWksû•ïüÍ¿õÍ/|éKÇaÜ�c–ãþæúóy>þtý)HþŠˆþ¤ªþHx¯U­ë€Ö?ôÅx¥.3Ý—mèˆcÌ„œ~œ·w®©˜ iRëÀj èidÏç…°8P2 ”4D_„v9éNdÊÁN‹`tçVÚ‹pšJ ‹k¤Ëx]F Ùí/2YzGíóUð?*ù‹ò¿[�içjÑN¼}Þ Q÷CúJà¿¢­}{ÒÈ H/)½'nbÅX¢_C­?�V?{�¨pŸ}@|VÑõ�|áKÿÊç¾ðÅ�§9ï󜧜%«ˆˆßž³ªÉ×X}d[$4–ï€"Á•=ª¬�¢ã »[Zò?Ìöì‰í–s†Ôµ+œ�·/ó[mµÕV[mµÕV¡6ÀV[mµÕV[mÕƒ)Ò-K›ÜH5K™ú]©"Á­h'μvyùìÇeÎ_2LML0À>1Êh1eãÐò…›êÑ~ïŠ"fÌ™�iòìíXWõ§V7³Úg$N–éî fQSjTkAOí}5äû:ÀW°˜²I%*]ÞeQ)e:ˆÍò¾œÛù˜J™êFXÉÊÌ9›r¦7)¨àÔÛœ¹ìn%ž˜‘†ÉïŸäÃ÷4%;@ÏbŠvní^ÉÁ:Þ“ ô,Ç>[;ç’ÃK$�ÙŽ‘«m´ç='ò>5 iH�ò�ÙìËÉ€w Ú¦[f3�uîmîÃŽ¼A( ÕîdÁå_nn x±–FËvwÅdJ®À+„�ŸPUhQÆ¥ou�J® ¨œ¬­¹°ÿ×&ÔUÑfÇí7í;ßý®o®ñÓì«w#Tã‘p+‚››/Žॄ7Þxo¾õ&Þxíu¼þÆëxxþ)y6|é{��°8èž+qEÔlø‹U}JM½nÖõD¤È�8ØÔ»kºCê‡UíZÅâ^*Ùœ#P"Ä[+ØÏǧõ´C6Ò€$v¦E€0(™óƒª‚S˜Çˆ� 0ø¸ÎÔî‰H†dA`Ê &$¡ æ•ì÷”Úf5בbÑ�–¼@+œ@UÓZ,ÇAN& .yž0gÁt¼ÂñxÀñhñ7×׸¾¾ÆõÍ ®®n±¿»Åìñ%(Ä¥â¾Â ¢Ìžÿîs0¤bÂíÍ-ž<}Œ§O/ðüò³»Á&€Ü”ã¬ñQÈTÐiŸÑ~ ̯£U¬½›À©nA�{bµ{%k‡^¦ü¥ÕŸÐ :{¸ Õn¬,Q™¥ñwtÆ©íœU-ÅECT�œØ�Ÿ J93ˆr›£º¶8}EEøšÛwÈ›/ó`?¿Åÿòb>GSìî%êì°ðT½–Ë«+{&w§%PèâD%̃�ä  Üí÷Ý…Dˆ%®ÏºÖøþ,Šiâ6¾È~^3êi©¡îsÆÉçžÌÓ½ca ¿“ÑóêëˆJÈE³•_íÏáu5.`©*�jë….‚À~Gð�ÿâ_Öœë8OïÊ< ÐG/QKÛmÏsÒô>I)Jú—ŒXZ\K‹‰ñ4öÜ?íÞTóå—1$õæyûkgpzjqö(ó}™ËŠu?´^w¡ÒKæÎ‹rä™ ª qW+Šu QFð»i3D†èé,]¢´¤Æ{4EûzЉõwî�ýÕ¢°ÂTªÆÇ øß­UCôHG´êÛ©aßKΩ׾®ÌµÝœ™ñUõ/-¢.:ä$v+ŸÑq¥^5àe#òÆ›oý«_û…_ø}U½#Â�BDÚbÉÜIÊA÷B K®Ô/}¼8˜InŽ¢‚Á£Ê¢+EsýáÎ-mð×­FX¬ül«­¶Új«­¶Új+ßçßš`«­¶Új«­¶*µwaE»ü^ÀЕ†’Ljš�ì̬À¯]^<ýM!i¡Õ¤Ûõóª…sÎf¯ Â믿�α;;ÃnLØ�;ìÎwØ�#Æa¨¨–·:{N«ƒ �_0Ëÿ΢Ýrº�“ÈÌ¡Qr‰sо͞¸Äoð#+U¿Å³µVUïj *_¤Ú¯ª mÜ Ì(&õÍ�‚ë뇤˜yf‹ÞP´9¥’iXLÕŸ’+× „ì�R#!Šª?Ža'=Q�P�Å83 #ÏŠIyžp8q<°ßßáp¸ÃÝÝÓñˆÃ4!Oæ9ãîn�»Û=öw{ä<[ŸrUï0ކ±ê9Ký¬”Фˆâêú 77×F$¸¹vâWkk>±RÐ… yU¾Û{Œà�Çx4ãáqÒe€BÒé2¤Ñ«b=»�º=3ç#ðM4#Z\ÿâ €zOéÚ¿;�5NÔÖñÜ—¦\iT©ÓÉ] Ÿ»ü%Õgw…•º�ƒ˜ßaqÓÖÎYdö½¤iôþcÅqM‹Ø™Bôyþì¢Î8äó7ˆAÈöC^ë%Tçòì<èÒ„ÞØ� K‡ ÿuyê‹D¹ÝMѾ?KõUÂþÊjÛbfzZ—B ¯Ðî[! P!ܬKÐéð[€åqápß(XÔßÜ\îúæúsÃ8t¯.×0&Åpˆ’9_—>m 4”ø¤ÀªÅGׇPÇ3Q?®¨Z–´±ã5*L¬ U|£�‰ž ï¦þçöLÀZ”U‰�àB'à@žiD€âþ¤ BÂ:q•‹¤ZïsUïcaA�þœ£Fç®�HV­ô©#àÄþÒ9@ø¿ßï9þ)i¬}žjïÜ¢�£@û¬FèX’^ñÉOàüÁ9fÏ\/‘Å&ùîp‡ãq‚J6A|0Ž ã8bS©;ÎDE¸jêï!a·;óÈòlz˜U°Œ¦^­W¬ó ) t¶~Opc¿fQd�ÖÇ¡•Íôû\œ?J»rUH¦D`öX bWÛšú?Õ&½8N¤Ô\=T�!3H:[䈚¥Î1n VñÈŠÁO*wgfMêÑjä“¢ú´½}›;ò4awÀÝÝ·77¸;Þáàÿ>Nw˜çw‡ŽwLǃYö{ sr‡”Úà”Zôƒ¿f’Ïåb�¨*nooðìâ)®.¯q{s…Ãá°˜¨wu9½1xpÐßµ¦ðm„ŸÎ8Ù�Ê5j–ßá--÷úô*¶}Š´Ø @�xVûcïÚ‘Ÿ-¤’×:æK�ÇVþ¯ tW¢NÚ²ÝW�Oºâߢ&hyG«Ú=\×K�ãõ�¦Û�´Â š0:'¬·ƒâ½|ÿÖ¿ý¿Â”'Ló„<«ƒË%.ƨóñˆã”q8üÙ•0ŽÇ)œÇ²÷´Àö.QèC¶þhqTìÿ»ù+X´ô½Þ¢F%,¦Þ·B¶jzÿO�2†UŠ/@é#÷1-(€ø+Q¨Oî äöõË3PU<}úŸùôg dÏjD÷ m¦wuDz²�F›ø(ÿ'z…!Hõ¥ÍÜ)Û>N* Ë\öfßOp%Zññ¼µ{írx4ò¬¿º�” `hêÉ(ÍÑC»u؉WÁR]¥§$*ik)€,ÊüÇ]d€7. ‰.ÌvüEL³nÀ‚3vJâ°óZ,4êüu1ç-²Lºé}":ð¿ºhÄÙÑôϦåT|¿È\W‘ågá˜ú‚©=\ �<Ô^>�ö/¿ÇÞ_ûv¿Ï-`†ÿë¯|û7þ—ggç7»³³ÃùÙÙÌ<@$cH#†qÀtœ0Ïs]ÿ§”0 C§Ö/€ýqšÀw‡fÛ/�pWÖñã8Vçªòg‡ þw.´Bêúh«­¶Új«­¶Új«°¶Ûš`«­¶Új«­¶*u¶Û¹R¡ªè0wídªÒqÊiÛ4dx>0hôüúêò óqú"üUÚÙó÷ÖÌÑvX„ zDÒd w´ bÑ^ÔÙ�ªVÐ�"¨”)nÊë¯s[ʪpG�n’6ö\o³­OÊ‹xf|±íW ç’).a³Êv‹*°Œ÷¦f3pnÎ3D²ïm8Ín)Îæƒì{ „Ä €�˜m³m}óŒ¡Â˜H"�LÈ�Í}±SµÆo.µ9­½!`a(SÛãÇi¾j±ù´3jÇ,`IbFJþÛÆœ«äU‘KDAÉ…-ÎÉN&2bEPzV PñEÈÉòÏÈ"ÐY+\¶)ŠÃ€dë¦öŽ›ãæÔP7M‰�H¡Aqõh‹Œ<窆78…ë>0)9åGェkÝÞîq<Í ÂˆÏž?Ã÷þè‘Æï¼óÞy÷Ý H˜Ã€³ÝDŒ,¶I?ÏGì÷òœ1çÉlZUNŒúÉ£vã<ÀùÙìÎÎ0Œc ý Ø�í0 ÃnÄ@ <±YŒc@ªñ m‡ÝÁÿ’Ï[í—Ér-ÌqRåšš?y.¹Å(xÏ\ò–2ŒÀ¾Imä œœ0AÁ° N$ghÎ�aKö¶b³®E‚NŠyÊ�|„B0{QŽó™ËÜ7C˜óŒé˜1ÏGÜ\ßàæî·×רïí¾ÏÓÔæ% æÞRˆ(×U\/,+»½ž¼ÏÜ\_ãââž_\àêê 7·7v=¡ ëßÖ@óð»øŽ¥ÕñRd®®ö_�%WRÃO«· Ôƒ(Q«~Ú7€5Qª8¸º°ÿWÕ¢ oàÕ Î÷4£:0C Õ)pŸ-Íéµ¼¦‚ˆ+ׯá3£=:eøfJ½–´=G×OeÙ‡¨{h�W#It þÜK»Žww·Çÿäßø×WïÁšŸˆ‘†»q<¹î¨ ^ΓEˆ­J@ëFJ)V%ä$@êÎUµàæÁ}GÛè>¾D§Î×Þ`þE­Úð½H¡Õv‰-N+ãyµ‹A@!†¥ýòêêŸüä'�Òhë.]汇؃ê*Оçã.Öˆr}¯È¿é\�^ÐWÕð?Ô`G·V]ŽÑen|#EœNmm&aÊrâÈ+\pŒaélðѽjþô|ý…º~Wà$ˆe¡!ç(¶Çr±©Ëç‹¶ø€…ƒ1µõXg³ ]›Ö¶]ü¬Mî+àÚŸÞ`¢ß~ÕµkzA'!œÖ>ãUèv¯BC«‡5¶P`.¤Ä¿ûµ_üæ¿úðµGWçìœïŽ»³3aNE”1 ŽÃ„É]“EvN6†ið¯Ùœ«DÓt4¢²“î'p2’j±úokw^KöÝ¡wÈ« Z¾³mµÕV[mµÕV[mÕj#lµÕV[mµÕVma0Œ5kÛ\óÎ5ÛÿC2p©(¿EÌ " ad¦³çOÿ81‘©ÿÝ2^HÌ0û²¡“¥YçëRQÒÉUZ”ÜÚdYnšV`¤íp»HÀ@{ÉR7�ºÍc²ìmUª®�ðl`4UXÿ³ý™ øËwËÿuÀ)—Ó+`¼·ŸŸOÝT-QÞβÊM½l›l¬-g3¥„qðÌvbdW[+Ì*ßÀñx÷dø*ed08äjC´n˜’+é ¢p…{t[¨*²…ÎmìÍe ¹tH—d³Ÿ/m”wåºc^tµö$†²`®Y¿øËð» R KÌ×E/˜qµ«ˆÖ óbOÚm4zÖ»e§[›–v�œ‘³@ò\£³ý½dš¶î*±»¶�õ"ô¾MjDŒæ€ ˜noñý›üàûßÇ£G�ðÖ[oãíwÞÅùîÜ,SSÍ �@ÃâT1|õë�2;bГÛÔ'€ÉÓdµÓl®"Öó‡qÄn0îvæ‡iÆt<š5ÿáˆyž0O³G+ø¼ ú[çJ()ª8QÁ<͘+ACB¿×ªz³¾�J*$™2.rθ¾ºÆÕÕnooÌÒÿúÆœ"*À´tazËù5˜a‘AM÷âð%¼OÉ.!''ðªÞë�~EéêBµQÑp€ø�ÓÔxjÕŠëªÉÈÞχñ’\Y¯¨¶ì¥é:õù ¢_U¤Õšœº|ö50·Ø¿W6SwÖ´r·{Òÿû꣺š·Þ9…¯øžêJFùZ"„¾Š=·*¦izqVvwÎ~ý )A)Ø�Óé; Ú«ô»ã[¼Q]ã!‹ÅÖPhÿè �ÿ³"j¤É2Í’½Lÿ.³¾é¾×ÐÊ‚ê” Sú*kYg,†„(ž^\à“ŸøT¸Š8Κ:ZjtA¼ÿºzVDìN(ÍŸiðK€Y»uáél§XŽÿ�s°Ò–u%[œâ$$‹&^‚é¢�:$eAî¡E�k »å¼.ç˜0âk} ïÔgèÂQ¥Ä5Er…Ø–ø³(Ž'6‚!l�ÖâëÉv¦ÑÊ^;’@$côñ"qnhöͺŸN¢´»}¡º>FXÄä†Í/§àüzÌSQ©¯z?„¯xÙùµ¨–ÎkQ-˳IüÞOþôÏüKŸû‘Ï<îv·g»ñ8 cNÉÖ…@!¥ÚwCöm�œRÂ8î0îFìÆ]%ëNläÓ²&f ɶ¡Ó0TðßÞ7¶×¹XY™F%zë„´G›ÀV[mµÕV[mµÕÚ>ÿÖ[mµÕV[mµU+r Áazw;W—Ãì«§9W`…™±Û�Ÿ�ñ¸ã‘™Î÷ûý/p•Rû_g›ŠA{S�Š©ÖI©nöرšª§ÑZ²íh]í¶×£í'P°¦² –¶pÕ™šÅ¿ºB›k®%¨—Ó4p—gíœ,Á‰Ûv§ÂUν5lÎÄæŒ¬¹’LÌkêu%ªªßþ€¢ÚÐ’Ûš“Ë*‚ ËÚÔœm'Ö�}36PhžÁ`±Ûì’úm#x)ÿ“¬Õº¼ÚÅÆ\Vòìáš…3Î ÑîA Ð,˜³`rð?ŸØŠ÷ö°Ea• b6’@ù¼¢Žl}‹AÔw¨„{×¢ìM%ŠbÄ•j noÍFX…oè{N¼–Ø *Ìã†+'ßT:Éž-pãùù9Μƒˆ0ϳ$ ˜g¨EÕ²êEpyy‰ëëk¼ÿÞðèõ×ñÖ›oáÍ·ÞÆÃ‡qvvÖ~îZ!b„;Ò‡XGscoSÉ‚ �··ŽË¢ Éâ„;1¢ÀPÉ,(Vm÷‚à¹Èì¹íD¶¡\H>Ò6ô‹=4¹3BJ¦8Kã€�‡ŽøSA�` KdñðqUnÎìÖàSÎÈ~-yž?TG�ñ­ ó<#Ϲªà*°ádNæˆ0$öLÛÁc>Èä›ÛÙˆŒªþ¯„Ÿ ’“³n÷{ÜÞ\c{‹››[ÜÞÜàp¸ 3Lkç¥rœç‰iáW\fäh{¡…~”–¿K#C¦|7æâ{‹ÅüÚ;±ÐVzeÑxw áþÇ+Ó6]…ß÷ŸZ•Å5s~E)¿=°pxŽd‹zÕ Þ~�$P½ßÉ —û§ÖЧ€y?“aa¥�n| ö•E>ú²A‹“JËo_¾ŽÖnÍÉ…^@öxÅ4…•«`¤"]ülUí@ôéxŸ�ûµë=1à®qPøWRœÖgh�íc¹ºN ör=µo_íDºxò¤µK�± Üÿúlsù‚ŽÒÔúJC´ËZ¯Í—ÏŸãÝw>Ñ}�¹ì¶"1"£™è鶸gT"ГN–B‰ŸjãdÍ‘$ÿ å7½Œ¥rÿ ˜<´DŒËùpSÆKi3�êq#NrçøÐqb®ýé¹é‰Ú^Ã¼ÞÆpë“rïXÔŽp‚.­’VÐ9 ôsMuÐF±*nNmí…Α ‚ù¥Íûu‹®\oœñ£ë€ƒÜÀò¥»ÕʹŽÍëÉóðÕæªµ)ž°:‘ß7°_ðAzß3 ÷“äÚ-¥ëÏ~ösÿ­ÿÉŸþ^J¼O)˜9¯yì·8¥B†±‚ÿæE5"¬¬¥ËœÌN`Œà±úOihÄG_7Å5ÝbžŽ˜¦¹ž»R7±%€•¿ˆt›¢%ÿÔÎf¬š}SÙ-æS±Loê6-ŠsôÖ¦$0CdFžÛ&™8Ø[Àé²Wój• 9C‰»�orâEu  žÐå�¦žb°ÿi혡J�rV\ýÌ ä¬FœpÕxÙh®ÖåÜ"²*òlñEed ŸF„lSÝ<à ´Öàp ªÐ¬ X ¢Üá¤åïFèr6P¨Ø<+™j›¤d½£ö ÕÒ·t¢p]T²£Dj± ÞÛ¢âÎŽåýDµfª–½ö¢ÚWÑ �#1ãv‹ÛÛÇ"¶‘šJ¤D²ã¥5…vÔßUÃóFÔa>éÃ�\ õµ©½�Ϙ!½Íl�L[õÁñ¡ç…èã×Üe–ûXIC2B¸Ÿ3Ê.c<€™¥+—¥9ûg¹í¿9àñ&)±Å ì×F�ˆùÂE™Ú >¯Ð@îDÂÈ¢Rp=AòÍpñ9íîpÀ<íqww‡Ãᇻ;Ë)u\<Ü^jQÁî\ײ¾Ãø.í|zðž‡ Žš¦R°Âä$æŒë+œS]ð2R9dcGÀ4½]DèúmyEÿy^"Œ«ÀJ#8Uà_W@ëw†j;TJZÐq¢7ÍÖÿÅ ?ºçM8GZÍ^tˆî�RXyiö+Ô·ŒD'œÚܯ]qBÊ€¢�(»{ªCáúúºeʿľœÉ4MØ��Ub�ôŒú0‹;*øenD 2¢ÇÍ”y�¨§™èšÒ_ï¿w qÌŸ@$!;žNæ]¼>Q‹ë‚BAa„)�tùª˜î‡#œçWû$çŒgxëí·ƒ"O=Ž@IÁþžìJó4#OÍ.\Ý»¾(˜ hZ©¼£üÖ±"vu°(Õ-Ô¢í÷-P�UE›Ê´m¼µKœ,6‰ni/s6È™A‰PÏÔ�Ǻi[ö øí Dmöû,õQþÎ VWD{ƒ2H3-þ l(V‹ÿdˆ\c!Œ8 ÒˆåsIqÃ@T­÷›” š­Ms†J®@M¢D.€oÖÚ'³W/mžE‹i@WR¬¸µkfâúßþ8¬F&ð#–á}ÕƒÊ1¢#­Öÿ5‘;.¸ãEòˆ”�†„Ä©çÅâšgäÃ]užX Á ˜-þ0ŽØ�ÝöXS·„âŒPÀÿvN¥O—~kNŠD pp­€�—Toªê‘¦œl{ß‚ Ê]‘w¾¢È´P‹dÇw'ˆT %܃­¢NÀÉ­�×6ÏE�$à} %³¿õ›×qP¸FPhTÊ©n˜3ŽÓ‡ýöw{ì÷{ÜÝ0ÏÓ=êì�‘]g-?,T¨ ‹ð.-_C »åå±ïQu#8¸D G›U4Ýó~ ©ÂPKTÿÄÒ{Iˆ €fm_½4ª¦‹KÁŠ\xiCM§ºò5¥yë„u�.MÇ»÷4BÄ¢*¨…õÏ]€Å/ˆ®‚ë'­…û¬ÕïTOT½+mÁ»bÏ›2ÚµÇ>°ìÏñ5å¹P‰z냕1u±åy¯µD%9ɬØF+ÖA`‚=3bÎ�øZ¤€ÿŽÌiT£Ö{Æ2:ç>—†¶hÏy8˜­á¡Ÿë¹®€ƒÆ.•êí÷ã©},�‰@±Ÿ.ŽíùÏž]à�·Þ´ö @îiÏ«n#º>g4U}r»÷‡£Þý„º¶¨óaŒ¨ð´SÃÇ.¢èAÿ�3ªPo`s!ƶ0%ªÏÇŽÞ¡Á� ÚÅ­”�’ÏQ� N/ŠVfq%æ†ÕùÝs¨k{]ŒÇRSßwº3Ñ~ò‰ÑGqŽ© ~èlºâj³ ÚR«êræl/ÍQ 'ætà¿âÞñyúÜ\üœèú^4«¿ð3þ^+€ÿúèµGÿ£oüò¯ýÇ9Ï7Ìt Â,’|9CÕHáí{ˆ¹¡•u-…‡[.ëœéˆãáhkœÛ=‡;ÌóìäM�”ªÀú¿“ði»ŠXt’E6Ûæs@«±][mµÕV[mµÕV[Ø[mµÕV[mµU¨ì–ìûÍØ�;œ��áüü¢‚ÃáàùŸ™fd°hÊ9ïDòkP}´ßßþzÙ�ïrÆEWæ—ÍAômóˆ{‡"­9£Z2è#äã@eÌŠ4û ö¼b®ø"LIÇ™À<€UoÍ”AÖóLfn¯0‹p)פfµÏ–°qUÿ[€†ö;"ªeD!Á @s{ŸÜ·ñåÖôÖ¦ó‰Ìk^>EáUUÝaoºnJS³-fv˜lS9p ÜžëgÁIU¥é6MM)Õv_E]ù_`'æ^í«Fr(YéêȉyaõÝÚU¤lZ{{ÎÁzÔvê‰[žuŽj5mÙëåèÃ0€Å2N®„ï®Íe ´-7‹Së�횪êŸa¶ÉŒj˜¼=Å=bé^líÕ+ÜÏ™ŸÂlÈ# �ªª’â �Å7k§ŸÀl.Ã0€9U�Âé"™*À_@g �…â« KðC;°}‘{½ˆÿh ­³SñW^s—¬Øów¿óóÒÐ_#�ß½œÚ5/• q©|&º¯åè4£;¨Téžù¨\(g±Žž¤P}ÆiçTPNB�Urw+*UŠ�û¶»Ù DâµrsÉ0rjDLÌõ–¾eƒCBÜÔù]ºF G�ÈÇ)¸Z{eÿ‚Ô½srp”é8-»Ô=ÜxV`žg #Ÿtï¦h·9Yã˜=ÉŽ¯†�sD#}X—ùý¨þE¤^(¸öòö|nDÉåÈÓ“5D77E{‰©X�»5E!{Øçº“Ð2Þ¡6‘}Ú)ñ>W/ç…ºf nuàÓž‚¾û¬å±Œ»9±=Ó–DŒªîïÎkÅ­"�"ºþ^ˆl‹þ\\cš+VŒ)óõ¤‘âzp°éoÍ®X#ùÜë—Pç?ŽžF0Ðâ\ÖZºÎWêq^‰žT€º^h„ƒþcIè{¸jlÓSB@¿ÖnåÖßï8N×£:ò\]¯éÊs:¬_åKW?hN‡Þ?xðççþ¿ôkü3MÓ5€»”RHyΘƒ™ÜÍd†™vYÌþ�.±­¿sžAÕ˜©ãñ€ýÝö··8ÈólÎV`®JÉ�ÓP×î9K#͆‡·©ýÍ…îx4'¶ãqÂ<뽋eÚj«­¶Új«­¶ÚªÕFØj«­¶Új«­jåhaHŒqLÇÑr«5[Nã8 öYˆND8ôµçÏž}þxwø)b¶üðþ‡ÜÏìÖ�*˜+Áœ<»ÝT%ÅV^! �h·‘Z•\ñ"´©ÑËf¯Aþ¨¶‘fïmàÝ8f$ÜÚ!7ÞÔU9 àD…<Ïn7é™–P�ô×ÄÜ 7f ºþÀÕå¦T™TAj)ë ÜßÛC*x^þHÉœ×\_ײ«ÀJ‰�`ñ<]ª»*9 (ÿ+  ´z Z±+�ƒ:´—MÁT9 Uf±’õ¾æIðÞvÖ8‚àv Í®VTA"-v €Ï (åà’ ½E»ÛØ[ßàf+ ÛÀ·á5ç@C!û .÷�©Ùÿ‡½ûœï­Æ¥[ô×Wµ¥ø!kɇØ�»ÿ—í�ÿÛó4ݸcæ °Ø#Õ ‘9+˜íŠçÜF ðè5-߯ÌÁèp<ân‡»;s7𿩯% ™æ$ÙÒÎ"Æ‚@•ý;•‘æÙ€ÿãáˆãñ€ãtÄtPúιjÌÑ]¶¢V57ùý<Ù̦æ¹P€p™©W|yŒAÓ©~~œµÍ»Þ.Z»û Å.‘ ©Ø…ÿ%'>09üìÈ7¿Í”]ÀÊí3‹Â�©ËO�vÔX±·1·LmU0¥V`íÎþž¢ ¡HsI£e5¥f;ïÿHÔ‘AÊf9�ªøÔq,‘ Üv¨SPÍù{¹Ê›ÉǹbÓúA“˜’UµÛð§„fmÊC7T4‡�8b¤–Ò¼}È€rë¦ì‘N8]m3D‰ÀI{K0¼,bµÖÍ‹3HÈ‘�„#ÜI€úø‘Ú︟˜˜u-Œh†Hˆ‘¤‚h^Ú�©ÅWp·D;@P­ÅklE½îØ÷Šý¸EX”ˆŽÌš¥nêÆs�gp”¤[[5w�Š?t6äèPœýžG œZCl,+K2’VâünsÅ×Åc(¼Ðæ§Ö'¹) ¨Úå¢7âS˜¡Õ-¦¨Ù{lÇ]/€+  léÀùFx(ó?:‡ÇÄ,­ÚkŒ�Ø#I ò¬[ؾŸF,É‹§D ðÐIdƒžô—5× ¸O¸ÃNm«%¶¸ÏKEü"3¼x;Ñ’8\sVÎ�è¾|xœDT¨ƒ¬æØ²ê§°ÞŽn#ßñ¸ˆÛ8uu/AÉ*ŒœÕH�x¢¾¢¡ó¯‚ÖM§ÿ¡I#t|ïyU2Osè(®9T�Ì>c:qs}�×=ª€_l¢îŒ¼M—çfC£˜ÄãY �º~…r…È)ª®9¥Ÿ Â5•¶¯ñ2/Fu[\Çi6½��žàBÁÙD„ U[ãÒR=^¬†°²Ü[S£‡ë¡ûθ¬!µ��Ѩú/ÏØê4€…ûBŒýˆwqü×>"‹ùªÿÃÜ—ñókl×jüDäÂ,­YtåŸúr›ýð>=ñVˆa;º:kЫ QÂ?ÌÿtªðRú�¾õkßþïÏy¾‘M6…òd´æoîZu½H.nL~…9g§ ‡»öû[îîpœŽÈYÀ̆bÿ?Vg)À"Ë8Ä¿0rnŸSÈÛ‡ÃÇãót4g¥<#ϹF­ ó„9o[Ü[mµÕV[mµÕV±¶ÕÑV[mµÕV[mU+9�Ç©š9Ú7 #ÎÎvxøÚCð0 ÏsRàlw™øÑííþÛE±�Kv»ÃüÉnYÔ™UíÈ °ZÆ{Ù/ö·QE¯m3ªØÖª(”BSž 4Õ” *`rU³g¡We+3'0)@É•un¹êÖópao'dšÝ&Y2� äLóß{à¿”mD«ƒ€ êTáL÷ä�ú� €Í<+jV˜’‘7Pé�˜ó[-—Þ^ωƒ:γ>‹õs±èvÀÀÅzfÝÆ-jþ1Ÿ€´�F#E¤ÒÁK–ê=1X¥ˆÁ—nÌïŠYŠÒl�€N¡o×ÌaãÕû�Hȶ·£1q�‰¨±ß*€Åk9¶6'.ÙãºcGà�še´ôºÖ—{˾éÌU}\úC UÛ½bnÊë*¶ŸÙ‘r¬ ˆ *’³mzZØ›kUkèÛ\•ÍD6vÍ2–-ú!öÝHÛ)à`ȶX_”h¼PpâH�PúŠB ¸_�²É,ÿ¹ªÑ©Y4£Ù€£¸6,<„K¿g'õ® ZóÏʼn¾u,�Ñ4j4� ÒmÔ˜’ÎÀúCvÕméþKË"‡žxˆhLKY€\©Ä«Å|ÓÙ_S—ØÞÛ:G"‹†Àî¡e;®´¶Ó>ÓèAŠ*jm ´Ö¶G§(nó µ¸ŠÐÀEaÜ>ÒÇNuhvÛ¹~ÖJ‰ÇD„gCl� ÓJ*¤ „ T»ã% ÀÜ*²÷{?‚玈öý‰¨Ì Ïvœd,£&ê£úÌ×¢èïFDy†D•º,è8‰ƒ¸ÙZy–d Jç–m×çiZü×D´7 ­™D2Ò�³åqrM¡ÿ—¸–0ͧå<æsz=LU¾s� D/v¢xÜ%áÍ�çE(#õÏ`œþ§k³µ �s9=Gi?´¦nW<þ�^½'GDUÛsH #G.ÀjCËÛPû6¡“¹Š*ql9×Ô¾Õ©½µ%Pƒ¸»¦ D�¸ú�NÉ­'Žöœ±ëÔJrÒ"IªuA‹ÞjóðRpnî9b㢨þµ¹¬(ZÌNl¬ éd‡øÌ&]Üÿ°¦H7f—Dºxñ}ìÅ+€ÿL |î,cK—ÇY4´Ê‹¿ï¨¾øgëÑ÷ý}}ŽÓaòjƧžßËÀÿÿôç¿ñ­ÿŽW9ç½*&"­q^)% ãˆÝ8bRý>`‘X1ö„‘×µœ³E"¹:Î3r–£�Ø”Qý_Ü›r!„õaq(Ä‚išÍ™Is%26GŠæ¶ÕV[mµÕV[mµU«�°ÕV[mµÕV[µ…Á�|£Ô6u³ßÏY@®Ô>;;@vrÎIEμvww÷ùéxüiÀìxsQÿ{U*Ô­%Ë/àöÈP§?úî]ÝHW�JÙ©}s+ˆ�ç¤S˜¸:¸l¯‰8¢A�©è³[«-m³›s~ôáûïý¦ª°eg›ý©–_Ož£ Û´LžN¢PÖ°©Xë9l<€PÊf£¸å¿+„ØrÑ™RK}“È6§ÐoèjÆ–¬�2šÄ@ÁI”°Õ25f£›Çx§˜YZ-.›JŸ˜‘(@Wц["€·¬á¢ m®Ã '®¢éb™]‘nÀÕsPL•Hs>ë}dÅu³½®$ `‘oìÖþ}“6à*ÌmŠçÈ–(êX“ŸYv}Û0.yó !q°A½è¾¹Kò‚…¸ƒæåže·TÏbÎÖ~Q©[ˆ °€Õè $A!è.ñ‚›==Ú3Û pPµ)Ê�§Œ¼»j•O\ ÔÕ”®@W£¡_b8H //äªJb=ɘ'¦Î½—bk%ét6Îo÷yq3¼|´�õ©a.ÅÒ>(倠š/!g=X†#(DIƒx´ºq4×�jû�X„ ÝgHãƒoig±/‚ÞÖ 4N% p?¯/úmœOí5ÙmÖƒK"™!Ü£@x‰âÓ €+òÎ!!¾Ð¯©‹P!C}*Áœ¬ ‰µ>�m\´ó¨$¸Ä"PmX ²D1ƒxA);²AÈ3_ö-`9+ñɨ]…k ˜TºÇñ^"ª�«A³ÿ�N/ÚÏõ‹ùò>L¿ØTwý”°4d¯÷¦ ë¨F¾�0Ð~·ÿ‹óF1Ï ŠÑ9®‡NÖ.§m»&ëÑ9-_×£Á‘צ  u¡ᘠ\YË<ö >p%~l×â¸Ô_�úüQž½u OYB¡‚G <�¸¡¡D$HˆYY\ ÝÃÑ8ÿ—ÁÉþÔ0úëZ(ü5 Ð?CNÿÛbNÀ'±Æ¨–{Áÿµs $1E‹  3E½3O7Ÿ¯�™Ú-Öû¸ü_ŸÁZª8-'#=‰œøûë�Rúýoþò¯ýùÏéGßÞÜìEä˜%«�ì>w3cÜ 8;;Ãîì cpÈñ{X]?˜ûLÎF0"™Ô6Jþ]rGœ��ãìü ã8‚9A$Ÿ8£Õˆ€J¸52€ÔÈ ŒœgŒ2#çÁ¿Q� ÂV[mµÕV[mµÕVqŸk‚­¶Új«­¶ÚªÔ8 ÅO´ZÓ‹ fQ ”fp,3;ržÓ<ó9ŽÇGûÛÛ_-6ä"¹Ï»¥•|ë²ñi µ‰ÃÛÎMË/>²øY¯ú’jM¯n§¯Päj¾¬Žþ¥4`Fw0µ U? ¨×Ú¤l¬VÐ.ü¾Â1v¼¨¢É㬥µ:8¢€eåuàæï[3–-¾X}GKt`@µøzûö𦰈†²™Æ¤`MnélÊÓLeC:äâ–MਫºU´6[ò² W]è•vñ—¶q[ç²á|ªXÑ?8»=?1€œ;ÅuQ5Ë~ÀòKÝâ¿î—«5¤uÿ}‹¨Xª)v  Bþ® ¦¸Án™¥9Q.*H p,�©,óÐ Ò¼¡KóK”Å©Ô{@�¬¸¹h,Û®µmt•H¿*«÷�7t@[^l8�‘½Ýú ¸U1“jF:¨%H%'j=û‹�wd%£; T$ßœ® C. ¸@„j^|U<#*©b#¢-Ba€> 5üŒ/(8] æPÛœÂõ‹äjë3åÛ Ê¶m5ãÿú''Ó‰b3Ž¨Æ ¢è0ß¿¼›g‹ò\¦H(G×W„¨Zìë"ï\—¹Ëu˜h³?WîÀ@›þ%Re|.æÎU$ªX«’x-rÀï…r½ëk¤·ö®|•0—ž( ƒý;°€F{%us@‰–üº˜îü)êý³³þ>YK @$§êàB8qZ)…UEN2kÚY‡·~_‰TèSÖòã©»k‹h†®NÕ²*ëVÛ `šg(ïYÔ,½ñ_‰äJ†A? v·‘ÖúïÊùÝû‘‘(ÈàjmîÝg¶~õbpKqŠðâT�OëçU�ö×0[è ¨;t<âz˜ùÍí ¦ÃÑ\¤¨¿“Úe4â×É‘º)£Ï’ïRæ«kNÿ¬­#3æÏ«v󂧤=³$Õe@ïjÒ‘ÂçЉåEìOáy·²Šæ •}üü…cO@­‘81š¥8JDຶVpDA{" Rf$éz÷[ö³Îª½-Œöî!z¹€ðð_»vV]þ}Ѳº\³,¦žð¼ÓþÿÂZ«}a}ôãd ÓÚ7›àž9Œð÷‹Àœþà[¿úëÿÜ/|ý›ÜÜÜÞåœ�Ó4ét<."€!%¤aÀ8ì0ŒC�‡“È  <{‡¤‡±F¤Á€üi:BD0 vg;ìÆ»Ý™Ï¹ÜÖÚÞ—‡aĸ1c%ŸdÙaF†=Ò@©’™‘çÙcêw¯Ûj«­¶Új«­¶Úª®í¶&Øj«­¶Új«­J%� Jf­H #ÏfóNƒV�Ì4~iòùþööÓÓ4ý”áÒ) ÙUàe£[¡ úª@yU¬*‚"ÝÝܲ^\ñ]«ªXÛÏæ 0›š…”ë†'Š ' »�e¦ªš›Á� –Ùå#\È� pPfew³ž¥rrÍ\ÀÉ�íerà<…˜€b{¯š!šƒƒ‚‚Po×Â8ÁЕ"–›i‘ÍbWPl÷ )_íÂö¸Î98  Q¬ ªgKWo�¿®º×¶�'Ú,ËE5—hç–›+DmyªÞ P.ígûekÉl·~iV¦RÛ¯nR2;I ´Å øVÌù=ÖfÑ]ÕÓj§­ZÇŒ�ØåŒµøFT9m…„5r¡SVWEZHÑm®‹øÚBïPmîÔº0Ý^*n;Ѳ*À\Ï…H‘†r%˜T«W½ °2v;çbžŽ:^£é¹¨†„r’!H À´€Êɳµ ‰‰Éç!-Šr´úR#Ê)¸9)§8o\‡YªM}‰>èâ•üS»D4 (R)¹<€ 熶Ÿdq{J� d!ïÞŠêbV ð4­dN‡ `Hè/ @s“üj x1$ÈSå³µ©›rµ�Å$ ó�ì¢Ñºs�X*ô5�j AIûä“`†R@¡Üc>´2f@xísAÕÙEcœ ö� dÿŽ‘+øV#³%ŽæäWd‹E F\u‹”ûJ¨XºkZD_¨Ï@Kµ¹jßG úOÝ컪Ç*%º[Ä&·ó‘î9�å“Ù ]ÅIh]ñþ*1í¨sÎñSÇÆbÎÑàèð‹p¬$~4 ˜‚üË ¨{¦bÑ)ÿî�ÁûI´¼/¸°Ó«¯Jwô˜2y›]<{†Ï|úÓý¸¯¤{®v îÚ}‰Jƒï5'ŠJâqÒGéã´½#ÀÛ“î¨[ýØb ²5Ø|6áî0bÜH)¹ó!ñÓœ(Rb iÛâÞj«­¶Új«­¶Šµ­Ž¶Új«­¶Új«Zœ³ çBj*XdH(€‘‚9ÏCÎÓùÇ~ømU$ñ,øº5ÈÁf2~ɧ/ •V*Š9gäyÆ{Ÿ:uêâªÂŽC°cÇה˩rÙUv¾$NÀ ,!K H‘@ˆ<‚¤  <€„�P$@B "O‘¥<¡€„ $’‘·¼$eWÕ¹ì½ÖÿÏ9Fo�‡Þ[ï­õÑç¿Ö>U¥ª·£}ÖZÿ?ç˜côÛ³·²¬  ®S9XÐtF@̧ïkPlE¸®Ï½…ˆ¬=cw+.¿×³u4ЭœÁ-dÅ‹çËaáG‚ý¿·Ë—¦Ã|Œùht)@w pFSUûxïs“'\Ws)‘QYêI>åZ³"•=AÅæˆÝÔLáM�€…ðUìe(ÄÚô1"NaÛÙ[ÎE�ìçâ•Ñtï Û›ª~´hWOè‡�,wLÇÊ㊠ ½Œ”ä×Í`“޳ux§„–Nüš;$ø¶×‰€Nוx ú0Ÿüq9&‚ˤ'�ÏÐÓY‡¥¶Ti´ƒPGª$Âû¯¿Âý;?ŽëeskŸ'é ± Ú&Pw™D Üó€V=¼Hµçy��„oЈ˜Þ é�c…_;ÜzßHT�˜àÜp°[ÛŽ ý°þD�¼E\ùgÌÓ}g�»¿Ž„ÏðúÉïº#Ž>hG4G[ûš»�Ñ,Ì� #&t7#OR‹k§;OþŸH(Ö�0¹—ÅeûGPÿcóC?èÿ¦óœˆ~ã�ÿ‰?ùwÿêßø§þ"zN9Ýä#gÇ�}?°ßïí»N!hdifFÊHueëß�6\è‚t¹àò†kÔµñiÏÞo¤¢ Dí5`ÿ.„‚ ×ËÛåR ¹:puÝ*×wKŒm?ÚøâEXµjÕªU«V­ µžŽV­ZµjÕªU­.— D©€f`(—Mö|äÈàˆ ‹—œ�§¯¿úêŸ(’‚"|îŠ~N]­mÚF]”×  ¢ˆtàÝ *Rà5Åö ®GÙ$fTP8ª¥yÏ›-ïaJ ÄU%\ÏË@æA@ªÊZ§$— ¢‹Ëç&.1Û»¥»ßØë`¦®- !•Ï©Û4QÈ‘‘5×cö¬S€«*Xµl A l9¥´Œ Fé–¯vþÕi Sã!lK“Ëû6»ié± v=)¬(„%¨ùáÞ“k;v5.ÜùU+9Aj ÇÍ×Q|Ùñ™Ò@·hÀ°InÊu•rݪR·užmá6QŠJÞéB[ö8šj€VB+HRë;ÔtÚ¬»uîª[åùªäoAÍÄ`NH¬ŒÑ+¨• f"dPÍÁî`„�‡)×�Q í,�¡ªg«B;òƒÀÈ7†‹SŸ¤I7é¤�÷.%£e¬w÷¢fÛ˜®TUd‘®Ê÷àƒ ´ªˆÅŽ/¬®G&â×acÇÚ‰>e3¾ËÍKÌG¬ÍúÝ}BrŽð¢JgêùòÎ:œ-nÄÈN©.ªƒeµk< �wÄqÑϾ™@kï1?9€ŸêÀ]ï¡Ö[D5ºWDÖÏa¸HåºÂ¸Nî³ÍeÄYø«§%[m*dzЃ wžÈÈE¢J¹¸�k ”íÐ#g¦Ò‰Tr†Yé¼µ5Í>‚p^îe´4ªtá-¼5Ä‹ôs«1:¬N ׎£ žÆÑ‚¨�WÇaQ„¼ˆÚ£�¸1€è6–£«@~ÅŸÜË^¯,‚�9®q:Û�àÿ0þ#y�^Eî½ç�†¾Yó«göÃ�Œ�µ“�!°s÷"f:ŸŠ#ç¨úêHCm�÷uéûßû¾ûßm÷NËÒˆGþ F|òt×ñÕ°?ÔÍ:_©-;ú9ÕÓÙ‰&�d<¾?Û½lÒÜÖņ_IQEð=ª¿)¸-‘š¹¿Fà¿~ƒ"€=€ÿá\QM¯Ó'ž!Fåì9¡Îe€‚¥~$tÀ=_9c´ñ·{Üê‡;ËÔvþg²À ¹°¨>˜(½-^¿Ó«ž§ÔÄX!<³6R%}\õÿ#PšÀD¿ùŸù#ÿèå×þêßø÷󑟉è¶ûq¿Ýq{¹áv{Áíå÷û½:¤1Ž}G®na’Ës¼ªàØ3öãÀ±W¶ã8h¹\ ºëÿëEšòß¾/û�c;p¹ˆ‹‹}+À¥5SÂõzEJÅ- ¥üK}NÉ•D½§£�yE¬ZµjÕªU«VùZ€U«V­ZµjU«@§^ Í–A,ÈyÇ¡ÕLªr•|¼y~~ÿÝÛËË5kr‚̇ý²|WÅ-¢Â¼�q*msÇr½ûæ.9©+Ìá,»ûÆdý·ôlp‚˧§Ú«Jݨ.òÊ}£Ô~-à€äG6üšwîͦ²ÏyÈ'�§ª +3x+ùä\A�F"�\¶ bÛ °Sî"i%/hµƒ/ÿËš»€Ô¬Ð;1Bƒ�«·oí® qUk_ªHT‡yE&¥¢@®ÿÌ97‰œ�b.¿–@jãG{¼vµoóŒYú_�£*�»m­�43#W²Dv`‰ÔHŠÒ&w¶<õ-µ&GUÐJ¡CGí}n+ŽúðíŠ~Œ–Ø:ä¯�jY�(ƒ‘à?=Ï^øã´ìõñ5ˆ-â@·âà_jvï2#ᢖ×>s�À˜ÀñhÄ…ÏPÑ‘«‚3 yî&5åq>zœºx¨'ï=:Þ„dñMJ1 h�dô½ÿÔú‡þîŸÿ ñß}~~~VÑ1>|À×ï¿Æû÷_ãýûxyyÁ¾ïH[–.8ŽÇ~ 9ï¥_%ã¾Øï;ö}Çí¾ã8Žfß¹^!¢Õš?�Ú&çŒ}¿#çòL½m÷xÏ÷ß(#Ë�B*/Ïî—˵)üEOÇÞHâå5;r>ÂsÖªU«V­ZµjÕªR‹°jÕªU«V­ê7U.` 0- ¦ô|�¼o¢ù­H~û›¿ñ÷EU·¨NªóU‰!NA�av�õC PÍÙ�ãôîvãÜþdöJVo›$âš¯Í \ƒW[ƒ¡”«å=5�˜Måɶ‘ˆ–ý�jÙ^²2»exùl�¤ʹ)¢$W{Lõêæ¨ú&öÊmÔ Ìrö±P+!�ú2-Yò,RmÀp ® &C@bªé~íê5‡k„z4 Wr.Î:ÝÆ¿(>¥8A »”(í¤ Sž×±VòË8$¹ªb¥ëa ´±I„Ä©ž=& a{úV‹w!%.ã°)¯¨}f‰­(ƒ)qéŸÁ…,�‹š\œ¥i‰öe$RU)y©ë¹ZÌ‚péË;½ÙkK�qÈ5ÆÁg$ÀPÉ: Tâ*T»ZÜ~6b…8'(A¹‚~•c„” ô&Í«�$cwêsTE{#cp—fÙ k�:ÿ¼ÂÙ[÷“ˬgs Öýÿ�— š[„„Å2Gn j; ’À-¢™ÀFsîp I®Q²S‹.³ÚÔÌ-èû:ém°í Gs(óÑg‰ÃYü×ö­Ýc”‡ •ݧ,g8"y}/šËØk`‡?6ª{ÅëJûrîÒûÞóÞ©õVÂ!¢ Ì)ÑÔN[«˜šMý¹¿¨êm¿ïYUñüü_ýð‡øúë¯ñáý¼Ü^êsÚÇå¨ßs2r>°Y €¿Ýp¿ßñrÛq¿Ýq¿ß�snªE¡oÏm÷ý^È·;n·—3Àý÷%¢£~G´ïTr.¯I¼á²]�Ÿž Ñ6ÅçBªÏò[JЋ‚¿ ³jÕªU«V­ZõûxŸ5ÁªU«V­ZµÊ*m59Øçt²ÖÍØbñ=H5_%ïŽcÿüùÃó/‹ä–ûìK-×ÜY¿Käš»Ý\=ÕðÖÉ– ÏÜ6Ԙ΀ºmârÅœbØ}>ˆ Ùr&¥ƒ’\l›¢\}¹Ú®õÆáˆ íŒëÏš=»÷rFJÍØµ©«»-­6ì2Vâ‚Hn ‰¡I¹’n/¸Ù�*kSéZ5ÐE鎠ºøMÙ"¦ÑÓ4Hƒåk.Tl¸i˹í*àâ Èî}1žW 5Ͻ�ÛcFs�;húR@Kö¼Ö ÞŽçjZL9®åòM½ß>�вGÉÆ'pJEÕD\ Ö>Ú Tmš� °mQ •�š«+#Ú+»Ë5"F³n9è Û Ø¡2× df@¨Y0k�£gµ_?¨!q,�òÓ^Eá44B6•Z²¹�{ƒ8PßJÛùPh›íà讯–°Üˆˆ¨X%?PUCêh–²‰�ËúEÌØÒ†Ä©\C³ 7"@Y!¤H\É3¬%Æ€KŽ#Ó€=ó‹ýÙW¢qm·f¯­°Ç3Rºù¢º^ynZ¬}DH# xÅ'YVölú: ™èt-Œõ Ll¯©7Ź˘”h—N}¬0úf?Ûu÷«®ŸÓ ZÏÃI‰Ûûëœi"h.™ïvÌy•ë8Þt¼Æ>&äUÝ9Š*<:øßסè ‚6vÚüìæCºS±Ï|ü§Þ�ztzQ}˜•ŽW„­ãëÅMŠ©%Žªk›Ú×a�q#8…IÖÓ±<ÙÀ»9P¼2ÕûIs؉G6‘Ñ“¬G"€GO�¢¾­OcVç'ìÜ)Îdj÷¬ÒÌTæÈdE9�•GHvŸ¬ÿm:œ–N®ä®ËŸWØÿð‡_á‹/¾]™´Áèèà?E‚Š ¹Ae¾2Xu©kˆÍ{•â–ÄñÞÑb|ÜròHŽí©RŸOÚ=M£SÍx¯ís†^u£ð.ž$*-úÇ-Ñ:Þžë³—úÈ��µaˆºûÇ„ãtºŸ ‰s°Á):Ä¿¡/›Î$<' ë &QÃw„þ[i/©8»÷Øÿ ˆŽ ~.Ÿ[BõÁ,›%£œœ&±)B¼î\§¯ò§~ú¿ú'ÿÌÏÿ?�c{¡›ˆôò¢"‚çðõ×_áùÃìû­�¯QàÚó“‘ŽÂTìÿ÷/·;n//xy¹á~¿á8ŠêþzypÙ6RJ¸ßvÜï=fàv¿µï|DÅÒÛÊv´'9 œ#¥TžÝˆ±ï;î·öû^I Ýi�™�¹jÕªU«V­ZµÊÕ"¬ZµjÕªU«ZÑ)d½ªb¡ R$RÊ„ Ð'Qýì~»ÿÄ}¿ÿ)¸ ½° jG30X:8H(ªNâ0‰JØ šf/Sîêï XQpW÷ÂÙêº�Mâ4ä  Šì>«*˜�œ‹ª_$ K\·T³ž¹(Žm”‰Ýõ „W©›´¬HZ¶ê©n ¢-Q²’ÃÕ¨Iýnc0“ÔÀSªâÍ‚\Dyj-ì¡‹$ýC–C „ ¹ïõ3|–»¯!AƒÒ«Ùà¢+�ÍQ€ÜÍêÑ€± ,ŠšŸ9@ÞÆ:qÜ¡µs-Àv‰àú˜Àš ,EI¬ä‚‡{�y³;—G¹²–÷]@e#´ßY¥eæâd‹Km3ÙYjKµ¬àNñl÷‰,�1|f9œ¥¶xµ1�¦°vôpšGQ½>>™È>4YfbÕ¢Ÿ`mí¸ãlÕ®¦Uík±s¶ÏΫ÷¬>4!>tþç@$ á¬ü¿Êø¢‡¶t:6yyoŸžÀ¥5ºAõ|~±�—� ·Ië”ð x§ÈMñŸ@g{†é]j¼Àà@B#žm1:áл‚ô#Kð_õ¾øò‹Ðí•Î=$P#D�êžÔ£<ÌyÇ!Œ•«{£ÏyGÒhŽ&î«v£4²•Ën ÷æèÀdËÆ°Nwº;èÉ‹B#¸­Pwªü�H êI™ÒݯڵÑ4ö$Æø?Î_¢ÁÅ&úvO·öÓÉ}rïáUü}] ÉtÞàÅî nþ�1að:‚�Þ)ÞSE§ë\ Í kÆ£ê®4CÚèð#Õž@4©¯ê§æ¿ö�ÿù_ü¿‹È{"º©ê¾ßwµy÷òüŒÛíŽ,¹ªè703®×'\¯O¸l¤´ÕçÊò¼[ÜJ4À¾ÈÇŽãØq¿çæL±Ý6¼Ünض )m8Ž{% Üqßï¸ßî…ÄÉŒT�ÿgfÑ`µŽýpÏ…�@DØ�÷Û3>|xÆíöŒ[%Øó+ó9êcÕªU«V­Zµê÷{-ÀªU«V­Zµª•:O¤(ŠËF\È™‰9Ñ•3¿MDŸÿûßÿU›mÆ·Ìfò°@%»LûªÖHÔìÕ»ë@T™•¸æ£M²‘Ö vµ:䔘šÅ»šgÛmS0æàT�ìÕ‚¶Ç] ¼%T¥½ÿ,�‹Ã» SîŠp˜R~°q6p“«òÝÛÖ»ÿ7xMTœz´ƒ4©¶3�ÀÐÏ„LÙíí– ðf¡mÊF׸퓩ª£+À—šJÙ)U�ʹâª| {vΉÁÌVë\“TÕ_uÉg¸ui'*ª?q IŸ @µO\fjÛÈÍTDaÀ! Jð³('™º@$³ý® tÛ75¸ºl]íãþ�ßóhç 4i†(—Œð`soãBꡊ¾øc»MrõyÇ�4£%>£ðVä-ÁaDD(* µ’R€x Ïe‹!1 w#GTS#3´D•PI{†V—�Ô8 ‹I=çÙ”›^™ÝlšklCµknøžOšCTõé¤oh/ü[ºõ¾:ò÷&«c·�ïнÍÅY0‹_6– üÑ9JÝ�+S'#é$ö½e©¤ð~­`~€�›„’‹o±ñ¡Ñúß®»žg™òRù(„�{ªÊz`®G üwçìÔË*ú@y�(âV)$7wû‹ºr^'¯Q‘ùPÆN'¥!ÞÓ&yìe®Ipd샥þéôƒ£ö®V÷Ÿ úŸ§ã¿K_ð+àVWéRýAiÈï'Læ‰ð¨ë"xM�tè#LÔ�°tΤS¥ žž^¾#GÁÅ™4·Œ�ÑÆÁ#8Ñ‘AÐÎõSì­É¹ÆœÛF-ŽÄÏñGýù`.�s¸8EW�×O‚@¿'ýð‡?Ä_~Ù@xï 0‡’ÒF^7Ú\gâr}ÔŸûÊZÍ`­$5¶ç7:X¸¹Dヱ{æÕÓ}Ï\šì÷íÝÍ Â©ì£;�ÀwQi÷ᨂ·Ùæ@xþû×na¼ûˆ‚v_¢Ùà¬Ê÷× Ò‰Oör‰TgÐßqpn ñ)Ó"Ú³Ï`àh¢Å>u·" "~}°æëÌÚdã÷Œ˜×Ûq.|j�l.u1<§zþ™Ÿý¹þ—~å×þ¯Ç±�,7;©�k#W.Ûú¤¸^�´%\¯Ox÷î-®OOØ.[#¦‡·Ñÿ+÷¼BîÎ8öÜùã8��<�¥Å˜³@ÞŽÁ!¹‘TDZèqì`&ìÇŽÛË //ϸÝo•( HiCÚRyáEXµjÕªU«V­òµ«V­ZµjÕªVùÈÈš¡’‘sÜ Ð ¦´¥ô$I>'á/^^n¿Úqê0uE•TпnHV{|@‘ˆÀ©«õSª­r eC)giC%ÓZ‚â–ˆ�”Á©Ú7Û²8Ûd§†ß¸ªÇèÖôQEY’¹;¤J8°M&É ’£Ï^™ä3gIÛV¡š¥k..-À|ŠÛ¬'Pòm°1P7¼Ý9K¨mIjͪïˆ`ó„r RCë-/½µ¯Ë�gâÈGPÃxkVÝh6ò¾‘;PÐT„”È,…»Mo·t(H¹yçˆK;Ú{EÔ©Ç%#Wp€NîÝTI=ö¢Ž"@ð ƒ (…½€K[›©WÛhr Õ¨.7׿Á«úˆŒ8!5åtûS�Sµ€VŸ¹;‚u,1!¦J�'° czÚÍ,ó¶õQj<ÈBm÷Ý€ŠÜÀŠª°ƒS‰1àêåÚO·�çÜä{ÒbF€K Ôc?llt›ÿ~ÊM5Kµ?`‚F†Á’v}M¡j‘2dD›+JuØ`>a°æV3Ñ£ó�G}ðV×à"€NNÀøv/ܤJR©„ çLRˆ¹¢8�½³µãt' ùÆÒbVÆùNŒþ9§…ÀÑ4Ô" ´DÔ­¾{»ô‹VtÒ”‘kÄH!¯•›ü@¹¨1…'v4ôI-¤©ÿGî˶ã6@N¬?ëu°­)|«ÃráúMO“{ÄO½%:"0©3’LQ ìú²ãVD;¢·Ò‰Ž5ÝàAö·ôOsf(“þ“Þçβ?�(Æu¹ /­Ž# 0a4Ÿ] ˆN듽—œ||/�0sÉi¾üÎ~Ÿà®Á4 Ü†Eez'öS�º‹Å@ØÐ¶¾Æˆ�qzŒÀêqìøðüŸ¿û,Œ ¸¹+“ŠnçÞ³“(ʺÝ}Ïž_‰ë=—¨ÌN?:WDr—º…Õæk ìéì&®-*KNíkm§á~÷¨gÈÝK¥Ý²¥_‹j8¿pÒDÎ]¤Î'7÷cMC$ð¯pI,Šø�EN½ïÞãG�ž£ NqÐà{"As �aÌ N:ô×kóåÔ{�"!È‘s>å˜?øOa]ò£)<¼üôÏüì?ÿkíŸü¿ä,óMUûÄ\Áu‘Œ´mxº^AD¸>=.— —í‚ëÓžžÞTbvæí>Ÿ˜±]¶JxªçR¬üS*qYäž½²h î0s¸‡xâZ{OÎ%&.KÆ'`ß÷ºfÜq»ßðòü‚ã¸#g3aÛÀµ~—\µjÕªU«V­ZåkV­ZµjÕªU­î÷¢‚,{µê/?wŠþà €Ïî÷ûOÇñ§„=lUO;(Õñõú—jÓÈ\³Ê+<£ÍÝ,¼¥yÕE !R "d؆6×Üî1Ÿ´ž»Œ÷ú›¦S�Ãí8`îA>jFfJÝu Y_—³iàkÛdµŒûèˆ2ƒæn×-PhR$°�½ªfd,%R€›GrÉ,7Õð›ªÍ°"KQàXF-Wð¼ÞPˆ5;Vú†{u:öôF�zÎAø×c È;:ÔæŸ·í…`ŒMöVô–±kòEá.8$P�®€T�ˆ!l Uß 5Ç ÿÿ¦æöø"F`ÀbȔҋ†ï9åîºT&9•¿Åå¹NB]Ïi¸¡B»2�F�ý¿;X�Üb,ln£ú/nÈ{麆ˆ�€�QÏÛ VÅT”ù¤…\£ZTcbG. ¥ÏEA‰*qÃH:6¨r·–®°åš ­¤ÃõE•\Ö€º¦N§töñTóæ�rß@zkc�h`‹:·.s%¨äŒ˜Ã ñýnôLlO,Ñæ¦1ÆÊÉ!ƒ�¾Få59µ}#ÒX €§¡ #¸ÔíÇ�L!��ò¾½¥Ýn^„ƒºf–b’àAâüœxîÇë+-R�I⇎ üÖ׎7ñÃ89~è㋤sn|ˆA^øÕ¾�/>ÿ¼ã§Öè¢îžì])ÔÝÃÎëËÃ�ð¬G!¾¨[ìwâ� JgSÑÖ?«C:™d:®Ï1Ͼ&†Èç{z˜^gRŸF·§øvGÌâ$´Çä4® Õˆ|ÊÑé˜F0+xïÔHÃ9«Î-*ÊœÔ0ÎTgàÿhݯ‘dâbÂd�OtÙÀäœo*Äo ,$7…_~â'ê¿ñëíŸü?xŸ¿0ÓîOKDpG'H)57€´mH)ár¹ ¥ Ä¨vО™q½\*iû‚mÛpÙ�fϽ^«s€}7²¸1ƶ%ˆ”÷^.¤mö]Ñ ^›B%ã8Ì7kÙŸŠVWlÃ1/·a:â2�1Á)<˜Èݺ�Èæ5ë¬Þ[4HµHT÷‰ 2[¾,1#‘ÙOs#•@©)2�4à#´°*`U‹"aÔw×5� $7£é¥;!9yû’\9Ûé@4”m<ÛqF&‰Ï^FPˆ<æ1ê„@9‰mÔÇi�¸ nçMnHµVcM�©�û¬ëG’’Wß”„Þ†[ë뢽çí¤ªÕ°ˆ#­P‹wPzÝY>€[ƒ£„ÿGwa˜(¼'°pw9 °¨#n<®KA!:~PüÀmWl[ìÃcûOêjk‰õÕd¡*â{r� "çpj•!j$¾Ž{vН¥pjL®Gÿ;á¢ÐáølûN¡…ЧŽÃN£oÀ'ÉðO}~†þ_9ÎÃA ]�Ltj7÷Pä>v˜óáÐ4½‡Ì†íô(¸.y*‹Ž¤L”¾¼Üðr¿áÍõ©“ôFûŸeO]û,JðH�v²à·h BR@²´ùÑâvÜóEo¶þtaÄH93ÁäHRÍGqèÐWÁ‰òŠ|=�S×áÙa¸êö9Ä·÷™OÿõÁ˜³Ct¢”†¨?0®“íüIÉüÃ=2b?tr‚âûUDO7TïYáçùhÙ¯ŸþÏfh#(Ð㘎WÉŸðy'f)û�÷»ÿ­_ùõ¿öoÇñž™_ˆhO‰…ysû"jßw ;370¾Ùðïicl)Õïk ÛvAJôªØ�kqi«–ÿÛeõºêÿr¹@r.ŸAÜ\®OW0×µwïß} \΂}ßÛ3Âqì8Ž’�5�@Õ=ÀÈÚ+`ÕªU«V­ZµÊ×"¬ZµjÕªU«Z}ýõ`²lv«þ²¡ÃP‘”�ãiß÷ÏÞýõ/K–“Õ¾/’1B ‰k^:¼íºmÀ•Šd�ÈÑç¶¹kqZ 쬥3 H34kSÈ@…ÛŸ@Ïo-¤„ºY#ä�ªH]P>Ÿµ¨—‘lƒªæ—‹@57U˜Y³¼Ô.î Дï˜Dݪl²1qm#U%M•„�AÌÕmXDš³Bé«Íµ²*8gìpDr>pßHÎÝf•È’TõFÈÙúîz ÊE©M¢—É-¶!oшV;^ µ��2Í–c¾µ©å«£¸vp¾¨ÔJn<‘€ˆ»¬Õ:Ä÷S³{Ÿ ÒÅAú†¹ßÜ·¡,Ûµo�÷8ªcÌÚrЋKA};ÁÑŒ°½ÒñÀTÏ킃BC`J}mãù¤$50T·÷w©vÿ�6ËÇc–q@ÌeíTGêiÀ¨8Â� 'Q(£�w#8µö Àº#­‚AëÂÑíçµK¢Ï‹]y#OÔN°ˆ»�T­bY[|ºs6çbÙí#ŠnD Â)3äì…�ÑË™àÖ!gÞî ÞÂ�HÝ5 ÏsrŸó£áŽm÷(;1D ˆw�ø1€\Ÿ’iM.)[4Ý‹@±¬˜löå4¶!£[Ì`èŸ!íÀÇZ˜|—â|¥Á’¿w©öõc´=çBqŽ ýÄpo³Oxìl ®oÚ@u÷�oòðƉ' àlÑîÈ2Ó¡Çet"èp¾Sê±¾ÿ½ïá§ê§ÚxÔ6FtîÞíÂK’‘×jLÔ+W-Rœ£Z‚˜?(õmmVôuÆ"¬NžøÒ«ÝΊ÷â£æo � ÑÖA=ÿ¼£ mž•Ì!ˆnw‰‘(¡:\šºu¯GÿÈàf௽EEQ h¤…f‡¢§±¡rvöÿ„©c®16Àõ‰wWñ.ßüŸ ÿêîÓ#Ì£Q^ýÄÒ úÐ_`ÿñï~÷_ø•_ÿëÿùp@_Xxgæú°˜‘ÒVû©Í�c;�3‡±©ª PŽ6¶¶-!o\®W\¶T‰©*þÑ¿�A;q˜¨¹pblÛú¤Ø¤(þ¯×'<½yjnªÚžC©Î˹P{fìîÚú×bØÈ=x‹Hòú2¿jÕªU«V­ZåjV­ZµjÕªU­ž?<×xùˆl[‚¹{«fˆäí~;žn·ç»ÝnÂÛASL¡§ƒê¬¨ò‰õ”ýnHYL­ž[½¢;(Îö®ê6‰5gU`™¸ØDר�bÓ¬†YcŠJ±m,6¯únM®õüÚGż6}x�,@ÄB¨ÆÄR*˜Ñí£+Y€�’Ë6��œ‹²:U°–¤Zíþ;@UHrÈÚÖâ D›•úq­ �\Àÿ,e�½«Bý|É%~¡�3rþ*ˆœ³B• ˆîÔk…�›Ø–ØœÜ©Šµiÿ©»¨âäE_�(%mÖåL\m@Єé$�2,›ªZÈ”øu PjèW LÔ�œÝ·d”f欠źž‘*†VlÆ¡Õ[¸S�»€”8ÉR8 °œOvî§ m>�š].ƒ«AÙøî£”)µ޾¹/' ;רˆrn%‚¢e¨ƒ¡¬PMƒ ¾Ï;†ËÞ6{sHH­bU"‡5˜!,€0”rQKW5¿š²ÞÚ¸�¥ ôŽhƒ.Z¤Å¨¾'æ�ã¤9$¸µ©‘w"Ѧ€Ïï6u\éfrññíÒ· <�ב‡�s ñkO·Ý×Ê¢ñ :PÁ{Diõ}gN ­ý)´ ‚3�F€Í¥Ÿì}æààó³I5*6ðÒ%#bñ$.þÀ¹QÐè{ßÚ°(¥:(Ì5¤Á ¼kt›J‰  HëßögÍGKUó®¼e8õõ¿›ú[Zã1ØifiOΞžBäÆpïÁÜcôˆÖ6Æ(Ú ø[ð«¶ôþ|·wU¡ádË2¬ÑÊg@Þ\BÆøT«Óy°ÔÇtea'"*ãÇrÀ^k)ŠÊû`Z3Äz�öØš´|l7OZñý÷ ¥C ½sc ÏÇÈ:©™›YˆlÃ۵ŬÐH„�Ö|}ÎÜ,0º&Ô{î‡÷ï±Û–&×ЇÀŽz¯7ÅûÚ8ú3´˜uëf»=Š{!µõ„¹ º! kŒó¦÷c[ƈ�пh$ò÷(Ž1D�D0ùìðÜéù �‘E]ùß./Žsÿ {£¥öçõážäI1.¨-Ùõ6‰þyaßÕè±^Çè±Ó¼˜üÇ’OÿÇâi�x¸ªþœBŸÚñ�ï~÷¿ûëýŸú·²è{U}‘]Ióèæ`$€Ùy5g¯à4Ñ�“T+�@¶ú�…‘—84{–5rb÷,Pª¼>�詞KÂåzÁÓõŠm‹€ÄŒûn€£ŽóB8(„eEJ Õê0 �`ÏR"¹ðV­ZµjÕªU«VµZ€U«V­ZµjU«œ3HMÞÁSWÝ÷{Úïû›ßúÍßúEÉrí`?A…@lªz§„lUÙTJUé PÎEºU}ÿ�z‡Šß2lÃæ¹�4©�ÌÚ¾}6;¥UAr.`vË¿ä¾ñÜU¾@ð®Öš3*Y“Íö[´+Ymo�SSôÚç6›ë~æ ˜-QƒÔµI·\3pd€%Ä-h%X®1¹Íh5ëõj[œJ¦fn`v½â¾ ì6³93¸�BQ)žYP˜ ±¦—®È+ûçÕ5@L`.º}r€+ìöyçxwÏ-wÑèå8œ H�ŠãC§Û­fïNˆc©ýnø`Í…ô‘s.ÿ¹FQXO2”¢òÖÍž�¸‚èl¯§ µ+HÊæ¥Wž:“û DõS³ä·øw¤­5Ò¢ÚØÛõ’G¸+ tŠ%wÖÿTç·�{fSeÕëuêïÒ4'Ž.¥.}–À • ÞÄ 0ÀÕŸýùSU^jw,0W Ê¥>õè †\]M* BºPWP‡qsŒŸå»y6¾«�7ÒÛô•F�Ͻ'Îx°yPâÖµUEöD�ÇH‚v+gt@§Íá=¢�Xé‹÷pŠ×AU*¦œg‹„T ­1+Í¿žÎñ*êÛ%äw ì±íC„àQŒÑ&Žœàb<0Gƒ}<´bÅÜâbÜ@èoÆÑ•·n hŸn™É£?,.…‡>$·fÚ°Ÿ<±ªG58®<3m†¶ÿùl-ð i d �UJ7œfŸÿM3ò‚ë‹PÐ)àûCÏ÷–qZ“ÞCÞø°ÞØ�â zÄ �8ôJûâÁñNóÍÀaLy€c³¼úÉИ¥D�ork\¬F'e�ŽëÇG?ßÿþ÷ñÝïþx=U=ÖC4„ª6°õ™w ™´¤jq'"¡®ˆ×w²Íȃÿ‰däcœ+ʨ®>Ÿ�÷'ƒGâðFþz|\€ƒ­+Íž¾u�棟«Á��4‚Ãá^1Ú»úÚŸGÇX'`PÖëÙ1G§®î:Æ;Oèó¨øøÚ¤õ49bçl¶�ñŸ²ð¾¾Ö%ßùñïþ÷ÿéÿüßþ{"Çûœå%ç|?2r±úì�ET]±âg‹H#ô望+Ž¿Ÿli+nb2FN•gÁ-mðNngçÒÖÇÅv)[Îå= —Ë—Ë©~z �ý™� òsž+DsBÎGyGwò2GY«V­ZµjÕªU¡`ÕªU«V­ZÕ .—®ð Õ(©èUEŸ^^ž¨öîQ¸lèº)'.KÜÔÍ­¨É¤š’_+ÑÀ”¨f�ŒTÁf¤ @—óJ”Š¢dÛpiÙ“ì#û0oËÚÁò¦ž%- -T¨ªË5 ”ûû@Ô7ÉLA>d°‚¸åÊwËx(ày®ŽÓyË›ª()N‰»Êß®N³4õw!AôÍÑÖöÄÝߨîS€žÏf�\? lÂB„è`“ìÁâ&”*`—Ù•÷ÒáÓ0(¶»½¨»&°ÔMùq#ÕP¡¦\2«xÛZmãM‚j7£ƒMas™Yê1²âÈ‚¼8$·1š˜‘ $$êù¿~#�‰‘Ø3I€ìÀq•JH`ñëæ½Yÿ; ·)öÙÆ¯ s®Pë7kdû}s5ÐÒ§BÁq¢Û¹R�V ¦¶5rqG0—ˆ‘4¨¿;æTç2“3®Ù¯�ÁÑý¨Š2;Ÿqø+z(Â�©°¹ºŒö°æ@%“$nâ׬úä˜%Mtßÿû¼cªk‰SBºAéÁ!Šð® °®V §qÞôïzeuêÿ1 ¹·‘ŽÞçaÖ™‹ƒoPoÃojyQª}áÆ’�M• êwywq½¨«¹ÄTƒ"Ým@ÆŒow)Øêî ó´Ýbbê}s¼ðzkÖ�‰rêìnÇïãúåk´žÍì‰fH¢Ò¿™bëž>#¨¸A¦ò´tbÙnŸ4êÈ;¨©¯9W×.�xža`Ñ)3¾­¿œUíh+Wt ¥¢¼v7˜3ðLeì¾'h¢¯¯ñ?WT7×{{hsÔ8ƒ�ã‡MZ'¥?é7~.›}Ü›{FÌ6°{œ‹qcúÑ0jÉ §®žq�!LFÔi0–uËe<øw›ó_õ~ì;ßinÖ#üm÷’༠Gv<ϲ8÷ã"ãÖÁ±C5¸ANì›ð™ž¬÷ ôÜe�ƒ§�NÆïŸãÄn�¦áþïc‚‚úŸü}eÈ ׇ@híćp G˜+ò½8ÞŸ—õ‡>"ßÐH¸SÄÞz4{> ümê›gˆ ÁÄ™Àÿ“�†JßtÞëi™Ó/¿ýcÿâßúgÿÎÿŽ™ß×—|äû¾ï™�÷}oãT¤tU@”ú¨¿“œ±;Ž£�ü<)ßËÚ\øÜÿÍùL[uPU°¢ŒXlÇÛR¶mض .×ò]͈׶Î[@J yËnzyÇ8#,'÷|ØÇ�‘V­ZµjÕªU«V¹}þÕ«V­ZµjÕ*«Ï>{WòÝÏꆩê•)]EïßÊùøSZ-U[}[&··Öö*JŸOlJ=oMÔ-±‰+(_6±Éåg„–k¹]6\.W\¯×–s™³ ]E R\ PUÐLÔb‰Pù™©�…ÄTlÇsì›ÒE䤸ãDh`†³ñcPÉÑ5˜B®%&6Í Ißà>j¾fP[…%¸KÍRgb$"$fPÍdUËc�yäf•ÞÜfÑ_ÝŒ�ÒrÇ+D_Ï£ &šø Q‹‹°ã殤o‘ÜæLi븶þvX°ýÌljÛtà:®8‹�î Å�´R†H!J´1®%Ò’�m<;åc»JŒà雽2‚RÒ©º™ãûªGOthh5•¾ô%ˆJÄB@(® >7˜yô)í}“ý뵑Œì™;XæAnuóNª#ƒä!AÊZq}8H}|ºÏ1ò@»*û?Gf‚J]G$3°è$(bk!¢ô›µ‘hjÃv­ŽX¤§Œløl‹S 7æÉ7WŠŸáÛzÌÒžœœ*‚Mø€Ì~a¾)‡›a´tžC‰JÐ9Ò DÓ‘p.Ló体k§éˆÆä|Ô§Ó�u ŽPà¿è f·Ns¹æ˜˜÷+ÍÁ ½[]g'Ì|GÎñpއr:Ž·òon г¿Æ|xùã4š’ÎIÃäüè˜�?*gŸEðÕ~€o}ùeuèÀ`ÿ>Y‡ˆ€üq¼Ù3áŒÌǵY÷®G¢f¼mMÇíxÎ6ǽq“K9€ Žq…vãþ !Ê qî»vžƒù1V†\Gù%uíðoøõJÏŽhXŸâÕ‹üé\>;oD�wˆ(ÐéÂ0½—¾>þ1¸vÙü•�@ó:àü#ëþµ�™>ÿü[ÿ“úoýí�™ß¿yzó’6¾K–ã8v`ÕªU«V­ZµjU©EXµjÕªU«VµúüóÏa[†¦ä�œp䜈èIUßþÆßÿÁ/x¢’Àç=w€UTzî;qˆcæo³ gKh'@ lŒ¶�ܤjñNÍ|Û6\®W\Ÿž ��ŠGµ¶,ŸOPåºÁJm3Ê,jSÍB· û´u2‹B“ÔvdHÈ©ëµ_‡íøå–OÛP'=’¢ZWR©vçØ33Ô”ç“MÜÎ ˆ28™šÌ6ñ¹€§87ß`U0495&E­>³Ù¸D¨ pù¿(éÚt1ð›9¥:O”ùÌ}>Q£ „Œ˜Ïúe.ÍF T, `¶¯ä]ªÝn`C‘;Àà RA´#§¨~TumÉ-~¡.”ÐJL76=�‰ÊhêTH!ˆx¼ƒª’Ph ;›çž}]9.r£+Ì1(Χiì­#èïûÖ�:‹°Gô»›ÀÉ>=Z‰…çhÛ�¶Vv_ÖüNØ‚`df�ä8?NÔO&¨ýÇq�±Ø–h™ÝÁ1µuätä¨ðoרhƒóÜÖ–Mõ<T_Kv?¡‘¬¢Q…;œŸœŽëO …3Lœßu²‰­íóÏ›R™J”ކƒY^÷øtä‡f'|:Âô§'ðÜ9u< }¬IdÖÙü£N`{ôñŽkÈ:xÐ×#è®ñzÔ""Èæž±ì¯¯€óáKrŽ³×Ÿx =“$ÐÝSâç–ëúÁ¾�ϾõE’¢¯ž¬R$EÑäg‚ÁÖ^{¶½?`˜�Ž¢££ÏdõçHRí™Ç¹MyBI›ž'‡”F¢Uw¬‡ÑcPhà�tª¸pÀ¯'ÍüÜy†‚‹RÿH míñ“Èž‹q~^=ÿ]ÇÓ\qz£ëƒûÇ#RÀ¸~ø¯^7¸%L?í÷H�þæéÍ¿ò«¿þ7þ—û¾¿’7ÏœøþöíÛLDÈGƶ½€áöBá»W°ÝHÓiK�У |Oxº>áÍ›·x÷Ù;¼}ó)]@ˆÇQv:) ä"5* �dïûŽý^HDºtRAÚ"øŸ%ÇgòzŽpß m-PäŒzÝ)Œ«óG!à®ZµjÕªU«V­êµ«V­ZµjÕªVOO× R³æé �±x'"ïn//ÉTT}�·o{JU![ndËR6[s¸�Kê6¡¶ù$¢%ß ÄUáL€! ”Á5Ó’yCJö_ê‘Ë#Ϲl%V€S9•c4%x9Ÿ¢¼®™ç (›ík®›ÚU®¶CiçOÝÞVœz³t]©¾Õ�¢“ ÛVªN¾X#|ƳwV°ýw6qzaÉ@ ½Íƒ=µº¬ò®´ÕjÁodÕrL©› Õìð¾&âæx›íÊ8`°å˶T£¨JzVÖ¢\5×PrD…棨 0ÀngY€ ×UdC¤oþ[VjÎ4ÏÌ`í}×MøuºA-* AW Öüs00TTò½¿½õ79…ž‹ÉpÀy9vÄ��í¢,–Â[Ö‚ÊÎ::+2¦È烌zrs•ÑÞW£"à‰ $WÄ&D�ôƒWâ LA%Ù€ãŒòàœÅdxË{›s]ŠÙçQ·‹î¤¦6~ÔgPoisY0ðŸ¸Æ(Á>Xˆ²SÖ{²Á ô¬sÏqÑÒ»+;}‹x|‚0Óýj™�ôr–‚«ÏÚ¯îÔðˆšDÒ—²ˆê.+¨Â{³‡·ÿ¥a€g[#XO^˜ßÎ*¸¢ Z_w—‡bo\Ø&Þ®¾G#èèZ€HàRq�D�@ЮÏ�ðzŒ í_?f™·;ë`wþšÒX�×¾WOÂ…è°BÕN“ƒî‡eœkÃxy�Z¬âg·4oéþj€û«2Úo¸¹õ7¼“æí2F4 p[Ã\N^®] § úq|´%0¬»QÅm¤¦€¬;GŠþ˜¥Cf}´Õ"q‚æ€7ÍBö;ì=^éÒzÙ9g¼ÿú‡øìÝgû|\“È‘Ûõ">K5r ª“÷ŽùÀìs~}#�À3pÌyÀ¯§£ÒÝÛ÷Ï"O¢Ê¿óŽŒÈupã/�yÆñ<ºôc·øœÚnýÒ‘ŸÆ¶9]�Æó÷1@jg©§¹ aþ9¥âTR…žÎ#þü<²çä�Çã^qv�øèêóQП¾Ù:5Ôõúô¯þù¿ð«ÿÓûýþþ¾_Ÿ�ý¸K–ÌÌúôôH[ßÚÝï÷vÿcfp%÷rN•°›*(OíïD„mK¸^Ÿðöí[|öùçøìÝ[\ŸžJ_È�|+Ê~s ض @‘¶EÎG}NÎ�êØ–¶Ô‰‘D5Î�!F‚mîh=ÂË"ÌÙGDë}Hˆ]ªÏ ‰¡º¶¸W­ZµjÕªU«|­§£U«V­ZµjU«šÊ%b~“6}w»Ë·÷ýöó¶ÁØ”’^uÅEÅOU-OàÁò>þßà,?)`oÍ6¯öïes²of¦®åzü ô³V炌,¬UˆrÛ&T=/!m •ÑD»M3§b9^,áÑ7ª´gVzñ–ãM•î³ÛÝy³{oÇwLíe›bÙlݽ µFÕš,̾ÕR“˜êuøÜmT€i¶�ú L¹Y w¢C€(EAhµÞ7»\F· Wt…tËYw`tùºr� `4¹ a·9_¬Ó]hqpSÐj1¬Pɨ–uSø�²Ã{- ]ÄmƒSÏ­ï ¦Tkñ¸Í[Ü# 0*•PÆd!Hë_@PUÉRÆ_ÛÚ¤n�a]!eSTêF}®¤‡ r­cÑÈm ik�ºP¹8k'J4e)ubÁ$‡ÚÌcN¹`Tã�Ó’E‚b´¨Û{v°�?ª}Á¹§õÀêUò5ú¢��HÌõ†g2"W,öê08jdüy;ßœ6œ7vSÖU#õ†Š0�d²þŽŠáú3µ vÈ\Ëך±=8g°Ÿ” ‘¾h:D#a«:ŽÒôóöÊîšÂP ²pËŠl~T'tÀJ«/<µõq-¤Ð1}ýDpϳ×[ö×{™”ˆ¦Ð¯ç“êZRÆ@%†¨ÔÌø˜›Þ×&mk訦Ž|–S :µ; _Tݽ”$pŽRmÜg5 ×nœú9&ª�ÅiþPÛ ²“h^='ÝÑ @»züÜé${åùå4bâç†Þ Ìüè}2Qˆ0&y$ÑùÓ^«~Lš‡qŽÁ[Ã4R€ö ‘ÖLc,}{­ :LÇÂäÚÆk¢HàÔ¥¢}8‘}¶žLûOØ,uë}ƒyøÃâÝ»w°¥ÍÛù«èô¹…ܽIl.›ó„WÛk!²EvÒœôþ„s³ðܯ“©HwS²÷«{FS§¬oÿ\4F÷޼«³YïñOñy-Z»‡èhdýµ¸šþsõn�l¨�ÌbJ0Wð«Æûf\ƒh¼yYr f.0cÜBk_¥é¢¤zeÓçÚO͆Ÿ½îôtLøÈÂ× àñ|ø9uŒ]¶Ë¿õ‹¿ü—ÿGDø:çãåöòr¹lùrÝôÍ›+.Û—ëOOÀ±wë}É€·ïMzQ\¶›¶_öòƒËëK¤ÚoÞ¼ÁÛwïðùgŸáíÛ¢þW͸ÝÍb?ãÈ�m æ­‘ïÌ-­;uÍÛ7׈¬|äö>ˉSû³œ7AHq—"¹Ä;޽8°¹�UW8lË`ÕªU«V­ZµÊ×"¬ZµjÕªU«ZÝ÷£’¡޼x¢oýƒ¿ÿQoD…�v8)·MY9¨@LÝÖ¼Ùg»Ï7p¹mQÑTËï˜SU—•“0%u>Zû^ã *øÇ$P)›ÃE�ÛUí-ÏRb:P&�$¤T!§DÅÚ]µ8 ݺœJVºm*7µVÎÕÂ<ª` ˜RËï`v‰Å«r[Îv´Ð/ æsª™¢>62BÏ(WHs&0๼—�myÏ Ö·$ň ¦„ìÒC„ôÍãN¡fã8p=Ëɪ–˜À”êë©e÷&‘Ìö½¨Cd… ÷¯hWCšs�‘#4j¦©:%´Me#"˜’ŠÌ�‚[{UÚCQGIo§,¦þGp0%c³kÕ:®š»€�…üRmì®+Y¡z0±å¬;'R.Ž Ô<N`˜˜Õº¥;(•9Q³Óƒ:q/;Ø5;G/¡ƒ:h®¯Ì/Ë!d¸ƒ@$ â©c²�­¦2§ þ¶=jë—x½§R©íµ»d@ˆºÜêJ&^Î@%?5R•kÖâj‘f¸î0dïõš~3Ò¬õýêF¸_gOrg7'åÝ�¨Ulí_O®òä�] JHÈõŠ?³òE;oFq˜°ùèÁ,ƒQ-¡Æ‚±&×!2!ÜSTŠ%0kÐÍ�¢.ŸÐ°˜tr‚9Uˆ#dyp¾�»rY¹šF¦"[qùÀ@pñ !b=0Ú],„Ùµ÷{Æl|[ÿÉ8z;>|£�Å� ÝÔsçÇä–Òp}èNO¼ÖçèÍÞ?þ„E�ý ‡ÎýsÕ;\ÄBLüä#éU6€§%x°6(Óý²[':ÃpÔÁ}€,†C㺥îþ2m[zÐÆ³X€ ‘�¯³ã±ëûýŽ——žÞ<…õOؽÛýÈf U;po³oà<¡»$5÷%G<ñŠ·¨�óAÃ3p\c&îO!nÇ�ìD �¡Û3¡'Ä�2N^¸µXÏ�^™y¦k �õ×ÚyÅŸ ×zŠÒÐÁ OšY|xV…Žë8E¿â�åÿd<<ú÷9¾dĹqänѰˆœÈ¿ ®ÿ~´ã_.—ç/üÊö¿ýæíÛ¯÷ýþ""·ûýv|ýuùĽµá3FûSJض Gu5c®ñS´þîr½à)?U×µ2?˜×ëžÞ<áÍÓ.×+¶í N\Ÿ¥æ š�3·:èqûz²€t€v¬Ü‰Þ½52$+Ž#ã¾ßq¿Ýq{ùž˜¶íNåZ/aÕªU«V­ZµjU¯EXµjÕªU«Vµºï7gG Qb¢'>ðÅ×_ý—£�©½ÎAuƒ”YÁƒ ¶[§ê ´Ò¦4§â4ËnK»äÆ—ÍU`Ï‚,; %SRòT(JÅn2�X8¨õ�b‹…Îá¢ônêzmjmí[É�/-ë»F!�)¡-Ó²9QóØs. ½í‰Šh³É„ž#,ûÝÎ/1u•=ª}?úÆ´¨"çB–PTŠíª¢YNS$�Ñ XœËº£xÝ¢>tþ>‚@…ëÚagSæ’@œ{‚�ìÐòεF0ùÑ=¯ó5T"Ï£÷¹õ5(�‡6 !„Ú…[„AÕÕì]E«§Kž+Ñ#uåA_8œ˜Ü™·1FŽFç,x?Ÿp Î�ÿ�«Ãæ¨$Tg¡G¯eßó¿éÙèaü0ýÍG€C¢‘ê@C´ÃC&S$0LúǃÿÀLáìÇ��RúªZ¡¨P£xP8Ø7AFûë¾úáñôôÝ퇆uÑ_–ð' ðÉúžâ< ±!Ô]ƒ€‘CíªÎaÀ}žø 5³šPw¿qQƒ¡þD» AÿσJû­°ß#‡5“ïQ5ÜåÙæw¢ßà@|mÏ�DnÜvÿ#i!< ìšÇ´Ÿ��ÿ–WÀÿój¡¯¬G¯½Ê/̤g\)¥÷W~í¯ÿ7ò§þÀ÷Ÿ_^žñ·Ûíå8öC 4/à~3a»\ùs¶•{µ€9aK —ëD ©LIæ„í²u²@Sæ×çaf¥¡ÓÎqCJ N…ôgqlå»Y ĵàfaäèfå/!² ~¯¤™¤ ÕŒcÏ8޽J;$p*ßaRJëËüªU«V­Zµj•«EXµjÕªU«Vµzy~ij�b§˜óö†~ìû�¿Ü^þœWsh y5xÛd¥† ‘SŽÂ«EºEUÍèÊjT|‘\�‡ËÁµÝ"Åš¿BÚÅ~^¤«™=ùÀ[Γ�õŽêK�"iˆ)iÏ×v Ù¾iÚófû6¸³EµÍ\Æ ´­ئ&6¥¬‹0ÕzÿÑs=ëä7ÛÉYsS GiÜ 9â8ruxÐæ�R(‡…D]�¦1ǾöèŠë&Ï¥æ0Ð|à[<ZÃõ¼ë¢„Ï•èu0±5žBHŵÛ”èÙó2ì„W{~�´ á ä.¯4U¤Å;›9˜UsNåÒØœ:º´»,çâ2a}WLom82v·}z´½î¶›ØÙð`ê=êÈiäôá6¥ÉÙ˜×HÕð N‘H.©ìFDAŸ7‰kn»SužªÙ;[frËwՉ¸_“}V³z7²e@Ëì25vó‰t‚ woƒ�àç©û\éáÄS¥¶è ò=£Ò£Ý0U‹ÿîÊáãȃҲ*¥aÖÜÞ²}ä¹3ñ?ñãHÕu´Ùë8¯mÀ ª ¨ê%§0-ýÍÕ)Ä_±#a5·ƒâ’ûÂwÚ=þiª²®ý-þèÅ¢pêTñ f’ûæ2B$mÞÛz¤J -×bóGšÊšÉËea;€�Âù©W›—^ÁJ5ª�àb\ÛD‹p¯æŽ¤ŽÐžÔIåg½ï\sWÎÏŒ]1ë§83g6ÝŠèúúJÖñQ)ãi›+ͬ¯ I…ð1[ý×à·øë~Ó :œ‹¿G Ž·¦‡Wi[–{<'Šã-ʹúëlJ>ާyt•ê`Ò>^y×™Ež®ÝàC¿Ûjû™e  FP—æ×`?~yyÆý¾ãrIe<ø9Ôûzµ£ ß¹J�+&ù<—Àݤ«¤úÀÞ©”UúXmñ ÝT|†DŸÛAÀ5®'‘ùõ@]| 0ªóÏãÌÇÌÔõþø£»‚º(˜“ÕÿÈw•~<¿†�íJ§×¸æR�þ~ÄÆ]âO� ˆ§òÊðqðþ^œÖex’çÇgèãߪ¿ÿ–bæÿðÿ…_úçþ¡øùÍ|ȳ*îù8Ž}ßu?ä|4Àýr¹`ÛŠu‰>Ëñ¹Ýþ¤AíÏõ¹?¥ÔȤ*Šý8Üú«¸^.ÕæŸ±m ªWÛv©.Õe„ oΞHì•þŸÒþ-æ� "ÚΈ"™ÀÚ—¹œ_Jk‹{ÕªU«V­ZµÊ×z:ZµjÕªU«Vµºï{°cO)qJù)¥ôÙßÿ�ÿøŸPÅg'EÝžåp3w+w÷KEÍ>WA>2H.†ßÌÅJß”µ@ÉnÏ9#çjá€UývÝ$ D3$Wп‚Üí°¨Ñ2¨�ç7DAÝ.œ HšbE¥ꆻTw€¶!(}7–Ñí�Á 2e$l6 R£:º¾-¾¨µÉ?)õ|vvÖÉ‚¦¥Z¤»©dŠ£foÖ€”ŠeýV@nÖnÕo½"¹fµ—cRk*êpÕh�Nè ,uPÃÚ!çJHpqAXËxqà™T`# 5'"/}ÆUy�˜�Q@z. ñ¬,®6¥L\UçÞÖ¹«”ÉÜ(ª-¹¶TuV{§—eï“­ Ng‹Ám.�ùQårå¤XY4ðµ(©¯píýá6W‰ÊøðçiÊ~TðÖ€ÅTÎŽ-¿=×|z ¶ïê@é;l²ÉKaD Ôˆ^-ß-â+‰„ YÃìu8€êº ÒT´�Ý6ÞƒV.ŠÃƒª¦Üܺ•;•>ä åw*F—c„ò¥‘¸ÅbôµÎÄ�[B!õì ôYë4UAŠ[oˆûó€;0Î5ÀÄ•ÓÁ# ¶ú…üRÆ,“ÅŽP%8[nH‰@˜Kûè̶Ü�c€-ˆ­Ë¢$‹cgÉšÖ,ÃÉ1èŽ4� ¢êúd†bÖÈ Šk×)—ÛÅ™Ä{’»¯šJžâyZ¬N?Œ'VQÏR·ûÈTNOg O"óÄÃÀ-ß}è³@JòĤÄSQ3±?Ý-�/äÑÑ'Ç0äWÀ»`†Ï&øÂjH ˆ¨q Z¨ÒCh‘èÁ'ž-N÷Á6îQ]/´·óhA¯¯4£WêÍ$hhš±˜ÖÒ¤:éª1àé&ï¿þ _|ûÛàê´á‰8!˜Åæ¬DÐ[ëëÌkVþèD êÔôžÈâ«üÙšCÈÌ%®‚ú¹Ïëæ„úF‡NÒè¦cäíñ@þç_«~Ý‚w7ˆÏš>¾ÉwÏ äæ×X=ßcÃ'ðgw›ñuñZ �gýÇ×…×É[jôwhý¯ÀÉöŸˆ¾÷�ü‘ôŸû“æçÿCæí™.¸]EŽû~×í¶áØïQäãÀý~ÃívÃóËs;Ÿ#å;Ó‘Û3–¦BÎËGFÎGç9ÕÈ6¥ö.wÁ�G}Þ½Ãõ$&ÈÖ•ýªÎò¿ýÛ=_ W’¯àÈ)ÈGBÚ¶x/qN@D�V ÛV޽)¶Ë†mßÊŸÇÖžRJHc«¼V­ZµjÕªU«B-ÀªU«V­Zµ*”T �|pæí)]Òg?øÁ÷ÿb{1&j¶M¥ì6×ÓV-ôëÛ(öóͲY ù@Î=³¼ä� ˆ¸‚åû~À�j.¼`5 rË‘·Œó �3`Ţи9ÛA+­J¥úšj}^æ²±&’[Æ}(KvxÛl%ÀÂÝÞRDá s®1=}´b>¶Y]znQ€Û&xèm VÄ]kuð6à”s±ÐRªî*V¬é¥«Zaê?uû.¥œ+°Ëƒû°®R@l­Ž Ü2y£[ƒRˆ.J O´å˜33Ô LªT’ºYžˆ‘S×fÛùA é )¹*€QÆXq0�ŒmìST«‹*4K°ËvpœËFw(©x+w…¶S6 iò€r·ëo:±:ö�¦|l VÔK;»cR£š�1¨f½* ”R�p¨†éÎIƒ½ºez ¯8ÍŸÁ©Q ¬á2Ÿm^iÉEÀÂãBDb‚�]ÄH‹½�t4h³~ŽÍ·æ8Àk�YЃE³µ5W½­~Š;Ð&Æ@,@™gM…<±õo‘ nÑrº�¾~�O€Kq¦è#”¨’c¨“zPV¬Ú~ç{¹‡ºSˆã´ö—êZAu®:úDêtÌ’~PíÞ2O'à�ÖüÑs¾\Wí¬b¼â%ÛÎ$bÆ� ÒÉŸ¤ýúGe,•ù=O¼G›À�íÖKJ!ŽãŒ“›�Š©­úøSg_n÷±fØÒ˜OÔ¸ÁäÚÙ¨«ܳÑá•îô*ÿÒd9Ã?k ¬�™—Y·OÚŒðÑÎÏÜ]/“v qȈ_)½ä>¦ÅkuÞÿÑÝâ¼>�:‘@*™'Gèi¬N.$"=ú¥[ß&�“Á«Ë³™‘Fµþóó|ñÅ—e�¤áéHàûŒôÓòèB/ p¸ç}¼wâ]knZc ç7zó{wè).F=Ù�Æ·FÒœ_ÿÉ-p:í�HêÈ{=³Æ?  »èü Æl‹ó `ÿI޳÷:Ò;~O"P§`�ß ô5§šWÖ- >Wý¨5ù”ýgîþ×ñ—ÿÊ¿à w"ÞSb¹l¶m«º¶H±,Ç~àØöò½¢‚ÿ9-¦Ç¾[ä|àØw•|Ûž7EÊïŽò€ê2Plþ-6 |ÿ8»dhø>ÛR-z¬þÇ,ÅáªMMÕO5’Š*ɹ’ê÷¯k¾âx:ð$Åá í©Ç ¤THçå‚ÖùU«V­ZµjÕ*W‹°jÕªU«V­juÙ6È‘‘5µ¸b‘7"üÅËËËŸ-ànª U‚¢ªFÄ6˦TbŽ6àVÍT»½ª÷Wॹ(ÊF•äšUÊà¤]I© f€VZò¦îNÌnS¨l¦fñ@[ÝÄs6¾4È‹ûhkšsÛL3 Mµ|†©a `ÊÈÕvZ¥g˜ëqT5¬@—sÝ£f?æ.›"�*`Ìdªn(ƒÊÑí÷á¢ÐÁþö~.yòi]bŽ ’Ì‹:Úç–û ÚN¨@ QÉ%:ÉA�è Z õà–×Úõµüú¦@¦¢(Jݸw£öÍoË,­ÅPb�d°EH´ÏˆêÈác,r±ê.¹¤"%¼½ñðÐh ³×¢¢Ö¢ JtR>«.Â(@3WeTùÜRÛ,«4‹~ëËnëL!W*R œé3+²¢:4”²s¸÷w{�#N Ç4 5vƒèÎ íb�e=hhO…�#€tÐÄÈ&Å1²Š÷„@wŠÛÑ¥Zu®BT�Øó�·ã•º·‹Vw…1Ȩ"ämúKuÒ÷èq€�W•Ú¥^3ßý•sû½Wq»H—vòXv µßìg®ëLâJÛ«;?ª tÍ wàôHN1´ÅÐ"Shð!À'�ÐËØRsß©#ðµO©[ùŸPO7†É­Ï�a̺‰,n}B�{!Î5€¥hë¶ÿØÌmØ"áaŽýÔn½0–bV·¢­±D6×ÐÎwV»í=�þÿŸ-΀¼ÿ›À;Ì.z$§s´öÄb]Úà?:×yÒ¸'·ô{cÇét•ut”yG'âî âŽfÎ :9ÃFa ùÄÔû!éã—L¯1!†µ¤�¡‡ wG°¹¦�sæÐp¿|øðŸëóÞdÔ£¦$"âç‹?ü¾~ØÚVã?¸,–Á¨�Sµ¡é„³ÁaIõáø9ñ1Å)óÉ÷v¿Æ@N­÷³¾PïÛáÚãu÷ß5‚AŸm®u²ðQ+§9�Ùú¿¶ õCùX. Ï)˜×?kèGçòë5;]ÕG¬˜aôÿN¥ÿNé;?þÝñ¯üÕ¿ùèY7e=Š”YÜ_p½^qT‚n±»/ßÃî{%û~¾  }‡Ù�âÖæKÿ÷}Ç~ß±{s cNxóô„ëÓÊÉ-Žhyr¹ÐvË+ÿ™ûXtÂðÏÒý;Åï;õß[J�ëOòÍ%’hOÜH ‰Í¥«:q­ZµjÕªU«V­jµ«V­ZµjÕªþ`°] — ɇd¨È¦ §ßþ­ßüyùŒRªÖá fÅÑ0Õª¾*> H—‘sAa‰¸Tÿh–`i,5(6ô¨vùâd¿^íåm'¥ªDRµÈO[U�T0%gíŠ*éà3›¢›’ÛâËò¹e¬Ûùšƒ0(‚ÐÕxf«J÷4å½HUVW»J‹> ‰­¸�ðª'¦¦Œ±v•–u6¿Üf> Ua“Ò&ªÑZ¬¼]dB#M´+ƒS<³·*­ÝªÝÖ¾æŽ9ÆÞ·©ÀýF ,K¼ªó©84×-FúE˜Æãn,² XYæKÝìj`6[ƒº¹(*`qáo–Üõ²Ø”Ô®ü¿5¨ü0´�v€æ^ÐgŸIÌ5ü¼Eâ~_¢ ªZªÎ'Òníš ’[ì¹SŠŠWG¡íùW 44¹ŽóêÞ–ëÍS€²Eí�SÁ•àâvˆy°¶í‰áó×5¸°S‡r `¯lŒÀ èŒúœuêcÿ…y>FEH‡7ª¡D´T·—ÞY_µöWœèb?ÇÏçÁù౎÷SÀÿp{iý tm3éê³}\óÛZìÁ¢É}ÅÌ?¿ÞÌ&Wfào¡OJ=ÐMš­ƒÿ:\4¹Ó"·ðwr #ø3áÊÿ¿ÿ5>ûüs·Ò°θ­–³ÅîB5Ò§~¼K´[é»h¨Õ1XŒt`Ú}¶µ‘h# v®#»õÚƒù-4¡9Uð�úF}ÊÄU€诧QéÜ (rthC ÷zĶžÌ2ukO'|Žm‡�€ÿ&&æ2ÃÇLÞª§¹úñÕà÷®¾õÅÿ‹æ¿ð_þ7}QÅ]Uwk3fÂåºAõ Û¶�Ø..ÕR¿Äz)Žc/de#™P'éÍÀr�YËՠă%ÞqöãÀ±g•÷HvßcH‘@¹»Ä{³„Õ Õ4>â]qSCûžEµ# bÃõ颢ü71Õòì r ¯¯ò«V­ZµjÕªUqŸ5ÁªU«V­ZµÊêzÙ��j�O`½(ôéýû÷¡oŠJÞ½uj³t‡"©É”÷]…¯¢ÕB¿«›@®`+³³}¯f¯~ ¶àñï©~×\Kbîìmƒm£«Ùõ'[Mnºi(€DõµRU­�ˆP.<ùìeÛÔ…�Ôè´ý°()’–s@b°Ûȶ�\Û¼+6—UõßpPj¹óª%7Þì_ÙYÔÛ†WGf49À“ªõ&·H³hŠrÚî�`º5>EMdq”PhÎ] é­K¬¸##ôÏStµœ! … �vÑÆMdΠÜÏ“ˆA)�rv¶×å>’šâžôtîåï–ÓÜ6×6âñ´–=X·“©¶%HÜ)Ô 67’Dª$”MWV‚˜jªö�?­¹®ÁY·â šÝà4~Š5k2UwU;ª#-�óÿFà;4Ky:ŠØMy•l�<Þ¦Ö¹ð7ü#Ä�Œ1ˆvË ëG øòg޶Ä'ÔOkF“sSÄPÒ�‰îì²�¥’ºã†6…»?­¤‰þs#EÇ}†¢�†rÝøgGÜp×ÕÆ4M1Åãa˜ ªR`ôäšâ«˜:H>®á䎊êŒ1d,ßáüh Pšz7þÛõ‡ÎYÅ��¹'¨&¨ˆÌÂdíë‘j. Ž vZ#i’#Ýòê˜æhII�èjâ¾N^½»Mÿ,³‘n(ïpÒÀD»|xûÍ,î@Ï£S‡ ‹G}PSÒ¤¼áÃW@�^ø±CÙ_17ð]oî._r×7ø7òHÿ-ÿeìïÙç×{5&'ª“§%çt1®ƒÃËÏVóztÖ¼mž:wŠŽ ÷(�æ$qnM€Ç‘q»½àÍÓÛÁB‚šk“�QpD¡¡ËˆèmŠxa)…i¤ˆ*e ®ý>fÏ 0÷.ꈢê�|[’CÙ)2íü竞û³«ï)bÜD¿ÿy®„­K�82‹Q�‹µšÜgÎ÷  Çè�1EÞÊÿ�£BpCD_ýìG6þ:‰jÐG×ó ~§êÿÙšv}zú?ýçþ‹ÿ¥�½a/7±N\&.[Ó‚D„ÍbR‰aÊÙbÊÊ÷•äc¸Ð×{ð}»Éø…jÛ¹’�coó·Xùçv¦/Ͼ_ÈõµSäªÎ.Ë ~l­ÆÛËÉ9¸˜ »XäAS[Ÿ†tHxB»ëטJA3Õ.¼âÝæÔy}¹-ºaâzÑÇ^Ï wä6õ@ó$Š€ÎÍ霊ÎD""Q?ëþ»9.êל8B}'Źû€Ü“D$«€û³‘©Æõw˜=³©×oÎêbèt¿lO4³wàÆÈ{ÿõ{¼yóöä`xn‘Ý‹gn0ä˜5íõTâl,ÖF©8áÝT†|uV0!㤠ָ¶Ô vø�k(Ä팑1§g˜ñÖFqNS»ŸÇç®Ù|›‘ BŽLsP„<�Çø—€ð,è‡#^î§?×�°4ÿ¬oZáù±þ5mÛðK¿ü+ÿ½}ß¿ô9¥Ë�™Ž®W“$FåSûë÷µ-mÅ팹€ò¢CU‡1ûnD¨Ï¿—ˆmKÀÓS�ÿ æ­9 ÇŽ}ßë÷'wî)á²Õ€*²{š´gçB*¨‘`œiÆbÉÊ÷F‹U³óãú½ë@bÆ–ˆR}ÖÌ8² å{䱸Ýï¸ßvÜï/ÈGn$èU«V­ZµjÕªU¥`ÕªU«V­ZÕªç8")ðÐÛï}ï·^U¾Å¦:†™Ã&ŽWÛf¢HƱ×\ïÄժܫÛËÆ«�iC©©Z6+0u µýÆ@î6¯M\€ÿ–9Ÿ ÈhùÇv'µ/|LA2¥l¨qݰ/–í^ïÕYDä e;øWœ Jöl"g ¤YdfBU~×ë&Ûä3ºõ»š…>7…+¼cCÍm' Y÷¢§¬ÚòÒÔ×Tóç-«ÝìñÇn¶Öæ*à³sc$ƒûˆú9>£9Œ¤`oëvÓÝ$(zí3¥‘?¨:?pª$ò€›:]!e¨æ äìêx#ø¦,ÖUJPˇ÷ÖÉ'k_í¤ˆÁòÚúÙ[¹{Sc&@™š¥|Pš‹†sŽ=ˆæ˜†M.‹»YR¿’CÞlžÅ�ué ÎDMnjz‡¬š†6“xŸ=¶Éppî‚–³NƒtU5ÏãµE¨zBЕªðjQà{zPT=RS¡9m‹hÙÃý"ŽóQ¤Iè´5'dƒ»Œpksh(‹€¢ca|§]7Î&ò!{ÀiŽx°3g•¤5�û½p˜pJp§ò÷ØÙZ’¹‡A3¼Žî“«Hÿìðä)Cƽ#´üöÓ«t2ÎuP‘Ó0Ï'xÛØ�¶جh÷íÄ%Ï<­ò£dŸ"[ìØxn—H8-î³y©ç¿Ÿœ ´IÏ `˜‡~%©Ï›2‚øhÀ|w ˆ„IœoÓp÷cd2�Ú’Ø öîÝiÂZ\>ü}�‰�Në˜w‰Š¥¹ Q'TаöNßK˜“_ÿ]×È{ÿWý1Báw ü÷ó‡¾úÙŸûƒÿÂv½þæ×_õþéÍ›—·ot¿^Ÿ¤8rÙü¢j�Ï-Œ9!]¶®#w¸ÆL¤Äض RJ Ž=A¤¨øELÅÏØ.ì¿l©Áí9®Äì¸ßŽfñ_޽5À`wŸ-ÿ•ï „´%l)u3nþ A$·ï4vît¯Îg\ÉÖ—Y‘ó�}ßq»Ýp{yÁËí†}¿áØ�å°jÕªU«V­Z5Ô"¬ZµjÕªU«Z9#g!Ulªxл——¿ê¡…RnJ)i›²1]¥Z”C€C Hî“DUMî6:‰¸@sâ¬A+lÊsxEÙh9®Õj€æ¾{«ðv¬eÃ5Á”¿U MµR,ÿµ«Y´¤€�ˆ*ñr eSó´áÈR®ñ¥-˜RÙ¼s›ûÚ²ÈQÕi âTýº¡¦Œ´ÏÖJP@UɳˊF·hvÂŒ.•ÖN’³SJ£‘Œ�³ê§TùÚbìœÄ”¨"�PÙ¬oíß £UôŸÙÇW[jôL^b€”kÛU[vrîìÔ¬èï ‰IAâùuׇހMIæøÑ�¸ÛÿFeÌ6÷¢Ë²ùiÊ|÷KBíó:kœE´õ�8»ûFfhÇ5�DÎØ�'}8D´äº–$‚“ tlŸ“•ù€$¥/… ~&v¢à>ÎDí¼)‚&fÞ-¼ô/ayw_Šüú{i*Ôú6«(ÙT� ÑTÁ�ùbæBâ  E:ÉÅŸ¿ŠjÕ‰-úØ"ëÎ&©}|¶s�±�á:¨®_ÍpsU Ô²{€G:]ÞEã˜ÌÜÚg·ÜE=œ‚Þ]”ƒ‹˜+ìehžGÖðä`¢â;v\�;ið ðJàù @�[k*EëþoPÁbgíõ÷"8€„›Å0pÄ«ÃüW§ ÷D³IèdŒO2Â�UÍIÇQ^Q{G ÿ×êÜâçH@†ë~Øž§¿Fæ£kÎDõLHCÍ)8‘Üý1rÂŒñà?¹)¡�¯ÔåZÉ?úøÔv”mdljº4� à”öÍ©>€0ºRÝõã×ïßãË/¾Œöüþ»ûphÖJ¬èk•ö5F$¨p%2ú›Š¿Ÿ� ]Ói —‰�ªž$¨}]k¤ Ç��æD.¾ º9Ò' j~t·èðÌtör—Öþ®º§t׉æcÄ‚æB1æ‰Üøp$#U9­iÃMï“ÖÂq ?×qúØ1Ùëw þ?øñçßúâð�Ÿø‰ÿÏøƒoß¼yÉù¸ARb¤�aÊú°´ioL„DXgU¤´W‡€-5p߀õœ3Òq@ÒUEÚž®W<==áéÍ®—K}Ý�Û펜ßc¿ï¸ßo8ŽÜ¢ŠªŸ�#¥ÕVA »XT�¹WYTA΂,¹�²†¨b‹>K%ÊÅ.I³âÈû­œÓËí†ûí†ûýŽãÈß(ÎaÕªU«V­Zµê÷C-ÀªU«V­Zµª•‰H‘'ÞŠêçû~üù‚ÉiWJk×µ7PuÜð©$€F+IÏ.wjh¦²Q¤Tòëx®ÒìY[4¥¦Þòö±¦P7 QœfTI(¤[�¨…�´×KÍÈÌõ﨧lvõ–É®‰Š’¦‚fÔ3ÂCÙBdª!ëè¹½=Ÿ3ÕöëYí ègn.1'Ølìc63Õ×1»ðùÞ+ &*P»Wgª×ÉfÉÙχÁõü;…ÀöpÍ™A©(xÈ”Ëò ~³ºŸ·m6QȈ�ê¿"$b»,uí D‰«è6£êìN;xP6²Y©’;ºŠÖo²}#^» ÐEQÔù£Ý¥âdO]Ǧw|×äÁ³u¾• PÛ¹Ï"€(ÒAÚ&¹Œzt ×[S—=x—[ܘ@ª¸»2çô!^Âr†áQG ½nãívÐ@/)ë€óúä*šwóè™`ÿ/ÚNÊÇáõý\«ª›:Ø@·ÚG¢ÑÚÙˆ,ª^½ìÁÿÁ¶}˜RN#@Ž>–á€^¢x�^È[¢\üDm£0—jt‹z‹êƨÖû¼ÛZä_+UýN4a–kO­%;ÀåNaHƒ÷mEAÜL£�³E(ÐìcUªoú¡¡Z€b®è&oæÕ¯“Ëm£»)n+ÈuŠ mŠé¦ú­çðj¾6ú|è¤�úÿê�u¼TkëŸ�þZƼ—±“‡aãaR }6Ûtã�Ëhá�Æf¢GGrãÁÿeˆp`nS¹Ó§Kg‹ü®àªBpï8»(øv|¼èN>3Çš,qýM-¯h'�L sjʈ!“zý:z”�ç Š‘9“h…�ºBÀó‡øò‹/;)ÉߌàîFTuf9ÚˆOþ.QAê܇ƥ$äÏOÆapq¤ÉFPu�EÞ}Â'Îójp‰#Eå¹Ó»9ub, ç®§Ø=MåÞG:F"¹¡£n´­Ý:’›ÂüÖ’ñn„W={'ÍÝøu¾zN¥Îné!+Æ]|"H¬ßŒTõpÙF%2ºÏ½^Ÿþ·?û‡þð¿ýòüòáØ÷—œó]ª,?U²/®îÙSãw-ûîe•˜ÁŒ·˜.æÔ#ÃÜ<´gn"*ÊÿË—ë×Ë®O×òš¸ÝnÅÍí(€}ù«[Àõ‚§ë×ë8q;ŸM )3¥TÁÿ ÒÖ]LõäÇ^Ž¿sTrCbHÚ�7î€C�³`ßwìÇÉ5ZÌæ=Ñú2¿jÕªU«V­ZåjV­ZµjÕªU­rΜ¹ˆè(>ÿÞoÿÖ/ˆÈ·‰èØXÜ•;Nã[Õü¶k@ª¨€1äÇW^DÀ© ¦²)Ú«b½|>÷ÈÛ,–€‰ $g‡!uY9F²�¬gÝ6b‘YŠÝ¸·TVj»ÕͺރD~STaé6ê°,Lnöm[Ÿ]¯PÛ¼/öôŒsÏ©mÙàQõë7Á øoÙÒÅ_¥«û-·Ö²Ï»‚¸“'Œaºü`4kYàäæªKo1ÝL�•šë@Tï ,š(’çEKñNÜ•Òv�Yz&ò�£ÛóÔ3‰%æéªSÛU´�Y‚p«¦$lÊIlè¬xï3$‚ ¬-Ú¾9?øÍÙžqO=r£’8Ô@ÚF¿1ÃøhJpê@ÿD€+�êÅ0ù¥âaÎj'¨8÷„°_O3ZJsïÐÁGÞ§²[ñÔJ»+Û 9„�’F'ŽŠ0)]!Ê…òyÙ£„9ÆsD<Ëyû\j €ƒ#^˜3ƒËr†p$€¶!®n†ü)60=ØüöæíSX 5â@lyïDŒ†Ó%ÅÖÇ®š=G«„Y>ɬ>uSÊ×á“J=:d<žwÄTÊ3—OLhjãpv4iÏ¡¼[Ãï+-fgpnõîFèøruÿ‹§Áºiù5ä“ëSÀÿ‰ Íïçsø¸'B.ÑA|šŸêÜúŸa=¯žÅ<|“ãþ·c|ø€7oÞ4wEÌ0ŸƒðÔ×Ï`«¯Žd@�Ô�4´9¨j‹Wò >ªþÍ‘¦¯ƒ“aOÃ"R­Ïۺ죊i/ºJE—…qršÇz긶 :2‘R|®IzÊïЇw™Ó1q­q�‘L0�§Ÿê�BÃ1çú¦jþß=5¹wˆJ)ý{ä�ÿcÿ3Q}ìùþëMñœµÆ_qJm‘è ÁÈÈ™š0¸A¸«Õ ¨„eå¶8irAΤ'¼�œ7´£�MôóR?_[æ´oXB¡9�öõ0¾”œÝ±ëG©À7\Þ³Ò ä¶b„ÕäìE^çyz™+æDÑÖ@P> ±Ö�íQ(s¿jŸG“8�Ð>Ú@�GÔ¸Üùãœc§= „ã &(½è̘¾�²æç"Nq©?ã{D%ˆ„Ž™u¶‡Êˆ54oç4þ[}¨J8�Ç ü˜Dr~�s×âìÚIº �‡*ÍÑ �œÖ9J¡78Íh!8ÐËÕ ðH½Þ¯²«´Ç˜ À¿bÈbq„n�c[_†¾Ú�>Ó@V³µR ¯‰ig$·Ó¸Gwœ!šŸû9] ö¹(ðþÃ{¼yºð³>{¬Äòå�{hˆ p´æÔ¡=VBí&Òú£ùÜ·ûУ–ü˜R÷"*ŽØ¡ÐÖïÝa%’x>#}X†�¿<ç{<„žÖ¢ÓºS× ¢ÇkÒ|*�ý=TuzÝ-Þ`p™Ð‡£B_Y‘Æ6™0_Ô­Õÿ ½ÿCø?ýßùòÛßþÞû÷Þ‹èMrÎÇž¼€ƒÓV\ÚzÀüw*z•½‘6Êw/§8ÞòÑ�ÌŽc/6ù˜®—Kñß<á²]À©€ôûýŽçççbû¿ïíø)m¸>=áéú„ëõ OO×FP�úœ`ÏU³é ¢µˆ4ðßÜrî}ÃÕÍ fR³#òX?2°mH¶­M�I�«V­ZµjÕªU¿_kV­ZµjÕªUšš3‰Êß"ð—û±ÿbC½+xfª 9Ú€)ì©a€E}>zCS³q&ÒbÉ@2ƒ¹*¡Pé€Uù‹ê™+`¬šc.`u³†•nõjfÙ—ÛVÔ+)YeFÎU¹¢EQ"*!W–�¼PíØ¡ É¿+ß6ÛÆhÝ\vÙíÍÞ;%$—ý+¢9z®{m#Û.ðu¬¾)k>ÙÏ÷x€úÓAÑžE‹Íf¶k¬àD®Š£F,¨DB³kÕ–‘köÕ*©ä ³‚•!¬Mµæ *w›ãòyÞ^ŸºMiJ…ÐA#pncÍ6‘ ÄÒB;§ùÌÄÈ$Õ²>ú#4-Õ½R'¢ �3SCžmÚ½rÌâÚï깂¥:5ÔØ ;q;H‰³`›RR0DÈ#!I®Ÿ�ˆR{!Žs§t3`$€pºö„`ʹe��Ѩ¾ôZ�åÚ¾ê”ëÚb  k¿�©–Ðä"<øÕ<š‚”¨Zä‚"a¢!h4I»�Bn¹86h�-i×%}nvrÄ�È– !ËÜÛ燡áÀ¡‡‘(@ko›Ê¢P·½U•:×+�¤Îˆ\‰!­ÙŒhQ΋¡ÐJˆÒ’ШUÎwAƒ22Xžû€è³~OýºY¨9�4ÒÔˆ±¨Y?Ë|î à£eZ�ñ>Ë™ˆ¦"ïž¹ €L¡}š€b#ˆ¤uL;ÕªHhq¾ä!ç~<Óɹ¹ëôŽ.E‘}ÂEOÇÖÖýþEZÜ.¸ETxàRO„ š¸)à4 "�AC´Ã¼ÍU]®ƈ¨¸øp2s%üìŒçÀb$F`òš¨Ì„¬;Ÿ’Áæ{ê× ��•áŒzôK_+Â$hsxæ4q²÷Âú±�ÕÆ ÌŸ9bÅ8A_©Î£ãò,)}ÄÒ+O¥ªå>¿ßn¸ï;˜SÄutBrkÊ`vA�Öæ˜¹Œø>+m!ðžý–AmÍïDEëO Î*o–ÒBýRz|ˆëgÕ9yEuò¸2ŒwG¢Ñ33*¶Ùè}þªúÿü³�)í 5.~ÿ®¢¯ÐZÑ™œ#S²›>ü>ô{#ÿØw~ü_þÓ?ÿ ÿï¯~øÃ÷"ú¬¢÷Ûí&"‚|Hɶ¿Üp»\q¹^‘.¶ÔÙÇöŒ!"PîNKiC{Öj<)ϵ99Še¾”ûðeÛp½>áíÛ7xzó¦=—î÷{SÿïUý_ÌŠS@q à´ÕùØ ¹©ó¥§sΕÀP¾;å,8²½¶¼¾¨ÿ˳+ÕÈ‚a�¸Fª)òÐ_FHœÀ)U2ó"¬ZµjÕªU«VùZ€U«V­ZµjU/Â…ˆßÑ—ßÿÁoÿ9Éòc„.yö%§1#«@sîvåHuƒª¨�Ò–*pM�ªͦN��ŠlÍ2˜$„T?‹Pmè+ˆ'¢Å ²Zö{’å‚Ïr…‰«ýµ»Lu“ÈTï¬Û©9”è%¦¦^ ¤ým#»ª»uÌH§ Jrj w ¥�ÿ$7§Sæwð_k¼4’B>}#tÅvS IUxwṳ̂ñ d8ÑYPäxÊe+Ž”Ëæ5uµüt0^Y-Ù ™rÅÿiˆ@àz­Fßä§Pn›õ(ÇH9ZðN®�£‚iWoŎDZLu°2¼Šzˆp™Â¢ n.}púˆhwÊ`H%B($( -’�«SͰ–æF }ë_�²–²Q�ÚŠ)·ls*„±ŒàÆ¥ÉÅŸëØ=%è);\´‰¢…w·JÖÁæ�ëý &þ-Þjƒú˜Éxˆ¥®¾„³‰÷Žž·Õò„(VúFÔmQ*Æ"ÈÐhYÝ,¸�nøa®.VÖ—ä�œA¬-ž�€ãÇuuÚ¡E]´‰Q¡gòvü½-ì8�WQíhCïÝ¿ ª3 =¸mx²¼ÛF´J÷m; ¨¨ä‘è]ÒUáæ·©ƒ¨šæ:÷æ �ô—˜~…ì¾v£µŽô÷• bo›{ÅcÛù¦t~j%ÚœÁm DG?"ƒ_ÍÔjþqÌ"c"à8p0�\Ãxè óbþ¨ŒÀ£³�øšëÕà˜Âè³ón!#ÑÆµqÿ]TM_gÁ§b^“{bŸŸô í¨ë‘”ÑÝz:骮m¬Ý¡H‡õ¶‘ݨGf(áùùïÞ}†‘öþÕÖ§Á-ÈÀu#ž*9‘ø+i¬ÌósÜF»OÔõ¤E ØsŠÈ0¯úóÈlè¶»¦=H œËˆ'ÿùY$ßsìÇQæ·Ž£ä�Ôhψõ¹ýÈ5#×5„RyÆ«D[Ö% Ž|à8ù@>2ˆ Û–p½^ñîÝ[¼}÷OOO "û�{q ȹ��QbÅŠƒ#ÕgWÅ~ì ™z¿ï¸ßï¸Ýï�,Å,IÇ…tÝ�‹ Pï&{ÆØßRùÞT¦Ww²ue»lض­üY¿ß­ZµjÕªU«V­êµ«V­ZµjÕ*-w<Ñ…ß1Òžßÿj±e/À‡Y›‡àÈ{³›. ÄŽý'$fl*Ø.E!R6P€”�ëª>‘jÛŸÀÅþ=¥‚Á棺HÌœW�TÔ±4Ù¬6Ðæiä‚¢Æn)ô"•РÀEWËj©ê˜î²^�sŠsÙ„7`UQì®Êï%"Ͷ^L5ãIfËOÜ\TRQd‹'ª‚Ð΃c›”c¢“ D«Ã�ÆÈ€zQm@/@Oq·º¢:6`¿ œ:dpƒ‰m£�ºÕ¾öMv5ÀÀÛ•«VrIìþv�8Û—ðë-#– �bvl• ’’«`êê�³m¡¶Á¢,ÄçÂÇ÷[vøD•Œ�ühüµW‰—ÖµÊÖ•×å~/uQÂ)¨#¬MÇOýØI%1r£¯Å�RˆÂ,oý~²H¯ º‘¤ˆbäKp ¨¿/Çr÷D¯þocÈ^Û E~-T—£â�ú-¦gàd=è0}ˆÐJ%þP‹|‰höô\Œd–Á|€™z´B%]磀ÿ÷cDZ€*ÒÆØÒ×§7xûîÞ½û ×ë¥:·;u‡ÕJ@.öÿFp>Ž£|rNP- þ¾ï¸ÝîØ÷{üSÚÚ±Jd›àÈùÈ-nLÉõ»Û–¶â4PÁ}ª× ŽsŠ™�RÂÓÓ×k‰#X«V­ZµjÕªU±`ÕªU«V­Zf7�XùI·í³ûíög M/å˜<ô¨Š’r uã„Ëå‚ëV6‰à¾À^Áüœ‹Í¾Tൂå)qµãgPb *ܵZBŠfgo*˜h3lˆ£*ÚfRÏ}-;”|0ò‘°ïnÌH)�êfYÎǾ—M©ªJ‘úyLÞ£-} šJ—b&<ä´·HMñmŠ]gãépDª¹Ÿæ Puá½m\îºÏ öeŠY1�ϵ‘ž=S.œ ™úg;íqØH-›¶•,ÀÔ”øf?êը݅@®(#3!µˆ rñ¦êVdÉÀ­@e´‰âµ—q&e¬¡+ª©åÇ÷\qqj=S�[†R¥Í)XŽ–, vŠO#Vh%·píç”RoÄ<_™ipu(cOêø//>˜‘RqŽHÄ-¾Üæ„Öñpä{•Ö7ÅFš·<{k1b$çN&™ŠPýØ‹ª¬©”á ]-$…v\í©Çæ`QÚƒ+Ù$£¸½öF îózòó° jD<²}ïóµÓ¶¶ ÙÎ6v�r[q"yàÎçK·ñÖˆ842JZ£À¥•�”Ý9”©¹�P•ýÔÏ…p¢öºž�mkJi m=ÎÚÖ„®¾g¨#�rˆÕ0ëìS¾ý (5÷ƒñµýõ~^”È`‹¯ƒíyPšƒL{¾70pKÏ0 ÎOG»|Õ ÃóÝGà2®ÓÔ1<øóÆ`3ßçÛxô¶^Êo›—âz…ž¶GàW©=XøL™ÊåW15ÕY†85tti:¥A4�èáç¸I�íãú›4:£8o‘5q¬R[»¢cƒ?3­ÑG(€>ô´ŽYë8oH‡µÂ‘ ì¥' µß ¥ ù=êÿ˜ Ò‰aȶ6 ÌH[;õØrQI¾FkúœÜï7\®çQÒï9§µ˜L]Ïí.S¬È¥“ 'à>�ãâDX+Ç�gbœ^‡µ:™0t&fgE¿º”xH�Ρ™k@\ÛÜÚíÕ¨¥ó‚ý1"€NÖ²ó*Û‰M§vÁë×F¯ÎשW� ~WÁÿ3‘ŒÆ¹èOþÔøþÌÏýÁß�,ÏDØ·mËOoÞà~?J 1ŽãQQè§m«ÿË}U‚h.nit ºÝy¸ F 2ÀýØ a€ªûZJ —Ë×§'¼yó—ˆã(Šÿ”¸¸Õg¶âDV¬øUûqàÈ÷ý(Æ"ÈGÆQcrΕ8ÀH)·ï9)E'¹þXÇåÙ®®vn—ë—mCJ©®{RÝ´\lR}†O)aÛ.¸\/ëËüªU«V­ZµjÕP‹°jÕªU«V­PÀÂ]4¸üÖ?ø$Kþ1æbtÛzRäcÇíö‚ã¾(ª5WÑìÜI�=Øï7ì{!  ¥,åjñ ùŒ¯yõµ Xµ�ŸÆMò^ f&€“ÛWw*ü\Uqy×Ô2Ãí L¨›Ú,‡»Â5lÒÏÀ éžÄÌUý�ˆfäùìân:¬ÎrVœ-½""g-Üï W \€€SŸ‰kOnã¦é׆�ÜöÙMÉÙ:±Ž>�ùÞ>×oÀ÷ýokt8Ey¼nñçZݼ€TàÞv®-7t0E€ä\zmN½« ¤tÂ5Gƒ„Ľ¥�Ë>º½qUwŠ#® LÈ™Át`'Ô¨´ØÉ� uƒTP@TÚ—™@’ªý<5 ÔƒØ�,â,¦+é†3Mì�1ô'5�Ø+ 0³>®ý$Ø#t{–Ùâ8r>­[¢g°ÕÛG•TI *¹i–«‘ž€»Ž¦^s`Ÿp%ùÔuª}V'åJ#W5Ól›ƒBŒGy�IÂÝ Án­ePîí�J¿®fH&GzpQ#c;O\Xth·¾x7j$`ÄVŸ)œ1#·�?±€NûôÕ÷z=]�½^�­ƒ+Ho;Ydì;r¯EZ‡ØˆYiwx±{/9×ßÚXôªríÔ]ߪK© Ä’y¿R¾ÃsÀ¬Mü4¤„h\‹»Ý€Çù¼ô4æüÜï–ù†œvǃÚ�`zÂívÃõzE\ÑøLek†­#ªZ"‰Æ¡×ÖçÉåR´»÷i7æ6äÛÐGRaf±?ÜÏüë,æÅßdJÒ“žŽçŸ;ÐÚUÇ[×ðo=M4OJT�Ï�Ùí¾“º+‡�©Ñ)ój¶Þ<Ž%ï'�ê1À_pþöõñÍKO‘&C®OOÿæ/ÿå_û?Þï·gf¾3§ƒ™ôzÙðöí[¨*'ìù�ª¢ý-ž.O¸<]q½<Ý‘³V}!h0§ÐsªßJÎ9"Ã1ɨ>£nHœ�xCb®ï8ϬjùŸ@Òo»ùÈí¹¼�}:Àodj1—·ê@á¿Ì¹B,P\.—ösæÔ>3¥„ëåRÉ´ÕA¤Æ5Ç{†DŽ_µjÕªU«V­ZkV­ZµjÕªU€”ŽÛ΢™ð½ßþÅb,PMP÷}Çíå†ã(~Ú”RÙ¸EÏ-í`ƒHÁmÊí¬Š@@`¤ÈGʦo͆5 4Øš;E¸pfàd�Š2VTºªÒ¹jåíx�c/Ü&8 *¾Ñæ^ E;g@ƒÂÐU^3TÀ'îo೜ò�5†ž—S&á-™X+hÅýJ»+´µ)BƒZN'|æ¶ì½ß}=ß°AÝÚ*À©Vøø`ñâkK6¨ýk}©ÎãÛÜ$¼4ÑÀ–¾±/ÕÁ!¶‰:Å´bê#±XŒÖÃì}U�–AÝ®Ùçzkì§Ö2Té&e!¡Ûôc–3Mƒb‘|ž{W»õ su®Ð`¶Ýíða¹íÑb··�W·—¶aÔÜ D+¦�t`@&Î7›~Ð+ E� �9­À Ö1ݯúLmêÝÄÓ_sQÝ¢¯?Ö¾�@•«îVê¼Åf?±u|$�SK‡Ž GÇUOBxeªŽm3Æn  BDÇ À~tߎ£Ãzy>™iâ·Î_¯|æÉÝFÇ™éØµû°>€Ýpó1°Q, )}�Uk+<û�ÇŒ×ÅΛœ0€Ò�X!6dBˆÐ� ቪYñ)Öæ}¸ø¶S}tŽêütîŸvÖgš¢Šc{ ×ý)çô‘ã}¬¹Oc�åB§‘yþÌS‡Ý‡DÏQîû¾ð?ÜËûâÒÖ¹öœ1\l˜Ëõ!P§k©õ¾º¾[88/ ä}Dž›\f'µêDáoÏ•ç˜�@š9YDL\œðJìŤÏU1쳆çïÇ3.þnr^§çÛë°§¡L ôx ÏÜ^ù?b5â ÿæýcÿØ¿|{¹½W՗˶íÛ¦ÂT¬øß¾­cûrm—Ëoß¾ÁÓÓ<]Þ`»Ð©RÊk˜Pˆ T;ò6á„Ñs×a«uóºÛ�›’%n@‡¼ÒÚîõ¼JÕ«æÕ"‚ú¯¾O»Ô>Áåò£j Vúü75xûüjJÜ�Z{½Ù�fg7­PŽÙ³Å’ÜZH ¹Ž �6ÎmpUÕ;½J $øLô¶aîÆ@q@§–#oWîÁñÞ'Nùkð£2´fšwq¢†>-ŽøM…ÐÀäâ#ª%±ø1N�TÐØ ƒSCáqþlô6÷j¼‡Õ2å#Ѧ ‡rðô@^KKgûß4�9€Å»\òéA+7 òh4‹ûÖÖ͵`0Ú­çÜ,È{_×X7÷:áAh#HA^µXm’Áµo؈wÙqµ¤® »ûeP®¹þ÷?’|ÑêØáÁ«šZ²;ˆ×Îa= YУNx쇬×sA[7-‡÷ÓäDݼB>pØjØf×hÙç$×¶¦�yâ°�î~Þà¡rÝÏ�°âž¢ô!5‚_¾-g¬N¯»¥«´Ëg¸goÛÁßÛ�åAS��Çj?€ñ.�ýššwì7»ï�Ä«Sêã3{­WÛ˜«óø5rÊéó&iVÿv¿mñªÔ„D13gxí„h˜»:œÜ£Œ æéÀ: ú”ÐåÆÝO�[â\%9@c¤Qs’)¼EÅ‘�¢ æYüΑ-è óæ’rêx�íàˆqFV n�Eytn²Gqó¡UÇÆc ä”ñ9%8�<°Þ·qDÂÑ@, ÏC!A§ë·EË ÞúLèdÍÔ™ƒˆ~´™æÏ3ç ­MKÇÐüÈ5=±rÑŸë[ÿãŸø©?ðÝï·g7€fÞ6¤ËNŒ”.Ø�Œ|d€ þîÍ[\¯O¸\.ØÒ"ŠÄ N‚”—šªµ%ƶmØ.l©Ç]ˆ*8).—ƒ”ûI$ã¾ßñáÃ3rÎH‰‘sÆívÃóË3î÷ö£ÆRe9õygÝé‰Sjß ˜7\¯lÛÛeÃeÛNnfߟ’µC!‘\5ãÈʹ8Y15÷€3�@‰`ÕªU«V­Zµê•Z€U«V­Zµj€‰é؈(¶íòo¾ÿý¿sdùÖ%1xÛ�·Í&.ÙìRì¦M5.õßY²>µ;$T…5ûööˆ“â£Ùu«Ïrõh¶Ëxïû¶A/èõýLòûåRra•´’P€ÃúpÝØw€cÄ@zÖ®z…ŸÙù×ãùÍGšlî’³ �èÑý@½4~t<8mc¤’–q.=3øD´pžÕî7‡ËIWm¹êæÄ .ã—E Ì%zÞAÚqÉY»NëBrg;Jò`i9";eg`Ô܈֞õx\ÁI#±4†ê0ä¹%�APUÛq$´×Vûe‚T€¦Î±É¦u!éœSÍ­ŸÇÜuÃt„å¾×®uëBÎÒÔ²_ëq ×S¾<ÐÈ(’¥�ÑîÏ\TnJÜÚƒ€Úàæ ac°áSg÷†±5šò|‡ÿ·ï/?ßô±uþ(w¦¤Ó M@9´�åñ�m8Wg[/gȲsWLAyòÎnÔ>¸ÎŽÓ°Ž�’­OÿßWk:¹¹„±…z¿Šç>²­wsš†7ÌíÜýÚö*²5Wh ×ò�¦¯ÏŸÜüö”ÎÆýˆ”þSX�Îj)Oúü#‡Rr@³¾ÒhCŸ|ºÚI"8[ïÏO»gž³"íd¼ËRÏÇ\N'÷Ð3ã“Ú<”>²êxØ[Cû‘#D ä¦Ðf“Ïok´�þåV)m¶n¥8V&¾4Ñ…$´ý8W‡’¨/‹§¹©. AÑDïmZ¨Ï­y€!FÆý»ÝK(¬…Î5: t¬ÝÛµŒÄ¨‰uA‹{]Hðô× šg‹œ V@‘SôH‘:ÅWˆþ‰¼7¾„ñ#E–|ÃJ[úüÂ/þÅ¿'"/Ç‘_˜�#m—òèE„-%ÐeÃå¢xA®`;3ãz)Öÿ_Áœ*q¹ÚüWÛ~ض i»`«êyû~”8AS'®\]�ÈùÀËó D2^n\žùT±ßwìûû~‡H>9õØ÷ ®öþçûŸ¶óO)ár½–?· Û¶uWê[JضK‰pÇVUÕ� =Ptðb�Ÿ“V­ZµjÕªU«~×"¬ZµjÕªU«ZíGVU•ïþäÏþ;?øÁûŸyyÿƒ¿©o/¸(À¸€˜°¥ H@Ò„¼È$æ ÚÚ’¡¢"Gg•QBjQìn“¾.”îÞ2¾ªZ‡I¿)êÕü>“V�·¹W×½u@',Íb0‘ÔŸAƒH£õex0fuÇrç® dÉŸ)§fùÛ®eÉg¡û-{i6ó�®„‡p¤žëé6¹*§M=K<ËM—!GW\ �Nªd·ÉN¶�+ âðû¢¢Ï•¤Á`¦žì¹î €2Ь©ë�ÛÄH˜ Éör´ÅÕiç†mæzþ­Í+©£)Ú™‘&™â.¦:Ä`èLIJ䲦㯋 s‰Þð'XlúhôsI^Ý$o×OÚç`²H;€!¢üϹl,CÁ5BDDŠ5­’@âìi¹ÐÐzŒîNa×Ï(q±Õ‘LåïÔµl(Ž�1¥ú[ƒ7¸w ÕYü¹}¤Ê9©o.Zã£ÂQýËr�®ýSb«�ÈÖ.ŽcP܆…q2>`ãÝ¡åñLx òÏmð'ùëání»B?Ú¶ý=ƒzœRx�™àô��o*týT{ó�)¥ûâø  ƒÕ?UâƒÎÏ;Åe´hÿ<{8Qo¸Ýv\Ÿzv¸¹û4ÕzuDaÌàöx9®ñª“i¥Æ�ìW3DHű‰@qlP_7m3ò_#‚h rvg}OXŒïŸ­��<7:ôèã|�F@'r8·@L(ÅÇ©3£“½ºf…û’>Å|�í,&÷¥O¹ŒWVƒó< ãg~æçþ%U}QÕ›ªîªª*ªæœfªw&†1TʸÞÒD©L‰œq‚|ØŸ•H ç b‘ëó ÌeÉÀú„”ÊsN–rÎGÎP½!ç½(ë«Í›ˆ ç\ÝÛ¨ZõûvãÚîùaÛÛgn— )À¿u[ÿz\NŒK*îÛ¶aK=@D°;(ñ5zÕñÍÈÄ UªÏ—¹ V­ZµjÕªU«VùZ€U«V­Zµj€bWzìRÄV"´ß÷§ççÜ^v¼y÷„wœL©âåŒ-•|vSe9#AÁD-/²A[“¸ìfÞˆ“MÍ"¯ �¾êØé3èÏðÈ�¯ërv½ò{47¶sò–ùÍ"Ö[e{Юæn�'àU*#جè6éqà4Õ íøjè ¾uÊNjö戻õÒÕ^ý} ¹B,»]4dëÇò7M‰n¿jv÷2ج֌uÑpQ1œÀlŠÎº ¯Ù9”ß±U»Fãöð/2P¨xòBy§„xÍnÞ,™]¾t „Kç1¢)‰4Ž÷z|­$ˆ@9BP`‹tG…fELgût{o#*�«‚(„9„]ë lu–ͽ#CÉ�Á\~Þ!"òÉÐ.ýŒ›£R#ïÙ639+²*²b€Xž¼F ´þm6qfã¦8�u]–cÞÔÍ ç–wÛ7| �x«|ŠÊ$£t&vjÖôM ]m8ÅYºJWp‡6¨€(Uƒv­m%">f ,;ÈYýGrBÇ9ÔÞnGÛàF2U[I\LEäC)jЉºý>ùMnt†v,æBÑÁj×Ùð–q“ã¿�¼°ûµ/©›}÷Žé ­H¦¦ÿ|{9ORòHý¸ôÃÊþlß+ØBâëaÜR%ŒóQ»†6åTÚXÔÁm⤒®¸…Ýsü8~ æ3žÆë$>¦�ô1R‘“>§©Z-�¤5ÖA¨P9‚½»öæšü“ qXö¹Ë‚SÌõ–ß��ÖßÚ½�ßÕÁ¡�ÆúcU¨Ù‘�¯™Z—·¿»º>>=/ÔcöÔ§s¬É£{ót­"=Ç-„–Š÷¬[eÏwg?þS'Í!x0žtöùã¬uÏÒï�sÿ�þ¿²ôÑÿØŸøSÿsf~N w¨Ä©dÖW üò?nÏïvÏ’39ê÷§â ´ïžŸ_ðòò‚——gǑܢ¶ë†ËvÁår©±€§HzòKLkgg«Ÿõs¬¯5g€ýÈõû¢}§b´Ø˜Ïí%’û÷–ƒ€e䣫þ­ò‘KÁmǾßp%žNA´¶›”ïš”s±´¾Ð¯ZµjÕªU«V¹Z€U«V­Zµj@DUõÀ$9oGÞßÉ‚nå» ïÏ//xûö O—+¶-�Øå¦JÝ¢b)ÕJûr/ž2ÀÆ+ˆËïtãQßÒA)°Œ 4šd•«Æ�~õ*ܸ!­§c¸Ÿ{@º,¨÷Ý«Û_Û{rvä‰î†P€j ù–!ßŘ@ÌHLíÚ¤:K^->쾫S¢+�@í™ÓÄŽh8¥-—±B\$”s2šj¿�¨uc’ê5@KCg*åßfå+ª�Eµå¾CÎ>Å>¿>lØ:'€ag´5WÿX®gé(ˆ#±5²ˆ‚IŠéBUþuåÏ&»"¸~¶Îg)<!0d(¸9áŒJøG�g–{_I*zR:PD4¤©�qÎ"}ž¹Lb?7*É�YøNè$–6_H¡m“¹€ññúæ e=Gˆ¼=8ã�S@"#�F;iÇÖ%µö¬À�:g·@Ï€ Hwt§Bïã¶ü�ǘ-J¶I¯“E “ëÉ"|�[¯Ã²¡§ÿÿ(@ä3´ýp5RD8-mà kàÉ-Ç’Í™:Ù"1AGççO@�›L&Ng%­�£QŒD¬GÍòz}$Oûôš�VDÕïÌÕå›s´ãëãWªoŠo^ôÊð÷¸ïû”cÂÕéxŸð¤çJôq þcD�N~�q,6×#ÌÂØG#+˜&œòŠ]º˜ú¾ßì퉮—· NmÀŠ(n·;®× RŸI˜¦�õáŠÚºG¼b¥ºÅ~xguè÷:¯¬W§ôÏ“ˆÄ­`é¯:ýªóU{6.f¤Âsèiñò„B�½–ækg¿vÿÎstÒ#e¿w´šTº Í×OTøO*íýS\PÞ}öÙÿêþ¡?üå|¼t DÕîŸáU—yŸ3ŽãÀq;°Gùû!8ö÷ûŽ——g<¿¼àåù·ûÇq‡ª‚‰±]6\/<½y›§7xzó„ëõ ×í¾p{>ãê<`cº+õ ðÏÌ…¨À½ò! Ú E„å|ºGIù{rÎMÚc:¨¹Ã%䜑¶ >Ê9byÁ~ß±÷eý^‰š ‚Šùè}Â$ë ýªU«V­Zµj•«EXµjÕªU«V¨9Ü ¨ D„ó¡Ÿiͤ´­¶L‚|«›Q—;Þ|ö—m+*,âjß ¨«vq7€Ña3³8ü;pÿZ"x¸yt@}M«f"pÖb«~÷rR@'›é$lùà€»–aƒW;ÀȤšÃÚq>ôÍy#HH äì2˜û†5�A ®$â â ÅBS�1>iL.ŽX¡¶Ìv4P@âzZ30yë[—_A}rn ù� Ô�Ô\ž6’€3äЉtÐ6³‰; í �@½,ªe|pL¥ ÷CLmš=‰ ; HkSR…€Ëf¥;w{?“×âÑVtº @Œô•É;ÿ éØÉ@›þNÁÉi`”pÆŒmw®@ÜÚÉ’¸Z×xç sÃ0r��ÿÒAòΕ(d”‘^£Úã?|”»´ñ§Q «i“1aŒùG¨1B‰‹Ø Žä ´¨œÖ äb¦ `}cŠx¾^�×JS�  –Y•½ò™˜€Ka´Å¸ecãuTLjE#àJ1ž%ftw@‹03çúð©ûËcXŒI˜YC¦¯Õ4¹ú@Kã»NoüD¨LñÉ`ÿk<í‡EòåÏ¿þ�ùÑ>râ.­ãÕ“øQhÍ\èá<_�ÉÅáÐ0õ±ŸÄyèÃ!}~�ÝÏmí| Ð6×Ö·Om—8ëÔ­+}ù¡aŒ*�OfõþÈ —í )mí¤»¾‘QÍ;Œ.§öÕª¤¤¦Z¦G¡¥_„Ê«ÐÎÁmˆS%¾dí*æ6®u¸A´h~EéwûÈ£ð;m?f˜]’Mñ¨ƒMýài]�m©ÀÄŽQQ�¤(*Øßû£Œ §´SRž=ˆÐ{Ú` ý¨A\”™½­ÐTú~ý2D?a`u·çúYL éñmeU /C¶xj˜"rŒ© - ÃZ©Ñ³!"ôi#¿ ‹„eü òN.”²*3Uëk÷œ‘(uCh$„G«ž MQ•_êˆDêœ=|ê«vùk¢:åïxN€wí÷‘3°OxÝì{à -eîàôðŒ?vEÍÖ~ˆ:ˆ$:ýÈѧèîDžw§†ëœ“fíJTŸµÝ|fñ:Z†<¼^m7gžÅ§�ÿNRÒpßüpžä~ȘQúH{uõÿ앾Ÿ )å C쉛Þ?⺭Ò|6NHÛ¥æ¢ÓƒùÒþ9 ©Ä¨E%h ´÷ˆ´9?ÃëZ«nà…uÏG¿´ø¢s$<’>r¼ÂàbÕIcÔnÍòh†‘_k?µÄûüóÿõw~ü»_©ê-m¼S}ñ䨦 ˆ: ž�¢z~yÁó‡g<ø€—Û žŸo¸ßo¸ßvÇŽ}¿ã~ß+àû±CEÀ)áéé ò‘A̸\6l)!¥„´18 [»8¤”°m8q!P�úRÇÔa Å¤ùkhß7*)À@~û.hí•EÀÎi‹†¿ÛŸžÐ¾'¨’q–u}9 !HdÉí½œx}™_µjÕªU«V­rµ«V­ZµjÕ*_T·5“ª>)TįÊi&ˆf0·ç;î·×§ .× ˜©Z8æ°yÚ-ØÝ&¶hxÔ€T·�Làõ¶«e0«SM#î‘ô¤¦hPåûmOoÓ{†D½•¬Ä YÒþú¦ÕfˆEuNÍ>¿¼„š*¿ü“øïÏ!ˆXªEA£¢nÇŒNß2 g¹ž/»ó¨ e=#Ãé©oª9@Xûù#KµÇ�¹¼'s8×õ‰ÆTwƒQo�ïQ dTâC»Â ä+ïòà«À‰Éa"~Û*5G…”à:u¼>âJâ ®|¯ÿ§Ð¨ Ç£sæ€ D ø‘ÛÅëXŸX“ÒÜÕZÕìgÁäˆÇ Æ •1¢×ñ–•Þÿ­gÏŽ†â—yÎ1“ÀIöu¢¥î"ç+P÷À¹`°ÀWî?ë,�œI“D��T¦Ár>ö¡72ÄŽDÏ`,M”ªˆqúEÕÀC¶¶hpLq\ x· ‹—8Q4·‘Ð퓵5¬çÀÉ椑VÁ øs¤µN‹Ð1J„óaÎÄ…G�…Âçúæ›9Ψù½œnÉý¡&¾×ƒ2znôO.G2²y0¦êLÕçÚèÑg?Ä9çÅÉ„Ùà�£/¦b쇟?Õ¿âºðjTÁìùdì¿“¿§Ÿß8h¯GâȤ-¼>ÚÇS�ÿ¡âCãú×ÈIÚõþLãטq½ÔÇ× sœ‰R‰0"S‚š”–g×/9÷�Þ¨=S‘#Nõç³NÎÓHTòÝá¯?ĹŒA8è$¢àp¥.òD½ë‘9 �0¬ÛãZáÆIܼnFžQ}ÍbîZ¥#ÐiÔéÚèGÄcVšoÿ׉k¿ƒ/:³uþ•:µÍ'8§ô¿ô—~õ_OÌ7Q½+4'�v¢dQúS®ÏaÔŸ7sÎØ÷¢ðÿðòï?|�ï?àÇØïwìÇ�|D2Ž#—Ÿíå?‘ æ¸^¯�#·û6Q|.b¢ªúß°]6li«à{}â–rŽÍÍj|®Q`į÷Ì<¢©;=•çšè `$„”JA!*lýyWªóÀ‘¡ºC =:­:Ï%Ië›üªU«V­Zµj•«EXµjÕªU«V(þu»•À`.Tó"U9¨… Œ’œ*)Ú//ŠÛmÇårÁåÂuƒ§+HËöìɘ ªX·\I—�ÎÊ�0� ¼•“ˆÀޏm×°¿k¶ìý Ä©íU=ˆU�6ºÛç´³—~z’{Å}ön5—S ¸Ì€T†�Û™ýnÜ@1°“4D2ziËž÷h¡Y÷ÖEˆG='Žxá³}Éî®doÀu�GØð®VîÙl>Ûç’öß½mCÜ+Æ­mÂf}ÿ‹b.ݱˆúçªÌûpæBa%êl䡃›{ï)X£žR³Wì€Ôþa@�.Yô(,Ê?”ªLò {êIŠ-®NÅ&™Ôñ1SE'Ïïdï\” Xl›6ô�Eó2Æ(ªqgŠDF†¶9µ XäãGF„bH�ˆóÔcChÄÚºËà¦2¥É'ØkãÄÁ/»Î¾NY Ë‘¢3xõÛ§*ji„aÜ…{g‘G1Ö¿v®ão¹pBü¦¯¨�ÛéÁ�ólm¨€SjŽ#ðªó ™ÂÁá4DøûFiüjFí=a…HñÀo;ž¯¾rj̦'ÿþÊÙ1œ1âüyÁúqFTùûVò|ª„-:ÝÛ  1Bö4éÿ�õó©uòžŸZç�ë¹»¿~Ê sòé¾áÚöÕaP»‰ý£N&̆ðŒvÖ¦,� p×o¸¥:ß›º¸Ä5‚¡ýÞ®Wâ §¶(�ü1Œt˜³"m=ÂÈfÒø—ó½ E69Õÿ@Ð@uk‹ºg$•x/ yõõhöTñ±Y9sè§�8€ó³çðóqé�‰õ\su–b€9Ù)þ^ç'ÝÇËÄ}¢Ÿ8æ”^mš¹)òµ^˜3�bdŒ˜_|ùåÿæ;ßùñì"r¢"(’ë3iuI3àš˜�J¸í;î÷bñÿüþ¾úêøðáŽãèJ{)ªú#ÉhQm*5n‰qÙ6<=]pyºb»\�¶T{#èÒ–°¥­€íÄ DßsÆq?‚…¿ÝãJ,dž,¹|¶(rUôsuض ¶Ë†Ë¶U¿wƒ`”kÈ97÷/sH[u'Hl× ×ˉ˶µäŒý(çd4Ò9�Û÷ŸU«V­ZµjÕªU¥`ÕªU«V­ZHiƒJC& „�ˆŽ*Ó®zïJ+ä ¦¦.rǾsµ©� È�Eñ/Èbê Ó‰×,J¶¬in®e ËýÑæ9 r£l…Ñ-Ú%€ðÝ2¾©îO¹Õ:Ùduïsày'œZ¾½à  Ò`+zª(ÇÁ4ÞþÔj¯ ÷“þñr:>…³è?¥GÛ£' Ñ�Õ@ß3§�kz¸!ìÏ‘ü%ggçíþ?€&ôØà~ú¡'|Þ¹£¹þ¹ïthÍf/¥Ÿú1âÝêŸ@›€”¢>š<‘„¦¸©Î=/;¯Ç­Do[L7gh°c× °Ø‘ùa‰ìQ%:ލ“åÀç¬NÖ¨é¢3¬ÂýÃ+–'ýH~ ðêo8RŽ›_q”P“žÒÃq§ƒðÞ»}Œía„k? Î-Ðñ¸ƒ%Ì'èóé«�ïHDC›Íî¨Ný)Ÿ5(µ}›~|6�äÅ�ì¤Q‘=Γ~ÝÓØð„¬ðÀï‰f÷îb’<‰Î·£žžc<Ã,úFú‚ç� ´ÑÀ|�sÊÚUÏÏX=V%ö»:'«“ú_½ÓŒ6þÚHè`÷™8J#yæŽ?§99>«½6Æüœ×ÏÚsô ÈC£ƒÇk÷}/4wÐWMߌðÈMàásç´­Ïïq öð—~õ×þ^â´+ô(S 8½KÍ¥|·É ªÅ!kKE±¾Ǿã¾ßp{yÁ‡—øðá=žŸŸqGûnT¦f±Þ×:Ö p¾áz½àíÛ7øìóÏëŸa»nÕ™MÝò?��:*ø{%0¶-�(!µ�cÆ“jã%G/&l[q‚»lF,ˆD!#´¿;òw#WrQJ o®W\ß¼Áe»‚Ø�é~à†TÛqà ®D¾Ò¾¢²¾Ð¯ZµjÕªU«V¹Z€U«V­Zµj€²�T³¦©nÚ$®–ó-Ó>l„ªÛL$ˆ*˜ †ä"³ö{ˆÄìdíÚ¦ø—,ÈY¹€I@œ)›Al„2·zðÒ°)IUµ¬À‘°mv—=£Ô²ÝO@‰R×Fõ³EµIJƒrÕ·R¤¤ÔcÎìã5ÈmÒû`?¼ÛA´í=9)¸KŠ/˜”¢)óú+Ç,óá- €°x`9ïNᤒf sˆC³U †°ùþ Ÿ[G»Z:ÙŪ�—È)ô#àqÏ–q¡£}=œ-üD�çÏ]IAÊ�Ö“©½j�Ò8å„»ãu‘rûl‡wЀÏ0&‡£DEàØßªÒ6²ýë>iC_ÑÁ§¨%=ǃt�þìýð“||Ç uîÞ"½ûeœm¥ÏÃÑ]§KÌ<òÄ‘*”†Ïû$’¡ŸhB‰D§�~ cMÏk\¬ @å°Ðœûzìò.ü­¥È ÎW&†ñA|2Ž‚Øk&Ž*öR·æœ„ñBÝy¦�2VÃ2·µ9±œ^.¾Ã¢Wæ`­¢H_'uJþi´7÷Ð!H=�¿¨ÈvÍîblFó÷ù´¢x (4·s12‡ÒiŠúû&mÑUÞ½=O ?|¤…�Ä®˜oNñù@ÇX‹ Ñl¸Ÿ`|šP k�¾Òš­û˜†ÃÛJåc„è�±DÍ´Ï98!Þ#5^Ç™äÑï1R€Â*z¾�Oª)ö€¹ö19û~§úêr#¤9'=9úh8ï¶\Q�A9ÙŸEr\˱è ~s¹‡Yˆ¾FeXν߇™ëÖd}ÂÇ~Go½ñ>®ó[ÈÇî=Ä×ÎíÑóý7¾µaþhøz›Ì-`h¸•‹RJøòǾó¯}ñå·¿"¢Z’±Trdù@Î]UŸR ×ODȹïùرßo¸ß_°ïwû­³=)‚4ƒ¸�«¯×+Þ}ößúâ[øòÛ_àËûïÞ¾3 ù(5MT�ÁÁä'*àyÎÇQÎUµœgÚ6\/W¤Ä�KÆ}¿—uÁæ1•×2sÿ·móVœÁjÜ)®ª ¼¸q(70À\>ûr½ÖÔ�ÂÉÙÛå‚«äò=²‚ÿ9/€U«V­ZµjÕ*_‹°jÕªU«V­P U†É`VÑK41Tƒ!!·î7—ý~K9r¦²Ñc…"NI­Ñ&¹}lSûÖOhûÏöKoñOοP ¸^ýª-½ êÀó¾e܆7à$d¦W,�Oná„í°·Q-S ¡` HÏŒ=Y·Û[ $r@uoG§ CT²=ÚðÕ1¤™úµÌk„Ap:~P©�¸†�[nŽñ×h=‹nµî7Êå>_cÆ:N2%w8ØËTíQ)¬Ĥq Î>‹:A¢Y{·1s€Ûy9ð…¼º³ŽSYŽ*Ìÿ/{ÿöl[–æ‡A¿oŒ9×ÚûœÌ¬¬¬ª®ªî*µZB-µºu1’-K xÀ/<¼ø�yå߀àÍVØ„�18Ü8Bá+8ì°�$l¶¤î®îºdž³÷šsŽññ0nß7.s­“Y­K2¾î¬sÎÞkÍ5ç¸Í¹Æï¦[Їk*J/ç-P‘4˜Pò“}ârˆ ‘¹õIMÝXº'ÂMðåZ‹Å@­�dâÆ?£àn4$St?¡"eH,3l—§u)1µ°ƒùŒ×)i µrWè©+°§†ïEŒHç Ó R Ågßú Ÿ~óS\ׇ۱߀û#àãœq =‘áØxŸý—ëožßàéú2çÌ«�s#¸$2�1—uŲ,°v‰±á59â-þéDBrI„FïLx�ã<ÓšC†`ãõë�ůðì±ÆcË6ž5kÖ¬Y³fÍšjfÍš5kÖ¬Y‚Ò>(Õ)˜­ü½¥8ªÎ»–⪠Dá9ìˆ+ʈ Ä Ú@ðÂz”" ”¬½ &3Á)«;MÜe6rv²8wè ¾`ÇœŽ'ò¶U|@Ú¸4Àô•œßCµÛsÞ0$J6´µò´Ójqƒ™Y(˜S[CfÊÊV‘ ·Î|ܽM±j«ß´?‹-Sõj¿¯Q©hÃ#Ø‚re«ìÑR'«\ÿõFw±£ïYŠ�Ç*Z§ß¬:UŠI_Tåj½›¡ÜéÜ<Î;úYæô@)†×µI»>††f’z™ˆì½¢Š„qÍA§ÏÔ›UÖsjwyö¨l”5I‡À•k�˜ Äœ„­’�^”ç:†+u¹4ëÐË <«¨E8i@ð¬Fñ¥΃/„;7Zõg/¿›¢yˆÌ÷Ö(¶t.À òçÓ�Øÿsƒ’r?:@‚ÿò/Ü1§²V¨†vpˆ¸Êž V€¥´zùõ5I…ï·•ÊÏ‘à(U8Muè­‰ŠâÓ®4•ûØ�„ÊzÝ@à…1@¢›.ýž;�.kÎWRewKéþÀ&ÞëʺžæÖ½hއžqÔ5ÐùM¸?sD“¹Zƒ qßV„­ç<-�‰ÒŽ‘gßÞÉûÁ<ÙµA=5ň‡gÆÝiQbæ=îOšälCñ¹ÁëQLUn»x¶ð,È�ÜɤgV3�¸�ÒBî«x‚†ìZÙã'à”¡³¸<ĉó”µîêÞ�ÎÆëÿÑÏG£�Û'X~ïsøÈ2õ:Ï‚äÔŽ©Gf1ã÷«FíÓ>SΚ'"¼}ûÑ¿úÙgßú€÷Ì|óÞûÃ9¸Ãá8‚ªÞ'ez\ۉƚ@¾ŽŸë\±� óÅ k,¼axvù»WZd v±xz~ÂÇßøŸ}û3|ç;¿€oç3¼yûˆ·°o[PÈ{öáYØ�H é;’÷G˜KÆ`]W<]ŸñöÍ[\¯O ~ïì‡Ån ŒµX@0†`í‚u½`Y—cT­²¸5mŠžý´ü�z€Rcn­ûnœùÚ*ˆÑœ-PZ™ ß�écV§Ð³ã•‰@¢AhˆŒvé‚PÙ³wœt¹Ó°Òúº`‰¾é‡Ð|&…h´v¾rÓ“úX·Î±æó)½:†“Ú½‚¸š=L  g&5ž¸c‰­ Å^[çyk°^92t1èž\ï‘ükñ^< ¦`ÝÜ`DÜÌ jHTõQ&)egGR@& ô‘¤ý�¡sÑ’(@=Ç�ä²Rz<Ÿ{‹áIYÅ� ÜÏi ½ëèd¦sÙù¬M¼2Cú(9b�´[@$ö�@˜Ç‰ÖIÑ_Ea„9þ½rŸéŽ0jç&£% tÛG�ÿ&nE5]²Õ©½Ïa‰€Á«ÐSÜÝC“I¨‚#¸Í @›–°º&"F½ô©¦š˜ Ò±ˆÔ�gLD¤?>œ�û§Å{��^Ý>Õšrºþ¤>'ýœÂ|ÒSÜ»ÓS; èƒ:~ðÆ6‚‰AÞ”5GZ, uM óL¸i ¯u#ÑD4.ýŸŸáŒ¸‹WŠtÖŸ=ÀuÐ!| D"qz®|Ý‹ @o«»”x�¼? (NºŒ²E5$§­tÞ÷hâ£zî͸§‡Øé׊4ø¹Y_>´~Àÿ>(=&ì&%{´òßþÄŸþ'þ7Áž_œó›wÎïÛ�}ß±ï;¼sÙÑÅZ‹u]±^®¸¬+Œ18âï½÷�,àYz]VðÅ�¬Å‘�“”÷v1¸^ŸðñÇãÛßþ¾÷½ïáû¿ô]|ã“Oa‹í¶aÛ©`ÛwìÛB XÏùsˆ(»|¬1Á^ÿú„ëõ —Ë3œw ²jðßâr¹âr½`±a‹ùp;\$Ooû�cß³c“ïÆ,0†µÛL$&ìÛŽÍÞà=¢„Üáà�ÏÎ0680ï±ûü&?kÖ¬Y³fÍš%jfÍš5kÖ¬Y¹(âR·×íùñ÷Ô:Éb©šþ•þR6][«óRFZ·ƒ@ÌB(?�*ü¢Þ%EvààA]ì]3€œì§…íiܬôù¸Q’5@ˆÌ�—§Ñ£ŸÍ>G¨:Uv^[g×ç\áF ŽJ¤ñ‡d¼²‚C¹uGd…Ô};ò<†z×G’D¢-qË%‘Î�Áÿ¢Ò ë>k(«+éå@³¶yÎ@p­Ô&zHa*�ƒ³È…¬ì¬À1ÕhiÒ×Lmž7K5ò(ÁÇ¿’ùÒõÀ#å Ý=Ü8~÷îÏ2Dp…Hˆ˜4d£’R S÷sQ@�rôûèøT÷\Ý^q-ÎQF¸=_t¹p‹é˜UÓ\ Çe°& d›l<xžÄȘEzIà¿ î3‚ÑØ“÷ *ÎnÙâ;fçÿíÄŽt ±‹Eú— ¸]xõMeŒ*ë‰ÁZÔ:+`°öÊÈ�ø¯FõÃ@o^u×-}�ET-ìï«ÁOÝ ‘,þEŽ9UÊ}:} <ÊŸ-Ä×½±ÜÂÛtÞ®Ê#¿o­>&ÓÉÏ«Ü+øÎ<º;ó¸N!ê,§ÜºÍbŒÅ(—r¾m+ž -RÄR¨¾ë%X®ƒ]Ÿ9�:È„EVLLá˜ÄR�éó-R?‘®»Ì¯î¬¢:ªçƒ!C–»ã¥½u·khcÙÏíØù�éÞyIGƒoûÝ›\&c𣲿OßmP9õWœ‘tl™Ï óóó›¿þÃ_þCÿ5ï™q;¼?öýàmß°í;Üá2ðmì‚Ëå‚ëÓžŸž°,q;vcÜÀðî€Ûw8wD°ë‚‹y‚õn±‘Lpß3"\®¼ýè#|ç;Ÿá—~éûøÁ¿�oç[¸^.8ö¯·Û¾aÛ6ì·WìûcL¾é{vá¼2™X¬YC‹10Α}ˆnN{¤<ÍôÉüÏ›|9Ö—|ôÑÆnÂäžD<͸م¤è Ðxp«°O½Ê Wþ�̽g™/-ó‘ågKÀúÌ0zlÏV×£«›"MÔy�FêóF=Wj¼ä‘ßÚ‹àœ]Kç‚xä·�b"q¦VíJý4Jö2:Îï÷œsUö¹œpçJºÔzD9JR,1µ}1ušâÁ±pïÔzpÒ<Ýlú¤�„»5öëutFO F Ú°HèŽ2{ ª;¿Š€àªÇIÌÑ´Ö2uF¥´wÏM®¿£Þ`±Ng|\�£ÂeIÕz§ó\åÎh–Ä1gI8äpmîÎIâ¶›+©ÖEp ê„Üa›kãsõÎ' †¤^3™hp=èYÇ£í›Úê„kØ�A …yÒ� ~À ä:­×;9GÅõ¢^ZDD õ×õ.¢G)ÆCŒõ¬,MçeR[ ðÈþni ÷Ÿ ¸¬1‘D=ÿþ!3èl�£ÁóZ �ù1!¹W0ç(›0ÅäƒÝ¸i—”î±ÒµPuŸ‘ÞH’äª1N̨˜ÝaØ8øäáÎí]›GkCÛ·ÒŽ?G&Iù½P±ÄówVÔÊæ¾ÓÀ‡£ó×!ƒžb†Ï3 tnë÷îÖÌü¡1ÿ£Ä�ÇΙïºð“>ø9V?‹'応gßÿ¥þï™ù�sþ¶»ÃûÁû¶áظ¨æ'C ÅðÿùÏÏÏxº>Á.îpØ÷Û¾á¶o‘4À°Æ`]®ðìá–Ëbá"Àƒç·Ïøæ§ßÄw¿÷]üâ~€_ø…oãÍGoÀìqÛÂq·Û ¯¯¯Ø¶ Î9có<$ ÷ÆçuÖ“��1[Î1öã3ãpn·¶möÝp;\t0Æb±Ð_¬ÁáÒð8œƒs;Žxkk-Œ þ‰HQ»£¤1Ú1Fny.L&ßÇÓÝÎ{ŸãfÍš5kÖ¬Y³f…š€Y³fÍš5k€¼©H ¦ý¸]ÃOȘÕNZåLµ¡.ë Y’j®ôK&àŒ„Ô ™–2 ÜÍ–êVÎùÆQ‘�|D;Êz£IÙ‘grs H· ˆJ•SnÈÊ(ö|Ó¿X“Ó J£I²Ý”•@ù|my[«á”4�ÉÝêØGC¨¢e�©�­qvp–à�gPÔþPc´=·Ágv¤’ €è[Vw²Ü3XfÐbfTõ›DË+ « ªV£»w¤-åå<ޝçtM€¼:@ZÓ$-([ÎC*¹K{�D¯š„À4ÒÚ´îÊæ‚z .€µºîp!-/è¨é©ZÙtœƒX3Rב8Lœç5óXU¨f)—µKÚþƒNW®¹t'Eú 0OçÎ:.#)j‡E ë|¢ȵ’¿ aѶt>5¶jcîIS©]7kМ‘¬›C=šïò˜È2ßW¡ Ôûjxjæ²úÌî:ÞŸ4êVÓQ¼ËwQÊp6Ò´óIO%,¹DÔ¨sÜ«¡Ô�ôÙA “EHÏå|¿iWŠ7d&hòÇë¥èO¬žQ¸ºðéÝŠšÿmÛ‹ iOõMÝI$€t½^vÇ#Óùh% H5bì 2]SO†Mä/�RÚ …ª�-wFfÎ='Ed+v)-o‹ÔÓ€; µv3ŠUJú$®ú6»ƒ@ØÞÇ1D$žÓ˜d.¤ÖL2ª OTH�]ÿù:ÓO‰��>¤Gn”}‹áïÚe–î½öÁuïKù}¨&A‚Fϳý ÀrR©ðyY–ÿüÏþ¹¿ð7ï^Øñ±ï‡?Ž`ýìG°ª`Èಮxz~›çg¼yûO—§à¸F7àØ�Ûlú�c‡÷€µ˲ÂXשׂÅqëjñÉ'Ÿà;ßý¾ÿýïáÛßþÞ|ôŒ!l·Ûí†=öû~þï`ïÁ€íìÃÅû@¨60ð&/»E€ï~÷»óKý ~ë·~k6¬Y³fÍšõÿg5 ³fÍš5kÖ,R%Çä½³ê—yÿÚ4ÙÖ xm*ªL˜�â–å^ªÄf(rñP xí2�lç³¥|¶ÅN!-þ6»PÀö¬Àÿâ‰Ø¡L & ºKyaMÛqx—Ä u,öÓ3ùNÎl_©[ üë�ÿ*ËVôÛÃJ¬p+­ŒYdv3�®S’Äŧ¡àõ´Ð™ÊF¹OôÇt'ž Ú„�1ó`/¸Ê/Ž™å¦Ð6ØÝÏ«{ƒMèü'å–Ñï— Öß¹&êªÙxD]X¹7òz‘‘bApÐ/ã{D�îèî» ´DŠœýUc-ô_ýu0¶ÜÂ}ÇeÀ½…Aœi­â½c¹ß¥ä|åúE#Sñ¶÷Z®·Nß*×¼\©t&`´à=LŒt%!…ú§.!ÇÊ&¼Ê$ï^ŸŒVà*£—�r66Ïr½i¸nò`-¯ú÷ ø?šLmDNK«Ó}ÛôFmOwU³™€¾�Ç8Céî«£Õåkózé²Aqr¥Ð§ çMƒ¾áºÑùJU÷{ýrÍ’ö.  “¤Æ>‹û* £KjO¦L¬Sh¢F÷–öU¬ìšªî)äOq%Áá© yRÞíúÙ†’ÓJ�ÿ¡¥:oÚk˜šd©âä½Q‚éÙÃÂRŠó3åÉéÅýtÀú30\?ëÉçkÞM{Çcn[D¥¾üò ýøæÖÆ'ÝhšµD¥ɵ®¸JI|¢�²_’¿¤sAaÂô×™6+`°€IÒNïÞ3ˆjL“îŠúH-÷çƒY€ö¨Ðô#=üFiù_®=�æ8þðùµ¿ºïû;·»íp;;wÀ9—�vcBÖýõzÅÓóOOÏx¾^q½,°ÆàpŽcÇëë-ë//Á®ÿöfÀ-; Ûüe]±."¬«Å›·áŸ~†�>þ.ëŽÃáý»÷¸mÞ¿�/¾x�÷/¯Ø·-žO´ê_¬ëëå‰ ÌBaï€Í ý@PàÁŠÛn¸í;Ží€ó.‚õà?œË¤ï=\&\Ëx,ބи� ˆñ+¬µ C`ÏÁ1Àl8`à]øàœÃ±‡þ0žÿ­±�Ph ì®mYìüÚ>kÖ¬Y³fÍš%jfÍš5kÖ¬YuQÇVJœJqIlUçÑlœ©q±N6�‰~æÓ¡3ð/?Œ«nµU›Vç¸êŸqþ¼7nR±´h1é]ò=ÄLr |p�Ñö2Q“Õ¶°"fªÞÚ\áú¢+Ù,x <N•Xño2Óx”h«€ ’ïí .º“�íÃ}×aNP�ã®srƒëü0+ziußÿUÌÅ=•îfxä<ÄŸ4Ê¿ê½B¸OG¯¯ŽSgwó�“:I)k¼3A¿RåéÆýóJð¼nz6ã9µÜ(6ét.êH§z~#{ÉS™Ô86Õ$©t¯oÖŽÁ  :ƒç)µÂ½�Q%€„‚~p�׋Ԧa�÷É“¡;vXD0@9ˆ§³<4Æ=q„çÓß°"µ¦m|?4Þî~6ócöç÷œ~äy·ôh©›ßÆgPp¹\ÿú÷¾÷ƒ¿wlûá½óŸWÉ– ƒÅZ¬ë‚ëó®— ÖËTóìá� ÛëK°Õÿ///x½½"Àë{xϰրÙ�Èã op}ºb½¬x~~ƒ�?þ>þøS\/Opx}¹á8Ün¯xÿþïß¿ÃëˆÃùp.답¸\Ÿðôtź€sÎyì8àû[§Î¯ x·GU¾³ÏÜhŸâŽûvÀ.6ÇydŒ…µ ŒMÎ ïC»K0f,‚3ÁN6¸Ã8âwÇø\’TC°váâ.×'\®—ù-~Ö¬Y³fÍš5KÔ$Ìš5kÖ¬Y³BeÇX†;¶¸ƒ¢7M¥r“«ŒhfnN«¡*‡»8ÞD-ÿÛÏÌm²Î‹Ê>o`²<ד�rÅf �ÏÌ}�œ™ªMrnœ’»[× —á¬Ê©`(Å4× ã€5²w…z¯Š0h©ŽÅ  w€l àDÒ{·B»xxöÑú¿Ê&£l÷UÛTêåtV-ÄDwEœúª^i*{üºÙk£ïz®ÄÖ×RråÛ¶§îØ&æ¡…oïóKêABAo3|ðÂîeIkoýê·å�Xý�¤`O`ÕíGrÂê,e†*Påü kQ¼´Ž³%Rsw-«ç+QZ‡ŸÀ»á5ËñNš¾Ó]K›á#"Èž-­¹8p€<à `| PëVÁ•QDpë…]Þ;²5¹geÑÝ?ßóÃ2ƒQÝô�´8ßHûøóAW߯:Rxé�“ã#¨"¨îT¸>´çÀ§­sL>´H‡qž�ŒÌõ¡á9+óõhÇÏ4&°% žEÌî ƒº«ò:ÕëB¥t.1’DÂèGw@F' AɸGË« + ¢c¿G�OŠD <1 L$”ç»àn# v…E ujx¢b(˜¿ÑçQ»YTñ3Í Ç®[ªþ¹ö#¯†Mý–?'9¤¿wîNÜÅÓ³@&3ÿs1vhàCrr¿d>¿ÏqûsIf83æIÏŸu{õ\Tôš~�"E÷ñÿŸK¾jñ�¦î›%e:{?øêPh}ôñ¿vÛ ÀÀÖ&ªí »`½®xº^°®+,Q×}ˆ xÿþ=¾øü ¼ÿ^_Þc¿Ý°o!À.|7òD c,.×+ÖåŠ7Ïáã�?Åó›�°Ø+د· ¯·W¼¼¼àåå·×Žc‡÷œ•ÿ—ëO×+.—+ÖËÖÚ â?l[°ûßx‡w Då?ÈÃb‰c‹A cÃ÷/&xÇpÎÃÛ¾cñ%^$¨û-–åIéšîp8ŽÇ~`_ca @þ´–±òŠÃ0ÖÆßGc`¬�µvY`¬�ãú´áryšßçgÍš5kÖ¬Y³DMÀ¬Y³fÍš5«°Ìyo¹V àŠ²º\¼Š¡Ôl9Üm¾'�äþ­pTškC€­ 0J§áQ‹¨´,Ñ„�\’›Í5ˆl=À µÉ©�«Ã‚(ËÕïÃ&‰X餯îçÄ'«Pù³>QJ_e\µgm÷ÚCûîšMgˆŒàìŽ(Χ(m�YYÅŸîKå?û�WŠ’ÞÿQgøž:É>jq]ø¤Ôþ§«Û§d 3šù3Â2óPŒöˆa�ä�œÉ!¶/,À»YÖú\zNÁ�uÆu}^�Ò2šaw§)9‚ê=âeÐ<©2e�rì{pNíΑ3KdÛ•‹„|»ÊÈsª÷¤û™«ë%z°u@µŒZa±.e‹oà Ì—Ú‘zúDµŠDÞŠ §Pëfñ@�V0Ú {åÂPÆ3�«‘šÞ#^Ï�8 Ù­ÔÇþÛÅŽTìŒZËXÛÿ?2¾Ñ¹ªÕ?­$%õ:÷þ¡iÈzE•à:ʤl†@ü»dªg’L”ä6bÎâ��ê~ANévÜêñ [ö cþ IESTqH"êþNù!«CnQó…läMõIÄ�@Þã*²H"Šþ.qNê)Mç¤5B^÷Ÿ^ª)’û‹Îîe,8™ ÄNÌgý¬¥'¯þ{CØ”ñW¤×d_/žÕ$åHšQïb?¼::ŠÑ}Ä…Žà“5½~öì’%ºçAmÇÜ{ö€|ö`ñqNJ�ëþóÈ©6DœüŸ�E|_üñ_ÿ¿I„�@Ž ²ùÉ× »Z¬Ë€÷u…±ç·Ãö}Ãû—¼{÷9^^ÞcÛnØ· ÇqÀ! 4�‡1—ËÌÀõrÅÛ·㣷ŸàùúËz�snێח //7¼¾Ü°ï78Þ»® .×'�]cL´û_ÃïípÝ.¸>]çwùY³fÍš5kÖ,Q“0kÖ¬Y³fÍ€ ¸öžt®©¨F…Y,ô{(B¶`•V¯ì²-Ù4j ¹0v…Tm‡ EATÙr§SU^æ!‹í~N•üO;�,¬¦“(.·û¼!ÞËïMmÜSLú �&!&d´@F»ñ©[m÷(,†ûGƒ$Ôª;ùiµJ’ ß0ÅÛVŠ`2#ð¿¼?ofw€›üw¢S’Àhe;aŒÔ†ìb3]€—ùüdGw»ˆá/+5:U§¨—>ýá%W¶Ê ³¡ÜÅèÊW‡³ðQÂ…¾¦‚ÿïð¸6!®€¤þùJÀ‚Ï_%~miÙ´5c`��¢>n˜Ôí©&—a4§èþ¡“ß¶ g ÂÖlbµ;Ž„¢â¦ê4¥*˜¡ó¬P˜€_V ,rZz$€ÂCz�9ÃèÄ�TD.ùðM¦7Ý�ˆ�m˜½t2ø\ 3¹ê{q¡¦h¤ò¹(­ß,£+šUìþL$gt¼þ è·Ë©<)&Ÿ{m Ÿ™ZUOuŠBo „œõ¬rÍ{åŒ@ÇÃY›k^ÆÉÕ-­A•óP p�@=&XçŸD¨H/I‘T†.šè&/ƒ4©B1_=g‹{Y‡Ôäåh“ט?“˜¼Äiòçý§=ÔÄni¬Œ*6åžÊšÅðåÉ‚$i]’+7wZ®} Ο=˜ï=äÍýA6WçÇ|zé­ËÁCˆº~âb>‹dzà¹ëË~�¹{¾"® Dtùy.•gþËåòûì[ßþ©!»‘ÜEŒ5Xl±—%Øþ3€cÿ¶mØöÞ¿{�Ûë ömƒ;ŽèT“HTˆQÎíðÞa1×§7xûöc¼yó®Oo°X _‡˜²•¿s.>K§ë 6üËrÁzYqY/xzz²Z„c9B4�÷Ñ5Àá8‚µ¿÷áxdH´“QÄIï=ö}ÎÎFg�ÐfÖ.¸¬eÜ ß…ÏØlv‡1 ÈÄUya[È^ÁE`�_\vƤ† ìj£ €ÅŠ5Öù…~Ö¬Y³fÍš5KÔ$Ìš5kÖ¬Y³ì]Ü3ÄÜQÅ’Y¿rsUæ\7°süeÈt vÚ0NjD µ.§ "ɱÜ(6×¾ÞË¥*VY*ú†–èHQ)Óä*‘)þÑ2g¾ñ<(ÁÝ”mY¹#†m3û¼YËùIàÚ,kÏÚ¬Ú·MݦS§Öb?Ozc¾Sõµ”׿‘×Éò;Y®‡_2QLhàߥ þY¶ìGQ÷To#…¡4PîZ¯”r·üJt‚BƒâÁuÔ}{ï]íâ¼ç†çÁrOºéO�_~~Ä<ÀÂ+°™Z¥~äŽ?”¨ÇIâáñi×d{ݘPP³Ë‡�:¨Ä©P6oi�ÿÚzŸ‹]z¿9›KiLH÷gÖÂSëPÞÆÅî-�\Ûn•µ¿¸³`�tEŒt îÎÄ¢¤ óBvò‰t¦|{ê9ÚœÚ^ %:W«HºiyŒ¾s‚PÅçS"t Fhï-½ܵèç;KEuPi(ÐW±÷ïEhº@@³’0 æ‘$PüÐ á‘UñüÅeùÃG©Ÿ:dž‚WÀ¬¾wS·_Œ½5r]Í+åBÒs@‰n!ádB½ûÝ9ÛDraŸŸÕdü‚�É„ §ÜoÏAjõ[ÜlÌßÜÏÕóK"|öŸ+{w™ùDyÝf>¹w'6÷ïs\Ñõª£¸¹¦ñ³Ñ—žA÷îV|©ï.݇i>]2é¶ãD�:’ƒ 5R¾øô›ŸýóožŸ_Œ1;ÀŽ™Ù‹5›ÈÀk(ö�‡?|°»ßo¸Ý^q»Ý°mçÀÌáõË‚e]±GüŽãÀm¬ëŠËõŠç§7x~~ƒ§ç7xzz äV¬KÀ�¹Á�á(–% €ê6Zó[c`ŒpÎáØœ;ày{†g�ÆM™Y†`8óÄáã l;–¥�Œ!XkÕXÝ·Ç¢¾œóØ·†ná{”g¬—ë²æû¸5Áæß:¯æ‘],Œ50¦Ä2ÀÌïò³fÍš5kÖ¬YuMÀ¬Y³fÍš5 à3Èà‚; Áz½Ë¯UDƒM·ÔÈükl6Y(~ež:™¬úJŸM2g6îŒ3k5$Çl[b ²OÊmiÃ/7{å&kÇQ }N²n�›àI‘ž�ÂÂ`p¾ôl‘¹Ût>gÉŠ\Y”s)½Që»úvåE¡÷øf®á’´Œú  ÿÑ^qeñÈb¤%»}“@‚R|þú𢾻mÙÉBY¥�î·]‹Xr¯AÐÑ•º@2Åó:mÍñ¹ž÷Qÿ€FLÚM�†J]î¬pŠÈê¼|®™²z\¬{imj>¯»BJ…(דb=¯Aaâè9jJ㘩à$“oÀ'} –,B7„ªè„J©Î3á;'.ÀbÒ¹ Ê“ät¨rÕ$ÖZA:�¡4 ØïWЏâpH²1ð ,Ò࿲ùÏ2}Ð ,:>mý±_9¤çø@[š×ŠåžIg=U×ÈmLEä9ß‹»AìípãhœÇ•bð´~5 î’ÊÚë“�X!;7Ñ0½Ð�‡–TjÇ™|žJÑ9åà$#g@þ"ur’$P¢i@�Ý-ò3D0Ê]‡Ôz)úˆud‹gjŸ¨ZB’ŒNê©ëQˆâú••= 2‡R’Wë]iLABä~ï÷ZïpŸ×�& ?Ó»$ÈûþüC^�Þi>àÙ�š�k ‡œ ’…ßZ‹cßà} <¿y‹7oÞâÍ󞞟ðôô„ËzÁårÉsãr\qÙo¸îâ'òuˆN—0ï EpÝu?—ãÀeßq8ïáàâšì³¢ŸˆšÃäógöpGqQ –%œ›1&¾'ü™Úþ8˜Ž£ÌÞä6ோ]2¸Ÿ,ÿÓÜI. 阹o½ÿ 1U³fÍš5kÖ¬Y_Ïš€Y³fÍš5kV.®”Ì=KxÆXIHKè¢ ÇtAÕÈ^¨KMÇV¾¨‘¹ÙÔ ¬éØD•(ª§NÅMP –«˜eÔ›Fmþ´´è¥j3?l¾š`Qì+PŸð,”’=°LÚâÖØü¢³L×&—ZÊñέïuÚ9+G‡‡2çÛƒu Ùn5¢1…èPâ20jH¨ÛcI÷èß—êÿu¾C+ê¤ÔüùýÞ�¬@߳ל_à#ŸòeïK¾›¾Ä;5†¸ýÁ÷‚¯¶kÜq‡¨AqËÜ üSy“öì*—»VØŠX¦n.=…Þ!™ãÍú]rUJ€‘½¨j#æ®UýèÖͽ¶£4ïËtÌ@ÕÇiŒÇóa¦LþÉÄJˆ˜H+§D]ðq�óây¨ÿ åÆ#é‘âÜ¿b– <÷sÃ{í†R¯ܱő.Ù âdˆñƒ8òu­!ß�ÿuìÈÄéM¾ÿçõÈõÐlë¶Ë1§¹1�©è#¬G“1†èó·o?úçÿ›ÿäŸû_}ÿ{¿ô£Ëåú~½¬;�üq€‰=“£îYyFŸsû‘€øw"¬vžßÀÚ×ËŠççg¼¾¾`ß÷à`,žŸŸñÉ7>Å›·ãézÁ²XK™ÔrƒË²b[/X/;Žc�ó̇s0ûŽýXᎣ½3’�¡à°. –eÅê‚g/ˆ”eÞŒ $ï½zvÀ}˜óv1L~MŠù ` '$G€euÙ)ޝ kmp3 ÀX‚e#b&Jþ™‡?ÂwLïç—ùY³fÍš5kÖ,Q“0kÖ¬Y³fÍŠ5Þ~ëø!L�3h/7îYÚO‚‹mT•’2Y—è‰�ºð§ï(|R–nú9g[~ TQÌ€7{aÿ™lçåõy‘å. E…z´¨DÞTVʲ¢’몤TÔõØ’™ÏÐÝ{àÆi õñ�ÈYê\¯úxå"O|Çɰ2Ö (>I¨2Mm_Ük0``­ßQcfëÝ{u¾ýÌ\+"¥]zujwŽGJ .›ðT«9 §zzz ‘ü±ñÓO ,>ùäÚ©—z='” x°ÇèìüšqØ»|>ñ�ÄBÈyÀ½ó¯ÏÊr—fŠzVY�´›Èy·PœkK?#°gøqý¶|~TÍ–$!Ö*W® >%täþ“l.i•^Ù1÷â0ˆÇm�ºÄz×m‡†ÜÓÎ1íÎr¾ Swåmçx‰Hè§ÔMsç–=˜áÜÜÅë6£ɉgüɯ¨ øïûë¸;_glòÎéN#qmkt~èžé�.ø,$‡´cA/.ã1Û‚ÿ¥xÏíÍ '‚ñB(Ðc÷‹2~#aH*eß*Ç“ø\ÂR9/ZJο´~pÌá¸æ ÀsçaGö0¿ºWp�\Æc/‡ä|Uy<7î=‹4·a™ÒȆƒj êß+ÇD'ú0ªËù ûçPÀ~~`~òø ™Èò�Oóý‘?ú¿üÎ/|÷?}ûöãß[.뫵v7d\P�ìÎ;¸ >3,å}ø¯¸k–e-+®ìþ½spÇ�mßq˜=Œ1¸^¯x~óÞ~ò.—kX5ùÀ¾o°¦¸c­ým°ß‚ûÁ¹=¸ø@>ð.€îÞ‡1Ÿz"ŠñÌ —GB¤�l× Ö‹ËŸ‘¡H 0ð&œGx�ƒ; ¼7áïî€÷NÄÄ…º\/€Uý¡FžçB>H×�ÚbÖ¬Y³fÍš5kV¨I˜5kÖ¬Y³fˆ,¢^…°”%@&6•%h@ #‚Ì«åî.åïÉVA5/¶ãrl@´ºf¢þµ›z¢bãÙ€µm&s½w”ö”�gX‡7vß$ˆW@«A Àp#8Å ` „|\?¨ †:78+óJ¿–¼·éÆÍ¥ "¸RWB)‰Ì<Á‡¹ÕWcµ7Ž«Qp·²EtV>ò(qáöWýG6E÷ç¹å,®­±d¦á§×Gè~"Ÿ¾jp޲õ¥4Xúê¢GE¡ûô; ?H¸‹Î;…GŽt‚OˆÖ#�SõRHüCžª( ”¹ùl©Ó3¹I[ʈŒAèw;u/‘ð€Õ4´�|iRª°é¶7O‰8y�Ž÷–^$α^äÕjýØð<›·¬ûNûy b7Mé­òÕÉÜô?uÞúÉ‚Ó#îu�.H¯/,“:«±Úz­`Õ.Ź@�G�RÀÿªs–}™}Ô¬gܬ�� úÉ8(nA\w{¹ jn1wˆ m óƒu¶÷y]€^€æCg¢¡SwŠç⺠žÝ:÷I/_#ý5‘âœMñ ¢©ŠBë<÷æ² ¦È�,Ïq¤H Ôt»Îîµ×ç˶b½îäE�ÿèûõÿõåý[úÿ¬ëúãu]^­1;�œwAÕöýÀî¼ó0–`(€ò̦�ª8|-Ÿf±,&í+–5€öãÏœwp‡#’*Y¯°«…ó·× ~ñÁI�wDð›Õ÷ö!z�ˆà—�vïƒ#�ñA�ì… €ûËoâ:Pz£¨ù}þ¬p½!þ@ªô­±0ÆÀÂÂ��[œ[`—ιì�®½Ä h‹ÿÞÜòÞÃS<<3fÍš5kÖ¬Y³TMÀ¬Y³fÍš5 `Œ3s8M”‚ ƒ0„ýrúAù˜#ma%¨VBªU†|ÿ!Áÿ®u|ù e•?96qf©Q禼iŸ²£YìNK«vö��#­Û@?)ÜVoÿë�ÓæXÜndùÑÆqQ"�u}Àæk×ÉWY‹`›«Ø…ÇM Ï`SÎåÜ3B(þ•ò¿:PT+Q{æúʪúõúsÏ åy$êöѽÞþ¬§}Ö¹çèEC ² ?Ô±2»šøL-;`4¨ó£#i¤ñ¯.ð_pú’oDD‰z†‰_v廵püÔ€�îi¬ü«‹åv­c:§$£qxâÃÞ!ôç1£GáS� ©Ï§�,c\¨îèεE1ƒ}™÷ÅÚ- šã*¡žÂ4Z¸ž™Õ½®úsYOøÌ»×Q4ŒÒé´*óW´Š—,Õϳۺ¾Ï…ׯxo0h7Œ^Àÿ¤É2€& �sê¹7y¸dQï^˧>¹=ð¿~RPnD”¯°wTͦ|Ly6T…›ôÎÄ—  Ï$÷Òÿ�ЀÂÌ:Ö†9s­Õš�TÍËD€L1OíÚj@êy2:ÕL¯žøàädÈÁÇèŠÏUL¬îº%=ƒÇ÷÷êù@Þ#¸ûì0~ïè–ÉK¨9ü Åÿ‰DžK|2n4ÐàŽûQßíøùãÿåîE’�:WîåuUÌ£´‚í�Ÿ~ó³ÿð¿ñGíoð÷Aø½u½¼_ír€¬sžÁþÀqlضÛ¶áð.ÉÀƒ%‘q(ă‘ÑV† €îu½âéù‚§ëËeź,ùY˜³›E8/ç9_ض ûq`1Kv`òÞc?6Ç�ÃI ¿(òe;yö!ŽÀ~8¢ëÀ~ìðŽAd`íc¸ÿ]Óæ•øD ï-\üÌæÛ¥Èøíba�¥øK,€ƒ9Q ü� )—`çá8rñ¼<ÜÿgÍš5kÖ¬Y³šš€Y³fÍš5kdÕ3ñz¹¼ekºëð]ÉÒØ®�ñdz€8*b�v¨Õ¦~±yª„é <*@Pº•¼í6‚V«yŠ‚�;Ö½ÜÙèg}<á@ Þ¥ÛãÌ9˜©Ù}d>cIä¹&耚N"~n¥Î–ðBüL æ„èb‚7ã ù tçÓ„©kÇšTÿz#*\‚rvn>IH‘´…u~Um�Êf¹Òj+9«rIhË{JÈÖÚyú«!Z œ÷|ÎO¿#z›— þjãª÷‰••¸²ƒæÓw#)Jï^°Î©g*£A_ø™/7÷½s¢Zî3çÊ×*V®×‘\±XÝà“bú1©ÿ®±~¦ßÐýÈ®é2B]ο?@Ç) †FúsjÆ$×*üf-ï¯ðò*4'ÖéÅ ƒN/òœÄÍœÜu{n1Yú]ˆ¨ÌŸ^—W÷vi{Ÿï ô5¬s\9-�¼£·Ï+Œvµ‹Ú8 C Ò¾üÉò�ù< �ª¬9‰,jÀð orâY£�2²sHg|4äA|hú`° sµ´Iq<�/gJáN�á-sÀ×ü·ã¬ÏU£ÑE>¶>ÐýYóðý°y¼èµqŠé·Š:§æäî0¸ÓŸñ/ßýî÷þõüðü§Þû¿ï½ÿ™÷þuYW¿¬ Þ�Úe°ܶ°‹ÅbØ%üg(dÝfªw2y^X20¬ñ‰,,- O‘S Fˆð8v”ú.¨ã]VÄ@ô·¬þ—ó7ýîÇØö ÛmÃqÒ€ó‹µ9ž@*ø“J?¯-žsl€\o2€çô…AÙû\wïq8R*€üþ…äHÍ-cìüB?kÖ¬Y³fÍš%jfÍš5kÖ¬YcMØLõëå²g`(B4ÈÎ-jþò÷¤âJ ½!€ÙŒÜ �r@&Jž´ø$Ú•|Ý¢ ”v»áåB_7ÛÃ9 qq'þt£Pî[*³i�Š©nz-)Ã_ÊÖþóà“ä�I€_ ‰äÚY!©z9oà'«W™¼Ô8EÉCÑ�!¤… R­ÀŒVÃì…ò0}†ˆèe¡ãN¿Pïå$ÔPý–èãZœ°Î‡oÜ>¼ékç‚ú…�~°/Ýï|��ªâèÃN²8,P´¬4Òyœ9\ðï=û÷ý–©[™“¢<Ž/e¯�ª êÉÖZæGš�[S›O^g­ŸH–ʺŒ¥/ §õž)«™ÁÖ?g#E7E!Ôw§…Ñà{Q í*Ücô$ÍsŠaeO FžÆâ=#[é‚j¢§´V#‰¹¸|X;k¥|êìÁ_¶‹Å)‘€4˜Hõûë±ËÖé½F“ó%è'ç˜×.ê�nÒ1|ç$ø>Ýèܽ—Z^‘¢î3ù€ó=N®Ëy>ÐCG*@9÷å§&(ÒDx-B“!Àˆ5wÞ-¬ü³Š¤“Ëg·4ÖY<',ÎxÀ0û '{t£œjWíGÀ\‘$ù¼÷›´™žý?Kb„XojÅêÔÞ †™öüøý¯,ÜœëÈdø,ÅõèëjïÎßqjh©O<|Ò(�D�þ!0Õ÷}?ïÆNUî ÒYaY–ßùKÿ½ÿþ¿HD¿MD?%¢"r˲bYd7.ϰÎÚ° ÀbY,ÖuŲ®X— Ìb’GyùPpYµï`Ì0`–ð‰]xövÇ�í8‚ÀqÀçqx´™÷ÉF_‚ÿpO¯€ýرÝ6Ün¯Øöàn±¸^.�Ð Ògyïá"Á Ë{cŒš[Þy8ï`¼ bÞ+'k-¼õêœ$A��Ç!~F¦¸¬Ë’Éé÷&’ fÍš5kÖ¬Y³f•š€Y³fÍš5kd[}€ØÚõHÀDPjk{g/ðÚÖåubÓ=Ùö·?oU€ÃÍN©[Ï–þÂ&ÞGfAG©M¨ö=)€ø/(V®I�ÆÙòº.Vÿ#fBüMÂå °Ú�Vê*%ëÏãfƒU¶Ñ‡è²ek«¼y¡(LÄÙOáß¾D0€ Ù@àÈûË)2À‹÷1ƒ°/7D�nïqÐàßZÞN£—F;vJø’´ … õA¢³$íîo©ï@g¸|n.¯¬ã(O_¦OÆ.=ìxÐ9¿nOÑÉ(©äò5Ô¬K½£hð†>xvµmŽQÀ]½_ªì•Ýý—ö[æ‡.ƒko†Ìjëù¸Æ¥u£…H�,ú}UªK‰wA±õÖo‰dƒÂ®„%[oý’UˆŠÚPà©tdid¶#—®Ö|ô¤Á�5>{yiÛ·d ÖLb…ƒð¿š8»+¨òË={ôF‹p—èÚAT»ý”·xˆ{nײˆp'«¡ù�ФåZÑ'µéeKºypc;Ãb(•Q�n±Ùî»×gUl³äýñ`}¥v”qM½Fàòy�Ï.u,V>—î󕎬`>yîŽðWþð_¹^¯�¿ÇŒÏ™±yÏÞ*ÄUC` ¬‹ØãÎôX‹uYaí c-,™ü�)Nž—œí÷‰lЭ™8f� º;pD@ÿðÞ‡çkï[û} Øä§k7Âf?ýçÙg@>©í“#@zßá¬u`^*{þüKå¯ÿ“c@ê �Çb-pŒ+® ò½Î‡ëO• °XÏǨëMn³fÍš5kÖ¬Y³BMÀ¬Y³fÍš5 €T©3?=?½„¿ÊÄ5¿„K]¯çh¥,²`kÄ�ðÃV¹åý,›•ÔR=ùßð*Ç.—PþôbÃYmôLþˆhK_)çIìbû® ‹;Öá4Ü0å^»‰¿òÉÆíxSXëz�PáatªÉù )€’cƈèó¤Z•àê��� 2ƒ­eVvÝÌcÐFëßy�‡ÌwÛÿ.T÷Îc“©Î6n7§éþ!xyö†³ë×s±7ÆŠB¯p¨\W'ôUlÇù.GÕßz³¥]»:m{âù�ç'qå6Ò?^ý÷QÿËé™3ÀU×s˜"€ ­Îý*’ý»+@oa-ÈÚjEÐS̳¯Î‚”ÃzÇkè":üƒ› �×=º®¼ôK–ŒÈ‹fq/Òq'SФ}º°!'nñpÂé¨nO\¬ÛÜnÿìÂvȶ鵺¸‰ÐÙÔdgËq ²¹ XGj0:ç{]c—Ó²f’s4—Åi¸œäûsoýº¿Œh:ø<:Ú °wIºã»Ë#gÂR³>%Ð,6¨²¿W¢3–*÷á®”# ÀJµ;²ñužsâ³��Q>ëLÕåÞæ¦ÏÃçÀx�7�0dì=^^ߥ°ã¬]$'iˆ:ëN&B åÌ17êvé"3鉤ã•ì#ÎË ¶¿' ®Ÿg*y¬ÃÚ©ƒëiÞ¬‹½Èù¬uþ§KU57û�¤tú@E§w/>¹OÉï.õÉÕDy]í÷fÆóó›¿ýçþüë7�;~¦Ÿzö7ç¼_. gR (&_pÝZ“�€oclrD€ó‡;€Ïá¿ðÂv`¼âp6ºiEÐYìçÒy±Äõä&O½�¡š Õr\f)fã:/%[W½±ìAæÍS�¯Uœ$¡êl²•‰”:3Ÿ£:v9om­œ.°¯Ôç‰Pí ¶CYjȨ:»U ðŠk-x» À4ç{Rzkt ðü�›Œ†@›�B�'ÛX‹k©óó"Ñ&>S�éìa¾×>q4Øq�—\§SôTs4œdª{uú¸ˆNúìþdþÒU'ºË˜�û¶ót÷Lxdµpïü»¶× £¸þÚæø‘ùro¢>Ю¬•èÔ‚õ‚™ú\€U¹ý’2–ùÎZò(QAØ”W¶Ø‰¸�Öyê"ÅM8ªÜ%(¸€Ð�Ñ6¾ _ ÐLaI¢‹´T¦î ’ý&ÝKH­4B‘ßqU÷EµŒ°pÀᆔӬø¯â Äàâìf#ÖCêÍÑúçµÆ™K\EÆÖ)Zïû¬¸ pî·!ôùpì’Q ŒZw 8ÊçûÓÝ•«O$âûÀ?÷Gµj›æY ¬?D_n­EÕÖ< þiœžÚ¼yæ2†•cR;CŠ#IzƉ9Û\�{n×¯Ú $ÆüxpPä‚8H•™ì`LãD‘¯œ�R Ê³%AÙÿ«÷å5Pž.ëè–Ä�{6¤¦z½�ë4�I…2ò‰j«ÿú™Už[~TL™çí³JCî º3ZQyðT*±…(«fJ~‹h’s¦ß‡Í•ñDqí/N 59I;eqcñU;h"â_ýcü/oûökÌç`zy÷úâ×ë ã ·#ðMÂ×"—Áü?Á\ÔùÉÀ'ðß9‡ƒgŽN€gƒcwGTßûh�Ïžs Åû•1dL¼}Q&„û@Tѧóˆ 9WÏG¸7Æ`½¬ðÞÁƒÝY¡o#a€™³3@:®|?sÜ­]`«\òû Õÿ�(°À˜Øâøûq€=+‡�ô^IV�cLp˜5kÖ¬Y³fÍš•kfÍš5kÖ¬Y¡8Ãìá=À3.YÙ(>-\C�•mmÁÜù@¤£É [•W”6œû{®U†+•÷”M\.YÎåZÅÆ1�É·ào>°V‡É ð´a+13ijßàPüXǃßd‚AÇ„V#@èÝ•BZ)¶FH°îOûùÊ^9ø^ÁìåPÒvÔhð�°W¹>é+‘‚žá»Üä%îšl  I(‡{:Ü” _ nmÕM‚y¬­¬gH •ÖVýwT=®†WŠ^5ÿ{ri¨UË�€ÿýPB€Æ` øÊE£é^©½øŸ6þ›ˆ «¼lŒ¤îÑ0©Â¬YZ‘‡)DD…P·¨Z¹X€Ë5žX»Ç|é{•ΞÖã4­ÚC‚ˆ=°¶É‡\Ãê6K}u©ûZa©B9/ÛU(wÚ %!Ù®«¶×L±D£*{<¿ú¤€~h *RH$ 4Î=¬%w§DVZó€>íà™A H~(ó¥wäþ¿2µàê>[U©Z}Å ŠÎç(ß›·DZÙNºç»ô^K(€6‘7KÌ‚W�g­ðìÓFSxpV u3ç�Ïlãøçæ¾[8�Ü%Ò>ƒ�çkPXT‹¼‡+9�îÎt¾6ªÃçgKd’©~’…¾o³x: úɹI÷$õL m÷.�ðMräÓ[Á€X@½u‚Û[¸"ÅT'ß‹;8uø€ç›“gŽ¡Z'Ù¥šOò‹ÊÇŸ|òïüà‡¿üm¯ÛOŒ1ï6·{kƒýý¾ï1ãÞ…Ø+ ~?\q¼‰㽇‰à»w» Jvç\& €L¾¹Ã#pÿ÷sâH¤ûmT+°ïÙíÛ¬þz¨�åkhøIýsPêЇGAyƒ1Ùëˆ~Ó7¹çÓvkڇψ>îÒ V+îŸ]°¦ûBìæú5-ª¡Y5Îõérw¹—ªO ¼IG—fUQàEc`t^1j`PÜuNt…R§ÏjP™Š�=‹Ï¤fžô¬ÎsÞËÜŸo\åÂP´oOL=ª0@nÖ“º•¨·¬äœ÷»íÈÚ‘¤]\ߎT¿*¢S÷¾#Û¨¹×‘ˆ�¸;ÏøNß{žéÝO%¨Öq8�|7êÝ�ô¼ãØ�<"sű™˜ôëáQ©ß#™µC¹wÎù½Ü‰xÐì‚bÆÅms7�Q‰îxµl լ؞ڠ²RŠ?bh2hg\Ä1MƼþêûõ¿¼mÛ�œq?#cnëõ 2vŒÃpރȃèˆsðÎGP?€ÓÞL¶³¥ýá²µ=ÀX2ÁM¦¤¨D@ÛgÒ_ˆ°ø7¤I�dD¸N<¶±FÙöýØc Œ-À½[\¸Nç‚“@`Ïòaœ$¥½$¤ŸÛøŸ±&º ØüºÔ>L¬Ö·L2p^/eÑç\$ØÓë¢ÏͳfÍš5kÖ¬YÿÕ$Ìš5kÖ¬Y³Ä� æ­ìÙYknûÁoÂæ++Ђ¥ý�ª´£N›k>Û%å"1WÜif.Ö¸IíǵC¸è“á:<›«Ÿ÷{`Ü72n�¹Ék§-‹ã ±†°FmÊ® ù¦†Ê&?ÝI@—àD+jÛUVíWºZ] ¦»yë÷€u † 3A ¶Ú=%fP!Y¨ù5¢"hÛêáFµt �¡€²*ù|·m•µù]5k5úz™¼ƒf iy­Ä¿¬?Ï ß�»“ ÿȘ$y‘UŽ7ŸÍ#¨È ­h ØkÈ Áû—,ÉSÜ{f…ù¹[ƒ:?¾—Ë~âÑY ËéR¾?å¹CÊq_­K-øßÞw$€‹í“ú{jó LWíßàiÉÍ€Åro„><¬Ç?h sÜ™a’}<ÑÀ}‚Û.ÍÿÓ‘ S%óüïÆ«ˆû<º^zŸ)õy|¯8[ÇN eÍ¡øƒW¬ÁÙy¢ þ×C’#X+&QŒq8·¯gá”ÔôZ¥5$à_�úøø”,ÚI7�ê[aÁÕ8aÊí´¹YÞçÂK½¯Z�1•OŸSôüB£†÷`þ€¹F<ã%¿Œnè<‡è.+O òö×ððÒâ-]Y*b‚|îÈvòhI byè^U74îÅôtÚšÐ_Ç÷”²^0¤‚ŸŠ[ ‘¸¶ŠD Èsù5Døô›Ÿý?ùäë8Ž;rïŒ1ÇÓÛgï‚Í?»D BÈ–ÿ|g†÷‰ðÊðÑÆž½ ¤`Œ±0†¢²�\ë*g¢–uÁº,!מªûH¾§é–uƒû§÷>\‹wù|×e ý¾ç{ ìÇw¸Æ5 üœV¢qàrl€�êÿä`M‰`fÀG7 ¢î\LòZƒã€k^HÖÎmíY³fÍš5kÖ¬QÍ'¥Y³fÍš5kV)Ÿ¼òáˆì ßÌÖ¬,Õ4è¤Ôt:Ç–•÷=Ãÿ*‚>�T‹Áâ6£µá—ÿ”“r½ÏðÓ‚ZšÀn”¬áe÷`gÎ`™8ú :jªî«XìëR»ñÛC]#‰AP½mZ¦ x˶ÚB"zòæ²1g²(WyCêaYËF©l“@Ú;)¸ñGj2î¼KªFQáv÷ìßOܦq¯-ñ¨ÁãÅ%ûW“Nè_­/qD^é_‹&a|Ø%UòÁ4×Eþ´Ì¹—×gÝB]{óûçÕ7§;/æ¯6 /�ÎE÷�R•rY/ïŒZIÞ¶g­4UË%éæ•‘'Ñu"‡\C:+)ä=£nED ´Õ9a¬¨U òæZYc‚|QVgNÍíáݳ¹PöÆÎ‡ �>©¾’–Z •Ã>Ž?ê¹4ã¸r@@¡Œµ`ê�TÀj�–Ú{øšš^eT�r§íÏV˜ÇWGvhÿ ™~ ЏçÉX¤~Jã×Ä&½ç¸ñÐm¨¸°œ†>9Å´ªôÜ5‰$ ÔüÙœ†MVp×DBQß'ÒA‰œ(ã6€Ùe‘¡“y$ÒCDºä0ZĺýË<+Œ\m¸ZOX­CÔqó E~eåÝ/ <„³IMm´‰xî?m ~xî(оzæ“cœÅÀ)ÉÔ¿w'wŠŽKEs#÷ »,?ú�?ñ§þ· úmfþ){¾yïyY–à;fç�ƒ1K0ÄŠ„\ö%Ã>ðP‚ÿWø]Û“#†1a“10‹)}A¬¾—¾,˺`±—LNN~¾ÿ“$ µóT:}$+}¥Ø_× Î»#€÷û¶åßKeÇ�àìå½S$"Êê»X,6�Òk¼/ y@ <į™”�¢Œ18ŽC¹xïáã1�C]÷_úgÿx¾<áz}Âe]°ÚÛàœÃv»áåõïÞ½Ãû—÷Øn7xïaí‚§§'\¯W¬— œóØö Ûí†}Ûà¢D"v¤ó' }eí‚Ëå‚Ëå‚eYsDƒá]$„pjÏûëlr;Èí`©Â4äŸ#Xô¹¥qà‡m»áŸýþ�°m7lÛŽã8”3„eYp¹¬X× ®—+þÕ¿ú/Í=‘Y³fÍš5ëkR“0kÖ¬Y³fÍÊì“ÿ${cÍ ¨7kgذòœ6B=zÀzy5Wû{­J¾gÿYœZãϢ؋4Ù8 Ú˜Ûâ am (io鱉q_çÉ?é'´JºÜ–í‡]�p`ÓÞóNË1¦!)úH(ʘF0€ÚþíÌÜÚÑ–˜trdõ8ä^ÆÂY›–Pí<”N¬ç¸0?ðº{øaF°žÜG¯ûG-ÐÉçŽê™ˆñs˼¯®‡jrF¥$¢>�O½ „3ûò1 sNvFW>zfÿÿø¸è‘ òf>ÑØêüî5õÿÐ ütŒfð�‘çþÈVž"(ÆJ…ÏÍ Dë¸ÅúI„޹y%�eå©_y³ío“)?ê®îâtI´�T)J;ùáè`¨a!Hb*ž+<ópM¯’kÛ]çéÉ£� ¸�´wˆ1„þ2À'«›&!(sƒú»%÷½öÕñJ)"áû¿øƒ¿òæ£�ÿžsÇïyç¿`ï·ïýâ/z"‚'ï)€ÿ5é,Ûôð /øM�(›lÿe›“rÓ98Î{²ÁÞŸ ¬]a—%|×ò¾�ô|EON¿Pù÷\¼÷p1’ÀyËDh¶ÆÀYãM ãXn�ã¹û2ŠS€øÏP&$2p¬‰Ž�",ë’#Œ1Ø�Á¶ï™táŽâ�Ž‘Î#D%†Û§çè½í{‰:ç¨kmp,pDÀüåå·××øÙ^ß±Œ�²ÃÁ²,ñ¿—ËclŽ=DV»êÝ#pdrDŒjm×�vHà!¥”ßyÃqhG‡è´`� dÏ�0Á¬Y³fÍšõuªygŸ5kÖ¬Y³f…Í\Ãî€3d^2LC x©*‰W^±M$ Å6i}6y´^ØTïuJ UA(Ûõ«ë�:°'×ÊF>ÙàF>¯ú×Õ�?¤µqªÛüPI§PÙ×¶ÖËH>ºˆ?QÇG¶»ÑÏÓ¢lÙ³LE´Cºæ9JŤ î¹!p÷›·ù½]exD¥í±ÏÛ¹þò—#÷� ŠÁ»Ûvj3:Q¥^†�VCO ×ñ5ÑÉå÷-éùý#í+Û&��7?÷”Ôg¶1ƒx¬A]Ñ%W@õ½¶¦G†�œ'Ôæ¹sc›_�‡$µ¤$E"$ÁL*ù©k»ÞÌv–"~+QÉ#/¾ü@C‰uUÍ�v’ügmg\òÈ%tX� &¨ÿ­2'šçΘ&´\Cÿç*sîHƒyðÚŸ[Ñ£/g×C·†™ŒÎ Dob´( H ]Çá ¸’R��çúmÏwò¼»}Ý©ýO/aä!²„¢E7ª™;ìH®È(zlq“ Ýã -¦;}ØoP§+‡‚&6$&z0ÁÃw}@R–ó-›TÛΗvmW5öiB@{1 ÚAôk¢ “ÀþãOK~ú±·ÄL9[ E ‰·GÑ€î]W�{g'l®[W—{L 6Š%»\’OÂ\ÒkêœðœÓp½åt¿éY´³ÎŸ.íE‚ËÁãå’î-·#"Oq·).éwœ'N!¨HkvêΩ6O�XL,ž ¤“ˆx LŸ:^$´Qzö3z¬5Hj±,gȹ¨²%:*Jf“öAh³ªèñù’„ÚØ¿× w§o:JqC$«ít€†yTÝy¸Ä_µ.="ðAîâyN¦me›pÖÚs¢µ,�ßÚõ©»¦‹y5v¿à³»û�ùJ�'¬ÊÅEY!t\xä5ªÇ·Êõ„:Ñ\yœë¨i[@þ�?õOü•ëºþÀç ~À}û[ßæ�€uΚüyA½Ox÷&Î,€ö·áMYç²�;Á‚%‚«%ÖBì¾�Â߃½óE�ž�õý€s‡Vÿ ~zݶÝÀ^¿lK¾Ö ªG€<;ÁF;z‰2Žàˆ€|V¬s´6õÎ9‘`H ‡Š0FÄ,a«Ú ^Î9˜H$p.¼Ÿˆ`]­y-Ÿï½Ãq\™§ŒHÌVüd(8+$ ÿu…µkp'8Ž}ǶÝðúúŠÛë+œ;`íc(¨þ#Ø" ô:kê©Çœ1^ÐÙÈš|œÚ ;:tˆŠ#Àè»}"„xAh2†`L º,vÁ²®X×`W;7EfÍš5kÖ¬¯QMÀ¬Y³fÍš5+løäà=ÀÎ,Ëû‚täW‰7”¿ŒŒÊ€s9Á$ÜX«¬é ß÷⦼IO  Ô§œa­tA=kkØË7¨#w÷<Õ¶l…/ÂnŒjÜO .§ çë•ØÔ9ïªO´+0�FºöÀÿ ÚD;JC%'»|Jÿµ’¸Ê­oÔÿç(¶ØêUmª�7®Z•º}ÝŽ^©Ž—@²ãGçÇw^%{ï˪ƒ;î •Dc�+ÞËÄJÊ=9-‰ñÝ¥“1£AÒþ|;ÓÜh«¦g¥´V8QO­Kýç^·÷ é«ûAŸ4WSfq„·dæq†IÏB…[2sEþu5×þß4õVç¬LÔ³�;WG•ù˜¸PÒín½¸$^ [óö½²ï{vêÔ]Ñôüë®eb� üJꛉõËùƒçm^½•{/‡�óà“·cî�sêSJ¸ b“V�wMÔ<®�ù37ŽÊu¦‹ùݹÇIД„Mú)vÉÚ;¢Muvu¶W©Oå�<…û Fi�Ú_(ñ©·† Z+õ=Wë•X¾3N‰HÌ“ò\C]™75ä�à&m:ó¸wX®SÜ£eI0·J6EAPE…ÑÛ.# ]k,Œµ³6€pm"аp.bA,Ä “Ñ˘|执ëÀàÃÁ³�®�¶Ü®º%¢Xg�¤ƒúžÈR±ÏíjITõº†ý¤×üp­ñ~Ågãøìá¦<ƒp'¡•óâ�|6N ø‹§�QD5¾ˆ€o~ó³ï�þÚ¯ÿGDZÿÄóâ¶ã¸¬— ¸pwY<<{8cïó3kç}´Ü÷<6ʬ‘s Â¥ò®Ÿ�}ãÌ”ùØöÜçHHíà�ãØ‹ú?6V°·/@¾wvÎaßwE�ÏháÚ-–å‚õ²ªõŸ™óçìGô³@´�/Õ3ÁÀ9w8ìû†ã8°š`£ÿê/a³zY`HCÝÒå ~®LVùpž;<à…~zÆ ÿ4Ñ…!(ó)Ÿcp(QGlÓž�…–Ia�µAåo(ùi õžaáI¦BI¥!ñŒ§ÛÞgu¿j‡æ9FüÝ §ªx±Þp;éóRƒ]¬ëÜ Œ�5�Ò fÍš5kÖ¬Yÿ8Ô$Ìš5kÖ¬Y³DmU�Ÿ8ÇzYŠ/2}{GZ»ÖôGÙãÓƲ¡U~ÖBr% lôéücÀÃsGSXísãl\6%¨Î{ÉŸr¦ñüpð¿n»6�·Iy΀ikS:O^Õ’ê~æk9פFJ  L«1$L&.³^ošgJªŸ/møÄhžÒ8I�'ýÁto°vp’�‡$ÝFçXg(@âQÄø¥óü(k^ÿìŸÿ‹àßá§DxqÎÁZ¯Õó@DmPåDZǎᜇ�ýæ"1`± ŠjycQAc"€îÛgbŠ“"èÈ"œ&HšbxÇè�çoÀlL°ºO¯€›pç Öýé}aÞ\®+žŸŒÊ ÷>€øÎØ�ÛmÃqì"Àg·ï=¿*ÀqìØ÷=Ò¹$‡„e]Á“�éÄ5úHpÂáÀ'{{!Å'ÁûójT@&LÝ8Ü3ØØ÷=€ÿÎÁ1ƒ¬Å`½¬¸\Ÿp½® ã–“@T¤ö &Ÿ¨%j$»"ˆ /Ý´krF=�ŒÈ(¬ÆÅ( Š„‹´F®ëv±¿¯Fe³fÍš5kÖ¬ð5 ³fÍš5kÖ,Y· öu¹ü¤±WÀ¿—?‚|A­à— J~kµ;7oì ªÁÊ—³á¾’5©&ÂO™¹ÁÃFLø=åüÓônÖªæê/g€ú}ð¢jQ j÷VñY4PQ²R±ÖQ¾™>БŠrÚïØø§öIêÿ’÷­ÁFq x9ÖÊ:ý»b}+^Ì™´2wµ ±JLçÓ–ÿ  C#ûÚ®;õO’ÛßöˆŠ|�„é)L¥tRv’ÈyGÔ–Í„`3pgñî® •%¥ò'¦†A �ªqV0Ç<ì0v:,Ôà#k‡â޴‰,÷±Q^`Ö$î4dãi“¸Š¼¨Ñÿм‘ ®Ü†=‹2�˜»}LwˆC½Áݵ×NÚò¸åãyä¶­Ô÷zx½A$(ŒqãòÅÈÆÀ/�ï´BY«Ûu›ÄñÁ�9‹žÕ=´Î¼& o>ý5¸Êˆ-šI%œ†Gšàì€åÓ´7w—A/‰§ /W±ºÇ9Þßí…;�tÖï^ôðúÀwÞÔyân!ÕÌÓ ëHè )OåG&>cèL ‰S΋ºm8"öøÎ=Nš²·±¿ÎÏa‰ˆ)?YÙ»›ð¬�¿eY±¬+k`—U�Õ ‚eöeNyTk2+N÷oñ¦üÜÔ�\¤xæíˆë "K°öï=. ¼Œ*â@ jäã8¢!¬O©ê{üSw}À Ã/­á£X‹ñ W«uœ˜ê¸€f=çêÊ3NR¾ç±!â2¯–c&|Èw~á»ÿ§o}û;Ë{ÿ#öü9{Þ’¢ÝÎ;X¶ÍÕ°ÝÃùÇáàŽ ¤gïAÆÀ/+V,D šÛèäÅñæìý Ù±Xõ[[Ü(^g±×7ÕwÊ×^÷]Ü“‹A²zOë[PÅ»ìBáâ5$0Þƒõr�÷O°‘8ÀK°Íw‡ÃqDÿ¶cÛÂßSŸ‡ÆÅàYöãÀ¾e½$Ö®bŒ@ÜZTùÑÝ jp\ì®Û’Ûà¤À.Ùÿû|í9vȼÇ(…ð9@ˆ  õk-ž®Oxz~Âår‰„ }5¶Xù;î!Øõ–ƤÿŠ€¼ž¼Š¦(çuÛ2GÜ ’òßÚ¥œÿÏ÷ö7kÖ¬Y³fÍú‡\“0kÖ¬Y³fÍ�7'=3ö§§ëï†ß‹ÉRµZ¿…; >I,ªÊSN¯ ¸†Ð¡²61×P~JNwÕGÑ}e©lÞô“¸!C•]¶PyœZ¸3tÛÑ÷H¨:•MÃÏì:³¾=d·­*°Ÿ¹RAÇ÷‡M*~¦¹Îœ}{ þww‡VÐÒ‰¡²D�ÊV$‘ûCc¨s¬ÿMÝsÁÜ£ðJsKçM¢lôï��O­ü�”z®3'GmFçØr(Þ銴r Ôì÷ßÝÏCo©w�ÆwÆF¤Lú)}ÐÙ>2ߨ,“ñÜÔ&q~%[‡†kâ(Ö�{ Ìr�÷¦5*Òw"7Ä:®Uèâê®–Á~ç] ¥R®é9@zL�‰¢¢zùÕÔ‰•Q+BY×I7 ×.ܹ'ŒÆ2Ð:£P¯çNõ²d#€ÈgÕµÆdbÕ¦™ÄFâßwºŠëX‹“þ¤¡û57sYÆ0î‘9èÎ8ë;¼œ­z²_wçîoméëg5Òuú¼ýºpÉ@Î*t9®¨ñÕïˤ‘Á<ƒZ’Bè¨'äZ�÷üæ-.× ˜#ˆÉ¬c�˜à©Zã¸ÌYE�‘ ¢Î-´Zû ©È•zª'—†~FÉ?KŽaQˆ+@×ü\v8‡c۰Ǭ÷lõÞŒ'®žksBD+‡ñlWÕþô�®8$þç^bH3ã‰j£†s~‡2ƒÑ xm µ¬ëïþé?óOýKû¾ÿ–1ôcçý»ßùû¿å–%)ÏKLƒ¶evÿ‡Û³ŠýØwîDcÀ̰Ö›õlÇN�-•ÆžGV†3§¹HÙ- ó @ñ~Ça’Z<Æ)z+ºȱ–Î#µ“´{×ñ\Çç�"¤÷/ë’Û!9G´þ?œ À9}?dTûÉRþpÇž,ü ÏÊÊþŸÆ�öÎQ<ÏÞyýzq]é{€g¢Kµ³ë�ó!rÀ§~L×#–PÖFç]X�Åz}Xí‚ëõЧ§+ÖË "cÑŠ+ƒ¡à´ W±°%ò �1r 9yЉÇö*f¢ô3{&|Æ­ûeT„ÑQÞûÜ¿D„Å,1âaÁ²DÀb§õÿ¬Y³fÍšõ5­I˜5kÖ¬Y³f… c@`ÏÌÀþö£�~è+ü}$)ûm�e–€'çÍF*ÁïE¹ÿé9m¦rPþÆÕ¦¦Š+Wg*O�!ͶùTmGZ!¯rqÅѳ5w¯Aã&l ^ñ#òÙÎæzÏâ}€,ÿQ6zõFi Ô#o†åæª�—øOyƒ¸l¼e}·zóXY®ÅtN¤7ÐóiDVjhy6¤¢ê0‰3xg ~V¯¥>ÀŠa.:i÷Þ{ŸÌ}ú˨«IäKhAØ#m—WíBÕ;y`nN£5@¿ÿ|¸§91°o§ÞÜäÓt’Fíß;‹¨”Rç=ÿIÄ\„aošŒkÙiå iÐÏT·á(ŽKê[Ž%ݾ-±ÝwÇKÓÃqÂÝ®x¬o‡Ã­.œ:Q�Ò@XägŸŸQ¥P—î%ÀÐÅ¢vQ¨#j˜ûÔ ê#`˜*¥®R9 Er^ã:2¡¦_Ô :£&ÑàüXõyÓ ö뵫E:‡šª¡îÀR‘Û%Gp7­…IœÑÉ@×–÷úHbLK!HŠ]ú2D:Ÿx,Öyõi�jT‘¬ˆ[ ‚|®Ò÷}ÄN“à–ãYÚ Ÿä±Ô«ž¸y“@së<¬¸¥æª;ä—3¼=;°+îC�Lj*’¨XdÀJzÖI$CTb9¨‚�¦Œ«š ä¯@�c`ÉÀ\®X/—œAP=Üï¹Î‹ä¨e(|T}{çb²DPÃÛÅ‚c,�M6Îå> �<ü,†¡ÖX2¨OÔF¡dàøpØí�DRð>€ç.‚ÿއ؊¤˜¤-8޳Ág?Å[òŠdc‚$¢¦H‚ýíè92AÁfðß›ï³ 07KpY£ ˆ÷;í€ Ç:Üû-�LvlH}dŒÅåB¸Ä5`YW\.W\Ö –ÕÆóbÀWÚ2¹ °$Ì3«õ£gýŸþó‘<‘Àÿ:€™šc· #�)¢!rl@$¬—‹µÚ!‚§À¬Y³fÍšõuªI˜5kÖ¬Y³fìbüÏ|¼½yûÑ�ÉÒÇkö/„ÈCÅÛN꨺‰ôfb½ùoH:׋ÍÏZØ&>ëAÃgq€:R€‡ïSú0¹»Ød2JãQí„ 7û+¬³SŽi¡‘ý._ßqfÈŠÀ´I¥2II0�¥#7êÙj¯`¦ uNY»£œù›¬ä¹ß¿Dmž}ånL6Ô8,Ô{ßUN´RÊuÇšJL‚Á{¹Ð}söf$3@½³ˆ›ùMœîØÏ^ÏAî4 ?ÄêY !GT£ŠÑÉ´hZD(¤+G f žŒIU0 MÊšDuΰ‘çI5\�|–gÌÂjxtUz\I03ãÓ]•7÷G„sž·EãâÀ­B²·�Aȱ½´Žo©×´ê¨—­»ª&4Š}’vý�+i<¸ïÙ_ãt†ûæÖ‡P¾d¹+Û„q¾Qš�T³Ü óèµ;WŒ˜6:�›W¬Æ•G¸¯ÔñU<€Vd�î¿Ô¬žDÕ½PD®î)$ÿ÷Ä1ä¿�<¼L¦`uÿ©}¶SÛ $ûMèGŽ%ÑÇÖù£Ì.ê{™d0I`ÿèD¦d‹w zë�çÙÃÀ”¸‰†Ì§Ÿç4…D·^GVtF))©»+ø…¸Â¢� Ð<Q&+°ãâ ž‚sIU¸°_§Ñ¼`lZ£%‰¥½ÇPõüQcql©Ak�jTBn_©ÐO}d,.‹u]B0—gûÔÍ8–�ë©xM‰ #ï ªÍƒ†«þé�cŒ Ëëäj‘fÖkL5îäsx"Ä•6­¾Þàr}úÿþÚoüÉßtÎý„€ŸìËç_üÌÔÏ)ÇÝ#Ž#¢h�\`‡¥o>Óœˆ¼†ï1ÖÀXÕ )cþVûÊÙ†)«·ƒ|¼–�'à;�RV¡zD\I sêƒb>�ñF¼¶ŒVc8þlÍc’Œ�q&»˜ '0úp– Î3œó1F€Õcc×Á¹€#Ñ�òXŠv]‘×ÈÅkÀG¢µ; €mŒ)Vöf m°xxï£ú¿8€äœ#5ܱÃ# `Bû$Ò†µ´, Ò…1‹]±\‚³@~�r®ÒÄ"G‰œç+b߃ìà©™hâ|¸æD:ÑN 1¸Eœ3EIZM“»‚s!Ò ÷,¡ ­]r[¥¾vÎé5tÖ¬Y³fÍšõ�}MÀ¬Y³fÍš5 @´¯$öÌ|°÷7¯‹]~âÜö�¢üG_ù/þ%7e¹ªZ>MÅv5)xKL@²üGy1döð™YlÏŸåþ"2˜ ‚dà¿{Xn@ù²”³8*�)œëÍf.ô îCm+u�þK»Tà?„]eÞI(6OãžÚ“\…+•­3Ü늾ý±TY£/òVÏ–e{Ÿ(Þ¹"> ÄlDt®TÌ"=›ú¯åEñ+Eìîô›êþ@�ßH’?„¨¡JÔ3\áþùh”£ ø‘sõ½)[Ф=|Ÿ uj C,6Æ›ÏÇ›ø§'øø…�Äózr02™PXk±,BÍ?7eÓ'ßû:"Œ! ¯§‘P,Üw€ ú5zÚ‰´•}¤Cœ@!Xks;kõ|ˆoHà¿]™ €á>¹eäèÛÐç&‘ Lèc,Œ±X–`�þlüS¬ _ I° íˆ#p^“½:„Cù½,9/Hlj�Oã¼và å"\øþ“Ùö?äÏÉ„…Y³fÍš5kÖ×¢&`Ö¬Y³fÍš Ú,†ý׆nìü˺^~tÛnßeU=ð?QíH\6¼©’¡“²Ce6‹ŠÊ’ubÙDD“S›�ÓÈ}õ3b¦±Æ=š]oõ»Ö™˜•j/ýIhןñð'ŠqâjP)þ={­Ò%¡ZûÖÉ¢»bø¬=sJ�›hT $Y!þ< é9Î#¬�Λ']A5ÙèƒÇ€Sÿ}Y_:T4§<ù^pÁy_¿2BA»*tùNtß%¥±òoN‚¤Ói±fñ›iµ6|èšÓª9¶A»'4Éñ4M}«ôø7£=SÚ9Åê¾¢×÷z*%ïpëNäæžT¯©×jã³µ!�Pq®Âà <8™¨ÆîE¶ˆu€õò\ÀmÓ#Œùã¥SBª…8 Aò*Ñ¡y;uüTJÒ©«OWJ�_úµò¬Aã €Ö¯8ã೟1«ñ!ûŒO,hx+®h?žÅs]ÿH¦wœtžÜaîà%N1:Ÿç1#êù—\Z ù3RmäoléÛ5´m‘â–$Ÿš×Îàñ×gtr œS­ÁmÑm’Z(#ؽ ªF7>±!äºGH«v©Ž-vý¿ì–Vç”̆d‰Ý´4Ðéßí«´ÑÏwú²�‡¬¼•5Î UîèzgópìÕýG}¼w‡E†V 5ÐKB;Þ眨ŒäÚ�PñrÇÈù$?[yTsdð*‚“Þ(ÒÕ ÷#ÕØƒ£AXeV×ä’êsï1T$Á@:©P_mywβÓ)Q@’=䆵”¶‹œíÊ\G�[ Tøt2   2¨©{g�žlZ'kË~ ¸é7@�jû|}V÷<ÒÀ�•/GYˆË¸/çjÀÄ0ä>“²ÜÙGU1‰{c�—À££ªÛ$7%è2¬>,ÈAƒ�ç¯ìÿ,»}êßÖî=/¥‹d=ªR&`ÏÌ›wþ=³{wyºü—YíD€’ÿÐŽ¹µ÷+—¼K†ÔàåwPÊÃUÖêÜØç¶N¸=%U« ãnètÛê3YXêæ Ër.2Ý7[Õ¢…þõ4Ú oϯóo.úç‡ú´´„Pý³¾vC$Õµe5=D=P?¬¬¯“q¥ +¶ÄÚžøìe>'�²¾YÛ.+Õ*WD•Qqyy²:ÍN4ˆ.¨û—;ÊàZ9/Ç5F 4Ùxó�QX_íCcn¦ŸŽŸ¬þ§»c¹ë—‘€±l]|ËléÎù¨D€N6øZ´šm¯¦ãÉ/_ÒÅé$êWˆ7*m¢E7îN|e‹O©GÏzñŽO�­\£3~ózÁ ¯HhH*Ê `;Ä(•‡ìÚàQÜhzC–FûFÞ‹X"‘ýE,ƒë|w¥ç.É-©ð¾ �ð! —¬ó„ÝØ|> èþ|!Ôùä噢žyu°QÊ©§p„)ê÷&]†x°æ“Š®¡Þ…�;Ü:19:@¶˜ßÁ‘¢ÐN¸Ã‚БÔ(T³;‹1ì÷¾é’ྠ˜(‹ÿ†ÔÆÊо¹Ï’Q®u̇œ©å™‹…‚Z¬�±ï’«�1½uš3�óÑuš«H‘àt®kY,ëfƶí8ö=XØ×÷,¦^ŠÂ‡ÍWw‘*g‹ÏñâöЪùùü¦Ç�Ûí'ßøô¯ýÒÿÀBD¿Cd~à¶£Ôƒb;É ï�ÜO€––\Öëe8Ü2Çq`۸É{P ,낡1pîÀ²Ø`¢}tˆg°÷s¸# ì=Œ¡¬à^Öë²°z•öí)Ž ü7Ê? ±�ª~‰ DKŒ'ððþÙõÂ݆£�½ÏR‰H`Œˆ0ˆ y±Î7™Xì3É Ä?$òCú.0\tSðþ€sá\ ˜Â<‘4<çŽ}þï8ö λLZpÌpÙö¿â.º$0|Y¬ëŠu½`]þ[kËÆ�HÉ}™’É{ìóÒÇž±¡ÝɤÿI;.ô*�+fÍš5kÖ¬Y_—š€Y³fÍš5kVØBÎ;¿1ûfþâÍ›�þð[Z ?mÚy`DÞÔ-¼Všy’f5¯©�S( «÷Ùù€(€°ÜDmvÁ×&˹l�twÒš‘AVz�yX™®Áò¥íïÂv…YÒ’šK»¤�è²ý�lÎ!rB˦}�#Qxàb¸žÕ´ :bªÈÈ›fw® ƒµ½vm‡ygT‹ëåÓ¯mMËYÄl܈0WBtô:?‘Šm+Ý?ÏÎè÷4u„w'ªÃê'­WÆøõåèôÈ•�Ú{hA¥Ô£»JB‘ùÍý6ËMÓCsÒÛ#uy9ÝSJóInÎRQœâD.9%bžæ|á” žUÕÚà•›9ˆ AåjÙ�›Ê¼…ø¡¾:{ÑéÍ%¿ÌÀd`1©S™ãÑ’7RkuŸ"›È„H' ¬!°'0Y0|¾gåq®¬SÊx“kWÏ8ÜË¡o™9Ãå‘Ý-À‚p`*S‹…•8‘ѱád ñòáÄ—íÝ‘¹¼ûrY±®KVOÇQ]7ó‹ëçƒGŠz!c %îÜ»Ï_�#±XãŒ1ïãOþéÁÚåïÑ�ˆè3ïÖ·èhÛÏ��eÆb ÖõŠëõ¬âý €°Ý6l/eC&ÚÏÇÿìWçpØD·òÕÞo Ø`·‚˜a£Í½5KÀ²X8ïÃgGKúdËŸÌG|gh¦8�Ô*ԡΖmáÉÈ1dÄ)½ðÜœûY€àåsJô��],–ì0£c8ZäS9[ i ûÔ>Ѷ>€õÁÝØ˜G;-Äk·o™,î½Ø=lÿ“ý¿s%z`YY!(ÿ×5þòå½/ß2cd«þl±`âú”÷ŒÃ9¸=8㤩›îwÞÞ0ŒúÉÝÿÊsf꣞…<äO�Àã\Qÿû†è`aÄõÉñQGÌš5kÖ¬Y³¾>5 ³fÍš5kÖ,êföÞïÞû€ß}ó³oþíÿâïÀqHHTˆ°V.5%‰|á’Ù)Û +øùåñOB�|5€½Ü0~­Z^«ª §ÊÿšÛ|ž:Chcf‘#Þ=V fj•2 üä(I¹ù²¥ò¿Ø‘k«ØV’ÉhLï+—´²Î@G‡ðX�”ì\e×jþàäîsÛQe“½ã…/”Ó@´ î¢C œ?Ýu~àÞÞ~õ—Çb#ú€NÇÎø±ÞËÑgÇzÀ~ 7›z ¾ï/¡†Ae/.Ò¢‡ç¢]=DD{1öLóêÑQÒysŠ Iëq|!fÖ’´ÆNsLIÏO2¿+«ðBPø †ïÏ›Ž…?NWOn†pZor†/3¼ñ _ðzîPµþ�Î-¿$µ´d™3µuw–ôÔ¿ûªa™IÍ,ï�Ô|¾"®aDº‰‰PG«ëNn.Ñ~¿Ü€YD”ÉJ°º;^+kñá /+™ƒ;ûÈ1àš Ñ!¸Kð**Ó!  ·q…Ö‹¶¼ŸJ»|Œb‚Æë}X¥ñ[˜Ïîs*¥~øšDJkoÆ‚$Ã…?ßy²ÉÎ'£çM Èm�úˆËÚ•ï�º^#Á¥å)f±‹çˆD^"£¬™¹è\™+”ž,MËm$ŸM-ôÀê_më›’@ÿQ™”ø6CîÆ5¼µf± `z9ö悃ۅ �žö#ªê�ÇqÜ ¹Möõ‚˜ZÖÙ@ $,¸pµÚçW"ŽÏ™6‘»5€ÿQ9¿X,6^‡ HÒ@v@©ØuÄ‚Ô ¯3|–÷ì˜(¨ä½;ó>’àÏìÂsÚ±¸Ý‚C 5|!+Ä6^— ˆ'ýÚù-ÿ<ö�ó>¶}~îâ`D’œJ;Þ‡ç;cZ�?}^ùÏgŠ4Ç Bň�ðH nw8öÇ^¢L3KìŸeY²Ê_öMz­å¯ö]`Ö¬Y³fÍšõ�VMÀ¬Y³fÍš5+n>08”cæ ðïÖuýÉåzù»·×ÛÓW@~/-™²\e?úä*…DÍ70}‹ÓroS»Uæ£É!þ’œ˜±«¡’JÓŒF½Í é�©§öØ_FÝ` øOªÚ*G:·¡Ø„—)A¤ºCôv.uÁ�‘pç“eÿ°"[túÇ;®÷“FTÞGp÷ëQwø,èŸAÿ’¤¡†|gÌU}$À&¹éßqòÄ|¸ (»W$€Ç) BåÝùw«t¼Ë¹7~¨Ç¢×…üÄà ÀötãâQEaP²}�kYŒ^)vÍQéFÕºšUæ$W˜ûïMž|w®=Ô«íOÅâ\–™JÕΣ‘¤•ýÄ •Ù¬lº{GhÁI¡�­Àÿñà»Jyé¨ÐËNO€3‘p:@@j‰��Ú¿¾8Ï!ÐØÍ_W²3™@èÌãsÙ M(œ{Et,‰E%+=aà£cJˆ/¨œ$kHÿ\»îPõÀÝ5¯^«™ÏÆð ãçl�¡š‹ÇÔO11Ĥ#,ªÕíÔ‘†Ñ8ôfª“’àÑ®¹šÜæYº%ÕSÑägꌅþã*÷Ù§>ŠrB"ˆ|’H˜ ˜|lc¯©�Kb^y¸l_ó*¢Cþ™Ôö½õKÝò+r‰'G’÷Tê÷Š—¹¬-éëÜô,u÷¹˜UŸÕÐés¸ Ä×€Àg5}q³bÜõ<›ŽAæCUä•‹—ˆ{=®¸ºg™3`€œšàÁÚù¶oØ÷-(âÙ‡k·!ö ¨þ×àªP݇Ò8Pß›"0ïâóµ-ÿ€Y� HVÇzÄ>&3¦Q­�§N1ë5•Ûc¼§”u—;JÕŠÛi‡®ûwY�%x*õŠ´a8´ñéõÄÅÝ·Ä™ŒHÜs€¨ö²V–ÝNçz|ôÜQg�axöŒB;×ZbI{ï—k}&‘ÜqÿéÓŠ3’vaâfŒÎ"Œsã�ãý]ÑΈ$ôŸ•ô¼�6žJ\|þø�N$r«Ó³¥kT³§ÄKˆvÏMi‰4¤µåÊáA(ñÅ «&�e‡%’}†ÊðFåluŸcAƨ‡"’(ÎmAv òµƒ%ô˺„'ëü±,±�Üpȱ?‡íرßnØ£Ú;(ñmTÞ/° ã —¢Ô›‚[˜¨ÒO㘣zý8\¡K»ú �' y:�¸JŠyy«É¼Þ§u¾ý>`ÉÀ‘®bº,ØZ¬Iùíú�Ø�ûqàöúŠmÛ²ë€þÇv·Ö7 .×Tþ¬î3$HÁmáÀ¶Ý°m7ìûŽm ý[,÷CŸ®ëšû˜"i:¹AxÃùYM+ÿ]u_ Æ¢?�ÊY�³s{kΞóZb¢ê]×@NYlãÌ ¿GLÀ¬Y³fÍšõõªI˜5kÖ¬Y³få ±‹vxðòÑÇŸüÍŸþä' „JÅ_€ýïüÏ`K(rçMVf½áœÑ”Mc¹ÿà*ùFõ_~—_§®O½¼ù·<q³ÅßXSËCk^ªµ³¹äwz&ÿ©Àà„Ð�c¾g½9�Tr†Ê&ü  7l5?t„nèT¿ }Ì�Ét«ªã3­$}™1=i3†¶ï%î Ô™ïbQKphr¢?˜ÕÀ§sO«�µº>NžroÓÂŽPúÁ„ ªLÅûã9G8`4V¨óÑV ‹"rÕ³mOüÙâ¼Ò‰…;5ñLövàé¼¹Œƒö3å0ãÚ)D’‚àGôt�®#ú™¡s}ÙŽÚw”¼B•š¬|-þ¡Yκ�ûn ¦¿j ýñÚ)—ø�U_«*åMNº{ôØ*v‚š…µ³VÅßSÝÂh „ÏÏ+„‡"LR´ÏÀa#“°Ç§Î V÷¤]âfa%#¬Üý¬¬‚íd¯çõ‰u«±T<Ó?軇p|©¬Ô#< Ó$Z{èa,®Ÿ÷ fð¿b¬P½†k“œ²¼Wr5v¤þþ¼R+ñÐv=ü•›¨Žó.®¥ÙãÑZg0wÏ€h¼²fG…yu‰F×á¨!ÑÚ п€ÿåWL2] D¯�¤ïÝ4jÝÖæºüY¢ÔÜuܲµ;€½e ‘ÔÚ€K>½cÉûCôQƒ@¶CG ¤…“ÛÅ™4øß8©ùñÀzÇõ³ŒŽuJÖ\ƒçÔ‹ø¡êyªbfE¿‡1cï‹<×éŸÉ–›!]I ÝŒH¶[u”-=;}îßç¨z.LÏ¿i\˼ŠB\ÐÏάîá5Õ ˆ÷ƒªßÒ=‚„‘z•ÉÅŠ T�Ì€%À¬+ŒYBÖ¼÷ç‹�"? ×�ÑÓ4Qç^+îw\=Ÿ‹îÑ$ŽðÎoÿÂws]/¿ËÌï½÷ÛåzÁb+eþÀácÊic%Œ|Àá=ì±"Ãl\< õ².X/\–v‰öêÎgRnš£ÖÀ.`ÿ½,Y�í=Ã9�ýp0Ä0 x”æ{Ʊïx}y�Ÿýìgxyy�w—ëoß¾­¢2Âß“Ò kËsr¼ópñºçpìÞ±{¢jܤ¨€ÝÆŽË÷Jö 6,øÕº 2‡sqm&D�@Ü�Ìk0N" ÃØ³@ÆðÀíåÇqäÿ¼s ä¶&âZï aûlÁ_ƒãeì„cß¶ÛöŠ××Wl· ‡ ¡!‹]pqGVóq|Îg6\Š‹ŸÁxÖ�yÝ ¾Á²Ú ÞÇ�3 8Ç>D$ úkYlt˜X±^Šõ¿¼@�^¦À¬Y³fÍšõµ«I˜5kÖ¬Y³f‰ Š6¯ö¼]¯×/ËåG7÷úf½QªÞüô¨«6è³RH«ü‰K®vïë€ÚôiB±�^_΃;ê`q ÖY“ù˜ð*U;¿‡±×²½bô6�ÑXPëöǭ¼Âß}´û‡°ê{ÁŠ˜bœn¥ÚvµÕ™5JBªmÐ;Nù]Ùä®-�ÇùÈ=azÇ_·ÛŽ÷À·b9À«~ÎrýŽV y¾I&]+ÚÈréïÎý× ¶Ùæ¶ýe0ñð¼øäT•ùñãÕ;—GÖ—la¬U&j(SE…èÞ±ú½ÿ™2Où íOÜ~ŠÓp:<Ú$@cîhÖÛ!ÓQ WóOª@;#)¢R}Úϰ FÁ•º¼Öÿçµ6ƒ4\½‡´}DGÍÌãùÀÐ_Qæ+š’ß*‚™<‰~P 5¯H š‡$2Щg?_ñƒæ$±ÆO¹¹£ —zd5Ï-•+.SIðóÈùòu¬�ü<5Ëß™¹�·Yéi„ µ¨cËû:n?=ÀÙà�à¿/.ŠøFý �ú9G¯Ù’ޤLEe‰1‰»Ù Á0–e…a-óY;�T]Ø;~‡ËªÚ¢~Poü 1«ë:Ñí�ÿúŸú¿c>wν8çŽ}ßÁü¢æ«tA°Öb1� `lRæ/Èq·�Ó’OkaÛ¼yÅO#øÿ£ßù-\®A~¹^±. Þ¼}‚÷8ï£Ò<€í¯Û Þ¿¾Ë¹óIµ½®+Þ¼yƒ7oÞâÍ›g\?~Âb-çðúò‚÷ï¿…——¼¾zr öþK¶z·µ 3Ž}ƒ;öÜ)ƒ¾8² ÖCç°o[õšäxUÆ`ˆJ8p¸`‰Ëbq½>áùùÏoÞàºÕþmÛðúúŠ——Ün¯9Ê Þ—K 4|óÓOñüüŒëÓÖÅ1»þvÛ±on·n·­ý™Á ²K"w$e|CFðzlpw¬ ;$8çà�‡w w„¨‡à�Áðîà3é-›¬D2€1‚ ¿³¤æF ¥ïp‹]°^B¤€µ�8ä=ƒ£8�Øçx•¤úOÀÿšâÄõ¦qœ~&?kÖ¬Y³fÍúúÔ$Ìš5kÖ¬Y³ò®CÚkõQÖÏì7ïýËÛ·oÿæíõýw<÷ìõµWÞ8OyÄqã•£4@>®²ª-@+|cµiß²î[]K3hª ,| ð¿kîžÏ¯§lçî1I�âÈ"G3E,¤Í:–«ec«³±ßE–:öÕRaV«HI«\³jL )q É&{ ŒíjÒΖ+¶ºŒn�ù‡ˆßyQ…öVã£qsà;#¦ü �zúÞØ,°[:—ÝÑ—l­~<Ñú׈<õQ“Ú䘥¾�JôG²)N&ګப³.ÑPOÝ!>k§@ðô¼¤e|RˆRTèU–óÄ1�ëæQ[³’þ·*÷:²á‘¦k~•3¤9ƒ«¨Wµ¦ëŠ|–)õ1GËgꟀȱ—öÚ,{` è¾KÊ‘@WÙ|·c�ºc¬vÈÊx¹p’P¥ãª¼ðr�|nþ?ø·X·UmØsv©Æ�Œ4ÉÇMexŸD;vVç`"èi Ð×wÇ ÕyÇòßi~€}¥sgîÞëF$€¼|U÷{îój huû¥<»¥¤Ö¨9åg‚Ð=g r÷nSž+¨õ”!A.+à/•ùF²�Q2çëç%©Ü¤¹ÛQs9Rܓ܉ Z7d›çgF¯Æ¿vMˆÄ’xnžpåÙc!›38cÆÄóòµB{㊬À\]Ú(º‡*W!ªžÓâ¿MŠšÉcHÏqÂ,\b[²&Ò`”¹.£~RÜ…xù|Ë,×…;Ï)Ba_“” ̲Ô³:‡ö`¤×q|ªÖOI C©\{Z"7"�+q]oß~üŸ}ôÑÇ¿íœû©wîÀ‘"²XºÀœ<RMäb�‡"àÔ5*ê¬T`³1&žÃºR”çiÝL ¸Ì…Os,©¼]<�ý8p»zRÇ/è®×¨¢l‡r€¼Ýúò:¿›åyç�X'«u5J;,6Øí[kac[dÒAÒ� ï3Æ`�võ×§+®OO¸\.°ËPpcðÎãØÜn7¼ÞnØ^oض ûqÀœPðËö7dGô‡Šÿè|é9ÍÔä€ànRîQ¡�€ãp°ûŽÝØ»@¹Í­1`cÔw^Šc"9ð‡¿¬ËÀü5;Æ~lÁA€ÒwA�ä¾S$1"Ç�ki¥k•ãwÖ¬Y³fÍšõõ©I˜5kÖ¬Y³fÅý‹¢¶"OÁ’¼;ïÞ}úÙgÿÁ�~ç·ÿ;H`³ðV•û^nÖÁWÿ'õžOj°d»Xvm‹²¤¶²GÞ,|¯3d•Ĩ·¡ÞÙ¼Wÿ[ wÛNƒª¿œþýãQºK÷‚l ëµò¿($�êSm¹\Ü” ±[rSì ®…ЂK¸fæ‡Çd­¨Í*3�Gð?˜ÙÑmž6÷žï¡Ç•Ì­…eÆw¿?èË_" J\“4#adG3Ú!9Pî«”e¯I¬À*�‘®•ä|¯�X�55—jî’cøÔýt%)ïgšhóË�ùÆ\”¡€Êlm>F´išlÜ h¼Öî¬4¦ï¤($Š Í‡Ï é¼~K«õB¨¢‘k~ozHט*fAÈóŠ8÷@öês*¤0C �ß Ø)ˆkJ•Ï%ó=»�´*�–÷.Þ÷°h 0BÚ œ³/l´Õ Ût¾×nÜ8Eä1TžyQÿ‹;öäµú¿Dé ·OÊlo�²š¡BíPb âuPP=Š)§‰¢Äëª!”òT(4a”x…t¿íµ™ÍêÞÎr‘ଶ à_‰µáì‚BJÈn>·_Y[ĸ” ýø šb�€µTÅz²Šp®`Õ»Ý�OrQ�*#^CÕZ!AÄüî³[‡Nªú ¾V£¢GЊ€?‰µˆë¹Ñ‰:K*© 5)J�½¾ñX»ÀZÆáü0Z@’.2¤{c©–óðe!G" ‚Žx|¨ïñòñl¬ù©÷þ 2效Ž<—‚b½ÆWߪsëE–Ó‰$É€½S®º÷>�'¬É$‚P?óEº;Ž=ªÝ÷¢zOdclV|ËsóÑ&^¬)êtÃOšÄÁô÷pÞE‚SîT·�ˆù°6(îÓyI:�»„ k –eÅõzÅÓÓ3ž®×h×O!çÞ9ìû�mÛðú>¶-Ä8G$x‘gÉg$ÏÃdg™øõñ¯‡�g¿o–¾ñ¢OL$Xka‹ÅÙèàQ&–gÏœ·pîÀq„5ÙY ã=Ll¯à�èU6Vka—%€øë c)ALœÃ>Ä-pŒ°€‰Öÿ Öˊ˺FòÅ"ÆÑf±.´[Î×cŒ�›"³fÍš5kÖר&`Ö¬Y³fÍš6;(©À¤*—vï>úø£ÿ÷õrý{/¯ï¿ïÀ§÷Ad{ö6ÓrWT(ü7Å*V€ÿA™àµ­/™ Ü@Èz¬v§”Å#�O,€@îŽí€¹ý£Úüëᮬu©YY£B`«7z?G 7yu´‚VSQ²û— éO§ŽB‹Äf±xe¾6NQiÐ^‡úIóšGô¬èæÃRÁÑM¹èt&ªdú�î«„«}আíÍß«cúò(ÿ]÷€~Ã�ðóîÏiðþØ,dèx¡Üžjªlê¡Ö’“Ë«í£éÿ=Ÿn_¦€V½^Žûïlméè>“Ú¿‡rÎáz¬qqPÉ3I y�œ·ÎҚДo^ÞÚzW}²*΀뵛âD %¤Óƒ· •ߊVm‹Ðó™´Õ¶˜çÌ-áI}¾ÿ•:)uI«”ë ‚cr.ÙG¯æÈàfu/‹�r…¡^«³šP�ò`.>F*¦©€sê¾ÏÒâ<-†Lü!Quˆ1!zˆŒP¯Æÿæ|åÏ…–ð"H÷ó¾«OŸìÄÀ¥’-ÛM9 T.4\‘wꥤ {Ð÷ ·¤-¨kk}iÐC:¦†ÊµÇx. ~ÿ¡ˆ ‘ŒõîG Îçå<©¹ÚŨ(›“sŽu©"Öpr”Jï‰jîËu�"«4ëOq[€rI*È%+Õ¾ Þ}êjþÚb]Þ#äøA�vÂ-Ñ#‘2ØÎÕ+Ç·­Ôï“-Ór› �ôv0öè'Ð�Þ~òÑ_½½ÿ³gp´^²"e$Ì)¦5¾2m‹œSï3øï+�›`ÈçEÏJIå³íl´P$Ê »�NéTé®ÿÚÄ@�vò«�ðæ�QFv?e¾´¥:÷Uÿ†àcç«Î� âX“¦rè…-½<ÇûUƒM¦C á©s#aKÕ{À£vÔmIõUÉ!ËUzovS‰y&¥þè\Cï¥M$ýÈ1‚š-Öó±Ó‰/~xäU~æ5ÒŸ,ò©7b;9ÈTµB,¸Ëè)ÂGÕ^T9²CÄ`œÏû;Ä€/k1Qõ1w“ Õ²u IК»&ÿ�ó«²Ù%AI‘@ÆùÕò´#ƒ[FŽ(Yá/:®äŒ“°X¦ºÛñ æj|ê9Ó‚ûwRÒkY¶°›‡ƒ‰˜B �?8¶’y×oiÁÿº·$XŸ [�Y¥Ö@‚")eÛõxÿK§’xCwBB”>Y¯‡Ï(çH|½9˜Ü�A¥¤ü4‘Ç𨈖ÏIUœó’MpÐM-,æ«õ·v'Èó>ñ   G¨Ìæ ˜ËTd}<=bŒ‘I}íqÇNGd•sÉaOc›¨s·àl‹¯ÁÁØ×F«÷sûJw¢è¬àA°…X%&¡¸õƒOs�«”ÛBU¬ѪÓâ Ž`•êÍô,à ú„‹Â±_Ò=7©ÿ`½,°‹� %n@œ3 R�"`È{C <¯"RœCíÄ"aŸÞñ ‘n" õeK^®öü÷ŒL‚­Ç~ÿV_^y'ðø!€«¿v»—÷`ñ|�éÂÂ>Ì…ZÂÚìâÕ>› Hiâ7’ÈÓØý "užuR™í?üƒÇ;ÿž™o2†�µ`¢x~Ú¾©VÛ.°†<¯7€¾ée< íÕ*cÄw«R.ÚØK0¾¬e¤”ØR© Øß;§ÔÿI=ã5[¾[k ÁÀ3¼óp‡+$�ÅÂh‡•äîr¶�™ø=¢óð•Àñ¦�â°G§‚c?°ï;|¢Óg—¸€’YÏñ}/¯/xÿî^_^±m¶mDZ%y“ƒ5‹]âñ™ ܇t”K·íSîj �£à€àÈSòQaÁ%4GøœeÅqÙqìG^§³XØüùÈÏ…H™ìA±Ó8�Î @pÚØ÷û®ßöá\pÔ3å;¡1¶´£؉ŒHÄðÞe’[ωbÖ¬Y³fÍšõ�MÀ¬Y³fÍš5 ˆIuöB Ö`øsçÝï|ÿ—~ñßüÉïýî×yÿ™�@´g/6ÚË&ºTü‚ � <Ôj©uÌÊ')IÍ›_$òßKžlcîš½[5€�òr›ˆqùî¨Ùþ€N!Emû\®ížš,¿Ræï¦Ÿ&õ¿<–r  *3·wf(ª…Úm=·ªÐo|OI]½¯t60Ta&åáèÝTrÒï䳫>È"kjúGYw:OfÑÊÜ ˆ6;Ü€ô5`@¥WÒ9ô}ªèƒÓQÔézì5™4ƒ³:@OÎŽÄ,¨ WÔæqî±ÌI/JV*ªØÎxê;7 ‰häêW=E= €š*W¦ªíhL縧ؔÇa ^ë(zÕ)Ô�™Y„3ÓÉ öBã¡gÇc^Ï)@vÏ&ŸzkU=Žâµ2IòBÄ©&9QП÷aЪw²HX7ð¿5�ç%=JÅŽ Ô'¢n~5HÜ‚¥–¹Y@j‡‘ª QH9ŒõÛA•Ó 3Ád²ŸT]ƾ�ðd Œ÷!9®…kd2YDÚœ@“$R‘8ˆÔ•2!îLê{Ñ6áþ¡Õÿ^ß—È€¼t`  Œ†÷e±ŶHýS[Í xŸ3Üs|W#0Þ�S[QµÚ¬þÙ(e>UNyö ×Égд VsãØTˆKB�ÎNGy@€úU„Kx·Ë >bðˆÀí²¬ës'¼zn$‚"Ð ºÈaÏDúþ.ç&ÕŽ ¦Ã,“Ï_}3ŸÚõ'­q>ÙØçõH?[¥}°gÏj næ6I'â™ñ±›•$žé‹âÊÕˆsß§ó—~$ñ{ƒµpNütÈ’$xÍé°Èÿâʆ’Ê+ÿðok—ßÚ÷í…ˆ^ܘù0DŒH *d†à²àóµ%w<œ‹¬±f1ÂAp]e;‘ß”ï:Q��€×d­/| üÚÅæ÷�Ž!ÁÚ¬ž_,KP¿§ãÎE•ü!¾‡iU¼$ nŽX `X‚ãÜå;13ˆ‹«Qð}´îßó1�sù:Ê5‹{F´î÷ñ½¯Û ï¾x‡w_|Ž÷/¯8¶ûáD$EtŽ1éOƒe106� ¤ò8%ANEbÅ{6ˆ}何È�òÈÜÃï}& ¤ö„ç=lEj™5kÖ¬Y³fýã_“0kÖ¬Y³fÍ�,KN©µ^ÌÆ†>÷ì~ç8žÖO>ýæ¿ò{?úÑÿÔKcÊ–ÎÁ: 5>$Iᵞ}#A¢¸‰Ã$7þ’j›DJ{ÿ`Oq£½#�¯å¨%mÇßUè?û̓ß'å›4Ø‹•›èåüXm”çÍuµ‘MÝã4ºã³�üWÛäÊ«MêoÐÃŽêÈWÄ8Kq§Ê‚ýìð2¹Þ6­ì\ïkWèF,¨¾CdvKÝn°Ï ¢[“DÛ$2ïG×Zg‡ß»'•q•ö¼µKˆn-„HCøÿn[ÔÄ ø¤».~î‰zšJ´‹$Í�<×<&¨ZØ;s¤k !âddîr5vì¤�!òà–”^oˆn"ßäÌBÝ™Z^êu.^ÆÎð.YŸg5x×M¶\&TqUïïûöæùùòl�¹ìG°…fïI¦½(­µxÝ6x>À‡ ßIûwô˜< °wð¦ÂAÀïñüü”×afÎêå|‡7u¤J¹z; I5TîeÖ¬«Åe]ñòzÃÏ~öcó=št»uœ}ªEÔˆc΃@Æ�¼‰¤�U¯mÒ)‚IT,ñ# ÈÉ ÀsV—äËý QýOÒµ¸Ç4I’å³F¶§Ö#)�¢ëÓ»õ¿7ù}êY$_‹žÇågÂ_0IÞ´©ÉF—ƒ´. ð?}^Ý­¤–:ÚÓhM#A$éxÒWÄ¢¾³S¡@”1Çuža �ï¬_Ôå!Pw¼ž?Œ1W7ד÷±/N(fu…y�41NÁ‚gìÈ%Á‘õ�¯8èã(;€êü ¹JäQA;È,Ëòw·m¿Cˆ6cŒ'âð Á˜ì&•UРIÝÇ5–ààŒ�·.޵Ô€hÉã(�¼éüƒÓE°‘·Q…^ÔÖˆ/x:–Ì”OJ~™YßÞ�ŠÈÄ�ø©ôNà¿s.¯ç½xÏœÝ Òµcòý×ZÛÄèë6ôZaŸ€üô³Ôá\L¥þçæ9©Ý¼¼�÷ïÞáÝ»÷x}½Á.;½‘1°‘@`ÈÀ^¬ë‚u¹`]@Àt­rŸïÚ¶åâ„`#Ÿ×Z€ȧ§&2Ö൬ÛÞ‡¶ô%/ÏÁ k (9`ØèòÙ5 YPÊ Ù¯¿ãó\ê3­ ŸA}µÒ�åØk�À«÷õl¤ïoúæWöåñùå D)6µ‚uòÒïT½Õ\Ô™´ƒè Æ—Ö;o;iå¥}ÌU¢Š•·oú»¼�5,•E®È �Œ•šž��s9F ñEåæÏÜyûǡ΢d¥ÌçÏ~õº”=ì×A® ß¹›.ÜqQÀ(¸Ê%åѼ»GÀ8³8½ãŽÞÐþ3ÎÖ˜¤žûù¬åŒŸŸ“ë?ºÇú‡P&þÇ˲ü­�>þøßùÕ_ýõÿÇþÀ¯ü((ê’±ÏÚØ”å»,kTu†{Cf·+E^Ú¼÷‡Ã~ìØ¶·Û ·Û Ûí†Ãí0†p½\ðôô„§çg\¯—p|»Äc#‚œÖYcðÿk¿ù?ùõ_þÁ?³,æ»?ùéøüÝ{ìà’µ>§q´õv±x¾^ð�o¼Áñ_ý.>ÿâöm+*ûãGÑ>Hdþögo`—ðÊ}ßq¡ÂdÅ ­èãxö�ñ“-õƒb>½õùÉâã�ŸðíO?Âïýô~çG¿ÚáT JÍòÑË3¯Al�E^ìá)¢¾ JÏKÜSh)æ+{ý|cª\$„Ý|ý#(×zȘtœ($ÄÒú]öãO>Áår‰–ØL^L ý|A‚¼Q”ðÅn¿��!Eö E+®!J<�uâ_”÷>´³Æ¨ïɘL‘,õK¨;X1†×s¯+ÏÄ.,He|€ÏnZ­³ˆ&p�z–iiZ¬wÑ‘£•DŠÔî%…ÈYGUQ&8pÌ}wéÎ(¬ûÓ˜ðÜâ°tCPdL’ÍYh°ÑM¤�£CĺþÖ¾m»±f3Ö8À²±� e@Ùa,9Pxò8€ îF± å0Æ Ömc‹­Ó�²òO€ï²,%[ÝûœÓ~ì1÷þ8D¬Gÿ“ýýzY…b\[×g¢Àb3 Ÿìÿk•ë@"Çžøô{©þÏDˆéšÒ¹‘1€MÏ®œ !L—¯g¢.9 Äë„?—uÅ‚àV°,ÅþT¢¶xï»Ý6ìûw„67Ôô˲`±¡½L$~-Ë‚u]c?Xá:ÁªÝ3ÀQp¶3¤,ùÃë Èrîwr„#µ�á�ßa§£íRLŠìç¬ô�ޤþ+AIÞG�Û¾ãöúŠ××Ün!á8xçò÷`k×Q!î·\ˆÌ€ïÚü§{�g†™³fÍš5kÖת&`Ö¬Y³fÍš8œƒ!�ˆY…Æ�7ær#ÂçÞ±9G¿úÇ~ýþ³Ÿ}þÃ÷_|ñKÇá>èbK‹YÈ.dÖå äHWÖÇq &%Ö¹¸Ùt8Üwø¬° J/­n$ Ç j‘à p!ÿÐGÞdB ƒÅX�È] ›\€1–Êz:ÍÊ—e3Öx‘›7TÎ\2�ʵƻގUȶexçpÄvaçrÌBØ[±,6l˜™h� â§ç7¯Eš2u=®löáôdÌAD¯DôJÀ íÁùÔ³gOÞyª>O ÄzzzójëòãºdK²í÷ ;J;«T6¯=;xWÔGq2I{c Yk­1æBdž|Ðg†èÿæ¿ñoüsÖXScÙ=#g0ðäÍ®Y³fÍú},:ŽãWòãÿê¿÷ïþõî?ø÷ÿÆÿëùùÍÿá�ÿÆŸü·á»ßÿ"g½± LY•yH5h_ƒJ2'AU˜¬Üƒ3Ž-Ç”€Ž�W�œ£³wS·Ûöãe1Ù(Ý(±u±_18¦hÑ¿ØNä�HKÔZ¡+'…àÈÙÇŠ”VY+Â3N­N²‚·ØÅàéù"ηvmiCª.Ž!\ÇÐEi±ó�瘔ù©‘ÁïÌqè; ?ƒ@Á M9n9Å–©À §�zx±ø µVø\¹‰ˆŽ�>ú‹]p8ò¤!Æc&b”ÞðˆDщâzó“kô—Y’9ctHŒM¤Ñˆà¡,4)°vj¢®e’~_0±âøgwƒš7�âŽ*%;Çö·¤Þù� ”¤vbãNžwùš²ýkð?Íפ0ÖOÊTªø–èà ²ÕAA¨‡Sû7\\u[ŽbÑšd—å÷·†ÍaÙú ºÚ´VØ@$I�îÎñA˜¼\Xg�üÙ[X�…¹ Ú×ï�ÌÃúî±.+ÑêÈkýq”çà°NKÕÿ‚e Ê †‡ï0á{<¢ÚÝæ÷¤ö³‹Uùö‰P–séV@dðœ~¯ïEˆj|#¢’³@ x„{Y±ñ$C>�áëº6Y÷9ö Ž)É Ç ˆu&º,ë—KPú/vÉvûỢvOhAo®Ú„‚³ ¢g"€ÉñX.’H ÇïgN�™“�Yu8—I/5‘»^žLþ¼ô¬¿ëî;n·W¼¾¾ÇËËk$ºÈ",‹³Á²øÊ¡ÁçïÆÉÀyÄ0ÊßWó3ÇŒ˜5kÖ¬Y³¾V5 ³fÍš5kÖ,€;v0ÙèÜs ƒM¤c^_Ÿž@.…€bP|ññ!O�õ'Ä #y1j,óâ{1ÑÏZ±@B"/¢&*D©«\ áÖ÷œ³Ï.לcôÖÞ­õÞ[s®}~‰„Ãh÷ÛwŸ½Ö,ÆècŒ>úh¿ÊÈ`Ó´Ç”wHÙ�lÀ³|`½,ó½œ8ðA->ƒ*”X9D®áS)ÚÍ~¼× ÿM§Jì8mŸØ¦ô]íäˆü�ORÚ÷ôxŸ˜'Þù ¾OÌ`nìº÷:pøìÏ«òZÝ�€rÑÏeÕP öüv;„¬¯Â¼§*þu4ǧ�i÷‹Öü„ŽD£CÅ•LÀ�(ÑÆ¦©ª5ª÷ÙÇ{)§f‘£(4¨Àãš`ˆjÐ2ãÔùþÔ_ád�O=Öׯ+QóáXÆc48ç‡ã‡ìä Œñ0k𿟷X lókŒÐhr¡m^8ùÆJ6­jz gÁ×c}¿(Èå[DTcDøù=FwµcÚ 4~}R걕×"Aþèý¤áu«¹‰°"�œ$,�Û×.½ñœ¦Ý{‹è¢ZfbkîÔÞgógîÇ"+Ò’Át„�°©Î«Z^|í_·wÚMfãî`oiþÝÁÅ|}îùìø×` •ïüŸ¦©Åä)7U?�µx�)gÈnמq¢õ%ÜÎË‘ˆJ4<óÄõôR:!­Îmõ{mÑìäUªËÊ¥DG×€˜cœêøÄ}¬qÃö,‹?‰ÇL0rÊHNî¶ç¡¦igã”ó3GÄ}î‰Ñ9DÃs`$oظ$°ˆß³` sˆ‘üÚIˆz”�?§&¶ç]fD!B(P$ïUâ“Â_£`R7Q¡�p‘@ÅŽS)ÇyÁáp…C�A¨çšìÁTܽMû,•k�FìÐ!Zä| ÄV[mµÕV[mõÚ©�°ÕV[mµÕV[0 ^fГ7𘧪º/ÓnzxaXõB̦i÷¼Ì{Rb¦œ²¤”%·æUvµz¥Úžt…‰µZã?§d "Y(»ê„Е_äÍ‘žj`ˆY`†‹ÆæÖÚú½ÕçæP°þ¡ÿ¥d�‘`ªCó’ºúŒƒú¿VÝMqAU-³+å¥Xö*Ìf½ß]`šöØí&WͰoGiû5¨0‡TYÇ¿X̪:û¿ªb‡`¯Ú–Üö�«3ñÉø2)Jlf«¶Ló>€ìJÒÓ%&eN”8 ÐI�yã›Þôu?òC?òù¯Îê›Àܺõ4îß¿�e9nöV[mõïº.Tõó�‡ÃçÿÓ¯ÿÇ?àÏNÓîÏîçÁ{Ö�v›/kFoˆUYÙµ7€žœ „)OØïö¸Øï°Ûï1MSË9WÓ«m9¤ÄSU­à‘ð«ä9b Oéì¼»þýr÷Ûfñ¦ÖˆcþûPd`LŠ"`ÙïóMM™ûÄã «‚s`d¼Ï¯óì›Ðº5ê¿5¼ÎÞÃÂeÅH8<�vé^ 8¯¶ÔD#¬J}[OKOéõ^‰`síäÍ?È�cbÆ­›·�sB‘ö­TêÔ¥3™ò:üçµ/Vô|äõ“´­#Ú1£ñœ[ÿ÷0¸'9<í ú* h=žmmÁ{¸JˆLÐÕùÕׇ=Ja×@ÔíðµÇ´ˆ hú@�pÙ·SÇX,D2F’Èé 6ÎëYP-ÌW‡a­LÅ>N0’ 4¤0jÐÅàðߦ>jä[ô]DØ]ÐuKtu/..^PÕY€…TT[, ù©S É®´�ØœPªÓJ%TbV‘J€n€˜ÌaÌçsUµ•õê\hkûjù/bD/Ô¨5 øÜTýõÙ�“‘ ˜S˜í¹'h¾L¨Ÿ"ØŽšEßIÌ´²š�÷ q»}ñmŒQkò@U–GPÿD7…ž\ /�”P?«F즩=7Ú=ª·°þ¹9ørNþL´Ã´›�òÔö_JܾÒu¢ê=Vt°s»€Å#<ž@a®:)·¹_Ô,þÍ9 @4õë�ûGaž­dsõãÑìçoOÛ¹’œ @qRIJ,í|`.ý{©Ï±æÐ£(Nç)¬žéðŠ[mµÕV[mµÕO­Ú[mµÕV[mµ`YH)ƒH0/nGè æT¦,WûËÝBLó4å2/IÕL³&Nš7bÎ Î4X¶®º+ŽÌÞR@”�l`�ŽÚ\C}KëÆ @¦j (˜«’Dƒª-¿±gÁ÷F£¾R€;Ð4J]ùO¡GÔbX5u¸7kRbk0rve‡ö|g1ƒ\ÑÚÈ1U�5•Ùö‹Ø•ÿ{ì¦=¦ý„)O`²±‘–‰~ÚŒ·F*ûï�!jYœX«®L=—’ªm}S¨’ÐB_ƒþë|€D ”Êv@«¥©?¬*,E’J¹„êþƒ?äCþÙÿàÛ>Ä£¢îQ *­[Oáêê>®®îã')'|«­¶ÚêüÁy>þž¿ýõïøÓ_ü«í7†9ùì½§‚Ç wt0>%±ý»Ý——Ø_\b¿¿@Î -C]Èêž'ONi‡¥ '¯·m»¿Åß‘z‰ÜÁ&’ëè!û9Û÷>8€ªY XmWû¾Õ­ûÔ2=¢¼Š]šÖ÷B[×ÛñžM�€:RP‡Ssk�VétêÊnëU܉¦øìKšS#õõ0�yí6Þ\Ý<«¾ÙÅûvÈjŒ×ª  D …4@^W` âÍ›7Á9¡ϲ¹æ¼ «© T�³ŽX>‚Õu%Ÿœ¨ö£;9q¡9?¬ÎÁ8Ÿœœm‰Bg¢ú¹b©I‚ nŸ ˆhqG5®#œ?í„1\P�ú|Š×]�ƒjç_� œ !Цlnàs³ÆÇ`�î’¬¡WuQLg.ϺÕRdÍ€Fr5BÒÊiAuX…ÆQëäF÷Â8½&Q�u3G‹�¶¨Öå=ƒëbq‡‹ª,"jÓÜìÏËlW‹³¢fÙnã`€¹G“‰9“©Ÿ÷u—šGNT&LÙFª"»*î«ò>±”ŦæfTûÉÝÁR ³®»G$' L“‘ õ{�\ì®`8UþGBAñEäÄ)->÷9bq;ùrò¾˜s_] êö-…Ï®¯${¾ôý­.´”a»jÄûsâ4es¿™vHSêà¿(T:èodž÷* ¿v.hã«äÏlvNpáöo  õ‡+«_[N¥ö›'H v3ænmá—¬‘.”z|ŠoŸù­¥”Œ$á.?‰;©\e$Ü5¾T0›‹ûX Gõ<^C¶Új«­¶Új«×^m€­¶Új«­¶Ú °,GoÆ¥Ùñ&Ë€4@¿ì)"Rf”9{ãÝTGMÉ’C#‹ºjÊ#ß»BÖ GÊH¹æÊ§Öë€ýh!_?'º¨²ÇtÀÐpÅ«W5ÄF™¿j ”ás¤Ú2׿4›E%gÙ�Ö¯J")u;Ý^´º¸Â3©ÈŸ¦i‡i·CÞM˜šõ%û6ô1Xom¢F{ä°Ñ­™^]€G•PUxÖºùÿÚu€:'`l³ý�Û1¤“�Øóª-SW Ƹ§ÀãP}×û½ÿûý;ÞñÎÏ ŸvšcÙþý71íöxøàîæ°ÕV[ýdÖÀøâ¿þ—þ·øcþö/ý‚/’n÷k÷˜®ºˆaôŽVàÈl“/..°¿¼ÄÅ…¹ÃpbƒŠ˜jPLu~ ^ÛÇ ÷ÉÈ sµ&€iâ�GÃ�¾ßJ»;k»œ�ÔÁhNaŽ�ßÕÁ&J¦IŠ6òc.{WS:Ù‡¸&hÛíà#�‰5€Ö[­]Šw;ìáp£®êijvëUáL@ÿAdî ìæjë%cNFóQ¹ö U‰›7oaÊ ‹Û–«êÙOl1´"6´v³øQ©J®†=YSÕr‡»ûáˆu÷„K&�i]Á? Eu‘²q¨îM©NcXAU[·|{0¶)öÇï¥Õ÷FÑ ¤ÖsAm�dû A.oÄ �®T»�3’F¬€ôk;Ç:�Áö_êIµ:àÍbÝã5ê/ÖçF% h¸X; €^ÕÑÖàë`íçÖº.nܸ ˆˆhsÙWã§ö¬!E0M ä ‰rN™Ú:½xÆ{�f™—t °=íØvíLÉ ¯i’K)XæÇyn w»#P¾þóJ`¬¹ƒ1RN D�êî š'4¬¯£H,¨Àp‘añMí/Ü3íëç@Œ5hNÜ÷±>ïØ¾�ŸQJAJ¥YÝKY ¥àx´q«Û“™=öÆmÿwF†kÎÕÁAœ¤PŠ=k…¹„ña³~¡Œq1ñê>9× ±È42c³ÄñR§ÆeïW€[õkñç6¡´y²’jT”'ÓË’w²èçOr’öÉýþÏ»œx#lµÕV[mµÕk´6ÀV[mµÕV[m(ËÜ=¬w˜ ˜��\uB˜j7CZz»µ6Wxh"TUŠ5e–"ÐÉ¡)ÓlÕ•®ûâÍé´°¾(…,áþŽFAYÊh[½²±]ed‚Vj™¦­¡Y·Àä}nõKHä Æœ‘'Wðš¢HŠú{ì ƒ#WK}oäL9cJ™yPìX±Û[ÆÆUÔ€§`2¶x(Xíš~ÅÀW Ûâ®ü¤1Ú•*ø@N$à¦Ê$ÛTox%³ÑlY—ã1 &EU_‚ê{?üg}Ä?yç;ßù) Ü\÷£ÛqŠ'‚�7o=‰e™qõð.JY¶‹}«­¶úɬ·øþÀWý­¯ø#þÚgîçÍmVw0£,Ѳ]›Å:»úq7e·NÞa·›š+ÌËnÓô xvÒ!U[hÄû�™ã²ì+PÛ�ðþ†án¯§dž©ª:�DµXÕ¢Í×ûÑ™�·£(¬ƒÕû`í_ÓñŸÓÄ¡užüYZšºÒ»«Õ‰ªµzØçjëMÕvŸ:0«ÃÍ·­"è­íöJ ÿmÑô*ú«šz./.1åì@šŒ¹ñÀIfÁ˜"r´ýŽ<’ø„Ø1Ž#…ÿ�çZÿ)X+4§†¶"CwFÀ€Þ¯Ôê’+j�ÛQÇ“ÛØØïµBOè WS»ú^wõ]W‰ÆL iÄÐJ,¨¶ôu�û!¢^ w0@c+èúÉ hÞOá´°5vØŽñ¼¯ùîñ$ÐñšYoUbD¼x×kp:� V™íÃeyÆa„úøãOÜ9�¢ªRJégE"ú3rʘ§ûR°Û©YÕ“‘—wºoÏBD„Ùíû¡€Áq>v,"`BSd3s³r±�ã|ÄñxDYÌVÍ"¼œ@QŽQç.U�jà°Ý',. ’°í–kTí´rèêïÂ/åÄ ¿>uW9î5|g}>͹;çÇã¡�NÉ\Ñö;ìw»æP7Á²Ì(‹üÌbfPªÄ‹ä³ŠÀÒÐV§q˜[»#Œ†wÝ`jÄ»Fè #¹B|žíóX}v”"XêsáR d¤¯Jâʨ#�L;#„ïö{çÙä‹»#$Û¿Ä©í'…yî¬ÓÁÊ ‚èÑçáV[mµÕV[mõS³6ÀV[mµÕV[mXdC ÂXÆ’�(²C);ì÷L8å�ýX RZ“Bž-iÍ&x qÜ-)µÛ!¶¢ZSDI[Þ®Òˆä#(D!Q̳BO{àcÞpü¹©t(dÌ2˜µ[JŠ´×5ÕyC0y£f2•'jÛlª*ñ,ÐâÊÌjêή&ª�s_ècQT¼ñÙ�NÀÿzDêûº{)P ¨§Ún®ôÔ�mÜÞ[›¸ qáI)J«X‚4Z¹Fð¿9< 7ÝTñŠ}ûG~ÔGýÍïøöoÿµƒv’†½ ’ÎØ½³_æ4áÖ­§1Ï÷7"ÀV[mõ“] à/øÏ¿æ«ÿÎàÏý’ÿç/;6[`–¢WEv%¤T•¬ÙTú½7Lì®°–“{ 9ꘆ�Çk N�«¯¨ìYßñß# Ù5Ú:ZsíÛ÷£ 0Úgƈ 3�Û=ØåÜn '`>B¬Ì Ç'¦áëˆèoV̺&<è°¦0™í¾Ü¶såh0d­¯Ìì™BÈšo`\ ·W_á©ãýZ»=¿» Ú?p·³lm‘‚²"ž'^§¤çô³4db× yõ5 àöpÈûw^å 4£¡q]Ð~~Þ ª|Ü­*€5¾VÚ5¹>Ö‘¬Ú#%|ü»`<�:©@š @ý�ÔßÛ¸���ÐJF\ñqc tâÆfœ´Â{û¥)hÀ¤êo0¬×Vàÿ˜ï¤8£fEüðkZTÏ^�mé\,×ukùþ9Ìü�™…™€V Zø§”ME^bˆì!y׉·»�]%‰‘–ólŽÕžg·è÷�š²Ç£øu*d‘"æ>°,(¥4%|Ut7ûÿ ú�€;@“çí:„C„ƒÅ|ćH4î±õû vî5ÂG�®g ç¼;´ƒ®ü¿.*à\Y@Á<Ï8 ÔŸÝaÞí�§ *ö]õu‡ÃJäÌïœ\m÷=�}fYÌi¡”b úâä'P1³97�÷ì7½ðÞ?)#CÌF‹ço…=¦ÝJ9âpõó|Ø.þ­¶Úê'³ÞàOø²ÿñøÛÿ/_õK¿ð‹P, ·¹±æ w§nvã¥Xfpu–1g@÷ ”n]rKïú™¥T¥ŸO+ŽÒ9€â•‚¢F8º€b^1µ¿á6ÙÑ f L²l¬ƒfÿ_ãeh¸§ãš-TÎ+ð°¸_í“F¢€êª]-ÏÍ>¾›‚»JRž#Úü+U·Ž$ˆêêC×/múáí6æ"¯×£¦MU^Á_ 猋ˋfŸ !õ•ð¿éû®!€ƒ¦Ÿz–µ¡ôÒ@ä�ì±&sº;BÝ+&:³Ò[¯¢ýHøïãáÇJ9DÔu—»$ÔamÊé!‡¨GWE¡;Vk5§HHPè7 uŒµF„ˆ�{ÕúŸT‡1–šéÍÔ¶‘ü×ó°�ëÔ‰ m¿•™FÃQld¢‘¤:ëæ £ªŸÖÄšpžŸž“ÔIÑàܲ^ê@]U¯-C¾_8UÅûâ?÷÷Š ¿UÒƒ µk»Ðø3%È"@ÒÇA€©î™FKî.±›&wš˜�'FNN:ðm1âíZª+‚;M“Ÿ·™¤�e"FÎ;L»=..ìœ^xnß=M¹ÅKS#)�#i4r›ïëú¼Új«­¶Új«­^;µ¶Új«­¶Új+¦F�rÄRÜæeFquÂn¿a™‹ý)¥)AŒ$®”O ¬ =)Õ¿³)]¨½)œ¼�”š�b8õí­*qÑ�qªc£vhþ®Èë&âZ¹UAé†$�«>ªj´7EÓŠÐ*�¸7Ù$X.› §‘&ìvfãœØsœW6ž±y#=4±ƒ=îãi‡”˜š:²7ì¢Ãå4×þ3 âV¶í½AqÊU¶"Hp,èvËk‡öİàÜð^(.>úgÌßúçÿô{ýÕÃã›O4œí8� ‹ŽÍlÛ®”v¸ysUÁáð‡Ã•;JlµÕV[ý¤Ô[|%€oúª¿ù¿ýs?ÿ ¾©Þá÷º~_£¦ê•"( 95 ¹¾RPE+ *>ÑBë=oË,ŠS$”âDp·¯ÁâŠjL@Ë8áÆÍ›4jÉý³¯#!œ:ì‡ÅWWœWÒ!¥jÝv=ÑþÇï[[;U€’§âäÔk¶À×am?Z«@ÿJ JªmÜ#©ƒ»@ýNÁZèÞ]üédMÕb±áÛÿWâ)APy êçÅà$Ð :¬m+ÙA›3FBM<˜kfúÚª‚Ý4\†XøÖ�i�ƒ¡a K§çÓ™™…°º�}}GÑÀœ®8%�rÖ"Ý־ω€ `ñ¹ôŽ›Ø© O‰'äÉH¼y™�SÂ<Ï ãËl$€"˼8°›ü�ûzWÌõ¬«å;XÏרÿ)ÎãÒÏGøûršLaž‰¸='´yh5Ë×Ù¾ÿ>f½‹ŽîkàþÜ3ÈYðŸztY%7Ôýªµ¥�G�\]]áx<˜òž óqBžŽ~�Aûžyž¡"6—»ûûƒ`)b„‚«އŽó1ê\Ã�hÈsÉ´x;Ž˜~AQ¸®  c›�‡‹‘ˆ[47B·gZ¾-êd Ï33Ÿ<‹@`¬e�,‚4™º_<–bJ–4¡ì¤¹JTG‰vüD[”À÷C£«ŒÝÇóï\ÄV[mµÕV[mõS·6ÀV[mµÕV[m­Q6/–»(E\ýRÐ $ή¼—n $½ùë1¶ðH´Ïµ¿�R _kÒÙ÷W…†Ù›…â„D)ØŽº­i”õ�ýÆ“ü_œ¦¥®Óh[|ÀP«hÒQR&ìlë¬ñGKÝ×âMCi�¦ªb™²e8ç)»JÄšr¤‚"®Ú’Q†�ÛØ§¶¼u{ª“ÀÐd¼FèÑÛ¾ãø¨®ÙKúšår8Ö­™ CfX¥5|RÖÍÅárSHõ�¢¼PüÉŸò©âŸ~Ã×ùñ¸¼~Øà3µn-8…çð‚—·pqqË\W˜çCˆ¨Øj«­¶úwZŸàŸõWþ­¯ðeŸñ ?ë}‘ÛÔâRÜæ™K ó´å ëʧZí;ȱ(ä*1]0Šß˘ƒøÖgQN„ÌŒœ)ÑJîªaz´@W+STºð›:˜é$æJh·„m¢ rÓàÄ,cÂÄ SN>gîŽmÁÁ¬�CÃý_U1b�þúµu²ú}œ¬„©PjdQ�‹Wª¡æÀrœöâþ¯•ÖñÕåãY×Ýbàü]Ÿ·nݲÈ¿ƒ'‚˜;¯mÝg)Mz6z©‘&+‰€¹ÛÇ^cý¾^Û -ÏžÚvçoxñ°£­Ç ãúFƒ�˜šíûð ±ÕJÏ­6Îló¹Ñk%Ë>NaL»Ë•�çhëÝ(a=£úRÛ¦òx¶œY®wŠëÁ¾MöÙ2Œ …ùaýuÛäø¿&Ü�5pÍHsæ9'&ìÄÔÓu[—à,PÇEÅžAˆ€ýóv çnÕŸ·¥+,æà$ƒÂ³Ï¯�ä±, –¥4'� ” pPÿ÷9ÄÎ7ÁÒâ l½?哨s‘¸Š¯0ï:Î=¨ôÇcˆà€fûKDf¡�•âÿä„F#'Tð?9©9å„ìŸ%"˜�G'Ì8®p<[B)‚©,Éò…àNÆ­nSYJ‹¸:0f¨¨Å©¹³Bu‚1†ÙÈ"6?3¡¨4⊆‡›èha$€ÒÉK dN D®ºï 7Ç81Òv‹èÑ'vŸš°ð2&T#)àÅÈ"Dö3sD`¤ÄPMÍI�+QËãætE°^GAlµÕV[mµÕV?=j#lµÕV[mµÕV¬Q1/‡ÃŒãሥÌöE¦„̉2v5ÛVæäЍ•jmèé…¼W6U½9“*ÔÕ1ó<ã8/fq¯@žvjnœ28P¨eÒJý¢kê|ö^ü*"µÊ Y’ ´ÌOgî™™k P¢dö�n™Ù”$ëÞ|t&� J#%ûãÖ̯hÃLM¨ròR”j!€®…9 Jo’ÉJ¢�¡"f±IÞÜZ,«SV®hd@•+WQ.ÐRˆ¨|ʧ}úý§ßð¿ýÎãq~¿s}ë z… çöš�ç„ËË 7n<†R Žó–ù€R–m‚Øj«­þ]øb¿àŸüÃð›~ÎÏýô¿g¶–ì TuJk*  Þ*`à˜™1§ ê3²�A…¡¤=&v9™vr%ýì¾ü¿ˆ@âú^Ã_“’²à“*ñPÏÞƒ¥ÚŸ;¸Ë2€”)1Rfä˜Õ}æ¾X�]ªÞèªÖÀkxE':�»#M³u‡BY0ˆö{~”×Pr¬â˜›öèN°èû(û¨8!AÛ¹ÒïçpóæM# JpB�úhÇ£‚Uõ{#°H+‚D‹wjkCw?ˆ1«h…vœÖ÷÷HÎlÀ6ubŰ t0,l£ŠžžZÁÖ¾i�`Ð+*=$ýÚÕEܯFrŒÇŒ:™'Æ]U€Ú¬ÎÅÆM+é³ÚzS­v œV4ÎÑò*fØùG׬“NH tºÀ�ÖÿkRÄø¦®¦–p®3щ+ÅÉ4qfuG'‹>wÝàt•sVrFo¶™æÑËÝOª=}‹#›;4{ž;¹…»ƒ³5§]ŠŠý!^äv¬·¤/Å0ªÁƒËY´Ìo‡×<ß^ÕTð„Ϙ@¹…Öƒ<¢„yéÜßkw0]ÍeU ß"Ëj„™ ù Ö§æh`@u%4§”QmY‹Q˜çFúVUhRP!Ÿ£“ V;F)%LÓd„ð”� jc?/3–£}6ˆ `'Bb#’ÊøáÖFRçx­¨»Ó±»0”zm–F N¤ÖJ'Ø÷pUÞÄIV¢õü ,‰‘²Ùóg*ö¬Wçê± F$XºœØ1`bpZÀ~¾ÎKéónµðO£…¿Eª©ÏE5l€­¶Új«­¶úiS`«­¶Új«­¶óè"Xæ‚y.(lö´óÎìÓ„ÄÙT”LQ¡ ª¶¨¢~kúÖF>ìà}mRÕÇrœ±Ì‹«ù&kŽ•ìñ£ÞÌI U� S¤Ú ¨œèíïÕªL»‚r¬žl¯½¦9âMé=çâ]®™üÂ4¨Ñ4gf†L™‘!'† ‡ûM·]O‰1eÆ~ʘrîÜ×}]PGµ|ý]s^Q³Pfv{ûTÉFK�D¦«Àöf[€�6p"@½¿N9aÚqs:¹3è™ÛÅð¿ÝI‰F'Šõîzì۽ϲ˜ÉU™ýÞöjˆ©qg”tÍ`Göþ#ÞñôôVH« VU\\\`7M~ Öd�¿ÍÉþBY/¬¨GóF¢a{5ŽØ©ÄûœF]#“"Úàƒ%?ÁηJÄ0â©´õU<— ¿–ne¿æEÅ×K2þ.nÛ`Öp‘å4F¡��õÈÎc;qÙÖ¸œ÷ñ«»ïGÂɆ)VW'@hõIßTÉq,NWœ+'( Vü5zK׎ÿ÷½Ÿ„T§¦á”içô#—mç×u)¥«”²2'¥`KÏÌX–l®ñA[t�­oËR0;Y`I 9 gÛ|Êâ®e¥@unJk#81Ú‰D³Þ�„H0®ÄNA9_­ÜE;ÁDŠ­•E,öù%䜆¡`ÏqQÿ¼5ÑÃii×j%Dw’ëb ¯�¿‹Êÿœ3rž‚›Ù¨ÖŸç¹�Iü¬‰{yô)%ì¦ »ýSÞ!sjdèzoˆD‹W0À=ç ÎÜzvÅ>Øæfæ~L@•È@Â< ¥%U´ó\x$µ¬²gT)� »ŸÙñÎ�$anvhÏýœHˆÔq²,ñ9Jš@Ýfîî ÐF\‘� "þýF^æ¡z-l[mµÕV[mõšª�°ÕV[mµÕV[Ù¢ Of…™’©ðQ,Å^ó±à¸+ÈY:Hk9íCîý`ÕºR�·F.w«V„|ÂÚ¢•Ú„ÐMæ×òuSÈ5]|kGëа-�Êm¹¼Lè+ð-žïÙUôµÉ§\ý{ëw˜bd)ËZÕT-rNà”ºˆê÷õWKS%v ·vüdÏŸÄ+x0Ç×…·KltסNÝkZ×öŶ!M¹þyÝQ³>¦è`TM˲ ”¥5ðRò@Èo!%Ð`ñ-´ÃÍ,ŸøÉŸòÿýÞïú®Ï{ç;ßù™5]ùÑ#p¦ë~®BÆ.Üea·»Ä´»9°ÌG,Ë¥Ìn•ªÛ$²ÕV[ýŸUŸàӿ囿ñWþœOþ´h÷£*5…{ ñ-ãý2üûÈ„«Dt#³ÙúadU↠²_ÔÙMÙÒwÖ3iÍ‘§p_XGô`‡©Fưm;+0eFqÛåjùܳÊGÂ[ ·q‡qR�WSKçªþŸv9ãÁÕñúÛ¢šÒº� .ñžÐ ÷(I¯ï\gÕ›Û‚›U:Õ{o]ùD'%U3XL‰J®,®àpUÖë™›~ÿ*€Uÿ_ãè¡1 rθ¼¼ DÀ ¬¤>I"¨�!s~\žPX3…¼¸1¬}ÖëÈë<}aµk³þט;_óßPkD ÅÉ"1æ¢ÇµiTÿGÒF3íC:âý'�Sa4ºPŒëº"•´b¦Âqª¦Ÿ¥þ[<î" !¾�üÜkdO©Û$#áf½ÜŒ†Ð1.IϬ„B DtêhŸ½v¾ n!ëcDç´ó'–8?Àœ!îÂU�§ì]!]I…M¥žó„ųì»ó”1- ¥daU ùÅ…!Ì däßãñˆy™!¥gدçl¢B?B‘}Ýox @YAœÀÙâØXzDX}µ¤oçz‘Á¾ÿa‚@#[¡‘PДç§à�¨ï]–¹9"T‚qWéï¦ y2G´ä~#J¸Àn·Ã´·ïÌdî •„ þ�U‘oÑ ÙIÖD¦²''��[¼\';K�*!¿GyÌM�«ìùFZ4HýSŸoŽË‚e^°,3T,Fψ¶�SÎHœÛÕ¸…Ó˜6�\Ú0¸¦Q%$'<øù·©¾¾Ç T=ê…á±s:¼o«­¶Új«­¶z õú·!Øj«­¶Új«­àâbõÜÊS¢˜šÄ”íÅÉ)I·N¤óô¯MÎuWèàÕÚ¢­ù—’YlZóÐí$›'7{ÏÞ„Ò3J¥ÚÉ?ÙŠWQµ�J¡Y¶ ]0˜ê •!'k hWm�YÛ nʳzä–÷i™ÀÀiŽ‚oó‚y°/ˆ@ŒFeÝz„åß¹ö:ÁM ìS«º¿6Áãö¦ÑŠB¨&`V>Ah®¹¨ªÿ‹ÛŠX¹�NULÓÆÞ›rªzð²Iô¡–�øÈ�úŠç_ÿúïÿîïüŽÿ ˆªæiçi�<íÚ0«ÏÅ •ܰ©h¶Új«ÿÃêy_û/þù7ü~ðßÿìÏÕœ{Þ2`€N�õ,wZW®2 ³ª>̉�37Òž5^In93¦]Â41v9¡4ûjž¼n‹u´\Љ9'‹…!y1#ñ¨Òçï`5ÎdĨ&˜¡7 *1cžÏX†òþcîêä �¶[¯¡›Ldxwfã~uw×¥»½7ÔI œ·Ìô°Á~ž´*•°!ÆJë~vÜ[¾y%êÚ��‡uÍå�ƒ•ûúsN�pƒ»|uLJ°“#šÂ8: è)¥çÖ*0,î�¬Á±¡ž8jà·†Lì €€Z ¨è ò—–¯ÃïGËþvJ§„§ŸzÏ<ûž~ânÞº�§»À­[ ‚<%ò4áÁÕîð¾—îàÝï~ ïyß‹xß /›j¸�Ò”Ù}ÝØ÷µªÊ}UX-#Ô@ÎNhTwتâQBâw�»RýˆF–8CÞhfN≿$åqÁKñ"�ϲ:·N)°Ñ´‚_‘2³V[u˵g”bÀq‘âñ(aAjÀxd¥[Ë-¤ZÈÃbJRÎà4¨ï o7ik>fÂ|<6›{‹:‰ë~Å#ø|ÌÈTãêÏb9U»y�Es°>ކ– „%8rÅK(žÇ¦¯¤–ª��×é8•’@Pþ×çÛÓèf ‚yYp<qœ�XÜ¡9ä„Ýn�ý~�iʶoÁ€B€9t€;å:¿¡½>›£@}ÎjÊÿª°'6⥸£‘±Ú8ÖsÊ]\TëS�‘GŠh0#ý°=+-îhw<0/s{Îar�>Mæd�38'{Vr·‡¨Ô'ð�×Ñá&ÈLàÄmÌ*#ZЙø†ëJ6ÀV[mµÕV[½æj#lµÕV[mµÕV€ýþ- V�D ‹oÒL 2]Q±Æ‡ƒ €ëÊ Á@A(Puë]�ù“1›ØÔš2tGHÙ”)eLi 6’Ú Åã¬AÔXë4�J÷Ó¢înëÿ® ‡¥œ’ú뺘M50’�iÑôoÍ'·›LÙl c·ƒâÛ8�“Ðd[u_ªÞ|‚ƒw�+[È@‰ } ªÐ*é#€0¡¯r^”—g¬}Û†€ºY€+1 õxƒjgZÁñæ)yv%±©s(Q�JÐ"U94t—í�G"Üîù×½üŸù à;¿ýÛ>ï½ïyÏ'£Z \kd»úÁ#z]Q‘ÙÜêx´Œaò†cÆŽ.û{UPÊìÍäÅHRÌRtk°mµÕV?ñb¿À‡ÿ½¯ùê_óù¿üW^ív)…Ë0ÿØýÖU‹ÔîÙ‚ÞO™‘2a7%WÎI©“²@Û¥„Éí”KÑ 8¾f^]ç® aaÀ "³€a6ðÁ�oì‚ù³ð²ÿËrV©ÛL9c—¦ÄÈ)c^ÎǶD+úD­^«üù–·~ÕNTt_în›OÞV™*¦²5¡ ±;íouðÙmìk¤®Q WW¥šOUaŽ* Š¼Û!ç©ì†#¥Š3ùð´º?²Ô 8®­âÑS]O½ž¨×b™â¹9ÉÓéz/|žbŒ0jŠg Øýw‡„µ-|´ˆƒjןs›ÞôüŒý |ü[ß‚�ý¨ŇØÁir·éâç–˜ýç âd+gʶ�L�)G|×wÿ0¾é_}7¾á_ü ÞöCoÇÛßùB§Ë©M»;pÄs·žsFêçr;7©.aüQ7ƒñ:ó3µƒÉõò=»Æ®#Ïíºò‹ÝÜ= O H XŸa�y²\ÓñšI) (Ô±hˆÌ–�…p” »e; çe)¶~[Jj ª�»ß”$8î癹†ÍËÒ”Ý)§ö<@  ídmç• ç³Ï0Ô\!ϹçÎ;Q‡aû•  p'T¾Q�wÙ2ØŠG Qª`N�Èé5Ú é×€ÿ�DQÁÿÃÁþm-¬jD™œ¦ÝûýûÝyšy ~wJÙœÜ žÿ¦òϘüúÐíþ©Ûá·ÎÉê¾?#Õó¡þ)Úç4„qgkK˜Í>ûu&5Jb>bžgs +ÅgcFbAIF¦ŸdB*ÙIÏ�ÌD Äö‡LrS ù1È)·¨ƒ�ÀíÞísÍÚ�gu/QÙžO¶Új«­¶ÚêµT`«­¶Új«­¶\\\„†€�þË< ¤lŠx¾¨´†•¸"É€äÞ$oú ¦¤¢²ª[«Öï"Ê迦”HSnŠp¨šÝæ*g¶çè†|Õ¾'aO›Øës·å �/÷µF©Ã¸õÆŸm£rÏ¥mŠÿÚôK¡ºnfêJü¤1�ót7*' îP€ªí°» Ô�£)„1¢¨Ö_ Y‹8Î Z£¶52Í’´¾·ªXƦz8f\3,û>H=W\]ÕrC™ îÑËÌüâÇ~Ü'¼p÷ÎËÿü»¾ë;~Ù�—_þ ÿc® �'ÙB¨ëëÑ‚—ðÉi$¬À2òýY ¥@´ØßRÿÈæ°ÕV[=ª¾Àû}åßø«Ÿýk×ÞI)7à¾ä¨�ðˆ¢h€ wwÙlýe1EìB ÄÁ1®„5N˜vSJȉ±AtÆÅ9³ÝfhÈiV8îÉ@šLY³©á ~½÷ëêFÙÉ„na®•W·2)[´AÎ <1®®f¯hp0ÀÿÕK+tþˆzQ:Y…(œØìúë8T·´¸w2çœ`×Ü�Xtëúº} ¶,ùSвâ¯pÔUôÄŒ——„Ÿ®©hü¿Õ±cN–Áš<ž+Ô7}ÃZàÄ¥'ìEí³÷וóz_£¶�_]ÝÏ£S€ÊÖ5ÌÓO=ŽOøØ�Ä/øyoÅ/øŒ·âòbïks0�´Ú§(M@_%ÕãRl!Íõ:Ýb@bž2ÞúÑŒ·~ôñþÚDÀÝ;ñ?~í·âï}Ý÷à[¿ípûÎý!ÏÁub\(’ÃŽ=’ »NuG.´kSOè55)žk�#¬‰4®mWä Šþ5sE@™Axû0,¿âFø·¤”îû`k�"µ#¹eey/ÜrÕã5·,ÌK³êÕ�o–ÿê¤i.6·»¯ô-þ«Z´K=/}eNdD �ÎÆ4ž’Ìjg`/7�ð„ÂÄ}ÍÉý‰HŠ[q‚jwâªrJ:Î×´Ž.X©ÿWà?PÇnÁñpÄÕÕ®sD�" §ŒÝ~�‹‹=öû ì÷{ä<5ç€ú½`4›ÿÁ)!ÄJ¤” ®|WÕæ �ÐTääìJ&¯ã^É\æâU°”ð¬áäŠø¼ÖÈDjO?"3¸ð.jŸaàÿŒ¹,(KÞ®Ä;ö9 ’«øAÑÁv>%�ÿ(}þð+”Ùœ!ò4aò?F¬‘5:äüÌHDÛ j«­¶Új«­~ÕFØj«­¶Új«­Ó4AÅTÛÌ yÊ8Î €©ÙCRož*�ò¡i€ñÖüÄäÖ¼qà7w ~ö†{ŽcT„÷fq„þc#�Îç­"¼$´×Í-ÛOÔarÕÒâ TºƒAûãûÙ²|âé'ŸöéŸöÒ{Þýž·þïß÷¿êËwn¿~”=¢ÖÓC¾0Ϋݮý,=÷á uŃó4�MMkþ–XX p•h Eع'ƒòLõUnàV[mõS½> À?ú îÏ|æ—ü¦ßþ²úý5³ )©ÍGjà‹ÍnU}ÙlýŘrWàÃî…)3¦ÌÈSBžsñÜán#½>™~WÙô~_)jj]ÀØ×)eS6p÷á&"†%C³ûîKkž€ê°~XƒÕzr/¬ëƒa‡õ‘Ú=œ@¾ÍõþsækF3D›SC®ŸÇ+ÛûJSð¸"õH… ê®€Wžvp5G¦Õ�ãZËœp×;ÜÀ²sK ÿ¯ÁQçÌòæÔþ?—ö^ê+½ð�ëO��pZÉ£Òϳ°6µ×÷µY$ܸ¼Ä'âGá‹¿àßÃÏù¸�0¢eÝ6?6ý»£Ì˜Û˜3%·Ë—>`¢@Ze(bñJgPZ´Öc�]âW~Á§àW}Á'Aøßð�?ˆ¿ú·ÿ1þÑ×};î?W4[3Ä¿ hv…)qh$Õ†7Û|FO¹nû£è‘ÍŒnÙlÿ]ÍÃd¹šÕ’ä9¡±ÌG)•âÿ]ºZµ¡bM±iÚ5ÛÊ –D{¥-¨Æ­:»cƒ6Ná¡ê)+6á‚CkðGi¢žûÔsCs�'þ«°Ê§UÎëu‡ÀŽ+ƒÁb„†"7uÁý7{SUz6íàzÀ¤Ìt�²4°<ûüs÷>é™§¿ï}ï}ϽíèçÜ~éÅ·4µ |”B²žF×îp g¬£&èQyá¸Ñ¹låøRS‘%ÊÕÔÆnEÜ8Ð:I:(�‡óë É¡6éÅ­ÁDZ©Jɘ';f˪Ês°ÕVÿç×Çøÿýwú�Ö—ü‡¿ýAlæaM‡ `ÿÝU)å=»œp1%”’ ˆã2‚[L^MØçŒœæY¸B„n3�GM{ÚÔõýßu ädDƒ¦š¯à$÷l÷sSpÈYÄ@Y–fyžƒSWËß½whóú V54­ov+'tçÉ¥:Vüºvo®öÊÝ’ŸÚŽ…ûeh]aÝòêkf;Áï…ážO f 5'¦þ}¿K¤48Ë\\ìÏ*Ïßú¯_—øöЈçS³‹�9äÚã‡Úm”®_XtNè0¢êcq~µ·ê¥Mq+ X=GPI«üÁï�_þy¿Ÿÿ9Ÿ†Ý~8ƒ�\5,$#«˜sEs)ê±ÏaAÂóŒ¯k´"Sþf6ç•Ùâjn‡G @ Æg|òÏÂg|òÏÄÃyÁ_ÿª¯ÇŸý‹ÿ?ü#ï²ý1�¦Q‘mÊá~|4®Gš5"…5a‹èG¡¯H«S‚F—¬¸º©äR ßÓ¯m%mŸXIˆ¢¢¯fõjçQNù¡áÿª¥:?�5€“…hƒéë$)‚3 IrW•sç�@ýú²õê&Fž&ì÷¸¸¸h6÷õØ”²˜ ßóé;Q8Ì Ú�½ˆÌ8¥æîRÏs³•ïs½×¥Bš»”ˆ ,3æeq‹z#!°¬¢Â1�ëu³œÏFØ]IJ)8ޏºzˆ÷ïãáC#”¥4Ðz¿ßáâò7nÜÄÅž‘"–eîP@H†ŸÙö,ËŒeY:1Ø·¯ˆÚöÔb6’9É|Y“`T†ûe»Vêk\H3·Í¶Ï@~ Dælσ×Uý•`_Ïq³ET4🸑̧݄)OH‰‡ó8îG<ï[,] ½×±ªÌÑd«­¶Új«­¶z­ÔFØj«­¶Új«­¬ÑPze71¦i²<ÃÒØÖ” Ù‰×ô΃JÙˆ€» XF¥54)18›bª$€€^kìGwôj½-‚« ÀÐÃÍöö“n=oÊÛæÞ*žÕ«Rzff)æ—ö½Í.9çög—38åÖøìâÁ‚À¢ð $©ûÜÚ>¢#°*5v ¶ùªõ?ššóäXÛ×õGð~$ V¾×+jDC<&µ™‰U3Ó�TÅÕ:]½“§É²;)ù6•~xë¹&Ò�’ð™œf½è%=¨ê ªúøSO?ý=oý¸'¿áþýÏýÈýð§½øÂ Ÿp<žQ ®×Ô9…gÿÁ9è'–ȧ½ëhiÛ‰áL_ U-ÿ™ÕšâízÓžï|zÎø1ÐbK‡Õ³:ÉÚï×gn ]á:ÒQ"ɽ)®•Å-g¥EŒMë­¶Úê'XŸà¯üwÿíÿü_ÿ‹JŒMñ{pUµªMŸòžý.á¸ËXÄæ¤™ ÅïG‰�@ »Ì˜¦„¥’’�ÍUm|2gPŸÏȬqÌF½3å|4²]NŒiâ�gÞ#mU”YŠ­S’”bsÒ4¹Ý¶Û€ßp…€ cX-4+ùþÁUçk]¹Àœ]_¬îM£=ÿH ª·Yfî‹›0NEÄfWÅ@(B ºE;³ÝÏ´üÔÞ½LÓ®eE‹Ž¤ÍYpFÆw¤aø¤g”¦'ÊÒÓÿ&ª£ÊgHytz§"ßFæ"[»K€½Ñ1§»Sè”}ÔG~~ó—|>éã>ÂÍ!Œœ™ Ly�Æí´ƒivþ²ztÒÆŒÙ³IÜþ߀¤=@ Ê—æÏƒ8š|�VZü=Ù�+ãÆ~�ßð+~!~ã}þþ?úVü‘?ùwñ�ßý#fEÕjÎÛF_F�'`P[ÞÅcÁÎè‚á Ã{;û´¹)F’`]* $€ó §‘ã;,-Ãkó4= "¢Ýb¿´c?,]CÖ||n)AJ_<¿Ý®Çb@5(¬Á;aATARPŠ+ösÆ~·Ãåå...±Ûí|ý«Í] î¸ö,wôø³—_…m(PdAQÄM¿jDœ „ÏËŒãñöí—Þr</Ç]_)όʹÄá5L~æ,mïíAÚpc‡P;¨^ûáä`ÐbªíïJ{‰1•÷„“pÖ= ‚xºɪ«A×úv¥îzGµY³ÿ7ƒ);¡PL˜ÜYàœ ƒ‘jJ˜süïk^¿ÕV[~)€ß+" È›RÉ{ ððxX~|¿K˜/¦¦Ðç™Qšš’\eÈØï'L»„ãa1°YÌÅ¥ºÈé ¶;¨2æx·{„ÏybL9ñÏABvBÜ90"àD9Y¼Á\¥H͹ ³Edî?8kËxwl1€,Ü_0®K†uGøùjBmó*…5Æ`Sïá>ß3ÊÔLcC¶žbv(aeG–Á€½KØòç©LܳÁUíÞ!*>—3../Vˆ*zæø¸W}¿bŠQu|ŠAèÉ gVaÃý3fÊ· úú}´Š– öìªãë+ ­hö,uwªdH öêkÀ‡|È›ð{ÿ“_��ý˜·¸KCqßNÍé¨Y ÜŽïC™ß :¾]î:ùÃî} ‚²„ÈâšÇ~µÝ'sù&ÒÅs éI€s¶fÓ% @12€¯Á¡‚_ôóÿoøE?ïgà|ÝwàËÿÐWãGÿÍû@ ßWÿ>_¯Ï„‚]PTø×µ%5µ;Q´âàpÀ‰¦§KÍx­62MˆZhç%¢7†®¨“ÁÍçÈ!qmkÿœvÓ1“>Jѽ~£cBUCÛš£?c°Çi$J�·Tg žñõÊR¸qã7oÞÂåå äÉZ¯Ë¼àx<`žg”@äêøÜb˜’_GF>`I-?¾°m[YìydñÏ•¡Â�Ìl„ƒÙ”ù‡+\]=ÄáxÄìöÿvžs'Έœ<3�¸©Ä«›FUæ�\]]áá•‘–yiñ9O¸ØïqyÙÁÿ�á‘• P�ìzLŽÇ#ŽÇ#ʲ ¸Å½Yù§"ÀšØó¨}Zß_tE §yêÏ8í¼í×ùäÝ#åºâß &äš1õç˜àÚÁ�ÄqޏprLœè“˜!ÌÐjz†Hèqk)&6Ç®­¶Új«­¶zíÖFØj«­¶Új«­j{ åßR°dVˆD" "KSTÙ»€¢ïG¹Rß•½E°1ÛDÑ!ï­¹¢ÕéZÅ•4¼nž«©Û¥†ÃÛ¿zÓb”g‡þà*˲� ÜÜ8(ÿ™»úÎl5—–•©5#2DtðßTÿ)™’�<Þ Û1Ç&ÛöKøçЈêÍjõëh¯mýµKµŸ íu^í·GUVF*‡YëHð­9%ô±Œö¾ëæYµ0]?hhr1µÆ”5>­Å8JD(‰A…»’¥’D8yÓ�û÷¸ÌIU¯DôJ4WäBUð4wŸ}ö™Ï=÷ì�xýK/¾ø–w¿ëÝrûöí×?xøðqÈ£l�ãÕòÊ?[+F�nwÛšÚD 5•ÿõ†�>p†0Œÿº�¾VÖÓ˜¸Û—ýœ7šÂ_‚‘— §�uPèQÈõÅhÁ½ú¾ú^ædêÇU.pû w(²@ÊbäœR°¹lµþ³¿ôçÿÌ?þ‚/þÕß,RHD "**¢ªBDâ“þÕ /Ý}Û~ÊXö)v?KDMåÏ $ϯÎîhóâË÷ÁDæÐn´‚â¨ÍÓõçÂ}þ�ó…V“©Ó8—¥ý=?Ñ ,žG$��Lf“ŸSÂnJÈnQ}ÿáÃQ�_çb­.¾¦QrW›z�¥³3ûùðúº¾àkHŒý^ò5„(Ä_Ý„[s%ÆÊ™¥û­� Ä·�\A߀¹jÿcØüÔó4�‰ , ±:z2Ö=B`Œ,ðqó�¶¯;£Ö�÷œk�ÚKú¸†¯£°•€(5Ö@% ­6€­©ü}­&ÿkVw%U*ž|âqüæ/ùB|Þçü|¤(ê¯êÝzAÔ/+ Wïƒ^ýÊáÇ™ý¾Ê05£-J(ÊÕýwõ³ÚZTV'Y`¹‹r£òÊO ]¾˜.¸hlq7©b—Ÿùsß‚oýû¿ò/}þë?ýµ¸÷àÊ `çèJ „�å+ _�×õD# ÔX¡Ö‹í\YKõ+©õd…´ºL4L¤ÑzØ›BãB“1ôCf8 Å[Œ!s¾MÕÊU‚ _OTc]�ÌLû®:íò¾o–¸[ÄšÃRjÎdidiöÄtÒLdæfÅKÉ»ª¤-í´Ýú° ¨«ö�(mÙ´ÕZ²mùY‰•¶«»jF.àê@jNµ]]BM´ßhR�ÙQ�Þ¨ ÜYjÿ<µ®Ù¤k2ÃÜ&ÿT•´dWª¨+YHiȰìêûOºoÖ×"¥æ¿^)ô „)ÁtDï{ê™§ü©gŸù—^=þÎw¼óÍ·oß~ãƒ{÷^<ž®Ø@×ôÈô××j¨ú;ô´A~†¿²zO'Œªÿxj¬ÁÿÌ?r«OÔÿt.Ë`l:Ö3ƒ¼1Jýà6í‹g¢ó_O¤a óPÞ!g:±[±Fx)³“6bÀV?í*‰È_ü¡øþOyÿxÓâÎ1EE�¢rdfñëæê»þõÛàs>ógË"ÂÅA£91’ç%Wå"'Æn7ábbÜ}8;ˆÜï}Ú/Ø!3œƒZ¶'vÐÙ¬ÚO 1m¦[t_?=Õ{‡ˆ`Z æ¢1Œt7%L™qïþ•EÄàqÐjžtB•G i¸?U±y›ûƒ‹@\+UráÈ[èVécLQÜŽÜâ‹|]¢i@kžº+} ¶¿dþñ °”؃_Âúì÷{[¿áäöpª³^‘b†ù¼¹–ÒÀ QíšÛ£ñÎYP«žY �™òÕ†^ƒò¿�´u:€€„Ïù|~çoû•xü‰›}æ (™« ôðnèÃDyðC`Ü©!µ×UÕ/2Ûº‹*(É�@ÉNn#ö÷Âïu•Ôšì¸IXéròàG!ü.ðÅ“àÝëº$uðA‘+‚„=¾ì×}~Åç¾ÿéùj|Õ×|k—n ®~mÂ÷C[�Z6ôk FR¬/D£ŒÜÉ¢-Û¼žñ‚5?’ÏD~�¤ÔÓtM\¹¼¸¸g;iˆ.Ñ@–×øœ-²ÚÎS‡N|:×F·Œ±uÎÜb¶Új«­¶ÚêµU`«­¶Új«­¶ZuÐUç$ã/B·÷²µÙkÈ®{­ölÙöiQÑ.(²X³º¾¤øënÇjÿ®j®fm¬=V [%²«3Ò`¿ßTeUØÅÕâW¡R Åš}¦üWˆg ×F‹eÁòJíGCöäÙ<ö`M;tºqžäpí�Y¥ÇŸþ>(ºý£”»UokÐÒH‹(Ò\û˜ÖœáG5ï›ÊÐnÕ²´�¿ÕÝÁÝư†Ž ×F}UFV’ASöfpU õ¼Ë8,ÁaÌ�ïã×Ò Å�¾ ÀM]ÑîÆ�›ùCÞò–\Oœ»/¿üü{Þóž�¸wçî‡=|øàƒ®®®ž‘<!ý bÌ׌¥®Ý¢4/œGÕö¿îó+‹dqBY�j1ÿù¼Í¾®vwe÷ ÎÈŠç£)Ú:Î(gÏ1öºº(ÑJgªíœ˜v öýÇd ¹²±”)ÕZV¶y~«×j½åÛ¿í_ý§—7ÿò­ÇnÝpp߯ˆÊˆ9<¸:˜éÇ.öÓ6%åLÈKÈzΰ›.öîÜyè$²S�vð·!@`V³¨'¡n ÞnIæär±Ë˜v1š¼+×Såù|æ"‚e©j^ ç„‹]ÂÛÞwgu¯]O7ÝIÅæ˜šz2f}¯¸O§Hº~®ï9èÝYÀæu%$'÷‚S{jŸ ÅÈ~Ý É"Y XÉæHÖ÷ãÂÂRêQçHÃZð`�­%èĉýQöÿë[ ãþ{4®y4D4ð_Jñ¸&i«ò_F ¸þ÷O<†?ôŸ} >ýç~ ˆs°»OÄDQ�܃Þʃ‚ÞÙ\²ÀÉo¾ ƒ8H`p'Ušç¿±>UÍâ_Å—–%Ÿ8ýƒÜ@EBñ¿¦X,ÀrZ鉟Ò%6@�$\´@KÁ³O\àÏý‘ÏÇgÿ{oÁoþ=ÿîÞ½²¥µˆß³ë±•a�=¤1�éø)�i÷æ˜È@ÑÉ¡Å�„ÏÓxÚhå ö»ºŽÏ�¸È†ºqë±{ªª"¢QiÝòêÙ#¨\Ï�ʃoÏ5Õ¢�lÓ�6ÍãI—·.qóæ \Þ¸�ýnß©ÙUí"ÚTïu_™9%”,HªHN(¦LND!‹ÿP ÈbóŒãlj{-Ô¾ˆ.Š¥Ì˜�G®Ž8¸5¿ˆ"ï2vÓ9%‹Èœ×µóR¿f˜YRˆÙíõçÙ¾cž‹#ðñËSÆ~�›7nàÆ�¸¼¼À~�Ûëê]�{$L,Y)z+ð¢¢8.E2 Š”€Ý.á=/ÜçÝsóI[Û„Y»YÑâÝ+)#5ˆv×®,ƒŠ]»�½Ò`C8å‘ðTc”,GÝ�˜‚¥º§Ÿ;ÀWîÊìÝ~çÄ ¹ì'³lŒðéòïaÚÖ“Å�{:C„ à‚] FJ)�4Dç÷"Õ·û:ð¿Æ4Õµ©»øšñc~ö‡ãOüÑß‚'Ÿ|ÜÆ—Ù€F#ŽR¹B¹ÿ}ÀÕ@¾·Ûq§à›ïä õŒ@ÌH 9˜oN¤ÅI sHÌ-NÁ ‘ÚŠˆ ðe.f7Ž+`™Qp (Ýxâ[ÆøÔƒ¶(ð‹?õ-ø„¯ùRüŠ/ûJ|Ë·ÿxÍ�0Ç(ªJks�±m5’N Þ9ÛpX'Ô,RØ÷·Ÿ;1J@a׺�”ÚH'×áë†G3§išK1ã²ÈÉ£ÉÚ²åó0ŒÏ(æXОqÈ€úu&û˜ìö{ìv{اl‘óì„áî~TÏS*ŒR�ͤΦâŸRFÊ)›º½^Ãâï-¥èîq % ·K¸ÇÒ 2Ps¥˜ò„ÝÎùfÉ¿¸£†ýw) —Œ�tbMUÖ/‹�þ‹ÛôWRYJ„iÚáÆ�K\Þ02ÄÅŦ݄ÄlÄL1—µRê¾Ë0ßÔc¦šœ´Ñ ×ëH´á¹�È�ì €!Bg-îãyÖŽ$|~#�d#Jpp�ˆï'JÁ®?›iˆSði¬Ü·À·½=å)|< ŠÓÑH;}ËEEI:}Fäšgîú.é4ì!ö¡Œ±[mµÕV[mµÕk§6ÀV[mµÕV[mÕ£ÒÆ3I+À•Ô­¡*2d­VUíºÁÒÅÌ£ù¸ET;VÂçÕb�P’cæpâÔíá�`ˆÑêКku›‹«‚‹,­ñf­–ú>êVœŒ¾k5!œÀû¸Æ] â;8(®b\@SüPo€sñáò×®]®¤¾­OÉÞÀ—G"Ð5ƒ•D㮂˜Ì]äYÍt&ë·÷´»m,l©˜ìY¢6öEÑTäqÄ!kTÛþ›E+U [tÜ™‰¡äŠ»¸OÖœ. z@LšmõÉ¡ld�Äô€ x‘ˆ^xú™gßûÔÓÏükU½à€›Ë<ß¼}û¥çîß»ÿäÿzøðæáp¸y8^]ÎÇy¯*<˜B?¸o Ñ`<Û'pÝÅ�Á1çœ)õÞá?»‚¯:=TëÂõÖÍge¦Ã¯\y{æˆD“ zÄö�³ä�ÿO~½yÚcÚ]´Ï7 Ûcû³ÅlõSø^~óþý»¿„ˆþßeâYIïQwè8À¼”oyüÖÅçª*ˆ yfÌÀl¶ü)gìw¢Šû ¼�øº²{oÿ]-’!ˆ©‚×ös�Ù\ö» fê÷)ª÷–Ók>‚<œÌ~]D±sÀDD�¸Øe¼Ç†í[Ú�CW¹uL{ô윉u~ÕâW´K_G´´ŸêD4ú%µ|ëƒÃ£§ Óþv+g�TÜeÀ9›Z4ªêµÞTNÖãNc±¶€'c ÚøRØ¿0¾í¥:Îògâø__•ÿXEðTûË ~é¯ÿ|ɯù0»SL%ˆV°Nrõvèý <ü¡Ž\Çó¦Ý�ô N¾Ïþ7Çs,ÊÝ� Iàv“Dëð°ñÐbQÉ_A�€±€ T‚*Þƒò“ € ¤G¨$V¼þ©ø‡ù‹ðûþ›¯ÃŸú+ßHÔ€\ˆØyæcÇDƒ?Ñx¼ëõ§56*ÄKaå÷E•œR¯Ù¶\]\AùÿJE«k�9=$b!²“But¶ê›nóÊ�ãîóRìŽ23–e±ýZ–FèÏdæ�PIKkxÛw¦öŒÒ¢Ãæ‰96'䜑§„œ'pbHQ¨–ÕÒãEnk;"S¬§œ‘³©üSN`eäœ1Mò4aÚí,:@ìPJq7�,‹‘hŠôØ6prÇ€R:yÁdžý{/.Lñqq‰‹ý9ø_DZÚù?J��Ö8)¢:«à¿”2Þïê8„4⇀sÏùí|/2ü¼~§ý;m ©­¶Új«­¶z ÕFØj«­¶Új«­`Õ4á�ÅÞ-q- 6ÙÆ†î „?ªƒ•dkV�4‚«µmÔ�³Ç�M³ˆäd�3®ÍÙª”@°XŽäb¹áó-+©çË7ŠѨֈMº�ÚàMЪTÓkÄέ]Nët\ÀßÑJU­A,Dî€1G¾7•ª•f×7úJõÚW¿Ka}h­™¹Nò ¬f{Êd–ÃÌ�äÑzþü¯Û!Ѿö{ÍqB‹@B$CWÇkËmÀ�š«ë^‹ Ö¹Ÿ0©–Óc³g¬>›Ýç":¨êŒ+½à�¸ àÀÅ´ÛíŸ{þu»çžÇ «ê¤ªÙÿ;=¸w÷‰;wï=ñàþý'އãÍùx¼9/ó�ežoÌórY–åRD¦ #jù΃$n¥ª®'ÇT f8»¨»_œ|¦Žã@­©JÏ�;@kÌšøqš\?#’\C!ðv^©{Š*0¨ÿÏG¼r'ìv—N °÷šKÀ‹»lÑ[ýT)Uz¿ù8'~À÷Ut²9­Þþ®Ûÿà¹ã8Ø• &‘6ŸNÉ�û]Æ÷üЋ.î§Àæz䵺ü©ÏÍ:»ø¦‚Þå4d3Ó«`9QSq„¬ÉÀ¨E|þT¼û½wÆm@W>Fp?®_T{|é×NÀ8?÷Áç]ï{Ã�ëP°ºWø=•n…îªÀÐTÁp'Q’6P_ÉÑF•º>Êü7æ@�Ràœ¹�Ùæv?ðûÔÙ�@&£ƒŽ¼-ê¾÷c¾v °e‹Žó~� ŠŽT¾ïRש"Øí2þÀïúUø¿ÿ‚OôüwP"¥d1 Ç÷@î~/ôþšPé„�.™Â>‘»%2ÿ#©N¹T¼ß>�"#ù:J)=ë¨�à]��Ô ¸¦²·ýwêCwK( (º—äÄÈS¶ç\Nç�TÇgs}ôßq_Ñåf«­¶Új«­¶ú)W`«­¶Új«­¶€–óŒ*hSꇦŠ7€L¹/'°EëØ“ \ôfb}EÀ# cƒž‰À”ÆE%K³û¯ªá¨üOžÑ˜¼‘ÖdgR›ŠR Ô›çó·˜�¥Zã91C•�œ@Jv\X»J¬6¥ÂWh?³Ðdr*P-Hêû©Y;[’„6×i¸`pÚµq2;Ý:R© ´ Þf+Օįì/«hp_/©âÀÀDD;"Š1 „DJÉw2=öÄ“üø“O3§0@¶‹þWW‡éå—^zìîÝ»·Ü¿ÿØápuc>.7çe¹YÊrCDn¨È…¨^@t¯ª7zC“Š^*�TdZŸd#à¿–Wösd$Þtôæ¬ßÎíoqöõ‘£ àÂ…åÁ�¯Ôˆ\ŸãºþîH¼:·„ÓÝÔwf}¾ßׯÌóËrÀ²ÌM-µÕVÿW+"¢üÁïÿù?ó#>âk�ô’’N&$g…þû¿ñõß÷gÿðð]Ä™xA) ‹«Ùï)YÀÛþÍ H9Ÿwù¿¸Ó{´Î? ×¶ÙP+J,bÓqÁYT:èªÛ¶r²›·¨Bm–ïßý¶wcYJÿéÄõ%Zþ¯¤îèà]gô_Qwk‰Ì¨ö†øA¯eV`¤ý@D�˜-nGMÿMÔ‰ dó¥“÷”Jd6@E�r·¤ª·‰ÚçžKY–*ƒJÃ>¸5EÒâÉ£!³»Ÿ7íƒF�09WòBUòŠv+ô|IS«nݺ�?ù_ý&¼õ£?•Sb¼Á â ”‡(þ5ôö·¹Eÿ™(%£Aq­Ê]ù^×`�¶îcN€³-oÇMÁ[Zƒ¤Ø%®}Ð §UlÌ¥¾§RLML·qLÀr¥€Ý-°$д‡bÊ¥(D ¾ð0^ÿlÆoü=_‡—pK­qWvq]9¡”Vg9; 9Bù5_¶¢Â´S!>'¨ž®GTCpÑõ\>¿UœÒƒ”RQU!.JL R ¨€Ý„…€Ö]µî‘9Ûõ—òRÀÌöœ0›cX�)1ð?çìϹ¼RÌÖþ8÷ˆ¡RçWNHyÂn79�mªôiš�(ù³Lê$d6Õ~Jö=uºª ø2í̶_»Ý|S®3ƒ&ÂN.QyUA?M»ÝÞ\v™”íY0—9Y¬EUÿ—Êñ�«¿€Á'Ùô˜§æ.P¿£*ç+èoäʲ"Œn•@ôu7ƒ¶VÀ¿ý¥~— fÕrzWS…V0×èÑ‘¦:®ÔûÑq^ðàêˆýƒ+@etˆ7““{Uu—Q³óv+îz/bÊØoùÎH…´º·ÕYÕÆ|œBÎÌÔîq݈œ`·ža†W´9d­z?�B7›xò}dD lƒRW¦5¶8ÀŒ"DwPΜ ¤l\…öÞ�çrÍ{[pÖbåØâ„€óŸ×²€Ðã™Ð³ãÃwŽ1m¤Kt5ÄRuÒGÿÏ<ýþÊŸþ�ð¦|¾¯WŒnhîýÇw£ÜýVàá�(›ê^$ °Ûó3Üæ_üý®ø'Sv·l÷)rÝ>å‘m�@0‹¥hy`œÁzÐìXV²ùúKK³7™þlŸ¡‹VGH¾‰¤7@|ð‹( œ~ÞÇ¿_ýßþ|áoûÇxéÎÕ°Ögw p#ý¶¹ºZ—6+u:Y¾†õ1µó­/]©=»åÏŠ Hq­°Ž.ªóÌx¾¦”‚¨‘žªÂû´§PwöJfÏxgn*s"B.%~¹Í_"¶ž¬Îc‰ œ¯Ùï`žg�GSì/FÖ(ÅÜÇ8Ø_#°±µON)çæ×âìsrʹrMšZ¼Úè«*–ež�˜‰ÈO¥K'7gH)`·èŸ¦rJHœ LH*È%ƒcÞ=ÌÅKŠB¸œäÈW¾>ÎNÈÝ®Þ#ZŒ€ílp2W88M4’ê˜÷G nkûÑ}¢ÖD€s¯eU(3 Ë h^ãÚ3K§�4e~'0€%ôýZj¤Ö´8�~,—K)íÙ§9,Æa²…”‘²�'2�gôÄQ!’Ö. ç› ÀV[mµÕV[½¶j#lµÕV[mµÕVÖ (AÉã[Ó 4VUN-@+POk°´zÍUµ_ÁöÜüÖ?rÀxE*°>Ðió&n�Àò᫪¤ªdæyÁ²¸ æàÖn¿Ûí/&RU½õø-Q-‹»,ˆJ8þ¬Ð¬ª“˜³À%êàBT“a-‚"EK)ZDHU�2'Þï¦é"OÓEÎyOD“R�p¸:äy>îç¹ì�WÇË«««‡‡W—WW‡Ë««ûÃÕa·,s"&sAˆ9¹¶¯�;ÀIêö¹ßŸ^dŠG;´ß+°&òT ó<í1M€¹êbžXæÍ!`«Ÿ¼bf(€ùx|ž@Oè„檆´üÖ?ð7ÿ‡ÿÏïý‚ß’˜ßr8. "J̤Jùæ¢üÔßúßý¹"êä*jdÁk¯Ÿ:WSPþǬd‚Òîòk Ý{éÎÕ½‡ŽWiâ…#èõJk ñ8ßL)ßÊÓîñøÁùÄdRÅKwâ…—î¯btpâ°Ó,ø•0Èàu¼7A]ㄟWåózÚÒk&m$(mj(k¼Gù+T Êü÷®Ûå×[Du; ÷-u¢)O�ŽÆpe…�WŠˆ8±v ÿN ÛVõuS'�¬B‘ 0~ww²5ˆÄ¼oW¿øßí¯Ÿ|â&þúÿ;ð†÷{j\I@˜!w¿òò·BË•ù$0$_�$¶ÆIÄÛÆ`Ž÷¤uÔMw0hîõ¼á𞸨Ǵ.�³`®þ;¦NÝ©ì�vФ¿_� ó¥<@ÊO˜œDRŒñ–xí�}*¾à?ú:Ü{°øšÃÈ&ÄÒίjgÏÕ1‚áýçhŽa5‚J÷ †ñ·(êC ~ý�ü¿®“ýÚh�ኪ$B?§ª*ª[t†µožAYJW�ûß)%U÷;³®Ïæü5MŠR–¦º¯ûU³Ú›ÓXâ>?ˆ“›ŽG0›U}γÏËö\ÂDÈ9c·ßƒ85Õ>9°]Ÿƒ|>6`¸=ÙAH9cõ�â.nÒ@çæFPŸ§(‡{µØ‡i·CÚ¹ƒ3T YKÊ®4·}\héqKu�O ®Ž…†ç-{žJN¶ ß‹D(¥`YçóñØÈ®ë瓸îkñæ0Ð Ý…aMžˆï‹ÿ]Ék@ŒÃ¨ Ãd$Ñ^ßïqÄ wn¨ã^I'Ía…Æg×þ<Ð�s)‹PIeFkgç¨Å5L~Îu�H8Uüë‰ÓY=Nñoµ¸„­¶Új«­¶ÚêµS`«­¶Új«­¶z…²†Oÿ[S½^›<Äu;Zt{ÖÚ¬j›ÄÙ7SSE ¢‰˜C€X¡ÁJè�ûáÄšÕdWU/¥@JqgWV§„DÖèªy˜Ó”ÌÙ7HHÀ*kìvÔ7ÕÍ«€/ÎÔ©‡‚4å¿�ßÅOëLâ3ÇLk^®2”Ê£ênýÅL�§0þª�Î2X·WëJ*f�’‰»+ƒÀ@Am. ˆ•ÙZÃ4Ìצ†|渋ÚcÄ5ù~ìW.Ç­Ù^ÏÕ˜O¡‘ÿhÑËâ¯Îw}%—«3£�¯­jP³|&N±ay £ªJÑ{D¸0)«6‹µF}²«¤v-•`"æ«\ˆê‚½*öªšU„U„Õå±Ä¤l^¿L@f¦  ½ öRdGŒÜ¸4Lº¿Üë�[7hšv4Mç”�²͇Ã1®®Ò�»w._záÅ'îß¿÷øáêðø2/O,Ëòø¼Ì�—"{"`¥ë/ ?á©­o¸ÎG ^×§ßÀêá»é»Ý‚Š`ž¯0/G,óakªnõï¤R²G|12Ï-ðósšì/ûƒë¯øïs˜xä£?æ­ï÷ú׿ág¾|çêsQ³Øƒ=ðuÀpÏÒðù�N/"›>ô#¿òxuõΗï¼ü®·ýè�¿øã?öo®>ö‘ÌÍ›7wÏ=ÿºÇŸ}þ¹çŸ|òñ÷»‘o¾ñ‡ßþm?ãx<>7Ì¢<ØÚœŽ@ˆØ:~ÛÝÌ� 8ÍDRÒH"ëJOî^Á _Ý5I0€ÿ�”Vdµæ¸I1O©’+}}¥"P_KMÓÔÝ„TÏÏsôo³b9} 5Û�Ó%Êþ7i7V±<#RÕvøüwR¢ðßœ‚�ݺ‰¿ügþc¼ÿû?ÛÖ"@)å¹ý­(ïýH9�xç`{wnbÀ…ø–äCÉîÂLÀwb€iÀ¶°ìïË`ØÚXˆÜå‚à9 ¾�¨k?'ª@=_DW$�îkCÍeª®iÐÙ­Þ ¤GyÞ=‰ýJAÑ‚² >ìƒná/þáOÁ¯üòoÀÕA|Sœü@cŒŽÀ†©ÅèšL¹‚裣;µ8XD­—ùN2 ŽêäÁ)q¶"üäDŽߕEU‘˜Sa¹î– X€™š“ƒw ÈSÆŽÌ¢?O¶Öâ€e׳êë,F�*XojöyžÛz3O9û3‹“h™¦<�‰Q¤îK¥+i¡pÁ<Ç i7µë|Êd/�Œq<Î ÄnŸ#Ý%Nxh™öÓ„\ÿMì 37׃ên�ò,œ»ºß@i¼‹ƒæ1f€xÜŸêT`Àÿì‘JKS½Gp>žWñ9oø½v=-†!¸¢ÅcVï‰y ¬£ Nttò¶�62¸M6/Xô\FÊ !9x#=*‰·F*pß•ÿ3ææþˆ ÄAù?­ŸÐH72F1¬-ÿÏU)ïÖ;¶€­¶Új«­¶zÍÕFØj«­¶Új«­>ùYTÿ÷¬ø˜y� LÆ[Erиþ+€ÉÜmMuσ¢�©7ü¢éÉvEb�ú"ä�Ûž§h€Å€ÿÐÜHœ\õ�Ciòf#»¥'à‚+«¨ªÍðþ‰>^WRE³­¯¦`×JÌ ÕF¸JkÔ6_WõÆ'©7nƘ¦ø÷1$(D–Þ&nÂ:(­‡ÍëÂÌš6¡4·êMr³†ÖöY„Ç÷ÜyDžÿ ÔìÛõÑ%kâ�ª&"•‘8au p6Å+°:´‹%ØšrkŽê!�}ÀQ;@’‡Mx B€ýà˜ŠM)�YU©d)˜ È™ :©€-«¡n&!)“Ñ2`fÎL”A:)$©"™c/)”¡ VRQRU#1‘&NœrÊ|óÆMšÒDóò‰(çœÒn·»Øïö‡ÃÕ³/½ôò>¸wÿý¼z¼,e7\;�tÐÆ 8�ÙÕ-Ñ×ÊëwÔ\sЇ¸ªtÑ2ªMñEØí.±Û]¨.$W˜ç#J™·›ÎVÿ§Ô4íüÊ,ª—ªºShªÊó_òù_X ìIÀ,Zš-s·X<öøÍ*ú€*XBhJÕ:1Ÿ#tgœàÔ”öÔ@»ÇŸxâ¸{öÙû|ñ–—Î'}ò‹·_¼sïxœq<pœ�(®”­¶Üun®êÑÝ>OÌü`·ß/»iÂ~¿Ÿ...^¬€ê„@ç¶—È®ãܱVÊ÷´nÖÛã¾Ö‹"¢è;2‚Û¢d€±¤Ñ‰£Ó ��ÂHaÀ¾êJÙÚ¿�Èî½”ÍÓTm�VóÚéÜøJÎ(äÎFä.à \mŸ÷”5²ï.ïu«ø¡¸Y'q!† )ÿµ“LoÞ¼À_øS¿òAïßHö& ¡/#Ê{¿ÙŽy™ì÷ÅíÿÁþ… �yHìêéÀ’¬ëÓ¿�ØkÙÓ€ˆ'%e0%€“gÁ Ycò‚6úÚ—©åf5— héãÚÁBs.h¤Èƒ�U!˜~ û¼`>Qä)PÁÏþ™�ãÏý¾OƯû}ÿó,ÃùEÊäk+föh ­FN}XN–XÚ׉«Ÿ*ŸÞnOï¾×ÜÑuý È)ß.¥@Š:S¦dTB¦|<-]U¤Ä(Ë®¯v,ê¶û“”Ý‘ÒIMñíÛR´ÍOÔ�磭ã‹Ó‘ìÀÉ\"82o‰ü˜™û@‹arâs6øÈ)eìvGÌËŒâÀ÷¼, ·mZ|-mDåÄ}Ž­¬¤!RÍíü³+Û'ìòSP£Çg±$Õ�PUæó²àpu…£+ÿ+ð/*Á)ëôY´þ]�cܶêà�§ÜܪzŸ˜ ‹¿GG÷—Ñ¢¿ÿüd¾ó¹Mɨ]¹\�Üí ’ÓÃø6fÏ9‡ƒzL–eÁ¼Ì˜çÅ&Ô÷��§>Ö)§¸þ¯òYÿ À_ÇŸ‰_MXÝV[mµÕV[mõS¬6ÀV[mµÕV[måMkP¬màÛÿ_=ò_›rñõ#qÀ¾"(é†÷[Rte….×´Cî+”R?pÍSî)ˆê¼Ä¦¨î¹ê¦ˆ©Ö�¯ìAöPõLãÄ›Ô!w+Ëùëb *á¢î_mÐ4— ê±sǫƬ>WTªG?ÔZZqèÙʉ€$ •Ô@…z ¨2+W¢BñFg²Ö4“ÁÛjÇ&ö|5€õ( ·ñìÃcˆ´:Pcê·�Kêy½Æ@k¸Vᣎ¶þm(c„E×z e…à‡×ò�¿0BСŸ;VZ�퉂ï4u%bSž®¢%:YÁ¯4Ál¥W€�íj'ÿ°ÌYC6,@‘°Š2Y漤Šm#)"ò °ŸVD³�!R¨�(³Rí}[ã”)%&‘ fa&ÎD|IL7nÞzìÖãO<ñ]zŠ˜žÑã‰ù±—_¾óú—^ºý†;·_~öî½»O>¸ÿ±ÃÕawz�×¢’^ N ¿[#œr;âsfDѧöÖpJØóMì÷7¡P,óËrÀ²ÏæßnµÕOü>NÈy_ᄂª“ª²B‰t•�ì`3K2:Õ;wŸ·4ÂTFk•f¿.�N✥áýÙIv)g즩;ñäŒ jÊ[`°ÃŽñó)¥BDGUõ¾ˆÜÏÓîÅq�qæB=;pÃÂkPŸ@þûÜ¿–©cœë)¾h÷«š±.`ÂuXC‘ƒÌ×`ó]ù-g,Ñë»êûÕ¢Rê]%(�;~:ñé5C4N‹§Î)5»�Öã]9ZõþOn¨OgD8dÖY� �À¦x…�¸üýF|ø‡½É7'™{~Ê€\a~éŸ/þ+°¨)üµ`ܹ…¿ô?ßÁ7}÷=¼ï¥#î=,¸¼Èxþ™K|ìG>�_õÙoƼßÍîn@Iš«BþÍ¥‡;øŸ&€2¨(5œ6• ì‡xüàvÿbؾ(ÌN\B€G½Îr? „ëë�bñK%eÒ%ní ÊqÆQf;^³âã>êqü¿õ£ñåÿïo Êè:®gå×E]CZ¤”Ýêe¼£žX’GA½¼¨ÆI]‹7Ö7éʸb\i×[rÊùåR–…ˆ¤Ye„õY¡EÂZ�Ðê¹d”²¸ÛY�jnãÀ™‘J”3d·/rsb$2'»‡ؾÌKZcÎz ëº×Ï(DOµÈµb¯.Nr)Yža²Ùöç”0í&즎ó‡ÃÇÇãóqÆ²Ì €¯sjÊFjá“Ì÷ð¼DI-`·›0ívØívH)7bB%©*ë0ïWý"âÊûcY÷K›ŸêµD쟳çW‘áø×ƒ)g�np À‰u.iswõ¿ÇôûãÚ  0¤�$C{¾h„vJ‰@ÕQŒ†{-…˜s¦ÁÿêPgç¨øs©9<ì|¬ó”Wc‚ÁѬOË#o‰Ð"6VÏKpW‘ê"´ÕV[mµÕV[½6j»³oµÕV[mµÕV\‰ ÚÚËŠ®™‰m—Þ„3~±y%�4ýºÁ’±ÁÐ2 ©©õ�ÅÕ\tÒÜh]C‡æ…4¥MkÔVM˜í¦åVr³‹ŒÀ?€„¨¢¨€%4SŠÜ2i�Ö[�•T€@Þ•émì)D&´ÿò÷–žûÙ#ª5-¬LÞŒ•ÓìG„œÓÀµaKí¸TõrTØP°mUÖ€ÂH;&ˆ TÌn•¹Zuº2ÎóE+ ªÿ»ª=Uyy°Zªr]¼Z›�U‰¥ª1µ±Y­tkµ@<Èp†Å66E8‰Ñs�‚ÍrT ¡mO±›&ò$#´ÿ›ÏX�PTPºýg ±öº”´Y”F [ã8H¸¾<ÔAZ™D {Ø’5AÝ~¶ÌvN(»�î" P¬J4UfbÎ ºÕ¬ú˜ˆ>N„§Hð$ �CõñÇžxüO>õä-b¾A„› ºùàáÃÇßûÎw=ÿâ /=sçÎ�'îݽwk™ç¼çw†jë Q÷¥™Á2ëþŸU¬ž›8võ¿ò´Cžöþ�‚e>`ž˜çØTX[ýÛ<Üç=†‰`¿/iÍøµû@j$7õ˜˜7ãHÍA¦˜a^]aüúŽŠu=½‚â,5Ì/]�ÚMT�,&ž)ÍÌ D®×m·2&ìö{¨êàJTï—Rî߸qùÎ_872�fó JãÊx cSIrm¿™�hmøÒ³ÓAã¾Û~Z¼M´:÷> ŠSˆ*Ѹ>ÓÓh"w’!ò5ašLylî t~ï±i­º>s·•ÿ«ßGׇx A¨5B<ÌÐ5o[Ý>Ý£‡š €v€/ûÒÏÁ'}ü‡»b~rp=º`¹ûí�ÛßFriJþ¿ü5/ãÏÿ½q<ªÙž'#‡Î ðÎ÷<Ä×ü£wàk¿î�øÅ?ÿ�ø�¿æga𨇬]vqTE>M΋óu% =ÛJÒ`[ÿQ�d‘ÍgßÖ*(‚–m$Î ðòÏÕ:Þ *å (?’ÅAû˜| ·ö÷pw^p5Û:s)„_ôiÏáÛ¿ÿCð÷ÃÚ°+ÿí:ÐæäoÇIÚÄЗ;ÔŸ DÝec\ßBb<ÈŠ1xíµ¹:35\ ìvÓ‹"R˜Yìè0Ô×hJF»iç“™ºûôB¾VªŽ[´§RPÂÉojÿ„Ý4µ9ŠØ®7˜—a'¨ñmï•ÑÓ™ìø�¨Þ•mýæÏ PA’)âó¦‘l ××te_p8ÀDMY¿,sSÛîz–©=÷1u—Eq×´2<䔀�q,�l°35zʃÅ}\V·ªº^/" ð.ÃVÜ- r…"øÏ«ø€ºž'DÀ¾ÆD@Ò…êñÕ>ï,ãSïwk·�Å#´Ô(‚zÞ$‹£s'0ŒÃÐHÂm}+Ô�Ô¢;�ý)FÀ&sP˜¦ÉÇz‡Ðî’bàÿFØj«­¶Új«×\�`‚­¶Új«­¶ÚÊÜÔ'=¿·Cª7®Íq%V�X÷f‡ dþöÆ-j‹� ƒ‰@™!´xÃüĀׇ T Ú€x•ž+YíýGZí¹®™“+ S³øï º¨ÀÁ ˆÐFZ�àkàû瀄‚¤*¹gmÝ¿T%¹õ§žmÎ0€2¸.D¥¼ #Ó¶Ï‚„Ïø,pý¯SaÆ&=MåˆØ Ójß›¯¯Õ'*‚ÅÁÿ”¨Ûž"äm‚AÞÄîV–ÛP~ìÑ g0'„Ú¬µ&‡÷#|Fƒ—hU!�ñ�]Ut¬^+<+(ÄLƒ2µ½†ãpZ0•Puà~ÅЕ¨Ô¬) øê8„r€¤ZÑ–ží6’C´E‹¥Öx­›*Q\ÙFÒÉ,u[{ëž\ùäÇŒÃyÖT[³] õZi áÖè6ºÐ*G¹W°ÜSå»D|—ˆ^"¢[ß$’n$àDÄtyãòrÿ�üæý¾ùƒö Lä_xéÉw¿ë]ïwû¥—^ç廯»zøà � ¡U‡}?u1iÔ˜ášÓ}q&*`xç5çUu°ðsºž_L ûý-\\>pœ8bž¯6w€­^u]\ÜÀÊÞ¹dãDÝÁw@ KðKÐ@É 0Ù}¡ƒT‹[F.ôh€]D@\IEýšŠ«íþFžËNÏÞnTD©À‹Ý^záeyþuÏ”¥”€û¥”7oÞzû5Þ+V%,!F5åŸëbêˆzìP�²_�Ž@~›-ÉlóIcŒ¹ÏH¨wwxúê¶?�BR¸G)€iÚCµ h˜ð†xû?N\;Ÿé£nšõûã;ù©ÍšéªïÃ9kê:Du-Ù\@³¨'ŧ}ÊGâ×þòÏALqÏ N€ äþ÷€î|'Ò´a�.æõûþÜ‹ø{ßô"æ>a÷&�X@�) !üÝÿõÇñ¶½�?û>û)!FÏÀAPSúûº#q :xÆ83¤Ôó(û¢Ë€zÔéèr…ÐC-ë5”šc£€ì�DàBgG@ Øã°€ßʸµ¿Â< GEQ‚ ¿õ‹>ßû/âÛ¿ïÅNÖi÷:Öߤjöÿ,ˆnVZ)Òâº:¤‘H+A5ÆoŒªo`ÅÑS¯ÕnÚ]ÜP$LI5‰E7(€¢ÐÖÔ¾¯Ѫ~^¤¥*øó°ffWÃwB1…ó–p_À3cšò�I�¶ „ds‹ð½´g‡NÞ¬k#â~mÌKÂT–¦ªÏSÆnÚ�A€ e.Hé RÄÔöÇ#Jñè‚ dÊH”�œ´"j·úy²”‚â`tu H9wB@΃B_$Nu wÅãX£º2½“j“?Ÿå ä�ï�; høœ¶§áü,À@F'ÐBXP�X�¼1Æ �s(>ÿÄïC{Fi§¦( ùœT:Á$Ф=bBü/˜ç%84H#3ìvÓäêÿ½9DÂsç8Žm¿é4n ?ßF"Ýx�ªÇzÚOÛbj«­¶Új«­^Cµ¶Új«­¶Új+{øö¿ |n�šñÏhÝÞº­a>ZKx]U§yŒeT†¢�uN¨ %ô. šâ«�ˆÅÅ ¾W•9y&câì�¥nª  š²·ÔQˆ>ÚAž4Èí{× üî€U^ïJ)€ßîñJ«ñ *œÚéǃ9áÊ6"@ø†êeÀš»`°19PÜtß®4¥Þð4‚ "®¬‚z:Àš†ñk玕¤[çZ�]éR›žñ[w”*ÜI'+;~ë³W�›•5 �²3ýëc:^á<¦1ïVV1ˆ,q)š`ˆ Hh\™‘Ó°>êB…ÅQ�70‚D)‚²H‘–;ÛÏ�*Õæm”™}ts^¨är°_c)�¹»"Ô9BÐmW¡•TŠYªqÇ-u•kÔE!¢»"2éÝ%â=€=«î5c¯Dˆ&¨îL2T³‚2 é™gžâgž}šL*rñòí—Ÿyû�¿ý#nß¾ýa÷îÞ}ÓÃŸÔ â0Ê‘üƒ˜µÒ#¾Jd±Y;ŸèdnçûÝ%öûK¨¥q<<Äáp…RæífµÕÙJiBÊS˜[¡ ]Ô�Ci÷òkµÎC¬ ¤J×Üq`š²½®ª]ý”¥ ¥cWï†ùŒâ„È‚Ìe~Éï¹FRbçÙT³LHN®’”ÛgÑ•; Ó4 €ÃRÊýEäÞÓÏ>ûC ®tõgœ®ÎL£ã¥IñÊ>oóÐŒi¦•@H¨­w”t5Wèêû®›äu½@ë·àA±ÁÿšKÍæ¨àóòRN?síVò(Jœ^³‰- ¬ýu× wňÿ·ýŠSeÜÌöÛÆ[P'“”RðÜsOâ¿ùÏ@‹)î=“ àáBï| �/A:eO þÆ?¼�¿ÿÍ·Áœ\±ޝ ¡jÑnõÝßÿ"~ÏŸøü±ßññ~γÝ)5^"Wþ @ÉV[„ân ˆ«®9û¼_ËdÛ_Š�?¥¯Ë)8. ëq-eØI ¶~3¢ÝÑÖ^eä L Y  30ÀÓ%r¾‡å^Á¼XÔ“Âý-Ž/øòoÆËwçp¯ªq9}Ñ$¢Nvt`S»ËÃÿ5žGݹÁ÷­^Pmñkè È_ ttzBáñÇŸ|NI˜X¡ "œ'�"òkCÚW232[v¼Ù¼ æùh³g_¿qH€êªîÄN‘IÊe±µ×4eL»]·¤W�,¢âøZ™‡ç‹+ë ÛöŸ»6� �SF!ÁT&stÜ7`žÌ™ eFbj×—À^7qRÖÒÞ3MÓ ´7ð¿»rU»Š´ãD¾dN'ë�èU׌ìdìsà¿®b?êgè™g®ÓgÛî E+`ÜâO=ÔÖòÍu­ˆ�ƒ .XÌT©u=ªM D¨¹ D§¶Ë9¸Ôùú¼:!”¡ÀŒœ¦i��«ÿ''­cl_³ü¬3E;ÎEèµi¤»ÚÃÈ[mµÕV[mµÕk§¶;ûV[mµÕV[meÕ”­Òs(qÚT±†I·`�6¸QuM±Iׄ@j€2Á³L­ñ Þ`#æn�Îê™ÀÜ´iªE±æ¡7OŠg<Ž`mmö¤ *™0å 9À\][VA†FYýÕU¥ô¦NU~T;Q4…J2–Û{«’jÍÝÔ4—M©.Nv°—%8BN,Qcy?–ä9Àµ±–“«œ*0I ‚n©Än^k]ï‰?œ+½ÄBj]éÕ ;TH,î4 �Øö ÔÚ„ålÇ+ëOa�15ùXh³ÇGõµ,×ÁU`T =²Î*ÁÇݦNq�«;b¬¼ í•,ü«õ|ÛHâ8uq Й1ïçcàm„M(EÛ¹XÄ�*„â­­Ÿm�Èê°Àíü²zÓõy*à®ÆƒõêÔÀ¦nÙª )(Zºms%¹C�”Eƒª jÛÙÁÅ+"Zˆè!‘dQJ‰rò-`‚0'\ÿ#¤ öæ5ȪzãÆ­›�½ùC?äûÊR^/RžŸçå ï}Ï{?ôåÛ·?àîËwž»ÿþ-•Ðf””ÿ':¯Ö¿t´ò&œ‹tˆ œ"¥./'\\>Åñøóñ Ër|uçõV?-êÆ�[C´ 1/f…΀Ý8Mié×l2q‹È!�„sÓ¬îÈ’úœœ—ÜI~ï?½çÑì÷ø äªåA ªKÒ¶`'r¿õ›up²ÿñ{‡¼ÿß°,¥<,Ërÿ¹çŸÿ‘”Ò½²,·È÷­’¢lî}4¨œ¯óòpÀ®ñƒÑ¹öý4$[³H1З˜ÚWKŒúgÖ/­`ÛÚÖå£_o'äµuXW(»Zyý‘á»NÜV¨ëYÐ+îð:!7®n‹}î ÷Û¶™:ðê:³9+i'ˆß³þðïþe¸¸q ìvû Ë7ÇáÇ ÷¾4ݰsG À3\Íø‹ÿó È)¦�o߯°ø°³tb_OþÉ7¾ÿò{îà>êyß]nû�œ˜açp°Æ×bVþ)£E´¨Æà*ÃddEöÕ¡œ_tB®ØXròñÌH™€’ÜÍ`²ø€:ÞE¡¸‡Ço(^xiÆR ’d¤Ìxî)Æò«? ¿çO~÷ÑT�MwGRwž’¾&ÓëÂ#Æ3«]}ÕaŠ©eý2~|O{|š•çž{þ})¥%5ÀèœAžgÏš†’ȧ`-Ëì϶Fá–GÏmíÍdÀ6çÔÖr´pœ*�&Ænšš»Z) xÔì°+K@ÊPý�µ Î?#ˆM'€ºÁBK'"‹úÚoivþvj™Â~Ê;LÙˆÕIc.‹ƒÑc|Tè ßžçÜÎY–æä ÙñG0½V!v²Œ?§¬mÿÛ¾ù˜¬��â8D‚Qiä„51`íFÎäU'°´Ï)ýY®�_œ·´G¡HX*a"ù5RÆçI®wa»Ø~õµ/³=Wø¿kàŒìzäR3ŒcŒÞD‰¢(XMÕ}Ãñrš�ólµÕV[mµÕk©¶;ûV[mµÕV[m**-b@ øïDºâè–èÝÜ{ õ“[Ó¶þTƒ}0�”A…@ìJð–-¶®60¼!T\9!Eš59³)¡ˆ”rÊH)ûß®\Ir=û3Ús‚LµÃC£é\k¼[ŸŠhIPV�rkÊ«g¬‹ÊÐз ÎÓìùjýÎÌÖ·†B9‚ë#çÛQ›„áý\ÉÌÍXeö‹·V¹…Gr¦‡†mÔçU¦"Á€h³Ðt ¸¸€@Z“´ˆ@Êz¨9A$Ïß›†?¡XÍ—Å;B7;N9ËýÜCpi¸þìG_ çAS9&` üGׇ?Ñä7¶=ìÇ„#q �!›>nHPDVÒÁéYRÕ‘Á…¢YǺÕhóO¶í’"((v.QW;I±�NŒNPð¸…a~ˆG�L­5Mr®�J4E\YJPÅö ÖÚX­ÍÕju[÷NH@"� ,N°kŠÝʶøw�Ì]·ïç]ÕKWài"z™9ÝÞïÓKoü€7¾ë�ðO2ÓãËr|ü�ïx÷_xßû^çöí§®®®nÖݬÿ¯ Ê>WÔÏí:×ÀâèkxF°v­YÛ‘hµßÝÀ~w0ÏW8¯0χ³¶®[ýô¨Ýî)í†3jšvGU�¡XâÉAd™ÎÕÒ¹”aöP–f¸ïªÒÉ�=23PÁ0QŸôÖ7e�fWóË”ûßJû¶õŒð„¯ùÇïÀƒ‡‚.KÁÂ¥]Ë<Ûgsªdæ„4%LSÆ~¿Ã4Mþ̲à8Ϙçc{®êSJ%‹é‹S_——ÅÖnUý_Ji®"ä÷‰œ§Àîî "§x ÄõRÎë.UÕqfˆn�H¨.s}-<žC1Imq*u*YNIá¨ÛNvªbÄU†ˆšÛMs–“ñÌ÷mÓ@6Ðöœæ®);øoŽu9ŒytA�#Aƒ“^#wŨ…™"iÆ5j=i2"öV[mµÕV[mõÚ©�°ÕV[mµÕV[À‰•bÚ‡ßÁ­"]¹PD:Æ\ù`-îj@·¯ŸÕÕwU!mö–U‘Æ•O� ŒÚò¦�z©ÙI&³M)»ýr»NÀ´­è�Ôȼ›ÚQe Z§„wP ÷ôÛªjD9Q¦°ç VáÔó#G%Xm0{³ž’Þhc Ùé3SsX°¦'7ë~U[U5GÝ£Ú¬DµoÖ³Àgm#-¤ö»Ë´g€J`A4kÑš#OQ1/gÕ/¬õ9؉öí^ŸàLpPIã‹ê8v@½A´Å&°R/:b ãÒ•­mŸÐ­5Sµ FP¸…�©äÕU£ÜcŒÔ²V×jÃh¬)èÀz©ªÁšaÍ}?•Zc5^Ï ,£4 Þ¹ìgö¨†”³Ù“N{ä)�± dG˜gÇ80×1´_k¥kvûñ¬iêJòù�ëØ: FJXCr*:^!F¸ Õ‡\Qâ#€{*ú’ª>à1U½Éœ/ßð†×}ïë^÷Ü…»«««ÇÞûî÷¾éöK·?àî�;oXæùfzêûsá1Bàô$­Š\]'¹#€†á·yÚcš àZ–ÇãCÌó¡eÜnõÚ/"Æå�ǃ`Öα7oÞUѪ‹ú Žàä9Î*UÂÎ’RHvŠä¤'&nä2vRSÍѦp¢j˱ï6ßÎY d96ctSÚê‚‹iç÷ovÇ(%@FÇ›úGa¢EUï—R^|ìñÇÿ—‡|L¼€Ì ÀAæ üÕ™cÂG¢´»ØÖD2ÁÊÒŸFr©@•Ç«{~´�úÔœ h5œ,ÔÆ � gmñ<6·›ûÀ9+õz¿÷�ܪ }Žža:5e¾4µ{t‚ˆû zN¹Î!2ªÇ&�à~]‹é´ß7êïž|ò&þËßõÙ -@Hà´·ý¾÷½ r)]Œ69´àÛ¿ï’»XhR $#0 AÈ€÷êXes/A9!A�|Ûw¿ìŽù« ë‰æÖ€äöín•O¹TÐÀãê¾,€.ît!üàLà“�!ÅV�ªówkðzñ-ößÌ@IFP’Ë”2^÷ô?úή€(CÁø_ôþøU¿ïe\e8ϧ.ÌÅÉ+i¸ZŒD0Þ Ç{©& Á ÁáŠ[LI%'LyzqÚå™Àu°«³JäŒ1"ëë­�«"  ˜ ’$ÎÈS6çÌH@À’Vs5+ûì*{{VQŸQ†=?ç+ø¿Ìs‹ÐÔØ–Ïž‚?Y\Á27ûxÁq>âpÀzŒä*‚j5HÝjÖm%[Åì`oRY#"5Õ:€–ù*E°,rÃ+Èɹ«ü­9äö“èNºRIUåHÜW„F=^7`£½Ä6Ô€rrkuUj¯IÞÕT›ÙÔĘQiÓìù½é)¨±b²luåû*³XÃ8ÚõSÝï–µI¡)í}åÚ|­Ìââ5®†“÷œ{Q׸kb ì l=ΪÐâÀ® œWõm5{’Ù¸ªÑ:€÷«f.u®Dk,;pP¼¨C\ÄŠ¼¡hjÓ5€‰ŒšB•ÐÐÇ}]P=yÞ�ÏJgF¢P"gs±cfˆ» $¦6/0 ”Í�ÌžMWëTfs«Ë;䜚sB#¾«»Ý…{Q%̵g�3ÏPõó»;‚ßgýûœ’Ø£0øÕElµÕV[mµÕV?uj#lµÕV[mµÕVÐÒj)®²ê ëî°n0T>qòÕ„)'k~xóbY¼¡J„àJBk:ä¦n¡J SõL˪Æ(¾}p`ÔÔȵ)”ó´Ê‘¬@©Œ.ªõ·ijp�긯­ IlJ«PÉ lmQ dX³°+9Ê@8`"ÐDÍ*ŸaÄGØ}TãŒq0¨ªW G¢Úyž;Z–œVeˆ«›Ð”��R0^¼¡–8$¨)­¡êcï=¼¤Ô�3ÛþÔö©[ñ‡,RÑfußÞÎÃQlþà•À{?Yc|Ÿ Ê)õ\[Z£ÍÆ-Ùx@9@;ÆDÒ€9¬T?Íñ¡Aå-My+ç-Ê¡R�ÜPJ'8ËÂlü™­¹GáÜV#8”ÅTUÅÏCysÒ‡Ò÷½F�ÔÆ7‘5)wÓ»Ýû½©•RÊÞ¬Ô›ÎI’’‰ “]ïÂŒ²Ø¼Àê×hôÉDz; yÑÃuxzMJ�ís�¦^cËE¿+"‡"r§”’A%—R’”’ŠHRË›p²fUÝCqó™gžýþgŸ}î_ÑëŽÇÃßñöw~ä ï{߇¼|ûöŽÇÃþ#YÚl»I#ÔzbË£9*¬jSRÂåå-\^>æªÀ‡˜�WX–y»Ù½†êæ­'‘R>=õxêé§Þ¡ªDå ÐÒîé>¯¤l ³®gQ�sçe6EdGˆÀÒ³’üÀ?KmþО­,!Æ¢ç¼�çx%qµIRÃg®œ‰êügöÖ5éCJéåýÅ}Â'}òoü¶oùW_~ÿÞ½_ršÑ@ò¨Sp)Ð`E½; ô4z¤¢èÕ "íþ"ýïoÑèiN=gýŒ ³/Ä\#îf”RvÀ:d«?jjë 81 ’Љë}¦Ñ/f ¹5¥÷hƒ}:óµÁî?tü[»+O½×~ð›_‡_þK>–Ãö¤—— ·¿LÉ\©@ÖõÒ~'¥Ú!" ’Ö(ŒÒ9*€2ÄÝx*�džWÞw|_”¢�õÌ~üã�Kú0Ö¦øWÌ€�28 «ÿ#øoDÄæÎP0@ªóË܆›AF|€[_‘[E¥.ÙÖ T-xóûM¸soÁý‡öoãW|ÖSø'ÿò¼tg�ú:Ñ›T©<8þý¿ÃåÁ®Z&Xì¿û£:ùçIuàŠã¢=üîv»÷圙Eµ°žâèÙÕÃx-kAß.›ú ^hq%‹)î\Õý:¯)0Ïv¯­ y)ÅŸ§Ð@pFª,!’ITPnVü¹=g4`ØÉ}Õ^D°Ì fWå×u“¹U$Îͤˆâ0q8\ápu…«Ã"bk¹ÉÆ(¹|òg«6Çinól*}fÓ„Ýn‡Ý~�‹ý¾¹T'‚þœ$'±DÜb¡j¬À²Ì(5žÊ�arÎÝ™ Œ…ˆ`ñu'à.óžµü©,YÔX�…‹s£RÐB�¯Y‰gÆ™à‘ãœZ¼�dÛÞldøz 4U€Úï¡Nó˜�<ÙslNpŽw»3'ƒ²" $$MÞÕ·¹¥>ûž#Ä?F‚ȹÅdăiç�°ÕV[mµÕV¯µÚ[mµÕV[mµ4àLµ‚ˆÚ²§Í&³õ2½Q­Ás³t%Z™!Â0JÐ ¦�0»~k4õ|á ć|uTÕ!{¾·Y&¦œø_?ƒSP…”Ú4¾Î»«ªZsĉÆ¡nµa¹Ôëü“;¸µüw°Z~¦˜JppD–¦Î`wnwû~¬¸ ¬�Ç4vÄÀûÚ¦�·WaùÄÄÚ"Ä:ì­�_Èm%9655œ+€24hí| ÈsX}o[Ôõqd%n*ùj»Ù¬ñkާhÕµ>NìØ£0»¹0ƒDÏ [Í]+V«å¨�¦Š¬ƒºÖ¥Q1Œc¢ Q‹Þe n P¸Û1CÚG„)886«"ÒcR¤}N5æ�­J”`)ÖÛ'€.PøJ=g;ß�mJ Ón´ËAM–úõfTot2”»Ã ©[ç–Öü¬êÕ¢‚$j��'M�,қŭÉI�ˆ!5¡Žo2‘äÍÕdjÜ¥xç¼*«Õk%›„«=´'*7<ÎÌÏèö~wqûƒÞüAïùÀúÀï)O¿øâ ïÿîw½ço¿øÒëîß¿ÿ˜[¼úÒ±AéWºž¹îqú3E€,ûÜ|qq �AUp<>ÄñøË|Ün|?…ëæÍ'°›ö²îýïª¯ç¥ ±g»£‹°Z†¸[é×s¬“„*™ -{ºý¬*Û½oŒwiÙï¢í¿¥‘ƒúš]kìZ!¼|çnyâñ[RJºßïËg~Ö/úýßý�ßñOìGô?žçùýÎݯøßÅÉm[h娡=Ågp% hy0ÜžÝéh¹Ï•PÙgTíñ@ãÝ¿ëtˆÎ†`½2HÌ«µ‹ž¸/çàоOD§g^nRã‡uá7];wEw…îôãä¶Jö¶ÿñÏïüÒÏ„°ÛÄëb¶Fº‡Þùv`~°¡þšÐFÒ ÆëžÞá�ïyØàdf2°9 (÷ W'%z¦ ^÷ô\޶ï\#£Ð�ãh+8‰ûO̯Áã€YõÏ0¶ì »dʼn„ 5çIÙ-ü©Zû[¹Èlï+ *�AˆÀ)˜ÌUJÙ¯»n˜Â(Šéò&ž|rÆÝG¨.v¶™ŸûiÏáÏÍÛÛùÐ/�UHû=ùv×…(­"6¡¯þŽêµÒ×/�T î ĸx^\\¾›™f€Š2)%²…ìZ‰æœ'_—Euz[SÆ ÌÉañ¿õØ* xàøðˆRJsm*Å¢Ól¾N°TjN]ªŠ…èšë‘VŽn©²Þ+Iºä „+ Ôþ½/ Š\=¼ÂÕÕÇ#ŽÇc{V°÷ÙZ/åÜÈ-Š­@?/F6PÐ45uþ~·Ã4í�rjÏ–kð¹Žoñëú«ÌY ZÄ[û“†ã$e¤|¬Ÿ êZÈžïB„@#YØw%f”vî °í¢•mIu ÖÄ— VÏ•~OH C5 Ñ)M�àÎu¤u'>ËYw "ògÊ~fÓY‡˜õ³ƒYÍ€sûî”rs˜Øj«­¶Új«­^µ¶Új«­¶Új+kȺÁN¡y?¾¶‚€ ÏD'BJŒ” �6üÖø7€·4t‰™´Ïüïùæâ x³Ý$†fWWEGjMª3{w’»{ªŽèyóÕy`üˆV ÖãM5`ß�¼‘þoþ;Y‚ØÆA˜@Êž qh)àd@µ`H*°2©ºÔ=Hüu«*Ö0�Í©Þ4:U\®m.µ}go…VذY1éØþŸÀ~b)_i+EJÌP®jçNþ8BÔ/Öÿ?{kY–�bßZûœsï{/"2#"‡ª¬™•5“EФ8SEQ&©Ñ�VCB«á6üË€n`ÿ°aÀ¿l´á?vn»e²Ü-A°ÛÝ”ÙE©IJ"kbq¨!+3#çÌ^¼÷î=gïµüc­=œsïË, ­™}‘÷Ý{†}öÞw}“¹d‘\UE7Ñ@iú¥˜0³Q_Í6—0ÞA( ¿E£ ºÇ*îÌãÖírË4gwJ|E⦋ñ¸ìOSs<>æòs‘Ót)G¸â‰5xD«²×¹MtyF¬QžIÝ‚u1KÀH aX#TàêH ¨@„ÁÒ<‹ÅM¡y‡øç’AžÏ¯ZQgw ‹2Ѫîõ¹©ë­Á™ÏÙº è)%&¢ž¯Š&…\ è’€K]ôŠˆtÀëDôäí;w¿yûÎÝ3'ûÝîÖ«÷î}üí·îâüüÑs’R �ëçbýn^õÝLêȡ޳yn³9Åf8…B1�WÇbækýÑ,"³ýïºM}PBxò‰'^á-bºO  …Nª@EŒ‚˜"Bô À:PlK�üϦfd%v=–2wÐ|Þ.Qh¢k wŠ�bBè Äa¦’» 4€lyÜäxÏçÜ<¿Û³¾c¼qãì"0KA~ò§ÿÔlúʯüòÿﯿþÚkÿfJé ZLÕÔü©Xu—‰•ç`ælzã<�¡EFÛ\ó"ôÖöïÛ!W�.–¶#.ÿmÚÁÔ•ÿ~d6ç  »v£�ƒë”¤³|ý3ŸƒfŸ“£ˆP#�óK%re"`™›Àg>ùAüÙŸ|¾�+lïAãKHç߶Ϧdä€Aa’€ºŸýäMüÖ×"š u¿ªå½J*s²À=ãã}›^ë£Ç XŽmP„|sT•œëMB ©Óœ, Ñ~!Ù³'jØ?|,r×ìA: çÉç}DJöw’|îFØ!µcb¶Ÿ—Tމ© iÂÇ>¸Åãó„‹�’"N áGOñÿ£o?œ <‹½ÒùðŸ;Ì &m5¤ÍØTZ>˜¶_Ìiþ½¤¨í�­xãæÍ{D4ÑÄŒ¤J” �„¹©�G³mº%z°;'-¿ÐÌ)*“R RCFc­N„‹‹ÇØïÍÍ,;ÕG1O²Ÿbß4^ݘ�÷™È,ɬßgIÆ,:‹ý“ˆ){Bœ"bšpuu…ýn�q¿GL±|bÊvô½[ÿω)%$Wé‹«ûUÕc<þ¯ßÇ(5{8&Ûwb¾†äX�üÞ™,‘ÇË¡å¿Ìî's($€üºJæ8Îç;Usʬ¦ˆ/¤ÂüÆ)Žz¯QuËŸSÄÐ|/°c�a.y<ô}ð8­L$°ï*v]æ®d!„)J Ê ¿ŽË¨…eLY&¯gw‰ÍÐcèýÞ5nk­µÖZk­µÖÿZ k­µÖZk­µ–µ%J6zmZÚÆ¶JM½eM�@¡•Í"K#NFUïϹ+ $­YóþÑ sγÏéÿœUˆš3…íïµä¹ fñ×ÔL×Í nÔèhô»5U-  ì6è�¹ÿíg±ç‘›úCm+VAråfô°z kãWeñj9r‚ùö“BUe¦½1�ÀJïzÍŽWö{ –û.Zñ¢óüÊÒ¬[üxVŸ³'Ý‚-a Ä»wX3�Ü~Ÿ�œ0(p$AB@ÊÑ…\ðnà'-~¯÷äö‹rëÐ öPªypÝÒ5¯�-u�Ñ RÇz�ŒjœD 1âÏ\›ÏKGµqåÉ÷†áñ¦"‘¾ëÍs û¸ÒòÌ7ÎZ GƵ°ë˜gy¥%g¹€+ÍUjl»kîm‡¾ó†4q�•  ">OyÌÃür\ÀnéDÀcÞገOYe«ŠA�áää´þSŸ Ÿþ,�¨àÉ—_|ñÞ|ã�ï½ÿàÁ÷Œãþ”@‡`ûwm¹Jïy�ÿO'úáýp˜¦=¦q‡iÚãÐ@y­? ÅpóæWõ¢‚¨‹!r÷îS¿ÃD¯1óÛÂ9„¦ü¼Æ8aœBÍfÙÉ\hե∴ªÇ�´@ZyæV0NcÊÓ’Tj˜æ¬çr ‹c„Š=ÛJ‘"N84 P³GVÎñ½�ó8EyêÎí«®ïµ !Ñîþò_ù?¼zïÞüO~íÿÛïßÿK"z†Fm<Ÿæë¼™ÁeSËl-?KTˆšŸm'zicõ/G�#jãÃçbcÑæioHYZ#Ë\sx¤Š‡ˆjüQ;Z–Ž '˜u5ÝuS-ö:Ú\OöÜëƒ9¨!¼Iû¥q§@Ch~FTñßù[?…¼öPbÈão8Þ+x>¹š^¨·ëðWÿìsø;ÿÉ=‹€>I�ƒ«Í¥\A�U°%)àç~ìiûŒlÓ¤ÁEúP4 ¾Üõµ˜ (oà?ƒ�A>@Œ �"™ÅxXNJU* aÝ[{®¹Úº^r¼5ÙI1bÎÌÌ$„Ü6ÝO=�ðà…Kìv‚8 ÀŸúá'ñýÃ7g앲ÍoœŠf z÷e*_ìkBÕý·<“2äIgÏ“¶ >€»wŸzQUÆl�@Äʬ�}Ž7û=¹vƒÂüÂÑ­w!f7 M�ªÝ€mÛw\]] °Ü!Í~™C�œDŠóPê{t)™E¿ßûJ¨9s°y³¹’õ),”ò\~VD‘¢Å~MSÄ8^a·ß1@ wSs›ý®ïÐ娘æbŒˆî�$5¤n.Ñ2ì™ò­úßæƒCÒ¨¤Jî‘ä®VRÁüÀÁçxžÏ‹9)»´ŸCB¾® ¸1äó¨S>ÏÖ?b:Bl=t˜O”x×½oqGk¾C·ÇÊ…°<!–ïíw‹ögg{gÑâFüýò5,Î "„ðÐ ]o®^ý€¾ u±ÖZk­µÖZk½/j]Ù×Zk­µÖZk-x‡˜ex ôz œ!ÏšoF0/À8Õøï�òâŒM3º©ý­©–DŒ ��µ«hº¬©F9ƒÝó‰QÕëÌh-‰¯ëDò̶1w4‹Ý%0·Øl�*äê,ku�J €›@µ=e‰©6¤µ‹lS˜�çïmZÊ×Å›€UŠ8³ìmûSÇphvðB¨Uhåëê}bª MV¥gåT¶µ�ßþâ²�ݨC®Ü/õ-h,Øóí࢑ÌyœíýÎ ±âDàÜf*ÍL‚‘U¤i^¦”Á,i\ h6¾íØBYMÅ~ìù‚±q9ìàÖ™åöù˜ ¶&tFÇ´Þ¡Üðn­þK²Ôæ·jgBè@”Ú�2Ó”¶ ¿|�Úyv8¥Ù5Çâ>Úø²»˜5˜ø˜]äȈk� sÊ"G;v9pÉ®­s•jÙV|.Nu@„þñ�îsJ"»Âýg?ðÜÛáçñýꫯþí¯üöoý�îÿ%Ir£™çüvu ˆZËp'`‘yÏmæ=²W&F¢¸‘ �ò:@3÷ž9ÔõMêÌ©ó'WuaP¢p´*‡›uÂŽI~&Ë«¯ãùu�z�¹hÉ¥¸ÖÍy]Óæý\qþiìÍÀ³O=�¿ø3Ÿ!¹›N¦i|ؽê;`€#Ô% & s„tøØNðWÿüGðý§÷êZŸ×G�¯>yÒOe+ÛwžyêÿÎ_ù˜’[Ç7xqK„PÁ#Þyp�W^?Ç[÷/0F‡ ÎN¶xúÎM<ûì¸}k@Ïy‰L06a³†ªx ÍáPF$`�bƒ&€)™ÕvF¢z�U�!lZÅ’HÙÇ}4áÙ»§xéµ ;sÕ �ðWì ÿɯ½�Ý^š½ë15ýœ˜ã}òe‘™·D& 4Ööȱ(–ëå9š±S´}î¦g>øÜ+1¥=M$fRÛ‹H·–÷µ>I!�Ö½‹€2�9Ï%\Yµg‡ŠØH¥€ÿ9òL9€ìvûoÖe‡²Ðu½ IDõûK& ‡2ÇsCÆJe¿’ b¤“|íBþ=»°u¡|�϶Ïóƒˆ Æ„)NˆÓTlöíø†a°<úFu_öJÉ’ÂNÿ[{~>Bj<¦ÀoÇK!g*Â5Àx&�É ®I¡\GHD5†Ê+9ñ-*,ªË�Kœàq0‘Íø­õ\�¹³Ä1·µeI‰“Y N&×f"›}7=ò�5Çíå=mC€T’Œ¨–{ aBg&FÇ6VB×Û˜!þîù¨k­µÖZk­µÖ‹Z k­µÖZk­µV©c–ãÅrÓ•m4{ñÜ8Œ9»—2°Yp>:ÛÍ@|²¼áÜdRÀTß[#ÍóÅ6@£t�CËù#J;öã9‡mãÆ\ìX„²ÑÌ⸘©iàä3ÌJB'‚jµ]6±Úã-ïãöö­Åç1ûüòß\ªö™ÙÆ··±¼�ª /Þ%²=?¾îßÊom£L ÐÀL4�ðA7?Âòoö+ÀÔRå¾4Þ²k„–LÍ¡Gß ¡Š˜xd˜ÖÔmÎb±ë+T.6Q¶È]æÏ×z»çÞLf»f”Ísêm\TÂD~ÔtA hQvÒ"¯VDÉÑõ ¡ó÷JM\ƒ_óF�O¨$"YŒS(Š*‚ÛJÀÅf Çùx•ÙžÓNšç¥‰�¨ÛÆ?h?2É…¡ãb«š£AHìyhóJ�œ¡‡ÏG¯Õ¼\-¶­ZžiÌqy~c„lX<ú¯£ÕôŠO½­ xøÌ3Ï>¸{÷©oªÊ�ó‡�ž{íµ7¾çíwÞþÀÅã‹ðTå÷”N¾ë§.'ôvÒ£/¥#ïºÛ®Ç L18ŽW˜¦ý²ÇZÿª‹9àä亾ÿ®^ÿÔÝ;_ L÷’à5&¾OÄ— �È‘3)!Ž“¹í4öÎùù!2øs»Ý"L±8óä  iž™LÄc�R15?’yíô ŠR!°uîì®FûlÁl=ËÓ@�à䫿8S9ÿ3pöÒw^QÝ'‘}>ø¡gÏCè.î>õôÕOý©Ÿù÷ÎÏý½ßùÊ—þê;ï¼ýs)Å;íS ‚bm$8Ð[Ëÿø¯Ï˜ï™ r1¯ä"wØ©(*û¬<æùêZFÐŒ¸ˆ¢ÀEýäG3±‹=J¶`',|0Ó]3ÐnÏÿÝ'¢ÅLãªî$Õ yŒ9Á+Ûïg‡€_üÙϺ‡¢D ÁÇðå«@¿1{û 6)¨ž\ÕÍ#€ÚõøïÿÍïÁ7¾s‰¯}ã!fÌ;±—jÚÄ@à€7·øßý»_À¦ç†Òù.(¼sÿ ß|ñ>^ºwI™Ii1Wô\� ÷Þx„WÞz •„iñÌ-àcÏmp÷–¢ þ¹ `ê³ûMÞWÃ-ýÁw€$0÷€$$'6ä5×÷ª H²½ +WFYôTvÏ>³Çå.bbCXñ'>wÿä·6àÍ•QwzÈ#ë0ÃBµºX4>PÈÑ[³‘Q"3–äÀì¬Q«ïú7§iÚ)tׇn !H`Ö Ð¢d˧”0ÅD*kYÝkkQDçïù€¢«çÍ©+!¦è@ª8‰-Òˆ]§Pe¤”föùA—$ˆˆ~ÝFŸC“!5�ÎÎV-ÖF`äïLIÄÇèÚý¹ªbЦ)ù1I�€xÌ‹Iû¾7à¿ïÐÝÂrßöÏÓ4ºEš}O)àÿâ³gÖó¾ß—常æõYýºz,íù·.­��!->ªˆ¢«“ ©ì»[²íÁ†¤bMìÖF––¶˜Z£hþšARRs-pŸ})n¶�inÿnÊ+UMpk‹bšÝ&0;Þ¬ÀÉŸ7k–QUê´÷ŒYÍ æ÷1;Ô pq ­!2„ øk}–Yºó,÷ùµµû+nušêØ.FÜìöºþÔz^ çúj”&¨õÍv?–]W'à4ä­ü–BjÉϾJãbP²Æ«ýð ÿoŽ%çñràÎÀ=kÀÛ3G*ñ@ê–­¡dÌ"?‡€7»“GlÀ°’ì¹l›¢Ç0t2µ^›í[¯¹»O@›äïöáK�Au°SàBÍ5à ߺyûÉo?y÷îo‡.œîw»[ßyáÅçß|ãÍ�ŸŸ?ü€Â${·:ì×Hå¬p¾vò¿öm¦@ÜžÜÀv{" Ód1Émƒ×úWµ$6›Sl6§È¨¬-züVÀÄò=ÏòWˆøu&z�I1óNDR¶$J0 J}ýNT î‚}vv†Ýn4q0’,”éN$±/s:l~°%ÄÀAvÀ­zƒ‡Ð!Fß÷Á²Ê‰]‰^\W0ÏbfsÈapySJþ¼7@˜ª««B“Mª÷^ze|òö÷‰H˜9ÞºõÄþGò§ÿ}"ü½¯|é·þÌk¯¼òóûýî£pDYk²²”«šùØWË ¿œ–³y^OlßU‰r92¡“,ÿ´xV3Q�à8òáÚþì!b¯8$ôi«Šo�m²“Ñru:˜nÚZö+š|Õ¨z«3Ê¿I²qôßþë_tgª ÄŒ@ ÄG€¼ RͰ"²™°€4<�UÐõÀ¿÷?þ“øßüßÀ?üǯ¸ºZ¡,ÅY¦(�9àé»[üoÿ‡_Àg¾ç uvþ¡7'( xñ•GøÒW_GLvüIiŠxí�ÞxsÂ~'ý€³ܾ½Å3ÏÜÀSwO¡)AÓ/½z…o~ûwn*>÷ü“xîéè·½ÝS²=Ì̾ß÷à¬pB&<ˆ�+ÊF$É\`ûN¨Q,  �9 €D<÷ì)Þzg�Ç��èŠï_øá›ø'¿õ°QZkq°Ê‡Ô>7Õ6é´{Tˆ�9½@ŠýÆbms'u·ºðÊååÅn†½n6qC1¼¥ ûNÇTÔîQ ºí“ZÂ1€ ¤®š�q²_)•¸¬¨VUt]‡k2¶ŠÓ×4JsjzÄe-”y-§È„ÅV�ßîgÏ�«ÌSŠLji-G^e603:ÿûÞI¡7²sqQËŠü+ƒïÙ¡-nŽ#!ú¼,Iû-I -ý6Â)öž�üÕ¹i]3;­Jø:íÔhûpAò¹·¸Ñå5£ðP+A¶ýn±$z‹;™×2w k]覘ÇP)©Ê–Òl�gµv?ÉD¾Ï¯Û¸¨ E¿ ì?S¥ÏU] ÆR‰“í¡ý~—ÿmä’|¨¸7`2�)© u´J$ËH �úàY¤€�’‰\ˆaD–Œ¼ãù7pDýO�h}þ÷¡3âåÈ oDsÈMsÔ¬æ”Ý rÓÑ~U@“5­4»#fSÝü��“U€CX_œ|ãv ’í[Åÿ-ç= x²E5gK}ö¦p(c[DüÞŒ?W©ŽøgµŠ0­w�šìàªLÊÎ T›çÝÂ5[§šÃe(h2¤“ˆå‹—9ÌÔ|v=©4kARHDlMáÖÒ–¹� ˜&v=˘Õr6ùîE蟸$à>1�p¢îx·ž¼Õ}ÿŸø¾_QÕíùùÅ�o~ã›?øö›o}ßùùùÇERŸÅ©ÊÊÝ n ./>“9`³9Ãv{f íi‡qÜ#Æq]CÿËZЉ0 §ØnO‹¶jfýOº¼Eöºgž}æ÷nß¹ý‚ ÞômÖp$MJ¤©¬e�@’=WÞ8€ìïNÏÎ,^„, Éóef†¸�0vFS%L114ø¨g�øü­Ð2eu}‡¡ï=kº/$2_ëYîFYÿdb¨em#[77ó�g!ƒ©€`p«îó‡©ßöç`$í™ÂyÂÛ?úã?ùÒv{òwëŸÿæ�¼ðíoþåÇ�ÿ°Šp&ž©ŠƒDs\›Ýëó$�•yè1w8(¤¢9 ßîaòµi㓎=çùç‹zyùÓy?æJÓ÷Ü'j�öɾü?ø¨™+QŽ^QO-à0 EðùO}OÝÙÂ}ÙmI=ÒþÈ×&ô“E6èèh.Ù�É÷~‚„Í øŸþw¿þ'>�🿈ßþú;ˆÑ-ºS„¨âƒÏžàgäiü­¿ô!l7y�ê�œðÕ?xßøö}@ c|é·ßÁ×¾õÞ|ë1bL`ä(Ïùö‹1lz<ýô)žÿØM|ú“�&¼öö„×ÞºÄ矿…Ï~ú9ܺ±©™`_t…ØÅÁœr–‘¹" ;@€ìN@Ù•";W¥áœÔ£ÌQ`»=ÁO\âü2ƒÌŒ�<ÛáƒOxí­ Ó×Gˆ†:³ÿçûÉ:§Íç8%€aÄ[ˆ,Celˆ=t]è^¼º¼Ü¥˜v’d""efô½Ík!ˆ(ˆbýŠ@qœ¸>æ¬|§EÒXÀÿqœ09ˆ[•Ù‚~^çø!‹0 dTã.Tj¦“Gwpy]Ýog ?„pêfµwžëbœ*Pâ§ Sœ )5ÎJö« 6ÿö}7—«ò_fïgÑYU½ÈÏÓãÚã²è„8w.XŽ4X8PÞs†ãÔ~��ü~ò{‰ðÁw»5R¹áš£¹*‘¢ìäœ�–cËr´C&¡ÍÇOÝCæH6QEŠ•@’#ˆ´qàÉs^‚*7q:O]×aú‰Ð^³”]’DÌ\ºj`ZýwH$h�u¶ÖZk­µÖZï³Z k­µÖZk­µÖ¬LÉÜ64š�¢±cmšw—Eý„©6k!;pÀ,¦pÏî€5j™ÑFº>«Q¬ù)‹]¬6�ïà×Eß»=�öˆëëç�q!kÞ24™ò\$T@hË㜠f@~Ûò¦FÍnÿÂ/!Àã °ø9Ì”ÕþN HY�ñš—É5²A–6í‹sTi:ŒÈ„ n?[g¹½KAG3?Ææ�²V-ÞFÌä ‡bª gUÛÈ(ÇÝ8$› °û�ØÔ[7Pg`7ãòݲ=Ë¿;™"0!BŒ¨aÊÆ8WÈg•¼[̶Wh¯c8Ÿ¼�'¦ù=¡ù³ˆæzç×,­d3àR0�cŽ‡Ù³gçØßeÛӹ®Q5µïO•ÐÞCÐlfišá©<Ÿí1rgDͤ£$HÑívœ9}€Š¬ÏÔg¹±OY…Ö-smµ‰�hŸÝg‹À#í@ô�@=ꈩ#&&"&¢ÀÉéÙÉÍÏ~ás¿+"ÏŒûéÃ÷^º÷Ão¿ùÆçîß¿ÿÁS§XÎ_^ÿï=Ñ#º”yT�>· üX2z‡Í)6›3(€q…iÚ!Æñè˜XëÝË,˜·†m3øuþ´drÏ‘[Ü÷Ýø½_üÞ_ !¼%¤÷UÓ#&ŠL$L¤rlÞj¦¾¼F±OüÃfãÓ ƒP£Š�ĬёGÎDwP[ ä±9e�Ò:ºì8¦•4S€}j×u[BÉ(&H¥K,Ó·Í(Ay¾Ëófšd¢Ž.˜x Ìç¡ }¡I›ú‘½÷'ìÇÿá·¾ñÏõË¿ýoÞç�ŸÑFÊWIRQk–u«%sâ(g¡UeßXöψ‰-�¤GÖÛ÷X`•`Î(Ïïusfëï1½öáÏU"C½´ô.«>#_ïŒØ…YDLu£©—äæ“ J0⢯Éz \~ÄWÉõPÝAtâs�°¼{†AAˆøñᅢŸøÁâjÏøÎk{„€DÖtµæµ)oe¡c†vª]Ij†kðù'¸ûHBÉ<¨©,}ÔYtƒ©©C“- èÄD“·ÒöÜàÀ™ ¢ª[V½Xî¨ÒýaÓŸâùO<üÄóŸøš$yæ�×^ûäk¯¼úÑwÞyç©i‡Æyê_s¨}^æD£¢èü.ñÆ9` l6'†-Š8�0Δgká`Íêú †þÄ”ôh„h]ÜÀ¹¼½æÓŸùì¯ß¸yó›P¼Å¤� Ø«hq³yþ/sÏÙe¨*{ÀÖ–œ3,ª` §¢Z‡*rª D ÄNæãj™ìl#¨äg|Ãѹo¨%¹™•êäšA�v½Êqm:M ™(B�ý~Bœ®p÷©;]Ši›�n}èÃyø¡ä[ÿÁ¿ø�_ÿù7ÞxýçöûÝGà6çÒ’DûþöùÓÙ\_÷;ótû·¥"3Ÿ£?�呦™ AãiT#€ü5G— =:½ÎÆ]‰3@s ÍR36Û·j½CÈ¥To(šÕJ+»t‰õ–5ÖÜŒþÊÏ}ÒÝ&\ÃÊ[H|à Ô™=? DPêÀ2tÒäëÑJlùç”"@*N6ŒÏü ‚E�çy §€—î=ÂoýΛ1þàá—þÑ‹¸¼Ü‰†R¬í]=ÌS͈(nU"ØM _þý7ñ{/ÝÇ/üä³øÂg¼u?âk¿÷6ôS>ðìMx¤�LFž _¿IA‰ìQPkQfOC€Éÿ„äç•à¤H(ùMxî)Æwîï\Š�LÅO署 (“‚3`\Æ¿(à„‡£$Áæ(î@�ÔQ€É"¡HcOò!lNN¾±ßLjòåùÈöCßa­ë«­»×8Nw+ËóŽRK4t¨6sg3—ö]îºb¥o{tÕ]Mv¤b£_Õÿ)¹U|JP(ºÎTß1õèû¾�ªZ Þ¢ŽÆý„ý~Ä8�¦üõyÖ2äûÁTÿ]çñj®ü7`¹;°Ú�ÉâRJF„jöR¦J7ezþ;›ƒÓì=’ÈÜÑFÀH)–÷Íä fØuk®IŽÜš¹Ð]·7q‚ùý¸¹gZHF‚R#,¾ÿ-cé.Ö-î×á~Uœ,aàÿ8Nˆ1"ÅäÄ;Dz;-N ªbÑÑþœ÷ßÁ¯sßÅ BHD¨ S‰å¸vÏÑ®Rï3¥X\Æëžm­µÖZk­µÞOµÖZk­µÖZk-ohU¢¥7¤ÕîÕµL-pŸßJkvma­¹!)•fäR_÷þwÙÞÞzIÔ�Ro•àw>ÌOTjx¼'€jJ�úºjmª Ä_Ëì“Z•TvŽ Q"‚L®þ­Œ4÷Ž=2áÑ`Y*²ëõ:Çks?kÎ.}÷ã ßÔ™9k{0öK².Õíø#e{h4ù°óñ`Ö¡U�ÉI�À@GpÝZ1«— Ðáá«¢Qô¿¹"Ö<i´&?1D« 'FSáDq@òÌTµÞí^Ôdm ×óZÐgеrÑ‘5 ¶ÿŠÉì†Ó"µqרXß5ê'inÎucnû-v zl RvéH3"ˆ5 s|�=ŸÂ‚@á½FïµÇ”ŸyËbp€žÈ3Éëi%UhLÍJHúøçtM–6@HR …œâc›)4ŠÕLCÚ Ts³Kïú]×c{bêÊiܹzpú¯ýRKdJ¾a8Aè†Ù:yì9\|_óô³Ï|ó3ŸÿÌ/Ñ·Iñº&} ¥fZ÷µÒcclÜq9&4ê{€|¨™ÍÊäq6óƒêH"\}Š‘{‹÷.æèL~Jl/³Y¥sXÄÉ$£Ðø~@�¬�î�åD›¸!û5ŠRfÆÛo½UõñOÞcŒû”ÒDW?üc?þÑ?øýßûú÷¿øÂ ÿ�óGª½äuŒ©¸À_´…·ëÉë‚ F•pcëÔ\šiŽûY½|µ\ÿ¼oËóL>Õˆ®Y³ãÊëO9ö9's"À‘÷8Fh�h®Y+Ú…e É'>~ÏÜ>A+'º{±¸Ve² 3CÐ@©‡r’…ˆFÁðî PL`ìðËíðIp'P×—½á¥{çø_}¿ôË÷𥯽^Ö3%w¾pbcáRúýe7!òõ”œ$@fÂþ*âïýò«xýÁÏÿ¹âñÅ„ï¼òÆñÔ­�-¡H qG#UÃíS°sËKYEuv3aB3c@�Ôâ20÷8Ý(^�Éb‰Hñ¡§:ܹÕáþyš<3i$«ÿ‹ãVC,›¹s‘_Ÿ&–«¦Q݇ÀÈÆÚ’”´>QD4žÝ¼ùbœâ¤Š¨™”$ã0�§SDÜž`³Ý p@ßu�•»ýÊvþí~u™!OL³Ÿ1G²jÏnUéßõ¶wÈk|ûÞ,Ý€ÄTœP2ù ¥ˆiš0Ž{L“[×ÙÚÙ÷t£¼÷ÖÎMÑæù”ÆiÂ8Z4Ï4NP·çïÀ]À0ô†Á�Ï­µ}&¢%íó^º‚ÓsY\È y=9æÀd`âßÝZÂBþn�kyò©ø€´},Æ$ƱUÓ¶.Á÷Á6h a¶OÊëž Qþ7¿ZrBK:3ò†�áä¶ÿÓ4!Åèñ ðHƒ&B@S´k“rD„G#äÏëš8\Î?%Ç¿±Õyq6÷W‹´¤ r—�è±’6×Zk­µÖZë}U+`­µÖZk­µÖ²ïûZ•Ç¢:Wе¹ØÞQ&>bÏH5Þ@QêDšÌGˆAœÁE啃¦ tÉ•M#Eqí~�ÃŽÚ@lj­2Ε»Š#êm­VãõÜßí¡(‚,– %Ï¡%qhìÓèDlš\áã0·½_Ù†› dSÚ¼ «MSozc·lÉÕu8¦¤G+m5~:ß[h3– Éÿ-$ÏÙ¡®õ´s'uW©¹M¾xcª*Ék¦»–Æy�i<�ª°,ÔÑH“çD‹å‘Fo8榯¦<¨ÁM‹¹X¶¶`X¢‹ëQ2®›k–í5£nQ�2ø•Ä•^R]-h©@ËñSš†mF´^Ó¸Óæº¸Õh!éä·£VŸœˆ�ï¥Y ´SW3šb�©6'ëØl~‰Î\ `Üd®¶öª­«ˆ¨BR©)nUÔT)5ךfNÚ(K�ä T±ÆtpÚ‘Ï1!̱~–¤ò,XƒÕ”ÿÙ…$¸Í¯ª[+“)#U€ÍWs€[›¸ Ù¬ŽÓ̵9?YMÌBb¦GD(ï@ô(€^pƒ€¨výØGû�}üc[€Îî½|ïù—^zùî¿óöç®.¯î (*2É´/ M Qá�ƒ36å_7¶„‚ Ó‚CLìQö7–£¼ÿ¯•;€$=ú~ƒ®ÛPLß-‹Ž5÷ „³goÿØOýØBø:Søo ¥«¤ çöÉÌò™C.êqIKâ°ßïB›q4[6³ÀX"ää(4c«Ž1õsŸRES¥°“‰]ã`¹Æ6µ‰»Ç$6ÒVëàRd�+0+ÕD{h�¯˜ªrõÑÃÇãöd8ŸbŒÓ•çDôö'>ù©W?óÙÏÿêýwÞùÀ×¾ò¥_|ç�·ÿ\œ¦gÅ]0?çók¶{^J÷ͪºN3@ üWÒYBÞÝ”H%p�IGíÞ¤ÞÓcãGÉ…í˜,[*\gäü}—ëÏl}(Šà† ’ç«…|Þïüà>TÆŸ=T Ò i¼¦¡Ìù*„ 6á Ђ0$°$S]ƒ (‡‚H Aêêý ïÛ”@;1Œ@¬ˆ)â·¾þÀÀßý/àÛ/Ü/àY¹�R-ãáËEYÓ©zňØn' LfÃÏvþùWÞBãßø‹ÆãË÷^=G ˆ;g Ťh<…ÄP6Å}&™6# ÜÚÄ�š�V1hÔú¤@ÔJ–KNû„´O€ ¸3uñ'>¼Á;¿s9'Øæ7\ÄHÌÖµv4fBKµ­Àÿ¯ëPžWòçHùE×u¯t!Œªˆ*"1EÐ~UEL ã8bÜïqzfJúíÉ †~@è;S;ÿÞ1îmoáó‰”x„úì” ö�+~fF×wœ,<® ŠU{–m^"°©ñ‡CoŠ~怔"öû=... )a¿±Û]!%‹ " À““­= èžçº8EŒãˆiœ�b�ìs†Cß¡ß 6ôÀÐåq^÷Ôå{_vp•¾4 ~»6Gw¡«îÝqE|Þcåï™™ä�# bŒÕ ï'˜6欵áoïO!0p¸Ö€J„�¿{Œ˜Ö9—ÊüÊNÎYÆ­q‰ó°}¡“CCŽ•°AkD[õï" )Nˆ…@aÇÎîâf÷O€Öaù=‡–®Mêd�t4â­}-Ätøwažßkšå®­µÖZk­µÖZï›^Äz ÖZk­µÖZk­ÒL@Í Ì¶”ªs…�5]´Ø‚צ æ–¦Z3 MÍààæLÙE3¥GQÊ[`S%ŠjQ_eED…µ¨Ä4àå^«i0.•eík/Œ€Ïr;“¶îf³ò&"$Jà)!Òdׄճ~í<ˆÙè_€j¥¼ÈBm>-HT“L9U›qå&BÝ!++1ûžåü{ý"ÓÔVŒM_KŠXäÔcÐËÂî³ØÎû¿•)Œ„D Þˆ„"erFc·ª¢3@nø…Ž T-™³´õoãA.i,Ê{i¤CÀ&«ófç!:³ÇÔ¦©YîÌøš}«¸rvfƒQ]R�h¯ÿ ‚¨Ë·ó( )$ª¨~1;- ˜4÷¦Èkþ.œ<¡ÚDxÓ0±¢wÒI! „¼ÌumlcMÝ�gÂÏìÇmiãrs¸%&å¹Äg#̃Œ %™bÍ Ä\~¦(Œ‰ý§A�çÌÒÌÆ¿Žø%¨•‰8³y¤µi§�Æ9p2 *7saF¤l"0ˆÚ `Øl¿= CL’’*iVÐOãˆÓýÏF°4Ûus`é:ÝC™÷ÀTAZi8F�¡‹àÔ¡) £ÅuÕ)È�qÉÖíÙ•¢�cFßuØ [œœn±6ÆÑÈ ———H’0Ž{\]^"¦„®³ÖíÐ÷899Å驸ZÃ ê‹ €ˆí}b4rcè;l·6›-6› †ÍÛíÝà–ýÒ€Ô™±´Ïo¼LÈ]šŒüŒôàUÏkÝ,òÊ÷¼™Ð™÷­ÂÿÀ€ ”(ªöûP¾¦ÌŒçBÔ Ðzse‚¹/ eß¿$ �ÐŒl`1t¡D6U»ûÏÖ™B`Ëç§2sãæ<óµÊdˆ ê(Vÿ³ï016?‹‹BL ’ä¨;Â|B=ÖÙ”™ß›ø¾ÖZk­µÖZký±ª•°ÖZk­µÖZkYcUùPRÄgM,š Îå�  ÆŽ€ºµ¾6@=PU²L EEh¦_:ø^3ÒE[Ü¼É ¦ÆÒ[¥‰šmëCeÿR-Q3mFc2[ÎÝã4"%)JÕÎŽ„&pä$÷ óŸ­ä‰YÓ¿©¢¦¿¶#¨àéÜŽ~ܨ¢4ãÅAS®d¦Ç2G\ç¿Z›€ÅñZÃ+€¾ÜÍ#L,·l {Ïèm#²C�ý\jiS^®æœajZ”îÑ9¸œ" ç!Ûû*Ž9�²"üF�j}ïüJU@“‰AÄ9âÀÀÿ(֨˶ÿ"~ÎÅ6� ŒÒÀw݈£;qðÂ8BüW½mÈõ¯–®m„FCÑöYS¤d­•dà'Ø#O¥•D›koçSrµw¼s÷öù“·o½œRzæüÑ£ç^~ù•O¾ùæÛ|üèÑeDÌ�f�­U�iùÄ…ŒÒ­T燢òôŸ+—Kda=�àöÚ€ÍæÛÍ™¯ q2w€ìàñGvÍô\^æ€zÏQîëlÙŽ)T?‘C˜é0__+“m°�ž�>ü‘ûÑÿëééÉWTõÛPÜÓÛÄ$ [S±Gl¤YŽphöQ?>fÇi2Õ}co_‚4sÖ™[c¯:}[`x¿ßÛ|Ôõèú„úÞò¤Cè,G]á`T*·’B…Ê‚„2K©È κw¨¤+'š¡�¡DÀ´Ÿ¢×UÎe¾}ûN–M¢xFD÷øG~äÁÿÈ�ÿÓ×_{õ_ùÒoÿÂÛo½ùÓ㸿+ÚÞq�‘�ˆh¹¡2…óþƒÚ¨Í�oÆ‹.^bç|‡Ñº0Ì×Çâpd[Píßø6#;(ÍÞÛñÜì šq_¸†sÉñÔ8Is ù¥Lø‰ü`³7€ºËfôòó hôm»Ò?Ç̸ڙ¤zÊÑOb?§€BHB„îì— ^¸÷6^}ó_ùÚ|íw^·]Œ’q´‚ÿS^{`yæv›0ó=ò¹c“ï³ÿݯýú+øìóOà{?w»�â�7F è± êû¥xˆç(«ò¬Iý=ïï dÇ¢j9ô@°ýW±+°×>yÊè؉øžñ…� ¸ŽªTL´òUlþà#ËMKä öh×òSCJÓ:‡áÆ�›ß¶ÛIR2s1­ŽK'¤8a§h[¼ˆ�Ä}?T }W¤gм�ÁÈã3t�t%¯>“èÚlöÈ]¬H<Ò¨s2Wâ]ðÁÉÉÛ“l†M™›²½}Ž«ÚïGLÓT”âðÁÉé%ÎÎN Èï¶¶/뜈œ,cîZÐuún0ð»Á°Ðî:Ð ÁÏ{¥ˆÉ‰-)Ü 4ÌÉžêyâ��ç4›¯«ít’‚8@ž÷ÅÕ+[Ýs¨Žs!ß�~ö£¬Å¡~6hð|{�¯ÛeÍ 8ÜóC¡IÅ¿”99tŒ.ðœðò÷×: [RŠ™p–Aýü^6žú¾G× Y"�’ ùž¹�;L>>Ë÷miÜÕ¢;)¨”õoö}�*¥–ÝQÇ¿;�r‰\k­µÖZk­µÞ?µÖZk­µÖZk-k0ƒDf�Ùc* kÐ4Šh,ì"={ÙÖÛ›zÌÞ8–Efcóõ“iSˆ¬J3‰˜h«§IPÜ�-XiF(ç£-Ùa~~Ü�Àb ²ã�ˆ"M ãn�Ë«Æý)%·ÿì]ehÊ ®ðf HÍɘŒ… `0‰gÆæ<Öã™÷×å¨ëLm)3€ÛÏ Õbµ½ Z"Ìj=«Øµð0Ã*Ë©À4ÏjÖ…¥$*ÀÌ~þ5žà0/”ÕBZuqšG¤««²Z Ф²°æo®W{iüg\Cäà@£ÎDŽŠ`�ÊâþÐ,Gí³@–Ÿ¦¦šòxƒâf€ƒ(‹ ´µÏDV2I6÷%WMRŽ�T ¸Ù©U %»qˆ7!¥yÖó}9�ÏéÀy¢^÷¬Î'X£RJÆmÚ¢âŒÀMTÃÌý@ê1åsB§ªë…ÛªB)&LA´÷c1@t×�”"ŠÀBÈîU·eÖ¦=y3Z,‡Y‰ dJa»~RòíÅɤb 9Q%+iÀÙá¤÷µº+äœðb]4àK�YiÚuL$L|ÅÌW \¸R•�¨\¤$÷E䵓³³?ó¹Oå ßÛŸŒÓtóÅ^ú䯿ñ‰‡î?—D­Î‘)Z”ùMoM¾i–jNyî!4ÏQ�SK$@3··îs[x€)`N1 §p:‰‘H¦±ÜS›+þÕ*ÔjLU•{,»…þ’Wn�د—SÍVîú^Ÿß¾óüˆ€›·n¾òÃ?ö£ûäô䫚ä[¼*”î3³ÌŒoxîl¡ H‚)q8_ûÝÏ�®ãM�$µƳK«ZíØBÙ?ŒûÑcPRê°Ùœ”¨�®ëìrU2çc mÖÏ»—Jë™È r°FU ë}mçCPãQíŸ>z˜B—wîÜÙ#Æ�íUÇýÍ[·.ÿä�ÿĽiœþÎï}ýkâµWîýÙ‹Ë‹/ÚÏžž ì/ˆ 6/Õ}HV�r³^caÿ|È t•6qst1:i¶wãå½›½Z8€šUæÄ5ñ‰–$€#û? rÖ�c¼º:Þ€^EÃ�(õô“'¸}kãÏdV­q| zS³�Ù‰…'I™“MÆO:›Å‚8±.-Uàhã©ó9]º|ãŸڿò�_6w�”ï¬Þ['Ÿf§ÀDKžL3jÙö2ȯ üïüýoá Ÿù>°*8¦qÂæ„œ“Æ>1ÖÀ~ß\dkÿü�lûâ²Ï ê¼c håå.]¨“½@ñ¡gCO˜âmcÒ:ÏTÏ/”ÿ*¯jû+–º´6íT‰4ÚÄD€gž}ö÷O·'“¨&Q'Æ„8Nˆ÷49ÈlîÜ€Ô�+ÆCÉqoR¿õ-Yª =¤³µ;Ï!“ª¬¶sw4±¡¾÷Ïr7#ôÁ 1ù~¤ª¹Sʤ„ Ó4`|.pr²ÅÉÉ)6›m%Nî®íˆC@`ô}‡®ï�T¨Æ11¨Ë¤éögbîÆf�QÔèܯ6ø¡ìS¸¹–"ÉÁí¹£@Qü罟Êl|Ì |?ËêþÅw·¢Ìo×»%Óh¶o?üŽU¾3”ï�Ò¸,ÕÿÜ€ÿõø$«�ìPö¶�B¤<6¡G?ô`"L“D05³±Š;[¥rý‹ Ž4äÒL¸àL&¡â Pæß† ¢@ÈDMñ嶺ÀZk­µÖZk½Ÿj%¬µÖZk­µÖZ¬1ÍTŠk2ÍËŸÝ–[¤(¾SšÛÌrèÐqo àsaM¬tá:€šqŸ•|¹ÁŸ™ÙzDP jUV·VúZ�Êq wð\G**@Äšpûq�ýn�ý~‡”Ä?–.¤Î›2~°­N¶»6רªç6ãÄð&#äù5j®»ýùXdó33tõg²å{>h­™ð:“mµJaª÷µÉ m‰ù˜;WE™Ý+gÀßÐÏr„É÷YgCÃòJÒÚê²¾>Úaq�Íî–‘MàÍ@Û`κЂF˜BÍòž…M“©Þ*¤g÷ÄqÖ¨_(%�FõD®¬?s‹Ï¹´DHù¹lÕ¤­”·1p0‘©?wÙàÀÚTö`uÐ-gÖýg‚5‹a J®&¸ª)7@  €ÄhùÔ€*äJ’šø…¬Ö"‹\Î'P,ûy¼€ Ä„H’Ì%!åùÈç$"uî´­±nÀ´5fSŒˆûqÜ›c€ˆ7»3‘ÌÀAž¬^³k(EO9æ™ûßJÈMZ‘|6s¬k‰½Û¼Ìs éb‘­Ë < ª2i’ }ÐDt „�� ÛͶûü>÷«_üþ/nR’›ßøý?øâ«¯¾òîß~ÇS¨Ìžr*ó?—Ò&ޥ޹J2Âuyà®>øgukˆ|ûƒ¾Ðu›ÙScëΑØ4Ø�Ç¥´Ç– Iˆ¥ É÷q™o�ƒÓò£sSg/˜Ûû‹,umH;ís}ðÌÏc" t5¿“g?ðìoüÀÿÐß%·$¥—”èµ½O„ÈD ípÜ…SOFþr§�¬ª'Ù"Í�²¢:çlQØÏ“Š�ÚX r2P“;<ˆ^›ÍI~‚ƒH)ýB‰ (öî9³ü`Mmc "tüž6×ßÖÁùý^fMg7fÆùùyzâÖÍ‹)JŠ"Ó4î/Æq|0MÓÉŸ{îÅgž}ö?{üøñÓ/¿ø�¿ðøüÑŸ™büHÎÏcP�PTžûBcäéT´‚5•W]�f z?÷¸‰•xw G–ÖíºÿõȦÕ]É­ë  Äàà9XþÇœ ¨-_Íæ‹â¸¢øÈ‡ž°‹Á¾1`7íÚôþ™NÖ‚ B‘ím¬²¿)wö:ÊiòÉפdkŒ†DÐ@Ô—Ã~ñ•süÚñ*ÆÉH�¡óSJYå›­Ìm›1Û{]Ë�hˆD~¿¹Ì·öŠwøÿþÃ×ð7ÿÚ!±ÛºN10ÏÀòfGc'T%X�BÈp ŸÑ‚é@°}³¯ãöoÛ ƒ(ÍÎáΓ=^kºæLÔÝŽÜvjÆÕ}‘âs>»‹RŽÀÜeÆÈ«„Âãç>ü‘{D4'Ñ×ó1bÇ#ôêÊîGìe]Ò LVUl6¦¾Níw’|È¢EU¿ü¹ ~˜)Þë>ÛöŽ]�oî0ö¥¾VDìûöH)b·ÛcŸ# šcÊŽI´ßãêê�Ï7ØnO°Ù ÖÔí;#%!„¡ï0ø�•ê­ëH^3ƒú>%°PJÅÙCÜ+ï­™:drµ_r5|*¨ºL`Äi:¶ë÷Æ \×ù{ñ‹éÀž@ùŒB˜‘-+¯c*\”Ý.•ùµ²dQÝjtñ=Æïsç®!TâH{lùº¦$sbk‰R„`ßU»Î¢xú®óÈEˆ˜'ßsUw7[Ó.ü/ûÐöz.�5_ŸÖ”…2ÙSë÷ÌúUG J…À°ÖZk­µÖZk½j%¬µÖZk­µÖZ¥a Jž(m·d^MƒXÔ*ÓT-ß­ñÉ€+$C°¦ y©�@iþönåkŽ­4XGbsŽl~aÛ µ\SMRTÃ*dÒ£½ØV½RT·LHSÍ2�I�ĽÞUb·ÏOIKDÁõ­÷e£Ëk²P’Ï�ëú6~Væk’þ�î�ÕªÙ,ä³2°Ž;ëßÎðüãÊ-2»`FönùN�Ɔrž;;¸ád~$fñkê. mÅ=¤!@˜6û[$“4eÐÅmèýçÔñ|i?9R"õbnŒšuñû™?øìç?ûkPýÐ /¼ðÅ_ùå_úËzΪDm\5Ú9¸ð¨… ÜÆzNÚYXÚÓõkJþCÑzÒÒ>|ÎŒ ft¼°©„—å¼ ÂÌÈ™Úc™�¿âˆ"5·~†7sQQ¢ÒlöZœRU¾·d(ò¹fþ\7ÍvÂfØžê3Ÿúûúð‡…D¿¥Ð—Õîó…*ï ¸În�-Éâ$Ð( ‘�„-çÜDÉë£&�w”P"|t>蜘B‡yÊjÀ�²X&9©�“kp(,sšÁI-àbêYŸ-…}²\ܸ€TÇî½­M©Îº9 áØ’%‡{� þç¹¼MÂãÇW²9vÓ¸�»ÝîrÜïŽÓØÅ;€¶Û““—¾ð}_ü½Ó³Óÿó½—^ú¡W^¹÷ �=úQUÝ–›ŽœW ôר– …€†êý¨O+80® µ8~,r7×�ËÅ3n@[& (æÙ&­%ü|£Æ7 ÿ�¢¬µ?ôì ç…A�ÚØz»±îe¾Jêöñ’7!öI™{æÊg ¶÷'ìA’l¼�˜é ÁÒ¡Ç ÷îc¥øúï¾á¦-–•�Ÿ³½„êàQlâ'æþS„ŵÊã¢qÒ€âþÓ{ø·~ñi$J' M l–c׉1Å^¨Þ)ÿ·ý÷�PYs´qBòƒÂͳ€·îÇÙÚ|ç&ãõ·–c«FX´„«£c‘æñVŠ&0 ‹ÄBÙÃoON¾}zvvŦÀ$I $ßïöàîª$ÇqÁ4�¸¼ä¢H�)ád»-±-Ù]&ï)8P!8e°¿ïº¸¨(×ólkÇ[D•ê�úªp-"Èb‰¨*r^Û¥Š@g*Œl�È%ÃxyÞUÁÓ(:’@RΩ´i`kr©˜ò9p(*ÒeU½c=ÀÖþ6;dkt=Ò|·&òaCFJGP`aÓ²‚ +h=ø=ø¯j›¼Äèg§ªÞ>+ëU¹ÄLè: ‚BšÔÝfsî$U5;êX« #ÐB£�go¬[Î5»‚W]©O $™"Û›j9*XH!\TÌN:{5Xö»L­p`0›šÇrk.ª (-ï…5õÊecü>„¬jÁÂÖ0W[Uþ;T`…òs“�l> sP‚’"÷-­oÚd¶ªB@ �µ¦L îr†x“ÏÚºI‰öÌ~ ¹¹ ”¿EJ–›ÊâÖùìŸáÏ·Σ˜¸ëŒdBdæP@ÙÇ!UÁ¡«Þb’â" ±6Þ%%¨¤¢Þ›_¾ÚMj.š’Í3DàsMð1Ð:2hPJ«ò]$¾kޝXZ{ Ð]N*å9áŒÝØjÚCußÎ5³U ’âF‰Î”»»�èBU§ç>ôA�¦«ŸO»‹ 1y¦ý}¿YÌk­2Mçs µ“Åu dz÷Hãæî½‡ù(Zr«ç¯ÓFu—s¤3ð9›gÝÑ ;ß àfÆ+ËiQqÏíªçÏäá�7«As½T•ÖÔ(ìmªñ¹çžûêg>ûé_êúá÷ü¾B¾#¢¯‹ÊnvÐ `{DRqõ)6ˉ„Ç#‹Q¢r’»)ˆÌFiÉfnb˜›yŠòrÀœ bϽjÞOÌ`æ6”ã”CB_Hß͆ůÿB¾_ž=`F”bª 5Ñz toÝmæ€I ŽŒ»Iˆºñd{c<ÙÞ(Î/|û}? ›¡ïO™Ã­ïûþ/>ú‰Ÿú©ßŽ)>ûë¿öOþüË/¿ôÓ—o•¯óq‘/””ñ' 8_\%29‡*ø•�7¼›‘sqSGß1Õÿ»=«Ío¤e-* G3âõš·¡Œë6�Oð>ôÌ ’N¶hï÷N`–Ç÷h2òMÍ`KPÆùþv.ÑK}�—fò�Hœ°ÛOøÒW^AJbŽ4²g N¤�‘ðd—†HIGÆ.é|?ÑŽGõ�`Ñ7Àåå„_ù§oãöIôè{ÅF¥ÎË%WA‹GÙQ-öWeáHÍøVj®‘ý~óf “lŸq÷výö~&èÕÒÒµSýÜ«F¸ß IÌ€huÌ8fÈróÖÍß?ٞ캮C褱ßlLmÏÕ}'Æ"‚qÜãü\ lGœœœ`³Ù"t¶‡ˆ)U牌!€ÎS”ü¤�4�R²xµ ö×ƈØù$Q#î÷Ç»½‘³*^Uc3 ˜¶[#hA Yàêò �‡sl6ƒ©ût]�¹ ²AàPgo&¨WŠS4w� ! ZØ—wMÊ$&w¦àJnÉöÿ]˜)ãû. wÎ@¬à3Ú}â1·2ºö×±b¢Q«µáo¿ é|B=>•Iëã÷ ®|Ízpx<%FͯY‰qˆ©ÌÃÌÒ¢€®ï1 º¾·ïFÌÅM¡¬SLP­¤ ‹± >/0K³nF»W¾V„Ð�€.ïówÔ&" R¾SÔ‰\›çqí…¬µÖZk­µÖû©VÀZk­µÖZk­U«v�ݲß:²µ±Y"Š”1:  idƒ!8p:t�5¨ɬGý­ªúÜUóœÛž\Ô¾s‹Ç¹�dÎi”¬*IM¾x²laI•?й:íxc'«’D’åûç…@6„®we‹ÙgæFŽéËÑÏ.¯ªz»ý|#H,Áy/>éú¹Z£4 ë}@yïÜX¢Öòhü9KYÜw,?bТ²Ö™�gVŸdEP‚†dàl—½™ØØã íQ‘)ò¢�@Np`P¢`Í÷˜ ˆƒ¹Cÿ<:¡mø%M ” f±oTï6÷3“7ØÁ�!pRw8(¹¬|*gHnžóri*'L3[ߪ©c©‚”­)ÍÕâþ¯Lþ| µAŸï‘_«†ÚâÚ Ï*(³-íÍf6TTÉ!õüP³íf32~M™ÄMa"6§v‚�gê%ŠÃ{?fpèû]è]Ý–L~_¥€qùY4տͪ "U¥••Îäã²FK4.*5Ÿ¢yLmY¿•Äåá­z³š;ŽÅüVš³j€,Ê3„ÃÙÄÇcŽ=ÁÔ˜ÄíØÕ¤ÐKU\}™™“¤^3ïDdU˲Ž#ö»ÇFè{ ýÖ3ŽÝú¡XHÏ�–6øK’ÞkR-Ù××ý �Ç{úù=Ëý9 ìTÔØm³ŠgP$ÊšXóº� zü÷6ç;ÏezxÏÐüÎÄñîÓOýΧ?óü?>;;{àW}ÀKªx]Uw[WÍñB!A:)n¶þ%Wø{ô E€´D]ÌÀ˜¼¶ûûeÀ*Ox!0&Ö²çEaƒ©Í—ÊÑFÜ)ƒŽ¸õÔÏNI0¥ œ¸ØvQQ?7A>(À3#tØú#•Œ�àæ®)ZI$y®YI³õY”ê~¥��x¾—€eŸ|þÓM¯½vo—RÚ§¤c½¼qãæã¿ð ¿øþÁW¾üåO}í+_þ³o½ùæ�Äos‰Zh©ƒÅ€0�æÎDÉv«À<’ªóØ:|uiÍ€%|Oó-ÖôË缺ÑâŠ)@‹5µÇAd.2�LqRRÅSO`\¹¥>mq ½ÛÇ'ˆ<→ƒÖn³”ØÊ 7õEý,]Ȥ‹<÷ù�G¼þæ%Ršðõß}­ÌVW×'´óºÏ¿ü]ÌwÔøÚÌÓ¶4ó;ËøüÕ/¿ƒãço£ïŒÈ§Ù^Ž>øÁi6—ýÐ�]’$ðÔ•µ1«ðw»€q¿Ç'�ï2»ý««+l7 › :·bÏùõ!Tp<„Lìks�>K©F yÔS°«µ—ûÿìà”bÄ4îqµßawu…ý~ïZM£¶ë°ÙnË~ZD0î÷PULÓ„Ýn‡‹‹Kôý€:œœn‹M=6$te +ªûì¦ÀԺЬj%xOÓT3åÉÁèÀÅ5ŠC%�†À�í³ƒç«?ûîO3¹…?D*P³on¿Ö¯>×äœ5Ñ^u²z¤”¶.9Rç÷k¾#¶ç#ͽIqîä�ÕùF–`²8†¾ïÑ÷†¾C(.ucÙ¾þs}ßùw¨TÈ6ÉÝø*Ù4øÚNŠsט-�Z§6ßÇ×vÈZk­µÖZk½Ÿj%¬µÖZk­µÖZÖ~ðû%¤QUZ{pÅCJÉÕÓðcWþ3�—Uùð÷ÿ QZUgÍõ’—þ¶7é©5p’ÄŽH„’_œ3[›ÄVÅÁÌïÚ”57«9,œÐ£GPÓZ\f'€™‚˜Šƒ‚YË&(“)³g9™¹ó˜÷rý*°&Hh2ŠÛlÇä/¿š¦í±_3‚Æ¢·%xÀûÆ\»ùÕm!Í �Ðvp”Õ«�ý¢$- oh,´1kÆåcoA)vðµäWkl®¯«É]­Þˆ|ìYÞ½p›s�øõ²P“¿^­ªKƪlüTâIÿ™¹€¤vï-­XЭà` €B*‰áÐR­s_†øÅüçÙ•ËÙ�¡ñÔgª ·ú±J¼-]@×õfóÚUe¾¸2ž$“/¢ÙÑjÍ�…À³9GEÐ+]/]èfQõQ5‡9 tú~ƒ®ï@ ¤›ç@�l@NÁ~Nk®´hš¹ƒ”¬Û¦©l®Õá ÏoäÔ�ºC�5¼ÍéÄ] ™ZW•ÌbZÚðLÐiÝ)´‰SÑ2Æê5àFqMÊ:Ÿ½�3g¹œG“ÓîÄ—'Ÿ¼u±ßíîöú6©ža¡ÿÍ?‘Òˆ”FŒûK\½†â–Qsæó¨^/‡o?佺ah3÷\tÑÎT®¿Îm§Q]DfàoŽAAþ;WíæµˆŽº¶´1 hÐNj”Ûó•– ÈJ]¸¸sçÎo|ⓟøå·n¼ÂÄú�¿ à-(vª©(íc¢�›ç‘RD’T¬—‰ÒV“ÿžgÛ�‘ÒdÑ! fûÈc@ZD˜Ú ¬ e$6€j‡J\ŒÈI}ß!¥ ¸¤™-bG"(¹wŽVð_I{ø–R#³q3S™.�âÙZØ*Í › tBóõSçû"{ÖÂ¡ÏæÂsúH|ëÍ7_]í¥ïw»Àüx6÷9ÐÉg>÷ù—ŸÿÔ§ýââêÖ?ýÇ¿ú“¯¼úòŸ»º¸ü^"„å�š�#”¹’–P½“rÊšyí‡æn? ðÿpXª±[EmóNZè2Ú°·6øBžÝÒÿüÔ“È„HÊ“Ïí Öàª÷ˆ Ѱ¸ªß#X ÙY�:§hY:B8š*yB¯¼ò6Æý¯¼ò°$޹|q¯­ê¿Æ½ í^¦Ý_¡ÎQ‚qóÂwαÙB°ý@ŠŠM�êè�I¾K¾†DÍÆ±q¤Jæþ‘ýΕrrÁÜ�N†€À¾/Ppk{Mô“–6nhÖò°Š:Ö1U­àÉ÷ÅD­“M],˜ùòsŸûÂטø’ˆöD”@Ÿ—@¿ž�«ZwŠiœ°ßí1Òˆý~‡Ý°Áv»Åv³ApKöÎ�…t–E4|nŒ˜"b•:Iªs–x<˜$±ø3¶?Ç8aGìw{ìv;LãQs–ࢦÏNK\öIê ¼HÂ4Úñï÷;l6ôC�¡7°·'srP�q‰I 1–H´„ì,í>ù÷#ivìRˆ L íD=:¶}K«þ?ˆˆ®µäo÷çùùî © ¸ûÙ¼ÏûÊ è×È”6Yê«E;ŸÏˆz Žç1Å¿ÈÁ§dÖü1FÄ)Z¬”ïq3qÂÀÿ 6›¡Ž1�‘Þ¤q\hâB°ýeß›«E§@ ©`N±8ê¨ÚøËD†¬þÏDÚ|mR’Å«³½áÊXk­µÖZk­÷W­€µÖZk­µÖZ«41´A-Ô3‘“7¯L1»�o•f¯Á‡ì6ç¹ÙÁ®öej@¢¦—"PëÏfuòAƒ€(”k“>eµnpHVãˆ)¿ ˆ~ÌþÞÌ9P¦äÆjNx±ä„�Õ ”fb¶-ÍÖbËßZfW û|)Õ³ê™É�l͘6‡HZAÅæJùIafÉ\Uþ‚lž¦µF®D:jÞ{Ø„«N YU¢4eðq¦ºä¢®à'¼±Ü6ú´ÐP•€‚š' 0Ú…¦ùG0`VBUÑ9A€É~™}·VêõGõàs¨Ém/ÐW& 1ËÙ�³{wïÞýgÏ}øƒÿ(tÝË!„7Eä!� ´#âAvP¾ªÏ˜u]Ã݉F¥qÀ©€pd®Èv1EHL§úùÐZR´÷ç`i`„�ÌEÑ]¤*'7›­�þ)"ÆJÖ‹þ;9‹­…‹K|@Mlžíaf{•„ÌÆˆÛK’ýñQòǻ허´™cšÌw?اŸz:Ýðà’8Œª¸Øž¤®ïBGĈ6›Mò“úO¿0�ÓßéÅï|ô÷~÷k?ÿíw~fŠÓ³™0WÓa<_<§[!ž-ÇîI…ËÖQf&ìn=h¦î¦Ùu*tA]Xú£:d…8iuÐml `aKdøÀí$“ý\RpÝñE ‰äëu¶¯³lg 2"ÝB&;ð°$ ô6»ûœ¯šLQŸRy¶ßyø¯Ü{ŒiŠE¡,âq2š’I}V¸!Üß3Ïî&Þ›«dŸðø2ââ"bsÓÜ1ºŽûq�ÿJ¾ð瓼“JNp�ý°×Ší“|:-÷’ÕîÛgáp¯Þ—™Äüyªc™üÙ™I´£—nFùÏÛ“ÓßÕó§KF(’;á#€ ]À[0ºÞöÔÄÓ8!IB=ºÁçÇaè‘RoÊn²H#ö1¨ï«³ÃLýž££æÄ^I‚4%DŽËa®)%Wðï1Ž{Ës÷}qV{÷ö3½í· ¦ˆ)Æjýîªói2й�¸©ÃES¡ÂP±½§Š"a²é|oׄÙö½9I"GÇÄ�àmƒ GpÇ踒 Ì®û‹ü³¶ÿ‘»f.D�|=Chß�gfy­ì;ûåÔ+æ„rÉëdÞf¾Ë~ä:Ç‚|^ìWug»†l>9ø?Mc%Nø|1 ƒ“4 C_bRŠF蘦B¼Ë{c‚‘îú¾C? è;‹?™¦bB[?9MF*ß�óu‚`Bq(? !å¹%¯¨yž‘ü_k­µÖZk­÷[­€µÖZk­µÖZ+·7\‘/PI¥1Ÿ½Ç³² ¹éÊR¼(pQq°¿Ž˜fŠç äæ.Z/êÜfW“e�JJ�)BStB‚9ÅTtDYM’d­%}®ëríá.ª pÒ4¬»Î,w–'SYª“#È‚êj3Ò¹Ä^ÛmítsÔ^c=ë¹Í*Õw lÍ3£g÷h2ÇÛÜÇ|-PÔM¤tháݾ6ÿÓÿiÁ']Xs¶Ç¥%7Ú¨^³ºª¨ �‚Q¬�=Þ6gª–n^ü TíJõë仪eö3#wåŵc'”jlO¢ˆ”æVâKùÒ®×Ô€UR�yª xj8fšuÞÛëÞvÍ©ùŸ�ÁdÔ炚îoVÞÙ1¸Ú�v]ðŒ×àME;Fòæ¶ß8Ë/ÕAQ!te~Èã$“DC³/ÛâW0?»JàÞ÷=ú®G×õ®Nµ¦æ,öCuaÝš­b{'\äëåÍïÆäX˜]QÈ�5k9/� DМ‡®ž¿›•Y©�½¨¶·�Ù#¿½±Ÿjƒ›¶åTìÉKf¯êùîZt–9ç¼4å¡îþ¬Ç=TEâ4ŽÓ4îÛ�}¨f•x“›ßÀ€šUrèÀÜÛï ©¯ü@7Ç^^¤sEvVϪÎ\æ¿ òÚlà£Ìk Á»€¼ó¹õÚ6ÖüM«š¼I÷nãWü•¢‚8ŽøÀ?øÍO|ò“¿Ù÷Ý ¼ÐwTq/¥ô–¨<âvÌœØÉCLR®Û2KYÔ2½í5Z›ú�­1«øº“ HåÒAÔ€«( »«KHÚÎ@óV"™³ßI t9Y;Õ!0!1{ܸæ§§§˜¦ Ó4�i´cÈJÊ yË@^#Y‰´võÀaÌÎ2"HÖùlãÍ…„WÉB•µ¼Ž6‡˜™ªµæB·/¦ÆÉ¦ÇŸ|â‰$Jiµß�û!lO6Ä!"lœrgþèGïà¹ç^Š1þ?¿þµ/ÿÉWîÝû™óGçß/)mÏ·Qºú}ÈsÍõÛ¼CÛöî1@KžG;†õpûh„·YÎCóQÅ=ƒ4œÅ£×rjœ0úÆŠ& ]º/NRÙéX ÁÆ:£1,P@4¸ÍBf¼q¨H@è@HÐ.™›�W{¼ñÖ%bLà °ë­’ ¨¸tš(,,¼šk|üÞ+‘’HUàµ7ž{jƒ.t n6»ˆ¬þ·y€“Úܱ=û $-H€)Ûßç}Vž?ýÏ=Óñ¯GܪèúÝäì9*Ší2­j±o'�»œ��ý‹«Ýî|èû ÙKézWT;i®ïÉö+ý`*uw "ìè ã4AÜÅlа³½Fßûw�üK«2:“ ™}�ºÁ÷¨æŽ@ '³2Æq*g+¢%ú(¦d.û�Yì‹”}@×÷¦æïp°=I×�nû1ŽcQ}ó‘È0"Bß•˜™� Tfs“ªB“bÒÑÝ%dnÛ_îIv20ò°‘q+q2«ôsŽ}LÑ}q‹HÉlñ³â¼Ä2йcjÖ}ùeª÷ëöa¢j�õùmþwÒ‚ÿ×eÛû>%.ˆçÄÝ&f¥Uÿ·ÄºL\‹SDJÓKô�:l· ÀaØ :0‘ýL2¢Ä4î1î÷ˆîX—IÍÜ›ëÖf»ÅvØ€™“ÅøÄ1MÆqï;N’Ïñnx“É题‘vÍ/yÔ]jÖFÂZk­µÖZk­õþ©•°ÖZk­µÖZk47rƒ*E³¿ÏNÎJnî\a’¡J~£5 µ~g2ób�ê9ö ñ m²Yªk&¤Ý8ÛwÛ{ RÖ¼SÏ2ÎÐUÔZ¾ËÈY¤Ìr3í½³²5«ÀT¬ûERiÒ…¡Ì  ZÏëÌz… �Á—YÑw_·Âàüçy&²]«¬Ä_æ&ˆ+Aï•ÿØ|P:‰&·Ä¶×˜-~¶¢÷li´Ée¬a²{BVé,3‚Ù¬x ÛΖ¡ö~?³®=f׌&qÀ£n‹Å¿z³LZ‡ T_u Óγ¾_[¹¹V"+¤‰oˆIªò¼½7pRÄÒZ$sP9o®~噸M,A× å]u ¨ãCHüµ´UAD�³G¹™æô­M®Éæ`q‚€¶0s ¯ù±˜sô+*³ÜÀ.“ÿªy±Ì�7:“�#nTšM<‚Ûëv¡Æ ÖLç 1f÷ŠÐÌ ùZTµy¡�<ÊœçMpv‚LQÂbŽ™ÏC!¿‡ß_%]¤²c9ÍH@à¹H½ød_Q�Úü,ä TA¨««Kˆ(öû=íw;jýÆ[°ý ѹùû¬NÎÿm„€# ÜŸ®¸+÷ ®ž«VáT] ê‚TùDd Ð�KÌü_þl{lïY�:yžÔÒ\û…¤÷àšÔ™°C®hMqôX™è f`³í¿]/ƒéE‚¾"’^ð€”’8�cf”xδÓ P–¢¬. …+æíÿÉç^<ïÚ¬{ŠË‹KwÀQ0Ä5ØÎCPmø«}¹�2õ·0ùsë9á¢8==Å8Na_Ön#â¸z–S¹vÌ•¼#Zç73SqÐfé€ãÔ�âmÌæm˜ô.à%nêŒH´ºak~Ý0>¬—Ò6’¶! FYÐSódYß q†«3Hë=&àô„ŽwZޱk#(t¶wÈDƒY¢Ñb.÷€"·ï<ýOŸŸ?Úl¶—›Í&n6’T8ôàÎ÷dŽ]½Gu ÀÜ÷®®ö˜¦±(óÍÝf*¤¶˜¦’éã„m:Áf3 ¡XÖo6=(˜K@Ù«ƒ#Nc¹~)¡IÔßÛ­â³Úš]õ¿Ùl0l6Üî]UÁ�‘RÂf3`ûnÆŒ®ëmï\œêw“Lü£DM3 =�+ J¼['�‘àÖñˆ+Ypw¤ÃöL«"NÑçØTÖ»–ÑÀåLšu§zñÝ¡´¶±Ýf¡Jù=[çÚ«yö¦Ù VÕ,D‹èÏnµý§ ‰ÀÜwöȸ–’K/åúk±‡žÇD,UB³è ØNÓ,ÿØÕQê‚f·of…©â †Â„~Þ”kÕød&q°1Ç–k_ÝèèX±?éñ×d_V/jVÿ,sÉ©X,s ‹ -Yõì#%\§é<82Y¾®4§yÞ¤n,Ws ØTÅíùiö¬½ò«dƒ.w°“Oˆ ¡˜ )Ûm+É”��ƒN9"€«óñ!ØpB ¢l@�0s&h@2"h&/�¾÷�ýùP!,É3Ô áËËK$QLãûý8d>äúÞöY«g�Õ«‘1�eLYd@‡úbÍL~ìzlzZÞUá|dþÃ�Uÿšt?ƒÃñ{ðÈÔÉ(Ïot@ˆ²õ2IB’IÑ�éÚãŽqz¤ßô%/ü@EšT $FÒa&hP|ˆ—,…÷'Zïe%AÙº™ x…<¢ÀÕnç@N‚(!'¢äér‰2 OF$ã˜xl…PÃ0= ÃÕ´*bd‡B¼#+H"�E|1k¡2ÛÜ‘o¹Ìì ³ã Q»ögSv ©q…Ø€Qô/%�4wCˆf ÒÍæ$=:xID Àà²c~ˆ¾;½qãÖ+_üþüýãÿýÕWî=ïåîâñùO¤$·*—¬úÍÙï±?X&Z€òÌPy&—{„wo´˜€�9ÁæÈFÍ4Vô„i˜:( HHT®@i„Ò‰-i, îQã^ª;�:3�[§ ˆÍó˜î±D\×F? Œ®‡[µÛÞ/•ý@Ž-j GtdžÖö>-žŠ†ŠÑ¸iãÇ`uóæ¨¿eÖ�¡X&¤ºŸÎêþêÎá,±lõOæBMtJë¨BÍà‘”]N´lÕ®ö‡„‡ïfÕPÅÌ ¥ìqˆ F­-÷03§Aýw¶'§ßzüøüÏÔ:ópõcs‚S!|æ8:ák¿'ÇÔDÄÅ䄾ä㣺xµäÖÍ0˜‚³E?ô<úÆÜb4'œ1ŽHIÝiÊH’� ¡g#Eô6†ŠÐå{*¹|§N‰™ ¡Úùå÷¦¨ÆB˜¦1¦B—5`­µÖZk­µÞWµÖZk­µÖZk-k8¨>MÓ8!&W§¨ÛÚ;è\I“�›Yâ¨6 Lo˜=4e<€Ã<çœIM…CÁà¢ôóÌÊdàq‘ocTŠ¥±É$ÎöéKÀ­G£¾&Zk棠‹]½ˆææak]!À¢ ·…+ çјyëÒ¢»®3@ŽÏ,Ì\õœÒº½æh˜õ³HΪ_ÊÙßÛ;;ÌŽÕ ˜¹,hìC­á,Ùž=J£iksË©¨WʵtÕòc“H%wzh¯‘f«ljìõ[õ½ÄOÈ‘{®Z_/*Å¡@! ”ÀÑÁW¨ª7³òÉÆlr³Žˆ®¶�S²¦;r&,ƒBVq¨*~�“o–Ç}x_©ù¿úysŽ|‰Ë+³óPÉŠ I}¯Æñ ¹åyRÑê ¢M$D¨ÛgÑÇŒTõf½Oµ¹ky¬>?ÈBõD•t˜Ñuc`Öâ ,v-Å Ø´±'°0ŠªžÊÖÿºâ6Ÿl‘ö wÈxåçbÞšÝM]@×e\.4èìÄ)ŸsµÉw¯ áñãÇåº�MÀò fªh\ú£È€©A K\@s&)YÖ-pY>#+ÿÁ£Byž�~žê± þÈœ…knJž‚+xß’ˆ–Àdµª&'ÀŸcb"Ô��¬ìÿnK�ˆè•@tO‰ÞÑTcûÌ€f{ww€¨ÙÙ­Ch¯µøÜ¿˜¦ñö·¾ù?õÎÛoÿì~wõ½0›¡¢ü-�£âÝø;ID´ ¦?ŒÉoÙÄ�ä멳½–ÿo9o5ã>ïý´¹wŸ~'3ˆ¶æ¨¡°©¢mÉ’BD¤²x4w[ó~|¾´á¬Ð Nú0'«<¿R!c½Û¢Õ\‰k.JëT‘÷� ²½¿±‡ëkÊ[Úëûaøõ«ËËÇ’ÒEJ²—”DD$¦ †MÂÐu�®ƒHW\‚е¼+燾Çf³ÅÕÕöû=¦i�ý~BœF$IP‰b1îÆÁ¾‰' , ¬ `5ÐZ¤Ù“8ù9ƒª #ß3J¬RoÖð› æ3‡òÚüž25øÐ£Ó}?àäd‹Ívësi(Ϥª–9=¯QK’s�CQLSã3Áƒð4€!Æ`ä%'GÆ8�O„N´¸7¤”0¥èVøÉöbMkÇHÛ”s“`Uµç¢ÉX1¥�©¡*¡� !pç6ú�0°’&·À¶H V¨YÍ57HÝÀKm†+€‘›ƒ-1cÞÜk€Àæ°kÉ_ÁY…î E1”‡Èr�E¹6N±lÐ.¬…2Á¢STuW�Ø{›Ÿï Ïg™`‘?37»3Ù¢Xèò<«ÖþLÈvϪRþ^Øâ2Ô›¼�ù²+°Éã \­œ¯'µ^óIƒr9Í÷ÐþÛlÎÒJx©Xsõè@…›-z »òù$ùû{·9=~\ž‚䪶™âŽŽ€séæ¡Ê•ü©U}Ï×kq,Т4o›ø6V]Ý>ŒÂp’J~îÇÊ�©þµØ™$¢3W�%1hIú®•÷ßEt˜†ö}¾Û�R-þ¥’Ê|=r7—r-ê¼ÌY ¨(Ùǃ$“l4y&;ÊÚe—ZŒzJˆ™8"qBF’Ø�l¸.0�Š‘ ËŸM)9³±B‡aðóÄT£y²‹�¶Ä ßêlˆ‹E«p@yî¡ÍÃ`_«£í/$€2:tî ¤IæãéÈ3 %Ž¢ŽW‹U0ç[ëùȺX�$뱘â—q²9‘qÇÝÕ8&‰OܾŪý0MÝY7Ž7¹£ûŸúÌgÞ‰)þò;o¾õ¡Wî½üç?~ü§™øé¹1ØZÙk!Ûåç™JÆÄ|EÖFÙ¯³¹]LÒ¢ˆ¦e*Õçs¦vŸeÛû  1b%„ ,`�ì]’´±„ˆ6hK@rBˆÂ²ƒÊ¶€¸GØAÁ¸qv‚çž9Aԩɪ¯d«|Î8xÞ¦É<×SØ5ãD=+É<>f3|ì#Ï€ÉWš°-ãLH«Y�ú�%)Vþ�,½?æ–ãŸ/yOéï/‚«½”¦œt±—ëÒ{í×DË^¸º$)¸²kD~ó³³›¿:¥x¥{ìT5ŠÛ�gEuì7²³ƒþY]¾EúÁ›Í——WØí.At‰칌b€nжœÜÞ]µd­€¡Ïn6NFeĘ$„ÀN\–J)ëŠÅ~×uèºÞâÊ>GÄ£2˜-„fÆf3`»=Áf³Aßר¤Óìçs>½ý½ÌHÚu¿‘‰lN t7î-Na¢©Ä¯M“‘ßbœJd5N2YŸç»b£ïrF¢¬`h" Žþ¤Qõç1Î�Íaî€8éJb*_™õÅå`¦Ùgu¡"rgqÒdUýOÓdc%ï_\½ße÷®à„1M%!ª`'Œû ûýTIe «Ñª �‚$æTAĘÒä1BÕ½¦Ä? ¯E�0�žÊ|ý®l9: ëºƒûµÖZk­µÖZk½j%¬µÖZk­µÖZ€Ýî )U0«eBèŠm6…å–0��Ú\qj@ÊH¤”Ï( ïâ.Z‰–ÁHU�V j²w[¥[à*�K˜ƒjö[¥–M¦ mþëüÜL éÀ%Á²d]i“R‚¦œ#nÀ®Àšä�GÌz¨™ðYMÌ~ž±±§/j(ÿ©lãOÅzÙÅåä¶ÚÆOîï³ñm!³™º$ëc GA°6:€7 Á3ÌËuÎ ”2,¼éŽ2ËnQþ Ô²NDˆ“‘*8+ðáVž¹yžwlÖÎóûOÐaÊŠ9R1SÉ‹4jy€C‚ …T›®(O)A¢[¾j*�ºÀ\PΫoÈ(1EÅ¥Äodkâì`žx�–ª²¹ú²-f*Чr^MBÊj|¢b±�K4¹²Å:Y„Á]@Šj·Ùs$§’8˜g·¤zÞùù•úLäGv�ò[jyfbdˆÇÉ·Öº3VÉþårm–¹í\Æ„ÍSf¡ªÕÚ# ØÕRÙ¦öàÍè˜íq2ÅôøÂÅEÁ®µšbX[G‘ú¼Î¯ Íf^ªôm!·CÏs"ÆÅå%ˆˆ˜™æÓæÙ[ZKP?“4Ž�¹åSÜ Bç$?W¹ClM0×íëm€Gwðéïöú?LœÀ¿ªÚn6)„ÀŒhžäÐy4�Ö8•LH©Ïúò¹÷ó²xž¼^T+úU›gÄ5lí�BÍVêZ“2ܤ’D¢…Èìz§�ŒÃf�=%)q#eŒ7 L¾½PéˆyÎW-×ήI¶4ŽFvÈd›Æ  ¯žùLÇw6ó1“Çg»öq!µ&{<0';D´@•ý\¢` Œê}/\<Þ  »'oßÇ>ìq… W yôÄí'Îïܽó"ˆÿ_ÿêWþ÷’ä™r7ŽÌuÇ“yîu%°«úé€ÀCTI{ª´ j�î|¥i‘3ß|Vɬ_Dqøzö΃˜ÜÖ_#¿„Shºò=ŸH€ÁÉO–¿ÒØÇn]îª~¥�=¬%–m†l6gq—r!FEœ˜‰Bfl÷$4#GæÅRgqö}ÓlþÛ½fÏ3´^)À8¥d댿Wµý�Õ�NÕÖ§†Lˆ‹[YŒ“ÛþGìv#®®.±ßïìþúye7‚|¢DLiÂ8N…p''ìGs�è;ûþîU…}¦ÍïÁH<¾”†únö}·uZk­µÖZk­µÞ?µÖZk­µÖZk-À~K® fWØuþgu†i[µf27ÊÕÜFlUP… !5?“Õ„EAH�¸géG;« n±«Òæ/¤F5Üß»Õ^›'Ý*–Œ [ûv*}&mìéÕ›¼¬L·Y¶3%*af‹IT3ÒͪQgŠ�ƒÃ-·í]p;äÚÈ1›ruU(cî¾{è”@‹k[m}›:h®Íc@À”¼�˵¡Ý�-ìBE?÷C¢F;&JôCá ”0 (dýõÜ¿»Œ5e�+çæ gþûl\3J´…ÌUÀp¨&°H2e9skÞH›qEÞ…Fñ4‹‰¨q€ûTž�¡CkÔy¼Àr¼gf¹¿×+šÛÜìD©y¯à�bÎrmçŠì”·ÍãÇÔVT€ìò®œK8íâÂL{\’¤L"ö¼äkPÕÂY±ß*wµÉd.צQóºÅS%&,_›¯U÷�vê˜eÙ/ÕǨî)Ô€¦e¬Ížq:ÈNžÍ�hl·ýŸB~öò-—ê¦0�£eï†@}ßÓ{Y¿Ò! þö^=ãvJ= Ñá¼ÜüX›?>Sj7@ìÁ³þǨ†ÍV†aÆf»ÁåÕn¦x­jìl{¯EùX¯ãÐ x9†«£FÉwP%]UÐx³Ýbô}T�œ”çå—°5RæL»™HÐÞ±qÜ5ëÜÝaîT’�³÷¯ÙМ:0¹ Š;#°»t"éMÕÕa6Âf”·Ùú®z‰¤Z¿cáâÎ,P1×–å<ÚŽÏeTD`.ïgà šq *xðà±Ü¾sóRT’JÚpÅU× 7Bà«2'éÜÜý/ÿ­f¼ÏŸ'cµž æÿõ½ž»­,-“”2…ek4‹9¢:¿¡¨ÀiöOoÜßÁÜ›ß:h¸@P�R² å}ÁhÇ�FHòÂÌ=£úµ4î ù¾ç’°â¹gnã÷~ÿU<óì-|ûÛoB HB‹¨,IPÍ6ƒ2À½Pû·ÛNiHyu]§†ÿè?¤d`>w@zè[•9)«~@ªJzñóeÒŒ�ì ~D¡A@ʸ¸’y¬ˆ.e~ÒªõsiùœÌ#`–¤ÚëöûuxÖqrrrö϶Ûí%€@Ì wœ&e�p™É€R�×Í6aHCQʇСë}ì±Ù ˆqƒÖ žŠ“|_’£r¸ìMìþl7t½EBdW&899µŸ×ò=«íGؾc¹Ý]3GjùsL qª. R+B`ô]�~0 ô]׬‰n)?Mç6�3ûÿ™½ý<‰láԨ㘫ó3QU”"[<À0  >’*%.à¿&Ebª)Ç¢ùœŸÉÏÕœA¿-$°Y�¿ÿp‰Â9FêÍûåìœ3û–ä®s9#__#¤¹»“ÇbNÅ�JUÍ�g±g‘6þ­ù>jóŒB$b?Ž §1NØï÷¸¼¼Â8îm- ’jèØböÈâyâ4Ùwt'·N1bÚï1ÅKѺ)„:.¤�iš@œœ\çÄÝLîï{t¡›þ°1Fk­µÖZk­µÖíZ k­µÖZk­µ–50b²¬L·Ë6 ®èÈ £f¶«t‘j=ÜšY¨0[ÒbwZ¬–zÌÕºý�¨ª›2¸ÏT±9jÀÉ?¤Šó_6ã°Bø�b‚`‰šm&™Â„ˆKöc× ]0¥¤¶-QªÙŽ olÉŽš,.� tmÓÛÒ4·;⢀lTKb=~mdyÇŸ«Œg È»\¦Æ ß>Bª}6eàñÐ2#¸`“(¡ˆ&gMäe>nä} Pn  ƳñTíëÏr°«bV¤j,Å»œ9Z§…|Nöža¡´›�sf�Ö`6r�7£ @ò&k 678;qxS2»b$sh\ Úsj£˜PHÖ-Ü�ÃÓÊòY“[…׎¼»pˆÇY´÷ë`B€ƒƒÿžõ (b± 5k×”¬ÑND e@Í>Uó|à­r–s69/Ÿïj5B( Ýl7¯MÓÛ0,Ë× R�w%)Š,Süyì ÕŸ=f>ºËk,õ‰�àØ™J‰ äÖ–ØÀì›YËÌà#çñ9‹ �Û½ÏMçeº._ »N�õá™Çs5ªaàÝ|°+XI.”�‰`±úüM{�çk ý¡TýØ×ÿ«¨‚ ›�†®ÃÉv‹‡tnà±2H ¾F¸]ã)|ò¥]þ«Î£:æç^ 7àädƒYøp‰CiUɘsò\«ž?.�óEµx·k~uµÃ0$°¸L›ës“…Ž&ΰÜb„NIT>;�E}8À¤4‹x¨k‘Tg�ÆA£u­Y^«9qh#‡ŒPÌu#» 4Ä›¼Æ” ÿ÷)×;ä9§Ù¨ˆ ïÜ$OÜ<ÝÇ!ÅnØND—i³=‰~‡nÓ‡$€öŽQ}nóŸH¢Üí¤—óCõ‚²ýP±ò?£X»_7�þlaš¿£½è;/?i2Рèz Ý0�d,à? {!"èÞ-Û¿¾ÜXÿX¸`i%ÀÝ'oàέSüÔ>�^x Y‘,ÌÍõ )ª’õ¨>“íÂ<£`SvKò™�(þÆßø ¨^�ôôêå²cwùGb•ˆ‡óìHæ8Ó�-¶J*! äbØ_ìu¶¾ €㜨xä.Ç�êá²0#Ç�vªŸœ\÷ÌÓÏþêééÙÀ$"Z¥T§©ÎIæ ý0l°Ùï‹bžÝy©µ<ïºÞ@lª–ð:Äh`ºzÔ4�¸Ú¹:;%LÛ-úaðyÌÆSRÁ�gsy¶þ÷H5sU« ïÔ¬ùy¾IFÊî¬m8ù¼Öªî38ÏUýŸ¦iÄ8Ž3w³vÍ›9aIæÕÙÞM˜šØ*Àòl?O~ûL„i"SÉS‚ Éb�4HÙ;_»×Ð�T¯Ù[ÒX=Cý¡PíÏj±Ù¯s3suw"·ý'ž¯GæØÒ!s(Ï{»v´¤n5r«ÈÞÆL4g‡q¿Ç~¿·q«½å ]èŒÀT>3Å„É�%ŽÑÞ3š�‚�•êØ‡¼Ÿ„‚DÜÌ^Ûw†a@?l0ô=º®¯{þǵÖZk­µÖZk½j%¬µÖZk­µÖZ€/ýóß\/ÂEõì³Ïýû¿þoÿ;xüè»Ý9...°ßï bŠŸÍf‹³³SܸqÛí]ßCU0îGì÷#öû©Z ÚŽOݺ�7oâÆÍ›¸yónܼ‰ÍfbÆ'ì®v¸ººÂÅÅÎÏáñãǸÚïKc/Ô}סó¬Ó®ç’[ºP”H½g¬f=ňýn‡Ç�ÏquµÃ4�%�=ÿ|ï¶§ªŠÉ³NÇq�«ÝûÝãh?BÀf³ÅÍ›7ðÔSOãøî>õnܸ"ÂÕå%>|ˆ·Þ~ o½õÜ¿�G�aš&;�®Ãf³Å�g89Ù`³Ðu=BŠR(eBK‰¶&êÐkÈ…>ÿÙšÑ)%LqÂ~…ÝÕã4!¥ ’²Åz(MÙì Bg*1˜Z}šÌÖsšöˆ*8:Ü8y'§§¸qã&ÎÎnàôä¡ëÀ�bÄåå%�?Âù£s\]]`?î'ƒ º¾Ã0ôè‡Þ<ý`ê÷`ªY‰‚iqqy‰óÇ�ñðÁ}tfUŸöWWxðè!Þ~ç�;wžÄÝ»OâæÍ[89Ùzc8a¿ßáñãÇxôèðì3xúî]œ�Þ1a'\�{Œãˆ1Žˆ)™°“�ìvW;œŸŸãüÑc<>?Ç4�89Ùâ#ý(>ÿ…Ïã#ú0þÝÿÉÿ ÌLÛí& Æ­ÁŸPb>ìFX4ê©Ň–þ4Çöáª|jlÁ%qµŸ;(Í£Rì/kt1 _ækë PÿS¡cÙnO´ë;œô�Ÿzb@œ¢Þ¹sŸþôóøôóÏëí'ŸÄÃGçøÆ7¾…ßùúïâÞ½W|öøè‡?Œ»OÝF×›wÇûqDL¦Üí»¡ë Qquu‰^}«Ì !tNôS­óöåå%ÎÏÏ!Él§Sb©c*C-E&î�å¾–Èû×Ýî)u˜|ž‚[úï&{.öû=öÓÓhÙÓ `:lzΛÇóýñ¬ëbÇ<ÏŸÎ6Ï�Ù,§9°$i-Ø®*NĤ)bœFŒSÄ8Y³ø˜å®G×p×¹’ÒÖŒüXÔ¼3zÆ»$ÄiÂnojÐý~_ÖÉaprr‚³³¸qãÎnÜÀf³E`yu)C?È0l5îGú>\]^Ý€êéü�X>Dh\—GŸÅ¿©6äDÌm¦~¦¥;Ù³Ý>Œð šHqÄoþ6ˆ4“‚šãûæ‹�‘¢+ß‰ÍæŸzP8éåSZ#H™+¤vÅ0�àÄt_‘YoìÄ?¨ Ùˆwn?�Ï~zÄ3OßÀo>ök!æôÔ:¿¸Çä9Kg·BgÊkß¹5‘ÒpÀýÀ'ññ�} —и‡ÓÕ~|v³ QÇ”2!Ãã{8™@Ùäx¦z«Âo ²›ÌÕUrfA¾›ÀÛR3Àøš§å™¾émýÃÐDÔ÷*ªãpè‡ï|ôãŸø]b¾SŒ˜œ�1BR²uÝ÷”ÄûÜßnOpr²-Êûì~’I«�«é-"Àæ†iÐu#Rœ άˆÓ„ UL)aGt½íBèB&ÆÍÛgØ�§�TÊ|Óé2¥øž÷�]gÇß÷©� ò9RèòºŠZ@ŒH1ú}®û˜v¾Ö†è"�ãX!YÍIlÏ’²úßçHƒÞö }_>+Æèî- ±RÚh©Lž†š§ŸL¸hÁÞ­2¯àò]æ†VˆR@ÿc#2Û÷çkÏ cæXåϨ‘´mÿmîê¤ù¼‡ÇÀˆc´½Ûdàô÷0g ';A$„ ìñ "y̤Ûƒö>°}è?V‹„H%#Έ®]°Ø�~°††ÀBˆ)�&Z¿¨¯µÖZk­µÖû¨VÀZk­µÖZk­µÖ‘ºº¸ÄÕ~W†%%¡Ø™,³º³­:±�©¦þ1Àô²ÛBK¦*¡we‹5{zЦº3¤Mí J“O¦ìŸÔ²Ly"oJZ£/yΪª ¤àJ•ˆÝ~‡ÝÕ./¯Š i×u† †ÁÔ&�çOÆ)`×]sËÒä�]Ì÷Øíê5†›ígn{ÚZ¦îvûòçœû  4îò5”F±O&—vm\ΔgkDvN¦ Oj@¸ˆÖ,dîÌ-`ùÙªjö›ÕËsÓn¨Íáà :h$(¢˜F´ 6› A×±5!aïo ^WÔZYq˜A½©³(“.ÆÉÀµ”Ðõ6¶ÎÎÎpçÎm<õÔ]ܼy}?@Õ¹S´ëkÍD­¶ã]lóýIå>fÀ°0ôº¾›�Ž ³>U¦Eð�¤6�W)*’ ÄL(Áíf×’+¨×Eêº �)EjóÝ;Á“7½-oU”Á°f¼²º“¸©LÇýˆ‹‹Çxøè=z€ËË ì÷{ûù®³ë:t½;©PÍ…íº©bö±))¦I!B¸ººÂ´ÛHàˆ«“Bù¿ÚDßê‘_ÛÊã{³Ù`è{î‡!l6f&ª„×áó÷oÕwíù§YPyôÔ…Ëxv 9t F!ÛÎwyŒÍ|À¿u÷ȯ}¯ú×M`&Ýlzí»}P&"%"OBpÙ5²ï~{íçêþÆ8Ç­~Ý1ÂÕ›àÔ¸½Øš2ôú¡7‚1&6ÒÌä¹ã‡4.ßÕþ^7÷PrÔ]{´Žm@ÍÝn‡º)I(ueÎ æj �̉d‚€‘çά�­óºˆe�çyy¹V.+¯9DËpŠL`2ÒØl«“?Â5‚èfÜ!̯9·6Í@à®Äœäh[›b±5§ûq�~o¯ÕÀ,R%J)‘¨’ŠÒ£÷oœpÜ£„æQD:;ù Ø·ñKG¸»Ný�êäO�Â}>YÌÉ!õ·âG¢uhŸÈï¼ü¢M�Þõæ#Ò@ 4¬$’Í_ € #à÷B™}nk]¸^ J` Í„ ¢xöƒwpÿü å/| ÿ§¿ý¥â!¨NX¸#Ìÿ‹ ¹¡8q`§•à3³$–×ý?ÿü‚¿eÚÞ@ŠW$S;—CB$‚$¯©®ðÏÂ~v�]¤D'TŸ 1"& &”ñ�ïÓÛcsŽõÄuù7ï:­ê,®ýX@™ <ùäíÿ|³Ýž³bŒà)€h_c$MÐÑò³oû�ã8bšFl6Û5ú~0Û Û3Ðw¦>"ÅÎl×§ˆ$–»§ #ÆÐ¡ëFô�½Þȱ=ž~æi nóŸçQø½ …`¨ÌÍà~~MŽ è‡Á÷®SŒ…€ÉÌGãsò>׿Ÿ„q ÌÌÐÎ÷¢Ù Àço"ÍÆG×Ãì¦Ô÷Fºb Xwüozl†¾�sdÔ1(¹8¨HµÔ'�hÉüÊO�Å(Ä£r|šOgÙåJÉ•îyP-Ibyÿ6B+ƪƒT˜­Ëk­ª6œþñ!²kÂþ}­¸å%Á'ÿÇ1Nˆ12T&prqŽëÁN(³ïxºx¦ÚØ/Û±Ú¾cF80N§{×õè;ÿþÕõNÜîʘ©º~!_k­µÖZk­÷Q­€µÖZk­µÖZk­?"õøñc\í,2y&¤)5 ÀaÓ{c0g5¢4ˆE´¨7§q�ý8ád81…Òd�&Ëîœ�ž ë€¡ï!Û-b´lÊŽS2ðÖ•ÚœLnµš›ŒÓ0ÂÀ Ø�£q±ßï°ÛíÝÅ *–6ìÍ] ³÷Ž©-0B˜5"“v»=.//pþè3NÏÎŒÔÐ÷8=;ÃØ8 lw{$Ï*Í üü>¢RŠE9SlT™S €ÛÉŠ4¶Íš�4+M¦bdÕ+Üäjæ<Ó6Ó”¹ 1C`÷4[öO“7�!èû€N‘ÒhT[Ùó=0#xƒ¯‚k®hRÅ0Žæ°ÙâL"¶Û-6C‡[O<�§žº‹Ûwî`»ÝPìvû¢$‹SV“‘ƒP I òÜä-/5F»—¹±˜1M¦aƒívƒä ìÖßEQ^â$ÈmÁsFl“@ˆK.r׈Âþ5.ÖÄ�N’)ú¤É%¯Y§%1Ž˜ nSŸmaÍÁ`Ö°ŽhЏÚípþè!>xˆ‹‹+ìvy¬guUoj¬®+.Fda³'Ìú~ÀééIyVì,f‡ ö{ŒD° tJ .`=þ‹G¯¤|}¼¡~rr‚Í0P?ôØnOfÙØ­esUõ—TúƒœƒEƒœZR2Äà¹É Z¦ó …%K³ ô ^ט‘¹µô!pq,‡a^ÿºÝ>úÜ?|û&ÿfÂð¦19C‰‚'5rS¶1&�ÑÈêMSiZ„… xœûýœ‘7ã"Ïã9ØGRŸÐ÷¦ œ6Ž̇×-•0¦¦C†°e=kãÑ–¤ˆÉ•º! €ÙÎÏò»Ë£ #EÏ4ÏØsL�=C[—3UµšµâVâÑF„«6ÙŠ†\‡&ÿšÄBgÊMAÉѨQGH¢¢.Î'Bð„.+D³#Au€q2�?eÀ~‡]°ù"õ½ÏUÀ˜sÏ£PáËÝÕ™?�3;õë Ú N¯óG$»ÌV³cŠá†ØÑˆ¸k>O‰!š“ªƒ„1 ÉèkÄšûðÒ«�1MîìàkÇ;Äh®¶ÀöþÙ @4å;{û�A€ŽL;ªtŸ<Ö™ÉDBP|øÙÛxðð ?y2à7¾ü¾ôå—}nß­¿ÛsžMjËÿÈs´JÍ9G W ÿÖ_ûi|î{? ¤‹r>úè«€Dˆ[—Û¹z< ¤T‘ø6¢dÕëBœÏPâ¨ÞPãrò”}qœ_8iæÀ퀎:\gÿ¿|U^™)ö€í?ù©ÏüRáQ×õWb~¦ÑD‹!IÌ�IÕpÀ”ÝãÔ#Æ„#¦iÂ0 Å6½F�¸«PŽgR`Ð1ˆo. FÊ‘)bÒ�&0�nÛ>¢zlú¡Ù»ol/ä÷¨7ÜÄ�'Gpã°Ù Øn·èûÁ³ÜG'1ÔLú”Rɯo‰Ÿy�“’eÀg7-U5òCãÜPâ'òÿ98_y1d1f€;§D?—®Øþ›#‹ÏÅ…Ä+õ9o�¹«( „¤nüfû�:>È¿ë“=¿3Ü<„†ˆ’B¸%ó,±ã‰ R*Êù<ï�^æñ-¡¢;²o(R” 7¤Í†?-QÜí*ù^:&$·þ·u‰‹ãZßW’t_Þ«/• Ó8Ï žÝ_¿78¤Ò oÀ¢äÏÿín•d«âaP%e¿êÜÐŽ‘œT�Ǩú±¾7 à_g}àéá¯=óäþ¯0�_JQþ_O=qòû�ߟ^M˜Ò„ý¸×ý~Oã¸×'sû<? ÈgHòç„ $(äš|�üÌ‚tEé§ Å_Žè‡Ás‰CQs#u/JN²hilÎcQ÷.ðãM4³‡Ïk˜¤j7X�퀦b _|$g![y�¢XŽ'Ÿ«Ù/sù»ê¢CyR¶ùŠÜCS¹Bíº nÙÍdn¡K)�c‡0Ù\ms»�Ð%�M´­5ê@’úÚGd´<én}EHÑÔËɳ¼w;›o»ýÜã~IBSœÐO‘öW»³–tVÉöÆ– ïæ¹.žõª³-Ü42ÒO³'jIïÈ0Õ%À†¨¸F”hˆ¢x×ùœ�ú) ¾ü{ïà>ÿ4„�޲åÀ DL)+E4’€àäE$€Ü €Aæ @¸³÷"ÔÖ™z1 ûÐ]|;&ü÷þ[_Äÿèùo¾õئ`we[�ÉŽþ˜ëDYãœ<“ô/{¡‰øüç>�ÿÅÿìo"„ [@:=D|ø5�#LÀè’¯ ³í'¿Žîl4»7ÅáņùÒÕ«oÇzûHýÝ±EÔ:J,=®¹8äEèÁj�lO~s{rúŠª>°#¢B‡¾Ÿ;MŒtR$$‹Èû«„Yf}³îgãËádŠ®s²­¬’l?Æ+ðŽìùN‚8Y6© rBˆ“YîoÌÅâ§s\rrjþ¬êne€pΨÏä LüÝžœØþÜÿ=Æ8›[$ÉlžÐØØÓÌÁæF'Qâ%Í>7Ïc-á®óŸé\Ÿÿ~N°bV£+ݧ÷ˆ ¦²f‹$è$Í-¯¬nîI&j�,uóp`ÉŸÔæF‚»¥öÌ«�ï�³S”$AÔÉ\Șœäœ?¯]3–n ˨†Üf_¥¸„Ž‹³N€)U.N3ÿåëÎ!¸‚¿Æªu�@&äÏÏd²C!!3g÷°LZ³ãë›5-‹‚“½S ù:ÿÇiýB¾ÖZk­µÖZï£Z k­µÖZk­µÖZDJ¤Z^21BוàÉf‹M¿EèCmàÁ^]ÉÇW——¸xlVäªfƒ:M£)Ç=`Ú]álw'§NðÑ¡·LÑ.&ô]ÂÆ Ð§Ž EWh“g¤º’>kþM1Nh nn6[ËnöØ€¬oÕÿ­½)sç Xm³%ç~܃×f\)ïÙNõ¬(–¦q*Öõã4:Ñ`:°[í:SÀnh@#¸}'£6ŒU´Ä,$1²BvJPMôq’){@ 6 AU0‰DÉ¢$Yóßγ«Š4¤1B4aŒ q̪6õ<Üýf@—Õf�床$¤(Hž[š•§8?ˆGçç¸x|Žq¿ÆÉÉO>q wïÞÆíÛOâäôÔcûýh¶¶}çŠ'.Š3k\:¸Ïž5Ô‰ ,5ú �¥¬†Ó ` PPŠ Íóg"N­Ío$ŒSB×™EnL !&·&/Î÷öZ·Î‡?Gw,ˆ÷ÓŒ¸bbH†¹b9b¿ßáââW»ÆÉH1Ö¼5ÂÎÙÙnÜ8Ãv»E=À4e× .Ž]dz&úv{bã¾±¶ÍÙ¶æö¡P$¨T’„P†�¹;ù½±ß)À±p ÕPÛŸþ“wïœléoõ¡ûoöÿÐÿeÓÿÿÙûó`ëÖô. û=ï°ÖÞç;÷޾ݢç–ÔMKB’Z�$„„±”` ¶I —C¥’8.§(™Ä…qA1ã„Ø…E°É‘!˜Ĥ–„„æ¹¥VOêéŽß÷�³÷Zïû>OþxžwXûœ{»qÙêË­õÜ:÷;ß·§5¼Ó~“Okž0†.lÃG'€æp‘ƒ=PxPAƪ ÚáMõW¹KnŽC€¼%"Ô6¶}žéx_Bé_ßçÓE`*ã•wxW øCïú¢§¾�ÿ ÊG¿u9¿ñÑi>Éy](—DÃ9Gäœøàთ4B€ ƒ(aœ¼Qw‹ÙQ+Y«„Œ”»ÓJ±öÝccÂFQ J¾°ž%`Ðå@À©Ÿés³<1*Ùmþª#ŠŽ©] ]ÁóN¨Q#êR›O% ‰¨uÿ}UÛ5f�]I �¡‘$nÈVšÅ\”S·m·¹ À–íc6Ï(`ÃÍ5¥¹/�d‰¥ª~õó—…š"¸Fà,«si`[ΈK¡R¥”žoùè’Ñœ;î»Õ‰].2ìÛ8>ªö¥� 6.1x�õîíð¸ þjëááiÒ3-ìÿè»?†/ü%¨CRƧÁºž;áÄ|2@�d@ b¹äEšy†k ÞŽ‘mÌ*h1Âxâ‰xê©k€3þãßÿnüGÿÙwáÅOÊ¿´×f9xÇÛ‹³qea}.w 7€ðoyËëñ—þÂ@ð `š ¿Èâb¯¦®‡ 9 D€bíÊÛýk„(§L/ÕKð‘O¬Êݲc?òþóKŽe²møäIâ•$Pûå6j‚ŒMöôk?ãïä”^p …¹öÍ86Î ,ïë %ø9Rbj Þ÷õŠw· ÐVç@ð¥¨Û�fV ÔÛº°0ƒJÙXÖ KËd¯$¨¾^0 +oݵœsúÙƒ[@›5š%5¢ðø} *ðë¿ßg]ßÀíêr€-Ij´ƒgfS’û{@q¿�¨Ç—R#�Ç8“>¿l>G :ãqؘ�ûpÎN6ó{³™:¹Ã9iëh˜Û‹sl6ú:×�Ž/¥0|s9Ëw,ÿÇsTW*†wbs‹)^ <µÍê÷gÑRe¥D€_\12ŒlLõù ÐO1êšÛ¾›ø4VÀb³h ³:çá|ow,� ©Q °kYIfz]K¤eÅù|ÂíÉbÕŒËÛ<­½öÚk¯½öÚë_óÚ {íµ×^{íµ×^¯�òÞ£xÍ¥¥šç8ÙfP þW@WzVg”Õî_-BBŒ :fU’ÃÀ„´,8- ®ÏçFðÁÎ#8]#ÔÕjÓŸ Á-À€�Ë› κ™X­ÿ‡¦I?K-Boàÿ Ê¯9ñÞûüÕß¹0–u�»íÇ)ˆâSó�Àõ÷ñ˜“·sSµò4;Óz DšãìŠC’„‰×„RJQò…°)zHš5§jÝTïE•Bú£@.9Bp!x¯öй0D”ÌXRBZÖÓ ¾ê Ó|#rˆp#h3Q�|5ðÿ…žÃsÏ=‡Ç�âd–õWǼÇã\áxu…yž«½´ÅOL˜³'\d²ÁùA‰Õ³´+øÏÅ7$À·û©ª(�WPU–*·šÒEvÞ!Hh›·LеE1åUòkH1)È 0*ÕAÁ˜zœõO©VùEÕxݘoÎR@ã–šãš›+ƈÃါ+ÿ�Ç#bœì:0–%5õ}µk�QBìÙ¬ãÆ}Wþ×My‹m–†^³v.p 3�¡P‘‚äëF=‘¼ó³¦ðÔáƒ_ÿÜG?ð;ž~ʽˆ‹Íò›.€ýªÌǘð|YÕ‚v´ë—-æWÿtGáO×­O±Ç* ?j÷Ç8€ ¸/¤|²ÐÔÇc}ºíÿûl¬ÇŒ¯ðµéO}ìÃßó—?ñ÷gŸ~×þhââX„ÈÁ; ÑK�}â|€óªo÷K‘E�çFHZSn úšTYžm^a.XSjùÙÚ_ÉrÖ�õÅt*Isè¢âúiú¹Þ9dRxu ˜ç¹�øãÕPŨ�B@ðð.*ñGª FU›–{,›ï[›{M4�­ŸqiÕ9£+\«¥²wÙ1œ¨ªpEÇô0¹T¦¶¬ivME_ÏA�‡Ò,»ÍŒœº}~)ªXf;�R X˜Ja*%?°»�ÖÛÌ9C¨ƒ¸=.£+oGîæºÜgÛ>° „¤ÎEÐñÜž ?Œëwßyp!ÐvBížÿò‡ŸÃA9:îĨ@–k ?Õ CßF‚b÷H@I ÉÝYÂePQ";ठÃ×¥<Òc>óM¯Áû9ãú�ßúƯÆøOރ瞿i‘?â…Ä1„»Q9£ºM(ðÏÌÖñpÑ:Iãío+þê_úF<ýô5Àg�ICn~ùÙÀ@ÑÈ iÖ·) m†ìWtÈCof<ߤìÒ¿ÛzRœÃÍcÁíY‘ÆY:Â{?°Ü3‚mnã§ÄÙþy­Ï •.Bøà›Þò¶ïXÒúB‘rÃÌë41{‹‘ò>´q¾·ësRçò¤u (¹ÅD¤Yö¡@#UT‘íE�tœ'Dr‰˜¸ — Sa[ǦÁ²¨Frä×0E1ÐUɉ9å®"\¼©ÀCˆæe±J¹:�œq>u§°Ë¨¬b€}]K«ªÜƒ96»zu‹Q¥ù4M-«�YLëجëcI}^�~Z×çó‚u]Z Ô8×<{Rºk”!Rààm.éÎ3JrÜ_¿w´1ÛW—*O»ÛF¾Îȉ6vÿõy1ÈfË\×�bsŒá=o–Gu­Û .m‰êþQà@]ýl=hʵô÷最ͼRË9‚cj$®Ý&fóŒó‡¥îm‚’–uÁÃG�qóø–U ªã¶×^{íµ×^{½:j'ìµ×^{íµ×^{½Bêp<‘S[a¨š'Ä8XK³om›H<ÚwPÓ9‡Ãáh sAÎ˺ —Œ´®XÖ„´®XׄùpÀ|˜ÛLõÎC¼ B7ת�i)ú™ª"¥¦ú©Ÿ«ÇÕU?!D3¦yF0eU=öœT­]­oë{º±Ör0ÍÆ¾)?mCôt>5E‹ˆ`žg}(¨ÞÕ.eR�öô£J2�š±¬*mU‰d—QX­¦33rV›Ì’32WkyµâÁà ï›mj–J¢ÐüO½w@pŽôyÞ©ž £äŒ5g¬çëº`5Ð)xEMƒw(%ª5¯§F€(Þ6 ƒ‹^ãeYðèÑ‹xæ™g”ðø!Òº*Ñ"¨J(„€iŠ]=´�Éi> #°nÒ;Rkìºí̓2‰9 –š� ÅdœÚ¢6¾ÞU¶±ÚÔꇒª¾ª]?ð@!‚@ݒňpzL+üÒI"„K»ž\ŠÙMw0pÈ¿5³1£‹P©ž£µý”ü¯›ÎÓ4aš”@q}}�®q8ÌmÓ-ŒœRÊ`sg¨ àyžq<Â^16»÷fÂ@fÝìW kÃNm|}ð8¸)FŠ!P˜<ý›¿êsÞøÔ‡�¿CD^¿‰ 6ÕXÍn›¿Šš[î´ÁÏÇ=âÑÖ¸ªý;°8~Ö%à^s}ð2jàâööÿhŸ³uèàæ†€mÀ}ºJD¯"c�º^f¹v¿›™×sý¾¿{åÝ*Âߣ6$ލ¸è§(1FIkà4ùœ«Ú°9›åqFZÑ"E4–ÃÆŽ�ÄE€‚0Þ‘'4çû#@^ë<æJ¡}ž¨é¼�WWFÊ‘mL ›*ß;Ô�¡�%lîŒ~¬µ x¯à 3YÆ66ÖÛÕvYЭ¦Õ.¹++áÁ9£¼ÓqÙکص-“3’mmóµ}ÑaQ#=Œ$æª-¶ƒÄ€˜=J™ŒäD Q».P«Ù&¢rn'"TJ¹êcÆà·1ÈíeÓ•¤õµÖQ�½ƒåÀ×Þ"wÚæÈÚÂû2ÄwЈ_ƃ´Aæ7&™R½�+À÷ÿØÇÁðð‘@ðXR�÷,ÀñÐ]fÓðNõr(�9å P±Šáií9½‚棙㠼íMOâÙŸó€ð—ÿ̯Æø¿ý üèO|LÅô¬X´��ÓñS4y µW ãœÒkì3_÷µ¿æOþ^�Ac d²c¼E~ö=Ý¥@Œ¨ÀP›ÿvܣǂÚ‰sÃË®x6çÉz¬?û‘°€ p^爴 >ðÑ´UIÓ� £;̽cF2 m�'†÷<ñä“#çü¼dy1'*±$a–ÉÖ{•0Æ4ðßg)"=®)wÅwqÌÑTã>8pñ`ÏpÐþï½ÚºO!€C€Ì³öSêäÂÚ÷óšÌÎAçe2pþÒJ= ®U¡E|f¤”�’:�Ï ÎçÎç³’AYŒ(ÛûÕõÈø{ðû\\ ‡Ó4a>ÔùË"½RÎ-"«Ž9º’ÅÕ%ds$H)á|ÖÈ1u;ê߯ŸÑ©§Ži-’kXñˆ‘zzk¡FJöØTª’.ÁN×oJ°ûmëºJ< Tç¼â±¦4¬ƒº8Þ\_ýÞÀö=Çæ5ï�€ijþèƒT”€šàV»/ö=Š â@"Ýæš0M±ý�\û“€Ü¯™°’ŠÚÈ©Nd%QÍssºÒïtzl€®s^q:�qº½Åíí­FÊT ï÷/ä{íµ×^{íõ*ª�°×^{íµ×^{íõ ©ãÁHè‡ 7.²¬âª¸)û,ž}öœO·`aæ ÇãQ7“ 7¨ä s?ðS˜À#8?XêZTð<45–¶…š;ë-owP–1£”ÔÀÊz/HÔÒ´)ÆH� <¥îdá’m”�ÜT„UíÇÂðQ5tst üëgé9ªbJZ^­w•ø�ˆàÈ¡ˆÚÚæê¬ÁJ‰!âxTõÿÕÕ5:¼²Æý H4@–[ls|ðžHD¾�Àßðùï˜þñíéÉÿàÇæöGê� !PŒ“ø°æ|ÁYI¼Ë�RÏ¿ºYt0¹ÉXxb5À†H3•Í›<0–žÒn1B >� —#Íо:^5ð'›¶Z[Ûõðz\�á¨IlóHNÉÎìü[ÃT —¨€È\=¸Ü1À¯êYç=‚<¼‘~|CÈ«E�Ð>¼¤„u]8×IJZ"SYVKêK—ƒÞ¦yÓÛÜ£�Ž³×ŽêfË€vž¨jÄÌÇ‹�~¥aÎ�¥Ûol]†WÜåì4[ûöÞ£c‰ý[=Î˺ìƒDjäœJÒ¨ãyÉon3¾û‡?�_ú¥oÁšØ@´„ã!‚yÌA}ñøEß7ÁñvàÄ p  9iT€©�Ô‹‚Á† Û¹ß"LWxýÓ‚G·„9:ü•?û+ð­ã½øÓé'ñ‹'@âêê‹A‚{#Môš7è¯ý/À7þÁß�oø†_ ¬ ¼Pä ~æÛ!§çñð–ñÇþ›‡øG?x‹gfœNŒyrxÍ“ïzçŒ?ðo?Àç¾µ�ëÒÆk‡&rföÄÔÜ;P¤¹¼ïà Ìví¿ïúÑ[›óîG÷iÛ0œå}O¯³mšÈ` pοø™Ÿý ÿ.3?*%ßä”sÖ©ºÙÑ÷H� –΢yð%„M¬.³Úî+¡•@,¢¤ºA‘ÙΤ)Þ}P·f³„w„œ‚�ËÒˆQËrÖ1ÓH©p.ÍÂ?笤ÇtuäúóׄuQ[v%jœ×š†ˆ"{M±±º‚ôãøÆ57^©5ð¡ªÿgæ1*é³y+À­÷ƒÚœ°�³œyslUù¿®+Š‘UÇx£ÑÙh´ý¿\—Ñ6³f3N\*ôklZ%€©áSiÞþ½®¹«ûÖHpÜÝÌÆã©kR_†ìÌÍuJG„`„aoàˆ=Bô réŽ5SÎH1hl„9(Õø¨)êz3NS»N9¥;N7"¢b56®ÍlßM€’•œ mÚ·ŒÂ‚´¦F(Y“ÎcÉî¿7‡®½öÚk¯½öÚëÕS;`¯½öÚk¯½öÚëRót0,ŒÀÜ7ñº*2-¸þT{{G1N˜Œ‰¯yòIDSàß<~Œ›Ç�U�S¼œ›~Î¥mz6¾Ù @�hªÇycu\���šf´€RÊÍ–T7µrË3eVeù»MiµÀŒUCS�çRÀÄ�P@§“½çŒcWܛʿ›o¹ë|ÇF³’*êœ3[ö`€˜*¤|Xm#Órfy¸þfû?Mæù€ãñ€yžtƒØTÿzþh–Ù lŽj÷ ç ƒ #™"¸Þˆ¨¢|]¤eÂ:é¹{DÄè- T'ÜÜÜâÅ_À‹/¼€Ç�"¥¤ ºÅTx"墸ŽÀB(E YZ$…:,lÕ®µªâ¯€:ÁTµ±C �b*ú’€• XtC®_GC´hƒ€à€N%ëF?ºŸ\'F^×¶9[¤`Ϋ3µPPrTÐãN×{X�;gk%ú8{ƒø‰8¬Ï#s Ùd™7°wlÿG¥?îù½×+Ë€…› …Ýv­Q-Íû5°ëñ«Žÿ�_ù¥OË Ëïäy³ù%ç‚Ýf–jqLpŽÔqÊmæ�Cш °T ÄÌJ_]”ŒCX½ƒ#®ùæ2�@ª¨ôU¼I›§Œu8[,G�ËÖä”Ô–•hVݪzQD‰^Ëšp¡° q[û‚�¡„œ­-Ù¸åT€¯Xt‡³± pw@\ÄÜ[ c1 îÓí-ΧS}ÍkŽQ]t¼CɃ8Î\£FÔEÆ™Åz»j·®¶Ç] 7æ¦BÁ9""áCoáÎ% #ÕMènì Ý�ðžRñÿ—*ƆFùú9²&ªíÈ94°¹’wþúß{/Þõùo‚ˆy%jx"¤"ˆÑ>½)ùë×êç5ÞH¨öí°þÁÃÁg‹#aëph蹜�x…'@ç¿õßúbü–ßüÅø‹ùGðWþöûðÁ=� \!úÕ$t‡ç<>ÿ Þ‰ßñÛ~ïÿUÆaÉ6fZ{Ì��?þ�Ÿûqü…¿uƒ?þÍÏàt6µ7iÍEðÌóŒð/nñmß{‹_ý®þôï¹Ætt 6We(V¤=¢.(ÀGŸÜž>(™¨0ð]?rz™x¯À½Íoã@#Ò€òK¢ÖÓO¿öïÌóá¹e9ß0óÊÌì*Q�úX¦õîè.HŠŒ´f¬iÕåtQ2”°€Ø¹Ñ":Ìu‹„�I4‚ËÖb1ÌöYêâS¢ZþWâ)‹àöt«d‹ *¶&-<¸#Ùš§^‹¶®¯ãbÎHFŒ*<¸� `ø8—�ÿî}'uU瓪.¯Vó•\˼�.i¿³l€ñæ¢0Äi)Éqí‘c›1ˆ²†Íz[ÉÑÜ»ìÇ[4VsBæo"2ŠÍ°¨ëkfd;ö»�ͱ後ûznÕ,Øùy߉rkJíqSÀ#ˆô»…oÔï1À{!mSÙH°êl¥D²ûãŒÃá€ÃáˆiÖõfaÆz^±,‹¸s ·H±zL"¥­ô< ¸Šg‹&d#Á–ÌúžçÕââ2¸¹ýt‚È^{íµ×^{íõê©�°×^{íµ×^{íõJY˜Å ¶“¢ŠH@Á�1³²þäü¯Ê‡CË}âɧp8q:1O“*ƒ–嬟)5ÅsŒqš¢>�¼ƒ#ÛTõ/>ÄÐÞ›�Ê •�À;Á²¨ÍéÏ5—€›j¿n¦µìP¢¶Á¼×÷° Ö…×¶q§›…aHŠ0œWr©íýšàýÒŽ¿fv6°ÝS€©Õ=³ó¾Ç8ç fÝ>ÍÇãÇ«¸º:à0£æç3ˆÖMÖ+`Y¡´‘ï9ïõ/ 7i>mÛ¼,fÙÝÕ¨SZ1— @„szžU!t>/¸½½ÁétÂj yýì¦n7õ\N‹;›Ú]mÁÅ®³‚ÏDbÎÕþÔŽö\Sª&òÑ#¸ÐlÆsQ›Y—ëýÕ6˜½½†¢Ÿç sTGŠèƒY3ÎñlïU�Y‰$Kî. \²¹[(¢Þ·€ê¨am8³¹aäoá£ÇŒÄq˜h KÒknÝ«)³*!D�`©Û¹í‡![l°<^SHW{\Ø&»µi¶lqÃç:&eÙ䊶³ôÙoJ¿`žÖ?,,ÿk¸1cYD¶À Le/ ñ—ùÝ—ÖÎ5Åš.‚À·QÏÈÐç)¨BƒXÆWT$ÿ ¨ÀÉð§�}ùŠ_‚úõ�F’À+Õ@ZT†Žè¡HW‰?¶Cëšþ�'¯Ã¿y û=poÿ«Á9òÞ @\„¹°Þpç $Å‚qŠM‘)¬$ªuQÕ&DÌþwB]Aìêìº]µ«à~½AR Ç®0JíÛbùâ—ó��·"—³‘\4� „sðf½íŒ€’r†÷çF4*¥€=·1gt„¸œ7™UÚ]f€à"~Ó–EŒDÎG §ó7�op:Ý*ùˆ4zEãSfLó„hàcñë #út æ‚5eê(Ðïi·éîs�õ'‘foï‘}T·rïÈ9"æÖUÍ>zìÕƒÇh&ÒYEFRºû|`Ðã�èüY»¸T…[?D#ö`ˆñˆ@„ÂoÿŽ÷¿ïWk¶6©ëZb�Nqãg¹ñ˜‚àLp0PV³ÙOf%Î}Œ#l®  B%NåŽ yÀ * ~çoûüÎÿÍ»ñá�žñ÷¾ýgð}?ð<>ôì#¬KÁ²f\xò©k¼ý³ÞŒ_ú¿¿âk~ ^÷Ú§Í¿z,-CÁéY¤�ý]”g~ÿÑñ"¾åÛž,^icõ¿!yÿð{Ïøu°àoü¡kB€81bÃÅ­Ýf0àg>šÛ}!è¡­Yðcï;oíÿq7¢eÓ‰^úŸ×ý£·÷þæ}á/þÿô¨”ræÂœ$i)aY\[³#à4U·sÊX°uN=VuÜÑ“JD ¨³Cu°Ž½Î¢iHš}tÔbš.Ìp. �Øêka%ÜÞÞØgjœS.Ùb{Œ€g$¤à=@z¬ÍÞ½”FU—¬ÜcLêØå À=3¾:`Qs:h„/ôq¯Žÿã8Y�_E=oÔú㺽’Tó�× à¼}–þ„aMNMA/bs„]÷v^> D]ûõ{H›ù¿?‰õU›‡X\:QAI›æ8VDZÁ9¡>·]“¢ßœ�¿%¤´¶ëDŽ0ñl$$1‚'u¦ ljP#†ö¸7ç¯iŽ˜ç ÇãÁ¾§².(œq:�qsó)©û•®%ƒÝCÚŒ‘ÌsmÓk!EÛxÎçåŒe9!§‚­SCœ"æ8í_È÷Úk¯½öÚëմϼ_‚½öÚk¯½öÚk¯WF\ >ØV{Ï-�ÿªž7ÝÍp'"Ì“nÞ\=ñ„ æã!N ÎØ¦P^UQ²¦ çÌçóáŒ4EÍ Í¶=䳫•ûÖn5—¢Ñƒå¾sÞùŒeY �.M=£ªI�yš0ϺéTcF2AÛœä®`­D€úx%äRtƒÖùJ¨�"s Sš±®=«T¢Ùò–ÉÃgýü¶Y#|L1àpÐü÷ëë'puu…iŠDUú”ÍVÚ5«h"ScMä æ lz8¯ PKAå «©˜Ø”`¥0Òºb]V,qE ‚×Íû” nOgœnop:©ãƒóó|9 ƈëpuu…# –u­[à¶{_¤)Ȩ®³ Ôà•0R•®.ƒ ñ>GÕrêààIÁoW†ûWÕ­Žàñ�ó ÀÇé€yŽ˜ü¤î¶Á?ϳ‚ò0KÓ¤Öá¹$äT��ÊŠÂ ¥dL%‚ŽGD˜bС�[ÎKJHë f�£Ð¢BÍbW`Ö©¹«ÿ5‡—Á\]ª“B±Ÿ ŠB‚�vãf£¶+z+˜™�²ë™µCÆ«m“sDž¨š\;ˆÐÈ}éçMÿ>Qù¿–£iÊw-�ÑÕÿz �·¶ÑhiYÒú›Æ 80xÈ©€áe,@·+÷Ôã PUù#ÁÀ€¿&Þ%Ù€�[àíºÕþßN[5?]ØK· xE�û…¥W—ç`"]fݤ/¥*_«²¼\ÝÜÞüWÏ}ì»ÿ·á _ø�ãêÈ»;,R„ ��¶–b®$›’²� @O@æž-7ƒÐ"Ƈøá~Ãk ¦¦U¥>_\wÞ8;¨«yïßœO<‚óªô†_=D€i*FrRduð ‹9b$«‰X\tN%"doŠrÖ“+,pÌ� Ú‰Ž�7�ãöæçesAŒäœZjÏóŒ`®1•˜§÷2ÙuU‘dS²ù²Gªù–%-®r',ªÆ[4MQ¯¯óž9bÁÜF–±/¶Þ!ÍÑ£](é÷SïAwèý»Â¢Õ“aìrzÿ›êh)½ïÉØE üØgõü•7¤ã)9±žb ÿÅG þïy~ÍWýBd!°8òxb {80„èxãÍÂ߯Y„Y/ªójïDV @«±Xê.@fCÁ „äºv¯ëær¯#Î¥jþÒùk¼ÞbD²ü÷¡¾„e3�±3ÁUq >lÈ }Í7— ûþQlí$mS™"÷Ø4€Þ5v©~‡©s‰ã~Ì9'½vŸ›ûDò(!¶{[ÿc쑞oduã]êsÀ#æÃ‡ã¡¹ŽU·‚órÂíí ÎçEiLQcѦI×Å!øN%�°ñÞ¢h ‘%+©(—‚e]q>�°®gd›CÔ5ïdñÓ´öÚk¯½öÚëÕT;`¯½öÚk¯½öÚëRRD7oœl”«hÏHëv À°qÚ&¨sóA4#†�S¥gRPô@°˜:$kvçùŒsˆ Ëy÷%˜õ¿Z2³W¯›fjCŸMµ¼É«Ú2gšló,›ÊÔ‡€yVÕiš1›z²ªÐSR@?›ú¦Fèõ`x§…jñßìH�ƒsI dê MÛછyõ®im 5ulÍØ,vŬñ“màU…æ4ÙµžxðàO>õ<ùÄ“8^ADHë‚”sCIÐsï¤1ÎÔñíyDpN‰ ¸«âݯ+–Uß7›=첬ðîÔ6µÕ&¸½¹ÅÃ_Ä£G�°,g8çñàê‡bð˜3އ#®¯¯á½Çš3Îç¥[WK�#àvlδÝExl£#Úïsij(òÇ€ãîìÐ"ÈA¼F-D».sŒ˜ãl�bˆ ”4#FEìÞ¤9­H°¾!®]cL“9̈“: ŒîÕÒ_Xóº½sàPUxÄú»æÛêÆ<!÷ŠHË_M)iŒBéö³Í*Ü{ëÛ}3]#r³ÒÌÅUP­¼#".î ßyüÌ×>}üïR^¾€«ÊÌ…ÅK¨ÿ‡Ü\@8h ì¨ðTðLóèÿn€B=׬ý;hìÛX =¼¼g�K¿~c6vU\â%Õ˃ë<6šæ{Áý‘HвÅ?Ͷÿc•ÄFÎ1‚Ìöà[$@źÛððáÍ×ÿÐÞðú7|ðÄ�¨%0CD¤ˆˆÓˆŽWW¤e=+æY#:�C›{<�8¬MˆS@‘D Ž›ªÓ<ø7÷FÇ�®|€ÕˆazïDÕ¶Ž,Ù©›†3µjm‹,¡`šbStŠÅñF} PËãÙµ«‘ WR-¬É€>�¯]ˆÞúi.çJ¦:ŸíØ»º¸‚8ê8b¹ã+‚ÑÁìÆmlÖ,jµž×¶)j'#b0¢�³<úÔáÆ ZPÇrΓó�„eîYÚ£�ŸÆî/—ý-‹ººfô)Û¶¸yáÅ×�µ—�‘†‡mM!¬oÖÇH|kï4<þÒ_û!üНü,HQ"ÝiuðA?ê:xsÿ'´¼pÿ»Õ�n…yàA… Þž’ÏýàňÚÀÌÉ€ .‚Ä\ISä3ÈEøùI°# /h±>yBTÀ�Œ\ÐîWw �>‚ôñ„òÌ÷Ìxx[ð§þÚóæÀc¹÷žÚZ¢EE°€¤aC�ù~jÅ?ø®€_ûÂc@Ž”ð`öàífxÂû~Žá=i4E�Ï øÇÿòñýØ0ÿß×6kÜ;¿Õ�œ¬ÅU2k|î‹ßõåßB|Þ9wc,!„àq>/JØ%?Öñ¥”lùåtA8è$YGJHtv ½­eSðº¶32¨@lÎ_Û¼Ç,˜™Á�˜]«F 9öðÀ.ã¹çÏ�¨�KnäW˜ËŠå­[ÔGë]‚ncáªBÀŽŽÃë.ÄÆ×Ç ØØÎ¢ç�Ö×m#ø?º!”ÂwαF3è÷�Ü×Ü�§’«… 8;d›gJÖȉuY”d‘DJk7·1O3ó!¤”�ˆV�Ö§Ó §“ŽKsœ »¾Ñ¾#¸î˜¦íÊ5"YuD(\°¤Ëé„eY�ëoDÝ8M˜çÓ<ï_È÷Úk¯½öÚëUT;`¯½öÚk¯½öÚëR™³eBúf;/R� 7 öR…R7Ýêf–s=‹’ ƒB·Í�SÄ|8âP³ÒpÉͦû¼&Ðù„`ΩmRV`­þéL½ßT0®ª˜»ýê¨ /EÖe9#ØmãªäLl'KÉàUS €÷ÙìAý�'JÙ¤ºé'âÛqxöm“²Zg:ú¹0¦<#§îPwAZ“nœYÖüšrJèK;†'\]]áÁƒxâú®¯ N0g¤uEÉŒ”³ÝGµÑ¯ óè¼ zý›ô ‚¹j9k±½Îõ VUñ&û3ç„ÛiÆét‹^x�=FÎYUCO=¥×zVQ´Ídˆrp˜‚ D‚kMµE„,¸)9%ä:Ø[³¬«"IjN)“m’êqVkÛR•YÐ ñâ¢T+æ!“׫ͳ*îÆšVœ×„ÓrVÒˆä~ïÍöÿx<àp¸ÂñxÐLV¬"ÈÕߨ>GûTÏaç’°,±�CJ ë²@ ðÁaÂažƒµgͼ_–Á¹ÅÚ2›•ownU�ºÙlº{¤ä`ªÎðmÓz@gá â¾ú+ßôï.ë£?™Ò«¢²º¼œú¿dÀ¡.�šG¸Lä< Çê `°8¸Á’˜ØHŠ¢ ã¿XUÊú'57ì-ˆÔóÄÉTñ4¼ÿï:lßgK&øô*¸Ç–g¬ ¢ë~ð�PûB't"Çã›Ó“ò±�½ç-oäßòì ø;,LÌÌÄ…¹“ƒ°æI£VV"Î6^Sµ¼÷�tT3±ÅˆNX3‚×a‹ö °y`lIi®Ú>ÏËb¹Ã=ÂÝq@ŸƒÐÛ©³ã 1`*Áæ¥Ò>»µ—Añ*ΡèkmEuXÕ6½°æ&{s,¨Ñ(%g,ç3–Uã?* ìÒ…g,�¶,±£d²û�ÛmƒulÒ¹4Àm»;ï,¼½ç6Y�Šãy×(�MÕû9\`µ<ï÷áòª‹ôù¿Ùë[zù0€î¸ÑõÝ}ä³~N Ù{i\H:(jãƒ:$¾ÿ‡?‚}è!Þðú'&øœW�1bxµã®vám\¨mÍEƒª™ä~R÷‡âÔ&_e³u5ÒòÊÆ’�º”u8€ç.¾íËõsœ7w�l–ï J’222°<‹üø‡ÀÏ~ÊùY;fÁŸûë·¸½UKòñ|Æx$Ìn\˜²¦H†Ÿø[¿öËœF +ÀÀA›(�o�÷~8kl(?ùÁŒ}lÝ�ýƱön+èsI'ùàN|L¦lÖšoxÓ›¿ùêêê#λ‡Dqž§ÑGm¤¤ëØ”’�ÉöÒ¢™mŸµ�°ãF­‘Áç5G]ß™«�®uÔýiÅÚI¦9k„ÔhÁ~9K‘®!Óº6G�n¯¯ë¿vÝ vð~s½*�2›€÷æ˜5Œ©àz´ãQÒ�¶�bn[ÉΩF9‘{ˆÅú\ÉóF�ß×÷tg½=Î�õ{ÇË£×76W‚qÍÞÈ……Ú½rÞ©³AŒÍÀ‡Nþ*ÌíûÂ}mpíKQ»~uRÈm Û¿ŸlÉ í»J.6ÖÊ&B¦þ^ﯺð¸F�ÐÇ3JöÈFh¤¢Ç’JR"pZõ^ä¬."56ʸ©úkt…þ™�Pº,gTšHˆÑÌW´”´‹ätBZ no�Óü×óù77�ÍþŸ1f̳ڌfÝd`N Ëy…€‚Y&xo˜²T{[µ0 qM ÌÌE­ZA0—ˆÒâ+”Œ¡›äìxK)©ZMX×„å¼ •Jp˜,v0Ö6Bï&8SLG<¸^qZN8Ÿ¯�,Ï4»r‡ÃWàêê<8b>Úµaf$ŸLýà]A!U–œ±žO¸¹¡ €—^w"Â<ÏE`$ƒyŽ˜&UM¥”QÊ­;ÃîÛ`Ã[Awr˜Þ“õí¬¿¦¢6à‰†€¦9º/ýÂ7~ëÃ>ö RÕÖ-+â“«ÿëuåš—›yc®ÖÇGs– O ”"ª0®ªUaHSØvÑûttE¢€¨`t㯿ŽäÝ#9¡çMËË(ý�»F/§øßT?ÿd6Ën)ÐëèþIÍ}BnnOácÿÄ·|Éçÿ‚ßôß‹–"̹p/^ h'göê>¨òœL5X�dÚ5«à‡µ@Æ`µ_�"œ€áà +è)E‰(õõ#Hnï{{s‚ F>pÞ)˜©Q0PÃ,�SGQbˆå'ïÁ!h{1‚p±P JDD»¹•Š�s©0R.ˆeB,Œ8éxë|i1#ÉÜ?Ä"ÈÞŸmžÊ9Û¥¿^;½N ìû6oª¸:(ARÁüï‹‚ypx)|]ç["»-ÊYb~pù¼OFnÑþä4Æcpþ›v°Ñe°®ýBã€BŸ¬¥_ÄP%éCÔFÈ¢K̶ ÛŠw—‰?û_þ“ÿÓ¯e¤"X³à´®¯‚ü@Te�qŒ4~;÷¸¢R+‹¹Š�pJ#=„¢’Š‚õ²<ƒrþˆªÚãhz(> P(ÀUR€d ?‚¤‡àó 7ïŸÌ�²9U„ðž]Œdi‡e„*ÞÁ ©¹8´±Ó€÷DsÈ=YƇð¥u ÂO|0Á¹ªþWbá¯ÿó‡wÚÝ«ü¿°…x‰ºÐÿo~Ÿçùƒ_ò¥¿äo;OÏÄyçç—‰áÉy°ZíHadäFVS"^•hëØS ×‡½Ì� 8¡HÆ\æ–§’‘“º+138¬¦«ò^-ø«Å½s�¤ãŒ ëÈ¡ *u<œ�Îlß½Y¹™É»êºÕ-ësV‚ƒ#×@âišÍ=ªº�Ôö¡ÎVF¸]V¤5£p±èßTë…YçXßëxÕ×ó¾Ç' ùû”ÿähCB**´c¬€ÑÍ« í§ªþ+(¯¯ ¶n`LüòíJÔÙ¦¥Óºj;á:ë˜Pç8uRñ}#×bt` …á»–‚ï>s]#‹Î•P2r12‚‘�ë:rì7•8CÔ¨ïlŽAsáêK�ÊšâŒÃtÀ4G½Vp€Kæ”Ä H©(ðŸ2Rζv0òF ªþŸfÌ“’öÚk¯½öÚk¯WO퀽öÚk¯½öÚk¯WH)€L £Ài& —®ú¾»ùv! 6nnnÚÆV² Æ 8 bðȹ4¢ª�u£ªù.xĪ”â ]©t'gÕ@™º¹&"È!›{A6ËfÞ(t/ÏKí* ͦ¶€l/x„f‘ßž5W³¾oÉ‰Ö ÉÀyËý.¨•ga{tóÐ,ÙP½4ò $ÝäŒð>�AšªýT-£O'œN'¨Yl�X1زºQ¥UXgKôÎ%cµ¬ûžÓZ­3Ö57¥OÎ+N§3Òº€…BÀápÄ“O>‰«W˜âï4O÷t:Y¼�n2ª*I](Fp”ÍVY D”PàK@¨Ž-Ô]¯7`vÈ%ófkç¤Q˺`9ŸÕÒ×À{ï½’¬]朱æÕ"J™gsŠ %`¦ÇãÖu çÇ#®¯àÁý 1B X±Âe"b(�Ùy”œ°.k³zUU²·Ü]o¶»¦)b2X·²ëš Ô�dHï«ýÞJÛtwø ç|©È8µ?b‚{ç;Þxíññï|ñ…�¾³mP˧¦þ—�úßÜ*a€‡lð Ì9¯à �V ‘Z¢;JQà_‘2D»6Tí­áîä ·ñ¬jÀvCý|:Žür6þÒ²Å�O ×ÿÔ «ÿ)Ê@m„D%Ñÿ $€ à8Ä>:¹izá[¾ü‹_ó5ßù½Ïý ÔtŠzŸ ƒsˆY OŽƒ‚L-cœå=ÛñUNJmÐN]@p,j£^ Šsp ”�„"›ûxº½U²”#�7‚:£ûüæhcêU�߬e:ƒc:¢ºB°)¸Íî¿!Ö]E/P%i�Oɹ s �[Ž3Œà[Žt² o{·ÞßY­ÂÏç“ösÆésšló±½ÀK0âKÙÄ:°YW»Â*7ûñ:ÖæP8“ÝÍlA…ìïÑd_ôËö. ø7ÂÁ š——o¶›_iûa¸t¹Óßš9@÷ÿè‘ T¬ªä&#�€ÿä=ïÃ'žùJ¼îé'”ì·ƒ$:Õšš�Ý�™»åþhÃï` ‚ÜÁœ-øÏ€$ Ú˜àÄ�ü PTpP àÀAǺô"øü @N À[ ²{Yss¶Äâ‚ç^,j P#WØH"P_²5‘‚Ïä©�ÅÚÿ>ðœÃÛßx§QÀ¬\ðÑç ÞûÁ„0¹Fê~ý™ó½6ÿwïl«înb6­¦ôïy×2äÉkáRPJÂùtÂù|Ʋ(°Îœ›Ú)NŽÇ#®ŽG�@`�¬ýsJN!%…øï‚ysÛa™KAæ‚’E<|adñœ#ûñÃk4#<³’4RNÈkBZµÍ­«f£²¨}/U¤§œ‘Ö!D,1༞q8Ly¯jÞÂa1ňÃá VÀ1Ã9ÂápÀ|Tåœfï‘K6žnÞÆ8é=µ¸ƒu=£”‚óéVó™hœ"®ŽWˆ“:=\__ãêÁÌS„s沑–eA) Ö5#¥¥X–9lÙÔõ.7r 5e3 úê�ƒ0qaÇ"î�Ÿõ†×¸ò±ï}á¹�½Y…©[…îh±|GýÏc³ªÿET1Æ2îÈFغ‹�˜çôíœãd—A‘ŽMN½ŽC¥�)ã¹Ûp×”ÿ0­Ï¡Á þ]/í`çp ܧ\ütÛÿëøØu_ „ TIè]é>3à}UVê3ŸyöÅøÔÇo~ÍSá]󭘳:DǹT²*�™áÁRÕ©®ÝûÂ<¨u,d€B‹Z؃#‹ƒ€’ÍÙ¤�‡.¼¬‹�ÝÞ’3€÷ÁæÀ>ÀC””y‚ƒ‡A¨1((Q½Ï-ÍÙ@?Çõ\æ5¡0cÍî±ÀI6"“¶#oÊËú€€œžc�¸aä”p>;ˆ(9¦9ÓØ|<¶Ã¦ºôÌ÷QF�Íßõ’© �ö¡B oó�ÐR0”$´ÉX×8�m[ë©Òú%‘ü–0sXÝØu o:âëô’únº<’í¿¶øíÿ:¾¸*c5€ƒƒº5ü©oún|ãïý¬E],RJÈp:3ž¸Šý�iŒ#1å1Ûûž\¤€wŒÔÚ_|„”Çì’‘Ì�…L_ @â&%°ÄCïˆW%žŒža™ÈvòÕ¥_-W‰NÀ4Àì¨$s��7¹oä¼AYAUð!>è9ö²º"øþŸ\ÀB-íÀYúËßö¢FÑ]åÿ'#Ð=m¥³Ïú¸_ÿz}}ý#ŸÿE_ø]Dî¡óþ±wþì¼çI* c@œ"¦{Öð!ŽœfÝ‹æ–TÌîœ�ì€JrôÁ#LØûrA –ÅÃÑ‚3­�UÔ¾½*çKn$)ruÝã)I�Û`Ùî¦Ø�¡|ëüT�'„ØÖ0óá”X§ÎL æ§Uc°*9ªž3³Ò3GÂÀº¬ÍÁ`$ÒÕ¹œ½¹c‰xpKr-’¥9f]�t/çR8%°n\½èî÷“Ëuøøo#=fÚ÷˜1ÜCpVÇÐnÛßÉ1-Ú€:YzlËÁûáÜò&B,Æ ó¬$�qSïAi‰bëSâ-òE¿ÃÕÖnßORAÎêÔ°¦ÕÔ÷J¾ aR·©Ã±}›çÙ”úÌóÇãÓ4Ã%VRÒóȬ„BFé}¬­+ÑãL,X ‚þ,â¼!ßk¯½öÚk¯WQ퀽öÚk¯½öÚk¯WH¥5!Mi“¥™“Ë’�òŠb �sDAÕ,�(œNg9�ÁÃO¶iÏÏ9á|^àü-p"0Ÿûƪm¤ÐU˜¶)8f…ÖEeS’ØFg}þ�U™^�lÍfZÝ<%GÍN¹©�ø.áœC ±m`¦Ô‰ÄÐâ’käïºj'B7ÇÌÐóé„ÓéŒóù„e]Íö¿ƒÿÁ>³žc ªâ"gà6妿¹¹Áíí N·7HIï]´ yU7ª%l  l—�Ñ7 ¥T%’ºHà »!§>éf÷²œqsó¸)â�ƒªúÍf6NÁ{$á¦(eédƒšË�áª(Ñœ�Y¶š’(WÙ‚ÐTU!}h'G}û°�ûjƒZïS.e“³ª›ß+ÒêAÎ!�)LçƒZžðÞ®‹sˆÓ¤€œA¦8ëf¼÷[ Âl¥ƒ÷p5 —‚óIí÷sÎX–ÂEÝ"A ñ<ÀSO=…'žx‡ÃD„”3Χ[ÍV_„M…–²�ë LH%|TÕkº©a2ܸDˆg.î�¯òúà_üŽ�âÃoÞ˜Ó~ªêl �:P7°+°;¨øG¤ï©}$\}íö½´’õn´ßɦlTãêû!yÔèý½êßï‚ùòÒ æ+¬æC�ÉÀ@Äœ@Nóèë 6$=ÇRجæ»3À‡>òì[¿ì ßú;¿ý»žû3GDDŽ<žpI2€gÎYÁi³Ó'ë¯Ú>„ HFHùRå½ý‚FLòÎÚ ;œúûå’@…š»«q–Í…!“>è¼¼Ž}ÎuB’ÔŒf?J#¶teµ«n6>ÀUh듪D '°ýå uWáÖoºpYÏC{Ôù#ÙXÍÈf]]Á¨nnà$º�4± ZvN©gZëmR’Nq¥8å ‘",¸~ÉFfÝs¼TÿVÝFà¾)Ç/Þç>ÀwÄÖ1àJÃÃÃ#¿a8i–÷�dí³�uFÌ çð�¾ã§ñÛÓ—á-o~"Œ5 ^|x‹œ!Žóa [Õód(Ûâ7»0àÎ%.’á8‚‘J6H P2Ä'�$@ÄG Ì7P­ <@ÈI¿Ææ,€¦ˆ×`�HZD‚cÀá�¯�øÄ³@� Rèë5K§eÈ{ï1ň·½9‚œÆ Iu|) �àÇÞŸðÌó¬ñ ºîp„ŸúPÂÿÔi˜?{Ͷ)l[^¶!Þ_ιå]ïþòoŠ!>Oä{ïÎäˆ7mÉìô+©1„€”Rƒ0/Áå*¶•Л|{# ©#€ƒ€*®ƒ�Ýß–3Úº´»fubD˳ÙôæóŒãÕÇ«8ÌSS›—ÂHI#�rÎ6.¨º{š"¦yÒ¸¢Rš~k�ªcQâÔ\}””iDÛºæ¨d�:Æ7RñÀå!gD]]ƒÁÈC´‰¨ãR“¶óp%€u½å¿s~x^gݼ�är ç¸u ’;ÊvÞ“ó^DÜærn³nÈ¥4âi½NúÝ" qÜŽ»ÏO“‘¥Åäl–ÿ/£ýT jÜ\x “AÌ@Hë„u=#­3RûŽ ‘m‡YI»µ›æ ÓÍ�¤.çóÙ·8/ ’�_£]Uº:U馮褚7¬ªjï€)YݬŸõ˜ÖEÕæD@Ϋ9xï “ªICÍ;5ðkkÚ-¦ÕŠº 0ÃKi›‡äZ,sÛÌDRûrvUmá¼€dPZ�4¹pËcUUm߬ïïHѶÒó[ã45Tˆ‚w(¬í#†`ú^c{V5–À6Û½¢…¨²Ö,Y•P¢AÛ!ŽWxâ‰'ðÔS¯ÁSO=‰Ãá°œO,K‚sj.ÜÏ— 8�ж1Ç6ð e<ë?D$DŽ‹øÂìßü†é›>ü�÷¾]ßšŽOQý?TUÿCF²À äÇ( ¨=u|œwö¬ú'›rP.HÕL ‚3ªÞï›b[±¯ `p°¦íªêòwÌúi<êáÑ—ßÄ~¥�èòxì\•4�€»qÔÇ�RÆ gà|^ñèñÍï#àO+¸ïHœy’õ1Á`aM]ÙÈÂÝ‚ý¢õv²eT¢JéŠm#­‘ÅÔ×rîvÒu‹ðÙ!†A¹i6Ûà\€ÁÆÁÊ'0�… |ÍlfõÜÞB¨�8 Š 3c*™m3P� #ÃŽc .ŒsÐã-ÒæJ�|6öç|SW�F-À¹�E�ŒÓ:@Ï'_UâÈË®òòcÈŠ'¹¸ÀÈk[À}¢îË9`ÁroßCwl¸Ó�ë‡hæ„s:¿ob dû£þŸà�ã¯CY.ÀÉX ÏÂô3¼µå¯Uà]YS÷\0}!Àƒ!ža87E4‹\²¾wa2àˆ#Ä­@~BˬðJ& WAü–ï ÷\LÍ-Ô\S†! ¿øsøÁŸ:u÷6r U{=ô ŽõMÓŒ/þ܈yÖ Uøj ‚ðÜ‹ßûã©;�¹ˆˆðMç…íý§ÁùƒèbVi4&}ý�p€»d¢ñoxÃþÛ7¿õ­?ày"ºqÎÕ|‹r×ùÄy¯$£æ $=bg裎¶€/sA.j¥ó|Œ,&èCð> †MÍÖõây9#¯JædîîLŽ+Zßâú \=¸Æõõ�LóÜœARÎp'×ÞƒY�‹ºc)©QàÉ!úXâÑê,²+×ù‚”2 +جM™›;V”hq= T{ï›{×]¢Þ¨žG'mÖhÞK_½Ä4à1ÄÐ6ú5n Ã-+Š°Æ LÕE  dˆ‡ì<Ö5!ÆY³}�W5´'UäM‡®<Àõõµý<�yž”!Œy^1O“Ù—«½°+ÕbC<‚Z£�€çB³?6Í5 ð¿æk¿ô×?÷ñŸüm'r·Ú $wÕÿ¨ñ!wÔÿ‡5pÝ‚ÞIÚsêÕ"– ÍÎ×Z)€Ò3×Ñm‰QŸKÒL2õf'\?ÁîKs¿À¥Ío)Ç„Â[År% ŒÌ†—½lŸ&B€3ÈLö=$‚]�Ôæ—šªs{Ï=ÿð�¿ì—¼á�ÿâûnœú`-°æb6ßäUõON³ÖÀ±ƒ¸êÌ@«î–Õ. †ß$ÐlòkûªsJô¨ÍæþÁÜ€£ªˆ¯êU™ôõ1„9"ú »ñP᪆/dío̵6[fî¦sªŒf¹‚À�¼G^“ª3…LåKð¹µ­®ã‘^¯ÞÖ*SID%%8�GÎ1êØ_Uµõ}z|FiÑØö•,ׯ£Í§J®¹Ôæ_f¯ã%µþŽÈ\r‡^ ü¿¿GnII÷’l|¸G‡ßû³ýEð¿ýX›ú�û¾íŸ¿_õeoSvp8/„Û[‡G�=ž~Íus8€‘”PïWUü÷Q�Uìàµ]P‰@@k?¾)ïŠ&€ …ÀÎgˆÌ š€êáHãàÊvÝ�Fq@t¤'%ËÕÈ“JÎúmÿÆ|óß{¹éÊbV´/1 WÏ»¾^s¼½'Äñë¾:( €³ —JLû—?•t>*hï ó»nðÁ�®–?8lâarÌe û…lÚ¤ÞÛiš~ôW}í×ýÅâ "ò@çÚ «‡ˆþÎP×ç ήöwëçêDâÌ9$ „ŒRB#6’ BvXW�°DÒ|u…ƒLˆ1bš|³ôŸ&%[†[‡³÷HëŠeÕȤ¥ÓŽ „u­=-²h>0E‹ 2€_ WÕÆ?#­„³?ÃyãçûXå£]1sZS²5º‚Íä*¡Èa³º#„—lLÙºfÌü¨dSÈÜœ{ ÷yW*aI6±b�šwwt‰�—€ÿ8¿�k~±x—ºæo€¾»å†ñ¡®�¼ÓøïƒÆ6Ü ci�«Ÿ[#ÌÆµwýN¢ŸãÚ÷-ç¶-•È&à—\j4‚­]g%ûè÷–5­8/g%oø€ls@ôêP¿_U§­Ö'J¥á»SîjÂåÂÅiè˜taèb}_¿Gòþ…|¯½öÚk¯½^EµöÚk¯½öÚk¯½^!C„#@Šæ×§Ô³èsIBp¦ÒŒ“憆ÐmEëF׸9çGëþ 6ðÓ4™ €f©‡� jCTüeÝ’RnêêÑ^½YjÚçïcAäÉÜ ¢ÚhzgSNAûd¶šƒ’µfH»Aჩb1ê&žYð¯‹*ÆSÎ=[ÞÀ=ïi2¥79Ï Ú焜ÏöÃ¥´Í¦yj×mžfÄIIlµ §ŒóùŒórÖÏ77ÀTY1"ζÁUaVáS) þ )‡ òºa|@œ&Ä-‹~BðSË�ofÄ) ‡)z¡o^Æ—eiϯćRºj¬*S/7x7™©NsŒ™4¼ÚÆS›ÅRUH®¸­Â f¥ê”ÀRA81e¢°f·æ’±®+ÈŽo]J6•¢s˜â„ãÕŠ«ãÇC³l­íFÑ ²°Äµýyg–ãÎâ‚ój·|ww°ëF˜çž¸¾Æ×OâúÁŽGLó¬öÀäM�ª›Î!xÌÓ„užÔâœL éÓ®‚üº‘;ªå\Í\èå®®¡¤‡ìtzÔÿ•ÇÐð ûÜUÿ�àîþÝzŸšet£¡°neP稀æXà}HÕžxÈ æ‚êÕ^-€«åp³ šªPLé[•¿4ä’_þÞ]A½ÿeÀÅ.üF�ú Špƒýÿ&á‚ ÷‘ЃÈ0MÄ*)çá£ÞFò¥ù1õ ¨°¥P),L„àBÃ_d;C>û$0Àžà £¸»yÊ}¼pF4 �Û�÷ÂDEáWSÂVPÐù¤Qš1r„è#¦)XŠ9u+)¢?,E�&FÚ”­¥db„¦&ŒT‚5,FŠ*[òÈоÆq¦NÚ·}³‘®\ RNF:r:?FÅæíª†ç¡÷Ï«ªS}œà\wMxp|€À;¯gȬ>Ñ£“ÈKÖý™àírõ“j½„û;˜Üñ娖ý›>'—y㋨©¹Õ†\ÔMà’àˆŽî›þ9Þý‹3ž| sáù¤óïé´ž~ò -Ëfd¥Ô¿�ªb©ñ6@:�öbcŸo¨@b‘Œ °F°d8J7�dRûg'lï#÷Ó¨èc<Ã*õ/xÇ~ï¼Æ_ûÇ�-.† ä:Ø(jáÍÈxÖ¹fž¯ðÙo&ü†_FýúzupüË÷®xñPPGáŇã¿ØÝ08lìÿ?Ù8Ú &¸Ó¦Ú¿ŸÞù¹Ÿ÷=^]ý@·Âò˜¹¤ª¶îÙéŒTJSt·÷héç¶Nˆ1êxÂê�®; + %,5ß=,‹’5ÓÕWWW˜çÁGx¯ïã£F>…pÂé|ˆ°Øé)Ƌ҈£išCh×PÁßÒ#¤èxe„×Ñ^?ç¤N]SlÖüŽŒØQÇ=ÖóÈ%CHà¡_aR’ Ö„V] ÃÁH^›ûGÚ~Íõ‰™Am. m<Öù¾vAÎе$@~�î¸g#NÆqµ®G›bŸY >XtË@ à­ãØ]—=±J,H9¤†{bVd»v÷€ÿõqÃW,‹­ÇClñV•dT¯S]šÔ.\½’ºJŸ…!…ªßAV¤åŒÅypœYÀ�8GÔ!¢~/a#‚,ãÔJwPœ¬.£Bšë�Ó˜-k‘Rö/ä{íµ×^{íõ*ª�°×^{íµ×^{íõ ©Ãa†s™e55+8­ù"ìëfUU‘ëf�*þ/ó0k‘€ "x˜:nˆ®áBмõyÆùtÀù¼ ¥µå•Vu~�"(fÇ؆dʲÉù¦tòö¼jݯUÝ¡ *ŠMô¼QYÒ @sÞ!š‹Áñêˆ)Zî»àÂ8/çö^uƒ´*‹sÊ�TÑìácPµLéd gvöl¿Ïól ÿ„išmS×5JX•i9+h]í÷•DÀ-Gvž&U…Í3æÃŒ0Exç dˆdd³s­­ÂÔ”±ÞS¾0Ϩ 8ŸT…+ Ö÷Ó<éŸÓ„ãñˆiÒ ÅeY±,«9”Íæi¦û†5£ä¢ßLјÊkØà(ðPRä¨e/ëù“m‚v «Æ0¨emµÑVu[Êi]AäÛ&'°¢dÖÌ[òšL1KM¡,w¼ÂTUá%Ò¤�ˆÚÆ�Zh¹f3_27å°óAÛîƒWx`V¾Ó|´¶&H)Yn*#­+¸d€€#æÃÃ�´.í:«¹3G‡þgÿ/€F‚ü/þç¿ìë^xæ§Þ #h&ò²öÿÀVý¿y`ãmvÀäpœ'<ß6þajdi ¬n ø†-Z±œªü³‘î¯å¦¢nvæ Ž&#þ”66U²ªM¥��z}Få߈ß]šÕÿë‘c{}}´sPPî^m�@#i`| $€î¤ðâ£GŸW££YJD*(]ÙȬ’ÉmÀüñþV5=ÌyEÀp,`³ßîjñNpÞƒrƒCD0M“~VñF3ÐB4Æ$­‹_Õñ%D¤tÀ<ÕqÚQ8"”‚�«¶]ƒLhjñúÞ Á«’Û{82bÕ4aY&¤uÁšVSQ– pTÇÊîÜ¡„�ßBS¡¶¶Y ˆœÍǹ‘ôBñÈIÁ-}?sQ .4T%§Žw¹�…Jªœ÷Ã]º°Á —·r¶Ë±loz Ýã$@÷(¾_®·�ÄÙÚÀWK÷;r׫€œªkËØÆì÷‡�Nøcÿ¯†oü½_‹ó’‘KAÊëyD> xâêʈæЈ#øoó.xDIIÎ&A‹=¡êÓ# r ‚ê듾6%° p.A\¹°ïqŽÀÅ$¸@¶ñÕÐBöŠg `ü¡ßq�{Â�ÿìbÇ¢íY LçO<¦ˆë+à?ýw²º8×Nþ'?´àCÏÍ™A›�w„?ÿ7ŸÇ²ïw¤Â„—‹b¡;)æ&#w[̃×â~îçý@�œsIHV0�‘°gJ'„ﵓ¯ ©®‘5rCç\Ÿ=Ö´"­9¥Fú,¦?�"Nó‚ëëšðà�Z÷‡ÃçÑ+`ê¼³x‡…VPÊ(6÷9€«r½1µ$6�•[ÜWýüRòæØK�ÞÊQóæ�3"Øèˆcjóz-¼ŽÛÑ{LS´q²$ZDL%òÝ“ÂUQ^•ïmMT‰¨ÞÈeJ lãBÔçˆ L=Jéò>Õ*¬kL�Õ Gíܽ϶N wœWˆ\#ºmÇemÛÞ!p#�µH3ûžRÛ×èZv1pŒr)…�s¶ïF¨ãu'«îTàm&hS§ ŽFÔBfu€Kí{µ5u œƒ�ÁJÒË%ÙsZsA" j»Ðx‰�dBÒÈ›ÎÙ:o dîÝ`¯½öÚk¯½^UµöÚk¯½öÚk¯½^!u8ªÍ£·�ZM…Ëš) dç¶ M`“I ê–ú<ÃZþdV…u*XIí$É!z8 8‡yšq>[6e³´_––7h.»/¦‚7kÒº�è=Ã'žº#€sˆ0µQ¼wÃMãt°ZBorVÍàp8âx8èq„ ê¿óY•ù ¡¾�§*ý´¦�Z˜ˆ§ˆ£ÝƒJv §ºSˆugu;ÐóvºI�Ôu`YVdS}ª©3 ù#Ž�^ˆó¬ÊsR+ZfUå\ ’l#XÁ2Gj•(bš&L“Zý¯)áñÍc<|ô77�‘VU=ΓZÙOóG‹{ "¤¶ñ]š³ƒ÷¦9Ú±ú¶y¯€ƒª 6ø^”H³¯ÌÎ6XÕö:¥U# œF(°� |ÐØ�}±¸¤”°œÏ ²¬Ç›H#.rJwâ"œˆi{ÿ+íÁ@;"ˆfÄ*1âŒe9Û¬*¼¦YÛÄÕƒ˜g�ÌÈ\p>Ÿ�óªú¹ pƺö{>Ï39À‘ ¥Üȵß*é‚L6_K)£ØZëo[Î7z}F{ÙûÔÿ÷m`£ÛÓ¶¸è!"¢þñ¦7¼ùØsÀ…ÂSÇ“ªÈup(-¾ mz7Ën†î÷óå ÷H6q0õzϵï¹óÔäÿ•€v_ûHwUÌÿ õé4xâú8XÁ˜^Š^� ZÎ<µë6F0ÔiáñÍJ"¾Åj¨ZÕCgs‚�žL `UR Ý ×`ý`µþ(DÚÖëqô ð*žÞ‚ˆD8(“Ž…œ3V#¼fœ—U]Aìz8罃wš•dä¼ÎqžP 9!E­57ÈÙ ¨‡×±`šu\—YÇ�eAÊ+rî Ö§¢ÞªÈuü7§GÈ) ¥€~²»svÍÊÙ;%" ø�@P£JôŠ3K#88æFj¼Ý+w/Øÿ©9]TBÇ¿BîóàÐâC6VÓŸbç^Û„âT£F€qþ�ý.CÞûw~ÏÏà¯ýý7ãk¿ê³uŒdÁÍí ¸Gð&¼ýmWGáïPxÿ­a�µgmYÖ€ %cú£ö��dïU’‚ö’”O€ „æà%Í2ww„¬}„©;M‘ðWÿàSø}ÿ�þÙ÷kDQÉbÚ\P£f|xýÓ„?û¿Ïøì×18yÀæ]�Ãû?ºâ'Þ¿tût§äàÿóž¼÷ƒË�È…¾âÀÿ:V·nE—Ñâm¬�Ë…¼sßÿÅïz÷}ûøöÑkžzêB,vÂ|¹n«ÑVTÖùUUØÔ@Ô"™‚ÅϨ»Ç„�ƒÍùç¶f(¶ÞàRZp>�p>p{¥ëÞ×W¸zðǃÆMé¼%5Á�|²õ ÚÖïûq]Ûz¹^�RyͶËçNþ‰ZÞGíç¶¾¯þ8F;GÍ…DÉ•¤.…Á%L�<ÓÈ4žzTŠÌ#8^×ÈõÏ1FÝ›Ôy¥~ÿhkuæ�Ó×åš|¼Ç287çà|1²dnko{m|¨J{ŒMj8F#¬ö÷ï×3{�uuv_ú½á¦ô§û¿› d‚ÂEû™»‘÷pâÀŽ›s ‹¨›.b°Æárˆ%¨1pb×·“fmø¡¾ƪ�L×~ÞGsÀæ‡í;_)Iû�}.A¿W„¨¯õÍÍ�°×^{íµ×^{½ºj'ìµ×^{íµ×^{½Bêp8B H>¯Þ�Lå"ƒJ¥*9d<êÆRUÏTp€�(Ò-CsÂù|µþ�!¢›ëó<#DUÙ/Ë‚S xu?Ð{�5ßuk�¬(Å¡ÔV{ÎuMH©oø¯¶òóAme+ïc€#R%ØÈ9¯  3CŠnp×LÒ"¸è¦bÙ>z„gŸyÏ?ÿ ^xáÜÞÞB˜™áÁƒk8ç�RF.+Òº"%³¹!F Day t6µ—3ÛâÑRµ*š2+©Ä礹‹G“ªÜƒ³|Õˆ�É@«i ˜g�5¨)*Yäˆ$"¤uµ¶ÔU¾R•æmCÕÃy̼YïG�)o¶º¬÷mYÜÜÜàñÍ nO·X×µèž,.cž"Bp.X—ÖeiJ½f­ Á”ÿ&Uû•Ò¢0ßÓ=v³Í �„ˆx¹}þÝ‚ˆ3«çûF�¯lìÿùžtîÁuº’L@„w}ÉÛñ/ðg†MõÁ&¼õá‚R¼ßÚî:r`×hP¹�L%” Ø0¶ùæ]?Úƒ Æœèª s{=pWaú©Ö§�ðöÏ~cÈ@Ç{IõŠQ°Y¤qÐ^ÕÙã½;ŸÎ�¹…€T* ÖR „¤}jlL³¿0‘�ñ/¤ ‡0�ÉÁaP7ŽG_o¾"óÕÑþ]£Ò²ât>ç[,§kÊH©è˜WFe±^•}CÎÁ‡€cx½86°„[ÛhÚu��ÀbD"Äà1Oq X‚ÇùìàhE.4Ü'4·”±��;ªsPЕ°,€ˆ: dqœ#Ä,ÃÛ!j1 õ³ôøKS—"Ö®Ž"U! z©f-ñç¥ žÚë^ª—è}ÛF‹\¸ Œ ÿ�{€l_ÑÜrˆ@÷jË­‹ŸöGÚ¾êq:§cÌÉâ/~ówâ½ãuxϺ<||‹�|ü¼í�Ocš ƒ6† ”Çj›wÝÁÆK4-:À�(‚Ã.ðdí{iÖ ö ç£Æx°/‡: ” þ=¤!ªÀ9iýúêÊáÿù¼Âßÿ® ßôVüøûŠTаÂë^#ø†/#üþ__0O(š;çÁÎãCŸ(øþŸXlÞ„³ „}ÿŠø]�^¤6œ…« ØÛeÝÓå„\_?ñ­ŽÜZ˜—u]—À,DAÄ";:§+š›zF*4RlU=—Bð9£„€tý¢³Üt=¶¨¡’unf”¼"%Áº®X–)�±¦k¬ëŠ|ý<8ª{˜€ƒâ@Þ¬1!çÒ:�®}Õ(akU_Pš£AaHéjír¡LÄ(Íž^#Œà¨EDÕulwÌ2…·Ù¼;'6Îô[ÛÜ“œCöºÞÂð}�ù‚\9ÄÕ¸Ãó ÿÒFÿåbZ:ÆÙ÷„J’ ŒÀÜÖÁ:œº{ jw\ϨŽí¶N·ùϹõÎøv+PîÄô?7ë_èwˆ:r:q·à™‹Åƒ8ë•�is¹ö]E]�ŒÀ]´/³‘+º+ØðÝÏÞG@ÔqMI)ÛQ»1;g� «Ë™3[0×7ur£Oûšh¯½öÚk¯½öú¿vÀ^{íµ×^{íµ×+¤¦8Ùo„œ“ª§½ßlœ•RÌ2´4`±>¦Šè!¿Þ6<Ýæõ RWÌf]ì,?Ôr7}16ð´Z×üTæ‚u]Û1Õ÷¿Ü0«ÇÎ9ŸucNÕg]Õ¨Ê}$æf£©Öõ 0¯öãC0¥'š­º÷š1__ÓUQæT�rÛ0ö>è¹Ç€iŠ˜™Á¹ær¦¾IܬZì>øv®ÕÊ´ª<ëf¨÷ÞÔÿ3ŽÇƒ©ÿ#ÙýÈ1"N"¼ƒÅ0Ø= ÎEx.ð.´œSç >8„è‚*–Χ“YÄ:Û40gîѪFV°(Ä€)ħ Þ©•ªÞ³„ÛÓ �?ÂãÇMÙŸš³FQ �ÁXÓ)Ö\šû@owº™Û#d³™\ûjUû+©Gû{µ”ʰ©­þËùñkôïUË÷Øÿo«Úÿ�„ÿŽ­-7‰à‹¿à³ñ ^÷žyî.ÁŸºÑMB Çf3ïzN7*@§÷ ìÚ�mÝî·ùÞ: ÿ|Ïù½¼ªY òRÂcºÿb}š6½‰ïþ’w‚‹ÀyíãQIí¼`¤†F ¤‹m€>_ï°¦òqfgã”YhKMuW×Áf]‚H?&܃ 6l�Ì­A…HA¹/â½Ú½ ŽÇc¯êºB^ãaÖµ€×ÆéÖïvc™5 üxœµ/C£[BfCmãfÉí¨C»Ø£ÎäMï @ÔÄyïÌi ªl×U³¶etPR€�Q·š­S@°¸jyË4�¯äžöLC¬‰·9DÏ_ìž^γ¨.¦Ì½ë†![ÂÆð™[�^’D ÛÿÝé2­g½”‹@#чÄ0í�ddMLjÖ|��çFÒÿ;‚�›H€e-øÃæÛðGþïÇa¶q˜·§„�=ó"€·¼ñ)LS@OeQ0Ž T£5"C;ŒÝ»Öîàa�Â0Qñj¯Ë J�óŒB¡ê1Ô‹Éõ¢Š:8¾c\!|ýWDüϾÂãÑmÁ�¾¯àãŸ(¸>¼óõŒ·¾®;h/€w@~öç¾çÇ×»Vß¼ð˜ñ_þíP :QkãÚ1LK Ô½\Û´»ûüYºCˆ›ŽÓÄ77·ß! èZm|ìm…7‘-un .´h/ñº«cr]gréªÿîìµu/ؼf8§q>¨íÏ 7òpæÞ ꚬ}2ǘ&#½VÒ´ó˜ó Ž•d­.a¨Np.ù £ƒS)‚œ ÖuéN€‘ÍBs¬ 6ç}jk¬½öÚk¯½öÚë_·Ú {íµ×^{íµ×^¯”ršáØ÷œÑj3<H–ÂH)a]Ô¦µ‹ëš°,gU,•Œyš†�0Y¤ÙÓWüúc@ŒæyÆ<ÏÐ:Ä!³Š. r³©ð»%+ß›“\]¼OXךÏiŠ—¦rÜn GÆ4wƒœ³f’–ŒuYñ葪Ôr)ˆAA£Óé¶åg†1ÏSÛÔs^mYõ=t-gj$ˆiŠ˜„8cšu‰\rÁš¬ËŠÓéÔ3ª™7“ä¨ÛÔ^l„z§*øišã„0S»+`Æ| ´¢}N#@�ƒ]pögÀÍÍ#<÷ì³xöÙgðâ‹/"¥Î9\�˜¦WWðš§žÂÕÕXñæV³C«m0KËÔ-%!eÝðí€ߣ6¯j­ú€‘L¼†M\A†f_�¬šÏ«@x‰õ=l£Øyˆø1C7Òc˜§¨êýpÎç3D`$ í²q”P…œ7ç�8M˜ªÛp)È…q>¯¸½¹ÁÃG�psûçóI¯UŒ˜¦hq ªâ圱˜’jYœÏ ²Å]„ ª_íC±��)%,iÑ>™’µÀ‘·>¤›·1#3x³„oÆœsš˜�táêËÙÿß³w[Aέšµ a…ä þ­ÿåWáÏÿ…¿�{5–? ˆ�ªjbÕŽGRS¬Êåc4€‘æ­ÄÜÍ¿ü·ÑhæÝžÒî'ôX�ŸßáþóÑgâ©'¯ ìp ¯1—$CE´KÀ¤jb¸»9ê5£ÜÎ'¥üaóüí��• Fä6@Í»í5u®EWg RðÕ¡Ú“ßïÀLÍüòVÖûq¸:*á£*ú—™¬˜Ö%ä´ZäÆÒÆž\¤K«:ªSOzœ�‹³‡3À,(UV,ŒÂ•Gz=½�:ßÖËÄÜI+Ö€œë Y�þ‹ð/Œ"Üb*Fò$òí;ž Ž)"‚”‡ï„欦Q\¶f�â¤ëâK²ö^{íµ×^{íõê©�°×^{íµ×^{íõ ©”2¼ý©nܲàE: ¡¹¥+Îgo›ÿfÍŸ3Î糩=2æùÐ6rTÕ¯Žu³¬ –úT)'µ°/󬛱u£.Fµ•¯ÀQðkJÍ.Œ&-Í +@[7˜|`D plŠ— ð¢j�ªÈñÁcžæª�odfV›{Q ût:5eÿš¨Ï9µãõƒÍz­úZ=Ö3¼÷H©“%â¤ctQŠ ÅAÙ_#,?»ªô7v¦"ð¶ÉçÍ^Ó‡€àƒnæSÿ÷�D3X%¢q㼂5Œ\ÎgBÊ >Ä‹/>Ä£G�p{s‘‚ùp° ú®¯¯ñÄ“OáÁƒêtàJÖ�ÉÒÔMb RAÉD'Þù—l§£Z«:94åÒ¨¨Üx<[¶©�*ŠõSs^¨ª?´ÍMr„É6'ã¤*¥Õ­Á[Û¨Å/ŒÝz\/ºÑ¼oNÄš�›sÂétÂãÇ�qsó§Ó…3UÒÁ„ìÄô4=ŸœÎ' LQÌa`ŠJpÞA˜±¦ëY UeVïm³/÷Á«ªPûjêí�ÌÉ¢ÂÓ{‘½ ûTï€û€ô˨€�wø¼w¼ _ÿuïÆßý¶ïÛF49·�Ó"p¬}“«Rt£Ôøt!]d<¸‰» £ŒžwÉã¹×# àNlÀ�6ýó»áýš§àkå7|O¯™º)lI€«1—ÒlV+ûMztè}�ÔòWw€Wû‹ô âê1@om“\Ícwml®Äòêõ—¦Î5":9a<p<ÔeÆù–©« Ë<7;u6‹îe]ÁÂH%aM «‘qÇ£öQ#\Á× id€ªhe0È@}6æL!‘Çe –íMꈣ. ¥YwWŒ³X|K1°(»êΣs´—ÎiSŒÞašg”\Àœï½œ»T™ýU’œG ܈WëºÂ9BÎ �©Ÿ!÷Zÿß7rÐ8<ÍJlNÁÿÍûö!}›çqO5¨˜.ÇŸˆ�oL[©{ÿw# �Œ#µ™¨ëf�®øéŸýþðþOñþû_…Óí 0#p÷ø‰÷ž°œÏxûg½×Fô“¦ð¯¾è墟™ê_Rû]jÀxœ.€ hF<; €S›wÐ qÎâP- ¬7—©ž:è�ýj®5B½E@€4zAÌúÂêÇ?°â‡Þ›Ô ƒÛ ÜîßÿÖçñÑgóü¯×ƒhëñ 5»Ù9¿œ5_~U ʪØm2KîêÌ Ÿ=Š©¼¼sð%XN«4§‚à n–vì ÙTÞëºhvûºàñãGÝRÝ":(/rí¥rÎX–µ‘⤴äô³kN|4@7Ýð„Tà|Èkºk¯|a/ëÍÝØÚîÖR€G³XÙ²8«jÙù®.Ê© ”3ÖeÁÍãǸ½½Áù¼ pi6·ÕÅáx<âÁƒ¸¾¾FÝ^SÒ�Á¤×s D2JÀõ/±ØÕÜ®ÙÐV¸ª²ºj¶e©rU´m7v«ûƒˆ §rÎ6auãÔI#š:J˜Þb"ŠÙ3ÃrqIs_;XáàáÕÕ™iÍ8ŸÎ8ÝÞàææ¦múÚÆçyÆápÀñxDŒSSWV²o‚g³j5›n;çÌm#e¬«æ~ ‹ÞËÚ&LA'�Ûˆ–âÁÜÍ¡7©Ü‚OÉþ¿>TIÝþÿžI·ú€¯ûš/²¬øöþ#hv²†âË€ºËhÛ?¸>ŒÙ¸À`å-wÏ¥ö—ñ¸î‹ �û~oíè~Ïÿš‘Þßë‚06æŸÇº¾>à·üæ¯ÑöÜî“�Ô®“ÈóæÏÎN‡7JÈv]ŒEADXSxo#é8à½øjHçÅ!(P#¦¸jßlöÑ®ºµ´˜µò—;í�ðRùß Âd*\(lYÊDSÄá88¤%!—ÎŒuQrZ.´W7“ãSœJäb�<9ˆPa½.D(,€�}eȹ¦Þ(±  CF|m… %«Ú3g�H)#%�ƒI)až'Ló„hvËêJãZ�cÊà,£ó™:·;Ö~å=7P°Æét®14ÂÌRÕûB—$¬OþÓhÉÞû$dÓ7Û¸_�ÿjãßÔâ/Éh±‰´¨jû¡ý)qª¾Œˆ 氣ǬÊE²]u¾hŽ5:/|ß~ò/üîû‹t.€\ÀÎáý~ÌïxÛÓx≪à{UKE7œP�zir{Þž #€#à©‘˜\àЬf jÉ�»aP'sœ¹«ØgS½i`/€8u©‡Ùƒ†Š[ûê×ôûjÁû~Ž&o¤šn·ÂBø³ãyüô‡×-øo*ÿ�m{UþÓöN7‰�¨ô©‰"2ïÉ{§}ÛxŸSD°µ— €œ:y[ Õõ^û»«îb 5kæ94Ê)X¤–: „N&´ut.ËùŒÓé„ÓéVÝ}, ÀY6{.kJð>6âã]ƒƒ»¤3%7Õu© �{[«T~뢅Ab¤,@‰G5–J×, ïüv{Äà6õÕYˆ‡)[—ç-,ƦŽwÞÛz+#Ûx�sA²ï etÅbî5\c¡%[²�çû¬æux7¥}ïa�Òéßa³)ü¡¤èœ±,�ÀA ÄiºMP¿xà|¹°ï—F¨ׯ—ñãqõçÀ®Ágÿ—68Ã}q¦Ê÷íºßí>rwa52„wv 3ŽWÌólN¹ä­%2õö‡j;l€ ("¶Q_L�÷îÑctÐqf·pçqÝ ßõ¦¿<úùÉÿŸ¨Þù ß‚_ÿ _iùÀG[»óFN`¨cÀhó`-œ„1»›€'Ÿ¸Z>ò9ç¼xî��%eîÆ&qç/Ò?•*@XIN±Èªþ•ñvÒû[ÞxEˆàÉ©…uNXׄRDÁ&xgZè(ç ˜¯kÿ+©í˜Ž˜&�}©€¦#y§ôçà ÙJ’ Yf´Î#e-È( D9gÀ AÊÁòœ×+¡±%�TÇ…‘2#s1ðAˆkš[Ž÷þ´1bÛÿ¨ØF ê±tow»;FÉE»Çey;:ªã‰¹)°Æ¬hÛ 0—¥ãœºô¼ç{§%ã÷üÖ/Rµµ«QÀG>þýÄC¼ó³žÄg¾ñ Ç\á¡:lŒ› @mr¸œ(ð`µ`bKÀq™Á $�À@Q¾1®jÜOˆ܉Äâ$Þx¹_›kš�ð„}<ã‡ß·j?‹ðŒ¼ ‚c¸à° ã�ÿ·ÏãÇÞwÞ9û5ÇÆ`$Ôß·@-.â$äâ·û£k óUʹßÃRÚ›©ãH2Nƒk$Ú÷¨©æCð` (1j?K .ê–Å…AÆ{™gç1M3®¯¯§ï7eµóΈM]ý­|˜�=µ Ÿ8ŶÁس- ]ѼG.q³áå›]¨ª\Ö²¶Í5o*�®ºW€fÂÜÀð Š2«R_A–ÒÜ$ Š'8.ð5{4èæYöI_�níŠ-9!çzžÅ“ ç,ÕëÆ§Æô,YfÝø¼T»ÔÌfæD„ó)ât8áx8b>Θ݄x˜1OkŒyÕÉç‚ÄkSªÕͽœ‹nvº¾ZÝD© HÄmÓqPC…lCصøQÛUf,Ë·7�±œOšù�?¸º:bž˜æÙbT©_Ï3[DsLiÔW�(ÙÈ"‰AÄà êZgÄŒ8EÄ0!N1¨E>927‘ˆ ¸‚ì¼Y�ª®d65�ª¶Î爂‘ ts7§!jÂ>äTP"‡eQ ƒ ÑÜà`Ùæ)‚Ì )uOxô�?Ʋœ[ DÇã¡ýLÓÔl‡a÷±jƼ÷<,Ü€B6'fV ×u%øˆi:àx8`6‚AÏ5‡ˆÂE èk~å/9N‡kàá' /²üëQ9:Ô¥ý?°µü½¬®åg{}µþÖÇßü¦×âÿðï}=þé{~ÿì; çsºój½ zlÒ™ÝúÿþmŸ|ßš³Áå‘Þ ^ÖK‘$>]5Å€¯ýÕïÂý¢Ï4’[,Ámr·ódù­Šž�ЩJÇ ¸n€„ðº×=ù½ÿ&8"vf§î}à@\pÎY›Ñ˜Ž;q Ã�j#r}Ø©å±2Æüg´>Šáµ½})¿»’U]z>±óÝ�†™Á·Ü”ór¾‹Zâ¯Ë¢„�iBÑ+±&z£:ˆDBa% ¹u5Òœ*r5;<+ ;ÚÒÛéB%Q@6O1Ày% €r+XËŠ”3Ö´Â/)�„‚(¹-*i*FˆB´s�1F¤”°®šÙ¬d€ª†Vg”Ú§ØH…3Jñ]Ds �‚ªCCõ§¿ôq§‹¨Á¡ ¾Õ¶-lzéåç Ôê€d`Ý£o. 2’˜º}GoßP`˜Y ðw}dgy÷Œïÿáá�þ þÀïü2Ì*Þ±@ã¶ ?ýþðøñ ïxë<ý¤ƒIµm 6«cDû7)Í­CPÁKX5Ú…¤(øîÀà�“W ­ÏÀTÿJ@PÛ‰Jf##8ˆ'PPv³ÿ®Ž°Â¿ÿŒ�=Wtþ«mò >Þ,‚?ú—ŸÃû>¼nÁÍû,þiKÙ<Ú=©`1õ;º1+¹'r¦¯ÃübjíB£6TòKæ JýuÌÜÖt11¨­GëÚUG(±õXÉ%³ZýOæ^ekŒ8E�G�ÿ³ÙÉ9´=šœÕ€ T¯su=&‘‘Ð]8¦iÖõjJˆQǶeÐ0w,Àuµ¹÷^ ¬sT2ç4™[J�,ó>#-«-2IDc†¦0Í3¦ÚÚÑ'gñW¥­÷u} .(•Xã�‡·>¦ó°®Óêu©ëžbëØË8']¯xçÕÑʇ¾–§-E¤¥‰ÔØwI`äÔ]Ê* ­Ï“F’¨„”“­ýK.X–e3ŽôHkG!¶ï©: d�Ú7Æø4ãØªK€£ ‰¦~ŽÚò3r*Jš(•¤ª±a"¢Dà”‘½ëî;@ÿ+±Œ‹¨CY%Z!Æ;%Àø-RÈ"²61[tÇÉ`Cø¶¶PÕÿcÛßk¯½öÚk¯½^µöÚk¯½öÚk¯½^)%P@µn\³f7‡T'RËì ˆq²œòhà‰k “w~óö\õŒ¢m€]nƒú¦X¾ºí5›}·ÝXóÁÃà "æî¬ëŠÕŽ0Õ&¸Çç:׬ùcf°×ìUò ¾DÁ‘1•ˆRæ;Ö £…h=¦-aa›“]uÌúÔòÙ6J×uÁ’”œ0EU•Nó �ZV/ë‚u•Fnà¦Ø45=Ô†—ÌN[`ªš þq1å)JM˯wD^7P-S´f –¢ÀÒù¬Îã„yšp¼ºÂñx…ùp€s…�”5N"Æù¤ù¨Ëù¬žEU’!ÌS´œÎ«ÝïnÔ]7ò›söVT<àH[eø]/l€£K I.²t/Ï£LÅ=×çç‰à½Ã/úÜ·á«¿ê 0OËšš]4‘fµoIudªq¦~îæçmìqÜz±ý`#M\_Íxpu< ÉFïÁ²wàâ{\Ã� d¼S�’Ù4Þ®:TÔ»g­Œ$ýØÇûÓ\FR†�ÿ)%,)ë\—³½Þm#]Ðä¦6=Ÿ‘rAf-K³Äž–ѳy>´±À!Ìùj…žØTrA¡Üò­…·ñ:‡„€àœ¹uDsÙ9êè£Í?z7ù¬Ç£àüÝq¾dF)p%Jð!(y­—<–u…È æÜœSêÜ)RèUŠ pÙaøñàÈQãJ@/aß_ÛÃED† }Ž:¹­öAÚ´†MëÛ‚ ²‚ä¾g\˜t§#®k ;'WÇœc”R•ÿ•ÎbmVYøÉŸù¾ñOüsü¿û—âõ¯ oïaýëcÏœð‘�=Ä;Þv…Ï|㮯lpeûÅÿš!PbÔš_DyÄ€�þbÏ'"ˆspŠñp98Ã1ÀÄU ‚Åð˜)n÷¤®é¬/4I¹~òC?ðÞ ?9L“\�Zt(ˆ !|ôÙŒ?ò—>�ç^,¦¨ßZûoÕþº¸}̵vU ?BÛåeÇØ øø`]13i4†öOP�¬Ê(m\Z×µ)ô§iÂ4)§EF45}Ÿ+Øî 7+{ͬ—aÙÁÖ{#%öÜtœc¿Ì"°]©c³F „ˆ'LSB) 2û~Æé­2:l)p}hd(r³†IU²�:¨ä¾Ž&‡Ôaè0OˆFxð)!y�R2ÜjÊðR¯IȪm!jkdÑsk׳«åÅÈŽµ¯�ÊïõÇ‘?+ÀMà¦aF¨ º3òC�‹r)pN@”ïÌíÎÆâÃajßk4ÞJ×mAÉ+S‰Á°1¥0cйk/”ò—à�°6»ùþá²{¿ù· Á˜JfHé×Kt¤€S*6– ó0ìûWb%Zp�j®ÞÃ…ˆhŽ^ÎÑÈêÄsuÁoÜ&FòJ¢v€½öÚk¯½özuÕNØk¯½öÚk¯½öz…”žUµÝ·Òåbc öçv“²¦y¼Îji=Õ,›½Ž˜êzØ VÕJšV8U!ÓÀÕ ÊÌú\. ÔÆ6ª{FŒ©oþ9ײ֥eCË v)à¬js.ì\K¶v¦t‘Ic Fƒ”²E˜btÈŠÏ%ƒÌ’³1̪Tu¶AëjžlË™—fŸY¤€ˆvmÓº 6¢ÝŠºdŽlj3èF¯]sr.v/Íi XDCÑóâÐ�#ˆ°®iãâP�rï�‘:€BûqÞcÂ%¿„iÂdŠ*ç<òàx¡÷@ÕzR€’3N'uNxôènO'¬©*U1w8Î8^quuÔøï" �(¶oOu9›Ã…Æth›™›ZM8«R4¸€«ÝXtsw]ÎgÍ ¶Íq·®iž�׈ói]A(!Sê÷’1ô›ïWÕ÷ÿãeìÿ{P@µ×ŒiÂñ8á×|Í/ƯúåŸ�ñ½?�ïû�÷áùkÄ6»·Ø5�œ¶`âà&½É"F ߌsõ�éâ…$=#÷åìÊH"øWÌáýX1x|îç¼_ö%ïÄñ8Á�s]X¤Ó ”­ÇW¯›ÞG ŽÈ5 ÀbÀIšDu`øœË[> !)$'¢lžbŠ`Aî.,±+( u{ç¢åÎÀØÁò¿ºú‹sªP2À{~;]ÜAI)'Û;®©«ïcàÁ‡ƒªž‰@ç¥ØrÊ‘’SFN¹�êR3!‚ëÄ,6×�RA˜b–Þv�˜@ ‚E³ÖöÑPt0ˆ“yBŒˆ1 x‡ÇD …Œ”¤sFͱgf¬ËªÄ¸t�««JÀŠ!N¨9÷:ævÅ®ÚU«:]DbP"C¡ ŽËKµq¹Cžiä\ihÓ7ï,0[~2‚Á½P>t&Áæñþÿ;Ä¡Jzî¼[µ¡fÁ]mê°æ˜!Î�Eð±gãþ‰oÇïú_½_ñ%oÔÖÀMÁág>ðï}ÿ‹øÜϺÂg½ùˆcÀþ›:_ªB¿Ž¹NÿÝg¨“†&ÉRãj`k-e*d 8À­P¯9«Ú·“ H;E5½qF0ûÿ÷}pÁwýè f€‚®IA`}\×ÿäoñÿþ›ÏcYå^Upý}ÅPI=øßnu5;½,í¥K$VÕõgW{|#KÖ±!¥hÆ‘ò„Rf„i²{. HW’jW��kÍRr'¦.k#Š®ëŠÓù„óù„eYQJn8ï½Æ q$@€xˆc°÷:všJÝ[„‰w^×ÄžAL °×cõ5>©®uHwÞžCˆa¡®¹ûš©,|êR2Íæ0™+—®/SrÀßlï)Ü>»ù—¡,sûªc}»ÎÃõwu <€û›�#BÔ9î¾6íû‹/Îå�‚Ý;oD�¹¹`-Ë�1M3Îç³­÷Å¢¿Vİ®ºöªß[tŒí ÷æ3, ¢™"¹«ÿÍq­0_¬UG¨¢DFÍ8žP)v±¹×£ëA#ë¡…«Ó‚·X¯¥àŒ¸ .:¡}fn]{ª«@uxhß{vÀ^{íµ×^{½ªj'ìµ×^{íµ×^{½Bjžgˆd³‹ ðœÁì' ¸{²3{Uõ›ªŽ‚暆®¤éÖÐÛ÷pθꚊ;—¬›¯« ç„eYq>ŸL¡iêê6 ßœ¦¨ÖÈ5#]÷¯ §“ª)§¶9V7µ6™ðœQJ€}³ <ÇcwaEŒ¹+ïÒCUÈ׸€5%äœÚµˆ1nÕ]®ÛÆsVg^3ä( OˆNæeMXÓ‚d›eÉì�++UInì6ÅlSÙb’‚V"p^ÉUiDš L˜Á¬ÖçeQàz=ƒEÁû)ÿ�GæƒåRø:Ãy¯ §œðøÑ noO/‘‹)£4 ÷x¼Æ|8œ�GÎlÏI�@”‘K蛄–—¬6Ä"¥è5Îv­Ë°Qª‘¡[ÂaYÐleKÑ em·‚<–eEŒ+â´ÂÍÜÖx jd#f"LUAf×’ Yçé¬`Ûr>ãñã[ÜÜÜbYÏ–Ë Ä0g<¸ºÂñÁæ9"L±©Õ´¼UçÔ•‚@-æ >Ã;g®Ð š²ðªÀbU°:“¨Ö>Y¸YUhçÓ �?ÆÃ‡/„©îxœŸ^ûô[ð‰�ý,J6Ÿ<ü>ÚýËh·.ÀKÚíoíÿ7oÌöæ¦ô Þã—~ù;ñåï~>ü¡gñ?úAüôû>ŠÓi݇¶�j½� �ú1æ »ž/>wU1(w )ûm›pçºàŽ+ÀøÐÿ8¤€ÏxÝSøüÏ{Þù ßÔ‘, brªÅPpÓÌûM�ˆÁN|<Ëíkîs¨ o"ÂÕÕŒ_ðº'QX¨”¹8Wt0ÕqÞaÓ6‚)³häG)Åb6j–1ZD—Üæ¢ ê¨ØìÞ™î4F¹Œp€ö{Îj?Ýsî¥Ûj3·óv¼Ík,=ïQr6Õ>·ù¤4ÐÄ¢UZTp$‚Qí¼cT̪[ÏS8©ÓÁE?«gZcr¼ §Xnu-ˆAmücŒ8�N8Ÿn±¦9%”´âöÖÉÆ¤uEN+®®àêx¥„4à=›jÓjÍÒ,¨u~œÚC+H{ÛŽ”Fp}ÛóZó¯Jk îínJSÛ=uä² ­ò%:Þ]òÏæ7¹p) ÒÏ’Añ¿y÷F91ð¿·³8²÷qä¬)2”Äq{*øÓÿÕwã×þÊ·ã·ýÆ/Dˆ`©&s ø‰÷=ÆOþìC|îg>ÀÛÞ4ãjª |�2a†KZ �…UpO®�yÂJWð×ÖL¶2H<' 6‚—øàê�‹2ŠhÜ?ûs ÿâÇÎHI¨[ÿ/EPˆ!LHEðþ΋xÏÜ !÷ƒÿ}l¢-Ùª�ÓØÄ�¡9ÅlǪ—S7Î021«µúf°óm-ŶÆÈ¬N;Ùò所3¦’fqšŒÐ¡@qýÏ�LQI iÕõì4Ex‹‡ÒuiÆéö§ó뺴õ. QWÁ”Ôm¬ }ä(­ ¬,�2ž®ú!P�º‚ðä[äV]'^:V±“ELeädÄLîäGï½F2Å sœ0�hªëð;sþà(’Í  (¼÷ðNÚÚx;’ÔEÁ™nì–ÔÁÿK»ùú«Ã¶ýÿÙû— Û–4M úþßÝ×Ú;"ι羲2ófgeVe=ººªÕê’Ô²’„ImH&Z0ÄÃÐf #0&�0˜`00i€!$ÄCµ@Öjª[êWUue=²òyçDÄÞkùãgðÿþX;vœ{³ap+mýi‘'nÄÞk¯åËÝ—‡¯íß2Ý AÌ…¦ ØÈ§x‡ „‡)LðÎcYou.½¹Çº.Û«¶HˆdnTɹ¹úÛ¿�¸4€î^`CPw¬§3Fƒ•b± 5!‰©EUÀÁF‚£Ôh± ¹@¿ª+×ø´¯Å÷E4Ĺ98s‹‡¨d–‘ð]®|íµ×^{íµ×^?;µöÚk¯½öÚk¯½¾$u8Pˆ£—/'Í)¦ª˜±Ò ­hvÆkÏ”€n𠜸¶!EdªQd”2änÂT‡kB\#Îç§Ó#N§3b\uCÎù¦€Ô¬RX1Ø6›jºÚUVkYSãÃT-Y¿Ô¾4;�ð¥g}V=CØ�]ÑsuÃRAéÑé ªfRÔMÜbmcD²È€&̇jYÚU1d m\"–iÁ².iO~ ¸½="—ÈÒóÞKˆeÕ6à¿ZŸš:ºX¾fÌ1ª €H�—Ð-:]µ{5«Ô"XcÄé|ÂÃý=N�÷ˆë  8‡yšq8p8¡¡dÁyYZíºª õ¼œÍÖ_šãÁ4:àööóá1ƒÛ�ݘ}ªí½FTe—Ìb ¼åÄfu7¨‹õºÚ¦n�¦¤SÛíhý9P.ÈÞ#åªHÒMï3ˆK³¾."@éî “Wk` „e‰�HyPÅù„e9c�@�wªÞ=fÜÜÞàx<`š§f“*³Êí˜`+ ¢f♼W÷ ç½:/ø§ÓYÛ²©œS³)‘6NxxP‚‚éŸù¼¬ž¼óþ×ññÇŒ¼ ˆŠâP›Î¥FL bÀš¨f³gá¥�õ ñ¿l¿ÚV¿t ¸«xÂ׿ö>¾öÕ÷ùóøÃïý÷w¿�ïþá�ðñ'÷Òó�[–x®©‰Œ;&.Ï�Rm§í.l^1€ëm#ûÏÖýàÿEDxïÝ;|û[_Åw~ñ#ÜÝ Ìî-KƒJ™Ì*¿¾Zü p0\›åŒ�-qé0öÊð�o­¾‡J)¾ä¢ŽzTƒØÕ›©Jzs'YDPRDLÙæ2 <’ÍÍD¤¹äýNÚ'Ö66à�XcÓ/£’’k"(,¤„"É@!:s)ȃãM‚ ’²åN"fñ‚ ·,æÔÀóyÊšÍï=&››<&¬Dz,Õd uw ³oæ¢ç¼s;¿Ãñˆóé„ÓIW‘’ºß,ËÙ¢RŠ�s6ò0f8vMÝ[û™Îµ#¸xws4!x&"’fÅ/ׯÉÓÚ€øÛ�¦=JìžTB@£fa=ÚùoÜ,Æq2~˜ÔÜÌê$)ÉG®|º›@ó !B‡”lÃEÇ 1)`ŽÒž7"‚ëÿö{øí¿õCü×ÿÅßÄÏôr éÚË1¡áo÷û÷?÷¾zÀÏ4ãåÁüÍ–@¶Ž%Pù¿ôÈ€v#‡–FÒ €È €$}žÁGý^J¿ö œVÁßýÞŠ¿û‡©^0œ×{ÀŠ€«�¸-éþæïEüOþõ�ñÉëü¼âÿ™Ÿ=òít7dú�÷çš%�ݤڱßè7¥ƒ˜¤„àD °¶£d±lr1§%B RÔ5ƒ‰ŒS¡$C}¶u±1@3§„óºªuzsŠÊF(º>Œ]Ý@Ò¬ŽZ¹E$H³»'f8'ͬ%—‚ÑlöÅpÞ1 ^ß[³Û}0•9759Q��Òulu·(¥ ®)®¶v˜È+™išgÌÓAÁpŒ°à�ˆ'-Ö…‹k–ú£ò»æÙo�¿W�QÉ}[·Ÿ§„×/öüÜÍ #¡8gä ‹¬•ùMïÕöÿx8àööˆ‡‡[]û™#;ÞÚògUý×õÂe´@wTÜÎÆû³9çþ}uóÇÑÆ�©º}9u¨Ò×’µijë®uSJÙD´UÒ@½nïªÛ˜^Ƕm®K°¶tnCll�kíÒÉ%{íµ×^{íµ×ÏJ퀽öÚk¯½öÚk¯/IÝÞÁ¾f6œÓM˜’ýÕÒ¸+ÜO§“Ú§N³)Æû&iu@ÄlÕkUU'²nþ4ÅyVè|>cYĸbY×€s¦ü.‚i‚eÇo«ª¥«²ž ª›Yëº •¬Ÿ_ �€H—"\tH.®äÚZ�ƒRÈ÷Íĺ‘cÍ(ï¹�1¥F€ÐüPk;;6»ÎbJÿî‘õ<CDAv?ÜÜÞ4€]3k k=�Z')0›)GÄ¤Ñ É²ã h–øjëÚÆ\N˺àñño^¿Æ§Ÿ~ŠÓã=Ö¸ª‚,ÌÇŽÇ̳Zÿ‹èût#[�º9©µŠ+T1ƘBãp8àææ‡ã æyÒ÷†ˆiš‚\T嚢‘J²0^2’98çÕê<S¨•ü5ïiÔš®Ý³˜’E$¸®l$‹(±€"#³ZæÇ´"ÆH†cFp‡ÃŒy>`žgó,?ÝŸ‘bƲ¬XÖÅb(2¼g„àp8L¸½=âæî7ÇÁO*º,ªPι@’ a«‘R²,Íi"x�Ù@‡yž!œAXׄRÎf.qPrðII)FœÏgœN�8ŸÏ88@¼¬1€ç€÷¿òóøþÿÎF ²¨rPmËÑlùõóÀEÛD.¸‚ œgÈÇåG83¼ÎPG|ôõ÷ðõ¯¾‹\~÷'üþ|Œ?úÞ�ñƒ~†O_?˜‚nP–6?q4•öUåhBÛUâBs|ñÎKàJ®¶Õ?Ð}{Àï½Ä×¾ö>¾ñч¸=*ðÀăBP¬WPÓTÐ €ÚÜdßS…î1D˜Ò¿äžqh÷½[wÿÜWÞëW·ª"‘ ø,ÂuS¿ÅdTûiÇpæSB¤E­²S´‡‡˜ã¸À!ÙØ®€*.làeÀuÀ£ñ¾TÐ»Þ±Š£�f©“¾?u(ƒ¥ÿ<;Lµÿ1‚�¼bìÏËRΪð4‚@L 77GGLÓ&�àd>€„Á ЙA´ SWW²Žff'¤Â@2µ.* ÏàyÂ<on�în±,w¸¿¿ÇÃý=p>éùä¤ÏØJÉö<8Ư67)w@�[éã8ˆÉdeu Vín3¶C©÷;´¬÷Áú�*Ñ¡€-w¼õÍR�,`ä¹jÿÿE«Yü� â1®ÄþOçÜbç!f®ÙëõZ L:ÆJ`€ÄÜ \ ~ð£ü·ÿÿwüåßú3ø/þ§ÁW¢�´sá¢`öïï¿ÿG÷˜'àW¾yƒ¯}eÆaÑl�¨¶þ£€!zM¥·‘–y‚!ÁJŒ€˜�JÆï/ãoÿÁŠ×�X׉¤€¿ë‹.sâ <.‚ùßü ío=±ƒ†¹wk÷Ï…vÿ]kÿf3¢ Mƒþ`AòdÆæT”N„òÎ9Ô©“Œè s²9ÁW‡�lÖóÛ~Ô3ì»þ¤h_É)µ¼û¸®8D¬\ f[›”x-¥­ë¿>«+³’ƒ�­y Ÿ3˜ë�ôSÁlïÍqЏ9š‹0PpÙÖ«9#YÊÃç¯Ë‚eQwÀ¹fÂ4M˜gµýw.4© <%™ÊÜ�DD#O@@бÉÔ•ø#‘ ‘:w´ØbÓE,ÊÌÜ{z¢M%ôH9"f‡O5Ž€Ûñ§ÚÜ/Uµ.€MCÀápƒ»»FŒ&#Ì œ¹–U‚p]Ë�'tëÿú· _|N'2w·†í{*Ù ®¿úß,ÔúÍ4IÃHÚ­o[äÅØ¥’ŒÔbÇú:o ÃZ >ßÉiÌY @ĵ6ínîíÓ¯½öÚk¯½öÚëg§vÀ^{íµ×^{íµ×—¤înoÕ¾ß+8}žÔJ8¦ˆuUð¸äÜ,Ä5§Tc„÷§aCË,ÿ±Ý'­�$ãÆ”æµ3Êj`ŠÙ¤ÆUÝꆰÝ,¢QõÃ=Û½nâ:oÀ¿”¶‘X�QDí]Kê››9eDŽ J%¯ºiåÌQ@Ï5÷¬ÊÒ­.›Mg¡MnfÊ —f]Ú2˜È ó„yšUá•2Ö¸ªMþñ8XrÆ´âæx£9«Þãxs@ʺ±¬Nl9ÍÒŠÙ{×Ô~?ÚëJËí€ÜŒ+ÁãÍë×øä“�ñúõk,ËDÀ<¦€ãñhªõ™½tDªÀµåÑ:Lj)àßàœ½ÿpƒy¾Á41"­m#Ó{‡�½ À‰TšåÞç„ÌóÜ6�5C¼lðÖºaYÕT4›².eRBбm̪«Du˜ðÃ&­’rŒˆ9š¢n9UÔ)yaBDÊ¢„–å„órjnÌ€ªüñâw/îðòÅæãŽrÉ •°æUÇCÔ{¶!”ĈÅ2¾={Èá€&�!p޹‘vRÎ8ŸÏJú`Bˆõ<��Ô`± þéfws˜_Õ6|ïý�ðú³áþ³Ÿ €¶®÷ƒ\s­ÙŒåEÁÔLȈ "%n}_A·Ëo† ávO[e=Œ¹2|s3áWéçð+¿ø¡±à?ø ßÿñküøÇ¯ñé›GÜߟ±®qÔŽ_�«[@ÿðK@¿oÆË60üió|Á"ŽÇXÁ«w_àÃ÷ßÁ‡¼ÔÜwSñ5ð1 eNC†öèƒÈOÒíúÅÀ~@2F EˆtðŸ€z®&ÂÄÍÍ¿ü‹_/œÂE Q¡!f™ x:„”\³Ñ�>€m¼‰!qj‘ßé(âx-Õóî˜a¥”Ž{šºµÚ—¶M2·‰Æeí¡$PÂBS€V…nAZWÍö¶1´.:v—ó)&¬)b]W¬Ë-no#Ç[8ö˜ü:Ðе"Ks(R�%"e— qü1ðË3ƒ�F’Èá€tsÄápÀñpÀôzƒ¿Çi9#Æ„’3–åÜÚ"%�y™§Cs„iÇâ�ä¥?œ„œìy!Ý-‡®éþ¥µß裱éóö]ÿÍê‚@]õ+ÍÚžP˜ÀÕ‰=g}Lô +«ßsÙêÀ0tõMj.VóU1]íJˆ¬ä‚]E%N»wÜæñÿÓÿãðWÿÚŸà?÷ÏþþÙâk`2Š9 ˜BÀ ~ûwßà·ç5ˆßúÚ}õ€wnŠVÕ¾¹”pV@ŸúLD°[×Sþ3Ÿ�3¾ûçï/X% y›ƒ{jŠmýl�žù×þÝ{üÿ½78-�puiþ‰{�‹Ÿ VÿX”Íýëó›<‰ �anø—ºžo‘c�¸8íº5fp‚6ÇfR7,%ÈºÆ Ó¹¨·¥³ˆ�Ž%阓œ±.ËÖ1*eøàí_ž¡ê¬Å 8Öu›F75· œÏmì.˲qpÞ�‚àY­ëC˜ºãSB³}¯kØQ¥^×1®HFÚ !À{‡y:à00ÙÚ®”‚´ææ¼¢ëÉŒœÔy¤¹V ó¬ srÒ­b®�û p¸:��]W%:·>ÕÔòvÍÄ0wCh_.Ãß•%p6GtÀš1µø'iëHm“µ¹QÀ̪›¼�iÕŠ›ZŸÒ{Y�Œ ‘RlÛÍV5gøš]� ß3¶ê1+UliŸ³Œ×û=ÏzmÁrz‰È®Kuš ¬úì•b ©MIVRÁù¼¨­¾)ëk®¯·�ØÛÛ[ÜÝÝáÅ‹¸»»Ãáp¬ëÚ¬ÄËZ°.J Ifùßì‚S„ª&fÆ4Í-½^j6"JŒÑܨ'„ ìÙÈ!µmMK©û{MÁ��>ú³ø½Çÿ¥œ Lͱ¢nÒÀv ƒ]A"#9%ýä–Å^6Ší�ð¿ @îEµÌvõ«”�€ƒç, #àk½ÂW¿öRŒœòxZñɧ�JxsÆ›ûG¼¹?ãtZp^TÍ­›ÛhÀ¸È…=íà? ®ˆSmT÷‡y 8&ÜÜp{3ãÅ‹#Þ}u‡/nt#¿*�íL€ksŽTÑë6@ÿ9: cЯ4�·+Ìõø—.ý"h€KëO äÁüƯýØlŸIA÷…Ȉ!LF *!HÉ£W±"„à�²*ã“óÍ‘c´Z¯ªíšï.[_ ` ÐO$5BÖ;QjŸ4Å©U¥º%X¾´f^{`Ì1e> ňeYñøøGŒÓrFZ�RDŠ9&Ęp›µŸ�8\@öÞG0GMW‚ d²g!eSÈáMȲ˜�ªÈ�©ø�ë3Þ+èçîï-g|5ÀÒpkL8Ì ¦ù€à½=O•@åý°™¦)"Fx+f3:M Š{<JÝ@ÔVšJU2Œ*!û—Áh_h3¿´>DÕB¾ÛŽ×Ÿµ!;’|d8ibŒ,™V3¨ ÂÒóÔmÞ q›gQU^ߟþÿÚßÁ¿ùï|ÿÂ?ýMüÓ¿ù!àEI9o‚SÈfg"à¿Æ~ÿdk í¯ïÜ:¼ºc¼¼îŒ›8L€sz=9g,8�k¼9¼9|ö�-&&!¯iÉàà0¡$aÙH: TKpm«ãßÀÿ᯾ÁgoòfMÔ]!:1©ý÷ëã©À†Å×£páÈ2‚�² Œ¸è`tÁ ¡0MÒõìÚ£I@päAPksÍ“W@S�XhÔ+_Ru A�82`Ý»€)(±sYÔ>¿”‚uퟧóÑÔæ¥ñA'Fˆ*5Ö©Ù©—M|AzL�úÀ°æìŽX:[?›Â¼²9b5+öṪÄÊ„dDĺÖ^‰„!Lº¾%D­kspÉ–3Rìq(ºÎópN�ÿqíÞ£-*JO›ëéš·^�€+ ™Ûš$‹¨ F�*ˆ=8TË’E‡®y×è|ïÛß.̹=ÿÕI,6ÂC]o¦iÆím6"F@ŒÑ¬5æ` 27Wª­ª~|Æ_®[ë=«ñz?5.@ ÑeˆÚQ%>@˜ç „°ãÁÖŒN×èF¨�«Xÿ-ÏŒh1¸ŒýµõÕ¢ëï:Úq®ÿ-¦úftùØk¯½öÚk¯½þÔ×NØk¯½öÚk¯½öú²,Ì‚GÝ;#‹pNsçð.AÕ�«�‘1#¦Õ¬ÎÑÔNÁ€†˜Mñd xˆn�3{dä®®2ûáhÅU�^7Cðƒ­%à+˜áÕîà0xS·:çÔÒöpÀ<Í6.ŒL‘RË­Í XLq–�œ Ö5#® –ó‚7oÞàõëÏððæËr‚H†óŒù0áöö/^¼ÀË—/ñ΋wpssƒižÛ9æœq^”¢.çóY-ÿ£‚ôÕVXÁ&#·ØTy˜SBޱå«éücƯlì‘�ˆ�Û57ßi>âÏüüŸÃïýÎ_C)6fD¦vÇ Ð¼a�e¼‹ƒ H¶˜y’É~÷ü4¶ƒ¡ã®°5 "8ò Þ怯|ø~ðR‰ ÉHIç„\§%b�kÌfWŒ–ŸÞmyÅÈÛ�ýyu´8ÎGu—ØF Jt«"2hZ-{w“¾ÐU±ôªã­9T+`SÿV"žD ©·+°9º þÉÃqpz^ÞyüÆŸûÜÜzû2€„TArb–œMµo˜N¶ó‡Ù=¨Ý?“:…TG øÕ\d.|å{ €‰™@¦FlØô!t‚p‘sœk¬Dn}mÓOMyʦätÌð΃�ƒA ê¬Q�wf€|>iŒ”Eœ�‹ó̃=º))›sQ6iJ_ªöd»ø” üäÒÈD &‡Ã¤1,Í)Dz˜—ó)i’Z†¾Ÿ¶Ä‘k§^ÇS tç|ü0fÈl²Mbæ�‹£\ëÏ+ Øü«Àã�?>ã_þ_ÿüïþÏßÅâû9üó¿õ!fW‰íôëU:=U€>»�øô3ÍÔÖó’¹d3#ÃÖDpÁ캹7�À�Áõü\›Hõq`øìùà_ÿ=àßùk÷øì¾XÅ%)²�×þ;¾â @›X‘ËõÒåzªÍ½4†“|NÉ%óDæi(¹à”£½¤€lÝáxÈd÷ÎÖd•È µPË0P ÑT‹¦"€…Q¤À­LŒóyAÊbÏ\çzz‘Û5Û\Œ¨ÄFxQ7€„”ý@ô”Á-‹ã 7€Ø9ß3ëm í\�ªn¥”¾Ž0BîÖž][N#Ât­ï½ïëM[?ŠPÔû”Úº>#§ØÖÇÌ <Ø»–ûNæ&ÁÍêÞæü:;2™Û‚>wj®¼Û¬aåé³ÕÖï¦Oú—%Št»ýJ\fÎ�˜\Õÿº†Zš²½oš&k'‡h®^Ý ¬ÿÍ¡×Ì›±Pû÷5[üJB«.ZÞQ‹Ç˜i$ɺîVâôÇã77·˜gsËçó^G²Awžè®õ�J´¨€í7ío½‹1=ÿãÚ¥ÄË@ç=`¯½öÚk¯½~Öö™÷&Øk¯½öÚk¯½öúrTÝ8dò˜¼mU{ýª¬1ܧA¶PµÃÏÍj3{��=Î˹E€oÙ�dÊ)´�Ǿõ ¶ºùB€·ÍªD©€¿7%“nN=·‰6Zˆh6–ŽÂ h�Y 8gˆ,]•œ¿;ø_34kû• ࿞�ªÈºŠ”»RQåº%jýJ9A²`µ|é´®ˆë‚ÃÍQmø}PP~òÃ9©SC±�¼’u“.›Z»˜bŒ�âJ÷šõ>,çïñðð��8�ψëÚòbÃ4á0Ïú5MðæÀ¦‚r´ Î ihs¨d îQ ઠ@-f»žfQ[ÚæaÿosW 6ëhSñºÌO6Ù1B˜tÃÞîÕ4©¢-Lj¥_ï»Zÿ« Dm*¤’KÁ“Æ@䂇û7øø³Oñé§Ÿáþá –u“`ž=nnnðòåÞyç%^¼x�ãñˆÃñï‚åŠg,N#-êõ­ëŠ³Ý‡ÔzEÇGræÌ¡Jÿe�`"Û N­Íü/I�a^7ýcß¼ÕñB"eÜ&¸yñ¾ñ­_Çßÿ�¿®ÇÈãQ @Á“ºI;8!ˆ p¹ ¸²¹yÝÆkµv¿`È…zûêü… Z€½©*UDXû{·‚W`Û\wzþ ñ®Bp™ûxf¨7ÂSêçXdzHAª.(Í¢¥Í£"׃q5Ƙú~ìš³®f ‘íò�$@xk[Þ¨ W¢ÆöàE\„¸ô¶f]�'üCîÛx÷Ý«¤"A^Èi`QW×—BHu®3 KUÔj²ÃÔâš­�Õ~˜·¹ï•°€¦ÈÌ bàùö¡`óµÒA*p¡`DÏB��D]X6÷¹É@"ï1•oÏ&ǦD-ª´O¹ËY³ÏÙÁ;Œ½³9ºœ€*ñ‰Í…†@¹Û¤·±S´í™“¼®Í·s˜:˜ü›7 �§rJˆæP²:Ç‹³<÷ë£ æÅÀ�§Êbi÷bëC}›ñôÛËÚÞ·­ã…Ð%1oµƒß—Zt€ÿnÁÿ>†Ÿ*žŸŸüŸÞ½�ûÊ’63…ïÀŽÎt¹N©ó=Á¹YÉ;RAqcáŸÓ°ÞÔŸ;Öµ){X,“Î�嬑Fj�ŸàâjëZ?´QÏW¯±[€kç¡Ñ$‘2ˆ9Ę‘’ºÛ¤œáXààl®©$u›ªÑVx2϶(¨ÆYuRfµ¦×¹˜+hŽS)V'¨ɤä¹Ë5²·9Pï}iñ.�:öôYF¥;C‘èÓ�]�cé´Ø’$æîÒAí:fÊÐgÛ³tèKãÚ¸¯C"ÎÖJÙî; Ï€íëÛý´Ÿ§›ûÒÆ @1'�±}Æè³rá¤VÉÇz¹Å-¨¥¿®ó*I³ö­iV‚Úñ8c>l�è.þ^ª÷9µõ![¼3ƒ\V"G'mwûÿö>Þ>¯«ê¼'£“ÅsÏØ½öÚk¯½öÚëOo퀽öÚk¯½öÚk¯/IÅÕP–¤­ ­G)‚ДÃÉ'¸T™öæš¹)„D ì€ÇÓ#Ä6z<{ˆS°’mƒ§w«IJÎMQ3ªAêæUUí;;¯ž[ß­ëu3J7cK)HƒJ%ň5. ”øÅÎÁ)j‚Â=S6• .Å€AͺJ¶žWÝ ÐÕãf“*Þõ5¡¼Ó�Ojê-Í<dÔ\áj{]²nô&SsÇ”°Äˆ››„ã<#Ì3Ø1&Ò¶�Ì ŠÈY7 z�¶JºpLÍB”�mèÅŒózÆÃÃ=Þ¼yƒÓéQ³dS6‹ù Çã·7w¸¹½ÅápÀ4Ïð. ª‰ôžDH_ÕÛUåJÄp´Ý€•¦Ž÷û«‹š+hµe΃Š7ÇÑ|ߪÔ+ȹ۴÷MÆzŸ\ÍP­vÙA7”½ëÑ)'‹QˆH5B�ÔZµÀ)e¤Xp>ŸñégŸâã�?Æg¯?ÅãéÉ á q/^ÜáåKÿonn,VÁÐ×u©]%•Í>w�=�†Lk%㨚·F!,ç)çW1^w0’AUÿU˜XèÒî¾Þ­Wïü~ÞH D$$S>:—á¼öãPo2Õ±wÈŃ)›Ñz¯«ÏEl._¡Žë�¶¥¶`.±)€Eç ¶·9 j¾mAÎ5—X6ŽÄlÂ{Ü6‘'bBüÂõ…ƒú¹ªðås”ÐõÛÇÒ"À5H@…: X£Á[6?×sT±¿lÀ�Ú®äº{‚ˆ LŒ¿ø¾ƒ÷ß§«ËÄ;'ä¼´oTU=A�HBFâdî •ô#�èE€8S„‚‘›Úq8»QØk ™+Eçtk«KWðR­œQT¹kFë"ÛÞ8Z)«=ø@*€zÁ3ƒìUijƒ^užˆY =§ÁŸM©ë‘²ŽïTÁ²Fk©ùÊêü‘u2 w{ül PÍ8g§ àišàCÀ¯ŸÞ£u�浨;[Iƒ7ˆs^ÉÃv«kÙè¾åÅ«SXu³¡îpÐûmwl«ÒF€1 uW¢a�T†Ï«ch¯½öÚk¯½öúÙ¬�°×^{íµ×^{íõ%©ÇÇG°gËbתàk@®êä*(>MÀãÃeîªÍzj{Ý2G1lŠnŒ®ëj›XeØ@ è÷Þ›¥¶Ûl(;Öl]Ͱb\›b¦äny® n6uLU¸ˆD¸müæ"mUrUñêÆ£‚Å sSLAbØÈÒóuͦ´)( ÍQA3b��q2<ŠÏxDI lZÖˆ$eæß#Ì¡�ÕlàÓ²ÂìceJõtÜÑÍ eÉÈ©àtzÄ›û{Üßßãt:!笀Ñ4á�w^âÕ«Wxõê¼|ñÇã!Lm³��Úç²ó`ç‘ר²_«ê‡�ªY³ÔøÑÖÐ�B6;׺mïÀNÿx�Y²ê&h·§î¶ÅrHG…`)ù"gµoÐò˜•=€ÿ•ä!R�£Æ/Ĩ›¬úë‡C“5îß<à³O_ã³O?Ããã#RŠðž1¸½»ÃÝÝnïîp8šr-q%ç<Øñç~ƒr²Z²¶~XI()a]϶‹FHÑ(�`×›µï`kß:Æn´ª^PñÛ�¼÷ÞWÁ¿òñwÿÖ¿�HIMA�KnÀ«Ô±š<'gêlf®øÿ7󢚨ïò÷¢ × 'ý~LÁ0Ô^œYI"ÕR\LðköâUÀ*µMú>�µ�RmüûϬ©PÐÁ: ãPÆs¿rÊ­½Û¤ˆE>‡Ð¥™À6°tpÁ³î:Wé{ª}ñÍaÂ?þ�ü*Þyç®�Ú§[øçœ�g·ê”A`íUÓØ) £ Žβ‹¹¹”°F²Ð€–ŽÎÖ^L@aU7‘!«¼7yÙ½£7Cÿoœ ¦|l‰:Ï'ÔŽqðwÀÄ8`öv] çN§3âšÚ32ƈóé)€ Y¤¹vHË�Ǹ+RPRFj-ns”¹qhÞ¶”Ç`N;ŒÉÍð‡ À›Y”‹9Üó 9‹;ed§JUŽÜ@ÁQ™ª ¨ ç$æÞÒšSê=Aw� Ë>NϹÈûþÆëÖ [DtC0g !È:×&”ËMï ÕàÊ[.Þkd"%×µ;Cþ7àæFD\ ©lãn«xÁ“Ñô“OWü_þýãßþ«?ÆÝ�Ç/~óönñç¿s‡o4ë³k¨2€/„’²Ø�6©×Öp·¡­ Àï|/â?úî‚¿÷‡+~÷œiMÎO2º{ÃxOÿ¥Näîê16«ŒÞåòd6ìà>mÚÑô_ÀB\H)~·ëº ä<ïÜH�¥(Ñ2®©­ODÎs†Üõ\ÚgeŒ¶ûhÑm}Y#­»ú¾¡ÁQ‡®<§ÕÉhŒ÷’¢£Š½³^«’{mýR2RŒÈÈÈP÷«ŒçþçFu‘bý[À³¹­ØóÉY{æÊÊÙ�íôY˜©«w°¿öQn×Ä›î´qù1§Ÿšë\¬q¥îµØ1œ8ˆøMÌ“\¸tKü‚"æ~“®¯Eh³ä©‘ õúrÎXãŠóéŒu�È9µƒÑŦþýÑ\aŒxÒcJ:q ªùeˆ+K) ëÇ)5Æléxq×û†” §ÙÌ{íµ×^{íµ×ÏN퀽öÚk¯½öÚk¯/I�N�MiïœS›Ûá÷ÛMt;}Ç ò Ÿ�SÖ¬xïq˜� ÂÕ¬ÏAYÂÍŠR�N�Hj‘ž’©à+à?Í‚¶¦JxnWA¥Œ(RQ»÷¬`‘cµu¨û‘¥è¦jS""„€)L˜¦ó4ižµYhÖö`êáJ„<©exÀÔvÅ5ÿÙ€—X°rŸu4ÝD…BÐ|qbjyÕÙ¬ùÛF;kƒk ,]’ç\°,g<><àÍë×xxxÀº.pÎá0ϸ{q‡÷Þÿ_ùʇxïÕ»¸½½…·Œn®Ù«®Äp¤*êÅló%F‹v(àâX$o¬¶k¬CÍÅ-e»yÈÎc"�iU¦¶�_Sà焸.FÉ­ßé†dwlÐ ÐÝöȶÙ)E ®ç&«:ÞúRÔ¯RNTEU7�kÆù|ÆýÃÞ¼yÀù|BÌäá0áx{ƒ»w¸¹»ÁtpÞC¬)ª5sÄ”�blÎ 7ÍÞcšg€w\Ð1F¤”ŒLЉ)0àažuŸõùf7~]£Z¯ŒB¦†�'pŽ¡Æ–£Ì±÷³‚[Åœ ¨+1°(ˆÄð¹(QÊë³Á±‡›`ç Ȉ)#¦„œ °Ä6fSÉp)™ÃŽ’Ô¼�eÑâFJÉ9£H¹ÿш .~ßöŠaN¡gFæø’FÚ’ök¹à— o“h‘-˜|A>Áµ·ŽJr!z&­@?½´8#Sä75òóaä.YßCOð•Ü&f¹¿9?Ï¿ýw^ã·ÿÎkü«¦@øÊ{¾ö• ?÷î„ÞuøÊ»/¯^ŽA09{æ1°®‚7ç‚O>Ëøô±àŸF|òºàÇŸ&|ÿ'ú}J劂¿/©Íñcóú-)`´þß:*\L×íž]̽ŸWò¼“ ÑSE·s6ÐT! ê½¼pˆ >_ÈHе©ƒ µÑæÿR Df—^6H—QÞ‡;”«cmÏ£©ô @Î9a]"–U£ŸRÔ5Àí4µuÉ™4’êñF7­¦a½/È®l€Ýjÿ¿’‡yztÇ�n*˜_ïmS¥%õ娯£‚,h ó¦.¯äÚæ eî$m}{C¡ŸßAú!Ú¡E ˜šžkÿíä%"—a ’í« _ãs,·ïk´ÒårÎoÚrt<»´Ä×÷h{—°8£ý¾ä‚X)‹«$ÐEI¤qÕãx,ú9«b߉k.íï³áùÊöwB}æÖÏL)6¢ñØW.­üÛ5pÿû£ùž”뀧÷o¯½öÚk¯½öúÓ^;`¯½öÚk¯½öÚëKR��'„9`– "A7}.r¸s®Ê Í%vÌ ÐÁ6«oï=ÎçÅÔþ³*MLE”T6 @7¢Ö¸b],ë‚óù„ÓéqM¦) äb›£>x—!Å©=¾©Z³¯1"®Q­Pc4%ulÀôä–¦ ~Ö¼wL΢Yî¼.X �E b“öyd R²´MتckfÆf�G�7^¡‚n!SÔMµ�¸0*�\Ϩö@mºæl�r³àlÀ>«ŠÖsÍ�¤˜À) ±dà’k–ÛqIx|xÄgŸ}Öìÿṡ¯Þy‰÷?ü?÷áWðþûïãÅÝ �jžgS°9³Á²$§jÝRÄl­3˜3˜IÏ;f¤9ã4µœP˜“f†ð«VÄ„0)A%L¦ ™¶¥d¬1a]ÎH1B$!儜2ˆy³©©çy‘IZ ¨(°¥=SIõ÷9F¬)µL\ôXss1eœ–3O�8�Ø'B˜fŽGܼ¸ÃñöÓá`Ù·JZÈkF±c×ÏXÓªí%v�G°S;ïNn #B¨»F.#½?ó<˜ ¢ƒuY°, –E�sܨüšºS€ßýýïý'ÿ±ô7ú$A–ïNFô@Á||�_ÿ ÿ ~ÿwø‡’�ŒdhLUËù0fIDH,oz ¿Ý ö€~óSeÛÿ.ßß,û79ÙÙïµ ¼‚Ç߀rÕ½cÜÄ®à?®�ÿàÿ malîîX0ªjø  ~6Þâ o Çi¥ñƒi¸_Ÿñ«¿ô¾õÍ÷ÌÑ£\¹irq/5�̽ åÚŽ¹©LA¡¢ªJh&4ƒàCÔ*8S¿oJÈKõøì7U­Û]SÔ:=@örSþsµ@¦JŽQÒŠ €˜às†Ÿ  ±Îá`Ï—y>à0ñx:c9/ˆkjà˲,vo+(gó³#øq£Ä„:VKQ•8¯î;EÕû¥t n˜ÇŠ÷~uHÁÃËÏŒÉ{ÜnoÖó‚’ …ô9i¶Í9eDŠÖ^™Õ‘¡Z>[Ö¸H¡ötÂ�9�MŸ;öÆò½Ž�q~ÆX¿O¢4ÐbºßžªÆG r(n$€þü­À²XLƒ4'¨Ñ^¿;)e”âÌU¡hVãVFÒsuªJ-~é9rˆžC·¶¿æ„á}€s¾éòÉE¬Q%Y³‘¯”pÜ-ôµ1³½WÏ/ÚßA)g)Á!ç‚dàý².íØú<‰ˆ15ç("gÏ ‡i �$\JV’o]ç¼!€Ô†k^^5ÂÍ\® Ñ[ÀHx(øƒy¯½öÚk¯½öúSX;`¯½öÚk¯½öÚëKRëz† «Å‰|Ë6oÃSjoêUSµ½wH9�9´�©ÖÚÐc�’9gä˜-ã^-,ëg„0¨w,è x#Öø¿ ¤”P*pKßѹ)üí›§�§J{ùÂªÒ qlÕÿ—Öÿ[`@:¸9€ÿ—€'žëF°q Œ$€U0*;{v¶Ã*võº2ÖÏ}Fq§€�Î?ï¿ÿ ¿ñkßÂ<RˆZ¾Kš?We*Oç�ê0Œ¶¡ÇÑS÷�zÞÒØbý}Ò-Ô·4j ¤sZu£@sýèó¢\�u°‰ ¹¨=Ém=3Ѐ—oÕý¸ˆƒÚªëé™9…6Ä�kaRòEçã‹÷m\®Í¢ôä¬?Ì9eˆã6÷h“+!0gå´X¤­ 6ó#3¯ rûù¨ÐÏW-Ò•”Øû¶lƒ¦0!L¡)Ò%‘A:RCe0qÁ;�Ìs˜p8pssÄñpƒãáØŽ“M�¤ 2›vÍwŽ�)´M("Â*ÉYñ0#xï0¸»{�/ï0…€,‚órÆÉ0%&³mM(8èu2&¨ÊQÍÇMƒ³Ej±U‰\í]Sýz%„„@ÄÕYŒ±oâWûx"o^|"ÿó"ð]š)m–M��°S T¼÷þÏá�¿ôÏá¾û·ðÝ¿ÿ·c‚DÝÐwR� 7ÀÁƒt¿kÞŽúw ]6ºÏ¾ø ð¿ýa‡ÌÞâ.0þJäú¯ŸXÿÛQŸÿrÀsÚÔÃdú`¹BÎÿLÀxñc¶ö ÌíbÚjÕ¬d�ãaÂoüú/áÏ|ô¤dÄxFÚè:œW  ²eHî$£ö®Â-Ö¡� bSÉŽ$ ‹7sº"è¥öù¢Œ˜Þ?D6é9U@­r,§¹´÷×ÏÔS ®¶Üï *K‹ (àêÎÂçôSƒðnBðAU•>€Y�×UÁ®¼w˜@0™…rqm´T`¯>̨ÍäÀ<í¤’|˜W8‹ ‘œ5諸�§ 7‡@Hç–¦rUÕ(•Œb ž’&ÜZˆ\xè[[]‹˜¸ J_ŽÍ BŒvjÎí84Ž¡b¶ìØÎÿ—$©cg´­ßèÏ7sÌÓ+0Bƒ�ø èà¿]@}_¿&i}¹edqèà™CO’€A‘‘Î#mÜ÷V}nb~']ÏŸXö×vfz²¯8÷ñ€žÄ.üÔ5Fš¼ý…›9îZ=><øãñ†î^¼ 7¯_ËØw°Ì(¹*û·j}bI%ðØr�¨Ó@ãÑFß9¢ÒèDÖèÛ ~V]C²ëyí¹‘9—6w÷¾, çú¼'ÅHšÝE¤FAJ[¯×/ñ.éBã›ê<éÌYˆ6cBJ'W¢D&B�©ý<‘)ã[äUA*”“­» JêîV•¸š*£º€ ¯ßªˆÏе}sÈêz óÓõ.¤„ÈŽ's‡®­rkÓR2RÎ)@ïvs"h¤µ¼±µmñ+�£¶åÖ9  NåŠÛ ‘SÅúÕ`¡/�X]Š ¤ƒ®Ø_un‰QŸ£?·Ff]Ž%v'œsûdÛã¿ÕUBãÏBsʨDäÄ@ì×zAzÞk¯½öÚk¯½~vj'ìµ×^{íµ×^{}Iªg¼^Á+h'¼Sņ‚þr;nv•7‡#¦ÃÇÃQÈ)€I�ÇbŠH‘M0ÏJ¾�7¥ˆÚOÎxñâ/^¼ÀÍí-Ž7GxËÐ\–E­ÿ Lζ‰XÕÎ5Ï=¥ˆÇÓ §‡,Ë � „` ìŒÛÛ[¼xù¯^½ƒùp@ΧÓÓ4á<Ÿ±®+³VUûVU­Æ”Õý ôÍb@Ñà=¼×M/@³LSJj…Z”¢¹¨]ýšVœ×3–Ó ëºbµhÍ•¡Zü{ïúaÈ[E»G�BÆ4EæC?ÿ¦0ÊH+°–ŒórÆëׯñúõ=N§G”R0fÜÝñòÅ ÜÝÝažgˆˆF6,«9,$älç$@Ð75`UUAF(Q5RÄêîÄ€dø¤´Ý*÷¹žª ¼77†"Å,Ý{ÒûV‘ÈíL˜õÞT5|s§hÖÚ}Ó•‡\\æ; „Ög„i‚cg9Ú+–Ó �§G,ËYs x³Q�¼o cÉY7¾”dvÚÅn¬}8LÁ6N{Y׈ór;ÆWä,�l›¸¬¹Î”ˆì!ÌóŒùxÀlÙ¾))x·®k³-¯™ï½ûλþ÷"òRªB¯©³ X€BNÁfa€D 8Ïøö·_ûê·ñ;¿û7ñ'ô÷‘— )ˆdy»ÓNÍ’ÿ²ä§‰¤lg.ù"Ǭƒ‡7·�{Œ©ñ[gsùœ¬éqzÐ ð ü¿=@šzþ* ¸�U_T„� ›ËGËìíŸéœÃ¯ýêÏãW~ù›!´¢áy±9Q\£T 4%£]³›<<ëyg)(™@ (fA\¤˜EGk[mÚØb�=ºZ¥— £Ä×”R‹6¼F…°3E£Øx4åhé@I¦Þo¤‚Ñ¡P² F½ƒ'%ñO Ÿ­ÎþE{Ž�d™§Ë8ÚÄŒ1ã¿õµ4¨æ»ÚOíÿQ� ÆFßÞ£m,ûÓƒ:§Ò0Éäê}¤g;¶×=8<×é>ýô“›yž©dGŽYäÊ3¨Y¹»aBd„“î†@®+âUY]ž‚ÿ¦´×x6¥‚œÎ糂¤F˜­Ç ¡+ôëz ¥„ì³­«÷pÅÀjûœª®.R69íJÌÛyÇѯ,�ìË®E"1uõ¿>òÕ-á2Ë]£\'ýJ�«H ŒN9�£Š®’�þ1%ÿ•Ø›JjÑ]bà?@r�£E”< Ò¢Ud/ô*K³ÿÏFä(9d¯­ ÂÈEÿ&­òûßZ£€ÛÿmÕQúýªà¿ãÑìCI R£ÐÏKךÔî—žG²‹)¤üW‚¬ŒKpÒ¿ó°íûí{¦�S¯©F¬Í³Fß„)4ÒJu?ˆ1mÚßOL��°×^{íµ×^?SµöÚk¯½öÚk¯½¾$U7˜¤e³ÏÎŽmcÇ·MÝhR@ºÿU¥ôòÅ;˜Mù<˜¦ŽØ”Ò "¯Ë²’¼ó(77Mõ4M3nonqkàÿ<Ï`ï�-«ý¼ž ¸Õÿö>4Åó<«‹@J ¸Ÿ&<<<"—Œ<ŽÇ#nnnqs{‹w/ðâÅ;˜æ 9'SB1¦)4µuJ¹E¨R?ª µY×\P€Fˆh])§RÉX–³ÙMSSMżb9ŸÛ×étÂétBLÑlFµ-¼àIí竽mÂVÛlï™HmLI•§a 8äY3ˆ‰�¢&–q^V<>Üãõ›×x¸ƒW8fu^¸³vŸ&@ЀÿeIÇŒ&Åžª-î&ÃÔ,@]in­i� Àçç9 J膮v+Ö‚˜VèÆoÁº&,‹žOÝýwÞ5@Ã_ôMç}SEUðeܨ¯¹õÌ §îŽ•42á§€išÍJ5#Û}{x¼Çéñ)¯ *ÞcžL彿Œ—b6½¥ÙR£tp x�é0OLód.bñ ¬aÌàR¡é¢ÄÒ¾Y³v�WVs˜àChÊ£EkÃ¥üÜW>pþW~±œÕ DAUÍœ-`ÅÀ6@6_�„Ãñö×~ßúÖ¯à÷~çoâû?ü(­ð ÿÖœÁ¿ ]ôH yz¬kÿ1nào~~˜líÿëûFõÿå ]‚ÿ[±ó8­*ãnÀ �p™ }éP/FÌR|0oà?WLÞá;¿ø5üê/}ÇãÔ@qY‘¼:¿PœU" ”1Æ¡@D¥ÀÜRP ‚¯ R�ƒ $U6'�¬Õ#!G“ìI Dx /]—öVµ÷˜ÿŒí=IÕÀ1¼‘qšCËdª­²¸”ÓÕ�(q‚ôö(rŽX×~?”hÀžá§ SJê4cDŸ Œ5×’®`�ç|#Tõ<îª îö^RtLKÎÈæöQA©”BH XÔg§Çñx_Av/!�’‘M)ëÄQ«@cžƒbÊõ–lÕúÀðíª9ÀÅ9¯—gð\z2°ŸàÝ}dkèßH;í=ôüuÁZ’‹¡Á €Z?¡¦ÄÏçÒñF¤ãÜcÄ� Ø×ÿ#Øs„èâ:Ÿ8 jD"}Ywh ÿ3*ûNBqvºr/Ƭï˺ˆ ¹ì%•t`ç'$Ûkú¢%òö{ §äëÀõ!”­m|Y‰)ç–g>ºÔ˜Y³éë„Êy›�^×Aí³-¯=ň\2ÖuÑ(¡1¥ !Lêèä=¼×ø£1.€]lkÃyV’^ññI4Fϳïn-¶J‰)+Ø-~«^7 nNN\¿ÿã³®P&dNˆ)!¤ˆ”ýµäáCiŸWIž"¢¤$Š×uC‘lç‘Í@÷¹”+c„ú³´å¹¹ u ½“›G}'×tU=pé…UÌ¥”4�9PŸ-¤X” ó&‚`<žþÞ NT[R@{¦[ts~Î p�[™Q%h  Üâ¬Ð#¯D†¸‚NÈYP&Ù�‰|›÷»#ÂÓy¡~yï1ÍæyÆá0#„I×®F„H)6§8ºâ,´öÚk¯½öÚëg©vÀ^{íµ×^{íµ×—­JÝÔËÝBÈõ›Í¬jZÁUU¨èÆØ»ï½§êãy6À¤ÐaV°öÑ�T™R7G™‘æÀ3ë¦æ4c æÃÜŽÅÞ¡x�”3£oŸKDðÁcž•4p8à&�¦0µlù”Ø9ŽG%(g„)À{gÙœªž®y9ç!+3c¥R ’s`àsF&Uɳ催qE)+¯à3ƒ[›å¨ºë²b9/X—çó‚óùŒ# j™]Õ1λ¶€X•TÁ‹¶E ¹ýPbÅ4Ïö>Æg¤”°¬+îïqÿoÞ¼Áy9A˜nonp{{‡ÃA3è‹©ÙN§3N§1®¶1«j0�£C¢�®Ž$­O J!S…©uLÉ\ ²sÐ\PëswŠª>¯ö®q=C$ãLj…𢒢µ73Á;o”îݪ·m¶zÀg‡ì|WÅ�$Ûë¬ê¨iž1ͼ (æDqZñpÿ÷÷XUñ…à1ÏŽÇó¬Î µ«•ØuiEÁv Ï^Õÿ~V‡�ÐY6:×¶@'ë1Lé¥X|U{#æøR ÿu3¾’z¬þ;þùúªrW›qU¡ue)™º¸ãJ–S^ 47�…p8Üà×~ýÃ/åßûãïâßÿµz/Ô3Ó7óÏ?˜;´ü¼ê }Ž|þŒöÿí'WÔÿ Ø|þ_‹�¦ mS¤Ýƒç]ž�h÷ˬ�ÍVùîöˆï|û#|û[_�÷¼Qõ:Ž2mA’z�§ÉÞ#*¢™ÊúSGrJbˆE¡S‹W©à À_�\ií8•/›}“'-ÏÜÃF¨IÅæKUAÒ˜)E /JF°<ì\ô}6¿Vv‹%V{g¨*8™å·c}Ÿ3ÒPâÁÀÓ,™�³x�òåfû],‚%£”©¹Œ8fp#)) K•´R”ЀPÒõ�w:÷<ÁûéÚ¸¡kÿ!ciüÙ["®ŒCz®³_Sˆ±›�çOÛO ?›Ä‚�ZCƒ= Q?«;{ˆaŽCª†ý®ý·2{Œ@¹NEÞ—bï²q_£<ˆž½ý§ã°¾P*?icº$6lf­vß·6ñ#Q@žŸ·7'"Ÿ«þ߯·<×CŒìp¥ãœN�·DLD iž‰òÒŽè6ôŽùJûQs ªŸ“�d׬ñͽRLm.sÛH)Ûå~]cÓDð^ã†ѱ“-½÷˜B±ugh`o%j´™a\Õ{ÛèZm^è×YAô-øNW­íSJp1!…¤.N¾ÛÄ{ç��üàrF†üR¤‘W`^�v±ùVòàÀPÛÄâxËx×7•hz©¶¯Šõ¢×ß³­UkÄQ�³åÂ=¡lˆ-D æW1ÀfŸ_Û)7×l\DúyÈí1¶s(*Ÿ…� é3£º1�@ÌææÌÁÁµ…Us º¸–F$�"ò/eÏo®)÷5dNÛ¶­ÿçÃólû!¦ˆR²þÍ8Ì1L¬óŒ¬pe|íµ×^{íµ×^zk'ìµ×^{íµ×^{}IJ‚]}éͲ\̳[4ò €Qð¢]i|øÁûaÂ4M-óXìs˜Omc«Õ¶Þ‘SÀÃé&–g×lîK)`¨"5˜"j A7DjïnïÓ4ÁOÅiŒ¹º¢)?³ºÔÍ)ÍQWÐ%¦ 1û}瘙X†]{‘Q}Cͺ¶nlå’P–‚³XV²)s{U€º®6�)"ÆkÔcÔìSpFB¸Ü°«_)�ÉLsNXãŠàC#F°ö í^—’q>�—ˆóã#îïqz!K†wŒù0ãææw··¸1Çú>É@±ktPbˆ*y¼ `öÝZ¸*ܲ ŬࣩÝj9äí`¶AUø-Ë‚u]Û¦t%¼|qûŸðßê ¼÷Í_‚]*ˆLí/Wr¸+ maº\ $€R@¬ãÊ» ßúö¯á¿óá'?ù~ð½ßÇ�~üÃ~s+0Á¤±@S½~ñóÞå™¶øÿ-~úóÞ\žu'Ø¢Ð×Áÿ ³ùIØ$Ù?çŠ@-ömLVDQ D„È6ò�c|ãëâ;ßþ>úú�¼È*=*òžªõ0N ƒ�¡Ô›³Ü7@¡�}Ñ uѹ�œC`=—â²Yg7‚ ÕëÊÈ™ l�4^mf¹p þCúmÔ¯pè±+ñÁ(}>HY�¢ªèǮХè6ñH%£�YDà‹Î¥HSms}žMb®&Ä ®vܰœä\Ì2^*J5|þ…Ú‚RRÎ )VÐÀé �€ˆP&ANÁ€PE�Š<õy*Æ9sS²2ñ.z‰\ë2×~4ܳ-øÿöºFx>õžÌQ�`ùyÿþ‹²9aÚ}ê`œÃhpÜ fò?æÕzŸZ4F#�Ô1ÍHéÖò܆íóH‰ sjsÙ�6vþOýÔìÍ;i¨ºðˆìªó:ꤵ˳üŽÎSøâ¢ý‹s”·Ý¦qað¶[ÙÚáúÄ,E¨:�Á‰[¬Ô¸ÖjïñîjÿÚŒAR×,ÎÎÖÎb­BSd{sÈF¶ÑH%{.s´×ËFÅ­×$OìöÃà,¢ƒ‰�|%U’À`k€êLp¹¾¼´µ¯íX*ø?€µ)E¬ÑÃûU� *9¸þ��zn¼X K%ŠÖ¿5’©øË`_JѨ 8S·;%+±S"H”«“:7ººÆ2Ç”F‹žmtAp+U%?�&+(>ê{Ø"žÆµ7�ž8l�÷²!Ü�0;Þkº°ÝW²²oïëŸ9ûÛ)´ÈˆêvUíþõ9—Û¸.eü]nÙÖš9S)(FÕ¾º"¦ÔHÑcÄ…±˜'%m‡)´¾š\Ú:hXrà'1{íµ×^{íµ×ÏF퀽öÚk¯½öÚk¯/I�Ï'xçàS‚÷±éLR7Àº•f/Ú¸1‹>xÿÃf‡ï�Z—\p!ÇØ#˜á&Îúýätc¯n|Å!I°ÆˆCΘE­ÕÙé¦ç4Ï�¢™ÍuÓL3Ö“Ú–2ÁYàp(ð)�a²Í©ªæŠQ7`×uÅy9!Ç„lÖ¯vQÍjTíI“m€%ÍHJ4)-šgS³1uÞa FP°MÌbÊ+µçìåå¦òÖ~µ ' Pm§„Õ9‹/èY÷>xS�U²FL¦* çuÅù|º,þ&àææï¼ó/^¼ÀÍÍ ¦Ióãe�(Y ¤SpH(�“$*0�‹Ê¥˜µ°êÃ!ìºí±YÇ+R@� —ß­êLû�öÁ„È þWÛþ®Äíj®ªøoê/×7BsÊËŸ—–îœß(´ô}ÞÛÆ¤mìÉXׄû‡{|úñ'øä“Oðæþ5⺂ˆ1g¼xñ/ïîpssƒÃÀŽ…›æòökUå5ßhUVAR»Î5EÄ‘£²X¿W QÕtšúM¤Êåjã[U}ëºâ|>+ Ʀ¼»9Î?à_&kp"ÂÝ_Ç¿ü�@ÄÙ&7ˆ\zTG“…¡å"#+ˆ aS—™M-~åëø¹¯|§Ó#¾ÿý¿�?ú£?À§Ÿü¸ÎlàP~zÔ~4~ÿb¯}ö—›+±åÉËä 9XÅoˆWÀÿ- lÉæ  ‚j |“®øUP‚«„* ��lvÂIï÷{¯nð�ï|„ïüÂ7p{37«ð!�»¹ .}Å7 íÊê)?OY¾_б“fûƔԢÞõÍ~ç&ÝÍXÎIçØ’Ë¦mGûýî”L›[„A�ºy>UÛs»}ƨÚ=àŽ>ߘis¹‚l`ˆÎ})å %h=wPÇîqáIÕª½ÀqF–žÃ­ªN‡iVâV½•Xç .Å@aîN%o]M˜, è»”‘(Y\E�¨jÍlN!JNsÚ·¼G™gË'P$H)  ™Îë¹~–h4Iy+5檎ŸpáýéÇù%ìGo9 p~©.`pŒÉñ´ñ¥—®šÞ†y¦Î…ösµ×1¤q-„Ò,<÷ŒAù+•D ÖG:@ßÝ�Û©nc®6YGiqu<“ÎåCRÏÐ>cVùS€´ÂòÌ}ݶõÛçÜí=¼j¶ò9„+.m?žô§up-zb]–;u š¦ .gDŠÍ"}\_ŒÀøe ÀP³)ÎyŒö9O‰w Þê3z]cÆW&ø6k›zϳÙõ§Øíè½æ`¢Çóæ~CüT@_Š€�¹*ЕÜXcx3—°Í…êÆ"ú¥ºcqÑg~ý™:(¨Â?»Ô¶|+¨]ÛKÒ1@¤ýdŽ@ÝEG×5ÅTÛU×¶Áþ>á"Jì+ºËû{Ü&Š€k3IWþ—‹¯Ñm >‡òæó6ëGû[¦‚írá(pmmÙwÚÜok,Çñl=%Çõçb»ÎóæØ%wÒG=� âw’C'a4§³ÿ'{†ä%VŸÉlD¾àõïŽúåØ!—üd­4¶‘öawéHµ×^{íµ×^{ý Ôþdßk¯½öÚk¯½öú’Ôãã£å1Â;UØl3‡ÄWÛ ª !ÕM,ÝØyç�wTÅfÊÈ,1fU %ÛSŠ(%)`åÞ©jEŠ Æˆu9ã|VkwfÆáxl 4{‡ižq“oÀĈk„AZ#‹èç-Ñ”CZ!µxv>tKÕeU >›BzY4‹UDÚ†!D­WÏç§Ó §ÇΧÖ è–�Š*å„å¼ât~Tà6«Õ½óóÔsšÛ{t£·n‡–á©–šÞ‡¶9ÛA0ÝŒ-ë´vÎ!XöüÍÍ Ü�Ãìfµ™wq�-Î!g½î"Á¼xùï¼z…—ï¼Äíí‚óªÒç-¨®xmWS¡)'U‰™ªV:š¨êyyÙò°«Û;2ÙÆ³ö§jO[ûé!åÒ@B%=8³´ö“ky½Ú60׉l™¾ý:Z»y‘ Žõ¼™.xs–Pp,Æ‘‚‡ÇG|òñ'øÉO~‚ן~Š%.`&Ìóï¼ó ï½û.^¾¸Ó( &µóŽkÖ�ôj}_XÀ$È"`)F*Qµ¿¨RTiµ$³×­ªÿ‚–w; ˜zíèq>ŸñøøˆóyѼáRÀ$€À»€‚ŽóíK|çŸüÏBÈ7¡1×ÿ+›”w8ós»r”¹U=Ç%˜ßT0øæÏÿ2¾ùÍïàñáßû“?Ä�~ø'øì³OAT�ó¨vÿâ`þ?xÉ•ŸÈ3¿©/øi¶Ǻþ_ÿèÖ¿#H¹Ñ;6e¦Y~³öe2 ¯8ÂûïÜá½�oÿüÏá½÷Þ“3…9÷#2€t-ß׿wë}+¿Œ/¸ü%–%ýN)(T:,·žÏHìá‚ÂÎÉÁì¡™!ææ—q�íÜ”?RzlWÍtÁ[3ʼn”Aƒ~ÙUq)¢ã(§„H�+¨�#Õ™ eS§Ô@™®Æ­Œq\Ôù çÔ2·K)ˆqÅ’Vs4aLó„iF�©Þ{é‘*õ¹„A¡»q*a6 š·€×àÜSûLn¹Öæ~ÀŽõ¹0åŒ2Ïêîâœ:Í�½’êÔ¾Üà!"‘R–§¤ <ïÉO_døÑÅKé­£‹>gHw°ÝÆÕ0Ÿ¸ä71ð€¨U€­ZñÓ3êóFˆ²/ô©oS¬!�n@#�†Ï¤'ÖàÚ×K‹z�å|7¢ÁÆ]ŸÉ€ñíÚá’ЕҲmŸ'öo³àÿó£È¶_ˆú _[dŠÓÁû ÓäñæÍý•ñÖÍ€‡sªëýQÝ>{ë}ç‘z ãû4J Ú3ˆž8(èqê\nŽ/fŸ`X›=½ïê&à1ùЀ⒥ÝÛ2€ëõÜzß áÐ].èŠËÁ@ö(�0LOúîø™•=’3ê1Fõý[©>ë¯En<#½Í«kZ½G9÷¾Êœì�ìw6‚XŒN1™bÄÀhîcõýºÞ˜rrX‡ur%§Ô‰ú;nÞõõwineú7_JQ�i¬ÿÕgUa W6öÚk¯½öÚk¯?½µöÚk¯½öÚk¯½¾$µ,g¸è�n°±mà´Í#¦¦ô„)ªs.pβ>#6bBÎ@‰©$Ox<=àñá�§ÖuAÊ Ž.8V›â˜VØñðøˆeY@L¸¹¹U=8ÜÓ¹ÕÌ]–ÓkT•óùtR�òJh`‹˜&ÝlòÞ6{×E7^ÏççÓ Ëº §ÜûÞ1 ¤øËŠÓiÁù|²F}÷æš·AËT]—©¨ Û¥¨°müùj¿j€í4UË}1¨)i†ÍÙÑ´e·šêªflÎó„t<‚Y‰D„)LHœÔ.Ö;Û¸V×€&L¹þêÕ»xõòîî^àp8ÂÃaMÞ%}{5ûnÙ© ÙB7w•ôQsLGubµ„õfs­ØÜ²’‹ûÆêc»¾¾‘ÚmO� Á6œ} ïÌö_3µSÒÌêhÙ³5?¶ªl[¾ö¤²H6— ç{[I,ç3–õŒO?ù?ùÉOðÙ§Ÿât>ƒ˜0ÏG¼xùï½û>xÿ}¼¸»…÷jýœÏÈ)u{ðZ-s5# !CK‹ H¶×–¦D.’M�­àMUôÆU=]t<úìðÚ�bŒ8ŸÏxxxÐ×ZòŽþ{þ`¢÷øÎoýoo Àl9Ó`…ªXUÒ@QåľG€›º–È�I –Û[�ÌŠ˜Oë�ooñ�_úsø¥_þuÄñã}?øÁãO¾÷Çxxx³Áÿ·N_€ÿ)¹ò~~ý˜=’A¾Ð'#å"`š”è傃£ž÷-F8¨®’2 ô¹£êûŒœ=œ·ˆ#Ô¹±e—ÙîJ|¨@##g†'%Žxï0• #”h“c�Q$‹‘²êGÅ>·U…»6ö–¼r}€ ÐVëëôyàÿ… ē˾Ã#¤yÕ�¯ìÞ}ÀÕQbŽH*|-¨ÞÈ8•ÄpÑíþlÊ+ �}yëS0Ö¿‰`h?êE�NUÄŽÇN´�NIZSЪÍR‡\»w‚·þtãŒr}¢+ûO1vÆ5®·UíÎÕŽÜÖ¾™ó”  š ˆÂ~]ΗÍQ¨Ìóëº6PUçÐÒÀV·.Ãs\Iªêì#-®‚ÙkôÑ÷ÔTävÍ#_ CÝ*~×ctè"»�mýZIœ# š£A�ÇRŠ:× @µ�X<–:ÉÈ¿TÏO*yÂb‚o¤X€P¸˜‘Øüª¤S)Ïë±[ß  <€_ñŸÓ !’7D‚Ö§6íê@ÙK[/Wòîö¸O]'uÂgäƒê* äIuÂr _Av‘ïó[½W>·ø‚ªú Õ gu"É%kñ‘ÜAmM¡KX±¿£l�ºF¬«9Y¥ÜÖ Î1¼J€ awØk¯½öÚk¯Ÿ±ÚŸì{íµ×^{íµ×^_’ªy�\2(Gµuj ê½×ŒÎ¦ÊVУ!EÛ~æ­ÀÃÃËŠóé„7÷x|ó€ÇÓ ËrVµ“82åG @ÖͧózÆÃýN�x4{úª¶Z–UÎÐ\û ÈiÒ�Q)ˆkD\UÉâ‚Çt˜q˜ġÁ¼óðÁ�½V9fœìO8Ÿ¤AÐlÒa�“ ¦ë �.}“Ò;ê}^}ðp«eZ– �cÄjê\u%P…¹c†?Ì :4õ¦³ÜRM ÖÕðÒÀÿ¸*‰!¥ÔTßÌŒiV2C%e8ÑëŸBÀ|˜q8ps{‹C>âæÅï¾ÿ>^½û.^¼z…ÛÛºW¾dí¤¤ç”¬óNÕÄÜìÅ@©Ü-B¡Y´ÄÔÉ%¦¬×Íc눒ÕvÈ,ÍYíF5wúÒrÔTx�›…¨3e³îC–f#«Ö´±g ��G1²€w oýÌy‡àœæÍ:Vw‰œp:�qÿ>þøS|öé§xx|„ˆàf�·xõòÞ÷}¼zõ.ŽÇƒ’=Îúš,PrØ[lø“^£:ĤÿJQ”ØìÀ]·ìFSœiB²ÜâÜUÉÖv"‚u�8�q>ŸÕ„››Ã_ðßúÆþ7~ý·p÷Á×›ºôÍ ¼8[“fU÷—¦pV¦AUÄ B!†8’ boaÔ6¢»_|Á%<8O|ôÑ·ðÑGßDù‡Ÿ~üü臂Ÿüø‡øñÇ?ÂÃý#ˆ;Xë_¹8GUéª~ ȃ²Ù€QcÞ³t­= í¤Q²Q–�B›k’¨’–@ÀM¤Zí#1`ÌÊeËŒWOÿ¯ˆà0|ãëïá[ßü*þÌŸù*>üà]¥ˆ”Œ’#²�̧¡` ¾(˜Õ¾[›”ЏäR¾û·÷Óß!¢„BⳞsµŸ¯í¼GŽâň9¸P`×OµNÙ€…rªJGsÐ�#:�’{À4Ou0|¢$jD£œMñ¸®M•›`HЕØ=¾D]\˜;¨:ª+——sSñ’`x§íXãÛ˜}[#ç¬Ï/�oHí|ôuÛq“‹ÆSÕg¥ö¡ís¶¾N]bÌ-&œ—3ÖUã§Rêäç<Â0O“ w˜`¯½öÚk¯½~–j²ïµ×^{íµ×^{}IÊ9Ö�¯œ� dâ XI@®ƒaj7.f;9f`ê†Ï~øCœN'<><àáþŸ½y�Çû{UÛ— �ª>§p¸9âX(N7 —uÁº,ˆ)ªÅ;Àcn–’úY¤*vïÛ&g)¢›Œ%#”�ndËa¯»ÁòX«R=æ„uYñø¨®ÉÔKŽì°® Ôj»NP為q5M“÷ ÖϨ÷D:³m®©…»ægª2Ƈ€©Ì Ã„Ù{LÓlV˜¾�ÿ"ª‚¯ªªk¹÷µTÍp¾Æ1E¸µ«‹|8�xùÎ;9@ÀíËøàÃðΫwq{{‡9@’$Å|A¢ªEGš1^7e}SÒ«5|2ez*5Ë[šs„wl¤%–8»FHF*‚’ÔÞ?ES¥„”c‹R¨–ÙDª;˜çÉ,D';i›™ºÙÉÚw@À¥ š 0ò&LóŒ)xu5(ëºâ¼ª…þg¯ïñæÍgx<��SB˜&7xùâ%Þ}ç=¼|çnoo�°²¨«Åº"ƨ±E†-hR+Ñë�1¶¾!"šîÙÈ%F&5ð�™6Ñ—˵¬ëŠe9·œáw_½|%"ÿ3Øn¸ˆàݯÿ¾ò˪÷È3~rÞ9`žlsÙa1\¸jÊ^7„Õ>\D@5¯÷R]û¤jV€¢žòï¼ûÞy÷]|çW~ a9Ÿðãÿüc|üñÇøäãáõýýFMׯ)ƒ‚‹ eíËٲ͙*XC r©jönÏ;‚» Ë<.€05‹àòD ×¯Ó Ž;©Ei›ñí>+ƹ¢YŽç™" äÁ' êp»g1EÃÃyT€€hyÒ]Dt¬HwP�ù:¬+Ïu³g»à@,�ëNüo{;mÿïééÛÿ« Ÿžh¼ éQÕûÚ±®ãÿý`ecB ÞWÅ>¡&®P³³�}Þ„ƒ(…mMv`x<çBMUýb£VÅü—/ó°ýåËð…ë­¯§·þ(Åø‚¬ÎËÙÈ3d.QÝ9#Æõ"îO£€6—Ò€Þ–e3êºÛ QOB˜ ,W7¬uYÚ8­Šõ:f¯Žé–MßÙÑ•j´ä¿œ .­ì/­û‰~ ùF¨.I['�J>¬í“rÍ�¿°Ž/5²¨ÎÞÑ€­}ÚœFž;}Õ(¬ásJñ€¤ö Wâ9Uã³ôÒ¸µãå½Áùí³Oìúëg×kÞ8%Ø}sÌ›c�€ùåú H6fÕå€Ý¥Û‘9yržz²ó‰àDp<ðâàìSûƒ’K}`äì7ýƒÙÛ¥Ç+cD2KñÑù�ÿè�ððð€7oÞàÍ›×xóæ N��È9™z(`žgÜoèæqð0µrW°L|ÀñæÓ<Á7P\.6Ìkˆ¨î#– %VS\9ç¼g% PT°¢d$#¬Ë¢ •�+ºQå;€fÙ¯óáôøˆu]�s1cž'ÜÜÜàîö·w·8Ì0rJXÏ N§Nçssih¶Ì-ƒ\�³¨ÍøcBNÎ鯫'oÊ7ßÔ¼£Â¿’0rVûÿº)¬Á ¬ë‚eY›jÀÿÀ7êÈ™n^à[éŸW»uŠS1ðî�_xŸìÞ�hlÊý ¾dpî€;Ú�fsWd;§ô'@zf2â}im½¼Ç|ó›¿€o~ó¡puÁrzÄ�ô}üè'?Á'ÿoîïñxÿˆóz±³zÁ*¢ kÀ;8ªkw³60¾X_'¶”  ˜bºªÎk¿Ò9ð\ï-©2¾²�]=&Á9ÐdcG”34­"�™ðêå>xï¾úµ÷ñµ¯~€¯|å}¼óâÆÈ,+R\‘rD‘'ÅÜÆÚ­é ̵ßs•Û_‚› X¿nŸÜnDû·kœÍ^|ý½?xó¿,gbDp.$’jql ˆ(ȵÄ".šRµHDZqi0PºYŽ_ñ—á¬E† ²³5<Ú{®ØõðŠ�óˆ�9¤´U�:¦ÐˆÜŸIÔ38«òRUæ¥=“*�®:a‹#È"jôzfd§q4©©Œ•UJV»gV²ZJÉœæh^ž£‚A9%UÜ–¢¤»ïD¬†U½œë¼¬}-𤢩óD¯w¢F'Qàúmºú-6l�Q ¿‘Ù?§þÛI›�/ãYÆ\zz&[¾Ž/¡Nº´h"yN­~Ù…esÍTÁtºH=¨kŸ‹x”ú”íÊ\^dd{Mo2¹z.Õ)âÙ&®ë-Ù^3ÉÛI_¤d¸íÛÛö ãO_÷yF`"G6BˆhY©Ä™ö¯­ÿ’©×ŸæËë‰-Z›ûêr©´×ßw°SI)Fä¬Ïês)à 5'ª(·ué8÷$ä|áÀ}^Õ(–NDƒ àRí~á(P?×9ßݯð$ŒÀÿHL?m Vlé €Fqyû<7�æìyfÙõüùâʰޫ$[û$½NÆÈ‹Nš©EÝ™gèVm.uƒ“Miß×ëçܧöý qÒð‘|1Þ%7T�^I‹z¹ŠÅ·ŒmZ] j¿Ë™P§fï*)aKVl‘Öï+AÁ{×cÐ H¹’@õÙ\ûÖH4«÷YÛ+¶ÿ^]ƒÖ14ªÓ™wý8{íµ×^{íµ×ÏF퀽öÚk¯½öÚk¯/IÝÞÝâ|vàuAÌ’û&–Úà«:Ú97¨žTÙ¼® BÒ6‘¾ÿýïãááoÞ¼Áý›7¸x0kþ‚àÇ#‚àRšš]$L\éØƒ'Ë®ôŒyšp81Ï3Ø ¡(€Ñ@ ”–‹ ³¼gªŠ�ÏIä.âµ^oY¥ ¤€¬xû ª­ƒ�ÿ‡ù€išlSï€fLsPõ¶Ó¯e9aY¤ÑÌvJ„uã­)cl#¬: ˆ¨eg³£M¹Ýƒ¦¢q¹„¶ÉDH)áññ„R N§ÎwòD^¾ÔÈ?y�GÜÜÞÂU¯ÆQ¢ª_óš�cµm­`ѰyØ[²©§ó°N`pÝ䬯˹7ÀºæÄF»§u]ª-4hÈ­õf—}80…©ÙÏæ”ÔÚ:Æf‹¯¤b`õhÙ L¶é©ŠÉ¼}åLȤ–ßKŒXLÉ_,¿Üù€i>àxsƒyîÊë´®8/ îððxRð=®¨³Å9xSø–²iyJ0P%±Ó4ašÕÝ@ 8_ò4¨Æôž”l¸ª´ºAÿÎË»ÿ‚ˆüçÛ{˜ñ ÿø_�›È2P €?ùŒ#‚F6ë{›ZsåÅÚ•GŹ‘>ÄU»uÓª\v€¤áÅc”äši]\ï \#óሯôóøÚG߸øàáñ¯?{�O>ý ~òãâãÿ8/ žÆ´ؤŽ" fœ oãÉ9nÚ 0!'½wº!îÚHFÆ èks¦f-ì<ãÝWwxïýx÷�—¸½Õþsœ=އÛ[�ÛC`a†0{SùsHP ·ç˜[–5±N¤Ši€‰¦R–Íèíÿn“*jˆÂx¸á}Ýzÿ´”åw~ÿõ²Hcœt˜‚½•€Þ¢+Ö:Ø¡Ê3XÛæFžaSÄ0 �b6Džö-ç<zæs‹�0†bd£Ò� ükŽ2KÙ¨7�n ›rœ ª-v}Æ ›4WAŒ�R€R3µ ¬'ȱ=¸�½ n±RÙPãÌF'ƒžgß]eÄ‘Yãó'-6r(•mL�k¶Ä‹ÑÍ ¶ãØ~Ì ®T5 ÏŠÞn—$€zìJZ¨mF�2D?éš±éÄBë?OFÇæ^ap©|àF’«äçm=$�ˆ«ÇÑ…Z%DÔ¾”RÚDg¨ Uwñª÷®:T\:*ìµ×^{íµ×^?;µöÚk¯½öÚk¯½¾$õâÅ „àq:{¸eE1ÒÝtT›sͦoù� !€–b@pÞ�¥à“O>Áããpÿ€e9£©À»q÷šZn¼$iBž=È© Ò͈<ÌÌÓ ÏÞ¬�%¿0  •\RzFn#µ ÿyžš“„*ü‹¶ú0­T“)ª@í£Óä0OþçEä8Žý�~ýÇ݇jÀ ‹GÈÈÅ!fàw?~íC Á‰Cq΂BR¸�óbï¥alÛ 4«#ׄ�\>ofÚøôkæáâÛkÊ“÷xïñê�÷ðê�÷ð��¾�¤²Y@^�Àù´`=/8/�xxxÀÃÃ<<Üã|:!KAIb›á¹ÖuAŒK<ã|>›“à|ÀÝݦ0áp8bš<;°#xWÀ(˜&ÆáÀ<#L3ØMÊuÈu‘ã1>ªŠ¼ E1Èy�HqÍQ#À}`~ù;T`ÐX­qåf»„Ì6ªdsÕ;ð©cŸýîwþ%&: S$¢ÌĆNóŒË;Wçò êTå1³‡’Ô½€�Ào ª`E+H”ü%…µ}è"Ø]¶ŸBh¿¨Ñ¥ddÉmþ(è ~ULVŽ:®šuû•ø€šsœ]ºÒâ=ˆôyIE!ZEŸ�…:È#ÀbA¼wÍÚѵX‹ê~²®ëFÍ[çwnϦÒÀ2H˜P¤`�+r–8Åd d½gD-7ž ›'=;Ÿš5ý6,~3zÅâžj³¯I˯áÜb¨°@„Æî÷,¶Ž«={û 2ü_#ž4°Ü ƒú|c�nî#¥¡Ÿª 6Ý=ßœžœÎÛTí4ˆ�Rø¢­ÍžX³ã2’‘ä#W&V\ãnlÏ«*þi{ú_ ¾“ç*øÜ»õ…=�arݾª¦‡ûûFþ<À›ˆà˜“CN¹Ê:Þó“|ö§Šnyb·ï|†3ðÔ[ @UuWÇ�”ÔË‘£º.5~]÷ .¹X_}ÚJ}¼Èf~(æÚ4ÎcuÎb*ûs`í¥õ}�G�wÛ¶©]½èº±Fjµóc];{v`Òõ´·µ7�Tùž23<ÐÀgÇJ–¬±=J­¤¥Ô®ÈFØ(ÈÄpŒfs¯¿nT—6v]#´x6»ûÒUì5Ƨ+Øx笿°@ož§ ‚—'Î cßiDlûŒ£“Í�ªÍ+ÜI ÕáA.œÐræö7Jökdˆóýó¸}fï[Û¾Îíï¢ýP `kÏJzë÷!7²Q»æ‚vü\ ˆòþù^{íµ×^{ý ÕNØk¯½öÚk¯½öú’Ô�e–;çUa,ï¦iÖœu#ÄU7�šíe® ¹PÅÈr>a]Ę´pjaê½Wëÿ›#ŽÇ#æÃÎ{U?PVH7¬Ù@u¦0©ÍŸp:ŸãŠlÊï<ÈS·^÷n³íŒ\ Vþ ){U{åÒÄïtŸ§¹å§;Rû⼩ɳnl¦‚eY¹)oœ9hDBz�ËB`V`[ïƒÙofžÖum–õ1öH…yžq{w‡w/ð2LSÀÑ,ôU¹%Íî^²@ꦰ!µì€Ô”æ¦ÞÝjgσ¦mc¹Y«!9ÍdW4BL-›LÅTšâŸLÙå{ãR’Z¶ˆ‚”8‘ú›‚/6W»M{.i؈6ç‹]TíššZi…敾yxÀ›û{<<>bY�õg%SLÓ¬Àšq�x”G”œq^Îx<=b]Î…›3‰ÚÞ%KßÀ%Bpš§Zm¼§iBÝþ_l£ÚyF�Ù”éU¡—RBŒNû€õï=¤$ð?ðªöã~„?óç~ `‚d�ÔàBªnw”þî ¾ó>crlcÀ�X€Â ÊÍÕ�”ñqÎ*’kģ̂^c$ªè&  ŒÀ~סwÛozkþ3V :wˆw̯õ¸½ ¸¹¹…ÈKHŽHiENq›EÌ켊§%£¤1/(ñ¬`/j{¹"‘ É9GätFŒgHŠ*Îw`’a⢆ 没óEµ:çF )O¤ÏÒ�~ÐArU[‚J>ÑÁJ›Dï'ï’AU/•f±�Öøüæ”þ»ð½Ó3»‚HDÅ1‹gí;ó4 À¢Yí#›K²q‰-Ár ÏjßÀ¦F<0Xj·¹¼åyçØæs²y)ÕK´¾\mœ™Íí„á\кúÕšÒuÌ·&”²‚Ò”)æ” vÓÜ#(ŒìPçqAiõ½3ašgøRJP0,'ÄÔUúõò ê%xrö¬õ ª€N)Uå�bþÒ�=r^”øªvçJ” !œ«@ÓÔ?Cx*íÚëdËY¹â°}Ýåû;0=2bä*Ò<ªã«…öø*jÑ4„]Ôñ"m>6st•®4› ¤�~-4å €\UUÑtqÂàROè´Êk "ýž>¹/õódPŒ_!U '#\¾ûÙzÛh\¿‡ÛÏ¥Ï{ó3o£ rmrË9ß@l�ÁÃ㣒MÁ|ssl–ï!L ìÍ.+3óf É3Ï£¸íÄ�ñhNó<µøžu�ö}Ôq]²�5u?ð|}[ÓÐ`sÚF¨ˆÈ¿é¿ÝeK` B&°ÜÏDæ@DàRÌ�ÊÈ©¹ òªÑP)!çÒòâ5%H N³ýwºfª®)F7Aà�´vÞ)É’•PSÂ#ÒJ6f#|™u)¬W"�¶T)„œ¥Í�º¾.ö9:‡Q‹Tàâ6÷`ŒÐh¦ÔˆcÄs}¥G.¸±PÛ³’%ÚüÞˆ£®‘eû}ªîD¥°¹2¸ÔhÚD%è”Î�ä@Ýe(—7Ð !ƒ£÷H«h€ç£0ºCE;~N ¨ŽJ{íµ×^{íµ×ÏN퀽öÚk¯½öÚk¯/IÍa2Ëñ€ÕU•ˆ‚ÙÓ4ašÔf�™†ìFU˰c8Ñ�ÑÉìÊë&•3°bÂŒ|SL�G�LÓa ˜|ØØHPàÍ«êGŠå¬¦¤à«r¤ªµ€Šõ©r¥YræŒDÀ²¬aÁÃÅ bµÈ?GµåWUà]¹ Îéf«÷Îyýꦛ©1sNˆk„wq�›üJUá§¶Y¼‡ÌG°S¥}˜&¬ËŠu]Ì ¦8_áÏJÄ`¯ÀßDS#” ×·Ïiª ®– b\ñøð€ÇÓI7L™qssTûïq{{@�éLm›³‚ÞëY3ha÷‘©oêV¥}�ÔëÝDEQà•›(«ú^Îäácu³Ë.¹E0è½Tò±nºï�²C)º®›ÁÅú©¶[°>Ô”NÞÁ?€[™rSöWGŠÌŒ52 ®QIiEN§å„ûûG¼yó�ˆ1i&·›àŒÌ2ÙØI%aYÄQ¢ÖuENys\Ï17›óÐ4sÕúÝ4Í!À{Ѩ6¬ª=lú[Û0vºaÎÌX–µÞü×ü3õõÎüÒ?ñWt, Gªì·ö+YÁÙóÊø›BøÍoØçé¦qPóð `er@.d’Úxv}“x�x{ÉU�o« ½¦5kßf5OÈí3UñÆp½?‚a>fØoŸg |=à #2ÔH‰-,îLa/¤y½ Ù5¸Ú×ÛŽûpø… )EÂZþ™&êN›v’jÛßó¿{ QOqÀäIxê$Ð|ü/lÌÍž(ˆQþµÿð?~üWØñ™3G ‰fÓë¹ûAA_pµ€(0  pê˜äàÆ2(›¹ž,‰ΦÄ&ÉçÃ’¦o5—Á$"›¿¼sÈÊ6Ú¼Ï YصrΈ¬ùÛ[µom«<Þ*Ô[¯×Å BµÛ)�LV²HÐÔ©jËœkquŽ]-ždYÔ�¢ ®"€’·œw(Ä+0— H*Eçʤ�íèAÀ–G]çïœxïR½W½¿|^m$°æ£2Ÿ.ìàå5·<96�ø¸°´¯–ø2þîÒ`ø\‘þ±�åFI6““4âÀV ¾UÍ�À{¿,©ctC:®¼½Woã9ÐBÛ8‚ñ…ƒ�ãY 4Ú~ô5À+3÷çôÏð7..‰jÒ¥S‚|�'È[‹‹Íɹ,ËÙ¢ƒºbùfˆ÷afsâ!"$ªãzkáþ6¥|†³)¯»%»÷Ó,ˆqÒµ€=ß«ª:™åûv\óy�ø¨"•DR×]�ZWIE"‹=žÞÇ"ꤤkÿ¼©iX/aãP0V%'±ãFtÔU)e}î:fH pì” FJX"¨[ŠÅ(ˆÀ�â=B�NÖ5²qôn�`"D"Ę‘3l~Ó¹™/œ«à´®ÕÚH´¨‡Ñ²¾ SÎÏöÿú÷‚¶UÙFïmÝ@1 •Ìé½oÎ]µ-Ó¨®7‚Ù9zsÅê‘z& Ào¯µ÷×êÀ @Ÿ ¯××ÔâzÄHÝm¿YŽH�T>£~îèÔUÛ j[íµ×^{íµ×^?;µöÚk¯½öÚk¯½¾, 3ß7΂÷jOŸÕê<„Ð,ÖëQÍeR0�‰¦€y>`žg�™1… !|ð˜Ü�˜çYíüçIUU¦¦tì0ZD-�«2.¦¨ ÔˆWbA‘­õ*³ƒ÷NUU(H¦¬.¥ Å‹YvfàBH7ÓÖ¸ EUûzÇÎlG½Gj�ÏÌ9b\ x³kU›xnªî¬ uÉjŸŸÕ~”�Ç<;„É#—ó±N Nç Öò9‚(1+íltÃ9p0"AØÜ»qÃ�-îÖuÅãéo^¿AŒì%gp{{×òA‰TY ²h›¤›{™ÂÜ{ß”³Uyéî\X3Û½SpN ²)ÙJ)¶�)}Ðbr©¶Ø‘ƒ†LQQpÙg�œrNúžRPÖ)eÄèàý ç‚:J˜Ò9L¡o(v[”Aõ¤ª´ˆ´®X–Úï—uÅéôˆûÇG<<;f�=A õÙ^£Dœcé¼å2#%6�2×¥uÇ &�˜³ˆ¹ 8‡i>œí2 Äô4°¾ÚÓ[[SÅs‡7wp¾¾K‰ §í{vØ×>צþÁÒ~Tçã-Ç33� `3ð.�!»o„–6¦·4œç<íÇîM—1ÏÌrÏÍ£„kW¿u70x}ô#h·J¦Ùœ÷ç¹7à"2äóê €ÿ*ä§/ø¦ñÞ©oÃsjëRòM‘B€PNº–‹’º €­ïnïîp< ôt«{=N·Éùç6€¢R¸;t°Ãä�8ÍaB˜&x#êçÈ¢ä¥=|±9Ç x¬ÿp­ÉÈT¥(Ù©#,d%ìéyÉÖÀcPÿ—Rž4Ç^çöÄþ Í=«gÚ«S 3#§ ç–vrÖë§ñZÊwÜ’(rÎH"@Œp)6p¼”ó x#�2¹Í¥ÑŠ�”‹³Ì!ÌÜ Ôó„‡ëâ�)B)4�ì꺴Ûâë�Á…Í ¥+ýÇgÁ5bÈŒWâ„÷ÁÈÞ®k$6—Ö?ë³Á7¢€GÎi÷û½¤�œ[ïGÿê2âÁžïEÕÿ9ÇF¨cŸ¹À¹mdÄe÷¯q>—µÿ_¶Í^{íµ×^{íõ3¶Ï¼7Á^{íµ×^{íµ×—£ˆœ˜s³%N1¶ÍÁº‰E„– ¨úȇ"àp8àx8bšg*àpÞãp¼ÅÝí noop8¨¢*˜õ¿‚:hÊh1à<«»nå‚ì |.f¿ÜU,5›~¢ÉÔ;(êFXÑÍEZ£Zô»®êy©ÖÍ¢ ÿäá\0W‚ >( €ˆ”°FœSÀÇnÑÊ̈nmÊ&fU´Ç›C3ƒ�8€@ÈSƺNð>àä±.YT “ŠÚœ®1¯‹Þ“ª‚e6ð‡šâ]-:‹º8=¯¸®8�Nx||DJ±©£V³ñ,Ãfœ#!ÑlzSþU ÑjãÎN³ÃÙ¬±�¾‘MP91ÃuL#+I ®gäR´m æ d�b¤Œ®4¤Þ³#ëçSÅÆ5"¥3bŒXcF¶œmÍÓö>˜cE€S#´øàW�è–Àg=FÎE£ Šæ_óÃ=–3#æ„ó²àáñçÓ ËQ2¼ûx¼ÃÍqÆ4ÏS€3 0¦Œ’rUJ•ŒQ‘(¦\mÏsüŸ0ÏA7|Myœsi¯7QëF±:%�¶o0§�bÍÜ8þÇ^Ô{öþ7~_ûÕßl ¸P'45ªIÊ «#ü¿ÿÀá/ÿŠàè”ÌP˜àà�òeÃÒí©³mƒ;!úLP¦ÉsUáúÍ%8½�Ï~ ýçç¨Á-çöR:[Œ_`ÖòÝK™üÅÙ0@EŒ´q±fzþÚÛ?´»°fºÍ7* ‚{å"÷¾�~Ú¨Íj\Äìï :Ä{­éd` ôr"üÞëÇ»ññ|ÿ1­ÐL‡So§ÉÉ¡€L�|— " ©�3-^‚Ê%òx’£Ây‘eL;—nã®s÷ bßlŒ#H2*e·*æ'ùØL@%q Î#ÝV¿\ÉtsÒ1°eˆïPGu¹É¼ôÛ¸yÞN˜¦¹Ó‚#)(¥ ÑìšSwãqNçB¯âÁÀ{'‚ÌD † +ùoŒ~0u(Œ,–b;3 3Ë<ϧ혤«c¯’Ôú°7<ïP�ÜNx~HÓÅé÷ ¯øÏÏ£+áisï·Nô4ø"rüïqOèÊé×'ïØŠôÌÙm[ºÏIÃçÓpû.?ÿªŒŸ6©*ô¶—^™ó6® o!Tà ÿ†6mLÔ#:ðEæþFÜ�öÞ+å€b€êJDŸµ¦´O y ™Þ�ðÞ�ÙF�ÖâÊFýùlç� !DЀƹLJ`c|A4G-A'$mß³nKÎME*Õkx ÈŒRì¿sŸÛIŠ&ÐÔñþlÄæzGG‚ú3ï}‹6¨Êw‘‚H„œ=Âì5½£V¢ŠH%ÀQ𥘫VRB)­„Õi4Cuåš‚y²¿?Ș:™Ñ@ý""Y—¹€�Q˜ÕÕh°¥¯jf—¢ó·g^‹EȃÓÊA6ý—àÿæ3å]Ó33¦)˜”lý•�’ÚÞˆ'FP×(�{ @‹Óãs*YĈ´•P�a.%r*�ü!Åþ&¸P÷oú<««ÒeÖ P‚…JɈqÝÿßk¯½öÚk¯ŸÁÚ {íµ×^{íµ×^_’"0)��f ™ËŠ”,ÿ‘*ð½6ëõªPöÎáæxƒ›Û[LÓɦh!`3n�ÜÝÝáîîÇãSP{s¢–<¨£ ¢‹jËŸ N)"‹æuzŸ,3˜u2Á¹ÐT÷Ñ[Ngtêd`„…œRQðŸÚ†((pÁ#FpÞO“‚É °²BhY-YÇ ÝjÇYÌFÙE_©ª¢L�XnÖìÁ›åþ,ðS³æœúp²ÜqiD‚3ÖE B¢›¦¬«Oß-_Û&䢀¹fÙ¯t'í»�¶3ëVµ'0yÌ¡ †II"ȱ«ícNùÀE²i”‡MhvÙ@µÿDä5"FË¢g¨‰àìšX]Ð7WÙiìApl 2@‰'Þ9,‹e¸Æ1êf( Íþþp<8ÂùNæ8#—Ä5b9¯Xgœ—qY¿,g¤¼ ä‚eYp2Eí²¬zÞ~6ÀŒÛÛÜÞÝa «ÚºnbvûÓîhP%•%‹å{׬nµO׌a�yšïí\‹8ˆ1b],KÜ€yºá«ž»žƒ)— €ª­œ÷(¥à�þð»ÿeÿ©ÚgÝ4ã;¿õ/t _{…¢Õ¢·!¿KàXð†þ½ßsø'‘1™ûG!À9´6”*™m¶ø*õ—lV뮀ämöÿÝ®þʶ²ýËí¿7Yï#Žjgì†ã¾}lóPúÛñŠâßE-ùA|ãvZÝĽ Jeà­‰¶_HñVž9_ºh—õÃAžû2´ïhOÞoÜ3·£¹Øu�%—üÎ)½ü/�ÖÛ?î«ú1<…;G5vƒ•GZÔKÏkî ™‚©=³@¨GˆW�ÒÀüJž(#(iÇ[–쪊�4žb¼¯Ã95õ«�Æ]‘¯_Îùöž xIíyVI8#�g« ¯6×Î\uªKBÎQ9çÂà§ ÎO`GÚN¥4»èi HQc|ˆÕÚ�t>7Ûf<3fçAÎ)‚ˆ3À k$HŒHõœK1âT]ëìœxç$¸ Ó4½½ìøiPš^Zß?#ˆo$�-釞|·QêÓÈaèý½ÞGÙèôÀWç�av çgŽ‹³è”ü¿$l/PÙÿK0(ôÛH"éä„ Åy Å94ÂØª´½îž¤²m„®¼ßýtqê¯\Æ{vñyŸŸÌñdŠ£«sÒsS:]̆´e"]œ°ärÊ9Ѻ®äœS•³}–¹Ç\8¼ï–ì!È0ôm12XQÔ÷t'n‘SPG­ §œZ$À5g‘±4wž� �Š9”°)ÔiPãç<œ‡@Zl@¿çÕåÃ5 ¿ƒÚã¦à|jk¸JNtÞµµfs"àžkï¼®‹‰É¢¤hˆãF·Úç07Uz.Et2yu#GŸ °.J¬¬ë)Åž�Lìrš`ãzÖÿ]9_ õXìÜörqßG¢@n¸±åôR#T=�™°,«­ëW»ÏÚÖJ�Ú}ª÷&%í µ­Çû—KANÅÖ‹n˜®©=·4Þ¢lbª ‹6_ÕNÛaÛïËE©ÏÃ<Œ±kd‚½öÚk¯½öÚëOw퀽öÚk¯½öÚk¯/Iu‹Ø^%ëæQʱçL‹°m .4Û~žgŽGon0O–Ljâ²fzÚfVðSÿ >Ý,2U©ª”Ðóº¹Õ3PsÎÈÈÈ¥ ” 2©s�wÞ€gµÒ¥ ú¿¬XÙaY„.%iÂ6eP¡nµ‚^I Á×È×”® Ê~³©GËÚì?«B''nª¨jW_-ZmkPóÖÙc¶MQvŒ½¹.˜%<14R½`]—–Ì7[Õžkêx5CµæÀBMOª:Ì3¦iÆ<©ó€ª¤ÌFÞ10M8ÞA¬›ygœ‘—ÕTWº!îˆ�ð`çi¹!è¿Uÿ« >"§U£ÌˆBðì°Ú:!4Å? mìX7A�÷ðÁÃ;UÛoŠvË£eöÔÂVã*’m|Âlñ=æi¦ÃAã²:#œÏ O'œ±,',ËŠœ"Ö5Ø~ÆãYžb±Ç�4›3ŽÇÜï0Mzþº™näÛÀÏ)võ¬tÓ³ Hn±usÖ{gýOïIÊ‚#N§N§ÎçÞ×Ôå`Ú ÂJV± @ðÝßÿ½¯ø—ÆqýËéŸÃáæ®Sšò¬@cç4kë˜ÔÀþGÀÿó÷€ßú6ard¤Ûì-ÙSSK†0!# Þå­*QpWülûi-cå™ï/�ë€ î7ElUJÒxF$‚µcWãË[>n”¶*@ƒáö ©³Æ ›k¯'TU=ÎÕŽª :›m¿#yÞþTý�?T‰*Œœå?ü“á¿r÷òÅi� ŠH­N‘í3E1 �†ŽÖ¸–ª”¢d° åŒâ²e?«ª±v¡‚É¢1 2‚½Uí]ð_Õþ§óIÉ\„rÕÙöUղЅ‰$)É+ÛóÉÙócTýV0‡ï�blÙÆ�0€xÅ"3j,œø0)щ”§ÏªÙ"NŒt”+(¦„-b‹ñ ó¬ÊáÕ>g]׿x q:ïNSû`êÿˆbÏÛ’ ¨ª‰Í1†�p7O³ ì¼°gyï½÷®³�ôQ­ÜGKˆž9O[Ÿ~¢«®[ûà5@—JeAÇ’¤½¼Œ}ãr�Ž$Õ$ãÉ(ºœrªzvÃB¸p£xKJÅÕhL&¨€ð–ú@¸Ú:ÖŽmî~VY/Ãí¡Ÿn&œbš›ž¶õµS»vùBØÎýŸ›½å2 æíÓýÅ�.y—Sâ#­ËB£š<§¬DWÈ&—Ý9×â/*�«àjäÓ§�+wv EèÜ—ržÜE�³³Í%„˜’9üŒ~B)º­Êc4ÿ�ŠÆC�.äz ³ò›C†ñ¡®SÜâGêWÿ›A¥9†H¥ÒÎ/'·‰(¿Ô’¾; dÊplħó±’C%[˔҈@Ÿvñö÷ƒF$ˆsðt½X"9Wâ‚ –ù®;Ã\º¸Q#׈ˆ�ØUï÷¨´ßÎOûßèPŸ~|&qWò§´bYW,Ë«W;èÞÛPãú¹Õ£+ä"Ò¡þl<—qš­îH4dút‚ cŒúá+1JŠ¶Ø®<¶uiç©Î?å‹�ë½öÚk¯½öÚëOM퀽öÚk¯½öÚk¯/I�¹Ž9¤\4ó1F¬«‚çªé–äuãÈjäyRp_& ¥Z¿‹ äd›ª©mDÕ�A­'ÍΜ�m²š“ÀVñt4«ô Ú×rç<˜Ä+ä’�… Ù”ŒNw¤½mìNaÆ<‚*nF࿪a6øÄ„Yæ¾uãöéæZ6…MFqCf+*æ' &LÁÃñÓ!´�ÍbÄ�ª<�9K¿_3ÍE%Bñ¥&º kÀñpãx{ƒ/_àæF#œ÷vU¢–¨pÞAæIAŸ”±ÆE²õ�|Õö1%¨*õmòÔÍØœ!99¡¤ á!E‡´®È®n ;ëÜÀ7þÿ²÷o±¶léyöýãRUs­µ÷é Ùì¦x¿4/"EQ´˶¨‹‘%ì�ȃƒ<yJ‚<~1Ä‚ FòÀä;F ÃIY¡ìD‘))”H‰Ín6»Ù¼5»Éf÷Þk­YUcŒÿÏÃÿ�Q£æœkŸ#Iêo¬Þû¬=gͪQcŒs|7çáƒk 2rÄ„À±Œ(£nΧ˜ Hß63SJHëŠu�ºiAÓ4©j½0–uÁéyÆóøˆÇÇo�èÏÏ eÍF8c]fä%¡0#xjö¼Cðˆƒæ³è"àœ½Gr9¬HyÕ<ï²6•XÉÅòTUõGNcè6q·Íýœ–%až<==c±M_çÜ� –é]ï;ÛñÍùâßð‰Ú7?õ}?†OÿðOA¸0Å]n·"ЄçîÄX,@.X€¯ø�ÝãŸú`2ؾ…ÀÐñs‰ À;UлÏn³å}W½ Ÿ§øú›/QW»2û¹A.èß'-dà¾È;àwÚ›¼d7Þ8Ô%qßÊß|¹«ò·ÆP‹—¸m*~}1æŽ ôÎëmV©‚px>çÿÃßú;¿÷ßûôwþÀ7^c†HÒ‰RÜ@$6º‡º|¨šµ^s$aË @ó¥}~�r¶üæ�¡<“b§x©¸Þ,ì›u¸‘ ÖuÖgGs`%�à D-q¾[“1 r)êàÁöÛÝß«9�ìeŸŸ¼G®Î0= `Gx0r†±È+�‰YAýê¶£Ž1úß…õ\JN:¯¹Èy×ÈAµ¬)ADIu@WW‡{9a@hÁ!µî¢JQ©9çöûa˜Ô€É‡¬f âv 0U§‡MfN7zÜÖÝUáÞìn*Ê/2çiC¼i4o¤Å¦ø¿ lnᣞGëÿBÝop*Ë #¨ÿkß»÷uNɲªlÄÆ¦¼H{K¿xS# ¼`gp¡—甼�Æ�÷yݼ׻ß]8¼hð~þÿïÃb¸üg9¥”hžg7/ �NS;ŸäR#,ëŠççs¦͸¯ë-"µOçÂñW÷¥âšõ>jâ¼^;,'¾ÞQG£a˜ŒÌè±.‹FJñÞ–R�SFˆAǰ˩ß�­Fê²Øñ¿vÀ<º¬vÚƒÔÁ¢§6 ùÍúž»CsIJuO.nsBÉ1vg4êÊ{#~z#[\[ÒëœTvϪ:~›ÃÁ0ÂÇÐÜ\pðð%‚=ƒ�®³Õ-«>oΗFT"ì�Zê5×¶/ÅÖ¹"í;LÐ/¿\ö÷vÍn#ôöàÿv½Jx]ÖóùŒyž±¦Õ”ýÎú] „¸EÉ”‚P×øÕæóR”Ì–Ks˜Ø?¿ÜÕwšzŸ0w†Í‚\ÿ¯#)jÞÍQrë§¼LH<ꨣŽ:ꨣþÈÖA8ꨣŽ:ꨣŽú�gny«U©¬YÂ+ÖTm䋆– \ðp>ÂÝ€òêŽãrªwNUáªf~V¥õ0 xµ=w^•Þqðj oçDÞÁýñÉ!wVÊP¼C @š»<ÄάÓ@Lž3’KÈØVý¦¼ƒÙc:ßÀ}_Ëú„f´«B'vÙ°Õµ`S 1RÎÈfQO™P\ÝtSõP¯n�!` £ô5kRFJ+ra¬œ6唣þ;ç!^@yÛÞvN�N§bPëèûû;¼zx�‡ûÄa„@æË<ëFç(¶‘¬>ð %Ìó‚ç§',ËA æè`µ1B•q!"x�TÕf"  \€B„œrZ�¢7»UjJ/×E{@¦¢"Á”Èe„Ü™2/x¤u±Üël›Ÿºa:ÌgÌã€a1MbpƒÇ8Œ˜† 㢃³v眠IÀ pÙÞÇv$ð‹Í˸% 0Gäa@N‹nÒ.gÌ3›�ÿŠuY�K•—† ÊÿË|Ô”J³þŸç˲`Y0—�]luZhÎ:>RJøÒ¯ÿÚ¿à_¨ÇNwøñŸû‹DÈÎÃqišuµ”æ.yºGÝ4·<3¢ãíëüõÏ{üéï>6©í+ à< àœZ–µ4ëvÛð§÷Ûà­ÑÝë\¯S½ðêÞÕ?ŠÇt­w½¾Sö·ÜfU$2_ÛìëÜ/ÐöànŒR€IÒ”sîâÔ\¯Ý݃«W×RI×gwSL·I•ð ê�<ýÞמþµÿõ¿û‹ÿ«ïý®ï~þÌwbæU˜K¯’DÍ&®9ÞV9ó"0óýxç,ÞÅC$.­Åªª´_/QÐ^/€}Ì�´óй´o!!�Ïê¤A^s²�Óè•Þ°¢f?saˆ—+ughVÊzq!$ŸTÉj¿Í¦Þ¬ã]˜!¥€«ŒR¬M¢yuQðf« P#é]y2ee±œp‡8 ;Eéy>c]Vä’u)™™uŽ¿ç‚moæ¦,Ý9߈1HT»é±}Æý®‰t#’Þ=Ôz·�Šé7E»tN%—7XÚ¹52ÐrÖ÷Q/ º5#P#îÈAô®Ù£ËNy×¬ÔÆÕ�YŒ^fGÉ‹óÞh׳@ݼg2\Î Ü�©ËuÓ;Ú5Û­ú€WS]ä%2Õ݉Þw†æ°, �Ï3Íç3}û·GSR/óŒÕ⓸,Ëlöøê8tº»Ãc7Ÿ;#+’d’·\{›ßÁÖ?¾ˆJ.¨Jkrê–äÜÔ)²kRÒcÎi¯ÌïI„ÍÆ^.† ÷JzÞg»³l+¢íݽª½:œÜþ·5LéÔÝ”6Eü¦øækÕy³³16Kük‚vë%B1W(·¬�TdP}´�#øàă%(_-o¤IfãAÚ³·Å–ô™}ÛYô›;Î…ŠþVTCÿš‡°ý7íÚ±”ÒÀÿóùllyçþäývŒÚKÑ8íƒ�¢/*ø¯ä€ýç_¶wßÏv®¾sÄè×í7Ê®¿•]¼@u Ðõ¡;¾�uÔQGuÔG¨ÀQGuÔQGuÔ‡¤ ÅšR9›Z^äuÑ�£²)~|ðp¢šI×,Q,¼x…1gÉMuŸs†”g¬Îƒ‚>QÁÿi'µk¤Öî€ÚVç�}€óyoÇiÙ©€©O¼G Á@( „€µSâØvCmÏ’‹ [Ô�w 0›âf_Zx¡)µƒWà>†ˆTíža�¥ÖFüÏ9o }rX}@ )"ÆÃá£�ÓÁ�H:~ Xˆôø¦èî7M½÷ˆ!‚"5Pª:xç0Œ#^=0 Ÿ〻»»¦þ'"ä”qƳZ‹¦Ë:bˆ‚uYq~~Âóó3žžñæí[Ìó )Á{ ãˆû»;8ï1ÊÐ6�÷p–?ëLMZaK½/Ì Zå”�œ9µ�w¢ÊWršÝj¡ààRsiõžEï@ãïuƒs'Ê—i],H«Úç;çAðj—~Œã g‹»0+x˜BV�Q p¹u‡ªr±SUßÿŒˆB©d‚2œÇÕí¤rûŒïÞòXÁßž� #ri@ÎÆCëóõ9ƒ¢Ì��¥´õÔª}OaUÒn¯W7–ÄÃ8`ˆBðx¢gÌËŒ´fÌeAfF2›ó5%Œã©‘XöêÜÂîs˜1xçÄ)ÑOJïr¹¨í^Í$*)f?^¨3»�ÍÎ^zõ:^º£ÖWê°ÜÛ™ïO‰Þ´S¯¦¾–ü÷*ø~þ#ëW¥')Èž-p‹˜#ò�?££r™þ_šûõyqÜK>ÍRüßžgþ³¶Ü$M¼K L7þƒ^zAUtóøôôŒç§'¬ëJ§ÓÉlþƒFò¬ÉžÙºžç³ôr²,˜¦ Ã8êÚÍÜL„RÁÖ¼ÅCõªzïLéªÚZ£�8› ½R܃'@$*‘ÔæöJ‚U§¤—bs¨ªkñ lä�Ú#. �p3¾`ßÿn�¼íÙ_ÿÎ{’Áˆ—��~¿ž­ªªd¯ ùÝ]ì ¤ïÌÕ*?aY„¶Üy¼®OÌi* ld]$W’™˜E½Îu�@Íݪ¿——k±K2梗«s¯5jÌûMM_ .•à•rƺ¬ªü_¬kÚÈNûH?ªCW ±�Í js¯áÍÅ­¿‡®säÚŸïúWw �P‡.o×{«ËìúWá�{Â%y޼?¾ŒuÔQGuÔG¬ÀQGuÔQGuÔ‡¤Š°ªíÌZ“Y•O)gäuÕM'Nëž´wj§ lÙ�ªð-`!¼~ýžZW–Œ´¬XU­¬im›ndÊý0D¬Ó„1« ÿG8Ë’wDð>"FÞò�…Mñ¤™ìäßÌ…«tÛlê²A·Ôlµ²Q÷Ý\Uå¿3 ªäbÇ(fsïPõ^àñÁ×ÐÀÿ¶ÑÖå„V»M¦ú È%!ǃý>ÄŒª&WP©*=KË�.Y�¿›]¨ó%€™1Ï –ui‘Ó4™M­Ã0˜††!"Ä"`M Ö¤÷.žÎÀ!€?™rT¼S ψ¥*Ç ¯” æ{ÛäÙoößRP8#¥€@¨l …«›Ê& È©Âhç=@Àû'¸"F†/dœ‡˜Í&ÀªÀW¢5�[ww3 � +@Â/þvÄ×Þ~ò� NÞ�\€‡ XDA¡ûÓ At#/úª.a5¹þSn…l÷¶ø•PtëØÛŽ\3IÞ’Ü;Îæ*e¯w^ÙWý¦§G›Ýf»)!•@mÆÚŽÍ/´RóàUà¯MÌtñªÍø¼^s�Úø‚/>O |óù9ÿë?ÿŸ~ýßþíßúê3‘[J,H¥äRRRPžsË�è3�É<‘ƃhá8R÷ çõY‡hÏ�9%Q„-R ¦DU\ZëXcÔU/³lêõîš‚ÍÝ:G¡å=C™^”À ^ïŸw…=ð¤ÌEûö€‰s(DM)éƒG)N‰N¥ìrç3³¶‰ìû÷Ž“Ñ�Šl€<Èi$‚�KÎ,ô󘕼檚~ƺ¬X×UrÆ’2¦éŒhd×ev÷ªÏ$ô.á¡�…Ë®“·³¿D…ª%%†a7×_J— ²Fn ¿÷¶úu.ÁÞμöù‹”�íœöÄy?gû‹)d{ŸÜœÁn5n�î]T‚¼ô¹·­p™1_Ý ä ý)}^TY¿Ëyà¦ç ½D©º|µÜžâ_üì—ïÆÿ÷±*mf‰��oižg F,Tzĺ,Í `Y#<›3Ï‚ÓiÂét‡i:aœ”PÁÜ(¯ñ::sËÒ5œ>wÅ ‡, oÊs‹ñ m ÐæÑH*—€unSË×?«:»öK)I´ôEçÉkráöüìÝ ÚzäH¼ Iw’÷‘3¸  ×¤"bUÿÛ<Æ=áÊÜT-^§?ÃkTKÉÉž"‚ÀCs(#OðP/�NûTJ+Š”NëͶ!–UÉ/0«ÑM¡O�Ú)gŸ_½~¥ÇMsœáè Rž�…‘óŠ”-ÃÜb ªxæ¤`÷�‡Þ@ð`6«Þ;„Zžeˆ1ˆ^mû8U€h],ˬ6®kj`jÍÚn ª‘jsÉ¥m–Õ÷fDÂnãmsàö:`¿Ñ¶m¶*�¡@P2£°o kAÏ;ˆ/ š ê=†Pò`jOFN\kJðËjçâÔÚyžq>Ï8ŸŸ‘ cG 1bF¼c9m¿’V‹x`Ë•÷^ˆè™Ï3æåÜ^Ó,]»(†\؈ÞgÍë¶|WíšCA1ß9Uöç´Á!éõsË ˜x ~#Ulˆh‹b¨çºŽ†qÆós„÷Ïx¢3dJ^q>Ï(lp+á£ä #|ð.ðÁcF”‡»·Îç¹$»OÞ©2 ¬ËYA0œ'œN'äü Ìw§ 1x€<¦qD:M˜— Ó4¡äÅÛ¹SQÅŽð±ÙÑŠpëk�¨€\Œqg�›“&v—Rðå/}ñgü·ëØ&ïñÇî/AHÌ ÁÔúž�R³®�Ž+›ÈpfiN €€"ÉÅÒÒ~ë›ðð£Ÿ|ï{u“; êÂÝ%bFºÞhv;Uþ ÚÑf÷ÝS n©�u®º€wǼJ%¿šÃ]üŽûÏÖ1^u÷Ôþ$ÀyU{[»‘Ô~l1v|ÅÞ7Ò;pøòœnŠq](Å‚.,ÛØQŸQ¼”8 ŸÍÀórÎÿÖo} ÿó?øÃòûšù•@‚Â…9¥ŒÕœ^rQðª>•„A0’‹sȹh´K7�úàí™Í^Ûži…sNûPÑŸRªEu�PÆŠT ÚÚŠŒÈ%M!Ùæ@]P¼×k¤1±¸%Z³ýáÜ–ÿ,�¾·0›'êm¡f«|û§vé-PìUbƒFŠpðêy*ðe16NÉÞ)°ä�0 ¬Ê~W#&´§®KB¶ø€T –uÁ0 bh \wPõä‡ßRÏžˆæ‹Á·¹�@¦îï�îéb¢ÇÕp·„¹Ã]@?,¤#lóÎ¥úŸÚñ/ç‘wçÜ7([ÈæVj®Wt%ºœe®c¶?±°÷p¹lÑ­½nD€È;æ‰ËÿÞ9 ÜnûwÕ- Ÿn1$¬íoï¥ÏèÈ m-pÓ~?Ó�Ͼþ<�çç3RNpäð~ùïÓOüäO‰¾f_#~ˆšƒOJ«‘hT‘�Ró=`±5{=² ‡l‘ÛúGIOÎܦ.•²d°g ð–éî}„ >;¤¤k°´&xç�lœzïá‚k9ð½}Ÿ_Ï,åeöìR®Ôÿý�tÑ:Où°½Þ�9o1UDȶ¶tM!¾�èÉÀu�ãMYBÜb®pË�/- ¥Í±vüž¸T¸@ò¦ÎÑHºž‹4ìLtDl€ls<9‚P„÷7æîžðå¯ÁðžàPãºúh–~~Ýî7ÒpZ5*¥¤ÑQFÛ·ûõçUHOFéÁwîÖç5f¡Zú÷Ѽ¯ßõê÷�/c ®ãê{ë÷ªœÓUüCß.½ËÀQGuÔQGõÑ©ƒpÔQGuÔQGõ!©R¾mU@)Å€êªÔP‹IÔ_-,ë1 Ö” LÓï�PÊ ‚`Y×Ö6ã8b%8ƒß›rJZê7E[þêÅF-sÁW~ãËÀÿ€¯ýå³êÏâôê:¶ˆáÄœò� Y…:�Øh‡¨‘Ðâ6DO�YÀ+€È¿ô;_úà�Êã“÷zLi¶÷ïg}d½¯Ÿv�——  ]CÙú÷8øe¹ <ì_ËŠL9`‡f’WÖÖW^Öõ´Û;º9¦©øk;Ü@¯ú؃zÅM èçA¼ÙÍm ?J�îµôø”þ�_ÿÊ›óÍyø�‡û‡s´xçVç\&"©Ï‰dÅ¥ªüDÀØ”}û — —=ØW[�Šü2¬Á@}e£¸@”âØŽ!âÕþ�š$Ôþ»Ëp–-`~:�ÚÅ2×\äJºqqKÄ ~7ÿoàH©¦ô»¦’¤ÎnBd�ÈV‚ÇfN`*\°9c�ö¦J¯¶ÍY#g„«m¶:¶8¯Ï1gÀ¿¯Ï8ï”HàœÑMŒBÐ3–U ëº*è”Ò0`Šª™MÑü(#dLr8Ê­£IO\Ùþljs»fÂÅëû±"džØž re'BûÒ�ßëùApŸøÅ†¾#3Tƒýí•Wá7£äω²´Ý¸ïLþ»|ÁžÀ°¹étÿ}ãÊÞanð>7gS<Ë�éžÞù^¹ý«­³\“^h¯›sïzй°È�r"a!?èšBDvjè @Wâ^ubJ¢ÀJÙÖ—ÒòÜUÁ@ DfÉq£‘~L�/ºÞ®ë9f�#�¤‘õœSküqš JJ:fSR@"Ž6‚ÌB ¥³^/Ûú¢‘Jh‹ñ©óˆ»<ÎøÜ“ 굂»Í¥ Í‰Åôò¢Z]£6·”ê� RÇpýLßÙå¡¢®ÓAö¬$By÷ "[¿“#„èA4®Su]Ê9±�ALÖv"é¦4#Dí6˜_Z›õJýà/mÿÅÖ¡¥9‰•RZ„X]Ç2s›K/£zÀþ’PÐH¹~§ãFŒ«}öúùv‹âàƒ>¯+™¡¿†yÃÌÈ¥t–ÿù þ¹µaý±è‡xŽ:ꨣŽ:ê£TਣŽ:ꨣŽ:êCR)e8S­oE¶�Y5x}Ðìù8D 1ÀZ£6õY-åCTÕ§‹*õ‡cQÛb"‚猢¨<ª*N¥ÀWëgiÛ ì¬�ɬàë†/gFÊ+–%a]#ÚÆ¿ÆZˆœ1ŸÏ˜Ï‹Újçœ_ãtwBŒ“ððê��ë²Ú¹b † ƒµ1D�vµË¥–‰+÷9¯;FÙ\:Dþe?èæï«O~~à§ÿŒÚñ×x‹N!Ippž�b¤³ìG—è^Áx1R€þÌ(Vò ʇ¿õ›¯FàG¾Mð©û¬vìðE¹‚ì»nj{À±Ó¥¢V‘sY.¸bðÚ)nÏ@¤ ê¸x!u~à²éñoSÞÇš¶Zw;2@ßÔôÕv¿·í¦[ÎïG[P€¸Ý” %0Á™ ¾7Û_ºŠ.¯ÅÂí*ÙE…åüøœþ½_ùÕ¯ÿ/?ÿ¥·_üä'>1ìwç8 ç²zJ%©°2ës"—¬÷Á@%¶¹�Ù÷‚œÞWe iíÍF_û³PÈ@ꚪªÀ«²› `8Ù€ÏúûÍæÝm±"0aÆ0 �ªµ´>Tóš•èv­Ü¯ «i5ð"uÆ1Ú3¢ ‚� iêGÆ‹vè¸ÃëuÞ‘òš5?|.Y|„ó€wmþRV§¤¯$zÆZ28+(”KÖµå….úÌ4·„=à·¡©D$x*è‡5G†Ë!yeÒ_»\öù[=!‡®\ZèÇÕ¥2œ^˜/n|ÖÍ_K�#Õª½Ùè�J_úËÏÝÛò¿œƒ" Í—6.mþû6ë)a³¼—ætñÎêÍ zòVPɨr1Ïn Gôç€ë¶½»x÷{nϽx!ka»_Ýõw"ä¼£#MÓ‰Öe‰ƒª¢ƒѸ³,W·“Œ¼$[¿”¶¦u^]}†aP’¬÷ª 7�½ˆÆ%IEmÌ¥eÁº¨Ò[DÌýÊ¢¶qÑÍ\G M™bÄ0DU�tJ¨³;,&Ú¦Uã!ÂpžàÖˆ\Öf®@†«@”’ #8QÐÑbqP•º©öÅlñ³d,ËŠùùÏççóóò¬ê}¹þCTÕu°¬TjZyþWÅNˆêz@Íj[¯ÑuñÒZK8ØFšm„qÙmê&Yš6�%†xUd ƒmF;ß6Û ÏÈ9áéùÏOOx~>c]g”¢vÏÃ0€ÈaGLÓ §û{Dï5Ó^T¡ŸbD¢nf3Å”[p†ëæhˆÁò¤·,è 6UÔšðbJô¬ŽÅ\€700$¤\•lj_¯ÖÙëiÄXr‹H –³­Êç¶±˜nê-��wðQ7à+Ñ¢„gî B)çsjnj¹­.§ñ„‡1M'ÜßßaOJœ`ÆùéÞ%g<ŸÏASÿ­ëÚÀâ•8ãý�ndŸN:~bIJ,@Õ‚>ÀyíW%s·Ùkíìˆ6"È¥ú?炯ýÞï|;€¿RÛ’œÃOý…©u8 ¸µ'É–¯qªNdç¶A\1oÃ�ð[f4 .…K%8¾ù ü'_v¸�?ð‰‚ïÿD�mNÝuz·pµoG�‚•¢€W¢‚ö˜ý$fö[U™½ÃÕË›"{=ÕèÔÏ®í� [r ¸rc"õzGÚûšk£™Ê›8'ÝÕ¼d°;ß &É.Û€P›çÈ@º†ÕH‹|aæßŽ#N§ ™‹U v†¦À猔5–Š™‘mIëŠ5kŒ’fÝ2m®?Þ·ñYº<÷l®KJlÌ�D�Aø¿V„‹Ôd›ÎÆÞ€Ýz- ò:²ù�䑦2OI fUír) 0ÞÝ·ú¹ÐçU�C+�áì®$ p�ðúÓ.êÁíÿê6¥ë±5Û°ˆ‚€-b „ „™QŒ^¨„€”œcÝÕ¹·óò~¢oN6ö=¦ìAÿýû/Ú¯ssºõ¬ï¿¶þïÞ[¸)ñu.èÔü¼�ùõ8—µ©+E2à¾tdÙ]ÿ;`15›;ÕF y©íHlGuÔQGuÔG¦ÀQGuÔQGuÔ‡¤Òº¶ [–ÒÔÿªÈŽM)S•9 ¤»üW+G8¡ÒºªòÉr¡�ó†Î†1bÈ™3R1‹u1ƒbRËbôY˜ìàEÁ'ï\SW ^32Ô’}™g<==âñéó?#­ € ÒC†÷÷¯㈻»; ã @Aô¥0æóŒq8#Æ¥ªò­Y¶r�ƒ qîïbÄÉTÎ1F°ˆç™JÉ�5¸–#»íï}.o¶|Uù7|¬¾çÿÄ?��Çw©2»>¨H˯6ºº± `⼆WÅm\UUo˜œ8˜‘Ÿqž&œîî0�'È ®;ºÎÔ)ðTl-g é\� ƒsý½>+aIÇo%Ðį¤Â:'…°˜ Í»#pȺ{Sý[|ðÕ‚?tD&t*úMõ�¶öÚÇ¢0àqþÞ<§„­>OÞ¿¸×AWî6rózÉ¢6jìX¹'™ JpuqØ¢·šÛXÐù]¯ÙÝ>>6‚F’‹ÍÍÒ‘Ý.�ð^¡ý³�[ð޷؆f�MVÛûÖ¹^=×:ׂz½MuèªßeêõP Ý³Pdû÷ðï‰ tþ:ꨣŽ:ꨣ>zuŽ:ꨣŽ:ꨣ>$5ÏK¬m6>x�‹ˆ> %„¨€ðÎnÖ,4]Ð�°§ç'³ÒÞ6¬†q@5c5CíPSÊH¶á$¹Æ˜§2gP¢f·éœ‡g•¢ŠiQ»÷e]ðüüŒ·��x||2+pnŠðñ4b&„! zUÿ;îªÍ¥Hµ¯†ª‰Þ þ×kkê© ›vu£¶‚<Õ&:Qkó XA°Ò,´…EüfJDˆ±®¡)|RJXÓªÖ±¢{ïc°\y§D PÙâ ªM-€ãc@^WH€ |Õ|Ј0D qÄ0¨’¿ˆ - ÏüŒeaÌó¢‘ óY£Ìn>„xìܨ“Ä._š*0 Î\2¸$H J"1u|* ¬v¤ŽôÞ4›oËá�ƒÀBF� ²˜†¬׫F'<==ã<Ïà’ã Q.àtºÃÝ�: Ãûªì;áþÕ+¬k†€Ú¦ï<ÏH)cžd³p­áðŽÓiÒ�å8pˆ±˜C5Ågu† 2Ñ{o#[7_0¨}´˜-øüþ×þIÿ�:&OïáÇÿÉÿ¢õØXBûoÊJ”P' ÂD of,j%λ ú3'8³Ög8ˆS€·:D%¯€Èð;¿ñëøâ/ÿáÿùoàÇôñ'ÿÄ�àg~úGpwÒ¾¡]®ÊïßÞßCW„wYH3d7Öö%�7Ôfß©#F=tóèØ•°°��{@º¾�øÂ®ÿâßõØl’í—¯[XO“»k�6�ØøâH W›ï”—µü­u•ÿð¾5ü¹ ¿/ÂË2ÏkN9 s¸QAµY¶¹¯ÖTè PßææÚ—;@Áÿ\ê=­9÷5. €Ù!e³\6Ûã’• °Í±Þ›“KÍ]®¶Ï•ŒQõÐbÀ¾sp‚6Ÿ÷UÌ}D3—Õ�¥ÙCß»©ô"ÎbÛõØÕ¦¹$�@@%(tÊL�E(›b8)˜ÄRº×]¨@íšš=]ûuï”áªÊ¾*MKFAa�ðfß„ 6�›+…Wמ#FΞëCJJºÈY þH%g‰ Ô¶·sùÃo~C>ùÉob"¥¾â؃³E‡®x971\zy>ØHØg˜ôjáKWê±ÿñ½šŸäêø;0{ÿ‘hN´WÈË.ßáúb”k°c¸Ü>©þê¥[à n;Mtç¥�Ì}{\ø2Ü4^ØHõWz›„þ~ßÊ‚¸ý‰/¶OÈ~ ßÿo¸Œ§Ó‰}¶Óé4á›øMäœ1£9a0Bˆï1uÑ!ÚŸjì3#å„yQRæ`nQêlT@ž”ÀhÖÿÌêv¥i 9"ÞÐuÕuf„�€ˆÓÉbPÈa™gsÑüúu]1Œê¶!ÈEÞŽÎ×dÏ|OdNu�ëkÜU§Æ¦f�sÛ~¾oá ¤ßôoའ]Å®\¯µÍî§‘îú›JÔ¹þtc“sÃ�‰Ûý«L ñ91l¾=ÎÁ­9]€à�3X»Ö„…�3K¿Q×sÌçxß&7È»è'ïv¤ƒ[m´o[‹yèÝ€öÀuñZ=pŸR¶g@j¯¿’½“Koùoß_úßõ± ·îgÿûw‘Ž:ꨣŽ:ê¨?zuŽ:ꨣŽ:ꨣ>$µ, ‹I¶ -o6  üGÄm#Ô]ØAêæ˜nPEðæñ-tsÍ�!F„àÍ%`P j]šÕFš³æâ÷ùæIPUÖ!DxGÈ9áy¤Á9£”ÎÜ”´è6CˆjmDò,)¯X–Ïç3ÒºP•í8Œ™"Ÿbñ1DÈ …dŠ6�yˆJþ¨ÀÙ²¨j™œUá–MYë!8#\ÔÍkg}wppєܺE,ÌXÖR kÃlÎ9­˜ýjVÞÚß�#0ä’tãç"îNwà�q1MwÇ7xóæ-žžžÌy"ò´�"xxxÀ0ŽÛýƒÓŒqª ;FöÊ&Rfic )ɺ¾Ánëƒ_ÿÚW€ÿu»¨ê/üe ã€\4ÝQÍÿ6µ9™Þ"\½Çæ4àa¶äàÀÊ7h¶ë �‘6 ð`vf3Í(¼p;nžŸp~ó‡fYNøû¿ôyüâßûþ­›ð£?ü}øÓÿ¹ŸÄŸúéÅÝÝ=Ï—àUgåoöæuœ´—]ì×kôÛÕläéæ?]—�!ð'BÞT~Ö^DÝýÃíãoÞÜ/(áèâÅÂËœ–^9]�ya%ÎUÛß?|žËßüýo¼ý¿øK¿÷}ã›å>õmß¾~ò“ŸL÷wnHZ×5¥’s)Ì"•Ìåàɽ`ªm­PI_Þ#y¼ͨ9áv}9ÐNU�j–Ã9D+`N°(˜-ØÃ´^Á+W} zòFwϘÁDúÙFjªä¦jÝŸrFÉ©©õPaÙÜêp£ Õ=–ºÏ]ws3Ĉq –+MȬϷd$-Í_f8#—í€4tªIlùÜ•àP3»Ä1Úr)@Úž9F 1ê1ª3Cg”^cmÜ„à ð)YíÉÓºÚyo®·ò§™¹Æ€ˆ–Ë.{K÷ý¢ï†‘pÞ—úÓ)½ßWãLÛØ¢Úóèò“+êòÝtsjŸÔç–Pu 1rKÏu¨ý�®O¶F€H÷÷ýÇmñõÞ_µŽ\þ¥NÔ·ÁÿJŽ —Ú�ð>ŠÝæ§›˜½¼ßDz{ž»IÂx)¤öI¹&u\‘ nÍ©ã4aGÇ1êP” 45 ßH5!`Ǧê&ï°,³F÷é'¥„ç§'€e]q7Mˆ9¯ÏµÂEÕþ,ðN×)QÀbH¼7²©¹ 8·‡Bˆ8�ôbœ³s(ê.‚5ilex©PnÊyuÙÚæyêâ\‹�yAM�ëµh?Pu4‚¹‹Äˆ‡vìÞ¹¨©Ã_°”ï×O/v¢ÛÝ�z‡‰^u_l½ºÌùöÞ!•ÐîŸZ�¢�¼Õw5å(9gÙ«ª6òÎo€a êT"Æql�!FÄà5kwYÀ…áSÒˆ‚\Ì’T�é}ä<"GUÛ‡º! À¹ A. ¡x¤�RwSpKÉ8Ï3ÂãÛ¶Yº, ^=Ÿqww�aà@aÀë×§û{<¼z…Óéã8!ÆoÞ| ó|FÊ OO� ¨Æù8S|Ëfe� ZNmÜOÓ¨ÎF>`%ÊHsÏóŒT2ÎO�xŒãˆ8Œ¢˜šŠ›€¦Éa,~êʵ€5bfÑù�œ‘ÈœWóùŒ”Wä¼ ŽƒvKÇ�`Yá³es,9Úýôhz½¦>^ÛÃß̧¯Î`D„uí=Žƒ‘'¢Gׯ-:‰K;Gî‡výýfÏqÛšäb¼ˆ=m{:[D”Þ#�‡ƒsÈ^×¢(탠ÎDä.g°×¹¶d·¿·~èZŸ«N^[ß¹ŽÑç¸ï¢`ÚÌОGz#ÐÉ^IOØ;%¼D8pŽ¢sh÷©:xsÈEŸÁ9)ºFôÏÑZ¥:åtn0õs‹‘¡{"@N{×¾nÏ!w/qÔQGuÔQGýÑ®ƒpÔQGuÔQGõ!©œ’‚ªÎ�¶‚G0õü0 Í>²Ù;ò¶9çà¼FI„ûoêªR³Â™‘Ö¨öºÍNÜ6±�C `±/‹Ð mUs9¿©Õ¤0ˆ]³+÷>`°�ù\2È9UñA|���`f,ËŒ§Çg<<<àîþÓ4a"†aÄäî ðSõàˆað­o}Ë|FaV Q€óž—ò‹OOëÿëi~ú[©¼÷w¾ïû~àÍÃÃC~{þƒœ×ß/NCz-9€%§ÄkJìWÏ H.,¥Xæ|ef9jÐúfa,�Ø ÖŽÁ~bÐ ü<‚w­}ˆBVƒ××xïདྷ^4ÃÞ”òkÛ¼Í{uÌš’Ñù-&›‰‚p;¸ Úæ×X�–·n}n]ækЫ7¥Ý ×€_ï‰Óž®sGD‰C»/1œN'œ¦ÆiBð ¯ê쑌 –•Èä D߬™½6{)›3gp1�©©�«‹Ž�PØÀùšÕ\Ô9À‘ÇÎ9¬ äѨ.Eh²~VU^:»ï�#R‰† ª€Ðç]»Mù©}~iÄìðm˜ý=íì-¥v€Óîϸ°éÐÁ«÷]!ÕÛ^Îý›©û³åÌwÊyi¾/Ÿä%!åò”©1$/Pö ÕnÚS+¶ø²X¥=èßÿ½�—¸­³ÿàŽ}“¾Ÿz{‡Üö×nÎ[KÊîø;ÈÅ-êMn‚ÿ×åCŒðÞS�/aa”TŒ ´ÝSÁ0 JüñÓ¤ ÷0ŽÈæL¤äN·S™Α­5% Â0Ð#Æ€H¡��ÔÃu]T³Ø™Š‘$õ*¨žs¹¥Ö5át*ê<Õ[ï³ln•\UíöqmÏß÷ éÀç]Ÿiඃs²‹u†ã¨k¬¢>ê*on/lsËLæës¸loî¢òF⻡L¯IÝNbÎ(>ØÜîÚ³W¼ƒßž»•¤ŠP¡Ýü·{œ_Dï\*Þ÷ ¸´ØG—Ñr;.ûØ�[Ì¥s™Ñ9>„"]Î…�8PŸÁim$Ûúy•$ÐÿV?áÝïùæØß_{u°s´ïDGÀQGuÔQG}”ê uÔQGuÔQG}HŠKi€Žk€mTÀrƒ.ݪÂCÁîªpˆB5!市T<¨dÌ Hœ¼ß€!o›^Îi)Q·®›¿EÐ2)EH@ò!¬ðA7í2kF'9‡ƒZ·÷¸xÀÝݦéd€sÍå«�¬ý&›˜¶i˜K†ÏÊÚ§5YöûŠuM[^& º¡,—ê+ï âuƒW Ö’À³*íUyªÆ…UÕéˆÚæZÊ ëº`Y0„0 ¦Ó ÷÷ TßÝéfŸSõùº¤ŽÜ 9ò.œ�ˆ5>À›ý&ÌV»8V³Í`6ò�º<ƒ("†ˆ»»;½ÎÈSw„'”uÁš´M‚YROãGNÓ„ét‡M�” –ÕˆkµËV^æb©áº¯ë|Š).MÙµP÷>ÏÌ Îb Îy qÀétr„a�sjí]JÆ<ŸÁ\°¦„e�±¬3îïµ} ãè|ÄÃ�7 ðˆi1MÕ e¬«ÆK“æOýtú®?–rI)çœsáÌY˜EXZ\ ³Æ©˜â™/ˆÚþm®„‘šíÛ�_µ¬¨ÑÁyS”q³ö48g'_É.„&ú4å}iq*e×7‘‚çÔ|Õµ�²º 2H¶þÙõMý)JÉa�à:’•v—J8p»ljGz�uÞUÛn#ã8a' qØž«¬‘5\’^WÃÞd{šíñ%˜£÷ íÚšóA%6ñö”b1:,ͺ™-v@ Ŭ·g·ˆyl6ÑA8 Ä‚R†�,×Üjaa‘" &ÑãKë êíÙ+ˆ/Íõ7LÛ÷úv�NúÛý•[¿n‘}dÿ—ægRGôþä÷• b¸û<#œ¼+:C AìyƼ׿×>M·®DÚSPùÀÎùÂìà†[B׿ޅí_50]ýó-ÇÙó}ƒèú)}ã„Kðÿ’ëV&êRU^:‡ý›N þB%gxç•$Ãë²îžY¥”¶öFFò!‚cjîGi]°,ꕳFh¬Ë‚e0Ž+ÆiÄ�2†iÄ8Œðƒ³h-߯½’tÔÙFDI{9g:Æû )\ PŒ”Ô‘ŠsQ_µÞoí­¤+Þ�é²íõ—lŽ/=¯…¹c¢>ª­|ˆã0`šNˆC„w¶–^m=]‰E¬ó½ˆÀ;%>…PPØw¤¬Û ¸˜Îå½%(±ÅÏt©®\ÊJ2Å';¦‘¡°9m8ò'ÝZÌ��¹=ôçÆr¥xoËŽF`£+'€ðwÞñ€ˆ-ž¬4' =6Þi‘ß–+Î9×¾¿éw¬½»Ð%øŸsÞ]ëvŽ®½ž�ÌÿHß1÷äêÜ®¶ß{O]”ÂQGuÔQGõQ¨ƒpÔQGuÔQGõ!+bËîâhJLBaFZ7U`¯ T`Ö5 v¯€Ï�eËR¥ÎêÜ�Áëg:¯ ç²Ë¯­Ç*\ Åì0¹À›Í<„U cûÌ1¸»¿Çýý=†qT‹cH.Íj¿pi›d1„�Ýe¯°©Å¬V¬@Îó<ã<Ÿ±Ì³Ö\Þ¬PGË�Þ,QÉJqȾ4»g.Œ%ÍH«·,Y‡8¨rjš¶M6.ªŠŸç¥Å¨õô„û»;<<<´ë­çË%+p¿.jóY.|ö±npR³ØöÞCâ„IÈ›‚hqȹ˜š5ƒ; Ê÷S9aŒC‹39UšæŒl®i]•àÀºÉ9Ž#^½zÀ4Œ`)­Ïjý¿¬+rJXÒÚY‘šZÍU…Ph9â¶û�j›Ë@嬛ÀE%Y®uRe-  ÞýÝ„aŒfѽ©]k.;3c™ç¶¹›“:FäTp:% £:QÄ8à½×Ó4âþþOO�xûö-Þ¼yÄÓÓ#–ň"Ë‚¤´ gU*œ?!xuH(¡ø?@3~½�¢d›ÈºÑûÿÁ/ÿ¨ˆü+µ<¼÷ üØÏþ9‹ÕbØ‘bSïG d‡ @ƒK•:dBM'‚¹÷ÓC1ûûF0q�ÛP"+«¢¼b8ßü½ßÜÞ¯®¤”ð…/þ&¾ø¥ßý_ÿ&ÆiÀw|êøôw|>ý©OàÓŸú$>ó�ߎïüô§p:�ì>Èf!ôUéé,(˜pf· s6©EŽvÀ"K//Ýòy7ÛnW©K‰ :æ*@BÎÁ#4àB¸ Z'%ƒ¹pÎüõyÍ_9?Í_9/ù7æ•>—øîsû¾ßûä'?™—e-¿û»_-_þÒS)Å“+LRÀ’9—¼¦5ÏëRÖ´Êš·<ßþW ‘ÐÔ�ä7kwˆh…“n<³U––RP-ŠE¤�yÎ;DÀQ uNѼxAð„!XdÀÇ%(¢ Ôfå�ÖÚöY[À³¾ö˜è=­÷JZà Ûê¨ãN�‡îÖ¹r)0䜃 æˆ *”©ÑÑT—lêüd€J.eÕvGþ7÷‡Rz[gÞÿ0á¤Æ YE÷™Ò:—%¤äÀ¬ÏÉ^Y\�H€¹*8�sSúf”P�²oê]ý �°ž!i¨xºâ^u¸xý³aÏÕí§!°�ò—tKU/»?Þ<€¾Ë\Ù…löø×“Ñö’KN�OÂUI½Åì>“D @³ygÞlÊû,sWç“mR�,êú¨6·È…µ—ÐnÉ…KÀ%P `º×ìû·ÛýÝsûп¢ôí*r;A€Þï¹#`Ôþ%/õ„6ˆ)(]ˆ…éG~ì³ôùÏ}A ëL©kže[S1C†ÁÔî:o¸8Àù¢shOâaF)ÉâoVôé äH#T‚GØ9Iô}®·–¯k¡dk}QNlTÙÜC 2gë©ùê7”âõO�‡‡’Ý6²á­{jÄ%^]ôïCÿ•5l„¨œ°ZLT¶¬œkμË–ß+Ð_¾ÙøëlÀ|çàí³R)p9_�ÅJ®êAý>·¾o;fFVFå®}oåÜ;GêPåÜÕw ï¥#0í—�$Q×Þ»g]=ÏâÁŽ-ž  �+!Ò˜/GÔbδVÇ™ÔÀîbÐ.¿Õ{ÂFéIƒ¾¾Æ D|k›ê”°ï·sß¶GuÔQGuÔG£ÀQGuÔQGuÔ‡¤tãÒ!D�8D A7îbŒN7çJVåκêf# $ Á›•;›�§GŒ'SiW@gn@LpúàQb@ˆÜ2ê mõŽÀÁƒY³Œ™x·9èà ˜ñG�qTP'îÌž=† ›‹e?RN ÈpÞ!bÐÌçPv*䪊¬›Wux]צX_U|U…©sN!GBˆºÁ;E M媛m)%¬)!•‚uUU¿÷ÃyÀ4N˜Ö yPKì5­jÿ¿.Èæˆ‡Ó8b:©õtxçU5Tjfi'ƒ˜Ž ø$± >Wš‚+oŠ^‚à Ùs†,J<Ó4"xu ƒÚN³9­M‰& Sz)PGv¦AÕòU¹zÝd/ÌX’ö³Rôý°¾|€'Od9¶ ˜B¹0×=ÈÌ,àT,¦aAI)«âZ]<Tµ­ªìJ)M½:¥ªEÕÃë²àññ­ÆLL†iÂ8Œx5>àÕ«Ìók¼yóˆqú„o8|ó›ŒóùKª€`F1‹og–èÓI7†}pˆf/88_¬oBÐÍX.‰˜ù""±ŽáìŸùË 84-&U�$ÑÛf®ŒÂúoÅOUÎg!V—  Ú–³ÖU¬ß0¬NL€y‡ ƒA¦P~úïay~úÿxŽªªNUE0åéŒ_ÿÒoá‹¿þ›ˆHË*ýúŸù̧ð™O;>þ±W¸»Ÿ0‡‡‡¯ß{…oûÄÇñÉOD ˜©Ùr×`O„â4âÜ+8QY&6à[Õó®å%Wko�Ú0CнÏ9ãk)Ë7JI_wž¾>qüzø*à~÷íýæç¿øôÛ¿ô-}éË¿!ßúÖ·d"Çw|öG>ËŸ}Í\X ‹ú]À;çØ‘c!.DÄ)"ÂÌ¥YQ—šÑ‡ªf7+ xíLýØ+ûZ6B³çî••…õ‡›êÑTþÞƒœ´|y"§@Ks¡îöê¢ œSaáû”ê$ÑÙ ·�uÙ[ü×ê ¢+°�2ÞÁ»Ðl½ÕÕMaí,úÅ™Jß;Wƒ÷(;RETu‰ „KJ€R§n}sS=öàÏ$ò¾>ã6é2wáÀ£ÇSåæÂ\�Ó‚’} *¡Ê99€Ù�Ùw6ÜÕ6º¿¢×lùÏ=AÏL¬…ˆý¯ h÷BtÞ쩎W°õ¹-17°±&m2¢Þ*^p­¨¿<Ü…Uÿv웳Îv<Á…¹ÿ±7u«¡ä…¹«’Pê\#crO$ºx³Ü"ìçBMÛ·³\^Rç ¸%–§. �*Áëbüô.ý3÷ÝuëæÞp<¨™.¼û„ VÈËwKºÎwóåT#Np*¥3s!*Á ¦Ó©©÷™¥°Æd¡®!Fx—Ô‰ªs ‰x;rïD®sÏ�¶¾ðÇás@ñ¥Í9¨ÞHM¡e]EÉ·k#ÔÈ�R­,þDï+ƒúñØMÄÖ¢õ~n]Z×;rÈEL„êx7n*)©¹¾x¯ sgï_ŸKÛHç¤ÞN¿WÓ×ß³ý®·˜¿žc¶H1Üâ~Üè+")¬kr[ß÷×ÌÂm]ß_[RWgí;Eߦd‘dõG­îû¨'Ú�©ê|ÃM™ŸÛñë1n­�˜…®lñ.ûÁBí9#§U˜A°ÆÉT7ºŠ$xaD_:×x1íîýe_ªç-ÝÚ¡¶ÕQGuÔQGõÑ©ƒpÔQGuÔQGõaY˜ù<†8ªzgš0 ¼S[Òm3*iÞiÍiv^¿Ž5?X”ðð0ØæŸ‹¨²DdgÃI}n®Å{¸@pé4o¹WŸÔ�Îz>à‚m¦Ýpô!ª‚>Žˆ–‘šÖÕ«-o¾ªR‚×ø|ûœž@D­DÙÀûœÀOs)€ƒˆ°.‹’ RºÁ`YÚy-Ë‚y™±˜š¾:¨Sƒ¶7€½’J: ² z(Y3Ä\öðU} �à ‚h`ŸnJf‹=È¥€JÁšrb; w#â0î"žñü|V‹Uë+"²Ù¨€SËyUµê¦øšR#E¬)€j÷ØTL1†f!®Ò á .Åeˆøf1�KFZRRõÉ]t…ó-³¼n¾VÂDáÒ²P¹˜ý¹ ÎÏzÏBÔ„Wg×ï½Æ«ûLÓ §Ó=¦éï„5£WÇNFJfÏb  32ƒt¶ÿÔruc@ˉõ^�†¿ùŸþ?ÿ3ÿ—êØøÌ÷ß÷£?…J¯!‘&ûtHE¯I\adS¡‘�:¿Fh S\“ =„ `Èz_ƒs3 Àïÿö¯}@pèƒÕ¦&Û(¹ÈÅf0¾õæ-Þ¼}Â~í˨nõþ €Æ8àáî„»‡îO#þëÿµÿò¿üð0âññÍ«´Ì¯SIpD¸?Ý»Wï½~˜ÆŽT%¹dÆãÛ§·��od]g)…“÷ñyšîžîN§7>orÆ›ÇÇò­ÏÿúWß~îW­|éK_›o½Áë×üc?ò#üÓòOæïûîO±÷�¿õæk|žY: DJ)’K‘¤ ‰iP»í˜;qÞ àÅû ä¼€ ³Õ÷žàC@ŒÞòä�ä3¼ pæ`°;\7øµµ8¤è|Z2#{F®`Iµƒ&�¿}ØÀqˆ6«kfË…¶øƒú\P ¢¿é ajdé¤å"rmn°ð¥üÖ âxÚ¬?ý³‰:w”vœJÚ ª–W²5‡�šoÝ€›z~�ʳ‚îUåÄW@¾ÏÄÞª*<7Ìy‚gЦÄtÕÍ�”U wJÖ:Ž¨Ëˆ.•Ý8ë³³wQÔs,D5È=ÕÞ±oõþ?»¼qû?WIfíP­ÿ÷wóâpÔòÛ?ÊûÊ‚¯Áÿ—_Ù[Ú÷¿­nrqBõ¾o‚íÙ';'¼¨nïíì/ Ôk|ÛM!ºhç‹X¥=yãV}Ëÿýµ]ýªµÅ¾qëÈtó··RÞç¹°»Ø[úâý­²sZ–Ù‡œ#ç…ÀëW¯�r²çv¶h2']ƒú´Â;§kT[ëzç4ŠÊGР.3>x�ç°u� ¡«©ÇKQ#péfvÅ8×áä-sžl û ú‹1[íí‹#M)Èíà@¬öð�`uñ̽Շûù¤F¦H �‹–­­ºy¤�ÍÝ:üÖ‹4â×­€m¢îû¹Œ*ÉhgEÒ+ý-ÚÇΧ؟,ÜH(Îï­ô�Û_¸<‡JÄ©‘,5ßž.">ª#Q{8ÚúEV×-%C`à¸#מ%ÛZhëO»©ÅîQu<Û\jLù_I;7ŽŽpy�7] DÀNcÎvsÝe_’KBǵsÔQGuÔQG}„ö™�&8ꨣŽ:ꨣŽú�,Ì¢GÆqÀ8LâˆæÀ±<Ê,S”Í’f0±Ò1˜Z™ ƒ´×—h·iE¦´%Ë‚tƒƒpЖš—Íâ<| Äàýã0˜¢S¦”Ò.ÿPòBSôx‡S÷J£Z—›Vš¥\@l'ßÈ ªæÁÙyE Ã6T«Xî}ˆ!ÌÞ#ålvÙË<ãlJðÂ���8??c]V0³Æ „ «Áo›­j)rä Äd›¢5{¸FY32yxb°c8x8Oà ðÙÑڕ¯)"ðÞcžg,iÅÄ‚�EðꯞÏxxõ OO�È는œnŒS¿±©™£D„R æeÖã­+–eÑH…¬æUÑí¼Æ#g%}èû¹Ûhg”˜¦Ñ²€¹ÅlTB€3ÛØ¿ñó=ø7j{úðOÿÅ©vA½¿MUV»¦Ã×­p"8$¨0˜Ì©¾Ùù3Ë.;Xý…dßÈYn=£ˆŽ]Ç¢ä"ˆüáï|ùöæýÿתWìqëC×cZ oñöé :ç2ýû¿ðw¿èÿÞßûûþ×~ý‹ôöÍ[Ü�“|ÿ÷~/~òOü$>ûC?ŒWï½F*_ÿú7ð¹_ýþáç~¿÷µ¯ ä3ßñiþñûQþì–?ùmï±ü¸0“ ¢j?g™ï޽÷C(1ÙÏ!FñÞI% )hâ̆¸ uùíb®D �Ffq>À‘×,dSrgG‚džἇÀ!†Î{�s� 3/àš®qQňF‰ <ç�rµ�ç@s{!�6nU±ÈMºæ ¶ˆ�=p²�%Ò+Ím¸qݦÀ¾¶x¿  ƒ«œë}ÿ¨î̽"^I5ŽÜ©Ï"%­95•®s"¬¹øß9ñ6Ö[ç‹N¡)á+YÌÇ­mé¢�ÉîïòGƒ Q/!AðaâÚþ<¼~™ÜhcÑk¾ÕovN×mVûÑå9îù#táð°?‡7ßúæý{ÿø7Äh'…Ÿøä·iP�ˆRZ`]‰°ëjŽ1¦äö>`"BÐïüÉ#äA‰gR ¥4ëÿ�jº­m5b£§"ý�ìH³5¶#F4bTë už3§“~N@��ÛeÑÅo´{s À5€¾wãbvm®c³qéÁü\•ÿ9µïrÝBóqâ ïÁâ›Y[_@ªí‡œ³~Mmí¯±/ú P‡0iŸU,²¥}/!B±©Ú{å~ý÷ËëØríÃ6'{]w)‘ƒP µÈ4�pQrné×�EI«J 0w…Ô�-#^xk#±òæÓ;*lmXZ¤Y6幸Þþ~×{èzWk‡žÐ¯Éo§þÉ=Iåb¼WbÅQGuÔQGõÙg>šà¨£Ž:ꨣŽ:êÃQÞÄÔöˆ–i\•›ÜmÎímxõ÷ÞTÌ®½&Ä€Á6ÌØ œÏpŽPü^™ÞŽ� z \45º)g*Ðï .ÌHkj^Î9V ëh€¸*utS­äm#�+ÊIjUí· h­móqÛ€¬ä�’KËt®U7®9¨C@ˆ†aSè£nصv:§tÂ8ŒxF ã¹¹RÎxzzÄ<Ï(%ãññ�OOX×"@ˆ1FÅC€óû\ÒíÜ‚ó� PS³33(dçàsAñž;…“wp…šZ-—Œ¼jž-ˆ0œŸñôôN§<9Œã wwx¸¿ÇãÝ=Òšà繩^EX_×çóŒTtòüüŒççg%,‹n˜˜æ�‚æËÆ ÷ºnôrf0°Ë(¬9ÞXL æyFZ“ªqIÕ¿ ‚mùÞNí³5‹6€ ×ê�\ai}`Y¬Ë aÆyžQJ‚ ²UUìÜk„0�Nxýú5æùŒóùYãl<‰ ’IÖTpwÂ0 p^·²«ú—ÁKµ'—ÿ€©÷é'~öÏâ½O|  Ø‘ ­Ø‡‡{À9†+ä; 8B*jÄ]¤¬š“+F(è'ð 0uvÛÕn— Šm¨»öÑßøí¯üÿ˜€Ý8~Wé¦xÛ¬ÿ ?³'ÄŽª­Ý¼öC¢ ŽfÊ¥HÉ’ œ÷â‰$xÏãyG@Ö”x#Ô1 qÞ•#Ó¨sWTÒ’'׈QÂ.6ÿÔÍz#(ñHÕà䨑¸˦¦àò#_mVÄÑëÜá]€ÈŠ%u©BÞ›í2ì‡D�Ù]Ž»ý�ÈYÌq ·¼{&‹1à1„JÊÚHT©#×Tëbuèòk·V•&ö€�v$sàm Aú>¡JÃJXÓçVAe:H7†ˆ^”ü"ÎA1|<¼Dˆ(Ðϲ,¹d”\”`@ d³ø§.çYX3â·ñ¾=ckT‚õ™]Ÿn6þ€�e³ë^»Õ´}÷„ÀÁ¹Œ\Ô`7h$(µ†ÞžwD€#›Ù0""qÎ=ÝlW0¹WÌ_•¤Î3ÔH»c`û….î'n™Ê÷Ÿ‚Àÿ˃¿T™Jnáú‚ëŠn„ì$çÒh/Cê-¶¢C~ë!¥žKt@½¸½ÿ?ô-$-º£k¼[ªøËÓo7ñÝõ� Ö¿yáïr÷7ºË‹ï{é]—jk½ôý™–ÂjJuŽ:ꨣŽ:ꨣ>$å½W%zŒˆq@ d*%'0›`o–ú€+ÛW ªÈ! ¨²o$‚X2d05*›ýg©J•M¹äj6¦ ¶ai@Ž0rª8]ÖuiFÂÞˆmxRµVµ9-YRNbX&ª‰Lê&U¼ÝfOíèÏmóª9 t*-g¶ìÎ+ЇÃ0bš�"G„èáÉ›�½3pËaGœN'ÜÝÝažgœç3–y6UNÁÛå-DëºâùùŒy>£”‚h ÿ0ŽÆQ7Ý5À9q¢Ý—‚’ëÆ®e²··d- é-j;(ç„l@ÝSxBêšPrÆ8Œ€èÍÿÕ+p)˜ƒ7°*@˜×OOÏ`BðúšyÆóó3ÎçsÛxÐTmÓ3D³§Ýfya‡`ùí®Å”—-¦!%%²\X–V5 8§fã¢)k9°ãŽÖˆ†ª´J9!™ujÓ;‹€9áîîaG<<¼Âóó˲6EmÎ3Ê:Ûf¯ ç„´Þcš&Ur» ¼¨øÿ�ÿûò€ÿQ·§ûWøÇÿì_4ëv€¨`ŸÌ 2 k» ÊGÉ6¦1¨¨s åkþ³�ÞsFpdÊ?â–Õ^?›¬OßÂÛo~ýÿo€w•\Øq;¢ß(Ì3³8a1£9Uîu $+è/¥èx±ØaGNeˆQÆaÄG/äHàj¿dˆˆ8"Ä4Äy C�òˆ{€¸:\ˆ€KFá‘"Y� •wÎ)áh˜Œ„dG³ VåzpN�Iœ‚¹8x§ÿ¢+µ©Å×CmÞ·²°äTl(ˆºD8#Bð(E£\Ö”�VuûȹØ\îHƒEyôý2ú˜²?ÉNV{‹�ü­ w8˜b–½l×�͹À‘C×áØ�(‚œF8'ª gü5B¤€¥´˜–­Pç³Í6¹SW–ê4 {‡GêߥÏrÁL© Nèb t^Ë `ÕW_C¤jS—Ù•]Ÿ+¬öÓ9§F"¨Ž2!èsRä€8çç£ ×@üé­à®‚Ú— ú@ªð•¥=`Y£úwööý7ïwgyq¾´3ù¿V“Ë…JŸn3ª6YêÚØÕ­BvÊÿFÀ¾�.1í¹C¸R¹‹ìµñ›Ã…ܼ¾þ¸}˜Â.Bè‚Ðp½q—°�¹½�üþ T e7Ý.�ZçáêqƒzP�äwIk™—{�çÙú€>ù‰O ×çûšp>+�ïññ OO�æ*µ¶8(ð«CZ•dªQ!P[WkÌQ²1¸·È߯úÞ¹A�rG੎6ß�ƒ"�RF¤<`>ŸñüôÖÖÃn7ÿ×¹Ä{tÊ}Þ­1*±G.ìùûbËŽod^Vb!‘3€s #ʶÞI6Ÿä�‰~®»i'/7#¤ÍaUOdÖµÿÊæ>ãÚ¿ë3µÆ6x‹ s6Ö(¤R6¾*É£äö¾‘Ú\YJs+¨¬�ïÌõFô;ïÄÛ}©î¥E�±}¶~ŸŠÑÅÃh÷>ìï ³~FÞƒú—À»`‹c«Ê‘½íÊŽtan4@v¯‚ �µ«ºmýÊ;·s `'�dAÝøÜ µï€£Ž:ꨣŽú(ÕA8ꨣŽ:ꨣŽú�”7åP[|… Ø9D€AÚÆ¦n€I³Æ FpΫµ(ªmf°M¶¶Í©œÛ&•‚&jëIÁÁ›jÆ‚K‘n&qáfÍêH-ö«ªØÀ²”X¤³¸,-‹^á˺ɺ�û}‘Ùj“ô€ÈF&h µ@I¦P ðÇ Ó†A77-[› ƒÍ&ÝU‰9çqw‡uM8ŸŸñöÍ[<>¾Åã²àéùgSÆg‹1ð!`ÇNý¿�âÛùSSâP$�ã¶ÁFD–+º]‹4ÈÅ kfh^uÓvs=`p)H”àÿ­b‘/•œsÉJØoPƒÔŽ�Å€^SeBš:^|%y/æâ NµŠ5w·ªÉr…­oÃhÑ)Q�pò{Kd¶ŒâÂêzÁEûÄúˆW'—G�B Q¢[î¼ß”–^ûº'2U»uôùï¦P·%…ˆwÞ#ñKíƒÌŒT@«©Tï#JIÈE�Öó¼ ­«eë'FBˆ1F³îÂ޼˯$¢ÎB}“†ó óFü`€ralyÑdªÉxqAs²«Õ·c8ÌÍ Ž[}áÒ,›+hã°{Fé}p ô©çÒ»"ljJ{^í0tiÇqŽà}TKè°ÝkiÀ¤ºT°·fî�FF)›mt%¹e{ÖÕç]‹”�4²žÁêBD+nZ­]]¤ChÈ6€›nàôÒÁÇ}ÂÃå �Ì´Óß_¼¶'FáEÕù*®Ft¡æoà¿l {êΥʴ#*Hÿêè`{Q=äž°£:\YÈF~‘Û×x唀Ë6—ÖØ%À8G7Þgã°ƒúwÿ�÷µöAªì;Ðí×¾tŽmÒrá_¸—7BUI_c•îî·È¢ÂX–çùŒûÇG¼ùÖÔYÀ Îgi¤>@£TÂ2 †Œ .Ô~-JÒc¶ÿÞ+ì�×µF�•ºT™×5w]ŸhäЀê.ÃöNÓˆóÝÎó3æyi$†ù|Æ|–]³�%r�ÚÆð8ÆÖ–Î;8"ô]T‰Ã0`œNˆÃ –åpÈyEÎkÛ­j3 nbçÝÆeµI¯dïMù<‚†q@‘ªÞxï�“Úú–Rp>?Ã9uªÈ9ááAÛ LÓ ¯^½Ú6\­ß+€±!BÏ-£”ÐÈÎ~ó+¿ñ"òß­×ý‰O}?þ�ÿíÕζa™ÀÎ\vYÚ Ì:À©ΡÆ<L:n2�D@%��Q"%xت¢øJlqÖ§hs–€óøêW>¥´ÿ×—þo?ÿw9åŒaü8~à‡Ì=bÅ7þÚüw°þµ¿© 5Ù¦A†�GÊ„Ïùwðk¿ù{ÿ§¿Žq�XÛæùÝÝ'pÿI¾øå¯áK_ù÷Uñï-›˜T1ø�ßýýøþþ1LãhŽ¿ÿûÏø½ß{ƒœÕššyÂg¾ó‡ðßÁ¶ñüÝøëø…_úRJ8?ÏxžŸÕ¾zUÒÔoõ þþ¯|yËÞµ¸–ÐÈK#.x»¼Áï|cFˆ¡�1tÿ |ú{ßkÀðç~íwðËŸûŠ:¢€ApðÑ7ÒÎG ÙÙ€ó 2 JaÍ…6b µñ7DÍ8nÏgŸ_eùÛè‡éÇ»_o€_% ôjæmΩÀh’TÀ«ÎErÀh L ÃÛ³-ø W<\I›.ÛÔ�JÚ¹òSßÙõëgVUí¦ú$#<(€´ÏÆ®ç_�gbð;Ef‹E ´ÈçÈæý�Ð>nçX<6Ei�„$öNÿî|#„oŽ*Cákþ6hSòß´îïÀðíJÆ“ö¾KŸ“ DëAmuÍ—Û sõ}§k·;âîÄ裾Áë"`ÙúV% ]Zñ÷î(혻`„ªï×›�ùΟ¶îH [?ÇN9MÎN7ññ«ûB»CÜ8áÎ9 5)]ƒÿ7?…ÐyàúfÉþ.�!Ýu\‚ÿD÷|GH9=8]k�’ ‘+U)®±S+^¿z…û;u陦¦qÄãÓ“:3åÒÖê¤kUç2œ"ÓMÍ/¬N=ιF$quÔ,ám ÍLW¹ò½{H͇׵¦×H˜Þ΀­¿ß;DÕ?ë\P×'M=^°º1W˜‘ ›ò}#÷Àyá‚Ì`BN©ÙÛï¬â½G¾9<…ù·~?�ú#Èb#ÚºÖÆ,ms§ØwBoýï ˜w�ÄQϧw!x© K)XWì¬÷ùÒÑ øýw"}•Í©Ué_�°‹=àRšK„³Å�^ãâ`‘b1#Ö €¼#1èw¾fxé†k'ŠËù�èâº|ëÜz7�›$¡íJ›{ÉÜ®Œ"ਣŽ:ꨣ>JuŽ:ꨣŽ:ꨣ>, 3ïá|0¨ªÝØ¿ª*¬¥Ö˜¹åLhžšëØ�nÛtÓ÷bË“ÏÙ¬ù¹m:ºâ Þ¬Šs‚ˆm–-+Òº"笧ÞcœîN˜îîpš,;ÝÙ³—½¹mSè,'ýf™l*r¶™Yí˜ #˃�ËsŸMõiÙô�qšpº»ÃýÝâ8"8B‘Œy^[Áʬ ûÐ+†¼"BÔLÍœ3æyÆÓ“‚xÎ+™"ƈi1NÓ•ò¿¯^‹æ�– ñ ˜Tª º«òß9¤5éý$jvÖU{Ž!ÓˆœT9.ä”±¸YÁ�¢Ñ88 #îN¯�‡Ì󊧧G¼}ûV Îg¬ë‚”ÔœœY�;o™© |ëfc@TÕìü…Ë�mPVåÞ8M¸»»Ã8Ž !j®ª—fS¸ÒNU�Í�‚9kwdª8³ý‡(À[�ð( ›³Ã±®[¼ X–Ô€|µð�q„÷÷÷÷m³Õ¹"Îç3RZÑ+©”œ úq"Âýà¹/ýúÿŠˆLõÿ™¿ø/"�‡¡önr€/@qÎH5£ê 8jöê‚@^ÕX¥D#•ªìRWŒ"¬Žu\Y/˜§Yðuû–¹àk¿ñkdüŠ^TWÉK>h¬GXxG Ea7ʤ¤šN­WmïëF»‚:û\ÛH "dÊ-†$ø€Ñi_™Æ÷÷÷¸3À‰!­«ÙQ“õ-¾Gš:ÏWµ¯Öëæ ›'¥02²±DÄ€v³ƒöã0"±a%,ëŒóù¬¦TU7,Š@ǰ÷>FËvJS­ïrîIAiá*±É²…!­Wˆ(ÀõœÐåGË…U¹XŽú—RíA´�1U1©./„„Õæß¡DİeK+Ρ˜Ë‚³8„eàÙ|ЃÖj›MNŸ3µ_\ª(_‚†·ˆ†½u¸÷êò ‹-ÐÏržP²oâýµ×Ϩ±0í™Ð½–NïÄäÁäÜzmùK©A¸(ê�óNµ/=Š{eù.Û¡¯ÄÔêr=¾hÔš»bäΙdAÏ&iÊÿËCÝ:‡í|÷ @ýw¯•Þꟴ¯]ƒ÷—Ö · Ô>Ú€n¼çò•òî.¹`›µ?6’ t�­Íd¯»SÇÕËnܪíþÓ»NTº›·Í%.øàbˆâHCÔg²L‚É;ø1… t�\^ãáÕ+¼÷Þk|üãoðÍo~oÞ¾ÁÓã#æóŒÕÜ|*8Z�¶1eêT²€:éºnD@€ºªÿƒßæ¾¾ë眱,³t2DF„袿°7Ríž ÷¡[ ;Ô§x%pçÁþgSóïîFæ TW‚¥4ûÿþ<ôsÝf?1v™ò´Ez‰ìè>ú\³çC^–=ÏûøïMIon5=±ª· ¯ÏˇpÃ@Dàø¶U}Oˆö&5æ•€«Ïn%�ÈŽ VŸ5FÍyAÕKÛgç”ðR—íû¹-^­^ ±õ'Fç¼Ñ“Œø]ݸÈi|�­g.c´ú®dˆÝ3K,ò ÏëžÄÁ]4ÂQGuÔQGõ‘Øg>šà¨£Ž:ꨣŽ:êÃQÞ¬1É,�sa�©á�ÛT-M¥’¹©7µGµö-ˆ¡›Dš{™±¬+–eÆù<›Š6uûæqT X1JË“NX*`̪ºö!âþþ¯^áÕæéÔ61™H€PððpñÒâ¿nøõ›n¶ÙÇh×Ulc+'ͬž—³e¹+ nôVuUð^7sLjqŒðÎ#eGªråÂ-Š §lê)ýý0 ÍNUóg3rJ –ç„HBð˜¦N§;µ5µgáÒH»MÁ¶';…ì>kV7ìR) ¬*Öâ�Þ9‹ZðÀ8À�UÉ•²¶oU»¯Kg)>Œ˜ÆÃ0àt—†XŒCÎë:ƒ‹Æ8EË&ß\ ‚Wë몢ªÁl Ç †hÇ8b'L“¨.x�˜( æVµUaÝ”®qõïÎQûÓ9(Z®@að4�Þc#RÒþ‘“Ú‹%Ìó@:�Š*Â}ÀétÒ[ãT)ýöíÌó æÒЛ MÇÕÏÿüÏÿ¬ˆüWëüžþãøÞÏþ„ÙíÛ=5§*Î ¼I{7 EM¾ ^&�3Òâ Ì�è±Z®ëjé쎲BÈ›€h.,mžÁç·oð­?øÚ¥iðó)¥Fìñð! @É:Ú¤YiÛ9v»Lã ž{·�¾ÛxïU�ÌŒ,ySFÁ —bÄ4Mxx¸7 `ñ Â/Ër‘­}ÀûÐ@›¼e@ë}u7Àtª–Î…‘$¡Ûæ=!Æ€ @‚k† ­ ó¸Í)››ÆËn —‡îßJÛ¥^¼àåóÖ¾~Ýnï÷ö+ÆÄÅ›wzr»]9ç{ù0 F�ÁúÖ7¿…t—š ?x�]:…€‡‡|âãÇóù�oŸðæÍ¼yó-<>>âÑȚ뺚»ºµp›O*QеMŒ¥Œm]æ½SR¤E´�S'›Ú[D­õs^�Ò¿ÌX‡Ó´b‡æœ²‹�¹˜'6Þ[4HG(e±Â³í¯¹Vz;ÎÜ œúñf�=ëJÙræ© “ˆØ<ï Á‡M™ß[ì·§îÞ^º";ß—öœÑó£f¥õÙ“‚oà)åÂ5f{~oÎ nûNÑYãonõùÇÝœiíXÁþæO†æþ⌀JÄèáÃFŒs;¾#„™Û™@Z_R"¢kÑn• W²žOa#¡ÙzÀus�3w-oÀÿ¥ú¿’<4Þ¡ ›KLk¯Ú®DæRt¹¦qk›«EsGuÔQGuÔG£ÀQGuÔQGuÔ‡¤œm*è¦ lvÂÁÇÍ>=°�!fÚìm·œÒª&VKþ5-˜ççóËCTU~ÈŒì=J)ð^?l;�¥d¤eA"‡4>ÁaÔ±`=MXÖ ëº`Y"’Ï@1ÀÔyx¯*¸aÐXG½�«*-‰M *¬JånC×Y�÷æ*à1ħÓ"¨âÊ¢$rV7çUdÕ jBÊœº&¨ °YXkŸŽÞ[ÔAD)ÚçÔš½æ»2R*™•Ì‘ ò)cts~GÜ›ª^�ž±®«�iÔ¬ÿëϺ®ÿc¡ºqÿçþÒ¿dàm¶LEf@—(ƒêÉ¡9îÄ 8×2Óņ0¥au.ز£QÙ3¤è‘œwÈ"ËÖG¬™È{0JüίýrS¹ÿ¨ à‹k^Õ5ƒL½m›èN•Ýb6Î0…¢q®Ž1ÞÀÍÖÍó ´Ô(� â�=sí›=™ :c4�—7k_î€b�Çp¶Ñ>Àû¼S"ªýû¶±_}”+hP Y�nã€Ó¤à•÷ã4Âù€qÊêRbÓI�Ã)Å»Mµ©D&u©DªRŠÅJÔx%¨³‰’œz;iUák,|¡�ßå¸W`ÏúÛ… ´Cɹ¦^­cL G‚\œzòj÷Fc9ôY° eo@¹GO!§÷®‚Nêbâë±±]“F†ÎI¸¯öý»gmªÑ> ¼‚Jlùã=(Ô¦CP#£h Úû²3o ^κè@çRÍ+‡‰§É@ 2e3b|ÞÝ”Kmy¤íŸÄÝ=ìI›’\Ì‚çÐßû{ï3Ï+ûé …F·^¡wâü�çĮ߉݃vN�Ê÷ŠKйô÷½‹]¶ÀÕO_.:ü;«ž«ì��n^ÓF¬¸\lœˆ>›û2²€pË1 ™ÿïš­#<¼à"P×(;ðÿ†q½pE78ûãÈe¼€jìƒ÷£§g‹‘I(9£pÞ-‚÷`ì™Bìáu®Våu±µeÎ¥, ¼f] ¨£Ò‚”&ÜÝMWë»RÔy Lõ:â‡ßµ È–èVò¤˜ý?3kÌRuºñAàC0çBEI»©tJwï$سÂ7åo/_ÏûÒ†›�¸Pç¼6à¯Ý†6‡ÚÄñõ¹Ò­÷k””Xü€sÒžÕ}´A›¿í³�“æ’æ¼kÏ?ýL×�G2²…kî0\X³”@;ò–s„œ¹u¡9[‡×óÖïkúLÍ3Æ’u9gßÕ4ºm»7úANE×rö €�-ÈÙ³ck“¢‘c´�6"8s ËúùæÖ¾ƒ˜ƒ®?÷í'öp¾$«(󨣎:ꨣŽú¨ÔA8ꨣŽ:ꨣŽú�”³¬b2J©‡©ûœÞÔ.úu3mS š>„š*=—‚uÍX—„uY±,kÛèñðp�¶¨BdSNH«)´Û€r¸»»Ç«W¯ðúõkÜ�î}lQ"€+›-wÅBo‘Û¦�ß(µ*h¥ÀÿŠu^°¦Õ>G7·Dø¯™¯kZágo §Ðµ±ƒgß,Ÿ‹�_ZÕ&vq DD ËjªtÝ ŒCÔh�û{Ü?<`:�Cl9ö@…šš«Ï'­÷…»œëËêód™Ùìá-?•<ÈëF4;VÅsf�ϺyX جô¥0À ïT9* ø!ÀÁTt–3>Œ'Í‘Mª~®‹5;\ïE¿Q+�›µóN•¥Ûi]pžÏÖÖš;˦þŸ¦©¦%¤”4×>§fÓºKº éJÒ¼\0DêÆ®3²ŠY°Âi¦k¨Ù°IûÊš°®ÉHõÏ§Ó !„êŽã` ¿ªs^qirük_øü_"¢Ÿ«}ó§ÿ©¿€O}ú;QÐ�bá£'°#�x8Q¥qg‰€‰àL ìÍaAÝ6{t f* rFæ)F`9�7ç 4Eã«_þÜnsýC^_ü‰?ñÓiYV��Nž4Åy%ï°0„uƒ�¼3ÑÚ"3¶ÍüÚCƒEwô›ïÌE>¬TEeáÒì’•p¤?z? Îççó3æy6PÉæÛ°‘ «9G q@6Wƒ~žî %°cJ)H«ÎýÎ9Ä!j¬Éé„ÓÝ Cp ›õSu:‡�tN¯€‹ª ŠEÂä¬ó¸:›ds¼pji|Ë5®ÀEÉYûiU\ Úß{+héI@¼)XÛëê?×ß2D²]§*-ÙÁéøhÄ-‚™‘Ö¥=KJf„èõhFþUð¼?bÔlkç]‹•)EçÇ‚ î¨óK‚\‡k‰e{oŠO=wnd’LÝUvYá $C%ø¡¹\°Jî•­l÷®Ú`+PåÉ�¼Í½Ü9Šè3Eçüz5ªˆ@õ~]âïfñÝߟ‹7Û!.TàB�²Ù\KG;ØAìüLÒ„ì/Bÿï3]ÕÏ– êw3önöî" ¸sn¨m£.hDÙ?”÷¿«˜>±´·Ì¿uŽïW;ŽìlÃÛ:¯ÝJ%ÑM"ỉ ‚�¼ã¤ìî�E*ìÀÙõ§[ï»}/÷„“—bhJÎ÷6^¨Å���67¯ ®¯ kZñj]1�N˜¦©9»L§“Î�~#ž”’‘ÖŒe^lÌHy½ÈŠ ×Å�x#Ù\'!8ñFôS²éJ ,JÄuÅ�KRrZg³ ¤3iä ž„Vûf#CÚÏölªkÈ.›ÁÈm1 !"Äg:ªÛ’i7—š�lP]`Ü ëïí6»²'|Ò®O´u,wÄ#ÀuäÑ5KÒ�Kç(në©Ú¦ý3´'Ø—d­þa¤kÇÚu·ˆ�€¸¹õTÕ-R ¤EÕvªÏøºŽPÂi6‚IÙŶx’,¬í‹rÈXry‹?³µÃF>�}~ÐãÄ¡ÍY¥¶µ)ÿk V‹/°{#E.¾cH#Á]ÝÔa騣Ž:ꨣŽú¨ÔA8ꨣŽ:ꨣŽú°,ÌZÞ%7à¿4ÕŽnX© ÕÀf”Ìe³þG³i¢n:m™“ºA”Í.R.”«uƒªf"ë¦cÙ¬FMU2ØFÔ餠Ô4�0Ž‚S»wÌKÂ{»è¾^Úh¬ÙR¸e¶æœ�’’Rζ�JÍòßù�´�ÒŠù웋‚*v ”sÃ0 ø ù©UYd j±�¼ù¬9gU›‡ç=îîîððð€»“Ùq[{²t¹¡j×y™Ú6F»MÌ—Úa·�O·�=ñ„€ˆ ‹@ˆ‘ëýÍÙl´Õ^'À”TÞ ÈӤà^2ÌÈ{×T²7­M/,–wŠ!f¬ËŠg"ä˜Ïg8Gmƒ”…ÍŠÝ�œ0´m�©óŒáfE  å½²0›j‹|0ËV³.Uà R5ž: è&fÎ+RR§%¬Ú:@°*Æc ¥Åb¾ðùÏÿz½æÓý~îŸý¯4³ D­i®H0Àˆ Í“åÞÙP*àD¯½Ú¾ÆpU¹J@æ vÒÀbx�¢-Ý aˆsøÚo~ñEÐåCXŸ×1WÔ8‚÷ ð䀙Á<6�ƒ ƒËª`*sêÔæXÿ;¸€¢Îoй"”‚5'�#¤5µÜäœ3–U�R‚½'žƒ<==á|>›‹Áûµe÷p.4Ld"ò8ؼXUìºñî`›óÀ«sJuñ`fˆ©ãunV�!8"Äa€wã0"Ýil9‚[=òºšº_Ÿ%¥T…"·1PJjs_µ€b´qQc\ÌnŸ«m0ÐÞ¨à�kÏ)@”# ¹a¾ýF¨£]9ˆƒ¡.ÉÞA¢ŽÓœRÇRN Å©AÝFØÈgÅbqÈlò‡!b˜F ah.)'äDª¬í¬«wVÔÎ5 F Ø€ÙðÕ 8ª÷­F?¸�DPŸm${ÜloÎ; zçtl»à»¸.Ü@=„È8MO7G{Í´¯ïdNè,üë}«–%ÒY¸Ë†X›Å‰9(ì,Á»cŠ\³B®>ûåÓÚ»\Èåwê\‘6¢@#áUà =AÃÞÍ|ee¾? #NH÷9ÔÁß]ÞË»ç_ÙŸzÍ ¼pÕ Žº†+"À¼¯^º¿^yßcÖgµÛŠܺJyñX²É´ëÌ€e™·¦œ±® ó<ãñí#îîî0M“:„°­m“ÍÇÁ[”‘‘`W]“y© Û½v¦bß<ím ¤s‘‚#D82b :çP±yi?/\Zä÷öýº†/ðÀ¯j÷Òˆ`šé®ªî\:RÌ™Æ;xˤ�!"шn¡\ªÛZx¿&®QŽ>€³…íïFÊ»\Ãný³ºP(«¤Ñ’D‰ ýûkLO®Y@€Hjízù=¢—wC´wúØœSw©À¡"JÙ ú¬«sƒE`…ïµ]ƒ‘UµO—öý+%uŸbÞbÅ|wê÷ïàΧ+{~Ùêo�¶µ7€öå>*é…wÄ'Ñ5k”Ljl÷©¿1Jä+m*¨ß'¼«Ï]Ù9duÔQGuÔQ�}æ£ Ž:ꨣŽ:ꨣ>åœk›ƒ½J¨4ûxj¤€¦î,¥T%¿t–Á‚8 –«L-×Qmòõµ€Ye°l£ €jÙÔÌú÷š‡AA(Õª›|gSk×ÓÙÿg©ª^M)cYÔÂ5ÑÁ98µŒŽÃ€8�Ž)gÐ2#UöF˳�Aí;ƒ€ º¹Ú‘"JÒ�æe]±¬kkëaT[üûû{œNwˆƒ³nÚUâ@uÞƒC„Ü2O/«Æ8ÙÔX.\odBªŠ©жÜWÝü°Sà"¥ëÂHkÒ¶[uhƦ �1âtšà°®¡Ùñ«ýü¶A½³o›÷ÜY䀪ëSµj6ºÛ)´|8MBëBŒ�¼C©„ k;a%^i{Ú¹˜·Uçºà̆9b Ão6Þ´èë]êææÎök‹Jrr6‹©áy7=7³�«tÏl±~âtÀ5©JD£-*e›{̼Æ`x�3œ �³µ‰R�¦ÓÝŒ6ãtØÏUŒ}¯Ú~Ÿê¬û7y—EßY×SoÏÀÎ.aw¼íƒ_Ò­_ÿN®þZ{˜t'Òû�ƒÐ’ 8­m®2‚ó¾³ÙǸ/{{~ì¯I:wjQ07{ú‹œ‡ædp ä ¡òO¨óìoJe¡‹O¸>¾ìÚêeÿ¦Ä6‡€úìÆ;ï 5ûyÚýã ÒÄe¸(.ù®½”™Ø®S˜4^)¥„y>cFuE±?ƒEgÕ1¸®êPJ�ó„4†¨ŽA]×J#¦’7ç›C@ÌÒÏ.8[ÿ’WP5�a›ëH%áŠ0Ö55¨].=m®J:7÷ ÿÒìd‹ÀâJÆ2·¡à˜VâVÄ0Žˆ1ÀE]“ ±U'—�ºÞ9ª*Þ\Rœw;Rçî¾]F¾tt�}T„tnÝûÉæÙÔîÔ]{}€/»v5±zþÅÖ«¥Æ�uN.J,ó�¨g ë %7"u7;ï-"42q�>Åî[.Ù"¨R‹ «²:gÇÔ�Áù6_y<ëX®ßÈÖo•4âÉiA¿¿(QCŸm¾b%…*Q–7"X¿›Õ{Zã‚úûBJ Vç7%$à uÔQGuÔGªÀQGuÔQGuÔ‡¦ªb³4%£‚«5#ØTy°Í2³Ÿ,¥Y6:§Êa!ÝÔ¬›r)ç¦.e8«R½æKV»|–Gez °Z7Ý@�¢¸xg Q_ÎáÊ‚|Yp{c8™•ÿº.šY¿&0—�²2Æ1`ˆBT%««ª7g¤uÕk"x`S懶áQrÁšÔ«›Îë² 'µõ÷ÎÃ�'SÿOÓˆhq Õ)!gµ›¯ Îì†�e€Üõ�óð݆,`± GÝP…�u³8Û«5ok‹ª¼,\�פQë‚eUÕûÝÝ=&Ë�!‚&X¶èj‘ üÏy³X­  »ìSËÑH9g˜Sú.CÛ9¯ŸKÀ8 w2‰ÆT)”ïa™g°”íøè²_YÕðJtd¶ O²iJ‘¶‘êÍ6µ”¡©ºkpJ‹fƒoÎfo6ãõ3?ÿ«¿:øWë}{ýñOâg~î?ßœ¤h<�wjã_�'¡-©Ù9ÑY“G2Á7Ël#ˆº ÀÉFp@4‹ó-»ºª¸DUã(X ÎÁ äðÕßø•wޝaýªª¼¹�%)D„\À>£äͽä€löÞ@¶±XXàÉÜ;R@ΛŮw>8¸º²Û¼·Í_9gœÏ3„ór¶¸Š‚y^�ÒŠRØ"$FSP°W§ �r)m|‡Àã¸Ö @V0QcL%¤Tí… ÖUðüô�î„_SÆÃÃNw'šƒ…3Ç®øöùû9·ÚÕ³e(S7V70¥ŒhÀ[Ô@}~Tº—T ´‹Á¨d4¹Ê\ï' ”a#/ÀÔ‹öYÃ`yÔf×ì½Ù`K{¶fËåÖgPqAU]:ïâ€q[Þ²:�8#<íÏI�Í Šì1‘ªÔ¼­ çR.Tý®©Lµ/»·a@�Wv Û-øË‘3u¤(®€!ÈÅ�Šá"ÓtJ/,-L¼_:ØýêÃöªööÙ,âûÿ®ï¨€8‹À.í×'Ó¢Sj�‹ëïm¼·¿^Î…í»Ó¯êXjJÙ¾?›üß°Î*[äÚò¾‚ór»�*Y@*Û ­ådçRP�úKÝ©øewäëVkýª“Ú÷D‘�rF}üÁ5øO¶V ‹> ÷ÄÞ¸eàòÎÔv£[=¶’víØYSu/¤F%'Òvã¶RP_çÜóy6·ÚåÕûæ¶´=Ã×Uã‡*aÕ9B.¡¥êsÔÁ=žÎY¥¸m¾«X@ç!S`ƒ€0Œ˜àœk12ÂE R-ŸÞµ¾—ßa±¿'þ˜SE%A±˜%�ÚöÃ9ï”0NÇÑÖSÔEÅj°l15¢ÊudÝîûs¸5oÛÂ"ÇCѦ: °ô¹05rk#ts1ćÍÚ¿�Ïb\�GmWoß]|ðÍ= FT—‡êr£.5õ;‰`ˆ‘UIƒí9ÄÒlü‰on ªþ¯kyjÏã\*‰8íÞGEÃö #R²! º(ræpTA·­�ëw­Úß�Å;A4Ò„íyYºçº®)\#Ƽü�Óþw1žøÿ¨£Ž:ꨣ>ZuŽ:ꨣŽ:ꨣ>$Uíî¹dS¤×lg¶M1K÷Œ|S©JÐl¥�}ǶÜÑu]‘“*Â7• ™‚ܵͦ-wrËæì7kŽ1�&ä\°šÚÔ™ÝvÍ%S×íÄC¼Wny§ \±ãA�ÒŠe^p>ÏXWäUÅ¥™¥qˆ˜¦qܬ½ê2žIÎe YÏÑÛ0Þž•$±Ð‚bD‰”*� ðÝ?<¨ú?M©Uªò§)ˆŠk¹mâ2À @ ìS“Ï€ÅÚoÀé¥^Gµø,5ÿÕÔ­ª&Þîs%E�7E=38g¬™42AX Áaô1ÖŸˆ˜"üÙa¡U¯› r®ýC7î]ë¨S¼¢Ya×Mw� P+î^ýŸs†÷ãxÂ4©ª9U­o¶Ãˆóó3r^�s±{ çS T%™næ‚�"Y�„ÞBÚOÛ(^‡eQÕ¶ öº±ë}Ÿ«ý÷3Ÿþ}áó¿ú¯0ów×>ûçþ¹ŽªÜ"³øWñ>�-ÛZD•²z{ÕZLjóO:®—êQÛTfRª9ƒ7 Ö6ÚŃY#T˜]ÀŽP\U¶¿ý…ÏíÆÚ�ú‡5ò¢gÉ Ù;¸lVÝâ 4°�©`ÉÀÙ2¹€‰àhźF¬Qó£G‹ðD-g7 6 vˆƒº1T%}Nx*1&¥„eYT­ Uå°l`׈YJ`ûUE�Äâý¥u¹9oP8#åˆÌ²2ÀjWÿüt†ˆ:ÌëŠóó30L“ö (ù…»¹ºåL;ÀÃ�Åß}b_Ì?NûŽ˜2°ÒS¤‚Q9¦) ë¼Õ­v]×ϸ- x‡Üœ²)ø¥Ý_ÆïÇÖ¾XeS<r%<¥뺢” "Â1wçÑÃ;� åkÛêöìëÀ–^[Ÿi]Y{S'µoD TUڼɼµCkúLr"U$×ø‚J²SBŒ‡óU…ª÷ª”¬ (%aç…ˆÄ=‰àþªõ+  ~ÐþŸ.pøÞBÿÆk«ûîî@¾Ú½¨Ã©+ðWI%—¶»cÑÅ'öfôÒþ§Ô�§ÍQe§b®x÷y®*ˆ;u0ªÃ�vŸ[©±ßÇáì7�/n-úÞñoÝ'ìøïPç·«ïšö굄wÿ÷nL\˜7Ø` _ ‘ôªpÜ"PlýÃÖ¨÷µO0^Üíˆú øZuŒÔçwU]×µq�ŠCÐ,v[«4’‘�¥ iöû9oN$¥F`•JðˆQsØCpä0ŒC#yU‡¡œs§¸÷ÿrðAŸÉ]?¬„Ìzíu 5�†iD°5f* ú ‹Ò’uáúõ¢£Ýü_¿/Ô~S¿wp#dÚ=e€P€¤kÀæPI™u¡rà â’ÐâB¨ìæáZ=!³^÷¦þ÷æêåw¯å¢í�mûM*ùa›ëÑÓr¶H™’íþ1VWgß�¶g�ô$®Â7£½êw*}¶êõ‹wSbÉE‡=¯É9x‹5ðænà|%¬̹ÿÙ¾‹hdoCËÜy¶X¯JF¢v]—SmuÜ8ꨣŽ:ꨣ>:uŽ:ꨣŽ:ꨣ>$Õò�¹(~C�cÑÁÔý-¢Xµn Ê×üªJZ׋©¨²�ÈÀ–I|«{@©fi ”T�Ö„ÙÍ ò Ö–ä°³~WK÷m§·mª–Íö4™Ò¾ÏUëU|�ÏÏ8Ÿ”’Lõ1�#¦iÂ4 C„U-¦öÙkÎà’ZžjU{ÛXóÎÀv›²ÌŒœrÛh®dƒaqw§›½Þ«,Í¥@#J#ˆ(�¡^Ï€ÐæUq EÔ¼ifÝÄc0JæößÅ”FÕ¦Þæ+¿eVëF¡9µ±f¤ SÐMÈ™1Žh‘"@\Ò6¯Õq”fΔu@N.V;ì­ïªš*![{›º,ƈqšì¾MG‡qqGL§ ww÷8??cžÏ8ŸgÌóYí|ó¢¹Ú̦rV›r¶û¼ªZvDf•0F�i¦)až<==â|>›ÃFÁºrSwU`2‹×_ø…_øX)åPÇçÿØ÷à'æO+ … ~þ¬ä8Ýw¼'0éïȩ㮇øÕ-À4›�PSÕ™À5û»Á¦ dpq`ïšâ¬Úß;"P 8)øÝ/îÝ*¾Ùôà—mâi oÉ«¹) ¨x…‘J¶ñ°Ÿµ�` a^Äæ€8 ï!¤¤ 5× %¨ f­@FU•kµ:iTõ¿¾ž› ±Yôg½Ë½Ê»‚®1††êm@Ãeߨ ;2WQ"Âó³ ƺ(àéùŒ»ÓI�Ÿ¶H˜T­ŒÑì‡ipðyŽýÌ^[vÄ/­>B#lÏ ÖkýÉìÏÑ�Y x5%8ÝÊ�·Š1€e°ùLÇ"nÏ‘ç&DkÛétjg¤T°Ì çóKY°.+–eFÎÙž%ÀxÚ€8tÖü;ywÍDÛ<·ö±‘߈ÞùSŸsµS+ `‹ØìÿMÑ+yä[¦z¨Íâ¼>�‘W‚JÐûXÉv¶yF¿\W¸íN -/cÃTNŒ‚AO‚00Z¨¹@d‹ËeÚüElÁŽW`³d=Fï†ru™²Í«=߀6Úܯ·ëè-Û÷/ ÍÚ¼‹Ø¿L>ÈmØ�½ŽÌsm¨×Bï8Õ±I{�ïÅOr´5^µ4¿²SÀÆ ,®×üRÓíš@nƒÁû“¯‰Qd7�êÜS�Íž€ž�zªo૎ÕêðSºëq ìe}~çœ-fJíÝk¬S%ryÝGSÜ£FOE›sÑuñ²ÌX×õéØÈ Fà`Ï�œ7 ¾kÿ £±]q0Äg3Ô»”RWJH´u…’&¨{Ë•[Æ•€ˆ™Bˆ&Þ;{An¨õ»Iã…~Юª@‹ÕGÛ´ë¯k¶!"†-¢�VèçáJÂt®Ÿ«};^¶û+ö}D×îQD ¼­­ûþcîk%ÎÖv{w�%0g‚œ!®^«À* L£ŒPjíŠíÞ»Fȃ’b-B Ëö§9é½nß v.'´'œÕç"3¤„ÐÖÒGuÔQGuÔG£ÀQGuÔQGuÔ‡¥.@,Ýœ¡Ny-(œ�lŠë¦zªœu7\Õ¯%pœ5>­IcridÄ„Ôl(©YÛ—NuÓo¼J·ÉUmdKΈéÿÍÞ¿[·l÷AØoŒîžsíý�s®î½º²q0qáJ\¤BŒ�ËŒmdëeIÈ�X&†THIQ©à .UÎ?ä�Tá¤R'¤(U±‰qücW„l!!Y2²ä§ÙBÈòC>º÷ûö^sv÷ùcŒîÙs®µ¿s®‘ệ9n­ûí³÷ZóѳgÏ^ý{E„˜Üê2tð"DÞ-¶ØeJÀrœ›’¾YK‹ˆÙò¯¦è4Ëí "Â4E\æ ß{ÄãÃvÝbß0‰´˜¢+º-ô²f0¯v|¾õzÛo[ô%"[\�&<\.˜¦1k?éJÉN(7±í¼ˆ …r·éÞ"Âîwýs•çÚïšâ¨©×Ž>ÁA‚YÞ_Æ\Z‹L à“gŒw‘°Åý5.f­ëÖå ¼'0R¢nqN¤ƒ²y\ü_4?vií}d]W,×+®×+.— RŠ˜ç¹¿.àùÍ3¦éµýüÊ„à ᢇ�´ë’‘¥ ¯¹Ø1‡èiÂÅÁQ˜çç¾P\kE]ÒFS‰ñÌ×€§§§ß¦ªŸµ{‘ð«¾þ7M-ªî—€ÁPªÆÇH€1{ È5¡©$xn8p'øb.cžÚ}T Uä,›*ÚU{õÇÏOov×௿ô ~Á/üB)ž=ÜCæ2"U�`î-Ÿ¾ýL=#="†b÷Š“qJ͸.‹ýmJæ’…HQèŠ7&Esƒhà}ërE)p²RÆšsW›고”ëÊ�h4ªðÛ`nªîгŠ{–0ÌÀ,”mÌV T8wõ½ÔŠåùÙÈ9ãú¼àéñ—‡L)u…ŸËЬM¦É²ƒFÉ3¦iÁ:Y4ˆµ�YËÓÆ&3€)F$q4ަ€êö ,4°ÆÕ­ƒ=xÙÇgÛq!"&lYËÖž«š*W¥¢Ö£ �q™'<<¾BJ3 „uÉxŸPkÅÓ›g#�­K^- '¬Ë‚ìϾWTfsÂY³?{ª“ ˆ ´�«¹}m$‰ `l×u»>žC@Ò>#IRý¾gB¤ØAU�¸Å˜sA«EÔ#Yš£ ƒ´w¦…TîãûºÉŠ?þܱ3½ûÞfa­äc˜î•ø޼C˜û5ß¹DÝÓž0ºÙ¢&ö'ùÙá´7vÀåè|°ÿ÷%ýÿypîÙô·‘z8¼Ž­»=C§ÑèÞ_a#ˆÝ¹ˆ÷PwŽüh!pwîyTéo?Óx}Ú|ôèð¿}Kÿ병WDÝ!MéntT�&º™ù<®jÈÈ�Ó4!Æd¤Y·Š·yqp²–e�(*î."SkŸß1BL¸d›K¿‚‚ùw‰RêlnG�ÐælwõÖh#])‘“ ¸waH�¬ØÈžÍš>¸=|wYiN$-ª æØ¢>7ÔöÂqW´÷lz'XøØ"/Œë[ÏÓ>~¶gH{Nè�®ÓÆK…©7sÈqlncn?oæí;Šì‰T µ“·i•7 w'ŠFøËý;LÛos„Ù}'ªÃ÷¢áøš;Án^/‚*¹�ûµ*JÝ¢𳆸g­AÕ~_U<êªÍO´ jÞæCRíz›²_ÑnŒÙæ.J›£O»>mÞHb}ã$œuÖYg�uÖ'«NÀYg�uÖYg�uÖ»R®þ h`Þ²™‰¶åÒŠØ‹wÀMWÑ=ÿ³)Çk-;å}Ûv-™Ì"_EbØÙMñÒ¶]M‘”-¯½Ôˆ’b*H)n DŠHÁ;åÊær@]Ù,ç—eí6ú9g¬kî»BÍîtЏ<<àÕã+<<\§ˆ0Ø/33*ˆÒ ´TÏöÔš‘KÄšã.ž —MùÞÈ̶8Ý Ä0DȦʯ›ê¦Ûü‹‡º“‚µùA±ï6Äö>ß·�lc™ÀöV¨ƒ2Ì2í#æÙbâ4A¤‚)8h ð¶(ÝÀ¦0#äà~#*Fါõ³M¹ê˜€ „{ßÝÎ×­iKÁº.xzzƒ-‚€ÙéçùÌѱÍÒ¼�‹µf„�LñÖR ,ËêŠ*Wîi@ŠíØ¢«º#blÊìºÈU R p” ¤ÿáÿß}€¾õÙ¿ûüBü=¿ð`÷(lñ›µ)»-€(€ÑH†ß÷j1�±©ü+ª¼LØîu²¶dB„YÌ“-±WUT Дjä™*Š Šù3ßÿ¥¤þ€|x|yY ˜Õê}jÈõÕ -v® ¨ic!†ˆ)mùó¥˜ ]¬¥ –ñzí`{’¸Ý£ÞD�¼Ôúkª�m,)¥ %'Œ€GŒ¬Ëî÷G�Ú˜˜’yün™Àm|R¨�iÆÜÎ'ä5™£†T‹ÿPA]”œ±æF¸ú}ÄýBL˜/¦iB�1BŠàRV,ÏW,‹¹Xd ÷lmSK€ñû¨)¥/—Ž6@§å@w‹ønõL¢ÚwãBŒ lJD"EÎeå �$SÂÃå�¯a,Ó UàùéêùÏQÅ¢Jźf\¯W<=½�J1¡dÍÈ뺩%‡kÙ¢7ZßR5Ûf©ºtÀfA΀ÛãµEx €ê6ŽÛ³¶=ö}ü áÂLô8Á€šë€J©¦¼õq¼µeàØ®Õ²W¢-àw&ÿûÒ=Ì­-6àÎKÛñ““Tåv†^ï¬ñ÷à?núØ.:èŽø/;‚I£Õ­Üé…ùÕ[÷wéÄowÎw ] |¿¾4Å{ëð^3�*fz�µAíZ}1ÖòþA=(ô7’Ëþb�dTzÛÙèÇù%í?¯HDƒ†|Þ%"@ÜÝÍ¥ia¡Ï,ë7@VY»½{C†¨î1FÄjF�Øæv¥JÉH�!º ŒÏRœ€yîYôRm<ýðÿ¹;¶F&¹}&�sB;·€5st¢bîZ�Já�Aa³Oxñz ­¶©#íÉG"Àá8ÁÜ;É[{šÞïø´‹Üèƒ3KÅm@Û×[ÔÑ`ñ?ºš TùEâ…=›1|wòèµâ„^f$/�.9F,t·6­�_³Sÿss?Ó!¶ÈH�EÔ¬ªîj,þ̶!ÊC›U(sßßœ8­÷o=½wc}¿—ÚØ­ôÅX–œuÖYg�uÖY_uÎ:묳Î:묳ޑ Á|ÂIy§ Ù,ô1¨èlÈòKí÷âjÖn%ÙÛÚ*H6pÃ+tkᣅq«qñ«ª€‡LÖÍæY:˜”’Y¢"ù‚\pÙ8K-®:ݬ÷‰,Ÿ}YWä5c]S¢«+Ü£Yx_.3æËŒ4Ϧ|ºz‰à`à^�‚ä O©ÜÛ`³F²óo‰Rën±9DÕÇvÉÅ,i�L±½ß®á¶P‚‘ZÛª«Æ…Äÿ[{7íØlÞUƒ-}�¸½g<.ŒˆÔRólà{ÜÁ<™®Š¢ˆ¹XÞy­]qcÄæ€<ã9!…ˆ'\Ó„5¯•¥a–ļkò–¼�jsA lñ\ÑÔ—›mµf nÃO› ^¦“²–"¹šC »3Kð å"j©P"%LÓŒ"ê\1çË´`¹,¨9÷±¯©ÜEôÊÕ3‡µ“k^HCß�z ŸÀð|]0¥ˆ”Ì ¤‘�êœQª8Aƒ T#Sh.ë ¢�íØDÄ2ÁÆ€iš,Á#LJ-xzz†ÔŠô<�£+h …²�;ìÎ*ŠŠ T·\sÚs·�é¡õï�`&ÚÇS7ÀI|üò÷‡F’¢þ|2›òèŠt¢]• )Å\ º º‘ .—õ8�'Ô­¥ÆF�Q%¾SÙoWŸüo#0?ªóo…à‡¹ÄNá®(¯¡ë†ÐDé÷| èHuؽ§“U¤E Œû¸ó¹1"bt*xQM÷ò…w40ωzPôw›ô-óy¬tOh¤ÚÙ-`³þÇævq¤ìÔúÝÆ½ÝÛêýö¸i}ØRÊ­ã7[÷qzøÛ\øø{‹Y nýŸzLÔ('&wNš jó¥À¥fdŸ!Š ‚¬Õ�\�+ ËuÅú°bÍ—îµ9 ´9ŸFkwø¸Õ„™|ŠÁßæÞ4\K¹!plN:tð]‰Å{Kû6�³k=¨ì™„­¿ˆ@ÅÉ¿�!Ù¢oô.éÐñu=ï·Ãví¸~�ÐÑÜk˜ µr¿¿¥*ˆ@ìÿ�º‹ÝÆX¡Fò27ª½CDõ‰÷8¯Ð£Ïì1 Ý ¦–6v·qg#Üub“Ï{©P¿R´ùwñ†¤Ýú0s…8I£¹ÓØußÚ¡'±ìÇö¸öÏ5nÆYg�uÖYg�õ Zg>›à¬³Î:묳Î:뙘M ¡Ænë‹!7@·97‹Ê‘ à ~›¬m/DP´ûåŽJ¦³‘Zžæ¸ǃÚ& €– ßr8Ûgªÿê ¸9fÌuîÇ3M !Ú¾`š&¤!R±æ˲b]×¾ÀÝÁÿ4aNÉ>ß÷'ÐTuà¾[4WTÙ¬ÀM*ˆnŸ¦ )¦¶KÏ�^M5\ŠgjÄ�{nÛânHÁ‚-?½A�gvß§iÂ4Ï€Ö-YОP‹àùùвÚÞ¤*®×%w~˜0Oõ k÷u1’‡çÞÌÙ% MsÉˈGâÇ ';5ÂW{f:8äϲ�LW�*{Nçlm šú×bZ±©åz‡î”]�¯¨…:a/ׂ’ËfIîÏ9#�ôÎRno¯—¸ÃŸßZCF÷ @;H=2`ÈŒö¡>ˆ‘nÄ–fÛÝá_?ïü¯¢F€ÒÍ¥9°åÒ{¾Ív´o  ïÀ©9¨èkq'¯Â£6¢ÂŽ"Ð207 �k[ïY`Z'”Ý|FÕ¦yG뀻oÞÂtÿ² ³†ëÛ³âÛ|ô °v® ãOoS€Óía$òF­Þ¯ÓñcA²Í�Ú|žÒç�LlãÉ4ašæ›üöF³{9X|I\í_rFN×€åjó UTOવZ˺`¹.X¦+ˆÓd oskÚßv.G'›KZÙw€á{Á­þíÜb >öS¿ÿE«»¸ ˜nD‘¾O'…öyÔ8>Ë}«ü¦,o$ >Xákmn)£’ßÈ{G·�~_"TëpŸÝ�›SÃKm·ë#}LÅ. H%b ŸïQ'Qmq*Œa„2'¯ÎSòyqíØR³üÚÐ3�¥72“'ÊNp’]»©ìQ†>íÏ'«2ñæ@#‚eøþ"3$DøóÁ¡Æ&ª¢ÜÝ_¶çô ÷ë)þ?묳Î:ë¬OÞ:óÙg�uÖYg�uÖYïFÍ)a¿êy$Tä�Weí6ÇT™m‘4¸rÜÎFkÏÄÌ;•ÔhM/ƒš{³tw%½“Æ…¸’›rßôÖ»Ó@Š ób¬Ì ¬%4Ù¼,Ü(ç� ÿè25ÎOA8æü›C‰tâ¬UÜÊÆI ºÊý؇v~øÀü§ÀþR_lßȉ £KDû\�Å*1£;ؼÐ"i`žgÌ—\�ÒŒ#4;Q¯n€>€ÁE&ôø&¿ŽE†¸ ÇûŸã7B³ÅÅld»ŠÍ•¬q'’_ÂFÐŽ)t§#l1)æjPv.÷îÄFBe9¿‹ŸuÖYg�uÖ'­NÀYg�uÖYg�uÖ»21ó ë½Êjû{­›âGÕóD]½fØà¨úP ìU3Mi [©�¿)k­Xë:*¢l¹î üo 7`äS‘fSÐw`7ooš0Ͼ ËܹÒ²²‡2·Ûþ4O˜æ ÉÕÿ€š¢’`À€ÈˆÁ6Ô¬<“Z–纮¸^¯øüOþô‡xóú5rÎF*øÍÆÙÚ¦Ô‚Z! 4{–³lÖÍmqÒÀÙ,='_HôŶ½F~X×uk Tèñ`ÊÙ€ÄT5uS$åR�K1g‚ ¹Õ6‡DUˆWbš"îz}Æóó3ÖuõEf'YðF ÁÁÿÉ]Ú×[Ü,Åì¼×eéêè.— æyÆåò€‡ûYƒ" ü(pp?c]3r^�Wû› B뻥T0g)80Tšú?"¥ŠRR�3øÜ—–~ì?û‘UUYUq¹<àûúßlkòì@ ¢¢C¡B{QAC$nWiv6Ëeÿ€¢ÝÂl0·…E´LZ…]+8 ÀnåèàKÁš+~ü/ÿ…ÞO¾DêOÿó¿í_Òš (pHàP@¡€¸tUpl¶Ú¬s7ƒû/´Å~·f�_ó„4ù}£CŽæ2Pì6àÛ"I‚˜B'5ÝZòΩ¤Ý«:8´x“æ2Qköüq0ʶæ÷yp¥%3%$&p (R»]¿¥T)b4—bT©ÈeŲ<ãéé5˜ ¹d¦O`U í`õ¾h¦ÁF|çv€A½Ú;:öò0>Ùâ@yûM)!„ ó•{`>”¾7¤„{4ºé7÷®|…ûý~¿/�×j³b§¤ ªEP«P­¥ßk›ª€ÅìÜecíIƒ+PêÎAÍÝ¥½_¤uwj²¹Övþ1E¤ä.Ë‚iJHO®×+òšÍö^ËÕ”ÿµ,ËÕ]”lÿ#ñ ÍßÌĉ©þ|h¤Î6´{¼ö{œÀƒÓT³¤gˆŠƒþÚçÓRe‹•im7ºßÐFV»1¨ 6ÍÌ£NbŒÝݪ½·0J)`'YÚÊ7ñ ã¼ä†ÿ¶€þ=†éþïý³�Ð!NŠ�-˜íû’¸e–hkëbŠúì;J`\.¼zõ0Í“�í™PýÙÙ®‘ÝÎÞ^L››‰�,ê‘"� ìï##·¦)nq+:Y@EöDÎ6Ö!ú=¡@wËÛµÜDº™« õX‡ñ™M‡ë3:mœuÖYg�uÖYŸ€uæ³ Î:묳Î:묳Þ�jÀ4!ìUWƒ*ÇT&ÔšºgPæ§4�cYˆª/Ê•®|jvž€-¥4¹í°-¶®ëj*у-(€nŸœbtk}Þ+˨Ì6%m[@\–ˆërÅ|5ËeEv¥Í²,¸^¯XóÚDfél*Ýy2õÿ”&S†ª-’‰«öš çÆ¢—àv›èÇBÝMAPrÁõù_øÂðS?õSøðÿ‰ëõ Uuµ,!¥Íâ?0#M —Ë¥Ç!Œ€v cˆ; °EµPõ®õë cBÈÙ3?c¿æ1ÈÔ÷S7­´©lEp‡@dVâÊê èž×Ú$QTb[t„"Âó�Ýr–JÜî¿”‚²®X¯W,ËjàÌ4¹‚Ö,t§äÊý�¢±¤õá®*–¶x싱¾˜Ú,g)Øõ”¦Ý¢tq'‚ìö»öïŠ\*¤ê.›˜hC9˜È,Ï% Š©óbL(¥ „€ïû¾ïûûDä[ÿ²_ñkðÞ{ïCò|TAšMPÝÿŸ9˜Û鬦êe!wPÈgiê>ê>²~¬0œ_Å1]6�ʰ�ÒæÞa Ð ªÀ�ýðŸÅòüô‘ éïX}oΫYå—Šªâ {Õ–¡«µ;00[ã0p+Ã}dNÜn‹®ê*ovð€Ûè.­_¢Ùè— AÝ�¬¡˜ÒR¨R�K6�Ü�M Ê\@6"UsaèJ¨µì\XD¨+Ží�·oj€�2€è`Kg)¨Š Šæd ²J͸®W<==P¤er€ ¸Q³Ý6ÆÔÐod°367”æÎ`ªóY �L:ž/”8 ¹Ó‹4¦yQ@L3˜M•»PD.ÏPØ}½.Xžä²vð2 Q5›´njÚ6t‰‰R{ÞwU¹n<� \ä;cÿSw-5ˆ@boC‘í9nà4R€çƒC÷à(@ñdhäÑ)¿:µT­µªBó˜í¾+¢²‘vÇìÁ».ÿ7©ðÛî«{þmtÚŠ 4­ìÖýÝô¤g£`P½£»#ÑáÙ®Õñ†cï *~äµkr£*ŽíÔ]œðÑGuÜ„‘iÈŸXw’(½øÉ½'¿:iG‡vûèÖѱîö›·î�l°?Îq´ ÁAU/*J"B9g”R(„x°3§Ð;ΟZÖ¨od¤f½ßæ–"¥˜ƒgÄ;iûqµgÄ<[4‰¹M˜RÂóók^l[2ôIÝ�dErÇ€/ûô§wà7�%ÜXÖ·è£ê�_UÁ`‹ø?*ñ{Ä@›¯×6/¥î²Á‡6ìºmßíøöÊûûÕ¾?4·°ÈïÎJÁúѱk|ìzYà^ߣ!®bÛîlßU]™oñ í”RÂãã#Þ{ï.˜Ò©+¸»ÃHc‰Ñ®WocÖ0´tr¢¶&7"uš’Ç 0jmd‚�x­>§±c-�ÂPf(Ñ�ÓÙ½[±'Àð¬`Èvãxç?‘3[Ï:묳Î:ë¬OJ�€³Î:묳Î:ë¬w¨v‹G^ÛB [Iª|Ë«äM•˜&Sráùù¥šõ£H5ëw¡X“�¶F>ð÷¹úÊö½'„|‘lÚó¶Û,ÞKnà£Så5ãÚÔRnÙ àõë×x~zº.]�Ò¢ ÌÞˆmÑr´ßïV½÷0y<SîP5Bĺ¬xóæ ~úÃñáßü)|øÓ?�œWÄ`í—ÜNº»Ä„yšq¹X`‹Ë%—� 1¨õ‰Èöw8ÞåÙØÀËœ±úBkË+@ÉÀ F©ÅH /. ת�¯�ˆèÀ5‘é~öàÍfw¬£­zk7ÈÐ~–�Ûwu+ð˜@è€ÿ4M)"ò�Eê�ìЀ´‘Q«`] ˜W„%€=×Úžm‘Ô,°3ÖeAÎæÜ²á[?ˆÝ5tÛïà‹ðsºH)¢”Øÿ{axx|…_ýµßä*~�T‡¡Ÿ1ƒ`ÀBA\¥o¾¯¦ÐïqæÖßÕþÃZðæà`e ÚÜ`×�ý³Í„�•@Í €L)U#~äÏý§»XŠ/‘úÞëu1÷�µ`É+rÉX‹;Šx>½ŒvÄ »l`SÙUr\ÉÞ¿ÉõàÈM Ñxèn"NŽ©à<î£x¦{ì�(±[#SÕ¦~T…:ú_ ­Š:»øýʨ® ÍX×+ž—€*1&˜›‚ 6§'S¹»‹2 �£â�•i®3÷€ÈF¾¢Fä·½Ãïûœ³ïë)M¸\2êE�&#¿(#†s¬ËŠçëJÎPŒ®±Ç©Œ*UU‹‹à0<#| ^æa,õg mêæÀtpz‰Ý{Û6Ålr¢1˜�Rµ˜Ú´² HíŠÝmd¦w7–á8ö¶ØèÄ–Z{¿xÚ@!‡}÷‘î·Wk$ì:çøFº3GÙmG½õmÚ2²Û f7ÓnG£ø^{ øgmHÝ€ø¾½Á�àèÍ¿ßà èµ®,‡˜Šá|qçãÝdû…6ícŽmzKpÛä»VvÀq\ß‘ÆÓí®%NPòç^cG—Œ}†>üWÜw*¸i?:fC@U.®x§Z F€6®âεi÷膎}ÏI†@�‰êäÃ�X B ªÐl.;ÂvÆ)n–÷Ód1TÓ4w‡­7OÔŒÖjϬ¼®>Oøò/ÿòÝ1�®Q}ŽÖïõX�­QÙ…P„À '—Æ�|ËÁ¢?Äm$£6Ÿ´QËÆŠ¦ä÷ç_ï«îH }~“2õÏôqgP¸×�A2¤]ßþâYmüfŽýššSÃØ|€øXß°|ø©êjûÜãTb²yþåò€W¯ñðøˆË|ñ~R÷÷Ù˜ŸÒ&ÚŒ·ºd ?ÓíZN1!¥1?GÚ™åŒñcž™õŽ«Âñ%îö¥ª}üÄþl=FhISÍö†@§ÀYg�uÖYg}¢ê$œuÖYg�uÖYg½+Õ×’kþ{†£teý²®X×µ4ëxµbŒˆÓ„É­­ËX˦Ôéj"æncßÔJÑ�ÚZ©àÇjY×Í5„Еÿ»}ÜØñ·…6SHÀš×®B]Ö×çgüðC¼~ó"‚‡‡›(Lji¶Lúyžü5cJbò¼g_(L·LÏ[…ÎÑZu«ÔÁ°à¶´€gÚz|³Ù·"\ØЭ�]µJn—lò 4ûXŽˆÁ•¿n—ji ¶ ±eî½WÔ‰@´¸r®¢`˜EJ ól‹ä{—ƒ²ËLm7{ôÚ•Èö~Sôµ(±‚ wÕ𺘠ÁšWdÏÃnÊÿB$�'ˆ˜&#&Ä= �‚¸›†u?øßÿ‹|m»Vÿð¯þj\^Y7L‚R±-’C:§bà¿ @„HP•ÀP(¨[$€ŽñÐ}fËBPÞ¯FèT ›»Ú1€ˆLø‘?÷ƒ»ûîK¤¾çõÞ JF^Ma_rA^s�³y |Ehˆ7 íæ$�ž±^‹>x9Ÿº�L„Àá` FîY³¯ô‹�;Nm¹¼D !#“ÀI# ¼Y9—Nâ:’¬/Yf±YÔÛõˆ3bp·—`„ †VE íFÕ£å6ÙýœKÆórE®‘ ÖV5;±BìYÂD)YäÊ”0M!¤n;̈€ÅN|ÔÝ=Àº »ç—Ó0~Ÿ(1†NÚȸ^¯HóŒéyÁ|YQó"Sw|h€…ª T‹$Yó Q±1ß”®¼�a#Q…à1µxlœf'ˆEAín-žÀO¡[KÛöüx¨e?·FoÿncK#Õ6ª@ Œ¨Rµ»×¸ÞÛû¬™„¸±‚ÛF®f?ÒœâÔž» ¢Ò'o­½~?Ñ;ï¤!ÒžîM_D×;„ƒí9ÓUßžåWh߀ƒ�xá„'eòçÛpL€Z_8í£‚_‡gãÄ)ÁûoŸS·6÷Ãý°W!«_W½ÙÍýV¤ý1(õ{ëc“º¼!± ÐIžO>w']Ü‹< ¿¥éìݦÝ�ˆÍ@Ä"x„ ïré7•ý¿ ••îZU͆¾è`óÞ”ÛèJ­�Æ´±;õq'¥ÉÈ~1º ¹â^<†%C‹¹gEWv7^#�Ïc<©Ø-Ct3ƒ£YÅGŸ¯‡w$*QEUÞUÜ3ÑêÀocúxuâpOŽÎVã<µ)þ‹o[<>IKü¢FE«wÜKî; 4†ÏÛæ,"²#‚ÜßÎFDÚ§ÎÐÁ¢–3–ÅȇD@JÉ­ÿðð`àLÑÆiŸû¢êÇC{_lÏçÓ¡—J“¹Jµ÷ÉFä%Ê�,Ý�[Ê›óYïusØ’º]¨B}ŽCýûÄøÝÁçLþ3‹BëépÖYg�uÖYŸ¤: g�uÖYg�uÖYïHmj-Øê´lÙ kÎX®W,Ë‚u]!nYÉÆÏÞŠÞ¼y³[ìj‹_)øªÑ ã PW°›Â±:i@]ýo dÓ<#†€5¯æ°îUîí8LQ{|-×zùŠ©ÉÍÊ}Eÿ§iÂ<]0_.Fy¬�åiÚâ5´ÚíÓÉ-“»’²³‹Í¥ô|ÒåzÅç?ÿy·þ7ð]W·OxxxÀ«÷ÞÃûgW¯Ìt¾\º¿; ”ÚßÚ¹›ú®–jy¡Uv îÌŒ ŠfsÛ@Â1·³Û5e±-Žê'Q{�鹯;uœT@ƒƒh¦H�kêùËR¥_/E³\¯¹úžˆ+؉%ízr=ß•x[$®P‹1ùkÙŸ›¨N<Î`š¦-6"{V7à‹ê¥«æbÝlRKÉÈÙ\%ì3¥Û§6À õ¡ËåbýuJîpÑÜ,h°¶ PÕ©*ÞûàSøÕ_óëAäÖì¤5@UFp8ŽÄ� X€Â€ {ìÃc´[4Ã�3S» +È¢š*Õn ÉFPG²Œ/|øWñ×~âǶ±äK£¾à‡¾ð…ÏÛ5­Å¯k·º©¦^‹!²5Q_èïïõEï–ŸÛrz7 ¥øË_+(˜M#¤Ä( ’îäìÇÖïdPå…ª0DÒn�Œ=;¹ÔèVÃu+=ê"`°TËŠ'5kþHF*™bì 3D»kËQA܉¦F4`¨” AEtÀ» –ŠÒI¦€ 1"çòø" pr É­õAÈ%û}¹¥V(6ϽñP߈ãçy¶6-vÞy]�6ù=›.,~AtŒ÷°±]të#ÊLG‹÷“�* ˜çäãEí `o{löÔµ HÔùˆØ|›™-…wÀyö¶¢GºêÒlÄSJ¨e²~§ ÝÀUTQ°Tp5‡•6‹V$­FJ!ì¹sàÄ«´Ø³œϽíGÏü]7Ù³Ó=mîHâk&òDwAë®þõÔ,þé66B�Tê6;í ÞþÔÀöÌoçž~‚ì¾}üÓ~Nƒl½�É.ZÇŸ‡MèŽmpÏWÃ\@vû¹±á¿9‘ã•yá 5§<þG;ejÛ–ÃA讋´>N7úiä#9'´»®mKªúJU©�á[¾z»Ïìúw�¹š;ÌQ!ÝŽc³uo §`çµ°9l€±èàê®Èf¤d$¨ÚóǤ:�ÉŽ¹Ôlªëb.Z¥»ÈÈ@å>÷ØÆûŠÚÉ•:^sñçGŠ3Ò”vî&"‚ì÷ŽVµyà0þ„\Ùoãß‹\."`Uü‘Ôɪ› íÉ žY_|~Ýæ¢Ýz~|4íÜKŽ÷̦âIÛý,F,cºqBiÃÕþ�ŽèÄ-ˆµZ9s’*«F=¾jJ˜æd®c>×hã3¾�ÞøjÖûÒÛË­Ö¶È’6ŽÏÓä¤íQøsJz|Ù8O¥ƒsØHºî±E-2I,?Êz”ÍB}ß»„î!»ï*g�uÖYg�uÖ—~�€³Î:묳Î:ë¬w¤lÁr¿2jYÏëuÅõzÅóó3–u…Џ5©©’ Ûâ^ûðõú¼SH5;SÕËPÎ9CT†Ìú¶H¤þ{ÀlØ.xxxÀå²mCª ÇŒ3bŒ}á60›ò:ÚBZ»k­ü_ ø¿®KÏg n»z¹<Ø~¦1%#:0™²H¨[rV•Áæû¨âºª¨/Ð Öœñüô„?üŸÿüOãùù µTÄñøøˆ>øŸþÌgð™Ï|ï¿ÿ><´�ÿ¹dhÞ-V@'O´Ó–1=ZÏv[l`¯ÄRµ…m_¼®µöviV¬Ì M¾X]Úû(ÕmѼG7@wŸŸb„&S¼±8Øe7@ÇÁIM˜gE-<<¾2ËnJ)HÉ/›º*€Š­–‹Ûþ̦†M)õÅLV ®×+"(VWêj'´þ[+÷Îm�µÅ°RWÿÆdêå‡çyvõ? š={[”ÿÎÿø�ý¾¦�ÿ?úk¿Óã´Ô¨PË–AÁË¡'&e‰!ˆUPÂ(¨`5x0k"€P±9(mû ±Ørg êSpR*M¹m ÊýàŸìcÉ—à{í×|“<¿yƒ5äZ]åëÀ©ô�}Á¼õ�ج٬—s^QJ�CQ7@ÅÕtµÅWäl÷meLiž Lp º‘K–…ñü,¨¨ž߉SˆpBTj'®€Ìj[̸åÈ7¥)»¯��µJ(*8ˆÙ,v¢ÙÂ}ËïjvF ÁÈPl ý�©;(Ü™Åc+F ®�âçVké6ë6f€BìŸÜˆÚuGŠM­7ç�àýór¹`Í Ââ º9ЬëŠç§)>Cª:@±,W¬«ƒ~6ªoöß®‚ŸcNöå2�¬†ñCd³Ï–µS ê÷©ZlŽèpejØŠ ¸{ÜÅ®£ÀˆF1E¤šÜ±Æ¶U¹öŒnyŽJA ˆP(b�žh'lµVm$$«L¼lo�ÿÕãP÷’„{`òž~³Ðï@0£÷ûîxÓ¼ªP’±¢!ÓJpòvŽC(ÀΦ¾Ãã_Ì�7æ¯ ½v·½]ÑÐØÙ³ïÚ�^nÞ¡¡öm8ÎY>–i½h³ÿ3íýMåO{ûr¼dÙO}Žò6 €}—ÑÛßÝáFÜ*4© ùüƒyðV±mãëºØXß\ƒŽQ]-Õ]@',ëÚ<§Šz ÇæSkè„Æ!uÎ:묳Î:묳ޑ*¥Ürµ…Äe½b¹^ñ|½"/‹ƒåžUŸÒ.û½-êäl™À–oi Ð<›u©%”`ûŒ"�ú±SϹoùÖÓ4¹2þæy6@wMwmîÅ ü�aŇsz~¾"çÕ Ñ•Û3Œ0OsW½¨AjÕ ¡ú‚í/Ý,^^¯ žŸŸðúõk¼þÂðü|…ˆšµÿ4á˾ìËðÙÏ}ŸûÜçð™O�¯‘bêçdÖÓæ\ÐÀÿÑþ¿eC³|ǶiÇbvj¨¦|×RQ¨`Íùnèœf0ëRÏqÑ[ÚÙÁÚà¦Ô,µjÚÎ…¤ ƒ£”�¯¸#N %›xЦÎ'X¾õr]ÁD(ê¤ w1˜&[ÌÞ"µø¿®Ùû†lY«º�¯h‹Ÿ�lÑ”y‹¶ˆÁã#RÏ�)!0£øy)Fªiíàw´m~Ù§?‹_ýÕßV@BhX‘‘ Z•� c  8°"ØF1«ÜP • T(ëC�= `¤Šü,]ç—H›†¬»%@€üßy | Ô÷åÕ\M–îºÚ:DÞôÉ\@ÚXB :Äë‚5˜²² žYÕbHºÍ|©ëºl õ $Øöâ4ajÑ&¡’«©Ÿž®3*´mPeË!×-£Ö .k‹^oNnÅkã„Ùý›ªžÝÕ#˜Â u AD@µ`È<7»û-ÞˆXŒ¨âªk#R¹=}³>nd# ln‘ÀʈUtõm£Ù-¡ƒì„Ë*ncëf•¯~“ÜÈ߀€„iž=¾�üEn“mno^¿A^V# © ¯×ë“9àˆt{ì60ù¹Â²Ž�pdÄ­0X[�¶Õ¥T#†”ÚÁ+³×®h§ná¾W^ÚøP©½ßm TÙ"IB€Ìº�;ó¶/("¸‘ÐîÿŠR]ëëvL=2Â>PKÅSKź.;Ð|‹RÑîw6÷Šc»oó°MýŸ0ňm¬ bˆÇ$ô6ÝT¡Äæ4Ý�ÿ÷G�½ÝKí¿Gbiû>ÑÝj<Ìœ˜ÊFŠhÙóìd;H/�Íl¥íÃÇåFÖ8Æäàîxb÷ç¨þ¯2CÑIm>¥Âɧ›û˜ªâ2ÏûXƒ< Ȇ¹ä®ä7rÀ�œLÍ}Œ3ð?£ÔÜI°*�ðÛú©GÉì\ËšÃKDе;^›ãuÓÝÜÂ\½È³>ˆ©»Å�Dâ1om~d]Þ-ŒPÏ/äg�uÖYg�õ ª“pÖYg�uÖYg�õŽT.e³¾…-ª–µ ç˲àùzÅr}F^ónan”<(?òš»Mê˜á9*wr±ÌùÊ–±Þßtõd[œæ¹+ª/—‡εê6ðq³‡ï€¸/œŠ;ä¼bu…mw fQß2¨H W¬™˜ÐU3ÊPäZP+£–²-@©[[åbàÓÓóÎIaž&LóŒ÷ߟùìgñÙÏ~Ÿùôgðê½W¸\.nïʦR-†ÁyÛBaÛOõØ„èJeT>P]¹¬jÊíFfàÀžõYP!µ Ö®qìW+Öy5+nW3—ºí¿-v[N-l!XÔ-ç¾i¤f�*¨õ!W©/"8èÇŒ�&�›ˆˆóŒÇç”ÕÔnîPµ…ÒR<6]ºbÊÀøÔótSÚ 1{õl‹çÞ_™mX†Å÷n}ÝsÁ˜7瀻mq[Ÿ0G�‚u5%x)ü�}û/WÕ¬ǯùú߀iš Ã‡šªº „ö$% ࿊ÊA›º` ‚,Œ`‰¸¦põ£SV!È! ã3¨Í>ÝaœEÔÉ Åó›'üåú3»ñàK¤¾GÕ@õì[r0×ìqRJHóŒ9%¤i20T 0yrØ- %¯Ö2ùýã*ÌRÊ6¶ªÝ˗˘gµhŠËãóåªØ½ž.OàÄ€(˺Øx#Õ`ªf#¿”n�_:ÚÑ•çCœGz¤3j0:e»Ÿ‹˜J< ’}UAŠÑz�çÙs`D�X€�ÁücˆPPèî#aŽNF”�RÌ…DòjÇJl¤f¨Ÿg×”oÂâ—É4þ³A§x z4‡©á�ÜQJÆó“âêL ‘ÚÉp¥æÍ'‘Š�ÜüyÓH ­mšj¶�%R JÄ\QxSÁJÙ®k îH ;0™¼/U©@!'qÔN„À®t7NM)mÖÏ�»Í³ª‚¢†7,Á€Iß'¹uõ–1od Q…h…1Wž@àÀÏ3r4úoGö6Cy}ñ/Çß¶«9ôΛ½™ÓÌÜ�ï×·ÑÛ,è`/O{�ÙæmE¸¯î߉×oÃê¤êÏÑ›¶û†skVä7Ø?�ÿìï�‘p@÷â^ !~}s¯Þ´·î�{°ñ¶¡öN/ƒÿwhô–ë"ú0uôŸÙ ±½Ÿ‹ d›Ã5±9Ãõ÷€í7`Y*{TL6‚Uw²÷WPÎþ~' U›×µíÇ'4kõ”®×g¬ËŠu±ùåÀóàTÜÄ‚@6m®ûè|¹;@™Œu7�Oðxs6€ÇM(m$±ÖŽG"Àîò”ã÷Tø­Ždªü�ó�NÔ̵È;b;v—°c5‚ÁM?!~�¼€�òý8ïoóá0´?œè–½?e¿Ö¥–‰“Ké¿3·²µ;rÙ�·mûu¢çädÖ’+r6rI{¾�¶8#…b ŒmߥI`lÚ«ƒÿ¢‡ñÄ]‚zZ÷X®˜¢‘Bô÷sŠ€v·$#3ž€³Î:묳Îú$ÕI8묳Î:묳ÎzGj]–›LKS¨¬}‘ªd³{gâÍ„öî[Ž©îí@»úÈ’¶� Ø Ýž³UÛvhÊêd€RË6ÑÀ"s àÀ˜®–¹|³h(b6¡noo±,…1M )Nfgí`»4¡-ÁÀ „ÄHÑ-•‹/ŠåÝ«+Y¶Ü؆O™Õs™‹/ø¥ÉÀè÷Þ{Ÿé¶ÿ8ðO=zËu5õ¿9+”½Í&‘[ÌÛï¦dmÝ ‡°[Ül 5FD„&X”L}áy%ô µ,ëŠË|±Ìçª(%w‚FÇ™]Mê‹�ðóoQ-6 ¸Ýz³ïùéªÞÞ1UÌÓ ÜO¦‡åá%¯X׌âÖëf±î ¨nÃjŠ"ÂåáÒ³Ó D3ÂA)˲lñÍÝÂÔÅAN„û÷L[8Ýõõ` ž9gd·cw0BŒ�ÿ—‰j­ÿj»~ŸýÜWàýʯ1Už*D îà‰ ð0‚UF!²º¶…éÈFQ!Åòm+äñׂ2ÀN1“HцÞ4Yý�à/üÀŸ@vÅa»Þ_ ¥ªßÿûßïþ4€÷Ì>ð?}úðÖW¦ÃïÀOÿýä·ÏkÀç\ÿûÿÃ_ôÚî#<)tËå­ÛøXç‚fË?MˆÉ’)ôÙÇΧëò²@J” Å6›úœÁ¥nC‡¢Jo ³Ù4sH¡‚CK‹)ÀÚH^‚Ú, Ý¶¾ Á²ÒÉ2¬G�# `6Ò€}l\Øà“'6R™µÏºf@ŸMÍXÄTxy^²^§Û¨y¢;टÒÜ�¬FÚ!”*Èëâ Ó©¥G¾4ý”¢GÚØs¤)í™´å<+oàJà`ª{b0 *•”–îf@:ñÊ9›»„�5¹ÿNuo‘Þ-§û˜l*Ï)9X8›}y� f nÝzƒe›¥µ‚ĉ[¡`ŠÚãB0â3—ƒH¸á†ñeüFø-òs½1°ß·ǫß-Mh·›îÑ\#TwÛëH´W—77Ýw3Œ4rjÔN°§?>Ž}õ-Jõ�5¦�mÚ]$nŽ~ïÌ0DP{çàóqˆíÈõîßÉI·ÛÑãçÆËF‡Žspc�·‚ÿãç>ªm5n„¢|ÖRQšÒ¼– 4Îy‚»KI±­ýwÀ*¹½Œÿ�Z, Žd׬J…®FìÊkÆu¹v 5¶ñ‡óeFðùð4-˜ç ×ëb øì6e7qÌ®ÒæÐ[I[üž”»Ý;bL¶¹Ï‘$c rÜ�_T�ïÈÄ-Ret½i×QñüïÏ?¨“€­ÝoI�œ í;�ìÿæ=‰é>�aìsÔÝaì»K ÜcwúX¢6ß-Ù\½”RQÊŠœ3Bˆ>¯ÍX—˺¢Ô"ô>ƒ“=Ç›ˆ_jEñ¹t)þìÒÍë#¸c�=ó�|âÏ‚# „½ëUŸøÜ™ßµöMÝßfˆƒ;b9IŽï8{[›|iÍÏ:묳Î:ë¬�W'ଳÎ:묳Î:ë)S¡l6¹ªnS™³�ª³'!DĆ\l¾ÉéìÊú˜0Ïæù‚ižº5r[4ª®æÊnqŽPne “€ cžg' ˜’õš&,ëÒ­òX^jí?èùÈ‘l!5: %H•®z$bˆHsGËêÄPV{EU@q'À�Õ,ü�|@„#.óŒ‡ÇG|úӟƧ?ýi¼÷Þûþ39¶öÏ6Åÿض㿭D*¨4 ÌóŒ¦iš׾®ª@ɨ@·ñ®QSF^3Ö–©Z+Us0È+Öeq+X—ï ú5j‹{)ÆÝõ•jñy5ÛÓ\¬}¥-&˦’.N¼ˆÌˆi‚z–õœ&¤yÂϨ¨9cY,ÏŠe-XW'T³ÏoV·ó4™J:çN6¸^¯xzzƒ7oÞàéé ¥äN€9ªÃ˜ùnn¬sqûXÞ©­Û¹s`H•N>©µâßÿ÷ÿÈ?RkýGÚ5üußô[\= ¨ÚÞ+) Tiíjñ5   8´lv�„%”à@ð˜l(¡0b U‡µ\ñª `Sa*~ð{¿óøxWjÆcóèo÷þð?ý“À‡Ãëoú¿? à¯ø Åÿû¿ð“ÿÛoù–'‹Ž¸Ì€Bïƒñ)bñ誂´B,<E³Ûùû8aÌûÅÖ7ÐÜM†÷ÅÀ›’ÜžZ7ªZÀ<ªÛ@3ÈÔ«0 (¸ã¹½rà`¯A`w=Èý¾ïïõ(‚&±{J«:ØÖ2�í(K®={»%^lñØ”ˆØüDäœl$¦fmí!Š!n%cÍëMÀ蟉Œ´{H Ñž þüU‘MeKÄÝп)s3Ä?_`%ËäX6•%´«9 ÷n×pSsw×f°Œ‰�@;¥µ��»BP0°�:Bwö)`°DP0i=WtÐUCo† 0t¾éñ*ÜÞ0/¢çûçé .ï»>߯(Q5U©+vÅÁb¢-›~÷,ÁÝ\R@wŽLñð½{Ëyë`IN‡&¢>|{šNÎF%=Àÿ qóyþõgéý†}ÉßÿcÕdU=x6Œd¥v§N‡FØ-Æ«±ï_‘â‘™(&Õ¸›W™R{›Stw©1M“òqs«2;úlñL>võ~å.ÁÝ�¸�àýUÜ™e‹2R¤¹ÒÌól?Ljx¹`š.¬Ë®×+–åºĉÈb˜Aƒ»A;v>æh8&TÑOª9H5—']J=€ÿžMßÈ!ûxpÆàÖ¦¥nÑ'}›‡çõH>_[Æ=n|wthù÷ìþßÚ£ï€ÿ;’WØznèNQæ`#>wkÎ@mŒ‘�»¬k'¶Ø‰âni�#â=jÊÉ'l÷~‹’hñ2RŒhÀI„lNZ�°¢Ø(J-Ýe`#1Üqc:Ùb|ž…°‹Ê 1 ù~Íö‡6§‚/=ר³Î:묳Î:달“pÖYg�uÖYg�õŽ”�ÍͶ€g#W©›âɳ� П-Û•øx`Õ2ß™iò÷Ïæi6°�ÙrØ¥¹—ÛB\w ˆÚ�ÕZ+òºv�m;Ó4m¤|¯¸"—ŒZ-Ï~TÍ›|BJlë@–K_ ‚�ìœꀲ)vvâ×ð Ày7?0#].¸<<àƒ>À§?ýi¼ÿþ˜Üb|\XÌZ[:I›’Š©ƒC"ÒHÇÜ×4%LÓdç °jÛÐêŠ& “@ê„Ì»Ål`[ìm¤Ë6·sË(Ýí çŒy6«Þâ‹«€¢”ò-íú~ÅÏþ9ø‡~åWn‹Õì i‚”âvï*b_HV  "VBFàñh‹Ü €Ëhí°‰bS*AÙ²ëkS‚úµ¹! lÑù‡þôŸü¢Ñÿ«ª¶¨þ_cŸõ×Ç©úü¿ã'ü€ðÃþ¢¿þÜ7ÿ/þçŸO1am*ÏF*)u]Íú·Žd¡Íî˜Cðœúa|u­£‘­¦y�@«bUA-Þ—Š‹¹ŠÄØAV³¡†xŒÐût»¿-ǸöñÉÀô€@ LMô^´vºŠ@´YQk~±¯uXµEÙ àÄ8>+€\ |a@�›×‹Û‹=ûju K¬òÀlv‚³gc#ö1ÏîÓªæ @…‘ɸ‚=+i §žÇí„7e'àH·Ö¶s–î Ñ€Ý1j¤_Såöä�‚A5#�B9@I·Ï9hŠ]k¨Ò**CÑóÖ/Ü n,ФV'‹­ @|+{ô„§í(ÛØãÿwxšÒ]·üNVÞ«0"ªòˆ«ÛÀÿ®|?Ø‘û›I©“^8±[`û¿ñœi×c‡s?Ì'^ßG2Ö°Y¥M-¯º…ÜGÅi§¸'õèý(:ÃýyŽê ./e>è¾½h×°tW¯¿³þ6h]€¶¦»¶ˆ—êùùÍeš(Câc°()-ÚŸó*æx²)îçÕŸ5¡ns¶º¹‰¨¦@lc²† [. Ùœ"¨ž‰Þ@]¨‚9 ¦Œ)%HÌ##L)`šf\x†<�D ]°*P«úw7{NÓàÀú÷'…ö¶F^i]ý‰Ááu$ Hu×¢‚Ç{ ·}œ$ŒÐGæl6�eÇö �Ï/äg�uÖYg�õ ª“pÖYg�uÖYg�õŽTÎyX8ÝÛú�<�«-¥”p™gÌ— Ršø ›ä¶Xe`û„ãÎ.µ•6«2¨ûÛ¢Q¡Ü‡Æc‹"}ñµ�\1¤˜°�Y’çb›ÍÎ}$&4«f`Xü+›-}[ÜbfT·l�¢ ›Õ|©Œ™u½A«fOÝÒµ+ÿ¥îÕcï¿ÿ>>õ©OuåWŠ‹¹KU < n) SŒÙö©ƒk› ªƒqdðˆAÍ5š’–¥-¶¼[`*SJ×ôlç“] «®Þ• H)à0™­uàîajµ¸ËB5ë@öP_´‡@|!¸8ÉÀPfËŸrF®ÙÁ�ˆ¿U°¬!fP¼î²iU*PÔ�Gc¶h‚R œÏk¹±�ÝŒC·öž¦Ùºƒm;à ¶¹ »³!;Ù¤‘VJ)]%"ø£ä?üe~E»®ß𠘩gV‹¬²‰"hç`ûÑ*¡Vd*ÝÐw$ ZözaTò…áùj-)A˜@U6ÓåˆH €øá?ûý¸>½Ùõ¹w©¾•eÀÏõ×?tüã·þ›ÿ·ðƒþ4€ðgüù¯üš¯Í*Ú•”ÖO°"|üÚ€“íeÖÆÁ\Q(tu`­E,΢ Ô�qã‰6ëF„÷ñ½T'ˬÝM&mÙsƒ34F³Î€:¨:¥¢ÀH4Udö7皆©’;lºQ 7W!B`‚†C¶»íyøW·,tmŠqó"·fkCÒá™Ö,ôA ÆLq?+æЀ¢Ím£ª@´BJtŠ»S�Áî­�\±)æL#ªPÜ¿Û|úý¹ÏNrbµc2uò?¢Ø²½C=¾ÅÁ<%ðÚ›‰ncî™Éß@jCìÈá~¾{ã[œÌ)åÞçšCÓ­É|� ÐN²ÛÇ ¼°Ó·ÜpZQeØÞÑ)áÆnoÒ;ÿŽù :¸ >öEÖö1ºB�b°s"؟ήµÒâî:Ðx;œÞJ xéÐG“P†zýú �ŸûòWDH,¥²ùÔç-hšfÌóÔ L„†"Ä. �t0ywCÜ®·�yF8„ »m˜;Ò`o_ͱ£»§¸Òž9x$VDJ80æYñ“å'ìn¥[0½ïDy¸åȈOýšˆ_WËjU‹¹èæêdQ"Ò];hgÿï13Ä3Â>3DJ�åÊk¾±óßo·Ý³é÷‘{’ÀÑàA`¯z—`Öâ²îýž(ìös<¶Ñ5ªøs°6×(b`pÌjÑ�ÌÛœ'àsNb6Eý”0Ï©SÛæv>Š* Q5Ï�nì:ÐãC2DtÝ’/Ž1 ãy6ƒ~žN4ˆ1IìàŒ"Ò¢ˆÊÞÍ·cìbg�uÖYg�uÖ'§NÀYg�uÖYg�uÖ;RÙsémÁj¿è]ù_�!bšgWÿ‡�Ò(4�ÞUá- ¦8¨@Ôí£7k{‘º³÷o*|F©Àº}Ö�¹`ŒØYƒºŠ±�â!D¤)!ESm€\Jî¶ôý³º)êí8Lcöœ ¨ˆ”M‰ÉûÌá*F((-�Ó�#¦ˆùá�xõê_="Åd×A3´ •´O®%"WÚz&3È]Æ…õÚ,=k�H8ØÒkà®ÊJš$ ¾˜hm’S�ù¯¤(ÞGšMh[ØHPƒäÙ`1E$·Ç­ÅÐsL±˜*VéŒô\ñÖN•‹ŸƒÛ™JuàÚúhL1Mˆ)!x„C‹£h× /xçlyº9ƒ8Bº³EËA7 \fÚÜ'Üî»-öW¶àÚw›Ò̲ÞíoG‹Úæîà¿û–vî?ççþ·ñËþá_‰fBxßj?³ ¡Ò îdTTS0à FUPˆD@ SÀ"@µö8%�Í•p D¨ÀªÞ‡pofþÔwÿñwÚÂõh-ûóüõµÃïžÿðøýß à;ýõ]ÿ/ù¥ÍÆ…0z.ïFìˆ2H wðH“»ÙÁŠËBA’!*ˆ7×f°N "X$@áÉs�ÅÇíí>QDñŒzŽf�ïŠÃCSÇë¨ LSˆSïŽv'}qý¢©+¡ÚØØî§æÂLf�4€o �Hç@¢jöRµ›¤n Qðç$Ò„GÞÚ�FA"(… ,ÑkìãÒ'âÑ ¢�¦~éq;#ÐÅÄ7ÙôLÔÇèí}ÔÈgv­’¡,Þfí ÓåÃçF‡ÿ£þ»÷í# ¾¨{ÞÿŸTÝê— 0üH�zÛkµÛ=Ô¶K Ã‰GK{}ñ˜öpú�ûºê­ Â0Në®U{»{w ñ9ãð¡î¬`ÏÿÛ¡´¹  “Iv&t»;Ûos+½ío¸8‡S=#ZÍØc¿û,ÏÏ�!"b"½�úUä)M˜¦ÔÕ-3~œ33O=rb¸¤P ]YÝæ!zOˆ*XØ"7ü>ìÄF±q«„Î1F”š0©ø?Í�ÈÓçW²w”ÒN ƒK€ÍÁ»ßOUA"6ÖFꪨuÛ·»†7·…¡=ø?‹›sM)¹Ç(Ý Gu8í¶y{aw× {Ëú�»®È€×zµõ¶}m×àßänžß=z…†9îØï+ð¢³ÀpÇqî~rÝü¸õ—öu°Ñßç½ë–ƒ=…hóܸɠû7èÞÕc$>Þ¡2aÇrп%ƒƒ^Ï×ëû™H•šaÄü'�,iªf¾‰ß€6"l@ 6/S1à¶;E*‚»f¡e­û8V@Í}bx΢:ÉÔÝ-¤65ùFŒ""¤)í€pb¶~5Œ ì¶H˜jQM*�°uãF¶jv1�Ìàà¿?6µ½@•7WUDGˆÂ~LÜZÔÁM?öïû{g$ðpËî#°úùÿãßî©ÿGûÿÑö †oÇqÜöq?cÔAÎ ÖuÁºæ>×oÎYG‚ǰYï—~­Û]bîQ›Û–8‘¶Šõw…Ñý-·EH'ÄîÎ{ˆð±÷‘=×{¿öHìFÍ�ø NöØ\ÆïN¡Ç5bÍYg�uÖYg�õÉ©“pÖYg�uÖYg�õŽT›m‘ÈTÆL¦‚¾·8Õ¨„ÍFrPÿÀåá¡“¸ÞgwŠÞ·œ–ÚûF[{¦Ä/¡ äµgÑ·RU¬yõWî畦„W¯^áÕ«÷ððð€˜D*žŸžmqŽ3ˆª+ºhg¯ßÛ¨o»-tJw=ˆ1¹ºÓ­á]!•ëf5_«ø±�<Ñf#l6²tTNѦO¿V¦‚]÷§æV°¯M±?͘ ¸qÐN7ûÎàùàµ*”#RœPç �Y•Ƹ¹bX¨óÕ[¼‚&;�˜"æyöß»{DzFºF,Ï Öœ-³üð�Óþþ¿T¿À_¿@ýÞ?ñ=ßàøC¾ÿWýª_£!sQ‰“÷ãiîÈ_¼/9C!,Џu¿©Ç™G0˜v2�êã)³¤*#®ˆ9•Ô\QP�hãgn'\ÕÁQñÞ–ySy;€ÙIê۽™B£ís`+!‚ÉbVZ[TâÍAAHVŒ S=F@íeC–‚Iý®)(EúøKn� C/“e9“هǰ/¬éŠÍñy`/Íå–Ð�Ú3Åžµ›ƒƒ†*þÌ¢è´à™:6GPLª@ƒî2¯K±�3‡¼µùhS¿¯·»5 àúŽxt°ˆ?\ã]>ü’+<–¡cË1»£k:f·ØwÓ"S¶3ºc�ȵ¿á À"ºUµÛMv§¿ÿûãûúï“ è¦Í^ºOî\9›wìNPð¼Þ·„sÐ~Iï‘tŽD€ûlž�sÂ/�Ãm•²¾b"€80õœóá~íàÜîÏdšsÑÌÚœ$@EPtL HUm‘I›E¾Ýï°øf  hOᤷAomÿâ*úâvñ¡†¡¯Ñ]KûoÑæDF¸Cä7:æÆwmõÇ9!×É28'5µøól¾�Ó ÖŽ‡vsh¼%6`t3|édá£SÀøææ¸šë—l®\ªu·ŸNBÍ6g\×ë² –Úç¹1Æþ]¦�›]kÙE#Ô²ENMÓ„ÔÉ0͈æÖQdçZ##¡ Ý»zþ7PþHzàFÈÓ�„ÀèÿÝ·åû*Eza‚³Î:묳Îú$Õùd?묳Î:묳ÎzGj¿°FÁ0£ƒ›÷Ò Ù«öÛ¶;PRk±¼ÇƒÕ丠ÖÔT}aµJ·»×ã‚£ƒ¡22å› Ðu]±,WÏ­ˆ1ažf<>¾Âû|€‡Ë!FË�ÅõzEI-¦Àâ 6åKɵf¬}±Uj‘‚c@Š““¶2¸“ÃÆ{¡‹»)9{L‰€¥M„šq‡ˆ–}^kÝPêYÔ¥2RËú¥Ø˜•B¼£Õ¦j?(÷ïÁrúòäd ßÑÞoýàð>ÐÛ`·Êoý¦ÍzÿØhÜÝ@8¢ý.pï8zþÃ=_oÛãèmßx_D‡£¿a80lˆîœØ5þK×£Aøz˜›?A´ÿŒ?µvÛ§;îûöÚßÇMåMoé34†&  o«’˃?p ''Ö>7m å”&¤wÑ?ã½ÑîaŒˆÔ�;šU³ÞW°ZLQ‘ö9_›ÿ±*BØÕ]û4硚±,aˆ$º�Ûo—yoãn}H {÷÷ž7ßνcTlünX½!´È‹IÊ ìq!!€yœçnãÇèLà’}ÔÌðju#±ö¹�Whn%âc0ïÔúýýÍŠ^ä.Ñi÷݈éæ6d2÷V `pO�Þ$-ï>çÕ\¹®FPp0òoJ!8Æ´#oÉyÍXSFŒ«_«Õ2ÄÖ0„P7)ïæº`ý–˜Ü©ªb0€êà#ëà€s;.j']µ>Ujµ¹¢x¼@q76�y¿¾a¸.)™ãÖ4ÍkpÖYg�uÖYg}Rê|²ŸuÖYg�uÖYg½#•RÜÖ˜M¡ Áð·�jÍ^T1O3D¹ä¾ˆÕAGktÜÀlªÃ.³ðÕ`ÖÆ®²éj›Ñ–rÍ+òš‘}‘-zý4ϘýbD ¡«¸s^Á�‘bBšRL€\2VÎx~6ò¸èŒ6ÎÔmÞEªÇ9dçTÄâ]¬I-{|o‹½Æô¨”îòàÑ/!2BJy³Û÷û À‡ä�ºq|€G{‡¸uÓì�àœ]ÿM ¼Û®îÞyƒî÷-Ž–þ´Ø]àÞø²·ýIS?ÖÛÛb¿UºëÐß¾½Ç÷ÎÞ[ô ®8¶ö�jÇ­‡„½¥+ŒçFG…;[¾CØ]ŸÝu7r�¾àZ@ç€;g{÷ÜJ-¯dÈ¥X—µs�rì“2DjÔÚçz}lqw�@´Sëë8«±²6P@®Jödç-æ E�´S•á°Í9,›½@ö±­÷¿�¦Ö|òó‹�øR·x/š¡¨>žlªoÈØÏÕ{É}ŸQ1Æ};Å€(©ÛØŽ#`û9l?‡= Ï�û¼«½¤Ïå6Pû8G­ÿolðé…h²ëÓ�¤Bx‹ h€v}¡nYäuµø(B`¤i²ï®~Ñ#V*A}.¼m×¾G-×Å{¢ÉI®²9 „”0©¢ªZÏð=¢J‹=ƒ[TU'ˆì÷‰èöÞmÑ T÷-žGâßÉŠ˜»‚Té±2Çío›„iJHi:ghg�uÖYg�õ ª“pÖYg�uÖYg�õŽTJ[Ìç:øß”íDzàì꘦DGELÑ9‚Be°³—KÍQIe•wö›!p À´‘‚;Ôañ.ç9¬«YÕçRLÉÜí)�Ùž„#Ò4a*3&)&#¸m)] %˜]kÁu1r¸ÌɬñÝz>ùâUUAFFqÅk­âYÓÞ�]djž–k séÖ m�“‰»âL=º”½‹"è‹ÓªÐl‹…šÕÎFÌÊG2´¦¬¨ŠêÖöK1à¯kO�CÀ4ÍP�‘r6«øv ]ÙSkAÉ+Êš‘Ws Pž0EWúF¤€Ö¿T]…Z¢«yÅóÄ`F©Š* –u“Bt°1î ‹‚"¦äÑ0`Ë”|„R+®yú"oýœ�¹D³‡¹€”‚JFÍ¥+ùT1F<>>ô~šÒ‚iJ(~ Ûuù=¿ç÷ü}"òuí~ûºoú�L~Š@ÁPª�ÅH([ðƒ Zá•�¨0@a#˜úJ@…�¨�ƒÅ PUÅ‚ `Q B=T2GÄøÑþóøð§þúî>>ëK²þNÿ€ñÿþÿø7þ¿þ¯~ß/ý¥¿\®ÏÏÈyP'LiÆ”ÌEbêSqE»�Œàd2E3\�è.2• xt5%º‚Àv_EµgQ ¡gd«yδ¼íô‹TW€ñX„°Anó¬ÒÜ硃ò´ÙC—ä.9AÀÂÁÁ8iÏ½Š®¬wà&† ±Ÿc•Br÷ý86»psvPHlNÍ9@oì½@X^p‚=wôr™® „ÕAßH.9ìø÷uOÙßDï#¶ûÖÇÁÜI È7óK–úí?´Z÷PÉ¢'î«÷?âàœÈ@»�ÃÇôø—[»ü[_‹»;¼ŸÐ"Óép°ã1Ð ûØïl³ñÞïx„Üip ØÇ#ÜÀö»�ÒmZÁý¦ì$�F@Ú}ä%’ÑÍuªµ<ªH´®«;q0M “»ms1íò;Ûxöø"‚r'KU© ±ùttG‡&›ì\TZ›Òæ´¢UŒëjn›OÖbn[ݦÿЀG@»Ý×âQIðy|œ�­4f¼+’mþ#ãûyŸ×Y*ˆ¦½í;u7fÞ¬dŠôIM÷Î…ç€ËÔæf#¡³½ÿî87´Õ½×K·m6·”m{¥¶1ׯÝ5gT©l¤áiJH=r*ö6‘CìMû^оë<_Éž—%vdzÓO˜¦ òØtG€Ð‰^£KUõv tÑc°Ýï7íß#iö$ñÞ¦wïø-2!¸CVLî°1�€³Î:묳Îú$ÕI8묳Î:묳ÎzW&fø�–§[cSåÈÍ✑ØIèöþª:dÚÛßS4�‚òdË>ß² œ*Úð±edÆ8,jè ›*ÒŽkΞU¼)K.ÈëŠ5„Aµ•bÄårñISuƒ\éèÙ¨"²e'W[¼ n ;Í3æËŒé2#„ÍÕ?�Ø`ûaâ]ni­æV *žjm¸u¶FPº]Án ÏR숩«†Bˆ]×Ú³VS­%"å™-‹–pOäUo?S“­yE•ÄŽÉ3æ±G1�_{r”¬¾3ÖuÁ²<#Æâ€)%�š¢lž Ä·sp’@JÝ2bÅ_m¡¹V…Hé} hùýâ03cJ±+[óºCÄ•r£ ‚‡ËldbP´µÌÊÞá‹­ª@)®h3ES+"ò,Ö€iJXÏx]×޷͸üv?\|î+~¾ò«¿¾çs›xN Â`VTáNhÑäîûß—ó™ÌšŸMâf ˜êZx ¤ 2 D 2 @Œ‹� ªF¨°ºo‚9죌 þŽ?ùŸ|û ü²Šü*ýðw÷ÿ×ü®ŸûßúyOîcäÃÃSš(˜›FÉXsí6Â!FL®‚±çG˹&0töñ¸*´Ú¿`a9ÚNp’¢�AŒØ¢ÒÉ�u%í XÏx?ØÁ�ÿ±Ë…÷±8¦Ø­‹Cxxœq¹<`ž“»Ž(raÔjä»Ìv?2o‘96ô™•vS�êÕ£’lNT„iYÉk.ˆ± Äjq#:Å„r°¹Û�+ÛyZ¼I4‡—Ü:œ…pS {tJä Œìùô·ài'x¬Jß?b˜•ˆtš.y'ÜVÂúÒ ëÐ7OùëüÑ*ïím›Jz Ý9�ŒˆÑÀiUŸËаìAoûË¡ò�`‚{Ýn8g <¶¸$Âñƒs<¥»®ýw±:|ˆ^Þ¤m�^r8D-(n ä‘5t`ÑÞ¾^ï Ý/Û½ÖÑ;Û¢q[ÞwèÐBûϹŠ>×WRÅ.•¥äö§)až¶|ru¢ãÝA4p'b2q?ÿª‚(Ñî;Cÿû=ÕH6/d0Ù¼Y¹Ú=äG^µ¡E«GªHW´݉B8*º¤ÝÅ9P›¯2R Föôø’Z[î½î¾0³�ÉÛ~Á‰îXú·Ï4Q•èÎVG€úoíÉwœ Æüú#�cêce`îjôñ;È=õ?�„³ñ:s»Î¡Ÿ Qéí7FBa·¸Ø õkñfÎS�— Ò‰ ²�ñ¢N¬] EjAr¢ƒ ÜñkFàÒ�ˆÝQǿϴï[Ü—‘I­ýª¼¹Ü´ø‰� €]Ë1¶¦GšÁ>gNfÚûA˜;ø?^{æàq[¡Ç*œuÖYg�uÖYŸ�uæ³ Î:묳Î:묳ޑ‰YË<�É-ó£/Ê)dmJömq®)j’»Œ‹^Ù.M%bèV–M©Ò,û[,ÐrŠë.k�a®å[r°E#»Ï7px\ÌkÇ–KÆõzíçKD¨¥€ƒYÛ›âɧ<« jõ¸ƒB¶(|™ñøê���x¸< ¥É±T³«Ï«¹4"³ô´EäÕì1Ûñ·ãq[ p_\1ƒt¥cp Íèê[d „ŠÜ�³–ß*GP ¼#¦&«u÷*Å�ÝÛ0h91„]1RÄVýv¯üÝ6évPº!Œü…›Ñôè‚ÿ¢ôß\tßó›u�q¸AÏõcœ[?FÝÚ~O D›¿¢çÞ+ö'z$( «ÈïyAܹ¯ï6œ>Úª¡Öú("½ë¶9h›ã¶lvì ûFNŸƒaÌ«÷y^wå!›[:ª¿SV7àœ,ZDG—l‘&nR)ƒ´îæÔ�HÕœŒ|µ)çÇãUVwcÁîØã^¦Fü Á­à¤Bä€Níš;!øè >6guµ}ŒãL�„ÐçÚãsœï¨ïG¢èqÎoÀü¶¯FVn׋‹@Þªüo¤�ñÞþÚ¤Ÿw‹^)?e±ZSJî8sÁ<_0ÏÓ®íŒHÍÐvqÖæîÀ ÕHÐsFDˆÀC4Gyç�Øs»Ùò£bØÍ›TÃðýÉ÷»k#£=ßCÀÙÇ{˜(´=¯q?ÞaŒ•9묳Î:묳>AëÌgœuÖYg�uÖYg½•’ePFW¡˜¾v¥ Y»gˆhϱ7¥aêvùåä7eIशècÛª" ñšbiXl v�˜Ð¸Ï—¬°®«ƒ­¥v2@ èŸ%2+ÿu]íïµìëá¡ÙîkÕ�ò¥-"Nó¨bšg¼zõ^½÷_="Å¡–ŒåúŒ§ç7¸^Ÿ±,ë–õ<,x5;æL+jݽMMêÊY·“5E@ì»Ø4:„‘Ú•ÿ¾'‹+›²Æ€"TR j^‘A¨Ì�ªÈîœPk±dØB¿è¶D�y1A<³U#LÌL nÇࢊ§çg<_¯HN*I1!†Ô# MBdLb9ØÅãòºâz½öœÝœ3®×ëºl*T6KûMM5¥Ôûdô…û"8,×k^Œ`°.ÖvîžxËÌfo«êÀQÙŽ©dˆ/Ì2±ï£EeLnÏZ�ÒÕU_þEò“ýÙÇß�¯üª¯†R   ³Û&Èu@@· ¶s‹|?ä|orñ½ €:ÈÖF+`2!w<SH:n4Ø9‹ç|×>–†SÄ”š­´+]™ «:Ð#}Œ �‘B€rpAÑŠRÐó¢k•C~´Ø6*@ ŒU2ÖuEv«ï57ž˜�˜#[ÁÉk#¸Ç�lÜôüé)͈)6;ˆZtLËñ^ÕãJ$€¸…ôý÷Þ_wmLèl´;߈c” neíû»úðópMI»üö;v'Xd̽m7@þÀf”–ô7¹êØ+ÜÕ»ëÛbº#Á[€mºéú‡ @ó{`~'^Üñ/þs犠c›lD½ÙîvPt8Y}�ˆÓïá£ÃÑíåz‹À±]6²í3 ô~F‚¨<ª*©*)¤ÏG7bLì@ð0Û½‡þ2Îñ¨)Ãýþ4›ÃŽ·É˜ÐƤ† ‘OzôÕu»¿v*ñ¬›3f´mæfÏ>Ïë÷20GŸÓ™+ùøWš¿YÝw‚÷ö¢;vòÇçó¨®osbâÆîÙïßÿU65ûÎaÀ¯Û‘µ‘†åfûw�VÞbýosÆÍùat?Fb3Fš&Ìó—Ë.ˆ1Þœßø�HuO´)¨Õ«j­ˆ5Ùw·)!5",6Çqp¾jEÅÞ�­]¯q|f'‘ŒqGwÂæúÐãM˜¶9£;Ĉˆ;VÕ~÷�nhÇó>묳Î:묳>9uÎ:묳Î:묳ޑbfÄ”0O©gešÍ¤YŸg@·9 ÜÁÖ˜’g —¾ ³æÕò‡}+†h š¶8„²S‡Ú{Bº=dSX{¦1”ZÜ~Ú¾Öìjû¼ömF'1X¦dê1¥Vè²X+Ùâ3#xDASã�*$nàÿ4pͼÿþxïý÷1Ï3`YW<_¯xýú xóú5^¿yº.P‘®”äÈL0À(ˆœ(W� ù¥›¦�úÂ!‡Iu§Üb6 wÄ"ˆõ’/æ•\°`A-‚B@Ôrq[hfhJ¦ ×!PPŸŸ‘sîv½D„iž½}RLàh*¹e]°, òšÝ ‚4›1Ï3¦yÆ4™ÂŽÃ4Cª`-+–eÁ3ªÖœû5iYªµØ%ØõI¥tg€vMSˆvÝbèùºÍ†µVÁZ RÎnÑÍ›bt,\$å ¦[&êØCÝzÖú,cYü~ßïý;|s{ßoú-ÿ$R0e§íë�¸jßÔt­ °Ùe³* ‚Zx'ÀÔÑ�,ÛY|ÁL!(*~:ŠZp'#Twà÷G'i +´Ú}÷wüѽ]ð;Z' àg¬~€ßàùmßþ‡ÿ¹¯ýšoüîZmì)Õ@~…öç@�ê€vH’Ö#»*š ˆ� @Ð-nÄ:¤Tdi`€+‡ÅnÅ–ÁÞdæÔ¢}RoÅ¦¶Ý"PTk'f©¢“�r.È«¤€c‚ÉÐÉ?D*o]Œ`ÔœW”7€0픢´å1£©F ¬Á§º6ÛuYPKí;Ä>¦„iš]�i® ýŒÝN;†òã‰1ažgÌ— .³Å¡4�LDPB@.aûïR -Ӥ¾üs?{iíº“µ»T§ø'݃ò7Þÿ·?  DÞ*íëtÜF ÜŒuŒh€0€Ó4䱿`“ÿçº÷¡·€Üt$9`P�cgh?èÈ ž_7ãàKžúã1Œ—oþÇûÑ�íC´]ú;—µ›Œç4Zì"ît H$ùøèØP‘‡*e@´ý� teðt˜ËÞ4¨zÌ ±~ÛŸQ›{Gûojùï•}àÛ›St×€±ƒv‹Ü<wÄ„áøÆû·�‹9´Ä:A¨G™p1bÃ@¬R˜¢½Íƒ¢;žŒ`usLÙŽ%ìÀr;N†ON:!`<‡# ý+ud÷1qø^q$>Ü›+ÜÆÜÔ{¢»CI�„[À™wí[|^ÚÉ �1¥ <<<àññ—ËÃ@‚¨7ÇHL Ù÷CQé$ÑÏ@8z”[ þ�€ú|Uj…Q|ÝLìÉ)L]Á/¢ˆþ�E7¬ê¤†6Fö˜‰ñg'ôpØŽ“ªo›D·kµk§ZKD¦|θÎ:묳Î:ëT'ଳÎ:묳Î:ë©M¡¾ÏD¦F¬µvEç–{ìjÃÉ2ÂúÂ^-ˆè–ú­xXøQÑ»Ê)Ûvt7ì²6Uë²B¤"—‚’ r^ÝÎÝmXàòŒÍäJÍ–7_Eº¥gˆÑíG[Öè¸`BÄ<ψ¡*`xx|À{¼‡Ç‡pJÈË‚uYðôú5^¿~�ׯŸð|}†Ö 4+èMyém¨jVœdÝò“/&j¢æþJ„�ÌzÚñv1TU¡¥vð§ÛÑ*Aª¢ ¢(«-¶Vq¥W¬)Mˆ®ªÚr£Åmø‹E!D‹Nˆ!àáá��F† àz½š+ƒT<=?ay¾BÄIçËðøê^½z0 -&Äd™¢!»êUyÝIv6¹] µÙ0I“b#b°0áÊŒâN"–‡º®+ „´%& Ê;ôm[ŽéTTK¤Q�ö/HðåŸû üʯü5FÊ@Ó+{ŒE݇:¨¾0«< \ÔH˜�`DE!l}‹Á4¤b¶ê±:¦Àˆ�ž—ªÀ¥³0–:/âûþãÿè�Wj�cÎߎúÛqî_„…_à;ÿøÿN¿ý«¾ê×= à Œ°š³K êŵT4­ ,Ä-“˜±ƒóš2Õm­»q=+ª^{~üêæv¾Cø6Ú»û™±ÙêW³àÏ¡ öœeÛלQ†gL»N-Ò%M Ì6^…¼öýäu”¹6–†`w¾Y;G‹ÛzLŒ¹¸²¶©\ýïFz³ãY—R+¸YF'8ø–ü™,žá¢ÅhÖ"AíY—RÂ<›uš&¤8m.8ª(9ƒý,ª5¥Œ)Ñ7kúfjõZ]!•".— ß{Ä”&WùQjØ­óEŒ¸ãrþÀrW”z_Ù)�EÕÆ;�4÷QfTÐB`pãÓ>Ó]T�k�.W0¨GÚ,늲.Àé�ÀQmJɬ½UQ‚“,«9Û¸[+jf2  6ðÈ�=©p0¤ ÖÒŸRÅÔÿ¥`]ÍED¡¦Ð%Fàè[2¥µŸ¿h#‚…!/Äà6Ô›#Kþ¾¹p�õ©ÕcvDöó�p°hZÚZ�]Ïv$�ÃõÅÜ�ÃET›¨» t=¼ D�z¢=Êæeâ’ŽŸ½é/nSO´Óß�k§¾ÇÁŸöÐôcÿˆ&Ø”¶÷ìô75ö�?н£yK³ÐuÚæÐú£^þîöŽ*}Ý�_z¸é#ÆHJ[|Ä íô·0úB¡�P¤Ðîè3ÎUí9:Xç¿0~‹(ˆ¶+²EˆÈõÜè$€®ù—Njý¬]^f‚€û}Å�m æʇUí�¬ÐsÝ™’9"‰ªE�w_*¹ì·c¼Uß—Ïk¨Á«ÍÍ[»ÒÎ ìx,[[�íut�êääZò/ÿÞ1ž÷8NÙ˜x»í»/~Áúÿ©À�¼ZâæÜå¸âäéîNåÎ1Ó4™ëÊ”cê`8ʦêo$‡]¿pÒI#o¨ @EåŒL-Ú%"sˆb"ÔM…!‘!•;áNÕâbª*„,æ:ÐzŸqï¬Ú3¬‘¨h7"ŒÎ5íÙ.0êý뽋“ Œ³Î:묳Î:ë“S'ଳÎ:묳Î:ë©fonutK0ð3ð­*¨Ù&ߨU†¼Ô¾�Ê8½·ÀSÄ<͸\.}!QEQkÅR-¿}¹^q½^ñü|E©PAZršp™Í^3M“-@©¢–ÒÕ8íxÛ‚S %&·eÏE·ãŸ§ �(�«˜’©%'S»—ë3Ö¼âùùOOOx~zB^-ŽÀì8¦ËŒËlŸ ìzXö–mª#Wªó`ý/}PA¡e›ÚßCg¨/6 j-]­/]2ç9�J�"¦³ö¯ÕœšòK1›ú?N˜.ˆUëš¡ò²ø¢d5WØb³YOO˜æÙ\Öˆ–Z±. ®×Õ0g•«�æ„‡Ç ª¨Là0.¬úÂq2EÚ4M!2âº"çÕìU¥ôÌì`&L)bž.1¥ù@Dx^®!ÑÜ-(#ò–åÊ]©ïÛ3_SP³ØUë—Å# ’íoý¯ý$øß¨ê|ú3ŸÁ¯ùª¯Ýá1Ø�QoÇî|j$¸å?Ü®»Ta(�êUïÁfþ„àžQƒHªC ZQ ¡µÖ@#�ÑH±:èàŸý®oÿ#ý¾ÿ$Õ=çG½÷ãlïg¨¿‚¼ŒüLíócÔÏWÕïøƒðßûm_ó5ßø‰1bM ²ƒC�øÕ‰4b B[ì—ZŒÐÀdÚ2ê»Y7è îô!T$ÐÆÆPÚC¡Ž´Ž‘óä7LÛ†Àbl¬%h5€Ed¼¤ƒ÷6fBd�¨1Ž=Û,^D¤Ú8ëUxx Ù±+eUËFȪ¥d¬y³/óæÜÇ=ëvïSsË ÉÜlÄØrÁa„¡[¾·¹ÈL)!M3¦iÆäÎ3Ý`p'ˆÅbxBögÓ]Km)ˆª³4ì·× ØF¢íê|±Ãˆbgw~ŒŒL,- ¦¦\}y“ríõN¸ýþÓ͇{ù° ¦QÔ²èþŽÀ݃¥ïãïvüÚƒì/ªâoظ2#د·írØèqfx— ÑÞ(Ûö�§Øîu:Ì3?Ãס-ޔбñoÈ€yާ÷ñWªJªBÀ^9n!eç\2>'î½úß`÷|uøø\Ø�Úbs¼›b€dt˜Ð�”Ûú&›PÛ¿D#TjûÑ‚ÿö‡ô1¤80«j/ëâ±NCÜ–Íõ÷ãùÝSÖ7€|ûîaãå–o?Sý»ÄÖg¶<úZíyÓ\HØÏGǨá{νk5+í"Z0Œ×¸!?�ûiß�z,€g×ÕÈÊ¥z„3RL˜ç‹�»NvÞTñâßSœÌ:¨íÛ÷©�4ÍØK<݉‰ÖŒäîgís�\"( 4F‹¯)ÃýÐÜ]ŒE¶™¢Œ71©9D¹ÃT@8´ÙqŒ9 í»K)ù&ଳÎ:묳ÎúÒ¯“pÖYg�uÖYg�õŽT𥠄¥Ðhù)�«eÓÇÀÁTþy]Qˆ°ÈÝöÔÀˆ¸�@@ v–¢ƒ�dð…£àê•”Èsà›òp¹.xz~6�=çn9¤hyï󼩣ç¬×RQTQªÅ”’QŠeW“«ÂcLfÁŸ&hŠHÁ”9–YŸ�¦ Sr%y0DcYW,þ¿y~ÂóõŠuÍfuiJ–óùð€ÇÇ f?§¾ÈæÖÏÌÑsT¹ã"MÕ_|ñ9TBˆ… dñ°~í²“²/Vh”Œî"`ÎÖ–ÅOKˆN#@@˜"¦sQ–e X×Ëšqß³wCÚZz<…Ã5‡BjA.Ù^ËŠõºâzÉ`ZÀ�PŠçŒz~qŠ—y‘¹”œ­¿­+–e±¨�ºÅØÂ·/8®b`ë·ÌN2°£yz¾"¯+®%»e¾e{›�usk¶ É RóºU�R�Õ¾…ƒí› ßömßöùg[ËüºoøÇÁ)Ú5‰¦d³Y¶ª9�70CUQÉ€%rpSà?û…íIâÆï+›,`ã*0* ¨ƒ\F^�~å‘­Ïr`�1¡;Ûï÷~Ç·½óöÿgùx7‹ÒáðQÛþbë‹Qÿ¿ôÙ# û3M ¸ÓF3€ÿóïÿýÿî/ðOÝ×ýãkÎ¥Û!bS`J‹)}¬¨2ÑUT>°ìkòÈU“?Pjjvº×ù_èˆÑOí¡hÄD©�§Çø�M½“%îYÖ·ÿõê�Cß�*†{D‰œvG@s”9dñçÿñ¬úXCË=Džî:Œ·H#ÚŒM²'iØ}³Ô¯ãî G^Â�3í9ãñݺ Œ}Mä‘ÍE€®Ð~a;/Ì߃'T1£çØ·qo̘?Î]�¯‘ÜÚòé�àès†>þ`º·÷ßSÆ�÷Ú�ec�Ž]Nê p?‡æâ1‚ÿ£‚�_Ê‹ëµT'­ëŠZ‹/Û˜È67:´ °�_xÁV_ _|¼-µîœº˜†8,?¦v� `ŽRa7n�Ï-½s]Ž® ÷Æ»�ó·ö÷7Ç�R²_¬ë‚Zj')¡Õ¾o4¢óH~ØÎ±îžÝ)% ݹQˆÚœ?!ä¹LHµØw1lDŠÀ ±Çp”Ê`ªÝ�M´ÇæÀ£wÇfc¦(™Á ™Èï�67í÷C•]|Ìx^U4dÎ:묳Î:ë¬ON�€³Î:묳Î:ë¬w¥lýÛ²‡Åò¿;èÁÈË $2;gË„€R òšûbÜ”&^ãε->†;‹�}ñT¶…T†Y"—Z°æ×ë3–«)jšê'¹åÿåbYÆóå‚4¥¾¨¢æ˜}iÎ+Ö5wªå†–Z‘j´EG"¤�lÛóŒ‡Ç .¤”,Ë‚e¹âéé�åÜ_¯Èké±)%\.xÿ½WxïÕ+<>^0ù1õÅÕZaŠ~îYÔÃC¤ JÍæ\ j ½˜$GêfÃ)¢(¥:©¡˜ý?\€Ø3›·äF¨0uWE• ˜lR·|èËŒ�ŒŒQkÅuY�×böü1�9šÕu©X–€6 ˜7—€išñððàç(ˆ!!Æ`€¶,ëŠøô uÚ¶ø™]Ä1Ï@šR·«-yÅuYzÄš7õДbŒÝf˜ 1Áh"d@¤+Ûòšq•ŠuY‡XWÆ– ÓrR#¾¯q£–IÝ;±ãÈbî¢7ýˆht¿ëSíÿ¤=_®ƒ�Z½}Lo2FüÖiôò½ÞA÷�km±ôò#MM®w&…Ã6�´‚åþø©øá#!€´;CìÆ#zÛÕlCÝ;PËÇþœwÔãYíþ®ª‘¡ï”ÒÔ�0Ú8Ðô>WuBS–åÀïûÖÆX„Oßù¨®ã¸½‘Wö¤5íI;® ”¶4 ínVºí7n<4’zF€°˜¨œW,ëbDͼ"ç²Sþ¿¸ÛüÔÛžñ"iÐ~¿Wý·ñ¦ÙÛ«Ú>j³²\^Vôß{¶«jŸ{�Žo{NÉO»óT¿°ÏR ®þÁ´À¦Ocô8¯}»�‘�PmÏÅp÷˜ŽÄ‹Nfs× ©mý¶ %! ø=ÉÄ(Ä�PkIEU³Û¹!í†cû¢¢¤FÆ£}ÄˆŽ„’*�4;’¾Û÷ÁFB9 g�uÖYg�õÉ«“pÖYg�uÖYg�õŽ;`™æj ¡˜ïh[è35?÷E¿¦DTdÖ›5q³ÞoÕˆIJ(]-y´¾lv�mq®Ô‚åzÅóÓSWÓ4 öryÀãã_áññ³°Ѷ+0òÀb ÿºšMuñŒå¶°kÇA ÄP�i¥¦)â2Ϙç bJ¨ÔÕ€ë7Ooðú ¯ñúÍ\WSÉ›²'ááñï½zÄûï¿Â«ÇGÌólY×µ`] èÉTP‹-´Õ"ÐZPx³Å')(|OÕ\mq¸-=m¬³g½MVÇnu7"Ãozb·~&çVg�uÖYg�uÖ»Q'ଳÎ:묳Î:ë©–w.ºE]á̶˜¨mY¢EÄ€Ò*›ú¼Önùy³ØÔ²íEq¹Ìý÷%ßÔ‹†)"לq}~Æ›§'\¯Ï=cúáá|ð>Þ{ï=<¾z…Ëå‚ä‹’µš‚¼–Š5¯(¹`YßWÝ ºr…«)Ó0ìø>õ©÷ñÞ«G<\fp�RœÀ°¸úµ9¸ì¿)ÙE¡øB>©94 ØÂXë‹ä!®¬1¹­̌ĴŠìK Ö5#ÆâC³ãŸpyx@L¦N�âd ¢RQÊ3TÅ\ª‘Aj)ˆ�ñêÕ+ëgD` àè–°­˂ërí.ª[¶m –Wm¹©¦Ì«¥`q»Õ"rJ(Õli›+™5®(¡ ÄèÊ߀'LÓ„9™SCpr…¨UQ˜@µ"V;‡:FYx¿©U­ýí̱,nUý§|…EÌøM¿å·öØ�D lJTñ6i⨼}S" ÀúI2›ÍD›QÍ@¹ã*wI T À­›Õ$bdäþE�AŒn×M¾÷;þ#;ÿ/�Ú�Tô·úÿ—‰ø¸uo»_¬ÀÛÿ—Þó3q^ÇÏŠHdæýwÿîo}ø ¿á7ÿkµHU¨Ö ÀÂfAÍ:XÝÄ®ê yðøvù´‹@Áv9ázï˜>Æ9µõeŸÂãã+Dw)(¹ »½»©oVäbÊœQÙª-쎈À1øÂTp ̾ºÀÀÿç§'¼þÿ³÷ïÁ¶,é]øû¾ÌªZ{ïó¸ç>ú%�Ä£õ² ƒñ ``†±HH# 6ï<ÌÄÌ?OÌx&aO„1ƶÇaC #K=[ �d!,BÂa[Ö£Õ’P«Õ}ï9g¯U•™ß7|™YYµjí³oKŒï½Q_ÇísÎÞkÕªÊʪÊõý^OßÀ¯¿Žgo¼�çÏoC„÷®¯®ðäɼöê«xùÉ\ß\¡ó’Nã xŒÁšk1FŒ! LšdÎê0Spe{L67kÖ¢‚Õµ¡—­†ÉP[p²@[°7Ri,ë|Ì–ÝZ¬Éè» BˆãéˆS0ašT’�KgyÒ®ë³ÂUƒÙÄNã !,ˆ�sf¥ß™UµåT›õ}JjäŒ`Q)ƒø…#‚s´ÏJ³�j†ª5zµZð\`Ëm¬z­‘À�á²*I³íiï; ÀÃpÀt0uGSÐÖ,mš�"i@’Ôèk¾®sø¯¿ú¿òþen}þïø]xüÒcSíb­H`Ù sØ"¸zj“Tp´ŠAÅÜ þ#p™PçÄŠ Tl]‘Äì°3¨’’  — oRüðýwøèG>üBåÝ[¡.�à/úÙ]?_ÿþEÕ‹ÞÌ~_úŒû*üß )`ýº7S[ûX"Yü?þÚ_û/ü÷ÿþ?ðW ØR@ °)B=,R#r'Îàx±«&‹íȹôÌ`auÝ"–m&x…ÈtmV¾D8§“‘§D10¤EíKvrÎ>ßû}çÍ…ÄQô @’ÅG¶ÖݶÏÌå¼ >÷Š«‰½×œGÌN?!äûaˆ1¦œ×LðΙå¿úzŸ+Ä-vdÂo,Õœar\�Hª ¡ v\ÅÅÅeÐS*Á)!ĈÅ(ßÏ õ7Ù²g&眧(éŠãtè¤Uq ¬‘£ª-{Y\M@çÂð Ó³‚¹ªÛà;m)éÑÊåë}O3J[crèÜ@Dg®ÚdÓŸ˯¬èi½ïZoä PŸ°P´—hAñ¢œm¨ü›2¹¢‰Æ f\(æñÃj¶`áü?ŸZüp¢–ûuÆÎ´>¿ù´qžKàçnä„3RÁZO’%ø¿wÿúë}ðä¥W> (13B޳²X+»?±,•Ê-h;¯%Ûñ¢Jb*¤ËBÔ)DÚâ,T×ÚgÏ"Ûk¹“(bdv¼°æ·˜ŸPo×¾Ìbk©ÈÕ‘¤~vYÛÇX•ì!L™`ikRdìŸi ¼Û³ åíñ™É™'Ð UüåÏ ~ Õûe ÜÛñÌädQ5$@iû)ÍäªârVÀë»Hí~ID¥g–D²ÓØ„iq:™ú?†X¯Ç¾›Id…]È ­óÌÙg6s¬� ÐÕ} ´Ú±Ú$MÌçH@´"ÀE@9Úeš£Qæ{w#U÷·<|¤>rù/—¢ü¯Ï†·×^{íµ×^{½ƒúÌûìµ×^{íµ×^{½5Š]—�{–% ’”†Ô ¾Xx¨�¤È�¹-+͘â N{o�SG öðÎÃ¥hÊî ÚûûËTüÓéˆãñ„ãñÓhÖÿ]ßç\ùkÜÜÜàჇ–1ŸvE•¢e&OSÈÆçàiÈ:WÀËn¦¦¥jyÕ �FàöxÂÓgÏñÆÏðô�7ðôésœNG†¡ÇÕÕ/=zŒ×^}/¿ü2nn®AŒ§È3Bˆ`>B²òz:Y,�hVå»ä€á™@œÕ�ŽAŽ2H¤ ¤‹ì\vFÌ^ÉôõÔ¨ìŠêŒ}VÝøÎÔ¤Ùæ¾dÇ)á¨G„iÊJ¡jólNÎÃu¦@%"„`rƒYò�%¦�á8f ƒ�7ï|mz‡�R„s“3D³þOLp¢U!ì&—A2CŠmÉT…D¦>£LžˆIAY¹ê�)®$gœ|çquu•É °±f¿óv|ì=jÜBŽHI3poŸås¦+€À'’Ê—|Ù—é MÒ@‘Î$ª$ övþQ.9äë2« m_ÌV™€˜b?‘€qU½²êL€ ‰µp‹1€Y[C×~‘¾A‚¾ãoóÛâ>Ö‚Ý—€ÿû¸l½ïÍÖ›}Ï‹€ù-‚ÀÏ×àŠÌ±1†ÿŸ¯þê¯úþßõ;÷ÆìcŸ »®¼GJ ]ç³"SËknÂÓmÚ½ •¥Úd’¯2ÌÏ á 0£^}aœ*HQ”îh›óíÍRÛ9†÷\ãÊvDRÒª"� "·È$7"UàÏwÝLˆröÜòμ|Ï÷­™m7�Ö c±_ªËâܘëMÌ=3pV@%רÿËxi.ô)¥.¥Ä(“¯˜Ù9"#†S•kÑx¢\Sñr8s·§—ŸAê4×óµ5¿pnè¾°ßo¯Ìç‰Î/¢üaÚXÊoèÊ[tM@kÛ¿%)§’g�JB Ö®bCð¿¤Ð´Wàž„TÔ´*`2Û}fkôuÞÃuF6)�˼cÄÚHλ. !Aˆ4\àRÊç:FLSÌŸ¨g0¸6:aS1 bšòûm¼,ÃWÀìq8@t�Ï6·±f*—|î¢ÀLª™cvÚZšçŽá:Ö>Wñ›>ï·àµw¿»¶¹“ˈ{ƒ%eK`†f`Ÿì›SÊ㌙‚JF( „®q�Ö¬¨Lª ¶|àœíf !Çä4WI BBPÃ`E¾ûÛ¿åm¡þ/cßþYþþ áð¢ß}<µ*ÝEHx�¿~Ý}‰wíÏ}öË®ÿêà|ý×Ã×}Êoý­Ÿª‚%óסïz{O¨C�ÓÄ®Åÿ0õ^ÜèÖß dä\WUUQ‘9/Ýåk~FÕ×@•Tkä”sÀcqWQÈ�Xá꽕´ š X…xæ]Ž+1b„så96«SË3âÜJ{~þŠ&ˆåŠØ=[Kž½V�»ì«f‡sá1ki™·Çªê“ˆO1RJCJ©ËñdÏpÇÌì z"xˆ)õŽõ@ÌcÍ<@j÷•oÍ®»`Ÿ3À¿>Û6TèŽþýMl3¿§õXÌàùzÿ©’犵ù†ë>.aî¸ðy<'={¯n½—ηQ^½–3û¡ºdÔþ’?]¤_l^py}8šÄúÍó~)ð᜕¡çïnˆ[à¿^ÿ ±¼÷x:=V-ß« ÛüÙº¿ÜSÝ,oÇŠ–¹ÙÉÉÕ÷×?W÷s"nûº$•ûs^'QV½ÛÚu©ä— ~·$ÝÖV¾_˜#\rP§w>Ú}äjÛÎÀ-÷®`>�h•ìÅ4à^Š{9wGX«ÿ�óy�K9:E®ëqx3ÏñöZîŸk�¾D¥Œã!Œ™,«•œÐuÝL‚õ¾Æ¤—œ)±p“ ³Ï(ÏÙâX£ªÕ±Šóçt]×y»bDlí×�ÂZ‚HYs“R3·ìªî,úD5)F·çê½Þ^”ï÷�[ÆæÊçÍw¾Æ·íµ×^{íµ×^ï°>ó>{íµ×^{íµ×^o�êœ7+UÄÌz8¥Ú.*k³–0fU1ƒÔ,ÛUÞÛ¶RÓh,ÍNßuÕªÐubßA’ehÀ8� 5bÊ fÇì³ÂÅåÌùP•#!„lu\ò–â]n¦³lð¹a?wì‹â+¥„"&æj¡?…ˆç·ÏðìÙSÜ>Žãí-Â4�`Šï~èq8ô†Þ™‚ß�œCŸ� º¾‡ï;ø¾‡ón¬ Ù"+ô�÷–=]c9Ob`qkAK”€ˆŠUin(†l+ZÆÎyŸ‘Ýa@ç=¸‚NŠ€ i, sµŠ€rDÀp8€Ù¡ï#D;0Äè¥q˜•SÚª^i™‡Ü*�7âá;ÐWej’ùc 81%x7+™’´MMÎv¬FN0µ~š­lU�ôÒxßÃ{‡Ãá�-¯ãªažIyT'P0Þ÷îwÑ_ü‹ñwøUe¬¿ì+¾Â®‰¼N‰y¶¦̵€%Ý$8Ï„„¨ 0LÅOŠÖ5˜‘qö{2Rgbˆp $a€ÅH%ŸXÉe›X˜ÙpJ G „ø½ß�§o¼þ¶Éf}³Àÿ] ÿÿ?Žù>Ÿ±QÖ¿‹ðf~>ÇÜà“UõßrŽþ/I³IV©:ç-GºQ)¥©)0Ò. ~«€Ö-qôÅJ))QÕ$"±“U4+5»­Iœ²MrV7Z¬A&™i2N‚r$m‹RñÇ»RøÞ9RU&brÞ±ó]ɧT‘GWWWïéº~œ)�ô1ûâ¼¾ø$Þý›Øm!^*vÿÐFÉ 0“M¸q,hœt7QœVˆVùî •õÿ<_Ï?õE×\&Æéò�²†Ï�ŠÅøU¢ÿÏ� %}±ã_€èzvhñÉo¶]šðì^DÛç7ÿŸ®œ=æ·eòæ–݃6ïÈàæ]d0�ãã5ɦ>[ Ýguµ°T ™ gx�85¢+5ù–k ±‘óŒ`Ô’yÊù¥L¢¢ þ»)â*�’7AÿÖò¾Ü«‹�|±”/÷nâB~Ì@?;ÛZÓyç]]›ðŽF ³õu±á§�¿õŒ¾ôL^“ ÌÀdWårŸ•õé,ƒ¾: äk`}>Úó²VÿÏNe³³@! ›ýÿ„buµqÌèûÃpÀáp…~èá}—�Éž1Ä…;A™s­;@ƒúÙ-Q /*à×Û³¤·¥³M&¥8_£ÚÊ8µÇî¼%ªs$1€0GÅHEVÆ´ ím­cÊsnžÃå{á^{íµ×^{íõΩ�°×^{íµ×^{íõ)b†¤¬HObÀoήMÁj'IP^5Šœ«ªœl…¾°ßT�9è{t¹I5ÅÙ6cˆµÉZU"lÍ,_Ô-άܧqÂ-ßb “í_2Å8€l±ÙϹ Éep©ÍÙœW•p�óªSÄ$@ ” ’pš&Ü>?âöö§Ó)[*ìÝ0 ø¾{†èLHàüyÎeûç~À�_ß�$%ptô·?½Ï–žœÕß¹‘j$… T—m“š €–üæü‹°&á¡ï0 ºþß™ÂGò{(Y³6E³Œ>M )‚Ù¡²zÔytSv�¹Â…cô½Ï ]‚ïK¶§5e‹�¬éÛ1Ek ³Yô;vHâ3 hÇhN‚'¤,Š"«íŠJÑå8ЙPz™Ea³»…ÍÙüyÎH Îu8ä1Ž)!û¼)Øñk6‡«â)eå¾ÍKfæ”ÒŸ-×Àç|îçâ“>ù—ØïhÆ0�Â\Së ¤�<ä¢svžr+Ãy@#@HAÈ$€â' 5@ øPg:Á±Í�À!±‚3p)\öI3øÛßôµ÷RÆ¿%îc+ üçãp©þyŒÁ‹¬¥·>ó.RÀ}\ÖŸùñäï®÷뤡?÷Mßô�ÿ¯Ïÿüßùáâ^ÝZ6w]ÎÏŽ#Bœ¦ˆB“ml÷e·–@è™Åxýç¶õ¸Ú¥%RþÏ@U,>E”öêUÉ›ïRîÅ–2ÌTb‹>PRUŠ8ÏÞ™;föÎ9Çù_¾ëh8S¢”ÁÀx&v,)z컎™™Œœ H)Q ‰xÇ܉ªOI\~>41ö䘈äž=}úàùÓ§¯�ÓôRᥧ—c�SL�cŠ�%¥Ç1ÊcÕôPD¨j7,6ÏCŸa847¶ÙžÖ±[všsïï´™?ûͬ·ìª½„±¬/�mù³¥ÿ¶«�ÖxŒ;ˆ>õQ:Š»°Øÿe„@›;¬¾«ÅúêS\xɨ1¡nÎZæœß¿ôŽ´ÁˆazT®Õvÿ9¯=í~eë²6>Ã6¼Rìk�;Ì3A¡Ü-–gn{¦f‚OàæñË„Jÿ-ʵVÄ1Ôõö%çžK÷û…+V¾GûÎg7…÷:ßÙXt�ýÞûÁµ‘×s®ü—r¬Iý®ð‚çó9‘�Ï“rím}ÖÖ1BsëîÀ«8ƒ-ƒ–˜,ªÕíLÄ"Vbˆ1@EÌÆù÷p8 ¸›•îüaª–þóq2ˆ¤îCÿËëJUÿË÷‰¡ïëö×nëãTIq�gë×;æ†XbD Ä1“RRv—‘9*N hœÁæÏ]Dó\ \Øõôö šîµ×^{íµ×^÷«�°×^{íµ×^{íõ©Vmi`ý rZ¶:A@QÞ qPUâ¦Â6°7†hV¤­ú†ì Ž}Î.·×8g Qç¼Y$w]}_±ÑdfÄ”p<SÌ P·h(:fPg*fÎ pD \•A¶Ý¢Ê ×TH¦ÓD1œN'ÿ�#¦1 E£ï:\ =®††®!Å„qAüaEœ÷èû†þ WÈ0D‹,H Þ;ôƒ‘ú¾‡wÞ€/¶ý£d¤)FHJ9£„L±˜•Œ9·U¤ÚµZÓ¶G×õúä¸*) @’bDœÂ4Z³6׎Þ�˜ºÎM@W²DK”Ä�£´ìD skHLYÝHJ5‹Øy‹„èó<‹!"D¦ ȾJR–®g‘3˜á2 o„³ÜP·c¨ _ñ¾Î¥¾ëÑ÷˜�XbÀ8zБ ‚Jô°k¢QTf|è/ÿå¿ü«UõóÊüûÊ?üGë˜Ì×e;~S¤â™-ص@…Ì&¼€¢E>kUÙÅl]®’Z¨œYJœÝ¸‹+ƒÈ$!dçp{�S$0XI�8Þâ~ïw×kêíP—€ƒ»È—Žï.W€³ûó=cîö_RÿßÇþùEŸ_6íw~ùœ÷_()-TÖ„)÷‡ÎG¸‰¡:Ú½¢Ø«µ¥8T\záÚ�'�3SQTª¤l—L`) ¬TðK�;SfkV73òý×€IJ"Ò¥;Ua@‰#C:!UuDä‰h`vùŽ{ÀÞ9 ýÀé*Y à�s~šB¨gfçœ#€s|L¤q<~ög?üÚó§Ï^}úƯ�·/�Nã£q<=ž¦éa ñQL鑤ôP$=\öbf0u©Îßg½kLZª¼Û·)´©Ïÿß’•ˆ6Aëòz-ˆ½.·WH�ûLÈÈ„m”åº1W*˜¸úM…£Ûm¡u(ï£{]C”Ÿ-AëlŒõÛP5â‰Î.@×�È�K縎ë"F`Vô*¤$/ÌãN÷s/Ñ•ýÃü\œ�Ö3g½c îà¡è‹Ü@.˜Ä7îóZ5ƒ©>ƒÿ]7¯ìþ$y=ÓÜ'tžªÒ³rõËõVf,Îæz™c•< sª"Lp>Û§“³h�†´Òªß·Ž@cÁ¾\7·s·ü¾ËŠuU5ð¿ï—ê—e:Ö÷/U[Gcƒ °ˆ4QÙ|6­Ÿ[w�Èwý~=íö[püÒ³·½þ%gh]ÊëÀÞÁ³ÃÐèò21Uò@‰][ÛÿÛ¾ù¯µˆÁÒ�Âæe�Ã`ŽjmŒDy†ÖØ„U4�ÅIµû/gãÁÕYK@Q‘XæxQ¤dÛ7CÊN@ö]…ÈÝy(ÑoDTÝöÚk¯½öÚk¯wN퀽öÚk¯½öÚk¯·H-²„µQ�Xs™7Lûkó;ÿ��¯ÙÂ@Q(ÆÚ*U›K4(ê’¶ ˜í�ú>Ûà÷Y½îœGŠ ·ñt´&¿wÅZÚ£ë<˜|¶ÑôÎ#ÄL!ÌûT‹ÙrµÚ¡¦ˆÄÙîYc˜p{{ÄíñˆqÀ„E²½®-Ò+ü&çÂÂög@ì]®ÿt怋÷OÊJzók@&a¬ÞÓØ®Û&g"Àt]\ �}uóëaä,vÑå.oܲwŸø—®ízäh¼îßô½` &·àÿLzXz*lÓ¹q´Š3°š.>çÚs^œT‹³³ jÝ–cLÍ&¬mÿ·Ý%tc®]‚SJ/•-V�™ ç]ÿ½ïÀŽ¡âêšÂœ³ÊëçTã˜æ9`¤�ƵAgªÊæš¼:dr ¨®��ãìšäÐ:«´cÚT~·ÿµìU^,ÝUsœÃ{‡®ïëïÍÁ*“ºÞˆÙn>‰Å"hº<‰Åò s'5ëÕû>Êñ÷±ö{ƒRåà*©àÒ³¯ýnÒZðsã¬P^G¤�;È|»*ß,fÁ.nÇ —�\�.›I"oc¬c Zá³0T˜€éÜa§4:‹+#,²¦Fäˆ f¸ñ"%©.YE�_HFÈvÈ72Bˆ©ò¯’è*º@«ë�Ĩ2d%Þ º)Äô¶!˜îµ×^{íµ×^o®vÀ^{íµ×^{íµ×[¤JÖùÅ\Ή, II9åÖ.“-Ô1Ãw¸¨M%viÑàb×dvjVhk†•F—s‡ÃÐXF÷Ye® ëLÙ2¿³×ó†F™$IΠ³¢¼ÉU]änFU¸d„€i4€ñtÂ8MÕ–ºï\ßpssƒëë+tC0… )FŒ>¢Ÿ"ú¾9IŠÎ; ÃWWcŽbLðžÑõ†ÁìBKóQÄTïSŽ90e~Œf½ÉìÀÄP±±už²ò?7Ý !CÕvZÀ- áV#Pt]‡Ðøàá:Ž@ŽW@ó„ÓèáÜ1Ÿ{E¯Þš�ÞÁ�щ)ð‹�°H‰°ÿB˜’ÙÔ1†¾7$,7£½ó@øè@Äp\2�Ks]1³"uLp¹á�Äšš½Ιj­4¹�/„ʹ¯³š‹ÈÁ;ß(Ý€ÉM³z)Ï"ÊŠek wÞá«ÿÚW}"€ßW®ƒ¯øÊ¯\‚¯@Z·äb.i Ϋ+´ÀfóJ" 85ɾºÜ�#ÌÊØlpAr§ö9J ªêØLPØö!P±×¥ Â(þ›¿õÍo›{ØZ!ø&ÀÿÀG|TU?šÿ~«ªÏL^óŸmÝæ÷–z Ë ì—òwÞ‡0 ÷ÀËž4ÿ=~ÑqÝ·1þ" ÿ¾„€_ˆg‰s ÕŸ‘ÿDÿ�V¿`_Ôl²+0E g—ò¬Ä/ϧBî±ËsºUƒçŸ\ðÙf"ïœ;8çnˆhdf/ªRM$)‘$¬*pIY’�sž˜‰Ø1;&rÎÁ;GÙµ†˜äE´hP•>%ô€:UÅéöØýÜG?òòí³ç¯NÓøZŒñÕÃk)¥—bLOb �SŒcJ/©Èaë1ÜÜUÖ N¼'Ê¿øç³Ê~sV^š­‹�,é8Wõ/HZ´°áo_~/F;Ô×q&‡1Q͹.ƒ¨+L¾Ì#jÔï `6ù¶iž�Õ! ,sW6Ǭ(ÞÛè� î\8ØêyÓ‚ÿí½o5ZËq¥‹§tÆÿW÷Ш®Í\m¢° È/Λ–mn»”ùÒŽïÌ]¹Û„^|ß*ÔÞ/Ùr©«®TŽÍ‰G¤‡÷0Õ¥LP´u†fÐU˜ÁâìI�I)€¢qؾ¾lº@‰ÀB osÛ³‘ Tv¶`P›ë…x»Î/t!@V€»ä»7€¬ˆ%�Xêë6ºÎ£ïs¨òþ×±ÊÄÑ‹öîE‘¾º¡IŽÝºÏsmëùe?×}  0§ ÜS}ݼ]Þ|&V‚Dó]Á9߬�IhH&)!5®\…¨áƒÛ5lJ(Ó¢ºoÏ•kHFŠ£…Ë@Î}ªëÐÙ�¢G×y#b¤ùœÖø5ÉÓDu±J)"ÛSòsunðÙé�C’ƒ*à84÷Çß°rCa²ï"ÍüXŸW‹þ1W.N3i|¯½öÚk¯½özçÔNØk¯½öÚk¯½öz‹TÍ~” {ÍÚçѹ‘.b¶ÿÌ KÍò¾Îw.`ÄhÙï1fKekBF‘|B ÎYšašp<q<q:�ªRÛ�YuÔeûÿ˜cDb\€ö¥aW�쬙ÅÊàµÆY‚fPXªŠ~Ù´cb0À}<�8žN˜¦ *ï;\_póà77׸¾¾ÁÐ÷pÄ�”%‚C@ôA:ßW Æ9Ëúš|8ï0ôWèv ŨàNPRʪ¡dTŒªæÊ‘ Bt!X.©ª)Ò¦�@<™‚ §®Ú]çt�Чl™¦ækt‡Á<¡ó¦óÎr|¹s ÊÊ{·Ë ±ªËÂ4aœ&L9ZÀâ ‘ÁÃuÈS%opntÛù,Ê©�Â0ŠÂ¹€bÈVªCB?(:6ò€‘F ‚$‡"•÷ޱ¶žÿ, Ø;r¹ámdûÀ¿Y¾Ûüò÷¿¿ö×þÚJ’a)š©™k±ÂÈ̶¿ùyk�­<ÿÌ¥óŸ_‘@pˆ™pæz¬j×(™M1ƒ ,©jPS#:sP.»|¼þÑ�â¿ÿÁx[ÝÇV ·ªê7øqUýi?©ª?ƒØÿ¿ÿsÿÇ[çrLE«JËÀKQézg$U˜3DŒ˜F‹)×!-r¢AöÚÆÓ §ãˆÓ8ašNˆ1âßø7€wx€÷ø„üç'x?€_à]÷8Ö³úx ¿Ï’ιßûõóoðïø]¿[�ÁO)÷ƒ!ŠêÎ!¨"¨jšgs‰½˜ïËð.äšE¶6YLȆ�y®�ˆnœóO˜Ù»1‰p �àDÕ©*àb€YUœ$qÄìŒÀÎw $ê?üÑöÒ¯¿ñøÙóg¯Nãøä4Ž/‡iz%„ðRŒáIŠñ‘ˆ<‘«³´Ný¸¨œõ 8µXðÿ|®àÌú~›Ðfœï­aešïjº:ž³#®Àñ´>O»Aç¬t‹(jÁ³#i %ÅÂ?3ÄJD�fgˆ2W©�ktFÈ¢í¥b_ÛѳѴ9¼…ׯ/¶< ¨L Züz1-paÜèîIÖ`ÿM–·ê‚ô°<Óí«õÌ�‚.M8Å"N@›<ÿzœ×zŸã\ýVD^mg;“¹K8¶û:óR=O h7ß·b2w" æ%²9j!1 ŠDYùœÁéy½<ïÇù}X±``Ô©Í�‚¿DnåÙ+¨öïkP»�ê10-Ôí*3y €Á»zü%žªëz8ï6­ö‰i‘åþ¢¸™ P¯¾{\Š´ÙúÀ™b¿îW,À2_¸¯2Êã¦D‚•1jUû¶½³ÿ7KüâQÖ ¦†G½‡0q;#Í`ÿÖyr+ç�ò»Ù¹Ê¶Ùº8´D޵ É‹ÖKe¿S�¿e]:Ÿ[ç]uáÄgëïœ#ÙÊw’B¨��y`cQÒƒZ’Æ^{íµ×^{íõö¯�°×^{íµ×^{íõ©�U÷© mš¾ŒÙ¶r­©Š‘ÒxÊMŸµºHWêúâ˜KÀx:áùóg8O˜&ÖÕÿápÀÕÕ>øS˜ ’c˜É �¥æ¦Ú´sÉUËIÀrÕ©³¦ �TŽ µÙåKÓ/细pšFœNFPǦ†:\™úÿæÁ5®®†ÁšÂ �bú))b—Á1â¬~§ªLÖÀãÜ¥—ÜìŽSðèc@J’<Ä™K€óÛMVS³-mOc´†cu|ð¾3U[ï¬Á\löÍQulø?M6�BH]4"ÀUµ(¤ïs—²�-C' ç ÐgZíg™«©¨§�]]×a8X¦ëÿû?þ�_ð¥Ùú¿ôˬé›Ï�:€ÒÈ*M…Khé¸]Á lÙª�Ì&`°È’ÀrÆl¡* Ø£J $HŽá²òŒÀÙ `­+ d ’0ƒ“àÿû�oØÊtËÖˆým_ô¥_þÚDš¬³ç‡¾GL ÎuYÙÙæ!G�sž£�#Ó0M#¦©�pìÈÎeÅŸËñÌ �Jµ#|ÞoûÉ{ÿ“ÃpøÉ››k\]_ÁwÞ®ÝÓOŸ=Ç×~ÕW=‚>À¯ð™>FØ<þ5ðø"å¥×|<ãAÁ×Çÿõ¨ú<„llCÌ  " Š�cM$ kÒßÂû�ÅmqÎ�'Z¨jÏ›kb~ì\rDôˆ€”#<3y"òÓétý±gÏ^›ÆÓËÓ4¾Cx)Æø$ÅðRy”bz$*$¥›2x›Ñäløë+VYç-ܹuJîtçW,@Ù�ÇÅÿâØÞ1èkµþ êÒ¹ê¿ÝÑ üòmå¾/b–âúM 7ƒSóz„%°˜ ÂD™÷w­*ß:EŠzÕ<¿•š û5{£UÌ·vöÍñÑáƒëpÑâ˜ëàè…ó²Å¡À×…^È«¹»¾O0­æÙ2;Bó€é¦�;9Ú™�c(V;Ñ~4ÑùÔXœ#ºßÜÝÊt·ûVz-'óÐ|>šX!ZÞDÌ™HyÝÖù„<˜#ˆ¢�½bT@"K!‘h}Îͱ ’ÇvqÛ·gW%"´ëí2Ç›#•FQ^×ð (ÛºoÕµy^ÛðߦYNyMïŒ`Ú÷ƒ­ÓðÂF¿ÿåŽùÇ~ܬ×[‡š6Új±ïM¾}ùÞQ×xªj2ëóì@¶ž#í˜u� H²cûSëxR®B+˜oDÑò}�$ˆd®Z)IÝ÷õþ×(®B¼ÞšÛ@ÿy”Õg ;ªómž÷’ÉÔæD@ÍxWD%ŠB½·fâqŽa°ïk%êÀÖXÞ"~Ö±(«óWæÙ°×^{íµ×^ï¼Ú {íµ×^{íµ×^o‘²Æšäü[k02–*�ªŒª ó jf•}n¦;vÙŠÞÀtqëÌÏT€¤”0Ž#n�·¸}þ§q„ˆäÌUÿonnpuuç]Žàª('â…Ý)`¨#�ˆ1€ÙUEji|2 Ì<7Çj$0Šk›µ§$Ä)àt{Âóç¶�" ýÐã0t¸¹¹Æƒfÿ8 èú!HÔLR !(|ˆè|òHMss•Ri–ˆË5ëÍ„˜ºÓ}w„ïtI@d ú®3'�áС8öM ÇøÇ„1Eh ˆbYŸ>FÄØ›ê›¨£šÉ�º}×cÌöŸŽ%R-…µÄB¨f‡gF€ÍvûR”L‚ˆHºÌ{-ç�™1uSçMuG°ãÏ„’$ µÙ:MæDDÄ(Hi2@ˆöY1b¸:àÐ÷æá(G¸EΩÙç¶ù·6?EæªÅ8ËÃÍÀq×ðÇ<€×Þõ.üößþÛàŠrfÍÏlNþ-ŒÙŠ6¹Æk Gbs€ˆ][@%pš•«)-UM–‰ +Ã"ŠizÆÇà”�J–¶þ›oûæ·ûm퀹VÈÊb·Ä�”&vç;õèú.G™Ôæ{2ÂÊ"R—‚J.*Ÿ=ÿg  48 úÎCÕ‰Ã4áó¿à Þxúôé?xöìÙ?!þU(Ðùßÿ}ßû>¿À¿à_ð+‘�»ÈË{z3×þ97߉è�EIA òE i:!LT�Æ$ÅF9]Zu,mäeo)ºç;¢ÀO}ðƒŸ|�ïŸÆñ&†éA˜Â“ããÂKIÒ£”ÒcUí›B»¹eØ=­Áäömèò`®çPv¹~A—R·ŽoÃÔ�èL‰}WÝõªÅ–[«ÿ²ØBlóÍŽÎ ä±¹ï-°¿þ“Z wó˜¨Z€óB «K{ÿ eñ|\+;ýbq ­vìùdƒøÎ©8óòAé/ÝÜNKÓ;æýŠhAŒU»^ü Ú²¥É;«ºöXOgj~ õWÎÞ8ï/åAzîzp‰|Ðìõ‚ ƒynSJé•"¯þèGŽž+ì9ߊ×ÙöZŸ×d éõ¸—ÌàªsœŸø%�}^¯ÌVÿ ¬ËcmÁÔLnÁ×dÑG‘ªü_Ù2Ôœ��º®¬ — õë²䮯·Vù¿~�_«ð—3•üš„¼~¶¶1R…n]óR_³Ø_n@î†,ÑQqzÈ®S)!¥Bú`8G6^ýç;p&î–9Ôî‹cªß£ÚóUöÍþK‹¹´ ü‹BX¯c‚‘žšµ,7ç^té^´"�”Ûr9fçgkR˜óZ‰bó�¯Dj^Eç„pÙ {íµ×^{íõެ�°×^{íµ×^{íõ)ÉvÉÈ Y‹2ƹ⌖à·–•M¾(`�<M»ÅûK/dõþ4ޏ½=âx¼Åíí1†¬¨2%Épp}}�Ãá�Áp©À\Š Ldö«1-Ô4)&D5…y±“÷9ǵë;8×gKwö<÷ˆ¥ôž!Z¶çi<átºÅíí-Æñ"Âáp@ß÷¸º2w‚«Ã€®ë ?˜•~R¤hÊ�À'‡ÞÇÚ¨ÄÎK! 9q âÄYy> ®®p•"eKú®C×wð]‡Îi %‚ó×åã @R)å†_¬ (ЧœóÐçV4g S³1¥Ù7( XÏu.%h˜]ºë1åÏ­ åb¯Zæ€Æ1€ùèDÐyk€W—€¬Âïû‡C˜-DcDŠ)c·H“Å„C�®ïÑwÎuYAWšì3zP£šf=�-œ7ÅŸs`gíñŸþ'7þD™6_ø…_vÀg€ `Ös+þæš:Ëi–ü†)øQ A"ÀG×à’F6©™¬yüIÄ”ý(¤æ�•†JÅ ø©þ~äü§o÷ÛÚ7˜â±4ÛQGÜâÞ31ÅI&~Ø(úΡó}µ1NN@”ã/h&ŠˆØ|^X–/2Ë›9”Á›®ó$f©ˆÀ{Ws¥]f¸fïúìö IC0€�€_û¹¿ñ'=zøµn®¿¶ï{üµ¿úW^ð/øm~€O,óz}ÿþ…Vÿ/fì…&¾sî3þñ÷ÿÃW?í3?ó˜œ÷ŽÙ‘cÍ'D•$)eÃk z\®ŠóŒø»ªÍÓ  kpÅý“ÿîO·,œÍÈö³ÃÆ«ìš1L­6î´àå û  ì{~ͱà~êþüVÐýÕàZ] –Dƒv�Í7Õ…¥» Ù×L§|Å•ûð<_QtQ¡NÕí¡8},I#K•´Ö9¢›$ h£dÏàZ«h¯°XŽú˜ æl‡ñã‚¶Vçx“,Ò¨ÅïÏó f=s‹ÁöüÞñg°™êq7sMî·/t)ÔaE>¸ë^øû î÷­WL„mWébiV{G�²‚ØA¥U¥¯^hÈ'«õï|?›or5Y!P&¯Îk¦UcêñNRIæà6ïï­“¯ÁcY2SJ�”ê\.*oÿ»êðÕÍåZÖç÷yF,¾O¬ï‘õ^ÂÍèl»¬¿_¼è™Ö’×ûSœªÎÇÐÆØÃ\f€^cBŒ©:&9çëóþ00ôƒ­)ˆŒTœÚ‰ÙÚè)SÆOÁ¢®B°ÿZ›þv<ËëçÏÇÈLu¿&µÔ?Û¬« çlAdÉ‘Î{ ¹áó÷¶ü/±-yCUΈZï³{íµ×^{íµ×;¥vÀ^{íµ×^{íµ×[¨ŠúDõÜ–xùº¬")™¢¹!ØeÛGÊY�ö{�®—l97ÕR4ðl Ž··x~{‹Óñˆq3XfJ³þ¿ÂÕÕúÞh�b¶Š7@¼�ÌFrVôÄ”�‚YšÊ(‹íº42‡n€óD’›¼ !hP„iÂé4âx{Ät:!†ˆ®7uKß0¦º·¿À§–ks}/ßúùϧîØ}ø§ú+~é§|Ê_aŽ×n BÕNU™T rDÄ̯zçßUî 5Sȶñþ¹•y\¬þ®@AZYð×hôeÖ9µtþç—`€Vµ\Ql½ÞÌ“@ï ”}¼ÚÐü¹ö‘z?ÒÀ " ª+�®Øu˜æ y´6æÅ€«ÚøX½#.¡½GªnF´0¿ž-bôü{c5yö3^X}^ËìšÁúË'š6fðâ5Û¹þ—÷çy’-æ7ïÝ´˜Û³#Âê¯. JTl2h•a°H(xÁ<£Õ?èìÒ¼à<м�€;Ôÿ”ÿzi'Uí~êC?ñÚ{ÞûÞŸ3‘ ƒååY¡š� 2;t¤$H)Ô(©rÏbG°§µƒ£²6vu�S3°"–à;oµÏ¸5軾O'™ rÕ)GK\�6êw#B¶yðe;)Ûȯíç—Šù³·ÖûÙ‚Ú÷|Æ,^Sÿ+Î ™´·&Ð… �â>`€·Ö«½Œ±š]fõ¿ÇáÐá0p8\¡:8Ïs܃,AôÍP×ÏÙ�a'ŒãˆqCÈÎTbçÔDUÍ[cTܸùó¾Ï|sˆHæÐD"$“R™¼'8§‹ïW¾ó«ó( r‹s¬ºŒ`˜ƒŽb'ìµ×^{íµ×;©vÀ^{íµ×^{íµ×[¤˜Í€”³Ž›„jƒi]­z»X=vÞ?shVÂx‡=Äø[”ú–!0žNxöü9nŸ?Ç8ŽPUô}oVØý€á0T¥½ï:ÛŸsþ*×Ï\Z‚ Bˆà0eûnEŒ17κ®«Çá�Gß™@ß›z_’`B¨Àý4M˜NÖ„K1šÂ›úÁ,÷‡®ƒÏ˜Å:uÆ1` R°€àDA]n<:ÎV±Èª A˜‚ÍnÄØ�8„‡+#[ÒÃp€¡sB�”•ñž³•hà³]11̾µ7Ð0QVwe¥×xšª[AìØ4)B²}´ =eâ…ÇÐwÕy óä$@EÊÍÂÍ�Vàªï<˜|ͯmso¨ÄÁYÙfãTH Þ1p8€Ù£ó¦©Ç8Nˆ1ÔüÚÂ4!LSžO!vÙ ƒjoŸip+Ä›]lIZíá-Ï×ULëç~î缈ü©²¿¿ç÷þ^\_ßÌùªÀ›#h¶ìŸG¡þA ÀÜf˜áDø”Á! H–«¬±’ìPHJVž3¸‹ Vßþ­ßTÇûmZßð•ô�Ùî{4ÖÄíK´i†…}œ›äâ`ÎÜ€eèzïáSß%;‡ �  „aw—1‚÷�e {�˜]ˆ5oМílJO»wæyž$Û ËœÕ«Ð0|×ãpu�Ga8àˆ1MþÌŸù75„é{UÒ÷ƘþÏé/ÿÅÏð¯ø"�êüs8¿wm3¥ô¦qüU}ùcù¹_|ûüÙ{�··ï9�ãËq /‡0½czI$½,I¿úÚ« 0ØØ iãEöæëß5χåÿÕë�Ö¨$ÖÿÖ :5ý:Íœt©’Ÿƒ6fÐRËÿm{»/öœZx¸±¿_ŒÂš ºtÈ`½åýÛbõas<7†©q:˜ïO›c~„7?ÞÂguûœÎ#�s¾"Ø5Oóõ_?§�÷Õœ¸Ùa¥Ù·A jþÏÜùÙÔf¬Áà®4ІäuþËü× Ö­w K²�žÇd²Ã:ZcÞrµ¦h83ÚŒK~O;°­à'\ÀÛiõ|›§i¾�^˜´u,wLÚš.íurþî�}ìç>ñ=ï}ß?!ÏçÖÎsUêKªû%\N)!Š­«ê¸2Ãç–§c—ÕÑ\mø]3gTí2ç rÈ™ð4;5ÀÖW1frkv,*Ñ3ÞûJj��¸¸ªÿËùLUy­�j[¯›÷r#ÕºüŒZÚ¹¨àÿ–2¿uäZ‡Xü›Ï�ÿV ^ˆ"ræ0²~_k¯ßZÛ·àÿ–+ÎüÝÆÖ¤v®ó±Õ3·ÚwÛ¯T b#È^]=Àƒpu8 ë|~þEÄëÚÜegç\VÉ—HÿooŸg×±iAZh¿k•ãŒ1n:¬# æ×ÌÉ‚�ÿ^Ž?ÆP×)E„`ä`*pž�}çf7£B@J)Õí'€y¼ÌsTÃÖÜØk¯½öÚk¯½ÞÞµöÚk¯½öÚk¯½Þ"5+aDšv¹YÌnVy?ƒÿ>[Ïk¶æï ä­ •Ü| 1ât<âx:áx{‹Óé„”bU�[ýÃá€Îw–áN„()«r èíÁåï¹¹”DÐu§‘–¦1Í Úš¹Ýyôi€¤"Ëÿ.öÜ*@ˆãd`~JwÎã0 ¸: †ÞÔ.0ð_aš"N§cÎHÉšçì\n#7ŸÝ<¸ª�1«UÎ;Œã€Ód*"û,g9°ÃöŒ$ÅÜ0mpÑ i›ú_:¡CdFtibË/Ï®)E„hMnN¦Š�1Y³2™Ò €åšvvÞ}ß¡ë |÷]g ?TÏ“ž©Â|vŠ(sÈ9®€Ô4h%I&7ÔƒÊ.¥RÁE9]!ºÎcœ¦qB˜FÄhV¹2N–-.1 bDêzt}B;H—ç§÷Ùú‰ù˜=¼�Ç ÛÝ×}ÝoWÕO-MÏ/þ’/9šLø-(�’)›î&`ÃÜ‚tÚ(/­)¾ràòØ{8˜ €!å¹WTUTãP¼™  Š÷�þÁ÷àç~öÃo÷[Ú·´À‡m6ÌàuVá¹$‚ƒÙô3\¶ŽÙÉEåæzßAÄœ .šƒTà«ÌÑÞÁÁPô*ˆ!ç-§Õ”•–9×9FsÁGL!äLf9iì^l޾ë1ð™µcŠqˆð‡ÿðùû!„¿ÿŸýgÿÉŸðåþ €_òñ ì%ðdë÷ç¿Ãgû>ð­*òdy¼ëá„jÿOàåöæ—œý\›Lò{Uã$OKཕgä/›„/\ê�û Œß:¶M‹ø•z¿¼b…ÓêþÑ?½è³[¹K´½Üð"â ¨¾¿¸ …þÏ�h²4R×MbÁÙù¯6Ó%ëZfko�ï²ËDƒÊ4›÷úÌiÀÀ]"dÂ-ïå«ýÒ®½²ûöŠÜ!õ³õQDëBiI‘¨‡¸:©m$B± o“5$DHÏŸMË né[°õ’öØZô¿%l]·”/Š™w ‹9ÚŽÑÙÕ¿um¬Àÿùž¡óNæÏ=OŸ�Áìõ�„—Ÿ¼ª´ŠXHyÍTó)©­-RÈgr©r‰-ró¹¬yx&^È™r~e½wKg§˜‘ *5{Þ^›‰‘Ò5JïµêZsÄÕ\o-ã×g¥uÄ¡Æaaû/²±�ò>×ߪY5Ͷ_¢@³-,Q‰~È�‡ï:xžmúÕ9¸”�œƒˆ.%%6Âwæà»ÎTDY¡CDŒÁ>bYššf"P`‚b�jsÌ#ùßy87Õ,õ)äX±†mÑ"RD"üŒÄÐ!dKxòœ%&8tY©¤9b ü©2·>ï7ÿf¼ëÝïÎK)�™‘A @6Hªì‰¢Íj8«fÍ?Û/Ïqåuà™a$BBP†:s2h�En”3g‡‚L |óßüÚÅõú6¬à[ê=Ëq�ÀX @8[ K2¹Nhl{K€gprà”Ì]\Ì×�m»‘Àw9;Øùš Ýy»ní¾3eðHf2N˜Ìþ÷t¢‰Yð±#"vLdc�„$ ‰gVb3±#¦dè ‘µù¿ø‹ÿ …ÿêG>ò‘¯þ;ßõ�àt:ýiŸti õAÞ:£C38Ç|ñõÌļz ,]?sα-œßÜÃÙS~½‰»­ð÷:œ/ÑFý_ÕõXȹ˿‹j@UáϯÃ9ZÚìc{¼‹�ËÛoÁPÝd\ß­1½µñsDÁló?Ÿ‘f�WÐûÅ~ñ3QâªB{îr¦µÖë\›ksê¯TÀºeÝO3¸Å„J(@:£�׉ÕÛUWqÍ %]ŽÉ ÁµÏ5ÀžæiUó¼±ðä/N;[Àÿ`×ÕÎÍi[‘ {Mϯ/Z)þ·ÕûËY¼òæÈçƒÎ3¶b1.ÌÙù²[ÙÑ7‡ÂôÉ ò81%¢ù¹kë‘zëbM* é±€©e�R@[ßù¬Žž ÐY±®E™Ïm^»­»‘י̺P·|!K•Ï+Kö1K0½½‡·ÿ׃Ùm…ê¿ÙÍûU×d¢Áÿvæ¶Q táQ-ò�J.€ør—ÊöX‹b³=)çGÒY,ÁyD/È1+Ê3[Õ×ÏIÅ«º 4û)Z¿/9סïpÎbˆ$ qŽëÈBJ™TUÈ9„”c³BŒˆ! ‹¶òàXàº�ÿI‰ÓÅçç]Êú–,RÈk’‘c=§u®‹V.åïƒÌæ>¶v™XÄ«–Õ˜suÌa~[¯;÷Úk¯½öÚk¯�Ú {íµ×^{íµ×^o¡RÌ 6Ñeó¦X:ö`oà¯[4਄(7�xá, bvõ!FŒã §l«c€ªÂ;�apu8àp0ôœwPRŒÕÚ?„Póé‰λªB÷9GÛšw�Š%+ÿSJÕÒW$"D³éŸ¦ ¾›‰S0 ÎiÂQ�ËÙ–W×”¼W" CoYâðÚA5U@’§’˜ N8D$ fužb†Ÿ�)óK0jÊê'³#­q0‹Tçú| Þ9°/N V4�ïÒ\”yžd׈®ïÍ="G2ˆÌÍcJÑFQZ€ÿF¦àÙZÔ¹f£’³xˆ>öѨ)Ūš“SBàç¼wè» cסëz³ÐÍs™i¶ì-ö¯þßÿw?Ào.sûý¡?Gs¶r™s†‡IU-¡4ùH- ©�µ7-0Hj�­|­R®¹±[H¶/[ €¤X ÿÙò+'(0ŽGü½¿û�o÷&ìßýßþ‘ýõr�Õœï<¼ë2øb/´¨Œ˜É1DÈÎ SÕç&g@wþ‘f{\UW{ÝÄŒñT­™K‰8H ˜ 0Aƒ`JÓh'>�N|:�Bà”„@ì�wŽ@Î;ÇLÄ"ÉÅy �ÙOND8I┢‹I8©8QeQaQeUuPåGòoù-¿í<{þü�üý¿÷=àéÓ§_¢ªWŸ ›ó¡±o2êéÎgLvB)×úE·]%¶‚œ»ç­ú‚¼úfKÞFUðoîƒÙÆi½¡KÇõ¢þŸ¯ÕµÚ½¹z’ÄBY¾€:©Áéb„ùrû/zšÓb¿ñq\ÓgN«±§:V˜AÚæãd ¤��¶-ðW¯Ó6k~±OçÅ¢*ø€™åög…wk«O3_£ hž3׋õ£§�í_r©Àêw q=îk\¡õl×ÿ/ǹr ±Ý¥êZ°äö¼hÎç^�ïJÉ¿¼¦è…{L4¿†6G„–ŸÕŒR=Ge½¹Ø]˜ÿØH�hÝ)¨!5ØvbŠŸ¤€g"OÄî�×ßÐÇ/=–y$òsBÕ”ÐI²³�åÀ—{‘­Îœëª-:ç5Å» h#ÇP(Ï€5±­Í VÍRP¬÷»WšJ»ïûJ€- z¢ ¢§V¿´Ë?WÙ[ôS]ñ¼æZ+ÍgrÍÊV¿9OTâóô]ãÒ²"$¬÷«îב*šã¶–äˆò¾js¿ØŽÛt P™¿7¬­ìS’EeQ*°µ¥$¸LHÉ}*šm CÉÁ¬²4¯)fK~‹šZÚ÷3;°›�%°¡æ¯³SÅâÛJœÝ—�KŽ .»odBr"b%¤$õûœ­ï ¼w\ü´pþ*ßI@�ÍÝ™ÀÕQ¡%î{íµ×^{íõΪ�°×^{íµ×^{íõ©b ÚªXZûÈj=é– ·u¦¦åYò(#bvò!L¦þŸ&ŒãÉì%Aè|‡~p}scÊúÜ70:…‰ö9QRˆH¹qY!9"S}g ºm~q=–0…Úø,Ö¤)&LaŸG¤q<žðüùsoG„@#'\õxðà=~ˆ‡âp¸3WuùiôŒ€…Ò¤A*ë—,ÎÁ xQ¨2àR¢3@±fÍ·}à›1ŽãÛývö !¦J>™ çÞu•Ô¡ªHш@!H 1‹.2z}Ž�n•£Ya¬³0‰ÀQÎd1Km-A³RÑ®eàá%!E‚¨rŒÉOÓÔ�N'w:�üx:¹¢SUvŽ;¢Þ3sç»Î3³K1ùÓíÑ1;?M“wÞ{.Åè%%÷3þðÃýØ�¿û£ý¹WŸ?{öÊét|mš¦—C¯ÄŸ¤”§”kѸ^~NäJŦ»¨pU_lw#Ŷ·�Yt¯9òBÙÀ-m¡/ç¯a¶ñ^ÊoÜ•€BlhȘ; ÀjJ›Ç³eW¯k¬óÞjæ{?Ôüƒ‹çU×qèK0·k³Ýö~µP…Ü3ˆ>ßÃÐŽ~k½ÿ'‚CÌí4ÐvgÒ_d šþÕ\*D"­ &ól“mªúæs‰VspKЯíùj,ú[ÒÛù×Åá–1W]Åtä},î=ˆÕ­�,Šï9`}ý\"§d�ôÆ9j-gYðóÓnsLí|œÕâÛS€ªsN%€ ùs±ÏTÈ)ÆO# #¢¯DòüöV¯®¯´€¦¢Š¤² ”9UžÄ0wΡë,¦ˆ*XÍ‹È"“9Ù9´Ø B"†-<½¼~4âeêÌqʎψ(…”Ûæ°£Y#U{%¼]²ÈÏ`~YóñtI^0"ÜÊ:71?w �£:P{ŸE% ÖŽrfÝ¿ÿËš¸ÌY)Ï Éa‰°œ‡´ ñD¦Ž†×77xpóW‡+ô}ÇÎ,'£du�)\�fõ?¼¯d…$N)“ $×¾Ç!«Wˆ¡ ˆ1Ô¦­Ù÷ ¦qÌjx` NÇ1žW þêªÇ£Ç�ðäÉc<|ôWWWpì«�xAŒ‚�b&;$S: «Í3ò\¥ñ7�i±-MM¤ï<º®«6²½ð^šWe`�¯`aPâ f @Î9Á9Ÿ-fÍöó4�f‹Û˜�b„¤”3P)Ç=t çAìjÓ±ØìÉ(Éy圭ù‹m(eëÿv¾8vp¬è¼GikÉYÍŽ¦ä·Ï6äÐúÞ×LU†‘¦qÂñtÂñö9N'‡ãqD˜2@ãLva#�xïÑwƒ9Q D×ìðïýûÿ÷WüÁÒ¨üНüÊsòælÖ’ç,`±1n�Œ ²\f³þY\ãêtÑÚNå|ü*acjpð1!Š»@À‚ð·¾áo¼,X¿1†°PŸP¤83øÎˆD„=\Ìd ¢dËÝ„D ö>ŸË™LTRLý'Uu[ΕˆŠÆVØæxG…T…TÄ%/"]J¡‹1 !Æ.„àC>ÿΑï¼ïˆ¹gÇ]çûþ#ùÈkú‰Ÿx×8ޝMãéµã+!„×b/Ç_Š1>QÕáì.³ÊÄ.uðßÞ;«ãówŒÔ‹‹Öªõ¹ˆâlTwxVÿS‹±7¤²Ù~¾<˳ ÏÎé Ù KÑ.½ðÚÕU\ÀLºhÔòM„åñ¹k~´|»gÔlëœÐ hñ\n�gv¨Úpè=Î45¯¿s¦=?žÅóU©Ú뀔ä}?ûáŸyõ]ïzÏs €H–ÍKã:±•'_† Úÿ׸§¼ÞÉ€úZ)q@K°^$�"Hˆå}yíä\‡®›íö»3%·wK·™Ö:uY(å¥]§6Ä�âfÀŒÅõR#’­BˆÖŠþfÎ1aû–5;µlÅ ´ÇUž/%v¬u$híð—îen4·cp°\’¹d DÉfNþTÅꉟÇB0Òièˆ]}V2`_ï±ãLYÌ–9˜sÄ0Øã{è;ûî“݇œw3 �C¡CK&^Í‘,ˆ怖¿ë-ˆXÌ…”RŽ&‹�CÃ{€(.Ú«ŒšÈˆ²NªQù»Z=?M ¯H+{íµ×^{íµ×Û¿vÀ^{íµ×^{íµ×[¤Öy–—𛥙Sì® Ç8xW”3Ñl4cÄñxÄñxÄétÄ8™�½5ñº¾Çƒ›kÜÜ<Àõõ ®®®ÀŽ‘$59 f¯Ùb0¥ñ¹°1M ]&s3´ïz¨à“_8À4E¤4Vðÿöx‹ñtBŒ¦T†áǃ‡7xé¥Ç¸yø oÙ"«Ù. iVÑ'Ä”cO ï¥î3€çŒUï’ó¹éW,HBq:Á ÄÑw]µUE¶Ë_ºçׄ4[¾Riæf5‘ëÀä *˜0A“"…„bµñçÈÁ7ªø¢¦JRìPKF¨5™Î1œgtÞ��‡su¹iªiY¶Ö<7"G!2$Iæ1R˜2 –ý+�aîl‡½ë"„)btÞ¦ÎyoNã Ó4BRDHÙ"~ç<†Ã€ÃáÊ"Æ["¢?V¬Ò?ù“?Ÿû9ŸSÕ£å<8«Ù¦\¦ì¾@•@ðˆ…S÷Ó*ºük¥Y†TÉ”œB nÀŒÚüu€V�ÛØ� äŠ>üÏ~ÿô‡þñÛýVö“~à,—wåfâÕƒÈ[tˆó B LD$*S BPbB×Sç«€3†H³¹;³cïw]O]ßQ× èûžœ³‹TDXE(¥ÀI‹‡iôS˜ºB—RìŸ=}zóÁÿñ÷¼þ±×ß}:Þ¾{š¦×bŒ¯IJ¯ŠÈ+ù¿ÇvvïS+T•fØmK™Þæ;¯~1ƒýù}ºñž;³†ós‚V rk©öl‚Q›Ê5tN[¸p¸Àû— ¡}ô¥íÌvè-ÙmñÚvßé®4{=ÿ›®÷�60Íˤ‚7S›‚ïŶšy²Î‡?çK,æmÌ7ªšð%–M[{¦gž÷Yqǘй5|›ýÞn¡�“omåe ¯2ëýÿðùâõó"°»Ýwš÷kžš%ÖaIžP´€es j5ÊÏÜó“ß:n´GA›¤ƒs ÷ås›ÜZ»;ÔùEËëàÂ%HgÛšD—¯­õ/Ö$»9[Âþÿ§êCŸõ®w½ç§¡8A1©jLÕ ~v‘¨{ÅFô“çÖ-¦¤`h¹‡5ç˜Îíõ‹Íºh!9‹€UààÁŽàÑ×uRð>“ÐÎÁòMs“{Þ)¨O�Z"l?hÞ¾÷Þ{Ê:jEn¨küÖ+¤dK»ùfYÜ’Œ'"s?'Gœ?Ãf‚™�uе^g ‚”óHó÷‘œ‹æÖUâCÐåï-bÓ^’]È3À{ôz€Ë‘9³Ó×ïNdçzOšI*õÏ”N åÐDJ\ˆ,¯ŸJ ÉÄæ” y}_*‘€9~“B�6çŒãÙ~—”Ž+“<òëœsØk¯½öÚk¯½ÞyµöÚk¯½öÚk¯½Þ"“�õw�ÿ5c>Ål¡n¶ôÞ{¤³ºÛ=ª:&¦ˆ0ÜÞÞVð?Åf‡a°\îë›+<|ð7×7𾻜³ ,�)°¬’›mÖˆN”L­�WÊ¥×6Ó¯!蘿6–z–p0[PÈr[E©�•òZ—#Ü:èÌó_×,´y|ym㾜h³k�n’IhÒ?w7XºeyýïÂ@®•ä[\› "ĸóüù³ß¤Ð¿E ÀIblf²æûü &lÏÓæ&£I‘óÛ™áœZœDbÒ‡#†8†ªƒ”{,Tð €›£’ƒKqa{_.кšèj\Ì1ŠHêÚQ÷ˆâèBŒ¬6çªþ_;¥1Œ ª��ý*F¤qàfÜ¥¬lÖ þÀÂ9bKê˜7…|» 8—³å½>¿&G"œ¹d{û­Ï.Ä0‹v9wÜ�êüÓ¸ 9ÏE•n)ÂLðä@‚<î”׿³›PY52º¾CO¾ÞÙŠ£P!6Ì:öj_6’JvaÓs‹ývßUt1WZWsHFfÆ< ¢€JŽ˜I–ëñjãZ€«Áù5…X¼×^{íµ×^{½3j'ìµ×^{íµ×^{½EªUÿCPé¥}µÐÂ4U Ô;ov¼÷ GÑ,¸C˜p<žp<Þb§ Êu}‡¡ïq8\áæÁ n®o0 ƒÙ°ªšâ:%„�∘RcyÊ ÉJšä�8�£‹ 1G°3…9g‹y‘d6”Y1ã³m&eÕÿ ãéˆ7^¯ìuœŽ·P(WWð�)�ºÎÁ{8#憳ev:ô}—Õ ö?¦)“ãtBL Ó4!Lú¡·íÙàV›ònè(º>+„¨4; Þ1D"ÆQà|¦’c®Ù¾ÜÈL)Ö4‹)7ÖœwðDpYÅÕãÉbž={ŠçÏo1Ž'¤†äQÔðW‡k†Ø1$ ¦0"LNãˆi´ÌPfF?ô5F¢ó]žKmÖÀIZ•H¦~B‰h¨ß\ãR‘ ’Œ4Rš%íL Á90€8æž´ÂuWt…®ïpÓˆÃ0€‰!!â„bH˜Â(àý Ó8BÑ'ð‡>ô¡/ðxøð!¾àwý®Å5T€@Ê€ŒªV`*§%\΄g €-o>åFðšpÁHÊÈMZTÀ¨�ȱ:) ‰)Áðßö�w­ìëͦ¶¬-d€Ó¡ª=GDÌÌÌΑ*<€^U{I©‹)¹8M ³"%Ïàž®à™˜<;VçÉ1ñOÿôO¾ò‘ŸýÙ÷<}úôݧãñ•q<¾2žN/�Óôr˜ÂKÓ4>Õ~mwÿóûÛ\ö‘»´-Þ3¬ùÉšð‚ýœa^ÐÀϯ‰1Πÿ¦’Y-y„Li–AºÍسö_úbŒ:«—î„¥9mlû~ãwq¸0ƒ¹÷ÚÆ*V¡��—Ç‚;,¹±Ûï œÅÔçO5UììîpyΟ#Íke85û|QR\×*´Š�(Ÿ§k\yk°>O-”™‘ïÆú¾c]‚ñe{wœ«K¿æ…U «h†ÔW,••«Árü3ý¥Êõ©*Ñ7Ï¢.éü:[ èìsëv3Á€n óœØð7ÃyQO΃&–C¡—®c*ñ9  y7eûtaÇyÇÃápTÕNUF™4ÕcÎy;š­Ö‹¼àùÕ¹j.V"ˆeÝ)Kµë.ÁDðì¾.äÊyœïÉ\Ÿ´Þk‰Û{ÕE4R_SCî­öý™0_-3yeŸ½­ÙÙgÊÊaËðrÎ °¼��û_!Ï,É(³»Jy�]ó+Q)òBe^ã¤2€U!$9rj~�ó®F"”µçìè •XP”õ@&ÈÒ<Îe]UÖªÒXèK^o;°:8oÄæB®-î"¶þÍQ¤¦ÀϤϔ²ÃYqéÊûÐyWÕþÎùìœe碸˜ÍßÝâ ‚¤¦Î__§%�¢¼}ýb@%U¨6Ï�e|‚jÊ„…c4çÆ5ó´�˜cbŽ ³i°ŒØk¯½öÚk¯½Þ9µöÚk¯½öÚk¯½Þ"c\(‡Öy™¥ácÄ4ާ ! ë ðíº¡ï Ü ã4ât<ât:áx4;}"Bßè»WW׸¹™ÁÿšDÌ= dPÎöõ0P·Ú¬ (ÑL`¶wâ,²nm=‹½¾‡s¦N¯ GÇH"˜Æ·ÇçO'°c ‡Î; ½‡ó`GHRpV©C`M@"³ÆGiL:09Lã„q1… Ây¿BœÐ÷\ç‘;óÖtÍà9e¥¾ó®Í’"4;˜àG0³ÇÁœD®X…zF×õp�5BUºlGK¶f£‘ Žxöìž>{ŽãéašlÑî<ú®Çaèqu8`è{°sPL1àt�@1–xEçg›ó]‘$�•ss8Ï«F|¥jv¥%O=�9dâBnÄ&Aˆ!GP4ªn„RdL ªS4â±Åäü]fÆáꀫë+¨®®¯á}5!ň§× ¥aÍ)¥?Yöõwÿîß�¾ë6�×jg~ @²#“¨þ.Ö ­Hd¼­í2[ê”-OX�‘ß�³èóþùJ¢$×þ;þþ÷|7>üÏþÙÛ½ùzð­­íoClêRJ]Jé "½ªzUe(\7ô¬*>JTô ªƒDñ)%RSþ©þÄË{ýcï{þìéûno�ï>ÞÞ¾|:_§Ó“0…Ç1Æ—U¥+çiK!«X‚ê?_ð¿™&+ëóågžÿ¼QCÓÝêò²¿ªÛŸgVÄwÌ¡&Çy±�µu~%V-#Ý2X‘lÞuÿF©^ø§^<®eìAki® Ùöi�¶£sÇøGrºëþ±ý‘÷|ä#?û‹^ýõ÷ÜÞ>×éxz5„éåÂyYU»ö$lcj3 Höô­}|Ó¥¿\tÉfüþÖüÜ»h:�f{ëÓÎç­ý{¡ú?¿oëu´ñ;xžô¸Ã [åŸÃãzçî`ß±ëõ£Z;ùj–ŸÑ‹£ .l{&Ð*–|ù÷VQ¶õ³�§Æ"^u{k/O—÷©q3¡ ¢SûûÍÈÿÓæŠÀ€.Çeá\±íïP3è)ŸÏ©¢ j!íjFOëëDgP¹02–V3q¦øÉ¯OÄÅ ú»4ûË{ÈzÇÚ}j ñ…(žš‰CgóC—¼®gÞB1¾Þ±F½ß² Vd�–DŠ6FâRPë¡°òS0Pœ¶�úúÞMðÿ|.ÒG±vßœEù‡o¼ñúWLaúša8<à¤Z³c^[f�¼M�+$‡¬ÎNš#¢r€Ì * vZß[ÉddÔj§Îœ•ä̶F. �ÈŠ¡fÄ—µnÌ ¶­“uж‘Ä"Y)ÕQײ¾·õ,Ù½©9ÁLKrF%jfpšD�䜔ÑÎÇ]þ¼¾ó5^*‰ [ËÍÇÔØÆ7Ûj�ÊÚµ:8· F¤+c¬®d­ ÁLD˜õ¢Ì'žAû4» eðßȲC^+{¶˜/"¶È§¼†M(YÍà}À4Mˆ)@Uàér”–µÍS]Ÿ–ý-÷å˜ÛT˜í;‘Øú>­ãæ?Ueãn¤‹q¨±å§ê”0昕27‰|>nª.lÊóº}í,'I ù;QÚ¿�ïµ×^{íµ×;¨vÀ^{íµ×^{íµ×[¥J¾#°Èql-3C˜Â„iœ0… 1Ĭøäj³�¢ý¦`ÊÿÛ[oobX4âœóÖ s]Uõ+4[`æÆ©´�Jû 7 a‘bëj](˜fOÙr ÕŽ“LÙäŠR˜�eÔvì�ëàŒ«ë+OXQTë³ËÞ³T›ëšütæp¡›û«`hVÇÚsFë³Ruµ-,�·¾>»0g^—ó]àyÝtÇ(ŸßÊTjïãÔŽÍD]ZnCe‰u/,ò/žÈÅ{ë€%@¨hŽ·q?@C˜˜ :s~¼..,jv霷øô– µ`+µ ,W×Ü5°zok€ sÜ‘žEì´‘$ïûÁô}ÿËÏú5¿þ?Ðýa<�ǘ‹yÑšç�#À9¸üìO¬PhÌ*ø ´J¶g/–ü&¶'s­rT-í-¶©€¬Wž�&)F„`.\!#­ŠmÇ{_c Êúk1ĺG*D%°š%õÿУï:sÔA‹m=L1� –3ˆ§&IˆuʱÏDÄríð¿ëz=WWè|_AüB$Ž1ÔcI•ø¹~V8f¨w3yuå&P¶S!OÌ€Yý϶îíLmoöõæ "PɱBÑܶ ×;�Îwy½ÜÛg—qÛ|`Úw�)Œã Ó4"ÆL¨NF*ð>!ÄSà/Iyå|ÎÑ f�«n[wᶸ[íxÌ¿oÉíŸÜ|ÝÒ¥Û©­K/8 ´dÞ”£%v€½öÚk¯½özgÕNØk¯½öÚk¯½öz«™Zši ÔZCG,«2¸¼nàÌ/B˜0ŽÆqÌ ª bC SÍ£ù–Ý ÌyŸ@VCñZVy£–*�y�õVe­`iíGs÷³6µòqI>¦5;‡ÃÕœn<À“—ŸàÉË/áñ£Gèºã8!FkJŽÇ Iœs†1 ®`º‚ïŒèP€|S79¨x(f«QͶö y?¬¹:“0:oŽ’""»lojÉž t¢Hý`$�)äæpDJ1©¹)䯧w �ˆ9äFkŒó9µýv`"t]‡aè³*ËÆ-æmM9"Fs.(ÇeÖ«¾’=l¬‹’ ¹)ŠzJCÛ ¦l›BŽš'„úÎc�è0À¹®ª�š‚.R¬.SŽŽ`¸.Ö¨ßy®o®Ñ÷æBQÎÕà\_?ÀÓgOq¼½ÅßúÀ×"€ßYöù˾ìËj“R€M@¾”6Užµ›Ã9£›r€8Õ×J!§ä òrmÌVèFà†`iš›î¨Û.$€Î!1Ø >ðõ_‡ÂÛýÎ¥Ó4}ÚWý—ÿùoH)½7Äøj ᱈\•û×ÖÍ®6®©·6ûåÙ:š6o™+ÀrVq·–ågÊôrΡÙKBã»åæµ³Lºn¯:XÜAØtX¾ ëºû�¬|¯(÷ú‹�#jíÆi!ŠÎÅöTI+žÄʼà|ôî·×ÕRcMiÀ`ZBhs¢Ð}?o¾Q@éã¨ÓÂl¹= t· @þ-æˆÞ9dZ‰ËY¹éŒÒ‚ºš¯—æg-fOwÌéòI�ƒYaÛfxk�ÙMh}Ýkcß~v`hmÒ[áÿ"úAW#¯z÷Kçg¥¸IPµâníÛg7¤…5{�® :owuÔgJóÂåX­®CÚ¤aÜG…¿7°º?.Õÿç÷iÐjÿ÷úÜúÌD¹—`ã:,l›óo¼ñú¿öÆëûÚÇ/=y®ªãa¸Òãé6UP•ÉÖ¥¦CÏk[(—É 52_™­“C9ÑìÅõ^[Ö©”­èÙqž “TÀÿ)Lc€HÌëãl±.²²S—Å|&ⳉÇh±þ÷]סqta­BêµÄͳ�ÙÃ9sv*ŽÌœÏ$+Z8HÔõm×ãêꀛ›¸¾¾F×÷`"ÄÁ·Œ0Íàq;`6pÜñ2J�™át©`Ÿíêq¦þ·uo²H«¼ö­ääB.…†T¿w2tˆ!¯±S9à3øïÍ)KKQ%o.Vdó"©"f²ë4MÕy @uürŽ1…²NR” V#È ‹ø‡bÁ¯jÄPuË臥@¹"Óêù^\¸Qì»fÞ4‘Ü(ùEêy²ÏŸ�ŠÃÚ馋÷õv'¢îµ×^{íµ×^ËÚ {íµ×^{íµ×^o‘"“ [CGÏ2QÏÁþÆVßw¼wõßÄd ²0™ý{SóÓlÓY6_TÚ±4ü³Í§Y¡šõ»uÕSn2È45ýxFu PHU°•lNÀ>׳í;®@m æT0N#D�ï@WÀpèñø¥Çxåå—ñòË/ãæÁÃÚ¿½‘¢`šF„AĈ1f7;¾^{¸ÆyÀy³Ò·}T8¶Ÿ9—›Œ™°0gÚ—PU (oæÆ[ɳGnú¹9%7…O8�#ÆÓˆiš²šÞÆ6ùÙ6ß@úüQDpžÀÑÁ—æì�Õÿ¾3õ?¬¹lyž3Yƒ£C@à;³AõÞÃy_sa-ÖAaúöÒ¤– ügkÖh$“0YsÕŽe„5íÍVÕΧƒósÓvBޱ@4’JÞ¿’� M@GLnÄéxÄqpuu…¾ï1 Ü<£ï\ßÜàÙ³gxþü9üÉòÝå—ý’_„_ù/¼qí¬�ŠÕ=}+€º ²"NT¢ìtW'€¤•z8�¦G¤šMhHlà—+×x&$Á%o¾]¾$˜Vn!‹mæ}GYßR£f‹ø| L‹ìùe$CjÐ ï›û´ *QCÆ€Ùݯ­ü ¢‹B6¦õù$©k¿5i@q¶SËû*�í®^ 8¡;žTˆç3ßGÙž)ïúÁüýÿƯÿ�¿éÿ`í»aÃh«Í¢„§eæ½k" ŒEC*Ñ D4Ç� ±¬g ®¹óí\’"%S®‡ͱ)…ºSVpLДªSÅl󎆀�ò¹4�ÚÖ¶~qyMßçuŸsœßDu…=O”9r‹8;ˆ¢Dì?ÀL_JüS9A\úÁˆ}?€�â~¬ßŠ»X�Í‚ßÁ5._k+ÿv¾ºUÿKJõ¾P»å»Œã^'3ÄT¿×÷­S]gê×y0ÙzYRBâ&šƒ©:¦Åã�òþ×UûŽ�RB Ñ1 ¥—ü* `uOaàN š£Pt¾‚JdJ;Oʺ™$œYùÏŽqu4�s9†–àWD¡qNX_Ú»À^{íµ×^{½³j'ìµ×^{íµ×^{½Ej,×MV�›Çpö�Ê“�3ug@qiÄM! „É�$v ï¼5Éœ¯Ù©s“ȺŸ*Ú8¦š±j�P^¨ö�NÌN§öGnÆ&I@2Gf{vÎö�¬Ñ™bÄ8M¸½=ât<"…ïú¡ÃÃGðäÉKxòòËxé¥'¸¾¾6}R Èۜ�iÎÖä:'0�@ì ¢Yñ/�$UYdý]³suŽ+`³µ)R›¹D'fO9gŒÎ÷f9ê-'b¸=ñüù-˜�©õChpnqÞ]u)àšÅÊ9{ÖšÀ>«¡ÖvÁΙRÌ9—gÛ^×Ù{;³ÞÕliDs„AÊÇ]JÖd�™,�*�a€È,ì}gv«ƒPÈqž¯@£ZšUJ‹ 8�F<{öÔb ²B¬ëz\_ßÀùWWWxôèþÝÿç¿}àËËx}þçýZüÌ�}Þõ‰¿Ô?Z^+™°Î̾(ô®$T€rVX6qSÛI&»�,§c¶õe2À¿¶êÅ”ƒ ¥ínN”/©ùïÿGüè�üðÛö¾UÙ"r·’}‰E6?Öš�¼ùâ³»!ÙØÑÝ9äu3ëO<³:§óŸ�½}`Ï”çK�û3_ï¾éo�)î¶›o�ÚöÙÑ÷ý›8oóõ¡öa1\+°<ßµ£õ<•Üï~.TÀùxëÏZž/¼ˆˆÑž«µ+ÎzüV?{“þò1Ÿý£µ:§93çŽÏÞäV4„‘rÝ•ú ø¯žÅmÖø:Au{ŽÖë�Îæ*­®1Ú·,íò—êò¥¢Ÿ¶.Ñ�±%\ 5ˆ^v¡¸*Ü™úÑätaûÚÄTG£ò�Œæ·›&㻎­Àr8j5zvš�l®k¯ùƒæý›¯£¢þ¦;" �q%­-•É?ßÅìb€ÏOÁÙ�Òâ^Öîòñöù—þÓúÇßø)Ÿúߣª’RUë6E�«›O~Sý7Cíh^«Ög¿Î$�L&@̶ú´tZ )êssu 1æx¤¸Rú7$RÈæLu~]›¹PóÞ{ô¾›‰ŸdyõB:[5—+-È!™Ì*Š”Ôœ˜’Ìg¼É·¥R¶ÈWšW(ÍEiÛÉkÁâԕ׃"©~hUþë?+y"ƒÏ’$“òÚ½! ›£€ƒó³š‘ ¢9.ŒF¨�„mÝ æì˜Ðcè†ÎùÊÂMˆ1G1ÀÖˆ*9B`Ê1’²[‚,&g!Ά� JplqZíz�y9ne|�ó`–c��™²3„,瀭ѹFpIv{³õ5@äàœ¹Áu âLBæ|œý-Au Áy&çêbÙ³QovÀ^{íµ×^{½£j'ìµ×^{íµ×^{½EÊ‘«@v±¨‘8e‚ó}V2Gï+x\r/½·|v"Â4š¢Þ€Uþ‡Ãýp0ëyïrãW Êõµägu«ÈM°Ü¥ãÆ>ÔüÒK»™*^.*1Xð=%86ðßyû�ˆ "˜bÀñùs<}ã <¿½EŒ˜77×xøè!?~ˆ‡âúú×××�˜ 1aƒYÓ�dû|ˆ1à4� b$IèØCA¹¡¦Ù"´‡g†ËcBŽ¡¢à)Ì6™Ò€cj ó1™…¿5/]qè{³êw1 ÏŸÃe‹íi<ÇY¥ 0 ÔÏ–§€ýÞ»„ä¬9çŠÊûJ(ª]vläÇH24ͼ!°h óœy›·¶þ/ª¤$š£ÚF¦Åô}Q¤øï;_?7ÅdîÙÞÞßyŸ¡”ÀÖð a³gÙ®4˜’îæÁW5à;¿ý[èx<~€WàÑÃk|î¯þŒÓ-~æƒ?€×Þ÷éà«Wlìòu¡"1q�P\jÝA  ‰RÎMÏN @êyÜQÁŒ–P¯iáú9$v’ßðµÿõÛüÎ57�Û1ÕÆ{�¾¾pû.ø×Bíö ´_z×7ô¢³Œúòº–p÷Öšc¿ðJªeõSºï(£ÚÁÏêüæîž€rÍ2sÍ™?Ö3�XÕŠ4» Ü;s=ßÂá¼…7["]p (çËaÚ"o¬çßúذ±�{�ù}Þ³þÚÞi3­RùÂçÓÆ±„Ù$Hï¹+¾¸¶n/pôð»E�ØØG݈ Ø$-”¿6€ÓzŒfTÏv£‚›•°¢ËºH@¸ÉT¶g§gŽ X+ôëØˆ (ÿµÉ r÷X];ÚìŸÞ‰|/£xÐð2hEn"š÷• d{-Ûçß#�d~ÿöÕK—(zi¢Q=t�µò&ê,§«úŸüÐ�ÿÛŸð‹~ñ†ƒÄ“¤‰9i¾†� ¨·µœcÈÚrÈϤ3­“%¯s)5ŠLˆäL 108fUø•ek$À™Î9Äê¤ÕÆxÉ<¿¤[ß3娪ÎWð¿ØÿÛ¼�ޔʶ8Ø›#*ÙÂWÐ8%´CO#:ï*è|:Mp/j{SÜ—ñ0WŸíûÛgËúYSÖEýŸ’+‹[K!¼–ñsX1Cã8bO˜¦Ó‘b�à�Cß †k W ý!�¼–�ÁtÍÑšÇÈH¹©Y?›cDYo—± &›bß1C•kÂÒªŸòƒ(“‹ó\I¢u]¸¦ —…1Lˆ)䵑ƒ÷DÃ@™ aßÿŠ“„ÍÏÙeÁˆ3ùbþs^«±÷�÷ zq,Ð^{íµ×^{íõöª�°×^{íµ×^{íõ)c²Õ¬.•ÿU_㾟›éf}ÙUp@ͲôÞ\†Ã€ÃÕ®W†ƒ)Ö…�m¬ìMã¨Èü®55K”­IW_Ì@@’dù›M)c™œfQšD!qº=âÙ³§xþì)nŸ?CŒÃУï;\† ª[cªóÔõR²†<ƒà:‡ñ8"I‘©ï�b pä³ l±×ÏJ!ß¡zt½)çUÆ Âknø2ÏmýÒ<‹!!†` ù47A‰€Î; Ã}ßן…q:�pÛw«œTÊÍ;gy§�7ðZ!k`çíõ<�\n,¡s4Ì€_iæ`_«VË­ÍFõÔ*`ç¦`ÌÄ3AÐÚÔ>$1bIß÷uÜ|çá�7‡ Q° ¹‰kÍ`Ë#ï‡Cß[C6EL!bšNˆ1ât­±ÆiÄãq£Gq8\aèĽˆüñrŒÿÒç|:$‘˜üìOþǮѿõ-ßü¶¿w)^¤­¨Ù"^z�©~GúòÃHk>7ÞLšû*«ºUë·€ò:ºþ.•ö‹~ÖŽ@™$ôqŒ/6ö³Ý³Ýcï嬟‰2�?Ä¿÷ý?áß÷žªhnE«¢Àþ׿ßø�ÿ¶:Æ”y®J/ÜÙ³XšcÎ?ýýŸŒ—?Ä+¯<Á+OnðàÁ]瀬–ü‘þ,¾î¿Ó¢]6ÆÎ¦�ÞI@q àãá–¬çp·3Ãö?6¶W³Ü/̇;A¾seõ}æg¦ ,_­çyõ/œŸÕÔ¡€ñó5s¶Ïzþ/®©õ¹iQ¢™x’U®´Úns[S<ÏšI««„Ç“.öYóÚ§ÅÉëõ·%°¯oÄbæèb§û‚EtA;n”Ió€¶VãT\ÞÛüwœÃ9¶A_4‹·ß½²U¨.Xª¾—ï:·~Y¸àü"k‡#Åøi?ð}ï÷«~õ¯ûwbŒAD‚#:ª*”T€MP²5eûxnœµ,‚‡P‚‚Tì\jV‰KK£è)“Ï"³²«3ˆºzÌ•éRž�Ù-Àæ@휙S—àŽsö<Œ¸°AÒä¿gâfUìg0Ù>Ç�¥¿ì}eŽÇ0Ž()Bœì;ÄTÖhBCx(ŸWÉŸ"¶æÊëዳgu}#GvU’iýÏ”õ@!�Úq„ìjB˜ lÑ^]ßãÐ8ôt]^ǘ#²ÓCCàQÑL敆g@º­Ïí¼·$560ÀbO™×Ý•x›÷Û¶µ¼ŽÏ�!æï&õ™›_Ÿ’`œ&ŒãI BßæÐ–Ç˾ù&~ÁœÜªCC’zþ‹«@«ú/qpì�Ï„hâJVØk¯½öÚk¯½ÞµöÚk¯½öÚk¯½Þ"EÙrt΃̆׹CÎÎÀÕ]m$iUåÏYöªÕ&3£ëL�~}}eÀê`™Þûj!i¥Y�mWälNÕœínY¢¦pÎ &;¼óÖüô¹Áª`†@AËÚ6’ JDž?{Ž7ž>ÅÓgOqO€õð54«ó$!‰À{�Ãp€>²íyöp®Ãsÿ§é”-YÂCS˜�×Ín Žà¼ÚÞ9k¦#i2»Ï°l¬*ˆI"BÄ�L%&„8XFh’ 6›‡¾óð]‡Î;ô�Gì;ˆ˜ Áaè�ì0ôYu¥ÍçIVÒIµ®%XCÛ{#{xçᲄ½Ïö=†€Ó8B“ D;wÞ忦k³Y]�±¬ÔŸ0¢‰÷ÖÐtΣz†:ß5 úr—¦bqœ(î D„"ŽÇ£éSš0N“)ÕB0KÖððá#üÍoý¯ø;¾ã;~³ªþ ªŠ®óø¼Ï}?Ât2UN<þ¹ö?à¥4axé“×Sq 5 ÀùnŒ€L0ˇ„š³�[7 X›P3Y†›h&”öêw}û߯³gOßîw.è‹ÆgÙÜv�¡{n­R�Õ½¸ƒ0¿o ü/缆�ÓP^«zé¾û§gÙVz¯£î PÌÀq³o+ ÈÔÿ÷´îÍ×Ãÿ¯~+>é½wù;ž÷Ÿøƒ¿ÿ7ỿ÷ã£{f FUø.ËË;^}–ã4 =¿ô¿ø}¯à}ï} O^zˆCß×XšOÿå¿þ™�⻾çû7Ç¿±—I4ƒÞJ÷ lK–Ïgî¡Ö¿ç']jéÂ]ˆ@Ð3€ޕ‘ÐÌëžßŸHÓÀæÞW ¾.ýíÿ„²ÖÁ†•¿¢±×¯„‰-€Þ57ök~VUð?ÿ[¥ØqÃ[+Üšþ솱$‰èŠ- w\óu\¢¨>+æû�åmœ‘T7oo÷¹›¶÷¸³õ(ap¾LØ0vh^QˆÍ]\éòE†ïV··Ï¿øÿÑ÷ß/{ÿ§~­ª×u£ŠV‚¹5˜sOQe0×±Ä8­èÛ=AAA@”ÌéA)M E÷ì¤$‹ö²Þq ‚'c¼=-×u\9Ï{Ýþ°úo}ž¡7´5mâŠm|ŒFR�ù¿²-³˜×z f_@â´øcf#�FÒl‰ ‹¹ØØû›º=»WUPšÎޝ€ÖŽ]%fxokMŸã¯Ú)Ÿ$"¤T�'F1¢f&?÷¾G?0†¼¦ïóñˆYÚ#!eà]Åæ]jTñí!r.“[8hÍç£G´±ÜW0—¿§ê¶@´ý,Ð�œ"[�¢ù�BÄ8ž¦`äæ|.�÷èº"}^›»Å:·¸}•ï‚%¦¢=Þâ¸À<ƒÿ>¯ë%ñþ…|¯½öÚk¯½ÞAµöÚk¯½öÚk¯½Þ"ÅÌÐT´!6\�±Î›â„jíXþf‹M—›rÞ{\ßÜàძiŠXgL’?[!š6u Àérã`HV¤g Sv€#@Фƒ5Zóþ™uj@ ŽÇÞxú^ý oo‘B€ïí½g¬É¬å§ÁãU‡®ëpsuSe­ nõˆS¶Í4b³ƒˆzÀ%‚¨[Xç‘E°‘ƒJ PV¤¨ˆ,pJ‹÷™Í*¦ãØ¡ëG À®ëfES&3xW¹1¨p®³feg± ª@SnÜ„0!¥ï=Bôˆ1@RÕ1`†lÃßƒÉÆvÊ1a H1á4N“©¹¼ï0 È.°-)ˆ$«‡°"8euqç1ôƒ¹ðRÙ¶V}qÎqí2aãp8Xsا9Ïuš0M“YÔ&É $W—fæãŸ,sç3?彸€8ÝPtµó-øÈ‡�È›×>Åö§‰@Ù×F^Þ*$7I€É»„Í}!ŸK©¾ªÎ$Ñ™Püýmð@y|”-ä_óÕ}ÞÎÛ² Ä“{ì?5¶ÜEÁ¿¹pŽ5]w€Õm¶‘�´ ø™†/”ÑwúbÅ7¡ËåÏ^¿‡V†éZ£=.!†³8x�ánŸÓwÝ›kx‡ßùy¿®*d×%ùø;|ö¯üT|ë·ÿ½•Ꟛ}nVx!I ô�Çõõ€—Ÿ¼„w½ë¼ëÕ'r„�=×þÕß÷›ð]ßóýwž­‘´:Ë‹Dú,^Þ‚¬·P˵ÊgÛ>Ÿ“º”¨_´ØŠ&h¬°íŽlD ¬Ç~>ÔåNo‘΄óo’Pv»U%¯lªKÃbÇP[*çt6D•”SfLÛý½¬f_‘šy§ùZ;#à”çzQþëüÓ–p³õÖcår°5aª³Áæ\.„„ò©Ôüm¹]ÕÕñéù9¤q`ûFzÇÎnœ�ö­å~w6�Ë¿ÊvÛcÞ²­8ãOµ?¨×5}ô£ù·>ô?öÃï~ï'üCÇ.AU‡¾�ã8  ¦žÎk!©dLuwÅÎÁÁÕƒâì†Tˆªæ"P¬Ô+q0¿¾­Îq�g*NZåw…P[ˆ´Ë—gsý% ¬£süPYm¦KRÕ<õDtÉC@Œ"q^Ï»“sâÅœB¶þ ãBUcÀD´Sq?˜ïÕŠ˜WEõ{‰Sø‹Ð’œjµùWŸ�¼œ•-.*ó¸KqµŠ³£�’í|ô}�a8à0X¼Y×ðì@‘j$™ŠÔk¼ŒT híð E½onœWƒÛã]"µÚëÍþ“lýß܇2!AšX`G rõž¥jQIì»Ò8Ž˜¦ª@ŸL]×áp8Ô}.D”™ŒáÀ1.IÅù³Ûý´H4—#âÌÕëź½öÚk¯½öÚëíV;`¯½öÚk¯½öÚë-R”µ* +±ËJ—Ùæ¿4uBŒˆ!Våx¤Éc߸¹¾Â£G�ñðáC\]_eÛv L!N�I0NãdJ‘P3dÍBÕY“ Ä GÇ '¦Þa¶¬MRÔÔÿEåÓw„@I)$„qBGOG<ö OŸšýŒ#1ºÎc8ôè‡ÎyŒ(ŠqœRœK™¢€ 2wð}7�à�›’’AIÂBù$jÙ­Þ9Ä0e°™ˆ Å6URV;ÙY—ÝÈ�Þ9DöµAO§ÇÛ#Æq¬ç×9�Ð…šéIdŽ Þew�ΰ†¡ª D³Ó?žN8ÞÞÖ(ˆ®‹õX�w(V§¾ËY°b t¢´((çÓÒÂR·ºPòIc¥Úþ¾m¤³3"�ï:t}?MˆÉILá4�#n�Ãßù;ç—ˆÈo+ÛûÍ¿ñS,¯U˜€BRѬLûØÏ})NxôÞÏ<»¶Ú¶û ¼è,H€5ç ¼—<¿hI@cîêŒàHÌ€HÉ-øÉŸø¾ÿû¿ïí~Óšs²‰ƒÝä­Í>.¨â.êª7ek”›’r•7Ý´u˜OïâãZÈl/Ï ÷‹îëO,yöÀ’äpg�´Ç�ÏlIå%¾ëjõ}JUñiïÿdÜÜ^¸ªÀoøìOǾý{Ÿ]þ(û¬ZÜ –cmã¸Ô+ïC×áúªÇƒ›+ÜÜp5 õ5¢ŠÿÅg~ ^{íe|øÃ?÷‚±oÌÝï:WŒ^hMè@ƒÀëæ ½„cÒÆ¹;�L¿àA3YîÅ. Q@Ï�³½émi¸—êÿóñ¬¯lNfK�YÊÙgPQú¯!;2'Z»¬�Ê-ðvHZ¨iW÷Ý ƒà†ÌÀÿÕ;©Í¸o\ Àõ%S}ºð›å|¨Ñ#Å `K_Ótyj|Nä �ã¾¾¸ .Näí‹hu¡—ß¼I9YgÈWÀPÕ?ýSúóÃáê Ÿ¼üŠdóøøñãééÓ§Zb³ÌÒ`R Ù$ºN—çÒ&… ÉÔâíÚ¦(Û[໺eµºs.[¿ÏŠ÷ú'Ïà÷ëÄ™tIs;YpaEHIš×¥ëçW&‰dð¿ä¿‡�ײ)f'0‚sÅÝ¢XГÅESÖ[™ó–çªàWµ\zUYD<•1PµÏ$™×…õøÝ’QI^ÐIU²¦­is]k¶×µf'2Ƀ@lߺ®G0’iß÷ÕÆ:“¨mü¤žwr”×�Ò®Øî¹&9Ÿ½FjMͱ¦Å¨À&hÇ…üí®š!ßÌÅ!!Ĉ¦)Tמ{„ê6j<œófóŸÉ·[ä“�P¾·‹÷}%öê½r˜öÚk¯½öÚk¯·S퀽öÚk¯½öÚk¯·H©¬í©17kàÐq¶iìrN£&¤� $H ³y„" Àär~{�ÃÕ®¯¯ñðáC\®AìRgËÔ Ù2þxÄ41ÅX ÌŒŽ]¶ŠtàœIê8™u~VÕ( „¼Å@-Ç“ä­ „1ât<âÙ³çxvû ÏŸ>Ãéù3La„s?t¸¾¹ÆõÕCßÃùARÂ8¤¨`Àì«õ|Œn»ÜŒí\‡ÔYä@‰@`vp9›UÅuã4Úk³ui&R¤³ef> šêÉðÎ=*9 ¥É²ìG»ÛjÛ÷’b´mwýç:°3�ó˜­‘zûüˆoq:ñüùs�'Ä0Õæ]Œ¦äJYµVÛà=E#7„)«ëÇÑìõ§P›¯Flð0"€7ñŠNJö(!Å¢2(¼*D ø®ÍñªjJÕ"¶þ¥1… ÝÔYlÏ�Ç¡ï�†+1RЦbrIÓxÂñxüãåûÊ'~ÂËøÄw?‚¤RÁÔdÏ–ÏìSÄSbœðò/þ¬ó ŒfÍuí¡ßÓ  �P&ðE€‚™$M¨$mHý«þj¶,~»VVèUÙüãŘ×Q?S�çhâòö½ü³ü_m£AŸ–Ð5|ù˜Ê¶—`~óùg;·<°ÙiœÎÀè Ö jôõ8ÞÀPÕ€o¦~ÅgüÒ{¾Rðþ_ö è¼·˜“Åå4_S” ôׯÎX7°ÉûŠ ?íS>éNÀ¥q›OÓ†\ ø¼Ú©v¦4y쫸õ˜®÷ =S–ŸŸ?ºð÷rOºèrœY¢Ñ–�¾­5žäÛX)ãu¥¤§ $€ûÃE³@Áý‰î¸ ò¾ΉZÀL=¿Il˜8Ü}¯ÉN2$k.mj&Ä2’`&_l‘„–sèüo>ŸtÃE£ýŒ2Ç ¡Fç[šlê…™}Ç¿ç;;]<·"V±tF¿ º®Ü¼fN�Õ¼.rDð ?þcÿÓ_êûÃWôý`¯bRïÝ$´ÏYô „B5A…Í�‚taÁJ8³í_d¥ÛtÇ "IYï¬ÏñvÀö%L•p;;?ˆ �]®D²Š]˪Œkÿ¢ŸÝ f»÷�ÂÔðjëU©¾Yת)Í21jd@±¹_×õvƒ²¶•Æn¾%H´×X%µz#ƒiqý¯(õŽë˜á}‡®ï,Ò¬ó`çìZH Jd@Èä‰J¶ãl Pj‘e-cãI ‘¤%7¨h�Ë)×cVÛÛv¤®ocŒ•¬=ƒ÷yŒSZÞÙêç‚eãö–ç@9·å»H�VpŠyÎ:ÅÕ<Ô™”ÂÙ�Ìe" !Š4䄽öÚk¯½öÚë�P;`¯½öÚk¯½öÚë-RI4éà5å5/�lK8U©Y�©Q¯Q„sÙ5 óÖ$ë{t}gM¶¤íï0E²HÂ#B˜2(n�»ä:8§p”ÀçýqÖ€ëÅ#¥>uH]‚—]¯Ö(%¹('Ü�xúüž½ñ··Ï0O`†~ÀÕÕÜÜàææÃáP-UC N1fІàØ[£47˜Ãá`ª/&³,U#+×™jÓÌTQ¦:�S„Ë Ë”bV£[s�5e�9�‡óp~¶À?­É8žR&p’(†Á¬¬Íâ^,à0`:ôÝvvÇqÄíó#N§ÏžÝâùó[LÓ)ÇÌy­¢R‰ 1¨^Téâmßc H‘$B2˜ÏT,F¹QaÍÙ¸Ä †‡w q ‘Üt,ö³ù¸ÛægivS"HšUM³µéêµI�b2ò„X,CßÙø|çM�ç\Ú¿ôþü�ˆ¾´\¿áWý2S«‰Â �X1Ê-8H �!UÅ—Š"ýèßÅ»Éç  4_”#é[µí]NBƒ‘ÁýL ˆeËfð¦Œ[ëÀ×q�IbøÖoþ¦·÷ +÷“—„” ÊÓµcöâÕ5º(„¡3Ù€ló°/Aû»§ç{ؾö–�I +@¿Uû/>mŽ5˜ÕÙK%ãü�ßsG>}u¸ {ï«Õò}ª\ŸŸñ©Ÿ|ï÷8ÞóÞWñÁŸøé3ü�°½ž«ñ/ íªÔÖÙã.“"AðéïÿÅøÎïú¾791} ¨·d€ êbSмž»kW€‹Iºæ \ÿgëütorœ/�?\ �¬?ç2ø¿Vÿ7Êöå.®¤™€E~ûÝá£vÆÌçisi‹Ýç€=6\š�l/§úŒ­À×ìÝQÂ…L5|‡¤³ÓA&FÌ¡³ÿÇò|Ò�1g¿*&(uîêÒ¹ó½´(|ËЙZ¼|¾.ïKù|ê%{‡;î§÷¹çq"lîÒÖ9×��Èǘbúôþ~è?ø´Ïøÿ¸÷^]ˆòàáC9ÞÞÆ¢ÆNíÛ´u$Êk;RhC0°›ÁÊg€o þëÿBölßÅ9«ëN}Áõió��¶¬›”,o^$¯£Tª£ÁÚ–¾¸”õêü±ë‰y¾§ öJ½GÛ¡ØJ…ˆìœiCææ{T»\�C#³ô÷�E½sjæhÚ|,�ÙŽßÎ…‘~½ëŒà †¤„I‘‰°Æñ„qš�b„WBvqʤÖ$�ì–�b‚Ôu(À”�’€9åÏ×åíH–KL)÷ÇÆ9È® ™ cÈ„ Y‘Hì€Sãôå2@/]—¿8#9ä5y­äÛâúVækQ÷K’³çÇü=`IH"Ù"ì_È÷Úk¯½öÚëT;`¯½öÚk¯½öÚë-Ra Ué`Ú)+9ÈÑEÙ$)ÿ1™z=Æloïôàqn¼ùªÒIª¦j)½5SƒäÿœsHê€XöÊY’LéO¥™DÇçBô)a�IzQ(}ô¾Ï* Å„išpº=átñ³d[ñ•zÖ€ýÖÞXï$¨ˆÙ«fò1ÂàìP²È&Ñ«NL ɶ×Ì |Û·~o¼ñúÛû†•qˆ¹é¿•ã=ÿüÑðóëZPö€Ò�×íà÷ ±ë¹v†òV�þʾä]ë ä_¬¾à@ÏÁÒKùô—7T! " oRý_úË?ñÞ'Z¡xÏ»^Æ?øÓ[þò”ÕÿL )ŠÔòþÅIË‘!¢sTËÆgJ²kî3ßÿI÷ÜÏefüçâ^àž‹{1 ‚A€08$¥EH¶!;ì�|³Ca“”mùÑa:а(…ƒ!ŠE œDŠÄtAxAÄtçyžÎ¸ÏÞ»»×ªÊü?äœUµº÷Á±ÏŽúOôéÞÝkÕ�•™U+¿‰Ó¢9h£Ð“-J“E¦�!Pd¨”{] 8,ªö}‡Ýî7n<„³³8=;C?œx€:䃊Xg1M>“�ÏÿìM‡“ÝÚ–wÃnð zÖzÕKˆJ°ØàÖǺ³€�€ÉÁY†VóJ�‚8›¬>½ ß/Ði£¡Ä/.{å­�_ðÇæ•ú“�|&gÈ[í»¶w`'ɺsš&\^°?ì1�XkAäó±MסïtaÁ/. ŽÓ ØÂ:†éŒWׇ~bº'ð À»aH}ʘÚŸùÙEfÉ®Zü¹�B�”mpMˆ`¿.ëØGE“·rõVÿ�ñù¬� ª9¥‘EIv$P“ƨ¦qÒÌ#�ÿ8öùú�—0ìv˜&ÀMˆ� ÎïŸHA³Ï¯�ZM² Aáå/ü6ž~ñ�ÝiìÆÞ"6€ý¥R?‚„‘íù³K†/Ÿ-ìפ©qH$€…8€@ ùÇÿè<s–»‡ƒ%a¾¬ä‡Ïj‘ Œ/-ç×¶WZó_kŸÇºyc˜�¼3ÐV®Ý@BWW¹µ®ëîIýëÆé :;¹öëYÏ)•ù8¤çh­1 ½wa ¯ñ¤ãã´ÂsøÀzçºüLÈ*1 Ýs9 ã‡qL¯cöŸ�Æ�°ÕV[mµÕVTm€­¶Új«­¶Új«û¤ã˜>Z+¨Ne e‘­.ì%Î:Lv̹ðqESü_gLZü±Özu9{ky¯jŸRd€é v2 3:,h†Å:çäœXkÁ2ÁM^1#,p–à:†‹ÊkE Ò \Ž‹‡ã8â0�°Ö¿Ò ¢�1xèÆ ˜¦Ó§hïw°¿Üãüî..α¿¼Äd§`óiÐ…H„ÝÉ †¾Aéïö¼OŽA ‡'AhO†èŒ�|(í?UZàUõB%e…¿ˆ‰8+ÚÙFÔ`ÃÈ6Yÿ´Ñè»9®Kg:˜Î[Z8¦´`¬œ³½%R"Bï'ÿÎwøÐJáÏýðw!dýB™á¦É«×ˆ šƒ½«?> ‹àJ{ß׿ø;xúù‹ÝÑ @ ¥pYIùïÐ,HÒ$,^Çlñ P\� ðÕ/|úàï=3–gå¿sQ“�Žå×Iîƒõ¦Ó£ç*{�·­N9¸Ò¸g†A­¶^ó{Ÿìb%ü±q÷¯,æ ¥î±Ì÷cíÛ¶G©h÷ªþÞ®X%žzòQ\ë$ƒbT¬Å‹O=œÎ§IBXxotÃð×dÑŽ$„Sõ™×.©A�s8 nÜ8Å�;çW¶W¥¯c9�ÁK.ˆ˜o9/Ä{.UÇ]*í3àzÜîa‰"÷ÒŠùh®å¾bK �•Ûÿ¼½Vè]òZdé˜V{ªÌòê«>�’‹A ølÌ$fêïdg?ãšøû}´¯_ήo¢ $ìž‘�¾ò~W¾7Ç õçý óB=ë²SÅÛ'?ïÉœê÷ÅÕùɬƒ¶î+´0qÍ;Ý ã¢èŒ2Ÿí›“×€ãn ~Œ•M—Ç™B€�¦ïýÄG?ô·žñ›þòO<õiò)|òøé^XÁ CÂsnu_X/À8i�-Ò9’?UÕ_K8>“;çªø#¯Ä¶ï¨tânÆ`PòÈ?óYð\Å‚Ðù�Ý òμ›— @…c�ì�Ôý„â5ñÙGæÏ�Y ‚÷±ÏÆ6‰Ï‹Õv‚½½'¾Ž§ÑÑÑÚÞ*8­í�ÁZ k]"§¶ˆ÷Çp“[�µ‡Ããá€ÉN`fh­Ð¡k�Òâ‰&‚üy l?[ï××t$Ü$8¡ùþ  â5N+õý&ýž9¹PµílºJk ½Ë—Ve7‡H ˜FÿG›É“mµ†1LøÙ:LÖÂ2Q<ìK…> Oæ­žë¶Új«­¶Új«·{m€­¶Új«­¶Új«û¤¦iØ—Jà?<\¶ýw6Y7&×R~A6¬pGu(Á/êì÷{k¥ü¢·HZRZe+iEÐâÅÊÌÓ!¨j{8YÍ33XÄY(«`•ÏМô=*@.Øâï÷{.pì •ß—"ÂnØáæÍ3aRÛõ��¡tç_ß™äÀ!OÕ““邪‹OOˆ¸¼ØC„qy¹ÇíÛwp÷îì÷‡�5ªÐw»Ý§§>. è òõJ'¯xoAwÎA¢@Ty)BŠ7`É‹ÔÑ�À+ÿˆV²AñÎ)Š"/€úëáÁÿqòmÛ‡ˆÐú®ÃÉÉ úa@g:¯š ‘±½ƒMi/"½ˆ ŽÙ8gÉYç¦qüOâþþÈû^À£ß:-`„aG—ú±¿V¿«j* xåKÂϽê䱤`�.Àœ 8¥’ À1@Á @,pp ˆp´ÇùÓ?ýS×R3¿Š™kujÂÚ–äì ¤UŠ�—Ê‘ÿÕ€)ÿ<*l«]K“{ŒLôIÇB‹6ÔÇj f]Ôø7 }¢ÒXN×ÚõŽpÞå¼p¯u€Á”ÃÓO?ìÃ�Ì@¨¡8DK}¢˜¦NhADa&€]€:f?O9›ˆO“hÅZ¿zýÜ_•£—оYÚÇK¶©iÞŽ�T²n/YåüRfË/æL ¸ÐKD…b®¼¢™¬äz}|9 ¡a¼Pµžûh¸Í8g¿õ‹_øìß¾¸¸û—Ÿzúùß>ÿâàðâ‹ïN ~„«†áû‹.3íð+TºZQz†«‡ $ç§dýN9’©lOÏwY¦©¤í±¿ö’žÑÃ3y’'þØ.†–Q´*|0œ—�û}ñü„¸€ð¹C€¾#Nc", ºL*ð¯ËÑþñȆóñYÎ&'…¨8ÇÆàxŸÓ¬vP¬aX@aÀÚ Ó8ÁN#Û@Öñ·2¼gLÓ„ñpÀ!¹iQʧ–¤ÿùG�‡Rkc`Âç�Hf&¥Q#“)tø›*\–À×ü½|M ¶—¯ñ‘;(¥gîÎÙôü“1Á5À?”ne�™`µwcÇé³@ܦé|ü;œ¶Új«­¶Új«¥6ÀV[mµÕV[mµÕ}R1»èŒ*’­}´hŒjP³`DÚ+Û˜1 ;ôC¥MÈ�Ÿàܔ֕™¼ú ­¡û΃è]ç3çÙ/búŒ9àR‡…Mx/p4A ‰x€d{ʘìä�€�&ŒûÎ/÷pÖÂh�îdÀ®prrЇnœáìôÃÐ唯] 'x Û³R€f*l9ƒÚ?,*RÐFûvqÔ>‚ÎtFà ‘¬Œ'¢¤N�v›F¢Í½ƒ�¼š m¯u‡Ýn„¶êû]ߨ.+‰Ø"ªþc«?FÆa¿×Âá°?àüâwïÜÅl8ûÞÇìNN°Ûíprzоë¡�;Æa<’A&ntÖC` «~ULürÆj\˜µpÅ"e°ÕñµiñR aQÎY²ÓD‡qTãá€išHDQß÷Êh­NNNèôôLõCO]×ŵv%>\±c²ìï';õýȇýȇ>ôâ믽òÂùÝów:çþ½¸(ùçä; ââkœY Ž�ƒáÉŽ,”µöŒ§:üë_ùê[ÐÝx&]û’ •Jv¾ñÄcÚ¹ßï !J ’ÍWdÄ�µø¹Ÿý™c¾JJ¼E?r(vvÛ@óº,1^†•¨Êg^�ŠmI»í0hn¾�òÛà9WA/�~Kç&så·,€i+›‘ö°¤ö3�1îQý_ŽëÇ~èêë+ ¤ùÕâñGNø_Åa@fªgBN†A8%…E}&x‹ 9ãmÿ»ÐX°e<|ó´Êñ^mûØþ´(G¥6ƒš#ȉ%  9I4‡Tü]f}¨vÈ El]íO«ÇL+§H^X‹¨¡Ð ž¹%ÐìGjúåú±‡1Hsà•2Äâø¦õéA¤Ž(�²áSo΃ \±êã¡fŒ–x~uýRÛêîy¨Ú™Ú9¨i¹ä®1‹½ ‚äRìM¦#H[ 7Œâ˱^V¥ ÷D4�ywš h6sÎ.屡H¨åµÊN±Ÿ„ùéW_~ùo^^\þµgŸ{ñŸˆˆpñÙÏ|zÒÆ8­µ}î¹ç%ñ¤çêîèH¡À~n¯lëhš@äÉ“µ˜¦É>fPǵ¸Ùû%¨ôýç‰))õ#AÚÏoœ ÈÂoø@ WZCk“Î/!¼ë�'Hhx€ßã¿tÓE%½�V>þA)Òü׺%4ñœ×†¡�©ˆÞµMŠ×ºª�Dÿ®ë ¢±í4E¸ÍŸ”?vIç ¡Ãqêä·áŸß,¦)ÎTZ­:lµÕV[mµÕVoßÚ[mµÕV[mµÕV÷Q‘R0F{+Ç�ÓÀ+_‡lûhßèÃÈËìN DA+�ÝnÀ°`´Š,[LÁ_Ä%p@it}²�ìÍm¼)[öÙíÖï¿O¥`� ùñäÕ2Æ¥90Y ;9Æ—ûKŒûÖY(¥0ô;œžìpãÆC¸yöNOOaLV­[Çá|ƒ:ÙªT‡Å7¿_¿ˆ6M¦ÃZ<îÝ�4y07Zp“J1D:啺¾Gßy›úh}ï¬K$€¨rwÖÂtÆéƒë=øn:ô�A×w°v‚saÑ2’9à�ÕZÁápH™�ã!æŽNÁ¡€=1¢ïÐ÷†¾G? úÃÐCk“”c BTžE••u4uû~£”©Ð†…�kÌÖ #ºZô%,ZDŒuÖ8vÚ1k;Y}GuØïÕ8Žz²V‹ˆî»N)cLgúa0»ÝN÷àŒÑÚZ§÷·ëñ�ì£/¾úê+/ܽsûÅË‹ËgÆñðüdí³ì\B#•Rè‚éÙ§Áû^z1,k€Úô²ËÇ:]Â……d¶V� E°ã…WyI\&fôâðÚ×>‰G±{ô©ÊŠ$€òxJ•{$hò²ˆ àð®BVs´@Oo„ø…_øܹ}û�˜«¸ KÌK²¹Ð1Ý^_*°Q¨z[} /5YÖ¸öîžœTã=Kï’B¬åÐ, ǽäkš�cþ·¬î¡.E„“““+€ì…v.ö}ôæñk+ qá>!ì,z†Þà°?$p˜À`(¨ ÏçêÕ�ÐpÌs—†�K/bÁl!æ9f°óó);‡G¾‘Û¯ºVGHá"WZÛÔ2ÙÆ5Äÿ…äöàf/Ú2$�Kda 4W69#ÄqQ�–ú‹-lÇûdtV�è^P[ÿ—7ÍYŽ�rpL»¼Ww¢æÛ¢öš6M×li΄ ”®ÍI•Ñ�KÇŒ(”ÃX-&´?f’HÜfŒhjÕïy2 ÊrÔ‘žÂÀ�s@‘wß:ˆ$€ÔWShì÷%ÁBdyŽ^™q®Rë×1Ë“úõÂTŽí¿é£¡íR GÎåˆMuãüîí¿þ…Ï}ê�>ýÜ‹ÿÏÎtoØ‹ÈÀÁtæAöhïNÔöÌ"KkvDs‚IKÈNN %°ëŸe³›uwIrˆ6ñ’›€SÁRRÜqØW{lœˆtþÙß%bAŒAˆïK½²pLñç¹Æþ(ïZ—d;eWoÕoí”ãòÑÏjÑ¥€iÕ%2°Vuï ÇNZwè{×-‚é ú¡GßwéܘëkÒu^ñOÊ!Œé uüLÔUŸ±”QÉ2?*ó•Ò• @ù™%FuIöW$€¢ï´?ÇívÐ÷Ûóï±Öñ.lO)…qê=q@Lá¸B‹1-qc#lµÕV[mµÕƒW`«­¶Új«­¶Úê>©PÇüô¾ï“�»s.XÚO�`ßx°Ÿ£±¥ªs+‡Ý»amŒ_ü›ãèÕ2»d›éÕ'F ´W^FmøÅAÀ!_T@:Úè{¥IT�ÛÉâòò·oßÁùù9Æi„V ''§8=9Án8ÁÍáæCa|~§›ÎzÕ½c *´øo¤dƒÝ¨�pØ{`v²ÆiD?t0]V½;ëÉ~!­‡Ruþ¥ÑÆ[eå|"E  FŒãèU4Æ$kþ¨ÖÚ 3“éâ¯WJZÈõʧÃ~�ËËKŒ‡ÆÉG\}ßAw}? v^ùc LçûDg:°t¡/جÞRÞuÁ:§ ²š–s[•.l^uõûÂ*U‰ÀˆHÏŽ»ÉN½c78gÍ4NÝþ°7ûËKs8Ì8NÚ9kL×õDÔ}í«_yüC¿÷ò;n¿yë›.ÎÏŸ¿¸¼|öòòòéñpxš™w-À¶äý«Mþxòã?òmP¤½ºÑdBÁt}ÕÏG\À‡š&¸°PÏaÌÇ�ÞAœÃ«¯|�¸7žx·¿Æ¨c”o4DcÖ%€ƒ' $Wʳ €( -q ’œþÑ?ø{”ýYF™Ô¹’”ßT¨†+à¦ÞBÕÒŠ`ž*P4f·Ï\ …jVÔf�,µNÊõ"ƒzaËÕ(ôKEwÚyýŽY>9äˆÁvþ ð?Ãî¥Jâ‰Ç^¿®ü瘹ìsš�³Øíܾ}^�-$ìïATÀ�QÕšX^=Ë‘¤™ŽÞz8(?� $0?®yèd3RÓj‹‚ä .ÁÊ2�»î/IRÚ©ÞZvh;eãþèQ÷—E–‰2ëãåèÕN£%ÚãËLµ_„­êiŽZ#œ,ÅÃ/ä -÷ü•¡„µʬm(«êŒ5(Ìñð�{:Dåóà+ð_E³ðR…ß�¤Ê<ñmÈõ>ò�úY'ö{ G5UÄi‚ˆfmÒxP¤9‹d–· qN$ƒ5dž¥è–k\t,NãËlyêMg½ºkj|¹kÖIhÿë¯|ñsäñ'žþ¿<úøŸÔZßÕZÑW¿òe¼ðÂ;‚×ñDAc Z×»�ŠúRI]©,áÙ<æá¤% D9º(RÅqD \RXÄ eÇ Yk&¥P«ÿEÌ„'©F¬ÿµ®Î/žT˜«#ÙOÄ+Ú­ÓPŠ¡ûh& *sçàÂó’·§”«¨»L€!•H0MžlÅ8ñN0‘L¡”ÿ"åÇ®Ò>úÊTPñwZ{p¿ë;èÎÓ˜½û•ïiñ3Åë¢=‘¹3=´îüWülæ‡x¼JåkX‚ÿJ«j>`öÇV_#‚µ6BÒWxΔâ>_¯µIÏ¢è§ðì“ìüùˆ8ë‰zÒ£ÓõKÎrásZì‡Dõ˜O#[mµÕV[mµÕQ`«­¶Új«­¶Úê>©®ë0t†Ý}°•”å!À¹*»‘Á V%�˜�Яl×�·óvN[(œ88ká ½G;t4ÁÑ(]ç5Íñà§xXÖ[šjÄEI50ââò€Û·oãÎí;Ý„]?ž°:œ�žàôÆŒR˜cŠày°)å2|DÁ/ü1[¸ DŠ˜Ó4b?îÑï;ôCçüàí­¥%‘´Ò‰XÄ|Ô&ו.X º`�C@ü¡àz‡ÉN< ÀtÌ!Æ€%-¨ZË˜Æ ççç¸}ûûKLAůµFß~‘²ó‘}ì;µÏ íŒ?ŸXœ”EœlGSNkpˆÎ^õ¥ÉÀ„¸ƒ®ëÐ™ŽˆH)¥´VÚ‘Qš: 츷d{Çn'"ƒc¬�ú¯~ùK7?óéOÓo¼þâåÅù ãáð¼µö9çÜÓÌ|–òœ—ѺغÍwÿ“Vù:œì:ü©üNO^ �À‘êžPÖD—°Ó$¦p ƒbŒ£ŠÌ;9ôìpëÕ/‚툛Ï|›o/*ÚÑ`_!ðV¸á÷щTÀiå8AŠŸÿìgñÁßû½b®Êm±IâGŵ´ÉÇ”í»3ÀYü}µ(áË@ô’â´6Ÿ.A£dížTÄh”¥KÝ÷zšÖ¤è®‚¹éÈÙe8{vñ< Ã�2Þj‰¾ycùºà?; „8Àáô¤ŸÅT$;¥ˆê˜wïpÈþéð *ب{»g fÀ¶“'ö8ÆéÐ/ƒƒ3I1§P‘ùáÜ6ø¾û‰–”ï�P:‚2^"ô�¥6_¸òÑ·BªlzT®uŸ€«Ýj½ÌÔá©7Õîÿ1±#|_‹%;úY‰-•{ÇŠ2ñ ±;@õÔ‚ö*^¹éü¯Ñyß:Ñ©Áæ½ÚéLÍ.éJ“´†!…z»ºÎT‘ÒƒMñ*YQÍÑõ´ôÙ¢‰@ÄõUpx«$´f,\Ý ¯˜)Û^¹ä¶B³è©ÈÔ¸&„û³³ßõÊ+_ýÉóóÛÿÅ·¼ôÞ¿­µÖR_ýÊ—I ÓsÏ=ï\ëQ^¿9 fÉê¿ýy�PZì·êëëDÔP9L¥‰ñ´BjÜZ§‚ð/ ü/8�D…D‚­—…ËŒúöží™P»JyÇ)ÊÏA¡^¶�sΟ•R)*¦Ò¸ï_ωT!ày¦Šˆ´³¥•…g[fOÖF¡ë´ŽÇäà`]î+7ÐZ%Å¿1ƒ·ÿÊÌHdñ|\) QU”ŽÉ?¸úçD ñhñ³El³ää•^¢Ãã ܬ}ã1gà~9†"~ÉT8XR´@ÜŽ1¦"10oêÿ­¶Új«­¶zÐj#lµÕV[mµÕV[Ý'ÕuÆÛ¾úaH £µSÊÔB ËgÂûÕ{EÙ‚3‚ZD ¤:¸Î�ám�-ky€'îÇ+õ½ý¿ë,ÆÉ[øsP‘Ó%õ�Q&,R¦i³WuŽãˆËË...ᜅFV�€w@�×H³dÕm’u\œ ‹xd ,À  kdèšwºÞ…� çsÕ²VVáÈLAå�µØ_^â®ÖèúÂkGÿ`­ ¤h­CØä0Möû=öû ßÖ»è ò'òÇÞõº®ƒéú@*èB,@ŸUü¤”VJMÖ*ñ²UÍŽ‰-+fG̬³rÖ3¥�†µ½êú^ <(ŠˆÈÀhb2DÊ(Àˆ�yùå¯ßøÀ¯ýÚ»¿ö•¯¼óöí[ßt~÷ü…Ãaÿü8ŽÏ:çnGE} Èv<ºü�Š Â~èûÞ�Ó“|Â8 Š¡­À‘J£é ÁÕ1,&(ah‰‘ Ûä âpû–àpyO¾ë� N¾. f×FEg"�‡ØB`�VÐøÉŸø»žú¿É}o�üx•¥êËþB­"¥gU é\Œ€©¤ Jå2!e@©ôŽJä㪕֔QÑâõ÷BX#¸7çþôò®ë0 Ã[º^-Xsãìd~Mðß± ÷‡ˆfœìz@)T¦ â.¼hS|$@arž�Ôlê›Ve ‰Å«ýÅJŠq΂ׄݠR¨”òØò©+%1s]«ž¯'I"ª,[’Gý@ä¾(׿ž´øoš‹®ÆIud ýpÞ óƒ«Îóø“ dKÅX¨Ú¬!µP…¾× H(h˜ tý~%@ þ›þ1Q•»¸ƒðZÉ$�Y¼AîQ6Gåö’}~E÷(¾åq–Ï£$KUÉÅÁHÎLi.º,Þ3eé�¯kÿ+Ø<y˜×¼Æú-OMom"«žjð²)"ƒ0¾øÅ/Øi²Îù Ž�1î™gŸãR M*ÿ\gÓ „l9««Tü¼vñüàï3ã}»'xz%vê»òüÃùÍÀB ’â¤�=ZÔ‘ ‘¬¨¡Ù3o<_nléãùÛÉ&ºüûj$Bs�Ë6ÖZC“‚"]'!c‰A$>â+¸X©Â±Ã[ý‡Ï ½Á·µÑŒ'þ[;&Ð=Æ Äg;­4ŒîÐwºðÙÁ[ü#“s¤c*¹>y¶Cà£"B©LØ-Ýb[•à¿4í–œ¾It+‹ÑŠ”'ƒ7ÖþÎY©@|ÈÎgì÷€q ®Õ—¶Új«­¶Új«·_m€­¶Új«­¶Új«ûåÁ,(½»®OÊ“Êf›š4„ŠÌL88¿pèýâ�W°k'Þ®S{xÌ„€QØ9x«QÀY†U€÷#x:º)XÖ; ¥¼eßù¬É¨ñÊwO°“\c¦³w pŒ>²@X ÁæÓ%@U+ˆéð�•Edf §üj©µÖM‰ô ´A×솆¡G×uAñÊ{K"C‘w °Áb_…kѱñ>˰HrƒBˆæÐ¢Clš$å’`Ì<¡‚ ·„¥ûv¾*|Vðna Ãói$äkÉ!B®Ž>Ë1á=ŠÀNVûÀV[mµÕV[mõ6^gÞš`«­¶Új«­¶Úêþ(¿ ¨g �>ÿQW¯ea°õôÖºd³é:ätZ;Á‘´WÐ{µ¹ß¾ÑÆN˜Æ`�_º,;ÈPü'ëÊœ³(÷«ÿ]ØW¶9MŠ–}¾}̪§°Èd:¯v7Æ/i:kq˜ÆqÄ4yå'‚Õ;�RÎ'‘†®¹¤­+@ùefçØy›PEìücniƒKA%#"@´¹ à±��#WY£jíDZØ`÷ïœÅÅÅEÎZ Ze[W¢œŸ=�¬�Âv4ú¡àîŒÆ°ë¡MÎmÕÚ_o­MÎ6%ê•R=õ;Ú DÔk«‡z˜y°VzéE¤á€ÇÃÉç>ó™_íµîžß}nyñÜa¿fǧó��ÄŸB[ùï•%´,+Ñl£­ãÀFìûYIöžw>ƒž~Ê(HPу¨¨ @‡(c¥ †!ì…öIéaˆï�ˆ«š¬e¿þ™ßÀÓïü^Àìf$Ð̉ â#0Z�s`­ý‰yÏDø¹ŸýœŸŸ¯¨Iß^U.¯�‘kl²8/TÎBÝS¬˜¥Øi©&�¿.3ÁK·êäˆRpY�µi¹4'ê·+Iyz¬Ç—ãâÚ¸¡Q£{påôììríbß¿qzRÝKæàpV�óý\Jºqæ7lRæ¡‹$pX�ÁEè|L´®Z&ⓞ°ã,D…ŒhçÉRb=`µÔ‘6Æj¿“öTöÃDªËL(Œ&V¶&!B•3ÁQG‚°^sIY:ø¥Hövȵ[Q0Þîÿ­tœ�Y_ÄÌ °håO‚YÜÀµwÚíˆO¡³Q‘QîWX|ßBíVŸ©@—Ú¦qMHˆx„î©î¼(çŠÚ1(ÛÈ×.)ΣP­ ËòùV¿­3Á×Ášß’ÃÄ'8nb’ûæ[è$´ÒåÑ’\hvu+Ó˜•ƒ‹q ‘:Û"]g¾•ayù}øƒ¿÷~ø‘¿ñ®w¿çŸèÀ…s´ˆìß|ãõýãO?%J« gˆËv.�¢88<íã°´>¤gwø{Ò¬6¦°¼/nw æÒ~C*×/¯<Ïs9³«¬ÿ³ª�‹y*ÞÎ:#œŒÊvŠVõù>_ï×;[eòƒ•Uz®�ÏX1A}ÎÕûÒvá½ ²š=«8ñíÌìÉg ¢âAv Fw!œ+Ä b(­¡{…Në†p²žÿløÜ3M#˜Æh(Ò�Ž¡B¬‘®Hk÷Sÿ™Àù÷„ŽÌäêk]9(»Ä6­‰<³ü/¿HÄÕïº.õ#c¼ƒXßwÙ±J“µ)&¬¼F‘ˆÇ•?†HôÞj«­¶Új«­”Ú[mµÕV[mµÕV÷IUj#΀&‘ €p^,rÎa”°¦i‚�&Š\P¼KXìqÌ>¯’”«{ÓiXÓÁØ“6ÞªžÅ/ÈQˆ`IÊ,¡¡|v§Ò^ectW-bZg1�ö‡ÎZ@òìw»ÃÐAi‡Ã8"ÓŽ“'2ÄóV¤Š•ÝÜ.Ф|.|'«­Ï-�mX`$ÇÁrÓ1Ä„ÒÈ ·ÄJÄyñ[)…®÷ÇÚw†Ý„ñpÀ8ùïÓ4A„Ã"ž�ÖˆJù…Pg-ã„q<ÀY c4v»“ zÒ0FÃh¿ Üu] n”=B´0÷"<8æ�µ#¢Aiubº~ÈÀìvv²'/ýk�}âcû–W_yùwïÜyþòòâÙqŸš¦éQ”iau<³„^é—s¬áˆzUàÛ·.,òÇdðã?ú>(lT‰‚í?Î�(Å ¤chÖ�®oÎáÖzP’�K‹ê9‡5DN «D¿þ¹ßÄÓßô=€9õû $À÷ùë�€ $€ÜÒÀOýäO>0s¯Ù8\—×P€QXP9g®I‘Ñÿlæ[ðÓÿ™*K9 MN´peÙÜbŽág\0xX=bGOëjÖê‡VPOHóàÙÙÙïK˜ÛÚÿ‹NO}”À:øo!<Á¹ r }§21F$jò§#éw‡ 9nÌV�€Áì­þ�2ž "6Øm;œ &˜‚k“*f òEтײðj¯5ºÒdéÿµÃÅ @d©ãe€`åœ bVù7b’ÛÀ½¨»×Æò‚{²ߋTçSsÇJ»ý«¦Œú… 0—âÔË—;JöááJÚ6kÀÿ#B³vˆ9å‹c•¨¬Ø—;`Ùïó-pN‹9r¡ �^£ÕQu!˜ã~sâ“,ÌÁh2ç¥�&�ù€Én.� ™OŽ §˜F-�#ÿ\šÒŽŒý*÷^–f\‚?uëÖëÿÙïýöÿüÜ|øá¿ùâ7}óÏ)E½ˆtD¤YX½öõ—/¼ã+ 3&é–aƒ‚>ÙÇS´SäÏ@ôJÿü{¥‚€Öuæ}Ñ_ýÄéïoDS­ÚÎc,Îé®p(â'qÁÁÛ~ÇSuìž)DÕ="üj Z'+úø7f;8<•SÚFˆ ~ŒÏò„…âÆÈ *|¥ýŠ¿7¹0¸¼úß;D¥ÏqŽƒøû˜06f5H±¶Å?÷±øÏBÓè#ͦiÄ8Náøš˜Nkd©øüèïmª"gTVþ,ÐF|,Xh«’è£ÔÀ(û\‘+�1Ð÷Ÿ/<á¡&†GBwÜ·6}×%Wf¯þw6’s_R) ~ÖtÎÁZÿßj«­¶Új«­œÚ[mµÕV[mµÕV÷QÅ|MÑ’þMa11.ðìä!Ç‘‚Âc;X²0º®Ï FäÑïh©‚ÚÚhã4Œîaí7¹è$m~$d6‡\Mc<¨o ”Ñ ¥“ªÈNÖå‡=¬³ ú®C7tØ�ìÐ}P¦8ÿ;�E09[)¿ jBÄ€R°_mfås"….(V¬³°“�5Æ/n;T2E)|U‹g*ÛRÏ”•á5Ñ­ ¼&ûýççwÁŽÃ"™ wå{ Düßï/iyAûý^³0£Ôn8UýЫ¾ï•1Fi£%"ŠH)¥üÏ̬œóöþJëíì>þ±�>õ‘ýÞK¯¼üò»Þ¼uë�ççç/ìûçì4Ý\îQ5è¿X1zxé÷Ñ,˜Ú-Ðr\v±½Ùq”Û*Üròì´Ç~ﷇ؂0A‘xk}M€KÆâÞ+ïà€.ü>Þ @Â1Øy ÇYXt Ï qákŸÿ-<óÂw�vÏ[òš$¾d€æÃú>õÉO¦÷¼]+/órºFUJk©e¢µP´@ýо˜²Ø“ê:Çx{ë¢oÒØK�ݶ (ëë_V3Z—y‘Ò*¸ i•úíÞÒ‹ˆ€““Ó¶¿õ~Sÿe›_ þ[—¬£ƒÕ ÎNMpg@ªN(ú<‰äÌu´p¥¤†‹$µ¸vâ‚+ÄŽS„L¾nG@ñã�‘ú ­^‹¥ùmyî*Õÿ‹`xCT¡†�-ú£b|i+Yõ-×<áh¥-+Ý«íkr”ÀPn#éå ûýòx¥[R„kH9‚š{’„±[SDêŸÒ�&ÓÙI$î›#¹„R90PrÆoÁÿô]Z€<Ç´t¥ERLùˆ¤e5ÑE´ŽTä‚u’Eœ‹$„ Χ�’²vé˹suÂo(¹.”Ó-MŠˆäª"+¢¸º‘(T\ˆDT‘j`fU8 …~B ® Î$ÅО;t8çÞùÆë¯ýç·ß¼õœÝxè¿}þÅwþODÔ‰ÈàÄí?ÿ¹ÏOX)Åb¥”�RBÞ³"Ââœì:­|^¼6èQ•!¯iJ;tA�À€à�óߣ#¸D±À“Õ~Iˆ ·°óq`ÎÂëÿ–Ï)"þ¹˜ÅÄ~I5QÀBD'Ð?¿Vùg*í�œåD’‰ÑLÕ?Ú_Ò˜õä/€É¦h›Ñ,v�ÀAÄþaq°âvÁ"Ì&ka�¿·MŽaƒ£ƒRáœâ}k‹àÝ£òlP$5÷ÕD�|}Ø ÞY8¢‚ò@\"»}ß'•»Ÿø™ÐPˆ>¤�øÚèZV¾':ø”ÖÿþsN<>7‹"Øj«­¶Új«­ÞÞµ¶Új«­¶Új«­î“Š*ÿ³‹ÖïÉ"3*é¿�3ŽºRœXgƒŠÐJûÜxb4…ŒÌ <"€ C³†VÓ¨1© ËÓh“ÚÊLVäx0L÷­V¦ ºAn�E×w|À8PÙÙKT��:ŒãAݽ{לŸŸw‡Ã¡a³Û æìì¬{è¡æôô¤†Á‘9fÇÎZשޙÍ'?ñ‰'¿ú•/¿ëÖ­7Þuq~ñÎÃþòùýáð<3?4ƒˆ" ÒYà°NÉÒ/ë_T›,ÕÕå+©Ýè¼8–Y­ µüÿ· 71;á$QPšGˆ½“‘I ¦ë�=“Ä1„ü"®¥dòï »Ý¯}ñ÷ðôóßœ>^¹Ë$€màÝbkü÷xûONDiŽÊWöhªÞW�aÑ ZZ/¨õgÛ+ûO€Š<ø R©:�„œZ}ZEvS?Ô€ ²Ð×[;k‰à­PCÀ"ò6Ë9o‡M�¸§§§ÐFÿ¾Áÿ £ÕÕ࿵°<0Þǰ”±”€Ø¨“ð¯ÈM³xpŠÁ<�#8¢T"[È \š5˜` <Ú'KsñuÔâËAý/U¯¯­èõxs8•Û•ýŠjµ4]u¹sæCs¾á™!ñ`ÖZB–n²lOÛ�y©AJ™¾ˆ�nAA’BØPþJ­K¯ì²2§TŠsªw-nÁq`fû?#a=\bÑBâ½ 9Z¢$^¤}R�‘ËB»‡vHmRŽ­ê—T©: #˜°T¶Þ«,§Õ)›VSäêÛDØ/-Ǭ4� u»R1´‹cN×2Îõ5  ê� í”ç©¶Oó»o¿ùæ~÷Îÿò0 ?õÔ3ÏþÄéÙÍWDäÀ±UЬå´hGJ9 ÇÂ|~ûŽÀO>ó¬˜`÷ Yþ¯7Vš ²Áˆî+GµëCl óØ<¡Pć¨0ÇþË«ÿcS5oGg€«" ZpÜy€6þÜUœƒŠû¼b‡Ï'Éñ œ…Ù³œi Z X+hÖ‰?Ÿ@¼k€* =ü½ž‚c�x·a àÿè]\ˆL }Ä»4xw4R¦xd)É.µ?‘?¶ÒhÂß׳³‚°†¨H’ @pó÷Wv«£Y"ƤÅk`´vþƒwT ‚I„9ÿY%SÆŠé‹7€­¶Új«­¶z�j#lµÕV[mµÕV[Ý'å¬M@r´ü�_]²‰ï’ åÁtœ/J ‹éo1¯ãÂOx-H+t¤!(b¯˜×–,¬³à ñD£<¨nzƒ¾óŠ”®3PÊ€Å/hí{\ž_àâüãx3£ë4†¾Ç�§¸qã »]Ò'ŒitAy,2Å/rY5ùó¦H00Æ/Œc`v ÆtÐl¼}´sfh¥|¾(zc°Û�`Ø� 3]X˜ Š*KpäÀÄ0&^VåÓ´ÁÐÐ�Nª£�w]˜FL6ÀÈ„ ¨Q�À1bšÆþââ|w÷îÝþüüb˜¦qèûn躮¿yóæðè£� =t£ï‡axùå—ùð?ô-_ùÊ—ßuçö�wí//_Çñyf!ÝM^ôÌ:�e”¤PiÆW¢~õ*ò!Ë@eTì-í}a£³W–ÊåëóB±àÏÿÈwz°ˆ ¡g hMpP€ó‹ÜŠ(‘”�éòB­¯½;Ãø °8À€Lð ê>W_ÿÊGðÄÓ/¡è™+I1kÕ÷!Oˆoܺ…_|ÿûÓØ|»Vm3Xž¹ú½B jXèNmÖ¾1½¾×íØ§ NR¿_QØ—1žZû﨎`ÔÌý¢ÿ—H­³ÆšMø¬»Ý ´1×�UXÛRÓç" 1túàÿ˜‹>CÅ` 㨞ŽTø;mYÏÒx· ²=qÿÅ1XÃ�Uq Ä""Ü<Û53Îñö»úÆõ¶œaË ¬8·Ô½–�Œªï�”Òü%©¥g–ùõÑV™YÖJ±RXšâ—@ÿµö© ø_©„‹ )¾ÒQ {QmKã ⾨´¸¯Ï¹�Cjð¸v �˜›ž‘Îp/l\ Zð¿rX²ɳQÙäR‘w�ï=„Õ{p©r—rCTŸ4‘*ÈA5a)°fs¦o'ö„¹ªsÓd¹ç”„ Z`ÊÚ˜Zñ¢¥yo=æ ^£·ÇZ¾ޱéÃÊm¶0(KŠ3?yyyñøüg?ý¿Õ]÷�Ó“ÓüÔÓÏÿ ¥õžˆF­õ(Z¬5p"b™Ù‘%"ûÚË/Ûç^xÁÅgÁè UžGT™#<‡H°·�s©R±¹4 ØGpœãRêg3É,iÀõ¿ € ü—ÜÍ+2 òjѱÿ€ÚU†“š_ÕC¥¨<·sG~NË_T¥ˆ$|ñœ|D9ÎÊ;DËÿÚ‹ƒ³ŒÃ8â0�íˆÉZ0 o¿¯”Bßw0½�አ:ÅŒRH½œš>/âÇ[Œe`ƒñÇ÷-¬O�€�”òD­5Lqn¤(Å«E@ß±¿¦é¾É9«ù ºÞ“�À‘ßgrŽS¹ýMˆ`ö.‘|n­ ÷cÞ>�oµÕV[mµÕT`«­¶Új«­¶Úê>)[¿˜æ´N9ŽÆH°„ÔÁ@ƒ™+[Ѩú£ h!¥0tªS „ õ”ê L€öûÆ”ô>g ˜(a½,A1b¦ëÐ÷º~€Ñš¼…ú¸Ÿ‚=þîÞ=ÇþòÓ4A)ÂÉ®ÇÙ�¸yónœž¢€È/HNqa2Zõ:8)–’%[Vv]‡�ÛAwÚ¼³àÀÖ p“Ï�W¤¼;A? ï¤!,ÂÙ°¨g³íiZ&†’ ¨Ñ Úè`½]¼À8Ž€¡"Тœ³úòòÐí÷ûáîÝ»»»wîœÜ=¿»Ûï/Oì”ÂÙ?ÿùoùÔÇ?öîË‹Ëwïûwì//_œ¦é1¡UepÊS¦ÊŶ\WOÐe TŠý¼¹e­ÌA²×ÑØ8£ySŸ\ÿÔ€haûZgà÷[ßù$¾éùÇ“òQCàÑžRæì�Æü¢©bº«ŠI)ØiïI&m*¸0¬;€F�Â¥0œøÑWùã¸y¸‹O¼;)ú#`�ÐÚ¡ÿý¿÷÷Ry»V^�§dÅQšY¿iß[ö’’ÕQq»3ËiToÎ éªÓ†íDR‚”ÖÓóìô¾%ÇŒ )r §ùqEt‰à²`·1soNwwr‚®ï_ÊÿÙ,Ò¸\þ'U¾�8a'öê(f�(¯\MùãX'¼D+hs¡mpo q��—ÈÇÂh�x)â{)ÞKèýÑ–k®÷ éJšyô- 4,²¤¤Ù>Q{ló‰W):¢Þ–+ÎTÖ�_¨V´Ku¯�™ú¿›u”Í}Š{™”`|j’�WNÙ…"Ù—ä5‘Æ(¡ÿIÑҥ󻊤£•DJ±¥ºÞCŸ®¾ABUDšõ,ÌcåÓ»TM(x4‹c,Í©Éi¥{r¼ –û¦f4É1N ]=„jSÿ¢�šÍË»*.¬Zï�Ñ‘‘Z"c‡Ð»iúá;Ó›?|çö�×Mg~íäd÷KO<ñìv§§çÌ<‰`+"Ö“”UJ¦W^~Ùîv'¶z×í£‚£Vœƒs€ñ}Î/Žù5ëU¦Žw¬@PJ+ÅŽ•cG†�b Œ6j·;Q7o²êû^±""e�Óû˽q|«¿s×õŸÿÜgžýÊ—¾ô——çï³ÓôÍιwŠÈ Ìâ"é•ö¼èXRp[“_ÚÔÒ*þš“ss�Ê ÕcF~ÿ‚Åu¶ÿ~üG¿Í·�òexõ3ÀH1W+°ˆý0yPÀS^:  öºZaTÓxY€"Ū¹¬›ºôʰ@Pˆ²v:àágü±•n‘ÀÖË…K‹€�ÃOÿÔO=0óÓâ¢p´ï¿n×CCÀ`Õl?÷µÖE ‰hH˜eE$š Þ¯ÕÃ@;ºRbµÔD’BÍ;?»æÌ[ð_êq‘2Œ '»ôÝ7üoíÿËïÖN�¶ þ;öÊ|vnò$"…ËýÁ“5JHJ[šå³c€ „«:Xöûç Jå„ ˆf”lÁý6ha¾¢Õ^w¯m7ŸÂVS)®Ú0‹¶H}´¡JInÍeð3ÅN,X¶O�¤µå£ÁÜ—•ï³éœªa i¾*›òb –ïR¼P ÒAŠY˜¼ËF}�¨oK€´²ùOjâ:«:( ­iÓ‹ŸfQEˆ‘ù� @¼§ÆøšzªË‰,ЦÜRÜlËvZ›+¤¸Õ—$€t�;rškþÿ‹Ms½¶ã4·ã½1f¨4÷ &&õ*\Gšø‘&.€d…&À�Mãø—ì4þ¥;·ï\£»ëúßv'¿õècO|Hi³'¢ 0“Ö<`•RÖhíŒ6>Šüs½cb’ â<�N“&*c,ü}µ¤Óp3âÒ`'B C>�FRA¸ÀuE A§žû1rŒQç²ÜöÔ€ô¸ÖZ{Ò¬ªI‰ðàBæ}8òÊŠ>ÚàõñÌ �hY9ä¹°šz$»GKŽ›<øo'ëÉñ³“ö±Q}ÉÍ]pˆ yWõ †€„A,ž @ªî;Á¢ßY¦;fÿYÃÙ¿@ÁÙC©eòN|ÖŠc›Óg#þç�@1€O à´�2Ò!VÔ‰|àB�Ò«\3b«­¶Új«­¶z{ÕFØj«­¶Új«­¶ºOÊ/Eà_ü‚76õq�ɹêoqáL+�~0 ½·qt (†sÞ¦’H�µFgüš‘Êx«} Ï  Ê…U5 ”‚°`rnœp÷â·nÝ›·ÞÀÝ;w1�»¡Ç�›gxüñÇðØã�áÆ�3t�[ÁdFe Ôg,¢‚Ï1ÃMûýv²Øï/1�“·A%…ËË= Ót½Æ;þߦ30J£N0ô=vý¦ë¡@˜&‡Ãak"8˰“Åa<ÀYG"Ü‘ÑÌFX:"êê`@0Î9£•6J+CDÆÓÝ8»Ñ�žž­”ùõüËg÷w~ë=_ÿÚ×Þsçö›ï¾¼Ü¿Ë9ûxic<Ë©m�cU)w•EãÞv½6m;‚¢ÒHø¯±×{*º 2A²oOÉ3\ý«nœø¡ï{/ˆ|ôC ¶eøX†þSa¹L�·Ržàw%0ª)TTÞ-ÃÚ1¨³Ú6X;ˆ` ù±l=*ÎG;<þÂw{ ¿!À¹E�Æ*3~ñŸÿs¼òÊ+iܾmç¥p- ZqG€5ð¼$Ïü â—$€²ÏýŠ ùh¿-Že©/ ÕÛŰ H+‹wŠ$€²AZ D®ÕŽ•ºš²½:@Ø ;ô}÷ —mNsù»ÛwîâÆiwüç`Ëï,ÄM°"6¨)mf­� !Uh-Ð"‚²ÒïË[þ;ÁŒü@¤`9Ó,JÐ0�WǦOy+=Ùn|eÊË`ôUŠúÔ=‹h“èR!«±åK‰¥²™V÷H)ÿ}ñϲv�ëþ ¬¥F=]ö±4Fd>”.ß³f.ˆ*’X5D9o^Þ) =&$€{å…R T§kãÍ‹Àú©MòGº?Tû¬œuæV ”~$”ºp" àり¿$¶é¡}#aIfŽr¯£âÞ†”y&HÓ¨,'Z,µpsÓh*EDKt(¢ê)¼¤ß,S¸rb­ûÖ^ü‰ËË ÜºõúA‘úœRú3ÆèO÷»Ýç‡~÷ÊÃ�<òµ'ž~æÕ§ž|êR XÁ É°8aç„II,@ )¥3%öñÙ äy�~˜ Ç7 *‹ˆ“&Ž�"±R$€fÄ×jÆ^yO¬ˆÆÍóQ ÈvþL¶ù¼Ïs‚‹s<3Xœß_A"кƒî Œ6PZçñŸK¤6Ô÷¶HŒ·�üæ-îídá¬õ‘6AO4)c¼[XßÁ“”øþqEäªù.z2ø¹™ç]=ë¶ì»0ñûv2&ÇĶvÎ.ÎCíç¾i ¤=‘¬öW Î9(«rÛ[—¢¢c\¼Ÿ¶÷ár®ó¯Û[mµÕV[mõ ÕFØj«­¶Új«­¶ºOJU®c´bŒ‹?Ì>ÏÑç2õz²�Ôú¾Ç0ôèû‡ñ�|fNÖ§Zk°cfˆñ‹ÊžhQ€Ñ0ìuÍÞ" œ�ÂB‘ßÿåÅwîÜÁo¼Ž7oÝÆåå9D}ßáäd‡Ç}�?á g»)LÖáp¡”†ÖØÙd'Ì,Ç `<ÀŽ1MÆiX0Ž{ c Œ"8w]g »]§1tv§'8Û�aØ PÔAœ€È/Â>Gs²É´·vìË@Šv»ADzƒˆ “�:£Õ È ¤høíý›/~ꓟ|Ïk¯|ý[Þ|óö»îÞ½ó¢uîF ‚0K±Y€›�*ÊWc�OKÆùEçh~—4’²¥¬óhÁ¼¸åæM«ÒÏê¸Öþ}­ ‹ïºPÿÿØÿì†Þ/NªlŸDR Htò¿ç¸ˆ¯н=nT²%ErXP&RP¤1*ímÍÙÍèÁäF¯ê‚JÈ!î3À“ßüÇýá$Eä�Àßý;§¹Þoã‰)äÅ–ÿÆŠRì /‹&Ë›Žî7�Yr¬¸ŠšQ’mû»|ì ”BÛ28++'u�³_?¶ÝΓ¶¾q—l]ýÌÖÒ*ø/l0P¨ ™qY2#fÔgF1ç­¡xCf¾‚5òÂ\V…²ã@á· ×êuoµ%×·Jó+Y*µ«˜–H"AëR±N2X8ËG&õT-‚ Ä êTá{8U)¶ ‰µ•}Rîà½H©¶. å‰Õwžs£Zw1ÒÙv%qy`Jå@R“JÛÿ2.^à#c*€0îg׃êЂQ³Ä£�õ[g%U–#†ùõ xûH&YkÁ3¾°‘obÊë*m^…,ï±Ç‚æï»Å|ßÎï%a«Ù‘Tïo��&Sª\%ʾL³ ˜ð&Yž+ÚáFÍ<ƒc÷­Ìî[­%ÜU·ñúk/㳟ùdwLDê\#]’ÂmçDêB)}[ý¦ÑúÍ®ïnwÝpkwrúæÙéÙ­‡yüÖ�‡nž Ø Äpa0s ž��ƒFx ±¢@Å 8åqk€‘Æ[îqŒFåûìyUüC©¬$WZ¡3¦RîÇ{Eõ¹Åå‹dGŒ³åIÞÅ,�Ó"�\&é~#Âõ}M!ÿžòswùZ,€ðp,Aõ®‚Ò¿ë LßÁtŒéPîIbº° O9G²DóiÜ}ðwçŸùô§Þ÷Æë¯½çî�;ß²ßï_d‘]˜Ã÷°ðžI+?äÊN3©þ’Jvî3}Äe¿ú^E*ã˜0$€å×– U¹_‹í 0X ·Ýî6Y‘ü…û.PZGZš„_K[o àâøy5hNbntX¤ö.£Þƒ¦H@-`yíÄDerþÛ+Ÿýž|×0P‘¬£TTE‡ãýä'?‰~ðƒo{ð?º-°k¬a‹piZïPK=¡&»\£}R<‡\ÝÿZhm´Í÷KTëRíoNWÅyWt…ØÅ9Ÿ°Û� ë»oðu[Wÿ‹x¢ÕI�U🙓â³TÛÉE½é`°Pë‡Ìö8,EZïxøìäÅÌa¿Æd¹šw�äþ�€õ%Eõ½e£÷F Ùñ椊§½œ¯g޵ @é “Î«$[3—Æv”Õÿµ“\+æä$Y;OšÛÌ” Ì(oO£$d%;þâêJùþ¶’R8"¨-ðe5Ê€’¢>«l—æ©0FíîQÚÍ›ai¢LÊÎêRæ±·2~*ÚJ•êj1ú�/•›OŒ8H¤¬Ò•˜�ÿ¹ÅKºFAp�š‘õ #4ª’½y;ÙŠ¬“µJ‚bqÏI{§Â§¿"74ó¸Ì2¤²ŠÏ‡fÏOWŒîòž×´gái”.iž „ù† èùíÒ8 mß8wp Ro*E/é×µV/+m^1Æ|­v_===ûêÓO?û¥““Ó=,9Eäˆà@ÄJÄAÈCÎ�,‘³Äìâ$Lð*åLJç$CU<€pM&SÊ÷Fë ˜Ïhq$ –Ê{Žne)¢!;˜Î ª{¥�?öñ0åý‹ƒ•~"@ D%R� ¢ ÁmÿåŸÑâsš�PкKŸ›t§¡ �]8ú{ (ñÑ4J¡"ÝHAuκ1¹˜ÆDIÑæ:Œ�ìA~ó`l‹¨èϱpµãBõ™Ñ9Œ“'ø€h)ȶz}üÊ„ÙÍ`«­¶Új«­¤Ú[mµÕV[mµÕV÷I•Ê›òç¸Pc­aœ¦`�?†¬É¨ì7Ú ë:t]�é0f>”HAt¡–a¿À×1Ãi•2Ù‰< @qaÁbšî0âür�»wÏqçÎm¼yëMœŸŸc²h­`T�~ð§§§8=9Á0 0ÚÀºˆÞ"YÕj¥¡�·…´Và A�‹‹ã¸O Ñåån½\^^b8°ô»urr¢oœôåÙ©Ú §¦ïmü )vlˆ ;­»¾ëaˆ08§†¯~ùËO|øCü®W_yùÛïÞ¹óÒ~¿ÿfçÜCÅ…©�' )üºsT¶Þ¼õâ]>ËÌô»Z� Š÷'uë‚ z©*À}%“»zméT°â�Ý×—�qy›ÇŽNªŒê÷¼óI¼ðô£gŠ + !•@3%+øX‹²)8�ÀMÉ-š ‚&å]•N‘#í¡¬õçÈŠ±x|"ÖGF@ @ åß×?ó¯ðô»¾P;(¢Ô/\¸Î'¨ÿßþå?)ÎâÜÔš¼ÓÌÜù(ùaé}s[ìf Ð ©bÊý'-l�“-*H³ý?-ï­Â8ÚMËj”v»�D(@p"ÂÉÉƘoè‚ûZ»—@Á�;wqcwsü®Cʈë,7—ùê9©Ô"—¼rÊÑy-ª9ïܽ¬Ãe¤ƒó\¯ðV\îán=#AÍIÍþÅ“!Ò1#wPIóììà»”™auhºÆõÉä´0ž½W¸6åH´A²ü—„d?ƒú9†(«ðË“�ð ÒšâP@’ëg¢Â‘£°ýŽc²²Ï¯”ÿ´BRº^÷(™šñ\bþe\CiçÂL”ÀŒ,‘½Š�B Sqj· ’'ÀŸ(¹ÒTGÙXá r»·svš=©¸ï_é°Qß ®¢LÌÞYÚÿŽÚðb‰xHך{Ò}Kæ„ËåûÕブžÇ j2Aós虼 {îH À ÂO9ÆS‡ijÇ/ðÅÏZˆÔ«J«/k­¿¤´ùR×™Ï�žž}öɧŸþÌSO=} €ƒ�%G–À–ˆ�xþ¤(¥E)ÅZkÑJ )’ð”*""Ž˜%t^"b­Tþ“]>�Tî•í¾³I…*ŽÇ@0Ú;D5<ˆOP`=»àÈ„%ÀùÞ0 Ý(Ÿ?ŠÏ8iž‘‚DEPÁ’¿üJöÿ:Pp”÷C�‹OŒÆ1!†%„ÿ‚ƒ”o¾EÁ}@%»}OpðÑdÖN ä_û,èÛR¥¸•Èœœä¬µáøë¢E϶å ûÿ<ϪŠÔ±ÕV[mµÕV[½ýk#lµÕV[mµÕV[Ý']Ú ‹`–Ø1Æñ€Ãá€1äK²s~‘ŠüÂ’_É ,v‰1D  Ãb�œxu�é4´3A£<(¯áÕÖV�¸½W柟ŸãÎí»¸¸8Çá° 0F¡ë4vC�a×£ë ˆ4àGŒqšÒW¹0¥DÁƒÂ u89Éí1ìv¸¼¼ÄxØãpa§ÌŒ»wïâââºë0 �éû¡†Ýpr²ëOv§Ãnw:œžœô»ÝnèºaPŠz@ú¾ï‡üË_}çÇ>öáï|í•—¿õîÝ»/�ãø¬ˆÐ*ôRZ‘û+S)“5é×W …xRèE%Oñ»ªÖ° 5õZ¥m_Ô,’Vªÿ%kóæ¸ŽO–ö»vþ±-ÐZ%L÷ù#/� $ª­�³r– .„TªCIþ}*€?šTV2j¯ÖwJ�@˜h� ØùŒñÐå—ïLQŸÐK‡¯ú7ñô;¿Ò�ùý…"ÂíÛ·ñþ÷¿ÿ™•|tŽY%BnÑæ½w�ôo©ýÙ—‚%–÷t¢K�"¯¾'™åïh}HHÒ«'rIevP€ Å´°xRmBu½IŠæ““Ó`{LßÐÄÝ%ûÿÖàÎ�s<ýèé:ø_�–ÏQ¥0ű�õ$úå ÝD46Ó‹çÁ4½u÷²š‹ÓüH{O×ïØÜ¹~�×|U mþm­tž÷|)H*/ˆ¹ÏÉâá¬Yý¢M•kÞSš'ÛþB…ŸŠJð?Øt×íS¿ÇG°ÌGG¼$‡¢r%ù¬¹Ï$«ïä6‘·@LõÏDsh°¼6Ë÷{.WÝÐÒCÀâ ¤tˆp¥Èúýò–Òû¹„�&.GöØÉA �Á0ô8Ùí¼"߀g-ÓL‡qÄá0âp8ÀN¶¥è: "ƒÎt ‚é:ìNN1NŒ‡=ö—{\œßÅùù9öû=œ�Ë}iô©1æÔt݉黳Áô§C¿;==;9í»á¡�~ôCïýüç>óm¯½úÊ{nß¾ýÍÖN7Ú¶/A89ªBödá¼Hž3�KàfÈ”"`IѼàïœ÷={m³m4ï)º ‡+”“KÖ¾•ñ*Õ“i¼z�¥TXX%`7üȼ¢@ ¿xJ¤jüZ»"ï@.Ÿ¯*|.DùkCðñJG@,’º<0M€f†+íT@:a8ž@“c<|ís¿…'ŸÌéÕiÿÔOÿ4‡ÃÛÞþ?VTœ•˜>…¬ìV8Ÿ ËȹØÛÁ—þN(•Ü2Mû¾ð_XJK<@´àû¼f×O…] 0S“Q-²ÐÇ ëØ6Ak…““¿àþ ÿÛ¹fÉþîܹ æG®ÿ³�¿Ã:~kn1Þ&þ3xÔQ"€$0ãö›õ܉"F¢¸¾ÑzŸçÃ{8XÈ‘¿5sõând=!Q$Ç´äYçz¶äÍ/$·Þ ^]MÐ82¨½sT§)ч¾>E)”¸I‘ €T¾Æ”ƒ b¤f®9T)ÚQ½ynž‘î ýþ«c65× ìwA”a;Tù²@Ö j’ì+åýR· Ù3H½ï¼�Êe(=CdðŸ*Á9åÊ‘)o6EKýÈQ’¸d�|@’Ôõ9Õ‚*BT¶eq8ä3m� RŸ(úFq÷Žnmª@ýc÷áøßܪcþy<Ç”þ%iF$G½ˆ`ü/⠤ț¡#÷½{ž~…u–uÖ~Ïa¿ÇÝ;wðê+_)ý5môg†®ÿô°Û}ü‘GûÈKßú¾Ï(¥& +"ÀþOD4j­•ÖÆ¢@xFp˜¹w'X;w2Oò�dEþùOHAÅç•x¹œ':Ç`ë³ícü {âŸRÞÝC”ò`ºž¹gÅ8$Iå_«þHÓlޏŽëVâDÙ™C¢åç]­5”Q�ð ª{_Õ{Iù1EK®™ ”ÿ;c`Œ�1ˆ(«m"ÐE¢5‘ƒsjæ&¯Ql¥t·ÕV[mµÕV[½ýk#lµÕV[mµÕV[Ýg•(*ÙcæŒÕ¸ ¿¸ÈNÎÂXOÐJs\˜ÔE¶' Î[œ;ç ´³wàãmÕµ6PÊ@‘Ãx° !ïF0Yˆch£Ð«ú]�³‡NðÐÙÎÎNÑõ=H¦ÉBäÂÀaœ°?0—-Ô€êÑkÌaÐäÌÛTŽþ+"5Y«‡±sn„åÄ9w6Möí7@tãË_øÜû^{í•ï»8¿øŽÃáò%fÙ%KÛ#€Sôê¥ÝÔºéU’aŒJ¹“ßà_T×/ªÑšÝ¬õ�ygIÛ¬Îs«Z'—&×·}a\p�ç³Ö^(AÆü~¿¯&o:ìT™`+ŸüÞwâd7„93ˆLXPõÐ>A _xÀŸ2 Â¥÷27‚=aO¬ 磈h 7 igaežE.ž`�FŸÁUZ/éÃxò™÷7Ÿõ¸3~â'~âš‹ BL•_NY±(-àÝv&©:/-ôß$*”ýGÆÁºˆ9«Äóþ¢Â:_leî:êâr¨Uéì•õ|ýz©ÆAßw8‰'uõ¿ˆàÖ�ókƒÿ>FA³Âhí•Âèå¥wŸ¶\ÚïnQ,·Î÷¹ñ“Å}¡ÒŽ*â‚ðûìùXõ­ c¯’#*ýºi3X*™4²˜M~õù”ÂaUÚÀ71×ÛRaãOTöä‚Ôm幸õ”Êÿd©R™N+€kMkõyÃjsÈ×=ßã—îÛH÷Œù}¹AžgÓCø…$#�ðìÒ^ï«ZXò\'µÊ¼Œ.¨; 5dCÔ‘(„y|N ½8ºf!¥‹ý&9Hó‘ž•"é+Œ?ª Ù¥&mQñü"3D~˜ R Ç*É(7@}­Ó¤s´ÓKsÉ‹ÁY<Â[|Þ¾EqöJ—ƒÔ|œ‹kí•#š'Ó\þËÕ3O~-»gìèž±ãô'ÎÏÏñúk¯á³ŸùÔ]cÌGúaøÐÉÉéŸyöùßyæÙç¾îÁ5j­G­õ!�&fvÎY¶ÖòLù>›xÚ1eлjq)æ’þûÏ6•ú?n/<zà?€é�ªìð££ÂR‡W1ã>Úð7×*‘#8žˆFù†déAÆ�KÇÞ­M„sºƒö-UÿÚh�‰¤Âè Âö.h1¡¸fÂSø^’"ø¯µ)J§†å?;Úêó�4c1º|##‰¶Új«­¶Új«?üÚ[mµÕV[mµÕV÷IE@@±°ãø¸°�Gnì!ã‚Q\¸rÎB›Â¥ p­¨ö�Î+®­ò`�°àe@Tþ+Ò~¡Uù,p;ùìt¥'ý Noœâ¡›§xèÆNNO0ì:o© ÂápÀ~€³ŒCp-`g‹ãW€ó �DÕk¨N£ë{hÓi¥©cæþÐÀì÷cן_ Zïc¸¡“7Þxõ¹/~þ³òÎÝÛ?pØ_~§ˆÜ¬ã^£ªWUÊ*jæ`^· /q ŠóÒ†¸µõ¥š0Pªèr60Ž¬è®Ø7_¿3ùõ&k8ïZð¿¶<¦â«K�¥¸°QBKT\íwaà/þ/Þ‹¸›3’§lïÀÿ`àå\ÅŽO=¼üµ�áq;bxôxÿûß�×^{íš“Ç<»æ HO$€• D°lñoK€O ­×kFÇÕ� }–à&¬tChmÁ¥pBXËv.ú av†þü¿¯©ÿàÖ›çW€ÿ¹ü=Fšqy9]»ýÓ¯Ôæ%9£%QAü~È´ø«5‹öÕm´F çÊÒqBÖÒʶËíj¥ àðz[Z;ïö§Ê¶Ÿ,íƒú?ªl³šÉí`¦¾/ÀúŠ "ù9E„½�{P´—Jð¬¾VX¦’4à¿àˆ²W€«Òì+þ,€ý¨P_ìR�þ‹Ä(de¹4ÀIÈ"•FiEn”"Þ'Ž•:¦¨ž]i…4‘ž�Ä$O„üK2HdŽ’XRET,´R3Æ®#©yMA˜ÈŽ4XèsŸ�’ …£‹¢…>Sm³t¹¨n?‹ãö­¬Ç\eÞÚÃ"-Ý?nLÓôÓ4þÀùÝ;xõ•¯ã#þݯc>8ôÃï<òèc¿öG¾çû?LD#€ID,3;k­›ÆI¬�˜™ED˜L¤E+ÅJ)!"¦L3f1Îy§c°s`ë`'ï*à?opjP!à­û�éatçã4Íìò#i:}N"Q¨€v?%ùý–óœÄÏZì ,‰ÈÀ!bD5×1“ï8¹?�"(ö@½îŒ'h�¢^X{§ƒxÌÑÎ?:_D€'BLõ#pœsC{¨@JRʤˆ†6¦�Ù…íR&iPá`±aÿ[mµÕV[mõÀÕFØj«­¶Új«­¶ºOŠ™³5ePÿÓÁtD”m󢔌ÿ›1>²´|úÖ……%)Õ}Îy\ܲáõÌ¡ë9,š©¨2{Õÿ8ްv„ˆ ï;Ü|ø!<ùÌSxâÉÇpvv c  €ñòwÏϱ¿¼ ïq˜léXë$Sø·ƒ&£i£õ))u&boúŒHŸ*mNºn8ùò—>ÿÒ¿ðù?q~~ç�Žãá]T¹è]ÙÒ‡Ey�B±ØUý_Ž€Eåâ²T ·´À~±ý[¾ç¸ 9ÉBFîý&ƒ”Ík£Z¶Šóheû„l™ Ig-2ã*Ìß—�«T6=ÿÌM|ûKϤC? ¤fˆˆÂUã5R¥@ÌÐp.ïXAz±ÿr ’Z)µ‡"”†1HfIÖ­ÖNP.\3@‹c0O€0’M0ð7íÿÍßú[΄DvvqTdð»pÃX"hö#]Ù¡g?. ˜Â ûÊšƒÿ²/I†)yÅˈsu�˜<9=�Ѱ½¯«þ€W߸}ø�tì €C„p¹· „]»ž3�·dSäò¢F çuG–xÌŒ[·/+Ò”´$€Y�*˜'߈$Z€Å«÷VÜ^ªñ-RæKKõÞVÖÄ©…qDó‚Êå"’q•ÇÅò}¤üw5Ëq&Éõe¦—.;‘�r¹Á¥è7s"Ô­¢KOÑŸ#øÍyŸY-O9"µ·j�ÒüYUcÏ'ªïÕñºµ�<‹çˆ –Æ,? ôi™Ðþ«p B7Ð8ª(•@ð줂ZüœEë…Á<56÷T[I´Î뢚c‘â-þ‰Kê‘湦hjõâ™u�'0s(ª)‡‘l�’�€ìlQ÷ÁLAEdðp5­Ý"sß]ˆ~‘6ó¡pF ÙÓQù²zb%:öT*׈u8ÞßVžîü•sÏŽÎ=;Æ?{çÎ|ùË_¼ÕuÝo»“ßxì±'~ý¥÷¼÷Ö9眵Î9ÇÌ€ÕZ;­´UZ;"²þ .*ß­sÕx'b°óîe£µ!FÀÛÿKüÜ ((éMúlä-ðušoÒónãÓ+‚†�r¢DðŸy©Š ´ $­ýß‹õœ]é-µVP…u#3Ãt=ˆœÏ¿LX™wðëb~ñ(.>9ò aìŽáâh pØp÷ü—ûKLv‚R„áôO<õ$^xñ<ýÌÓ¸q¶ƒa¸ýÆmŒ£ÅÅŦÉbœ¦àF?‹ÌOf†³ŒI;¨ÉA)gˆì+У“³�‡GíWù;>ø»¿ýC¯¿öêwOÓX¯ç,Ú HR±€+(ãpã;H9ÁR­þÎ}r[gTÄ¥÷ švA:e*7}™‡�~·º˜=ÿÝZU¯/UÊ¥X¶ArÆnù¨,ˆë€ÕÅý.UùJï áë/þÈ·&ëVˆ‡ð�øè a”ßÈq;SŠà{T�¤⊶TMN $EPÐÕA)R0]ŸÁ¥PÖ¢êØY:‚âtY`:ä¶øÈ¯ÿ |ô£ û–·ùl”ç‘ãZÙ†hÓö�FÙt¸Yjº¹2³îQ÷ÖÊå¼0�¨]CŽ´Jñ"@M�óvvr1Æ`·Û-XXãk øoÿëÖ›WƒÿŠŽóµàÍÛOà⌔¹B—ªy²q<©^G³Üóöᆱ(ܽÓ–Óœ*EÜ­ï Ñu-#–g3ZÖįvÂ…]ȇP ,\¿*R£èŸ ±µ]¼$ŒSk];\ëžá�‰*>ØÜÊÅu•…±^Z¡Ç¤û_º~’È^ù\jõ¿™÷üçúÞG m@µ…½¢näwÍ¢í/Ùú»yXÛÉøZV®“ÿS<3ˆ`*VTÂÊ-™±ti)b¢Œ^@“Ðô鯵 î)Tàí´L \å¹Ô±u‡+û&­'6Ìúví�¾+åç@Y8Ÿ8†D@‹î”H2«ñ ‹ý¬& P$›@fm»†Ç^µ—ëÍu«´Îj£™°¥,�Œ‡ñÇÆÃáÇnߺ…ÏîÓ¯u¦ÿí~èã±ÇŸø•'ž|æKD4j¥'m̤”šˆÔH  f¶Â&ïð¢„ÁìÛй tŸœm¬ÿòg£D1iZC‘.îu\Ü%\øA­Leµ_§ã½2‚ëóGUæñ³[þÜ�•RJAà_)í#TüüÅ È\ ¥UpPáyÂ!:ÀEâ³'dW8IÊ&ÔFÃ9 ¥8]âcŽn©]9÷ð³ÕV[mµÕV[Ýïµ¶Új«­¶Új«­î“Š õj¡sA!Ÿ´Váß F{{É’`tçÿîü"z²†€•„|Øl/« ÉY‡ÃaÄ8:¦.ïžãÍ7oãüÎmLãm7nœâ±'ÃÓÏ>�gŸ}'g'Ç8??‡XàââõÍ Qå ¶_hò1ˆhTB´¡,|S�ê±�~ôC/}à×þù¿óõ¯}í‡öûý3þ½ëֵ̅ª²éP(•óp 6F•à‚?q):ž�ÿ(ºT4I­š7—wÞ—£ee9ûœŠltÌ—oK«Û¬H¬äQ<í¶Q¨7ËC,Ï~a‘¼Øù¬ÍÚ³PŠ ãÂh…?ûÃïõ¤m|Û;4z¢H'�€E@Ê€H@jphMðÂ-œ€�_½xŸ ¤½%€(Oy懈½Â¹ëæÖìÎÙ¤•F·ÉÎÖ-äÿüÅø/.ïÊøúdÖ-ê¬êu°w)z#v”ÔÖ³¾y¤?ÏÆY¿IÝY(DKÛñ#ëßsà,o‹J™-Ãn@ßõ)ÛüôZ­¨ÿ×\^{ãîQð?]/ o¡a¯ÞÚûûŽ@N¥ùŒÈ2àˆL]‘+�óó} ¬Ç9¾usX�¶Ó±}¬ö#™õ :òfYš ”ú„,OXh ‘d#?#&*û_˜ûS€^ìDzzüí1Sý3Ñ|,‰*þ+æ*AåÒÚã�­ÿô¿$Úɱéh‘X$×ë|u‹_‹|wÅ€ª:cm[¬oÖmÞ>–ÏSKïoû&5}ˆÊûûÜ#¨ +ã@h9,Hž9èŠHE´Cé¶P�¯pdRŸM&e­<·´s@rN ôLÜ^ižüæn1‚ªAš¶”ÒF–oOT’OÚ�h©G¾¥0œ‚„,÷—†½EBÅüWÎeþþ)Ì�Æý�û»sûöÿù‹Ÿÿü§ú¾û—7ºùË/½ç}¿©ûî’ˆ"lHÑ�)ºT÷0öjwç,œ³!–Ì÷b•Àtm:‘¦�'?Gg)ÉÛâÒ9„$¼&‚ã:c²mþÊýRš¨µòç_#Á½ ³>W| OÐVÕg„ò3„'¡«+ÌÆh{oOà?s?àß§R¸ò>pkLEŸT› ÀV[mµÕV[=€µ¶Új«­¶Új«­î“’°øŸ-vsÑ‚ág"(ò0MRÇäÅ*¥%¥û…1†’v¹±\TLÖ‚E`-ãââwîÜÆ�ÛoâîÝs¸iÂÉÉÃnÀÙÉ ÎNOpzrŠÓÓÓ ÀVÎ/α?ì!Â0ã\8,ÊyãÑly`’Á;9+7ögþáŸøô'?þïݹsûEÄ”ÇY. S£2T*[rB8«?g®¶- ‰°˜ß[æþƸâÝñU3€9d º¤ÅÄ)r-ŒcQ°TfJK³—Âv¹Ü|VÑzVõ•µ¸Z]'”V©]¿ï;žÃ£�B‚JGëfË`…�¹Ê¶y,(„Ðc*L´f8”ÌÁ®?»“ض@Ã/$À*ä¹’'h‚)£5ÂõrÂÞ¹!ö‹@¢x@3·./ð¯÷Òl”ÕÿrÝw`¦Þ§ÈNWö)¬˜ç€Ý)¤4vÉí1Uä‚ ¾Rûó¬Ó®œã‚ü2Z{CZkìv'� õŸ©»Z”oëÕ7îÜøöþ+¯Ü­ÁȨ|=ÖV =sr�cíM ¥Aܾ{¹ä—nWõÕE貘[WTàG;–÷Ks‚Vü!o"4€¨”$€4¯9£˜ÿltN¤�£§¾üŒQÚ”—*ëÆî"ë­›DôÙó_‚5vt’Â�¾™H2!¯9_¢l¹žn]R[¸ ‚Â"ø_·]² Zh¨8¶ÑD$µ€t»¿¶OPÕfÄÀÖý¤ŒZªP�Ì5ªAh”î eÜ‚ vN �Z§‡Â1*´í¬ßQ>EÆÂÊþ�±Ôf”"uDFyîœ,ÁÓ†üP¹K´ã1<ç(Z¾÷4÷�|* ^éÙ“–ç¦x ä6jTþ²F8:wÝëýÆÿÌâL–ÜGPF™T㊘ÝKûƒ{épØÿ‡¯½úÊ­¾~åìÆÙ/¾ë›ßóË7¾y‹ˆ@dýS1ç?z³sÎ9'Ñú_„+ç3ìôMˆIÓÚU|°´×ãžè¦@ä_ŸìøUíškrœýݬ)9¯Å+ãBôTbP”ÄÀe Œÿ&p¸Îá£Yî×,�¯:§úFwƒ¨à/Øq"”ý(’Âól§?…9¡z«­¶Új«­¶zPj#lµÕV[mµÕV[ÝçE¨íòój‘_„R*.„e¥4,O D»J D¾³ÐJêR‘m/á³90 .÷{ܹs·ß|çwpGtÆ@u ½1 EÞ¾š`'¯ŠVP0]‡³Ó3L�ÐJa¿¿Äá°Ç4YLãä­>…Iœœ:æ‡EèaròðoüË_ýÞO|üÃÿÑååÅw‡SœµF® Ë.)+¥TX´_W2ø ¸�jñ{–&,R¬ïI¥úoíÿ©þËìêêp¯z<©Œ¾D+Ûf5¿j©¼‡×�V7�þm4t•ýîb'=öOdJ%�àÇÿô·"�ož3âYµØšÁá\àF03”éÒ ü÷.Eû« €¨à.!ÿ{Ç€V`2Š4¤œc(¥A�ßNt’ É²M1 1 ƒyÂ?ý…߆uî�šwܱó¡ëA1Ÿ6E`Ì\²kEÙ]×2Êÿ}…bQç¸ü±E^úÕÒñ »†aø7z�îUý/"xýÍ °(M×n»—߸Ìw#¢+•õW1GDާWÇ‚WnÝ�u|t?9{üØÙ,]Þ:»}•P8Gü¾ïç%  � (AOªÉ«è Ai­ŸKi!®²éï…ÇE –ðñþ—ð­âQ�X{¿,š1ºG”q+3’ç/%z�)¸xœ¹R”¦\݉ªh�ëY,õõk�"‚HeŒR#QsÜe[žF‰°GÕóa”‚cQFKyßHÎ( �Ê¤ÓØ^DKSj˜ã›ý10åñÄ›þUý­"]"‘Ibß'’Y÷(IË—ºPrcŽ_S3²öÜ”ž÷ÐÄQ´nQÈ÷:?б»^E¡™³ÕufäÅ�èº!W̡׾Ï€<2Žû{|}ÿo¿ñú¯ï»®û§gg?÷Îw¿ûý�<öØm¥”SJ� Ê:ð–‰�Xfž˜™\žËh´ þ«ªûF@ÜGpzñŽQÞú¿ë:� åýÒ1W÷N¥ÔBRÉž¿¾¾RŒsx’�R�¬ Òç3Àsá…Š8}°‹X¢((ûyÖÊy.å䀪Ï]A¼,ÿ›ò«­¶Új«­ÜÚ[mµÕV[mµÕV÷I)݀ɡ"[ªÏ=@Y/tæìGï0lZ(ùÅ\FŽÐFA;ã£Rv$�co÷Ø8¿{·nÝÆÝ»·q8xfן¡ë ´é bqyyŽÛ·na²´Rp–Á–¡M�³³3h¥±Û ¸¸ÜcÜ_â`8Œd?žŒÊ="Vž¹{÷Î ¿ø ÿì÷Æë¯þ9”«œ²ä£ZdoI¼”h=59»²6–§UQÓúHŠ®B£\�ýT‘òߥTAËÚ‚üzU�‘ÀPA3Ë˯‰Ð.I×MUm;÷5¬8%`ÁùàŠ@i�×½y‚üžwx•¿c�o×Oê(ãû¹ˆsØÇ€!Œ�Ÿª@ òþ©mp€¸”Ý+/ò.¨šáýÿ3ëµ�Øzx7 Â4Ž=ÎR[0 &žðk¿ùñj.JêÿëvR¬ƒeFV¼–p Õc£/¨�]¢¹³òµ–`7’*b‚ëÆåIU«Uÿÿæê^Ôÿåß™_~ù^|öÑë�/nݾð4YK ¬L¥³×Éâ1WoU„/}õVî ë†ïþz6û£µù´øGÊ,¯`NYÛÅœC°t\«±aV.Ý^&EÚœ,X™Ç¡�RI�Aã.Åû­wÙäsCÕ­¡ÿo¿²Ø?¨:w?Co‘ ¬•6ªúj…U\�r¼Ó÷tÛ"”ßþñ!¼jþOÔDH4¼ ‰Ôü˜„–ãš}.Äܯ‰êwJñŒ‚FÁOɸ ¼6Ÿ‰¸xV™Û(¹õùü¥}v =IÓGP;Áû¶¨( Hj{±ð}ƒÈoSJ�œƒTG€‚Ú¼è¹mLFuŠ™DR·ý72¢+DÊì÷”¿“!Kî‘H„eCœ«ñ×ÖV„I´@b“«æh¬§éÌçùbüŠ,?2Ë"�v7N㟙n�æwó7÷ýnø�<üÈ?ûŽïúî_Þívw!8ˆÈ^Dö¢À2‰ˆM>eE½VÚ6Uts°c0;8ç0Yb&ï EHŸ…Lg¼ýpJ;þ£™#¼ú_5ŸÑ ‡ŒHùã#JD­tލ>7„/QéC†k€ü¨ð/c{|¤–Ê}] f�s¾»@¨ï!™4A‹€� °ÕV[mµÕVVm€­¶Új«­¶Új«û¤´‹Ûªø ‹�q�‡ƒ…?3‡;t¹¸ã&ÚhŒÓˆŽM`=Èåíw¢ºÞ––~qMX0ŽÎïÜÅ›·½õÿùÅ9¬µ†Zk C�~0p,8??\\^Bi `çó(•ê°;´10]�}ߣ;ì¡/÷;¥õ#j¯žúÜW>÷íïÿ¹öÝï/ß™[#Ã…4³ï/í¥ã‰£Îš]Ê—ê�s»]¬Z• ^ªÕx¢%ÒÆÈ_€š"+Ç•sº¾á·2;±y›Ä HiíŒâØÛ=HÓL×ÉJÆGò[• ×’ðÃì]áo aØ‚�#ø‚2ÆwTغðZ0…ítÙ"[)( Ÿlœ9€Uì€s\Xh .eÅá*E`&�Y™.2 |€à„¡¡’Åý¯þÏŸÂùÅá�™‡Èó ]ÕEâŠë„”#|VGºÓø_�\±�Eaw1V¤8ž¥yCÖìNNÐw=ð P‡ßóµZQø/©ÿÛ÷}ôS_;JˆŠP°wuùúk|)°kŠåwR‚M Kø£ŸðÉÏ¿zĦ¿½R4wÓ§ò~²°—’�¢S4 Ijž•‚Åi3üvNØ nážì�C)@¨iÓV%žH5uÜK¼ÿ®Ý;ê,uJªþê計³)ΠêúRÝ�ê¨D«w)ÜŠjçœø<“Eàâç[™ñJ°LQK¶[‘åx¾Î«‰r—”ãŽ"ʇŠgŒrõ÷5.¬¿¯zž ZÓ™Sm߿Щ5ÏíU ÙçH½¬$-ÔÀÿ• á4Ç¢êø´ðü’]+ 2Ïç{ d�2 @rZˆÔ×|yö¨Ÿ—Æ`šÿ(zå'*ã7$º5ÕÎ ÒŒÖ;•ÝÙõ©™Bÿã*2£yƪ¦ÎC…š W4:o”bPÓç/º¬ü¢Š'X°U‘Ù}PV:Í12˜ìÆýþϼ|øúŸù¥_üù7‡~øùÇžxâï½û=ßö¯E¸‘= Dd`‰È‘�"(­’š>‚ÿR€Þ“u°“Ã4Y8牠^éïßÓc ´öKáÎÙz®“šT½üU:ähµ8Ý‘"hxç5c t§ýq+Õm¥¹6‚cOGþ\ã~bD�VU•ë›�lr!ï®æ&X;ÁY—c„“s@‰p»�ý[mµÕV[mõà×FØj«­¶Új«­¶º_Ì´ÈÛTc`Lc¼u¤° AaQ‡§4›�¯ë�;E„i!Ú/DÖÅ¡ÿŸRQ°Âôé"Àd-ì4a8xëþq;�¼Šfè »º¡ì÷8ËÐú¤}¶:…Å+¥4Âú~u�é†Îô÷Cÿôo|äß÷ó?û3ÿ�iœžÌ-±Xçªp‘°Rë-œ©v• v³YÕÞ3MÌv,—•¥ÅÖÛÙ…ã\!h9Oø˜¬RèI‹P"Djéø?šgESÑÀs,kÅ aõð記‚ÅiüÅ_üÓß òz~@,´õŸJHu �é mÈBç—ÒÙú?jŸ+¤A!ÛU)ŸË!Q°³E^m<( –óìa9�=JÁ“”שÏç3, �hWìÛòícÖD£F ðá:—>ék j©Àö8ŸÍÑ�{pºÊñâ0|ÅkJð_dnNÞ‚±¡º®ÃîääJç€?°ËÔ€ýKd€öµe}âs/ãÏþÐû®èþÌÎwÎG8h]©e�H5onš½†H¶îà÷™Ï¿Üln‰hµDÛ(€Ü”¢•d™Ò€"m~Õ¾`v ³©S®1uVû£â>¶<ޤ VäØŒü:Ej•ñ2'Ðe€/*Üãïjg)œt*m~ê•û�dRAùJ ìØÅ׉øx… /Ýz‚Ò·$Ÿ,5d˜—S^E0BiÞNiÈ. Mß]˽XÿËíW Ên@Q/_·ŒNÍ%Ù/À?J $pmjPöGªûÖ\ ¢m?-víú¥ˆqˆ$ÃìÖ@Åù… ‰–û¥U“D™ró¬E×¹u%ð_ €U$G 9 PÞ—,;(¥ÿ7࿢…¡85"ò¹õÅ(!¬?®Ý^J²NSS=kRX@«ÑPh}MfÎ" qPk�vKv÷WÜýdaš-Ÿw…åáËË‹÷Ë_ü¿ûÕ/ùcý0üôSÏ<÷OOÏ^‘% ÀÁÁù÷#€ÞcˆÇÓ4��­bº´Ñ鳕R*Ü{´WØ‹qå³+%w5ÿŒ©b6§Øïœ$è'¥ L§Sô@$eßï°Û èúJœsPSP¼ @ÂÏÁú’È9�S>7Y¼¦Ó*E€VÑòß@£ XÌ“µ`fXë`'ëUÚäU7Ã0àäd‡Ýp‚ÞôPDpvÄ8z‚@TÄ(E0Ú«þ=‰ÁÀeº®¿ÑuÝ#Ã0<õë?ó«ü~ögþïÎÚ›J‘_–{L3 >ÈUcÔ <Õ/5�»MÕ^ÈÀêñÄ…mjjíÑ-¼·&Žªý›…Þò5-¶Ó‚ÿ³|æ¢=¨�;ΔKªÿ+¬åìír+¥úÿ]/>†w¾ã‰ ˜�@à¼5?¤Lqœ€(¥Ø…œS$Øñƒ¤{ ^ÐOpN{_ ´8ˆ(ï~áÄ/úC@H`ÀH«‚à³WÐõ €�¦SAüÞG¿„—_½ýÀÌA^ýïêÅàÙOWäËiç¾/…@Ù�ÇL9d©Ÿ­�Ár­sŽJß•ñí&¼ÝÿÚ\é9þu�Vÿc$€ò½ð‘O}5Ÿ`´kç¥S&|ä3¯@«œ}¬ˆJ�Ì Ë¤6¬Éµ£jÒZÆ4ZŒãäAºÜU0ŽŒOñ••¾E×»G”`´á¾Ê +é3«³RÕ÷“+úeép�HX'¬UîM” é‹$€´‘ ZôàP:ó½�“"}ž¹^ÇÔq¥ï� é›’!R¼uµRP�‚œ à³Ê»_õm¢xGâ#Êûwõò ä¶lûnú§ëGçCiÔá² ·÷[jÚ#wÔ|G²Euš1¶ƒŽ‘ZäzSÚ‚;Œ$gÿwO*]hmÝêèE´yA³^íL´Ò0P�S+MÄ@|m«V2¸ž¦‹¨,¿,šMÄðÊ*ィoê…Üš Ðl>¬\ÓªZþ¯ƒ¿Õ˰%à�žÒ–úÏý©— à�ŽÀ�@‡wéd±«´IËè숅�ò$*NRˆ:h£À¢`€+X%a?Aá//­"ˆóï§À)åWäc€&2UœŸsÞ�ƒøÙ_þȃ5 …ÅìÅ>9÷ƒ^SK…ò±^[ƒîóÞ5ƒM›ˆ�UÂ@Õ] ˆz•|ÚÙEŠÈˆ¼I¥†a‡¾ïóXƒü!]¦ãªÿ5õùû[·/ðñϾŒ÷|Ó“H$™é»"|ðS/ƒPÚ.Ï`2,=²Ð¿âqŒÖa˜p÷â€[w.A$“¬³!À>øEL“½N@ös$ÿÇÕ Ìñ{Y›v±LDYwY—Õý]—›2ªš#@kˆnÈ~õ ñ Å–#6Ú<è‚0P½—2@­ŒÁb›RCçUü3D)N…c è­×Ä‹ÄKLB¤É¶oîYT÷Ú ¨J¾E[HiÑ_fØ7s-ÏbÕ‰D€µ~¶ø AY£ DIlÐr¼WGÐÆ-XÓ7Ï^×›ÝêH‹™»@y •k<%‚5sí칃–È3­×¼ÌÆR¢tIy+¨3ð¿e6е¦R51�Šÿ-{›ÈÌ=¥œ¯K@™’‘ÞwíÇBY5K<¾+"ÊÍ.‘î�z—MfÓ”È`§ñ/ܾ5þ…»·ßüÂîäô'¿é]ßü÷‡Ýî €.\  DäÀN¦|[‹iòf6(â�Yͯ”ÎñjŠhòkUú"Ò³¨f¯°·ÎÀݦë—mú=`øÈ›áÆÎÁ9oÏï¿d‘T�ǫߞÑ}ï?³Å(+ç8œûk­·ÿw.µ¯Ÿ'2�¡@—%0»Xä�9¶./ª· ³Õ*džK³8H¥5rZˆ/_TÍLÕy\»Z>CûÞD�ÅÔÜ3RÄâ¡4Á­ ¯Xѧ¥× G…êÐh…?÷'ßë~ˆ“ F Ç ^•¯L—KJ!R8)Gƒs€(€'°SÐFƒHC“”�t�vဘ4!<à ˜ W”ýxôn N)ôÊGLLÓÖZ|î˯᳥:ù©Š°èõŒÆOœŽ °f#3`èÈ@¨È55:vå{x‰P�‚´mJ¹ñ1«y Ã.ÿþžöÿ�­п. 9D?õOÿ5þÊüç‹9.«³ÞRþ /ßÁ§>ûJe Ç„ñ³©­˜#Û×ÛÉáârÄëo^€\\`Œ*2•�_úÀÇó$¼Æ­:™,O¢y½÷kWí§%“Èz‹Ðl,4/o kÜj*@£b�d†œ%³¡uþ[uíÒø*³Ö))œëk,Íx+í»ct€*ÝphÁ¦T—7÷‰Ep¾±â.Ÿ 2‰oÞKÕu[/õ<0f(ȃ  Õ”'åÑ\"_m眙êžÛ-+�‘HUå(rö¼4�ª|X!€�Q>–y?èéTÖ/’7eÍU °È'¬÷ÏÆf>è½¥¿¿¥K“×Ú¶qÈÙš ~-¸MIÿ%¹cÈÂÜD`ž³ãeµ¯,?ØÆ6®½"D®šƒê9§&<¼•PÞF"­—À¼]Ë98?P)¢4Òc¿ãâüîÿñãùÐÿ~89ùG/¾ã]ë[ÞóÒghÞ;ç&;Yž¦ Ó8b²£·¾‡ü㨎 >åø�ÅSlÁ¥tý¾–33¬ój{çl�ä÷§)o\p¯Š$ ”ý”$Äã®q߯x§8cŒw ŠŸÿÂósÿ­µ`犹�‚K–Æ~^ØÄÿ[mµÕV[mõàÕFØj«­¶Új«­¶º_ÌŒAßuØ�žx ýô]×Á: ¸¼¼HJ¯"q \´ÿ'‚ƒX�ç¼I� ‡ŠC¤€Vp–Áš1M^Õ<�¬ ¹‘@°¯ôöÿ''^ý?ìz�ò¹™v´8ì÷¸¼¼ÄþpÀ4ú…7¥¬é`�ëœåÞ±{ À3¿üKïÿ·~ñçî¯0óIø¨„ȯ`'4@ê|äÐVD­’¾ùÞä¢Vªü2Ù·ÌqmUËÌcɰ‚ P‘–C‰qM˜¬}ßavÞf—P‘kþ0ê* � °´øð'¿‚¿þßü"žyâá:p$‘"¾ôõ³wÏ`xÛbÅäg?/Å×_½ƒ7޼Ŀv �ÑÐJ¡Œ¿uû¯ß:oæ»ãÕ5§‡Y7:Ò¿¯ú�ÿ­\¯;®ËdqâÏo+H¨²Õi6Ú’¥9ÁÏïKGÀÿöø °uvQCˆŽ.å= ”‡^Eâ´âlÌ�ÇD* uëû–à˜�Oò‰Ñ‰lGËAëóAQ8ÉU3Ì2§âžfºÒìG„ü#‹ZJlÏYâóFI‘´?TZåKîãf®òÔþ¿Åo§‡ãO4ë‹™¯@GbZb(]coqût�ëB óF¸+Q1Þ¹b~\4T™¹DÌ®Ž™Hz“£Ï�²Ú_¥“kþ×ñ[™µuûL(-‰õ³é3•DÀáü¤˜ó‰fyèòââõÉ�äßÿÂg?ý O>õôßüîïûc¿!âöŽÝÁZg­µl�uÖ:Ç̬”b‚ø9J)�R ÷S®íï#`žTü&Dß”-ãï“ιê+§ÃC¦¢ä˜ÓÞÃ[ˆRöiXœc8(ù @khãÝâbŒŽ@ÀŽá\$„è¶ð ®Ãsxü�`Iå�Wä÷㸳ÕV[mµÕV[ÝwëÌ[lµÕV[mµÕV[Ý¥”F×uº»açs¦µ‚r„ñ ½ue™×ˆl÷*•²‡�_ô¡BÝU”ˆÀY‡‘ư8ç-#÷ûö—^áLD0}¬¯ NOw8=ÝÁhl/ÇÃç縸ÜcÉvÒx{J%bNEÜ#Ìî¹_ý•_ú·~íW~é?cæSTj;©‰*r‚¼äLc¢h‰ÜdY†æ–õñ„—TÃ…šY.¥M±4`@XÌ–ÉÂï1 jé�ß‘Úæ<‚þKÒÿµh�ÙŠ|cE,ˆ_n’šö£+–É ëgZig’ò ~üGßÖ pñ_ D�ÅúT@DÚõ ТC`kCS ‘ , `ŸíJÐЀÈløàãÀEÓqX�Žáç˽(=Ä@)Fg:¼ñúm|ðc_z@fJ¸…ZyAKel lÅÃ�pc–ÆÇ¢`³×®é¥j Dgm Ÿm—}lÉP©þî¶G ¼ëÿTü×ü|¾¯,œç“O?íï%, åf„ãý§T«ù5’ùœóæÝý[i�âÇ«ÔcëåyT–@Çjͯ#‘9)ë}ÿx�Ï}� ¢ •}µÉjÏ*Ì]WôÓ‚p—æðbþ§¦¿åûàÂa&ð_åÌ÷ÊA (²ÙÛñÏ6Ae¶z¿CT¸¿óNe%`±Ÿ¬ö‰ö*ÈŠµyœz4ri sZíÒ²Ú†«Üd6NŠgºè|Pí©h§âØ�öÃp]Î蘵Ÿ\£Å�I üV�ú¹«h¥ü§ê×O$o¢‹ÎKa“*µõRäÉÑnE™ UÞÄŽ;&ÄûËÜö"Å,Æ)áøœŠb.8ö–…ù÷ú“U㘳Øo³‹Võ…BÕo²D)¥déq´ )¢½sÇ?ÿå/}ñÏýk_ý­Gyä¿þ¶ïþÞ÷3»ÑY;YkGçÜ("£Rj""öqRj–wÝÓÊ{¥.\«(DQå¹)ª÷ƒýp^c¶ÉÎ?GˆD²�ߎD¦H ú•Í¿ÀB)U9PCPðŸýs+E‡‰™½ŠTŸ«ù#îO‡Ž—:´':¨-`«­¶Új«­¨Ú[mµÕV[mµÕV÷I)­’â$þ¬ˆ -! • €a!_åE¤¨tQÊ?êiÄÅ!.\YÎùˆ€ñàm(ÇÉâpyÀá°Ç8NÞÆ¿3†»Ý€ÓÓô»`§ “µØ_^âüâÜÛÿו*]·ëŒyÄtÝsùÐÿدþò?ÿ¿9æ3B äs­ªGPÙS€d¥V@fóÓù"/ DªRõ?ËùDm¥‹ZÁ+¥´¼§k¤ T$€bq-¬†f2ªãD¹p˜ÿ°¨ØZÜQA$ÈíR/¤7 бí°öz´ï\"êWe•}ŽJxè¬Çÿžwùãc�(”.]ñ`:ξ¿“ó}ÂÅEOåIÐÎo—…AΫŸˆ-8õ•ƃ6‰sWãárº>’´xfŒªIc^íªñs¿ò!ð þ¯3myùZψ‹×c,Ù5_P®õ;Z}õ±‹ Ë}š 8Crv5‚â¿ï»Ð.s@ô³" �ç'¹–êÿø_¯V[‘.è2)8ϰp•sM4§DÉ<0ú!:aÅ1à˜]ö,*`ÐgѱÃÿ¯èª-ð¶´©+Ò¿%ZžÑm%Å, ueô{kù_:ÚHì+Â~ž *ÓÙüÇIø®¢ÊV$Ý‹˜9Ùƒgà™h[ƒŠD<š© Û…9'n®a^¶wo/wÿSí¯Ðâió¾+Õ�P9¡Ôg— %mpn”tiÆ­T‰;3Ç¡ŠâRÄ P{t”ÉlG§cYžA×z(5ÌZŒy(É*´ü,‘ÎËà?-?o§‹•±˜¸)Ø^½_¨!4Ì»Ô, )‘p—ZkÑÒc¡�É;"•Ä—Yÿ¤Ü†Gú²Èò/d厖nÏ«3Yô@±¿Ò켫Ἓq( Ïœù~<›µj`ñrkí}åÕWþƯþâÏôìÆCÿ¿g_|çÏ[ë.ع ]ú�Cê µ–’ÌÇÎßK�³pÌžÔÚ‹ãg•Á¥sd@¶ï¯ÕÿÑI 3�âlZ’�çk¥T"'D·,Ió&¥{yÿBô„£‚ P~©|*Ÿ�â<«Ãù¡ŸT¸Pè�°ÕV[mµÕVRm€­¶Új«­¶Új«û²¼5¥uÀd'Lã„qa§¨4‘lçJźŠ$�Õ×¼•³;Ńÿ"Ó俇‡ýç,cúÁ`·°;=Áp²C×y;LvvšpGL“M‹S]ȦìûÁ }³†§¾úå/}û/½ÿþªc>›å¤ÔŠj4+ÿ²’ +dßJy-з€?pÎ:ÀWª«%ÔüÄ‚­k„-©ôk5Õl¿TZÌ.õŠrƒÔn¼Êg.Û£kÛx฽+´g+v¼ùµ’ú®¤¸ ø“ßÿÍ0&ü[x&ŠîÅÛ­24D âX @ hñNP â˜9œœü—O<õüÏ(­�RJ+­•1Ýh´¶JéJýï‚“YüüBÕç•Àù²¿ø±éßãÕÿ.8ø#W@å$,`âŠ?ßD’ª'P"Ï:§Ad¯qˤê8•ÒPÊ¥Ï~"\NT*9ÉÅq!’I»¤¨ŽrÙj«­¶Új«­ˆÚ[mµÕV[mµÕV÷IEu‰sÓ8!.V]î/qqq�ýåã8&›}~AGkh¥ý÷ü—à«_�§ ²‹_N ì0Mã8a¿ßãòr„�FFûív�A?ôv=úÁƒû`@,�Ùgª´Ö0Æ ë:ÕC?ôýÙ°Û=q÷îÝwþãôþÚ4��‡³L¹ê¥º�ÀRóÞ€¾–‹Ùe¤hy¢Ëð¤Ì0|*°K¢§Çþ@ ±ö°•^Z“PH¨QÊ£‰_9zer_¦öQˆŠ3_VÈ/;IPÓ]©z]lKôHAíUOŒTÄs”¯/·YN¢EôÁ2‡g©«\Õ©'DZÿ�Ì�(æa*úû±éKŽŒšDË …ã–âçk‚Ñ,€°{ÉÞ½ó×÷ŸüßœœÝøÿ¼ó[Þóþ®ëzÓ™½Rj$"+"NØ9çœLÖÂZ›pMÁå‰ E|ŽHJŠ~ñQ8\|I *xK~ æR~%¡w s¶ ŸÙHy‘ä PÆ­|^,KäïHf`.æÙ"ΠƵđS:lÐÿV[mµÕV[=xµ¶Új«­¶Új«­î“rÎbš&ì÷Æq3ãââwîÜÆÝ;wp8`­W†(¥ ��é4tgÐu]A0•…¤_ìVê!N8çü>Æqó­5´6zƒ¾ïѺÎ@k Î=µVèº�ñ‹YÃÐïúax¨ïºÇ‰ðâOüwÿí_½¼¼|GeS߯8WŠwžY‡'¨@¡ôǵ’¥Lß"ï¸XPÎ6Ú\¨ïò.JuòÛêcŸ)•›ŸM„ñK¶¸ë�Õ…ÁrÁ´T RÎr¡ëèf¯]­Z+öÍx.Ï?ý0Þ÷Òsp†E\4ì$ ¥ €Á0�à»ÃùLR!@ˆŒW#k 8xb€ˆ'ˆ �­™p‘‚Ò*–r†…v Ž6ÚébGiG@Ê';°µø'¿ø¡nîavåÕ<^­¹Œ–zˆT£öûºWϹ2Ÿ8* »aÀÐ÷a¡<.¤ßßàÿu¿â{ÊïíÏËmX¤7‘"1§X‚eÇ|î]Æ HnD¹uS¯ù½4‚Ʋxä×ï%×ÃýúiÊq ýâ¸iÿL+C£%RȼmÂ[�ÖIißf>·•âäSÌáñ¤ªé¥œ…½t¼’î?9k›‚sD›J­ØU¸•*c©ÇrÝ5gÊèteÚ¸’æ¾´zÏ\œ•àòš ¯äŲ;ƶG´Ëö\¹á–v¨ãФÝ>sd‘£»ºÞÝŸªy>>¿å؇ùAµŸ�íÝGpl‰“Â0a1ãþz*fžAdF&­�U­$ˆÄs®)Z=·Š)G+}wíšÈbsV¯§‚¼5;!¢þ¹§kP52+>»]ñ\¸H–Éêó5p_VïYk¯/Üœ8ç¾ýüÎíÿêþ�_â©gÿúw~÷÷þ¶1Ý%)u‘ƒÙ�ÎMÖÚ h!¶¡u¥ ŸJà?9²ñk¤4HR³ãôà {b+ЇÍbNÅÏuÊFe¿ö.! uø)ÝòçI—ˆ *º(í#Z b°Dw ¿4Ý—ÏB[mµÕV[mµÕ[¯�°ÕV[mµÕV[muŸÔ8Ž l±v‚R Ó4áâòwn߯ùù9ö—{HXØÑ¦C×uèâ÷®ƒÖ&XA*8;AiíUõ@Èæ À ¼å·s“sÞö_ˆc4†�A?tØ ½ÿI%•µµv´‰`Ð÷”R0¦3]ßÝúáIÓ™çþëÿïñŸÞ¾sû»j ¢ ùŒêÜJò�ÃB²4j¥+³Ç�…$_ª�‡*«:,êÅEµb�6*ÄJÕc¹e¹¶õ8òö*Q[aÜf¶.,޽Zg‚OÝЬÏ%¤tö¯ )XȦ-šÛ¶ˆýŽø±?õ^¿€.�+Î-d&ÇXˆ–”ƒÀ/¤*8À ]ˆð$m.*YÙ;[#œ´Hˆ´É‚G,®ýºl´Èjqaî ÿêw?Š×nÝMýæí^ÑÑ×»Šàh_.ûôþ¿ÐSV{ØGÖä_5¸hÁ‚ #)žÐÔ£ëú4¬¸ ämþ—Ç|¯ÖÿµñÊU+@¥uÀRCs´.ç´êºÅfå¬ümSTŽ© eh§«»Í=Ô²A¹©%�m!€¾y÷7JI)«÷»:ÀÿBk“bj‹íøsðg䀂Èí±ãw´ïWª¹VŽl >/�ét_‚ÿƒ2UQ™FúY0Ò­ç‹ ¨ëtýƒ®Õ·*Ut›¿½r?_ê»Ò¸þÓL]»ùiŒ1 WªâŠî+€P�.g…þñÜøåá �crä9¨Ýä,E Ÿ&¡ÂÅ¥ŽI¨|J¦åvJöüqŸi^òêëÅq�`Zxô»¿ù£ŸýÌ'þÖw}÷÷ÿW'§§/³µŠÙ)žˆ”KýŠòó~œ[ÊÏ ,'.¸…€~°ß7¦ƒÒ*¸­áÿÏÞŸÛ¾\çaØ·º{Ÿsî½oÀ@œI$’‚ 8ˆEÓ‘TIUÅ–Ë%Ç*9J,;.•’R”J9©8Q%±œØ–-GŠÙŠ5GEREФHŠ‚ gqÂ@ ðð†{ÎÞ¿^+ô´zúí}î{ î»ìõêÝ3íýú×½ºwßú>ˆsIe ¶­W°0¬ÎÁŠÀˆIÖQÞ_[¹cRÿgïÙ”Ú,^KTWˆ„�&ü™œƒʾ¢" 2'’øŒ3f̘1ãшI˜1cÆŒ3fÌxH­+ä%ö­õ•%‡Ã××÷q<“GwÞhò€ý²,X–�ðÃÆCps}�eñR²S  ŽG‡ãñ€5×Kù[\\îpçòwï^áâòÖZ8¬ëŠÃÍ ž{î>®¯op\W,ÆââbOæÎ»'Ú-vyÂXó²üþïûÆùË¿ôoBíÖ•çe£ªâ¢R¦^  Rß-âT]|§šZµXZ`%ILJ¢8-UÙ÷®¨l@”õl³?�ÚFWPn*ov銠§WÝÇ“¿u=.ºý«#µPçè±fvªˆP:åá¤!–ßk�¼žˆÓØÓêEó�JÏw‘>øß¹ý†Dž_¹ ȃXº4ëm=z\&TòI©æ?—†rùäïÛP"liÌ$´¼nÃ0N 18ª˜p¬ôÈ•bF¸~o Q*`e¨>u¡VÿˆkΊ Pt—b¼K-ý_õ频-¦d0?�æ–Þ3ýúþ“Wƒ2Tܯpó¹�§âTÎYÛâ[Áã^âº� ‚«g>ñÔŸø‘·ýÀ|ì‰'ÿì—¾îMßÍìž‘kkÍ‘ˆ�VcÈ%KòF I:f8vpÎWÿkk”h�f›ÖÀþu ǫϥêõy�êï‰+Â_ä‡uµ1�$°®�ð}Tjq\zÄ•4VB{K|»�vÍ™Ö3f̘1cÆŒSLÀŒ3f̘1cÆC«[D¹Io"A"J^�ÖZ,Öb± –ÝÖZk2ø*Dî¯×¸��?8å*÷õèp8pssôÄv{‹«« ܹs…{÷®puy�ý~ÇŒ›ëoxúégðÔSOãÙgŸ¯+–ý�?öز[öWr!w¼üç~ög¿üGßñö?%"6VEû�©ú]IüêrtÉ ¿ WÑ“–Ô-un7��Iɰ–r×¥„l T%)Ì üOU‰DêZG ›ä ±ÆGèH/¾Û#)Ý2ÀñŠë*ÀÒžä«òÀ%jOU¡å%–ÇóòÿþÝÿ£o~È,¾Õ¬…= V# ,Aª?�TëFpŸ}#™ðFI ã¿÷ï!@ \ éIGˆ ­†`ì€àýZÝjÀİäüæªãŒÀ +þîwþøI�õÅñüÆñ¸?�jþZK 4€Q®u”ê¬ço2G¯ñâU$€ÝÞ[ ìw»€m‰ª}ñ<«üï�þ#e€­j©U@è„G¶JÑR&ˆÖú*pI`X|—¤ªTÚSn‘q‡Ä69Dy§î°ôBÊù¼Ç7£ÊŽ‚ºS“”—]\gÛN·éµ&J?“·jH&ô‰T·1„§Ä¸|ª�ˆúª}ÌEIš³cÿ?K!îq@[TRXE´Òêyþ*2 Uuü$¸^^+Š¥i4 5’¬!EõyÙÃc•wT7ʾê]ÀôTgVk�a/)™%NLí½H·2aáÙ®s0µK“!ƒ ÓöݹEjÅ µnŠD¿ÎšH+ˆº6ê%½n VùIæ›"˜�#TÿdÉ ‘¢Z][¬P*¢ÏëA4÷ÞªÜt­t%üHò@=ÀŽj~ñÐwDääR³×ïdð Eƒÿjm ) †¼¦ãnõ?EZVãê¬&´Õj!J½KpŽ_ùñ�þöÿëGßöÿô³>çóþ¯¯ø¬ÏùuîƒpC†®‰ì ‘uòÄ(ðß½jÚê¸Æx¥¯¢faƒjZœÃ]Pð·€|Ê`<ƒ;Ù÷{kM"�!_ýïÂù#Àqw}�ÛÓj‰ lJë#Ñ$°Q.˜1cÆŒ3f¼¨cf̘1cÆŒ3’`ØLO~£hgÈ>ûLc°[,Œõÿ&x2sع‰›Mìf1XBUÍz\±®GÜÜpÿ¹kÜÜÀÂXv .¯îáêÎâ1ñ4Üêpyui Ñå�««Ç™¯^úÛýÈç÷?þÎÿȹõ®2#.Ð¥Vª$KQ‘�ªµ$•ú…7 62{Ñ%óÛJIð¼w[�ÿÍaûÏ}¹æì×Kµ•p0Ó+ƒ:B¡²Kƒ�uÝP½?õêñª×7 ~Ø0Ù œ±3è%¢ý{—Åâ÷~íëaí.È¡2œ–pÄý9WŸ#l¦§'l­ÿ…ó€–QJÕ©Ñ�š@ kRÕ±,W. æÕ¿V ˜ ÆøJ-" v+\�³&r^ z£ŠÃ/þÚðs¿ü�G+á²C)ÛLݾ>†(W5ê1vž;Ç­®UÔØ7Æ`YvØí¼J§¬¬(Îí³Ïãƒÿ#à_ÿ=~¯¿Öß§‘Nfãyõd×M–E6™ÜQæ›X‰œI=äj£“Ï”6{«îOã~Ý‚˜øXÏUU;ÒhžBe;!ÍäÔžŸÎC‹]‚¢ Ù'æ‹ÀÓà¿„ªýˆ‡SGõ}‹ÎãeÖÛŠÖ\� yº¾{É�7|+ N}7�ÒC¾Ð7l�^ÜN›ªïs©|Q?ÁÌ) Ñ´[UÐKÂE5ÿ�êZõâ;ÚV�j™ýLFHV $�¥jöh+U<ç3ûfo,Èæ¸îˆ÷&iÍ¿Ñð2ì6B°o"¡Ö~�*¥�^ߊ„A "ªt—ÊõnVˆíÝ#ýÈp}$1‘d…)uýÒq"œ$ÕnÕaHgÓMòè©çï=åIW“i8*Å0÷‰j ˜¬9sQ+ÿ‹5|x´,�ÿê¯ÿê¯|ÍG>üÁ¿ôåo|óß0fÿ4Ùð¾ëP'^Ï`à¿[áÜ1ÌϹ¢ß˜Å«b“‘ø¼Äq u‹“�=ÛÀŸ¬Æqÿ£²ÈÊœl<ÐïÚ¹¾«Ê!ó' >7̘1cÆŒ3^ì1 3f̘1cÆŒI�öž$k,L”d4Ö¬iCÇZ¿Ù”6¹„ž}î9<ûÌ3¡úÄíïÞ¹sguëKEø•ßö-ïOÝ\_. ª²P ׫m¼. ÀG ¸”à´›«MàðžTUNù ê ãhG�íŠH›êSRRµR—†Féû¸)­ê¶é¼¶óûÒœô<ïë¾êÍù�­Cß/# O„7~ÙçàÉÇïdAvb‚#‚=ÞÀy1lZ† ¨(‹J¡¢d�¯h ®^ €ýµ:—¥y�™p…,°"pçV‘l0È«f��,Þr†¼ïµ ¤“õÁ�ñ÷þÑ;UWxªÿÈìNv‰~©a-ë‘å®�-ü¿GÊ9+;ÂZ‹]°<±ËRžGd£ õÅñ<Îÿõ³;Ç ×W›ÜF51«zÌ,€©³N©ÚR¾IªG@�çÛFÀiB=ÐQq;ÆJ]™ÛZ¼ôjUû4(Ülåó(3Þ½î�w­©Æl ´êð…=Gô¦®Õ¸(‰ë‘ÔJ] ¶˜*ƒ}ƒ‰ªð…§ìG­ß“ZièTÓJƒ dHð£Db d‡3ê,ÔOQÃ>%©Æ_Rÿg%yžª•GÒ ¤Õy¶»)»„,E_­5 ­TR+µUà[ë„–P÷iTk¸Û FŽiéŽÈÑïÊŠ©¦ jrPs~=ˆ …‹1øß´]›$™¤AÍE HkÚ3Öoí-çéHF¹]N”Êþª63©l/"™DÊ'´µdE Ô ?Q©ös³ëVÿ{ÂeÙmk)Éfé·2¶v¨l«Däî3Ï<ý§â?ü?|åg~Îüe¯ÿŠŸðô !¹†À1‹'ˆ†ª{·:0»P-/)?F6cŒ¿TVía‚}†56)·¥ù^r[$룠@†’ü¬ø÷׳úüÖ …u™Tç�+_)çÿsy<3f̘1cÆŒoLÀŒ3f̘1cÆÃ²0³‹ß ÿ“1Áêœ26Š(l4cÂ^eöîunÅêV<öØã¸¼¼ÀþòÂK›ß\ãúþ}<ûì3xîþ5ÖãÖ.Øï÷0Æ`q�ËËK\\\ÁäÀÕdÂ'ÉorÂcÖÚ—ýÓïý'ð£ýí¥)L+öaK¤Io ×"@½ÿ*YJ7m‚Ò™xOYÁ”ªžÔÆg!×:¨ü×Þš¢6Ö ‹éHg1à$K=¥ÜAEŸrMè´MöLîùײ®åAQ€XC°bKö¾�ö -àòûï—¥þƒ°A ãïÏž`°ƒHÔÒ5¥Œ.À„gm ¼†-oÖÍ X£@*†X Ö1\*W8ØX&Ö“Œ�]$ä ‡u]!†ÀNð›¿õQüä{ÞûÈä™ì Ñ—ÇïUk&yïbÌéêj닇Ù#[�¶ Ñ. »`·[ ?ÜS„”×óØ–õ?e 0›£l¨¬Yú@%PS„|õ£0HdÈW2*éèâyW9,U’ŽlMŠóöû_ÛŸºpÕó} ç¿JÚ+ "‡ÒíNÑ%Ùl ÊÎq¬Ý!VrGëœÒ÷[B¢U”÷¼d댜~«ïK%©úÕ &)¶HÑ÷¨°ãÉÇg9üo›¦O¡(mJN7íˆLP¾¤•fE¤HôIñ‡ºª:EåºZ‹hמÞU’û¥ò}Ú[Ã�¶WPgŽ´¾L± ‘ñ•i’Ê)z%UN5T>KŠk#ÁxþH⤌:÷¤$0((é56æ5Íý,µ/Ô«Ï­ÀVdÓQ.Y¼Ä¶`©tª´7”óI’]¾‚¨È’ú"„E‘„¸\Wª ~"j× Å8‘z¥]œsØíüà²,¸Øí±ÛíC¥ àXÀìý-—e‡ýÅ®®.pss çx¹¼ºsyçÎ�'Þÿ¾ßü²_þ¥_üc¤½†K(!}éVšÆè#Üå1Š×g5€: �²Øü«Á¶ð*ÕÆ©Â.œ#¿·¬Dk}…•JAMˆmB”ÿ®ÿ8K;÷¤¯…Ò¬ØhZꞦª›’BtàôfbØàŒ;ò;|ÃW}±ßTŒ×f¬—E]üUxÀŽüæ¯'Äv Ð?†�$q, Cäû Èz¢«K½â€u^Úš@VˆóãˆX{ÔV¼â†s„E¾’ë[þñO<ÐúðF“›^Ý“#—�=„F=$ƒ&½ ôªXºÛ³3ào±, Œµ/œ�ûÃø€ý·­Jÿº?žªþ¯ýÖ£vSa©HÌ ·:/AÆ]VQ©²%J¶P׸÷ ϺçêþÂö™žt{-—./øYûCv\s»ßï0‰¶j»§ ʧšC¨²(Å?¤ðÛŽUø%Ø+…ÕMdœøj^ê"¦±RõÛÌS/$éƒ^�ãí§ÆS:6mHžcv{މ (hlÔ£k'é® äy�Ùj� ¢_Ò™O޶Å(J¶g Ó±úÉUú½õfþËà~¨Û(Ô.‰‹¥_K¥~²œV:Çïµ±ÿ¥jx­6a4ù­•FWš¡K¢¡F¾�%¬A„‹jù`â¯ÃPÉ�ŠJÉra`÷CÕºVÏ£ÍG‹l:õܳÏþñ·ÿ³ïûÆÏúìÏûß¿î+Þü€<+â®E䂃·)pa ªHVD­ê€"Gò¢µ^Áh¿ßcY–B Ä­.�\"ú%•72·#ù% @)¹P5S&R 5Ty~ Ÿ1cÆŒ3¡˜€3f̘1cÆŒ‡$ö^J2‚m ƒéøÔj™ú(éØKi:ïùÄKžÀånc)Èkú 7/ßÏù ¦ý~�‹ý%.ö{/‰Îð>—«ß˜3Æâòê÷îÝÅáx‘1ŽùÎÝ;wŸ¼¼ºzÅ}ÿ÷þi¹Ô–³EÁ[!¯š%]ÿ_µ‰|ÀÍš¶S»žê,¢dOE]/t{* ÍvCVm6ªj©î‹P¿WmD¦÷ul âO09¡õ/ñ:0ºçº¥{ÛÞÃfë�rø^«*´¿ê Ÿ‡Ë½‚ZÄĂȘø)ÄKôÛU âà¢j[ŽI”+Å ,â�§®Þëf@²$ D‰YYÁ+@Ö·±%dòN³Ö¬†@ÆàcO=ƒ·ÿä¿TÏäÅúœã öâî’í!ô^¼î"Tþ½ê`õ2^1"þÖÚß5¹þAÀÿ­××ýsÔWÉP)/R"†�|ý…Á€!òsŒ K:Ò²óž ´¦ÑÉjëM‹—ç�ûÜL~õL"*§Óó§”d=ÏŒÛ ßŠ'Î$_ófFêÜHÿ+z >ëiÆ&íiN(»ÎÓÕì"åŸ%Vò¢�…ÇÛ¬I(òˆ42õEuG%AzËhÁ…çñä…ͨëôž@;‹ÿ}¨RɱwæøÍñÁë^Ûœ1ªÎj%¬äF ˳Ö#Tõ†þUŽªà»vŠ˜I£Mo©” ¨£tuFbºÚ÷Ô³‘t+7PÓÅ8Q /¨l$ÔZ½¨=•®áxSÇ¡N'�·IÕëR¬ü©³ožœÎ]Z‰¡uQå Û_[ÂÌêÜ«ã×õï|ô£ù‹_û{¾é/[kžb_ù/Â|äP�Ÿó¡ðÙw“à Œõ«ØeY°Ûï°ì,Ë.¬ÃÖ‚¤?£ÅŸ‰Ö2D²%‚—ñ7 âÒÞ$Ù&u‹ÑÀtíÍH‘ ò¨0óùŒ3f̘ñÅ$̘1cÆŒ3f<$±ß]¤Í‘ æÇŠ~a(Øyc+ËBfyÈ—>ùƒTùï½³-–Ý– Xkq÷ê O<ñ{ü1\]ÞÅnwfÁº2Vç–Ý—Wwð„·0WWWwD䉻—W/ûÞïùÇÿ«››ëÏ#j=ê 5Ö eã­ÍO-EZÊ‹—r¹þµa#¬� ‰ãFúß¿Æt6Æ"H$êûtRý·îM)@uK¹�ú"� mÊr·To«klÀ-ݼxÑØ!Y®|Úœ¯�€!cLz˜ßôu¯�cÜêAãvƒÅÛ�…˜=ì8X�°ppp™ðRìç{€ó ä „8Õúè6%J}Àbb`ÀÌ”`�ÛÙ.¹Òž3ã[¿ëG±®�^5÷º_n‡R‰ ªSV}¸®ca›@ÿßM€ÑŠ`¾–ø!Á¯äR<›Ê:„¤¯±<® éŸDpb”0JÿðhÛÄÜ7dî3ø´AE¢î[·sÞ© Òª5•ätQ?ž*ã[8¥d‡ ¤o„ ¯f5Ñ�ÞÐYl)4NŠn×c'à]©¯>HAx�ºOi@TªÇèãú9•J0 ƒç;xþ½æ� p¥Âœ |cM,(\"  ¯†ÑrVÀµ¶Ï 'YK¾#©ò¦'`(U>9¶)±mG­à�nk—Á«ç^|“•?Îêo�ÉKçå#*¢ŒOQå ŒÁƵ\ʞج;iL‹ŒãXŠ!¢~�í…k”ÍžSê8m;�mY"=5ª@j*æã^{vU ¤|ü�}–ªîP÷YtÆU9ê¤Ý³“BiÁÕ±ý ¢ª~ÐíD�•1e¤X¯U ÚÏ!Yž~úò¿ï»¾öU¯~ÍŸùÜÏÕ/ 3 ˵ˆx5ìbáV/MlL¨z¯Á슰A1fV>Ï9훳{lé³Ý€^gH«×sTñó†UBú’¢ø3‚‡RȲ�§nøßÈlÃæòÕÿRyh¨ç.Áÿ67@�émÅyíެî_˜%H5OiÕÿü_T±Ê)ÙxBµN¨fÝJ«|T´\N©µ©ƒŒß_µQå¤@T*Õá�ëõɸгÈx§ÿH¯ƒŒ*§=’ô­Þ¯úus…2V�μÒºC�'¥>Q¿Nš^€Ä£RM’•Pç틤® íp� Î…¹h¡W¤¸1q¥ì R[qhÒù¯ÊNÔ&ˆÞX«»VmøÑTÏWÏ\[¾H§OIjÈz€eRTÊ#õh.*ù±�X2éuË2C¼Í@ʇ[NG(ø4)‡Ã›ñçöÛ?ô¡üïÞð†¯ún·€åš€#ˆœ1äHÛ$(€'t�õs�_ùÿãë½ce‡u=b]W¸uÅêV~³>Z ŒUvÆ`un5`^™ÈޱhzYÿ+‘ 20ñÿ3f̘1ãÑ�I˜1cÆŒ3fÌxHb¿ìüf�aÈêAÿu=bu«WÕÿ&xBŠÞüäbp¿ßãp8ø­¯ü¿s玗a·w.ïàÉ'žÄ§ú+ñ²—¼÷î݃À{Q€¸¸¹OXì{IvY콫õêåýí�¼ê=?ûÓ é ;Ê'õ\˜ªr2þ’ôÔ¨mÅŽaБTN@ZunUmd Ñ4$€ÂWóœr¶QYªl³¢�¨H^´%Ôl=å„®${wW”ºÎÚEå•H’ÿ¾òuŸ‡Ý+. à²Ï;[o+³À{‚@"X᢬²0X)â)bÄ&{Kgä j+0°À’…�‰`à ¼úc3Ä0«@d™Åoæ3ã;ÿÉ�áæ°†û’G&ϤqP÷�ðÇ…Ö¹okÂX¿©m�øw†òïê8䯿×j½×Õýr«�FР„ੲvïÙ7®¯ïcYp ë#˜q�coG#Ì%±€h�Ï›/z…¯õáF×Ôôû  Öðgý ðPúÐq9®F@¿Üêv`·,UÛä\N b†²}È×ÑwωrÑ¥ ¸H0_)rîN5ùLÔ\�f®7vª¦?™ss5¬Ôúâ½é&¤¬€�‚D!$=©æH_í+͵ »R¡ãC}•úÍÔ™ƒ%WÿKA†CS N²!_«Ö8›õó’óÄmfÆàFø [ëk³tM|ˆ_M¾@©¤ž×†\›–– Õ’ÚVA„Ob…iò‹hæC E5}«"†Õ×ÒþŸ™ òõŸœÔyLÙrP{Ï�v«Ÿe~¦2 hçú§{K L~tMFÐ*^OfîK‘ âz½k•EÃ,«û)³<ñÑ�|ä/þÈÛø¯¼á�oúóžè>®‰èhŒY‰üüÊ"@Pȉ„7k Lø|a­M`»ŸW�GG�¬ÇŽëι”ÛlXDˤx OÆ38Á­!.Ú¡ëÒÓ`©§¿¹\›1cÆŒ3½˜€3f̘1cÆŒ‡$¬%xœÄû@®¡d]\ða6†¼”sÜëÙØ­YÙḮ8�1—X–v»K<~ï1¼ô%/ÃË^þixâñ—`·ßãx<€È€YÀì°J¿éd/w‹yÒZ¼ò}Ç·ýÇãñÓÚj!]�wÂ�ØPæÃº’ŠßÒùc%ŸÞdÕ²œ%T0–K%J„‚¢ÄQ¤òÊDñ�Ôz›Íj‡UzÊéÕ†næ!PÚüí’ô{ê¦Ë:þêVÏØòSêB5zäUâÆî¿ö{^›-D0œ;FX(IÆZ¢À!(J°)±J(< 1\4S~¦ŠÂŒÀž0ñ×ÊK'ÂÞfƒøC{€ ž»¾Æ·|ÏÏŠe|^?k¾¾Çøü †TAþ�´ÎÖ}�@¡*ÝT |øg"@ þ'•eÓU�‡©R:è•ýëù4'9óÜýgÿÄ;üoøüW}Ñÿö%/yù{ ‘µÆø[ߘOwÞ¥Sï×¹Äêz�ª:²�QÎξ}IߑȠ8’ÅhÞdͲ°•Wrs¡ã�뺲‘{ ;¼Ô˜:w[¡ÚÌIjçÈø;•íß¼­© ¬�Tí 6ˆE¹™‹>TaŒImp÷ê_ÿÕ_ä ïá2 €ÂMR²0–¼RV`À¸#¸wÒR›J»×56â‰(ñ·0 Ë- d=Âà„!.à2øGß÷“xæ¹›G2ÏÄê2 /mí•0 ¬ ýÆzÿY(09JØ2wÇÁïú\~‹Jÿs$þ·*þO�ÿ¹úŸ •QNj ¥=,‡# Xg´Õ«¤ðžÖ?=ö!9¡9ü �ņ¸þFÕ¹´ôM®—îÑh+ÃË©éû¢�lÐñG‡`Yl‡A°í]Þ€'<.Tþ£RõAs gpIÛž×mßHÊCBo›Ù÷^¤�ßÊ‚ø\9,HïÉ�ƇªŒo;i¹–)�ÿÔ’ù,ƒj":€S ôõËó“\¸–b(*¡3ø_>zªqø_�øF 32ªzÒfÎ/Id-Ã(U#¢óÇ{®˜ïÎ`PP-:�/  ’HP›(eқΩAðü¯¬;*2fI�ȃE´2”<@–S¾aH {,M\ ”Õ)2ÍhüR>©×±Ò!–jNCÃÔ®µâ�"wõUâ=ˆF�»Dâ =641¦Lï,ÕXTç:_ûË¿ðóßòi¯øôÿõ¾úK~Ì�¡ vC ¥PàÏ``ÕñÙ1D+3Üêp\8Üø¿®Ç°¦ ÕÿÉB).£PPj;ì 0ßílK SÃÒß>�̘1cÆŒ3…˜€3f̘1cÆŒ‡$œs8½äñè¥ÿ9H'¼¤‰U.d@ÞqT9φͧ QúôSOãúú>ž»ÿn7pŽaí‚ýîW—W¸¼¼Â~cV·ÞÇ3Ï<ƒgžyÏ>ûž»ÿÖõhˆŒµÖ^,;ûø'žzê3üGÞñï5ètN½›>¬`›"·@KµYÝ“éƒ=¤ÿ«˜ ¯Úpíâa £Ž“À­ø› ¨7@óq¥ÝóݺWèvDQõ£Î È‰Ž¤mÒfïœeå _oA.¢ÒrÅH»†ñþ‰(ùˆ¾å+_…�] à ΡR‹|u”;ÂÂ+€]<ñ„ÈÂ,û�çü&­YžPìÂk5†ØïLú‹À� »Ì`Œ�&gD"]@ÀîÀáp`üÝïúéæ¹< ±®kú>úÑÚeñ2µac™0ôÓfñÜ%Þ~ÒÊ%’ÀÿSAû”ïHz9(ÿN“‡\мW–Ö‰5}[æ»R}ìóN�r÷ T¢›ËšVî¿};UþîݹNz *¹Í•¯ßš�œp¬õˆ,QU‹k"ÓG6ëŠs?Qi\­¢Uôr‰¶ ‘Ê¡l¨žb{«à«Û³$~¾¶¢Gi0¾@Æ{Ï£ÔPP0gë=®L什y$NÐØ©…ãIɲ7·[{ý2‚»Åû”ýIMjt ÚaræZÔ{šÙâI¨µ)ØߪKùTß È�$€BÀ"µ¥Aá B5DR§—N(Æ64Q¦ÃnJãƒ Û 4ã#+>œ2‘èiÒ¡8ED·š¶úPŸ)º=^:*vÍõÆÏ+T�¤ãGâ—âó�š/41¸h*Mº!‚iT�Âg‡‚ÐF…R€¾1îæÈJ=AÀ}Ƈ~ë·þúýgŸý¿½ñMoù›DDdȸ�À‰ ‡c&´¿cvŒÕyÉÿÃá€õxÄq=ð߯£­1Ø-¾Ú¿ßa·ße"Àbýót^q`u+ŽÇŽÇcú¼˜Æz,ZòghűÜ7>Y3íŒ3f̘1ãS“0cÆŒ3f̘ñ�Äê2øïœ÷N�¾Ë”<$ ³x9Hc`(VƒøM/-é=—?þñ§pÿþ}\ßÜÇz<‚ˆpqq…ýâ%(×£Ãõõu’�¼9\ã¹çžÃ3OÏ<ó4î_?Gn=.DæÒZsoÙ-/ýŽð÷ÿØÍáð2ŠœÊݹr“½»y\G:å_Òà‡"ôŽ•¥UãײZ¬¨~®6²YZP^ êÊ·âzÔ5få´Gnï¸ñÜñz›JZÙlÑÈ£>føG“7ÊJ­Jê8=ÛÌÑ×AF"ÂïûÆ7Öz¹}@V¿Á+Y.Ö1tð`¿¬½h™,ÙЧ Üz¶â•_]ÇåFn¼4€ÕÆ: ÃÀ„JÎh�ï’ÈÀÒ±6gv,ßñýïÆSOß/žÁ‹5ˆ¨È˲$à¿­PWëŒÁ˜Ûð{¯y¾àÿ8/øêAÕJ°‹Ðø�o)ž”rQ ™iÏaœ$~ц݈Œ9l1RÜïE!ªuÕ|×™¥� i´ÈÍ�\6õ|³;D«ÍRðÓ÷VÜCxl»Ý® W4ÇL zŽŠHsQùOT³¹}XUKê¥jä$ÿî¿e¬dó£EP¼é^t<–ôHéW�T"(¤ÔÓ{D½'üÀÑT,gÎK-ÿ.­lCzäµÐp¬ôO¬ÅüIåçr]¢×5TúÆÇ¯ƒÒ 쌄Ó]ª½rõþAA´ßüH€?^ƒÆ#‘O”ò5C¶oÁ¤%àSJÔrôŠqAÔ*§+‹›¤¨0ìBÒä�‚”Q\sÕ)Œ«îcTc(ZU¨fó〽$<³²-Py+ÜŸ1ä‰Ä¦Ìaº×*¹#”ês„Êeú¸ñ~Љ!*tAÍ“ÑÖ*5a»>Õ¤S¢2—i‰Ô’…j‚„&“sÕdâñuÙ?ýô'þãÿÑ·}Á[¾î­ÿ ‘±D°Ìr#ŽÌÂÉì—º"ç\ÿ�8op¿Â¹5Ü`­Ån·`¿¿ÀÅÅ%öûKìw;,ËNúÌ+ÖuÅáæˆÃá‡ÃÔâ(XkÙe‡…X’¹ „�ZJž¹þþóKÚJ¡^ÄÍBc »w…·¼ñÕ0D€õ7ÅL ¬`RàŒ8ø‚âcþPBdwž @Öß´1`"˜õè¡'r(z“L¸4o;€ À+€CEk|!³/ã‚ýÆýþþ?y÷‹ø� øŸ3è&¤ÿübÞ×_ÏþOs4îõ¸5¦#N_I²×`^ÆÀ+àIr¡«¯lŒŠ¨<çÛÓ…Bïìç<ÈsgtÔÉ K5(-~j€À3O[y}w=³;óÀ9÷¼eMÐ{µ¾‡eÙõ[¢62ß8'…˼ìˆ*R\1Ç¢V‰¼mHêÃÌà§°NDÁ0G’ܲö4#Éõ£©þ¶_Ýtú¹ˆ’ÞiäßÕ$.]/{Iã.V$Ëà„WÍ@œ÷oÞÚ[¾¬K t«ß5ÆMé|ÓÛã {‡šŒCg º¼ˆlþ*Ô–PuŠ=M n’ès(ü¦ú~ÐvTp »wA:gTÏ'[Pt$P÷@•_}¯ÿ+û Evõö,ž Å¬+¼#ÑÁ$õ’¨òa´�F“Œ¨fprõ‘•-*°ÝP¶Hý›P*tˆSþ� ‚�$µŠÞZ¸ þ+ÒI9nuî.¦áág�ØÖ…’Mæ�âþýûôíÿü>ë+ßü5æ‰'žüƒŸa曘«9) 0ܺ*ÀŠã1X¼I\ÃYìv»þ_àââ Øíö᳟¯þw+Ã9‡ÃáˆÃᇛÜpÎß‹±‹x"–¥XÆ'Ê 0;Õ®‘0 3f̘1cÆ£“0cÆŒ3f̘ñ�ĺ®XW—d �¡äŽ þ�K ,Ëâ½.YW—8¬nÅêûøS8\ßÇê¼ì÷~¿O¿,‚Ãzѵ‘tmüN[ì”Ýïwu‚(êÆuåjN›T¼¾kÀž*sõ i5�|Žüƒ Œ5…¼¶#8Ö¼»�È׬‚ ¯+ûPY?Y(P›UÛ'žYü¯_@ã£)K£f,ÉékѤâªZâžp6/ÀHþ›NuWÙ žÔ¿¤ŽŠÃ)”]z÷ ö¿a5ßMºú›ŠÇ5uÔJ¤Y¿RÕwõ3.[†Ê‹PJå:9çÌØn5zÊq*%�#‚ÿŽ9Y‚ÅC™Œžk­4Œ Š„ØŽŠõÆXiÖáåç5(_è‰Tëk­&#IˆÂ“e$t³ê³µÙ‘j ‡Þ o•T-*õʹ/ì@™¯p8¾ùÇôÿß/ý²/ÿ?ý•Ÿõë� ÌrÐÑ8ü/‰äm@$0Æ`·[°Û]`¿¿ÄÅÅ%.//°ßï±,;ØÅÂÁ…5º®88Ž8 çØ[`Á²Äc{Å'c�¿`ˆ¸îzc’f̘1cÆŒG3&`ÆŒ3f̘1ã!‰u=BX¢û.lðä6Ö`± ¬5ÉÒ›«ªÝ}õùæ·~E¨ /e !öòûÖÀ {ðž ß_�x˜¼�…ˆ°ƒµ `w ³À C·ÂÄïëòÓ¨IáÂãkãW#±Ý lŒ\³àï}÷»Š\0�þ‡7Îþ{¯;ä¿­äý{“ª¯d”OU÷«¤Ó—J ¤ö &í'¢S¸PΞ5è|òüç>ˆÑàA=›ôßK˜ò›.ö3X¸9oÃè¶r^û,Ë>Ìç Úu5l[ýŸoU6-Á&(N,ªú?°ê Ö0&€›`ÀpÈ+¡SU•|f[IeFÞSªÇUóº�gÇçt¿!æ íw^>ÜF+è {ˆüB©ÖGTÚ/TÒõÒ¬ÙFàí9ùâT¦áMøêcuͪÖÂF44Ñ÷_?��~�–Ñ#PS©� ™$êµúi‹ÔÅðåU*å�šeYWµ79i”hį“|å?CX¼’˜ˆêÿ(û?õbÁï¨ ¢�¬—¿ëIÿ“Z£Qµž®áL ¯ÖÔUºÉ©ÃÔ \÷l %iìP>EÕ§¥T/�r¤¸õøúwÿìOÿíO|ââs?ïÕ?휃sLÌâ¸t·ÁžMÔ¸5Æféÿe�‹‹ \]]áòÒ[ìvü·Æ¤5‚s+LJãÇõˆãaÅz<‚™½Rܲ6v ï÷ªZL"”Ž¥í¼ôúsÆŒ3f̘ñèÄ$̘1cÆŒ3f<$ÁŽ“¯¥],€LPUÿ6ÿIV¼®`·zyIv¡Ê„qs8`u�YÆz2�±þ½Ì+‡××÷ñÜs×8°ÿ÷XŒ½°ÆÜ{úO}·>ø�?ò ÷T¸Çë 6µaåHÓb!ëIS%�ò—íTj•ÕPå–-™^5Rz#=û *ýŠÕÁõö7•Rúr¢¶¾‡¸YÁ¶¨6ki$:\¾.ö-©}Qoü÷—þ@÷î^â«ßð*DQ\"@Œ€`‘DeÅÁ C,ÀŽYÁì` Á­G€,vfŒóVda÷Þ?zÁ€}r+,¨"J˜¢ÊЀƒ@¬xË U¨qJíd‚Üí÷üÐÏácO=÷;>î5ÀoŒ9-Ý?ãSü÷Þw®äÿÖ÷õu�ò@‘¢ÐMe�ÿRžF6J7¿¤ïVôõ車sG GÃy‰m»âZך—`cd¢¦U[#˜ÁlC§ìa¤ÍùêËbÿ6.fŽ-½Ãã�¥ß ŽWKÈ£¬¨–1Pxj #8O=�ÿ5!CÚg+ÒëCù85IEiô” e’®ïÛRôT€úýìÌ–‘rpk¼¼÷Cq  ^PçšâŒ-½B¤Ì@Ž»}©Õµ ï°”�×–%2|Î¥ä<Òzµz§^oRUº.2\×Õ£Zª uÿ�Õôa¬ršA5¬{N¤*É|)Õ\„¤“Sr¦Ó·h¨l-ÿ_wIIzQ¾_!º×±¢RZ¡nrö\Ž’Ó\GÝ©èäZž�ûì_ÿµ_ý[÷Ÿ{îßÿüW½æíëê,;w àÀš—£ü7ˆK=c»e‡ýÅ./¯pyéö;쿎É^x3íëêp<¬8½zœ@<9œ – ·,;,Ëί+Ó:à Zf®=g̘1cÆŒG1&`ÆŒ3f̘1ã! Ç¡FÙ -Þ4Vý/&Týçª`_ Âpìeÿ�s¡ò‡Xdk v»=.®.pu÷» Y¬ëv 2ùÂ8Uuïöv¿ß_Þ±Ö<ùö·ýàuÎ=¶uízn³2.†H±A_ïu¥Pz _"êjÓWEŽèOÊ—´½ jd]smܨêK3G%¥¯¨å6Õ}$@Ú �“qã±¹tõ+÷-a£±ã¡+Ò‘ë>/JÂÁ¹gÁ×~Õk`¬ mhÃ}y1a[—)¸»2ÌB`À¾Z ä@뫽Y‹Ev€± ÚaÙ]ÃR`åì;Á…ÍèÚØÛWÄ\êHñ)ú N&� ›¹ ÆÑ1þÖ·ÿÔïÈ8×`¿µv&¾‡<^hà_gôû­ïûcÓdÎRN–·F:€4%8D¶SyR¨ÕKh0_„ûI‰�g™–ä2y{/ïK¥+iy½«e4œOc J†¾œ8Ç S¦]@€eYòkéu5ïÄç]€Õù9ˆ²¾ÑD´8/‘I¢Û0ä¬è'žy™�º æégQ¾.Bðh,䌻¥ÂàÌq_|/ÍoG×KÍó�EØe5³VyHm¬ºUÿ²¾÷B ]�¬P½×fÕj¡õç/ nc5ÒŸ©O}©Ÿ‚–ÿO˜6õL¦ªÞ¦”ŸNÝC&O¨>\þÓ<ÿºð\Rµ< ’L½@–l|­Ì¤‰FT˲?öTAÊ>Èÿ{Ùÿœ”ô JY ÒÅØèñQDk7H·Sv—Ò†Ô…Çw²œ Ô„ë’žŒEjÜ”GÖ0•b€tl$ô8§AÖ*Cª’ðüàþêq]ÿÃÏýÜ/úaÇîé Ö%Dä ””Û °ñì-k –ݻݻý»ÝÎÿ¿ì±,KzNÎù÷ رW} *×ÖúŠÿe‡eÙcÙ-Øy?3ˆy`s�ÁgŠ3f̘1cÆ‹=&`ÆŒ3f̘1ãa ‰žæ±Â:Tìã7ìŒ~)û ö•ÎqØBªÄ³–@fÁngqçî{üîÞ»‡‹ÝD‡ƒöÇ뺦j¾‹‹ º¼syu¹ß?þ+¿üK_úÔÇ>ö{oãå|«­£b¿“ŠMCVKªª¢ ì­ëø“¤e+J�%ƒì ÄHÇä¸WzI£RÒ6ÛÒ‹º®Ø:eÅn|Ö©êŒ�ïÃ×¼‡¦êØèMÖªâ0’ × „môà(• øXkÓÆõ7}ÃëëB%~ì¬ëë-`9lÔ† j@ ·‚�hÖ,Y8Z°�È‚Ìv—+WwŒààI#¯l-ݫׄÃ=y�ˆ¬øžö3øðÇžMýè… öÏêþK*–îW�gäçÛVýŸÓÓü ªª8 ƒŽ´ó iS•Ë é{)�Ðqé¼4Hð�µJ œÆÿµGwyäþ …9c„cJ4í¿H• OÉ_—J}—ð­¶ÖVVÞæÔð`vû4ßK§�d‹•P�ÿz–àä.%@]r²€1&äx:Ã4¾¼«:>Å`P¤Œêý¤-½ÓRužN%¿` D—ówo$UÕݵ·| hˆ4Ý } µß—EÉÿ÷úF÷tZÈ|“ÞƒZÞþâ†>)Bgý¦–>Ð!-ÿ¶Õ”ú=�Næ– þ›¨®…X‰ŽNµ>º7DÅ�fr©¯ bµ~ód:Og³sæc‰´*ÕµhÆB&©"ÙˆP÷\*;P™xkµƒþºº"‘%±”·(úÚD)‡•T�R5½d«ô‹Ê¹4)‘”—¶òÏËÂ`“sç£ùð_t+ÿo>÷ó_ý}áOL kc�h;§øÁ“*õwË.Èþ/Ae+yj�¾úŸ%Ù<ˆ"ÄXc±Ø;»Ãn¿ÃnïÁÿ¸îäø9È´€x®¬â2cÆŒ3fÌxTbf̘1cÆŒ3’�°yhÈx:l쳈—*ľÚßœóRêxПv "ìì‚eo±¿ÜãñÇÃc�?Ž»÷îa¿¿€¬‚›ë ˆÆއ#Cöòòbqyñø²Û½ä=?óSÿ KVßÕÇÄ{Àðïµ ­®ÜQâŸ�-pTM†Š*.*«P_ 0Nuê'¡Î>ô†Î¨&0t®1VÉ G?zõVEJBe¥”DO„H )4½G*?Ú&#Òß%¯®))(°5âk@¸¼Üã-oüb/É[I{V †À T»“€Éy¥_¥Ïa¯G¬d¢¶4¬Ý{yi»`Á¥ÿXA:@V€Àc$ô�d€Úøõ•©¡úîèð7¾í]/èXÖ€ÿ¬¦zåàOð_ó…¨ú�ý¬H«¢:¹®Ê/PP5.8×ÊrëwJú[ZЩ:Ïd­·j«òãû2Ai[a…ûž§ü8«Ÿ9w~P¾ÖÔºœ—à¸t'¿Í åš`QâSã‰À~·ÕÅ1Ϫ£×~Ö½ð?¾ÇƒÿÞŠˆE9]9jBž¶,J•ÌÜL‰¼õOaâ�/æäzBÐÒj –ˆüuÇyòA?J_Vƒ Ì…¬ ëØ¦�»Ô½´|Ø"½õ�ª�(´Tô)«ËGÕÿͺ+]šK‚ñš¡ò™G¯r»²„o:Ïí˜F¯¥$+Rl@ÿuÆÈJR'}%(bê¾x{*`¹Ž­É y­†0¾¸Þêê+�ÁµI'×KC¹�Pý†"ï ¬NH!¢“ó×á’¬D1 o–蔽¿”bSKŽ’Œv§öò—ç¦þSpi?¡òb$No~.«¾E(Ä $‘¨.?þ±�ü"îϼê _û]ÆökBs4Æ8"#zžO€]\3ÿ9PYLˆxÛà?+R1‹…ÆZìv –}PX– Ôeüç£*ÙdB*ÍÊÿ3f̘1ãŽI˜1cÆŒ3fÌxH¢ˆœÿMÿ·(aoÈ¥ qUÿÎùMDc;ÐÎoøììw.p÷Þâq<þØã¸{ï¬ÝÁ9ñ&ÖÀÂ~¿ƒ[Wc ]î.ö÷vËò²yûÛ~ϳÏ>ó•ñúÚ=ÁÖ ¶;:ûIYÎÕߣ¥¦åfÜpC/…"Ékð"íV­Ñ‡¶¥{’özÀù”äŽËê|ßiÓÍx€¼RóÏÀ�"ˆH2MM6ö4î3¹ ªËÔF?Õí�Þ“Uêh+ˆãoðÁ›Þð*,6Ë>醗â7i7ÜûC¢PýXÄrhh†[W€n‚ï)`±óUPvï?¼„K_"Š@%°Ó۠ؼöUhßó¶wãCy¦jÏÛaY–)ëÿ"λ½>p`ëïçü­÷ý(j5‰¶nöœÍüóå¾cí?Q Ž7W¡¿hâu g¥ªàì�¸›§JCo¢©±,Å£÷‡Þ§íjòt‡�1ýÐø ÃÈj=½«ƒôŽe­ÅóÌÆë¢NÅg¨qHUÀ±2õɯ«Áÿ¸&ɤÄ@äªÚHW×’óÛèlÙ¶•xM‡Ô·©»Ð>ß“lÅJjz-Ö.HèVÒù[£¬×E² C!oDÔN¨%rrLC©evôíGê¯NÝ¡îÉ(²J¶‰•íPÒí §!_l6ç°µûjr RZir©QV‚ÿ¢+çXTl*6P¨¤7P„ÑÖ¾é´4JÕ "�”Õ‘¢PÎ3i…¤›wfˆVЃ95%uÇb¼Œd¯EÑf EÛIûa!_³V ‘­ÊþÒn£VT�ÐÖ\}ñ‰§>þŸýË_ù¹‹/}Ýÿ�5†Œ1÷�±×­õz “Eãç.þÎ,pì²@R? ¤´, ë× ¾Ê?¶'@¶ˆ@êEß@h˜1cÆŒ3f<21 3f̘1cÆŒI „|uGÚˆQ›ûøÊ¢\ñž6ˆÆ,0ÖbÙí`�ÅnYpï±;xìñ{xüñÇq÷±Çpyy k8¿Qdìì‚Ë‹˜yGDwìξ̽âçî=<ï ©mGê»úJ¯Êk°Y+3Ð ”u5é¥ñ;ýÛô%Éóyw½aFµÿ¯ÞÈÓGª+°: õf`]Æ™+£â¦›dù×ÈQ+4Ø9’£éV ñö�ÏCµýĨ¶‰’ÅN÷¦~ÿ¯|Í—ûJ,&ˆ‰;‡€‘ $€¬Iòû^€r½>!6)ùý±`Ç+yÀ>Ÿbw^1`‡H60"`/ŸáÏ�T4âÇãü‹â~nÖZ,Ë2«§^lùöDµïw§€ÿÛ¾·×ïn þ÷ªŠ·s Ð�b;òmйFóu¾�ÄAˆ¶¤*u¥#ÿR@}^š ôRw¯ Keê<®‹¹Lšùá䷪ܥ}’†rà»Ý^]W¿M®>"•³cX|$pÙW–rÂîÒ½S›4Øí Š4¦– Y‘'>k]ßSâiçféÙ�R/Ðà•H°ß‘è:1¯vÑjé?ÉSœj/göWRd ýV)ÈÒ½®[’j·œÞÈ�Š,#hÎN�rê·â Âó]Íãêî&74$£Z=A õš D�El½æ«î©¾óòÍz-I™¼¡¥÷Of§­´’­T²„4ÊIö=å1:�;ýX?�^žïQ(„¥´‰žõ•JHÒ‚iH»ùu”ȱ™`Û“©™••@Ì¢òãpx¨ÏIK½ƒÕÏu4Yžzêcÿ÷Ÿ÷OÛ7¾ékþ¾ÿG�"ÌÁj%Úª”ÍÉ^Ù-œù¸®X�+Öõ·ºâca­ÿìhlT�óïq °a¬ÎÁ9HñÜ5Q›žß;cÆŒ3fÌxèbf̘1cÆŒ3’ˆ2ñ…Uf#e7â¥(”!c`‹Ýþû‹ ì—‹îÞ»‹ÇîÝÃÝ{wpuu…‹‹ 2` YX³`¿,ÑF`à€—×wþÃßwÿþýW·»-°7èz 4P(ªêêÍúpª|p´ø�’çå$Ñ«@6êW�µ`›:‰Äj89]ˆ%£cUŽßøš•§õþj®‚�î¤Û5wúÚýž¨(a)Ï)½JU]•¦¥kIª X J&µå~¿Ã[¿öK¼«$ÙÛnèF¿h0+ và´1¾ÂÁn Ï“óuî»ìý{# à€�Y™Àa¬ÿCäÑDyhâ€ñO~ø=©úÿ¶a­Ån·›‰ëE–c{_‹|†À9_·ÞÛûù< Á¥¡~NJ *'JIêê½/ÿ\ƒ©ì!H—%Ô³|V=Ê@–ô@·~à(l$óÎýõˆl­’J;ÿ�uVÍõ̯~yqqc¬¯Ò�ù“4X¬½½uµg…U©êÞBö_“âÈxu¡`MDTËh噯KòóN‡*H¤ˆ�°O¯Æ�&�ÏDm_# àûBv­Ñkˆ Òö"$Â_MªiHxŵŸ�DìÇ?öÛög~êÇoÞøU_û�ìÄ‰È ÈMþMøüfƒ @Txsä<@$�ÿëº&ðÊo¤Ê{›Ç`x�cÆzôçVIJ’1ÙZ&þ?cÆŒ3fwZ³µ2¨?6Šç„F,i˜'À´Êa‘ )ÝbkÒ>å¿DÊ~d0~©ºÂ暨f†jåùžu×í$€¼”ˆšyÍEƒjöVÿ!æ{*4bþ”6O“RÄ¢qÆé%FMJíužü¯ü™ËuºT^¢æ¥â½,½)HåFýC}@sHc÷%=�1ÕÓŠ´!ùµ»Ü/ÒXô§0™Ø– ËG>ò¡?÷S?ùc÷_ÿÆ7�;ºU<Õ­µÎ.ÞÒeYcSÞp«ƒàœÃºq<q8°®ÇDt2ÆÆ÷%c,`"éØ+¹8!€Žέá—‰Rˆ,¾NàÆŒ3fÌx$cf̘1cÆŒ3– X¸¢+Y‚¿%J�WD7žL¨Ò³0Æb1 vËÆ:Øe6“†<° ,YÐâ e0"²wìîý£ïüöo¼ÿú³Ò¹iË5Uÿ©ˆÒf É©$=9â�‚±UpLW~ŵÏq½ÃÕÃqDF—Ö{mPè Úê¸LÅú6Ñ›‘Ò" %åjû^*0ûpo„Ôš±¨PºQ€ˆðÖ¯ûr_Á†ÑýVÂ2¹�„°É�øZ|±€/Õ�8�Å gÌw<‚p�- ÀH° ÖëDð]Ü@à``‚ Šáïúg?‹}äéó‡'v»]ã½>ãá‹S|üù…T8ç¼üÇM~(BXRùˆy´”‚N€®ÎÍ¢*O;`~�©ºÉ'TeHuýÈéÐöå@&=©ëS°¤Íu§{B¡ó]WŠöÎGßøH®ŸÎ˜ÃêYë$¼L•§y¸}C{ïƒâoM<1Dì\:ƒ¶yÍs#…iG’\vÑ„Tñï«ÿK�jo€¤ÔBB>ß«ç)#›s%Ô Õ7ý¥“²ª”í'²¡„ž�Ý�'U�:Àâ ¢�”K'”ÍùÜ-y´ß~¿^�0ðv€¾Ô±å ´ÅêÍ÷HÒÊñ‹Zûè*l!o)T÷ŸZÙ‚"&,¥5A·5F%ü�Ç=5mÕ¨L ¢òQÌÓµ­Ee�ÙLt]{”p�ͪ]­¨;‹Ee±4 ¯B@QÅ‚*uÊíÃ’ÇdšKËvë)8lÍ�é~L^ïçœÁªˆHcð_êy¯þËù¬è»É&«±BØ}èƒøó?ý/~üþš×¾þŸ‰0[»ˆH¬1¼,‹'g+Iàÿz<âp8âx,|"‚…o cŒ" Ùº°ó$ÙH`µ®XÃ9qÖŒ6cÆŒ3fÌxqÅ$̘1cÆŒ3f<,!(|à‰L–· ¡¼z£T/�^8ü¯ÀªÝnˆ°�¸1ì ¥Á‹ÀX…Š>k ˜iàÎz<>þžwÿÌ* `Ï­�Ê?m½>óýmÒ–#Ðs¯öm’‹HUÅ¿ú_5m–`­ÁžØëÚ¶¢.¥ø¥zuocSº’¤R>â¹)ÿ8Ù8GP_ˆ§½û)š]úžâºM­1xë×"œÇ”wŠ�/:‚qXÄ‚EÂÏ ä› ²Á»™ýÆ«&±ºüáÅ@ Xë%øm¼ÎõæC¶Y0ÂF< Z,ão|뻆ϣŽ)÷ÿ"HŸg‚þ£×<¨Àmþ¾õsg:Þͦë�¡ �k“Ï´ö½ÎÉ(W�V„Ÿ¡Àq� Õ%U„‚Æv%É’Ç'¥@#{‚ΕIs‘åwµ»|öQp¥ôç¨â¸CUƒö½ ÀVWܪ äæ^uûVß‚‹Ë dzšüœÀR)`éBŸR}VjOrÖq�«mE[ ·í@A–ZÙôè9±™D©èj½^¸±`"¸Å[ÎÞ�KÃã¢�3÷Œœ¶rÓhñ -|ôšDWÝ…Bç†äD³é5Aç}=Š uÆGÍÌÕÿå{7eòÕ8íKAd«êVÿ×ì3L(\¨Tí.[Òj)Dõ� s‘BD:UöÈ tT)"ªráøY”ž >n¼¦.�µ£l‚Áza "Ý -ÛOmæcÑŸmú�µwúÒê¢ßiH¯g™)^E´µ&î‚ÿšÊQ)Ä_ð¦â aN¤çú,|ñ¡~à¿^–å�|Þ|ÑO™gÉ�,ËrX–�,ËR´�sÇã‡ã1X¬pî˜í±ˆ`­õÏÛë¶f�±&õmöVœÿ‘°¾ö+n4ºn3f̘1cÆŒG%&`ÆŒ3f̘1ã! ‘RªÔ�¬Éò¶" ö^ŽÄaÓ‘ýV¹f,ýÿ|FÇ~¾ÀÊÿÆä m-íN›…ËcÜOI»§ñ^è-wjd[„¹¤w•«©E—¾4z.¬-=Í!}šUϤÆgdèsÝϱ[÷Ó€ÿ§ß-°“æyUUÿ½JÝýÅE t5w“[¾°bPª8 8+Ú¬êãòäCÊ_sõ?ÒÚ£eBèóNü×òå�^¤•ßì{$RhŸQϵ™Í*ç :õ\:ÝOªþ $€è;  Ú4ðQU/-6ŠO]ò†åÁ(h£ÝJˆm?ã´™+¢dxÕEÞÂh6{O[úME“Ýw¿ùÞ€ì?®K¯ Ò†x¬ŠÀÁÿ`Ç0ªì“ýFfP 0 `1`&_½$G™ÎaÅ"À6¬í²óò§ØAváÂ�ÏF¼€D€ð=ÿO=}ÿ$ k­�àÿ§8Nù½ŸÏýãÏçþnëX/ðû\¡\B”¬RjH�å¶¾‘T²uϵoa°|mµ¡@‚*(%Ç” �c"�(ñ}m’ëV'ö*œG÷!e}küJ€ŸLëtI¬Q�“-û�ïìXO}Ê£›Ó1³<6BÞn+tE$YÅ94¿-×[k9ÿ4§ê¢Ø HJòßáøV}„zMÑŽ•¾æø€‘�I©€Ìóˆ3ç<ôÓà{­Aqˆ¤ñ h�9?wB¦� /d않ÑøºcâARØì°µ¢�zÓÖúŽÆK¬j\VĪúc˜Fj~|å}ŠSÊ•ÚfA9”$# ³zÔÉ—ó´ô×�8ÑÚ9iK´ó¢<~eëQЃÀ´-ø�Á'–µ‰Ì%µ_Kt�’L€JùK²Ô>Q¥ä@[´™†J¦ìüú°tÌíËýÏ2°·jÀÿÁš»œý¤3éÆÌŒñ$€{¬I­ÿ>deÓÝ®�ø;ÿð_œ‹D4eÿ?q.à¿õÚsŽó  þm€ÿÑïºýÍx¿õ´ŸÆiäÖH²²h¼F*ð¬&÷ôU‹#0‰ \U¹b˜àQy‡+ûì6-–ä#�— ð[ò/¥c#“ýÅ;ª(… y?±vÉ gÓ†©¶ùå¹àÏÆ`ó-¡½öû½WSÑ8›z¡¨*SJž&ÙâÊÊ×ZZMŽíüT]D¨ÿÓ³UÿÇ·äyZIiÃ?îGƒ„ºì@×>ðÆ·»wmµT|R 8ûyÕásø¨_Xc¡¾}¸êÏA)Œ®¶™$Ð¥º°Õ·O¯Ôšf¿²7Öõó£’_©•è¬^^/Ëþè‰�uhÓH\ƒ4K·‚”X^XVMòã@4�ÀÓúºŠ| =õ’z 4–Ò+ ܺÓ�A)B1.4ñBI‰ËÕl¿�*틤CŠ z­Žbüë1^ä ´œ‰¹ Ì Å|PÌQŒ8;*”'8ëÜǾ´ãJªõüpèPùÜGêe”D„êyÔ¬ÇÃ7üèÛè?úü�ÿñÿÉ9ÇÌ|ß9‡ãz8ŽG�G¬ë ç\ZƒãÞ"€¨œgÓ¸` ªq^M ^n$Äãc`¬_wDë�H˜1cÆŒ3f<1 3f̘1cÆŒI¬ÇœÏrfC؉…`QR›1ÂæŽs~Ó†"Aú‘BU- : ˆÎ¹ #éA"³è.‹<ù®ŸøÉ×=ýô'¾¢¸ �š±èo:è’©º^²a³n,÷Ù;(ø Éµ löo•tßh®¡:KS"˜`‚ê¦k\k[¦”ÂN½öt4køƒ»DIrêº[ÝèzÃQùìÆMÕ àOPàí“I \¼†Zþÿkßü¥ðú£YÀD .Û'¢}€]¸Zö$`L–…&À�iX6}Y$Àñšîe ÿì@ X³ §»Z�†ß@ý»ßõN<ýìÍɱ8ÁÿO~<0ýÜ*ÿÑßÎ!<ˆúÀÖïFcÞ¦J¾Ž�~©R#¡* õÁÿO W*R§Š³}u¾¶ ½žÀÙ® ®ý­%‚ù M̶ä¥JA™c.m+Ї¢4½ŠÜxØ“T�AŠ.~ ܬ+¿‡óG;¡&]xýnçåÿIªûéÈ;Ç™ŒââA�ÿÌ a¯ ßë_')k’^$ÁÕspò/*rãÜÏ V„=ŠŠãªB{oc<[—-)ùûŒ±iÒɨR§IÀd_UH«ƒ0΄ùV*AªÐM )� @` ˆ¤R÷Ñ-AÉÚà¼~w‹¼Üô?ÝN’ÁâŠf)%ußñ·ožcô—NÛêåS @”Ë ©€þ¾bJ/5vZÒ?�3Døš€Du_¦Þ�Ks«¥òCOÕŠ µý3†Âð‘oª5r½Ø­óIon@¡G”‚ƒE’¤¢tÿ9 Y÷¢Ê�Õ¥T=¨˜PTï×àN-\T}>‘ŽJ“æKvtü¹iãÐ&e^Íîß¿ÿoÿð~ï/¾õ›~ßß眎G>ŽÎ9_ùŸú›1°ÆƒÿÖZëÉE…7þ3»Ôßâ:ë[í°ì,¬±0Æx»8f¸ð™rÆŒ3f̘ñèÄ$̘1cÆŒ3f<$Áâ‚AÄÕî±r%U�!WjH¨K¢¢â+>,¬Úl8'`ñ¤ ‹\­Çõ%oÛý¡¸‡]ƒ"m½¼4—>:h››Ð=0$JFëÍíê¸2Øš—מ¦š�Ðñ³UàWU€'wÖ©¢#h@·Ý:¿Ž€_QI�ë­o„¶] ´Çp!­ÚJŸ\KŽÀ7ã›kA„õ-`“o°p^Ú?^R¢( b0 È0`–ôz �¬…ÀÀ¬«ß $q„„€Ø ‘m ¬ìý'¹€ÀAxÅ'žyÿ¿ïü©-G¡%Qg¼0qÉþs_ó  çúŸTà_�©V‰h’O­-"¹ê.àŒ3sS7#Rå}“wòÁÕï²:JQ�8Êl±‚?©„÷B ”’µ€òCïN‘쳪ò‡à?埼§Óª¥&N!ùÝÁìEWQW &aqQÍGJN\ûjwJjEÊÊ|šs¾ò\U’ôµ§ñ#-´XÞ›¨ wiÛ¢Á®¥¨àmŸhkÑÎËeCuÚ|*£uI#Õ>˜§ÑTE—ÖBµIFK»“Üß9NŸì�m­µÅÿ(Û¢�éÒÉž=|EE–�@B‘zÍEm檘–íÝYUM‰PMG‡×Lž¾lH ›Ÿ;'r†¶1Qy‰N¬ã:‡ú…Ü �u”Ûä©íž/„¯"׊t—ȉ×ú_¢ LeŸÐ64êy5W©‹ÐÀG‚¥ßBÙí¢²ÈhÈGýÓ×࿾Mv¡üÏO Â\øñ�ìÿøÎýïõ+Þô–¾:çÖãº2³‹ífŒ™’,HF©®("‹€Àž..|NôÏ PX,– $ ”no-1cÆŒ3fÌx˜cf̘1cÆŒ3’ P’ê%kà¤æ»c_Åï8lÜ”c°, ¬5¾*$Vހ¦� Çr8®kô†\Üêî~ð™÷æG>ü¡¯U¾O=‰ùâJ½±5Ø8†´j³w\±$Õºö4­66Õ÷Gé€ÍE‹ò<.¯õôC¤Ž­@y¹çÚ)P¨‚-ÞTÚÚ9*ôµIDoÒÆÊu¢XÙIÃûÓ¾£ðØcwð†×}±ßLµ_\ObÎÇÃXlÃõ1`üZMùœˆÁb`8T ¥J? ! ù*ÿ• €c ` §ö°Ñ;�,Èî@nŒÅßùöÃs÷§? -ó#Òó‰s�û}߃üí…ýo{O£ñTL*p°‹L÷çä/}†"ɰ.$‹c>��ç£ü‚€í„§å¥QÚ«$Ð[Yˆd%êaÁ'ÌÝûó‘ߥL¶›“ _zƈh¾Õó uæF(&^|÷n¿O`…Ç5s5'’TslBÿs?ÇÏ’ò¤ƒÙÏ[©ï¤jÙx¦p©˜½$8$­Y¤¤ «SnÑN…ozõ�[Jµžd'cb•v2�Hæ$[=Eå·4ì `¶¬ú=¥N�/*RÝSAH]�:$LêZûÔ8f"!ÔÖ<Û™¢ã¾^$Š$û^+�H»4;cdÔmÜÿAš$…V- ÷“œÈ‰Ý\¨ "¥z»Z…èäým�5˜´ÝKm›ÐÍG�ÏÖév×ç‰ñÛȉTm"'™&9“•búZá" NÝŸ ’Rûþt2*óo­¶¡3Œ_ãfeQ첆z#Jé¡iP*Ũ‹èªË¤GCtú3C:/ïÞÿ�÷þçOþêËÿÐg|æçü 3Dx%"¶Öê¬é߯â«ôÉxÕ+¢ ÈE0¬ ÿšD/­½Œ5XðOUÛ*mÒf̘1cÆŒ/þ˜»[3f̘1cÆŒIØ�…aã½Ì—ìâAû(ß/"X׫s`ö@éb˜�Ábÿÿâ+ Ó¦¬Ýa·wpÎotñ*X�ƒÈÍ~uëÝÿþ‡ð÷3óÞ_E‡cuÔ¦Fn¹ 9Þë¢ÞË‹ !4ç¢ t‹ÞLTGMû‰Ô-†/ P«6·•’Ö0ÿ·ª…IÕÆy¿•ºr­Eµ+²=@÷ý ~­j«­ˆ¨”ýßè›z£ðk¾êuXìƒ-@.‚,Øcßv–A †= @×:°‡E]ý?ÁÝ¥¬zÿÔß~§%ÿ_ˆ×ž{¯ÝüHJªW�Â^ñc†)iþ&çheíü:鞺¾SÏ«º¦8/4`Ûèt}ì³;s�ò©×ù²÷Vjro›SËô-?ì±Ý“Ñ-ÚUzW3¨Dí5–4äÂåÕ�±Š8Åܦ w-+ìã©£?3ÕÖBÆPÿÉä Øñ±ò,SgÒM&¤ú�žJDOÙ¤¦xUŽßxvoxrK'Ê}¸Cåäé¥Û· Ö£Z‚'Idò„®`ît•Ȫ®�’=Nw ‡õU}ºVœNö³„®«‘  ê€ZlAªëJ«�32§勱YX9I³^ìŽeDµ 9#“©Q?ä PïÕ�YÓYkR{UT7NgíÖ[=§Ö% ãƒ2�E©VøöIÔ÷$茼”ØAͽg>‘·.ýO�F¥ð1ÉžE¡ÔÒz;óuƒÆv!4r}'u7Ñ9�e3å§u)µ¶¥ê˜¾Oý²­”Å– æÊx„õxxó�½ã‡ÿô×}Ã7ÿYkìÊ 0» ‰çc¿t &60l l!‹M¶Eþ¬GXqUÏ≹ÌÒULš1cÆŒ3f¼¸cf̘1cÆŒ3’Øï– øj`ÈÀ$OG†s«spnõ8ª]°Ûïpyu‰Ë‹;Øïw0D8WÜ¿/caŒõž�;‡ýnG‡ãÑÇ‹u=\½óÇ~ìM‡ãñ@gË­Séy;ÁÓÚo4ÿ^:ˆŽ¶n‹+Û*£Ú§ºÿõ_«{«¯S¨òe-7ÁÆufÕ†d dQiŸPŸº¥YúÄ”ýC»MžM¤OVümY«ç`­UmNøê7}) c€á ç`¬ñ¥GðÞ£†ÙWby €òFƒ3@pÚ…ˆ/geã`œY-kîÏO6["0°¹R¬8ˆ\ØØe˜ žÁøÐ‡?ŽoùG?qV�ýÝD¸-˜Φð9•ýç¾në5çþ­þÝó©ìà¿íO*_>Â`Š&÷tÇpÈÍ¡r¯ŸëŠí[dïžwv ¶§Šu\7âä[iH©iI:Y²"BQUúYÈkk?o¥5þ‚AƒROÚhGéÙŸtjç®ÝnkÀƒœß#�Ë@K’gèrŽ«ÿ¾Ò ¡²Ñ.äÿc….!Wô¶h•HHYÓè ^ËÙG[šüœ mü¦u©;¯“’ï ´œß‹u‰°®B®çÞjlJE£°FŠK¥lÓÐJ«Cƒò o‡ž·75i‚’zGDü5apk¼ÒÆà¥Á™ûûù;)T8Ôñz MŽª�¤Cö�eˆ@JŸ6O£ÅbŸßRœû›2Ѳ"|�÷LU_ÓàÑuÃBõS¤'ÑU¹/�ÜZ4 Äö,bNIÇ‘’ä’$ù›¹P²ü}š;ihi‘,¤?�%U­…©ÿ;s{² êÏ—Õ9Z«3¤<ú ÷ï?÷ï¾ë'äoxã[¾‹ Ë‘yKBN† ,0[0/0KPê€'Jª1y=bªP"â­å&ø?cÆŒ3fÏ Ù¸E¨’?¿Í lÐÕðu•iï�——¡¢=^Gè_©úß4 |(÷üºÿHôÿF"ŒÄ2ðhæÕ qOD,Ô�‚žw$T59eßì �Òvyx.WߘœÚJñ ü÷giô Ôöµv¼KG‚œ’4{oænªÁ›‰}D¨10ăvÉ¿cÉ�sÜÅ:`¬n*Ñ$ýÌ©”¢?Ù¹©Yÿè+9ÃŒC}K’éG±ú£¢áê9„N'h2'm·Ÿq¯}eIíÙ{~­U//ç»N¤"e—‘ǧ'û`l¡…J-f¤"ÕÜQß=¸¬ß#ŠpÕËgÔ“�馸\úŸ²Lñ¹ å›jÌhµ*ÀÿþA Iþ_[xdPŸR[ùy³V]‘îméžÐ3½9õ¨gÐd—’VôÛùðŸ{ß{ý^ùÊÏþvìØ1;açÕ[2€Ù€™ÀìàœƒqÆÛuÁ“_Yúz]²¹F™1cÆŒ3f•¿�lÀ�Zy`³³ÎwúÔªÒ„!×�rÞ�$O>ä ÀúÊ«>oh)AÂ[ûœ×Ï™J¦” @˜ NN ›€®ëó¥\ q”*õk•ˆH4ì�Ú€ƒ¥V’E¿Ëv”~áR]÷HkHºF>[•×&C¾�ºy€0²/úXA°ˆòíMòÓ©ÖŒ§iz‰ÓÃè©ü§\“’ PäªÁ@F_ä_çèíÎL&ØU’O¶Ž@¡ÔßäÉÍ9vä^@Ý׿¾/]�?Î;-Y‰Òy<ð®æ0©H%��(Bˆ”¹2<´ÚΤ×¢ˆ""ÕxV÷£IH¤ž�Ÿ&¥ù\Ñ6ž è}Õ¸9ïù¨Ü™Nû`$`ÈË~å—~î?}ùË_ñï:çÖu]WvˆYñ„aˆ˜ ư·¹X¯ctžŽŸµ€Dë©0cÆŒ3fê[¯{!¼×¿¿ �ÿB‚þ>·P«H²Ý"ÉÊ¢–þ�yª­¶Ì`TOé¤â*©æ.O¨•’Jk3@cË�;‡)0WXR'Õ´*@I(‹€u[)_[¶˜B‹kêçï4¤ Šêçñnuñ ªõldªf‰6»=kÓü¨¥²“Ä~xN؉ý‘B¨ ó2% ­¶CÊuÀJê–ƒ74¤¬$M³~è<éÀÏûþr¸÷Î÷nú>Õ3­wÓ™ƒ³mUócz2¢Tq¨¶]ˆ6 (ADHÛ› ËŽÒ¢AD*‡¢¦çªú²ÂZãØÔë 9'�8ªrûVô€sSŸ^§Õm¯N=WIÕ©shÓ±FÉèp¹nb°'¢öµïŒã¦Åãy*ºå5+UcÕ_A �ƒ�”&Ôè<¤ýìI“T++“3ªæD�W˜8K(%ø^+.”]$Ï[P²ü™l@Åçý¼©ó4Š'&(ÆIc5¡dJé5@¼�HnØÆzºSj5}zMÝ>š¤L�òE™F„+MœÊϼ×Þ‡ãákßõ“ïø£¯}íÿ²cw`fÇà5=&C`G~€…@­µ‰fŒ�­¬‰´üÿ$̘1cÆŒ�^LÀŒ3f̘1cÆCÂðWì¥�Ç5Éþ³c/§�Á’6svÖbÙ-06o‚cÖ„j�(›Ndˆ°3f¹keyâøÀ7ÕªÊÖK+Kgƒ®k¨GÎ\’H#x¨¬üÏÛoÒ©äÉ—¨«ýòq¤WSªå�+àª�S-0¢¾§iStü×WÓ݆<Q<+mÕ¡ÿ©·Ñ¨eÂÑ‘n­Áôâõqó5oTÆMÜÇ»‹/}Í@ `ƒ\,U$ ‚³9@L”¹­œ[Ã5ØÐF\V÷FùÕ°y+,ëUHL~ÓÓ“,ÈŒÄ:Xn½�ˆ‰ÃOüì¯áÇ~êW?uãù¾óçë…~í9ï}rÀ UýÛ÷>ŸãÝæ‡ÕþÜ-ãr™LErFE9•d¥>Ù©Ê¡ÊS¼§ÀÒœIƒD´�Õjå}mg)ŸÔ9R½©'¡œ*K#  x—Œ9QÇ;µuLqãÜ»Ñpò�w” ƪ٥ @ï.//bÅB¥%ŽBú2øŸ«;…ƒÕŠògÉ礈›A8¥À#½ MÁ…=7µÄ5©Ö…åOµnØ�è/$UdÀŽOE<¡�§(¥ BñG25xÜÓD¯ˆ}$EÕ»t:)+ä·ù¾¯ìêU7ÓVGµ  ¶Ö!Ý•Ka²±þ9—wPI4¹C“1ô¿¤Û˜Ê&?ÓÉ£¸Dª-RbkíWRíwñ÷ºÖMœ HBu|u-¤z.µ½2謣µN¦‘Y—î;± ŽÄ­HŠ l¡ç'ÑÛLv`áþ‹æJ©aswíTÓL«¢ÖÁªS÷ªý£r‰þì0tØ(cW‘+®I‹g�žËG¶0hçijǼ¦­Ôĉðý3Ï<ý§~ã7~åm¯xågÿ€#<Ö‘$뢪 ”Ä“³Ê×j ŸY°:¯4ÇΟ³f̘1cÆŒ�FLÀŒ3f̘1cÆC,ìÖÕ…ªÿ#\ „"fÄ _Ýo@†Ò†—ƒÅ©ê@% ;¶dpADwñ~þóžyæé/Ѐïvé¤Sy™bè fµÛÙ·oá¡J–¿«ó&d¥@uÅ•žj'˜zçÙjî’FÒ©tÞ÷m¶Ð†@�ªö/ÚI�ÿšÇÐ�@ºUPeÑjÞˆ¬¯Ù“:Å_ÿ%Þ3Ú18|Š0±¿(ÐÑ’õ$!/Ÿ¿8X»dLk/‘ž=n…ØÌ.Hÿ;xßÓx/† ˜�ñä’XW°á¿ýÞ|Ô[€Ø²ùYƒýçΟìj«Zaà¶×ÿ ¤€Û¾ÿAÀý³, bB,†JÞH?Ó¥ü´¥ŠÊD½ìÑ·&)+_ÛªÜH⊿� qvPÿWeÕömVü#¤ôB…œ|yM™p¦˜ �ÓR+a-Àƒ´ýN�ÿå\D¸s玒Î÷¶@5"ßz;—fü„°f l@Ô¯~MD •Ï`�xÑ›<âãPc¥J;ì§›± ;°©’ãï#Äe?«­"êcwº¾ –Ο"‰R�ÛœS2úÞR'ç¦(�[¿ ƵÀ¨ãJÌtÖ:r*+túnºªÎ›åıHB¨ hP™+c»ªQùƒ“ÕÅ– �ÚëªÎ‹Ý�j©wÚ ‡B墒ÌZ5U€r3_h,4Ýgyv2J¨|EFS‡Dx ¶T{<0ŸÇ_zNì×jDÝzû$Á¯Mâe"œ7‘ Â1¤ž3ø_Hÿ'à^”%‰¢‹©µ+©v¯ªêÿÚv éD„úsV™ÍzO3)’]~øÃøs/}ù+ÿ§»Ý²2d¬9ÑJ&“Ê~ZÎцÈ$E/ñJs"pŽáV†s+D\X÷Ûù�|ÆŒ3fÌx„bf̘1cÆŒ3’`Çì’ÿnu~s†óF•ÁZk-,Y¿­%‚u=‚a]˜W€°0Äê..<öÏè¿@­¡šd|“<µTO!²ì2>V,�ø{û i°zŠmBÔ7²E¹á˜*ùÓ{ª3Ž<½‘TûÃ3k+�¿þ-o/ˆ`lF‚´dDmظå ¬Ø@0`Ça‹zÿ¹¹‚ðƒTUm¬ˆERuD¯ñøæ¨¤g»R´ß“Í�ä·«‚õ� ½úzÕ¥õ�«¶¤Áó´è:içõDo7?W]�÷ j[…b=œMTЄ‚® xë Ÿy‰˜R‚ÿµy¡f„Ú RÍ�D®ÔõÏkÃh-¢×I՛ǜu¿•¥W&iƆPåßj'zÃj¸Â#tó–o>©;oº×øJÓ͵J¡¨Hï¤HÑH*`»Îk,�â5ˆ”òÆ�®´ÿ¯¤„kð ¨…YQí³×†ã#—?�+òÛ€ˆGÕŠ·£=ëRþ_6¶ó£Ü¬’áøÍlϲÞ\üú¯y£‡ß0Ä 6ɇ9µ�ñ½8"VÝúß‹×05`àÂSˆýŒ9ì¨ HL†„ Ö®–Ü#Èø+'˜¼ þòßø§©�Þ&˜Ö¶ÕO[þ[`ÿ¹D€*°�÷œUEÿ<ÁþOÖßú¯/i²Q}½ÅP*MPFã{8ÎSŽå|^f‘òk‘¨N%£H(èÙØ«D#M…b èê×IþÊýÀèDýüŠXÝ/}+—îëÑ­ò﫞”óM”·�¡\Vò•o�æ—� Ò¾ÒCÛ¯îÜ  ;”‚BÚº£Ð�8.2&�<¤ÛÂ(йpø‘ ØCK•S1Ééë–—¡/Å-íœZZ‘³^" Rµ" 3x!4ƒ½"þsjí ÁÃTY®iÒ�xP[&ôÖTOáT)XP§Ò¸°Ãw[ª6ÒË&5Ñ@Ú¦ÔÏ<ö£3Ô[S…ûJ^òè«ß—9+ÊÓ (rYëçÖqçHë¤Ðï³ ‰jJP6K5YR*âjZGE‚Hd¢B”$®§+á }M2Ê%¡jûdÐöüFrÚº�U@Ç>C¤Ìa’É[ ×’J¥*“YT½ôWá…h@š·‘û9¢ªˆÈpÞÕŸY zsœV8ƒ"¦ÖyžACJd[*ì#ht£¨H ª­¯¯Ÿû~ë·~ó>÷ ^ý3ÖZG†ŽÆ’3T«´k•þ×òÿ‰pî‚Úœs‰(f­™Èg̘1cÆŒG(&`ÆŒ3f̘1ã!‰ÒðçÆŠ¯â°˲`¿ÛaÙí`¬ßÌw·ˆ(mè¯8Vð¶”XàÜjWç.>ðþ÷½â™§Ÿy5�ÁbiŠS²ç²†·j€"y/« uªJÑHÿC¥ßi<†(¹SéT­û·T 4 kûóû•]g«¦ö$£Q"G]¼¯ÞÜ=ûä}À0W¢u*ŒëÍy]µV•Í›¹(@ÊbADRÅás>ëø´—¿ââý]‰a…À`¿ý¤ùÉ�õ$Kðv.lš›èÏê�û¤8¡é ,0Ć6Fà ¬]ƒ@yW†á~ÿ�ãúø�A¯œûå6èÛªÿçSaÿIÍ;PiÛ×}2žÏ5�ÞÓzåÞ&YŒÇp9ü¥“ ¤ÍY•D}–/Ò_õb^  8¤ªg©H2j°Ó¤¤ô’³ôôЪÔDêÄßÎÕå [Ú¶Le9£ˆ ªZ·ÿÙû¢Z¾�lÆàÿ¶"M�€ruy•Àùz­PGÈ%¬™9TçKÊ‘Ñ ÀƒŸ5’YV)§jm“Áæl)@}ùsd-ì0¾ô’@WØ‹h—ôòYªù+’¢W¼ÕzuÀ�~ª¤ð[�)Õ”y± Ù iU‚Œ*7$ˆªw•cAúK˜L(¾ÁÐ3ãdJR­Ð€æT\Y­aÑ[à_N¨×…ÏʰQ‰Ä§9öy;ô+Ø•´�+ÙW«\Œ}­À07æ3L&Q%ÿŸ^«³P9|lU”­áºôä\˜ûu,»´x±•瞥†Ryè—z¢"¯Ë 'k >¬]  úbfÈtç�|ÉTM¯Ò<›üoÒD‡ƒ#mÛ‹ôVôpñ¡¾ÿÿò…_ô%ÿ³e·»!C7Ƙuî+¥ï�"°Ÿ˜]øÌè¼*—(;†3f̘1cÆ#“0cÆŒ3f̘ñPEömL¿!‚5v±Ø- –Ý˲ >�f‡¸ ÄÁB€™q8°°¯fv^êqqn½üñý‘¯aSV×Eà ÜY#HU™«}|ˆªÞƘè’Ì`nGüÕ¿ùƒE›Ü&"¡Æ„JÙS•þBè�ów"žÏy>V¿?罩ҿ0Gïù¨pÒ€»´=–ää/òï¥á¥U…ïäØÖÇKZÒý*áâ^”]²Œ€v}Î  Ÿê]øÕæ×ê–Ukç�$o.�¨&eÍu«‘NÖm=èœì©<¤{�8¤ï­.:‚0———0ÖBËú뙹×E2‘�…™ªRB0ÙsžÔ|Á,%ò˜ð|Š˜på¡«ò Œ¡DŒ*Îù±ßq”(aJÐd…ª&)˜t- ìÕ7ßòèF”HŠR5faÖ° òJoUtäì -‹ÞÜß("uTu4\)N-C¤ÈC ‘D~Rg¬¢¨ì½œ,­JÊ(¿H §>¥åôE­ÁâŠUÀ[X8´MÞüb¸v•ê|Ûy1·H>5ëõ£ é{±oxBåöú¬%dtäÿѯ¬§ ªŒ_GrÑߤ°ìRvK�ÍSˆ(+�Ö¾ƒ´êTmz_ðp*ˇÎ|Kj­ª©¾}©öó¢�ÁKwˆRW}¦�¡¤ã7 jtlY×J$JM 0 ï=�oüéw½ó_ÿê¯ÿ†ÿŽˆž#‚à4Yj‹P¯Y™] 0X©Îi[‹3f̘1cÆ£“0cÆŒ3f̘ñ�DÜø÷À>Òf·1c,k±ìvØívž`ã7Ó¼§ºßÔYy…ˆàpsg—Xcœ[wÌ|õá}ð�áŒÈž—¹z¯ÜpŽ›Píö­t¾§NÕeÝþð+]/…f)Z²Ÿ0˜­¯G¤³?Ú*/.¹ù¹Þ„§P9×OC 9y²ÚË·¾ª¾BI­êö¯«ÿ«æV¶ Ònj« VcLê_ÿõoÁbw`2`ãÀ«ÀˆCÝÁzÀ‡L��%H 1 Øpìý`Ek2}58\7‹À8Ûˆ,ÆZ¯ @^öß8xñªó[¾ÿijÏk®ëŠeYÔ¸”³@ÿSþcUÕ apîq~'_sNh…‹­±I ÅM–'Uê4ö†¹"¥"aõú4.Gµœ…RK ¤IDç¿2ßÕñÒ”­ mÜNüe$- Zg'ìÛF¬R%å ÝM’[—"hk6;mzòBFóOõÊ*�ºKüû�»wƒõO°Mx_Y½,:‰'Ešè@SÚ»P~˜Ë‹"h4ˆ”×{ôȃÿ”ĽÁ ¼ž¨*�Iªþ®d© l(él&\sæ$€|$ý±§3„$wUÝ=zXt˾¨eùõ9ãX—î¦q'8'Wk(y€ñS_%Rž>Oé�^æFä{¦ñL„=DÛ% Ö=•*ƒ 0ìLÜÈvB¡R}¤LÐ[ ËŒÛPF¼ºšÒº5¸ˆ` % êFjRçÆ; �z©Öоr{Ôöš|[÷ë@f‘²ÏCHúä’˜ÇÚöËV%8k]!M{hµ¯Z†r>ª¬_Ú+Ð×-M{Ò`öj‹þ¥D'ÁÿZñ¢Oð¿øÄSûSúÀû¿ç3>û³Ÿp#“ˆ9S :kíDT�ù3T8f̘1cÆŒ/ž˜€3f̘1cÆŒ‡&²¶³16€îž`­�],Ë{ì–(Tòeùüø?ãæp€µ‹¯ä¶dh¿®îÎ3O?ý%ñ<ù¬ª’Êÿ1ƒþµç.²™]ð?ViêŠþX'ÅIö2Jÿ×ÞÚú:u+•b¤�V”VNX —n#D#Ym[7ÅÏœ†QV™&%…ÆÛEÅm––¯6^£–š%Ť p½yó6¿VK&Kì/Ë‚¯~ÓëaídV‡�d!˜€yø�` Õe™Å«ˆI•ElÀ­0Æ€±€x mè¥ý—Ú’E'0$©šÎƒÃø`x Å1ã·>üÛøëßúÏŸÿ(T*ñçÔÞŸ€‡. ½×þBù/X›é D•+šÍý¤h[wü¥‡òïBîG(š*1Ð,©½Ã±*—7y¸ø7ñ˜O /ì3ÌÕ…0W«¡häp]±OŠx¶qŽºÊ¿—l“\=Ò:°§|˜@¢¶·jßjÞÙ�ôï>§çÙe—eÁÅÅeKHòÜùgC¦ó\¼ wVVi�(¨ˆ”•÷¢æ–\yßteû&ÞF¢øo™”�Ï�M�Ä8¨¤´¡ vsRu~æÒ€(Ž©�Ïôµÿõ»å®WY‡ÐT"ë`¨Ô=wC:—$¹ºYÆ‹ŽñRdà/PHô *yIB(‡•|Cl�… ÈEÊò£~“èçR[3èsÐö|Ñ­~Ž™WõÝ[òÚ±±V À5ù¤!+(ÂÑ9ɘÚï ?ú #Ú¨%©&ÀôÈQ™CªüBE&)€øœa’-¥²U¹=“jł޼߬øëþ/Œóà þ'˳RqJFÌä¡Öç§H»–ÞåEû³tg{ÚXw0Ë“?÷îŸþÓŸñÙŸý§Ü„›¯shór,„eúI2ÃŒ3f̘1ãÅ“0cÆŒ3f̘ñ) ªý{ÃW>¸Dc Œ±°»vY`íâ7{Ø_x_GÇ`ÇpÎÁZc»¿º¼º|ß{ßû•Ü À�û~”dY©¨ZMpl‘Ú};µñ_(ä×׆Ý(*â©=6Pnê5@L ®×¯h8� lù‡Môâ8úš¨WźQQ *¤Æ—ÕÃÅ´®Þ Ö’çßô o€|&J"Á€½ ë@¥@DÉZOÀBàâF¥µ +© Œa8çÏ¥v2ÁI`šà ãÕ€Ÿyϯâßþîtl2sWBõ`ëýNJÜ?ßx¡ì~§ïµýý/†5ãÝkÒãH[&¾TŒmiK§…:ë�¤S½-UÞ²Æ-ó ‹-¥œ®@¨®¾v‘š†í´Õ€ ä-•ó´R›)<›»GlioÑ�p‘ÞIÉl“€†OžÎÄ¥‘z2ý½‹•‘WD"ÝwïÞ+þ*2êãzþ 0×RÚYÒœ`!o—ç÷þÔšŸ¡Gÿ“‘\ø­ovˆªÂXH•áG@$TŒ™zl•2:#ºð1¨j¡;}«®~Þ4ì®ÛH‹z,IY¬¿™¬Êæ‹êM˜ÕÕò¥r�Èd'Æémr*PØ’Pm‹DØ–ÑXkì`dšåY ¨7Ë8ª—q‚–ªönN¯ÉGH„aŸB½nñ¬E5( ÂU$T5’).—І�“±é©²`ÐYŒ> ¢Gûj9ЮçFêÌ]Õr;‚е<ŵU8/ׄ#é“b#p/Ñ’„šõvÁ!RsZ¶“0÷NÃÜô™t©|rÐFy¿ìÛýOCc1ó[øÀÿáËÞÀÿ&9 $€°ônæ ñq!ï3»â³W´™ó\íçÒ3f̘1cÆ‹?&`ÆŒ3f̘1ãS]yRÉ’˜©2†KqÓ=�¬…1 ññ�¿>oˆAUaI�6ˆ’Œ÷¥Ì� 1éMÐFº>‚)5$ŠYû×kÙVå)\TÚö*âõÎsf�M‰U)�)ýÔë¦uþ>}§v¶“?i×̶ڬL€|k Д 9‚hîŒÀ Kª,6êþ¿òMoô%_dÂïxÙc ÇvD\è þ™ì%ý9VâÈØp+ ¬qp l’â,€%�¥R½Æ#d�@˜ñŸý¥o?)¿ÿ 1øk"@ï=“Üÿ'«M>U×P ÖT }bÈ÷l5f’�ÆpÀu/Aaé ê�Ì@¼{Q›ºFò© 4ƒo¤r™ô=èãíTL .æybÿ_NµK° A£†øDK9·-åùjdõ «‚”êø/U½táõ\ÂdÛ�_N¼†\ñÒvºÄÕÕŒ5Åœ“ÖP~Í•{œ?{y&@øc1{[I¶/¤žKüß«¸"C©›1G‹—8kË…\ÑßÌ�$ÝÎ u%tBÎIA– †ÅJôÁø­ÇŸlkWTÀ* ®=@Jí&ò¯Pl•›ô3ÖŠ±ZÉFé¤44êa³I �ŽÅI1vÇk×Ú&C—‡ N.ŒâiÁ®üK­â@õ9;Híò«±jêÙ�œVùжãùCŸ®ËŠƒ‰ôýÒx|l<ŒÆ©JJ;˜úyÔgÊvÒ¿_UE®½íIõ[ˆ.Éò"YÉ” >l�”J—(riRMaÕ#™hÓiÒöý¡Fh<Ð'n�3îE:&=¾€Hï²Ù}â8ïQ•ã÷n=¾ñÇßþÏÿЛ¿îþ@"ZQšãg-öÿ³ÿlÉÕçQcLÓî3f̘1cÆŒG#&`ÆŒ3f̘1ãw8F,q˜™ ™F�3Æo˜ÂÀ’�!ª;¤ÿ×ãŠu]q $f†sÎ8æ]=ýÔ'ž¸¾¾ÿͦ¡.¾¬‹I©È±äeQUš@¹¼©—6s5ÁAIÐG™nŠ4)áUÉû§«¦N�2~�’ýÏo¬AŸÆ7œjÐMI«#Ñ �$ªC¨å~õõwè]iò¦ó…/üßï÷xík¾Ð{M†,`^¼a]�¬ ]”d� &ãûE,î`­�3³ú&²€8 ƒØ„kw¡ ÂÅBß?þþŸÄ/ÿê:ýõ“#ð ø˜ÈçÜß§òýçæÏF�¡",Êpn6cJ�*e…;@|'4Çï£VU¤GÐ>÷M.Vžè9©’"öT9Mz-ÒÉ×£68ïIwó mœ5�Äy‚²ÂWkkKÎFôDÉÓ�ë�ÞUÜ�L‚"Q¼j�1×´~ê›Ä ñ}úÞc�{ ©ªs‹Ù‚Æ Æ@Ø¥gÌZÕ|öh“ˆÒŒl-±¡Q+^d»­n‘B›5¤$)©ªÊ;Ü™3*ÌÕ‘¿¦´¬qÎt%C*5 )ÖyúZKk* Ç5b{{­Z¼˧ü̓ʑlÐDºë´^¯Ø ¦J¥Ÿ_')“öPE«ÃÐ*È•L&�HI/•¶ãÉVÿ�ŽœK¡>¢sK>·tr{è³ü?póŒ·<£íVPýŒIBºcÜ{’ЉyLúRü…’‡´‚-㵜C3´¬œÐZÓŒ„bâc|êãû“Ï<ý‰ï½÷Øã×Dt 2G¢²?1ëÏ[\ä˜z= ÆXmù2cÆŒ3fÌxÑÇœÙg̘1cÆŒ3’ å}*Ì`çÀë ·z`Ÿ…ý^œñ›Šªèוq\W�+Çëñˆuu@ÌÎ:ç.óÕÿ³|½ˆ, ø¤�úÄŸÚœå�[ÞDø§(û¡¬À©Ài*�4ø¯Þ}‹V”á¯56V¨„6H÷MåÎoqßèn3¶�@�ʯ�¢5ˆVChŸO¡Ú€L–¨ÿ/Ÿ[nß,¡ö‚1éO¯ý¢/Àn·ÄbÕ¹ Èв‡5{,vk/ ò �°Ú±Í­m@Ö "K;в„Ÿ�5 ÚùªS2 ²^.&NÇ®¯øKÿÝw7›šŸ”ñÙ±¨ÛúÔVäV¯¿Í±nûÿó=Ç'£Ý‰ ¬µ°Ëc-Œµy Ôã¼C`*ÆVoõÆ�Qúãµ÷*ÇûPI¤zKƒšSûÇpX¤¼-Õ“*o%™uh–ÖÙét#óm$¹Þ {Ï[éÆT¹¸ËFsÐmÇ‹~¦�aÿn XrrèŸL:óªÿón·Ã²,inL*92ö �—VQõ”šNj±¼±sš�¡Ç®”}#óLYù8�9_/”6©y=[5ç’š4—ÿádo䯛ËuÄ-Wí9ÚáH�šdúsí²ê7dÁõBA�‹¨ÖF…o¹ä5@ñ@¥ÿ¬E­aFý¢ø§×w¥OÐÖLÚ¢ Ò܇l&R©�Nx›‡‰\¸þKkÏ ÁÿÜÇh3�–)a\ø¾Ãj\tމÕ§Gy¢þü¡[MFëDRù˜šÇ”•!¤yÅ¥µI˜É@ÊÕo·ïJ"¥ó@eQöc)^/ùëñ•H”Õüë½DtCëÆÉÒi�+a“õ*�õðè¥:ÿž˜Ë†ã³GŠÐä\júM½^�sX�ûÌŸú‰wþ;¸$¢�5d¬1°ÆÂšlÛB…Ä�dâœúßÛËX»`Ù-Xö»ù�|ÆŒ3fÌx„b*̘1cÆŒ3f<$ATo®Å À À’·‰$ÔÞ±ßÌ_WÀ‡£ó¿ˆ˜eqÎ]¬ÇõîûÞû_�ª]±kÉú¶JQɭ빎äkV6%]¨šŽ“|(0]ÈŠ‚:Uì/D´›£õuçjÅícœ”œÞ¼øÖ¯»8d3jÿÚX�ª*vé¼»îý›Ð•y¾úM_‘ÎÅp0¢I ÆÓ‰—lº œ69‘ ‹ßÓMÏÚÖ€„ç`±ƒ³€ñ*ÿá›L”ÉRñçdøoþÎ÷ácúwpŒRöUeÿÝgq püS­ð©<¿–¡%UNJòÜw±,€-"…¨o-áÞZGgýâìW|æ)^DMî«}­Ïxë8SÐVE}ö ×€Cc@¹ªº8�R%Im"…>6Ƶ‹9—Ñ- ©ç&Ê—DKÚëg�ó£tAœ¤˜°9gP3Ïóa#ë2V„i­XêúÍ ùù¶ÆSø{¹sç.8öeQþôº‘¨½ríá-I�G U$m‰ cäü�É cÓnT·™Z7„<(�æñˆš·ô¬ZHL âr·ìC:àYR5 4eêjY5¤¼ìRnÿtOÞô�çð“#8x“S'ú—HÇ)¥œRZi§�Õ%•º’r›„Ö¼M:¹¦ÈËIåäVlépÉÁ}sqLy™Øy6•*B]¸®$'(¨6$À\ìÒ´Ó3ä¬ê¤yA>~£ŽàeóI¨ X饓R²ý† …î'é8ý¾.$2IŸÚþ&d �"�’*Àϯ�„­ùáÓD´˜ŠdS)Æ”#¦™ ¢® îú“UWΟFõ Ñ—b XÏG……‡ôçø³XLåàö™Oü±}ðý÷3>ësžèšÈ¬DpÌ‘·Ø C ¿¨.Û»ZsÅÊ d€3f̘1cÆ£“0cÆŒ3f̘ñ�QpÝ%òçDAXcè\TŠ9çpt+V·bu«spÌ`ǰ–,€½sëÕápsõô'>ñÅþÒÙ«ŒòþTlv¦ÊÙÊ#·ˆ ¡âêlºAI^Jª*ŒÀóp+y¤5]¼¦Ü¥KªæF?éùÙ¼·g*¾uQgøH' ‹r5WuÔæ$°ò�Vjèd/,6ÿ¾â+^ž3ˆQÊ–[�xÙÁ®¡9‚ƒ“æ. €É¾¾‹XÀİÀ-€q–€ @¿ °P>¯ø­}ßú�ïø�U‚µ6[v0¿ Àÿ'+J ¥8RoJ7i†Ê±JàÔ~Õ"ž ”,#HûÿJЇD�FäT(SAE8‘QHÉ�—ãµ›M¨AbÛ à�rO�ùt’÷Æ¥Ö$­åA¯¡è4?Š:€eERÊ „Ê›}Kä`„ß``Ì)Q£&:áã,Ø$"ÔG�Øg´ª°ÖàâòÎe9¡6Ê‘¸©@;ÇG°= òÙ³>Ú9„¿µêò€¤Ô˜¸ àï,×ëúXœç�I«‘š\Õ¿ ¢•jÔ8g²lÜcëy-ÉažåBÉ„ãç“ðY…¢•Ž{ÌEå{¼&::*TÈÒUvÕL%¨Põymý¢;ÍpÙ\VÎßKÑgEkñēȓ—l�Ïäƒ'~á=?ûÇ?ã³>÷ÏÑu˜?…ˆØ‚ˆW0†!â3eïR‰((oyK/<{ÆŒ3f̘ñ©‹I˜1cÆŒ3fÌxHÂP®˜ó»f~cžˆ`�ñ’è&l¶±¯‡fvp«ƒs¹y¡·,Æ9Þ±ãË››Ã�çž»ÿ*ѾDÕæu=6Ë�+)}b›ÐòÚh1©6éÔ‹2XF[ÝŠÐI¿—F¼ '4>¼[òîÏ'dã§îï*©òÖF VUõ‰]ŽÄHU xb¡*´ÁZ‹×¿þµ¹nHr§g'�…‰$ö ØÁ° ÂÎ÷U20ìU´<0ÁB¬'€ lýá95I$8�ÍÓÿÅ_ùŽÇOé˜�D€HpÎd€såÿ_LÑT·ž±Y\Wô55ùç¶øpìDZæúš{×Y*ðTÎ*ûÌÕ�rÛÌ áL5ØZ´‡$u>¨Ç¼œnCM;(ÉtÀ@Θˆœv¶»~1)"X¢ZÕ2[÷)£¾×ϧP×OÒŠk×¹“z"àRÍGRVtJ øn\àÕ�;ƒ×PF‘š‡8$}hÉ“L—µ‡¼ÇµôœÛK&K _©±QTñëFík¦›jã¤òŽE&¨(T[óP[­7±Í“ôRƒk‹Qs•žý¤êȨIPÀ1JŸ…ªú9^ UÒß±%ÒWJÀ%_�X½ dÕ¯t"è²gkŽš Ñr¨ÿc[t¤Ü�JI‰²ÂÈ­ry%IÞñV�âáÞ�æJ~­†âA_[v¿Tq�!1’:ó’ôÆ:ΛÂJ¡†óHI!¤‘ ö˜‘D+Ò9†šûŠg«--0 ‚Q•'«‡*þTñÏþ+G ¨8×Gr—�‡eavC¦ÿ©ß“ËߨgßíE1(%�|/娋c¹!;uŸ«l’z“bB¸ÿv–”áœYºÐX„ëûÏý[ïû�_ûo>ÿU¯>`"#Ä*Õ­ØFÔcèiû7CÀÄÿg̘1cÆŒG*&`ÆŒ3f̘1ã!‰ÚõÙ¦ª ƒÅZ,ÖÂÀfÊlRr½½ßıØí/-7{f¾üÍßøõW¬ëñ¥ÅF·’®7¼J€9ý£6sÅuo¤àò1ÒV ¨”.Þ§|vefjü-3˜C…»o v²à½ ¾Jj_nõ{þ¨[æ-°¤Á'êo=Ю§ CÐ�z—]œë _õ¹¸º¼`Þ)¤*éâõ› ñ¿ƒ rý _õï÷}]8C`¼¦¡DÏoÌ'KŽ`"�¸P¡F0ï|ׯàí?öž‡küaY–Ôo£2@OàÅúŸR›Ðd¢Ð/zB ó²ºVý¥P¥Í- Ì•z"2”l'éËÅŸøo5R÷‡Óo¬•Ÿ•ä»V 3ž‹¨›ñÒø¨, ÷>~¸)Q�ŠŽéœ¦ 訧 å¾N¨€`(€Þ×W×ÚÛèÊaêô œèçƒ�Ñ9¯:ºV¨¨o_�ʃ;Ww7üHÉh×à?�ALŠõÏ^漕ú÷rÜã~ë�ºÅJºÞ‚ fLÇ$¢ÃU?JL²¼¥>4´�M‡d”7·‡²$ªåÿ#ÐKÅ3“f¹BõJ,�˜ù0�ŠÕP&I _)õÝÚoJâEª‡ggŒI9“…üójú•EäÌtÔ‚ÿ”øk¨öß@À“åIOк:¾NVÔÁDõ8Ó}Z .Œ¯lgˆñF"SާHÏ ©ŸÒÉì¨åä·Ë·¥|u¼×A.i¹)¤úõ½çáÃÍ<®×Þ�JÆd\é<Ó"öæg9ÝM’ÅÝjí¯o?ç\jòVº?ÁÝ_ú…÷üû_ð…_ôèÀù7Ii©£?oåù6æV<˜•ÇŒ3f̘1ã¡�I˜1cÆŒ3fÌxHB´ l؇1a8)$IN A` Á.€9ãêêÒ°_×ÃåûÞû_Î6Ó2ÐBj+‘b•yŸ`ÿs_k`­©(£®Eq!ý^WVeR§?_k" Ü¤J¼‘ÙìTaozEWrà…Gu}Óéûúg<çúõ@K”lu¯z¹~ÇÙ–ÍU”Ç5Ʀï¿ê�_‘úISÅûžh�b“7øW£H€Áb` ¤+­ ˜ØFïÉ{UÀ­€Vþñï?Ô ºVÐc;’â×Ûݵώʾ>ê ô€»ÍõÕª]âŽÚ¼—Щ¶íøüæüQU£ªœO"”Oqg<v§¥ê{{ü·Ùg´íÆû)Ö:Ïé\¸¥ü‘@½àúÀ}ZדÐïÜ\[)OE k Ч$3ÌѤúÐÙWNÕ·EuªºÞ¦’¶# ¿ùœ;tit\B7%\üî½{°–:ï§ÂH'Kj—à¿(@¸˜[µÜ7³bÕyµ²‹trEûXšìÔŽÒæ…@Vý5©sˆ®Ú.Ÿ ªŠí¬@/éxeGÖþïÒ*iD<\•Ómݵ%…’x ´ä‘R}¿!2Uåúy¤H•W£zngC †RCäD ûFÎÇøÿtÊv£êâÛ9G�ÚZzÎåˆIÏžÔý±Œsu]%^ÓJNº.œ™0â*uÚ‚*e…Þ Tõ„Þ:1 lHɾUý­ĨÖýŠyeGV¶/¡£_ÕYµêµ| –�$ÿûUÿåõ§ë, õšYå šTLÙ¶2 mv,,¶-Âê§DÃqª�_Ž�¶]¯ï?÷o¼÷7~õ¯~îçáÀ18çóøYHç‚5”?ó͘1cÆŒ3Ù˜€3f̘1cÆŒ‡$˜]¨¤Éžð†<ÀX2v«/Ç&€X`ˆ°X6Ø)øþ2îܹ2DXsñôSO}�>—ßG•ìåª*þ AÆožQ�'Ù®d§’ä JQÒÿõ›Þ€ÒÕþR€H§nñz]!³-Á^EÃÔ¯©ÿL'å¶Ûí½îá‹sDP¤.â’\ô9P¿íûW߯iV×oj €7¼áËcDïÐ@DHʪÚ*x‡‚L Œ#`1Àª”|)–'8,¼O¬±Ü€È€°ÿ³àì¬VÁßú–ÄûÞÿ‘ÕØŽ@¹1¦lýj½ÝPï<ûÆ›¹~¤rÖõÄówüãíHÎS¾P)O~ªÏåCžªfoæš,SÓbHù#Z�Tm#QÎ]�+¿‹{9ÿSc¼ûˆÆžó Ã-$ñ m>,=î fxErnN_kùk]‘_Êãk"GV Q$4‰•„N¹¹ªä¯»Ež+뤩*@¦º~º;ò-)u…’’6xêJI9Ї9ØX‹{wS(�îÏÈ«B‘'·sêKÊÇœ e~ ¹Ú‚™ÃØ(L}ú�;þšb8¨h�šnVÌÂZi?ŒCÎTC5?·j Å"¼¢3Ÿ™7ô€+‰�uºL\ýo�ì}¯C&,스›£ �ˆTA�’$CJúŸÈWHõ¡Z©ÔDç�ÿ%¦©Õ8ꃵ„ é¶E= 7�Ðûy3áó¥t=ÕÓéüY“ÓJÉø² žŠ÷�dQtŸ(ŸB9ÆO¦×‘ÕGÈ+yª£vµ&jîÔkáî,ÅzÿD~$ÎR“òô:%òòÝ„‚Ü«çi弚uÑV[‰È‰•w¶àèLï-A° T®oú]t»ç6&æóGF1 µ¬ )-8ÁÕ/üÜ»ÿèç~þþ§"¸‘YãmÖÿûµ~ßC¦ùÌ6cÆŒ3fÌxtbf̘1cÆŒ3’`fpRˆ~ŒÖ,ùªhvÇã c†,~“m1´,°Æ€ƒùå¥',‹Ý?w}ÿ³ëó¥*ó(�,Ê'S•‚E�Ñ ¿èzãL�øM…"UR”H»S­ìÏÛs$<½½sÕÔÎÐh÷šïµ1ûÂí’i‰cŠr®ÕýBËÏêæÊ‰Îƒ b? œ~ýë¾ DËñ´•�CäàðZ[À8€Vû  F¦# Ø R_ÿ6ñ, `ˆÁG?þ þúßû¾GfÌ×ô±}�spÌ�g�³¶ªMz›ëúµœ­’ÞÓºî~8íÓ^Àæ¸ý¬6Û%ƒB €‚¤¿õ/´Üê`€ó>ÆÀŽ}å‘u ±`"_•‚á0 €E`HÀtÀÿó/~ ®¯�tñß²ªZšŒÚP6êõ¡Ç—)´||Ñ™%oåow*§èªÓAõzQý/�t‹1°5ð='Õ9JbJ1ž†>΃êüÍ«91åœQzÞñh;Kt^S{(KS¡?:Ôè…\~e¹’HÒQ2Ø IESD_oå=z8ᜬžnŽ­¬>�ïG“ÊŒ¯s•ö0·ÎþíMYkqï±Ç()Û Rc]´ ÄmŠÓK·]Ƴ¢ÎH lÉ ¤#µž�3˜CÕz§UöO€ì¥�º#([ÇHB5;üŸ  K- OÕš"Ì}V(µ–BŸšG©"Zôk¥‚D©&n´ŠµÌ}¡´Ð[ S°²c)®‚Êû‘2Çnª ´^è+�È­W6ôó†&§*Tͳ4Cùÿa ^ú’¡qºjzºR¿Ù°DȲï¢L“פê¿Ïc=ZØhµçñ ²ÿ%S¢bMÿãep•t¦-F’P ?T–7iœHŽ�ck P“ʵršÜ)YÎ(‚/^ÓX*ôfëÛõㆌq"Xä‰w½óGÿð[¿ù÷ÿ×"²°"^1Å‹¹ÊR,#é>²Ý�@¦ÀŒ3f̘ñHÅ$̘1cÆŒ3f<$á˜Õ¦¢)*@%€ÿÎ9_ÉGÖXØÅûŒ»`±ž dáXpq±‡%2Æ,»u=¾ÔÊä-°ª\,R”ÉîùGÿâö÷Mõ«®è�•sÕ–5.wë¤oj�¯'ÉoC*¡T¥�5(žåuO<Ú�ó¯åYGB�»�­“ÅjBÚ¨Ê` ·ÈÆ­Á—•À˜PqäkýÃ9Œÿ¨â«Ð,`VüÔ»~?üöw=úy €ÿͳ‘ ¤€ñAÈ'­à¡z…ˆtü>ô[ŽýÜŸB{!¢å~& ̤-.CQÆZºkÇ,—p–)öyw躳¨')Aé_�¨ò‡–™ïUº¢5íVùQª²pÚjŽ­'×鋃ˆêÆU¥½¾tj«õ¡•HºÀÿH‡[Êã&KˆÞ”–`笎SÔ£oõÙ�×x¥ÅýØc�¥ªsáÜ¿³ôWh^?²J±§[/]Ìïi$‰VÐ$!u,-£¿ÖCL&ͧ"š<ˆ�g¶ªjÎW[vêàA‘¨!�5ãZ´Z‚²IèåMIVHAùH(ì[ã:wH!íOèv¬êA@=wê±>r�«ýú£»Éѹi¨ Ê—ÒöCùÕ)J5¼I e¡µ”§l—:?x6M÷GŠšA|î�I ªëOMIñrÈÊÁZfôdP½C\’­�ŽªŸŽÖ†a<m®F«Àüw5÷»j…�‡"…$u¯â UdE²)a¨h/m3 ð?öÒiñL´˜�$+"B¶ªš*#�!žR=øšHÎ]g¨|âé§þȳÏ<ûß^\]> ¿×¿Bq¶= y»+@ÄÁ"&s%þ3cÆŒ3fÌxTbf̘1cÆŒ3’`öû8Æ¿pkAÆ@8v» yꫬ­]°ãv»vÈîa­õø) vËΑ1Ö.‡ÃáÉBF<ÊÌK-a™«¹ãŽ0Q–‰F|¿ŽD‹ª?“ÆsR¿µW¡TÖ®•»£ÔlZçMf)6”¥�5iðŸ¨ãõz»ŠûŽ=kçÍC¨I]A{�•Ô¨œq̳B’?½ˆà+ßø†ìßjzbܹ­‹�óFîœ@d `V€- nõç„“Äøþưãõ[ €aü'ÿåß|¤Çܨfv ¤Ôþè¨XzôÅð˪íTà„cF]áI}ðF!\¢úl½á}»¾I«T‚(‘¡%ã4ÙŠú·Üª3ÈbKCزA)À¹�ä7ZY{•äPDö¥ù�’ A·³YÈÏWÿ%B/aŸÿüêöÛ¨<ÏMÞJ‚“V¿hª�G*U¿� ½ @-tªÿi#wÁWêuÔ³hYé0ß»wÏŸ†¹q«hpc©PüðGCXTàÌ%q„YáðU‘䢿:•U°Ñ¢¥˜—“ >‡ Þvµ“Ýg£bÒÉjÈÀZÔ.¯Æ«Äœ$ ctµ®J|¢g±†—‚dÔ[HK¡)ÁÊšìQ‹å÷@Ë|T‘·ÕZ2ù@We«X�ÿ匮.NXØS¹nÔk/RDÌþp(׌Ï/üú ’Þ'”D ©Ÿ“¶tâB4Á²h’Š!›yò¶œÁx,5Ǫl´ôWྥ�D£SÞz:>i £>¯Ú£ »¡¨ânhLJÖŸ†æÄÛ€é˜VFxü‰ÇÁ’e™E·QÓŽcyù¨¤#E?‚º¿øÕ{w'Š^Ùãj ~ÒÏ,Ëþµ¥”ƒïŠR3 j6‘TØ%¿ [©mÉbVÔào`KµvœLÆ¥ÔËïZd¥ýsïb¥ ¯$vXXSàª<#-¡ÊeÈ&ðŸí#¤"|èCŽ€q ÇÔ¨S�ÝT}ê�*šÑBÏC€‚W9E[ŠjDž¾¦w‰¶#©žŒ` ‚d‡‘û‚¶Þ©1ÎYþAIÞ«~UßS¡íSXúô¨¶:‘rá�Þ—siÕ;¨` £¦ì ¦»M µu=©œÓL]խȽ£ÊûD~Ndé-»P™o{ÃCä„× m,NÏþÿöþ4Ú¶%½ ç±ÖÚûœsï{÷5™R¦R©ÌT‹D#ŒÕj0UØ l(„0MyàªQ®²]àr•E[ÃÆØ€).—q x „Ë[ØPFØ€ ($¡IH©ÌT“ÊLe¾|ïÞ{š½×Šˆ¯~D³¾hÖÞç>Éèéf|oœwO³÷Z±¢ß1ç7g6fÛš;§V•Z}éÉ“7~‹5æÏ ãxPD çÀŽˆ¡”•Ç÷Àz°ßñªÔ-zôèÑ£G�ç+T¯‚=zôèÑ£G�·F0»ü׃ÖÐJ/MJ¼Î¹õ+ès´ •&=hõ¡~ðí-%ë⛲0�°™6³cëûøjœýÓ:nIþ—õqÊdæŸuVoòóF]JÛ`Êê +m˜0W$ Â}*]ÎÅë©5£ ÞhâíäsU,ŸnQ:ó„Ü`Ëä!þ$39«y˜×5€‹~Ÿ9L·L‹5*ÞŠå-PuãYéTϿƗ �çl*Hßæx¢f[Vàü�}æ¿ÿ‡+�'®‹rŒ­Àñ©ñ%€ÄB»‚ÔQ\wÝÆガÅù̪šúkXo¢9)Ï—wü²_T2ðkR}ªGÇqÿå l¾ ݺï‘ä. º–Rš, ò‚ÜlÕçë¦Ü‰Õ}³ö4Êžw³²k‚Õæ´[l?\øâL¾ý¬_K{’:3?² d°X'ïµlÏúuU@ôÈ=¨ì²½9ÛJ–{d.ÁFÛr‚·'ojîû¸Ø_Èû²Pé ª ìÀÎ÷oNO'Ƶ µ€jiëUw©œ@´* åëjíjTƒÿ~þjÍéëç(fÞXÓÛ ÝâÐak^t_ÎDÏþ3³W'àÓû•- ˜jl…K9k?çÛþÞÿüUD´'R“RJZÑ ƒeÜ�¦tŽá¬ƒ sç\"ôèÑ£G�=ž�è =zôèÑ£G�o•`@)­ Àq¡”3ÃX“exQ8ÄQPÚQøð‡}J+ˆ>ññ�½²yOᵬñêA�*¥¬„WOaÎ2ádF¦"òe¬»:Ü'*ïEk–ñ)³ÔFö)m€“y®O–¸Ûð6ob:t>_'¯ìÆò»lu�â2"LÚOkyrÉÒcxã„2ÊÿÀ;?㸼|˜Ô'�õ„S­^º )t¯@p(ö$_IÊÊŸZ*=À)^@uf0Üz˜îÿÞø'q{{žåùMM²Î–½qÍ Y÷Y–b–=&râ6äëËÞÏÔòjŒFÒ(gÃ+ËþçÍQ@÷%­ñ²ÞŸD&1‰ù©}ÍgRG#S>yÄËþuÀåŠmû޼Þx{¤S/ÇQÙ*tâ‘x#W¾_¥²A[ÅÁ'XËlÙ\fúôØÌ繓= ˤ öíW¼ÔÆ+Ϭ�õÏ,0VE&jÚ-Xv;Ó˜Û�(·xXÿâ‹/z°-ÌÙe]Ź÷¤#y¡ÄÙTø]°ôÂ^_²*ã¨Ì»›¹="ˆNe£s6AdYÂQɤô™—õ*T‚Î=û¶º % Û�GçûfX·(lx8í#Ä8 •À&kŸe¶´$;rfWê,2À‰«9*sDÏß‚W·ø$^A‡Y€{r÷E((Ê0Ê}U‹ôRÚ†”’øb<6,Öo‚’M¿Tíת¡!+Ïkö{™�ž:[ÞsLø~‹d“ ÖœRñ¥%5ŸÖ1ª9¯xŽÆj]m83�–b Z÷c¡_åK‰T䪎ÅÚÕ¾¨°þÉÚN®c‚¤[‰{ R/7vyºmÌ>ŒŠø±­|ÃÅçª#N¬Ô9aŒî¯yäxƒürÆ…Ê•¼±ÜÈ·¿ñÆë¿I+ý?i­¥hàœs–ˆ`�`ál¸j À=ßûë=zôèÑãS9: G�=zôèÑã­ä�ØqÐ˜Æ ã´”Q)‹.z7j¥0Œô0@éJÅÃ{ï#(9ussópë†þÇÁÇJì·È4Œ-E¦O,·R*BgÀ–PX¯Jmùÿ{Ôa¼ñ½`ÆBn¿)¸ÙèüuùÊ{:a´}gʉ Ô±¸”5—ð•�x^× _øùŸÈ%’ïâÈ”¢È?È% ݤ"ž=‘âý¬AÊNAa€Ó`’_³?yupà¾åoþ}üOÿó·…gáçvàÛ@ðI]‡²ª\ÉYÂ˹45Ó³{*·G3ò±^:|lJßS °idªú_c€¬l‡dQRBVTŒÙÔßOȲ—¥­‡\yšè´’¢'75 ³âÜä!H™û¦äý=ÎÊÁ•¬º "Tòÿù|_Ï“©ó$€V)d»ÔíN8©œ*¾èÜ87µÆõ„6'Ê–G·¼qÙ«×ke$¢†uøFÖvâù8…uÂþâÓn8”26ÒPÛãµI´ k-75ökíHPb�>µ¥{ Q*<¨7W®„·G‚ ‚Þ÷›£*yê¤âÎIªÜ‰zž‘öD–;TšppÕGà½ý¼¼™ ¼¥r•7HnšÎîZà?7çÊí =Á�Ú&�Ðö387Éóóé}ÓÆÖŠáŠ6&tiÚ!èMlÎî¹ZmWXŒœÝè5¸9¹„7G彑{Ï3Áﶸ9kKÙÿšÀíõ0î3I~b(žUù• oô˲M·7Â9îß–îXUÊ„rAÙC7ÆeÃqëd‡x3ûÐmÂ’hè‚ÀÌ÷üQÑ?±Ìǯø�ô=ŸýE?ë‹¿G)50DžaçN\Þ¨þÐ =zôèÑ£ÇóÝ G�=zôèÑã-$WAªq Äa1Ž#¦qÄ8NÃÏã4ah¥¡µJ>Î9ÌfÀÄÌt8®Ú7Äzx—ds•Šƒð$o»‚ øg'~F.Å%'ÕÆõ³M!ùŸ¥ÖšºÅûųÈGLÁ•Ät^åw÷ËÉ?#4š¿‡órå’Øçï»užŸI Wj)Ê–IwÒ>àgþÌ/ ?kT–©µB)’$þá-V»€øŠ²�µç¦�‚¢¤ÿþ`1À€e<¹¾Á¿÷‡ÿÄó>èx[�Òª› ¦ Ù°ÐÏà­tº‡nʶgv…íÀ©GÚ*Ø’'–}5KnPUwk¿'1ž6ÚWEã{HCs& Ï… ±|Òˆ©„àÏùÝŸÛhÕ�µ}.CÍÕ\“ϯ@™áŒg)�ð§þ_* Sý1³¤)Àà\¨äª×5" ­Кy©·$¤ù̸Ùhß•o¡ðèÅGB9cÛî…h{�k–‚7 Öh«,«Z¬ÇT¸ßT6äiI¦u}>Ûy«JÈzaQªÓ3ßcyM²ægL2û€TP)*ž³rÊúc>GF™uû#WHùWó˜P::g£‘l€ü¿ÏäÆ÷«Îû�XÑv”ï+A¥µj��òqaƒ#ëEÎ� ŸYíåëÅ¿÷*õ›Ÿ�Öí*Õ_(È«b£—í÷6À>½T¬Å©ä³[»@ìÃØåv™uB{¦È¬xrîec„„j†ci#Ð\^O>[¦°!]Š áfä÷)¥ýs‡´Í1UOãù8rülà¶o’ë?Ÿ}™ŠÚ‰¾{žì©øCïÿõZëK¥¼ €·–ügÌø™LIâˆv&ýóx�=zôèñxDÝïÃxmX‡ÔW�c>¢ œË6S¡‚!²àóëð:—µ2¹¹QòÖCHU‚Bžþt à<øO {’b¨’ߥâ7”Z¡‘ý_Î÷ï^a›s:Ÿ[EfÓü|ªcF¦H�‹SF7gíÊB�`©‰qϼó3]”6ÚøLß~á…1 ƒP<);šèÇ,š˜ùìx[O…ÙÑFHÀ[5¹k!x{þ’RàÄ�Î*ú̽窴å©I:’2ï$úæª,”¤ú·ú&¡A:Xg Ztc[GE�3ªëßW{�f‡jðš0.·Çl½ÏÙ˜Vå³¥º‘¿Áék°¨—&�cõHkÏ›\º+»‘é¿Qý}Ê5’ÎÉhÜgÉ£{µ}ªHÓ?™¾Ø'·kX­oÊΛÛ䄾ïÊQW[oÈ~S™/ˆ={äË&Ä(¥ü‘Š~w~OœëœT¯æâšU¹ªÂ¡¹ÝN•6ÆRƒôwbáê3Å)ºä=¨Æ|ÿE©|ÌÛ›Û_>χ?zqyu @;ë256%>·eJPô¦WÇ=zôèÑ£Ç[4º@�=zôèÑ£ÇOqÄC­5ô@ E);�aÁ°«D=)(å39†aÄ ÿzœuXŒÁ|8âp8`63ÍËBóñxÕÎ #‘M#¢$<цÜ+‰ˆ­ÔÚüÙZgß2!ЫÄ ¼< /Þƒ³ì˜ÜË8= 噉å[<<Î¥„ï—ß?ÂF NÖȬŸõ.\e6‹Ä9ä)ˆÅW®ÚÎþ%Ê2;å�^«ý#Ù$Æû>û}€&h]fyÊû¯éXTåc©¾T=“J À�ð­ßñ}øæ¿ú·žïqŸ1j�=÷¥•ã#ïdíëÉ×ÈLíû«T´óO«ë“ïÿJwÞñ2�êú®q¼º˜±È2Ë�,LTD ö@E%ÁQ�ñòqy�çÚÕÐ"K”J Eæq陜Uã:îjn‡˜ÃÄ¿¸‡BC«Q‹·Ÿì g™ŠÛ«TsA»n6û‚œO2GöѪÌ~.ü  «Œûz6ŸëêëTÏ'kLÓˆ^x!Y¥TÙÿ,²š9Wn©9ùúVõ¼L1‚‹Žs.@Ñêe£�¹©ZŸ«ôdÿQzVº-bB àE5‚vÿËÕs¨íÙ²î�Ø/ÈöjÓjïyÂ:Ÿ(1n…}šÈèæ‚h(÷Íñ§{˜Ð²‹Ìíû¥ç6f'f8v^î;Ú5q!šÎíŠÎm™ª\|QÒ%Eù—Ü6žöÔºÆbà%EvžLSš¿óékQ£¯K•†v5s{n(U#¤"Õée;·0�«7—}(òì|Q7ÙÜ!æš´-çŸB“ŠTèß÷³Ñ₵ÀÅØ>•Õ.ëÎd¿3o�ÿ,¶å´9_TÕNùÄY{äŠDÔjl ôËyÒŽ Ýµ·wf÷dÌ4íÖw;g_ù;óüÅFœ8÷'¡§A¤¡¨Ã=zôèÑ£Çó] G�=zôèÑã§ ¨Bh­V©õ(×)Á¯�Õ�P ðïq`¶XÌŒãáˆÃáˆù8ÃY«˜™À¼æÒH<ð‡}éà,øI2çE)kÅ!›ÌÊ’¸~éÚy|ë=I€€eæÞúmÛ98çÀz� oêJ�àlfr^Îêæò§2µy­ÏÕ§¶T Щë“Peâ¥Ot¸&q£Î¨ëŒÖdÏèå­ÖfÙW*•˧@°¹Ç¸"ï…M `o°,ü¾?øÇ×>ð|NkM5'¤ ?’jÀ½ aK´ä„7ñéDÇ�{5»ãµY¢\Ìl 3@ hÓöõ¸™éЧàl"Ë3"³±±]u«ûª¼ÀD[ ½Áµ�×±\̃2˲òþ� )m÷‹tEC*ö™dL²Ò«ÊBs*kf”ʹꄢo“Oò÷Ê碰|F{|ƒoV‚÷iîÞœ‚Eö¿LÇ)±ƒû˜-·À<>£~°>ÓË/¿(ÛÒ‡;Ïþç²ï×—^ö2ƒx}¶P‘Ž‹q„ÂAev9Ù­J{…­Ú�¡Qˆ =„­ù'S@¨ÇcìCÙZJ'&® û͉)÷¹2íÌ5èÊ¢|Ä+‚cöt9>ƒÇ6­êI¼¶ñª^ÒZæÅœwv äÍÞ}Ä©;kB„¸—ΔÍ]çäÇóq¿ÑH› ño*I@²–ˆ°”¤'*ÄP ;¤¨óÒéÔbšï=K¢ë-œ¤b É›àŒ$'ÇeõYH퓜1Ä‘Ðlβ㙋½s! ³î?$)8–ÿw\¬Á´I¸] !5Ô;‡1Ôœn(¯w¹õÝêC´jQ´”2hs½áöDÁu�ȼ½‘*–½µ}é̘>÷çjnmŒ—×^ûøÿÀí¬œsÊ9ër5ŸbËw@�=zôèñóé‡L6–3¹ÿ5ÃfÅîËCËì–uH æ”̯âA ùñêùЀÿ¸�¼Úb…¬Û3¶Ü¾¸–…NÀ%Ûygné‡)µ¾ö½ïyOþ2åɹ€7)\è&A~"s:°ˆV´D èiÛY•E€]�TÿÔñ_âÇ>òñç~0ÖÂ9‡²SIš’Ü4Wê³²c�ô–íŽÀW‚¸TÛŠûA€›ý½9ZݤV}41{jÞ»SŘ,IùŸW«>ò®‚Ã\~åXJmÕ.ãFžhè�ž¯2;ˆðoõ MK“æätJUzã—T&sgí²‚XH„&ÎÞC9�k«…šìTOÂRš$:É�>ÄBž�°¡:qªoý6'7¬ý5¹¬ñž^À´ßƒ�k¦ì ÉvˆëS«™Éks¬ñ*ÕÞè)sŸêõ†ïëÎ��_ª½Ù©ö5¿çî(PÇ(c²q+µ¼9íR=o¬ÑØÚ5Èõµ1§*±G0TpɆ‚2!úälX‡¬·+æ>Îf¾OO¥²¢Âhܘd¸èƒ90Jí[´Nl—ÔFûz"ÕªÔQõïØ iv–*,ܰ†ŠD…‹D0ÍU€Ûz$ &‹õ3›÷DÛJü½\ù2àh¨µpð¯@õ‘ìRö÷œ¸æ¡>Á@Èk¶mÀê¶Ÿú©ÊÉñ•Úg`*W”eÆïvý´ž�Öûµ€˜ê)Ñ`ÔÜéþWÚ"„¹Md4×bêk–-3 bË=»åT”•D²Q®ˆðʶ”6'²}Åóó‰ ÔÀG/¿ìÁ®†Äµ€õâl]evJ}žµN!üå±éC�rmŽÏD²u¤íuI\íW�WÊÈ{IøÅVû‹{ù¸ ÀË•L¨96%`ÇœKÚmõâ˜Å,�3Î/2�5qâ,G€ßšqh‘”vÀ”íQÚÓóŠ—}`íZ-òúù} ¹ì5™4|öèR5¢œ!â>‘Úñ„�9¤î‚´µã£zÎÚ*f9©Òo]3›=Zª¬s+­Š à¢/!ãÜPõL”)TÈ놎˽­»¹6ð�†�‰hÇHö+Û› …ʯë‰/¾M�Ûÿ7· ‰Òबlç%ècÙ) pnܸEx–§{«¶Ô¨¼À•ë�\zê¹›PË‘·Þ³®N¹"Â}@Ôz AþW0 7—˪¼òÊ«¾L¸ÜÈz.¨wX(¬œj±Fõ J¸ ó­Fí_ŸÉBÇâÐé qä`9G¥!l�u´1®VWó¬O à¶��Í™$<7PJê"œeç’óœëMäŠ ‰â°¥´¼ÅlßoÎ-u�=Ï–òB"GˆÑR‚Õ™ÅÏÆ|^eVv¹sƒ¢BBEH93޶waëJ‘ÍÊÅÒ#ëÅT¶¢e�›²Ò‰êzC.KC¯NúÔjчŠúËÈ·²Ý9ÏÒO¥P”:€‚˜WÎ{¥•Öçl‚ÿUÅçsa­²–S–wí…y‹—$1®Ø�l¸IX¯ë}7� qVJíB^ŠCÁxXNòµ¡�þ"¤øe†»ªK€'‡ Š`Ad(žIÊ‚g¦LÂ:¹åUz:Nú S«>¿�‡ê’”PJܳ§’ÉKEàFüÌw½ Ì€c ²ÖD^’ÙŸ­3œ"�ãUÆ?XD„)"1‹(U¥ÃA)‚³jí`¶øæëñ�ýHj÷ç5˜&ª$´†O3Z`a æ=ã©-g÷ˆç  ŸïÖ­¿1‰¾È§T4rÀzÿRE€’¤»ì»k69Ò¸%â ¡O�e žyXùþs’¸ïdp¦mN]�h[5@Tç½}ϳÚy¶rErXÛñ;·Kˆ¯ 0�`ç¹ù« ‹”Dá¦þF�ËþA[ ²¬¾i•Ã)WÂ�&öÏùà…°ÛíÀΓœ¸�.§BC¥YãIÕ‚ÛöAb=Ë$ .ÒfWl©œëM�¶õ4[šèȽÆ×�*ûxb‚ƒËÇ/KIx¡””‚ò‰²$+Jßqnsc]öºpP-¿^0JË$Ù§ku©pPy¦£‘}Ìè-ûgµÖ‹LvÑg%Á¡d®>õ5ÁŒ3›„‚ôÃu‰ãßUé%Ï\Ñ|j{ºc; ˆ–¼†Rõ$¸*]4Ö‡¨€%/Z”�ö½ÎpÓX–€=tÂ~ƒn#ž�2sC=€¹’ùO$‡J6'¯+¹oð}'ï?µ’Uí×k•õs!¯À8o?ƒ{®½,->8ëûÙPjy—ÂØ6÷Øß°Î%õLÔ+½É=ëFæñ;�Ýo� cÌÏþîïü¶÷~ÎçÑ�5Ö8çŽÎ9çØ¦OJi_? ° |Ý=zôèÑ£Çs�УG�=zôèñ‰x€äØÁZ c ¬1°Î¦CÅqÃat<+÷™…ÎZXk`ÌcMä”ù��É'3o G×0»Ìü¯ÁùÒ8ý5OÛ[½­3rÝ*ù_³þ>÷Tª”Y¤U©’söÿRi;»ÝVÕe�52këêt�üG&ïI…ÌõIEƒòzáï¥äÖEû¾÷=ï ‡€  ZÃ{_fŠœ(ø×3\Nð¯ý@%)w"f@iküa£sŒïþîïÇŸú/þÂó-ûОR8(=c¹Õ�72ë_mö”¤'ÔWåRÛþ~Qú,gþõâ.5kGüÈ� )õ_ã±n��ªbÚJ u†߯ñÚZ%­æËª¤Iª ÑÎàgªí\É (A d6zEn{�·õúL[ïß””–kL“ø$ß›K‚·æì)2|Kë‘ÆlÛ;´ »©�IÌê¥vëž ãˆG/> `皙΅•˛ʹl Ïü/=ºCùØGç´ÜÅÅ£¤z’˯ŠAYg'b‘6¿QØ­ ’å˜ifs¡ ë9ôiy�Z�E�¢zMl+­J@¤Ì�c=Ù©Ðzÿ”å­MXª,P"qp«2Pà%A°¢R½~c$Õ”r!àM�¦¬ì�õ@’LÊ�½ÐªÎb«ýV­W.í!Yf¸Ç_ÆŒÿ–ßÓG*)TµEùï©P�Z ª…}= o¶ÉÖþ_ZFdËx4R‹+à¿T½'Õ« »i±Q(H5Ë8e¯§Æõøkê}?mÛ ¬„8ÚÞ–¸Æý*.@nÝà•6¶<¶€ÿój>-òí³öNíõJ™‡ÿè�üŠ÷}ÎÏø€snvÎYfçØ±E$O:OæUÄ`Å€{Î÷á=zôèѣǧXt@�=zôèÑ£Ç[$¢ß½sΆ/vpÎ[(v鎄ÿ'ÃÁ9k ,;XçU”Ö<í&Þï÷7ÙWyK­Ã[‘…šs€¡ö3β—Òß¹¬åJ¨+é _¤WåRÌ  &4$ò‹Û”0’<–+e�‹âm›¸VWG…D¶žùÄõˆÚÚ:kŒ‡´´<ˆÚYJÒó”Rø¬÷¼'ô oplO èµ1œR€skÞg" ]ÛEˆ$ÿL w‡;|Ýïý÷aKYüçm|pÎæ²Ü²®*=f®úqs �Rf/VôÉö�›êþ8å­^½¦Ñ 7I€”Ôn]4boœ²øI€Šq¶’ù\¤nJô¶›aÑEEðÖkϧ2Vã’šY¥Õk²Rñú�1Þl¿4™Ð鞘‘OK•Zz Ûrô%ç#WVÉ3‡[yð|ÿJnãÿg§IÞž±×_PsAfÂVº¢¡^yõÕй\ÀS ŠIEƒþà•ÚGkEZ!R–h YótO*öå:ÞÞ›€6À>Ú®e©B,ûzÝ—HìhV\¾¡ìÀNçXì�ƒòY�rêLN–8„\J¾¡Q—¥À9—ØÙ˜–IÕ¹êEÖ+AŠÖ¹-›£e 8®;u" "‘¦Ê}Kæ[-ˆ×¬xÚ˜{ æ]a—"É刪»:gj%iY*OT’N”«L1{JÓù�нc¶0¬u˜úa>lsE‹’¼Q�^åþWX’«S WR )£]*$1Ÿdõ•#¥&Ÿ²½)÷‘áT "±~é̺ë�³5­(¯˜,˜OÏ­,Xtæ3Ñ©µ€™…êÃöv…[óIüçjmm®ÑæƒåÜ/Y­y+¯Þü pOð½`t6ûZ¸Þáöæküq3J¾g´¨c®G�=zôèñüD'ôèÑ£G�=z¼EÂùçÂá¶8 %”Ò «�¥sÖYXÈáÀs·Û1÷ò˯¼þ¡ü ¿ Q�Ã¥À7²í«HÒá탢5ÁÞgÏ“ðÕͯøKúõù=²2 П2mù^Ï¥¹AˆY«…×ø (Ö'¡Ü|þæ_ «¶y×tY®®“3%¶¤ËËÚ¨Ùì½”dŒër'Yu"¼úÊ«˜v£¿Ÿµ¾ÿY~hb8 €–J+ ]7’:Ê“˜ ©çtú©,ø�þ“?�û±�­�ÿ¼ª0ÃZ›8S-O]gõò†üÞ)K‚Mæ.$$2®ëëÕ6ÅPÜ~ÍÆP�DŸ­÷�hûŒ€BJ;úÜ'QªÚµl' ÓÎpç̤™�¾A¨À=Ÿ»º£Æ·öUŽ„onOËtjBª&ßvmÊæŸ{â-¦”'ïÍ 89�P9í'.Ú¸õ$@)Æ×}Uò»y0êÑ£—1ê1YúHP,ç¬ÅµM­`攃ÙrŽdο @ðH_ðÝH­k牶mv/>å-Cõûå[°48ç Èú/-��gÿ¯ê@.‰ì™yEËY¬¬$ž‘6ú³l�hã7yÌË:¡ŒAÈÿ®r]öl«•|F|.EΫÔ$ÓhµSjͲã­m‰ íi¨=ÉpsdæÞô¨,WÚVÈHÛ›rÀR*—µÇº0\±¯¥¢ºe]å¤ÏÌf‚KÒk#Ó^lj™DFú†É<1e@°ÌþOÃyóF¶n{‘)_�J[.Ô¨5[ Å(¹Çß²;‘däûáÆ«©�"Ùž½Fkm«|”PJE‰ÙñrÎàíu6½«P àŒœI+¿’ZËqMKkíù˜ï;H} k?÷ûþáw|áçáÏþV‡¸õK}‰Wz'ôèÑ£G�Ï_twŸ=zôèÑ£G�·H¸àGßcÜ Jå_p™ØYXkᬃu6Ɉª�°ßíÜ£G�Üg¼ë]Ÿ¤ø~òØ1Û(O,¯�û¶²&kU}AL¨äS…Ì­üŠƒUv.ÈÂæ0·"òå×k=èX¡N9Àß°yJWgmŠ OQ®ìPõ4ú“Eùô2ã²$.P�œ9­ÊL3pñ½,C#,Aˆ¼ÚÛ@Î;Þñi  ‰@ƒFôKeë`Ù±lÈ: 7UÞ@TÜ”S�ª&9DÁË{ïÜoý¶ïÆ7þ…ÿf}þçüg W8†²l’nîu“L²Àe¿¤\©c[£çyà9ÛòúŠ´ýzq°¾ö‘í(€VªÈ@+F^Ž�ò7™B@6QºvYÒ4ü7dßKu)7žê¸žh×ò´<›E©ç”óõ}ªò‰™‹(Ÿ·îTÙ¸oõOY—kff‹´AÍ'çæLÎíz¢ªã¯í"§H:×Oå¸â:•³²—¸ººJ+ª+Æ"D¿#¾á{æ•þJé~ª‘”¿o¶Mµ­k÷ÉÖ%´¥ÿ³ë"W3`Î8&tªïTíëë9‚�Î:!w^þë8ïCéùÊ9N4:å[d>æ1\pLâœÊÎyï!�¾gØ` Öõ—°lRPŠ ¥½Œ _^�g%|Vm^ôKÿ�ØGeõ"·ç|9T(³Ž87¸‘!¸3쇺Ë|ë‹ù¡9·‘ØÇˆ~¬Vúµ kv¼l+Ib[ÇJñŽJÃ+xxe.Ÿ%�ƒÿOäðcÔïG•,#j+€uüPMÊ åŽŸØY8”½Âóøñ‘¸-ðßÏ#œ@çuDÃ'B¨vñ‰%&³OXûÿ½é³î(-òG¡²\@snÛÚT´×:®æu>Á\ûÏëÓp±>1P(¿Ÿ±²½�hGÎïÏbœ£\8¿qþù-¯­�ÿøG©ÒjRJ�Ji¥•†RZ|~¢gßSôèÑ£G�=~ZD'ôèÑ£G�=z¼E‚«,# à· ¸Nà¿sÖÌÆ`±K�J+ Äiœððê�ù‚ÏÿÂO–ò¿9ðÕö¨®ÔÈÓ�U”«¾ 2„.ñàHÙL«Þ©¸>Ò¡8E"€Z³Óa«R� á™óêpu‡ÿe5œöݾp™…E ‡¦×«¸qq8Xõ�¸[ik�ÓgÊH�÷ß¿óïô‡é¤}ÓP:(Ö1[ÀùÃuÀe:åñ_T´\•@� ‡è^!àÉÓ|Ýïùýéö¹Íü¥ýv?YûxË›·lÆÓ�ýÚ‰¸èN}1“1§5pãº\ž=Ÿ&Çœ žÈ1ÆÕ\XÎmCÖÍåØákf½ °�Úéß ¨ŽÏžÉ17ÚŠ ²E=½Þ³ç 9+µ®sz®Ë*%ÕI³ôt¿+n—ìÄÛ™3Àƒ›Ê3Ô !ANäR÷5WÒÖë® p-.»~1÷Ê¿‰òÅ{〗^~9ó¬Ä6Ñ{$¯Òú©Â:‡Ìݵ#©Šò”jhgë¨lS•‘ H€…iL58z-ÂXn*PÏJ\É›ó½ú*—èoªsWá;!]-.Ððq¨†4o™ˆË>�›R¤¬vÑV?ú(Mßš6àí{®]‘ŠýŒª,•ˆ¨íµÊáªq½Ö•“ã®ùUŽ–â7tê¯÷�ÄŽŠ× ó6´Ê}NöM•‘·(Û¯ iü�9îôó°ÿá ‘Ìã¤2—PòHÄ�Æ*ªªR€*É$‚coÿrûz1Žh‹�%”3VÉV³q½<ä£ìäŠ@§Ö|^Ÿõć£FOÈ $ñs>³:ñ=Å V"%�x»92’$�¥�åe”6ÌmïÞš¸ $èEša”ë�’Í,¤´“ p5‡áøœMÂb¤ñŒíÅ 9sœ¾Ÿ˜sÚÞÜt¶ |âÅë"Î÷*4W˜G­Òê I*ោ‘‰ÜŽ¥Us,!{à4 å3¸_}åmPD¨x+™y¶Èæ—  3*¬ÁÅÚŒ 7Ià K€_füWÖ7i =[�CFòã°§ÈûH&_äÆÒ}úHlƒº”M.ÁÿÌUFf‰£æó”rôr9—YٕĨߔ¹œÚ˜ï÷,ÈýÜ©P¤H´¢�%_0ÒÔÅ M}*æÎøïSΠ•zr£{Ì ùsI’DkœrV_ ùÿ0—¯Kž$ ´÷ZTÌîiL@=›ïÎά¼Ž¹Ø÷øÏ®‘/ü<¤ª†ì@åRÄEGü¸—­­«8#¡m·‹P#É”CêW»B¡R™h(äîTeç§çåû‘9¥í¥AXìúJF,ê˜p Çö³œ›€Xªkqn³Ñtê ÚŠûó¶„ñ™±UîéO4̹e;„1Ëçÿȇ>ðï~Ïg?vìT6�"WiS�УG�=zÐ&Hl\ nP(7 `,ó,Žä… %è.`õû¥‚#ã¯ås€ƒ/µ6ëUûĹ+{l:Ýiè|-6æÔÓ€7P¨6ö¿1!—ÈéÖ½¸œ(ï1›�ùóqÂ#<›¼B]°{ƒÑ'®I¼ôò+ÇAdu iþâ~¹"� µ±'’4Po”“‹1Î!Ë{ÕЦUî[fwBçp%Ü£ú*íðx'±Âˆ=îÓÙà¡8)kÀÇ®æóqKÑhK?ƒ;-ñ{Bbs‘%}ÏnQöÕØ¤Ž]*4UL*J“¶œßPÈs7Î˹£Ú*põFIÜä3#£�é�=#Ußœ¯2:33âåjŸ‘¯u¾¿¹`Ï‘lü®^ÔÐRŠ%øŸúr&±oáÐÜûRª¦�lj}_�2E,¹¶³Ì§ü{*m§P�ÿQ¥‚[ÞÔž“’+åJ §}ã©Z‹òy�Aƒîñ™@4Ê5csiâêù¨škb»ÞoŒGR Q½ÅgÜCbà'²çås¤Ö$D?òCøêÏzßç|¿b¥c�jká¿îУG�=z<_Ñ =zôèÑ£G�?Ñþsù䡊À‚ÙÀ9 c –e�1–D Ã0`¿¿À²Gt0Öñ|qqù‘'O¿»ö­2õ¨@æ¢lÒ�R «¥@óiÓ5Å‘höW™�[e¤ÉL`x„xh]føçBÒœ^ãëN\“NH§¯Ë‘ìâ|›t´„8ÏžÛ¥œ?I¾Æ?½Y‘ J=;32ùþ“,€@•  )z–{·rìÖV§xXÒ¢@^«•}¾Z`É>‡B²žk`½/k_—* -áƒtg*�dö]¨V´Æ!(ßëK‹$?äóHnáÒ¦˜u[–A(ïD™:e~S¨��Z9¹h‡æÚ÷ÅDõÃõ Úøs¹÷Úü\ð“²íå3«ëåöææ+üi¿­g�[×PUÙ·õèÑ£G�=ž�è€=zôèÑ£G�̱™õ_âëbö?à�­s°ü7‹ÁbMÅô 0Žö»Ø9·Ì³1Ö<|ð£û¾Œ%X–«Ì àWôrø"…-Á#ûít&S”* @–áÌ-ªS×ú!ªî–�fjñ9·Iés¢†*Š�$ÎöÓìP—¥·:'¯U3ô¦ìvÛ 'lE¶€ó*cxk®¡*�Od÷Þÿ‘¸Ùeòµ`µ¨à,7±�Û¦v{sÕC¹xOND)ûÍÉ~®qyq�^|1Ëü°YûíÔX3N.ŸÔ^K%¢Æyû)Ÿ�¬Tí½ –ø%µD¤ÍOE )-H8s?È2v ¾GIrXAH„Ìÿ�†U]a•9û9låú¯p�¹¡ô'ZŸ¥~ÝÚ�¨ÊÌÎÞžÀÿ¤_Äb?âJcntA±ÿ!´å2(ßÀQ p™QNë¾hUŒp�Œ@~έˆ§GwN´Úwp´¶ÈäÞ)¯;Ùè>ó_ âK©ý‚¦T-tÏ)#Óä.¨%µßY�¹àa4æ›øŸqzÄ )ze¶¼.°ù½ZsZØD2v¢ÍXL¢tNâ*ûx@h»Ñss¬6É7,çûbµŸ¤ân¶î7…¦ê”_ƒ{îö.é…÷öÀgø륹tgÀq>þ“OŸ<¾zððá'Ð 8I(!Jž]=zôèÑ£G�ç(úòÞ£G�=zôèñ‰2#šÈKÿ§¯púfmÿ��±ÖXXãàC)…q1Nˆà¼8kæOûôw¼Ÿ³C½Õ/8Ü-Ü/J«–à×p™·ð)Nnb=Q8X ßÒ‚Œ�ä„Ydr�æv6yð²ôϤ�g ’,ÖÃèfj™nY¦už‘´mJ2Sªù¦õ;’5•õ¤Öoy8Yª—K�m¬«—WWëǃT Ji�RÐji´à3û�eXvÀþìàYÁªÁY$ª~Ï¿ýûñ‘�~l»Íž‹�ìÿ1Öf‡÷Õ‹˜3ßäUeC€_ë謲W¬¥1†ÊñÈœ«d´2 IK%ÈWŸùË�§ S=â³qHÅ[¶³íÑΧּReDÕÀábn“ êy¯Y½';2`¨q—*™¶þ"k”«Ú­†q£ƒm&FR üÏýªWÏõb9óôÒ¾áÙGu# ¸™‰ªN•ÏU¨�QÚ^‚6æÚg‹ýn‡—_y5\܉:”Yùܳë²Á.-IíÆäÏrª.dÉ=y°~¾|©}?/.j,­áI Ö¶D6K*ù¼–]‰”W6ª’ijA(¹õ:”+((¥ ÃÞE%ëõÊ®ÅÄh^\½~R½>s‘úO$•�êé1�ÿÙ#l•xÝãHõ97Aî—ä,G*¬Ó JtøRbσrkÃ¥ª“ßO¥zvÎ:XÇ^ÅF”9=oíèV… UÌ¿”íÙÿÅÂ�=³è\ÎY-{+m-]§–pÊÇlFt%b¥Ø³ó’ùE[2çÞ𜠸�9¶P_‰uš­ÒÖCX}PcŽÈ¬ <ç$µ7R�¢"f²hæë³$/4¬OšsHú åß‹‰›�M‹ÊÚƒsë´÷›¤Ùé8—pÉ·q%ë¬ëzí?Ÿ´¦™Ó…î³ÂŠz༘åSm[!\|÷w|ë/`æ‘ë(›D¤ 4�tœ?ûçñ=zôèÑãyŠNèÑ£G�=zôx‹„s.ËþOÒÿÀö6 Ïˤbíÿ¨‚�»”UZ-¤Ôáçý¼/ÿ‡Dd½Gªe>ñ8@ˆœæ”­åT\Ä|˜©(ˆ¶@±ndý¦ 5œg5œi†aÀ+¯¼ ®®=M ïÖœQÙø,¨St¡$éM©�]/ÃźvnNÛèÊÁ?šKA8E6uUµTøˆ·ë'#8|ݨ´_H;‰ ;Œœàp�мžO QÊ’J/–Ý\°Œ¼·¼è�EƒgsS€Ì÷LùžŒP:’B]Â÷5P f¡´û¢ „ g� 4`ÇTå —ô—}©ÐÂçl|2;_/åGARˆ_ñ=(Æ�PŽÊ›–kÌWì)·:¾¬·Ô�‹-'ŸèS+±�3"ÈæÜ#íⶬ5Ÿo¨fÉyÎñZ�+a¡èç�¼É ®TB lïõ#Aç9$·Y-@Êe3#søõ@§JæMtW‘mÓ 6veùÜÒí¢æ¤!Iµ5�ŸpŠÁ‘¯ ÔÜûÝã£GŠë§O~3f™Y3Ç­�‚"µŽß=zôèÑ£ÇsÝ G�=zôèÑã-D­u:Ø�Jx­z ß�´òÒë^§€u�sôàˆô윻{ôÒK¯ïv?|wwûÞÕIÓžZ2â•ïz^gþsæ �ŽÈ8øc7ð0J2ã(ÊÐŨJM¤\¡:z©s¼6gà"eBœÜ¬wyÇõyVŸÞXË÷«dÜ›ºÉ÷½©ýƒô"ß0Xx‘ §Ý˜Lå#OÓ8h Ç€†ó@†ÈZ–…€�c ¶v-�sp Àj †'|û?øNü¡?üÇž_ÙñLìÆ,©›æÖ²ù¡ö©ž!eûcVœláÍ®ûdw\$íZþÂ2CŽnÉØn•üŒózËâB8„0ÑfŬ£¸öìmÍ— w�j>‘~¢pÛ“¶¸S8?ÞÑ´x†•µ@´O(æ8i%!”ÀKé鈞$¿yÞ® jôèÕß¼ñØ´Q-esÑç¦OZï[’](Ùºä=ió:-ªµÆ«¯¾Šˆ“dž÷2û_\±‹™{•ÛæŒˆ%Ëš‚JP˜¡¥ÿ)·þÈ;šXKj"@ògé»�ý`›!‹�Àä,åVu!Ú ±q–�ކAÌ,_¯±‚¡\Y‰pÊþ§Æ\]¯žeÿ�;у˜OÌw$æjZAéÆ=£m¬ä-K ¹yÊ„‹²JRk¯eoÁìáØ�X¥¹¿Î–ŽAn[Ä¢(íéâ|ñÔ(ùO’4„¢?œ˜û�Ý“ ¨æ&jy„íJIŠHJ:T;‡Ä]"q`W1 ¢ IKªÛ3ã©^‚ݪÅ1'ØR­TBE?ȶœ+vqË×>Ωr]ŠåüRö3{9ƒÉÑв¡–Z�$Î0|ýËSË’ƒÖ{ ÷詞Äè&n’2[¿àû¬áÌ8Ï+¢³Û æF½T�W˜ðÐêøpŸá5Ïó—¼0X|�#›”£è>¯ôèÑ£G�=~ZD'ôèÑ£G�=z¼E‚™¡µN_É ʨ ËHÖÿëØ‹3Öº ù Xç`ŒÁ0i§iœ­³wÖ™ë‡/<øÞ»»›÷®7Dvr�”òÊ"à 9øŸ{odÅWæ¿âOàMm�ìÚM47S]QyõO ^y U¾­§kTxè2­$T‡ÏT“ÖÊp¿c´{eSG0&ü?÷ÿ~ö{pº¸¸„ÃJ´`è>ÒÚÐ`pN#�bš@p€R°äÀ |ä#Á¿ñoþcR?Çnüד²µˆ„;oã@ù”ÕøÚŸId”0ª0ëf1f(Œ¿À/³×h'Ò_�ê^+Áx ~ìõS ÃÀèY:eáïΉðÔ]<¼.ÙVs;;Yûj/çjÄ¢ð~F ,~ÓÍSúu.,)@…YÞünÌ/-R…|¯ZÎç!æ$ŽœLu ɯ“C:í ¾å°@¢4+1„ïÑ·Ê‹ý\Ðhøt34]”Â˯¼ŠarÒK"@CŠüTs72ÓYôGéé¼fÂ*QŸ´Ö� à³¾½}¡Ç#HÈFŸ^–ˆè1œ¢ªëdkx�Àg*re'ÑN\âÝ«/}ȰOö™ÚIž†-Û‚ï!—±ÙҼʕ¸oŸò�äåà�ʹ𕼠'|TV-ÍõRÌ=Íæ ‡vÔ¤V€—~Ï)31M¼D_¯¿¾?=BØ‹åýº–æ§“–m©.¤òÏÎ+TmŸVÕ„Æ|}ïùw#Û>‚ü‰ öXÉjÁm¬ ”MÏÍ�6fhÝŽ²ñËö!ÄÔ�ågïZ@ùs¬c½]œÞ$ˆbÿ�ƒÕ$ËÛn+�嶤¨°¸>5ÔÊŠÙd][Px9=D�4 ¼-yÓP6IS�¸�\T¸¡0pRhd“°)LP„³öÝ?øýßû™ïýì/¸0°Pþ£¤ÿ¬É°®ïÑ£G�=ž§è€=zôèÑ£G�·HxWµ²ÿU!ñ©Í†A¢“@äOÖ=`†Vä†QíÔ�5æé§ú;ÿþ�ìc_4²h‘öæ6þe*Ëú’Ù"”ɦrqˆ¼æ3µ²îV €²,Õ�Œžp�5;s•Éf‘¸‚‰ •pˆ¦”zæ ^̤n�2qMHד ïùîø�~MTA�Y½¼]¡'ïÎ>Sv#´/‹¬*ç�ütFÍÐ ÚY8 ^‹Ö80Ûz31d�ÛÛ;ü¶ßþoá�7‡¦{Áñ¯µιÐ�Åy¸|-—à?7Îns Š*“¿E/£Ð¦TöÍòzºŠ"“½�\Ù1È^Áy$õ�<Ûps0dÙÿÜè»Xû'�H/%wd€n®×i€�”ç‡çŠÄ§8j.8Í¿÷tÖQ ï6yýq‰ÿßãím­g®³U7zJý[n�À¨M‰Ä«bjNdùPE]òfÏå¼�DéÙ —$"¼úê«ØMSay°fy×\[rºU“•9—úáÊΉõzUåQA¾YùwAÞiøÞsµ& ÒAvCØÆ8än’$¤ªË'¢Ü^(ë‰õâJ2D¤*þþù(l†âÞˆ[ó" $+õW•AŽOÎÆ;7Û¬šq[¤£êÉŠI@*B”j ­ñSŒ.iµÝ{)íS8ô" TNRql¥>‘Í÷œ”8âz’‰È2²%'Éy.T$¤ô;esê*sÎhr³Š.Iž%XM ô?7à AV–‚ Ñ\“©Aó*·†b_¸¶Sní!pdF ÔšòLü¸n×`77Ø&\­}ë_X�x«Ú/vï\5JV¡[©–¢o‘.d_(Y}¹ ÂI©d#çÄ3Ü®ŠDܯ›þ+åª%yjí½Eû–aÞ˜Îì뫵–¶öüu|ôÇ>üï}ß| ‘ˆ""Rĵ[�=zôèÑãyˆNèÑ£G�=zôx‹„ÖÃ0`Д–¾çO΃#e~5´&�r_ñ'|ÆEv, ÜÑ“¯þ§~ÉßùîïúŽ;çÜÅ–TuÌsì20xÍü—ž�„ɹüð”“ælyÏxì%V׃aˆòs%á[äÀ€ŠSf3" àlÂh8|¤˜/~Î2î·AØ"oºYÃMaô{zªKIo>!IÎh猥£öâÐ?J|?yúÔ´&ÿ½Ž:×ÉòAC+l¼�ñéCÁ/ØŸÄ2[ü[¿ówãÞÿƒ©ÍžËHÒÿÖÚ¼�Æì<ªåê7�† d]³,yEï·{­Yî¥EÅfV[FÀf¿*�‚Í>(µi³àòø$³ó©Úswq-:1¶Ð–�Y–�óPë ¾~(û÷ü"Õ‹· ?t:C­jo¦Þo~(ç—Óó\ tò™aÁY–.£ÈP>7¦6ˉp*ÑJ™Å¼ñ 3�“s3)«¯¾ ÓnÊê8ùK72�e×Λ¶\ãÖjOð'×u)×è\b•Æ÷öAÁÇ9x¾3Ðò¼¨¾-í~¨Å0ãu¬0Û0×õ^ucön2ùúÎgz¹�^çù´ª4ú ß³çgü!¡ÞìáÍ¢—¤’r­ã¬\Ñz'ÿ±�H”£VmÁæŠ^ÿȨ°ý–ü¾[÷>,ÀhÙâ[¢"9éFÖö ¹¥@ú;倬 9õ¶Ý‚÷'ºPF:‘kV¾.­BWœ�g9×H’•~VÔÀ‹±ä¤*H±¶ˆ¯¼E0ãí¹,S©âü¯õ}ON¾ÕEXè–4¾dÐPmç•·B#×�Úû"fÞj‡R݈O¯{yŸy–½(·±1ŸHE”�µ˜Ï®ì�ÙêäŠ}â³ÅvÜÝÝ}9ß%ÝTÿ8Þ£G�=züŽ'�9€,Ó“Å�mÊÚg»>Ãp=¤¬A‹:Öƒb`: �‰ókòz03žˆVòܽ�œ-î-3­613Ÿþî둤Y:ŠT·ÓÁ\ä¡Ò–à·˜¶4Që2ËsγRÞâFa‡ 2m`Y–¢î8õ%R*e¶‘"€´ª8»zS3àýüíÿùï¤:yn#€üƘ ÎÏFÖWE!ª² [mJ'ÀÑÜXö_ p-ÝOÅ€9Õ¿«ñ{â•Ü–¨Ý_åT%ÿœ]'C¤é! t'ν¯OJ@G–u)ç§- ž6]£Ñ.í¶jÈÖPÊê´¡¼ž5 ¡™ÞR8Ë5h^…Û~Ïg®q¿¶$¬d1o��gâ„·½íí˜v;1~„Ú Ÿ¨%éUßz•Xó –š¨ÒÁ%±.øÊ;^ïK�H�4¨Ô–¥ÂVV+Ÿh�F«$YýX†Âû!u{jH‰o·5ˤ¬2ï+y@è(´Áÿð0IÊ‹ýÉqEmèL�:â¶­ �?¡¤qÞ(GF„eœ$ f{­ plÌ¡bžŒû1Ò–ŵÞ^�àÙ#p(Ë@rTrµÕ«*Ò×à­d½:K®žAäU H­tƒÜ‚a…(#ÎÇE†vk¼ÐÀŽr¸,Œ÷¨ Ã'I+§ÆXƒd? E r¶ãLb]<7–ÔÌl]šIbÔ6øŸg3SµÜ®ó7�Iʲ¤9g2ds\is¦‹—¶%Œ|ÎäýŽ$ ¾]HÃǾBœù½3—ëgd²œ„ÙîMR助q½v¡On—j>UûÁµ©Ãv-‰þ–Ÿ’\|ëÌnçMHšëë$% Ê•¸!sÂõ¶v]×e?izóP³› ö):ï ß�h –i:Ü´f¹Æ7«ªÚcQmÇ€ZÙŸ„äÎyûœ¸/f´ R’̼Umü,�¼Yˆ3Ÿ<Î~p8E¹pνó‡?øþw½çs>ÿ†ˆ¥ˆ’¥;X× =zôèÑ£Çó�УG�=zôèñ E2«ÞyŸVçÁc-¬µ`ç!)ÇOáDÙ  Ì˜ŠÈi­‡ý~wû+õ×þ­ô}ßû¯XkÆû&Iá]¢<;¹ÿ›2»É_~Cð»´ÑŸÖ[¸\æ{’<í-^f+WÙÆL $Í“ð‚Â@ÊÎ\I>Œ�*/ýË!ê®>,ä7Dp¤Ô¬•šZˆh&¢[GÜ‘¢[Rê8j=Ót»Ûí—Ý´Ÿ///—WÇËËýqÚ],WWoµnæùp4Öô ÍîâÂ>¸¼ä¨ýÅ%í÷;RJùyqXì‚e¶Xæ#‡#ŽÇf³ÀfE„q0Œ#=@)0;Ìó7wÜÝÞbžg€ZÇã0Aie Õì¬]Œ™�uÎYE ‘€ Àà�düa­…uÖX8¶@Xƒd?°ÖÁƒež1/3ÌbàØaF\]]ñK/½„—_~/¼ø"]\\B¬±úp¼Ó‡»»i>Ç×>þñG7w7/ÞÝÞ>˜�óÕ2Ïó2_-Ëre–åÊ,æá²Ì¬5Œñ_ÖÚ«r�Ùö3¾¿íŠR„W^}vü—•È–Rü•9µ@, <ë‚$éyòt/äà?‘‚Šë&ÕÄvN(¬+77”r®špþ¦<8‡h·@Z^¥äéþ¢•œçAYÊT=êFåbÁÉ×]®v“$²Ê„ûôãö”Öø%¥ëq"è!¨)µúeÄ”âA6€ÜSsa´yY[·’j¯xšTh¢4,U ºTÈC¸¨K¤ŒîÕ€“ Q{ï\�]J…œœ,Ãí}ÓF5Së=\ëõ™qΈþ(÷ÎØ ¬Š¥2�P <�…(É;’t!Û¯EfhçÛRXŒ²‘7:7ÝcQn)#lïG·6»|Â^¨š—$¹lRáá@t?e�µîÎldвÀ¡gܸœ¨Çgª±u7s�顊�üØ�|É{?÷ ~�ˆ4•l t@�=zôèñÝÍÍ�½¹¥ãííÝlÌrt3Â̳ù85ŽÖ0 Ø÷+kak c`­…cŽæÝq½pÚ9°òýGi†Âà€i0X†Î9Xk) βļ€aåÅÖ5F€4�+€C8f€¬Ï´.ëÏ sAUįQ l×,}çœW±I'bMZ)¥ˆ0ZvãåÃ>º¿¸øe§i5 #ÆÝÀÓ´Ç4î@DÚZ«Ž‡Ãp}ýtzúøÉøÆoì_ãµ—nonÍÇù%ëì ÎÙWœs/³s/YkYk1óÔ¢BÓ·Jk¼òò+Øí¦BŠ}µÈáÒ§œ$èO›«ÕI[…¸~¦�%ÿQ±(�¢«P+ã¿.Ëþ—D?d²ùíòPµžm½§ý¬³@è¥UZXÛÔJ'”ˆr6‘*Qú"3�ĵמ i�D<ÉJfîÓæ,´ÎÃ\?Pàg±ËÉGYv=sPjˆuI¹Âƒs¸—¼°ó`çÒ~&ÛcT»Ú°‘c€ê!B央V’$ÚÖ6-ÑôuïèÀIéIÌ%(/Ô Ö,ó•É‘,—h¾9ÛëÑJbã�Ç v¥@¹F'%”’ùù¾6ÛSn<“,µ€T°�Y¥üïe±ÃÁ~£¹9lLg´7J. g*5”­/÷b£Rc?Pñ3øÌ¾#osÙ'6·5 E1>ï4P§¹W¥{Œ;Y¯g?™ðfSm’oÎͱôfg_ww·?—€¿¨‰4TKÍ¢G�=zôèñ|D'ôèÑ£G�=z¼EÂ&9ö2„ìkl[\òSõÀ¬@�ÏþS@)�æãœ�¦iÂn¿›÷»‹›_ñ+å_ùþÑ?úK™Y…÷f’ªF¦0ƒyÍHN¿‹…Fž„\ËŽ®räþG®ŽÅ8°*8 ¡ œH{©[fü–ÿñÂïü]¿¶�Ã^ƒÙ«läP·U Š–ik6Pb”Ó1³Sàÿ¡kÑù>d$”DT(_˜À FK7ӮɅ]ÇyZÊö߉ÔQ+º!¥nê–®Á¸ð”�k¥ÔÓAO¦ýîéåÅÕÓ=ºyõÕWo?ã3>óæåW^�‰ÎYÌË‚ùxIJ,pÎYOP‹ÖÚh=X­5+¡%_~Çžpe½ê ³—wàAk‹i2à­sΙeqÖ™¥’µ–Œ]¼R 3ô0`¿ß“ÖOãä¸Ås8̆y1ÖË †ã4Ñ<ïAj�V ÎY˜ÅÀ ³Ì0f�uÎYA˜ c×V)(eÁ¬hk= †Ö_«Š@j‘f‚rŠ`™ÈÈ…>¦VŽ¡ýr²v,Rš3´ökàP¹®[?ôd4§Ñ>‘ˆÖ4­½¤Œòâõ ÍÎjkíÀÌä)@9 ÇžA e­!k�¶Öjf”Öúòê¡§½rÎ)¥5ív;}±¿Ð{=N“ÒZ OŸ<~áõ×^ûô››ëwÇwÎËüŽe™ß¶ÌËÛŒY^‘bô ñÊ+¯b‡0à(«óH”“+X®ÆsªÏ—ÙôÅë9ø/îÆŠ�§"Þ«Dàß9ÎAËü²¹wœWJùíLgãÙпë)R�Êçn±i­»ÀÊv‘`p• ,×´D'€]cO!¤þ!HLå勿L°¸·Êåu Ýüoô—íyµ% 3ùÅ^‹JBUÝ^öriMaa‹"È’kö;W{†;åÉDbã"Ÿk¤ÍKì3¥)=ç9Õ¾ÍWÖm‘=pΫ@¡C�D€&‰`ÕZXWBiïqªÝÖ=ß6PËÁn;¨hѵ·2ÎCÇyïÈžG* 4²ø«&(mNÀmG‚Ö>–8ß?si�‚Íy˜Ÿ%c¿œ˜ÃŒÎÖð½CƒpOB/?ûmd,óü…FÀ/ÑrŽåNèÑ£G�=ž«è€=zôèÑ£G�·HkÀŽH‰À.z2ŠÃôp˜¯àÀ ;íã´V R8�pÌPJ h=š‹Ë‹»¯øÊ¯úÀŸýú¯ÿ®O|üã?Ê“S)Kê3® ÒìЭhÖËþµQ޼ôЕ>ÎþøËq[º9É™€g¦ì{²–Å)åòùÞ@¡T;ȯ˜=“ÈœZ¿’üÁÉ »F(ßÃèuW&9�{f3‰ÃCç˜ß÷}ßçû‹s‰\sÁ”°p”µ`¥çU)þê_ûkøº¯û:˜� ÿ)1^—eí³ÉÒaU“¸ï)ê†Z±�ƒææ™6Qî‰}²¿ËwRAÔ)½†ù~Ê›Ï!<¤µRRêF)}£”ºÑJ]k­¯‡a¼ÑÃp£µ¾§éé4MO...ÞxøÂ£×_}õÕO^ì/î³›ç…ïînqwwË77·öp¸3Ƙ#€YëaÙï÷æÁƒ+÷ðá î…^àqšpœ� "8ë°,3–eñ€¾sÌÌN)å­Y)ã”Rê�d=:Ç0ÆÀXËAnŸ‰ÀÃ8¸‘Ffv¼ /ËÌf1Q"ŸæeÁpœ1M3œ³ àÁ̬‡ZkGDŽÎYffÃÇ£ÁtX0èC0 XçàŒ�µá+€ÿ.Y´„L{öcwY|¸5AFkßÊçñûŸ}V»V zPÐJ1Ø1»(;†c§B}�$‚ùeDÐ °òD  ë*ã¼&C3!¬A`g-ŽÇއ;ºŠ"ë1ƒÀ 0+f&f¦Lß±¯S"rÎ’q–œsÄðr1J)ÒJˆH+MZ†AéaTƒ  /¾øH¿ð‹£Òj7NÓþòòryy5�ãxqw{{õþïÿþÏøÈ‡ôK¬]~Óêé.²çQƒÿb…Ê“æyƒìí+2¹oª–‰Æ8!ýMAÈ!(ó�ʉz‰÷ Ì•ÅÏ \²H^¯V*€®V4!ÞÌ•¯Ôj@>“9©Ö霫Ä9YNf_KµA°#ñ ÒJ€T„(~$ZÖ³i;«^’>Ò{9w#'Wa'Õ� rIeAxó åm&­€ ýÍOg-³PzŠý'á²’ì„'ˆ\QüH8µJJµòd÷’Șç6€[V6Ó³Ú²­L¼¨Öäuö?oÔV¯«EÇ*Çß’íßj²Dµuį?µ„ó&»ä„jG£ú$øO…-G©Š°~vÉ똅BIiÅAÒ§§µ‡Oÿr»€eÿi3îül/–¡Õ «’Ÿà=O kÍg?}úøò¥—^RbÓ™úc�=zôèÑãù‰NèÑ£G�=zôx‹„Ï:õY•lYjQv@¿ºqÊ‹‡oŠZ ÐZãpœácЃ—yWƒôþfôë¿èŸú_ýù¿ð�ßðsäý¥Ü7 €<´æÜp´ð%mŒH¿ZAò”Íå³HÍ£ª€ÂëYüë79ù'9ñͳp‘B-�Ä2`5z¸ bÂ3œ­ççÆHI•%TPY…¼ÿæ}Ú‡þyög¸niUÜHJ„µOž<Á?øß�âç~±?Œ6D‰€` ÀD@Pø³ßð øà$éïçYþ?¶[ÌòΚ¿:A \·/J §h ‘i(ZeQtJÒ?Ge¥FçY�ÀdJ‘½V)}};ŒãÍ8Œ·Ã8^�Ãx=NÓãÝ~ÿd·Û?½ººº¹ººº~ñÅ—ž¼ôò+O�YÖÚÙZ;[ç;vlŽ[g³³,‘šµÖó03ˆEä†qà�Û+Rvš¦Å³8çŽJ©eG3èÁàÅÖˆ�Ï¢·ÖF Îz°Ü‘Ÿc(�BÖ¥uÖøluç ˜H†a„4ˆ­=ÙÅ9Ʋ̰Ɔë( Ó€Ýá€i𼢆sTô ¹u rŒyžq8ÌôÎм �sîmÁìRŸ‹@!;æþ¨ C©�µàI,þM“_†aÀ¨µ—ç­í¬…±÷´v•è´Ö>ƒŸ Z)¥@FA+_ÎH\‘@aÃ&ðy1Çãwwh­ÁŽ¡´†],œ±s¡\!$ÛAXŒñ¶8¡NµVÐzðc‚ZkŒãˆa1 †A€²–f�ã�3öÊ,öÒ,ó%WJ�w˼|±c÷Ï4­ ®X‹)*ÌsN#ªAôbÔçÓ®”�éBÐZÈ)ä`�Wú!¥Bæ¿\vKe�µM"q¡ÌZ憂}¾”7Wòj"âÍ®qÑÍú@Z#ÙI0Ÿ²5ÙÚ¹æÙ—_÷%`qµsMŒ*ÁÆì(Ëàm’ñ‚*F"W–¦JüÇF&3ÉÛrc2§Mû®ö­Õ„V hZ8qI^L�®Òµ9Ú#qÜ?¬:2eÆ7W¢�ž$uSi·ÐÚ �ÈçoíÙ˜‹2ˆ&^‹(öšEŸ­ïT¯ðQ¡#ví9Àa+UÛá$†P½IÄY�–ò6K†Ò[ã´Yω_Ps˜Çu.Ÿ…êÙ�6öвŸp°é`®y\JrT¥#±Ýå{UWYN–ã<ÛK�ù¼qr¾i“{6ßz¦©ß, ˆÃ~ÿ÷|Ñ—|ùW|„ȳyØy˜ëø�=zôèñ\E'ôèÑ£G�=z¼EbYX3;ý±ŽRAÚ?ø§ƒ);3|%€g1Ž`L“…Y,ØbÓ- _ûÕÿü¿ðÿý«ÿÝ_ù®'Oÿ,Á5s1 b‡{·‚Kð¸ßIT”ûEÄ—U©"`ë…lmæé*6·oË`½*D$QÒ¸6!¾W´3ÿ9O–,¤KW•uZ]žr´†jÿõtX.¾µ½éc8çAÑoøÆoÄñgÿ1,3ˆ*(çÿîïÿýøËù/¯ÀÀó®ʈÒð•ìþêAí$x#slÍ®MÿÒ*ÌÄù»·s@SŸ*NÞYŒRjÑÃp3ÃÍ4ín§i¼ÆñZ©áZ)z¢”~C)ýdœ¦§—Wž¾üò+O./¯ìÕÕ¥Ûï/Ün7™a ÃÌ ÀùLy‹a™Ý²˜q±ÆÎÖÚ€Ý;çœcç¬ÓÌÌ�@F{yþ…ˆ ˆœÖš­1Žïv;g|,.°M”RéËY—ì'"iÉZŸ5ÁÿÔß­ƒ³.ŸÏDæt$XgÁÎ�ÆÑ€ÖÚÎJÁ‹y^àm� ä_§4ÁZ?¯Íf†±Æg÷¥f-óqÆ�`-C) ÌÎÏ‹2“;¨ÂÄ1ë_èÄøtÊ�1pÖ"fë+M¡ü‚À�@î­h"`‰Jk(žtP«qéY"Xí¬ íBžØfL°Ì0˜GÜеWM0Ã0„6±p–i)ŽBHP uæœÃUØ Áî@§A¡Â:ÛŠ�;fž™yÇñÀ g�Á|œGc Ç·û¯¿~òø7BzÎkEŸ\økH‚žxc DÛö^/äÌ–'‹DÊ+2”@rá��«äÏ‘1H”�¨"lòÔï‹‹$¯óò)�TXXŸ¼umje¥§gqg½ÓËçZ‰‡ÅE d7÷{ M𠥟’ KfU,²¿å•â8ÕwˆÎH�ç„ÃÖNª¾.ç«JkŸT€ø�û*±2Q\#±,’ZÏ·!Ÿ(2äÇ>¼àH¹bo–�5nTê=hñŒÉ[‡›åc¡\µÕ@IâA6žâ^!‘jE�º°äÜÔÏ3|b{\îÁbωF'6ëx�ój ¼øJ 4Ûëä,ì"ÚšE¿ÉöG,TèTw+¨hªDe ñf‹†Û|*F±ÿ/ßóf…H?ëAcc¡ÈÂ.ž0ÏÆË­3„ãÑN_öó¿òOüµÿþ¿ù#ˆX¯ JQ%1^eôTÒäíCEyàFYÆP˜¢ç«Ê/%ÀJE~N#ë*¿;5‘RâÕ··Êè‹/r P´yä˜?S�µÕdQ“&jE!o\D’é-ÿ¾jínö­Œ P¿€ ¿å¯ÿu|à?€÷}ö{}Æ¿ï`k0û€ßù»~>ô¡‰â?§à¿ô(Àp£Ãå�­Â„g²xíšš÷–í VÊ3ACv¤"š‡a¸Ñzx< úZëñZ�ÃÓÝ´{²ÛïŸì/ö�ˆ`³c›h>S5�YàË£µŸõà ~<ør¬$ «”U�ö.ž,`qœg¯:À g-v»ˆ`¡­˜<Ù(’"aÀ: kLPðÏ¡´Â0 ž´Ä ­4ô Ä3¬¶ _|¨ˆh""Íàñúæúá÷Ï?ü·�Çã/.gÅ”.ó{8µ·A´h-î&ïÕZ{hõ�W !0ö räçò ëi.®ÆËÆâ‚’¨ÀìÎVï,“\’8æ\”+qØP'Œó}מ«a˧¼õ^Î]ÒåpüOs|#û?e¬ËŒo®[!½�(“Á/¥’𾇧zy¡˜y�æW[PâÉÄÒÅçà\~(í$~®AúB†_�ØGÁb§TÛh=›è%Y‚u­RåÇk£LÅÀ�ÊTŒÙœ žõTý«¼pX2¢!YeE•«L ?Õ‰±Òð›Èú6¯*ïYËŠq]î©7%HŒ—Æ9a»úÊ™„ÎM ¥mžE̓Ö,ýó³^cnËMYÊ®ü,ÀûGÞ|çÖg‡û>œ¹UóFÇãáó•ÖŠÄÖ+QÈ=U�=zôèÑãùˆNèÑ£G�=zôx‹„s!+•¤5´& ÀÝ4aŒà†s^žÚ®@dÌ€%”†ÖÆÁcnoüô¨”¶Çã<~õ/ú¥÷ïý�¿ý·_ý“_ É·äÿ3@²8 ¯ÓêPH«®‡æÌ$^7Ip†r’ë–—:¨Á[Yò» ËNá_¦â:Ø D—{V� ïSqüg>[V”õÙúuVü„qVu¡©P´‘ÌF;îðþí¿ ú?ÿ“xéå—¡CŸR o¼ñþäŸúSøÆoüFcD‘ŸßÌÿX½Öñ þËJlX*È6¯9k¿Ú¥‰È(­o”Ö�µRO‡axª‡áé´Û=Ùï÷O¯.¯ž¼øèÅÇŸþéïøÄg½÷=û§}úc€Œ]¬½;ùîîŽçåc�ØaqìfÌ`Ì·‡;£•¶nr>éoh¥x˜F¾pΘ…�1ì¬ãy>²µË2#õ`fvÓÎ)­Øw+â`/Kî lg�Óz`N±ũÔäOLŠ â!,¤±£* ¥Lbn› œbSæº –(²Oæ>é”͹¾�. ¸ôL‡W¾XUWTÈŠ' £'[i­‚Ü=Ã, Š ·Ð×ÞŠ@¬q˜�3œ5pÎ$—…Ï’_ô ®£”ÿ*ŸÉ°”ãСlHˆ¬³PzÍ>»ß¹è†!Æà�ùH¼š��± Œ5pv }œ¡8dþ+‚s ì  GÄ,f¥U˜ú­èÇQ¹†À¬0è!Õ©*’TÃÎb&(ÒažRPÊ©äXçâDÆZÏܦ�¶�û`ÑèÞÊØ‡œ[xͬ'Îm³�©ê+Í�U¿«2æÏ(äË)€ªùûŒN†´q:%ðÐLÔ§ÆÇ’¶íÆI›ˆûŠ6'çt¾_w^–åsµ43+€É9Çþ³¥éÈ{ôèÑ£G�ç(: G�=zôèÑã­ñÀ,Iú« ç?`œ¦Ä8`1 ¨�íÑ"À“ü Ï‹/<‚Ò ã0��Ó'OÜÓ§×ÎX˜e6×ÇùøÆ—ýÂ_ôŸþÕoþ¦Ò1ö+�AuÆl){Ì\%I,” ¯×tD(¥’ Ö,Q­)“‘nVPxóÖòƈ·ˆ¾»"u*'dI°È¼Ï·”Ê{4è yY¹&doßÈã¶@ªÏ€ãP×Ѫ€N¾WÿÔð­/«û‡~èCøÕ¿æ×à7þ‹¿¿è«¿ û«+¼ÿ~ý¯ ¾å[þ:‡C¸Í§€Qh¨7ŸqnÖßq Ž4@‡âG¥Ô­ÖúF ÃÓiœžìvÓãÝþâéåÅÅã‹Ë˧Ónz²Ûíž\\ì_×ÃøÔ˜ehVJ-à�Rƒ�dŸaÝ~·³W‰ôáñ�g­‡Å9gcÙZËAVØÁX˜yq–8Ì-<°Õ‹ÂÑ »‡ ê8ïŒÇ Ã8cYf/»¾,¨^fÌó‚ý~Á0xe­¸ÁaÐ:}ÄŒ Ï*/€ü0ÇA£™�oÑ"e›Æ,o­Sö½Ï€78g³$"€±Á—ÞÕ€A«¬ó;"X‘bï"p©‚ô´Ž ¸Â0 ì÷íì¦ÌÎ$p{ž¬óýăy>B ƒ›B¦§³Ã…l{ØÀÚÖ`æ Ó¯ µÏi}f9XW*Hx‰mÇpð}t ÝÏy%†AA«f4°fÁQk(¥0ŒYp\f˜ùèI‘AÚ5³ß9¥†”UïUk ŒYm¤|µÒ:8Qª'猱Ð4cóë §µçl=Qð‰”Dž˜¤µïs�ÈåëÄšW——tqy©÷»Ý0 ÃD¤.ÛßùíßöK>ù‰Oü~ÇŸ)­¿›3[°ˆY»)­,uª»X÷š+D¾îÈþÎe |©þë�‹¹¹è3pæuA^3xiE‡òõ�›¾ÕRö¼T7iâc¢ØÜðåvÌy‰é>Û¦¶ç*‹¾”¨�$«µT,­yD¦¿dÜH83J©×@æ†�‹Hn ” =eþs3ëX‚­2c9»&šÖò­ýF-^ÏÅö¯T@H"ýy™E¿÷oqù~¹Y@X,üÞ‹×ìw·“ÐIî+e‡q›ÙA‰6Ï$ðóKÆÖ­ì=ŠñYgþ—�0×–U_¥üžE?^I²œöǙڇ¨q’cµd\©ärLùº¥jżµ¡Éí·R{¹z;ºY•Ím·§6:=P‹D'æ‹jL´�[NjjÑö^ý¼ŠÂOÖGF®…c6n#­G©Õ˜÷<}úøâ…�”ƒmf-Ô£G�=zôx.¢zôèÑ£G�=ÞBAÉßW{9-þU D.ÈMû×dz§(ÙOAÔ±Å;Þñé^¢Ù1‡Ož<Áõõއ‹5wŽí“G�^yÿ;Þù®oüð‡ä7E £Ìügq¥˜óÃÂJO럵²&'à*ù%àŸ(€1¥„q�Vå­ÃUq›èHÀ?‚'Tø¥Ê{GYõõš¥R�=Œ¬Ÿ]ÖW�ÎD¼yÚ¾0åòïÔ��/…VIëLš¡:ô�ß¾öÚkø£ì�â?þýÇÉœˆ>%ÇdÊZ–à”G8Í ‡›q¯Çqx:ŽÓ“qš�ÓôxÐÃRú1)zt|ùå—–_|É\\\8"âÃñŽon®qsýÔÝÜܸãñhÆq2D´‘ÑÚËâ;çxY¾»½5wÇ£¹Üßw»‹e·› Y€8r39­Á‘qä\LL%"XvPÖàhÇD Æš•XÚÜã�â£Ã ÌóŒyööÓ4bš&S˜;læ£Á›bo$‰w pØp³™÷p-e50:Ø¡èAùJigñþ ¤’ÉÿƒÂ½‚ZJò9w ²±B á¯ãˆ1…ìt Ègúï¦ Ã0bÇ0<ðÉZÇù³Ì ôèË©Ha ‚S€Qÿ¨^iıCÃ9O CP~Ñ:dñ[€‚òê#­¡”ç`Ýj æü(¹ï¬�Rã0ãpë‹ò©uƹTïñL€sç|ÿ×JACAÀðrüFX×x¢Å°ZÓh�1Ô=)kmh ¬ Ú-©\í­�£¯«€Š–5޼’ ;k=ùd§a7M»iÚí‡q¸tƾð÷þößúW¯Ÿ>ý­Ì¬V:”¿�ŸÕ sÁ}…bâ—2ò, v®Üë^qá•r/Ñ£]�×$™­H,�à?7m|ŠÛð,åRáZeŠÛsï‰jå6 -)9Pû"ìš�•¬(÷6²|\ãùºÐôßlq.�Ú/ôťܮ£‘Éœäγ͕dQ“ýjêoÔï6ø/­ß!÷ ¢Y³lîj$�ÛКÝÏq¯–wÍÍ Q”èÏ÷Y\ÑÀ”ƒÔÌE™‹½^¥Eõ˜�ÜËýiF.[ë‚ÃqέMÚ±‚8ï«­ž^�¥‚™»)Î ÷}MâPYãõÆ›‘¶©„qbOµ5g¶>[P³ yo.Û¨t‰`ÞríÀ8”*Ѥ÷ÕçoLq'æ„3Ÿ!²újÿ‘ï3‰kó£þÞïúÎÏû²_ðUffÅÌ6®É=zôèÑ£G�ç': G�=zôèÑã-^>;Húyã� 3�UòÌpAB7÷ñøÚ1ã]ïúL�G\_ß`™_Çíí-^ûÄ'q}}�Å. )ºÙï÷ŸüÊê—|ý_ú‹ßðåÇÃÝçÅÁ¿ô™ÿYúÕá”<õÍìpx¸¨z`)ž‚‹¬°ü P?>£ gjâ >�5‹ƒø˜ èmD¹Ó�tj Ð}µn¨´•„%>ïËlÀÍJŽÞØ¥5‚<Ø%º‡Ü-7ÿÎÌX–:d]Cdcª;÷Tký />zôc®®ž>xá…»—^~ùð¶·½ýæÑK/-J)7N“‡ÑÑìœ3Çãânnnìo¼�'OÞàë§7T·J);í&3ívfœF7Nƒcf¨Eñ 5†aäýþ ãèX"²Ê#ÔÎXÇÇÃÆÌÇ™Øãq±ÇýÑì/Žf7íÜ0 nFVÊûÏ+¥Y)Å>KIš:fÇÇ,MgfëSÇ­µÁ«Þx0=d\{€ÅB‹Y`–foàÜER!QJÁ â°ò® $%€ {Ã9k,ŒñŠ.e{œó`ýnÚ¥÷i­1Cº‡¶N9¸�•ïãC«´¾HÓÓÌ ÑN­Ôjštÿ!Ú­(¯L0íFŽG,ËÌZkì÷;ìw;h­ýs9‡e™1hÂBì�} ‚…RJ!|EZ½§I4âz@°nÁ°pœ�óÀ|h3f0“/”˜ÿ‚u¬ ÀÞC†M´ �`¬÷ˆJ.nœ0#†hO£5Hi™°v9(ŠÄµT Oˆ�2  [é½íË f�c¨4ÿÐ,H¯¾òê0MãÅn·¿¼¸Ø?øèG?òîïúßöïÏÇùKR¼·±fƶ· Æí³Œ)Ïü§–õ6�ɵS•9\fÛrDÊ {ª¼¶ù^ z'å üÉ�ˆm�¯NߥÆZÀ ­Ê§åvy71.ÚÖÈ®sµ¹±N¶±»öÅ~Ëœ—´²íɈr\™0`Õ�Èë=‘�6€DyŸ¦pCqYN¶ð�Å�Zu|";'~Èûqãw¨wX®@O™[ 42€|Ì ü§SÎñu‹·’Šk¿ˆc•³Ë–ÖëFM*b÷/ì“üz*ú ^`Ý@ò*C¼j;.X¢ü�±“2˜ª1p.!¿­zpj.ábþ‘ Y–»è·|¢ gÊIÅ|Єÿ nW¾TL¡“Â,±ï²P˜XÕèìÞÍ5ät¼ie­Mµ�Óªo¼þÉÏð7™1x€uŸê^=zôèѣǧPt@�=zôèÑ£Ç[ ¢ü~”}öš“`AÐ�Ë$Ç Içଘñ®w¿ ×Oo ?ñI<~zƒe1¸¾yŠÇOÃX­ÕÑñòøÁÃÝGñ?ýKþ�¿öWþÊdŒyD"ÛßÿSä%¢}:‹¬–“qR+ˆÏ¿Ö…OæÏÉò�»MØÌrª2æ‘gŠ¥L«úÍ™+¯÷ij‚à†‘g(– ÿ& €ªG ²²™ède³¬M°ÖÁ¹9ɽ �É{×g~æ?ûÏýª¯ý" ̬¬1ƒ1Fëhõ¹&çœuŽa­µ¼,Gž—™�1lŒEL¹÷>÷Љ”%o`œ´ÏúÖ¼Ûï£4;+EŽH3)0;Çó¼0,‹ãÈËb`¬uf1nžgž¦�ã„ÝnÂ4�Þ>d𥠂l½?Äv`2Á^*>ØDùüeà»uA:–Ò\`Œñ™ß!Ëžˆ �ˆ"ä(J{¤÷¸�aùuÎSPNeý*¾ÖƒyY`–U‘Àû¹súÿqVëÃèðk�ƒ#—2Õ�s Gáþ*'ö sÀ¿êJéˆr,o1’´"¨Ý�’À•"Ì£‚sZ)ìwv»†q€sˆ7ËèÉ vñ’þΓ�l°0`V`•P\¸¶ÂHcš:[«¡¢#†ÃñZÇ‘ða�õ²ùdÖöLÿ”´öÀ¿THàp=¯"àç=èDX–%)^ †!¨6€¤^€,À.²=)Å%@ÊÛ%$픟ZÃûøu�9|åëÐë“Öz¯µ~ ýðÛ¿õÿ÷K>öÑ�ü^çÜ««�GaÑ’Ö!‘ÝšÊ)/× R7²ˆãë©mÀ°ÌœKÀ—ÀW.Þ.¡¹^72¯ìb ÏÌÜyeÉu…rCIÞóM’§@·åð)ËÊ'¦¤<‘UpRï@ÓN ¼®c®·Ñå}²kpž1 AB©j›¹°bØ@Þå^‰jº€|�K ¹Í‚„“<~¢¡ÄÑPÓ˜Ö‡Ïô‹Î�(j‰"C|sÁ+ø,Áÿ†<5÷3«ÍÇýN�ÿíz—YÛ’àUE8VÀ8/Ÿ,ÑÆ~ Û÷ Uªu¦†u�ØËs k–ÖY$…>‚úÈ›Üx6òÔÚñÅ{OÈÜß7xÃîãÜ^T~N ÑŽû+¥‚Ey¹šg¹y#á*‘Ù2$ð¦u¡"vöZdžöûþ—Û¹õ„ͦ=î>�ˆ443SÇþ{ôèÑ£G�ç/: G�=zôèÑã§0$ðÁ"-@ö2þ–À¬’$v•µÃ,¼•=Èóio'¦é1G‹iü8Þƒù¸,pf&mØ�·€{ýó¾à ¾gõÿõ¿ûËÿíï›—ùíp¹§nS´’æl<_þ¿,Vù} °må£ÍH(<‹ó£æ$ëÒ¤¸Ä>¸ÎÝk'øHáó€th‹S²ªgÞO´ýÎH~¨ž{;?©–'åÍ6cÃL©_}Š>òèÑ£_öOÿ²¯ùà2ÏLDÎ#±pJi7)íxE�`³µfñ^ôË<°ÚûêàS®uOáǵ±!Û\aGìŒÃ¥|¶µ iûÌŒùx„R Îú9Á¹;caíÆ.XæÃ8bY&ìö{ìw;xIy¶Hù rbÖ€ƒ¹(«îà‚ì¾µ>ûÞ9R>+|G¸ ó¥å™JÔQ{²Á0@ë%d˜·ç8À+ ȈÊžøà#Þ#*DÙx)M¯çÊAk¸q³]eåÁ@|‹Cò²·¶ PzEêÞ·‹Ï¨@¸³°PJÃ`Û¡ÍÖ°Àª0 ‡€W)ðä ÿå8Ô1˜ Œ=âxôjÃ`APi„®}bHòýÆ,8ÎÇÕF©0/›´(K°AeÄ9·Ú¨ð¥C¹Çã8zù~6”� ¿mŸ«aͯG˜ JÁ¾@C�Cêóõœ$eÖC½Æþá\�ñ.Ø‘”¡ âŒÂνç³ßGOŸ^ë›ëëažg­”Úk­®no®_ýö¿ÿwÿoÇÃá×­½1b,ô® P–9Í’$­ÝÃ+¨¶©‘à?µòÿ…Ä>G— hîß�í!ò(�‡ZÜ‚b·×¤ÓeDžX¹žs°o¨7ÂÓ< ›åÊÅ'ÀÿìpB»Èþ¯빬LÞxøâú™"AAšH{Š 3ÏÀ¬ç¬ \ ñ×h*1ÒÐ3í6u'ÿЙ‡e.ÀÔ:ùŸS6<™�Qe—$dÚ«\î‚t°’¸¶6Š×(í  À·Qn•Z(Çú)‚˜DöxÑö «)ºÇþú|“rÖû(cl)g‰~�$&¨œD²ÏUG:UMŠ¢ßðÚî™J1X0}¤íP]÷í/%�?ïQÑ!³f¨ÜÚ>d[d*žõÔøÛþ0õ“Ë<¿�ƒÿRJ)íˆL§ôèÑ£G�ÏQt@�=zôèÑ£ÇOQPÜ¥5Ó”çÖ˜¶ê�dÇæ 8@ãââî †aJY˜J+ Á’Â8i;�ãaôMD¿à~ÅßÏ{Þ÷¯}ýŸù3ÿúkŸøÄÏ—²ÿþ²œm9I”OTž‡ñ •|®Õä[³ÊŠÒ•dì†AÌ ã­‹n>䃤ÚHÔor¶Íûðùœ=óãS‚þ[¿Ûý-ú§$¬íå‰Ñšâ¹´øøƒ~ù/ÿ•¿êý‹1¬”²Y­ÈÖ`uÌ87`�Ý([ÏÐZ¿x`dž’‚�ƒ 4tßÃ8B^ dÐ<ŽóÄÞïAj p<0/ wîcM ¸àuUE€Òèp9©Ç«q¸ÐÆ«äþ 5xœ¸Áö(Ío­—š_–ó¼`:³�"ï^ï%÷uÜÊ>UwëüuÒ—vY4´^¼½R 32€R†Á“¤f؆ë¨�lï\ê÷1‘\¯Y€òn6‘œu°Á‚€h *-C'‘`W«Q~¯v ±Û]x’–°D0K´nñä­YbXç Uh;òªÃ8bœ&ŒƒXÌ =�'bh‚:ú:_@Ÿ²é*‚‰Š •·OЃ·PGoo µPÆB…µˆÈ×™Ö„qðÄ"‚³Œ}Û0@JyëšaðýuÐP¤Ò³²s`gÁÖgûCÖz &¶¯W–@fÀÛJ"‡ }Ø¥¾n­@´WZï‡qØ+¥.ìGäç}òµOü»ìÜ{äDÝJ|å‚# `–h\ÖCž©_íp3 uü3Úª(ºQQªÜYndµg“L{ûœ·€+ˆ Y?-³çyÓ¢ÎXX­4³Ý©Ñ{8WZxÖm®´O¨ª�ÄŒ³ÁhÝVàætÁÅÜ ?8æbN‘ûZ•ƒªZÜü†—‚Û½ã¾Pû9AŒû¼¿ñ>cÍg{\€¥H‘%R�УG�=zÞ–²Þr»Îäi›ê Æßp­Ÿ—áù¡q¿æW|í¯þAf¶`vlI‘Ójr÷CÊä�YóŠ,œC’Ÿ”R˜F ¢ˆÓ´Ã0Œ g8·ÀXÀÁºXß {àUx²+E¢Œ?yàY©7×׸»»ƒ13lº­±0Ú`YfÌ‹d €²À!U_) k†r:Såðþõ†aòêZcž�0Ʀ`ƒü²,‰¤0Œþ£¦"ë�IÏJ­ 1âÜ–æ½ UiNŒ¯M6vH–)1|Ò5œrI\%W ÿ»8WrÌr$9“úvìë̬0\J9(e3¥2ûÙ1l,«wd�ÖAI�/“Ä=@˜u^—ÎyÕv€U^r_«Ì1ëÞ[.�&�òÏäË€}­ µÂ¬"xû‘sx�V^±aИ†zô$€A@°Z ¸� ØA…¾?MSÈòW�dWUšÐ^‘$ü¸ðäoGž×0MØ@8+æ+o‡�Òð$Ö·ï ïx÷»³˜=€Ã0>0fyéCïÿþùîîî·€19÷«Îûƺ³¹)ŸCiÕs¡3~ê�k b_RØý3°\á‘-­V¸™E¶ì –·D3QCê¾(5Óæ:Þ\¨íKŸ²ÿ]_¼ÚEIo1–Sv{”Ú¦\  Î€®=Î+eo> nK {ݾµ6!¹É{ȧ 4NÌÙ€erAº¬ïÙÒ¤àgVufkY·^†-{ñšV˜ƒýåc´Zó™v΢Žóñ¼R/Âÿå„€ª¯sý(Q‰  à«hT0"a¡^AÔáFöz±ÃjïÐÉàĸ[“ï½Í‚ã-k�Z*#göQ^%‚å^–r²+m{{j99–NîNÓÆøì–—„ÂJiÁÅØ9·wNÀUOÜþLм&¯ /L(¹\ØZM6ojd4´lÒÿ†­{ûkŸøøÕƒ‡/< ½ €âŸ”$=zôèÑ£G�·Dt@�=zôèÑ£Ç[$”ÒìSPä3'#à�gÉ�–Ÿçl½þÉ7ðÉO¾�×_77·`vØí&(õzP¸¼ÜãÁÃüèÑ ËÅÅ…SJçx^{ûÏü²_ö_ýü_ø•ßòW¿ù›ÁýÐÿ¹Û››/aðȧOø*ÏÔ2{(Ô¾ÇI†¿L„’Þ³ª£ÔÐ^Årà¨H]Êþ)jQ¦CÕoá¶t>™Jþ9<5 ŸRyðú4Ýü‰¼{«ÅÎÐÙŒ"u­=Õzx<ŽÃãa_†áuRêǵR?f­}|{{ó¥ÖÚ¯aæwý4‚ß9Žã×üÚ_ÿ>â�Ë$)˰ÒÚKÝÃR€lZbFùz¨> D;ŒC)�iÚa±Ç0x°ÚZ³,°Fƒ É|Ç ½ë‰@ìAÜÝn"²Á}–õ4íp8ÜaY–õõ”6‹Å¢€1Z I D+ÀbOðYû‹(‡tq¦ÉašF ÈãqÄ<ÏpvÀ�Y0Ï:ˆ~ñD^j>>‡ÔmK‘°‚é@Œ×‰“.§÷]fá=ñzþä±}œ["ùÀ)/¸ÏPIé`�O¹"f÷ƒAŽ9@Fˆòúþý>{ž"™Ckè@Z´ÆÝ�Æ1XF¨@vXa^N3@ =(h«¡´Æ]xÀ~·÷ë‡VX†s bx•O°v …aÐÇ!|�FߟçË<‹yÚ(XAìv;L»Æ Nmi"à�ìhUáU",¬1ÉúÀg¾Ç¼gßaÃEàKõiµ¶;!¨ø¶..ébÚ�‡yÞk¥®ˆèÅ�þØé'~üǯ5ö}±?8æ\v\?¶”ƒ9\S“H�—>Õ€X«äz(H}yîºþD2J99S eʸjŒ@zžrð¿Q¾(£žY¬YÎÄ´µÈ§Ë&+ ^3gÓÏ♓�C>s nTK¶o˜ƒœ\¸½oúi“€©U¡+`Æ-/rY *³ò¥u7ÖÕÐö±-2+‡ ùo˘S{/Õ,ls7°�ù¿Jæo·oÞ'ò}¦ÜWq² (ë½·¿ÿ®†!²Ë9·(Úme]�“hµvblö¡rOÉa“KÞ$'Œ‘h7E©¾¸i%€zRÙl*ˆ y{äº œ‘†ZÍY9ZЉ=¯mÑRþ Rj¿©MéþÐõ'Qÿu¾©�OŠ~ñ¬àÿ–ê�"õÅ …©ºpO˯¼è§ˆ"'+óÄo+¦°$º„�žÿè{¾û=?÷K¾üã̬V^õªG�=zôèñ¼D'ôèÑ£G�=z¼EbÆäŸLáÐ7fþ—^ÕÉ#”*‡ÙtHøÃ?úa|âã¯ácû(Þxã ³`¿qu5aµÇ àáƒ+\\\ðn·3jІ™ggÜ­µü”™ÿ¯úê7þ‰Û/ûÛýèGÞù}ÿð»¾úõ×?ù¥ww·_äœÛGYËhW€Mœ€ŠDÊúVþ¾•»Ò� @“dS@²f¹qÊìºD_h¬g¹\ëÏ!�ç[Yÿo&ÿ§eÉz*ˆÈ)¥nµÖ7Zëk­‡ëqŸLÓt½Ûíž^\\\ïöûÇ»Ýþñ~¿ýââò5­‡§Ë²¥_^^ñ£G/ò /¼è..ö3‘ºsÖÞÌËrkÌòß¾ñÆ¿ó/ÿ×ßô‡Ãá71»ÀøÓdøýU¿ö×ý†ßøXé0¯rÕƒö>÷Ó4 ðSaIþô¾œc8Ë €Ç Z�§Ó8b}æ¾Ò>#ßÍ ™u,‡¬ &6­c8‰A„i ô%ÆaÀnš°ß_àîî‡ã&’@ ­AÊßËâ%ìµ—•x� QÈ0W p�¾ê©<âÞÆZìv;;ÜÝ‚€/©µË2¯ ;f/Ÿä•¾ €Ç ªœ2ˆ Z5¥ÒõæFk,X¯Þ½ñüÖq J&3œuë}؃ߎ½R‚Šm�µxKnd�{~" M¨ŽJÑïœÈgÝüó¨0×k­¡˜eסµœ·'°Ö+ ˜`õmvÓ¤ø†Ñ÷©iÒXŒÁtœqŒ¶/ÊKós°>Pz}yÂnŠkŽ —ÅÂYN*~-Z³úµŽÄ“É%ÔJÚˆå³Æbv ˜�(³õeà\^9¶A"?%Õ‡¨fàÛ2@¸ÃN»eÖDJ;çFkÍNuqsóäí?ü¡÷ÿöÃÝá×2 !€:†¹û¥o;•Y¡ûl•rŽÞçb 83§u0༒”Ò\ ÙnŸìN€¨Œ¦Â‹;Y TKh~/á÷½*Ûna㳪vDV0ŒQ �ag—²¦9Ì�i½mZùœ»7UÀó\èMð8µ(¯}!©-Ôàu%½ll,Vð¿ô)�&o�ÿÈ3¹·�ÿ3{˜[á^Ðü6nI÷Zœ�ïLk–}¼vF"Éúޝ¹Þ¢©¹×¡›�|�¶Z×s©ºÑr €à{Êlö¨#$$9•üDMÈ�¨Øšõ“ìN«Z¡¹ç—}ž“ÊÏ ÂpÉIJ%?9éß+ H {4È,EÉ«ˆóúL¤ ¾GÏÏ—i>§€²9×´¯M’”ÁL÷*囬àFÿ*}h *IK‰í�7>ù9ÇyþvkìÀÌ øIë=zôèÑ£G�·@t@�=zôèÑ£Ç[ ¼DøHàZ}½‘±ø ™¥ñgÿ&ïçý�ü^{í5¼ö‰×p}ó˜ vû\àÅ_Ä˯¼€‡BkŸê%¼­Èh¥f¥ôAëánÇÛ·¿ýÓ®_~ùÕô—˜Ý ïÿ�ïû‚�}ô#?ûɓǟw<ܽ{YÌ#5“æWâøýúoL¦ÉÑr° ·Ô̳-Ïk”ÊC]jK{rp¨.y•ØSg#PÇ€R)ck«h›§kñ’çÏ ­Öú.€ùwJëëAë= ×ã8^ïvû›Ëˋ닫«›‡Þƒ>SÀj  ²PJû¬yRp`X£aŒñJAÞÙ-Ž­GÛ°Ó^¹ �øÁâõO~�¿cØ_ìqqñWWxôè!=z /¾øDŽÇww3œ;@ÆÝÎ\X¾È*¥fEêæx<î�1;M_ð3¾èC_ôE?û†q7î¦Ý'~üÇßöÁþÀç>~üÆgÝ^_¿ëîîî�Çùø6³,/1C±<æò¯ÈŒ£†®éút›õÈÍ×—u�˜&$ ¥2@qX&²BWË^Ë1ÕÊ9/‹†O¨°4PJ”¢‘ºUZÝ)ÿï­VêFëáZúé0ŽO§qz¼ßïŸ\^=¸~á…‡×�^~ùéÇÖ:g­eëœ`­Ü0 vG·ÛïÝ~·çi7bG°Ï”vËÑ8 cÖ²c§HÙay·›xw±çq€ÆÁYkí²ÌnF7Ï3331³ŽBZ+§õ`AXœs -β5‹±ó2óW~Õ/þ€?øáÿðüöoûû_ à7øç}òÊííí£»»»Çà óáøâ²,¬³�u{ÇvB�šÙúIßu=À农ê}(DëA+Àâ’Tá1Dt$"KD"2J©;":j!…;"uTJ™aÃ0¦ÝtØív·×—WWOöû‹'——O¯®>}éåW®ßñÎw­Œè2ó?aà‚Xà‚"Eÿoùf—è‚�2zñ~Yä†ü?“±ÛÌ`fnÔ7-x¨(w•K,m)΀ÿ²_Ûp:»YHK_‡JT õ૬?Å>Cùèq…»œ›Û=w«ˆ9`Î'€÷û's—ß±'g rÃ)°µR`T3²þ)òý“×:!´’0À¦ÓH6ž8SGh¶× ¨HF“ÏÂ…bµµ-šrû¥qFûÞçZ‰›Ö- 0jÔÖ-’O-F'û µ.]tªCŸ›WîS%å4P^cã´1ÂÒj@8I°Ö~†sN+RZQÁ‚íÑ£G�=zü´�NèÑ£G�=zôø)j¤`™Åø Ýð·(u­çå§9)KàÁ¦'�ãúöfž1í½´½–Cbð½ö Ø€qÔG€÷{˜KëŽÇ£;î–Ý´ÃcExÊO±Ü8c#ئˆÜ@ iµcðŽ™'ã츛¦áçü¼Ÿ÷#?÷K¾\k¢Á2ïœsã²,Ãqž•™�8.G²‹%ëìàŒ½øØG?úÊë�_q¾»Û?~úäjžu{s½óÀ¨Ò`Lã4yË_Gêææfo­…uÖ˜ä+ýw//.JkŽ’èJk3 ãуœ8êa8,˲è–]k­o†aº»zðÂÍÌ֚ô •V ‚5 æyÆííw‡ÛüªAÑ4M¼ß_àêá…¹ººZ®./çýþê¸ß팆…ˆ3;g-”R4�#ÏËÀÓdܲ—y1‹5f¶ÖÎÖ:㜳ÎYÇìØŠö÷‡º”È"eZŸÏÊe‘ê‚ü¼ ÞÓ $Is›õ+Ç ú…5k6°ÉYLÅàÕ ôýbYL ´DEƒ@¦Ð *d–úù›“mÃúA²‹ òøœ@ˆ Î9_.åa†dýæ ¶èÕ:�N¸@|­1À²¶•WUÞñîÏR ¤áíFçœÖJO.~øÿïü OŸ<þW¬ãWVso l«D3gý7Ϙ”ÞìT�Ä«$>(¾¯ò�#ZVr Â9 ­ú­s °/Ž 9eÉýµßøÚ_ Wl4eÑ ÿë+,ÿõí.Š~6}÷Ô‡…Z©xÊÊà› ¬A` ¢2Vð‘×mʧ�v® ÅìèÊS=ï<˜Ÿ•%ï/9±‚³ÿÚ¨}¾ŽŸ#fp lõäп7)È"Ðf×pjºß®wCΜ×ö¦¨¸¿`$Q¢’Äotǵþ(·³HöœTøã\±i«!™<Íj‰ó"2ÂÆ:„2¹xou¦ëVd•œ šHˆ2GÒG�š,ÒT¡Ó} T^ ¬=i{Œˆ_3³°[)ß»m±PSS8Ñz‚N÷¾ª/j†N©F@÷¸Zó×¼õXçˆÊ…jDöê÷)åïÛ 8gß©µÒDJ)¥UWèÑ£G�=ž¯è€=zôèÑ£G�ÌAú«Çy†wgŒÎaŒ€Ž¾¢µ“J×¶0Ô“Æ~7a±Ã8 å˜ãñ/•— 7þšã ¡‡ÑË¡3°,ó|ÀÅÅ%† M�Ë0Ö8̘»Ù±»5ó<-ÇãxØïõ4MÃ4îô0ŒzPJ“V#€‘�Óìœ"EõEJ�5Mï{ðÙ[3ÝÝÝ�···êööó|d|qy‰G/¾ˆ—^z/¾ø"..}fµuÇã!€±·¸½¹ó¾Ó´^Þ!ûÔ±†sÖ13;ç,;kÍ2/Ëb–e6Æfg)@$)­Ç0Æ鋵0f†YLÌæVÊ%•§r Ê€iq‹³ÆL»½‡Ñ)­œ4ô  ØñÞì°˜Å-óÎçÙÌÇ£™—ÅgnÏñÅXcè³]=@ýÒã—ê"Àµ;/pv ójÇYCG¸àå{<0ÏGï=¾xÿqŸ—º7lC?¤B‡ÔÂþÇ”¡)ÏT•?ªýÚ_÷/|Ìûdzü±oþKÿÕ{üj¿ÿË‘¾Àoý—þwÿû¿;Ž#ˆBF·µ8¸½»ÃÝí-æÙ+h­1Ž#¦Ýû=v‡†ÑgÚ›ÅàîîOŸ>ÅõõuzO³ãàAái òñâ<5ú SÈòTD0€jg³2ç¾ÚÖÌKÈ‚O¸Å4Zï1Ͼ¿�ƒ†¦=†QËÅ8ޱØ%¾ æy V^Ú>yÑ+Uüá÷À Ý[ç}ãÝ2ÃæÙgÕ�ö»„!Øp@Cb_õ÷_=Ã[se"¼ ÀÃp;Q~ xµ §y“ÙÁeþÊÞ&¡�A €³F℠Ϭ¢Ð†2ÆgÊ[mò«de@‰0àßá¢_z +Yc0/ ˜g=88èÎzk€i±ßïaÍ¥¬µø̼à†æã1OTUgILE€r%NÄö[ŒóËjQ ”Àé´²LìŸRbžAIaÄ”l+üµŒ±XB]øç±€ÞýÙŸ«”R#€3OÌ<9ëvÚ÷w~û?óÆë¯ýëÌüžu­ãâù$b)Ýò¼Ç:µÐª‘j¥”|-r+÷¶¶ÈøM‰×QB�“ÕA쇥?xêóD™ôÿŠ|oh>5K|ŒÛ{…ÌϾ"�!�Ãø uÑÌþÏê+Ã$,qÒkMDÞµ¬vÖ,áU*œÛVX³ÿ·t²¶+nåUú3 <•‹Ì÷µž”à,ðß­@7šd Ê”&Êße ƒÓ 2Á[YHÛ©á/@`:¿ÐrÈΧ’sÁæä\—B¥"W%oëMÙ„¬çÍTjJ‚œ@Ã'T ¶r§óÎ̼‚¨Àæ‚8À²_Å„D¾lÙ“lVxA° ¼®)�8f½$:c“UŽ!Úx~æU­ÄqIX¡J=�Nô©3ð¬;»¦P>7 óû^7’¨žOÛ)œ.û6�á<Ùæ>à?3¿©;¬vH¼)àœû4"‡aôè?Q'ôèÑ£G�ÏQt@�=zôèÑ£Ç[$‡–eÆ|1Mv» Ó´K â0 h�À›ö–0ŒÁ¯ûêá®./0MÀ<qý”p¸=Ppá�RÓ½ÛaP>ûTë{fs�ýŦiÀnœ0ívxòø‰÷zžë¥Ã­58ÞÝÍ·»Ý²›&5í&5�;5 ƒ‡Q ƒÖJZ+ fÐþ€jš&ÒzPZ©À8/óÀÌÚXCÇù>2;ç�®Ãá˜äÍõ á´ ²ìkjZ<|5Îç1¼h½È¤TÄDÄJ“Sz°J)kmœc À)Òì%òý™˜µ‡»–`@03²™"àäœc3[wP³#"ë¬3Ë<Ûé8»Ýnâi7ñ2ÕV ÝŽ™˲¸e^pww‡»»» ÕMA̤U `GIH?Û9ç°X>z9x¼wüw+ØÌó’›qôßÇ㌻»CæËÎàä¾,Þ[~Ð:�À«¬º‚Ò#T�ÏÙƒü¹÷�÷žôðK~Ù×|èúúúßÞÞüáïøÖoý,¬d€/ÃOœ ð ¿Àÿû7üæßbÎG,Çf6¸½»Åíí Ž³—mgvÐzÀ8�ØM }Èþ'ʬI"€¿Ûí’2I/‰@· 3ްÖy9üyÁ¼,ØY #ÂÇÑUa@cž�IƆU.ßyù}å´˜ë”öüþ£m¶­óäc°˜Çy ?[D¨&* (¥1Œ:HãÇkÇû13LèÃè6 D1ÚÀ:) òIëTP °0QF?ÌÙ¤Œñv‹u˜�Åq^p¸;ÀY‡YiÌó‚iÚ¥²ìv;¼ðÂCh=`w¼ÃbOp^ñÄ f:¦¾Bðm£ÿ|ñkÊ�þŒÈ# v"BYFa×qÜH¤ðj ¾ï1Û (‚Ô‡‡pÏq1�öÓÎ[:ŰnY‹0¿â�ŸûyJi½SD{f¾pÁÌ—?øþïûÒO|üãÿš³ægQ ¨æ pÏ5XÄ…}ª£ØÎBŠ^®̼fK/vÊe«)€ý‹ïó¤õT"f¡vàh—ìhU%¨¤æ#ŠF¹Ó654»%8Îü�û‚§Bi ³‹úDª‚œhÂmB®N¤d‡ßPdU(Z3“›Àz ö7dÉ%âĪÑ$ÔU™ž1kœ…�„ôDç|ý-à Ð5SbÈʹZXHð?Ï€‰âÅl�} Y´Z•¾è³ùëòë´eá¹Rg½­èÛ,ú™ÈÓ÷ ûZc…�G£þ$I�$Ñ#Îe´ÄBi£"£Z@$ Q¸#S>ªÆ^ âSR")HmÔjBÎ;4�ipâ¤Ò’CÉ /úŠDAYv~Þ�ù„Ðoê&T@u,ÚÉÇ9Ó¯O�>¤ÊÃöe%Qa‹Œ!)*\Ýc³¸T÷ξ9?\³ŸX”�Zj]x[‘ "*UªÃÇ?öÑ·¿ç³?÷ í³ÿ; G�=zôxŽ¢zôèÑ£G�=ÞADÿöþ%Ö¶-=þÿc®µÏ½ER–cI¤©‹EEI¤^”lY¶eIñK�0,ð‘N‚8AÞîi$�´ †Ýqzi‰‘4 Û€‘Ž‘†A°(J|Y$‹U÷ÞsÎ^sŽñÿiüãñ�1çZ{Ÿ{IVñbþûžsö^kÎ1Çk®=¿W-¯Ùr¥¯øÊǃ>ú¨ålw{kþ¬UX+Á#ž>ºàã¯|Œ�>þ—¸@ÄÞuͨ8zó1žžžbÄÓÓl[Âr¹b©êñªè/víöU-a¥´M‡/É "„„ „n£®S.´½6Cž�(±¬–<¿eø³+v5X’`ÛVl·"h\ZAŒÕ6?B$š E˪&0UKõ’^즷ti æ?þ'ÿäÏúo]®×ëÿõÿü/þ0€¿ àŸðO¸|À²ú5ÿ€÷Ÿù›ÿüwžž®.BÃþ\· ÏÏ7¼{ûoß¾Å'Ÿ|‚Ûíf.uÞ/•�sEŒBÊÏÏÏx~~nêÿËÅ\;a¢¨áE(À(C 2'Ír¿’xv`”õ˜@‹§’;tVc.$ÛØm! FË…_¢åÑWà—˜ˆ‘�¦þ^ŸñîÝ[|öÙ[ÈbVù!‚¹‚÷ ëëc¬ë3n·›Å;Te2‡6¾ÀXE îöWn„«FÄ©¹ÌÔ#zßA'ÄÉÙHëŠ\ÀEUÔ“EN¬+ÖçnÏ7lk1á²nH׌åº` ožž ü¿\ñ¼>áýûgœIï£�G ëcjÿ·¸ŒÝ�ÌùõTïÍåÁÇc3kþÑ…a?GÝøRÃB»H9R‚×�Ïöü“e~#ÙûÕµD§ùr¯ÿhèó´¾7�ðzðŸæqÆ—ùrï7Ù¾\ÛýB¼ë^1�íäxAôp=à äÿŠ!*ȑϦÝååOÁ:ß$&R\ùëÛO?ùÁ�Þ|ôw°Þq�9묳Î:묳~�>kVÕ³Î:묳Î:묳~ë‡ø‡ÇdåAÏÓÓGH)C¡Ü¿yƒ�?þ¿ï¾åûp¹\UûZ^ù†œûÃf.vÖ…PÀNm༊ ¾ƒ‹Êö²,xº>áz¹ Æ’s/‚u]ñ¼ÞšÚ˜ˆCÀr½âr¹`) �Š4Uôó³�mR\ à”áƒ%püB™b %ê ƒMMiš’Y‹»œï¦$/×Ú´œUñæž‹d¤bž³ „€§ë}ü1¾ò}߇�Þ¼)¤Áºnxÿ\@¶Û ÉbJêË=}„�?ú—å Ø¶Þ½{�O?ûŸ}öÞ½{‡-m &,;þÇ_ù >þþïÛ7o/—’…,H[º™ò:¯N)ìíV+X$2�üõÍbœCíÃ¥€~¡�¬þ!4p¹\ñæ£'|üñÇE±ÎØÖoß¾ÃÛ·oñüþ=ÖÛ†\”ظ(œ©)a™âšënóh¹,ˆÌ€*Ö-a}¾á}8“‹d¸\/f«½‚C@Ú>{û¾óíoã“O>Áûwï(.× ¾ï+_Áïûý¿ÿáÿõßÿ~ÿ4€À?à÷,/ðŸøßø?þ•¿þO?ǰ˜�}™°,Ëb*ü£‘I¶ÏÏÏÅù €Å¥½FN(€fQ׌JSâ›<ÂõrÁõú—ë1dlk]³=cݯ UEJ Ï7#%TW#z,qÁõé oÞ|„7ožp½>€ß\l½l}­ûÞJð6øýü¡µ£öOmOëµur!eä”�3šcAˆ¡Xý;ÎH›9…ˆh[˽oM‘"“ä‹´—K»CXÚ¾ÑAêªÔ—¢VßšR=å”W¢BwÏW•îy"Yé”^]-b![aÁ"XÌIã†woßãùyÅ햡ʸ>}Œàø!|ýë_ÇŸÿ™?‡úÿüæo~÷ïþmüÝ¿û³ø¥_þüæoü:n·÷`1oÞà£�>Æ›Ëb¼É !Yš�z�¯æjÀŽ@dces# D•:¦Ý€š…õO�¨stݶ>ŸE@€í+ožðôôËň͹åý{¼{ÿÌ·Ûsض�1F¾^/Ëõéi¹^¯×ãÓßû;ûOþÚ¯~ã°ÞnEç”i7E-Æ$«B%77¯Ø¯Jõ:�ÁFª±’^umÔøŠö>÷z訒W#qŸªÛ¸µW¤Øi×ûµm¢Õ]cP°»ýÞ‡Œq!ºìóÞ½u¿O4rZìÆàˆ°÷ÚQ¯©m,xp‚ Dm/¬7f.ĆnE]Û7«è+ÑÁÖ®ͱZß»*ì\ æÁ¨}µÒ�zˆ=Ø;BŒãÜÛìû§ÆôùEÍFÝ_“?WÀšhøÌÒc'î$ ºè�}¸ãÿ¸s�ù3DŽ»Ÿúþî¤üïðh�lñQD#=¥õÿàœ ;[yB%÷ }îô�5öÁ+Û~h�ûó(¢O«cý0Ö¸ÿs?—ÑhX7ºStÏs©õñ‘�Ù�ÁnÝõÿãqý°¹…;àî÷ë¨äÇ î:9„ÖÈàŽ0lÓZxäDàÙÏ5:ÜŸöóíÈ�çÐòù{w>&üàýðÿìŸügÿùÐoK–OþÝçý|þ¶~ÖYg�uÖY_Ž:Î:묳Î:묳¾‹åôH6`E470-†€ÛÓ®×ͬ֫Ú[*˜WÞS@*oùÌì¶›ýô ôAàZŽ‹ ²ØCT�h±×wÚµÙlgS³»ìIXªuüWp¥ô‚S­Ž än—V©@DâT�ýa¤Â)á àbêiº^p¹<áã�¿‚¯|ô1.Ŷ=§ )äf÷«"�”dfÐR‚phYÈx#*à)O iy ]�×2§°%”;È:¨CÝ3̦"- •= fˆp{R‹Ò¸ëœT{´³Þßn[Lˆ!!„X”¿—ËÅÔ×àbMßA )óDEœÊR@ d¨�©¹) ªã3Â9£�WE�¸,±Œá-ˆÙeK.ÿÖ¿ößøäû¾ÿûþ½Ëõúïýoÿí+ø³0BÀ?àÛþcÿÁŸùóñ稀å9çžY_ÜB%žÔùÆÍÚæ¿jÀiû åGà±DϹ€áª„ К”MëÞ°)%ÜÖÕëZ€ëN±�bw™÷&‚AË^Ae-Xyxýa–·hóê¡­×øí'&zý³÷“PÜGBt[d •¿É(Q‡‘tPÄP”ÿ1.…˜A¥e¬g³·ïj}mcÊ4&�9©T€8@Üm˜;Å´¶}Ñ@PˆEnT²VÚ¶-#¥EÀRæÌº%¼}÷Ÿ~úq[‹cIQÁ*y„¹xP³\TØâ÷9qóL,Ðh$€vˆf¾^�Èêt`?ë u¤À¶­î>“R*×dN52Ãç¾×~ÜÖât°¥�SZ$ËEbZˆèb_|ýùŸûÙ?õßüµÿÖº­ÿFÇýýõ —Wi\ FR¢í`s¸+úÛ8ÒNŠ>àU [KÓOF„ßå4�êÀtg«ÍŒ"¦¯@;ܶw6?ÚÃë>¾¾Ü×è@µ|ôÞ)o½¸¼˜�¹ÿùþÜ󱇬tõ~àæ-oËJ¡D©yÕv®Q�ªƒØVfu+XÝcöýP�ü»ušƒã˜×ƒ›ý±ú_wû †°ÁÎ#@: ökóöqâ󂈺·Ç¶ɼ½R|ß‹ŠNøðí£rÛÏà¢3¯nu•>¤–‹AÀøú¤Ž9Âÿ¥îÐNøÀD,Ù¯Ooó~p65Ûî«“€è`Õé<}îÎh*9zô†‡¯ë³§=zë›°w”Ø5F"�[_t´Cí‚G«þ`o¥GwÃz¥—Áÿ£¼*þãq/?>Ÿ*nÏïÿÀeY8‹‚(�g�uÖYg�õ%ª“pÖYg�uÖYg�õ]¨#…GˆA�ËCc•j§�mÛ ÐšRQ47¥ï "¦þl*pmŠW𰇊`´ZuêÃöA ÊД ü¯ÀO…ò¬"uÊÿ¦0¦JW á¸�àÀýn/\¯¯?;•Ê€©-³@6åì*˜ŠE}Œcp}Âõé —ËªÙê!ºƒøP@ZÌAj9á†8˜Ýµˆ]ër¸ë5ÒôœrQ*«ŒÊ,j×ÌÞ•ÙTæI %ƒV´�²‚U hß;OÕYžzIgÄdå²%LMÌ±Ä dˆbÎI dƒ*²t%É'2›Íu)àÀˆ­¿RnÊ1À€³êcDŒK#�TðÓÜ+¶d–êÌÿÆÿð’!úŸ§´ýçÏïŸÿ—ïÞ~†O>ùo?û ·mE– ÊNÑlÏa˜B±¶g„Pòç�;†ˆ6Ub�ƒÌ„q©6ó£%ºW¶×Ìx”˜€�ÒðÚ è{zý{�$¸�´u§€PæÖ²,Ååalƒ¶=C]nù¸Çp¹ r¶è~­g‘+ ¹ÚäÛk"0(äÛye$Û´uobëaMz Ö¥¬‹ªØwë8yâ;š*=‹{¹‹ƒBö€aw;˜UŒD„Êu¨m÷û¢¨š2’hÚ·´‘ŠTúÌÏ�ò,Ý­-%l«9|¬iÖ6¤, (²$ˆnHéÏÏïðöÝgx~~g䢚ßÌÉ¢Dˆ&ˆ&¨²*€Ö®Óú4e`n2‚ëë1¾��öŸ^AËk¯÷”æ$�3¶2ד#|Íó­ªê·mÅmÛ–m[/)§«ˆ¼ð†™ŸBo~å—~á/|ò�oÿëÛ¶ýE¢IsY@÷¶Õç�ëàzPn †:BÀh__�Ä=ìß^U× y®Ž÷©¡Í]Æ?˜Øë¨íÀ?¨ù;è®Óµuäk¤Ì¤–Cµ§Ž: ÷á©fe<\–yýLÑRAnÙíDÞ=A¦L ÷êÉåûÜ™£½z·A?VÆ)|Ç5>ü{Pß;ÛXzïÅÐãû‡®®¬wvõ4vü‹u¨Ö 2Ž€äkˆG%ª/¼Eïwù�<»Kêz(DÆ®ô¦ºÌGkw÷ª“î5Iw ö,"ÿ¢!çw1kOuÕX^‹0ÛG'm$€JÀ"ò$5=\KCÂáªð„¡Æ×Ãù½·¸§Wv ^àì*qèAy¢ž¶ÿixÓNù8Jw:|žÎwcDæ÷Ò$í‰S/G Ošg°~‘™úò«rÎ_QUb+�øÿYg�uÖYg}™ê$œuÖYg�uÖYgý.Ýy¸²\-Þ<ç­(¸cSâ§¢$�E•Úre+0_¤ª"¥ f…†OqØ™ýq« ÈÛTóîË¢L뽕s±tÕ©LöÚüŸ Ge¢)u™=˜Ôm¨¹¨Ç›ZÕ� L]“D…�ªåu2°( ½©‡/—+–åj .1Ñf±à–Wß�°¢6µw[Vq$-O¼æî†jMÞTýüi®vÜf…žVûS³bº-&.çŒP@'Á°­ØT€\Áci < ƒjî<&h¡¼HÈìâ% ò¶a Ál¨™‹ À€bnŽfqŸ�l¶øÉ­)®›z^̤92„ÀP ÜóUÊ1.¸\\–·%"§’‹ S §”±ÞV3�dvñËeÁS~êÑ9!o BÒœ2¦d.Ž¢Ï;i–è9å–moÃØsÐMùσC…)ßS™gÒÆCÄÜ"6ÞÊšÎÃù;˜ˆ¨Ä‘Ê|Ɉ )Û{Ŷ&¬·­ŒiBÚlŽ—uT6¬ë3žo7ÜÖ[!ˆøØØdIg ABYÌå (ªhÉÈhb#µq‘ùòÚ~:”RÖ8€¶‡‰*r2'ûên5CLB‹oÙâ¶nËz[/Û¶]sÎ)á#Rý¾_ý•_ø'ß½ýì_ËY¾>DLÌbÎ#;äf‘?^Lu©6õTö4fr Õ¤Ô~äßOîØ;˜}ÿ¶æ,€ ít^[#lfõ8ÚýB>;0üë�úæ8¿Y‹Ú˜ô•à�m©M#ÕÁ ¢ž³"¾‚¸Úÿ2^ãDþ”ÀNÝÝÔÚNÞÚ»ŽÊ$»‹>/c!GçäÂÝË=Ó÷#ÑhA�¥{ã¤ø×È<š×ÀBïqЙý>@�¬qÅQ¸ùÎê� ñ`Ê Ói»¿T{¶÷?2•9Sý°7'‹|ôùÿŠ%P[´»j½»ô:Y�ºÂà`\OxнZæ£JåŸ*H_¹p_º>¢që¾mä&b ÙÒ{Œ^îS½ßó®¦wHÃuj?°ÇáZ؃.Ñ‘¯­—@zzø=܇tȃÁÝÏÏŸŸÊâÏH–�R6åÿ|ÖYg�uÖY_®: g�uÖYg�uÖYß#õt}BdFÊKQýb\èTAÄZÍ< €¢¤­Ï^åßÁÌþ<^[.<È d#tUtnYؤ@ª�»J69`™×µ]!Þ�`ãQUeªÈ¬¶5p]C@P…áȨ<8ÐôðŽ,Q³º+ 8Òƒ† 9U×Ô÷�à€P501gShUóÕjÏ.ÙZâŠ"@@Ò  %ê!§„¼V­YÏC�Æ�ü™±,–__ÁuÀL"H6{P¨}¬û—Ê“Ü9)d@rFÚ2Ö°Äa±> F@È!)Ûf±dEjn¢¬Å"8ð×\„ºJ̓& È¿^q¹^qYoذ¾¸l Ä›MKÄ@f÷½\p¹\°®·¢JFËM Bé ݾ¿Ø©8;tû.±(îCénªòœÛVðÔÀPÀÆ ˆ¨Åw dÐsÉ�¦¾oªjÉ…pƒFЉÅþßæ92AÞ[JïÖV�©ä 3�–þõµÕÎ_Õ®¥’ ˆÎ ~ H#Ìvúó­û�¹yÐÁÜ-3KûÜ¡Úڗ؈BÚ¨ª¶fÍÍA ,—d1%9!åÜ€¿j·Þ2Ç�ãƒß[‰i·Ÿ5b*¹÷” ²¨‘Øœ$¶Íæë–ʾR®�¡ÅA¡¤¥}Õú_š•}�„'§šU¹|Ù2(þå;Ö.”Èf;3 6õž˜çp�‘¼SDNíËö™&!DÄDD2‹jض´Ünë%mÛSyZ×õ¾ù«¿ô/??¿ÿWE䇎]!î”:_„IáÎÎJ½�ý|ïØCˆ|™r¸÷(»uþ 5¢¼©´öœsEw °Ø âêÙTµùÛw{óêF3Ýït×Mûõç_7òæÕY"m*€‰BV™Î!‚Â\Á$ôHEÛÖ±ë“;¯;jØþ7`…(·§NÙàî:+!¢ƒÿ MÚÔQ<è(Å>º½’f[ô‘ü1âÐ4]® JЃî)§¹¿¯Nƒ{ ‚?ì£ö 9¸¯¿æSk‡\µ0º«ÓžÔÒ>»¹>9>Ï�6Ü‘è¨÷ˆñD�BþØŸûܯyo½¯thé>¶—¡¥Ùì{àÕópl=�EKôÁ�a }—¶õýJ§!c9h6ÑP‹Ÿ™i5ëÝ=ÿN5x÷0�l ¦½ÇWñoóàÿbÞ}UéKÞþp¥:Nºúôpïü#†ˆ x‡KD\"°°õ™*4›+AÚÒv3õJ¥?Ëc¼8€Œ BQò²YõçêÒ°™ÛA�Ù»{…Zry:^DÓ·ˆœ@+ÄXhЀZRsGl³[‡ïùPd± óÀÚÀã}1ºe-—¾cÄq½>a½ÝºÁuéÉ‚­Xês粿óR¢–‹/Öbµéùì^¦-@¾e±[Nû¬Î·õÊŸuÝ�s=è„‹ÑZÝÕ”6#ïpæ3‹â`·�î"=<èläòÕgG¿öûõÔŽ‡1" 40µg^‡ut%øÖÎ?G‡È½s¶þÎÅB�ˆõ½@Î6W$6ò}A©G42Oqê�œGU´ ØŠß�0`æ 1`Ù»02Èh*®RÚV!¸×bB1ÄKq”`@s†j‚æd®TEâBr12Ru逳UWìɹ¨þ™±Ì]¿—µÝÂ�¹èá8Öù\U»F˜IHÉ6JÿDaá.Dt°¨È%K¾fI×oýæ¯ÿáßø�oþ+ÛzûçTõà€ÿ»Êÿ>�ë»»_øÉoûoÀt‹ribä½B½ºÝص;¥þ!Цþu\3Ù]ßû=¥ûÇ;'=ÿéànmÑûêG0\¿_ßNK­£~vÞÑΰÞGV 9îÔ¬ö}»FxšÜߺöµƒÿóµø}Ê_X›Óä~Ž’' :õ•ö:n×0ÿö¾èΩ„w÷CÕãèÿÿ}rû¾š‹Â 8Ÿ6ƒ×Á�:h¥ ‚€’ŸÛµåôÒJp¸¦¾¼’ŽÀgý€vú}B§õ§�‰ó µÓ_&Öˆ’Þ%솊àÈb}…�{Ò£kë‘GÄ�ÞŽÐÉ{[ÿJ@ú·‘jOöì‹—v>}yC<ç{ã@Ó:Ä´ç¿Øm¯h‹Žÿ;¸Þé4ŠW¯±ã+z©Í÷,&ôsžïuw*UYÖõvºÿŸuÖYg�uÖ—°NÀYg�uÖYg�uÖ÷H]®×!ïÞT EÑXmà5›º§©c ØiêÁÔK}à^rª{¦<u6º:Nq_À¤¦ˆ.êÿdÙ1�›¤èjÙþ³˜N«/S^Ëp¬Z=FÀ€®àÚ�ZOK¬4°Û@è–XÀu"ä”°m+TÅ@5›ð”3$Ù5š¾{ÞXžÃV;qE±a//âËx…eA\–â¾€°m7¤ÛŠ´™’V²€ŠÛC‹º˜Kn}ˆ‹õaê·,Å5ÀŽkêöª_ìÏ%v°–wî6 Œ ¥ïsŒà’/?ÚÜO_ÎÒ¶E Ð ¢–y$Fdi‘e^2tçJR`1 .KQDÛÜ­ãB)!Ô¸a Xò6ÂC�]‘Í1£DSä¼!åàâ0ÌâÙlÊ“2 ˜míªó±G9T²M<{ç…�Ñõ0»wêÎÈA‹-tq´�Û8Ïë˜ÔÜu‹’è‘CS¯7¥~�Òfìˆ8TÍSäGí‹JD¨×!\•öyøª„£©�$„�”PçsßD¹¹ytÐy‚[eäì£ Œ„P÷²ŠµŠ–€K¢-^Ë6CL{׌:; (,¬nk¹ò~?… 9ïÍÞºì+ÌKìçŽÑ¢ž®<=]`. i[a¥ÏkäDŒ .ËK¼ †ÅœIPYÔm}å‘8ÁÄ�˼ Ñâ$l¿(ÎT‰TÒÜcªÃ…ý»ÏuÛ*±AêäŒ!„ká)„ð†™ßxàéïþìõ}ûÛ¿ù/­·õ/ëÆA¨]ÏàóÝKjfU5½úµá€u2sýÖêÑwÚÝ“&ò™17F8Ôe‘ƒÀN�Z^¯Žp0� Ú}ÄîÜ€ÿ{è×H £CPöÝÁººn&P¶IæBêûS—=]jžù�ŒîÔ£’[œâÞ”Ï:`­G$„ÞçÒÏFÚ³àý˜å”7µ5ùØõÉyÈ®‰8¤#Ì<ƒ[dê!*0)�½;+ÿït°»�Ü;‡o�5·x"é£bààj±îbfÛõƒ¾zÙ&\¼ïl%÷™ðœ×»}Dð’aŸÐ1�]› NYçzç<ûɰ»'5á·WÛûûª_u­k{_é~Eêë¨ó?ëžP¼_›­óR™û¿¬ÓfS‚£‹ÖÆ£H‹Z¬ûƒ½tµ¢ŠWÉóçø„é‚wgÓ;}9tj×C7•;Q\/‘)èŽs�¢�s·ùím]Õ–ÉÉ8묳Î:ë¬/S�€³Î:묳Î:ë¬ï‘º^¯f#W•o¶¬öœ Ü/öÎV.§<„bÑn kÎföÀ•Š‚� 7ØZÃ�ÿ*¦âvUAXëH5KÎ~Ù«þ«­õl^Ý ìý¸f£^-÷©+¦A@å4Ȩ,àiDÏP²èCqˆ ˜ú_ß¡ä´ÏjéYq­Ú3åsÍê.`B½¦˜ ô ‹�ðP,ü³RÍxß6�“�nT?œWðŸ�1,XBDf{îE/‚¬jÎe 3–¥ƒÿKŒ|EsÃo‘ªŠ”[ʈ¼!Ä1$¤,&‚TÐ3ÞË\¨!´õ 3ˆ°ùZílj;YDª¥=÷¹ÛÀWé„€BûÒT2ÜSFÂÖ\/BLX$–ã1X ) Fí) «´èŒ”–K½´¹™sÆ–Œ `¶æ¥/·6ÄÖžh tQt«‰n1ƒ  ísZ i¡EP ‘l¤�:·¤[ï‹Ê¡@_ÖÆ þøžíøR"+¨æ/-E(íó󼺣߯m‹¼(�Ñ…œ|Ÿ•l�Ëúõ~D0NUè @߫½t%¤I#êŸ[W�ZUšs‘õÍÎ[²È~Þûλp!¼èE,·YK?,J`ŽˆÙv¨%.xóæ ®—Ë%”ëÙ°¥i[Û^ODl.×ë×§7¸^.ˆq¶ˆr(¤²XÔ�4!;!J„.Õ™DÀlÍP�  Fö@sŨdiÌ!-ä€1¢ â…™¯!„�bˆo"‡�¿ý[¿õ‡~áçÿÎßüôÓOÿ…”¶?Ò¿ þs#ýæœ{{p?6ø÷`VSÅ—½ˆáòE&G?À•X “Dxfp–I€jâkûÓ!nêoòÑDƒývŽëþ4%ºúÞ]\œÅì¯0}MƳ–µ§ŽÕÐmÆçHmý8âæÒÈ]‡ÀÿàšRþ¤®zïdêÀ±»V7˜én àÕÆ¦“ŽÕ¸:Ï‘]èþ{Ƕ›ñKËr§WôþƒrÀäÄM<>šë£q€ÛÎ9P Æ¿é MÎ/•î‚pçt FwŸIý;÷èj}¯~dàâB€Cd¸:¨P3M»vrä¸C pÞü#q' “+J¯Á0˜ÓÅÏä‡=ÀÝïKzØ~ßšbK0Å;k jãäÉ_$%þÈa8æÈë6+G†š¹ зOLz§íôнó–÷}ï�wç˜&Û‡�ÖµÎ߯Ï:묳Î:ëËU'ଳÎ:묳Î:ë{¤–Ë×§+.—!@i[±ÞVèZÔ¾RÁ|—õ+¦^¬ ]n„SìrhÚ5kà¦â¦ö`½(AÕ9 TuÖlÛ 4€Ï^V *X謰«jydÆãuà'gi$.–ôz�‰U±*Ò¦2p´÷˜š¥;±ÅlY°º6Uåw ˜KˆàXÔð"Ør‚lZ@2iöÿµ*ÀË1"\m)pËï®`zN )—¸�, FW7°˜ 9˜­~Œ±�ÕÚËRÁÿÅâ†h‡®è7ûÿ®ÜÞàumó–’wO €ßdsjê |�@­�_FÎZ,Û÷9Ü ò×+x�§ìø:SV¨® œ‹K©š;#‡hÇN¨ó1‹"¥ÍH!"åhÄ‚¶VÊX ÝÜ1ªÛD@\b9^t„”9C½Ø�sm·³æ‹D€èÐâ'&Kì¦Â÷‘q*ŠLÒ,æsɸ÷¤›G<»�vkΓ0ºò[wí³±OíßüÏe¯!%�w2—¶ù¯æ¨PÆÝHý\èïN Ü×.ñ N¯m¯ÍË_·9løŸí#GÐjvq {¢By=—ë&tP’l/@´y¤@§EÍÿæ£ ®OÄ@PI¸Ý2žŸßcÝV¤mƒdƒƒ­ç§ëž.W,ËqY%d$ �€¨d)÷ 1—ƒBRUàJ` ¥¿x m1K#¸ý‚T…Uµ|I€*ÃpöÈŒ%~bæ�~ñçÿÎ?òÙÛOÿVZ·\¡C¢f4‰F¯€Õ®ð®öü`SÜɶ¯$‚!JÀÍëvÜNpî3ÎÞýhÎWpRÑÁã~#uà·vu¹RNu‚vˆ¸8» �ÿî€ðÛB'LÖÿý¬ ë²1�å³éý ÞÓÿ{kÿ¹ÝÎ7½µ©®Ó†�¶¬ñ‘ô •<0ó'TįÍíÿÒ HŠãæÇvhædY®ÎšÞCíóÓÐ[´×=p�À=€ÿnÝÌ#1ö±o"ŽÃxãù¡÷,óÆt—ë>Ç-Cƒ "£/ûáûŽß¾‡EÇ. �s”í½nNéÑ510p|^{˜ðJ}:¾D�b#0F1Ô()ÚõEW�Ó�ëÖò¿F8èh…÷÷ ã ½ž¿Œ„{þS›%J¯ð ùÀ"¿'ݱÆmÎ Ì·W‚ÿG)Ÿƒ;€£]øÅ†û¿ÒÂëÚx1½Ý¶õXg�uÖYg�uÖï•: g�uÖYg�uÖYß#µ\\ß<áé²›lÁ�Mq¼¥� kîyÅ0m`f4«u?T‚�ÏØ÷VÇ pèêɦž¬úCˆíï^ÝXNÝ¿ËwSËÚ&j–ó`®OåU�:€@Íf½XžJóFžz6 =.Î ÕI@�,[ÞÌB=KhÌKQ�sŒfcŸ“ÙæoÉ”ÎEq[®Æ®%©"^ì|1d"d5@N‹ZÛ¬M�Š˜ ‘¸Xø—÷ÆÐ@g­ “@ædb´N‘Т–Kăل‡âö€bJ½ŠZ»¨ã+ص… k¼CŒÄíóK‘A¤±»3Õ±²Ç¥þû~‘¦zïù:€Ä¢[³s”SN¸­¦Ê�q‘\úCKœƒå¨Gf$!…BòM1š›<âĂ˲´9(ƒ’½Ä0Ø¡ÀŽ]“|«ª<0Cce‚ãq…EJÉ\+*@ϼ[.µ/RJ¡Îá#U~�Ó�‡kL'r‹* a$T2ˆLŒ¹üq‡ýFú{™ÜÈZt‚:ç[§ÌŒ ‚mש©Ó¹¹/Ä%´÷j‰vP­dm€$í¬Ó;™¦:zT`?“¸~æÝ'ÚÕñw |.VúUå‹¢ p±½0UŒ§ë–R¬Û3ô–ðþÝ;¬Ïï‘·Í"ØÖùå²àérÅåò„xY¬¤‘Ýô¹®¥:.ÖÉ<’›ÊœeÒB†ˆP¢Y�BŽý½4:XÜŸýK±|ò�ïüÐ'ßþÖ¿¸®ë¿ *?ÜÉ>hU‡h´Ÿ ìÂë=àVÓ9ÐÁUÞAÀ»x�_uÔ±NöÔ^i_£ÕÕåÜAcÈÞîmUêN,ìöäöºÌïüvà¿W¹ê°.gY©böÞïÑ “R³Ã†ù­* ­­D/šÇP{›´žî9I«Îåoͻߧ„m–îºï«úyaއGÔrPü•»7T°ó($€Úuµ£Öøíç˜Õ¼ŠBŽ¡ÿÇ¥¯CLíF®ð˯¸õ8›©áCKu˜GøàöÉÛ1¸ÌÓwtQçd@ƒ—=M �Îî†s¿žDÝ„�65µ‘öçr$€WŽÛÞ4Àí£ ¾v_•!ü3uG2K&w•±?öT‘#'üW ½ÇëãÉû¹hý0äúþç�Þ/J_ÀáÿcózŠÆëÁüÑÀÁÇÀÜ ñ×%e)¶“pÖYg�uÖY_¢: g�uÖYg�uÖYß+Ì–€KŒXâì¡{̹�Uª0+ôT·,å1™)a³$m¦RϹXDWKg†„šóÝíB †…r¾ª`miظíïàÎK€¡/bÖcUp(Võª¢ØÎ°Å ‘�³Äþòl5ëó©Ë»«sAËr507˜õ¸¬€N©[œ«6•¶eÍI\ì¥E€B˜°Ìm)½ÕUî1D,åËìÆÍc4.¹÷‹âür¹ ÆKÉù®@¶@PTò€‘,J;+ˆ™ É!4Åt³ßWušTéŽj@­TÀ>•4+ýPÛ€Š(˜’¢p®VÞ ˆ‹Jðöµohzl ·Å/RÚ°mfƒžÖ„Ûºáùù=rÊàÀyÂe¹‚ˆ±Ä—ë×åÒØÍ�¼€"¥Œ´­ösµq¹^Ò[j†º û Ûq˜«ú¿ Zû¹8 dS™¥C†¨òlp È )%likð 8÷vúãz�i™k‡öµß`0r±"oǽj�UÏï‰B=B0Y†öV€¾îGÀ¼º5Ôkb.{S! „±\\–èÒâh£á0+ùËÚ !v"Âì„po|ØÇ.è¾Ê(Ϋº|âÂr1í=\ˆ:DŠõùoÙïÞ}†çÛ )e�¢¹$,×',—+–‹ (Y›08= ¹T UivíûÄÝÑÂõ‘õ;À`Q0s°¨êB„'@¯Dò¤ÊOëíùû㛿úמoÏÿlNéχüîº=WÀÛõ’K )<,m± ‚1ÎeþG»÷D÷‹},þñIõXž\�‰ž¿›wµëwU�í2œ²˜ÑÝêq›¥v?¢è°Œá#-tàê%ˆÌÎåbtÀï-øgª½^ôHÕMnÞïQâÐ:qçTøc|3£%¸v°S|†�Ÿ ðùõGë²q zŸV#Ñàz` åûåMÚȈ¾Á†ê꡽ö±*¸î=Vôw­þ£�û×%èbx:œÐw,ÝéAóîÚñ¿¢¡¥¹l<èOh6àÿýßJ2êçÞ¡a¯ #oL×;öß¡?ÂÃÑ<š›fùÈ®88 6ý:Nà>¦î¢èÕ׿-»8‘ƒûÙ0i¾&<í7twE̱úRPÛ^÷ûÊ£BƒK½nŠÿ6Ý]ç/M¾áŽq‡à»ñr}ú5UÝßÎ:묳Î:ë¬ßëÏ™Ï.8묳Î:묳ÎúÞ(¦¦þP²Úðg•¦8ßRBÚ6d1¬H-¼E�¤ˆí9� H9uýOQõÇ  ´k9¾M^ÚÀp.@‘µ«´� ˜¿÷P�ÈHˆænîíÔ}>¼ˆ€*šØeðª³J¨˜¹*¹‰ 0j@þå²€™�˜‘%�wõb=µzp -z 4±½´;*˜0Ý K0õ®=`5@oøB·¯7/m)—eA\.X–ØÎ“EªÓ7RdIÈšÑU˜6>ÄÔˆ \«ö¹5Ë»¶÷è _s&�)#‡Œ@–®PÅ›Øy;°£Bzo¿N;‰”Ò*¯[¶%¤´!­‘Òfã†~,̸\\–«ÅT;jæ8ÊÙõÚ!—ËÒlþ�ä0庫ñ§7ÒH³Ž'm–¶>xT‰S"dÎ`Þv×ícT¬¶ÍÈÛV\r²ãj˜þžf€A�2ö¬W hf <ùk�ëðùâõØó8q¸j $´ÈìÆ¾½6 e,ÍÍ ÚÀ÷9S 7¹ì3µ]ü_°,K!]Ô6$„�°2#'FJ[s™ÁÿØâ?x_"r¸GµXé.ð±%ÁGkŒ{#,׋­çÀ¡NlÜ[ÚðþùÖtC–„÷ïÞc{¾ÙþK(®—¸ Ä‘ƒí…åÞP÷C¦xÛö'HfFæ€-2DÙßl.)q âH.€^ˆèJDoDäãoþÚ¯üÃï>ûìŸÛÒú�Aõã}‡ [À@ð/h0„ÂÍ=Ý©?g2€?. Ù¨&Õ”nŠw¯Ï|¼Çròí2f¤^0|§Æý£�ê¡crÇu¬´ýçh¢Eb`×oxô†±):’*:­ ƒÙm9Üüø¼uçÚãâúÚvóè®åº„O‰3ø?«”‰Æñ2è�c¤¾Iv�çz&âdò£ãÃ1)‚H‚Ä */>õàçtI=<Ò«K‡À…—�U£/£ð} Ðan�»šzþzÿ¡c¸’Q}ÜMáñÚ9>¨ú Š;ä‹;�~¹ðºn�S$:h¬pI8"' ÿšˆ;¤4ìœ-Ÿþ^ƒgÈ4V~Îê!q¥bÚ=‹îAõ÷· =�^5‡_ÿï´B4FŽš¾0ÔQïÛúo#È¿º/^ŠÑÿäåúþøû~ĪBD'ଳÎ:묳¾DuÎ:묳Î:묳¾GŠ�m9ÄÙ­¨ÓµÚl‹ p3åT@uŠ`À@ÃSd™l�QAv˜"Hòhýo–Å¡©ôím¥�@@ÝLÍÞí¶½Âî-õ úlfH±ºîߺSF›"_‹*ß@8¡j×^¬ùcψÏ)#…„Ä%ÿd™Ò(äÞ^Ð`û§¯ƒqâ«Í8H‚œÍågZ”ˆ¡ôChÀWÑ\DL­/‚Ô¾rwSèhê�U¼t³Œj:" 0CJÜ„óÛ.Ž U†²vò‡HÆÍ2½Ï5ê`9‹�Puó!t`9p³�'—­^Á⦈µ˜†”@ ¤ÅÔû�-GÝâ¨*6ÚúXÔkÍ‚œ¬2'¤œ‘  ªž+xÔÀõâ .+›hTÄ·|x&¨†2 ºÛDƒÀaX >òÂ�UΕ`äž”ÓÔÕÞ�qÕ¾ºƒó•àà¯Av*ßFÀˆ»Ò~\ ñesë¹Î? 5òÅÜ÷ìô›€‹¨ë$Ww† 9Fl)¶=²n€ìýuÎÚ9C%)·ë­çÇ&Ûú«sÂÏ×4G/tM(s¡í9]d‹uY3D8غÚÖÔ¢B´õ¶ÄˆP£@<ªéÁÚê–@LLls@¥«à«Ó 3§òÅÄÄX«–í ˆª¸Ô¯oüò/üéwo?ûë¶þÓ*òÝ œæ�íäßÕ”>’týˆ:dID‡öòŠ;ùãT@´ÁwàÿDJâá�ãeµKï~òíª'°ÏáÅÛÖ¸{²WåIfµ‡kÝ9RŒ÷£©›Ë}`$U ‹Úƒ…•PE÷Ô§Ñ ½_e'ÿo±áµqs¼9ÑØ½ýÐüW_S·ýïJéÖÉÄ Ìüˆq<ªÕzÏ=—þÝ´: �äûi¸ûù+âË?Xy¯£ÕýQ�žÀMïÀptk:lH[¹h§—ßâI;“0½óEGÒ�.w¨»Èz¡þCžŽý3Í?š–Jî@žü‡ƒÀ4Þ»f² p>Ôü³¼:pT£D˜GôZ~ŒûÓᬺ?`G+ö…s?ü)í¶Ì/ Ø?æFÐ;0½>” ç?üG¿ú+Ì”Ué$œuÖYg�uÖ—¬NÀYg�uÖYg�uÖ÷H)wuwN ëífà`JÈ’›Z½*Z,¿ËC} ¦çª’*vöÌŒ°,–k@Tô¹æŠ—#˜‚vAf•ž™Ìnšœ½wˆ1Àž0óÐÖ�ý l�”ϪÝ�t €›\B@©í˜10b4k{"S„§tÁ¶mÍŠ6FsEàj¡?Ù“#u±ˆûÔ€n†‰½òQA%󴒚Ŵöëë–é );«ôbûŸD°ål.97õ 3CCC@³+�(�à^�)Q9€—Ò÷ P$eäv­ØlÙæ­/¨ÏÁB$`â~‡ØHø÷Uíï�¢Æ,í0åó‚åzA¼Ý°aë±�á:G@!ÈXæ|6 SrQ¿[?ä°ßI0.NÝ9ÚÍ©ì�0zV—ˆôÀ€e"Koù@XA� }-tëÿ”6¬ëjë?÷~ó¯÷DŠqß §’t "ÆõA,Ql%‚#ŒÄs8 0ä`Û<ЩÀƒ§\æ‚MŸ �,m]y;þ:_S‰aðs†˜vë½Þ¡¬Óº—BœÈî8ªà»1�y¦¾¤â”0:/(4e—C^€uÍmNµè‘ê.Áè$¢Bˆ‘”‘óÖˆ9¼Q‰{éä+Kq:‰1"†¥õS�ÃÕy¥ž/†YtçÆP÷ ¡œ%l[ŠD6 Ç ˆ‰)ç�¶´üÂÏÿìŸüô“oÿ3Ûzûë"ò‡ç›Ô¤9j³®ÙôJZõîý ø§éÜ{𿃎ö¾ªmý…ŒÕÖ?N`îÙ3ý,^ò«wúŠï€ÿÞ¥¥‘i*cõ~·oËH rQ*#ÊîÝ\$ÂÁ1´ÄœN˜BÛc:à­=ÂÀÇE)À»Ì€�´éGö­t×Q>"°ïÓò¹A åÞ2MtŸ+ 7Ït€’ur†¸?;0œm¾ÂòiàÀ¡¡÷‹[2wÎ$þ^Tâm©’w$2š[;ºoÜk—WÔ«îÓä»SM.lÿï̼ñ\�°r`X^Á×#ø‰�sc3^? �aΕk¼â>·ÓÁLPw2Ù²?*s4™÷*=Ú ±s¶¨ý¬…À§ew¤ã~Ç´_ŽóH]·µ|B™'NÅ]‰; úâ]ak®Ë¯÷××k_O�›óyϦ_ü˜wWÒ¡ Ãq…~îéúæ–5'ò+2GÎ:묳Î:ë¬ßCuÎ:묳Î:묳¾gJ-›^ì«Yƒ¯«}?`Ú,�]–p…AºB½ƒÌLܲ´C`ÄÅ,µcŒEÁ$È¢@ù³¸»eºÝ˲4PO$·ódÔdôÐl¶Cy_¬§s>$�Œ”8'â�¹éDu@5�v˜Í²»œa°è®ñ1F,ËROÕ!T€^ Rc 8ÙlábQ£Xÿ3…ÖV•ªžR—Î%w\¨gŽTúÂÚÈ ®ãkjõ$‚mKÅbë r`D±•®nµ˜ˆ,…Ò§�%!2Bf¤5` (¥6övë„_eˆ}ÁÈ–Å )¥¦¶?ÊN¯`g# €c3áúÄ^WliŶ�0P÷%R–BŠpVí}ötp°Dd¸`NÞµBx$( ä’,e|jÛ{L†¹ØØª(2²ë· ·˜†¾>Dëºa]7#.âÆ°n‹«B­ž®W¢]Ãì9ê|ê†È(@‹=áU€0:]´–TU¯­ùTú1­À%ÁT²P­sqáà¶d§äÇЯÞÂߣ�^œE9¾B™ï['%B"çÜÈâlþküB=N#ö0ƒCéãl$€J.ln"ÞáAg÷‘›â­•ª¹ÌMENRÚ°¥ÜœIbè×JLˆäÆšËEÒ\ì›ËqÅæ·~¯;qÙ8ʾ'’I�‹dY„ä"Y–œó5åtô àúóïïüÄo}ë7þúóóó_“œþÈ ¼’‡áÉ�®å$^Õ­5?½nª0?ðà¦úÞ&“s̽|?Äët´ôÈó» Î-:e𧇀ßd€ß€´/Ü$U#íÎ]VdÎý¾ÒÅå~VÁÿ#õ¿.=y©Ã×èN.Q {ûð¾¹ïÁƒÿžt¡£òº’èàÒý}¹ …#£\|†=î¤8ì@dq{žr %�½ŽádgßIS:ŠvÿópêÎÕbv±rìçO~úšO‡è.=óÚ«D¯Æ¾£Ð?^C{5ø0W]dÄpl?7tÌ®o{ÆÁîäïÖÿ2ÙÁ{¢vÙôÞA/)F’‚ï›HÓ¸îD{ ÿòêž¿þÁ¿Ð^|¿û–Ç(hSíë+vÌiAéñv‰)ÚÃÎé'ŽX˜Qè×§*¼Ðj•»w&ýôÒÿéC[w¿—?èÔ_¤èÑÆ,qùÿ†%lœ9 ûÌ”³Î:묳Î:ëËP'ଳÎ:묳Î:ë{¤P”sÉ/7KðàU_ÅFlþÍõûL°¼i(qÍÃŽKŒr.`ósØ Àö>SÅ/MÁ-9€(•Ÿ¹¸€¦X.Ùõ¹*ñ$gs{¸NNµ×í† DÎé5>›œ¬Ú™‡‡ÄâÕÝ…,bÀ²\ÚûŒÍò¾€1�9jÛØ@ŽQbj ˜BCbìœjý8 �@I!”QmME±¹9Ø×Lõ—S�–od­Ï%fH±Io »Œó†‹u~„"𥨱 A¢0R`ðÍŽ—sjÊ÷Ay;ÈxK¼”Ù"B,1 N6‡}$Á8ß+°ló*#›Ô¶ÚJX·µX¯Û|ÙrÆšŒ£E¡Ÿ¶Ôæ[%„„BÒ€vkzQEN‚œS9GŸãµšÕtS„‰LB{@Stšïû×~¶— Ž´?ȽÄsjĈ>\`ü¿/ã *ýßÝ ežçÍéažUÀ4¦5® Í�`æ<ÒGG Ú¹ì¢ \àaj, éîâuŽ;xÍøaÑtçˆARÝ9‡±(ýs÷�½ôο^jA'«Ü“�{grD·Û ùˆ%?l®NûÑ€ÿø�÷�óæ ‹óöwß+ÇX�{® ü‹å‹�üæ£�ÿ‹㪬›H± ;묳Î:묳¾4uÎ:묳Î:묳¾ªÚN›¼åNKÉŸ®ßW–2Ê÷òÕ” E‰O-Ï>t€®ü¼YÛà1gs�–‚´(S‹-þa ³YyKvªÚÁV»>@Í`–ÁÂÜ+|í/»žhÚ4 �§sŒç¬ V)öóZ”ÙaP§’'oݨ`¢Y@œ�˘¹­’í!½vu~à].`JEá¬�t! ¬ÔF¨6Ì,U­«H¹+Á«Í?°;üBòhVE. N†µxu(ÉæÔPЕˆÑÉÁæÀ‘ûÜÒ6ó𠸀ŠÍ�A²"SF"‚#hBq˜ÓÖis¥�ËLòAE‰¿,‹Yš—1ÙrÂûç’Ä„”Öçg<¿‡%\®RÀáT²ß˘†€år)XuÔ ª–E¿m[ë�Yˆj—ËRm»îÚ—YRsÛ!šâŒÌŒY÷¦æ�-߽ίN5E2#s¦X–ØõÕ À"?œ8šš×4È%n‚  n–ÊÇkí©½9O¸ˆ (õ7ˆYHë<(ûJýbî$mQçÁѾWû§®­F$ FRêŠd)î y°l·¶š»I=¦_ï²mH›ù7äb@J©3 [îW{ñ  ±q_b“½¥?"�ŠòÿrY̱!Ö÷8Kâ:u˜P1wrÒÙHJ`P‰ÎÐ! ¸*4÷¨ÝA90¿Z3Ûž QႸÄ!âÁ^K‡û™w¥ð¤”6bhàÿ ¢ZL!~^I ò·-Ù<md˜”!Åa/©qK™wªK�(¤_"DFháE:y�P¡’‘Ëžž²‘»DRÙ'©¸:T÷#'T,_!æ?RœaJ?±’"ŠåÍ¡üNŠLSæ8Äo}ç·~è[ßúµb»­ÿhÊù/@õMmç=´tõÃXb-™Ò¤:r Ò�ñ&Ü&½k=®.¯þîô›ÔÚŸÿ†‹ž‹íqvç~áNZHz i‚hg‘î<pD0g•!Q}ê™±-�>ˆÊ>;€{Žqpêü ÐQqn9Â+çÏžäÐÁÝÍ•#§†ý±Ð# ¯6NÛ'we>À»K¸(¤Ç–âd=ÏgoY¯À=ÆTe³j�¼`§jß«þuäìÀÿÑÕc¶°÷/n¤Á•:E·ë4çŽWP[£4/ÁþJ&D_Üzg1õ˜røÿ±ƒ‹;ÜQëøï^K³åþÁ­J;aA]ÆÅØ“;d `p+9â9ì¾C/n6�袖K£ñ^q~eùØ‹¯¸³÷ÌÿÚÔè! º®× x�E¯ólzñ÷| ¯ÂÈGÓ‡¯«×õù‡bŠ’N9E Üˈ8$NüNàñÖ€ãÏþØ×òªX‰t³�8|Î:묳Î:ëKT'ଳÎ:묳Î:ë»T3°%ò:ð¿©·˜«üÓ¬°‹ wYÌ®?P±ã/ f(P”¥DÎ*H"È"åy(·S~U@4”ó«S­bPý›[Au�ÔÐÖÕ 4Ù—ÖïéáµÎ$€š�mºàN2`À®�ÁdHÉÀÿ8Œ„‚PÌ9ÁÙ’{Y%jŸXI†ÈƒÈ®Y+°“>-µ©ùËa8€€Ñε!€µ›³{;bmjò¢ž/}׈R] ¤ÛF—vK!l�*ˆÔ@Ð�‘"kù¾4[{»HT€›\¶°J?¦*°m÷ÀÁ¬È¹¸ lë†m[7„>‡ê8ònŽ„`cFô„�¶„÷Ïop»Ý@·TÛ톷oßðXâÒ"vŽËr�ˆ! D"#ZÜnϹ`¹D,1€yqN¦d€b Ÿ’E ¬iCN¦&�K14C }ä”ZÁe ÄîÎ!"Èn>s B^ T�X– –¥ºPX,S¾â¬ÁHƒ€#oh¥˜›G%…À-7O¾ië’{^»:«yQs#1»l…p¹^°„�í™H¬ïkÙ;™x"�wI¨Ên± {›n"BJÝEŠcDÄ2€úõÕáÄÞ»̹€\.¶rc\п¶ÍŸ˜ˆ-ï½­Qtv�fÛæùXI&D¡9�ôÝÃ9„¨D€0-^,D¸Ô?%ËõçîgÿÔ·¿õ›ÿØíöü§”lï#�®ÔÁ.—’îú6jÙcê9:x9RÙt¤6†“©ï�&Ú b¾_>¨v*ßû„‚Aª£JÖw†'ãøŸÐÿ„V̼[©»¾‚º{Š¿¢F|+¨:õi³èLj•·u�‘CÐÔÝ{túÞ¨Áÿ x®Ê|íábÄ[««ìÈÎ<<Øa¥îÐÐÿñ *ºÇyQ\YÃòä—6ù¿�I`¥øžx˜g¯wTòç¨C8”ž{*¹Ô =Vºßnû<¿»bŽæx%AÌ@¼îßLý¯ß™ö‹ûü–P¬NDóùJg¨îA{�ÁdÂ+÷‹Ñµã•F ;L›×;Î�b¦ÎÜ£»ñt|Å¡#‰ÿœÝÉ[Ç`:yìÚÇL¶PÝþíIèësê �'ó£Î~åÒ4@t‡y ŽþÅTÿØ“O¨þáˆÍøôØ'º{ß;:ëõúôŸX‰°Â(ÛÂ|Âg�uÖYg�õeªóÎ~ÖYg�uÖYg�õ]¨#k`œö€ž¥[èW0­ƒî£j½‚ÿUÁL`,ǨÀT.YóR@gÑn¹Á©à,ü­t°&—‰[ÿZ# ªí·W;WL�½Õ¸³‹îêØQî ª ¥1ߘ hPAln AÏ[ïùï¦67+|sF fý?Ð�®êZ lÀK$S'’ÄYç;…;Èe{Uð½d×ÈaÉEØÈM ©¢–K^Ìv‘Ëù‹?…f›¿ÄØâˆŠCD¨ãàÜï�}}‡¦€Óz¯åç‡�°Û»^1.á¤êø«‹"¨Ä¡è\'ê9;ñ«§hÏĹE¦X\Ší'!r!Ji_'¥/}¤ ·ˆ–îÐö7UQÑ "QU#A/\ˆèÊŒ €Ë¯}ãWè›ßøå¿üîýûhÝÖŸQ‘ÐGjÇ�kŠ* 'š”«èF Ò ªyÒ耙ǪG¹ôþý“«€º¸îû©Æ{_šmÍõ@)}h»¤ÒJ@SGö�‡Â÷îò0W\h9ÞSGUóA˦>•©©tœÖ@´ÿwçÃü‡sž¹gßÏJ#©c®¼îú|ôOþ¬k³8cÔû:y'€ª¸¾3ˆÝr¿”,ÿí’úýÅñbp%Ðc•½w¾ÙÑ´€i¥>½ëËŸ:̺WzÈ?Š 8²|8Ö‹fÏÓ8ÊõªúÊfè�“èÁz~¤„Ö‡‡¥úå.6z�Ú¢ÚðÜ:¦s[ªÎ‡)òÂXú(’‡æòx«?躻‹í—´:€Ÿ’t0·ÀÝI /õð«ëeMÿƒ7þ68.ìÆê ;€ !bGx!*â‹7O_ì©?øƒ?ô¨ÈZ˜‘™ˆµþžxÖYg�uÖYg}9ê$œuÖYg�uÖYgý.ÝÉg¬ Öà{˜‘R±õ/Rü£³ê¯Vÿ{å¼µG R{G;FŒf¡ËN7ñ½B°g rl)7 ´æ¦K-ílU=VÁ<šå’åAÚ@;Ù�-ç|Ök窤ÕnI_ŸªÕüw 0ßâŠÍ~½¦ñ!f·Q.ŽÜdªV㊜=  ‚ò f)N ¡1Œ\š-¿:7‚E~—°mÜ©íð­6÷ÄV5ëøÍ$únT‹vl땚SΰªÒóÕc›KÂ…òEUÆWÀÕƒ¶fÿßø:�ßð÷µ“= nyÓ¦ˆ¿ å„´%‹XØ6Ün+ªR)p,n–OÏ�—§…AH9c[7Õ>?g‹?-�ζ¾Î»z³áç…wèÄžþÇFÂÒ„Öù™ÝqRΈ¡“ ®Wu±ÁÍ_[´¹\OÅ[´IÝ/�s‘DŽt˜‘›‹öq[b!7õq+SÂö$Ûü˜C`æ@103‘ùî’Xž ©‚ËW°º(hyÿîýÇ¿ø÷~î/¾ûìÓtÝÖ¿�sþÆHæÒaÇZ XnJå�†²ki¿dµ•:YàÐöÝ«ù©ƒ˜;èí8¦‡ß« XeÝ�±ýlKµŒÁ :ž‘Š‚—vQám¼�Š]Ý|ð Ý |�ÌeÚßE©Üû&W ¿O¦RÈ�ÏÓ{Á`²Ku d‡×^ËøßÄõªÃ®Õ�"Ôj°…7ÛýâMA^Ù;ºqÌÀšâP.7â@d"@4»v5»ü6¿Fµ¼’"F7i ؽ’Wаåë–÷yáGs¸×Cµ½êø3õK{·QLçÝ9T|˜¾ùÈÝ` ^ñ£3íé$ã¶Ó©�G„(=œÝ8ìõN†R:èw½×R�¤ë�1õwxBZŽEþºÛVïPV^ú-ešÆŽÌ܉ˆ§éœ£»ÉÝÓÒ# ûõZùù^tïšõçç�ýÅ—M$€Ù áwz?¾àãÏýé?ûÿË,’¨€ÿÊxE ÃYg�uÖYg�õ{©NÀYg�uÖYg�uÖ÷@™5y€_Uvóƒ˜ÁF½(W+XØ”³Î2œv BÏ÷ñÇTc¨8 ”/*Šx‘±mª£ú0'�”3ÒÖ•ß9¸ÔÌå ÷c©³æÖ(oïkVsW�™ F0P@¿H e§†àxÁ D® ´¨¢{ù îJ‚½v–wŸRrîUñoÇÖ `í $q@ˆ(Yó�(a6ôqkF1žB øcÄr¹"ôyåf{Ÿsú0g‹Hi¶$¶lò€ hÄ‚ à¤Ò‡)(ŸËµ²ñE¤ä0£©š1)©kÿt%·àºl1¥ÝËeAΗf• ból 7³ý�.¶ðDŒëõ‚ëõŠ"RÚðŽßc]oH9áùùÖH ËrAÎäœÁ RA@2Ûö¢ÜÎÎi‚™ŠS×¼zׇ …’"0 =ÁÆz¹,¦ gË•ŸÁq".„¹ 2ƒ†C1ÌV|¥àéx@KšcDûT±¡9�07ç‡ã¶1Ts›Ö‡¡Yþ{�ž€Ð£õïû+sú'.±í•—Ëëº5ç›·=–Â2¾rY?’l©ãeû�‹h‘êÒB%{!”8ŽÅi¥¼¾î�ª8Q`æ˜#›ü?UÕþ®Ê*– ‘s¾þÜÏþí?ñé'ßþ ëíöRÊЧº)š½Ÿ|ä] î+~ÑÖJútŠ©8²šªŸŽ“¹{T|U]?v™6rAwµYÌÃG°Ôx—7¾×ÁòÎ�§æ°ïŠv-àÿ€…;0ý%ð$bŸ±'P×UjˆIyÿ|yw;‘F%óCð_wŽ»vµ›� ý­eÌi˜f�xr—8ÒzÚÛ÷wàW1“+XIÍuBa÷”¡ñq�ý;�íЇH¤ÞE+ýÒ»c^q°oºqŸ–l#3L“”üg�—Ïðâwé`/ßÅ M¯GvþýØ@y:ÞzüüÔCˆü¾Bþ¸ =ó~<—>è›ch~¿ÜôUöÇĪ€ðéÌsôˆÿÙH¨ ÇºÞóZ8Ú¿ÈÝNú„èáµï‰Ýõ¤ï£tÜ?z/*âóàžòÊ%‚ï–Þþ£�>þ�¶”W‰™sàºg�0ÁYg�uÖYg}™ê¼³ŸuÖYg�uÖYg}—‹œ*»«p Èíî€õ@W Ç ¸÷–ÿG› ×+ÝJ~¶Vµ¤�y1.q±œ{2õ4Ðó¼kt€x+Eõn | uVM7Åto›]›�à ˜²óøóW0/m[i_ÉWë‹.fó u¿ è ¦¢NȲ ”¦ª¶[Ö°êþ!õ 2Õög&ÛWA¬ˆQ1*€ØP‚YÃ{Å'jÀªÍ ›Š8˜¢–›q‰¸^–fi^Aêm] �$»ñ/3¤]Ÿ�SËyÃ`UNdb*}iŠêmK“ À8ÿ˜¹�j^Þ¯·ZóoHË¥©ÊÛ/-ñ‚ËE¬'sjvÌ)'PZ‘Å~­‘2G–å‚#>úè#\.W¤´AUñîí[¨*¶m-Ç Xn7,Ë¥€ÓŠ ‹9OÀÀ÷,¹¸�´Z½/ –劗Ûîˆä×i°xª`”�è!°9.D,jîóvÊŽo.(?x~ÝIc®¼¡Ô7TÀ­Y ÐÝÀvéÀ�_Ë÷66Çããn? 1X<íó£�ÔÏíç…˜`±)=R¢Ùþ—c‡°ÈOO©†êØÏ1&ôB;,A�¥¯{Bqy`˜ƒH$ÄrAëÒË H¢ Zˆha¦ `_ªX ºX~îgÿ«¯}ë׿ù3ïß¿ûs·ÛúÓªò}~\pEïC#‹¿®µ9U!ª`-•5ímëGpeÈZž ÃˇÖ÷™.ZU¦ã^D„‡$7¡F€©R¯e²c?LÝn“Ú_Mnn0Úqn¼¶Éż`æ®xüo]Kލ"c¼ó«À¥ä¿Q@ßU··È0O€ÔXÐË9Ý…Ö $¿ þWÉ.‹@›ËB¿<Ÿ�­{ÅÿC µ÷G‹—ñsôPñê‰B}>•½Sî‡Qø¹p4ûÇ—v0ö0ÏökVõä>¾Ï­º‡e'å?í'Õ×N�þ’ [çË<þ<»Ï‘÷ÿ¢CYT?Pþ=’"�ùFoï¨E¯8Ö4�‡{8�{ä¼§¾pðŠŸêÑù0MºÉ•€†©¹›3÷ ‡ÃdèÀQöÁ"R�®ó%èkÆúu=w¿çÉñ ôNsõƒÏýúùêÜB†›ÏÝþZ¿öã?ùÎI6"d‹mŠ ãtÖYg�uÖYg}9ê$œuÖYg�uÖYg}‹æ Üš]ìô«’^rW¬V«újùïíþëa:€ÂÎR<6à=ûójé[³è™ �¶çHRTâŠD£zÜ@ƒ¼'TÂBQœK‰€@ÝbÛìù 4&�ŠYF|jBSž§ Û–‘ÅÚCD ]qÎÄ%ç7@E»ÐP]d‰iÛ‚©v•€€8Dhþp`\Iw•™¢”x‚BP±üh‰À²Dë�Àƒ>Wûx;Dí8]îT‰¸ÄŒJóš?D 1PKH cn45Ëâc¥yÍ+÷ ¿ûæB#.xp«95LýèɦÄg,ËÅâ cY"O`¶­ÈÀyJ[›¿P´>4õ÷o>zƒœ¬Û†Ëå "ðXq»­¸,7¬#”îsÜ©£c`ˆ qà#à˜ÂÝÈ4�ðÒ#â² Bµ¸äÑlè ê•ìês×ëô¨®k?¾£D¸’ŽŠÇ¼a#<Úˆ«’ö˜Ÿ¨û‡øq#ÊÎ cœ?>¾£µ!˜ëˆß뢧ˆGåü¹3t‰¸ä ¶”°®7清#BqRáB˜™Ï[•üÍ­¤¬Q¥â®@lQD%aÉ9¨h,¿{G0.ºzô àú‹ïç¾þíßúÍ?ÿüüügÖÛí§Tõ÷�ùóeïšUñ£Ÿuk:žƒ*µÜøïQò@xKѶ曹}Í’§ÑÎúu´"�æ+hÖ›^«™ì,ì@­N ˜ïÁÎÕí&Ãn݆ÙL¹m=r‹}pGz|j9"C+ôÎuì×±Nß×ñjʸz»}Ewª7¯DWg›_×ù¼gwliô[8'urz.²Î�yDÔ»Nh»?µ¹;vVþ#Ôs ˆvËCv¶ îºJ;wWuH~ þ¿vζy9™mÌÎxa%ik&.νu€‹Swˆ�$ö³ô%pt&„4Â,:úûõÿÎ~Á[ö—ú¡ŸÐþ˜­úïdÝ¿¸ >rLx Ó¾oô…=ôá™GW®G[U¹ cËi"}MŸ"üH÷{g¼J¢i~ùWÓ Žšù˜[²o燞æÎ^¡ª»5¢¯åWÜ€ŸžÞüG?øC䪺ª"‰�í þŸuÖYg�uÖ—®NÀYg�uÖYg�uÖw©f`ËÀÓ þ›ªºZÜW�9Fš%{ÏÑæ°Î¹˜ €\šªš —Œ°EC3•ÀɲÕÍ�]!ÈØŠêþ„s`:*\ÕÂÊׄ\æ}%,ÀH*yòjpÊ�S+¢ƒý±ˆ@E,>e¤B2`0”ûƒs¦°}n°¨@’Ë»UEVÁEÌþ›¸’Òch楃� ô ¡X*£åÈ‹$EI]lÔU;X]mÐëØV›xUg¿Žà¬vôÊ/¦ø/€4 œ³a&šs¡ëƒsÞwt>ûÐÆ/š¢û ›z—ý—éîæêœ­žs¶¹ž8¨— !.1\pY"nÁˆÛ¶YßgAÒT²ÚíºIÕlåã‚ËeÁÓõ )'\/ϸ\–¦—œ�D’6lÛ†eKˆ!v~Cy¡Jˆ16wŠª.�KD¬}­@ÊŠœŒüRÝB X– –h¿vm…¸²n+¶-•õRíäH·ë×ÝXÛ¸™3DqºtØ—óiãáþŽ2òÒV…veî„1,äÁÁ¢ÄO‚r›NÒ€Óc¿�¨U‰4õª‰Wôs>0‚†1[{:Óèj²Äˆe¹`[6Û3¸;ÄX¾‹>ñçt}IDDÌÌ‚ê".¤e¦@”,.\)AY$SNrÎQD# À °]ý¾ñÇß~öÙ_ÜÒöç³Yúÿ¾A±OƒÞ,ê] ôЮ�¬²£†ª|0g—8¶YªW-k=FÅ4ýÞï�ÿ²çj•„ÞkÎJY½ÃUØC,tW¡z\ÞÝaxË;£á_ÞÜZ�ú_*á­¾ZZæ—–tòJþ=i üï:´é×£lùi(‡k¡Úc4¬éº^;±aguŠc°Ÿ3Ï8礫M¨Ä�È�nÕ]€†�™Àé©çGä±£|w»ÆégнsE§¦î/}Ð[¡ÏÛYõ¼ÿ`÷2øïmëu¼îoyíôwc«‡½¤wÖæÎµã¥u6¿uúþ«WÂ�*üѵêîUïlŠ"ÇÝŸ[tÜ ÁЂöØãyzRÐ'úc’½tô{Ä }a;–ëÁ“»Ï\ãQ<¶~ðv;Àƒùv0|ôÂôzݸ?8ß«æÓƒ1ÑÖ0Í»Îcw’/PúÃôGþwDôÐÍn3 ÍeíŸ(ÁYg�uÖYg}©ê¼µŸuÖYg�uÖYg}êHÕÊlªmr(Ó–�J~»ä\€ qo >€€íL ˆ�Kl‘F&ˆ ¼¼@ʈËD ”jí%r6ïÀ+çA–ÜÀÿjýoÇéVò1†FXÈ…< “dË«‹«u¼¨ÛbzÆülK^­¹€¤Út�ªåþ§´XI‚°¤¦pÏEE¯"‡c×ÒY?QW%׬r;D—…i D„\bèŠy$g¯_śƫ G8àhÚ¹òI�DZð×1ƒÆžPr0smüwà4Dä<ªÞ™ ¡�=j4…þ=qèñ©´×ŽU\˜q¹\š ¿äÍæL!­¨f)˜�Ì‘ Ì�ËÒòàcvc°?Ó–ZlEÎÆæ_38 ¹’XJÿD¶s•'ÜIy3Cík‹¡ˆÍоŽÅº­xÿî=¶m-À;Ú=Ìžn. Üæ)ƒ èùô’ÇùÊ�Ûú�Átª™öÚI6�ÊÚ/Q\ÎA°� •Àÿ£üã²G·ÍT'£€)[yr ˜pæ!jfþûU2ŽrÇû{èØžûÇ¿ì�ºw A²äd΃KBuâi{o»þº6êý¦Ä±ø{ÅÐÝèùë#pF;òÕpY�°÷R�ý8ª¬ í:rŽÊ!,ìoÀ…”àb¸ç‹Ú¡oÔǾ\g»ï¨ÏŸ§Cðh�x¢‚¸Ùm: ƒŒw™ˆlSS}l&—û–…ÌÄ�6†ª÷•ÒîúBÊuŸÕã~§Dó>¿`ƒÿw[uðwzøZ�‰ §À.}ZÝ4^É(ØÓ~ö sŒÅŒ�N[Úæ5îë@W}U>ÉÑ9õþyõ¬OÓ\~|¾»άƒîí§:Þ+”^pjp¡ žÜB¥ïU©ÿ}º¼Ž«W–—ºlxÇcŒWÏí×Ì :äiìÎð’õ„–½Ì“æhGs+ç¡a,h×>�¯OOÿÑŸü©?û_ŠÈ;ɺŠHˆÖYÎ_ÒÏ:묳Î:ëKT'ଳÎ:묳Î:ëw¹îYZWÛöŒžuŸ³`+ªhÐPbÄ� Ë*·‹jM;ðËÌX¢�¢`U$+rÖ¨ç ˆëƒ’i^Ô– _U´U­O`!䢜´× ®å¡ØÖ,á ¨_Õ‰-o¹þ=Ks¨m¬À½á6f%^-¼«Í¯Þé{* X�¸ jyö!/ XUÅa_ôq•Ö!D0+D¸FýÁšÓZë@L@.KŸí•A™Ëx޶ßý‘ å�×9SÁÿ-%¤-!çÔ@vnVò~ÞÔëèc‹6d¯`úrY°l R*. 5¾ €ÿÕZ½Ÿ]?Y$E\ìבJrÈ9ƒœú²öé—"¬Ë‚°mH€®ªø ôr( ý 4±À— –eAÎÉ©¼ûuÛ8±¡>)Ïœ¡js"Ld’œ¹(ûSJH9t ñ&D0GˆlÈ9á¶®x÷î¶u5P?”sFG–pöÛƒC5Ù5q(ë逌2ƒ`õg{µ¼›¿\œ3”‹ ?ÛMÙÞcÆwQÄ[û�{,S[Ggèûÿ8FªÒï…žT§rÈ‹˜�ýi”ÚšÕê:¦ÞÞ[cwÀð¼ÔX³šØú�®ÜC*ÛÇaïß÷†Q ¡‚ø¯“1ÿÐ_:EÐázò-—rÎ?4�çæÜymSú±%ÿü?XÍ»f"Ì=ò MûÃ#𿽖ÚúzQ]¬õu{eú8ŸÇÙ³û¶îaæQš}_§Ý¦Û´Öï†4� õù3m‘Ø)÷õn#”ôuqô/ÿ€‡$€W¼û‹¼hHº ýy÷«_�É4í�„Ýz«ût#’yRÀ£¦êýot§–Ñ“_Ûmcbü¶¨è?Dú¯�—Tû=`CwgÉþ_/·o?ψ(ýÈWüß^âò™ˆ¼Ë,kÎY*@qn;묳Î:묳¾,uÎ:묳Î:묳¾Ê+§ùÀ"»VÏ?ù:(P¢â"��¶ YúžÀ¸/ ¶mźvÛû”²#Œ6ÜLèuJÙŠ/kÉ-øÑ¹ À,êBHÕ/×öл¼O ÝÔìj_õ�#B(JôÖPíƒ;+{.YÝÕâ9å   %ƒ¾‚šD`®Jö0#¼êPHž€ÙM{D�sl˜¿ <§æ ù>¨ ïððPJ¤Bq`H9c[¶mEι½¾ö{T®£¶sš�Á“,Š@54Õz —˵©ÝsêN\€T³ÎßG]PµÇ/?¯jnÁ˜…>÷±âbýO©³ÔÉP�´ºÌEÉíìþ[„FÄårÁÓÓSWlnW…�+†âÄ€þ0Ôœ*ˆ]ˆb‹%`Îj$ر˜BYÛºáùý{ÛµFc�\Äwþ´MÅ)füŽ {¸ÑËu?�î® à¿Þ±bogoÖòôʱöQ zÇù`<¥¾rç¨#BêO÷’|¤‘èÀW8"ì/‰È­e%×îYëwi?wöí)?&ìò?�Nü¥~�þvï¨óîíoÝbœ»Ëãq? `î4Úð|×”*}`ÿêN]¯4¬Ê²6Q"<^ÙÝôÛ0ž_¤/ôm%hÙJéØ]€v›ï4f|Í›�>ú?ý¹ŸùGþ+U}'"7Î)3‘&ÊÍ… ¿#©g�uÖYg�uÖw«NÀYg�uÖYg�uÖw¹F ¼ç¤›• ˜+ UàáA@rF–là~Ê-Ç7.Eá„X-Ú„�Â!lHÛÖ­ñ%5et­x°ÓŽ16�5çdÙì"NAR]ºµvhêó(A˜»ª¬=»ï`oÎ]ùo0³Ïç€à³»É}Þî¿‚Ãõ�¢d1å ,j1 µß8BL¡«4vnvÍÅU@Äœd¶dL†#tÛòyLs6{ù dVPš‡�~­ªŠ´øŸRê¯'**~ñM9ÏíA°�)@éûêX R•�6Þ1\¯ë—Úyf›ÿ:Ö5– ÏõþUE*óCT ‚2W¹õ“½ÏÙQ—؆vL±ñ0Ëýh ~Y5B#ƈëÓÞ¼ùÈ"²–h€Xb¸(Á¹] 0šm½ Y¡‚ÿ[jꛚ…ìBlóG€”ÏëŠç÷Ïx~¾a½Ý¬_.0b z;ˆʺ#T¢P[—bQ^ý¿WgÎ{š2×Ï˪ðæÀ� 0Â6ÏH �\Âwy›ÒÔ]:x²ÒÖ d«™ô 7~;…è¨þ?T_ê} oV��/ÓÉ…F÷×êÉ@^Uï×ðtüDáÀÿ{íí a@Çï€Òw¿*çQ·I× ¹1: ÝJ ȱû’¨>èRç*MǾ?eÇc€ÿêòãý2UÂ+p==Øc¼%~_µt°÷û«ÜƒúL¤½Gèþ·•lù÷óêhŠS³„×Ç%C+úzßüå­~|�úõP]}ȰC~X(ý�ÑÝoQw_ërƒºº\¦ ¼Ô¥G/Ÿlñìñ©9'ô Ÿ¶ÿÚ ÇC>ßÞhº‡ì�í½È+ßäÿqDš¹c°bd8Ú�splø¼´s›úÍ¿ô—ÿÚ¿}¹^Þ«ê-§¼yRh"‹t=Î:묳Î:ëËT'ଳÎ:묳Î:ë»X3Pfßã Wà¼>ÈoV÷Õ›÷6î¦Iµ‹šEùJü×,qo-k»�Ֆجø‹Àq°«çþ_°\Ä`YÎ[*‘.ÏP0qkï¬x× ˆ¹ ^SÚsS–ïÁD´g`\Ûª€Ù­××v€¶¶çF�)#ep…²@3@"�ÙÁ@¹=N·ö!v;0µþ“’² „<Øÿ{à»ön(c H)™•±˜ÏÐÁõMý¾d{ŸÍƒÙ-`z<Û¬þÃ[ixoQ Ò^[cªÛB%«XÔ@ïëyì#‰ø¹^ÿÞ•íÖ' u@÷Aö²zZA$MyË¥M2[yH'ÂÆÓõŠõÍŠœR#ÜPk/ €JW¥� ¬Yÿg¤”  ž£’B*€-ªHëŠõùëjàÿºmMI¼,—€13–`$¥ÙÙWKSÿ+ �û ïó{Fu«˜AAšIA‰[„rWõ+0�KŠ€8÷^Õo}'»ñ÷¯™­Ð�;k~ãñ”ãK‰HvŒÀ�Æ` *ʪÊjÁG¡þ@PÕÊv©¯ Ÿ}úÉÇ¿ðó?÷'>ûôÓ?u»=ÿÉm[ÿxÎòC=—½€«â°ž"crdpý°szñŠë¶–ïƒ}‚xx±õNÅ?ë@Å«ËGP[ï‚-4¿ê÷Ô½¼ßû9©’$ú¤6BUé# 9ÿ€Êniq£øÞýár¶ùäûÖ9ôÔ9îÀ,lq}8ƒÿÝr¿ªèin�æÞÀÕÿÍZ]þÏóˆœ Eµ¶WÝI‚ýÏF«jçë�òß“ú4šé)4E¨‹ØwAõW»×WÚ•Â~¨[Ò@Op{"á09àAÆcði×�û©¨x|~uÇ®s¬NïìC´_Ãä:dÏèÞAô²Qæðœ>kÝÇYø}æq3è`è‡m‰mÐÑrÛµBñE<>·èz P¼.>@é…¨ ÿ/ÝGjí]Æ<}Õ\ÑÇ„W%F€ûg?š/ôŠW~ȈÞKfQwAGñ Ù…´80½ºÁ/ß#Ê[ÿàøÁÿÍ�~íëßð,"þc$Äh8åÿg�uÖYg�õe«“pÖYg�uÖYg�õ]ªäò SqˆQr³€ä°, –e1@Ïë U55r=SæHWBU±,—f;Y‰Ä¡Ó(JbšÈ5+ûr�X¢ûÈ,Ás2ësÛFT¥¸* yÌŸG97àrÍA‚Ñ¢€•5™½:Sw!¨ü: Í5»½X�§”R‚ä\0ˆ:9ˆ«Yžë`EÞ�üXÈÜÞGCäAÁe¡’Ë7©'qˆØõe¤Í"¶uźnæPÓ#ùíºj¬A›KL-¿ÞÛ×�ýsçQh9† �bõNÜÉ1!E#*ÈôZs¥èß3«÷Œ´™U{ ÁÔÛ¢U~Ý,çë\É)Å~FNÒã DÑ%²´Ž¨ vJ ,lóÙæÜ²,xzóUÁº® ìQÑfÓod›âF �D2(ÎKn}Î�DRÏíç{–„uK¸Ýn¸ÝVl«‘$ (k³ºmIJöÀ«ÆDU;~ƪ‡‡}fŒ™àáx€õëKek‡¡¬Eo^3ÖG’­ë|>úþ<Ï|ß²#+ÔöŽÄ…®z­ócÛV‘ ªQUcù]7Q¬_Ì!ˆDˆU%qÌ9]¾ù‹¿òµÏ>ýäO¬ëí�oÛö’óŽ† ^VWÕ k ï�j‚?»~è”åÝûl¶_4ã¸�ðýþàËÍAšG-p—ýAjÿ´»Bï›îú²ƒqûÅ}�é"½­Òìÿ¥õk_ƒèQ ‡ÊÛÃøí}]ïLÔÜ=üÕ�¬‘’šå>0€ÿâHÞaÆé{P^ˆXë¾3¤KOx³#иÞvŸGæ˜s£v„”q!»þ]!ìãùwÓæ ÷[ïK¯Ó&÷üþÁ… 3ƽ‰v{ÔkpÞü?RÓVþEß�ÔÑñÄÙ¨[;Yè ?Üg‹½òþhA|0:¾Ë}׃µå>Øw˜Óz°!‘#¼¦žØF÷ºýC>¤?ê±ÕôÂg©Ïõ;Ís}Õ¸üNÔžv¼Vè�ÎlAÐ�ò;£æÆÜ5a*}M÷ü΂ÞóµÐ£Ë/Ž%ÂkzK_ú P®õz}ú¿ÿKÿÊ¿þQÑw"ºȬ ¡°%Ë=5Ÿ$€³Î:묳Îú2ÕI8묳Î:묳Îú.Ô‘­á $f,Ëb€™r:ĈeYpYÄeÙ9HÎH¦„¼mȪ Dp«B É@Tq½dËš—b¶O\ˆöUIJ°^Ø 1"Æ¥ä¬W•³B•KV;µ÷¨jSJV+{`©ß«W¼w  , ´º 0#@k·[ïêÒ§âv`Î Å]„¬ŠœªR>5¥»8ðͲ˜«{5µ8s=–åͳS�Ã=Œ'íîk{Æv{(è3Ð�‘±m7¬ÛŠu]‹@ÞYDwð»¬qs¨ãSzº¹vœTî2áûœò²k{wŒ˜/ ¬­€øÐF6üñ #„aþsQÂ÷ïoÛ ªŠmÛ�Òj¶ñ°9!bäÑØ#+È”Áëºèç€"®—k#l›�ÿíö €�³‘cBiWU¬‡@ÙFTA öÙÜ/)e¨Ø±ß¿»!m#Aº�ÁÅ�) Ä`tͯ€A�9+{ŠY<¨ÿç=£¾­’bD’ ñ#9‡™À €¹1¶¾‘¾T{ÿ5¯·i¼Fn}ÀÁ» d'RUJ9‡m[ú®1çs΋ŠD Eb^B1ƸX$ç7¿ñßüÚ»·Ÿýäz»}=¥íÇrÎ?¢Ð Á©Åi¶æïvÔ>¡ªx»¸¹Ç´X'Tåÿ$ñ­¯©Ä¸wð_v€lŽõlz qÑð·N†Rró³R½ËUu-;AêÁY©ƒèìúNUÞÔÿ:—Óx¯´½^!P¨˜;†B â…ÿã}ăx{Ãx »Úž?ºTwÒ{ñùÚu¯nnNã¾]±}Oªã[e£2í±ý^®À¡“̼PIËZ½3_¼:¸’²êHCü4{üwãÙg‘]Óλûê?Š5˜æýH�yYÅ^çp#º Ê~5i��é‘@ê»à�wþÓ~§üç¾�࿃”½5´‹=èë­G‘è, ?”ÊËt:D"X»ØwP»qÀ\%¢øµMíÕÚÖÊØnJ©�¯öd³ühL.!ó ¸§Ö¿›¢~/R�$ÉÓžÖ\D›ò–y �2´‹ ø�e½ŽÌ�šY‡ù¬ƒkF½‡Ó=\u }8ZêIRØ�Ñè⺇¿ûŸ3æ§Å<¬]ÿr¼/Þµî?º>ŒkÒÍRiŽpx­ Œí½ëzõáÆéþ¹IyÝËŽ‚Gvy¯˜K»SºÏ8¶OÒþV|o”uÇ{‰³›ŸÛ@aŠ›¡ñ»Û«_sžé¾¥ƒsоfõüÿÈÿâOýéŸù{ªòNr^sβ%�Hj÷7¤9ôõ8ó|{”CoVÒ½ñJú¡«¾¾ª£´çÃÄü¯îOzåZÕN–y¬þ×]Ûušú4Aõ“¼zm¼t_¤3øEŽŸ¾0F·€¯|ß÷ÿþÅ¿õ¯ÿ‡€~*’ŸSÊiÝ6I[~/é÷Üё鬳Î:묳Îú½_'ଳÎ:묳Î:ë{¤ @«)ûmMá2z`-ÐÑ€â-æàò`G¡H’€uƒ(ÀlÖøíöÃd "SlöÛ I���rŸS.`yµ'g­Ýú½ü„™A ·¿¸î\ûçÉÌ@wU@ʃ5q.€y‚€0Ä„âXp)‘ $µ�ËV%¾`+Êû¸l¼áv#P6мö¡Ø QäB°�\]Ò.ÿ¼ƒß|çÁ¿Ì„!;@qTX „6%·ÿq‰S{ŸSC4AÐ.k³á¯X‹òœáâ¦è¢p¨M™kŶ_h—/jKæ€Ç(€N fŸ_ŠlWùBˆ0E¹¶yÚæQ!gØ5§œ±ÞnX׵Š˜=h¹ñ)ÙX¯·[Éž_±- .9"§ ârÁ²D\p�p�ÅhW"mŽÝÙÀÄ,¹8X„ƒˆ¹\Š»T›í ‹‘ ÈY­_K|F“�Éú¸ª2ÄC0* Îù †�ˆ!…ÀÑÖoJ�d!" D­NKŒ¸\.ˆaiçïûO'e! Y›˜ÙÙå·eD"ŠDC !0·£ƒûQU#€`Jüä“O~à¿òK?öö³O¿öüüþëëº}-çí�@»5¿íÄSŒ Ø(ì�2tU'Û}õœãšÕëÔÿ´†“=ï5Î3¸O»×L�òït|<¾Û_éãŸßûéã¨�ÙÙ˜üÿvñ"p d ý^ág"îÄ� èi{Ü7RIÛ£'EúÜ~£ÑõQ WJêî½DþÎC`»�¥¨ö–Þ#@Ãö6¬4: ìÞ®R³}îú±nÇ%ç50G[ ­÷—ñ3ÊØ¦F—Î]#ç¶@ ‘<ã焊»„®Úž °BÀC$oòiú[È@tÂ]Õx›ø¯þ�� TG�¿þ'׃uÖ÷º“[ߣ)ôå€ôúSõèZüvoß8òz8¢ÝC®_ãëÞeýÑ[ïçÙ;wOx!.áQ,ÄCxõîìÚþâ–~ ¿~ïíÏ?-Ÿ×,Š)ªEïý ÖEÇcAÝ\|u4þ#Nrè1!¯¥œÐ°˜÷«O_7‘êr½þgë_ýoþ¯Tñ™ª¼K[Ú¶´¦õ¶jJɹX…Áñm$ôžuÖYg�uÖY¿×ë$œuÖYg�uÖYg}•:õ§ÈûU+í\lë x€¢0. ðüGœíjN$«ÿØJQW«}bB(VåLPjvÞ)‘S?v[Túƒ}"0BÎjhVÊ5æ ‚ô¡(Or±4Ï’‘Äìï¡2X|Ö¿[Î8`8!J,–íËrÁå²XdBQC›ÚSš;�µ¥ÏŒje¯%=›<¾užYÞS±‰.}_FH=’A¼Å5*Šê˜‹äöºî E%~A]‘—èH]�]ò¹Ì¥Ÿ[ÿkÉj/-˜ÚvLÛÜÛ›³8µhö™¨�¯‚ò¬ É\^—ÛÜæ­À…`çd5@¼:"H!¨øÔs(2b‡$›;Ûºâùý3RÎÅâ4 ,6¾5ú¡ºWäœÀL…L²@DpU5 ]cû«KA½^"”ãô¨�j¥¿m[SÔ0×G 1Ç`C÷„¬ $›çÊ f1W &(¸xc"ZˆsâG0 •…§¹ÐÏŸÙ[ö»þ”ÌÁB$öô\âRÞkd…:ÿ (Î\潨€s'ØÊ ÀÄAUCù"Š ]ˆi Ì‘™"2û~Õ¨ªË¯þÊ/ýáï|çÛ_¿Ýn?¶mÛ×rZ¿š³ü¤N1Oh“…¸·ß%§º''2ß‹/€Ìyá£ú߃:^ñês{ñzê0p� 8záþ'å›ê¿ñáª_� æP*£ »6z·…îZ¬-EáÈ*Ÿ ö„³±É³r˜ÀŒ¦úçÉúÿèzì¸Îº¿ÜóŒ'­}-¢Á©ò[+D�r"ÚÚ»³sÞ½ï“Ïd a¶9>vÑluV=�“A]ïZ3)×õ!Æ®�šÑïwu zÀ¿õ¥‹ÃÐöÙDÜyîPaJ¿Ð¤˜Uèãìnõkó1~éÐ0Gpx/œ{õ>Pø‚ßwÉL×!'ÁƒÎþû÷æÏ¸çìMÙu˜?¼ö‡÷è´�´Åï¡G3q��½óýÁÖ×ì¬þéÁ›tæY¸>¬Žã>±›—mßrÖ÷Ÿ;¥W½B¶“;züŠ~?�ዽî"n‹êM*WZ›~ù—MÍG„ôè–×ÞŽvJ8"È«~{k{÷Ë$›GkgqÂ!#â%†Ã/ÿÕ¿þ7ÿÍ�¿òñw¼Ï)­[Jùö¼êíöŒ-mQ0,Q̉­~Nç&8묳Î:ë¬/S�wö³Î:묳Î:ë¬ï¡êÖÆº³gôöéTlãè\`–ä¡dÞWkøfK^€Ï\@XÀžýûÇK¨P À-³8›'û@V¨¼ºÕ³Sq×gi0!fPŒ ¤_. b蛊8glÛ:¨’MU¯Î.ßÀ…9k°<ËËeÁårEˆ¡YÒ§-!mÖµZ�gY¶»µMq®�žûìòàÍ6¿:0ô1È’ Ò-Õg‹jŸÝ�E‚€•ÚÏK5Ìz½Ú¶‡`î1ÆAåZ¯ŸŠDNy˜7U?n¶õÀ-Wu7›‹@ÑM3MÇ*DŽ7�<<œ—þ�ó¶Ç0W׃É=ö Ä€º³C’:HVhVÔyæJ@k.ó'KÆ–V¤œq[W¬ëÍD‰%"ƒš•s�ÈÉ"T„Ë’¡*å5%z!Ôõ¤}ž¦ù�{|C™·Zçc ¸\,Ë!ô¹nó'A�™Pæ+8bè± ˆl–ý"ЬÈ9¹}À •(@I?îꎭຶ4;Ërb&&. ])Q‘ˆ2±2 ±±i ‚‚3r• ‚ý‘Á �–÷ïÞ}ôÍo~ã'Þ½ýìëëíöãÛ¶ýXÎùGDåc›�]=ø|ñŠÍAwÛlÔñ*¬¢©¦ PIz�U<û;rÁˆIiCq1¡Zº{«a- su óÅáÏÿï6¢õ줕‘ dí¼£Ú¥9³Ý.Ê¡A©NL£R]i®8žH �‹Œ0´f>+±ƒºe{]ÇRˆaÝRŸ†{oUï«|+š¿Ë°/WI:¨õ+,W癆DáVØœ‘~ÏÅÎýûœèz¹óë5Æ öJ®ó×°ë¿þ3^GÇt1Ũü¯ÊÒƒi'2fÂ7rȽ$÷ÏûyÕŠ=8¾',4·íÎuõh ïúàûN�T´»¬Õÿ@¼Ð=éHõ`8õŽ Ø­Ú¯·qü°�³xÅzŸ&×�×<Ò´ï}NF|~ìËNñâ…˜€—v·Ç𸋕¾š¢Jšúˆ-À«ìÞûŠîŒŠ>¸¦ë+à‹åÞ÷èé^úÁ ¹sm³Sþ]JËà¾sðþ{çÙñ8ŠÄ�Îyh¸ðùC'^Q}a2Ó·ÿÔOÿÌ÷«?úõox'"ë¶å´ÞVÜnÏx.‘TPEŒ±ü^Àí÷>Î:묳Î:ëKU'ଳÎ:묳Î:ë{¤˜¸ånÀH‡ u)–õê2âí8Bˆ~ÇÁÁú«À²í)HPÝ&¥zi[{=·)1y°™¯Šçš#_^ôÍ9™Ûã÷ðVÕéK´ä±){¦»k�ÿ1.Åö¿*ÿ�Ôá�_ëAÎ¥Š:¶ö5%x‹œ(jòA­,@��wh»võ Z—ÃMƒ�3�!í¼ š‚BàN°ØësQEPE äl wqhàÉH$"(Ä—¸€€Tìë·”°®IQÁ~ï¨ÁlN×ëµ�Zàܺ’•K®x�¨dE¶-áù¶b½Ý9щ5j�JŲ\ñôtAŒ•‚…´÷ŠxBn]W柒cÝ÷üiŽõ5bä�àsw÷#8E©¢™SN¼¥5(”ÙòD‚ˆ°hå-�ˆ8„ˆ(,P†‚ÄÌD$|ò�ßúƒŸ}öÉßÖõÇSJ_Í_“,? —± “šS›»G½ ½?ç2ÇÈ+Їì‰ p¼RËüî -y_ö©ˆ¾¯Þ‘ »¥ÌÚ-Z ‚•„º ~½ü xeæ÷}ioÉïÆæÈÃÚ�è—\ÈŽÑ;Èß©ÿÕDêCÄC�øØZÕxêHÔööê|QgzŸQ9,a Þ©€ôJŽó½×!àƒˆêíiÃÔ@mÿ w\Iö}?œÑµ³Zz¬ôÀóØ?¼Ì9øØ>ÚÇšXÚ§ù=ðŒs¨Ù;`ŒE@‡1Žr¤céž49'ùÏ=Ã\TÅìp¼~ÈqXtèóFÒYõï7¾É ÈGàÿîæ×ý½áîkïµA÷yÃvÖbTâ‘{ð£V�}Ø}Ièpxîìsº_±:�14€^ÚAKïoö¿+çŸ.ž^á�ñòÀ=šA£;ÊþO¹#�O÷ Ù}žÐîtذ–Áþúp¨èwtÊ=‹éí�ýøŸøïü¥¿ôWÿ?!ðgP<ç”·­8RÝÖ·ÛŠ”¶6fa Ãï›g�uÖYg�uÖ—«NÀYg�uÖYg�uÖ÷Hq@’ŒêíjõB(õ€f—%­Ý\Ç˱ä~«À¦*ŠDb `NNŠ ˆ0B´è\¾€®X÷ঢ?8²çiRv§=:eâfÍi1¦ü¿Ä¥dÜ»ðjŸ¾nØÖkZðŸsvà> öîP­å«¥{Î )14„þ¯xÿþ†Ï>{‹ï|ûÛøÎ'Ÿàùý{¤œÁLXâ‚ËõŠËå‚åbÆÒ¾šƒ^¯Gœ‹‚ZKg8…©:µ�H:àÀ[;²¯ªÌ©ªÿeY°\"–¸€ˆ]S±u/ý×óà·2Ìå D#„â"Àl€œ¥ƒËÙ)m…  ’ê¼3ð̦«#0�Y�FZiWÓçzû‹½¦·¯8P$¨B‚Wí+‚hÔ6ë\!BD±® æ`q Ö.;~#Op@ˆÚÈ-öà”±mT¤Ì]‹¨D�ž“jñëºáýûg¯Ï_ùÕ_þåýì“O¾v»=5¥í«[Ê_…æßç®t¸è�#ÿ¬Ð›eå…1;07hn× ?¨ð‰½#¸5z¤*ŸmÇÖêh5>ÆŒ×Û¢,ˆ�‰A$Ö»Hùÿé=ÛazXy bRþW�Ë©ÕçaÄ0L:Ì\§Ž™öUQë£\¯›úßE·´‰ú[¼-}g]LýÞ犨"K‰ÒÉÒÜ:ˆ¹­Ì®n(%«zŽå©V÷@uŒÀ˜>‰ñe')Õf_Átq™òžÐ0ŽÎ“{g��‡¢g:ikr¦^£w°¯ È–ê 1£õ‘Ï”víhñ8\­ÑFÓUí•î®Sýœ£éiZ£4õ¥€zä=üÅù~y ¼~¨:Ÿˆ ø?­Ý~->Nã „àúìó‚w¯�¡yʾ\�¢ü!‰ÚŠL*tŠQx©àËЗÔmúçÃ`"sØǯ™cîG|ÑÒ]›^*Åý¹ø»RúÈÍŒT!=v2™wJïlò@m?6ÇGõÏôy|^ ¯×9D¯ó”¸Gµ ¢Ûÿ‘¯þ›õ¯ÿ�ÿ,,ü 1ÝrÎkÎYÒ¶aÛVlkBJ›9†�%ç«NŽ=Ig�uÖYg�õ媓pÖYg�uÖYg�õ=P$TQÉrWðŸCèN%e ±DÜÀÔ ¸Œ1‚ ȹˆb  )+¶d £ˆ”|f—�ìÁ6§üöjûþعꅻK��§NýV^b×——ÅÀu*¹÷Y¤¨¢íaÕšVSq—læ nVù–3^°�Ì1`]7@f†HÆóó ïÞ½Å'Ÿ|‚o}ë[ø­ßú-|öÙ§X·²,¸^¯øè£�ñÑÇã+_ù Þ¼ùOOo@;8PUþ-ËÞ€‹ªvôÊ×N@S$B ÿ ESÅÖ—ÔâPÁiBŒlr\°\T 8mDåa^‹iȃý|ugˆ1b‘ËåRìø½‹B±æÎ�äQ/%ð˜«ms *Îsf+û °™Qó­k©Ú÷�cD%(ÔyUDUèÒÝêZiéîxõæºÞ,Ó»dy›»#Æ b!OT þëE±\.X– B¸Ýž­ßTMñ‚‘?Bq‡\æÖŠ÷ïßãÝ»·x~ÿŒu[Û¼\â •XAް`)±1^Ê8yg�:TÜÆ…¹i öiëP²�ÃìPûP'u¯HFNýo�М›íy`B)3€ÀD‹ª.9çeÝÖ%ç™C$¢…@¬‹d¹üæ¯ó�½ýìÓŸXo·M)ýhÚ¶¯fɨ8€Ô­eu¯‡4?g<€¾þxúø°sx =‰‹ð‚úŸà㦥RVKyï¦[<&Cù¶Ìn ~jµï·]�¯¯Ï•âR¾¯/Ž·¾rÍ.#zl8s'.€Úž¶¿D¥‰^7EÎìÇ{w²â/o˜I¯ZGC É}ÀÑíø>YàÃIs§Óí�þ±¯þ�ÿÆßü—ÿ“¸,Ÿæ·ªš·œsÊGµ•X*ûÝ ƒ˜ÝçwgWtâÿg�uÖYg�õ¥ª“pÖYg�uÖYg�õ]® „JŽ{èšý!‰ÈlÊ]ÀøZjª] ¡)Ÿ›C·*À”‘f±¿®Øx¾é�³<ªg�±_†ö´¬râö`·Ú(ƒÈ®‡»Í³%{Sÿo›=¨Ú È–œt÷øé”8�w È9áv3ûÿ·o?Ã'Ÿ~‚ï|òm|öé§Xo7(€"®OW¬«Åh¾àz¹4….ÑAØ7ñ�¼ê±‚EârfëƒÃLÐÇ9Œ}mdïôÐëKc W)qNH9µã‡ÒÕ-"Æ�r—{¤„€[ÜÛ$•$�'Ûùª”5Ë~U… +þÅϺcE�*¨¯ã°`¡ €s'Å´ø‚2 áaK iÝÚ|ÌU#rÀr¹àr]ŒÍƒƒ­‡ëš°ÄØ@GSóçi g³ýÿþÏïŸñþù9'.—˰n+!&.± ˜ˆÍóÌåæø‚95žœ4Ö^=Ÿû"…R«Ž�PRµ/‘L9×/!)lÁþTe5KþÀ’s^Duù�ßúÍ?ôöÓOb[o_O)}-çü5ù£®m_rýM¥{€E¾F·zß>÷䯀ªÁÿ4«òÑUÊTFƒ>øèÌ( ji8õ…€V…ÂE0L¯ŸAf"½ãRþÜ™ÜÉÚ¾Û‹úoRŒm­nõœ�LQ÷µ~÷ #Y°‹b8P“'HatޱýÀ€i�Êt4õÿÞQn þzÍ)FJœ�E(.;ÔÐ>®Ç'Sïó]¹\-ì;°äzuÎõ48TìÛ½G>[?·Ó0çç�9ÔúÈE@æ.°›W#0=‘JåÿÁzuŠîü·¨ÎÖqÀäýýŠù­Ø[Zë@4p‘°}Šè ³òx¯$':Úæø÷�!fD0iPüÓ(^W}.«#ág¢F|ȧÔ{—†# ™>ìð°öù¶×8€±¿i7 |¬D]Çå“ >—¸¹�Xf Ž©¯éÅ,=œé�°Úa¢×¬—/ÐR5òA·�;˜»¾²? :]2ÑέAÝOüéÇ8h˜Þ;Guo¹w=¯EÔ àpÜó” ÓóW¿úcÿ£¿ñÏÿ­ÿ[ áÓÂ{Uܶ´A5#mkSÿ‹¤‰…ýÞî�'ଳÎ:묳¾LuÎ:묳Î:묳¾‹åNW%´WAVKîö3ø«BQˆ‹5wËxw')*Wæ`2üpYÛåŠõ²"¦)[üÀÐ&óH6•;¼úß+H»óµöSsÖTx–h (›}> ˜¤�)™rßò˜3²ØWmSSåMýÑ”Ò.kÚÀþ¢ŠÌ@Dp»­x~~Æóó ·Û ·çnÏÏØÖŠÄ¢¹Ø¾/xóôÉ5 ðj—OD–£N ´|hmJ{·Ðâ«*2´ØµKQþ�@Vïtmjüš³œ#„N9dÐÆ%@時 ¥æ‡ÀXŠÊ;Æ 9Gdær>XlBíÿ¦†µŸ³PCñûƒBo)omWåò€>ÛŸÑúJªBÏ+.ÉŽYAÿ¾ÌrÛÖA,ªôÐû·Z[ßK¤d ü´nÍÒžˆ™Ÿ.xº>áz}B¼.XBÄp´_…Ò–Œ vœœrq3�”`}M�$ض„ç÷7›G·ÛfN ‚­³`s§G ¸¸ùYú9çl¤çÆbh‘Ìlùæ0²qí £ïË÷bbS`æ˜)p0"‚ªR– àœ3mÛn·•RÚ‚ª213"â·Ÿ}ú}ßþ­oýøívûzNÛ�ç,_SÉ_Õïï{ &E_—ÇѪV‡gö‡ï÷Í{½ÚxBÈ›þ-õ\ds‘Hšò¯‚”#@Z__<‡EëN’ÜZ=«UÇfð¿’q(]‰&Ä4Æ‚ ì ̆w-x F8R{$¿:�¸CÍäü¾½›CÝ[Y°–áÙ*ÔÐÍÚ}Ê‘>´«—Ò—2ª¥gÞÆ!ð?·B-R"8Æn$”ñ™AIïèïlâÔ«D£â[Çù¶7n �½·UÜPÑNe»óË8DĆŽ5di«>8îqûÛ1š›�Â{Vø¶¶è†Ò÷rü‚Ç×¥„`t ð½íçÞœ!Þ]'h6&¢’ÎË�î­÷þIð>Úáü':‹»«VÇñÙïŸ÷ë~ŸÛM9z-ä9]ãÑ6zø™ù¨Aûõ­©•@pL ‡*~<:/áU;óoKÝ‹¤¿×zåvÿ¹C/ š¾ÜÎFTÑ—'À�ûí½ãÓáÜÝ�ÈÑðÖ ‚Φ{À‹}ð$G\y©3˜é“¯~íÇÿûÿÌßüÿË>‹1¾#¢›ˆ©¸>e‹E³ÏõÚâÚêïn ‹ØÍv½¢8묳Î:묳¾�bf€!ð J¯íG±¯Öå ÌÚ^²Y˜›Í½å‘gI;õyÁ,ɉFÀß���›@µÀÖ¢Ì.ªòú ¬X¼ûªíÕb«nàl²\hg�ÎÌí©>ESÄg¾И9€*è+ ¢Œœ�,U\Ç�n}DÍ®Ýõª<¥¦~Ë"îº9Y;�ʘt2„�tÖG!'¤�6S­g PEs[ðý@vs×Üú—Uêlì @‚nÎå¡<|ìã�ˆD¸Å4+ðP!tËçjË_rê …‚"¥ `³cµxFX"®— žžžðôæ Ërm1 1ZŒÂ¶®PQ¬·b\l.IgÕyÁÞ¿_q»Ý°m[™gh ÿeYp¹\p½^bY¯¹�Ö·…!æZ`„m׺ÄX¢;pe=k›— ¥ˆB‚B5@TÕhdp PÌ!ÆâC4û�P€"æœCJ)¬ë¾ó�ßú¾ßú�ßøÑÛóûßÒöÇrÎ?šsþ£ªúÅ*Ð7 Lä’B¨}ÕÑÀ¯1=x`?ÛÚ{e3v/'‡Ëk#Ðh,aÐ#kÉÑþ¼_ç½Ì�ÿàAܯPà\Ž<Å]C»’»F5ìíÿ‰iŠ:yB]Gµ÷ Gqõ–ï¿À_ïjé¯ÒŽU‰ ]Ñm 9+X®w°Öƒ’êˆwNÝÞgêÿž?».Û+;ígÝsÉí_Í™aœ�žpVûÒ9d"2©J{m3ç';~ù‡Üðßùœë¡…ºæè>€¨(ëïä~›«Ïè$‚©ÿÛc¥¹W°«LÀ³£îèèŠqþÏQó‡N¯²áA©?üÈ�³:òƒî%É5òuœ*×éÀ²»cþ� ):ÙÿÐ BûýPØêë´½@yävò"?H©¼Qˆ^2Ô¿óÏ]b…ú nÿ£ 8ˆ�QsziŸƒ�‹ÀplŒn ü`^ìÍWo­x}±%_¼]_ìJ^ÓkÕ6¿Å&g�—û…¦9q§Itïxí}±¹¨#0â{ÓôCúàþ¤ãµ63ãÇâ'ÿÛÿè_ùkÿo@?ã€3ß@ˆ@4aËrÞìó7ŒhÊï\æ4Õ�éð3ÿYg�uÖYg�õ{·NÀYg�uÖYg�uÖw¡è�)�1àžTA‹êØ@§Â'¡¨»UM9iX|ÎMe|AXV,9„h]ñä$’Íjœ©X£s³;oêuš»~Õ”ËyȤ�qò,ˆË&€»»ÞüODƒ©ã\¶yÞç?;�>Æh@íÓëzm¤³ü�1”ØšC0ËøXHÖßEi&nø–Ð@jQ)Œ•®õ}i/¤ÒNšÛu¨(²RÊEv@3c¹,Èù‚”ªê‡[¿vÛþŒmK0g)àt'GT�ºtkQ¯W2B‡zµª3—vË0—êµp‹#X©Ã H(ŽÜÀ.ïã-€ šÊ„�i'­%&pŒˆË‚åéŠË›'<-OX.,!€ãÒÆàv»™C¨µÕ@z)‘æ °m Û–Ú:é1lDƒ7oðôô×ëÒÞŸ æh‘Œ¨ÁœJŸH‡³EupÀ–%bY.X. –h9FÊX�MÂÊ,”x!*ëR~¿‹Dd¨ÿ²ÄBdæøÙ§Ÿ|å×¾ñ�{÷öí×n·çÝÖõ«)å?&*`@ÛwÏÄÕEELVã€ÙèÜÍÖ\Kz'æ´�8Rµ“ÏÝž Ò÷oÿמÖ;Cý®ÎH†½Í§aÐ>ßùà¼3{”A]�{)‘‡à?¸9>xRC�G[ KÿØÓÃöX/9âjÙÿ/ªÚõCd3a£gÊ×u_×tk‘W7Ž»¬eĹ{ p˜s]i®>¨ØïUw‘žé „–ÝØ4ç¶{iÃÿýX Ùí %s|ñ¦ª]m?[CŠTU0↤i¦Öãú¹'UÕ9‘S<¤EÌèqζÿÁbîôàFWð¿{ˆFA_#/‚ÿ�CH²ŽòýCßVïjÔ_+Ó �›"ûçÿá�î‚ÿÓ>wä¾OÓÄ é„Ç‘ G8ÊQBg©ëð¾ã½äµÆô¯‡¬ïïY#9K,ãï2UÜ®­ÝÑkòADÀÓé ½S_êžÏU¿ý:ï�îëì¤w~:êÁÙAè�_÷D½»�¼0RZÞ^c ôå+¿ëðrÏÑ�5´{�ãÿï'þÄOýêOÿ™ŸK9&IžU$#Jn±cj¿‰ ”Ì‚EKÁý¾X+K6²2Ÿg�uÖYg�õeª“pÖYg�uÖYg�õ»\÷Àÿ!ƒEMëìî»J\ €ÊhÏn¼ý|¬™ #H[¬Ý« µ: ˆv°¶¾®«ñÌŒ@¡¼¯ºÄò^PráÑçœ,�>g)˜Ë�Ò<ŒÊf¡Ø¨s½òïì§§è ÞBu F03®× ¾òñW�’�±1.ض DÀårÅ›§7xº>ár}B¼\J†;q©@E:fJ:<¤´ö–C±4!§"h*Šo¶×6×bw ª©Ä#$äl1 +oFP`F }üÌ"àâç’Œ}SɆaeäL¡B€Ðæ�íB%°#PÐn¾Ž9ÒT,µ Ò¢ro3b,d€ ¡‚îæ!P˜¢0ª»AìÖú�¤8;¤Ü$µ±ØþÇË‚ËuÁ.!@E�c2§†¢í± )à¿n QÔxÌÑÜÂR®%àrYðôæ ®— BàãXC'¥H…‰ˆ‰™É¦!¦Å%Ò#Å `RUÊ–@™#1gbf&æ@¢‘ˆ–òß½ýìû¾ý­ßüÚóíùÇrJ?šsþšdùùCh¸ªº¼ð¶)¸Mªo+3ÈfóÔ¿ôìi.ý¢xœRONOû=Rуw2ä+¸L4zr7”À^]çS†>ÐWmèã…W%jSð;Ksª1-ÔÖTkK#è›y‘‰|€}ÜÝCÊÒB4:RÓÞ½èž!$ì%—1¯Ò­¶µ)uß5JU„[ÆÊ#�„å]yéæªº@„Òö!@à.ø¿7oªtç\Òî·ä¢t\ „:g†Á¦^Ë5�Ê}Á�NeNS;t?ÕF@ }üÊ÷îEP3¦pN4ƒY=Vý?™užŠã5$ú ÷{ˆß-ü½¶Ë«ÜõàÜäÛ×Èõ~¤Ãgœãl?V#¶¾ÿG~Óx�Þ•Ã\/èΔuRtÝï™;×ƒÝ é~lëù¹#T¹l'Úÿ¿|b2Ð}…t[KE¹½#?<ÂV_ˆxpeþ{À«ŽB›0€ãô;¡øÿ�‚õΜ/Ÿ&w u7}å¶M‰oŠù¥€ãÉfMŸÒÖ²äsJX·©åË[„�B( »¬ôzÝ ŽøðŠr”þ”–œMÑ¢ b4Ç�Ò/Lf'¹\ðöé-ÖÛ ªŠeYðæÍ|ôñÇøè£'\®W\.—boàvu5�,MQoýÀ�p)çZbQ‚«=€£òðЮ¿Ä À©)ÝÙ@y"Xd@é3‘4ŒCíû#®×Ë‚–A͘×``µ'Qôþì ’Í%sgˆ±(î æ(ÀšQD±½®VìDÎ&^ð/5´Îmªs7 A fsU°ù-%þÀ©syœ’)oØÖÛzÃz[±m+Ò¶AU;©µ‘M±Ï…@¡ž€Q•¾*Í–¿:BÄAWë›#Þ¼yÕ§6!šzßæVQAkBÊ‚´%kWJ”sÅ—¾¼5rŒ1„°‡‚é‡ÀÌÌ� ÄD$””…˜‰)03öÙgo~å—ñÇÞ¿{ûc·uý±œÒW%篪ÊGÒÒ}&vU¹Óù¶1»IÓA¾6`ÆyE4à¬�§¾âðwnÀˆqêq y¼c AÆîÐ*¬{ÀPÕ&Ý�ƒ�…­Ø1  Ülü‡KàvÍÔ\Zæ}KZt@# `€IË꺺·Óÿå€ÀLêþ×€GsñIïûÎq¤#"çL`cÀÂÇ=8}vºÝADç9L‡6ì‡Pþ4b˜¸ýËŽ˜ÁaTÿÓ�°*È$2*Muêè⌠fp²[k> Á“ÝìÜÕ;¼² Ÿ5J†¦ÁöäŸG=tˆf š÷Ä@s©€·Ø/ªKSTê Â+ÿ§«çs=�Œ ²�%ÔïC8 Y¨�íξώ—½Þ±ß×][õ 2àŽ¥ý#Œÿ¨¼S‰êƒ½íøh{ð\/Šû1¯FTõΕ4C•Ô×;sÔ;‹Ôh’‘@Óïm/÷Ž$t¿ïnïz§Ã~|D ¡ÇÃöð5»qü€.Õpžÿw>ÿiñÑReÞ û!¦—¤ZòBxM»pãƒé‹}»»SêÝmè¨�òÿgïßbµKÒ41èy߈õíÿÏCUuU×tWuWwueÖ¡Ó3žñØcF¶c #B‚k_!BH $$�|‡„o@ [¾!`,@ s°ÌA¶0¶™É3c�ÏÉÕ]ÇìîêªÊ:dæÞߊx_.âôF¬XßÞÿŸ™UÙ©x«vþûð}kÅŠk}ë9½öú'þ¥âŸúOÿ‹"òÓëÃþ®*ÞcæÀ>NÀ+¶|¦Ú¼‡ãôY„©E‰ÙÏR¥ód}_µjÕªU«>Vµ«V­ZµjÕªU‘ aG”‘”ÓØ©ÿ3®9¿T¤)fÓYÀ'«ú¢'4à¹>¬«„Ón[Ì}n¯Ø é@gÝî¼!f¢ê£bLûb¬ù% ¢ÆfÅl¶Y”Œ…üP²ÙË6‹Z|Ü—}˜Õ}‘Vðör¹;Æ+¯¼Šç¯¼‚×^{?ýé;xx¸O&Ü]îðü•çxþüÜ]îà�Í“¼S“Ø'Źsé�ÛvÙà˜²Å~š€+'{xPš8[Ö§ãpÝùPM$€# ˜¿m¸\î$µþå’â ¶Ë%+÷S>l$‰LÇüÌeI¡5¶âÁ0™‡vëIðwOJ˜NÊA¼N§9óz‹”¡ý9öåS »‘0nÿѬ�¨CnÅ|îÖu”ºx™§Õ8j›"œÚE£;¯ôØæ0__ŸðË'þõÅ–Z¼@{?xõÿ‡Sú2õ˜Åôü¾}â)dÃ2tKÛÙ]ÃY;Æ{fþãÏþÒ/ýwþü?ú�ÿ›a¿¾+"ïtÒ}ûWç@œwu­#J$V"†–¸¼fpŒØCl×7(RjÙŸ”Ñ´jÕªU«V­zJ-ÀªU«V­ZµjÕG¤J¶xQ“Ûe��à˜ÅÚ÷Šª‚Ö9‚wðŸË>ÌA€Î÷Šèøln‡; Ø�˜¹: ”÷Ùv¶×¹ÓØ„óvµÎ…HðìÙ¶-)ó_}õ¼òÊ«xõÕwq�“å¾c‡ËÝž={ŽmK·Ì"ª‚°G\C@ÈÀrrm@¶õ&8NJp¿yl>Ùç—¾jàƒb¡‰™²ý|!s\SédÛy‰{¸âz ‰IÕ�‰Ïž]@D¸l—<&¨à !8Köh矪ú4)ÿ.wÜe×—É"À5r^*‘ƒ&¶¹]Æzµ6‡y}ãùUäsþ€#CýU…wš£$ú{"ì×=;h$W†Ò_1<\w\Þ{€ç9õ»p>®×4÷Y$= M? îŠ á™glþ‚»»g¸\60oùxÒùܯWìûއkÀÃýÎ÷÷÷n߯[WcÜDħÏ`ìÙÁ‘'b°÷Ýûçü½¯¿ùÞ;ï¼ñp}ørá‹1ì_ŠQ~Éľ·g•݃ œÎBÕë{í)k*èö=‚Xe6ì|ún¤ø°6ñÅr=o“p¤ÊX±#:z¤ãVæ¯�¶ëèìú }'MT‚SlŒ0ŒßC'õà?²ã8­ßvžä%Arÿh¶âxl5î‘“\„ EŸÄ8DìiT�¸Xè-À{Æ>€¹N–�“>íï—ô¸ÍÇÅd¢ êxíçE½mT>º÷§·Ÿ~Æx-½Ø ~ÉqA/ÐôBý¦Oú Ý:‹DÓAPc'ôBºÑ„ǯË~ÛþÚoþöŸùoýÚ—¾ô�ýz}7„ð QeVlúÜÁÙù Ød«S›™*¼<þ/¤ât½�ƒ¯�ã«V­ZµjÕǪ`ÕªU«V­Zµê#R!$ËFç\7 î2("â @Ü Qçï_ø™h.5Pªjü(‘À‚þŽÛæªK�²ê·ÍÃ;þ?Ы÷»#ë”þÒ½vÚ�«A§p¹ÜÁg`ÿÙ³çxõÕWðÞý=öëŽCncjÐø"RsácØ›o~}Ðæ½K*zfg ?ƒ’ì˜#3¢&‹zQƒMÄ’=½5jRÈÇÃ!RμswÝpÝžgõg²üÜü›ß½˜qÑ;&XËnç’kÁÝå‚ËåÛ¥9/€\DàD .¢’ÙœŠú(F©ýß\Ž=8÷oR&Q@„HÝØœ;'=ô²�9õyr–ˆ�{„%7¨jr¸À{y _Ã÷ïaÛ.õ¸ö}Ç»×wB>ïLÄŽ(Š’ˆÐ~½ÒƒgbÇØü…ôN‰=Ó¶]ÈyO(†@L ¡=Ü?ÐÃÃ=ï×Ý…|Œ²‰èÀÇžÿøí¿ÂõÍã—Uâ—¢è—Tâ¯äN¼-F´*c}:1*wë<1jI½õ¶ºyC0‹ ŒbÂ47LGëøª·+™Í€3¶ÑôÉwÐÂÏi‚˜`¾ ÷޶׷±GUio�Þ$ò…„PÝðɬcù`›+‹LÝ¿ Þì­5Ð +wí_€ˆ%¢Ù¡�7ú€Fûå¥ÁèìÌ5ƒÓãh¢K¡CNý@È.͉€p–¨nûóxŒ4´Å�’ˆ&ª÷þç#Ð8söô­Q’&:0‰2'd0aîvß é8.CÂz´y˜é ¦Mj�7†¼ô¶® ÛnÓ6¡òGÂa›ŸÈN9ƒk†íOóG�©ë ø?r::p�³¡Ž%;ç@v.4²�àÿ ú®·ä:Œw€.›üüWŒN0&.ù|Ð#™èãhz$bàfÒÉUÃÒ?ÿg“W­†Þ¸ÿ}�ƒ Çzórú³/z1€ü¶ÇÇ îø‰Û={]çtò¢CåÑNŸôúè¹v®¯¾þú¿ü—þÉæ_öÞÿh¿†wC!„ Q´’×È�ÝçÒ:{Ñúy±¸�C·6—ˆ+ÇŒÈÔœ ˜lFͪU«V­ZµêcP‹°jÕªU«V­Zõ©}ßkþ:*X�Ôåé�&«øì†>*ð‹ÒZD«²#æ×1¥Eé�Ö¿h_ì–É*ƒ©<Åúœ*Ø+‘u(-Ç-/�ˆÀÎÁ»fÿÏÎÕlõDpÉJwià>Q²rwîHz8ÿ»Üø¬¾çÜ—ÉžßÁo— _¶ îî’ª;gµg[øÔ†#ö=Tð;ÆpžÓ¹ÚRôBþ"æÉƒôÁÁXð+¥üp憠ñjÞØQž"><06EØ“ >ŠTp;�3—-A}Û—&°]ÍCHæt›÷ض .w—ÚG*@^Î�x—©í«¡#}ä 0gçÄy8߈{ˆ5¢H¶éÌ)ÒÂgƒß|:rÑFð›ß [Î4Í OŒ÷yÛÛ}ŠH(nĉ‚ëõ!F""çÝÆ—-�HäK îáþ�œcwÝ/ã3(Srsw¢JªâB ¼ïW¾¿¿w×ë=¿ûîOï¾ÿ½?úòÃõþ�ö/‹Ä/©È—TõW¸Þî¾`}b4^¾=±�5Û›m¨*ᲟÄ.ï-N:(Ç;¼sPÁ÷®f»Å²¿úâ•êÍÕ¿‘qã‡×L{'gBSusèC 0Íé°›?_ç­y9ÁÏ%YÀôd§�/�`€M%"F­«Õ@;Õø£A‡~E%SÙk6Å�Ýz·9ÂD÷|ì5Â!„ã¸'o(föëù÷„­¢bÎÙÜð©zûH@Qò«Ý�É>®À¿¦x=̽ܰ“ùU^(z´tWë”0Û‡ë×llwÛê³êÛ5qÒ ÙþÎíòëʹL'ãI{»ImfŸ–yYÁjÓ¾G#´'³˜·ö õtb‘?F3´sh#Ml—¨qqèý ‚ëÇ ‹lÊ´OÏÎ_v�EØ£‚÷69èÅAßÓ”�'£¹“5—nŒÓÃI¦[¹èÝzTWL=^%n�¼§öÉËÿ*œJ?—·~è{éyN‰@{¼šìg PêKg,´][u3=‡?úsß‹éæüßÿÕ/üú÷·þô?ô×úÓë~}7†øC 1HŽA#(Bú ²3îMLZú 2Æs�­WÙ1ŒsT-ÀªU«V­ZõqªEXµjÕªU«V­úˆT ì h[UëLŒ§Ð6ZhKŒYUMèaÀ†T›æYŽ{g\•« ç˜Nœ-¬©=h*À½Í–,ªÂ†�ªþrlÞo‘ €Ëaß+øSlõ‹ë€mïØ¥êïó{Z¦s{-3ÃoL„(¶-`ß7\¯;öýŠëõŠk¶—/ ¿u¨ D`çá/¶mKÇ丞˜òzÑÀꔎ9]9«†µ)†Ýv´Úå+¢$›ûöýš¾®×z´Ë` +K›-#Zéá_uIØ.ÙÀÕó%Ö¿stPW@-Ô÷«ôöÉD€0U{êtÞ=¶mË`|V‡Š"†¢ê�ÆuÂA/[þ>Ôm¤s˜ˆ$w™4Pö+Å­ F\U+ ‘@¼±E%@á%DÇÎùí²¹ƒ‰îA¢‹".„Ý=<8w¹<¸=ì^Bt"ÑÅHî'?ùñóÿøïÿ�7Þþáßxï½wÞx¸^¿Cø�(ò9¨ºadv éH_ú®üÆþÓ¾íõï= à,Ƽ ð>!TÅýÄB¤‰gÍ€.ŠbC6èñ(šLT[õp _MAÓqÈ |v7è£'€@×?:º$hm/EqEaÍû„ ¥<‡{Û`¥¹6¾ªƒ« PíÙ½QÔ�C.:DÐ8òèò>8±ÀkQ^“�UmÞºvÙí ì§*Ù¦àSO#“ 6¸ì‹!Øc¡LÒЂógrµ±©˜±M (Î4r8j Cºsßç¬ÝXë�Šû²‡ÎæþƘWšœ¶Ã|•CDA7÷`ˆ:°¶üŠŽkw¸2%àÙQlÆÁd @fâSÕ?¬ ¿öË€ê¼ÿ�ÝþAý¯óg¯ƒ#�¤wƒ ©À·¿»¥Pš"ù¸}­Kæ¸u¶?’ô1~s_˜­ O]{]<èæfuê¶ Ó\ô[ퟓôàtñ"uüÿa¦O±» Ƀ^vÏD'ݧ�‘$×§ô:ÝØ½øp}ú™NוC¤RúEO(ÔÉ;Ÿ:elöçÏ_ýŸÿùä?ñ/½òÚë?•wTå^b¼ŠÄP®Eéú�î·cŒØ÷ÌŒ+—è°ŸV�Ð\þÜVî•­S §�Ž©#…¯ZµjÕªU«þä×"¬ZµjÕªU«V}DJEA.«ò«úßç‡8ÜY9÷€ºÖòQœ3ãÕy®>h"�Ë  qÞOŽ cv;PìÚS{¸‚ÿ%_žjn{±z/eAÚöž|·J“`ö!Ú1ЉU¡NHŽ#yáŒPûW1¤eþºcó €&vð®µQTžTã×÷Ø÷=[tku4¨ ¿aÛ<¶Œ3w¤†ºïl÷¯Åfz�gÏ­Í/oÑ T¯íÙ~R«ÆÂŽë~Åv½¯Û 9.@bü –ú¶Ä@%;¨*ï˸ðùxDâ®#¦pV3÷üÊ£Ý8šó'ðÝûäÂàr¼Ar[ˆ™*àVΟD‡èRô€ªÖ±SÚY¿òÏ×krr�÷Dè°±äÞyvÎ9çý¶¹Í³ãÍ»dM "^¡NT¼\¼¨øëýý+øÎ�ßüƒ·¾õ¦„ø†HüõÂ1Æ_V(«4rFù0 SÀy\Zå»@§ù?Ó‹Ò$Ä»9ÍZM©Va©!)§�:üò ¡žjÛùW¶oUÕj2àíónc‹�ãaÞ¶êô±gà(eð\M¨úSÖáAmlû’ì î»Á€M�Ÿ‚qe ³ÎÞ8d2.:ë,lo,ÙÏ\�å)¼Ó¨78É$Ç <5¸Y[ûC ™$=e…†#¡-sIÜ?Q×A²±è�4Dºþ§LähÑöÚåÜ—œñªäW½ T§ zþ8g–úSóß;ÀöÆøÆ%¤Á:±À¦B�8žWjkͲåɸè¹3„NÖEõºrã¸ô|¾Oû`<DÓ˜ò‘ÀÐ7VíÖÆîŒÐÓÍÕþØóB‡¼+¤Á†kß!jÅ’ú_MÖš³•¥õMÿ:³s·;99Γx›~-×›óì)êê§\G^þFýIgíÚa,(�~âp<µ¾´'tú—§Îò�èCéù[gcNHxìÑakmy¨V.ðÎÿûŸû•/üó¿õ;î?`Gïѽª^Eq›;÷·òY#„P?{”ظ> ͵{j‰ˆùó‰�w³‘l«V­ZµjÕª�G-ÀªU«V­ZµjÕG Z–#U Û{_Ø ¢$6¥|V¥ZRƒŽ dbr€Ë9ß ™­ŠòîS}HTª`!5" ·¥¨¥Ó&£l—r }{±ö/V”õ!”yM±Øoöú1«ÙB ü@Y5^r+‰ä\í;[Öi *ÂEòñ‡|ìíá˜{–”2lHI1~ÅÃÃ=îï±gB@Å}=¾m»Àgð߻ՠ¢ˆD4Ý}:_jÅ‘ËÀó4ÏÞf‡7 »)êS BØñpÿˆ[Ž“1·HÌñÙ1 ÄL´Ø¤‡…p¹Dt&Ù‡–\lÓ&¦ÃØ-ÿ–íˆ6¼�™:5¿ß<6_ˆÍ1" ÛüÂ@Ý·qÃÌT¾¼ó¤*e£-03Q–£«(Å=P�BŒ$"DDÄÌäÓæ7öÛæîˆ<ܶ9ç6罿÷Ý×¾÷½·¾üÞ»ï¼y}xCBx#Šü†ª~ž‰‰8Á‡åßjSŽæB`]ª ¼.›}|ƒz»J¸Í¸6T� 0ØC[§~5 èYké‚ãtN] h�ºj‡Ú{ù£Ï{ïAñQ)~lÍíš‹DGi`�’È1PÛ6Y{åz¦Þ”­:ÜN0Iý¹s¼©½Éjóµ‹oÈ¡—&²U:Ù=©ïÇs{<“ HM¾u?)/®cÕÌ�=!Gûý¶µaXç˜�2ÚrÞE;Ò��sjÆiË ­„¶Öž~&ÐØê˵7x.ÓBÉ8��«±ãúܺ}±µÊ¢kO¯C2ìX<Æd`H%µQQ)mQÑ «A»)¯•x£¢Œ²AŽï?7À7Íí<ïÉ`h4 Ð >NÝ’ÖÚ>ªþužEOÇ)eIvyÑ›ÿó]fâÔ¬ sg™‘ Ž[šßtÞZMèpL}ã5÷£«Æ#ªÿÓEc?ýž�1oàÊ_tËzó}Š�VÑdd鯷·xìáôºsr'sœ(/Ü—ô„³FǵJoLÃI3¨Ýßþøµ×?ñ/ý…ìŸø+wwÏä¼{—ˆî‰hW¨hDvœTþâšcZ©ôgÏDß‘£-9Ö™Ï{Å™Œ«3—ƒËÄèU«V­ZµjÕǧ`ÕªU«V­Zµêç\õ! œ÷ð.ÙÈûm3À{¶cu@«Ê®<Ö�ö¡;s7¨³ýZ0´§Ùÿ» ¼;gÛÑÀì¦`·*’fëŽÜ¦óðð©ü+’Ôè1$pz¿&åzµÚW‡XòÞ]O28+ âIŒØ É )ù9ù@,„=àzmàÿýÃB—q¹0\¶¯¿»{¿%’†s.çG D¨³¶vÄ¥ƒ“å&ap©>Ä2t_ÙÀyÕ-÷krRP$¿‡ˆÀû‹‰iÈjŸ˜ÆL ×ýЇ‡+bÎ{(€Ë傞A¢¤/ŸÜ A#ÙêËÔ°„ ä*ˆ–úƒ±y_É-…Pâza+™¸€­¨’ˆ™;fïy¿±óŽ™Ù©*…=8""Uu1D¾^¯,1rØwE˜ffïy¿^_}x÷�7þ%J|Cbx#Fý�(ásЄ‰($Û�(�Š­|gCÝÀCírãy¢ªÞ ©¢½:F´Ã “í×ÑYI/¶×·Á�–Gß«�¹ä@}äÙ~«=µÏ®óÄ©d¥‘­0€KúøÇÓá;Ào¶BZF�±žˆpÍù>®MÈ6棋Â,ÊûÑ»ñN¡ûX_½D`²Ég&ÓŽBŒI࿵³§!½ôz‘ô`1ßfÐ)×mW4RÕpX™e 'j~E¿!y|*52Á8=O%tFÎ)@V™ï�rݵðÖµLÇ>ï',ü6á��:±õ·öøÅ¢¿W³�ç�ÓI?g©._J…\¤“q©?e˜÷vŠJwºmØû¨1@g»=˃ïõŠ[FŽ yê×Ó.Æ3ŒÛèŠÉN!ƨ]o†õ~lc=ü9]è†yÇáÕ6Ê`¼]œrÕž°Ô¾´Zÿ†kÀK_^’0Mxíyº_ülŸç�úaÑè%//Ý·SÀ�#<‹�øPjþÏèÍu¦9õ4o¦»gÏþ_ùÚïü�õ×~ã;ŽÝ;λw�s÷ι½~Vºrô1ÄGͽsÚo!¯;™¸ºve’òè˜ÅÎåÏz)öëâ¶õÁ|ÕªU«V­úÕ"¬ZµjÕªU«Vý«³Íw¼óðÛ¶í¿UËFEŒ%#½¹QK R`¼ +ØŒô"jŠ× Δº¨@>™‡EEå[œb”¬ÐÏàsÁMdÅ£ù’bm_ÿ®PŽ1ÙW&õÿŽhÔ-½…%%ú‘`£ò¿û‚’1FQR¢oÄK1A¢`É.þááŠëõŠëž¬ä­úÿr¹àٳ縻»$wƒÁ9@J¡Æ7p�; r” U$$G—I õØCΩG:~ï=ª¾�Þ;0#Ç'\q/Þ᪪>ƈ=츿ÀÃÃ=žü¶�ˆp¹<àºï•`ÂŽ¡Î'UѰ‡½FD‘ÎÚßž«ô;m*ÚüšD&Ù:õ/öçÎŽÔû-=�Ü6ï½wÛvñ.ùö;¿yç]ú€cfcpûvñ~»:"rÜõþ½×úÓŸ¾÷ë"áK¢úü Šª_W€ŽºÔu ¡OÍY£�Ý üG'2щÀl`fQî÷zÊþA*»ÛÒMà`M?BÜÍ  �p´³ÇDÙW,ðiòÊÌÐan•·&1~°qo¯9±Z¿-“<¼ì€ïÐãon„Ž¡ÍÍ‚c°×.g»ýA!NÒ€6R–iž"�{k­M'ˆU—ߨµ83<Ò‰OÆÃzis;תéÚÃå»ê!wÝÚ—c+ÿA¹Yg_B¹¹ŧN@ÿ: ©f<ˆº}5§§Úùë! #½¶wÚèóëόѾ°‰ÐæMÏéÇ”Þpºè] y¥€M4 ?’̵m3#ý‡ÕDóqÔÈ�Ú6J ¿Yu´ó‘¤0b~bmª<›£ ~™{�ÃÍ Žæô4™ ÚÍ•~Þ kÕ‰5~Ùê)¡C�ç­Ò1Ê|°ÃB¨PØñ5‰ŠÐCç„áPN&øMð_çsì6ÆJxÚ›ÆßÑKfº·ÙDÔO·—Zóð„æ¿à†f8õ‡ëKðÁ—þ,wDx�ÎÖöXèö^çî:[]ºŸ¼ßþ½Ï}þWÿ…?ûþâ_WÕ÷˜ù�‰¼sWvnwÎÃ9®ñoÉÁ+}þìù3`¹W¯d‘û%ÒÝ{»ìÆVHω¨íá}r Ø�>{\ü~[€U«V­ZµêãT‹°jÕªU«V­ZõsªQ‰¿m.ÛÛ¶a»\à3 æ;ƈ}¿âzÝö�­ó%«Ã³=?µ‡ƒ#ç“5}RßçÇÈ›ò:ÄîAQi3ƒ‰+h�ÿÒEh¶•/ë•xíØD6ô—«Õ°V5KÎ#bìAåäàà¼Çå’ú§8#$€ÏûècfUˆ”Éׇ+®—\÷KÝFØÛÃ4ÛŽ¤þßp÷ìž={ŽgÏî2ßÍö9=µvì@Ž@>ÿ.é�“Ê4«ó£ßDp†ø³egVê�‡s çÒùfF>OÜÔö1"ä¾ð~K¹îÙ^šUC! ì;öLP¼»b¿îx¸Àõî¡s"@\÷ô÷}¿¦‡�–ìÀç㺠é|ºê0Ÿ¨ä¿m|Ù.nÛ¶ír¹óλ�™½wÎ3³'"GDž˜<ÿýïýñ'¾þþî—ß~ûoÞ¿wÿ¥‡ë×b¿.Q~I´‡†Ëoà?5n Y[ø ¾Vk7}4À¥‚ˆ‘ý¹Wû×ùbŒÉ«]|F+4#‡†K�öUÔc­>_ ø§É^HÒ ¾7kL:3LlÀ ´·ñ7ªÉl¯dÓ7Pq̵×Q= R}ÿ�ÿ;¬¹6Œ@£–ó~žEÅ�*Ö'¡=¬­® öе“KªíŸa ÌF•mÝF߉r˜p;":‰\hî³Í�j}â†Õ6n2ѬüÜbÝÙôƒQYëyª1‡ÇÐÔéØ=f/¨QÕ×c 8ÿ#Ìl�© )¡ŒŸ3¼öˆ)•­Ýë͘Òs*Œ âHÿf~É”x¡3¡|×âÞŠ¾“Ô´³åYœ1|×2ä�n0Z¶U»¾Tò–žL®+þÞÜ`fjN=x>:ž’ÏN°�åÅ1è+ïÙIZÇ)Pÿ|ayœuþÓIÔÀíõÌ}î¼2oðü}/¸ÂÏlTÞÏ};N U^ú’óÒ/7N(?{òÀË_iéE;üCnÏ­}ÒcïÁÝ:v¿÷ ŸùÌÿè?ùŸúgÿÏ!Æ÷TõŠ„BT &òJºî9O…‹‚¢˜1ƒùÎy„°@&õ¢’´Ó=¼@�@TÀ1E°“ü¹)¢£÷�¨/<×W­ZµjÕªUýZ€U«V­ZµjÕª�H]î.Øîîp¹Üá²y°+ p³¦ß÷ Þf°@¶Äg°O@yЏ$»õ¬–/`~±GNJð€=+Ü‘@“±è¶jîpKv"H`½äìvUÉZ­%9Y¼Ï«Wéûÿdµ®ôvÛ¶Á{‡m»À{_¿úX—­0÷º—LsS€ÞD*Äq}¸fBƒæ ÍÒ¯.¼Àeåÿóç¯àîîRU3õÜĈñ€)YkÒ–•�Ù¶ß9Éý_ ™³rµô³µ¾/€¾= ø÷ PïܲmQæçß•(€Úû�;‚âDRø_¯;Þ{ï>e�æ�%_tß÷ä°'‚Diëä¡!õ_EF]QHVUŠ1RL‘œ‘ˆÈ;¦Ë¶ñ¶]ÜÝÝ3¿]üÆDù?ú£?üÔ|çÛ_þéO~ü•ëõú!ì_!üºˆüR=®lM-2Éî.T”ù4€ÊcH«µb†å ¯ƒÉpŸ=BíÓß²ÓÁB‹55€qóßWÚ3 ðÛmu ðCÆ7áHf˜£�G0¸ º{§›ã>u‰¨ñ°ªm䌱Ô7·Z·5EÁfýOÍ’ŸÀ¬¦v>¬}Y_n¨ÿ»Ýêq,ܪ„ï{GKû!§¼sÀ|’±OKÇ÷ÒTù8Š�›Š¾åp7òÁ9òœ-࿽¾Ôó^í-Úßô„t0•ÿ*êµæ¶f3ÿBÌëÈ:ÜÈéˆÎ^ßÿ•Ü2‹¿ÆìŒãÚª‡íc˜¥©gD¥bß_únZ[%~úo×_¼ôd�Öy|šÉ}œ¿:DZ(Ž Û0"`’vz¢…y‡”òC;Ï–3cËO–È5[_€|D•8�JpÁÙŠ šÏÁÞ`æF`Gßùìž;Ôuø)~ï:ÿÑ„@A/p;¦j¶Þœ5è´Ní埶&/“êé:ñô>þÙMÖ©k˜}¹Ò“ŽúdDˆ�C/tV^¨ ìÜ÷>õÉOýÏþò?ýŸù+—»go‡°¿ËD÷‚bUùKv¹Édmà6IgésŽAT"µ"ö�> \™©æhn¿LPœDªœ£Ü Y09–Aþ$yQ¬ZµjÕªU««EXµjÕªU«V­ú9MT¬ÛvÁårÉóf…@T“ú?°Éú1V[ú”eï°ùì p¹Ã%«ä™¹wè•qݓһ¢´íYUž]’‚¿©2%Æúúz,DM¥n@éô÷ÞÞ>I¬mÊ@z¼³½ÿ¶yl~«ªÿü+Ëž  ƒ=wàyË¢§ª21âz}¨¥ Þo¸\¤Zü;çp¹Üuà%dU¼u ØpIÖüù½>[n²[òq‡¤Âaû„/÷)1�¤'3|þ×U+O®d„}ß�Pœ!R'%QV23Zö§c8ñ�ì"¡b„ýЇ‡{°cÄ+À¿‡Ð9$´qìÁÊhŠ\M¹9xPV…SUR�N¬J ¨‰,"E\&0ÀŽÙñ�Þ~û?üþõþ½w¿¼ïû›{Ø¿Cø ù¬é)Œ‚̾ÍkŠ�=—1ÁýCÑgéT?hŠæ¿jƒò/²¢Øª4M£G°3`ÃÌŸ’©]‘)=¨÷Û6̱Œ@×$[¹áxEMO]?Ú6õ=2ÉÃ1R=WïçL�º½pÒ|#€AUcGÞzƒ´L1ëo«‚uàÿ™²x$W›2mžÁF:f6Îåó}hœ±§G·9Þ¡o.Ýîv:"ô Æî¹”säep"¨]T‚Ñ©€Ñ£dÁçH«üÛÙ�¾D‡ù¨�ãÜ*ãÚ%L6�%2è@Š@Y/Š3ˆÎ�íÿýü£¾cÑÅ€†R¯­— ]=~ÛKš�mûr¶-Yh2ú¨9‰ôNŠn%ÉóH†ã“|n›‹‰ÞÈÁ>§¼¨ÞÊüÐC¯Z®Áh`AÃäH2›.-uÜÌÁz‘�žý #�`FbRœÿFç eú“1Üy4†žwáÐsÀ“ûò ]}²óG�•?âóüŒ]ôé£ýÉmÖG;åƒÿéýnᆅ@i-3ÿà“ŸúÔÿòÿËÿÌÿæSŸúôDâOCØßpÏL»jZ¼7‘ªc$p$8.÷à.ÿœÇ}"ö&B02AÚ#d÷¸íáŠ}@-Jm°³�â× i¸¸áHÄ XµjÕªU«V}|jV­ZµjÕªU«~ÆE'hÌå’¶Ë—Áûb‰ƒ dõŒ‰P€á”ã¸aÛ.Ø.Ïpw)Jy‡ƒžÁ€ÿׇL&ØwÄêé¤éüô`*Ù>«HÍ~ïwëà›½z;jÉþŸ†¼ðB*HJ”v\ÛæqÙ.¸ÜÝaÛ¶ üט ì ßæ%w¾XêÇ�BVˆ!b§¦ú/írÞ᎞¥–3Á;W ¥Í!\÷l‰¿·m$’‚¤¾$Ï.Å0W G$90XÇUCê1qû­;�÷.» ¤>)PR*ÊD€”ºmTΨ ˜J?Q=¶‡ûH°K€"BØBèÚÁìÊøqæË‹¨S'ª ¨Ô«ª#‚àbŒþ'?~ûÕ?|ë»o¾óÎO¿²ï×/ÅÞ�(¿!ªŸe²`!Œô¾�M#nªƒÔ•šì¸ÚžWðŸšCƒë Κlõ2æn:r[ Œ·�C&f…Ž–ùh€wM­Ï“Ž»PÚõ`ŒNðïƒ2½Œƒ²é!> (Ã�mcnΈŽ/•ðӈ͟äÔëÑÁº7(ÇËa®³´*É鯮0[DÎ_L“‘<®!ªÚ�_†,3ÛÐÑÁ ’Ç}”~�—€u\ÏNÊ8éŽãô®ò¬czBÃÍ>œõý àêü‚9wcz�<øÆÞ¬z6Nòš÷8 `¾«—±§Ü à‰q7Ç ^ò½ïÇ§à±æ{(¶mÇeó¸îÂ^ÆñKQCus »4Nœ(B\«V­ZµjÕÇ©`ÕªU«V­Zµê#R)ãÞ7U74(‚BÜ%¦7øïàýÛv¹Ãå²5°Ü§ÜHÉ„A(6ïû®û5Ð5gÙØþ`¿3s>yð×ræ­ó{©ÙÃ]5)›Ò:¸ìh°]’+‚÷[§ø¸Áùß²­*îå#p¹$B…w�rœBQœî{ŠT¨äJ€?yŸÈÄèx/")BášI¦í©?¨©ø¹90¤…y³:§€é¥³ç/dÊ–õιFPp.G=øJ†Y©c4ŠAŒèHÉÍ`Ë`ÿ¥:48—ˆ å�¢HDйß2øcL -3«ªËŸ+y€< PE½ªz@·‡÷žÿÑ~û�÷Þýé—î¾²‡ý7bˆoHŒŸC3ñ6 ò¾mV´ê X1Ø`wPlmQÀT°Ü>kŸcò ®H˜`ŒÏÀŒ£ò5{ú‰'¹q;7€l”“ê»ÀœéwÕÎ_ «t†B f�(ƒÆ)Ûzpúítf?%P×—ý!Æ 8n�fm2–ä¶Î�“@o&n‰õ%ü§é’Ö«‹µFº¥ÐDL;…vh±%(‰c¨Á¦Ïº_»QF�²¹Ï\Ûw¾=ìÙéTe=LÆéI-¼‰´&# hÏܽ…ì¼�¶Þ¦¤-²¡#«h#Nç U¨Ò`õ^%i|fRqñ¨q>tÓyÌi7ăڪñˆÇÔø,ê¾ñK´ßމ„Ð3öÿq ½:¼­«Æ¨vÖ3ÓŒÃ0“›Aç�Ô�\ fmo}׿Ü~bñEk™mÝ@:ÇŠ‡uŒV¹-Zð_oÀt[ù~»›Z»ž°�¾ú”WŸxìëÍ˶½4èlÙÕá:<¿°ÌG(ݸ%}2Iâiý:;Èñ¿tvY¼ÙËô�´èé5Ðý>HlXÏ/?óë‡ÞÜÄû9³¡ý´˜ˆF×câ·^yíµÿÅŸû‡ÿâÿö—?÷¹··íràAUwU‰ª1ªj´¤Óþ3ª€jRü³cH&f"@¹ogÇÙ¹�à¼"çûø¸EDCnNŸ· ™7—ƒ"}f�Wâi�ʪU«V­ZµêOn-ÀªU«V­ZµjÕG ˆ¨ÚܳóUuÝ2æ“úßæ®;Çð96àrw‡»-åI^@Êêý˜Áÿ€ýzÅu¿&Ûú(&ß–ªR½9ÐéèÞÉàAÌÕ´ÅªÈ O•C°Hª}—÷è¦ü>£Š <·®LŒm»àù³g¸{vçÒmoŒ¼ïÉÒþºCb@¨„Š+à½Ç–#RËÿ€_÷=ƒÿ׿gÉ}‰ `þ[•y�ˆ¸'By_%w©ûMd�è·Ú›‰àáá�‡sí\.q±º>´6døŒ_p¹Ü�ˆˆ‹·h;‘œÛL"‘P&pŒ‘b@¬ÊÌìT¥ªþ¸=\Ÿ}÷›¿ÿÅÿøí¯]¾öðå(ñ ‰ñ óÏçÖ÷EÍÝÁÿjÇ·´w#PtÛ}}ú�}8íøà6~–Â0=ΙúÿläL¹&ô‚�xûœ’ŒM�c÷^}íõ¿òÛ¿ûçþÕOü§üüÙ³w™ùžˆTuTÁ·ü#à¬ýÚ}]ï*q·|F!yÄÌðv Ñæ4pݹ‹SÉä€(`ëCùªU«V­Zõ1ªEXµjÕªU«V­ú9Wc.Û–dÇP4P[BS‹k~zÉœNà²ýß¶ Þm ì€º�X-ç¯×+®ûް'GÕÁö?ÿÛG)Ö]Ò“0!艅°½Uµ¤¿çmæ¼ú ±AëÃ+Ϊûâpà¼Kª gNk§–OÛMà¼äþ)B`ÃÝÝž=ŽÍmP<\¯¬‰Õº¿íÉi”Uö΃=×¾ A±ï;®W\¯U¯ªµß˜¹ªrÊy(Ña�!töÿeÿÅY �gAÁä);øÍ×í1;øLR(»Û�œ"Û9&reì�÷›Û¶ ûÍ3'",Q8Æè4�pFöY$°ˆ8aQIð÷ÿè­/<Üß%Æý+!„7Eä ù¢ªÜ�¤§žùéŸü³Â¯ìÜTóXh`FÉ[?ðR&9ö=@>QCÓ13~ž'­öå'vÆÇ”é[:Å™@jKŸ*N3 ²{½1)×#tYÁ·‰½ûá0Šêõ©Ýô~î£rÀÍ<…ÇWÑºå Œ�.Úˆª1À™¼1FPç}OýÏ·¬¸©‘È�£&&Çœ,ïÛ*±TO,Ä5xDô$j B§ÊîÁï6nŸÅ~}§90šID+€: ½JßDÅаŸÎ¦Ø\/z[{Hg&F&ï³E]Ðc Õ”™ f-éæ¶�€¨ý&‡h‘|5x3usËñP1Öÿ0€½ÙÎü7¾¢ý8´ä(Ö/™9‘à°îM/â“u¢[[pÐk7ÿÑ‘YF`«Ä ôø™UnrÑùÜû^'±‡ñK�­'v öÑgó§ë#}DŸ<1úhîG�4kûÓtãzvnM»Þ: ‚Æ“ë�ª�¼i¼®Î¡RzÁ+Åd0룷'/~Ð/YúØ6ž0v?ðz’MïkžvÕÁÜ�‚^¤{Íõ³æ¶|8–ö¨ß¶¿ö‰OýÂ_ùÍßþ‡þmv|¹\Þóìßsìô ”…¨Üã[€ä{³4ŸÌ�(eþEýϜ⿼ßÒ¿Ù1HŸ!úu+¹<¥è€FD és·ÏqésHú HË`ÕªU«V­úXÕ"¬ZµjÕªU«VýËM™¸«øƒQ·ìÞ»þ_žárWlÿ]{À“ò²�=$Õy¡‚ÿ" 6b—ráɹü€‰�rÕ6r¬(ÚCµó18Y{²¯*Ð,,)àûõzŬ…~{Pe·[€iÄ1ѤŠšÛ|ŠØ.pÎ%U} 5Ï~ßw\³@SϼóhÑŠìkýcŠ ÈཱུÕwÞÁ{_s9‰(«j"€˜£®)Î!Ƥt5Ž�¹E=xïÓk²=?gÅ�sé� ªT@ lg/výÅš”9e„{fçîž=ó¯<î.—;OD>Æèöýê÷|ŒÑI/"NUýÛ?øÁgß~ûí¯]ïß{3„ýK1Æ7 òEQ¼R\Î�_?æ¦Üå/³LøáÙ²‘üÍ«UåkÞ÷Ò 8rȘW½eª\ÿ[ŸS{�¬6/ ápÝQ�ªñ–]Þþx£ŽFÚ‚¼B�žõJбAS lD ì·¦=Ú¥Åê�î…,ª_¨j6ÂàôpÀ¸´Ï,Î×U1$€™ò{F°h¡(:!�´Øu6âÖ,¶óš€åŠÓ+L~¡t¸0D„úÚìä2�ާâ¶�Ýh>«êÐ>‹?!iè!†Å̯’‰ÜŠÞ »�Æ0ìXk¨Âü£]OЯ�å{mr›/íœ5‘F9Âj㺱ÔÏ;½m‘ÛJ]{d„1Egg$½vT°×EG�sÐY�U½‡³vâZ :mÁ8k¢ÀlùmÛUgíW·«žwÞäõ4q8�“‡ÐB>²HUR�6‚Ú­®ªS¸ü ¬>ÿÍØ~(wÒß"-²;n«§Ÿ¥>Ñ_�Ë6=a�tr�y¡{ï³C~™ËÐËÜû?vo‚Û/ÒÓ/ýéädú3ÜÝù<¿M³¤:å#®OåZ½sw÷ìÿòK¿ô+ÿÊ—¾ò›7Š<@uwŽwf%â+@ Ð=$¯I9L$ ‰”ç €«ä3"®ŸÉÚ—ÃvñØÊg ïP%{ÇB„Èž?·œKŸ˜Ó69Ùµ{Jbˆ …x½`‚U«V­ZµêãTëʾjÕªU«V­Zõ)Ê6ʵÎ"Pì8�Ì~Û°]6lwéAPR­»‚dÂ@ù*–õaßö‘ ¶3Á³ƒs[Š(Ù’@~ E5K<©R8µ‰ˆEÙ2¼EDé!TRd°¼D‹5Èü¾ïU•o�žfW)iŸh®q8ÆòúÒGLÖ= )dDÐBÚ¯ì{RF#"9[þd…)�܆v<\¯¡2 8Ÿ”ø)²`ÛÒόſ"JÀC't�|¨ÇM €U50r¨í«ü%Z·SÈ"I±ÏÎ;uLÎؼßü³g¯øçÏŸmÌäcÿío}ó3o}ç›_y÷Ýw¾z½>¼÷ýK!†7Tô@¯°•ªVžêÇ[Û&?�*fµVûæ•#À¬<Õ!:`ÄqŒh»tR…;`Ì€ôö_Û^mvç�Àèlaˆ+MÖ�p݆ÓÑgzªjí�™1ß¾-,  S½µöµ¾²ÎÇœßÒ×¶3U{ü›kÙØ:zr,ÂhÕl•°½}:@¿R²a‡6W…´‚ã7@¤"ÛΖ¾Î2JþóÒ³dƒšžÇ­h‡`´öÚ×rE'M›´`Û¦yŠ~ ÷$3ÌÉ*…Eø8î팻õº]­dˆqÀö%õƒ))èû¨ë¢#BDsûòjº,““`Èk6v \gºíèØ]À©›G¥z¦&æ}÷ú)‚Þ¬ð�J½Î·¢,= Ûþw2añè h¦:_ÇÏ@Ðâ0t<sž þÛ}“æ9޹Š_'¡–™e[NçкÎb5nØh£¸u-$C‚Óã9ÖÁMf ÓÍ‹Çt�yzVº¾Ä_Î×Jzâ6^È~3z‘ãúàîôW£!AèQ¥ýÓ�÷<2ý€ÞxC�OOÚ„>Úú ÉlŒ�û½W^}íý›¿õ»ÿû_üìçc|ˆ1\ ¼«ª0s$b!¦HDÒî{w´(Ú}v!¦ìêŨç Öà>“µ�Ãæ78ßÁ4o/äÏUû~ÅÍñ¾~–H®ÿŠ>5î.˜Eµ~nbâõ�|ÕªU«V­úÕ"¬ZµjÕªU«VýœjªjEDhn›�–/ï¼Ovÿ—K³$‚j¶��ÍJ>°ýšíöc²Ûž\"ll~›*Ìh.R›@¶Ñ�IÇ(* „‘–�hGD(íÛÞ•ô’ÁfÏî¥ "±öËH(ŠùB`àLª(¤�‹ý~È™ÓÈOjý¢Ø1ÂÅæJÊÿëŽýº#f�þoÛ~óØœoûªÝgê5À~Ž)p.»+4k΢à  e8çˆ;.ÈE÷%Qò÷Ú~§B1 …(ÄÈœqP8ç¼ÿéO~ô‰?úƒo-îׯîaÿJ ñ+a_•Ï€ü X§)˜ÐÆÆˆ)¶ýö €hÙä°V gIœ=GÞ;yƒÌY+@ŸÞAfàWÕtÈëÑjÜÄÉ+y¦�sd”Ð4N,ã–1ëá–�p t‡Kýï”*ÐÔ9 P˨ï¨ ¡bõ77—ºÑm:®« h©*‚ËùrßòÛ°rAïV¡z´ƒo�Þ¥&‰¡µ#Ï›.O2-{ÞDMt2ãž: i'D½Ò›¨åˆW¶þõ4Ÿ^O‰5uîÖ¹D�«ƒ%ûˆ6·€Óð¸‹ü÷9mük7UM\@åHÜÈU×Þ©Dt˜Êýì:#ߨu±›™:ÆgShbMßíïÄQ¡ñô––÷„ŠPÆ@‰•0¯¨n 7bµ †}ïq–ª>%¬|Üï^[,íiâ¸p̘1ógr =][t¶ÔÕëÝÉjûø=+Î" ή 84z$xÕ�ŒôÓ­€Î2·úóÃQØÓvþ²à¿~À=ò¢ú/è‰ðBãq²„ŒÃxr·¥1v½Ü=û7?óéÏþïþÜ?ò—þ*¿à=Q}Pà P ’X>Gp‰ŽÑ‘gbÔ” Ę)0Á¹ëæ¼ï݃òµÓçX2ŸßÊg†�?kĹ9¤Ï)uÏB9ÆMëGv€‡ó¶m«1BιD(_µjÕªU«V}ljV­ZµjÕªU«~5ÿ;�<$$«x"•È’ýžU"Å¿©ëC›cúŠBÌÛNO£˜Î{\¶Kzàä¶Ô•ôŒ*«öÔ|ÉÔî˜T³6‹]š @³áo€}òCL*ø=`ÏŽ±¸äþ`cÐ"bg�k‰28$PQúç× Ÿˆ*ù ¨äóõ™Ý#0›§“ºFŠ7Ÿ‡ËvÁ³gw¸\.É–„(!»7ÄÚ–œâ]A!ö �-µ+Æn HD'p"$�sމ¨|9"bU­_éwLÌ䈉™Ù9vìÓƒÆgïüäÍ(òù TÞð&€Ï1sz`Ù)„M^ø�M3ÛõÏ{o+ìŒa}Q&ë 6­¿ïM‚©äž[E²i{—y>·Œâ2¹ûÓÜÝüƳïÎ2»0 8“ŒÍ¿ÿ×¹ Hщ�¼Çz=ÁZ´;>%2d t`b³6×Îåàìðt¢°k€èÑûÛjìéðp6F{}œÝ¡Ó[�é×<¦bCšѹÑ4©!šXK cûÝŒãm¬€Ù™œ„1÷Ú€Ööœ€ù ÖV ¶õh¤„Ú“ÁZITr°A/ןòÅ”²€G@å{U~qÃ(¨póûñjÝ.Èv–@ƒÖ¯uÎŒ˜I�H‡9l�ž°Æ•˜X.…¦k`·M³nœ8žXòL{ÍmõÍ:'Å"ß�M:?€âhAíX­«†]·jû:Ò�N,ü'½dúSëúc²sqâ£M“i;s‚Ñøß³¶n×°8>�—q¶BõÇûõdàÇq}sÍ«'pnúõ±}¾8¸=·0{:û-Í/­Àcøÿ4ÿäË•¹yÌvõû×£�>ì†}à¡ç¿�°+èýŒÞƒÝäPÌâ&tÒçüôü•Wþõ/õwþO¿ø§>÷=ïÜ{DtOŽÞð@WE0›µ7¯Ëõ3�€Óý5ήæëiRß{8ŸœÄ’ ?‘¸m±ãLüvõN*’L�P¨¤ uC©wFÄHŸ#…AÕ!ÀÁ-€U«V­ZµêcU‹°jÕªU«V­Zõ©( B�mïC@ˆ{~X�–™m"�l‰ŒdË_ìòC üOY“1«ÿ¥ÚÓ–(�mÛ°e'�( @HŠ7rû­`9=Àª`95p±(VŠà¶ØVª£Šº=ìI¥RÚS'IÁß«S MI¯FQ$O4“bRús¹÷’â¿´•œÚÑ�±Y¾/± ­¸ÁÎaÛ.¸»»ÃÝÝ3Ü=»ƒcFŒ\³õ”¼ÏBN dõI.ïCÀ�!«[@Š~àÈ~O`¿gŽŽ˜<39€<@ž€SUÀ‡ýº}ó÷¿þ?úáÛ_¾xï+ûuÿR á ùUUu”"äc¯jWc[bfRG…ݪ*ž $„Û[¾Ÿ¨N©WŠÛ7RÍ&·™Ýè2—iÔŠ;çúÈ·R#òz,›�^@òÃ÷‰=ø67ÖÍjÈ –žäPOÁ7WзèæÁè�û­=êۀ؄Ð'`VU9ª'ÆÔÔ,¿ÕtwüÓÃ8¡6Œ8™êäœ�yx¯Gš€ùuœÐÀeh¶ô\eû65(£mŠ�“¨@­BE°n‰¸Hù¯Øk–Á'êölÉO³mêq|YG»_Ík­óí *H ɦ‚Åa “8êpF©9 •6aǸ}_ê vä8ê@ÏÑ!dÜóŒèq2V3™�ÈuŒCÙksh×M@r�ì¶�[kɯ@ô¸ š;g¨eFuë Í×);8�“ñ§õâ´ËTú}ŽÁífn—q2Ò#† –ú=Sþë¹ïÁl)­o¡¡ùÖå'.5‡5|îr3%{è¼?+�-ég®*4®ó¶ë`¹ñØ2û4\—&(ýÜ}çE€ÿÛ«ÿñ�Úçx<­�_è8¶u+eF_zkúá´pˆ|ù0:‚>€fÒé${Ú9¨·£ÌoÝ]îþµÏ|ö—ÿ�o~å·ÿ>3ïÎñND;]‰é Ð`'†�H Àn×¹‘UHTIféóS÷)¾Ê×ØÜ &†'P"d§Ï‰®DS‚Rq k>¦*¤q¢äP—t4ÒtúLÙ�DÅ™³jÕªU«V­zÙZ€U«V­ZµjÕªŸq�=\I vʃ@b¨ö÷”Á»ô ¦©3¢*4+ÈÅ(í“•|³Þ�19 šßœT$þ²Á{WÕ&Â�šÈÚ@à†÷ÇPÀúœbYí÷ÛWï9+L‹K�¨ÔÜÊšMiÜ 8Gô9÷ZòQcGÊÇ|Ýwlûµ¶5õez�VöS`ZÏ~ó9aÃÅoI�ãbßwìW@UYD\ŒqÃõêUtà‰ÈÑÀ3Ãó÷~ïóü½?üÚ{ï¾ûµ}ß¿Âþ†ˆ|QD·â;ªj5ÊMÉ ¥¬(•ô@°*�éÜp¶äÌRpyÏ9*ŠHƒ ÿ`i\ÖšU?xR÷$«®7*ëÑ=ùˆ·%¼­Œryö8]§ýÑ®1+˜ªÙO3¦Ñå-vA1Á‰ë¿½ û�`ìFðØ‚ÿ4è VœfkÏ»û4 „£mÐ*»ÈÖd/jÚ6µÍ¢Ðèx¶ÚîÈ]lŸRß –(“„à`Œyçæ¬uöõy]Œf�͘»9IÚ—öd§.vÃXÖ«ŒVù8|oų�MÝ›B„Aœ\_È\WÈvBi¥(}Œ³à¿e­mý¬ýxR3¿�*8kÓÙyôŸ#­eM`êíø-³­Øk’(æ Ó�ûÜêßÉ0d†è;{‡=®4Uá9N•£ºœOÖÍÃx´ëã|Ût òèùÔVœ€º§v+“µ&ïE{’ˆõ;èBc¦ër¹æèÐ¥ýñê0„¬ƒÌSKOY+�A¿v Ö+þ×õwp yq(oÜWnæœ>uxêñ>öjÅGÚÿ`K_ôœ}((ý·Y=½VàeFèxôÓËåòíõOþ«¿ý§ÿá—˜\"±‹Ì,D,E¤Û¹µ¿rO "PŽ-±Æ "©2H_"„ÒçA ‰ÐLYÉï‚Gô1¿¶]˜Óçš-»‘¥Ïåófùü¥Æ¥-}ž´¤k€’ œbÕªU«V­Zõ1ªEXµjÕªU«V­úˆTÌ`±d ùªr/ÙÈœe˜ÍÚË»zÑf�cL™�1Ö¼{ $•{�ÈY’é±–B%š¬zªê}æþ‘oúÙU *åÕ§¯¢¢/�ßcäÁ†²f(ÄçÒû³;�s®’¬íú ˆbb 4)ìA«KÀ\T„@�Àì¡9nÀ¥ã÷.½ÙaÛ°]6\2 Àû Ì ‘dÓAäἃ÷©�>Ç1€‰)€D…¢FŠ1’Ä@ €Ù11Á;æmÛàœ'Þš¬J"‘UÕ‰ˆ‘í�Ÿüøoÿàû_}¸ÞÿV ñ«!„/‹Ä¯¨ê'ë Ñ@�þ%Õd�É(ó‚µ8;dE�rSý� ’ü؃ª¸ýÕý!·æÔ†½½.C„]¹r6[žš»D‘w&kò™¡}# ¨f`$DZ‚´Ë‚'¾÷6ý8Mòáö@µÛ—Q]—ã¨À�ÙnCdÑÞµºEX•™~m–ê8d‹k÷};Å­Œí®«ò1Aë£}ž¯nönÔÉ©#´¸O j]`0p×óÌòižº!ŒâÅ:bH�ºéŽ\d _5ç@T€©�ûÒ·xÓž°@„¥¦S%w]—Þ¯êAûû~~i˘œÅ6hÄ Æ Œ2Ýt‘µÚOªüCpg¢nž”]ÓxR&‘Ý8·ËØl¶Ãï̈ŸNÆ‹�¾ÐŽƒa¬†±Rççà` Î�ö¤—‘\r¦R¥ñå½£JûY&SX»¤Kº™Wu€ã,£k¤öçµ{Wÿ49?4Ë ×>ÖÂÎúÎ= •¨ÞŒ`!šÈˆÍõOždç?´Ë^ïr?�öDÄ1râ|e5ætî<5çžúóà3¬o/\�+öË5ôèö1ÝÚ�ß¾ rÝ¸Ž¼H}¼¨ô!lK_°×^¼ÿ_æ0ÞYà)m¤‡mÛþê+¯¾ö¯}í7ÿÌÿõ•W_ÿ‰ˆ<(ôЇ¬ø�’Y´€ló_'c·–¢s ²…옕×$¤D«Ù8€r” A5v¶ýÍIM„zŸ(9Î1ù³ $²D— Ôþ–>s%â�*jtÙªU«V­ZµêãS‹°jÕªU«V­Zõ¨fÆòW¬uˆ,HùÁ Q‹W4�Áíb)1Ûíg@ù}U} YFŽÏ›Å~r€’•%ªF!š²sÍf¦ ür… À“¥3µ(áôPÌ9~óü¶U@i“µþ�1ÙûÇ�ãòêúÐË'R †È°7„S8qõxØ%Âe+€ ¶Íƒˆ„àDÀáT ÊðÙ2“9ñ`Dq*ªÊÙv?1$&"&bvγ÷›sÞ11¹£ÿƒï|ë×~ôö¿v}xøJŒá«"òùÕâƒM£oû˜é 4€•šÛ Ì 5 d/i,¤DÚ;­�àÿqàÆ1†h€Î:Ýn3Èö¸w°Ô®CÍDDpSMkV.©ÁI©Sœ¢d“éžÚ§¹føvv“Â’¡ˆÅáàF¹U«öÆÚ©mõV?=Ó÷;uyòZHV™þ¡ÉtöÇ]>‹Cºã l§^íñ»{t}£sqð N/‰"Xð?oSº$ídÆJÉ1%{^4E±ž÷EÅ?édDkÁãsLPzàOœÕy(sƒLfp¿öŽsȂפcdÐ!÷g‘×�dŒ–ûa{ìlÄ©R¾�ÿ…ø%µ]�¬B–³dÞO§'³WCSGPû±�3‚’Š §0¤•c>ü(¼7‰2~´§‘–ˆœcFA;Ý€À0�?ãüg³{˃QKP¨ÓKº97ºˆX÷�ôÎTú†9aìOªù€Òà& Ý¼9*îËcß~Œ±�@»cäÅÈ u±& üŸæmœ^§Î2Íg×°Ö½à?Ññü“9k/žOÓ%þ¸›}RÔ ™çÇ>Vœ^d[öŽõd‚ÈÏîÓÆ[ýþâô%[15¡÷Oæ ¢w·íòÿ~õµ×ÿ_ùÚïüŸüä/þHD®"ñ*"W®P\\ËõqæÖf‰éš&ǵ!ßo+1*(î9N,¹¶Iþ¼ÖJ Oû™‰à�ƒø ÈjÇ—\Ú4VÇ8ó9ˆ)»§%‚�H"B×h‚B„v `JiyŠâúP¾jÕªU«V}ŒjV­ZµjÕªU«>"Uràc„�J °ës¤“ò_‘š7­*� ’”1fEG±âúë¦fŒÒÞ[Hª¨ê·E�ŠÙ(‚fÿﲚ¿Wü[{ç$:À§ñÎ{ÜÝÝáîrÁv¹tê{ÍËÊvŠ @aÙ5Aê±0sgË]bª�u>öSÉß4 2{·y8¿¥‡îˆ¹Ýš]r<«¨“}Dp ø£S‰¢ °'‚gÇÎ3»þàûŸúþ÷þèk÷ï¾ó•‡ëÃWÂuÿrˆá7$Ê+½â·”š\ñö»©%²RùŒJ\ É6æ ôÛ= XÌCÎCÎ7N@ÿÉv�‚Uk{”A{pzL¦iÀ2Â@JŠ*UI n…EÈU­àqˆ¯6à{Ù™NSÞ!3A"ƒI²ÇdB[@¶žGtöçPã°0Í�n*Ñño%mQ§£åÏÖÆdUx�O,Ý kû^ o–×=Zð[ûyMØ,«Q g\²c€$æ@b¦J‹‚íb‡—uª%ÊZ‚;LÄÂñ¼�ø}î’˜¢ º|>óÎ�È�×^e‚J%—·ØWï©KÅL_µjÕªU«V}|jV­ZµjÕªU«~Îe�òbq/¡Ù0V5‡šêU}‚lï¯*Pi$€dÿ/Í&?gOŠUÔG��} ÕHÛC%( ^áØÕ6e<¨‘ª¥d*uZ_ïrô€xÖDØ6�»Ë]ÿ·í’ìù‰RÛ56@3·+„€šSB…E]³v&侈Ð�P@.—²ºs ŽGPj¿sœ^G„(‚(A•E„ põ£ß÷à£êÀǽHô×ë³ï~ûo¼óÎO¿®×¯…ß•7Uå—j&'ŒzÓXôžó“!iTdÌ,Ïn J]N<+ &œž&Jâ†ÛjÏ10à' ,}hãf 1 XtxÞÚ­˜A4‚™D]ž)¸� 2à—ŘK²:ØöC›¼�t.‰¤ö&@Ìê *«w8¼ ÜÖå¡×þ6ß�Û.Û39¯„Ïä‹›`AÆöo#Y´¶¤÷—HÚS§;=ç˜u]o™„@#ðß©ÖaƒL;@Gƒë™"ú±œîÃp­’{´œõ.jÝÎ[ðø8®uTEWuëÄßJeHÙXâ ˆ"@hÀã<ìÜÕãK!#ÙÎÆò¾ô-÷Ñvþ¢KªÀÙzfâ€Ð;Lç;`TøÓQÕ)ÔË7ö\аÛ9hªÍía~A®ëR%ÌÐ|›È6!"fQÏ  Ž+‡é¡u¶ñíœOÚ3ÆÕØì׈�¼eQ3fûùÙÃø}TÌÐe£ o{ÿë^Ý?ÿýÜ<#i‡Jþ�«€Òñ�î,šÇüã¥úˆÙHÏË9®ä–ئmec#tTûO{`üM¦|œ©íëíÍ ¨þsÇÑuÒÖ¾Sç€ðã[üHyÿßIJ_d§Û¡OÚÀÏòs Þ¯•ÿ˽�ˆ¿»mÛ¿ýüÕWÿõ?�Av´%ªª&ú�"ŠBŠu”$3¢¥]÷ ÙXí=Ìu;"NdÜú:iלBü+×~ât½çap¼�\r`ëØÅvˆìaGÜ3€ó áïUÝp"¢$U×=¹x˜QœÉj*¨Ÿ¯V­ZµjÕªUŸZ€U«V­ZµjÕª�HUå_áÅ*ÛÓîLHÕÙ?ÆØò"¡€hçPÔˆªÔ=¼J�Áò©˜ö©L´Ù“‰¨–ýéA—Q²Â¯ ó4Su fx߬ý½wØü†ËÝ]ŠÈà?[÷r€†¢GÏÖÙýñ·€ºOÀØsRUÆ*”„4 t˜�ªrÞ‰‹DŠªðɺŸˆ Þ3Eu xŽ!:q|ŒÑçÛßüSüý?þÓ÷÷÷_ ûþÕö/Ç(_t+ ºÍ­o঵ݞÊd�ΪذóL/s:Ÿøþ%{˜ŠÞoÿÁݳgÿÖ'?õ ÿÆïü™?÷·Dä�ˆ®LîA%îJ.�î³OùÜOˆÌ5±Æ˜iQVdH©Ô ^úå3[Gö#®¯OÍìßœ#Ñ|&O'W™Cv¸&·¸¡¡ z8—­þ£"ñµÓq†°ãázÅ~Ý!¢p.©ü ÁœÉ!HHîj‹°jÕªU«V}¬jV­ZµjÕªU«~ŽEtn†©Ùº^)+Hœ}0–³cDŒóC £,K’$�<(NÅN¿=詹”µmæY¬ù=3Õ/";cŸ’›YŽÕ9×,Îy\.— þ_.[�(gÛj iÀfvÖzM$‰V�cf1+¹rX ED™~ðìØ9vÞ³sä6·1˜˜Ù³†ûí÷ÿãðÅþð¿ùpÿÞo…¾*"_‘ÏæVM]šÛO"¼QUÚM…Þ½÷�=jÁ�(ƒH{Å¥Áå.½qf7Ú«�+69XvSs.µøY× ±êA7 ưp Qß‹£�~§ŽÖª»¾¨Ù5ƒsàTÀçÚ€ªVòé_N«^·Š}ôjX«>[íÙ˜± íº¤‡T¼([²G;4Ù¿uªHNdîK �ì©W›ޝmsy8~ˆ™ �Õtæ÷Çq`2ºËþŠ;Á@ š®%¦O‹“Ez¯TúÀ p"‰Ôæm÷¯4ʦ²4î�[H?š‹Ã�”pxé@<¢ P×®#ÎÛÍÑrÜ'þ9X§Ã|7Ç3"˜ùglãõðFÇ™ž¼Ö¬ŸZvLQÂù»¸œÞÍ@ǯ!¤;Þ1¾ÅFصsº¦šuT‡qI†Œ2tb;\ÒA*=‚ì�ê4QŸëÉù”[n òØ�¦¤&$MÔñKýîš3 ³‘�–Ôfï’û@!¨‚¢…#"Ÿï�=…¯¢Nbô*â$Šÿñ�ß~ý‡ü½¯½ûÎ;_½î_ ×ðå®_RÅ�µ,ÏVCà dFMUl"“»·ÙcÔS[_´ýZávÁJÕâZ |ï­ÐðŸæÊâ[öé}M”ïhmAþOr­ÓWÔE Ø>±Q-îÜ€{ÖAG»èÖd’D5V¯G¢Ã­#gTz°lÚôX˜I•º<öo@hó0Z{¢FY'søahÙ‡×ÔìÁ� kK@)$‰צÐÑŠ;+´ˆzE0õöçjÁÿÙ=lû&˜~§"õ ìü£aÂ%\‘š†oŒz ¤Õ¶ �|êôŒÓ°~ç1YcWòx•� RÏ¿ Žï=í{‡Žá$öD““1›˜òLtY½²ùX*i‰,®•LQÞўʚ§ƒ£Ã¸éìï�ëÎo}j³ßæ"ê5¢dÆ·1e,üiXw;âES€ÒY[:VÀq ÚÁR\!ìá‹N’SO ËY²s@uÃb],ìÚÜ h4“øhz¼ˆˆrúŠr�o›Òîœ÷s’…Óm,‚Úèš ï “?ªú¿öé!Øï×Ü)øÒ{óeg8¤91ãQ5:n·ãx…¤ ¨¶>·€s�ãË×ï§^JÍ~úzzŸmúÑŸ‚ÿvùœžcz¡c} Ÿ¥¿öÓÕ;ÿ7îž=ûk¿ðéOÿ»ñ/ý“ÿþåòlDÂB»*¢ˆ@c¾‘ƒ"€(Ó4%6•}¹Wïܬ €Áur„ÞöŸ™áÊg¢î¡Ù–¿/‘Ëê~žî‡™à½ÃåâÁìC€h€ó¾:ªSºç²QKš\Š@ˆ’ÔÿW¼÷Þ=îïßþG8G)J@"Àår�¢2×çñU«V­ZµêãT‹°jÕªU«V­ZõsªQùËäÀŒ¯¶ßü/j‘d�ψªŠ?ì{R•0Á9T ýdGY€,¡)S’}¾BY�©`�Az›—Îd¬*ëQŽËæ[–ýŒ sñ½O¶œw�‚´é´*Ǻi>V•ü½ÏÛsÌD`a�z%öªÎ«SÏÌž˜6(6ym?úÁ¾ðÎOüÕ}¿~M¢|EE¾,ªŸg"¢ü`®;\¥©Eøáa8F($×ËßÛ먀à4ÏB&lŸ­ó§cU�Šó:æ4ŸëÚœþ_ 9FØ_ßzZ;æcÃNÍ� $;[g£Ò£Q7{ÿÛû18"L”¹“RØåMœìÕ+Î@�Ò.MëVL6µ3/Î PTA,…<`òîøO˜[ç[ óÀרãôÈ4é@ùAå?WÈŽUëõmÀ¯.nºî*ïߺuÌüÅgû³'B»€øDä  Xl2á©æ¨SV¹�ÈÆ§D+ún ²ÒpŽ1�=ÊËE!Ü¢ €Þ2Øõ¬ †ñ“sä‘ÌË91Çf¼÷öðó¤2§¢•LÚÖòáÇuÌ‹zÇŒFÂéãºsK=ƒ é _ƒúýöGÖ¢Kfàí´·¦¤†!>½ŽÒg+Í@ÿn#h$�©Ý¼ùùÄÂ_O²ÜËüDzèI'LŽßÆHPã5* )›}«¹VœÄV˜IÞÝKUÐÊ.3Ô÷îd¥QªS^�× îdÜNEÀ¬5Ä­‘¦èih7Öœƒ��¬’óW> â)žÂÐY¼Ê üAƒì]Ø=ýÕÚ=;Nør/Q3£“éþ@:UŸ0VßO¯<½ÿŸè¢ Îù¿³].õÕW_ýw¾ö[¿û×~ñ—~ù'Þ¹Ý9¼w‘™ œ8'‘•ˆ…ˆÙî?æ{­Dª•ôÙ¢›óf}±ÖÿàŽ ôk¬æu«–�O@¾w®#1W×€l|&¢b%0Su `Ο¹¢$§�òtŠZG �ãÕ÷•9êò¶lt�HŠ Ø÷äp�}ßÁÄU0{8ÞR{œðŽ×ôU«V­ZµêcT‹°jÕªU«V­Zõ©¦&ÉJùü¨ŒÉ��Kwò¦¤vNêE‰Zs&Ù%¿rÉ¥LÛÓ np~�dP‰Šû$qzàå”AH€ äð\é?Ä÷¥]"±#Xå̸½ò³Z¶(»™˜”•á=13‹Ž“);vä6GÎ1£Xü‹:¢¸©ª¿>„gßû÷¾úÞ»ïývû×Â~ýJH€ÿ't´ˆ’�~f6¹ìÚ©ÐmÂxÏäû4™ë橪gÏ—k,ƒ®PÌ=˜2ÚM[Khjð·óÃÍí§ÑÕœ@Fð¿‘vš½b+?<¢®(ê8÷Ö€ô6íútgt{Ãë6¦­Ž¶��~Îâ€]�X*±ýƒqµ} ÔGÚÓü·D‰Ný¬G¤uxPБÅ1†¡×8ªæJæ¼T;XÅS†ˆÚö€} RœKš5=à *[Úd,zÕŽsK€ÉçRO�6šëXË©©FvC·_tä”�¬BjÜ9Ÿ†ÎM@ H U¯Y‘§�²_»5£µGÌœŸÀ³4NèP? áj £º¦”kŒVeß[I}©Çs`&Å™¡®«Cߨ‘Þù y1Ÿ™w̱h�°q”œí8d2bì¸:É¢ƒ¤ÝXÓ÷Q;zh¬Þ<sÎÙÝä�œ÷V5»E‹Fè}íh\½Ù^;×Àê¡Ó.>¼×Ë&13·®[#�¯’n‚™öZj}\ç‹ËÆ©[‚j]#g· /i¿$¦{K~p�9Ý�º½¿àH”¼ÙG¾ÎŸžr^@ý?¾þã0蓎M9Pzú^äýêœÿ½íîîo¾öú'þ?o¼ùå¿úKŸûÕï¸WÕ{"º'¢+f ÌN¬e¾*àXŽà»¦È£qݳÊ~U®÷ü‰À5Àˆ†µÕ|~©*~f»LÀ.Df€P§`á��ËÕ= \¿E"ö°ÃíñêÜ碜ÜÞB@Œ1m7;Ÿ�LÉÆß;ï=ˆ 1H½ïˆ19¾Ç8lj±º´0¹5FdÕªU«V­Zõó©EXµjÕªU«V­ú9Mý_r$Ë)ç<¶mö]à7"B ùÁ|HÈ_"€$K÷h)ÒhÖ–Ü+DªÝ>Q%T‡éóæ[}y×ì2-C¬i[R9šEdPÅF¤] "bfö3{Uõªê½ª°Á;ÇÌÎyvŽò£·?ýÃ~ÿ7¯÷_ {øšhüªDùu[§¦n�žù˜ê_Òƒ½üðÞ…ávyó0 �Au®t>CÜ‹-éür¯˜,í(¶á]î¼Q­Ö¤çRPÞÈЖQu>(Xú�šKz±âŸߨ4˜ÇdÒÓ ÐÇè8aì8Øçy“‘q“QjÖ™P�îòÐW»ÌøfføßH›%¶þš2¹€ƒJ &C™žëþéþÓIõ1†Â*%›ev9ž΂PÕÏÊ›:»Ã)=UŒöôÝz5­=~ ƒâ“¤ªƒ6ë½�~‰ÔÐèQ^©ç“bÔØ’OÔãhÇ@a°¶wÕWŠm�!¨”š�¹Éö° x9—€sæPˆ&‰Ø ´'näÉ!§ã=™gBºQ=Q€O^G¤G£kUCzèÉ>¶#i\ƒ @O®¹Í� ÷' mu¾ôn.g3ÁÆ”õ�º8�qÜô‹Z'º”ð°3x†CãiQˆv-*Qý@¶;¨wŸ9ú¦¤þ1ëu½FêÁ=¨Ç ápØtqE q�3íÐ.nw�cG=‘dÑõ‡N¯‰g«¤¤¡ž—g®uDÇñ`'®>…Pqc1> * sH…9›´Þ“ⳫÎg1FàŠ±æAì P°cÄðp½âþzžïˆÁ9ŠÍqr@s>‘•vÐÕ¥—…ZÇ GͱÀ;‡mó¸løm@qëCúªU«V­Zõ1ªEXµjÕªU«V­úˆT²^×JÐl1é½Ç¶yø‹‡s®=ÔÒü4_Ú—æ¸erFRü[ugsIÔaoEE^ZÃLQˆ$k^‘–é+B °p²?7üëñ¨V匱‚ù²‹AïPÉp3Î^U73_\ ¸€p!¢»‡‡û׿ÿGø½wÿîŸß÷ð5‘ø†DùSS�ŽP•ÍöáeT;ël¢äš�»—ù�MÛ@:¨µm`'¶œ»àü9xX ˜�>G>�êý3ÿb³Ÿ”IèÎÓ¡¯ªC*Ý”*úòN�mÛÜÙt[×í4Ÿ=à5ó™wV"ŽÌ/›�Îq$r�£ìªD4”{™¸;\¶­•Ë¿>„ªÊO.^RÇ;qQí»‰ëX&ÿ–Éå{eÔÏO…(×£šQñw—ÖLÀdb4¹Bæ¾3\u°„éê6&!\ÁÌ1âz½âa¿Bb¨Ÿ øww¿¥X5‘ˆ¥s6`Ê1iÄpÞáÙ³gxþì^yvÁ³çwØü İ>�¯ZµjÕªU£Z€U«V­ZµjÕªŸqщWj !=ªUQï\V»l›w bh´2²ô“ägKJõáRy0ì7…q{¨Åœ %ç+ksà˜@ø5Œº[Õ€öŠ5€âǘ9Å`, xAÆßE—•þwî\Üèî­·¾õgßyç§ÿt ׿Bü€m vQukSêáil[œŠd0—šx÷t¢Ú¾N'½ÌGK|˜‡�Ãóc �€þ»q5c�nµDu[Kâ^§=o¶§ š±Þk—qM4�6èÅp¢Þ®µ�[ëÏ~â4€Ùy:˜Kl²Ç“S4Ò +™ÑLÔäšU3Øä,Ì€×$7c™nû¬;‡­Ó*«=HV12Økia„:•lwÞµíÛB©(>ö Úø°`øñT4òGÛý1§»7hºF¶µFP'rËy˜ Ьô d>î/=9zûÂÁñc\e ÊKÅ="ÁÆSTôÎ�šcïàÊÁYalïJ3goÌtÃ&@Tû‘B“kÊtÜõºÑìŽV ýo À 2¬ÕKúuñl,¨‰@hóVo�[›5dˆõèÆ‹=:Ï6 “}ÎrÔkTMv_P4å=Yп.*&óžÔòŽãsþD“ [þ–'�{¶Ýq}§#1iž/>Œõ²¦ª�yÁôÖ~êœ\SŽÇ6ÛëÑøa—Ç“Øh8éÆ[©ê§Ór‰ÒÛ�?»Yºq‚Þ_½¨þÏ4§h1½”½úGÏŽ�»> 3ÿžóþomÛ寿þ‰Oþõ¯þÖïüÝW_{íÞo.lÎfŽD,i2 auŽ•È  *¢c”=ìö(ª)ß^\Z·]uØ (Âæávgb¨[ûÓ=²;�uºd«á™õÌ#â ÀÕ}k¼O‘캔]cT«³™½/)„„Bˆ.¤¿öúù*fП™D°‡aOwÌð›À®¹ 03DÐnbbÎ%¥?¼Àû ÏŸ=Ç+ÏŸáîîž_îà¶-¹ ì+`ÕªU«V­ú8Õ"¬ZµjÕªU«V}Dja�ÐSæ}¶‘¬ê“ú ½ñÍÆ˜É%姇RŒdåÝv�jêb?éàÝ¿y8ž(ø @hãc|BV<šª¦ÿ"Ô§Í% `NUœª²ˆlªº©ê3U}öÖ·¿ù�¼ûÞ;ÿìöJE>WŽ=PŸ%= ÍP3Á‘ÊB퀓ëNåߦ¢¬¶ÞÆšÛn³ü�-‚ óg¦zò «¤íÔa4ÿ阠LÕòÿ¨¥ îhîùÝ«?ÑL*}¯Ž�U�ަªgÍ3Ë}Íà�Ñ Þ� §~°FßãirnÔ¤‹çèb»YÓ}ÔB#@#„àX› ºþG�¦„o èÉуò4µþž%Z�Ùåønf8ëtpËît4"C¾îl Î ßRO„È}iñÖŸ¡ÎÙN5^(‰EÖŽ{ÖˇaÓ·op»8XÈ“vöäõÌ àÅ��‡“½sÐèf\mWw xVí¾4άC›VM 3KþùbE–”d®Q7¨�Ù(1ÆaCAi�ír¹ÐŸ»a¼‡u±-d"ú ‹jµ‹¾5tœv  ‡{É^Ç“0öéÈi ~ýho‘ÛSþ‚%cT7mÎ…îz eØ>Ý"ê•@ÛÀ(*Jg䆡¥P6ë=c‘©]s³®îÖ¥°û<Ü¡]Ëû·ê¤‹NH}gëÌ8Vú3×ÿt*°„­€Gå'ÅÐ6ô•>±Ý?›&œ^£ŸDW¸•¥‚'<|TŠ™è½ÿ·ËÝßzå•WÿÆ/þ‹óõ×?ñv”}'Âî7·oÛ¶ØsðÞGï}döZ«òÁ|ÈV÷ׇ„$24;‡;‰Õ È1Ãqêœó->­´¯¨ßÙ*õÉÄ5iÝ·¹ TpùÓ #©ý3]œ?k5¢¤ôk_^E!HÙѬŠ9Ó&AÌëjˆÑ8§íÙ% üN$©ÿÕ¥öøèS|Ô9Ä= î;$Dh”ڇРˆÛ¶áîr‡Ëå‚ËeƒßR@T�0¯ä«V­ZµjÕǨ`ÕªU«V­Zµê#RûõЏ'µ<AàAªpÙæ_DÁPHŒ)×W5?ŒÊ¦²dUþcx�cÔ¶œ!Ûeöycn2—‰2h#Yå_~ÏæÙÓƒªLˆ1ƒáýùü=«Ê¦ªU½¸dàÿî‡?øã_ùÁ÷¿÷_º><üDäWÆ}hç¬Y¨ï*4€0 À~[DV‚0j&=MÔªöáÿe|æˆtS›ëùßÁ®½œ¸&Ú¤›Ã ½}7 �Ú½8*@c@1¥J|èšå÷˜+?ëv 3ΰBR:ª! xt ÈÈm¯„�¯Ñ<ƒ‚CLèì˜mžºQÇSϦýo\ÙuÈ\PÓÀöØp$åèà¤@}ˆlÿMF·C\¡ÎÉ:’b0ãø@çŽÐ=š�„9®ù˜�éa8€œmÓÔHå½bcæÇYÆj#sŒp1MÕ°8äµ·cŸémg¦àÖ¡É¡B"ˆ36ž¡cЉJ¼ë·!þ‚fkÑâNJ2ý5ÚýW�ßDÈ̽Üû¸Š*b§Cÿ”]Ù�ÈÔ�¾¶æõÜ-5Qé_�¬÷m¨�À|:�²: ÿÙ1�×�é}ÄUaþw™Õð| "ÖvŽÏ$ç#­Ç6Íz?:w[�`§ÿ“~–'€¡†p4Ÿ÷}ÚФgúQ „ã7Dß#qî”,I'JÈldÎÕMJÀ#×Þ*=o2=Ŧ^ßw#ôŽåå€ó§)÷õägºyÖŸ¶×Ç_C9ù?3ÿÀûíïÜ={ö½öê'þö¯|á×ÿö×~ëw¿}Ý÷ðÞ{ï…÷Þy/Ü¿÷n¸¿ÞÑÓÎÌA¡Á9 Þ9ݶ —»;xçëµ DAØwÄñpÝq}¸ÇÃÃ=®•8ì· ¼ßcÈä§r/Ë rLÏŸ…È�(ÔŸÓ—Ï.gùs‹çI.dªÚ]OÓÏ ÀÕû”™;å ´ ×èDhÄCÌû@µüï/àÜÖñ슣@Uòç9Êûˆ¦ÏˆjÈRLÉ­ÌÅ"B ‚‡‡{\÷{&7$r„3pÙ6\.[vRàÊÜäFY^µjÕªU«V}LjV­ZµjÕªU«>"µï×ü�HÁLð$g[Æ(  =LŠ1©W2ÏŽU0;xv)€¨_×ühÊê?"8ïqÙ6l—­>ØJ }zXElq $nÀx±¿¤Ãã¢òðÊ*ÿGëKj’ýKVù?WÕW<ë»ßþ3?þÑþ¹ýºÿSéžUgqÒ9š:LµÂ=åotnÙÕ*3ŠÍÚf°Éx®*RØ÷ZÐL[.{kŒ·’o¸ÔÕ}k²§�ºÑÉö<È*Ö†ßèÁ�!½J!¤ !`1ôãOˆö¥³Œd=I¬ïÀš+.Ïw–Þ£cnywóN€­~P /9mQCþ� ßñ•š€?Ú5¯€±Ã!å1&üד1�ZìDçVp«O»ó®§êâÎ!—lôuQö�:õÂ6cçÜM}øýhá;;—Z×-% õæý‹óöcãˆP§¯Šr‚EÚ›KÁqjVК(·Cò\Öž¼bÉW6ž‚¨�óòz›m^]>:p¼?E5®f}ióÒœÄjý¯íí³ˆò¦n°Jü‹£Á8tpÛ(Ç GGÿcŸÔ¯z³¦ÎTÈ?Ä�†µkOQ2 6Àáz6¾Bì ¤@Æ­'ÖÒ³m•â�뉣Næ#sӜ̺þÕëãá\™õg¶ù>`¦½—¦ÇJ§ý¡vmÐGÖ¥“Ã�†sbEt ÙÎH030–æïì6¢§í™¹,Œ�:!œÙï�Hݳy>LpPßÇ>ŸN; ÷Õ–ã�Eõ?1ÿ¡sþïnÛö·_yå•¿ý¹Ï}áoýæïüÙ?pÎGçœ0SPU‰1Äö¸ï»ìá¯á÷}…FxŠ›J„Bˆìü¶åÏqú¼SÔñ‚p�‡û{\÷+D$)ׄmC1HŒÀ&H½`ô‚±1&Å¿sÈDßhìùU¥[Öa–A¤�(íúƒñ$Çž‰Ô(7 R] D*ÅÉèÜs¨8%·µDžNí¶/Õ=UëZ?»ñžˆׇ×ë=bÕõ ÄðްmxïáØ·ûs�ˆ¹V­ZµjÕªUŸZ€U«V­ZµjÕª�H…÷˜$1ƒ(‚³$óhRxÄóC°”}ÉÄI�uá0ýyR<6 �Æç=”ÈÌÏû%ÊàxÞøÑöž&–÷ãx=žÿ6×��{ù§›óèâ:@Ô´g°g‚fŽƒói?o¬r�&ŠØ# 3a!mQßÐ�ÝäP'ñåøÕŒGUM¤ éyTºQ �duô:'³@(ÎÚxâ: ·ÈA“ßÎMLÜÆØI:Œ‰“c}Ù5ô2Õ~-�‡ø¸zéñÜ×xŽ1öªéIg¸ýÍùúl|4FÐǦÿí-éû·Ú!-þ£Nö3ÕüGЗ骡Ù�/½Ì�ˆ!/îq@/r3½Õø°Šˆ®Î¹ßóÞÿ½írù;Ïž¿úÿûÜç~í?ü¯¿ñÇP݉hgÏ�ˆDDÙ=ŸTU5Æ !D�!j AcŒ"’!uuéî<“±˜®�¼±‡ˆàA$ñÎDöˆ}¿bW„šó’&br”˜_³ƒ�¥ŸÃÞ>wh"0ç˜çÒg#æŽè<‹*ƒu í\ˆÈ¨îUûÀ¨˜ÉÎésO&?k"t'0_O¯ ªÒù3”Äõ¤" Ç•P>Õ÷Ç¡ú€ö[cúœø®)f-߃#G%¸êD ¢)*@Òqݯä«V­ZµjÕǨ`ÕªU«V­Zµê#R Øß¡œºdçO1€‘E  1=Ô�‚Μlý(ÏI/œJ…£ÔüÉ ï·¤H�˜ÁìòÃsJn’Ç)�“0ØiÇ ø$¢�³+óƒ§BÍÕ¬1ÌÞµº0»ç^ùÖ7¾þÿèíïÿ·÷þB÷P0{Ûh˜ PY5Öíñ4˜ÜbíÑg @'Ürê±ÝÔ°�²YÇãA¨¨£‹¾ºG»óc޼„� Xçõ€ùtï+ 'Ñ�Nõ<“�˜>¨Ä©K|i�ä.wêÎC·Òò¢¶“h¤*4�\‹5¹ê“t� ^õhã_�¢wz¨GG¶¥m¿"YMŒ¬„ÖI*y—ëÞ^µd�vp“¶«‘ëÍ´…G+5þ¡‚kÚ÷gek]4л8´8ošäžÃœ/긕$¨VðjãEp$LÇV‡ƒÑ±OƒÔôCFêGÅ]šÃÅâ¾üú8À‹Ú»#P¨™¿„ä¶ÂèãVH"M>nj>5¦Ã_ª« ¡ž¤)>"ÅÄ´ ‹XvsºEwÐÍû3Rˆét=*™-¤ß‰Ì;é{Ž`Ñܦ£z2 `b:fç ïeN×í”H‘ò¹L ™ˆP)ˆÆÝÊ@£«ÿâœslZq`#Á1Á;—?w©‰ ˆ1V’©dWƒcuŒRŸ013|&zª¦Ïm¥Ç£âÖòU«V­ZµêcT‹°jÕªU«V­Zõ("ªù·¶D1Ä Öˆ¥Ùÿ�˜Àäá8?¢„Hÿ÷=9Äla Îíéá�T�c. Œ¡ŠG*šÍ3ƒ X•*=D {À¾'åŽÄBÈ –sÞ9w罿ó~{ÆÌÏ¿ÿÇðëßýî·ÿ›áºÿçÐá3å¥UnR’­WEåDj?-,Ô�%h‡6àújŸ_wg­“šë1†PÐö5‚ñé|##Ž;~®w6ëã>,8SAkê@õq³MôDí¸Ä-<Ñ‚rdPÛ.³üœSÑõIlV8™¾LÖÝY5…§1å�Î ¾u<øñCCÇÌq˜ñ˜pÏ“A‘#(DŽQ'”¨É�TXª:wXÐIŽxÀ¶˜ù0Ð Lû6¦¢ô5Ùq2�Ü;D¾ë´§çž�ƒ‰ž€ŒPçBÐâLtâ’1ë»ÒvÍàt:Wmδt”"î–F™«�Û\Ñì��´D}Öºöc«‚ãÌmÛ ˜”˜@±ÌPmqKIÌGfÎç݈�|½éþ$µüÈ}š¨½µ[ƒÌq²ƒ�“ÝšwKILtøKÝÆ`�l‘¥Æ�Ѻ‹É!5•„$&¯ÙÄâØýWGŽº¯�pB=A¦Î9ê{Mgaæ:;Ç?Ó 4~1àŸó~¼’èlŽØë¬��yt^›­NˆÇßhçÆaç ºssR×öhçÄ2D‰Œ×§?ž÷£þ' ιoz￱].¿÷ìîùï½þÉO~ý׿øæï=åµ÷ˆ(Q ¦@  D AEAUwU v€•kˆ’/lR¢hDƒ „˜ëèÝ7ì=\%þ©žŒ1ÎÎ`[&'KýŒá¼‡÷˜ª‚}¿BUë¿1ì!àú°'un_vkÎcx¶]d™Yg™ÉûÍëŒt“êk%bŒ †H�?Ÿ1ƒ”ë}CUÞ« Æ"‰µ‡ôJ¢ÔXWûÀá²mð›15Â@ˆ19Är?)� "•´œîUzç6…&÷¹(¹=ÉÁmÕªU«V­Zõñ©EXµjÕªU«V­úˆTzHÅ9Šž�RD“:%«ë5H¶g8ÇðÎÃ9NjJº¨BC²ÂLtbµÓ¢Dhþ}ú»€œCHÒC.A¤+P•-53 TɽŒ![wî;bÕú?E°gægιWœs¯íׇOÿþ×ÿÞùÝ÷ÞýçTõùA]|è�Á¶yÈ\îløŸ{°æïÞ|löÜ�È nÁµæ|§­�É—§C=YÏC¢`BãñksÝ.yú:°]ó CwJ·MŒ­»Bi¯æ?S“Íp§^i©ª§±Ýcñ æ›|Zz�ì"îCNo?,zõ8’JîçÙ�þ.‡±a Quû{’ì¤a&ãŒc!OMñ} „ÚÔFˆ Ò!뾇΋»Äa-Í;¤ùl8bìzLÚÖºžÁ8_`X×nÄ tñ&`@ô¯ªfjF¦‹ÙåuæœQI^Z]ê\íæ}‰PiŠUí Uêöë{(g7mþõ|ôë™áp{ÒFíxÝÄ!ƒZ©·¯·ëët™àºOµš×I|Á¼³n—vÜ éúÂGÈ~GOYkÎ×Ùš©òh³'.B·�®œ˜I�ÜX#ß—Ç¿žt‚ÞXƒß¿À4l_/ï²ð‚½ð�-Ýo£ÑáCع?tÎ}Ë9÷ímÛ~ÿùóWþÞ/|æ3ïw~÷Ï~“™w$@?�úZEàRo¨™@`Mw¿¤y·ªªª•ô]Þ_} SuêœY¤†ªj>/Vì^(3‡Óçι¬Rßv·ƒAÐBR±‹€Èaóúì›øz¹cf¸œmŸÇÉÞ>ì!ì™à\,óÓg#ÀÕøÇ.ÒõˆóÚ9öds àêHP¾Òç1v çÈܳ·u\ò5¦\û¸ì×¹t]‹‰@!±õ›ÕëdYí½fÙ'3gBArz‹’ÛÒ½¥š )&0¸n®ýÈpƒƒ›H‰nÛqÝ÷EXµjÕªU«>fµ«V­ZµjÕªU‘r.)KÓÃ*Ι•"ö}Çõáû5¼séa–cxÝ” rí”âì¾’ ˜—ˆíîbì$%çDf¥ŽH~¸E5;394%¼Jr~dÈíÛ÷½dW2GD=ðÊý{ï|öÛßúÆo¿^ÿ‹ÆÓ;WQÝöU€–QkX@Y¶Šø úO¬‘)eB 3¸€]õ‰R¼sÀ�_MÔìa](¬B‡ø˜ªy0(�?0u*a®mÒ1†˜0X�kn«Ô‡ûjìéǬPéĘ)¥Œ·e3g¥4šZäå«Ϊ'Å6.f Ÿ6ó…z>fd€Ñ]ÀZM�¦9pl_9F,Db€’"­*‹3°™H5ÚeÑš-P¿öÜ›n€±ÃŽÃÉ‹; sT �ÓbNÒ¸—<¾ÔXîöÆFÁ¹²'à–vÞ{ÝØ¥.cþ8†-¤ÝÒyÿؼw2Ûod¤<µÔÔ!& j5^Š[qÅ™À´ûµ2–èªs€‰p¦n e�´óh$¨¨ eÓUg>¬! \×a^öëuÙŠü0Ç^•ÒOSÊjKЀn›õŒ¬„G½Ž@¾µÿ7îÝÜþgRîÙ~è|>ONŽ¿/züG[ÔE¿TöY£p6üƵSo¾èE4ë™àíÈ,:"p£{L!º�öÎÉ‘¢3ø]Š"‚}YmŸ”ÿ!$«{ÕÌÊ5·}…཯Îj’mýô÷Û¦˜“]¾ÏñÞûê&@ĵ{†jÿ‘H.ƒô¨„Ï(IáÏŒJ, æv_Áé¼Çœ?wnb[%"ˆ@¢V"F‰†£ÜïH§¢º·9Gõ³�B¸î;®W„EXµjÕªU«>Vµ«V­ZµjÕªU‘*JW69"$eý¾CE°_®×ôðͧd[ØRÖcÙPyðÅ1ç‡qÀÕt—ËwwÏðìîç®ÖÈ"±‚vhvœÔ,àTAÔLˆ!\ø%¨nî@ôÀkôßùÇ~üã·ÿýP2ýwšÅ«C¦oþ¦³É¦ÁÞºë ª—,pÌlÎûŸ+¼l\¬òš¬P€°–ùÔÀTšØ'—‡xÚ’DÒƒ¸(ÉJt…Kæ6ç‚h]‘þ#­3(Õ!¥ú/@Ò|ÿõ¡q·3tí»ÐnO¡=6‚ºù×B bTéÔ’éW:9}Ä;C)fçc2©Û =¢GŸAp|Í íd H;q‡s4Y¡\êèM¤Ó嵨 �`çÖû•o Æmm.M±âa/züÛ9B�¹JPkC³¢jßc?˜07Œ¨×E�ªëNÙ®ýzdÏKK† XÚÑ¡Nút~¬í»uä@ŽŠ á}-,E q‚p9µë§²Ž •®Mý=&ÈvØYèx›¦sÕ:œ 9P¨Ê°†PŠgÈm—¢îWäH™F²¡º^P±(#Qíµ£­·ýXÔêˆÒŸS”*cÆ•NhF§…YÔA>¯Ó±C�+JÒõxaÔGN F2‚N‡«â AöšPN‘Þ Æ;–Cª} ‡6< �ä¬û?ÛNŽú é¬ž¬;'?iw Åãàÿ8…Þç½á-‚ÇÍwèÓw®7zâìõôÈ¡?¥{^èˆn�—îf�žt”Ó_=ê¨@Z¦!7Ô¹·f÷–wî;Ûæ¿å¶Ë7/—Ë7_}íõoüâgéÛλ+‹ß¶x¹\âå²Év¹ˆs.ŠH$"!¢ÈÌ!‘Yc!�ª$u|Ë / úF- Šä¸ed ûf�_i2€¼v KŠ“1&*PHv.s`Ç(ê{bÀ9—H®XÎk͹€C²c»çeÎQÎÁoÙ®žŠí}HD‰��Lm¨[¢l‰U+Ûr¾¡n/Û”J¾�&" ~sœópÞ×(�tÿÝHy]Y½gËÂÊê5GÄzÌéóå¶¹­V\jTÄ ¼/ÿ‘"à€¸'ÅþâSƒjúÌçÒù+ç‘ð¤o`>{ˆ$Æ¾ï• ¾jÕªU«V­úxÔ"¬ZµjÕªU«Výœ«<ˆqœPmÛ¿mð~˯P8öYu¯Ðò°„à³ 'xrµ¡ÎöÔL<\Ú|Þþ³gÏqwwÁ¶m`·%ûJ“_YñÚü0Éç8ÊàiŒ•¤þOÊÿ šä¶b~àUŸüÖ7¾þ_¿^ïÿ«ŠÜŒáø;œz´·ß˜§|ô,`x¯x5aÀ�m~Àw‚Ø,ã©Kq>·G¿T}àÁd“Ó� 5'¼dSGh>Ÿe?ÉŠ5﯅USd?3B°æåjü�­Ê¹Úò�ª[h² µ}<ôYtcdxÕiž =©³÷W�[z�gV÷?#?XÍv§ORbžÎ>L‰'ڬᭅt±)oçL{Gþ[U@ÃÖY¦½’¿Ì+Šš�´ ¢Í3ÜŽ°bþ™yž+6˜o³ÒojnJçm*9Æ×h+~ŠÜÈÑZÉ(ëQÑûidEé§l]¬*?§z¥!Zb´©×ñøQ_˜»#�Gµªä2†Uªå~²(×ê¤ à¶G‘äNA”€’KDçfaáS��¾Ô"Qi .%TÖ1L&æ8gËû2t4‡�$m¬"1Î mI.óø¸î&RšB3Á­ö5§¾I‘.sï2„L×”Á»€l—êa /ãbæ|¡/ÿ~�è¶9µ8\ì&Žy¬YUû àÿèD`®§o¯½ ÈÔ'€ÿªçî#)mN7@ü'ý¤Ý\ÜSæG2¿áxâºÝ¿UŸ~iÁ­Lû—½f=Úàa1~œ0uˆ¸ ¢Óé¦õÅ.½gW¢IûÆ1@sÂÝÈÕxŒz@x¤-4Ý®Äî-"úf÷]ïÜw·Ëå­ç¯¼úíÏüâg¿õ¥7¿öG~s€„=Ä}¿Æ}ße¿^%„  fÖôCÒíx —RU!"átó™9‘ˆp^5ÝÇÇæàÅ.�à¾8yåë)‹B(»~ AEÒµ3ƒßŽ]g�¯ªˆÚÖ�þ‡¶–2*a˜‰³=Eø-Yû7W³øëù=¤ï�ì"à¼GUÛ—¶«¸¤³/¶­*÷¥ªê³êžÒ{9[ñ'ë~†wÙY «ã Ÿ>S•ˆ€FðÉ`sðÎg`�ê}§¨¹™8\”Ó…#Ò1‡SÜA"J·¸ÇØrTåZÜÀ¢DD  Ä›°‡€C%(gîÑ\! ‘X¹~¢Î¥©�ËgÀU«V­ZµjÕǧ`ÕªU«V­Zµê#RÅr³¨ô·-ߪÉ‚Øü†Í{Äà€úp‡*0ßTjl<9ÙIðÞãr¹àr¹Ã³gw¸\.`·µrÙÖ³8€žÊC½òÕ”½Q"âB@Là?¸0ñs"zí§?ýɾ÷GßýÆÿ¢µv×Ñ!îØßú%ÿ§^Š=©}è¯0`´ÊøU€ÔS dâžÄR a›?ªÀfžåFA;ñë× –6Éç!í—z×�¬ î<쮿Y-\Ô›¬äªÎ¾�¿Œ*ú^1L7,€�ý¿Ui›IãyA{°Ü2»§†Ã¾s?d”^'*×§èÛ˜$ê`¤(J�-M7u&eG§Ø¯¹Þ¥ÞeÀZÿM¯ £ÏêÇÙñÞ*µ6¦ ëví¾ S@#Gàþ'ÂG&¦Œ.·6ÿµ6źC2s¦#óЉº¿\UV®‡¬ó6—™'�, &5 þ þkNÖóð«S!abË_6Îsø0ÇLŒ36«%¿5ÀÏÏnnöë‘�±ßwóZtìüü2Éã �ÎHý'Fý/-2.ÑDüí*QmV[€!ž�úëŒYÑEôèJcŽEOVÀ1ž¢~§óhŽþœiÁQÈf›‡ä�ÙX3k¢Üœkz\fM|ÃSÝÏ^d!S1'Ô+í�ck^d=¨°0Í_þB˜û„xö„ Gf½ñô5x Œ~¥/É�þ!è‹.Ú³K#= üïúUõErÎ{�N¯öÞü�Ù½åœ{ËoÛlÛöÝËåî;—»Ë·_{ý“ßúì/}þ­‡‡ûB"Dï7¹\.ñîîN¶í‰!"¢ªÐE²<ýÀš”ê¤D”oÏ™�~—ÉÛÐbaoc„Ê=|!ñVç/2Ÿ˜jTRÚ3ÒÌ´ÖÿÈO÷ÙI‘Žj³ŸÈ(ÎÛ!‘s¶íw ç]%—{"@ˆQ°‡ׇ!4Õ¹÷rÙl b8§ˆ¬ð® ÊÖúÞûD\ @„é�S;ˆ[Æ}».·û­D pÕ¥€¨Ý[€þ»EPâ D¤¹ðÈ1Ω2ò…¬ÞßRžu(Ûõnkëd Õ�@%ÖÈŸ�ÇDX¯QÎK“»€¨¦È3"sj÷*ýø9¿–¬ZµjÕªU«þd×"¬ZµjÕªU«V}T*ƒúÎ{¸ÍaséVM7Ŷm¸»l¸^îª*ıÃårÁvIª~ç! >3ϹœÅ6¾dY^.[~ý–í:ÑÀ�’Ù ÀÁ€" I£’í,ñ,1:�^˜ø9;÷êÿÑ[áíþð_ä—¡=$fÿo:âlíää¸ þÏ·ØG:‹Ï6VÝ-Š@M÷èðp¯9%ty÷xÑÄä‰B³wh‡µ«/ªkK°™ÞŠ#˜Oj�ÈàçÃyÕaLéL¶{ìà®=��Ý1‡›ÎbŠj—NU¬¤'dŠ�(CÅÁ‚tjáÿT(D- „c£È;ƒy£Ú¬êíî}Ò9MÀ×S…åã@X% -Çý°1j9ÆÖ� àq‹¨¤k“OZ‰ ÍÉC+(ÙòJR’q %»~œ½' å<öT .U¡G­©�x(ãç0a�“ƒu)±f*W‚n-Ôƒk|s0ë¦FzGä!P· »Ýr=Io Jv�&F"_�%Ñ m)J×ãl¤ÁàŸjí[}�Å8½ª3Ųž­~QyH!=eú´óôtÔrJRy�Ùý¡sî-çü[~óom—Ëw_yõµoæ3Ÿýößøò÷.Û&wwÏÄo^݇xÿ^|÷Ý÷öwß}'8vA�DU’¤Ð§ˆä%BˆT“â=�ÝcÐ l€÷ôU\eŠ‚œ²:�͵0½ÕÂ^¢"†ô/Ã-Ê~K(�@ùBæB&&:Ìãdý+(]¯k °ËŸa¶ ªgÕ|Så—¾Oªõýq½^±ï×JˆÑ§{ˆ¼� fŒ¤S"À1C|äc–°LÕM+ÆXÊñ—‚ô¹ËõG™\½ëÿì€î~,Ä ø/Ù¹+Fª Q!²Á�1˜K?¥í§86!ÄÜn‘àò½…c‚T—6 uä…4 ¨Âçýõ¤¹æšV#”ò Y«V­ZµjÕÇ©`ÕªU«V­Zµê#Rå�“c—Ød«Éd‡éàýÏîže JÀÞáîÙîîža»lI=B„¨ÁlU+B4º¤¿«É’é©gªé NGÉàÿ5 „@1ÆM wz…˜_{ë;ßøÏ¿óÎOÿû€>?KJ�‰ÎHXÝͺÌšïó¾aÐðs âñçñ «JË÷5Û:¿,Yk—¬ú9h«Ý�4Å …qR̃\­àh‡@ÐlMÓAÙ‹©•4u 9¯T©º8`pE¨õ鉣â»+  Õ<Õ—´×&¼ŸŽ[˜‘̹"ÊÏ´ÕôŽijÍó.*ó†9óL¯pbCþ˜¿1õ@àdõ)±é‘¢ð/Äéˆ)zÀ�8E²9ï*1£9¬!½b ˆqoQHŽÓ ü¿HÒ9H”zw%(1˜ØÜoÚûr­ã¤¸Ê­ZµjÕªU«>>µ«V­ZµjÕªU‘rY ⼫Yš¼wì“ýÿÝΧ‡3ìÛå‚»»;l— ØqŸPí9E²Í²Pý9ÄÞÓÃ0âö .ƈ³"‰’-¾)FD¤¬e‘ˆ}ß±‡!^b¸¨Ès¯ÑëßúÆ×ÿׇ÷þk-A^�£ö8ØbwxÎÑâû€´T¨GUóøxxމè©J;ýWAB¢¦4l;>HÙ¯ ’/°_ùÝðuyäÉ6ý;‚Fr´ý¬M1Î�é�4PUbu \#[œÛñ@Ë=·`e¸µ>­Ié #*núÎäa`Uµšl¡Ô§¤æ´�'Y‰h¿: ¤s�8NÁãúzóJ�CŒJ·èiO8¢'IÊoûÍ…ï–µÿã5…ögñ1�ªúé}í÷Éï¢*dàe[ª‡{«3Ïbþ‘c~‹�ÿÎæýw�ßÞº{öì;Ÿxý“ßýü¯~ñÛ¿ú…/þ„ˆ„’ÙUöÞ %Jâ5 ¸UTë/ UU‘¨"¬Ì¬ªªD�sr¹Ü‰ª »¨šÁäb-ßlï5ƒÄ ‰ÑÄíP§þOJyî”ê€vV퉠`i) ’í`æŸ;¹6R]ó&BX6—Tâ¯@b& ÇÕØm4µ�“ @v`J@w!3Ûû—D†HmŽ’>( 8f²� b0Gó¾ЧÏ+I�ß®ß\‰-(J„î‚Bn'�½eÞ;ç*ðŸ#9#ÇŸuwÂjˆÓ†!¢ÕA3k�2 "í;G&0Ãoés]:ç¨÷Í1ì!"î1«H"Yä{ŸÇV‰­‰™˜]H *‚¨e†º�㳫 9Jdó‘§ÐÓØ]ŸÇW­ZµjÕª�S-ÀªU«V­ZµjÕGåÆlÛÒ—wÙò²D¿y<§ç­`Çù=>ç=&kN‰±> “Ÿ\ž—Æö�Õ9IÌC°ú@²4¬ØI 1b;öëŽÂ&"ÏúšÄø ßþö×ÿ!ìÿÙ^’� xW€AÿΞ¹�â6²ÙÎÆ²› ˆÔÞ@ƒ}j:€ìòQŸž›cN® WSm†ž�lFu³$o}U‰lT[ÙúgjfÕÎ ¼³”<ÊÉúƒ“Õ+ H @süOrvÕ˜h—,€¡hV÷ŠšÜöÔ˜œûã_»>ÖÎÂÚ(¢sŸe…“r‹89wc†7ÍFY—Ýy*çÆ3tk˜kz-X¤vLŽ‘„iŸÔ ôî<›žšØïÛ9rT–êêÐÍȺá~`a·ÃˬR_{C=ΡBç‹€¾¤BµºPH›ç6ê¤�…þ%›ùÚe#ø4µF. Itvõ±Ã“jÿû¡DÏÊO¢ãØ› FßÜšªZ{H]SlpOb(™Äº Ñ‡YÚ¹Lµ®*7OVÚGu—°U“nÝkJÛi˜¯“U…Ðb8Æœ—ø›}0]Ï{Ëá:qdWã†BÓëžÎ/ˆFͯè¾9L �¾ý À�7æÓhì1Žõúp¶¡Ð×1þ)Às×`­Î6/·NL.A“Ž|yðÿü€føÿ¸dŸþí}ì÷Ã(�\sè†ûMÚÚÇ.4ò˜&µý0ñwœsßq›ÿֳ˳o½þú§¾ñ¹/üÚ7~åW~íGŽ]H¸²DÉZ}"ï\ á*L^‰H‰ªe‹³z6ž6 Õ|¡Õò³fÀWCØ‹�½‘^¶M(3#„Pmñ‹¥;;Në½4kv»Þ2S—_¿wå3€@b›õú*ád•oÁèú£îî,êÅþ•ÌV׿r?,é5f‡°’Z?„½î§Wÿsïd4sÑæX`¯™gãI³Å~±ÁOíOÎ"14BØ ‘¢l#BïŠÔÝ�¦ÏR…àêv¨EÌt÷ÞZÁþ(%Ê¡©ÿkäQùÌÁ¾Ž…ò™‹9Ç,ÔXBŒi\İc�aßB¨ŸËÉ=`s—mƒ÷¸C"7ìîŠëž>Ÿ‰d·†�ˆ `Fôé_V6÷ÔéèÒ9ôðžÁ¼"V­ZµjÕª�ÕsæÕ«V­ZµjÕªU�º»$%ÉšTM€{L ÞŽìØ7•PA{¸&…þž °Nö—ûîáܵÙ�2õ¶�p9”!Ž!6[Raß]»‹Qž©èkû>ûÖw~ÿbüLjÖTͪ ðž‘Ò†M"sjz€ËŠN›ý'†'è ™¨ÀG~ «Œ›ô&  n½J«³.Ÿù5o:Èÿšuz±ùVâ”ïj�H"J*× UÞMVÎ!×gÜåܵ,úä_@P6YÖ/ˆžèà–P2ÏE%e¤›Ü÷Q�Ü©� €e?‡}u'�’ª6U²�ž æ¡/e'‹4¾õüÀÿù·Ut:4–JV{§úµêÅÑâ¼9]0Z«ª¸k~gn­ÂÕFG@Sun¯d†Ù=!†YO,ð6DLÆÛ $§IoëdŽˆ›Ùô¶mjö �ÛÁ˜¹2ÕjÆ`é‰26hL}d€*h,][´[KÔ’̪Ĩü:éÎsqê¸ÙU½éyžOª x¢^$ã`­ë¥Î—6f ÜÖï )¨ç1Šä8<éÐÿe,V«ìœI,QÃnqp7As 3à± àEGâ×ÌÁþ­RŸ‡,åS6 õ|�ñ¼#Ž™ ø¯óx�é8é3Xf³úÜ:~Ö'tã8ëX™¬éµË�¤£©CÎÚ¤G2Wåѽ8Ú­�þA�ׄÓñ}2öéEãn™òÓ#/î™�í÷V`Ò‹ô¦¾@”€žÜ•iì¼ÿîårù»—ËåÜÝ=ûúk¯âëŸûü¯þ¾Û¶&ï·¸mwq»Üí›ßvç\\bDVðk’¨Kˆ1:URµä!»~”ûU2ÇA”×öþ!ÆX¶¶î—mƒw![ʧÛÂv.¢ÒnýM¤ÚtŸMÅýË%5¸óÖªŸA”ìý- À’ 0žumñYh*þÔ®ö{»ÇOï ¦�1Äìjœãœcï+iAóeNTA)DŽ´žÅ}9žt ÌZÁÂÕë™HÌí�1"ì!“b>.+õ‹z_UUògž½* ž­þ�sض hcCÄh1 ©¿�ÛÒ6ŠkZŒ!ƒíÚ­L¨—»-ƒö[u…¨[+.1¤c !}•íæ±äý†í²árwÁݳg¸»€{ØÁ÷IÕ/1BBÚvë€bçýe<¹5ø�ÁN»Ä›U«V­ZµjÕŸüZ€U«V­ZµjÕª�H={v¿mI® ÉÒq¿îˆ!*°w@¶-*š“-ÿu¿"ì)O36Az( ÀD«pᢀ¡üð-‘ ”\Ê•&1`¤¸öKŒñ™Š¼zÿÞ»Ÿë»ßü—c”??×èrïiJ˜*)kæ7&–Ìö5¨Àio©­½Â°Ze§¿?úpÝ€ dlÏñ ý½œŒ™å8Îí¡íÁ%pV0V•*¬-ÿ MÑAI…lCŸL3ç‡×6Jƒ¢•:…{ßÇ:oïñ— ƒuüï@È^±ÛÙÅî ]Ë(ET@úsÖÆVŸÕÝ«©µæ±W5quïNÛSæ%PÆ„u‰ -ŸüÖ¹µ6ç]Ʋ™Ë8w4wo*_ —ón2„™ù¹½M¾¹ôÌìù›µK?—k™`ÿö×ÑÃ%¥;�tp8ú¿ÏÀ�gì$�Ç&´L²A&ãJ'N“ž,2gC7yJ<é�‡‰Ño±üwH!yruüÁ#»«ßýHT8°þæþÒ"|}‘¿½œKÊ1^�^¸_f—槇ËeûÛ¯¾úÚßüÌg>û7~ów~÷?úüç>ÿv�xÝ÷=\¯áþú÷‡]BÜ…@✷mrñ—è��ì¶@Ä@qc– !&;~"Ê䪈Yž€ãv¯ÕšóO¯ — €ÛÜøìZ€¹\ªb]r Ö^ÕçÌHOà?PÝdÂGJ÷*É @ê5°}°à»•{ Öîñþ4žü>†¥þÛ6xÎÜœJlYÿ é ¶YŸÁü´Ï7ÆL€4ç6*|u¿üO$„ÒÏgŠ}˜˜�ª‹9†¤üOºséw\£Š¾ ýÚú2Ä€LŸ¤�Rù3A>‡Þ'›ÿÍc»\à�OoìrûbºþƘɱ;OÄ O Ÿ·sw¹`óùë²Á¹ô8Ÿ%¦87‰ˆÑÁ‡È ª}TÝÌXoŸ3C Ž«V­ZµjÕª�W-ÀªU«V­ZµjÕG¤¶» ¼ß@ ôÀ Éòz½GØ  Ç ñ1=x$‚¨ ª‘{~˜$å¿�§°29À ƒ˜áœ$wv`R°ºª”DâET_QÕ×~òÓá­ï|óª¢_k9ï³#£üð’¦q ¯§^ít*[í@ì›RØü3@��k¯; Á›²Ë:ðÇ_6ù¼<ì7¼‹›è!Ay´™ÎàV�ž'¥ô³ ]S�g»W‡ÎZ»AirÜ'ùÖƒjr«V+ðƒ: +RÆ%@*Y}Ýk_ÕÄ$0ÂIaÞpDÚNÇ›æ¬÷l‰‹Þºšêƒqôvâ‡ã€;Û×6kÛ»“¶ÔméÜž›êÃåQ=‚ŠbÚIÍN¼Cõµ’'ô¨õ7FòÙ«P;�f–õæ÷#i`"ðmû0þËøH® úDÍ*í-åÀœŸS25úÄå`¶¬Œ ÙºŽåìI•i¢$J܇iLÃùzh»¢äsI¦¿¬móÀÖ*ßk¯µ¼AvÌ8qýÐÙš”‘rà0§÷HP£°²B�²ý9’’))h¢d°5¡ÞeIMÕª/¼óÁûï~ݯüÒçþ ñò ÜÕ{`]ÆØ¨&œ€”¡ãzáÏ*(3XM43ïjÜØ ` Ú ÈGÆ#V£¥>ÅkOÓÚ#CSVvZW­,úkKg…TY¬-¤Áé«÷¬FV­Ác£Í*Pá`Àª ’…-e€ )B»�gê@÷ðºÐ&dÕÙ°Øu¾h‚‚5«qnˆjüÃ"0F–ã ¬PS[kcý®E»ÿKÎÖ­"Ž•�:XÔ*’ýÕj[®?sñcß Ju]/T·ßô#¤ÑÀfÀ9Yü'P¦µ§­X ¯þ˜Ž¦Æ ]©€ÜÀ¹¼ÓùÚ•¿^¤§ ž· #…9ГV¨>œ¬p�¿# t¦<´—îø3°Ÿ‰*aNc>B•ï{?¯¡7Å�#õα3DÓˆÙé@ì< BG2}¿œ;ú1?hÚ<.,4¬µà9µI87xz´D€‘õ~oïÞ£ªvNB5ÞmK¦ûE¼RFfçž÷\"ÂÇ7)èA§Gk�£d‚» ¶e±è=µÿñ½t8ŽûÃ4×h|TÚ‘ëÆ™î¹³ ¢;îž´êIsŒ>léáCÆÍŒ¼îõ�ç#½èþl>b‡ñ2'ÛÊsp»^–ågß~çËþò×|Í×þßúmßõ³û¾ÝDåæÜzÛ½l¼m»Ÿw 8¾¨ˆh�ðCçԱú®º^žpYW]–'e·*3Ç)@£Uý•â[T{x¿�¼Ç-ÙÞ‡ìöl!�>‡œvŠô0µ}^šøQ©?n)‘`yŽk9ï:”cÄlø˲¥øâ ù@� ™\ÍäÆ�v`Wl> ¸Vˆ¤ªî«QÐS&@¤ý¥í{¿cÛ¢Y¼È w9×>)ÿë}QŽ·ª#’r~‹ÖùÑ Ù÷§kànáΙJ|e²_Ž9þkAuñ‰xQ©Ùµ�­s@è³�£vl{Qû·®­€ó¤»ðynu¹�Âc¦æçH/~÷¡=üo¢#ر‰Xr»pþS_×v&'‚[b¤� ퟣm4((í­2SK¬…¥7 {Λyª�Éô�n¾iχúñ«ñµ`^›V6Ñé ÛË=p\h¯IMDŠô.ª¯Ywš¤ÑÝÃRdй/”ó¡!©vɧâB£í]åØÏ#Åøh˜Ð  ŽFެ-ªö{ ÅífÖ|}_#Ò¦2IgUïèNzà ئ‡CFw‰áaÒØÅäã�K�â±|¡õ=äCD¤±Äì~í�wÞþ÷¿á¾ùßû�ß÷C?彿nû~½mÛ•ÄÝHù`SÕÛ¶ï⽟³áKv¹[\˜q¹¬X//pY_`½¬X—ÌK^U=Ä9ìÞaÙ=¼[à%ÆcÝnÛ .ªÂý¾ÃKÌ‘OÀ«�Ͼ>Æ`1Ã;ª¥ÛqÖ¦Ö!`ßvì{È ÷‘€�"‚=ü%ž�«lïmÕsø�÷ˆ· î{è€ÀýZÑÞªâ[2–Z¥þ¾cÛ7øŸîl'@ýÞ¸•ø¹ÆÇh³`ã_îÕÉ�!» py­É‘å^зW²Ðà9ÏìÌ`ˆ%Æ 9.ÔÛQì¾\ÃLˆmÆL•ãC¤v„í.ËÀv�î3Øc?©¢ ¼�VpŒea,K Y,ëÇ®ÜqTqÝ®à�á6Èé.'áóÀâh]á˜Íù'å?ç6MŸRŸÄÁ½pÖ¬Y³fÍšõ¥]“0kÖ¬Y³fÍšõE®´€¸ï{\¸òØ÷ Ûõ†m»áv ÿ&€¨ Hæhˬ!C2©»Àp ([‚Å?Å_“<…à8‰‹MË‚uYàÖ5’È©b‘ )Þyÿƒ÷¾ês¿ðóÿª÷þ»«hää,�-õ5ƒ­’Ym&ú¨ª�<ãN*`” ¹ ¬P÷ʳ˜¶QPxs{×%M ð#­P²JYÞì\a3¾Ëu®Ô¹ cG=Vh[«ojÕÚ©­YÁÂ’BêhŽ¥vˆê/%xV°8(×êÜÒ7 øŸÈ¹µƒýˆŒªÀX>±´M­dˆŠ3`+S4êc5ªwKlQK" pmí¾sÛ1H"DbÇTEßl6Úé@“Ã@<[1�žÔ€Ð=௠JMè/ªó:¾iùÜ&íÂùCÔíÔrò:I„#� ˆ–ÿ£þ¯£–µùÍ4PekÜåvéH$ZEXG�y ò,AvÂkN)½ÉÝ¢k»âÀRÆÁx¯T¿`xϰŽÄI¾m×wFቤäyü°äaeÛW0:tK«Ê­„��€½˜Ùz@GL5s½‰ÉF,¹-¤:ëŽbs`áAé¢'T£îŒÿÔüÐ… 7P_ÃÞåb0GξÍ6‡ó×Ì�àGç‰óy�ºãÖ“<¹7Ðð©aü=<ô“z=tLñqÁötÖ“N"1<Èz 5cîµ¶&—§§ÿð+¾â+ÿÏèýÑÿçÓÓ‹g"ÜTý @ø"ºÑFÀ¢]E!ìQ­Ÿ­ò Q‘ïÀDp¼`�Ϩ øO`¦%23°D2VòÃë!ŸE Žá}x––4OJ!'2·"Úé”ϤOî @ßs‰Pˆá‡I‡„–Y³fÍš5kÖ—vMÀ¬Y³fÍš5kÖRÛ¶……+ïq»nØo·`•™¬ýŃ•ÃBËþœPÕ,YÉm1;¸¸ØÈ‘0�’”UÍE “r&×e1«Š¾Ü�·ŸoïÿŽ_ø›?ó¯zï¿o¨¦DÚ¶àf=¹£: µQËbdûMtò‚ºR†xãÒ&4gÉ ø]@Õ{Aã$c*MnŽ Qu*ö„ËÕ‰`eZtmÜú»*ŠjTÇVœÊâsþ#ô ÛïCP™!YÊ’�qÈÍZd»Ö.^ÿ1˜šC�ßxxÐ4ŒåBF99ív��7 >Ú+«�qï²} ŽsOŽ ±mLfÞŽcU(¤"¤ü‰÷:L47ßÐ9Y£XƒSwu g‡$‚ïBQ'iÚ¥ŠtГÎa=ê!l'J×ùp"ÕLÞÒh5m_NƒkÛ‘P@–9SÓßôÚÔ ÇögK‚¦p¦°mÈ-]ÃkÞ�6GhÔV5n"Y΢ ¢ C Ì¿®–Þ̵Ç,CüߎzÕq[¼NéÁÏR]Ä~Ò{Ô¥¯Óð€™ß{ùÖÛÿη}ûwýo¾ó;¿÷oÑͱ ?tÅ.Š];@Ä;“JâVªW²î™ìJ„ðÌ’ž³=;Á‹5µ¬U›ù–ŽúIP�mà øŸÆYøòÑßW h±è�_ZRfü¾oضàâµg»ûH¸�öö™t»®pnÉÛñ 2–ýñ½…$P2Û]t*`ÏÙæ¿é9ƒþåN¨ÊåYPk»þv®É.bñsD±‘/Šû /Ï© Œ·À¼u_@äc=“yFT[ ñ¹¬w§Imd÷aûD þsþÌd¿ìµI®CUû�¸€øì›ž™K ‚j"5†ãXw¨S¡…HˆÛ-DBˆúð<íðÎ}Y<==…~±8¨ ¶[èÛvÃmÛ°ûð¾Å9¸eÅêV¸%8'°#09(‚KW"ÈT1Qùïóµ„ ¬ ž€Y³fÍš5ëU“0kÖ¬Y³fÍšõ†Ôí¶Á±‡ìÛíŠmß±ï¢Q¿CE¡\líÊI$•ä‹[‚�ä’TS…~¨R³,.€ÿ—u VŸÌ OâýÛÞûOÿÌOýõ~÷ûÓïU®Y¿Ùš²þ+€RÖ~¸ÞdR7cd`6ÐX [;~Xµ}Ry-jGÀàà þ—v   �¹ Ðà~AAžHáÊ‹?´å1€3�óZgn']œJ ”Ôb+®Lˆ/8r\ÌDT™ �ñ8&°Ê2Zë�Êv=倫¹F£6Kû¶vãVlž@ÆL6È—¨·‰ÍÿI œÔo˜oûAþ ½Ä«VUTþ&•Áœt">Ô},�>Yr eä̤ÀÕ€8FИ–v6 ylÿß ¢V•ÞvI=ê}õ:ìø}å¹ YÐb jN×—Z5!Ðý¢JÚ奷î#Uû�ïqhÚKÆ '51ÉK œ†¢ Q7ר(ÈðDut@&{id�ä.ª;f•í^¶ØG$Ô^ Zý.U ‚Êœ]EÔŒ<Í�¤vDб�³Q5Ò‰DEÇख़×j€ݘ/ñdnhæ7Z“G¬1‡ÆB5lTÑ…�˜{Q¶ö×à Ø€ÓÎÙ½êÞX¦1é8ž§Ó\M4$ÿØqÞ÷dÒL,ú  ]“³çƒêjô÷Áÿ6âè¤m’Z^�P@‡Çr@w¼F9ÉV:)çÜ/êSŸþ·~à‡~äÿðÕ_ýµ¿Ð+"ºÑ €WUUõ’þÛUUaÇetàÅCdÏŠyUÉ6ðêãó�GŸ ²ÂcÍJò¢¤ŽÀ.p–œ‹À."90Ïz‰ùó„¬Ò¾ô­’<½&¹8·t¯Oç°Ýnx¾>ãz½A¢Ý}ŠðZÜ¿_pYW¬ë%½Áº>loÏ®`–|�¿Ö Ò®äÒÇ<{vT' d³|;“øsR©—9Ç’p^âÁ¸¥dѧcίçÏ'9 !#‚í½ˆÏÀ4±%T4®‰˜�@l•á­Y}йJ×ËWî Ì®#E’4™ëi‰æ=2¼÷ïã¸X÷´°}/JŠzRȦbûx Ln�Øí}t„`ÆJ°šhˆëåÇŒ-ÆìÛŽÛí†W¯ž±í[ƒ .—útÁO ·À­졆X�äWÈÞ v"Âï´êÛ³fÍš5kÖ¬ONMÀ¬Y³fÍš5kÖR~(™\HB“úlM9ÑÄ9åÄpq1.,i"ªH–h%™aAMà}P!‹˜…Ïô_ÈÂd&º(ô%€wþÚüWþôv»ýqïµX+ C³e÷HÍH 8 {ù½ÅÊ�ГFUl¤5㜠á¸PZÛ_߯fp›’”àÅ£´Ii¬^Ž28êd›TçÂÏ8ª¢"Ę�-j€&mÞWŸ‰I75v¯ÅG;�TüÒÓ"tÊÑ&ŽÎùzÕ0ÂÝ+¬Ç–ã•®ÀAb®{¡Úƒ³6ù) ÀN’^k­Ô“‚Õ\ÃÖn¼³í^”dUn‡å}3!öZ@Xð³q €Õæ‘·`¹¶™æmI-nPÍNW:B¶ŒÚ?ïcµí©?ª‰ËÝ"º~¡ƒi§û»Ö^‡öó�WviU×£lèÊÞŒ§ÜÜ59ªvD)óh꡽¤d÷ÆýJœ_ Þ_È%’ ÿ7VéuÿÎDmí¶ô*ýöû–h“-ü©yM5¶ìLQ·¡ž±Q*7ê®DŠ(ÇNÝüTh0ކuöÊÖEOï`‰…§­ Åø0)lÔò£‹s~ átÀ·Cª¿ªÇ3»¢‹[©®õ= éþ„k=òPŒ ŽUúÇíBw·q8_~”€#€™?yÃir^Ÿ€¸,Ë/}æ³_ñ—~ôÇ~âßyùÖËÏÑû ¼"Ð+«ÿ=ÍRAi¬ñYS«y�€ûH¢’ $ÏŠe)¶ï–àåwŸ�ÙbnôEÎ__— ÆTé`¬ºBÔCt…èÕeµxŠSÙ yKH`>‘ÏÊ}[É®ývÛp»]±o¬å¨Œ×§K¡SÎûâ–IÀ‚í¶•çWã@ä«ç·ÚvŸAäH h%•;�]wíί�¢«˜sä^×K!Ç÷$Ž—+�÷%®î›I�.�ËÀ(R ÏÝ’\døúÖ¹@ÄW×*Úù_GÙ mËq!Jp´Œ IŽWñ˜«H�Ô�ƒ#‚ãàL! !¼Ö™~Žmß}ˆ„P‰Ÿ¹l<cq ·”íç€à*ñü|ÅõúŒ-º8WH"Ž\ÜC“û™/Äïþû|ŒÅ‘!F5x? ³fÍš5kÖ'¬&`Ö¬Y³fÍš5ë ¨d /c_„–ei”=.Ø>º�…ê88X¥21ÃEkÑeY‚R‰ ä£ Þ.n&kJÁî¼#¢U•_ðö_ýÉÿèõÁÿ•p ¥o2è,ÖEŒòÌ }© €5Üd­튪Üsê3âC¨{ "ÕÝbÔûuV*rÛX ‹ˆ£�{�Øs„1 -¦%«øÎ5(*Y9S±•X$ .‘@EýZ�rÑ¢Ô˜TýÏæ£縗¤Þ¥Î£~d"OÍÅìÕñt¸È˜@Ö|,}gˆÊÿ†¨€œ§ V÷JZ{}Fä ;nûa�—¦¸�ô¾V] š¸ùSQaÈM·- î}jLèƒö´!µ@;U-¢÷Æxr)88¤dËNìKk+� ü/Ž�‰þÈü0Ë^‘u;=º´Ý�]?húl? úK�[ƒ’"¬r<(4Û|i ¨f·ƒd£ç%¥�盇²‘‹j¥íïH#Eï?›ÝœmçÍdµÜQ‘Çsôáñ¸§ÚQ¤Þp0…½âÀ£V¢·Û1¹Šñü‘ÛE�{\Š%�yŠ#Ï'÷Fúxìb4,è¸uêÙòÎð¿4=u®/åk¢Ò½} �o€s«5m š€@÷úž%ÅuseÿhÒOb?Õõo0䜴ÁC¯éΖ†ø¿ÇÉ#Õ?oñ²|îË?û;þâ�üèþ¿?=]ÞðÊ{ÿŠˆ^‘ꕉ¯D,‰xYF�–ýeÛ|ÇÜÁ$ŸdÕ¿÷ ¢0Ç$à?fÅï�àÜî «àry²((ZGÕvÌ~wKè;âƒíy²æÏÖõ1–`Ûn‘”ë+@Þf˳ãL^(ï@ï¶ï€*œ(»JÙÏÌXÜŽ.€³‹@;’¾"ÈÎ,æÙT2¿6|6à|ofÇ&>ÊÄD&”í'p=‘Ò÷᳃3íå²½²ýE��mÈEÍ\¤çÀ*Ï[Ò€}Ö=?Úã(. fŽ;²�� ²Ï”]Oìž *"‚yó¾ô`� ¥‹‡4ŠÄƒà®Àp.9b»©Àïûúyè�[Ž#P $ñÅ9ì«Ç¢R=g¤g /ᘼ÷Ñq#|ÞK¤‰Òvóóø¬Y³fÍšõI«I˜5kÖ¬Y³fÍzC*(R  ˜À"`Y\Ì–ÔhUâ8.Î13`·\X¼[–5ÛS*‚§F@#ep‹^ ÐUD^.νóÓã¯ýÃïþÖçÿÛ§ Î¡ôÏ*.{5h­‹Æ� €#·�’~õQã ”­£ÓÙ’å{±ðO u¨� l·•9´H8%×­˜Î¿­RMµ‹šÅH²yóšm^ËN4çÔ‡èy5ÇŽƒÖÓŒ¥2@BbÔL†·µeM×SS;õ¼œóÁâí¨µ@¶fà‡š, cí_)OS;jQØFð•ˆNáC Ú- n@Ýè ¶hÊBG¶ÆÎí“öÅòÔŒFÊš£©É· y3JN½ûÍ188À=ˆˆj塞¿g ¶keí mÕ{Ç‹dû~|N-¦-jYâáîz’ g³Ñàü ¨]"Æl¥Lè‘ýЪéUký¢–/ûÑ£97þAÒl§e|DÆKv�Q £>`c!t|m¼}4È»ÖóRÝžm?Êz8¤4‘ çÄÄÍ�w…4;Ë„ü^éU5ê`jÁ§�õõѨճͼ‹Žþ¦ƒž? »Póf5|¼;Þ ç�ƒó*.>÷‰QÝYµ‘:èÕtrrÓ‡I÷ŸQ4‡ÝãõÁ{o`æ_ûô§?ó¯ÿÈ�ýÄ¿ýòåËDqõ"‚ÚÿÆD7ˆlL$ LUó|�È‘5¤-“•:{ÎNUÄX�Uàâ=|•ý¾…˜¬mÃm»Ç,Q°c,ÎësU,²b]\˜ï²Š;Ç-Ôvùœ?Sd…{´üwÌYu¿2DR»ÇÞ’Ï#�£U™W@~Þ_Ù§[ÜÁø×î¹19N�ŸËñœ+ÚÓ=„‡cŒ,™“ì³Sÿð¤±}Å{ì{´µAbœEz®êü0€]þ¬úPjßÎo/¸EÊî}ˆ�K±ñ8’ C&s$ U¨/®ryÞgŸ rt'À0faÖ¬Y³fÍšõ¥]“0kÖ¬Y³fÍšõ¦qä)Úû;U<á±­àeÅò3ä8/ q´µ‹€A‘‚¼8å½Ï‹x$'Â*ºˆÊ‹Õ¯oî—é{ÿþoþæ?�”èy >õeá�üOj¤b7_€N£¼¢)vQÞ‚.:TVùóxŽg ‘Ô@�-�TâÂâHÛNm®7U'[�%ù /ê¡jÇJgÀ¼,ˆ(+å«�LJD„Q*q­ê·î­Ë�¶1i … ¦�!8”•³Ia[9 öˆ¢fn‰©�ˆŠݾ7G9D(ð68hû’Ÿ¿ˆ*ƒ[ÛêSå0‘÷Ö‰èký«µãWP&hç`³Ã©"�Rq@Q˜0ê‘«óÈëävè·Éz÷Ó¹û6‘u(cMMìCu~:’èvf í¬0¸(MQª�)Ž�8«Ùu”®Æ’ŸÎ·Eõ)Ô­: L„wd w…ÛÓ¼§z¬Ô*JV2"€¯ÁÑEêvÕDnÑ ’H$†dP&+jF–ž_ަQÔί�UFVªš±‚zþÖ“Üq:Þïá=¡:/öµÖ©¡ÌòM¤Ã0bÃôu:m%؈® £¨›˜êqušuqÞDï8%Zýßé] èé�Q}=9ÏrR=ºþ¯söý}¥=¦¶êð^rÖš�>)}„GÆß¦­•é�ßû²O½ó¿üÁßÿÿW_þå_ù›¢xå7@7U ȯ&!"ñ`"Sqi˜ƒîN9æ*[�`cžgAhPQ ¿ççY¿ïØ÷-¨£ýñAí¿/Ÿ•Ï^’µ¿Äìõ=Þߎ ³ž°^V¬92KqÛnXŸ¯  mAkfÎD[Ø—ì\|Ö í ÞÕ‹ôçe]B×㌋ø¼ú›@£Ê>Å0¨rî+ÕõbŽ1¡Ï(€Ýïáï{ØÞízþo�P‘ž�™Ë-7;›i‰X�@ð“xͼ÷Øüâ3ÄFGÇ Ù§À¬Y³fÍšõ ¬I˜5kÖ¬Y³fÍzCjߤ�J�Ø�ÈÅE¤6—Ls£ ¢@pËŠu]¢{@´bõ�`É꽇ø{Z ÒxƒÉÓmôöûï¾ûµ¿úË÷/¨Ê󵯯À'ÖÂZh÷—ö�y¿˜´úcm¦|`øsê;m`úY! Pbˆëz%#a¬Øth|?¶"Ðhá=²ï>P7à¿] ­Ž6ö �QV'OÁ�’ån¿ÈŸ@Ú˜ˆ•Eåx œw‚DǪ }HeØX§H–(AD&VAMÄwŒH´.(ð+KÛOó©”üïÆ5¹‹W -€wµ™ªû¹hø•²�9Ací¹¦Jüž¼€Ÿ�Óq[Ûö´�kíÄï.ƒS{íû“Ô‘{:s®#ç�3H.ØBåiNEí|ÑuîpVõ¶ifÁž:ÛûálÒÏi•Á‚Á”h¦.ó�š•ìdt°Ç^ÝúH`*5É! ©#)n @ñgãµ"MU p=Ï£h…}ô@kîE#ÊY®÷mþ?¶zˆ‡@íüá_¼õÖÿí{¿÷ûÿ_ûõßô9Çü€}tW…W£æVo”éˆp­uº6&„234¡ÙšNjüH¬ dÄp;ó hNÖæá8âóK<Q�ˆËî/"[ ¿J nqS�[°^¼xzÂz¹dµû“�uyUYÆ{¿‡(®e ®ØÙj�o Ù+ÚÅo·-·Mé}d5w¥Ê·'H¢Í?×V÷Õç Æ/Aþ 8Ä&ÔnDÁù „ö!ªžqZ2Bq  à’SC$5Ûc«Ž“¹"TÃDšhcåÏÆ�à^Y2)¡¾-©@�}I½ßrœÜÄ\ÏÃÏ59Lä~Âñ÷Ñu"¨ÿËuö»Ç¾oñs›—†àŽˆáÝ«äk#D]4¤ž Ây°ù™«öš5kÖ¬Y³f}2jfÍš5kÖ¬Y³Þ�z~~•ø4J;âÇEFW-ЈD•GN"¯w,P“’GD!�¸ê3 À{®V"€V^¨Ê§þÎßþ[^T¾!ì+ Ž²¡éüÏP܉%ü�Q¸ÉÃŽïgÊÖö•¨Rì×S~vY$¤bßOö8‹j;¨gµ¹nuÐñÐÛŒòãÒ.£¼Ï>/¥n£Ï;Um,î•È )q×µ£|sÅÒ¶ƒJ(,–�®i¿x_“)¤k#Û>õ)RÕOZµue-ß‚úÕöÂï…�¸�¡+‰ û¯¥¾l܆ï>èÃ9N¡Êc·.``òPâ‡�%m?bœ€=·ja>6d‹÷”¾{˜’=©íšõø¬ˆ+±ulHni¡Í¶¼E�sµm{1žQûÑfª€Õf «Àz ½U*ïjŽê›”2ï« Ð�<Ð8hŽ„¨ÏKIA#«²Aál0†�¨™»‡„–Ÿ¥ÙX¥ Cî^h®5¿îÀãBø9Hk2Èøº¯æ³Ò§O·Úÿzž�e2.Z®‰¶ƒfЖ4¼#TÿÏà)Ÿ×ÏÀõQÿ¡‡Þyt3(sluM�>v ¾˜e§˜u½ü•oü¦oþ¾ë{¾ÿoÓû€¾ïE>說[eû8£|ŽBñž7P_£¨¯aÿN^•ðètàÅE‹r›s Ê¿GE½�ÏÃ’ÛWÖ‰`0ÿ-Á@"¤Ý®-1×0õw"V†%$—ˆ@”h?‹Qvt(×°�$(d!6¤ŒxÌ.´�[jÇŽíÈ{ò\‹í]ÜÚ±sŽÌÐHZ™ëâ>BˆNLp ƒæ«D¤Hm G\Ìš5kÖ¬Y³>95 ³fÍš5kÖ¬YoH½ÿþ»å‡˜á¹pT 3ƒ—%¨Gˆâ¢WXÄS€ëìd�²Hj#ø¿GeQZø‹j�˜í¹,Ì/Øñ;ûçö¿áýþ#U–õpñýª)ˆGÚ÷é-qè‹Þ€g #.ë¾…w@جTĸt˜ Þ..ˆ…tìnŽ)�QV�5à6�!@VëصÞ5ˆ[›Å(ÌŠ£@Vil‰÷Ç$ñ:hmrÛW’¨ÊMMvìµâÚ,8G›rko^ÛÅY|”)�€*!�GnûD­wÕŽxQµ7m :¶Go•q±³In'ÄŒ["P,uû§…Þ²À ‹´éüˆÙ´�Á™“å}ÓÉÏ&FcŒÔD@ úk=P©iŸVm4;BO›ážÁËϦ³„¨±´ 2îUn3®4@;ý'A#UŸM*TØ9®7SŸ2$‰ÑBzÚg#r®*`ñQ5ÖÃe³dç›ÆâAõ,6!üÎÚsW£%GÇQ<@‰å0N%Uß¡æ;^¤ê¯ý´9“}ÔÅ©w`—ß±FjëÙ¼«¡ŽP?j࿟.9}3טV : �F‡}ÀB‚ùÔß•Nî˜Õýhøóèþ—w|à€CÔ�)JÀJ×öÃ'€:F⨿N鿤ƒÓ|Ý:w x=ŠÁÇVw�y²ù¯}ö³_ñ/þÁÿ#ÿ.@¨â¢W®ªz°�ú}ÙÌ�ÊÔVîù¹$*±ÙQQU/.Û߸Hœ£¤vŽÊtO`{Q%ì¢óÕ.ðPˆdËœìúüì‹¥� F€³s—Ë ï/x)/ÁÌ1NK̹°[D°{_È "9Ö‹™±,.F ,™ ëE°m¶m‹1šÏ3ƒ÷¢E™H&<0ÈpÑÊ] ®Šê q1\7ÑVý/" ¦'BB¹÷icË/`v”_cŽýº^¹1EÐ?ÊÞyÐ^Tÿ©M²{›¸_®‰ˆÏd†¬¢ç\S:'’ƒX)ÞŠ�  Ä�q\Š»„xÍîTœ Üø)š'GB,$¡�;C± ­ÃWi㽚³‹GR ;8RÝó%^S‘"NþV)^ƒÓó“¦Ï}™”!¢ùµéÚÏš5kÖ¬Y³>5 ³fÍš5kÖ¬YoH½zõ*†IáâÂ" a��n J ¡ÞÑÚªp"A e$à=ð_”-qÈñ².Ë ·,oÿê/}î�ܮϲÿ{À÷Ôö¿y¥ÕÞ†_²²©±”©ýû=ÊAÎ{m­ï£…6‘T¹õ4:µ‹‰1„ Yà¶D#°ªnC þk²CoóQÑž¥‰jÏJš«Prk/›Ž?c”¤U¾q9NÊ[Fìoš~-µ*4›�w¶ãã+“Ïú„H® ¨6J‰Ð#®/�VÍlÛÄ4N£&n/Œ1ÿ& 6îé-­Â[‹›D¾®¨Û?€ë¡_ˆh ˜HdDU_sVÕÏé°´ì kWŠç�ÁP²Jÿ²¿˜káªà1[sªÀAªÚpL±d“ó=�iÃÖB1ˆmÈ€¢äþ]Þ¢çg¤ÝL4ˆõœS±Ï{–vÂ9L||o¢\âµK41› .”IØDԫ«DÒÎÕGjë¢<.�H‹–ßÂ@TT/Žj»uf F`e²›Ô¹õÜ –‡c(„@ñ øø}é5ªèÓ1xçB$–÷ð»Çæöhg–KUÌë²BŸ´€ÓF¥î#h½o;ö=|y‰.Î�‰°®+žž^àéò„Ëå‚e]Šs€ÖÛ=áÝ8Q•zà‡ç#Ú˜¥BâÌmaþÔéA E-m U$;Ñj>K…{j[iîõ�í~weϯìS@äºmÔ}ŽŸ®½?l¯úgÊxºÎ!"áH·-*âÓµ`0§¨—É+™ À²j$ì•K²¬X"ñ#¸¹ƒ÷ s|鳋H¹¯%¿ƒeĦçQñŠ}÷Xx�Û_ò#JˆpÕç•@JH�B|a~“üIfÍš5kÖ¬Yµ&`Ö¬Y³fÍš5ë )ïw„U΢ª±EQ¥â¸ƒ`á/Q�#ByAˆyÛª!#u÷q�sϯa&8çÜâ–§e]Þyïó¿õ�ï~þüOCÀtØ‚¶žËC‹îTŠ¡Û?¥<ô‚lð¿(è+§ìÈ;ZìoTõà“¸ ·ž÷KIYRa Œ²fÚê&©¸8ÓY²05ç­ ˜61²¯÷¥�â j5•õûZ‚AŠ�O‹íµtÔðo΄©WÌ7Ðq!¤kÆj¾²mªÕÀÚƒQù•Ï9!fÚÚ†º·¤‚Ö¦;õÃhoßë DO¤€òÖYÁ(Äm¤{S‰†@—u¹(—L Ê`(s@›i„ÄÖnÔ�C´êV™K}׬>L|×Ê$}Ðû)«8k¾€v wUmÿ ÍL%7YUyW ©UµqÚÙÐ'@Ý)?€ š¹”âù¤ïUÏ-÷6…@�ûž%Üph86׫r{°Lœ†ÃB• @z`Ü*éÁ�ލ¹ÊÑA;o2GST±£“Žc—¨šò5·gëÖp˜ßAmûþ:Ùh‚á-Åœ¨™Ž hTï]F�üŸè{÷ªãØ<2ë¼§“�P£`E¿ Žìà¯ýùëá˜Ñþ>…� ÿÂ]�pÚËaûÛ‘‹Ã£d‚ƒ ŠuY~úë¾á›þìwÏ÷ÿÇDô®ª¾¯ª¯Dô„ÇR‘Vùüz¥�Ê>£ÔuœcQñ]¯ˆ–|/±cŒUتÀîlv@õ\¥Y=œ°B@šgÃíµØ§ïÛŽ›»Å¹Îƒ÷°\*âs.»U°Q¥V÷8ß÷Þ'Õ6c%²¬xñâ%Þzù/ßz /ßz O— –Ïÿaû¾Š0ÏUÂQ¹íM2Oxî§x®"Qe6‰(XϤàäR Fù_gj`^+'m �¯‰u°}#9Øën÷•Ú1�÷uÌÕàYɸèÝ>8&NXw‡öõ©]¶í†ëí†ívöÝ2"]ïо\ýñçú›@@qHîlå™强k2žW™š |qWJýØ{�ó‚tí×|�u6[–@Lð“0kÖ¬Y³f}¢jfÍš5kÖ¬Y³Þ¨ª­>D ‘ÁI©BEõœm½Ï‹’é=@P´ˆ—¬þOŠ¥¨òàuqOn]ß^–åÓ¿öË¿ô/*ô+òQ Àÿ Öm�8YpêÅœx÷m¤âÚ¨%´Ý…,�5·qTÂP{®VE›È •y» ØäÞëyÛ”ÔîÕÈá½Êe(T¹±`×C†Zûy b–Ç­YÚ4YóÖñ¼f!ºì§=_ªÉÔYR£S,k 1Œ?O1š—V3Àì¾'´g)R[Ыµ‡¾ÚÚÇyc˜Ln†ÂIr—0ª5 †'ÒŠ«Ý|èj̳i@véJ"J�ñÝ*ÓµõÀ#zkÜ�”ª}Qú' ÃŽ‹L Ðv¸5 ¿;x*DÉ™@ŽÕªo#ˆ¥„±Éù‘úÙ�ШyíàÈ{¦Q¯6›ªTq ÚlGEAl¨DÕf$AøÞð=õÅ^!^[ôjK“š3spås;¦q®G1ôߺüp:zå€81ˆ“É=ý´ÙmœLK†ª�þ�¢ÍÖ:wŠ“¤çø•w]úËYßgï½G&´W¤� è�¦¾ÒQÏ ã(…á5?›ôÀ Î û×z ;ÜìknëÃ=ÚoéÐÑጊ¨G$L ×/û²Oý?ô~ì/¾xñò]ïx_D^‰økR³àY)œîÉD}´O�„h;_ÀI5ªs{í)f3¹üö üONQjG )À¬‚€F’¢¸8§F%t~ŽŠ¿K‘Wõµã|Aõ¾c¿Åìú�#ùŠó6¬b~¤XÏÑÌ€Å-`&<=½ÀÛï¼�·ßy'|½õ6ÖËš·“ÀòQ ÆÍË‹‡��d7Ï3´m %”vŸÂßÝRîÙ¬EÔf*Q íù¥Ï¹ Ò3¨iûZïw0»ì>¶›Ï5 �’½¾mßvnÏ…|$MlCˆ2”꾚]&¢[„ˆ`ß7\o7\Ÿ_áv»eRF‰ƒêxæna,Î`¿&3üîãø8’£úÜ`ÉÅù!Ž'>"Œ&DE …;HlwÛF).#‘LÀÅý:iÀócø¬Y³fÍšõ «I˜5kÖ¬Y³fÍúWQ¼Ö嘃M{Ä{™‚�gX˜ µãúµ‡ ¦ ´¡d“ÇÅA¿ ö=D¤EE"Àñ²,ëúòrY?õs?óSÿ„÷ûgx ÖÁ@&D5Ó�Ju=ìÔ;Xô'³c:|�e¬ÅñÿÛ¢¢¬'XÖhíHËbó(‚9Ù«�ÁàpÀ¢Ò/¾[ki«¶B²—¬DÉP>«ô þèß’¡É¬»D4Õ(œî£ Ú*ù3âkÀ·!èŽúïYÝl_Üœó~A‰&°ãîÜÞ~kÝêÆMJ¯‘®e\·ù-«¥‹tEkuFVr•n~b×­çu&ï} D«¨­Kƒéc ‚q�0D‡¼­“ø•â”Q9f ñM7ÇUÈe¶»é‘[Ä�"3•Tœ•D Ò7 jÛª›º`­±këÊÑiDR¹‚¨É‡núX��Ќ߃qĬ:í§É~¿QˆÛ9[ÅÁ`Üû‡‡[Ï!©ß葺ÝX¹¹ÕõÐatÀءÇJúãôF˜Ý@ô±¡«‡7Ú;cWô5ÆzÝácðДZ݈è�11ž¦èµÎ÷Þ© Ö4úñÔùÛÀ8ŒSPÆUÜÝŒv×r]–Ÿüúoüæÿþ·}ûwþŒsî3]zVÕ«÷þì1&*ÅÓ8À…{œö y&ƶªÿ@Ö pÈ+'/ùy¬{4¨Nƒã<”×! &Þ÷“Ÿƒ Z½V÷†¨U/÷+bDã|ˆÞ nzï\Ða‘ XgÐÚqsŽõ3 °.+^¾õo½ï¼ýÞzë-¬ëš-û Eˆ—è$àA;a NãqP¼šÁýüì“Û—‘,îGÇfŸ{ ›˜;%¿½^"Rñžìš¿ûÝÃ-K´!Hd‰Ø0r ¢Yœ»ˆ $-ÁBªÏ>噾v!�ì ÀÕ{í}/Ùþ[¢ƒˆÇmÛq}¾áùùŠ}»Åã�öùË‚â‚QÔüe;ÎD>n/ì/]›²/Œ ãþ3¸‡ ¸5ýÏæšÆYîñw‰ˆ‘þ扰¬)—jɯïð1kÖ¬Y³fÍz“kfÍš5kÖ¬Y³Þ”³Ëj­ùá˜ÁŽ£ê$’âÂs²yÜEà5ªTbj²ÓLvó^BiZ¼f&·,Oëåòö¯ÿê/ÿÀ«÷ßÿ¯åˆsਡ*ó¼µâÏT½û¤†òo³¡Á6Úüå³2€»!€Qìà QíU/Ò% ÿ¢¥.yõdÁ6Œlìq¬jG¿h^�¬t>λ»‘—ó(@b>‹áÁe5œÖmœlã Û¡:†bËž¢ ÒaPÞ8 ÀG5é•�¹9Îm‘U‘*¹VÀQÕöù\õ5ú^õ–b�U­÷zu 8c°DåÜ«LtKÚi®yv]0ç[ö‰¼šÃ+ýÛþЫôïUÇ=²:›ªZÓTŽ„Ãv [G=:†ÆÚþÐ+ÞÅ4�?P#Õ:¡¶íGåð“O®-Eux�À…S†¨‚£'H9—~û,0$2`ã”AÆŽÞÆZÔC¥¸ëi¦q>hÝ’kAßt*1ž#n‚�-XÀÙ™ ~.3m¢,R{1˜%Fc¢Æø96bØ&.^: Š“5~-nÁƼYl öÿai‰6Ž, ‹™»—² )‚IJìØ-뺼Tï?óë¿ú«À0@ÁA%uVþ:\®/1Çr%é,'ùl‡j€¦&÷ž¬_p©Ëk‹-hÙlNH  l!Úd�7§5 ¢ÚHwÊYµ„�öYÛµjüû™rQµ-à?zƒ¶Öí"{>^*$Jvô¦ˆÉ­M�ÖÅ>Ð8UƲ>msÜ®�Ä¡åz“}WoWÝ)«Ç�§ÛORýÕ¯lÐ s•Äœ%0•ÔŸAúmä5¥t!_�Z7t*½dtfçUðüh·{4guß[W Ø~B�•¿«^m®W•Go¯YQýWJëäÒAM;ôF\‹ ÓáyÆ1I¶{“écÑ™@´¶‚GŒÐ@‰Ö8½Ø‹=ª+šŽ2‹Ž* ûà8a¶£Ùû¤SÕ×mhç¤q z¦iݸÇvã Ã#»ukޝÐvD=~F;PÄèxN™ˆ�I»0Fqn ó-EBW«è·|ÒÁ€ñ~ÚïF7/;uxO´°ñ8§)9g~ð�ÜpÛL=¼Õà`Ô¡òØιƒŽTÅrèI›(ñ顳Ãý�صüÑ�»áÇñlxçr~˜]®ëúÿú¦oùÖÿá7|ã7ÿœsî]ç–÷�ãg"Þxž#“SÔ�¥d 7æ4b&äç•Ä ¬Ç°c ì³Mz!0hçæñIò�–(ú¡3r¤N19‰*nXãñŠ„GḠå2 ~ÇÌ%ÊJéÂïûEPÿ/ËŠËS@K—eÍçãýßã+Ûxç–uÅË/ñöÛïàí·ßÂË·^âÅË—xñâEEÈÏöq{·ÛŽeßàø÷ãý:»s±QÞDRÈKPMÁ b®cig66öÅŽßåãbÖü{|ÌK¾½gÄýî{Þ¦%7ØëÿˆÂ<¹P¾ˆ0ýÇD1pšƒ*+ý)àò¹»Å’Ãû×Û ÏÏÏÁþ»bßw¨Ëâr{¥¶ ÄnÆCr8’�ÛBý9!»˜û[Š°Ï¹il‰*$ºrx/õáZD ŽÀ½£%üË%BA4€ÿûæ±í·LÐèʳ,;DvÈú>G6}rÖ¬Y³fÍšõ¥_“0kÖ¬Y³fÍšõEªv!ìòô',6.X×ërÁeYà˜3@Ô4>,YkõjÁ Eq%i¹š¯ìÖ뺾ý³?õ7þIñû·eM²YÓO¶ÄÁy€c4A Ø�0€ü§;>ÏCô©Î—µÛŽm¤“*–Z0›rtA L%* ,æQ†ø(+bu ÈÇø`*€³Û3‰ÂD¨RPöGû/(j¬Zi`¹«hÙ�ƒðGØ#Hi»ÅæÜäñf›÷º- qÀfŽ_‹Uj�8 Ôº4–È-Фu$ÄqQ×Ç™ìu¿î@Jä7UíÙ9³ÂÀ³ÖEƒ¤ÚK> ¡¢ëQ YÚâhÝV«KÛúd?‚ TO*þªu³õo¹üjƃ6 àlù¯cKï¸RîÇ£ù"ªƒ~t¦º¹“¨hì—{÷æÝu·,׺€Êšóéûmû/åõMxÆE냳 šíOTy¢À.M^}Žb0lM ƒ‡“ìJ¡�l”Òõ$îþÄî¼B¦µZê�PÜã­ö¶µ~§#c‹n_Æ õÚϾ–P÷9êHAZ9$ ÈúÚSEROõÁŽlÖóx6Ùæ5y&Ñ5L}£kÚ® DëlõÜ ÔŒçjnD¶ßÇ`j“àÿŸ»ZˆPC½‰ãʨ ‹w=µÖšW„:k]ó�¤ý$]ˆ­SCó;{H°ð:yÔ_¬üÍJÜX*E¿�¤+Í$h;Þê}ÕóâÑœAõMìщ­s+ÁÖõÚÌU‡®;M”C¡+á\ч<Œ2¢ç–Ÿüê¯ùšöë¿þÿ&1àœ{圻:·\Ýâ|QUµH™�@þtñYÔ9Î*j{}Ký‘ÃÏ�û¹ DDAÝÌæÃ#§&—Šjk g˜Ê |§&jÀÜ7íÃLà«å8€ÿ.©¼Ó-@|&.‰hP[7ã"¿É1`»m¸Ýn¸m·x€sŒuYq¹<áérÁzYÁ®8yaßóó"w7Ü»°¸~Ùá¼Ë®Džƒú]¼À¹%º8ø&s¾}¤g8W\Â猥·-6:.PØæÝ×`{²Žgâô·×aÔ7Ô�ìëmTAmç?Ø.jå<;îbBœš ®jë%:¼ß°Ýn¸Ý®Øö ûÀÿ°ÿ@HÉ1 1–-} J‘öY%õoÈ È.,�|RÈ5áo!Ž€+ ~Í‚ä{ñážÆÇ„Å-X/+ÖÅ•ö�äc¿Õìò�-ö=öQ‚,–Äö¹¬“0kÖ¬Y³f}’jfÍš5kÖ¬Y³¾È••.(›˜%.Ì9¸e ¯Qý/ÞCö¸Pí§Ã¢^Y JÛôQ DÞÏ èâ~ ŠÏþæßû{À`¥§ªLkÅ–¦h�ž_G4ÚÒXŽH#ÕìZ0Øw·­~ Ý–[µsh³´]5jdã!ÝA�µÂ3(ø%3JNg~7SÈëŒÀ¼@û0%ûDÍ«£ í–ªÒqtŒuxÎJ×n�¿VøÕb•ÃÉÉ :(1˜S~-ż]«µíkɤËýãž…¿f²¬õêáÈ£NüšsÜq¬Z/âÝRBù+—EYÎvRl›^ʤ�~ÑêðbWýc˜Š¡�ÂÜ€hæ’@šÔ,¸¹{åZëR Å—Á`·Œ9ÏaoFTªt¤¶yÚäÊëAÛK^=H~}|›úñqÈÛÈ„Š\5Ùöw;e’Vó¯éíÆùDÇ@aK&²ÍB&>BÇp7Sysr€�žÔw* aŽ jÈ8=¤Þíê="µ(µ6s ®Uí·Q¦ªûbKª:±¾?§õØ-Ÿp–»ß'§[?›9M |È¢ñ¹öƒwx=ºF6"�Ùkן_ó *âÒ‰;ÑogÕòojžÅÛË·Þþ ßñ�ßû¯/Ëòyfþ€™¯Ì¼1;ÏÌ»ãd™ŸÆŽ‰hAt}¢�»eÁ²,X–Îq7îDîo§ž®­f ¢ ˆìÙú]#ðpÒ@`"É sRá‡Ç oTØ °&c½™Ä²%|T¿+Ž€‹zøu�Û°ß!ÐJ%Ï\b¶|ÿ¯Øn7l[}mÀåé‚eY±¸°üºí{>.iÔÜÌaЋh’‹£³ƒs1—^]¶â—äB°Wq_¹Êñ{ÿ8›¼ùÖ†¾ñ.ƒüÌõ6Ç�hûŸ¾F±Aõߪ\Yö·5"ŒÈ– PBD#ᣀÿËâ@Ĺ­¼ß£*ÞWÇÉÎaY\ìÿÉ5€3)0]Coôc×Dö¬´Ûc…Ïv"K‰Vp”¯Cúp|Ÿ�À¿`÷A¹ïU@VZr$Åe]CT…±x51Ú)¹˜iq“AîWÞ»ðùd+7‘I˜5kÖ¬Y³>I5 ³fÍš5kÖ¬Yo@•œÊbÁ™l@�¸Ð`O‹U»GŠ `Ö²ÁÚÅÜ ò&¢‹sî­ŸÿÙŸú“â÷o«ÀÞúŠ"žYƸgÍ*«}»qrW‚>:P-š�´ðjTÇãåçƒä`-–ù^NTƒ�z 4ï�Ú67¾^ìÌíYÛ´Íïî Ü,€Z°Ykp�å£Z«L³Õ<�ª÷j@´nœ÷lMVñZïZ¹7BN®ñl  ¶�j€JÉÿ.êßÓqi›PM®»½t kÖŠÌ�Š:ˆéÄ%{TÖ“nÝ�ìR½�Zp¿¸B6»*ÑGCªVôRÕ—ÒyW6æÝu¢<è{þ«žYK— ÒzÆÒ�¢Z;P{Â^Ëá .M6Ö �7q½xëyµoG®ðõÕƒµ ‘�…\Tÿã÷ÛOzL”ʼ�Ž8& ÉZŸO Šë8+}°ùbY¯ƒfj¶�z@ªžD-èhn:ȤM-‹´zm ºÞotò¼0ž+é€+7rGÀ‡À·Ï£T8¯×išLj飨;5­ÆìkŸÚ! à S9ãdlß;xvî¾æk¾öŸþúoøæÿ¯÷þ]"zß±{^œÛ�sRfT÷ÝäŽCA÷˜-¾¬kˆ¡Z/ÃL÷‘2f¬UâÀ‡jç2ÎJ¤‡äãJ ¹ß}h»ç1"ÀÕóAÉ“wPwÁºzì P÷È.‹s(@iP{ßnÁ>þùHªŠõr êìd÷U÷û¶c»má£*;<§3·Æçø¢î÷ÞcÛS4XRï»NeŸÞû¾cÛ=ü.晀¢Š¿¾ÉY¬ëÛþQÚ(“S �KÀuÈËõåì$1ºís¦ªÆÏ4ý߉©zžµd�Q¿ $C^àõàÒ×Ôÿº‡ç&ŸŸÓðODøwK!Á¬Kþ[þ-ñÂç8ˆÜ#"ñ•}$Rh¾Žì8¦Ø¿0g �dìûž¿€ûÖÓå‚u}ººhéÉ Ø‘@6ή ÉPåj 'GŠ×qð˜5kÖ¬Y³f}iÔ$Ìš5kÖ¬Y³f½AE•ÅuXh kA12.4ù¸¨Fˆê„ˆ]¬&åβ€Ty!¢§ßøµ_ùŽW|ð'-PF�¶²µ{éŒëho“C®Å.½³]ŽoTXpÜn‚Î&~¯#<£q×r,ÑK;+~Í›F–Õ£cµ�Ad¥™F¹žÖ“A{c± Kž(™óE¹¥Æ§œ*ëÕ¢º–â Úµ%Q“¿=Ö‰çæm-cÕJv�Ú¸uT'ªûnµ§ È��B$ÚúRÎAíËîëq� µ"ïµ ÙdäpŸ,‰sÿ6è6¡^­+Aî{5PU;;hqC)ª¿¹öá™V™â暘¾3"£¤s¢˜¥Ý¶÷øú �r¯K¤C‹ÿÖ€ÿèlJGÉ Òƒ«PÈ7'Ž�ŽÙ¿ûSóBeyEð™NÚÆPTqåÕXÍs«¦¶·*÷A_ï»S#*vÝܼ7)ÏÜ Û¦j§H̱܊tAÔÛõ­ ®ÿTï þŽ@šìøF³ú“ösM*•ÎtÔ èÒ'Î:ÂáVÎ_ªƒ¡õ˜êž:@mÈ¢Ýö�ömçÄñ)¾&èóè¼5ÜWôïzÚë`¾=»šƒ{ô¹ åÙáˆñQ’^‡SBÝsW¹æ=±¡¼âí·ßþ?ýÀýÈÿlYÖ¿·]¯ïÁá&~v˲9£^Q˜ˆ(£¤Â fv;¬ËÓK¶®WU¨?'´àxŸ«3ßÍÀëˆL ×€–6檷`n•ÿg�dº@ÁàŠ;e,ËŠõâ¡âá=e »<'õÿízÃõzÅõvžmØýž­Ø]vNˆà¿ß {$l·êFÀâ–å‚u]20˜k” ½ÁB>�Ú©GøA5 ³fÍš5kÖ¬YoH%uGÉx�ù� ÌÜû¾a‹ù�"ØsnÁ²®Á¢’S$�Õ,ì@Ä OÌüò×õWþYžìJªœ©¹ZP `¶ÉèMx¥UIk¶Vo6_Y@Ÿ/ï矴@Òj½-CB©ÎîîŽ×Ú…«Ö¶ýZÚÄ¢+aqN£}?28 nÀ»ãEñÌ ü¯Ú²,VÇ™ùÔ/ÔBû ”óOh�žªA©äÀª±‹²:\Ÿ�qÞæê–6°?·‡T€Kh9µƒA¯ú'›ÝnßSíipÑÀ Á€)ewuvÃ8=¸þ¾u  Jdvcú–¦Œß æ›×d7÷‚£ŸÎ­ îµc­þXÞÿ!ÑúCþb.ðÚ›Õ‡mãܯ�gå³~ÕœôYFŽÌƹå@s\ÕÅúc"èÉï�ïKT#NL °\.?ù�ßõ=ú¾éwÿÜv»½ïU^)áÆÌ€ç˜Ë΂‡ åø Êu\g ÞEPÑ-®õËýBò³Q7¿f;};7_°ÖE+v¼°tK4åûR‰ÊªúQ$†ØgY žWãBÃy~‰à¿¯HvŽêV¨ø8ï‡íx Jïí¶áÕ«ðüꞟƒõ­Ù÷„ÅXÿ§ýnÛ Ï×+ž_½Âívƒßw3–eî^»‡3@t:‡@ÊXB €pé±M8ªºq�¥VŸï@ŽPc#Ó©ýU!¤Qå§¹�cD‘ƒsŒõÎ/çœ !¨ïîE‰nã$¸_\D<œ[:²3w„“ ø§êóHKhVÕJÕÚ&Ùök<àÄåûI&8,AùŸ D TŽê=$‘ Ø!‘×HJ$[vkJºCu1ýÕÇc ±Á%b Ç©ZØÅHƒ‹ ŸÿR$g�6š-–L˜¨Ý1Ì8D4Ìš5kÖ¬Y³¾´kfÍš5kÖ¬Y³Þ� v™TrÒ‰‚ò:fAV€¼hÃQ ´DÕQÉx•Œ9v¸ôÖ{Ÿÿ­ßñþ{ïþSèqánÁ(ÿ!ªnÚź�1~·M ©•‡ŸÚ¾ß—öe§}sܵ°=eÍE®É¯©sI“�hÙ„ܨ±-%”!ÄѲp+g[Z$�Ž(”ÑM¼kð_-‘�zÉ"†´P«��À¶xñ§“öÊõº{¨±r·çß^©ñ¥Öh%_9.tÇ|ÐMª}Ô¿¯ Ø{âS»•ƒlö¶Wö¢Õ.’±§oqù*5€lP&�¤¨�Ê-ƒ™¥� ˆ×Dê:RUwí5ºÊ•Ê”`ø!vD›¯]"¹!æØˆ�Ú&bõc¹Š A±á¯Æ5^ Í5±­ZyÜ!4ûM«�K@]_´Ðe»-ÅÂèÔ¸£d‚ÖJ«žF‡‡˜²Rõ¶üµž/=Âæ®+b€ :ûþ~†hÆ Ùñû‡å~Ø=¡%ìÄ ·ºfÚŒ›ì-í©qLTÙY¥n�1à_lT_ǸÝ^=lŸÃy¨%¼Ø¹ë8£‹§úñïCÄùd>Ç€;@�ŸûhNi•øå™âè9áã­ú§ýèÛ¾gˆ@£ƒ ´$ó2ÿö;Ÿú7ÿ�þØ¿âÜò÷Ÿ¯ÏïªÊ"z tv�J\ìû!¸T…hR,E¸KÀⲕqRv§LuG¥±næÝiZ7$ª÷Én)í$®ÞwÅ`ØGœ>ã,>¦™½Â“€hC˜é4�â98G.€Ýïñ¸]Ûlÿ_½úÏÏWÜnWø}�õKTþ‡ø„5�ÆQ-~Û6\Ÿ¯¸^i`�â×LZX2€®9¢ ©â“u|у*=³ƒsq ‘BÖÈ÷ã èÏŸ9Dà_ªçÑê/º ÁÉÊ-�äà¢"=‘cEöCFÕwADP}¾°Ï¸ÌÁî_Y»>UÇFÔdþ‚etN£½äÞCáAu�0G>œcp9ˆÄê%Ƭ~�ÏÑ2?EZ!"!º$¬ßCüÉ6RˆÐò¼ÛJ„°ï·mÃv»g�m‡È(¢õˆ&X\pË ¸òä‘"ŪèÊÑ ÖØ?|&i´mU�·Y³fÍš5kÖ'¢&`Ö¬Y³fÍš5ë )‰ WhEË˸PT&>|EðšãÂn²wtiAˆƒúÚ‘°2VU÷Ðw~áçþæ]E'¨UçF¼QZÕóµÍ«uO­¸X`[5°�.Ä�¶U´xhãì‚UkW]€WcÍoÞ—òL-Ãä»2h…NÄhZoÉ0€nlG²Ùá ô*×VO2Ϧ$XöCgyoÁ2M0r7Èo1`lú]¼há¸PY©×ö T/Â7WÎ’#Ê¢]ä¥;€4U ¤õžÆ@}¿ Žl°÷¬Î*×ÛžCŽ;h2ˆÚ•Yù­ÖÃxÔÒ+Z§s]Š‹D!†dÌK%Ú"—}i"‰h ü? ²�°Î y f§mŽ‹£í”øôËÆ$¾Â¸ëΓ]4D«ë­ƒ3³ÿZP¹…ÈChö‰²Ï:¤½ô¼SW’†¨4öÒ'&ßÚ̽mB{k„B óÇëd®ë€¬ÒŽ1µ�i—Zzȳ0ÇIµUI›×]”í¡/W„Æ…žrlH}!z<ÂcÌ…�ÎõÀç¿v(0ó¥Q‘VD·“¿Ç8ƒRŽûAwcìÞÔ%­Œ'O�tž¾=V‡à3®F €~Θ ŠÃèú¸¨ƒý½@Ï›ÿ|Ìžü�™å«~××þ3ßõ{¾ï?‘÷nÛí=}À5Yy3'ÀÒ• õ´Ý¤ZV1ÙîÈG츞&;¼u$)ŽHMq§þGÕÏS}´wgÎàÿ²ÂB"èi~Ë#mjÈ‘DÙ›Ñq‡T±ûDs dW�qMÎ…óaxÄ n·g<¿zƯ>À«^áv»b÷ Àì²àrYq¹\°¬E/"Ø÷=~mØ· Û¾EÛþxl;7à«fÐ?€ÖÞ<{…öYDáDkbéI¯Ì®NZÇÔ1TõS³q_à@H@t8¿är>ŸìÞcßvì{Š`Ð*v€¸D=7ýKÄŸIìs˜u.*rovˆí¼óÞÝ�SœA8V;ǃu.`‚jqu ꈆ�uÅzYá8(û÷}ÃíFÀ¾g²µLPó9`Û=ömþ_±ï7xÙÂõŠûvq|²c°#DnÀ«d’Bwv÷P†ŠkÚ©¼ïì³È¬Y³fÍš5ëK³&`Ö¬Y³fÍš5ë \§*‹ {à:fŽzŸiÂ"f\è�6­K\D¥hM©D '@ßùåÏ}î;_½zõ'Ð&ê|¯ß³‘�@ª5sñ’¯sÖ³R4h+Ë@ýÞ òªûÚƒg'†¡¸3Kæó‘[‘äˆ QË¡-#"µœ›ÕdŽ×‡‘H.¤õ˜Ð| ÔGTûn­š%(”‡'š�KEµx�Àa‹@Y·5ㆆDOh‰5%Ê!- ©¥Z¯‹aŒÂÀ¤œ¨!Pˆ/‰cÆ¢¿Š¼í;«ÖêüÖëÀZ½�ƽ9–GSnëà†`Iןš>§1^CRÔAëБ^CøêçiŽ®gµÛ…µÆ×Ó÷Ôªø¯ƒè“®ÝF÷�ú§Ð¦Úu£<ü;äÛA¨ŸÕ h:,$ÂKÜöZ•�?Áé¹�†»Éàë+= oÕ×�çÕó;³Hùè Ð)øðŽì¡¯¡Å§ÇÚ¼mé/–ε;Ã/8«ËÓÓð{~ïþ÷¾üw|å¯ìûþ�÷þYvÿ,¢7àØŽƒ�¾s4D!—Á(³-Ë�"ç(8,`±Löy €¬„h¯”£–Ò3­ÿÓ=,Y¥WÀb$&8^Ì3¬ËÄÖz®*3±ÀÃÅçß@6 ¹’F ¿1NŠŽÈ®… P=ïåç`]š\˜…¡Š}ßñü|Å{ï¿�>xÏÏÏ�¨¢wn�[– ü_V,Ë­ñSf¼¯ïëÐ#“âsé¾ï™lY}/ò~Dz\à–=:% ~Íùò-ÞÚóg‚H3ßÅ´íwÖž31$ýœ"!¼Oêõ-Ú×û¨äOó¡­Øñùø4@¾ˆ€„ºŠü|~ñàÅ~Ós�@5Å\Û{fP]¸›!ù!SGL¶�¦ØÈܺàr¹àéÅ \Ö"‚ÛH ×ëÞ%è\µ¹˜k¿möÝC}3D²·Ë×£>ç° Ÿ>Ñå#}^Ì&_Ì€K÷…rŒAr©˜5kÖ¬Y³f}²jfÍš5kÖ¬Y³¾H•ì5K…Å'«:L Y">«¶DMX �.ªAŒÊ†h! ïüÊ/ÿ�?ÕKÐL&b³)Ë‘Ü��†Uq×Jò”Šg`Î7�Xïö®Ùr<Û�šÿYKRó¦þÀPli«LhÔÙ¯ª!ƒÓ‹fGƒ€™Q¥¸  Èè·Kô °pö笢'¶üe�OZì´¶ï€Dy³RÀ“¤Tåj'+v* ¡€æ  Vng„�ï¦v†ö°h¡M¨uë¹_ƒ ]Ï€f•Ý»Q°Kpm2¥a®³ÉA¶‡‘Õÿeá—šêÀËdª#ˆ" ,íÔg‘¸ JPHå”Ú‘V"Žæd”Ú­Š´m3Q�rä|ý{éºbÕIá§µn_òJß„¡4OÕ1Ó ›aòö´èMmõ¯�#EOŽ©;§!;Tï¥.v¼µU3§˜ ­� Ê®¨Œm¥ ˜³Ç3r�|ó ½¿9r„ s2]¬FÐúÄÄóµäÕÞ�†xt”v*�yËá é•ô`&VâLP¯SÕ7è€7V¹CœÛß?tÏ?ŸÊ»íG: ;5ƒž^CÙÜQ~{xºûÀ�5C‡t@øÐÏ[ƒ!óÅyðÃØ¥A�ˆˆnŸùÌgÿçø�ÿgÿ’÷þÝý¶}à÷ýYU½÷~÷â•8X}ú,o1Š`µJ_sMÙâL Fÿ#0�#‡bßnHˆ�ƒN—ç¾@Òõ9 Ÿ-Í—H`57…Ýo±™ñ™ŒF©æQ6Jí \7@.E{Þ“*8·ƒÒó9°ö¶ÝðêÕxÿý÷ðüêö=€¥)'~]V\.+ÖËëe�ÏÂÁo?Ÿ;St;X£ ½ÏmjŸS³r=‚ù”Tö|?.dÎni‡6¯ÉÖš?\s®„�vp ç¼xÇÜÓ-8\×p}·Ýãv½áv»bÛvˆê!;žc(’Ž.õ�È:Œ%òT>W`Üתg|Óßúv@&,K°øâ¹.É ¡y±n‰ÃRžÏ’£Åº®xñò%Þ~ë-,Ë …»>çûê¾qŽTs‰ì’‰¡& Þºf¥ëáÃ1Á™Ï6"’ç6�ü@l.ÄĈN�˜9:!¼÷ðùÞí& `Ö¬Y³fÍú„Õ$Ìš5kÖ¬Y³f}˺,Ë’-©µR©K¥ Êyôޱ8†[ 3;p´� bu¿¨âÅßúÙŸùÁëõúŸé–ßÕfOÖ6®@�%Ÿîý­Qm√ÜìÓuÿD!H@r HjÊ÷ÀEzÈ@ƒ�µçªq‘̧(€©ÀÚ²«Q‡K[%�´)Ç]�¸¹¶ÂÑ#gk«ÛJúaˆ]P­FomE+ð¿VÓd[ñ¬š+êõú’YµmÉ” Ä�¤'<Zg¾¶ªââ"A±‚í‹*ªÀt†¯\WG@¤ø‚lY@è¬Pν–&'pÅÒŠm²jÕ¢@SŽ­°à½v1<A@gòy˪6@£Æ7@³Z¾´Ã­kˆ þ€X +ÁÎyZÚµåyŽh3Iº+m¢YÁÍ@Ã…ö°t”ÑæÀ©•5;jÔm„¡B³ê‡ªFe^€ƒôûÌsÀè˜L @{•éüÞ2žsšˆ–xürk=v‘ 2ØþX‘¸ª7*Æ>ý›Ó˜©�:èÞ!¢¥c„Ç­Üû6¤{;=Ÿ÷pÌ{ÝKŽ�yªRØ>ŽæD?ú³L{>�+ Ýy°S¼¾  5:=.{�i<¯u%_£_#|TnY~ñ›¿å[ÿ;?øÃ?òWTõ]Oô¾Š¼â�wH�½°” @ŸíÊ¡€·ã–’jÎ ÏKÁVœ˜A.Ì�" ¨/ãÞZŠSRS•7¢ª!=>¿z¿Ã{_�ÚTvœòÌ]ÈXG&-xÀU¼òA àÇ}¦95¦2•°*öÿ‰Àé½­Šº| Ž ¡BU±]oxõÁ+\ŸŸq»Ý ªpËç¬ë/^¾ÀÓÓ ¬ë¥XÜ‹„;e|.ff¬ë%?Il‹ �>µRï{ïq»*ü.ášg0™ ñ# ôd^“lßÏQ•žÈÅ‹c£Ü'XWz†I×ÕKPÿo· ·Û·Û û¶r3–8o3£•A™�Ò_ùlTH£×´öø×s@õšàAu‰ûXÂ1Åvc޽Ø�wx0ïà=GŠrð"ñœBÿ½¬Oxñô„§/°.Kn{U�zGR dYg‘A …±ø%8Q,K¼&\¹CìL 8¾½÷áZ¤ë#ãÒ�Ý#�Çç‘ϷÄmhp�›ÎgÍš5kÖ¬OPMÀ¬Y³fÍš5kÖPªŠu] èï%ªÿ$g¨·VÆÄ1K“8Øšëv‚bQÅE/ã×ퟌ}µ˜^Ð|çÌjp2êfÑ<+\-œQ@@ÕÆ²ôhU}´x_að øo‹l†i´k¥�jWQ€‰jï6�]ë ðœ[ß"}fñy¢´ö³G׺;-Vãz°ÝZ©�‰jßk*Û-×øÍñ QU[@üòz•8·n™¸Y@<¸TÔ·I£¶ßWJâ°• PÆ‹6@i$7X "÷ýôúÎ… �F~÷ª=ªÕ‘•͉##0´µ¯¦p ¢lRò뤀¨ ÈYµ=ê/U·È?$fgæ®:Tô·„…¡~&4ÀäÐ*ZB�鯨{?5=[ÂÛý ^ªyû„s#÷Q[EÎ…=ïAÛŽŽXìÜ‘¦P2׆JÿUJ䩪U»™€Kt0§ ߥ]”ŠŽ¶g!5×fNmÎ�èx\Ftœkw#DhôŽ¿ƒšƒÓŠ Ç{"ȇ1ôïÓÛ�8Ùlá¡hsíšaœwO]ÿiÛ‚ÆGòñ!Þƒ9ôC«ìm¾‹é“w¦…n—Gn13@î^÷�ÒVõi�öòâÅ‹¿ücø�þs_õÕ¿ëW¼§ª¨ê33ï‰X%ì$ˆ“œ]NL•º?ÿ«ÜTÂG:€ÿé>šÔÕ5A4=o2[Wc·dðß À–‹ äœÁf#¤!c)ÌA9ÇnT«3Q°ý·d>sͶÿ̆� ̵ XgœÚ6?ͯâCÀ¶G{v Ùñë²àòlß_<½ÀÓÓ–e à~¥ä{Xœ.Èî]û¾…ˆ¯¨ ·»V÷Ïò·d÷¤ÈA¥à�ýö9Ï:B”9¾/dÝ'�‹Yó!þ >æ}ògzžö^áw�}ßÂõÞwxÙá½@pNAQeï™À¼çãíÚ¼q í"�ý±ö¯ Ò©Ù¨à¥qP-`?sŒ:0¤ghr O¸·}ƒŠ‚‰°ù=8ˆäx³c‘Ú0�1¤¸(,.Œ‹ø|Ì¢:R;§i��“%_'aˆâ5qà¥D6ˆoz†‘@Á.Ù<¼ì1:®D;ˆH DÇ ëzæ7?”Ïš5kÖ¬YŸ š€Y³fÍš5kÖ¬7¤Öõ’ÕNžÃ¢©(ƒ¼de;´XBV6¯Å6Ÿ8U½¨âÅOÿõ¿öG÷}û}v!<©™r¾}ƒhõ72sþ ×;¹ ÔÏD f…[¸ªþ �øŸ%’ó3—h îûîà<ÃÇ~ÏL�$C.î°Qäx³DØüŽ}ß²+Bú,“ÜÄ xqÅáÁ|®œ5kÖ¬Y³f}rjfÍš5kÖ¬Y³Þ�zº\Š�æî°mÁbôæ}V™Ûo.Ô¨€UtÑ—Û¾¿õ[¿õ›ÿÍ�!£ÊÃuñ*·¼¨ÝkÀ¬Éù6–Úµho`Ýáø¥6ã8½ÞB½œ¶nY�ÃÇ£*&.ˆiRcYƒAò·dׄãùšÅÑô=wíÓœ,QÝîÔì'íAµ1Än2ÑÛƒkô÷åêÚYµÕÌ@÷,ÞØ¹ L}“å�/‡NF¿óù&4ÿdÄác{ZŠ Ø‘7ï¯^irÕ‹kCR&ðutqu~ >1³¯œ[à^”ueë^L£¼®zA—¿ÎL€G…О%ÒAb¤+º•¾]�Út�aÞÇJôtˆ&ªÁ�V4Š7B¢@�F­�¨¸ëbÔ¸9X5sü†öÚ’GVúÕ\ruÒàÜ£Ò¶?•q�CêË“#GŠ8iœ0h›‘òßõž¢|RPæðڢݪZUºvVýíïºMd"eH‚z¢¾Öss˜®¿àØY%À4vívÐ\w{Ü0sgëîR¹<Œ®Âl|o¢ 4ô‘ã­¦8¤ œ¨ÛÐ Ôþ:bþ¢#rL�¹ï¼nÑýÝÜ5 À�év¦ãi„^§9èÞÅ,sŠc÷‹_÷ ßø§~à÷ÿ�Ÿ‘÷˜ùÀ-ÜáÃ=¹<ÏÔvéfÖ‹Ï(ݳe£ÖO`.i¤ê•ñ+d”ðD¥ñœ÷á³%|þƒ-y´¹GÈ/‡sùx™ìbü‘! Åá Ïí¢A² T@¹ªÞgÅOè„øK•¼Ÿd%Õ˜»—Ë/^¼ÀË·^àåË·ðôô.ªÕû“ Üø‹jÀ�¥\‹Ú)!=û+þ/p΀¶äND3GîˆíZ€]fÎÇeãÄòó-Õ–ô‰@kmõµ% “fuy²×-*ûô9AD@ÞÃ#ÅéØûlc”ŸÜ`+R{u1iЦ? zÉç�·#ðžÀìóç;£W6ŸÇœˆ@ ©%€ö a†ßw<_¯ùxE$|¸ÿ HÄ §Ø ?O¸à*áv8qðÞÁû%º($€‹1&âaCší±‹ÏŽ Ûvƒß÷L\ ×gÁ²îX׋^‚ A"W´Ž>³fÍš5kÖ¬/ùš€Y³fÍš5kÖ¬7¤ÖuÍ–•{¶ÿöaqN¨R:Û J…ˆHñþÉ{yë§þÚOþc~÷ßZ-(V@jA6ì‚5JÙ²¸-«óßzEÍHIgmöóZ:Õ _j­ûµ8€Úc)Ž-ø_;QGëØ¨F/uæ¨õ¬}Gå.�ó1ƒZ‹ÙE®È Ídƒ’‚Pb FŽß€Ÿ ÷PÚ ~GcÅ[]Cj»ß!)Õöø™€Ñw¨Ê„!ƒpü7Šé ‚�;(’¬"->²[Ek«¯�=¼iÇÈe|«qa¨""Á¡²ƒ?��1¾šë[I½Ãßî¥�“µ{¯ðs©T¾ÑÀ5iòLó„¼Ü ²'ˆPQÚ)‡i ,›¬ðÚ¡ýH mÇ3§‰d“~, n¡y¢[‚jTÐõªöz~Њ|S‹ÑãqxŨXÕ‡ƒ6£¿�÷îeÇW tOx‚ÑG›R­ÆrÁÙ5ÇÀÎ]ÍønÍ)uÒCµ}{Îw¨½‚Ñ_'=éÝ¿ÓZT?åR¼†RwG®�)ÌÁÃÌmÙY�FngçдCûdûæ#bp:œ_2QDtÐÇws?¡}ã½=õ÷wŒîïÇ …¦oè]e¾Þ=Os+è¤!ÎvF¯qñá/Õ½º\.ù{¿ÿ÷ý™¯úê¯ùeyOU_!€ÿ¢Ñ_L”‘hm1o⋺{$/ÅUJ"ÀOЬ°¦ÅåÈ'vûÙ&¾Ùn:®ò¼%9‹ÜÚ³3 éNÇ%ÆŠÈên Ä7¯•…þxš­ò¢éOËÝMÀCcÆ{;ïPEBmlæ5€ªÞ ö¢ˆ@þ‚u}ÂÓ‹'<=½Àåò„e ò|�ׂr�ØëœÀ-.%w·øœ€âàÜ’]D �ðPåÁ¸,ÏÛì8G”}pøj×Ó÷…h"æÈæ9.“|8NU†ª3ר%x$§2DZënfŸƒK¤uý®ô=_ÅØkÊ\€}2Ÿ:‹îY)|'^°oü¶ÃË}Ñì„ᜋÄ×+¼ßquK¸‡›cÊ× ˜—Bêà%’`8.Ð;ˆOçÉñ³KzŽÒtëP O±O‹‰ñ~ÇîwlÛHÞg'®ÅíYã±Ð58Dpè« žÈgÍš5kÖ¬OPMÀ¬Y³fÍš5kÖRÎH‰j+/Þ¢5ªQb¶ªP‰Ö�"€.ÞËËëõöeï½÷ùÂè7ó;¨‚1ꪔôé ü”­Ý-hÝ8ù7JÒð¾ú_X0=+‡©Þ˜}Y€un­­ªÃ³�à¿79êÈ(R¶ð'.VÓÕbd²ýw‘ó:““‚Ê™¬`¬e»¶´À·)µ ÚµÀ bA=°^ÿ¹&zD§çoŽúHŽ ’wßìÆ*^)ÛÅ3Q±ÿDPÔ@¶>lËœâ)* ß é½ÌeE,Ù?Y«ÒÞ¶}¤l·’ðƒ¶¦xÜb"1*u/ˆ]X’ &»"æŒø2d$=¯Î4èg¨mÖÛ~Ôái9CZt»¤#äþAuìCë[•¹f¸$Æ<­±ºüq¥|ýŠc¨ôHT"3j mÝh\84åͳ0Œµpœ´ó߯æQI0U7özTmA‡€è¸�õtÁ½­4s@?c�ÿ è¯õ�£‡éh8í廈�?ˆ….yj!:†Ìˆ½×.úett<íwû9ê«ÚçI5 ³fÍš5kÖ¬Y_àÙµ!dC¬’•*ªEãNÈΰ #õïrž6/oýôúŸüç÷Ýÿn«¦ûìA]:”õ%�óÀ.õðüÆ¿'ó¿Žs³˜—T›„`¡Nf0`X%gºd³­\£m§øøe3@³Ü¸ •�¤Š²¹¨D�P4°è?kÊVžu0Ze›e{æ–½SÓž½ÚЍ•oö×~˜¬Ã¥òÜÆbLêúAQÏkΟ ¦¯¥Á¤²—oÏT €ï´SJQ¨É$içÚtF5ÙãtÔC3Õ$j]tô˪�ÙžmÉ8Ú s¶ØK•z(“Â×gZ€¡PG}f¸‰H´"z L1ƒÁM„Lè¨[ ºJؘ‘ÁÃñý•»Â‰ª»úÏRÊïù2ì /Ô½ö¸ÙTnt|Ê­cMë:`ÉÚ²€îô‹|>¤UDøü'ã4Ò^ñj`ž÷µÆ®¡»µ4mAƒqòÏA_kœÝ‹Fï¾k‘ßiÂÃÇNx  _{�¿æsÜG~̪ì_ü�_õÕê[¾õ;þ*ˆÞ#¢g"~f曃ª×c÷ÁÚ[¢ý9�TÈ&žÈ|¥©Ÿ‘ü^lúÃv’Bš!^ è˜Ø¨ØS„ƒQýKQ¼«q1½·Ì”©`ÍmS� ¾ÄcòÆ= {:ûeAbб9éþ\î³ãÈ BÄ`9²ìæŠ(áw�ÛmÃív�À/¢ò›bÌBŒÃsb¼ÿi WØí´ÇœÚÞZò§çŽŒ`ùTÿÎ9,Î…||žtZýœÀøn^æÂ{½7`;$¶£VÔ²Ð_M”€‰ùIjøüÌì\xv1.¡íD)ZÁ>gkémŸ•|\ýtÞg�Òý*ÍÛDS;6¨zî**þ%}KtF²íGt^ }sÏa†K÷ _î�� S" ˜ëê2Ÿˆ”Žß…#g¢Ê]ƒâõc7Ÿ"‰‚¤rV5.Ùµ!ý.Žóø,CDðìã1÷%ÂÿgÍš5kÖ¬OZMÀ¬Y³fÍš5kÖ©:"@\hUˆ “*T{°r ¶¡šmDwçÀ΃2ÿi0~©šãÀ±|S©-÷mŸìÅ냈“2É4À> KÍAÒhþ8èƒÕí�0&t*ùƒ|÷ÑŽø*ܱÏG�Žï-C £ã»G,ÔG‡ôG«�ïÒ·'êËåò—¿ý;¾ûŸùôg¿üW˜ù}çÜ33ïÌì‰H­Â=å‰o·-ÚzoùÙ‚#”â‹bCÛ'Þ\Ø%ƒÿû¾d—ìh‚hç¾X�ò¬КŽeß7ì"Ø#XŸAü4_E S™áH¢‰ñ†˜(*Øe)…ç]ñy›~/.)z‰™áÒ=?eË+xpˆŽ C L$TàH¥¢¼O€¼ˆâ¶Ýp½>ãv»a÷{ž¯0p0°Ïª¶½j%{±à÷ÞÇs¬�{"Aé 0wnÁâ8çÅ�Î À‚Î1!ï[Æ$€L"Ì÷É–|Ž \P½kr• *zƺqÜžVäÖäœE$1úAMÜA eØÏ‰`AÛ¾D”ãJ{SVÞ§vsŽ�ë×Ä……³žÓƒ¸ÇR@%�D%>…g3yÊç齑R"—|U6¢à6�œÄD žóç:&6dä@Q�±¬üUÔ€ÿ©-|ˆ†²îdjb:¢«ÁÃ3ÃkŠ(�þ^;kÖ¬Y³fÍúÄÔ$Ìš5kÖ¬Y³f}‘«V,f£x•¨öÚq½Þp»Ý  8'P„…Aö œßÁ;“². ¼øÙŸþkÿð¾ïߢI½£UÒwVÑHF¨µ}t_ubõ£eíðx¢ ­ìp }ЦcÎ ˜R¢+ð_ ȤTblþi"%pþ»¨¸¢˜½ »�ªZ©Á)¢,uGQ f±­¬Õ{ꊸqÄ$¼Šl‹¡õµ®¯ñP”ÀG՞ȳSk4uW¨S¢¦Œë8БÇD1(NÒØÎ'+n¦�aÞÓ~(‚‚=Ê•J‘É­GGø› d³m |�¬Íãw4:œª­´>êda«e¦ nX�&âñØÌ¾˜<¦Áñ£évzBN]„E�0îžìRµ…>hù_µ'•Ã'}øýý¼kçÁG­î[ÐãqeÞ¥v¾R$ep"PmÛ^c7äDu×5t ô >Uixðl‘€•®»PwoÈçK†ÕÑlçèºèh®onSQ¤ltè¦Ðý8iì ôÞîd<'…æYœÈÁTt¶W½R¼¿6¦3˜Çº›ú{Ûˆ¤Ð¶çÃ1 ¾¿ý¼�Óëzò»ïõË>õ©éûßÿ%¿Ð{Äü�snwÎ�g5yêŸtßq»]ƒ¥÷î�r¼Q_ç÷&pV2P.†¹ïA-ìÕ‡9Å3ÔE�0m+ÚÜ'�5«ü�j?ƒ‹ù<9G‡DqUGËùÞ 4Äì3í%ÆŒóÜS$Së@šQ@ 8\�qMJÿƒ$Ž+©ÿ�Ë{�í¶áöüŒëõ–•ßõíL‹�‰¡bŠVêQa­¡ ÛëšÎ�Ùå¬xvåz.ÎEÛ™Þ$�¢B&“)âÏ¥í\gs þÛ¶Ô@(ª÷S”Ayn”èD¦Æ%¨Xû—}ˆˆ™»5‚Ï Œg‡ƒâ`£.8:#¸|ü`ø±Pú"w®Î�R�Ä’è@€ù ¢/¤Õ�®¥x0"B$[$øûyâï–�a+DÏ®�[Òµ�¯#NÏk(�†H!š‚+ŠcAõ™¢+4x¾³#ŒãfÍš5kÖ¬Y_Ú5 ³fÍš5kÖ¬YoH)"a±pß=¶ÛŽÛí†çç+žŸ¯Ø¶[P+¹`×2éw8·±[Xtðôþ»ïþ µVã `™l(kUýàxz•�8h`?ÊŒ¯UÿiÏï•e¹ê�;0ÅrùkRÌZ€dòC$ ,“ DÂB²š>Îù¹õ‚a¥òJªëH*"! Å¼Ï œi@ª-HU écŽ©Uˆ—ø„’U*rÀ�;d‰Æu €Ì =“Lˆ¼µ�¯ Ìö©!ˆÃâzVÅø†œá€–£ly‹`Õæ!‡¶D¦çŒWs<:êÌ'£0�U:h²$Øm' :c]­5½VQ©ý,´š²š³€$D &…dõ½R ‡Åg¶oèäeQ½‚@‰*µ_uEuÒ­VÌOÃŽ#‰€�Þv}ˆËžøÂW zÛ?r,ȹÂYíœò€J·puÚä¸÷4 ¬»ín¥}¬::S±Äº]P tÀû˜²u–ŸTžy¿Q9_¥ŽÌìŠðD9ØñSí¡ç¥åáwßž¾žÌô¸kÕÐ�†ª~}oŸªõx7÷€ã{#u±zvêâ^ïãøš�~I½ßBGÙÒæÈª~™n›÷Nî®Äk×k²èãÚï�í;æ_üš¯û†ê[¾í;þªª¾à="þ€™÷¤àO  ¯ƒú?A¯·+ö”Cž‹ $vÜå¨KRêKPÕåˆGòâËs�yFəvîiN41F&†¦zÞçòÄ'DF•]˜<â;íÑ l;¸7IV+ÃÎÅlŸ)°’��Lv„(bIh5lU=„HÄç=Á¾y\¯Ï¸^¯Øo·.Ï^�º:� g€ï €/ñ ©�íµå/å\yÞtK!�:ózô|ž”ì­ãHÚ7†ÏjöõœAE‚²=�ß"ùbãÞ#·Ä7$RŠŸU¨€ÿD•C `Ý9Îç®Bbh»%ì8Þ§–ÜÆ‰À�Ü1r\Ccd”\¾2øŸb.Ì Ëé+^³eqPY Εãu.Ç@ˆ TwÓ7ë'�LpÙwl‘´@FÅŸ¶É¼†¸‡…áV—ÇG ü�Dñò¤_¹$"ÐâøÅDL„ ¹àÂ. ÈQtÀ�=5kÖ¬Y³fÍúí¬I˜5kÖ¬Y³fÍzCJE!òOoûŽ[\x|õêϯž€Ë�ܺbñ;Üî;ãéoýÜOýø¾oß=ܾ]¤UiýmÔÖ0¶òD½‘¢}5Ñi ÿ�"%ï3üO"Pß ªÅ}¾Q“f•¼6¦09™D–b…II5cŒ�êߪÿ[«Ñ¼Hê}Q¥WçK™xA±‘ ¨E6�º(p»7ÍRgã+P^šô¦�,ÂÒ9<R3*Õ±6 ;UíOýõÕÆ €ê,û + lÑHk`PH&¯Ýñ6g�¥å(YêšÈ)d µ¶€ˆ=ߊøPg†SÝ '‹çGõ¤”bÚS3ýÀZçgÏ„”3œú6‚Í2qèß… “vSœ=H‚Ú:¶\Œ¾§TZ{…�£^ÕFIôζ‹§†ì\%ý«z*¤¤�ÙKã™ohÇn@Ø ´8�G&ðÚ1h=˜FÑAU©jã2ŠóÅx�}ËK”‘*’]ÿ°¥Lß®“1s×»ý¨Þéõz>†Š›}yä:P™×ãÆ5¥š »(š{î!:”ß—ù¸6‘HÌÜMÇ‘'³ÇùÔs–ÌÒ£3‚5/<ˆ‹°äÀöÍtâ)ô°ét>Ÿ4f^§!Ÿ©?î²Û¾\.ÿþ÷|ÿïû3ŸþÌgMD> ¢g"J¶ÿ1ëÝeЗ�¢yß!ôv»bÛÂs"P+œ+{}ð?9!훇÷{Î�W«ÚÏÎL!�� Ænfºð^_�Çø3°)ÍÍòÑ0IÑÊÄCwÍêuõb,ý¥R(¶/•=ƒeˆì"*e¼%~°­�òøüü!1 ‚ÕÞcÛ®Øn×@¸�-S£—ì„ ° ¶½òɽA�ÚŸ˜±,K&|¸¥�>\R˜wÏŸÞlS»khI)öê(š‹ò3�%o0˜%ÚÚ3¬ýK*)„�ä(!™4PÔü¥�B_MmOæw\}óÜ­ ("€%O8ÇÑ!�^ã pâà÷”k/Õ5.D Ÿž ³Û'·ŠŠ ‹Š˜æØaq+ø)’"á&9„%ë‚@Ž`|ˆfM]<öp߉Ña_ÁU`Y¬——Ëîâ°DŽB!0ö@Zˆgj" Çã[¬1~Kâ6ˆKtöXÜÇK!æüvOˆ³fÍš5kÖ¬/xMÀ¬Y³fÍš5kÖRiÁjßwl×g<ßnx~¾áùzÃõvömYU”¢¼Vñ‹ŠR¦ï}þüWÝ_Z£µÖÒü·9ðÑ0…1ÐZú¶ �6Ìê\B“à^@yh¥Fj·Ô0A þ‡E4€å…;c =2¯Ï Œ ’�[Ö² ¹À‹†œ9Ûa!Å“Üì¤46)¬ÙnS# [Çf‰kÉWÕ¢F¥#0¬G�U¯Cëþ©Z‘'†ýÃØh[pg¤þ/*¦ô¯Â ÅSѾMº.TùöuQ+gÙ�ͼ$Ú “Ú×SôU qV<¡A<A$Æ$eš¢é9câF WªëqµÆ ¨í”ÎUZHbnŽÅgnÕûÀæ™›“ý}ê0fßéX“5~!%\¼ÆÞ8C„cÛÍuIíÁyþ ¹o¶m+*ðñy3)ó‰V¨.1c�[ÖI¡ªØ¶›!2ö}Í‘–èž—¤ÄìÁ ¹<…Ø ‡Ë~�—OxÖ%CèèsR˜g)ŽIÖ@0IÄ Ç{7áœÃz¹`]×ìòÁñ"y�³fÍš5kÖ'©&`Ö¬Y³fÍš5ë )�Ù§·Û ×ë ×çW¸^Ÿ±Ý6ì›�J) Zª¤P§ªU}ñ¹_ø›ß·oû�„�Ù-—¥pµVåU®4*ÿj}hõÕH5; ·vdµvxÝ8`âr;YЈ'* 5» 1€‰Væ¡‚Mnüâ˜+›ÕÿÔXv%®h þŸÁ^)“6©ñÉ(iÉ€­\NN -rA�ðïÀZÿkQÐk|˜×—…Ñ `O‰Ì%kÑV¯PŒ‹µDÀ�šã®ÃÑ›%Íf—vˆÇSm«xߪmCÛÖt PnÁXµ¹î†6@mK›,zm °µ¤è`¸Øöï€95n£Lrs8ÖF7¿>”ë>ƒ�e·¥ÃT@¦Öäš¶“鉼€¡:ÉG=—šy!ÿVuˆ^ŽÉµCAÛ†½5¸FDÇC¸½ÆõIŸhÛõ¤�w˜©UŸ×ÊéÙáá`6×(£]Ç–ú–°p4»ucÆâ˜ª¸§Æ•ö¨~$eç­çªz�O£™òÂCñÚÉñ Ž‘/zÌ8j¹èÄP_s=q�Èdz ¶>ó‹8²ä¯ÝG‚SDK¼xªŸBétü8rÚ<§'Ò¶ã ?´¯G�� Æ »åo}ý7|Óë;¾û{þ} ÷\ì©ßç/6QDYù-!jÛpÛnØ·­„­cQÊ7ÏÏIªØ½@¼Õ¿"�šóË‹²:DPΨïMùöÉbÝ{Ÿ£�¨gšùPVW'°wÉ ÷îù¡�lûpÉ9'íŸ=ÎÞŸ®HxD�„a�ìî³³DlÖ¢lß³š<=7:·ÀqO—%ب§JïãæülÔTjP­z_LÌÂè¼ä0ªl_ Ѧôƒ£9¸V÷·*ÿÒ£Qõ—¾ÀëÐ7ýî±{ŸÉÊ–a¨`.3n!D~ÓwÙûÌ uÚ¸Ô£ŒÍq§~%$ݱ¦¹º˜û{ˆ0HRý-|“HbÑøÜˆ áx�[ƒ²~]òµVÕèJI ÎA¢KL4U:.øð¹nß·8®£ËÁæ°¬Kh;‡à].ÇŒA1‚ÂX[ÖtÌ.Gl¥˜‰uYC?v.·]ÿÙfÖ¬Y³fÍšõ¥^“0kÖ¬Y³fÍšõ†Ôî=nû†ëõϯ^áùÕ·ë ²«×¬#ff"Z@ô¤Š·>ÿ÷ó×hî ´ ®f`Æ’’b$á€g×ð’ÂÌfËy *ý¿µ�[P§?4HìpÕ=6GƒZ;g“9Y™bÕl(jR\9vqYH4øFQÿKYHÔ�ª´;?ØÉ×£´“‘kÊ­·MƒÄñ¿Æëž^¼ü¿þàïÿƒöÓŸýŠßñïùˆðLD¾šÇs¶¹«òÞ“½ú¾íض ûóÍUb^w‘­k@êǾ²hß³ƒNx}Y¹X¡súðn`vñçˆïÞ÷ªsð’-ñ½ßc&º•w´»wœ{P"­=rƒãÎß:3‰Ö*ïêýPű]<°*ÕHtØÃù!¨²Ý‚e½`YV¬K K°["X€ð-+ÜðÔÖª b•ï”íÿÙqV^£™wÅœãÈ¥)=“gÜ9À)D8´«j>–vé=6ê*(ö©¾�ˆ‡ªøìHÈÑõ öÇ9�?�‚E F½_“2LÈÑ”ÔÿÑ…ª u(`z5w$’­žÌç…ÄÔí�ÀdH¤€ÂkÿÓ¹0à>»BNç´8\Â÷뺚¶.„šé±oásß¾çñ“+H(�ßôLÚ+nS(Æ4Ï ñþ@ 80ˆ°#¨¸rÞ 7b\!؈LüÖ¬Y³fÍú„Õ$Ìš5kÖ¬Y³f½!åÅc»Þðü|Åóõ†m»…ÅG&,kPÕÉŠõ²`YW^waæŸÿ­¿ÿµÛ¶ýC@£>NYá[lTçqÉ"ˆ®וV7½!—�Wªu¬Y§¬uþt½™XšÞmHÚ‚|'² y8dÃ+3HœÔoñÍÊ x ¨®¡záSDr6§�FÀ òΫñØÊF…Ÿÿf|jÁôˆÌÐ!Ò´·ÙµÈ [;ø’}»ªµG ÈeKõ ­wT%V…]õ”±ä”@F5¯h¢±MóRÃGàÌ”Y"ÚZÕQË’•[àjÁñQú~|‹]|UèðZ•©¾ì¶v½Úä•#E Œ-2›*ã+ÒT Ä�¾ŠØH‹ÄtϢߌ`¥C»í¡ÝÁè-?²Hodú4ð­°/=sÛ}VmB½€>prÈoÁú>¤Fž‹£’ Õœ¨<‡Ä^iˆ"µj½Wwj·pÐÿGœ¬Öåã¨5µ�l°�|×µ[Žy:½¢bƒí"-øÿ@GQ}¤O¡q82ü)î3õBÏûîxÇ:2&ÁylC=Ž:w~<Ú7}}x|Ô^�;¥U&8¦ü+ŽI_�"zÿ³ŸýŠÿñ�ÿÄû·Uõ}}èUUnü·÷¶¾×¶ï"/ï7ˆÉ5·àxÈCw(·Î"Iýo3ÑaH«±j/sQxf ¼?Ÿ�ËÐÆ©”Løä�÷•ÑëºdÀ1�ã†>fÛÛg$ J'{ò.š ‰'Èïe“=Oµ]|ʧßAP‡ÜV¶o—û±æö^ÝŠËÓ ¼xzÂz¹TÀ9EK÷@²Ð|-B[ÖõRñáÚ¹á@øMó[mY_Ÿ›­âdEµ«‚tÑØw|&¨ÕødH\=«9nñ=95µ‘!ÚÐ1Õª‰QC8’p+‚l|äaT¸Ä6HøÜBT;aظŠîKÂ5ö¦}™â9_{?�Ô¿TÌ“!‘2AÆ´{"·€2Fí˜öìþ·-Œ¹«‘žßE4 8€ø‰ÄÂ.ΉLÀ‘<�ÛksÓ ŽàÔÁÁåhŽpâ‘PÎ.¯sµÛÐ$Ìš5kÖ¬YŸ¨š€Y³fÍš5kÖ¬7¤ŠÊk‹ê)3aY¸hÛ¸`½¬¸<=á鲸խ·,oýƯþÒY¡O@—¼_7_¹ÆŒ³ýµ6ùéáµthS6‘lÝÏÐêÀ²ôÞÑÚTÿ£­ª±’ö^àÅÀœqXTvŽªÅËjñ×(ó38�Uܽ-¿v"dªþ 4Auu†êÙ#³øF�Õm£É/Ï„ Ó1ƒ|5ìÝ)4Ud@j)¶µ–î#ûZÛ0F±ß’9š6($€�Š¸Û‡vQ}�@«Òؼ>åè’U_`h"ѨQ¼Rg^nþ­so�JyÞŒ-'ƒ LéŽ¬Ä L¢ý(‚à¬}Ûï‚Ë3}'‘Jô`k @Ÿcè1õvÛæõ¹èñùбZ[B‚ìÛ · …/㆘¢�Ýr;ÿÙáœÕåªq+F>À£¨SØ×óé#o#rô�Ö3¡Í4�[Ã_=ª.d¾ž­õw²ºV ÇÎy'Ñ�b_î"¸3[€æÌ´ü]›)ÿ  õ±%Þ?Šh�ŸîP�ªále·E½�ÃÇP4H_=G”œíš¶}ýÇz€e�mY~ú›¾ù[ÿÔwÿþu@ßð¬À�'bOÑž¶úg²ä N£k¯€æÉ<‡BѤºKQ=[eÒ@v]À¢äè´2 ÖP§u§¾!òÐ}Ô¿ÆŽõÙ w øöúªõ�W½ßï?$Ž0  Un%èg¸Nk>4¤°YßÃÃÓƒ#yäT*_†²…j`–;Üëh#çT`wEZ⿎´s|Ö#> Ù·–ú@õCv”Þy¤pmÚ¬åÆ îÕwZöCuÝ·ÞzûÿøÃ?ö‡ÿܧ>ý™ßPÕ÷}VÕ­Ü(Ó³+ïÎþT¶}�„P“Cßè–%¨ÿ3Ðèºç:ñ0ŠhKrLï Š|KÀ¾-þóÜoœ†’mxð‹@ø²ç,ôܲFå;àã>sŽºhÞfŠhJçg3Ý“C��7HíS�Ò\ÛÏ3Å}ØFú£²ÜÛö—ð<ÕÙáýnYp¹<áéÅsTØïØn;¼—ìº�€g·C:þÝ—ñ¿Ë0ú }¶Yø'à9U›“¢=üû¾W¤’:æH^2¼WQýQ öåö'ôœPb)±€MLÒK!vÔvúqîR}@)Çîu0~tØž!FI‡¯8¸nV ó ljàà%Îq¦¿±wI… i%�Ër,¾ÜË5ŒÅ@JqØ×Ð�‰af} Žo.’tRìGºÛpŠæ"ãÄÐÝA)ð“ØÁÙÎ»Š©øŸ5kÖ¬Y³>á5 ³fÍš5kÖ¬YoH%ðê§e½À±‡"¨58*¾ÖuÁº^p¹¬nY×õçö§ÿ˜ªüÎVÚ*y+àÚûyq*‰ç²•ú™%°ö™ÚvO£�ôÑfª­Ä…­šc`©o²QóYf€=Y ×ÇÀL Ëb\‘È,*'}„…> æ%ª%P‘&[u²´ `*Çž•Ï À¯ t‰Ô)ïí*¨dà½oÍœ]nUãc¿è(­wQ½<Ûí7ªêêê+ •–¾S´Éacø{9ºsÀiÎy ÁœW´Ævû‘JWÏu¥]¾utˆ*ÍúG¤ª|Ó‹KƒòvÂe(8®áÓHôÛ�AµŠp-jk¢ZõÞ5ë Û½ê8èún:îüû´{è`¾Ðž ò  ÷‹®ƒ£œgŒWБ—yŠ´°d“flÏ-){k�÷Ð>tM0Qª~Y›�úzK0ªËNI=š:Ëw=FIuÜøôÀï÷ç›}ýå‰Ü»ý1œ™Ë�ÎQµGUŠÅrÃÆ¨ˆI£�z/Ã Ý Ó6õîuiç\Ôn#wã(O3 𳇦§sí¸íï�riÓÁœÑ{]ÜåWÜ£'èÉ߈ù|åïüªÿÁ�üøOü{ªú®ˆ¾§¢Ï€Þ,9/Yý´´ä�à0ÌÉ^D°Ý6ìûžóÏÀ˜2ä“AÏ®N!ªæ/SÈ� ºu6ûðïÚ,ªÓƒsÀ^Å ¤ý’Ù‡ýÊ€äðºRs`AÔlßN%³<�¼ÙŸ+ÖøÎu}†ˆ  Òü:vA�¯¶å#!·8PTf/¸¬�Ä â±mÁÆ}ß £¡ÿ9®íº,Xæ û®¸‰Æ¨„=¿¯=ß{jlñÒ½&µ¯f ½§ÛkÔ)èã3-C`ªMšêû7@Ìpp Œ›8�kQH¨Î3�$æúJ¸/TOÆÄ óW,ó�Fg̃]¾½ÕŽÚUU!&ô¬®DÑCÊý0Ÿ‹}cYÃ1qM€qn1mÇÁ�cY°rʲ,¡¿ÅtÎa½8¬— –Å�\ǾˆÎTn鈠!j,�9Q€U¡H"]°]vfÍš5kÖ¬Y_ú5 ³fÍš5kÖ¬Y_àjÕ)©¶mƒÆE£´€©K´þw fж¯+Öuåu]—eY/ï¿÷n¥þ',â$)öˆjDÀjdHô¸l»Z¬�¼�#ðƒ¼zc£Mqqjä$ ÇÑ¿,£ò/ê#4™çªµX�‹{d¢CÕÇйõ¨hÄ[`1�´‘[ûlÍÇIÉè3-ÀBÊqä&ÔÆ �5¿d+Ð ê4è •sJìgs¹ŒÛ{£&§ršëåuäEGjÎ#kìñ•PsþzWlmö™e¥#XBK4û�3h¿ÓÆÎ?�=0_W×ÎŽÏþ()ò:j6�W ½P]5ëΠ8‚9«ùSí|bU‡i~õ҆ġuÔÇÌ>j÷S€ùJ5¤“~[tÜ)Æ7׊˜cª�BxÈwfø§Ðë A‡D=øÕ˜È’+mdÀ½¶ñ aÄôÕ¡+@s}šv®:äûV£ð-ò{Å8•¡�Ï©;w-7F 0=¸NwHwæõ!ñÉ´ß²^þ?ßù=ß÷§¿å[¿ýTõ}ñòJU¯"rSã8T¦j6êûX[’ûÝcß#@|ÞN²_– Hà²+Ï8ö>Ø}�ûj‡Ù�È—g£˜o�ÛöYðè«Ì=ƒ/¦î6[9 ¼/ýM¢¼F‡¦ä8�Ž5½F„E¸ÝƒHÀÀ]U‚j lÛܶ ^v’²›²#Á²¬qPv¿ƒ7Bäiäk»8`YÖõvÉÞ'ÒÀ‰¿%.Á9çÌ.ƒèGŸ#r_1. íg Xñ·}À’Òë„B[z¥ÁµÕ*¾B£‚”ÚÇÆŸ{ˆ£C»lo¯0î[ #™ bÙ�;W3KPùŒ“ˆªœã‘FíQ“ä EE¡ð�Ó…%©X— v Šñ ¡ö��tâ°RˆBpc]×L aGà…°® ˜M,ššç:¢êsBëÔ¦�•?…yÌ(�”AäáTÁÊæ3ÁŒ˜5kÖ¬Y³>I5 ³fÍš5kÖ¬Y_IJ‹bVÁ´,ÎäµR±Õ̹¯nqÌë/}î¾yÛn?Xm³ù®^D3 ¹DUÎz‰²¦¬Žmß=ÊúN¯«¿×æ;ûª² mÉF}Mh”äÝ f3çü£ôÕþè�ݾÝFþ«Õö£¼N çÅ·â¢@¤Pµ¯ŒÙR½ê-ÒK«2xªR{Æõb¾m÷ Ö $Ùö4€,i^øÎÛ±:Ên3™ H™ÉǶڣ>sô4 z9^:öêù¸«¢ôè(FÀ˜VŒìŽI'D½…¾6ѶˆëÆl ü�T0D;ÊŸU¤¾~ÆPã m#࢈µ=èärÍ h<ë™·Ÿljm"cÂl£È´rÉ8D íwYïjæ¶ö�¾vB¿ºßv¦+Ôu²ÖøÖa¾uP ”Cð_�º�´��ˆœü©éô (‡_ êv¯C2ú8ïßòZÛ´Ý�>Ôkie¢u÷Öá´YÝO�ãh89œ@ÿù¥„Úæ»žÓú¨¢óaô@뜼çØ#ãt'z§›ÔM´¿ýΧþÂ�ÿ‘?ö¯¬—åó"ò¾Š^EdŸ²áËùRÿ[»~kÀ 'e}\�‹À©s]Î8€œÙž-ÎE«mˆ(¼OÙîrú|šmâï�êG¥M9ãK�Ç# xŸŸPˆÊëͶÂ3“ÄöÛóþEš¶ýj×× „)»¶ˆŠü}÷Ø· ·Û†mßáw î"Ymžì÷ƒ¿Àûûâ³ÓûTîÉUöèX°m¶Ûfâ\ó8HçÏ/�¦x¾ÞûÜŠ‹ƒtÄ ˜g¨Ðdœû^eWÏ&.JÒ󡧃ÒS›Ö‘0êtK2àòÚäN@”ÿ øt¼ÝdqüL9ž&Äá9=D=4Ħʥ«Ü£Ã¾lŸ#‰}W?«!F ¤mR€‡ßËXÌqÒ�ý½£Eáó¡â‚Uø'’!º`Äy¥":§çx DŽD”Hã$?„ë q>ŹC¦ À¬Y³fÍšõIªI˜5kÖ¬Y³fÍzCÊû° é¸X–’Y â°J~±(°þƯÿÚ Å�½±ÿG“åm¡d²$QgŒgûýüƼѾµŸ Ó(ÔU«#­«Ø›dó¾ê›ú¸²Ú¾rúŽ6¢ùwÇ áp±K­ @ ÒÓ Œ8ÛÓVÿ+­¥VŽžìùóbžÙvì„ÅïFEžìvÕčެ¤kU{Y„µ?X`O+Sês P…X•8‘m†ºaòu”î2׊qœ@ˆZ�‘:² ªÀymœõ°³ü½Á²¶»ºVÚ€¤vÛÇæçJMÓ¸‹áíð;°~O޵‚:ÙæSV¤£�AngPì»zçŠv[qáúKY2 4R¼«=µÀhf-�l›z¢Gž£ �=À(a3Û�Ý$ŽÜ2ȨÄéxª†’¡ hÛ×ô~+&ÇH©ê¿‰æD¹�Ïæ+`EgÇ@÷FúÊÙöí½äìuD\è½�ý£ñç¥:˜cŽÏþlŽH¨žRi/¢Ík•£ºd¶}ÛØêR NûûÙ§!ÓèÀ…ãÑöÖ;šÔÃ(¥Ç˜^öÔ.ìøs_ý»¾îŸþ®ïýþÿ·ª~Þïþ=€žUÕ§üx j�À¬!K>‚ÇÅ  ØÙ‹¹ò{´ ÷û/ÞXć|p·,`®Uâ üJe_öHPö�POêÿù@&ÆÊ¶wxm °‹Ùöˆ–ÿ¹¿šë˜ÉÈD„!ãîàš§>SÍ¥T·²ëÃå2ÌpKˆ{ðä+r�=ït�R¿N.)Á"ÀèCT…‹û6Î=d#<Š X"m0Ǹ*„ Mî_é™.×î!‘|’¢˜Ì ¼“Hhù¸âwfÍš5kÖ¬YoJMÀ¬Y³fÍš5kÖRbl<9©¦j[ÏI ]Dä²mÛËççç´Í|µ@^­$6Ëè­º5èÀiV9]o:ÓtnÝ—ÖÓZ"}è3ÐdÚWÂ÷,¿°d‚C nµng'AÍÛj’@ŽUÏ k€©LŽÐKÛµ1ÁÙÎS*w‚bG^Y*GÀ¶¾dZ½”Z«`Œíõ»Ì{\Ö 0:¶Âî–jµ¸8T U»Ï üh=s£GÊa­þß›¡7 ›±�o3ˆëq`”µi1Ôea�ÇŠ„6ncDY)jãF�™^ÛYÏ[�LûK×"÷°åcì[›d8ÈYÈ{mÝã\FÐ]–%f¢/pnÁ’Õû€÷‚Mw¨îŒ.qtbÊÏ…EYì"^+ÃG_a;ò)ç¾¹Ö*¾Êõø™ o×W€(`A^þ«²g@rÛ÷ –f²„ëAÒÑñt@ª!ÈG‡ f†÷/Aýï½ÏàÿízŶoáØª~­™PO—'ÖeŲ:,‹Ãí¶Á‹À1—;®h¶ü¿mn×+n·nÛ†}÷IÎ_” ¼-m]“2T}Œ-Dˆ äç\Ü X—¸>¤ó!*"h’_[%ÊshiçôÙ%Øü‡çYó\¬¹`qï˜Aû¡@ ^àE Ñ€7N[–æeTïéÞUŸ§Tý…Œ-‘ËßÛ(�#ï"°Ïì@Ø«gÁy`UþªŠ}ßÌ`ptë`ˆ£þÍqü1E@?µºò† 1ÿÀ1åÏlª@“Q>ËÄë¿{ E[!…Ķt.ôâ%öœ5kÖ¬Y³f}rjfÍš5kÖ¬Y³Þ�ò>*2›…£´uíªNEWyñó?÷3TU¿ROÁrôÙõ�’°Ø¶Çÿ�®óSTçŽmýË>GÇ‘§·”~�*¹åªË#„J¦nì¾ÙUVîÀkßš®×dû¾Áé�ر«±YW"•[0«}]84•{cO�.�]{PÕ|'–¨ äi›ó#©æc=þŠ-©Dœ^ñDÊ0„jÝ͛˛®Sq£(íÜCäƒ<…äì`Ýð£ÎßdÇ€(Ŧ{’_Œ·ÔoÔì£Î9/€^΃O×ÈöÿÊŸ[K¿Ñ£Ë[<…:²ó>¾t‡–ç�þøgÎ:G‘§ãn]I´jÔÁŽiÐM´g¥õ`ÓÌFD]¿u@ªøÚŒ£Qƒà¬-€ÖÙ¿?|ô»FÝ�Я£Ëp¤n/Û;»¶w+ޝâfÒÎÇtwüTc@GítOý?&}\¥g‡}¿qú€&о i:ˆ2чŽNµ±TÏÏcx�+‰fjätѪúµý¿Úë×¾^î08î‰-Ñ v«XLôî§>ý™ÿÑïù½?ôQÕ ú�ˆ<Ñ€W¶yl¶%„x öõà˜±,+œ[¢r7(Áoªñý;v£ÞNŠ`Žjèä*Pß"¬ú¯ÔÿÁr?Þ;… �mÔôÊ´—ÚU@|ƒsr×ÉDÄ/£*¶ ´¥÷øQ“N-ðûxÊ™ïîÄ wé-‰4ìøwܶ [Tý'Ë*ŽvÿDœÉÙ²ßqÃÀüŒmÛLÛ‰ÙG°üß¶=“/l4ƒ�ûaƒ9¨Ò“•¿½oXË~Õ Þ‡¬ù|¤?2 ȸPVö‚ ê xRèËç>ø/Tà¿~8Ä")mu„X+õþîÙÖ»ù]ZLl²ßUëLmûÏùq5¯mQ^j7yf»\«î«ýŒ€ÕÊÊß$`Ê^)ª´SÇÊu=8ïÐ^(½ÓZ¤d.WZ|,G‚ŠX ¥ùŽ,¿Oìt›îú„õû×|à@�Û¯R5AŒ.‘-FbЖ‹PÓÉ2Ý:_è)@Xìêi¬À¢hG@ž(Y¸K7†»÷ ›©ÊÊ`_O¡j,é©ýn3.’#@7t©³Õ×;�£‹9±öïÔ€�íÆ©ïÐC�£n^G6´ÓYGÔ Ó_è¡9�Œë0ê-ᫀĚÁô£Ö»Çm2î@–ïMC>šu?vc|7>¼©ÿ±²ùcÝÍáq爺ö{,X4ØžÒCm�HJÄ�;1@ Ló¯v(9Û]ü‰>ÖýðÈÕ‡_þТÙzù�~÷·}Ç÷k¾î~ß÷÷!ò à†üï 8MÀè¹%yˆvb^°,+–u1ç}ƒH xŸ²Öã¬KViÌå^ÿÜd€ ï7_ `^²Ú¹"›²pPJ†�ã ÐLvð5_ƒÿ­z?}ysl©Òû\>&×)ÿÓ>wïst@z/UŠì{Jfàòóµ÷ ï5“6@Œe àÿº¬X–`±.ݼ‡ß%£ƒ[Ëî°órà½� ýЉE|qP Cœ ¬mþ£®¶ýÒµµÑV™^®½«âJ¿ÅX­ùÞ‘ÊöZÇ…³£MΜ]+ÆÓ‘�â3„†KæÔæKð#ÁQ¯ª€ø0âCQ.1V+~Vaª Ý<&¨?û˜g¹ü$Ê1n–À&Æ-í/õÛâ¼@/X×%’\~ÎÒè¶�£2ò¢ÂC aË @=À‹`ß<ö}«cE4—# ¼¤n~Ÿ5kÖ¬Y³>I5 ³fÍš5kÖ¬YoH@X¨’¸p”Ô%ªJļ@õòþ»ŸÿÌî÷?‚‘¢z²[€¤ Fów-‹|j»í{+å\ü©Ê(8°p?‹•'µÛíNv°}È›Ác»šö\)ŠSžmP•U §YHÕV¬È‡•:§¡d�+L §öI •e>åÄqk‡Zi&%F4 ¬Ù[«m¢ /Y„tG‰Í-)äÌΨz“bQ�›(Ù›kVgá@Ãß�b(µ&…òex{¦d¢)cÏÛÈŒô³–ÈŠnh“>¬N®NX �xP”²5˜H�yFvV@ §óO£Ð×vniŽ­vŠ8sÑØöÖà¼Ä3Æë`Žöõh6r£2 é�GR„Ŭn½sÝÒžià`¸u³Ðщ×1  :ò„]‘ú\F˜ ,l§ÔsÏúÓùâÎmàø¾t¼ùŽBS{ ú@ÇÒñ…:MÍyädí8›\ŒÀò³{¾ÞáhËòÒ©ªgŠn?•êhßððˆìÃfÆd•ÇÝ)èúéOæ_þCôú‹âåóÛv{À+¹ië£ÞöM¢h÷A× Õ¿s Üâ KÅ®ÝKÉ莠p°uw vY‰@:4�äS¹÷!ó;}i{nq¸\.X/�„Žƒ‡c¢„¥ÊroÁcfŽÄ4®òÑ�ðœÃ(–ôÉÖ¼4ut!0 ~KÈàÿ¾c»mQÉ\@Ô¢þ/–ë–�‰™L€ |qKG„ö.(Ú�ú®¸¬ ˆ9¸4lž_=ƒˆá½‡s.F¤ø�mßóq…�ß%»)à\9þ ç¬¢/d‹ÚÆþøúw…”3T] BS™£‚•?ð‡®� j"ÌÓ(áD~ic´Žy2îY*Å#;R'ËüÄQôA°Í÷†˜Â¡sÆ÷qõàCö�Zp¸»I|¥h !¨„ƒ²ýlYÊ8 nLhq�èã8Žqü&ð~ÏãÖ¹µôÿ`•� »}§Šoòš Ê% ªð‘ !*�]àøïC¼È.{!ÏØALaµ[V곃[\e¯ŸÔØ ¸5�s•òß’z‚*?€ÿO/žðâé ëeÅÌV®YLC;þd…ߪø‰ïÍY•ŸÈ ªÕ¶í³b9×Zýo ÞïØ¶ ×ë ·Ûµ"´Êÿä>0šßˆrÁ�Â9†K@.;,‹Ë¼sŒËºbY×L$PUl·+> ˜Þ– œs9ûýv»â¶Ý°oå™0“ $]W‡õB`ïªëÓéÖŽŸ›{µ%}h`‰ªF‰Î-:/P#ùÅØ1jÇ£Uÿ[;óllïMñõ.’œ3)€ýšI!mIJ~H È%B »p�Ò35©Þ¾7µ"’pù3NºÇ�55�`pV¨B�uº(ç\È`¾ŸÖuÅÓÓ%G}xï±Uý¦ŸìŒÅwDò�ê€P¬"M")(jÂŒ%yñÑÄC5D‘TϤ„×›ogÍš5kÖ¬Yo|MÀ¬Y³fÍš5kÖRi!w�Ê¡êoËGD̼¸<_Ÿÿ29ã#¹ç!~FIMc �Œê�޵Åc“â¼�:ŒÞ,LÕ"Ó’!?„ Gæi¯ç1ÙGie/'x[¬ã‚XÊMÛdÔJÕûtÐXRí‚èP9Œs0ÎZå)×çb#¨úÛ(ƒ{¹ÐÚ(±ãb©Ú¶hÏ›ìFâîã=¦>“ÿ èÿ¨âýä‚vÑÙC ±Q¿FÅceìnâG}sxUû]5 UÞmî Rî ö÷PbZvœŒ‘°¡«†žý�Ó¥aÿI*oº“uæ¡Q?~ ÚéþVS›[Ò“êÉ��ÿvÒ �ŒÒ^›ø–t ÷LWj—–Ü™:ܳ>\i®Ü-謫˜>z>©êÝq@MÆ  —Æ�)'õ}#€mú4ž;žœµçëÌo¥g‡8ž‡îŸ1 |zðSM²ì8@� ¿ûÇûÚà?ío¿óοö£è'þ—}êSŸwÎ=ÑÕ©^óm÷ûÆ`ö9^Q9Î9$'€ ^±,K”—%*ÿ�¾Ý6Ün7Ü®·`Ñí}´…ªvK´ §j˜²hº××÷A�æ|y®Õì—'<].¸\žpY € “:PŸ]¨�^k£«,øLßDä¿9®”ÿv[ (Ý÷=ƒÿÛ¶׬䖵d‡ƒ F%½˜h­°ÏðžeY°®+¶u…BòëÖu N ëÛÆCD±ïªÏð»À-·ìôàýŽívË.á Ñ£v)`8‡å÷¶¿¯ãÌZ‘1Fm›¯EÉ@D OƲ¾ÿÛø†äò¡�ž9:)¸à|‘ÇÛm…ë‘ÝL_R±_Ò‘ÊpŽÿ‘QËÏ´ˆÝký•ž9Òç-÷=d‚[¼É&ªªOý\«¸‰!ÆRŸ\–—Ë—K „÷n‘¸£™ô“Æ]~ø¥2?‡8‚†™£]Èòç«À¤ÈŸ³ìõü/®  BÔaçÀ.:Œ8žÈgÍš5kÖ¬OPMÀ¬Y³fÍš5kÖRI�•”!jPÞà˜Ýò÷~ãW—ß·ßÿˆúÈZR¬³Û—•í$$J{×q­^58³mÒp­�hmÚà°,Xtºç…Íø¿œh8Íé²4ßâ"ÿöþìç–%»Ä~kEäÞß¹÷²X¬¢Š5°ŠC‘%¶©¦ÚݲÕ6Ð-ô¿ä~2 Øè‡nØ0lÀ`ô‹Ûö‹ =Øí¶Ô�jµ[¤,ŠY,Ž¥y`WÝ{η3#ÖòÊ1‡=|çÜ[·b]|÷|ÃÞ™‘‘‘¹ó7•¼òôQ[‹Ólá¯z­Áh¶rŒõìÅ `¥ŽÔ¤¡$­© Ùú~5ž–W‹]ÿMî}£Š/™Í;ñ {èk¶ãyzôG•¹[‘°n�3gV’e8s�Ø‚~¬Š’<Ûõ¡Ÿó»*¤u&µ¹Ë}oé1Ú Ü Ðìkloù‚ëÊ™âvíGh§lïüpYú†Üm{¿Ÿñq÷Kï^ AÅî¶ï7ÝY±îkìáЕs¨*ôÑ>XÙÅ·¹í18ŒB¹w$´]óŠ GÒ\v#bšý(š(‡ÇZÔ$Ct®^]{kPÆ�h‚«à—©°Zg€%üŸâÅýÆl=æ ¼uéÛ´«ÛÆ®ÇÃ�¯è¯Æt@ÀÚ¹ˆÜ±ÈéíivW1ûï|íßøýʯþåÿÊy÷ @Ï̘]™Y‹ª=2bÈöû"X¹€ë'å¿Í>YÔ9 \°,3.óŒe™Í²¿ølpµ³çªÒ®`o H6«g¾ž2ƒók’ùt:átž0M'øÉwÊö¢Îyã)Ÿ1�øðÃÿã¯üê¿ý}øÑþ¥Hü�¿°‘zŸ-ò˜ ô]VÙô[r¡)¡�óüŸ¼7•mCö aÁóå‚Ëós¶­Vð œ#ªb¶ù×´ß\ÍýœAfMD ï Ð>�Ïx:?át>Á' Ýòë„%ô a ³w'¦r]�±ÞÿìÝÓîE¬‰šík]à[¢`Ç‚yYj5Öÿë�6cžwÀÒ Ì“R·$—ãtPî½÷˜NN“oÔïæ`€oèÔꦰ¥ÿ˜m¼óÐÉù¬ê¯}Z7ö®ãÔ�)ÚHa)D€LÂȶò­ë@'Ö:d5¾äßóî8Ú1RQ®W§…ôoº1Ð&Öƒ1 :3p·Ü¬-ÿEj–}{ZwmÎÄ—r=܉Œ¢Þ1 Þ³Õû”Br°Î55?Мo;ÌAU¨D„ô'ÑXæeîGžS¼„wPµˆ·ã5uç¼ÉC"í} 5+9ê£ÞP]œ�/3�{ƒóy�šà¼ À¨Q£F�õ^Õ Œ5jÔ¨Q£Fý�+?\rÎÙÃWµÜGAठ3;Qç¼›žŸ_ÿt•—�AÚ.£zo_h‚·XWzbOGÞàÖÐf;ºêªì^S¶fþy{¬Úl3ãÓU#«ÃHÀvÚí$_�Gh¢V»æôbÕþáX¶ Õ¾‡«J}ÝtÝæbcŸxQÚÙúý‚š@PÞ·çžÞ£�²ßê(@[A>Ùä‡wԂ͸ÖÌqºoðVýøÈûý¨o³ $5xÊï iÝ1f÷‚GnT÷;VøWQ¸µŒ_÷^O5yå³èÎ1aËÁ>ØpÏèí&s¬Æ×}×޹Ãh“ ðO;$Ý’hôU©UÂãýÿþ+´– uJou&í¼ÿZQ]:š+@XÇsêÊÕ Â"빺žL€ãõùžëÒµwP³Ö¬ícøL¼ôï^EîŠ+‘õo·÷»oV{¥ƒÕ½ìƤ tî4Dë+\{ï±CÎË»;7Aï<Çk9çÿá×¾ñÍÿÉ·ÿìŸÿ»ªúqŒñcf~­â—l+Ÿ-åU´ôà´ýÞ!Ã�­xV²3sRþsÙŽ��Ï——çg\.ψ! &ð–©â­MVGk²ö¶åƒàÒºÙËLæÌ>Áû©íÅ&<Ä´Ç�I§ÉÅÀ»iI§ÌßÿÙU5>Þ Ø·1­"½*Ã]ç4‚Ë<ãòl¶ÿamýß¼¯U—ïÞ÷uàx&Äò¶®[ë\{ôD@°÷eKõäÚe_Áö¡ ônâ€qPÉ Ü(Ú{Ëýöß=ÛyR“©íÛ÷µn ëëúš`±wÍ_“¨‰QÈD€¼}Nä�¢ÈOS£7Ü÷'“ͧ¨¡»ÿ,êÿ(Ð(Ey_ç4꜡ê•o¤-Vüë5ŽÓaÏ÷ŒvÖ½>­öE}§¨¤˜(‹ãÈ e\&•Xß„ØØü7kæú:N®FÒ+äªÔgÒ8qh�+£�±ìoŸÈ"0ØÖs)q¥ £F�5jÔ¨÷§`Ô¨Q£F�5êsRÎÕ²–Kཇˆ°ªºþOþñ—çeùK`“J¡7ì~«ß·®Àñ"o+ƒ@­ ú:³º¨h¨ÉÖDóÀ?�ñÒØ¿gûPl3NË[qÒï¨ÿ×¾ù;„ƒõaÙßd³£ þoDÔç•îamtYï/ÃXˆ�¥¿–}7kÚØvˆÒÊ=aÇU ?VJÖÿöÄ�t ž7Dˆüšf„•b�®e@£’+öØh¦ÌÁ¨êYt. 7m¥7íÙ·HßXðê>ˆÙ�=ùœÒæ¼¼†Âi§P.Ý�šo]úNS¦cN+9¸½h_A¸¯Ï Ø·Ÿosww–(¬+öIÔ†76°Íª'½ƒT€Ã8ûþ•G€çM;uíÿm€Ï{¬Ø;¾ÕfneBÏÚV¿óÙoðf­<ñ•뿨tgMZG…mGé3ôE º•ñ€Ïü�¢wÖ‰{?<0yi;e÷¶rÿ߸ü\u ØxûãŠ3¯=›WîÎáùƒ?úßþê¿õßù_»iú~ áÀ³ª>3óÒÆ0‘©¸[•²Ä ˜ºÛE]DGΑ‘¤j¿àry¶ìøNoû)|MJ}mlÎ52ˆÞ‚ǦfÏ„Z¹Ì‹Yë/ ü¯êú þûD"âîq¶@|%/÷ @‰èЃøµmf©¿Ì‹µožÈÊTÁäb_žˆ[‹ûz½i\|RÎË‚fïc(íÉÖîjËt«ãC„ËïI¥ô·�O"P•þgŽà™Ad® ÎÌïøp>­­ô×÷¶œÎ3v\œ¶ó�nÎÕ½ûŸÖ-àpn÷‚|‰§¾½éwLœÆÍ�±!ŸåþS©yõ;"Ú”ÑZõÇrn4óíqÓÝ73Ñ.u0)Á�;¯´îÁ¢32I¸ö §f&§�mDe²P& yù+וÞà ·G»{.kÎ:®¡Ý ‘9^ØùãÍĹò¹lÔ¨Q£F�õ~Ô Œ5jÔ¨Q£F}NÊqÿÀ´Í„ª0ýÉÿá¯h{·õµß—Íí8hßõzÇ ¸<üZƒ¢‰PPÖ)j¾+@ÝÉ­œ¼Ø+Üáz¤N¦�KÁ5íer­6'ÙÎØèšŽaMT¨  ãîÚÙ©ù×ÕÝ�W ¥=ð…Ö€ tÀ0e µdû¼{]ÙÍö@¡6LƒÆÊ¼U78ÞË}žV*ÒÛ�7¤�­©ÞÊ…X�ý|¹á8gt5?Ú—6¹ë Ý8„nžìîÚÆJTúr=øÛ`ŽØ.ع¬‘»™g»û+ÏÂoæ�ky@;ç“�í)ðæwî9]çè~ºüž”ºØáÖ߯Ì:€´nÝJ\(”©‡±ÞýyØâšwoR¯öÚñä;dx¡ºTܳó†ôóøl¿óÐZ‡›ŽW-]ðVŒ…õ°Ñ‹çîzàÿÝ¡&ëcê\xôŽ6Ò¡Ët èßóúÕDÝ´VW. —q—4µ™<ÔoÑyÿë_ÿú7ÿÇ?÷‹¿ô›ã'ËÖ9¹8äöªJ!XLƒ9’…Æ2^ª±™sZÈæ^Pµè™P�Ç©u@È}!ï_C¸Æ”±çm$B¹'lïW÷ˆ)ïI“]µÆP ®ßœa€Vs³Ü/ÕõAûþŽ€ÛœôœÈy~#ÝêĨˆ‹¹/Ä6¾bç¿f"ÖahÇI´Õ‘â Ø2À8µTlL4Ú¿1FHÄDÈñ« �€ÌY#J‰0ðß�ȃy‘«ëE·¾4Ne.ëÖ¹môˆ³¹°9š×à4fy<2¡%.Œ5jÔ¨Q£ÞŸ€Q£F�5jÔ¨ÏIµÊÊyIUYU'U==?¿ù5 ssfæV^}? ±±¬®©f•ª»ÖÿgV <,,�Þ¨É oQº&«Ú°5mïÔøØ‚¯‡Ç˜W*þõëµËÐnR¯×é±!íì¾€‡ÍVi�—�ŸôÕyͬîÈ´Pz¯ë>{è·:ž þkº©Ð*¡Ñ�º¾©Ê§è­©Sac¶Ϲ¤íp9Ý€�º–^¯±¡]҇⶟þÁä×¾£:Y÷ÔÑW¢26}rýwÚ�_ÿ:]�Ÿm¶k�_Û€NþÞµ‘®w­UæØœ/«Óì~ðšP@5AW{ÚñFß[«ÊìÙ8HPÿš|”ó-½ønÝD�:&´ÄšÝù¸"±4@úMÒÅî<¦Ã5¼Kv!4œœGé×ûb÷ºÒ™ÛùB8r¾¸>ºÛ7»ËÃGyè÷ñîDþW®Áï ôµBoÌ=º{t7ݰÕúh¹ãûî Õm@i÷–’EDøÑþÃ_þ‹é?fâïÏ—ËÇ¢ò&Ƹ¨jT­NL!„% „1L8]lþÉn[Öv³Ý#„d[/"KÀ²Ì˜ça™%$5¹Ý7µ6öíþ´sP"ØKú\÷|z4·Ý=‰¹K-ÅQ ƈ%„r¼íý¨ó¦ü/öÿ‰PbeqŽ‹@:°’À„jήicÿçþ'ÛÿbŸ”ËÕºÜw¤m~¨½Žg >õC‡çççD‚ˆÉÀûL6P¨žàÜTúÆ9çï=D"¼÷X–¥·‡Nà¾K(yõWìœ#—1Ü#Íé)Ò}¥l#ˆöÝ^Êû¥wÈã_ïçÛ3N°çÓÑÚ‡”å‹¢õ¿‰ äk}mƒª@4B`N5f ’K,§Þuñ!9bd‚ˆ®2¼hsý �Z’_Õ@sÍ ½[�_šb0’¬ÿ¥#ðWW ¨E(‰!x$}V`䘑ª¼§r½±¨…5‰8�·}µçx=Óœs Š9b. frLs?[9í:2£F�5jÔûTƒ0jÔ¨Q£F�õ×‘ŠŠröc}øKrÌìˆèüúãüø²,ykûßæI6(Åð»Ã 8ËíJ[Ó>¤æa®�˜û$ékòÐ&§ºÿy˜l½Þ·vù´GʃµŒR{ ;–áèÖöÊ:SWÅ”•ÉÒî¥i×JEØÅ¢ïdèv}†ÞJý(ÔÀŽ£ZÓAH{AÅZ{ƒßíD¹S7óèÐ�~w¦­¢ô:4³× FQ9Îë™ã»ç_Ù–^QжíÜ›ÚP3°šë1^»Rœ‡+ÔS‘æ¥ä5„FsK•p£¤û//órgàÚœîA«º¼;Ûþw°±ði�"zOŸ?À�û®õ/nçõ0„ AðÖŽõÖžéöÔÔ&SCKÒH©i:ý§_ÿæÏüÏ~ò+_ý£ãÇñÏ"zi­¼UˆðâàýŒy™àýÒÝ¿e Qº,{×]Ï[•r ÜÇ�Ôÿ)Ï>Ę€jª¶öŽ;îö%ƒ|�žî$Åo€H{_ÔÊQ¤dÇÇ‹í¿ˆ4êz·Õ[Wªâ�Úc®Xÿçöçׯ¦�‰hçÞ­ªšC˜—˼`Y–âzÀ0­`pÿ�óÝ\ë˜Í¼”§CDˆKŠ?˜q¹Øxd@¾g³nUL“&P×54 Ñ�Y:׿dñO€c³·ùÑ€«6�Dªòz­ö/ ó†@Q@ÿ(ÝÏëÏyÜv£°VÛjï?¹q$hûÒçý}µóŠvÖ‹â]¤TÜsÅèæUšëDNVö\Æ»º<´Ç¦bÖú• ݯ�嚘Ék‰]ó£IGì½QÄÆ ¬!._9õ‹"û¼¦0*�h=˜«¥¾©ê]ãØ!ÔóØú7Þ3ð_•a\!øcré�ÆÙÀ¢+´qëè# üÏç¡õQ‰L@�–ZŸÏ" †®>`�5jÔ¨Q£~ÔkF�5jÔ¨Q£>'•lN“)�T„Ø9çŸÙ¹§?þÃ?ø+ªzÞ`U¢¿Þâ.ȤÞ"òºÿÜgõõPCº«Êî•÷8/)Õ̓àõÃÆÖ T¯qªÕfs§y; ꣈�ìÆ`íôŠº®ï@÷iŠ�HêÇ+ƒþ¤;®æë­u|ƒ:XkäÆVµQó÷Ä�u¾@�MÕùxÏð¾ªÊ¶˜ aW¿ÿW®Åý¡{×»ËÚÖU[:K7-tcOyŽ¥ïw”øØq2X)Ú÷ü ½–°Âu÷|ÌD€LÞÙœ.Wb?6œœüû²îͳvÝ8ý×�¢�ªŸÖ Ôk¹õ8Z¥ÐÙ’wª~j8+¶ ÑÁ‚XçFK«©7.[Ç=x4¶ä ]�gZi5›™¾Ž¸>û“☦pý,Ó£9ö–uıhÇã‘=éµ�Þ1¯nû�Béñòs{PèÎþjºÍËoO˜Í•¥]b™ÿø _øâÿôÛî—ÿ3"¼&àYU/.æ lçu+ÂTéaY°x�ù2Ã;‘Øá™�ïÝ ”—î~n & /&År—ãN¢g஽ÒŸÔÄU¥n=r³™� ¨­k©Y� D|ù× ~¶·ÏkÁüöÂÈÛcÏ_®´½*ÿ£Õµ¤�+2øÂÒgÉçýõ¿OăDžmAaíݪ¤Ü—j7†aY c Kg1a^êñ™U»C&[Ùï5¶Síïä˜Ðº#XÛ¨º7¥yoíUàŸYJ¿˜ÂÝ*ÚåÎçqسño )tåþº%î9Y´ïÙ(ýóoÅ”ô’“¨h‡Øš€¥JÑtLA’‚_j¼EiG;�7º"•æ�Å…‡Ð¹Yéæú™ŽEÚø†¾OʲTtJ9wWÀDðé3œŸ¦bÃO�SX�a#!ÀH*(1vl±sÚè\vÎ%.öý\mý9E�´1åæÚÌÎ$(†v1ÝÛÀ¨Q£F�õ>Õ Œ5jÔ¨Q£F}NÊ9ïèL Pç¥'t¦xkÞ›ÕL-¸@µ½-d…µúº±øÔœ©^`¢kßö§C]}R÷7Ùôš³¥[y<õ.wDl:2�%²ÁVRü݈M )ÐC«ú>K¾-Ú¶êëÜíë±.Vu \ï"EÛLà=òÉÍÇ�kçðÜþ6ìG�Ò©ÿ×Äm�-ÙÈ7‘ôB~=>ﺯü7Û­÷9.´c ­£áèdÞ%ó`ãë(�= YwV†�ŽÂÑ;ª�^­w½‰EXõyû²&较Tû½Ÿw%‡¤þ½]guo úŸöæàæÈÚó™î›õ{¯ÒuÆH;Û¥öš@×çù[�ýô®µ÷t°ÒãATþȵæà4¿ö‡Ã„�O ˆ¡ëÐüî¾uçö€^ÐZÚ.�uVµfþÑ]Ûm]/èòôôêÿð þWþ—|ðê_xàÕ @4ËUë]gi/bä!Ìó0�¦nw�m ¾åægi·@+“Y­›å¾ï@÷ ˆ·ï«`´]” hÄXÁ|´J{2Uqµ�]»2¨Ø)Øoòâ; Z{sQ<{W^Ÿ !¦löPÇ—SÌ‚¨Â5דG°„Í~˜íx©XœûQÀì à-’½� �µUE É:>Ɖ¡�-"c²x·½×.ÞÀuN (Nª~¦ç¶i"hH·TŠ4ÃÜï92"“4Ö€ð~<Ã9í¢$Ö%Ú*Ȳ‚Û¾ÇÆJŠí|ΔɖõùwÄ´�ÀZŸÏíAh"ˆ,Áœ$J· ¬É%¾™ÿå‹Í�ñ’æ~ÛTô•½ �ýKáÞüÙ’ËXÃo­}„]{ð­Ëu¾{:¥]æéü7¾þÍŸùŸëg¿ýÛªú¨~’TÿË05ÛpYùU¡Bè€ø¬òï-úûˆŸöo-€';nS4g»ób£ïu~,ÛÐX‹»•A«‚¹9Æ|¿µ>¾½è¡œ?¿&/´6áí¶;pÖÕìúüº(!Ä’{®Mü '�RW9ö±Ý+[Õ×ÎqçN�÷]÷›Úc‰h`p“~¢åz/* ØŽàîçäZiÍ%¢Ëq�xÈD?*F¶ ƒPÁ|³r�@!+W„¢ü^VsS!,åõå}ÒÛÂwãèÌvÞ{ß�Yž3 xÜÝ)g"JCÕ»O~-„Ý]Žjk#VÜ*#„n޵ó¾ú[G…J ©Ÿ¡²»Fo™_É”H$¬ý�†4}šç�m?E DAµé×dýßÌ ";LÓ §§3üt‚óv. bGo"¦´ø|;nû€tcƒ{ÌAìÎDËGœM¼JùxB5E¯Ü´ˆh%À„æxHZ5jÔ¨Q£FýèÖ Œ5jÔ¨Q£F}Æ¥W¨13¦i‚zDDž™Oÿä{üKªò�² \ƒ¤zЉˆ…ï~ŽøU¥.QgáŸUü•hÐÃøÓÞ—¬ûÚl¹N­@ûÀUWvÜÉ[ …lÓP~8v§ï ««‚Âú ]4ÛòScƒOûc»ƒaÖ’McÚ6f0ç��zÝ:4tãx/Ý/²R°>(Ïsçžy½×Ž›;”J6ê=m¦;·.G“}g‚\Ë´×În.9 Ç‰ÿÛqÇŽ²ž*é¥Ú­Åî5[ÿŽdÐÍQm -h}V\…�÷'úuàþ>8ñvê]ŸíƒÇ78@«cËkÍ-£«‰è;}Ð-i›ƒÐ›óH»ƒ<ŽÆÐ�#ûþ:¯ýºx ü×fËt0¯®®À÷õ]_ÅÑ’ªîÛï"Øýgì;¸¸òû· Üœ27°ôžö /í¢‡z/¯�ºš¤ÔÜ+Ü¿ÚìÜ~éË_ùþÒ¿ýßýOUäQùDU_‹È³¬ÂÕ[�{ ª–¿'`WD0Ï—Cµuþ¾þ^ø¢¨nÿÆŽÁb`ⳊÞûÉÀÍœI.Œ–Fiïá§ž�‰ @Î'rÎüÎÛÞ‹X[ˆgÛþ=…ylò6K›¼©ñ]ë\�¬í%ÔÌõiÅÖ*û+–ôÚχ|Ò¸ °sM|>l)Na  ßsö¤ƒ‚a:[rCŸën®¹]yîf0Z¢BvQDb œzs.�Ho½cØä´k?¡Ðä.ŽD¢f^+”«¾D?Dé”äk5ùö>¾ªÿÛûiÚa²Id]Ô�Úšs-&ZBH$ IDÓävqåóRvWðÞŽ90ÉKŽ ±¨ùcÔ/ÖªQ²L¿+Žù˜ÒZÅÎašž0M'ø“�ËÅn¿/°‰4ÓÌ'nH ’ÜòP•ùu¥¨ãhäŽ~�­Šì ‚2§8ÐBÐ�Œ5jÔ¨QïU�Kû¨Q£F�5jÔç¤v¬:™ˆ3Ÿ¾ÿý?ýw·ï¨J÷˜)úÕž8¦Ÿ2dBÛ´ò*ˆ-ÛÛíVUOû`žöòyUw�ˆÖÆ—Ö‘Úƒ«ET2\÷@´VáÞAù‰ìŽ¥yŽ[?²Ïׇƒö÷}޵©ìE×Ùä+À‰š‡ìZ“Í»gà­2X©¯íp×þ(*YíRÍSÎj~h®7ÄÁ­…¿&W‰Ûsu­ÆLç¿~ï΄i_ÙL¨# Seؾ²Ûõk;l}e黫r¾™eýè©?øÝ6¡� {àÿ 4ÓÄÈYó„ RôÏ�+ˆLvæ÷�ÿ¹•+ŸÝÚ¼}¶ì1ïD…GCÝ›eWb¨?_¯�.þ¤‡ëKy¡Çó}óã-±?m–õUd A»íÀÍÚ\”z%öºoî&¼M]ïK{væÀº¿èh#ÛÁ¿¦’Ç=›ÁÕÍ_�HïÜ à–�þ×Úöícxp^®××{ãHú}~üá‡ýoþ­¿üWþ÷¯>üè&~çfþãLD±á`w­t�ɾVóß2ÛYà3orÓM¡ljZ‰ÒÛ•§¿«ºÄšŠ=�èIÍ®¬ ©Vðàpš¦r¯¸§PÚԃ؜_g‰·¿ÏÀp V'«þv_y[OVüÄT®Çy;RH @%·GËYµgþ§ÓoÝ�k‡ˆ $Ëü�å¹�Y5®D l�¥myÆe59%<;ïœ7’ƒŸ|ŠàfnhêŸÖሉ—Lð3Yà� ª2Ææ [‡ªBI7sBD@B}´@”͘`�¦a¢ÞÓ¯mø×÷bíg©Ÿ rl†ÆB�$©Ü5Ÿ£ÛýKˆ“rÎÔ( ‘3Û˜AK´–ä{ðÖM 9  üÎ�TAIiß‘S2™Z\46ýGŒÉO8?�1MOp<�ˆ!@ŠPˆØ_ø2ŽbîZ%&+€Í­þ³”ñ{Ú5ÅmHjY'6&‰¼Ý®ÙY#»É•‘8\F�5jÔ¨÷©`Ô¨Q£F�5êsTíCi"b"òìxz¾\þr÷Â5.¾±ô§. Xö¯¬Û @”-í¹*>·�ñ›¿­•Š+‘P²§LLZ ·½\éVý¥kV;"^!Ú`;Ôí»¾�€+2¤»U}•·jí’®¯ŠÉ€výj`»öfW�Úª¨ZÀcõ½vàÝvƒ„=»òÜ^êb‘»˜nÚÊš«Ò½ßZÿ«f úYÔª—w§áãààž2ÏÀË;$Ù[œøhM×ÝûГj,ÂÑ–¯úÑßÞúú½]~ñ®³CrÇH�N�s…ÞpÔßmŠëýÛ¼Au«¥¯Mû´@á½¹Û¸WÀ&½¦)Ùïa£¾m\boIŽÎ¶+#šUã; yJë+1%µ:ƒY: ¸¶¡¹WH×CI‘q±ã !¤û‚&Wbƒ¡0PU)jÉÚÄb±ì¦Éã4�0�¨{:•ˆ…«…}X¢�Ę}ÊsפèNý"½K€7c ›¹ÔŽqSAºÖ�!GâGOnÉŽLh)@9°�ON!9† X¿j"r´J¿1¥yb�"G ˜ý=«BÁȺwiÇmå`Q�ýä^A¼ryˆˆ¡wÛÐwÁÝg v5áä�;˜�°ÂÎú @ú¾:y©ÄâDÖ’d¢$˜@”àˆÁÞcJóä”H:1Sjµobû¥’+lm‰�sOû9ª'ç�¬w#9&ÜÐê:õØ€Ð#'Ë[ 4Ýø½¾Õ²õ€]ĵMžWt?þOW7ÞÞÉÔ–zNßÞ,ïÿþŸùÊOý‡ÿƯüê~™çOBŒ¯Eô “Α9ÄÀÁÔývP§†n«UgÀ”Ù5�IÝžÁÔ…¨ä—·ÙéD} PuX 7Võkûý¬x¯ç¯µ©µhÏvûíýÀž=üЭ¹õ=9¡í‡öý!„®¥�İì�ƒ÷Ì>]C¸É@Æ|Y%×Ü¿© ßyv1JØMéžfMôª_mœ�å¥GH ¦&OŠënMlî3%fkt»J9rP—sܽ©ýO'œÎO8�Ï8M¼÷‰Ôa ú²¤¸�€à ê@¢Ý5l}ß[µë†h±žy~”y'–Žи>˜óƒkÆ<»;„^KŒe.T·ûâØLßÇMp™êÙ ÀåøuˆJæøÕX÷«¢èƘ¥ÚÑ7.…dÒòù¤ªgíaçÀ FD°$G†¶_r„„¹nɃ3™¦!ÑEsȉ@L@z¬–ü!ÆBìÉýw:M8Ÿ'øÉÃy›ßõ>[T‹Û×191¨HC¬MŸƒšµ«:c¬VTCu£ÈN À9‘‡ä¨„< œ\гF�5jÔ¨QïM À¨Q£F�5jÔç¤êƒÙ˜¨9""÷ßüé¿þw6¹×&]ªê¨unªýÓW뫯TnµkEA‚ëä‚6V }áÖâ×*ñÊ5@¯¹q7¯í­Ô{õõ:SÜp:=D£U·ˆ~«”Õ«ñTHk5­a® ô— RxZÁÚkÊöbŒä‚°i(vîX­hz”ê®ûi «í`•,�ƒáÃîœÙñ‚Þ9¦ëiëz¨> Çýíž‹²|#ºC]¼jÌ®O…>FÞ#?·ægmÁYÍc¿žKÛöèa‹¶@t:vûàîãº1TzëEÙæ~ãp}W{óÕÜ)q+zÇ\Ò»ÎÚZ¼Þ×—wd*í‡8Ö Ãvm*oØ'o­ÖÃþ�ÔñÉhíúr0—öAd½ož¼x¢ÑýÝ|혯ž÷íâeëÙÛ¡6zÇ1ݵî]=ßW11Ø®�Gêïýï}éË_þ�þ{ÿÞ_ýkÏÏ—çËåò,ª™EuVÕÈ‘ ØI‘ªªWúó;&¯¨ª½`R…÷öx¬®¾©ùwι’/¿tiEÞË [¡S=o²×§©³m_ÿk¯K`nÊ/ùé��{¾lIĦ€n£˜K@/¥o:r´fˆ*È9L„¤þvpŽ“óÀBp D°�ï´RŒ'ðo0”ê4Û4†ÍÝJLàwl,ôÍf=&÷¨~54¶‚TÊD¯c@ĶçÓä1�àdÖÿ­K„HLàÿó¼ „ˆ6†Ç9mñymÍq¶¿þúB»÷6xEÖˆMŒƒt¯uɆÞyWÀUMqÕ±`Yæ2wòó©ÿbŒ�s:ç;?Ê^»û¢lÝÏ`(k¾…1¨$óQ“ŸÈH-q%Kž«-¸oÿΈ‘­­ÎP<“ BX:r3Á›õ¿³>uÉ-!“N$µ•ÄôY";@kßE %® G.8ïq:�Í)‚]釽uQÐh犈E T@%XprVÈQ¶¯tfJ`~ó‰K•˜" ´ÿåF ;DX��SL:�‰9ãsø¨Q£F�õ>Ö Œ5jÔ¨Q£F}ŽªU†Àž®¹Ëó›_iœ·Xÿ:?h,Cë¯:’€ê _=õÉxqRÉÛ?‚c|Ü2íûôøª†c¢£ç½ý1¤ŒMZÉø €®ÎîSè{œ<Ùu—cÞöÒžsõqL¼oî¤ ì+LõT¶Ùd]wƒÍ¶Ê‹QÕût”s]=ÛÚñg°�nO¾ý­íÄgïíz ÔnæÙ5±´î¨{_&¸¿5Œ‡d=œw‚ÿGYðwŽ(ÝxÕõ6Öy¯´îÈ+ۿÖýÑ ñ£¸u:š¯/.±†ü˜!¡z‡ÃA#Á7"�u,½ ׉�|ó¯rØî@%‘6ñë¼¶¿­ÏɆ˜µŠ°ÈàOºÒ��É"t{êÔÿÚ؆:°µ#FÐ=´#ºk½¼þºï¼~`O/Ñá?™ru¹oïw�ÿ´ê¦ûÂQÂz+kpÎýÉ�ñ'þWõ×þ‡ÿïüÇ˲<ƒh°Àpº¨ªI!B(Àa&9öêûØ�§Ì ^r:7À»¯RÁ&#¸% ÆÐ)î×à,C–sžòÂ+8oÇ™�ÚµS�K®ëíÖüùŔȡÿ³{Ìþ’Sï}]‹J;Ù„0usŽ*P1Õ2ªK3!NzÊ?�²Ë{·†´Ž$í i{³(›×5\ÏîÞ‚š¯!Ñ�8¢Y]˜Ä.m»%”c®ŽëÉmÀ@Wï<ûŸ0Áû<þ®Xè‡0_fÌó‚eY I n���CõÞO]—·×£=B w ¸Íaîæq=O,îa:M%–¡�t($”4ÿBˆ ¥ªÑ]K(óº^c­]šŽÅ±MtÈqe˜±IýÎ(IФg#Ëm¢˜+ Ï÷|<õ˜k[šb8”8À��/–ÿ…“�1ŰÖèƒcš&PŽó‹M‘2¶Ùú¿,€åsMzMéC-Çî}r Éd‹t]]ö iÎ ‹/QT‡Y4qZïíz¡%‚�5jÔ¨Q£Þ�€Q£F�5jÔ¨ÏI­ôÀÍËòË@뀺óÚ«;8‰¶ Ö&ñùeÉ •ÚóºU½S~-5 RÛq ÜorLí;eº©ÖÞ}Ø­‡c´ùÕZëPq8Æ·œ¼�ì¯�N1}y·ÞÙe›&­úO©9®wç÷ÚYä7Çq+5as:Ñ»k–Þág{ä°¿çÓÎù»·�›É´ŸoÞ:’ôc½·6P��mBÖÔÛ�Ð^p;nCoLd-ÍÔ«s¥ûÝ -ö×kèµeã˜>ðö^"\ñßÍ9¨ÛkÌ#M×{ûùõ¿Þñ—#JÔ:Ú‡Ù}ï‹?ñÿ»ÿßÿµÿó«?üoòZ$¾!¢™@�ˆ4ƒ”PZaj[»õÎv;ö$€ Â;ïŠ @ FªS8ñ8&€Tµ·ç7Ëò ›9$U²¥�›ó€têäòþŠ*_DŠZ·E«óü/íå”»¾�ó:¸G&è-Æcym,ÖúÙiÀÞ¯“¹ LK@“ PbSw«"F DA RrÈ»ù.v¿‘RÕ NÃ(+\4s8µa‹ìEäm³cxõé>“ P»��Ú‘èÊýi"xP&¤>·~P¨F,KÀe^0Ï3æyF Q¢ù°O}Ì`ÖÕõ‡Ê1­�Öu$D;6¹MÅ*_3XÒkk<„Ï.EU¿˜cBž\³ã»lû(ˆQ(tó‡Ð|Ï(Î  š«‚ÂJ=—„WQöÅIAßÏs×�O­ú?ÏÏ–øP" Tª»FŠ~ðÞ5mOÛ_‘uhõù‹°uóP¬çʺ᧠çóžÎ'øÉ¥¤­ÞÞ_D ëyÛœe}ÕêX`.>Üíû5×0iHvR¤{Câ²mûÐáKÌ•dc p—Q£F�5jÔûSƒ0jÔ¨Q£F�õ9©üÐ+YÎ:fv¿÷�ßùyUý€¢‚Ò�îŸ6¹š„>�v# oÔ&UäJ�þ¼æAJù™*¢Óîl£ ¦FŠJG…F ¿§RM!Ðä0`Ò¢nÍhœ& {c³žþ¥Æ”x�5°­º‰.hÿQ]·­þOk÷¥>ªJþ­sÃ:㕌TБzƒäkŠÒîá¶vÞ Å�`»@»„ˆÖ³½ö~þÓµ‡Ž7«ëÛ·°ØÅ*’ —noW÷r©»Ž×›ù¨ïâÑéšøÒtåfníÙe�MÉ´Ï§Ä ÝôZg yµDܪ‘îöÄ gßµ7ëΪ�õ.kƒµƒÄ:ÚåÊÀ5ëÎQ�ÕUdwþ«ÒÎù@e%ª^Ý8ŒüxäÔ/ë<=0Ç^ˆ…g¢5ã®ìH7­ý8é;:¹¯S?î|ï BÅ;ïsºMÀ�}ëzM¦æžpÎÿÃÿâOüŸþÊ¿ûïý?¾ð…ûxòÓ' z£À³ ^ÞØ­~œî7²mvQ¼æ\ò•@±ÏàaC[kþlï5vï©_1Ý·¹zxçºÜõyY К#Žý1Æ’E¾,K—�^¿*œ÷!“*Ÿ;›ï§â\�ÛŸÕÓ-ØœcL=]-çóñÚ~´´?o 3¦0!8—î¥1†d�RLB3Jà%@Ùb“òñ@Rq‡ dªT…rwT…FXSþ<̈/ðnJý“¶…d³.f}žò\ª=ÔÜÒx:ç ¡CT!1 †€yYpy¾`žg„eAˆ¡p-Ñòã•6Q2Ìͽ'µÄUiŽK7ßWEG¯r^4€½»ní<.®ÑÔôD îI¡Ôº@ :æ0µ—<0b³ýTÏsÚ9†wçóç§3¦éï<ˆ€,J!,1,…@#ÚÜaRå­­Ü´Å9#"©ÃÃ1§Ï2‰(’9ªá„EH´×ÄÆ‚@åý¶?‹L@^Ä™›CYç þ5jÔ¨Q£Þ¯€Q£F�5jÔ¨ÏIe›Qç9ï¼cöú¯þå¯Hê©9îùI­tŸE Œü¶ögU¸®€âîZ³ç;Ûúà§"PæäÐ&÷ê¾_|.ÕL«´`øJŸUÀÝ ÞçWH²‚%]‘ Ò·9º@Ñ*«jó)Ç •‡Ð¨]¸ßÐ 4?8N–à¤GÊËô`²ÉmØ5*o¢ 6³VÈæ±¡u«àŸByÇð%ÐM@¨R.º¶Þ È%£ïÜ“[¯G!ªëý]­Þ]eÞ¬ˆÖ£Ç:æêNï߯®)•¯½ì¡í'?>:íû�êDÜ·¥ÀË­Ïw�ß#&÷Ì:œÙòG¬Š;R.ê®he‰ß¶Aq�2z¯Õ-\¬Í:¢% dE!m@ªÕ9O�œ-QtÅ €®Ýá–pï)·™Ëz›¼°7É©ý‡v£ l˜áG“ý¾¹¼Û|½>_Þ¶èʀܻŒu—æº`qÎÿõûÂþãÿÖ¯ü¥ÿâÃ�>ºœÏ§À„™,Pˆ¶Òðò³púž‹}8ñãG­¢П¿_æË2ã2Ϙ/s±#¯™ö€cÆét†÷¾€®Î]1†b§Ÿ— !}æÜpÙÂ0m"ZÐw­äO$Ò€»í¶îvö{'a©$€(±�sŸÄ—ˆÅÅâîCÄ2,KH9ì-ˆ�Ý ÀùnƒÀ.·)g¸7ùè’Áþ~6«a!çÌùƒÁÄð `"ÄIÅ€ÑX¾¢eÑ#€$–5"ß·ÖÜõÚÏ¢ J ò¼\žÍú?,!Z|��€-| !LÔqr…dh:FéTÛ­cE÷�¹83Ôñ�ƪ^wÉ“žº¨ "/cʵ�¡Q×çûÌFyN.›’!�«vÄ�–ÜBÔ!Zß>¥^×”S/iÍ%‚°À9W] Ê¥´'Bh¿UÈÑ"æ  G•ÄÃdQP òsv  úg· é¢1¤Ûn&oxçq:Ÿp~zÂùt‚Ÿ|!AÄ(X‚‚9u䱕ú~ûHÀöÕ\·ì3àTÀŸúBsT@"´ÚpvÓ9)19U4±cBåó’–Ïj>E³™ý†�B<>„�5jÔ¨Qïi À¨Q£F�5jÔ礲’Œ3y"òoÞ¼þUS{ ÿS¨‚IÕÞ¹yk�¬UÀ½•¼×ýJVÞ—œû#¥)(»YÈÂ&µšwváWæÕÒ·¾!+h�[²“Oݪ�òƒ½NM§ºê†öF°¥M¿ßRæëèÊÊúNm«;c³PZGvÚ©6TYÑIÞ¯e¡¯@÷Õý)«Y³ŽwØ™ã»WÁ:im×]Ógå> do€iÉjó–Æ—ŒQq‰a1[ü&ž¼­ñPŽ\Ê,'# RéëÀéçzöq^›•ÊW¶8ggJu"†÷v½—¨1` –Ù¶"K¬ qg»�ªT'$ÇŸÝ Rœ bˆ)~}+Tç&¥kØQƒJ”C¯ºŽ† Š�Š½Î‘øÆÐ¸4Ô÷ºÆ‰"Ï7ï§nþ;çR$EÄ2Ïåµ²!Ô«^{\$V{þÉጹ?Û¹9O ±�‘UÔ\6´žËÕ‰ãçqw¨j7Ž-¶¾”؃|�‘l!"¶¨8ïÌ%Ÿ¹€ÿ"bŠz‰REî;ï=¦éŒÓ4ÁO'#&¨–ù &Ä` ª ñ �e_¨KK&Õ5ÁqŠs°s¦ûLÑ€û6TÙa;»ØŒL˜sÍH3#­›É™#µM ãù¨Q£F�õÕ Œ5jÔ¨Q£Fý«}ø˜2/É1;"šLK!½°<€êC$Í*ª?ç¿ïAhº²—ïm¦+UMÞ?UUä1¦ MÊ€t{eÕ|z¥Ü–sZ‚ç‡Äå�mXåe±ìܱuoî±ÞQ÷Â”Þ êÖ�ö)zU{�¾<ÚN É6&`PÓÆŸv�vÄÊFä¸^цH±ÿºë«>lû^¯d†ëŽ’õ1Ël½6¦«o¯U—\A÷ŸÇÇ=»nÀmÅÞQÒαÐá ô1�Š_�^_çãzû¹íYm½‰¹gý;ž<›^z!Þûí-‹ƒktìGNì –¾Ô á€ÓBÇñʧ´¤IZ£ûÙÓ»„`×µ�öF Ú9§ë7Ô¿î 6«�R¿®]KÝO|¸=Ž--ö’£ÆµÒÆ àñõ°[û6ýúпkμ`¹»ºâ\ÛÚaPÍjžÑì½ÿëO¯>üOþÌO}íoð‰óþµc¾Ñ `�jTݸdhk Ÿ-Ü9)gÞ„Ò§õÒ_­ß˽›b¾·¾—¢ü7Û÷ ²+}xß�ë�:Ý?™mwÍx'PU÷¦/ËU7…zµ:{�·=Ž(¦pvNV9åÚ!VÇÏÊÅ!€gUÅä}º_¨vâY±NdÖç˜T#KŠÒ^4+¦¥\$¤]‰)q Þ�ƒ´ý9O&»WÒLX‘—8åÊ“¹B¨WpàU‚«ó)� ïõå¾)ÂÉf¾±‚ß[;l¼ ¨Wÿ·`+Qv:hÒ�­pžS$©ákTE –eéÆºuu°Ÿ§Î…À{¿²�D�f¨ªÍAìcúsQÊxƘ�IҵLj)ù½#V ’$ÆBxÉÄ—æ_q+pÛ8ŒMlØæ³”Kç×ç8ÅyØç Òb\»Nb�BŽˆ1väŠ ÒûiÂ4¥˜�ÔG!Í¥°D,ËRÈ"Óäå7°fBWâ 3ƒ½K¤œÔW+W’JÚ¾ã+}vm‘D‹½HÃã I‚Ð; Œ5jÔ¨Q£Þ‡€Q£F�5jԨϸŽÁ예ˆ‰È‘~~~‰ßîlð¥ªq²Z¦Ö×Ö>¿x@7 Dña.°}÷Þ.‹ü0÷;9’,v` N4j°úíû¤¸Ð¸çq¼c ¯5K6Û¹çïfÒ p†xŽðJBµæ'Ýö/õí9„t÷Æ`wN  ö{ÀgÛ­Bûfº¹®À_:Î\­‡ývOÿ¶ÄŽÛ¨vàÿŽgúœÅ1HûRÉ«n:hrƒü¾»§¤�›îØm¦*öΈn;7ÝÊuW½‹kÇ^DÑû ôzüÍÁ‚Bï®oéñ²îâAãð*àI÷6ìÚ<Ú¬µ[�½1ÑL*Ò(/Ž/z5�¥ßíAV´„©UŒLgåOÛ cï…Í{¯Ú•4Ô7ºÞ«›Þ¥í¶š³û¾-)íÆeޤnv‡kÑ×G†ŽçÞúŸîê×ëËàfßÑOÓÿ÷ƒWþ?¿úõŸþMÓÓ¿XÂü,1¾ð†™/ÄîÂÌápL@a°¬kÑzqhíÁ×võG÷]YÉ  ämç÷Èk`|Vþ_.Ï%ó]Dl_1BXÙ‚tBÀ²ÌXæ¥äÅ‹8ÊÎát:át:c:MæF�¢œ[œC¡€£Ú@sžx üÚ±0|ŒÉEÊÁ¹Píý›c¶¾råg¸þïùßìh�•ã�ÍÝFÍY5í~O ÙaïÜ¨îØŒsRvƒÀœlΕ ÊéžHúy˜±Þì @”„1³‚UA¬pž±¢ZÒ«XlAŽ:2—­NLy?¨M iŽÏêAf#ˆô‘ ›�•·ÎLIÙ]É-¡#ƒáÄWF@´¤øëSÜ'`:Eäy¥Å1ÂÚrV…÷S7ÿ™¹ØÊ‹8d8wó ¾>©è÷È?©KD"Qv`x•!†¦í089• b°…*ÉÄ9®Ÿoš¹zôY*“‚Zç3ÇÓ4ašN8�&8ïMý€Q¶ãïŽG2ðŸb;bìÎ5f†óÓ4ÁOuÝ(m v\ùýëü*‘DÍü0Á€ù†””§R>ÿc!=õs+_Mˆ->£:…ÔûÂâAj®6‰¿ä< .7�ÖNÒ=ò¨Q£F�5êG¸`Ô¨Q£F�5êsR–WILDÀô{ßùí_’O€á�¦¨?Dá‘U5ùûüÏFSÙªgv䬯¥×Uú¢h”¦=ø/"‚67\wl¾Û¬åÖ9 û @K8n•ÎZíEUk¶{z#”™AÐÕJ^ï{2ÖÚon; ß©îîc•y¾¶WVPÔÖX†­’¾™350™´Ñ÷ÅUmç8ïyÕ�¾ÂøßôÏ�›Ámµêcm(û+\”&S]é~ûñëgùqû…ùžš~CÌXå”ß5oÑv½µ‘Æ-¤³L ÝÙ½Ú2½›.=�߇°s”ª‡­ÞXÛß…·ÒñÔÅ�®ÑcKûî°U;2FçpÕÍ£›ŠºY+˵c÷BÑñ °–~ÓÕE7‰ Àš[@ £Á^mžŽ¼X®ÄhAì´ŠPzà\Û%<²j;†´©>´ùÿÛÞ˜¼ømâœÿ{¯>øà¯}ëg¾ý×¾úµoü³Ëósx¾&ÛyV†St uíCΗ/QÑ@hl#-2Yeo|3x½&Íäý¬·U.ï›u!»°õi9JYó€#‚!6î1F,)V!Tí5#:‡–2Wó¿¹mÅ… ¸kXÃØàt>ÁOØ9ˆ(X ܶ¶EsiX¹ddð?„PÔÿÒ¬.Eµ9ç»~hÔäâ±`I±ù½ÜFn¤ëh¶ý/däÆá Ç“´Ž'[“þ\ÚDLTöJ!e"e ß5ç 1±÷�5jÔ¨Q£Þ›€Q£F�5jÔ¨ÏI9f""§ª“ªN?øþ÷ØÉ‘ªÁ¿ÉÙÓÓñúð¼b÷º’˰AÎöÀÜNÌIœ¤š·YUü( ¤¬[ÛtÁyW•P�TXù�3@Ù5W³Ë –òr 4µêî-¨º§~Þá÷ŽC��±ßN;[ &çš®÷Ù[è×vÖçízÃVº‚Ëǰæ±ÒôHèy ƒÏSíð‘bš¬ºB´*€¹3WoX€_Åådm³Ðö†± z€w\×,è×€ó5¾Ï={sqclçð,¿€ß!±¿O}´íÔoêîñSíÎám³·ÇÚ~óÐórºrî<6Ç ©bãž¡eÍÛëнɘˆF+û�|n()núñÓQâêâq4jºóê}}ãJ�¾¡«�½²«ß#ƒ`ÇÊÿæùyп+À5"½ËSûÑ÷]¿Ýw‹sþ7Îçóö•¯~ýÿþí_øs蜿:‡@ ‘àaâÈŽÅ9³G7vá­¢Z¬×c~gKõ ØZ@�Ú\uk�”Íhb¬9ÞI©Üî�»ªæVM®F¬»\žñüæóå‚Ë|A1©êÌï=N“¹8Ïp/Wu‘jG–%½*ôyç-©pÎ�C@¹‡kòäÛãvª…PMiH)^�‰Ó½­ò×¥p¿ÌâÞ¥}Ô~ÏD f—þmÛÖž �”®ÉXIy¯–£Nb i$SþKqHªk¶vJÙwÎUׯ)J¡B;S¬Bžƒ*e~õí²Ó+ˆ‹ÍÜÊ–ëÎFÔR­êþ›£4w#‘DD®D¨¢HŠ]ÈÎ �“Vk9IQü×ùÑÛåÓÔƒà´P�¹XÇÞ¢WÁã–�Q?–PV˜CÊM½h,‘1ˆŠ�þ‰˜Ð:jˆÄÍù±+M ®ÖÿÞU…¾©ß˧„ÆJ¿Æ~´çZ‰'hÀ&Nîiþ¦>Î1 æÎP× ‘º†æ>bâr 9 Â•qj¤‚âR‡·œ;%~L’Õ„ DòÊê6§�e´1~K‘ 6ÿÃ`Ô¨Q£F�z¿jF�5jÔ¨Q£~HµŸÙž$²ˆøãt¹<ÿ²½°ªå‹Â?)ЕÊÖ€m¦ô@–ÓÓ“å îlš*°:@WÔfËj«[í𜊟éMKù­‚~ý÷æ8wÉÙŠV[0é Ú‡…ÔÆ  >Œ/G–ɺz\K÷Šú ”§•ÖY²nsÛm·ç|ÓΠ›Ó;Rªô©kxwªÛÊ=Vîz×_öqÝ™#ºC¹>Rô²æÝ»8rIz¥÷Q;�Û~ ùÞA8¹§ã_lã)t»aëпÝ:„O�$¢o³ýJžéøÛ”˜+]¨�ÛÈÝ»½{¶Þÿ[²×-¶Ä.P­=¦¸^c¯©ðÓëµ,Ý7XNëi©·ÖÓ•ïË•CÓ2Ë~ÄC¦·ÇìÎ÷áÙûéïœÎOÿŸ/ù«ÿï/ýäWþéù<=ŸN§gÏ.ªXàŸ¬å‘ÂŽ`—”µœ¿Ž ì9áQ�t*Ò93˜}>É“ 9t ÿÞõº—Í}„y°€“1&÷¥FOœTÀ 4e¶½~ ÏožñæÍk¼y~ƒù2C$¦ló DÕFütžàØ!JL9󼯤ZÎ@¥DÁ<_¬Ìðίbš+ØJÕœ ª€¦¶®Áþì€� B%¡)½LUI÷…Ü�>+˜H Ô'kõz‚²ÙΛÝy�Ø1 Þb2È-¡Q¢`ùòå6*dÊ­VðJš¸&ø³'p¯n:¶«µ�È¥÷µ�ÔîDR!6òAe9Ý´ãº@pž0yï]q$°ÛÚ¸šŸM,†#F€Y;WÕžp $¢* æXˆÜvô€¾Ë5åù4Y›sÁ*Jcõ™¥!tع@ /mç¡6Ä…hŽaAH”ã¨~2¡u+ÈnùX²ÛÒÜ›¦ Ói‚÷Ä®ôÍîí¤J"-èŠt ]ŒÈúœ€(Rú©íï 1�sé:Ì6¯\åË=–èJÙo¤�JÕ´&H9‡Íy#‘q\½Â Fh(sTÀ|*s»ù•PS Û6ÿF�5jÔ¨QïO À¨Q£F�5jÔg\GÓœsctQÄÅ}X·[+}•ý¬hmìÜ[ q_Q l%îéت`t ­ ®RE|Ëq¡¨ï¶øºk½—»MPˆ½‡ƒüÀªË7FC@h˜ÙÃÿ->R€0“ã$ûÚÞþȶïk{}ôû»>ÀØÖ žÒƲŸÖÙÞ;ãrì*€„kévߺ5)›&ìn×ö±= 4µànJ…ãöìêU¯à�t3ýº'½ªJ¾ŠÔ]±+ÇÝjíÖq#«ß@GYãÝ@÷ëC Ì]‹P×Þnwt}|· ;X—èJƒV¨¦^ÛâfḃpźÿZ›×¹w>¶$¤·ÿ7î«n¦Ã@WÎÍ.6…’Žv½¸ñ²Zû”J$@·Ó‡í^ØI„rÌQ'åùQÛJ«i‡–449Ë�êñÚ]WåG”[oœr/Z"ô Oo8h0ó¿:?=ý­?üÂßøÆ7þoøAX–™û¢™ˆg"ºÑ\î#¨æ� 3\lÑ‹¿«@;³Ë—Öe¨å2¨Ì͹(��zwÿ‚>Û¼\ÏÕn2 ˆœÇ.�s@U­]®�ÞO`gïI9<_f¼yó—Ë3æy) fVgø ¸¯íóó1�sf8�”mÄÒ8˜}§BÏŠé ž† +±!ÄBbȱÞû’oý²A‹­8SÂ¥¹Þ•™QÆ·l9¡îÔ9OÑ ø®`g=†P~F¶xg$ûvnî3µ7Û¯”“ÞLdã’hRe§9Ñ|O%6…ÂBr(–TÚÙöÛ&ëþˆÚ÷WR7. w®}ýú~ºÒÌ„uCú f]6ÚH˜ÑrüCî'ç\!}Ù†¡“OãäŠ ~îûŽÐ90;ðdÄ#v4ñÚ€ùy\U™G’cƒ¹O �óA©&ÏÃj½_I k >«ÿ§é‘I)î¡=¿´!åñ(ó^ú¸*D#îÞbg�êNRc%òøsùÌ�ÆŽ_W‹öç÷ ;m±×p™3L e ¯æ]KDqM|GjS"ƉJ¹w�ƒ0jÔ¨Q£F½W5£F�5jÔ¨QŸ“"{RÃÅ/ËìcŒ?+YE²ôdYu›¡.5 ¾©7W Z Ø'åNû¬6ÛÒg¢³’o”þͱ¤¬Pp´• ¯rœÛ?ÀNà”CiÏ[i�M›m!?—E~"Ý‘(åµrͻ컬Ï?Ȫ׵ҹNï§z8ûÒ^*@ùʲxûÊÕØ­ö}`óŸÇM°q1¿rë ¬~µmp¤¯rcÑXÅPm¦ðF)�Ór“°µø¦½¾î˜µMü]n÷7ºø­jÝ5úö{èͨ1z U½¹ï>Ký_Õ;øž×ÜP�ë�©CëIý6àÿKL VëwmëfÞRÓF:ìÛ+дî t݇zí¬¸q�[’Ѫst'êcs‚u¦ÞžË÷Çf­ÔÏŸþWzõ ràžVèv]¼~ýººú-Óiú�WOþͯüÔWÿÆ_üÕç·ŸŸçå“O>ޝ?ù$¼y~ªˆ(Ñ’þ D´¬îqŠeVÑ:Gú7ÙÚ.9°sl‘ô—øv®S�ë/Yíª2Y!$¨Ø·;§ÞW‹qïÁ®*nCÊ3Ÿç –yƪª�3[«úd#Ï>ÚÔf8Lj¡õ�.= +’œßËý.•¬°Øü‹YaŸ ,Ìݼn¿gÇpê *åo•ÀÒÛ&Øö<ÜddÏ®w£Èq\-ª DÄ4¯ÊÜÒzÕrÎ\ë¼�8ÊÛuÊûL"ð~‚Ÿ|êAHú!9Z”X vÍ<ÞÜáwWÓ¶ßZÒJ ê±¥Ð/ë]s!VÀˆš Ò‘ êºPãÚþÏ$›|üyÖ2”m.Ù<Ò:kˆ»¾cv W�Ò\FÀ¨Q£F�õ^Õ Œ5jÔ¨Q£Fý�«yXD!F!¸õ/ÿÅEå'QìÑÓk¡Å}�¥vߥgÒ˜kë'­7q³ ¨Û)·{ÿºÃ�—V e^KÏ)‹¾ ”]€]`Mµ*W5=ð×+í­Ç�N»¡›lì- àºêþš@«=UÝ#ol–Úöù®Ô³HI»¦ÒÛ¹ÐûÜj·ùèpÍ~k»ÔëÇ}õ·´îÃräÛO}¤9T¸S}ÙnC“Éꮊš”Ç»§\ófÅ£HÔ£=zó\ýÅ[ü÷™êúÖ2xºÄ›ƒÔÛ¿i² òÿiEJ¡ƒ5êeÇ{Ãÿžˆ¬NoH2mþô#Atóü×;ºXïêÿ½—ÖS½éó—„ͪ¨G$ ‡FåÆù§‡£t㌹Š‚f¾½l¥Ð{ßuÓ±A»yÎÌ2�Nëƒ�~ìoþò/ÿÅÿü§¿ùsJ 9„°\æK¸\.q™g !ˆŠˆšßº‘±R üî�•PTÕùÚ\Aÿ¬Þõpn‚ÏöúŠât8ÈD@ï‘{° r²ãÕf©(“Q€ü Ó45¶ùÕ®|YfÌ— æeNÖù”ìÈ'œOgœŸž0�N 2+þež‹ÒwI�¢ÇŽ¡ t¬®Hmð8Ÿm{çÓ“)£Ù@ÉËÑ”@sÚîóÀê°ê‘Ø}2¤7UðÔ)Ý©ÃìA^>Ø,Yw”øõ�¿õú–ˆ€êBÐ4½<UÅJG·ÉJîA´æ_í¡žCfk1{´ìe9¨çëÛ·`öUðI¯lwó:­ÙØ8˜xj½á±­}<„¨î6Óöµð7Àð�¹3yƒhõVÚ=Ÿ{rصùY×>¥ÛmÐGûD÷º{Æ·N-·|%Þ- àÊB¶·\ï]?ïô ôæM¯…ˆè_{?ýW§óùïüÄ—òo}ûÿüwO§ÓåtzšO§Ó–eVÅ|™—åùù9>¿y#Ï—ó’e­6ç�{µJo²â›iêœOêþ¦Ó„iòïŸq™ Шÿ3˜Åìšýé! ÙÛn÷9à«~ilâà�©¨Û£˜º9„óF×õ§ó9»>v6üÓtÂ<]0/'„%¬ÔõÍ}K4šb:”ýµ„b€ÁÕ�mœœ(à=ˆ¸ „æ>·mGÄÐ6nÏÑRõ2ÈÍ}eº—P�(¥X˜šYF`XæÏ—g¼~óoÞ¼Æ|yÆ<Ûe`¼ŽmÊ Ð6ªÀ�I-çž}9ž£5ÅÁ@t�jÏ�DrÐl}/õž%Å78·Àys`çàšqq y‚¸^~”a梖ÔQ#:‡fˆ »~n'õ|Vµ‹H÷µ>ùÚÈŸÎU·RÇg{ü¸Ø× ¿‰£ìna}ÀÌež‡`1DÓdnœ" òýc",ÙQ;Ÿ¦D�ˆÉ]"ŸÃEÉŸø·¤“ÏΜìò³#õó;¯ yNq»b&ÙD1gƒ6bd×1"“ˆÑ$5ÑHiŽE#-Õø‰üwß/´Í§ B8�ãtN'ÖŒ’\É�5jÔ¨Q£Fý(Ö Œ5jÔ¨Q£F}ÆuÎ^.3-ËÌ˲¸7¯?ùyUi\ó˜_,Úo÷ªSà«îýkØ¢ƒZv@ä‡Qµ .[ímûK0kí¥oHgmYšF¦¾Ù{@u”�]¬jiKžè£¶PŽÞ–ªêý˜Í |£+¯{hNÉ"Áª_û7¦ÿ=¢Z×;'­úfEŒPÅ® ›è@{Û"‡mìÅnh6íwéÊÖ\õú{öÛpm›X‹ÕÜÝwðn£,Ö’hÚ›Ýwœcô‚üòÞ ¾¤òÈ�¹ªã°÷ŠOû±ó‘ƒ<­»]¬õioðõ´§W_?Z×HÚN¼‡¸}LÃc {ºãxWq.©�/RòÓ­³ÿÓ¯ÍztÊÒ[ÒûOZºç—;Ì>"ú>;ÿëÓtú/?üèÇþö×~ú[¿ÍÎïýršN‹ªÚ—è—¸d‰"Ë<Ïx~óožŸq¹ÌˆÉVž7¹ÓT³Ý“RIåÝ: Ù«33¼Ëê_· pëÈbÕæ¢Ø[o½´¹×j·ö§J÷®¥5s½Ú˜úû#²`YbY¼Áùü„?üO¯žp>�àÜdöäa)jýÜ�dØ­ŽeöÄSzLí±cÉjzI± Ö§Þyð™á'�ÓùÔ»ÕV<¤cˆÅ½`Y ¹!¨Öˆ‚lÑaÍQ‹fÐ)D eÀG259/Á@SQ€É¶'*©�b!?Ô1ª¹äœÔøù–-29¢UÔ—ßÇä* Wˆa ¸\žñúµ�ÿoÞ¼Áóå‚0ϦªwޏW{g—,ÉÝ™làÙ—uÛþ¢$® �•KtIá@« ~É–×â‚Qóá¹ØÅ‹6jü&6£ºfÔûYk¹ÃQ…´Ž ɱ€Y IA¸ÆW(k™ÃU©/�ý~Þ¯ üçI‘•è­F !¨Ô艜âDÒÏí? ú­ ˆß»ÞS#�ß·ÄîÁìŒZ*´y�¥ûÈmÙa«**Ïǘ e1ÖUJÁ÷d1ë'O逋B±ÉßÂ<½�›êk× r9ž ¾Rjǽîz/@¿­±îÚø]¢WÞ³Vö“nxôÞÙÀöÇ#x%N_kèU¯Í#:èÇ;ºGÿá–ï¯[d�†�B{Ô‘–´ð2dðþ"\iß#»mIýq×Ã¥]͆´±ÚÙKóØßjøt¶lº©ü¯iuÚ19ƒîj�~J‹ŽX¢Øšèî�Ñã“�®;^ìŽùÕS_ê[º÷T>ÜØÞVô®Óîñ?ÝØ�vß<2¿vè�v=øSçüoøÉÿ—¯^}ø_|õ?ó„¤Õ"‰(ªj4B¡ˆ*1ª"†py~ÆårI ê1Z–:9FG´£PÑì¼CUϦžbnÅL’*]µ(x‹âW+qp æëóúkÿv…6ßï½V«qe.îë×ÄbH@½”XƒóùŒ§W¯ðÁ«W˜NBX7—ËrIÔØª0WÕ´Ý“2Ú~6uûçÓÉòϽ�²Î1;x7á4�º~ɶê1©«—eƼ,Yÿ­ŠçšïÎÀ…¸U Š+AVֶñŒ…È�Aæ|ž1;xïA4ƒ2¦É?÷E´×èFX0ÐW¼—eÆóeÆåùÏoÞàÍó3æËQ"˜,óžeþ9ö–Ÿ”Üõ^ÚÁ‘À» ÎM šÓ}=¯s?ùÙá\‰ÍÈDŸ%ÄeAs§tÏ× LäÈÅù³MóÙ!÷��ææž ‹±9î˶ëˆá§ PÔ87Yœ}r`H{²í2í•×kEþ3ñöuŠ ò�‹ëŽ˜í&U´®5&ƒÊ1×8Bç<Ô�rbŒéïF*Ÿ·Á¥È YEVĘˆéÜôé GF^ˆãóø¨Q£F�õ>Õ Œ5jÔ¨Q£F}NjžgÄYEX$~}ý÷jâØ>ìФ¦y]~n™`j’j‘níÕ[ý}‰,€·U­ÑÕV†¹µÞ­ ÿú--d›·ž=¨Û›®Që=÷øL„ ÍQ¤6`³¿{,ó;ÅÏŽ1±®úëêÆn;Gïjºû²Þë°×®°”®ftÜ’®OwßÚÎÏþ}ûàÿAÆóÆ9@ûão�襈[3.�¼j… ›C…ôÔ^ç¯G×ÿº À]€g£n?ÚâµfEØLÄÝcÛéý0¯ÛþR€ÞÑ�Âó}7Ñså17€}ðÿí¶¹9×uÕÙ›Sîݘúß»ŒÝË?yŒò¸kÂƒ �´êê;è‘m¬ÎÙëoª«.3ÿçý}šNç£/üøßþ¹_ø³¿%¢—B!ÆBŒ†e9¨‚HˆH ¤”¿'UU‰‚Ä0cY ü7e®&ûîÆB(Šãœã‹¥|«&¶ëD{ÀK0ŬـGH0@Rë1Ö/·² ]‘ Ún¢«?×ëŒn”ÿy›* Id„üºµjÚÔÙÞO8Ÿ&œÎ'Lþ”2À#­À¾Ä¢¢®ÿæ}K§Þ7 Ö\–eÁ“+R´€XäÀ¼Ìp×õ@R‡;Wë}?Ù•ÀÍ|ܳºOÊmS7£ô�¤Lø )DQf‘ïªSš«E<ªµ:k•�æ’«Êe‹8°ˆ…Ëlàÿåù—yÆ2Ï1صË1ˆ9'&LSŠŸ˜\RÕ»Õ=vu˜Ø#°ƒ²B4ÖùÜEÔ“9«¿3pkJîØE2”¹…vÎi™ìmíÞ)±[ë~+Àï4».ȆؑX RÔöÒDM(´D>d°zšN+ë”ó-GG´qm$�d—†Õ=`�—ÙÉ¢?7Ë9–] ¢ еÝcŠŽ“Ÿ0y›óÕ!¤~¼QÀ\šûÅ#ÂPu;p‡¡vÜ{«ýä ‘æN{k{Hë—Û]¿êúi‹$ÍÚJÅ™ƒˆÒ\ân>0púsþh'Ö÷1æù8µ˜ U@@pé>›8¦Q£F�5jÔgSƒ0jÔ¨Q£F�õ9©IŒ$*,¿–_²¨;lh/³Ø®××g¬½B ;YÔ럛˜¦§þ—�ŸUÍ:¼¥´xFmu6툽Q�·Îõ{ê\ÊDƒæøÛã"]©a7àµÿZG…îåk”çš3¦�u³Û£×ï:Ü_U’·íÁv´u_ýh½­zå8ö”÷7¬ô¯ômFýÚ¥;ûúøïºBE[ÒÉNãªËÆÁãöcÓÛì»ü‡M¾¼çH¬‡{§Ý~YOBÝåÛܪüÿÚá?ž'ãœÑG:û­ëNŸÞ8Ç÷'Þƒ¥;§®nÆeÓï² =8º·zoe¯pÈßuòxGàÿ[œ³zçœ~|îiާ‚:Çà§Óß}õêƒÿú«ßøúßþö/ü…?•9Æp‰!Î!„9,Ë À¼¥…@)[áå5¾c_FRÕÀ½%,K@ˆK±+o«U…ǨP‰ \ Ào€7Ë7÷(îF9Û­Ò�5}ŒKU�Ëp®vü)Ç@Q�ç¶· ^×ëD§5ð`ÏU º¬bœƒŸ&xoà¿÷"Š„(Z¬ÒE"œ÷©áºs.ç¬ûXú J@”aYŠÛ€÷ËtžâÙÉòÜԾ̜}Ü=fð~j,Ê-Ê€Rv¼Š&ò€9,ËÕPÔÅD@àШ§›qÕLbÐâA0—(ï=&Á>¦c™à½ƒSJí'· fI)6‡T‰ ‘K¸<ÏxóæÏ— –ç¹ØÉSŠg˜N§Ó O糑&¦ Þys` Ü÷TÈìÒùá'xoŽQ fr5Öbç"n¯ÕDŒ0òIJà=»3 N•—K«ÛþÕ­mU’Ûøæ9""§)naŸ#™�zs…0ÛþV¡ž‰9¦üŸà'�)Í5"N÷ *6—ã’¢4m¤JdI¤#mYŸí¹Å™ˆmôD4- ÉÑk™Ä`}É~²¾�àêÝž&‡ˆ†¤lÇ/›ózÏ]d³jwWY�Û Ûþdž”ï­bEqÎbI³¶1A”W— MD -¶ýÆaÀ90êÔ˜]Ñε-v$–uX…Õc¾ŨQ£F�5êG¿`Ô¨Q£F�5êsR#©*È©â«õ/;¹è‡¤öýüpp-L¿ò€§Ô:B©4ý½cø¿›ˆ­›?µî ¿ Ø†¢>dïîë×f5.­1ù¦¯d¹:NÔ NåaáJáÞnM¯ |»¯]µé^¬ªËÓÖÖÛ&´ wï�»^w~ä"p»u™#¡›ñ§ò ½ûÍtg2Ñ®é5º)q¿,|Ûææú©£è­ðhºkVÈëU!ÿþ ë 3ê¯ Áõã¹}Îl~I��3w7>÷Awü÷Õ5Zƒ¾³èƒ-a£!ä¸*ï‹9 íMÑGFå¡Wóãf ¯øÿß;Ÿµ>²#œÒþïüߟN§ßüàƒýkßøÖ¯ùÏ|åO½÷ašN‹ŸüÂL‹/L<3Å…ˆ€�í¬‰Dâ†Àp“Ãä§nšjÜ%en@,êmQ3aª‚d5ª1bY,K€¤Œ{À”¯ÚXjw箘*>r1FÌ d^B@¼˜ (ËêÙ6§;ç~ö'5öåw[ûñ·³F=ì½Yò綪ÆDRlìÖ5‚"A�ÃuZ–6hC6PV hGB,Séf,' ·3SšT8Ÿ @ê‹Ý»©òÙ1$ æË‚7ϼyýÀ›èg ˆŠsuxh�r,DžàØÃ¹ï/ð“&¦ÓdŠsïà&WìØy̶O"‚%øy~Æ2Ϙ/ –˜+PÁì³?ã|>ãüô çó “sà¤Ï÷x"¡¨®s\A&G‘&’…KwT­ÓŽ‘JDAÌ.±8@„¼‡`Î6Gî®Õ†Jl‚�òTbħØBã�Æde;KBqêÈQÜØþgðß9{œœóìƒd`ß-ùž¾(ð“óEv¸Ê‡$›—F>ñiî BqYÊŸSHĉP6ï½…X*�Fb½'I„‘xÕ-$“„ò|P•~-±E-©ïW×ø¨ü7w�Ø­w„D*Ik—"E”µñÌíDZr~Q¤ý¨F`–ô�Ï—¹!1+ÿ—í`®(„ û|ec“CÁ¨Q£F�5êý¨A5jÔ¨Q£F�úÑe¾<‰È—ì -àÓžUmk�¾Úì᜽0m´qxT• ¸ï�l`m¯øoذß�¢”lLdkþöa|ûÈ[ë£Tmìïµþ]•ŠBª=xÊÁ «øƒüÙÍ)¿¢úÔ#Ýqk°A§�ÞRí^Ë;ènñí1¿òXíkc«ßlå.€MÄÿQ3�uÝßDÛ¾Z�­ºªY8Êßsp×õèªö]]T[ÕN˜vöÿÐ�oÎÈ·^%^´)½æäp§nÎþ4.tœ¬o}Ô·8 ‡o¢O¹ûï<·;ÖÛ‡²—/±ñ ¹£)zÅÑãΦtg·éýCq-âáá¥#òË•y~Íÿ¿ÿçÑÃ}Çs©+av¿ç§é7Îç§ßø‰Ÿøòßý¹_üsß%¢EUE‘™"3Gç|tÎç\$¢ÈŒ¨NGŽD$ÌŒ(�J‹ Éâ3<›Z}š&L§&o�‹4ÆbIoÿ¨Ìl÷Þ3œwð>“ Plæ Ü\¨¯]Öu¾‡ÈöÖšïW»ì#æÙ2ê3pjï«àXÎýn×:•}Kïü¾rÿÒ´ãÆ½YNó÷ë÷$;ð¼}çZwjˆn�xàDÊZúÍò¿]üPX�‹n„ˆºýæK� ˆ1âNS€ŸHÍò} Ke�dën ùétÆùé„óé ~r òæ`p¹`úä�‘ ˆ ¹,LµyÐ[ÏwÄ…d9osæD’0pyš&œÏO8ŸNŸO˜¦ ðH`;pØÔî*ŠË0ÏÌ—ó¼¤<{¤¹O˜N'œÏ'œŸÎxzz«Wæà 73D¢Ö{˜¢†Ÿ¦ä®µó¡æÅSQ¾sr»È÷v’,ác´6.Á”ë5@ÁœúO\s“OM,D¿öÕø�¤&‡Â9—€v5rI"dU}¶¶oÝ-bŠg‘2�óyæý„é|‚Ÿ&8ç0­INf5¿¾¹�†C�²4¸s3PÕÏࡊ¤‚WptŠr^B,ëAvL�D@"X®=ˆ€¨ˆiŽjq7ˆ‡ÖþÜ:¡¤c­ó—›x�†ÀÉÕÍ@b",‹$G ID’D‚JÎ w~.4G 4÷ñéÍFÔÐ2D’“#¹pŠK¨$QI„c¶µHs4‡½7„A5jÔ¨Q£Þ§€Q£F�5jÔ¨ÏIQz þý?ý×_”ŠÍý¡5ømkâ#_í¬DWßHÚËî×òýþ†’ý¦¬-×ë¿}d@µçÔMB¸–Õ¹Mİ,^T7írhß•µqL¸Òè;hwCé¡c׬ãñ=|�¶Ú«ŽQí­ÿï2×f¶¼s {EÍt¥:Þåͬߣ´¤h PwßoLÄw¶žØn»ã±>L %¥ù¤÷žoëÙ}äDp|ܸÿïóþCì{«kúj]ÚD_Õ}À&FCßjVÝï×þ)úÕî ôÛëœQ›Ü×Ú�Ýñ�¿éݽú’~þ¯ŸÚÐÒþröŽlýïé÷¾˜Ý?ö“ÿÍÓéü›~ôÑßûÖÏ~û׿ü“?õ§ªºˆÄEUƒŠéJÕNx!"evÊì„+‰cVfVUÍß#Wr§38¸¢äçtùiÂétÂ4yLÉz; " ö‰ ètÎ,Ê]ROSRº{?%ÙÚÇ‚°–PKçØ¬ÝÓ�"(©È³Õ÷œ"Z[rS�»bmŸïbÖcùwuŸµké½GhÕ¬ÊÍ€ ó®¿.£‚†œ€US¿¤dpG h²XMN/PóÒ¥Û¾÷ŒHKëT@%j ïÏÞ-vA1D,!`zö)çþdN9·=Ù¦‡Xíç³Êûtžðôô Oç'Lç'Àt¶2��»aA”LéI@R.ÃL H"4 �òÝ�©ì=.—‹)ôç3žÎgL§'œNô<¡‰Š/ÛÍjúËe1Õÿ#bLnHá¼Ãé4á|~…Óé çó§Ó §ÓTb$bˆÐhªøyYŠ"`~òÑû *“¦Ûbª™¤Â®T (‹ A ÙžÝ"Ê-�ºJbIÿ­nÍË-�®l­ìüòõ|q®'¤/"²XÕk!p´óÚ{�é4á4%7vQWP�?ò Ne\™",!–¸¢ycµ¿&Û01¢ØÜÈóÙ{�°8„`q޳JŸjOe’4h\Eò±eòPÛÑôO^/Ùññ:²Rå—ñMçX(„—-I¸:œ][ƒêßì ‘¼½D*QMÙiƒ,i-–äŠ"GªDœ(Xb,?/aÈG�5jÔ¨÷¨`Ô¨Q£F�5êsRì©*_.—/—_nTŽUº†ØŽUçTAüüÀ¹²{Äo Ó>ˆ®�é<+Ç%Ûeêv_hö¥MfÿJm”þZ :hLJœZÓ¢tÔ9#ìÁ’G`�¬Àöݾ՚+Ú¿v‹€e€ÕÐìW¥¨èU…öUµjŽK8�Z`šä×ï/#�ÁŠ&Ãa“¨°ƒ¯`ÝÔl€H½n“¿ù�¶}ÔÚ=oŽûâ~x[÷»»äC=×6'B�Eo¿’p�açT†c)ö•qIm#,p«^¼—¼\ßz+ûëÞKš­xYŸ6ä,=ˆ yÉA¿t„éÆÚûàÔ]mé%­zÛ†—�‡Dü¯ý4ýÖi:ÿƒW~ø›_ûÆ7ÿÞW¿þÓÿœˆ €™€YUg /€D%�­�Ok¿ )Ây£à Ì%Ï;]Eõ휛Àl¾S„‰b…sÕBÞî[ß]!ïØzacíº×2‘¹dtn&jçRšÇÕö?Ŧ¬¶ÏEBl®?%. ¤s«¼W"¢Rr[H±É%"¦s¡’+BY‡an™Ô%ÑHBÖ7Ã`Ô¨Q£F�z¿jF�5jÔ¨Q£~ÈÕ*QT•–åò Â}.ûäP(ö¥Ò(6ø‚=0{k¯ªØ¼[eÿÚš�úôùzLz¨“nÚ½oל•Æy[Š}ÀT†˜Ý,'¥vnhÎ>Fì©rÁ¶u›uçµ++û:¦Nº�Ú÷}´'9¿k^­&‘=ÁŠ(q¤È×UŸ+ˆ÷Ü­5ÿ/¥’+¡wBÙcwõ÷}ù=ºóë6õ� ÚJ¹}×qâáã{Ë•ª!d·�îŒ} {ß]¶èxØéÞ^ÙÁëõÖ@ÓÛõÿZÏOÇݼՌ?Ú±eÝ©d¤r¦ï‘‘6×—;wúdº«'õxüèZûõêžé†]Ë»¥(ˆùO½?ýÎ4�~ûÕþƒŸüÊ×þßüÙ_øžª FU P�1†@@ ¢`!¢ü#¨Š´¶ö­BW5&Kg#É9Tb@άvªˆÔ»ød‹Ðå'‡)eÖ˜·²Ñg2@¬Ø‚;Lþd™íÓ"N€_É€&FÊ›O ²÷>Y‰›+A¾Ngun�PÑ¢Ynul3˜_-ÌÍú=Û‹g+ó ê5ª^×gŸg2Àš`n›�nJhç]±Éo݈ò±MjÖð~Juj£Y +bå{Jç'5êð æÖûížYå_ærm��LÕšoï72@VPçcÏ� 823|ôÞ1–°`™gר`¯ 1Ѭô_5`¥sŒç‹Ç²,i{ủ 4µ¾İàt:áͳÇåyÆì=æeF !�Þ@ T�²Ì\.&?Áyo_ÎwêúÜW!«ªÔ~akŸïìïKXà.®*‚%.˜—óó3.— ¢(¼sNv *H ¯Å ¨ å×[4†ÍÕz½Œ*PͶ÷ùË� P6‚D‰ÅÐd'ïÔ|ÁK°|�Á÷<`ûlã1òÜoö<öÎ…ßA àlÄ þ>�wöwË·•“ @\ݸ5à¿„t>Ç|N×q©çe%X´ÑùÞ¼œ³ |Ïýk€~Ša€S�€Ä΃lδ¦·çN/’Àÿ–�àšØJ(º@ ˆ²g�|¾€®×B”Cìëï¥q19Ž/ÑG3ƒFk_Ióy®û™æUŽ)ä¤%¤€Q£F�5ê=«A5jÔ¨Q£F�ú!ÕÎà RUŠ1~9ÿ½1ƒÇFN^~›�míÔî}îûN–´®Û±èfõL†ûѵl)¹ Õc/ϺSú7ª~RKîc}¼Ùä³QC LjŠ´ô€| °Ût¹ ×Gí[%ü.=A-fa?WxŒWydæìþ´a§ü]*Š÷zzk˜«‚¿´ó;½yüë_ëþôB+€{ ì^¦‡íßd¯ë‹‡dÿºç ±};½„®o=’ûX.ŸÒ�oì¡vܵz0·]¯Ÿ@›¸ºÚ÷�Œ~Z#J‡¿¡’E½s<úè nϽ:>ôâc£ýõ˜ÓÅ–p¼]ßÄKIDüÏÝäkšNÿàÕ«þÁO}õ§ÿþ·éßøG"""*"1JŒ¢*QMºiÿRaŽÚ±~I(÷Ú[t·_ìÞ�i^׿ÏgÐ7¯¯Ô®ƒIµ*Ùž=EýHg¹ÔÞ›¥¼©©'˜åt@Œ çìJš€`o“¹“?€l“cÄ«Š?_ïr¶zr/9o×s^��;Ε}'ƒw–JÑ—0»ï9ï~gšN¿õôêÿÿ•¯~ãï}ëçþì?˜9+ùc QDDUÛ/3ɇñײ9LiV"R’¯lËÓà�&P:FËÇ®×:)àHöø!,)‡Ô{8í])²ŠÕ2»—”Û-)ŸÝXï=N§S"d _±ÌóR”²Þ9s%`—âN8�Nð§j§¯¢ˆIõc„,1©‹�À«@oçRÎx²þÏýdkûÖæ{Ÿ˜·¾vÒŽ:ur¹�P…ÄF=ŸúÞ¹ §Ó„§'³ªÏQ•ÀaöçÞ;¨NÅ–¼*…¥î[Co�ÎLæ�Ó©�} •€?QÜ–°t€¬ÜwÎãÙ= î (�É'âÇTeçÎOg³t÷Ët)6ï´MÛlû0+ŽC\p¹\ðü|Á|yÆ2ϸÌ3æç .—gÌó‚%̈aI@2 Ä'Eÿ”â |™s6^œúƒ‹(×A0Ï ï.¸\<.§Lb1çkÏÌ—ÅúkªJnQ-ñù>ËÎߌÎk�¤Ê½O±ƒªÀ“7ÍcÉàe³³¼{é� brÀ`唤12=2ÀjJ–ÿ(®Åq( óì �ø­+Y%b䜪D[WbDÔ¤ZoFë;¢@®â’àê¾ûýÉÆíd}ƒ[^KR~§j䊡‹ËN'>m»]2øïÒ¼i׈–H”Ï�ÃKnÑDzˆÑ"Êò‘Åd"€µ/–@Mý\b% ½#ƒs׈‰| AÛ\*žMë€Q£F�5jÔ¨ÏAU^Œ$Q>¬ª÷Œ TeQ¯Œ·WHy=’x™²Ò¯Y¸×íÒN–}Útioÿ»cÕv~Ñš”P÷¦‡Ù=ç!?´JOÎE¶X¥Í­l¸ÛOÓn\æôº3t¿-Õc7ü=`²%l¯£ºn —^—šÇÐzàúpdz?=@°�ÚR‘Vëû¤-ÙŸ·W»pÿO´}‘¾e[~+È;ÛÒ(}¡¸ûîVÓÍyK«–֔ϴ›ÞbŸ³ë ŸfK¸0iÝYZWö5 €�(ÀÆN€ÞEw)vÏEzd±zô8nì'ÿ{ÞOß9==ýÎG?öã¿õ3?û‹¿õÅ/ýäǪXTu�ªYõC€EAUC²x‘,ò(bwÔñÎà­ÝI¹Þð¸Uð§«½KêOÍ×}*�76êz„ÑI§T-êÝ`™ê!)±íòëàœ/ wûò`¶ýGŽ`î3ÄIÞ{L“YÿOÓ„é<Á;°,ˆ ÌOZ”X}¹cp^3_ûµ [ÀÿQpkí¬°ÞF[û|"‚÷Ö7~šp>�p:�1�¦Å QškÀ5±‚§1©€ó=R±K—ªPÖB* 8·š­Ì«Éݨâ£p Ì•¤/D¶ýG ˆÑc^Pˆ‰ì`íž¼ÇäO˜ü:arfaï&�)Íç#DsÖ»ÅJ8Ÿ]|cs/1 ,órÁežíûyÆüüŒçç7xýú5Þ¼yƒËå‚eɪêL´¬d‚bRB+ˆœ&¸(çsÔ„‘`„A°¹yš,V€ˆ 1b^f\žg,Ëѧ9ãç}±Ä7‹ÿìLa6ôªæ|an ®Qå{88'%KÞhZ8,ˆ\•؆U[~+Á=\²ñm,mA6JÊlïÍ=À{�)+Î%c:�,W^�«òÞÆ‹áuJ6õ¦Î�1¹6kîì`ª|eMJdv \&Ú=G¬�¨Ïõu)}'P@bK©‚몂²(ÁGqŠ™<Ø; ¹8覯¢íCÈrÙ�Âg»r­ ºõÝ“©Í%b¾\ðüæ|ðo޼ƛç‹ED1ï ¥z_˜ú¬’7ªŒB4%*d˜(Kó ‘f‡ÙÛÜÌDš¸Ìa1R€¨ÑúA<\v°ëˆ.Ù�B²K…xDfDï19�%[ò'Ç ñp E29M‰MöHj*oΠ~[¦JÝÜU�Ýc_êú e]¨ç ày¤ujˆ #¨ä5£yŸÆXוµjµQŽG(êwêTéëó0F‹¨È3ªo¿^´åÒ6\>Ge—[£úõ3¯#ʺYk×ç>SÚׄ…‘L–’ÒÕzÑQ$ºëöU7öÿªÔœ£y|Œˆ@L�àúxgó<†ˆ ÕÝÃÈÍ…®Ä�9K¤¹‘"F�5jÔ¨QïG À¨Q£F�5jÔg\GÉ&“TãGÝk:´¤·žµÐ=d+JQ¹eÉ¿øvÛ‹´-Z¹ 4 Š\ lξƤ9ô&H¯Ô5PÔ[|W0�À¤mcû€-emjrM°ý_1ý¿†Bê`¹F÷z¡]²Ó߃îKs¬ôfÖÍ3\óÝþÏ@>"ºït·¶ÜˆjU{+Çý™s?÷j˜�·½ŽÄxTýrëþÇöóì[ l=²ò¸gRÓqÒÝ=w#ʃ>Û¾Ò{ÚM�5�YâÕ=q/μO™ÖuC´{.½ÍtK,=ð†=V½¦|ßûéw¼÷¿kªþ/üöÏüì·ÿá‡?ö…×¢* ‘"D… j8·ªÆô%€ÆtIÀ<¸‰e.(9Z,»»€ö†Ð†ÆÞ9¡E(� }X�c«ì¬V_Ûp[ò¬°'»®"W1D,ó‚°˜RZD‘…åÔªòÓ/«b×bŒ ÈÆå¯'NÇ) ®qãà¤tíÂ.�å5�\b¯Ä·î|\ù_íùQ¢Qö· ³¡/N ù«:þt:a:™B>;#dKï|çÂL€w‰àjˆA$‰,�÷SÁFpŠõQºyNÔøöF1Ì5ë�Rþzy@è<¼?Áû Þ�Ìåú˜çYˆ�­¹FˆLàPÕâÙa"ÄXNBÇ|œ ŒôɦŸ\ú»ƒc`*áÕ>øàÌó‡xýæ æËln¨réŸ"–eÆóåaY 9f >SŽ)Ÿ0¦ê‹+s+J„DAH.ÇV²âÓœ4{}†wÞH.ÇTØk]ðÎc:yL:Y¿Â$ &°g8aˆ¸jÍ4@v“!¯ Yçõº�Æ1¶s¸Éýº�ÆRc³.äó†Ëù•�ÁnòÅTõ1&›zIñ"R�þüo&`{Þ Û:`7Ncw’bÌN\H* }˜¨‚VD(¦ê€‘û4¯=¶¿XÖ¨|®×5·®ª®›K¥½)bEbC¨(ã†Wvxc�^»raéÏk*ă|L`MF¢ðM„‚B¦ˆ%8,ó‚(!9ÅI"‚å}Õs£F�5jÔûXƒ0jÔ¨Q£F�õ9)Sÿ ‰âûM¿�•€ùw-xÙ$ìÖuCùÍÖ+°¾RñoÚs€0eW‚bÔOÚéx5Ù÷€ë*P|%8%"HþuŽJȈýK€B# ?"_Ð …SÝï¿ãÜì¦�Ä9¬æ  >í_AÒTxñêhh3X½eøßíïW›†é!i‚v"»éê.Ž3ÂדôZ–½®È ºÛ}z‡ÒXxí�L]óþ§2€Þ3i¯¤�<܇ô6§ËÕ&¿Èÿê©®oy$7W’~êlYÊŒ>æâmlêyF�ïIù+é‹]öÏÕf¥¦¬•@pÞÿ13ÇûéžÏçßúâ—¾ô[?ûóî{§Óyñ~ ¦ØG• "B"9]&aýP2ƒ~ÓâÚuWTEsP"Ö ü÷ ³‘D¨Uóµ´(Ö±YÂ6€vŸ³Ý9U7�æ5z[j‘Žl–ÕÞ.�j”ÍC4@u^ÌËb¶ëÉÆ¿Úâ»Î†?D# ,Ë‚e™±,æ ªSq80µ4ƒÈŸ „µßLáÌØn¹ÝÉ:¾X`«�Àøa© d™+ù‹‹½÷îT]Yއ²]7Å$Šepc¥2n�Fgªîé4á4�à½kTÿSó&gƒtó—@¯@Î`®÷+Ûï Ù¡*{Û~ÈÀ«®@Yï=X’Mzru8�N8�'L~J h:^bjG¶€—bH€®õg�ˆìo9’‚˜à<Ãû1úšOÔMVíÞùäø0áL@ü@—WxõáˆKÔæžõ�‘1æç ¾ÿñðñ¾��?ù0K�SL%>"“L8‘Pk_&8 ÅÒ] H\çKêøÒ¯Žü4!Nï\Ì€D²pÌ"¢�ð“‡Oî¶oIçq]'äÚ¸çùAŒh0MS"ØqÄ( ZBýL`çIv”¨÷amˆ�;1½.Ť¼yçˆMa. Ù¥�mTšûÇ5ÛŠj|çØ ¬Î«•Ý~™ëÖ¾ƒ­# À{°¹`´s¼ZícãB\]ð+X{&%PQÁЕVuùÔ»#݈Q¸}ì‡Ý¿»­}­þUðSûáVT¥ªe®¯côñ¦jÅ»ˆ´óÃÞlÕ;ÚTûåë�]}C­ïÛš„kç°Z_ÜWoë¦psþ7¿×+;í¸5éé]o°;à|þõvÉúiôýÆtõ7z÷ºp¥Ä9ÿ�§É÷t:}÷Õþî�ñK¿÷ó¿ð‹ßqnzóæùuœçy‘fP] ²@5°ãB„r–,'¿vm¢mZEf 3he ”¤ë$w¶ÚuÀÄ@2Ì7Om®ˆ êJ8  ìg}ÿ�wD;Ñ9ǺXä£ÉáÎÊÿ¨2È2»£Š1D„P¸ý>¥ç !p'1ñâxsh�´Ø%À–”ÁB£(�M™œmÇ Œ4§�>'@Q1_s & ¼·ðNÛÛ±þ>jÞ^«®ÏàfOc0@9DiæŒ)ãÙ1Ä{¸(ð¾ŽWŒmä“$'€t¥¦5ÉÁ”á-Q¦:<¬¢‘%>«²�s˜&?�à§É€xÎÛS01„4eǸS»Dm®€�šÀÛXrá5�;Î1œ÷X¼E%x·[vï<üä&žNvùi<™:'‡ÀˆðæÍ8ωXÂ\Æ’2Á%ÅO¢¼|ôpÞ'¥¹Ú¼c6å=eê M_·¦ä%ÄI›x$’�"!›!Ì%>cò§¶¦Èˆ†JÞ @`�­°sÃOÓtÂišŒPáìžz^¨Æ¤ü—4ö{Êt9õÕ�"Í—Îqƒ»õ&Ç'¨HbîènD5çX�Ð�êbl¶ÝŸ‡F\($…ËkEìO¼{n·æ*zã^<«û×ëÀÞZÑ*þsµ`yë°’I$•�— öw‰\ëïÛø’ì^P]^Ð][ˆòùËp“‡wήWÁHÙ™A´'•ù\Ö-WÜ,F�5jÔ¨QïO À¨Q£F�5jÔ¡ö&3319á¢,õ@¯èì³Õ¥³¹l-Ù©ÅÊÑ=¡küVù®r Â}žÓØÕ²�l«€Y[Sk#½_Ûÿ·Àz ¡³Éx¨·Üפбˆ9mK;�ìZyÙU j·ÁõltÕÇrÑMÊ8¯æÖù©ý�êNAÝOKf ¬C:V_i/xÖ­êï WŠ›Û:ê†Ö™°�µþö±½à­?òEï¨/7ÄÅ‹çÅ#/¤—4yEø4úã�RÖ¡ÍÚ«h©M }ÍJd®DžÂAâÌ!¬¿¾hI£ëIÒGШsî{?ýÁt:}÷éüô�ûâïÿì_øÎâ'^;ç#3E(bŒ!ÎóŸ/Ï‘ˆ"& … ¢, 60–1�¡¤’X‘¡ûõÑ�”@)T°Œóµ«åfde,»&>§µó—4æuû`¶}ß«À3¨Û‚Y!©Ù 8…œa�rË�)ëÙ›ZФ 6à-„IÜúZ&Q`ýcªÿ!dÕ®Eäv•+w“  RbÇL¦ˆMYçTÏmÍàx¬Q1"«X±ê£ý~ë¿Ï€qŒ˲ЬÜc¬gðjë~Ñ$Ö‘¥ô‡õgê—¤Jϼ9,ðé¢åÌk"dlÖ! €J–wŽf«rs�¨}nxÙÿï}åWV"¨©Í±ŠDˆ�z;Ø\Ð €Ásða‚sÎÐ(to^Û8wN;ºî{ò} {ˆ«D嘻LetÜùUõNWýÁuÇ®…·õ�ìŽi Rê[Ì—{Þ«‡ŠæµU¸XèkÞ–õöRé”×Ö¥¢{Xx_™º™¸7'çCEx>JïÙZE7ÿrìf±I¡_È÷EèሽõX´û!…üg‰ýöWK »=ßéýTH¸?Z€ÖûßâýPP`æ?qÌà¼ÿýóùÕw¾ðã?þ{¿øK¿ü»?ù“_y @E%F“§ Iß« ‰"P!¢è؉w^" çQ‰#‹3€ß£ä' ]IÁ¬ ¨ª¢‘,ìQlì�@À 3€Ãd Yó3”ÁjÔÈÖü™û'æë$¶\œrÜÛLmØÁ€¿„°t¶öYåk Ï ~òpÉ:Úù€˜ß#DnÕ� œeð<„€�Ôÿ1‹¢ g"¨HÄ2WËÍ@#(+Åó845�“›A¶_l? ($"°° àô?ºÎX”@(Û,—>¿Ÿ�©Éó¶¢3ÚHµgGcˆ.À©b KŠF˜1/3–ùMêp§“½7‘ œwñð>BâTÀãÜÕ !Âܺ#ÔðjÀV¦šSnÀuLã¡Z•Øøwé8‹{�V‚h& qRW×b…ÅÂk!;äy ÍÞ^1r!oxïᜃ÷pÞaZøÅc™føÉ—ø…¸#§œÎ`G˜¦ ~rpL˜Ãyï¼cLž!B˜Ü„“?á|:c:OpÎA ˜ÂŸÎ™°œ’�;�\ΉOàx›?Ÿ€lÅlŒcLî)ºÀ9ï&ïKtB&à,˜斀`Šm?MvÎ%"@vr¨}m™÷—à½Çé<á4yxïÍD#¢ÆDê1Øùýö»tÖÖs¼q¼¨ñ!¶–X?aÂÔç"’ŽA%&B Ñ)#ÜÚ~€È:ò¹Üƒìš£$�½�,ц0¤ ‡ò§"f#%ÒUONP«‚?Ç|ÔÈ�Xã¥|Ù�6@|£Ì'Š+Nëv�îxIŠË€*šH,sRÈý‚†`b T”ý™¬e›¹�2I@d*û�!¦ùÂe›­›ƒ2R é¤&‡É€Q£F�5ê}«A5jÔ¨Q£F�ú¼Ü˜MfkÊd×reåHɆl~.àjs©f>u9Ä”ÛÃ,{`�Á…šá¬…! ÷ÅÓïú…·€“^ÉûÖ- Uÿ7ÇßF ¬÷ØZÌ[ÍU‹ê.eÕ *Û ]%½l•v¶ÝµFwSϪ}BÄÚÒžÙàC¯UjI8hËÑ\¨mÌ®µóZ‚Aóú q0—¶Sg3oèö}¬コÿΑ½ù—Ã)°þ#oi“û~7 ïh ô¡c}I‹ú³ö¡|ᘭ×-½ºz½ì(©�înÛ:�†èâØý¡sî÷½÷ßñÓô{¯>øðw¿òµ¯}÷|>_û0�NñééU8?=ÅÓ4EÑ”†,šD¸vQ‹,)%ŸrQU(±S?�DJ�5†¨¢ª1F0-pÌLRS0À4ƒ7λN ,;.Ù_• Y•­ú D,×ݺǔC^‰cœò¾-üpì©f7¯-»cc¡�¿Úk%SÊ|.ï³|w6coǶچd ó�€óJ X‘r¨QÜ«‹¤Œó&W»»géíÄ¡±¸dp9D‹±mO_í«]Ëð¤`/Çœ¾Ï}dï«ý»ÞCÕ’#²º¸(àaí4ðIdŒPÅ5Þ¡dÆgu¸�³}ÿW0Ï·;&îlÃÛcÍÀŽ‚°¹P•ß�ƒW•;DŠ•z”š!OÌÝ'o©â • v*²^ŠË``º!†0CØ@YŒà<ÜbYä9ã>FÁ²,€O§3$Øù²,8?a™g„xA”PîÛ˜-n`šN8=�p>�à�ˆQ0§¿Å(PR#x¸k@\ªcƒµÙÆG掱„XIœÖ�Ó4ÁOÌœJAóRâ7B ¸<Ï ñw:�,Ò`š0MŽ�ô Ä ¸7å¿÷ŒÓÙcš’k§~AŒ9Z"–sÍÔᄊ[·q±| R£*ÿ½Â.‘/(¹Heð›Ù\T4�ÚÏ+ŠÎÊïþóè<,nïá'7fÞã|~‚gêì§“´Zeß^½¨×}Ù"“�Ý#¡ùÁZ &hЪÜi XõV°7ñÚL6ØõׯÎïÖà{µƒ^ce9ײo¬V{å¦YݽÚÛãYíw­3¿]/!5ïW£õKcƒ�Û*\Ý9>ÚÝî^½%bY¢´ØÔâ®9²1š¨óì�ñ¸Wé¼§J>~!>5ù¿¾›^Ë¢«ý»Ÿô°¨Ó½ýM·G”ÞEßêcç.Ý{öëþ�{ž ô©Œ“nþÙb.ï‚åÒD†ÜØ3ÿ+ïýMÓéOOOðc}ôÝŸúÚ׿ó+ÿæ¯þQY^òIøä“×ñÍ›×ñòü–°DU2Ëþ¨ªA¢Æè4šy>AV8{  €�g…­ê �¡ÊyýÍï³ÜetÛT%»~`ŽJî5�•‹*VÂ^ Ö.ù×tÀUaª)úG˵y{½úÓ¶ç�e™{?•Lê |…%` fÍŸ•®-�Ö’Šº>,XBÀ’@ââôA=°¶Î:p«\n“ê·®9{÷ÛmM÷7F�È”í®�‚>·;[±›å9’]~k½¿ŸÞfn·€}þ•â…s!°÷ûÜ®#x™Ó81»ÄÐï²²ê§2'Ø8ºd�/˜Òvlߦî%¦]õ1€â·1PªFì!&7)@yvލ_µŸ¬3œŒÞ3ÛÚ½‹*°†L$@ODMŠçVQ-HÍž<ÛÒóÂ)Áæ¸H(á4§ÁÌó3˜=b øø?Àó›×Ë ‰1½ß€}ï<&Â4yS´‹Â;ï,r�Ø8æð`‹ò\bs,„Ž%;ïA`ç0M ¤gUIñÆ.óQIQçfLË‚°,8ŸÏˆñŒixçl_ê@bR{‡hV^"„eA™oæ´°”¹µ½ê䘑¥ ’×ND‹¬7wï|²“×4Žj*Ð(PáäÜ!‰ FÑëa@µ6ks{í}¿^Còßs´G«f§BÈIsËrÑê6³Cš(¢ˆ¾]»ÖbJ˜õ}´väkmÖ"êÈ7åz—€t—^'…ƒYFc";h£ÜwlãRÚ ;c0€9Ð0ÄI!ˆg�Ô/emkÈ<ÖŸ>µ‘àœ�ÿÓ4Á¹©Ì×Q£F�5jÔ{òœytÁ¨Q£F�5jÔ磜cL'&Ê{D¾£†ÙÕ‡7ŠfJ™É ”‘úh6—Àã&rÇ`Ý2·CÈ¿6ÁU÷‚ân½®,ÜÚå;ïÞkËþa¦ö%N¡ü¿¸ÝëáQo{æíUÇ­=þíÍ] *ÏýÒú�_ÛèÍŒîÜß´°_EAÛì‡ýÅ�£_“7è3Æo‰µ?Ç࿾óæêfßÞã};-çñµ—7�¢¸F-ÐG&Õ]m»«Gv~xGû�öÐfiÚ}¨f‡'ö>–ËýELçÜ{çÿh:Mt>=ýÁ‡?ö…ßÿéo~ë÷¿ö�Ÿþþ4ùx:ŸÃiš¢s.ªJ˜—%ΗKœ—%†°ÄbQ(Ö/DUÕœ�Þ‚ãÕ‚}ä4 ¦K`9³�|p¹hÙV%œ¥kgŠ5 Æ%Ùž>eqç>,kZ²öŽ19ì”ëIöÍ+;ÃÔ]»©ì M¶{ z·9ÕŽ]R9›=¸Ù?“©äSž/ób o"'018)¡ó1å»"„ó<›¢:˜"¾ÃÛëMV¡®µ¬¼ÎDï¬}“O g—ΩO±^ ‰Üa÷/BRn%2ˆ•-ð�ÓNÉž7S2Гb¸ôß  ]ÔA²tÇŽ’>å‘Sêß=ÅpVcGŽÍï¢ÙÀÇj¹^æXÊ,Éñ��ÎÜT]wŸÇÌEoƒÈ‡÷y®•ÿ1˜^ŸòyáØsµ‡9HHTÄ 5 ÅMSrŽh"'Šó„‘gÈœ2ˆ\i£c‹Rà†�“'¡õ‹ì.r"Í–é<_žÁް„aYüàŸà“O>Æóå1Dxõ�IÊy›#/\ýÓ½²¨pò˜NœgbÎ Á¢4juýHKÿ—9 „¹ÌAç|ÑÀŸB"Y 8,ËEIJ˜ÃƒHUÎg¨ªZr¼F4"�»´Qý<¶5A;uwLDˆìä‘Ï×�Ö=f‚÷¦X÷~Âtš’<«ØQ@sO€2A”¡œÑÆEH,.%äù•£9¤[—w 5ذ^Ó1׈ WH] W!jŽ,*õóƒb¹Vô€–Dœû«‹+[‘2 ‰›¸‚#"C&,P»^æø�(›ÃLLä€r­i¢È18ºB€ÆDLId Àœw´8mØúij¹º&˜¹Œn>/rêÇÉûEq‚ó¾s95jÔ¨Q£Fýè× Œ5jÔ¨Q£F}NŠ8+úh±ßè ,··|ldHÇË›2‚Ñ�èä¥;Ðlª~£W`Èš4´�®9]ôÎ\i"P—5�m›éÈe`­²<ÞWÆsèmÔþ/~kßO=1‚ÚøÕz;àÞ¼‘ŒÜÍ‘£÷èÁAQFt©cœ<ÞgýÿVóþ�mÜuÌWº‚nGÙ¿«z§¦ö{D z»m±ó+qt_Ñ#Í¡~]ý`[9åp'ø°>oþNïh ig�;à@404²^½'<<µ„˜ÿ©cþ#vþ÷ÏçóïôÑ�ýÁW¿ö�ïþ›ÿí¿ü�&?Å(AæË,ó|‘‚D³ê•ù2‹D"Šª"˲È<Ï2_fY–E$Fµ×‘”É ÀA('25Šn©2USþ23¼3�Ü9o*ãàP±�’j5«ë‘•£%=­9Tå%s] äE (CÉÔì¢M¿çüçößÕT#&@¹€í­å|@Õ,·¥µ8w.Y‡Ÿà'_ˆYÍžÁÆ«J™|EÒ5)DE€íµóå‚yž–¥ôÏp— ùûܦܮ\Î;œNÙêüŒišÀ)n@)$õŒi»©¨”Ñ)å™ Dö©m¹-=Q¡u6¨$i\jz,δÊÎ6ÐTøÖd”Ç nÊf_�£Y’ ÚF"P#ÛöˆÄ’SŽf¾u}™nn"rD„*×ë°äÚës"%dð?ÇAÀÈ,Ù "«ªó9e®9#Ý:†A`Ö¦\ãN!PS.³ƒ¸ÀÁ5ê—ã*\&´ã�ÎÁ¬&Ïçc"72ì‚.xý ð墊Ëó3^ò¯_¿Áü|) è)Nf·ßÜëH~bˆz�ŠÍÑé„é|ÂÉ{°Ë® ɽ!„rÚŠ(B”çÎórJd"³Þ÷é¼d6ÅüÉOIÍM¨lÛÕò»Èp!»x8 4´÷µÔßáRý—WçÄ׋¤D[ËþÙ"ƒêÞŸp>W‚Ž�MnkhÈ›0€ Ô b$Ð bëŠÄDXXÂκлŽìÞG6ýÓÎk«Í-v‰Q)Ê€ÔÖJ©!Õ�"]?V®`Dû4ÂÚOº%4$€º)îÖJN {Y/£½Ç\X¤#Qú\áPÁyv\:vÝq–ò9"_»5E£ä–ì‚flÉdíºæ½³ø¹óÙ¢+Ü)9ˆŒ5jÔ¨Q£Þ—€Q£F�5jÔ¨ÏIåÒ0³ÕUÖ<ÀW `Ó"²T…T�ø]€'Ûb®ÀrÃj€¢nw[¼mGÝR/ÖÞl¦3ó¿¾�%LY=ÔkÿEUý[fi~–Nw�Km5½xl¯" „W`ÖíÏ„&Gúa·ón¯Ú«÷l#Ç2ÐÑñ<�î®÷�H¶w¿ú�îžoŸÉZðíã~G‹[ªÿ+}J�Œö�›½ÅB=¢7Ï·ývÓ‹Lßí€êΨ­—”n ksÞî;xP·<u*ì=ÿ±óþ½Ÿ~ÿ4�¾ûôÁ‡ßý©¯}ã÷>øàÃ�™9øi çóSüè£åÃ?ЧiRf'D¤2‰†ÕÄû¢Qºˆ‘.Ëœ’\Dç%è2/º,Ϻ,‹ŠDM`�fÐ7EŒ¡üœâ±+ð¿c�ÁŽÉm™Ì'°ã¢&ϹÙ3YÞw¶NÎ×ê€7Ó­g"GµŒè#Ð,…yˆ(g£ëê„"Aåy›ïÞ�VnÎ{L§¦ó„ÉyQQ›/‹�ø¦þO6ùÜO«lu.Q ´›/¸Ì–WCHÉî@â”I}”—�UÕE¥LÀ4yœNgË9?M8ù)½8@¢¤¨ .1G61ôÐ<�D„È Žœ|¬€¯zb´@{UK×ßçéÏLPõ¬&®`eXB!ä9Ò’ºëeºŸ‹Š];óýMͶBïŽS¢\·îVÛóþÌ6'�|¼�ªZj›bSôç{’•:;GCÔ‹”“.šÀÈJ'ʯGž£DpDάÅ=\ŠÊpE•n㮣³ GrF{ŒˆÑˆ.™�Sç”+1a™!"˜—ó› Þ¼yÆóó„mÑÙ¼H6ômt´Ú¿×(ˆR­îDçáØ#¸¥œWDÖÏŽ~òK€÷>,j¬‚÷S© “?Á{oëÎÁ{�é“ —ççâ*á�‡c×ÍKJ±%µ±Gá‘ 10w"ðRÝœ‹eŒU{·³ý·6yjH/¨n&E-O…„b<»z~Q¬cc�Õ(ë!×¶ZF½vvúí¢¨ Á92±Âù þ3»´O#%Q‚’ÅháJwNaåü%%ˆTÀ¾u2X»°´n(™c &€®Ý—d[þp›X¸Šõhc3@œbÏìE¢¡’€‹-MþóZÖ’p¬_}‰Èð§Ó]Ÿ‹F�5jÔ¨Q?:5£F�5jÔ¨QŸ“Ì!Às‹Ùw�Ä2±z¾Ýy ج¤� ´! ¨Òa€¤½¢üþ¬ì;lþ7¯;οöª’ǹóÊ5øß¾Ì£XmÉËÑrôݵÂ=„7?Ú†U?·ØÞ Ž©¸¨nœîkËArû½êê»Q|]�Ýá.ïÙØËºþ-ë]Ûõw‰úösìúôÙw¡·oý]3�v,ð¯¢^Ýð§òœÞf|Û“˜nß–JÔŸ�ªý�sî{λïyçÿÄŸNôÁ«ÿðÏ|õkßýÖÏþü?gæ…ˆ¢ˆ„e^–Ëå9,ó¼Äƒˆ„cˆ1Ä£ÄED„9ù±” “€×&õÖÕ–ùBH9ÖɆ=Û ·jûvíOÙËê-šÈk?X”U®Oç3Nç3D"&?™µ¾.—g@¡Ë´/yí«uOÕlÀ³ºía&sH— ´Lï¹ßæîhÿ‘ÎV¥)PËWº|zçL½9Mþ;WUà™ÀbhÜ´]2ð,“ $Ú,Ë‚y™1Ï»Hêš¼í#å®vñ=½Uýä¦âRpš¦èiÄDœ Ñþ 21 0˜AD*Ö÷Ô¢]i,Ûk€9F®Ì5Y�y¹­Ä §hî}ìw$Sµí�ÏPf—€Ø¶ŸZ2  Ê…‘mßE¤d¬¯‰ùýÌÜÖn o½4Qï’Ïß›éM«UG‹=A•‘"ÍKß8ïÀìàQaAuá@r|ˆé+�'Õ·‡w.¬ÖË°Ì .ËŒy¹ÛùÒGœÈ% ˆ¢GðÄ*Ž•hU¨Ÿà¼K·Ô¼Ç Å:_Z}òf³¸DŠ@Þ;# ø 0�&œÏg¼zzÂsrÛ¨ñiq%†�ŠÙÛ‹$ÂÊÍ€,?Þ©B˜Ó¼we=Œ!€Óœ£•*Ü9Så«úæóAñ À! ˆ–ûç¼³¢î‰ � ´g;_ãGÚˆMk~^KÚ5%»šµ$W¾<¨!Ljäy,u-R-¤çŽ ­ZñLšhû§�˜‘ôy¡m“ˆ€�êRQÈ ¡&̉¬ÆåüÍ$&†r%tÀ=¡»F!0X\ù¬§ÐòYFsŒ´œÐ„¼IùLˆ“;…ƒL€EA°w…`1jÔ¨Q£F�zjF�5jÔ¨Q£>¥ªˆu¹\´Xô7Ï�K.j+Ûº$û^M¯«·ZT’À^ׯ.^LW¹¶Ë×·þ¯½®íôæ;3`Q¶´‹HVµzû¯’R\mßû(�¡ôBà8ÃëKúóÊöwA½o„ÖŠã×G™6í{¹²úö õÀMá]@%?Šº¨2hu"ÝÓ›úò�Ò;éå+$ºoÎÜO^ª ¿�(¢÷OÖÝøŒ·<èv/*QmðÚ9÷=?Mß;?½úã?øð�¾ô¥/ýÑ7æçþàÛö—þÙ¾ÿùä“�åùù"!„ 2³ˆù‹™#3fÄI$¨jTÕ MÞü¼xH“Ì"{ÁB±“×d‡ží÷s^t›sëÍÎ�;eëæZ§Ûìè òæÊŠmçÎOOxõêˆçÓ%åG(€e¾ „ee¯Í5¤‡Æ1¨ ÏV©n¶ÍL./5ž"S’3Ðw¹ Yý¡SROIYœAåX²Þ%9Hcïœ/qÒZø²Ì˜çó‘·Þz[Þ~ûyýõ×ó4Ï’s’çÏŸ+1 )1)‰ÂUɘ £‹!ÇžÑAº1àåš:P¿Zò—8“B" áÒÝ£�³ñ¹”ˆ ¬ÃœiÄ/€2!ôÉ[e½É!A¤Í€;¤â¼“­¿P>GuÔQGõUªƒpÔQGuÔQGõ¨k úº&%àZ¬ܯÝÂÏnÛ ½ÞUG î¨­bï¢ÑëÔ‚î@× üUFn$|˜Ÿíûç3ÖÀXSÀTçÑ܉ôêïMî›=/1#1÷¤”×èó <ò"WpØ{‘�¯Ö׋BݼÄĈ1TbNŒ±’2B%eX›ä”.Æh!d”Ï,ÎÄcÿ.ýVs[›(¾‰+›ˆ•ŒÇÈÃѾ›¨RݸÑ0HZ,YO.(.…�ÐGlVÌþßæcn t™ïój.ÉâvN¶îˆØ:mó~Ñ‚e™°¦ërÆ9Xl‡#ਣŽ:ꨣ¾JuŽ:ꨣŽ:ꨣ~ÍuUQ¯PIý¼ªÖ:X�:5Wƒ{7à?Xî‘åR…÷èR ï û~Öû–Dл0WÓÝ�{Á–Ô=ÆFû�{û‘h ¦óÌúAS¯ ÷`¾�ÁºùƒjZÂø½z†ƒW¨û”ÛE£Ô[ccx¨zyÚbœ®¬lHÕcZÓº:�è½Ú¸/™!Ð��nþvÿàÚÿ4ºÚ‚W”ÿ;àÿ¯F®¯t¯¿°¹èž{v­ÿÞß–¯ˆ’_í+zÿ}¹6~õî ]i}zùÞúÐçÜsÈBø”Cx?px?LÓ{sŒïÍ7·ï½ùö;?|ó­w~NàCÌóé”N§Ûu>Íëç”sN"’$‹ˆª…cP�X8U˺ žÇÇÅ>†‰‚œò%ø@„©ûóZ-óMío Žˆº5690!`&¥ªÌ”b-½šâ^!*š½qš XD®Ú”o­ÿ/ ù ÀÈÌàq+‚×^{/^¼À‹»xñâù `×ÁR:´=Ruµè•àÅ¡c<nõŽ!Áæpj÷3‰"¯É€|ÍP5≿ì^¹�� Y–¥:pñÍu"ÕÿÉ}K-ŽÁÇ‹;…‰ÞŽv§ÉÈ.eþQ$dÀû«d© û¦p/czÁ™áÎú:8¸[IBr·€i�Xã„5EÌSªãbŒš°ëIÓTÇBœÂÍ N§b`ˆ*ÖeÁÝÝž?�çÏg<þww/œØº¹¶‡ªb~3gU2R¹?I|~Ôªò.„¹Ì 9G¤”1¥µªó ɪDŠ4�ÝOfFv;þèÑ=€bôßÄÝ1‚ßËÓìŽ ‰+Y"øùíYîWðܨ™[ pfJ[d'éôs_ú�¤SÆÑ–L´%S”vî‰ ½CA™/†¹Æÿ,Ž… 6VK™ à_^[þ�´bâ?ˆP_AL|ÌJÎHk±�A‹‹A!hµv5Â]†P3aYœïî8@DpçÑqÔQGuÔQG}5ê uÔQGuÔQG}IÊ-aD?o๻8¨m¡è¸ßª»{4zƒí?,\J¼ï˶oàÿ`“_ðíü®‘ºí%©».Em°yQwìvžÚÓ.Îñ:ø¯÷Ÿm²¨/TýÅMa€è¿ø*§±Û&ÛV^öEÏUÆ‚í¢ QdïøýåÿÒ¶ÿõ$èÞ¾zŬþ÷Œ‹¡ñ«á—ç£c ~}vúzOßÖ—¹ž‡úUÏî×5óî€ò÷€ÿºÓ=©û—îôÝîpDô‹‡!Äâ4½?ϧž<}òîÛoíÝßýƒ?zÿööfIYrÎ9¯ëš—å,Ëù,iM**BD™‰ ¤Š¬)³$²ˆf1„Y8ˆ§ª¤µlêŒå¼Teeœ"˜Sœ�&³éçœ!$Ýô§ƒþí=E…Yþ園‘b@ƒ“5@ªÄç)q€B±±&„ØÀ¢bÞÎ¥›gv¬ç«J ÎÙ2¼ÏËwwwˆÓ„ÓÉ@ÅÛÛ[ÿϧK8P§j–Ë®Z�qzp àÄuâ«S¿FͺYÔ�#“ALÕZ@.Ñf#-bÖÖ…¨F€ëê}ˆJ‹`»óp:E—¤#VtÄ s ˜0O3¢Û¡÷DˆBºh@cBZW¬i­êÖáþdA¢TmïSg;}]ùÏ�Dëðs[ëÒwŠ{„¿ÍŽÝÍr¿o.™å!€àªãÚ‡ØM ¼�UŒ•Á@pu»©äûqº‹ÐÇFŒöäD»�OC_+Ç碄ðÏíI)ýÞ«8Œ–ñµ–v­ u¯IÌ PÔ¢ºÖJüHkªVñFhnÞ‰»xû,à3²XôF–TÉ5ïÝíõcŒà*#¦Ü�æ"aNZîgt°—ÚýC¹§“QûnùÊÚ¤äTưµu±Ç/ó× Æ Ö5b™f›O�\!Þß%Ûø1`M…csò4EÄÓ 1äÓ Ó<7ÂE¿ïÖü-U\>z«ÿ±ßµ¹/es;Pÿ ö1¿.H넵ÆpkmŒµ×fGŸ£$Dr% q1" ¨ÊüC¨®}LKùºpø¸°Ã'ÀcXÊ·+¹¡´ÄiŒàYOÆùDœôŠ‹uoø‚$‡2Çñ3’rnî$ÛˆF¨sjuS#9� 6/ùX¬mç¿o”(‘B„Sæ+DsÁFjJ8ŸÏù»1{ÔQGuÔQG}Uê uÔQGuÔQG} JU8‚ˆ•™ìÀÚUѾý�ýçzйnp>C#ìÒ&ï²üü’3°Rg½ñ¹¨vœ¨˜ìk‡õºB¹~ë*NhG¬×†šnßô»gÜ7øËÞÅ]ûÚ‹ û>øúš2ÿz/Øtì�ž[DbP²�i“·L¸§°Õs¿ì£ÅÞ„`ÿºz÷cÆßý‡øÂ‡îaæú*güË÷—kbùþñïèîÑ7Ä/o�ÿªçû7ÿÑ÷„ÛutÿB7„“•™?bæ÷™ù=ñ½yš~tûôé»ßüöwô­o÷Ó4iœ‚‘0‘±€DD³ªŠš•Kñ”WOW ˆ…ˆ„ˆ@VU­�˜Ù1×\büÔWN+–³©•C4 tž +@~±ãî׆i|Ì“âznŠÍ’¯ SðrÀ«j%`™¥³`MfüœØÌ’ÝiÀªp«À ͶÂ�˜Áþî×>O¦¹¸Œ _J¨*öä­iµx ¬_S‚xÿLbQ9¯–û~1&{å?Õx„ø7À¯Ü¥à š“6Üf½ª_½_缺 º_îŠ2ÞÀ^bIGÖPoÿ<îwŠËC±C§êö Íæ>eµ*Â/ç‘–M^�Œp©ê/DŽ­@—ìS¯¹Ùƒ·8ˆ2' ’¨Æ“0�Ûx´No@¾ «»8dSÒ'ÉÕE¢´MßNª vâÃ^»–¹ä³—|y‹�`p °Ïµ�û\¥Rü%¨�¤d± @¨÷SDYU¶ó7Õ¨W²�q 2¶Äͳ¥IÁ™+ù¥Ùç“MÜîvRæŠåîçóÙc6š’üöæÄ%jÄæå8… .W+|j$—r¿ú{¼-)$«)a]0/6ß ²:iË]Zjˆ°Ô——�“ßÛB`6’QPHTDä�;ïØíæFÞ&qŠ˜ò\IK6f¨¶Ùpïê~­®'99�Kj| \]¿µýï·*@}ÿ½‹Ø�®/w”ضD¦æd� Ê5j Ÿ—Ë|_Æu»×tñÛE‰c)dkK‹„QäÈ�ÌPæ�ÒÏÄ †Ö¹FD±¬ælQH*¿NæQGuÔQGõ«®ƒpÔQGuÔQGõ¬þáÒ4ÍBÐÂOÆ× æÄâŵªb®µ� JÐ-`Òãq5íáåK5¤Þƒ¬@<х寤×Ë7_WìoϦ ô¯8 œãù>déMÇèžõ?¶Jõm^À/ÓwÆS¹Š‡êUmüÎ÷¯™îoÛb›¸þx`¸×”£û ¸«�øÝóþ_â„õšÕü#¬ã¿ð¶¾Œ©ØB^]㯿þÎpÍQäÞæ¥û¿§û×ÅÌ?aæ9Ä÷CïOqzo¾¹y÷�7ÞüÑ·¿û½8𢒓ª®ªH8Çeš&™¦(q ÌêêTUU%ª°ªj‹‡'(CY¢ b%{o“õšätP*–óU2WrðÜ�”gÜÐ ¦yáaÍ+–å\1bb§vl–Å"f«ß…„À1L� 1˜ÀºâìÇÌ\U‘Eq¦ qš0Ÿf'4%j‚È�Ü@¼>7¾‘Ê�,çeAxþ¼Sj nnn¡"ˆqÂÍéOno±œ—úyÅ’9Nô”õT´)){BÀ¶§ˆ¡gí›Y*A¢gf).ãY¨×UæuI 9¬H CÏ)C³ºM=WàˆCD`(=º¦Ïw'WžÂÝbœpšçÐ[S—v`A´Š ‚Pk#ïODT[©± Úö"�c‚�lÜ�ÿ¡?¤:ô1%SœcÄé4W;óBNXhuUt;_‚‚ˆ!d–ÿä$€¢4‡p?ÊÆ™¢SìÐz )tà»ÜŒ0ÎöoýkHÈW(ýÎïI!TÀ|K»q·¦Ž$@îÁÃ>s]FrÁà¾Q>Ÿº¨Ê�Kê½4ØÞ@KòÇM®ý9"@B@(�ÓÇp]Ï}Nfèp=uýЀÀÖ¦bãý\3u×Q¦É#.<ÆcM+V'uÔQGuÔQ_�:GuÔQGuÔQ¿¡Ú>pšæI§i’Ó鿣Ïð‹ú`îÑÿæXú5ðÝYë_1o§Šé_~Ý]à�sÛ³o/¯ê»�L|kÖÿÀGnN˜6ê™Þ¢_w¯­~ÊÎz =¤ë÷òZx:^öBxç#pcÕýÓÞÅi·-w²vÞ²µ‘þXÙ?p{.ìô˜öüµbÕ;@õ}ýÅ}�n{y Ôƒêñ÷uÎ_QƒÒ}hºJð`? ‘?Šaú(NáÃiš?8Ýܼÿúëo¼÷�ßùÞ»¯½þúóœDD²©ïEsÎÙ¾‘s’œ“HNVfNÌœCB”ƒ ]77ÃÀå¬*ùɆÍX<º€¥€1ÀÊ@¸¬–õ«šë'03D1D·ü ¸½¹1P„Ëyé€  ™D&"æ ±SxZÖs@”ÉÿmÀAQ›ÇjûlŠD ‚àùóÁÓ1D0“�þÓ„yž1ŸN˜§©)¸Å>Ë@‘vÇzàqÏB5÷8a9/ £ªH)cžg‹A˜gÌó §›SL{õ*ûßËñsQy’c´“ury>2ÄÏ\vð‘t£ªUe­¢ °‡9c]×Òg«å·ˆ¬ÊÁô¼!"†P󯋭x–¦úe&²ÔòºÝ¢w@ˆêÜžwÀlÝ®ÝZ,®ø—­°¦ƒkèIˆ5»»ÏÂæºyi6ð�|G®�S´è‚ùÔYþ›êÕüwS±3¦®å¹¸«»„Œ€q,¹ZŸ—¶­çÖ©Ü­?5õ½Ù�·¶éUÓjf@¨k‹ñËú"íÚuiÁ½œ¤¹ztý¾9+4KôËþkŸÁ� > ó”=Š+…Vo~�—| ZwPÁ1΢ú÷ˆŽC_¡�Ç9[삊"ûx®¤é,ß )°bDãøª~PTî…ER�ÜcÅÕÓ"ä �ú’M•ðQŽºG×2¼‘]y®uþ)Ñà|>ãùó;¼xþŸþ:nnoêg¯ËŠ»óÎËÙÔÙkjŽ#A!›qUˆH<®@\í­õ}s¥HÖž‰jDAœ&̳E~p0âKòùD($•h U1H2(™AŠÉ´±¢ï 0aãnPˆæJá@70>¹›GQ¿'kx“là¿«ÿE²�ÓPDZ_/1ÙçËkÑ#:$sõf ±Í/“¯‰âkËi�s턽£³V"Bÿ7÷¨wv ö¾  b|6ò¾Iˆ!�ëI[#­}l^Ïmm Ö>ª Í "jqi=~A?ꨣŽ:ꨯP€£Ž:ꨣŽ:ê¨_s]æ'{¨¤o½ýÎ�~üéÇ k¶çWÀæQ�¾0ôn #�N×Wì{PŽû? dW/ÀÁØm°™×‹oí¾x8EWfí:ì©{ú³¿´ÛÉ {*úKÇý¥åëî�~ËE·¸ÿ\FØ_¯ÞÕ¡ |öؾ¨z„Ãcšå×;ίžÏ=jõíUPëŸã8zø3_¥ÇÝŠ_}ׯ�@±Ç#¢—yoe¤ÔìÝŸr Eæã4p:�>¸}òä÷ßzûýßûþ¿÷öÛïÜ™_$ç,)弦5§5çœs^—ET‘˜U¿A„"…`êÿL„Ä`iŠÛbß; ĽT²öêÛ®pl¸Õ°73 H&b ™vÊA@‘òE 77·5Çùsþ¼ž—E`ÛÎQ‘cDŒÁsº Ê\�ú¤~NS*³�ѤMM\¬Ç'Ëõ!`>M „w`%#%.!Wu."ƒâ¼‚ ªöºMtÊCtÀ“'OkôÀ4›ê=­ ËrûÑ Ô†»(ä ÈS·~÷AQ™÷wTÊâ8ôcòc7UØû³vjXB; m,Rª ÓÚ.ž£@�]¥ên J®˜V¤l}¥¯D p‚FoÃÞ”à%2^ˆög†þþò,‹:�Û£³ìvÿÔòè ê¢Î`à¡mÌl•Ý–ÿΕ´ÀÌ�+ý8eAZW³ÏN Í€N„¨ŠÀ­ïHj‰¾ár}í+l¬ÉÙ‰§�z®M…ßz€qv jñ+íTõûyÝCì�ÛógW©ƒvbÂx¬ò’zÏË|Õ9 \~]ßï6‡ élæí<£ÏeÒ°(}PÍͱÁ Fh(®RcÆýš^Ä"l�Ýf/ÕZ_U}>äëý·vhî ØÌ‹€Ôqµ]mn7›vÉ‚Ëj¤¤óùŸ?{†Û›LÓbWè¯ KJXÏ RJmÊábí(1å5!DH#_yÿ'jM“ÍëižmN 6GO󌛛N§#E¹:Ÿ×ÕÛÝÆII¥Á0ߊÏ9ªÙ’ÄkežjýQºót˜G²÷#Qÿ§iBœæÁý"Û"…¼–S)kŸ‘S¸îcFÅ}¹7–ò ıËþш_êÿŽ1bšf̧Sç2Ò»kè†Ó; ì}Æà–°‰,Œ$ÄÄÈ’A¹‹ ðH&�˘&Ä:T"�̓í˜m­·qU�bÎõ¨£Ž:ꨣŽúÛ_ਣŽ:ꨣŽ:ê˲1 Acœåßüö�ÿÿê_¼P‘Ûm¸ôe {ü‡?±óXø1ööŠî0=>î(ë{À}ÖêýÃLÙQGêYÿGFè=êçzH?ùKaöËË�_ ŒÞÿ­æÇ½àÿKŸOyÈHÔ·´w"W]�ï=ר_| ‰¯Š0?âÂ.ñþ=]¹¿Ûx£È!6ö±e'àþ+¹W�=fú ‡ø!¿ÏÌ„ÞÓôÞéææƒßú­o¼ÿú›oÞÍó,§Ó�ÜÜÜÊÍÍœcŒB"RÕl.ü&í—”³¤5kΫä,úC‰HP,ûUE%kÊIr΢ŠÌLP4‹{Ë oªæ¨I4}¾e€Õò˜MµÝÀuS6:èÈ6©I6Å¡”dÿ'ØÇ1rfWHøcvé'¬Ëâ‹�1Å:Ÿ:°«œ+ܹ�èÕñEÙ8ZÿU@²Ö/…1D Bˆ˜¢YÍOÓdï ^´!¼]¾úö«MYcnùhA½àÅ ÏRwEé#²ˆ+N-ƒ›S¨ÀZ…ý3 DI„Èc¶»Мk\`±äQëíð1,™F qCy¬ e­ x– ©Äˆ~Ú6[úè÷"¸K�²7¥„”¥ªñËJÔÅ”1Õ�î}01¥C@pÕ-:@J¡ƒÊ¿¸YPGØ6Œ!7Ëì¹1X[91&'W6 ˆ¤8Ѐúw‘lÙêd#¦Ö-ícp7‹qL÷Ÿ[,ê+sè§¡µKߎ$c_vûýÒ�ʱ ¸}¹¿Q¨ƒ¶Å*¿ŒM¿®�ÜŒ|Å¡÷?joM^¹,D@—²OUÝD$µÈŽrÞ¦¾·ÞJ™Ê;5 Ù�Þ!—A÷ö¯´Cž`P3‘è†c3Í�YÀõÞi�O˜»>Ý+»�xUÚ\ÜöŸÈß*F²}n†¨à¬+²|Žå¼àùéä*÷‚�ë”JÄ�t`tîÚ¦'¨4;ƈ˜-º%€l‹ñˆ˜ç©ƒ™q:͸¹¹ÅÍÍ ¦i1¹ú¼9"HV�* a±9Íq �PŒ˜&ñaçR¢:Ú¼e.7åz*©Ç]7ˆØ«PpVôS_ñQ1пÅsŒêíæu©D1Ð¾ëÆ¶}{‡›âÞÑÛîoפ⺱ý~ïèQÁx¯E‰_Àz‘н§l>Í�8èF�Ð;fˆ”ø› )‘@áË@¡=ꨣŽ:ꨣ¾°çÌGuÔQGuÔQG}IŠ !rŽ1f&þ0Cÿ€6¹ë[�ú‚óîåÏ_fÏ÷Ø„}]ïyÚþ�Õúq`­Û VðfãL°gT ›°d�vsÕ�­ kï%´÷®«¶ì¿J¹óuþ5ßöÇ \W¢¿B¥kq´Ó€—óØ@Åc¿ùE »ë§üKÝÉÍ`¼Jxéþ¡Øíxä�¾‡ð@׈¾ZÿýÕÊÌŸ2‡�BÆ?œO§oŸ<ýàí·ßy÷ûçOÞëíwžŸïîÒ³çÏòçŸ}žî^¼Èçe"ǰ›g5š˜±6­"ª"ªˆÿ]»×hýSDÔ-¿5¥¬†‹¸Í/¢ÏÆ&»Z/oõ*êÐ�M±[~Zì§.�[¡ fo·O* ¼�Þögì¦Ú¦œ‘7êÙ’_²ÚË\l§ÝHÆé*¹Ý%ÛÚ3š ) T ±¾ïb5ê€øQYÝÀ�4´õV1k€Ôº¬8ßÝAæÉÕ£f =fWgHÈA´wRp`§Ø<_ ×^¦žûñ§a¯bÿj1씥‚ÇEÍiŽ Á3Åí]E-Ú÷®ýÆ€´À� d®0{øT¡ñsH™,‚\Ô»ªÒ.Zsß{ÀÐ åõVùjJúvG‰æ°±ÂνÒXÇ6­#¦=’�9hPës}N½–ñbmÎLŒdgm@\±]�vv„Yg‡hc¦mL_™{_únçÔÞ:u?.®ÍÎP6žÔÀôœR×ýh /ÖaGK Gý äŸÝåć‘^ÏNÔ鯵ÄØÏ÷Ö‡FjÈ­Ý`¨dƒaÛ�E(›Å ¨ —YSv-¥•›Æ]; œ S¼W@ÙAtbîÚW«Â:evòF²1ƒBú!P kÉÈ®"C"rÆš’‘tD›~^éÇ��‹ëP]^ˆbÀTìüÑœ'LY?Õ9.pÀ|:át:a>�c4‹}6SŒ+r2W�µË"Rêº�Í\«ÕM&K·¨®¢�%â:g¸n$�äëK·á'Ÿ#3­/±R›÷b‹ h$�MÙ:þ^Б$ú5�.ìû�ìÃ4ü>rÍ�¦›uÞÛûþœ2RZ±®kuˆÑÝs`„±@s‹Í©¡Å8˜/Y€œ“Á4×!BLŸ²ÎÇïãGuÔQGõªƒpÔQGuÔQGõ%(0§1�¦9‡ßÉ úú¦¨ÊPÝ� ¸îûêïC³ãK¯€é´ÿ¹ö£be«õßÃ{ôÒ.þø¾�N(ö¹´u-Ø`ÿ»@é}êù½ yÌ=ð² ¨v Š«àøîñëÕÑNÿ~ü»úw~qç­×Iº#\‘½^eÐË7]ÍåpÔ—/߆Düþ8„ðIŒñç�æÓÍG777¾õÖ;ïýöïþÁ‡Ì¼†ò§‘Œ¬ Yy£ˆoz£zH Š¢1Dû3õêy"zPƒÕ€¥bùN�̾�¸ºÅJ=­ëjÊÆœl<°g‹ON>a2 to£;``2UiSf�`M΂uYpCËJÖööþçœ5ÖÏ�G²sêÖ¸vÜYÉP¯A;Wñ‚æeÚœJt؇õ=Ѩ¹PNjٜoQkwü·�—‡>‚Ï?¢²s�cßÊ쯑¨�Pà¹ô~ù� ÐÅ%®Võ A ü_ݦÝ3ê•Bbd.1÷Ñ줭9ô9 ˆÖFð*­Ù­#1I<ï^Ëöø‚ dÌ…!@§©ZïÇ.Ó>º"¿´Fö(�#¢Ø¼”É#¨‘�˜·ýu\G é*§Œ”“Ím”‘%ƒSªó4{$Làˆ”¦êö@­c#lö™e…êÚÆ!Ôk‰`糿#1âwdö{˜7û“öþìN@SØ¢‘î.ˆ+<ÞÓ\ÁÿdàG(„‹°&0Ù=&W˜r�ì@¾µ£“T&81Ê# �(aM wí™Ü©b>"Ž:ꨣŽ:ê«TਣŽ:ꨣŽ:ê7\í!”™$Ƙ§iú—ëºü—®#íM‘eÿÚj6ö×ýá/‹v^³2êcrÈ;ÔãB«î� ÛsÞÿ©WÌëõË}üÛôå-ÿ¼ßû7ìq±ð¿Ìçн7üu_[8Ьxiý[øW&,§«òë%,\�Êï±AøeèôºÞ=.aj}¥Öí*q?fŸÆ>ŒÓôѧ�O77¾öúïë;¿ýÁ×¾þ�ψH˜HÄ‘y³ÝWÕ Q !H,ÌA˜Y‰Xakñ?³ˆfÉÒ)”‹v?ŸÉ6udø7»íèÚÌ*ˆWÉnm]YBˆ0ì‘®ßøÌÓ T˜=yÊ@*ªÃÜÔÍ€Tp€Á 4ë€ÅdÈ.1"NÍ’™zp[ÊØs“M=è ?w ~¡ (¯Ù9™bpâ0Oˆ<¹cB—ñ.p…{®$ QAvKð~è0±æ² úê}’ÜT˪Š5%ÐÝâV×4^ÓÕušvÓÑz}°'Á–ÐPþ¦žS^%(¤ÿ·6à«À¤[ò'â‹›„Hø ár­ö¾.Yü75w!H—©.P€ !1RŠˆQ�¡ˆàa6¨ÖÒ�Dn¾ãjãÀsGF„Ȧþ-€BôèÛ¾ô¹bg¿—;_Èëº dQn÷º€‰\\+4×cˆ¨ØÙ|ÐûgÃã$Øàb[Þ+Âþk{Œë“Bتð‹Ú¼�ˆÚb»uض73×µ¹)¶C§vn-^@1’zç î�ÙÜ›ïPS{ÎLÛ9N[œI!8øï;<'ÁtqÝ5¤Ø¯ u„ ®mr9O÷„‚ ¢ý~43ܱ¥*Ô‹ºº#+£ÂÓA`~“Å…CYÀ*P ]f½E·˜õ{##0 ¦h/ó))U¢�ê6îúèûk®Nyˆ~hî,e¬Š{'´ÄàÎj‘Å’?Æh“‡ïÝË8o„Ô5r7Žek«›¯Hm=È,µÿ `NNÚ9µ¾æ$"EÈK… S×7'%˜Mq·a�Ññß‹ºõ»Xó[sÁã< ¨ß÷ÉawD(ó`w?¶m€MEù<Þ�%lþZ�Ökê0RCJÉÎê¼Þù£¨Æðص´k]}MgÎÂ�Ï D™æ¨£Ž:ꨣŽúÛ_ਣŽ:ꨣŽ:ê7T[ AU•ˆsˆ!?yòôŸ?öù&¤|{€ö×m–9íæyoÞÔ×ø¬{÷£Uõžv<ÖÕë½÷5=ØØåV'”û; ø¯�#+Ð#îÇËßЇ?h|î¿Açƒ?¶cí|]Ú»¿á ©À"tñ%®…×KïmzÂýýóþOüâ‰ãqé;ЕWíð[6Ãa÷ÈôÀؾIiü¿vEÄüSbþ”‰?‰!|Ä!|8Ïó‡77·ï¿óµ¯¿÷{ðGŸÞ>¹M>Ý©4ù¥6´tð\¸NE½�Ì̘…ˆ”ˆ”¸ �T�¥j0ªYäoýK�ÿÞ»Hà#¨ŽÀR¯ì•êÕÎ{°Hæ�RxÕú»Õ2Ò©‚u–?ße»€¨©ÿ{[nª!Ûm¾%¦j,"Hk²,f¯ìjÆ Šq‡ìñŠQ�+’‘“]—°�SŒiP«[_‹’zb³ß6$#p4+x4«ê’Q,Ðξ]ý.[�÷ ¬¬à¿ç3»rr5k–ŒœqAT�r'ëá=pU@²F<׉Á®¹#—\¸øZlªióÿ¯î»ýO»ó+ñ¹`ÅÕ€˜aØÁº�q^ )BȪ�;ÀÖÖPQuå°·©ŽöúÙ�®àý&F�„I‘‹"™�l °‘ÄÛ¶Ç–ì>:!”Üy꣈‘ `çPÕ°�Ø’[†¸ƒl²QØ–ö/€Y! „jÞI'qíSÕ�A ˜êºÉT„Æ)bšgLq²~ËT&�BTpK±•§>|ÞUõ…Ä@Ùõå}Ôçª\¶c¨Ç¨6¥o�³paÏ^û�+� á¦8‹ôÖèc7bJï>0®$\ÎP-D€ûÖ·ÊbÚDÔVÚ%ö䕿À´�£åŠÝúH °×øŸj (üïÕú¢8xˆØìöDL ”û Š @É@g&›ÚEB$Ê œ�‘Ú:@ÖÙ× ªýFÒÍ6¿~o®Ú® DÔ,å9¸ ‡©Åµs�Ñ,@n„‰QãU�¿|f#Ý…Ø9¨0{¼€\ÞUddRf'GäÚ@”É […–[$�^‚;ì‘îlY$¨òàŠãŒ8ÅJ”�IiC ¹áô×½ÿ«Õ7ë—»žômÕ“œŠ €9C˜³G>ؼMyÏnËç^¶ù8÷‹;ƒ–xŒ.ÎÃIqÌ@`BôëeÀuÔQGuÔQ¿â:GuÔQGuÔQ¿�ڛݙVsúú7¾ùÿþñ§Ÿ€ —ø¿n‘ÿñ¯ô0_ ¾~ø¹¸êI7”¶–¹þßúHRÔ�BºúaŠ­¤–®*Þ/ÚÆ/¬w Úo¼½fÒî\÷ã ô—ΜßiÉÎ¥|Y¯ç á}�W14×UGÿŽp@/{tëDTûæÅ§¾êÙî4]sx•{ À/oð²jø†‚˜NÀ'Äü1Cø8ÎÓG7§'ï½õÖ[üÎïÿᇯ½þÆy]VMiUUÍÌœbœÖC !äÐ…A‘r÷w4°ß‡¥]¨)~+²,ý1ˆ¨o�jŒr9Ån�ÙÇÙ›;{…#_üölJvÙUÞ -º½ý%(ÕòÌeˆ¨Ž0Žæä‘M‘hóH `âx0U`S¶sP(RJxñâž}þ¹³SŠ6ëähß—�9Ó¿ÒšjËÄÓÐvìD†b»Ÿ“"e·0§ÐVÍ@†@Ù�\4¥¬4ÛnEÍ‹¯yÇ+ø?yþ³‘&€ ‰RU‚KÎHÒ2SrÉbê@œœ¥º&âCiÿœ=Ò gon6áDЪ3CÎì*ÒìBZHkè» u{p³øV·ù/JNo'Г Jžgß,ÅÍš?j@t(vý dd�ÿuà T!nư¤ˆI22²Í™Luο§Éó½ [œCˆî–Üùp攆h€¾Y®zBJ©Ú‡øß;5PUk†dSûï¢ê�¦ Ì„#xMÈIê8öeÏáç8€}LLSÄ\Ƶ_ŸM<Öîªr ¥îsÊœÓg‘7w…ÑÊ¿(ô7‘!Ù9@ hDt6àÕi!"Æ”dŽà@5¦£ÙôëEL�¹nlló»ù`K^¸ßë;2ßëC§ßr62U¿Á݉6`p‹‘«QúÒ–œ³»ÿëÆûà6@6öUØ]À e‘€„;÷˜çdsŸue­ä±²?+s¥ä÷‚k$³�î<ð¾’¢ò0¿–†, ·Åi4Ëûüïè¢�ÐîPnF.„¯¢ÌïÞ˜Aш3èûCñÕ�ãYb„*Fޱs Ñc`d´LFð1#ÙòSqEÌÉ fÅÙÅI€�#•öm¤«f¹_\1B÷ûD#öD_Dšº¿ÍûÖw™‹ Nð㠮˜t€êLPÚ¼ìúõ©'S”Èñ{Pâ ©f�ŒVÞ(${!×1_Î/ålîk²¦º~Óêù–}ÆQGuÔQGõÕ¨ƒpÔQGuÔQGõk®kJ󜳚™iýþý�÷þÅ?ûËŸ‰àmºxoQ,Â�t*²°ë9òŸJ®4õðñιҎýõ}¨»v’—™è÷*ðï•ï+Ë´ËVꜰ±ùÐ+ÿÀð5_ÿÝSÔ+ ÝËÖÚäQMB×î Ù¢;÷õÊ%V<ö’ÇcêâÚ¯æÐï}–ÞÛ‰hå úÊêÿý,÷_i”Ã}qD¯ôÙDüþ$0Büdšâ§ó|úðæööƒ×^ãÃo|ó;¨âÅÏñ ¹»{¡ä4ŸäékOÓk¯½¾>}íµ<Å()ç¢ÖW5És°Q"¢¼Âì}¯(“{kûòÚ]ò”(ÓÏ#åxâs&ˆŒ6¼=! <°¦D?N`†tj¿zžÕF9Š} (* �áЃMIÛô»ÒPº¹ Zõ�ªÁÒØsÊKV|Ímwµe´‰Qm´‹ºfꮏ;ßáùóçžÁ caªÐàªPîÀá"‡º·æ/ë@�Àêöî0"k€Zœ‚éÅU €B—žk´‚ÛŽë8“ÈI®ügÄÉTÿlÙë3¢R­±U¥‚èr#0cY““ãÈóºsµ”O«g5§€Yï&·w.9àkJà”‘RFJ⬬™Á©?%«Y4×7Š``Un�„®?õ®ƒó*9#‡E€!×H©ä7…9 h%¤Ì‹#ƒ%Û1(û}õýBq (êÿ¢�Ÿ§ §ÓŒiš0MS%°Ûü+ì>««ûµ*¨©*ÞkÉÖn9%ϰîÝ2šõx]÷Ý(D„L¥-Š8E!Ô|ìœÌ+'¤”+¹¤Û�ø=�[ÿsƘæ8!ðäã‹«s@sª�Κœý^¡ªþûiÄîwGä­¹B#ôusSs!µŸ%4󩠯ؕ 4¸‘àbÞëç¾æ²Ðƒÿ=±ábéòè;BA!Øu±=è\"Fz½Ô1Ä ôn*ª–‰Q QÐÎår­ÙË©rÛý?"¦¨.$U²4ûôÄsz+ªÒZTmnÓñz¬±‡‰�ˆÁœQ˜'Ìäk‡µ£Yþ'`ÅEüE؃»ŸPçø°];ëºXÈiN,ªô"�”mì¨¹Ë ±¡”è¢Ý.#R‡±�ÑÙæ;�h]¬iÅÊ«Í{¥Ÿ"BÎXR­‹õeê¢bz' ïí~ ˜³ÏÅ<Œ#sÕ uL4ð?x{ùoCÚγ¶I¦.R(.¡®‘­Ý@]›BGèkÎ !$»q4ƒÃL!¥Õý„ø¹ŽD‹7àò;&Òšp>/¸;Ÿ±.Ë@Ž ¡8€£Ž:ꨣŽú*ÕA8ꨣŽ:ꨣŽú’”ØS `p!þ3‘õ_/?•‡�åAà>Tü�ûÂ:]éºz¼ûˆ>ûÙþ¸Íß›%Y¬w/ÏiëYþRjõ ø?þLw>çàþ À»ý¼—8»—ï/!L×?‡´÷Ô«‡ÐG]SËþUüR \É«¿ÆN¸ø¬�îr¦ÿéß’™‚.þy_óO™ù'Lü þ$„ðãiš?:�n>zúúk}÷»ß{ÿ­¯ýÖs¢¢ÕFŸ˜DEóº®ùÙçŸÉÏþsùüóÏtYV�1ÉM¾É 3KPÕNÍorg×�óø2X¸÷`N›;ຽNH�‰Ìž¾üŒQAq¦| ±ñå}‹‰Kv·g9£)›-¿YÕ÷ ÓHDâ–Ÿ[•ÆŠCÄ�`Œ�-Z3×{’ƒwS@Zm½ `ÇuÞ7@¦�p 4t{á)¸Ò,豦ÎÒ8á¼,ˆÏŸcžæúž5¥!Sz«,ÀxQ朣RvÈ,ì‹Ó@!kÕ5²’ÊÚMîáÁÉq%"�˜w"ÑF@U‡”anÙ×4·³èÛ¯'xlÛ›¨#Ad©¹÷k!T­«­CÞn!†º–­)Y䆔¨”Þá¢s:ð5�= ÆBò ±ÿìõ1°¯Ó�ê?ËÐŽvNå篧ŽÈê¼TâÊ÷m}±Ï7‚Út±çéÇc#Ú=*÷7Û×Ô¨ 4kçRÀQœ6€äÊÿëRÖ.õöjí¨[¶ÂGuÔQGuÔ£ê uÔQGuÔQG}I*å¬D”™h°œnnþÃu5€nmÿKÕèOÚ<®¢þÝÒjŸ¼ûÓë'Y”™´:íøzïQiïüt>ÁðhY/Ô.x?AwÏíQm�BÁÅûnáWÂǯ)½u_ùN�ü°—²™×ë?h$€/¦^Õœÿj›ÑöB^Õúÿ ?ËýO¡]2ÏÊÌŸó'�ùáÓãÓ4}|sûäã7ßzëÃßþÞï}òôµ×–œ³¬Ëª9g5¢‘"„ Ót’8E‰!¨(©ˆ¨ˆhNY%‰®ë"w/^È/>ûL>ûü3½{ñ\ ˜e6”Vˆ¨|©?äW"*.Ü’ë€iµÖ- L¶ZUãØò¬C ª²+€€ªÔõªøvu`¯lWíùwjŽÍV˜ †nñË®ÀuPËç锨P@j«ògQè·–âܰýç°�{·ÌC´9œã‚»»;·?ž�s±r ¥}K[ÖûSmŠÄâVÔ!d¨Nè0žšŽœ*çŠh9w”ó6dT`öÎ �óüytžáWÖ¹œ4›’~õ<åu]*�¬ Ñ@L®\Ÿ1Möˆ$úC±ªÎ©å3§´Bœ0Ñœ¬�¦Ù€&­ª÷b™_ú Á”å¥ÏŠ«]á™ëEInÖ×ÒÄì ´Ýoq \Ýá!ç4Dôˆ(v¨À¸ªBŠôÚ�0ÕP׌PA1T@^D­ rvŰ®ó„8͸}ò¯½önoo0OÑï˶–”±¦˲`=ßaÉÉI~?B»[Ñ%è­`¸(š ÈUÆ­a²�Ú½XŸ;é'B¡fήžÌÝ`»ñûjYèvï˜ û¦€åFæÉ…¨2(åËù'ªíÕ¨;ç^ÙMø/ÄŸx—+{)‘ [U» 1ñåç¢ îæ·KrN#ЕMÄ0_kîˆ º3ÇwyìÝ< –'1¯ú÷öçÖ>S<�6$(®± mi ¦W@éÍVa¸'äü*ŠÌ2¨Ü¹yXâÓ·'ÐE¼”k·~&‚ºÆP�*b4·‰LŠŠì.(F~+':Ç‘ò¹˜/.3Bv•åLTÉfÂÔãCZ_±©›«˜ÇØ„�õ»Dh”ön$<'‘ùð1wƒÙ?$eïÇZßècbD) RN.Aý:ÍÞ.Óds»È„iRL“¹ôôŠú^EŸ}®Ê9A$ÕXÅÆ=¬Ž�µ@LÕɧog# )Ï®ŸêœZ®i$ª(Ϭv qBŒqÇ ¤Ì?enÌÒÊ`^�`c$gÁ²&¬KBÎ=a‡:‚!€£Ž:ꨣŽúŠÕA8ꨣŽ:ꨣŽú’TNY‰�3hp~û�¯ý_>ûÅ/þ[hyk™¿…«Ñ¡jâù=@ðÕ4ûöà}ð ÐáùC€_9¼@Ç�»��»½goÍý1ùUÕ:áBúÝ¿âe‰[²EùÏcAïG~Þ®©<Ýõpaÿ²@ücþ= ï~™Fù>îê›éóGSŠ¾Â­ÁÅ­ÑǼèq ÌÌŸѧÌácbú”9|Bøxš¦�nŸ<ýà�wÞùøÿΟ~C�Xˆ�Éå-þAjJgR"V¢šW¯ÌA95 :*!gÑe]±Êªçóî^¼ÐÏŸ=ÓÏ?û\_<ŽuY”˜@À4„ !D�!hÉÍÝ*׿„=ðû> ÓîÃýík‹ îBpU_¨àŸjÉU6ð?Æ©ÚÅ·üå¼Ë|ïB]l@¹§£‚4„à`Ëx˜z¼[jfq±¬nmT>Kkæ7#ç\s¼GÕ+WÕô¥z¸X’r4ŠÂŸhEJ–åŒó2Õö¾f=Ü[ä«âœ¹�” ìÒz9®zÕ3yÔ9ǧáEeQ¤ 0zÏ4#Ì…% åŒeY°¬çª,m9Í�O`fÌžÿÇf™íÿ-ÉIârW-ǰîÄš¢`îÉ-õuÂP¯Ü§ÙÐ�Ý}$HuÄ û×*Ø©øžnP—8ˆ<Ìý¼©BP!S”y¯W/·9…®Øæû|éq"º3oXd…�²cP�¨@³‘4K×6ÍR^«âÕ’½œCQI?Ä8¼Ö¶�˜€a´d­â$d‚ÙºKs³!�´0pÚÔØäd†¢¾Õ�,e}¤‹ßPˆ=T8ÞçÍÅ¥¨þ£[Ú3”›ëL™› Y®Ä››þjý/*àvÊHÑóå}þb‘=’‚â›ïâ(bd®óõ@t¦c­®L íÜì|ãà$æùÒº¾Í_©:¯¬Ð”ªSLZÛÜÜ÷�BŽ �‘Ò Á<¬m3B,í/Èå³²6²’ï? È<Þ§9í'¼¹¥¿+óÙ� úqVîeq jûÝÝ11(Ú|Sz1NÑ£�é½¾oë3diD}¼Biÿ&‹&¨î+ÇïãGuÔQGõUªƒpÔQGuÔQGõ%©”V5�'Ë÷ÿèOþå{?úÁû"ú]{ES÷Aµ�}#Y6l•—oï¾ó�¨€!ëýšþÃàÿøš‡�öÙt¡x¿‚ºÖçi;Õ6ÿºL~8·~ïÐ×Åò#H°å<ì6¼ƒ)W‹æn\åvAš G´ö«Ô¯FùþJ§±÷ºæÂ0:Elï£>&~‚¶Íp[Ñ�«öÂ>f⟆?ž§ùÇ7On?~ýõ7>ù�ßýý÷¿ñÍo?S•œs–5%Ii•œDäCž§ 1ÆBf2èSErÎ9¥œMWhk`v§ZËC/´ 4è‘){UíÁúyYp>ßaYÎHþÐ=KçyÂä¤{µîµy@TA€}ïTÑ1}@kÇ�²‹Ê·|�{`¶²cœÜòÝ2ÊÉóž ì-Yï}ž5!„:‘+ŒTìγ}”åªZÔÀ½-q›u�Ù­‹KVï=à}¬~ŽÙµK%ôm©jJîj¯úÌâP�Éœ+�3‚Õta±Ý!¢µo€@ŒìêQ ìB%\ïr¡j¶³04Tÿ ìú×uÅy¹Ãº,XÒj}Ø] ØÕºfµ1O±ÚL—²ß]ÃîàIN–QÝ«Š{Eg¿ÖYôAÐ !‹_ÌÙÈ(ÕÚÙ?3™",ˆœ<ЯÁÚZÒÈ`ŠŠ<Äl.E�^œC*0í€duP�f5‹ª70Ulй€^�LA ¬‹‘ Ölí@>öæiÆétƒ›'¯áéÓ×c€äK<[{¬+Ti]q>/XÎg‹½oÅkß¡ÅvôÄ›>r�¹¨û/Á«ùá sVälnRÀÙ�àÓíuè‹X’ìˆ(ÔèK?(.Ò|"¢Ü­¯—„NòT °´(k#–ÁÒ Ü” «ví÷õ}¬ô`£ª åâ0‘*¹¨Œ 0],óCtç¦êˆ‘E€ $Mž}>:'<¸Ç­s³:Á`¼÷÷­5½½¼wt3ÐÖfÎQßPi%¤hu0Z�9“HÙKöc­#Wç—‹ëp@–ÔÖ"q‡ &x¬„ßw]t€»Üöu•°]SË<�sFÊ œ‚yÍןSHè'´í‰¨k¿¡­™¡ÝçVwHBcŒÅà^ãíʽ;€�!Sø/iÅr^Pê¹Ë®¿Xc}m`!¨ë@Þ+U9‡:.ËîS7�³[ð7rF™£&›Çc‰p¢KuŽé÷Ü�!ºÒ/áÄ_Ï9`š&L“;„}€¾DÉô¿7©(„´FÅÙ^ õ¡2‡F?vDÁ�5Ž:ꨣŽ:ꨯJ€£Ž:ꨣŽ:ê¨/IåœÝ¡7gU,ªºÌóü¾»»û·Ëk®fÛ£72ßyZ×ç½×J/ÀnÝUÙ>;Ï�õàÿžxß”O�¥ºw~õÿ€Ñ: ‚·¸ˆ“”È}¯hÔ ? ‘ûµ^>{¿hÚ‹�ßa!°ˆõ g¨ä„b›®›uór/µ�úqO›U‘|žiïïÏ¿íÅ6.Å÷`ˆØßGзN«;DJ©FbhçQÈCSŒuÌ”ÏÊ%â#›{×G�‚¼o##T‹é­Ý‰º³?hc&T—‹žeíBú«>bC@J ©dœ~«öüTkY¯ëç¨M�³Û·‹xf»Ôµ&F#-™Ë›ûŠGŒPÛ›\ô)Q52,"‘×õ¾$í·‰:תøæ˜vÛ™˜�™Ëh‰6¸Î�,ã{”ò=…Å.”õ¤¬c±_™Á”ìu*u�ÐŽãñ+‰x¥JRA�³¥ÞéˆæTâ|Â`Á_\-Ú5 DÈc®D¡i?Þé Ľ|ހσ üï�Q\ÊZ4î ¨ÎC‚œÏ—#Sœ’b%FöNHGuÔQGuÔW£ÀQGuÔQGuÔ—¤JN+Ì©qU•åíw~ëÿáïýÛ€+hw$àöU®F™78åÒ†ü>±[Åu»t`k}OWþUެýÃÓ‡ðáGûñëeøcT}ô‡=t?vH {‡Þý(zx¼×^zýFöïâø�Ëó)oÐûÎáBEÿp³�ýl º÷î½tjÂr]ûLª=÷ÁƒÑ~Ï»cæOˆù§�Ã�9„‡>™§ùãÓÍé“7Þ|ç“ßþ�ßýä�þΟü<å¤êç”VQU%"ef%"UUÍ9«´R‘¬"ªÁ›T$ˆª@b"Ò¨QcÍ9«ªŠk6ÅÕëEˆ4· »/TÿÑsÂE²e?Sȉ x¢U…bÄÁÍÍ-b(yõùâ!G½ ¹ÙÛ65ྭô˜}IJôUpacg_ÁÂÀîb0aš�!§Ü½/W;ë¢ü' Õú¹Ì9"Ú}åÁ}Q›þ>+YDw®s·ìžt€°róÕèójS[r ¨òÕvß'Œq2`ô×¥´â¼œ±,žMß©øyC 2µyðŒc¹ŠUÌjzí£T†KŠÐTDLÁ¯mö,yæU­­xÈNlGl¨’~|SuiˆaÂO8M'„)P¬iE^²[M'¤¼b]W,ëZ�MS^ �¡�![eÓšpæ³)i9@Õ¬òz®À�q-~Å÷‰ ¬ÜÅO°Û¦—ñ”ëÞ�Ë1ƒkÄùÜê—ˆ©ÿGˆƒqÜT¹E-.«@h�Š`]–uõ1#µ}E9­H난2Bœ |ÂPWïçÜ€«’ï¢)]çù„Óé„y¾Á4O b‡ÜT­"» Gï`Û¢¦äÍ9#+y›Q�; DËõu-·¼d—7bBý~™.IûŽWÄš ¿»Úü§rÒÞ½˜#¤Œ÷ËüzâŽÿ5� .ÕÆzqÚvk¯°ÁÃæ WVg­™ó¦˜§:RhÑ+Ì\&OHµ¨�Jr@5E­ôóã^[YÓk·îéî{.@ëî«Â<´EKhÑ'sù~ÞÙÏë ¼GuœÐú¿êŒeì_hV(2Dr^[tE—QoÎ]ÀÎùTrÑfƒT怜3Öu©Î ƒ;m¥¸VG†:ßZšÐ†tÄC»‚,¦ü¯×ÝÄNd[\¯‹™€`k,˜­x¤B‹:`„8Ùåûˆ¢G4r€�é¶ß êÐÒ�ýº¢í�<º¦sâ¼�«ê>¸cKôóF%#ªi5òEyãˆÔúföñika¹�Xöå¼Cp’‡;<ÂM½7ª›õ܉$;óƒªVÇ�B¶Š~=Á ­Ÿåãò£Ž:ꨣŽú ÕA8ꨣŽ:ꨣŽú’T÷0GMªºüîïÿÿûÉÇýÓ5­~”§«ÊÎ÷"{=ïÚMŽPùŹtß¿æjn„ƒ„ö…¼÷ÿ;ß| B`.ß{K=ôžl~ã±ï¯í °ç"°±Ó×Îî½ÿ¸—ð*xõ~2üå¡ã<‚`°{?tó÷>…~]AãyÒ}×{Åô‚™þ†8ü”ˆ?aâŸ1Ó§!„sŸÄiúèææöã¯}ý}ýß|ã„' 1æ§4OSŠqJÓ<å'DpÊ%&%ìõ‡ÝÚYɪošSÖœ“úC_%2ëæœ¢b.„Æ'%"È$º¦ÉRHþ »Ãû|ì– o¬= 6'ˆ„ÎnÚ©YÑÛƒäižpÊ7ÕFzšgw(!ÜÜœpss‹ÛÛ'˜OsµªÍnUß«ÌMAoïC4x–³-{®{$‚‡æÍm¦µ’xv»©¶í@„ˆ#Nó„i¶ËN1UrZR2€À²•7àJmóFèÌýŸÅ²¸W²7`#ÔÜñ2ÏS¹g¨JC"EtWk_#l(xk  Ð+ß·9̦�ˆÁìÛ§y®¯9/gLww`æ ¬ '¸U|vÀ¸Ä 0›ú›)º‹ƒ`]œÏ Öu5P¦'t L†µ¿nÁ£b_?�:@Æz¦xÕ¥4ƒ), bLqÆ<ϘO'Ìó !LHªHë‚õ¼`Yî°¬ 2(4í¾Æ�T¡êÑÞo Œž 3Aä1Õk–fÑ¥‚ã[ôD¹>?g M© ò{œ3RÈÞYš H! (B 5²JQÞæ”!Yë{ú8�J^!Ô,k‹OPdä5y|Dª}BÕúÚ².8/gÜ-g‹x uc3{.yö¹Åæ¹h÷cšp:�šÃÈTâñ%¦‚æâ^½ 0„ÈuaÏ>>m h#À)™E;vÆeÌw"€9šíº+jE$¹UÔ²ÄÉ<-ܧ�”’%Wò“è¿¿ÖÚ¼Þe¨×XË/{±~>o×SÈ`ަ‚‡5RE¡´¤�û«êC[–�B'F”ñ*"ƒ[AQt�j¨ãÈ,-7¾‘OhÈìAÚ~^ ]FK±8ß#4òw1TI)ª¡sá¡�zà»Eð‘ms�‡�f£R‰ê®(€& #!Uƒ”1·="FtÑ¡ºì�g¿&ÛøÏC[Š(bî@`ÑêÒÏ·†ÿ_’Ì.îH[È–väé×/·Ï1—B扊IAC»/%·"„ P5>3×¾��ÃB�8é÷¥¯*Yt¸þºÆUk!ëÌ„ Å.ß@yb®}¶¸2”S´>1uÀž„�/Pn÷`MÉIrëoÒG•û˜SÚ±|….!ý=*ûö>]È Ñ]ZˆŒø‘Rº¦ãò£Ž:ꨣŽú ÕA8ꨣŽ:ꨣŽúU÷Qˆ°Ñùõ7ßü÷~ö“ÿE!m¼õ�}€]uT%Ñæ=xü/¯é5ÿõafå"Øc˪oÜ€Æ-Á–ÚƒÔÍïK°o£Z‚úÅ® îËh¿‰¿,ª^o ºßà‘Â÷_¢º»¢\GëL›K~Uxþñn ¿ÊäÐ�¤�]à?3‡Ÿ…À? !ü$„ðIˆÓOæéôÉéæôÓÛÛ§?~óíw>úÖw~û“8OçuY4§$)/º¦¤’RVÉ @"¢ÄÁìõ ð BÈ1„Ä3'"ÊfEï@íF•¥Uµ<öñËœÙ}ëúš¡\V"¬”:›biÖÖvä D7dpP¶·kÍÊÜ0ÙfcÒÜÚßO§ëÚ²ÓçyÆéæ³ÛÒÖÌy8½è˘¸¼^€à­²�v,‡/‡o;H© ±�¼M ðmÖÉfK^Þ_ÀÿBx ÊÕο€=ªQTûðz|"P;ºù¨»GíU{Å­Aö�߀Uf%;ÏÐ)ðÅ�>bH¬#æ °¦´w*VîÚdŠÑÀJÏs·ëæ )ÃAc"ÄÀÈÔ P@IwÍÎY°¬–ŸÒZªbù^r™‹ê�ªõ:s?�]øv\(qËO¶YÍ¡Ž‰'LÓ Nó-âtB ¶Œé»Ïž?ÃÝ‹;œÏ/ žO_"ª]òÍÃg¡œ2rr[ý:¦"˜WâMuºæŒT ŠPõÀÅ~»€�æ´`ÎÅ5¡f§gçäDª®ðqlYÕf½NU­êVÿêÊø¬NÈP0…qÎa¶ p5ÛïÜj9';ÿP"Uœp~�gÏg„8A\­,’°æ„”L%[¸庂Û\OóÉnp:ÝbšìqÕº&–¦î×kjð6¶Ú|›»9·8&mI‘£Ý¿µp›'‚÷moKQv›ô2n/�JT,ᢺ ™ê}“eO {”鼯VïæAö ãÖ5¥M“ÜEÜDõ8®­�E a¤Ÿƒ™#bÜ8®P?þÊùnæë …<ﲟ·`BIP¥‡9p—S­õ!wÎÅΤ§Œ¶ÄýϨ½{­¨]‹2lÂ4 ô¦·¥Õ ž™Ü�Ëüíø³+„={]Cu .wÚ@Æ=k[2›ûŸõm–sS®­nC>ZêÚCùÉmu©ªì³?ø.`µÝ¿ò0ÝîG—)­[ÐO;ËÞ©>TÈ픥¶Sã’“1š:ñúx’zmf3Ì×_Ab¨7KU"Vá›ölßgŽ�c¼·@ÏH@3ų£¹C&²ˆ�ÿçó‚óº ¯k%‰@°×åaÈg®ufæÞ¶¼QâšbÔWU{ÜQÁ3†d;®Ù*[ @äCÒ‚å|ÆÝ³;<{öî–;¤”ÁLs´¨€›ˆgœzç —rr›yRHXÖÐ ¢`*Ïe5"DZ D.™ÕêùÛEq[æpæ]@%;]ÔˆkS6ÔÇ�8²Î¡diÇj�˜#´Ä#Øg—ÀLáàÎm®±~’U�lŽBBTÝ´Ë€_×wç;Gäœ1¹ÃÆù|¶>à@»²ºŒÉzÀŒiš¢õJ¹Ž›kl|Öþì®&"‚ГGº|íœZ@O°îx™kÎU]ãåX0ÂJ[›uØœi›2‚B#u±(5êakIß½^ùß[¾_�vcXPׂ¶Ç¤Í–P7D«¶F¨+¤s^+¬:ˆÄˆ ûWÎÙ"A<7ÝŽ^\<Æ£(§{+sG²…0ª¾Í™yP{�÷Y¯í.c{ßc·à'&�XÛoÁîÇî�JÛÁÛÅî³Gì°‚ÈHà kXW[ 3 ©¢‘ؤ•F*èwV—m#{ñÖ�ígF "ß‹‹\Fð`'×þ1n=»m¨mÞgæQu(_AÃcÅ��dÇN>«û€â~“r˜k×–í³gä�‘×9¤´iO8*{„B(±ù.­Éç£v�b ˆaBˆ±Zø!Œ†ßñ i3çd{ŽäÑÜï×ÚMSm§c_±s8 {¤-I£’šb#|䔑’»·¼8¿”uÔQGuÔW¨ÀQGuÔQGuÔo¸š-sðDÕº4Ñ]ÎùÙ;_û­ÿÙ§Ÿ|ô�Э_ÿÚr„QÐtÏ9ÜŽE�XþAÚÔRõQ–j³nÝyÿ`¿ãð°”_w…ìtá*€ Nþ8 ûÞÖÿ¾³ÞóÊwýU)zù7mMJ¼ï¢ýúÇtíºîcfàž˜€Ç!ˆèÌÌ3‡�Cà�CˆÆiúhŠÓGOž>ùð·¾ù­÷Þxóíç„™tš&9ÝÜÈ“Û'zº½Õyš”)¨*4å$ •,"9‰Š$-6üb†üP!‚XÖ5”™”ݺ?DÍ›[B„8E�§ !LZÔXEQÛ¬óÛCÜ’�Ý?¤µëlc­·!ny¾SyÊx*vÝp±¼ØÑn_¡þP¹C–Y[s®3†|{{Xí6ä(çâêhvÊÃõÀ[·Ž”3rJn«ƒ£Aw_ëg^Q„ía{àlÒæ¤0>ÈæªˆÛ«ädˆèç±úùUÛç`4ç‚ÒþÅò]W,nU߬ßÕ^F»g¬…[ÖpÓnóBu9PTÛ½Exo‹ÿR;”n½#H- $'³95PÀ<Ùš¡ÓäÄ¡ ëº*æ’Q²Ð�¤˜ƒEÊ ²Z슥ÖX©™ù¡‘´‚ƒ¯» þB÷ãÅN½��úùóUŽUî£nÜÌöžë¶ŠËøF³ég_ç�ü¥k¨º;åËõµÙàç ‹úËãø¼C›xˆýP<¼´ÅFì9\‹ï)¦:ÇøuŠš«ˆä\ãaTÝõ ŒŸ£Ê5õ\f[Obõ5õG�Éqp±hqAÙ‰-FÞ”âÔQ‚ë~,g,ÞD)gsªïËuogŽ&³L¾W˜ØIh{�å”ý¾Wk¼nÈ-Žfìû�´Ô“ h �ôqí³Íúÿ|^p¾;ã|¾;~1?ꨣŽ:ꨯP€£Ž:ꨣŽ:ê¨ß`õÊJVw}`j€…ˆžýÉŸý½ÿðçó³ÿݲœÿ­jéÙI¿{áÉîí´�¸†t6´èlý·çYÄJ!8 `¸ŽС{@óþï�»7ÔsØÏȵ–üÛ ÓàJ›ipo•6ÙƒÌéâõêe¾TŸ¥H¯}ƒv›ûÊaÛ£ú(è’EÒÈgüaáÃÀáƒâûó|zÿékOßûÆ7¿ýÞ÷ÿè�?eæ ‹dI)å»e‘e9KJ)çœsÊÉÔø<é4Ïz²ìn=U`ž�³(„T²"ç¤)‹VëWU%"€U ÐÀATU{@Ì be†Šˆ¤%+~rP£3MIÖÛͦœ=ǵec[)ªõ­ »e÷9ˆÂ�ᆭ�²ØƒæuY‘Ò‚”SñíåcÞlo?_ÔûªÙsÈ¥*�ME�á}fo ù4ÏÕVÖÎI°¦ËyÅYä L{¸ÞÈ a½r–n¼tYô¡e!s—7^Χ̋ýùq âŒfOíªR– •Œr;†Û·Ç Fæˆ ¦ª\×çe©cQ‡Áy€‡\é=—‚#æi²Ë .Íõ:m¾`‰“—:g*`Is,ˆ1T‚F‡¾Õö÷ùÖM‰_ιï#å{%·}Y'FäÔ[ óÔÀ'›•iWÕ€�%%œ×ËrÆy9CE¤'Ä |usµjÕN‹ 8êyË\‰eRî¥OP°¾ªj³�@ÃðÐÒŽEM¯]`ªu#àR,«E0^‘on@ˆˆaBŒ'„ȱ,æÊPœ2´„,Ž"A•Ìây] ¬–¢^¿´Ž‡g‚6.¢IâŽÍQ§8Ûÿë0rRÙÚWZ.yQÏFf2­(ò�˜*˜‘9›+ÁÊÖ!"å9Cp6`V9­ì.®þÌ� P‰›2V¬Sdä´Vrβ,XÓŠäÊÞâž8´yMš2^ÅmÎéÚzGèÙ+ïËœ¢Œ…УN$(æº ¦Ð�]xQìö@r!7x¼L][z¥>%^£·/c[;¢X¿õãœhÿkÜŽsC{_àWoÿ2Íó ˜æùfÆ4-ˆ!`9ÛØ(nÛy({ÔJ™gŠ;1às9'‚ˆ äAÕù«{äÿÂ{õË?‹º»7äª6ïû]uÎðîÞ¢X,î§ôÿì¤ ^W¤•Z|J'�#†÷�Ü ĉ‚eÍï·èä!}„Aé»u¿äkÙÌj™¥ô"’L‹Éfmì¿àħ¾mÅmê@&2Àœ@‰êÕŠ_—­é ª¿ïÐ@œ!Ê7%²½EŠ ª·Õï� ÉSý{)§Ú¦øÏ>ŸW§'‚4ò'3C|M"¡JªÈÙã´�Äç†pÒßçîÑ·sßž÷¹V >G�—ç»çóéˆ8ꨣŽ:ꨯT€£Ž:ꨣŽ:ê¨ßP]¨d:u™ÿ[™9ñ@øþÿéÿäŸýþ_ÿºª~{›‡4qäX�ÿ ª®ë|ÝÚ �ºÓ€6�âѩکô ‘àâB¨{Å£òZnêæJîiï{X ¯ôñ×UôÛë|ÌÕ]ý˕ڕ�*m^5¾k÷ÈWÞã%�ùSbþ 0§éýišß{rûäýw¾öõw¿÷{ßÿ„™“ÙñK†Yïç8™cÌL”Œ J¢l¸É’%å �èDZÔU³+¹Cˆà@¡ <Ö¬ ü¯çȳ&.V½‚”L•¶.„,3GcF»ôò°8Wu^®Šÿ­=kblóëG¥µÈ¡Xë@Â�‘�êÃübSŸ‹bF¾à ÐÙ>î-ø+q¡Ú¢ÕX¬váUìÀWœ&³•%!ˆ9åªÌ¼ì&£�´H³Éoê=jJAûyÂE‘Y�' ä,N:hJºíµ×÷;øo}&Tµu!Vœ—¥Œ« ƒ öÿ£ÕwÍ_vð.zž9W[`@±•·Žn âu� ®<ö8w ¨¯Ï2ÄHôÕG…`QŸÑrâQÀ©fÛ~¾;××…«2²¼¾oÓâªÀÂDâ`à©MD±. çåçõŒuuBLP„ÀÕ­…‡àjÝq¢¡–�€8Ôüë²Þmc3ú¬s.6únëMTð¹º>Ì9[?Ÿ#žÞ>AZV¬Ë‚eñqçÊÎr�¨(«eöÞœ-FB¥ÚÖ9Pd`g±Üï¬åI‡É¸ãÔŹØ÷KîÖû’[‚‘JŒA‚–�°ö|æ¨`й5t#ž8™!ä5ƒy© l΂Lâ0;5tÜQÖ€B˜Q5À@á ªóDé_9 'k£LX×3î\•º.‹�ÿ>Ç‚y˜S áÉðE¬÷AÞ,:Zà—‰«ô¥Ñ‚Ÿ7qÖvÙÉÚÍm€;³WK—î ¦4ŠÛS?ç…ôÞÜsAøÙQaoÇë~n½1.ö ¼U‡wëž¹0˜ÓÂ<•9×®%NÑçi;×”|W6ÎÇ¢£ {ë�Ô�­X×gûl­ kaK»�¶mÑùíç<¸•óù}O!¿×®íûû$€{>h ¯°M¶€ÒˆÜ‘² ÙuÛϪj¾D_¨T…ûv}hÀù&&¦fhÜY·6Ü’6x|{o¸3WG1Sá‹&_b�Cx|³S]Ð�'UEÔX××þ>—=ݺ®Àz騳½^rrê½)ý½ý~—³ÙýàßÖsTR—‹»�QR—ó“õÞéÿ{ó�jÚÌH�F.]׳9 uQJGuÔQGuÔßþ:GuÔQGuÔQ¿�ºö°¶Ï°vEK&¢%„HßüÖ·?þäãÿ;Ÿ~òñÿЩ¼®õ[Y¶õžs@{Mµ‘§J�úðvã%ÐÞÚö>}ø¼‹ÓÚí4P@®À¬�KÝÕ¥×6è�uõLÕÝfP<Î'ƒzjïZû·çK÷µØžêê¾cïÇ.è•ãm펉®œÉx¢wÂ!„bˆLóüîÍÍÍ»¯¿þÚ»ßúÎw?ˆó¼ˆˆ¨ªQf9†˜Ç,’²gÕœíçfÖÇ3@B !d!�Öå 5™¥wp�œÃäŠH†Âóú0Uª þB ¯ålj»þ‹ºZ›µ¼VT Ô²`Í‚zM©*þSZ;•§VE_¯&í•�ªª³·äÝ~^vŬˆÛÍVÂ�[Zoò†û{isŒ Ù·y£�ƒâ7T ½æÂŠ ¨˜šº§T‰#[%ýŨ£^6'{›0‡ª2Ù€DI¹?¨®FP‰qÆéfÆižë¹˜uv®¶½åõ¼éGu ñöÛ¶K¹¿iMU½^@¤yš ‚ÅU@E‡±¥ÌÐÌÆš ¤ R#e$,iqg/6#‚bT;î�W<D £öIt ÊØ×U)X-R¢Îð~þ™BË3WÿÏËóbm|{s‹©d6s2ïîîlž 7%ÈñÕ¢½*[ YLÁŽÜ€Oh±Üod‘ÐÙ[“d$U�Ø8ÑÍ"ÔgÚWõ95¢ƒzÛq>Ŭ24™k@/€a€É®—ý«Ì Ñ•« A°rªçš9€(UE³ý? R0ÒECo!ßWˆ�ž€  \¢KB�÷Òšœ8d‘ë²àîîÖ匔×J°²=RQÑóÁjX©9#YXoö@ý¢W:¸2J¨c•TEpjJôJÈ2lHì^]F¤ÒÄz•«î#„‹}äž+ÈH`à]šŠÖu©gÛ}éõ/© pðõ.ÆÛž&_Ǹk^÷’Š�ºVÌ™}ßÜÍ€GͬÍ2Æ?ì9%Ø9ËŒoÝ.ÛgŸ8§WœöÖU¹Ún{~³%Â$N±îMl®P�Yk ó.ud‡Bì+öÿ„²ŽJöÒ_Ëjlß'(—(j}¤Ì3@%æ‘ÐàÞ`ûéË(†½k.íms›T×ê£~¤çäóXa=)<Æ#eçÓp.}·˜’6FËWî\2ê½éˆ3ý=-.>L<�’RÎ�» ɲ` Œ•œ˜¸ººîÄ<ì!‡µKY’GHµþØÖF�7h�)Q�ÃÞ²sh²6FÝÅx¨÷§5ù¸Ê�«ÉQGuÔQGõU©ƒpÔQGuÔQGõ%©Ü)›€Yã¤!„LL =ÿ»ÿ/þñ?ù�ÿ£ÿñgŸýüZt}:ŠQÑ`} ø�ÖñÑ�áô:€Æ®ƒÛ|æõÒá}¸òÁýw7Ÿ×[Ì;Úù�F¿�¸þZºr6ºst/ àeMú7Ò…“ÃŽ�þÕƒï�ÿ[wƒë1 46ôÂÌï†Þ !¾;OÓN77?|ë�wþú{¿ûûÔûyWô‹ÀBbCÊ„™…‰`…"çœE$‰Ú“^!"�*"’E4ˆ)‰jÑSú‹k  H@Í–™C˜*àhJ7³ôî•� BcˆUmcpkX©Ù«RÞ•Ûfûš+`lÙòÙí¼“YƧÎÊØ«X©›’;š:r£ÜÜ46üäžµü;9Á §Ü�Ý{`D³¯h£"60à?o$'°˜:.d8áÀ³ã30 l°‹*¶Cد ÁåÃ÷`(€€?<Á�b¬¶Ê@!Œ9¾¥m¹»¶£ÇÄzŒBˆX×wþ§u­àÉ¡¾°HÞqm1ïV5Ú®¡(ËX´s·În9ܬÁC˜0ŸN¸½9™½vˆ °iÁº27ÂCØØô×>¤Ýy`$ØSæ¯ë2€8!€BÄ#RˆZd· FJ|´h½®¦þ_ÓZ£ú\v�#¸»C¿©€ºûÀ>� á TˆŠ[+Û9H Wœ—þ$¨“Š[fÖ3–sÀz:PÜÞÞ Noàµ×^ÇÍÍ ÂADøýë’l.H k²{¢BmŒÇÉ�GÄ]Ê}­¨�«þ§f-ïª_søHÈ™<[/âq´ʹZ½�ÕAt"“J@jöê9ùñʼn#ÚÈ}µW2�ÉÇ\àêT¢Ù@|Áº:€ŠN•®æÎ'sÀˆ!úû}ž*m†"€„Jº¸÷ß’5¯*X@>Fm|‘¤#ùÔ1:{ñÐõñ.Ç› ¡Ú À•º´é©ÀÐÞ6%ažÆ‘-RÀ3­1,côJ·£0íç‘Þö¿�±Ê÷·óM‰ŠÙþ¬?ÖÖu¦E ðƒ4{Š-°K„êžSÜú¬y&BˆŒ�#r΢Ȁ°ùŒâ�”üwöéÄ�Á\c5R²µö|v2€G÷„þþÛü—.ˆC¤Bˆ¾¦µö,€hYc÷Þ{�0°O ¸üÛÙתÞß÷á€DF†Hðy×wˆÔl܉š¬×Ê (ß:,8H³Ç£h%G•1D`çë{½Œ’©.2Êå÷Šæºd×(…ð'‚òë ¹cH%'(*`^É’ÁMeM–²/ÛDÚ„ÌÈ|éÒÔ’¡®»dòcèæ¢Ð\¢N K�"97"€G’l‰IÁÉ<Åa¥7Xhñ ‚ìŽ:¶îûœÕ�ÚWTÃfîè#Tú~qéZÑ“"Æøƒ<�(™Âñ ùQGuÔQG}…ê uÔQGuÔQGýšëšee±¶‰I§S ᬪÏþüüÃÿí?ùþGßxñüÙ÷jücÁÿ pxç}JèÜ©_Êró�#_!Шäï#|Oém݇Kñƒê¾÷=pµÁs%�¶—µù¨Ëó¥Ý³¨6ý{v¾ÿJ®€gm!¹Uÿ�Bˆ?œæù‡7··?|ç�¯ýõþѿϒªfGíMŠžà€¿ˆ¨Šö-NÜ`f !`š& !ªƒ¬šÖ¤9gÍ9«8ʘÕNIƒ°Š°2›5º=�ôœjAµ–¶+3`*pSèv>µM�†bmËUIeŠÂ¢,ô€b¥[oÖ˜IkjSýwUÅgбdƫ܄0ŸfÌÓäÀóÜÔÜß¼•¢üuËð¢ÂïÖöDƒ–¿}X|ÙqdÇZ¿Ø7‡Îî°‡îY2rˆV(_@íͥ Èî< ‰ÀrŒ½»åR€ 9æ¦�¥¶#˜*5„Ð�;4S[‹mîÔq1FLóTÁ5î•Æný>ßa]×ñ¾Ð¥ª~«²­®;î ØŒó=ï‚ldï¯1ÌSDŒ3¢ƒ©…¨¢7}Ãù•>s¡ Ž Ï){ô…‘Î YâfžœC(2BS*æ 퀘ý9Ï?[ÕA³ët¯çbÉÏà0!ú½1ò Õ±l}j»–Tëå ê»óD¦Nñ\æ’-!F�¤æP�̦þt:áµ×_‡ªâæf®D‘”>“Ï‘Ý1a9/XN«�R˜§ÉÏ�°¬+Dm|ˆ¤š3o.FB‰³#�HPrà¦Oèã&zrGµùvµ.—Ö")9ØGP@µfSÒʨjî :‘²bvò&cH=œˆ9ĈsÄ<Ÿ0ŵQîcwn{.ÒÛwsµ57å¿)QKû—ˆ•:ö|º›PŒÖi²~é¶ùâd³â T\1F·ŠÞ• ÒÎ=BwöqÞ¿<¾$ÆPc×FW)½ï×¾¶WêÚ¥rjäfLñ€ Ž:ꨣŽ:ê«TÇÊ~ÔQGuÔQGõ%¨šì¹ËÃìbÓÍ̪ª)„pŽ1~þçÿùø¿ü§ÿä?wwÏÿ]Õ†•\=~û {^¸y€D-í%ã¯þïœÈ=Šû±hô¤¯—Ú@ö}Üs ŒÑãõ½ÌQmÂKW„îjôâmgôèÏÞdÐõ•¶JÌü1‡ð~ ñÝiž~tšO?zí�7ðÍo뽦3¥ãcÌ1ÆÌÌ™ˆ³Ú“ÈDD‰™3'XU›{‘ ¶�Éâ4YNü’‘©X·6Õ:Têë% $”�d Ú”›Õk±Û&±Õ! 8LP87Ű©Xýá*5×<]vE—Ytk§¾µLVÉZís›U²€ xœGe µ»��¢È*ŠàyšL kbGUŸ÷¹Ûõ@¸{E·dÙ}€}…è^Цï4p¦Dkµ™GU*™½¹�#Í  mÔ£; C•»‡íM9o÷ÕÁ„Þb¾(‹†6Þ·^ÞSåSµVžü^Œ½Ô‡^éYT‹Å¡ÌÃMU?Úü â ¹sjHiPzйe®„ U¥i0X±îåJTtësU W·‚~éÝ#¤©<ûÿ  Äul°Õþ›û@dÆ´N¢»Šòî®Z3±� &¸¼º’ rNȚݢÞ[&Sup¹*=GÜÔ§-½Å#é@'_EªsGAdÅú{ÿòÎØ²ªë½ÔÚDÌšþ4Ϫçó‚gÏ>Ç/~þ ¼¸{�œ²©�ïθ;�"cž¬�Ì8ÕÎ/žŸTk[P „‰1Í^G »Þ�õ†úPœû÷R¿Ìn[�m\ šú¿„�•7zwí@îÒVB°({I¥ºeÀÜBÀ<͘æSœûž¢�¬§©08’ŒãEkŸÔjÞ»¦˜ÕüäëÍ4Mqr³çÌcCÚñIŠ˜]áê`¨÷ïΈ|ܖиÞS}G¦rÎÈþÍÔ͇TAùBpŠÚyÌï¾ÿ¥]ƒ}�k›õ&u¬tÕÇ<´ïÜ# sIÞ„À´Áf8 xñ5½:é(®$Du%]†¼×ÃŽÊÇw¶ÉÉ€d´×Ó4{• vŸò¾wŠ(ëkÙ÷q>ûªýýµ¨­K„ÅcȲ @à­CÄ^ŽÛé×YQ�0©T×íÖq›¢^*Á…ªƒƒÓ|�Túaw "È<ÚEw×Þ²OÚ:´ˆ…R—q¥;Ä&ªçJ…jüQ¹G ƒÊ8Ê ¹ÜŸnß´%M–ï—d¾­#G¨ 8w¤’vm /û·BJ¾O+û»žÐÐìü™"¢($Š6òÎfο_û:¢f¤'ñØk‹k ?àæÑÿ*XLÚ¼ac£¸ uÔQGuÔQ_�:GuÔQGuÔQ¿á*f…[g^¾T5‡Î! !àïÿù?ø_üåúOòüùçÿCaÜZèk÷9×@kûùöÄÐ)ÿuø¾zMWÿQT?ÿ†s2ЀÜÂ’†ŸH×p­–ùp¼Výò|uçd¯]™Òಯ÷µÀžRÿ�F´{Óþ»ûæŸÄÞ 1þhš¦Ýœn~ðú›oþà[ßþÎ{óéf�«öa0zVÕ¢æïþ,öT4Ùk‰È|yíKKß)âsÎ]ö1!"k~ê#„%*°pµzÍ’ý¡s¨I«e¶?ï–ìÀl²œ{ñû˜9b �#˜cg}*V0 ˜³ÛQ»p˜{‹`qŸÃêVìb@ð²ÚŸ9¯–þ— @R@ú­ Ül¢Õó½§iÂ<Ÿpº9ažgÄ8!Nök—Y{ŽxW%û·´µjX·®´QmvÆ{½È"É{e¿\¨çEìêQ¦¢öÍ))Ðjeß«,·$€ñ\KžsrÊt· ï3j-¯Xµ;wº:g^€+ݼB¬¹ÊÛŒÜü/`OÉD¯Ùºþ¾Ð�Ó-v¡�@1D˜FÒ�²$8ëRÁ�â&Œö½)TÑ"™í»4@cz›çœ x]–3ÎËbí.ZAí,Ô‹}u#0”ô hÕWfÆ4͸¹½ÁkOŸbš&¬Ëf#æHÀí¸µö/Åà ˜Ü9U0CGŒ ãÚ,3Þæs­%S|BM‘ZÖ(íÿW-ñ=�ݳæ•íšK?SÿÙÅíçZÆ9°<Ï3nnN8ÝÜàtšcðÈ�Ëù–»§)` 'Ä9 Ĭ Ö5«“Šû›|Ó-b±*gÃç/2âÕU¡t¹ŽUµª²Ç!èeÕb¯m’f‹¨ŸámRµ3T2 ¡æSkÍÐný#å„Õ•ØëR¯mLOSÄ4Eœ¦¦iò~c„ƒÜ+—� µÁ8[”@wŸËu33XPÍlq.±#Xqóš ý�QöÇçKêI¤eÌ �HLjd7~¦¬%!´{ÆIØÈXèz„PÖªÒï³T»þânTÖ²þ”úù«ïgæzª2¿’zœxYˆ+ÊŒ2¢BçÜ Z&Ù L6�”-‡àóweFèÉr¹Eõ€½èŒògé» €(2¬™—qFn˜éäQC©öñ~¿­Ò6ÜõOXWÌöûMÏÅjï®÷·�&±ùý�èÕ~-Ž'•¦A|üb~ÔQGuÔQ_¡:GuÔQGuÔQ¿Ár°Ío»>!Ö\Êò*0çâ9„ ‚üÙßû×þ½õ/ÿù_ýüo~ö?W•o•‡@[^$¸®ÿßêñ;ežâÖ¶#)iüG=îüï_³u(g1X˜j—§ù��ê–æð…ݹ Àx¡÷K³é1çiäžñ»Ìünüƒ8Íýäöö¯¾õ�ßþ«¯ó›ŸÇ•ÌKWT5»Õ¾¸Ý~Af…ˆ„™+À__lýEU•™… a"ÒÈT+zW`¥>o�›-|q«ˆ1Úƒàì fë¬sntH-÷>+R¤uź¦šIZ˜ÇXÀt|bˆ°$ 8‹+ϤË9æúÐÛlÄ‹Arëâ¢úKȹ³Žª¥®ÙV%‹5Êø ÁÔˆsQÿψSl ]èU~RÕþU©Æ¯"¦æm]‡º<ôñ{e<ôV³~”ÁŽ¿€ Y”Ì‚8©¿.`„¼´*íº‹zÕö·´O³öyƒ·™µRÇro%­2Z [ód'ó`q½�3/•�<ªòºè€¾M`«dÒ‚Pmñ HžrFPrº A 9 /"X—^ IÐ70¤øû†îÞ� ]±N¯ŽîRPÀÿu1+lëof}®aT>öd²�áÞ@åBµ9ÍnoŸàé“'ˆÓ„âáíWwk[¿´ÙÇžYL¯ÈiE`6Çâ‹èˆœ³Å,/°¬N§ �Ý‚> ’d„eîL³/~>CÔŠ#IÍÏ9%¬‹ƒ\9y\AEè³ì `GL`ahðüúâÞ±A€ª½ÇZÛÓgÃJÆjîÍ‚ÌRIsªŠ%­8ßyöµç^‹d?ÍÖš&#ÌD@N€jîæŸ>2¤s×ïæ§æB2Bï¡WéÖ[ B–®j6ájYè)Y–Œ‘dš"�¨[‡‰Fc 2?u6ùT<6¶ê%¢„»èñ5�˜@B� óFŒ¦XçnŒ–¾Û;y\Ìu˜)¹Äx¤®·Ç’ «óâtÒϧ6¢KTŒ“>:’”ê÷Rú–í ÄûƒÖyÅðÒ8“îv"�«Í ²×æL!'±d¨&wq\?B ww‰“õ…¢¯C«ƒÇD¹æ¡o•Ñ…ä–ÒŠeY*  _ç™ä6´åÀîÛ=~?wÑŽ»¸ wƒ!±6 Ëß ÚxïwÖlm¼Ä`ñ%ÁœQÜᦜ÷Ël{kþ0„ðÃiš~âôƒù4ÿõ›o¼õ×oÿÖo}t>/YE1§išÒíÍÍzº¹Éó«<¬6LY]I˜�òŠe]«²Z$¹õ¿`ô?Q,]éÂr¹´GQvN1Vðrûùúð›FPg›1 ÊM•˜!�w_·w¯F€«¸£ªÈ”$!­%"!T…`ÍX®`�Tп[¤±å³¸Ç÷Œ«KÀ«}o¥WF@©·L0þÛð»{ –S®ÊÀíûª ¿*ÔyGEÚŽzåñ"DªÞ¬lN×ÙØœ0?ç„”˺b9/8Ÿï�R!ÆBÈÖÏíÔ±À1üß#N˜@‹Î�‹½g!`�dš>Ë�}ßÂùŽ;ÒUµü/û�2J!Òhç®âî[t¹Nõ‘•DÇÁ ±E¼Ô©\ãJl*cPÙWä2^­¥ÜbG´Ü‡‹=ƒî»uçc1/|IجçeŠ;éô`þHŒuíï�SÚlÛWÊ\Pq\Ý Ôç©äŒ¸#D]‰>*c‘qu/Ø÷Óá5L°x‘Ž(ZÏ“pÔQGuÔQG}uê uÔQGuÔQGý†jûP&¥\ÈmU¾å!l2%V!d"(äÍ·ÞNñþ‹ÿ½ñÏÿò?øì?ÿïg‘ïú§Œ9» A½oÑ¡›‡Cn±Oý9^S u8~y@xù’�ê_j—öÀ½1¢NÝkŠýÏ]ÐGÄÜQð’wÑ3ê Á›ëâ…Ìü)‡ð~ŒñGÓ4¿{{ûäo¿óÎ_}ÿ�þôG¯½þôNUóšÖ´ÜÝå»óYÎwwù¼œsœ•)…ÓižÓ4Ïë<Ïyšg) sfä5CH ½~“ºURo�íÎ}-N±ÃÃV(XG�·¸³ u€ÌcN¹³e'âjÓš’­ É 8œç[œN';ã„ÈÁÕ~|÷^+Zm¬ËYI�ˆH6ðM+Öuu¢YËÖÐ=.€ZlŠ’U„Á‰PµäÎ8 ôìË6“UªÍ}yhÞ�ÿò09„0æÔö«kŽnï”Ñ«ÄF ¨ä#�÷—Ú=Qûs¢iP÷å\@A‰éh÷ÝÚeKXj s†¹¢õº+(´[U¶ìuosªÖá#˜VúAŸïÌ›üÛz{çrÝ}Ýο*VˆÛWO1V ?‹.(Ÿ Ô!O“÷¯'h×�®}Ç�2ç/çwwwXÎg¤É@8Wçƒ` ÖÖ*½ï·U5Ÿ¥Ëpw%m¹ÿ<‚‚*½ZׯZ„À‚Ûc�3ÉÆaí“\#ŠòŸC±_nßì¶w±ÀEÀLIÐöfwR€¤Cti*—u´¬–eÁ³çŸaúY„ˆàæt8/g¬i‡’7�rë›Õ`ÅÉ.Ô»0øX0š�·:°•«³Âr^°® $%›S;DÏŠžþÀl~¨’vF àVÔ3EØÈY¡ºX|‹¸Ë€ŠYñ³�6jÞœÖJ TeY¬ËâKSÈVÆ›zì ™7T!0DB§vÕMð*h»Qûu,uß+äÈJv9 QG9gˆÛqCµ’Å´�:¡Þu§Ï g�ÛÕW÷X Fr@ºDRp`A¹Æ È6h©’¤ZÅÇ©¬á”¿ÌÔN=_”ë…lT~nkE¾Œ@¨íÁ @Ãïå…@a$_#µ¹ŒŽ ]ßA—Ÿ»½FV#šN0ɶçaïP×ódëVJ‹´:?R•­­\£Vl�c?÷Üb=ªÊƒLqOXWsTY=â£z·@èy@[¸s\rò ÕýE³ÿoˆ½v„‡fß|¸T®ÝÚ��ËqÃbóy÷{u ¯Ý,ÈM1¯Ýý¯Öû¾¿'\Y³¨w¸`�R™¦¹­iNr*Ž}ÿC¶¶(ä&Aq…j± ~�ȯý×שºwíÜ7̲ þo]Ú~ÔûƺÖ6€À¡‹‰u»WeÝ­d¥ØˆÝÉ�³ ©F-ÏÁÉM…`‡õ¸¶Y?^ÅÛ-ðÎuÑÅïšÛß ˜�ìK™Ö{rü~~ÔQGuÔQ_¥:GuÔQGuÔQ¿�Ú{¸›RÂ4Åá¡Vî,`s—k Tu÷BDªj�„þäOÿÞÿá|>ÿßþå?ÿËÿöóçÏþ}ÇÞMûŠô_ï‡7±ýΛôúõ .Ø ô–®Hä ¿ýC‡ó|èÉ”«ò±Ÿ‡©×ÿ²)Ú�9Ðá‚hø ?fæ÷‚Yö¿§ùG·Ožþèëßøæ_{íµ»bRˆ1Oó”cŒ™ç»ó]�sÊ9åœÅü¬…ˆ„˜3å)Æ<Ís:�N˜O'L1Š&áÑv¸Ü¿=Qo›:Ügì+Ùêû[ÚS)•‡Ìn+Q LÕ½èB™j #*pç§›N§œæÙT®õ!¨8Ø#ÙµÚYÖ+HŠì–ÀÉÁÿi]ªºÍïf}˜kÿ§  °¦?çÞ"¶\í+V•bæ_SsKÙ­tU8^q PÕpÛÁTÚ±exçAÍÖ+¤SJ`^M6·Ø‘yšR�¤¥ªO(c‘ÇjN•È$•˜`˜¢B5�6ÿÊ+p®`Y9Áš€ÀmÂêíåm,ææúxEj$Äž"¶ÜŸ¢æ+`yßnlkÊJBvRFPv® ëš@L’«’ÓÜ f„èý(Ënvw¹GkË�_Î8ß�q^Î�ú¿�OʼêÀ‹gÑW«ì�¸Ïkî�åÜÏçÏÂsÖeÁgŸŽç/žã|¾Ã²®P…Yø{L ÇK;oý®(B‹ë@ˆaPí–è�l"oD¨íW?Ì#J�{DÚT4àYË|\c2ÜÉ¡ô#À²“‰¡j@x¸2rÜÝÝáöÉL1"‹Y 3œæùæ„5-p(ìsòˆ±ù¦:‰ts„õBN˲`Yî°.këó"ÒH¦®=Šúœà×GÌñó<#ð°žWäUäs5k(ŠÜ�‡y¼)Рªp“‘ øŸV˸'w®ÌSœKnýü•1ßÜ9FõÎ5õnÚ¡ï&¥®Î}?ÜE#4g›ê<‚Jލk˜÷KA¶È†5Y| ,ÁS!#âʦ£#&uªõ½|qÙØõoÛ£Ÿ‡kܬEE½¬�5»Íw"ÍÉfÜ 4;òâÑ;T‡˜ë÷1 ×¢ê#º\cwÌ2o ó¶GT’@?÷V…4Õù¤¬mÌTÏwu"¡Hœ[êœ^µîä‘R#:XãÓ…CÊö>õÅ<’ó®9ô”=QOBÈÀ?ºcè€ ŠûmdÀ5Âgsç±±Ù"½†=ç.–ÇIÕ�I.>kïóúþ=yÒ|š˜m̸=~Z×J.*„ R”ëuIO<ÛqÈé9³€|OœG¢†¹„…!Bi;¦ÊŸÖoœ|·®»³®uÝ�10gäiö²eÜ {æ!RÈö‘C€Lâä¨ÙÇ'Ub!{\@‹m÷ý\SúTßÿ¶{ú½}Æ0LK߆ÔȈ£Ž:ꨣŽ:ê«QਣŽ:ꨣŽ:êKR%�¼ÿa·CÍ}¶j÷ÀXª"ªJš¦yºû³¿÷çÿ«Ï?ÿüýà¯þ³ÿæÝ‹ÿ-QùþµG:<)Þ[ŒþßÄÕë½ |S•éE¼ÀÎñ/rNË3Q6GïûLUºç|ʇÑå÷îq0€‰˜ßå~BüÑ<ÏýôéÓ|û»¿óׯ¿ñÆó´&YÓ*9gUC—•ˆDšs6éh‚¨ªd+aóhu<;‹ÚS{e& ˆÂ™â¤%ó¸dS—{�yçÁhÝE9}í~mf=¨]•…"ˆn -yÖû­[@�&LP¨öHèÀƒbû«ÈY]Ñf¶þÑUdói6ÂC`€í!¥fS®™‚/Õ?³çÅð,o‚@Kö€×U…âŠF®*êPskCˆfc[Û:Tõ?‘)EÙˆ¸âQyþ˜ÚÞ«-еµ­½¦ìº–k›sÆê¶ñÕJW;bQÊHÌà´Ö‡Õ3Ï1 RŸ\•Ù ì<â * õÁ5ª‚RT;€¡E,Øu: ÃeL2ÌÂ5~ ŸT-׸Ü30 ¡Íb[€§Ì¡eœ”yµ'0›�xœâ È-ÀR;^Q0%aÔLo�ò¶Œ£¥ŽÁ2BjYÀí\Â�Ñ]ÕØ®ÂÍÒì©ËÜØg©‡À•´íWÍÊyGa\ì™EðâÅ 03Îç3`9ŸñìÙ3<ûü3¼xñ9 NlæÒ�£™Ž»‚Q¤Ù—(ˆ¢À®ࢦN×vÿ˜¤Úv—vëÕð>ðÑË;*Ö š§ÎÜ"Š)AÒ¬ÉCKUµ¯¸»»ÃÓónN71B˜bÄÍí D3Âb×c´Ìy(Ö¼BWBÅâÄ#H·¤QÓÿ×Üq›³,ŠdÔ .Q¶ï!Ìký&†ˆiºÁi¾ÁÍt‹È“+Õ D‹©®sFN ¢¹Þ›cÙûnô8Tr†ºCCHÓš kQä:™‚üØR€³Œ¬±8›¸·Ìi²É ïðÔEÊ´yì:pÕìÇm@H6�^s™¡M}NèÓÒ-þH·ÇáÞQÅ�@:÷S¥I piJšïl` ÃüØÃ*±ª�Ù6×Z×Ën,'ŸÓú¹cÛ&uÊ�rÙ¿WmÊ}Nµ¹<_¬!ÅõEE ÃšÞÍ1€†}Ùvw¥îÎSÁÑa� 2 ”R®��×­1v_ÎÞve�KNV+ã¾ÅÇ4;z;¾ ój#�puåé‰y�îËÎ/Œë¸«âûX$ „ÈîÞ¡‚ÕÞì÷>à Vú U‰Ãi²!îdÓT×ê²�ÆÖþ~ÃöØ7 �SŠ‘òÐ?°Cl�Ä /N$Ó<9i3Ôµ8¥B�Û•twï¿û‹Š�±â´pA�qoS‰ˆ>†ú÷拽r?vÆãJUè§4’˜$»ž†FXqõß�ºu¿w*±�ìóSÖŽt)Ãy^súÚîëuÝã0R÷‹ª¸�+pÔQGuÔQGýí«ƒpÔQGuÔQGõk®ûóÀJ©Ù‘6ÐçRñå•܉H"¢;UýüææöçògÿÍÌÿè¯þ³þ_~öìÙ¿µ®Ë¿èkõ][ü�Ðþ nj ª‘vÍ ·þ¿vÉ�ƒJ¢%G^‡Ïºß¾ÿnýY´?23ÌÞ‹1¼b|wžæÝèóó/ßÓëýîš²p¸7D»ÊâØRHß‚ð•å>1Bd€&¨æúP}K £©ç_s|™ýa²?8-`°V˜ zvÀí|>cYÜÊ׳¹)M%&ÙóÄŸV…–�ýy°wgŽcfpÖ,é�ŒRâ*÷òÀ–™/#|·c^Fðzï!í®òmg.Ø'墆”!/º?®w|am6ËSSZ¦„¥Z×°¥–'‹QhÊ5SG&$&³ùíTŒDŠF"àjñÜú³B¥#¡õ€@Šá¡ød-­=ˆhP@7ð‘«}~èÀ¬Ò~—5=EÑ œ»LêÀyÐú‰‘ 䎼Óú?·÷§QÓ¤¡êZЫê·\ôíu˜í»ÙôÛ8�å¼àyx†u]Ûý^¼¸»ÃÝ‹X×€X!ÆFp*cT:Œœ²§|nó•¹Î«’LÙ›âês¾ÝݬômÞôc V¾JpÚ6‰ÀÜO$K�WRN-Þ¿^EËj1 nv½…9‚G6$BfÔHœºÖlçïÀŒ,Ê^s\]ÊõoAʽ9iP—o"Xúù¯_úµ£(½·€ò@ÒFà´'ظ ð9™U‘}CŠlsBùœžL¥ƒ“UrP%Cˆõ·”F2U…Pd›ß är-=Ñ«äÞRT#Ÿ‰jlE§äfß{42`‰ZÊ»kíÞz-[�•»{ä{V[CE»¢a�«~�R‰¶ß¸$ìm¬ ѧü}Ç…ÍœZ¨2Œ¡ì±3~]ü“EIôný:7m˜8VREu"€ƒôÜ» ™#)µuÄ÷$SŒ˜â„8MÃZ784øÍ·s³u TÂA?ç{+ásDž&L%Š'µ6ȹÛª ø>�xÜ£÷àÿ5‰²Wâà„×iÖI‹óÇ#”0¦¨ÇKÐ=‘JcŸÝÿ™úK¦¢uÔQGuÔQ_º:GuÔQGuÔQ_’Ú{pkªSºj=Šú *"Ùž½º4ÔD_Ýýéßýóÿµ×^ÿ¿ðÆ_þ§ÿÉ¿ñ7óÓÿÚÝÝ‹ÿBÎòõíy”w?ôàü^"Ã×4gmˆu×0¤\®σú :4ESýï�[ý™óO˜è#ñ£øÃ§O§Ó»¯¿ñæçw÷Ý×_ã<ŸNiŠ1È"’—e•e9çu]²@RÕ¤*)gͦòoÙÀ–Km„Ùflæ !Ë]e!WIÆšËZ�T„P³W/Ú¸#apX*%†t¨ó¶M¯Yüoÿ]²mµC`›U°ç)s@¨,íá»=tµ t0åj½Zb£K¦0À`V0[î+QQFqµo/¢i1pƲ©›‚7¥kZ!«��€.軄gMsˆUÁ&ÃØ³Wc´kŠå~”ìb@%U%yÊyׂYƒ?¬WAÖ vRÃ%HÐOD��Z;¦¼kï\îI_åÁ°l"C pW²w{`»WõKä fÏï`i ¦ŠL ›³àV0Ÿa*ýüÒsœnÀ "…q;!FL®¦+àX›{÷%éE¤XºçJºq5~”fmž¤*MQ Ÿ&¯“`öç�Ëx #Lˆ?7�»sq¨÷ çjS_Á¾ÐΣVuc‘�Àáà+u@‹ÅTxdÆäÙÁÅê~MfÃí ô–ŒRl™ïî^ ¥4Ù3ÆSJPoWf†d-ƒ(¸sÛ°/o_Q(kµéß[?4g›¯Xwç¦â!DöBºó—^®@RqÀ¥ÒU*ÐjQ!9ÛueŸc¬¯Û\|:3ŸfL³9¯œcÄâ1 šçuA’ «îîÎ)<^›"Wá•¢@NÀZ-Ç}®*]O¡ûq-ÎÄ#â¹Z9Dß($[Üɲ.6d1Ìé$N¸¹¹ÁÍé7§'²8ðŸRöñê�Wæ O§AÉÙ‘œ¡ìÀ«»P`DQp—€Sow_\D.,ÕCl{ìÃ;cr!ØÔþÚ¹'UÕòfocI]îöF1Ìl±Lìn [ß ¦ÁÛÈÚ&eוrÖèD`ϦW ÷í´Uïí·ú×´x�f÷/Ìà+jß4-÷bA3¬;Þ?¹f”—€n+ê-˜+AC•i°?®�7‹IT‰Ø) ôœ�ÖƒÙ6ï[†HÈÛý—žÙ¢8ˆ0~¸º]ýèœB¾þ…kÎû0o]Yß$ ’£Ú×ûâ`îEý´Äƒªî E6÷ ·Áï"’°�mÚ7„Ù«ûá­/F·ÃTm.eŸéÑ;L�Ù¯ÅÅ¡a�ŒR5Ø£j¸¸UwŒ€À¾úù("È÷!LSÄ4Í07¬Ø>¿�’êÏ·�UB@– NÔi@%Ö¶ñi6ÿ[ ÿ5­æád™ò§¹Ø("buêèÁÿ¾ò@V”¶–“}F!ŸÚÚ��ÐØ“d=ðæÇ/\Uø_ûÝ“‰�ˆ´·I8ꨣŽ:ꨣþV×A8ꨣŽ:ꨣŽú’To«Ú×VÙr]½1(»@ �Ócž¦˜BëÓ§OÏÿ•ÿêýÿbü÷sÊóòOþñ~øÁ»ÿðٳ籦å�$çß1cíÊ•K¾l Û_XþWئº”‡–—שФ)æºJ?#?eâO™ùfþ4NÓ§Ó郧O_ûàk_ÿ懧Ӵˆ‰ò@&"‰!ä8Íùt:eæ�s&óz"ÊÄ$D¤Dœ2´š%gG&GCKÊ%¸(px€§ð‡×jŠÞÀž�METÛ†Lå\ÖgSÅåêCߢԤ.ûšTAB$ïõÏ>+¶|¯)˜`¯P GhQêê˜!¸ºUD²±x‡åM£e”¦6ÓÊUédnú•ˆY؇u©juæàÖð%¿wuÀ@ÜFYÑ»1—^Ælà2ÃÔ³q²‡®1Z–kœ¸>„�»{%HÒTô˺"­«MÛ,ëË/@ž¢æó+4u®h³ÌïÔúå={–·eœT…g÷™Å ¹Æ÷ݤöMçvÔÌò{À¬4{Û0''a°². kµhצ¸ÜÎg Ü(#b˜ZŽ;@Oêƒó :tm]«ßqå³åò@Q3æj‹ÝT¸D×ã%ãÞCw“fdø{Åèv7‚€­upháÌ1 H>Õlâ¢@RÑFý8´ø„  ןFûuÉç”pÆ]ësÐ!kºÍ¥Ÿ4KoõqZ6°£ŒmM~Ñ@²q)ý� ¥}'Ý€ÿ½Åµ½�ZžyO¾Øé�PEvÐ.ù¸µ5ù4ŸcŽ“ƒ Ày=[¿; @ �XÏ5GœÝNŸ©Ù•ÛœŸª“‰Cn6S±UïÇT³ü®`Šâ±)ÌwGD )-8/w8¯/°¦3²˜£P Æ#nnfÜžnðäö æ›ÁIJ)gäÕ@oÉWî'P£O´¸ˆ`M+èlà:w²Òw·Çèèq~»´Ô¾£R×™¢Ò•”*Š!ïûb?Õ¯×Ôìå'Ÿëjžvä‡Éhìù€æN­í¤¹mîø¨ÖÁI¦F¿p›ÏãÆ6|ŸPÜD Ø ';»øÍœÕ;±ô÷b»?@çèBînƒ{Ûßôÿf¯`üœþ¼¨®Î‹ ¼FʺٹEèèÚ´%0Tåoý Q€Ô¬{"2¢ŸĨƒ*;„ÑQ¥ôݾîõ«m´B%VÄÉök" 6Y¸â$Ð7mÏð8û÷]'l‰´�\Ê%&î”Ðõ‘☢êÒÂ�Á±Å¬ôóïv�¾ˆ0bªó\qÔa¡«c€“¸H2Lñƒ¹–ÌóŒi:!NÁ÷žæ%"�øX‪ίQw+Û{L Ègãc4¢Á²,XÎg,«í5Æ9 ’ê`4ìÕ˜º¸¤v/z‡<7œöfëÄÆ!ª “zÿx$plûæµßË=ÔMü…ê¡ÿ?ꨣŽ:ꨯZ€£Ž:ꨣŽ:ê¨/IMS¬›zÕÑÖ®h­¶–ú �]Å;-Ó4iœbf¦EDîdYbJküã?ù³Ÿ}ï÷þðŸ®ëB)åø³ŸýøõßÿÑŸ>öüOÖ´þ~Nù{"ùÛ"ò@O:жÔõLùmmô@� À½ïUÿ 3ý ýŒ™ÆÌ?æ~8ülšç�Oóéǯ¿ùæ‡ßúÖw2ŸNkÎYsÎ*9‹ˆ§Â„¤b‡W!dU¥bÍ/j²q%¢Ì�…ˆ…ˆ]Ú@½ˆp›¥½Ó*d¦Ì�êQ=·àÏ’—îm)üu¹dµ[·öƒX+˜vùà°©•·jû¾µ÷ ¹ÅúW‹ºÙ ›ÂO!äjtmŠoøº«ùÏJ¡pÀ¨¸®ªä;�§BfÌ�`¤!&® i!*ÄiÂ<0²¬XSÀ²ÚܚĢämhÀ3‘Ya7 «Db(r7Ý‘�Á@µÇæA1ZÚRª2³+U€ª@sFNK%³Ü�ïpw~†óù…å¡«ØùD6ëÿù„››[ÜÞž0M“‘«4ƒX½­E2²›ßUÝòß~FP€`';•÷š3;¦Ÿ ®�§t¡F/@WÉcßßcÔ~/æ\`skg0ße°Û{ªÜ­Ñ [NÌöÝÜÌú�ÊXwWšQBuÖÈ„6õ¿YËsŒ¾¦4�¯qŠ‹y¡Øžsàdì]z@‰º1 óT_„Yå "¹ j33´îhc•ÿÿgïìvd9Ž#™Uݳ<IÉ,À0üþáw1`ö�%Ã-ž�îÊôEfýôÌPò%5ˆO8 ų;;Ó]]U[‘�‹£Œ»ùÖ£óaõ§.÷Õ9@æ²y)ìøË¢¤?íCg§ÿ(±ËZl¸^�ù¯�ßuX¼²™Œ]Xׂ^x·þ÷^ Y³ÐÑV7�§"€Uø·éÆ1¦¼çß®û¶Õ«Ï­}ìõpŽYì©Z—ëV!fñL�ç+ÌżV¨)¤®�îåÉAÊÝFtÀø]¦ÍB¾nçŸ_SF1� «þ˜¯mkD÷ÿ Û^³ ÓÑÒ! »t÷ˆQèf:æypkd¹GŒÊ~öoQªŠò¡Ã¿[þ÷Ÿñ¸'ëÏXŒ«2öà±¶—¿ßˆLA¿†õ¨ [ÜAº“ÚÏ>ù Œ¾øë³÷tŸ–Ú›Ö b  „BÞ B!„üBØ[ËÁdØd¿Êí^»âÔûaqü}d²†xq»Ýpûø8÷­š3ÓÖN=Ž»~~Þõ8îr‡˜¹~ÿý¯ÿó‡~ý¯"åŸUµ¨Jq‡º»þÇ¿ÿÛÿõÇ?üýׯ?ý];Ïß´f¿qØwpÿ•;¾¸ÛwÄÌ¿Ÿi¢™h¤)äÏqò(^Jù“ZÑòß"ò§RÊ�¥”µÖÿݶíö}ÿñ›/ßþéþñŸþPËÞT嬵´­Ô³”Ò7[ݳûÎÜQ‹yØ´ŸÞZ‹^ô¶t¸g_ÚâÚGï"ãOØ»ûòßqíàkCÆÅfV2“ZVÛ{KÌ�–¶§NЉÙr€gK–0¦MvžV8¬–qlî>»¹Ö®ìy°Ý¿]/–¯ò–gg° !ÂÛë¬Û!㦥é8Ž·õðÞ�–‡èª#¿Ôš�,ÞñõÖ`Ãa …�ë"~Ün- dê!¦c�Žë·æº_¬‘MèÈ¢-C0U¹F-øò9¬ÎóˆîÿóX,¼¥Èr�®#?˜¶¯!üŸ‘£ÝÚÈòµ!x÷Z“îf°v$ª{Œ'Ñ‘;?ÇÝ,êïõUçÝuîXÅá~­J¾FØ¿÷›yÜ|ÞØ™�µˆ–8œ/e?qšìÓbÛqqy?/…�ˆÐ‡1YƘ“&Ëxœ�ÞŸk8ŽOœÇ'Žó_ÓªU ‰÷Ø.9Ê­ JiQ°ä`»/²æ3¯XVL/± }<È"’­÷hvï·‹«Ã°ñÏNÿuÌNA-F£YC1Ã)‚SSLQâl ªG|oë9Ù2D_mS hÚÆÚÑÇG·´ÑqÛÇE-êó[½¡na‡¿¨5‹HŒ–sÕuŠÖûg"ëÜãÞap+϶ÎCæ,{º¦ÍÄëHw’1%;ÂmÌËÛ¶�K.y/â)Zçuï¹ÝRP«a«[¬Í*)�§4:5SÔÏks¹�Ýe§°/½p³#Vå±»ÙÆ|ØçoEÆ{¼€çtDaÂO?ý„ÏÏ?ã8>#']Eû¶ãvÛF´A©uÄH¿~yÝ/VÞÝÝcÄ(ŠÎ¨�ZÃÄݸn¶8ã\×M‰Y…]yîêîÅEñLÊSW«{X}[ºXX›sÏÕz:ëÌ1Ÿ]ü"€„h·ínûŽmÛG¡Ïè�ÍX‡R ÜRh×gÓ÷=n%n‹ÆzƒXóz¢ŒgHͨTY\·¯…wæ>Š ÎãÄqܧèž÷&"@Êp Y×ó¾&¤^®…>}ýã}X…ñ¾âw{rI““œª³8oº¬{7»tô÷¢‚§È©WŽô\ =»Éu¸~À_„™�¢J�êjW_žö@ãïr­UÌyùq]�q]:¢Îs:ø”ÑÞ ¶P<½=¿^'oˆ+»¸ôõk�×¥@—;ƒ]¬0¯z×}]b7r=Ðù3.®/Ö°Ææ\ת¹ïèîH­X¸)-±E¤Ý¥ª¤ûIw×ñe¨gÁÀV±o¶-ÖKä¼k͆ۑ�èˆuδ¹¸.c_Rz|ÀRŒ³-Q«R)sß¿ZcÛ¶‹øo¶:!Ùa!ã÷´˜Cb¿¸Ь…œîs4�—{w[Æùã\°Žíù åëÙçŒ „BÞ B!„üBØöû¾£Öí©ÛxmÏ:\Æ¡ñ"–2:Z>n7ß¶­hîa™~¿G>pXgŸp‡P)"­¸»šIqwuwùíï~ÿÇßþî÷ÿ""’].¥”ªªZU´(­5=Û¡½KºY“ìt-Ùu¹o¶ßn¶ßövÛöV·z–²™ÍݽÅ!ºœG[[„º š­¹�âh@ª÷éñ-¥ç ‡pTÍQÎct[GS®6›âb\Üü§ä¡¾>Û„>þ™ÖîödËÛ;åjÑÈyª d¶íÅî¾×%˜ÃdvÇ…XhÙ§üx«—¼äxÑÕ×Í ÜSÀý+ù¡qðØÎùù»]¬ÁŸ,ïÛµ îQ@˜v±ýðrvÅ{Šä-tãz*êÙE÷WöÛŽ­úx­Ëó�÷ Œ¾z<¬[C§�Ö�„-¸eˆ•ñ;Gwôqž8îa;EPFþúV·ÔtŠsæ†v4œÇ1^ÇRX† 4ÅD8pzÜo;g‡7 ÑŸ\lÞK‰¼ôQ<ôzÇ¡ ε`«åÒ iæ8�†óˆ´ã´ufœ´6l½×®ëUË¼Ž°Á(œKlÉ{«»FI\ZfŸ§ðxM\²OÝF DŒ¯ -a'=ç„–ñ%Ñeú4/ÊÃÐg×tŠ�ÜŽÑý<,§W±Õ;ǰÝ 1ý"þ/‘–…(£˜e‰SéEK憣�ðvà¸øóO?âëý+»Ãâÿ¶‡ð¿ßnÑéºÕןS{EÉî~Y,Áó&¨Bk_û¾å¾E£ˆÃ= rüaΙ. �Bêóúƒ§½Îúw=‹ýbußG�†hóSÉû�3½Ï‚¸õµëVqÛwìûm¿k‘_âU%ælѧ}@.Q°I ©_€2:}}¶¹/Ÿ/r®q8«À×Åÿn?¾Î/=?ü¡üLÄÏÕ.|¸+¬Šëóù¸èÅfÝM¡xEVê«@‰QøòÚO?x¸o<ÜÿŸÛ‡MQ{óòŒÙÁ“(Ú‹õf1“Œnû¾‡¾\O}.¼}œ;ûzÅŠg:Òä¾BÅ[8*ŠëËB‡ÍІ3PwWÊíÝËgC—¾)ã{ìmº$\®‚ÌëУgâÃÔÎe]ŸÏÍtg¸º)ÄxÐØÏeÑæcÁܺ/‰()ïdÎ KÔŒ,{Ûˆ×Ù°¥k“Š ¹ÁOC;¦+S؈bÅdÞ3Æ L)Íßâ~6ض£Ôò4?Íè `«Ûåw·GW­^(Ó÷Ôk€è£õ¿Œ˜‡áBô2öqÎüKÿ­¿FYÜB\ÍÒÕçlËD!„�w�„B!¿.H*ÙÅ{íJY}Ÿr6—S-•è,ݶ{vov»Ìn]Ùéçìdަ4ƒê™�@jÝÿî&£kK®.­cŠh*ùïêî¹ÝM¬5¸D—Œ–âÑíZ\¢õÞÎv6sk"§eœ‡ÐÜ`fbm|0Ï^³HÏC1¹«³ð¡ªãzE7õ mQ,Ѥò-ùÜùÏÈB-¨Ù%'*éÖ;åó<,éóÀsÖ­!:x´6Åk¥Mþ8HÅÌÈËŽ¨ž;ßmð{@Y�)«9€ZüRp9ºóU0·/¿3?qv­=Ÿí¼XñÎŒÝ)¡Ê’oêùÕú×/¢@)¶ˆ²Pôέ†ãˆÏ�^Þ8JŒU·5H\°o‹¨¬ŽÒ;æ×nòìäë¢�™K·St¬\V"×Z<9Xt–¶óDk!Þ·óˆ¼Yôœïì «µl(e¿ Ϙݡ!7œÇ´Yí‚àhnKQIŽ'ï÷Hæý[Å]¯ùÙcxå™ \¯K-([ÐuZZj{ ÖÇqâ<î¸Ú]·cZºöV©w~¾Uü/(%ǎɰɎîÜkw\ïŠö`ÄX6 ‡0wž÷x_÷°[Ž91ž½ˆR)˾ÃlíàŒŸ2ÇyïwÅ*Wñ?^é@…JíœÏï[æ¯sÅY¯½Xå•è7ç¦þ ÷²ž˜-­Åýq3Ø©€õ±_ãs—M›g/†Z ÌB,\]»£»`[ë†�/ßâ»ï~…}ÿ˜…K$|)Èb4ͼYò½{ÍÏ*ðôûâÙ"r,*—îÂóãëQi�<>ÇZv�™òªkÒG£¸¨ÍnÝŒ ±æYØ !R…u´rcq?éVÞ²ÄDè´Õîvúî!L¹ùñKX_—nÝ¿¸XNÏ…YÜKJv?{®ç>?E÷ka_¿lûŽÛmÇívÃ~ÛrN{ôüD>Ú%ã>ßGŠ‘á\­Ø¶Š} g‡¼[Ö÷ù¸”‚ŠúäÊò*âhŽÅÕÔc|̯ÍXk—×ÐÕ‰¥Ïÿ²ºÝDÊtá�Åû(âŠy°¡¡�(›Ö»~Š{¼_Ÿ³[ôÇ57¸ÕQ°£yíúȹÌãîXÅ]&¢ó?%c¢®âþât£ TŒB†˜sZdÌ{óZÿ¼à7i¶¨~~|Ê(z\ŸþpޏF„Œø¯òX€á{Šªía´Ë{Ít±k¯—.kÓ1¡ïg1‡/=®èu¾ºµ¹ïinÃõdîsæþo½Bó‚ÛRü“þlˆ ÝÿºîYûïÖ;ÏetÚ¯óç(ŠêÏI?p¨n(zä\.Ë~r­¥xŒšX¯hcl÷˜›ù> Ü�Ze8éŒñ{q0Èy2ͶmǾ…øo<]™ŽãÅ•g{ˆNÂC<ÂrÅ{¼ÖêZð¸×­µŽyj-ò-eº¬mËܱºg=Ü­ÎDk‘ ^ÖýYô6Þzߟ¯ûõYõËsùê9*O`H €œŒ „BÞ B!„üR6fuY“ÝÂû"ºæáNaÖî¯Þ×�¶´”‡ƒ· zŽ·uûÜ~¨5Hg7•ˆXõ³ü.O=§ÿQ¨›«Y“Þ j­‰åAt0zé]…·fvofnÞÓŽ?tŠÍãÏüGëBzf)¯â¶KÌõk¤E¡§¸gîjÞ"ÜŒÍ<õ&éçÃó€Y–�Cãµ `±»ïÇß)þK—òÓܲ½<: }س§Üníž]ðçìd³´Q?§6HkqO‡µÿ̇ÿõ¼qú þ?"®‡£­�iO;fŸð™·Þ‚gÇ¥ÂÌSD�ƒÇÖ,…õç™âÿq¦Û@œfñFÜãgQXÑñº"ª¯=:¯“-U 6,úÃU«d¤Fˆ~v†ÃÙÅÖµs3E„ZC@ªuC-5ż>>RLÈ˜Š–8€@Ë«ûâ€ùÅòÿ�»yéN,ÏÝŽ«Ø¤ªÐªØJÅ5­ÍUò3·Ö|N÷ãÄ‘"»Ã–ÃãìZ}*8è‚­ç�µöüe‹ÿoÒ-Ž—PøcTÅ3»yæB·Ö²#öÀ‘â-º˜—Î'Ûçñ GWþƒ¢k·Ö‡ÓÆ9òxg”ÀÕê8 B4 Ááósº¨ôy¼G*Äü;]J1”tÅxU´Ñ¯ÛˆÎ»8¸eÑA‹"’óœVÓÝ5@KA­'¬mðj‘cAAE+ŽZmØÊ÷Ÿ·5]°Uìû†o¿|ƒ_}÷¾ùøRít­á8ï°OÀ[›ªŽ!ü¯E?#uý켓ƒd™ö¯ó¿øÓ”3b!FqO_¨´•ìø-Ãu¡¯µçYpQ Ê­g†wŒ¯rF‹´g×~é³§B²Ã½ cÄX,Î#fÏ£;‹ Bx«£`¨³…»C»¬ÿ±®¥ˆY4ŸÛ(lèBøy8(¦g×ïÛŽ��ö�¶=,îî+Î6‹–õ-ÅùæU ö}ËH�ê¶Ã¼á~ ߯�b±~z‘Ñ!"—ýÍËcî²—sK�çX«èD%:îµ@K¹¸j<Øô÷sÆžÙßۥûïÁΜ¿çûš"ý(ðZ¾^´¯[OT"o{樉b3àÒM}™G[›kj;/Ñ0�Dý{4cüi½ï�Éö²›ý1#¼mü çš~¿O{w X]t}y¹Y‚;~v]»|Åòþ.k×òg�Ëz^zTŒŽ $½rÉ( ¸F9ź�s—ËËŽÿµxeü]·nï1"—".¼XéÂÄÆ´×—Ã}1‹étÞ•'ñ¿ÇV wÚ)?óSñð~æu˜¢´Ž¹{½_kºB¬% ¹úž¡�Óøý¤ægØæ{U…Y�ÈñT7"  ä\W±o±·‚h íHG¦û=Ü1Ζ×Å£#Ö¥>ºòxƇœí̽h¬«zÜ#ò¥®¢~Î&ÝößwÜnØoû%ö©Ï¯ÜLfdGyr为,<îïðôl¾\Gí¹0ED Ežžï¾Ç 7à¿Ìs„Byƒsf^B!„�_]�è‡ÎÝîõ<ÏÑ]nË¡ùš3Ü»Tdé4Y;›:ó`éµõ.²[¿wÌiv‡˜›OQ P_š4EâîâîÒ?=sîÇÁÓrÐeÞÜóÖÌ[kÞíúgBJY«÷n)ÛmÒã}õ”Ó¸k矦@8îHÉ=¯Gv¼º@^tÆû¹fnF×XË"‹E˜êfþ»šÁº,¯È~ªq]Gn‹CY¹f8Ìf@;Ï<€íö±ç¸ñzñýç©ÙñuO‡ 1W¦ýjk G)P,¶Íy�%—q˜cÕ–÷â)¾•Åz9,`kÝ£Ø&Ç\/X»ùZs¬‡Ý5Ÿ·8äm8Â|5¨èwÝþÞÕºý³;Ü[ ”=#¾�€üyµ„kAÑšï[‡È|ÑÉz¿âóóH�; 9TQË2‰B¤ŽùbÚÿcü»JÿÞ†ÖBXˆ{½tãù¼'W[\…H»Ì]gk8Ž{SDq‰–‚ÛmÃíã·Û Û^Çû„9\%‹zþû*à4dïÛRPãfvæjÆIL1èHw„㸂Rê2G—'á¨)ŒÌù®;ftËç3Å‘gÞ»ØðÏct;ÆúПQ�žeX[æºô×P�÷TJÁ–ŸËÍQkM1BÃ5 -Åo·|ûí·øþûðåË@ÇÑðõóúUÐNÃ):3¾1;^{®·Êœ[×ÿ »ù>ÏØÒå/²8�`D³DnDz§øt2™óU(Si1®™dAC­¶½b«u¬™!ÖÊRë×q¸ß?q¿—°çמ”¥VèÙ n�6#´”ÙYœâeCÄ,¥ c=ˆ(…J:EX/L Qê8Ï!ÈhvÆ–E°.%®ekQ¬tžGq¦óŠ–ŠZ ö�n·[>Qs.s,ä!‚Àcå±%—¼GzHŽ£Z+¶Û ß|ƒºoa—Ÿ.C8–Â�E\îE1}ÿÒÝÆÏí8ª‹{†.U¹FúC6ú(JB8�¬ë¿”K‡íµXò*¯ÎJæ>ã_îó}j‹ï1]rîf-SbÍŠ¹uÚœW Q”K'ût´éë^<ß>È)¾#ŠË�r”±ïë×qì U†Å}ÿ»³Ç©ÀÛó>p“ûç;�3 &s_2¬Í³£s®z4‚qsØ+ýù!æÄ×±ö°ÏíÏðº¯êñ>½QšÌ¹pYCºóÇÈ{/5Ç`¹„Ìb0Cïò7{,ȸçöõ}ýüŽ5â ŸÌ5lq¯êû*W…çFeˆÿÅq²Dî\£sz1²hõjõ]U–ËMèâïeû´îLJã”�â«~­TÛòÿ£�ó8œg{T�•’kÞÜ_õy­µéë¹Ï=³ j‰ËuN5 ç–ó8ÐÎÇ‘…LèócÌ3µVÔ­GA•ËÕ´,R:�þŸç8Žp`éN8KäÏeŠDQÂ~‹X•múá<ÑöpýÙîâwZŸÙÖzQäóƒò¨÷¯Å·7{µqãæˆ˜‘(œ�«AÌQLqð×qB!ä­wÚûB!„B!„B!„B!ë(/!„B!„B!„B!„ò· !„B!„B!„B!„�7€„B!„B!„B!„BÈÀB!„B!„B!„B!ä `!„B!„B!„B!„ò°€B!„B!„B!„ByX@!„B!„B!„B!„¼, „B!„B!„B!„BÞB!„B!„B!„B!o !„B!„B!„B!„�7€„B!„B!„B!„BÈÀB!„B!„B!„B!ä `!„B!„B!„B!„ò°€B!„B!„B!„ByX@!„B!„B!„B!„¼, „B!„B!„B!„BÞB!„B!„B!„B!o !„B!„B!„B!„�7€„B!„B!„B!„BÈÀB!„B!„B!„B!ä `!„B!„B!„B!„ò°€B!„B!„B!„ByX@!„B!„B!„B!„¼, „B!„B!„B!„BÞB!„B!„B!„B!oÀÿ žÀÿð–`HIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/a.png0000644000175000017500000000742214757047403021204 0ustar00paynopayno‰PNG  IHDRÝÞ¹P´sBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î<�IDATxœíÝë¯UÇñï)‡Bim…r‘‹ŠZ.ª¹D.‚$PkiKÅøÂøŠ7ú˜LÐ7&"rǶJ,B1�R@44R¤´\äÖr-§íöÅ:‡^8—½g?Ï3kÖü>ÉNZRÖ¬5³Ÿ½ž™5óÌÐAD"l®@A'ihÇ Û¼PcgDJ6 ùKgøóbmÝ)ß‹ ÇÚ¤º{"Ò6 :‘` :‘` :‘` :‘` :‘` :‘` :‘` :‘` :‘` :‘` :‘` :‘` :‘` :‘` :‘` :‘` :‘` :‘` :‘` :‘` :‘` :‘` :‘` :‘` :‘` :‘` :‘`ƒÿqt50ßyw?rÞ†ôHoí©Ç ð_¶ï¯Ï+ÀîAc’±é­=88(`;ûçlGº¤ «Ï’B·%]Pzo&ðþ©åÈg80dd2¥—5[츽A`Aàödšéâ=FÜ,7òy:dd2Ít5š WÃv�N¬a»² ]¼:/jè‚J&”^ÆÙxƒøÔr䳨Ë}”2¥—5¹Ø»ÆíOæÕ¸}Aée´Ò»úÐzJ/cl¡¾Ôrä³ 8Üy¬òqJ/k°Ø­îN¤uB©‘f:À³Ô?Ë�|Ö£S‹hšé‚�N^)Ý¡Àuw¢­t1r¼x‘cŸZC饯éÀ»ÔŸRîúyø¤ã¸egJ/Í'Ïé)Àeuw¢�tþrNãrî[Ñ”^ú9Š´.Vw*9Þç·ÑËŽ”^YJZ.°²Í°­‹Ú” h¦ó1lÀvVZ¬1nS…‹bh¦ pö%nn2nsR_%�f:¿ÃvFÚHºâ8ØlÜöJ§} Û}4Ó±Ãtvö>Ä60~±Cû+�Û>e¼dgJ/�-Äþ<éæþl�bªpQ0ÍtöÇv&ZÇÎWA'ÿ3ÞÆZã} ;ÓLçèËÀ±ÆmÞÄð¹À°�åÆÛ˜Cê»8SÐÙ³¾Ë£Ü2Ê·N1Aw¨„QziÇ£ðÐêq¶÷„ñ¶Þ"ÏûDK ôÒÉÅØm–q›ñ¶f·)£ÐLgç�ØÎ<ï3þã7c_wå¾>÷�ŒNët¶b¿îb»÷osðÙŠû@ƦôÒÁì/L�—Zް¾ ¢ÂE4Óõoø7¶3ÎËt÷zê½€MÆÛ^‡®l[ÓLgìLìS²[Içky�ô^qK‡§·)Ãt6<Ö·ºI-GhÍ®a”^ögö…‡žè±ÀsÆ}Pá"[J/ ]Žý‚ò =þûökvS€K�Û”ašéúówlg˜ª�Ù�}=–‡+ôCF§u:#s°ý’wH%ªzÈ¡?_è£?²�ÒK#nžøŸ¸ü¿cYìÐfëi¦«fx ÛYe¤$CU3H@,ûô2*\dA3��o`_â`9é~˪6wõeÄÀ¹Æm¶š‚®ºÜRKË6v¥5;cJ/{wö…‡ÖaS˜Ö#íUá¢þ)½ìÓØŸçìZ’¡ª-Àííìh�´)F4ÓõîIlgë÷€mÜ¿½ß%#;Ó:]NÂþ ý€C?sèç\‡~¶…ÒË>äz%¢M]P1¢™®{S€7±�=&*ÉP•G•é·èo±Í4ÓUt ör'éËlíUà^ã6U¸È€‚®7MI-=ÛVŠi@éewþðÐ+tW’¡*�:œ[IE˜¤7J/+ð(<ÔmI†ª>V·9‰´N)}ÐL7±IÀzì/ÁÐ÷“úý¶¯un­Óõè,쿸‘‹ÍO;ôÿôÀþ—@ée�<.ÜèÐæX¬K9€.¨ôE3Ýø<  aÿ>òñŠýE .ê�fº,À¾ðн¤'¢<Ïøoÿ©b iÝRz¤ ›XÝ5-­hÍ.#J/Çæq·þFêyÜ4àí ý�èóùÈA4˜ÒË.]éÐærÒùP´w€•í.rh³xšéF·;éþEë™áÔÈAìÂcé£Û�´�Öéº0û/è:ê]Tž¼0J¿úýœ9ˆ†RzÙ�‹V%ªÚ†Öì² ™îã< Y—d¨j6ö3Ýf`¿ÈA4�fº ,ƾðÐC¤GÖíàã6'“Ö3¥ ºÑ-rhÓó¹¹^yôe©C›ÅRz¹3�»ò½J2Tµé±ëqž9ˆ†Qz9�‹^%ªz¸Ç¡]]Pé’fºí¦’΋D—.Ä~œo¢ÂEcÑ:ÝaÿEô.ÉP•×âÿe‘ƒh¥—cðH�¼K2T5,shW)f4Ó%ŸÁþõÁà‹‘ƒèÑ\ìÇ»˜9ˆ†ÐL7Š+±¿Ek-©¼y®Ö`_6b°Ð¸Í¢(è¯ W7:´iíV‡6—¢ÂEãRz ç`Ÿfm!¶$CU‘új=þ¯F¢”^îÂãä?º$CU€?9´« *ãhûL·éŽë_úù‘ƒèÓìÇÿð‰ÈAdNët;øö_¸ºJ2T5…tÇŒõ~Ðý˜Û)½Ü�G´‚zJ2Tõ>p‡C»J1ÇÐæ™îìÝ;Ô[’¡ªÓðÙŸ‹DÆ4Ó óHÖ:´ëm5éÖ9´ÙhmºÉÀ7Ú­»$CU|Öì“ç½§µjkzy >éÔìÈAóº.ǧ,¢éê%° û/ס#ðñ öûå7¡#ÈSëƒÎë.ŒïDÂÉUØï.RÐñì¿X¹•d¨j:i¹Ãzÿ|?rj}Ð=…ý—ÊãÙ´º,Ã~ÿü3tùiuÐ}û/T‡²ªŸ}t|ä 2Óê »û/Ó+Ø×ɬÓn¤¡­÷ÓÏ"‘™ÖÝT`ö_¦ŸD"È5Øï§×�="‘‘ÖÝ|Ò¦œK2T5Ÿ}uiä 2ÒÚ [�ý—hmèbýûýõ‡Ð䣕÷^Iºˆbí‡6sáQ~ýlàÓí6F›‚n1öu;¶··™“ÛI¥ú,©píH/½^†èQš<7wa¿ßž¡}…‹Z—^žƒOJ“Ó›x¼ÜäЦWªßm˜éV`ÿkÝ´’ UM^Ã~ÿý*rhÕÕK¯×B]9ˆšýûý×¶ÂE].\€Ï‚ìe«Ç9n¥iÍ…”ã)ón‘RœJ •t*—¿Ö­Ù•t“�Ëëî„Lh驆Ö(9è.ö­»2¡ƒ�³êîD¤’ƒN©es´êX•t­ûõl¸Ve%¥ÝbZvžÐp­:ÿ.1èHA'ÍÒš³Ä ;8¢îNHÏZ³¦Zbеæ³@­8v¥Ý4Òý|ÒL^÷Éf¥´ »ŒxÒL3� êî„·Ò‚®éIáŠ?†%Ýlàäº;!};— •tKh_Ý�M"�Û«” ®¨»b¦èÐRž?›ôÎ9kI¥ÀelS�ŒÛœ œB3ßÝÞ•žÿ->O6�æ™…Ï+“9ˆE&š‰Oá¡wÑòC·À~ÿ¿MYû¿¨r ñYP]IªX%ó¨r]ô�MŸéÃ'µY;øšC»µirÐy¥–·2|²+=óH1¡À› ›˜^Bª¯ï‘ZÎ Gi�—±?&›i~á¢Æ§—KðÉóžth·-¶�.BY›LzV²M›é€gñ™å®G©NÂçØ¬‰„ƒF¯Ó�ŽÏAÝJJ[¥ÏàsŒŽ‹„±F§—^'Õ÷“.OKÿ–9µ»Ø©ÝpMšé¦á³Ô–Ž£tGâsŒ^£¹…‹›^^…ÏÁÜLºPì¬ÁçX]9C�M/½RË»�7œÚn+�' �5»¦Ìt³ñyX²É¿ž9;ŸµÔ!|ªxkäL·Ÿº›€{Úm»—€¿8´;HoomÂL7lÀg–»>pm³Ÿcö/šW¸¨qR.Àçàu€3ÇÑ6ÓI7B{·¦= Ò¸ôÒëäye=�œ›MÀ*§¶}A%÷™n_|Jt€kÇÑVásìšV¸¨Q3ݤ^=x]Ö–íVá³3 ˜çÐnˆÜgºÇñù¥|*r-w>ÇðÏ‘ƒèScfº/Ç:µíõÀ¥|œ×¾> 8Ü©m7¹�çÉòrǶeg«ñɤ€EíºË5½Ü“t.à‘–ü5p’üŸcù"Í(\Ôˆôr°·SÛº€ÏkŸB×Zs�éîÃç—qû·ÌHwžÀç˜6áG4û;R< é>ËúüŸcú>~Y‘•ìÓË¥øåéºjYŸÛþ¥7¶'p¹C»nr›é< éõWõ{ŸcûHä *Èz¦;¿µ—;Ñë¯êæuþ5—†.Ê1è<׿”ZÖoð¡SÛ‹œÚ5—Sz9ƒ”z¤¯ãw§ôæn|ŽqÎ…‹²M/ç“ÞþâÁóVzã•q̤!/óÌi¦û>¿€à”ÀqÈø¼^«Õ~8Ž^d¹Nw>¡¬§y�÷—î|Žõ©(Rn²L/¿íض×ú�Tçusø–SÛfr˜éIÕ£¼fº£ã†"]òz­Vxšü2›�fºÁº{2l?àZ§¶ßÖ:µ-Õm¾K:­ð0ØèÔvßr˜éDJ—å9�H+(èD‚)èD‚)èD‚)èD‚)èD‚)èD‚)èD‚)èD‚)èD‚)èD‚)èD‚)èD‚)èD‚)èD‚)èD‚)èD‚)èD‚)èD‚)èD‚)èD‚)èD‚)èD‚ °½Üøà…û"R²Y¤ªÖ �^µ{­Ýi�¡ÝH/b<¥š"Þ¶?ý?ºp}5¬éøUIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/a.svg0000644000175000017500000000513214757047403021213 0ustar00paynopayno image/svg+xml A ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/add.png0000644000175000017500000000072614757047403021514 0ustar00paynopayno‰PNG  IHDR88¨†;sBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î<SIDATh�í™;Š„@†—=À€žA3L¼…�©à<ƒ¹÷é+ˆ™Q”Þ`“]ƒ=3®[M}ÐIwS]–”À}oÌ«³8“�«8íoˉªªàyÞ¹¼LÛ¶(Ëò×ÜJ0$IòW9½˲VsÚ—( R‡©Ã‚¯`Y ÃØQ�y<¾‚ôaAê° uX�:,HíWŸ,öèºÃ0(—R>\ïûMÓ(żßïp]W-�ŸC!·ð}_.÷^1Š¢ØÌOJ)…Ëý£ö%Ê‚ÔaAê° u7ú,Ë”ÿYÔu�yžw×ÇAš¦J1ã8VÚlôÏ`šæÃ¦†áÛÎ’’½ž° uX�:,H¤Žö‚‡¶Ÿ¡®kLÓ´»nÛö™Ç8Y0Ïó3ÃBûeAê¬îAÕOéÿ‰­Ü |¿ùêʧö%Ê‚ÔùËk8üì¦ä IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/add.svg0000644000175000017500000000431614757047403021526 0ustar00paynopayno image/svg+xml././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/advanced_user.png0000644000175000017500000001103714757047403023564 0ustar00paynopayno‰PNG  IHDR‚ƒA_ÃXsBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î<œIDATxœí�{”]UyÀûÌÜÉÌ„8™<€DBb „D0i‚Tp—ÆÔdœ¹wY<Û\Š/Ô%ºJHY‚¨M[+˪P‘¦�ÀäNÒÐBWi»@+T�3@j•T„ªI3Ãä5{÷�}îäÎ}œ»ÏcŸ;÷Îý­µ×ÌÜ9{ûœóÝýú¾ým˜š4ià!àÀŸæ»ø-ð"°8ËFåØgðYà%@¤k*ä½+È3<¸@ÊN•ÄÉb`p’bÈ¥ƒÀ™eòOöùäUÀ+ÀFkwÐ ~ˆÿKÌ¥�2ù·æÚ,ÝCƒ8€Ù‹T«—Ç óžÚíÞŠš«]�„ø°ÀðÚ¯y?¥÷óF Å0ï>àõõj�0ǼEˆ’¾•Ô Å�Sí $Ä÷’óÄä4I0„ýႤn¨Ax® £®A™¼Ñçÿoþû-Â-eäÏÞ�^xšîTb úۨЋ:»€ÏïDÏéW£—…“,*àKÀàZà.ôLBæýÿa;�¡ÁÓ”)Ç�ŸÿW+]jåILa.¥ú/5LÚmãaLeî£ú/5L’ÀùžÇ”dºé¯öK ›¾ÿ# �¨v"p Ú'¯ÿü'z–qp.°¸Ð‚¬³ÑVÏøâûvžþ èô‘·x!F™ ø@ÄgÐxžx^ÆëÀ:C™À¿Ç$÷00?Ü­7Èg5ñ(ÃÕåÎD»ªE‘ù=`ià;nP–à&N-(MÿRîú�ò›©í±Ù¤f>ð·1™2PÖƒ4œ]cÁ^Î"ÈúV9wG�“õæ�ð³×¿‹ ë¥×¾AN"Ô›"p­©ûY9êÊIµÞ!Ȳm;zA',K\»¸,‚¬†,ö|°øñ�òZÑ3€ ²$ð]F+´ _fØéã/ ç~þÙ�òÚ,¾­L bà"à¿ ÿBr鮀rW^ñòÓ 07èM7(æ'D¹ô5Ìö.¾x5F¹7„¾ûãÄ© íéÔMéM? �;‰ßì½>–'I.u¾øþΛÃÀ6à§åÝÀ©]Iq2„ÞŸ�3C/!~4èmxç -ŸS†™˜÷«0s ?�à#÷É”>oôäêŒ÷ì!-7,÷+Ë�,é(pºá=&BR Joxý[ ¯»“ÚlZï~]íJä“”", x½©"¼„¿GðzOC’C/åö3¢Ð <%ù>ÁšÎ Pöbôœü$ð,z]à�ÑÊÔ„vrý¯€òæQà}yu{zÎMè �{u«yÎFïÔÙ \�ù¬ã Á¨©eO =özõZXæºYÀ�Ö!LÚ`XïšfÅ£�P9Å™„{¨~ޤgPl_8@ycзCÖ#HêªPçšç|ôº|©›B+Ëñî2ù*%?k�KùýŒ¯RzÞ—³«_ÚêSçšgf;‰ûÑ»~sœ�Ž_¸ß o©ô,ðI&zúÎBÄ*åýµWïs˜¸ÕVzÌè‰Ö ¬½â÷0ñ=øãÀv´ÚËòÞêÝdž˜êR)¥ÎVÞF2QFl¦×Ð�2ï�ç0pzŒ"€wQhÓ/­ ó°'3~ÛÍk)= üs€ë¯+ñ,î �?¬³KUñ[P âÿ7™9Ž™ ´ÂÜSâ󛀟ä? üÀPVÍð.üCÖÖBCOéZ�Ï¡p—»ö5ü§Âk(?îîVV|ª5ʨþËŒ’¾Pp?zåo'ÅÑTÿÈày|½ Ï>àT^ó¨yšÑË¢Õ~¡aÒãøG–=ø4°ïÈ„:ë6¦ Wò›¨½ÙÃ�Wï1ãRý—$]iç14€p›L«‘¾mëÔ3AüjeZôPµ+P‹˜š‘Sèà‹"ÊþÅKÿ üíÛ¿x¯—¦G”ñ$§––ÄÌF¢5×GÑIgW�3ø²w}yïˆ|Ç Jò0á_ÊËèõþ ¬¦ô\¦©fÏM¨…]Ã,´Áe:ÆÏR´9yi‰kM8¼Ý­å<à ¯NAC/+?�vcô~ÝÚ$†ëºmRÊy¹¿¥”ûvíšTŽ« _îjàvà÷ˆ/ÞZôx ,ï#Þ Ö½Ìü4p+Ú—1V6mÚÔzäÈ‘n¥T¯b%ÚcªpŸÆA¥ÔsBˆÇ¤”¿k×®0_”XhÇ‘s-”ý z Y娨¶ÝêÄ•W^ÙyìØ±›ÑÖË™Aò*¥žBlÉf³ÿW}‚"Ð}ª Þ�ŽIG9¶�C ÷ŸÉd>ˆöyˆÚ¢îVJ}t``à—Që[Špí\Çæ“f´«\˜±B%")‚ëºMRʯ‰¯J¼tg³Ù'c,³"¶6¸ ‡âæ~:Ð Ü�ŽŸ¸:‚¬ƒ@6Bþ²´µµå6á&Í˶˜*¯€¿‰AÖFôÙÍÃè8ƒÞÏath™ËÔ©…v‰‹�;vž³Q¶BˆŸØ–ä¡ÇýÎ@;½œs¹V¿=Bˆ(þa8>66öˆm!¦Šp.ÚÌZ |•àQÜŒBÜKéhi¶Ø‘„G“‰"L ÚùGI2]ß0á÷+Òßß¿W)õ]e—@¢&µŽ‰"lC»±Õa«p)埠jØæ‹ÙlÖtK$*)ÂzàÃITÄ›‰o™{»wïþ…”r#£¾*¥sç[åâ·j¸=å«´a23ŒÞìò¼�Âûúú®SJ}³³‚ð½±±±ìÞ½Û–¨¿ánj[ @¯Œ~ÃVá;wî¼G)µ–xO|`ÆŒk“TðoÐw’r;þŽã¤Óé³€Û„W~ä€Rê»b¬š1~ç"´Q‘D¿ ý=J©UèE³Åx>!Ä!¥Ô‹Bˆ§”ROd³Y+ãÜŒÙ~ÃßpÊP´ýæ-—žA‡·ÉuQÌ¢À* Ïž©Æ§ñ�¤:@é¥âœãK%¸¶L]æ¢ÃýúåýL„{mP�ë)Ž@zÿ€Ü §oa¡’+·‹n…òóHj4àe­q§bìÂÌ­�`!lúwϨ3Ñ­‘òêõAó[i•9w/¡ýñ€å/dbdø 3çý-æ'¬äjÂ~6àõ/‘üÙMu…_@Ê8yí™dÊ^[‰Šëº³ÆÆÆÎ›>}úÞíÛ·[q€©I�»í¦fÊeh?ÇIC:�¾Lq;^|&!Ä!Dº¿¿ßŠ?¡·ÓúôŸ}J©m?¶! ’k‚¸Z�`µ}}}oWJ}Ž‚`J©n/"J¡çwI2™Ìf`}6›5 "¥¼H{^(„¸<“Éô;޳¥¿¿ÿ…·`DRç>îþ={ðã8z+QƒK)\×½$“É<¨”úe"¶H)ƒ8Ù^¼óV¸0™.—RîËd2ôôôĺ 0)EøÚ8Ë'Í@‡á«9�R>Nå�=A¡p6lØ`zÔϪ2Ÿ;€ÛÔÔ4˜Éd¾ÙÝÝ=¿Ìu�HªkÈq”„£š™âºî%RÊ[¤”kd ¢3„3€×ý.ìêêj¦ò1Ê)`s*•º:“ÉÜ-¥¼-Šoc’-¤$�N_œ×Q€e[·n5z†J©™Ó¦M«;bîܹçah½D/Ø}Ìqœûúúnîîî›"éa² úúúÖ(¥>¬‹PNûÞ½{¡Fõ(D.ØÇi•®[*Dà ]‡RêÖT*õÑL&s‡ã8Ýßßo¼ÓkJ)‚ñÃÀõJ©Xâ7(¥–a¦3•R(¥*~cÇY¦Tè Us�mRÊ-™Læ^Çqþ²¿¿ÿçe†•VktwwÏ?räÈ£h¯ìØâ+:Žc´‡"×5˜(‚”riÔz¡§“RîO§Ó}2¦„"ôöö.K¥RO¢Ï²Œ)åòJ×lÚ´©½? º´3K\4 !nO§Ó÷nÞ¼¹¬³PÝ+Bww÷ Çqv=hG9*¾´‘‘‘qßO“A[‹•Wæ5‡úb¹ÿ×½"¤R©»ÐA?¬ „¨XvA\_EH§Óó°ä4¬”º1“ÉdJý¯®aݺuÓfì C‡Á¢N~xÀJ]CœÝB!ø|©Ôµ"´µµ½�S}³5ZZZ* Ç¿áŽãø¶B›Š°ÂuÝ"e¬kEB\š„œJÆÜŒÁû½Ò!ŽƒM'OžüýÂëZ°0K(…·Ep'¿Ï¯f×€ã8—}f[h5BD Á_E�Ræ�*µÖÁ3ŸO n¡··÷t¥T,–9*ÍŒaÆ íøT J©©£”7ãÚàôÞÞ^¿ ÃF]CKKËR’y'ç\uÕUŸÔ­"! îÑÜÜ\¶{B˜®#Xï<ıcÇ.Èÿ ¡1!¥ô')‚ÂöŒa¥ÔŠü¿ëVH>Ü�Ÿ"-()¥’j¦†"xýßâ„Åú M»†ÄZ„™C]*ÂèèèJ’¿7Ó®¡Ù³FNÀótŠÝØäÃ…®ëŽÇǨKEHz|à±ÀÇMlÂQD###E×=óÌ3gc)$`ÚÉ ´^—Š@uŠT*UÔ´{ލ…±§‹Æ ØŠ�RŽ�Š#¥LÒóæÍ›IÁ^)eQ‹P EÈ0Ö�"x¦gk!xýðü'0::ZtB])ÃS’SÇŽãÔ¯"´··_HüqM)R„T*Uäd"„(5…¬F‹0>s¨;E ºá‚‹º†|tÞg¥•‰+ðÆ+®¸b4!n—˜u …Î)===3ÑÑ_çĉ+ ¡qÓ422²$ÿƒR-‚”rB×ÐÔÔ”øø GnÀXWŠà-�$v8g)JØŠ¡„»Z5º N½DåxÀÈ”˜B–:×zB‹P�Cžì•PgŠ ”ªú¹%¦�&ƒÅªµÀ2×u[êJ˜Œ*B©a‚"$iu,A XÞP„øYê-+ç(µYe¼kð®­ê!èRÊõ¤¢”/^héìì7�—š5�×"Ì�;÷ôñÇÕ¤~¡§§g!–Ïe0¥©©i¼{È‹‹0Nþ¡ÊÝBˆu¡©©)…>Ы#/uü�È7ÏÛðòyM8L!ó® #NN*¥ÎªEÈf³û�ý®q]·-•Jµ·¥R©NÇq:¥”�BˆN¥ÔøO´µ¢/éÌKs0³cŒ˳Ùl¥qK-ÂQ´²%!Äa¥ÔøO`Ôqœ£RÊÃ'Nœ8¼jÕªW·nÝ*ëFLðBÉŒ¢ү”áºnÇØØØL!D‡×ìwÞ&–ïó g<-FG™†„CJ©¡ü¿¥”¹¿_Ë}æ8ÎPkkëPÔè¯{öìàÿ‘įQ_(îÍIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/advanced_user.svg0000644000175000017500000001774214757047403023610 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/axis.png0000644000175000017500000002131514757047403021725 0ustar00paynopayno‰PNG  IHDRBCOñ9sBIT|dˆ pHYs??•ˆlÆtEXtSoftwarewww.inkscape.org›î< IDATxœíÝy`\UÙÇñï3YJiK¤²)È&úª€Ëk�—¥‚€E@A#ÍLZJªUQ6Eר¨ øÊ¢€…¶¡MÒB^�}_­ˆˆ€Š‚•}oÓÒ½IæyÿH€.sgîdæÎvŸ¿lι眶øë¹çÞs.ˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆˆÄ†•{RšÝëF/c®9ïJ;Ó:¶´GÊ=&‘RI”{RÆ.åæ$�$Œ”{<"¥¤ ÒpÜz¿<|êkþ–² F¤Ä„ÂñË}<0i½56ôsl¹Æ#Rj B!ÑOhXÿgéSÊ4‘’S S7þ™9{O[滕c<"¥¦ Œ¹Ï-ö÷ÈTV—¦µÄÃ) aÌ $8>¨Ìa*îzÅJjž‚0ÆÚÝë�d–*ï˜Þ˾¥�H¹(cìÉ^¶ÍV'�šHíSÆXbÃw32cró3>²ã)aLÍXâc1Ž Quì˜1ù€DÊHAS &¡fzæº=–Ú¦ Œ)÷Mß ¬ ‡ÏxÍ·Šr<"å¤ Œ¡éË|W`Ÿ<.iè×–;©a ÂJ§9Žü�`Óí±Ô,aܸ›A*ïëŒ m¯ùîŒH¤ì„1Ó¶”‰ÀNúx`*R„1ã!ÞÌB[î¤&)cdÊ‹>Êà˜𨱭—ÿ)Ú€D*„‚0FFð)`L�Í衉Ôa¼„~w0�q¬¶ÜI­QÆÄÔW}{`bš;z /B;"CAõ ŽêŠÑ–¶ÜI­QÆEq¿A2I[(cೋ}oœw±Im¹“š¢ Œ�t]AïÑí±Ô ½[ãšÝÇ,åy èlOðì±b·+Rjõå@%ûâRoZë\l–¡xúì&ûký¿Ä�0£=CÑ ;Œãèv³þ°mm±ŒOx!`u¤€ïDѶH))³¸xœõ¶-õ{q¾™¡ø¸€™³Ïf÷F[Êÿ›|SØ`Z>!àÉmñë㙂ûw‹ýg RjZ#Ì¡~?rx:CÑ~Ó—ñéb÷7¦—¯�!�Þ>Žyù´5e¹¿8´(ËlÇi½ìaû"%¡ Ìaæv¶Ê2Ïqçg3ž÷Í‹Õ×gWøÖgdì*Á—ÚÍÒù´×ÐO+ÐPœÑe–ÐC© Âf7Ñm°0CÑÛûFrZ±úI÷q°ÅÆ?w˜;g¬ýaM¾¥.m¹“  ÃÌÓÆ)À&32ƒoLïõ íâø¥þ2× ëÏ<#Ífú/°g¡ã a‹-ÆpD ú‰Œ‚0¤9ãìA‡Ž E#ÝøIA�»[Â9� fœ9{¼=Ÿw›F[AcÊCZ[î¤Ê)óÐ_ÏÀ²M œ–é½~ÀpÛ=¾—Éûg(Z´ùXÎË·½v÷z7Z†;žPÖ{Nl0é³+|ëHû‰�‚0óÆØËfœ™©Ìá¼f÷¼5h~ÆGZðŒòÔ ÍÖæÛæS½| g›|¯Ëˆ¯â×û:š#íO$B Â<½6– pþ™¡èýc–å;:f4§™ÖïœÝd×å=@À,ºwƒ¸éöXª—¶Ø Ãô%þq7nÈPôrvïh²¥aÚùìb[:ÁcÀ¨�ŠúÍyÿ¬-íÑ|Ç6´æ`D¾×J[î¤ZiF8 ³¶´͸)CÑ[yl9K×q›† ¿N¬I3™†àú[Jêêi-U¿"Ť .ãd ÓúÝIŸ[ìïÉuyÛbßÏx”Õ’�:~8ìq%JðîàzÖ¿¥p§µÝ]ÿMIÕÑ´Ã4k¬=ü"CQý@"û“Þv÷ƒu6]š0Θ»…-Θ¦-óÝÌ™0œk‹dÇg–jË�Ta!úù>ðB†’�N_â�ßõxj)ÇÞøç-ˬá'áLc(\Ëx ‚šHÕQ`öx[ެ çŸè¾ÉZ]Û+>ÆàG™.IÃ)=fÃK»{ÂýÍ5ºr=søŒ¶ÜIµQh‡±Ìþ¸ñÏvYµŒ7¹ ŽoÛnücs®˜Ód÷wÏ,ã#; ÷ú"ÚbÌŽ,÷ Dò¡ ,P»Yš4§�ánÔ�ïÎxÅß½¶¥¾3pr†fVcœ^È8ÜKû�$+m¹“*£ ,‚Ùo±ûݘŸ¡hL_ýz;Qœs±Œ§]Ÿ=«Éžnÿ'¼ì£�O ÷ú6t¢HUPÉ@?_VlüsƒiÓ—ù‡Ûzý#ÀÑ.}¦o-çÒ÷Ú>E†÷¬î~üö�’MŸ°¼fN ã,œÛ€å!ûh¨ïgrȺ"e§£ú‹dîVöÜñKü¬ {‘žæçÀ茧ÍÛÆVÒ·“sKÝŒ+�_§{ùMÇN¶æõ‚é½~Ìù·é–¾Y[Z÷뿘áÞп”ý>aÐÎúlðéñyü6DÊF[ìŠèD÷+—ò(°kÈKî›=Žý ùæÇô^ßÑa™g÷4ãÜׯrm�ÙºL×·õúµÀQÍ¿:»ÉÆg*˜áÞ�^Ê‘iã4œ}2ÕI ð_—meÿóû)'ÝÑ…fk„~è‘N'áÃGSØôïñOn<»É&Ìg=A!àÃüÇp¦YßeMvõìq¶o>üyã:im¹“*¡ ,²Ëšìê¡õ´ìŒ™—�³ íÏ}ƒ�¯L�=Ž sÆÙ]a®·ìA*¤/k²{vÇàx w½«?æz‘rSFÀ�S�lŸÝì­Oç{Àf\þÕ7¶fôÀ²Í6_üÆ"ôh[QŽ¡‰À…ôUù^¥5˜qÜHq6ðµ ÅiN¼0Á„ß—zX"…X ÜÌ„î;‡³F¨aŒx³×ÑÈL - J‚‹¿#WÁ—rh"ùrà ê®2›·²�Æ4#Œ Ÿá›³ŠœÃsVÞl üôk°å’ŒL2X äz¤XuV}~¾;ƒ'QWšg�.¸Ô슫QÍcÀ“ÞÄ*®Ãɽ]ɼça¶\òÏ …kÁWåh DÖ0x;S‚:¶|Miêô­‚†µÙëô®:Ø ¢¹'¯¡r‚p%p$æ@ç½Ã¹õÍE3Âç­¾-ÎÍÀž!ª`|Á:í²¨Ç%•Í=¹Èû5”"{˜ ›Í7›½aÓ2Vîœ]ÿÛþ Kû�ÀȹáÛò¶â=#±?аÀ¬#ð”£J §ÆUnhËÜ9ÀWC^rë˜l=–ë=Ƀû±»@݃d^—MƒÌlþíÅï·å@°;É<\ þ!³ù�…k«u[HÿÈvLe./¬wëû�Ú))aófo¤‘ÈuŠÌ.ç9>k÷XÅÝšÔ÷ÔqàÅ/Aß^f=/¯¿æñÐðƒÇÚgªÑf6NøöR?Ï´=—¡[ßôå0p‹YÏÀ0Ú(+a•ò)>Š4=À¤PgÓɆél­¹§æ�·f.µ[ ëðbìŒ|¨‘¼z°ÑcÖý™ðí%w#ÜC¶×ý¸úºÍzªz?¦Ö«�'½‰47û†©Žóuë²s£—¬û"4|xç¦eþ1H� ]çÞOË©‡à ïsy6x6áBð%  êæ˜Í{4Ï>*–f„UÆ'ûvÔq ð¾Õû�Ï[—ÍŽxX²÷É‚Ä}@c†âµ�ÞÇlÁ_†ß~ë ý;2¯åõƒ`6ÿþ<Ú; Ò×f©²üF`N¥>õ-”‚°Šx‹¿‹·;„¨¾ §Ùºí¦¨Ç%›roùØOŠŸ€Í>0œý³îSFÁÀ ž“©Æfóý=¸ÏØVÅ?„sÎøÕ{�#­Ûî‹z\d÷ŸÂ¿ÉP¸+¬>˜ž»‚Ü ýçä×ÞŠñl‚¯Ý@‡YwlviFX|ŠDšk€1!ª¿€1É:­‚¾KOî-[Câ!ðm2×°”YWwøöRÇ‚/(~Ò{™-Èûy÷–À&€]ën,ôÓ˜ÕHAXá<åG3ø/t˜…ìEôs¨]a%;µC²soùØMdþÿÚ2¨{¿Ù¼ÿän'ë{ЉOšu^WèxãJ_±«`žò€ÿ#\>@‚}‚•Ålþ-àç�…�+Üg4dkc°¼¾‹ÀC4ü|…`a„Ê“~:ðKÂýÝ dóìåhG%óô@ÐSâÿ†íÙ¯_qvæí{<#"ܾº5®0C[æþ8%ä×ÐH‹uXŽc䥜Ü[w…ôƒd^çMƒjÖuç¦×e½µÎk �SV�¡-ss�cC^ÒÁs|N[檃{r:ô„—À÷4›ÿÒ›õs=lÉo �Ó­q…ð)>ŠF®#lg[—¯¬fݳ|ð•ÉÖ`s·Î�{{¬38éQ�‚°x³oIšÛ�ÃÂTÇøªuÚ7¢—D¡ï è)ñ$hùòàÿü×7<ã�EÃØB'YèÖ¸Ì<é;bÜJðK²ë[‡1Í:m~Ôã’踷ìö2ohXv*ø…å}�ÞßlÁ¢e¼(Ëȧø»Is+á¾»h¶.»9âaI ¸·| ìÌa\™×: G·ÆeâIÿ0i~C¸ìú¶ˆB°fìþ`“§Ä9 c �„¡axÊ~MØ-sp˜uÙ#ÑŽJJÍ}êöÐÿ°UˆêÃÞB'¹iFXbžò$p3áBð1êØ[!X›Ìæ>Gîog:øt…`t„%ä­þe`�uKÕ`eþÌ:°¹ötä“2ê»x*{?ßlþõ%NL)KÄ“~:Î…„ù3wîb3²{%ú‘Iy5žIÎÏgš–°"¦?àˆy³×ÑÈ/�χ¼ä×4�Ô–¹Úçž:üfrÿãè`G™uÝPŠqÅ‘‚0B>ÉGðæá4‡¼ä"vãDk·t¤“²úÝ_�mC^ò ôíQ̯àÉ›tBuD¼ÙGÓÀÕxÆŠ7eœ­Ý"ñ0¸�®a6áC`<4t¸3©_Á“ i�0Þâ[ÓȽX¨tàT…`œ´œ PøðL@Ùa�<)š1Å›n�‹Ì'û;Hp+–ésŽ›XLµ.»"êqIeúÝýdùÂÔ�†ôÝ@]æ:‰ f�úCiFXDÞâ…!Cp%ÎQ Áøü]º›Ì!pºÙ‚¿˜u. ÚF7ÒÝîÍ##f,)‹Ä§øÜ ¼-Dõ%¤9ĺíÖ¨Ç%•¤ÿ—®a·@÷oþú¹v èÛÄÿ ÚjWD Â"ð”A𻀷„¨þƾ6ßB€[ªŸ{ËgÀŽ (~Ö¿þC�¡�¨·¯\ó¥Á³K1( ä)o®6Qý °¿uÚ?#–T÷äÎ`—Çgz-Ƭ{pbpËéYî“3}˜]ò¤ ,€'ý$àrÂl™ƒ?‘æ[`AO¥¹O¬: ü��kÖ}SÐõfÝs�®€â­ Ñ1xšµB€Ãà¸y«·cœO¸?Ã;ÁÁ6ß^�zlRi¶;Ø' ðX÷íÜmô}x< ðxüÔá�M^§×gò4´eîb ìQéÝŒbšÍ´¾(Ç%•ǽu"¤ï ók0+!ñA³ÎPË$î©ÿ¿�Ìw}`ÿcÖõ§†k57#ôféx$ï“|�, l:¿`7¦(ãgp ]º›Ì!pBØ 9:Ѻ¼Û½ytÞ Æ‚Г~ ô’ä�>ÉGµíi>Ž-¹ øt¨ Œ³­Û´o8††¶ÐÍ"p �]9´ö—§ÝÏî(Ü~–›5„>ÉG`ücƇؒ­íßš>îQ}ã Ú2gÉS€# ~Yefíi°©À’€*3_Ó‘|ÕLÒÄç�Þøµ³[1šõ)¾ {…¨¾#i�ö«bô-ÕÇ=õ>àÇÅýà­f]AïædÖõ,øŒ,5.qŸºCp¹dRAè3|sŒ36øa‚wÜî/iB¨P]i�ve¡ýJuÜBçW›e®aß5›_ð‹ôfó¯ŸPÜýóÜ›ƒÖ&%ƒšBVòe`› ~æL(¤IoñIó[`ûÕ‡X—ÝVHŸRí.„À€ï…u?-^_õ'A[€†ÓŠ×Wí«ú×g<å[0¸î²ñö¶U¬£Ézl]Þm¶ø‘$¸³±ýIê8ÌæÚ¿òíGj‡{²ºè…ú½Ìæõû39N²é‡ô~ú|8µ0#<…Ì{|7gæÛ˜·úT\M¸ü;°¿B0ÞܧìäØBWÜ0ë|ì;Åõ�èro óµÄØ«ê ôi>ŽÁ rt^íµúÉ8„;¹ûÔq€uÙ³ùô!µep Ý@06 Ê/ͺ¯�n»� ÜP¸ ¬>/º¾kGU!}œ4e©ñé0ï:nžòŸâœG¸å‚ÅA6ׇªÔªm@ðº¿Aß×£ì}ð•o^ ¨ÑæžœåjAÕ®z‹oM‚£²W¤Õº-hÓúà–¹ü gzÈ®;E›v‹ˆ{Ë�`w’y÷Èð fó.ÍXR“Ào$óÿ§—{™uçø~r|UïÇ›_—É‚ƒõN"àôŽ¡-sÝ8Ç„ìõvãÔ×w‹x³7Òê ÖÒK³ÆØóåFmK? uo'$–™u>Qª‘˜uÝì>e¸JäýÐ0NªrFè)ƒ§q¼¯µãë´7hcš�£Ÿëqö Ó%ƬÓÚ7øáà{†�„vi¿µNÛ¿ÜéպFøm†à z³¿qûâÓ|ú¸'dŸß8E¤vT]zÒwÚò»ˆ÷3‚/¾q} �=C\·˜l]�§ ‹H ¨Æ5ÂïîDè 9gzÊŸfo qÅ àhë² WD¤FTUú7iRü|,p Áçíï%˜d ì/Yk­c5õ<0Ìñj7�à÷¥ˆHµ«ª Äù>á‚,H˜kÿƒs˜-° £Ñß`WØ¿¡xÇ}…5´ðª,UºÙ•ÓK6 ‘*W5O�=é{a ¸©„]¦�KXÇw¬Ç‚¾VÞì#‡B0èËy¯ádÝV®÷EjFÅ¡ãFŠ?,C÷ËpΟÀºlØ_.Ÿá ¬ä×ÀǪ¬Æù˜uÛoJ9.‘ZU¹A˜ò£�«Ë<Œå@i~eóío¥èÐÛ=Átá¦Ù‡qôƧéˆÈðUdz»'xœ¿ï-÷XÖó(ÆU pýü1ªwõ<éçaœTŒÓfÝÖEß"qU™Kg2•‚ïÅù ÒH¯'ýÛÅîÀSþã,!ð… HñUÜŒÐ'z=ÛówÂ}T½œVZ—í•OúIçV0¾e�öãbõ'"oª¼C¶ã8*?ûpÎ)Vcžòã€l_»P!(�Ššz³7ÒÈcÀNåK€0æ’à"›kEùN­·ú'qzúGÉ™K7Ó ÛøUp)’ÊšŽ`^q!˜î™ÉóüÚî±þb5ì)?˜4 °À¼†ç™®‰VÅÌ}šoFOÛ—{,C–b\‰s¾uÙߋݸOñ ¤¹ȼÎèÜE/‡ÛͶ¶Ø}‹È†*gFØÏ‰TF>€3“ÑtÚL[EC_¿»‰ „?ÐÇ'‚"¥Q3BoöÑ4òoÂ}K$ Ë1æ“æb붇¢ìÈ�õ]¨g!°m@•GYÇ�åÞâ''•1#lä+”'ÃéfZWôGXùdߎ:n'8aª)­²Ï}š�£�E@Si:d- ®#ÍLë.Ýê†~Ÿ÷üÑçqö·n[Tª1‰È òÏûø:ÅA'{¬ÿ&Í¥ô1Ûzì•‚û˃ÏðÍYÉ ‡àRœ�+EÊ£¬3Boñ­H°Qo¾úÒÇÕÖcõhèÝÈë€Ãª¬µ.»¯„Ñõ”wFXÇ7ñHBðEŒË‡~”í�éB�>IDATÐRoö:FЉ†à:œc¬[!(RNe BŸìÛá|¡ÈÍÞ‡s>£¹ÆfZ_‘Û΋ãÆ~…ÓPe§ÕºíÖ’LD6Q¾aßF¡¥eW0À¥:30”çàL(uŒ/X—õ”tL"’QYÖ}²¿ƒ:þ 4ÐLä/>—§ü»À÷ƒ+ð5ë¶sK7"ɦ<3Â:Ú^®zàç¶ÀþRÜA‡§ü²‡à‚"•¥ä3BŸêïd€¿‘_ÿg}\ZÉ/{ÒSs >ðö"ë²/•rL"’[ég„ü T¿ÎZŒ«0.±N[ýÀ ã-~$Æ‚C°›Ý8±”c‘pJ:#ô”¿xˆìŸxã2Œ‹lž½\¢¡Ä[}_œÛ€QUn`Ç”ûI¶ˆdVêá™dÁàFàvãVk·ti‡5|Þê{âÜHpþŽ“‚"•«d3BOzÆâ�ú|˜E—ëÄçRòuüg|@•àLJþmdúXc=¶º,}‹T‘ÒÍûx�Fþ|çnà’Jxñ¹ ƵYBàÝO–j8›hä'À7ËÖ¿H•(YZ� x»ïËÓŒ²Ù¶¼TýFʲ† ˆT‰’®­ýÕFŠH̼ͨ‹ˆ”PùÏ#¬fÆ“8‘Ÿl=lVÁc‘Rû9ú*jÚ8±€IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/axis.svg0000644000175000017500000002763114757047403021747 0ustar00paynopayno image/svg+xml Z Y X ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/background.png0000644000175000017500000000744414757047403023107 0ustar00paynopayno‰PNG  IHDR}z’…\�sBIT|dˆ pHYs)È)ÈyDÖtEXtSoftwarewww.inkscape.org›î<¡IDATxœí�i”UÇofH ƒ†€$ƒ ‰¨¬"« ;ˆ+[ÙQ!ìáàB@>zeQ8Šˆ àQ8laB‚�„E ‹BHHÊD“@Éaœìîžm^JÂNȈþ<T�c%pTsûW"Î¥‡Óû[€%|¸¸øf:V¢Ih‰ý½BùL¸ 8%|wJ4qÒ ,Q>W.N Þ£Á'}0ø¯òÙ p 2¯/Ñ�'àOÀîÀ[Æ5?Ö£Á¡‘0 ØXNÞdJâû-,ÒA¦r{oç'?tïQ‰àH"àdRoÅâÏ~FÕëWH#àyäÿšqþDàç ¶U¢ Q¢^v^6Î\�¡½½ˆ,$Ív^2Î\´ìS‰ÀÈúdÎGˆÿ‡q~"p°F‘N•‹<Ãñ?çnŽqþ`à`hÞN•‹¼ïà…ˆs÷Wãüñkæl¿D@q¼ÞƳŒóû·k°Q"ŠzÛ�À^ÀÆù}‘×Àð‚vJ8ÂcеØxÌ8ÿàï”Ä÷xÍ«ÿƒ<ñÓŒó#‘ Ïû�ì•(Ï`Ê2Ä�{Ô8ßÑ}n=G›%rÀ;‚6ºû°°%p?ðg»%2À“ôí�é¤çÍo < làh»Dx‘>xX?öÿåÆç7ïþü�ì—ÈÒ÷î¡ÞI{Ø ËjØ qü>ìЇP”ô‰è˜g�]�©Ú‘ÀuÆõ›3�i]‰&¡é'"«jñÅ•™Èp­¿¯Ž~e´3xøh�¾”È€¼¤OF2fâ×?ìü;öÿUÈÒëF{!Oü9ûS"²’^.FOмIŸÖòæA$5'?5Îo€8w–¶®„²�Þ \œ¥œ»ø2¶·¡ œ üØ8? qîöËЯ9p?=â¶s�Ï nF9^N¾×ÄF{Uäu0>G›%t¬&`„tÒ‡SÑÉ)šû>Ùh7RÌîU°ý‚:Õj†÷RÿÔU�3€s v梄6Z‘ÛNm”ˆ!‰ô‘ÈûuçØÿWÇ!º6ÌÞ3ε!#ÑnN¶J`“¾ß6öÿÀ¡À/�ì�¤U%%R¶w²z]œ ‘¾1ò„oûÿ2`ð{'Û“it#™³Ãâ'8ÙÔˆ“> ’lû”sŸƒÍh®)õr¨iÈ\¾K¹n(òƒû‚C=j½÷·©÷¢" 'hC^ š·~+=Ù³‡"ïyísï"1��#qÊ?æw2ÜŽ=õ»‚úQç`ć°¦s‡;õk0 ŽôYè7v~…×EŠd�ë€Dù,â�têß@GéRCgQŸ‘£�ç+‘•º4ì¼£\EîŽvêç@Fêð>¿¬Õ-€W¨'k9pP†vöA÷7ªˆÓ÷-§þT$’þ(~Š”Ï åKâ$-!_xu\÷µñ“ŠwyÀ"sì=& ?™ €m ´»3RùÊr<¿] í�ŒL±÷<øe‹�s‘ª§ ´ý"œì4Î_|¯@ûƒÞ¤O®¥¾0ÁldáäE³�׃Eüù”•¯áEz©4eEÙvGT®^XŠi,LFVðJ(ð(2yº'*çn#=£& ¶DÂÁ)Ÿ;ù~g"ï²Ý(ú¤··¡~p ¾„ï€L)ã" -Vp:p%e¤ÕPäf¬‹xþû*ç.BæÎy0x€zäüî>¼j\W–ý܈oš±%vx’p;?�­Ø«"‹EI•¯¾¨?EàBzRã:|V±¡�™.Öèåê‚Mü à+�ú•…Io~�þ…µÒ`E`• ™Óf•$¿šÕ¿ÛAFߪÈ2ñ�ú—…HoCždí‹z˜ˆþ4=„¯s!iôº=WÏŠIDÄ Ÿy�›ô¡ˆÞ\û‚Þ%?ŽC÷˜ï&LžzR6îÅ)׎Ç&¾ q{¹HoG h_êT瞈Nø�„Q¤´b/«6:zíJrå«“]{œ™IŽ^íq%þ…û¢ªñ#”è°©Dí1z�Å®|âáÈ‚L¤¯‹�v”¥ø_#°<æPòâ5ÐÓ¯»€Ór¶ù9d[qí{T�ïërn4Lzðê;¾ÿ¹èÅN™%„¨ 1Ý?éN)ض&ŽŽó ¶Ÿ ‘>]Ü¿ÿ¬µëP%CÖB„‹q{žuf·C×ñgõ¼�Jú¦èõ\;i,í¨QT�dÚM¹?9S-,áƒwúõPdji‘^EJ°5 ‰¤_Šž”°ß„Øf>k# @q{ï_u´3¸]±£Öü߉¤/S:¶ß­0[‘Ív›Iø:è‹w�/9Ú†=’XÄ_EøÊW™wvðLýM„òl­ÂÞ«bíèµóç#óø¹Ê¹èå°F¨#}¶Ñ‘çñÝÐÞ’…œÃŽDŸ�,Ã×!µF’—éIì�ž±¿%\å«:Ò55ˆV®«,©pÈýÈ÷ˆÛ\Šïæ~–„JKìØ�ä’g7&•:¼'•ëʃaè!Ü•À×íÔª'ç�ÌhI¨’;¬ctÜŽå«DÒçâ»d™$µô8½r¤wÚrº„ª‘ÄŽQè¯�èð^gH$Ýsg„4©plŠ.|X„¯¢Æ’PÍ¢ñQr}totÜ�<4hŠØ¡Q©°'6G�1xO9-‡ì²�’Ö}ŠŽ%øÌž‚“>ýì-I®Å6èš¹fI¨Š”%Žîù×Þ·M õ:0éIRá= ¶ma{ô8÷<š#¡º‡â‰V´0:Þ¦˜ˆ#éE¥Ây`-e¾€oŒÁ’PÝ…ŸÃÕŽ9²ˆ’ü‰ AH·ÞsY¥ÂY`%-OÊ·;é› ¯Ê…”ôZ;2z—³ÖÆoÂ7z¶/vž]ü˜Cúþ5q¸’R*lÁÚ{Õ»ðŸ%¡òÞ!Â"|‘ò¿¼£™éÍ� Ç1}|_áÃ8ôDÇxî{QX„߇Lÿ¬jš‘ßÒ¨~Ï…ôfJ…#Xª’‡ñ­âlI¨¼×¾÷Á&<š ´bë ª¬¾ “„¤[ï¹F;�Ö¶Óð>€NDZî{VX„O§> —”ÐèƒVˆôÞ� [‡,»<4KBå�Ø‘…ðD2fÿ ÉA¨Ü¤[ï¹�Rá“Ð¥ÂÞ{°X*oåÎÞè„?LúˆU~¢\ ��´4ä"½7¤ÂVÙï5çc©IŠä¾[(Bx„´’g‹ÐgM™I·Þs³è=©°´¡Ÿ{˜DübdÏzh�tí=W%¬TØrR¼Eá‡;Û MxKôY¥'0•ôfK…“*0{O—´w¡wî;ÈbÐRÅ–7á¬YNY�¯½¿u¤O5. )¾Ö°yž£Ëë QÊ"üÂîÿ–Tú¬Ö/K;T 'n®7lzæêY%½CÔ~Û=–šðÇ�^ó.•ô�Rá[{]À$G;­À5Š�U{›ð–ÏT�l-’ó=B image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/basic_user.png0000644000175000017500000001112614757047403023077 0ustar00paynopayno‰PNG  IHDR|yûÓE sBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î<ÓIDATxœí�yx\ÕuÀç�,™¬ÛrX L �,$` ”½$¸@eq±A~3²qiJ!”/À�†|iœ²fF.PL0à”Ô¬a)!!!1KǸZ àXl Ûx‘4z§\�=ÏÌ[æ½Ižß÷ÝÏòÌÝÞ=ïÞ¹Ë9ç®Ë�À÷€•À à*@\Ò ,6¿f‹°Žu*¤8 x t(8Cÿ^_&íg�-yirá# 8*²Z×ñMðu`; ,_èÁž/“6^NŒð9êxä~Ü…• /bF‚|þÞGú~àÏ"}š:eù¼ +þ)/ý~˜aÛOú£}¤à¾É£‘±>ãç~Ë{€M€ Œó™Ç ÏøuB$lÀ/¯$œU•' €Uë T�AàÙ*—¹¬ÊåyfW8˜5sµxX]Åò|±«ü™*–5l{7Œ®IÛÌ$k}‘ïVb~[ÝvÒÂ`m‘Ï€#€€·�ßV¡£–Và—lŸ0½ü�Z0¿áÕš°9˜mÚ“€$ð$;/ëî¢:/ߨd)å�uù> �{‰w^�1Ú9ï <Ü ´Ç¨çGÔ^p•„ãÃo’ÑËî˜ Z­…VIXz«ŒbâÔ^`•†AàÓa7L9bÕ,,dn&Õº"˜IåcÕ*p¤®Ã÷‹(ïÿcζ?ö¦3�‰˜žæ’êˆóµL&üÙùzàü2e6³}’fÙ7UÔ» ¯ñ7ŸóXîu!”—«ó2ÌÆPXÀ•øWN(.óQ®°ãÎ^�°ø0&Àsïòì ,!xã¯}–yj€rr½ú˜ £:r2ðþqw€²ÆP\ƒÕ-ĩJ�ß×o,+ÈËUóUÑh;ï�¦9`YAÒí°¬:X@Ћÿ^÷t€ò‚. ·`$w Pf�!¾ˆ9yÊŸù Y`Ÿe^ œüú½œàYwivRìh24,Åûdê“­–JËTàA`�@O¿ ’³& k×ë&Üç4“1[¯a”— © Ú`—a<á6zî¥y’â;n Àßb´QÃ,W�ÿ ¡=�ÿ†ø©Kž§Ès¸…µßDµ6^¾ Í—]¾ø]€|‡·›«Y`µ~H€4“0 åè �ïpÁaÏÐÿ“`CÞI.ù6ãmM<U™ñÚxa¤‡·alµ~ | ogºS”îjL›�t™ï€×0³p X‡ ü¸câäù¾¸¦Šõ Ì7ØùM}žòCvK‘4^Ãí.õ±)®Ñ Ívg7TP¿áý‚öØø àjàNàVà3.Ï5,ø¥‡Ç-Àåßž<¦H|¯¡”uÆd̶d©ú¬aGå@!ØÁJ�0* ¿GéÆÍÿüI`Ÿ¡4‡Y^m¼-À,vÜô8øÀCÚ^¶¯® ~Ã#Øw›·P^Ø…áCŒS›•ã{ ›1Cá>ÓmÀŒ0—„X/á´m]s,Ì„È�°ýÆ ’§ßü? ³Õøw´w͹†è8Âf`ÆÍ¦ß´¿ ÐÞ5ç-jßèµFصÃþ½u?/þ~»Z”[‡o­Z-†‚ÝrÇ–obõùÑ6]v¥ªÁ\jßÛ 1³ç\.÷×ìÜ,Œ'(/e­Â¸qXÀÔ^X•Ï ü5fi¶€Ò6åfT;¸D{|³L,5�|£H¹»§Ö¦LÁlbÔZp•„î‚gjÆX‚öØ,F«¥³ØQÈ[0KE·“½aƒ—ߥ3Ùî8g¤YM¼†QYÚTâû©˜çkžó�ça+—5˜Ý¾ÞÊ«9üè¢ö=ÕïPÞO°sø:•àW©½ ý„+"i‰Ž×ãÑ-³Ð¨pO­+1’™ÄÎ3Ô(‡ã0òù~$-±‹ð�„'ÈŒÒÿ©˜sã}0«Y˜“µ°<'~€»ïQO±Y÷8ŒÁúA˜5éÁ}íOTXÖÆœ÷G˜Ñ¢‡`NèNÄ®’•Á¯€—0;_¯aæ!¬ ?ßÌ�;÷çZ–u”ª¦ª{ˆÈz GD–‹Èƒ]]]U;CÏ5æ…ÀE˜eʾ”³8ï~ËcÀñçŠÃ+ë€ÿÆøW¹sf:ííí“,Ëú¶ˆ\„ûH³¸:�N?E]òŒç߉(ÿÜP~:f×Î܇Ù%‹Šu˜ˆV…™éìÙ³O·,k1ðq?éTõžþþþYwÜqGdç抦¨ÌN—_aƒyY…ЍhÁ(G„F<?ß²¬ð)lù›±cÇþlæÌ™~/æñŒ…±�Š øç Ò¯ÅüæGÉ”°2êèè8ãN,°Ížª?vìØÈ|·Emˆð,•ßÿñïaT¤8Žs !˜©jG"‘ˆd—0j�¿B+0zÜÚx<þeŒÒf(¨ê•aå•OÔCóC©òR* a+.žÚÖÖºó㨖;‹¨l³Ãd*å÷üò±–––ÐøE-ðÝ£¸2‰‘¡ç=��½3©jè³õ¨~ þïþ,äÌ0*5"fï ¡¡!ô<-Šßó»SÙ:7F4»mù„òüªú|ùä±~âĉ¯…œ'Û—=væCÜ@ðµþeD«¨oPã8ÎCaä“CUM&“Å,O+Âæa Ó7„�ù€ð?�; sÄÕ‹¸8—�®Žìîî~x*Œ¼UÕH¶»0J÷ÀÌåꇄC¨|2òyŒ¹Oå½3Áö—ðû„ãeêá¾Zðoè[¶ª:WDž£òIæüîîî—èS!^Ž-Œzo<„ò²˜k"oüùCÖx̉ڕ˜a¼Ò£ÑÌ]ŸUu‹�ǧ÷bÜ”á‘ÖÖÖéÉd2bµ¶áµA�$œ]³|!®ÇœRmÀØ{ïC¸~ãþƒ]ÜnÛö –eÝ«ª{ùLšQÕË2™Ì@$Ã_zwŸ+Éc¨þEñÛèèèï8Î M7ã„e"ru*•z:êzùø=Œœ RàÌÝ$5eΜ9»;Ž3Ýqœ/Y–u˜ªî."Žª¾¥ª¯¨êÒîîn·yMÕ™I¸ †ÕÀ¬êä᥇ˆÑ ‰6S�b&‚‘,íæÌ™39›Í^("…×In&ï„ODTU W[)Ø{‘ÇÙV×X,Öç8Î&à�t:ýFuvxƸ}$ßžwÆGM¨Ø¶}†ˆÜEõv^PÕK2™LEÞ'Ý~ ÑomF‰b¼.Oˆ¸x<~°ˆêß;¶ID.N¥R�•BÊ ü«l¿îx¤ò{ŒàÆJ3ŠÇãaüÇÕê†"¾ÛÚÚzM�­×rì÷c|�Žtaƒvß§ÂmTÛ¶çŠH7µ½•Y€i7nüÌÔ©S^¾|¹¯5{¹ãÑ*«×°c¿J'‰«DäV†I‘svÛm·gÛÛÛ?å']9�?^a�† ¹YoàçI$ߌê0£Däð†††e³gÏ>Þkšr�cÌsF2¹­Üï? �^âñøTõÚp«ªº—eYOÄãñ„—ønÃÓdŒ;ÍC}ÖãuŒO”0Y…©ï'ñv°’‹s#Æ)°/’ɤµzõê"Æ¡QP¶b–Æž~FD¤ËqœËËíÅ»©8½ü9Æa�Öc ?‹q`_‰æªbî6¹ã/íPŒO¯Â¾ŽÂnkk‹õôôük�… °AU¿ŠG]Uí‘§ÚÛÛ'•ŠãE§m Æý³› Ï£�Ü9ôÿW0køyÊ(Å›ÀW€Å˜ãÎõ˜Ãˆ31/c1r¾ŠV/mmm�---÷`¶“½¥z_&“yXU§áÝèqZ,{¡£££Øu\ž•{1Žl~]ä»�˜ë©ÎÀì_²ÂcÅX^âó1>Ç ½<ä&hG€Ýµyóæ5µ´´x5`TUýÚààà¿åxEUû2™Ìï¾€w�š½ÇùE"‘8§ð ?Z«ë1jG?Æì^9˜3çÃ0öT¥ö«_'Ø­¿Pþ›µÀù5¥7ó>»³Cè‹3fŒx˜î!ú ˆ´g2™Z–TÑÁÙÖn���k[[[OÅ»¥ï8U]�Ç¿“L&·ÉÙ¯šòG;òŒŽÚY˜]¬r䮡‚—Ña fÏ`"F‡}±ßBlÛþø¸qãWU/çýƒ"2+•JÝ "‘ œ«d2™M§ÓWcVP^:‘_ïééY:oÞ¼= ¸^úJû>+FÐaýq? øý"e±m{‚ˆ<¥ªG{ˆÞgYÖÙ©TjQîÇq¢t+RÔ¦.�Ng€“EÄë„ø+ýýý?Ÿ9sæžÕºÆ*Èÿàÿ®H>3gÎ+"�aT¸Üجªgvuu=�ÿa”=\DJQ¦Óé_Æb±/à½SÙÔÔô­j ÜOOͱ3WˆŒ¦¦¦Kð&ì –e�–ÉdvÚ­‹RàªZvØîììüýæÍ›�~â1Ë¿ª–ÀŸÄxoòBnò·¨l¬/6ØëÇ9©««ë™b_ÖbHÏgÑ¢E›Òéô¹Àõ¸+zhµ¾cgö4îñfÃäÖˆëî/áû–e�0ddP”ˆ{¸W»xM§Óß‘s0뢈ÈýÕ<Ó]�Q,6¨êm˜ë·ŠZ¬RÕ“»ººþ§\½½½�L˜0!ÿdq|î�l6»ío)õ÷žª*…«êž”¾Æ«(©Tê§¶m Ü/"…–»¿3f̵Ã⨯–Äãñ“1ÆùöoËÏ_¸pa$.½¢fƌ㚛›/Æ\Ö7ü¼µµõîd2™Ýåf‡­¿¿ÿ8UÝSUß.7„שS§Îð¥>¤ClÛnì)S¦Ü¶Qaµ–e£Û¶OH$¡,¶µµ5ŠÈ™ßÓÓSöl;u�Câñøå"ò¸ªÞ3{öìPŒ,ÛÚÚbãÇ�¿øË¡�Ž�ÅbÏ•:ÛB}H÷I"‘˜¨ªwaôr|("ǦR©JÎþ%�w—ù®ODæäNè*¡.pÄãñãTu±ˆìäŸUUW�3æèÎÎN·ãâRyÿø—hÛ�ׇtoH<¿x²˜°DdJ6›}äÒK/mñ›¹mÛWâ.lÛ²¬'‰ÄD¿eä¨÷plÛž`YÖ�ªzºÇ$Ïôõõ�âÇçùЙü½ÝA/¼+"ÓS©ÔK^ËÈQïáe°mû(yɇ°x¾±±Ñ×±n&“YÓÚÚzªªÎ÷˜dU}u�{`òäÉWàÁ�ODš†\yy¦££cŒiµÛŠéÃX,vþ’%K*ÒÕ¯ ÜÉd2«ªçy0퉟óãweppÐÓÄËqœ® ”2‘öL]àÉd2kDÄ“ rCCƒgÏ�™LæŒ+ñ’'`"’Íf³^·]ËR¸?R^ÑX‘J¥Þö“éàààªúa¡iÑÐÿ²ÙìôÛo¿=Œ;àê÷CWWW/æV‡~vî‘ýªºÎ²,/öå;0¤ÿþ§±Xìfà�¡¼ß‘ûÇ9báÂ…�TZ÷õeY:::öWÕëTõDÌìºXÜßßsX=1*þä4~h`…[IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/basic_user.svg0000644000175000017500000002203614757047403023114 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/cfg_file_active.png0000644000175000017500000000414614757047403024055 0ustar00paynopayno‰PNG  IHDRUU8õ¨ZsBIT|dˆ pHYs??•ˆlÆtEXtSoftwarewww.inkscape.org›î<ãIDATxœíœ{�ÅÇ?½³p烇Èq!È* hQ<N¥DƒáqdµòUZ‚±*‰Áø@Ë*ÄT�ïÊDK«LÆp $’` E�¼´(Q!A4ˆ@Ö�Cðä±;�?~³îÞ²{3»;³³s™OÕÖîôþºû7ßêéþu÷Ì@HHHHHHHHHHÈÿÊorPDývH_úí„Üœt|¶x|®žÓxÿ…Ìül-öd*á2;XŒ³ŽßCNÌn¾Cev�Ž ì&Ý:^zúéð´åË¿|ö£(bÀWÈ ˜ÀB*£u<…øôo¿)ÌG„ÔÀ1`†¯uäIįm~;â”ÞHÿ™ºÜ?.öÕ£3yñíC¿q¤ŸJ úÐÏW�ró8âßv¿±£ØOZÐç€*_=ÊO*òøÈoG:#3 ? Üê¯;¶<Šøú±ßŽä" d–³3Ã&û³™­åâ~Ëæ€ƒóȉ_-µÙE]“•þž•>é_·#SÊL6ïf¥g>{‘Áª iÑý��ÜZà,d°ºX�÷À¶T/9Ù´›Ò‰ÍÙÀïóü79�/Šu RF7¹Nçs÷ëȽ˜](¤r“SÖ÷2àF$Òè ®~‡¬/,Í“?¼üsE–Û9s€Z‡´Òθ۲=RŠ]�2=ŒB±£Èà¶ßAþÀÆ©å  h)"_اz@(ª„¢z@(ª„¢z@(ª„!•[§×kMR×£8_C4mZ±OiýQ4¡ßi¹pE[F–PÔ\4î›18‘Ts 2ÕÔzZw”HY‡J‘¨Ræ„Ïš6jô’^ÑÞ‹ß°¸ä=*·æ·‘¾óx²]vv7�¯ õJÏÅùm>ß àÐÁ¿Æ[>¾có,�0O!O"L—éSâ3çê(;Pú‡!(€†>}§ÕÏõ÷«è9¼¶hmßRc:f|Þj.ÒèÛÝ,7ÙžÀèU5m}Ýk¯š7Ð-5¦cƾÖÄËn `ôŒ‚ÖËâ³fš7Тîm5u£‡UZé—'¶~oœ½išÀŠ:¾µišBÏ+CUÝLm.�°gj¾�Â3¤¨c]_«4ÏR¾Õù:Œî�Ø› �µª½ú§È6I9¹u|kl¸ÃÀ‰:6«Fñcª6¦£Û9'j4’˜NÇ›+ʇiÞ46«¶3 œ¨Z«é¾U®T­Ab’�YàDÅýç¦ C©ñv&�µq׌³)ÿÕ�lg(QOj�ß>(Ô`;›@‰Q¯.„þv�e}׈khmûð] Díq2êäoQö÷­JÔÕC›�"÷HùˆÊõXR%*Zoöµzô&;›À‰ª"‘ÕöVÞaD£ÿ°³ œ¨&‘?ãßË7­Ðl{ù{±›:š"÷ˆòp8ž:ØP×̘m7¼SuV·±.Öá¥ÕoÙ¹T_æ•çÔŒ>—‘+Ë}¯óöhÝá-ª¥k…T)Žm>Ìþæ=å¬Rk¥âDPpïòß u©,G|ñf¼wÿ™õ+UU¤Þëºüz}Ýò:µwKÔÓ”ðvœb8òÆŒîjŠiª  ïŒâ càá{ ÉÈË?ÅÚ�Ë·«ˆžLaïpŒ†5Ñ*#æô²OhQÖ \ö^RãpùmçJ³¨í¨q}KÿæãöÖYyÝtÄOÆÆcÕF$±­î¤È{ 4ìŽÀ�Ö Z–ïá5[ºŒ¨)&ì�]€™œ�¼Ý§�7]lEéçkÚO¼°jت“¥øÐåDMÑx Ö;yÒœ¢•¾yÂo(ò°/À `¨�½ÉŒ¨æ·¾VÑ/¡­h.Þë†ö¶1ýáâ`5´ÜIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/cfg_file_active.svg0000644000175000017500000001626014757047403024070 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/cfg_file_inactive.png0000644000175000017500000000367314757047403024410 0ustar00paynopayno‰PNG  IHDR;J[,×sBIT|dˆ pHYs??•ˆlÆtEXtSoftwarewww.inkscape.org›î<8IDATxœí›iŒEÇ53,{°à(º£¼`Q³Ž3« ®‘•¨‘C�P¯Ä`LL4FŒ&žŒQ<"F4Šˆ‹ *¸‚xc<4îÁá�€¢{Mùáõ8Íl÷Û=µCäŸLz¦úÕ{ï_]õêUu øƒj`  àó‡Oœq=ÐQ$Ÿ�nކ<�,¦Y¿·s�6:½à` üV<x—dk~é·‘q“åËn?•Ž~$It!Pê§�âFÄŸ?ýR8ÑR¦�8p/yè6=Ä ˆ_yU¤€[�.’]å¯J}Æõˆo{¼(é¼B²ÛþœìÙ5ÿ1ñïïž*Ÿ�$ú0È×üÇ,ÄÇzR95Qxèã›kþc&âgÎSß  ÝªÜ�t‘BÇuˆ¿ín©IExì¿"xUœœ� •V$.x™#µuÍjv8XÉÞ‰ÂQŒ§CX œ�  |êQç5–žÎL‚Ã�Í$‰.Ê<wCIJæØ~¿¬õ¨wâ{W:¡z$y¶' �†Óá\ËÖTŸõN'ÉÁ!` ÒÏw—¯ùìD*N·®:­TîÈ8f¶›·áÑ"ÒçÊÙÎÓ 8�ìÓQ{ã9Ö±Gc¯K³3�ë´ôîGºÖ-À’AïN’Q&°Îú^ ÜŒ¶c€÷‘UÖ&K× º÷Œ¬zJ"(MË$˜“�7ÔVö¢¥÷®Ùg¬ò+\t->BÀ8„ ¶î-²Ý³ãJ’\cŽ�h(ð,pe˜os6[œ…̽ $£êrdšxiX§ˆ›±ûAöf$�\˜Rþ&Òm¯ÌAWĺ¦&;ˬëqYêÉ8f{ŠZ ç4-µ2!±b–RÞd]]÷—0ôdÃø·S±i´z$£K iˆ7ÒÔÍ üJø g3’‹ÿ�¯BÆð«¼É½ª™'û½u�ìr¿–ÜRÏ·€€ç€(2oGIÿT!Çy6ôbÈ<—˜—_EæÄ¹HÔüÚ&_‰¤‡ ¶²D;9DˆÞ |‘£o¾“]œ‡¬T®µÊ®B¶R×!SÎFàXd`LŠŽ�Öõ`ºc¶éÒHÆc�ª#€Û‘¡�Ÿ‘³ïg 6¤è±¾Á}ú›œcÀT$[d:ðd¢ ¹j xç�­‘HtÞ|›r¯èëP§�äŽ`ðð¡�¶‹î�ékdœ¦[Û^l“à$PhOönàad7£Ù=ù YÇfS?�‚ïÆ ü‰L[¹ÂHºX(ØOÖŽýd÷Qì'kÇÿŠl!N=´ÖÔ Œuž*ŒbZ¢Q»°ÿ.ï\{ÈŠµÛlUö-²?ÕU éøTPõq:«€ èÿh(´|UŠŽ`šë¢Ÿ)XW�O…—5îd›ê"Að.¥õ4PNË@ghU©Ñ•Jïx½jÄÒÉë7°§Ëý%^¯�Ù–qÑ J¿UšY8¯w³AYå€òÉ+ÏEÕ�ý¡TS]ìV­Ôb|:”RQÒ—E§�BcõiS�î÷Ù¦ºØ}Jûh,¨á’â¹ÍµÕ7§Þë²-uÑÙJÿ÷æ=OдÔF÷ÚÞ5N¶µ6vªÖꦔFÍkª‹�(0JV×Ô„âJÏC6¾M \éàc‰Fɶu\†V•&mc[j£ãÀô“Õ*ÏãÔÅ.b×XRÑT«Rp¢){)Ó:6v„±'«”ž`Ê–ñ€oެ&fÊ–£}ˆ#« œdÊ–³}}”²M‘H h§·v&q¤²ª´«þ01ØÙûJw’æL¡!tšy²«Vu¿™°å ÛL&­muƒRl6�YoÊ–‹k�‘  —›²ålŸ·�‘ R¶Ÿÿ'—š‡ô?ìC{n|06_Ömh`EdÔòãÊK/Ê— 7hxT½ôR—ýIÞ1¸oÄN¥,èt‚6?P°µ¨X;hÉšÝF—xÛÛÚyhÓÏ&M¢s-Y³’GÓÓ¡9¦ã ú÷%°>™_ F2K{ƒV,/[}iâwØ‘o£vìjƒ’õhÖÇçÑÔGìêºÚ^Ð+»‹áe�¿w„B£�/ób@«�éj¯76îu0­×ö�‡¾¹jkG{èlí~ˆ«§˜(ÞSS±b]·ô´×ÿÕ¬A5�«¾Z)}ÞÞ |Ì©hX½ÔM ×É&ðË„hyÛ?Ìu-rÈ+;(ýðÄám}ž´î¢}ôzâÄà–["ñuJqºÖŠØÜ¡`“Fm‚øZ_/c¶ºÿä˜=j=iëÓIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/cfg_file_inactive.svg0000644000175000017500000001653714757047403024426 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/compare_mode_a_minus_b.png0000644000175000017500000000742614757047403025436 0ustar00paynopayno‰PNG  IHDRkkp¿| sBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î<“IDATxœí�}tTe~Ç?7“ !$ˆl°ÎQO ¨ ]$ëZY¢‹C+ˆ».žƒJùCŪÅxjs°À®@�X|;UXÛÀRlSt‘VD¤ ix v7˜IÌämæ×?îÌtîdî̽wf’;çÜï9¿“Ü;ÏË÷÷|ïóÜû¼Üç*"‚ƒÌ@Ö@p`ŽXG¬ ‚#VÁ+ƒàˆ•ApÄÊ 8be±2ŽXG¬ ‚#VÁ+ƒàˆ•ApÄÊ 8be±2ŽXG¬ ‚#VÁ+ƒ�Ýß*Š’ c€±G-Àÿç"þþ^DýÄmð}`\ðoèÿ" ø6h—‚Ï¿O¿ðK÷R4EQ\À��*à§ÀhÌÕèà ° xGDޤ˜ßÍÀ"`a�›Y€£À¿í¹œ:†‘”ª·›€ß’B; ¬nH‚ß�@5Дbnôï3R^®))x8Ÿ†Bˆe_K ¶ø-Æénî²l%j3w® "ÒÓâp›ì n‚Zƒ ¸X@p` "d~àuàên9À_>ðà�H~ý&0øU°�º"í[àçÀŸ 6àm¿æY)sKý,EQF£Ö¦G°__mêãöÔGo»á{À.EQ¶+Š2ÈTL 5ê:à4…Ʋ^àg\ÿhµ/=û �—–f˜‰Ú!h'cÙ 2ç€fðÓ³ÀДŠÌCíÅ´s±¬øQîc€c6à©gÿ ŒH‰X@j3ÐNéÙ_ð¡¸`®zv’”XA'ggôì9­Ã�P‡¯š³žýƒe±Po'ôì-3÷Ü O�Û€w<û™U±^²y=kÆà�9†_ïØ€¿žù€É¦ÄîDQhòzv§¡‚¾ NØÀ=k ÆýKÏ™aØ÷]P§J, áã6ð#ž½lT¬gR‘á¨Q£¤¬¬,ÕN´ßKV¬ ŸŸÚ@=û.ÚÏ>“�Š¢ C�ì+ LŸ>�ýû÷ÓØØÈ´iÓ’I*ωȚT$¤(Ê-À¿ëý~ûí·SSSCGGGØ|>���(Š‚ËåÂår‘��6¿ßÏ¥K—hiiáðáÃìÛ·�Ë—-ÏE®‘¿ Ÿڞ%WÆ_|!!”––¦òj³—càAjôèÑÒÖÖ¦ñëСCRRR"Š¢ ¹¹¹2yòdY½zµx½^MX¿ß/ëׯ·âó:=±žKE¡nܸQC´¥¥EÜnw²éöS-VÐï}F8œ½úê«qÃçååÉñãÇ5qºººäúë¯7ë{•HÄ|–¢(“±¶ºGƒ{áÃ‡ÓØØ¨9¿dÉ’d“þu² ÄÁnÔB‰‹ÖÖÖ¸ÇÑèèè`Ñ¢E¡ €œœæÌ™c–ߟ‚vâð§fSˆ…eË–¨ªª¢§§'|~îܹŒmùZàŸRÁ/fâ"€Ï…ëîîÖwuu%Lû«¯¾âÔ©SšsÓ§O7G*EqGŠeZîh\{íµÌž=›�?þ˜#GްwïÞðo.—‹Å‹[MúˆˆœO–_ìJWÂÇŽÓ—””˜Mâ*à–,EQòQG¤“ÂÒ¥Kؾ};;vìÐüžDSø‘uV†‘6±šššâļPÍú1êJ ËÈÎÎæÁ¤½½�?ü€�>úˆ¶¶¶p˜I“&1cÆ +ÉÿG2ÜŒ@DN .ÙN9&L˜ 9þòË/­$sKH¬ŠäèÀwÜAaa!ï¾û.>ŸPÛô÷ß_.TûL¢!Y~ј8ˆ9(ŠÂÔ©SÃÇ­­­lÞ¼ÙJR߉U”,©eË–°mÛ6ÍùÚÚZÍñ½÷ÞK^^ž™¤;�³É±3ŒS‰ƒ˜Ã#�—ûÌ™3¥½½=>Ù‘œPͺƊÔ!,Y²—Ë~°ˆ„ˆðÖ[oiΙl û« „Ô¬¼¼<ÊÊÊxå•Wøä“O6l>Ÿ�Õ«WóÄO$—xðŠºˆEµE‘¦¦&éíí•¢¢¢˜aJJJ4Wd �‰'Íã�~¬Y3ãq‰®Y�GΜ9¶óçÏK �hÜwß}’���T­  I,"¹õÖ[ED¤®®.n¸è¡š^xÁh[ òHào� À6ÔWnö¢ÎWþuÑÏ`Sœt~hF,ŸÏ'mmmÒÖÖ&ß}÷]‘"ÑÖÖ&/½ô’äææ&%ÖˆdÔÞ¹s§ˆˆ,\¸0n¸G}TC¾¹¹Y²²²Œä±Ù€XU&8/O•XÑ÷¬‚‚)++“yóæÉ‹/¾Øg”^Dä›o¾‘òòrKe�MkÕGŒÁüùóX¹r%K—.¥§§'l999äææ’››Kaa¡&î¸qã¸í¶ÛØ·o_¢lÄ•Æ8çG­I!óÿî7�ž%x<<G�e÷îݼüòˬ\¹’U«V‘›› Àu×]G]]7Ýt/^4—AðŠ²´ÒvÅŠq«~"¼ýöÛFòyÝ@Í”ŨKƒÅIGÍÒ³èVEDäÀ�¦ïc¡À›Q_80…PßjõêÕœ:uŠÎÎΰ…9³²²P…¬¬,fÍšEuuu8þÝwßMAAOÜ÷§ ãý "þ`– $5Š£‡M›6QYYIeeeøÜ¬Y³¨ªªêó¤Á+ÊÐä[¤MŸ>]DD Çq»ÝrñâEͶ|ùòDñŽ[©%kÖÒx\¬Ö,@ÊËËûÔ®­[·š*óÐýªÙ¸¼*Bµ*z°6zzzxã�74ç ô¹&*ŠÒ_n]Œâøñãøý~͹ٳg›JÃ’XùùùáIµèá¤Dˆî8O�:•ÒÒÒxQ¡î“ј”®„;;;ûŒ¶O˜0�ìlÃ[‘X«Y .dèСÔ××ÓÜl®R666rðàAÍ9µë¦2±Ž´‰pö¬vˆó믿¦··×hô£!±LMA<üðüùæ›f¢…]»î¿ÿ~Ünw¼(–22�àzɉéÌcüøñšãÇ›‰þ›, 4—ch ®¢¢‚3føàƒÌdÆ{ï½GgggøxäÈ‘Üu×]ñ¢Üm)#s¸�4n�äv»™8Q{-|þy•‘ØyãþÐHŒçŸ€††¼^¯™ÌÂhoo§¾¾^sŠ¥TQ”´^õ¨kßã"úþ’•eü¹§¼¼\¿½½�ºº:£Ñ½ÀASbUTT„Ÿ`,Îv†=r1gÎÆŒ/JÚj—¢( P™(\A�vEù�!C ¥ïr¹Ø°aCøXDX¼x±™ûý¿ŠHOdC!Á1õõõá>ÂÓO?mzÄ#Ò¦L™Ò§ßñÚk¯…W·Æ°iì_Ýl„ó‰'4|kkk ùúì³ÏjâUWW›-¯_ˆѤ7Dt¹\rã�7ÊÖ­[5žûì³pø+W®HMM�Ñì�ù®w�&=+2`NNŽø|¾˜…‰={öÊxÔ¨QÒÑÑ‘0=uyŒ4žKƒP£ÐÙ.hìØ±òÔSOɦM›äÂ… 1yvwwËž={dÛ¶m²víZ©­­•O?ýT¾µµUÖ¬Y#W_}µ•Vh}ˆk¬W~ö? þÏc�=†×ëåòåËx½^zzz¸Ýn†ÊðáÃñù|ìܹ“D4hË—/Çëõâõz¹rå ]]]øý~rssÉÏÏ'??Ÿ¼¼<|>_¬™g/êz÷K 33EQþõÍ™>X°`AŸ?ñpéÒ%š››9wî\ØÎž=K]]�Õ‡±NTÕáùWZöÛ�)ÒÖ¦°V ÆÞox®×ðÕqb» ˆêY'0.Eb­²�?zæFk,öÝMF€-)ªõå¼�öEÏÖ÷áÇ™m@XÏz�›’Ëô´P?Úi ÀŒXCQß-hâzv ûéøö—6à¯g�èìJšÈ©Rಠг½˜ÜµùûÖÜõìçºÜ 8W‰½7Ùª6!ÔUÀqpÖ³qùtò18¢g lcŠ:¢žÔ2ñ4Û‘`£H3ÍÇ/mà�ž]*ðßlžzÖ'ÔÀ„XÙ¨#ó혞uƒw°Ñüôì0Ò�&oÎ ê× ìº—XÁw0ð� xéÙ¯I×¹…ðgØû)ñïP׿ÿÖ\ôìW€ËT¹[+(Ø ¨ßh§cÙ¿ ~Ê⌠¸D›Xe©Ì­Šl8öÚhñ"°(ª¬F½Ÿ 47þ˜`¹¼“+¢P¦¡îQ>P…Ð ü=0L‡ßµ¨è�â÷ßÀO’.çTˆQ(³éÿûÄg@¹A~óQßÕê/nß+€ì””o*ÅŠ(”;QkZºšŸ&Ô�æR‹ünÖ’ž¯µ;€»€A)-×tˆQ(CPŸ·�Ä«°A;¬þ(…üÔÍZ6$É/mEZÚ?#Bp¹×TÔ/Ö¢®}ˆ´kPç—šQ¯øÈ¿MÀ’Æo?_~ˆüÎcô·üÿw(ÏEýVDzb$›ZŽý%–ƒäa·Ï)9ˆG¬ ‚#VÁ+ƒàˆ•ApÄÊ 8be±2ŽXG¬ ‚#VÁ+ƒàˆ•ApÄÊ 8beþÑÛújIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/compare_mode_a_minus_b.svg0000644000175000017500000002166314757047403025450 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/compose.png0000644000175000017500000000155114757047403022426 0ustar00paynopayno‰PNG  IHDR00Wù‡ pHYsÃÃÇo¨dtEXtSoftwarewww.inkscape.org›î<öIDATh�íÙÍ«TuÇñ׹ݭ,+[X=X+S7™å¢….$‰BúZä¦M"Š-Z™©»@³ •fÖ*íA¤@‹@M´‚ž,"KÈ$Ë2•<-æ;ôã0ž™¹sfÎ îwîùÌüÎû}îï|æÌÜ,Ïsÿç1V7À cR îÑH�,˦eYvY/Ïmœ@–e�ã'|”eÙ�]_�çyc6,Ãyä±}�¥¯©:�çðÞL$ŽâŽF à‘þ‰Ø÷ .„Ä1Ìl¤ÆÙ=…¹IöBò—XØ8,Áßq¦¿ Ð?°÷…PŽç·„°gþi\�wø,~�ÇkKç© ~þ øåÉþq¼•¬ýu]çª~!Nà³…ì^œˆìÅžæ1üƒ±Æs¬(d³ñKdzžs„ð$ð+ Ù=8ÙÆ¾æü‚ä¢\ÕþçÈ6!k”îOàW²»µî{rlî~蘇“¸¦�ÍŠwØ[06¡c ~.~íÔå¸+�e¢ðCÀœ~]!»?Föê ðCøŽ]ŽÛð]d[qÉÀÇ«~v¿¡�ÍÔº5α 㕳Bø‹v9nÅ·‘m¯ ¾2�².øö�æUÂW"PÖå¸%�ß�K«„X Ðå/§�‚›µ>Óæx—W ?�@¡Ë·t€ÿ<²�Ÿ°@Y—c:>‹l®ü„ʺ7áHdï¾o�².øÃ‘½7 ø¾¢Ûð¯à¯ÇþÈÞÇ•£€ïY °lŠg~>�l®|?íwÑëÛ]gþ@ìÿSF ß“ž À‰×p>‰ß÷ášQÃwˆ®ÿqö&¿ÅϽuÁ÷"°_µ×5¦D=¶%>ƵuÁ— à¡€|,Ù7æ¿ï+÷cj�ðÝvG¯·/ØÛñ¡Ö÷÷OÖ ^*µyÏc©Ömðy|�ùuC÷"°"Yç9¾Äò:j²Û6®óø/áâ@fMYC¹z�û/e¿cR î1)P÷økƲÔT&ÑØIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/compose.svg0000644000175000017500000000537514757047403022451 0ustar00paynopayno ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/crosshairs.png0000644000175000017500000000052615143647637023147 0ustar00paynopayno‰PNG  IHDR00Wù‡ pHYsÃÃÇo¨dtEXtSoftwarewww.inkscape.org›î<ãIDATh�íØ1 Â0Åñ¤ Ú.‚‹«ô$Ãkx�áYTpwé$ø9XÁÕïBà=™úš_ 3#×ÀXcœ1¶ÞŽy3ÀÌ[�ðìg÷:F€âÕÏO¤T#ï ¿Ó™œZ¨;Æ4iê*1¸XŽqXa¶Ùù;*à4ÿø¢¿æ1d Ì»š;pu•d>‰—ï=`_êI¬¿�Á @0äX?'oAn@ñ; €Á @0Œ#€Á @0ŒY†}.¶ÊôyRðͼÅï€{/)sªÝûô ¨IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/crosshairs.svg0000644000175000017500000000101315143647637023152 0ustar00paynopayno ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/datalistener_activate.png0000644000175000017500000000461314757047403025322 0ustar00paynopayno‰PNG  IHDRTTkÁsBIT|dˆ pHYs°°œÔtEXtSoftwarewww.inkscape.org›î< IDATxœíÜ{ŒUðO·K_ж@ hKE*-Ä'Øfƒ€¼•¨˜J$F…ÖCQˆ,±‚à QT ¡]!…H@‚òhA¬…RJ ¤”¶ôúÇo¦swÙ{÷Þ¹3ûhï7ÙÌîÌ9¿ó;¿=çüž3´ÑFÛF 6%a7�Ãp&a,Öã?xwcž‡ŽÀBlB¥ÁŸÅ8�E0°µ¬Ð=ðcWuïa܆Gð,6c4¦ˆUÛ…ƒÑ‘´ç&}¶ita•Xmoãì×`ß½q ^–­Ø›0¡x6‡¾&„XÁ£8('� ˜�� ­çðÑ"N8Slã ~…qÐ\æ}Û�!ƒÃe bz?mÏÀj¡¡Å}X›ü}-vÊÉÃ�þ‹19i üILæº:mF ­¿¿ÄžUÏFã«xÏ©Yì€ gçè?dð~±º6«ï ýTx:õìÆ½°D¬²—äàé‚„Ÿ{sôtœ Ûb}Å+Gâo"ôÖìj›'”܇šì·§LãOm²ï ãfÁø¥5žŸ.ÎÖ�ä Ý‰Ç…áÞ,îIø:+GßAE~¦oe4Ë´flŸ,ó‰&ûÍKú-jaì!‡³„V_ 4FˆÈþÝMö;TôU[IÖc¤Hk\[­£Å¶ß±‰>c°AuŸxtœ$&óÁAä!�z}¦úfGßm‡<Îîä`FÒôó¤ê›Ít:ÞU;ù‘Æ)—á/ÂàÏ ðñRrÝ5/�¥¸¸^ ÃñÂëy G ðØ©÷½ê›Í¬Ðñxw�gS´¦móâ&qŽ>,Vêì{tr]_}³�ŽU; ðC\�ƒ©Öp›=-4E(†»p£�ó^RÏì­ê›Ítœ,ô…ýÄ*-7e‘¹º=¡Ór~ &u*Öàªá#Û­/TßlT #…«Ö× í¶ØîI»ò°ÐT;¹×W ·ñxÛ9-yºVD�Ž40[?Ý Oç鼃¬T¥wÄ{JÕ³Z+¸ut;X·—u[b‘uZ>†ëKã#°‹¬. ‡–ot…VS{ mߪßk)­þqA^Ù[øÍÏáP]ªCéåkü£„Ëù¤¨«Ú‚<í½í÷ÿ)ò t±‰Žð î>bž‹uá:¼¡Ã³­í‡ÚSbÕŒÊÅKcøTr½³÷ƒ"Vè4qެ“W GZ-ò=ó-î×Üè¢ÃifYÓµQb;–…1"N ·÷~XÔ ]‚çõLŒ5‡ßÀ�·åÞv÷±À,÷5HéñÞ�›—ú8AxŒ+ÑÝûa£MWÍ&}Ÿ¡K±\+gè,�«˜�yn·¨8oÛì©LÄ)Ê+H!, ø¹ö@£eÐé í�-ì)Ù¥â¿V]Lp‚,x±o$¿¯“æ*,·Þ…ÆúœN—¹Í—TÌÅæx¹;e“¼¼Áy5‹“0SÔ:]Y‹‰ s€ž Ëc?­ç Ý[Ôÿ,Mî§Úuü¡ F/Å9ŽõºEÎÅõFºcU,h ÿDQ!Ò%üûUõ›çÂh™ß>_�—ªz LX�Âw¯ÆCø'>_u/5™– !NNú#Vá.x](Ší“¶ãd~ðø¤ýÊ-»üN·3Œ0×ë²¼Î$·•"ßJè|Vy5òã½"SX�èLqަÑÙ"8Ð!Ò¼qŽ.ÖÊÄî°¿n,4³F‹pƒðŽ6ˆºúI5Ú�Ù2Cþ”" “�œü½@Ô+¼"R …ðó£»n9ö‡ñ ¾£üXèTQ>Y ÃB1#!œŸv‹ìœ<»Uü7ó›PC“D-TúRÄöõ›7�Éz–ô=«gõÅëBk?PôÀƒ€]ñ1ße¬…j6§ô¢Ì-ÎË¥UÏŸKhÞÜ$Ý¡†}ðWQ°s„ãÒ/šèf¡‘wgËHá%¥H5r�á�–Æ@`¦(ï™&È'E©Oi¸_Ø|ÇygÈîjü»€1ÆËB‚™Ùo%Cm´ÑFm´ÑFm´ÑFm ü3Ð[ì~IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/datalistener_activate.svg0000644000175000017500000000662014757047403025335 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/datalistener_deactivate.png0000644000175000017500000000503414757047403025631 0ustar00paynopayno‰PNG  IHDRTTkÁsBIT|dˆ pHYs°°œÔtEXtSoftwarewww.inkscape.org›î< ™IDATxœíœ}�VUÇ?»,»/!-˜Fø JECÂP„ÊhÖT6ÚD/NæŽãØäPT£i™6˜¥¥MSYÙ+8H¤“™6:°¶ֆض­¨,É*˯?¾çÎ}öáy¹÷<çîîÏwæ™g÷žs~çwÏ9ç÷z/ÔPC Çê›�ŒðFàb`0˜¼x øð,°ØJí3H �(zU•¸ÝÄoJôù¬ë“Ä? ôqÒoÝ&ä–pyʱC�è<4`i‘>³�ö¿%Ý9nÌzžntüüÉcì cñ+¯ü…ÞÒ®¶µHɽ=å¸)ÄFʱƒŽ_"Æo.Ò~9:[ßáA»ø2ÜÓâQÇ×�±ƒŠ%À]VFÍÀn*3¶/A‚ywÊqkݸ�Ì=ä°iõ·T@£Eö·¦wè>ª5ëaðE“Ç:;Û‘¡^)–¡m?&Řf Wl1=ƒVƒÛÝ¿«t‰³‘¥(êuAîÅúÂ}oHدiÔ6wi r'3ú¥Ÿ'æ^L#ÐY$@ Ükð˜•\LGFuqœr7ð2øß˜¯$xÁ}Oð%° øJ^ƒó vt[‰¤˜ÁeGL ¹¸y=/ï É[DÜ:_�À}EÚ¦â©m FÌ—;4ÁZƒ>Sð"ºv�ÁSz·–:>bëÿÇÍ5ßgð(âR•üˆ÷Ôœ¶+`ƒáÛ,çø0h3¸7™VàG•ð‘ã‰ë¼´üxb¡½5¯mQNÛ<ƒ Ü_l0ßý}~ ëPV4K\Šî·-¿!©š�Î�tÏtÄNJÍZêàW($·•Ûì&Yb.ÂN´j+奢xs~CÒšÈ\�æoëS�2˜L�:܈üë³€ÏÕi{%E#éú§E3ŠÓ‚,‹~ðh¡iÿ)@l4•Ž6¤~6ú�{CðR+�ÇØ‰ìß~Hºå£hxG¯Ð™È‹ÚC jrÆ Õ6-ÅÐqè|˪ ¡対‹,›~H»Bó³… (%» ýj¹>ù âàE/±ÉÕtïGÍ.ôƒ`bú7×”iütˆoò¶d·•«€¹È+»³nBÚú â<ö³ô_¡'£úŸ]îzäOOGÞSRÜ \íþþ(°Å)Ï®1¸¡^,1~r— ÿ¾+ÅÜIÑDì·ßJ‚‡žtŸ§QA@îçIà«y„"Cz*$èC?ÒU(«ã�ÀX÷™Œ>¥6æ¸kL2Øk® Á`‚Á«VܽéæêDÙÑb™Ñ¸E,ÑEº`tI¬FB‹<¢HpõÄÂ= ™9©Šÿ  ¶tXޱlp·ÁsÖ¿tq6ðc_èEuõÉ‹‰ ùKC¾Ð�äþ¿ÕœîÚ–¡sluÂ_78d° ïúéθ¿,çòyhÇ\Oö±ÐÈQ0”0 Š9ŽpT|º =5ÚÎüýš‰M(ƒºxçÕEÚ2 p 1w†ÎÈÐL¢I_;ý«/þ‡´öI ,5è5Eï f ÞçVé‚BíaÒ%†¼µL |ëÑvþ$Òz}À•9ímŽ�ë“38Ïàƒ­„ gPgðŒ•®o ‰éÈ…5¤ìNËr²=À—PŽÉè¿j6¹k#ï¹0XèR[¬pÍrBvîX0 €)ƒ¹Ä’íÞ–ñ|<Žl¾å²Ûü³ƒåÎÚlðú]FG°Zܘzƒí–í£ƒ ѱeè‘Æ ®t9<€JP®q“çž{“8:¼×³ ÜgÅ#Bgª+ÝycW¬³ðéïfà:äJõ³5Ëá›HãmþêCÀ­ÐRBY©n~ô ÙËïG¥ÞQe²¡ð¡w1­Ï#ÍHãEA‘Ô¨ƒ_”ééÿö¡Ÿ‡F”÷Y�ø>�Âgv'ð”°í‰à+бè°~Äwâ2ç¾÷ 5‹Â!À#è¼ÿ ð3t6¿Véd>�VM ž+4¢ •—Ðz¹§�À‡Ð1ò2ªœ 3õ9Ü;rþ.–V®‘²:X²W2ôç~ú�}ÙEFh�æžkY­Ð(ør8½î;óÒCŸ-ß ¼‚<¦R1ÊJ 2È{@ˆCŽ™Û•¾ w s(+ìsß¡lÁN÷=¾d¯ðèN˜4Å 4Týg�ûÎüa-_�®$ÛTmT'5-½(™–e®ðhV)ÚQ<`rm½ m‡(ŽÙS²W jIx ´"§xszcÝwwÉ^0TzE{Þ€^d.µ UCU We\€VôàØÎ´ªs‰_ 2®LßRh!~YV¨Ú«ªÅ6$ˆµиÒÑØQ®ãñ€+�0^$V,iñ>\p,¡­,Ci—´¸ˆøØ˜T¦ïqƒEÄUW¤7�øí Å?n± ¦Ü;E"´ d¢¡·QÙ±V�¨G�EyŸ{(9ZD\í±�ò¯% ŠjzÖ»ø2z m=r7#¥Óƒ"I‹Q�(x³ UÔP Ð T¬Èç zå�¯UPªi…æã à½hK7£„ÞS¨Î5ëÇjj¨¡†j¨¡†j¨¡†jHŒÿ¨²¤¤*nK…IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/datalistener_deactivate.svg0000644000175000017500000000742114757047403025646 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/delta_beta.png0000644000175000017500000000351514757047403023047 0ustar00paynopayno‰PNG  IHDRK4Â:ÅþsBIT|dˆ pHYs77±d£tEXtSoftwarewww.inkscape.org›î<ÊIDATh�íšilUÇ}m[(E¡€HˆZQQÐpAD‚´qA4àÅ`€c"FÅÄ%!ŠÆnÁ/òA‰¢"Z•Í„¸ b•B±XúüpÞ$ó¹wæÕ‚é?¹�w{¶9w;çÜ[Äÿ€k€ÑÀ@ ÐØ—kÛ�Z`ðQ” " eƒ€á¹{e@' 1×ê€�ÀV`°ßõkZUÀ£À Ø’g30x×EQyŽi;�uhÿk€ Ø „-ž0ô¼Cð“£í^; ,°5l2S’(ò·ëlZà;CöÌÚJà×ÛöçZÍmqFõöƱm“ã}`…�ŠìS"è_±g%0è࣭Æï)ô�“ü‚K E�'*ü¬¶õ¹V„,×r ?²‘ŽúD|H\eüÞŒ,1 ý�k•þû�EJ°YÖÏ·ûþVÜ ÌÓu“ïÝ#À´ÃÂ0x ¨qä Ãæ‡#hœ!¯Xê)~0x7‡V½h©HC&¯‡ÎÈ€ùmA¿Þ mú9è{PáïêýÑÿA ó�ŠL4§àõpPêû]|B[ŠÌj?j‘ÃÊŒßEÈ>ä;KsÌ4àde…Æxã÷ ¡ù›7ÀçŽúö)}ݼÿø�µ øÊ <ØÌBŸy-‰bàJ£oy}g¥o‡£ÎŽ.Ä“KÇUSØ SÃHC#Ñ6Š Í3uޢȨŽbX 0hí`pæÉ—‚ŒQl¼ÉQçEFì64ÙLmÐFdÖ r4. [ ÷ÄЧuV{$žôóÂ"¯‚œ ®Qûà‚Á®+ú*²O‹áIë¬;þØ„z:ÁØæ`.2{¾Fæ(§½tq0ÔÄ,CÞV ž4ÎA0 Ï�ƒ2ɺý ó˜€ �ç‘%¨9ìCdj'Á C––ª˜Hâ¬Rà.à/…÷w¤¥b²Fý -Œ¬6)ʲH®éŠr‚£<Ê‚/ÎYí€ÀéÈ©ÿ8ÑÕ‰PG#…;?ñ؇9zm㯲”áájCF=v{`œ³¢Â"³©3Ù[^“�¸ÆCɸ³F‚dï‘‘ò£²qºÀŒÚWMŽ2Ò`Rø Ågä{6,ÿŠC ÁQªÃ~†!™„Ÿª%o¡fÖàY —¦ä…á>KM”üØ,p†%¿iK¾Ü,…\†Ydÿ¾Õü¸ËÅIgVð&Á’ìHà ~s ®þLh‹‰ äÛU ô†ç"[†eÀsH~<×ë\EЫi’æм§-yÍí`ŽƒÞ4qV2‹¶)2ò䘗‡ Ôp±¢ìe ¾žHùÅÏw¦ƒÞBä†åÀkŠœ: Sèn048*0¡Õ„´º¾‰qä;‘lá¿Ä!ÄÁæek%0%C°†Ó˜Rá¥ÏfY›ûUÜÝ`K¡ }ù�ËœIN0eJ_ÜÒn\fôEúZë‘SÝ�¡‚Ë&4²„V±¬�áMþ ÞOiGd VY»g~H;ÒÝýi·){cxÌ»ÁÕ¤ßÒÂÜNŠ3À— á�J†)}qµ¹_µæô`–˜öfÐÐKR(¹Té‹ r«‘ÀÏC3R¢im˜Oê3HaÏD É.Iœ•‘qÌYõð[Ý’^ôVá»/Ìa[¹¢Þhü¡pc%ó•¾¥DW Zr >@²kŠÒ÷±÷Ÿ™£Ö]Ø'± G¿�g�³#x*Gúéµ=ÏZŸ^ÅíÚ® ð³"g¸GÐ1„`zÜdb0rªšü+cøn 8@Iï#Üå¥[å2N@ &­I8}fl%¿0èG1’87(|ûˆ~G²Dý( QÎòâ¦éè˲y­h^¿ym¢¦ð©e[€'‘Z×|à`wíQàú˜�+%8'ÄðD!ÎY^ûy± xX‹>Ø^ }IT„”Sl”†µ&ì‡Ñßaì–|l�åÒVÚØ4ý-®í&�‡a‘Á›6qÖœµ˜à-³M; <„ý+gúå”í±¾ y#¡å…aøÖ�y¡i�°zV7¤Ò¹#æš‘Lc!re€ÍÉ“.ÎC¤V!yÛd&­ÅîÆØ�À÷F__ÂߊÚ` ð¶Ñw3òdÓC$”銄MȾY‡ìÉ…*a÷’?ª› ³•ÒHâÝg˜ûÚ±�8Ç¢5œU\dôµVUÔ iŸ%ÁùÈ å¡%B>ÑÎZ�<î?îÐZ{Öq‰6g9 ÍYhs–Úœå€ì~YvD‘Ø$IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/delta_beta.svg0000644000175000017500000000457214757047403023066 0ustar00paynopayno image/svg+xml δ/β ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/edit_downstream.svg0000644000175000017500000001050714757047403024165 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/edit_upstream.svg0000644000175000017500000001040014757047403023632 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/exit.png0000644000175000017500000000175214757047403021735 0ustar00paynopayno‰PNG  IHDR>6Ÿ’*) pHYs¯¯£¦ÈtEXtSoftwarewww.inkscape.org›î<wIDATh�åÛË‹Uð_ÍDcF‰Æ@ˆŠÁ�q!JP%.\$+õOPw¢³qap%‰K º�‹€ ¢\‰˜ 2¾â#jF¢ñ5bÏx\T7é.{zªª«{ªÚîâvßóõùúÜ{ëܪS îÃs˜5LáÊ’¶�x Ã:ò}›°Im»‡¾Z!eÚÜVVt‚L·ûçñIY²‚ha© Íݸº«ÿ«t©~XÆ�îˆ-C0FÜ„õF~ {Ë�5I8܈ôŠ_Æ=E‰š&®ÇY½âÿÂEHVºŒß¬ØÁQb_û¯ø\‘Ÿ’npDÕÞ�gp'¾èúìœÎKÐÄ©Þ�YœÂg¸&¯Ñ¦L?é;ªÞX”NïiœËk”Þ¤©Þ�ŸŠL�‹& öÂãbVY)j-<¸·�‚¿¶»z°5ˆ`5x5zóô¡Qgá;ÚÂ;í\ðHܵžê¸,ÓŸÅ+ÁûÁ Ãg3·ºaóŸïÅÉ`¾½FÝ#¾e�ïžÁé(q2«»ðìTï‡]x7x-Ø‘—x„w° Ác‘C×$ ‡mxǃ› «ð vsÁÎ`[pÕ“¢Â;¸'‚CÁk úǘ®ãÁL溜m¿‚oƒ¯‚ïÖŸ§� îßháÛ+R¶ ®ëø2î5^vêV�}8<L�û<¾‘Âa+aîÿqøÏF|ÔX�ž°.—¦š[¤ÆfÌàé.<-�Î>o¯�³Ò,ïå$=”¡ws{£‚© ÁÁ!7´Ÿƒ'¢ÏLwÄ‹¢ìÒXÆa<›ð{¿“&¼…#x:YçŽë¤¼Ž§¾Ìc0 ÂßÁ“IZ)‘›ÔûFÄ óøGRÁï•!nâéìsÀž²¢iÖT?/-Rz>áïa‰› | /á`ŸU×]øMøe䡦™Û(Q÷Ímd˜ÒÜGÃp¯’—ãº?P„ñ6Žã–2M\ã3Òz—Žß-ì)BÐÔ5>��]ý“ÒL®šñ]Ò²®ŽÏ+¸µ QÓ„¿¥×çË5Iø~½þ.ü@b š"<»¡.K–轎gK©WäÏ�—Úöëaää\vñ@r­ÞZ˜p—!ò�h`kò …)¼Û±8,-ã,�DúÏÍc{æ»"/ÍÌX»l£,gçÞ{7Z8&-ZÎÉÓÿïÄÔ¤ÿPuIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/exit.svg0000644000175000017500000002502514757047403021747 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/extend_3D_coordinate_system_XY.png0000644000175000017500000020240215143647637027034 0ustar00paynopayno‰PNG  IHDRùô>(T:ÈzTXtRaw profile type exifxÚmP[à ûç;$á‘ãЕJ»ÁŽ?CR©­f Ç$`BÂø~Žðš $ArmEK‰€¨(uˆ }qвxáPW鞇¸$DFd+´b1�y¿pÆÔ¡òŨ½½°Ý *©=Œü!žÄîFêFLVHnÐí[±h«×/l#ÞÑl…Iï±¼còמ{©˜Þž‘d¢ÁHƒ™Åà¹rà¡`b4…C �¹‚…‹w‚�ü›Ó‰ðìZSã» w„iCCPICC profilexœ}‘=HÃ@Å_SÅ¯ŠƒE2T'»¨¨8Õ*¡B¨Zu0¹ô š4$).Ž‚kÁÁ�Ūƒ‹³®®‚ øâ.8)ºH‰ÿK -b=8îÇ»{�»w€P-2Íj‹šn›‰XTL¥WÅŽWta=˜Æ¬Ì,cN’âh9¾îáãë]˜gµ>÷çèU3|"q„¦M¼A<µiœ÷‰ƒ,/«ÄçÄc&]�ø‘ëŠÇoœs. <3h&óÄAb1×ÄJ³¼©O‡TM§|!å±Êy‹³V,³ú=ù }e™ë4‡Ã"– A„‚2 (ÂF˜V� Ú�¶ð¹~‰\ ¹ `äX@ d×þ¿»µ²ã^R ´¿8ÎÇб Ô*Žó}ì8µÀÿ \é © Ì|’^ih¡# o¸¸nhÊp¹ >²)»’Ÿ¦�ÍïgôMi ÿè^óz«ïãôHRWñààÍQöz‹ww6÷öï™z?%ÙrîçÀ V[iTXtXML:com.adobe.xmp f�›bKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEé  91nN�Ü IDATxÚì�yœdWY°Ÿ÷œ{kém–Lf²!ˆ²oa‘Íð±).ŸDAe‰‚,ê‡l¢tPÄOù·„}‡L„MYC�UHI&3=éžžÞªêÞ{Îûýqngz†I2ÓÓ=SUý>¿_M÷tWUW�{ë>ç=ç=ïÃ06ò׎—ÿ=ÙÙT7©8EÅšÅ0†›ÌšÀ0†Ÿ !;-r¾ááŸúÜ+/AEQLó†1Ô8kÃ"arÒ)¨ 8tÒ=ünœÖ„»ÄñÈGêEß"ÝÅ0 “¼aƒÃ$“\TÇè�øy¥Žîæ'*d[@îû5ΟdÒo†aÈërÿæT.¾¯\ìßñÄÿÌØÃ¹ϤZ'ß0,’7 cPAx¿Q¸àIèGy[V"?å@<1ó,œwùÉç"¨%߆IÞ0ŒA åE€‹/ª¿»äI2ÇGïÐ@ïª@œððï½á[©5˜a˜ä ÜP^QA&QPøÖ%ºHãî#0NÚ*zûWn—M~jÒ>ÿ†a’7 cp"ùIÇ%;&™¼HøÔ¤ÛÜ,ÛCh+”stâ¹[®¿ßä#ˆÖ`†1ÜØ:yÃ&Ç3©rõ0ü+9÷\q�ž;¯ Râðuœæ>—‘ÊZÍ0,’7 cH‰w “*L"?Åw'/H… (tŒìaìú7Kº3 “¼a%úÄ ?ó?µŸ‡8B+WÄ#¢©# á>oùÈß�[v½a˜ä Ã$ô"á’K˜¼ß‡‚–þ7ÇøDÀ ‚~Û9»¹»5–a 76'oC%xdò¢I}�ËçÉ”ÑSï�¨ª™6D äàvU<¸ÂÍ0Lò†a „ã‘KÎE.8ëËîâ×Þïn­ÅüÌ ¤Œs�R Í£##�!çéý$(÷\çÀY£ð�•?ëBñmøkiÃ0Ɇq<ÁYê'ï‡îåÜ;RúR ÓL<"NKÕ *-å®×…q`æpOtºã±޼`ùÿ' Û§”)“¼a 6'oC„Ü÷¢09yQÜ´8vÕZW/ªPjE©=§ÚAuA}Uá¯, ÜÒs]ùÛWÃ]_ wý¼´PÂ×=¯µV6Œ»&¬!Mà©À#€–5¯agÆÇÅÏ/á·Ši85àÎÉØvVà¾ã*£L!»Hüú÷6±xS‡@qëOÙ€ñGÃC¿7~®´F6Œu¡¾¼‘[];Ñ’ß |x€+Ã0 ÃX»�Ç__‹'[ËáúW™à Ã0 ã˜8xÇZùy-#ù··ãc†aÇ̽Yƒé±µŠä� Þ0 Ã0ÖŒk%gÃ0 Ã0ú‹5i7ɆaÆ�b’7 Ã0 ã6; z+·÷XÆñAQA‘ú«S¾ðaœ~â?’½A'q¶�aœP~ë6¼ùX‹ä Ã0 Ã0Ɇa†IÞ0 Ã0 “¼a†a&yÃ0 Ã0Lò†a†a˜ä Ã0 Ã0Ɇa†IÞ0 Ã0 “¼a†a&yÃ0 Ã0Lò†a†a˜ä Ã0 Ã0Ɇa†IÞ0 Ã0 “üqæ‰Àv;d†a†1|’°øðfàIÀ„BÃ0 Ã|É﬿ž\\ L_^œŒØ!5 Ã0ŒÁ•üJ2à¾ÀK€K�yàÛõÿïk‡×0 Ã0ÉW»�àýܵŽì¿ ìª#þ �Óìp“³ÄÚÀ0ËÉÀ#Mòý�Ÿ<ÊÇœJš»3pÏç�Ûùml ®VkÃÒ”îù+ÁÝÀS‡ù gözwO9–�¦Žê/ºÀgëçÜ | ˆö0 ÃZÀOÔb?ø) yÈ}.5É÷—ä×òà/x€›ê‘‚eé_cŸÃ0Œ�ã¬úºþ<àn·á¹ÈÑ�›äבë€ïwY‡çÞ\Pß®^!üË€ûì†aô§­ÅþxàvGñد{MòýÅë$ùÃõ—‡ö#i8YúŸ% ÷†aÇ—m¤d¹‡áØVR]:ì�5ˆ’?µ«O¤ååzàsØ|¾aÆz3JšKÿéúvOÖ.iÜ$߇¼xàOàkhóãóù—×Âÿp­}. Ã0Ví¥Ô×ןÎëðw�Ï›äû�yà¿€÷ÑkÚFZ–÷¤úÿß[å_ÌÚçÖ0 ã9kEàôh`óqø›Ÿz&ùþdgŸIþPΩoÏpå éf#œX†a·Â±$Ë­Wl„†TÉ_üÑ€¼VÏÁóùK¤!¢eé•TèÇ0 cX¸"Zã»LòýË€`l_ûÏçï®;-;II 7ØõÀ0Œ§MÊ|_¾ÖÝ›þª°:¼Ó$ß¿”¤ù”' Á18…TVq¹´âÊõù—bóù†a †KîÏ� øñã•åú‰²AFP³~í;‡Dò‡²r}¾Íç†ÑÏתóWܶ ÐkÿÄFê} ²ä‡›Ï7 £_8…´^ý|àqÀú>V³Ù™IþðMàFR–æFáÐùü)Ò´ÅNࣤ²¿†akÁVRe¹å!øs†ä}ɶå&ù>é�íž¶�?„Û9x}þÊùüOûí:eƲ2Ylølßç'6ÒAô¸Ñ%(·6ŸPX†Qã�{q`tð¡¤Ý9‡�K7ÒAÉ+ öy=ìxå|þ"ié¡ÍçÆÆ5Yn-è’63É»€oçÚg÷6åàùü=ut¿øp½5‘a +“å Ü~ƒ·Ç¤ ÆLòÄ¥&ùU±ƒ[žÏÿ80gMdÇiC—åý}°‘ÎC}±¡Éï^hçî1³r>¿Ç�¡ýK�¯�æø Ãè/Ú¤)¹å„¹‡¹5‹I~˜$ÿiR<;±×Ž&ðˆúö'À>ÒnzÞjÍc'Œ�š,·ì!-Ÿ3ÉË[Ï>ÔÎáuc ð3ÀÛ­) 㸳2Yî§Ië×�ÕEñ.ÙxXÖ@î4ɯ+ðK¤zφa¬/;€‡aÉrë!ù G6DoÒÎáu¡ü")ß0Œµg3W–»«5Éš³\<Í$? |‘TÝm“�ËkÁ?ÉoëBx?ð(Ò\»±~|“ ²ü¡¸!y)ÏX[ÁÛ½a¬à¥ØrÕãÁ'6êwCô^vÚy¼fô€_0ÁƺóUàѤ,ÆúqéF}ã&yãp¼ ÑÆñã+À,¢_× å3&ùÁçÛXiV‹à c0ù)“~ÞšbÍùiEóÁ[oô²â«°qʲ~x<°`§ÀšréF~óÃ&ùËì|^µà-ÉÎèGÑÃÆÚiò³Ñ›äMò·~0mûT¼1ølþ�TÝM6ØçúsÀã,¢_¦�¯™ä‡‡=ÀÛym‚72r_¾mÞü&pç Úqÿð³À’�ÇÄN šä‡ï &xc0þ8Û"õS¤¡{‹èWÏ'6z˜äMð†Ñ/lÞÜ“´ÛaiMÂg°d<ó�Iþ >MZ f˜à�þæÐ!ú¿¼ ¸Ñšç Ñ?� ¼ l•|ø‘I~øXþÓÎo¼Ñ÷èŠ~YðoÁòjǤkŠ#æÖÃ)y°!¼1(‘|xð à_€oX³Ü"—?t­)ޏ½Lò&y¼1ìœÕo lËCô à�¤mVß|é0Q¾a¢_ %iôÃ$?¤ïëK؆&x£æê~¦þ8øgÒvÑÆ‘ñ àçMô·Ê°½†Zò�´üÄo‚7ú+z ^ ü ðO‡DðÆ‘ñqÒ½‰þðØPý�K¬Ä­ ÞèG<ð"àYÀÅÁ«Eo«‰~KºÛ’ßÈ=9¼Ñ¯×›gÏ>@ªê&Ö,&ú5fiû^cÈ%ÿ=àZ¼aœ0ÝEîBà%¤�-9víø(ð‹&ú›¹Œ4ek ¹ä>i‚7Œ¾à¹ÀËHÏŸ´æXs>b¢¿›�ß@’ßHÑ‚ Þè×kÌsêþràÝe­«èŸ‚•¶Q¢ $ùKÙ;™à�~A¹ý2)“þËÀ{MðëÎ{€'o`ѸÚNƒ�#ù›€«Lð†q\ÑZðO^EÚÏû@eMsÜDÿ+´½-«~ƒI†{èÆoôk4ÿØZðß »±åŽ/ïÞ ¢·ùx“¼ Þ0ÖAê+³èDªG• þ„ò.ÒýF}EÊû06˜ä¯`øªB™à�~åA¤­b¯! Ñ›àO,—OÝ ¢ÿ"°ßùÆ“|ø¼ Þ0Ö�{KJ|z« ¾o¸xƒˆÞ†ê7¨äaxJÜV&x£O8tˆþÞÀ?Ó¤=ám½vÿ‰þW‡\ô–t·�%?,=<lµÓÖè3î¼™”Uÿv|ßòÀÓÎeŒsØFGZò_f†$zz+ðkvê}Â=�¨ÿ7ØÏýο“6¶ú!ŸÄ¦‡6´äÓuéLôÆ îhJ-õ;’†æ3Ò\üŒ5Ï@ðö!½ÍÇopÉÃp-¥3Ñ'𳀫ÿF`¯5É@ñ6àÿ Ñû±ùx“üÐõôLôƉbiy\£ünlËØAc;ðÌ!y/×’ÊÙ\ò? ­Ý5ÑÆê9 ø;`l…à�Ábiû'-Š7É;‡ôšè�ãÁVRý¹¤$»=Ö$)øË€Ÿ¢÷dóñ&ù�‘|QGGqÇñ­ÀÓoã~ËISŽërÈ÷·ôõÐïmxvc°|œÇH¥jÏ%%ÙY?¸ü0 >Ôïɸ² ö~/«Ú��›••ì¾^GLGó:—E©^ø-ñHRÂÍpi ãÆú¢}=0[pý¡ß«}|6Z þo�ó€¿~dÍ2pœR_ÿβ÷õlU‡I~Ó¤m/ïÛÇ‚‡´,I€7¥èýˆþÅ@X<Ø ´HÕ°ŠZö?nXñuiëÞ½¤RÁÆÆ`¬>\Ÿ[&øÁãv¤%Ägá{³ùx“ü�±³Ï$Kµèÿ¡þº–¢×ú÷_ÞY?o4kÉŸBʺ=8µŽÜŒ×¿À©àɵugàúú¿«þù,i“ˆC#ýåµÕZÿ]=äu‰�ôLÿw…à¿nÍ2pœAÎ>{HߟÍÇ›ä+ù—ô¹à×Sô+‡Ü#©i�Trê0Ï•£õmsÝ8™4¿wÿz$ U�„Zðûêˆÿšú6]�ªG–꿹,wYñ=&û¾  ü1izç_€+­IRð—wZÅc¿¼xu¿¿Eà¿ì0›ä峤áævŸ ~=E4”ut>K¶ÿæa: mRæõ`pZÝøIàÑõÏ}Ý©X û/O\_5)/`¶n›Šá+½9(´€?žH*ƒúyk’�ãöu¿ÁxlÝñïÙ§ïñrlŸ“üaèŸÎÁ÷‹èo ­#ó¥Z؇£YËÿ¤z`[ýý9u¤¸¥î(,?×IÉ4»øñÜ€]uà–²û7ìo£GÆr]üiC“ÏX³ ¤à/'U%<®<Àêóâõ}ø>m¨Þ$‹ì<�’_í~ðË¢3G·|íxˆþ¶è‘†ê§€oß‚\F9x*`;pRþÄVÒT��¦nX!þ›HÕ®®'MÜÈ�o’b‚?r^TŸŸÿbü†üçjÁÏòó¿¬?C¯ë³÷jIw&ù[í¾f€¿–¢ïG”4Œÿ}~¼Ã$Â{‚=à×Q¦Ç"ú?¬¿ÿˆ} ˆõ(Àr‘ŸÃ1BšØ^�l¯;ä@Ž@³~®™z`_ýõû˜X^9p¸crK¬iÀá¸(‰þ7êþK¤D»`§ÂÀ þrÒÈÔÑrð„U~¥èG€Wž€÷ý5Òt›a’¿U®­/¾ëU ªžt$ºZÑ;ýQ±¼Lð†ÃÈYHS!›I56‘rNî<ªî ŒÖ"-êçYY-ðZR�€=õhÀº•ŽD&'yR}ü¯4Á$çÔü‰ü2“õ¹ÿGC ™ä‡„�ë$ùõ¢_/Ñ+ðQû8¬ŠåR½±Ž.ö¦�×·6/ÜÜ xDݯeÛã@�€k887`¶X$%$<ä¯ÈE‰ ª2y‘À$ßܤ CUUð]‰s*?¯¸«¼3LðƒÅ]jÁŸ¶JAþÜv"_ÉÁ#ƒ&y“|ßIþ·\ðk!ú垸‰~}:’õnâÇkd¤¤À‘z4`{= p)1ðau`„Uê¨ÿêºp#p -¦_—3žŸä ½É‹&Ù¾¡ ï ^§]qN;¸+º>ü3�®¢ #øO?ÏÚ�ýQ}ÍyÅqxÿK¤å~†Iþˆ¸¬Žœü€ ÞD?ØT+Ä=EÊâ?ôø´êÀ8)àÔúë��Ÿ"M4(pK=™#ûÚþ?¹ˆi§¯úÁÏ6˜~aëv‚VNŠ\ á�xJ‹áлւ?u�ý8©ŠázMý!i´j½÷¹«qa’? fI™Ö÷Á›è›[˰�È ¸µÏòV¯lVd ªï²]UÏ\ <ôód›¿†[x,eûSêO[‘WÐÓ3¤å‚{9°±ÐLý7#¶^~ÿ±Zðë=jóÒ:hzù:þ ª7ɯê¤9Vɯw½‰~ø9V™VÀT€)ð Þ�Ž"Õüx,üÜ™—e½?=·b{3 çÒüî7—º_ dÛzÄmŠžCÚNvó!# 7ÕÂßW�0L“–Î�¦ŒãÃÝjÁŸÒÇ‚_æêkÎËÖéùm™§Iþ¨ÙyŒ=Ïã•Eo¢7n›6’W%Y-OÃé|<³“µ^Ù]êîúe$´�³ïÞXÚ÷î¢ùÉÅ‘JXÒÈ�Õ ÒtÀò2ÁͤDÁ;÷®×äÀ �©Zø3¤ü€åÝ ÷“ª§Uv@N¨à?ZÇ;ïâåõ9õÒ5~ÞÝüø.˜†Iþ6ù\•Œ®Rðý0Do¢7Äàm¤SÛ7qFÇõ^N·,î±…ÏŽÍêU]²y£çè5c½rN9P>x©öJ|}­ÈIÉ;H9[H `g’– ŽÖ�€ªþlì_1°Ü!˜®¥³À‘Í CTFø(¹g„l[Åc?R þDÍ_¿¬>nk9Gÿ lúÈ$¿JQ†´òÑÐoCô&zƒ ƒzä̪äetkÆÛ~r_þëmâ�Š„àQBu¤Ìåê}=$Jƒ´D°EZ°•ûÜž´Tpy��僅º#°›S7Õ££‡H]6Ø¡<Áøßœøµ—ÖÇíÅkô|6o’_5;�Ròƒ"ø•¢Ò~ô&ú!¦,ѧ._¤B‹ÈßmŠÌl"4+‰ §BÄ3Û–Ö4µ¾X½ï9Ìï—w\.6‰ð Õ8 �ðŽ—×Á7È\£ªˆNÆrA }/ï&¸§–÷/ï#%[-Kw¹FÀRnÀ6à'H mÆêçê‘ ý¨–þð?õÏö’J ¯LH“C¾?írï:‚_�àß<¥Ï¿Rô/¨Ûõ·Wù6To’?æ“ðòº<¬‚_f¹:Ú#°¡ûabø=…Q‡¾-Va—÷!hí!E!YòAi6K½8@ŸQ8�ÍÏ!Röõm„4pûZú[ëNíyõHÀH}Ý+8°�pª˜6šâÀþóG!ÍcíܧÙÖ!üÊã÷üº�žk’7ÉŸvÞŠä‡EðËü7ðŸHŒ1Ñ6£ÀïgáÝ[2w!Há=ž 8d± U^+¨õ¡ ¡§þø ׯVêGzßåÕ=¿›`FšãoÖ‘òöúëàÈ _1ªÐ«;W×Ò¿¶îì­Gæ8x…À­MÜÚ{;Á_R ~–+*iÈ>.<ŠÇuIÉцIþ˜øÄü2ï«¿šè›V� ¼ '7êñÌzâ üWÀŸáˆ›J¢*ð#zKqƒ´ÓÊ%‚ûH;PJ›{œLZxi¯öûÔn’1,Õ¢Ÿ& ýÿ°îì®;ûëÀrÇ}ëkÏj1ðT«�’ö ÀsŽð1Ÿawe4Éo®'eîž³o¢Áÿ6i.÷-À é86ðtà½ì įåኢÌa“¢z¸Æ’×yl�ÙtVÈäÚ[¸^N�ò6“rx– �CÊh‘¦ –wœªÅÿ£_¯!­¸ ð¡úùŽ–ÿ~•Á,8¤õy+Ùa6To’_3.]!ùa¼‰~°i’†>XGt?<ø×4¼P¥áejd”8ÛSâð2;˜‡[¯†on4àp9+«£ÿå|€åÑ€‡ÕßO¬¸încu›cý;ðôº&+Äy¢W+úçÖ¯ù7Mò&ùãÅκ‡¹Qo¢\Á¿¸_-ø¯Þü›´N¸ƒVî(í:9ê (ª 2A,„_IE~Vvºä�Ñ—¯Z¥à¯ÞP� ìå@²Ý ~¥èŸS¿ö[š£¿‰´úÉ0ɯ —ױ͓7�àMôƒ…¯# ûï¾vÐoˆwH^ ï‘NJ+8…ˆâôæ 4 ±æ\qÝÚÏÎ&kÙ-ÓµÜßÅ�$ÛHS?$­ ¸šT+`¾î,røzý&úV=:q(çÖs “üQ±Ÿ´Ôæôý›èû›x&iǸ_¼¥ wJ7ĺ[ �ùnpŒ¸H4C“ÐëiÕ¿ÙõÃÈ=�¿"%ö-^[Ÿ£¤e‚§‘ò6“ø¶Ô¿k×�YàÀ‚Ÿþ¶>_úíxGàõ5çi‡üΆêMòkÎ76øû7Ñ÷'RG:ç>Ø‹uð„©Ð�— Ä�Ð,Š*f8éHŠÌÛfƒ"øZ˰[Gé»I‰ÂzÈõ¼Iš÷ßÊ�‚A'“¦÷ÿÚ§í€ß¨Ïó_]ñóËìÔ1É&ú� ø'ÿ«Žè>wË—Ê �÷A|hPt3øûÌú§¶©ÎŒDÍU¤š#ÂÒ’ …®?÷ªß^Åc?ü‡²>´“¶¼Lp‘TàgåùójÒ¶µýܱ À¯×ßÿ*©Òáõvú˜ä�õýòV‘&ú'w%•w}2ð1n³(H�Ë•§jwø†Œ¸ŽÛÂuig·UÇñR-¡–{·îÜ›”(·Á¿x kNzYôBÊ)0LòÆ:òÞú«‰þÄ À£� HI¡WɃ<-IÁÐj9:’•"DU�£DÁW¶H¾ÿ>àÏÙ˜IgË¢?ÃN¡cÇYG ú?çè‡ù–Eÿ8kÂUs>ð,RÒÔÎ#:É‹’¾õÐ�‹½°, AÚ Íç©”f&M�eد÷1Á©h�a‘¼aýÐ!À£€g“A/;â ~„F¤‡ þæðH5¢¢%±A†_ª4xkìuà�¤Løæ*ÿ,)Ò0É&ú¡ü7Ik¢�jPÝÓ€(ü�GF<•8�¨¢ó~ù¾Æs^-øÆ*?c«53Œ[½Æz_„lèþè$ñlRq“gÛ‡<,/£óž.è4ú½R)ª‚ÃÓƒ€Úù¾ü{Lð†IÞ0Ñ7$í¹} ðO¬2-®ðaÙö ^öÂ7Zá}ü�"Û³ú85?¼t5‚‡ £pzÉÈÒ{'ØCwæôå!÷{ðO!O¾þ鯉ÿ/Üó_;Nµf7Lò†‰þ¶Eÿ˜>yO'-¹ú8ðiNàp¬÷ˆÏ“Ü[¡Õr�î¡ÊќǵucK>ÏçøÒΉG=DF¸}ôèÕø÷^YVè|~ƒn9¹“¥m nwþ¹¿‹~øÃÄË>†¾åÏ`qyæK±zÂÆqÂÊÚý z€ß]…è'ëï?~‚^»Ô# �éÁ/Óèz ´¡[Æ“s²;,5žQ� ¢�L7ô¼pYòsýÖÈ€ÃóÌEå”k¢ÛóåRÂå¹ì í-øù©“®²‚¹ú¾3áe¯†ë¾žþß]$¾ø%°ùv¤ü «]`˜ä }‹~¸3ð©~|ÚUÎKá!€â‘VD Ðž‡± T8]ò°�WÔýÂê/àÛ¯ÙW.cÓ?îg~GÌ;3šÍÝŽ2»^ÇN›Îº»òêÀ€ýÒžt[Éüžt3 “¼a¢ïwÑÿ p{R Ó¾‰Œ;%o¹€‡zͶCīТZu|IµÀKåÃFÛnö�¯&‚GÚ¯Ÿñ’2\S#À<ã[;®gj¦]‘OÄ6süø¼¼a˜ä cE¿ ˜ —D•A=IàÔ‘‰‹¥*Bâ=Òec þÉýÎˆŠŒ¾~|lþ=Ty‡Îq|;ÙÔT»jSIΈ”ÌA»#tl‰œa’7ŒaŠè¥oDïO ÔѤ'à<²B@@Ñ÷ÞC@ ÐÀûBº ³P‰:JAŒÐ€f&ôzAðO^¸Š¾›fèŸTù–SN“ÊÕ–P–©ÍÊôÏ|¹2¹Áoô¶„ÎègѯvyÝ$ý³¼î¸ÚðÌz⬋ïŒÈõª#TÂR7@ÿÔÕ >W2ÿ'U>ñá6Óöi4Lò†a¢ïÃ×ýãë"^?“qc™D<�qFÜ�/Ö~*ð‚U >}M^mú0­q7>nkÚ “¼a¬§èW»MíŽè´êÏw4䣒!â@2¼,mÆÍoF†xݯ®NðD¤ýš¼<ùýäÓ0ŸÇù™¶{Ÿa’7ŒuäßLôGêö Þ#Iòδñ’ìUjD5'OÙåóKqHCÔ§Ï_•à�{ÕéÙÜ`ޱ“É&ØC¶u�]' “¼aÑÿõ*'@{ôR#•µ 4 c£�ë´¼Ð*œ'—@‡ùY_A6Œåpž<ïè–©oðÇDÿÑJbÉÝ·‹rŽŽvç‰öñ3Lò†±þüËQFô ¼x߯‰ä=D(J4´ FË(ä"x*Ð&™@†ýÓ�ß>ú‡5ÁŸýšÑbÇG—_–¶îÝ\l �1ˆ=ÜöšçeÁ¿k£5PQ!àS‰[&nK“Ó«n×9 tH7Ö*ï.Æ^N,Q�¨*âš ²¥¢Òå À€ší·€ß8ú‡mV¸×k‰ŸºœØ¡S¢oênóò†IÞ0Ö•v £ßo£ír:Ò¡MI¥ä™Pv”²Tr„­ü‹|%6[ßït�uÌžU’W%Ð�’†Š*Dñ,� �ÁR´5àÏ~m�+á”WåãÚyòÙ¼­}7Lò†qÂbyÎÝ13~á/eáþóH§Ú+³qŸ {Ñ]7:nÜÝ`÷L£ÜûÉ¥™y*4oÃ8¸,ƒùn™¶ýÌKh—’esRfÀÔðGo…BÚ‘Ž†ÌSĽ”ìÁ)¶:„‘^O M–6„à›ÁÑ{Ysû®ÏWS'éÞ¹ñªÌ;Àû¨&yÃ8Þ<ªqÃȯí{ù6z[ÈJ)#ºèôöT½ €9=™]ÔõПW· 0µÔq»fÐÝKø–(v—­rÎEöÎÏesS´ËiˆW2?ü³®-ïeТHËé¦!|j”o>eÑíVt«G¤íq³ÁR4û¬Õ ~›Â]ÿxóÖÏ~af_;nß:í;LkY効1Lò†±~ä¸-®;3æ˜Sò yb¹4ò¸^õ¢Q¿ðÐ"8ŠÊ)h�BpQ$ R*ÚS$*J7gʯñ.Û"ꉪ ôˆ•JY 3MØýäœ=™®”§#»¾û®i±ÿª‘¬ÓîTJ…V%šÑ–¥� �:Y/Ï…v&œŒÏ÷vB˜óQ%4‚+äæ%l%xð¸ 7ÿŸ´¬o D”"­ ć´],m~v„Þ ±P<¨w~ŽhwÇÖ†^=‹Ô^ëF¼°40¢û0ð3À©Gþ�ÍŠ{È;ðùØüLzŸS3í *ò‰ÒYŠ�a’7Œu¤œËãÔiã®��çÈé~®õøÈï�ÚuçCôû%ꌲÔÊø\GU7…ÆæltÄ£-…Pï+u‘H))QçqêòJb¦BÛÁ¶ç´J‡‚b<ª³‘²Ùu¥ve! ?š�ZpìYt�…©ý�rßBÆü,ÞP–eYÂÌÜÖª“ç4¨¤pK°Åg�éPB[=(p� >GÊ®�0Z‹´ <Ýô³@¤ C£\(Å(�R!€OÏJ”#]æ‚ €’;ß ¼tvÍôr.Rà@zJU Òér#)áîïŽLô®„³ßAóÊ·Ð)5 ½³âܳ9yÃ$oë­yÚ»$tÚsœ§´ŸÕãw·«lI¤ƒg–БœÎ¾^{š…æŠŒDò&´rhEeÌ+›UجÂV�± ´TcÓ+yCñ€D�Qbú^8mÎ ›Ê횊´ÝI[Û8º±b®€ùv‹”{ƒìÙ-ÂÜ?zNÿ�'¿ÃBëào˜(* ”è•ÐP_8 ,j£±˜¢ö€.¯I÷£‹ ”D‚—¢ðÑã¥Á"¤ ‰=øFÅy*�Z4dq± �4ºžˆ¨ªÍ Yªü  W©è{í±ø�…k>KgÉ†ä “¼aœÚäÒaNï¯eû)¿³]óÇJ™w°?†E¯þƒóe¸r4ÃÑîE´€¢pUd„=]œ¶p2ÒRœR‰f´F]¤é£ßäð'9ü„“Îf”M ܘ YTÍ¢à¤tH© *DDPÅ¡-Z¢loÂÙ^D …Ä­¢ó]Ð'†ü�šTsÌë| û\¸iÆÔ¬gß>af&uÂ| ìB삆ÐRbTAñ…ÔYð7;½Ò*�nzÏGLhx) O/E#@((Fq�¹2œô$Ä‘ôêÀ ‰~¬Åóº¼ñð¢?)àf_D/|)§¤ÝŽEí†IÞ0Ž;�[ o˜ä ã„p®vò +žsûŠ Jâv;íeqô= ¡ó�¥v%UYi»ÊÈcE·rÀÉâ] !à DpÐs Y­¢JDÅ!¾B@Ä‘U.1öˆ½Ygª!û§Ë�4ÖyÞô“"ú-<è½´?öãmÜTE˜Ù·#ä¶LÎ0ÉÆúÓºÍMWí(÷´÷(íqwï™yžZ¹'Ÿéã^›~ŸôÂ~Ot˜¦s•wßC=]m¸xÐÞç¡®^'Ž$øeTµ¸\]ÃÞ-ß#R¥ï  4Ëå{$zí¥Øy!8<ìZŠ€,e•4 ܵÑ Üeî“-ª‘±Œ­12攑LhgÐRÈ%‚€ó‚‹‰N¥‰*€’ š¡ìPa Р§Tá‘éµt*dvÏãnZDgw7âž*2ß÷GçŬG‹B«%�ʼn¨A7K'WGCªêGp>VÍ ž•õëSFÿH#¸ KÄåJøéj —2ÿ=�Ñ”^³!õÉTUÊ?hâo>f=ŽnCçqÑå²åä2ïr:Ìå�?ã~ēϛöW}Þýè¼ÁsÚ%ŽO¿·ìÌÅ}J¹'•>¶�ža’7ŒõgÓU§—{Ú3:ÑiÓÚ2ïžBösw’ê‘EJæÔ‡X…v2®$öÏêÊElõ«ÒÑÍÉ4P…®£œ£º¶ð¸Ù2 " M¤ÑÄåž²)ÇÆœú1§2®QGÛÄQMAI‰�ªTh (¥ "êdù%(-Ýê…³N"°8»pQ‘*@·Ýt¥ÌÝÆl…N/§f|X¥7±(y#x*@ðrÒ’²DÆ=õ4¥ УÒ4KïYªÆ#!h/!½ˆpóÈ·„fß@` ?OÈðu—ɨ‰ßìIïvºÓ˜’÷í�¨ MçôÒ±ïOÈ–îó{Š6Ýþ±ÿU6çŸJïýO íï©«J(ÓfDö‰3 “¼qé0¥TmNnÏù wµžp6ÅóT%_BuÎiè(ŸéhöÅ¢ŠÚ JìãM�{ˆQ+EÄ N+c‘W’ÈA— 7ïèid>Föâ/�fDš8™sš‹Ð´‘)meÂÁø¨è¸S™ÈÔ�9UÑLD3N#D„'BEPˆÎ cc^8Y�1:x…­ §¢V,5�¶+­…Â]žˆ<¾›3ÿí¹±—öw#Åþ@·‹K ½æ¼@êAd–:âëÑŽ€V=b¯×ÄÓ�0Ž„z/û½JÉÂ!]¤UH^ÑV^º¼Uºn6§Üð’{g?½�…WBX˜@G·�oe±[•”–`g&yãÄ0×Ú3ò´÷ˆ³é=/Ã5ç%ê‚Jì‰~–ŸŽÝŠ,fR€f<4ßO,›ÄN�_EFqô@—ˆi* :ñ8 T7/‚ë:´£³žƒ^ª%_i…â2dOåÉ~$ºfF6êµñèH^t““0¦Ž±‘H ­_†ŠˆÖË%-,=â"š�•T©Câð™ê�·«œ%•p—J¤,ˆ³=Ñ}… û*˜Ý·ä¯Wdßqz¿wé~‡Ð›O G ‡GBXÒ‘ùfLï®Jkû›©3°tóPÿjq„rTCYÅŒ éðúo±éáÏdÿÏwA˜ÿ­÷^[Í p0m4Ã0É'‚3;3üF�GÝ^&¸Ö¼ º_‰]ôóQ¸tnÉUÍFt�XEíóx¬¡ ’� *¥F•&NcÔ\‘¼B¢ƒÒEJE#8Q©ß[•W�¥ÞÅÇÔ{.ÒHCþ±“Ånác—’½3J*ÍiE¤�³è÷J«¡:ê�-i�ªNx² W…v ר¨"ߎ ŸÇ ‡RI”ÂÃ\Ð(Š÷Âɶ·Rî"[ Dˆ+)ƒƒÅÇ)3,Íî¯à¦Žgj>cºö}Ñ/]·üÂ"Tó¡©KK ¡ 9Ú¹ø›ï¢+cW™È¤,;šwN*ÊýWôàÌšŽÖUÿo«v¤"×N½ñ a&yc=ÙÚöùLÊv)tPÚm·µêðlá±?Yð¢ˆ6;(³JŒÚúr§ÕݹХh“»¥ª’›åòŠ�úW‘˜êàǃ“É|Ýa¸ùïU7ÿþ ¬ò}„ýÀþ¹! §fQoï„ïÍ:ý¤sUžW4‚c¤òl΢ŽeʘW7ÑVÙЦ -¹DñJÐJT¢ •D*-@¯’«j¦p𧵯T8 !¤²½*H¡!ÎgÓn)Ζnê SspS?ÿíÞæÙoQÌ.mqh>�DÅ9¿ Û¢d{³×3õ®9¾2McÜuÊ :ÌéV�óóÚ)'(�sšç¥´³R² fæÚ1µG”ä”i â ¹@F^æ´;h™Ï-w¤C©i¿„¹Òæû “¼aä”Ìw‰�‘wJ^º½ßmVÒîûð±ùrÕ›‰±hÚ¥ó¸ÐÉ"%÷9JÉUåCˆ3®ÏAr‡x¢äM.’ç™SFC”ñ&:ÚPÙ¤ÊæFiƒ6«´ÒÑypN¼ŠJGÓT€ÀˆUa‹D΄U�êDGYÞ…¹îY,ªi7£èîïã>�¾'Ñe)®–Míëý)›q»ggª¹‘ö„ÌŒoq´ZÒÞûÝPGßRUè\•ן òL ¤�!9�U¥vÈéP*íRÚt$« /s�-ó¶@–¢ýreÕ{Ã0É™r‚’RÉ;ò’2ÀÙ÷Š–�›–aV Cøj>\�2s…µ×ñ:,z1„ªŠfUU5‹Òר :(2耆Žë½44÷‰[N'P¼C²mªÐÞê%2£ ›œÊX¥:žålÊ#Þɽ:¯*®¤ŠÑE§àTÑ x…Lˆí* n»Hu×34èséÉ6.å½ZÒ@Ð'kG¢Îj�]•㦪3wÃBgnoó—�ÍݘUe•çJ»-)¬ïÄöx髪ԲB;�Œi7˜îŒ¡Ý´1˜6P f3Hˆ­ ´—j¯Ìª\"2âñû½wïüñ‹¬*a!„„$âž“'3ùÞû½ï½÷Ýûý.µ|±ç9?hs¼]+{ «I¹v®Ý^°cw&eÈIHÊÒ&ËQsÞÈF ?²4›l¸$Ï­V%o·\ú}ôg•ë^PF¿;�í^7e�`ƒ=`iøðzAo@ ®HC³˜�å£èJEý[�‰ÆR jbAZ»â� «ú©¦©¦ÆUÍt€xL�L6¢ûªÂÐ|uW8†N–ªˆ"²‘²©Ä��î”Æ¬Yˆ‘(¥ð„ _)¶¯ŽõÏúòL—Úºûk^Û;Ë7%úÁݦóLiŸ �›4t*6¦2›LÔÅpÃBDçª8ßy�RŒ ˆˆÅ‚m�L¶Çd“T"» Ì,Ò>:("ÖŸX¬y–8Ó£\쥜ï¹òÜ—KWÇ鞬1Xé’6Fqç;h•ü‡rrBâú²$òå¡8Îd×ÒÀã=v±Ò?N†µþÁÛqé-IÊ‹y‰U¯“oÔ^š¯$ÊÒq™�Suµ�·G7×ÈF ?²ï2`oç:‘àù$§Xo¿—W¾$�«NØÙ³uƒŽp\ja¾W°†CÒ!s|ì1ïF{У öŽ%$ü31¦3‰ç+¬÷ФCzÑ[P6݆™€oå±³a?þåÅYݨø×Ë<ˆ>»5ñézÊ1u«ÝqSöîÚA{ñ¸­o´k;ùòZAHWý†ãœ‹9çRõhE:$ê4N±¤¦47Õ6«1LC¼)5×Ĭ©„ºÎP11§WÀ"PST«'A l­þ_¡Z/œm…ò™X°5WdÅ£´�?ß+“3¾¬Ÿ:GÿÂbZ®­ ëi{¹wO{sX$×|2qıÐɵQ&Ö`R–ɵÒÀËd yî­Á„ÄC ï�[;�FÞ°’„<©�>IJi´½M0)È)io kî­‘ y‰•”@Õ)0*ÙäGö][9™¸e4JŒ~QËÝÿ,Èÿ6†¿¶\ÇAÒ³ƒ´ø õtF#öØšV [U’L{·)…ÉrÚ:ìÇú 9‰qý.ÍÑí¤q§ìëVz6Ågî¾¶þñ{?ÑË¢köñw ç]ÿGã*ã`~˜žÁ�u IDAT(U‹ˆ%Q Eßi×Çz~î�£† V¥6®4€1„Í1L¢L–´J˜HŒZbÔ]¥ $¥ È�·Èu¥áz† ¡ ÓθfL…IJ%W�QH¯DÖ=¶V°r.Æ]{pn–KôDVï£è�ëwmn„v¼MXÅ/SÆË—…•˜ò²ae’@#âRʼԒ’v£enI^Õ ´ÁòÆfa"vø¾Ñnk“rÔ0²È�ì‘ <mšlá5ra÷Ë�ßkb×–8·&JO9áÿ¢]ÔVq—zàGöØ™€9‘ª ¢U){¨ªè.’ôÇ/ÿô{¯šâþÓºsïŸd­hòÕµæ@—û41!ˆ=à�Bé.n^²±�Ñ�iP/99’:dÜ!¥£¢î¡ªCXFµt>Ôa�*ë— EÖñ–ÇU&dLI£Àxꘈ5šª[¼Ù°©tÚa“@œ˜DÎ,!2‹0 uêæ‚!jR�Õ…³í"žJy©[ß¶šØSA_é]WÑEw:ç;Ñ �S]–û5ΩËϪåkÇú_Žñ§¶O�íÂé~h³håDÛåýD¡!” ”åàG6ù‘}÷ÖfÒ^”·7Ýó;WZôô5D;¨¬¹òLïïå�ó 4r•8§Øèþ±·!%>"Q%#c¥`‰ÇHûìJW Kú”Ú—xÓÏ.EÏØC(µÍôîenºrœ�Ý�ÖA‰µ!I’ÇI€då¹ðUÕUÙ6Çs*—;“Fõøº'$ µ‹Ù$•Še±úSOÕ(éÅJ¬HÓÇÚ†b0p z_è;o! 9¤Q˜"5Åh °MCŽ€1$lv&S‰ÊD‚L ڱȃ©áDE@Ä›Ùèaˆ#³IS.ÀvÂ~&*0pÖ'x/”×Áâ«<ç£Ó�Ŝ΢¯sîBß�9��/}ƒþ¹¿oä=hÈd޵GÍý#Ûù̈÷‚Í€"† –îfpªÊ3æ÷aHÞ(‡ý]vPÞ,x0Þ�È›Fcùäµ½õ”£ý‚ÉÍn²�[¼=�ž¿ÖÞôó5~Û@ž¾Fk‚ä–,•Nß×VÎãrb•œÜàйKÍÇ À¢X] ”‘I\Õ“˜H‚IáxÔ,–VIíéÞ”¬ÒñµT#-bõ>–ÎæÍÏâKŸÍö›:4®y w·ŸÂWÏÔ®,†KÅå¯Âƒ>äåEâ6"ù‡_] ·QBø‡ ¾æ°•3 çy�‚žóÔA†¸iF•_¯$:ï‹/+b" yu5Œñ-‘n °IÔ&³‰™TPÇH�á†EŽ®pˆ˜˜AĈ1b"®éWWlBbµ>ìÕ«Y×›M¯ä®Ó§}ÎÇœî6XÊ;�SÇ\~r^h4�?gŠ!_ùì–ôÏ"¶nu<ãþÀÉåÀÁ,ràna³ùyq³ÌÀ¶·TÒÒcfÎàˆd´ìÐ,B+3™Ï„™ š‡.9™C!ƒC™mp6W•œ"XPÄ̱ 2çÑ1Ã÷ä‰i¥nAT ¯…C"&fÁ*Ý ªñÏlv~oy5ìôðÞÇÇ^/¼â½£Ñ|’ÚuG¯ËDyÛk{²!/ïåõעߨI´/G­{·î£óæÊ÷÷cVÙ}ßl£U-TÒ²æ¨Òö…c¥²#ÅbPs8¯�ÞfÚ'8`-]sV#î儨y&<â9zÚ5¿ýPïÔÚyåìsøÀÆÝbïÉäZå ‚–àÖO†Æ(q(‘Sq΢š£>îH 4CÉ$0鉦µiƒÉÈ‹‘†Ãê‰| Tb†F¨PQÌÄ•bN�%H¨;e«óìïÄ2ærv«³Oc+Ï ÑSÇWü?OZröª–û,ÿêpª†;Ern‚úÒÒµý•ÙCó�?l( ƒÙÖ<´ŽÚ ï¤E« 94ô?f]–ÍD¼e›ÚA 0'd È!³lnˆã™ }¥ ˪�Ë„Ö^1™±¹êEªÅ;Š-�˜oaÌÀ ˜Ì1g�1#Ø,Ìí³lö¨í�Ù "Y&°—/¾â^¹i4–OZ»§Ñ7ú[ŒÉ òâµ_ôɯMRî_‹‚!₱\OÂûÏ”œšèÇnàühо�¦Còçª*ú>è”ãS‚l‰`7±¹A‰ÕôRûú÷ÜÙpˆsHQ ±BÓïJŽpý–A>ݼŽ�Ü?9N]z§üÍüÍG÷LܵÒí>T˜ýÄ4§EðűuÕ¤ÔÉå2gLP´ð®»ëÀr„9DÒW,qŽz䨛ÐÇXÓØ¦Ê”3šØ"ÐŒ°TŒš1•” S�Ây‚aËX ²8Vß4sÛrýöRA�uÁê”e¢¾}Ý}²vûÁŸ]QÜ}«p¼ÍÏ�Ø�/Æx`ÊòÓšY÷Ešå g(2A³ì- Û�–öG+Èž™AöíC˜§ºÆ!äÐ0„DLŽfˆÝeÜj¶@ņ¡¼È(’ÿ^ƒ<Ì;˜±ÙY²LØ{D˜ßËL lkÉ £eÙü¼0 ïb¿1D˜=ÄÛ¿(0Bù'­Mæç¬½k{ô¼Eâ7xÞ>—?ì½Óu”¶„nܺ¢§K°訒þqôT}rÃHÞÎ eI„•¡ŠžCL<‡XŠ«×ˆÖºÛ‡ø‰—,ñ“/ [dÇÇtñßÝVÒîo‹Ï®­åUÆáI3öñÏ„Ëk‹Õ‡Z|ëãE#bñ€©æAµpË˸;JŒJâbR§Ô"¥™*“ L‰0í#6•ÊÄ´Å›€Ø«uC¶¢¢B <&nPÑ!Å=l³ ›\›šÞÓ¨�Ðèb7wé•+vöKpÞb΄ã/Í~øþrz;á�“ Nå)½±«ÉîË´uóÍ.Û¾]! ÌŠZ–I‹C2‡YdÌ…ŒŒCdp†½�6�GäocÖíoUg0s µ3‹¶�ã>rÏ´þc†h᪭{xÕúî©rö©kG¹ú–Þ]WD÷ßž_ó2ù7Ÿ8¹8:Í'©Õ¸«—£_öîWö8ý±®Ot€wyˆrW¹ÜçîÒ;¶¢Ñzìm”t{<„“bDUµ¹©ƒ!g 4%u¤}Ñþ£òêÑÈ7­÷äóüÔ� |ôiÒ�ñΞS­i.Tކ\Ž�Oä�>𠃀‹m¤>F.A鯤\BùØA¯áeøq%V«h­¸Ì)ð€ó Eáè¬ÀY¯N#sRó¥>*¼—2¦Þ+ÜkKÑd·ET¸‡š™ÕšJÔT,*1) )AJÌ)H®[}LÖŒ‘ë¸^<”˜&¢xÃî'2ÍŒç¬L­É™/e¿s~ç´a÷§yïñéåÝÙ‰ÏÍfÞñ tÿ ô¶Ûaÿ JËT21³Qpð¨�ü�9ÛÆndk÷²“2z ÁvSÈ5<÷þk¸Q®³+ÄÎ×-àÖR"ºNè®;‹èßóœôO‰ºÇîMÆÇ‘N§*~™2.cÑ1:obÃT�]îÌ È¡�ö—aQ†m¸}—]Ù#´í�(YDã$'�&_š•yô/ÿz'òšžJÈ]éVTò�†VßóÍ€’Ò�<Í¥épƒâÁ5K#ûþ„ò6¼Á ˆë™D\0s8L�ïE4׉BÏy?L7«ƒ8%6í©SéËù Ÿ¦8}/ý îì嶯ÔÔÉ ©Nz©ŽÕ‹¸x’­™‡ú¼’ RHq�JÊŠŽ—¸¢y6j> oâ�b踥ZÁ˜Vgþ:Ìš �*–¢âbu⊚.3 ‘çÈÀ _�Ãéº�,`Œ;ðQ€š7A©c4iHM‘t€6‚Xâ…(¨à‘ÈW$Aô­âùñXGh®»�¬k‚Ø7O9{Í;ÈgÞab'ï�9ž—Ü]�äô™„³E�3é ¹`×Ñ^øw„ƒÞ%ðfs‚d£Ðá‘€<É_÷Æy*‰4‘àˆ€º@¯BY3©@9Fœa‘W¼ ZsQzªxzñ?ÇîMÖó ˆ329™ÙÇœ"3 ™CäH A†¹!©*-mX¼Á¡ÊÄ0\•ÒÙ¨b½èÊÐ -†ïÖVÐM�Ü­x´‘O’ï*Ý‹óä Æ[w¿ÚG¥ëÑŽ&ƒb¢üp·[¥oªÈ"�F£ø}5sˆD8éÇjæ�àÔ"‡8D*±7¤cý0¾7ézírÔjÄRWèÅ^TQ-š61±¦Òç¦æ¿¿»ÙÓÛ·p×âN¾q¼D-Uд�A/O"¡¢èÛ\‹.ºŒü—KjŒÊ%š¿‘Ñ�Ë_sã(à¡Ækãš)fŠy&1RÏc3ñ˜U2ÃÞ…Ë�A|T}u/í¤†Ea8ƒT¡Ö�lL«©kzH=RSsuERqY½“˜+0ñˆx�sV½rvÆ ›JðDÒ Áî2t tËÏПÔti×Áú±Ïð–?ýÛ·|tïÂŒÍ2 æ È7Y´?�X�¨aedD*lˆ> bDPX0§ÕÁ}Á&uÅtôÇ|äì)žû0ïr•Dü•%Ù‘,0‹pà­·!;š™17ü~q"Å {Ž"á²Ùµ ë¬ NªÕž ÎF³ú]Z£„ÅFbøIÀó{íÚëàW® Ñ¿àYèÖOѾ4"¸y"DójHc¢Á “‰!uœóú½©®Š�OQó¹÷=À)_äUÏèpí¶«;Ÿ>ò4>¡YÀ |ùëÂ7ÎVoê…ª8ÄŸou6F»ù÷ßD0A �Pâè¦Â2¸'NM‚…Ø /45�£îqc¾LKˆK,V$ö‚3C¸h@D 3‰ab»º‰í[UŠgÖŒï9óZ3­s³£éx„ ߨû³±}¡v˜Q'¯ ÕÝ”¨ˆ¡‚ÉCŽjbƒK„¢ ²Jlè..Øû.¯´b…?ã©îŸg‰©…�&gãg·ÎÛ½¬¬ßœµ÷ÜnÏn×f¤EKe¸9n^€……h.�ߋ۶€|2meó2#G«öJ™€‘Í�ÎtÊç‚]%ÄÆëËÑëÚ¼q�Ê«Ë(D¹b«&¹Fö¡³Q¸ÃŠš ƒÑx?�}ÃÜ0ò«9¢¤Ï nJ0J1 æ-ù^äÈ…¦„A/X�v|‘_zÉi^~³’Ê{öMrçÿ³Í­ |íÌt�dàÑ*ÚtJ”âBñ`\-¬Ç‡ ܰS£j±& Õïê‡TŠ•Bi@\7¹l! *¸ˆšB juoÔK¤®XÃC£DR5‹ cMU§DÒ“à.˜÷+ÚØ×ʬ%ÙÈï{$ ?óî£�·´²�<²÷0ÇÞ¼sBW_ÙÞÏÄ¢!çp*"FY–Ô%¡4¥¤$•ôa}ïH6³ÎÏÑS“¬KÈ‘€°N� 4íüí_»}­Ýß*>pÏñ'|š=0u;yºJ™�ge`Û„qd›ÀQcæˆÐÚg dYµ/ŒâøïÞ’ó“0]'þÍ÷Æ=D¯HiEHl…05ýp¸#.œ®7®>\�W `¢uJ2¢ëd“` â€b¾ªj¤ç[åxÏ�­£ 6Åwës÷�ãE7@ì‚,«³AÃQkø"íŽ7‹D\Œ„ÛPÀS?ZG�W«m0„*Õ¿á%C Wª#"·áa*¶A,ä7!BÔúCFŸêà?‘G¤i9મº}‚ºó¬­„ ¤ÿç-?õGǹõÌh")Èoz;îàü‚ÍË¡ÀÌìÉ�½�÷Üúüûäõì „×i!?­.ÚMâc‰‰ 'ÔlÀ]ãuû·ë>¹Ê·}Ûw1 8G0³Â ,F,Á¤N×6ƒ\‡˜’ ŒˆàK<1ºö Ú˜œ¡ïN _>NÝî‰Þª§ÿKë|íz›ïi­%ºó›È�ʈÇñ‘X»±Yv—ËòoÚüìnøEOIßDV)‹>ZÜm+±Z«4sg:’Š}Ü™\Ð#y‰‰sIÍCÝ*GàbáÖ#‚:hârVìiýÃ_mè}wÞÎë~²´­O{:ý»+ÜÙœÉj—A“*/(ñðä×cêÑoý #Ô|˜÷T<ÂCö9 à¬j×ÔѸê’ƒÈ0Q°(¸!+C=®Q‰½ÓÒÛ¶xf„‹ràʲã?üåìÿöüì&eæ™m�æâ�ü»n´p«‰aâf�i™Þe-,ðµùƒó_ýµ¿�ýÝûjö 9ɤÁKÌ7E„ä?ýOØ¿õS /“Oð‰o òrÒ¾a«á³8¹’T®Û.´9‡³p‡©1”3IÂVRÛ�„ç#!8gë-»·3X6ÖÌÉYÆÜIîr‹”ႜ¡NÖ¶s<-¸ÐyùÕ»Ðc§ ü:¼ó(²m/nÓ öº3ØAPA&�>ì8ðIEÙÅšþ9àUïcšÍ´ìPUÀ\†ì=„ÌTý�ý)“dîp‘.xxCÌ€Ûvh£ôûPLâEHY&–Ói7rvûe~5ð{p¿T:¯"ë˜_‹ù›¢Æß§]GŒRÓÑ&ü¸6‡TZÝØ�%²a5w~c¿?­A¤ƒŠ‡xO�r‚¸¹Ö ݸg±Â.Nôk|ðs‹\¹¼—/~Qb]çë¨Kª òô}GéúÇ‘éß‡Ž˜è?|sà sáòÖ©¡‚`JÔÈ#-‰Lð¶ñ‚!Á•>ÙÙ¡|^‚&²xŠ«Îö£­÷Êl ÿ)[Èôõ¯ÏÃjkÍ�üÖþ_¦8s²›â“ºÅkñÄ`‡-ò4›äj…+"ô: lRc dš(Gˆð`¸>œ‰ˆ9 .1•Ñ1œí¦nä‚âÌ<ˆ Å)ƒ„‚7Ó>†ÜO!' Ü?;ßÇ•zW[ᦰzk§¿ÆÄÕ9 Wû�täÀÁƒvˆî{mNf* #-f²[tX†Yf@&BÕà§v1ú沌CÙŒÁ p´b{2€9iqÈæå"óÓp?v/9Z:O29aÅ?.ÍØèž«¤iœm¬0†WÍ"«(Ѷ»ý“}‡n=Äx”Ô ­áìîµW=åžóü1¿zÿ‹xß—¦šËqÒ+üÓ8òé@Û’¼ª6úÃ//´{2UÖ?éüŇ˜›oÇ\´qx¹�6”ÖÒ‹Ô(RuI‰yEmÀÖuüM†Ör�³Ö±Ös¯ãmOÿ‹Ûv£Xë 3£Íæ‘‚üCzÒЪ ,Ca"wJï>î9»¯¼óE Y¦óì•¥7¿÷á¨ëfûo÷´P¶Q²ÄúÜQ–²Œ{3²ÏfdÀŒZrÅŸSëì`Ê%¶¹lø]þ »Béva²“�»ÇKm+±M#ÖD¬* ñ•(„š‹@"  G3p¶•˜ë­Øù}iD˜¸n� -ž º|ìŒM{à—¿Ì9¥yzaâs'è|á é›—q«Ë´´ ­mÀ>aäèÍÈ ó™ÉQŒ 5LÈæ˜µŒ-Ë€Cd;šÑÊÕE«Úc²Ëðþ±³Åd³QÏeWt.:½Òðo#?ðTÜ¿N)Ç:˜v¶ÅÝ»T‚Õ$*­÷�°ðŸê¬ŒìÉaQ¨Ü€"U'ž®/ì옻1&Ôª=vùЦqýÕ§¿ëð*û;`0SµU�¼ÀGä+þ`ÓÌ*{²£À,þˆ!-G„½Ÿ{Åë=ʧìôÌ·Üá‡Ȱ¶–ÈÒ¼�›¡3=„3sG!ãæê–Þ‚ýÙÏß¶DÒ=ÏDï lFâIên¥{*5w•%ìDòk(u®"u "Áˆ\¨þ ñ8ë[Uâ˜ð"“ˆíyý¡D�ËEΛÇѳ¤×–”U~�ew ô$�ûØÊÙÆ :;¯¥ï÷ÑŸú—”r�ø™´f7K¶ðIÍ64™²9áf*Ÿ9¤êÿ?d�õ"vDRk{ÛÝË垤~�ü¥7à~ÝœŽå‚[:Øm>å¿…Â…hD=ðÄ‹è7*ê*ýuË!Da·qúõÉÇ1ί00šRëÅg»ÏÞºÄ O3‚ƒ\"u3çcP¯hùAýð¸*U'úà(~d?VZ‘ Ñ€P£­Åùö"ð‚­­ ²bØiÒ¿^ÛY¼éçþÈVì  9«³Ò9“éÙ£òëœ ¡ñ¢ `v7/(6˜Ch÷|)庇Áø"½¬ÙJä¦ X6ƒ1—ÉüÞY¡33C $2X8b,ì³²BÌJZ9WÍ.½yÂËëöóÅw¶°¥?Ap|� ÛY‹÷0e»‰e‡ö£ëñ~›vRØbÆH´NbéÅ€0¬1RŒ‘)3v£¦D‹£$(……|“ËssçX¶sK>‹W¹ç¿îáBôŽìDØÁ"Æ9Y›óä\O™‘q37»OòIÝ»7“™ùL˜}lQT on»{|Ã~»­/½ùMçt¼gXW#í‡�¬{ʦSÙ(ÐÙ$Å ”\dU±t“Ó�GmvÆÖ Äbî;“ 4ÅÌ!Ä= ðÏÜôÕ•Ý+G?|?vôK¼üuÏá3w^Ï—¿‘÷©¨W½S¶Y¹T�sˆþ~¹=y¬¨©K ,E\Aºï£›œ„ZaÙLOÃGOÑü…·½ô½�Û®7k0?”_,—�’;�ä’÷óY>È­¯Îò'¼<º“›ë�-;Do#‡æ@@3°ì°DÙ�à ²ç‡‡ã®Q!s^äÒDÙE:ÛË¢X›áR/¤ØÆ�-©ä [Œ˜ÁZ-\ë�Ø'÷a­CØ ¸7_‹»•ýFg"ç“ ÷gÙoÜ7»�Ü%îïø;‡µâ{ŽM7ˆlK|ÛÚNße;�d—k—טc�5â]Ôüõ˜4HˆLˆ$ª ‚…V]£F6�óÓóLs¨¢>Â(p´ xº¤œ"å_’s¿�dg޳”>@¯y’m›Ža/YEZá±�ŽoØoµ/»�è7#gc¹b]�NîP°ð®�†J?w�ÎߟЈ_:ìTD¿ЋpbN‰‚uˆ}›gI¥ŒÎ<Ð]Ó~ŠsOåD´?¶›»¿’LµSסðÁ)xUIqÎ!V ªÃc‚Ì¡ÍÜ“Ç*Ʊm]V~¨¦¡Ö3‘eÌN ŽöÚßvtµ=Ϭܸÿ°ÁE e"³p&6,\¹~ßÈï"—mü÷öAÞ ~ˆƒr�7Ø{ôÕd™Ê°ó<4»ì³ƒx8XýòÞ÷>, „€e:ý* ~K±Ùƒ¦Pä!ïõËžZ­Êi ãp¸ýÒg¬>»~Ë X«%v_õJô"5néø©EÔÒUžr®µš=…Wj�kØV[E¹aÜR"'¦ªB°@jF„0)=¦ öâ ­*ÌâB™*z�;>Ðáw&êé=RrŸ49VÖ¢Eúéi6GkhX£Ÿ¯¾ùów½Ÿha{·é&öë¬ÍÂBKØŽ#Çfþ}ûÛqÚ�’L%[pd”ùLlC>}0_'þ5—¿øêÿk,ýfXElݸ­Ž}d-ö¾ôXšÇ¨YŒ‹}É ˆ:Kq¢#IÙÇ�P&¸¤¬P½B¢1Vó"ƒ ŠÃ…çú”úÐ5TQZ‰ÆD¡ß´¨Ùsë=JÙFí¾¥Wnû?ñjÇdxŽ~âSû&Þ{¯t »–O}%?è\LÙPuFðXØÐžø'Ù�¶ó' –'H- âÑUì7¥ƒÐ$–c]ï^œ iᦧ‰>sb,üwÿóŸ[Ç>$Ì�™Ћyc!ÀÂÜ1È߯»y ¯çÌò·¼ß=›_´ûøÏá'û?ÿ '£:ï1@�l(ÃÍÚÙ( |3›Ü­o¾^ÇXM™Š›|nWjÛvةƕh´‡Ôm± ¿ oT@ï†n‹X‰Z˜bB"‘6 ¶áÙÄë}…0ÈÉ­G�5âøì­7Ù nb™ØNÞ2öÂãñj87þuάÃ~’þuÇ~ÜZäÖšÙ¦ö·$›Ï„£ø³ÃYúKO¹Û_ÿ¾ µ?Œ^¡ëϹiÕÍLPN®EÈš�Bîp.|ø‚§ßwÃ#]ç ¡ˆµîÜ*8•"V‰G$&�Ïum—ºãÌ�¨çhD$ž AªhÚ ™ç¾x}Ÿàb\?…�ö¬Þ'Œ9¢{—ný2?=Ø3Þ�ºöÍpÃóntS¥?ª�Ùøú1¹ªØ3DHRï¥Í5)^h¦õÜÎΣŸq׆×øÝœÏnœS É0²CŒ´è¾ç ·Ù7Yàf¸›Ãv¯´�ñ[?Ø›äoaTÄ IDATÅœ…Í·p3@‹·‚έYû׿²v'²Œ¯™Gî˜!î¢3GC}ú«L–“~+W V¹sWÛXt O§ô››˜hh@†!‚G¨tz¬9üÚ*NŸ*½JžG« Õ¡è&teŒ6ÿë÷§9yŽ…N|ßÂßGÇâg…SÑôÂù_‚œ»¯o¿t cObÛñ³j„z +ÞÑ#ú&µâè›Cb�ÅÄi"‘bŽ� bE·ÿ·G?Á›~RHwÝÀùDðèhŒ *õÃ"LI*åºÆy‹oJñ›<�¶‰�Ãî›B_û¶�>i%`8º¤+:*Éx@þã¼——ñ6}-?çùãÊéÿ�å-ƒaàeKí¥ß+â|‘ªï½’Ä3“ ZÀ>†µ‡ö -¸}¦¥´®íÃLŸÖÌ9˜ûÊó8íVfnÕ;æ‰ï9OÚ4ƺŸŸØÃ…0ERnC‹«Å¸Úšv¥Ä\kÆNœK ‘Eˆ‹Ì™ *¦"ô�°Š’„FcלãŠÿýÜt}ùwàÿí-¸F�¡L©0[‡~2 ¯ûÎäí©3¬n9ÎʶӬo¹�åñ9$Ÿ€X•ñ ?ê­{<Ú°#¾j;RH@ê^®ªc�ªd9BŠ šâ졎\4ƺ±O\ŸA]Ý…þó¦6q÷ÊX±nëÄ<‹��hP|z çó\W]Øà¡ÿ^Ùh—â™:ˆªJjõUï^à[;ç [Aã1û笾›¥%›5\‹Ì°Cb2dMý£òàå³m¼žÏñ§?èƒrQÆö2Ô¿¼GÓ.{ìâÚ±K‘>dÃèÿP†¾€d&ì›fÉöÁÞ½H ôÖd-l^¬ �u˜]‚#Û`­9dïÜÑ1³¤µ)Ý޳GŒkl3;¥Ï5%red¶IaÂ8B²sý?ÞAúü»°žÂK?Mô_^Fom3I¯F³L+ª  äìVÄ]GpŽ2R¼Ö©§ŸvY‰×Xž^fmË*ÝÆ9V§–É'—èM§·å Å–Îuꮤ°Uº¡ßP)Sd�"µ‹<&%&«iÕ^•à$wj¡†³¸ba3�ÕJ¶ï9�¹¡èÊå6p—¨VdZêª"¯ä²§šbê�ˉ}ìŸXíý„Úl7ÆB+ÀO�ºXã ¿­Ò�؃ÖAƈ]NðÞiäT|ŒHì%DÞ-už–~ªÿ¦ÙUö\±ƒ»î±þ^k3N6³t4©¯ýqVÇÖ%íè(]ÿƒæ€+’ƒ^ŒŒN5mæƒøE‚mÉQ–ÁÖˆÎág^ÛáNn›ˆ²ê!ÌÄlÎDÀª £ÓŸGäÑÍÜÀþ†û8þŸæ¼¨TÿmÐcÿ�޶z¼ºž}ëƒÙ¥çëc�=x�€…ƒ—.\lT|ý´�{�…ŒÌí�Ïä�³7Ë‘ÅúntúTÉøÏ|”üŸð‡Ï=Ƕ\EÖp\u:,¿û�øæÝ»ÙòÀVöt¦ˆ»u¸0F8?‰\˜Æ]˜Bó&q¨Q/K¬ Œ÷„ín3¬mCî�0‰±x@N gF/ñt›ƒn7éw»“XÛ|’åÍw³rÕýô®þZº %ë9oê 3¦NS\¼¦~ܧâs4\‚“�ͤÄc *ÝÎJ5+ƒ˜”H&µ”ê ZM: ЉÆxüÅÿ&NÊX¥zÒ¥9ô:ìë~R8¨€SdÃ3Ì!5-Å¢ û‰ 4ôëÚt}çœ:¯Ãæ�ºÄõÍOó ¯]ãé;Uº¬ØŽëyáîi÷É“1+`àÖI;„GéÙã6S4Üœ¸Ë„kš…3�t¬=àÆ¿¹ÄÉš`gMND[Ã_s~þ 0cìŸÕ ³ ±‹QÒ0 :š÷G ä_Æs=/á}¼f4$OLË,ƒ¹Ììp&rd>?Ålþ™ÿ�«¯XŒßZǶæ¬]u3嵈sϼ3=ͽÅJÙät·N³]'éŽÑì�1Qns‡ã®O{yŠôÞk˜<¹•úém4Nlcjuš‰2Åu¡¨Q Íà�AŠušÕç‰vì¼ü8%Ž2ŽŠ¢6(òf›•ñs\Øt†åmgéLcu¼Mq®,üXe©[êÞÔ™½iZ�ÿ¦‰j¸Øy‘Ò[¯¨©U’ÖˆC,F$Â%ÁSó˜wP€õT--.Û¥†Ï�€×ÍØD?]î2H@âM¤õ•¦ÏQÖhNîáËŸ l~yÛÆwlçÈÙÝ|ýÜèN™TÙL 2TŸˆ„Të½ÂÝaÛ<"Dí”q¢Fô/×ßé¿(3ïh9˜QÕ>Ö El Ÿâ÷ù4 É4‚CæEX²£³ö£ÿWnYåý1þy%BÇDWÖeYP(%‰Ÿ´iO´­}EL¤ž ˆ1¼Uªz)ä/>B;ö‘Eˆt&}í®�<½½‰‰3›ˆÏO-O¯ŒaÝ&�õ1üZ“Z»Iº6NÒ§¡ ãe@Ò™à곓OG%Æ$B] _ﱞæ´ëë¬6:´ëÚݲLwò,�ÉS¬o_¤˜øZÜ®SPJ¯ÃqI41ˆÃU�¢Î¤H0Ð' Šh †W\Nx.*11äzwOž øR¥„þ±9ëÄ~|èöD]ŠzOʽ>þÊÙ(ùJuOh�êE|è¯.£½ydÃe1‘ˆÆ‰©õ ö—èVAä‚S9«r&4ìç¿�ÿÆç2ö ­YlvHH2TîÙcòa�ùÑP<±mn˜ôš“L_Å»67¸ðu)n˜°"†�X½ÁÇ_øl�½B)!2\ ’3¼†™¸`YìÒÈ;‹qÁÄ‹FD.§Q—üÙ÷óÕÞI"±:’~B­ŒH& ’œÕn‚vƉ/L‘¶ÇI–'H¿ôž½Ö$½0�[œF–'qE{#êÅŒ­×ØÁx±Ç 3KÔ ˆÐ¯ƒ4ø^Rø|l…Õ‰3œŸ:ÅòæÓtvÜÁr°´�Ö ÕÔ�r(¼¦X©U?8Kžç_~.ÿd+wA½úéáª#WS¯ÓEì ¼vŠÔîçÇ®NhçW·�­Çë²—»;]Nýå8ÇÏñw&h3²'i$¯¹Óà”8"]Èó·ÓXs&gÕ­®¢o¬åóŸÏæ‘ìè¬e™Ù\•˜wÖ�0ÍÇäGöÄ·C’‘e™¾âŠlký\òÇ)_80lçÌdm¯çï5öëxÁ#ZÕÊ‚· uÈ(D ®Œ.Ô:¬Ž/s¡Þfmr‘ÕMKt¦×ÈÇÏÓk,ÑO×|Y;Ç 6À’¢rXIuðd[ööíÕA÷¸8õîDÑ ŸæW_ÓáÏPJ{&ÿõÃ/óïýZ\?_솕vŒ«yÄ�ÍÆ<*±~GòJ‚‰"‰áVn_» ²nÂu«ç?ó&²Ãܶe7Þ23,±9 S™MñäGöív?G ±YÓ�2ËyÕéè}¯e|ó¹ø}S”ÀГ°v]ÌC  ˜Ž ®ªvÔ U$ëÔ0S«ŠÒ‘€×@!6B@ã�ZÅ5iV5iy§Ä’c8 ! Â8FT‘þ»€Ù5ç8ºÄð)n#áLH›ëäã¡!Ž4R ¯ùå�Ô¿¼›wmcÏ`šZ{šhqi7‘•qty¿^ÇÊ4&öF­3ÝÞÂÕn ˆD Ï€nZ°ÞPµkÍœ||™Õú«[N°¶åÝ+ï¡[»Çuóš2–¯{B Ipñ Š™:«»P+$ò–ZO„J‚Å �š5âBÑtàŒ†Fm“y‚º’¬®Núcê¢)8u°€âcH—–ÎúN-)ÀuÿH<þ`Ó‹ß•¤ïÑnƒÏZž¾[ˆƒÄÞáSu6Mmqqgñu~êÇûì†w Ú±ul‹/ ±ôc/Úwjõ‘âðš©Jˆ�\¢ªÑaG¸µÀ³<µ‹Ò;�+zQ¸åM¿™¶ äC·„Ì*¹3ÙP$3©:’F6ù‘}+Ê›µDKÄ#[ä á÷ÿüÖæ³Ž'—¯ ¬šCÐî>ã e­/¤âÔ1C .‹Ÿ Ã_Š.ë…÷—{îAýÖ6úP!Z< ă‹W €œÈ=€ù˜'’þ�“ù}Ïç´EÔ{5ÒÞ&¦ºŽ¤TdSÁR-gm=‚»¯dìþÝ4Îî`âøn¦–'ØÜ¯ãòÍkÐK¤L”ÉPae c;fÏDq¨sB\êúä ç§:ôç9?v/ç¶ž£7±Î i3h¬«Ÿè:yyI‰Õ•+ëÞÕJÔ©CsÚx¿•F\–Ý0æ±çÚ5Hs,Fiv�ö�Z!DŠ3D<–üÿì½y”]éYÞû{¿oï}¦š4­nõH7’çnãábÜ}Áƒ érñ%$±!¶o ŒI®©]�¸¹Îà,|í`c—XY±a1´LÀ îvÛRÛÝjµ¤ÖX¥ϸ÷þ¾÷½ìSR·�‰›Á«‡ó¬¥µªJuJª³÷þžw|�h1&jWû½›Ç‰Ö¶Ú¹ƒlµàB–¥ ž2H,Àb©*KÉ0 S/áÃÇaã±Gõ«¾uŠ¥p;�Ö;¤P,i‘4º‰Å²ü²ë'íÚg¼Õåùàëç;SGD5õ$Cå¸Û+œ+€5sê~èe¯å7˜Ÿ‡|r”üúÜüµÍ$™\á ÉOðEN?1@ï=FÂÂB$ÏùãÛóiŠwMaoê%ÁUÁ£Äá�ð§‰c­´k[Dì>; R¸ lë1ŠÆ`‘ìJk¹¤Ôèƒ$µ+ Á#_±Äzãc~׌é§wrë•}ÌlÎÑÚè�]�Aצ�a“r½ÅêJ‡dcšV¯CccšFÙ"�u´1µÒaÿRÇ)ûÕx…ˆ8Ó¤¢ÌFôýˆÍ†2ln°6»¡ÝõÿÌ £‡pWnbz‡Ç¥gus®ïuoB¦¡P°²…cX©/ ¤ˆ&86¢W�æApMëá7§)¢¦gIÄ¿Á_OQÑÈ,MÀ«C²‘Ú6w¥Ÿ9\žøœÇŸ¸�Ëgº�]"ÁÅ2_!˜é—n03Ás*õüJV¡8O20¾“»&=¢��Q™†xñkùÀù�XPòXÜ–q!”m§.+] "˜j(NNêç² ŒœÙÈK=é†r—!w*¸Âe¥Z'ËúÂwí·£‰ÀqñP}ÊÍ™ü„ä'xZ‘5ÇåÐÑ£þÞ?J~¢ÉèHÓ¾Xu‹úO6}¼�ú˜”… "‘HÜR¦ÒZ=ò™ý;" ¼˜E‹`±j¬žáëÉqDðˆÄÐЂB3Áy�¢öĽ60X�ŸE*_ÿ½Åh˜XñÁXœîûîNÊõ ‘4%é6@|P|³Çh{l;GâK‚)ãæ¶à¿¿Ç�?Ün7ß|ZÃ)�i¿�Þ¶ÄZ2D³º™¦ ™fÎ_¾íÊmîä…uÔ&*••i Ìúl¼à·ùèܺn "a»¦>Rá¢Å"LtŠi�3Ü�µ ×rئU¶Ú1jlkR#B– \;Å—†ª6­h�œ3)\˜<„Ï#Œ¼™�^œD–îVƒ»‘Ž%‰ñª¹ùŒòÿ~kþFƒ7’Û<ˆ(˜Ôò�“î΄ä'ø¢¸×HŽ/˜ráè‚åä\|Pü‹i¼†ÆOÌR¼½Lð£àØ+n‚OÎúx¾43TâxwÊ?‰"žéká†Ù“Gûœ]/cŒ§¯ý6õaA b†…z¶ž40èÆ’0î)†:†,ðTË\o %¡SŽ‹ cô(u��áv¬Ú‚dk¬ßø›üž›a:ìdÛ°Ãléh6Wˆ:E"æC*�2šµTÎí¼âªÀÞÎ*1:ˆÎˆŽ¬td>vœ§¿éÐNå\1d ñ…ìþ­7ñÆN�nk�5†ô¶5Î±Ú¹Ìæ¾%úÙf6¨âlBâø•~R̹àU´fнíusF´ƒœ:ÿMüÐï×·-I¼„ûg�»PtGYÌš¥�e­úD¥Ä—ˆsHA0’ÚÀV�9LkJDuàb}w\‚Ó q%Ƹ²"8�ôõŸ�(}­Z×P‘Ê×*Ò*Xh“6»>n˜Þ°E1ÙpÈeÕQaÓ?ñ¼÷ÿ7¼õ½:¶ít5Áˆ‘OZ;’Ÿà/Äq±hGÄ-ŒMnäþ{݇ï9ïöpúGç(ßð>aÝ…òVå“Û… ¥¡¦Î¢SQ�ÈÄ¡ù¯HJÔ‘y±Ê¬´ªÙc=°‘>žœ«#Ф¸x-ûvŒ\e�€í¾äÊ—œÐ“W¹-$dEF£j�U ’tD‘VŸzÍfR’?ÝÁßcºÛHf»;Â>dÙ!rÝw’nýu>nÓ_…YC7Âøó/c·oé�ñšudg¡…w7¶6³»†Çÿ AºïŸzx3C|£LÓ€M¢u ³d~àj NFhÄ™–˜¡Ä&Î¥øuÒ� #k4Ëċʨ"�؉ƒ€5ëÞŠ j6öºÿŸz|9ÑûŽVά·ô2u2Ûµ¸J<¨ð’(&›æl-Wà?ÌæÝÇ¥÷FlÑÁQ5±‰SÑ„ä'xZ¸¿¸ŒåÇMO½#{Ûq·~pÿƒKÖ]”�RÔ䓞( ‹ã¾µƒ± íämü› úºŠ fR8MuÖ.TD4Á* uoLZï *2ýèðÄ죜°”¤j’Å6Í*¥©¯¯`µ$-Š%Cdß%*m†d� ƒ´¾Î#GÜ÷Îõ”Ør�¨‰‘lˆ®»-øO~_]M3{õOY½•»Ò’Gz¿ôÏ‹›¹™×„Ç>Ö¿£Çæ#�°kö2£F—ªPÄO—nºƒšš¹j¤Zá,ñ(5+Q•Ì•n“%±&Š5q.&AR�¨P)Z§ JöÌ/&=ï Ññù‘áÅ�Œ|´ALö^l†ß»‚Åeü¿ÿ�›Ãü±²ÈŽÖ~Ûµ�ÜDÅnBò|©°ûŽš;G ‹áG_üÇÛ�w 1ë‘J�*Üè81£z†èPÔG ‚ÖÖ�“wñ¯1Ái(Õj™WQUT±PD|"êµ!µb@Iæp¦XŸ*&½¤²ºsP5`è�n^ûÙÔyFí'`Y…>ÍùuÇÇœ£5JiÏTéi„i¦¶�&Ñ#Þ§•++©†©¢)Ó£G^ÕúŒû¡ƒïä%Zî×€»fŽ6¯à êJ ¤(Z%•ß`¥Ù¥ÛìÑ›Z¥ßZ/û³+Œ:W%WèÏ\d´c…臙Ž@+0ï�� ­!AFNi–™�¨%7‹zÅ1üV'á—•€Çá0b¦Bž€½Ü”´¶AÊUªöîó|Àjƒ…Ìd±‰èñ„ä'xZX´E�Ãöè;òtóÝ|óvGŽXÖ5aUªp³¦'¦}õ¨gžÊqm$Û!õ´Ö$gúk‡ÆÚRÛ�'ÎÅ!¦XƒTP³_ùÂ$Ö[ ÃH4ŦPçAFN­VºUgדÛpM{^ÀLk1¿ÂÚ¶åÆš'‘>}ͦH¥Cb Y\¢¿“F²L¨ ƒwi§Hº±÷»œgéò£'�!,ïË^ò v˽L/µ(³4 °¶§Õ7kr°·±}ç4šCÄP:¥ŸEZQ$ewv‰Í©UsŸfiöƒ™'ê&U´<^%® R¢ÁA¯ƒ÷Q�Ñ$Û{Æ%ó[· WQeWßÜ=HÌúæxB4–þæ­T?ø›æ£a^òz vÞêq™Éý„ä'øbOXîLr‹>’#’cvô}÷88¡›ïæ›w ?gêZ›NÙ0Ó½&�l£zd¦†y©Í�ÔƒÙ$‹ÿ›‚3Ì‘8ÑPg18#Q)ÒÊÅŠ¨sš¥xsPÌ4AQ Ne�BV1vÅsŠŽ�sήÍ޵b­5,©FD ñ=‚ë„é¢lte4ÕOf+¤‹I%i¿›ýªÚÿ\_áUi)¥ÝdŸ•ï­~½¼ûç 1ãôŽK<1tpîV¦ÎÍ Ëû˜ºx€™+3̬ïЙaë5¡ß"¤LÇŒiuX™@Ø+»‘DˆÉÿJ”5£rƒf—Ít@·}…ÕæUú3鵯0h¯SN­RÍ^¡ÜÑíàÉdD©=*vJÇø÷T –8FuèÓÖ–KɤË(BAÕÂY‚x®�gf U@ÓM5“ 5usˆ6�­÷Z+4–¨%ˆKqI…IÀÆ£™hK½¤ÂL¯ùðœÒóÄGlk(AB — ]ªì˜¥G³>° Ö·äwïúûƒ7þY±¸( óˆájãÊcÞ¤ÞÝ™œ’Ÿàó�“Ã1œ "÷>b~ÿ´=ê¿ÑGÿ%¶û`›*º9 öÙ‘«uïÆÚÒ“ü—ç�T3TÆ:ñcéO†DÏuá¡X]/_ ¡^äSÌuÿÔòÀ|p­d-õ,ŸUªºç]×פú”Ú+(ÚµaFîò\á _m”Üjòv~±ûþ¬-—¸\çªHl²ýS²ñÀ°um�t;Ì®ìgßJ‡tsšfwŠt³ƒzª*cõjÎï¢yeí^‡t8G…$�Sƒ†ì¡iÚØ��uBÄ(}ÉP”‘‹ “Q� úÃÙ%6çβÞ9ÅÚþÏÒÛóD³â,0Š &Ö¹õÖÐWÙPÒXŸ85ìX“DÀ1"èˆÒ<&êJ«€Â•†«‰ß+Xß©'‘ˆ˜ÉPñªbC4à:µ´�o9ueŸnÌTÊXH깕SøÚ¡jkÞêhÉJ§–jºgMôUÎbÖCX3lû��»Âß;ü~Öx?Àj2®õàåhœ´X&$?ÁÁ¼˜ ö¾$‹,ˆÉýâN|ߘÆäýQ¶¡‰mˆÚ^s�í}¸‚Eg ÄçlÒÇ|¾¡åñÃ�Ñ’v‚/=@!�¯ÞsŠïÿº’ïT)Ü>û\õ}¼ÿ‘×ð‡3.­(ËbbIí8"õ9ïÅ0#Ä8»ÉêÜ*+7e8|âHÊ„d”�f0Ô‚"U‚TýY²K˜=y ·ž;@ki›¹ÍÚ�Åb†z¤/$ÔY𲓠¡í`G´«7¢òRJKâبh L-Q„ÏÐ\¼Ø%™{‚ng“b{�Ý~•u í bZ&4IÅ“‰Sèg%ÒÀe6ªµãÔeZë ×6H¥‰)ï i6pE…öB•šñïêjÁØÁé¹Q…$ba¬l”ª—M%z@÷lJõJ�là�eE¯ÐüíÙ¯ýÃûþÁ‘eޱI¶>!ù ž~bXgô’ÇùûÅÉϳO¾ûèßnFÞgv–°N´]޳»£}¦p5Á àqbªf2áøçŠH„Iq¾šÆ‡¾žâu7�àM«r‡¦QÏ;€÷Êfg•ªÈ�l†fRs]¥Ó&‰d87ÒD{ŠV¨y§Òr¸–ÕúܘwãÖ’�µ¢—n½³Á½Â©6+1Y1Ï á÷ú;xó·^å²å†Ì× ÁÚuc’ÍOH~‚§—Ì/`¿~áÛùàg£Xt¡á<%–˜“ˆ ˈDø¼$U0<ˆÃ¶VùäúŒ¹%šY4$ƒñ½ u�»n?¥ B” '˜Ô¨0-)1qq2×ìQÎõ¨GÄ­F‚ ¤Ì®zvWY”V©,³öµ—Õ”ÌotеK»Ø¿:Eóê,­•iÝ&²1‹�–7›TfIŸØFseŠÔ¦i—‚U‚z¦û©lc·¹ý†{ b| 6 Ö‘aZ2hn„õö:ëÓ«ôg.±qÛgXo�¢Û;†+R @“ÒY¨µÄgøà¡ÙOÔÓ�nÒ×J±DÖQï’ :žèOp©‚ÎF`’¨4n–*¤®Ö Š©ká³se-\d8I‘¤À|¨¿/(Z¸öÐÙoꃸ€X‚³Œ$é¶â0ë56K¹»‰›î%‘npv…ÆCK/~ËO}üÈ¥Çÿ¯£3�ÜÆeú8oÈ„ä'$?ÁŸ—® vìXî8–ËQ1K±KNj?xwcÐ8ÖÁöö€Uk`çïûTPbðŠ«Ý•ëÇêχ‡t}:ê¬B“B YÑ�V‘…‹ìm}œï{㈯Þo4ÉôŠ~7¿úÙ·ðã”%I¯MB #x­Ýk’”*ˆ<™ÞŸ’õ}~XKöÖ»Ñü9ãWOº+ë×êõ-“k[˜@-Ý+‘Ê®‘Õ“«æ% fÍ ÚoÊŒ@ýdýæ>ë7,$xMñÑ‘ i{H/ ,3WvhD…`�dæSû¹óÒ:K;�µiØì`ƒ&V$Ø Cz i7e× !‘6>N£vƒDœ(XHSqhèµ7X鬰6»Îæö%Ýœ¹ÈFó2½Î:Egƒà–C1³¡±œKi8%Cû�ŠÊ Jݪ¼%eíÌ À4‰ó!• ¬áúˆb�ÄÊ­ÖAéfZ/r¥ ’– ”Î*‚m­b&ÑX»Dsã3ÃD+\,¤×.J^ ¶m]¢õ#\€Çš;‡ßñ¶�sþmvX�c&Æu¹±.½È¤T?!ù ¾(Žž4cþ}>ÏÅdÞ$_ÈíäÜž ’÷MK±o`ŽQfÍ_º™ðP„R õÑ×'ã¤÷þ¼CIW[ ’RÑ~•Äf1{ŒÝ­Oð�ÿö€×í¡Íù»|è³ßÍ/?a�AÒìeA‰D)-:¼k�]ÝrŠÁñ,ô6ˆ3�’DÔÕ‡0Eˆ¢Јµ×ÕKsØËzV}ÅãœÐŒv™’U ­A‹Öj†+3I‡•+-Ü•9Ë3¤·ÑÜœej}Îf6;ÖX›"­T Âô Åþå1n¥^Â4 �!=§ ½é�v§6è6W†ë­Õawç9zÛÏÒÝýYúsÕEÔ*§”-\p¥H(m¤X³ªë&Å^Nj)•´õE à í�uåE¯i/”Šeª±—‚‹õ8eÖÂZ#s¯0Ø6¥kp‰Æ™©Šï|ÝN‘Ûx°n~òðMH~‚§Ä|ÉçÃkï«gAôkÿ5·oÇk^84XǬi²zS>QE�î¸ëîéò$W¶ ž'÷ ¬G‚¦ÁÑÂWÃ2¬qï¾_»‹Ä¹4œÕoã××ÞÌûÏ4êÈ öˆš�8�—и³ChV`ˆ>!µ=ü³®(äÙ"-‡ ÀÙHJõ@†sÃB3+|ŒØÔ›YWCC‚³ç+L"`Ä„Ä9¢DL‡ \œ&ûÌ Üty†]Å4�õ6®7Cz~'zy[Ÿe°ÑÆ•é¨AO#fì&u²4ãŒýª‚JŸPy£h‡ƒökS+¬Î]bm×iÖ¶�a³½F‘, �––jIJ,ԓಠ¤ò*TBb-ÔIDÇ÷ õ$‚*e¦‚äá­Ó5¾*ªíŠxé™p9ÛN‹ÿmíßò ;Š‘ƒ˜¹|A,—‰Tí„ä'ø’!×Ê™9Ë‹ØÉŸf�é/ÌQ½¨ë�u a¶¶ßäcê( ã#Ø©0‘¨}^?¦�HI%M+ßÎò†íŸã{¾F±¤–íÛøï½·ó‹Ÿj{D¢ÇˆdˆøfH)�25oS^11Ö"‚ÃɳqhÜĈ5»[å®w ¼Ç›š•Dðˆ‹Ñ,ˆÆ2[þÀ¸‘ bfÙõ¥`$Å9Á1™.f—guow»f½&ô3d�‘3¥q‰ëyqÌUÊ̽$ÅDˆ®bÔÐM׸Úé³¹}�ÍÎSë š½0j_¢?s†ÁÜÙd4GÇ7èQª€$)PIJ`kRÇ‹˜µ‘æºq�SÙ]ŠÉ‘K–.’êïýruìÇŽž4±ã~ëMšŸÇÍÏc“òü„ä'xZ9™ä²ëmù®8�_ÙExùºÀ†¢ ÒÍ[©þÈœ�|mÿ c©-®ZãÜMŸOð¤’Î…¬Ú¬ÊÕ*«Nò]w]äͯ)eÛlbË|?î­üç3�d½ˆ!1cìÞN 5«6#W`EM¬Î„A Í=uÊLlÜÓÇÅz À¢E!Áã„P)bbb¢.àkŸ�ú tHåÚ,€7'HdèJ�` H!õ“F@·÷}0£ÛÌFá k•Š E‚”-dG‰ÝôCyX†à‰>$çw°¹¶“é«ZkÓ4ûÓ4ÖDMÙìM‡îùí4/ï ½¼�æJ‹lØ@Ô!Aè” ³n;7®ìDÏÜ&ïœX´F$¦�^ ýF½¤¿ÑË6Øì,³¾íÖoüLØè\¡,Á2�TA4A0„¸ÏÓdݰ%d-6«#ßùïý÷5±c‡ÌdQउÙD�~Bòü|îMræ àÈ1qÛ÷>Þ¯Ë÷µ×øåi±WuMè›à°ÕT�Ž>ãÞäzÇtœÅ‹›TÏž»•žø"Ñ:¢sH¤”!~=)×ØÙøÿä }÷úƒ^›’ÙùømüÆéàÿ}$ÅH‚÷Ñœ7—E_Kà22A¤’ÚÍ µÄUõÀš$ALŸ¥×S?{² O¸þ 6~lâS_aÇã\7>^“°}ÊxI¬})yò�ËêIÀkúöõ—DÊ–8}ÃèX¤J¾ß¤•Db;02ÃPÌ<®J‘K»hþÉ]zü ;Ö¦ˆö�”mdÔ0·ÙŒq#AúSls ;,Át•„[À½¢'šmVÖkŒØ˜êêæöeVç•�?ÇÎÍ”Æ'<‘ž¹�M.Eµïxhôú?~Ç=7ºwÿ‡w8~&æùq=zŒä¡—",�þèaÁqD�,rø0rüµpü¾Z\a!Gòy¸Ü.°Å…ܘ?$,œ4Ëçí¸‰¿·�¨­1MX9~wü£(ó×.`}ìM*’V`ÁìÁĹ;×ųÅ#æÂiä¦BøÿÚÈ+†˜m"Rb+‡„SGo4~yt“µ¸ç\•ZW¹RѤ£i軪åT¤é'xûßêóõ7:m‘°Ê7ók¾Ÿ�jxsI̤ RÉÌ» Û*MËõQ\]FºÆŒu¾?QJü½¦ã0Ý)a¦ð†É8ʨ1 ™ÜrŽÁîÕòDï3ÌTJ¢)ÍÍŒÆF›¬× 6[\î;ì¾7Cki'­³{˜ZÞÆÌúÍÞ.¦xM,©¶�s‘.¾ç~øºMâùfÂÅe=ºeƒÁwñÖÒ~ï[ÒæGÎΞØè¦çóïÜv‘ÏÉúͯ[-9sܽ%¯­±�üØQáð ω#,ž<¬¶\¯Ô X.9–’Žê|äóÂÑyä¾ùÜÝ zŸ,ó ^8b°¨vuiþÚÄþ„Ü'$ÿ,Ê5r1™Ï£É!‘|éɯ<ºwãaÿÁ=f¯�lˆ‘˜­ßwÐQ?ünìÄ5Áó ‘ÊH‘jœšÊ�àP*u¶Î‹Z%_3çéxch/çÛoãC�6dÃ|Ì܈2& ^ËDmK±¦NŽê¹²Z¦ÞªÚ5O\Tl‰U­LÐgØ1òÁDSAÄãôú�!H41ð ÚÁ]ÚÇŽÇ·sKÙ¦Ñí�žßŽ[™Ã-Mck3Öÿ»ÿ�íßòÇ$18{Å'Tíï k;h#r+çíç *óºáP|5’¸Ö³]nxæWÓu2{â}o=…wç™ö�³ròBc×ÉÍâ ‹}™}}-X<Èsyð"rh %Ï �`q!7˜·ãó uOÎBž+äÌslì¨,äµ[­gñ“rBòÏš‡Z¨wäÈóyÞºW¶/_–÷ï ~MO kXiôî€�“X·ÚÚcq*"ÔJv<�²>‡Œ*ÒN‡ÞU PÙ2wdóc_Ûuûvˆ®Û+ùpÿŸñ ŸÞÆæ(³ÄU šá¤Ì̃(b:Þgw@Ä,CÖÐLÛøn«“ÆIöôe„—ºw]B¸R,$&jÁ®eù(¡.±˜DÔ�ƒ4EĿŋÖx½å±¸tð"kƒ&Y‘‘ª#-3:±A{û9:; \×Á# jWc 8suiÄÇÔJ"ÎÏØHf¡r¦7™ç¥¤‰jB,ô‰n=¹ð‘Kq™Kv[òx~@žÈ§u‰Y¹ÄOçË;%ߨ�Mî;^¼åø>YËOè"Çä$'íxŽ;þ†\NœÎõ¸c‹ G'ä>!ùgdœ;!¹ý£#yçübãC»)¿¡Bܪ˜‰Éðv³?Vd3©mAj(f“rýóªX•Fc˜x` áMw,ñ¯èsp¯×u^Èï/ÿ4zd»?ÝKb櫤Ä@%š‘ø� bb^"QA¤–‡”x.» ÀÈb &IÂÄÙèË÷‡/¨œ‰ip†DÄü8(‹cß×¶^o2¼FT¢7G­�!%afD•™¸4[)�¯ô¾�yDÓeÌ(ù••jæ°þ ¬ÄHÝmnZo¦äæèü6‚ bÄ«/^�EAŒh†™gs&º-àoÁ+$±ÎÁGK”àzW¶võª-É»Ž/ýRóøŠœùˆ.>æœN\b…ÍÅ;÷ÄÅ~ªœŸ‰,ް– H>!ü É?“žÜcÞäˆ b×>®cò$—<¾ö^²sÿ�wí§ø†¾ = •þa’?!©Ö}qÑK¬Ç„1_û›0ɱžËA`г*SïJ1÷ÐĤ‡]/ñSüð}K¼áe¥ßî|ܰ»ù½«?Å¿ùÄ,WµŠXð¥“à�$:hJ?X«¬úk�&HD-€#ÔzôŽ–‰#ÄI&ÿå âj\¼þž HJD⢚âpR»å †ßò|Œ2‰ÞG …RÑYW‰¡‘˜ÞåÑÛK‹¬¡zIL?d²ökWÜ黇›¿ýÆÓÄ<ǸW}|!þ@‚Û|Uli“}½2k7�Ù VùÛÄâ~ v[`/ é˜sÁi]”(1TŒhŠ· o;Ý€&Üf=�à1Œt,Zh² KçvÅïá¼ýðɳú“\HÖóK®Írj\�‚î÷J>œg¾;¨g ÄÄpp¯ÀqàˆƒÅÊ®ï'Ûu5Æ­·yA¨Õöåp¬ŽŸ¶ìô {Ҭʸ‚B-Ý+ùµï­q¤Däd’è8øá™»…0!ù¿òi}TÅro èGk¥Z;ÂÝ·/oî9ÞüwMFß5p¸®:b£;°3_­†€‚ɵҪ]{žñ“£÷¹}àW‰úFé°"‰H<.ThQÍð ¾ý%K¼î¥�ÄõxÇG?ÎÚ)ËêLð4œÆ²®ÿQ¥À—b帴µVvíÞ$3%jŽ ³ÉÜÝ—O&÷'gçàÚÄvùx�ÜŸúýÑÆvÀÅÌ�´ ‰8‹^ß^n71×Û4ÑÇÄÞó;Þ^ªÎ˃—~,>˜�3åãŽÎü[†À*pâú¿¹íQëWÈ® -ö¤»yX÷³b»\So’>7Ç72mpì%2%^A¤VS¬œ õž£ ކˆM!ì3C£C¨ÄуpÆ )­Wbƒþ¬--üY¾œË�_¡�®R„Œ’K—8ÉüƒSÛÿèfÛÁéx+GœØQ8µ7á¡ËÆ"1_ÀÈk#�#‘#á$‡m~¼í$ùÖ�Ÿ‹I^S=&Ø¢ G�y°ùú Ô$n&Çê•BãÚ�x†�¯NHþ¯\‚3De>‡…y^{¿x>šë�ŸÍ³¯¾Ì;;TßU9’uEGNË›•ç„åÒ0‡Ãܤ2õ¼Œ Q’¾·™ͤt.8 Å–Fûö´ä ·Vn¿O´Ç=|¬ü>>øð ÙçPp±´˜dË,æ Ȥ¹yÊ×Űˆ (QÌ*‹¸ÚLnN>KPËÜ:ǤY' ®îà Ö¸ÝSÜ©à7€K&Õè/¼S“ÿ2rá… AÂÓü7OÝa%Pæ,ôçá*œxx�EËÁ8†cé4«34Ã�hì“ n±)»Y¦¸#Œâ^“dÑfˆ6‡£c‰z‚suž\Z�kl:¡e`z•}¶$æñ¥Ã¬+K(ÈÜ�w_îžÉlùÌàÜ©Oëƒg›pÏ…ÑA®6œ�ÿgšnwž! ‹ ‹z8‡üÈòÅ:ã>rÙö#¸9tL‘#f` œÇØVFÂð‡ë€x�Û1OnU&$ÿœ<¬íh=%º0/äðÑûác¿•7vœwïL±bDß×#„;Ìj K©wde¼Ò4±‰}þ!KÕ7]‘�¤@¥ ±Š¶ÿ~òuWyá-^7í0+ÿOÞóÙCþäÕPJL2K/£,Š/ÿü% ùÂÏÅ“ˆàDP³ñ’6‚–%c“ Ú}RL±Ê‚"8!ÜšY¼säñƒ(\6«Kí¼âÝ4Õ¤ÃU6ž~ÿ’‘ç"óã·ù'‰ya9`j"P 92?Ïã"üáø6¸Wö=p|ºB_%ÁIh[F�¥~±Ç÷É™¼'V—wIÆÕÇ–á%Ÿ‘‚8%®ùö‚¯D?³6&w]}N˜\oåY‚ËÀ…  $]°‹sö¡¥­Ÿ[Û=´ÖÒn[’¥Ÿ �=`ýâŸ>�þ±ÙY×kî‡Æy’`Ð �ç˜Ùxç=χN,rÿI䣠ó¹ÙÈ å0'åÄ‘Ü�Ýžp©ïY¾4ÅãÛö0¬vÐngh·’É-´ã� 9€w{qÒkâH1Ԕĥ&ªê´ž[0q§8øqã=©-J2Ö,cÕVép…nò˜ á|sŠsn†3½S¬Ò¥ ¢â½»ÐãE9�°ˆåäb^NB]ѨËõ™€ù{€÷üÿzà7'™ü3 º¸ÔÎ�=ôA÷Ïwã~d$Á�Ì14â¾D?µ+ø³•«E"㤠:� âb!µ«Aª“¼ùî+|Ûk*n÷H—;ìÁÞ»ùÉö´/’•ˆ/!ˆF‚y_&>z‰ŸW’¿Nj×Uà¼sÀÜ<• ÎŒ*ñv¥ŒqbYülºeƉ™'aDÔ&.pc_é1ß»€èYìC?ÖàÝ!a¸ÝÝÝ$YFÂP£<Íþ±leªcy[×§·Fÿ¹&78?NëÀ ·…8q¹ïÐãäarLÌ„£v˜\çä2_‘Kµï T—>¹¶z"?f‹ùIc>7w»ÛÙíNýׇ[d£9–6öÑÞÀœû ªä&Ñj��’VÈ®h:CFFÀ×(F¬{¨E™ ¬�±©E%Éb¢NtPÙ°À4#f“«”þ<*ŽNs_8í¿‰åøïÓ+y;_›äÝ. Þr‘j?Äü<À:!ù§Åè[ŒOzL2îË#GO¸Yü¡YäG•à† =¬ºûävã\•Dpø‰6î…zjÕ‡Ö7ÛÏ9ÔSôh–âCD½&T¨Å–:_ Y£òO¯ØÑåë^VÉí‰XßöÛ ýg¼÷Ó·4.ʰ ”ZïNg #‚0«Óÿyb6õW·|âÕi�nK-N XÀ.XÜRU•É}÷ D• Y³Zz8ŤôõÕ x!pcy�:s…ÂeDOa¿öS$ï_¶#é¦P¥Fw¨±DÃX…÷K¿ä[Q Œ³ú­…Ëš¬Ç{D5Í˵`@žš‹‚-n�—@.9`ä&óóµÒ-¸g|´æ@>&z”9 À‘nÎâæ¼pvü¿’­[]ì6ç`ûú)öqÎïc#îg`7aÜdSþ ê÷ˆ+wáIMð8qX='M4¤Dd@bŠ7\† 3$áv¼!‰¥W1F]/Wiûóïk¸e³+|ª:EŸådŠ'Òpvø3lpê@äUç#»Ð#÷b‡�‹‘÷Ý ù%ì?åÈ…¿à½ß}'~é'ðÉÕ|¡~wóüZPa×¹é)Ì&$ÿ—:±¿°ÌuLŽ…Ëü\òJ÷‘·wÔ¿‰~Ó`Ã7Š}z'œ+¬N­¼b ÙÚƒ¾öó ûØçh‰µB3:RVE´Fp¾ÀHT²~C#Ñ®j|ûÍ›¼|:±¡ìædø§¼ç±—ðÉõ¡á]ÌÆwFEUoXŠEôKÓZK %(¨ ^âxªÞOZòÏXdRó2’hF}å#UpÖ’ÊwÊa�ùJአ§L~õçØ{ØBw ëiðð¤ŒüKÏ䟴]&O^ý“Ï?í‹ÿ ì©qE~-*ØRZøÂà£þ4ÖkîÒkØj ¨Ö¡ œ… 9 râX.‹·âö¬ÄìÊrô�’F5Åö0⶘ØW°ÇÝÀ†ÝLá÷˜0k1îÄÉvRRDj_ï £ÿrß0¡‰cƒðâL� O CÂPq·”¼òÊ”éãvañOåñÅo–sôÝ*»GW:c}ôüÉï—Ê GÿÌŒÜWær8q‚z.€ùza‘CÇ�#bºuͶ&$ÿWIì1‘ß‘|æOo[å_Ño˜XÓ�ðé]ðxa3‡Œ[ðÅxšÞ+dO Ñ‰)Ãs‰CЂjì1$¤â%0êÒêßà>«?ú²³¼þU ]·“ÇÊá�½F~ÿŒÔƒu%51Oî�ç×á"6"𦏤ª7qbT£¢Ú•F÷òà4ë¶Žã1“ßý‘]ñ?®­´ÊƒÉÐCU›Î>?fr™7Žæ–çØ¡CŒÈàè)zÀ 9�ãØo�ä¤ç8Kÿ?{ï'×qÖyŸª:§ûôÜg$�$[¾%N‚œ5IlÂ-$6�%„X^lv_^X^` I \v�È¢Y–$Ü—d Í5ú IDATÙdá…å ïî†d $œ«sqìÇñ]¶uI=š>Ý眪çý£N�$Û1ÖX’¥Q}?Ÿ±5=]=ÓÕuίž§žËÒMæö¯¦f˜ÑE»ÂV„mx{ �n‡°Ãtئ†M8?¥�,fÏ‹Ñq+©°HÈÇ"êü¢®Á´�Œ¬€SÏ#Òxúü+ ùâ—µ�þ´õ×`å•è ;E÷Ü@`wüÙu/Y2›,éU­+e Ñ%`·ÊZì¿$Kþ©Ùôã¼ûå÷¾¸GþúL†Ý�Š lvܾU¹§jýP6„6ø †@PoËI¨IÓ�{¿1 Yc #¼£¶«5þžú¥—ÝÃë®[áŠÃ1™åó£åÍ·\Ï­}ˆýÍ-H‰ ¹4ÂS>=O‹ì|¢A5’Õ±õm#m§-±ó‰1AÁb¥± 8lÞ0; \ã XE´¯èýØÿöç?³Ý—ý‡jíO#,ï÷åô¼¡_^¨º¶Ñÿ,� ÇgØK'ÜlUt÷.D¸¸ v­EèÒMKÂuKܪWâY:ZßôV®ÿàuðà[¯û{n^y@¸fE˜ú„å˜!g‘ŒtÌÅ Í*¹« ¬r6Ìã´º2…htô?Áu)‡ôrír©:qXUr‚â)ð1‡8fRû½ûóò›öæ¯à@g~ÏC2Áþ7Õ*‹ù>�|Ý0‰üSd*pÉ2Ú+QiÔhá¥8ˆV"*X„Ìk“Cé`؃ÒÂ0GW2p^ËLX B“fsÞ¬'ÈtUc_1Ð}aÖîå_QóŒÂ*2Ãú#üòç¿’ÝÆ¹¡k 5¡ÁgXA*¬Áê� O¨ˆ*ö„ƆmÔ§�çœÅ[ïñžy×i˜+}vMN]“ ‡A>¯æÓ9ÕüâMY³*e ë—ZÕ˲Ÿ Ô]°‰çÕcXd'Çëß¶�ªìQaOÀ&¹—XÚÕ>KÛîxªºt}ë_º‰];áÆw¢6ÃMw^ãÙ6uˆëoÚK·¯ð�\ÁßË×Sè'>þ Þ~ÉæÕ±Yî6ó½ûVwÔ9›ü½ú/|Ëìô,Kˆ7FbÚ‚Õ£aü±ú|j–0´Â°/  ]–îòCd{&‘?%‡gð!ã`‘%ýË‚N]k˜ÆØ �&v‹2GÑ#—ƒj¬*:%0%m®²0ªäVU3CÓ ¬Z•AÇ ôX°”�À°PJ#Ô^ñµA½]+{‹“‡Öj3ÛpðmÔ¾´ÿWQƒbl°kwýµ®Xm4͸LЉ��m+îŽ#9ÆùàÉqkÎOuȆ%u“!¦vÚØF¦É쪭˜é5ÝÏöâÊý¼ìR5«:¾~”·=üM|l¯ÁjBÀ·â,5Aå—ß)‰ûxÕJŒ·–HûÓns‰§•ÊÆ ;‹Hm•ÌCm¡É‘¼t&Є Ø<ðæZcê¢/°âÿˆ|êÝsõϼ«˜?Ê�å0–óšZö–\°{¸µÞôK'ß½gµëc.‚v쌣üN¸Z$æÅ·?;éåùÄÚ¿nb©?²àZ€5p xpŸiŸZð"¯ûå¿1'5„-¥ÑíæqšK†AÚ ü †kôIÀ‡.Vw0àUBù§È¶yþ`¥oï¼¹¼kÃ6ÓØg‘K7ÑÌ5ÈVƒÌØq…ĘCJCLXömG†ãÉ•� :kZWkÇǸ<ÐÆ¨6…0ì)«Ym†:ÈÑU„ÒZ*#M° T " ¶2ñboÛæBÐ*÷†öØà¤u¬ÐÆŽ[_BãNè—£mñ”€IÜòªM0thš2 Ä—jÈ1šj]ÍÊgG?tÉ�|óuÊÐ,„û›×ñ‡�¼”÷}.s#êF¼õ)�íB£ãE2ŒTøàdˆ¯Ú)ó�K%̬¨»Öš¦;ŽyôNi>õÞI~îýÇ8\[Vê‚’2Mæcú§õ�߀þÕ€�ÓÑ“ØÎ ³Å)wè1¶á¸Ïä²�LçÉÂvœé  "fª$òO‘ç�ö—–v¿oé�· 7ìAåûÌ{x¿ÙwÙ]ÅÞ~˜šÌ_>dÓ�a癹º+&YÝVa/5„m™ 05$t�`¬ Ñ7â†4ª22Q ‹Ì  9ÅêW¾ëmÈðuª¶Ì0ÐcdÖ¯Z¡vJmu,r�¸ºí ¤cûÜ´›`Bx™·X¬j ¢„ T^h¤éŽ‚páópË»çÃþÔN*Vr-çÕЬ(ý´ãÞhô§§Ùóãý[p-Ã]PÂ7™wîn¸‘gÞ…í¬ÜM·<ÈL¿gçl]_äGòÌÐílO"ÿTÙ%,íºAà5Âî«ìj^®»…Ý»j–è{AtIG¸íÆ‘ìùú·ææä5¯½1¿æÓÊÜü+‹«®¹²òºXˆî†ðì6÷, yC·ƒ)œŠ Ä´M‹¢ñªxÔôcËL…žÁÏ9õškL�ȼÁ"Þ¢#`4‰vºÐ�Ë ÌDÆh¥ø&@byìqDè8x«í’'àU+m‘Íôù?×H·G6ê»JMÍ�áêÙ;yõ++¾b.`ÈØ«ÿšß¹í[yßrQ¼JeƒéVÙpT5&Õ » ɽ‹•!UP‹HÆŒí5ajXÆêàŽ¿±ÍÞw¨Ø7M®ýâÅ ¡tYšÀ�hÉoíÓß…ÆÂé¢Kªm&6,ÉU²ëÆBÛ.w„jÍ'÷¬²ýÆe½¾þÊ'vßdéÀH“È?õ�x«t»uÏ;—Dô6Yb�.íÚ)ìºq­î¨Ä®MzÝîWÉæW¼“òûng°ÄáG¾ç;?Çá+þ€W]ëÌ0—4Ì}2gó „Í— — <;�Kf„KEí¥¶e4FEscƒˆ JÚÓר÷Ù™0aG„EP«¨õ„RgÈ0ÇŒ :´„c":Ì-C« Ô!hbóh4ð9™€A§M?«-ÈJÖ˜ÕÑ˶zž?í tÃ>¾“?|è_ó®‡9¡òX…F„B­©¿H©ÚÄÆD«"O­šcz5�zè®nL3Õè²Z »ûýEùúß-³‡ç§JÛ—‚¢�fBé´¼pCì6®%'ª»4�íAâ?±âÝÒk·]+H´$°KÂÒu"º;5¨yÊ,Ec—]ãLf]eIתC©®Õx•µ&ÄKÑM¾v«_B` vîn¸!Ä´�ÝÂÎۄͯ®; ì¾]¹m§\·çF¹é†Ì›>°§óu™û Wvé_¼èêmÚØ+¹¸†­Ç`±C3W`\�KPÒÄ>z¼eP‰ Å(d!z,¨A°¢jT¼CJGdÂ(Ê +<à �0 àK �AÕÇN{1ÒÏÎkëÑÉÔ 2ÄxtÜk;œ° B,ñÇ«o�ìñuüx�{×~¨k1¶O o‘Ž^eôò¿…‰þb²ÀùŸeØP\�ìÖþwLÝÃÿ}'3Ñïâ�–_ÍïÞÒ£ñ N½I®ˆøŽT†Tþt–™¯-ƒÆ‹SÀ��ñ:�_÷Ü`#6¨7¢ ñCÀ°^â'"ˆ±t‡�»ÖH3ïÕÈ÷`ù‹YÿÚÿ>âa€¢�å)È–Õѧ™.¥î?áG)À/^Ÿäóœá ÔlÛÆË~Hß;ÖEOŽ˜m³TÛ>Tñ?Ññ*¢è’i““Èo�BÛ …Ý×c_1EÞìÇm¿ƒÍ±½ØÚ«¸ôìk7aôè0#lé “ .D�oÛ)źæq‡bŒA1¨˜±Û>ê“Øá‘q·\ŸAU ƒ2ì #G8&–¡êºé¬Z¨G4Þ‹W«H¬™Ç2¿Q>ÕŒk»µ‘~ã’ißeXs‹@0QÔ­:—}ßéõm°`›7@e�Ž-y«"F]9àumƒp‚®íPOõ¶ um‚ÄÒH ±�ÝÂÓ�—]R+E8¾ƒ?¹óµüνEgd\ƒŒ‚W9cgïÒîè�Ä„hÉÜ6U¦+4äê4èrE$5¨9kX�K«"Æ<žZ«h-MV«<߉n)á° nîùŸýÃÁEŸë_1È8"žååTÞ ‘Dþ‚´ä•ö~­ xa7ê®Øzn�¥ÝKXÝ¼Š¿'„Ñ”PÌü}Í¡¢ž¿2–³F™¯Ì–zÅ\S2qy“O.˜j¶ç™ëvô`K»Å«nÏM˜é3Ñ�¡΢¼†6Ó·†ó¨ÁXÈ,æ2 WÁÔŠEB†i@!”ÕÕÌë0‹…ƒJ+:ãk�:–"‰ƒã"ö<¦B¤ŠŠ§¡íî'´7ÓGgŒENÑ'ß ^Z¯c0Æ"äHØ‘ßÆÿýµ+|ãAè…}|+rï÷ñ{wõ_Í¥C%õŒZ4kïM×NƒMÐ5_1"kÂ9jÉoÌ�xÜh�ù)!ÖÈ YPž7…nï+zبÙÌá¿7á orÓ·Rì×âî¢Î¨é§YL$‘¿P-yÚž¢ñî®"‚.©È®ñyÍ.Ô¿AÄ„"3e¿Ð¦.´žw¦ì–°¯¬4Z,†nÊ8ú×Yu´®§$C˜« M©‹+ž�õ”½(˜ž§œ˜°Õä¼°8Õ¸mó¶Ù:%lϳ-ƒY�^¹%8‹ƒ5C‚®¶BmÁˆøŽ�Ž("l2ŠZb\€UCîµî µE+‡¬PZÑÒCñÒÏÑJ!!¨A} 6Žð2.냱„¶µåc-úSR�¤©ñ#ƒ<ÂÕÓ‡yåvC!–‡y%ï^y zß c,ƃ:_³J'äTg܂֓¬{Ej°¦Æ�7ƒIàÏ"Þ€ñBÀ‡€Jf±Æ‹­°/èÒl]]Ű7pø„Ý¿ÛáãEéȨé%)>‘DþBµä׺ ¶fk{½„²Ôm(`pÑš­]h²¾¸©¾é½‡ŠPÒh�Õdd5k51Ýtß4%Zï/<żÙW¬Ðw+Þ9ŽÍ—“†Gúw•Y£e�)Óó7�érE¿º´sÏajëîÈ‚ ºµt[Nج°¹¶(:ÓUq]5YFQÐ( FâÁ@Pr5Ú1 60çTÄ©ªCèDcÝ[´²ªe ”¹0ÈU_: Ô5”q!¢uÎuCcÄxÑ€ 3f5\Öý¯½.°iÚq/å¦c¯ãmŸžåذƪ ^;Ú‘c2ò]3²ë)SûT6€‹#Ån£â3L¨š†ä®?+âQRŽ1C|9¦[cû˜ç[üÖÒ"G<ú îèYõ†7ÕÜ ÊZË,£Ü\Û…‡ð‡ÒT&’È_¨–üÚ™< ²Ö7:F_ʸÿ³8Ä(bm)u�Ö˱æõ %�A�QfN˜Î„ºV Ì”ºÔ"+…¦Ô²DK2( ³ÒsàÚ_‰Ï)Ê}d ê��þð‡8r¸ÏšéÎPç'+·e»ÅÀ¶L†[z–ʼn†Í²)CrQŒú‘¸�Ö @cN±V) R `‰gÑí„+hG©­èjG©ºÈ(]QG%PÚÀ1MøÅ(Òˆj°ˆõ�µ[¨ø œ_ï,V›Ž¹•ž{ˆo~ÞŠ¹bKàøÀ}?Å>VÚFs0>ÄŒŽÁˆGƒ‹Í­�!³^QµqgæX�ãÑã>÷öï:!÷àñ-FQDÇ©x19¡nó“nãûˆž’Ä™½.ãGg•Æ"E’c �U{µ¿h‚¡ôªcVþÁT¯ |œ ¡ÌB’QR¨ý¡éB.à¦3‰$ò‰5aÌÃ'4^Š~Z koNŒònÿ]×J}âÍ$úË“"{k(ëðh÷a¿ô1/Í2Ü¿¸?~×>Eæîsä^Xf~êÊåp©ÃN¯ ýƦwqNþŒfg+³ø%ä—ö�… ¿=“f“�¯`>óôã5�­U0Xј>f‚ª tEµkÛès«¨«!GÔbÔ@Èb�€Ugu˜yYÍ[B³:ê”xV¥±df8²õ1žµm…ïýZ¸Èfá _ÎÇ÷ý¿qû‚-MðBæcb€Gi¤ÑØ_ºM&´&¨¢j°b½h´&hÕ {¦Vdí4—µÿϲ¬Õ®&º*b‚‚‘@P &FÁcë VB*Zxf=l­ÇÈúèk*­Ð�áË:øíU00�ýAŸÁì~ÇD¸¥YA×*ÑSk9¾–ê$ð‰$ò‰óˆ2ƒ{§º…¥i4+§9Fé5ŽrEFdõèãpÌ,‹É[ØÇ·5 bh¼Äëã{nâsŒ@ˆjÌÂ>/*�ŠfÉÓ@H¶üiv¨µ5Ö^!XP‹q•^„+U‘cªÔŸqþ7y˜½¯GÉb9%ûXNI"‰|âü§ö9WCY+Y&…¡_×´Ýúj”,*_íÀ50]gâp¬Ô�Öe£°L†Ó(ç·˜»¶8áð?ßÔAj–ÿÁ³\ÃýÓˆÔaš’¾f…—ÍûÌ’ÉK;s%~a�+0;rt[™kàbs]$Ï¡“ƒ³À~Óøƒá~Uó2Œ©9F 1Œ[U›[¬õ¼C$WUÁ«€:¨­PÙØMt`ahÑÒ £Ì¶���­k‚¯£Bcqw^|t:„69î‹ZzÓzâ¹{ ¶2ƒªWiëŽð!™òg£qî�7â½»L©®l3@¹­ö’ý¿Rø¿,¥–²_²æœe“òáIä€2;.Vu­Ô(Ù´”í÷�Œ÷›Vø÷M»“Ïû3'e¿ Y†d+e˜ZAJ`™B¡Q g˜r¦x Ït�IVÂað7ÑOáŽö3îg®°8`X†é•’g+æ2ènjtZ0—?$áåGá+ïUzHÐmJøãe*¨æ  •Êxu<è ¨‹ÁW"Ð1JW+ºÐZåjU0 jÑ:_åʨ[¡(R¢¶´„¡�ƒµ^îÇ¢�cÛ{¼ªUQãƒ:¬Ä ƒ$ó§›ñ9ü¸È’ÅÈatÇ$ÕÎvUàuá!²ßyã\ùÇ÷£.ê‚r:3‹eŸ}+Eˆ+=‘H"ŸØöü£¾¯�ŸG– �}Ê£�Êøüº \^Ó¹rüó“û�zÁš:þŽýesü9ð1Øò1xð/DéÅ»vô„? Rÿ_ªŸ¿‚ð–Ë1[.ÏÂÂEµ™_ö¢Iš)#:`ÆÂt¡’`M[3¾V‚¶âÚ`Á¹WÉ2˜t ®�¡s(™ñâÁaj‹ -UÂÀ)¥EF&¦Ž@ë jA›Ô�¬2Žð(µ4êÚ~]󨚵�ƒŽÓ1Ûã �¹Þ±}^Û�šöàÀ´ß‡¶¤°Æª…Œ«û�˵ò×Ã‰îø“D¾G&רkD ¦ªô² ;k0uìUõ÷ ôÆ¢|Çý‡‹Êؾ_꾸¾Óm!‘D>‘8ÃLo.n¿_3y­�¢ç‘‡µãì½®.Ã}¨'îñÖ0e,ƒ¿°êÍN?ÕÙŽíöÎÌÐÌ„'az1ç’<èìTM‘cærÕ¼ÓVå5¢U+òŠ AÕ‚1„Ž:sY,ï+*h°±ÞJÓF]eØÃTV~à|Ö(ftŒQiA3µâ *6ö0–èþ�G(VŽWö Þ¨:/8oÛGÒ¶0ضºaEdXcÕHð¾�'ˆé|¾­«¿QÈZúG?>Âzš }†AžíUL <"�¿Oøã7Ìøÿú°Ï|Q–R¦¢D‰$ò‰ÄYçÀE�÷o€ %˜»©YôškŸ*Ø|Uì*Á Ë!oýßÙ•ÆNPz8Œç^ëQ`v4!]¼™ ÎfñÝY˜œ5Ì^ÖeÛd¥›æ½.̨Ì[ Ó(HÇ!™‹mA*]+zÔÆâaò RXñ‹ö« x‡ø */~hCS»UC(-49¦1„Æ«!€†xˆõ 4ÚØF\Ì�(à�†öF’·­‚m�:o5z Ž{6Ú"y¼¾Uãª~PÏån$Ïöx³Šð0Ößmš?ý�)~ûÈá…šéZ2\´â‰$ò‰ÄYå;8^uædâ�}¿AÔà7›Ê©Å£9V¬÷”xµɽÅ÷mð]C–‰÷µR¡ûé‡Ü2Os?”>çHíyÀ&n­l€¬dÖ¨��üRerG­½-èÌL`ë¬Ê´* ]ØâЩLL …#d. >Òžr �wØ3ƒdºV™658¼˜è¦'C‡V©_æ0t0´ÂÈYFÚPz/Mƒ6^4ŒçB<1¡5ÙÐ@�“µÿ=t<Xo�¿TU®ªPé[dÙÓ܃üÉ/g¼ýè‘ÅJ˜t¦®û�2Yò‰$ò‰ÄÙf/°íñ~`cå»O¼­ ÛµÞNHYÕ�àÁrO…×bu5Ä3iß ž•ÚÃjnÁdÂ0„ÄÛU&¼Åú �[îc8ü°­´Êr!Ï>Kå5Š^Bi'-vÒ01§:9˜™Ì^Œn™'[œBŒ6 ˜ìB§ƒµŠÒÔ‘Q܈¨bT3 “è˜�Ö78Em#êÀ;¨s¤ÊTFB(ÅPi�Uƒ–‚UhP÷ m *:vÛoTÆm‘r‘ö¹ˆ·¥Â�zúî·OÖ¿}g>Õ�—òϪõÖé Ê:]m‰$ò‰ÄY¼W+p+pí£ì÷6° ¯™ùÈÕ¢^: õpºv(¡B½…Ê£%�c| Ì‘(}*¯äVð¼WðT x˪EȆ<9ÈÐ j”z¨x¯Þ"w‘{ë}“{[‡+üýÞZÁWšÛZŒE vçÐÏ!üè—ÿ¬ÙàLI¸ëˆð€U™uA7+fÚ¡El�X«ª ¬õù-BôÚ;#d¢ô,Š BCPÛªQi2t B”•a®2¤ŒÁ�aTCðhð A04Ö‹ àT°±ÎþqáÄÇ’¾1-p\±™ãîò`‘q«aLŒ÷ ÄÒÁ' q‘8S(1¢þNÐ�~†Â'©ÃG�ç*è0 ‚®Ž…á„ çêÄV®Õ¸ïøûÇkóÚ†¿·¯U­ý ÕIÏõ… ”'þïµ›c† y•ë^ªº›.¯E³€`¯ås?çío“{sUeí ¸Í6LO*‹=«ó9Ìo«ÝöÌô›&”M9¡gâY¼Ô¨V·V«ˆAŒ‚µ˜ŽQˆõtÜ+)X%äHè@•#eCEG™ñ¥õnð£Ztä­o‚"ÐÆ€x4o;éxQ\ ÜogR�XØG¼Gcñ  â�dˆFšbúO(3ÛnLûxˆÝ ƒÇ<*¯0È㟽ç5jÈe„ã0™—MáZ$/QݯF÷"ïÿÔd* IDATÝ­þ×>÷HQQ–[Å–°ŒokÕ¦+.‘D>‘8‹<x30ñ(áó0ð.ÎáDf©b¾Üxƒa[3WibjÀŠõJ§Ç‡«Ae±Þn_u ¹m¤2í­+ðYÛ¹¿åb£‹s�…dË”ÊV3ž0©ÈdFÈsƒËX„׆è+5‚J@Mg ç@rAl@-�Z¹šàS¨/�î„×ËrÄãKС(CÞ‚Jl¬•xÔ�˜€Ø¶Oôxµm_ˆåÿ´-„Ñ7Hx¬Z9.íqS`¾ˆM_7ÎwPã]%YÃt_ÖíQˆ²WÍ-¿îš7ÝQ1*§³Ô\&‘D>‘xšÙ ¼ ˜ä¸Ûþ€?ž |ø°z.¿ O}«Ï*Æ�ßRP´ã‘©«;ˆ·1rÎÓÄ4ºXtH ­¯TàW? Ë�çsÑ‚Î[¥´öºj4y1ÚÛ†�� ÌwÐÅŒ0×uÍbÖ°i3ÕA¦ä5Ñv À°Í¡o³øŒŒ•�¹¶“à^¸Üÿí„�)µ"µÅ ÕU£\Ny-ŠÖÞÒôxÉ8Áˆ'dŠX\Û0¨Qï�µF…!Š¿ªñ¯‹n‰'ÂØÆ4™¬d¦D¯1hç°J8D`¿voù7|ý}«+ËÓ>I6{"‰|"ñôñà�é¬÷�»€à“çË©¨ï!Ï�¬àÃæzW©l™R6/j;*­‡jñê,bÛ–ÁtÔÖý‰¡ƒã»E.8+4•âÚsH‘ÃßuXñž>È#=ƒG92ð_ÒLe9z¶êÎu˜™ñô<óS [faó&ØR [3˜u�ƒfq¢F¤AuÔVó�YùbéBÇá§TØ,ŠÆ¾‚ˆ†ꎗڡ£¶kà Á :ÌÐÕÊ5M0xSQÛÆj»Á@ ªA¼ÁÄÜÁ è ½ñ˜ ×tÑÉ#ˆöQyùìÿšþ‡÷æô9<˜ÆÌ÷kö¥|øDùDâiø7[8~{+°»øók…ÌJ^{­*¯`9þƒÓ|á»ûr@a3X&mcƒA3¶‘Gžh;»\ ¢Ç ö›w±@ŽÍ‰õ|< o€Ñˆ0uÔ÷;©‡x*Ðë™Ïå>pÄ{ëmí¬tpb‘÷0eë÷#( »&cn³2»#èÜæà·Ø‹A_t ìUaÊŠNöTóBŵz0jDÖ "*¢bWcòCG�Éq„¿#`‡hÞà;˜Ú@©h™¡‹–Î1ìÃn-C‘8ã<ø`á�ÿ,ðï€#çå; •b¦2k�ÔP?3á\€ X�c¾�FëxñxlÓ¾÷Ñ :�…‘`±£Žx¼>6¡Q¨£#ŽVV‚m¼‡Æ"ޣ؎Œâ/d0jBÇGOiiþª¶û°n?]+¹Ad +«Ï]Uoþ*uw\ªÍÔlöèB‘³mZÙVÔaó²)Ç\”! Š�Í|ÓHÜ ¨wˆQ„ 8ƒw¢ãcK ij ­3¨zÂ0êLZ§¥�¡I?XäÞÕ ÍÄPüµ“Êä1à� ûµû�£õÏüAå÷Ë…ÀŠPgÚŸï–‹ÔY.‘D>‘8Ë\ü0Ïqsí6àÇ�£çå;ò^[k[É�ðNS‡Ú/Ði™¯§d µ,»ýLoòùBEþœe¦éìØŒß>§ÍB¹Ø!›]cg+tt"G­C%Ö,ˆÆõ#m@ž*êêúj'M[¼W¼jNÌÊëxrš`°õ¬Ê=ðÛŽaç÷ÒܱgÇðgþì ûi )ëRKJ¥„²Ä“ªÚ%’È'g•K€_j~Ìg€ÿç¼ø tÉeuµöU{¦n‡ß¶Š©ñ¡ã�A{&}ž!¸>¥ëóPIè7èþ£Ùð¾’ò#Y}´¨G6 õ–) Ùþý²ÉºwyIgÌM{6å˜ÍÈ�‹;°i]è2¤gÀ)Ð4´žzF* Z`]c=ÎëÃw8ÿ{CËboÔ¹áL6?ýgG³}Ó¥£OŠ¢O$‘O$žN.&ºè/⸋þ.àßËçû›ó¹•aå5'—*÷X*ñR®Ö~‰êÔ(Úç£óïí)M&%uX³�›6Û¼ÈLìZX“í_ñ™üƒ)ÿàËcLg‡éº{h�.kæjddª!ëÀ¤Có«È tq–°u.žT¶dHÏ¡½!¡< ™¸ý'Š•›¿zÈ3»võãï�b_ÑG¡¡ �2 }"‰|"q–-Àh”Í?ìX�˜÷À¾�ñV=ϼ3Ìt Ï®üTOÈQE=–£óSˆj”lZÈ€ºÔ¢ŽM^¦ûÓ:`´SÈ>ç²ZkWK“}BA!e¿‰Õoj´ŸeÒŸrÜ·Òxšº™&8ùhV> ÐÔhMF:åjûu9óWò™ž©æç s›ÒtöuvÇ"µ¡F¡¤?]HÖ/Óù{"‰|"qÖ-À˜÷FàêDÿ1Èîá�ð&-�� ñj©°Þë¼Çnó½WÁàr5Phnxe Ó #~¥vY-PS:Èêö6VrlÔaü "¬ël5 �ŠRhj²ê>¡ÀIV¢ôÑšxZÞ/ ŸP7ZP“Õ5dHY {úÅ�ŒÞAÝtèžf¸¨8'4û•¬�}S°…Òîo}Á>šŒX‚8‘H"ŸHœ=m~xÞ ¢¤µàÞ(oÒ[+¾"`­hV;œu¶Ê¢ä‚8T Ô:BÕ`ä­>NØÝ9M9Ðz\¶TJ®±�Q†ê×CÝ~šº®¨O {«)©µ|ì‹*e½&ÌeûÕþ…2þžýø“>5,£û!À¾ã["qŽ`Ò$.º­ÀÙ �~ ¸#MÏyÏUÀo´¹1/~ýQ�%Iä‰ ¶¦'€Ÿ¾ŠãAv}b%»ÏmÄ °�±î7ôçý bdïq~vM+ôé²H¤b"qþ3 ¼ ¸þ„ïw/n¿WbzÜ.à£r¼W‹•ؾ¶}hã~Þÿ ˜y‚ç<øÏÿÄs‰$ò‰Ä9ÎD{ÿø�À+€Ÿ=Aà!–¨ÝÜ|¡LŠ'o¾¾±XÞlzÏ}N»ùÛ”.“DùDâü£ ü2ñlv¼®_ßZôcy´¢ÿá AÚB@=žQ ,>¡HEeÍèGÏS;øM`Û)Œ¹x+±?A"‘D>‘8Oè Û¼àQ� ÇÓäêVà?z!LHì#ï©*T®ðïìæÿìCJì¼êbÚóõ-N±¾€ºË€ß:ÅÍA"‘D>‘xšÈˆía¯}‚çð^. ýÀýÀ¿\ÇØ‹‰®ûKÒ4&’È'ç.®ø¯~Ï}%pcš² Å#À«ž*‹­Ð?3Mc"‰|"qn®Û%àkžäó…ØYî_¦©ÛP^ |~cç�ÿÂñ8ŽD"‰|"qŽ¬ÙŸ^zŠãø& OS¸¡8 ¼øì:ÆN32¾4Mc"‰|"ñô#ÄV°/]ÇØû€%ö)ß°X‹Ø.,]‹!/„yödÕ©¥VƒA­—¢³¡®ýà‡€�¯cìd+ô/L—W"‰|"ñô üO߲ޱ¯!ºw7>5šcÅxϘçî³ß;¡öbØ€Úfýëø·ÀGÖ1¶KÌÐxIºÌI䉧GàÿðmëûHkå¼&Ê{4÷9žl\ÎVg³3ðÓ‚‚Zޏó6Gþ‰¶BÓ:ÆæÄþ_›.·DùDâìòZàÛ×1nñ¼ö‘ i²*¼úÜÊ0Ö ¢•C P#tƒ–´¯�ŸÞ³Ž±Y+ô¯H—\"‰|"qvx5ð]ë·Ÿè¢èB›0ÿ8WvŽ3¡ý~ÎÛs½Ðí%í»ÐuNÁÏÿs�÷ÄדR.Iä‰3ο¾gã?ÌúŠ¥œ×XÛ–ñÖ!÷�{­õ­`v0fÐñø^ç\½þŸ|7ðw¬/=â~æ€?]ÇØqÊåw¦K0‘D>‘83üŸÀ÷¯Sà_Ü{!Nš·–<÷†¼’*ËÅä•‹”xŸéZ�_ÍG=ìh¤k›‚s‡g·ŸßˆÝãê§ðZJlCûGëú×�Љ$ò‰Äiä;€YǸ•vÜÝòäy�R¡ ÊpÄ¡÷4Ø‘‚VŒÔ÷z&6©9gØI<ž¹x#§'ÝQ‰)ro]çøï&n&Iä‰ÓÀ·?¶ŽqÇZËë/ô ô-hÏÜ­•#žp§ÕwyäÞT§ðÒ[Y;¢?øâñÌD7ûêi~ýß'v®[Ϧ滀ŸJ÷ËDùDâ©ñ b±›Su!�s¤o¿àgðĬ8‹à½zkùÂD7Ôˆ7(‘&GøsÅŠ¿ø^b°ä/·¶3Áo†umn¾ ø9ÎãÖ}‰$ò‰ÄÓÉˉí`OuM‰ARŸJSø(µï�W€·8¼�‘›²‡°P¸sངè¢?üGàÀþ}ÿØÍúŠ|c;Ö¥õ•H"ŸH‘øâ|ð8u÷gÓ ü‡Ò>Š0>g¯°XÁû�áÅä˜Ôae hhz^ž¦öÓÄ49CŒ¢ºz |ˆ˜�Q®cì5­ÐO¤E—H"ŸH<–¿Ä©»=±—üߥ)|*¯U›Wµ�uÓöºcüsGµEñêT~dõiH¡›^Õ~¥‡ŸÎ\ý[ˆÝ ×Íÿq!së XÒVÞ“¦ð‰©¨ÔRQ{4'ð�ZDTQÅеØ�âÏZYÛœX5îbdúgÎÑé»»µè÷¯cìeÀÛ�‹Ó*L$‘O\ˆ<‹õ*)±@ÊŸ§)|rXÀ‡ñY»Çר¢ÚV»Ã€X½ÑYIøî¶Ây1ÑEë9>}÷?Àúšm#žÑ_’Va"‰|âBâÀ[ˆg²§Ê[�w¥)<‘÷9x»xs­8 ^ �ðz†£ë{­`>£Ý¨}ì<™Â‡‰±÷¬cì"ð6à™i%&’È'..%Ö _Oòo�¦ðÔðXð^±Ö2= ‡*$ª‚�BÇÊŒ®wÀ¿hþ×€�žgÓx°õ@ܵޱóÄ`¼«ÒjL$‘OldvÝ— ëûvà÷Òž:U+ÜÈå„û²æ÷�{}[»~¶ñ2;ê�©óx ÜHL“üOÀ‡ÏÓ©\&ãÝ¶Ž±Sí{ÿÒ´"Iä‘­DýzR‹þø�4…ë‘W+t­éæ|t×÷=ác Sd#‹`ÛÙÊÏ„È ±™ËW¿ Ü|žÏè ±»á§×1v²ú¦…™H"ŸØH,]í[×1öOÚcb½Ô•AÙÒÍr_Q`…,ˆRk@”#<ƒc§»v½; ^ß~þµAftÜÆx=G]àWˆå›‰$ò‰óžùV¤·¯cìb~b½x¯Ö£EeáȰ±Ä’8ù«UFnÆðÎ�öÔ9Ó ü+‰-]ß¿ÁfvHl†ôÁuŒÍ�_ 6bJ$’È'Î[æˆgð—­cìÿ~Ð4�OQç°Ø*§­,TÝ\Fh0Àò8}Aw¶øo"fBü� :µ±òz60Y+ô¯H+4‘D>q>2KLw»|cßMl5Ò4žr+%^-ÀDfsëeÂV¦‘J P ô¼¥szjÆK+îßüÀ;6øçX·Bÿ¿Öy¿}=1(1‘H"Ÿ8o˜"–ª}Æ:ƾ¿µp’ÀŸ.³Ú{Àã© ŠùÊU÷‚ž0«‚8F8F�Ñéøë�—sü˜@ìžøÎuÎÙ�ß™Vj"‰|â|`¢øç¬cìZËÆ§i<�"?þ¿õÂjå»¶a_ªA¶«@Ž5%�bíSµä¯nh7jÿµµr/”x¼ôŽu ýë€×¦ÕšH"Ÿ8—)ˆ‘Ãë)úq3ðsIàO·Â[©¼Ul.&ÃäLˆ7È##­4¼6xµ#¯Ç·§Ìs� ü5±Â[}ζ¶Ü·®süwkú'IäçÝÖ’yþ:Æ~øIb Sâ ãíiÉ«‰e_ßÓZðž ;`ò÷Ÿ‚ÐðSé^œH"Ÿ8œ®´©øEàëû1à'’ÀŸ9rŽ»áO¿¾óàû€O 5§ym�ÏBÿfÖ“ðmD¯–M«7‘D>ñt“µÿUëûéVàGiϔ٫Ü�ÿ_qZÏCž|?ð)¢›ºI~üü:§ü�Ýœ•Æ€‰$ò‰�Œ»ÁM´ù©¬GLu{Ñ:~ïg�ÊôœM‚¨<å¨÷+‰.ú‡ˆ‹ÒFíñy°k� —oj¯Ë �ç¦)8=¤]ã…Ç]Äî`×ërö‡€í÷{�ÃÀàQÂ%àÅëø�w¶?HÓæ7¨©k‚§âhMóQ˾¸q¯Fë#àñÞê“4:Ÿ¼º]'oLÿOò¾v3û‹ëìµ›¨{oˆ¿‡˜¢¸ƒT+‰|â”ùbëÏ‹ˆ…k."– Ý|%±,m‡xÆz x8ìl­¹õl*~¨ÝP$Î"±�¬§ôè''òiôØZY[Ë“m3{ðÃÀ~¢;¹ŸföIñ÷ÄàÒ7µ×Ó©pM+ô?¬^`óöíÀoã®f}��Iä/hjàóí×MíNYZK=o×ÄB+蛉ýà¿s�+GÓ´Ÿ—ìh-øeâ1MøSãævSý+Äã±SáyÄѯ»€®Ÿoþ˜ãˆß”D>‰|âÔÐ'xÜsÜ=¸ÜÛŠÿ[X_|Clê±ëÿoïÌ£ä*Ë<üܪÞÒÙCBÈbBXeW–!tTtÁeÐÃ(3Î ¢(�ŽÛèG<3ê8²ÌŒÅ…UApÃGP B²t:K§×[wþxßkUWº“¾ÕUÕµüžsêTwuߪºß]~ßû~ïâ"±ØèÏ�ØrÀnÌõ[Èúe€\y¥dðn·$?âÇM$çXÑ››�© ·=øWŸ(o­ñq:ë@™«Ií>¹yQ">å7ú¤üøk÷ ÌÅ–`ÑÙÓܪ ]@z]ô_pKq#ܵÓ'ý Ÿn'�/Ó€·ûñù˜~ÌüÆ…úf¬‰Sc9øW×ðq8ø&{/kœ„y·é’È—‚Vê;PìXº[R^ÀÊ�®Ëä8�z"0ÕŸ—�]8Â_‹ÏË=˜«r›[2›üF×…Å ìÆò’ë½Ë(�Ôh’Ù§¸å™q�ß$¯IQx¸óŒÍJ¸í"à XlËú—×b Ã-g¤�s(¬t°�Èï—¿÷;ãGëpß? ¼¿€íÖ»À?¿Ë{·ßðò‰õ§˜�ÆA�¯ðçcݲ™èï×ã“€�9�­d—vPo‘ài‚t#AØ›ÎLL‡©îÆ)4±““›ÃC£=aDi‚¦05µ�ôæ={-“LÀÖ€'b.úMòš•uÀ»\èç%Üv.¶F•O¤k�W÷a ®F¢]"/‘/mÀ~Ã{í÷‡°¦1IyX ¬-ðsckKá{ «Ž—?H»µ9/Güçæx¦ød!t«£?o–º|2°Í½5#bi =@”¦)€èíÎÐHÃâΦ š ‰ Ÿ°'Ü+o¾[šiÅâ(ÖëP6ø8ÎÏÛ$ÌÁú\�e­T3‡bÙ<ûâ\?­ÕãB"_TZ07X]iêDè¯q .)[€³°µÇ±åYöùÄÖð·ÿ;ÌùÜâé,ŸÄK‹ýÆr2¶.ÚŒ­õ÷ú÷ßì�-9“‚�XbÕ4_ C¢&š‚ˆH¦iÍ„A ƒ©�T&HeBÒìjö„¤-•n¢[˜ °^éøÒ²)Ç¢OÚžyŒ÷^à™*Ýÿ%XÊ9£Üß×`™ B"_4Nv± Gè°5êZu]^�åÏ'¥ ë'^ŒN4ÂÏ£ù\Œ\˜7ç}§8Mp’{g¦¹Õ¿ÐŸçû$à$Ì}Ozr,ÿ�9‚—}2�¿ïp傼IKYÎ�ˆ––T?ý�¶ÉRH&" €($µî‰"_ǘ„Õ¢_ˆÕ^ÿƒ.ÿ²Ð‰U¼™äÙ+“�ÏbyôÕ–b¶xóÀ�–Õy‰|±Y>Ìkïsq¸Æ\"´Òx‡ßl’²K}ùy•ìgÆ­ó8Š8Ï÷¦¹¥q0ø48$gЂ¹#Ÿ íô @§�ËV,þ ß½a¹÷4†Q‘†FS�á@ÐA+{ÒéV2áåîñøtÇZa—[äÿ„­O'a’ ýß?­’ý� |×'”Ih§°%D!‘‘¶^¿ÂoìWÔ�пkš´‹ØNl þgU²ŸÑ>¬lrö¿‡lLÀ¯G¸f¦b1�•ù}˜éÞ€c}[÷»Èºý·¸W  [nØŽ-DÅ:ŸÌýFô÷f€ ý§ƒ50’Š2A#é “›ÈðV"–`)ZOé²7¡�{Q^“pÛ¬ÐÎõÀ÷+|?gßÃrÿ“r æm{I§‹D¾´îçb{§[ôo¥ú»p]„µ MÚ¨hðú*² F#ú£u¥º@oÃ\ö»�»òDº‹˜î�¹þ| æš�ŽÆ±õ §ßü·1´ÚYàŸ3â„,L§I!!aº‰tØ @”šƒ=t� éwÑš‚Ïeàq]öãJæ)ü8pZÂm›°TÇ»ˆV"S±4¹# Ü>À–ÿ]§ŠD¾œÂþkM_âý[ªXè/ÀRS’ö°î^‡„a��þÈ¿Y¥ü1Å­›È. ÌÆ\çÓ}²14Æ ÿ­þs·ÿÞ›Uù8ø.ô‡D!ÐÕDæ…0u?dæ ÌÜ5�ÎÀàŽæ†Ì¿dŸÈTO\a-Ó\‡¥¯.O¸m£ ýÇ€{*l¿&¹ÀŸ0Æ÷Y-‘—È‹¶Qþß›üF|Õ—‹}® |Òãß�5�xT§IÁރб7 �öIf«ß ôÉÀ4÷‚Å ´ød!žø2@Ô¼œ‚]í"�Þµ3 û~šÎ<ý¶°os+Ììe0393ásƒ»˜Ú…$¾r>€¹ßW'Ü6åÛµwVÈþL¾ƒ2�•³ýºPD‰|ÙDÌe}'pq�|+1÷rÒÎX±Àß§S¤¤“€AtckøÏsͶø#žLs�À\2Ñ u€� ¤‚a¦èniØõR˜ž95è£1Ê< Û{úÓ³` ×½3ºyV¬Íê p^Âm,â¾�ñ/ Ó¬)À+±/�À2,2_Hä ¦81á6o¾…¹¿+½ÿó àÛ M !p)p·N‘qg‹Ø�¹í×åLRQ�†–F¢ÉaKÓºû¦7’š908¸ü„�‹3Aøä„èÈ]½{>ô… Q@?�YO/úäb;sÐE6;@IÊ'ôŸðûÉ› ú÷bK>·ŒÓ÷O·à�Øíy‰üXYæ3Ф¬ÂÜRçQ¹õîã&… ü�:=* ÆkNöõîiî!b+4gX5i³�Ü•jš©7õ„_ùɬyoèZ· 3ÀœÐ––b̯ò縑JoÎ`Ù4Á­XyÕ¸t°Jßß«s“Oæ./`ûËÈv‘,')àVÌ»YlVcŠB"_0cq-­Àr@Û±5ÒJâ$,øeRÅÛ°Ï¢è‚>ÒAÞ=Qés[ˆÎ?wWªé<[ÓôÓ dËÛ6tܰ™Ž â È>ÇÅ‚Äê,"[EðLÿ{|ÿèÂÒ›vøD n&W&Ü™7Ñ„`ô|Ñ'QW°í¥X&ÐgÊ8Ñü<ð%zÿð˜”ßë´�ÈJ[<¸Ðï¨�}:–ý7�É’x7p‡N‹ê!mŽõBR)VBtÞÄLtëJV´Ð{|š` "âÃ7X…úŽ?ë\¡'Çz&ïõÍ�öIÀb²Eƒâ ‚Çú„ sõ÷ä¼ð¢¿ÿ.Ÿ êè�Èm˜‡ðoI^Ïâ?A¾çMX¿RÒŽùÄLŽ/Âûœ‚å«®düû  †Å”‰¼D¾`Ns ¥<ìB¿eœöç0lùà€¶½s»‰*# RË3gšR÷ÜwµŸÿcž»)Š"R �¡�� <tÜHÔQü¯�Á2ºÝzÿ?ö®;Þâ"?ÉÅ‘OæcËGúß[ýývc±›±.nÛɶîò @o³û¡opIDATx¾å}Éë[ÌÁ²c>Bn]…âðA,õ¯´ùy³[W»D¾�“§˜ƒ•š\á7¦r²”ÑwyÊçXsQ�¤R¯ 2Ñ…©€{Ã3f]ûâƒ?|lj�Ž£4© "ŠRDk":¢¨<^ܽ<=9¢½øÁ0ÿš†55Yè‚y˜‡jfΤ¼ÛÅ>Îx™l€àFÿ¼8C Úãôýù8Ƀ„—bKwo(¢H^�¥ü•‹f,vJ™>ùÄ,/Á{�¹îÏ¢|u—q�Ÿ[À¶ÂRwDurQæòî âÚèÁM½AQp<ÏóÔŸêá4ƒ¹+í¥ö$Ã{»ÿü“aþ>Á­ÿx`�{Â2Iº D> ètá�—¶ù$c?SM^€'0oÛ'I^ïb¹ ýëYo£°ÆVc¥]"/‘OÊd,X¨47^³TÎdïÂ&Åf¶?¯€m?Sæ¹(.K€w§žÈD\Ç‹}å3ÒÇ…^¿žÖ�äÓÀ–ª�Í Xì“߸áÉ4Ÿæ ¸Ðop/@'Ùì€Íþ·JK�ýp Ö ¦5á¶§aùæ«(é-dÝÊùÇe¢ ìXLÍR·ÄbíYçæÜ›¶»Øo%k°Ñ'|‚°ø+úƒîÓ|àq¬¶G¾ñq4p/É«f–’´J_Óé(‘ßmãô¹Ó]¤Ïeø¡}1+tsBŸ{p õ¿ø£N�ªøkÜÒ{+¥ÏØÅ�ä ý†_ °ì€¸tp\0h&–"{0p(+ÐêÖ}\5p=û³[FHzn=æ÷¤¸:^\TkFŽg»D^"?–�ãgOÃRÞ^ï×hhÅ:Þ½¶€Ï{ØþX¬ å'ö!òAÞ�)æuöñš(>“s,ø·c…dDmxr¯¥È…{Ð�ñZà‡9ÿ÷h%[4(®8Ï=Ïûù’´ëätõÕØRÐ÷(¬¨V98×Ç"£ÓJ"?3€W�ów˜܃µ©Ý_¯ä Xˆ3 øœ.¿`§cíŸuB~¾i ,ÔêÖÁN¿Y, [L$toBwÎ6Åÿ@b_¦`kð·à%ðµ? éõ ¶Ї¹ñŸgïºô-.øw’¼ÈT7>vV°À㞊)mMþª'Uçûz…ŒÁD·ÎWîãš°µô3 xÿG°V—`9ñÓ°Ô¹áú€_ ü'˜w*æûoàFà+X>}³ÿ~nÎMáß°F |ñiþÒ…þr ¼½X´üé>¹OÊ„ ø˜vj‰ü¾h«°ùÝnÑçÓˆu¡Z]Àûþ8[»z öûª EìŠOù#À‚~Žþ‹¸= kŒñ· ÞD6Åè"ÿnGú¬ú%]REg暟�•}–l¾·¹–þp�ÝØràƒ5ºßy‰ü>Y^aß§É…ô‚œ×ÒÀí~¡&åÇ~ìÆ"ú§a.öCÉ.Õ¬ÂzÆßæ–xË›ý–[k\ü¯þœl^ðw± ùþ?â}Ù]Å'Oº÷@ÖæØy=–Ó|=ð_QBRÖµ²Ri—È�| ëÕŠ¯%ËóÌ…¾¡LV˜+ÿKX¾|¿.¥1s–Ó|V—@ˆRŸ§°xŸJy!‘"òµÂz·àוñ3#à7X™Ü>]Fc¾á®öIZ©&3¢”ü#ÖØ¨–x%ÖÝOHä�ÊË�/”—]Æ«š"¾Ç.ðmX ä'0ÏH”3¶B›�cÕ/k‘U:¼y°¢0‡×À~ìÁ‚ì~«Ó¸j¯½åÀ�/_`ø^áB‹ë±å ZE.{‰<¸0Ö‚+´¸¹u«Ù‚¿+WüYî¢Ä¼øh�ïãr¿/Š:ù¶Ú—+°Æ0)�ÊUw3z#¶þ~–Á D©x;Ö˜ªÖ™@m¦FKäëXäÁòÝoGmƒ«…“Ü‚¿¸�¡5 „(6oÁb=êÅã·Z‡¼¾E~.VI¬Ö¸DB_ñÀk°2À÷ïÃjÈM/JÅùÀÔÙ}þu:ìõ-òËkxßÞŒåW7ê´®HŽp�¿‹nîÖ�ˆ²Òïõ6ñ_€¥Ó‰:ù¶ß¿ �obÌDå°ëÿ0ð7Xf„¥âL¬«ds�î¿\ö²äkþÿ&„"ÆŸ…À»°–¾ïA.zQZNr�¯ç‰¾RéêTä©“}]…­ûNÒ)>®Œe@ü kÛ£!%äl9¨Þ¯ûeÀ4�õ'ògÖÙ±=Ã/øÉ:ÍÇMà¯Âª¾ë(D©8 [𮡠X¡a¨?‘_^‡Ç÷4à]øeg>p%ÖÒ÷j`'rÑ‹Òqð p€†âOÈe_‡"ßV§ÇøDà!ÝÊÆ<௰–¼—a…(å„ò!,=XdY�ЄՕÈϧ¶z''åxÌ•7S§|I™\Žuæ»xQC"JÈøEн˜ §a¨‘?S‡šc€Ç5ã/3�wcEo.ÃÉE/J9¡üµYÜ«˜Ö¼D¾Nö³M‡°‚,�b.eQ<&`ý¹3XQu¥d*ð*ú²?´./‘¯Kž^¡¡(˜Ü:àÍØ"ó±`¼#5‰ˆ­õ[±N_OÉ‚%$ Ü!Á*ˆUÔyÓ®zù3tžï“±(ÝWk( z‰»(õ=ú6à" EALN–È×.K°ÖƒbßÌà ç!*ƒø"p‰†bLÔµ¤ÖE^®úÑ3+�ùZ …Á§±x16ê:_¾ÖE¾Mçw"¦ßNÑP1®|xŸ†¡(E{t%ò"Ÿ©nÑ«J ãÇ�k5 E¥n]öµ,òKQe·B™Ü�Ú5 QnÞ Ü¨a�ÈKä÷�ÖãÇF+Vxã  !ÊÂÀM†’pÐ"‘¯-Út^�™f` – .„(—·0´d²(®ÑR—š ‘û£ øp¡†Bˆ’pðeÔÿ¼Ôԥ˾VOªÃQKÕbÒ|k¡*„(ËüÚjÐP”œºL¥«U‘×z|ñI»µ¡¼]!ŠÇ€Å˜»þ ¨Mq)Yì`]Q«³Ç6�Ï%ú/aë[ŸÓpQÖcµéïðßgcE©NÅ2\ŽE®übÑ^o©Züè×�IäeÉW9Gst.—\èßÜ�µ[ÍZ5Ñ©nvû¬ŽÅÉØzþ©þÜ¢a§c¿vHä«­Ç—†.¿É<€•¾]¯!b\èÎý ÀñdÝû§úkbo±œù»$òÕK›Îã¢ñ,æ6|ë;/7¡•GÀ÷Ì¥ß�céŸ�¹ü…Ñ.‘¯^Ì# cÖ[þaà^à% ‰UÇ ð”?nÆfϱôϨs‘€ºXƪ5‘? ‹L£#ü‚¬ëï1¿A!j‡xÆ_ð×»à/üŸóëh<æÇø½O"_eh=~ÿlq1ø°IC"DݱÖ?Wôc÷þJ`Q�ïÿj‰|uÒ¦kwØYü/±f3w?§NÜTBˆD¢¿¸-GôOÇÒ‘O–ÔØþ¶ÿ ‘¯.?¼Œõ„¿x‹ŒBˆ¤¢ÿÿý@¿¿ÆÖþqTw3�×bK»›%òÕë�™uzAO’�„—µ.„(&›°Ž”kü÷Ù.ú±µÿ*ª«¸Z [–¸C"_=ÔÛzüón¥?Œå­ïÔ}HQ&6ßðÀd·Žã`¾±–•Ìj‰|uÑVãǪ+iGÂ?¥ûŒ¢B¨Æª|`Eƒz$ò•OŠÚÌ�_›sáÜìÖ½DQäWåkÄ–TcKÿt`Ê8Ç&àbàV‰|ås 0½öcð#,þÛÀ:Ý+„5ÀÙ=ÃUå[1N÷ðCk}àkEäÛªø»?M¶üübBˆZf¸ª|Ç’ ä[Ì(Ã÷X |P"_ùTSÐÝn¬Íݘ þE]ïBˆ:'~æ�ò×ÊQ•ïh`ð‚D¾rISÙùñ,¥íüÄOh!„#“_•ïp†¦íKôWå|†D¾9ë\IlÅ‚Nî6èzBˆ1ñ[|Ñ?ˆìzþ2à +ÐÓ.‘¯l.ª€ï—Ž�EýGnÁ !„( Z §Ðª|+€f O"_™\6NŸ»ø¾‹ú=@§®9!„7ò«òÍÂRä.p –Ê—ÏDl à!‰|e~ÿ‰e¶ÖÕèE!*Ÿ-À-þ˜œ”céŸN¶*_»D¾29+§X*þH6`“Bˆêc7C ôLNq±?¨VwºÚE¾Ø©s½ÀãXÎúýÀot]!DÍŠþƒþ¨Y$òCKǪыB‰|…|÷S Ø.·ÑËÝÀ³: „BHä+‹ýz|l­ßƒWôêÐ !„�ÈW.ûrÕwc•å^®Çz¯ !„ù*¡mk=No{è×áB!‘¯>š°Þı¨ß¬×áB!ª_äC`jô"„BÔ¤È !„b¤4B!„D^!„y!„BHä…B!‘B!„D^!„�Èk„B‰¼B!$òB!„�È !„B"/„B‰¼B!‘×!„y!„BHä…B!‘B!DIh(ÓçÌ.Òp Qzæ0'`Ìa,†“x:uÐGÀZ2Kš ùüÀ_B”›ãÊñ!A=¡Ž™BQÎ(†8 !„¢‘È !„ù} §BQв^L‘_«c"„B…ßW’È|RÇD!„3_ž/Æ¥‹ø¥~铆SÑZ¿BQßÞ ôãÍ‚|ÁE.ôu¬„(?3˜tÎèdFç :îäèõéÔ*¿�K°¢è¤¾÷Í–Ìšõ­3 ³SyòBTýÀ³ÀO5Bˆ‰ˆ"NEßøeøñ½¤¢û óï4Üu�"Š�–µ�ÜêB!„D^!„y!„BHä…B!‘BÀSþ ‰¤�PÜ�y!DÒtdz8òU]*/„D^QMtDùjäþGÑ�*!$òBˆ*Âsß#àFžYCðlÎíoaä¶¾ á!‘BT#7@´x[ƒÏÞ.²£C®z!ê€ÿßõÐÐë-^IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/extend_3D_coordinate_system_XZ.png0000644000175000017500000015425015143647637027044 0ustar00paynopayno‰PNG  IHDRùô>(T:ÈzTXtRaw profile type exifxÚmP[à ûç;y@“ãЕJ»ÁŽ?SR©­f Ç$`BRÿ~öô`Ò¤e±êµf@]�„å‰v0e=øÀî¡èžO»†dDA”Y°:#�ù¸pFjPåbdï(¬÷‚ëŒl£xHFG ±…‘‡‘ð,P´ù­\Ý–ëÖžï°¹Ò w?¼3ÅkϽ.˜ÞV�æ.HƒEt6 c•$ ÂÁ,h ‡ºˆ�I(:Á@þÍéDúêëZL”.{„iCCPICC profilexœ}‘=HÃ@Å_SÅ¯ŠƒE2T'»¨¨8Õ*¡B¨Zu0¹ô š4$).Ž‚kÁÁ�Ūƒ‹³®®‚ øâ.8)ºH‰ÿK -b=8îÇ»{�»w€P-2Íj‹šn›‰XTL¥WÅŽWta=˜Æ¬Ì,cN’âh9¾îáãë]˜gµ>÷çèU3|"q„¦M¼A<µiœ÷‰ƒ,/«ÄçÄc&]�ø‘ëŠÇoœs. <3h&óÄAb1×ÄJ³¼©O‡TM§|!å±Êy‹³V,³ú=ù }e™ë4‡Ã"– A„‚2 (ÂF˜V� Ú�¶ð¹~‰\ ¹ `äX@ d×þ¿»µ²ã^R ´¿8ÎÇб Ô*Žó}ì8µÀÿ \é © Ì|’^ih¡# o¸¸nhÊp¹ >²)»’Ÿ¦�ÍïgôMi ÿè^óz«ïãôHRWñààÍQöz‹ww6÷öï™z?%ÙrîçÀ V[iTXtXML:com.adobe.xmp žË‰¾bKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEé  :  � IDATxÚì½{|\Wuèÿ]ûœ3ÒH–l˶ì8ï�w¸¼Mx$<.Ï -÷g÷…Ò!áÕ–Ò ÅcÚ[(PÒO)—&èmé…Ú-·\ny$†„Ê-$@€ðÈÛ‰_’õ°f$�4眽~œ=¶ìØI$KÖh´¾ùLFi¤™}Μï^{¯½6†±ÂEûaØ…"*Š j�cí‰õæ c¹P=½ÎK:‰žÆv\ÄÅ0Lò†a´—C´VyîjôYœu»Û²TMö†a’7 cI œ‚€ ŠC+î�OgC¤òø Ù¦K.ñ[†"‚Z@o&yÃ0–Šã¡HÓÞÛ¤¢îæ‚Y—!UX·®rá&³»a˜ä ÃXJˆ [* \l”mnt„˼[ �·S¿¶*"Xâ�a˜ä ÃX2¢ÝÄ›=Z¨üã¼7n ÏŒŠ>€¨¿ì¶QÛ›“7 “¼aKU¡‚lÛZè{;°†‡N.ÃãsAF;.X9ù¬Êå�MÉFÛbï £í"y6{*[xûÙâ|=þOFG‚Ú3æ.¾¨Bn±¼aX$oÆ’ æ*Åù—�r¦ gÅ Añ@ò+/®T"®7 ‹ä ÃXRÁ<°e»pó:Ép±â{b¥H¼A2õç¾j%åÍó‹^:ó±1!ù¤òB`Ÿµ²a˜ä ÃX”P^`û6*›¿å'‰®èÄ�{'HŽhÔsòxv èN޲IM?ù.| u$ç{Þ^VvÃÖÀ†±4°ázÃh;Á#›¶ãøÙf=‰/G ’gzT½ƒÜ)B„S4FeH¹œcìBwìþ|ò[ðÉ“=O8ü-p%�Z#†IÞ0ŒEq#ù�Àiv| Ã0 ã¸y2ð£V‰ä� Þ0 Ã0æ�õó%gÃ0 Ã0Z‹yi7ɆaF›b’7 Ã0 ãQ; ú·/ZƉCQA‘pïnãÊäoá†ÃéWý,Ñßê&"TmwÃX®zo¾È"yÃ0æÎ&kÃX¸aË‘íÖ†a’7 Ã"yÃ0Lò†a†a˜ä Ã0 Ã0Ɇ± Øœ¼a˜ä ÃhSlNÞ0Lò†aX$o†IÞ0 ‹ä Ã0Ɇa‘¼a&yÃ0,’7 Ã$o†a†IÞ0 Ã0Lò†a†a˜ä Ã0 Ã0Éω—ývÈ Ã0 £ý$50Ü \G‘Ük‡Ð0 Ã0–¾äw„û³€+�mÀ0pð!àù@—RÃ0 ÃXº’ŸI \ ¼¸¨?ÿ¾Ø¯a†a’_üØ÷ÞÏù!²¿ Ø"þ+��v¸ cVñÎ0ÖW˜ä[¾9ËçœD1w°›Ãçó{ìü6–5VñÎX~tQLí6Á}ÀkÚù ÇKìõî^}ÏoÎç_ Lß¿sðCÀÛgÀ0 £mè. b>ð, ãˆŸ¹Ñ$ßZ’ŸÏƒß<ðCa¤ )ýûíóa´5Û-š7Ú’³ÂuýmÀ�â9ÏìGˆMò ÈCÀ/�óàw¯6‡À}3„ÿ `Ä>;F[a‚7Úƒ“€g±¿8eÏý°ß$ßZܲ@’?Zo°9´ï)†ó›Òÿ6Åp¿a†qbYK‘,÷Là2Žo%Õ�íÞXKQò‹Q»p"5—ëÕ�ï`óù†a M7Å\úóÂí‰Ì_Ò¸I¾ùïÀ»€h_C™‡Ïçß„ð€}. Ã0æì¥§…ëëó€g¥ø;À¿›ä[�ðÀ¥-ôšÖRÌp6g9ïšåß°Ï­ÑrXâ�Ñ:œ5#pz°êüÍoÓ&ùÖdG‹IþHÎ ··9ð£Ò¿u9œXÆÀo,Ç“,7_ܲz©JþÀû—Èk�8|>’bˆ¨)ýPú1 ÃhWz€§ÏˆÖ[¡ìø“|ëò]`X±_{‡Ïçï �–I »íz`ƧL‘ùÞ¼Ö=™Öª°:|Î$ߺ¤ó)/mƒc°�¢¬b³´âÌõù7bóù†a, —<•Cð¿ÂÃ+˵_f™Œ ÆKøµïhÉÉÌõù6ŸoF+_«ž?ã¶z ½ö–Sïk)K¾Ý±ù|Ã0Z… ëÕŸ¼8u‰¾�¹lvf’_îöRdi.ŽœÏ¤˜¶Ø|•¢ì¯aÆ|ÐGQY®9n›¼¯Ç²m¹I¾Ezc;€×.ãa?‡¯ÏŸ9Ÿ0f×)ã˜Ø:yãpf&Ë=“">nÃ÷yÃr:¨Ký.wÉÉ#Íçß4¬‰Œƒ˜à—;ð$�>“bwÎvçÆåt�ÛAò ˆ}^�úž9Ÿ?A±ôÐæó ‹ä—w °T“åæƒ)Š ÆLòK„=ÀÏ� í³û¨tsø|þ@ˆîw_vYFÛ13YîEÀi˼=n¡Ø`Ì$¿„¸Ñ$?'Ösìùü¯Uk"ÃXr¬ ØÐ¥Ù¡ 6Òy¤/–í ùÀïØ¹{Ü̜ϟæÐÐþ�ÀísüF;aCõí@™bJ®™0÷ ±f1É·“ä¿EQÏNìù£¸<Üþ¥ØMï߀ÏXó´ 6'¿Y®ÉróÁÅò9“ü£¹õì3í^0V/þΚÂ"yã„33Yîyë×�¹EñË.Ù¸]Ö@î0É/( àÿ£¨÷lÆÂ²x6–,·’_vÄmtð*v/ÓÀ+)2ð ØVqxe¹ó­Iæ�fñ4“üå{ÕÝVÚ¹<ïü&¼a,eàKÀs)æÚ�…ãN–ÉþñGâÚä}d xÆü Þ†è cá¨×`ËUO7,×7îÚè½ì°óxÞ˜~Íßæl·&h~¼€b‹±pܸ\߸IÞ8ZoCôËË®on^jý‚-·šä—>?ÇJ³ZoK“ïRdÒ׬)æ�ïPìÝa’·hÞ"x‹à—6\ߊ¢ 0nM1¯Ü¸œß|»Iþv>ÏYð–d·Ü°áúVäÛÑ›äMò�|0mûT¼±9ûn:*à*à.¿‰˜='u]2Âã×ßA÷u\—(§u¨¶ó¦+ß^lý¼0 üÐ$ß> ?µóÚo,=î>G³-l’;·!¿8…sŸ>°÷Kã£Ü°^ùü¶;ß|Žl»S¨ •-ât«´ûÎjßþ 0igÆq±ð&ùö;¨† Þx4ZlN~û6áãwo�¿ý4ÎíwüS½ŸçÆŽ Ó /}à.^ °•ŠTDs*ËbÀîfŠ¡{‹èçΠ˽â6|O;€ß³sÛo,)äg?Cþù,Néëå ”9ßOÃt�<#Š2.®¬Û.'ݶÝñÉe Ëe—ô[)’ñ¾B±W¼aAß²�ä¿E±Ì0Á�Dk%Þé×~�Sdÿ +¸(Ëp~ ç‡ð²Ÿ,o {z�+ïÃW*[¨È–åt¤n¥XG?a'í¬øð I¾ý˜þŸ�ß&x£5©(UQE¤RÁ=áNIøœtòT�Æùqò|uã$ÞiNvýÿE7o‡ŠŠCe¹5Û-5,êv=fn°&hOɃ јà�Ö•|hߺ�mîS¿Îê<æ¯K]\ê u4¯‘¤£�gÅj™Xˆ.lÛ†WÈ+èr\Es#ð `Ê΢ÇÜ^&y“¼ ÞX¦,Râ]Te«T¶hôòÛ6¯îþ&ZÅË´¼ä£ˆ’5@¼&ýœH)F?Lòmú¾¾�mø`‚7™E𓝶ðüQ麷‹k“n^¡ŽI4Ãe#0½çêË%½nvÜüª‰þù.¶@[K>§X~b‚7Á­†"ϸ[VìäCô°9ʉäéȆñõ½ˆN›Ü…¯SÌÑ›è�Ž Õ·¹äÁJÜšà�Gf‘†ëÏ¡g2ãÃnoBIdZ#Ê �}ˆŒ“£¨w °?6_ ¢·ÕDÇ’î–�ä—sOÎo<: =\¯ÈåJ¬JRdÒ«[5ʪŽ>(Ýü¶Ï&мF” ã{Á�ƒ€¨ "Ñ›ègÍ(Åö½F›Kþ.à¼a,‚Þ,š‹h&ÀæAé:k/wñ”Dë�W‘|Ip~ “ñ&ùÇÂW�Wšèò Š)[£Í%ðM¼a,ªÈm*±ƒ�?9À–´‡×排ŸBó0?=ùTÔ6—:¾b¢?ˆÍÇ/#É/§¥t&x£åø¿Rɯ¸_:~ùK>àʼ�K'ɲ*d#0=€ä5„ÜæÞçIô¯¦X>¶œ±%ÔËHò7²Þ$o‚7 `^×Éë%šS©ÊÍ•Š»'eÓÔ*>¤N§ Cóa´±ɪDÖø'„¦˜£_.¢Ï€›ì°/?ÉßBûU…2Á-ÅÖJi¿p³Œý¯Ns1}ÚÀù’ ¡�ý�—Y’Ý îʽf™ˆþ{À˜òÉ—Á{¬ÿ<×o Ç•/«D·ô²©‘p­zýâk��Bc²QœX»Å`[¸ÿÇ6¿æÛPý2•<ÅÚAò™ Þ˜7æ±âݶMÄÒÁ+]ÌÇ�Ðë8­!ù0>B³œËP\±‡¼5þ¢ˆ^€Ïµñuߒ[&ï³]zxÐg§­±hè¦TT•Ëo".uñUþ•X­ $¯âó!|6ˆfCD’âÕã½¼YLþ x-íY ®J±û¨±L%ÿhæó.iø ð›vêÇÍœï.R*"[Ù¶Ge«ÔÖóÂÜó7qýL!~‚È�âCHºç2‡SÁÂøÅç Ài¿ú!ßÄŠ-kÉç´OÖ¥3ÑóÂ†ë• ZQ*Zà‰¯ª\2ÑÁ'´ƒ5yJ”�C:‚N¢�aŠ4—Å9‡gŽoþ® EoóñË\òÐ^KéLôÆâ°D· [á/þOÊ>—tp2 b�D²4 Ñ;™&÷j‰v-Êg�ßo£÷cóñÇ ^FïµÝzzMÑüO;•��lA7mÞ,7]ËÙõIþQJ<Χ8­á³H6ˆ6öãHñ gà­š]ËѼ¡MÞËål�eÉß Üߦ¢·ˆÞ˜=s™“ߊÜóWœ·~ŠÏ¹.ÎË�ÕÈÒ4D§äEof Þ{¼zK¾[dÖSÌa?Þ¢x“|»±£M�¡‰Þ˜=�4'¯*hÅi*›¶)Û¢KÞÄ#\urqš¡2‰kŒáÒýd�!œä D(æá Äæå]ðß.j£÷dóñ&ù%#ùð×Ì>!¦)ú×Ù)mÌ*Àö;E¨ m®èswm~|VãSQ7—ä’ÖÈó4À§C”´„,;púp™Û°}KDðí$ø<¼'ãÄËìý~#´;73+ÙÝ\7Ë×9sŽþïíÔ6•íÇŽæQÝŒÂ6ݬ÷ó{*gè×K/Oñ TÆQ9@Ü"o àÈ@ÕPÑ.¬–3Z‡ áúwa›½¯Ûi�åÑÉÏÃÀ[\ð \5‡ˆ>z ½% Hf<&3¾žùأ݌¥Ê£,¡ÛÌ&`t�ÓUù¬[ÁÅYƒÜ‡$;†az’ç „¹ö¦àmG¹–áàÖ6<Ø|¼EòGapq ¾É§Âýß̲3=†ˆþW)–ÏŒ{�ûÂýŠäÄa`˜æðz„Øí"Þ®¨Êvþ.éÿ©¬8ÀßE+¸Ì7ÀÕqY Ò!òl/‘N’GŽHQ‡4o½¿–áTŠáì³ÛôýÙ|¼Iþ¨’w‹ ~¡E°?Ƚx&ÅpÞªðw|ý0ìv‡Û.àAŠ2’yøY“}»!¢—}‰dê þz¢—KeŠ\'#ÊÉóÝ82DKÄ>Ã;œÎèü‰†¹}c1ð¸9<÷và‹Àoá÷7ü‡f“ü‘|›bgºr‹ ~¡Dßò=Àÿ:Êù°Xn�5aäãÅáëÎð;Æ�‡Â@Sü{fÜöòðÙž«á½èQF ¬Ãp‚Ùt'¥‹¶“m©(o¾M¢»jèä9¬¬óñl /�§@§ˆÒ.ÛÃÔÔ ‰d8Q4*ޤ °9\_PübrZˆàç"øï/ ù:ð±}�7QŒ6&ùؾ< ~¡#ú#É‚œ÷!^ 7V'…NÀ†Ð)xR XK1ן‡÷8D1üÿÀŒ¯÷Ì%¨…‘™!x9¢3b,!ñnÛEšmUqT¶úëïÛä/g{yr5ñkù¯JŒ“¥5¤1‚φé Ch&ÙIñŸù¼åpÖžûï¡C_ ÿ¾6|&ÿ¢ß§ Õ›ä�ÉŽE”ü\÷ƒoŠþ:f7å9[Ñy7…›‡ÛGÏf��Ž0B²2ŒôSìš÷ŸB +Ü¢!4e¿‹b*àþÐÁØn㡽Œ á‹»Í*²}+¾²­"^Dy “E¼Frb'ÏjDù(d»P?Aî"¢ƒYôbYôm$øïÁ׎xücáZðÑ{¯–tg’Äà‡–�àSô�•,Ü&BÔ~ïQεΠù>M ¬ÎžFÊá½U�IÏ ˜™Ðü~ý�“#Ýc£Ç࢛‘MåíwH§sü™–¹Rsb?A–׈ò1H÷�Ô'8UŠ åäðž ±èœæ< ¾É_„Cý‘y¯»€_Ø!7É‹…HqÝü|Š~1ÈBd>Ä}4:Â(@oèô‡ct:pIx, 勵kˆ"Çà¡p\÷�pËMðG! ×¹¹ù&é\Óŵ̛]õ)>› ÉÇÐl7šWQu8âBwÉäÞ6‚ÿ6ð’G|“�†Ïч-Š7É·:>| 6/1ÁÏ—èï~Ü‚Çe:H{�£o8ÝAþkC‡àÔðïs(*z­ "¯£À>%x0ü�q%‹™¹ú(£­}ÒGå�'†í¯De«üÚýtÿ²‹JÔÅU’eê 2L–û±P¯A�ª "Hˆè�ÅçŒp=;cϽ5~ü1þüG™ðç‹üžm>Þ$ÿ¨ì8A’ŸoÁχèÏQïR#§¦¯Îè)ÛnŠUk(›yçPä Ì,4:<á=î £»(rösø0¿¥ÀR!Hò˜ŒL#…/[+Û£ߺ½cl�wi¿�'òS¨Ž!ù¤1ˆfµ¢½€„%qE’� ¾U8‡"‹þ” ø&ÍH~±Dï)ª÷&ùEï N¯¾²@¿®¢àKe¾²Ä�ã‘r�·9¼º¡¹»íŸJ1-pÅ”ÀeÀKÃceŠé…:‡× �‚}¡£±—bµÆ‰îó¢B¨X³çbâ±®‘ü¾ÄtÈ8>CÒaüô>D«¸ƒ v9¸{œm0ÓJ‚¿ 8yϽ%œïãsüۦȯٲïû‡¡n˜ä‘Bä¶P• ùË -Ñãý‡¯¿² Ž·r(S_¸Ù%м€n-ì�‚gRL”Ã÷›9#ª М h:@‘˜òðœ€cý{ÁF"bI%%V˜îJ£žÁó.Þå8W#KC}º‘*¢ž\ Á;@œ€ªå4´ç†~1ߤÎÛ÷·a€f’ov,�äjˆ~¾Eï‚èøê2?4Œ¼LψÒrÄÏ$!zéV‡€>Ši€'Ï¥¨#Ð:MÉïåÐTÀ¡30¾7Éà zÈc±˜ÃtÄ*$”d÷ÓWdݼÂA)Ë?�æc�îÆû‘Np*3rìŠ5ñÆâs^üÆ9 ò}UÊ\ØrDÀ`’7É·œä¯Z₟Ñ7{â_µ�Ä#’RÌã�Q á­-»B ‹"pcø÷S¿WSäE:#!òŸ¹Dð¡p£ÈCHyxõÀYãi¨Š‚æ:ÞC¿�I¤Žº.BÓAÈ€�Áåä⮇Wq8ªŠ:SýRü ûVÔçù5½?\sþè¼ÿIŠå~†Iþ1ñ�pñŒ–¸àMô­�çÐ2A€_ã3·šÃël ~}F¸x7KOP ûØ:{Ãýp¸`ÏòW'·¿9ò­E®s½Ü–€f¨àÅ;¢|‚|z§chºɆPW$Ø©ÏÈ´³¨®( ¢xE�Ã’ï´ø£¹›QQ¶†Úüý¼r~üIsxî×�_[Á7ùcŠ‘®…Þ䬔­I~~<µ o¢_dªèw4„bȇʯ§X}qx¼;|vÓ úûÃÀ^àÞX⡵üݾ:§í©Üö¢qj¯Ò_V¯èØÿ&4Îð}#ªu¼;€ËÇqì#φqäx‰ˆˆï ”ä 3Î!•PÎ6'/Âû°þP Îþ`Q$Gœ•»mÁ-~j�_ã5!hzïþ ª7ÉÏé¤9^É/t½‰~ù EIj»Δ¿ ÑR'‡J¯�€S�'«2ÉzU"ïLå’¿�p|ê�¾›Æé_æ¢ÎœFéGš7ªÄã÷‘kõPð.ÆùŒÜyD"\>#É.È\ÃI"Q²=> ¼Cúø°ÄÎ"ùùà‚ ø -,ø&ï §Å{è÷[“ü¬Ùqœ=Ï•Eo¢7ù7÷˜¢…Úy”c×)娤=�F×ZíÌ6®~eã…ݯæ‚�~ÊZGý¥0ö˜»I'�;ÐÒ:¤Ÿ(êEâ5D²‰Jˆ$x—à$&"Â!^Ñf´æé}ì‹uôâo z­"ø¯†àcê¿æ÷†kÎ5óü{÷wÚ)a’Ÿ-ß¡˜û잣à[aˆÞDo@‘0™Ã¤k¬¡\ÝyÖ_¦¥žË9=ë¡«4�æU$…õu¢ìb¼§{rŒ”Œ$¿™¦ÁõH‘¬¡ É*·’(ê%�V"®­ w]HÜE"%\ÞA¤ÂÁ 图EòÇÅC²vÏýJübÍ_¿'œó9GV–Ú$?GQßJ±òlhµ!z½QPFÊÙ0ýïçÉ¥Ëy·_ÁÚ¼ŽŸž@eyâ7aõ·èüúSÈ긥3ÊÉ5%O•„œ™.óü$š��e£L§’ë8hŠ�Q"re¦¥Dõâ¢ò¨�XÖ•Ö�D=àºHŠry47ž•ô—ñºüãü¿ÿ•ÅOP»&õ?œ§ßgóñ&ù9³c–’_*‚Ÿ)z¡Ø�ÞDßNœÇå�I÷Ô]2…Öc¨g‰vý÷ô‚•/嚨›u�žä5¢ ¾Æøoü5Ý·<?U•²¢ž:":ˆšõ~醸ïઓŽÃ† r4¯’åc¤¾Šú b&Ð|€Rã~ð“x?Å„o�»Ôõ ¥~:Jý$Ñ*œïÁK/u‘Å]¸¨ƒ’DÄY‚ÄÅ`€6§¯R�÷¨Vñy•\ëDÓ‘6êȤàóiR�&‹W’Pb"«Ç甇²�Ý^.í©¬[yo�d{a´Y>x¢ÅÄ6Wž"ø¹þŸ�W·h;(ðŽ ú·ÎñwØP½Iþ¸O›B/¸]?Sô廊œe¢_⤫c·~ðBÿ±ïÛÌÆÞ×r k9ßOC>‰Ê¾Q#iì%÷�N)òß½ ’ã³b�øÇ¤y§…¨½ ^ U¼4\³ü­‘¢Î=¹/¢mŠ’S1"'eDW¢l,:*Ř®k šƒN’úI’¨“(� ®ïÉVfƒr�§º‰ÑÞitEˆäÇ(²Ç› 57ÚnÍâDSGùÌ«|ð±¶^HžDÖ×f‚ŸÙ®omú“¼I~1Øñ’oÁ7iVO{.6t¿´ÉÊLöýXNú¯lXýv*¬åÂ¨ŽŸžÂé4jÄù^ E’q Eá:HàgT¨{ŒWj)d/èÁR‘Šã¨(•ôiD IDATxPòâ�äQÑ�Ž—æ÷}±æ^Ãæö*Šæ ‘‹PIˆ¤“ލIúñ�qO•vÞqúÖ¸çéììÌKã«iÐAQ# ¹™Ð™ÀÓB$‡nEs¡!ŠDw…s¸7tA�ÇÞV¸U¿=>["ÁÔÛ±¹rÏ›¢HŽ6LòÇÅ ËDðM~ |�C°&úV¦?ŽÌò$)ŽUÚ“HRKU©Ñõ"úW¾�°Ž‹¤ŽŸšFýšíÃQ'——:Ô6ÎCì!$µÍîJ}øÙ"AüÊãI¸²8€$/f¼ yH¨SE�‘ˆ˜¸¸ú' êÉÐâu H.¨D8>?ÆgT–h{^FE^w”ï}F§Ë0É7c{zÿd™¾} S¦,õÿ\í>ó¼+Ùȳ²—N’i•D÷“×÷á|NѼ¤HuÇ»Ù%ÑÇ9ðB±�ЊyûŸ†ÇŸHQ)s.‚ß®×¢˜hN4— ¦á¶ yà·Ã5çµG|φêMòóÎO–ùû7Ñ/¦È{qqŒÔjëýÉi�ì½GS@×¥i•sÞÃÕr ÏÏ3\6 ¾Jœî'kìAdqŠæâ|Ø)Žb>^Éls��É�¿dnCôßn¡˜8xVh¦V)òö„ÎÀÎp X!0¡œ¥5σø­pÍù��ÃN'“¼a¢oª‰Ö”žÔM®º'ŠïKÒ´§;�×üW•ÇK=$2I®£ pÓûˆ©ã](*ãrTfìþ&¶ñëbó¤ øòžû€rô!ë•SÍ•'QÔ ¸8<¾‚"‰pšbnû»À»Â¿[Uô¯_ÿŶ²»ìô1É 'úæV‘&úD�T“t�Äõa�ª‘Öè{qº²ÿwù­èl~5R:™„|Í«¸Æ>”‰¢¨Œw«ÎY‚]ëðdàÚ9 þKÃóÇrs™àÝ3“ðLÂß\ä¿x&ð¾ŸÏV¤)z¡X¦h˜ä�ä‡{ý‰üP–‡¥¯ÞÇ ôOFë~‡×ÇgóJJ�ÂY:†Lï_ %ìN‹è]ÄÍiÎ×h-Áÿ+ðçÌ>éLƒ(sŠäÀQŠ!{€³)еú´MSô§Ú)d’7LôíE‚dZí‰ÒU¸³?ÉÕÉylrN'ɳ*¤#øÆ‰ÖŠ‹º“"“>/ªÙiH²³ù÷Åå)ÀÇN°àÛ‰lFçÄ8¬Ço„�Â&yÃD¿ôé»÷Œ<¦N2²ÆW“^âža—”Séûc^œ<�+Åã¤: Ó£øtâ«Dêñêñ’[´×‚‚ÿE1œÙòÅ9~¶ Ã$o˜è[2’ïy@2z©ö¦R®¦ZïAN»Ž—”ŸÊUQNä¦qÓ…à³}8‚ØEÎæÝ[Š_9ÁÞo˜ä }›15…OûªBMH8ãc¼0y*WIÂ*i5Æ?Ù¢£ yÑÞáT,‹¾U¸øðÿ¿(æï cA°ìzãxD–u?÷Hž2½#hú¸jÜ÷>.K.åDôú:Èš��e{q~”ÈK(pãCº�¸i%Áÿùÿ�À_YÉÑ/åžt?$”AèMe¤—²$åºTÉ´ÿ÷yz÷e¼S”.™Æi¦@>„Ëy û³ E&½(j–7Á†Eò†Eô‹Œ ®ñåòpÑ¡®—õä´,»©úrŠô*}V÷å\C'«(ïÓH¶²!"QÔ)h3rwˆÉ½%¸Œ"~.‚ÿðqkBÃ"yÃ"ú6 Ì$õzÙ×ë§èi««q�T)—¥ÿ£\¶òy¼�NVúœØWÑlÒAòl'Y‘E¯ÖÄ­ÂÌ}þLð†IÞXª¢¿ö8Dÿ¢vmí¯Ge6GOΫI�Ç}¸þ´îÿ̸+óiÐQrAê£�IZ̽K³\­³9øüŸ2·QпþÚšÐ8‘Øp½1ŸüS¸ÿ=f?t¿%|ýµvk”d_#ÓÞ=q^íqkßÅÊ/æ}t²ÎM!R'žÃ3@®#ÄÒܼ™E¨ÍÁ·Ïþä8ÿ kBÃ$o´ƒèø]}ÁH¹L_g=Jjeí~kõ¬¾_¥B'k|ŠäUR_%‘}P?@§hÓñÒl?JÕZ4¿˜šÃs?ü­5¡±Øp½±|�bíï\†î·°T‡î„$‘r‚”˸$AÖs†cnDÊš¼±ºqõ&Þ/Ýôû'5HkÄé>²©!"—‚wˆ„ýà‹,zA,Œ_Tž‚¿ÞoX$o´«èYV}šh9I¥7í•�žXúFú¨n¼ÇõÔÐèõlìx[K+9gjïÆÈó1â|ÃÄa¾�ûQÖÀ‹­‹_LÁà8ÿikBÃ"yÃ"ú6ˆè“$Ò„�>²šfå{¨�’—^Æ ¿Å5¥~.j4 šÀe5âÆ~òÆN¦QÍñfñ–ãs¼]�Ÿ‡³Ï…•½3âªÒÃ3 “¼a¢_ÔI•ZÉ÷§©$õ^]ùN]w%ï�×ñ¤xïªøÆÈF¡±ŸHÒ°|L¤Q±/¼�2-#ø­sŠà#w]\Î? ¸W½÷®�Iaÿ7ü!îª?…¤lMl˜ä�vý\ÎÏ¥#ú4Ñ>ú\™aj Z»²zÒ†×ó¾d=O‰8?ET¯‚�ÆNrm€ú¢DíÁb7jëá[€ÿ<מø¹_*ç+>[�lÿù?ƒ OB~ûwq/|î9—á?ÿa°f6LòF»‰þÚv}’<<âNI)�h�„ÆKXsîÕlí\ÍÒiòt—�àó$Û ê‰T‹(¾©uQT½m»È¼,Dðnö'ê×Y[ºRÒz9Õ{¹·éÅðê7“îÓpûmÖÌÆ‰ÂïŒ-z(ÖÑÏEôÐ"ÉxqŽ>M-S–z¹J¹‡¨ ŒœŸvžy $ý<^§Pi�äE-ú<$Ò"YóÁ‹í,·˜üà½s¼ðA’Ÿ06|2(§B=tßümÿ�Û=†¬ê„»î°f6,’7,¢oñˆ>9CÓr¯°Qã~ú]$Lò‘ ã®ó®åOËkyZ<S“äéy:„¯ï'Îê ï-bo5^>7ÁG ïV¸PódêÇð£<êõƒÇ×!W¿y`þÇ÷஺b›�7Lò†‰¾•E_OÐòŠª;}ÏÙ:È ¯÷ÄR½ í8ÿƒÙ»ã~.ñ21…—%? �}“¨ r·%q-Å+€÷Ìþzƒ¼UqëÕ1¬PûõTIÒgì¯ÿî‚ÓÉ?ý!ô3†õ}D¿}�5¹a’7Lô-,úrº†úxâwò‹<UÝYrÖ§ù]w*Ï%öu|~ÍFÐ|“a/xçpNì³×"ü*pÍ\"xÇ;=Ñ™�;Uê¸á»úûˆÓ-’é»úÑÞôÓƒ½»a×CøO]‹ïž„Õ�³¦7N6'o,¶èaîsô |}1^xµÒ•{}=™”Ž ê�>È;ô4^â=‘¯#:2F\ß…—ú �¸¢z�YõÆâ þݳ¼(=§Rkë_FîOvDâe츯Ld5^êáäl„¼1ˆÓID¬°M+òJàg/øä�íòÑÀJyç s²½yîg›8µ¨sŒEãµÀÛæ"ø>�¹¡[½¿GX½íÉh)O‰Å®”†Eò†±ð¢ÿ«9I­²�a’7Œ,vD;p=Eʳã^ô…NÀ`=p*ðäðxGxn}†øGÂ×ûˆÀ`¸Ïåõ‚ˆ0A,ÊËíMR÷–”ô¢_‘’œöî8Ýõ=�(u¦Üñq:îøõ4têfdΧÖÑ3Lò†q"Ñ#ÿCàSÃïÇ’j „Û‘¸p[¬£˜×_î×g‡N@Oè\äa4`æTÀÞÐ) �Md¹ bñ.ZñÞ”ôjà“‡‹þl„k"Ò]WÄý•ïoè¾IïßUþ!õÌŽ•a’7ŒáéåJï>Ãñ-ZnÍ·»�rþ—€Î úf‚ßêÐ 8è ·˜b¾Ø7}/µlœ•qŸ°Å ¯Ÿýcƒ\�ý™ ¿«*Ä>>­6º&Ï«yBåò°«Z=zÃ$o‹ÎS�w?þ˜\à¿—…Û$ÅðýÎ#¾Q õ—)2û×ÓœðœINÉâùÅad´œ÷ôÔÓÚEï˜â®�’\¾�”Í‘Öú3†¶÷t»©ôßÙ·Ë¥5¼a’7ŒÅæ,àmÀ/)¢³VÈ{ÎC`’b¨þÁæ7ʧÑõòA„5vè˜0Q“¬FC©ÕOñý}wîIFxU¶î³Rß³2ÉÑ:帩§LT« çim½/Çbóï†IÞ0Wð<|œbH|i`êXp›¬ó¥ƒCÛI>÷ýÞý»$ç–ï*»Hë#º§Ž‡:¤u­›à “¼a,'ï£Xúö‰ x«Zg$œ€P.K5>O\õÕÿE&.ø=A’xz÷¥�Ò¯®6þa'åŸ<@–ZéyØ�U¼3“S€?¦ ÿ!sÝoÌ@óœlrš©rçˆcðâó;Yõ•ñÈG#äT…¼œôô%¤¶,Î0LòF EðÎÁÿÔ¬IŒ£Z^�înºëã}9ñÿþÅdü;ï ûD”×4§öJ×ß'5<õ^k,Ã8®7Sðð™í†q4D€ÉÓtœ'ÜžmTÜÎü'7ø¬¾‘?¼¾<ž(¤¤I”…´nѼaX$o,ë(æà»��Rž1 Ô…y� ¯ *Ⱦ;N9=Úÿ†¤S¯;kg�ŒÆ ©v~ùãLÿp bÒ(WŶ-0 “¼±xôï¥(<óQf½«˜ÑÞ–ïÉñ¨‰"bõxU”lÃêkã˜(¸œ|ï÷Ÿ2ÊO¯BHÉE�4BGn?m?·¿s©÷=·kÏ®[wm<��õ^êx}p²ÁNO¯útdæœ|D1%´:5ÐO‘ÿqpÅTQTt% ·¡0ü‡5‰1“Hptfž\=Þ%”$ñhÿS¼r°ö‰Q¿ë =îÉÛªqÄ|•±K)j2Y—A8¸Ï«‚ì׆рõÀFàœðØ ŠüÀ4Œì ��¡ðõ ÅTÁ ¿M²a˜ä�ý¦Ø.öRàï�[­IŒ‡òŠŠ‚8$N(í½—=D%×wJcM bÖÿ8KÎþ÷êª�ôI²à/GgDå#áv×�€(Œ”)†ý×SL¬#çQwê ?›Éï €¡0Âp ÜÆÂ¨ƒå&ycI þ·BÿÏÀ-Ø�¦q4²´˜“ß{WÏ>¾û�  2òÂw�¬ï÷+WŸ5¾²ÔAI!WÅψ´ 2΀zè‹z ÑÛg¶Ý%¿å õ¢7GÅáÖ|‹ ¢¢Zˆ^U€ÍÛ¶gk¸X+ÛEå�ßÇS­1—)/~3þ߬9Œƒ½?ÉðZ"‰!R‡¤)�¬Nš$ttvGϹv"¿áMÿÝàê~Ö/ãæÊ(’öª�ð3Ý+š+NáP­€ ¡�aW)’ «ZØ:ë¿�¿‰¾�%/*ªl znkU©°U+TØ$èf�íŠTxÙm=çb"Ù¶=…ï±Ö\~æB„Oªp‚ â>|�|K1pÇÀ Ø3 ÿ'Ž�PênôÀÏ·UKûÏ!ùï!¶ó×­ë÷¼³æO]Ó?Íw‘ð¯pþz¢1ÄX‘(*c1¢Œ ¯¬«!jý«}y ùüü'5å¯1§Z¿ôÚ%3ï­ÎÄ>óþ¤œy 'Ž+gn49…xþ�£R?gƒ>¿e8ÞÒòh©€¶hI«:¯�4¾øÙÁ¿‘2W¡Â…�Ä`Å ýÒ3—þ íõ�¼Âp×wŽ’>0º´û'¦v29µ› M°EA�Á$ I D‰ Å?ÞðpÑ™­6Á;/¦Êb½­i‚—¿2°ÏVËøÏ%yA�+æˆ|SÿsÇùÔ-ŸçþŸÿƒÑæÆ³6zúc¹aJ¡ðhÄ€FúÞ3Db3BÈbF™§yø3í¥Ffö‘éål¨ŠQ�}#Š!££],]~“ —NÒ�§ñÜǧæî#�»¿ö­¬ÛI6ZßA§µûƂ՗xØà3ì—´T(©½ÕjAÅò�$® œ(wåD¹jðF…/7äAŠ>¹«“FEÛw=C9}pLX*›¦™’‡‹o"„±_�[‹³UØþ‰l luÔ€ï8?Fº¯ðÏ"y`Nˆ'?5ç¸q&‘ñÈÌÆÚ~5ïÝ8Ìû>×âŠ\â·Ó•C$怸0L‚Q/QBÔäcãÓú»«ð·_ùª¢!(¶Âr*(M�è$Ë(‰¿A±DKì'ôX‘52¹óöÓ »Çü¡Ñ~Š2�ÿÀçª%y„H^õ¨€Î ¢:3¢b8zð½éàïË­­[ÈÃ3Í/Ó„)2¥‰…hþü ¿P¼ç_ÍÊ?Á­î þQQ°�š½Çˆ—u+5 Å’ ˜R (0ôƒê0NÇ0ìË3´Ñb7†b /†M¬¬‘š>Ï2=½‡~¿e„ý [�ƒ¼£´@gAƒÌ2� ~la×€à×)‹ì*‚¯€$x¼1بkq!àƒCй�ø¤I³9ÂðÆuïY¢ÖsÓ7þcc@"ç;bʺYƒX*¾ àg(sóß|¦Z’GŠäðr¹‘ùüÀ¿Vn�o%ÐQÑÛ9¬bZ‡É÷·Ž|äõ·úXçS_\åàH¾~b$¼ó×_äSoýÊŽü‡X,>ÄŸÑB8ú\õÂîcÂsݱq–+ØÆex³3ññ꘎ž]ªf'N¶‘� Q e¥€HõFˆâTt ‰Û°áJ–�1`ÐèÐlÅ¢\Nä~æì‰sÜwâå Y`Ä̳'?ûVÏ":µÁÑ¥l¦Õ2»ZÇôFn67rT„ƒ�çÐð¡Ã¼’W±:WÖŠ*>L«5ˉV9²²ìÿZ­³7Í(Ì)“ÿàçŸ�úl9ˆr<€Û{GÙí7í.ŒìÂëU8öh�=˜¸â*CP!DQ1"ƒA�Š*˜8ŠÕ�pƒXÐÅ�dD»H‘:&YZ’±£§ŸüÙ£ 1 �¦þ–{Ù0÷#õ³ìmŸÚõ%:�ÇÝŒ™™�„ÏGŽ~°ÅÑ%´uh„V ÑãÀŒÀt«P@Ž”Þ?[]€åsú©-ÞòàSàµÁW¸[äl &| xQè~äÿŒÜùÒ B×›'6Òçݦ;/c*x µk±ý‚~ÍQ ±j‹ªð ‚ÿ%à:J�­÷UKòH“ü§ù+y)¿§Oå>Í<•Ÿ`“M>Í#¢ Rx©³¨´‚Ò›lÙþv“üÝo¡_MÕÖ#aƒ²+næb˽l~›˜C˜BZKG”GôÔ^2�¬u˜µýǹ{ê@žyùÀ]˜»N‘ð%êŒ ‘²—®^EÝ^Ž‘ÝØÎUô™Æ L`ià$£çKRW'pŒ€º�Ý!5”Ò?ŠIË�MDZñ*+J¢G,¬)Ú÷Ë…®-h~¼‹ÌŃ”£Õ#û^}ë{¨~š2D?ü._>£BŒ`�6XGâ=~zß¹‰Åø‹¼ÿ×w²û½ñ§Ÿ©%Ôú}ãHTÑš£vÞè·å8Ùj5ŸÐH)»v¾i@ðG*‚´H¼ÞÅ;ØÏ!ûlîˆ\߯ËÎ{Ú³-hÍ0[ò´J«%´NÐz¾˜ÖÁ‚´¾êɱ �AÆù‚>ÂÖfQþ;«¤¶|d­á0pH[ J‹�?ç–�¹%ôÄ ´5[~èÌþ£Ì�8ÙOè<‡¥¿|î8ûï\â„\Ëy3o7*öØgvÔ�#µÛ–¶õ…1¶¥;8—_‰årn©¿^s-%E‡€#‹!Š´TƒŽ¢)‡0ì@äÚÐ'#¥†@)¿›áXaƒ6WœX•;X8ê�ÞǺ¹÷�w§8T»›�Ë$›cd7‚ „ÙÁhß qÙ’òÝZ·²(PUʨËÖÊ©l5_�ÿ<}þu†‹T‚ÇA~aÑßǸSàÑMç\ù�ÞW7âÌs¿X¤F�‘€ çXžœd[Ù¶»7²vã-k£Wßk\ƒÑ~Nß:Üà^%*ê�ÅOaÍÅñ*<ÑlEJÅ²ç¿ ¼­Z’G—äácü!ÏâGâ7ðËz'ïãó¡A¹¨ý|x«$õD¸ië¤}eO>”Ei¶Š‹¸ý!�‹mr¡õ]´ÿ”˜»ð�àèùµ¸`€l=&DX(€nÿ¼ØB~ÑOQ”¿Ó»H&ÚL÷zì#ìì[Ý î ò8 ºGû0Œ“jC�ÔÊ脊,‘LЍ0ìØ«"¨C0ª¸µBXí+ë¦æœdñ�ÏD¸£Éý­´Ké}l×%L\"cñŠ?¡ã^�>•3ÃLÂ!„W~ ó�1Ì]}ô¦9‰¿òúRQP�ÞÔ2SGçtî™�—Ï9 ©X¢ŠbL�_v:•ß­iín"x,ùÅkb=äN`G±ð›ÄÜWÖ÷ã’Üú_‹ —GŠº#í{úÆO<­Ã'_¾máš÷t&þ}ÓYj“7Ü[·1$)=÷-�]dpëF´"ø'4x)ðà×�¿¨–äkAò'¹_¿À{åffìïósUU h xq«€ÙÓ‡átiCÌÉ-¬šy^ZŠ�^ ÖYb¸’ݺ¤;$awÙörên·÷¯¥§“@‚ŪÁŠQÑ@¤r)sVŒª\¦†Ë ƒ–ùM4 ´µ š5³rï ²À?²vWò×§çä¯NÚÕxÆãž7O7Nò[ÍuN,ù£SûyúÑéøÊ‘£æøL+�iþè¬è5;½èp/—aãM–»š‡ŸTÑ8ó»EÍœTŸKê<š‚¸ñ9šçÄ”T I¾™ÅH}�ržE…Ç¡ ¯u°$e_{ÃP Ї]¼ãÉk|ü'·KoHõ¾ç5bþ÷…5XkìñW‹Xáapˆ2û*‚ÿZ’<`2:ú)>>ÌßUË2{D˜=¡Šèþ9Ì‘AÄàUs3‘­°°£ÕãÃdœ`©Õ‚Ö‘aæ¤ÙÏ19ñî »>�MžNº°‡íùÝ•ôuŸŽÈ¬\Gwˆ ÛųØ'ŽHÙd䵎qkt¬IΘlpê°*¢Áॠšb3èlf6aQý‰{CïÄÝoöæ>û«ñt}½5¿w“u9·w�•Sõ&5YK-ýŸäZ”7Eq—Ó(>E¼M·‚š¯uqiÛ�{ äJj 8r¼â«kåqênÉ É£…§¯‚Q‡Í3ú´÷ÕêUÚŽÑÏõ]�ÔöAaýA¤­Ò£¯pþ�ÉÿåLû _3’ßÉT¼žóa~¯Z’-my"23Ca0w0Hg¶Uh9o¶¥Ì*kÊܹšùŽø™MòO¡ÍSüÝ­Ã@ ^É-öÍ­W‰~ÛD]ãʾ6IÑßiWtO(Øaà* ìÁ°=ŒÈÀ0¢‰Š¡@‰ªe:@œªXÐ$X݆åë¢öc }!Xâ=mÍX�_£Hæ³›ü5Ùeík�#Õq>¢#Lp�½Ò‰6·‡�‰%rrõÎCŠÁ奿dðxœõBÈÕW¡úÇ5<Ä\šP÷‘B€¡µô¹ï0‹ÒîqïÓjµož+¢�š‡1´*¤ª0ð!�¯þðGT×Æ×˜ä¯æ•ÜË<ÿÀ›«%�ü èí|FkúÝV]‚\ðSôA´ü"¢rdFæfætn낞m À›[¯ ´Z´ZåèÆÖÌñ³œ<ùùpì˜2ƒ>õæØ)MjüíØ8ýPg´7aƒ¿BáJºO®TaÆŒ�™:¢M¬X-JÊÞ…žºqâb ÈK(vëwKÁ6ÖŒEøVL<ÈSBÏ$äÀæŠvÛä²Ä²]àœ�g�N˜%ÎI�¶f~-îÁu‰•#ÿø…É rÐå3¬ˆƒé½ìTA˜:Øwûêä;Õ" Dq¾,P¡"xøvà‡€¿¤œ`«eùZ“üGyåuÕr\ÀE=å†%¾0õAe„çKÙýCáБóýƒW,8L‹­YhF[ƒÖ\‹Y™ €%ã]‡:0ÇÁW#Sù8‡`i9 Âp<3Ž ¯Æé³Ólg:¬qe¿0—¡q»é„'©e\ëfDj kÏ_ù ™ü«ì‹Šc»É–Z„ˆUŒbÔ©Ññ˜Äã¢ÊóT­’ÅÈZìqÎ÷d1ën=œc�å¸Îš=ÉZq«]s'ê½QšâÈÉi«61!Eº;°é*‘UBœâ½Ž9Œ60n},À§mºÎáÞhŠ„Uè¦Ñ�xºŠC°�d+ßÔu]Ðù€nRÄŽù.)©ätÕ¹òýU4¢,Š‹‘h )ó骨t».}ñÊ6·þüv†—XzAkql»¯Ý�5ÆC hÿü{+R¯ð;�oxðE)²Uùÿ[H¾ÂÃ]�ÊWÑ“°ÖüÃ÷¸·�X~}ÈeÑë[­‡¾§üsáµ¥:ØÑ¹‡ù?Kô:åüæÏméí@nÁÆEÚF6¿GFO°gíåß›Ïó¤€ëëo‡¿·O�ï2ÏâÛ‹I™¡ë<ÖˆÖ£s #¬Dë­©•ÄG3ŠÑ1œ^)CŠ&Aü°¦´‡1>>3f|¯v½ívVµ»®=»ÄòÐîÑÓÜÏ9Þ«óyƱˆSÖÓØíýfªŒ:CÞV—»8‘§&t'bd�Eµ£Þå > ®ë"r¬‚#´ö5s�¹z<Î!¾ëbŠàr!õ⬗|�à=ç‰þ oÐ|ð Ö`󜬖R/ ,ßÓ\å“¿0-›S°ƒ_¸Ú&»îr±ìÀT#”m¥* A8�~¡5Ïææþ™Þ�‡Nž;fîøûü!ZÜ &Öoe3¿•#\—¾—ÝùNöÆIFdšöfh,¹µ÷?â?Ø/p­zjwow˜6Û˜Š£î)Ú°OÇöIŒšà‚¨Ñ0‚�;ÔhˆlÏ”]yž�Œ}‰qÃzÎùž_dCÏÊF±”ðŒwµ›ãLTwZ…7 þÝ”ƒg²ŠØ+’¯ðˆ°¼Dma˜EŽ*æÇµÌ‰¿â5Fø!œ{ÛP¨Íõ›„¶W2ƦMWÓ:¦;–š¶­ ë>43 kǺG»~ŒIrɵ8îäŒçÖúº»={“ßÖHl¾)ÁÙD® “n‡n�óÅF¶Áj¬6ì _û�×\Dð›Õ’T$_á‚–9y¥¥ú!Ë�¼îûÿŠhä/±�¿*ð±Ñ† *i-Ø®[ê¦ÞMéúI7…,ÓN!ÅЮ«ozYÎÑt¢c;‹uOCŽºî°Zß)rç^ŽYgÕuêÞßç»ÄCâÉÔ7�!O{aÙoâÃZº+þ^>d.£!ã–¸§S¡æÆèùvmW1~šÝl“]BÅ0M�Ýš2!ŽF „²‹€X®cD”m¹‚È3 ¨xú´é…%|\¥oÎù̬ø®_cÕ,s*_5ól¦Çé„e ò<ä>Wž¸�ûXΉ`þ9Ãm­)Y¸1Ù\ûýõ‘›ßg“�”Äh•{¯ð•·ŸÁÿpGEðÉWx”p¸…´ÊN½—"2‹•#ø8רôZ�P$@ŒJN ‘º—¶ËT�Þ͈x$#S7próxê]¯àðxõmB'à¡í#ÔÅãñõ 2�ëë]7QàHÿxò³ÃøÏvéªoa —nó.W›ÆùÐm.u&ŒÎL.ƒuÂ+6¾�=ñûµŸFÅC1-Eƒ)HY<*©ˆÖpšªØÔãTF‚QPJÌõ©²Y¤ÚW#t]sYO–8§ ¶í—Ó,e_¤MHûŒç†sihvƒz o¦’vs Î34h 0¨UL¸Êø¢–¶`ôZÄòĘ`Àôè·»ôøÄk¦XÞŸ–cÈgZX°kñ‘°5n¶B…‹ð$àç€ãÀ+_E|*’¯ðHB¶ÔÁá»�ß@õÝx=ÄÍ-£º8ou—ȼ>؃õ[_ÚbæÉxp±ZF¦_ö8¼è\ôüÅ�é¢té{èCØô@›m:À-Ã$“¦ñúíï9³gñù njh<ßÖªmg‡ßmóØ4§õ6ý('|¡V¿%ÙkvÛ†§Ã®þvöå–oѦmñÑNê8¢€ªGJ¿tÌ+ãÄ\lÌŸ $1c“3I‘o˜MŠv~6_c™+¬º5·_ãÅšCê‚AlQê–Í}�aW+eÐb#•Ðß$¯Ñh&˜ì†·®ò‘ÆT"ì¹}]…!D •ªM®Â—ãJÊA3 À�Õ’T$_áÑ ™½ø ÊœØ]ª¿ˆkÚ¿¬@$™ð¼oåþšo>P«w Ù°¦4őѩ·ñJûóâÏM°¶?qFù.»Ás9ÃÅ´i°S �>óÁÚ� nœz˜rM?kìˆ.6dS�F v¤H£0 Œ qŸ"Q#še1ÒUÃFYµ½LQcDÛ*oÆ`DÀ ˆQÁ ¢˜¡”Ô—³–ÍôuL.Þÿ¾6“K~ç×Ïo�‚¸ò-"ÁX,UN¾Âƒ ~X~X§AªH¾Â#ëÀ_ôø%ÀÿÜü×Kù—ªw»?Œ'ÓÔ­„®¯k٘Óm[4:&_ª{òae¬#Ý:øquݳÁ§ûËðV� ÎŽ’¬÷Ðh‡kz]¾+‘"q·†ã9RÂæ£$ìiêS»/²O /Uˆu*�Z4bÊ¡l°šÊvœN‹j c#A &–‘‹hÃÜ`‚*5‚d#qé ‹ñs/fç‡6öÜ0¿«�±Á5·…©Ëý˜&åÜw𢥑 ñ|ú¾B…+."øïN_t©U¨H¾Â#¸w ð/�ß> ¼‘K\:²«éˆwˆïÖã0ˆ÷cä•ÅÉàÉÃÄXÇJNd¹©ž®Ò^Œuš²Ü„¼=éÚ~J½"“Yƾ]t‰8'ø ›OJŸÓë=2û.9Ç]a˜ ‚™�ѸK­lÓ,I´É»éú%†“iêùˆm°«ØÅM‰cT#Q & å¢Çª5h¶Ä’r h{‘•xÛkÆå�gÖô�§5Îìü……‰�lo\é¢à ŠÄ’¨¢*¨5ðRåä+À.Ê"» xpªZ’Šä+…Q$‰`úJ0Z†íä‰Lxë¨y%rÞ“7*µà&Ÿõ‘Æro<Ó/}Sʵo_Þy¹îŽ�  Ö`DALT¢æ!…Zc,?Û žˆå¼&ÌV¡Þ �_Åú/yŒ¿ØÁéb»®ZžŠä+<²øfàÊPÙºÕ’T�©Xƒˆ!ñ…Xlâ!ø€M h¤ -_}Û;?¦<0FµŠHÀ›„$*1D‚ X0"ˆ "ƒÜü`¶2¶ôø ¥A€ôç¶40¥W¿åÙWdI¢I¢¯ÿú!_¡"ù ��÷¾e-_O9¶ñàßW_á<Á+J$úH°g,IðøÎ&›»ç²EC˜úä÷žiž½ŽÀ�å† Q67ÑzNô’çˆ-HlN¨)&”¨JDlÉב²mÓEd๫”ù{¼)=x µl7¬ÆÏ^²¨¿BªyåÁW$_áÑ%úë(«çO¿U|…‡Âòð*à!k³ÞyÏ¿³ï–Ú÷î]ïìó¤× ÉFÊ­ù:Vè: 6$>ôÅ$�è&!É1tºH² v±ƒ'/¨1Ãù¹ò#Qc± ÐA_Eò—&Áÿ,°øaàó¹W$_áÑÃÞÁ÷)sñëÕ’Tx�(H€( `s•Õ�÷ü„åöM5—¼¨[� 7®Ã¤ŸH0‰Ú(.ŠóRj#•&Úa§ Dµb x͉¦‡!#Ö×�$#au¢b€è0Æ£&@iTççCø·ÀÓ€—Ǫ%©H¾Â#ï¹oYÌ»€?¥,>ej…'0´ðÎ’È€à}Y ' sò�÷¿ÚqûÏŽzDˆ×.½ciøËXD¡ IDATX{ü‹WÐZGkV]ßQ‰W›`‹:£‘lL ¢«‚è1Î;L,“÷@h"2‚v÷¢T ¨G¥ ˜œèzômFbze4@z`z�ˆëƒ)ÊÉh�è0eý~�B™Ë/•ù”`IiJîQ¦òÄ�zR(y®M‹ä®”gNó&àx¼ó0žZ·¹S;h"Ü$’"¤ˆï·&:‡øqg ¨[÷Ñ{— )B7�O°Ë«üðtà§)õ7*ï½"ù �ÑïþØü°\-KUÔYk0¡À‹5@(($Ͼû6ùä«'ˆë0|"èüuç{ùÐè§?�?»­Ì‘ƒÚ>jû#à–‰2¢&T$&*8ÞXg1qñCMÁ;‚u‚AÔFYƒÈ0‚Ĩð«Õ�Ju]�uH6è×:$fE¤œŠ'ZP˜@llÏ�œ ¾N*¬Ò|¢l} ײWÂi“œ.^ó4\..÷:f‘îj¬OÉqêñÚI½#ï–zÞåâðX`t)-g8àIAð9xô –«þFÊPýÛ«»­"ù �öoxò¿R|…‹¬? e(|«ÀM�ù÷¿¬Ç‡_7ç`ä³�þêâå÷Þ×ø\üi¤¹Åc7hoÛª|·€˜‘såñ(”:ÿÅ`¬bL Æ@ RæÚk5jy]Ù˜ /†�ÓÔ:5Q�‹Æ[Ô˜rªpDã°jPT�PŒEÌêk$]KQ l†¸¶Àè{û×r£?#+,u×Yêñ…nÏ�Ì‹]L€òØNSÁåBÚG)ªÔÎ]l¦Þ8�B*m¼v ê ç!Epàý¾›*äš» R$·NÈ/xúO ^x%ð�Àaào«;­"ù �¼ç¾µ©ìüîÁßW-O…-D�¯9jÁ€�à,¢ž0ÿÑoisëk¦Ñ ¥qgä¿rvüÊûGný:ê±�¤Lñå‚`ÎÙÍ H?*Q|)Ý[(Á�‹u‚ABo höoc06òÅA0iŸD$ÔbÀQè6ÔÕ„!¢w¨ÖŒÃ”±EÔ‹ˆ”!`$~ƒìå€<­6�ù"[Ųì•ö©lqM6Yp]ÚÜż½‡U>ÆÊè}Í¢‹'oÓµMÁå�® ).ͽ†u¢÷©¦FArÚꋤmæà|Ð6�;+xÿD zü$e{n øó­ UgDEòq¢ŸþËÀƒÿ-àÞjY*\ kq ªÑŒ|þ£/jóþ×NÙžÓÀ¼rýŸ¯M\ÿhÍ�h@%ÃûAž{¨F=Š8h}»>–ùraЖ8ÁXƒQP‰�²š^Õõõ>hD£”¤0d°A‰¢DÈUÊü»1”Â[Lw„X4‰Fb®4kjj�U1[éG›šHÓ‹ÂĆMâåAˆšˆè6(Æ4È>ò˜Pðãä+ÚmÓ³KdöËñ´Yð‹ÉI–ü<�¼?”Óí÷Ó³¹g(ònS=urï_>ƪ,]š6—®Ü{óBÙÿ¾EðÿÏ€Ü,U¡"ù ÿl(°øcÊ9ͯ§”¬­PáÁŠABD¨‹è™�?u™Ìî2½ rž4×{ÞßÉPÂP/ÐOC•‡­õ!/ÈM¹½™—fA´Ìœ.–íqA”`c�d0PÈK#”Zþ$ âkˆS„€ï÷é;‹M@ÆÚÈhÆ[´oT1øšAœ¡H,¶Xæ#KwògìÒQvºí²+»9 ó"I™£PcY´@Dµi SêÂuše/1^IÌŸKúd½52–ó +äfѯ÷–Ìf\¯l¦§XÕSùF~ëù=d>Gs‡�?®/%C9¢úÛ)‡Îü—øü‹ É?­è-‚¯S›¹øMàsÕò<Á/ï b±F0¤oˆIA( ,ßþŒ Þû¦�ôê&6>¹ö�ÍçüIh”±Í>™­‘ôQ ’ä>ÁÉ Ÿýáâ°§J'ƒˆÁÅÇ¢\0¶X!2˜=¯eÎJõœj,6µ¥ÀNÐrÆ=€ô 5…tëª!4JkÃ(ž°XÏYHýØ]�f÷‡kÍ]4tJ‡Í.R�& "$}Þ[dÌÇéÚnjaõ8eR�*CRÓmêLÕ†$z™¦Š©e‰ͼígOÖÂ&)ý¤ÏÅœ%]c)nÖ–9éOÕ�ÇY#ëµ}:!Œ†œÍûé�úiq¤’ÓÕø +iï3cY“T2ÚFsÃút¤¹XŠyÊ®€�!äË¢uå®,iÓuº>¦ .Eº9‘Ð$ÝÙuù*šÐõ‘òa™néSRON®ÿ {ÏwSŠÜ¼xkåµW$_áÑC üî döZàxµ$B©E/1‹�±$Ç$/%g—�ݰÆß¼qš¬iHÎ*Oÿ�‹{žý±±Üà4¢C ©¢ å ù\)|Až‚SûÕs­[$ý•¬Ò¯xl‹Ü%(ÇÝlˆ‹ž“�þ½>äóˆ%8õx2×Õá÷ÖO§ïmþ·eÚÑ5½iLàŒ#]»ÎN'ÒeÎÄN:‘9×FºŽ`ºuúÞlw÷@úÛl+¶1$Vë‰ Jd¯Fk4t “ô�b®F50‰ÊT_õZ4{±D"�¤¿¹Tdœ[÷C«dù¹õÕÅ%»ÊrlÓ.¾hWi·Ctì¾Ýaj=“S´ñÝTs¾‘‚6óè|Ù!`I¥î›’®7q<-Méâ´KWq^ÒÐÕæ©±Ð¬OŽ—¯£98ïXtH>n-9J"ùÿTÁ �CÀPªhV¨H¾Â£j”7ßF™ƒÿU±K…ÁÅa#¥¿&±”® b�ùO>s…¿}Ó²A6”§¿vaû³?6Üw ¥†¼æ}òz�z€! ç˜�al 6c Sw !sç•ÔZïSÖW‚üŽ{è.Ð�ÎyI]è¸:¸Žø±Lxg¸Ùÿ,CqºÞd¼˜dg¨‡i—0áÎq–&ï G£/ŒÄmLÚá0‡™v£<9³/X›^�ªC˜(¬Lb“öD›§Á#A2¹9ôÔɺ º¼¢ók+}Yugâ)¿lÎqÊ®ðñî9wà›5†ðhêHjŠ$D)”à=1°r^ç’AæQ\]ð™:×ORÄt¬�ÍW†CÈB§X`´OkŽg˜ºtê^<2_Wò:à¨{Ïrs™å±eÜ™1ÍÆ¼n»XŒyëNÕûÙ)rç¼Ô�ÖSšÒ¦C=“¼¹ N(ü¬q++u†ïÏš�ãü ª&L°-î©¥ìì;66 Åu¾ u÷Qõ2Ê„ß͘î²]„a,cš�¨˜íbûSbxR¬ã‹†1Œ)Dõry§§Ï“M~P7‰ltƒ¬Ò±K¬…7ß]”“ÝE{’õ°Ißvñá}ºD<â‚3ùf¤x%Êâ^~�7ÌôaÎ03 xAµ¬›,¿ª|Y�ÄEÿÑÒS¼^E”¿CÊãòà�AµKÌ—½¡BEò—>ä¢õoßC9tæí•%ýÄFÔ²ÇÜÅr F·FBM°ªÄ3wo_äÿ}ý4í]{VyÚëWv½àÃ=Ož$¤ñbA¬£æËܽÁaCŸ¾GÅ âj½>›Ö‘\jëTwHæ3…RÕŽ’£ �á¡3°`K?Ê2-��òÁ�º(]¢§ mB MØz…÷h‡¬üœò�š=äžÍè(]·Ðk'úÝÞIÊ6¶™)‹;d8ìÒŒ o×ã#ë2½¾M†üXœt“:âw2%O3�x�öð$X,"Ê(ʨ&z™w`’‚øj×W$2&!¾ŽÚÊûddeéîOßµr—3÷⽬Ûd2½›Fsž?¥Ãñ%áU7ú9®Ò¹#-á* Çn„ù–êþ–rÐÖaÐCsÊ Â ª´DE™ÓݺÄ[á p4p=Ð:‘2zP•#U$©îß[Àø9àÇÿÁWx02¸P4ôé;G‚Áä�âÜ�É<ÿý-;Y¸Æ «ÄñÛ ¾éÏÖ‹¢D"_³$×ö ªÅzŠh ¦¡&¥àMuõ}m�eõ©@P²Œzæ#γÐ\ÀáqŸ®wêŸêtêêDÈÀÎN'–¾tžO›—;]—X¼ ¾=<þšT·cdŒº6hh*uuàŽ%ÖçÅ).—ø)óC¤dÔcdH33­\+&‚DÄ€ºÌòfŒë½À‹Í&ÿÒ�ægŽ�${€!N’sÊ8¶èÿűUùú%(69öÅlÿqâQ�¥9tfîHy)·€¹#3´˜�‘ÒOŸA™k)|Ð*-´5+²‘™-E…Šã+’¿„‰à�ŽYm±BÆš€8G"“{úçÎ /óÎ?Øen¬EYB'ÞŸsð?-Oï+¦�`BAaI,IßÓÇ\Т¿§ö`2‹9y%ýºGÔ\zùøKÍffó<‹Þ9)Iß©ÃK½ë5eRrºt\‡úÿÇÞ›ÇÉyT÷úÏ©zßîéÙ$ÍX»�Wlc°1!�@â$ÀeËrù 冄ì—5B!¨Å $˜ßäs³‘Å –` 1!¹þ±˜ÝÆ€¼È’µÌhf4k/ï[u~Tµf$K¶¦-Y3R=ÐîQÏûötW¿]ßsN�:§ÙO†e¦¯˜•¬™ÁÂXÓeÃØ“øñÙ~ßÌ`í¿ûî¾7ÙAªåJr·ÆöÓÇZíµ+«ß/÷ÜÜÛœÄÿ~ñ¨fášú)ÉÈ:ŇÕƒˆh‰ÒRë­É(\iÔ ªe•æò¬@K=-�–ì“–m}gÒ×ÑÙ»íÍ^þXÒ/{™yþþ¾|ÛÁ Îç@ùém“ƒu\íÉè¶m[Ù­S‡ÿ¨›k¨óÒ÷Ãõ ·ï@·ÕñÁ¼]8U&’È/?þð„¬Ö&äT¥æ‰£MA:¾µKÚ#?èÛÇ ï_ÏÞÇU|vHxÄ?Lò„L®{d{­Œw8+˜Rñ(ÎÆjrÇ>­Ì—®¢U´�^ª”¡úÝrÛ#¿œiµðP6c‘šžLJ‹Tû�ɲ©Y«IµSÎÎx2„¤oÍÆ2?ÙÓ¢¯3ÛÛgfdž�n¸7[±¯§œdÜ3­Ñ¾9JQÊæD†ìé¡Gfts›â•jݽÜÉ.^[mV_×zmm=§gÙä0š¿ÙX..=kPé£Uö#¦æ-¢‚×PÖй<+ˆVù M· £WbOh<ãÒМÛ8‡Ë ¶t”êÐJF… ö¥fØ{ÌA>víöüX�„ßVûä÷êëeµ šeT�£”Øé �e`åø¡úJ�//ZPÄV²âýqËÔ'N‹ÊÏ(À‘Œü²#þMe¶©Íyk@¡„rFfþÇá¼…ƒÐ„ÉÎsÍwÊÛî•€Òä-%“ÓÌÐ_^÷xŠãú¯¢…p ^¡áîz¬‚åÑä¬ÐA¾•1êWØ•~³Lr¾¯²YWù‹µäq¬ÒU†#o„Òyi#VkЪ êes)Ú¦¥p¥4�P”~ªUc’¯ËÄË{~œ²ü.S²›ŠÝË]n·Ý:ÎÝ8>ñí³XÑÊí®½Zë×Ýêë‚Öë"·ÝÊ%fºßÎö° Pï B=ä¥PWQt§€h}l¯³ '5¾Uê±3ßví<ÅŽN§†$òç,Oc¾È͇HÝ�Ä2µ KîãV9ïpÞãÇÆãcïY-÷>µ hå{Ž'¾etxës-ÅGiâfæ“ù{ p•o!s¡U¬«„¶ò‰³‹MÀ«â<³8ø�žm›úð\RsJûàέÈÖ�z‹Õ3¬Â\RÅìz:¶g3«ùçû6ù~½HçÜ#œËÖª²†¶nDtØWµB¦–L ¨„.=ÎÛLt@Aý!úUe=–¬m~^2œ¶ð4Ås™´xŒNÒØ¿+÷ì±·Ô÷¸ ÷/a_þ:Fß5À+™<Ì% dWù!^hoâ ¿ƒÔ©+Wl•«/ÚiÖ\�‘íu¸Pàvvñ¶w<}LÌê~» °E…zØèX_¢CùÓã¹/œtŸA(yGú$ð Å�ƒ-=.ËÉÕ SLÿøÎšÜùó=šß#ôÜ^rÕ{ ýÐzÔã Àdd®MËZ2N²$m.X©`¬zJëPµ¤XýÙÅjà· [tß:ï•w�j±;ÐàÙ¢·ï¬Ù–¡à‰aëÃÈöç°‡Çé½;@nc§láv¡^gò7ÉoòôÜ[eek‹{X§â×ùŒM4Ì…Ôt5óˆRY‡ÑŒ [‰8°Šñ%¢^¼¨ªE«Þ²Â[·¹0BaPZêÉDŠiŠÉBg°LÐ{çn¾lF^Tù˃ô]÷ƒ�f$¯p_±zç¾[¿ÍØ%rI u®©cEE¹ù!lñ£>ZWnGëRg;°“+t[}uÝj`‡†®¼�@ØÒŒ‡�ªWexàðóÇ€çžcBðtàÚ(ðïæ–Èë»ø&ðÑ4'vÇÀã~9o“!.Ë=ÒçïÃøEô׸öîåHè¶lÍÒû׺‘¯½ WeFØôñ9žô§cÃέ²‚ÉÓ´hÅ�kI!ãOÒ“‹u§3”=q²Â ÙR5;3DziÛÛ>ÈçG¯ËÞ••e¨[ÇL¨z—XÈy„¤Þ ¡ÁÕ]Çüþw åkmq"”NÈÎ8¿m%®È‡pÁ‘cæ×¯£—[�>q¨Ç28ì¸Mغ®G¸a?9»j f}¬™YÅ„?c.`Ð]ÀœlÆÈŒ¬¢ôCýÍQ…\rŒªxU iÌêÅâ1�×"ˆÏž~58rZš1'–ƒŒëL¾‹ÂÝkª~w^a·ŸfAuš‹W�3Y6±‡Ú|�rë¶­\ÏV`«ì݆t¾A‹½_ |à~ÿLàÆäÉ/]~”°¿ø‹%$ð‰%‚”Æ’¡!ánn‚©Éu…oübŸ2 kohVžùúÃ}ì2&T?ÁHIKÀ—ò™N–Òã¶|¿éèä:ªß~,J*–Û#>±ìè^ñÿ<–¨]"QÔc±šŽ^ËÑ gÛãf!UapÛv¤¾s+õ­[”íGêÜ(ÔaËê²]ëuáCÏÖO/z<\ý}üâ¶o�“k¸ÆÔx´½á×>)üÜáÚÍ•ùªæPQ㦪dek]YØ Ú– J¹†*+Éu†š|¬ÂS€‚AX”eD6R-®BPß·2<%¦hðƒñ1ÐÄîå|w×G¾¾sÄ÷Ú¢anÛArÆ6M3õ[ÿN«^Okòç’ÿÂÚû>BG¹©44ç°˜Ë|’]§ðŒs”šc¤EÛ[LQRL~ö%Â×~½ßR*?€~×Ȫ�l(Z´Ô‡ÐzÛSؘh'œ¸×û âmrÕ·ÑËﲕ[rçJgI‰wË�^à%À ðfàîS;«›5רEüBwþpéô^Ðyïvg¼1oÄ �lß(/)Ž<ɶm�Œu�ÞÌmܬñ¯´€IDw߈s®ÆÌ¹|ôN`wèÊì0kÊ)ÝŒr+íxÙŒ–kÅ0ôªH‚íÌÚâ£ø;ŒªD+Øb%†K0 MÄgã®(Ô2CÅÞ›™ÉúÿbŒŸñßcÖ�Pe7ØÅ=ÕCÌÚ�¬ÎQ™h_½‰ògv û>‰\dßĔРxpyÕÇÉê£(«ëÂ5W(Ü®uê\±Ùv{=Œíöí:ÿu °yë,‰ü©øócæðà0i‹Ü9�÷x¢%®T\–‘g–¬p8,¶hÓûÔïz¾úÒ!ãæÔWî®úÀøÚ-ÎómJ+˜,#s·°ÞçbkzƒxÐï;3¦“JÚ.kj„Ê™o8åÿ îý‰ �“3䨩óØ?ŽëlS;úȸÏíè_´&ƒ0*eüÅÖë1wtæV€ýˆ>†�J“�Îêùn=Í›ýTe“m¿Ë:ªôa|†Ä:^„BƒPZ£*UŒö`ü‘Räxáé}‰gÍ.¿õjñ[@ëÛàš-;Íê+êºeH=¼¿:u®W1·+Z�!“$ò§ŽÍÀ߯ŸßÀ‘6X‰s%”ªµ&t™sŠ×W´h�êž/½l…h¡ºòÖ‚Ÿ~ýèðE÷ ä9=®A#«R�m1[µ§®SœÆÙ(Õ¬_öÿ"à1Qà¿›†dÁ5®ÈN0·ƒÖ;ÝpwÛ·I��Zß»GýQ`ëã)?„–‚4€Ñz�ï¯_ïä¦âwîW»$c¦’ëìíYÏ&›{¹ÈVt³®à|Úlò9›ÕÉy8V•óÈè!âªxÜü—ÍxoµEö@_¿òQò®©Ã¼eê—™Ùu�´Ø÷±[¸kg�]¼ŒÑÿîã�ÝÈøgžÄ4¿Ê_ÙZ°í'äýò¼”k¨ÇÒ@IäO }„íq½„DÒ´Ÿ˜Ç£Ö’)¡ÂœoSH‰¿ñ· ¾úò!ãgÔ÷ßæxÆ«GÏ»øÐ*1/9¹8^G¹‡‚CÕÉ‘–ž©xýòøW„Nì6±�˜ýÏvd~@]�¾šh¬é IDATÚ;¹ƒl¶oB¯<”zÝ¿ˆºòBЭ»Š�Pn»ùi »¯ÙëêuÝÊV3ʨ¬fµÙYß™ñ$úÉu–�¶ë™±çSÑ!z F7R•Þ–k�~ Ò+SZe„ ÔŠ¹ã)3<-”L´h™f±Kfš¥§âï5ïÜû¦oì«dìùR�̰¯Qá@ùSÃZà‘@¡líX¼�’ïFâ¿§YömRÅ»³Ý“u.õoÃV7�¢ÖÃþÏýR“[~g®©^*—ÿß©ÕZéŸ+Öd¼¤Ñ/Ôz •†§-òЖ~ÄÃtL¬€f^ÛÉŒJkJˆà7�«�÷ÿ™â1' 8²+A†]AÁõ(•4±Ý©1Ô3êÔç‹Ü¨„ÂÓRÿ‚ÄR·7CÙyÅNv‚î¼ýÏ´x: ¶mcçè�p3uüüý&ì®IzhööU¾S®,¾Ê¯+üþÌ!¥X,‚ATÔ£4%ôšP@\M„~1¬§É£ü4Î[¡4�Ñ9Ét2‰ü©a/ð?�G�u„õùGO"d½V¢°�E¡�çMFC`8 €"Ë“¢¤�çTœÃå–Ìy<Ó.)lF&¿ÿ³ÏŸá 2Œ¶Ýï¸àŸ¦WþØgÅ[Lî‚sÑRʾŒU´¥‘‡¶`=zãsÈh/¨’�‘ôÉ- 2à�þ/ð…4$'0hföϧªêý®ôÎN€ûŸK}�ñ$ Žï<^¿ß_½yÁÏ;�Ìßu€ŸBááÌM¶Ãœç¾‰oð½ÈîeZ/¿ÏiéEXÖJΠöÐKp$:ᇠøÌã�Áè †•IäO -BÁ›;b ®�ABÖýŠx¿1JPnˆÇ9B6þDôþG Yú#ñ±=Ñ@8žåžVX—yNk°^Qc0âÐB�\‘ûþë'Çùï׬¥ôл«dˇfk?ò™V>À ­Xò–§L#™8ŽÀÿ¡ÛߟNCrv3øÁÁ;^õÁW}æ n€m×ïD‰œÃ+{t—qïäpïaÖ7ûØ(%úŒ ¨šÕ&+¶x¤5FKLùSÏBqïˆîð­øørç¾…~sýó€ËbDàQÑ0è‰ÇÎÅhÀA`ÿ‚À�x?�ŽE¾„r»É£{ˆ¸g Æ�ª¢™Åz wpß-Oç“o9�2‡Á¯y~âµû‡/¿gP* T„l¶`¶ŸË¢jÜ$Î žþ¯�O¥á8û™¢�:Û•úêÔ©o«³ÚPo³•iÙÂ=sW\/lÝæ·îĬšP3±ßÉ-W`÷õ÷VÌôºö.I"jÅýx?/ü÷‰îÛÀ=ñ¶0:ÔiÒXVÅÀ†8Ÿù\€5„ä?!„ú'á ÃѸoA„`â8¯ÑÇ¿•"ÕݲX§AàsKV þàW?Á§Þ²FÊAÑlüðû­¿êžµÚË:5HµJ�úÔÛ q?ž<5zðÿ–†ãÜàÒK÷óüï‰ÔéÔ ¨ÇªÀõ0 ÔÙÊöP™È¡êa‡pë'Ußvëa®gâæ›ù^ù%îF.€YÂþ±T£ÀW€õÀ%„&çòž – ,ÐŒÇƈÁ¡x‰‡aû_¹ÀàHâ’”.xò™Å–…ñø}·^=Á ïZmæzÄË}pÉÇæÎ{Â÷µ Ú6VÁ+ ZÕœjQÒ›<ùÄžAèûñO„}ú.ž#|:ˆ»†ÒC¶3wjõ:ºýˆ×&ìíqÝ”í‚þ¤ŠK"¿t£r�{¡àv~ß$„ç5zí_;æ¹lùQÔ7Z'•ñ±K [9*ñØ6!p’°,p�FÀáh´âùç®×Y™_Úð„µw/ qG‰ZྯþÈŸÝqžL­1žƒžGüK£vÍûgÄ0xäÃVÔ‚8GÉixg�J‰/b>#˜¼MË4KžLÓ<ÞR”çb=°O‘Øìç¨*v[™¯ùkñ„ Á²=&†ãSÅ»%.ôô˜>ȱ £‡ãmw4^IÈø‡xLOôì‡Ëk ù«€'Fc ‡ÒoÅ皊â ãmj�pÖNJΣbâ'`|‰³`=¨d˜û¾|Õ(7üùjfV­ì�Ëÿrš+ÿi¢gÃÎ7�ÌyÕÓ[CÞíÂ� s½äßy¥ _|ò—O&t‹»øÇäÁŸ{ìßßéæÇ1¥€åØr¾Çô Xø 4‰|¢ hF‘–ãx&FÖÃÑØ﯌�Æ‹¬Œâ?NXÿï$ v–ÆâßZÖÌÍX'Ò))ƒªu­2Å6=ø­‹ñÉëÖÈÌ £•;=�ç¡¡§ÜÔGÆêÜ#YNµpçk.å•ßD.ºóµ+(¾y)Î Vóä#.1~øUà«À‡“À' IäS„àXA?Þñ £'r;9çÅÛÚx»xA4 #'3„ðGô-ˆtŠ-é‰ÍZw¤a¦z¼É±YFÞjãÞvá(ý›µvf…ñŒ+�ú§éÕ?~S¯XŒ žY†µ¶‡7N.ˆQÈË -ÊÒ ‚„rÚ‰%Ã5À¯_Þ¯!˜H"ŸH½ó»¹,Å=�Þ~Gü‡c4à‘1°2£„ä¿)æ·NÄŸÇ ˆÓg:P­aœÃź±—wà¶G䣵V&×ǨgÍ[þvÂd¬�ಠ×¢-ópê¼É°YŽÞ=d5�œ‡^e'qªx<ðË„¥´&�O$‘O, o3„­}ÇFrBÝÿþ(ö¢!0DØ.x%óÉ�~–ù¤ÀC„¤ÃN®À\<æ´U ´ñŠ·‚CV”÷í®à†¿X+‡7[aDuÝÍ%OyûÁ�ë†VI‘ ÆŒƒ3‘A¯_ø6Bî#ŠO­f—W/¾¼+^ÉDùIJG ýí(Ò{ãDw”¦Æ(@!쿉�¸:�e~¡Fcb6zþ£ñ~|A4 `~‡@wô`ŒÅZM¡tŽŸ~Û“iv}ôû&dˇÃYY‚f–LãñB0°X%Ô¡VÅËü¾‰ÓãÝKèGc¨�™†EPk°hù3Ìe„Žr·E�ŸMC’H"Ÿ8—pÌòÙËñ»nõEá_£çv Úq3™n,þ)æ+v¢S½;à~"8·—Öjxãñ*�u™Ñ1ü…ž^õ”«ícefÉUÑÒŨ‚ .c\ˆ(` Y§õ«ó§'¡O†…F9Þ‹6<…/1“êן).^ |ø3΂¤ÔDùDât0Ë|Á ã9a‡À†X��õ„¢AÄ%�Îsf~—À~æw ¦\ePL>•—‘2n}sÓÞ¯ût³ïïmdƒ ƒõgA¬!ÓXê¶Ó¦ïB¬\qó¦„5§'”/_üÜÿ÷h88D![µ˜B’/þUÑÀ|[øDùD¢{Š¢}”ö1¿Mp0Ã1ðˆh \ÍÑ¥ƒ½Ý3Õlbem™S¼i#ÈÍþçáXQL3k«äy/½EI!ƒðÒù?ÅHßN¤^�èqŸW¬GpämO)‚” â“ÄŸ6¿MØUòÖ$ð‰$ò‰Äé¡SDÂ/0ŽÝÝ–ÊÛh¬¶ ×øÏ<ÜC{í/’5wSØÙ¿ó|›þÉ;ð¶�jeÓ¨2íûð•ä¦�ÒôaÌ™© RÅŠAÔ£fþµàNSàÜ:´�¦�–”™!ó¡ÊžIífVÖ¿GØ%ò¶xŸH$‘O$&޼2>¶xð¤¢-—�ŠA»Q ùÔ^ÿCE§1v�¥t‡hÙi¤q®ÙBñXc0ÆàÅàµJCúÐlÖcóUXÓ‹‘"Obš¹Æ=íÑ$ =°•–ÈÓ㽑 [U¬W¼€É2rwœjwÚé1o�fPø›ÑÐà¨ðnBµÈD"‰|"q†¸ŒPbôI„:ÿU5ªÖåT/)JŸÓ“²šÜCö_‡A�º¯3”åaZ:~–ÜMbÝÖM!í½”³ÓÚć—^4_EÕ¬Âd+@zÛ�RÙ>„™©`%‹ßá°Ör÷¢wBÚ)�i1¾À—çrŒx/&,[7Óh°#ÐPÑ/<õÛAc¸#$¦HÀÉ ü«KCo t‡L$’È'gˆ•À;ëñG;Æ´´÷Ñ`<¸*ù‰dÎÄVɨ�U†èQPE�"ZPøuM¬o‘7ghë ™?„ãeqZLâÊ9âÅT°’SŠ¡‘`¤'+;Ln1¦okd"ˆ6"HÙÆ¹§`�Ã;P#ˆÆ†5¾ãÁ—%…„:ÆÄ�~\×P‚0ßE)yöÆð B^Çë“À'’È'gžÿy\�DE|µÔü‘˜èˉTÎ{TÁBîÁ;$†Å• ÖTȲþð%ë$çáñªxõ(¥G§‘r‚ÒM`Ü Y1‚ssTü½Hë6Ä7C<54¥Ÿ ‘å«Èì „~¨V�¡S¢mz¨™•PÀXÕáD!“#ûøU5Ft>Sñ(’ÿ@ G¾/zð»Ó�$’È'KCä�+_ƒ®u¾º'BUJ¼èñËÀ‹AÐ`xÅ› 8’ð·Ñi0”è-wŒØØ3²†äkɬï¹ÐO§- m�¹9ªL¡~Ó>DYŒÒnÜEé›FV†r7�·Š™ÕXßC£§›õ¢fdÖö“I lÏü{—hȈ ƉWÔ…jy�‰$%ïŸð»„í›oîLC’H"ŸH, ¾<ãx¿P”êe8S¥z$!î�N3˜NA+ÂÚ¸ú˜ø¶ÐcöŠÎw�$¸Þ .t°b1R#“áhLÓëQ2uh«ôú›ÿ€]ó½–Þ´žâË)›3�DËq,ã˸…ÏSR¡05¼ĘÓ‡ÚA¬íÇŠEm%CD°$�?=„B7„,ú]iHIä‰3OG¶ÝOÛ£îjî}ïUÌzÃJÎ8¡Ì)€#Gìƒ 0óž¿ëÊáHÜ_�d²z¾ë‚áCÈëÃbºv^�,8DÅbÅ‚©â†<ò('öà ÚoýZu xT›8?‹Ó&â›Tý^›˜Ö4Þ݃×êâhI“ �™^ÄöPdç‘›H '½=ˆäˆÔÈ%¾'¨ïË-xG^rLDÃë‰VŽx-qY_iúƆu2›Õ²ŠP.é<€ ð2B¦7*Ú%Iä‰%€? <—ûïFS;È?D†°Êx¤?ïkß‹?Ê„¸ÿ�óêr‹ã�ŽÕ™)Ìg¿ˆÁJ,Æã5-mŒX }XÛ7ÿ>dßkÍãq8- ª¾ nï&qå¾h �¯2‹ÃŠ%3YX^0…WfM?bVaì*r„¬±UŒ7ø#1ƒ‘h u^£µdV‘¢ 4‚ôöb[c³EYe†RJë�‡Aà•°3ãO“À'’È'K‹vÄÉš£|ãÀ÷Ìágs�ÚZ25G¶ã©‰¦C¶`@TBRžú)�9\9Eé§ñ~ŽLÇ�[ŽbZ÷ ÚF}“Giû‘Ê**Ù*2[ÃËJ¬ôâéÁQÅ{ƒ÷/,½TÝNW4 “øŒr©J|üð£ñúNú:%’È'K‡Þ'ëNØþFà½À£ã¤=Z{*üòÙºqLA]I)a;�˜¸ O%,-ˆÆ-t>åQTAL?ye�Jg¯½7a‹!…oÑÖ6ª-ú} ü ‡)ŠÃ”�Ô�†z,ƒÓC™ àòUx?Íš¹Y~ ËhI1åJFYz•â*Ào &}0 |"‰|"±´øÂúi¾ÀYýwBmñðGŽ,Aôìõã$ÏÈcu‚zÅY�˜àÖ‹¼ $ÓÐTÇ…]þÈ^zŽ3+½ÔL_3¯xU´F•ª÷¨€ÑÕYJ�Dµ�¥,P”“ QÊÓmYrÒªˆÁ«c–£»N#„\Š™xk=ÌÿÃÀuÀçÓ×)‘D>‘X:<‘^d~ùû?�·?ŒB±¤(=.ìßCò`ÐØè�)†Ó áûNÕ»øXÆïþHd@Ûï4{¤@èk�x”ŒÔèÑÕ 9’¯×COÿ_šúg}gëûÎÖ´6Ø2�!u¬&4z.&/ê_0¯5£Ðï#t0ßIp/÷_žõA`Uÿó5åÏ®ŒFA§Ša#Šýáx�ÀóKÏžþ_“À'’È'K‡Ëáøþ�ݼ6Nð‰åÇÀÌ÷ç9Ö–˜Š·½'8¿ �Î2Àp46 Åh€F¯ÿ“Qà?–†>‘D>‘X:\ \=·Žÿu`{øeË€w_êt·‘¾o‡ŽèܯÖFãðÛ„�~"‘D>‘XhôÊêq²î<ö à5ÑËK,?CˆÊT€§jÆ¿hŸÂë¦sßYH$–<& Aâc#¡}ìE »øcÂZkbù±…•©-xìÉÀ»Žy,‘H"ŸHœÅ×ôð&à’�ݼš�`•X~\ üa�üX®ŽBß—†)‘&ÄDbùÓ|ˆPwþX áÜ+‘XâôÅ ÿ1„¾ÝÏ\ð»•ÑÛû!æ¨Æ¢¿' ÝòÃ{ÖJ Ÿw‡_�¿óÒÈ%’È'Ë�àÏk³�ëúõÀ³!ú…¿SBѓ߾—†nùáp«œãÝ„ýí'Ë…Àû{ã‰$ò‰Ä2¡JØ6õ¸ã\Û| zð|7 ÝòDѺK¨» ^ëÓ(&’È'KŸœÐ<æñp}_À|ˆ~4 üíiè–/Ù½ÖòBN\Ðæ�ØDÝoN#™H"ŸH,å¹>ü��äñmÂ6¹äÁŸ —áðBàÎ.N_…þ’4’‰$ò‰ÄÒ¼nëÀSqN…£3ëËŸ1àeÀº8wˆÐó}KÆDùDbi]³o T5[ <;Š}âìax ÷oFs2 vd<6 c"‰|"qæšúÓº8w7aO|; ãYÇ4ðÛÀW»8·? ýÒ0&’È'gVàÿø¹.Îݼ”TÕîl¦üð¥.Îí!ìÐø‰4Œ‰$ò‰Ä™øßžÛŹ¢—w( ãÒÆ[D Æ·h{�× #Šb¯hÑ�¨f�\ �÷Í(ô7wñç+À›�ŸJŸD"‰|"ñðò2ày]œw�°^{ á2˜Œ <€ädÆ`DA‡7%ž&:=Ž+™Rj…œài àµÀ ]¼„< ýsÒ§‘H"ŸH<<¼xAç�BôûÒ.ÄãÄ`TQð9™È 6`�ÑùâÉ™ŸìrN|°-}"‰$ò‰Äéå¿ÖÅyÀïÐ]±”ÄB32‡Ç f…]ƒÓ^D2 =µšÉ©ÁTðú½òîÆÞ^üRúTIä‰ÓÃó�ßêRà_ Ü“†pyἆµx»ßsEVÃT*¸v‹9öÕù8 ÈådìBc¢w)ô/',%Iä‰SÈ/¯èâ¼éxÞ]i—>Ǫ´z<ŠÚa´v!ÎTèõÓ¨÷|cˆ�f §0E !íORèßMhNÓ ¿BHÜL$’È'§€Ÿ~·‹óf¢ç•:Ë-qÔ D=P5ˆ¢v-¦öH 1Td W¦ô#Üxð_zþsš]~zW6†u0kÈ"ÿìß¿X^@hKœæËDùDâ!ðB±›ÅNà�=Ò©ñÌr˜tª%®ƒÉãÁçýø�Kñ€mÍQ¶§ðìåßîùëìÏò»ÏkC˜¼�fÀTžwó§ÿx;<èzþñx.¡}±MŸ`"‰|"±xžEh ³Øk²IH’úFÂeâɃb+X Jçp¬@ª[ÐRÑ¢�1“Fùâè§xOmOÙΆöšF#÷C ™^¦¨5 íòÏØAÈÀ_,ÏŒçféSL$‘O$NžŸ"l[ZìõØŠü×Ò.¼„mr™`ðýøÞKh¹(©˜)ðù�æ¿òÖæw×Î6jPŽãÖ6äàà4ckL£¨éCx 7F¯¼ìâܧo#õ@H$‘O$NŠŸÞÈâàðº«Wž8³“ލÃ;ð ‘÷>’¶é¥* Œ£hïåËãŸãÅ·†faœZc–’i%²Ljù¢×ä�å&B™änz<xPKŸf"‰|"qbž¼‰Å‡?Ë(ðÿ�†pé¢ÄRµ x|'L�A”ô^J‘PÓÆ5°í¾=ýUþ´ýe¦JƵVdäµ1)§d./`¼áò}#å@Ï)™»þ›°£ÑŹWG¡ïKŸt"‰|"qž¼ƒÅ‡==¡—üÓ.m�{ßM¨K�Iw:ˆí½‚"«bü¾8Œ+÷ñÍæwxK~ãÚ‘¢† ÓD¦x¦ ß(PhP#Ó]­©�¯ºÎvqî•Àû�éÓN$‘O$æy,!˹[�ÿlÂå!ò¦ tj1&h>ôAïe´¤—Ì5‘ö4ʾ߾•· |äò} š­ÂÀÜÃõR¿A( 4ÙŹ—ÎKŸx"‰|"�®eñ뙞P�ü3i—Ô ’gd¦Ä»’Bû1µ-ø¼‡L07‹Ê÷Ì|—7r {öåwøbÔ­M£2ùTÃ?L/÷àÅt×­ð"B±�5éSO$‘OœËl¡»„%�žÿ i—•'/j1ƃDû°µ‹™«žæ$ÎŽpç}7ò‡îÜ3>]sÔ£ƒ®ö»™öÅšÚù/ý®èÑ�tqîÀuÀ¦ôÉ'’È'ÎE.¥»D%þ øXÂe8Á(”í²Šô?’v¾‚jY`ü âGØ5ý5^_ù&¦ƒJ£TŠ)­�ׯ¤ghÊ0Rº‡ù%ï^HwÍ�ÖÖè7§O>‘D>q.q1ð^`°‹sßüKÂ%ŽÅ¨„úó¢€AÔ"b—¡µK)í*r߆rZ#ìn‰7÷|¤voƒ9�S�ç…4˜ÒF‰6§ñ‹¨Q*Ù¼¸»‹s×.IE"‰|â\à|BÍðn2�?ü]Â¥�:</£YÈ¢§I[ß·±«-°:�oïæÓûyë¡ÏÞÕ ¡YÃô M™,GŠ"Ô–/ ´óóâ!t¿«‹s‡Éx[Ò•‘H"Ÿ8›y!|9ÜŹ×�†p™àƒÀwúÁ+(U²Ê¥�¯&£ å4Úž`ÒßÅ;åýµï 2•C9‘»éñA×(r]bïjœ�Œw[çºß=6]‰$ò‰³‘u„}7[‹> üUÂe4‘‹QEiÓÖ ¦z>[�wm`ÛáÐìnÞÚ¸�﵆L Ý'µ¢Æ`#¦8C¡ùcšÐÝð›]œÛ…þ é I$‘OœM¬%„Ú×uqî?ʼn1±ŒPJÕ*¨ï§Z»�vu5¢-ðã”åafZ÷òöÙÖþ_92ì™”e®�Ó3Ô°Ck–tÓ—Nã/wqnðNBùæD"‰|bÙ3EzCçî$dà'–º¨ƒŠÌ·öZÐö‚ö\LYY‹õ%Ö5±:Esvï˜ú'þ_�œSZ›(C;ÐèôȰ[â¥à›„fH_èâÜ ðfB#¦D"‰|bÙ²Š°Aç~øó ‰%‹€Jܯ¨Wœb¨RÉ.¢¬¬Åh ŠY`”éÖÞ3öϵÏåã¹oäS@FãHRÝÓ㸂1í®„üÃJ›Ðùó]œ›G¡NºˆIäË‘•„ínvqî¿o!TµK,a¼Ã‰‚1˜²¤À£›ÏT/Àõo¦Z´pnt”Ébï=øùõŸ/}m 0E–S«5–ó¼SD¡ÿT—óíë€méJJ$‘O,'¥j/îâÜÏG' ür˜0Lh \–ÆbmNÅ$;_ÝŒH/ ²â0s­}¼gÿß |zøëû[C2Þ¬ù¯ÂDîó¢8¨gÏpp-a™ª~øítU%’È'–"=Ñ“¹ª‹s¿ü!!‘)±Ä½ö#?ƒzƒ xgP{eïù81TÛm¬;Œ“C\?ò¡¡�f%:•CQÔ´F!Å>/)Ó¬vÖÍ;û„þÀ«Ó\œH"ŸXJT€·�ëâܯ�~Yø©j³°Ý;JŒÃK&«ñù¥øÌÐSÎàeœÂ�ññ{?“ý=å¸od9ƒE4è¬Áу? ÖäO$ôo§»Ü’ç¢Z6]t‰$ò‰3MþG»8÷›Qà[i—º¾£* ã=΀±Šˆ 2LÑ«¡F� IDATb Ÿ›¡°c8òñ½;³÷®ýzo‹<(5ä¶�o »%¨g;`IJ$‘O,ÊÄ›¶º=¹‹s¿¼’e°:öÁ H«Eɰ.CtÚs)*Ë ˜Y²™Q>½çýïÍÆÊâ S~xªP€©s³æÁ Àv ìâܧo#DÊÎu~( AùÄíÔ�ïâÜïG�ŸKø|ðŠ³‚Í,Yi@‡ðµ hC¥=EÛO£­þmì£\»F¦}Ù\«cÔ”5j9ç<ùŸ%¬³w³$õdBÕÇÚ9|éýp#çîõ“D>ñ�èxW•éV’èì:y}ô4Ë.Bñtúå…5dV0Îã*+ñSd957‹÷ ìì>>qø_xW~�‘ñZ9T$''l˜|¤t�ÆÚs¹zá’K»Yšº: }ß98nÏþØ<&} :iýçÜCâô¼8™hô°'€1`4ÞöZmN/"¬.–ÝÀï“iØ—ða0¢ Ï|=zu¡M‘ “U.§ô‚•RNãÛû¸aä:þñÙt×ý/‘Dþœç qY-æ�ÀúèÝ_ <ª„rµ]ü�=ÀK£¡�XÊxTƒù'˜ òâ!káÜ Lö¨xlÑÂ4'húƒÜR~’ws˜¢ÈrlShkÒ‡ÚôE[ø:¡è͵ÀŠEž{9ðÁh(:ËÇéi„” 5éY„ DùÄ"qÀA`¸#zóÇ® üzÏ?üB/ù&0ÛñÓÐ/A�÷xc0*€ÇK(tƒ"ý� õm�-G˜õ|¥}oŸþ3 bjS5­5¯�‡ŒúÄñønêk£a½."ìÁÿ�ø}=ù1àcÑ©XÈ�aB„1‘Dþ”ÓËÙ™(¦'ñ3Àu)ðs„D»_ŽžËÂå€Î2ÀhüâŒÊ4Ý­]J2N&zð�éÅJ/R½‚ÒVéiOQ0…×Yvþ$onÞÁLg{Ü 2>xL¥ÏáAøðbང<˜Åpp!·eïY6.?BØ‘p¼å üº+œH"ÿ üaôxßx¾÷7F‘_,{ =³wÇ/è0óKçk¹âÛÄqžî�÷û£1p8S?q/ Ë)@æïKƦv1�¼‡Jc’†�&+Gùîä©7ï¬ÍR+ep¼¦kkäž »DfRs¡“äà…Qè7.òÜõ„%¶ßŽß“³�ÇŸæ�—Ÿ•D>‰üéâà'¢ýÑ9ô¾ÿ„Ð4f±ŒV÷®øï¸/ ÇãîÜW€þx¿žÐ½nu46D#à§â—¿½üÙèõŒ·É8ÙMöÞOÑÝÞäsOÍ�¶’T‡ƒ¡z.¡ÁJªå È y1Áfnã Í›ÔÈ�‚Sº;Ÿò2 Y2ì#䪼xÄ"Ï] |ˆºßµÌÇáRàß�¡9î™ÑaH=.’ÈŸRza$û]9G„þ•„¤¼Å2 ü4pû ~¯ÇÜ·™OÈ;@HNZ(C6ƒqØ#DVÅÏ©Ÿo*zþ‡âm|îÃ1 Ј†Çƒy�g*jâ <¢¡ÀQƒž-xÛCUg?~Œ»çnç͓׳¦(¢ÈG3N‰’ŸXxô‹mÏÂ2ÀÁøs' Pr6÷µ÷ ¯¨UPƒ˜‚RzÉz~ˆÒÔ°Ú _Žp×Ô=¼±öµ;kyCÊbÝ0eË})br 'lM½–ÅwqÞMèK¿Ü¶˜m>GˆØ�,ÏN"ŸDþTó“Çyì÷¡û—�…Bðq²Y,“ÀÓ�¯�â×£'ð®eÁï„¥€½ˆî—¶ÿmŠ^ÿùÀ…Ѹv²;4 w§°ÏB�[øs•£—6Å haI` óuħ™_�»—Ù•sô³â¸Û—$*€Áhðê@«Hߣ(L/ø&RÎàËIîå«lŸùHí®,oP»÷W¬Ùejh£V¦)áñÔ ýË ìž°Ès{…v^|a‰¿Ïó€ÏG{±\¿Ÿ÷¥Ë%‰ü© ÷A¾lÿ;zô¿ÊòOôÚ ü‹/o<üìiø‡Uó¢w~g¼-ĺíU˜ß!p!IðB`�6¹Ú5ÌY6 8 x|¨q§B•ÊÅ´¥£ÆMኃÜ׺“?m|dð®"oP5m°Kkh#eøSOƒ)| ð”Ež[ÞL(;ýù%úþV¶Éméò|žçªÄ"IµëïÏ�rÿ¢ Çò|àï—¹‘ô\ÂÖ”Åö°n?=‡å6áë1·=VF`¸ ø"ðwÑÛz ð¼-oâç+kÙ½„½ö]ðóŸ‘XDµÔ€½˜fu5™ódn_ŒqÐïâÍ�¿¼­1ˆP Ùš†­åH#Ë�œÁ"ù§‰6ðBBÚbÉ£Ð?g ¾¯þ(ð�ˆÏóìt‰$‘?U\s’ÇýðÑ“0–"ÏŒ¿Ø»½ÿÏŸ%ŸõÉ. Üï˜u?NC N–þ7\ŽÔ£/ñÖbª½«ð½ë¨Je-¦™kŸ7¼!»½‘7ÈS å®Q 4 ¥Qè)T)€×ÿÖå\þ:`Ûz?5à„Dæ‡ÊÓ–é\›D~‹<Ñ£½~™]|OïÒ8éü§Ó%²ô‡WÀăªûáC�úLĵÐÖRìç�ßÅÛ[_à¶ÚÈ _KÞú™Äo>ÞÍÇNȸþx`'ÇObî6"ðäty$‘¨ô?¼Ès~øW–Gÿç§ÆÉ£g‘ç9àÑ*OžÜ²Pùø?E)q(ŠÀwŸLqhcÛ9Å™ ÔŒ3Ûá]‡ÿ™›9ŒË†ÆLN/Å9ÝÎ|Iý[ [ºúWv�),ayëT‡ØŸ•.�Å“Lö£y2óÙÔ‹áQŽ¥[ï¾Ó¢�ÿ•±H,'‘(Cûز3øC”_y6æ+¯DËÏPŒü7Ú˜äß[Ÿ°»Yãó‘áÃEmN`Lz°ÓEª2vQBÝŠà·º8ÿW¢à¿÷ 8ŽÃéY6x6!A1‘D¾kJhé©„= ÏâøuÖÏ$O$$¿ôwáQü:¡Çsb¹‰DðßU«ØÞËhg›@[X?‡�ž`êð?ËÞ¼ÍÕûcnÔ·sYÃL–î›�¶Àu � ÍÐ]#¡D÷üŸ8æÝxæ/ ìzÏ–_!Ô×ÿ¥Óôü——°üKú&‘?ƒ\s "7F¡Ÿ\"ïé*¼ ĉ<‰—Ân‰¥ªä‚ˆ¢êƒÇ.áß8ð^ÀV°ÕK)z/Æë§ðæå“îã Ÿoë‹C¬hŒ³kWSúK=åÚ¬õø‹ [{ Ñ-GØY1F¨=0ï÷0_:x–�»‘ÖœZþ–!ü}_“Ṅ¥Ä‡£ÑÖ_ªø�NžE(”H"¿hú P*?JÈ>:g¾òc�ϲøÖJ(sû¡tY,q:âv¾‹¢¨x@ÐÚE¸ìR�RÇëò¼÷bñyæä6š;wê uÙK þ¨]*QVz<"ÞÖŠ]FÈ_ ,•Qìç¢ç?ï;턲ÇÛ¤f#Ýð/qŒ_Íâs©žçú‰ÓøúÞLÈ8Ý$‘O"ß5O!ì7=<¸) ýèz?—–†»8÷�a·Ä’wåQÑN’�GKPo¡w3ô_�i7�)Ç)~öƒøÇ}ŽÊ>�Û²¥^î vAǰëÐññ¶¸ã^ä*B± UÑØH¨¸)k<ÿdŒŒGƒàÞ(þã„jfMî_³ 1Ï¿F#ªÎâë[<�ЧátlýcÂÖ¿‡ƒk¢C6“.‡$òÝ\<§’+ cž¿\'�ää»<Ëk E_Ë�…_Y,¦v!ô=šÃm3OýšOúƒU=ôØí[ëÂõP—û…×õ"<ÇÒíÑi$ôHBø-a]u=!fÿ{g%WUçñÏ}UÕÝIwÈž�•�°%a'€ìÝ, ²8$£p™‘mDuFñ蘊ãa@œQTœ#0ˆt†n•ÁDVÂ8D`BXLBÒI/I/UïÝùãÞ¢š¦“tUoU¯¾ŸsÞIºöwß»÷{¿û»¿_~)© çýjö‹Mþÿ¹úmPñõlô¯k)—Ù.¬&‘šN4faÔI¢«…�‰ªÆvñ­cïfQmhN �5I›1M@Úä|Cf9wúIîÛ8k4�Ëk>Ëß³³�¹8Ô±þ±:òÕ sVÿ6\ÉÖ�þ±ò•ãΣ8·ýužïbo\ŒÎ9¸úáWØj ,–ÈKä e .@m(8x 8xuˆÏc6n ~FïýÜ#Фw%ëåÙ„DÙˆÐ$I¤f`÷:ˆÎ`QØFjÜNn©y’k“aòžN"[c1ÝÑ%_úA@ÓåÑ0fßï]TÈâÖ™ßÚÅ$8…‹¯Â¹ÿçzOÀL?)8—}n�ºÛ‹ü;ÞÐs) Å?×F0áÇÐΣ6ÇO¦ópž»ù~b?Ú‹{'Îíÿù-‚›pKÍ~’Plêà·�+½ÐÏ,ð½³€Gp¹=z‡áÊߎ)¡k”ð†Ò]º]%ò{¢~„¾wDäwׅ˱¤—žI_flöfyn†~bгåòýwàÖí_Æm}ëIÊ h�ŸìïÿÍ-ì'õ5¾Ÿæ õL¼ÍO ¶ú¾Ý‚‹ºÿ.p@ÆÇopÛÔ6áâ}¦–h›Ÿ�Û:©ûZ"¿K&ø™ôHR¬Ä•©}x¯…KqJß³ø"yW ÁÔy¸#J…�È �ËQ€ €Œ%¢†hÌ0¶šdØÑVBÛʳ£j¸øë7ÐL“ŤW`ÓjÆž ô\3Éx1Ý„ |û}¯ïǪÉäwÌÁí8Õ?ø×æŠ5Ïá\ì…&ÆÊ-¶–°ÀãÏûè^!‘'Sx±‡¡ Ö[çà\ø}Q…[K?µˆÏ·Ý䛸ұ›p[ù–ã2gíÊŠï½6iwñx_ƒ˜<ÅcL.U­Ád,6YG°× ˜( ;ì &jÁ˜V^xc<—œ»‰æÉ‡ih\f¡É’^®V,}«÷÷@¾å"úwUbµÆOruööž€}qy9r¹ a”?J�ÅùÝTøù×—Ðoí­ôóúx.…«Bµ¤ˆÏ}ÜO¾í;íÕ8Þü„â™]Ìä§û×MôƒÍ4ß^’Ï™=½ÇDÑøA¦V?à^i¬‹µI‚`<ÉÑ'aMA¢‹êÌ6·°vöL.>wš–¥m}+­5VÑuñ˜ô·åR?Ü� ¼û2ðQ\v»½šÂ4¥"òB"¿KJì÷T�¸Ð9¸šî*âóžÄ­[µoz¡?ø>.xçVè3ë"?©ø!.¸ïà'Þ ð=ÜþÔ\®û�ø÷Lð¯?DÝj€øÄ7ŒM‘ Ç`k�`G²íÀvµbÌf^JÕrùW­þSÓ:ç�7Hc›l?SØ5©©cî%ÈMÚ½þ<†ç{…o”ÈWqA-¥FNè/öð×E|μåß֣ïÂ%9Úwø�þñ.¸g/OLö¢ýUœ«?é'Ÿ~ŠsõG¸5ÄspÉ1÷¯ËE‹=à3Õb-6²X›{8Àd#²Yˆl5Ñø#É&&P“é êÚ†Ínáå1u\rÈ™KŸk° !i¢4éÈÅê»´¿�HKu b*ð¶�£ Xæ †˜u#ÎÔ¥—È÷E} Ÿ¸Ý ìEE¼ÿy\b‹m½?À ø;¸èüÜšÛ9¸ä8?ò–{„‹~Ü[úOâÜôÿ |Ì3ç«|w–Ýu«~�È\%¹À¸ òÖÙˆ(�ª1cŽÇ˜±$³m„´�´[X�aÙ¯ò| mÏâ2ƼûyZ.}â¼q·Åì¼ä²—ÈïRäK™ÅEÑ¿è·¹× ¿¸·n÷ÜZÝùþùGpE.¾ëßo{xj€¯ã’eü§ ZüsÂñ}Ê{E¢°µÄŠ&²^”Á‹Kxã×à‰'ƒMí… w� [HD[Ø0&ࣷý�u—¯jŒ–6¦�µðšÈ]_©Bÿ)F¦DìPñAòqBB"_6"_ /ã¢ï7öz<…Ëm½7®¤ìƒ¸"Wx+|+nŸþïzˆ{Žj\ÐÝS8Wÿá¸-=)ÜöŸ‡pŽßˆ÷ý7é­ï�ÆúìôÕ‹ÈÚ‰ºühÉ`+» ]p^úù†åØ¥,cé@Ýír×Wîçp¿“óÙ —æVHäße2Åå{/eÖã û*9·�æFÿ:‹‹À}·¾nz /‘¯ðÔ‚‹ X Ü€KƱÆÏžÁÜÙ‰K{Ù¡.ՌɯÉ[6À˜*‚ÚCéªÞ‡T¦“ÙJ”ÝÌAÀGΟïÓ�®À66­6Ë ‘<óbcÿÜ��\ö» R÷Éׯà°7¼è¾½‹ç[€ÏóÞLw;È×�ï©øE¯Çn%Ÿ>²Í[ñ¦Ç,ú5oÑ+à® •ÇØ0am’Dí<ÚköaT¦ƒ ØŠíÚʶÀò·/ßÁ“/5¥-À 0ÆþVXƒ1Êö% ¿óàïSÊ"ÿ�º´ùž"Þôü«{x]W/k�¢O¯ç²}<ÖÒãï\9ÍÓp1ÀEÕˬÜ6gÁ»¼³®º\Hh«IŽY@¶j.£³Ýû™Î:ª’|¶a#�®o$2Ɖ<ËÒþ¢`¾‰[¾‹ p¹ú_Ñå}/•ê®oˆÉylÂUbÚ0Bzµø\ÀžJŸôÓ„²‘ÛâDXaÃ$Á¨d«ç‘ˆº0f+d[ÈÔ>}ø’¥wÝ|y:‰ï*‘k�ˆé¹�¥Ë+K\îçƒbp;qAv/Ž�ÀƒsÓ¿®nÔë·öþn��ÁtG„‰$‰ °É¹˜îB³� ÛL‡ ùò´1ܵ´±‰…ëš0Ë-˜AVzÞU_Åe‹+‹q±F¢Â-ùS‰ÇÚñhÜV¸‘>m™Û“õîìL.ÛM@` &•$L6¹?DÝ$3­˜îmìŒ2|ñãÏòïõ éhÙº´]žÆZW£Fˆbù,ðÏ1?Ç ÏÑ/K>†ÔÇè\®Àí§¿•[,]KÞb ` CŒMÀ¨ydFÏ%‘íĆ­Dæ/´Ë?M>Š-?5Æ6`M.gŽìDÑ|øNœç(?¾ß§K^Ù–|}ÌÎçR\ªÊ¤nçÒ$ ð*�ÍDd�ÅVÍ¡#1t`ÃáfvŒJ°|æaüdzÒ]Æ6„Ë,�ÁXm•Er1nwL¥ì|Y¢K^Ù"? —ž5n\$¡/áNbƒÈ×…O’¬žcæS•êÄtï ‘ÝHg"Ãu‹rËš}é2¤# CÔd�\Næçw!p.ß¼(¬ÁD 3 î02Q7Q×NL¸c:øÞ!ûq-�`—-�Œ5y1PN~‰KI]‰Èe/K>ö7ø=ä+̉&a¡j:fÂ"BRQ �ÝDÖ´sû¾û’n\h#k¬« OzøÜòÚ'G>ྒ'úJq[¡"?WŒ¥8 ¸WyNŒ¤o±L'{!¢Žvl¶²Û¸5ªã c¿AgÃjƒ± �Á’Î,vÚ'7ÇE–Wz¿?§Û¡òDþÔ »¶§ø?F·ùð� °�…LDh,$¦ckŽ#-„m@3&ÚÊ]£góÕWΰ­MM„kê aMƦÍ0n…”%'Vá*DV:Iàt5Cå‰|C^ß“€‡Õñ‡©3…ØDÙÈb f*Qídjº°a¶k6lágÀÕ ¿M‹É¥Çq‘ôŠžŲ®|ôD5Å»Èe_�"__¡×øh\…8 C�Kr„¤ÆÕëÍv’èn%ènænÆsùýë—6/\(QƒÂ,ß¿§©)ÞÃ*·6KEŠü,âU;¹PŽÂ¹ò&é–:¬$‚Zºã‰LD˜ÍP•iÆ&šùÅ!Ó¸òµút+K›"–ƒµ#œ DkòåÎT/ðsÔïc p¤š¡rDþT]jÑŒˆ�ù:ì˜cè& ‘í ‘x�ÎìfV~W­<©±ÒÖËrc1#í¢×š|93ø-ñLî5˜Ö¼D¾Bγ^—€ùÀj`†šb€g‰œõîÓט` Œ;†lr/FGín|vkê¦rÕÂ&6¯`�M“+Vc ²äEqŒ@I_ö„Ö婜lHù<�§¯ª9Šc³ÅF‘±DÕ ‰L)ÛBÔÝN"ÚÄok§pùO±oLNâÓÈ¥«¢0j�•ÈÝá–46É’�7û¢5«¾Úd50OMQ$/�1 &2®N\TM*Ü�íÞFd·ðBÝ$®:¾–�Æ®P{‰Á`”øÕýÖ·3Õ²â+•}¼Ðﯦ(œ1 Ie«H¤BŸ¶Ö™6¢p„m¼2®–¥ë¸È†Ö,W$½(UÀÏ4žLÅ»ì+AätŸï’Y¸`¼…jŠÂȾB ™ ™D‚ªîvÈ6óÚøj>qîã¼”n 4 š3b $€;%XEq^´«DþÝç»eo\”î¡jŠþc"µñbÔÍŽÌNÚéæÏa+/�ªá¢gÎäé5Ë Ò¤ iSºg]_.cô(L²XÆÇUrÄ=ðn®ô Ø=S€5¸õ«§Õ{æ±Év缇Ìe㦲_ÍVº¶¾AP½“hÝ•¼`°XLhlk¬1ËKTæ%¥Žn.RS ˆÅ8�¥D>†ÈU߯ãRcž<¥æØÓèkBΠXëãw�|0äÌwƒé�r¢|¹ø5ÀY\S©'ww}½îï‚ü8^MQÈ]_Ê\|AÍ0(L{t%ò¢LÅ3`"IDAT7c½E¯,�ýÇö8ʹëK•¯_R3 *´g‘ßev+–Zà^T®Qˆáæï%V�ÈKäû�ÖãÆh\â�sÕB WßV3 §5ùxQ¯ûzÀTãVn/PSÄ­É——7�Â4‡Ðh©HM�È‹=QÜ\¨¦bHø0pª>ÔT¤Ë>®7ÕA¨¤ê`’þ ø˜š"F(ð®8Ñ÷­¤šbÈ©ÈÒ³qy­Ç> omhß®ƒÇcÀ\œ»þfàE5É�1×€E\g�õºŸ‡LèoÅ­o}_Í!Ä ð&.7ý�þï)À±À ¸.G Wþ`±¸Ò&Rq¼q ÊW?Ôíû]àj5E™£À»Re3n ë5¸šèã€3€ë�Ç�n5Ñ€D^–|™3˜ª{yÈ…þ“ÀýÀKjŽ2EkòåB°ÊàòX‡[Ï?Áÿ[£fê'ã~µHäË­Ç Ûý ó.õí›j!F„½Dpy÷þ þ1ñ~R¸=ó?—È—/õº��u8·á*\'¹ ãD“¬ù˜Ð� à{ çÒO‡õ°ôÏÀ¹ü…c±D¾|18wŒ(Ž­¸Úò«€_o©IbŒ>®dqÕ×7âfêaéŸ L¬p‘7”[­ ‰<ઠMQï7ðò®¿5~€BćxÁ7ûÇæzÁ?çýœUAí1 8Ü�}ù2Cëñ{æ/æ«€_Õ$BT¼à÷ýœ{ÿƒÀœ˜Ÿÿ‰|yR¯¾Ûç,þ9\±™{�g©7•¢ ÑßÜÑCôOÆmG> ˜³ó] |C"_^3 Ø„« /ð.2^! ýÛýß{ûñ5gíIyÓ9·´»Y"_> LªÐ™ž" /k]1˜lÄíÇÈ¥PšâE?gíBy%W pËwJäˇJ[�Õ[é«pûÖ[5 !†‰ÍÀÝþã­ã\0ßѸ –¥Ì‰|yQókÕ�Ki™‹„_«qF 퓃G9fåû0.iP‡D¾ô ˆçþø =:Îý@»Æ!DÐ;+_ ·¤š³ôOöáßX,~,‘/}ÆÇàüc¾31ôÈU/F޾²òA>�ïD`Â0üŽ%ÀW$ò¥O9ݵã’ÑÜ‹sÁÿYý]Qá„À3þø7ÿØpdå; ˜ ¼!‘/]”öþø·¥íüÞßÐBŒ, ¼¥Mï¬|ñÞm{ƒ%úgõø‰| r®>p)±X� :Y ¼­þ*J ¼(/^ôÇ-þïéä×óOæS\‚žÅy U{"—:6'êOx ^!ÄÐð6ïMÐSlV¾Ó�j K"_š|l„¾w3ð;/ê+�fõ9QVÈ]/âEï¬|“q[ä>ìEüÜV¾ÞÔâ–’È—æï¯fk]…^„¢ôy¸ÉuÀzXú'“ÏÊ·X"_š‰K§8T¼N>`îa\V'!â�¬xQY´óÞ=uÀñ^ì§Çõ¤Ë]ä{ë\'ðnÏúýÀŸÔ/„"¶¢ÿ ?b‹Dþ½©cUèETZ“"ö$Ëü·_Äûzz¹X§Û@T$x!$ò%ÌÑô=>g­¯ÄWtêÒ !„�È—.»sÕïÀe–Û|W{]!„�È— õ}Xë¹ím�ݺ¼B!$òåG®6qNÔïÞÔå¢x'„D¾D �¨Ð‹Å#�B"_Â"/„BˆÝ¨ „¨PšÔBHä…ñDîz!$òBYòB‰¼B–¼B"/„B‰¼bh�»^‰¼"¦È]/„D^!„y!„BHä…B!‘B!„D^!„y!„¶Ð !‘BÄm¡B"/„�%/„�È !dÉ !Jˆä0}Ï )B S™j˜ S™ sác4ÀÔ ¼ŽÝwág¹�«¦ZÀªÅ„vŽŽ/1ƒèuÍ„BˆAálà�Ág!„Bĉ¼B!‘ß-ˆÔœB!Ä 0(Kàƒ)òtM„BˆAa})‰<Àuº&B!Ä€¹ xu0>(1ˆ?ê9?i8­õ !„Åð+àR s0>Ì Áœã…¾V×Jˆ‘aLó„f&4O yf3û½YœOûgfbæc,¯[󸽓ì�ë£ –æfí“bäéÖÿ­¦Bì‹5XŒÿ7x†ËR·Âƒ¿&°÷ì�HÜjI`­Qk _äVB!$òB!„�È !„B"/„B‰¼B!$òB!„�È Q)˜^…ã›ðÕå…y!D™‘6éÜŸöý^/„D^QnF»H[€`Žò�Ýø#"`EÊt'DÌùÚ ÓJtÁIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/extend_3D_coordinate_system_YZ.png0000644000175000017500000020607415143647637027047 0ustar00paynopayno‰PNG  IHDRùô>(T:ÇzTXtRaw profile type exifxÚmPAÄ ¼ûŠ}‚ZxŽÝÚd°ÏߩФmv™tDÒø~öô:@E’ÔE›µ–11êš}Æ’eƉÝB•{>í’À f/hs.g>.œ\:T½é; ë½`âLú0Їøèˆ ¶0²0bòB ƒîßÊÍt¹~aùõ•ŽðÓ;—xí¹—ÓÛ*’L4iDfñøX5q‡0Db4…C ]YgF£ äßœN¤ì-ZTˆŠi™„iCCPICC profilexœ}‘=HÃ@Å_SÅ¯ŠƒE2T'»¨¨8Õ*¡B¨Zu0¹ô š4$).Ž‚kÁÁ�Ūƒ‹³®®‚ øâ.8)ºH‰ÿK -b=8îÇ»{�»w€P-2Íj‹šn›‰XTL¥WÅŽWta=˜Æ¬Ì,cN’âh9¾îáãë]˜gµ>÷çèU3|"q„¦M¼A<µiœ÷‰ƒ,/«ÄçÄc&]�ø‘ëŠÇoœs. <3h&óÄAb1×ÄJ³¼©O‡TM§|!å±Êy‹³V,³ú=ù }e™ë4‡Ã"– A„‚2 (ÂF˜V� Ú�¶ð¹~‰\ ¹ `äX@ d×þ¿»µ²ã^R ´¿8ÎÇб Ô*Žó}ì8µÀÿ \é © Ì|’^ih¡# o¸¸nhÊp¹ >²)»’Ÿ¦�ÍïgôMi ÿè^óz«ïãôHRWñààÍQöz‹ww6÷öï™z?%ÙrîçÀ V[iTXtXML:com.adobe.xmp fÁ02bKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEé  :w»°ü IDATxÚì½y˜eUu°ÿ®}ιCUWWõP= 85QAEã@âµ;ú#Q£5Fû¶Ñß§ h¢‰ŠC4N‘.QD„VZDPdM£"ô<ÏÝ5Ü᜽×ï�sª»º«ºª»†õ>Ï¥‹ªº·îÝgx÷Ú{íµÁ0ŒIÍÍTžðYäöë`F­†CTÅZÆ0&?ΚÀ0&7›ãÆSç#Ϻ;ádj ù·Mò†a’7 c Kb¥æ„›5®ÝLŒjÔ,ñû1¡<7­^ÀÍ8E{Ä$o†aÆñ5ªŽ]éR¢•+‰®†Ÿ^ájª=\ù¦¤F-²7 Ã0 c‚HjêÐ¥Q!qùd…'\‡ë»ÂÕ¸WžJg�¢3`ƤÇ.tØ$ˆ"Z­Ñ£ºA×$ÕÏ „*€J˜ßÚÄ“k ôôX$o&yÃ0&˥ȭ[½3LýA" TºRwwÞsß2µ–2 “¼a†H ‘ZMV×_ô‘'œhŒj¢Ž– Ï㺳•ÅK-’7Œ)€]è†1YКSÑÅ‚,Õ›Jò”-¹;-µ©sMÐ6¼ð©ÊãÖD†1¶¨"Š ª¢Š ¸0ý¼oAóZßÀõ~¶ÄÓQµ�© ãÄó—�áÍ—Z$o†a†IÞ0 Ã0Lò†a†a˜ä Ã0 Ã0Ɇa†a’7 c4±TzÃ0Ɇa†a’7 Ã0 Ã$oÆ G­ Ã$o†a†IÞ0 Ã0 “¼a'Ë®7 “¼a†a&yÃ0&–xg&yÃ0 Ã0Lò'ŒßæØ!3 Ã0ŒÉ'ù7;€�+�¥Àt;„†a†1ñ%¿ªø÷TàMÀJ`p'ð!àb Í©a†aL\É%ž ¼¸ è~Uüÿ³íð†a&ù‰Á/€í�ãó<µˆìï¶ÿ›€v¸ Ã0Œ!t™äÇ ü`˜Ï™O>w%°…#çó;ìü6 ØR´‘Oí‚Û�K'óŽ'Øû]üÉ1<p>ÿM@¸µxÍUÀ=@°kÀ˜lXÅ;c SÎ(Ä~1pP>êwn2É�/É�æÁ<𻋑‚A鯳ëÃ0 cÂqjq_ÿ+ài�á¹ÀðGˆMòcÈ&à7ÀSÆàµgËŠÀÚ!Âÿ>°×®c"bïŒIÎ|àüBì/ ã¹w»Lòã‹[ÆHò×ÚäÃùƒÒ¿•|¸ß0 Ã8¾Ì&O–;x>Ƕ’ê¦ÉÞXQò'"¢vʼn4¸\¯ü›Ï7&6'oLpÚÉçÒ_T<žÅè%�›äÇ!ÞD'ð=Tyè|þÍ…ðoÖÛui†1b/�[Ü__œ”Æàïô·™äǽÀO�ç�£÷4›|YÞÒâÿïåß ì·ëÖ8QØœ¼18uHàôb ë8üÍM“üødÕ8“üÑ<¹x¼ðÀχHÿGSáÄ2 ÃxŽ%Yn´¸e*4ôD•ü÷�÷M�÷qä|þùÑ ôï¶`Ë0ŒINðœ!Ñúx(;¾Õ$?~¹è¦MÀ÷ÞÆ‘óùÛ‹NË*ò$�-v?0 c‚S%Ï|¼×�Åøª°ºø²I~ü’’ϧ¼bƒyäeK+]Ÿ6ŸoÆÄpÉ9΀.­,7ž¸–)2‚Oà÷¾j’Hþh†®Ï·ù|㘱%tÆÞ«.ò˜1�Þû�S©÷5‘%?Ù±ù|㘱Ä%摯W¿xpÒ¾$~0UÚD–ü`y–æTáèùü�äÓ«€ï’—ý5 à f’W–‚ò$ù\�gÛr“ü8é�­^7…/Â9¹>è|þ�À»O†ñ8š,w>y6|< ?ç�Sé Nô8Õ%4�6Ÿ в&2 £ Îäðèàùä»sNvnšJy2H^±Ü¢Gº€‡Îç÷“/=´ùü)†]ÆQ�ÀDM– 䌙ä'[�_‹íÚ}LÚ9r>Gݯ®6[MN¬'7¥š,÷Ràä)Þ·�o0f’Ÿ@Üd’syäùüï­‰ cÂ1�|C—Áýï`ƒ9GûbJ1$¿ øk;w�™¡óùMíßÜE>ÇoL@ì?©©’OÉ &Ì]$Ö,&ùÉ$ù’WÀ³{ô(KŠÇ€}ä»é}ø/kž‰… ×O*¦j²Üh°ƒ|ùœI~‚1¸õìùv�3€K€/XSÆqgh²Ü‹Èׯ#‹â§\Ÿw²¬�\e’SZÀkÈë=†1¶Ì^€%Ë�…ä§ñ$:x5;‡Ç„&ð*ò |Ã0FŸ.ެ,÷Tk’Qg°xšI~‚ryu·N;—G=‚_j‚7Œ1¡ \¼�|®Ý;Ö0Eö�?7I>GFž€gŒ®àmˆÞ0ÆŽ:ð.l¹êñàÆ©úÁÝ$ú,«ì<5šÀ˜à'¶„n\s7ðbò,ÆØqÓTýà&yãá"x¢ŸDL tâ©Ú¹ x…Eôc´üÈ$?ñùVšÕ"xc¢#G=¦ ·“gÒ÷Ú)0êü˜|EóÁ[oŒž4E£úÛ�—}v Œ*7Må?Ù$ÿ};ŸG,xK²3Ndä>È»‹›ò¦h{Üj½IÞ$ÿèÓªxšà�‰y/z+ðf D^Zyª^Ë?^fý¨°¸Ç$?yØü¯�×&xcÂ݇Þü-ðë¨ýïÖÇÄ* ˜ä'ßA5LðF�ŒÏ·4øpÀŸ“Óÿ¨x˜äsV“Ý[D?rnœê `’7ÁÆñF�ŠàßE>ý kš‡ð#,Ï|`’?‚’/3LðÆø ‹xm!ø;€¦ø°êcˆþLáe`#ä×ÀF“ü䣸‰�ß&xcÜÊ]È7=ZN^ñí*ücr y ‹º5ÅãæFk‚É)y°!¼1^ðûÀå…࿤Ö4�‹›€W kŠÇÝ^&y“¼ Þ0Ž£àŸ|øðòÍ¥ ýh“’�~˜ä'éçú¶áƒ Þ/rüs�Ï‘— þªEð#æFàÿ˜è•Û±½&µä=ùò¼ Þ,{âß‚Ï>l*"xü±ñ=ò9zýÃcCõ“\ò`%nMðƉîW þû,à³À.à3Øê—Ñâ†BôÖžŒä§rOÎoFŸ@Ñ?³»ÿmB2Ñö‘oßkLrÉ߬7ÁÆ ãéEÈ‡ê­ ËØð]ò%‰&úœï“OÙ“\ò�×Á6ÁÆñ‰Ü‡&Ù�ü�ŸöcåjÇ’ëMô‡°ùø)$ù©´”Îo<¢}�3§�gÏÇÀÇ€½vŽ›èÿKj´%ÔSHò715*i™à�GD�[¾ ü°ÓŽÀqåÀMaÑ?¬µÓ`êH~7ð ¼aŒÙ ÁÐÇŒBìUò9øÖD'LôÌÔ,4dYõSLò0¹‡nLðÆã2ñq`&ði`q!x‹àO,WOQÑÛ|¼IÞo£Ly-ú§aCô㉯“ÏÑOÑgÀÍvاžäoaòU…2Á�›Qž“š¼wL> œW~£µø¸¢¸tŠˆþà€ò©'ù:p› Þ0FµÏ @ðïÀEä¥j7YóŒKVNÑÛPý•TP¤¦8Õâü8üÿ ŠwÔãÐ÷ò§éàïGv©Mšso9ù†(_aråºL%¾0 Eoóñ�@<…>ë*àÕ“Lô�ïìõÈ’Gµu"¢é•*±ÅÜÜÊŸ¥§âXK`•<ð[‘?_W­X�Öjª5ÍãB‘"ùJ&o[$²�@PPdJT·èè�so–üíÖ²šÏ�ä+#&6o’Ÿt=½Ç%úCÎV5‘ËV¨‡[ž0�ûšLk-ûð²��ߥ¡s×áé!e)aE1Ê»f)ôH®óÕH4GqkÀ/CUW,G%$(FDE /(‘‚?Ô90&â¹öVàoÈ×^ßVôÄšfÂ2øóIòYÖ“—³5¦¸äÖOœZ¢WzT+Zá‹3"ÚnÞÅ¢nhß'wݽ~Μ°¶ân*g;ÛLNÛÈ¢íÛ_òêWö=ï:”5d²f™gáæ áŒ9DwÖE…šGjÔŠžDMPjHMEƒ,=Dü‰CŽý©¯Þ|‡¼îÄ1¾¬q‚™K¾âè ‹âMò“�UÀ_L¥ˆ^–+k*góé2 ûžé·Î> i8´Õ‚ƒ)!¢)'Cª*ëæèªËïÜóýËY/ìÜáÖ)wÿE¬ÝFµk#ís7.ÙýŽ]«‹y½K Y¾ wß"ü�AM‘š Ó�ޱwõzòyøë€ïYkšàÇ!6o’Ÿ0’o‘×ÿ~ ÃKн_<Òò¢+WÂêšÈ=µÿx?;ç?� *8Q)þŒ¤‚6í%pQ¤\7$ å"r;M©§žÆ�ð#Þ5àøÿ6פ²¶Fc#®}c)lØ0ƒµ[híhžþ±�úÛ·§ô ²lR.Û™ì‘üŸ‚ÿ1¶}çdüÈ÷˜,øâ3&y(z°�ñ¹ª`h%»{�+G(z"ú¥ÐBí¤…¤¥ó@—)¡1«O2’Úbp‘ä}UEh´¡ÅÏ$BãÈ;ºÐƒ]ÐÿtÔ�6hIU[<Ë£ÓRy jˆ»sQÿzÜÞ mÒõ ò›­¥,ÛÕ"Ú¯?ÈJÂmÏ¥tz™(tmJ¸qéšeyzFOžòwa­æ–@¸ë¢gWê(×áY^«+�žÅȲ¥„%­.>H­0 «A~aqá¾ehP$*:HAUTP™$ ƒÃŒäeˆàßW¾¬“6Á™WÜÿO²Ïu“cy´I~”ØÜ<{ ò b|j˜¢�Aôz¸�é‚#¸ê‡³rï/ Õyøú"²ú mó�y ÝÐÖ�ºN%*�CŸÏ¨‡àõpóHP—��ÆÐU§¥d¥'C×Kòß ÀS|‹Vš}1?Øã—Å[ΧmS ¾™JåÁ¸±c³c`GkÞ¼]K^õ‚úó÷Ö¢8Ã_´fIƒ]o®[æ—.FÞÒ�ìZŽ,#×xm¹°<w®Hþ+Vn‡%À’¼ ”|´Bõ‚èà2@™Ú+¸¤ü½ä‰v™Ý*'4‹È—Ÿ> ?›ÍÇ›äªq&ùGªEÿ™âßÑýQ4ZI×ï€;Hü"Î:5«¯íB\�Iü48ØA(wÑdi6_펴4Oi-ÄíÐjƒPEÀ DäËé#Ei�4!äîE�9!j‡¨=sÌ#”+YîÕFO¢ž9MÙÞ¾wõ'~Ò·ú“²‰6Në6zf®m²zC«6öú`FßÒ¥ßxË[jÒÑ�P-"Ñ›%°$ÿ¤+Šå€µZ>61¬ßfy¾ÔOŽzU‘I‘,(ÃûÕK€+È«Ø}+02Ñ9‰|8ûôIúùl>Þ$ÿ°’ç8ü˜‹>�U‰hβH©ö’Ñ é€Â€Æ ZïM`oJ}C'÷R* ôâ+N $øSÛH}™›áÒ®л0�Î%b¡o>!Ìr´—•rI‰"$ă”$ïxªÐ̽*"h¬ é­"û¢¢NKO-qPº-%„K2�}Bc÷7{nÜyuO²=8~MÔÚLuæ6nÿ-ì;@÷IœüŽæ¦oÝ_z.aõj|GòìëðÔj,§Æê›‰~øCÂrQ]¢¬j:ÅÒÇ…¼LíÀ¯È ¦˜à'¾àoNÁsï¾|p¾~à§v˜MòGs+ùÎtÕq.øÑý—Nó„TIvAöD`®ïSªA¨—4#!bJy„›™Sh‡z¦P&áÁ^¨÷›êô+¤—…ê"!]$4¦UB”uâ·uÅijDõd(ϪsN�h†U•ÔáBŒ8 ͇ý5M$H ß-8¤4¨¢1h·âºÉÓò�AhCÒ8å »Úw¸]ÿ¹û¤“d£#Z±asZN72ó¬uœû“]µ§¼®ÁOó\r­¯-—hMŠ™‰I²JìqGüðo…à?o‚Ÿðœ\Dð#üíÀKÉëÁ×É÷)�ÜÌ`„`˜ä‡Ð O&ºx~TDÊ)È76ðÕ#ö­'Xõö@6z)d�‘%Azã}�ÅIÞ1H³ÂYµ$P)LØ d�¥> p¿§� ³-«:!ö·‘U!kWÒ ’^�3hN›‡Öœ@Û¼ˆh^Js>ds„t� Ó…v ”PHD¥¨Ò+Hi€6ó�« âA]ý3 †G•çq´3H³,lÛ§nÛiž;ž¼Õ1°Yjgmk1ë~\¼…hÖ&©ìÛÀYº‰×ÑÇ›z‚²¬Ä¿€ðhô a0  š] îTp�à@X á>ÐZ‘7P;ªó°œ|ê ÆR�¥¨%(‚¢*°B`¹N‰�.üqîÀàô„gŸvY?i3pêž{ð²Bð�WÄ“b„g¼aCõ&ùGdÕ ”üH÷ƒý•à 1£�ùÜŸ<ûÈÎA.B Zu¤íg�U›BÚ:ø¥(iùpäOkÈ+dPLÃ$’Ã_ÖC‘×(úYƒ*Ù·—xßÞ îü+T§9ÒÓD™�–´‘Ög‘îYD”Ì# ³ ~aBÇœ€ëF]'¸rþFòpU ä9¢¨?ì4ñ.–â Ü)9Ú 2`³Jÿzu·6ƒÞZÝËeOZs×Oem™æ¦÷o¨ò�õi;×þrÍ›S?ÕOÓ¿â2üRjºšÕúlð=¬Öû@—ƒ._Ys«»k²à(g ÔòDþ¢. Êä;‚ ¢Å¾+„å5ôP× Ï92ÛýÐ>�3p×¼4¡O):�»Šs«e·Å)+ø‚ï=êû). ËÇÙgµ¤;“ü£ö?4�Ì¢¿ÿ>#üògpæø?:õ}�l-Ä1Èö>bú`Ɔj=#Å)TIéuÄ>&+'D噸�…Pš ÓçÀÀBˆgCk–h6CÐv¨šhÈKêËáXV ð¨ôåö#A‰$EÐê†mݹš Mæ©{×·({Ö)w÷‚ìJØ~_ Ý\‹K[Hž¿‰êÁ�øÞ9ó@ïî/ë羺éÏk¥ÝâÿYIëí,ÍXºt1ÂJèYZËãyíîC¥–/Œ¹UŠ¡=tüUû<þårE<…¼€R�¼>CÃn‰šS Á�¤ªç# ~�+Š+æ_ÇÉgÝ üÚ¹Iþ‘øy¹tO Á›è•Hùàsò]BOßG'ÉÈ—¾&�¥1Ô«mBš I?ÄH3²rJ=ôg›HšBÜȇ¦µG4ç–5�SÖf¹�¬¾ú»Áw£ÙBQæˆVf Q§â:”ØAY4�öó‘ ‰¤È3òµ©ùª�†SñNC#ZEÒ9-m?­*Y‚d@}Z*´êûñuaÕ6­½tíIï¿pÌØP ¿‰Ù°#ã»;ä ÷ì¹ó¶³ZÕÇ}´îë!“Z«!.Ç-]ŒžqZ+4Ÿ;/C–ž�®¡†ü� ô‡~§Oiå‚�ȇêëv;œ²‚¿xù£~�Ë‹Óé_,Š7É�wBqA,›`‚?ƈ¾_à½À?óÇñáéªNÈ‚’ÆJ Y~J’ü´ÍœBâ ̨ � ¤‘ÆõvbâÞ’€muìÍ`qIHª 3E�Ò Y½Š£�,šA* ¢EN§Ïôôž”ii– Ó) ‘@UUuƒñ³B,�U%í%ù£4]óàà™"„}´ ó*}lH{Ï^tÇ~¤}³óÛÖl êÜPû`s=µ»wÃìÞÒ¬ùQFí ½ò’ZôÂNÜ“N_š-íé–ÂÊÅ=ÂÒûkú¤ \zjJúù<»‘�cÅD&:O(îgOÁsT¾ïqþþ¿÷œŸàÏlóñ&ùÇdÕq’üh þE¿�\ôï):ÿã�´¥¤i.«¬šŸ¦qTóŸ k“‘Å©æµZòßˈÉH ºhä#Ô‹ŽA€í»‹×NÈ*�ì!N7R ¿HÉ ²IÈ îm8åôvOe:®4G�ëFsºZó!�‰–:иâ¢W¬ÃWWŒŸ{Õ¢>Ož3 @Ä ìŸL'D „ø %B˜ ¾„úé*\Ò„�}pp�~ýôm\]]wÙn\‡ÌÚ�ò`Oô§;xÃúƒ=ÓO>ȶ»µZm°²ßQƒ8‡ù‰çd|úNEÛÉ“ªöØmpBó$ò,úEÇAðƒ Fò'Jô�¼zŸa’?á=Á&ð*àú1zý‘‹^ÿYà/Î�êÏÆçáI†œ¡ÙaùSüœßM€Žâw2ˆ‹QçåPâù`G¡š—îͲ¢ÓĽ‡_Ÿöü÷zK�ÄIwy’mIû›H2HSˆªÀÈ:%¦Üæhv·Ê�R?‡ 'Å”»…ò¼ŒlŽ:íÎߤ‹Q!4&_ Pb°T°J— Ú(Šô©¨º*ÄU4^€ÆÏ@ m-`Ð,iÑ|úAúÛ¶+¯ÙVûÐË·ˆ×!û6ÎàŽ9uǶ=¼qZÊA_"JúÑä6ï>Š#MÐ�Ë özOD õ„2m’u ˆ÷øX£¨)Þ£4#íèò±÷¨o¡¨o¢´E‡“9›^£Á¯;p¾…âÑ(|žúHyð� YTO4ŽUð7 GðÜ[€WŒ@ðCEßÛ¯kî!Ÿn5Lò�Êzò=ˆÇªT‹|¸ëÇøsŒPô€�ÿ­ Ö"/ûîø=LÙ£w€#óÅ’Çx�쨳>9üœ4è¡äò´€ÓÁNG-,ë…¸W³¼ G?¾$”óK*‹ëBìòEZN¨Wºœscª³EÓù-²¹J½[sQ¿@(—ÑJ¤¾JQQW” JÈ߯ ’OôT%B4qà+Ð_Qz»AžA£L‹*¸2Bkçé5ü[óBÞXŽ©Ë6Ç;Y²­ÜàuڬʞT"ê{ZÜ•ÝMûüÞ$>@h5½÷ÞÓ¢M!ÂÓ¢wÿlÑ2bZÄ4¥:ÑÄk‹˜&ùòÊ®ýêñ´hѤ©DùæåfÞ ˆ"/DH!û[fúòä"‚?‚¤VÜsÞ7 4“ü$aÕI~¬†èGYôM‡ÿÁ?"m Þ`—Ã1\HY5¯@ÈòZyçÁÛ³¸[‹¦@Fœu�1­œìˆÛœÆqÙÆùd»ç’Å34s #âyŽò쀛OðÓÍÈ#ÿFÞ‰ (伸ÐR¥¡©B"ê"·%T«ÿÅëýtvùëy‰îåéí ¯ 4^U'�M¼t/ÞíÚ»­²‡°?ñ�-$›w£ë÷’ܳYÓÄ÷ªoz… ï½F²ŸL‹è\ŠN”ì�Z‚÷ŠÏˆ2$"á�&^ñ‘•�€�<Ãç)…àŒP�¯dô-—Çý½&y“üx•ü_NpÁ£èƒC¯{ON½Øö éxCǨG@²„CSÕP‹6IÈh)YkCL€ÝÀî,Î~ íBãã’ø88âí_žF:m6™Î%‹»NV­ÎZ³a`� 4�DÔµ šÔ+!¡ïçºìÁ´Ã‚²‡DcRIE#/WF£ùNe¾øJÒ64�„¨6ßà!ë�Hw)­=�½ÛÕmßê£ÝûÐÝûH[{»ûðk²2ëèìòq©4àê-B½Ž Rw±‡æ@È“ù!*âw ã�«àoþ£¿’â}Å=矎Ãç _îg˜äß/î£÷ÕÒ IDAT3Ñü1‹^¹î=´b�ç[D?ê§å‘lÖÊ£ù¸X �Ö•ÌiL»ä⯒u8)Ô³�Q/Ò2â,&£?Ä8!C³˜@Ö°úöR=ð[ªu4‹!P¥-‚¹eÍfÇÓ»•=s ó(éBB6§”89Í®ž‘pWÖÎsÝ~|Å¥ÒTœ²$_ˆ“¼+ò僚åç„ö«ÈÌLʳò<‚yJ8 i%>s´Rh‚ßÙÂïØ¹?Ù±»’î lØKò˸{ïH)uE´ê!Êh+¸R„ìÀ{�Ú ô¸xj!ø‘,�ùðŒÝRÉ÷CWc½/È-X)[“ü0ØÜ œ3 콿æ=H‘ ÝŸõš'÷ ^Rƒ �ó„j*Y½¥‡Ä_�Ãá6!«z9”ô’J0Œ¡ã€@=ßD(m*i™8«�Sñ}°_möÒÕ»>ÞÖî³Ö bv—[¥ÏýuÔÚrÖ™è —ò¥×oå:ÿ ^uýýÉ)®Ü*ÍjŠÌ„lªÓPW‰EK‰h±-°Jœï¤�¡Åv�€ÄA\‚FUHº òd<³‹²ƒ <éù R×Â�˜Æ®@s—gï¶ÞƦÝD{vÁ–Jý½´v ÀV�Ø�ÄÄóN"ùÈZ¢eEe¿Á}�‹FS=T'ððn‚µ¼¨ñCŽŒ¹ äðú°¿4äû‡þH^-Aò½ OØÎ„Ç"ø Á�u±£wAÓ?Žáß°¡z“üˆNšc•üXgÑ'Ñ{‡^÷ž|lÃD?<:æ{p@I�¾ÒŽJ&L#}hÙàâ÷êEÅ^ƒ ‚YÜ€uYo#Ädq ©Sú:BÖ1˵÷>Xî—O_F”ž»ˆêwž•ôUŸ˜nrݬmm¦í–û£³77ÙéqíŽhv?»?«Í¡3C20 ³ ñL2�+št I[ ½>)JáEƒ íz•VÈ·WPÉ—HH‡JÔ�’œŽ–ºÐð$•+„†úz¯Ð<àðá`_–ý¬²kÝEK–Ig]û·3O{å' Ü|ßæˆ62þ›lE­¯¬É¾Sqô¢kv¡,Ck5‘Å‹‘SOÍËü®]K`iþ®´¶"¿–]• kz�3Vä¿SÓ‡éÑEÜ7á¸ò´BðóƱàyOÑPï£×·"8Ãd´¶Ùr<úôÚ7 ŽG.*. ‰Á?1|Ѹ€\òAý K!,³¥ ÿõfÏŽó´TºêœVràHßó ÒòÔ¯áüüjõ™›£úÁà邨ž÷QK™©ÐWö%:L+:.åHéïH“¨mï$tÎ&Tæ Ñl%š :Kpí•Mò JÅÝep·^-Š –EE¤øÒƒ¸¼îP^G@�:E‰ú Ú«¸}¥ÍÖ6l¸µ §ü6åS;éLúióÍ¥çºÙsºf)ñ`_¾·—=›LEAÅÝÑNK ˆ4¥8ìoQ,3˜o2pè¦y\%,‚ÿnqß=åŠÿ_Ù�&ÛÉs&ËôÎ_Ÿ|”Ÿ¿¬è¤Y$Œü˜|Tû$ü1DôÁ"úñ>—U€^²¸¸Œ³Œ˜ûã,úÖëÅï9Op×j«óç%úNõÒ$"�å „�€¨™gÁS†VYñ(QSZìU¢ºàw+‘óxÙ¥Ñ>ðx<”T4Ê r‚ï@[�mø®N¡c† ]u-$4ºÑ¸Óá�J%RÊDNÅ�h±s =4Õ*^‚¨‚”iˆLwJ&áLB¬0p¤¤À[ƒhîâ@sWOÏ%›è)o:ãý•õ„úƘ“6&lXÿÒ±:ýÒíH÷éD‹3ûÈTñ¬@kµâÏÖPÍ]îî‡�‰j¾)�@Må!Cúc̳ȓƒg�à¹×‚?Qó×ï.î9£9Gã$üñ»WXÐ"¯üôÒa>o¼ Ñ?¢è-B6oæS&úIÀºz“üâ¢,üÏŸ"«s×h˜}I‡óéAu‚DÁ‘"8`Z]´¯TJAð%�2xQ|P| J*´‚A.~_­ -§´DK­XKT¥E- êí£´µ?m…ü¾€KfJ`�àg”H¦¥Ýø¬ß>SB{wŒÌKiëFZ](弸@‚ªËKKªù”@t8Ôv© Íb÷>¼S‰ç¢Ñ\¤í¢% B‰À.m@¸ŸiCuûIÏ¿s#"[Ñz¢ kñ[¨œ»–Ùÿ±ëÎ;>*—^Šïé![¶Lµª+kŽïJÌàWH�åÔ´6þÿàÕœøµw÷œ¥×³ùx“üˆY5LÉOÁ°iŸ}Ò™DÜ⑋˘è'X(‰ê±ÆÔɲk^#|‘Jå[„¶ÛóÙ³BI¢Ð(¶•U:h¹:ý ‘P�H?�WŸ+ €oåÕë|þŸ<û½(ZxZx%J*ÅòùÃ7”*¾ Þ+Ñ.ð›šàw‘¦;ñ¢DN”i”þÁ€Î8µCãÒɪîdÂoÿ$Ò ïm/�Ÿ£Ôgš�P4.’#Q yú_p AT›(­"APój‚*]PïuOÍsé"ðÓAº¡±Weó¥Íç.¸t—Òx0°k-¬ÜÄ??gƒT¾²�Ž“6l‡Ÿ\Êb]QjcMžYm" ~¨è«ÀÛŽñu´¸O&ùK~8‘ÿñ¨d7ª|íç|öyß”œ3¼-ÃMô'”Ä $P/éÕú’ÝBz’Â^2>ñJØó{JrmÉwþ¤Uq.j / u8Ò‚W�òP? õ¥ÁG|1‡î«ùÜ<äÃùDà#-Îz=´Ð4rBä¡•EšÅ­$"òUèë ž:ЫÐK„OÐüyDE.@])�æh‰Âæ^²úزYó¾ý�ÏQzæÒÓc²yi[§sÑþdt ,pšÎS�gZ]B<J1âÁyAƒ¢Q¾âA‘¼s ­¢œn†h?J •PI]ùd´t2:ã"H DÐßé¥ß§ )œ»¯‡™¿éyÿ];•õ�úzxp¥™[éìÜuÍ7Ïí_ü4¤2@úÀ¤K.ªj5·b)ŽÅV–/ÎGÒVw#?/A—AœíE8›3¹›Qf ÷T)ÁÕp ¯{Úï“.†hi±]1ËQ‘6Ì­À_ý_Ãëü‚|NÞ0ÉÓ ôXÉ-ã}þQÎzPù—³áÄD?a,u§ùÅš‘‘BRÒÙg{ÉøÔ%°ínU¨tÞá¢D"ñÎÉh¿—4•›x=@òÜŽÀ£!9³G¬Y‡¿ZIÂÅ�ù)þQÔâð¹•È¡¢‡Ÿ*òõˆ×ÖXгÍ9¶à uR·‡8üŠj›hÜ)>mª1Ú›(­ rp&YºÀeÕ0kV ±PHg‹ÊtÑl„ªÏSoŠýDÐ*hü`N@“|·A!/%(PQtì9 �%k¾²o¦J«½É.×xÍùwõA²Ù³w]p6P®îà?¿{mÍÖ~ºö±h÷®ÚÏJ¹¤CjÕ³eùN÷tM>2г¹@8ó6øžgø‚¾ÞúÛ¿½ôk¯ìÌ`¹ dœœÄ ¼½ý[Gø6To’?æ“ðfà�'«àódò½%þž£Š±›èÇ#õR.ݸ‘ ¾ š9©»Ï,A7ý1Â÷C˜¶ú�HûÞAÉn²­ âÏ{ü›ÐFÉEÄû¨y„œ'ÆÍ*H¾р€fTˆ)§ Û[0£?%Û“Qÿ­cY¼:z�¦3#Mg–É:Û#/3(EsЃsð¡›à ¡â.¥Ü ® qœïpÅ¢x%( ñçÓ*À©¶*@%8��ºEht¡ i&È®2ýœÓ‚´�Í3÷³âàÞo¬¹[¶Ö„õ„®pë¶5÷�ÝtJœ|æŸ2cØ|‰¯¿õ­\ú‘�~4­I­XÛ8¸sÌ Œâ�¾Ç¾­ý[Lò&ùÁªG‘ü$üÑË}7,o\_ ùîz)yõ»ØM“+/D·þÎý?÷fðZÜ@‹|9 E7!Í;�Í¢œTP)‘H½äò!ø DV, Ü€´_¡NšU»óÝðâ¼”e{óúû„BoN‘Í}>®î •ýš8W7K4î LØßR%ssâPšçhÍoQ�‡è\Qæ I ²v%�‘’äóý(Nu¢"ºo¡¸|€^J�Ì-ÍBå4§þyâbÈd�â§e¤¡®Ü;-Ë—"‹™3¹ú oàµW\^Ë>ú©A j5´Ô¨‰²\/¢ÿ«Â;oÆóäÉцIþ˜¸qj~�Ó�·÷À¿/eÈàaˆ^‰.´Z÷c-¶òJ¤1�³[Bö¥%�MŽÊ/aÖõP*vÏó¤¹ì¡â\ÔHƒ/EÒÕj�¸:d»9˜ÕKZn.EÊŠv¨@VÊ;<1Pßòe„U â$u!A22H3=ôój3Ÿªˆë’ÏÐh’µ¶“V œ¬Ëâ}B¼²J¾Ó¯º˜z{M×í¨Ìªh4;ӿə4íVZÝ*¾Sµ-¦%€ -p*xQ¤©š?ñÔ5Ï,´'Aÿ-É oá’Ûö¾÷ŠO]ñ`W„:<§¹õÎZÔ߉¿äÂ]ÀŒgפ‡šGÆÍ6J¾>Üo~œÏùcWŽ×$?…Ø ÜŸ‡¹“]ðƒ<ÿvÜ½ë «ÿ~¢ÿ§"¢7Ñ�%II,.“íÕÀ—–x£�¬qLëñ}PŠò½|%;T"Wi¤ÚïSmÐúQ‚¸AL�,Í”¬ Äšo›ÛKFÐ|c �fPïмæJo1rB öµˆ³ý�ô·™ËWdÀ,¡÷tEC~Ç,¥oDs�º“Ä3ÃÓµP4[iWžÅ¨‚ ¢å ðQÉ·G.ïAyùsšÔo…Y)Äû�ƒ›œwÏ‚îpaëV¥¼å^UqãìH*ùܼðø6³¡z“ü¨qÓÉOrÁ”Ïÿ6�*èwMô'TæM¡„Æ,¥ÞRâÞüò¬lzi5ë ÉÏ üúÏ}@é¾Ú#‡£³–W*¨t8z¾¿Ý9ÒRp¾.Š/ö©ïJ©´ZU�ˆÁQv莕ú7‹Gtò/ŠLÜ;ä¹ÅòÑ8cp)i–¿N±UnRŒdÀ¾âY½G(èMÂá÷p¸„Äù° IYÌ~¥· ñ‚„4žë|:7hÜ­ÑÞgáÿíåðàîÁoÎQd�S�‘24æÁÖyøøј@EC{÷ïÞù‰?}ùšÂ¢?€ÈЬÊ&ú·¢¿Ì$o’?^¬*z˜SCðƒD/ºF2PLô'Ž*4:”ºSâ!+ö�ˆ÷Rw;]û6ÑøAÇ̯yô‘—G„Tñ^I}èj‰Ä€‹ dˆâU)5Ûýí8Üag ÔAÖ¦´¹-�ÒVúï?ÕßAÿî¿£ÂÅäËÑC«$Ôå·s - w@ç<ùþ³/«yf2�·/ï+R6ÆÓ1Wò!{á‘çèw“¯~2Lò£ÂÍäûÿÑ”ü çyÑ5™‹ \g¢?¤NÉë—d¹ô³˜Èô›§ÂáeæUå–¸räõÅPu‰HZ­ Ýd³fGýOP£ž ¥ºh+ ÖæÇeè ²™@ªp×3àª+ ¿mد%ÜJ|Î%=0W£è$$™CF·¨› Úé4%)ñ@{¦uW O*ÉÞæÝ¡Æ?h^Ÿw¼uìE_þïÃüü{€�¬&ùQãpðË)ùéË/ù6 oC÷'ÊqýpTŸU�^”/?ÿ¿ï"b-2s%>n¶¢^ðÉC_ÂGäË"}þ‘—i¾Ñ±Ø'¯Ic§QVB¥Uj|C7¹X“ù[L»P…ìçÏ„•#¼pÖwT_õ!Òý!À¤‘븊2½„vUñÕqyV”ö¿Ô£¯qYåw%Uwð>y:ù¶@ÅÆ<ãEøø³"¢ÝQ?³¡z“ü¨óË)ýé£]ƒÇDÂH ®]àåÎw£é>h» 7òâ5îá‡Ú}Q•Î�Ç+•$jë�4NE2Õ~D£–¨Ÿæu‹�ƾï6¸ìýžgBÏ#ø³¿£•×}˜¸d®èÈ „â�ŒxO/Ľ�]�“Âì×�/æ“pø(»"r�Ó4xC!ú×ùþ÷í$2É&ú F=�ìòÁøâ{ $4ü�óqw¼ m€êCÒÈo íÃEá­üÛII"|‹�µm#r>ªC_êóÊwƘGòáÏ"|ó ¨W‡/øs®#ZöaÒz ­s(á0k/FZP!¦$“ÍÈý±Ãg‚Ë�©e†îM¥ã§ÞÉþO‹¯_ ¬!_õd˜ä�±½ zÃ;LôcpÙe•à ΟdPw}oþÖwZ%hÿ$”G8Ýû‡�ÄJ^¢V¤¾T‘¨Ñ¯¤N±ø‘ J…XèÔhÚÞrè#XâÝXÖœIøÖå#üÙ×-ûpá!ur†®(ˆ]^€ ² ®E"ˆ *ŠÃKq¤czÙõ�%zvÙ d’7ÆTô+�èMô£Ê`åº!Ë»ÈZùf/Ñí П¼7P&t]1­éï>-ÑˆŠø–×Ai4B‹ q†æKè"ð�:Áfã�‡à~&áêËa`$‚ÿ6Ñþk.ø)Ç èO²“èØqÖÆcŠ^^z9Ã.‹9(úþ®5"�Ââ½äÃïE•6*DÙO» ßÿGè«BõÓPÝ ^‡w9çëÃ}Ii/êûˆ³|à6’A)E®>Ml¨~láëW˜àGÞÖÙ‰d’7Lô�”CsñY²pËÌÀêwB™³‡È‹�†s·Š‡@‰ÝD[�¯¤�‚VI¥t ø¨Ï’îÆNðwžKXyÔ+Ãü9×ýÑ¿‹àÖ�3Lò†‰þÆ(^&”o›E|Ã{”}�N+_ ëÚ‚÷y¶¼ƽ¾ %•ˆ�OÀGN¶—"/ñÚˆ¼V}‰¦´JN|É’îÆçsWšÃßâOÎùVÁÛZö€Z®…a’7LôÇ/jgH=Ö:t @Ì]eiþà-d§CçÚ· ÆäþD�Z õ•²£’¸vß®$ WW� -œµˆZ©‰`,¯WZ¥ þr;.ƨb‰wÆðEoÉxàXò4X7�2ìVØ^ɸæ¯aÿÝÿ`Ë1ý©4|# „H ‚€. ³Ø� S¢X|äM&£*øŸ�‡~ãÿ�LðϽŠè5³F4,’7,¢Ÿ°}èÁˆ¾êYˆ³Ý%¢/¿ ·ïé¸ö/ ¥-Çüç|>_"Z‘ö)ÎI?.(A…�o¹ÚJ”ÈÙpý¨ þŽcü×F[ð6'o˜ä ýq!{˜ˆ¾NÌ®RÆÞHØó (}�оÖGý£pLÀ—"i‘ÏÇÓî¢J#Õ^öù¢È™6É´dCõ£,øoŽPðÏû¢×||´ß’ÍÉ&yÃD¼#ú,.¢ùõIà«—Áî å•„ÙeîÐÖ¨ÇBkHq›(@Ôb!¡ý\t±œ‰§®­¨­²‰àØÿ\ô›#œƒÞW‰^ýÖˆ†IÞ0ÑOT’f>l:˜EŸmIЫÞØùtßHCYwѲ¢ª=Ž�.ŠìÌ}lªû…¤T }×wÔªMÁßú¼"‚O†/øç•èÕÿi l˜ä ýD�à_dÑouޝ\†ßþ\hÿf z÷à¶°y&}rÌÍGN"JùR:ßN‰LJÒrRT2Ú…e�·�Éä�ܳˆwBâ„úm¢×�Tð_!z• Þ0ÉQô/þØÈEËK&•ÜÒHI#… .㋯nßóí7@Ç]ŒÅN`CÃsï5òv�ÓQìÝâzWž¬8CՎƯ–�ݰÒá¯L’ç™èUŸ°–5NÀÝÈ0FC2¿»2_^wÓÛ‡¿¼îÚ÷æËë^pã„nƒ,Î/«ÈêÄÉÜ^Û_ åïâ[‡Wªv´¼Úpü(J¶)¤Bœ@o=Hv÷EÊ·kCŠ WðŸ$ÛùgÈ�ùD >íc²…€CÄÊÉc'z¹øã#‹è¯}ïÄ�èÓ!ýæùv² Ÿ~ l{9”¿ƒ´ßZìø:vÍÏàÒ¸H|T”¹5F-â™ù±õw¼PùöŠ‘ þ-{‰Îû2áÁ=ûÕDî‡c%x°ìzÃ$oŒ¹è_zÕÔý�¢7q ô‚ûâï*[_ïBt=aú�ò»ä8¾¥Hš„ `7ý‘PMÉNð÷^ŒÞXƒlø$rîUÈùý(ïƒç½]}œv«5®a’7LôŠÁ}á�,(Ù×ÎG7ü©Ý˜qK¾•÷oðÚB[äkà=^Iº‘öMëµôU…ìð�°�f�¤NžE?4HwBµÕ.õÖ?¡ß©Ac‚_òY¢?üÜð9äµç!¬Å�öEkoÃ$o˜è'šè³Ž\Y|þØt™Ó¶[ ã@8”I?Ö ùÞë~¢°�òo��Ã*Ý=”ÈŠc¸7ÿ·Ã‹ìÜþ÷ʾ ¿ÍdÉgˆ~ïóàyÂE„[7#ç,&üöw¬½ “¼a¢Ÿ`¢¯Ò)q–@üÉà6¼¢_Ón$*·áòqM¤A!�$ƒØ ûï™òŸ/‚=Ã9¹èÓD¿÷…ü4^ûFôiOEÖü#þg÷ÀóþÝ8ÛÚÜ0É“PôÃeâˆ>¥_3>}~Ý›¹¦}ÛG©%9O2 %æ ¤3@o¸ý»`ÿÉç/{ÇEpæïánù ò¤u¸ƒW }úß ©Ý{�ã‚-¡3ŽŸè-¯‰è×ËëŸ9Y÷—hü@äۿ…¯`óßEò�Å ð·½½ö] Ã—°\t%Ñ%‡çÜãS~kþNï˾p/l|TksÃ$o˜èǽè‹esá¦3ƒûß·ªë"JW�‚?ÑíIäS=¼¼Ï†î–Ä •XØÿ£—£×¾sD‚�^t%òò£’êæ>LYÁîFþ0Œãƒ]óÆñ½¼x[kŽ—¡û:d•¢܋ˮz&ზ7•¾â)×=IÁç(¾„PI\‰Q$tÌŽO¡1}Q¹ñD!‘ €R›‹üTaHæ[ÊþŸ¼½f‚%ºàc”þøKvqÉÆD�è³*ĽÅ×?;)ÈÿÏÞ›ÇÉu•wÞßçœ{kë½[-©%y‘¼"<Æ6«2KX†˜iebL„@Âæ}! !¯ªß!a>C ™��! Éð¾5‹I›�°�ƒÌâH¶,Y¶µ¶ºÕKuuUݺ÷žóÌ·Z–¼a ËÚî÷óéOõRÕ]}êžú=Ïsže×ïˆÔ”ÿ ¤ ^9Qì±WðjÔÒ^<¯]úuC¤£p1ζ�Ê™è¶?RôÝ­¯E7½ï'çÔ÷èK6¦ 츚u¥ôiÚYóøW¢f1€%Â)¡ë"º0ÆKD*‹‘YÔc-8É3þÜ-×d//ý+.ûBÝ͉ÛVÆJBX2–P( MBm9I,F<^ëˆÇžÁ^gsâWà‹ï=6�Å_`_ù’é¬;åÎÏRkíOŽ7uÉ£ 9¹ÈçäBÚ%Þ�–d ™ˆ>ëÐìÈž¢P—eןa¸›~÷¹ß;F�ÿöå_<þÍ|ÔlN.ò9¹ÐŸ¶ÛÙb�S‡g8€i}Ùáñ©A¤‚5Ý„Bá TãnúÕ,ïãXþ•Ž}ù—òÍ™“‹|NN.ô'Ð…óšà2/®dŒ�ïJ¡é¥Ë†ˆiƒ?Ä\ºPp›3ÇÛs7þ§'ŸØ `<òˆ}Ù ù¦ÌÉE>''ú,fÙÈsP²¦BÒöž–:¼éÈ)8{†¬É�¿†~ã]Çpvþê¯å›1'ùœœ\èO<¡ðPê24×(!Ø’¤xU,¥G($N;M)Ü�ס߸Ýcóà_ýgØu7æ›0'ùœœ\èO.|¢ÄNñN{c'%ŠFD€Qœ*¶uz¯AãÇס߸ÏÇ&ð¯ùÓ\àsr‘ÏÉÉ…þ$wÔaG+Ä¢CÄ}=A}©âQ Æk¹uš·´u_{#þÆw£Àûâ›òM—“‹|NÎÓ.ô/ûOþ�*�”ψ5rðduû¬‘~\ÿ³ÒÂoIƒ§ŒJ«Üc²>û§ã|õzô›?�À=ßl9¹Èç䜡Õ??9�~±�ÉK¿|fˆ<šÍȇSJ¡)‘JÄ’5»Sm Zh©§ìN¿½ï¾z=ú­ß9† Ë#¯ý¯¹À眎ä½sN=�þ õº_øS£�ÉSCœ¥Ö[Kˆà @ÖÔ¶„‘ض åüéáÍ'0¦oz ú½·“o߀–(û IDATð_‘çþ[¾¹rrO>'çdúÇõèÏD� N,J]ÆwZð8›õ9õ(BCŸÚnwº´¶ aêûoÅ£ÀË5ÿo.ð9¹'Ÿ“sÊxôg¨ÀÄ¢–’¸Øi„W’ȧ€u¨âC„* øÓæv_~Üò–cxëK‘×ý?Ø|;ßL9¹'Ÿ“sJxôg°ÀÞÎ�†8b´�øHgP Vš¤ž²5 ݧÁwÃo¡¹Àçää"ŸsŠÒ П®B·/…é2$æ±…þLøŽ3�W¢Èc(0‰ìo _H õ¨v‘H¡æ�]p§¶7ïnx;z뛟üÃyýŸäŸs¦�‡ësNRÚ¯q`ÀÖÀÎ!¥ýP>]ÓHÿæüo¢Ã[1ϼûŒ^²‚PlìÕyÊÿÔÉÖc”‰Ä°¡àNÑ™òî†w ·þú1¼Ý%Èëþûü[óý•“‹|NÎ #1ø/¾�}5²ä 0° ZýÐZŠÆChó|˜.ønT‹€[ÃݹÁ,RÚ …tO ý“°ìÒA)…žüé9�Í!м+ '¥ù†�J%S×YõÞ" 1(…ThzÊ%×÷Ls?zz뛎уÿöy·åû+'ùœœêÁéMèìk�áÏ"Ï» yX‡6UADÑf¦– Q4¡¹â!´u>Ô‡ààºx�›y°sBÂ9(ï…®I¤{ÎÙ‹ 6!ðÙ‡}×przÀÞ«\”x¼‹�žå‡BeA$ (Ø@°îÔóâk?ümtÓõ¹Àçää"ŸsJâÃuèÌë‘%1Ï¿ñ փ¤Ò†söñX~¹¦  ó°°â^´µ�—Bë88‚j ~êAš`g!˜A  tÊÓHßA™@VÔ œžÜ˗ݰÇh FMD Šª�•ÔŪàü©#ôî_ÞŠ~û¾#×þöÊïåû+'ùœœFbð_~:ý+ÈÀ¿"ÏÿêQ?>Ê›‚áv ,?„,?ìxD4/PëFg‡`ašË Z†&C™ph ú`ü´ã½Ûi÷AaÆS+ÆàÎõ¤…,J íÎÖ¬�î#ŸÑq�X‡³V\œ�ÇS‘Ÿf&ÍÚÝZm£Zˆ½ÆN­# ¹ìFô®WÃÌÈ“øŽŸ |N.ò99'ÿåkÑÉ_E¾‚\õ…G„èŸrÑÍÂòƒóÈà÷ö|såä"Ÿ“sBpVñ7¾�ú�ÈÀ×�çé¸ ü6*™g.=»�Ý$ð/W¡߂ðï!HÁ‚öu>À_®tuöY D™àËdǨƒ9f¤¦ ’ëÓ.`$Ž;gíÎAä|?nY/á›DÛH úŒµ3Ö¹“öºP°Fð­léÒ†…¾¥™û¿ßMòç{|�¾Ô†×¾ûÜæ{,'ùœœÆ¢À?ð;Hÿ7�|1;o?Ù7�%=¬FÒ€ L>ŠX@Kà+ ðC™ ½à/× É:Ø8  RË ™Ï"v"ûfL«c<ª[°®€+9ƒGq%JÌHIÚVTDð]B­èÜI=O^�ФÜZJ‹ìp7SÝï0¤çúà¿ÿ/Ò±·Ãžå�"ðæÚ?Ä\ž |NN.ò9'¿éÙ™Àwyî)!ðO2$gf¾ó�]³03´¾ü0hw'p>h¤¥Î>M3±§uÄq@çhÀNƒid÷Ñ6Þ)1zê ˆ<µÕÓ0”ûº˜|? þ¢K�6–¥=ïüCêõ!˜9Zàßð˜g矓“‹|Ήà þÖKÑ{Þ› ü ÿ7RHϼu�¤ã™×ÁNqd^Àaµ;èíDAûÁŸ î2 LÖ¹Òã‰<ѱÖ3'$‡¸²²˜d'¢¨É’ÝÉk¨ÁÒB¨“ÖÔϹLIKN¦�jxšuÌ3÷R¸æ]Ä7ü5LŽtþ}˜goÉ÷WNN.ò9'Ôƒ¿íYèÝÅû‘|æÌø'&w½Ñ1ö3$;ðÝàû1ô‰£OI‡ :â$ý…Yu=‹"ï ÜÎÞwàêû™CŠ“Pœ…îI¤wº`4«xܧ%?û>?�í# +LZ6´Ó4øþ-”/¼�ú’wÔ_›†½‰¿% â5<×½Ëóù?Ǭûæ²;óK&''ùœ*ð›.Cïù}(Þ�¹ê£H1É娤°sƒ�;ƒAp¡B„ÃB¹Ûö6'V ¼À i‘pblV*Øzø>ðeÍ~Wp0kN#…)(Î@e:kÔWƒÀW� Æ,ØÒîºâÚ é=3r[êÃï þ߃ú*M X2+Þ”•ääää"ŸsýÒï¬E·¿ ÌU…rœ/ÊSH‚z‡á“¶Ÿ ¸o·ú¯^Br ˆ®bø»wšóöAªà xƒÆ¥¬D0î…ö`Ö' F£ Àõ€veFéá†A„“HPÏfTf Ø@¦¡øä^ÓB$Ä«€ƒš�<„`J†øüß—¸uôíÖîânù¼ÝI¹¶@b;? å´r�ÏÉÉE>ç üíãïz0WþUÖ­.çøŠ~¢Ó„n'º’×@§Ã�ñ�Ò~ãÁx$X€ÊÂÃc�à4)@s¢h¡i7Ä#™0_ÎrÔ¢w ÍB8ƒBiŠsP©!ÝóPnåu[#f!¶ŠÝ q lŸ–]âM ¾q v-eö4ë$&H�2´Ðü…ÎÉÉE>ç„ üçãïú¦0W~ ªå‹rJ¼=¤ÙìõbÝóÀƒGÎBfF@«73â~4^É´}ÔºÀw‚J;K4 ¦!<ˆ„s4ƒ)üÀ¡lÀP¥e( y™¨o7¾±V˜n¹°|I“ÃE999¹Èçœ,Ï2üOÞ vsÅ_ç:aXw„°÷h#@’B6@()v:.A“~H— ís�J�g2Ähˆ–c/q›4õÞüÿmüê&Âí¸ƒ¤8ƒMd8‚�(_ûœœ\äsN(NÐ�Ãø[?(æŠ�!Kæòu9“…B),Í8Úq±¥lûpç_Š Vb¿3Oºs�øùXÍ·¶ã‹çÕ?öÄLŠ˜¹N^@ )í…ÊA(Ï!K&�å3PL¡’@Ñå럓“‹|Îqã@þÖ? 0Ïþp.ð'Oz�[]~çBãi¿êYÖ_ð&¡¤nð.‚OŠøµÿ¨¾ü å,qåt!f q½ßê�Ör´½­? f‡Á÷¡÷J§ñP=3 ‘ÂdVÐ=…ŒìF†kÐÛÎÆ ‡y²^N.ò99ÇÆÞ^ÜM¾Œ¹â¿!Kgò5yL(¦yoB¡»ßž3¿¯´¢Ò‘fQRbºŒmÌ9gŸÆf8a[H†:<``JKÑR"–>/ðç¾1¥Ë" µÚ»Òi€·5‡ ¨cJIέu kûó»¡^�™´Ñ­h¬DÓ~´±æFà@zoç½ÎÎB8v)„ÒtD¦�U“°|!¿�rr‘ÏÉyLGíÁ~üÍ é díƒáÙ|Qž&§`4$”6^iž;xq³t½% ’ÁµÕÙ#JížlTÔsbÜ Ôý¬§T°Qi¿Åõý(-nÿSi^ðtz¹³;¾Í+ŸÔ/—ž&ô4ö}-.N˜BkC°0œåÄÃhóB¨_ ƒ¨–àÍÙ(ìëô 8=�ÞiX2ƒ,›‡ž¼ô3'ùœ3Qàw â7ý!¤Ë‘‹?ŒYó`¾(O‹ÇÒ&QBch7}g„HbPKhfq‰yZŸ›+‰iÐ¥6š÷¸º….tƒÞ2Ed÷íVÜ�B{9vçmÛ+ô©°?O™BF¦€{Ž6âR ]èüÔF²^ía´u,ü˜êC}‰l QÒ1dF@azögÍ‚g‘¥5jåWcN.ò9§ÝøÍï…xráG1çïÊ×äé%+}7B E5$^ñŠÄz‘U€®†hÞæ(ƒx\Wê6¤W]hÓ•—'vrgân¿ƒä�Ø»3 go'=4¨‹õüÇ…b’}tEȲi`çцk@³í":ßõeÐZÉ � Ï‚C=¨–;¿´�õ ÷#á ”&¡r雄¾2X‡áÆË 0úP$"''ùœ)ðîÆ÷@|²ú㘋¶çkr"p™Ô·#< BÁƒÁ@ÎÄ´þéKȳ!¸K/5éÚw8––ñý/!Ø5�†»Söí·I„3'ÑÐUÉæ*€…ŽpßÑ÷qêˆJh£§ è4 Š—As-êÎŽ�ì8À4 ˜Ê"¥P¬!C{`pÊmdé”Ó\àsžz‘WÌF�Qð"�NRª²1£ šÝˆ¾] ?)¤(|J>%oãmùjž‘´‚LàÛ"çþ-æ™?Í×äZ1I¢>´bÚ‰÷ÀˆOUm6ÕŽ¤ÇêÞ·#ùÒ¬ÐQK„#RÂAãJ5¡µúì é~IŠ5˜9ß²š•)ݤ8×”@89ÄMž@�~±ú;F‡xä$ÁNbàBWf´zaa´‡Ñ´fÖ‚ïA÷†€éTÌe={çtï‡ÞId`&‹ô´¡”>"šÇ^7!;lبäÆÃ™*ò*(TÝŠ´s=xD¾lÇŽ�ã >�ØU׿-å3ùbžBL þ‹o‡ö¹ÀŸ /�‘O»X46qν´Û�F)‰EÂ6^X‹ç¸’7FáLQHJØ$Rç�Zß~0åÁ¿ ì»Ê$…ßôvïm˜m÷‘ Ø4ÍÔètâ¡ÄÀÅI‚?>Úˆ PïBçû`a(;ˆÐör4:f‡ÙNbà,ØFÖ5°¼?kÜ;A¼tÓ?«¡­f³ýTa|¼ónÜ åœt"/ hØj`XßQv3 Œ�Uu´ªºž1ÆÀU…ôfn¶ðò|5ÏŽø�¿�Î_�¬ùKÌ%wåks’ÐN<„‚E¦ñ‡(|Í‘^+Yò�Ð4ÞYÇqË®·¸Â9°�q.P ëõ´‹yijßµÉê ½ùÉ?áÝ™=…PU�R ¥žxôûÍu£ÓÃÐê�æpÖ+ DkWÂôRØÓ[…Ó¹ö°­$ì^Ë/¡ÚÞ³b„=¯}- ŒéégMåüL‘ϲMAE<Õq߀¹ZE6¯WelLG×VetmU¤ZUÖn†E6Apõ_ò¼%_Ì3‡Äà¿xZ{ rÎÇs�?YÈDÛ$^œ• |óû°íÅè5‘nŒér�4J)$öø¼É›@puOÔ…‹—“<ï ’È*5»þ¹áoü1�îÁ$ÜýY›DÉq56N /ÿ zÓÒ¿€ô?v ¿6‹ph[[*îì磼ð>çþ!8pýÔ§˜�±ÈfL‘1ì&ÉZ?^ÙkÇë;|Ëc|ž'£È�"&³üÔkF«è(c:θ �¿ØL1ªë7M 6/®¯/¨Æ`õ�‘^>žŸñœö8ÉÊ‘Úï¡Ó×"gséóµ9Y‚,N“Nfº/ZcÚ‰OŠ¡)·+&dÞ, n–×! ‘z#õ00ž¿Â6žñ.Oà+/¡Tù)na†RÓ8Š’%æüüÆB¥ gï'HH|^Â5­ì%ßÂþ¥ÕÉ^`… #xÛ é ààUÀ٬ߘ&:‚çv¢cìjÀ‘y”Ï�ýœ“Eä7v’ëaøËtÕË,o×YÊÊòYíab?bà\ÿ}»l»s«(1@q²+p¤ùl¨ÓÞK\øëÐé×#K¾€ùwäër2Ùa­(Š)µÑfyˆÔ£R�¶ZgqÇÉ�®‡^a¨Dcj‰pþn!Y¡ÒTLrÈF‰†”$¢âIšŠ ŸqÎS‰>ä\ âT|Ë¥4�‰JÓL ¾3ÑÏtt ú€%G|œ¼è†€"wþ@Gü÷»�ý`˜šù‹p2‰ü§yŽéç…òùàìà¦ô\cX}Hd§Eº¤›…¨€Á‚(Fňµ¨ÔP�½¤"Éãle145½d ¥ kG‘õãU… š]“‚PEØP©úÎñ�ZEdíbæ?UÉ{„Á(¢ªÈáÊ€œ§�E~ædèäù_É×ä$#Dh;%¬ ‰k†LÅ$í†*ƒŠPJÞ¸$tG;cÇ€™‡BŸÁõ€k+‰WBJ‡ÄÖ‡"ÇÖ§={î‘ú/©è�%âf¾ì(álSI¬®îLÕ?�~þ#¿uøµ÷áŽ�FG¬yeAP–v €å�ÏŸ üRç祎©¹ÐûI²¾ûÉŽèDj# 9ÂÛÏCüÇUä—Ðïá«ÓËÒD�Àà%@ðd ¡H0YYލxç�`|,y¼×§Ð y³¼Yfy™VY¯ë6a«Sþà_•]UÏ(ºø ªÕ*ÕêU6›Á¬Û‚Œ_Ží˜ü¢è4»,ä¡ïužœ¢"¹{𺈂ÿê5™ß3ò¼}Âg‰9'Þ+©´ÛÚEÁdïáˆÇ@’êS¡­6¹@û?©Öyu6žQ¦ýº~Wü~�v“¨+»nÇ${ÕœÇÖ;Z`;š‘ót“$OZL`qÀÔÁG1lGä»;Ñ€A`UǸx%ÙQ@¥cÔÉŽðP>ÀƒÀÍ@;…ŽƒÈ�®æ[«z“[?z'Ю7¥äW¼°Š4(€b4U55(¨à½Á¤ÆB⽩ûÇmßÿ—øŠO¾ùïÇh~ê{ßænûñ\ßÄ–ÖÊKHØF¼mm;ª²Uªd.=¢zuvQÈèF‘m*ðÁŒ#Yî€T�ªvJø�°Zó4�§è-Áà¿òZtâ�Hß7�lÌjƒsN>,OÖvÆHâœCo!\èÖ$Ð6Η"Ñè)x �Ý£øÖõáh ¥ó†Lã²ßzÎ7¼pGRºù#Dqd¹÷ng£Yü›&©N«¨®#Úó� �ŽÈt �%À° X üZç¢ø5àö|‰�ƒÈ�_‚›ØV}ÝÞ_ýÊß=ôâ0mþ§Ôór_¡gÁ9o¬Zoç%ë>ëS§�«ª‰¬�Éô1(1Në.e5I ö׿˜Ä›½ÜÁý|×ï¥û‹“Õá¡}Uùè®:?Í‹V¬‹ÖBF¸œ ©›u\í¶mÂ2*FFG�Qa›¨ŽUJ~&üD^Ö©Wƪ0.ø�«f]½z5í�£Ü»þ�ëv¬šÚü·‡b®ˆÊn”o ›¥1â\ák­Ì¿2£÷>Ùá–¨c©ªôJ * š‚&¢ª‡#í%õZDè¥Á/€Á¨ >‘°žòƒz¢çP¿ålаß9vm ÂûÙìc&9È€=A u„–rx®•fo‡Âz0S�Ä;A·�VŸéÃáŽPªB¤JÕÀV…ñ¬Vép³ GƳF;qÉK@7€Š ªÈȆÎ#NÚ$AósÑ�ïAºoËþÔqåñ€‡+í �‘Ѓt.ÿ‘„HI¢'áE0±�”³ˆ�- .Q\?P›†§1«ÿ§õç¿ß•§>J{OÓ€ëÍÿmÔöÅ`PžYó‹À»€O– üqyD2y­f ½~ýC/×�ãªã›Í†*mªÜ&?ä{ý†�¸]¼´ž®â+ÊýMxl‘ÿg~œ¦Œò6J ÷`¢~æ“e:éW©ó#ØtD=_ºt%Âoî´p´¤™!�ª'Ê’„5¢$B…½^e¢—aE°),8Øï›6ITÛM)s�;Ùo™ó†û ì~æÝƒ…»Ø×8Èûˆ˜:ßoÞÙça‹cã¨]�ص@y úÚ+pUA«Te+keÃL±–Q6Ѝ(*†ñQWÝ�¥f„Õ�À6… *Yb l” 2ª¨PUÌ¢pâ/‡N!¤ÿö³ÐûÞ]w ¿øO¹ÀŸ"„NLbÕËÆ&-Oj >ÀH"âðZ¡`4A×LÉ5ì�öf¡ù°%ØÁ/t×bžýLèŽ)|ën¢ig|Ñ8fÿúàÙyÞ¢nv›_Vg ¼x7ð-à#¹À?"ÿ3¨V«lÞP5ï\‹êê…±=k·V?³-�?·j}{–0ó3É8žqšÊT“Q¦€Œ£cÀæM˜Í«Î·ÊL‘»âÒÒ™…žh˜%�9]­eÎñEw‰œ‹Óe8éPèÁb°Á{%EU*Θ ÔõQ�Eu“Ä-š„´øk�ÌÎ=AÊ^s\¿ÿK†}iÔ=Kèæ¶ü°Tgèêvõ�u)W£SÕ«Ù¼¸¤šyëãÙ?7¾vTdì êA…ªè&]oÖ�@Uµ3ô'ö¹þ°Ë_U´*�ŸÒð´^þæKÑ»ßå­˜«þ>?ƒ?…p¨¥(>ñᔤíSÀ¤xÅ©`%Æ+õÄ=éP¹�À'j‹+©ÀÚ¢D^k~QP%jý�/Ýö]Ïä!ìÎIâ@Ip¶Ñyn~î’½œÓ�u<øoï¢|IŽ÷»úkøJ|—Ïó!¥ç�|�}la3ÚQyÝ´/ëñŠÈÆ�˜mãøj•æžMëÚtÉŒ²G§P€÷·‘êâ ðG•EЏªîôkÇI‡‡i^=°i†©up�ÜÁ2º™WÙ\%à*í¢­C”XB�•`Ρm–‘š5Y¡3Œu}˜´Ä‚f¡~ňT�@•RÖ’Ÿ•iÀ%.kìíIði€b-êÌ‘¶&i}{‚ÞÍ»Í�Ln6ìå7ØÆÕáv¦Æ/¢¶öƒ$—ï×-[Æ=ULuƒ°u¹zË'.‡Ëw)Œf•ü"P­ReƒT…ªP}(Šrb<@#¤^I7]ŠÞý{îÇ\þ�٘͜SoY ‡{ãÁ…4kà )¡…ót•l£‘¸'åH›@l+Ì(niXL.¼&å¬z F™Dmé2¹Ýº4u6·X-gÛ=¯‰Ï�+;ÿÝŽÀ/äKòtˆüvÈyü†~ž�1/àZy!/Õ¿ãƒXÔHG˜E‹´l\‹Yõfw=7ÛÏ<ŽÈÇ1lÕ G|/†“}kçä›õ‹YñWgЧ™ø�U³:‹ �®›aŽõ̺ƤJÕl®z†7`Æ·﬛·ú¨Ï÷Ó¥#¤œƒ˜Õt±\ 3¬†ª,PCŠªˆw&é"`¤ñ½ÎÆ*4E½¨G R—’�%jÛÞ§3Í"öÚ–¿ÿƒ÷roùbUv¼£tÑîú Ñ�’õŠg|Æ·ReL©"›¨šuk«Y(ÿD…죞MÏ"½§#ðÏùëÇí“�sÒ’àŸ@Éš¡Ÿ!šœ�Ká—=P$;×N�'×ñÎ{ut©b÷IÛüä&|º]’•Ãmûš%QGM­ëg£Ž“VWΆ¦åœÉ<«#ì[€ÿ’ üÓ)òßã<‡·ð~ƒ¯ð¿¸‚õºƒMláÎÃ/â»ÎTÙ²y3²n}ÕWAª×¿œÇ5[i‹T;_nÈtý°¨ÉbÆ�"0ÆÆñªŒ�¢Õ,!8ëz76¦Uªzõ(ºh0¶�jµê³:UG•ôí¯9˜l™fv —C×–;«÷¢Õª—Ë/ÇÔ¶œov¾·ðúƒ}ì Î¥Û¬€t¹1~�Odm]. KÕšAJÚm,EõUÁ‹éÔúZ”A½(«0–«¸Ç~!@õ,æ123ßd-³süvÝÊ/î¥êòÑñDƒ3Wßå¸de¶ú²×Üý^f1Wü 2PÏ·Æ)Hgž¸Iõ0V ÑVo~òRäU ”HÄa:Nõuå;÷ cÁ††hyŒÝcöý4äÅ›ãpv;쾟$;bp ŠëêdуÅá\¤ØR^÷rfrð~à'dÙôóù’<�"÷ê¾ÁÅ\Ë.6q/ãk¼ëÈ;IÖsÖT_ÍÜoA…�`øÆÍð™Ç5“�”“Å?¾#jGµ«PÕQóE¡Óª¶š Á¥ º˜ü¾߀ٖ�y#‚ÿDUõèçlÝBUG©ú�ÙÁ`S%9�²‡J¨P×Ï–p…¯É snsz>�ÁêJ*r1mú°`0ˆ�zO¼ØuÏ~Ñ! ¸ˆÀ½D;ÑT3…2Aäe¦FÈ4=ó“ÜL°Íì35¿«:ÄÛ IDATœò€œÅƒ )ÓÜI“½8æq@úöýØO>˃kýÆêV·<:fߪŒî2£ë·ø�Àæ�È·Çð›_Œ‘1ÐHH( ¢`a“ï[cZwü‰d¾�¾ð/â oÜIY…$[ï8T¬œÑJZ–fPÏfN&Œ’D}±d�Û‘o‹f¦]s�¶¶$¨RRC$þQ£ç¦Ñ™N×#„. ã”RoHôŠ—‘®º˜`ÇבïÞ�m‘&·Ý:‡u8Mup‹5ð Î&@˜ ü™ÉJà�€ÞÚñàókáiy ÜÂgÓëùßz–)vé×ùìQ÷y¤Éßikº¼üg¶°Öõˆ¶¨ÿÙ#¾~Xûa_»Žö?ÆßYü¤ªãGÿ�,vpô};tÔ•x_öè1£Êæª7“k1Û^{¹òåKt q®(gÙ’žëœ;7õ «Ê RY†¥B—”ŨQ�J‚gÇòÞ‹¢ZD–2§k |ÖÂÏâežÐ8VÚƒ¬ÖIJ•]ŸìÑû™öS<{ÛÁõÿ—L®ì£vÁ46­»ûk^`þ�·³ž?Êzݼ³y|T¿öœñ@ÊëegI! Ô¤F-Ñæ~ô»)áúìÇ•åu\+[ kú8ÔbZ̬ŒBÅÄ4ÓD‰ó½zRá�ïÕ·½â�tœu]E_ÁSïX¢%!!y /Þ®2øƒWSè7„MpˬD¯ü�°âUªB�^tYÚsÇÛl½;q6šÍÊöäèÈ€]L²ËÏáÏ`VcdƒkÞÌC!úÜ9xºE>¹…/É‹¸K®çÕúe>H^Û˜vŒ€1`l…uþòn–žËimcgZeGVZ·UF�ñ­ãö%-Ï6µ݃Ž gûƒ¬Ð.FÒ˜Õ çP‘!B9›T»0 ˆ¢‰ºNPÁt’-hˆMW«U ɺš 5“òC_Û/ÌOt³O~üÉ „ƒÅ2{Û ûÀøzö1TßK}Óì«ÿ�˜çn6´~/ °¤x¼8œ~ã·’°½ÿÊã‚ZÐlóPËÑ,ç. «Ò¶ íŽè§F‰óÞõ'�:ˆ#I‚FX0GAí]C��™5iV‘ò‘Ÿ‡ÄSâù)V ží W§¢ žé”¤ÏjI^z‘ó,þ€¬?ýÛÈÏàO¬Èªp ¬à»|<_¨R¶ ²¦7äð1@§, óbǵ*€®G•1¨S•Ô'ÛÈvª™‘;5`¯†ÜC…aúaD#V‹á\ífµoëˆ:ñ:,J/†EŠ*�c‡6HÔ A¨†À�Š ºçbÁDÄ9L=Ò„6Ïœns¹™¢-÷ñµ=+ýá³U| �$Ëë ¿pî§™MR&£B:]vÌŠ;ì�;)Ö  °¤.óЂ4 òäû“ ëññÅ„âKƘ悛¤‘f=¨ES?úÆÇ©r‰ÝÊVÆ8”'´†¾¨ÈpÚ¬\D#PãV’¸•êXEI†tK(x#€¨H'Wƒ³–º”QõÁè/08•ˆ½AÄ]u‹ã=·õH¡ö�¿;CjçHûç˜7ijL÷̲gpŽ}}uv4Ù×§6„ÀË¢{¸yNÎÉAâ”bh²q³¦Í ´øÒk0±7>!ò m%)Á£ˆtèúÅiÔ• ¥rñòØÙ’RÔãcÒ» ýk*»¿IÒÌFÚzŸGtrîÁÿ1YBÆo‘�›Í9Ñ"o®â z—ú›øý|I«$>Õê‘jµøÛª@ªè'ß}¯ÎäŽlÞr Ø»ø°Ãþ˜V ãU!éïÖFs©ÚöŠÂ Fâš=›½é3Š·ßñú¶¬Lh¬±|ì†Wþ`Ü\rÇkü°ë!!5%‡¤VU}Á ü©.AÔ£ ‘ÓFFpZÆòzRmñÁt�õë•"3R‘v(*"¨ÝÂL!uaKHº5«_¯a,$ žÒ  /ºçHzÉÊäz;w¾$'‘Ès#_Í—â4>P5€²þ À£÷Uƒ¾jŸÔøû¶lã®-Út…qªò™ò]þ%wÿ˜‘x%Hú¡+^éB;Dü€sƒ½ƒºba)ƒî,ºtXËf¥Ó³hŠGœ`Óp#˜z³bB / —HÄ«‚&iÎûâÌ|Ôh§˜é�dÇÀ¶à'5Ê¡`kž¢…ºú¶íR\ i¢`!í´LevÖÇx…")  ]lA±&´\¨A …´H³Ò$ LÇ.’¬ãšóàP\ÈiyÔ`y(e6ñŠñ�=¹ÝV ó âÎÊZÏ6‚.GMBZ÷¥¬&Ô‡nGžŠ›ó3þOþ7€åKr²‰|Îé}@=£€ŽQ«BžÅ/•ï�ù[GñRu¯žñ¬>Û¡ŠIÅ4‚ÔßRø éð�iô)ƒÖ0³ÇqîÙÒiÃì\B°RQ‚ƒµa™yþ®nž7ñn³T/Ñ"é£âC•ì ˜ |8:€¡‹P+“^ß^�CQ=+'\cßÐ<{Ò“Ť¸ý¤H[mÚ4¼£AŠ•LÝI£išhÐ ©Ð-)Žf³åƒ4kR�’h€°¤Aû´»|Gà <~�Œl]Kî“8ë�­+´Ây_ºû‡>ºûûÂËþTÙ³�ð�-´óý•ó¨ÉêàWoê|ž§‘‹|Îññä³I7ã ãkaü¢%vÞò·8ûÜ�îö‡g£Õ¯Äš5ÄÖYŸªâ¡Öíº%¥©´�öñ S›ØŸ@‰¡è™fÆÑk”tž ϶°ÎÜÙö«´‹J«[Kñzü0…¤Ÿ½¥ v ÞA¥g%–ÄKèI‡|k“·HV Ta1RJú4Nº±­•æ~�¥(g‰" ‰­£fŽÀÌÏjižÔÎ1Û=Á�þIö Ìð£e‡ø÷¾:+Ä&›ô“Ц�‘ùÅ’¿JlSjv¶ï$��f¢t*NŸ°}ˆ‘¤ó&ë $^õQÿ9_P�ã^uaE(žW¡yÖ9Èî»±»5$Àñ½Ïzn#ÑÜ�Ïy4 d-jW¿ž{ð¹ÈçwW>ËùGBË¡?Åò›µùQ°`^!©º”È{R´œZ]¥FMi¾ÁýtEEi :@ŸL§ø]’vYC±e‚»};Ýшª M.ß3L*½-C»­´ÑRº‚ô×J‹ñ]²ƒ@…ë éöÏ äФ#}”èÒÄì£X¹¯],‰Ï¡¤KñRB\?�V(¸¥ˆ_B‘Ljeh–íu\.1×J‚‘iP£^ØÏ|÷Aš¥Y¶÷íc¡«Î\w“¹®&{»ÚÌ”R°P7>mâ³�½9}¯‡RhÚÍôÑÚ8ÁD$ô�¾à"»pÁ;¡¯WYs¯�ÿîCPÄÛ[)U¤«Ñ ‘÷´Éy¤ÿnàR²:ø;ó%ÉE>ç83®b¶�¡7l»Ç|x%¦òá¥Îo90ÑôY{ Ó H¼K½*ÁµO©(D%MK ’¦ ¤óš–T"‰¢š–]Ð0 ¤”¤4‰ƒH ¥4ÓãS*šv%&¢¡¤¢´ƒ4h$ºþâ™_�à+�â‚°|¶È Wa� ø.îî{`h׊ %’Úµ"G=¬›üMúâ«H5–n-iA,^”\Åb(£T0érLë"†k‚±Ê%NIHHMƒv0�sH0G¢^œ¡Ñ=Í�þYœå¾¥ ÁwΚO‹‰ô¶»e¾w6[PÛ†v¬ôT,uqġңvÙl?0(5¡XB/Ô¬+zC›% …r`i{o:ï–q4Õ˜€Ä)mñ$Ù˜DB’NKY²¯“'öLФ3Î5 Û·ý$…‰ oºÄ…/W<ƒuJK ­KVéš·z–öy™ÇèÜ*Šk*‰�j…Q쓸(�‡’ïsruã­�_œ*—‡ès‘Ï9Þ¬))©¦@´ø&ÐFy°¯Åƒ´à¡ž ÓGöËØ7‡vœMÿ4ý.mÜÀ@°LkK(Ëéw+™!-ÿÛ+ ,ôsŽœÍ`²„�d…)¸ó}YÏfA%Äè6´Á ”ÅS‡Ï$¼XZ‰Ò¢‰‰ì�ùZù s=Sìï�àß—M0Y\ Ly@›`¡=¨ûгŽ2ai®l¢¢7Ý ¢ê‰¶+ÎЬh˜€Ip!¡4IðÅÀ'ª,à†f+š’h�¦úÁEŠCñ‹jLç%8e=â1I¢S”’Ÿ:ÇKh½ T$K>L5KÎÛ­iOëXð×õÂÜv4Žl¤>±‹qþV‘s¤f¼ Xü.�7c<'ùœ§Ó±¬¯>lâTÑÕk¦ÝnåP�o¯ÜN£yw)=�(¨¤}XÔ8æ}J[ÊÒÁÆÝ̬vEšAûu“—pió7(h¯ôú~-Q¢hBR‰¹_Lüí¦èº(ºA@h!89—RS8{Z9ÇÕ"xÚÿ‡½7�—,«ê|¿kïsNŒw¾7çÌ(ª$‹¹Šö‰Y%“¯››àS@l›BlúÙýéö‰Ù¶¾Ö~ÚO[QQ¤Ú!/*Z(YR@•EeÖœU9ÞÌ;ÇtâL{¯þãÄÍL†Bh«J²2~ŸO܈8qâÄýìsÎþ­µöo­… ;Äá E´Ž³ë¬M.rkg6y¿3ì-¦{q¯àÌä€A¬$ÖWØfR3P€4TÂ4֋‡ ™�Õ0õ8}]Âr¬X !H¶ú�œ¸4Lü?ÖK2”m‡‡ +¿áCà½;åüº¡ü)ý‰WûÊÉß![ôŽ˜ª@›‹ºQ¸~„ 3ðŸ€�\ô™Œ¼ùÉ�ðÄ@.z~¥æ·¾è¼´Ð�ý®²ŽŽ¶éøR°ªA1AqårPÄ�V—æ(jŠ ·¶ôYsüUv7KÑO¥¡N0ET˜23ñ6ô.îˆNqµ‰«&tŒmÙ Ûòífg÷-ÚÔŠ†"$Æ ]¯@É·äÛ ûB˜XQžI�O ¼Ð¿‘-êФ'YÞÖ̶Óîéuþ&¸Ýpi_• YbÑ3n �šmwÚŽvM'LûÑí�ž$Ó‰~ƒ* ¦¨›û‚å"©V„ñq;ñÉkè%)q' €q±¤Þý ô4Î07(è¯Ó0§xFãAÿü¶å{È™¤Â ÖM¡ÔˆjŸÅÈ}T˜d²ØFà&ñf+§3c=ÓŽ¢Ij –Yµ¢RwhÚ”å¹�Z"É+¡“‰k]|á˜\¹·K'ZfÛ�æóËë0™P�Œ‹½ Ý´8F±à\}t—�þ5À~å"‚…èG$?ÂHì›Ïo~ ¸8ô”p¹’Pû8.Ór"i—¢¾dó}á”v×´¹¨ÄjÒT@WYªP }:Êš m:J!P„Ã} Í²X¥ã93UŽáýœ+·ÅÀ O B%HÓ€ÐAó×�?bN­ŸÍf˜ñ[u‚u[økÒšy¨>H) “³RÍ®£¯^ñˆ�0RÅ]‰º9©BX·@>S\›^Ákzo¢.±ª‹˜0a•%–ì:§X­ÜÓ\M›ÎÐ4Öœõ™S�Ùšª[l1mºiÞûj*ñßðSÂêɈûþ2Ì·J×.ªÍÇÕ5:Vź„ÜÕ‡ªt³0F²]­Í€œ/èoŒ0]´}a“ \Ë­Áе'¾ñχÿÿ¿ôEŸ�ÎçˆäGx‚‰þ ÀOQ†çߣ¥Ó'…(A‚†P¬ NÍ2íVÏcq8<9„_ïŠ�C?Ìjƒ’p¼ú òäy¾bDfœˆâ_ÄäÞ�Å‚x\YÒ·³‘³3&ëŒQɦd’krc&qþZ¼Þ>ù®ôVš½Šözƒ¬NÓôžN^¹xÝô‘Aóš£á¿Lˆ¬#-f©[ëï}Ô�iåøG³–'õØâ§¬[ëçc³ê)HH”FaÀbûr!«Âêð!ÔºpHò"D*sçf}N!6…ºº™ ò‘xïRÃK€× Éý¿ç ˈäGxâ¡Àwo>L)´ü“eGA¡‚dµ™u9iÙ¦b ©÷õ|B\kÉï¡øJ.õ´Nü)w;¦ù)È-•4bÒÕ™ ÇÉÂêf9}Tõµ©€F¿I{�ȤojaïÔ¹ðÊßÖïe. {õô =“*.W^о‚g¤ß"¢»rôéÕE ¿ôìø«ŸøÄ«ÝàÔ9NÞ1`•-œ«²XÐi'Ô éæbœÝ¨ºj¿z>,›Lv ]ëªIp$6UŒŠ 8W½Gm?ÐåéÕ€næÉ�'©@Jî½rÞÚáÀMÀ-Cçáb‚yï#’á ôÜ7ñbàg)ô¿Å¨±û“†**P�˜•BËÁ}]läøœDãflð9a\'Ç+¡3qÞv•õ1M‰$‡jÂY:ÀY¬Œ‘�PrR%4–Ô¹°ãŠü®ð0W¸ãºî'È¢µlõUiú¦ö WéDä$êÃPh6Úíœ)æh‡Ú¿ëf~ƒ[ÌNºß~‹gì3Ïgò¤²¨xÆ£$¤´ÔÖéÕÖÈmÇu¢¶ëÖ:,ÕÛœivùìÔ•°HÖLæUª®. ±‚ ¹ñX/„*®ZkAQ¥!`M‚òÇ)p„' ÿ x3ð‡À/ ~tîF$?“à½àÿ  ŸÝ5´²Gÿd:ò¤Z%|R(’Cè%Ç�õå|è¬�‡è<ÄÞ�'5y©š¨Ô ¡r4LE�w¤æb��(XrŒð9N™ÏÕN× ÄRÐÞÑ 0F´iåo¤x“3‘7¥½.ucèÚœÛo*xàMM$¢¯]89ƒlh¡­„A8¨xÄÚÀÕ�•:á`³ý²ßNÕ²â¯É�>1ÎÄd¦�wj+ùFÔæÔØ�4–yhºËñfL.ž1o™Ê4iGݺ'°$8rņ£Pï×?^ü8ð甹ð£ùeDò#<‰x>ðànà—Å?ÿ \ùŠ$I †HTT½’{�1BBñ@N®#„Vð^+y•œ\}èÀLšú0ErrÍ+aY@?Ń/‰pèõ†„äaOÈëÚ#UðÐ÷¤â›§š½pI<)Tj¦�®{“‡J¼ ϶‡èýTjóqæ¬Îéçuü38}rŽSÉ'k™¯ìXeª¨³geÌ]11ÃtйÞLË‹¨j¹È`0>ÄÈ$Q6…Ú}aÆ(ל͹Ù{¬q¨‡kô£uÚÍbí°n×Y›j»å°Ç™É˜»Ç»sËW¨ÇQAd�¶K=ÁX¨ç›A˃U™JǤBÅÄô}Œ×b*±ØôÂÔ[O&J=3Ä‘¯5qxM(ãZ*b[Š(£|h` —²ð‚A©Pw†�ÀEp•§V㢯�àÿ=p;e.|1òàG$?¹ˆàß £Leü?‰+ŸjY"¸P6Ëüz3äeOÊEÄà½2ì„—nž®¼|ï�Â!¹?ÞL—Ö­ÏI•<Ä_|º;YA%41KÞä!ÞÌ ñŠÃOà BíÚ¦¬ýè¿¶m÷,éÿ×ÅwðçùÕ'ÂÙ�ýúÔo}h¼vnª£º~ÖmØ{vl¸†;eûFÜ jÔ�âM/7ýïºÙ›Z`ýŸüä3øÝ{·óèÞ#p×1t�dZ×§ÖLm½æQ(¥]ÑômoðÐÔŸ�Pö/¨«s¾ÎT>�·9Ÿ?ËÎ8¤[s4–U)xY¼�çö¿Ÿ«x:U‚õäªb«Îd¹j…¦ºb‹Ar0±² Ï6ßd…ÿëHŽHáœévW*m>›ìˆ_Lrß1'—YœèÐ�;gÖÎ4²úé7Å”‰1º¬ùÂö§tq8 .. �ŠH(¥(4"ÇF)œÌROìµBM*Ô$F´¨x¡¢Bj4(¬–qêË"ZýLÊ4Ü{€· ~„É�ð{ï›Vôs)×ÞW)×Ⱥ£áÁÞÔßSCoÆB›¿á»à¦osÌYtÏw&ö½¿þלÉþš­±Î©£F”õe*Ëý¹È á@ÆûV;è×|­ß0›+Q&$êyP:ÖÙN#}j¸�1G¿ëÈ늳Ê�Á2K•w1×ßÊd6MÅ5uJ¶S¦ÁvüÇø®®MSIǘv³4Š)fu+“úl±ÞhÏ;¬ÅRU¤I”nã[ÄÀé×7àp&!“.E¸A®ÇEÐŽãÊ*Ýú2íj›£ÛÏñÀÖ6ÛÝžs3²ÌZùÿã‰ëB­¬¼_l䎺µ¤U%®û$Òz&…Щø µZ)Ålßž_xŠ! ‘üB‡Ãgÿ¸ø×@gäÁ�H~„'�è÷¿ô�ÿ<"ø6á©B y¢ž.Ô÷mÑÞ‹žíeÚŠ®èCqþÅÿ$¸»¨ öš�]RW ƒžÏ¦v+ë휆 èwŒ Ñ@ ”A¶®X 붦u5g:Ʋ½ß°‹ýÕÂR7èy€èt3ÏÎ6±Sgp¢ØT+uµöl/u·gmÖPaÕr…|óúÍzUü*2�‘P#5T%B%gI+ì1‹D"RG|…ÐÍaÝyZæè�#Œ£ì49Ïy0%$Cì`9·ÄÑ9:õs,Öytæ,OoPD9‘�ŠY­õxB*D’’iœ©Ç…BPPAQ!Zó-‚§ž'Ÿo.‘ï¡ Ñß ¼XüˆäGxr Àõ\PÏÿ4°Ì¨ÅçݱRHúí’± ^óBeë4:@y8ɃÛÿá3 j ¢SRË`0¨•Ä�¥Þ2-n½]€Ð± ;èû*S&w^a N¡F4ˆ`1ZudWH4ˆ†ÿH†uçðÄ•:Á&J[2g' k+4e‚b‚(½V,* `'Æ+9…ðmaŸªfvƒ"Zg½²H>ÖæÔøiîš[ät£Ï ‘“7=ýÀ±¸`½êêDR�ïl[V&\�z�%ïIЩû"X§ãÊp˜r)‡ËyåôÌ2¡ŒecÌ[™t[h¤»dÆ}«T|‚¢VQ©Wbó+ J#³çÐ+q&¼1ìãÌ*&è­Õ.gÇŽsbb‘3ck|~ë G§zTD¨ ¥gïJí~j´HQ*‰ !�€ µ:Ƹ‰éû4ˆI'û› �…s‘¯§5H+>#×"(ˆ+�h¶Ÿ* CSq¯ ÌÖEG$?ˆ‹Côã”kð;€ŸÎŒ†gÂ\p;1>ÄûTËŒüf ì¿Ò±+ÄtwÊy>þAÜmKV­»Z2»¨t¶û9î›{e�ýä´ô¨ÆËàÿý03§jËàRkwô†lï|5­ ï�‚¥ê¢‡ÀL³Û,5N*ÀÌÒ˜_%ÖàdTp2|´˜¾ÒN¬Õ4 ò‰ÕÆ*à¨ö'4 ˜ö«¤ë¾Únj$ðòö}NÇjÅÍâe‚cLø^S*æªá2™Wa‚ 'Ð&¡ŽSI§IÙJÖv­›YÉÙ¡J„ò=âQÓ'¯®0ˆ–éUY¯-qnb…v£�«Æœ˜ìrïl\9º5«§Mb²NßSÉ%H+­Ô|F¦E�B=3q‘(qUƒÍiÜ~‘`žO#ü0Y¯óݽžžN?£0ýˆäGx‚½w€Ià×�çÿqDð#œ‡›—•îLSüø¶H6~ô&åšoz¨[‰îøPÁû?€›€ZÏØAGlƘ ­…Ë+>ç0TÁ"ƒ(»ä<ù ™Øœ²$ ¨B Rm‡¾Hð:Ðð–%)ú T¦LáœR±¦ºæ=¬²J¨` X’ O£˜XšÓ%êZ� Š[gÎpkñÓ<½]¥–[®ì�3•me NU—¯ú»ç=z†³&}Æ `oÚ`{>ÉØ`–]ÙÛÌX:ã£B�Å™@Ÿ� ¨ŒN!ƒi‚ÁuLyeÎ(ס(ŽÂ (l¬§>\MÓp�¸²N¯²ÊâÔJñðÄjñé�k<89@�`‡E)\Ú õBe¿‹'™�Y$y;0E|Ïoÿ6÷íß?ràG$?“…)ÊRµÏ§Ù ÉeÉæeïö<, }s›OÕàñÔ!|ÁÕt߸OØ{ƒ'1*'–�,¨¿ýSØÂ[·®.kë¸Fh|V%"1‘Gr< N#gÉî’+çVÐQ€* Š€¤È<$ÕŽ�Ô4 .¬EŽFa×V’Ô7˜�´˜Ð¤Ñ–$˜ú�K”Äiƒ†ôIµ?} ÖêJµ+ÉŒ´«m�I&dõ‘jB¥!Ü]ïM0¾˜R�4 y¤qœÜæÕ{›‰-•é÷¿÷8~œ-ŒG;ˆ³>2Ó„Å8+öQýCäÚdkºƒ©b6œAtœÈï¤æ«ˆCÜ8’m'ÀSÇPWaFWÚ„o5ßO‚§‡¯lЮ�¥WYa¥qŽÓ“+¬Ö{•”Sqñ©ÄÈ@´d~#ðè�¨?Üò”{ŽbQöYø¨SÙ +Š*ÈAEZ : 5¶@Ž€,€GPEEUE(�"ç·#¥q#›ÛRwøcªŠˆŒ" #’jbÓŒ~¸øà󣡹Laê‚1‚IÁ»¡ç^lŽwÛùægIú�¯W®ozplýÀÏGú¡3Y”�‹p‘J”AÖÍx?ó—¨ œ/…ÅHŸÌgt”hÆ�õ/1¢/§«„‹Uý$�–Ûc¥ æ�‡ôq 1ôC-Åä@!@@Ÿ´$˜µÈAIMÛÄJ²zþX¥8°=40è!)%›Çøým·‘-¼$™aIǵM;ô@ØéþnY{þé*¯8ö}lK^DD‹ˆ¨ª±J@uS¥æ&±n Ñq`›˜Ìh­¯L¨p… 7J�71Nºä•6·vÑ_{“¢Á‚^Ý…ooþzñãÇŽ¼ãxuù‡È÷2ÔÞ¼ ßù΃r°Õ2�¾ˆàåT>½Ï±pXÙ�.0oæ� Ú](C�r°%CrŸ^¯´Z´Z�pð r …*jô|Ìà`i1(Š §ÀÑ�Hþ©Œðs”mÿ;ð¹Ñ�\Æð¹šõ&SB#x¯anp\µÕòŠ×<·‰¤' ìíï¦øóÓ�`³]§ÔºF)ÜòNœ’çꃕP�8�* ƒ åÒ#øKÒ–W>"+U "EÃ*‰�: é(wç1ñöw3•¼‡†k²¥˜Ó‰Þãº�.ý©÷ó`#c¼Sc&˜bg:͌ߦ۲—RË®ÀˆHˆQQA\/u‚x;Ó‹ÆŠ¹ê÷;|ذmã§$Yÿ·+ßH�;X9þÉÃt9yç~æ8³ÁC,U×{¼üpŸãßsGVìï.(Z²w®¥:�È<žƒpè2pAX�}--T@8„a•›¼}ÐÂ>„ÃŽhë²Ið2Œ Œ´#’*yï›°:ðÿ/¡lûñÑð\îHñÆ�¯‰šµ„’›P±/ÞâógÔ‘\Œó^îþôÜeÉɨB´Yˆ¥¶éA’Yíá½gYW¨ „XÜ¥&»»DѤli|õ3_í;)pz®±f î ã*ÍARí-Iõl-� ÀJ)¥›Þ(Hβ»g8¼rãnžÝ~F·h¤S4üuš©ªo¾�xqµß»Qók,ßû7†F»júZׄY]�ø} ž(WVðؾÃJ›œsvË'É9¥c—ÿÂi×l­ìŸšj/ˆ¶Ù f^Ä�8~DòO5¢Jq݈àG¸S¨”-Üé©¥)¹ !|ýõ&}Ù=AÕèbl¸ëÓ^?ô‘›À�Pk nj+’e™ZWƒl DÖ0°~�hù~_ÿ³�Y°ýƒã®Öœc0U XOG½ÂŸpl”VWÐ*“¤Õr ïü;LJ[’F"ôk¬ H À@ß{ª=™I&X]t®ÊViüå܃«?óKØŠ0ë¶äMêÉ”†E�ÏŒg=y]˜ß6ȃkÆ9¶[yî‘Üc”ÜÀbŪ³‚WÁ‰¡§"΃ÑYµ²ÕYóõ㕵‹©†]_e…«ìÙÖß»³TÍzßsâ/l~búJ™^k-mýÛV’lÁÝùfòƒïl¹ÖBKi6û^Ôâ­ï@Z å 8^Ðá ýˆåG$ÿÔÂO¯£¬h÷‰ó®×èJ¿¼ás- –8¼ñøú3¶Ò{í+mú‚� §Þ|öw<ï¹×IÎZa0«ð ‡B­0.sj]¦Î9ÀÊ)èÿAmËg†ÍjUÁu¤¹®®7õ'eРЀ €„ÌX!@ï™vÜõÕdÒT«4K²¯YÓ<  ˜°–Fa(v”kÿA[¬VÛJZëà'ªkÍ5ŠD¬}·C_”ñ¶qüs+üþ>åO^úÛüúÛ±®>=oè®Ü¹=Æs…÷v;©›#—9 M�Š�ĪUïD(AŒS0 Î†ŸEÜuÆ`0ØÂ§�øô^ÜZ é#Ï¡m”“ÑyôgßÔz4 x4ï>søÊðìáßm¬ó.×#®Z÷žKÙ'Z›óß#’¿d=÷‹_ÿ0ð”júO<Æ~#<Õ1‘[ºSÞø¶ú0”²Ç¼ƒJÕø¼í nÞ&½ï{ •–3Æ«äçÝè;µeÕFèlv°[—u·Q·Ýwô*"vS¶©×9ðã5X ˆÁN=ªVR ]ŒBèDšÎ°‹P_(!¢�ê9–'<¼ʆֺgÜŒ9Çœ2®uR>ÅiSåDPåÔà#´ù}»p\�?´Ý¿LÝ`¸ø–«…ëò*­¡’oþrý<ÚUZ„½-Ù7�¼ttSÜ7\*�yPÎ þ”ƒ*C]à…}Ív°Sà÷QfÁˆäGø’`,pË�äß|x4$—1â)5~I-âÂ\Lî5LsMÃk#É^ýáú­^RD×ð|övìŸÝAæ•Zf¢Á,½ó�ÛüëÐÈAf-x£!ÈÀKA>ˆ¦L´ž i=7yOOŠR}_\4åžWäNâá~Ã\w Útüðåð{$M…ú_Ä›�¢è(„AÊ#ó�ߌßñ»ÕâƒÄ/U_˜Ík8n*Ó´¥ûÀ‹´<ûè½ ÎAq´\´oí3\ñh@ÿÑ�ÁXT¹ª;“®²ÝZöè”^z•æÌè@f4ÓY “„Ô °(HŽ’# ÅuïlTfÈôét=(Î{Sà]ÍçyŒãF‰ù–`ƒ8¿‡ŒSûCsÊþ?þ!×ÿÜ*“¦÷­Î¡×Ú{}Æ;¿Eß|Ë›yóþ7sïsG‰Y˜CnxùΣhKÔt%mm:RåR�J)ò7 Ì#,ˆz¥,3:Lþ£${uœO'ªˆ^ØcDò#œ'ø7ÿøÃÁ�`òž™Ïp¨P¥n^Ñ×^!¼àYž@Œ.¡Üu\›ïÿ#zå|S˜Á—?ðPI9ÈÞ'DHf{8’25/ ËT»Q˜ô7 2…yxMo6ºã�=¯¿ê/yì€â?|,Ê[Rúê-²…½Ýxÿ+Y}ðí”#X`yräWµÚˆñ¢Î„Œ±»8¡»�[Td™ßM {|]gQ�"ðP�pT%_Ñ õ1VU”€1 ò�ö"¨æª.Ãc�c½ˆI³•õ€åðÓGO»Ž.¾ó^sö]Ñ;�‡=Îù‚E¶pîÎÛˆïlᘑë�‡„ÃûeïÌÑÚ:6ïuÿ!=x^p�…Í*´dž–,(:ätJ›àÒŒ¸ŽHþñÇÅ¥jí�àø àOFÃ3‚7�bÀ.ar£ž”ØìŒ¨|ÇUfð�oòR�=›Ã]÷©¹í] Žn@Tzß®†£T¿,ËgÖ9 ÖJV5Æö�sDJ•Èô ‰úÞgã¡¡Ó ì/Yô˜6…yäU¿Ùñ¾HÿÍ­ ^=©‚E @í×dÉ•…lÄpQÑšýC†¡% ã*ØK_®§ºr?ÌK«µ {`Þæo�QYf—:ÛWȋŊ£¡|¹8ç”Zh²�óDÆ`줈&�êç«Ýþ3Õæb_'PGß�®ÅK ãyè•hòjdÇûÿã”`¬S�ëùièkì?¬RçÏW®k•n(©ï|åºÊ5ìyð:¬m# -®‡Öõz´…wÉŠ)-é²anŸÌï;üéAçAŽñu;¿|–©³ÑèD\ÊÑ Î}£'ý.£Ûo�ôGÿ8Á:‚0†!�NCOñµ-ËÈÅ„¿¹­´D6ÃùC�¦5,‡«"-�ÖæÀù×[p¥Õò -ZÂK`ß©w.*¸ãh[[6ààC9lnå°Üɼg~�+ž0iœ>ÆVN3CÈ YíjuéNÓðWÊ »14¼¨ @/ˆw:,…hT¥‚Ñ�¸=bPà½2�•Añ€€uV9ËÿÉòáyx…„c ñÂI„ã„ÕãÌN¯µXËPÜ<ø…Çä�/í»éõý®á�Hþñ'wö? ÜFÙx& ÍeˆznÈëZÉ! s¨†^êòñš5Ô0eòƳwKÿEs^BÐ6Ê'¨¾÷ÃQ’á˜G[D ²!•9‚Èj¶l:cëœ:šÔY•®QG®3 Rød¶6ÞÙÑ9úºwÃT° Òª¬i@�gíF/Ý�ìxŸñoý£„Š/ÓÏ µ%è*~¨. äk Û\¤?ON¦¥õ…îC{ "k]ØÞ*�}KkóÞŒ•·~¸}àÑ�Pö¢Ô¤”^“²ï£|æ(³ý€ÔôJfíU üv°Ç9¦5æj™£"FE­ªzÀaHEQ6’1DÇ€+(+‹ µ¨Q\æi§}nç gÔœdÒ?Èíá9i6VØ>ý0>Yg6îÝøN’Ÿ¾åmæmÀ-ü�WÞŒp‹ãŽì5Kwš‡¶ÜàÃ×Þiò‡û,ìz.æí¿Ex˱Cå˜ÌÏ—–Ò Ø4&6�±á©hYä€ÓM»LF$ÿx<À ËÈ3$ø‚¯9h6ÂSyEÉ+ê© á9!7RÓY-Rš¤�kÆLÿ{ÿ…21mt ÏçÏiã译œŠu‘\Mp_åµãÜW$îÒ·3£tÍK …(EG :l‘‚Ÿ ñ¢Û?è¿úƒ�]´‡~Dû²¬·qxŸznc‰–œkÁ]›9 G8$ º_æ Ú[Ó©è¸nmÖîÀV¶»±Å4ýÓÄëNµL£D€•’…̨˜‹ÁxÞ Œ+\�p½X/¬6G“Üq6à%¡.gï|¾9÷Š»ÞqŽº;œü�þ-'‰ÂS̼nv lq@�€ƒGÝ¡#‡F$ÿ¸]gÀó€wRv’{'£ý„%톱‡ÓƇׄßóZüK_cVXÓBîùk‚_üŸägã(k pT‡žù×&å(…y®4<­\Y(w8ñëHri! (ê’pÿ³Œíü�÷³÷ZÞø›Eø üðZ+.Óéü¼Ö½l…·‰G„ׯ eMœ›nÇ…’º~~™¿¾—ÝË:ðÒâGd�Š0ü45LPc†u¶Óf7˜m8®PÕ=ÔØ�‘iŒN�˜•v–Háу`À¨­zd’ Ø=ìÑû˜X~;?òŸö¾‰Êá±øgí…ÅÖLëk×ü0éÄÏáÇÆÐÃó噇C È~¡(Cú-jF$ÿø ü×!Ùÿ0 ÄÃǨ¬Øe fLÈ ©HNd%ÕÍð¢o‚ºQ³zäúŽwã»eîºu‚³”k�¾Z‘Ü&ƒ;§›Dq®�CµÀóíGÑ¥KÄ�Çóð³‘Î[|1õP oú•"Øæ¾tú‚ä²£ƒç¯ól õZª/"­ƒCAà¸AŽÂÂþ¡µ¤ Ú’ƒ , Ì{>}}�Ö�n 9}>¿°o_yO8 측Ñ9ª5šÓ“l‰§é»§aåÆu»¦ùÓŒaªuS¸¦*UbµC®_1\¯©¼X—Ù‡AD1>!öm‰<ò3lxà É8EÊ1j<üޜŅ·pî—–ž~0GÕlÆwFx|\¶6°ø÷¥ûFNYMjX¢Ž,')»Vô†³xÎÎcÈ!v›Wq)þ4�žò_ ,IqqØ+¸èyÔÇä„邟þB¶­÷ ®‰IS²Åä•«›fð²gyÆ­2Àú#}ÇgßKôˆ«eÍRNe‚›› ®£eGâ¯ÒÿvNÝy›Ò‚Ëu•péÕ®¢A† V©®�=¾ž)½ÞsÁðÎ;÷L5�ÄO=ðÝÿ­¶õÊ)cìÂ}Y@²/yjsiærAKð.V·«–(ùa©R;ˆ(­‹¬_U´5ü¶ «á ƒC fžÊ†Ÿ>\~ï0ж|g¡Õæytöݶvî­“èÑùÄ‘#ÈÂ2ÂaÄÿ!OkŒù�þ,SÁNòæN‚În]Ñ—ßúØ>‚B.Öàd¨´OÅ;„r£ªz Q2|GoìÀ_Óþ¥·ÑR¤åU‘É?>èó”J¦†�]Àž!ñïž=ôðC£ Ö€>pvh œ–�sC£!>þ·ïÙ:H;®{ 1T†7¿?/Ô¨Ð�¤Ø$§ÞÈöûßrÚ·–§ÊÄå8ú1ˆ§|y+ÄÍ(zÿá» ¶\)¤Xîï8û÷¿‹½õ(YSÃ(³ê]Àd2ƒPjX‰PrQðªÎc�7Ì´ïuB~qÖÃh6ü CÏ<’õ=|y¥ëì�ø· �ÝCcàjàÅÀøð{9°>Œ¬~#`}ø{zÑãKÇøzKœ£à‡™U-T‰‡ß©@±¦UÆ%aX#û ¼‹þaO¾]ö‚÷M0½á¨zÉ©ŠçŸCÿ¥/Q®|²F G?“Wß÷Aü'ï�²Ç °]�Qý²vä¦Ë6³öÄøîÿ�©®à^ò_¾±]lyŒìðK{§i8�?†ßðµ_eß7~hï¾Ã¦öÍZ;.lí-±Ë7t‡Û ÏÓÁVRÝFfv¹ÂI°óK8ºT_’ÿâ×ú%¶aIÒËÀ‘Ç8NØ \ ìF®>¿˜šú~AX«C#àì0B° t!$'‡°..÷Š8�£ˆ+¢ÒÚô¤H†‡Gäþµ#š%ÙSLHj�±ùë^lóñj's¢ôî¾;ßýòGS\_‘8f…h²Q�šËU : KÓhï‡ÑæJà^öŸ ^Ð)ä|H>ȇ^û—,YÌ‹\ó4äá¯_Ïâ IDAT�'íø@ïëa•£­‚OÐÕÖ�ðàA�#,,p= zD©,l¸ ÙÖéâïÒ5ØÐÉ}�…>ðÈðñÅ‚ÞݳÀUÃHÀvàŠáó³‡Q‚ÆÐH¿˜Á²�Vܱ֜Môé…ѺÀ@!W¨BÅ ÅŽáϬé…TÑÑåñUÃo¾ÈÁ^)˜Á¿ê९ðl1ÈVOv½þMò‡“òT6p ”ÁÕ­•_îo%áø 2øq|£ ¯þiøæÁ@J£{”°óT�ˆ:˜Ö¯äÉ?° d~ž²£nKE —ZG¡µÀ!‰°?9ôa²yÎue^ý�G³ø×¿Q°yÆüð}A)Þ;õEFƒPʰ#Ê�ÿÓ€­AÕí)µÝdÅNÑÏÍ©½§pºì�iƒëþK²ä’`W[ò$˜ê">\…pµ5¨Œ²¾˜|XÚ`¦ ~ÎØüÛ¯ñ쌔�âOåyåãLúWËà°Lˆc �e¥:z4З7r:ãHò#PË+þ«ðü^ÁY…F)œ-ÆÊë+èŽëRÇ¡Ãe-¿ÇòäÏÂý²à…C(6KªYŽ@…y� ûµ¥HK¿\5¤Éý{ü_ÍëÍ÷ÉðÑ±Š–Í$¬•_ø=uá<äŠ9ëáÓ·:>ÒÆT§pñ./æÙè ŠÄcÃêËTº¨_…`ÌYC´Áºµ�¥‹³ ˆ¿Ð- òÊmu)‚ö—^zEzÑúÿ澑”!Ë‚ ÇܼL{½ßÜv‘éüþ }âÎN°…G°¢¥MUO¬éõœ÷PÙS¥ûï^æ¸æÅHj}´í¹mÁ·~´ôÖméÁ`ÉxœŠÓDN°U‰¹fÖBcÒ^Ù9ôé[ÃØàZ²‰OQíV™ðÿ‹½7�³´¨îÿß§êyîÒËt÷ôLÏβ(àJÜ·ˆâÂŽðýš¸£ùÅ|câ—â’D‚Šb̦¸ @\’àÆ7Æ-¸DPAÙgë™Þ—Û÷Þ穪óûã¹ÝÓ3 Ît3 ÓSï׫_Ý}û©Û÷Ö­§>uN�:gÜŠâ'c À~¡ub¥ÒŠ�jx…¬ÛÛ­o…ŽÿÂ÷zž5X‰+µæì´uDn×Çä¶èú’óÎóì³{Ïøt¤¿ÌÊ(¼c›éBE ì$ ,ŠüAàږ׸K‘¤•¥*eŽø…çi?rÚa:iP×1 ÊÊP' u{î…©%0¾²eàŽd�H³ 5Ä›)�¦¢ƒ»t4�nÁµ €…‰&‰6ƒ9nɬåZ"œ°íˆX1�¹Äia‚£ÇAÅÁq5 ?Ùax8j+è¦.˜lS~½ÔÐ\©d=Aü pÇA½ êiQ J§ðL€3 o3°ƒ)�Ê„†OÆ3œÉ h'qå–%ߨÉÝÙϳ-ú}wË‚ nF¤=ƒÊä¹Ç^ùáÈh¢Ü·IÍÿ\�ýøf[¯*Tij÷öÞ-(‰'ƒjÉØz®‹À$Òèê…¥5˜êÐå¶:Ôîê1°r?κ*¸D!Á2Ü|šô©žü× g®w$ÛÛÄHúHùÈnqó¬jRb$W©#�¤]pU-"x8ê³Ä3ŒÂõâ pçÞߪk ÖßÝ@Rf}·cK�2ÜÌÄrh. Úèw¸e¹ — u uœF„-cŠÝ�LiœPí‡Ê8¤ª¡Ø¨=ʰÝ×‚Õ ‚’ÚÊ

µ#mžñÇÑ�&†ûCHøM’›û©/Q€Ì– ä õ½SËÝ·¾„�ñ™Wã‰&’[§Ö‹”H¥^J¥8“³Þí?Ú)“W›l|;˜UNÿ@ƒ3í¨H!ðõÖP¯Æ®ŠD‘�̇@ŠHN [XÎé ëafO=¥¨SÝr‘»YÃ&©ïðœUHqM·bì@B›˜PLR)F S”\Û¡<°Ô3Òg¨uAmE Ñ‡4ŸpËЩE… kttØjh;vH0„ò¸ÃdÛ[õûbH‹ UQ¨`è‘ g=ÑqòÑBŽò`ò‹ïnú6õf°tˆ·cŠÍ +íEamy²b�ßz(êŠB Q2 Øê™Ýõû—*Œ•3úߥ5†£?ØàÕëH‚àÜ,7ýüˆ{ò‘(ò!ß9÷‘-ŽÉ¹  àò¦¢>m×·‰·KŠÇ“Ù�O“n?”Š}Dq4(ŽêqyÖ:’—(1…�.�—žoɬã¡A’ÿùîæ›ñ.‡ž1Å—°¾_QœÕw{8óœ/"öm-‚¶rtq°v UØzÐR'‹–ü>YV ±‚«µÆÓD¶ÿ­ô(£Çÿ�á’_„*†’r´ˆxŸumÒ >Úf˜–³àØ)DZo7X]nC�¸ fd)¡Öghô&—¢SGc²§bòn‚¤0áC�BðÙä°ƒP»ÒQ(²Á¢¨¦SÕ¶,fÏdËzÎv"ðÛ‰�Õ’©Ö½ÖuÛÒø”¯—êd™U„L|pZÕeñ¶Z,Ó|<´·oDÞc ) nÂb¶œæhä„¿ zö]!AÈ�Τ«�-êó˜¡cà]$Š|ä�.XŠŒ_Çm6êjšPBp%G­¿n‡¡Å0¸ 3µKÑìhѬt‘¢)ødBÿ¨Gú2$ÃúÉ®gšÐh¶Š~ÂØXp %Jm„’ ÛŽqÆøÁàÊÿý1Ì�÷Qñ–eÆÏXÊ;æŠß™›|ãÕšÞcÁVe˜0r?úµ#µýÄ­ø_ÞÎÔ0Ö Y#zt÷É »Ràa…IM\g¾8¨y&u^}—c‰àòéUlì¯HùÈÁЉˆÏyG…ä°´¿"u÷jðÃÞ �Ú·c¤M¨û� òžÅà[ ³ª õ<ÔKV꾦TÊv�JuÈÚSSªù�õû‚! b£¯Vô¹ÊšO(|Ÿ¤«°àg"é“=8 bà]$Š|ä€Ä͵³­úYÇŒ¦#þ]œ{ä(Ÿ}j`†á¢è‡Xâq}c…@�m„ö_éH~[ArŒÍ·üžgóóñÒe�zª?ÆmžB&—’Þ€?õ�bÆŒ„ �‰Ȩ ãŠ5ÈH0É !†t LJ®8�÷�´e¡8ª‡W*e[­çZ÷žª¯ÃˆõȪVlmÒgXb¹Ù}‚`8Kƒ¼\XþyM.ýoÒ^SľLç£OŠjt×G¢ÈGâpÝ•øï ö;º@§­þÙA©ê+”ä!pU)D}’ª¸ÛŸäØð|˜|䋃jð>HS¹ ©ã·2Ù5@Mªš· Ú…ÑÝŠvƒ. ¢G£õNÐEºá:˜Š2vC� Ç“AH†-fl«”p©™oÅïlAP2B½h¯ØB<2ðAë½+SFëE'yƒ¯V õƬÀ@ض�ðh[~ïƒÝÅõÛМ,jÁ'‹¥8þ9 .ÁèÃg-½\Yu“rÁ¿^£V0^2k|îÁ™8ÞE¢ÈGlK~·Hçöx2\IFÀõŸ: ¿é�×®•ôFZGDÃ�¦âg ^JažÙÑ@%$е‚Ÿ–æL@Û!ôí K@—‚.(Ð#dmJ3xð‚Ud;22ŠIGÆ@ŠŽ1Ý’²Èd¥†zcAJCý®ŽÕE”ÌxÅIG-„I[|I·é¹v÷í‡fGK¸‡Z^$Qxà•Á'¯€Þ…W‘dIqMžë#Ça´â#Qä#‘½CZ®ÓN`Çí�˜ C£M`–]$ A‹‚?éoаºð²?ڂ´¾0øYi…Iµ0õf*îÌØ`à«¢huÝzéA}/Ðn9Ð…úNB]€ ȤÂÍúhc¦žl èpf’:A'ê‹×Kã©«Ñ4}5gk¤yÉ£ÙvùüýŽD×þïžHÛÄ1¥¸QÅÕ0Œÿ~ ?ËpøW/»)aÎU¶¥«�D¢ÈG"ûЏÅ-k~)ðéßG³eètÉ'�aDÕx¨Ü‰L®ÞͰ›îSÅ£ØPGLŸnžYXg€ÄzŸ(¡£ð„^A:ƒº¥×§Ø'AhG¤\Æ;mŒ…nUl†Ÿ6)mt5&óV\@Z‡ª·”ÄOçxĹ}¿Ã÷é¿Gñ/ìð©Vb©`Ëz¾aÉ× —~ÚЩn¦àÒïò2E"Qä#‘=¸JËYê¦'àtÆrßA£‹Ÿl?,ÚŒN¶.Ù‰lvÄO{ì¶ç÷( óņú°µð1ã­&ÆûR°y×rŽ|j¦–¨ézëØ/íLr¼™k� 4Æ- ç@÷7ç:$�aöß#‘(ò‘È>§ Œ)T…d‚’;þ‡½ñ•ímpÓ’ùÒ íE$Ûž<«dCKÜÙÁZÞÕ¢ÕÆZ‚÷ž4Õà³&F'W éÉÉdédG2æ;ÿʼn×ÿKÇ1[d|c%UWVFÆzS½H¶ê‡(Ù“‹ÀÀP àÓ™3ް…�Œ£E�`R‡¤YOÿè €ßÃέ÷*€z¶/ŽÄN~ßßS§Ûá÷ §²ÿ ‹¿MrÉgHQòé¢JÓçà÷uÕÄHùHä ¢•]l–ËÔ%u Z˜ínƒÍøÁ… PtzW>€$æ©7ß¿bF_÷”Ðo'ðÌÃ;Њ–/•¤½‘KÍvš”QA!1)Sä´C[›³ã‡�f…ÎnÙNz=@Óz†Û`¨3±]„±eˆ[Œ¸C0îTÐ :eQu S`¦ÀŽ‚nÅ”Æ2é ˜ H2P‡ RŠ@Eû(�¼å.±GÝÓ”ÛÉôåŲž¾&™µ°hî‹z¡Üfð[—*fÃq¨Úw;œÿYXîÁI °‹D‘�Dö9;L¼3g”k¹þO`ä TÁ?ñhû¿÷`à¦̤yœDšû –ªøÌkNP¼×Ö«Å^»!C•çÚ0’ô‘¶´Ú<¶<}ÐÜ„µ”ïƒBC ^MïVj��ñîÀdR_ ÙJBãd ¦ZE„˜’ |:!È02f8† O€õÅVD« ®m¤TüL£ø|©2³·½;îo·ëÿ±Ny­< •I�ŠâªjØxlúVèù)¼èã°4¤èŒD¢ÈG"ûOà¡×ä£oƒ�W"Pµuèø”Ž€¶Í°úÇØÓîIÜ!ö¬§~ψ|ÚzžÌzhäa 4„D-^ F&q�ŽÔŽÖ}ØéÚÄÎzÐ[ ðâg·-ë´³žÓ[»kÄz‹Çc©+4ÏÖ˜è6d=ÁŒ.#L,R KÁ~1„‚‚NµrŒ¡L!jð¥6Kg¿°h,q]Ò`ªüY‚�`w¨,8MY¶ÚƒÖsb[\IqãŠ>FCó2X´�äÌHÜ1ÎQ•X=.E>y\�ƒ« æïÿ7:töt8½’60']‰9ó{3.ß´,ä�’lsú³“½ôýLÈ•Š1ÔJaˆæÀ(ü·CŸ« ¼Ø±àýL´þ#mùm‚oÙ>aÎv«�m×[+ÅšÀ·Ö‹ ø€í7¦Ÿ6«(ÆS¸Ì3`¼Ëøþ¨õ¦º ëƒlš%Bv4ÚœpÖû�;²YÃd¿æ£�im#Qä#‘i�§‘À?ÿ/ÂðÅ-]H›†Ã® á5ß#t2“? 99S…†¨iMâM¶E�ïGJV2ï±Y®¾%Ä1“÷aþëY˜g+J•¦liÿ;Ä{áŸNø3ûϾ:ë�¬%ø¾•^wz/¼mÛÿ±ÓyåÖWçXà�1,×ä‚,C×]iôøµ°xÀ³¹–)“+ÐÚ|³ò#Àõ µ6¤fEq‘“›™PØbHûƒIÆ;•Q|¹¢{Â]ŸÊ‡joƒ¶AxÅû]rìT±¼hÌ[‘HùHdߊz ä-ëÊÕ,æS¯ƒþ‹@¬`QLk>¸äkÛRã¶ÈèGÞ’tS<§œ%3FðA})*jJY²JE64Fœ`DA}U…Le¿Ø>ŠU¿“3ó6cûÀ8;ëñG[0ì¸0Qa¦/ÛÀ¥€ÅÛîyÒ(œ0 郉+"Úƒ†KèD[º•õ«¡Ù…ÉV¨æ+ÀŸÈ:Ðzª 2ž#~ t5[0fˆ` :`IÇ¡TóIÇ¥¾ØóOZ¯½V¸çg﹚:> ¸ Ú‡àùï#9~êñ�ûñ,|Lk‰"9HI!¯·„¤&˜üCÂàE‚Z%¨Rr°êƒpÁ×H¦sŒÏÆíð=´,¶Êããí… Ö{õÖ ™Õ”@†a%�I` A ”ÁŠ×±s«}—Ø]XþsXôøÙÁiÓ‘Jauo/–nf�{‰‡%Ó+° `}ñ9¸"¯Ož n¸b™¬zÆ:‘¡¥èØ2Ls):Þ'Á?IqÈT›'” d83…0ŠÊ–â„€%$ýÖ•Ç<¶f©Ny’&L¬Fô2´cžõ~8m¸8z÷ß#Qä#‘ý�ëÆóO磃7Z$�É Ë®6üÑW]+½ívÕíZú\Ê #„+¯)F©© %Á'ø’Êö{ ¦-ë;I Þ ‰SX^÷P‡|˜ÀC�)ÁH•^É™RØRvúP; -‚‘î„áA›Ë•©.Å�Dp=B^ 4Ƚ‡qHÆ ô�èâ­Ê©NxÚ°£]iÅG"Qä#‘ý ™bþþtÃQ,"Æ]ù Ãn�ÎVTtõ|ƒ~Zç,YÅ�FØH-WŠ}ò&ª¶®Á—fÒù-€Yl:â¾Q=ɶ\5ÉôWœ£žlh‡YÔ„§6qÉtÍ⟇™Ò¯˜H íž ]˜�¥Pë%„%pøm–ãúaeÓQå‘Iqö?1ð.E>r�þñt†7‚ZQëÕ,ûÇ ðC_+1Ž{\NÞ»Öø TÊÆ7B b ¥LV5ÔžB³Í¬ 䞺BYI·í�/˜ÜöŸY²“Ùέ,®™v¯'…°»´,E\@{ëÂåÞ×�ƒúÆ= 9˜\2kÛ`úÿ=¾ÆIÜ“�D‘�„…N‡ß+H‚T� ½Ÿ²á�Ÿq 8†[…jê[½–5oßÈ #.÷JÞ½¤‡uQz‡ V Müò�”ú+>#[ îúd–`ïjÆ›`û ¸dº}«/²Ö×ôì˜%Á%JâZccº}�Xl&E>Ù/ ƒ;tægÃgžäWW¡!UÐÂ�ïþŠá ŸqÉ´Õž¶DDw½/!³J !ËÛ.mŒH�ˆYL)á³§¢?½ ]ªVUT¡ó[ ¿ßñ„&Iêe%7 &PÉb§,º�/»MXwÜã+Çp$E>Ù Üx<áî+×]¸ç ë»pþû\rxƒê´Né‚q×O›í™ŸY´TG©ÂO!|æã¸Ï­…<ÆE"Qä#>uгÍÓszzËQðó÷ ¡5%aKßEßp%œÐ$mJ!ì•¢àÈBÉ3îƒú™ˆy#Ñ1ÊC£jo×…®÷á'¾üÈR¸ó¸O¿¥xD¢ÈG"4Ó‘ñõ"ó™ûÖ„~üÅ©¢ŠvÞç^I²ªIâ /kQl¦IYN”´Ù~>Ëô^Êã?§í¯€ÁȂ۩wO¸ùï >+¿ðºÓq×_�NVã=‰"‰¨¸NŠãn)ØÿîE¾šuƒ"ˆ‹îH¸ð/HNnYð‘…%ð¿=’ðÅB­í‘¼çüg®FÇÛcGE¢ÈG"¤!?Ҳൔð•¡�#¥í×Êïv5Y¡E£na üC« 7_c]�~ѽ'㯿î:x&u‰‹ÙHùÈBâ¶nøÂÐúŠ ¤ƒØÓßCrZ�Ä y­å¢�,tSáÆÁPï®/~ð øë¯C·ô ]ÓÚF¢ÈGÐdÿÛ¸å½0yìö�»^‚9™´$°DpUpµ8ù-ˆÏ| ÿùÖ»ßhÃaøÏ]‹nꋉ"‰<îÈ)RÕVŠ\ã.÷Ã.üÍWÁÄ“v¢½õÝ4¾yÔŠ´¤É?7^B¨¤ÆЬ8�‹“5d¥Emí�àñ!¨¶ëàà;�쀼2÷†Åõ+âý‰"‰<®¨Ä’�Öï?[·¾êOž©-ò‚A¿úçø¯Ÿ5“›~!“¥BJ*€�»Ð…_qìTåõ š*`1B–kQ�î@�µ_�¹ø�°bÃÜ÷¯"|î:Âkî¤÷ä#Qä#®°ÄÝJà�rã`üI�.ð3fŸ ß|'þÖszY `ÉñŠµÐ…Ø²nG®)ÖL�yªÖ`p¯†YÝ�½äM°æþ¹7è#Üpឣâ8ˆ{ò‘(ò‘�Ó„Íeä“ïGë'ï~[ôÖËðß8!÷�°F|É •Ô`p4m�bÖrRJcâ¡íÀÃÒ7„½èmpȽso<¼˜ðù�~y|¼·"Qä#‘ýN <�8¹æ½èØÓçÞ^½ç¥Ð\À>ûÖ^<|P¼W0T=$Xã ÚN.%T°éãÔ’ßü$ÀAº{ieéöÒ7ÃwÏý�wn¾†p×IñþŠD‘�Dö©ÕÛ¥ª¥ß¾øftìó{Εc/ø(ç ¶Û,�5”,(µE>òx&iUW7ð©KÿÂ<&®¥[1¯y fuÿÁÓy›yõ ø”~däè­ž�[DzImGf¡B ‚þêY…À/úæœ�òc\}”r’?x<ùso›§èW®ÄûeòˆÑõ‘(ò‘Ç9Ã$¬åS—ÀÖ×�Îcœ.ÝŠ¹ð-˜5›ÆÛÙ—y¨•,STÕ€8DG™ô“äJfö¿诟†œ?À¼ò»ÀϬ=É…ï…So™‡D¶r+,ü#—‘(ò‘ÈþÁuøä¥žû^??�ïÁœûÌ¡ª~ As¼z€JkÏ"0‘€êPub½ÝÏÿÛ“Ñþ‹¡ýGØW:³=ìÑ$~yúMóó0ÜzþëÆ›1E>™793uàÓ’Áv9ðñs›_:—r÷(æ‚·bŽ|ð ¼›%Å •Š¡‘‡¹’¡cÔ}µˆT¨ 6ˆ·¥ý(ð…nx-t܆=ûÚ=/ðÓˆbÏùòÌæ'ôÿùü—ÞïÓHùHd^¤@‰ƒºÑÄebøçW ß~ß9‰9ç�˜£8(»³dÄâÁZ)e…5ߎ•Åt&J"‚b( ¾¡û-w½>tzÿ›¡ýì+>í{ùH£(öì�!Ïÿøü^ïmã¿ô¦x¯F¢ÈG"s&)"éq$LøÂË÷¿Sq󗓘ó.Ã÷›ƒ¶;3´ŠÏÔã,]¸tª4Rèªh¨ÖSõ%Ý÷�wºq úÀ ú+ìË®ƒ®æ>ûßöeŸE^ð11,Ü IDAT�¹Ç"èmá¿ð§â|‰"‰ì>õ"’ÞAàÆ§î¹ ü<Ædµ�9ë]˜ãuPwg#ž!WKI‘-zVz“�[RÂH½ÚfZ©ñö¥À‚Þû&(?€}åßBo}Ÿ÷�=ãä÷?&ÌýõÿäU¸þœ�÷m$Š|$²»¸A…O?]ùå{‹Ãñs¥ÒÀœóÿaN¾ó`ïÊ¥"g½Ï5Ã+@'Þ¦&ëŨ� ¹–ê&ìÓŒw…À¿Ìæù‚žÆ~ë$û¯ g^żÒýì%¸.‡<‰7n$Š|$²KR ·�ë®ÒyÕ/71g¿ ó¤ŸÅ¾œ¥clËR¯Ä�`Œ€¥È]Ÿïwý6�ŸÄ<ï*äÐÑýßAϾyÅÚ"d®Üùܧß�Ri‘(ò‘ÈŒÅ^Ó"Em'¤^Ѝú›Oòý«!ŸGI´4G^ù—˜Sîˆ�[�•êØ†¾½ÛVÈ„´l AS¬Áˆ'è"ÊvrUž”²tï[ò:°½÷�Ar̳ދ5øøY ýÞ!gý9”æÙ¿îtÜõW£“Õ8ê"Qä#z…¤ÉI½¬¸?~z ªs®Ä!¯ú ìÓ~ûu>{ñ¾uV>ÏC$Ð ÄUú³¼�½YO^´øuoq˜g\‰»åñçòxÚ0ç½ÚæpÏ)øÏ\�Ž·Ç�‰"‰$EÕÄå(7/üüÃ�Íc‚49óJìÓo‹�º£È[Šc‰Ð°¹ÒÈèz,ˆÁÈ.БÚѽêlíj |(þÄÇoR"óäŸaÎùh¯Í½ñ½'㯿/E>r�3¦8P¾u¤ç'Wëüþ*ìï}+öçï¸�C®TŒ�cØáQÌNÔ+B/L�{É]_k#üâ óŒ«×?Óm'߉¹ð­Ð56÷Æ>ýÇÐ-½qüE¢ÈGfSøÊžï_Ù¢ù üËß‹}ö­±/…’•Ìzl–+9 – 0ö0ò5Tœ´J.ÖÃÞIk;ÙNøùƒ[Šyú{�Ÿ^Çýóš7Cï<ªn8ÿ¹kÑM}qF¢ÈG8yë«©)RÕ’€ûÎrøÉ5И‡Å#мäjìs¾û÷wÝÍF à­*©)á%«TÌý¸\0"§¾ªâK{zO¾^!üâRÈ—cN»9iÃ�×G=€¹à-°tëÜo<ÿÙë­Úÿ“z,5‰"Ùë¸Bèq྿¾û×ÐX2O�ÿ;ì ¿ût7ð™b-dVS<`XN5 €A ”Á±Ùž<'_¯~~)4Çœz%rÚýîŒxÄØ‹ÞËçá…Ø²‚ðù�X³?ßB,5‰"Ù‹T)‚¿Ô3ŭ놯~êGÍëéäùǾèK±_wƒ<¨¥u(¬BŽ…´Ê"£¨ HBIðeöœ%_¯~þZhœ€yò”ûüYqÍfì%o„Õνñ@á†ë÷d$Š|dá‘6ŒàîlþýP?r~ÿ¼O`Ïø\ìÔÝ6ã)Ò¸YÀ’UŒà=ëÏ•  êPµu {æÿ5ÊÛþ¨k0/úÑ‚éJY6„½è­pȽso<¼¸°èy|“‘(ò‘gMBSáÎ6Ç>¤Lž8¿Iö9ÿ„}ù§c‡ÎEãƒRIM†/¢ë+˜åsµ²1XE4£©�A–S'Ìor}æç±¯ødì̹ayyC™šðKÈW-¦òV0`ÅPÇ/—¤DúÜõÎ~z1ÔOFù{Ì‹¿¿`;Uz&°¿޼kî�';7^C¸ã)qtF¢ÈGöñ'ŸA¹d –ŽZ×饧^…jÅ�!õÅyá‚O½�¶IQ`žmÙ±vü¨ùôÐÉ“ç7©>ãFìÙ�Ð< ùR‘›ž’|P|…š¶“F'ˆB»0�ºÌÖæiÉ« ?;¦NCÖ|óÒo�]Ø�^Ò5‰}í;à ?™{ãF…ð¯‹ÿá³ã�D‘�ì»Þ§¤Ízè©7`ó�«2A¿R äM¥n•zYW…ú¥¾DÉÇ”¤uºÈ­³íˆ\’uUø·÷ “Ožßdú´/bϾ6~:{PŸ@DhYíúoyôÎßG'OGÖüýA!ð3ÙÖ ¹ôOá‰ß›{ã,EÿíJümÏ‹#2E>²O¨æ©Èí tXã:—ÒåBÚ.T½ÐÙ×™’�$l-„|Ú’O& q§Úªåõ« î_ßã§Ïï�z öœ�Äã?{ÇžÊl§‚ÞùtäeÈÊOa^~ðü åœä¢ÿ '~{îmóýÊ•øoŸGe$Š|dXxLš¸ÎMîR6»êÄæ@}SHê5MêA«eíœ(kâ:qT·­:§KŠß]l2ðù?ƒñçÌïÕœòu’ þLˆŸÌc£„�Þk×"Ñžø»Ÿ…Žœ�ô}óê¯Ä=œ“üÁÿ…S¾6�¥µA¿únü­çÄ‘ÙW$± NÔ” y÷ÛÉþà\0[1Ú_7ÆÕ7¹Rçf:u~$£!�jÉà¬åa3%¯)IT!¹>óVÂØ‹ç÷JNü6Éùï�¿ð­ï™W‹ì‘NÕ»Ÿ…n=é» sö!äÕl yÍûðéúã9 ¶ zëexŸb_úù8h#Qä#�m~V’;î@n™@- U:QŠL­Bj«À+!…4HYÈ‚ÊÐa™pèX€�Ò0ônVÒþ`üâ6%^FÜ×`øoÞL¨'Û¦÷At‚ddRån…ùBê/ŸS|×·0g~1ÞQÓˆbÏýÞ8ô‡Ì]èÿó-øz7ö¬�ǾŒD‘�<†¹ k…µkÉ»;ÞMmSƒ|Ù¥à@=¢ÅA�2 XQ´¢¢°ËT˘%QÔ)ê�§éeðúIeÓÒ" k®û£„K.w²(�4ÀÕ”z ´3³-àÊ@BÒhWïS’:¸†&�G…b×)Sp$.R\2{±P=H>l3cÌ}¦÷Ð6z;róS©=±»3ÂöWíJàÏCºþ󪂲�7ÔŽBεøêú_oœûê¶‹ñö¬ëb_F¢ÈGæÅмœµ¶ìZ^ú0¾áCå‘©£›Hd}*,BK@E«¢V@PP‡h!EqZOTþ-ýru^//º›¶w~ÄÑY¢9âÑ:ȃ� +¤ÐY1P)öû]P—×—i$w—4Å¥F¨XÁ�)nLÉ{ÀuâªmŽjý`‚:cÅÂ`Fð#»'@¿> Ýztüóò�ö ¸Ÿ Œ‘üº M¨H½ZòD ñG“:êè‚j��6 -\Õä õäZ§\u[À`d7„ç7§¢›/…Žcϼºš±SvGèK5ôÖwB˜[@³þäU8W%¹à½�DoI$Š|dF3¢ªT€DO==õ ò�\ójL2À&Žà7ëªÈÝwÃy7ß䡾³´Š»s±Ö¶."9á|íiNøñ¥*_ZƼҟ¿ÌóQNE“lg.¦¦ŽGE 9„õš*S¸•ãø•5Li«Kd+ù¦ ˜E[©¸ÍÈàˆ å)šROêÎ;¶(ôk‚‘”Nê�]m‚ëPêA‹ä=y´èw)8÷‹nºÚîÀ¾ò#Qàç"ô/ú2¾4…~õ/ÀÛ¹5þÙKp!!¹ðJHãŠ4E>²›sv±áž‚�*x.GŠ�YE¾Ò·yò“‘Û�8ÏÜr ž˜:þnêçžÀ¦+ֲ޵˜µkíë ,�_%Ë €óTB** âÙ g‹„lŠ"Á1áy'Lv Þ]ì»ûïB°º 2 “£?„/Å#gŸ %=sä.¸óùÚì…®à<½û\dàä;ŸúdÒõ`ï Ï/ÉtñšŒC�ÚáVÓÕ‚[©  i[ M¡"¢(^À£8E¨ Zì<(ATÔTÊB^†�^°O0>Ÿ ”TPQ8i*ˆß”ŽØQ¥¹Õ™Ò01BZéGª[;*ƒ r¸K…g+•έ†Ú–`¥)‰vH³QÕ¢c2 V¼<,PÁÒ-E Ø\S¬àÛ ™UOM=ë –Eb镌ƶÏÁ3÷õT‚¦­3òä.tá×7Uy½Å'Í-FÈrõd ÕâÓÖþèý¯‡Òzì™ï‡Ž(ð�YèŸvÞü9úå÷A³<·Æ÷œ‚ÿÌÕØ‹þYT;ÈzîàŸZsÍIÀ�q0E‘�ìÍõ<øÒ<þ7À‹�!Ñó„+Ö ÀÚË‹Ðýï𿲱˟»ž›¿óðíçbzÄ– Wü3ùÚMŸÖ¯1ÜuôRÆvù½‡icõrÃà‘Jeµ°d…¨9B`‹] m­Yd E@- xò錋š´¡Õ#sñF TD‚ª2î§tJç€ò¬-Øg÷;+cdÉýL l5üjµçáàMªeëóု€ïÑF< õ6Ç·ƒÏo¥¨ön Ñ(LõR·)Ï86+^ ·€7­.ßý8,KÑ&Ç+¡Ñ‹PÓEÞçñ$$f¨Zƒoí¹hÿ ô7o;Œ=ó}°t*û=%ôOù!}'áKµö¹5¾÷düõ×b/z²xì é±WŸŸ5×¼,Š|ùÈÞvm}&ðM 4�çù-ð<` ÓOxùZUÖ\°ö;”+TôîÃ7·*o(Dh­lâ9ôß|?<ïÜ›ëÞ¢žðÉÉDï¿¿ÄÄŸuc­dè¡ChviB÷CXí5]®ÔW ¾lR”’@"E" r¡¨¦&hP4:£~Öª�ÀØtl5>A|I (å°:vyÃø þŒÚâQ¡6ì [±“ƒY2:†�#ÏFìx}ʳ5À bÓš­+>C±©`-øÞ"øLñl˜‹¾o3þ­)ž¯b Yæ-A‰G]±9Ó@ÔŽ‰÷”Ál^‰Þó0u̳þ6 ü^À<éçPzá_ÿƺæÖøÁ'à¯ÿö5oG– -ðžzð…4é à}qE‘�ìY¦þTàóø{[¿ù+ˆé =)~C•â¨ßLqšµ*Ó�s;‘oOœ§Ïå<kɯx9kÿ°v9k7Âå?ùηÅvI’ kÞóZåÿÓ®�J…¡#ûJøÃE7®ñ,9\É Z?D¥­­,6štYBaDHÄQ¤”VèB†ÒÀk¢˜š‘,8BÚ\ŠË—ŠvŠAÀw+~5‚qŠk(yÝÀXÀm…ÆeMsr@¨�Ãú ¨áÇrRÛ.øZ‘ů‘‡¹ZòÛíåÏrõW$X“¡Ú‰—**“éÐ ÜŒÀ_…4¡ª�‹ŠÓVàC±å_dJÁt€íC+GáÛ/YDÀxÑcx­ƒŸÀûÜ``tF‡1 dr \E€ž¯)6[2ŠäAÓÞÍB–AŠ4‚mí¹7-¨G-* ¹LvlYJí7T| OýkäØ-Å䳂ÓVŠàé)bg§ºòÖã ñh⮄þØ{à¢7nü0 .�[ã�‡â?{æü·cݸÀzæiÀ×)R]îˆ^ÜPù½Á»Z&ÑU‰°O[ñOþÐ9�çÙвà|Ä?˜ô×úùA€k‹{¬eÚ£/;y‰3?ù߬¢éÀÚâ9ÎÃ?òÚµ-³÷ÏG0·þð�™'VŽý³jôwãO[ƒN©åÆjê‹W6<�råpÛ˜˜òÒ[-§T5hñ6”bï¿uTP¬€E-r 8«ÐÒ.È…Ã1=¢Z]£ª*M ÍqÁO(�1ðýBsƃ¯ `ÆÇ±3x0ÃNxºÓ¤»¿Ç�ÚV1!*@ 5Sâ}ªBS‡h,fêöWˆj¢ú{W’œ¸ Rº¤ž¶Ä;ω+¼]µ]Àͪ ¤e!éê„â9ŵqVy¡?â!¸ø�„/|úWέñ–„ÏÎæðõ ¤GN¾¶‹¹æŒ(òQä÷Ï¥:kþÏAð~8¥%ð‹æÑ~ E�Ýý cÙ#ªç2ÅILq›xëÖõaN¸Ïyk5åÆ3]Ó$á‡×¨Z*Ë{ÈÓ>ü¢Þ”î>Ê}�d©’¶+Á@žš*ˆÊ-Ñ÷ m­OŒ…&DQÐPQLE±}H› *F¨h#HH2 O�TtBòdØ÷O &&‘Á­¸þMÞ N<šõFîï2LžÒ¤d70ùZÊS¡ý´¿¢í¤�¸²Áå87¦.™ ™HBJYr’"±`µeÙçcº½‚§€Qr§Ó3‰K� �==ªÐ¯ÙŒ¼æ-øÏ6¯™[ã�> ×Á¹ïÀsïÞÇ·‹wqÝK™û¾U$Šü.©´ÜHÖú¾Ð„^v°¦�¡²›�À/~µ :è�ŽŠpóZÂMÇ#ç²VÛ:1YM´™Ü7Š© Ѱ`ɧÝçII0Ým¸e½ä«»-K–AºÆ—¢Ò-è Ñt±¡Í°Z8$Láö$Á+ÁÑL¤aÀ“5Y¦* ½„ä0$‘ íQ¤Ï&ቪäa vü+¬{ ׇAV'›xÁ¢`Où&�Ûʵ¶Ež‘IǨ‡õ uuUŒ«$B£\œïÏÓBØ“ª@*M!�*<õ\—âÈ‹™$ß“5ì²ßlÕì%oÂßð!XäÜ/.,ú³ß‰yâº´Ž¾ ,Û�kO~Nù=É3ZBÏ,¡O€?ea%g˜ž��~@ä2WF�ßî^p£àr¦#üE.ŸN"¤H–ª•RMòFIyÄ8‡zï[gäðj�Lìƒ5Ûöã X~Y*aF'qÐ)ê–¡¾7 ¶­ •˜Ž¥¸R·ÐÙgµ}¹¥Ô¨t+TB±�®AQ‘ÐT ¦°¨EãA[çì�zÅ øEu:º¾È9|‡šNî²>½^—3Ø)X¹»z+Ò>hênõÚfpƒÁ²™ô¾!Ò ž¼ .gCÒH ”ÕaÔÊŠ+jÌ'.QëìÆ�×7Œ½ôÍøÏý°mU$j}Y A §Ü6bð¨MŸÐ*åê)Dߪ÷(SxðL�/—1– <êx ó5!h†¦BÅâ,ÆY ¶bѥݸ¾>XÙ�ëZŠêJei7L-F|/˜v4TJ"AÕšbtJ�»k›ôeMY:F@‹Š‚‚ Úµ£ðÉQÂDmŸzü‰Má©c†‰�JÖï []‰Í”š[0í£PÆÔê4š7¬Î�µêDv}÷õL`/~þ†Â}'έñdáÆk ÿ?˜Sr€¼ã¾–·ðÐ9¶;øÿÛ;ó8¹ª2ïÏ­[Õ]Ýi:é$:{BXL”5 K€Û‹‰:¯h£2,¢ã¨Ì;.3¾£"’ /ã>n£Ì«ð:(ê8i—P‘$ˆ HTF‰€a Y:étwÒµÝ{Ÿ÷�sz!iBºººûVÕóý¤>�®®åÞsϹ¿ó<ç9Ïs�vùrÒþÏ¿k¦½»‚…~¸›~š³à/ász±kðUåý×­Šqm—Ry�\®>"‘‹l–;´â­IÍHK‰ù|Âõ��D]h|ð‰ÐÔ…H>ŸwûàêÄfÉÉ…„[¶ÃÛ„ø`H@ª‰Dßž´A楒,H{ÔÏȧüY ù¦™Í3 ¦ØŠÙ7SÂG›ê¼ß§„+¦‚„^ÎßóˆŽÕ".R 6Ž ð0$E¤12©9�´É… L¡9òŠÐ]Â>¡þ1³vá-Ù‰·o &»IìÂäöþ¾‡t�P?Ó#H‰] píSßc†Ê 'ĶÙ@UÛäÐmªè Éc« ÖC�tÏy†ûž�ó„\ÂîððC>ä®HQÓú<‚!H‚Ÿµ ‹)Á N|G›º—Äï'üö'᱓G÷æ\=Ñ÷>ƒ®%qÚ½1R3€{€cJxïñÀFÚ±£¨È—@v è¥x§³è¯`ä}Eqøáü/°kñ£¥xð`Í]ƒ;2Nž&y9x÷——�ú{˜G–€Bûe¤w…6}ù=6‚þñb‘Ç÷]¤ÛžhÈg£®& A�¤PÿŽÃØ{⺖YÜœø3÷o�νñ މš—Ї{„Ó…Ü4�BÊ‹¨³ÝÃøö¬Á ÝñÝŒ'›ˆ�˜zðƒpŽ­<Ô …p`¢’s˜ û½¾ú©¾þ�ßZ °+òÂ-øÝ»Ý ú“¤zz Ð#65pD@A|çD�yÞäî0�9ü+þ7Á·¯‡GVŒîÍ…$ò£ë£µ$ÎXÓáÓŒÝ&·l ÷­ �ÿ§ò¤"_NçÀ¤ ûs‰3Ù.­0¡HtÓŒÝ.öŠ># ¼ëâWâD¡'êNô A:™Êf/ Ø·ô”&¹ùØ~>� _0­æ™âñrßW/kçÑ ë¨ÿôï|àwi¢ûgP<¬•0ÙF´s!æzG çÒ3¡¡Y¨O bÄAv; â‰M# @Â#B _o�z#2Uðfç¼”Ab$‰‰ÒPh)B.[ ¸GhÝ-fö|éBŸ÷k€ì"ÕÛÇ”®þ¾Ô ä·†ž�mÒøA+iRÞŽtÖ CÝOÁ´”×ç‡6€0h?[/élD–E Ò¾�´N¹âdÇÚÔñ/½†à;øCûèÞ[L"ÿuaápú�1ë•SœÀ/ãç¬V‘W‘/‡:ÀÞì¬þì¾§¸[ðÃþŽ—ñV¼¤Œ` H¬×n?êúó"SH…ÙüEâq¢‰ê2g÷…›Èû…"¡�^™"lè“�7˜þ;®Äpç =½›ài6As3Þï®&¸¸S"Áá›ix¬�äÞ©—´yä'¢Ü�õì<5™2ƒËÃ÷þO*©"þe#øîÕðÛ׌‡üøjú³�ðöÝ1é’iàVl óX9ß_yé*ò%ò`]Ö뀋cÜù†§‡˜UŸ:�¿C»H\Ý4)¿Ð_x£‰¼Ó‹õ©ëÈfoNµ˜ÓL·!IÂ$$9m¯gv¯5°ÞdX ÆÈI·†p6²$CBÖY œÍåù��<ÂdBØ8úH³›qP ÄØ¥ÿ5Öä™Ib˧ñg^• d#ÑÚ•D³ÉÐÑ‘‰:€µï}ãÖL†çw4ã=�úgzȯ\D: \5M’�Í‘äžÙ, ì;‚(1'!éy!S�€âtð’öëŠv'ƒ$l·5Æ CdŠ`ò Ã\ëB m�h“4�$‰v‰!ŒÄ˜Ìüm˜¥ÛÉv�yoûöÀäwwû}/àÑC1NÕu½ˆÄ[>E˜ìGxóh…^ø· ‘™%:ëÊ3SnÁºØËÉ*yù±²‚Ò ²\èÜRE|òÝ›ýfÕ?£À¯Óîk. Š.0Qâš\æc·`2‚ã›ÄÆLÏÔ§¶ò‚1f0–dxšá%JEp@ìI†L§û¯û¹|ù`Xü0¯V'ÐÙE‘.Š/."fiÆ$7oøw�›ëçY’bú¼@f-*$êæ…³Áoƒâlƒ7EH»[–7t¤&2˜œØÝž€‡¨z`Œñˆ7Ù3º—Ù]‘>HDÍá,1ø{…`v€<Þ x}»Höv‘hÛF$½Ð[ÀüA¨ß S’¹™Ø(ý‚¤�iPÌA²8¬¹ö ~Þ. ø fð–®ÔÁÐR�MY[Ë!ðÝë.ùWòé}D÷¼}ôÝá:„5Œ})|ô3àXïf¹Y�Ýʬ¨È—ÌX\Kç9KyñÚ(\ç< ç•ðÞx¶Æ³_Î^‹Ç—.Š.úVg&#"2˜Œ©ƒ ÀÈæ ÅLæJ³ô*žšÙÁ–ÿØdû­}ÈʵÚ6œ”JÒU—caËnÙ»Xdë\¡ió Á¡©E¤eä¦�oÓÚI€˜¢kÄÇH€]y2Æ`&LB˜“kDsÙ'!}äß%fÉóÙŽ—è"_÷£Ý!Ö ü�±E“Š3Ýc®ý2tœfHÁ� bœRM†Ì3xnâ6Þ¯1†�p„°}ÿ/€�uö×%Èßž„°&®…îG:ÙsUO·Ãƒk×"K—b6ÏÄœ2—ĪӯJ²sõô4™ƒÌ��eêC´úÚDv-öHÎšš„º¦ÎG|0�ÁËCHd+ Áä†&aÄÔA¶öL�¼ÄBH�x vI 8Óíõ�Ù#ìÝ%‰Ë·­Ø€\ÝÛG%ôÅ"¯ýþ÷¹£§‡×S¾¸¡¿®ŸÀþR‡��Ò�>*ò£få8|æ+°®ûs™¸¼Ëk€�•xoÿ˜³ •ør,ðà>çqXgµi¢¢q4ãÍ‹oèw3Ѓ_4 iæbö;Es°S¾xĜÛö'€òpÃÞ,< �ÉàeÈÀÒG 7ì4ÑcŸM‘on!{ûÑ¡±-à½óC¾0~?Úñ¿Ìçqèˉçß��v¬R‘W‘ í8ý…T,ƒ5o°¥oÿ­D�ÿ:ðþýž[ŒÝ:¿Ä.U~Ê K=Ð�] ¾ÜÍä?ãžÿ 6ÒûVíNe¥›¯àOØl_}¨«rRÉ¢ÁØÿ�q¸Æe L£†­1ÿ9àk®mînt7„¯ºsxëâÿª›¼ÌuÏ©•·¯\åÚõ�Àm’ø0<ðK Q±ÿæ€×dÜkĦå‰Vº JÙï=kÓ1li,c�ekÄîwp¥É¹1zªçñó(bÑ(Oe!¶²äy®¯�Ä©ØâV�1iþ3°ÞÃÝÚާMÀÙLüÚR+°�ÑÃ@Ü$áG%{76;U´a×ä¿ã„ÄÇÆ |ëzØý¼øÖ•ß üëž?k°M79¿x‡ |…NFø& }�±qö‘{¸-xFC<E¬,qÎs…cGøÛqØíšM1jÚ„»**ò/Kû$}ï4à§”V4æLàvJKÞóK¬KýCnÐý"6%o€�Ú.ºÉÄ{°u+7º× ¬Ýí®Ä¦óý6i¸Zñåø6ØN^9Tžv÷‡?–Øï6¯öÜÑØš-1<×Uz¹Uä…•“øÝS�8Žf¢q²{O)ÿ'¬‹ÿ΂¿Â É&ìÂ_8ÐÝ>ß=ÿ;¬¿ »&'nRp®{î~íJe¡dg°)k·¸¶ÖÉ“r¨lsãò÷%?ÁºÃ—`ófÅô<_£¦"(7Ôc'ù¦8«üÜCxírlà^)�/Ï¸ïØ‡]wûgl®þiû½n;ð†J—ÝÌÆFá� Ę=t¹cÚ®ÃiÌLs|ä&`Ok“(%²Ã�Ó_•ðÞfgHÜçÆ~\™IéKž5C­Þ�“‰N#Ö…þ¬ $NÄ®™•"ð?wŸ½—¡ž»°ùõ÷/Xñ,v¿ý@5³_cKG60Ù�æ‰èÂfŸRW}y>�MxóÇr}°Ñ¶­Uö`ƒénÅÆÍŒ†´{Ä�U%?"í1:–'–5Â=úUnV]Ê û%6yECnß�ÇH©d˜`< G›²÷_œÕ¿I~LÔ—ºI÷;°».Êæ¢× SÓì^wã¡ÒÑuyùƒ²2fÇ“Ö {îÈ1üØu«r&OŸ€O×9ÑWJø¿Áºß�&øPÊO¿úTá¹�D¼—Tä'‘éØÔˆqc@è/ź=ˆÝ»>Z~‡ÍñÜ7NÇÙí¾£ ÆbÉ$±kï °®úÿ�¶Tw½âÆéÅØ›jÂ`ƒ‰ùh�ñù'€›±®ðæÞÿ0v-®{ŽU¾t�¿멹]WTÆŸÐõµ¯WÙy©Ë^Eþ%E>Î$J´àu3[Ío�+p ðA¬·fÜ&K: Söú¿arJÄŽ`= ŠŠ|E‰|)<Ž�¢Õílñø¿Ænýù 6“˜ê°2‘¶fEµ”–> »¯_Q‘d&¶S5ñ6�ðíÖ±%�uÑ/®Æ¦V”ɺ÷/®¢óQ—½ŠüV|5Å#=ƒÍã¼U»t¬þ�ØhàO`ƒ+e20À n©"¯"_µ"_-<ç,ø-Ú�c-ðoÂæÿ¶¢Ÿ&R&‹O者sZŠÍÈ©¨ÈñÛ_*Û�ÿ¤våXs¦{|¸‰¡l‚f¶)ŠããØX�jäB½¼*ò`ˤSçÑ� ²{T»ql1ØÔÉor7×'ZàQw�2Ä@¹èjE]ö*òà„±Œ›àïÕP‹µÀ/:œ¸¼j®2¼ø?U~Ž+Ý}Q©q‘o¯¢sy7ðU4=qYŽÍZx#¶âŸ¢LW_¨�óLS�[£UäkXäÞ‰MUékwŽ ¯.~„]‡7jÁ+“Ä¥Ø8�Zñø­ÖK^Û"ß]…çu‰ }l8›ìæ'ÀGQ½2y¼ø÷»Ï¿V/{m‹üÊ*>··ÿ�ͨ¦LÇ9�¿ÁœÕ&Q&‰ Üý Ö&þó±Ûé”ùö*?¿7?êµkO8Ë€·¿Â¦ Ý—ÓÈÌšãìRQ]�ž¿ºìÕ’¯úþCJ«?¯”Æ1ØØˆ±%c÷h“(“Ä©Nàky¢¯[éjTägKjä\/î¦hŸ�~uðð 7n¨5ÃñÀ:îYLÕîP{"N�]۳݀oÒn^V̰G x;ðð'ðª©ÊdðJàn`š6>pž6Cí‰üʼ¾g?×�?n†q[ýïíÄh ^©9–?¦kS ¢.ûùö½Æ'?Ó@Y-y€ À›±®únme’˜çÆw›6Å‹X�& «)‘ŸGuÕN-'a]y3´Ë—Å’¬k~#° uÑ+“Ã,'ð µ) 8Q›¡vDþ½Ô�Ý¿­3þC·ÐU%3�{¨Îä^å´æUäkä<ÛõRð `=0G›BQ*–fà.4éËË¡ëò*ò5ÉÑÀ/€EÚµ�®%T�Àí¨+úPXŽ]ÒP‘¯r¡kV#µÉzàm E©ÒNàWhS²¾ýmµâk•Nè�Ô¦P”Ø“¾§÷³QSó.ûZù•ÚÏ_’yØ`¼eÚŠ[À·T°JâBj¼hW-ˆüÙÚÏÊáØ(Ýcµ)%–÷èoÚ%Ñ œ¦"_½�-=¨œVlr—“µ)%6àFàmŠ1QÓ�jyuÕ:Ó°©1_­MQ}J¡T$ŸÁ¦LVÆFMï—¯v‘o×þ=*¦?NצP”Iå“À?j3”…WRÃ]yeš�E¯Y«Ý'_q\ |H›¡¬Ô¬Ë¾šEþH4³[©4·¡åe¢y°V›AE^EþåÑõø±Ñ€M¼ñzm E™Þ |^›a\8¨W‘¯.Úµ_�™: xƒ6…¢Œ+—_Aã$ÇÓh©IMP‘W^ŽðŸÀ›´)e\¸ø:Zÿ|¼©I—}µvªcÐ’ªå$ |¸\›¢òPÓ0Ö¬pcËצwjr+]µŠ¼®Ç—Ÿ„³6tß®¢”�û€ÅXwý×€GµIÆ�Åά)ªuöØ®ýyÜ„þ&ìúÖ—µ9*ÝB{žÃæ¦ÿ–û½›”ê ì—PW~¹XUk©jì8ÍW?Þíû%àýÚ•sÁ”Šbv 뇱5ѧçŸ~ ´‰Æ$òjÉW8¯fi_wݸ¸xL›C-ye\éîv°y,NîçŸá~Ök3ga~õ¨ÈW.º?>ìq7™»°©oŸÓ&QK^™öí'úià$†Üûg¸ç”Ib÷Ìÿ@E¾ri×~\66c݆wcëΫ›P-y%~d±|÷a]ú>pÜ0Kÿ|¬Ë_±¬R‘¯l£å,íÃ%³ [[þnàÇÀóÚ$ŠRqÀ&÷ø"6`ö˜a–þ9ÀôyS+óßjùWb#S•C#~Ç�ëoƒ»A(U6óUjšxÄ=¾æž[ìÖû9¯†Ú£ 8ÞÝûTä+ ]�yv:1¿¸ئM¢(5Ç“Nð‡‹þ€{ÿ`a•Ÿÿjùʤ]Çøßc‹ÍÜü]¦­)ôb+‡(úOß&úga·#Ÿ Qeç» ¸^E¾²0®3*°[þ6àgØÈxEQ”ÑŠþÍî÷ÃÝýuÀÚ?‘Ê^ z5viw‡Š|åp,0£Fdüš¡HxµÖE)'Û°);Ýï­Nô¬ýWQYÉÕ<ì²Ä·Tä+‡Z[�ÊYéwc÷­÷ê}HQ” bð}÷hrÖñ@0ßÉØ –qfµŠ|eÑ^å×*‹Mi9 ¿Iï3Ê¡ ÑõÊP‰Yù.Â& ʪÈÇ�êÜÿä°�s'°Wï%Š¢TûgåKb—T,ý³€Ã&ùSÀÅÀ7TäãÏñÀ´*8�~à~l$ü�€-z¯PÆŠg(1 ÈP‚ž‘²ò�7I÷𣪽á«EäÛ+øØf(ü}n0(Š¢T3#eå;�¡@¾@ËÇjà£*òñ§’‚îöb“Ñ܆uÁ?«ã]OtM^©Bà!÷øœ{n"²òÌžQ‘�/ â½?>Âni»Ë=~å:´¢Lê®W*”ý³òË·í•Kô/ö*ò1äl}à8ѬÇ�ÜlÕñª¨%¯(câQ÷¸Ñý>›¡õüÀ+Jìî«TäãMG Ža u쀨ßï,xEQK^QƇ­¼8AO©YùÎꀼŠ|<¹|’¾w°Ñ‰úíÀnsŠ¢(“ÆþYùfb·È]äDüìV¾ýiÄ.üLE>žÇß8ÁÖºzQ* u×+5ÊNà+î08u˜¥CYùV©ÈÇ“±éÇ‹§ ˜û96«“¢(ŠRyìåÅ z¦§;±Ÿ]­']é"_î­s9à^ìžõ;�?é¸P*u7)ÊKŠþOÝ£jQ‘qêX-ô¢(Š¢¨ÈÇäØO/á}à ½ÜlÖn (Š¢¨ÈÇ‹“9ôõøkývlpEN/½¢(Š¢"_æªß‡Í,·¸[{]Qj�®WùJ¤}k}`{Û½@A/¯¢(Š¢"_y¤°µ‰Dýà9½œŠr ]¯(*ò•FÌA ½(Š¢(JUм¢(‡€®É+Jíâi(Ju£îzEQ‘WE-yEQTäEQK^QyEQÔ’WEE^QEQyEQF�ºëEE^QEQyEQEQTäEQEQ‘WEQEE^Q”Q [èEE^QEQyEQ* ÝB§(*òŠ¢(Š¢¨È+Š¢(Š¢"¯(Š¢(ʤáOÐ÷Ì:´¹eü˜5 ³þA#<@ÿ’ÃÀKEÄ¿7àfÍZŠ.Õ+ÊdsâD|I¹v×x@¨×LQEQÊÂk€»Ê!Ί¢(Š¢T!*òŠ¢(Š¢"Pˆ´9EQ¥,”e ¼œ"ÿ¤^EQE) OÄIä>©×DQEQÆÌO•ãƒe<¨ß»IÃèZ¿¢(Š¢”­À;�\9>l< T-tBߨ×JQ&� ´¸ÿV<ç/z Á?z�(` ë‘OÞÕÒòB »Ù½[÷Ê+JŒ(›�µ)E9±“vAŒ€!ƒw=éSoÅäo‡è$ú¾ËŒˆV U”Z@ÝêŠR…€¥&"AD Dˆ�£¯(*òŠ¢T2çyP 0D!ˆ�b"ÖjÓ(JMMøE©.D0áÏæÈÔêž8ëyá°ã„gýYüá´ç$g0º¯(Š¢(/øëñe‰LÆyîDtr¯(Š¢(U‚a¸×NE^QEQªÐªGŒ "¯(µ4ÃW¥Ê…}hÀëZ¼¢Ô¾6�¢T»Ê[�7tÕ{EQEQE©Xþ?&%$ÆéIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/free_edition.svg0000644000175000017500000000244614757047403023434 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/full_screen.png0000644000175000017500000000124214757047403023257 0ustar00paynopayno‰PNG  IHDR;0®¢sBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î<IDATH‰íÖMˆ�QÇñÏܹfŒIͰ ‹›·ŒR’YXÈBDv,ÔMIÆìL² ‘’”­X 5‰ì˜…-¥ÌxI’ddb3(ŒYHŒ±8Ïmž¹wî�çyÜØÌ¯žÎ9Ï9÷ÿ½ÿ—óœÃRšÑ‹gÿˆ¹GóhļÃOÜŠÚz*‡¼DM¹Ødnb�p«þ¶ q#Û“4=X€aŒGÏo ¢-´_0³u8š+¢÷ø>ÇÆ¯°_3€÷©kˆÙî‹/È•ýàqô_ãMÔÏ¢o8‡O‚·£Bôª‚¯á­ài.b^p– uóB(ª •r\ê·ÇæãzJxNÇÆmèŒ�‹(”ƒ§Rø¾2èTª(®jœ�f]7áX›9®¦Aì­1?WˆÜ©„öƒáW�¹Q¡Š+ ¸®šÏ€Ó(Õ)–ÜŒKQ[Mg°¡žàYô~ÔX×�]Ø’œ�õq^8¥ú§±5&|ó·cGì}‹pRÕ· W•Öôjô.‰Æ°ë±M¸�ãå óeã�X‹ûÀ ÜI-i‡pOo+ ¯Üã�B­ÁV image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/hammer.png0000644000175000017500000000043214757047403022227 0ustar00paynopayno‰PNG  IHDRÓ˪sBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î<—IDAT8�íÒ1Aào¹ˆÂ4•;èU·p ½Û8ˆ¨‘ ±Vƒb–ÝÍîl(öO&Ó¼|™ÿeß³Æ'\pþ0sñÀ+d5N.ËšP›!��Mqm½± ¡ †ØG€² Âå™`Œ6%³¥y}•mÑP¯"vÞýXkåe…ó?©ÙÊκš]Í ÿ[³öyðyФnEIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/hammer.svg0000644000175000017500000000465014757047403022250 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/health.png0000644000175000017500000000412614757047403022227 0ustar00paynopayno‰PNG  IHDRŽŽçý0sBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î<ÓIDATxœí�ÏkSÏƟئöbš¶I±HuçÆ_´bKÛTÁ�îºr%îtëJý.è¦Kq%\ñ/pq·MlMQü�)ˆ %&M¢­ÛÆäÜÅýæ{õšœ™3g’“™ó|à@i&ñU?¼ïsfq„xeOÐ3¡8D ŠC” 8D ŠC”ˆø'€+b×BÌà€Eð~œx†£Š(Aqˆ‡(Aqˆ‡(Aqˆ‡(Aqˆ‡(Aqˆ‡(AqˆÖ‰3::Љ‰ ìß¿?èR¬Ç±áJ¥Rν{÷œíímÇq§V«9÷ïßw‰DàµYz^€–+“É8ÍÈd2N4 ¼> ¯À ð}]¹r¥©4 .]ºx�¶]Vdœk×®¹>~ñâÅUŒgß¾}w]søðáÎ"Œgjj ÑhÔuM2™ìP5áÁxqΞ=+\322ÒþBB†ñâœ;wN¸†G?FÊ!‹áóçÏèíí®Âææfª Fwœ©©))iŽ+Ý-ŽL¾i@qôb´82ù¦sŽ^Œ'‹allLz=;Ž^ŒgzzZ:ßG7ÆŠã%ßUº1V/ù`ÇÑ�‘â xÊ7ÅÑ�‘âLOO£§§ÇÓs8ªôb¤8^ÇÀŽ£#ÅñŒŠ£ãΪâñ8Êå²çQU­VÑ××צªÂ‡qG%ß@4Åàà`* 'Ɖ£’o0 ëÃ8qTòMæ}%N<Ç©S§”ŸOqôa”8333Jù¦G•>ŒÇO¾Øqtb”8~ò @qtbŒ8ƒƒƒ¾ò ÀQ¥cÄ™™™Áž=þÊeÇч1âÈä›|>ïú8Åч1âˆòM¹\Æââ¢ëŽ*}!ÎÐÐNž<éºæñãÇ( ®kØqô!ÿ¦Ý‘É7 H$®kØqôaDÇ‘É7™LÅbÑuM4E<×UV¨1BQ¾)•Jxóæ J¥’ðµ8®ôÐõâ ãĉ®ká8ްãG]/ŽL¾Éd2 %sŽº^™|³°°U¤ëÅå›b±ˆ·oßþý³Š£‡®gxxÇ�w]“Édà8ÿ}Ût¥RÁöö¶ëzŽ*=tµ8étZ:ß4uv=tµ8²û7¿Bq:CW‹#Ê7…Báï|Ó@�9ªôеâ$ a¾iv¨ÉŽÓºVœt:�H$⺦qþ+¢Ž##Îää$îÞ½‹R©Çq¬ºnݺ%üûËе‡œ*ùwѨº|ù2­8±XLø§5ÖŠã7›T*¼~ýZS5öa­82{9n¬¬¬ V«iªÆ>¬ÇoÇá˜rÇZqüvŠãÅiÅqÇZqüŒª>àÓ§O«±kÅñÓqØmÄX+ŽŸŽCqÄX+ÎÖÖªÕªÒsyÔ ÆZqµqµ³³ƒ—/_¶¡»°Z•qõâÅ ìîî¶¡»°Z•ŽÃ1%‡Õâ¨tc9¬G¥ãP9(Î/¬¯¯ããÇ�mªÆ.¬Çë¨b·‘Çjq¼vŠ#�Õâ°ã´«ÅñÒqªÕ*ž?ÞÆjì‚âüÅ«W¯ðãÇ�6VcV‹ãeTqLyÃjq677¥:¹cì «Å€r¹,µŽÇÖ‹#“s666š~)i Å»� Ö‹#�™o¼c½8ì8í!ôâÔj5¬¬¬t¨{°^œ'Ož¸>¾¼¼Œoß¾u¨»pl¾¢Ñ¨“Íf�fÔëuçÂ… �×hèxm¿R©”³´´ô›4•JŹzõj൙zEþúÁzzzzpþüyœ>}¹\�=ÂÆÆFÐeKhÄ!z±>“ö@qˆ‡(Aqˆ‡(Aqˆ‡(Aqˆ‡(Aqˆ‡(Aqˆ{Ø÷�õ¤Ýä"þà"€�€‹!fðÀ¿#ŽÃwUï0ã%(Qâ?øxŠåÌfIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/health.svg0000644000175000017500000000540114757047403022237 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/hide_3D_coordinate_system.png0000644000175000017500000015045315143647637026046 0ustar00paynopayno‰PNG  IHDRùô>(T:ÈzTXtRaw profile type exifxÚmP[à ûç;yá8t¥Òn°ãÏ@*µÕ,‘LHèßÏ^L4Ë5çhÕÊ ÄâB›‘¢Î8qTgt×áNY�e,¯L§îÎL ,]Œìí…í^¨º2ÛÃȒуìnTÝHxÈ ÚúVÌÕÊõ [�wØZa„wŸÞ‘üµç^ ¦·'ˆÂÜ2¢ˆ®d¬¤�DÃÁ(žplèæ�` ÿæt"üì'ZSÂJÔ„iCCPICC profilexœ}‘=HÃ@Å_[µ"A;ˆ8d¨ƒ]TıV¡B­ÐªƒÉ¥_Ф!Iqq\ ~,V\œuupÁwÁIÑEJü_RhãÁq?ÞÝ{ܽüõ2SÍŽ j–‘JÄ…LvU¾"ˆ~tac3õ9QLÂs|ÝÃÇ×»(Ïò>÷çèUr&|qŒé†E¼A<³iéœ÷‰Ã¬()ÄçÄ]�ø‘ë²Ëoœ ûyfØH§æ‰ÃÄB¡�å6fEC%ž&Ž(ªFùþŒË ç-Îj¹Êš÷ä/ å´•e®ÓF‹X‚2ª(¡ QZ5RL¤h?îárü"¹dr•Àȱ€ THŽü~wkæ§&ݤPè|±í� ¸ 4j¶ý}lÛ� ð \i-¥Ì~’^ki‘# o¸¸niòp¹ >é’!9R€¦?ŸÞÏ蛲ÀÀ-гæöÖÜÇé�¦®’7ÀÁ!0Z ìu�ww·÷öï™f?²ôrÀrÓÁt[iTXtXML:com.adobe.xmp ôœYžbKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEé5饯 IDATxÚì�yœUµ€¿SUÝ==Ó³f!TdG– ‚²*‰‚€¢€’ HPˆEÛ3¸¤GA ‹,âBF( ¢@"ˆ€‚âSÂC¶°¤Ifß»»ê¾?ª†ÌL÷�m–îéóý~óH2ÓݧnÕwϽçÞ+®ëЇUÀÁžç­DQ”ÑD®²XT8�žžÎ>’^,,c1E?\×�ü h�׳ŠìóÏs]w/m Š2zœŽp肃8d¹µ¸ Q½+ʸ þp i¼_Œ’˜Ü®¢W”ÍÀ ¤Ó–#,LÚ:dwÜìž!8€9sLã ¢(Êx þXàÀ”ñ|]«Hã±p‹ëºjÓP”M#MšF|ör,d±©ZÍ9dª�ìó¶¯N“VÇ+Êø ~p3P?Þ¯mq\önv]÷Pm"ⱉ<¤ÓƤYb,\‹14Y¹VfÛ«™ú/Öíɬ´�6ªyE{ÁŸ \ÔNÄë[EŸ]€;¢BEQ6€ÆsY``Þ\Ì}Üìd‘X 6�cÓµÿ²i³ŒŠ^QÆPðg?˜ˆ ¾T$a�BST° (ÊÛ¦òFXÚýWÓ\éà¾íâ˜Ý –pÈÎCXѨ¥wŠ2v‚_|w"_*’‡°PáQá‚¢(#§ò#HV4™nâﮄê@ÀÂ’¤‘nyêNzyÚÒ€)ʘ> 4©‰~/¥t“×ÎÑ/Ð&¤(#eòi‹¦¥iDÒ�Âò´U—ÈÑ��4�… †©YXÿú¾éÙ0EuÁ ø*+†÷ã”Xüj�o»®ÛëyÞmÚœe˜ãI™G4 ¿˜Y³ÄŠ÷[ûgÈbaÎÁ'Z9–=†HN£¦(£&øK€ÿÅòžJq¸np©ëº'i“R”¡„…wÒFH#ׯaƒµ“-HA0`R8Äû…Ý)Êè þàœb|©J s.u]÷DmZŠ2Lôa/õ”½¦�ƒ,üŠ˜Aìh“;$‡ÿÞw}µV×+ʨeð'ñb{o¥\x³5pµëºŸÐ&¦(ƒ0�BSé}ïñMÖžýVŽOØ‚ ‚=u—Õ¼[ƒ¥([,ø‹¢ >^Œï¯Ô«kë€]×ý˜65E ’nL“^1ϼŸ'b9œ|Œ1–!�ÀXØHø4²¼‡hÀe‹3øó‹UðPz…w…˜ÜäºîéžçýV›�RÞŽGšf!óv|ÒZú½}w¯èŽmï€d b YɘX`áàã û›}ÅÈú]»ÀŽUpÐà?ëƒÌ³p‡FZQÁ»Wg{²ìL’xoÜàºîtÏónÔæ§”³ççíhìô¾˜Ö*fí@ÖÎ 8ÆËdŒñÅH…a·×Ÿ¢h)ô‹fZq`ÀYoõ¦…ék kTòJ™Ë=\ œE Œ†O¦Í0¦i1žRÎÀ>�~:ÝÔv§þ÷M*^ê6¶Y“#kú-cz1¦ËعöÓðGú]Ë®½v»vû|5cðÿió=�²RÆ‚OWD‚/‰$y²íx5¸ÂuÝÓµ9*ešÈKZ ½8m}:ݵb'úÞí¸þG»,VZˆ$KzˆÿqzÜß+ó}ÿ³;:6ôß»—? ·ßës“ÆX)SÁOnP$Ý”£äD‰ëºÿ¥ÍR)GË“N‡ÿµØÈ�KMæõJîìµ›19Ìÿü—%ÿ™÷˜ÉÀÛo_ÿH&\ÿ²ðÜR8Oë”±à/Ž+%ÁOVÉCx¨Í·UôJY²Ò‚o„€y|ù…}ßXrVÖ,»g�a� P3®¯24›Yî±x«º>ýBàq}UÀešÑ+Š¢”„ào§Œ‡è J~˜èŸUÑÌ远¯ÅxŠ¢(E)ø�[€=4$?Hôþ®¢Ï#|8KE¯(ŠRT‚?”p™Üž�·‘|$ú•ÀGÑ¡ûBÔ‹UôŠ¢(E#ø9ÀÀ.���|$ú5ÀG€'4LyÔià�£WE™PÁ4 �<²o»­­çy]ÀQ„ hFŸŸÑ-ÆSE™(Á ü‚p_e(9ઠî]ïy^3pp�Š>�$p1º¼N)jv��2 ¿€p¾^£‘G\åyÞyu@M$ú3�Uôy¤€ïjF¯//é=«L6ÁŸL¸I­F#�,p™çyçÂ&œBçyÞkÀ—€©è ŠþRàB-ÆSESÁŸ ü@3ø‚d€ïyž·hà6é¨YÏóž> <¥¢Ï# \@¸×}…†CQeÔ¿ˆpäT_Xðß÷<ïkƒÿp“Ï“÷<ïß„[à>©¢Ï£ ø:°ÈuÝ”†CQeÔŸ GN•|Áß68ƒßlÉý©è†9…Hç¹®«ŸŠ¢([.øonDÓhäÑeð§úKksk$úÓ€‡Uôy$�3€F½¢(Ê þ©ЄF£ à/+”Áo±ä#ÑÿXüž°d_YO,ê-VÑ+Š¢l–àoÎQÁ$ |×ó¼o¾Ý?²¶ôU¢b¼/w¾Æ}qàtÍèEQ6+ƒ?9zŽ*Cé{ž—ÞÐ?´FãÕ<Ï{ 8 x@EŸG"Êè¯Ôb?£ÿp‰Š^Q”2Îàu™\aš�/nn?.’$ú³€»Ð¡ûB¢?¸F‹ñE)3Áë2¹‘Yœ³©Ev"ùA¢ÿ"ð}1àSQF¯�]Q”rÉàu™\aÖç�†àÇMò‘è›�EÀÏÐ½î ‰~p±†BQ”I.ø+Ðer#Ñ|c´?®’$ús€ß¨è Šþ+Ñ  (Š2Ùäw]÷rÂé[]&—O+0s–É�ä‰þ À£*ú<àìh(KQe²>\ ÞшäÑ |fK‹ìŠBòƒD$á1µºaNþ597*JQE)uÁOn œ’Ô!ú|Z€¹žçÝ?VB™¢b¼£€?«èóˆçiF¯(Ê$ü%Àq*ø‚ü8Þó¼ec™5N‘è?<…Ý'œm¡(ŠRŠ‚ÿ>p*:D_ˆÎÁ?0–/2áÅ‘è�$,ÆÓŒ>_ô'kF¯(J þFà$Â>•¡<œâyÞ_Æú…Š¢ÂqP1Þ/Uô#fô:G¯(J)>Ü ˆF$�ÕÀ‰žç==/V4Ë"ÑŸü\E_PôçkF¯(J‘ ~:ð`?|AVŒ—à‹JòƒD6ð[tg¼áÄ€ t½¢(E*øí�ßû«àGüAžç­Ï-º "ÑŸD¸×½j“½Îr]÷rÝWQ”"ü^À½À{UðY ìyÞ+!�¢#*Æ;%ÊèUôCq§5®ÐCmE)Á_ 쮂/ÈÓÀ‘ã�Áµä‰þsÀCèýpöº¿A�©U¥¯Côùà1ÂerOOÔ›(êýƒ#ÑŸ@XŒ§sôù¢?=�^™|È ï¢ò(jÁß  ×¨ àN¤à‹^ò‘èŠñnWÑçán4ñ}½2IE?ðÀT‰—à·îöÒhü³Å ø’�ü ÑŸ üºŽMX¨x£Š^™DL¾4D‚×1‹GðÛnG>C£QPð>V ‚/ÉË赯pÖs4p—ã)%܆¾€ŸÖ�¼S_tü£ÀL�FAÁ?|t¢ŠìJZòƒDp�Õ6•÷�<¸GE¯”0ÕÀuÀÎè}± ~/ÂB2|aÁ?|Äó¼5ÅôƬR‹dTŒ÷E`©fôEÿà^½R‚Ô?ö~¢ù¢üíèýH‚ÿ pTä§¢Â*ňý=h1^¡kz0ð�ÎÑ+%Ð)_ô»Vݫ蕱nkƒO‘;øoªøWÊ®TËœ·ùI•üøÞ!YiD‹ìFü÷=ÏûZ)÷¬'%ƒŠñ– sô…¾û«è•qd!°ˆ$s£ìB�¾�ªÃõã#ø3"Á×jD þ¶RÍà'½ä‰¾‘pè^EŸ/ú€›UôÊ?cÎþ›J–q“L¥VŽ(÷gS‘~ð]½ ”Âüi“áœÔ ÊèôjÛÍc/à>-ÆSF±ó8øëxÂJú'Y"5ÔÉ‘ù[TòcŸÁ_TjDòÈ——z_V½åHô_~¨¢/È àÏÑ9ÑŠ²¥˜HðŸ¾üƒÛÄ0EŽÙ„ß¡Ãõc#x›pÒ¥*ø‚À¥<_–’�Dßeôßú´-ç1xT3ze”²ù#"Áÿ‹Û$ÇTùä¦ýÑL~ô_AXdw�ÔˆÌà/›,|ÙI>}Æó¼oE½X]^WXô�é½²R\Eá~ôÿË­ÒÏT9NŸM.ø°ˆpyq•F$�’^&§7R¾ìÓ„kBµ/Ÿh1ž²ù@xjÙËÜ$íL“ã7³Û Ãõ£'ø)Ñóî|@·¶.,øïO¦!zí-¯ýe*ú‚ì….¯S6�÷×/qƒ¬ak9e Æ4“=Á7.aÔ!ú‚¿m2fðe/ùHôß®D7Ì)„®£WÞ^ÃC‡è÷nš¹AÏGÌàç{ž·¤\ �bý.¯+”g…UÕ7º®û Ǥ¿Öî”v90‹Fyˆ½ÇX𠛯nXðÛjÿ¶4Ÿñ<ïÎr‚J~âX^§;ãå?ü·~âºîÁŽI‹‰-p0_—ûØW>�ŒÃÚk®ß�à¯'<éOçàóiæzžw¹B%¿ñ½n�[Xô;îu¯ýäd`ÍõÁœ/Ë9@Î@¨—WNèpý‚ß‘p™Ü¡šÁä?Àñžç-ÓP¨ä7Eôß$<¦V«îóE¿3ðËéÓ§Ÿ ÔGíJ†} üþÐz^×ZŠí9OþÈ!r⸠tŸ¶Â‚ß5º&WÁ䟄sðh(Bt˜gÓDŸv]·¸=Í)ïù#"×UVV.êééy X ¼}5Gß×Ý@ᨈaèæ*¢7Î ' |˜ÃB`¶œ€5Μ8Úñ&ø½ ÏÚø vŠ ò pŠçyOk(Tò["úK\×툀õ‘õض¯­�ž²íæµ���}À»€Ã¢8Ù„› uë€UÀ›ÀëÑ¿¬Ú sè¦DEp1ð Îà!>jÍÅš€N­nÈ:Xðï"<ÂwO�FAV'ªàUò£%ú¹®ÛI¸»”Š~"¹U•G‡ÿ©×{{ÜW!÷ª¡÷oÐÜfxÓ7¼hî°auá¾øs¢&£ ¾x…°pÆ‹þ{Õ ï^Ô)“‘#:J°‘—/úÞËâcÖ§°¨ž�wÓl5ü¾„ç¼G£Q�UÀÁžç­ÔP¨äGSô·¹®›$\£Z­ À²—[U5}ÛÁéÛö÷m…�¦!ìÌÏ@°üuáWÿ¿ �ë ëx�€Gö!\Ÿ]IÈ�nêñ¯^ˆFZ�7¢ï…䥂ß0çÇ1Ÿßs”5wÂ:ã þ„›ÍB‡èGüAžç½¢¡PÉ�…è—¸®»¸¨Ñˆ ½õ8Õµ•`N¦¿ÚpçÆÁž~$ê¶öÆâãÀ¥�ë;™ÿº×BG�aµmxV ÷ ¼¸#áÆ<•Qüã„sým¬Ÿ x)Êþ߈¾¯:ЕÃG>,ààLNâA>iÍÅžàQª2®�6›º‘p©ª >ŸÕQ¯‚WÉ�©èït]7 ÜË[3ú!ý2ªëÓv2™þ©›êžjpªÁÙ!\KU Ì@Ø…°îh`:!· 2«!󊡫ǰ¶×°2ÏW~¾°a•xuô ì‹¾Ö.µY¼ ¼ýw+aÝ@×oÌxà–ìAš´¤I[ÀÉÀ™|–‡™g=á‚3ù²[$økOúSòyš°Š~¥†B%?¢ÿ�뺟~ã\�\ÔøXöÔÔgélûý}3F; ­†ØnáWB}4ðÞèï/ˆ¦²o„�€¾vhé6¼†a•{<þn`áÖ+1 7Êô› ‡_‹:ë¢NA aa`7áÔAI“&-„;¦}�Oñ0Ç[G`3EŸN*øC ×Áï®Ï�‚�ìÇ�…Zd§·ÑDdô_$ÜoŠFdý=iY¢º.‡i]°ýuM T ÔÓ£Úì È®ƒ¾NC{§aMÆðFVnm¸{{X7“p“U!Ü'¡�pèÿÍè»G¸DðUÂe‚QÀ”å/”·ù»1e _U$Êà¿ÁÇy–ÏY‡ã0½hšNfò®ë~"z†ì¤Ï¼J¾øD›ëºãM׈ ý£ÔÔCWû©ôõn]Dïí­Ñ ¡2Bú•,k × ™CG'´ôÖZo+Ãã;À#S§‘A[¢€Öèû ¬ŸX9�÷F6ðp5,,CÑϾÎÇø7§Yûâ°UQ5›2+¼s]wpáQ¾Jþ=ð¬ ^%_L¢¿œpX$úTm?"Ÿ§·g»yß[?0P0s�‘O‚Nš!û†¡«ºû -¼>ÃðüLòÃkuÑh€O8Ü¿Š°0ðÕh$`%a!Ñ›Ñh@ïØåñé4s�oðažåtk/f]èË(“w]w6ðKüˆ‚ÿ;pœÎÁ«ä‹IôIàÒ(ÃSÞý“¤j;k!=]ïœ$ŸËª¿„$árÁíY_pnÔȾ }­†î ´Ãj×°r{XYa¸+FXèVþìð2CkÚ¢Q�nÂý†ù¤±Q1FÒ�i^82mù¿ÇcŒ<'Á-#ǘ[Ï™³Ì»ˆñŽ¢ k™dòQÿKtôo$Á?ãyÞ ‡J¾˜D?°¼î&tÜ!÷¬ÈsT¥nN™D¢ß˜Ž@¢: ¨\dH]U:~ ô7zû Ã14»†×·ƒU ÃßãðTëw 슲þ—¢NÀÀËTÐ|yŒ8°3ÍcýéÆ4íÛ`ÇMܶñlÓlev©ØÏz¬çËÁÎÄäŲɟÉGEvwî¡ä þ à#žçui86]{9ö7ñá„U÷ZŒ7¬é™`º»N.#Ño)AdÖA·¡+ ­Ãj˰º ^Kî¤Õ²ŒtN¢Ýñûšc½¸Uü�·vV†õf §/ÎRÁo9:\?xž·ÌuÝãõ¦Î﬋õ•©,�¿°„ŠñжÓ‡ø ˆÏ� ÃVýæ¿26-:ýÏÊ1=á#³H<÷LOßß|œ©ýS fb*QMñçX�ÐjàY0k؇ö¶‹’TÒ@‚zÌÀa ¶Ôc3mÔFl‘ɸ±.“Û àœ­‚×L¾oî�kÑ“¤ò3zóºÚÒÛ³­†ct:PY'õü"§kþë]'d/‘†L÷�®!±#²ó3ñàÞ¯g®ÿsÆž6Óøká�fÃã-†»Ââ¿é„UÞu„+D¦­\M¸Lp`…ÀÂÁÂú€6 �O�cO©¢�Zªh ‚bQgÀ–)Ø4`QµÁ�ð{³–«Ì'&S&�ê-E«è ‘NPÁk&_ªý_\×=¸ØC#2(£—ÿ%U{ p¦fô£� ^],™¹¯wã42×ßf»g¸'%fc,lÀÈöï«ya//àHÖÿeWC¶ÕÐß Ý¯šŸ„5†ÇÛ wYÀV„Ťõ€K¸·ú{—&ø-9~k2„›­‹:Ï�‚iú8îRÉT¦’¢ž$ÓˆÓ@Œ©Ñ¨À”h �0I¶Öerüo�Ïi‘�J¾ÔEÿ´ëº'÷A®MžPÑÿ›Tíåˆu–ãm�àE^k4渳sXÌIÁ$ÄÙ­ÝÚ+iÌÖ>Éà± ©KœáW22ëÀr@¢ŽÀâ.ð[!× ý« =oBïs†Öà 톻»àßõ„õ'S£¯m£žDœð¬ú€;éÓuVG���óÚÀÔ ’zI�:FüèÞ…ð ‹ìNQÁ«ä'“èþ ÌÔˆ ý‹T¥n&\^§å ›@ÃêKãæ“ÿì9$HóyÙ™$q€jÄrÄ-#ØäD,Ù¬|ØJ…_±mNä-ï |šp@vu¸K`¶ÙÐó´?nhî6¬Ì~íÃK©HxÓ£{à=„' ڄ󲹨SpA4 ð&áRÁ�C…NÌ{fïºîG¢ ^—Òè”w«àUò“Qô+]×=xTE?LôÖÓT¥nA8…ný&DnÝÕ>‡?Öû~û›œav'%ñ�¿ËaŒo#’3&K`,#ÖØ™ÑJAbçpúž¨#àF�ƒ�Ïæ è€\Kx‚`¶ÕÐ÷*´¶^ë2ko±, IDAT¼àŽO�»'°MÔ HD/ÒN¸9P;án�^ôÿ¯E��7yk“þ!�€Á›1ŸFá<×u8Œð¸X|>¹¨ós¶ ^%?YEÿŠëº�¡C÷ÃDÿ*«³ óé!Ù Í×ú|ø™ÅÅæ¬`5’ü·1,‰ç|Kl#vnÂÞ«8`7„_‰�××EÞ*U93 ÝÖî ¯BÿÓ†¾×¡¥ßðšex,c¸³†p:`�¨÷0P H”忉a‘àóÑŸ­%ÜR¸oð›öß[*x8 øAÔAQ†’n.Ô";•|9dôG¢Åxù*�S™º– 8�Þîí5 #ÒzSŽ5±‹Ì² R™ÿD|Á` â‹ØÅ=È-±È×ï ¿jf ÌGG ç¼°F 󢡳Ùðf‡áå Ãc6<”vö�F*£ç^†õÇ ‡»†‡­aýù�„§nÔ踮ëßûmt”n$Áß,VÁ«äËEôÅx· Ë놉þER5?À˜óèëy‡$�Ž;rÌþÓøo¾&2] nXÓKàÇ"©gÁȘ×�[ëˆ><ªê¶ÞÌ#¥í³@S„_¨àUòå*ú…ÀÍè†9ÃDÿÕµW‚9¯ÈŽ©�hºïÉqüuÔóe¾#áʈRi®äy»Æ"¨ÍS6Ç¿H58ÕàìžPLGØ88=êäV……‚ýž¡«Å°¦¼¸a¥cøÝ6°ê½„+„ç÷D¢o&úŲ¬ÕA¼Ï¶íÏImŸÿCà"�ƒWÉ—«èÿâºî™QOW×Òý ªë.þ›¾^…žûrÌ¿‚¤·�oÉal#Õo÷¯Ÿ­3Ïf°¶ Ö`L ±3ÄA�Øn¡»ÃÂ;XŠà™Y0íà7‡�€Þnèê3¼™3¼,ðÒLäw»ÖÖÆÞ‹ÅÐMÆ Ñ|ø®çyÚôTòe-ú\×�‡=Y@ôÏ“ª½8•¾^·œ¢?åø¯Ëๅ|[g'©Ù`ÎOŒ€ÀØ ¶äŠ~N¾¨Z^ d*XS!¶«®þv œê7Ô5ìÄ·Xá4¾2Œp©çyßÒPŒ?–† (E¿ 8žpPÜ`­GIÕþ”Šäª2�@ÿ9¿�‰‹å0fmXðÆÆÇ`LÇ2¢÷þèt<}j ž¸]?r‘çyi …J^*úå„;‹¬Óh ýrRµ·’¬|¥Ì>yæŸ>W]÷�Æ7e{IÝÆÿl`�>&°ôÞßRÁ[Yjî'Qq Ъɧ¸D¯’WÞ>£ÿ<ávŸÊÑ?Bªöj*’o”É'ÎþÛçÚó ·ŸÈrûÉ&m®b‰XTXà#eSx7FíÏî§®áâ‰[ ·æW dð—é½J^Ù°è |‘pkOep&%ÏP]w%‰I/úÜó>?;Çpóqœ%ç©G6­¸+àdÈ–ôŠ Ñ{ _S÷±ø­„«è”atK4ƒWÉ+/ú€/©è ‰þ_ÔÔ]9‰3úÜ+>w~ÅpålNç|DêÙŒùôýÖÊ’ä¶È™˜1ˆfò›-ø?OÜH¸Œ^F'áüÙ •¼²i¢(ý«�|ÑW×]JEòõIöÉü×î]høÎ!œÌ©|Üš‚µyÃìµ9Sk¬  0F‡ë7Oðµõ÷OÜÀÐq•A‚oô<ï …J^Ù|ÑŸ¼ºj¨èŸ#U{cTu?Bã¿ðà—¾¹7ó8‘ã¬zlb›ûÛœ°êÎØ�e²ˆA3ùMk_V–ú)7GCôºÌ»Ý„»Ø]¡¡PÉ+[&úG€ù„Åx*úÁ�Ùz‚TíÍ$«^)ñЭ9+àü=ø8gp‚4à�Ua’q3ˆnزтÏQ?õvlç>6~+û²¢ø†çyWj(TòÊèˆþÏÀ©„{i+CDÿ(UÕ?¡ªú9D‚R|[Àãg|i'å æK=q•-R}Œ 0˜,:\¿ñüÔÛqœ»4ƒ/Ì`‘ ^%¯ŒMFÿeà�ÆpÑÿ�ÊÔÕT¦^(1Ñ›®€œpÆöÄù¢ÔQ‘¢Üfu°p@,�ÀˆÑ»�hGv?õSŠãü� ~dÁŸëyÞõ •¼26¢¿8 ø:t?4“—"Ñ—JFoú +Î 8µŽ½YÀYRO¥ŒÚ)f- óF/’3˜�ÍîôÞ߀àkîÄq~�Ñd5ð5Ïón×P¨ä•±ýCÀW—ש臈þ*SWSUýL‘‹ÞôþïŸìÆYœ'µT¿ý�3›Ê³ 毢_F8t_êgc ú—IV]MªæÅšœá¥E>Ÿ؆ÿâB©¡~S¶«Ý8ÖIÒò±Í@µ��“/D,ÖNmý�Äb?| H>+�S£Mº•¼2ÎýÉšÑýkTTÞJUÍŠb M`x5íóÉÕLá,¥’©2FG ÷6H€Á1Fw¼Ë|¼•š†[pbwœ¦ ãUàähs.E%¯L€è!Üë^wÆËýóTVý„ªêÿË[2†7.ñùøK$XÄEÒÀ ÙjÌnt1¾…-F×Éç ¾�šº_bÛªà ´Uài`~ôŒQTòÊŠþqàsÀó�á¢_Aeê:ªªŸ+Á¯¾Ì爿çó=™Ê¶2cl‡ Dú1�ôá¢÷þÐ ¾î—º~dþ,ŒF •¼R¢øð�ᢎªêKIV­œÀ´hÝ5>‡?,â ™ÎβõX¿f5�…d°€œ€fò!ñD35õ¿ÀvîUÁæIÂ"»Ç4*y¥¸Dÿ0pðOtŽ~o�ª¹4Úo¼iù±Ï‡—_ã[2“Ýeæx¼ê-öÞ ØÊ3¶è½Ù¥jƒmß‹Ñè‹ÂsÀižç=­áPÉ+śџmiùÄeô+#Ñ�gFßñ‹sþ,âB™Î¾c;D?˜é}l‹‘ÆÊ}3œX¬ƒêú;£�nt™\Á¯ŽPÁ«ä•âýÓ„sôϩ臋þeR5—RU½b^­³)Ç~ \È9²5ÉL`Üö��á¼–˜Pje+ùX¬�êú&çWè2¹ÿ1ÏóVj8TòJiˆþßÀ1À_4ù}eêzªRcYuß}oŽÏÝ |�…LãÃ²Õæœ ¿EŸSïýPðñVjnÀqîTÁü€£<Ï{Eá’WJKôÏŸ÷}¿U£1\ôÏQY}-©š�Áoï}(Ç/~•ùlËG­N|ê²ËäãñjêŽe/WÁüãÀ§5ƒWÉ+%,ú¶¶¶ÿó}ßÓKŸ/údÕÕT×>9Š¿µïá\ÿ{&Ÿá|ÒšŠE|">Ÿ_æ÷~<±ŽêúÛ±íß«à þÏ„Ëät^%¯”2ýýý=���ûþ>Å�P•è_%YuÕuOŒF¤ÿæó�ïÀÃgs {ñk*6ɉúl¶ ?F­|2ùDÅjjênÁ¶ïG«è ò8p– ^%¯LzzzÖv´žÐíç>Ä4 Ch#Yù#jê߂ߑù_Ÿ.2Ü=Ÿ�ñnæ[ 8¤&òSýv¿78σ¦YŒcÑß„gðu7aÙ¡Uô3øç4ƒWÉ+“�l¦>ÛÑöiüÜ‘*ú<ÖRQy-5õ�nNdŸñ¹ö|ÃÏNåCìÏiRKŒê‰þD±rDãÔ†)e!øŠäÔÔ/Á²E–¼.“SÉ+“ù&Ïfêèhû4¾ÿatè¾€è“×Q7åþMø™Ü >·þ·áæ“9€C8Sª‰K}ñ=Ý+'½ä“•¯�ª½Nÿö‚×er*yeD=-§�˯¢Ï£™xâ¶�ÌèýW}~}®áêO³'s8G’cu¢Ü–^øÉ-ùÊÔó¤j€e=©‚/,x]&§’WÊà^k‚2›­¥½õX²Ù“@�F Ék©©»-üÕ¿ÿŠáâ£y'³Y$P5v'ÊmùS¾bÒJ¾2õªR7#¢{?�€.“SÉ+eÔ£_¯©\í-G“Íž¨Í¢ è¯!£Ö<𥀠?†Ëa,–€q‹íÄ,ßB01«øÆœªÔ¨JÝ‚XO«à µÔ x-²+;t|¶Œïù¼?ð´·Ký”lçnt¹Ñ`Ú©H^@GëAk øË—.8”jãbÉÐ ;ã»ß³ƒ]b˜J°ãöd[*^U½‚ÊÔ͈ü[›j6¹\kww÷»»»UðšÉ+å*ùÑ·¬›�ŸûZu?œ>*’WGC÷¦3੯œ¹; çJéazq `›.{–ƒløñI5\Ÿ¬ZIeêj|áèø5wtt<ßÝÝý¦ÆC%¯” &ùob´5Ÿ„ï�öÊ诡aú%|áuà�\)]¸²{q¿oßôÛ6†Ì$®OV½Bªæ2DVjÓÌ#E.{í­Ÿ}¼¯¯¯SãQžè¼Œ-ÿ¶Jð+ho>™º)}ÑF"ºèzZqœG>2mÚ´m×~f�°½¼«zóbÄ`Lv’Üöɪ•¤j¾‹ˆ‰çSM6sí-%ú:� �‰fòJy±Áí¿r¹­§àçŽF«îóˆÅb±=^¯ß¦4nt+À‡XÉß÷UÕ+¨®ý† ¾ •d2'Ѻîh‚ ¾Á½¢’WÊ0“ “i ³íSärŸÔæRàþ©xª¢¦þïµEÿF{ $¼è‚S²R$ Uû4•©«€uÚ󨧯ç|Ú›?Æú�‹�J^%¯h&ÿö¢ïj;?w e²åùÆ“E’·&©²¸Eß)b,, §$úbe©®{ŒdåušÁd½ÝçÓÙþ~Œ±6ë^WTòÊäIä7éÆÈè6:t?ŒnHþ$Iý_ëŠö-®›b�×Ã~‰Sr=5Ëî§¶þA**nFäUmsßÓu]{<èp½J^)OËoêd2 ´5/$ð?¤¢Ï $VAý_ë� øº"A[ÒþŸ]R÷½e÷S]û(ñÄm «´­ ¿‘Í;éíþÝ�{<:\¯’WÊ“ÍÂËåR´5/PÑ�”Ñÿ¼‚ú'j±rÅukÃAıJHò¡à&Qq#Ъm,ïºÎ¢§{�íïAðšÉ«äÍä7YôU´5ŸNàPE?œ.¨¸£‚†åuؙ⺽²&À»D ï,»ŸšºHT\¯‚/(ø]éé:�îŽYl VF%¯’WÊð±EÅ8áòº/DËët»…á¢�ß§î‰Ú"½oÙÄ$ VÑÏÉ‹•¥¶áN≀*ÃØšž®3èîÜ• Ãêp½J^)G¶¸âvýòºãÐ-póEŸøu‚Ú¿‡èc�Á¦Ø7ñí>ê¦ÜI,¶è×¶”§ìíélÿf$øñ¹×•¼R†’}WÛÇÉeUô…D_±4QýÔ~rôY†Œo&ï8]Ô6üŠXì WÛPžàw «ã«ôvo¿I?¦‘SÉ+eø¼­_”É4ÐÕ~~î(t÷Ìaô@âç êþ2±Åxû4ÛLbvñ% fгð.o¡¶áç8±_‡�Sò2ø®Ž èíÞn“R£§’WÊï‘1ªCx™Lí-'�Ë~ ¨Ôð&Ý×O¨è}r¶Û@Ÿ_±d<ÞBªölç OÛLž¦ßEO×—75ƒ×L^QÉ—1£>O—Ë¥ho9Žlöx ©L/$~• þщ}±Ä6Æ×p}<ÞBªînœØ¯Â‘2Á{ÓÓyÝ�³Š¢C¯¨ä•IÆ$_ô+hk>–lv:G?Œž0£oxpü—×å0&ÀƒHÌ¶Š¦ò.o¡ºî×8Ž ¾°à÷¢»ëº»v)®]QÉ+å—ɯÏb´·K¦:GŸ/ú‰X^g!"‚“óí¢xî;N5õ7b;¿rÚ6† ÞìDw×|z¶@ðc}¯+*y¥xù1}Ð~‚޶CÉôˆk¸ Ý×=>~¢ïÇ Ä6HPëä§›º)×cÙ¾¶‰<Á¿‹®öóèézgÑßëŠJ^)³L~¨è#›9ºF7$–&¨ûóø Ý¿Yë?Õ�i 0ì •¼ãtQ7e –ý� ¾ àßCWû—èíÙn´~©J^%¯”c*?.= ?A{ëQø¹�jF?œ>H4Åi¸¿~Ì‹ñž®â5ÁZž'oMØ}�·P7åZüˆ9÷»éj?ƒÞžmGó·êp½J^)ÃÇɸ=a?A˺ϓË£¢Nb÷Řr=vÿØ-móI:¡à 5\?PdgÙËUð…2ø`zºNÍ ^3yE%¯™ü8½X£uÝIärÇ¢C÷ÃÈ@ìw1î«Çé£ÂwéÍÅp¬dÜïûp™Ü]ØÎ]êœßÝõ9º;w“ñ�±J^)?Æ}Ï­ë>eôzzÝú!ö‡†ßÔo‹�Á�.&@ŒÙqž“_¿LîÐBïB‚ߛG©ÈN3yE%¯DÊ�˜W�ÑÖüY²™ùšÑÈè�?9Ô>T3ê¢@zÉúÐ?Ž·ýúerw¡Côov¥»ë”±ü„t蕼R–Ÿ°!„¨/ÓÿE J¯Ä`rû£CíòÑý�q’8"H0N·ýÐerê™á‚‚}éj?{¬�׫ä•òdBŸºáòº“é?HéÕLb¿ÝŒ~›Õ±#Űc à0ö›×ë2¹ þ ¨Š~»ñxA•¼J^)ÃD~ÂoüPô‡�ÉœÔê%žÑßïPOí¨ãÕ˜¬mlâ`ƺº~ý2¹Uð#¾£u}½[—ͽ®¨ä•2Ë䋾½åHúûNêôª ÆûÏ6 ¿­ÛbÑWœ¸ï�ÃÁŒ¡äÃ"»;¢er:D?üqø¢³íódú§Žk�^c¯’WÊ0•/š7Äèh�M_ï@�^™a½ó'g‹E_›cJNr9ªÈމak¨®kŠŽ‹U¯ ÅÁ÷§£íúûfŒû¦ñWÉ+åçø¢ºñ�±èhý ý½g ½<ƒÉ‚³ÜaÊÿÔoö}Ä7¾…ÄñëGû-V$=RµK±�ßj_PðGÐÙzâxgðoÝ]z TòJùQ”OâöÖÒ×{>:GŸoiû{³‹ñl�$q;X˜Q¾ío’ª½Û¾O_Pð¦£õ2™† ëCëuPÉ+*ù¢¡£õ úzÏô* Æ7Ì©{pÓEßšàå,Ùß ÈŠ3j·W$=ªënÀ²þª‚/ ø\öx:Zæ“ÍÔOàûÐáz•¼R†÷�ßÑz }½ Uô2zçu¿ß4Ñ{)þÏGÖ:&kâm£ñV’•¯�ª]‚e=¦‚ÏÃ&›=‰öÖcÉfuTJQÉ+`ùbƒ­‘é?YE_ £w–9Ôÿzã—×ű@$3 ·}Uõ³¤j–`YSÁx¬f³'ÒÞr4~®6{ÒL^%¯h&_¤´5®ý¢·ÿj3å6îôºÐ�ï³¥;ÞU¦ž§2u bý�îÍïNårŸ¢½åX¿h Hõ"©äÍä‹;£ïë=-Æ+ ú?ÛL¹sÃçÑ[€ƒeYˆlÉ)tUÕ+¨ª¾‘iüóˆ“Ë}’Öu'“àÑêz•¼Rž”Ô^8Gÿe B¯Ü°ÝYæ0µ©;3òí,ƒ¾on&Ÿªý'•©Á«7ò ­ëNÄÅvð’׫ä•rLäKî)fôçiF_ £wr¨¨~Dѧ N �,rÈ&ïx—ªý'ÉÊkyV_@ð~îÈHðNQÞìz�TòŠfò%$z]^Wè1¿3FýŸê ŠÞîb–êŒ1²iÛÚ¦jŸ&YùcD^×8çQA6s2­Íó‹0ƒ/ݽ¢’W¶üÆ/Ù!<]^7rFÿU¼`F_ãKU«&K€Ù„L¾ºöI’•KY©ñÍïþ�é?�öÖ£Šl^3yE%¯”øº§õËë¦è•.ú»bLiš2¤O€@l³q™|mÃr**¯WÁ¤Šþ¾3èhûP± �“WÉ+šÉ—$áòº3€iz9“盩w5¼%ú Æø–ø‘ÉW×=A¢âD^Óxæ1ƒþ¾/ÑÙ~P t¸^%¯”©å'Çèh=ˆ¾ž…*úB¢ÀyKô6`‚&‡l@ð%YùcàM�cž.·¥¯gm¥"x•¼JHœ¥ÛÄ`$ú3k™Á1Ë€`Œ,5ا*–±ÌYbˆÂo@4”*ù }Ûþôöœ‰S;‚èïl ?g[†osž|uÝ$+¬Öøå©rúzÐÙþ¾".²Ëçòv§”MrzŒäÒzj—Î%¾d 1n¾¹‚»ï®äù«,K;„ÏqkölœÐ F–.Åfé\›eË–-sXjlLÚÂ̵ÓËÌÅ6¤-–bcf;¬´Á2ë¿ÒX¤Ó ƒ2ðïÁ„Þ1„_ʨ"áÓÞXÃÀÖY¾AŒYs1@£ÈÒY’ž7×xFì%BN ¤ ’ÖyŸÒà`…ò4œ>™>Xuí“$«TP…îò)»f{ÏýS‹ÝàûÎ�y°ûL­.,øï³<ûôö. ³í}”ZNÓÈ/ƒ[ùnË^Øþ)ä:bÈêÌJk°*A°r±7«±×®Ý±¯uÞMK}ª“—~¼–BÓ 3—g¤‰¦0ýc±1€˜y+æÚ¬™˜9³}hÒid±14FnI‹‘ÁY…!-4Í3o.�`Ò醈:d pB‹XÚ„a.Ì! Fi4�f®`æAã&=o…™µTdˆ¤Ó³0² o•‰fÒÝP�íû_¦¢ò:]î5l̦ù¹XrYCCßÇ[Û$ðE�㈤jŸ$Yy­ ¾`¿=½Ý éî܃R´\‹ñ±�ã¹Jc¬é>òÎvÌÁB€t ¦‚l6ä:v~IÚŸšs|k€õR¼ÚÁ§_›Aðj¦ŠWö‰Ó²Keº{ÿ Ý»ü 2i!H§0Ý’eÀÚY†iƒsç"{ì�°”ðÏXŒ,ð¼Y‘FÌ;ÍõÆ,fˆ‰ú":½0Ú™=à™´Ï¼¦À�–&ËŠ(©O§£>h¯ùÐ.¨2*’ÒÛ§‰€y&hDäî%ØÓ·Áºï…�á‘ s±Ùnê6Ø]3k³};µ×²==Õ[Ù/wöîðç¿pà>û>•Õp–Žäm²„)gNÖYÛ°œDÅ-hñØPl á0XÕúEË÷+©©[Fô:˜W2b^ÓáU7Ëó6Þ;b¬nx#¾ͼAÇòðçÌ^"pzEk¾6Ÿp£å;¹·'ÅNĤñÃõ6=¡e�‘PÊbŒ� È $,;¾*³kæ³}+©™ef¯XAsͼes„Þ¤M×+†§N7Üs½O“&-ÏðŒÌÙƒF³˜´Á �ˆ<Ó„ &l(ˆLT¼Áâ° ˆ «1ÃRÌPúoõz�Ú6.O™ôqêlÛ�¨Z|�^ò·ð±íû±m‹ðZe¨à¢»óDz»·c2,Jd�1âc ÆLÎ4³.·ÈÙáW÷ú'©ÁĶ�M¸Â*@¢Ï6UA`âTæ žC�±*$ž'kŒä0’ÁXŒäÉ�d0VTUó. ïªÏB[z|ßüÇôtg¥¯&ˆ¯uçT¬|”…×ýqö‚ûg-ŸkæD“¹-‘|%kŒïìŠXLÖ6Ø�`À ól1Ø�1¾±‚°Ç³¡>°2uö5Ü»jþº—–gœUM+™Â‹±VÖXUtôÇ^mçÓS{™»®?ýLÚgÂìÙ4-|†ôŠ4�64Fßߺ�b XÌBX�øƒ®n¸Ð�õUáøÀ�ïʆžeåð!;ÛÞ’•?Zõª¹üÚÎü~tµÏ§¯×e²¬ –ÍìЋ`ðñÅ�CÈbÑZ°Á²±Ä€ñ�ï˜Ë·Hæ„ÊÀ'æ*rXU9ˆûNbÞ° IDATÏ‚“Å8âäˤËîÇD2ƈÕÓ«z:™©�dvOØæ ÞÝ4·éÍyÚ4·PòÉYÇ;fÅ~A'sK#Ì$K b K,ÄÇ"¼°¾2Y_Úp �K‹Ù §_,Þ ÈÆñIJ¯ÕÕõ¦iíj5+ÙÉZÉ㬥vùkÉJV;ïiZg^¤µë�tÇ>söñŸJ?Ìe®4ÑH#pHZ8d9,_n7¦%X: kÚräOi šÒKe®¬Wr°ØÒ�Zä¿ñ™|ÙôŠÃŒþ*’ZŒ§¼Ý±+]í_ ¯wædûd›ý“ýVøÃV¸ÄÛÿ?È„ƒªYؾÕÔ‰1€e“ æCÜLEÎP‘E*L2É,ŒåˆåWU�`K�øV³±R¹Ö ¹GSÚ4IZ³ø-‘üÜ›Vt.lJ?8ç™YËXyúÖÕAÛGz„Ó}‹Ý1vß÷- +C6›¥BbdM@–, ‰Û¹pfÝd°Œ�q°ìÚÀ ê±ËìOO`ÄÓ�ß‹ø]$h¦Ò¬{ê_Oµ$^nÊüúur¼âTñZ.ž~¥ö)zãmdÓ�£uŸiÕ†g¦ ¬0Ì}FhÚ#\y™»ÝšÇk&_Xôûb‚ɪ%ˆ¼¨WÿÿÙ{ó8Í®²Þ÷û¬µ÷;¿5uUzN:“Iº! ³˜n¸pÁ¨REƒ‚|îå¨'�žÚ¥÷xP$Üä ‚Ê`½èÅ‹ãíF™ÉÀÔ�©“tzªîª®ªw÷ZÏýc¿ÕÝ`"™:é¤÷ïóéϧꭩßg¯µ~ÏïYÏ�â{þé4ªï¦ÛÙø”{oò(ú¬ »¢º$Ô¿Þ‡GˆÔ¬µNõIø?¹ç'J.ïlè  $ÿD Ög=.hy³Cðæ„8­{Ü2™ß{û�ÿÑAnL«>Ýó®½™ðÆ«vê¼ìV¦…›®ÃÜø$|;¼Þ÷åµ»™0$ÀjßÄz«î,åø@Ó…cØ€²�6[pƒQ±4CH`2I$`¨UuØA¯@}rᮞ�PÅâ4$&À“¥ŽÊ]sÏArºßvý‘|‰ÙKY,ja�VnœÎ>a@:qéûa˜x÷¿ºÂú_=ÇŽrŠ#û(?ˆÈ}éJHq’àëÕwÓ{ <À[ø_ÿ÷_˯^ýjż߲?|'¤?�´U˜@Œ‚xð–à%IÔŠŠµÉ§>IÉ—a$ˆ� [Wà*‹ ;xŽŠ×á/*ŸäíÓ3óŽéf*i‰ö£Rò7\­îƤ³ ™ütEý]*vϾ=¿kþ[¿öÏ3ÿýÞ¬¾Tó3’ç…ª”ÔX‹ ÿúW~¿{ãÞ=?®×q�yÏôÕ~ÏÉOaUØÐ¿� ¹AÜbSÜg+FÎ'#ëAÏaL� ‚Á¨ Π^Ác€‡"L’Ñ ˆ{&‚œ1ÚløAëz+JM�£hs—YdàîÇÉ-w8{3}–mþÀQ?‚Ÿ®ß‡LmÇŒ¯¢¯_@w�g"�h÷nÃÎÏ{dVOæôϯºÁrïM>š®èl’À\„lŸE¦“=0Ü>‘ì$2;�í ÓCÕ,À4˜ ³k{æ H&1†$]ñœs‡„V};FÞ:¬£O‡¯¤¿ƒÆS˜à×Þå£úqŸd˯‘½xøÞ‚5`5îôÒ)p€Ï`óëXb]û….Ä âpcƒÁ³B|Ø æÖ/ ŸxÚ:Þ5³Oãën{õUóIoå•’`Í£SÑöÍ¡QW~“üâ.8Ö _žÓÁsdzüÖ«¢;£("Š4ü+D¯ºÊÒ?p¸•!sµrPîmÐE~@GØæa½…KÔ1î•Q�1¬-a°¯$é‚ADuÆãEŸqX#Õp8ÍÐÓ�>!u�ûèËa÷Q î¥ï�a²«L¹*�n�ò¶¶Å7ìjÈ'¸EgÙÉNÞ¡sLk4_*¦+v€F rN"ˆfOÛEÂ\„ÌFÓÓÀ>…ÙaOÁ9�ÙS¥œjø(%ÿ±Œ ¨õ†~Æ›p€¯°¡…}žâ²�#àš˜Ê?àßuÙÇo®éÕWÇÅÌ >í‚wH>©UŸ1™M†W‰Ì‹lß�Ý··dOùùh»°wÆÎlgð ªTNú’ SKèÜ>4–ÕEDÀ´@EÖÿÙÆFMÈÄ Ï¦x�MΛM(éÉ6 Èè$�Ž!5ÿ‘�ÿZ¥†®ù*Ã�‹¨bQQ,*F;ÖS—˜eoXÐîÇpÜS8JÙ¢aÈdV0Õ~“Kx¦Pv ó³È¾=È`ÏÊ>”¯I3`Ù«‘T@#`öô+„ †}hÂõ$N³ú8.â$\üSSâ�ÿåœ]øâ)”î¤Pº‘ýéIpÎüNšµ7=“ìˆä?{ý'åמ0’·>+ÎôÔ‰q9�i ëj®ðù6° Fþ~¼¤×¾üv¯°”]n­œïqAO9ÿÁ)¨ >Ò¤�½Ñ>`†x¯"v{…íûvDq2¸à߉¤f’z¼éïQû³Dhaª"²4¯Ç§éÂta!bnD\³Ó›¥w þ‚›—['(·¿ÆŒ�3[˜‹Éš 4d#Ò¹��Ç$M°„(Ö¸äMHŒÑ®&7M†r,2‚èf�§Ó%qLG䄯ڶ뒡ʯ³¢bŽ€?L�ý3·p/“Ë¢±ñ"ºñº£od —H<]�Ê®Hà‰ö|ÞGk=£9á’>sHRÿ?öð8>tƒ«?— ¨T íæeÀ»(”þ‘ûÓÓàœ!øѬýô°Lî\Prþ &È�öCÄöpYò¶tÎë;žâ³MAV=Jækûoû©?ÒUÝ%É­}Âë27 }¦uògDÉ IÖ Ó‘̬àq:‡)zU Ü?ÐCЗ®!ß•wª^$óÛ#˜ž^«€�†_Þ+°C!RQ*ajF®-#¯¿ ½¾‚.]Ÿ¨jö`ø4YBΣleT7ȺöRâx ÇFúº•€"¡Ï’áô¸¹‘áDMŠFD@ñxõX±žO¨1sœ®'v‚ûmÌrœã�ÛÀ"ÊqòÔ9A‡KDDæ®áó|ÞoŸ�d`/�_ÂàMÀ¾lø�u7Øò_Ïù pRÑ‘o¦'ÂSÞ¹»œFõWÎ ¿†·ñ™?ù¸ü×ç?QJÞ…ÛG3*ôa|ó"#.×QáªGásG{û§olÜ|ÝŒyÏUøyð$ìTTÖjõR’DJþç#|‰OsãÉWgø /±wrÍû�fIô62;—´(Œ@£Ýb£�»Ap̽ÚItË*y™‰f×ÚÙ&\ºÖÎö4«Ó§Eää-wE’(Aåä#¦ÑJS¹ýü´2‹Nƒ¹ö"Ì�\¥4Ê>¿ç¾(ú�û೑»¤GÏüÿߦ•`ÿ�±vâc‹ÒÇPÇÓ"Ã2çV9þ[a´àá K™ûi35~}a©’�SÈv…Ÿ‹sÜù><ò÷Ýg¾1ݧVC¡tÅò‡SEÿ%øúS>‹þ�ñóüÝLf_x¦•|/D²‘ïlÒýf` Îaƒ6Åæ‡Ÿë rÕ£Ø/,º™ÿüy]Öψ›f#Õôþý±&ùgqµ¼ƒÝ:ϵü3Ÿ0¿ÈGµÄFý=^vî÷ÑÉ‘d NL˵Œ›¯½^O1絎ñ¸Ãù¾Éf½r>Þn%cÖQŽ7k°b’RR1ˆúa•¨J2ÈG0’Ô‘&nF€b%É–pÒA´�“�9FY+z˜¢ ªîx.ÃBó ¼…î%^¡ûé8æ§tçtEöTPöí”?¿fOð–-w«^ú1'Ùß¿é¥Ú ÿ·þúu¼ªœn�ï~òÅòJH³îŸR¿ƒFõ—ÏAŸàZþŸ?ú+‰^t¦I>ôH7ëÑÁ0[.1.SªIÿùªŒöÁÃê"þ ñEú¦ëÿ”£;wE~V£µÛÞ4“þ1FÀmܬw°‡§1ÍÝìÖKx™ÞÄ;§=�NžóÌ4P¡Â�à§�ÊΨþksQ=‚CQÄ·öÎ#·M´pvaŸË�}‹‘AŸ‘x’õ½*¢f›ízB.cO Z( ä½C’†A"Ä$Ód€Âðߤ±´“ñ<>©W��Ðo…´¤H�OѼ/óÙc6æ€k÷îùª=<ݱc{N¼:Ü}iý—P¶†z^/xzޏ�.ÿïó&Éxÿ'…Ò¹+5É“Þÿ­úÎY‚Záq!Í�AƒFC<…:ƒç ÔŽöÅ™U�e¯ûïÏéϼû:]àzÑ�»##DÉ�{Jïg€ä¾ÁßÈ4,—ò?´C•Ïò‘sÝ00 Â4~ú¤c¹–=%ß H4;­;ƒ}Eµ[Ý;S›ÎWØñJ¾ÍyØëåªÊUæð_Ü’9¾�]eƒ6š<[|C·0Ðõx.Ç&AÇ|YÖa‘$€GÔ Sô¬»Ä S�Ìžš+šv-=$ÿ/ü/æÝþ5¼Ž/ð'ÀàÜÞªkE�§-¹“ómO}ž4Î9ÙãF@ET"¨;†ûg· ¸eºâ©\Ô…é.•éã0÷ÍgqÔ^¬Nßèo›'Ø‚LA)¶¾RÞʲ%LáûÛDÙ¦=_.Re#ÆdpV-b¬¼õ"t�Pź|èzÅ �³þwÞÇs.­#¶�øoÿ“ïÿƒÇƒFrÐ {irǦ¥éäï~fœ¿w“Ëž°þŽuY7È—;dGN�›XÔpl€˜§êãW5´[—€¼cºOë蟜ÿús¦Lî?&ùÇGÉ{6ÉC2Î�«Ææ¹7Ù8¡è*²õÕ4wßÍÒ’Î(¦B¤è¬¨œ,ÃJ þŒ�<Är€›tŠ7ñe>t®åäÛÓXÿôò@=ík'צˆžRú Õÿl„΀D*ì˜fˆvÀöíHü�ˆ*è¼èè 4af *ìÜ�LíD+sÈö½˜}E 3d²£~Êd«(ê¥Ë…ä|«:î{n+B !ܸˆïûÈ<û.´íá¿€ý»Ó®M¶³Šƒ÷y y„É›Äl¿ÉÃÀzbŸÅebº™«A�;Î_¡6¶ø²�Ü÷,Ýš5ÇÇ3z¬œuµÒhì²#-Âò=dÇã'ñ¬Î“Šžw’/~c¾žžO X¼~Jðg�ä=I2qà¡o p¨hH©o|/ë �^ð|A×uð¬€Ö°Çúe÷º×4¸“›Ë6ºz—ŸE“Ì$AçT4y!Í¢ŒŸÿþŸ£Ë1®çÍ©Yž|ˆˆÌöùH®ŸÙ){ö.æ6ÇûÆŽ (½îs<÷§?Èï?ó8S]'ZÅ Ö-×/Ꮋ7³îþI¶6F Z9X.âNŒ Ëc˜åQ|§@ಘ(#‚1¬Eb‹J€=:8Úª´Ã˜V¡G+ìÒ*/]Þ¹ç™íÂíÇ#÷lÍŽgZFV(ŽŸ ?Q'Y$,ëYï(ùâýË…1_LÚY®Yœ{ ÍÚèu×§æâùÄ|T~÷šÇ4ñNN ­¶®A¼ë ËŽ«C8o€1Ëâõ°ÊA;©o~õ‰ù/Ó�1ȼ'Í¢•ü‹ùa.å…|ŒŸHMò$%y�`.R݉ì�ïa¦óÅ_bÛúÅà]9t²#Në1ÚÉZŽ_qgæÄ…÷ôW޶rê9ÂV‘B»H¹/˜‰M—úÊ(™{.däð$¹£SäM1Z£<È`Z×Ï’u!g�^m Óùì†;œ^yG,¯a€aXúÙ�B�ÕÒqnß´ÀÊÓ�>£�¹ë…±YÙ’ët&ó®11¦µb±;È«ä'–È®[ÁæŸh?¸Óºõo¡4cÌWÓÅvÖüËiTŠ~o25ÇTòB2OÔÉpúœ@àÀe|®Ý7ϱèTŒÈ²x=¢Êbߨ¼>þºL_/P10ïï.Ÿç<É[Ë:÷¯ü._à¦Ô$ON¨(2/Âí›Ñ—¿Ÿó×UùD@ü¬B#q¹W›†Á Oß3 Œ%ëÔËu­¯°>Æ "N”8iU¨è¼`/õ ¶jiŒÄÙ»6rY}œòÂ8Á‰2ve”`µˆ¶ 4šEâZ�l½@¦V"l”Èû�ÒÀá{i”Ùvlå2¼ßT±ßôÆÑ͵if:ÔsMªù ù&û¯X¡U:òÜNæÀUd�^\ô÷MJ# Jur#-2åãd'«ØÜ™>&“ä­·Q[AäîtÁ�U08÷2ê«odÐOÍñïðØ’ü°ÐM¬ˆ�m÷¹j€ŸD–�—c^\^ßðµÎo|9b»P™Ag† I†“;R„€@BT¼±x2ÄÁ€^¶Aµ´Âr®Nmd‘êø�±�Ò ÚöØ�/_ž,nÌöS_*·É�T)L¬�›X"ë=ÄÒÁ\á0S£ÿ¹ß“ÕLºòžHäˆ?I£ú ƒÑÔ‚_â#ïý3yßKëf8âÁ¦ªæ÷ÅKM…ØÚqÜëÞF´››7Úèê·»HTt.iSžö¡|•|Š'›*ˆÎ¨_ËBÕ‘Wµ{ ¥‰ãÁÇFìì5 -®vIÀ×�£î<Þ¡¾(˜œKÊQ�$¥/Æ+ª^ ˆqÄÞᜠÔXEpøÀe4V jðxbãé{'гHŨsÖ %›4ý7Õ �sü’%Î`z¢£B¦Ð¤Sry1d¬ÚA-^ÙHî›Ùp×[{cdëcØÅ1¤^@VKø•q3‡BðA¬dëcõul3ž†ˆïˆéÑÊô?ÝÌûO÷²=j…�Ò ÕÜ÷¬?Ä­Û�Ó:?-ÝÿZ<|Æ:5“cËn´Ôö#=ò£Í–V4·î(áXŒ˜n{ O ~ôË·?ò"I÷Ђ<ƒþhÔ^N»ÄQµäÚY2íqF[†pà‘ñ>KÙµ¦…»Ï§xßfòÇ6P>¸™Ñ•2ݦà;Yhg(ö2”!¨)¢œ‡êx Þ!.üMsdõoNŒ6hçOp¢x÷L§½µI/¬ÓË6vxS¿¦¤‡¶eGë'V¿m;S½ òWÈ¢¤±ÇEâÁkhT_ASs|ª~Ädj5Qì±MöwÆÞ‡– ãÙæ’Æô€U5�A!þÕg_ç™�…h"<Ñ©á2'K‘Ó-“’|ŠsËE¿sž€¹9Gñ•K¢²ÝÏ–Ð76ƒØ b‹Çu¶Â×Ãj_O>lѳÞ}6KÏÄ^€ñ&]§´ÇÉÏ/õé{gc ’©€Äù�EªÙ/Ù@LÎ…ßžä¢ã©�‘¯ÉœÁ¯–�NŽ~5ÏÊr‘ V&ß,’­•Éöó„.ñ6JËE6-�g“Wž'"F}0 ŸéҲݽõ¬ßÛÉÕX­Ñh~í½ÈµK·–ŠrWzh=>(Ñï½™fmWJðYÉë#Þò^À�3(è�±må T.�QiâôtûaüËϸ†?;üYu€%г©bOI>ÅÃòˆìÙm™Ûéx#áö‹)ÜÏÿ5�ys×Ķáоqý‹|psÞÆË±KúÝÛaþÅ“a· ±OþÃV­ Ä*8ÛFAŒ„p¢ôq>ÀšNLÛ*w_²±ÁIJÞô…  £=V{ZY¤V$¨°õ"áÞ‹ÙrÿV¶TG1GÆ=Í"¶‘WƒÆ† 0îBÖÕ #pèB<_4M65­^,”?QDîM‰þL+ø~ï­4ª×à\>5ÇC&ùG®äE’ž9g¤kc¬%èôÍe½â3qF‚ï@|L‡ÁZûB ðZÆH˜Xub0˜gä`#K­›#?pØA–|£Dn5½qŽÃ'»Z&³2B®Y¦pì˜ïU‘lóÂ&¼Fn(Á‰t�ždè÷ÞJ½º ﲩ9žäV�…®QíšXCKXó\®ÈeLá˜gP%µýÓÿp“ÞâTæp•íÉ)3‘|Jò)žW®0_‘í33vç—ƒßÎÑ}W¤�ú–èàBo¿‘³îHh]Ðï™8ƒˆÃáÔ�ÄßTõì~�H+ªN¨:t0ìža“Ì1CubqqÖ÷èùŒ`,H<–“ ƒ âØäëꜢ¢™8[uå–mLÒ¯ÆâC‚F$ÀÆ›kÒ�pclŸØwè»úxlßÝdËžc4š6Ñ_òŒÜPFRE&|½ú’”à™’Ä,ßµªÖY1â¤Ó7)\ãhbXçN¨™ÍÐÿ½·G¯Vx5‘΂ˆ"Òbø”äSüGØ©{æÔ³afN#"ŽÞ"ö²/&ûÛ£ô~©`»±¡.Ú;¾1jÝáàc\/n8FÆžFëgûdEõôÔ¾“u{ºvÝpÊII{„ ªhœäÖÁi ƒ—$ƧKE‰5&þ.‡Ç*ø>q±? * ѤíInˆ3˜u«ÄA¬¡C µ¥ ¿#7–‘#éáöØ L¿÷Vj«/A}˜šã‘‘ü÷uêû6éZ—õ"«˜¤“�ÆÂ\úšú côJ'*5ƒó¾ÛÓòo¿é†×ÿ>o¿ÁÇvš„àD‰Ò2¹³&5ÁÙ‹=¢N÷ŠD3¢JD´{§ùñ«/1ϯ˜_£ÿN‡µqP5¾‘ò�óàÈ@ñêŒ:’¤´ÔŠ�ý† úxCƈŠê÷ÄB[›ÛÔ¾�nJϷdžàŽÚê§ÿ¨ðý…|v�ŒŠÕ�â{‚omˆ«á.ððL'*u5ºêL¼¬æ�mÔx? 78´b’"øGq/�"%ùs»±•iˆôîpf™ç³‘ý¿2†üJ AÕ8Y&\àƒo-‡ú‚sÃ{ëµÈ|Š3·iÜ©„ß…Ö–6ÍŸn¡—¤DÿÈ1 ÿú!Á§ÇG§äãï»Å"jÀy4ã­ä¼5}ëYÅ®��{†µuà8ê0ï¿i›Ÿ}5ÚPf€HDS>II>ÅÂîšÑæa涸Â4ßÇÿ1Žüf€Ët¤ ñfÃÞüqF“Ä4Cb½ˆõi¸ìLÀOßkðànTãÒ&�Ÿlá/×ôZòac|¢eªà’hmmIeªâ2NðlŠÑçª'l)ZÓ�èGšWų¹OûÌ"0 *³-d�"%ù§PÑ ÌìÓ»7Ìw®© IDAT·T*¯�è!ši ,Ë ÞæÃ½cÂÝV¼„ˆƒ`½øá^“tË�x—Øøa'°AóÂ&Í×6ñ—¥DÿÐ1A¯ûVêÕkÒ$»ÇQÉ«COæíX/Þ3ÕRsµ—ib8(¸U¼~eá–¨!¨Ì©F¬u¨Õ4‹>%ùºÃ"£IÏ AU"Å *37^e`¯Ô?À�M .Þä뫨ߠr×8ƒ»bоâÆ)‚¨ Þ"ΨjútÏ̦QÔˆ<„HIóÂÍ×6Ñ R¢ÿþ(Ò뾕FíS‚lÝÒïe}±þ»?�óØÐÐóL6cû|‹f»ÀhKƒ¹ä­í7?_µÍo—YP˜UÑYAÄ‹VLºÂÏN¤—]g""˜Ç$‰+"W+6\´»¬wÛÊ+­³ò¸B ´îůƒ»¶ˆÞÑ5IUœ5ÃÞÒ6õ¥i$^5©F|ßÞ¼°…‹2šfÝ?¸I¿…êmϬÿõ—Zn¿YâüM‹°«l½YÔÈO´âlyù1š(xn-×Áw-SµˆwèZ¤O-àоñúpýªøu™&ª¢KèM“SñÏîøSVùS€i’¥/É( ™qéÊNI>Ń`VT½1ˆDÝÍs¢²[ÌÞá•¡ þÔI<ÞQÑšxÝ æž�âoï ±:£àq&u£Ÿ°ô!!\ �vú„Tk^ ²ïííËoÞú•ÍùöWÚ¥EzñwÐÍ1ËëÙpˆF±No¢‡öª? jWä]c}±í¦&jŒNtÈ�4É–—È­;F86@Ò8Ö)’?­œÄ¡±MτފsêÅYÀ¯¯Ëàù™¶A–<þ8¹}Y÷çw½mz‰éyQÒ\Ÿ”äS<\a˜(z‰Üìn1rý¼~ã3?šsܨ¯ëi@§S†ûÏsú�žI^‹õ^URŽ?[1úíŠU€ÕÔºˆ?Y.úi_loìÐÞ€ú�âNdôx„8? tie:WÏvÿ®VlÒ,­ÐYâ¾Bƒî¦ýÔŸ}”ÎØ½´ ñëŠu®œXfÓDÖGÊUŠUÍO45YÔ°t®øÅrZÏ XEƒdèŒtB§™trÕèóðdjX]ÿ/cëº?÷²rŒéùáïÒ¤�dzÿž’|ЇUTD®ÖÈn¼öVf^š%ó?-UmË$,;n`|22éã {“z×g#ƾ1JáÏóÐJmñý`¾iXϘ^ð \}kÇŸ(¨­�;KàFÛ!cÍ›´$°^àRU«êCe€Ò ¡8ºAÿS�ü‰O-�£:u€#S÷Ó¸ønêŰ٫sýÎ Ê�ÖÖB3ž(5ŸhSš¬’+×È”ÉNÖ±¹§É÷Ož f8UNAóÎJ#ã¬*£µØ<ÏxŸˆÊ²Z–‰ÿ¿Ö:ÞüšÓH‘ÙäB0™:‹’ªù”äS<¼}8‡rËѼ”çd0ÏÐi°"1ã†û×{nAC%X<Þõhì“;OšEyÖüm£>žüÃA·)ÒþÔ˜üBlF–Z…K¼ýNc³ëÚDñÞÍLÞ»…M«ët]'«´3h7ƒtÂØ2ÞÔ ^-†MX9ÕãŒE­Å…}º™+ÙêÍË…Õ›WFX?J½ÔàĘçömUâÒ½âaº¶öC¦Î³JKæ¢u�œhSikn¤Na¢Afd‘ÌDó$¨ñ;•]ï¼EŒ³ôQ_è3¶èx^_lŠÊ ¿@ü­¯_©o~ïeó‹ÌOdN•HAE"„(]ª)ɧx@Á.B$Ȭ&]T"‰ˆˆn¹ÚF¼Ú}}Wùyš•~´-°L¬e•û7 ·¡Æy; q‚dMÁ§vaüæQòŸÌC5µÅÃÅ!û§fdÓ�—è\ÐoÉæ[–Xýá¯ËJHÆÖнՅ)6­”È�%¿\&ÛÈ!µQ¬+²TÏ182JxhœÜr‰PËú‚Ó±”[¡Œ³ž‹Í&Å<Q 6ÆÓÉö¨f�°O;Wû×j¡ú¯Õò ­‘/þwå÷ÓȶqEÅôBèv_“mž9QgªÜ—‘‘–ŒLV)Nt|¶Ü$3rˆp,~‚óô½·ˆ‰ 0š!y×É4³õ¾\•Ô›�£=Nö¶Åçt~â=_Ÿ^¸ï7f˜/ª ‘ÃônV‘”äS’Oñ@r]ÐùùÈ0ÉŒ¨¶b—ˆÈÝV¸åªl;;_D74�Í¢‡/ýVìq±õ˜¤£»G°ÑZŠ'ä¡þû—Öýë8ÙOg¡–šç‘â HøÉâH0)ÁÆ—Õj«1JL/ζ‚ê¶Õ­ÄXb�!èÂB‡fK¬5ý"Yg¡'èÝ0ò­M\¶°…â⤲Z†zmçÐ^€¶3H3 l„Lµ)`]¯›ÅaăÆA ^ >Ó,ÔX..³:ZýÛúÄâßÖGŽRËciC•}׈ͽ‘šq9žxv©Îå*'VŸ¨Q(·É�ÔÉM4GŽŽœI[ZZj†g†íá´g\Oš…^Ÿ‚ŽWÅiËÁ¸'7ÙyÃ;¿ÎáwêAæU”SSä†}éEÒP}Jò)3ûT™½ÑF‘¨ÌªDs‘þ[Ä%A;¸±,½�m5,‹gTíÂ6âÛô½â­³MïÞÏzŸý»,ÔS[öú …~Hf�oçɯd0ý í Èòñ<æøÙ¥£ãä꣔ªc:R/jvµD8ð^ÑX(·ólZÚŠrH�”1½l‡¦ñ´³=šå¶o”j·6rË·Vó+4&²tÞýÜû´;h�vò ¨ÃkÇX�X0¨d­Ês�×)‡•¦ G�û aï'WßÇ­:ƒ�¨šhN4J‡Î¤$ŸâaxÔ'ƒìKtß{Yï{á_Ž1¸²a�*�U]ݤò%oè“„ƒ�üp|гVÁçÿ2M²;¸W$|¡°£cLø²••;U—°»Ì©4ok±êUû8°ˆqN5ïú�²Õ0⬪™.Þ*ôµ !ƇJ¹gé÷úÝ篺ýÍbKØÉ“m—(Æ–Œ´Ñ VXÚt��al${x+¥£çQ¸o#£K£~CcÂgš9he�v†°“!Û&0M+†±�gjž¢"83 [hÓW9QlQŸX¥^\¤VªþM;פ[X`iâ÷_tУh³´pÄô¸\–yI¹Á…c &Ç;ŒŒ¶(ŒV%?®¾êhÉU•«�—óú¢²ŠcAÃ¥v0øÙOæo�ŸÙ§¢{ìš‘fg1³³hžOI>ÅÃÐòI ŠH¦ÞM¹¶|jŠø9U�šÇg ë1ø²íÚ> Ȱ�”Ï'“�~г‡à¿6Fþ#9è§¶8S8Áär—Çæ•+«·ã† §I7gP§N°!xDEEÅ›ëÁ®í@ƒ„NÔ�«FGÇô½ @z’ì4büDËÆj�3õL7>ΪÅË€Ø÷¤ŸGÖõÑóï¢#·K,ÎÆÁáuÔW')Ÿ(’_-“k•É®fq>¤Þ,Ç�Ã䎭£°4Nn9O¦“E¼Ab¡Ø5l]žÄ¸XÖQ§Y‡ cš!´²qÜ Zµf¦F½¸Duüð«[î¼£ºõ;Ýzœ}Ð FÔz‰ãAÜF«”HUÑEdÕåÓ?ý…¾ÄÕ3*:/°]U*ûTTÓ~ô)ɧøøÜªD*Ì*Àô¼˜ñ[ÄÜȵÜüÒhca•O–E_ÐP¡¥‚AW¶0øº3‰@]ó¡‡*^L=;{±ˆŒ|{<—Ý�üã�˜ær—Êĸ¾beåŽS[MO#¢ø”S¬Ãmã¾»¨[:ô†U)NQ°Žµk±ïªïã|ÒO&yÈk¿.“dêðµá�Äàèo^äÞÍ‹à‡×9Þ`[9ò�Ãbºª(U‹„ȹ¯^Îöû.`Ýj wd=A¿€t³jê9çj¾m¡UbܬÓõe¼Œ \æ…à,N­øÜ@›Ù.µRÃ×'–XÉŒ�Oþ9“õ�ì­GSM­Î‚óú†Ûº¯øÊ»®Þj>ðÇï2Ì]ï¢h�Ÿ™'¸íYs{Š�¿CÐíLKeºÂŽÈžk`Ï.œsÍÂN0S •¹H™Ý.ÌíS�fu�ŠÝ™¤Fˆ€ª s {ö`ö|Ïìɘ{iäà1EªÏ"57¿Jì{®ÂWæT™Å"Ä÷"ç÷„�T^Еºé£ËÛEo õîZ¶ã#aæ‚VºžPl„ø»Ý»^¶²rç“ã° ’9TI”†,'ñCöOÎ!N†VaÖÖ˜¢‚È0 ¨¨Çàpêó„í™^†ÐÂ~†¢ËR˜8Hq]�M ƒé:Ñ/lU÷›ïÅ­ Ö®ÿD‹Ñ‡±ˆã�QP‹%DP¼ Ž�ÖTƒŽ_p4ÜGOQö‹ŒÊ.^šj›. þ­];{×îy½¬r“Ÿfš}ìÓ=Qdö¼ ™¾?}šmffN’{ªèS’Ò°¼ ·‹ÓW²óçÑùÌq£*^:ÛÐ/†˜¬—dž¬Íyv&Uòg#ÁWÆÇŸþÑ0ÜÚI÷ÎY�-¿£Ó¹ý%««ûŸ¬G°' áÉ0žïqÃ$Áï]bŠf°ÞáÅj°âé©ZÄz4£búàQÓW®°ÂÅ}µ¦�ꪟX¯•?û½‘¿d´µ™ªÛLh.¶e¿ Ç6gì8Þ ¢ÄbÄŠõFÕ€ŠâÔ¡ªbÔ$e£69¬ð£½ôA›du•œ.Ša±˜cYzPÏ=&˽A–…•eêä×;Z¡çðˆ£²ÃQ©x4ž™QªæS’?›È|ÞªL{AôäljOD¹kvF™òWøãM]ÞÚ¤©"uhî ø*Á`%Œ­gœzzîŠ:�31>%ùGNð11ñ¬�Á¦85ÇYGôïìtnßu–½Oø`Ü)µš¨sö“OÔ¹ŠÃ %üšÓ¯€EŒ�ÍZìß{´~TÅ DÅ4ëÂ+bü¥}«ˆ.ˆú�ª¬þ-òágÝà£W/à¢e'–§c·˜ú Èû›Ë\À(›É³™�½XÔm¢Çy³�¬ %C€Á Ó‚/ŠS�ÅbÕ�ª eŽE°(J8lZ¨R'ÃAúzÜ*‡µÀý~‚#Á ¦ÀR˜áD ¿(Qg–Y;䩤›¢¢Ø)°˜6Pè©úäÄÑÓƒsBÒm_¦�ùÄZ§§(rÚan‘$:ù½ ¦“DDöÁÉŠŠpöV!¤$ÿXØP#«s‘Ÿ›]› /:Í´ý‘�•ì‹rïÏÑ}‹7uo´ƒö.D¿Z²,Æo1þq«�OIþá£gLðÞ©©}ÖÚ‰Tbœ�˜÷Ÿ:�}»ž´Šþ!8 ‰º×cÀãDuMX¬ñâpp1*W¨¨­�®¨q·™+oømó�+«&ø¿þ¿AôЕò%w“­'sBȳ>s·ûMTuÊäÜùÒb›Ë²•2[€ 8J¢X•“¾‹¢!©sTIº‰ 'Ú)ƒJÒíË›}m‚¶ÕE)²¤bŽSWèÅ{é Ho�,‡xۖζ/ºŽuî".òöo¸í˜R©¸hGÒÔ'¦™–„˜wèì°ÚI¢5î›C£(¡zT "ÈŒ?å"èš3¦¨ŠŠHòâÐA`8“ä,NLKè­�G™›/³ÌÍrÍn±|>ò[>e~ð¿Ydð–�!¨z|×øþ6Ï-cÂR_QƒAMJg3šA�}ÿºuÏÿ§”àÏj,�ý`>…/yн Ƹ!i&‘¾C,IGùì%–Þel XPdó_ýšÿИı<Ü(ÔþKµô#æZ³pöÞ>GE#Pæ1LŽAnp€\‰’ñþ�-¢I}­àñƒ„†ŒÀ%•+þöÞ;Ì®«ºûÿ¬}Î-Ó»ÊUs 2ÛÔ`d0$ðRR~2᥃ 6:„ª+'ZB0lp ^JÀ&[€ lŠArrÕ•U¦—ÛÎÙë÷Ç9#if®°e�¤Íú>Ï}4šÍ\­³Ïùìµö*•@ƒ‰Ø±_¿+ÓvÅÛêß[Óú8u#®~Säy/�ÜV,âÖ­K¶šÖº­§(E-êd zRë‹Èä÷¦lX#KoÞ˜Í�Ò¾{˜îhKë#¬ÔQ–°D#VhE–“—.šèÃùæ½�»E&ÇÛŠÄ‚ªŠw^UÎI bzà ð䤎ê�«2 Âvmq[©»�tÈòõ?2F?môÓÉç1ñÆ o”~ÙèÑµÂÆÓc€�° e3J-¢²š rVñ,…"×)EdO{ÿtx�Aþ褼(ÂF%8c=þ®~2#Ÿqïïý³FŽ ”ÕE‹‘ßtßMz.(HÚªÖ ?÷´­©©ãÓ§Ýà\[læ˜WZ ÑËkµ{çSyÝÑ'q/'su4ÄeÁE‘¬ò°Z -AüG×úå·úk{j´ýà#yâõ4goÖñê»äüXuÖ°X�~¼vŸ†AëòS,¢ª)ä‹EÇêM¸~3òcð늪ëA6±ANd³lZ[Ô W?*dûxÀ®í­Üݵ˜r½‡\¹›²GVŽ¥9^A™ån Nò yT¯žÐeT¼÷Î'y *Îá<ÎAWAbê5² j–  …Œ†tQô@¾•û\;÷Œma€QªÔ©ñš>üÆãÙ„°-Rd5ëd3$�¤àßÎä�ZħWXѳÉþær÷Þ>Ü?V$ru2ñÒÐÿ®/ ¶Ö]¬BÒLÅäç4à/ko?é ÑÏ[͈9Ó•4¤Bìs¡†™ˆ•ãȉŽ þ^ôò7Ê�s‘v¾"ýW1òÄGþ‚8zßio•�N>ïÒ6ÉÙ´$Óæ§=Ï~=²i5²�µ°ùDe]Q—H(R”bŠÅuP–¾�`ûwÐMÅ«uCq³²®¨Nq�b‘Ûò�ÛšÈW:Ù9¼”¦ò2:Ýc¨+Å×k5\NUûPßN–,9r ¢ šæˆ&ۯū 8„¬„8<bœFd©àÂÝÔ‚ð² ¢­øhkÐÌ®xYfÍõÁ¶ FGaâ¼õÂ)Äsy��Aþ€ˆ>9‚qÊ‚ÎqF1¦o“ûõÞÕ4| $vÃI&}}úÛî€ûâdA9«$…ð�wé�ðÉb3ÈàM³ ú×W*wîÛw¾¨"ÙTE=�A¥$AÖC¬¢!zL y‚wêêÙŽøÛÑÿ÷N®¬ÐsÞ>©(’“ªÞ©¾ï@úѧí;ÒNö“Ÿ—½‰géF`ôgþŒ½ÛŠäßÓ}BQ%ùùIÀ`ú?Uá,p[ÁÝÂZ_dƒ®“É9Ò6xÑSÜ’ï„î¡-,å¾`)Ãq� V¢¬¤5X…‹«õ�QIîi¦â$FŃzTqŠóIºC(B H€hF”ŠNˆRÑ@vÓ<@Îí¢Uw0QßÂ8»ÂVîÏ<ž{ËŸe˜-Ëcžö@L~íôÄõH©„|þ(nG×ñRd2;P¸z-°Á×§fz®¸ emQ`µÂY{¾V,îÙ¨í½i/ôÔÐj�Ÿ%]ÍÕÁƒ\>Õ]û†>\„Äá˜ÂD+„[ûàîªà“ÞHÆ'�nb—xôž4¡æ0{ òðÿÑÑqÊ�ë0kêI@?ïy ‹Ý2†õ|°¡ƒ8îÅI72I¨URp¦}Šˆ\Œ ¸d|˜¤½½R' &têd¤FÆÝO�»©ê6šän²rãn€E•ÝÍY†š`l÷âç×8·7ö98ѯãYÀ/W# Þâ8ÿÔx’â ¬/"›6!NL: &}ÿ“Y«7 kÏR¿'ë?å»Aþ`–*rÍ£³xÁÖ šÑ‹šFC}7ܺRØZU¢ÔMOl�N� <¸t±¨Gýa:Ó1È7Ö@6ÛüΞžgýA$oÖ8ºÔúŽJå¶ù”Œ'1ŠÏâÂ:h@¯Å. ð§EÎgÇRÇÈÞ�ûÆ/ëÕUïaÆé߃ü¤W‹P,"«W';ksúŒ-¢WsµÛÌfÙÈFv7ºÍÏ  è ƒÅÁ(Kâ!–‡+‰´ñ —c©:z iSO&}¤»´šN÷7Øó¬×Q‡2ù B�Q!fay· ‰ï ›Ùe¸/S bv�÷ñàÒo3¾ýóÔyºv5ºa-žõ›�5"}»Ð×¢iÙ6ÅÔ/¦oÊ<ùƒ½Ès ™3GxUF*=*:¾'ÔMK”»bð^ñ�Áí FùÉð|Zqy8ÇÄägj0›mþÇžžÓ'ÒdÖ8:Õñ›*•Ûϸs>¼ßÔ ’ A"P¯hFèQu§y|~T�]*þnÜ�—ð_×ßÌcßËžAzS¨W‹8é§ òª¸ �$ƉN‚=aïºÔ?›ì"¼~=ºº(I½êzÖËj6Ißš ÂX¿6n! ÛÑÌMt¶øáö8Gom„G‘c-£u Èr” h& LŸï“i’I|pš´P‡"i§ƒ¤>R�:�Ž’gˆ€Q u‡8î¥Ìýp·kgk½Ä@sÀx¦“Êðªkêüx�§¸I`-°Y‹ézõZÄ  ž{Ú!M!•oçŠÏë¨Wwâ[Uï¨t+÷†^Ær¢9(‡Ž*‚¯»´ŸEÚûÆÇiKH=|™™ù™ü» ð BK’d¼;æƒG¤5Y�DA!.Œè¬zN Õ5�¡:ÜEðóæ²oÝÎþ $³Ÿ'W5â¤äeŠ7&Óžâ{>LÂÜEÖ œ¨�”"Ib Å"ÅuiÆAÙø,Ü?^CQ_ãÙ°I8k—pʨÐvKÀyt�e1VÐä–Sq+¨Éríaœã|7¡æÈÓ†S‡ÁïÓ½8R\’™�Rx¼w@(!�*YÝBô CBðÙ|þ„‘ÞÞÜ\/¯‹•8&Ž“I4ä"ºÊqæ”,õ¦1ñ:r—ºß})÷o߸½ú„îð p²Ûú¤†]÷¤¢é¤3­ûìÒ÷ *lH�¾EÐäð»¸.ýC§ IDAT.M§ã©jñŒÔ1.ndÝj8ëjtWl¼ó”˜¥mýœ±q犛G)ÉqÜ gÒ¤·Ü| Ÿ_Ù—£6ÖÉV×Ý|ïøŠz–^E Ree½…cq™cÉÆË|¤yuix7HúkÒj§*.Dîpº ¯�@OÖŠzà+�PP*ˆH~ DfÃnóäR×´óÆÑùx’©Š×@Á#RC}�4sÐd¡‰“d�*„i]6ií¬™€(ïT&20Ö„Žù€rÎSiRÊN¨ÇJ\wh$ÓêHSBħi¦IƒŒôÀqšµ/éŸ7*OiW�÷ÁÝ{Ç>źϢO{d§ÇIÿi7%“Ãïéø8o'FmkjêøLGÇ©�k·U¼°4—ÊëjdãÄs¯J&†zQ—-‡Þùf¡oBÝ©ê|Ó„ÀhròÛË›ÿåÒËϺumáÛ–#Nú &ñn>†�ÕÈÜ3HOm”ã£>–ÑéŽ#æXð‹ð,–ˆŽnB²’#³çy=ùN† ybï 4ATñæÉ¤–vsÅèHpçVäØ|à—º(xTYÕKÔ!KÒLvH”„ÊPW!F” N\LVñA; `sq’—9Õ¨I¨4+㙺«4¡Yt¡ÔTD>¯’ �” æ’í@:6Çá½€Ö²±Û§eþÞÍ­BÚiW'ÿNª°·VçÎ�›§Œ¿»¹¹ûÒöö“ ð S»�þÑÒÝ­Gº¼.‹dpR#ö±‡ ".VÍ•³>+5©AǨ†§.ÊW�±½S¢ß^•û§ÏýlâYÁC~ï½lšÛ”ß¼–áÁ"ìXÍÙÌYº dÀÍä´J+A®ƒ ·È •WèK YFÌqde)í&ã „.‡âÕ‹¸ª¯äR'¿ZGŠÅõ?(^½IX»•׺k¹Îí8fKÓ¶ßÖîé>¶Bï®JîQY �ke|i�`•Ã/ �6m|>\ ’v«t#TˆTñdDȈÒ ]“�%é~çãÀgˆë9¨åÊÜèX€Nd‚x<ê¡R<õ¤É5ÖÓ J:éŸ'~»ë¾y™1àÒŽ×IÖn2³Gãù¼£µuÑç[[Ÿx£s­¶z6èÿ-ŸŒvwË‘ôèU” ±�d @~×Õ”_»™‰"ƒž³úêÛ<î'ió·Üʈ®ßdé›ð¾ïXᘉ˜ž•Â*Ñ`•ƒ¥"§¢YxAÕ#”8#Î Jè’4€§è„Ð2$,v  b|©g�JWuh%À�‰h%P ”‰êÞ«÷à“áѨ›GˆßÒÒÒûáööÓ ð¦}5 î?òùšºº¢gþñp{=* SWÍâšëäê•ðÏ"µ�xt@î'³õ;¹—_ü�êÙë8 À›'?/yÖnHÿ¶Y‘d°qéŒ6 L~G±ˆ‹é•Ý3ÆMº ®_\#¢ë­Nþ ULŠàX—ögD‹¢uÏ|á)½ŸU˜œc\ÜÛí1éSˆ@V¯Ö®õP\/¬Þ$ô](¬Ù¥¬ß¬lZ-k6œ%×®u_¿!÷œÝtÝHÏ£óŒ,_Ö—j‰$Ó Qu*qˆ”CüDF¨f…²Æšb*9¨„BÕC\ r¨ÆI© *êpB»À!AŒú8i â3ˆ‹Q—|nOü²w€O%Š÷ö½Ü7À{×q£É½[ZZz?ÜÖ~Úm"9[±¦FZ¥Zc¹¼ééÃÃ÷8=4ªÉ>9ç!vÄÉ05qùJžê$êŽÕÉž» üjûÚw|käíïU2�{¿y4âä_š'?ÇÆtʾ[²½ý€E�Z˜V h ÉjAŸ–*ZtPTƒüQ¸@ÖŸAðÂ6²ÑNÂÂíôÝX¥0âYÒ\cÕ¯ ^ß‹ÓãÑJ¿(‡¶‚†>a|:NIñIR  Î¥ ›ÒöNÉ”K‡H2á1)òâ ԚЉf¤’Cª!~L*N¨×£Üxõ*QK¬�"D ›´ùM(®Nâ=»Ó=Ùüˆìéò¿',Þ‘¶ù e²÷ä$ãc¼ª(hk[ú±–Ö'Ýe¼é!´B5:¯Z½ãÙƒƒw‡ô>­¨™„|'‰¯5�PC $ÊT•ÓB¤¯‚êî·#v߬yß§â�ž¯dO~„¿y$âä_ä¦,\Ô„{&Ïl®‡âúõ•«Wå©è8}ÜË® ZÜ|–þÇúø9‰owú¿‘§é˜n)'ÕGÉ}Á*¶„}î†Ölí¶ž,²(DÚêh»mÎ)’Å9DødÀSÊa�*"GÐ:9=BÀ‡1šC4KÍg ÑŠSÆ÷¢U «�ªSª¥ÆÄuAëÄ£{Ëôu‰§>MLë¨{'=ù@Eîjiﻬ¹å ø™ Ò ‘Åq÷ê~‘ðÓùücs��Ñ3††îžmÐ*¢¨*âbGLL]�@ѺD™ºÊɡ袪âÙíÙuCóŸ}à3yå#üämjZ¸l0ž¼NVMê¾áa=°.õ�ׯ'(®ÿ¾CnSn8Zž¿Ÿ�ÿ¨“¸Ô©õ¡ÅTG 22¼Dw•ûØ–_Ä=ù>þ§ÅÓ¿4ë|GÞ»–4h$ƒœPI¢Lqâ´ˆ ÔÓ=AÚä/CÒ#À¡ˆÏà"�Hðå:žA+™¤qP9*ÎQ¯CÝy"ÝS�({BZÓŸbw¶¶.ºÄ²èªô%õhçN'¹A§MÛ›ª>ˆß\.ß¶fhhËl‚^‰A�†ubMî ëprºltÐ!;¼ü‰;ný'ôŠ¢Ígd a(âä[Ì“7È›æ5åÙgÜ#:9÷¹¨"ëö^l%”âä¶0¾á8üþ ÿ�¿¬žÅïj'ÌSî–ñ�eÒ_Yìw…Ëݹî­-Ñ�}èhŽ àà â28I8=FUGR—/IXSƒÄãÔG­ç�z€ÖBt"Ê�PvBEbÉ¢5ï{kkï§ZÛNú¥H³-Œ©ê^U­ =ohðæ�L>eGë‰?‚.ý ;ù7V*wþåààí³z .õi#¶L@àb jO ˆ–Ô€wÃÐÍt|ðcò�3bm}ñ,üfƒ¼AÞ4ÿ?¥[£îãâ˾IŽð ›Cnx4?ÿн#?*øÝ�Ô‡V1>r¬ŒÕz¤ ‹¸3ÛÊõm‘ÜߧБW óH&鱿jÒÒßMFìU%Ét �GCDBTC„\²Œã­íhÊGwv¶n™<Æ7MüÙµZtæÐàÝYoõ5¢óM—tvœt“s­±™hŠZAÏ®Õî}Yÿo6Ï“L�Ìj bﳸŽ:áˆ'ø¥Õ@e(F ;|{¦öÁ÷×r t¼|–îÅÁˆ“m�_˜²3ù£f·¶çLž$`ž‚>ɾL#ƒ„ˆK}ýC{RçÚ×6HÈ MüV{�c€É£Å·áÔ�öITê–ò@¯NT—0÷ò ôÊ=™Þ`k[oôÃÎ åÞ ’Åi콦ýå‡AÐeý^ ‚ûr6{ ==<ÐO6Œ b�8  h �pœ–#.Ô¼c—óìô2q+nýgå{Ç«ïzͬßj&ƒ¼É4פH¶®áÒí„K·ÓÌèŽNK61äñc=·ŒÆÍ—tyÙfF›¦,è9ÕÚ=/Ü%{�èpYñÙ}ŽëZ¢¨ö†]»¥}½Oþ¡%ãMѸ˳Ùc¢ž÷wýý¿=�3zŸZØ�8bñ<&ëei e@<ÃÞMü<ï?úÏ•owÆñâ7›ÅM³);·4Ík­[ZkÍWözÙ˜5fzðV«[_Øß[Wõ°#Ý]W©e$‹¸}Yï£ v÷ÿê¬(Úa»ÿ™ý³ÙUßëêzl,:\4¢ßxMz:DœCOá1 2†c·õ[Bÿ™‹+ߪÇ,{/‡&OÊÂõy“iþ©µý4·}‘;ÌÓÔþ‚juë_ö÷ßîIF™¸43¹í«Ä~ºÇÞÇõ—öÜúÊz}[Þà0E ŸÈçOøAW× ú=XMlŸ�qµÜ1Š>:RÜ0ÊÝøÚVÜÿMþ{—gÕ‡ÝóXí:äM¦ù¥¶Ž›ijùŒ~?€?·Z½ç/ú'‡®8bb�‚˜(H:_†È¾©3@ÿâ�Áͯ¬Õ0ÐOÕÈÇòùÇþ)�~ò~r¶C€“atÔV{ÆÙN¨%š¾ø¾üå·—ê�½$sß¶]Cƒ¼É4�ßyM-Gä>3Æ4u‚Y­¶íÌ�þÛ+¢êI²®¢ yÎgâä™_—H]N'[�ô-H>nŠ£Úóoû›z´£Ù 1ôÏçOøÏÞÞ“#7ôÚLBÑG–°†×"þ‰uQ7BÀ6 â-Ⱦ/ü÷ߎTN¼yGF»~ Xvôfš_^jç/È72cLS7pv¹Ÿ14ØšQNnÆÕŒ{â‰0ÎDŠ«ŽQ-  $Æ«*΃$M%N™®ÝÇñËvÿ¾©»;º*“]6a}5öhäÊLfEØÝã_Úßk˜ì§Ï©Jìh�ªÏéñ9!VqeàA‰â{…«Þ›ÿÌ�F'Nþ4XÃ&“AÞdJßu#ù¦K€]fŒ™qˆÄ¨ÅW\HÅÕÃq‡/ Zöeq‘ÃG±:8kggtE.Ž›å÷h äª0\šíêŠ_:8øû¦ˆ¾Ø�Gâ ¬p¿§¾ýî§›ÞøµRåEŸ„`éa~‹yƒ¼É4Wÿ3òMŸ5À7zr¯RÆÏšFN}ÜýÈãx"ð�˜a©G;¨²³iBnÜ}r÷Ó×û<ÅÅ�éô¡+ã· ÷*�¡×>ŵ‡hS3MH¨j{æü–<*h®’¿jïä¹v ö¨rE&³<ßÙ•yñÐ@WsäÃq�Ý8Ý¡rí'xí%·—ÿï'!<Ƭe2È›LLžÁ6c4üè+Æ;vlæ:4�òÎ12ôljÕ×aýt�‘Í}ŽöÎIÐä ò&Ó‘Q&3L{ç5d²_¬úzàŸ3ü·Ã”?òÎ1¹É婵¸­Y|Atràù¡r}†áÁP«ž´Û�¢Q2Ù«èèúâ"óäMyÓÑ¥\~m�Wÿ Df�F€ÝQóìÙ&„`i½ù|”cU ‰lâ6I2Þ³¨VÎZíÂN}6÷¥ô‡Å£7ÈäM¦C¯|S‰¶Î/?2À7ãcuÖàYÌDV�O]õ04©óqŽÑáÓÓd<+¯› ú/¦ò:5ÈäM¦C øí´¶ÿ7ÎýˆÍ Ó?3fàœÁY|*y˜Ÿ;d}R^gýT�§åu×é:z“AÞd:8¾¥ý«¸àGØüÌ;0:3bð%óv?Ã�“#{Ÿï-¯;KÆ›®ÙÜi> 8d&æÉäM¦C£¦æûiiÿ*Að|_:zvÄÐ_Ž2À§Oø^»Ö¡2V^÷Pý—hëüaxHzEØ�g�7™f_¹üZÚ¿l€ßÏ�Ÿæ9à÷ü6i´Å8¼šZ^g¡û©%›û m�× Л'o�7™fðm�—¥gðöŒ™ø§Äô¿bàpdÀq‹"#(z$çÂî-¯;+¯› úLv­‡4to2È›L³øŸš¿?À¿ì�%Ù5rãäê|ö!() 89r3à÷&ã½Æ<úýzô³ÚÏvÙy“iv””É}ÎßHñ©þ°>ý½®ñ»9rJ@¿†ZõÕ@“­� ¿t³î­„Î o2Íà[ۯ¹› ð î´è9ƒg ^À'<—9Æø}@&õÚ+±Ðýtí-¯›…†9yƒ¼Ét°€ß–>¸Îž)�ÿÜèp%Ù=Üû\æ‚i|œchà…ÔªtÛZ™¢¤¼®£ëºÃÙ×d�7™¦ª©ù^Z;¾‚ ~h|#À?;bè¹G ðs2\?ÅÍô†þ‚jåÕ@—­™ýéèúáÁxô¶ë6È›L�ÔƒßNkÇgpî'fŒé ’$»#èÁïú ­µ\]êêph‹“¹yÕ€á�3©U_…%ãMWÒë¾³û;�ôŒÞ o�7™\¹¦í´u~‘MfŒé “Vµý/<Ò€G@¿#xM‹Ëc ð(:· ?ùN‡žGeâmØýLÐg²W>Òyôyƒ¼Étà|{ç'ù½£�­‰Ø½và$Ù5„|°×í‰Û ˆEæ¤éT£ÃO¦l o q²¹ÏÓÞù£½AÞ o2à ­óbü~î¨hMÄîÿo€87GñR£îk!â€ÞÏåǾªcløT*oÁB÷�@ÿ9:º¾cCmLyÓ¬?~“,úŽK¹ÃÌ1]!Ôþ¦NÿßàÃ9•€è²„.ïM‹ çd¸~¦GŸtÆëµµ5Eu2Ù/ÑÕó凛Œgž¼AÞdzèçDS˽´v\–ÖÁ›¦(Õ—Ö|ö qÖϱ+‡Ô�Ó‡}çb™Û�ŸýPÿs©VÎúl�M‘'ÿ‡îÞË ‚ÊCYÒJ^ ò&Óþ%âii»ƒ–¶/áÜ�f�éj†êK« =chÎ>¹€H™8ÎhBù:¨ÌßN8#-¯3�~ª"‚ðèìýa8fž¼É ozd€onÝBsëgpîWf�™w�Ö^\cè)ÃsðÉÞõ£wGÕˆðªsß‘ŸúZÕ:ãÍT� ¸–Ξϓ͘9LyÓ�þš[?ƒÈV3ÈÌÛÇW—T‡Ö ÍYÀO^Ê;ýZŒÜã�j0ïî}axàÌ4¯Ç–Þ4�Þ×ÑÖùõý�Þº?¶ä}‰ŠCDe^¹ò ©&ËëÆß,±%8E1Aø-Z;¿Ùôyƒ¼É4õ™ÐÚq3Í-ŸDä3Ç å¨–_Oÿîå¿Öù1áKˆ´:>CÖy7ÿ ? ú±‘'21öV}Їá×yôyƒ¼É4éÁÇ´uü†|Ó¥ %3È uP)¿ƒáÁÓñ¼x€:ò8�j è¼1 ê=‘òøP=Ö–äy‚ð´w]ºO2ž1Þ o2âê´uüŠ|ó%ˆÜo™¡n*å`dðé£3Ræ‡ï‚ññ8$ç<‚P•y}%’Ðý“˜=ªÇÛÒœj\ð:{>OŽå ò&¸ J{ç�)àï3ƒ4ü…Œ >}Š×4OŸâ²¸4$� 9ZF ã#«)�Ÿ�êr[¢Sã‚ëè칄Lf$kö0È›8àÛ:n$—ÿàA3È õP«¾j�¿W‘Ï�ÿÁš R[¤Äª GǵÆFž@¥|>6¦¶1è;zþ}u>Ÿo3{äM ð7�Ë1ƒÌP•ò õÿE£‡¨2?ö¬Ý“Bç{½ÛCx9š®ÒèЩ”'Þ,²%;ôîWM'´´´,6{äM ðí�?No�4~âÂü¤<óÅ“×fÅ+zÑ2êå(¼Z£CO¡<ñz,ë~ÆÕ'‚޶¶¶¿, '™= ò¦…pá]-ì躆lî‹À d†º(O¼ž‘¡§þ‰ï©ë|Ii 2"ª¨âÈ99ÏèГ)O¼0§uæ=ï–—è ò¦£\Ad:º¯y\&{¢oà÷è*Êãoetè)ñ�ñ¼)Eó9%ív‡ã(%ü>}µòjKÆk¬“€k …Â1f ƒ¼éèÜÍÝÝݧg²__£f�€åñ70:|êÃøîšÎ“:y ¸‹�Åû£ìL~º†ÖP™°¬ûýh pC¡PXe¦0È›Ž" …žîîî2™Ìc¡,f‘é€ã£06òø‡ù/æ�'?˜a°†xAUp õ×tøT*`gô µ ¸Ñ€7Jèî.D_î‰ÓÞõNY›¼Ñá'Q=Ða˼1èngôyÓÑø^kÖ˜y xc#ç3>ú¸ü·åyãÉÿ6ßA¦ 8@ &’3:|*剷`åu µKÆ3È›æ=à/^a×»àŸÆØðù”'Éñd]‰æÉ™|ÆJ]=Š Ä^T«S+¯û“: ¸Ä@o�7Í?À·×/¶kÝð§0:t.•ráþŒ!�/ž|Æ•£ Y7Iv\N†•×ýI=Ù~cï£Z9˜þè¼ ×׃Œ«¢ÞÕÄ�_�‰—{ËëVØmÐØ£·ò:ƒ¼ižþ;ÀŸÛ5ž¹äãø¹Œ�¼ì “ñ‘³¨”—ìK5�U±IDATà>O²ëO ß,tª ¡ Ê® L’ñÎ7Ð7–•×äMsðW¤¼ÕÁO[êÞ?�‰Ñÿï`=ø©ªÍ�ÿýÒñà™ê¥ Y§¶>>)=£·d¼ý€ÞÊë ò¦9øÀeÀ_š5¦+Àûg2:t.å‰Y;‹õóÉ“ojNÒøƒ'VµE‘‚þ‰LŒ¿Ù<úÆZ\a 7È›Ž<àO¾¼Ð<øFüŸ3:töA&ÙM—NžÉÏ×;ÝÖÉ> ·Ðý~õxàÒB¡ð43…AÞtdÿxàkÀsìÁÝðO?€'õ‰�±ù‘x§Áôµ!¶V¦€þ$*¯µ¬ûÆ:øl¡Px¶™Â o:¼€? ø2p¢~ºâøùŒ Àï…|u~XCíNH�ŸJ­ú±:ú†:‰¤Žþ™f ƒ¼éðþTàràdüÌeG/blø¬ÙM²kù™ÏUÈÛ1üÃÐðÀÊ6ÔfZ |¥P(œi¦0È›-àO'É¢¢~º„8z!£Ck©Vi¯rÝç£9Ð_-’k”ðu8±uó'<ú¡§¤ ·^÷ t ð¥B¡ðb3…AÞtè<øË€Çš5f.g¯atè¥Ôj݇Ü9žOžü-Á.`lO[[ƒüC€þÉ”'.ºÌ3µ‚¤×ý9f ƒ¼iv¿ø*pœYcº|ü†ú/<€Ÿ`Ÿfžé÷ºAþáxôãoEu¥c¦–. ¯0SäM³ø“„è ð ÿl†úÏ'ŠZ×/õûùxnJ ê�ôçR#ª'˜1fjðñB¡pž™Â o:8À¿‚$D¿Ü¬Ñð§3ÔQÔbæØ?ä§ÝëVB÷p56òx&F/4Ðïô …·˜)æ¦B3Áœü+�‹�n³Æ r©÷'Ü76úìë¢(`¼Âú XÒtè~·îë½Ïýнó¦Ëä@ãc�9�æÖÏ"òG3ÈTu* ”J¥O˜9 ò¦‡øW¥€·zžŠ¢zudä†J¥òÃ%@?p°Øì^ï…Ç· =½ÐQr}�é…°‚^W€ÁŒ1S-ÀûÒŠ!“A~Á>Þ\ô˜Eþ À{æ8àçE–úæ6½·Ju§*D> y›-±Ùöè—22ô}cuÿ”öþ0äà/Ö‘$x™¦9FÀëæ<àçƒ'?¢•úׂgl#×ë2ø; r?Äýó! 1ŸT-/etè-ºo¬^àæÑ^YâÝ‘ü›�bgðûü§€Ïòü¥Ž„_‘oG¿ŠžòuâÌq^⛚ôÄZåù»Eë* ¡gŒO¬ K#XTz3BKšò�]á"’JÓÃôèá-´¶_‰ ®7ƒÌôèÿ¥P(ì,•Jß0sä�FÀx�5‹Ì|>>Z*•jóè}ÏMo8¦Ÿ†ïŒ®‰ŸÔÚÆ¢G]¶ÜKËñå¿è[ö‘pèž•¾Îâ˜ëû”ë­I¿€%$ „ºö¹&·ÂsÆ„'M…ô"ôä…¶²í�Y’Ì °�À^Ð/CõÕ´vä ‚kÍ SÕ\ž–×}ËÌa�?ZŸ^ivo¨¸¸T*}ÐL1+ÛŽáð'úþèßý)yô¯Ÿ?ê²/!ÓP‘NˆÙõê�õâº�÷”Ë+{Ë …½Í‚–ÇÀ�ŽQ~Ô§°”¤“`ç>ëx¸ž7!œR ±Ðç¡»Uhí„LGÚ"x) 舰ZY„úWÐÖß·59UíÀ…BáïÍ£7È €Ï“„ _n6߯q©T*ÎÓ÷?·Rï<î—A1óñúêÈéKZ¼~ùy„g橜R �º¢|`]’Rœòþ'? î!’RÁ}?ï€Lêµ/#iœ6 úþ2åû+5 ÉöÍéæ­ Ü�þ¥pÚ ÇÇBWZš…–îtzàQ·¨Õºü{:ºw!î7v§Ïôè¯, ¯+•J_1säç+à[�^†…è©LžŸ¿¼Î¡p½R“[õCþ#ñÒªðþß+�ñ7Ý£Ï!«æÈ9-®GÖmPô!62qú¸3}í+G’kÒLòïN p×å®ã�.M<¹¦}ÖÀp7œ8(œ:*œPVæ¡«Ihn�ü’ùº¨ÕºÜýºz/FÜÍvÇOUð¯é˜Z½A~Þ¾¸x‰Ùz¿ü?[ˆ~Öq»~Tß#]ˆ?ËgÝw–WO}×Yýsîø„ªâ¨ã©R÷°IŠëÑC:ñÀxúÚ Üü|Ú÷äI ßšÀŸcHŽVÀ¦c•M�K7ÍéÏK×ÊýÀMðg#ÂSG…"ae+´µ M�[ºwràÜÚDQ+ƒ»ÿ‘®Þ�ègª‡$Ï@o�Ÿw€ÿ$ð×X©b#�_šÇ!úé`;òÑ„»õ_y‡Lú '|7~Vß»îÿþÏ¢�(±8QTŠ7(EÕ½QøÃð§Fo*$C„¶74øþÉÙ�ÀJ’AB`ÜúDåÖ^MŽ H7CÀ ðk`œ2 <µ.¬Ž„B7´t ¹nÈŽÔF ŠZÜý.ºz?b¡û™Z|¬P(4•J¥KÌùùø�“„è ð35B¢¿ÈL1K}@?Ët'¢¯øn\à]úý+¢"*§p7·àI�.„¢DÉ„9Äïë‘}�؃éÇ¿hðõ¦Ôû/¤®L"€gÀ-«”[ršüžq`€d‚`)ÝôÃ3„g”…Çd„EK ©WÈõBvÙ¡ÚDQ+Ão§­ëJ‚à[¹SÕ‡•×äç‘ÿ2¬¤h€O©Tú÷£ ²GR;ôrÎ×-À?8á§^y7÷«‡ÏI?"ªw÷ìçëŽ$ ¼’ä8 �$Ip)pR¸±S¹Q4O<œnv¿L6g :ž—I�z¡u™�é…L/„éfÀõÈv)IÆ{9m�Y‚ð›öD˜*+¯3ÈÏiÀ·’ S9Ó<øý>˜ßxž»9È÷ëÕœ­¿.~ê=o(R,BôbêŸ2íã˜ä8`pó>Ÿ—ô¹—M�²ˆ½G«ÒhÀ‰À@;\z®¯§Ñ€�éëAàwéÏ„ç–ÏkJŽÞF Vëfth-m]5óègÊÊë òsð_žm€o¨Qàè¼iõA~X¯á•zðºÔ«}Êø:YG!©‘[0Ò‡ù±’ÌE¨‘$ômO�Í>� Ý4‘”N,K£�N'I̪žTàó`úº-� ìªðüªãÌNaIÏäF VËôŽ ¿èØö®{Ÿ$²ÉžÅ3=ú+ …Â…¥Rér3‡A~.þràÅfÓ†!{´†ß?äÇt#oÖïç¥P9'õ6M¯8öPº Ø´u�” N¬")|B!Ȧ¯®ñ\;´ÏF lŠ*|MF[›ÚÛÛÿ5ý·¦½ÚS^|¹T*©™Ä $ß\ ¼;ƒßŸÿê£ü|íð>|&ô—|@¿ÉÎ%9C~U #�£ü$þÈE˜æí�¤¯ÒÏýˆ©G9’°ó¾É�+ÒHÀñÀŸ§›„pll,®V«;{{{ÛEÄziLUÉ(î|¡PøB©TŠÍ$ùà øO¦¼…ègjðþp®vø _Ñßs±^Æí\@’,vþÀï}/ú#³Ø÷ãjºþw‘$òÑິ¤Ðï©×ëËOëêê:WDšÍÄSÔC2’»£P(|¼T*Ef’‡/ÓÁþÓÀÿ5;6ÔƒÀÛFÍ«È×t+—êø¯O½ÈW´¥6o7ƒ$G?þ«R©¼EDþœÆÇ ]�$ý.H}™ ò‡ð—g6l¨íÀ;L÷ªÃ‘x±�«õ_¸†—§üÙ$�d”¹Ö;ßôP Ÿ|ùi×R©ôÛtóv‹]×j>œo 7ÈJÀ·? iUkö›©�ðW,`mv³›oû‹ù/þ.Ãß›ô®¥R©ôà�$Yÿú©j%Gm½Aþ�~°‘¤™†�{ÎÔNàìR©ôŸ Ð;;T€æGúa.å¯H¹ÎI=xÓQ¬R©ôsàméfÎ@?ôïHGx› ò³øc€ïO2ÀÏ”÷¾EÑëK¥Ò·¢÷uhŒÊ8?×�ðIý ’zíW›±ýBýuÀkö¹æ¦½jþø½A~6ð]àÏ ð §:4::ºaçÎ�ÿo�ÚGÁO¬òý(Ñç�d`ŸÍÞ,íÔq¶fç/èšnî,t?Sí$Ÿ ôùƒü€Õø†€ß=22rûøøøW°‡©³üÓ"6éÇx¿>8x3S»² ¶æ7èo&Iƻլ1C@x§�Ñä àŸF2þ³F#¾ë¶ÁÁÁÚøøø(ðË…k‰Y„¼âÙ¢Ÿâ�z ðhàHމ,D¿°Aÿ’hÎ�mì×£·d<ƒüþÙÀg�Ó̃oè¹þ¦Z­¾©R©Ô�ëH:Û-d{ÌÎϹO/áMz,pðÞ}o2Ðÿ†¤ùÑ÷Hª,L{•#ɺ·ò:ƒüÃü3�˰,úýívàÕ›H2½¯Yàvšoׯp�.N×Ýû�ÿ6À›¦�þà Àÿèg¨øgóè òø3�¯�Lž2Í„Ù�€¿)•JíÀzà¦ú 9œ|ðÿïÝz¯UNN%¢75ýV’cœëI†é˜¦‚þbà=–Œg�oø_"Éf6ÍÙw€×¤ÞÄI׿õ$c;ºm¹†ô»¼JÇIÆ—¾¸Ê–›é!@IyÝ· ô3Ô¼x{¡PÈäM“€?‡$Én…Y£¡¾GÒèæþj·?$ıÐÿÈ!?ªyƒ><—$Ôx56dÆôðAÿàújÞ¼;íRj�_à€ða’q�¦™^ê À+K¥Rƒ¯Y8ù‘Ú`BÉ;ô· ð<’)[—îó³Ì®¦‡ ú·‘œÑÛš™ªVàÀ‡Óy#ù øó€�‹ìž˜!O2!ëù o:ÈWôVŠz÷ñ×$}>oÞ˜é @ÿ,tßHMÀ…Àú… ú ùB¡ð–Ôƒ2À7ü À K¥Ò˜™c!_Õ;ùý)àÅÀ×€�™f:HÐoÞ„…î)Î>¸A¿`!ŸþC$=ÁM3¡u ð ðËZÐuîå³ú#~΋HÎßß Ô͈¦Yòèßf}CeI†;]´Ð@¿ !_(ÞF’Þbk¿¡ÿ-’½~6=ùˆí\æ¿Éxp-I—®ÈÌgšeпø_}Cпø·…”Œ·à _(Þ�>\ÛlÍ7üçØü,C>f€¯ú¯ñMþ:üÛ€2¦7Ð_�ÞËú©Ê›zôYƒüÑøO’´ 5À7üÿ`€ŸeÈ{F¹Æ_Ε¼ˆ¤;àÛ�q3›éƒþíì-É4MýùÀG òGà‹é…µýLE$ ;o6ÀÏ2ä•*?ÕËøžOÒWà­À„™Ìt@ÿ ðF’1Ùú™ S¡Pø¸AþèüH: åmmÏP�¤…ê« ð�ñºŸÏGÜ¢—r±>øI+R Ñ›'èûIΡo´u7C!ðæB¡p‘A~þ{ðï&©—4ÍüåÀë,Én–=yųI¿ÄôY$sÀ_›Þd: >IÏ j3“�o+ 6ÈÏOÀ¿x�yð ¥ü…¥R©bæ˜eèoÑ+y§>ƒdJß¹€m¢LGôcÀ Iz_è§*CÒçþ¨ôè�ZÈ …w‘LóÊØnèÁ_œW*•,ûöà5õ¡y¯~�7éÉÀn’3Ñ,Tjš ÿ?$=0l=NUxk¡Pø‚A~þxðïÇBô�T&©0ø`©T²íÙñÛ÷ö›@¿Éz0 ¼ ¸Ï dšc >I/ ýLпêhóè�:ÈïS&gYô3UÞ|Ò?˘÷”Ù¬ÿÁyºœd2ß9Àýÿ{÷cWU`ü;JLPƒDÖ †Äú¢Q”b¼o AiË¥@¥¤4¥EÆ&eZ…B[*ÔP¨…Ò‹´&@ÒÐ*J AQ" nV ,…vÚ9>¬=¡Ó½O™Ë93{ïóý^€À]çt¾þ÷^ko—F% ýËÙ÷s“¡o9Ñ׿}­"ï1¹zX ÜhàÛl'/ðÛæbæ5?NzEì4àïþUÉC‘}ËÐϯËD_›È{Lî€^z�¥¾¦7ïà†æÉ¤{óge�—ª2Ñ{¼.ïà²:œ£¯Eä=&÷Žü"`¥›ìÚ¦±ÏßJz„(¤óÈOùS ½ÇëZ÷qvay•�[ùÈg�_à_hpµ�ïX褷̞4ðª`è=^×ÚÁ¤‡X][Õ—ÚT6ò!„‰Ù%úïf„Û Ì–øŽy x8xÔåPÅCïñºbϺ_SÅ×ÔV2òÙŸ¨—;Ázƒ´?ÁMv�1ðCp=pŠ?U£Ð¯s¢Ï‡~àíu• }å"Ÿ-ðõÀ%x¾Õ߬6ðczã®:…~`3Þm†¾0ôgWV)ô•Š|¶°‹H;˜ |Þ«xLNÒèC?›ôêiCŸýyUšè+ùlA¯"=|¢ßµœ—³ ~¹�—Ô†ÐÏ6“Þs¡·œ…¾›ñ*ù,ðב68ø¼íÀ<Ò%z7ÙIjWè§¿ú\‘\;¿ \WöЗ>òÙn¾…»è‹ìæÆ×Ž?,©�¡ßÌ~éD_8ÑOV–9ô¥Ž|áHàçÀ—¨ùkqGèuà¬ã:—BR‡CÞ£/ ýTàÖ²Þ£/m8C ½ïü˾Ðvàôãí.…¤1ý ÒfœMð'ùÊy85Æx¯K!iŒB?°ï'†>ç Òž±e }é"Ÿ~p¼|¡g€sbŒ[] IãúK³!ÌK÷ùÐOn.SèKÑ,ð?>Ëà—€(y˜cÜìRHç‰~ nÆÛ_8¸«,›ñJù,ð«€Ïø–�¿8Ƹť�T‚ПŠçè[…þxà¾ló¸‘Ï6ÙÝL1ð9Mà¹,ð÷»’Jú¤#dwâ=ú¢ÐO~“õ­{#B8Št4c’�/ üÀt¯‘;ÚßWêdèÏ~�÷è‹BÿàîìJu÷E>ûÎÝÀd_ø¿gÇp94rÏú�$u:ôÇë¼tŸý±Àªñ ý¸E>ûßcà[z ˜c|Ä¥�TòÐlÆ[ ìvEr¡ŸBz2Þ˜‡~\"ŸýB×ÇøÂ þw¤crs9$U(ôßË~¶ú|è?9ý˜G>„ð àà8?÷œ~ÒÕ� cŒ�º’*ú+HÌyÓÉ…þන܌7¦‘!|¸•´Aƒí%m^¹8Æø”Ë!©Â¡¿¸ÞКD:GT­"Bøé•…“üŒ ¿˜c|Öå�TñÐïÈ&ú«�·\‘ÜD?™´ë¾ãý˜D>„p° xŸŸoÎÒ3.ˆ1þÓå�T“ÐïŽ1.®Á]÷­BO§ïÑw<ò!„SHÏ9>Âϵp‚ßÌ3ð’jû^àJ`—«‘ ý$:¼¯£‘!\Hº¸ŸgNøù1Æ»’jú¥†¾0ô=^ױȇ¦ßÞëçxÀ þe—CR„~!éd¯Ë‡¾cÇë:ù,ðË€÷ûùåìÖ‘vÑxIÝú`ƒ¡o9Ñ·ýx]Û#Ÿ~p¤Ÿ[aà7s²Ý§’Ôm¡??k„¡Ï‡¾íÇëÚùl“ÝM¸É®Uàï “3ð’º}¢_ô¹¹Ð·õx]Û"B8X¼ËÏ)§�´q¦�—$ˆ1.®Å·×µ }[Ž×µ%òÙ¿x·ŸOá¿èñ¼$å&ú¥Nô…¡?†6lÆuä³crë�÷ø¹äôgü/I-C¿ ïÑõñºQE>Ûd·Ä ¾å¿Ñ ^’Þ1ô p3^«‰~TÇëFùÂ,à:|ÐM«À¯Çcr’4œ‰ÞãuÅ¡ññºE>„ÐCzñ€�o=Á{LN’†ú�ãu>/ú¯väC½À"à0×½0𓓤ÑMô>·8ôÃ>^7¬È‡—‡¸Þ9““¤ö„~!éj±o¯+ý��× 9ò!„%ÀeÀ¡®sÎn` n²“¤v…¾X¼éjäB °f(¡RäCk€¹¾Ðž,ð ¼$µ5ôKH·‡ßp5rŽV‡NUä³ ~0Ñ5ÍyX\aà%©#¡¿†ô>zCŸ÷1ÒñºGù•Ùoàóv�ààƒn$©óýÍÀ[®Æ àCÀ�CŸVä³ ~¾�/ôð`‰›ì$iLB?¸ïÑ…þhঔ!E>„p-i“�»èóv’Žw,�1ú§JI»Ð÷’vÝû³7úc�[BǵŒ|aba90›¼k¾þG:BxUŒq¯Ë!IcúÅÙDï“ñò¡Ÿ ü,„ðé\äC‡‘^û78ØõÊy�´?áÆ£g7%i|'ú^ÒÞ( öAàÆ�‰~Bø#HÇÀ.ÄKôE^.ÖxI*Eè—�®¬nw5rŽ~B˜tEXtSoftwarewww.inkscape.org›î<™IDATxœí�{œUÕuÇ¿kŸ3Ìðfe0˜ŒFñ6"J}%†D�ŸhD«±ù­ÆViK«cŠkŒŠ1/M°jÕú1†ÄGlP –Ô…$*öšEe•�a`˜™{öYýãœ;sçÎ=ç>æÜý}>çsïÙ¯³÷ï³î:k¯½ö¾¢ªT ˆÇ†W-0:ã“þŸ[Oš]�W�fÇ“m«µ•3@6¹ ¤ø8ð‰ðŸ¯Žë�ã Ž—þ®'�ŽG³½ÅõxîWS¼ÍƒÝÿ8prH0 8ƒ€Ì)€Zßøà¦rÓÄ:VÂ4pû’¾Éõä ÇcùÒSSƒ4¤H0rˆ\ üpX)mˆæ"P2¤7û¾§\‡ãÉrÇã‰ÏìÞTÖ�Åöw�É õèyÀ5À‘¥¶£û©q,ZåH·cÑl $]�ÿ ¥ùÉ\ÔÕY¶�æÀ ’›@f_"øé©—I £'Ëס;FJûß§Ç"}ê¤xÃõXô�K»6|¤¹1(ä&�éÀà¤r´'>x/“0ݨɼ8¢ ëxRÓ£sc¥¶']r”ó]�G�;¿ù—�e—â²’êÕ¯—•ØDð<ð_À&`/°ÏÛD×–“Ù¡]ýñw¥Ù±Òèzåx4¹)ir<Žr=Žr¬Ô†’ÙWØ@‚#ôó®'‹¾>wY¥¸lä&�ZàûfU1ØL@æ`cí'A"2‚€x€&U}-ª±/l¬:Îõ¸Äñ˜ézRëxiu�Wº}ÇãQ×ãÎk¿²¿,R\rÈ‘À�€�X¥øðPÝ‘¯°ˆÔûÃÛ«êÖ|u®XUUãxòY×ã ŽÇIëgOÞp=®›w}Ç€­Š“›@N'�ر·À¿÷$Ñí…>CDFûÂÛɪúf1}¼zYuSHò,×£ÚÉ%Á)pm¦éÆ_Ͻ©c@jb@ä&�ÙÀõ€“§¨O?L¢¯ûM >¤ªoÛÀW«nr=¹Íñ8!Ÿ�ìx²Ïõø«+ï{¡”gA‰ä†/®€K (¾¸=‰þ¾è…‘Z`Ox;IU[JmkÑ#5Žc¹Âõ˜ç¤¤:�>Þëz̹ì{û^*©ß%’{=…Y?'Q[ôC2Jî¿üB.TÕ�ià–{G6¹¡çÖÁá÷vÇcÎ¥wï-ZMn¹øVžb–@Z—Û¡‰;îé8W¸žÌwÿ¼bvíá…¶[¹á ì»À¤˜b¿f—b TæÞÔñœcY ÞîÝzDk›! ÈBÒë�•[ m³PÉ]œ“ÿ60?‰î‰)Sñ¸êö޵K~ÙÕÙ¹ŸZ›ÒM1Âø‚ã~äðó«.{I!íå%7�œ \S¤›€ØÖÇP‘-’eë7Û“—®îÞ5a¤i®†®5Hp(Éüýºóêòª‡XrÈ$à¶Ç2ã…O×]×v$¹ ¤ ˜™™¦)ÜÔLN5Óä½ÍVòÛ»CŽ^# ¶9�áXn7–w{¤Öf]>‹’§×Oˆj8Nrç‘å3ðÛ£×ÛNUó œùŠ0{€;èPÕ ËPŸÊö¶�÷Hûãss�Ôê¡÷g¥ÖøÜÕvNrÃÉÂ9ÙéN»«&ñfë�tØw¨‘%¡¿uÈBUWGyÚ>ó³ö•Ʋ,Ë$˼ÎjžV|®ºQ’;ŸˆånSÇÆ}+˜¤� <'"q6ð�†ñ¹ÕñÙ™aŽáø’ažÉå9ëe'$�iÀŒ˜gÝm÷êìÞ‡i§ìt •ˆ3~¹g·±rK†I–-½ç¶;î�ìz¹$wAÌs6%ÑPÕU½œ`ɼX¤ª^YFS�8å™¶gËó}¤·×r¨2>³²ëô!7\µ=9æÿ˜� ª?ŽQÕÇ<‚ ‡ñy¤�Ô†ª!´$fµNn¨êS>«þ¹1mÿw]—+£�5­ácåYDz½¿Ý ÆÊxc9¯Où¬úgÅ´ÝOjßoøØšÝÖø<ÎØz¥64ÏDéóbë!74¿¢æË/'Ñ’–:†Œåqc¥3‡Ið±¶Æ†{ÊfÔ‹“Ú•ƒÔ×!‡£7îÞãøÁ´Ø±½R›� Ó_> ·Ë#/2¤/¹=�H ‰–{+‰þaÐz:qÄ+»^u,/„fX6Žjklh€^Éý@j‹„ñe½ñ#³§Ãä– cÙCî˜RCôÄa70hñ«CÆçw@½§@ ¹�D‡#=7ЀŽáŠúm­íš¹pL[cC­!~E·ä¤÷ ÖG¤à$S¹ä˜¬÷ ž�É›žV QØVæÎ 7lˆÉ›�Or? 7u-­;é ÊÎF½K´ÎÝ[IA"â,±ˆŒ&X6ãòß9|Ü~G#à› 9�Xr+FߊÈeÀ—Eä‚�ÄæŸr†<Û•âh×Pgd×aÆdnA¨w�úÌÂ^ ‡ÛÝ4tü–„\#Q!�'ªjÉ×Å@D> <ŒÖ‰ÈùªzÀvA†èÞ$°œŒËìUmÀ‘¾R 0.rÍ+U9Ú¶‹ ªüàCÀjùSU]q : ª¿&çÊkkl¸‹+å@m¿54w";ª§ðÊ!_ç:`dÄõb¹:žªº–`14í< ,‘¸ø5D¤ßšÖ ¡-ª ý(Å fUªÚqЭ…€à5a’ < Î9]Dæ zç¢É��¸5)á>ˆ³ ö¯¥qƒˆ<”² øÞˆ§Ø•1dÈPÕ.`6pGFòŸ+Dd\Vñ]*äÞAîV]T†RyG.€Xü �¶{gkE$sç®ðó|̘¶È“M �™‘ #§/å�ªÞ\@°Á‚sq։ȩáýîtQ`‰ˆ:H]‰"׋#·"%7ªú4ðIz§é€ßŠÈÅôJ®>t÷ u#ŠÜ÷†4¹ªú"A¬Zzé$ð�˜ì—ŠÈ…”Qäî4D;&$r™jˆp/ðÀ3a’f³Àýaˆ~YÐÖØ`Èšáf`§!UÏ…ÑÀQåêÈ`CUÛ "áï�(âHÙwËøØz¢WqÞ3Ä϶¦–±#e‡ˆœ)"?‘U"’$˜ÿ猕 ásDäì2u!Î]»Óâ0S�'ËÔ‘ÁÀiÇi <$"Ç©jä @ÄE„n7ëd]¹r�_Ù’«ª·èÚe&W!þ^‡ÀÍšo X!ˆÛø¸Þ$Qx%W®ñ9úÄN3º �4¨êU�Ið+[J¯#;˜/"qäÄ¢­±¡Š0ø#vÖµ´nI[ýôn5mË•Ú� U}YU¿Hð^tW�¤ÿ‹ˆT—øÈ©Do2_½¾…>zWzw b|N(ñ᪺UUçø~o#ð+ý�Ùø(Douʃ8©_›~dI®ã÷Äúcll´yÅBUßSÕ Я_ÞIge`¡ˆœQÂ#N‹Éë•Üðø©�c— eÊŒδžÞˆ)"÷ˆHEûÒPÕ½ªú}‚•„«€æÅ–³©­±a$Dþ¢ßªkiÝ}]Ž+E{ÃÐ3CÒ�ÏŸ‹HµˆÜ$�¹ôŸU4Tµ[U$ØŠz °%Ìàxàº"š»€`J� =ûF2ÉýI--ý6û»øüˆñ$�[ |ôz£†TÕWÕŸ«êG œïφYß‘cóÕ§¼qKL=§¤ô�›D›�Ïÿ˜>/3!õ&G¤¶ÓtØg¥),ú�PÕrN# Tu¥ªžC`R=Ü'’ןr6ÑGÕ¶ÿ™¾éÓ�cå'YÛÞ1†”±0éBÙïTs¾ª~~¸m�RÕ�ª: ø Âð.‰:á/n]–Öôár}É5>+�eGæ ­fïÖÔËŽñSåõ™œîŽ£¢¡ª¯©ê["2Ø*"?Ìt²·56œL´¿Å£w».�Eî†Ñ¾u|ÏÜöî"~M=;E�ÏË=  Å�¯«�-"r}hÅIíòº–Ö·3úécåqcñrí³2V¦ÏZ_õ'eFeâf‚…M�`‘sñ×yu·¯3cê<”�Ð�ÜÕ‡Ú÷Ÿ9¶½§¥yáåkªúíÐNPÕª:—ÀDû…®S3ñßo|Ûú¹6B®­kií(žóÍh,�FÜ€±Œu¬ÜXÞáT&Tõ÷ªzÑ“ c¾}Êw?@�‘\A æªyÜà綸ßq<>×ÿ?ÀM ŽÇWî?§û™œ•‡ÚŽ!X“«êP9J${Yls]KkNUiÓËbciík÷†“ q|n¼zYuÔúѰ@èV¼¨ÈA,Ä,E’ûëc½]Ærk_õ ˜ž#øh0–EAecñ𴮥uUTfìlä©©Þ3ÆgEÖq{=/8ã3óÚ'ª?UjÏ+áîó«bм|;®�¼KçÆr‹±´õ•Ú>þ‡ó‹ëö�Áb¢ù±À×êZZcOåÏKîÒSS;�•ÅŽ�ôžë’ÞÆ—’ÿ¦RÑÖØ0øpL‘{êZZóF·ôñðŒî_Ëô?×Ep,ƒúÿ6 Óbò^þ©�F ލ1–›+›²Ü‘íÃô¥öÁ‰SÙè$PmÙ-êXíy¿ªv�9®Çñậ¼íòÎay image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/history.png0000644000175000017500000001056214757047403022464 0ustar00paynopayno‰PNG  IHDR@@ªiqÞtEXtSoftwareAdobe ImageReadyqÉe<IDATxÚì[ pe¶>Ý3™�È$’‰ò^ˆ êÝ‹ÆeÔÝb�”×Ò$`é^¸Å³¤¼>n�J¹¢¢liYò ÜòÊ^¼–²ü99 Š|áº;agYy4÷}ŽúÝTðo©ýØo[Aƒioìý3çIJJʹ•�;A‘”ƒ•Å>�a©ÓÄžó|Dê£ÔüíAê“ú˜H{ž+UÔ”û7r—]j÷ù&Ð<ö?ž¡ûO¦1Ÿl ˜ßMks½¾¾>˜çÛ¬aÀŸ=zÔÚå+BȸãMD¶²ÆJªó8|¹\ ™,�þ+…b„ÏšJ¦AýIs´�« X\· ³‘Rc']]ôS3‚>;4a [÷.M<}˜îYµ‚BããÚ\ß½{7 >œ/^Ü ¾½ÅÖ!»Ë BRX Ñ�ò?ÏKäØðŒjþŸ]Ô;c†8×ôÙn û—û¨fÕG”¸+ ÉZMн¡Í3£¦O£Ñßl£¤¢C4à©ÙBè‚y¸  @xÏž=´aÆ  0ÄøÜÜܬ.A¦¿¡ çj/’KõRHHˆ5ÍŒR…†ž·LE–ûÆã(Wѹmþ?jÌ9LÍy…"�qï—žJÌ¥�øØN-Á:t¨õxÅŠ4iÒ$9rdPøgæäää'''¯¹m¼J’ Pyië,Œ@’, ƒö-;ö‘åþqT»äOþØÃdCs– ¯;ó~ °q£(~Ó;ô‹³iÈêådIˆkÀ� òüóÏ·êA ü?#ÞÛ»woæm€½oÑÁû¿—浆Aßµ¯RXz ¹ÿ^@Ž¿|A�h^3)�jg-¤†ø�ÑËPâù48ëm øþ¶ !hhfÍš%öÁè{Ý2ÙÁƒb?mÚ4Zâk€è³Ï>#x÷:ï3aÇŽ™·l¶û€S›qúX.yóÏ�÷4zõ¼"²ŒIý²Þ$[Ý1`!…Ø‚Ó|çÎ�b<ûì³Áb·ÃI²xàqüâ‹/Ò¥K—ÚYŸ~úiæ-€þÌ€CuàÆ¾šÉAn ËL¡˜ì-4ðÄvŠÈœyCª8p • ÏÁ4 ЫC† iýüöÛoSß¾hŠhÁ‚ïÒOø€víÚÕ® ..®Lll,½üòË⸨¨ˆ^yå:sæ ­_¿þ:àA„1 Û{7]„’ôg ç�»+++;%j¼-]ºTìu»8~î¹çÈn· �ÀÏ………´lÙ2zá…ÚœòÉ'iß¾}íVˆÆXüÑGeÃø¶›(„hs¯ïG F¶_þ’¾þúëŽòqë1S•cŸ·wÞy‡¶mÛF‘‘‘"¥1…ƒQרÊËË)--�üq!€¼M™2¥µ`566¶›‚Œd°áÄêÕ«wÊiÈè½ÙÏÆ¨9‚Ìf³ðÞ±cÇnÈöºÕj¥ôôtš>}ºøÌñÌÛ÷ßOo¼ñÆuN�:%Ž/^¼H‡±ŸššJû÷ï§÷ß_¤Ã>}úð¯½öZ‡u§ÓIW¯^¥ÒÒR*..æJ˜;w®µSÝà^2�ÇÙFg{ú¿^¢þcLjNìÊ•+4oÞ< Êcÿ=ô�LŠøøã�[ 1f̘Öί-óŒ3Kžyæš9s&õîÝ»MÈâ·fÍêß¿?½þúë4tèPѺÝnòx<tEE…U>ƵR|ïUŒí~ø¡ý¦V„rÉœ�+ÉÚ°¡tåO+©¬¬Œî½÷^:qâ„xqJJJ‡"J‚A>ø Èøøxúî»ï„W�¶—ϳð€[cœQF�%€£¶¶–ª««©©©ÉÆ!!_8pB‰ /j§·Óí°O i Ó_ûío(::ZL‚éׯ_?‘“¹qél…g„u`ëÖ­¾ettþüùmŒÈ)0Шþà,k{»¥¥Ex›C’+Ff&¼~ƈCÊüÀïã΃KÒ�x–µ30ƒ«�&’·ÈCT{1Ñ'  4ec0kòòò„åov;v,½ùæ›â¥+­]»¶C~æwž;wN¼¿¤¤„éï¶X,ç#""¾DÈCxDa~.ŒzQÂ\ÛÂÛëCõ5¶ úñµ¿×ß“ø·PU™�cQcAa„…… opîž:uª¯[ìDug\g ùâ‹/­,½õÖ[",˜ÖÁîgOg¸\.ƒ�²,ÿq.XCÆ`l“1Né�Ãpa´è#¨xVÜÀ—>|,Óa\XSWs ½¢b ^TTú!YL&<<\LŒëÈ‘#4yòäNׯÆbÈõ?cáÂ…¢Þg�`€\ùñ{8äXàü Çñ¬BÌåSÜà!l|ߌï�Å9®ÖœcŠòhjw=32žø@ëpÌ€ˆÇÃú!/ÅK'q°²2p6Oˆ™ÀÂUSS#¨(€½zõ"“É$ ¢Ãá —^zI¬qºËÎÎn½æ7œ8W‚w• î/`_Á^önÂ=f¤;ænÁ=^œãu£7³ ÂF´Xc²Z›YŸôÁ[!Êü€ÝÂ0Fòä8Ýã\8OúøñãB�9=uÔ±éßk]í½ûî»E8è׊Y±q\ŽqÇ—àýZ ÀÙÃ&Wuš›`À€–|Ž_¦êØnøWä@éñÏñr^ÅòcêàÁ�(Dò&L˜0Ö�dob¨:0âÃZ�û L< 9&&Ɔk½õ{x“õ0“ô”Tª6áÚUì¯ê÷ðýìQfšŒPàc­axŒ`Œ“a|�ŽÅ¥ïù™M(}‹oÊ »ïðòX{� Ñú„œœCQ™9Au,ÞÈÔ«BÌÓé…ÖâǙƪ oC¸H~úbÒ½#éÇÁÊrKxž`{›³æðÆ7±·™êx—EŽÛX»áûîºë®Þ`Eþ-¯ âEÜp_Ò�÷Ñ. •vbb&‹f0Ô‹ØvrœãÅ|ÜŒ0p£Fðà^• LìÚŸPô˜ÀÎ0ƒWš››%|O“ØÃŒZìø{¸f‚Ç% 6/D/h„@‹LÈJf¤À^S'Œ”¯¿£7îk¾å¿ é¬ ]AŶ|ùòfL.�U™±p­Îâ£h†Rë4ž4<ª 4ˆSÒAk:h‰ÅŠAëM�¦Ç·ð6Ó`4xÛF(:X¦» ÌÓðÞPäûPìY�Ì0œ†Ò×­jFMqFŸ.×2ûnÙA¿d6_Æ$qìcògÎ ð€Ø³“ŒÁéŒ3לBY/˜Þ`Š žÆÒ½ÊÇ&®îZå±F†we„XŽ-Ø™Á6 $jg-h@èb£áT æÆá‘ÄzÞ-¿Xµj—…1\”´Ê¥-º7‰{ö¦h4|Š,Å &Ρ˜ÙsÆu<~7Ƴ ¤LFˆ°(ê{qרiÌ//Âà]z˜šYÑ2Ÿš={6k‹øœ+éò_ˆ ö¯‚Vx^ 4N{Lqö>ŸÓY`€ƒ™EË Š¶èÞ–`83{“ †kaœæø‡!Âbª*ëße‡àšlÑ`  ½zî7ëºÂ5Mœ8±]g4g?‡MÜSÞm¿y÷Ýw9UZ¸™áå+¦6¡&&&J!Ig�QšÊš«UUU2WyeD€É0˜®ìQÿ¬!®£uŽA³Åìð^è&]xÿUhWyU¼l�ïUuûo„PWƒw±úsmúk¼ŠÃ`«šžÆ4Ý £êíªæ— U#âðÙ¸‡=o.,,¼‚QŠÇU¬[·®êv0Ü–M0€ �Œ¼¯qúBï­ 4xð`´ÀAgVrYÂHm~5�æW )Æã bêÇÆ=\0Õ®_¿¾±GüHjÓ¦MV¡7zq —´ÚÉ“')))IC�.sׯsìšt:“¡m~Bq�ê’ÿuý˜¯qK[¿aÃOWýª­K~&‡”؈9†ÃãÊåË—¥aÆñÊŽÊE ë×~žõ/…ÉÏÃ’ß9ÃãŠ^á5t#uÓÖ%?”ܺuk$¯E §—Ð+p#$±Zûí·bÅÆïù’^ì�`Y¿f†E’û„¦�7z¨·.û¡$´ÀÁiéG‚j¼œú ¥÷óº¿èi~^Wôò˜ÛWÎçÿ‡ýûJ— --ͳ}ûv/Ò‘ŒNPå á ë±ë/t†š›ü>³²»²²²\ôl]öSY€vBC‘þDêC#¤xÛèÓEû¬72 \¥Ÿpë2 ˜Â&Ôú¼|åïuò3÷x�ø/­.ýµøž={D�~äȉ×<¯nÙ²E¡´uÇÿ 0@Á¿Ï €÷ÜÿÎìêÿ„‚›ÒÓÓMô3Ø®ûÓØ�¸Ýñÿ:ûOüÓwøöÿ «ý±èÙ%KÉIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/hourglass.npy0000644000175000017500000004012014757047403023005 0ustar00paynopayno“NUMPYF{'descr': '|u1', 'fortran_order': False, 'shape': (128, 128), } )ÒÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÐ'»ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¶ÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØÄÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿<ìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿë9#$$$$$$Àÿÿÿÿÿÿÿÿƒ$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$†ÿÿÿÿÿÿÿÿ½$$$$$$#°ÿÿÿÿÿÿÿÿuvÿÿÿÿÿÿÿÿ®©ÿÿÿÿÿÿÿÿ{}ÿÿÿÿÿÿÿÿª£ÿÿÿÿÿÿÿÿƒˆÿÿÿÿÿÿÿÿ œÿÿÿÿÿÿÿÿ’—ÿÿÿÿÿÿÿÿ–‹ÿÿÿÿÿÿÿÿ¦¨ÿÿÿÿÿÿÿÿ‡wÿÿÿÿÿÿÿÿº¾ÿÿÿÿÿÿÿÿvbÿÿÿÿÿÿÿÿÒ×ÿÿÿÿÿÿÿÿaNÿÿÿÿÿÿÿÿóöÿÿÿÿÿÿÿÿJ4ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ0ÿÿÿÿÿÿÿÿÿ8>ÿÿÿÿÿÿÿÿÿïÿÿÿÿÿÿÿÿciÿÿÿÿÿÿÿÿðËÿÿÿÿÿÿÿÿ•–ÿÿÿÿÿÿÿÿȦÿÿÿÿÿÿÿÿÆÈÿÿÿÿÿÿÿÿ uÿÿÿÿÿÿÿÿöøÿÿÿÿÿÿÿÿrCÿÿÿÿÿÿÿÿÿ:;ÿÿÿÿÿÿÿÿÿCÿÿÿÿÿÿÿÿÿz{ÿÿÿÿÿÿÿÿÿÜÿÿÿÿÿÿÿÿ»Àÿÿÿÿÿÿÿÿ×�ÿÿÿÿÿÿÿÿùûÿÿÿÿÿÿÿÿ™YÿÿÿÿÿÿÿÿÿVVÿÿÿÿÿÿÿÿÿZÿÿÿÿÿÿÿÿÿ¦©ÿÿÿÿÿÿÿÿþÒÿÿÿÿÿÿÿÿó õÿÿÿÿÿÿÿÿÌ�ÿÿÿÿÿÿÿÿÿ^^ÿÿÿÿÿÿÿÿÿ},ÿÿÿÿÿÿÿÿÿ¿Àÿÿÿÿÿÿÿÿÿ,Öÿÿÿÿÿÿÿÿÿ%'ÿÿÿÿÿÿÿÿÿÔ€ÿÿÿÿÿÿÿÿÿ”“ÿÿÿÿÿÿÿÿÿzýÿÿÿÿÿÿÿÿõôÿÿÿÿÿÿÿÿý³ÿÿÿÿÿÿÿÿÿ¦pppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp¦ÿÿÿÿÿÿÿÿÿ´JÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿGÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ×bÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿaàÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿágÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿeÞÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÚXÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿRÅÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿3þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿü.•ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ�åÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿá LÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿFœÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ• ÛÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÖ 1øÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ÷,cÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ]–ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‘ºÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ·ÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿË ÙÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÕÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔÊÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÆ ¯ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿª �ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿþ{IëÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿéEµÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ²¶ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ´LìÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿêH…ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ²ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ® Ìÿÿÿÿÿÿÿÿÿÿÿÿÿÿý±����������������³þÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉÛÿÿÿÿÿÿÿÿÿÿÿÿÿûš"%žüÿÿÿÿÿÿÿÿÿÿÿÿÿ×ßÿÿÿÿÿÿÿÿÿÿÿÿÿ´')·ÿÿÿÿÿÿÿÿÿÿÿÿÿÜÝÿÿÿÿÿÿÿÿÿÿÿÿèRVêÿÿÿÿÿÿÿÿÿÿÿÿÙÓÿÿÿÿÿÿÿÿÿÿÿÿ³¶ÿÿÿÿÿÿÿÿÿÿÿÿϾÿÿÿÿÿÿÿÿÿÿÿþw{þÿÿÿÿÿÿÿÿÿÿÿº›ÿÿÿÿÿÿÿÿÿÿÿôLOöÿÿÿÿÿÿÿÿÿÿÿ–hÿÿÿÿÿÿÿÿÿÿÿë47íÿÿÿÿÿÿÿÿÿÿÿc5úÿÿÿÿÿÿÿÿÿÿæ(,éÿÿÿÿÿÿÿÿÿÿø0Þÿÿÿÿÿÿÿÿÿÿé'+ëÿÿÿÿÿÿÿÿÿÿÙ  ÿÿÿÿÿÿÿÿÿÿñ/2òÿÿÿÿÿÿÿÿÿÿ™Oÿÿÿÿÿÿÿÿÿÿù?DûÿÿÿÿÿÿÿÿÿÿIçÿÿÿÿÿÿÿÿÿÿ^dÿÿÿÿÿÿÿÿÿÿã˜ÿÿÿÿÿÿÿÿÿÿ�—ÿÿÿÿÿÿÿÿÿÿ‘6þÿÿÿÿÿÿÿÿÿÈÍÿÿÿÿÿÿÿÿÿý1Éÿÿÿÿÿÿÿÿÿò!&õÿÿÿÿÿÿÿÿÿÃ[ÿÿÿÿÿÿÿÿÿÿciÿÿÿÿÿÿÿÿÿÿUàÿÿÿÿÿÿÿÿÿ»ÀÿÿÿÿÿÿÿÿÿÜmÿÿÿÿÿÿÿÿÿù%(úÿÿÿÿÿÿÿÿÿg çÿÿÿÿÿÿÿÿÿ„Šÿÿÿÿÿÿÿÿÿãjÿÿÿÿÿÿÿÿÿè ëÿÿÿÿÿÿÿÿÿcÞÿÿÿÿÿÿÿÿÿjpÿÿÿÿÿÿÿÿÿÙQÿÿÿÿÿÿÿÿÿâæÿÿÿÿÿÿÿÿÿI½ÿÿÿÿÿÿÿÿÿlqÿÿÿÿÿÿÿÿÿµ#ÿÿÿÿÿÿÿÿÿë îÿÿÿÿÿÿÿÿýƒÿÿÿÿÿÿÿÿÿƒ‡ÿÿÿÿÿÿÿÿÿ|ÝÿÿÿÿÿÿÿÿüýÿÿÿÿÿÿÿÿÖ6ÿÿÿÿÿÿÿÿÿ²³ÿÿÿÿÿÿÿÿÿ.‡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÔÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÍÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿbÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ\¡ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ›ÞÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿKÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿDzÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿs¨ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¡ÐÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÉöÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿðÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ6ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ1QÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿJiÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿb~ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿvŽÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ‡�ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ–§ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ ±ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿªµÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ® (((((((Ãÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ¿((((((( ?ïÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿî:ÆÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÀÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿØÜÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿغÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ´'ÏÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿÌ$././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/icat_gallery_opts.png0000644000175000017500000001006414757047403024464 0ustar00paynopayno‰PNG  IHDR0.±,ÑxsBITÛáOà pHYsÃÃÇo¨dtEXtSoftwarewww.inkscape.org›î<²IDATh�íš[h\×ÕÇûœ37i$YwË–Ëò…hP¢7¥©Ç!M\HûRF%Om¡ê—ô¡PR :󨩡¥¸¦1µ ôB™¡7úá’ qZ#K6n«‰íØr|�Ðý>·3g+»3N}¿äKà[ £3gÎÙg¯ÿ^ë¿.{­µ–c*¥5¤R‰D"!×@ëx\>¥R w˜ûÍçÁÁÁA9º®ë‚AžÛµkx8�ÇS)ÐZî•1R)¹ cöõ ïÚ5<<<,31ßTÿ¯¼\·úZµ6F,ª$›UÊu‰D"�N&]W)H§wïN§!‘èïwÝlVîtÝdR)­³Y¥`rrÿ~˜œŒÇ×½víµ×އ+W"‘L¦··¥¥¿?•Êf�uÝ;”úûˆt6nܳç¹çÆÆöìI¥ ‘”2@€<—Lš³j©€õ DÉZÆã}TZhª'00ຣ£±XEµžžDÂu[[wï6 íß?9�g2{÷»ï¾õh]_ Ž/¿ü�ïÀüü»ïÂÂÂÓO'® ét"Ñß±X*££³³P_oÛð GŽÄb±X2ÙÚ:11::8¸c‡g`@,u` JUêÁÀ¤Ä=âñ£GEeP*‘­•ÒZ,gdä?H§Ÿzª¯\W®C29:šH¸îäd,æºçÎ9òüóW®ôönصµÁ ;ööÛ`YÍÍ nعœã€ç�9>ú¨ãÀÖ­mmpêÔмÿþ•+`Û��ÐÔ´v-lß~íôôìߟJA:�Íö÷»îÀ€,¡,—À”LÊÂ>8€œx|Ç­EqˆÅ„kÌZ¸n:‹A,‹A_ßÀ€ëþõ¯çÎÁÐÐöíÐÑ1< ¶´€RÓÓpâÄ .@<ÞÛ CC‹‹�Ë•J;(åû µçÁ{ï àyËË09Y,B¡‰@8ÜÕ/ž?,-Á®]»woÜøâ‹ét6+ Æn†Tq�ëŠØR©ž×}ñÅÇáÀ�‘øñ�Ïœ�¿üej nj‚••\|¿±,KVoeΞ�œ„\îòe°m¥ li�@ ½l»£<϶áÂ…éièèØ´ "‘P`fCmm(±Øš5ðÊ+ëÖA©tàìÙóæ›®›N§Óˆ\wÍš5k`rrrÊåR 𛡵ubBk”RêFn(�üÖYÐÚšÉ$“2@*•LÊêô÷»n<žÉ þæ7_ùJg'ƒ«VÁÜœÖ`Yï¿�?^_¶=7J•Ë`Ûá0XV{;8κu mÚJuuÁü|±~ÀæÍ¶ /NOC$Òѵµ½½ Ô† ðïÏÎÂ�~ôÁ##²|Êè(ŒŽZ–eÁøøø8xžç�ïLNÊßXÇM€»îž×^“dNÖ¥¿ßD/Èd28{¶®~ÿûµkazzjʰLss}=LOÛ6hmÛ46‚Ö ¾�€Ö2 Ë(•`~þÂhmÍç¡PhnË …À÷›šÀ÷- ŠÅ‰ Ðz|ž}¶¹~úÓƒ«#–eI¡T%m¼—Èuk;²úúÄp“Iù°âñxׯ‡ÉÉK—À¶ÛÚ ê¹hl»© B¡¶6P*�u°mð<¥ÌºÊQ)Û†ÚZ¡ö•°ír|_k�L6jißW Nžœ™`*œ#ñ#5,Û–ñe9\\³Þx#™tÝl6�®¤]ÂA_ÿúÿüœ:µ°¥ÒÜø¾çA¹œË�mG"ƒ Æ."\#V(ª–Ëò*ßß B!(ZZ ZZ‚bqv´®€)**eY`ÛgÎ@[ÛÆ�²t–TD`1Ö¯¢ªD®8&<==££pèÐçÏ_ºµµ== åràyÓÓPW·~= ¾Å¢ã§˜Ų”±+™¸$‡“ïË]ÝÝàûccW¯„Ãæ[­Þyç»ßUÊ÷gf¾ñ °¬—^ªØL¹,–T.Wœ­zyî”›]·R)×íéqÝíÛ!“X¶´ä8àûŽ‘ˆÖ°}{W<óLk+X–@àyÛþ8ã8Žmƒm‹ËX”ËŸ\)!XXèìÌåÂahk[µ ´¾z …'À÷Ïœ�¹¹W_…|~nN)Ï«”¬J•ËJÙ¶¸ ±=c�²s²Y×Íf¯]«««ºèƒà8«WC]](CC¾_(„˜§âÆà20v$ö"Î"à‹++°~}{û•+½½ããàûù2R*�> ŽÓÙi’ÀhtyÙðQ>/±líZ(B!Ã;Á Öà8Ès9s  *5W0ØÐ�€mC±X(Àââ… ðøã­­RŸþtü8ÌΞ< Åâå˰´44Åâ¥KP*‹•>�ÄCãx7PøŽaú¨”J™á’I©j’I8ztd¤·÷ƒÀ¶%3°¬hòùBšš„�ææÀóÀ² ð}¡óåe(¥F›š‚Hdnjk‹EÃG’7ACض]_/JÇ”ŠÏób1hlüæ7¡¾þ«_…htçN)VLܲmËJ$ ¿ÿnmäfÐȹ%�3™”F×ð°ÔÈðôÓû4444€ï‹kxž¤z ƒðÅ/ÊÔ•‚ÚÚÅE¶Ãá…ˆF§§aãÆÕ«á™g6m‚ååb,kõj(—kj*®'aÚó ¯ÕÔD"Æ:B!aÈ|l»¥§©I)¥Ä^AM§7o~ë-³Ð—;·�ê`o¥ÓR˜Júµ¸˜É˜Û‚Á矇X¬­ ÂábJ¥lÖÔå¡�ãÀÛoŸ= óóW¯B.73SQU)ؼ9�mÛêëahhv,«© ´‡Í=B¼B©ÅâÔÔ×K˜on†|þÒ%𼋠‘ 33°²òÏj ù¼!q¬sçfg÷ísÝ––{ƒæ`Us�i7IGèõ×ÇÆàìÙáaèêzâ ¨¯/`ýúG�7ßú(,--.B,ÖÝ çÏ‹5yž¡X­kkM=%ðضã@©�ÂøxM ,,> & ܶ ” ‡¡\ž›ƒ`pe{lçNèìlj‚#G2¨©™›ƒk×þüg�xU*]¼ž7?¯”Rå²IOM½Wá�“ Y¦múÐJ�ŽŽŽ¶¶B PW¥R8 ÓÓZÃþpü8<ùäÒƒ’”-.B¹ìûÆM”ªö<(<} …lÀ£´-+›'Rzh ßûÞ… ‹;]]G�Bg§lòh ¯¼rå ôô¼þ:tuíÙ6:›7ÂÖ­'OBOÏ¿þ}}?ÿ¹)SŲ,+¢uÇ�D"‘�&¾ëîÚµk@8Tž²,¨©©©‘²( “Uxïî‹Õ[oûTµ $ž¥ÓZKã,�N¥`dä¹çfgãñ�;»»3™x\k…¤­!Õ–�âªU¦.¯­í섺ºµkavvl r¹±1(—§§•’rW–Á²L")O:Žï‡BRÌh-qSÞS)d¢Ñh–———+åïÇ­æÎ9èÚfZÇッ•Ý€Êöa"©”lïUÚœ55&¥—ÜY­ØH8ÜÚ ííßútw:ÝÝ¿ûtvîÝ ��_þ2ضô\±³ò¶]ݸUô1QPê}yNæcY7{æv0ý·üg7Òu+Ûnf×Ó4î͹ÖPWuuF™Šé›µ±ñÙgaãÆ_ý z{ÿþwèéyçØ´éðahoùe¥§¦F*9˲,¥Œb2¦e�8]EÕ¹�Ü#Ðȹã„B×+|oÐ|”I›Û*,¤”!îDB)‰mýýBž°°‹‹Z;ŽmK«AÔ0õV©´°` s>3¥Ò… àyçΙ SçWjtËRÊ÷«ó#È�”,•J%­%4H:kÛ�üö·¿þõ� ¸(·†ï�³sZÙ-¸Þ¿ÍÞ–Ö²ö¢–ŒâûÒr�F{{!ýÂä È円 Ÿï=¥ŠÅ¥%S�›Z½¦M7Ç@e>k­”ãZ‹Åâ­»y-v¢µ”†Ø*gÆÕÌ'Ùq5�ºnõ*71ë/Æ^[ މ(¥T `YÒKtœPHŠ•j¶‘(gX¤âRæË‚p8~�?M¸½ í�Èl %WÒ­övho¯©‘ª;4•X%…7Ž&jå*´ÛÞþØc²g›HÀk¯íÚ%É‚ùGsss³é†S*UÑõ,$ð Ìá°¤ªö7è¿:R þ‰ÄõYF5¬üÿ¸2 )@µ¹K”¬Î¼´N¥$qh ñßLÌ<®·²‡�úN7™È½—yŒ[�ÿõ®;—{È–< õî_>EÝ¿= ¹ @÷¿ªŸNµï\nÃA·yøž”¯~ãý�ð°Åùd^S-Ÿ-›ºGúl)y?r×} ù$çð)Šbw+Ÿ LŸa€>ª¾k€î|Z÷¦À�<õIF±{´ ›M±ºŠ¹Ÿ1o=þÝŽ|?r_yÐ]¼æøâÿK�Ϥü/߀±©šÛIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/icat_gallery_opts.svg0000644000175000017500000006257114757047403024511 0ustar00paynopayno ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/imageNotFound.npy0000644000175000017500000040012014757047403023535 0ustar00paynopayno“NUMPYF{'descr': 'tEXtSoftwarewww.inkscape.org›î< åIDATxœí�k�UÇgÙ²„�D"`ˆÉ"oy �" Ta¥@ 0€Jii ”_,¿X¥_|¡”Z IiÉKD$�$I„ÈÁìBp³9~8w6½·oïtÏtÏô¬ó«êšÝžžé;óŸû:÷ÜsDUiD¤ èæS�½�®È£ÃÞñ.°p�ýÀà5Unì'ÈŽ”U™Ž‰q°{œ•ãÛ¯}îèUÕí9¾.”F™ÅnA¦5ðö;�ç€åÀZ-É—ÒtqDäààD £©…1ú�ÀJUhfAš&Žˆ‚‰rDÆ—¯ï`}Ê {öˆ°¾i0ØÇ�O‹k0¡žkFÕPqDD€ã0QJù²!`Ð ôëTõ¿5Þ{ð1`Ö|HºÚ:¬PÕYï]+ GD&ó�O3«\þ>ÖI÷¸ãÕ¢~µ"28 8«ÁÕ„nWÕç‹(�OáâˆÈG�ETm­–«UuW¡… "û`? ùÀŒ*—?Ü©ªïZ¦"Å‘À…@ç—½,UÕ— +H\ów(pp4ÉeßÜ¥ª+ +K⸠ãåÀ‘ — Oc¢lʽ9!"S€S€s�É —­nUÕ·r¿ÞâˆÈaÀ•ØÌÝgx x¸ÙÃÔ,ˆÈTààØ„K†€û€‡òl’sGDö>œ�™R|67«êë¹Ü° ˆÈ±˜HS.yûŒ;s¹_âˆÈLà*’‡Ç�w«êPÝ7K.ÞØPyK‘3|™Œõ£§%\²øUŸµnqDdpá_Ó»Àï‹zŠÈÀ—1ƒèØPü9àתúv�÷=¸ŒðÔàeà—õΉêǵÅ7z®–¨ê¶šoPýþçcÃôÐüdø¾ª®+ðþ€‹ ×¢õÀÏë1¨Ö,Žˆì\ìï=5ŒuŽܼÌ~ÊØ&™õÀ·‹ž7‰È…˜ÕÃg#p£ªÖò¾5ÝÌúą٠ܤªÿh€ewÕmes€—U½ûAú\ç&¸™É,Ž«Ê×b<Ê.l¤òR-ÉXÁÌ.iÈjX­ U½øSà©YÀõnI$™Ä‘àjà¿lXÇÿlÖÔÈ,`Ï”×Î.² QTõaàVìûˆ2¸Ú}©I}±ûµ^|"ðôUõ‰,7®“,óˆ\æiQÕÇ�%XKe.p^–÷Ê¢äà“�ó÷ªê#YnšÿÁ†ÌiØPdAB¨êSÀoˆ× óDd^Ú÷I%Žˆì \xj™ªþ=íÍò 6Ò6¡�jjGášø¼ÓÀ•"ò¡4ï‘¶æ|˜è�[¡ªw§|},ª-º­QÕ�(L^ñÎͦyqUqDäxâÖå·€;ÒÜ (Tu ð àƒ„K675®DqÜüj1à[ N‘P1Š1Åqv¤‹OÝV¤�,-®ó½xxkã7bsŽëUus‹€[J¸3ðÔB×]$2¦…@D.N÷N¯RÕ[2—²ˆÈDUMªIMED®NðN÷?Nš°'Öé&n3ÚNx¢U Ê*Œã6Ìí*J7æ«$(ŽˆtbW]æÏE¯›�Wœt ñáuÈ&$ל3‰;dôa‘mjDU{€UÞén™º>IœOyÿcëä¥pSmq œ Öž˜8"r0ñ¤GË0ò¨êàßÞé£Ed?ÿÚPÍ95pîŸy¬Í˼ÿs¸Å(qœYá8ïš^U}3ß²ýßó"à·D'‹È(�%¿æœ@ÜßLóǸÄõÝ~ß3ˆ�à‹ã7i;0×Ó6ùóàûWœá¼ˆ€ˆ8"òÌ?ÊÓµxô·©Žómó—Z&cÇ€Ñ5g~à=ÚMZ±Ú®R‹ ªý˜cÄœ÷¦ÛéðYlG[hÿi”–˜¯9]Äw=—þ—¦ªCªz鬭b¸õ7XíÝA|ŽÐ*Ì¡}¼à‹Ó§ôü"´J“•߃¶³ƒ¸i£•Ä)l3pðuØÕ®9åÁØÅi%ß´ñ\s´ƒøö„½T˜<OâÄZ°,ÊFÑ­Ì´R\ ßLµ£ƒønJƒ Óf4þÊÀ»­^sƾ¥¦?Ts’ÂUµ)– 8~ü³©Õ¶ÃµÉ·½Óïsú;H^ÃnÓ8b; pâl">œNÈ M.„¾ïMΩÚ_–nלÆâ‹Ó¯ªÛ*³Ò>ïÉý];ئ1øâôÁn“�ßïqw©6àÂpúkjë`·8¯0†Cu›Bñ7«A´æ¸m~t¥¶8�ÁßÝ1¼£-¡~¿3§Ýï‹s˜ôC ³²¡M¾8|?NO4'ˆ8®ßñ·´ïM8:a›ú9ž@ »è?þêÛ#ÄcbÆöÇ·É…ÐæèÕÑ£ÄqA‡žô^´¿ Iß&'\´â¹ÊßÚT´Œ¸ÁÙ9–­�oÀÛGUßÀ²AE9Ô¥÷jS'.Ì¿øi³ª®÷¯MÚŽçÇf�ví©ôû2âßûc¡ëƒâ¸üi¯z§OtY¥ÚÔΙÄ÷­nÀâÄk#k(²Ñ.ûG+QmBCp¹ üØÜ»€?$e)Kœgˆ[ ¦_ª¹„ù“ƼTÔBâóšG\üµ ‰â8ûÎbâaé�‘PL¶f�¦7½¦»\o~ˆàÞ±^7æþ|·qé¶ÀS¹p.qa^~¢ªióË�~ï:ÓOÆ’¹†".Ç>x]I�Dä&,jQ\[k*·ca_ç7�Õš]êŒàçÝH8êÑiÀ÷\‚íšp“¸×úú”„òjWÅ¥Kû.aaú�ŸÕ# ä�ÕFú�¯‘œõv9pO-ѨDä‡î}waÞAþñ>uävZ˜9&{�•£b­¾ëE„“…ƒ-µüVUëŽ.’‹80’é+$gRÚÜ¡ª«žOzß)Àp­ívÂ{ f‚š¤ª©cý¸ÕàE„G‰Š-³üUUsÙHœ›80Ò9.ÀÖ-’Ò¯ÆDj™mêÎÙülÌc&äÇ· X¢ªks½oùŠÜ‡¹”äfn;°XYæ4cn½ÿ3X(ä¤þùyàw.€w¾÷/2™”žäYú.ìÃ-^,Kf+9e¬ÁÌp—ª¦6Çd.GÑ߇ˆta¹F}×SŸÌ=hE–~ /\“|–¢«ÚÐ}pKÑÙ¸ gäF"Gai”ý`>Šùm¯^**ì°ÀÌÆ¶ºtcCâjv¸ÍXs¼*¯N,&Œ¬ žƒu¬iâ(ö…ôbf�õÀÖZ¾wï¹X"‡yØÄyBÊ—÷Òষ¡âŒÜÔš�#±¹Â‘d› WL0ýØà 'ztbNø]‘c&Ù image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/input.png0000644000175000017500000000177614757047403022131 0ustar00paynopayno‰PNG  IHDRGR«É7sBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î<{IDATxœí›A¨e†Ÿ×]²…+�.Â]ä¦RI±!µ(-�p®T· µrÓJ„\EHAèB)t¡q«]›¬6BA`a‘�^ïëbîè9ãí×{ÎÌ|s†ÿÙœ³™ï{çaæÿÿ3çÙ¦M$=ìmµé˜,‹Ðe�½ÿŽöÿ?VïA¬œÛ¶¯ö_Iw�äÛ*A–“ ËI�å$Èrd9 ²œYN‚,'A–“ ËI�å$Èrd9 BåHÚ é…È )¢¯œ§€ó’^ α(Ñræ€àŒ¤w‚³ÜG´œù…ÏpRÒ�È0Uº"§äCIÇ$)$M….É)…ì>•ôh@žº$g˜7�³’–·¦JWå¼\”´²­0Uº,à9à[IkÚS¥ëržf%½Øt˜*Ó G‹Å ’v6œg„i�EÎÇ€S’5˜ç¾¦‘<¬¸—õ¨¤OÚ˜ê§IÜ[ í¾’´¢æ<# öË´É`ð8ðìu6ßIÚjûçZ’UÐîî¥z1pØiû|%­Büm5)–ç$í©»ø´Ë�â–Ç%}$©¶sêƒ(ÎÃÀ~àsI3uí åL¶�â7ÙÓ“쓜aÖßKZ;I‘¾ÊX \’´mÜ}–#à à I»Æ)Ðg9%�3ãØW9åÂö$ðªí?Ç)ÒG9åïµÃ¶ßµ}sÜB‘›´›ÀÀ-`·íÏ&-Ö79×€7lÏÖQ¬Or.[m_©«`_Æœ¯�uuŠ�é–SÎHÇ�-¶¯×Ý`Zå”3ÒÛïÛžk¢É4Ž9óÀMà-Û_6Ùhœk²Á"oÛ>”g„h9Ãò ŠÇ ¢ÂT‰–S^9P<Îü!2L•èyüB±¸ë”ˆ¿r®ëm_ α(¡rlÿÙÿADßV�&ËI�å$Èrd9 ²œYN‚,'A–“ ËI�å$Èrd9 ²œ‘�,YxC¥k¬*¿DÊ™aáÕ�®’o«wVlÊÆö™â)IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/input.svg0000644000175000017500000000637414757047403022143 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/invisible.png0000644000175000017500000000134514757047403022746 0ustar00paynopayno‰PNG  IHDR¹ åisBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î<bIDAT8�¥’_HSqÇ?»äRjÚj ûƒd„�–"!(C!6(0¨L‚|Xc"öb° L(_z�2Š¢Õ|ˆ‘)l´¶ w^£ÙõRñ^dBHKôZ·‡mp»)I~Ÿ~çœïùò=¿sLl™L¦QQ”g6›íº°¡¹¹¹C±Xì…¢(Beeeæ¿ÅöF£ÑWªªþlii9gµZg6*fLÅ`qqÑ …‚óóóææææ‹v»ý À–ušwÀ hÀPUUU“ããã­²,[�NgGMMÍt±Éd)n§€ÇÀK`¥X «««‰d2Y�Íf_ûýþËúºÞY5ð' 9 p¨µX,ËËËÏD"[{{ûÕ†† ð¸|Ö;:HÀa]®˜f³¹opp0çõzUQ»tœÀ$Ð uÀà�Ö;€m‡ãt,«—eUU—ššš¾é8_�³À}àÀ p”¿ñ@„‡SSSþžžžœ$Iw�çÀ�5¸`¶ø�Ý‚o`` ÛÝÝýCÅ{ä—•ÜÞà}qT€ãÁ}ÅD8~ÔÙÙùkhhèp’ürf�]:¡:ò]o´Z_ìH$}^¯÷{0Þ2¸&  ˆû×€²ÞÞÞ¸ÇãY™p»Ý%†úVà 0ÜÆpôÉdòÒððp­ËåJ´µµ}X^^Ž’?ʰ³@\…ÜÚH¥Rç}>_6 ½Ó4­ÔàÆJþŒþ�t:ÝÚß߯Œ��Mhš¶}CMëA’¤›ñx|RÓ´ŠÍèüc:Ô;.IIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/invisible.svg0000644000175000017500000001041614757047403022760 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/lineselection.png0000644000175000017500000000563014757047403023620 0ustar00paynopayno‰PNG  IHDRGGU°ZsBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î< IDATxœí›}L”GÇ?Ïî²,«(¢´Š­½Z«¦ô@±¶ è�EM¬V“ÒjBô$±çå4Z¹¨gãÖ­/ô%E5wz'gªmJÕ«´éÕê5¹^ÔÖU´¾Q„²¼ìÛ3÷Ç<»+†‚í.KÃ/™ì2ÏììðÉ÷÷›™ßÌ*BzíþfèõÂéÀzát`½p:°^8˜éA?¨(Š¢¿¿Ò)OéêÿåE¹ç‘€_(¥u{Âb¡(ã;ÓX Š*„ö*ë (  (Úk0‡:3©Š’­ÀìŸj¨ëAhÅ+Ú`aPdÁ 0  KGéá�ºs„¯*p{Áãx„UõbP Â&£‚É 0 Fôl@�š­„�jQ…À£‚Ë#p8ÍæÁôÉÚÈÝAC‹J³SÅ鸽Bª Ÿâz¢uZ9Bs#�WÐâüتâ1xõt.ÕÄ•ƒ¤o¤ ZaÖ:7*ÒÝz¨‚:N‹J‹P’º7&.ýcn¯JŒð ²'êÝ3TUÐê4:MªÏgSç"3öýU¨z> ST‹ó¥zSTDG�nÔ{ Wk=ÆÊë.óéï�ý.Ýv?|Ç¡{2å±± àOgΜÁb±0ú·³pÇùDÄÅʼn³gÏ !„¸téÒ‡š ŒÓÚÇQH¥ÐŸá^ºº·Ò�ÂDx½ÞHýÁíÛ·ÉÈÈàôéÓ$''?ùå—_¾1|øð$ VƒjÑ� í°w°Ùx*Z1!bV]]™™™œ>~ıcÇŠSRRFÒ^AFÂPÐò9MMMäææräÈüHyyùæôôôQH@ý�:¬5ÙÕÒÒÂìÙ³ùè£�ˆ‹‹K8tèÐæ©S§>NQPÐ3�N§“9sæpðàA _VVVœ��=„TPØ IšÔív3þ|öïßOllìà}ûömž9sæÂÜÅB–Cöx<äåå±gÏbbbâöîÝ»yÞ¼yã‘ Š& …4ÁîõzÉÏϧ´´”þýûÇîܹóͼ¼¼|.V€B~ú ª*”””óÎ;ïlZ´hQ*>@VÀLê–£!………lÙ²…¾}ûöÛ¶mÛK–,™@ ‚ºP·ž[-_¾›Í†Õjí[\\l[¶lÙ3„ n?Ô[µjëÖ­#**Êj³Ù^_±bÅs@П‹™è@Ý`íÚµ¬^½‹Åµ~ýú¿M%0E ¥;B è�O<iÛ¸q#N§“âââÈ¢¢¢uf³9¢¨¨è¾ý[³ÞVQ5‡‡a`óæÍ8�N¶oßn^¹re‘Ùl6®\¹²_¦¶Y{/E úéjX¸•¿•””PPP€ÑhŒX¾|ùš­[·>�\I÷%Ä[�°ƒPZZJ~~>Š¢—.]ºº´´t&2Õ° ö8ÂÀž={ÈËË0¼òÊ+«ÊÊÊf}€H$œ '˺%æÌ˜1ƒ]»vuª­ªªŠÑh4Ι3§è³Ï>sM™2erÜ@Å�~q :‹ÅÂÀ�¹qãF[Ý‘#Gp8Œ1‚ÖÖVÕãñEQÚ­þª(ŠPUU¸\.a0ÔI“&­¨¬¬¬7nÜß‚=n2«ÕÊáDZÛí,^¼¸­Þëõb³Ùxÿý÷ùôÓOïäææþ¨�À©•f­®¨ÕÚÔDµø[ÐbNTT~ø!™™™¼üòËÄÆÆ<ß½{7×®]#'''.--Í \.�ï;pE«¯ABiBB ºKA�àè`222p:�ÂjµRPPÐÆív³iÓ& ƒb³ÙÆw€[À5à*Ì÷ÀMÚÃñõü8÷œÅbáðáÃdffòÍ7ß8222¾SU•¥K—b2zqii)ÕÕÕLž<ù‰©S§öAºPT�Vîw�‘næÂO9Á\>(=xªþ•:˜¬¬,.\¸P—••uüĉ—***ê† ÆÜ¹s:imm¥¸¸£Ñhذaà ­Ú�Œ;M€C+Í@+!?O9ª¢(ý‹Å¡C‡˜6mv»½&33ó¯555�ko¿ýö9€W_}µ]'ï¾û.µµµ¤¦¦Nš2eJ<¾I‹¥�V0Ðu8ú•@ð H0|ðÓ§O§ªªêVVVÖŽ›7ožª€ëüŸÝnÿ1--� &tèp8غu+&“É´aÆ‘ =³ßØôïkƒ²«pËbð40wòäɯ ?»råÊõäääåÀ<ày`�¬]³fÍ !„Ø¿¿¸­ÄÄĈ††ár¹œiiió�1Àèn»™Ñå´]$Eʼ922²Qxýúõï³²²^¿|ùò·Èé÷ð2¨Þ~ë­·ÎÔ××»^xá:®¯¯gÇŽDDD˜m6Û|§&äV¡[¬³pÚ.w!á8‡Õjm¨®®¾ð)Dÿ[¹§�Äc‘1i °Èd2mª®®v!ÄèÑ£ÛTóÔSO‰íÛ·‹ÚÚZ!„ÍÍÍ?$$$<�tÙ(­¿�)§Ëù!„ðËL ÿúû´ó_µ 7�u�§æÀ�•………鯽ö_ý5ùùùŒ;¯×ë½xñâ™S§Nhhhp‚ôÄý¬Ë?FëRç’¢>ËY‘ Ї:Ên·¯´X,mÄ«ªªª�=úŸmÛ¶ýëܹs�j䮼é $gVš²®r§}ˆ¼qã†òÕW_�LIIWQQQùÞ{ï�*//¿¬=¯ÕJRqnB”Ãñ· *Ô�Œý�³Ï€ÄÄĸêêjÅår Ó¢�ÈTE�pB¦=8Gà[ôÁ·¸HN$ }Ôó7!!p+¿îõ«V‘ÿ¼>M $¾ÜM@þ&Øã¼Ÿ]9m_¨ ÿe€nzÎÆˆü±_ˆ£[Èà@ ÿ¢Û½«åv˃P[Há@à�õiG¾éf(º…NO²°½HÖ §ë…Ó�õÂéÀzát`½p:°ÿqÚÕ—|¸IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/lineselection.svg0000644000175000017500000000630214757047403023630 0ustar00paynopayno image/svg+xml././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771225048.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/link-slash.svg0000644000175000017500000000174715144537730023046 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771225048.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/link.svg0000644000175000017500000000176115144537730021732 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/list_selection.png0000644000175000017500000000316014757047403023777 0ustar00paynopayno‰PNG  IHDR;* ¯#�sBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î<íIDATh�Õ™]ˆUUÇëzG''?µQ3ËÈÆÏÑ´,ƒš ͇"-2j$"Šì%*ÅA|(Dł҇^Š?„’°èÁ,?23%3#k³ü˜ÕÃÞgîº{î¹sçÜsµØ{íµ×Yÿ½ÖY{ïuDU‰#™ŒVÕí±Bÿ‘&पˆ“É™|°VÛÂwÝœ‚šáÀn™+¡ªÝ`Ðì*4^îÔ³�×€o€«@M™:çœ`RA™“úû+t+ÐéõGÏ@RÐ}·×wèW ص~Âî yõqàÓìéõïñ:× Ì0«>¿`ý{úÞ=�¢îù^g'0³Øm^°½P¤ øwö‹”²ÝëÝfǺ²±ˆÜ4ùîVUý'6«¥C+¡TU/áò@“Çäo=+LûÃJr ÉÚÿjWË»¾¸Œsýe %CØ¿óc¯»€§Ö†ñ\ ëÛûUõ¯ž–NÕ‹HìÁ$ ‰È`éSŽoÿ~ßÍâðu��gd¿êÁ˜zy8 œÚDdu¹ Ed�ˆlÆ%®6Ù&"ÊPiqtá«Æ%‹(¤ž,mÀOÀ3䲞ï”ÆÇ�Cäï½êß5+a(/2z.zœ4/˜3y1¹ïàiÏ{ØÌë¦&«Àyàc 5à·C€�èiX0ëb&72c<¯w®�øëÊðìp“,�6­Jvh cQ˜hbû¢ªþA@þ{¬õݪz@U/ÇŒè¸pn‰ô›ªžö:Û€ç‚ñfÜ…ªÚ ØD;1Ø$ðsÌÄNàMàò÷cp %¢Q½1¨}†û^#ªè9iÚ2äßW»y5"U]­ª£UuKÄ‘¾À#V•À Bïº|°oM Êâ©Ë ãB)D$+"K€£ÀäF”Bý1 tt˜öÀlEȃ|8 löß%0¢ Á¶'Ða�7( ŠÌ#™ülÆ%¢%ªúp&�¥ÐÕ ¬ TqÊól–Ü1\Å ‰HØÜäY©ê¦/ï …a›¬]°l8g51“É…îÉ#–Dd©ˆ¼!"#‚¡lÁ 9²`ãòC¤s²ˆ¬‘9=è°xÎeq`‡zÆ�1“ÂL—,úÚŽˆ4oùîP`iœl0o0Õ°Ö¨?)øývPÝNºt/î{ù$e�ï‘ o`3þ*´Ï0g¤e‘ˆŒÅý7jÑtK³sq÷á-Edfšö>Um�\¾‚œ»w¦jYÜUí P•b/ðv6õ ·Ó`Z¡ª]¥Ô3p†t~2-ÆmO·¤´.Ã6÷ 'G„©¡ ¬°¯ØtÞ Ãª‰É”eêY‚ÌtƒåPÄ·åÏÓ~´È·P©êßêJ,©’ªž*AÌÚŸÃ|cQQíhÚ¹–ð¹B^¶›gÕ•BVúî8±ñÿ y»£ís¥Çå(X‘*Ü9X��×ÛC ½ºÉÛ¿—`/`Wf<ðµïŽªÄwW)‘:\…T�iªú½ïöÆ ¼ܼp-ŒL‘–ãv�å!P€bá°w›™r½C³Äð�Šû=³&N¦[[‘W€«ªº*u¤L"ò.ó¾'ó/²Ý~Üü~7IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/list_selection.svg0000644000175000017500000000172614757047403024020 0ustar00paynopayno image/svg+xml (a,b,) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/locked.png0000644000175000017500000000053014757047403022216 0ustar00paynopayno‰PNG  IHDR;mGúsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<ÕIDAT8�ÍÒ1JCQÐóDbH%¤Upil݂ʲ[k ËlÀ,ÀÄŸŒ…#üÿ}_”¤pà20÷Ý s畈pl�íp*“ó!¢”r‹;ÜàñX}`„¢‚Fß4“y Ö¸ÇUöuÎç?š`Š-^1éq“œo1msý`g¹Î2"6½µ7X&?ks}“ËìOÕyÎ~] 6C{Cƒ÷4™KƒE'ŒqP¿È·3¹@Xa¨JêþÑ·?©ÉÎgX©H]çÄ+ìýî2{¬¾´†½¶3Xf…ÇIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/locked.svg0000644000175000017500000000563514757047403022244 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/log.png0000644000175000017500000000117114757047403021540 0ustar00paynopayno‰PNG  IHDR ñ”÷sBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î<öIDATH‰½ÕKˆŽaðßè˘“ˤi(¹LÑ,l…\ÆÆ‚RŠ,ci1 ‘ +ЬPJÊä¶R"×’ ¹�…ÕˆY ƒ‘1çy›·×7Ó‡^ÿz;užÿóüÏ{žsžÃبÃjìÃS,‡[ &`ú1‚)ÿ;€ çñ½¬Ã'ÔÀùV–x­”ŠÊ?ì�„X�Éx…ÓxQàÕa+Vb*à:ÚÐT‹Ð¿×@ áh ¤—0„MñÜD#šqÃ8†mÀE¼LêE¾`VòuŠêÌñ2ߢš1‹°$æŽP[Ú|?”a§Ð`4 ’}—ãõ%;Ÿ¨�'˜SY‹7cÐ!þ¼¿ÊÚÃdÛ“½!Ò½TC`ïq{E1ª w±jx,jb•ÈD>Øìênå|�¸‚Ù˜��xý'‚’ÈÄœïxòm)p/ãžÑ÷egâm›–¾šPµÐ—Ù�™i­gEª»ÅÐ:�ÛhÍ�Ñ.Ò>Røq­ù6*¢ëð)mjwú<ÇéÀ²Äí©/ÖÏfìÂ5|oÆ,�T*ºqWõ·e΂:ìÃìG•õÏ8T¢>¸*z¾Ëha6‰¶ image/svg+xml -log ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/loop.png0000644000175000017500000000564514757047403021742 0ustar00paynopayno‰PNG  IHDRI;7™§sBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î< "IDATxœå›}lŸUÇ¿÷åyÚRXe]GÛ�—ÙÍ1Ê6Ê& p_þ@¢@P"!�1 “£Fþ€„?ÌT41h"‚…d¨ahˆÃÁË /å%µcÝ: íX·µëï¹/Ç?î½OŸ_Û߯í�>mÑ“ÜþÚÜçåœOÏ=÷œó´RD4/€&÷xß;Ãø7€ëˆŠu›p>àjáL4¸ÀéHøKÎ`&GÜ2ï!ø€þ9”Oh™w�ÔxbŽádÇ €›&Ó›yåsÆØ¶h¯àÜ‘”or!Ž !¥ƒœómÌ£u�±¶Îh½Ds.^�z·ÑÏKÞ6 1Æü@ÛTω¢¨ãÔÚÚ-zyEkkWE`NÀÆ"@d-Y"êëï¯íêîn;:8¸öäÉ“›¬µSMàûDtï„úç ‰1V· | ÇŽÔÔÔ<}βeO¬lm= „àB!8çœsÆ㌱�Kˆˆ,‘µd¬cŒâ/íÝ{EÿÀÀ´Ö«¦¨î‰èžqzͤGÜ0Ùq5ÕÕO¯[³æ—K‡¤”B !„”BpÎSLŽÔ($ïIÖZò|È8±Ú£µ6Zk½û¥—Úõön¶Ö6L¢†p%=[dCž�c×x´Ü1œó¾³ï_ßÞþbE2’RFQ$¥”Bá`�BbAÂùΉ,Y"kŒ #¤´6J)Ý?0ïÚ½ûÃ'O~~µÿ �ˆ†R;ò‚Äk„+JÆ!Äþöµkooin>G‘ŒœÈ(Š„t’Bœs./‚äv²DÁ‹¬v„ŒÒZkH)¥¥”RJ?ûÜsŸíøÊøˆè[©-9Bz.šP„Ý_tÑí-MM'â(Šâ8Ž¢(’±%£HD”c"SÆ“¬ó$‹´.ZfY@‰R:I•$‰znçÎ+ßëëûJƒ"‰h'�$¿› 'šçŒ ¬oo¿¥¹©éDUGqvx�Š(çM.6P)$ŸÇÇ"ïEc=(IUð� …‚Ú¾cÇÕG>øàŽ2fü�ˆnB)#f@n*wí%K–Ü×tÖYÇÃò €ª² â8ÊÆ§ll*ò$/ÚÒZk¡5Ù 0Œ&‡DÖÒ7>ù÷mÛ.O”Z_BÍkc·Ñ`^�¾Zj¢ººzÛÅëÖí’RÆ>þH¿ÌäX� K0»ì‚íà݈Œµ6¨9OÎ]º0à*ZšÖʶիïÝÓÑñ0UM j €/x`Æ!1ÆÚQ&'jijz,ìZR!¥Lw´È‘“qɪ8Žã8Ž¢8–±ŸçŒñÔpkÉŒ–«º¼ïX+ýÎ'Œ1Òa››šŽ¼ÚÙ¹}ddä3%ÔýJ.�¬.5!„x{ÕÊ•]Bˆ8Dc)¥>îH¿«En¹ÉØ�ԳŽÇ9w�ˆ(‡Däç`­%k —`Zé ­µñ‰*oX´èozzJA:È'&--5Q{Ê)Û9çLpθWRpÎ}˜BËzWØùªâtßBÆYKÚ£”ÒC7ï÷õÕŽŒŒ|ªŒ-r€äƒêïüt¢ùááákö¾òÊ3ëÖ¬éTŒN�'vŸmŒ)Q঵[¦ÑVÔCò^¥(¥TÚkÚÓÑq�R”ÀC¹@òò{?ÆÄýþNOÏ]g/[vË™õõ*›¼¤½�Láêù)eQ2EÇŽ¶JÒndT’$:I€=¿k×U…BáÊ26l%¢~ ߦۓ>Wj>Š¢ŽË.¹äî3ëëU•+d£PÜú¦›L›¸¡°ßt#ëj´ü�*í'…ÆÛ‹{ö¬=xèÐ=%ªÿ Ÿ&¢ùB:À>µ¥Ž‘R¾~é† w.nh �¶Ð:×¾õшešnEí[Œ$­µÑn‰5Ú™Ô»vïÞpèðៈʨÿ(¥/ò~ðM¿*wŒ¢çì¥Kï]ÓÖÖ™öŽÜçôøí}ì²ó ôÐÐvìÜyÃà±c7eTzÀùa©ùCbžPn{jmíŸ/Y¿þÁ… j™]fÅU{1¤ñ�”FŸ–dù+¯½v^Ww÷�ƘåSPû‹Dôx‘yBÆX \ZÐ<Ù±œ±#§žvÚÖU+Vüµ¹©éhèøAq•ê%dÏ!UÈ@²/ïÛ·º÷ðák …ÂFLíñ÷"úÎ8ò†Œ±OÂyT<ÅStuuõöº v-mnÞ»´¥¥?t8Ò*HcRU(Øo½µ¼``Íñ'®ÒZljN˜OºÀo”ê×L*Bˆƒqu )�J!£(äœ�(­ë´R ´1uZëF¥Ôeòžrr?m.9Kù½fS ´çúõšrC¸{R[rÔ  c@(7öX;%{rt#€ãóB©‘ÀUÑ”mšA85p±§Å�Μã¶X>mÛfÐ*¸—#¦«¸ð3¸äî"¸‚²0ÃpöØ  ®bûfÐ͆*Pþ=¸úhìõêàj¾û¼€é¿ºÜàq·X ¿ƒ˜Qq À«ðÜSÎéÊ3n$¢w§xŸ œ `QfÔ½ÁÛ—‡tR¥F•’ ½§ @'*[^?Àg*ÎÆ¨Ðל¬P/€Msmp®�œ÷õ†J‚çS͵±¹B°ÀÛÀQî Ïy À·ŒT¨9727H¢ò/È<  ~®�Ë€õp�…¦ 'pÇG}yM Àw½±ÓÔ `Ã\”+$gØZáòzÀ¹6&¯ÁˆŒ±ÀëÎÃô$°™ˆ¶Ló¼�”„ÇÅ €_LóÜ.—þ¯Æ´oc[LöÝ x À׈èX^ŠÍ' é ¸ŽbK‰ãGà¾@÷›YÐmÞȸ.cì2¸ïÔ�}€÷&€ë‰hßì¨6dܳ("ÚW©gå!íÿ�€€�”˜{ã~€KÜJDζbóIþ ±fcpÅŽIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/low_speed.png0000644000175000017500000000737714757047403022756 0ustar00paynopayno‰PNG  IHDRWT÷\«ÂsBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î<|IDATxœí�xTÕ™Ç?ï¹7$bBÀÄ6ø �U¤²Z­]Úºúø‹Zl·+ì–ú¬Ú}èZ”­k«TkUlí·Zum»m­R¨J]¶ËêªÕ-ˆ?p‡J1”bBB ™{ï»Ü;“™ÉÜ;3É„L‚ßç¹Oæžßç›wÞóžsÞsFT•JA à˜à©ÆdƒíÈ~Ë¡Åö‰Þd;<óètgã`·? œÜRÌ>†Oæt@ŠÍo<°“>¹)b-W‚0°³I_o;ò åðÄò�$»©K¡8`äÆ 8øàðþ”!š�@É�ÞÜ÷tº.Ë‘',‡úÉžõeíXd{™Ü@�ž |8ª¿åè>j,­²¤ÇrÑ\‹$],‡7i^ùƒ¹ÝûËÖÑ<TrcÈlàrü¯þ€�|�˜qaÌÙd[ôDHiß÷¤`¹HVž$[l‡%ß¹ {ÝÀ{šƒBn ™,N(Gyâ�ó:1Ó#ŒžÂ«£ªp-GjÒ:7RjÓá’'�g;,³nýæ?í/»—•Ü@¯~ø|?‹è^þ¬:�½Îzº7�Èíàè�î”Ë•&ÛaªåÐl'¥Ùr˜j;Lµ\© $3[¸¾‡èç-¶#K®Y¸¯¬R\6rcHð}|³ªlÄ'óy`]í#A"2 Ÿx€fUýKXaŸ[Wõ!Ûá³–ÃÛ‘:ËI©ƒ‚ÒíYËl‡[¯øÊ¾²HqYÈ�!Gw,2Kð+àgqtG¡Ä"Rì ^? ª› å¹ð٪ˑ3m‡ÏY'­ŸÙb;\¹èê®[&7†œ‚/±‡‘Üþ ¸+Žn+¶ ì ^§¨êÛ¥´ñÒÇ«›’çÙÕV> N‚ífšnüóÂ뺤&Dn ™\ X’*ð[à‡qô­Rë‘1øúàHU}§Ô2þíþêfÛ‘›,‡ã ÙÈ–#{m‡/^´tï+ý© úIn0p}¸ ˆäk�›ãèŸJ®(€ˆÔ{‚×IªÚÚß²–Ü[cY.Ú‹¬¤TÐÇ�¶Ã%ŸÿÞÞ×úÕî~’{5ÅY+€¥qÔ-¹’ ’ûüoÈyªÚ6�òn¸»¶Ùv¤8¿>wX—\p{gÉ:¸drcȧ€oHæâKëòRt ñíÛj-ËáBÛ‘Ë,‡Qª¢Ãr¸øüu¾^Jù%‘C>ÜÔD$ëþ5޾PJC†·}kôߨ·û‡N§÷ØI.:÷žŽx±åšbÆ�àDû0o8 pÙU]Ï—Ë�+Iã‚qÁ8bŒ Vðn¹b<~²j~ÝÅ–[¹Áö]`RD²—�ùý±* ¯ëzÆrY,ÎîÝ:9Ñ®“ÅE|²…€ôãÊ�Å–Y¬ä.N‰ˆß\G÷D¤©x\|s× w>Ò½ÿ>êܤÖh’QÆ,Ï_GþžúìÜC>[LyÉ�!gE$éÁ'6Qd*�Eòøš�î‰ËŸëÙuX­i©†î´šð%8�d¾öâÙõÕC$¹1dpS�2¾Gÿ¯„~TD¤øp°õ•Íîɵ†Å™Rk<“þL�ñ¸¾P¹…$÷Rr0ÝG�ºéÙŠ8úP:T)‘ñÀjü§-ÀlUÝxþÝ�O—‡MñW°\f¿ò‰ú¹Qe‡’Cš�9™ašÄNnaJ²…fg;›)lï|˜üŸØ–T„år³qÙ™–Z7çñX?¥á°°‚£$w9k^cÕÅv¶QÕr<ŸÜ Ì`džªºê㹫mgßÛ±Çx\Ÿ–Z_=ôp®Ô�ëÂÊÎKn0Y8#7ÜjdwÕ$ÞNÜJ—û.5À="rg°Þ:l¡ªÏ…­´�þ«ŽÕÆåñ“,ó9­efÃqùò†Iîe„lw›zÖí]ÅL µ˜ñ%à‰²�‡5ŒÇ�–G[†9†åI†y& òæË ˆ!3�ÙuÝîvêŸñíÞû‚°“ñ ¶Ú‘JÄÇÙ³Û¸rC†I–+½gµ3nBn¾|’»8¢žõqô÷ªÚ¥ª ð·Ì{€%ªê”¥7ˆ“žlÒry)Kz{-‡*ã1/7O¹Á®í‰uü{n€ªÞLSÕû܃ ‡ñ¸7KjÕXóS«²Òçä?+¢ìÿ�£/æ‹(fOk$À¸ò”å²­¯Ý Æ•ñÆåì¬ô9ùO‹(»�Ôl8öùÝ®ñXÌØz¥60ÏDÉØÒäæWØ|ùõ8Ú¯­Ž‘ãò€qe“ àØö¦Æ§Ófä‹’ÚÕƒÔÖa‡£×íÞcyþ´Ør{¥6ç¥>¼On?`\îÍÈ�lrÓ�ˆ! w–{'ŽþyÐZ: 1yî7-—W3,SÛ›¡Wrß—Úa¹ý†qYAî_˜RCøÄa70hþ«ÃÆãe ŒÞ“À—Ü&ÂÝ‘ž¨CÇHEÃÖD¾‡f>Lkoj¬3DïèöÛé Áš�pœ`€É™ûí“u�ै¸Y)µ†­enÌHÃÚˆ¸Ã IîûäF ¾5ÑF¯Sv.lÂung¥8yˆH ˜«ªK‡¨þ±ÀD|ëÀÍx¼w�·ÏÆ xÆ÷CN!’ÜAÕ·"Òtr‘/ßjEä U]9˜í Áé@^‚§º“mê�ì:ܘÌ# hÈLì´rDwœØ®;˜+"òÌHKE¤ X´G¤™ "wµAð)ú(kѼ�¯&·;�°»S5iÀ“l©ºç•\mû}`bض�ˆœüÿ«˜Â `¡ÁIpUý0%_\{SãmäÙ)êúì¡ÙÙQ=� ®áJ|‰É÷¼Ú߆ŠÈð÷ÝúØÐ"2JDnÁw-JÛ\¨ªóU5TÒ‡amʳ[+(f4Uª}Ï„ "rðãàuCNÜ4`9Ù§.ÿüƒª¾YÎv”¡ÿð(�›ÑålAà“õ�ú‡nȈ» #E¬,N­pb¡÷WDù”�\±€ð·‘RÿÐ "2øðwÉߨêÓåª�QaI *O\9%÷fàd{ñLVGf„­¾¨ª»ÊX÷`#ôfßÌÈÇ~mž°’!"\™Ü ¹"Ò&"�ö§Î¡@{ScŸnÚ ¾«z>Œ¦ö³Þoà»FE¸`Ù’Ü8€:‡ „÷ñ=CôlkF©µ‰ÈyÀ5E&OMÛðÝ¥f©j¬Ô:‡Q˵m6uä}¾yTDä|uÿ¿Ý ü a•ê°Ü«‹òÝfãÏñ»�êÜXã1£Øc€Á±ýÿ&ÿ@˜Ú%ài|B­ª�yÒ'D|\câ¨CΣçÉòu¥2ÑÞÔ8 x¨êR­-’; ÝXߚȫ*CWk�ËRã’ȶ{ƒI†‡X×^úxuØþш@°¬øm¿Ž<Ä‚S`^„’ûØ1Î.ãrc¶zLú >�Ë’÷ ²±ˆèŸaX^ßšx6,2rŸá¡ΓÆcUÎu{éÎx̹âÁê�÷·å•ŒàôùÅIÞn‰*£à&Žq¹Á¸´gKmÖúù¥5{Ø`)áü¸ÀWë[‘^ É]þ‘d›qe©å!½÷º¤ŽÃƒñ¤ß? S©hojœ| "É]õ­‰‚›Em?Þ3»ç1ãòtß{]ËePßfˆu,á5|G–‚(ڣƸ\g¹²>g9²c„j¯áß8•‹ýøê (7€’®Õ^ôhµe9\b;ü Ûê›ì‘׳´75~m!|£¾5ñÛbËò_ò«T´75Zø[9'ã»]ýg}k¢¤ ‚ÿ˜Œþ}’‘SEIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/low_speed.svg0000644000175000017500000000447214757047403022762 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/lr_mirroring.png0000644000175000017500000000070315143647637023471 0ustar00paynopayno‰PNG  IHDR00ˆð²“sBITÛáOà pHYsÃÃÇo¨dtEXtSoftwarewww.inkscape.org›î<AIDATh�íšËà ›ªÿÿËî ™5ø�«îœ¢LêÈyDDD^Dá}{Ý¡ (ÐBÐ3Ðíþ‚ò�‡ΟÝaÆëž%Bìƒtm±ì­±‹6σ4%H¬C²2¤Œ¸¤M¢&Yóýe j”íÍh™šñO=;/3‚FÎd­—W/e$±²~wKVžqÁ ÒX'˲à[%Å_TÒZê (@A ˜õ|k¯� P ¨’^Óy ·H+醂  (@A °’”&H«•-•ô­:;=A± «op§ŠmõÝý x‹ewAµfdÞën@‚nµ†k’åt·k®�¨É:ã±/f=XÏ¿ê³6÷ˆ+AQRòŽÛõ7éžyYs6ç�-öŸð] @A |q¯3_h8IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/lr_mirroring.svg0000644000175000017500000000415415143647637023510 0ustar00paynopayno ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/medium_low_speed.png0000644000175000017500000000737414757047403024313 0ustar00paynopayno‰PNG  IHDRWT÷\«ÂsBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î<yIDATxœí�”Õ•Ç?÷U 3üf¢‘�€ü�½þ âï$¸ºù¡]Œ'+úQâaCP6&Y%ºÆ¨hb6nüW� ‰šucâO²ìfA$¶ Á   L�a†�fºªîþQÕ=Ý=]ÕÝÓÝЃ|Ïé3S¯Þ{õÞ÷ܾuß»÷¾U¥ZC8*øÔ£Ó>c’E1¶ÃFË‘VÛáË¡ÕrdóË»Õ3@ö5¹1¤ 8øxð—¯�í€å–“ülGöX­¶OôzÛáÅ_MuÖUzüQØëäÆ�`ð |2§Rh{ã��ðÉMk¹”��IúÛ‘',‡g–ž’è©Ð”B±×È�!pðàÃCéC4�’&½Ùשz=–#ÏXO‹ÿ 9_U·—ÒÀM÷�l±)έƒƒÿ»-‡¹ݵ«h\4¹1ä<à¶<Õ\|i]Zì€ö&¾{çHËr¸ÔväJËaD„ªè¶.¿àÇ»ÖÓQäÆ�£�G€ºˆjÝÀ?ÅÑ׊ȾÄ�·�ú¤íp—Opèrz§�à²sîŽÚ¯)´b i~H4±€ÙÉX€+¯éyɸ\e\IŒ Æc\°‚kËe¬ñx`ÙÅõ‡ÚoAä/°ï"ª½ \<k 0-—…âàtvêÄŽ.�(.â“-¤7Wn.´ÏB%w!pZÄý­À•qtgD�ªÇå·ö¼vïS}{öôRï&´NŒ0ž`yþ>rð÷ã/Í{a!ýå%7†œ \Q¥ŸØŽçP•,’§W¬sOZúrÿŽCFšÖZèK© _‚IæŸ_?§!¯zˆ$7†LnÉÓÇwâèÿ1�ªƒˆ4/g›WotOiX˜.µÆ1©ÿ©77æë7ŸäÎ'립ԩ›Z‘ý,Ž>9” U Dd°Ãi0CU×]pÿ®gŒË/ÍÀ -í¯`¹ÌXý× ³¢ú%7†´3ÓË4��ØÄ¤D+-ÎV6’ßÞø(p$ðg|b[“7,—[�˶”ÔºY�EñÓ ë8Jr�µgàu3F]lg 5­ÇsæÛÂÅ%NlŸCUW⻡ÎÈÞm;gI÷NãqcJj}õ0ð‚s¥ÞxÜÖwNrƒÅ§³Ë­&:k&ðnÇô¸¡xXDî ö[‡-Tõå°�¶Oý¼{¹qy:Ë$KÿœÕ:­ñØ\mÃ$÷JBÜݦ�U»—1 Hnfü#ð¢ˆDÙÀÃÆãfËc{š9†åIšy&sr¶Ë.ˆ!Ó€ϺËÝ¥·{ ÊNÅ'Ø.u"ÕˆO<µ³Ó¸rSšI–-½g·uЇ²Ûå’Ü…ÏYGÿ @U{Tu¾Ë¼¸?äh¿ÄÉÏw=o¹¼‘!½–C�ñ˜�Ý&ƒÜÀk{RÄ3þ-»@UïÁÛ>Œ¯ƒ—ˆÈ'KœKUÂx,É�Ú@5–ÄìŽIM5õ³ÚŸÑ÷ïâèë¹n¨êFõ·×®>üVDþ("_‘ƒJšQÁ¸òËeË`»Œ+ãŒË9õ³ÚŸÑ÷ ©Í†ª¶ão¢+¾4ßl ¤9jobXà˜W:]ãñh°b�ÚÀ<%ãÅ–"70¿ÂÖËkãhA®U]|/­È.^‘µ"ò)Ä™Y•0.�Wöä0ÉŽéjnúXªnZ»(©]^ä®Ò ò¤Yw4¾ ~«ˆ< "'Ùï>Çá«:wZž¿,¶Ü©MÃùÉ*B®ª:À™ Äd?o$p)°BDV‹È"2l, ã²$íE†d’›2 @ Ox°Ü{qôOÅ ˆŠù‡ˆ*I›øà~ ]Dî‘iÅ>kocâÛ;Þ±\VfX6¦t575Á€$•S%¤ ª�?¼ˆjÉý‹QÀ\àMY!"_ ‚AªÆ“&|VÓ¡Âä¸ X�ï·¤4Ÿ<ˆ/͇•øüŠÀ¸¬Œ ÷DCê_8t%…ô¨j/p!Ñäf» àÝàÙ%Ç(TÆãM¿‘'ƒ/¹Í„‡#½Xj@€ª®Å—à0¾uq!0¡ª“Tõ Uí.õù•@ãæŽnüÍ\8²«¹©ÞíÑrR6TõGÀ0X‚“R;_œ¢û:Ũp¬)7À ˜ÑxÈ1Y!¸ßSœNp?~¼@ð¤ˆÜ*"ù‚ûªoDÜ›žT aØ\Α¨j'ðwYŵøóÏ×\¼ "—óùÀʈ{‡ä“ܲ’  ª¯ÿ’U<ß_÷m^g«DäÔr�¡\hhëØÎà…R�Q:wWƒ%/QUu >ÁJVòŸªnÀO]} ­øàw"rD©ÏzðíîÍø/ämøß®Î]ª ž ¶Õ õy%Ê®mCUŸ‘SrÜë¾,"¯÷⧬‘9ªúTåG˜Ë À¤\÷ºš›î$‡§¨äC³ÇÓ^;•·?tßÀß½Êõù}¹ŽŸSšÑ£ªáGÃ$Ó£êÉŸƒ±7ÑRžÃ[+(f5ªƒsÂÊ UMˆÈ·òÔySD¦K€·T«*„*Œ\¢\á{íåQHŽƒªî‘ó(âø€½„Ýa7ª‚ÜB,‹«miÜvÉ�{UGn•"ôdƒofäÂÈÊŒe¿C¹N¹$·0„‘ûþrKG¹Û á‡Ä�‚S©>ˆèjn´ÂMÃvƒ¿NÎ…ÑäX9@ _мoˆ^mWþñìWˆÚ®Ýn€¨”÷äF#*"t‹Á÷“õåºk¼äæATpá Gàí\w�ÇáÛcFWf\Ã]ÍM5Á9°½¡­c}Ò¤wƒ¨ic¹üUÅF8¼qáIæ¯Ã@ÄM†Þ•�LAŒÇñàpF”Jx ÈÍ�\ËKÅúcÜÈhó2¢§’?Õ9²]¦Îh·Rn™D#~`÷ºš›FBè7ú½†¶ŽÍ�Ÿ»\t ==$Ýx\""µÁ¦v˜‡[ðAÅy„oצòFÒÉý©--ƒ‰½|~Ä8âøéP£ð÷#ª2†«Ò–¼QG$¤NII‘G[�ÇÿšŒ—™�x—‰‰-´|ø³ÒT}ˆ©ê÷+3üªÇß~Tm7ðÛäEÆÆŒåÊO³ÒÞ1†„qaÂùÒkÕr®ª~¾�ãþ†;"’bæF4{¬¡­#y¸\&¹Æc¹qiO¡ÕĶºFiwœl˜¹Òê/ÇÀ«"2Ø("w§Ç«u57�Dø–€Ã@º.�EîÊÑžky<žžön#^]#Û-E�Çß—{"UŠëñw¼æëEäÚÀ:Š’ÚgÚ:¶¦ Ú¯5®ô¸ÁÏ­·o·>7ø7ÀN–Ã×~òéþçË7•êDWsÓ‘À@M�êÈQ"Ùn±u m9Ue¨�̸,6.™vo°ÈðËãúùO׆ù�ö ÛŠßjr þI�9Jî¯�rv—›3Õƒ`RGðÑd\•<ƒêÆ¢†aiC[ÇKa7#½»OçžÑÿkãò?ƒÏu,—ŠÇðîD¥%¼ü¨�N ލ1.7X®¬ÉÚŽìÞO_joá'fc¾:((e·¨cµüªÖ²æÚÇ?è¶ü–9{†t}µ£«¹é«ø{ ©"àÛ mÏÚÇ>ÿ%¿jEWs“…ïÊ9?]ëßÚ:Šrü?ÀsBR<IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/medium_low_speed.svg0000644000175000017500000000447114757047403024321 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/minimalistic_user.png0000644000175000017500000000627614757047403024512 0ustar00paynopayno‰PNG  IHDRll�fWÍsBIT|dˆ pHYs““ùäN¶tEXtSoftwarewww.inkscape.org›î< ;IDATxœí�{”WUÇ?¿á1<G˜åQ6AŠ$d@„ÚÃÂEjÔ²Zf˜ø(_¥%¶BW¹ð�d+K%3(W-YZ’ ,!Å’¬AHÍWÈCžƒÌ0¿ß¯?öÜ~wîœsï9÷ž;¿ßoæ~×Ú ÖüÎÙ{Ÿsî=�½÷Ù2Tº•[�”1˜ÔoG” Lš ÊfpŒ)À¯‘Î/àš�òW·–ñÊ®Îz¥«f×Fo`6°�RÇ}ÿÏ'+ê}¸õwù|ë¿»�ÀÑ)ëÞåÐx�¶�¤<°‰¶oMOd€uu¼AÜ î€vt| u‡«èG¾zß·¨wq´#ÝË­€#ÔX”½è�¼U—!ƒ‘3¨×C¯ ‡ù›\ÛLëßa­é¨vaÞù¶ÔH…ÌF6SI%£¬F:7 ÞÏ-)ð¶Fg0€µ˜­E¶¨^Tü½/p0(™�'PÚºoîfc€ñÈÖÛfM2¥<òv]œ Üü­õoÞï—¥ØîªD7àß”ÎKÁƒ®í–‚¼ó�ßZ€©µ¾ 1ƒôÃÝ‘Zë«�‘îäâ <€›»�ηàíñ/?A|r8x »Ný–ÿ1–¼7 ë_†ôÅnÚšfÁ»pÈ‚÷ØÄ­±D5‘©( ±ë“þ)é¡Eµ Øû€G°óMÙ8GcÞ'Ed]½yë3øÐø!⦷™óÀó˜fï°à]ôéò0“ê8צŽQÀ+´í [šc g*vëWðÁ(¿LÔÒN‚U$?8�h)Ý¡ö`B9ç¨ÝJ¤ý ×C|E*Y�Àä ÒáUÜr¾ Ü�œÍš3ÒYÀ8Ü™¦Nþê€O‡£'°‚è'²9_é°È€‡íÔõ·¸¼_¥Šï+˜:ó„Km³å¤ªv¯ÌÅ®±õ!¼§ò}bMˆW!U¤y…4Äa‹õíTþ–ù7ˆµ¾¢0Y¤ßkPvvoÅ¥!¼¼P3ÿz\{\­E* s|z7c*.2ø|J÷­òH¸—οTK) Ì”…Ènþ(¿±’Ù´ì%�iÓ�™À‘ˆ»g.°ØŽ¬¿ç…è^Ì¢¤¸¿1‘˜À lbݽàŸp íýad‹Þà+{�¥LÝž4é¤JÁå¨ËkL p%ûÞhäÄoÛ1ï_@ÌPC€?û䨞üm­òæÅ�iJ©OòwÑÏáÅÀoÏ"V‰àßm¦ž"rëñgˆË>ŠG‰Óü…t×±©Éº2}\�]ÇëÞB[òä™òÊ#ƒÛlQ>Ž^7$êÍ”1u8t¥’í ü¹¤þ/Ã6æWJÙ¡ó+�¢òÏ=~Øø°–#×_‹À‘‹ ݉no1¶v€ÁÈ& Í5Á%ù§ã°Kéû€cm�Á·ˆl:lB Ê‚Y” L§ÃÝȬpá¾³ íì�XïUiv·RE7S~OùÄ„Îöé\œ,¡íFd!úio$fí•]|‰*ÙÊû19 VòÔøóýë�éȶ?j�êƒdÐQ®â1…RÀd¹'8nÞ•^Ó«÷QþRÑä4]‰0Ù÷BÖ„B9ªº^§'A—0“³ÖL$3ZxqO!¡ÍGßDd³08Ûs_Y_�!ÙÃTUvRoäâAC+�>Џâ¤· VôUšß{!~°¹H,D‡êJd[þâƒÛ@:]"‡ä Ü‚Ú)g³Q@Þª:C&ÿ ®ª³ ±b|ȶ3ªçSêdW»··€w[êq®#ù~=öP†ø÷´q/îwo*‹‚ Vãþøðñ˜ºT$j�øA—h"þ&eî�εŽù¹†•5ÅuÔTX‡„=ÇAµ¸âëùpàð|†!%ãÔG®SÊå�õ+.¶ºRÄ!†ŸAŽ!cCp0ø¨ÉĽ ™ÖW#ß¾¾�G‘cÉíHÔÕEˆg àv¡_%0CêâÑôzôD¢±Ö&�»¸ ‰\â0Äç/ÿ0ÁD9—Vv?¾üÓŽu‰3`g/;Öa¥ µH*&ÿï‡�Ðv#ÜïX¹"ñwf‹SÐåtCÙý�è]×ò=ڃ잗þ^¾bÚA9à*àfÓ (Ï!×nlî"�D^¹Ú[å�@2„a:02¤ÌAβ¶•ß6dê�õh ðIä “ ®@œ¤Æè�L‹®CŸXèPOòŒ7Áº»�ôèQ8šð)p+ðmàöŒFŽ5&m¹Ñ�§uÀG�×v>2ϾE²ÁûÑ GND+î@Bì‡K‘P´ÏD\ÿQèGûp?-ÆÜ¼ÄXdר㽑”�®jB;‘ŽGi;<Ù*?@²xÆF’e  [¿Ã¾ÕbŠÃ‘t�ŒT>^ðdþv5UÓ¯&y&h×Y!|�€¯Óï»ý¤ô]—{B„–“NŠÙžžHaÏGp³ñ9¹QÕ†¸f<-†“<5]Z´ŒxëÀ×5üöÓ>n1Ž¥´þ{¤ûB âƒt‚îÀST^ŽŸ®ˆÑ®g5¼æÇàÄ`Úo¢v#Ç–Õ¨åÞæ@. ç³rHy)ÈUßÓat¯°s˜ êï·Ÿï$#ˆÕE%{캟 :.Dä�×1Ïh}­†ÏJó®Q¢7m¯[‘#‡ß4ÖýÔ8‰8¹Z‰ë–ŽLïG5õ¯3ïžvèü!À¯|UQVgþš“@>j˜V2å‰*Í!ÆiUý¸—r¨“¿\¥)?[#YLù€\]-÷ØPÙáEyÏjê牿IÁï–�òÓ4:¼S> àÆa�ærlÊ0‹#¯á±Ý®{þ�˼î#ü¨1X£C3 Ï}(] 7é´FÄ ç=±IêeC>^Þ7 Ûtº†Ïf›ŽiŹ ý&Ú†Y«Ñ¡ˆƒL:½�¹5ªƒW"ìzÄö¸1¤NXçÿ‚ÒåïÈv7¬|3‹¼�9J•r" §ÐÞäô4æ™I½|'Af©‡=�ß)˜{ˆ™Mû)àT�Ba¿Q!»¹ç|Û¼tçX¶å‹ù+,xL@ÖKýõØÅ?îÖèÑVÉÝW‰Ÿù“èS Â~À–„Èÿ¥‘ÿ”a}•Éé5ìÌY5è³ µà‰Òqó�]dÔéï`ú^?oº½‰R2[LÔÈ^oPw’Ñ_o;ðKê4:±�–vŠØm>Îè�4²ßŒ¨×Iö쯳�xÞ‚aš(s–sÛÏH ë�ú‡È×�Ãú Yv‚�7Ðè4�ü—L*§9¢ÏY”Ý ü'-E|x¹|®‚jjëü–¶Ÿë𢜖ÇÔA÷A�çcòs†zd[î…è¨ü¸õzõ~e \õUáKÊX#ÿz“Êi~ý{2Ç_Œ~÷Ó„œáîIQ� G\:ÙPy˜‡¤~ðc.vÑ`A†þšï øvjŒ@múj¡”òáÅïw9�}‘‚o™‰ª6wG è·òh!â èƒ$ïÐ’ŒL%7ÌXœø,êŽk¦ýçj¬ÃÍ—÷ÓÞBâÑÝøw L"Ü�³‰ÉLо´?Çy´8Ê�Œ.ƒ[ÑØr’Ý®1C…ùƒ»Ð 8ŠðÔ³›ˆŸ:âd$×¾Ž÷�IïŠPÝ‚TQIC8�hËP¹P²„p;êƒÄ<WSšX—¨E,§XÖÛ�¼_D,õ{û䑈‹e2²ÁÃÝÀ7Hï;ž�5”œ¢~š�Äh�“®¨ Ï`‰;iß™s|¿Cì�®‚Š ˆyhª­ê¤¸óÅ¿‰µ×¹ó£hbÎå²]m ë�\"ô|YK‘ô‚aéûj‘«C7ˈV>ý‘Cõdº{ñi­Cr¯A¬"‡w£òÓeð¡Ú>:ž!C† 2dÈ�!C† 2dÈÐÉð?‡�ˆ nåIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/minimalistic_user.svg0000644000175000017500000001530714757047403024520 0ustar00paynopayno image/svg+xml Ø ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/multi-document-save.png0000644000175000017500000000162514757047403024665 0ustar00paynopayno‰PNG  IHDR((Œþ¸msBIT|dˆ pHYs°°œÔtEXtSoftwarewww.inkscape.org›î<IDATX…í—ÏKÚqÇ_™ÍRhÐ ò´ S‡Åt1#¨CìPD4ˆ[ƒØ¥KÇþƒÎ"µŽÂ‘tp„µsàa`-DH ì´$Š–Š}vp:�~Ø÷k3Ø<|Ÿçù<¾ü|ŸÏóyíz 컡Pè›�Ñ‚˜žž~¿¿lËår…ßë?�tà©‘€8<<”ãV«Ubss³Ê^Z$€ç•É Í Ö û€xQ2´ €øL±t0Þæ7///“J¥V ½|Þê ‹Åèíí•ôOMMUÅd³Y©p#ð^®ò!iƧk°J-¨¦ ÀC mÿéàà ­ÒéõzŸ�ŸŸ�N§Éçó˜L&ºººB°±±A"‘Ðý�Þð»Ö××eñÄÄ„Äââb•Ýn·ß¸Õì`§ž¿¶¿¿Ÿ¥¥%,‹dŒ×ëÅãñ·ÜÎÎÎØÚÚÂï÷cµZëÆ$“É2à?9$'''Œ���ÇcuÝÁ½½= …б‘H„ÑÑQŽ��1›Íú:�NB¡P#K8==­k�ÅbD"l6[]?4  ƒ�Ñ)¨8mIëN4êwÀƒ‘‘‘—Ëõ h« Èd2–d2I<'ÐÞÞÎüü|Ù¿³³Ãêêê�ÂápÍ.F£Ñªg›Í&Û„=O±q�Uv‡ÃÑ´A•�º!™L&ÙS puuÅå奪|ºf³Yfffp:�’í&0>>^z ‰tßUöõõ199‰Ñ¨¼Äår‘J¥p»ÝtvÖÞ”CÕÙ| |‘Ë'144$[ƒRZ[[“¬Ÿ•••ºk*ãìrpåí8::¢§§GqwþV:�–ô•Æ0-ªz_šê­–oÔ-ØÔyÐçó1;;[co¤6Û(ž$º»»™››Ó %„`{{[u#ž ¦Í(]u�h`` ‘ëì±\³G~ðAÆŸ¾Ê%h6`pkIÐò§ø? V•s¹œâÿ5º¾¾&ŸÏkÎS©fNÄ­pwâÿhbþŸZüVÁœg�ÑYÅIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/multi-document-save.svg0000644000175000017500000001367014757047403024703 0ustar00paynopayno image/svg+xml././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/nabu.png0000644000175000017500000000026014757047403021702 0ustar00paynopayno‰PNG  IHDRí•tÇsBIT|dˆ pHYs°°œÔtEXtSoftwarewww.inkscape.org›î<-IDAT™�Ì¡ ÄÀ�¯ó5-P•�†¸ˆD’èîÀÑÂòϸ+˜Oñ ` ”«  IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/nabu.svg0000644000175000017500000000763714757047403021734 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/output.png0000644000175000017500000000200114757047403022310 0ustar00paynopayno‰PNG  IHDRIRbù„sBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î<~IDATxœí›1ˆ\U†¿?��E$`�XŠ b!Dmd 1‰�h#*¨Š`lÝÖF¢„ˆE$……ÁF ‚ID XXFƒš€é’Ìoñæ±/ãÌ›³ûfvrgÎ×ÌÛ�3ï¿ûí½÷ÝwgFÀ»”Áªí¿g¼e¡¥±µq| øcV Ávàà¬Ñ”tÎöo3kÉ$]?ë6@·))@J �’¤¤))@J �’¤¤))@J �’-IÒ-›‘S´$àkIwM;¤tI;¨D­L3¤tI=`øBÒ£Ó )]’û�KÀqI/N#¤tIWú�[‡%½>é�Ò%õÇ¢êY«’ŽJZšTÈk~€,% gpº~£!%�ævà;I»SR;7+]×IóJ¸  ^y>§Ú�rxÄöÅõ4¢“$Û纼~ýíŠû?þ:øõÒ!{Þm|@u›1ô ÖFéÃm\ûë5ÐÛÀã ¹Öi =ª�´×l´í–Ú ‡”À¨r½H|Öö{]CæQR�j‘ø˜íO&2o’ \öÙ>9©�Ò% ~äïOª›Ô&Rº¤fO: <`û—i†”HÝþz=qAÍ�’9¬ØþkZ¥KzØ¿ÞÛŒõRôœdû•ÍÈ)½'m ))@J �’¤¤))@J �’¤¤))@J �’¤¤))@J �’47ÝvJY8#¶Ïºpµ¤'fÖŠkœnþ)øÌó½xa~IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/output.svg0000644000175000017500000000664414757047403022344 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/parameters.png0000644000175000017500000000532714757047403023131 0ustar00paynopayno‰PNG  IHDRfb¢N¦tsBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î< TIDATxœí�{°UUÇ?¿ —§ÊÓr „ÈyKÈC¡@g"G'IlLK3Ã&•AÓTFýa†=Ft(Rh°�Ê|„QY†BZø„x�"„BQ Rà‚\ï¯?~ûÞ9\Ϲg­½×ÞûœsùÎüæÎܳ~�½¾{ïõø­µ¶¨*'"2ø0ØÜ ªÿqЛÜœ <,VÕU‰RÕv+@gà*à@[É SýÀ›Et×7}bÇ–wåäDHàûÀÞ"•Z(·–±óÛ2úG�{�®'ˆq#æ±2Ú,o£KØø¸£ ùÆ(‘“vyk\°¯ª�ú½€ÍÀ»m¬TÕI>1Öù®!”mÔ 0øj«ÿÝ�;)Û<Êí—˜§=Ëß&"Ú,ÀµžúÏ{–?ALFxÎW¡½¶1€�¹; ô(l£\Ð.ŸUÝìÈÈÝj_R �᥌ü¼G©æ^e"2øö Y©ª¯)óu`n†aÝ®ª·´Š¡?0)’zàQU]Öò{-‘ò<ðî‚ÿ ø+°2’�s²�Ž›€ÉƒZý~ø ª¾µGÌ"à³yÇ‘KUõ¨!bD¤'6pì–w,  ÀPUÝRK�ÿµT7)Ì‚ybDD€­ÀyÇ ÀéóŽ".$=ROaÄïC�ßÉ…®À�¹OÁšÆ¿÷)xW9Üô*á³{íJÁ÷µÒÆô lïŸÀDU�«ªÿ-V@U›TõN`$Ö‰-¹ßí�ž˜aØ;Äݺèëé¿/ðj ÿ¿ºä^©Éé Ü ¼�°b.�éÿâ„~w·ØË»BS h,6ͧr^Lèû1|6ó€î…¶j¥�i�ª®Î®жmàÙ„îŸñ,¿˜ ª³UõPá5G €cÝ\¬IèÚ7!¶*º‘Þ�š$¦¾yïÜ|+ìJ¨ß‚Z'æ˜gùá ý�ô,__ꇚ%FD®¦yªMLèölÏò3Dä!ôŽ_òîE¥Ð+¬ ~—µsL¿‚å‚âømn£ g–{E$ädl½×±˜•Ó,wÄô?;¡_ÅÒŸR­‘•˜Ñª—g�þÌ)ð!U}ÒÃÿp¬G×9€€9¹ßé�ž–Ÿ‘ün-”Àu޾§cwzHÿ;k¥ñ?Ø^à'"ò¤ˆŒŒò=-ÃPyXô ìWæ¯2™\ƒÍm•Âa`‰ªþÊÑæT`yòèJâ ¶_æïÀ@àŒ¼´03ëWΙØj×Gzº‡íuv+Yö]³~•]tò(ï³xû.ÏX*‹Uµ!kb|GÖ>#é_¯yÚ¯44?†ìGþÃ<Ë¿WDNr)¨ªG±|L¥¢ ø_™2¿SÕY¶/ñk_še‚‡�^X]¨¿Ë ÎÆV@~!ª¤,Û�·�Oc³C° ¹ó±Ùè#qh¹–,ÀG°=ˆ§xè�ó¢œÆ‘�:¬{,ú{j‰rŸ$ù �«4W·s=ERÙ¾¤tž(pú éÐ2º—ż°ùŽö߇-Š(ŒmDå˜1ëc½aÐ-Ò,ÞHxa ÀÀ”‚¸®ö;ê¿ L-Ð='CRÇ×±31À{°ýì¾�l%½‘øà÷1ôŽ®ëfOÝ&loÍŸ�eXÊGC0b°†Þ7€J—£Ø š‡<õ´ª›3ð[Û„ï"Â6ˆùLTd²»ó]ËoN*R?_òô;Ї˜¶Fþ;Úø­š±ø£cYfªêÁ"¿ÍþâhgðoDz‘çÒOŒ"ÿ;<¤ìN�®ïàÅ2å´uWSþ•¶ø"Ð%tã61˜w…†’E®q,v\ëžã6Š¼ÂŠèßÔJï0p0É— gb"Ç‘ýÜRrw™ë쎵«K±ÁpwçJ„K±´ÃM”ØOã+NL™G´7°J±§ª¡SЩÁ•˜NØLè˜Ô# �Œ”Myâ§|Œª¾…�´•+[�˜Um¤€G¢LU·?O1–4°MUæD8¯’‘.X_¼O@ÿ ؉«›°éŸ1À©íŒTÕ��m¦�žÇLÂôŽöcYÄa@‡"~úa‹èÖòwOˆ^RÖâCÌú•ô0pš£¿ŽÀ×°§*‰Ïƒ@ϼ+:(1Xß~ ðå„•ÓHüM§gÿHèvy�¼+ÜUDU‘ÞXŽbH$gEûcS3I1WU¿WYD&bóRÄò ¶`csÁß ªº'€í ¸[Vz¤Ý,«�úÄ�6ÜšbŒ�ÄHf¥úÄ`­ Ét±^Ñæ¤†D¤#° ÿ][>­ªëS´ïŒ:Ò#l…HbRÔüüu[m`pÊö�‘öJLïƒ Ë ùç?ªÕFÌêÀö*i³.¤1U}ëUÕ<Ò&f`Hc"Ò•ðS6‰´‰™ØÞÙØŒ@Í#mbƶ7.°½ŠE¶„4-Œ‘îíM h«|OkJ uت÷´p pgC"r0#„­X‡ÿ±V©¡y®ì<àìdÔØÄaÉhbàU]WYDúbyûP§¶*¶¾lSdw-ð°ÆøjEZ(š(‘zls¶or205�Ÿ×€1ªºÛ;@‘Ø÷%§'ð¿Ûm°)’—´ø"¾Ê�ãb7ÜWÖ—’½ÀUž—£(¿ýÃE†ç=)é=iëQIß PAŠígXÆWgàÛØç“ú[–w%ÇŸœÿl�uˆq„b[5ÖD²û ëØHFc �éªú›@¶2ƒ×‘%ÑÙ)—§Np¼ VÕ¦¼ñ…ó3�ŒJ1–4ÐËÌV|Fþ °”s5¡x0ú¶LUÁ‰¹Û¶P�ü4ï |Q¶�‘!XÄéè� Æ,U­šƒ€Ú$&Z}ùÖKªv&kôq¶JG¹WÙØA¥¥ôgç]É©UÂ(`OÁE¾trÐý|LbîsŒí2Ž?,¢ ¸>ï Ž+^¹U]/"〯DÿºWU×:ªoðñå«§ª�ˆÈÓÀ�XZ|‘ª®ˆé3wdv„¼ˆôÁÒ˾¸PU]å©dvî#Þºã¸OZU#ë±}·uï×+kjYã{÷·Ë§²'f™gùå©DQÈ”U}øå×7`‹ü~�zPŠÿýƒÍ!Ī~£IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/parameters.svg0000644000175000017500000001347614757047403023150 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/plot-xleft.png0000644000175000017500000000312714757047403023060 0ustar00paynopayno‰PNG  IHDRGGU°ZsBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î<ÔIDATxœí›[lEÇßö)ä"AEˆ‘@‚h´¢ÄAMK0"Æ4j4F|!(’¼…Dc41>Ô˜4-Œ¾PA4<T"�T}Ј/DR¼P(í9ûù0SØ.»Óíž=Âþ“ÉÎå›Ùogvw.{DUÉ-/mJY‡28epÊà8”Áq(ƒãPÇ¡ ŽC‡28epÊà8”Áq¨<‰FEä~`ð7ðO T#ÁWÕ±¶ÎÏÀP Ã†3€µÀ(žVÕõIø¥Dà�À1àj`BŒÍ)à‹@ú`pc„­€#ƒècÿRÕÄæWoµ Ç€š˜: »#ÀB`X’~Æ…¤zN/øÀb© �†`n»°ŽÚãàUÝŸ¤�.ë�¼è ¤+�Õ1¶Kíñ­4ÁÉÞV¡ÛåUúÞZg€É!›)@7p¨NãVêãOá ‡µ†l¶Øüiƒ)*{ñËBpòÀT[v¯ÍÛ’6”´àx@{Pæôf0¹˜>•  èNεh�+Ó b.ªDäcà�Pö�ÀtUí)ºC1Jknµó¶ ª¹”À@JpTõWàíPö³"2, â”æ¬üƒPz"f°X2J΋y+DdRÑ=‰Q*pDä6` ð-fy¢WC�µiø¥¢¿­DÄv7·uÀêTuWQ‹R ãœ'06ØôÌZMpܳ ûÃ¥Š ¦³–s˜ÈO+xärƒó®½ð×Cùð}ÎARZä*:`�þ®ˆ(ŸÑ{^º\àì°ü”Ãæ«œN`â% XŹ%ŠZ‡Ý¬ˆÞó%0< 8‰�sD¤BDêD¤ xÍf{ÀÍŽjã#òf[EdªˆÈ`ûéTB=ef¹3Ü z؉f¯ýdà�þ7ts‹Õs’Ú}˜Šyð·t (ª�ÑÀ຀ý(`¤tøËÖéÆŒƒjõjòù<¥²žóQ¶WîPÇ¡ ŽC‡28epºäàHkÃã²fÍ \WA�ˆˆ'"q!•–T›¸vÏYW_7ЦœpDd¸ˆ4c¨‹H‡ˆ4‰Hå@Oœ¨„øì”ÖúuÒÒ0ñ¢›‰!Û=¤Ï1¿.à`:æS¹mª:çbO𤤥>|A�¨®EO½©K·wEVŠ‘«ç,€é¦©êLàA[v·ˆÜs!'JQÕˆ¼‚W½WZ\HEWÏÙ‰Ùؤªóù¿×[Uõ>gã­ófãçÇቢ¢¨¯gãø>*6íë¹x^ñE)EÔÇ·ö^^Qï\™Ÿ7ǼïSfóý¼ây_»/Ywàóœ.Ýò]p"gåvûäV›<*Þcá¸Öe¬ùUˆÌAD8Ġ´Ž{¦?+ vùFÔvrO��ø€x戂WÈûEfãÑ.-õïSá­Ö‡ÛŽÇYƵV(‹‚0FDF÷ãH©<àIzü}ÒÒðŒ|´°,Î(J#ñßCeûñ±nJN¯*­áÈÉÈ;(n±ëgû>ׇʮ Ä£>• H‹»¬Y¸ÑVzÊ_ÐG7Ž3Š„£ª'Eä æ ô[BÅWâ'œ.ôäPEÝUB¹/”å…îJÏ÷x”U9_ð|é÷|!W!TäHKU‡28epÊà8”Áqè?¿ùÁ±·fæIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/plot-xleft.svg0000644000175000017500000001516614757047403023101 0ustar00paynopayno image/svg+xml././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/plot-xright.png0000644000175000017500000000311514757047403023240 0ustar00paynopayno‰PNG  IHDRGGU°ZsBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î<ÊIDATxœí›mˆUÇÏxw×Ý5×UÓĬ¬‰ iQf•ijb”FänùAÁ?"˜´ ½A$öe!2W£Ò/í¶Z�½€*D¡%½i©©hëîºwïÓ‡snÎgŽ×tf®98Ìœç¼Ì3¿9gΙ33¢ªd ——¶•¬ ŽC‡28epÊà8”Áq(ƒãPÇ¡ ŽC‡28epÊà8”‹£RyØœþò…j`¨/Tu”-ó#P ·¡ nÃSªº1ŸÃ  8 \Œ‰Ès øÌßÜ Ü’W�ýÀá‹èã¹¥ª±ÌUo·'çG�†ˆ2úòuqúâj9Eð'€f©õ% cº]PG춸SU÷Åé£KIÝ�W½¾x5°*"ï“v»&M0@¼Ý*Ð]^ ´kõãy&§�@}]©ÄŸá µòtYû#iƒIŽ=ùE8ÀD›ö€µu¥ %-8°3¨sú3Ÿ¤OǺ‹³‡ö÷ívEÚ@üA¬Ã‰JD6Ì{€&UíOÜ¡¥õlµ3Zùµ®’À@JpTõgàõ€y™ˆÔ¥áO”Ò|*+‹™,VŒÒ„ólˆm¹ˆŒKÜ“¥GDnZ€Ý˜å‰¢j�WÒð)L‰�V"â_“�;€©À«¾, LUÕ‰:¦æ9K0ÞµñÁ˜µÿ¼göÂ¥’ÓˆYËéÆùìÁÇ ¿Üଵ'þRÀîßà ¥E®Äá“€<ðpEHúÜ�ÖÓz¹ÀÙnOx©#Ï8ÝÀØÿ5`%g–(ù¦…´žÏ�!iÀ‰mž#"U"2UD:€­Ùnq»*Ä6 Ø*"ED.¶ŸNÅÔR¶a–;ƒ­ a4‹ùÇ¿9òÃq`FR-'®·17Þcö„Nƒ€z`0¸Þ—80Ì:üiËœÆÌƒ|åcòù,¥²žs©({WîPÇ¡ ŽC‡28epJ ޼=oœ¬Ÿ³IHxÖ{*kžcWïF«ê¡ >à¦Õôv?ƒÊ* žÚº�ÿÁé ­79[Žˆ ‘u˜ªƒ"r\DÚD¤ú¿LÖϹ�žžoPy3[†½±~#t!Št̾CÚŠyðëżãn×÷—{Ù8ëj¼5À|óˆäS}¾bá¸ZÎB ˜n`’ªNæÛ´é"2ó\•KÛ”*Y?{9Þ_ÙR ®:?—“Sä=GD¾Ä¼øPUçùì¿×[UuVdÅí³îA½µÀ�NTÞD } U9”h<»¥ Õâå-¦W�ä0-ß|u�3ylÿæÑ=ÚÒÕTœÐ&moÀ·Ùèþ@ò×8¡ë2²aæ ¹×À{¬}Ú|Q‹¯Ç %ÝOl¼$=B±òjÊò‹ènÕàK ƒ0RDF�²zµ'ïÌ^F!·(L-»GÁæÛÿ=�öƒoTqG[[ ˆw3²U®´|8Q#ÅQL›à†@Ú•¾ý’Oeµ¥s³´Mù�šÑKy³@u.íÉy”~Dó¨äŒÍ„~ÀØ”<"y´�é/‰‹äúMù™z” image/svg+xml././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/range_selection.png0000644000175000017500000000134214757047403024120 0ustar00paynopayno‰PNG  IHDR=3$h™sBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î<_IDATh�íš½kAÆÏ^È‹±ÑÊF¬T‚‚©­,ÄÂÂÖZüì-¬D�€ˆÎÂS ÁÂN #øE° 6§‰1"÷Zì$›ÝÙ›ÁÓ“™L±÷î3ó>;ûq¼3æÑÖ€[@ffüëdE>k>>2üh{ŠÁÆ�Œ<Ÿ¶�Häî<Î9Îÿif}ÿÜF‹¤ ˜tœÒN&JÁ¾™ýEb£¤˜ˆÚ¼%m›¨q¹Mÿ*Ét,$Ó±�LÇB2 Ét,$Ó±�LÇB2 É´/’f$ÍJrÕ§ªtS’æ$M{êZ’KÚï—év‚LKÚ-ièË@OÒù!µW�uà%ðUÒµ¢°×¤;|^«’ø^´­l­ w‡¬7ßag=¹œhÐ]®Ðp¥A7 üªÐÝ2ßnIçg8R“¸Oºù�Q¥[&ÚGŽ1ç}M‡ÜÞDZcŽØA`¦&6  ì׫$Äô.G¬íx>§úuÅ]cºb•„˜~눭8V@>�?—Uô�G¿ïó©$Äô3àUMìF�ÈÌ6€›5áE3ûîózÍïï�§]-!oï9`µ¤í­Ý^àyI÷Ø× p»¤ûœ y{—ײ†»JfË’æ� Ààp׊ºž¤à"pøH>Ëßt\’ÔÈ¿÷ÌìSHþåUˇfv6¤£qFR838Nÿ½c!™Ž…d:’éXH¦c!™Ž…d:¢4]."d’\…¶ÿuðŽÉõÙä¾,zÃzH#Ÿ´¥"¯‘mrß$/Ì�Ël÷ÉóÙôý¹%¾.�¡«ÄIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/range_selection.svg0000644000175000017500000000224414757047403024135 0ustar00paynopayno image/svg+xml [ ] ... ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/red_dot.svg0000644000175000017500000000103615143647637022417 0ustar00paynopayno ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/reset_3D_coordinate_system.png0000644000175000017500000017531415143647637026262 0ustar00paynopayno‰PNG  IHDRùô>(T:ÅzTXtRaw profile type exifxÚmPAÄ ¼ûŠ}‚ZyŽmmÒìówš´ÍN"3‚ŽHèßóŸJ$/µh)¥Q£¡Í˜¢Ì8q¨«ô̇C\˜Ál…ZŒÓ•÷ §•oFuóÂú,¨S}ùC<:"ˆÝ�Ô�˜¬�Ü Ù·bѺܿ°öøDµFØúôŽÉ_{ïeÁôöŒ$uF‘Y¬+nŠHŒ¦pH¦&Ëx'È¿9]?éõZGf¹ô^„iCCPICC profilexœ}‘=HÃ@†ß¦Š?T-(â�¡:ÙEEkŠP!Ô ­:˜\úM’GÁµààÏbÕÁÅYWWAüqœ]¤Äï’B‹ï8îá½ï}¹ûêe¦Y1@Óm3•ˆ‹™ìªØõŠ !Ds@f–1'IIøŽ¯{ø~åYþuŽ>5g1 ǘaÚÄÄ3›¶ÁyŸ8ÌŠ²J|NiêUò88Æ ”½îóîîö¾ý[ÓìßYnrœ˜šæÙ[iTXtXML:com.adobe.xmp ç1—bKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEé  «$É IDATxÚì�wœeE™÷¿uꜺ§{¦{BO  ” 9¨dTD\e `BY¦FßÅÈ꫾»Š¨»†ÕÅ…!""’—Œ30=Óa:ÝpN�zÿ¨ºô�fúv¼}ûù~>÷Óùö½uêÔ¯ž§ž‚ ÌÔW.¾œðh:mÐi ,VɰBcÊBãs„ËSŽU¤pôš?}ò*¬²XDæ¡¡ d¡�°(:; ¬Â`;ƒ£÷`yö(“ÊK_j/¹÷+‚ ˆÈ ‚0{褓K¼�~ÌÔ'mó3ì• Ôw²²¥“NÑxAA˜U†¼­Xð߈Àª+¯D[®Ô?†ÏÿÌ/ ÊßeÞÑ\‰¦ÓÊ&_Ä’a¶ Ö§snŠ…3NÇþ–ï„1êÈ”& 5ƒ‡\¿Åž(¬ß ‚ˆ¼ ³Å”W ¸òÿÙU§«~~»c»»R PýÐE(î¿ÄÊ€ ‚ˆ¼ ³Ç”·X…êÄ‚…û¯²Cdöi‚–TA@ òVúŸwlv®é”û_DäA˜=–|gÀUWt¢Tç%Š5�Á‚lùÄм…ÒÛúî¶§ì<†TLÉ“„FÒx:­:ï†ÿ${î©‚L)8¤LJL€öp²½×ߊR‰ŒZýrxÙÝË;>QàÌRQ½ï¥7ÀI÷Ø+ŸYsñCœýçÕÌky�¯œt:�á—ÕÆlÄŠS»lçOß¡Ì#‡òdt†½øØ Áà’® Ýù¶ô²«ÏM9k/9¦™CHÐ� 4œÐ[¥:ݽ}ó×Ô®=›Â;S•d•Õ*Ä�‚Մל|Î[OåòËc±º¼ˆê´ÂëùÜeßáüy%ž|ë‡Ô ]Tú;Åôë½OÐþ�{ùààj¾û­cÕ[ý„ËÞ¼I^j‹„|+ÓÅíå'xÆìª]køÒ¯_f3;Ü¡¾{þZû³ÜþöÖèÛ"ò"ò‚ Ìb…pEpî¸#¸úÐÏÊÄê …Å*H, R«ºº¶³{¾ýIÛ‹R²è Bƒ"gò‚Ðp‰âª«è<ðWÆÆú¿ŸW.¶^+J¡­~†}d°¡±‘3yAh(�Gu^Ò `_ÂIÑá¡!%«Tj­ mFY ëŽn”AyAf…Æ£®Úuƪ¿W~áÀ=rCÑÊTœª4«²�Ò€Cˆ:ĨB[=—_ «šáðêï¡üü�Œ´ ˆÈ ‚0:Æ*«;Äö6³çNÄ:VÚPi” lŒÂZ£¬ÊYvêZ€ž­=ÑŠ€Ky_åëÅŠ%]–.yAx~¾†Z öá÷‚ĺ‚0馼Âvtv?bÞÞß#÷È•èøW`~…J�þÌÕèøgè«…ùcyÚãáÕŸ‡�§hÞ&ƒ,[ç«�‘Qa EÞ�t�–�N‚[ õrŽûQÀ£¿!°¿%°? ó»›3ìuå¿‘KGù}a·…G΀/É ÂìB¢ë¡ÑlùÎN÷Ù'­:ìJ[~ª‰K©ÞhѤ(›`ÿ÷ˆ[¾ñзÚò y·ƒüqŠËW}Ç\öž€þ“â* YZfÓ]ŸÇúlŠHô¡ Ô-exú÷ð5€~ßʦ¤±� ˆÈo�K׉Eࡾù#ü ÷AD~L Ê� ‚ Âô gò‚ ‚ "/‚  0"ò‚ ‚0Êœ�¯'é©VˆÈ ‚ B� Ù+§JKÞÑòIxºXD^Aê€ ³ΰò)ƒŸós…š?Á§Ü "/‚ 3L6»SSw||t·Az …Ë•ÊÌ›‰×#­fAa2>ÒóÊñÓÿŒ-¼zZ ìæìÖÆ •âÖRœV¯BŒKN¦† ‚0›QÁ²ùVÛ mZü0lX8"ðì˭忘æv´3)ò Øø°œ ¤‚ ÂŒíÝnÓE—•‹Ñ{�¥`ŸO[ϾŠ+ñÞÐ"ß ü?à·À[�ÿ^„+{+‚ ³½º ³ô2Øø:ˆ�AWÏö›Ž—7gò«�_+ýÿO�—{kþ+ÀU0½g‚ ‚P+óæµ· Íû µ÷¿ 6µB:V�´fšÊ¼O›%„-ArŠR|Ø®jƒàZW¾ø4ðe/ø‚ ‚P—dægÚ†‡úÞgíƒo… m�ŒUà-pðhȼ ? ¢¨é¤Þd-{³õ`»Øwfq%ð2Ä}/‚ ÔQóömåþù¥Ö¾†�©Eàî�6{:þInÞÛÆÅ£S£�Z^àõ,.ÎæÉ”Aê‚׻µÅë:±ÅsÀvÔ £8 øË8þí¸³Ð¦\äµþ„Nâ»ŽŠ“Áã¬M—Œá*ÿ†vĹï ì‚Dß ‚ 3ˆR‹ÛʦõãØßC kÐ¥ŠÀß<Î=î8µ)ù”kóÖ<°‡u�vQ- ÍÌU87~V¦™ ‚0ífXzχ‡Î‚�m5ÙMTà'Ä”‹¼5·*柀ù1„¶–qÅåî\| è�é&‚ ŒG«Ç'ð ©4¾›œ ý k<ƒ?y¦~ZDÞ½Ëu ¬ÿ6¬Ú : Jk| �‹¸?øp4â¾Aj•£Z>Ó±Ô&ö#iÊ;�%`kø×¿›É7<ÍÅpþöªc;Èü(�cÖ¼¸8›ÚÜÿ‚ ‚Pƒ¿l©M:> ¥³Á.¢¶3ø3q™b3ÊôW¼³€¡7�ÚÂßAP«û> ì|Á‹½äÔ ‚ “J^-YjÓÜE¤�Ÿ¥¶qüUõð>f¬v}šÚ§`»WâÏ@.©Ñû®�vœûþÀAHÛ\Aa2,x¥—–ô¦óI×� ƒm5ºèëFàgTäO” ë£°l?È_ªV«>á…þB$ú^¶Â*‰_„1²P‡KÁ¾?MÒ·B¹}6 |ˆ|…ÇïWªåPožªñ�C\ýÇ€oáÊãŠU/Ïò˜•1„1ˆ‰Ú~iOš»ÈZûv`p$ðmàmJ”'‚Ð�œ»Üt<¢j8N·À¥À'¬�}?ëEÞ]‚¡!ˆ/F©½q}{ÇÓÕnwàSÖòuåvÉ-$(O¡AP¼kÜt-< $5 ül´àG䟽éC õJà\j¯¯�%`O3qù'¥Íö8—¾ ‚0«þìU–57ÁCËæšÀ7–ț߄`_PÖ×fÕÛfH÷°Ö~ø °PnA„ÙG¬ÈìŠå÷ÁCËÇ!ðŸœíßp"?BÚ öß@­Æõœ_SÃGÀR/ò?A‚òAf‰åŽÊ(½[bŸù é}ÿ ë²5žÁÿ—R\Â,ɃŸ£"ÿìõ‚Å?†¶·�^Sã¸Ìþ8Ç-‚ Ô-‘ 4«k.Àš3¡ÔRc-ú” ßi-q£ŒÈ軾ÑBïc°Ó«!ó…Ú6„ÏÖ¿ï®ðŸKPžÌ7AêŽVñêÔpAêz»Ï§¶4¹5À+­MJ²èÎJÙ û~|¼Æ?ÔÀbàÀÏ�SqùBm„¸‡ZòSAÆh”õ¯.´ãøWƒbYÍjþÃÁ_€í¿å4§&«¾ Øø:ð`‘ÜW5m”vÞ H�ƒ/‚ðëójàB\ Öx¾¿gºO¯))ö7ìøuˆL�)–àJêþ8\kLã¶× ð,àXjëø$‚0E¯Ö(Õ¸?GE,?/£¾Z¯U¤ö:ÍÀÀ÷€wû‰%l�yÀ^äWù�Ѿ²9a’þŒËE¯Ö*šµ�+ðsVäÝ%þK¬Tz*.¨®�Úó!#`G\.å·½pI`Ù–d€=ü{/\,Ãjàh¿QA˜ˆÀد/­5| Ü£”:=µÃ›} æ´(YÛ›hø¢r)rk©¡ZBÕøµ'W§!Ay4®µï«€—âbœëþ\ƒ ±æA˜ˆÀ¿f¿8ÞÚ´{. Öœ·< Ö(ÅÕ ^ \ ÕhÕ+ �K¯ûoÙ/’›�y^Ì_Ë–gð•^/©ñæA¨üG¼À·Ô(ð]ÀAÀ†¹2`â^RKjá^àõÀ§ýN¯ÖbÚ‹ûû�kpÝíæª¥ûoÂEÕëQ7i‹·îW‰È ‚Pƒ^í\ŒóšÖ*ðpLŸœkƒ&ŒÐ|—Nq 0LíAyM¸óùç1÷‚ò\¬Âëqér[;¾ýÏöA„2¢öõü«Ç!ðχÿ˜‹;#aK ðgœ+è @7µå…À œëþ»¸Hü¹Rÿ~!p .N¡uónœ;©ÌCA¶Aä ‚ & ð‡ÍE�‘ß6=ÀÿÁåv?ŽsßÛǶ8¸×7×àcÖäoÆ3€å/0¿r8—þA¸˜qÛ ‚0šŒ_#Þ9�?f® ¼ˆü “¿ÃåyWò°Ö ¼,.’ü2\µ¼… *h.øð `o^Ø ¯€\qœ%"ò‚ lEàÞ…+'>�?xx.¢ˆüØxWpáýþóò8¬úîœú7À{q$¹šG‹q /ÃåÀ¿ÐÍX)*t.‡^ÒéAmÁ¿o‚ï\Hù±Sþ wÖ|3.ÕÎÖøYàE¸ŒçáΉÚà:TÄúµÞ:ëûÑÀJà(ÿwbÍ TÍUõæžÀŸœŒKÇ�‘ŸRàn\PÞçp9—fx{à�À‡€×1» ÃDÀ>þýì>Ž÷‘Ã¥µ¼‰´ž+ôøÍ´ýܳàÇ#ðOÇ‹À‹ÈO”ÍÀg¼åz PªÑª×¸Ôº£p£çy‘›7Ë®‰ò–×zK>7Î9¸+.o¾–Zhlg¤�’�ï9˜ãó?ƒ+’õ>œÇ´V�_çþ>¹}Dä'ü W”ዸûZ»ÚåpÕ›Þì´ãpnëÙbÕ·û×|*°`œ ”òÏs Îu/ÖüܵÜUÕ|ø.#e×9"𕣫st]®üx]ôë€�ûåV‘ŸlºqMnÞè'Z­Ay´v,ð \ÊÞ¸t´zÞÕç�ý�Â7Ld.Ušý6�͂дàÊCï2ÇæA8Û¯%ËæØÚ\mÁŸÌØwG ükDàEä§’5ÿr` ãKµkÂE™¿çÂ?†ú Ê qåj_�;fÈL‚7W XJÝÎ]Úpi¦ûá:;Æsè½gq™)oò›ý¹"ô9/ðïǹèÇ#ðoþ*·�ˆüTc�G€Ó�Kqu’“­úWîuÀ¿oðn¦ŽÞ§Âåú¿ÂojjImy¡�Ãþ¸b:ÒÉon0ÚEÿUý¿ƒ  š+hœ7lW¿Ñ9Ó }£Wƒl÷â8þ)/ðkäV‘ŸNúqåp_‹Kµ+R{Ný<\�åópùùûãªçÍôõªxÃÅ"¬˜Ä×ø…î¥þyµL¥9±1®Xð�¿‚¹yk¶Rù±u”Ð7¢g«çš÷þl/ðVn¥m[OÂäc€[½Ð¿WüfA ÂU©”·³¿vŹ/ÿä=ñ ΗÝqUíö›‚ù“ÁYêßç ÜÀ oÉgq�«‡âú<Ü3Ç!ãßT5.­¸ã0€Kp¹ß¶Ž¯c-¯m_à[¸ Š¥~Ôê¢�K¾.¨Ô¿®vr¹Æ¿×8×ø‘~Wÿϸ’±µìz's®,^…sÓç¦h±èðÏ/¥n'�Uõ6Ž}øÎ{ó=àö­Xùs�&\­ˆÌ¨1ªýG¨ïbQµ\«<®Úg×ß"WÃû²¸ôå÷‰À‹Èוú÷GWQ{ô½ò7Æjà=8÷ýq~<].íÊ‚s4.æ }ŠœÊqÀ¡~·/gó“Âcõ¸jà󸬒'ô¢·µJ‘•ûî¬Y ôc½¿+]*_Lm±FÆMç?�‘¯GÖã-\‚sE×*ö¡·nO>è­ú]˜žú÷•r¼gáry§rs¡qmh�öž±æƒê »ÐÏáWàJEß>‡Ç%³+~ô¸ÍÇÕÒø0³×Ã¥üý| .ž§¹FCéA\ÆÑ‹À‹È×3¸r¸Ç¿÷_ךj7ןþ�¸²¸‡0µ44.ÂÿL\àtl**y³û#Åq \¼¸r[ðÕsýаj+Bÿ–YjѸ`ÚOã2‡jÉÈ©ü…¸é-üd øþÊ�Þºßn ±’Út’ߘ´MÓ⢼—b2Sô„úXoÞ¼ø.�t._ÛŠx¿˜±µf®ýųȢpg À_W£A$x$º~æþ.å¨õZ‚P´·àÆE¨®~<àŸ{2nˆ¼þÓü¦bº6…Ê¿·Ãýûú®?€0ûD¬šspÞ§Ÿ�á!òß:Æû¾"ôgyc᳸&YõjÝV,øOá2�j)U[-ð71· #‰È71ðCÿñtœë½­†ëR©¿ Îý¹Îz#°i‚ÑscWsÀô»Í#\ó›£�µÞã!®ºÙË»½À¯ñV™06Wý¶,zËH7Ìz»7&*ðÿëþf\$¾ "?k)?÷7ÃIÞj®Õª_Œ+*±£·~ �ë·“·Ôÿ~\W½�gx#X ü;wt ›ÒÙ�õ×îõÞš»Óo8šg©d�ä'xT,úóqµ3f2¯"ð—âŠf‰À‹%/Œ"õV÷�¸ÚÌá‚Þöð‹APÃÍÖ ˆ ÊÛ ø\ÉÐmuÈ«¸Ù^; Ðd¡½Wâ(àQ\ ¢œÍ׿5¢ø{pÅn$pê¹›éZÏãŸo¬ÛpG"_ÂÅãL÷=R-甾ªœ1[žÁ‹À‹%ßðVPYúMÜyÛïqgnq 7o¥lèJ\7»�úÝõ2¶DW± Žõ ôLºéGÏÑŸtºå2gëVÔUÕ|9W�þnøçek¥l'CèÏŸ�{7ÀÅ}fœ®’�¼Xòs ãwä¿Æ¹ñOÇumÚ‰‘nUc½ÛqÕ¢VàÜÞ?õ^‚BÕ¦!�‹¢ .Z¿žºÀå¼Wbïá�³ùúåP\«ØGp.zø­¯»»2¹=ã«…Þ_º§Á¢¯øSÆ!ð÷FÒdEäç¨U?Œ;Ó|Æ óë¼·S[P^çö_„sßÿÐïœûüÏWúç>Œú«2øìoÞ‡ƨGöþ—Õñmøç%òVüd÷f¨Ä°¼Ó¯ÿwŠ…~2þ|\б¼ˆüœ&ÁµW¼Ò[H§Çû¬AŽpgô'{Qÿ1.À¯àoÒS¨-XfºÆ�ƒüfG…™eôy1p¹•+äúl“,“s¿-¡—á/M‘Ðë*�?Y^D^˜8)ÎM}‹üq}Ý÷õ7X-Ay-~QîÀµ®}àWÏ5±•_TŽ~ƒ‹Qk¾>xð /$ÿ)‹ö Î㦶/CEèÏÅû}e’…~´ÀÏ«áoc\0æù¸¾2WDä…*,®{ÝcÀ¼Uÿ\ŠÙâ�JýûÓ€!j«´7S‹c+Î͹®PF‰´ŸiöȦ¸Þð½2$Û$ò›¢S¼¡®ý»ý=òÕIúŠÀ¶Ê‚�‘&™Joåëq�h¯÷7Ü.¸¨ÝZ‚òZ™=M`4î¸áåÞ“ñ™ 3²Ùªl8Wá\ó!.ЫG†gL"?U®úçú÷ø¯'*ôÚ_óÏãVÕ*ðw{�¿]~ú�t¤ÙmÕpí¿Š;{»‘ŸŽc1˜-4G₵Lƒc.x3ôüF’11ÞR¶“!ôïõŸ�ç~¯üpñ@"ð"òÂ4‘põï?�K[zÄßH�èÊqÙ‡y/„0ý,òó,ãþ¤ðX×Û¿A�N/jµÐŸCí-£«þ8jëeQî�‘&FŠ«dw®}íeþóÍ4fpZ+Îå¹;rä4Ý,þlUxalD¸J’3ÑðIùkw. o¬B?Q�¿WèFÎàEä…I Rÿþ*àFêß—pޮƕº­×”¿F¤E¿'îˆhƒ IMŒ§µìd ý"/ôc±è5®ÅÇ)ðÞï?–åòÏ b5¦U߇Kµ{ xWjr�ÄÊbuðK\j¡t7›º±¶~î|Ñ üÿ ~\äpçñQÜ;úëúM\F„݆À¿|œ¾·äEàÅ’&™JýûG�¯ûõ¦§Ìåt.˜{ãŠã´È%ŸÒ¹4WÉîoÁ?!Ã2.ƒjg\ié™­ý€wlÅ¢Ÿ¨Àßá-xxyaŠ1^Ø|W¶‘,ÌÀKqg†2—§†y~£x®ÙÌZ’qQI�ËÕÑýSú·W ½Æ¥â^6�?ø»¼ˆ¼0½VD .ð¦ÑÞ×ÀÁÌÜ9g£¢€ù¸àºÃpµèï’a73}¿-¡¿x›_võüËÆ!ð�¯ÏERhüÅe/\�ø�i¬ µJƒŒ—ãºõ=…”º�,òÀ§qž’ø…[¿˜¶âz/DuøÚÿ,ñ¯ñ`ýÇJ©Ê‚¿K^D^˜>4®ûkpîÖ\¾Ç<®LèKp׆�R·%\ ¼ ø.ˆS˜Ø:»S_Êv¢BÿnoÔ¢ %oÁ_ _¿–�иÖC pð Æ_éj6ld–àÜ‹Ëü×jÔƒQŸ Ï?g.ýò4\×ÛdX&L†©i-;Ù×¾iœ/.zya†–—àzÄïÔà׺WjóD¶wP]o]Ø6ù9óàFŽI!‹‹kˆè=•€[q…nîÂÕèêq×7îæm¿XD㥸ûÅE oÂjy ×±o=ð´ÿ¸èGªoUo€¬à q¥Oìparææb\}�FYo‹ÀŸq.úûDàEä…é_´—àºÒ�@m½žg3Ö‹øõ^ä—àê„¯tÚ+úÇFà!ÿ»kq56á ƒ úÇóýµ•ïÍJ:éT�tÀ›½ÀÿÒ[ðâõ˜"\0[3�q\$/"/̰À7ãRu^‹kËÌ¡÷¾È‹ùOpUð*B•Á=åüï¬ð_/ÅD-ƹT#\g¿~\}�u¸²Àkýà!\p_à7ë«ìuÒ©€³€�áê)\#·Ñ¤’Á¹êÁ›VÄyx.Àu¿�‘fàzsFsè½WÒ”^ ün”—�.ÿùZ\ÉÍjoíÏÇ(.ö€Å¸¬„íª,±×øg=îH`½<ËoŒت×gG½ÞçûÙã³ •RÞ‚ÿ8.ê÷r M:õPÊv2Hü�Ÿë"kêC“DêˆO?.ºü5ÌÝÆ-°=®.@—㱈gŠsÓ÷òü%[›pUÁ–xoÀ¿!8w,0ß{Roí?éŸïI\ëßʱÀ?üÏ·¶Iy>ìäN”€KœÐÿ³·àoÇÚÉ};¹h`%°3_Êv¢”�5¸8—D.íy›Éé?µåç¾qc� ï´288Å‹Î\MËûã\ëý“(�Ãþ±n+â\)ºW—`¾ßp-öÅ¥÷µyo€ñ æ:¿`®õž€'pM_6ø Jaêìø”ÎNN÷üßEà§ŒJ•»F¨O‘ÇUÅ[ïçËdÞ[Âlù C¢lié¯Ï9©tÊå¿’!ž¶Åä\4ýjævj¤ÆÛíí-詎¢·þ‘â‚ù6neùGwÐá=Kp…|Žñ€/¶%oíWŽªcú¼W`È[T[ºü-ê’K”BY«:/QÐÉ#'uæwXk­ €UzT`Õ«-ÁÝ|ß`DàV÷Ð IDAT§VäáØLùyû1?çþ[„~ŽŠü!}ƒé[òÅøëš?þµ· ú½ß’I0µ8—àk©¿ÚØ35Kp©ƒ7ãRçf²Ô­õ–{%XoðÀVîÃîH`�ýËp9ÿûàŽ_ZüÏSF¢ÿ7àR×ù÷ù89º¿Ñ‡ trk©ó’N6o�ÎØŒÖÚvåÕyÜXÔæ»Šr M™(Σ>KÙNä=->êçóUlà*Ì‘0EÛ“}`½ZÜ¡dLùM׎sÑŸÌHš˜XP®Nÿ^¸sñB�ÏäJ¸»pG £7.9¿hñ×|™ÿ¸+p$î8 C™`¸¤ú ïÜü.¡;°Ÿzô•º?‚i_‚± †…)��ù>šXlø)][÷öµ ÁÖœe@§¿§~,B?E¾°Û²á‚ÖÌcRåpŠÉ1’.·œÙÜ3™Ö|›·¢ð–n½/BÛÚ§ŒÄlë^n×–ÕFF/ÓE–XkWޏ…pÁ�ƒ'ç×X½|¨I}Œ’íÓƒKÜè7DqG©Èâ=þ�f£zÖ¿Þ\â¿¡Ÿk"ýyïH66åõ“wߥ¸ù~å©»v«�ӽŠ­V·$‹;ï¾çÖ®÷çDÈè2Ьš›QÉ@KZÖý+ÿ–.Ý3aIÖ ö$ûà}ÃÅÛ á¢é"‹]�Ëå^0ʳ°É ~¯÷0tã2*�€„m‹ü! |_ŠÐÏe‘ÿþž»Z¬MÃîaᩳú㺄�Ë7ýs¡¥^èðBßø P%1a/'°éÊB˜ûdq¸¸þL”É¡vÙ'3Üû“röº¡¦D1lSF²2¸ã€Jšà?ÏvÅÕhñ›§J†@—ü?¾}þ±Ù/øÉž{‹pñaƒ¿ÏŠÐW\÷ƒ"ôs@ä7yºÍ]ñ¹ä¥½mö·2ÆSA³÷W᪷‰Ào�w.¿›·B¿€Gℾ“æ7±}!(]L1.ïÛÆÍóú쫬 œšgJ¥lê3ç¬ÿËw$°aÔ³j¿VD¸à¿ÜqH›_äWâR›ý& ñ›€ÍUހʆ W9m�±¥ n­{ �óî§”íX„þSþºüD„~ˆ<ÀŽ77Û}özL÷ƒSÔ…oüµ\ðÉ]@öÎðå~Û±îlþ.Æ^gVO X�Z™Ä|ŒmùÎÞ½ÑÙyÒ� UÆ�Å$c‹Jõ¾#Á�£ÉàRs¸`³voÍ.ƒy‘ÿ�#1ƒþš<ÃÈQÀ&ï h%êj–]†¹”éRúOûkuµýùòÚ!»fu¤J¹—(‘ŸÄ›i.ÐîHê»?u½ˆ|‹·ª~ï…¥¡£AãÛDfÙ0éEV‘#å?æ§ôÌÇd•f«HÑôe�áI ­/WYï¶òsí¾R>¸w°ÄÏé}ý÷´ß$^$?ÈÈqË:Fš U: &u(&9æ^:kµÐ#B?D~õ࣠ïÄCÍû‰+yò«xðJÜy©ŒíØæx‡ú ¸èñF^x: ˜�êÖ®@…ÊaLj�F©ÄÚ˜ÔfKÖ&Nz•1Ó2¬7„+ò³5ò~Ž·0Rû!öÕ+n­ÚØnÆÚŒ«¸Þý¤ß l`¤>‚å€ç?PUžƒñŒK¥”íJæž—­b„T,úŸŠÐ7°È_ó—Ëíò_Ä@Ü"£<9TRr^ ìˆ4ªÕ²Ú×XcS/:ó•âcÖ¦Í�ù¦xº’Ÿ! 2IBŠ"$P-µ c1u5ÿØàÅû4àg¸–¦Ñ­Ôhó›·E¸¸‹#üç•ÖÊ%\� µ^ô»€‡ý÷6âJ Gm¢%ôã½O_Bc”²�ˆÐ óK¿±¡o4‘èëÙÍb¶ksâh\„óë¼U#núÚÇogœKø¦°.ü Ò\h¡9À~'MÌz­QcS°%”5 ‹…Ô°6–l6`¸”Î’÷W‰J4?£DYûGî8`/úí¸2LJxO@“_÷ÊŒ´vÕ]ó .Fú 0ö`ÍÊÆ ¢qZËNDè·.õ_‹Ð7ªÈ¿øH»öÅæÉâgկ܇å��JŸôS€—úL6Nµ�á¿Aºx”ÆjÈÒ ü ° \é3ecTYk4F †b“DþŒÁj“S²zúÜõãõ±þn%; ÄÖ» †^x³¸ÀÀ%þcÎ3V‰ h©ò*”ü&à1/úOø�ÀFïièµa ¼'á æV›ççú¼Ð[àW8×½ÐH"î‘%®Ë­åÑð/\-c= ípàÕ~wÈ�LhÑy‘·Üå¬0¼Øø�ZW.c5Zƒ5ú4iÜfÐÛ¤ócRkH@7)SNçÈõ¯NìÅ5/Mž‘‹q�d qû{¯@Ö ø°únœëÿ¸,�J"¹OGî¹Ïø{í×"ô &ò_>ñ*vŠÕÛXgEäÇ}}vþÉ[r?±g�·²n§1܇9à=¸B5WÿÀ8/OMZ«^Czgdn,Çáa)Ì·X»‚̰¶H�Ù* U–ùÏs?¶ââàŠ-U ­Æ�E/ö¿#PVûþ®WÁm⮯ å�Óqér9’ “Å�Ïîî­®Â,/ï®ô–deÈhEÙX2Zu55“ö•¬ U_“a¶] _Øš7`k1Z€ÅÕe�ú[ ýŽUýoDè§w𧌿íy–-ô.³dWÈH×N3p.e®Ñ:YÍ䯩 çz]6‹Ç4 ¼Å}%ð·gbŒÕrA�/1Vc°X›! L…–ØŽIž[ó��ä^ݦÐ×1³Y†¤D଻²é�_ò°zé]GÈ‚2v"¿€¿X…¸é'�;Ùm–Ž«Æ�Á„K/»s‹ŸfP:B4˜­QŒ%gP¤@€¡4€Á”Å»6yTŽÖš�ÀXú¹$ò{mXÃn;ÄôîËh�ýšì„Ë> $L®ÅµwŽ=Ûj‹GÀ;p)Z¿þÂóÄ”ÁR4©ß¨Ì@Ñä‚”0dM–l©ä­~a’D~$ª^„~®‰¼Zõ;—�=PwËh�M€''à\˲OþÏÃ¥Ó­œE‹²Þ ëþ–­ ¼Ñ˜ Œ±M+¨¦&²e’4$PeÓ ¨DæÂd’¥ñ»ÎM¶Ð_ ç½Âlù¶÷þÀ>¸à^kw�Ñ~aòÞz?Ýß¼35h\ôþ³d#¥p�Çåÿéù,xŒ±Æh«5*CF° 8¦O¿1O²2%±‘UªÖd›ê5G~6®£¸èz¹gÇ~î|^„~–‹<@ü—}8¸´ƒX¤Û&Ä�¿¿—.'n¿©%‡sÙ¯¬c‘¯¼®Óü¼¸¸é…×N òÁw:£š‚6L‡ ÒfTе-h¥‡Eà'ñÞÝ©D9¡_|A„~–‹|¾7%4r&ÿ‹ùB\ûØ£qîdÙMýÜß綯׸ë¿3€ëqÕúưræFæN.¢)V§��Q F—dLRÇb¢BÿEÜ¥ýlù6}ÞövßÀ½�¶Špm�&œ+ö¸ÜxIÁ™ž�U«ùzmøs,ðvààŒ¥x�FE™!å>ÕPìOK¦Ò�MaQä36 ±dC••À»É ç-yùñ ýNÀ瀗‹ÐO.Ó2)?÷ËŸS,íFw®øõçNð}pg®«¼À§^„T•E'‹ñÔlrwÄ5/Y‡«E^.l¼ IðGFÚ¦ncljÀd|%;clå�Ø`mŠU6&Í¢‡käy2îß•¸’·²9Ÿ‹þ"?ç¥TÓl±ä¿{ãÓvA²Ô>½ãBñçáÒH�‡píPïÆµÅÜ„«�Ý ôáfÄþ‘ø…?ÝŠ0ÉYëØÅtpõS§Zàï~L�•g50šr•€§hBP¨Ô*; aX»I$Løþ݉¡™,¡ß¸ çÅ‹~¶Xò<ü&^wHÀñ2æÏ±½¼°ÿ›ç&/8 ü¤Ïà\øËÉ)�‡Ëõ^àÿ^ã¢Ä›üsXFiŒÞÐ[Ù¨9~l‡+uû3_nó/ðÿ~Ä8JË»B8e‹F¡5EŒíÆ>T@íÚ‚ šÆh+uë'Eä%unò-ú/®‹~–ˆ|÷!‡qÀOʨoIŒ«£¾Á‹mÀH3… ‹übàÜ‚-^œ¿Xâ/À�3¯Àò)ÿ·‹p)c¡ÿYZuýSÿw‘ÿX-ú£?6⦠2ÆûúÍÖ#ŒÕ5>ù œ‡ëmþ=ÆÙ;¦¬�ûKƒEkµÑsOÎüìuEµÚÂ!J-ÒæÉ0�Ê-8¡¹Ó‚kN#"?ùý«„¾ ÃRç"ÿÅ®ÃÔ«n_há^õçR±¾ÙÊÂ^ö‹Iåç=U"TYæTid“z‹¿Ý{R¿ }w p‡öv¿Èø¿kòßkªÚ4{Ï€­º ÃçYôfã ð–ü^¸îcåx /ÎÇõºÿ!îhfË£VDFå4ª–²±àÑ¥í�y¢ß*?½J! dµr]j„ ¬ŸRÊvj…þóÀ…¸Ìúzùnx÷¬Êª7¼Š¿vüBÎŒkßlmC�nÅ+0Xõ{=U®“ʆ  xW÷<ïo¦ÔœÏH©×JZ_¥‡vÅjYä¯2æãŽ ª7ùª�IàO�Ú líó™´È–â ÝŒë>�îÎÞ‚¯|qB«cll Ðé|96 )  *Å€(‘Êš9)ëç>UdaòÇw5îŒþ}¸’‹]¯"ÿÚöçºÝ†Ôoæ‡"ð3»!H½· ´‹µgÔNºZ€³Œû°^ðç3Rákžß´øïU¼‹ªD>_µi¨Ä4ùß­öÓ¼!¨¼¶Ý½ev‡Ú阫;ñ‹ <ÆX€ Zbã\AÆfºHB )Ö†!Ê$Zîʼn‘Á݉«~òI¼ —qG�gâ’»‘Àâúù«^œ·Ç{ =¸ZF¾þ6£¿mÉ–Ù2(­·êó Jì­튗ÀxQ_ÀHà`8ÊKTy Zýÿ®x Zªž7ËÈq„õ'º!¨Ä;„sÙ¯Ÿ†Åd;à_ü¸~wÂ_Ñy¿WÒFSÐe (“ÓAiȦPĤùJ~C Œ‹ÀÏ×í‘R¶“5m+¢^Ã5`ú3ðW`#õ“â*"¿5.>?c�ÛhÔG/ßž3dÜÅKP½!HFm†G îÓUŸW[늑X‚ÊsÎ÷�Š…?¿ÊK ¼Ø·ùïiF²ÚØòø!?êÿŒÞTÇ:Tžw?oÉ?ÃÔ¹ì­ø�x�Ê·˜ÌâŒV…²Ï�ÏEº96´PPXHd�F“ ÑõZ;÷®Út µ‘V‰z w¬x«Üéï¿ê”a ­w‘˜×dm|ÂíðQø9¼!16G(ŒÝ®ªŸUùU¼óª¼q¯äÔfÙz,AG•—ÿ½¦ª×VI9\æï»q5 ¦ÂrظØÿÏË™ä!mLå,DcìC°_9srV•;¬BEV«a°&k”N@šÔŒ I�«}=¨vÉ[æ·{Qÿ .e´èE_D}¶ŠüO›Cûx²§D¡ Ï·ØçñTÛqîíʆ@áÜë÷}%°bÍ7Wy Zü@3sЊË.˜ÇH�` w¼0îÁŠWà2&m4Ú@Q§M°»Vµ[em cœ_þÉ·ä {׿ãö–‚NlAg•6{[#"?Q/Àß½¨ßü/0T%êâTj‘ø{x¿,*ÂTn¶tÃù�OAÀ–u¢ªçÉy±O˜šû…Þ‚oö|×Ô �­U�+™¡\j‚!•1±òa Êú·¥_8GÖ×mRèϧI‡ÍçŸ:RrtÔlVÅCRÊv‰íJüÎßpgêwâ2z6WýÜ çë�)ò‚0M›€ÑŸo­�ñ Nõ† gÔ&a²Xä¾ øîÌq ô]«gß¡ÙÒe!Œ�(*¨–ÜÁÀÀÂ4Îo —%[ì ö€t®§ÎUËpŤnóÂ~7.8·b©'"ê"ò‚0Ó‚Ñ^‚É¢ç¢_ |× g W^c1 #­ÄNŸk^acº-°…f­Ú×̽õóù‚åþì­ögpÇi7½ˆºˆ¼ 4<9\¡›Å¸3øuSý5ZŒ5@б±Æ±£ÆMG6¦�(Ú ÂÚC-fs°lØàƒ::Xn.HN‚åDäaÎSI ü®Èθ8ÓJYC9ƒ KRÞn2OÄ7žG,2ìú¸y<Üh§ –-‹Ðô#Ár"ò‚ <ï½u®øï3]�™Œ±e¿ö‹¢»Ÿø{_;<?dm¼: P¡6ªd´•uzKZ–»š0ê†8¢@lÉ·±~Ó+Ôàö'k¢Ýîϧ”Eà+q)e/à÷00w,'"/ÂsÈïôÿðL¿ �L&&–β/D±×íz€(†8‚ò C³ìœ„|{–Ì:…í›Í¢^]Yîqœëý6F*ËU¡Q‘¡Š¬·à�þ§^;qY&’¼¥5„ý»- Q¾ô?›´ódÏ *½*/Þ·0’Ú6:XNÎÕEäA¨¢:Ý.œ üçöf—Ì»…1�¢§)%ŒUHËKŠAŒN3]Fß{=¦ç ê·^½­²Öc —Ú¶ð'àÃH°œˆ¼ 5-ªøEÿŸ½Àÿ çþfQ„‚˜�žÈ@7¢4`Þ�X{¸bó|ÔÍðSg"_-êÃÀ#À}À½¸öÅEàcÞjß(WYD^„ÚÐÀ[�c�ßáú^Ïä«Q¬epÁuÍQ90V¡°«C÷;ré¶$׆芒<±Ê·ôWØáxÓf쮃–¤…¤ýhX̰\-ê%\*Û½¸ ¹‡qt•4•8Œ9_‘a\¼8¸¸a&S­QD(c´Íi£†¢œÊ¤CQæÐÛŠ@Û oQÃsø‚E* Q…ˆZçóÅ^LD«Jè¶=ªÃ_ôfÍò·§¤AÊ&=Á– §…J¹æJÀÜc^ÔïõŸ÷W‰úÖ*"HÁCyAÆ�NN¨�¯�)jkÈ)‚bœ.ŽwÎ’¬Le”-„vN[uqŒ�ãç^«–6tOW»¡}³¦ç¬ã5‹Î6¡ 1e«ì†aØœcê]õi•`—q=îö¢þ®(My¢."ò‚0 4»kêEà]W9­Ê X4*—¢ lKæEB`‡5HŽü–$ ¶§¥´>¡ò$JÞ;>øñ(Yö1C¡9U·¬Ãvï4"_,—àj¾WÎÔïc¤·zEÔ%XN‘„iàÀÀ7êÉš*`,Q.0hðÖj€RÚZe±6!µ-ÃÖ–Ñ*ÑFúÉû–ÅqÙÖ8O�~›DØ„Ï>Ekû:ÓsÎ�ÃØ{™Ä5³ú\½€ –«¸àõß‹EÔyA˜9æãúÑןHÆÆjœ€§`B¤±µ("PZ£J`çrð]Õ¹¼�hµ�WýMoÜKÏ;Ƥ\Këf `áÞ{�ºå1¬=–ñŸo›*K¼ˆ –»Ï?Äõ[¯–¼ "/uÂT´¦¥1Ÿï­15lŒA�µ  TÙ`Ñ­QsÑ’o[N4¸‘$)tØe;lˆžî]n(�zÅý?˜Òœ×¦÷5FïrzGÜÕ»�kïÇ–Þ D5ü‹ÑÁr�{1×[½‡mË ‚ˆ¼ £E^ƒ1€Á�Aë²*‚íƒDÙ€K™4… dCE©4'Å¥wý†ioÙ 7­ÍÇ!DzÿKYôbÓÁˆ¡í[ ÜÓC8?$)íý"o½°WÚ°>_°\Å¢¼ "/BíƒÍ U¬ÑZõi“öÙôûiªßv»k›HÔð0é\ ½‹ˆUK{A÷ôä“––‚6îøÜ»ØxÆ?ë´íŸ Oü†ÜÍkûmk¥›ÛcW1.%êIÕ£¬®Çå«K°œ "/Âd+¼7èGßiÍM¡yúì²êoJi -´à ÌI¡oié `iß9HzÓ(úIw~Cž‚¾÷g†å Xpõ—£¾ÈÆó2™ Ü¿7†¬êJ°Ü®ðÌ=ÞZ_‡«6Wiî"¢.ˆÈ ‚0…jŸÓERÊÆšææ ,—U*D«áI0–¾¹9:=I”¿s—°xйI°v}þâG‹[þÒUøsbÂ䲨/*uÃàvA™p%$¸óôJüÃÀ [6v‘suAD^„©ÔvcµFa 䢀"i­ @JlS°‘‚†SÍÍ–7oÞ9,öù„–Ò<”ÏÜ´^ÿå{ä×=³")¨.:˜·˜0Y¿))å’›ËE~�Ë_—`9aVÈB‘AéeÈ@1M3‚BN+rå@)çC.0Ч^àóíhZ :hÈï,^M–ðˆÖ°¼ïim�×}³%øG6Ÿ' �Øu1iÌÛ»žx€bÙîžÄ•�­ä¯‹À bÉ ‚0ݪ³ÍËKì¬ôe¥‡HMJ‘’`l–P•(5| ]a ŸB+DÔ’Å=zà¡…åöüÍqOÓÝ—�Ñ¡»÷ùš¥»?Í<ô£¨§#-°á9ÏÇ>QDäA˜iÊeR0hWâ–VLЖeER,+l‹u¹ýI£F\°ù|!èI°ñàÞ–p×ÖÅ ~Zàéöd€[žI)ÿ1ÍÚŸ`þ8ˆh¹ "/B}[òÆ‚Fk£´ÉPÆØfP‡ DgåIVeÉZ €-e[à ‘WP ξ}EÔsÈûáÞk7îúyøüõyÚ¢·ü�`]_”ÆØ¤ ¿ÐXÈ™¼ 4Ú="È4ù�ŠI´UÚBIÙ´%ÓðçÊ1‰-”߸Ló9ËvG”ƒü‚ Yùr‹sä{ Qo_TXH¯$‰Ü¶@Ä’„©¤=¯£�B‡‘‹an º †¼«%®Uh4b®=§žx\™Ù‰[¶+¿?²Ú£ � yÊX ØŠ±ÚXgòùå„ô’&‰{?ùÕ_h 0-{šLÏm”õN¨¢RôlÀô• äÉç»U>‡JHû{ÄŠDäaêé)˜�¼Š‰Ø%¶Á#ÅÄB+­…B¥e—ˆ£Ð‰{œ¸EÄ6•�ÝïÅUÂG‘"ŽÛzÕ¨HUL½”‡ÒRDcmеd3„Ãe7f!�“BW̧Qa¡…˜8ß…Bš�ºl!þÖµùrþ�}±UÆexìßÜ<ˆ)ÄØÂ(Û_Däa*-²<�ËT*ØGòØ| U OLb‰BE\°Ä±%BÑN@òP)àmö0QQŽlèiôÔ'c¬24.ÂÐ)h”RÊ*kS›–1ÒdŒß ìÒߢá©4Ê£X¼<Œ §ng7n~Šü’¦B¿-¨î²z·ßEæÇOµ´ {äü]‘„°Èh§µP°q{A¿²g~ól.¯[Œ‰#R’ÐRL,ÞýÆí=-$$ˆm�ÄÆ Š Äqd!¯È{qïixkÍ�Ê�ÑƤ( Se-”E3Ü„‚†MÃÞý£µËFý*¶A6¿ös%Ì;9Ž»ƒ€�Ïkÿí`wϺ¿E­¿^<�p`@ÊÎ "ò‚0S¶<{vô´œÓÅû›ýtºc‘o%ì«m0h¡ë�ý�^¼xg€y›7ÿºåÖ떮ةPxôÉõ]äãnHÿÎ@㟺æt�‰�-—]:]7˜5ÍÜ÷†¡à‹m×(•×}F7”5»0†Ai)ÏÜ ÒåËa`xf ¡ëOíí„=½y³¤½[è¶qYb©Z'ˆÈ ”µ´…ÅžVÓO¿%jU¯Š‡›N*%5ëÁ#Ê& œÖZÒ—ßpcúôê]u!›UÔýË–÷¿úÕ•Ðv ½chˆÃï¾;m}ìqk±' 8ní¢%Ü¿Ï~™pðæÍëo¿þúÕ¯áT8íñ›ïn ùBbI°IŒ É«K>R|°^)ò¡b1:ÚX0¦_+H•Âb2EPVϦ°¥XŒ]†À¨g¿FƒÁê\90)–²+Z@Æ(m\»Øª^rŒ9D@±ÜÚ>x^OÏÒ¡Þ1¬Ò|êQM´ã ™W@­k-'”±¤Úb2V—k²™Ì�³Ú ¶’“®›‡4€‰I1Z•Ë:Õh•aªŒv£3Ͼ¾±¢�54›2dŠše�`m6D 'zvº« ­„ù»U!iµO—Ò ¾ý<ÍòSm1NRZ¾æ¿ð£ùó¯6=³ð& Ãâ’Däa&È©ýö çß�pþ�lˆÕ@8éD:úûŸÚÖßãÚk÷øÈœÀ<ûýoþþ÷‡y_RýûïÝqåÓ yÇñÇß²úÑÇöÊõô¨¾í·Ët/X6•J\zíµ[V€´þÑÓó¬w`ùSOY¬_±·Ýtãæ"ØW™èY’~ì@ ›³isHWŸ¦·WÑÓ“Ð_3`ˆ‹�Á“³¤©%@�±è²òQðÏjzT®Œ*‚­Åæ6­â²&ƒVåŒS¦ÜLPè�ÍB ¤LÚT‚’ßÌ6ZZúƒ��¼!?FÏœv&,>5ÖöœQióÞ…$oé."bòùBÐ_«]‘„é7È¢�%a!zsÂÛwN2¯,RN (õÐA/1{=þØ?rÿ'MæÿûÚõ×-ý½ öÙû–½n¼õÑ€´írôM)iKÜÞÖz^OϪó�>:^ñÔ:Va Š}}éúí¶ †³Y¶Û°�¬Í†‰‰ã2I« 앆Va™o¬j7…µPà jó¦oˆ´ÛB׿b¼Ù¢zcÔÆØå�`z[[üF£hË&¥lÊ–˜š+Ö”)[MF´;—M&¯¨Ôb5CiVZ¹=˜%Ë ÑðúS2ƒáï-=A’¹PaCCïuù° ’B‡mY²Az%^‘„aO[ˆÎIx× gÄʨà�XÍm·MÛkøÒ�7ö\q–û—o¸a‹Bæ•ã€÷sL_nxÈZâ$Щn6� S•eÁ±uÞeT hV–æ,o²¨Å VacKRBP}Û õõÅ)Ý›-›z 7v“é{ÛûñàXÞ�"Œ*‚ÍP¦`Œm7èåüyŠÂª4€œÍ茥… ;Œ-Ͷ²¶Q«êZÇËÛmMO4ÌÎk~[z´s'C÷Óäÿ뺖GÚþ–øÛâ»î(§)óKS¨È‡�³©Z¤ÿŸ½3�“£ºîý÷ܪêG3ÒhEBHbK,Æ€F˜Å˜Ï$ØŽwÀ±ÁŽ_ìØñ3™š8qb¿$$¶c%~q¼æMljñF@Ø0› ÖBhiö¥g©î®ª{Þ=›EÈêûùÌg¦º«jºoÕ­ß=çž{ŽX£R²X@quQæ©0� è<Ð$*$ÉÚªÆÈxú&0CSèX_ÆöÇ–‰²05n™**cZÉ!ärNY‹E�$ÑYzjÈH‚*uj0Tgq88}5¢¿&“˜H¦±û3áWŸ ”«‘ÿà’•r¶ B’¨ã nq\�?Èâ|,óÜ âc�'�Í‘WÚ›�=BŠ^¼÷®Æ6Ÿµ7yèðýþQìð“õ[�¢�Q¢þjêã´ë¥¤"Ÿ’òâÓðТ¨ßÑ|è“kœ0oÃ}Ër‰ßK"2EÄŽ“OÑ}MM¯;’¾SIÉaáß6mzõ¯¾ÿÎ3μ¥þÞûzEl½B�Q§Î¨Ô«ÕZ[k +HÆ  V•µ J$ˆˆÙ¯ºJND›aÙlæ+*Æ*'P*C)It”HF*¥ÌXŒObFœd²¾–r~J¼z·†š¦Z“äâkŠÅKU!vˆ-L+L*LDÐ;g¶lÙ®^ߣذ%xÀó-I6'ƒÀ4Ή‹dçÉœøÙ²”_@¥;µÕàÃÑÁ| >á¢È0úá7¹Ó¯þ_ŠfÍxÝEQvâíaùÆ"þ=�xqQµQÚãRRR‘O9Œ„ (±O³_t®Ú›{Ó *רŠ7�êhӬ亇ÊðÐCGÔwŠMxæ ®¯ß»ñ¢�~rXð?¥ €÷�pÂ�¹G³µ¢õF%睊3ªŽE]u µ`"ŒTbk¡N Îš¨#ÄQh]”`5f:kÔ¯«÷‰3žlË%zàC àh úƒ 'ø$¯›mà8{Ä ¡Â”ŠLDhïtäô WœÇ·i¦ï¡z)'$3µì(ÇŠ›ðÔuþÏCäÍy‘ñr‘)¹E¥÷§+ÞY‘IA2™GkçÔ71UŠ#�Ò»””TäS~;ýzÁ‘?1­+(_ãb²buRÅ^32š9¿“ÌŒÏý…òÕG}퓚¯O¼ï„×û�òÈ…O1ü•ÿá?øú}ƒ4įUÍ;¸y'~“‰‰-‡DM�çàÃsúߨy�yÅe÷‰´Z¯¡Éóýü%pðéô˜Zò))Ï_㉘(aÁÅ #>¯YNù£ÙXüű°I&m©Ã�±*Q¹"•òÔï‹÷÷08ø¦âûþ‰ãÖ+€3’9³ßÎQ�øžu¸>7±RJ<¢MÒàïqæÏÂô��ÄÅ‹Ÿ—‘úFC.'þàcÉŒõ-qŒcOˆ»ç Dø.âniÈŒ�û‘ø„âÆàEžA#Ïp«Ö~tpÖû””TäS^ÉDy""Å å‘wÆŠÐ|:çØ†é„dLàš üo‹2IbAUsÁç“xxx�þþuO·ÏÌ@àtàR`õÌ 33˜538$äeƒ\ü¦‹?2å]öÇ-O³Ï¦ï=±fŸG±ç)¾/D@Z¿>râ8Ò(FÃг¡ç‹Q•xß<$C�p!ªÏBQÂÈú 13ß"õÙ§¤"Ÿ’.!QÞ7‰Ã•'Gqg-n¾”`'ù€&éýö[½6ÆT\�C±"`f °aæçðá–“¾�{ìÑÏg¯Ñ\ör)•ûž�7 ^²„ºJÅ`ÉÐ�õÃ�Ð÷Ù5gŽLzžÌ�šŠ?MüU3!q<‡“½ÿ}Ù¥ï˜÷½¿m„ÊУ9ʽQù‘K‰Øó‘ð‹¨O“Œø>ÄêÅ‘æñ$BϓȯZôé”’Š|JŠñ‘J´âìGʉ¥¯)/׌Œ9iãüö9œA8_èùåÛfþ|XÇTüž§ñ¬Ø?°Z÷»9¶|2lÂP®PͰ³Éݵëc5KŽúiM¹¬~jèû2œÏˤç À@m­{Óe—­8øüÇŒŒØå?¬•±o,ÉÈäìÆá»^óšå¡ëúû÷›ÿ£ï½oòµ§ëtwß´’A}Ì‹’/Š4¥‹óRR‘Oy¥‘÷�†ÍD%ÏÕPJ%ìïYVœ9Y�.šTË$‰^32–Þg/¬XuH$á¥�îà)�µ,8þnþx¼$'ÖftŸÇŠ«ø\å§LÍ;pÀm·?¥Jà•]t׉ûúN­ §�ÜÔ½‹9Ò46¦¡ïËg7nmÿÑÓ?øÞ¥cuLíÉR-‘xEÜ&žÀV�ÿåëÅÍ�ˆC82“ì ïÜH|bâ=éïz3±ñSÇQ¬žXFhõ<áþøÁ'¯ ç Q¤^ näR]ÕBXL“¥¤"Ÿò< öbhë=Œæéõ`@býC7ZrvèþYŽdÁ„¨N*¼/½Ç^:V¼2Ë¢*Bü€Ð²p>Å�]:Ù”PÌ.àÁñ IæjÃn°|øéŽÙ_Rø€ç`¢xãÐâ%K×­µÆÌúüŠãúD57:§ÉŸÎæÌt63¾nýú9Ãù<á¹ç°½©ÉPÍkD]T�x¯­T4[©œzÌȈ�Îfev±›8ßÒqSI�Ñpάޟ^vöšýÿwÎ÷~ôÞ�L4>)LfŠ#Ó[‹MÉ¡ óžÁu…‰Ðú‘§>y!´>ˆO,ùÂ0VŸzqg.È¡=ðC_#™ÜÒä'E·YK>”6ÔKÄŠ¬X¥šVþ%Âe¬¸þ{lýèþí×pßveø�òÜ%ŸMá^è+¿Ðÿñ÷·ÝvÞA›\ðW]tÑOþá–[jž²óúõ¼÷â‹ßÝ\œøÜÂ�A§fj kk3þä””jkMèûf¦9åšÑѧNüâÁê€ê¼óЙiÂlI¢7ÜvûNo"�ºé²7^zÀ3ö½\Þã&ã{cÊyêµ¹¾H ŒFذH>.žÄQÑFTƒý#PˆÈãI}1Æ&A‡�áì½ï�3›ŸçRŽúÜÝüáïÒrtÛ÷¶žYxàÆ�w_vð>ç ½'ýî¿<ƒ»þpsÝé§ß~ô}M*Ú0zì1sþäñÇŽßÿÞ§Î<³Ò84¤þȈ ›¤TWËȬYf{SÓÓ>c÷O ¿{·�÷ÐÃVÀ‚LYìÀ¾WŸæ>¸äèåû÷Í…á^)Üèïë½£wËúĽsë®°·”À€úõ‘–< UK"ˆ|š 'µäSRžEòzVXl\ãò™%ê?ŽØ ¬¼—(�¢ â âXH@#A›6Þ8êsyÿï :',&‰l‘Y‹F6Öþ�üÆž§®÷ò:|æ¾ûžô<þnmýï/tw¿þ³7>™ÿat€ÎSOÝ÷úÛïp[#‚3¾l¹ŒÎ™ãøaÕ‘þØâÅfÓ²e†eËöf€Æº(â‚înõÆÆTÀ¼fÓ…çŸ}Ö'>ðņٛ²{‡÷þô’Ö5¥“�z€Yß»õŠG(õoôÃið%¢ÅtqÊ~‘·´ ,¢¢�bÖ€i­V·TQ¥ 1?ï]²!Þ¢kå*!®Æ~È¡Yx›òÒ¤%—¡§T!ßdòÅPݹ¡óêñbãÛ²üusYŽ'IÆÙzæYÓÜsOÚ^/A¦�]žuߊ<•ßjwššNæçw…IóéøÇÅãÅEó·�ò+SؾÄ}�_èî~ý3½×ñàƒ l(|º©©û³7¶¾÷â‹ß}Úý÷ÿÑ™{zëGÕ´gîÜ:@æ‹ê‡¡æš±ý+Rf*®_àTׯøèø¸õËe èR™üÚ•äC¡™(Qì9áøÉ{N8ñl€¦ïïš.Á¯1ø_ª£� G/@¯Îü«Ãœ9†¶'ìIX$€´¶bº»± ÚÕ%¦�6hþ`õJ ¶*m� ›%  í…@¥+ÚZºmt<Ù F:±@GP­–°?(D[趈ª¢²ÿIµä�ö7@Q# è�ĉРªè~�¾(Ð)ÒÕ"A{›îUqnbQ Šér�#ƒçì®_ÁÑÎHýN‰¼ ó®œoGjÞ9éüåœ3C¬Žº±¼'ƼÒòˆË]�”ëPwP¸ÿ}úÛu×W-úU_¹�‹ÚÏâ»ßý![®úÕ÷_+ôž$|÷†—ˆ»þÅâê /|@P÷ŸÖßzòþ×ÞwñÅ�_½ùæŽ+/ºè®ãžØ¶²þ‰mžAœñeKe´yŽÎçÍ ë×ÿÚ>÷¥Y³“pvMOìÐÏ¡£§â$ï&.zH_Ý‘`z�Þ,vG/^=Îàà²ÒhûW»ê}Ëç.)Cz´�ÍR P5 é˜åvCO›Ã@³Õµ­ t A€t¨Ò9£-Áé>PEY„B‹h{� Á�II5äŲäEEº (mÐB*�t*´ Ú�+5hïÑ–.‘ �T�trÿåËV¿¤”f+ùayÍ4ÙwÇÞ'óD«Æ�D+‰Ã{bÌGלwÇõ·Ý~NÚZ/MÞ{òÊ—‡p`®šÃíÉý ÿz3ÇÎ.3«ænn|û»Î>óûz×Î�køï›¿û4ÿJâ†õëOûÕ×¾zóÍð4˧‹?꛵¢0gbâÏ¡š+`qÿIþä¤Sª­õr““2ÚÜl®Ù¸Ña¬šÆç8‡Qׯ5ªfn‚;Žž#XD`RÐQäÙ¸¸b›ŒoZû{£³m vùýÝó±»*µì\•a业`ê,„Ýû¨‚ ‚Z˜kd0Ø¢ôŠmmÈÊ•]T_£騝ó¢Ò zµ°NµhÅŠÎŒDRKþP[òh—mZu“�вY �6ÚlFZ�à6,-]B{;7°Ê\ݵÌR袭K(IÚœ/OK>R\8×9m`À½*æ“ \.Žcc‹Ž5ïMxÅÎÁi–ü×ñvÌ!ZÒ›aÓ•N?\ÿ·ýäÓ¾zûëŽäMg'$ºœõ?y‚^ÿ›Ž{¥Xò‡’¿:ñÄõµCƒî‡‡Öü3nÿ•Äó– ­JæjÈXÁIbÄ© ¦Œª¥ê2·$£"nÕµ«9Ta:BûŠ0¤.}yØÅf{Ù;—dçŸÞ0Ãtm#áÚw–5k sçZ6 í«R CzfŒú 蜱ðƒƒýû*©»þÐ[ò÷ÓnVªs0� ?X8së07m}€ÂÏPÚpº�ž³˜7O.jˆÚ—�÷°ôêé-óœí›ÂcΕ�6­²°)ù—)9³tdÀùÃØ|h±±¯ŸŠ=[&6{V¾*z÷¢…Gí¦›v¦­ôÒÇìw¸%V·è}¯>~˜µgA‰JN‚» ½/úÈ#¼ýÄÙ§ßÊ]w3­¦/ë�©œˆÂ6¡]U—Z¸ÀâœeQ'B¥¢H¡Æ‚„`¦¨f´ÆEVxp¬Ä¡ÖK¬èvµ!åº�цqÙ÷óà3}𙽊nÛEÍõ¸{G»ïn†¯¿»j7öþM°jKA­¢ªéj¯MäW‡4×®fÎÔOe‘s‰.¢"ÇpêöcX-óDužèPNÌx‡)#LMu(m}Uæ+4Œoc.­X­zcžôT§\¼N =ø#¢JÕMSÝSU9ØÙ€t̰”§Z}béA¯¥¼@æúŽ7€u½�ÐÈ q¤…Îcùðäw¦­$¡‰ÌÏ^wáȺõë›yèi»!ÈLo1‰Öþ²�>çx*][9ç->ÛË-Üÿ‹éå8,üõ]w¿ DʪOæ9\¦tÍΟçÒnC®°Èš2¶-õbÁI¬#N,ÖD %Ũ`’êȱvB¨WÀSÄê™´¢�öý�ë Û®×�Ñ=O¸ì #Ï9²wŸG_%˾̙ ë ŠÝÿL²¶õ�«bè”4æëŠ<ÿÅ�¦ëXŽ'5Hbp€œÀtõÙ *UQv«¹ž�Ø b³ÆÉôVޝ¼½´ƒ|‹¶öôP MÛ7¬Bßar§²é*å‡ë4 �Íl–6�•tj�¢H'"› ‚Õ™P}QAg‚7討Qè~]90”™A@z3<_F±�~hFc¬æ Fæ5¡÷NåÚù¸—ÆNd¦±}ǬˆÖ­_ßœ6Ø‘gÉ[T‘ÿüÿÖ~ö®Ùlø1ß™^�ËJ‚>Ç…“ËÐï€~øÀþÔÿj(l‡×ÆÈÿ¶jΰH&7R•• j*¨ÄˆÄ ÔTç‚ñ@OB9©1‚G¦“D·(¶l™Šî¤”·™Á…ks;îäƒ_YßzõÍ-ÝmÚ¦Hj̽‘¯a@÷x\kÄ*9ŠcSµ³Eq ¢‰‹Ás ÑšÊ,çKü¨·—dh[wÅí½Ýv0›'¼QL-Ų·kœßŸÒ6T6 í­­>¸™ '¥sæ÷� )ª`hAèA’ƒ®®Vµ^àÉ(‚ªà)¿Sž+~¾§Äy|àÕÓÅìð¡%‰ó–21“ öçkÎÓo»ã{iky”©$yO_ü¯§pùL°¬y)wlÞÀ=8‰ù ¾*½/Ž�;AßÈ3„cmÃ\çhŽÀ�P×"n,U¤ŒqÊ$€HEU\¨ŸkMýéTæm—Êë²J×â}œ\h+ô·§ÍýEÞoù=W{δ´Y#’±‹ˆ°"Š F ’`ÀˆBb<¡%2†«Ø…Œè<Üòj XË>l”!Á—ÐLNöëè䨺ì`¹ÙÁ= Òнۯ¡Ï=¥0¤O0:¹&(®Z»*Ùl²m´I�‚•N`M ¬é†în§3ÛÕ‚iîFn Ä‚.i“žêJ:T@ :Ó9�¤ò¡ G îu¹çŠ"ïZlåÒÈIœÐ¢w\0ã¢O9"ñ0 ‚‰¾¨ÉpŽæê[áü5–Œ ²xå[Î2ón¼ç®ßMþ•Å2ìw€ïüŠOáÀør;úÚ>!«­WLR[cí¶ã¼nZ’[‡ÕTâQë¯,Z� µâ_ˆÈ·}µg⃅à'k7·l`ÇU êíØEÓÂU‰áDÔñI’ÄŒ©:ú¢("'‘Z""²’qâê̺V0š  .Æi°Æ6b£g1mUÐ)’I&É2L�mzxÓ(6»½PùîbvºµìŽ3ÁΆM„™1¢bFW%4×+››z”¶ÍBaeuåeP5èS;þˆ@ˆÆù�ÌÊá^7jÞµçe‰´’xºùÌW'©À¹\‹³ÃC¥ì&¼XKèÎeí�÷qÖIàšDF¬Ñ²oîÙ¶#½)ÿÓ wo`ÿ ë̯$IŠ–d˜Ìÿ¹ú²ØÅº}ic½P‘oüfmW·vIGB[ûž[?Á×Ö}ŽóÞÁÊ„ä [‘ßµÆY„»ââ(F$±ªe¶Ôåô‹“±·<1ÌÇ2ŸiŽ"‰ÄÑÍĮɀT„DU+ª .¢*9¦´ d¢¯ì‰ 8$qDŒ‹?�"*û(™ÝØw‘ӭε¶×ÿÓÂPöXj¾V÷ÊLu5öHšÇñ…Pô›dQ4"/ò{‹àÝ1%ÙvʉÉSÒv¦q8$T j¬#Ù±ÌìÏØð–‹ØöùM\ñ¦Hçw<7ÿì¿èûãô ¤ü:¶"ßvpþoˆ½e/VG ßø¯/ýyW{£¥íji/¤mô‚Dþ†Õš¬SQTL›`Û j·¨8ÝÝ<ܵ¶ë¡O®oÿËmY½PöðNñ9[•:5ŽCâý¿�ýMiÝæîËô|Â|®mµíþG|c©æW¶3?7b�ާXWXŒ‘%ddè\f©QA0uCbP«`1€G‚"Ì!£ó‘äT\„DHŒÑÉ Mm¢<¢Œ«‘>†ˆz IDATjͶ˜¢d'‰ìc*Ù“�Ë®L…á‰ë —.ÄîØKÂØ.àË=Hs ¦q½bº,6Zo³H‡ˆéïÞ|ƒÃ¶[mÐVÐŽjD�ÒÒ�´QudT›5�VÓ HL5v  ÌJÐö/)8üÁ$Æ ŽƒD‘§.>HÑY�ð‘„7.Ƽ'2Vb+2‰Æ×=ôP6í*G8‚8Z½#^Ìzò·°óO.áÆ¦–Œlä'¯O?å7±}Û/‰m޾sÒl®mïÑø÷‹³zU—EÒYù$ò‚XÚDP*š@Á´�wv2Éžü nèåè¾’sqn::£±6ùAw`ƒ `uPˆ(&�I`x¨T]'¼y•C¥ßeÏT†ØË©;^ïÖ—çëÇiž¥æ9ØšÐh•�Y8N‚ClP!V0*"j41žZq[‹ÑEL'«¶ÕHpI*½”Ë®¢¸ÙNEö�°½½ÖÝÆۇɎrz2¶n¢4NýÒ�î¥ñ&¤uíZí Õ´Ò¢�Ò¦AW—°¹@[pµ]  ÕTŒ�Õ~ö@ð)Bgд)´=ÕlO Ð):´Kd~šÑþ™•‡ kÑ9YÌ€�ºÅ¼ºõýfQ ×F¼q™k³$5E# �É5£#©À¿ ØmQuñ�öZ.ýÆV^õêZƶoã‹oð¨ÄDZùŽ�iÓ§üvÀ²žè…d-œº‚�ÿíû˺Z´Ð�…¶tÅÔ ß?ãSAÚM@A:„T¤K¤e%NÏJ’V�î °]A‹°¹Ýio!z«´šÃX�†f„A´³ f–Õ@›@Aæ}�ìÄ|ŒGSä³0ÞÇÂÄš…( (ËR óÉè\�…Pƒè�úÎÕtû3+5tæÙ¦3K\DÅÅAÅhèXŠ3l û4ÏN ý–š½Ô'»™pö‘ÉŒ`ÆF¸Ž2ƒXšQV¢]HO7Ò t¢ô X­&–ÍH4:e.`èAé@«u Cc*ÇjÆ»|Ó·É…²< ÍÞQ?þaë ˜OeÐÚi”"Ø««U±Rž�#)ãÝav¾»¸F`î;T¹ëWqÙ·~Ée—–iÈe˜6'ðÝÂCüçï’ÁCšñî�‘î»D1ß‚U/•Ïôæ3˱×=v؃|¿±N¯ºøFhem²¿ºÊá4‚^––üÓË¿(¨ ´šÆ^� h'Þ¬H�V`³Ðг2ˆ«… ~uœ€À´Cu=^Û¯¬aï @ Í‘Á.ío£mÓû:{ `M«5ƒDÿõm¸÷âM Q?}/Mˆ›'g™ådÍÑê± �!²�r(>Šc’ê—�£%µ(C},’GtÈÉ”¨L(2¤1†iõ¦‹’aŒO1¢bzÁî¡ÌÖöMlc}þn&,£¯¤Ôðv"Y!q[ k�5tßfƒý9ƒNa Õ>�HuýÿL±‡ÃxÑ Žd‹±.še«ç'Ÿ"<ç$Ì§ÔØÚP0“‰$W£©À¿ŒzÍ™~r÷½(É!«$t>§üóVN:NI „â0`›JËW§<+–c¯ëtDѽd~4¾ òþßÿÕµb™Y7H§JšôìųägIö/LG0‚­§��¢«\eSüta6»§üK}šÐHWK mmûWÀ3ooX©¨¨ …‚ÐÜ.WÕ#W¬B¿\@¿\µªéÆp#Y<æ2î.¦AáÊ|JαÄq3 ¨èb\jñl�ÌAC1RýÞªÕº|Õªœ«G\‹‡ÅÓ1!®é§¤ýÄÉ·Ž­NÌpœcw2Ÿ”~|Š r,Q@`Ö°†Û¸Í¶tÒÐŽ=Œµ?ozê›øÎDìëŸí9'Q¹Î1Z7­è”:¼Ÿ$}P¿Ì,ùþñµÖi«%™Ó'Ü÷þCX…îµ¼ùß~ÎùW¼Š;»‡ïž|ÈΛZò/KK~;ÎùÇ�üôQÄ¡ºnîeÖÛ>Ú¶nâþO´›Ï­ÂvUËž  ¢b˜)yž^ÉçcÉ¿‰¯ár7²îÀ«íü#ç;�±æÏ¾¤AU{éè€Ä Z7€�ÐyI"Á¦§µä¥S$èØŸÎ¶ª¥ûÓÙdÅjÛAÞ9�y³ U/Aá@#ÚÐBSø2zÛJ´Ð�¶�¹jf«”‰ú�Ûº·Á§·Ã³€-R¦l~ÆÏâ´ànÝ1ËÇÑÙîýã â)æâ{ M1:F ‹Õw’��•„¼‚‡£‚#N5@!¡b«€jý†zLÒÚzË?tw_”v�——%ð-Ø9 ³¤¹÷}$ÏË’?�‹¾z/o¼Ô�O^ÅOo¿›o¾haÏ©%ÿò´äCl?ª{qîÜU›´ÿÉm:¬?”¤èTÓù÷CmÉßÏWù ïàBÚYÏwÌ)¼[·q÷Ë]àgF†zÐÆþy«(ã�°y`àU4šuW­ƒ+¨ÍZœ„Æ8Ô%¶¨‹X`•%Xg13[ëã…ÄZ�Rõ€ˆFX­ÀÌøÂAðı¾Bs"œ‚‹2)P²�”CB�&‘q\·oÝ麛ÓÁÕ=Wמ¹ËKúë~ɾIØÇ›(­Øñ-j¡­Ù¶®*HÐ=­üë† óž£× Ç~+‘ìß8ÚÉW�>fÚê‰òã2;ÉH<€Tà_¾88“ØDx^ï.dí¿läwÛוœ)}49é´´USž [¡«ÃöN³,yÇ�¿ÊP°ºÓ¢H€t�Ö¢;ä"ÿ÷ë£tsm<Î]ÁEz+öŠvohpÀØï*`Ú€Ö�m ­Añ“�A1€ÝAÀC›»�Úp§Hœ}=InÖCä£ ùxóÊcƒš¥ZëÌÃãx¢¸ Ñz�zß&H5u°1BµN�€ÖÌüÌc—Ëtµ<�5'BeÊcJj)òLnÏÜÔçÄìH&ÜmÝ�îÉI¯3«{è=òø±ÅsQ{:·ìžœ%ÉÑd46\5#ð)/o"ÐZ1Èóqד›å1µ{’ñå&u²mr4mÖ”gÁ6œ++’¬¶úøÎœ¾ó£ŸÐ}|Y´uC`„ :çžÚð/‚È<Èw¥�/ȱü•†Œq_{¥7Lt€Ð†m;`ðï�ª;(Ry*´£@DQ-�mnoó ¬|#¿:-l¶²ª°Êìùú¦LÿRò:Ê|5,0>GÙ =ŠHça9Z :ËÖËl Bu] E4™ ѳ8ªšE$Ǩ4!ªÖÑSÔňÄVll…8¯%œìN²sà'ñž5ùèØ½¯AnΣv1¡ö}Øçïs;þün>“v‰—/1‰õIžß£ôçÜôV¸‰¥|`“�Y¸rþ­wmîKÛ5å™Ù�{ôRâ�1É_U´ÝÖ€½ü£7mØ£k%™ uN ãɺ¢¤RèEþ'|“sù¨½œ·r_‚WxzXQ Ø¿(ð [î@}Û'·«‰óEªëÞg–苨PVt´ØÔV°–• ­D¡­:q{�UÀhÛ:û@îÖ!25JíÔ=õ‹Nð¢fle©(KµF—ˆË2U`L†DÀQ1ެµ"”Œ0†ÅK|/)×ÓϼÏ^ÏéÇ‘ÿ;Ÿø‹Wcü Š¥Á í9(Í-ÓîN2‘§Ø°�±Ù»mÞËä¿ÝÂÇÓ®rä“ß‚Ãs‰¼{§}ñG3ÖG€vÌœ@Vví+¡¥)€]W€ €v‰F@E`Ú¡@뤹-t"-›1=µÚÉdls²‹Å¢£M,�ÇDÈGµÑ–“ÅuÞ‚ìç¯'óê-è´…sîÀùÞ¹L�7áMg©‰2ÔFk} >Ò71+HŒ!r,qöÓ\™‰)e¦uÇ™5Âøì1¦ü~ÆFóƒL×ïbú‹[øó+/ºèëgܲéѾS–,¼î¡®I»ØKƒ÷¯8®W·>Þœ úlŸ¢—qÜßÞÎûÛobñ¼…l¹h/Çü€­—¥-šòlØÃàã8}•úä­—Oð÷×;Áêµ¶UQDíTÐê é¤ü¡µYüõ¿¸™}|™w¥Ír䘖®@¾ÜÞ*Ý›r‹âžY½uo½™3þàù›Sûi.%¢cÄI†‹+xôñEÌÞ9‡Å ¸S9®%Ê#ó0à ذ7Éb"ª9TD0ƀ㠱ƒŠ‹ºeB¦U™öb¦jÊLy%¦òÃŒ7ía¤éqF�ÞÎô溗[›YïØq:²¸•=8÷^ErÖ¯Ûÿr޽þvÞyù(§,Jd _'d5ßþúϸí=‡ë3§Ñõ‡ŽÃ]¿ Þ± ¾¹ sÕ°ØÚ£²Ë™£ïºd¨ë¡Í¢í鲤Qô‡Ñ’?—×q,gó-~'m’#Tä5€Î@uC ²¹+ì¥=¼ó–Îp¯Í¡sBI´ˆ£aÖáñ ã\«»i.7s4MÕR3]K}E0Mì2%Š# dž8†üž9äö6ãïn¦alõQ3eH*Y²‰GMb�r�¨©žÓ™O¢'ˈ0DY‡÷gË„5EFëúnÜÇHsùŒÕ©hD\;…ýÂ:Ó«ùÛgœšüb¼-¡éü¢ÖÍŸËæ¾Ã)ð)G.Ëà›Û1 ‰ý§^ewçí“_Žï“¶/  tÙÃ�åó/òŽÃìävþš;¸5m’#EºDDƒžv½øïY2{Œï¸Ä§E* vtÒEr»j€‹íÉñÔÍ϶b#õûq‡êqFpGkÑ©&&k‰ÇkÈkÈŒ×áMÔá[�º(Á–d¢ž¥}y”ã±â¢â`MB)7Íd&¤¸p’‹ý Šþ$S³G˜Ê÷1‘ïerî•ë_†Þ€ÃÅs­ðñ~ñ>ø«ÙûO㬾ì,~ø£o¤Í˜òدdû�±ëû¬ìK|}Û½á§ïh íhûLB’™Ê)‡Iä“nºÒ¦8²éœ)\Û)�}374ù ;'•ÕeFE‰ÆÎŽ™ý߉·Sˆ^P÷ºä1–¼½iÿ9œT_æò•cì} Ž?˜¨£}¸�L±o¤žÌÏ_Å)ã5d†gaf!#yLÅëàÆŠ3íR;™e>uŽÃbUTÕ«¦*‹PÊ*åÙ WxÂÚQÆê÷1ÔÐËHÓ^&æ?Àˆ— ÑœSæeÓCJï†çÏÙ\úM�bxÝW¬8SFoü¯o°ëÓÖIùMÄðWãFOï³fl û®lØuOÐ…=íª�Õðe£�Cšw1å׊|Ê‘O‡A`/œÌÉõ{ÿ^GtfYÑIŒQ•ñ³ã¸i7Œ{(ƒXW ñþƒ·O›äLò Z^uÇ#Ü1VC­zäÔ¥¦ä‘«Ã®¥lkÙÛÛˆ·m!õýó’Ú’‹;ááNçÈÄ^â’�ö�‰êª¡W¢r&Ö8X2ÄnD9;ñÐØ¢îÍÏ0Ö8ÈĬqº!¦ýAJ™q¢/nåÏ_‰÷Ço*Jsɂş»cß;Þ|/gœ`‰t%GÍÛÌ7/ý÷�w]šö®”gÃ6áªq•Õû¬ë'yëû 6pÿ¨¬¾: TÑD;�ÀJ{EŸŠ|ÊÓ£ ˆ¶«Ý…ª"oÞë|ërêšúÝo5µ–�q`Z’ñó”YûOP[+˜ÃÝÅÎéçœç²ÿ‹¹ùÁEÌßÒÌâò,²ÅY8³�b 2Z‡©#žÌ¡‘ÖÅ�•lÑeVq6KÍ|„“qÀ&Ä”™ÊT˜ô-åùe.« ëFË 26{7ã³û™Z²•©Ïn%x.Ÿ1£Ž–#aÕÏßÃÒo’„òlÜDˆ«¯¿ãì3¿ßµëá�ûÞ¼¶ÄªbcÁNè$:;íl)Ï–Ç †0åi'¹úý×4ùáÕI Õrg²¿"‰€¨Êa,¯�Š|Ê¥òª‘î âЪÝ‚¬%ù믯«9y—w}=œ?)0¦ÁN,ðU{ˆÒi»¹˜Ýð‹zNS‡EÓYþtº‘†)ƒY¤±Â`6d|Ò�Ç—P»}~ß|êw-¢a¤ž¦RºØ0 ÓjËê#Ô©E™‹ê‰X Ö<’\Ä•ùQ†&˜ö‡ª}‚þ9ýL×ORöŠ”ýIâúiìÿÙVõˆ›˜(9r²teÜrÅÄ•XfTþ›wm¼ô­Ìû»Sùq÷ÆŸxÜžqyñ ¶?º3íl)Ï‚í¸L`ͨš0ª‰?þê5ÜHG�` ž,.s`)²¤ò©È§<=ÕѯmíÂ¥³3!¸gEPïlåïêзOº±‰bKžõOsø5|~Õ?¤ÿvÚóÔÍ[Žâ‘þ䋳ðÇkÉ å±£uH˜£2æ32\‹;^�?YKv¼žlÅÇK€ Ô ×²p ÖXZåL1j݈J¦Ä”S¢˜µ„‹Ç¹ aœ‰¾ï°¨ôæŒcøçÙæ¦Þ÷RnË8öK‰lF=*O¾þôÿ¯ê_;9çç‹èÛqw½/íl)¿‰mÈU$ÿ´Šÿñ«Öð÷ܤ à ©ÅžŠ|Ês4äéÞàÐÙšðv¼–S³“¿h¼«dbg"A+&©¼ÖRóô‡¿ü¹h',ü¿ldUE¸ àÕ#Õýûšùáx-îX N±oórŽÚ¹˜£Æ0½�–ÉZœ _m ܲKcâ1»èbÈÃîc°Üi&Ùk“Í—qyT‹f-{%¦ë•H¶±{o�׿”Ú¥â…ØÈÅ«Äàd®øÏ"�õ˹góOùù<Ä7^ýPÚËRž•o.7ö†>KyÜÐù³ˆyëM£¸ I{ ª¤BŸŠ|ʳÖxè\»ÖüÝÍ�9e�ÿÙ:ÊŠQ3m ÖØèµö©Kä~寸*O'�² Øtðk§òfŸÜ~`?�È2^ÊáG N”ÅŸ¨#7šƒr#ý}³°{ÉŽÖ“É“›¬§¦¯Ï–ÇŒd§U]­xžhT[ödΔ«N�ÿÌ©¡W�KWq>M^…r.$ÌM0�-Rr*$µµ+o|póï¿í�181!ŽãÊŸmáܳ²fŠcNz'ãS_ç‰ÿ�ö°”gÃ̲)ä–>K4F&˜¶'ÿÝBÝ”¨t’ZªO™ö€TàS‘Oy. ]iiowZïv?“£tmdµS¢¿^àgÎð2›¾b8­ŸóõµG9õ„Q|ºýnäÔ�Nò¯w6éÒ¥½˜Ø�=¤bÔNe±Ë}ºßϼëoZÞ¿¼÷xN®ºÄJ¤/¦’™bü¤õ›o{±¾£-{±€ìàè…½œRS6¾A‹éˆ_¢”Mï‚”gÃ6¸²7 H’ ©éÈPù?W—(\B  bA…€t1|*ò)¿ŽVÅíîTK B{§ìÝ$Ϋ dÏ%û™Ê×T\œRl(Š–—ÀŠgs^“6í³â™àäQ¼T�Ì(cË÷œû·ñ®Ÿ�Ï¡1¬¥¡bÈ冟~ ð®ý&Š™_;B’HŒ’2CÆIˆïy˜÷>Ýqo8™¯Ýüv.©�dÂc”�ɦ�Rv#µ}ïÚÊ•¿éûÔ FIôh¶îy¿µÛ^Ó^Á;êT6ÜÚEïÇÒ+žò›Ø.\0fX×gm©¬õŸyÇ Wü Wß`gÊvšªÀˆ¤ËäR‘Oùµt‹&Ú&¦s¦È�lh5?^½ÇÌcÛ'gQùPŒãı0fâÊy?m±ÃìUQQ­hôÃÛ~ö%àKlÿÍÇܲ��\´™–ñ!–Ç.™r†l”%eq½åÇžá¸Çg3Ï™¤~"ë6LÌŽà"ƒ‘•Ø=ÜÏÖ§?îÜÕ|ÝÉᕜõƱ»7e³>ŽYì3'„Ýwdñ¬çž·¦W3åÙ|QÍÍ£ ñ0|¡!˜ø{öÝ� íVEmj·§"Ÿò\Ø€SDƒ®Ç½ÍíÇÆ]ê6 àcyœ�Ũ;f™¶DçZRWëo�AyîS·<À…ûÿ~ËÖ%5ä"�\ã=“È»!²`‘ÍÅî´‹�öªåK†dÁ/ÙÕû4Ǽ¥õ¼KÚrû9Q= +®¿gàdN^VaËä·ÿwyÉ–¥œ?q×Ô±“_»…j裔� ª±ˆxó3ßÜÚ—…Iy E¸¥�qþáÖ¥qÇ×Ð €Ò^­·]- —f±KE>åÙ¢kÛUºº ý�¸@ŸÜ^øH#r��d&ñd’(^l8÷9'&O94×ǵ‚E^Hû߸�«žÍ~-¥–ÒxOÏ]Æà—’«º÷ßsoUo’ZÛHÍâY¼3±±±0`<vØ I^Ð�GBV< Nx¼<’•€$@B‚ÁÁì«„„Í ‹eãc�WflìÙwI£­[ê­êÞóþèÖxðöÆØ�]ßÏG©»ª[Õ§«êwϹçžó8e}õömèáþ›|H2_=ÀëôE1ná{ìgò�lí™AB¦3gnñåÆr:&óÔ+�äê K~Q 4Çš…~D Æx§Å›„ªñ,J½3æ’`žrç$¥ö*]w2Ùy€J>ûì“F¯¿1í5ÿ$a7fâeQÍö½â]]Ã+×ÿÙ•[¢Z„0,Q³€Ý°¢ÍŽé|*ò)îFF%ÒVÑG"D"T7_~Ž�­¾ô!~m™ð õ&_2žyU¿\åfÒ¼–_(Ò,ø û¾2Á¥·ýÛ¹t�¿½jšó†4ô$½[Þ­qö§I\†�/ÙÁÆ+~ùÜ;2µ›J{‹ÈÔ íWQœ(RœëõÅj]ÈÁbž Òá2txƒ6Hú`º ü N¼ê�q¡ÎÁ\™RX¡\˜`&w„ÅâA T s4Úgˆ¿´�ÿýWÿCöÐBý=ÌþÅäÒÓìÆZü®»ÁO�.jð½§ÿQå÷6~LkŒ�‰‚‡aD1ˆ8ÑQ«‚—ô¦”Š|ʉˆ`£‚‘s .ºªCïµc/µÎ~Äã ‹ %/¾î9 =/µÜ//­®OÐÛÚjþúÛ¸äùJƒõº…?æ³å·pÓröÝ·Ïýè¦3îÿºOþòÙÛ»*[¦ÛKäÊí„¥6LÕÇfŽ´Áþ>r}Ú«]„Nœ’uÐ^ÉÊ9õÙ~¬³x#8”†mPO­ÝqÉ¿ÖöU2ª§Nre×æÚ¶3»ân>¿ï¾©€@Eªy5Tà­ƒ¼íý‡ø«ô¬ûù³Ëð+ë<ß߆øiU�B¿»¬/ùý�W0ËC4Å\8:/›]št—Š|ÊC0,ªŠ^D¢îæQ¹JÌÖ‹xiè‚+œ$ÝU�¯ËÕüó)ø?M­–òPœÉs?»�ÿuÑÏ\æ¥nõ'ñ›¹âž?aüôãyýïÿh˃.Åüû ^pÀ öOǯYpųϽcÍÝ7\ì$sh�ÛÖ±~ï*ò“ÝjJy|¹ulÕ"‹BP é$'ËÈ  ô:=²/gÑЀD ‰U~'_¡Ò>I}ë�57—°æWËüËî}”ÿ`5ïé©£”‰?°ó©ÙMðq‰PÁî» :éñä¾Óù«µÿqák‡¦ÑÔ[OE>å_TÍ1p$‘¾JŒ|xToûÐæWä—«$½u ˜ÃiŸáŽS\*ð)ͳxÑ—îä·_› xË€nwÿ›�Üü'Œ?ïѾ÷[®¾få±�ÿèÆV`Ø ?Ø!?ldµà ¡‚-·‘+w��(/d˜>ÒKn®W 3„³].7_$?ÙA®”#¨d ÔbŒÅV,T–£~PÜ‘Œ¾„��äcjA�ÅL•ÒŠ/n[`¡}†rqŠùB™ZïvJí©þË=Œ¤gÂÏæÁ㑆7£Ó Óâ¿×Õ[ûÃ_}.‡mÝ«š³ïéü{*ò)�UTDÎÑÈn�­c›/Î’ù×€¸gQU+$² öžæ8+5VÊñ�—?+æymø„";x=—ßóg|ïy�Çÿ>BŸóHö¿zÀ|wû ¿fz9}•vÂÙz¤ 3Ó‰�,‘‚ÚR7‰3[ÐY éZ(°BÛNUµª>Tb”ÅÝŽ× Êù#L3×·›#}{(/»—Ò‡wñn€¬Nü IDAT· òö¿:Ä{Ò3¦ÉnìÚµÞ}»0:­¶gšäû‹½üÞ;Âa�FTÁ´<ùTäS‘Oy$ÎüÊ–qÑó.æÜ æóÅ 3’ÐmØó4ǺÔL)Çi¼ê»9%4L;y5_>ð.¾½ñ‰z¼Lø‹–: ~eÇõP¶õù؆ó¸ÒúOñöÇå•®¶om;WRØÝG¸s+f{µ·šU*´–Ajabé® ê¯à ¬œ„êù8cQkqm Þœ™gæŠ9¦×ÏòÜÎCÌv¤Ô^¦–÷¸®9’ö)êØÊðSå¼Ù#kqÃw zXÅ"¹í¦3ô÷Þÿ´ÑIF‡ 2¢J¤ " B”^n'ޏ¤&x\v"i®9 ’ˆˆhËÙ–s^înâçu°0Ö†.¯mWÙóLtýcu ßDvu ³/€g¥ßÈ£ãáÖk ­¤œö‹<ŽßaÕ?^Ï[ˆ×¼°jòù‚ß“¼–¯ø'þõ„~&`òÔ€­Ï©qáý·ý`-?™i'w¤“ütÙr™ïĺ6¦J9â�„ûºÉM·j…† ± ‰ÅúPB0V1!¢l‚#¡š­3—uTÕÜ嘕 ££‘a4’Í¢^›!/‰ˆÜ­…-gg+ÙÑ6tù0£¢Ytÿc)ð)O>.àÔ•7¿¼ÆóW(92~Âÿ!_¹ûüs·òO7�à7§Äh.ñ{°mçïæi÷î–þáYeþ×Òã­Ý\à,/« ï]CñŽ<íÐ*Ú&—)³PjC+9´ • ²–Cú*�°®¯+Åaă&A >4¼1“°P˜gºmšÙÎ9J=“”Š™Ïf¡mŽzÛ<ɇ¶?±MË­x0¶ ~Þ¡`GnYõÕoº‰ýoÒ�‚Œª(÷u‘kÕ¥O>ù”‡aó6U†/·Q$*Ã*ÑH¤?ˆ8%¨—wH}°¢†iñtª=t:ÉšÔb)Å 8ù#[øÓWT¸x9&äwùÔÝ—ññ3.»é©g�c`ã,WÍ®~Sps/Wù …FH&ÈWòäg2˜F†JÐÆôD3ÑEvªHx°›\©“ö¹.-–Ú4;ÛNx¯h"tTò¬˜Z�²$|�PÏVY0žJ�WvT(·ÏSÎM3—Ÿ¡¼l/ ={(_~+ï|ÜEÞ�ÇÀýŠÒÝ-ø9…Cdw·¯¬¿æâl'ÒVbÝpz‘¥"ŸòHPTˆF�h8¹àª×[FÄ¿ðo8¥3Z 9½ª0‡jNeæt’U©ÅRŽY6 Öxa�1a²Ç¿’¯Íþ WlL-óàœ3ýÀ°ÿñmïÿñJ^z¸H_½ƒì\³P$Ü¿ ¸ˆÎuR™/`ÂZ– ÈV,Y—¡ŸÐÈdÑ(+4‰HŒÐ°q»ò‡¹*•Â<³íÓÌtb¶o'³Ý»)f©gÔTIþþÀcY@0÷sæwb_7£^ { aýU³ÿÀ-º%Q5шh$i©ÚTäSŽÿ2;z�EL�¡ÛÞÏ€¯‡Ÿé">£l�9 «:{–Ò—Z+åa‹K®¸ƒÿù�…dJ_É7–¿ø^Õ©m+6á­á­w9­šçòJ;m‰%#ô¢ýœ pCÿ±{�ìþÕ´ì§°k�ΩN¿¼Üã3 9XÌ • a5C¶!8L`¬ºbO/j~ $DEp&¦V¨Pg9²v‘‹{f)µM2ß>G%·@­pˆÅân*ÙóÈV8T Hn—áüužÜ+Ü|wö! §*Aüû_ŒGoݼMEÇí’»?<ŒFÓð|*ò)�À—Qˆ¤ïMQŸ«È—ûHÎ�˜÷ø,aé,âÞÔN)Ç)¼þ?¶ñ{ç7¤»3Ð)^Ƨ÷~š�¬MþçÇ%î¡Ä¦¥ÕÇrÞ¯`¸ë¾çnèç¶Ùeti#?ÛAn±ƒìlçCJ Iy¹Ã½¦ºÉMçÉT³ˆ7H"´5:M«§—áwŸ,kŒ¨Ó¬Ã… !,&ü÷`‘…Ì<¥¶)æº÷3»ê'ÌuÏ�ÑvÙ–;Þô@?Þ"¸ÁužìB.:¢ú¬IdÆåâ¡×\ûÑë9g³ŠŽ lP•1�m*ªi=úTäSFÏ­J¤Â° �ŠéÞ"ær^ÇÍGƒ…Y¾Ø!z^Y…E :sñ²Ôp)ÅÅ,ÿÐõ¼å’íæ%k¬ÏIF÷»Wòï;?ÏGNK­óÄâ¼IÎdòø÷¿ú$þ󯧳a×zgÛq¤–USÊ97à+Ûé6½ ¾/E„u`ž ÎâÔÞés1¯ÊÖ˜o/Sê™b&»—‰™O¸e¥�ì×,�Û4œ/qÐy}õ­µ—üðÒsV›ýÓ¥†‘»(÷›G n= adÜ¡Ø!ðÝÀ�Œ �±q#2~Œ_ˆS`$B¢aئtl$R†7#ÛT£aW±›*ª*Œ€Œ�cƯÆ3|´_³@9x¬I—Ðý¼ˆÔÜ|‰Ø÷��Qe‹�ìDNª Ÿ+¨œW•’i ÓÏE�O—Ð=v<ÞKèzyϽÓ\²ÎÐnBfä×øìÞQþéI›œùÌÄ3ðo9>÷T9§nZÁõ±'ð!¹R†ì|�ÌB—ËsxÑ Ú± Eò“ËÈï }ª›â\;¹…vŒ  .ã1"ÅEMþç(\ô Ü—~ 7¾™Lf�z#Ëľ§sSC³“a®¾§�°o¾ý ?‘¹µoœiìÞ�ÕYºýØèfظÁ²u#lÛèuC¤ ¡I$Ãl�6ëpDªD"›‡‘)�Mà#TA1°UaÌ«´Hi•ÒKI=ùÉ‘�De8r*D¢Ûà·=cóòù»ì'TŸ[™%P�{¼>åÄåž}ù-¼ ËÒf•ªžË·J/:ç‡åÑ›SÛ<™8÷ Ï}$û_u2×îêa]£@¶ÜF¸¿3Ý…™ì@g‹ºø»ß¤çÒk ß\~ ÉW?ÛK‘õì×uÆÖ‰ÕúyƒÇÆ5q³ Úgª»¿ΑÑ}—Ï¿~;Öì§ÃîbzÛ�lß¶Rý’±Eé|É"Ü[gl{BÉ–ƒÈ†YMôK=ùDä#¢J4"Q4Ìë—KïÔaùTú¢š e…š°ð<¥øxWêÉŸxžü<íƒwñ÷—LšÓÖ‰Ÿã9|kñ|úö—²ãùOfû>=ùŸ•w³©žá�Þ62´¹,…ÜÃÓ—¶ß�œ{íj½þïÇÍ´h³‡osÆÝb4Áa¬A’$6 j±„J€WÁ²ˆ5sAÕri6ØE]öÑá'é”C¸dj™0¿b ¥;.ÜTÝø—Y¾ë‡bÛt<ŠÌø%ÈÐNüÐ1Ç¿yóQqO=úTäO•—ÖeÄämûDz£ý4^ƒ™0ªâ¥úl´íñ>¬TäO,‘?…×üÛ$¯~ö"k–Ã"§sÍÔ‡øç{ÎgçùOvû¦"ÿØpæ/§Ðw}a@Ç>þ·ÅÏй¸’9·’Мl;üZk�±Ýx/ˆ‹+ÖU*ŠS‡ªŠQ£‚€ë! éƒ•èY�%§“b˜lË1-uv«g‡É²3ÈrhfšùÇbèÙ_tŒmtŒ�y4jÝ3£Ô› IÃõ�ZÌG­Ê�D�þ­D¹ 6‘Ùûuþ~õ- ² BÝËâhGj¼”‡cÃ7íå’g5l�±n^ÏæûGÞ¹êcÛÎß¿óÂÔ:)ÇÃÍH²O¼ÿ”ÊôW'Ìγ«¥ï¼|'.ŠP6yëNÇ® 0¥ó\Þç\˜f �º’Œ®ÔØž,êVP§_–“•65&ƒE0^P”ŠÅ©Çj«ËL…^NV�‹`Q”�%A¥“{It°_ߺm�/‚¹è�)0*GÚ¡ü‰ªÃ Û–3êš^¾¨(6 ŒCÆb½o}rs ¢ÇF„fµ}F›}ô–Úé)Ê}KšyŠ"Httß&CÍDD¶ÁÑŠŠðÄ]…�zò�… 5²:ù‘á¥Þð¢C Ù‹DzçÊýcŽÚxCPòF«hýyhþu°©'bxò+yÝw&ùÝ zD©ê³¯½‹Ë¯{?yÑSž©'ÿ(=xám3j¢;Œÿpd8kÎ×ò—o;Ññ{ʧÜKvn‚Ì!Ï@¦Ÿ»ü æ´ÏäÜI²ÈZ—e5¬–ãhŪ ˆE ‚kª©`0ˆH«£�â1¡,àM•†.€VèÔIicJÅLPg¨'[©‡�ú!²ì㵫ªko´—^·žõ~L�íËn=¬Œ�¹hc³¨O 1$MaިíÕN-ißEM©GÆÙìï"´*ú"Šª¨ˆ4Ÿl hõ$y'¦žü£uäQFFÄËp#Ã\p•X®Žüª�E™çæmÄ‚9�¯ßx¾'ŸZ-åáø5Ö~ðz.Y›6ð œÃõ�7óÉ»žJŸòè¸]ø­ƒ*ï܇ÿÔ;|ð¥šINH$y„ï³ýTm�ˆ‘Åa8[ïaL#PF1ôvA.ÞM.é¢Í)ƒ2Ï:m×µÒΩIÍ-W úpZÄi†6 ¼Å ÓÔʆ6ÝaïrFÈ+¨? N�ZlàÚëb ¨“1U>t¸¼;£S»+{·ßé·ìÉÝÌn,jk8’{óè \¦ CÉØÈ˜ßA44D4Öæ¡­H÷Ÿc¶²aÔ#Cª #lk�š+Цo?vc³j¿[(*­ŒÂ¥HC*òOJ7^77³DG†…®¾ ®ÿÏ(ۻ߼#Dߢ8»èC”$y¾×TàSþ¿ÜÈ{/>Âéë¬/éF®oü ¹û·Øvnj™”ãá̹‡ÔzG¨ŸyWÌÇËaèƒXk+ûý¸‰"‘ááfSšácŠy¡ ^Eê@˜‰�áav‰p]Kø6ÉàÍã™l™â‘yz’~ã'i™åX¿\VkMV‘“nÍKŸ_0Xl³#€Š8°JÖ TòÆûN1~…·<]…ç7šÓ‹'+qmNçÌÈiÛWvò¢`2Ú,ä6ïàLÓÁôXs¼ŽÊ¥c—ÊËù°FlÑ!a|£À&`¦PFD‰Ð�¨n` ‰6 QJtì¼À7(ž†ë½//Š0®Ø Gð÷N–>dÞчykƒ$X¨ªI�Íëq_ûEm®ìx¬Ãõ'óêoMðÛÏZ`CŸPâT®žû.»ë7¹çùOEû¦áúŸ�ï ñ£ŸúkŸÿÄlUó“ý:)“ï¦�¹Yëÿ÷‘Ì«.‰5ŒZ5ÕM[Ï #E¨j«K]6lãªmÈÕà‡#Õ�­ŒÉF¶ÉÖ¡HÇFO 8´h™:Ôήîªq/ÙjU]OFÖQp«©² k–c$šÃ¢*xõ&DPñÞTÅŒÇÀ¶âêˆ#Fh�aV3ÌhÀ mLPv˜$ÙŸkg¯)²{a;3”©Sܦ>üøÕx¶"Œ¡–mÐŒh4ü§áú'­Ä·~_^w“¹õ“æmý˜?¯Ibjj¨*n0ðëÖ&H­•òP¬â|o/¯A4ð I«¼ÜqßòdIì[ f­×j+Á¸yÔ£» ¢Ç¼}k`0&èØÒýˆ$”Hex¸YéI8§uk�€hTüf¶°€¡rÄXiXØÓ:*�fï\Ñs lÉuAÏÜvÙk™w+¨èI('i»]ƒ·b}XB,F ªÍ#tŠ4©¨Ç*&ƒIŠÉ)"XE,â¢ÜWD©•­¡`÷_ž5SìР³ÈTÐξð—ØSý0ól_å8o¿£?´ Ý8‚<ˆ\~6D‡Ðá/KÙ�Âè0棑–/ÀDS(C‘À…ÍG·EÑÑA…Þ§M?õ…i*ò? Ò¬aTF“Ã|"xŽùö·yûÄْ¼’¬]Ÿ–vHùÿ1Ïo­-qnG Uég[òùÈŽßçÆç§–I9^ƅ䕯|z•~„ùD(W!F!†j3<9Æ#?~Oþ˜ÕeLJ;Ph¾§>ô{ ?=®ˆŽŽ X(À͇®ù3Æ’rß1¹Ö~ˆç  ì�D"Fdëh$cë1Ó.31ål[ƒlÜNORãdèi ˜•ÌëZêv@…NunFz /M6ZN€ÄfUÈa覒œ&ÍÕê•‹Kª&I®%æliðœ‰}4Â]ÔõÀØ�dר¯É^Í ýµ#ïÏ0wÙE,0ð’ãU�õd£æ�6yE¸g‹ðús¼)­òþ#lÝJ3/€anw‘ £È�¨?šõß²`*ò�ƱGE¾ujðã—î|CÁË{gçUtõËàεš†èSšW³òoä/žµ“—œP6ËØÑøs>¾ã�¹fCj�”ãåZŒÿ‰Êwþ¼Ï]6;�o¬ ªbB ~jÞ˜‰dXÙi¡6P#›·³LqÏ(£ÿ¹�m2Î8“ѸÙö<ò@'�:`Ë,ws âìI$ºüj“eP Ë\‡zÂæêy1êUUQÀH‹øÌÑ’ü�PÃÙ˜fu¬@ ŽÃRª8JaŠéÿ:ÀûÜÞ÷8’„c{ßë8hSôqxð?X2‚nˆ„m(‘ê#²�­Ò·iLØ#Ã0¾K¦³À�tµùù¢Ë²¬QⲬ¦�µ³B­¬Bi @KКÀУ#�fvF›åÔ ˆi†Ö-`P Æj™sXÊè„öPeŸXv™";ãƒÌ,‹aµùjÔ7Å\½Ém¶iÔúІ�Ô“¤ž{³(Bëû‘$›Ø½uÍt©¨Š’14BÏ[Sk¥<ÏâÅŸý1üÒ†<­€Öµ“Ý�¿á²[_› |Ê#àÄß‹½ásØwݱÂUKc-f&]µØc(UŸª“…ÚÊþ'ZJ4\šÃŽô¾yF„!`# Í<Ðh<6EŒƒê©8¢ùxüÊ^½ .~}ÓUŒm^>%œ]:¶X^G'YMÖ¬¢fVÓ�UXíe‘õXßC YŸ“D›�~¯ŠÐ¬�—¨È)d(Ñ#ï §k V• ÞÕpäq1Ó,˜#Äîùkv˜—ŽÈ\ÂT¶gì ´1ù¾˜éj¾§ÄáÖR‘”txNšA UT5šw’?‚»ö*š¥‘,Bˆ&¨P+À—-|nz}j½§ÿÒ3?wÇ�/yvÌÉy«H'ûõOù»{_˵ÏM­“r¼\/è=*·«#ù›ñ0Y”ƒ¡KU��•ñŒLò ×Ͷ¶,•±»Ïy—ûêß¶ TSa¬•À&Ҝ䎈†[{i«;žªF¶ÂáÑ8Ã`ó(:Õã÷œíì˜æÂñÉMDÛÊ”õ\+‘×-7oáò“ú²4ºØiz {WÇ–)ºBꜷ±®#ãVúDsX54YðÚÌ>¨‹i҃ѕ·Z¬ž¥5õÞâkV¨•”¢3’›9H8v$ ×?J¾UäÒrI>Ћ„uñj<" Ô[¤•9Š b¤yŽ(F!Ó,í¬¡%Éy­J%„8ýÀÏãx¿aÙSTf_à93ýö?K¸~uå]¼ê…j¥Ïï“7óÑCoãë«Rk>�4\ÿàü�@ïBnûfwü—_Î÷Ì35ãšIvÉS*\bÆ� c„»gém”99éc%]f=Žuàûñ H =d$K¸”ýè—‚ÍfBç=V­¢ŠO=ùGÉ`Ÿ)—ì=;‘u9ëMbO©!k–‘t'ÈrƒtÚ¥ ‰Í5¤$@¬‚k­á1bŇ‚vøÛïÂßf ¢ ‰A“¼P+ÀÁPÍë×á¦H€qâå¾9©”Ç‘ ¼ýßïá›”šéõ{“?á³‡ßÆ×פ–I9^nÿIn½²�w~�ÙüÂŒç©RM�s‚«ü¶!Âá&60&ÛØ¬[AÆn&«uÚ±ÙN*¦ßÌUW냬ıžŒ j¡_A`²(^½ˆ©ûF*ò�’³~_KQ4ò�ht«04†Ê™oó}3±v{þ@Éw==ëj,›ªeOÉh°¾�ÅÁv�ÁZ¤ÃCG Ÿ cU0#¡F¢Š !%o‘nA¯ý.Í´«¸Ö‡¸8 �,öÆó:P]K²ÿCzQyb×gzòñ<~ù“·ð?_ôžÝï±t±;y ¾õm|û9©uRŽ_à�Þ [¾Ùãßý%Û1�/g´Ú£†¤¬”Ò+ú„¦¹ Ñ/eé ªD‘,-7ŒÎ¡6 UxÅ4°SØx£„¡Íœ²�4[ÞI®z„ÎRÁvÛ8^éêrŠÏeW¤"ÿh¢á!�7 #= '/Õad8&¢ÑHëWmÝ\—±‹>jèî–7¾isæì)ŠJwO/å�Å 9µát /ººæýÓè+Xz3 ¹,&¨OsÙ¦EQŒ8UjJx‹ªP0¸êöd®B q­õªj6õÔ“œ�œñ±ÛxÃË<§Ûc9 ¿Ç[S�Oy$Ü@àï…»¿g“wg:?Q$£¥ü4ù2¾„©�Nt?^ÆZ3ñC ˆŽh³pºh¤*  ’�2¼yÈ·ºáÕQ�¹ul‘›gôÂxÊ–‘q/ÑT]S‘´_ÎѪŽ#:6‰èV‰Óhxƒ0¼Ù³†EE7�¼^ú^�Ÿ¥úGÛ¨DÌ~í†Ñ»˜] ¯?Ç)˜10'%tßš¡¯â}ß:aműºâ9©SX#j× IŒŠfŒõ"‚ªG¨�fßçÀ4ÓÚŒ¢á´ï j{ðƒŒ¥ËSŽ›bý^Â�ßÏWßþ‰jx¨§£jK’'_BÃÚ$¢#é:ùGM¤ÍÑ×°´²85%Ò£Õ¡Tå¾pŒ K}Œ£fA¢£E&#"ذAòÍe#†­Bß…MSÊÈ6eëÙ4¶YƇ†Ìû®˾ðÝ×Ñ{jŽÒª� ÔÄž*Ȫ–/À@–¤;� òˆ±xu I+ð¾”^¥ÙZŒBè›U’,ÍnÐVT�Š �CþmgÂgÓo^n¸íh›÷œú`ÛÏäUŸØÅ¥¿Yb =ä°¾†ÏÍ\Á¿ô¥–;>ÒÄ;¸ü.ìá¯u¹7}µÎ!€|3Î h@‰¤X•¸„X Iïžøc«ÓͱAÖ£óª"ª»0€£«´©AÒzÞ7k݉¢‘i-"Ly²� #b/é “L¬¸›¾ëê¬(y–¬¹û¦e=­…øþ,Úø¦Æ·¦ëßL TÁƒbP1­ÓÏ4¥Ùá±¹Èp!4òèËž ×<l~‰pë„öû‹üËX÷Ï?á×ââó+tæCJ¼’Oí;ó‚mþ­W�¯OÏÖTä�‡,:áì‘­{ë?;¶B)þ™æÙR‘ “†ëŸ4áÑVÔ@¸ ¢‘‘Úè†Hžƒ.ÒǦÆ4Ú¶Y?2â^šw÷€á A@f¥!{²§…דzUûrÂò A_é�Ž-ÑBV‘ Æ Á£­òÑÚœ$²ªH€„{õ•,5“v>Í"šÂÎD?þäYxM~ʃº€�^Ã¥/«ñâ“bc%ï§ü«øâ=ŸäÃÏøüÕéyšr|üHðž© îmŸ­¬¼«´¾2'Ž™—Z'%ù§¢'¯H³ Ÿ*à„a6ëp³ ô0†$‰°:â�ŠÛå}½Cˆ�„T®�™ÎÇ=wCÈL˜(= Ó—ÍÙUÚÖ%™ö^Óè*8º³øÕèÏaû�ꊌñ�9oÚ²�ÐÀ¢xœziF™\SìMˆÁXøØ7áciÖ0(ñ!f Ä þî³ñ�V÷ƒY ”¾”5—ýˆ?ø•2/Y-?Á¯óÅÝ=/ÞÙÇ•é9šrœoÐ of¯5þÝï Šw’ŸÔüÎ|SJÍ“’ŠüSÕ“§Õ“@A4R‘á¥ùšaÔ½[Ä„|hª¥¼&q^ãžÀTsU¡VRʉægð5ðã!óÈÅö IDATß óq\ÜOˆÐ’ª”â»Ò›‚£ÚÖfí=Â@G öØdy‡°"“˜Áº d,>°ˆ1XPÃëb³Å$Œˆ[nQV^)¨QÔÒÌ °2hœm&~â csãEŽiÇu˜3г¼|…!/–C¼œo–/>gKí®¼ñäô M9nüm—gv ~äYnÈWBbJù*érø”T䟪žüÑî‚Íj�Kí#”¨•´¡€!PuxâÀ'aI‚Ž’É…ƒy_%Ñ8Œ CcŽÖÄ Š%“TÑx2ïÈ÷˜‰|™RPvAÀBO•I8\ Ù^ ­Æ¡Rì1)VËú¼ªí~:Ë×s½�×寃|ŸB_,ô+Ú™S rjÂŒ¢ ª $iN xU!£F?þuåãÖ£"ªB¶©³Î¢“ýèYð®ÇGäõM›¿˜g^voÚäYV ØÃÅŒ/|‰÷¿tszn¦7�ßE0wØx×ûbn ÕX«aHµ/¶½qÓ©™RR‘ªzòGçäiVÑmMš7³/�:œ Fk«Çh<Ó¬y]¦ „‡TÃ@(†B+ P •¸ªù°*$U­VÑ*!äó¦\hõ[‚rsŸ|u‚�¦ߘw³×17[¢úÚ-]Ö0·è‹{'“�Š=«H1[ÓžöFÐß…í70J­¿`hKè ‘e!’Ũó^q(4ƈã k•AƒDWB´ÔÔ©eoÍ*±³Ê9gÀžG}ñX¬&Y³–×\y¯8³lÖ÷gü>^ÄU{¾Îðºô¬L9^î€swcÊ×›ÆÛ/ƒ› ª¡Ïƒ„T©NÅnº˜—§pÓ™”TäSŽ ûž>¦ñRsÒ^½_zîØõµ­¿ãX‰�½™4c„ÕŸÊì�¡ûû‡«Í}À[3{g<{›�JÀm„îP‰¹Ý0COÇ.ª3~M€-–ÑRà;’`U†ÌÉeººfàdÖ�Þ·"”d™íi@Oè((&PÔ´Ù*PƒEq`¼ª äD5g‘ÝÿXT ƒ¨Å¨�éý­gâ¯:s×êÙx�ÓËüá¯ÀJú#<››'.-~ô'_O'OSŽ“› ~¿—ʘw~¾Íß’”ѸuÅÄZ]º–âTàSR‘O9�¨†°»#'�·$‰†Õ" TÝ,P-K}_×o†…¿¿šo¿…¾vK»š`×¾äùÕ\v-¦0�¯tåë¾+ãèÀô¬°ÒèÏ×—wtf‘vÐŒ´ÊC©6“j,U2R°ÎZ¥ßz¾%‚ Úê Hj/¢‰&CxÍ3=׬¦¾ìTÊv WÛ¬d5÷”¯ä=ƒ¿š |Êñ ¼à罩Ü�óïý`­p])©R‰‰SAOIE>åÄ&Œcí)ÇšÄ5� ˆ�ib%�„a,au)°j „É Á¡™déõãùZ•0_ƒ�ò*‰„µ¿¦Ò�î$/âÔæm­}ÐjÛÚ„žv,ï•dEFµ?�]añýí0�ÅIN *Kaþ¥Òšû°¨XQV[ìøwqÌ‹úêßÉßJ�Œ —grWN¿×”ãã̹Uâ;÷¡¿«…ß)Pe Ú!ÌøÔ:)©È§œðÄÀD€ÄP�•0òyC©êƒ¤Õ­/F ›SëqAÅ8”€€rœh\Mf 4ª=ýf{ ÌN¹ž$ö3s½c&†½EDb_¤JIü“¾{J•ö5‰í<×Û†vç1«3è`éN`•�î’É@6�&Mâö{Ã^UóbŒ‰YÀ“ØßÀz‹!Ö‘»žw‡ þú;ßI O¥ü»ð?8@xÅóî[U‰¥ZÊ{Â*t–É$]Ÿ’Š|Ê“€jx_X2Ž•%,Jµõ8O"K“ûIKø'ŠÁOÏ÷‡�TKU†HX®úŽ2RfÈ+$J>0t¦4[óP¢‡VaÜ 0wÁ|)d/ÝyKÔª¾X®ò4Ŭ…ܲD‹‚YwPüKçá¼ÝJaŸxTüùÆI‡WÍàŃZTÆiàÁ�®ºîz] òuÄ `šÍ±ÒªE)¢¥õ'³`€K¯»Î¤'ÄSÀƒÎ=¬ÁwþË{»«_Ø»@œ�óT‹¡¨–˜(ç}óLOIIE>åIáÏßïq|ß|dô�»Ü/©ÚÜ?n%έþ\]ÚþS ‚¥û½aLÜü“Õä¾}à&è¿ ž\þ—Q X¯ì‰GõÞõøËÖaú×…¾welzz½]ÙNÒaD»=tZ(æUÂ%%ù””Ç•W.ŠM¿kÒ ûÕ»>ÓÔ�âÐ V¬sTqj-’qW²Þµå a(ÎÅJ�¤ä3:’½PuæbÇ>[i»³a=„UºŒÚNȬQÚWÇZèG;;=Ë»TŠªôæ ?@; ÐÖ†ä|€4k6g jæðaÖžàßÁD `iå´µÉÂà î�K¯».Mü9p»å·fœ|f;òÅ¿ ¹|~n †*´&ŽKžjêɧ¤"Ÿ’òxs|° VÁÃíÞx�g�ËYgÛ¤Úˆ=Þ�ód8 œæ½<ͤiƒ•ØÁbÆ‚ …š÷gisëÚ¤n?¶:A­öCÛÐF˜2á�i8ÍÔDO¢jÛ-¶ÝÐÖ­ÚÞåélót­Bû{:Ð^£IoÚs�Íb­¢$xu@€ˆ«.ìÜ.ëvlç[Ke‘¥ù¡9-�,_®i$àggŸçÓè7.o�?vO¦#!S�ÓÆzg1„jœ)%ù””Ç iùêwçÜÏNCsÈ¢N² q­æs¶&¾�: ‡V� VÀ53XÀAÃ)+8Î)8 8Ë¢Ekà�šÃCFˆQâšâœ:‹l'ã¬sIÆÙ0ÛÀíuÖ ®¡‹±H¯Án¨™üÓño~¶q§uùÀTñÛç„}V¥+ðÚ§˜b€æ `óˆµªšŠ¢€Ÿ8Ìê‰Ã|ÍàM«`²/¸åË™èןWb ÀÁùdºãïUùú?#‹ Å™2�G{ªæÎ|è)åõ�ɧ))©È§¤ü¼PšõCÜ—%ÇlCáVbÿ#à—´æP@]kÿcV87pzÌýé�îA´\3ôß|ÉÒ14~j_çPhà€ê±ÿÃ9Íe05ÐL#£hĹг. =b€–»ÞéìÇÈ8³±am'}ÖÛ•�‚Õž ô ÆÁŠ,tðËÚ”e|Á*Æ75^bT¢èÄ!ЇóMÄ›V]e‹4§p*÷õéó¥õ'ëolß~Ü÷¯‰á 8®:O¤qŒÛ‡|ïËÝ?Üu8ß ZÕf1Ä*ÌàZµjÓ+.%ù””Ç‘³€÷m÷þ%_æ ¼�YV±÷ 0¬‡æ,|‚Ð\P¶NÉøa£Ò°ØÎV‚‰Ä'€dl"�¢³Aæ°Ùu¸þUFº=½½H‡Êò:¾]‘öŸÉ‚Œo }B€Q@‡špûýpžf²C’$xðé€W+Ë9AKÂ\-¸ýjnùÇ yßÝ êÕb˜6—IIE>%åÌà}@;÷…í¯>üp;°X|"G¦°Xu81né#yE³é([=’EœEš„DqÍ¢CZ=b]#€¸ÅÛa&qÜÕÔÝLóý­µ›õöUhaÛÕîéÉ¢!¾;$a²"¦#‹t� PÓTrÔTàð$kOòïˆS+HК°­�Á‡J¬Hl1»ÏÆ�ñD´ÿ5à&4wËg‚ÚÛ÷„,–gŠ.I}ö”TäSR~q<ø xŒ÷~#0 ”�[O”Ò ¡8™Œà�2Î2�/W•þ¥Ï8Q›U9bTP‹ÓÀ"¶Õ2Ø�Ö[uš©ƒKw‹ŒX!i(®¢…ÉgàYÊÎQ9L¾`p(s÷Œ¤#ÌP¡`¹î,��ŽB¯£§#¡¿ ú–A]BWÐÐ �¨IP­ãšëP1Šd >àNÿOAEÑæ@@QŸ�8«²7@ÿâ™ðo�·ío¿ ùñ7ºjï¹2C‰Ù¢§ˆé)ÅL¤ëáSR‘OIù… üû�~i ü‰ƒµBh%;m4œ‚eÜÕEvünI¦úÀÒnS©T’%¹îhúÎAF A� °â›A ÞJhÎUÔëøz=«®€Øz]4g sWÆyæœ³ÎÆ®B9K –:™¦ÚŠáÛ:ä!<;¤»OéZíµ»Ï»ÁO?3Ó;3Û}¦N½õ}UõEL†¼ÊÁÄDì» ZC䣴ÆàçUÅþ‡+Qœ×VÀ )ùD·‡þ>üÌ=¾¢�óPj%Sg¬ª?ßdÙ`¢�X¡1Ë 9Ž4Sã}¨å9¼5YÔ2ƒV>Fù(/Rv €Áè Ê3(bƒ‚Œ‡¾÷[¦: ྲGƆ0 A¯âÃgþ±ÖK~§"Þgzý� ?ð•@ï+ŒL(¬_:î1Z�“呼 Ì3›€–R�ƒxp°-ߑ֯EÛ†,*gÃ{Už }rž!ÀU‰¬x©TŒUí4*é�Mñˆ©æÊ!+üÓ¿#y®býþôkvÿ—Ö†"†b1 ÚúF¢Øï`ÕÒp@­$T£™!—ëܲ€Ü)£ ®"¿núØ%&ZÖƒZ›A­ÈDþâ³L_ãg0ÊÖ,°ÁuOƒ‰ÁL&ƒÉŒÿnÇüƒ--hLðP&�Žsðú³àë Î™Ä¿ï ¢G®[WþÀõ# T),™%C J%4RÕNÉ Â¼²ø„|ÂÀÿl[Á;| ‡œšš uàæÔý²�F„è8ŸA#¿çˆ™qJ™qv—ˆÇ#ÌÐÁly{‰ÒdÃ…°²3®ð!KvhÂ<£?ì=®DþX2¨YžÃ[чZ©`m–÷c–õ/Ë¢z=È "61Æ�&£(›~&òõ×nÓÞǧ2ñgî÷ͪÞJ~û-ýÑû¯?˜Ý7XÊ0ެ¢Dò‚°�¬Å¦è×PMÑ?|m÷7§s¾*ÚäÈ© §ñ ”΢JS¡^T”1ŸWÚïí¢¬*ÆOÆÆ‘Ûm^ÈzöÔÂ�ìЄ.�Uwy…â]º4É`ö=™­D‘,…, QK@ DdóПÁäN'»ª€Yµ˜xõRXÛo8&F-Õ›Áô–‰ó±†2}½§0q÷eNèñ§~þUUØWÇ@D�‚*‰è‘¼ Ìshƒ²ÅÀ‡�uOJÃn‹{°¯3ÞªFãÛ9ï,Þ`'z W‘”1�O…J{Š(Ä�Td�°d ¡=äep|ЄÖùd²¡ 3¡Š²À8q�‚*�Gv‹~ˆÏfÕø@†í‘& £A²åuO¶´ 1!Y"0™Ð~Ž¥'s‹z½`é�%#QÉËgð¿fYEèb Äø`AeÇK2ÿ.ˆäaÞ#@»=îï€3SÒÆ.²ÛÓ oÒ² Êhãàkm–jüctï[¡xœñ `r~mÀË1Ý^[» ÙPAH)ÙÐuc…‚*Eã„…¬‚Œ lj 1DE¡¤ˆB²!„ãÄ2*[Â0Ž ±³åãÏ ŒL��lBU*`®/ gé1Ë÷o�Ê« ™Œ"2d j߬¤äE«t�}DYl bAÉ Âü¹øpvJúc.‚ßÓ)oRû¾Ò1¾¯L6ðür_f§X¥‹9…Ê` 1¡©`Œ_„Šö mVV®”4L ÃÚn!@Z > azÙ[H‰Ð”žúK ¥ðI1—ÜÃýJöÿBšð a31쫾6AhäT)¡èq‚Fê¹À;�Gäò‚ ’„ö¤ø(p>ÕEvãØJvwâöŸÝK#‘¼ týN溯 v{ÜÀ=ù޵6>¾²Ç׺§¤‚H^:ŒðÁ”àÁ–¨½¸»[.‚&¶²WÒ A$/íM²b>ƒ-jsQJoE'ýŸuƒÚâ£ÑTbâQ�û jƒQOý‰óA$/í‚qü‡�ËRÏ…Nð÷tÃE°çÈk‚€è¯÷ä¾ þn(<•±ÇÐJ‹„G¶Ð �ÉÿðÂÔseà¯é¢½ ‚H^è4<'ø?¢š¢×Øúôß—Ë#‚H^Z3:WNâ6õnfüë€7S�‚ÒÀ•À·å ‚ ’„Ö‘z"î¶�M¶$m{�LyÚ÷¿øS÷3 ˆ�à¯uŸ ‚ ˆäa#uåÚc[‚vØœ,~ ìÄGžDó¯Þá¸ç¿ |¥ïû(²(]öã_{e¿` ÄÉýA>,b<ãa|­ y¼JQ–Ö ‚H^æ&ROK½[¸fµúINðƒ.ŠÏa‹Ø qHar^üEª'‚ÿ\WGð!&‡¯|4hÍïŒ}þõÁZ�Á�1~$ QDò‚Ð\©ûNØy Xœ œ‡=۽ञwß—Ì¯ÇØóB¶¤¢øWIuX üðùn¼Ö˜9�ÅóИÅo5ÞÒ˜pP¡ÀøŒe´!�@^Dò‚иԽ”Ô Àrª)ø�.Šï¥šnWÓ>‚="|'0êÿlŠ~&Áw½¹´Ñ¹OÛk¥¼Â8È ¼ÇT0¾\,AÉ B�bOéÅrK�ã€MîãZ'ô¼{dR?w8 v¡Ýo\4ÿ|àîç¾å/IèDÜÞ¡ùŒ/¯£'ŸZ¢}uÝÊÇ¢®wïBŽn‘¼°€Ñz:R_lpQú À±Ø¹ö$ýž=L¤ÎQ$_s¿ó=n‘ü'DðßGi�¡Æ9…†L€2.²'�çóíç=Š•VœÚ8xp§Ü ‚ ’æIê™T$>¬£š~_ïžKæÕ‘úL’?è s¿?áGÀߊàSQ¼ï“óµ˜ÀË©?ÀÓ¨’Ö:kž¬ñkr•^*~Ñ� Z‡“�·9¹žCZ ‚ ’š(öÃ-–KVÀ�MÉÏ´X®çž öït™‚„_%‚ŸAôƒ·)c9Ô~m¶Fø'øÄùˆØTŒîíõ˜(¶Ò´üiÀ[€­Àß¹¿ýB¶ý¤ Ê”� ’:FêéyõÃ-–KÏ«{}^}6DÀ™Ø´ÒÙÞ¼˜’?ÛÌ’/à«|_�i?æ›oh­NŒáäcЊ âbë¼ìS± w`36S xôc³R9`/0æ)®$ˆä…6’:ZY.ï¢åõTçÕ×1ób¹fEëG£—C`=Œ=~\þ„3>õ¹�Bk£s¾ú¯žlŽkíaðP*ÊU t«köÌ�!à“À俞p.p0 ìv»Ç>`Â]i#‘¾ ’ZMêɼzRhf»Xî$'õ5N¬ÍœWŸ þ4Á¿‘?g ¶ïÉzL¡sYŸ �R@–œWê­( öWzºc=¶$ñ~ìúŠá~=(º¶~š‹ê‹n²;õØpϘ&}AÉ ó*õ,6õÞëë�WQ],×ïþ½¤~¸÷ð¨ü�üi�,÷žžÖÚ$e|€¼xÊ øt‰¿´Ð/v‘‹àÓBƒ·ÀI|¿{�‹° >7a§�Æ]DÀ  ¶ŽÃl-‡@¢|A$/Ìu¤žÌ©'+àÏÎvщr‘Ç\,–›‹Èêqà]Á×@6§â00�ÎJk�Ëy:б?5¥3ôx1~%oòDà£* ³º~)¶ba»€r´ÅÚ\±çžKî»NeYj@°ŸjJOêg÷ºAåË|¾ ’ê{²>‘zRþTà,÷X“ŠÖf´2ÃÀ»Eð5'n|rJkgÑÊäð¢2&ƒ¯Š*Š1Q¯VTDðƒØmrvýþk‹ÆEê{œ ýÃÜw¸ûîXà'ñ$µŸÈ>=Ÿ?ìþ=–(_É GŠÖ©÷`Ë®NÇ®Bš‹ÜœÔ ´V ¾JÀf~ž¶}´ ž 1­ð³øgLrI†`¥Á˜ŒQ 2è =ïUïa·Éå€�8™¶Z›4.ßí>.;ÊkL¤ï¹L¿Ëh÷ó{9t.?ù|?’ÚDò"uª+à NêK±ECΦßOr�g2çÞ®RŸÞÑ~;ß)�_ÍØ 3—Ó^èrª××ÞúÐ;7ãÅËc@ÅŠ¾*jây®^?¼›iºÂ‰®UÑTWÓ/­ó>J§ö—¹Ÿ?Õ }tšèÓò—Ô¾ ’ï©O_,·»èçLì¼ú)ØóÕ{©.˜kåyõF~Ž�³j$‡¯¼¬V€Æd{P`ˆ &c%LœAC¯ïQœ7™ôâÿqà¿Ú`�™Èø”YÞÓÉ=Y šÚ?›©šáïrŸaSû²j_Éw€Ø�¶XîiTOlKŽcõ;Lêibìü6ªéL¡ム5&GNhkŒ�RÆcðT�¯ý¢Ž :ªÖºŸë±¼{@Ñ_¿j£68ÌÌóò³½ß=wŸ÷aSûvÿýÞÃHÔ x%µ/ˆäÛ$ZŸi±Üi̼X®à¾¿ÝSðµFP'øƒHÚ²n| ˆíQ² Ñ!Æ`L Ä

z+ÚŸó„}�‹à×búU]Ê)ì¼yÉ Tæ/5ZŠÍÐ�â·c>µÐ Dú‚H¾…¤žÌ«÷bçê’yõ3±…hiÿÅrÍ Œ=uNRõ�H^çýäÂ;·[^eˆ”kOÐøsÛ¶z�7aÏ8ø$po›]J�-³»ËEÝÞ<ôéÔ~vQí™n 1ÂSï%ë¦�Ô¾ ’ŸW©O_,·ÄuvÉÖ¶Ó€Å:¯Þ­RŸÉ—°{ã+Òa5b&t`ð}¾)£ÍØ b…ñäQà£+s¶º>¼ÂµùîiÃKc3JÛÜ€|!ú’é©ý .‚ŸtrŸ)ÊáÐÔ¾ ’š õZË%RO¶¿uò¼úl¢§¤¸ˆ3Ú�ëØ}ÀWc”âíÙèZBuŒÆlòPjq)ôcLÌ…|à5À3�O?kãç~'Ί»w’é©ýÅØ�5!6µ?}.?‰òrèT"~‘¼P£Ô�´Xî `%‡.–ó$Z?j§ZqQü”tF�èÕWd}ÕkÊ�Žñ}5®‰ï]1°·Rñ ñ¿o?9ÃĜܯ.®înó+Zv²q÷w+Ý·é­z«\s¦{Í#Ó¢ûØu?+¨ÎçÇr�‰ä…Co¨ôb¹>ª•åΦ»Ë5“ 2?;ÂÀ”}`eO67TŽ||UÊÆÊšƒÂ0VDÏÁao ¸¸ø ¼Øšzì¡Z…O¤/’ïZ²n|,¶²ÜYØmmëéŒÊr­ÉOa÷PË||#hm| §}U+G¾ëås;¦‚,yÏP±7~¥£¦^_x ðRàš|Ò&÷:ÆÌý⻹�þb÷ÜIÀŸ¹(;¶ÐÔ¶”ð·a· )é "ù®ˆàW`�üÔEïÉb¹œH½¹1(ÕßZ.GƒžÀÇ|JE6§*e/*è8A¦ñ�à/¾ÜÒaÏ©ˆw° ßCº�*¸ŒÄàYî=í�Ý'�عþd«žH_$ß±ÑåAìÜâóܨ¸ÐF#úvºÎðìêz‰â%ç«R M_龬Ÿ Ë&ëk/RÏ@  Wû *³¿ÎÊ þRàfà«(ƒ 5øìï€{z­ýì.ˆ¤ÖþŽTdŸ–þnl¦MRû"ùŽ“OÑIþÿ`OD;ˉ^¢÷æRBæãgVk�4�Ÿeïô©Ì¹½^´Ø€ÊE… •|—½Ÿ�,.^ ü CŸôCØ•êÇuàûKN²L×Úš‹à÷Ï ûtj¿‚œª'’ï hþ‡îFxvk�ˆ¾iÄØ²žÛ�R¶³“¼ É|_+=¥u�OæüšXkù‹€”ÒŸ: IDATW;Á_IçnyLŽžÝç.m'gñÒQ~†j­ýgºÁ÷ÞÃHÿ ì´†¤öEòm-¡1ס)'ú§‰è›Ö‰H)Û&ÞW�ÆàûÊË^N÷ÅÚ›R}ºâ){N 1ÚDãW\áœÆ–?œ¼{Ràèì5†j‰Ùv�m·�–~;]±Éý½'€�‡‘þ.ìª~Ií‹äÛNô€ï»FÿN×Ù‰ègO²u®$—¢¹h¿é1ö™À›�o_¢ZNµ“ï�d^~ˆÎ˜—Ÿ�ôÓ©ý%ØGö�íTÓù[RŸ¹L€¤öEòm#úÛ]C}§DôM‰”JØEw²un–äðU�öÍÿõ§ Üç¥:ÿNo£ÉVºã¤•=‰G5µ v÷Ñ3œÐ÷1ó¾íTSû²UO$ßÒ¢ÿžû:IÝçEô _ÏQ¤”mÂvmÀWhmÈ⎔o'aœùOì"Ԩˢ{Ü£™GÏvZ”?½ ÏFªëmv1ó¾�ØÔ¾FRû"ùý÷Ý ÿlê^D_çYÁÀ™”¼éÍÔE<Ë+{"ðV×QŠÙ®ËoÏv:á$?‰]�.]úIj?©µªpý¶T¤ŸçÙ‡ÍìI”/’o™ô»îówJDßeàQdë\SH¨ CbMÀÁ�蟾0Êü)&\çá)Ðhí›ãüã±Å ö×…‚Oˆœä÷9aI­ŒúH§öWcëí?ݵ§!Míÿðkì9²NG$ߢOR÷"úú#¤’»©eë\Ñš’Æü²/·“ÈL&7ã£tmï6î:á�`‹¥ts[MêØŸ$-lÖQ~z«ÞFl™ðçº6ösì¶Ì­r©f?²š+úO¹¨, «=:Jª‰Er9ZŠu.‚þ¦ËŸH~ȵWY;Ò|é'©ý"ð0Õê—‚H¾åDÿà!‰Lkê4+îf®÷hYÉ’Ì-뱇™Lur“öjçãwa÷Í˽Ýü>tpðe'z9Ãb–Hº¾ù�t?vÿ0ØÅx§qèA6¡¢Îc÷]¿Î]»=.Rw£øÀ=fêp…¹a1ð‡NðÁ‚¦zNûJ¹¯çDð×"Ù’§p¦>WÁ/xÀ¯½ÿÉÏ­èð—"ú#v˜£À/°'û�€=+i—El¼ýØã1÷:áŒQÝvS-Æ"ñR{µ4ÀAÁÇNð{]»•ë[\&[éÎD²¡ÍüÕNð2u7ø¿0µã õë%’o±ˆ^D?3eà§À‡ÝMcKg®ÄÖÌ^ã>ç>žƒ-©ÙGuÁÞA×á&�÷õ�û·îZ î£ü,J—ý¸Ï×ÞTv�ã<;¯O2E­”ñQ9í-ÊàŸÒ‘€¿p×÷£Nð’5yªä÷»kHÚ”¾rÕ½þ(ì+­Q'W �æUM÷¥4йm¼#©ˆþ/DôOé,KÀýT�¯›¢Ûå÷Nû™dqΠ$ò_‡Ý’sª{~Ð 4Õšãc®cÞí>q�u±“$æ~ˆñÉ)(Ay*^–%³i4÷Êúd��]ÒOÙÜ ¼Í}¼ÂeJ„ÃNw»6´NîçY þ:àZì¼þœþÈ5j÷Ø.Üy�J$ßR¢¿-ÑŸ*¢RòSØêiÉùñé´°:ÌÏ$5²÷¿š¡=÷¸ˆt…¬6¸ ÀIÀ³±õ¶ó.+cWö¹ÇpjP0Ž-€Ò6sƒZcräT > íÓkÕCä…^¬¼X¡ñ™ÈE�o·ÒõoÁ.¶û ¾¦û:ÙJ·Vî冯áÀ7�Evµâ7ÞÊ‹î^£žñOÇš+Eò-)ú$¢ÑÛz[좒’83|~¤�BšÐ=&Üï~pZ ]ns±‹ú7¸�ëÜ àYÀ@jPJEþ{R‚}n0�û½3Uæš>h™—ŒA mèéñðmÓÄ{ �‰ˆMoÑwÑû±µè7ÇÖ+ŽÞî’:ö12/ߨà“þ|mä÷‡T¦&ÙyÎÅ×�t}‹5êýÀ·Ü׉èó]ÜI–°õæóhÙØEç㮃~x†ï)P-Á¹ÊEjÝç'¤=Øì¸Á‹w€Q÷žF° —}ÐóÝâ|­�Ö|È’õ²:4ET/¨¢ï÷ë7¹ŒÇ'° …ÚÚïͱÓCBí÷àÁ_+|}Ü»æsÁíÏ57½pÔð?%’oÅÈuÿ´ˆþ”.} ›ª/ÎcÇ|¸(›TV¥DuMÀ¯sÏ,®x'p!¶&Âr— 8Ç ’è~‚jÚØeÆ\[8€�.0ÍèØô»6åPÉ)*ã„‘Æ3ŠXeñUìë1€áxàsØSå„ÚIŽžÝGw=+ü<óêÓnÎX¶‚;jü~‘üü‹>IÝû.<© EŸöñÕùø…x GúúpDNÐû]?‰]O»¯V`çþc�à\짻糩ŒFý'âu×g¿{>=‰9Â4�ö}|´Òh´ŸÃ×� Áx€"¯ôd1º'7ÈTeIoyE]�ÎnŠ•þ�‚9}¢\ü€ªèŒQF«™v¸6y›Ž£º;@:è§Êd^þð÷ù6à߀ÆB%íg–œ¶q;Íó¥�½DýñÏ�-tm*ú·u¸è+Àc.ú‘›¾yØÅxy_�®”‹ù†ÈÇ!á‹û ¬<}ÂËõƒ÷Ú’¾æg+ÖüMflÛú8d•¶Ó'bë<Í}\â~o95ØKu›à6 ›”îÆÁZ2/¿Çµe™—¯öi[�¯‰à›}a�åñ‰s¹¹p¼DòmxS 7¹¯;UôéùøŽ*'Û:-I›<¨ ¾Ê‹¦‚iæ—Nx¹—‘íõ)«Å ~ãP¸ùŠ!6?Yÿ:]qPQ-´['`#Õ*‚»Oú�1ì–Ãn �&”T&Ÿ61Ôž“š “Øú Ò—YÁÿ+ðU|sù¥²gÅ•“kßq+’Ñ/„äÿS$?7ø6±n@ãy\æe}±ùò%d^ÐCù¼ÀG…ǯ°ê7?ùwI‹žTôþà´ç=ìö?ß 6Q-”T<Ç z±©þRJüÉTÀ÷û'Ü` ]k–';)ö¹�O7ÏËk` 6Eÿ/Øj–"ø&ò/Œð[ÜÎ?°‹ÓEòm/údŽþDשvÊûv£û@þÜsCЙð9ÃËÀ¿á÷7Æ_Øf.E^“'ï™ÍA]±j¯`Räã~Ì=ÒxØÕÿ½Ø”ÿrìÑc]Vàxàlì¤,pR:xˆê o{Ü` )$Taþ*#ÖK²]ò$‰àEðsÉè.Ùˆ»j¿´"ùÖýÍîïó§®clwÑìüC—`.�𞃎_ç¼o®­<ý}¯yÅÝ<ú�Æ-øÁž`(‚ŸC^ö`†.QêËk÷Õr‰ä[…Mk®ÎpŸ·sçbÏ))²6¼ÍSÜÞÏŽÍ•WM;¼íp9 l� õTwlž#p¶Ë,v÷TèDŸ83JuwÀ�û·âQ,ɼü™tÇâ»Dð_uü<°íwbdíô¢ÚǤ"ùÖ|/p.ö¤³óhïCl’ƒX ûJÙÎ�·wÆ1oßÌæÒæÎÏfÚG5íódmË0ðóÔóÊõ{9l•º•T§6¸lÀéÀEØu7˜r¿/y$SÉâÀ¤Ž@ÐýªÆ®µøWì<¼~žøì –Ð7U6—Nis¿H¾­ßçÄþn๮³i÷¸¬ü)eÛlŽs‚ß ¼ÃÔê 6£°{äºSãçÆ‰8ÀÎ¥ïÁN!¥ï?ß Ø½ïÉTÀ7 :{Äp¿,TÜ#ײKÿÏNðÛDðóÇwÍy¼xäL>}Âë¤v}‡ ¾ÝÓI)ÛY¸£e;‘MÀ›]ù&m ÍÙ�ïqív:Ø52K¨t�ËôÓ™óò"øf÷¯_Ï [¦8î·oS[t™ÌÉ·©àŸ¼ËE ƒÒYT°«n¥”m󨼛6~ɱ¶ª«VvÏgF`ú½:î;Ýswßîx#�SÛ"-øÇœà¿&‚_ hi·¯îVSS·Ö(É©I­%øgïm@ð­'óñÿ‰M�J?{V¹þ 6U¿§MÚB§’Çvai§eTDð-B6¿“M™Ýê\o¨æÁ¼H¾5ßüð?€óë|"Ѓ-|Ó%[˜îGRõÍü;\ùûØEOBkP¶»AW§´s| ±¢¼�žhÌäÌZ‰äÛLðÏt‚¿ ÁÇØyß·¶ð�c÷$?†œY>[Rüb·08µT[ßîq¼ŸDð_Á·o˜ø&甆رêäšF$ßZü@�‚ÿð)ìªßl:¼Õ¢ø¤”í¨t³b›š�±…‘$‚o=Œ|'Èи÷ñ¯"øÖaÍÁSŒ?ÙKpÌ�šFÞµ†àŸÝ€à¿ | ;�»)Ï.£Zè£HŸ:'4F/ðÇNôÿÝEðBkŠqÄý}ư«îÛ¹Bå$vkæ^|kð·÷®`ø’A.Îz|¡¶¿‰H¾=+ð÷ؽ¾›ö=ŸÀÖº;¶¾w+t2ß8lj~©‹à’KÒÒT\Ô»ËÝí*y[èR—�¸›•�ÝW½ÛpU}ý¨H~aÿ¬”àkÝS›NÑÒÝpÛfø¾a7ÐÀ±åpŠÐuvÛ‘£e¡»ÿ}=ð{À¯û5›Ü'Ws~ˆ±+쟞F{O‰..¡º¾àd]M[ŽÖ„öü(p;ðil”mGøþ2ðyàN®N|2/¥lü›±íÞÁ¡UÙêd‹\ûùm÷O¸û3jó÷¢°õÿ_ìÚâ3iïòÚ]‰Dòów³ ¤ÿ¬ÿ=àsîóŸÕðs£ÀßaSndz0ç\Ë||cä±sð'b§^n—AR[Iþ€“üì yí\ (ý¥©ç$¢É Ón’Aìêùw»Ñp#‚ÿ6í]Otp7vqÞ‡°‹·æ3sc°[½~í"z‘Tí‚ÿoÀÉØé|ûa¬=Agœ/?]ô;G/¢É‹à�à/H ¾¯Á¿ »Z·^ÊØÓK�×b�­�¯¿y»Ík/ퟶœ/rNðg»�Ù¿É%iKbÉoÞCѪӢI�…Z^_ZôÉ SD/’ÁÏBðû�àßÓ à“›x7ðw3þ>ö4­ÌÂnÅüª ^<»š¾Ñ/Ñ‹äEð� ~Ä þsØÆâ&ÝÔiÑ¿�¹MÝk7PyDnþšÚËeÀ �¿u‚7îyµ/;/¿ÍÝk~‹¼®[�òËÀõØ)Á½®­½ Ñ')ÿ{‘m²"ù.üsœàŸ^‡àu*‚ÿ ¶XÎÿmòÍ�ˆÞÃVN› Ñ'[çÆ®.–JYGn/¿ ¼È þ‹)±‹àÛ›ô¼üù-"ù»öËÀ�Ø)…øiª=>ŸÚªe&¢¿Ìý üRõ"yü‘vü3°‹®šÝÑ'¢¿Úýîߟ#Ñ'[禤YÏ þ•À?a×MˆØ;ã"äíØ)«…>_>ÄSº¸ ›¦�S÷ë]©¾êÔ>GŸý�_HD/’ïdÁ?»È®QÁ8»utŽ^k"úkÜëkvDŸ>ZV¶Î9‚%ð lC¹N�G‘jí÷ZKWϵàoÄ…;}p*Ñ{.¢¯å5+`%pyª ‹èEò‘¥#øóü·°‹ìŽ~ã¢à¹$rÆÕ)ѯiR{ˆ\'²IÝŽ‹€ßÅžîõA®*¡0·ÄTçåª U-‚Ÿ.zÏ=.ªSô/M ô)¢ÉwŠàÏÞœ‹-:S«àG¨¦è78AÞ;O¯]Oýë› údëÜÀ¸D§3ò,Á¸©!Ðé’OŽž�@òÓSôG|ZôÿžêÃ.rAÌÑHGô`S÷"z‘|[“”ª}6E.öİF¿›B�ç÷�ˆþ*÷u3DŸÌÇ—¤‰<¥½<»â6lÖG®Qg“=»Í z—-€à¯ªCð “Øs/”{$}=¢7Øj›"z‘|ÛÒ? ÁS�ƒh�o‚ôb¼,¶2Þ± ¶ ã:³_!ûã§sê4ÁË¢Äî Œ-:³XÂüT¿ ±Ù´Dð{©+î$ð“Ô×µŠÞãÐÔýÝ _D/’o+ Ø…SïÅV(«Wð·`÷Á?LkÌdž.¢ÿ¢ûºQÑW\‡¶IC§9x#ð}ì´ŽœËÝ=¤·Ò�>’o†àÑÿv¢O"ú#‰^jBˆä[ŠœkìïkPð7;Á?Bk-¸ ±‹„¾èÞÏk�cêh#éùx)e[eð—Ýø $Eßm`‡Dë9îsCì®–«› ø„‰i}½¢ÿ�i}x˜k$ˆä[‚,p1¶¶øÙ³ü£´æŠêDôWº¯_‡=*³Öv"óñ‡²ø7ðy“\—®•ü(Õ£gçêTºÀÝ{W·6IðÍýK©î£ÙM"’oaÁ?{:X½‚jÁÏ$zxu�¢×®3{ÙŸþíØ“øÞì²Bw’³ÝI¯Ù’Oÿ%ìTàP?]ôIêþyuˆ~•‹èc7Ñ‹ä[Ž<¶ ÔüMÀç�ÇÚ¤q'¢ÿ'wc¾†#§îÓ¥lG‘R¶ë°Ç�Ž]Œ(t/1vqë4ÿèÙDð_tü\>-ú»ÏÑ÷×(úÕÀËÝ×"z‘|Ëà9¹=;ŸzVƒüç±sðí´-tÑÇÜׯ=JD_BJÙ‚Ý‚ø§ÀAìA@OÈm$’Ç–‘Ýéú€fõ»v‹Ú—æAðÓEŸ̹[ü«Ñ'ú_‰èEò ÉlšõØ•æ+]D_ëir£TO“k7ÁO�è¯tïû5‡}RÊöº{ëÜ ìÜ{Å}Ü!·‘à8è|Ü=4Û”}"øt?_÷Ýð#'nå‚ FDµ bi"ùùf±k¸'aKÍ.£þUæ�bç°¶ÒÞÛÉÒ}"úUÓ®G„]è³…î-e»›¢WØýð�Èm$L»G¶:ÑÏvñ]ZðßœgÁ§EGêëzD ÕÔý\D/ˆäç…¤bÓiع÷çKë¸N»À*9áé~:#}�}[–5}zëÜÁ.�â À[ÝßüÜOÒ¤÷ËÏf^~!#øéÁÌlD¬½þ· "ù9%¬w�gcç �£ö#"“Õå?¾ <ÎÜ43ߢÿ/ªgÜ'¢÷©ÎÇ»h0˜t¬yì<Ø‚7�"; „™%¿ÓI>h°ï °'¼-d?“èHuÕýsý àzàëÒLDòsÅp6åú[ÀïaO�ÊÕ!øýnT{#6UûP^§DôÿÏÝЯp7hRʶ›¶Î%�ÚRl*ö±» ápL8É»`¢ž”}Å >Yd7Ü"÷ZRÊ:Ñ×#úc°;—Îs?÷÷ÔWg_É×4š\‹=ié™Nð'ÌBð�º(¾S˺îý%ýeNü»è¾•²�ÿü6…*Gë+’£g×Rû©tàçNð·µ�àg½j@ôK±S^'`‹�݃=r[D/’Ÿy`ö¨ØÁ&Eð�»›¸ÓÓÖiÑtÊDEñÆuf_®EÒóBm¤çåϯQòìñÓ_t‚iÑöf\_ð÷µ.¨Qô=؃¾Æ\¿ZÁ’{K$_7 »z~½=ÎVð?À»ÙŽÝ25Ñ%×1p£íÏ»ëØmçÇ›i¡–6³×õ%޾Þ'‰à¯ÄnÇiƒö6“è{kì—W`O»K¿G½H¾î÷{Õ#9Á¿®Á�¸þ&'÷!'ýnj�¡ë´<¤Ê� ÔB›íÛ‹] ¤jümmÖ·$¢÷]ßp¾ ŽFRëþâiÏ‹èEò5±ØèFωà“Uô›ü�عèq'únœCŠ‘¹3A¨ç~ÙêÇ3sÊ>IÑ'|;ãØ£•“AŒˆ^$?gøT+Öù)ÁŸOu›\½‚ORô»°û⃜Ÿ.Bm’ßîñ ’Oÿ…6<î5�ßK=׈è%u/’?"9¥¦O³¿ÃÝ€í^ÑN„ù•ß¶òÝv}P'Eð‡}²åôÙ FôFD/’ŸN?‡n…K�üÆ:? ÜŽ=Êñ la‹}HªZ„ú(»>d� @<÷\' ~ºèoO=W�èW!©{‘ü4¶Öüª©°DðÏÁÖ^oDðßÅ¡x[âuBš�  �ÞJwv¥ý=Ømrß¡óð¦EŸDôÏj@ô’ºÉ?YAéXª >š%ø›°•ì¶Ò½‡°‚Ðémw’ŸÄRºÒõ3£*¯™"úzEÿ|]è+¢ï2ÉçœÀOkÍü ØXv [ÅA˜½ðF\Ðð=lÝöÛ±ÇКßš zƒÌÑw�äû±ÛQòÓÅbì|£‚ÿðoØšÑ#Ò˜AhìQÔ¿~í¢Ünè_Ñßæúè<¶VI-ÕÿÒµî%ußE’ïNäÐêQv_ü…À«°Õíêü�ü5î&”ùwAš‰vrWtß™I­û[]ÿ}ºûX�è_8íy}‡J~»pÅP(?ŽXìÿj`]‚¿ ø'ìyð�4Aæ€nßz;��ªX ¼8£Æ¾ZDß%’Oއ}R𹂗QYµ´2nžcâ8‰àë9~¶ŠÝ'¥Á�Ã&÷ÉeZ‘ýÀ_c×'üðôD/sô(ùdþI�›XyA)³X•ÔsM¼ÊEðµ >rüç�Ï`SI‚Ð!l‘NOheà_]�õIà4‰è»[ò<õ0ÌRLpalÔ«ÀÔ+ø}Ø3Á¯¢ûæÇAƒ­&ú2lÁ±ÓjìÃ=ì–é"‹ñ:Bòý<õ0X \h ¯nPðïÄn““íq‚  ÇÀoßÀ®«ªGô— ©û/N»à3ó6¹¥Àó¨.²«Wðïu£^¡%^ \Mí™ÕtD p°)‰äÛ‡ iÁ+ßhµÌó°Ûä꼂÷¼› –fAZ‡ð6`7ðÁ:"úµÀ‹ª¼RpÙv¸­kÏiÉ/–§ŸÉ«åQÉ»Ðý»î[—à=ø(×™X/‚Ђhà£À£ÀµuŠþÅö˃ ~‘ƒ��Á¶®LÝ·ƒäsØ#a|£Y•ÌEÆèW¸?h ïC¾†ü0*ø?ñ5Q¬e‘� Bëb°UGËÀ×ë½A©½¨Ó�sô­.yÅ¡Õì|ì sC�‚ï3°z¯ïZŸÑOEñ¼ B{pð»Øâ9õ¥î xJ¡<@™í‘®[ô‡.èÉ7‘u@ßtÁC½‚NÔŠ“Þ¨¼É›ut¿l­Ah/nÅžEw¢_gàE±_åUÆÏ#=9Tçÿ;×èv}+K~°º9‚?y·â¬W®¼ÛÈ ¼ B»rv}Ö Øéj½zqd–eM|lØ×Ë·§Š÷Ö[®ür÷m@ð'ý'œu©áÊ»åþAh{Æ�K�¨Ýsf-&z±Ö‹_[,Ÿyjƒÿ¯¦½¶�·¬ä“ýðYÀ÷<–+Åó�—×.x°sð'ì„3_W> ÷… BÇb·Öý ¶o7X�û]âàcJ½7×àÿ»R$ß {¨L_ÁÇ1S¯à} +xœüðþ² =IDAT,øÒ�Ü‚ GøïÔ\0'Pðpΰå阱ßS|¸QY·Õ¼|«I~9°‚§¦è×Ô.x"`7Þä3b¾ºKîA„Že/p5Û; Ü¿Êðë�öœ�z_ÇWÄk%É/rQ|Zð/¯_ðÞ¥2ï$Ú"í_¡ãy[ʶѯ„__¥ÌÞ‹<ÿ-¾H~îé6b ߬À–%l ‚W»QÙ›³Ùøi÷‚ ]Ã�wÕ.ú)à�§ü˜‰}CÆß¸²7דéÄ Ó oj[—¾× þàw°çד¢ßêfˆþWhÙ/‚Ð]|ÔÓÁ¼›®Aô÷ÿ–1™Õ:ŽWjeîêÉy”ƒø DòÍAaO�ÛàDŸDð ^íòð®W^î“=!m]¡ëˆ½Œÿvð§æýì¡‚Ò:c·1¯ uæb¥Ôr‰ä›ÃrìÑ€½Ó¿ºö×¥"ÈìÂãz¼ÌgLTÚ!í\¡K-EŠÌs ñ�À µEôøo0qt©FÅ(?ö|õÓX‡#É7N/v‘Ý,�|Ï�žê½6ŽJÛ¤‰ ‚ t7†hx-PGD�ñzˆ/S&¾X¡Îïéí_!’o ›¢OÙ½¸1Á«�žÊÝèÓwMÆ7RìFAH¸xo�¢÷Ál€ø²8ÖUBï|?»¢íS÷ó�®WØ¢6‹�•.‚iý‚g‡Rê†~^zÁC¥`\Ú ‚ inÅîÐúKêHÝ8c.G‡ •¥§°ì®riÿ°H¾6Á¯ÃÎïtüK�Uµ¿/‚ì.Ï�n01Wãèá(Á ‚ Ó1À—@­^æxjž£7ÇG—Ç*TT2ôªüO‹¦Ò–sôó%ùDðkœÔ_Ô˜àvã Ü”‰Ë×Ffì‘Ù*'‚ –ÀϪO𨸱æ¿ÇÕ&zãC´Ñ˜âKB0>q¬PwLÛ‰~¾$¿›¦_ ¼{‚P‚Wvã­¾ÙSS7e˜|(0Q,íWA8:Œ‹~–O¢YäüS—èµQ—ÅŠØórÊ�Õ]å¶ý|H~µüª”àWÖñ‡ v‚‹ò&î𽉻ŠAYN…Aj=À‡Ý—uˆÌ&ƒw¹¡Ï‹½‚Êgöÿ¤”ˆä-˰篚Á×X+Ø !~By|Cyü côOƒ`"�&+‚ ÔÉ8ð¡†Do̦؄—ÇjÀ×ñ/›ÿA �w»ä�“¼²ôîB¯Ã3ßÏæŠ÷TŠãEi§‚ BƒL›ë½ñ¡¸“»Ìè<‘ŠMO~ðŽre¼åE?’WØýï'4Ág"X±–Ý¢þwôÐÏ*E=%íSA˜%cÀ'œ«^‚=­7ilÀø—‚†±‰¼¬÷“8Œ[ZôÍ–|/p Ðã¤~9v«\‚W!ôïB­ùfΟ¼-—™øñdY—¥] ‚ Mb—R\`L=¢�}ˆ7ÃeqäEFeLÖ7w†:lYÑ7Sò¾‹Þg)xµÏ»1›þzáà/FG'e½ ‚Ðl~Üá>¯CôøÀñÆø/Ŭί/»xp÷ÇÆ¶äéuÍ–¼‡]9_§à6Eß³ÃóÊ×ù…âÿ§öï-I+Aš�1ÄÀwSº¬ÑgÀœQVǹ\)Üäõ÷ïøÁääHˉ¾™’_†="ö™ÀENö5 >ÁŠ=J Þ˜Ë ÿuyjHØ ‚ sMøqJF/Áž­Rù.‘û7üK+•eMÔÛŸÿqq²ÒR¢o¦ä'�ì�{S’WGID°loý÷ c)—Eð‚ ¼1†=ÐÆs�K±§¤Ö¤V|ص�8û¢8¤yqœËå•–™£o¦ä'€ÜÇðFà ìb¼Ã‰>€Ün¸5ñ!ôƒ’ Aæ›mÎ[ —a+µÖ¸¯r¼‰ýË£Ê*Ïóú=¥öþÈ˜ÖØ^×ìÕõà1à PÞœþTÑ+À ޖɉ£ñ¯Åz·–v&‚ ,¿ÁžršHêÒÚEO81Žã߉M_/Þ©=˜-ß!^ø‚9s±O>ö*Å-�0ŠùKcÔé`œèÐÁ¢]Ê›øCÏ”ïŽâÝrÐŒ ‚°�`ë´çê½ÎÀØ&LßåÄyÔR“õËß õÄD§IÀãznÍæ•+úÝÆ„§Ùˆ¾WÃÚaÔ1o5ñ�î dƒœ ‚Ð:¢ßÓD¿žšã•}ع³èùJù“Ê�Š…lᇥriÁÖšÍiíú(*OdÔeßÎgÏU‚mo7ħÀ’ƒ°æ�0w|_Ú“ ‚ЂìÄN?á©ûD_ñ`x F½@k&MÜ_êí齫XÞ¿ EÝæüº(¼mÜäßñãý°@üøs=rŸŠ¹ã>iC‚ B 3 |‡êz²:Do2Ƙµ.¼,öÖ÷©x “ïyüÇ•òp¥ã$ +ŸV™·\‡ÿZ¬·”¶#‚ ´%àFì‚r…-òV£èÉB|²‰Ã� Ì.RœâyJß›Ñy=I53_ÿ‘‰¾p@Ú‹ ‚Ðfà×ÀûS¢_[›èƒ ìY‹Q/„Þ@ye?w𧺢Γ¼ ‚ ´1œè=àEÀš£‹Þl[mèÍÆÆ{ÈÌ£àEò‚ ‚P;£À\DIí¢/ôŸÎû‘éžüÍA¡f†�ÍÀíÀ.lm˜#i¶è©ÌÁü ^$/‚ õ³øJ ¢/zŸŠM´{¡^¨¤ëA¡~îÝç3¥î‹Jq�ïÇŠ°è›H^Aê'¾ Üë>^ œœÜ|ZÁcaÈ‚ÖuÉ ‚ BcìÑê7·`kÜÇîaâ8•E$/‚ ͉ì[î4Yx'‚ ŠH^ADò‚ ‚ ˆä˜Ï*¼‚ BGÊÐO$/‚ ˆä;ñMý9q$ZAA$/‚ ‚H^A‘¼ ‚ "yAADò‚ ÔÍ}î£ÁRIÛ äâ‚H^„öc³Ø œÇ& PÓ­.–‘¼ í„BØl¦Û\¥¿c3æ#r©A$/BaŒ{þåG@=xê¡Ô?ÚÓÆÅúF.˜ ˆäAhC®sð  •�ƒ�•; sófIÕ Bðÿ©d%/FÄ’bIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/results.png0000644000175000017500000002277214757047403022472 0ustar00paynopayno‰PNG  IHDRQˆw3ÀsBIT|dˆ pHYs??•ˆlÆtEXtSoftwarewww.inkscape.org›î< IDATxœíÝy|\u½ÿñ×÷Ì$“t/�EQA–V-JÀ¦)t¡išbËÒ´ˆ n¸]~ŠÂ®r/WqAJ ˜Ò%I)mIšÊÒøµàUDd§{›mÎ÷þ1)NÒ9É4gfΙäý|<£sæÌ÷| Ì;ßó=ßó= û|x °ú ÕÏ[ÀÕ€ãýW'’[Sþ‹ Ÿî¾êù·'9£TNštңʠ è�I‡]€ôh@ÐôG ˆ¤¡A FÑ  ‰!ûm2„Q£FQK¿÷Ì3ϰk×® Ëûì׃8ä�C(++ ¢–~ïÅ_T@„„N1’ö ˆX,D"¡¢€HR@ˆ¤¡€€XÇOç� i(A! ð¸Ä©€Q@€G@”””仑ЉÇŸŠ2Ø;àö°O °'ƒ¶¶‘œcß�f`ommÍ`Ÿ½íuuBº�ÕƒIÄ àÃA6ÅÅÅA— �½¸Ø ´÷°o�ÉDŠ@¢‡}Z�Ý´•Í_ž¡Žºˆ0Ò)FèÜty’®wýp.y˜hÇ�§�LÊÚŽíÃÓÃgK€Ò Ž‘Í¶†g°OVèC4,Ͷé?5ù,$ ¼ÝñçÝÀœ|<�JI†P:ß¾×u£"tö¯e°_w×û ÍÜ—�÷;Zû˽{ñìL;8«1ˆÐy8-‡í3Øo(=_ý‹‘Ù—9“ÞõBàð ÚʉþÝÙï2g4%‰Q‹§µã§'™\1˦Ô+o=]õË:̓Ð}n©= Dö›j­+" ˆ€©!ah@h "MbÏž=<öØcD£ÞÿyŠ‹‹qœôùjŒé6d"‘H·ƒ Ñh´×Çõ€úDÀöëAlÛ¶�x ˆZrÎqœn騨¨ÛÚX,†1éÞ�1݆SOÇތ۷o÷ܧR@¬_-Xëº.ÍÍénIIêî= „Æ ¦ÿf ˆ€õÍs‰¾'“¦$Ëð%…àÞ  ˆÆ ö:pÉi¶1Òß(³O0¨›÷{šã?ð4=»§©À~ŽíÐýXŒßcw7=¹§cï~ ÜÚÍ>}™"$vwü¼t!")4!"ž"âI!"ž"âI!"ž"N ‘pSBD<) DÄ“BD<) DÄ“BD<) DÄ“BD<õôä­œR@ˆõ D¤�bˆˆ'„ˆxR@ˆˆ'„ˆxR@ˆˆ'„ˆxR@ˆH8) DÂM=ñ¤€O ɈBDÞÕõNN„ˆ¼K!R(ÆÆW|gìU+NÊã!"a7!Þ_qp=.õ§þ¨ö°<Z!fcã5µ°ýàK›ŽŽ´q/Ø|¬ôèjRÑ   «qW/?Æ&ÌJà„”Í[Á\ &ï¿Í  ¡€IcÌUµãm‚å`ù÷VówILßøÃ™Ïæ© �bˆ„͸+.2®]×9Ø`HŒÝôÃYù P@ˆ„‰5ãâËãÖò[ øÝ­pOŒ¡åâ³ÞÈsA�„N1ú�›ÿDÑO¡-è:ÂlB¼©¤™ÚßYÌy)›­Á^µ1>sA@c�„z}Øò5Œ^¾–…‡¾Í›ËÖ01èzÂêô-=¼…mH ‡f zC¼*P8@B=ˆ>¦¶–Á¶„y¾ |xßÿRê–­åìYgñ‡@ ™Sãµio³õÀûR6¿¶rc¼ê�AÕÕA!ÙQ{?Ç'"\äZ.†§Ùe ±¬Z¶†ŠY“Y—ïúÂhÌ‚åS�µ÷CR6?c¢‰Š ?8çÅ êJ¡yÒ{7ÿ‰¢Cߢ ÃW\ø”GGx0 ãÏÔ“H» öX{�O³×¸ÏyôÓvUWúGbÅZ¾o-§aiÄ¡qæ™ È{@Ô<ÀÐ"—·è¾÷òª�‡-4¸ V�3�—s]WX­ZÅ�–ç_>œn ¯¸µ-Á/çLãM¯¶úsHœ_úÁ‘•À‰)›wcÎßpeå}AÕÕƒ¡À¶”מÎgyˆe l\”cHÿ›0•6ci4†Æâ˜6�°ž#fÍòµœŒåË$ÿn¦ÙÅÖXøÕÓY�ãfÒî²5\Ÿrº°Ûš¾}º16¾b°84eó .L4>sK@eebÉïå>žÉg�œbìS_Ï€Dã\‡IÆ2 ø=ÏÍH¶†Ç¥akŒ‡/*£9÷Õæ^M ÅÑaTšä•ˆI»m~o~:ëLz5í·?õ$Æ,Xq®±Ü”ìÛfa“-23½¼òõà*ËÈpà�”×'ÿ?Ÿ]Õ71"ÑÊX×0¾#0Fgð±½À#ÆÒàFxäÍá³ñ?æì ¬´Ì¼�òúÃÀæ|ª€èjéj7§u„ÅTà½|l°ÉX¬¡aæY<Æ+$Öbj×PŽáb U¤“i1P—0ü윳x$Û5ôÕ�˜zãªØ¶wZ \�²ÙZøÉ¦xå÷œy ÞJy= Èë)Q¨¢«¥ |ÐI0ÉÀ$›ì‚§›Ô‰�×€‡,4DVWœÉ?s_©·ŽAÚs1|ËH�Ýž7–ßDbÜVQÖé�¬ëk!1:^?"†»ÜbOKÙÜb°Ÿß¯ZXa½3: :+ 2USC¤h('Ë$k˜dà4›ržÙ�¿C²wÑîÒ8gJ§s¼œY¾†ÑÀÅt?è¸Îni߯²9sHä£.è;!1.¾ìÃg%ptÊæ·‡ªG®˜ùPPuùÐ5 FBïÆ�z«`¢«š ”ï`¼5œŒ>EÏWHþ=àiyÄ4³¾²’�ÙªiÕ*bÍQfô0è¸ÍÀB~:c2/dëØªÐCbì‚“±üžä¥Á}6[ìôMñªT–_‡©·˜Ÿ<—ÏúL@tUÓÄ âƤ\!ù8=ÏmožÚw…äõü¡7žKø q¹Ø¸|Ã�ÝniÌ�sÆŠ³B ‰qñå[Ì/IÇ1ØZJÚf?þÿælïæ£aw(�z¥åà/ù, ÏDWµ –p9£#,¦Ðùî=/xÆã8'�abÇ ã, ÒuÍÖ°¸¡ê,þìçß'W )$f×ÔD^ÙRü?69‰,…¹¥õð×.yü‹_,¨«YiFr mŸã�ÿÍgý& ºê2àYNfÿîoøƒ…\ÖVMåË›Fbùð�ÏýÕXnk…ßäkÌÃ�B‰ä´i{7pvÊæ„1\¾áÊ™×UW–½x5åõqÀ_óY@¿ ˆT55DІ0Ú&šdXŒJ3øèß�#�Xš÷Ú1Ô—›*'ÓÆK­Ý óŒËO^]÷�HÂ] �®í²† 6]9³>¨ºràpà_)¯?ü-Ÿ( Òø]%C[‡¥ÜÊ�SHsÊ�Ž�×,Üê&¸¹Ðï! cHŒ�×�qqW�ì~ïó Ž©ØxEå“AÕ•#G¯¤¼>x>Ÿ( 2�á€çãÀ-ÛŠYØW¦~C¸N7Æ.¨��µwйw÷h;E3‹Ÿýš×ç Ø‘Ðé—Œ¢,]ÍáŽC9.åöX¸iÖäüΑϧà{ÖŒ[P{©µ\Cç`¾·•È…�Ç+|O=©®q ÉÓÚ¼Q@HF‚êIL½qUlë;-·Luêv 7nâÏß"Ïè.ÖuðRÊëB~çÊhUkÉȬ)\n-?NÙ4À@}.WËþä�—¼í�Öµ]¡¸pS|æ7úx8@]QJ W®{³kj"ÿüKéM[ûã˜KIþÀÀ[ ܪGã³ÎƱ Àû€ÔÅsßßåuÎ) ä€e#$&Ä›¢í¼ó¾våÀHke`¤MN'N.²kكٷà®ýk;ý�ñYy�(°£�ty�×› Ò+™†Äè›o.*}uÄ{ÓÁHzškb¹à àÁvöúxÕ¶n÷ï{ÞOç1‡÷ÑyL"ç´ì½ôʬ)\¾l5¤„Ä‹¹ï;·Îùï /Ÿ�Åžf¯rL¢Æþû:ãic‹ÇL*r‡n ÙjÓùø„BȨxMñ0§äC®µ#ÿk“Û6å˜_<{Ò¡�'8Ø’O¹âò—vŽâŸÛ?r Ín5ðw [Œa³ [¢6±ùáø9y½¤B  §©7®ŠíØÖ~¬kíHcÝQ3’ä‚%'¸®ëX ÷?ÿ5vµgìQ÷Pä´pÎ ?bés—§ ‰­À0›1l±Ön.*Jl~èòs^íº£z²–môµ5C£­EÇ:®ea¤ÁŒFn{§õýt\·=üúÐKÉ«�©!ñé®v×¼pɪÍoNh°Ön¶Eæ™X$6ìt™Srã´kVokkû`× ûzÿ›êU`³…-vó…'}ó´C½8/åýÐÝZ`Ž¥óÝ›GÐùîΜS¢;5¾b¤ À|*ÑÒ~ˆÓ‘ÉfüË(¼``KrŒÀnI¶ì-ðÜÓß�¼;uÇ p˲ռ”:pÙ1™J!Ñ;��A¨Ñ�_z”ƒ³Ì…dx*ÉÕ´ž»Ù`žµÆn6–g‹öÜúxÙÝ|¦¼ Üqt^Aê=t^a*ç}ÈøëjÛ½î·-æR¼ç´�y Øb±› lq»ÙÔ¶%›ÏŠPHdÅñt^ƒò0:¯Q™s ˆ>`B¼©¤…í—ßcÿ¿Ã6ƒ¹ã6ZÝcÐßò5§@!áÛ t^ÅúPð~öj.( Y<îŒ5;k¯cÿåî,p/˜ïoŒWæu¢T _N¤ós0�Ü>'¥+D�_1 ÌìGÓ¼Ýè:ö²G¯¨z<ï…¥¡�赑t~ÔžBº76¾ü“`®&¤y{3Æ,Øxeå’<—Õ#…D¯t ˆt~VgÎ) Äø«k�wöjàÓìùëŸû£#G¶Ý¶dΜ¼=‘ë@¥[™ —éUSYTMbÙ>l Â±,©œ’—ÅcGÑùiÞC~WE×<ˆ�;ýÇ5‡´µÿÀMد°ÿß×ÛÆp}±ú³½„Y“ùî²Õ´¦ô$âp_XçIÔÔ‰g,–鎥Ò& ±ÉÇ$æciýÀçA( BjB¼fP«)þj{+—Üåí=~ÞVÒzM¡=9*Ý] ašLµf ÷ÂDk˜�¥—aÐå›i¨ Ÿ„N1BfôÍ7Å^=ô"‹¹ŠÎK»´ƒùm´¨=^è78­XÃO,|7eS`§ËWq _ü3èþg+–¦a1¦—•‘ëËÅžJy= Èë/DhX3vAݧ±ö’«wÕ`p¿µ!>«Ï¬žÔÀe<Žóѱ| ¨¦£{øÈ;±¬´1êªÊÈ×Â5…N�h ìÈÓ±D(Œ‰¯˜dà'ÀÇÒ¼½Ñq¸¬@_ߣ|…DÍJ‹w2É&a:ÉŸºó‚�z,õ½}ˆsœ ¤> hdïéó™P@h|¼ö÷:0éV†Þ‚1ñ0^²Ì¶\…DÍ*)v˜Šaº…©À nvwI~WõU“ Ã’�O¤¼Lò�Òy£€À¸ÿ\z´m�\ T³ÿ@ÔË{uØ/Yf[¶B¢n5£\˜Ž¡ÂÂ8º¿•}°¨w-õçLÉï­Ôø8t *D_6:^?¢ˆÄw |“ýøûŽ1ü¤P.YæBoB¢©‰èÖvÆ8.³-Ì$¹°kwÞÀ°ÆX–'X;m-Y)>7ºÄ `·Ç¾9¡€Èƒ�\¿fà ={/±–ï“<�LµÇÂÏK°×öÃU›÷“IHԬ栨C¹� ,3HÞy3l±P�aeÕ$) '­�þ”òz É^OÞ( r(å’å’÷ò§r�¥{é¦xÕ?ò_]x¥»jáóÀ{MòÊÃ8ºYçÂ@³…uÆP‰°²¢¼Ó² É)Àc)¯Y»%?š(•—,_µ?¶Éeújp1ß~4^ùtÞK+3'séŠ5� ÜÝÃÇÞ°†û¨/µ¬�<9¿]ñ |¢”"ËÆÄWLr¨½ÖÚý¯­[Øä`.Û¯|0ˆÚ Iš�ØŸa‹±ÔõÞȦxœ¾ö¬ND_1þªºQ®ë^ ÌNó·øÆ\±éÊ÷‚)”óßḀ̀͜ËVÓ–2&‘0° K½¡nÖ™�Sé‹…äÔøª!»¢"ûNû@ã2Ø`¾àºîyìÿ´ô—16~Ô‰m·÷§K–Ù4k —/[ÃëÆðfQ+«§OgkÐ5å‘"[ÆÞPSêìˆ 7´—X§¨´�D ®-5Æn0%X[j°%Ö8¥[‚µ¥.&ù¶(S ¶„äzŽÃéôC 5Å$¿é ×óûNƒ½Ái».›ë<öW³&scÐ5¤?8gL|ùû8Ë5ÄÌ×ÚA`Š [f0É/g)0Ø@Ôb†l‘M^Þ÷å…àb�¸.É%ÞMGæ&ƒ×bÀÚŽW&Íòï]ú€»ø´^³!>'¯÷íK¿Ð¿zŽa´µææ}v5�sÿðÜ÷5áI¼ ,MDœËþøÃ/ô¸·Hfú÷)†µÎî<þ;ï%ù~Ðn`›…V`·INÆi1°ÝB»…íZŒa�µf·Ámua›1¦ÍZvZÜf³×ºvg1¶Ý–Fß|ä²Ê¼ÞD#ýBÿˆŽ/fê·­ãKÚ ì»L«�í`Ú\ìŽw¿¸°ËXÛÖÝ—Xlk´eOÛúøœ¼Î_É’À’3)-y^ëNDzt:Éïæ¾Ÿ¼ëzYNDÂ#ð« ‘ðJ õ D¤„ˆxR@ˆHx) DÂK=ñ¤€O ñ¤€O ñ¤€O  /„Hx©!"ž"âI!"ž"âI!"ž"âI!"ž"^ ‘ðRBD<) DÄ“BD<) DÄ“BD<) DÄ“BD<éá½"’õ D¤�bˆˆ'„ˆxR@ˆˆ'„ˆxR@ˆˆ'„ˆx < ¢A´phÐEH¿±Øta¶€xðJÐEH¿ñ9à·AÑ�À{:Å /„ˆxR@ˆˆ'„ˆxR@ˆˆ§À"lW1¶_ºé7º€( ºØÜt"!x@èCD<) DÂK=ñ¤€O ñ¤€O ñ¤€O  /„Hx©!"ž"âI!"ž"âI!"ž"âI!"ž"^ ‘ðRBD<) DÄ“BD<) DÄ“BD<) DÄ“BDÂK!^êAˆˆ'„ˆxR@ˆˆ'„ˆxR@ˆˆ'„ˆxR@ˆHF ˆhÍÀX`aÐEH¿1x2è"Ò0=ï’[a ˆÀ±A!ýFiÐxÐ)†ˆxR@ˆˆ'„ˆxR@ˆˆ§À"¬ƒ”¯¢«’?o]€„‡-À…A!":Å‘NŸ¡€ ¯ÀO1"᥀O ñ¤€O ñ¤€O ɈBD:ÑD)ñ¤S ñ¤€O ñ¤€O ñ¤€‘Œ( D¤̓O:ÅO ñ¤€O ñx@„õ¹"’£€˜XW}>†*wPtþú²Û›»ÛW=‘ðÊz@Lª¯žüËlgW{ã„úóGt·¿B¤0øˆ²º G¹–å@¬£ÅqŽ�üaâ}íõ„Hxem¢Ô™µçaH¬†uyk¤q��e+/�îs ‘ðÊÊ)ÆÔUs‡$Ltð¾tï[ËáÆuÖ—ÕVŸÝõ=„HxùˆÑ7_\ÔÒnî>Ú¡vbý¼/¥nT@ˆ„—¿€°˜!Gìù pf†Ÿˆ`íMåus†M[—9EÂËW@L¬›{† ôsóõòºêaÕ´|A!^½ˆ‰õÕŸÇòƒÞØæ¿]¢S ‘ðêU@”×VOÁr“Ïc'Œá„HaÈ( &­˜{’u¸¿Ã–o6V,Z¡€ ¯š1aÕÜ£\cVaêó°×®«\ô ÐU ‘0ËøcRÍì¡N¬Âp”ŸZÌïÏxâ˜Ë÷½V@ˆ„WF1»fv±[[Šå$ŸÇ{°$:ìÂx<îîÛ € ¯žÂbÞ.)¾(÷y¬-­Ž;óþi?oIݶ˜‡ÿtÒoÜ lºˆnôe+ç^ fž¯ƒ^µŽ;íá³ïÚÚõ½°Äಠ‹�~ã�p@”ÕÍ»ØX{©Ïcì4®svcÅ¢Ó½¶€‘ó ˆ²Úê³ ö—>Ûo·Ž™Ý0}á“^;h B$¼ÒÄ„Úy§Ãïñ?×áëMÓï\ÓÝ. ‘Â`Ϊ›÷ÇØ•À@�™«ÖU.êq¶¥B$¼:M”*_6ÿàvìýÀa>›½«©âÎx&{†m Âv]„ôíAЃw":°(b£n-p¼Ÿ-¬ÑÜ|&³©Ûa ˆç€AA!ÀÃÉ &MÃg8€ÝlEUKæ,jÍô:Å /pìçF3七}†ÿŠº‰©ë«nßv R@ˆ„—9rêq¼wÆ ~ÛÙa ÓÖμç¥ý B$¤/?æ°ã¾ø �ÚŒåÓM‹žêÍÇÃ6!"ÀÄú >é¶Ú�Ç×Ê÷Ö¸ö �•‹èm ‘�™¸üÂc°‰z§ˆˆ¿–ì+ßá§„HˆL¨?6q?É{ÍÂmM3ÿÈo=ƒ ‰±5³KëÔòÙÔývðË_êy·ž) DB �;¥±Øb0c}6õ„ÛÜ2g}Ùú¬LS@ˆ„Àƒþ§ª|5byÙ�ÚÊõs–ìÊRY ‘ •×λì×|5bØîX;mý´Å/g©,@ƒ”"�*««žc±×øl¦ÕbÏi˜¹ø™¬•B=‘€”¯¬>ÝÀøûZ0ŸoªXܘ­ºR©!€I+ç�躬[â§k¸¬©âÎ;³UWWêAˆäÙéK«w]w؃ü´cà–¦ŠE×g«®t"yTQñ€¢b–ƒy¿ŸvŒá¾Äà—¿š•¢º¡€�¼›Ðô™’ usÇ]G¾MhšÝm÷,Árª¿–Ì0 ksº£€�¼*«­>>²£}£ƒi˜P¾ïû˜ IdçQ?¦ùiàƶϨ¯¸eO–Êê–Bò¦¬¾z¾1üÉN:DjÆÖÌ. º®|˜X?ï¾â³™·±Lm¬¼ûõ¬•]Å�œ_ûÙÁ1Óú+,Õ�Þ°œ4 ¤øZàÁT–åµóγÖ^å§ ›pÛqLeSåâ¿d«®L¨!9U¶ò‚Ñ1Óút ‡󵲺 *ó\VÞLª¯ž`�½�.+Tk-ÿ¸wó=M•‹É^e™Q@HnXLymõ7ŒëlŽífOcp~7©~þûòUZ¾”Õ]8ʵ,b~ÚùÛm�óÂâ§²>K2 ɺ õç�(_Y]o ?Š3øÈp×uÍ®™ís�”ð8³ö¼# ‰UÀ0?í¼Tû,/Õ=^O÷Î1„dUyíeŽ�) $ëœææ¯XxÁGÓ&ÖϽ$kåAYíÜÏZË}6³×gÆwýµãµBúž†9K¶;Øs�ŒŸ¹?sý¤ÚùËZQ94±nÞDcÌM>›I`ìÜÆŠ…S¶) ¤ojœ±ø1à MÄ\ãÖŒ¯ýìàlÕ” “VÌ= c—‘ÙåÜnØo­«X¼¼ËF„ô]ë*ýÄîóÑı1ÓrcÖ Ê²‰õó�t�Y…e¨Ï¦®[7cñÏÓlW@Hf°‘6óYcxÕG#Ÿ)¯�›všv�¦®š;ë®Âp”ϦjÎxâØïg¥¨P@HN­�uç¸î\ÀímÖ˜›Êj«�ÏbY¾Œ¾ùâ¢æK��ølêÁXtøüx<îõßF=éû+ïj²Æþ—�&cÏ®™íó”ÕÏ›†1¿òÙLÂZæ6T.|2ÃýÒ¿4V,¾¸ÕG‡$Lô®|Þ^¶ò‚ÑÆÚßãs6‹ýzS墺øˆBúwpôkÀÓ>šøÔÛ¥%ßËV=Ý9«nÞŒëÜ òÓŽ1\Ý4cñ�ôŒÑ·kIDATö@Òÿ¬/»½Ù¹ØÛëF¬½²¬vîøìUµ¿É«gÔŽ½8ÌgSw7N_te/>§€�þ©iÆ›±|ÛGQƒ¹§|Ùüƒ³VTŠ MŸ)im�Õ¾æ_XX‹¿ÌÜ/„f]墛0ÜÓë GÙ¨½=ë·†[ŒÙÑ~«�Ó|6´Ù&¢U=ÌuèŽzÒ¿¹íÑ/ƒýGï[°ÓËêç~9kë«ÿÛæúlæ_މL[_uû6m( ¤[_uû6Œ=C[oÛ0˜&Üw�¿%Þ:L¬Ÿ÷%à[>›Ùi Ó*þÓg; ‘uwýkøh"æ$ß·†O¬ŸW�µ¿ðÓ†6ŒýtSÅ¢§|µ³¯µS@HÿuƺÆÛࣉ›Öÿéí‡Ëëæ~kïü̯°XsñºŠÅk}´‘J!�Ç]Çu«�×zÛ†�Ï•×WðØÁÄåc1+��½=v²sźwÞî«�.-¦üY!ý[cåݯËEøø2X˯Ëï›\¦ûO¨?Nbpho� `á¶uwþ§Ÿ6ÒP@ˆ¤j¬\´cnðÑÄ nF·†�­™]ê©Å�q ¤caµüò—ü´V  �íÿ*ýž�M½ý¼…Sމźým�Ç�Ò’âEXÆõö8ž‰4·œ·¾l}»¯v¼Zÿ7õ Dÿâ-m6©vô¶ køNyÝÜé^ï?ôñ¿þ˜Y½m?y^v#vZÜ%Û}µãM!’κª;ž·ðM‹ùíéK«ïúFY}õw-æë>ÚØáX;mý´Å/ûl§; /M3Õ¿óÑÄ!Ñ":Ý>±vÞlc¹Ögi­ÖØY 3?ã³�žQà˜Ž?Þ ¢/8÷ó‰¦%9¤Wó Lxlés;�æá'uÛÛ9E‘Þß»aáÙŸoj{µáoKzÝFæü.§ï›vá÷ú¯H úÀpN¹~ Nqïæ0Ù„Ës¿x”c?;š¢ÁþÖ½}þŽ'yqéf_môÒùàãÆ¶^ŠãÀße‘\jÝÖLûž6}d¯>oÃ!cÞK$æoª­ùÏß‘éjqYµ ¸ðsãW¯ Läûà"bì-3¿[úžAŸâØÍoî~âÑKê®OìM$ò|è½$Wßò{ãW¯D�ðõx4‘¼ˆ1 —'�£óy\tÔ  ‰½‰Ýù9™ah¿­pHR@HÁZ7cñýnÌj£ÖþzÝŒÅ?Íj›L!-~ðD–š«?¸¥õ’,µÕ'h B ^ù}ó�³ ÷qü<ϰaïÞ–Iç,éýÓ¾ú õ ¤à5ž½ð­á«½nÀð|´ÍT)ö§„ôëæ.3ï?öVĸ㨸ë¯9)ªÀ©!}F4æ|8�y {�qf(¼) ¤ÏX;ùÎÝÆ:s€æ vw1vncÅÂ�¹®«�) ¤Oi¬\ø4Øïõ¼§ý溊ÅËs_QaÓ„ô=S^?w¹ÅT¦}ÛØŸ4U,¾,ße"õ ¤ï1ØÇ^Dú5j>õø‡2èa¨!}ØÄÚ ÎÀ8ëØ÷¼MËCî�èYëËnÏdŒBPBú°u•w=h ?îxùlQ¬e¦ÂáÀ( ¤OK zù* KÜDtÚš)K´jûú?Cú$G|��éIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/results.svg0000644000175000017500000001203414757047403022473 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/rm.png0000644000175000017500000000053414757047403021377 0ustar00paynopayno‰PNG  IHDR87YЉËsBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î<ÙIDATh�íÚÁ ƒ0Åñg)ÔE<\ {d q#q…ä image/svg+xml././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/roman_four.png0000644000175000017500000000140514757047403023126 0ustar00paynopayno‰PNG  IHDR%+ÿ”AssBIT|dˆ pHYs°°œÔtEXtSoftwarewww.inkscape.org›î<‚IDATX…íÙËjAÆñ_’ѨQb@E£xÃËFp‘•+ßÁgñÄ��  ¾„  †ÅK\ˆˆ �ñ’h2.ºÇžS3=3=qhèþª«úß眪®ªžÀvH[-låG¿ÖÄÏ@ŸÊÛk• &ð+¿a\¬5)'ûUÕZ Ü naWI{‡'8€A�<ïò°öåç§1ÜóXÖ1Bû$ëíÇülZÖcËåºE/×ÿ"�Úd ¶Ž×�~¾býI\ ô…n (xh§°»BÝ3Øè‹ÅI�PSù{ÙÕ„¾PœÔ Eµ^IèC{j9¡W�Š<µ†ÕâbP¨·øèzԛĥ@_Ôö j /½—§æü«Úm¡ýbP(âÎÊ×”õÌ'†ƒZIèçºÔéÙó¨ßStÏ«ÈSM¼i†�êwX˜�Nò¿&�Ã@}Àç> NŠóm¡, Eì­Tø*å£�:ˆ#�^©ç1(âFžjâUYÜ.¨T’?ÅfÝPË‚%Ru\Ö²uäSPkxèådO%yG>1<qÏ–ÚN%ùH image/svg+xml I I I I I ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/roman_one.png0000644000175000017500000000045614757047403022741 0ustar00paynopayno‰PNG  IHDR+qNsBIT|dˆ pHYs°°œÔtEXtSoftwarewww.inkscape.org›î<«IDATH‰íÖ» AEáÏeAØÀGn öcb¦ö``j¶b Š  >WXÇñ…‚Éø“ËÝ;Ñ­á€Ì… ¶â¬Ên•qŽZ%(ʋюd­,|Löºò”Ó·9&AV ‡n�ï0+¿¹2$âÜ2Vüú’ ’ ’ ’àÇ‚ô+Ù�H·ÀÔeˆÝ0r¿Þ½ãOÞà¿+-ÇÂýXj –±F]eŒžSá'Û½ÐÒIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/roman_one.svg0000644000175000017500000000673114757047403022756 0ustar00paynopayno image/svg+xml I I I ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/roman_three.png0000644000175000017500000000062614757047403023266 0ustar00paynopayno‰PNG  IHDR%+ÿ”AssBIT|dˆ pHYs°°œÔtEXtSoftwarewww.inkscape.org›î<IDATX…íÙ=JA†ágtÅhä5 DMÌŒM=‹—016o  ^Â@ÓEüƒ]aéí•ZAv‚z¡’¯kº_h&©nð†“é£Å×°¦¥�w4Ã*Û³ÁæÿpØÑΩÛÏ’”ŠÒöp\Y8ÀR‘ÝâºÈV±]ùþ wE¶…µ"{ÅE‘}N²}2øãFë´Ò·[ék±_é=¯ôÝן›d5KR*JJEI©()%¥¢¤T””Š’RQR*JJEI©()%¥¢¤T”NJ58Äf‘ïÎ>à²È¦™Om`½ÈžqRdGp¦>cšUíuòú:9óì¤T�¸)jÃþŸW‡E¬Œô-Wz_  Ê=ƒïo/¾×jX”|µ–YIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/roman_three.svg0000644000175000017500000001073514757047403023303 0ustar00paynopayno image/svg+xml I I I I I ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/roman_two.png0000644000175000017500000000052514757047403022766 0ustar00paynopayno‰PNG  IHDR+fl˜ÆsBIT|dˆ pHYs°°œÔtEXtSoftwarewww.inkscape.org›î<ÒIDATX…í—½ AFßÝ-&â%æ X€hjZ‚` ¶ab– &†v "h"rk �7ÎrèÇ L0ß|ìÛ¿dàd”ãܨp©ðl�*�Ö;ëF·¢Ð ‰H"p|¬y¬”Æ*úFÔ90R|;àôQïC;X^IyÍý€o,Œú d È@2�� d 5ä€0z/à_‹:øæÀDŠKôç—YÄša›7,ã€3pz›òCg¼N~¾è-áû–ü­b8øO·ëIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/roman_two.svg0000644000175000017500000000773514757047403023013 0ustar00paynopayno image/svg+xml I I I I ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/ruler.png0000644000175000017500000000323614757047403022114 0ustar00paynopayno‰PNG  IHDR00Wù‡ pHYsÃÃÇo¨dtEXtSoftwarewww.inkscape.org›î<+IDATh�íškhTÛ†ßo}3ÉL2#Q+‰™6–�¢T8 �Õ¨�Çh‘x=p$ET(DDÅ?ï­ŠˆJÔš"VjQ,¢DTüA«â‘zD±ÄÛš`j¼4æ2º÷~ûãÌ2™‰Q“¹úÂþ1›=ë{ž5³×Z{ÍIü/Ǥ` ù¿@2""_{½ÞïŒ1D¤äƒ“̨À¯EÄ?~¼=tèPKU[ü´ÏëÓ Ü þk±***ìÎÎN>|ø�ùùù–ª¶—Ѿ«¬¬Ìnoo§›G�qäÈ‘–ª¾ðóŒ0_DÞOš4)ÞMCCC¡�¥ªÿé-‘ ð³�1ïKKKíׯ_Ó¶í8’|òä G�e©j3OFø¥1&¦�4Á—cÞ–””X---q=}ðàAŠ+++ÙÕÕÅ .ÐëõÚªz@0­&cÚ‹‹‹­gÏžÅÁ»9tè�1,--eVV–mŒù€aqí¥~¼ª¾…BVSSSŸðnV­ZE‘Fö™Bø/TõUaa¡ÕØØ{ñâE^»v-úúêÕ«ÌÉɱUµ©çM›£Uµµ  ÀjhhHØÛ'N¤ßïç•+WxýúuæææÚªÚ`äÛNüOTõùðáí�$oÞ¼É3gÎÄ<}ú”£G�¦Ïçc °Tµ@a¿í'¾DU[† fÝ¿? »xñbfggóرc1õõõôù|¶ªþ À�?ªFá‹TõÁ`кsçN hGG+**¨ª›t�$ÁÿPU›�€uûöm&JGGgΜIá¦M›8bÄKUÿ `Ì'ÕJ|¾Çãy”››kݸq#!¼›ÎÎNN�:•hŒiÿк?%Fcú|>ûòåËqÀmmm¬©©¡eY$¿¿qC¡�%"aUŸUsá`Œ¹Ÿ��m_ºt)a�×ÕÕÑçóqþüù|üø1‹ŠŠÜ%òÏ>»î Áçcîx½^çܹs$É»wï²°°�{÷î�‘عs'E„Á`ÐQÕvT{à‡¨êm�ÇcŸ={6 úöí[–””ÐãñðĉÑóÏŸ?g~~¾mŒéð‹× |®ªþÕãñ8½'&WbúôéTU=z”­­­3fŒ�ÿrP>ýÀç¨êecŒsüøñ8x7=Çü¢¢"ÇÓ  b0à?[€_D.cœÞ³i¢´´´0 :_ üg È‘s"ÂÚÚÚ„ÀÓ¦Mcyy9Ãá0ß¼yà &ØÆ˜÷¾LøOà‘:á�H~?ÚlÛ¶�ŽãDª««£OTS¦LqDİp°á?I€8!"¬©©‰ÂîÞ½›YYY\¶lY̎ž={˜““Ãü¯’ÿÑø?àöíÛÙ;ëׯ'.]º”¶m3³²²ÒÀâdÁ”ðܺuk¼›�7.\ÈÙ³g»7ì²dÂ÷+�ÿ=nÙ²¥Ox76lp÷m :ÙðˆÀïÀµk×&î¹ùdY«ªª\øƒ©€ïO`®^½:!üÉ“'™——ÇÓ§OÓ²,.Z´È…ÿMªàû° W®\I’¬­­åþýûcš››Y\\L¯×Ë3f¸ðëR ŸPÀopùòåѱ}Ö¬Y>|8FâÕ«W,((pá·¤>N@gÉ’%1czww7çÎ�Ëžs€ã8\±b… ÿ»tÀ'ø=MuwwsÞ¼yîÛ·�kÖ¬qáw§ >‘@žªþsÈ�!Ö­[·JÌ™3§çPY@2F "1JUŸ«çVŸ›uëÖ¹ð`Ò ŸP "ñ#cÌc¿ßo×××GáwíÚåÂÿ1àûˆH„Œ1÷ûýöùóç¹cÇwûã8M7x¿‰�ÇóÀý΋È_Ðã÷©L8$ÚgD$@€6uìï )N¿™žŒü¯Ä§ä¿%‹j‰ù\äIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/ruler.svg0000644000175000017500000002401114757047403022121 0ustar00paynopayno ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/search.png0000644000175000017500000000311414757047403022223 0ustar00paynopayno‰PNG  IHDR00Wù‡ pHYsÃÃÇo¨dtEXtSoftwarewww.inkscape.org›î<ÙIDATh�Õ™}LUeÀ/÷‚|ÝÉÃ�ÙÅõØò£å\3Mj¥¹ò�¶¶f ®lKWk¹¡²þQ26mké¦3û«/­l­¹ÒQQË’�Pâ`‹4ˆ¯Ë½Ü§?Î{ðåp.®»>Û38ïyÏ}žßó¼çy?ŽngIù¿¸YI(€RÊ“Èß›–Íx†�RJ÷›�‡€|`1�ü ô—�Ï�Ó"Ò“ '‹ˆL[°ø�iêð°b&¶¦íÓ œ_ ü6ÇÝ@Nþ[TÁ›pÞÔËÀ½‰ˆù(¥ö¯E»ïóùZóòò.åää\ÏÈÈèïï÷_»v펞žž•¡P(7ÊcýÀ&ù~JãÓ‘‘—(*¥‚Ë—/ÿàÔ©SO‹ÈzÙ "�hÝ("†‡‡×WWWïðûý?»ýÐ ÌZ”Rk€o€4³ÝçóµÕÕÕí)//ïR/V96Krk mÙ²eÝ™3gvG"‘t‡™_€Õ"2güÝt™üXi¶/\¸ð»†††š@ €³<@qã…BZƒ{÷î-¨©©9‡sæ^‘· ð ð¾Ù–••õç… v”––F€9Zm7€°v~«ŒìܹsÙ¡C‡Šˆ™Õ^ HDúâˆ6¿â«­­ÝSZZ:¤cMX@¦Ö,ÍÔ}Òm­««k+))™`>P�óà’¥ÔR¬‰j\�ÀÇííí‡ ÇMÇÌ,€•;úA`Dë00ÜÒÒ"%%%'B¡Ð<ÃÄyY€[¶:*++?ÕN¦i�cØ™ˆý9Æs©ÅÅÅᢢ¢/&TJ-JÀýæEzzúÕ]»vubEØ«AlÄJÙQœ·_v/à-++kpñcE¢òÍ ¿ßß¡ûy µ�I5 Ìè›CˬT ¥¢¢bÂu³›0€ììì^¬êb«]óM˜4¬¨gi Tã~Š¡ PÅÅÅA�Ç3è°»8QýX/ -¢ »‰³]mS>£”Š8ÚãÚKx]Ú±"ÀÀÀ@.ÖÌj."ZÍ k«æ‡ 3úŽ?ÛÑÑ‘‡}»]‰è6/úúúîr8<¾DàF©TúžýwTkȱ5rìØ±ÂXv§+nCè¢y144´¤¾¾~1#;a††°27¨ÿÖ÷L&|úôé6k]”€Oœ GŽ)3œ°� jG‡ €ĈÂ]]])mmm›&~‘¸†Ð$ùh1ÛZ[[Ÿ:yòä<&FÝV3úfœA`tÛ¶mOŒŒŒä9Ì~�ó®ZêÌ‹H$’V]]ýjwwwİ#ïàÌÂÜ·o_Accãv‡­�÷∶õ—€{Ìö‚‚‚³MMMçÎ�k×~s†µK¨]¥&¼èÇ�÷WVV¾ �K†×Ed¼®‘1à%íȸ\¹r¥,Ôž;w.•ÑŸ*CÀPUUÕÝåååï¸8ߎ#Û3–[Êݸl½^oÿªU«777?*"ë­ä&C7ŠÈúúúúgóóó¿bò<"X™¹é£–élê�b�M’”””ÑÜÜÜ ›,Xð—Ïçêíí�×ÓÓ“×ÙÙ¹z```YŒø} lŽw3Ä>VÁ×»±&¡D«8µ ÈŸÕs! ò$pu– .Kg@Cdb�ý3C//Ä@7P2«Hð8ð®ŽÞ�Ù^¬S�7€Rã¹¥º4ˆëÀÚYˆå �ôýa­{¢A �Ýr€Âæç§€Û“@CdŸM^NZ áŽÆ(o&-€†PÀ�‡�”¤0@\—-†~ÌIZ QÅÔ3þ×€/i4ÄV¬}D4ˆF`¾Ý?龋ÈGXË繑-À�æI©À¬O¶fô–$õr@�Úù³À\gŸ¸>tßJQJÏûÅÚ)N¼Ÿì±$é^â™Êmðã0 H·ãp•IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/search.svg0000644000175000017500000000300714757047403022237 0ustar00paynopayno ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/short_description.png0000644000175000017500000000054714757047403024527 0ustar00paynopayno‰PNG  IHDR.0¯tPsBITÛáOà pHYsÃÃÇo¨dtEXtSoftwarewww.inkscape.org›î<åIDATX…åWËÃ0Qÿÿ—Ù¡"J1 Tó1m�åð*133’@DD$Orù{0ê¨ßb Ü'i¦è9–æÂLy/.ëAVw@x¬›Œ*‰j ùØ_š4Z>–¬N 6˯¢œu]l¬à„DƒG�<73E~ö£aC= ¸­þFa6ڵĬ7ë3SôJó?p5ÚNƒú¿ÆˆRdYsG<3§žrÂöÑ­y¬KcoîT +–‡gê)'Ü'²Ñfáa$wZcuDnVxͯ»Ÿ= ?SêªÎµÐƒ/iúÍBãIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/short_description.svg0000644000175000017500000000350114757047403024533 0ustar00paynopayno short ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/show_3D_coordinate_system.png0000644000175000017500000013756115143647637026122 0ustar00paynopayno‰PNG  IHDRùô>(T:ÇzTXtRaw profile type exifxÚmP[à ûç;yá8t¥Òn°ãÏ@*µÕ,‘˜ IèßÏ^L4Ë5çhÕÊ ÄâB›‘¢Î8qTgt¯‡C�2² Ë,¯LgÝ/œ™XºÙÛ…í.T]™íaäÉøƒìnTÝHx ämµsµrmaëñ[+ŒðîÓ;’¿öÜkÁôö„¢0wAQD×d¬¤�DÃÁ(ž°k�Ï–0�s:~ëWZNóI „iCCPICC profilexœ}‘=HÃ@Å_[µ"A;ˆ8d¨ƒ]TıV¡B­ÐªƒÉ¥_Ф!Iqq\ ~,V\œuupÁwÁIÑEJü_RhãÁq?ÞÝ{ܽüõ2SÍŽ j–‘JÄ…LvU¾"ˆ~tac3õ9QLÂs|ÝÃÇ×»(Ïò>÷çèUr&|qŒé†E¼A<³iéœ÷‰Ã¬()ÄçÄ]�ø‘ë²Ëoœ ûyfØH§æ‰ÃÄB¡�å6fEC%ž&Ž(ªFùþŒË ç-Îj¹Êš÷ä/ å´•e®ÓF‹X‚2ª(¡ QZ5RL¤h?îárü"¹dr•Àȱ€ THŽü~wkæ§&ݤPè|±í� ¸ 4j¶ý}lÛ� ð \i-¥Ì~’^ki‘# o¸¸niòp¹ >é’!9R€¦?ŸÞÏ蛲ÀÀ-гæöÖÜÇé�¦®’7ÀÁ!0Z ìu�ww·÷öï™f?²ôrÀrÓÁt[iTXtXML:com.adobe.xmp ‰î;}bKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEé3V%": IDATxÚìÝy˜Wy÷ýï}ªº{vi¤ÑnÙ²¼�ð†Äb–hpX�`HXâÛÁ€y €�,SÖ H¿bb'„%!„é$$Ø`òÐC°08HÆ›ö}öÑlÝ]uîç�ª‘ÆÂ›vµúþ\W_3ÍÒ®îS¿sŸ:çcj�ü•ã·®%R)NQ±ÃbÌ™-´C`Ì™ïz—z^(xXÛ÷ƒî"*Šb1oÌÍÙ!0æ ¢QäTP¹µ—°´—”ñW±n�öl"ýcŒ…¼1¦zDDôd5zGéÖÆ½¬Š‘¶Y}/+š#"ËxcŒ1¦ª y�©àoË�Jo/�Òü |ük�Ü�+‘¦µô©uò�±JÞS-DP:¹Á£ÐÕ‰ÞÅç ò|àÀñg¯_€ÐŽ 6ùÎ ycLµ”ò"@oOöY±SƸëœèW<¢1úËçýð¶»îÖ2<ñöõgAýÕÂí[„záÝvx�±�7ÆœJÝ ‰ ž.ñoxµOHÔáQ<±«èú;oPV=ù j:àöFeÞ÷•ëx‚¡}cŒ…¼1æDÑnI7½ËêúƒÃñÅ¡àC:ÀÓÝ­Ùþ8�é%pÝ‹à5[`ä…Ž¿|«ã˯Š@£hcªƒÍ®7Æ<¦2ìùÿáÓcÙ­l¦!»±�1òƘªöm¸“ôaŒ©R6\oŒ1ÆXÈcŒ1ÆBÞcŒ1òÆcŒ±�7ÆcŒ…¼1Æc,ä�1Æ ycŒ1ÆXÈcŒ1ÆBÞcŒ1òÆcŒ±�7ÆcŒ…¼1Æc!oŒ1Æ ycŒ1ÆXÈcŒ1ÆBÞcŒ1òÆcŒ±�7Æc,ä�1Æc!oŒ1Æ ycŒ1ÆXÈcŽÊJ±c`Œ…¼1挴Yíc!oŒ1Æ ycŒ1ÆXÈcŒ1ÆBÞcŒ1òÆcŒ±�7Æc,ä�1Æc!oŒ1Æ ycŒ1ÆXÈcŒ1ÆBÞcŒ1òÆcŒ…¼1Æc,ä�1Æc!oŒ1Æ ycŒ1ÆXÈcŒ1ÆBÞcŒ±�7ÆcŒ…¼1Æc,ä�1Æc!oŒ1Æ ycŒ1ÆXÈcŒ1òÆcŒ±�7ÆcŒ…¼1Æc,ä�1Æc!oŒ1Æ ycL•‘YeÖc,ä�1gPШ½1òƘ3Gð§À¼,àÕ‰1òƘê­Ügó€n.°€7ÆBÞsfh>œ� Ñc!oŒ9c´\ü=P±CbŒ…¼1¦:>Dÿ)àY\Å—øŒ¬²Ãc̱ ícN‘™Yó­YÀ?“gòÞ#¯¦bU¼1VÉcª½’/\ÅÓù ï“WQ'—"vxŒ±�7Æ<©•§Û¶™!ú<ði`óO|@®¦N.˾ÃÎMÆXÈcžÜæÓq Z|x!ó%>,/¤Ažaç&cŽ/»&oŒ9YÕûìóÎ{€—³Œ/ò!YGƒ<ó°ï¶�7Æ*ycL• €wof)En‘_£Qž÷]»&oŒ…¼1¦ÊÎ7׿Ïîày&M²ÖÎMÆXÈcªÏáw‘»¸™F¾Á-rͲî ~ÒÎMÆXÈcªÄ�Àû©ç{ü�\H‹¼èIº6\oŒ…¼1¦ Î1on¦�õ|VÚ˜#/¶s“1òƘê#‡=^¼¸‡Û¤…¹ò’§ø[ìÜdŒ…¼1æ44³]ík�÷òEQæË+ŽàwØp½1òƘӴšqðÿË%¦M^yd¿AìÜdŒ…¼1æ4 õÙ³è¯"Ý�þ>¾ %ÚäÕvn2ÆBÞSý®>lá³2ÊyÍQvl¸Þ ycÌiä2àV`3+ûY"¿w cvn2ÆBÞsŠ>D%ðY`�¿•Ý,;†€·s“1òÆ˜ÓÆÀm€òiÙÂ2¹ö8t!ìÜdŒ…¼1æ»ø[@ù”üŒ•òû<úŽsGË®Éc!oŒ9Éf†è8ø; ä“òsΓ?8Noç&c¬!cN¡•À—��OÈÝœ/×Ç€·ázc,ä�1§Hð@ž�Ëi—ëNÀ’7®7ÆBÞs’Í>4ñQù.«äÍ'dM» ì`c!oŒ9Yæ‘΢oçÃò.—r'°;!vÈ�±�7GR¥Ç¡ë§rØç�÷ñðÏí\;ï€&Ò­jÛé‘ïpå x€F;øÆ«ÐAÍYü°Ølö{��À� ü&oá;¼Ôuâh:éÏ"g/„1òæ(øc¨”%Á²ô‘ÎŒæ"œ¬^è�´� @¼]™ú Ž(ûå‘@ùJ{çf=‡Ö¬rÔ¬Êß ‘^8|nÀî¬ðxUÞc ûÛ(ÁS|q³�=ÀosßáeîU8šOɳÉY%üOø?ï®ÉÚÒ51—ßoGÅBÞœy•ü :iNGrYr4e£k�k³Ñ€d }”~¡P<ìÄó}�ÿœœ¬&]Ÿ=7 ¡$;AÍÿðp6"0LºR`øqÂËþɽx5×òM^î:OYÀƒíyw|Ã=þ�tŽÍ^àUÀ/íÈXÈ«äOD'`Öh¤—æ",®Äq ð±‡:啉~›TöÊý¢ü§À#+Iç4�NË“^ëáÐ¥€ÍYõ¿'ûØŒeßg�|8à]À[yßæ•®“€ÖSúÌl¸þx|øÒQ3~B:b�ŽŠ yc•üIÏžf›!<7]KÕ ,F¸ø5à](ï…ò6e|RéŸR¶ÆðPƒòO‹€‹�9¤+˜ÎýÀƒÙHÀvà‘ìóaÒyã�wðøÕKU;BIDä€7oåwù]î·NyÀ§•¼ ×{õ>øSàú¬\!Ýšøì¬l!o!o¬’?�;¹‹ÓG#Bk6ðôìßß›]¨ìI;Ó£04¡ì@Ù%ÊÝgÁ�.%�$XÈjÇ©¬Ò$½$°#ë d�‚!Ò‰�¤—ªZD$À€?áU|�׸0ßÎNUðX ü9Ð9ëhN’^ÞÚgo!o,䫽0ë²@B °0›ð{³F*0}@= ì/+{ò°u‰rÇ XFºÉªd•Ð(éÐÿ¾ìãnÒ%‚ÛI— Že€dV•ø„@y‚;ѯöWE² þO¹†ûy“{! O›—Ï*ù£ ø8 øðÛÙy^³~ðmÒù,òòæÌ¤6íWG€„yÙ¾3ÞQ¿âa(�)c`hZéwÊîEÊ�Î…ïÏ'½$PÈN¤CÙÉt8ûø0‡. ̬ø•'òD/Øñü?v8zÒ ¿ø^Æ/¸Î­!dÑiõÒØÄ»# wÉÞƒç“.�|IvKYçsP¾ŒÇ\nç yc•|Íwr³— ¦s–ÍJä×þøA¨ìQÆÇ`¢¤ …°s±òÐ2eý `ÇÜl4 !îßÅ£w ÜJ:ëy_vB>a[{›EEv\~{VÿEà€,à�…¼±�?s©²÷cy}åÏ'×úˆ?�ó©'Ь>‹Ï;<±ˆ“£z¸¦ô‘[>s÷@&ð൤«*{Ó]+ƒÊäfý‘28¡l­(ÿšÀæôþÃé¥�eÙH@K\žt^@> ´ûI— îâÐM…fî$×BeŸUð—“Þ)ð•¤3<éíc?܇ÝYÑXÈ›” ן‘ ÏÀ§^t÷Ô3ƒ?ã-z M’Ÿù·Õ$@$V­àÕ©¸÷&pMP8?]ÝEÖXšužün ~ â¡ô‚•aez; );Æ•‡å+­0öª,Ì.–g�€BöGFI7%�°;ûïYg`7éT'`öæA<Îו“~?�' ø€t’Ý[€.ÍVØ |øEÌåÓÖŒ…¼™©äíœqoMxÁ�ÒÎGõ&ßN‹fÿk'ù8Á#„8 T‚S7®+!óÒGáüC‰»aUö=o­À„€»d;”~¦Lï„¡’²Ã)w—•¯¶�^X•õÚàà2¿éAÛ³Ðß<”}­ŸtKáÙÁ(‡}~º|8øàM³~ø*éŽvSöþ7òfvÈ[%Fþl̯9—÷ë{åbæIÃáßQFHE!’ˆ§÷ ·ä²¼¾ }ÌÌXŒÐ¼èÎn%ïNç”Q *ûÆ”-uÊÝ|§‰t³˜gg# Ùy¯Ì¡Û §»¦7pÙÏ¡û ½ëàSzÂÇ»c�Uðg‘N°{‡¶zI7¼ÙeÝ yc!ÆûJLÇ—XÀÍü±<‡…ò˜ÖLá“\öªW@å„ן´Ž@~ö̓ ¡álÒ�»Ho%œ ¤�ÒezÆJÊ®²ò€WÍçphN@óÁC–Žì"Ý:x?éðø¶l$`”t^ÀÔãŒÀ“_x*ççKH—Ê岯þ¸�t¢�-•3òæpvMþÌ0qgÌk>C+oçÃò\–ÊãîH7ØÀC A‹ÃÏ©àUkfÓXi†°ÂsÓû´ ÎÖ×g�xW:Q°´[RöOÁî¼²5T¾±v=�tÅ@! ÜÉ,èI‡þ·e‚½Y§`4ëLrl×ÇÞ—u>4ëhü ðY`“¼±�7òg¬É»b®ýKêwßÈåj–Kó}÷ýsõþ2n‰‡9Šj Êvgur§Ù�®ÎâÐ]ßZ…d0íLMÀø´²/V¶l^¦|ýB˜XBºDpæîCY0ï%�0óq é �Ét`…Ð dîܹ®P(à÷ïÖyFö{î¾þଂ7òæ‰Øp}u›únÌ;?ÜȇäEœ'-OZó“Ãã5qŸö×äO«N@¤ \ä.ÒÕ¹¤—ú>03?`J”`¬¢ô‡Ê¶åʆóaý¬*³NÀH6 0l‘=ÀRïýYÓS]U߸í2Mêú“¤þM•JóvpÃÊ–Ñ„WzûÀi3aÐXÈ›Sªb'‚ªUúqLÏáGoã£òÚŸ<àgB AQÍ:œÅÁqíf•âK ¸_îbj|{%_·Iƒp3ÎmRç&ÂðºK„¦…ðˆS~P[H7*‘ûo'�°�t>ÀÒ zýÀ�½_€±�7òæôQùE­ïQþñõ¼W®æYÒz$?í$ñŽzç™{œ^¼Ï19±27=µœ|¡Ÿ0? BÂÔÄEg4ž=ë;Ç¡<ÓªŒÏ�á‹”ÁË”þ<(ß Ò¼g&�ð]Ò[Ъ…½…¼±�7§•ø¡„/½KùÜ«¹I®a­´"G¶—{Ζ‰}ˆ“)‰ý™±„öñ>ÏôÔR˜Zzðk‡uÙš ® ê²ÝÏ:ì;nŽ!�’*NÙ‘óüÁ«³Àÿ';ÆòæÌ ;ÕóZmKøê;”[:¸žßä7¤9ò›°>«_ž_O¼Âã5§"ŠvlOï°?†Ÿ !×¹6¡ aî=>�ɉUñò¦6‚ÃzUHvz¾~£òáµ¼‘7q�›�;ºõísb�£N¼Wµáúšb/µ…¼©­o!_¿Ïóí·yþìJºx=¯v­w=;š†.x4ÀQA«ä-äMM°¶Vɛӎöüð&Ï{Vq oáwd!…cÿ½‚"Ôç5§ˆØq®�7” ySSl�üi|>ñüè­ž·�Ç y ×J+y©?.c¨z­à©™mm�òò¦æ”­ÕŸž'ãqϽÿÇó–<—?äe.u¿zG¹£+å!ˆñ*j﬒7òæŒ5i!úü´²é�<¿?—+¹�›¤•†Ç¿áÌ‘*èž)$VT³ÉùÖö­”7òæÌ4m�þô:—”_¾+áw \ÌM¼[æÐüÄ7œ9R÷ÏÓÿ á!BDœUòòÆBÞX%oN¸XÙüþ„×z–óN> -´ÉvµOÍ€Ô»„@gfÛ©Ø5ùÊx®·�7µeÄBþôà•íQÂ+÷2Ÿ›è‘Ú¤íÄü©’@Ò½ëU±¶o•¼±�7g¦1kø§Á‰WÙóç ×l¦ÀûùˆÌc±,:a ]4qàm�¼…¼±�7Öð͉ ø½OxñO�÷ð iãlY|b‡ DJ¨wÀ4‰kûÖÖ�…¼9£ÙuºSvÆøt‹~ ¼Ÿ¿”…œ/KNôßlÆ;¤Œb«ä­­ ysfG�5üSbèo^Ðü1”e\"ËNÆ_]5\Y€E*HN±¶o…¼±�7ÖòÍq5öå˜uÿ¼ŸÈBÖœØ!úÙNs6*ó4l3«ä�…¼±†oŽ›ŘçÿðÞ%Kx®,ãØî'zDr$3K4}é-ä­­ yc•¼9v_�yÓ€?æFðYt4÷„?bmß ySS;'ÃÔwbþð“ðÈû¸–³y©[Œœ·x¶áúêÏ[%o!oj°á[%ÂM/æ½�ûÞÊë8‹Wº6ùÓ¤Ggm¿†»‚ÚÚ!¨YÖ»?¡J?Iøð‡á{ÿ‡Wp¯só ¨?UÏ&ÊVÉ[È«ä�5|sÌÊ÷%|òýÊ×ò2.åZ7��¦SùŒ¾¶˜o*áCª¨°Àq'ý™SÞÔ­Co!o¬’7ÇGec­ïQ¾ôûü:Ïæ:™CŽæSý¬Êâb²Q{e¾¼uèM�°ázkøæ¸‰NøÂÍÊçÞÈU¬å­R /­§ß ß`!omÝXÈ«äÍS—lOø×?R>õZ.gï’€úuG¹c}á-ä-äM­°áúÚm÷òÇ/à÷z¾ù壿Åtð~�ÆwG¹c?ã×YÈ[[7òÆz÷æ)ÔÅû=ßz›ç/c)WÓ-žYzº=ËÞ%$*þÔ¬â3ÆXÈ›“™NvŽù{~øvÏ{_H3WóQ)3OÎ>Ÿéåc\˜C@ ÈÛò9këÆBÞXÃ7�Ox6¼ÃóÖK(ð"n‘IÊy§ë³]>´‡È �äm¸¾¶Þ«6jg!oj°á[Èý±›ðüì&Ï›wp‹Œ³T.9½Ÿs¢¥À ”m¸¾æÞ°v,ä�5|ó”MÿØó{›€—s“\Î ¹´ ºŠ(JÅÕÔëÐ[ÈkøæÌ wÏ¡pê7ºyj =ÀyTBrÖî­Co,ä�5|ó8üJÜŸæ¦ðI_t!´v_[MÝÚº…¼±JÞE%_5^Ôအ�ô­­ ys†÷î­á�vS%q?0_¿ç‘�B›]_c�Ý��¬Œ5|óÔ ùªk7› ŒL#céÖîk«©[[·�75È*ùãSÉWEU¬š#DÄ�8 yëЛšaki¬á›é{*êA›xgmÝØÉÊœñíÞ*ùšj7‰ ȉg×äk«­[ÈÛÉÊÔ ù£&‡B²Jâ2‡÷BN„À6ñ¶n,ä�5|óªî/m%æÅL;‡R«äk­”·CP»¬Ko ßE)_mOxõ`ðkõ$g%¢äÔ&ÞÕXS·¶n•¼©Á†o•üÑg|Õ­“‡„8P ¦Åî4kzc•¼9ÓYÈ×P縀8IPp¨Úp½uè��¬ŒõîÍ“·›*Y'£êQUDr�³Î½5tc!o¬’7gJ»qˆˆ Š×8 ì¼omÝØÉÊœáý{;ѵê»&_ÂyQ!ñ¶NÞÚº±�7Ö»7�ŸòÕö„÷ÍI6”Ð!�*ò5–òv,ä�5|óÔUÝôôŸ5²Cp{ÓûÉ;k÷µÕÔ­Co!oj°á'v ŽºÕ¸\ ΈTÉÄ»„ú0 xņë­Co,ä�5|óx¼¸ÊT‹†¤j¢LÅ9Bç©Â[åšcjêÖÖ-äM-F•‚£s•–OÈØo­ &—U2tïõˆ P±kòÖ¡75ÃÖËÖn»·�?Jsˆ[êÊòžy¢Úòûª£G'ST’ù@ÉúöÖ¡7VÉëÍöé2 IDATÝ›ÇVAp¨+h!Lªd¢ý¹^Ãzñ¡â­Ù×ZS·¶n!o¬wožªKÀ�R) Z)¿|oî%¢¬ô!¶y½uè�…¼±Þ½yL„Sý ÿw«øŸ–ÓÕðœ[´h@^qHž¤Õ^ÅšjëÖ¡·�75ÈBþèI$¬šÍBRO>Èy‡Z³¯¹”·C`!o,äÍS¯äe ¯‰TÏ�j† l©P™Lœ§"aÅ^ÅšÊxkëòƾ9‚ޑˆê¡Jr~w¿L�þУÍ�Ø«hŒ…¼9ÃSÞÁц¼ v­’R>„ˆ‘²5{ëЛša³ë­á›#Wáýäc D’xPÛñÎ:ôÆ*yc ßWÇw4ðÐ_X…¤çq×ÑA˜fƒJo/½�ëׇ¬_Ò«9´3ˆ§�Jäè%@;B)N=B"QäP$Í�™ïMsGIæ¸ ºE½€¢é©_“nÕDPFWo{eº;-‘"‘…†õîk¯’¯’SÒTÀDiÉ£¡ ××–µºåº­‰ ]‘ç5 Ç×䊲÷œ¢ný!° ØUÀoÝEn_3uýý+§‡»º{þ¢Þó1)u{¡¸I;¹•"Å´ü£[T´ËEQgÀ� ¼®Óz„¨éV�zÒ–¡‘$鳈Ð(--D#¡Ø.*�Ú“þÆô )6Oè„…¼¨(@o¥:Aˆ@¥‡…ˆNA» g•F]›´½W¤D¢H ;kT!kPÇòaU½å]› XæEÄÆqjG?šhú¸AÕ-L� FÑçI¶­Ó¸ uT*9��¿YF7¬{ͰÇm�íc¼vÇbüör#ÛV纰!šx¶�¦úöPŽE7zXèd=Ðß®lJ#»³Yµ ¡—ôkt#ÝY ‰¨lн!ˆ¸]µèÀ‹fw‚±wçñyèuЩ]]ÙŽ�Q$´ozÛé,BÇ‚¢tE�z{….¸�ÕJïF¡«›.°¯¾˜²�?•|•’ A"THl¸¾¦Ô!Ó±§R§H^¼$ 1”U\I�†“èñÔ¡Ô{¤¾Œ<’/áëÑ\,‰b$ˆÅ»ŠÂ´âTp  £ÊRä €fÆ}Ñ_îrúÛ·0Õy‹n+‹î|$dûT…‡êÙ½'ÇÞr�=ùg1¨ç3Ö÷·$ë:n¸>†A";_KÈóU¾>ÙÄyä¤IP'0™žT% åqб'Ä\�ßU¾¨ü»Ó[ii׎M›(Ò©]ë× SõãÛ” ×+wÞž¤ó."ÙÈFéYE�v)Šô ²±ˆ ÙØ�€¨ Ùä ºÓ€ šÎÆL§b¦¡°(Y'ÀÞ ò'¡’ªm �8D<ªÞ¦ÐÔ”BEU%AUEc—Ìî­*écâЙTQE‚@ÒVy…é@½×¼‡†ò1Rðêê<’�!¬¨JŒJueTbDb�2ê²Yõ9Ч¡<­µ1�L&‰>¨ø’g¢ò¦[|¾麺­?àÆÏüWÇ ÿÙÞש�ŠÍ$9¦�o`¿&áE„Þ‰W´(�\Zg‹@Yu>½pŸ  Õ»òÜàÓ|}×.’�Í}åp×÷|q+óy$7Ì~×ÈX)·}”×¶MÑ9PŠ6F ]oÜH´)"¥'ûxð…Up´#lB�}~%›õŸ~7¤ã�úhž´5ÇòU—9Å•('-é*% ù"GÙ¡AIHD‰*8&ò¸' Ϋ$š„êq‰£>|B.Qêb\c ùò+hè‘0œ*RÂ%@¤¬*!4/ô®y!å6/åK ÊUË÷pi±³¸¯Ë^Æc ùúöׄºéYþ�ÞÉÕäý2*xÅ 'Ip¤/lârB¹’È¡â—2¤‹KkpàC<{ð•< õ2åÆÇ÷éðø°†lå<·•ÑÏœ¾õ ì /+è# �¯�ÆV¯[�lˆ6øN:¥HÑK°6ÖöA__ЉïmÇ-èC¾‰/F½Ò)›4­ñ»U@‰zìäõÔcÊzÅÇò¡;x­õS,ÏáæJÙB¾æÞ­G«äÒvék‚$ýoãÓAU�@E� q¹Y5„àEPð�K Ÿx­‹•º RçÑúê+HÞ« Å%� Þ;O “’¸AuMñ°¯_UŒ´hK´�-ä;?»éÀ�ÅèÛë6¶¯gëõKšýÈoL ×'ŽKРž$IœÃyAP*• u’£¢ž  ’âôʺ–qš  !.˜ã�oÅNŸÍ¤W @'H¦�aœƒ4èÀ†ÿÝ0Œ/l)–ÿu'1ÛÂFvÄùhÛœ LåG¨D3¼:aA³²q�À&¥s£P\¥ DQz²µ:Þ*ù“sÚ¬®ëÚMeYœÃµ JEĶBª­Jþ¨_í‚d»¢&éPÿL§6—�B< nfëTŸÿ»ô{⬅ø$˜¦QBÒ ÿˆ„8Ÿ¯”8g»U‚w’è˜'$ÿ‰^ñÉíܾÇ^Äc ùÖ›qëzû´Wº:»v~ëf>ûÇøBîõ¬JH^çËò*ï‚eäâPBʼn$^µÄƒMuú©ñ8w^âXŒg1“œER™#�6h>κ<ˆCEHTµ¬ "šC¥Ž �r>¢ž\)'‚�ÄbBüèÅŒ¡²‡i·ÿ³íÔéÃÁÛý®ú÷ °¿áóÅÑ\‰‰ÞV¦6 {I­’?9!_]Ãõ¥ìbu>U«äk+äýQ·õ8&Á¥ó¤Ô=Öï&ÝÕƒ"Žtu ¨xÐ q x’ÍÀƒ„±ó•X Ã%.˜ñ 9þá«ÿ<ýÁÞ®VOç ÒU´×ñ˜Bþ¶5šÜžî,è:ßYTÿ JÐ×Çÿö®ë½ï}ÿÕõ‘ͽZvòF©ç9ª4© ’ÜWÞýÓ·oì{…ÞÌÍîc�k|ß_Sï< ÃÂâò× ùsâ –Æe–ãälò²t¡sÕ© 8œ€#q¨Wð8 G‚"´‘×ÅHr!B"$Îéø_™Ø@iHU'{it;yÐí§’l#‘=L$; Ùž/3xà¦V,ÅoÝM ñ½À­›�í¸Öaôu{Ðuàé†H Z¿ÞÑñ]�tëÁ9ý=ÀËo Øü-uµ;�@O„´w#�é’´¬1EÒAä:€vÐάj Ü*Ðî™%l§`2‰s¤Ó-æ�%ä«í¾húF¬ØìzëÐ Ÿå{V¡‹ÿÕÀWNQ—Ì^: àóõS�¯¨ëÌ/Lr¸Jœ[r€Ê•9|î1{ ü ðå§Íçí]›4¾ù Ö¬îõˆ]•?¦�Ä#Е¾&d+ß(º¢vñÆDQòo—þœ»öï✽ÓÁ‹ê&+ÏlmL¾õE>Š"ÖDÅ E È80ìî›N×À /_PÞ²s"Oœ«Óp´9l.-Öý\¨-¬ð°(ÀŸ¯ ­^™2— hBˆ}Ùû鈨ÓÄåÔKˆøFœ.c2YàǩÆ@BHRÞE©”£ÌõŒmE¶P–�$léj 7s¶ß‹+ óŒdäöÓ£4¯˜¢oE¼„Ò±n�vÓá:h×éL7ÚX¤3ºÁ¯�P�ˆDHøyeæ�-ôDÝQ§B'°)ÝíIz¤H·öÊÁ�Ÿ²ìÏVœ$Þ£uNµl! !_…A™ž^mv}ÍUòGòÎýêX•ºÇ}{ÍŒÛË¡$pe|Å%x¥œ÷.WAc�×mãÄÏP|a d/$ãhñŠóyçEÿtOI׈»ñÐi—�5äó�¡Å4Â"|7*ò€L·¯âὫ*<¤/Š|/íB'ÝT·*�PíÞSij€ ýŒ÷l¢?Šx$"úaDtJBQ}‘Â�ÅÌq9�W©�—Æ{XšTÜRT–Pr+p,Ö¼¶ê\DM§†Ä ¢âÕ e`’:TÁi! >Ý�?®(*nb*ØÁ˜Ä ú¡­{tÎÖmoùû< »ûšïÞÁ�ÿÙCþú!ÜÈEJÅ|q°JèÙ´é#¢¯7Rلᢺ4¢HQ# ›hæÀ(ÅÈ‘~1Û'0š•÷'OÉáŚαTòéB£ª‰KÁ¡xñĶNͽ[O¥ )�¸å¼w“„Š›–P·&$)¤Côèrgk“ÇE·­aõPèÌ®5Ø;ö„|º°úHÓmìˆ6]Ä)ÒlÚ#6­ŠâôÆ¿2H$Ep]�®Çëê£1˜â*kYë¾Ëw}{{$�½‘Ðurgº{•œÇ¦)SÈWÕÄ;šô$ç”¶’…|�…ü©�d[.x—/£yÄ•™ž;Ïp’&†TýnøÏ]4¼á�ÏûÇ÷¬ץЛN@#p‘­9†�Ÿ'ä‡ü·üjͯ°öÏ>­Q7i½�t÷€€�@£õDëAHè¹&‘hÃcVòÒ#tÏlg› eÛÙΪbµsÖh€|_%%(¼ƒ�h±ˆ+ÞŠ~wZìF;Á]¿w;«•ÍS|·oKýÉXë–ð ”(¹ïóýø^-†o�[O óÃ{F—Ä,¤>·Ô�UÎUÇr­—Rˆ/�„…� �éA„D„²OW�*h3.ž+!—¨Ãljø8@)ã#!f‚<»È³�ŸÊ¾æ¢=¶ÓŸßÆdÃN´nEŸ3‚OÚÞÿˆ•ÄÎôÇÒQª®ïö;*˜ pR±ÁÏZ{·žÚ€Lw¼¡jÛ�繟&UdÕÈ7‚v}Ó;7�ŒõÒ%kV¯WèðU¤‹§¢ÙÄe{ß]È/eJð‡ú|Hx.ëdoÔÏûß$мd+Ï#ÁG³~0ZG ë²ÿxì� ²Ê^#8lûLôèÉfrØó½·Yß“‹éï.fu8l8ôÓ?êû Œ”€‘ º9}üÁ­q+Ž;Ék@!?ÂYÉ+µ gQÏÙ¾Ž•”´ G›x!4iž�õÞ£‰’àU Zd’9 í8ŧ3TògNÙÃd½ÿz€{Ýž`Ò?,6K[+…`?ÓùÝÌ FñÉ(ÓS#×ÿˆòƒ_&èëCoãßÊjߥ]ÐWâ˜B;?†¿ùfÜ�«Ñn‰¼D}ލÃÓIÇä¿×å$®#|%ç}->ËZÀÑw•ªíŒ#B"ǤUò5VÉŸœ�/å�B‚HŒO‚t÷›Šƒ¤�P&iœˆÝU9|~aêwü`GcrÝ{¿¨ôN¡T¥Ã7è³p?æ�¿‡Ïr#¯çjºø/¾ì.ã÷t3wócÖŸùoþY�Œ¬C’v{#L£=°qfbàõ´ºÛ¯¿^GcÁ3'Hh�§ôl?¦ËX╳ñÁròn¾6ÇK‰µ™4è]Öm­àµLzqC4@ÈIàë$Âe„(ãÓ’ÒS:I"£„áÞÛŸ¡;xC„ºó†ÆgmG’}M¿`Ï8ìáeLŸ¿õ%ZdJ‹� |Çê¢D½‘°©ƒÏ­�òמõ�®¿àK‰þ"¸Ú�_þÜòÎK¿ÆÖŽÒ¬áúª8à‰ÉùRº”ÙÔLÈŸœáú¦L‡hà Q4 �HÝd¾aTÊÏRõuepý8ÀÿÀ­L^ÿ�Ï2­éñ(¡DÝØ½èŽ{ÈßË=úKúx�<Äz=ŸßÐoñg5Ý(ôà°ƒöq�@‘"·ƒïŠÑØûz¢±vD÷lìEîí$œ ölJêæÞGK¥LKÜÆ¢Òç¢n…6‹Èq•x¢ÍÍõ>AÒ­ƒEˆ‘txM´!{´‰óçÉdz{Ÿ.k‰¡<‘cBã_ß’¿ko³59nîûq°5¼4ÙÌí¸¦x肱çõ£,ÏéÂRxiqƒ½ý�ž¯²‰wÐzØ)´öÞ­'%ä+ cHpšÃCˆ#¡aŒÊ³*Ì)K↽>¼­NßøÎ›u·Šv¬�œyۻ㄄<ÀÏøWéä¯äþ\§á.>_ë&ºAèÄw,øgfDé7(’ö<ºP  ¢¨N�lìí¬/²ê¥ü êñ°ÑËêâj·ó‹òûVТÃ,VÇWÏYþ€žEEá9G– :×7Ë|9$ÝT �h’M\ôªZ@¤Ža™‡¨ú@/Ó'{Mð±â�&(L$Ûö;Þ¹¶¥rÁî«�ûêïñ¿¹½E¦ÆçO –ïžìo¨¯ZȵL§wˆ4OXÉWÝf8Ä$>¤É^¼Ú«äOÎh‘‡r¨'—Þ¹®~@Ãgä‰[cÆTtºyþ•ï¼kýN]' Š!�îC÷µIv' ä¿Í?ò|Þé_É«ùo>M­Ï»Õˆ™E�³Þrïoû¨q0!I×½§·ÄS•ŠÀ*²¹ÝíB6t=Å•ÓÐ9M±sôüüJv«�áÎÛý½½„�oP'~Ô¼œÁd¹Ê|y…(+´AÏ–�•ª,Á¹<‰@ âu*x/êE˜vž\RŸKJ�çîcÑGoáŒ!¿˜øS7ÜáêËwx“£óÈMh¨äi¬8¼¯ÇQ�Ðö-qíßJœ£xb_ ÉÇLç'GùåÙCŒÎÝÿÙr¥w//¸}­ÿ�½w°ìªë|?¿µöÞçÔyÔ³«ß�t: $Ý$’ÈC¸tÇ‹ƒ:TÍU¯â8™½Š�Q°v©3¢r…�Ç×­G® ʨiÐ �<èNHÒïw=Ïû±÷^ë7ìSÝ�HF t“óû'UuúT§÷Yk}ßßúý¾ßHÏU ®^Ë\a´MX=La"û:Ö°¸ÒïŠ]{­â¦2¢¡¶Èä¿20D�ÀCb p¨èH%1¾_ð¥n?x¡ S]- �Ÿä9ä/8Â‰á¦Øpª‚×óÚ?–£Í_Ï?þÅøâŸük1?v�;€w\üÁ¡�/ÞO¯ à0p &6{byçìËäÀÁ¥âŽìÐøé”Êkþ’oøÞßäm·œgºëEê®>ãÖÞ÷k<ôȦŽobWsŒ ]„Õ2neYǬŽá»%W ˜¦hê¨t„ÍfêÓÈá½UyùG5èÓÅÑQ¥f´K}–ÂG¯Y¾¡9zø–NéÁk³ÑûŠåQ›Òèå‰F&„£K„U½bG®,?yÜÀB,ž Ï<Úò”‚üF Ï™|ÆdCæ¶”õÖ—}n É&SŒÔ=§rÒnr¯ýŽ•…OÁŒrë¬�Q�½À’eÐáâ|º@þ¥|3×ób~�ï>’+3b�a>V½+9¸Ð=Íl÷î7°{ËRðÆ"º©+NÚ-XÎßø…håšÃÉzZâL»H©Q$l—)uÊTÁL69az4ÖÆˆ_Ãè©MÏL3rrš±Ú8Õ4´ .)Pp!%g�~„6Õ`»õ!§7?”Éw’bHKRèÓ-5X¯œçÁígY»éÌs;ÑÃ/ÎÌÚÎb·»iÄ5'ǵ^.÷Òb¹ÆÈä2…©5ìÈåø¼¯ÄÆ»¼ 7Ë�É¥$UÔÉÀ}N pà"_ì$æv‹Ngˆ¬Š×ÓÊÉö{ZïÌ>-3ïX4°0”ªýjƒ¼µL¹�óVþŽ¿>’+4WEDXFãC³ú­¿ÊUS5þ {^ŠÐTñë-Cš&$ž”0“,lШ6´±%Àú 'ˆ8Q2Í]õ"è¾è � ³jiŽf…‡·ñìÆÕ³+UìÚÁzm—h¶Êdõ…F‰¨^!lVñ!•ÔáûiVÙ}nåÙx þAÅþƒ7Ž^±C+êÒ(¶¨�49;ÒâÑ×hWNC7:v+…3×–ýÑé ¥2Ú¤2Ù 8Ú&ªž§°©†-~õŸø•U®× ÿ ‡›åO-È|b5ÀŠ€øÀ!…N­)~“ ²j¼œórÖ�èwªûæ¿�Ù+,΢³A’�sÇ0¾J ï°0|WvÌŠ^óûWòîÉV¿(Ém}ÖEÉ,µçdÁ§>ád¯�гŠqXIQ%óÎYãÔ[ Ld3£Æe8ÉÄ[¬é’8Û¦{óQ>Û9…ÅxCØ )¤–°Ú§v©µC|³B°:FÔ¨®U‰î.7×KD«ã˜¥qdm“„à-A¦ØN@¹U`+kÙ¥Šª†^>ÕùT¯ ô#G'Lè–שUÏò…M§Y{ÖšÓ÷c3í?¿Ükïï÷§'Ò¬Ríø‘j]K“M¢Ñ%�Æ›˜§”Âú+MÖvòC&ÿTý>Ö¤¨wÆX¢õ¾<_0Û2u£rΛZ ÿÚBwá“ñšÕ8V�Ï óFA.¸žãiùa\ù1'1qûoÙo*žÿ°Bú‚¾¢-ŒQ•úÞŒ{|�µÈ„ ñy¯Œ"dºái�ʼn3©Í(f�ZiJ†#¡o5�’ïÌbг‰$–È‚k¦d!b1&Ì¥ÙΜ‡ÀíòÙZ‰²†5 Ô )Ô*„«eú¾Ì™Ó„G¶S=¿Å•{A3$色�Ð:!Ò̧>„iÙŽÊ ðÆâ‰î΂ôî~¡I­²Æj±A}t‰Ë¼ªN÷+tì¹W“­Þ0’.m+ôÓéÉÔWªŠ£5J“k'— ÇûObtðJë®— ÉÉäŸy ÿÔ6¬«�§â‘P1µ¾Ùga{"NZ*œõ¦v÷š$¾‹{×m|Û�.VEc�b/³Ã.ú!Èã‰ÐŰˆè¬ú�6�yåû{ßIeò|ð{c¤ûû@舫_ðiçh8�w¨/ ¦èòqT'ùè‹ñŠªWb@™t¸™‰ IDATw8ç5V>p‘æZ“ª�'3žÄ;QœEº(F�³N¨ Ø\ôß8T¯9Ï øe'Jaú¢£BTjÑ­¸1DÖ� ž­m£ø™l}xš]ýq �qìÒ8Ò(!ëüZ…¬UDÓ|@�)…FÀxcŠÝf+Âs±à}ÚQò¡ÖˆÿP¿Ð§^êÒ­¬Q+.sxËIîß{žöU�ÒÖGÿ¥?>wJͦñU7VéøÑÉ>#c]-TÖ´8u†p<ŒÄDj® /¿f™‡•èÙŠ�n¢gÈ»/P�ä-ÄF.JÕø,¦î¸ÙÀµmùaøLÙf'EÝàÞÚÀÀ…vøŸ Ï«‚^!×�‰²8ñ”NËÉ÷ÿö!]yïʾ ºumäÔm�ÖwL:Yéu'Ç’ÞØhÛË …Ê Åɶ0üä¯T&Ÿý“‹T,âçG„Ò³N;.Ø’™ì¹ªØèyÔ-cí¯vgsïGe6÷ÛÎ ä†*vC�Æ—zǬÊÂÌ>�-2ÃO]üá ä-‚‹Z„Ò"ÍvŽz gðx !>·n>ŧ>\€ñYâ5¸Bî³Ç?úÑ-'‚®sozW¦[ÿf ~5Âû<Ü—�$¤¶Îj±I³Ø¢UYci´F{×*½Â¹Wxwú Ïl mmóh?«–”ÊuÊãuŠkD£BAøÜ@þK“µM,ƒâ"/¤lËÐÛÕ¶A넬�¾¿uk6÷þ{5„ùyTeÑ+Djòø\bQAöé#oŒÃÆ;xõ¤!F4jª°&i¶Û‡«6}ÄŠ£–Ô€�w`Ä_´�ÆSÞå–ÚÆ”À.ëŒoÿó‡‘Ï�šüÛûÛÏ}äwûI“êÒýÎÅ>hÉ2ÒV-ruk3¢Û Æx§Å›ì#]ã?Ò”~˜Òê4Ç–X«¬qêºÏ±4všÎÈñWi¿þ¼JªÓ•TFG[:6ÞvÕ±Ž*m¢Ê*…q?ì¸,™¼:ÔnœÖ‹÷L·Õ܆¸¨­†“â]_ÿØCú¦¿¸/îÅsçm°sš·Ë »è‡ ?Œ'Úa±Q‰u úHŒHŒêì{n3pÐ7ÞÁ«7 ¿­ÞŒ4Œ§®ê·ª<Ô39Q·a -=¼ƒÿªP#ñª—õ‰VðdÅ÷þÞ™Ö‰â.ÝÅô‡ùo­Wò%9˹¾r"u¸‚ “Ÿ•ú-€¢5_ h–[ÝζÕ2a£J±Y!l”1]KšF¬­”áÔ4ÅóÓ”ZeÂî8¡§T:ÙBQ}a3ÖY¼Jb“ÏuÅ®gÝ G'êÐ[buü8‡w?Êúö‡hM�üF¿Î-åe®Ú¾wTƒ]"SA�‘ÉvV¨®> Ž‚_ÿË5}Ì2U›;TmôÁ«š¯¡·¬‹‘QµÖ]FÿjÓtöýûÞÇ:ï˜!_úÂ…;x™uÃÍä‡ñ1'ªо'ˆEݽó¢r—˜ƒ/çÛB¼ÏI6ÑUѺxݪæð6ñ&B¦Î(x\€1:¬ƒ~�NÐ˯Òà­3z{³ó'ÏÝ¥dfœåìÇø�‡^ÊÝ£&LI2–EEƒÜqDòsÞŠ¢JæÜXƒµñ5V¯Š0"ØÀ$A/ Œ ëûô�H*Ð#:»“±C×°çÄNF–&Ô4FðÍ1ÔEØ®EÚBÐ £(›ˆJ¦œ®ìÂËóH4 C†ÞÝéÜÝ©,ÑÏ>�îÈXÝÒäôÖ“4Ë ú“}´_ûö ­ß8âš[Ê7=Ygl²Kq´E¡ºLqêáx:ì¸ä/'qhfsã™Ð[qN½8 ø- I_(u ²ìñç)þϱÖû·wüàÌ23 ¢":dëC�Æ“'†9£—ØÍÝ%FÞ¹ ŸyÇì¿(:Þ£’Mõ5 †ÓiÃñÍN?ß79À `1¢Þ«Êã‡Æ[/þ ýîû¾i lá Ù�óŸÚhج¨ý4ÕŒ€ÆXRãs­#"Î*x V‚ÄyòZojQÇJHÁzÀ‘¨“Ì;[ê¶{Õ’K÷=Jš)yC¨`›eŠÍ*…z@³±º2E±6¥¥µ*áú¸+ÖGYªRl :µc± �­¨ß&n%ÒW಑”^Уuÿ¤QèýI½œ76G—9ZjÒÛþ(�矡;~„N){M¹ÁÍ“«lŸlÚêX“RµFy²¦#“- G—4¬ŽËuÜD2�b†Ùõ3=¬âªý‰¥Ú»^³2F9Ì�¼çá—Ë_¯KfE¤'ª‚—ŒžZgµrÁ=ðq‚)’((VòdÉÄif;^j b#™x‡Ó g³Éž]¿š™8‹™¶ˆ·A‡´âÊ"8Rú®�j¿€éŒ>ºƒ«W·2Ý©®—ЕqÌÚviVJjdÎ@j |ÀX'd¼Ub»V¶\¯jU}¨¤(í’ÀÑ ’?jެüÑêè9jÓÇ8=}œæµ�Ð(¯‘bÀn+&ÝU»í]¥V6Yi11Ù¡²©F±Z'ª.QØÔø:é’ Ÿ­¸Ê)舳ҌœUe¬ž™ï‹©¨¬ªe•ìoÚS¼ö;W8§±"sù…`î:‹2dóC�Ɠۇó(÷}Ñ·p{„ùýˆd´CÀšdLŽoñ܇†J�Z<ÞõhæUÕäú°>ù ÞÈŠÛz÷–~}öÅ�˜2Gønþèô w�2ë2ë�zQ 5ÂK‚qèc� 6܇…TñðšÛ�[± ¹ ± ^A­ &¤£þBs—ˆÉD5#3„iêE¥eÛ8!¢`FÈÔ&™†Kôn]â Y…� YDØ/2’°Žk¬°ù:o?ßÜáz'·S>²ƒÒ±iÂ#;Ù¾>¥S݂҉Ð^„ôÂÌ2ÑÔ ^-†íX¹ Õ—âŒE­Å… ½¨ÎZ¡vïjiýÞµ±³¬Oœ¡Qi²2îypw�¬²L¿|Šž­ÿ¦Áó*ËfÏTW7Mv¨Œv´8Ú 4Ù$]"šla®!¡‹ ¢>oÌã, êK ãKŽðå–¨¬¨ø³dŸýôÍúÚ_~ö 3™W%VP…!n¹!Èã‹vbÉgNˆ%&&¾ï6ó*÷é;ª/ˆh-ñc�U2­ªߊ>€çmJâ1 *ȃü3àýôÇgî_ý¥7½(1¶XòG²ßœþ¿xÿCNÔ™¬`, ¨‡ �p8ß}-(Ä�>çb¹{(Xñ8UuŠ8 3XË€¸A;–‚N"Œ žÌ+)êúQ11"Sl‘Œ·H=‡YsdÚ‘$Z±lN#';ÖHw.³þÍŸ–µ�ÈÖËýõ³Ól_«P\cdµJ¡YDêcXWf¹Q$==Fxr‚âj…P«”ASÁt-Õv(láZ³]1· jÁf82º…>µ‚£&tŠõ�×Jµ�תk´GϲtíçyxäQš…®¬˜~½ÞwZé-“ ¦«‰ŒŽ¶etS�òdת-¢Ñ“„ã_ký€”Ä{‹˜ Ñ£AÐqݨUh$rkSmŽffô<…–nï~Ç/}zæìÑ7ϲ^TAb”éÝœ"C�‚ü0¾]ta!6,Ä2+êRì»J÷ÝZèÊèÖ°¦¢ôÔõ¢ŸÍ<.³“+º{.«Ãøš¨_ã¿^Qs×OÔοí»nUŠDþ¼ÿ>øÐëøÐWÑ h•ÈH@ɬÏÝs�ÏH¼ òDÿ˜Ç+›äl=V¾HûÕ%«2¯WwÉkvǨ€Ë×¾#Uš>îWYµdªÅÌûÂÀÈ CÉèg…vPÛݦ¶‹L³ëC¬3]CXêÒ 2É4R“”)8 }A¹šÑÏnçÙgwR^Ú¤¬W¡QF;E´ �i„Í�éN@ %¬«âu‡8ŒxÐ,Ô‹ÁG­R�Õò*ëcµ?nL.ýqcô õâ9–·Ö8tm�Ì,Ó­Wä–0åù•WWkl›\cb²N©Ú¡8Ú 8Ù$=G8út®K[Íà̰}œö�ëK«ÔOx1èDMœ¶œ†ÃÅMÝï~ý§9õzÝ'ÈB.è¸qÿ>Ð¥–ê‡ ?Œ'ŒÙCªÌ½ÇƱ¨Ì©Äó±þmÌuA'xOUúÛ:jXϘڳ»Ép�xÅ[gó“qx÷>ŒK¾p×�×zoû�qJœ—ïãýxR � ØŠ2�ÃI¢Î`çP�ðƒ:зž™ªE Þä‡lú™ŸÞ¡¥=QÁ�>¿¥é³ŽrÐG”’�( éŒ0²a’ˆNPfõüæü8…åQÂ3cTjã:Ú(ka½B˜x¯h&T;#l_Þ…²$|�Ñ/tiO§Ð§Uíøf¥~³¸zmd�æ¦,o>Αç±>qŒåMëœÚž¡¦KVè¡a‚j×Iþe¡Ë³ÇzvóX[§'×etªåGª-Tƒ±Áä ®|°™`P)X-7•op^§VZ*œFŽ—Âþ¿Zÿ/ܯ³(1ˆª‰çEcJÕA~O‚ymœ§1Ë‹è¡_f‹ï‡ÿ}œôæ¦Aj@Au}»Ê'¼!!ÁÆ C‰Úa\Âà÷Üwûßžø¹ù›<”²e} Þz¿ûÙ’EÄYG„ˆ-f!}²Œ$T«ëQQÖ‚Áˆ¿ÏpÅå让¹xk`-V½j‚‹çT3ñ. Ø)¶è•β)˜ô‡ñÌx`Ëý¯øÜ™Ÿý™›™ t™Î“?8Vj}—ª8PÁ�‘öŠi‰žé£àÄ«h΄AúÖ©¹uÊTtp§�qy7€:uB€ÅYêo2¬ÏÛƒ„N.ôX5‚8º&ñ4éK¾ÓÈð“m›©uÎ4¢^vžu‹—”Ì÷$A¦ôª‡éʃÒ‹³YpjŠÆú&ª+eFÖ«ÛU ëœi´ªYóÔ$ÅsS”–'(®Žu ˆ7H&”“€13É®ÕMøc׊Ã#ê´àpaF+„v!ËZA»ÞŠê4ÊËÔ&N=´¾ó Õv}ž3»Îs,�0¢ÖK–Šà¶Y¥ê@jŠ.!뮘Î|ïß½ûÜ6«¢ {UeQà�ŠêP�~òÃøßà¹U‰U˜S€™1÷‰y¯ãÞo‰·•Öùê苚*´U0èÚNÒO;C{ã0W¹xc:`ñb†Õ³gt„çê¹ÿôC7YŠé)÷>täÇø¯‡(AfmŠScÕDÎ’‚ =DRÉÝ B Lš7¬I�‰ú+ts=ö»K}²‹@ÛÆ=öêÐAŽ0˜JqŠ‚ul\‹=f<Áù¼õ/áÒ_å�€:øÙà-8’KÙ±~p�ã ¶]d$p¸RFOÅ£j1iˆœ�¦xÏ ì=z5SëÜé-I éÔ4ŠÎÕ|ÇB»Â„ ˜ÒõU¼Œ"\æÅà,N­øbª­B�z¥é“ˬNdç7ý6›!…û-Ž–šzƒ³Îëw?Ð{Å'ßxÛ.óŽ_£aþ�.ŽøÙ‚ž‡0À¡ØðûÝËŒ,Î,²oràepàŽ\\a>Fâ9Øftq>Væö ó‡Tã9= b÷ç­¹5¦ ó `| ÏÜ…0?ö†•ƒ§œ ãéˆXͽ¯ûK·âçU™Ã"dG�«úÂï•T^Ô•†IÐÕ½¢÷…†Fo£ž¨OÏXÜÝ^¾¡Š®ï†cÃéË 'PPk^'îê¿üu¹&½Vƾµ|Ï,·æß0i¨˜�5y5¿{âÇùÀÁ['p‘$¤^#56E�Z^Au±5Ñ›ÆUÆB¬tÉNd–cÞ‰¿\½rLñaô97â?? õ¯‡“Vm¾¥E¹P‰HA ‘X�v%i�2šzRlDê%¢VWá\Û §+ØÖ(#K›9¾…Êò£µ ÅVãBĈ À¥xŒÈh[³·/ÿ3Üÿ÷jÜ�Y¢¨E?)pþä |:ÑÂRXì/eœ¬7ÃSLWÎð©íþ¡µäØ1üëx·®3áfaß^ËÁ}phŸ×½±2ƒ h,±Ì±Wæ™Õ¹ˆU‰Efç�e�ýàcT™G˜›7pPaÑëÆâË;C†À>dòW׈Ee.v*{EâyXÜëÝ8»µþ }ÿÕ÷@ꢪµkáÓš=Ð 5±!_¦É—þ7|~Ï'NÍß³,e«tõv>Üx=x¤ uµ.2=XŸ^7kòwç}e¹L½¦ Šã<:h²ÆW§ø`2ñ�f(ZlàÒ\™ M·Ø£g3«àÔ "ã/N(‚8K§”™³Û˜::É5I‰B³Lxj³:ŽYª¢ë£Úþ¾?gò;>Ià2£/¸ßû?þvüú%DöpJ¯1¶OªÖ× ›öÄ­·tÚt�}0¬éÉ÷Ôï|kNQµGY=tº0}¨Ñåb[Æ^цGú,>šÇrßdï:ž8V@æ�ÅùXaNÌÍ瞘ù8ö3Ç‚<¹°ŽÌ)fÀ⇠rÈä¯�=­Uây‰ã9îÜ*SËçäãè·öi*ô„Ö>•OhÍm̱æ^ðâÉ•ì†Lþ2gòï�kÒ=O/“ÖÃÓw×~ä·¶-™g]#¾Æ ùpû-üÎ?ìäH-š£i”H!ÉÍÙü%®c&'I’"»Ù"ˆ/aNdèªCÕ æÞ‡Lþ«qعÕ% ¿€þù d¹iæ‚¶*y/EÞÁ«¢¹x�S?BØ)õ#Bo“ˆ²+PšµXXØLò­)˜óFU¼tw£w‡˜5¬—ÜOì`©;3,×_ ÿrMzÍÓòÓ‡^r¨ÿ¦ÿ8Ñæê­Ðæ&>¾ü~óáI{¤¸ˆ4Hòu“á#J¶#¨‡óäDp vã4¬‰âz‚ŠE‚ìòt6úzù':‚=‡ êù7h”TÐë^\ +ž¾ªE¬G#“€DM¢Üh…kµ¦‰ê2ª°EëWFÿ;cíÔÜBs­­úÝ8v;c'ð^5 #V¬7ªfÐè¨U£&µùa�sp# ’€¶(è:E]ÃR¹Èªô9¦žÃ¦À‘ ÀÙµUŒlq´CÏ©QÇâ>Çâ¢GãÁ™ÙüSÃrýW æ VeÆ ¢¾Îsò –ؽl?щ?åíÛék[�– }/í}÷¤5›‰gÅåm¨Í}áU†9í3=&>÷¯N×òGoH줱®®·ò7+¿ÄÛîcŧÍlb$³Jà ¥ut$Éú>t *ç5Í”,×£7Œ¨2÷øž´a<�ásŒ»øÌ$Äá bœW�Ádf /ì-ù IDAT/Ò[J8k3C�4S<$?¦bRQ¼AÄ…7Xüu‰:Öñþ¬¨ÿ€ÊúŸ7Gní6þ竎àâe¿·î&ìÎÓx‘ñE¶µV¹š1ÝA¤;4µ×ŠºíôÙ¬[)HY�‰°ÆçmÁ ŠÅ©Çj„ÕM¦Ã” ת@Ë"X”%ˆª4`陞·[8¥?qè¸+§ƒZ|Ö”X•• 4ÿ½ÄÝ9æì€ŒæjˆŠb`¿À`ÆÀbªç“õ¢ãÆcžrµ}™òüiÃNOQä1H^n‘$¾ðgó˜É94áò�B2ù§âjlu>öósÞð¢3ÌØ—o[,¼ôlñW‹ôþµ7 o´‹ö¯Aï©X–2‡·ƒ{Ñ¯Ö ü�É_L~ìÐ7î¼)Þ�1)JW_À�ÞÏñž»·Ë²Üd8‰»Ø? 0¢4g` ^#Œ¤¸ËÖmõ™ÃäŸD’�³{ 0Ö9ñèçü}Ç‹÷r ËéÞÕ¬Žúÿ[¥Ùœ£ 3Ùâü¢ßC<3C¼˜óÌAdâ'1÷²wÁ#3ª óäùä@~g"̀ݗ«ö»�¯¨ : 7* C�ÿº<áu6¿F›ŸbøØ]ð‰¿Œ S§Ì[BôGgÛ>DɲëUÎ$’ÏÈJ>)7´‰Æ…xÎÉàÞóoxר 7]c}C÷ñ‰ä?ð®‡öÚC+Y".ˆ4ðXéENlòŇ0ä/–@#‚W i3ø+ŒP L‚r÷IQ�¦šy#d{"uÏîYlÇ çTÓÃaåw,ýÃÍJi?Yx“ê ûýKŽ8™›ËSˆ¹KļÐP¯"} ÔçcdnŽ£"Ü=X†ûeÛ½¢B“Ñ•:“Ùf¶¥ ®Ò&[±~«fìÒžì¤(:"ÓN|IÀ`±¹#€Š8°JÁ *#Æû11~»·Ü ÂK’ü:Àcñ$íÕ´–œgMsVË<·Kñ¬œ§8{˜·°J•ÕÅqj¼ŽÎß(¯â�3+¢3Â�}û�°Œ2/JŒîCu/‹H<+Ä1Ä(ñ¥÷—oQ|X®ÿÊ·ž(ÂÅÞ1�d•°ñó–iÌO$dAK «&Û‚<0†;Êà^Î*È@ªö« òÃrýW�)×ÿ¦ìIwËSâ"6yøö£É¶Ôbï´Ðàz>VûE~ãÁë9ÝÚ^Œd%�ȤGâŸhû^Êäóîz#ŠW'J�+%�°âp—¥ ΰ\ÿ�ÓÓK»!�`"0Y&W{Ø+4AÏ€;l*øQÿ‘©„ê·>“çÞE)ºWÛýÿødî�U7Àæ�½ƒ¯g. šaâU¸ÔűaïA�Eî:„| ü\¬:r�EÙÇ!98ëâÂugۖ峎Nl¡›NQèNÒÕ=Dr %·‹.;±f+FŠ E !ª‚WO`Bï½ñyß‚Š1�1€ÔÕƒÜò!!b]#Ö4`�2çi‡M–�*V8aF9Öz”5šôIénÿ4þÀÇðDXDcbö2'‡ ¯häÿÃrý×sv px=FôÀûÍÏlÆüdO2ÓSCWqÛÿÙéÌOM>²â†©Õ0£‡_r²ùÆŸÙ™r�Eš\¯÷µÞÁ[ïÝR:C” >³’eâ™Z›ÖYy¢ñ7�׋*pÖ »G!UÁ¨’VÏ'Î -‹¯ ±ôp¾€ŠÉØ•Â�µ-ÐÓˆ?Ž~àGôÏ Yðƒ|ɺމ>9ù#Ù`ªy[Ô§/´þ‹\�œÐÆ<1ˆu~îEîØ;£ÚGœOþ©0«ûˆeq_L,s)±¤Û^Izö3ëkã]Œ)s±"¸Õ\Çfóèÿxp„¨7ÎR}#ÝŒ›g‘W‰O·h/Ø©}™vêG‰ˆ(h°Þ‰â4=N�P"éh e‚b"x#¾“â¨kF•cÁ ‰=…—ÓÈŽpGvÄþs–ݯ…çãR¼^íÄÍ&t^w†t;¸ø2n`îñ'…èŒ�AùwÄŽéƒæóYüÉ‘–ýÙgêy'}ºý̤å„Ë”ñ§’Â[o¿Âç‹mÈ䟑L~ë‰�‡ºÿîW¶×å¶1Ѷnç ÿOüê=/.ÜÓéfdâQQ!é¡>°XïìÀÀÀQ0ð—|mAz„·TpUÍÐÓŠ?Ú˾‡Šw—a¤9PÍ¥‡CT›®‘§¢º;AnòFMꑳˆýãŸàoÖ{L½î’C*Ëäy TïÉTßüdôèò%ûÇÔ/¿'Ÿ’K“�Ç¡ <7<ÈrØ¿P0xü[U˜sÌ}Ìø˜E�“�9dc©‹Þfà¾â8LÖe'ì6ên;®B¹ŠŠ½o·ˆI¦±„*û†�ô$ÀˆCŃzT1Šñy»C ‚UÄ"ŠÒÓŽ(=µ²BÉž¢`–©èy:飴Y*œ ŸÃñî;©óèNÇ‹N9¦ñ3ûÑ}óÈ™3È{n…ø,:ã%f£;PX˜}ÿmGþ}ÉË/ÎÖU´…úMð¹i8ÚW2Uƒ ®àûƒnzë!º¤�Ƶ›Ÿqqó¹‘Ï·è­õã½W¼$ i6q8ùI~ëðKåãÇD!o¬K¬ çÙŸi‡‹h§>Äi>‰ãœWPRÒéЙÛ3㣖¢5 ‡Uþú‡ ÿãá´³ý§‡Ïb™Sfc�ctï^zD0û(-`•˜‡XøËC’`)>`}##ÀcºÅ6ÙêjlÃÙ«Èt;ø]¦À65l"pUõ„ùô¼Ýèc# ñÑIþÀmQí˜�‘‘ÔqNG£#,³úÑÓü’;ñ %V²pñÄ[g¬c™iÎmûÿiŸ½äUèÌ^ÑÅ<óù?qÿËb3½ë>Q���y• ½ÿ2dò_Y¢=y>Løò þ ”ÞTGE×ÀOzp«òˆïoýFóƒë /ËÊ¢“e¨&–:â}æÄª)zßxW´„Œ[™æ‹¶~מ?ÿÄ¢ÆÄ1íP×nÖ7>Â?ýê©Ü´¯akj\ “4ìDnò jœ&*bî�biJˆñ +¹Í!Á–rzêžãh›@tTÑ{°¿ø{¾ô½[9úƒø9ùåkQýÏp³Ð°¹†=<ÍØªèšÕˆpp,¬n–ˆ_6,œ<Ìe z$Žá}ÙeÏb씟œ ÏÎ:ùRÖÞ$¼p§pü˜Ðu�å tSb!)K(›Ã¨™%4ä0¬Îg‚•XßG¢e_‘.DC¢ß«"„Þy¹Š�ŠB‰QúÄã½áqšH‚U¥„w5m¸I1»7»ÈÜfÚ.¿ËœqÙæÒ ØYî[»E:Øq^Æîj[ß(ÛžS‹"ÿéò,݃¶WQÉÕh›“¶]¸£J *˜pZGT±ÓZ4WP¿½™É[çp.L¢¡œÓ[uéñ%²¶qñºä5¿þ×ò?}ëÖúãÞ’þöSa±a5û«ôöï2Õÿ–ý+îkUX[,}‹ añ{xuñ(-¦ã©êð)Eækø2V¯‚s/@wÀe·ïXܵ›S.Ûq2Ã7�±EVòS9•6½æêkøüÒ�2�ñî6}í&–d%ú”:K³V`Ò”Ü�ϵ‚US¤wmhŽ ¡ÕN]LѰÚ`tã–ˆÕã´¦Þ[|Í µQ¥†è©ìÙBºvWL×?D¾?�?•¿Ÿ�¤uñj<" ´¨\V 'š ç‰B"¡Ø®Z;kjÉ+ž «2™Âx:î-Õ²§Ö¦T��9Åeu6L«£( _DmÁ7<pEÕ¾ÿþL9qž²÷po×M�}r:]°šmRÂÄ+”ªâ:)Ðìø8'ÃÃ{¥ëϗó¥Òõ»üOØ¥wÖÿêwߺåeÏV3!~£¼ƒÏmý}.¾±Œª· Œ˜ÏFæJº¾a¡äÂÒLf•ÔAf!/aJÕÄ{rß. Lª9A�o›s · ×}¹ýã_üYõYAÍo9ÿ´šó„Ÿ3g ïZ1÷€¬ZKº~/ócž0D�Y‰cøxJÎ †>JR&Ýo¯›v8 ò8ï±jEU|Œä"‹ûø÷±Q{ûÝÈŠŠõ‹Mn�¨!ËúÉ{sd‘Aºm³CbØCJNذìP k¦FŒ£¤øTÐCز uy ¹QÍÛ„Z»2‘f¦Ö†N–Ð „ªµ4 Ô äÞ‚ŠW C#Å6Lpб9ï´QrfZËü)çV¡¨ ÔæïäÉ´y9Z4OñÅRäwaùn{{ý¯Þ}Û[Î|®R3óý=ùÛù�m§qÉ-iR'ËÅY'Ñéžc”�HŠ‘Î;)"Æ©–«%_’†4 {L“¬É+u`Ü¡·K~ÝWËüìÏ'Ÿõ0¿‹ƒ/ÔPù›ÏÁ!l†í«X+7s®Þ²àjÊZ§[îfÒ,0#Õ%:Îb†p¬¤$‹Iµ�Ô’˜2ŠW/bê¾Eþ!rÜkttxxÍ%ÃÜ$œ³•ך‹ø±Ù¾üζͣ¾kž§oE�þ�µò%MVv2±¸�]fð‹-Òå¡«†¯$‚±vfxŒ8„¹*^€T„T”6‹ô†:�°iÕ*®â¬OqYel5ÅL‚Ž[t2µn Y¢dÖ“…&×H’”´Ÿ‡¸]p:eÂJ°):^‡ªLsáO1êüdypç‚ Ûßõ¡y�Où}�¥‡õù;ù̯žÇÿîjÇo0ž”2‰iP�Ÿé\2í¢ÔpÞH�ÅbÅ“ ªÐ�Ê“�䕺ö!Ü×~µë=ŸýñØÓ÷;+Hd†Ûi&æÃi�*Ãá ñð ÔVC^´¸[8öJ.X%œs.GÜIZ»›JuÝ£í¶×fÙ�«Ë¾RŒ"ÿPY- ¯>Gà-šc=¬ÎÏÐ5šÕÃŒ›AtXë—Þtn]Öžú9Co¯¼å­ç–ŽßÉ<¥·o>c '’üȆӅm¢KjÞ�Ã@»e~)§RÆ´%*ÆY!ðŠ§ŠCÍhb™ªÐnp½‰:-iØ™:ƒEœEë@½-W R‡$…j*:iŒ6—{È|h�½¿"´(Þ Ypªa,¹�¶ãw Wï†}õ¡®ÆŽ§õz )›õÕüËMgqÉ¢8•†õ¦ÒHkõF1a.2×(9++5^-")ÝZ³Ç·á»Æ€=X½ ný¶yÓ§8úÒ€]ô€ÂÄÈÌvöam±N˜6¸ý�D‡U‹�Ø0,ÇÊêsÏñÅ4¼:ª¿Z;Áà¹{ô”ì.”kÖ\æexg]£È?tO¼¸€ÖèÚ †Eô&f­¯^%¬>wßQ S›ôä5o”�7âw^@õµ739ÌÞm¯[uÁ-ì]y9@ÑüÀ¬³4§÷W%&½X!,Ÿt,™ô,í–‰Úe§äFEKÆzAÕ#Tƒ8#aîsbB@‡QtRè�ZE­Ã—‘,Ej%LÝ 5‹ÑZÉR³Êd™÷ê=ø0<5ÑtÜ/KFt}åý|ËøÖãOs*~;/ç?¶¼š¯o-ª€h ž:¾M­Éî£Umdö&‚¬ŠXD™j ÓžQÎjÉïå&ïõèµl$½û{å—Ÿ÷­ú¯†dé5Sñ“žéç�Â9k‹ßnV$ŒÖa ÂüµÍG £ÃÃì7#ÅCÂð V‹€>YD×Ä}ò™á첺èψ‹2¬ûç «ÊT:F…æãá©n�¡O!ðj•pÎ9>lûX#¬ºIx‹pòNeÍÍÊM«ääµçÊeçœcλtmù9»èýó�¬0zØÂ$[¬¹=R�Ã2X4 Ëä½m˜¤ 1¯$/ŠCJ¼J˜-F!õ! ` Ó ­¨— Õ?™ õ’PõÂx›£V†Z"Ô=¸ª…Ü ê¤=TÔ`„ÄkëPïÂp 'ˆOãPŽÝ«+€ ƒnj¯øôzo§ÎãƒMî•i¦Nƒç,RvÂ�®øßóee¶ä7 ïŽÑ •5/½|ýmvÖ( ;S¶é+ùÏ=oæK×¶“»œD]R—’"âÊjP©Ñpg›Ùæ¹eаO ñzƒÞ{‹ÝÌb6Þ5Qùð¥ˆñà X'áÄX*µ<9ÁHÞçÔÈžuØmÿ=ïœw}{ô/ß«¤�yy,縫ˆ…w3;`,&ÝL·PSý€E•éØ¿[@µ˜Cþ¯"Š›bad¶� kNÁ¾ ‹R¾ƒdðV~VgpÔ³¨½Á²k±oíÇèáh-Å/(£� ‰_ŒSR|( TÁƒbP1Í´}hÔ'aÂ#Íi¹.…F:ÙŽÔÊH=Á�‹¥f„,Ë˲:¹sâÔ*’"¥Ðæ7ȧšfo·¢Ò¯é!íïò¿?-ÞP´ùL¤Ù{²)Z¯Íþ1÷j#SìjCŠÿGX[a—`ÊyÂ$_öƒÏÉÙaÒ9ýþ¥#•�éšwß²í¶çŸ4Iw[Ê(/åß6¾‰¯ÞÚǨ÷X•Цöž*Åç傇)dô y¢˜½‚OUö„…7#£¼Y)òÅyÖyë‚£ÕH4+yZWž” 5TwYÌvgwýÔžü·ÿà>úF¥t܃üË£9Çý2ŠüÜ$¦ëgMºGtÿ ˆKaxÍšÚ«†å)èl`çZ¾ù\=�;£,îV£?È=mËû¤ºw¥ì©!÷ØeÜ™ ˜Ÿv–·Ì/! ¤+CçÑö²"%Œ1@ާ) ÅÄ\«Š$Hj°�Íé>qhÑ ŸBž 5£Œ[˜ð¢uIê5�ºQê©’%— š�NmÓ3dâBP_ ûhØ©ÂÀf$oUÄhRT8Ýï LÃýÑÿ•¹°ÁPÐä7Drá¾äž½«×P»ã÷OËŒ•6¿Óÿ_»ý­üËú¶rÝ$9R÷Nå�ù×RxôFˆɒŪÌk ¾¤n“A÷4Ƚ+ú)¬ÇÒªˆq‡#Ä*šIžf*Ç%¢ êŠß+È.ÏΟ¶ÿÞûþqòï|ð¿?©‰"iéH^)ìµ*à„Õœ««ÃèÕx8G†× cu�w*Né::NŸÐn6²ˆŸ°ªx¦·~̈ÛÒ£Ùæ…Ôodtß"vVØ\YÀúÊßíðº{qÉøîŠ7ehKÐÄ¢xœz Y&WΓ@ÆBj¡Í@o ”T0™bŸbr�\ðÕ²êDê´–†ÆAU+Zã2�LUýÌK rÒCNðD¢ÈGZ=’§˜I ¬»Š:¬"«›ë5«Q÷g�Äq? ²¦Ë«9z){hçí–'÷¿=+áwÎóùÞ �õ}2±gHv×ú�ÉafSy‰ùEgGþ³�zÚs(Y|bc° †×‰B¨-W6P¥C„~£¨%ÔX5”œfe$³h#A'­Pµ¢U#ÔÄÉh m(x#x5¨ó„ÁNöOp ßlPÄ÷{ ©CÌÔpî%cºyþÇž}ù 7�u†¡M,[y!޽…ÿÞÐͤ1ã@—1AÙ—hòZïÝ+âQƒ5®é Fãÿâ '„n%*©Å'¶�}b…|Ñè†Íž½WÓýþOë¿=m?5~r‘(ò‘fú|ÿLÄæ¸Áa”á¢hCCRD³Ec$m`wa¡Ì&íâz-vôxÀ¿ðc‚ßÕC¶u£+d¼ÑÏ^u“]Àí¥N.íÊe〢Ý•¤¢&MÁ( D8Ç„QêxU¡¤FËFÁzzIT5A(‡`ÝY´aU«%OM Z&Kª“ ®š@] ˯4=ÈÏ:ǃ1bœ 08n¶óÉÇ\xÕ5o?ÝÓ?/a§qÙøÛùܯ{¯eX5ÞiYË2.uW1uûHv¶ KÀ&4G #¿Å¥ßÈsbºþÁ–’JSÃy_ÂT2ì(æ8‹[TµÈˆC7‘ì»5m|à¼ìÛ' �/zØý½HùH«Fòû×ä ]t›Ug¢ªH³Åº$ˆ)býC{é›.Åtí%a/m\§ýÀr ¹´øõc’oé“êž~�¬/bŸëg›ôËú´ßÞÝÕŸÿ°'¥ÚŸ"%QŒ:ï‘P¸�fñ@n<‰b­Òf�6”ýC�ŠÄ[AËJfE'ÊJ£‚ÔSÑ1MhT­gÜ@î=.T1Šä¢ê-b¤…©ô€ë q⋵[l==ÿ•·üâÚ³Ï3+”üFžÇ¥ÞÃGïé$¯Ú\K`œ eƒ‡úD�Ö…’Y§¨Úà™%¬3+D§rîÅëš¶÷àà£(¢Í­xasBV$æ%lº ïƒûžhyØ®ËðÕY%·H[¤„msÈ>µ¿§Æ-4ÞPuª[1c?7�¿ýT~Ù¡ûå‡$©‰"ie‹rðq¤2mV}Ø:·¿�í£ݘ®íZêÚN èÇ“”ƒ°¦‘ˆÛÝOcç|­ÖŽaT³+_Ȧ´G6·Ï3×tx®íIíŠI5 £U0XѰ}ÌxU¨ˆjÅÕçVÑ$ƒ¢£|zL$Vk©“‰4·UÈ'jBV†j Ž É-©©ÕmÖX}”ÜÃëŸ C6õ»8‘«·ÿ9ÿpó|[5Þ © J.¹Š _F%OÅ�fxUT V¬<¹fxmžªÙ¿šËþÿNí²ÿͨ]MHU„ F<^Å/õx‡Í¼7Xñ±iá¡Í°#ëB®© h�4<©ŒlxÃNãÙáeòzÌšÏÈÿ®¾÷OA"!E>™iRJ™&‹·’,ÞJ;72X<)8*øñÒØÒ«õ‰ùL4†Ø› èV;O¶·õš ]ýîâö #� %)ÚCi±5¯F³“‘‚uÖ*ÖzRAºÄ©Z %'µ*^Ds+4R´V‘êäGr$cv?±›b ·�­æoìHö™‰¼”—’†%—PNí!Ñ)‹[³�ðüa» þ¸Í- IDAT†Âˆé¦~‡l„/ ç̽öÜ_Ž]œ{àE<^Fæáooàzðˆî«*¾ûdzG¶ø„ ˆÁ‰EwG•¼,n ìÏ>o&¯¬ø�~¬ö�ç¾#~j‘(ò‘HA Óy�V:ï¡Rd�c÷;Â_çíø±4¶/bb|#Ù|FÌvµõ±¾£›ëÊe®,ᤢˆ•fš?C™,Ö>,*V”²Åv%8ž+꟣|7—:%×ÅD9•±“Ü4’SWÑjêl|Ý£™¢¹Ô;Ù_ùæ››#(êõi6° µá1®èQJã­ Nž¹ �1Za«*ž S¿Ý‰J®¢)FJˆÉÁÇ0ïaN¨=ö ¼‚· “4ôH/©ŠŒcØ¥’]Ÿ¸<¯öíÌ3´†CãxÅt}ùHdÖf’ lï:Úz×ÑÆ•Ú�‹@³EdûSd_£ŸQ3Ÿ½f;çqW{?OÊl-— ±À“»MÞp�ªy>ÆdŒãÉÍ$&™P[²X²¾‘’ª N4�Ì ¦‰NZ¨Y´šõÔ…�¹Í2¼ËŠa–D‚wáÄ…7ä‹Íq÷i¸=¦È„uwOe U§Rô ¬ã| å-FÃgŸ8#Î%˕Ƒ¹b&QÖ¡�ͤÿúOòŸ;=Ë>ÊT±ÅÃ}D‘�"‰Ì]r$ÝD©¥~˜÷÷Ï'Ûz<¿þFI^;´žº^iß(^+þÆI—W-áŃZTÆiâÁ�Ž�&¡øJÊF©`EçQ¹ZLŽZ4+‰k””z9Œ®A>©HµU‹¯¹Ð1X³ýÂý»„m‡Sµ* bœ×+a‡A”ù‡ß±Tm <€ÅÈ^tI'�Uì„À6MüÒùÛÊo­óq�ô�¾¤HùH$r õ»<7Þ°�áÞïsÏ9(íÁj‡LøF‘ìïd‡<‹�ž†Y2©ãËF¥±r›‘Ã68í¹Q+öWtY˜×¦’¶�5EÑc¦x-ÄßÅ‚JN%M¡3IŠº%5N�O0™E&­ªøÉD©Z¤nÂÁ:hÖÀùLÐ<u‡e«4kJ&¹&E¿îϨšýŽƒ6·cË"*öz‡ñyÅ4BÈ‹…SüºÒìî7“{å?¦§ã泌í¤2™äšä"Óhèòñ«20“š°YÕ­Cþóï’¾n´vì§@J‡ÜïˆD‘�D"MÜFÏ­ç{þèÍÀ™ÅÁý!¯uAô²UÕ¤j}ûž6Ú÷´ ¿ž¬Pxjȼ&ŽÉþLvõUÙ·pL«{È{v¨?ünº{¬m]ã´•0½%ÕR¹èÊï2D…È+*xU ÆàËF( ô¦¡½¯H˜?ímè·’W„zE©µc&õÀt?R't¼¦£ÈG"‘)ߥlx64Ìý˜ÌݤªG1Uü�#ÂF«Ò“xP̼mkÛ†X«ª9ìŸó[ð!kŸ!¥Ý¢$^H½`𚄱€jTò�¡TË*µ’J]�j(ôõ ¼C½u‚!·N¬‡DúìO § .´ô Û››™J—{‹4G cB½Ÿ'´¾·‡%—æAñÓ?÷Û¿Ö¼�$­ŠƒoâL¯šüqÆK2² £ÛU.ú$¯ýÜ­Õ?ú$Ëã5‰"‰­¦Z›ÙÂ0Åq¦z‡9 5ãåàkï¥ 5”¤Žz“`R'ý ü ÖK©Šê5ºùñç^öÙÛv¾þc�ýè�ב(ò‘ÈœÇmôÜr�çïß1u\Txp$¼}ŠÝPzè¦VxWa®EÉÂÖ€\ºE»Ÿ½ƒnv°ˆÛüQÀ3Á¿ðãB¶ÝÒØV¡zC;£»:Ù¹÷pî1G›'ýþÝó‘]*‹èvøNE:S|©dHJ,BNR”è+5‚ŠG�‡Ä@{RÄzÔ’«_Rã“Üd²¥PépºÜ##W­‰RKÀYP Cƒµ!NëM@ŒGl1‚'d œÚbŸíÿ´h„Ñ¢“`ñýcÕÊ”´§À܇DfyâʨqICÒœy9<©,ZQãwвY͵ŸHžñ÷×ï~ûj¥ô¸G×y�D‘�Dætï¶(wüÈsþ¹pkGÐÆ’Âà•†wþÂðô?›=ÀóŠÿM‹Y13ûÍ 2�qÅø¼¢F‘û~á¦S)wæ”§‹q°ƒ#¸›§r‰ÿÀ�C¶ ÛUjëWêÈÈRvŒ.g“ôWÐÁÏûR|o%ɦ9ýó0]e¤+�R‚š;‹x Vì¡/vñÅ+>MŠI‚›a…!üœ>U2E2‹©µ©N$P/)µ.§U…IE3gÉ=š»)/LjçŠX’b`P®.Aö*ôAüU�¯.¤%îcs“[¤³!ÝUôxƒ–÷ªøÝxvhåÚ¯$G¾ïF÷áw«Vžò(Ÿ±sqùHd. |¾^¹ãÇ'΄_wAèQ8þËÛ.VüùÁ:’i‹´vÉA¶šÆ×«Ê‚.eÀ8Q1ȃ7ý¦ÊG@ùÑ.Ö1À:Žä'L9mycG™ê ]2º{ Ù6ÑÏ–ÆR½\{ó+z{` ´¡‹RèI š$5¢ 9ªõ¢›Ø•/F‘²Á—\— ¢hhá+ˆ¨/AVv’%h½˜8™c&´–¢�$ϽÁ™™Í­Š`Põâ &È¢ôþ„Þ8¼ótO"ÇWÐÎDGQÙ„ÜøÝžyúÑØgß‚¶Ÿ/±HùHäQøìÏÍ?öü¿sáú�Á œr›á w ýï¾ï–£Ú:Ÿ ò“NîzÕ¨ìT‹-ö´‚P¥|D•.Ft³#ŠûÎEðãH¶ÛDk¿JÛy”Ù“ Ê·J/n,öWô·aÛ†>})lV¡ËŠv¶«–ÚT’¢AF�4· ‚"*v"l~( ÒÙ¬ðOð A´”ãʘÌ@UÑjŠNZ´š$ÔÊB­’I Gž¡.ïŠM‚ÏxÛž\õ„ ¾stÊ�ÂM?JÞ÷õ±o¾ ×ù‚™sžG¢ÈG"sNàë×z®½Äó‰×Ãí}ì/¸zâ­–7ÝóÏ)tâ~lç}MvŸAÆuw$Éè$‚bAÜýeëùo:Ñr'”Wºh0À�~%7ó¢� 0õÝÊv)ûÒ]Ë”–éÞÉA6ûù\\ŸWºdþ™S߸Îó«‹<y3lh ¼Â’›-oúô½óþ¾ˆä[À| "ºs"³”ŒÒÀ€x�ÉÝçL'¾­SXNž<ÿŽæaž ?&¸Í%²-N·´•Ç/ëalßѵ­µÇp‘ òãþ^ÍçW�Ãd ÉmOíí(¡6A%ôÑY€:FŠ‚™3d·x®ÿžçR|ÁÒ øª°âï~·©`JKÞ¡bkV]1*&Ãy#Ú­iL—bŽ©“ƒ¶3Vëa ØÈcø!Ït É7c²-¸Æ�‹luô0?6ºR6L¬ô?ltrñ¼d�ÀaeèïDçWðóS¤Ý@¢@ŽW_dꨫPÃk6É­#qºõÖÄ}¹fYØ^/Ÿó�Îü¯ÿgËž.~þ›f¦S‰"‰Ì üNåî‹=ç½nd*×~§á_4üÞ~÷¡!-"“‚u˜êDææuQµ>T·ÏN¤ M�Á¥Ç@;Û\ÛXÌÕzpð‘1Ám¶d[Ú¥q{‡ÖF:Ù7ÞÅ–Ý'rIÖÍzzð‹úà°Ne±GúAÚ´½†/{5:n~WÛØ•'Õ8¢b'®þïê…lj[ôÎx}E¢ÈG"�^@3¦ìºÈñ…ÓàöæE9w oþ€áä?°¡!Ú³S È“®«](¢ÓÊÏIB& '=fTÛ`p4×r ÂÇÀm†|³Ò¸)‘ÚžÇÚ‘Ú±ùÆñ¥æ‡µEæ¢ö]yÕ”ìeé­�\p²pØß2Õ8/Fò‘(ò‘È#ÁïRvßó¹ãá—«˜*™Þ)¼zØòº5`‡ íÔV0  ØÅYûar…hÓR*¹E4]`Ž�ôh#×n®ËrGƒ?ü‡w!ùvöå'%âFjÚy¿µ~#Š|$Š|$rˆÈ×+ÛÖ:Î?~º F ÃW�s‡-ú^HŽCKl¡ó‚,d²$HvýeªH<-|& -õ£¥c[Äm‰"E>™­d·(¿æøÌpùB£ö™ïMø³·Aú˜ µÊªüïv,‰D‘�DZ…Æ ž¿àùÒÀõO†z‘¢ï~ÿã–·¿Ò‡�µFá�ÊŒ]+Žá%ç[^üJHW=dÛÙ[èµKŒäç±w}ùHdV ü:Ï5ñ|ô°þSÇWŽ^ÿÃÉ/»ôa�Om‘ɤ3kùÉGæ1�™e¸�ž«‡=~ ¬?yJÌO x¾áä³�/¤0Ÿ*ÈÃ5ŠŒ¢hT÷H$Š|$ÒŠ¿ÍóË÷yÖ¼ÖŸ>Å,Ì„W~ÊrúŸÀ·N$¯ TJ?»%tÚ7"#ùÉGæ1]™%ø}ÊMëùøÓaË©SLJjÂ+>oyéïCéqóß„V�ùƒÞE‘Ÿ;E>Š|$ÒÒäÊöóç=î|Í”€-sÂkþÃòÂSZý}Š|‹Œ”?X‘]ÔøÉG¢ÈG"-aÀ&.ö|mn| û— úœpö7,/xÊ¡øâO·Já]TùH$Š|$Òz_½Âñ�mÊů bVXæ…S/°¼lñߢ? ’�éúHŒä#Qä#‘Ca¸j?w|ë.å__{‹Ñ°ËU8û–³–BÛÓíKð-ÓñîèÎF9›D�Ô:1Џhú£ÈG¢ÈG"3“êO_ß \ð Ø›@X©Â™?°œÝ •§<¶³%ªëä±ÛíŸtÀaņ>1’�"‰"‰ÌD×8þó6å?^ {‹é_˼ðâZ^4*'>2¯£5 ïì"LŸ'›'¨Å‰¦?Š|d÷ÉGZŒìÇ÷~¡|íÕS?ä…üÀò¨<í‘‹R[$]/HƒÌ7Ä ¼�f?‰"‰Ì´þÇw/U¾ø'°³Ž†pö–—&Ðv�hÚ)­!—¦DbÊnª‰ygÍÆH>2'ˆéúH‹P»Üñ�‹”ÿükØ\�àX„ç^ey®@ûi<âëÌ­±…NAˆºâÕ–1Æ MÿœÑø8 &Š|$2“©þ0çß„~ê]áØáκÙpÊy´þ§9oý<üäc@_Ø&· á¬[,/½*OàQÝ Ö2£fåv«_wÈzxTm¼öc$™Ät}d†R¿6ç/¿WŸ,€…'`xÎ&ÃsöAÇé€}t_cN‹¤ëÍ]Ÿ�:gP "×ä£ÈG¢ÈG"�Ù-Ž�þ3\ñ!`(©c0¼`«áY”žÂŒhæÒ:‘<Î’ÐRJÆÏ´(ò‘ÙNLÙEfn‹ã_?®|óýÀ`ˆàŸ,Â)› 'm‡Ò fL·6®5¶ÐQÁxT`ÑÖÈ@D¢ÆGb$™Mø½Žï¼_ùÌû‚À'bxÖVÃI› ífP;V%×i†cìÄ„K¨O¡ ï¢ÊG¢ÈG"�œšô\ú~eø¯€åÁ0=N §�N¬ÛäìÌzÍ­3 Æ”0y M°2)yìxE>E>yÄpÊñ¼óÀ²`”†žºÃð¤ H—3#ªäÚ*ëÚ'§Š|ùHŒä#‘Ck|”íŸu¼îɰõÉáÐ2„S' /ºAè}ÆÌ>G=­Ék»âMT¨¢>*|$#ùHä üŽóo8¶>-BxƤáÌk„'‚´Íì·�µÊ:l*¢Š*†ŠÅz$ê|Œä#1’�D•ÕÙùÇiǧ„#ƒ§6 /¾Jx2Hyæ¿ ×2[Ñ|9´Ù÷(† ðÑòÏ™«-n˜Œ‘|$òH²ï›ŽS�¸·ÀŸV3œ{¥0t"HGk¼�†¶È>yH¬$AÜÅ;ñ>®ÉÇH>#ùHäágââœÓ»î-ðÏ�4œsµ0ô$�öÖy/­ÉïMÙÛ@¼ F0ÛÚF"1’�D^ª?Ëù£q˜85ü¾á”IÃK¯†Žo�¾Iël¡[7˜ÿ7°Þ½ëMC#ùHùHäá£qcÎÛwÀú³Ãï=OË /ù?aè‰ �-è´´L$]¥#‡´n &Š|ùHùHäá‰xïÌþ\uVSàáÄÜðÒK„�ÓÝšï+Sò1 ©·J¦EPœ—hø£ÈG¢ÈG"·ÉññËáÂ×L; ÃK¾+<æq`Z÷½�h«Dò©©æ)%Ó´ö"1’�‰"‰<$ü.Ç翯|íUìï;¿B /¸ÈðÄcÀ.mí÷7Ö2éú̦¦ŽzÔCE>ª|d«ë#‡Ê®Œ;Ö~Sùìk¦~È /û¾áù‡AºjVά5 hÅfI.¨QhD‘Ÿs"¿ïÉG"›M©y.Z«|øÕ@Ž ¨ð‚ZÎêƒòq³&:j‘êúÆìcÛ…$Q!j|Œä#Qä#‘Cî¹ì[ž¿þC 4uøÉZ^> •§ÍªwÛh�—¹xÂ>C½ ª@ k4FvQä#Qä#‘ˆ÷\õ?žw¼˜0N®’ß°¼õ˜w6³G\|+Eòí¶a¤0÷§ÑêG"Qä#‘.Üv¡çõgL‹à–Ýòñ«„Á¿™E5 Ú\“oÕ+=FòsçÊŒ>Ý&ÞÍ-™aWÖ]ì8÷T ŽôÇ]lyÇ Â²áÖ8óß2Àxk¤BÕøÝÇ)tsˆ8 &Š|$òPÔnç�g�8%ð(œp…å]· ß; ~Jäë-òbcÎnn_¢‘9K¼ôçæ?O™Ø Ù�àv€>©¹ÒqÎã€ySÇJ?6¼þBaág©Àh8g¼U }$#ùÈ\àNàlÇi5` Øl‡§î;!,©ÃPMè3ÐÑ&¤Ý�tC2/´ŸµÝ`zÂm⎜W{§w­»YxË¿Žüä,ø{ »¢Ìðr¿\ ß?�äL4[b0B\“�‘|$Š|dVògÀ'�!`Eñï \¹H¹r™BS•ñã…°Ø\ ìvŠë>Lø…×­¶¼â#`Í!Ã9ã�èmv'0¾¿­-ÄæõsGããWE>2‡È€;ŠÛeLuÃ2…p'À|àÈBÀ—‡·Ç½G »p Í ®�…Ç+므y¿: ´L˜¾Öœ47K¢#ûKs1’�‘|$Š|dŽ\ìJØñ]-~ÖDÚ�ÇÿC(²k>ß-ÀÝÀ1ʇžè #œ[2óFatèxòN᤺°R„ ôö m=�ö�í/n‹i�ZÀÏvF¿Ú8�&‰"‰ü_ú§ ü�À™…SP: Exƒ C°o1aY`)\u”rU�'À@ Ø\ŒÂwOŽL…Á>èì Ž@ihš#°hÆ‹êÌù§¸….:÷‘(ò‘ÈCÀ„4>üº"Ú¯·ÝűéF¦)*ÅsuÿNXX<®R®M «4 ì+žo p-°^7"œØ-ôõAGŸÐ>É$óÁG@Ú¡Ýô-eD�7p¯ÍòQä£ÈG¢ÈGætì7Å ðà Óûàl¦Òú¿Í�4ïn»Ÿ¿— Š¿Y²¢ø÷8`%С|Q•/V '`káÜF( Ü ìÞê…ÇÎæ÷C÷ P€´’"#�,éxȆSgþ¼—'Tu‰J&¢)9c2ÄEÓE>E>2§ ƒÒï_.¾)e€çÖáî¿—›‹Û/âXÂrÀÐ4ñ_, ™†ŠûSåŸ�ÂH!ú#À6àÿŠŸw»…s�pâ|aÉtöC¥_(M9¶Lÿo1œ3Þˆ®IžYR¿Ô¡ÐÀÅhsêRŽ"E>9hdÝ üðœiÇw§·â¨Cî㾜°†¿¸á çsh#,¬`j)`%pðTÂ�2ÐP.¨)ì,Þ×ÂöÀë G`^•'.@ç€Ð¶l[+‰|É8“/Æ ‹JŒï"‘(ò‘¹*î"ø%àŒi÷�¯"¤Å…D<ÐèøÀÇdÅm¬ì›x_¦p\:Íõ‡ `¨È<èj:@Uùʈò•æ2ÀNà×Àvà%­"òN´¨°WÍñ*÷ÉÏ¥P>~Qä#‘顸GàÅÓr/ð‡À%L¥Ö[Íxø":-û–ƒ<¦�РXHè°¼øùˆiN@…°t 8J3}Ó_b¬I]®Š�„Òú(òs‡¸:E>¹—ÈýðšiB>¼¸ø€h¿•£™�”æ{ª2Upã}\3Ý„€?ž‰àfúµ4fœs¼¤ØfV#ùHùÈ )xmÀg�WN³“Àk�oÎ2‹¡Òæ„z€Ý„”ý8†SÝÿfæ, ”ÅPeNœL‰¶Ç3?ª|d–½ùÈô­kçOx �5a|ä¾™ñéÐ{zäWàwåû(=uQá£ÈG¢ÈGf¹¸Oø�?=mýÇE¯Ón‘4¡7wé†:õ¨‘{KûæøÅÅ34E>2ûI€�ZœJèZ÷àëñ㙑ü¨Ö²¯Û“6Sî÷)þ6¨m·›X”‰Ìz™ÛÑü�wLóøëÀ__‰Ï, ®{’¯Èwò_æ'~—®ôâþ¯M�mÔNß%šMª0‚ž2*<¾!,ÎaAUèO…Ž ´UÂÁdqV@+ò1’�"™C¢>�7?í÷ x'¡ø.†V�ä»ùaòîüûî‰�],8vÌ”:ÁüAÕ}ùCNFÖ/õ —(—©¡_À"B¡ÞâYjÀõðœqቓÂ`úæW„®Jó ]‡Íl•�AùÈÜz^|ú€sà€/Ä�hV¸û’ËõïòöÇWгO3¥3IÛ-5éÇÎ×ìȆWï`xÿvù齄©fA‹€åð£åÊ�4L"\QÜßyÀ÷ð>ÂØH+QϤ¹Ê§Ÿ­Ê�žÙáõßžKrj…ëËRÛ øIDATÚñ ‹dŠò¾Õ°¾×ëŸ>-p¤¸ÝtÀqC(Ô´…°’ýMƒ.R.^ª¡™Ð¡©RN(â\G^%˜èo 7ͼ�ßœa`ýÚ )ÿ~àh`îX¤Üq8ЫaˆP³ÿµp(ÖÁ±{…Æ„£kÂÒ ô¶ íPY�(ò‘(ò‘ûzÎ>_`%¬%ÿ;¡’> |ë›òœ[õ£ú7Ò‹øs}É|ï°ú ï9÷ì+¹í“ªŠ!ÃS'óp“ ¯A‡E!tHœ Lú»¸ò€ÇT"ßÄŸå„e�%pÓ å¦ÇN@{ñ|ã„Ú€�ÀÿÁï� OŽÎ…¥�Ð5Ohë†òâ©É�ш‰"?·®ðs€™=)¡‚þ­„ŠúÈC¶G?›°N?Á»dRÐWáB÷¬�÷l¼øçùeÝb§#ŠªA‘áµÊ°ê#Ø¡xºÒT ÑÞAWüÓƒ<¾9; XJ$4 Áõ�W®ï×°l@áPŒæ+\ l‡ã÷OÉ„U¹0Ø}B¹ʃsЈ*E>2K£÷&§ êÚ˜JÛÿ[Á×âG5 Œø&ý oÓˆ¾IàB7È{ôâm5Q•ãYÇ5øý)�D”ÌòO;E>2#y,¡¨nÞ41ú6aàLLÑϑ߭ðÇz-!+s…÷¼m˜áêðÜùÌušó:ýgGXØ \=í¸v¯T8¾ ˜Z XVdŽN ×Í¥‰çÒ¬Èì(nÛ€_ϽN«žÛ–f¢#›áD‘�̶è�ÂP}·ˆfšù€WÏD>¹ytŒè>ý>¯ÔŸo*¢Ú·¡L¬–Õ #„ sÒѺ¿Ÿ•�Áj ú¶‚=ý:²…ÐFØØ\ *²�žI(,Á%uÏ%µ øl+n·™��Á¡>½n8µGX4ÿQp¢ÈG‘�Ì"#'EDraa˜š\Gh€~6Ñq½ŒwèÅ„®…ÛŠïv"~ ®ì‘ ¸é �éº Û›KË[WdJÅÍÁE£ž‹F¦9[ŠçÝ Œ5ál„§Ïõß�#ÐE>E~nEïz@$¿¼ˆà—N»ï:àE…a9ôåVQä-“zïÓÿa;¯'¬!¿ª#�øÝ¢ŒÀ�×ÝhqÛTûÑ×c™°L6½8pIq}<½p’©أ|kLùÖnÂVÁà6à'Àî� À /¶ÂI8�οG Š|ùH ¤¦aQB»Ñ﫦]Øwg›9xg³hZIäkzçé—¸•7ŠÅÞ¸_àó»�<²ŽÀôŸëE”¾“PÈÇA¾—ŽBôç‡G™€eÀS E‚Íy{�ÝÊ7w)ßlÖl-œŒ-ÀØ”òúvḅ‚…Ð1{6¶!E>ÒÂB8¡¨î1Óî» 8‹�:l «k’âGø�¿‚Gf¿yCïæ‹ú~É[‹HïÕ„µøHk]«ûs2|)@»š­ƒ› ƒú�# ‡à(B¶®½È4»nR¾°SÖÁ… Øm}ùHkÒ4K�o ð·Rô€�†â­„‹ÿIÀ‡Šã~ËsOÏp€¹�x$ ïr6s�~œïóšÂhÿ1¡‘Ldvd¦_KZw^|Çw?›öøæü€v¦š-)¢õ¡"°ª¸¯}Úsî‰ùHë üàB5}“;€w¿‘Ðí6¶ÜLh2"› ¡X¨½ˆF EFK )ÂÝ…šG(ôj6Ú˜W<>›ƒbh߯cßñçñ_¼¬ø¼_~Î�KÓ�{Âr@��Æ_üß�¯ªÿÛ…�Ý…£ Ä%º(ò‘–øà;EdÞdðÂBà›Qøí„¡4ïŽ/<ü÷FâÀ þ\B Üaô¬0Õ¯¸œ0Án ¡Øè€|øpU4Ì«ÀïãGú!¾øÿÛ»›»Ê:Žã¿ A4„� ÝèÂn\èÄ•†˜HBƒZјå¥I |¡ Qd 1’XL1  Q ¡˜P_@lRR#V EjLK±›¦©ÂЩLïãânævhµuZ:÷ÞÏ'™´s‡¹´çLú=Ï9ÏyN>ÙH}^à9 3™[ÍòE›cry€Ãèzs’{’¼èµÝI>ÑE}þ‘ÿ#©ÉwK“ü´ Åà à”îcpûÝ{»hÿ.õ±õI–wg >›¹[Œ>“:møžî€ã%£¯ã¨Ÿé<ÕnÉê¶4u¿ö¥Ý˜f4Æa~�ö‘g‘{Kjíù †Fõ/%ùX’-Gøž·u#øéÔ¤�ÁYœ�$¹?õ°š³º‚ßwaŸI-�ÛKr}ê1µƒû‚�šôÎî=þØdLâÌîvÞñ@¶´[sK;/5éê²ÌÍÒ>FK̶‘gDœžº¾~ÑÐk¯¤V=ûËa"Ûºï¹.µÎ÷ªî``i÷õg» ?š:Õ?%u=c’/'ٞɼ?ˆr;ŽïÕÏöv{VµsR÷Miè ÀH~L &Â]9´ßfR§qû/83Éy©Õü)u[ÎíIö¤É™?"ýGæVñÚ›äWÝhýŽÔmxÛR�®M’'»?Ë“ZŒÃH~ï³³Ý�kÚ»Rs!¾.ð€‘üd~uøÁh{’«’<ü?¾w_7jehô¿'ɇ T¯ÕϽvkjIΤÖÜ>cèkSø6d²WY;>ÞÝ~œíí©³.7¤&Hˆü˜ê¥®‹/µ|é (R§Þï;Ê÷Ùw˜×¦�«ýó^{-‡Þ‚óÏî×t›“ЯeGîl¿ÍS¹0uýýzûùñ·,u½ýŒ¡QÝÚÔŠr³6ÏŒäg³;÷ö×çñ\�ä—In´o‘oM­L÷øÐk¦n�ûwœÊýÈÌÞü¬ÿPÖgYø¯¦Ö$°o�Æ5ùÅaoê)pë’<‘äï©Õí¦mš1ˆ|?/gCÿ¾<�O¥Vüš} ˆüä, { µFü#yýÊsŒbä[dS»7wå£ÝÜWR ˆü„E¢ŸšŒe"Öhí½v„×gót[“ï´óSÏ‚_éà x#¹&¿øb/ðã0’oégk»'ßlJ=Þ÷r�DÆ!úÛÛYÕ>˜zJß©§¼¡œ®‡…ëòÙŽöp®ig§é{u’ÙD€ÈÃhŽÛçÖ›ßÕÍŠöîÔ#y/N²ÓN§ëáxd¾Ÿýy®Ý•+Û;RwI|1É‹6 `$£ìÕìÈÆö‹ÜÑ.JÝù…x / ò0.ië“\›º6I’m6 °8]Ç®7ôûÓ“¬è~ixKÕFò0â¡ï¥ž;0›ä²$µY#yÛ’lN²<É›0’‡Ñ׺Qü�Rrz0’‡1 }y@ä‘DDy@ä‘Dyy@ä�Ѱ¤g€ÈcéÑ‘Dy@ä‘DDy@ä‘Dyy@ä‘Dy@ä@ä‘Dy@ä‘‘Dy@ä‘DDy@ä‘Dyy@ä‘Dy@ä@ä‘Dy@ä‘‘Dy@ä‘DDy@ä‘Dy˜pOw¿¶´6üzKÏÆ‘FÏT/I¦’œ“%½$é¥7¿ê*"Œ’^z-™jókÞþ/¦Òn²©@ä�ÒZ/IZ’›’ÞÖué=7ôÅúÚÁÖ�õ› "Œ “¶.ÉÖ${u ¾ßKúI25åT=L€ÿò;{™î› IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/show_coordinate_system_label.svg0000644000175000017500000000256515143647637026741 0ustar00paynopayno XY XZ YZ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/show_plot_toolbars.svg0000644000175000017500000002107615143647637024730 0ustar00paynopayno ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/single_selection.png0000644000175000017500000000103714757047403024306 0ustar00paynopayno‰PNG  IHDR,:Ë »‡sBIT|dˆ pHYsÂÂnÐu>tEXtSoftwarewww.inkscape.org›î<œIDATh�íÚ¿ŠÔ`†ñßÙɪ… ƒ`e±ÛˆX*Š"VÞ‚…V6âmˆ`ç�X‹V‚•…`µë ,ºøœXLË8³3Ùä¬[|¼’“ï<äKRu]ËÎà¾â^aÔ{ÝÑcxŒÔ3¹ØwýÊ@DÄ&áÆ Ê6ð±OŸ GÄiÜÀMÜÆuÄ’ÛÖÚ¯e%ረpWq«É%Œú t¥Šˆ'X7•áÎ6‚mÆ–?½C¡ÂsÝ·êÞá Þâ>žj¶€e¯Ä7lc«É¶éGó¾®ëßmQDÜM3œ¡Â|Ÿ—½RG…ª®ë×ÿ[¢ ½3‡MΦgS„³)ÂÙálŠp6E8›"œMΦgS„³)ÂÙálŠp6E8›"œMΦgS„³)ÂÙ %|jź“} %|~àºÅ 0ãs»þ�ï™—-lôéMÓ•‰ˆu\Àe\ÃCÝ&Svðš|®;H6ñlæ|;™2/cï ¸Œ]|ÁÏ9ù…Éì W¬¶�G"íDÊšì=éNÍËÚ>×öÍ_šßÆÏ[Kð¹IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/single_selection.svg0000644000175000017500000000171014757047403024317 0ustar00paynopayno image/svg+xml 1 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/sinogram.png0000644000175000017500000040604014757047403022602 0ustar00paynopayno‰PNG  IHDRÝÍóáÝisBIT|dˆtEXtSoftwaregnome-screenshotï¿> IDATxœì½Ûv¹Ž´KÙ’½ªûï÷Ò^]ÖÁÚkCŽù)ä”KU> ÆÐPÎÌ$ žÁȼYk=¯Á`0 ƒÁ`ðn¸ý§ü5ø×¿þµÖZë�?þXÿó?ÿ³ÖZëþçÖÿ÷¯µÖú¯ÿú¯µÖZÏÏÿYc}ýúu}ùòe­µÖ—/_ÖÃÃÃZk­ÇÇÇõøøøòÎׯ_×ÍÍÍZk­�?®»»»µÖZŸ>}zIó¿ÿû¿_þ*­zïææf}ýúõ"íº_ñòw÷ìÇëöööEž�?¾ÜÿðáÃËû„Æ­ï1-‡’­µžžž.òñüüüê·–�>Kye¹(JÖ>\ä5å½þ>|x•WW/ÏÏÏëéééå™^§¼¦ÿÌS¥_2~üø1Ê«Ðv÷áÇ—øU¶”V…¯²b¹ÝÞÞZØþTV×>+îOŸ>­µþÓ?þüòûööö¥Ý:h»Ñkm÷uÿññqÝß߯§§§—÷´¾ê~½¯y×¼j|æË—/ëßÿþ÷EšNª[mŸ777/õõñãÇ—wžŸŸ×ýýýËX£õ÷õë×WãN*“ºÖ4KÎ’õñññ%� Wiº>Yr§z­tˆTî·k›l{ÏÏÏöY…Ñ>¦×wä~Ý�‰úëÅ•ñׯ__õÓ”?E…[ërNÒ:®x]ûd½hßÕòúúõ뺿¿_k­õðð°þüóϵÖZÿû¿ÿ»þïÿþoýïÿþïZk½¼CYu<ûðáÃúôéÓúüùóZëõ¸Uy¸¿¿_þùçú÷¿ÿý’–ÎÅ•Vj§ƒŸ£tÿÐIáîîîbâÿã�?^®U®�j­õj@¬Aäñññbâ¿»»{Qîîî^—ýë_ëÿý¿ÿ÷¢ìÿñÇGJ7ÿë`œ”1æU¼N™Ó´U9(e” r©Ê'/ŽÊ«ô%¯æßÅE•ÊSz–¼Ÿ&pNdN¹cxÍ‹æƒåK¥WåsåðñãÇ Å˜Êóã”ët}{{ËKe*åÎÕóVíþ�?þXÿõ_ÿeû‹ƒSJ´ï©Âõðð°þïÿþïe¢NÊO…ãb­®“Ò­q?==½”÷®}êuå[徿¿¿P j|¡ÜÕo´ïèµöy £ŠöÃÃ�»þw |ý_éh;îúQåŸq§tºŸ›œÒìdª{‰ è”n�Oú^µ9�ƒÊ°^»q�QíäáááEÕ¶Z 8Çæ‚+­›Š£ÚúýýýEŸxxxxéÏŒËÍUµè®~~{{{1êñññÑŽÙ÷(Ý¿&FéþÀÁË)¢nðvƒ®€»t5�nMèXÞŠ;ÉÄI€ƒ•*j]N–Äêž<£ì|¶c·Ýäžò_ùsYZP0î:-*RxÊïXáRžwJNɾַI²&ÚûûûWÊvÉ@%Þɰ›èNúÇÇÇÇ‹6Xyøøñcl3iBwýU™@¾c,+~Êsww÷ja£yè¬N‰(v»Ê„l¤+Ó4èÿ’G°‡‡‡¥[ëâññ1ö·t­Êa•½ÖEÇ,k?ïXk½Ö0š×Ô/SÚNÅi›×¼k¾S»Ý¥áƲTŽ,33®aå ZwïN¶.¿i K‹¤’£îq!¢ï�²ýkcoÛ ƒÁ`0 ß…aº$vŒìóÎeÂÅ«ÿ+Aó«‚ì@ç’Ð1'NeÞ\Z‹r‚ÄïÞ×´”%tq°^Nå!ÔlžÜ•–+;úñ³ÿÕ{ô5zzz‘»3«“éÖ:¯ptó`�±\5ý]2&ÿõûûû ÷eÁ;†˜õïê�ã ™éŽõN,¨csë?Ù|ÍÃ5ìµëÃ]¿vyrïº0é��¥RÇ­Ä@ŸÊøËÌ17Í-»9éäž“ÇY‡Ýþ}0J÷/€¤hwJwR¬’’Õ=s›ôÒÄÚa§è¹÷k0U9µ�9y7)i:N†4`ê„NSqAãuåØ!)Š¿iýíLŸ» ¡”,—ÖÝÝÝ+?J·™O+õÕ­�NÎ?Wå*…>)6ɇ¾S6»ž“[•B•�nô›ÕxÓ2nVsý¨È8·†’Më_}Ó¹¨`xÖmÉWnÚwª-i%Ÿî1©ûªÐ» —���/‹±r!Iû4îStJ‘ËÛX·¨(°ÏëÂ4¹QiXÆ×-è»q^ã#’{^Zk»EåÉ"€cç®L]~]\lƒŒãTéNé»´wq�þ{aÜKƒÁ`0 ƒwÆ0Ý?9œY=¶Öåj;±™dK#L†‡ï){è˜D2�{ 7”íXÇtw&`—oþþ+ØeõÈpWdN®aæ Ž™"㤬¬–U1´»¼S.ºŽ¨K 74º¼”ÕÍÍŽÔ¸•å¯t¾|ùòªLx\¢¦¥ÿÈx²�¨|ÊLëx”Ú ¯i�T‹�¶…daKyIl¯æÃ…鬉®¿¹±2õË4‡0>–·cõ¹©2!¹LV?v›¬»ðÝÜбð‰Õï˜îÁ¯�QºpïήNfúÔéÓ`LÓònâwH �ÊC_dÈ’òDiwbÆÎÜ©×t3HèÑnb¤ùýDYHá©(¬•O�à ¾–IVgþ]«?¶�îz´œžc«ÊS:rŒùay½eÁâ  ¤ƒÊÀþ•ÜKxrˆ¶÷ºæñz<Ç:É’òÍzqåXòÔ¢`­u¡ð2lÝSßí’q­^‰HŠ••ú…ëI-zœaů ÷ÉE!õùjƒ:éño'® l�<õEßÓ<±ÿ_³xØ)ßš†Kã`R>©„&‚¦+Ž9Úžô˜OŽ ×€ò²wùuèæ·—ûÍ0ƒ_ã^2 ƒÁ`0¼3†éþÉÁ“CÜGT t#pæ-…c4šèNãkÛ„d¾%#­Ï{¬2uƒî4÷^Çl$“}—çŽårq(D0™Á�és'OµÁ�É–¦æÛÛÛ ÆT7 ò„ e‚ɪ׿)mØd¹9+JjϼÖ÷´]Ë]yJÀ ¬777gM+Ó�¾ ™ÚÿódŒ‚Þ+95¾’‡.Ÿžž.ÎàvòtV/Ž'j9c(¾|ùrQ<Ñ%¡cŒ;7‚J'õS×~ô·c·µ¾»¯]ºq‹i»tÞÊ–îæƒîZ YVÚ5.'7Ùëççç‹ò*ë]‰®‘Û•]76tè˜n—?7Æî¬iƒ_£tÿä¨Aà âz¬71ñT uÐ<èGNîïï-+«Ö wôŸZ:’å%•ï)œÊ‡2°ŒËèäqåúôôtá¾ñáÇ ”ÊrZÿš·b¦ïîî.êYMñtÒñãëׯ/.@‰]uý Y–ê¾ZGª´LÔíHÝH”éÞ¹\ì˜n—g�pï§þBë]’Á•ÝNÆd5ªr©û'ñÈðòYœ¼®¬Ü{»û]Y±]3Î}ìGÉ’§q³þ g�`9¸|Ž]¦û÷Ä(Ý?)’‰M�n£™—JNgJMiv>ÝiB¾Vq`*Sªð¸cψΜ|29¸øÜ{;…^ïw¼*~o5]Ös}§è9ñ8E‰ænº|¸ ôùùÒ‡ûùùÙžÇ�ŽîâĪqŸ~b>•¶‡Ô¶xªH: NÓåä®_—T¹N&`-› S÷xºÛ£sÒ1ƒí$¹E0]çÂÁ4ëUŒÔ¥$}ÒÝ� “dÙ-D;…ç-Š�SúÝ©0Zÿ»”ô>Q-׊_ÇÁ�2ìL– ÝlÞ:꽓²e{va´�VÛÒ9ɹBéo.–k^\ËqUËXÑ-ü4ÍSe”îßã^2 ƒÁ`0¼3†éþI¡lŠšŠkµÖ·}úª]AÙ®îÓFÊ‚²õ^bJ:f2™+îÄ vŒŒÆ­ìbb3É$1�ôa¡dîvñïd¦yÙ=?½ßÝ# {sssÑžÜi*›;©£âûòå˃É/+&y î¬igm©g»öä°�u"�| ò•<ɽDÍݶS _`ýë9íÚÇjœr§”¨ d~w.%FÓúÞó‘ûœÎŠ?aדUAãg8Z4OòæäIVP–q]w²ïpÂY˜Ò«Ö±dåÕ0”•×Î%…2ÑzãàÊ££»ycðëb”îŸ4aÞÞÞ®»»»µVxjpIæEE躢p —m ·Ëk7yñ„†.œ “?•¯´�BN9OóÞ™r�Ï»+÷nÑ”wÞ§«ˆóµÖ<ðþÓÓÓËéÚæJáJ“¸ÊÃü¤8NMßî>n>c=+œoûîÈŠãþþþŸšõžÃzͲSå–®&®Ï«Ük­‹… [Xö\œïvÅýüü|ñ�§ð¨Û‰+�¤èŸ´…’¡ÿv舄Ô&© ;× ‚[hSáÓ±‹äJj·é™#`’Ò͹e×V+n\LõZé¸qUÛIÅíN3âq¤Št: ¿pšÆlæç‡Qº/ŒÒý‚JY+§t×D–<Æ_Ð B• 2:Ý`êâæD“ǺvǨé}Çr¦ÉOã9Yp�åÿ4ñpÂréìšNgYp5'c–rTûq pÆUÖ—/_.ü$éÃ�âvÊTÅí{n!r2yQëÞ©÷4*ÚÎß¼ íF™ÛŠŸ¬¨*]Ûàp¢ì'LÖ7i—^yÑv£ mš¾žõÍg´$¦Ò•AÊ;Ë â½VÉI D¶Ûn\Ó{?\?pá\Z‰5¥Â«òpÀgN~í/»½4'å@öXã¦bìP㞎Iܬï:YXºÔöu²WçÚvµ›C¿&Ƨ{0 ƒÁ`0xg Óý‚~¤Ê@%¤X¥Ýé% ²4åñäˆÄ¶h<‰%Ú±=Îe"ùwwŒ·cZwŒ¸3�&–âû­p Pr³Ñ0‰ív®BOÅÍã5žûûû—SJÔL«>¼Î”î˜;mg® Ý *õ;ÿÕ±J‰�T6—Œ¶“Áå�V€µ^ïyøðáà û«,1û„¶oÊàÜ1h%R&¯êj­Ëz­òqL7YoÍ»º”hÙ‘Á¦µMËÇ�Ñ�m´cDOŽ…»†mtÖŸŠ#1ÅŠÄt»4Ndq¬¾ß”Õí\Oܵëvã-~»|èµó_g^4dºu JåMK�¶UM/Y Ø/Sž†ÉFéþ ¡JR)ÝnSÔZߦÇÇÇWS7Õó¤h«’TR¨;¤Uïñ�d"MJ»þÞ¹$ÜM\.TxvyUÇ!™�¹yªpê2³Ö7¥E7ñU·ÐJ²Ö†8�°Ô…€“’+U^\›K‹8âÔ”î�Stc`Ûgz†J�†çâ—ÊóÂ<¦t5�%§¶ý?ÿüó噞çÏ4U™Öý"ê6”6m×XSï•ûJ-üÝb‘ÇÔ9Y4ÿõŸc�S>¯QúÒ˜¨iqü%Ò"ÎýæýTçÕ®ÙøÉòcߨ-øë­ó_ï\0ºqÀ…×öÉüÓí#)Ýú¾ŽcÜTËk7–þU ôé9øµ0î%ƒÁ`0 ƒÁ;c˜îŸµÒv››Ò·´9)1,4Ñ+›ÑvÊ¢0=÷;±ÊüMS*wó'æ<�XÑ™ “Éž2uùrï¿å†ÊwÇvºüèoe:•I®k·IOÝnnn.N¡x~~¾`–N6‘=Ôk èÿ´�”qÓ”NT|êÞ ÷ Ü1Üzß¹Ö�±Ô|(‹šâ®~èØ{­£*Óz¯N”Yk­OŸ>]äUÙl̓ž^rwwOwÐãÿØ”'[ÚYÇN\(Kbº]û¹´¾¸}Nû¥{O¬Sé=–a7†8T™8+O7gÐtjMè~»|pœ «–+eº?~üxÑÙ÷ÒÑ„§îN‰縕0L÷ï…Qº"œ(Ýœô;¥»Sô~r)áä¬áO¬'àÄêç ¨á)gRŒ5M“ ݵH¦Ôd®{T6�r²3WÓ'·Þá{NÁÐö¤Ç½­õúë‡)}æÓ]»ó®5¬sp®\p0L]§:t L‚õ§uDL…)U4¬Êàú®+ÇÊ[ùo«ù�'–h^yJQ-Î>}úôr¿Ü‰\Ù©ï8�,Ôg§Šó—Þ¡ ]ÿOi§öªe侯«ùsí�uv’w×/]ÜŒ/úŒ.NÄnoó¤ã¥¾Ç1j7>¥°nÁËóþ¹`U—KÊì”pæGÛ7]ðÞ²0ì0Š÷ïƒq/ ƒÁ`0 ÞÃtÿDàæÉµÖË&Je•mK¦ÝkX&÷J²ÜduvñVdó’ ;Y•a*†1í~¯ü<>>¾’[•Äö$sç5lýµ #¯ M:±†øøñã‹«€Æ¥'fÔ3e�µŒ‹5Uš§+[e­q;‹'™¸²($pbÔô~1Y‰¥<ÚVµÎ5]ÝHìÄʤ}–®]´®ì˜µ‡‡‡õøø]Ï´ ³_ë&Ëj3üñÇ…Eíþþþb“šÆMv»äN츫/מ˜Ž9έÉ�{'fÿB•Or§c>Ü8è¬e×Îâç˜U>s¿S?`š�Ü).ÞÓñ¨³$$&ÿ”íMeÅ1Ò}©’}OÇ1çfBW˷µ™a·OŒÒýÁÝuwwOàaÿiÕÉÝ™å�¿)MÒ�¹óÄ”KŃÂάJ%BãH)…Ù üj~í”*˜Š“…'! —òÚ•5Ó×2Q÷]|¸ÉÀ)˜úÑ›¯_¿^|Åp­K3®S’*Þ¤\'¥ædb®zt2Ë8õ .¦’{‰º�°¿9™+>·@d¾¨°:9Ãh]ª;G¹�¸“tQ©§ÍTTÝÝݽøëÓ) ®½k>é‚”ˆNAq'è¸ÓJRŸ;ƒø]¬v§ÊTs‹‚$ÃnÞ�!®ŒÙ~Ò{�¢ÏzéÊÔ-8¦¦ë„Ž8Ðð5Fkpcˆ’R\¸ÒÝ)åûééÉÖ?Üï.¿ƒßã^2 ƒÁ`0¼3†éþIpssóÊ¥¤®»O¿ƒE€Äë;4«’™$S’˜½Ö¸OÌ‹4jü|_Ù‹S`¥ïÊÇÇÇÈ`Ÿ°�Üéšaô·«;Çœ’•­ëb¹•ýwndÉ_N½PS,ͲŒ[ë¹Ò©÷ÒÆÜŽIreäêMãsí„–E’­,%É,î\Jh%âI2d‰%V—²dIQvóáááb“¤>Ótµ=)ÛWéh9ÔXÃÓ]TV²žÎÀ÷v.'$ƛƆ°OjÙsC¯“…i§q¨c?;•÷vؽ«å{bpñïÂUýï,Wd™9'éûÚ§Ø—´­«ÅAÝ¥tÌ×ñ€›~9Æ&w¾“ùà„ñü¥û'�N~ê›[®%Név~· ÉD~ê ÿï© Ù…á¤•ÌòŠ�¯n2—&ó»[ÐÌYáO&¬ÎÜzbV%R~>~üøâPõ¥fV§tßÜÜ\¸Ð¥¤:—W-?~qq­K?áJWåq‹@Æ‘òÍ{ƙܙfÉãœØÝ"¥âfxíWN«¶®§$t.\ M»|íëøF•)-2Ü;OOOëÓ§Oéò”†-¨‹‹[ø•"äü½)'ÛCZ`qÜJa4l×G5ßÉýªCŠ»S<ù°SòõžSPÝ¢’ ½veçȃ.Ÿî½n¼;]L¤±œ}ÌŽַz­c/Ý‚•m“‹8çZåòæúìn¡õ=‹ÅÁÏ…Qºð˜@2ÝÚiÕW³;J‘'ú2:&±ž¹É"±YT¢v‹ÊÙÝï”î4xS†·lš¹fr>Q¢�òÉç:Á([§uÉÏšk���/_.TkÉ®=¹‰Œ‹NDI©ìØM·rï;fVe¢²¡ÏTé®vÛY¾®óÖÉä”î�?¾b¬ë·nh¤‘”°Ô�t±TqTÜú9mÆ£Ênî qò¹rtLìnQšú™I÷ž¦IËK ò¸Viº†M‹©ÓÅ~§�뽎Iñí°‹/-’*7V›K‹`§t»ý=ZŽé8KOhY¦bí,v©=~?ŒO÷`0 ƒÁ`ðΦûG­ˆuv}g­×þ†ÓMÆÀ1¼ÏÏϯŽLìÏn7�fcMß1]¼NÌDg%Ô™ùcÓù…“õ:a¦xÿ”IruÄøÉèÐq­oÇLºº\ëCôðð°¾|ùrá»�Nû(¸úQVV¡òuùf:;swÉáØ?eÃØ†y*ˆ²UZ¾��¸†uœúï˜÷Š×} ˆ×…§§§õôôôâR¢ær5‘W»O¬®Ê ãÉZßN>©c5ëÚ¯æò¤å­>ý´�¹cÚ(/­o'm�áõ^ryHcãHèʹs5èÆ7½ÇqúÔu0!1ÛÚŽ]ý8YïµcŸcñOÞc¹6£ï¤ýOšîZ~¬«ß<�¥�ïº7l÷`­Qºx¨?¬ÛHé÷58")¨úŒ ArèLƒ)MMÛ]ïdsïwŠZ·Øè&ˆ”nýæñqú}�u2=�$]˜JSÓ­ö .%tO¸»»‹uP ÜŸþyafu›‹Nàê©Ê„>¾õLßÛÕ­K�>™Ö¹¤ÐÝEB·Ps eH ”*ÜTè.™§U¶ûûû­BTïê{nÁÁ#Õôìí4N”¢Ÿ”U´uÆ}!š§ÝXàdÒºKî4Œ‹2§=+ s2NhØTyPÿ“¢Ý)‹'iº6蟻~™9¼—d`¼'㾎qz_Ç-]øÕ¹õZG]9º~Î6�pºhåû÷¸— ƒÁ`0 ïŒaºp¤ⸯD®•?ˆ³c)œ»„s/q¬à§'O¸ç;DA¦†Ì0ïïØçFÐ1`dÿOL¤gÇ$Ótªáô4Ö‘ZGèþ ñjãäÓÓÓzxxˆŒ¸†9Û=£ÛµGç àê¿ÂŸ´ Þw_så}‰MTùƒVa“è®]+—’µ^ŸP²ÛH§.!ÉZVÐã5ïéZË¡ Ì¢ždRùq.j ¸¦�ëu÷,õ¹Ä¼wîÌ/ßqr\Ãf¦~ÐÕ³ÓN­i”Oó@+ѵ¬·“Ó�—»“q’l Z�\˜ºVæ;¥™¬Êt»ù@åѸºwO-ƒŸ£tÿÀ¸¹éÏæ^ëõ§J7ÃÔ5•¶ÓdR¯g�âé&ˆdbMq$\™(v.1�IÓ½wª ¦ÉªSÔ5.UZÖºt)Q…§¾VZᙟR°þüóÏ …N<—ßt¯àN~Ð<œ¸f°]¸2¦¹=É¨Šž*˜OÛ Ê•âäT…¶A*äNFæ½ÒZëÒŸšï�.`Ÿžž.Ü�´,ôô")<íÁ)ÎOÚµ�äjäò’Ê‘‹8}ÆEÁŽ<èÀœ‚§Ï\:ÝxçÆh Ç÷õ·ó»Å§s‡`y'å0åa§LvJ|!�HâÒMcÛ\š¿(Ojûéˬ' Áºÿ–ÙàçǸ— ƒÁ`0 ïŒaº`¨{?ˆÃÓôÄ}´‹ IDATçà˜ Ç2Ðü«5éÊB† [Õ×µ27Ý&”ÄÊ»¼h9$Ù[âL‘N†ÄX3lÇwl”¾“L¤ü]§‘Ô}erëƒ8üЊÖóýýýË—&¿~½üè�²j]þÒo2žtßPKÌé 8ŠÄþQe3ÓGx*žµ.Yp­s¾Ç¶ÔYrÒi?‰åÒtÕô­ídÇ´³Î’{XJÇåCóRP9’ûÌÇ�/XAý�Xa¶U•#å{ÇrÜzK»£,epgB§4S^O˜à~çr•äúðáÃE9w7&vãi²øéØwb¹©1²ò—Úûe7§¹2((Óí,j=rc‘–)Û\’uðkc”î<&Ppu/Yër =ùø„Þ£ 1™ƒ“ÿc…WE#M~œvƒÍ©©YÓ*YT>5]wÊþ鄱Ã.oiÁÓå‰'Ù8…îÓ§OÖ¿{­o§^¬õ¥»&VýèIç7ÚMÉdëN×Q¥Õ} Gã¢ûÈnrNŠ_jßšÆZ+g˜ÚmjßÕÎv}Ç…/%øááÁú›»zHÊ�ŽO59Eçà2*�"ÂòÙ)œ©Í¨L=á‚í´[À¤<§ò>UèÙ/Ý^‹nÌÖëŽ�Hý…eÇñrwÍ:JùÛ��)'$…ÊîÒwcAçâ”d[ër\ÔýOOOö¤¦[}±dH ÎÁ¯�Qº@¨rµSºkÐq¾Ÿ¼8@QA¨´yíXB…Kçd KŠi’óL?±f§l—SŒNÉnâHŠcW&ÚT‰£DGMçË—//ì¶ZDœ÷Ž™ê¶! Ÿ6LRYѼ¥…$A\»u B-#Çð1ÍS MòÖ¼V™ê9éúå» Ã… óäŽD,¿m­«´Q’ò8…EÛ-t\L“¾¤L¯ò¦L¾cR]uÏ:Ë”Ö9û¨æ;ù"³=ó=çÎÁòaý騢mWËA™|º;°œÈØ»<$Kˤ;5CÁ¶zÂ`²mu.%úßÀõ7מ]¹2dÇÝ;Gгîu̾“¡›3øÌõù²ïƪ.nµ –%NßIí&Y*i5üÚ¥ûÍPé\]NPî ‚ÝWÞÒd£ƒ(²'ƒsÉQq§Á8™1Óäyf•©ËC2«v“ep÷y�ék[ ‚òùóçµÖåño,÷r'(…»”n~iRáS‡¤lðX>.�+�­d9©©˜²ª\Ø}g­oÌ�²‰ÝG&vLŽÛHéÞc\‰MTf­擹›ï$¶å{̱îÚ‡ך;OÌÁL[™[edŠåvmCYÓûûû—ÓJj³d:Ù&å·c¶T^ž¦âÚ`wbF²F8VÙ±°Õoëܹ$8vŒåãúB¥£ì:ÝIÛ®uTe¢¬³æÕ}Ô©žœå«þ?<<\0oîñññâÔ�7¹_‘qNùc=kú‰ÝdÜ»ßõ?Y KéÊóÔ¥$YNØÎR�»± î'Æ÷”�¾fœéäqyMÖÈ.nƣϺùÉÉÓ�÷´¨¤~αJ]½œÛ— ç,ƒÜì¬ùÓñV㺽½}õUé·Zs?FéþÁ huκvŸ~/…ûä˜@rnâ rÇ! €iøNñÕgi‚Jƒ}¦K‡×j*tÊž3iT6—V’É ²4O§£î>}útán¤Šèóóóű€åZPmäć²3³:S,}ÿ“¢í.·8ãB�mËùíîN%Hù£r˜Lö<=Äõ—››×'ti©Yd1]n¥œiqåòSuél§è»¸©¨k{äâØ•7ãNcØ©2�úkNûÇükÆÄ“16-Ðv ‘*^•¡ât–’küz^u©Ä–úws¡Ý�ç nž¬6õñãÇW–¥JëóçÏë_ÿú×…\ƒ_SÃÁ`0 ƒÁ;c˜î4ÙwÄq«}2݉))Ö‹'eÔõÎ|¿CÇ.wL™ó¡~k:|ϥ߽ëX¢$[—'2¹Î½¤\‹œ�¡2jÅr§ãÓ–Ìþš?šöKƧ>ÜÊðjyPnæ�eå,,U>Η\™ÍºvmW]ML†;ɰswxzzzñÝÖþż²4}ÓoÞ…aû¤»LÇB3%ÛIŸIL·ÆíÞI}L¿ªêÚŸ “Æ;-7ºßésm�···¶UÝ;ëÇXö�d½;±ˆ¥²ª÷NYÝݸ|—“áDîÝ»î='wj3;«JJ³~뾩OŸ>½¸špÜI²2Þ¯_¿¾œ$¥®"z’IY Õ�°˜î»»»õåË›‡Á¯�QºÿaðüíkÎæ^ëõ§•;óäZ¯�§s×nr©ßi2N›XNPNá= _×îÝNÑpŒ{7ùwÖ;ÝdQ×tI>¡ôáî\JêúÄ¥„P4•N§pN6lªÛ‡¶UÍ+å¤RC·*W&ô¹ÔpÌ“s¹ òÚùm³ì Ÿúb>??_|­NeuPÅσ¨‹Ío]kßqÊ­{OÁvšÚP§î”Ê®�¤…�»wÒ¶t!È2¡¬NgÞX&š?·ªp»1Í=ß)Ëî™k ×¢Sf¯‰»«gŽ¿Î}Cß/¤�¹IžÓÊÍÍÍ…;�ñK{7ܼÒU—’j“šŸ"TñÿüùóZk­ýë_ëßÿþ÷«0ƒ_ã^2 ƒÁ`0¼3†éþ‡ «Üä^Ð}GYÏt —²0dº5Ýä^â\ #“Xâ´ñM™»Žõ9avlvN𤋮‰±Óü9f+1§¬óµü—&K†úš_Ý×� °ìÃÇr Üd:�KIçÒ¢ï&ö—õB]Ë„Vg¦§uEˋ̴kƒL71ÝŽùu}ѵ1 ¨a i#óóó·�9–Ñõs–)ßsåáêĹ5¹p©­9ËûëRÓ©>áävn;Ü(Ìö™6¨±í»4Ý3Í_z¯û=­ÃŽ�>9Ö¹¸iM¤Õ¢câ]:l;§28‹‹Cê¿k}³"«{IY“K‘ÆË¼U9Üßß¿´cuq{||¼h�z‚Êüñ†ÇŒ~ ŒÒýÁ�JR ·;U„fU*?Ý T×irçù¤§;¨ÓdšÞc˜Îüš&wg†îÒfº§“¢B]MÜ„’|”éR⮹Ȣ’[J—*ô¡æäç&W¾u�ŸOçñ„î””îdŒ� Ú)ûµŸ¡äѲÒ8¹ê&Ótš ËË-†œÒí”\]Tt~õ���Öµ¦z´˜úS²$E«Sá6Žë™ÝþùçKøÁ¯ƒQºÿ¨¢M¥;}ú]'mý0Šós¾uÕ±OÜK8p¥É¢Ð½Çwõ^§Tœ*‘I‰H Á5p“ }�Ó¥dp+]Jz윚´ijL ÂiPùá)9®­ñk—twquAŸmºé⃟t×pÚ¦S¾S?PÐo»s5¡B }®@囋3í¿Î]¢âУ“"¢×é$}Vq9…'µ×÷5]]8$Péf?r}GëœfúnQ™âVÅ:-’‡[(¹k¢/O�iÁÚ¥u"ß[”ùJÃ-â\8}Ϲû¹ü;×¥käÝ•e7Nhý«{I)Þkýg|ªÅ0m\üºþrq¬º›é8ÁãÓ UƒŸ£tÿà&FÝH§>ÝdyLàZ^yMÊ"7†ìŽ ¤RÂÉ4)Û ã& 7ø)ºIèd`M8�Ü(›Öƒú@k¶õ‹ÊZ—›*õÁ»»»‹ý5Ú�µŠeòððpq~·ŽŸ:Ÿ|üøñŧûÓ§O/a†ñþu0>݃Á`0 ƒÁ;c˜î¿Î�ƒGÆuÄQ“ò/$ã¤i§4ÈtÓÄîVîdÁ™^rõÐwÛM“Ý Ã³cw“©™Hqpq©|k½vŸP’§s8–ñþþþ‚½ã±€)¯INÇ´©ISÙe‚4]•‡×ü8NýOìq¥»;ÓYJ\½¹:Jl0ã«ðΚÃðUZ&|ß]³/9¹¿|ùò*ïîã8»t«ÏëÎ}æ§Lwj·ú,¹¨8«…“�Àa~õ}2¬Œ«®¹W&•Án|sa˜¿¼5œ"õ^»6tÒÖ»çUç;&ÿææõq\Ü®Ý;†™íLÛRjûW±ÜênR.`ü0؉Å@O¢ªSªÔUKç�b×?þ|‘fW>ƒŸ£tÿ�HþÔ<§Ù™—u#�¯êÌoTô�»ý¸ÓFô‰éRßÛ)‹5ÌÉäs¢Œò^Š·sŸIeì6¤Ö{êJA…›>ÜîX¾� I*c�´žyL LÝ,TàFÊ.šTún»O» Ú½×µ}Æ‘ü©õžNünbíÎ!vyàFè‚ûºdMÈ�§¾°®“‡ñu~Î./õž3ͳLtÖ�ñ¹:§Â«õÒ¹¥Å°¾Ûõå´`qŠšËCʯóáÚIo7Ž¥¾éúËÉ3—n׿®QYg·‹?5N>'Çå”·^!X¾ÖÚµh÷ׯ_/”îäZScäZÿQºÿüóÏ—4çÜî_ã^2 ƒÁ`0¼3†éþ› +XeDÝ(Õ }˜Ä}œ¡~w,lÇÊVš¼NLPBÇZÒ¨L@w"‚c™\üIǨ¼õ=ÊEvs­oL²3ç¯u¹ÁFw¨ÓuèÄQaõ?Qò¸B”Ù.†7ÑÅã²T'«Þw›yÕÌx5¼š_“iœ÷»6­ï¹ü‘‰vG•9¨œL·˜.gEÑc"+î»»»WñÕ5O’q2\Ùî¬TdÈKn–q² ¤òVù\]è;®¼µýu_ùd:iÌpG®õŸ¶ª„›éòw‚ÄÖ2cÌëy’Ü»v¤nzüŸúQ²\кu"'ãIVÚÄö—;`mjüòåËÅq‚is9û¼>S÷Pks~¥«'™Tš���¯,dƒŸ£tÿMpŸ¶^ëRé¦ ÈZgG·éÿt ÍÝT~Nº„nÂÛAåwþâÉäÛ¥×™�ù;™!õ™SÚ:¥²ò ®œu'¼Ö1'ˆ©®’Y�uî&§t;…ƒ®é(>mëîÜyÝ·�òֵϤt�ºLQѦ²P߹7B']í¿ºp¬w´\µOÔØàò�Ú|§ä:8Åו�¶Í*],t>ЊÎ]¥ÞO‹!…ž}Ü)¿ît¦Ô·õ>ÏsOïQɽU÷Iù¼–Hi¸kÞ;}OQ2¥ÓGXv ³‹¿îŸ*ç»ø8¾r¼T|üøñ¥ÿ}þüù¥ ~þüÙždBùtŒÕtKéÖs»ÝQuƒ:=e\L~~Œ{É`0 ƒÁ`ðΦûoÀÍÍÍ«³¹Ó‡R” Tæ�æ[·™Ê¥KfÛ±Ž‰5##Ñ1-á‘ÝI,…cJ\ÜŽéÚ1.kåM?ŽÝ^«ÿ Jrª÷ôÌUuÒ/>²OØIBM¤lsÊ2ž0Ý<Þ±},e ui¹†¨EÙ�;ó½¦é6&óÔ½ !™¤KŽúÏòq.a”“æóÄþ“­M›ïÒó®-¥>Ër£eŠí¦ž¹ðÅè©ÅçÄ•!mÐÔòÕñÕå¯s_ÒruîEµé-±¶¬ók-ƒìG®�±�¨׸YèuúÝ]§8“ÜnOñœ0ÕŒ+¥—Â﬈*¯ž8¥gf;·�Š›îoÎ R–N=ÍJÇX�³•é¾»»{õm„ÁχQºÿPáagÖÎ÷–c×òJ¯S�‚˜ÌJ+¥Ã{o1ê@äN¨àïdÚíâæ@¬‹ *ÉÏ2MŠ–*›*Ù®^“Òt­éš‹.*D&?•‹ž³ž^Ǻð»~PL´cº;¾s)ÑvÑ�5íäy~þÏfKǺòNã†öe•™V•!Yk4½Ž…Mlw²`\ƒÄ¶k:U'®ÏïÆâ“q– '[’ÙÉ}*C’Gw–2mnS#¯w.Ÿlß:·;ˉÎ'dºuüü\¥ûAêÔ�yÌœSÎvÇ&xòé>9Ý¡âMÏœ©¯'¨Îìx¢xSâä’â£ïé®ì˜/n¢®øy2ÉZ¯¿ìx2ih¾*n7™ª¬ª˜Õûš®[ÐÕ"`g®Ö¶TiêÞ7™UýŸ(ôz/) Ì7•;…*Lüø�Sð˜®.f’›'ÂT_ì7å3Lùnoo_•y½“2m�;8© ï”s…Sº5¯š•R·¨ÐzУúêYRè96UÉ/žyI.\ôÍÕü©«‰ÆÁ¾¬u”ÚYR¸ùìTáv}7�‡ì‡iÑs"C3 ©�¹ß.ž�Hýß�¥Lãéé)*Þš&‰²ô¥J–cš;Õ}êáá!~™WçÕø�žÁσQºßꃙ6OR�[ë’¥¯íZç«;¦PÉ49wƒlR˜ø¾l¾nÒ%kJ…;å¯c·U‘ÕrÕÁXÃW:Z» {»I­{–Øm-¨/~}±S*�º®Í’ªètL•{ÖMÚÌŸé;ú['z*tWbÞ4|õ͇*Sœt]¾;¥[••¯Ž«ôT1×Åùnã%•Þzæuæ“ùP0¿n� ivãÅ_ñ™kÆçú/áWÌC…×ñWYô´ØgÜz¿{uqºxpãr7ºø:ëŒËÁ…ÏNV½î”r×_vùéÀ±&-†Ø.œuZðZt'¹™¾›çuóýZëÕü­é*i2øy0>݃Á`0 ƒÁ;c˜îw‚såP¦»v?ó(AžXâ|&;ƈlPM«‹ƒ÷²t9 “Òeþv,zǦ*«@LÇhÔ-«TŽt¥àõt¤Z’»s!IŒZw*�2IÚžôc&êúÂtdGóÃüéoÖ›²‡§,yúíîWœü0MbâÈ~1nÇ&òô“ŽåLÏ:†W­_Ú¶Øæ´^XŽ�LíÛY ’u+ÉͶڕé‰üZ‹™Z™øQ¦ÔÖ)+Ùúz¦Öž>Óå…–L}×±¿'¢.?Îj•�ÆÈN¦ÝÅ�~wÖÛ†Ö±ôLÃ^Ãúk\Úwèê±Öå\ÎD¥>O¹iÑÒ÷8—kºuí>Ð3øq1J÷;�›ê’’â>ûî”n:ªéy­×Ÿ~×tœÒ�̉D'à º¸;å;™5wî!U~»÷:—–©n~ÕA’'é+Íüì6�vfcç*àü¸×úÖ–Ê‚.%??ûwmŹ.ê~¡ïu‹W½§yåDÎ~éÂó~统üÏYç•fµ]P9å òíaÚ†uáx�rK— ½¢@uʂާµ¾“ÚÓI‹3}�ypõàÂt>Ý ·�aY±¿%Å;Ýï”×î¾_v8Ïç5}ñT†kºwuì;YðPùUÿnuÑp\ܱÿ*9ã\ŠjÜt.ªº~ðãcÜKƒÁ`0 ƒwÆ0Ý1;ªŒ6™ne¦vN©÷ Ü,¥÷Ü)Žõ¢ ùZæºVí»pŽIº–Ua˜ÎÅ$™KÉz¹S Ô=ÁÕ¥s)y~~½q2™O�‹E½—Ø8Ö¿Û<É0µYòééi=<<\0*‰E׸x’…Zkc�X"nÒK–²Œ‰�âN-ß·f \ IDATnÌs›Pëz·q)µ¿ÊÇ [«2°^”¹UÖ+±f<¾’e§í›ï¦~ÙY—˜í'uÄöàâ®÷ÒØPeRrï1n2Ó®ÏÒÕ„ñhûìNÎ…ש͸÷æDaK‹Ö_·˜Ò~yMš×7'ñuïéxé”ßRºynw…á¸ãÊ�+ÝEÝI&•öàÇŸ— ƒÁ`0 ïŒaºÿb8殘Rýxˆ2§…b&u¥œŒ´’ndh¯a‘*îäîpbò%œ ÁIú×2"i㤓Á¹”¤ûŽÅR–‚çª;¹OMô‰ÕêÜchª¤ÕÄ1Á”‘mWÏ”§É=É­ïÑ”îz}Ï™�][£Û ûK:£ë;®Ìk£Ò‰«�"Y†œ'1éÿk]j92ŒšÌµþ”¡KU>ÊNfù¤ Ÿ~x‰ñu–}§cåºÙ”mÈÉäòèÊÛY‰Ü¦º.î]rý`gQIŒøéÉ1®|Ü ''›óÓ¸³“Áµ‡Óy'µ÷Ë7Yš´Õøøõë×WËqî"U.Oú±ž�uSO/Ñëï=ï~ð¾¥û/D÷¥B휪t«)®&ÒÝW(UA!Ô‚®t-Ù Dlw“ZRN&”]\»AWóÃ/Ú%óp b�;NÝwõU2¤#é†àò¾[xh^é*àü;u çON `™P9£\]ÞˆRÒœß48¶u¥PÔDËòrÐûnU2pñ˾ؕóË´]Ù%庻¯nDÚn™_-;mÓªŒ¸PL 9Û‰ÖåÜ�ÀTáO•¦®nݸӽw²øw .>Ò»õŒeÒzï\{Ø'vmãTïÞKèÞO‹×/;ùRz'2%·¯Ê›Æâ$+ÝÕTáýôéÓÅ‚©íkzúŒ}™é똯D�ûRåàÇÄ(Ý!’Ò] ·2†:Yñ³ïélîºæ™ÆT$’_yRº‰Ë½›d*t]7àî”ý?I­ �StN•núK«"óüüüŠÝÖ÷4n�uòìÍ’Y'M·®;›?Ê�Ž“ë&µNy¨çº“éºEDýN ?æ')ÝT$õ¿*n?­©]nBß),Z¯*ãru®,.ÓÓ8hÍPYÒ§±]{æ©2•úG ãÊÛ=ï‚¶Sô]©xô=–7o 2.Ÿ,>ºòæ¸Õ¥·—]NÌ9ÛôɼÓ-¬Ò½nŒíÒ<™—ºùH�ñ+¶{­ÿìѹ¡«;7–ws‰‘j[µ©rïãÓ= ƒÁ`0¼3†éþ  +Ne~hþqÇêʖǺ‘]sÌT­šÕT¬l»ó×°‰!ê —˜\½¾Æ½âÄL¬L‚KÃÉS哨mšÝ5]uápŒcÇÈÐ×´ø^§øž¤Ù½wͽ´XH -77¥2ÖñM•îÏŸ?¯/_¾¬µ.÷×TŸJ.Q:–k:]{â¦J7¦ ~ Œ{É`0 ƒÁ`ðΦû;¡ ¤;±d­ÿšÏc•âæ-Ç`tìXŹ֥‹ Mùs’˜ Ž}qHÌ-ßéXÇ,)ËMfºcb¹ÑÔ¹)sç˜Dž âòE†]ï;�QSFŒ›g¹1'±Y‰Ñö¤L �–Llm‡bü*>Z;ºÖ¥ëBr ãØ!�Ü£éÑ�«àÚ㮼£Z¿S¾ë¾cÿ¸y2•eã=×;®} à޽ëØëdYb>X^ìo;F´³RûÙ�EŽ¥Þ±®'lµÞ£{a׎OÚzgmé6ïú�ûaçZå~Ÿ¦yÂä§´:¹5þúbqÓg)Ͳé*‹õæ©"i\¥Õ2Y–´Té‰Sãfòãa”îï}‚麰ַϾ;?YUºKpæåtòHuÌîÄ’JSÃ)’R[Ïvk7ŸšOw2jºîÓË]šz� #ºV¤Sè?½sçprh9¹kæI•áJ«þÓ\é–µš¾9PóD�ÝDF¹]Z7ݪR=»öͶ¥uÑ!™ðonn.¹ìo<l­×uìN¦©ÿ¼¯iÓ'[ßqùs~Ü N†®ïQNýt¼’Ý"‡ŠÑÎeBÛŸun1©L]úÝøâ�”®4î1Þ]y»ÅŒ¦YŠëɉE�‚Ù)ÖÝ‚ÌåëdAGyv ø[|Æ‘äÞ…aÒ"ðyR::®ªÒ}±w«³ungÿOóÉ>u7IŸ–ü3÷’Á`0 ƒÁà�1L÷Q+SžX¢+N~ ‡»Üë?Ïòt«rç>Qÿ麢×dŸNLqú¼cŽœy¬Cgvåª?±Idÿ]ü”…ŒbºÉr;‹ƒž£ÎgŽÁ>µÔµ¶“d†®6ã6ÜÐ �eâÚ Ý/ƒ­¿iúäÇV‹žXþ®¾�5€rViÃdAë�çoóºP mbò[èÂwí„gövîe ©ÿvró™Û¬ì¬\‰…£)?�c›ù–±jgÝÓ|ð=gñи]\®Î5ï®mrC]ÿ™—nwí™q»÷5;f¹cÑÝ{;üÕï©L«Ïk¶‹4§¸1¬N%Q ÷çÏŸ×Zk}ùòåÕ©djuLL·Ö»†qsÜZßÎì.¦›óÕàŸÇ(Ýo„SŒÔÀ}�Ò™ŠõËwî#é¤H’Õ)SŠk±µ^JÙý/œ*îI*À…¤„pbOÇÔUùÐ_Ú¥™µ$÷nâʼ_•Õ�ÚP2Ôb�“³;²âU…œ»î+.. œ}jçy¦Q÷ÓXÅ}7*›Ž¿úáœQ¾ Œ{É`0 ƒÁ`ðΦû�pLž²¦Êt;×ÝÌ¥gjêj¶3—ë;4ç» ;Ä K±K×…Mi�„éØák6O꪿þ+ÓÄûŽuR&B?š¢ìÓ#CœÜ'´°�(ƒÅ ú[ãHì Ë û`Y›º§ÏYæjâLm�mαTάÊ÷yÍMšZ<û¾cºë­¶�V�ýšP+˜ËC—™.¦™Xô‚c׋•{xx°ì•‡žõ­ Ÿ~àCÓ9±z1O×0²ZF®}§°Ý½ê£©^œ…4~×ï:]ûÛ‰µ$YÁJÞkò·ËS —æ'÷IÜ]}'»“Óõkׯeãiq`šÚKOøüùóŇr¢E"1÷¬c×¾k\W=Ä}loðÏa”î7À�ÈP×<±¤Þç`Z�•“ZòÏ­çõ¿®»¼8åt×Ñ;t6M®)Lç‚ÂpômíÒ­ÿÉ�[e£Â]iñºû`‘ÊêðTn Ï³†éÜ"-.Æv‹€šÌ;EمѶŸÜ<\Þ]ŸHîõ_Ë+¹¨û (,_×'ºÓ4xäç ¨D&ň ‡.¾Bg.§Ò�âÖ0÷÷÷¯Ž1]ë² V�×§yÒ/.:¤>˾âÚ]·ˆK}Œ¦x÷N‡r—9);Æéu'Oýzz²û8º¸S[åÁ¶ß‘ižØÝßAÛã[q¢øë{©>®EêG:¨2œN2©>¥ÊðŽ\såíd¨1_•îÕ-fðÏa”î7 ù«/•û¥vN[V÷É’¤�PeI×89]Ãtéý´ çö=šÂ d;eQŸ•2–”î4À‘µpõâþï˜D")Žn"v2¸�ÓMnS­kO)®Jw§$ÕärºÑÏ)ŸTJ;pcfũ啎TìêrçëdHJw·pPp¯‚¶‡®Ž˜V§¼:¹µìTŽ*ƒ¤tkšªTh]j[`[½flp}¾[,ž”ßëú,ËG7¾um}7Îrá c’–#‰š4pñzÍ‚9!)÷|žræo§_û¬žwýt·x{+X_©Žô½ÛÛÛ—M•E´¥±FÓé‰ÚßÚ/U'!q3øg0>݃Á`0 ƒÁ;c˜î+AV�«YžX²Öº`ƒÖúæÓµÖ·cõ9Ý ôY]“etî%4;‘Y<ÅŽev.úÌÉÝŧi#°c&´Ó�\œ™u­×§6$F3Õ Ÿéo²íŽq\ë’™pGÛU�óx³dõ y±c;Ól¥ã|¸wùV$·!Wß®¼\Ù¹SJêYÅ�\…’Ïcǘ©ÿ²Ë÷ ë¨æeº—iýZÉz£é&vÕíp㓳zpª2©ëŠÇÉÆºLx~öq&öŽ�Õ|ŸŒƒÉâGËëAßK²Òbèòçü…;êÊ/Í”ggÕqiîXæwÀ$c‡Îšqâ³ÜÍU.îÄ@§º¤’ZõK•Ú¯t¬¢ª“�®^õÞÍÍ�eº£jð÷a”î+QJšltó$¿@©fÚäoZqj¸z¦×ê/ž|Ì;¢âïž×ï4 w¥S6NçµüqX;¥Þ)ÙIQcþNÉÝ•ãé{NWN·6¶Ö¥rÝ×ÇI±[u¦âŠ[�¥r u½Ï Á¹”0 óêŽÎÔëZ$9eŠÊ·æ-™y]y¤…ˆ.8®Qæ\ð¸½$[·øà}*xL‡v.”å.Nñç˜È2I}‘ãÖN!Kù®0IaêÎÓERA¿[òpáÔÁ-.»:wŠ¿Æãüv;…Ú½—ö8%;�}©LÙ·OÐ)ÚLëdQ²[à+vsŸÖÓå{êzš6(_;?¯µ^)ú•^ýŸM•?ƽd0 ƒÁ`0xg Ó}5%VÇ�XRP¦ûáááÕ1�õN25r­Ìæ ÓM†ysÏv,€†Olò5LybMÓ�Ø>'Ï®L׺tO «tµ *|ªÓÄ$ò×ç•Õ§ÜŒ�V8gýqL~Ç:§0]Þ\ÞsëÞÙY÷:üD–k ²jÿãØ{"ï.}7·püf]¨žðéÓ§‹:×#i5 Ž©Úîô™nªÔ÷´MêI&?~|¹ü½¥ûô“ÕF­f£¤tóÄç6PØ ”: ðH ~SÃr—õn�Ôßirã³ÅÜå‡ùt¦yç«ê¼î˜ºN¹× Ïù×WøÓ‰„®Iqs jÉàm—¾ó©v§¡0Ïšw7eU¥"ùqwåÁòw "ÁzÕ0�û͉b‘”î.]|š/ío×Ä—”½ä^Ä>¢ý^Ç&úõëñaWÅWß Ðs¶ÝØB9¨äèøT |™âw‹O"=KJ{É¥ -«ŽLèÚBZ¤°é=¶ûTn;Që�Zð¦±FãeûÚ¹>$e<ýÞÍ\xœ‚ò¥ëî´™T¯¬#Ê[ÿSNþݵ÷Ë�®¤Š0û ãsõEýAÇžd’ö¢ Þã^2 ƒÁ`0¼3†é>€šXiÚ×Õ£;±d­o,n­bÓÇV4^ «ÿ+nž�6Ì1ÍÓ©ù<±Æ' wbgœ|'ÌÂZû“,hjÖ°<éƒ ûŽéÞ1:Ž¥'s^²(Ay+¼2ܸv‚ŽyS¤ÓPÜ.û3mçþ¤×)e·_•ÝI¾¯eÇß‚bS9¨€6ÜšÔÜ‘<···Ö[�Ê�XÂÉ MÏÏÏŠ?•îS“§"M˜ŠS…{7€véwér¦²™d8‘©§tkøÓ‰…uIó  OÅJ™4‰S™JeÂÉ&Õ‹sqJ¯*Ptgè&m�³[\¹<ÐE@%7ÁÉVq8týÀývaÒI$8ѦvÖ)¹ê;ÊÓC\ÛRźmû»2­üé35w—»Åç©Âì åÄ/:R¦Åú£<ÎöæærS-¦¤@ó|ó¤Ü‘QÞ±„¾!úÝ>ëʦžq¼tï¥ð•�¤ïʾÒÕrpJ)Aå,�ÅTîµ=×½’!…ç= Ómj¾Æ�›}ªS”ÓBrׯ®U€)n. Ü³”f·\ËïH Z€tÓ¯ÛÌß剺†ö±’«þëžœÙTùÏ`|ºƒÁ`0 ƒwÆ0Ý Ü© µJU¦Ù�X¢«æbºÓIdCë˜nž¦¢á5N"±¿º¸v,@Jg^v§W$†×¥ÑÝ/³Úî='§«#2?é+�Û‰¾«yÕ6WŒEbk êÛ§²'™4n-ã݇ixTVr™ríÍY-”‘+æ&õ•?1¤×X3\�_ô¥6£î=§ñ‘ñg›I§ý(;š¬ ,ÇÎÔ¬Ïv{G\ôZË�þ¦Î*äâ;íÿ×ßNÂÒ"Óíg¨¸ùß¹J1 Çg�`y«Y/ÜÙZv‰Ñî6‰�ZK®AÇfj[p'W¸~°³@© H±f´>�ݮ뇇‡Wl6dž¯ñϱm'(¯–»sŸ¢|l3©]×3æË1§CߥŸÆN¶ŸÄˆS®Ô†Uí¼¯ j’É�uIöN¶kß!�GׄOHsÃIX÷Þé˜ßõƒT—ÏÏß\U·ÐÏvò³Ý A©¿Õ<3Ëù{0Jw@Rlë~MlTºu2å1\©#èuR^ØI’K ‘z¾Ó Ri@¼¶sº�"ùž9³óiütåP¥Ëù.^3ðw¦ÆÁÉ®s'ÑüQ¹N®K;ób…wr1¯ôá®ôê™›8NŽ6¤l];K~ÛUÞ'ÇÖ%…EÓrõ¯íιÈ0½�ÙØýæûZÞÌÛν¤�ú­§áÜÝݽ:é")UJ§Þ¥»\ò×ïÍFË8)Ž777¯NøqØ)]®Î+\RD©°®õúì{¶i¶³¤°ê; i�YŠYrÁ©ßº�ƒùL~Û”Ç-R˜ßsqìòÚ)²]Ý~¯RØ)¬i¾äëÐåÕ� ÚG*NUºùÅÝÓ¼iä^ M“ÇιÝƽd0 ƒÁ`0xg Ó (»áNV(¦Û�X²Ö%X+ÆZ±:Û­¬•ïN,©ð‰ÕSyê=eAë˜Vþ‰ÁÜ!±&db5¯º"§ÉE… ¯2j:Û•ÕI»�²ÛZÆõ¬ûè ë¡‹CÓa8ýPIÁ1ªŽwùÐëÄÂ%–]Û#-A Ǧg‰%ta\}WÈx'º~°3q×ýÔÈLé¤uβ׶žÚ£¾W_¡¬tÒ (Žùsl]Çzw–7¶ŸÄÓ¹cÓøHy©¯8¦¹âæ;]ûª¸Õu¤sÐsÐ׺lË®w ï®>X´œ°Ýo©Sæt<¿æ�z�s©ƒ>Ó¼“)O}Du 2ÝÝ8˜Ê˜'i_¤n¡sÃ÷Z£tNñSe¥\Kôô§t׉%k½>ö,M¬€©ˆ:Eß)`�²éL_î?‘Â1Ý–OR6Óàµ3ªÂ›º$·*5»Ϲ¿8%Ý™*5ý2ù¥6˜Ò×ãŸÜ³Š›ƒ»~FZeáBR°î$ ý�&]-W•/)SÝ„ïò™Þ¿vv§v¤8Üd̉¹ëCÚöU�f? KJů -çÆF‘µ.ǧ§§§W‹Rç#¬yýúõëÅÉ%o=sí›}Yãc™$ÿn*ËTpºE¡æ/õEÊ‘dLrßÜÜX%*ßÝâ#ÉŸÚ”Ö±k®\9¥ñûdÁs2u`¼i¾"áòVåp·€âuz/ÕGo¹X9W&ž*¢.ª'ù©2ÑôÜBÒ)Ý:îtnvƒïø— ƒÁ`0 ïŒaº·�Œ›tó$7·(“”ÎåîØh2éÄMóïÔäí®ËÜ¥§,,ÓHæ.º;�uM¬Pb³ºM¬*«“wŸ,wbX¹ -1˜ÚÖÃÏt´Lv§,(»Ág^˿˃ _×<ƒ»þ_s óÉß Ï6 H ýŽ9Mé(:òβB¦›Öíÿdû”ÉT ™rµhèæÉ‡‡‡—0´8h;qõUõ˜,6Ê®ÑÂw²1ºkû©.wÖ}–ÞuV�*ƒ]]ò^’átS\‡d•¡%áãÇ�ÏNúÞ)SÝõÍ“8R½f}oÇ�;F&±ãÉ•"±L®¾œ5Bý�OxbÄCH\^O, »´NöQ$v»~ëÿºNndž &Y+'Ç=±DÝKt¬*Ò£W$ IDATöرێ=Vù\›¦ëÇ´ä^¢áxÚ‡²p]»M'ž(:«ÕI›M¿cÊÖ:s5IõåØ_Ç¢²Ži]«1)1Ý^-qÅt?>>^lÊ"ªaj|º½½}U¦ÚVí6ŒQÖn#eWç,ëŽi®ÿKOâa§¶Å:ëdqñuHý=…åH¹œµ¶Þs' ½•=îÂtØõ_'O×6ö$MÇdwãL×®\[á5-�Ê>ók•ÎŤdHåе[gÙWkÛ_qÔå`”îWî:Y¤“ChšK~Ü'G£ix�¿dã)¦°:óä5aNÞ/yº÷ê]ú«vJ7Óq^}^xRdº�ÕÉ­rœô•¾‹#™´ij¦ò’Â;Ù ÉïWÛ°ç”i­¿Tï4='_]†×ú=iS§J÷©žîѬÎzßMÞl×ltqÊkçB¤a¹g­g7Vé;OOO¯ò® ø‰«ûµŽgl.nŽ ú¯»… óÆwê·ëo®¼µ 9·˜k”íN¡ÜÉÓáææÛ1ÝŠ´øæâÈ�»*O§@êóô~ŽƒÝ{%Þº"Üâší>-€Rß)}DûÒίÛÝ×qFݼ\Z•Žî¡|?ƽd0 ƒÁ`0xg ÓÜt…www÷êt]1¦³¹ Žm¬txr@:É 1–•Ö5¬öé{;–‚,Ob}Üi,d³Êì«ÏNärìS'gdž2M'ƒ+wÍúR&!¥Sype¢ïíʧàuÇØwŒŽ«3¢ÚðŽª4 ™Â'�r/Cæ¶³n¤0”[ãpýºäÖ1िÕ)JîYÊúÿðð`¿’Kv\Ùv2Ýž²)»éÜoŠ]ÓúS367”;¶u×Î\©YvaRxÊÁq‡puÁüœ„ç˜H™S�sLL–M�®•jupéÐÒádtù;±vèØè4–œXÐvò±}»:úæ]ÛªëG5~¤FÞ’M[óÑ�d2l÷÷ã·Vº9ÐÐÊKê½µ.ÍÁn"sJ·3í©‰È™�ô ™…NYì”,Ö�ÊÆ‰¹,Å‘”6gæ=‘‰ƒl™Wžè ÏSÚÉÌ[ЉÆË¸ïé) éÄ ýÍzIévå›íRx´½§rÒv¯»é»"óÞ)õ"nrÝ)1»t(¯Ÿk3,+Ž'®LK6gÚïйi›Ô‰2í9aßQE»Úd¥éNgÒr¡lT~µï¨®Ÿ¼v '«ó/hÙ«)½SÚÓøTi¦qGeÜõ9wÝչ浫ónLÔ߉HÐòÒ1»++}~Òf)ëé}>;éË ;9]9ºwÜxä(ݘïÚŠ.x´”^ Êpé']_ì ¦ãæìôyøÁÛ1J7BרÉ8kƒ%ûã”»Š_¯«ñ—¥Ê£2¸NëLבO~N>awšc�N‘é�²Uÿ�¢âMÊõµr»0\À¸wOÙˆô~’UŸÕ¤šâf»uÌ ç�«qÝ¢ÈýV¸Áž“͉‚áòîäq²¨—då&¨Ô—uÑÆ‰¶“UeN‹3¶ûÚ<ÉñÉ•UÝ׺Õ|«UOŸ±};¦[ó]ÏÞÂܹ͗,#•�²�ÔŸÛC“²Ôæ´Žø^º×õ 7îó½Nëh¶A·p˜îïÃo©t;ß5*¼···gdkG Ò�㮣їÛÉ�ü€ÝDŸ”À·(í)üÎÔèÊ5Å—ä-è`“øtVÕƒS0ÒX'Ï8)1¿nÖ[F<±™]ÙéuŠ›¬nJs×µü8‰ªÿîYŠ;m(íÆÇî^²°i[æ‡ÜR½$YRÙ%9º0§ù#Ü8ýW Æ)Wgi¬ã{úÛ1݉ÝV·¯Žñ×ûz�,LS™ïôqžA�ßNéNþÆÕ˜jÒTó0Í‘�ɶà&Žú­ƒ~Ÿ<÷�:E—Î5HÊÏ©²B—’4‘½EÖNÑv&Ml§ b'�†×rIþªn°ëNP©¸¨L»S-8Q§… áqÊSr« Ñ-^N'+–ÉÂÂw’RÁx:¥Û…uŠ�–ÏnAXϺӆÒi!nÄ´&)#I­ô“KP· t �†}xxXŸ>}º8N,ù¢v}^ýÅur¯W˜wÊ”âݹæ¸kWöî?Á6Èþ’dÕ8S_f¤oB8œŒ ÉíŽe¥é3�“…‰^wï¤>ç¤ÅѵóànpªÐ»>ËwÒ= ã\�¢ýôôdO2éòG95>•Ç)úÚgÿªËï„q/ ƒÁ`0 Þ¿5ÓMFVwê’�VÖT™n®´;‹z�›(“{IbšÉD$è­Œ·cßê·‹³d&·KçŽeê˜N½NaRulÔi˜&¸³Zh9ê{ÊD¸2pìšc. 4 +k¦›ƒ;7–Ob†w,u‡Tß.Þ¦íëÍÉ3µŽ)#XLdbº)›c–Y¾©¼SùÐBðÖS\?ªSQj,SË Ë˜L©;9„c1- �\úNgM¨´ÓÀ¸OÛSÙDEgtmUÇ�úïÎ3ßYe\;+8+HwòŒ¶ï÷®�R¾ôînÌ/\ÿ޹ œ±ÖëSEtÌwßM`\Ý|É4©Ÿ(ÃÞ�©?ðøm”n�$ÝqV՘܉%777¯»�ÉÖ)pê’âd¨4ÝœN¸Fyåãâ¸F qn:”¯‹3 úÌ)ÐÌ×Z¯?ºAEÒ¥sM^9!8ó4•§4éjÜ�ÀI×-‚\þRÓTìÊ®\ŸÒ }²ØSœNZÝ„uÿéì”פð(Xnî”'ª �|IÉNy«¸Ù'’£õÊñéZE -^Ë¿»”ûA,],ºqÁYá»ZÒØÒµ™º.síÇ;·Ž#©¿íˆwr;Iò—»ö~Úžºû©Ý%·G¾§÷wý8õƒ“Ï.-‡·*¿§ñueì\ëZû�ë£üO²®t‹ÒoN\LØ–*Lé@•O2qéÎ1î%ƒÁ`0 ƒÁ;ã·aº+K¦[O,Ñ•äZ¯ÍzÎlœL•uO]RÈê” *_:‡ú-Lw’)ýÞ=Ó²+y®aÎwr'ÓY€Äüœ\SnÊÕ±Ú'›]•ãÊÏ û£yçç‚SÜ©}>??_XaÔ½„eâXýë�Ø-'‡ËgŠ+±°§éÔ;;Ëó—>äB �2šd›“å$Éà,`‰yåi%§ÖwBµÝHY›yrK¡ëo´øtn …tz†ËË[7(»öÆö}r&=ÿwõ•úebÑɶ§öääx 4¬Ûpí¬miNJyR8«ÞŽÕOñ—Ì»~Ͱî·k).O.înœ'Ó­÷iuГ֔éNgi'¹Ý«éh™Ò½DO¶œá·Qº�2Íë»»;{œ �JK;ÇÓ„Rƒ6�[¢ îô7§£âܽnAp¢¸3®N¹KÊe©ç�)®S®\|Tx:%<å¯{Ö)d»I–q$¥›²vJ£Æ­G¹}þüù"½¤ÌÝÜÜØx¨t3NúÎÉÇCRún·ðà{'ÊÐ[ÁúW—}¶;¡ÄÉÃ:îÚÃZþ8;­3�üøuº4‰Ÿ å¡â­´ôC9OOO/&j­#5[— é$)’»ò©¼ï¹.?;W� ß�Wîº{Ï¥Á÷4Mw‚ÏNžk”ï..-{mgªøÕ½zÏ)åL§[ð°}§ñÿD©|kÞº…ºÊt�,ÝxWÏ9o�0\ë[?¬gÉýƒrj?H'™TšL«Â Îð[(Ýip¿¹¹¹X-òŒlUº{t¢tWºbLŠ¿;&ˆyè&EÇ>°|Ò}§\•¬'aJ§dsŒXÝ`Ôù8v!óà&¼¿¬K½ÿ–ð4•�êêȵéîX¹Š³þ§ÉAe SÎxÜïTN1w“qWŽ;ådWdxدÓbƒéº~í~k®Í8EFëO?ûîò[×'lòná§ãb¥›ö¼¸rrã•œÒV÷SÙ=??_( ©?2nU8OÛwR*S¾—”î¶[Ø%ìÆ<�GFlCZϧóÓÉónl?�SÆÓ\£pc®>ÛÉ�Þ£<œOæU}Æï‹è‚é¸U7ßêÜÐí9s>ÝÝ¢tp‰ñé ƒÁ`0 Þ¿ÓÍKt…¨&c2ÝÊ2(££+ïĨ�1Q3uia|éºCg¢ê~ïÞKl{ú�l‰Íì˜îÄüt+îŽýí,|ÇÕ?ÓîâëÐ¥[i(›¤nI;ë}·yíò‘'2wÚ¦5¾Î¼«3Çr%–êZ‹…+WÞÅ$é³ÝÉ8üíN8ÒßNö®¿¹>²Ö%ã¬L´‹ÛÉãØµ“¶®ŒÚãããÖõ¯ŽéVË‚;uÇÕÊ_ÊCÇÊê}Z 5üµ œ]ÛOV‚®}/ãØÕ¿Öëı«×0 Î‚SÿÓ8ÑÅ}:Þž²èÎR±«¿ÎR¤q¸¸]úúžZ7õø@=IèšcýœU…ºJçK>_¨<Ão­t«Rý•Žÿ¢ÿ«S>Ò„â6¦i:4[ïLM×*�éŠïìoÁÎäÇàTYç='÷_±4ù�ž.d �y;]»ö§ bj›É�$)ȼwÍ„×ùž—–ÒÖ¼sÂã‚ÃÉ}Únonn.ŽÕ0ÚŸ“ò[ ÓnqÎß|vâR¦é8׎ÝÂf§t;0N–Ïýý½Í}EÓØÂÉ}WŽUßnÓßnüpcˆ+�7XÏ ï~ëøžú3z~Bãpa®Qº]x—·Èpc§ºÐÕÄÍi�\©OÆ{Â-ÆNú]'¨0n#4ãïâvc†Æ]×···ëöööEÖÅb+]¾u£q¡ô#*áÌß÷.ú~uŒ{É`0 ƒÁ`ðÎø¥™î´¡LWäúᆴu ¡c0xM¶öäÄ�£c‚:F¥[‘ïVÔ.ýtdÞ ë�XÇ<8ö¨cº]9¸¸»côhÝHLËÞ1o,§®Œw›ÊxOóÅü±Ž´Ýqs#�¾d^5�„†çÉ 3Õ}\¤kÓš®æIá˜+½Ÿâ«w³LwM;±›”³s=8í‡]›p2�…?aaulbzŽ•­çd�ÝfNZ^žŸŸ_�bBÐŒMÓµ“�r2]ûîÞ«ÿC\?èÆdE²Â¬õzsx·Vï¥üt,øµÌ¤“Û�«Zw‹Ìø˜ï“¼2¾Ý<´›7»ùÉÅ­÷iÁK̲Kûd.MÐ6èŽ>ÞåÝ=×±.Í—ÔŸôÔ¤AÆ/­t»†wsssqŸ_ Tó¤N TPœÙˆ“$ýñÒ•”îzîâ.¸7)m×vhN6”ǽߡÜ“ÂâईvnZ8Ð|–Œ‚3ÕéûI™r“¢{¯S¸©,¦/ý©¬¥¬ÔçÜKÜD–&7‰vƒ·¶9Wv.¿L') ›Ê˜y`¹öÀÉŠí3)9ìó;…†&[…ºÅ¥¼¨|k½v/aYîúh×»÷5ïznüÃÃë6ãòäÃê^Rg€ë"N÷tý-¥Sï¥zå‚PÝÝ‚÷t¡åúÚ®_ºqýdáÐõ'Ÿ¥ö�¿u­{¥©|º>º˜9Å÷ÆwÚÖôÙŽ8égÚ*Âåb²ÖåþŠ´`q2jŸàÞ #ÝQÌ£t÷÷’Á`0 ƒÁà�ñË2ݺÚ&³¬«p2Ýw6÷ZÞD—V©éÜÒä^☷S³S2ßñºc[˜N¥Ÿ˜|–ÁŽUI¦¼úíÊ8�ùÌøÜ™ÍIîºN_ä{L«“#1ÝÊfueïº0j¥Ñ²g9ëP&HLj�²^ú[Û4™šdyÑ2  Ìÿ ëåúᎵrõâ,bÌs*;–IÇä9k‹ë×Ú>“e‰òðt¥’çZ¦;ÉIY»6ª–A¾G¦Ìå»4~eo­ÿ0wj�T–YÿÓ2Ä4R?peÅ:ê6ƒ*ïòæ~§ºìâIc'Ÿ)Ø_´|»½÷RÿMîJ���±w}þ„¡ÝÍ‘.l7'iîìà¬wNΓ9¤ƒö ýXŽŽ!Ée‡PY•é®tô”µ¶ê‰)o9ÕçwÁ/«t'_]*¼Îœ¼VžÈºŽIó� s>Ýn"ë`‡“ŽÔ HÉ\J“ÖnÒeœ;YÓ€ÇãìºÉBÃSiÓ|¤ëd²ÓûÝ #)¯T(Nöì”mUÆê´¦Õù€v® šF§œ%¥„i%ù9Áw¦Í„ÓþÇgLg­ÜݤïÒ¥;åtùs2§öy’·ççg{LàéÉ?NÎÔ>“² û’ëÁ‡ÖãããËo=•„ï±^trwÊK)»]Û¨÷N:¦Sqèç¯]ù¤rH8Qº»ñ6-+œË+ݧRÿ»F×0ª:¶»<¸Å¢S’w2u8‰[‘æ�î½”æ.Ž.nÎqŒ¯”b=•M?–Õõy·ÓñMɉúŸt©Qº3~Y¥›,‘óC¢âÂ*ùÙUœõßMTd½:Å6mÀKŠ2åL¸FÑîÒOÊÚÉÀ¡º–iuL÷¬³,0¾$W*Sõ1¤HE=)‡©¼œ©žNÂð½´é—rº¯òÖùä'4ŽNþt ÞW?ÜN9àýEœõ’&I]¼¤¶½SÌÒ¤í”vö=�4Õ‚Ñ-~ÜÄè”nM3-rN2�Ò;­L·2Ö777û 4>UV;ßQ-«-b§ý�ypm°ú޶ãn<Ðü¸ruc Δ‡]¿ìðÅÜå¯+×ÔGØfÜ\Ó)Ð�ÒÝ)µ©.øÞI| ©|êz7/vr&�ÁÅëÆÿZ òKÛk½žWUžŸöë�Òí6U¾uQô+c|ºƒÁ`0 ƒwÆ/Ét£æšäïDsXrqè˜n†'âVˆtÑø:ŸîÄþªl¼f9–‰i&3¤c½N™ïúŸXpWÞK“äÖ¼%¿]šÙ\3ßü�ò™˜©Îr�ºdÊcy°Ýñ™îaHèØ¨tŸétmÁírgÖq²nt,Sj·'mÁ±ž‰�T$ßÚdyQ9ëÚí÷ nnn.,C,K̓‹£c,™NrwḬ֥ºb”kI={||¼`õ•Iæ˜íX4'/åÓß&±z‰Ôñ‰ãf¿OÕ®miÔŠÀ÷ºãõøî)NÆòÓðÝéNº¨²:±@¸pkåñmg)è�ƽ—Æ|—æ522Ýd�(ëŠ2Ýz’ɵõªí¾ú�öKÝ34'™œá—TºK)Ù¹—8s»vnwÔN§tëÄáÌDN)tŠëΠxWº—&Štížu迵¾MÆÎ…ÇåÑ ºÝF,*ݪÈh¼ª $3Ÿ¦[›Gvu£ƒå;]<©¼777¯f�ß¹p`¿¹¹¹0û»|7i°ýkúI1vy­|œúþ�ÄÝMôõûöööÕ3ןœæa NAëú¿k»na[÷UÑz||´}Ç�Y©þ˜Ïn|Ò¸vŠ�¶Çêóš×N™r$…èÒ=—´N|æ%«ëWì«lg'GLrNIJiZHîà©'cAŠG¯�‚©ñ܆ù�ÒíÒsåàÔÓ¸¯Eê³§ „´8tÏSüJ,п[ušnìuý±ÛTùôôt¡WéýÁ%ƽd0 ƒÁ`0xgü’Lw± ºÊvGÛ�U"+“>R@6Cá 2Ý�{‰3W2�»�˜j¾§i:v-±â]š%_Ǽ¬uÉx»0\i»�üd3x­,±û°E}ÄÃ1Üd{:†?1DÌ{2'ªé8YD¸18}y0íP§¹O™óØ–Sù(»Ks8ã©÷X^š†CêÕSßqõÏtëåÚcßsuαà­ýÿÔJ´c0w̯ÖË ‹Êt”íÒ6­íV7_2ïÉ:©_©ìpÂ<^s?•]1÷.=Zu\ß=�ÛÌÙ±µ§íVÑY‚Nä9CûCš‹»ÓKTžn~KõЕÏ)Èœó~²p|;I[Ã8�ÂÅÃyC]Mô$“.-wŸ–*M‡Ö(u;™“L.ñK)ÝlNÉeGO“HwL SLùµäîà&Ü¥y§xïžqPLiž*îÜ€Y“ÍnR¨2Ý™õw)Y鋤:¸èd�<]^ÝÀÈLÍr•–“Û¹Æ0…StcÐ.¾N�Ni°Lø^ן©ÿ§…²+ïBr­U¿ëÓñŒã%uοu}ÿï‚q/ ƒÁ`0 Þ¿ ÓíNàp› Z+Äîƒ8·[§U åëN(èØ™´ZìÂ1nÇ 'FÎÅëV׎õ(�­à‰‰H,LÊ·[Ñ;yœÉß½wR¦]^Ý3WÞnï¶×¶ÈjyíÎ^MŒ¸î6'£•Îv¬`]'öÕýf§¬¥k·i“�KŸŒqwˆþ?uIý�ñsLJ VÁ1ò®þ)7Ù¶TÞêR’,"®�¤:R$¦››‡•9xx°mƹé¤6y-ÓæÚ°c?]ÙíÀ¾§m£s éÚ±†IáõÝŽE¥»Ij?Œ/�åÝ=­?º$¨ÃÉ9æŠT÷dÞO­çnNJ¬~*û“4»9¶c’µm¥“Lº2`Ù% ÝX4ÍÛÛÛuœç_¿ŒÒ­J–Sº»c×ê™4@:å¼ÒÔA…+'Žk:e÷¾KÇ)©)®“It­~0¦bG¥ÀMº§Š6ëX;z*º|h�™/ ~kåc"yOO Ñ/ñ©l¬›ÍíS IDAT7‰W9²íÖu§t'ŽÔ{LßåÅ ú齤(Òân§|³=»Ét§tw‹D‡Ÿn*!Ý^�nAÎtK.•SÝvååÚ†+m'éT™n²NãO/qyªþ»“µ[@3L§0é³ÅÊ�wŠÝ)®Ž\Ÿï”X-{*êioD×GOÑõå…�ýÒ�±5_kþ*O×|lådÁâäW9ß²pKí©k3§qkÛHq³\�Ò­Dd-~w‹‚*%h4Ï�¾uÒ¯~ü2JwÇtó*Pk­—Æ´[QSy]«Wº*MÊ ²&Æ9ɱSbÜÄÃ2a§uá«óž.œ¬ô™åû»câÜ*>)ÚÜ8—Ê)MЪ`t`Ýký3Í_÷%ÔºN‹Çöh¹º �×Z–dÞë¾ÛĤØ)#Œïšð'‹¼T^\@v¡O˜û�R’&¨´ÈM×κá@%«[ìï”—/]`8<)/©?sÁàòÄa‚ë+nl§ ”Uqª¤|“ Աȅá"+-x»yIãv~÷×*ا åô¬ëÿ*ÇÇŠ«|ºÓøö_ï´àéÚÅ[Æ:*¯§åèä9�{w .fÖò›*]í~I¹çu¥uz¶þ¯Œñé ƒÁ`0 Þ?=Ó�le�noo-˨+ºbZ’{‰c&Ý{dâ4Í�ߦcˆvLÂÎlz¼i<Ý;’ 1­l+o4“»<ðw·¢Na]±|O6Æ—ýÍö©mã-é¸ß”�ñ¸öNyÊâãXp—G—_ǰ'9’"Å­aèR–Ê+Y/NÊÌ=Ol”c,»ñàÿcïêÖÛÖ•�Ò¸ûý_÷´Ns.Ö7] `†rœ8]Ä�e‰?Cr8‚Å×εq1ŽýC9‹Ê,#ÇCÖÙ•=é…êc\ŸXÔ9õÞ‡ª/þÀÇd…¦ë߉™vÏp?6Çq«`øÜµ?n±`[ÉeRºîNð¹Ü–jea«ûnüÆzÀpÝÉ0êÛÎ„éØ—˜f®'¼žô%Œãìªw\n·[-U²áö0”Am/©|&ïÁüWðå�n·OÚ l< óžBeÈ*^¥åœT¼ ‹ò¨4Ü �é»gˆÎ™æ½UÎÙwN~É’œ|¬÷¹Y¸”ÑN2°1V{£YV”MM$”c’ ³srÙ©}zz»�ß7Ñr5p8ÇŸåÆkçXñQ×^I§Â*Åõ+îË®NœLÝ‹§Yìè°Mâëún@׿“ÓíÌäø³>¡œ“—ù’H÷¹î«¾~ýúõÛf¤ t²�îý%—«ï¤�NWÒv¥41ÁøÎ¢=šl}Ã|Ê¡Ÿè·³‚Ò#7é™8µÎŽ2IÅN7ÖƒÛ΃iªvx� È*¸�ݸêúåJ)B…'¯ì+=V¶õK}‡BíéÆ|§zü·bO?6666666666îŒ/ÍtóÌ�gt8“ÃY¢fm///|dDåÃàc ŠiwÛKë2a¸YVÇ9Ö#ÉÀLÆ„ý­º¬û)¾š‘«—�ê——ÅÜ6Ǻ œ•�bºÝÑH(3§�ÏÔ _±Yœ?3j‰­q2¤0ª�ù¥J.‡K»c°�]«UÅz±<È‚M˜-Õ×ùÆÇ:t×®,Ê>Ç[Vy«ûe§”nLí‚OcafÑ骓ÕÙ-Ö1NÛŽ4Õ�ÔÖ…ŽéTzìÚ˜Ã)ÝJz•dDY Èt³MSòq¿Ä¾ÝÙî k­n&åéd¨k¿Yð§ûøßõ–wZîÙŠ=túµ²Ú0±;|í(~v²"Ryv¬<¯Rð©)ÿu¦û¯qºÙiSK®€JÃK¶õ¼â³±I�˜eã­8P°cŒi³3àsÔ§‰®$§�ÿ+ûŸì£Ó­Ò‘[ì*BmÓTß(Q@½Rº•œîçççÿü &{{ÉÆÆÆÆÆÆÆÆÆÆ�ñ¥™nõAœãx¦»c,ÝÇHÔËÙí%S8ÆÖmoàp‰ñåûnëï_¿Ú¯y¦ôK\À«xKIZÒsL=ÏÊU\d•óÇõPñ0Çn(&™ÓNo”»üÝýJÛ±m)-ÅLuŒ•b{ºU ŒÃ/ºmDŠuIàþªÊy PžËå"™®´ZãXuu²ÒD7¸�Z÷Ò‹”NÓÍÿÕŠ¢ÎŠwzå^ûöí›üÊ^bŸ±¸˜ÍC¹•-èÒSL¤ªcŨv¶Oµ·Ÿ¸í”ŒgÑÕ·‚Ò¥ Ó­Æp¾¯úŠê‰ñŸÈ½ e#'ùMâàø¢îãj[mAªÿ¸=T¥�ºQéã–´äûàõu›É—vºÝ›ì¥@n?m�çŠÓíŒ.§›Ñ  * „ì°¨<“cí œ¸ãø÷äç¤bœ´GQÉQm©öçO—*1_Ì«d˜,¦ãº n QAm¥á ÜêþÞe˜Ý@„Fš·?uηAj‹¤÷ª-Ù)u'”pì&§œ—IWþì;‚ËZåR_sUý�år:�[Àð~•ÕmrmÌ2¸~„u„qø£LXÜç•�ýþýûq½^ßœš4™”8¨É†š¤¸òð³äœ±þLcµ�e¨´ð²ƒNî×ßøþÔ©t2({úúúú{òZÀ­&îýN[Õƒ*÷YçºÒK¤EWßÜ–.NrÀ�Ÿ ÆØôåÏnbSiª´Ñ¹ÿ¯:Ý{{ÉÆÆÆÆÆÆÆÆÆÆ�ñ%™nÅtÇŸK'j{Éq¼�©M^PÌ_Çtò‰)i¹”åRpŒX¥«¶´¥¤»7²piÖ‹×éƒj¦¬Þ~^•ëDmçp[;Sq{¤^�E&Y~Ç`ñI˜ï03Âew28f)åã˜Sf‚ñ>Ÿw=9•ıŒNvÅÂMXkNñº\¨Ój…NÉŒ+qÓí3ɦ¸òqü•ƒzÖÕWJ“YXüð 3ìX�¨—ËåøùóçqÇ›ínŠÉUàrsßé˜eeÛœ=á0]»¨¶ÇúrŠqú4µ¡lU¹\<'Bõµ*à^6>Ž·gãc¾nIõá•F·ôY×n eLÃqXÎW-מq°Ý €–É~:%·»W×üñnKw}ùã .ɤîó€ŒÆŠã¨#]ýÔ’ñ­†Ú (Ê‘`ê™:2�ããýiÝñ=5ˆ¨/ñ©>‹¨=øjË…Û×ÈᜃÉú”tšû£äR8Uwœ)˘&Sn`ÄgJ®ÎÙf¨þ’³ÜõŸ�4;Ž·ïZ £PöÚM�CÅ×�ÝRepõ=í»n—žËÏ à.^]«Á”�2ê¯z¤ö[u ø:ísO_ÅE8²À9{8ÁpLf*krÒÙ6°Ó§tZ퓞L§N)êÿÓÓÓïÿ×ëõøþýûï°¨£è ³Àåã¾çœ@åüò~z.SÒ!Ìc:á˜|å>íxWžÉŽUÜd�1÷u•¶ÒÕïU?ÀkW�\f5³mPíÊÏœœ·@•o2˜¦[é±ÓîòPéó;gLÜMôۜۈ�n$©þ‹N÷ÞÓ½±±±±±±±±±qg|9¦Ûm5Pì¨c ÕìLÍæÜ^6f»=Ý^‚3Džñ+(¦FÍð§,·J�eUÀá:ák•ç¥V*ð~ÇzàlŸǼ&&ÉíÚ¡â¨!ð>Çq ¿+Wlf0+Žõê˜Ì$ ë Ó[–‡?x¡äQ¬•c-&:ê˜Àô^‰*¿ ‡ù+¦›utÒßÔûêÝÅÊ£<†mC±ð.ßQûM1í²xc…c;ïôŽû‡ÓA'·êSŽÝœ°‡©Þ’>r˜Î§~¤äse˜>ëòà牉~zzúc‹Ñq¼}‡Fµñ¤|îýšdë& s çâuìøê˜ lñ-l´³GÕ×ÔÖüPδ>þ|I§{º§Û èuÍ_´ceQƒd-o«½ºœ'Ë9l]§g¥vKî*—¶3˜nϬrŒº2²‘@¹qËËä &×w*Ÿr~9mgy«×7—~ç:‡×•Aù——&m4uTÚn’À:ˆu£&,(õQŒ£ÊÊíµRo®ìi’¡ú›³MJnÖgç@«í|Ÿ¡lSÉÐ9?¼5�mìÔyq[$Òdm,ꞌ÷±<ìtã±giâà ÞQq}6Á9C)¾jÿd—¹|¨�øß•»l“’5É=±!“‰ —�í„»fùعãíJ•7OÖ\Ú,³ªcW.–�1qÐU›Lm\׿Öù1ü²2ƒ')âtãýÿÒ6“½½dcccccccccãÎø’L·šwÛ9 8ËMÇ Mâ»|9¾cCxÆ�÷]x·•f:ÓîXxwl™c‚øY’Ám)a9ºr¹2¨29öF}†ãÔ,¾Ûº¤þ+¶-ÕÊÃ,üä«�3áî»¶dp>Ìîs¸j#>�óÁúQ:§V=”¾¹z˜°”Ž•ÆrTY'L÷Tçœ}rl8—GÕ�Òc¾æ~˜Ê¯ÊqfåÄõW%w1aøEZÔ~a �T6µäà#ÑÒØàê?õ7UnU?“U0†c?™eœ2¹’�à2Mì—…íÄDo+<§�º Žku¬<·ƒêÃÝ8£dU:6Ñ›³Pl9ßwõíV øƒZ\Ǫo¦û-¾”Ó]F¤ëdÆíéâ½zç8(cŒyÕõd{Irb’óèœÀ[·”¨rÔ)%NÙÎ�¨e'çðâqD˜7×±+ ×Mr°óW<<Âî8òV�‰ ÇáÏ+O#†q“¦nP]u’T%7§á¶'`;£>ñµ3ÂhÜÕä�}$�ó}f²¦&Úèª_åX©ã̺>¦NÒÀ8XVÞ­Ž‚ära¿r`ävá²(°S‚aq2‚í̶€Û�ntºØùq“^å,¦¾£«dR>Ók¾—ê›ûߪÓÍz?-Ǭ·X“-&lj�­Bû„ûì¹-ÔÞñëõz—ÉÇ#bo/ÙØØØØØØØØØ¸3¾ÓÍ/±Õ½úuÛKÌñLͱēpn†Ø±°iÙJ=ã™cbǧP3|~i´c·»kÅDà¬Ã%æë;-ÛML·üÆËþN>'#¿A?Éu˱‡õ_± .1Sê>owHqÃÇ ®fp|þÀR]«|*m'OÚÆ¥Xf&=›ôEf�™ñÆrL®“žMV5˜�RÛ•Žãí·¸|Šác ›ìú%_§þÉ'GT<<³[Õ=®:t'ž ì,¢â¬2†“öR,º³·*�z–Ql—‚êcJ×\ŸPöõLÉéäSÏ’ÎqX_Jùe@\ùÂôT{)™Ü*�Zy@LëB­L¤¸Ýˆ«;ê¾êã¸J„דöSºªläõC9_Úéf‡—5Ð&'²ââo]s§DªÓ¯8Å“°�ÓíœN—¶x™Å èY$ñYJ;9?Éh'ã¥âñ Üþ¨[îÚ�p§'ì$aødØ'Ët�Ã6�j%ïÕWƒ³3èÊ¡wá&G|M'tÊ)Á¾­ô–û<Ú$DšLq8%kÅWu¢î«-%ˆŽ HΆ³ª�–lÊ©P(¹q{Úo´·\ßx’ .]s»¦Éž*çê³.|çèMóìœäz戄UÒd!É9ÍgâtwŽ(ê4nwpùª‰ž*ßÊxîÊ€÷VõG¥7­#'ùUè߸ñÒÙ z¦ü´ít?0ƒâfPÌ8Ç!BÍÖã£ØåH:Å�8ÑÇuÆ”§rü&y«|Ôî —X�ÉÌ�÷¿ª˜÷s¢Œ6súŒ�’ãÐ_;EÇ©ê$9lXVv:0_,W•íÛ··Ç Mö,ã5·¿ŒÝ¡ê¾›Hp>,–‰åAf‘'u®¬ÉQéà5�RùðÄÖ9݆'n®,Ü6Èþ«:`½uú„髼•]e‡Â•ÏMKnåÜ•œ�nU}àdÃÕÙ¾Šä@¡ñŸ?¾9>�ëÇ9Ž,§rd:'WéSçt»g.ßïÆ�ãx{¬›êË)ý•ë©sšÊŠv0•�ûêF…eÇ‘Ós}Ž�|U¨ö^uÈ+.ç‰÷S?N2`Ÿp{ãÕ$BÙºêcª­;ÙœÓÍïá�™€|5ì=ÝwÆ—dºÝÒ‡ÛrÁK‰!êökÕ,rÂt9¶ýõÕŸîÀåî–|ºe¦t_± ŽAÃð|­ÒUr«™­bÄTÛ©úÂ8g†*«Ê·þó5ÏÆC¤ädÆÃÇŸ'šð<êƒZÚW¬�cDYþIW™™ä2V9y9±c@“¬Gé�cüŠSíRÏ1N·� Ó~zzúƒév Û§br¹M¹_ª)îË Ýrý¡òMí<‘g¢oÌœãJÛa<½¤˜nÕ^ªîøšË­¶z)tì¶ ÓÙÖé=ÅD:›Äñ&l«“Ù�í²cJ;(û‹íÈéq?Æû¸]ij‹ùžóRý2+¼Âêv,pªc7v©ç|Oí pº¨|ˆËåòǪÚQÞjò_Øbò%œn·••_-‘ªŽå޽Ãxu]àeÎ×]'gZåÉÿ9ÏéËN *m.o¥Qõ¥Œ®ëЪ“ñr;ÖìL+‡ŒËãꙟ)]HeP“7(q›c]v/HñÄÏÕ ¦�2U6îª\î dî,mîv^ð낪¾Xל£‡õ•Òv“!ÃñÔD›÷³mJNkåo?yŽŸFvqØéîÊãäsò8¹�Þ°Þ¹û*�jöqü³Wûÿûß›òTÚhk¾ÿ~üøñã8ŽÛ°#°~YœÃÅesåìl§jƒi>][9Ë9dî=‰nÀº�œÑ ŸêŽ'>%›ƒ›l”ŽÔ~ÿ×W}„0ÿ29”ÞɘŒUwÅIvùbY];OlßgÿÆ·‰eQÛ|8=uf÷ÁéÞÛK6666666666îŒ/ÍtOXæB:&°®ÝKz< w/¹¦‚›U:Vgˆjöœ «ØÇþW¹'ì�Êë8üÛÊUVÅ&©:è˜ ÃËÀ\7é¥XNµñ¤ý˜PzÇpÇåñR¾cßû£XW?©��>:ýDf[1�ŽáqL¤CÕ‰b ÔJæ©ê˜ÃðöµôÒvÝïXîžü�õ…ñXp›N¥¡ Ê[ò­„¯|Ux–ϱ£)—.ÇÁ¶¼^¯¿Kfîqµær¹È“LXnÅtºò¬²¿N�;Æ{²Ê€ò¨0h‹Žíβº>å€r;Æ:¥ÓéG7¶V<¶wò¡Íçg¸•‰íoC;ƒiÝ*¹;Ýì|’ÔFŠé®ÿxâŽ/�ÍÆôª_–}uzó7áá�n5˜wNwµT˜–¤Ü–Þ†�òu{�¹LxÍyªxnpWá�CÈÆÉÕ³USÇÂ2©-%JÌ×9ÓüŸŠÉ@ïÞàæ|±>”¥òå0lÀ»e¹:©ÊIRu¢®¹½Sý8ÇÛÕ7ËÆº‰K¶| …`ºw)TÙ¹œ£ÄíÇuçQ.«êçn¢®Êê5ìì*ÇZ9Ê)e&r³.óäÃ¥úWi²Ã·â\¡ Xµçÿûß›½º8Ùÿþý»ýÊÑ9àlºôn_r§Äõe¿Tújâï&bÓ Bš,t¬ÒAÔ=ÞӭʧtDM*‘XqöC¥×• ËÇrrÚÇ¥‘ÒSòV8¶óªŽÜ±&¿XÿiO7:ô+öö’����������;ãá™îÄ2:æ†gœÌ2*ö¡ÒU³5ÅŒ)M±Öœ¦£âpY;fJÅë–þ¸Nûë‹4SF–I­@LÊ€3íĈpxuÏ1�*®*¿±�í¢tH¥3eyÅÁé“cëûètR±èªL˜3æååEö·b=:}àºï^~Vñ[¯ ÚÓf†õ{Ú_]-–[}™“eÆ0S•åVußé?êIªouݵ¯BŠÃq‘鯏lƒ¸½\I6µõ ­@9Lì3ÿwvŸ¹´¦Ï�á'vÆÅwa¦ý×Ù~Õ�°�Ö³zþüüüÇK•j¼Ä4pÛI7¶¤ûÓ>1©;gW§~‚+o/a¿Á­ð¸ô1­b½ÿ L÷—rº•Ãë¶y‡ÞR�Âuvœ£�¶€`úÉÑf9Ô 91¸Œ2<Ø×õ4�dDݲ‘š •J.É“×FÜߨ)Tù 0�®/*¤2azn"Ãÿq©ÓO}Ã===½ÙÆÀÏXV”YõK ‡Ž9‡ã¶â<±_*{¢H Õþ|tÛ“¤k~2ð30,CݯýÝX&Õ.ì8`ÚS'„÷xOú¼ÓÍ”÷JÝ8'Ë9ñ\nW¬»é„ªsò9þjۯµ �¥èCð—+ÕÇ»Øp¶Néˆ+“ë\†©ÐùNgT:˜7û\®m°¿:`}×ÇòTßþÛ°·—llllllllllÜËt§™Zzy²®ÝÒ�c™Í:Ž·/.%¶ÝÉŠy¸gŠåÆpÌ&ª8?Í>‘ÝvojszÆ-ùñ —sÕò·eÇŽMXW˜¯bÚÛ¤Œ*'þwg¶:6!±¿*ìqü¹Œ9�Zqò8ÖŸÏ¡VíUz¥¶+±¬îd fTð>³I¯³‚òðËvœ2Õ(�ë¿, o/qõ�×Ü/•Ý“˜�Ã|Q>e/;¶¾dàrUÝ$Û¢Ú/é*÷=d•î–l*ýŸ?JöºÊí^Øêdtp/ž»²'Û¢î3¸�:z…eæ6OzÝ¥™ÊÚ�ILW&ã†ãþÁL·óÒ CŽaO²(æšmâ”Eç4Ü}LÛ­rž¼]­ûV× Ëâ¶—üÍL÷Ã;Ýjo¤rºÕžgtX:ã ¶…(Cƃir]™Ü€7uèUš\ÞÎ1âNæœRÕÕÑ€è0±¬j‹B¥��ž—?» ‚ÚòÑ9�õ«Œ/is:h¨»6Lî!Ô±…iPKÆ™ÿ§¼�~«ò—Ãíöq+9Ý; ¸e&�À‚ëëζ(ÙT_œØ&–�õ�h®;µe§î+;¡¶ à3瀳œX_¨ßN âÝ}ç,q�8ñ¨sµDÍá°]¾ÿ~üßÿý_kW§Î°š 8[¥ìÌ›€y©ðnLù¸ö;“n‡U\MRùšå›\œÓÍãöÑŸx¢Æ FÕµslU™RßἸÿM®X´Å]ª1]tº±ÿòV¿¿ ïts‡qƒˆ0�Óíf•¬¸*\ VÎI�Ë¡îW˜— ç :sÕ�{y2<çÐÊX©£xoegôÕ3–Ÿ�_7(UÙÜèœçÈNV¸~]ù&l×�sXÒ}.cb·ë: †\�ne VØ7Ü‹†ª3Ôn:()Gï«Ï�;GËÕUÉxoÏìÆI :ܪœX>g#�s¨Ž¯sýÕO…ÅûJ?9-¯Êƒ²bZ?~üøýéw–§ÊZ»kçÎÖ)¹œÓ”ÆU6õŸÓPmÖÙÚ”×ʽnr– ôÕéK—fÒ¥[Ήåð¨[ÏÏÏø ³›�Håø6ÉÅaxlpeVñ\–G­Þ(9• Y±o*-åCü­ø{K¶±±±±±±±±±ñ xX¦;1ÉŠéfvue¶¥Òv§Rp8žù!��IŒ8§åÒ›Ìr1_UŽ%tñx–Šÿ1-Çæ;FœÙu–ÅÉå¶2¸vQG¯©p©ËT骕 §�,‡cÝrƒuÎíÕUqœ®– ¼Ç8Á1ÛnùPm)+ð‡-¦l¤cT£]×nK‘cèqyÚÉÁrƒ�ÏÔjÃXíß­bð¶�—킪/Åê©ü¹Ìª³<‹ªòb›Àò¹Õ\Æ~~~þ}ì ÃÉíþ+}rö‹Ë°jƒX>g‡c?-æãlA‡$ß4 ?×Q×¹<ŽYFæm ¿¥ÊÀ'Mñ8æØgÕ/ê>_w~Œ*“k?&¥]ù«­£éøÀt²¦u¹\äjùªŽ<:ÒévŠÂNi·çY)wTgô�ƒRùLeÀûnpÇÿj/(Ë� ¢ºîœ=÷ßÉ‚—Û*â™´%9ÝlÀ�QsPu’ÊØ=Cg69Ö“A'Éâ^ S駺wG'âÅ'æ…Û\9ø>¶ê6–‰ÓÃq¹ÍÕã3†Y9©ÿº~©&›Îñ”ØVáçá'Î;ª8vèú�{Æ[¸Ô¤09 ·=Ðõ+ž@Ç?/TÇ?ÛH”Íxzzz3¸ã’vz˜Ë1uü•Íïì­z�#ÕIršÒ¤‡í“+oWÂë ‰3ÁÊĆï;g˜ëÈÅç>S÷�ÓíLå3LœdŽÇ4×–�_à&�¼7ÛÙb—¶7–wõPvJ}ßão;³{o/ÙØØØØØØØØØ¸3–éN[,Ô ‘ú¶*ÂÕw÷i¿2ö1¶ßÊéRÏnu´]œ•|�^£>à'âÑá¶/N—·ªü’“Ý¥×ùÊyv“#7Y@Û‡º¡¶Â¥ñÓª~ù7ŸÙ½·—llllllllllÜÉt»—ëg@éä5;v _];¶-m/QPl}bαܓ™pbëkæÒv³HžÙòÌŸëÞ-i©³7�ü(&©c` £X},+ÞWÌž’'•C± nCµcbü9oU&Öoµ­ÁÉæäueuíÃ/öà}×ß3ÉÏ«Ã×,ƒb‚• neªcãêùõzµ[J¦§ñà=żO˜|•�’›óÆ• ,CÁõ#%7—Aõ+f’U>ÇñƒÍl2†­ó¼üøñfI›íeÅçzH@Y«-¹¸ŸvmãBï�±«îžzqŽû‚“Õ±ÖéyÁ½àÚµK·2Sÿ]¹qìz}}•+'h—QÞúU㉂³ÛS°ž¨ò9Û×ù2)Ï”–Çm=)¤í%Óý�N·rN댹#t§T¨|:ç\å«:L à ê>*“®�ÁqÇ�uËTi Åúv²ºe,ìHÉYDt¨Ê„'p|w²B·?×a2¹«ôð:9gÝ$¨òqi(¹ýúõÇ'Ý•1fù¹LI&ÎÝdk Ÿñëׯ߆ãIÊÇúɧ¡ð5§Ý•õÔI[`¿äßrÂS|•—+÷q¼ý’Þª~O1íÎù`»ÎÏP7Ô–9¥›µ¿›·'¡ÍårLHUö. î?gûÏñRëÚ¬Óç¼NËWé»­JgÏW&3©Ž;Zµe79æñ’ §4 Ä:B¸­9NÞI{s:ÉAMN²ó5”äì¯Ú^ƺÅí�2 ÁÛW»U¾Êé÷t+ãuÿj'À¿n†èŒ3ËÌåRÏ8­•Á°dVû@§/OV:êåquÏàAM•K”É`ƒŽwf¾¯&É(w%Îó8< Çy³qù&HúìÊ•&[èŒT¸——ù~ÄqøóÁ»AÛÉÈ]é ë·ÓÞoÎ,¨{™寲¹ý¸Oé7Ê�ú³Ùü¤ª”£ÒƲ+pùpòÒ½ø¬äè÷nO¯ÊÏÙ¶§›'?N÷Ñ>].—ãÇ�Çq¼Ý·Ë/†a:�sèôWR½(}TyOœ¶ÔÇ\Ý¥}ûg&qÉ–9»êðäL'G²“ç8fN·r0Ù!¯´Ø6Oû˜*“³?ª¬Î¯Jã“Ê“ÓC?Fù�/VrT|f÷ß„¿«4ˆ‡bºƒÍ³)\vèXüϘÎÎÕ~<7+œÎ$»ªdš0ŽÝvû˜;0«ì¶ó¸x¼ %!±QõY"fgÕI�åfÌÍÖ]cžœ–GÕ�jŽ;a:U90OÇð$†ÁyNY3–GÅc�÷ ã±…ª½Š}Æzu+\ž®¬xOÉ0±!¨7|Z ¾íŸê•í„Ú¶¥XjìêøG•6—9Ýç|”>ñý‚²-,§á¶ ºph�¸,üuJÔ™Õ%펵­k^Mbrᄌ>‹ÏVÆŽIÿU+˜çd\Å>–˜å©<Ö´ëG«ŒÙ¾Ïï�ð;anõÇåvõÀÕë¤Ô8˜ôÈÙXµÉìêShÓxÛ—[ÁøŠx(§Û5ºsº�r”ÁuF{¢\Nùë:íMDYù~Á9²É‰W¨rò >A§ÀÕ º­4õ¬ž§8Ýñ}.ŽÚÓË�Þ9IÝþî-”Ó]÷Òö’N‡VÐ9<êy—ǪÜÎÑç{©%GV¥Í†Üõ\ò­ÿ˜oÚwÝ9Õæ“—¡T]U9êLqì£×ëõMû±}rŽ÷1—/õ–�‚tN‘»Çpp½K àú˜J»ËS•»Ò¼^¯v?-ˆÎpÚWÞ9$nÜÁk5‰,y¸o¥I“Cçè9Ç&M&”Œê~gëÙëÚ6É1‘§sâ”ÌÊñË·8qÿWùOdÅ´œ�èâuå»u –ImÍB{àÆ'´Ó³Ó½·—llllllllllÜËtã=f�qF¥fy5›š0©˜¶û€ ‡ï^BRróï”év,³“™¤KÏ•¡fô]:¦;…e…qaܪEZÁàÓ0T{ò3ÇÂñÑ‹¼Ê�€/š$L,Ç:ãÅX×=õ5?•?§§XœÄ`ߊbݪ‘{Ãݱk\o®¿)öØ1�ŽqBÝÀ-%///oXo„cT1lm—À~Zp6Ì=ïòTu¤dâ{Ngxu*éw·*¦ìžê¿×ëõͲ5âÛ·?È�ÇbÿÀºp²¸2t mÉŒŒï*ûŸÆ 'C×]žŽy-Ù�£Q4¥?‘{²ºÑ•ϵ%�'je�Y¶ÿj<`]Å4Tþîz:†Nl_w;X/Yp|Kc‹Zbp Wõþ†SLÆéNïáîNÐP[)¥X.\rÚT’3ÝmcpJ­ÊWoóO�ÑâòrJ¾ãøw�£Kåå£]Ú)\r ”¡/™UÝ©ec·ÓKÇOvƒ§—œ %‡»‡y)}ê ¦­ú‚Ê<ÃÛ¨À;ç…û¯k>Ç}:˜¿‡pÛ¸>Ü`Ï}ŒeåSJŽãŸ£ìÜàÁí§Ò®r+½åI·Ól/µô=ðYöBšø;»ËŽzr®8~rº�ãø=ÉQº„ƒ;Ú0wÃÔIEù¸¬ÜWÔ~a—Žz¶ç8´Ž«gÜ..}Îé^ý*§Vµÿ©NtXµ±Ñ–WÛ±ž¸w5ؾ9”ì°»×¥Á¶¯•ícI¾€òÙT[ª÷³8?~/ìo:Áäï)ÉÆÆÆÆÆÆÆÆÆÆƒâ¡˜îî­í “بãÈÛKkÍá•<|É$mõëØúŽÑä²ÖµZŠu,eÊ‹g˜Ì”)Ö˜—»U™�ãÏe'ÇF°<\v,�bÔ¬ããó¤sœ·ÊãMÙ0§?*\úß=KL‡K/ývŒË™“œf‚ëY×ņ8f±˜N§/Š¥RϸO– È€q?p«2¨·Š�ž°Â.3ÝfibKº21ÜêdúÞ€cGÓÍe«’ãøóô’)»¦˜[”­ƒcõÓYñ* •g÷ŸËÀaVmAÝOL·ÊWõ¯©Nc¼4¾°lJÖ$§ó'pe˜Ëä¶š¸çt2¨ÿªœ]™”¯Òí àr8œÓvewrÇÛm_Û×)Êév×ìðvoí³‘vDgÈœ¥%é´UarJF2rª|¯¯¯qùÜ¥å:0oßqi`8ÞûÍíç>¨àò¨4�ìÊYÀ8*5(ñ¤BM”TÞ·|1�±âX;LdPÇ9uÔª Tƒžº�×n� §ÃN*žáöN'@._vôÔ6¯ãøÇÑÆ­&©8g�퇛`ð}UÇÉÑ›8S \§l¿”íúlr"�l˜öõz=.—‹”�äw‡Òv ©cËå«kLƒOF*p›§q‚ï9‡|âXuåPi±ó›úlšL%�vrºúqõ•Ê:-SÝWï $VãÈÊd!…ëì¼r’»~咞�ý¥äqí—üü€�ÓÓÙ{{ÉÆÆÆÆÆÆÆÆÆÆ�ñPLwÇþÛã˜ênf�yq|5{U³Ež®”AÍ$»Êà™?2ji¶îfþ ÇÂ;py0ü„=LLDbØÓ*2D¼„¬Òì˜n7;WËñ*NbËWêÊ¡‹‡:ƒŸ·Vqùc4*Ç´MäPá°ìcÙµ¹ê¯l7TÚ,“jKÇÕ3ÔM\:ýõKÞ�ÁéM¶Ùaš¬O˜Ã1Ýîá®î:ÛmÓp 2Ê”XOU*-ÔA'2jé[]™WÀc–[�È3a§'ì¿ê‹XG]<5Ö:¶Ö}ËÓK6¿ksgC&ãÇsåuá8~!Ö•�Ós²Nì¬w\ÚÎ~»>ß龪ûäÓp¿ÆûìSà¶�é6«¯€‡tºÝý´�á8¼c6ɇӘ:Ægºþ«m1SgÓu`Þ¿Î\u U'N¶ä€¥}é.߉QIÕµ-.Ë&ÇQ•Ÿñο3žŒnY eMËf®~UÙ&rc¾OOOqpŸè†Kƒv çœ\—xªmê¶+ÖsrÔ õq&×·]ã–WŽ®?8‡—í�BrºyƒÛšÃý#É‹÷’MD}J²«÷T\¹Y‡]ºÜ&\6<>�‰ˆé{ J‡’n2°�p[”s†8íN/:¹Uúª]TÿWuÇý¼Ëƒã¬8`“q'uçÒs6µžñ$\¥Íc桜d–�ÛŠí“k—Uÿ$!ÙQÌóï>œUòðd8½ŸóðéN·sl•s§˜Éä`8#ç”UÉÅÿÕ~'7ãsÞ+�œó‰£Íeueq�Ì•I…ÁN«Œ¾2«puWíêœnåü”ÌhS}+ùÕĆïcX%�kK.·ÛoÌᦔêj¯±J¯z<Ö)~•VÒÅÔÎJoUø®½0/ÆIû»ÕåXp5Y*–uH¥År³>¢nðÀåú9²Î!S«l;y‚èÚ–ëzbë’“ìlŸs†*mõî×Áõz•ö�nf×x/ijƒI?MN�J›mDg/»|ùšû ÚNg·ØÆV8Ô–gűårñµrîWÁi¤ô”mHvB�á}ÿ¾H­êèååE½Ë2¤ëÔ–ªîK—&þÀd¢”œnÌ;Õ;3ÝÓ×)÷žî����������;ãәµñ[ä‰�š,«¹Yšbºó®dTeHr«òªY¥còñz¬¨¼Ô>î‡O,Im¦føiæŽu¢XýŽ1V¬�+Ëí–lUúÝ,=é—ŠËzâ˜èŽéæe»”g…q+üᛩ ©þ0¾cÑT=bûðìÿüÁ [eUý¯[)ðñ¼:¢ž%v“™2§ëiµÁ¬¼:IˆÛ€ÙH<FÕßã�qýv}™mGbë9¥[Ì®£®³]PûHÙ~wL²Êwb#ÜGT&+•—c7“ÜŠå4NŸÛ]ùLÆ1ÖÕ•ú[AÇœO™U´çÊŽª#�±Np,Ù¤©Ü]8¶ËÎ7pã—ºv«·ÊFr\Në}�¯zŠÉ§;ÝG”�>7hMöÜq>ç©s˜�â±»�hê¨)eUqÔî¬îe¢T¾nʪ1t/Œ­8Ýj™¯Â$Ã÷Tç5É3ÖïÔÉåûNnÞÃ}»¬ Ø—pß�Àk0àý§Nænâ‚a«Ü ÀËíÎYP÷§Û¡ê(9åб®º� 9B\Ž´¼\÷SÝ©ð,·‘›T¢cÄK߬¯ølêtcþξ¹pÜ÷œÓÍÀíj///ö¥Ê鸓twêlwmˆÛ½êÅáIäÔqd9SŸUéL&É+GÜAÙ�«íÅá¦i»°ìtc{ñ1¿ØGÝD+Éе_£Ül;Ó»iSp|gkp‹—'À¸íë^“®�ÂÞ^²±±±±±±±±±qg<$Óí®y™Ñ1|j—äá{nææØß§›¡vGe)6cº¼4a­y¬˜ÎžÁ+6Dµ£šWYÓé!œ�:2¯ÓñCª¾»º�°Ž\*Üôe)L³òìXùºïô�uAmCÀçŒ××?¿˜¨äd¹\¹¸ï ‹êV°m]>J•\Ì®§¥ýª«ëõÙÕTVÕ±]ùÊëÚUååô›¯3ÅzÂödòò¤K[épZ]R÷±Ž\»V9p•ÇõE~‘rÂn:¤~ƒÏ“]w§\𠩬ÎÞqßAY]Ÿà|\?w«|=yé3ÉÐÅåkÎÙå‰]ïdÂ8°¹Õœ§'ý1¹iºò)9• JLwÊ‹¯Ó–ôÓÀ|©ò«žbòPN·»ÏÆÜ9KSçG¡â»�ƒ W§ j@rá\9ØÑV°sBëç™N;Üݲ“8T5O`e„±¬i@Àk5�:܃󜂗“¡œ8PwRŽØU[bÊÐ×tdœœê¿j—ÒA×çjÂÂr» ï1Tû�ãøã uw²GÊÉ™8,ˆä@©ûŒdg’sÏõ«NHöMÉQùNNŸš:B.ë5ÛT ‡Ç®” 1q¶§åàúç´ŽCoÍélRÙJU>'ÿJ»²Œ�­RyuŽ£Š3ñ0MCº<8¾’K9޵MË£èlXçx+pÊÊò(Y±ün’“®9oT\”›÷qc¨òª4Rݰ x4Så‹i¥tð¨½)ÜÀ\ò¥�}¸åɉÓíUL�OQ¨ûJö*J>îS<áKκJÛ�âkΗû ×¥srœÁïL&²uÊ�’�Ë”œ-×R]¹A;Ùçh'‡S¥­&ˆ]_ìì  Ïû¤Uy~~>~þüÙÚ|…ÎYTNÑÄÞðé%J«-Qß�­éþ3TŸg}¯{©ÍœÎý"9ÿÊNÇ{ ë&*_—O’õ‰?œãúoêìä*™ÒKù.ø¼³'ÊOP2¨ò¡NÜžnÔû¯„Ogº'Ýd€êRÌ®Mð§49œõ› ‘ƒ›]§ ‹«Ë•²:9ºˆáSTá8¿d\؈;Lê; ŒneLm,“r:YOœœ\¶Wßx�ŠzYuªOÊQôðŒd%§ªŸúïœu^.Ëàt�Ó쎴cyù:õÖU–�}»›¨ü’ó«ž©þ«:”­+ë´ÿw×.�’!õ ÕG”Žv¶³ƒ²UÊn%çF•ÁMÌTÿH619bœ>÷åd?Ô¯ ‡ÏоðxÂññ^w h¥5™ ¹ýÆ+ίúÿíÛ·ßlw¥çö¾;ßÓKmɺŸtÐù\Ž„›ÔÇa�™ŒO(;Ý__Sê����������/„Oß^‚׎eN3-Ç>1&³¢ kÝ1ƹ;¦[Í€;(&€eHqã˜ÊÇ,§šMs|UîîxÄ)S; £X*Ì£«of3ÁÏY‡Ò)õË[4&l¦“G•ÁLDb 0—AÁm὿ŠÁ`†Çµ]Õ)Ö‘ªÛÄæáRªÚÚ�ÛŸ0®ªã) {n¿éX8Ç×®Ï8f’ïsÛNû^ÇtsÚh³Ó>îé}wåPi¥wŽCŶc;yœ|'É�×N¿quŠÛHÙ¦$—ú¯ÀÛYî®]ëWQCëdKzëô{µsžÎöóu�Ëê½—´Åë¿V›Ú„ÛvÒ¯•¿£òáò%?ÈA‹ýŸÓ,°]FÖ{jŸ Ÿît»A°s~ Óå g$y°áx?9±ÊÑÆk'½4ØM$P~%·Ú³ê®�Üœn7Ð×µK�ËêÊîîŸAçxvy9�©gx?éÆAGT9èõëöm»ÿ+ÎÊÓM9>ÊÅGú9‡®òQº�ˆÓ2)ÿ«Í*/N§~'Ç 2*9˜ö•;gsâä(gÃ9".^§Ã˜ž³y\ß“#6ñ9:ª¬8Ýê^70^w.~9H?þ|“.£Úuâ(sœ[�Ê€íÇøÄ�®4YþTÖαN/¶ª{®Õ„'ÙÕ•ò©ô�SÎc¢›Ä±¬Êévc¢§íÇeêž±­Rû»Éévý*•�årÛK¾¢Ó½·—llllllllllÜÃt»k^‚¾•éVq]¸‰ Iî)CÏÌ�ccëf¦\ÇÐOØmWn…4#>Ž?™É³ m=ã%ÈÇ^8¦úìLšÓPú ˜NÕækæ^´sì!‡sÿ{¬ŽZK `ýâ²èqo f^Õs•?³¾îŸaJ\ì{ݱ�X§ê¹*¦åò®8pÉ¡SŽ,+ÏÔÑNÎ_'™8ÞWr+ÀÿÕ>nÞ•›;žëXékié:ÐT¾[ê鳩ÃÔÕ�:Â09Ý'gUnU‡ÎÐãçé²|l™z×"é7¢Ûšár ï_Ï'„¨�¬«O•W•çLc¹°-ÔD‚ïc^øßÉ�ʤÒãtÓi+ÇOå¥î¹c×:]ti§A??=�䤶prN�$¶¬sjLSaYßêWݯðîä ·}b¥Œ“³ù'zœÊ€8[÷œWš@áø[_?Å8]½¹þÏPºªl¥ów”£ÊžìQòá\ùÔD û!oŸý*øzolllllllll|1|:Ó�×j¦�Þž=ŽK‘fWyÓ­âá³î­ß Ó­XdÊÔì¯Êƒià’~bŒ'a\3#Çu?a½&¬Ë–Œ”ç”=p28}Lì6†ãSJ[?}qMáL\æe™™EQew«E•ž’©ÒrŒ4—ÇÙÇþ¹U.ç¯ÊÊý?}ˆ¯Ë^÷xëŠcÔ°ÿw«%ê>—W¡ë·¨›¨3®�9Í ™ì Ã1�.}nWd#üø1büRüN~›Ú•ÇÔõ¡«$›ê×SÖÚ½<9©+l3՗Ѿ8››甯ºæ´œd{‘úkê_�V¬s'ù>Û ÒRLwò}T:ÇñÖ¿ùªL÷§9Ý©]#©ðÇcbdUX·¬’äK§—¤A¯ñ2¶�Ïr¸òð^y5Ù¯­.˜—rÚ«�ÜÄÝ9%©/¹ºÄ²ò\7ù`¨¾—þO&ž¨¸¼x/i•Ií)M“™‰¬“8TÛ«�Ìð»CÜç&ùbœ´¯vbãñ>;Ï.^7>%=s}Ñ�'a·@9ãøn êOé™j#w _—w¥—Â(ß§œÜ3F76 <‰`Äø¼§û–>òøzÓ„����������/†Oß^âf«j9A1‰–`:3s2à9Äêwr�ä^]ncp}¹òàÌÒ•UÉëÂñ}µ„7eaßX†Ž™gy#›äSåq³k¾¯Ò`ö@1Ü\'x_m/˜°T®]Ýs8LóåååͶÇТ>¦å@dC•œêÃ4©¬,»cZPnÖ n/%»:ÅEåÏíˆåaýR vê¯\.ì„‘U}Ù1â¼ZÀ}oÂNV4\ÿ(ùVmiZ9Ž·a\.—ãz½Çñ¶/{Ü1»Êžtáβ«î¬xÌóׯ_öô Ì»c‡ÓsUÎIûª°XßΞ(6y*³“©³±«Œ³j[fºãïì7?S2ª0œ¶òcÔŠ׆g2Nó8„Pþ`­>Õ^Q{T|úö¾ÇÏVœWLgª„. ²JÙT9Ò€âŠïwJÌ`‡ sJ»m%*~gð9nrâ Ó#y²àdëätNwjWŽ‹ò¨p*æë޽â{ÊIê ÒtpVN¥2ì®.Ô22ocp:W29{œg•{2‰ÃçN7¸M”U&®õŒóNz?éç÷q+™JfÞ7�åqÏ.m”‡Ã%»šÞKH¿JÏÙK—7çƒqª‘£€q.—Ë›ø8èwm›Ê9½ß=say0ÞWúuÚçž‘‘ì‘‹«äÁöľ“âMdÇ8Üÿ•Í™¤ëÆ_ühN]—n©qãŒÎu“e[ª|+eÄx|�`;�is|O¶Ó=ÞähO�´Ë‘”Ä5®’aEîB÷2ÉJÇa9Uqþn?–«ã©W×XUV5À%ƒÞå›duŽ”r�ñsΡ’…Ãñ=®c%�ªoå¼$§»ÓoWþ¢�’ÉÅŽ­­�ƒÓfvãp¹�1VuÀ20ÃÎÆ99¶x�ÏpŸ:ï»D¤FåÃá0µŸžË®Úëeít�åpýÄ•ý8ôÊ„sR®ÿN‘Âb]b>Ê©)‹qê¥Êz‰å�|‘ð¬Ü(ÓÝd¯ìõ¤]¸~Ð(�N¡³½Ê±wýÛűõɆ­@éIº¿’Þ«û¥c�ÜÉî¤I$§¡d`ßbr4¬’Å�q«“–í+¾Lùµ¤ÝØØØØØØØØØø‚x¨í%êÏ´ –ò8‹´—¼“�\Jâ IDAT㨙ú¦[1®5ûtǪkÎÍD];u³W%ëÙ%1Ç‚'†~ÂtººKÏc¸ÂLpy”ÜŽíÁxêô�i¹8ÝtïÓíNÚHy"ˌ˪Óü;F‡e`FŽOaQyV>Ø�ŒÓ•'…å=ônÅ…Ÿ)ƶd�ØGÇê©:p« µ,?=Þ4mÂû«,æ”…EùŸŸŸ³�?þ´õ˜êØ­T8$=ïòÀ¸ÈÖc8<ͤ[�ÀxgƱ V™[~æÊ�XØd³Ýj¦y†åVi£oQ6ñõõõ÷•×ê* —Óä1�·Ùºq?•ÕùH¬3JŸ8ŽÛ^2éG�€‡z‘²s^�3àî)ãÀùqcªçInÎÛ�¿©:úê w µï’eëí._WF÷Œ¯•éœ%GºÆŽYiÕ²:†/G¦› ¨ü;Ý«ßÎ ð}·_Ðå£ÒKÿÕýäNŒ˜šd¥ ™’A½6ÉŸŒÎQzª& ©Ð6(ç,ÉQñ'Çèu“¬iÛb9}týÒÙ žLM0ÖoÕ/®-œã¢â¸~�Ž1Ûô+Üóóó›íEjL¨øéKŠF9@.ì¤LüÜýçö¶˜:V*ož|ºðgÒVaT¿McÄt‚ÀéNú[’“e˜ä‹N7Ë�Úe"àœïºæqUM”ÙQwyt>Īïó�î½½dcccccccccãÎøô)ݳ ëÝ-M—?”\ÓKðßw MbÑ&3`·ÜÂr¦ÿ“2¸_†š…»òL'« ëX8ÞNÀ:¤ØÖŽÉœê`·|[ò¨²ª�¸•ņLÙØŠïN"A¨å¿‚z!Q±ÒX>�a £˜?Ü¢RÏÝ)0ܪ…Ê»òç“B\8d—¦ö™HfœTûW8,?Ö¾T‰ù9Tåp}Ç1 NÖtü›Ã {È}Þ…QúU÷ÕV¨ËårüøñãwÚnŦûâè-XaøœÞ±ýVý_é©[!9Ã$ŸEÇþ®0÷·ÊÊmäXtǨ×VõÒvbúC¯dá8Ì,§ºì|:N�Ç*þíl'èúÞ£áÓ÷t;ã®¶o0Î(ç 9å`Ù”Ó뜒ºîŒÒÔ@áµgvj`œÓå&®|�#3 7‘5ÉÆ×j€ác³8MåHvõ˜–å&íËŽ5¶í¤¾Ü£òpeN“5�aÊ«róÞïiùØáQíZa” ×ëU:Ì]ßA¹/—‹¬7¡S§9L&0Ý=uß•AM |t£ë£É:¹œC dWõåô­Cêoì„ ¬j«Pj;œðà ¯ÆõþQê+JV…•º™8<ÉF*:§ý=l>ç§ÊÃaœÓ=M›Ñ9Ûª~nÕ[•7n39Ž|<^7Ît28]Wú�yv¾•ºf¹»ºãø(ßW9ÅäkH¹±±±±±±±±±ñ…ñáL·cM&,ó”éf¶ ü¦.§Ç³=^âU �c¹'eQ`¶�Ÿ%Ë™ÚB]#ËÑ…U,š+Ç�Èäž»3d‹íSÛ>\~\Ÿi[„c·£ÆL7ʖήÆ|“àê-½¼©XpÎG�—Ь2‰Ž�˜²3ÌÈ`[ºrt ý‰½¯tÕ©]¹cè€:ÝÙ*ŽWÀÕƒéŠâŒÜÉö©ù\Þ.7F(�át±½ÔJ€² øR%3oéãViKàj™SøÌ­T¨söÑî(œVf\Ý'9;Æ?•Kå•dÅzp_¸íÒSc{Çxsy\ùÜ*Ÿf2ñ#Rû¹>ÆíÅv^éSW�Ý}÷®”Gùlﱺr/|©=ÝŒ[+V)Ww* ;Ý'W£[Ž=TÆÄ�æÿ�ƒ©œÕÑ«S¸r¤¥ÆU:9Æ\ÊØ;Ç©ÊëÊÉÏ&†6µ­«GLÓ9…Éh£�RqU[+‡I=ãtØøaÚjOh92\ï\†Ôç�>+çÓ/‡.-—º¼J—Ôˆ�l;çt«A$}Á‘åQöĽÇzÛ ôªì ,ggû x�ù¸¹NWÓWG�\Ê'rÛiSù’/¥dO“ŒÏöü+àÓ™î®1”ázOg›eëö’'¹]>Ê@�)ƒrÆø7í“MF×9㇠;VÝ€ÆÎªì”ÌÉ!sr«¼ù^!¼‡L‚0»2WÚç ¤:`CËé)ù8mçtqºé¸Glg·—Õ± øÅ¾ºï͉>ðË2<v=ž®Oð}î¿îEQN{Â&;Âç<;çÏïMr”Û�ËÜ ˜ªÌî™KOé>×/:N>7THö¶sÊÙñ3|©ÏSONê©›\¿‡�u—VDP&tèÙ�Æ´[ÇgWŽJ;�] Ýx‹i»±�s7v¥ñ¯“1�Y,Ëqüc“­ëôxÅñgýq¶BÕ‰j«Iüä7`ZÌt×õ#~ïéÞØØØØØØØØØ¸3>õã8 Çt¯B-;%¦¢~'{#U¸Ž}áôY–[í]âràõ”P³G¼vlÆ”=š<ïfÞ®¾Ý}'ßK§a86Ú1êX¿$KÝŸ´W:‰eumÌLl'›ëFÝã6áÌS1çŽíM20xKɤN\}«~í˜.×æÈ‚–|N±fgl2;n›”[%Àën‹¦Ë6÷6«ºïú3wJOVà˜ù¤ûs¯îñêÏÊr7³úÓxTÛMlçqøc q‹¯F¬ÚùÉjVbŽÙÖ¸öDf:!Ù-–EÉu¦¿r:<ž¨ëú�ýWe'¦sãVwnõ}8=¾æ¸“ºdy’_ôˆøÔí%øËaÜÒâd+U|§�C§–XV˜ÎaUx~~~#¦ÅÁ-!Mu7ñ`¹UçPΫ+«2–ÉO& ªXF„Ú㦖Üù«u<@ò@ädìþ4i`ä#Ö’cTaœ3†y³l<ø&g¬s®p« ?SÛ"0\Õ÷ËËËx�Mz†v‡'ÎÑv}óB"`úâb‡n‚Ï[8¼zÁµkžÔ(G�ód'b21u×Ɇ%c2&p_vá8ÿJ»œne+ÔQ¥x�{¼'ކé¶.¹‰­ËÇí»çw$°ýS?p²¥ ™‹§äï&J©¯9{—ì ÷k•f—�Ë+Õ ÆqÛ~Òùê.'—µÛ^¢�Ú(Õcj?ƒ¦¶ëQðønlllllllll|q|ú‹”x¿c™ï-Wbòø¾c'ÿ§,2PÌT¢\ÝÌåWÿs?eº9ïÉj¦™Àåsòq›àÌݱ”êZ±Öª½Ý’«cõ&ÌM’ Û?­ `<ÎÓÕO×ÇpÛ€b3�¼õ%ÂúÅ—*1®K+�ÆáX¢Ž�Ie*ù¹íº£¹�Üj”Z rŒ‚ã¡nàV“§'½ÌÞõlsUæÊÂH³-Heç2rÞΨ8®¼g˜×”‡b¶“¬Évò˳˜g*›³Ë{©Æ©Î^VŸPùNÇ7%/ÞK}U=Wìm'�kËÔ'¹î&:£Ê¡ìt²}øïã—*U¹:Y;߀}·}Ê¥ÉåK¶Øµ™‹¯äã< ¿§û£óì T ×9ÝjOgR T"6èOí§ui¥œö!NŽ7tÎk‚3’JN×Q'{‚§Få~yy±{T9¾J_9�ÁKé°ÓÍù:6©L›¿Š‰§”¸|:ç>9Àjù]íÛTÆtRœg:2 ¯�C‘þ«�FMø= þMƒ‘+†K“×ÏÙΨpÜWø¬ptÈ\|®×nB òFY]œä4ás֟亴1<×�j󬓕¥rg[Ò˜†×N6nc ™qfòÂò$y•Ü©�¦Ú‰$Ÿ“a%�‰3ÌeÀ¸¸§»®A ê�a•·*«ú¿RÖtÍ2wõÊýÍ�†½½dcccccccccãÎøôí%j&Ô½°5™Á¤™NšÑ¥ÞŠ<8S+YÒÌÓAfAÍâxÆ;©.—]És³—¾º™õ*ëÍÌf’[•Á1”Ý=f™’þ¨gSü2gŠãX˜ çØOF±YÅœ liû2/(3›‰uvÛyø¿ZyQ/—b|Çð:ÆOõ_ΓóQzÀ¬ðDŸTZŽ…FÙ¸-Q¿#ËÏjéšÛrÚ?xõËžäwp«‰5saS«^JS2 xìRLwWn §V R¿)9RÞJõâò-ÛKVŸ;û_×.ï©L“¾çäá1ÖÙâé8íäHö›ý„ôÑg;:ù*m7æº8\>¿cÌUÚÊg[99è³ðiNwzv¶1n‘G¨ät»�[ ã–y0®;)C�XrKùÒ¤ÂÉÌpËScw‹�êÊÀÛx¦:²Ü îîh-üÏÛ4¸|xÍËÉnPÎæ¥dÂûîƒ#çr¹È¥{µíCɇP³KC ô%grâùšÁõ¥LNëGµãÔùTqP†4Hb8NÏå…eR§Å(»¡NÜPï8‡Y•/m‘Pm>í£X>”�‚”g¥Ãé¥ð©ñ³n{ N~ÜxÁi§É‚*—Q¥‘òFðŽ(›êS�e¨¾çÊÂáY†IŸäôø>Û�©­qm™â«ô”}u6¤ôìùùù�_©4Y ‹Ï”SëÆW®_výµ³±ßm/yTìí%wƧŸÓíž%zšÇ$œc°'LðqhŒñúúúK�f¶Ý¹“‰qD;Æ •©~Ýì:±US–�ï©2©%-%·*CDztò¨çéÔ”?‡wõ˜˜d|Æz�ì>¦ÍQçsºø‰áÔùc1®ýÓ}”‡™KüEöV1jJ6UõB22§‰)t:ïî'†áØnÇR+–Q•§â¨•%C=O/(ò*’b9ü„ÍR2!\¿pËîi;¶ ¿ÔºÂÌr¶ß®ï8ýSi«ë„Ô_ùJSÕ±ú®�ÓÁIº]fXWÒ;#Cb ™ÉW¶Eõ‰ ;îî³lÌöò ¯ªÍ‹žþc>iÜUqø×Å?Óÿ0�¯Ât¨ÓíZ]O µºŸ*¼sP�C7�¸�Ç)5Ìnù†åqxêÉÑîÏ„©Óý^Pƒ櫌Պ¡åðºúàr–sɬ:ÇQ«?8`ºÓP/µª8“U+õœz´â+ÇÖå¯Ê e«ØIåû¯¯ù}€YÒ$ªž³^$}RûÊSÝJ…zP• Óf}vúíÆ•Ê×Ùb×Þ¬n ™8IÊ)QvK•½“'íÕ_�P8y&ãAšÀ8taø¾rþ�Ã÷QNßÙÖ=Ÿ8Þì3 ½s/—s|7)ç~bÏ1Îd,Wes>‰Óï¯Âtï=ÝwƇo/™Îz>jÆ’XÅL$Ɖ1™ù+FNå…2tLBbº§,qw?…›°Þi JÁ•©€,WÇÈ2óÖ±¯ŠÁVy%&ϱ:iŸ$/‘1cå˜JË©êEs–˜0†ÚW«Ø•žc³Ü±jÌ$ᶬo>*Ï1÷ê—óU:¢X"ÅŽbx÷‘)L›—±ÝVÜžX!÷ŸåámŽe-õ{¾§ê1±ñªŽ;{ëVrØf8]Ví§äq`}vìvßélÍdÜJåã|ñ>2¥Io]n�c¿“=è®]ºuŸõC¥ÿô”¿òšä :Uò ½­-&Çñö¶·é¾Ê»ò™œ€åî�õóRuL÷´?ŸúEʤü‘¯2��BT‡S ê @…w w÷"Ž*Cr\8üT)Ï*kçøMÓLް{æ\•¯«¯äLó ‰“r¸ä’3Ä÷�²Þ¨3®U>XGj‰˜¿@É{Ù1>;‘G[•‘ãL¿Rèœ NÏ ~�S£ädyR8L�W§õ¿;fO•ÇémJ§®ñhÁ²U®¾Y6Ôïξ•Î9{ÖÞ`Zêe\Dõ•n²€i­ÊÕõÖ[gÃÕ}øß‘3˜ÿœ¾Û …:ܽЯîMíÂtìëò›È‘Ê Û$C»œL)üd,N>Äóóóq½^c>*�³¹Jîät«1�åJàtÒ„à‘°·—llllllllllÜŸ¶½¤›¹p Ån®ÌpÔl)ɳ’—{ኞ©M˜nWWõ汫»÷b¾ ŽIJÿùþdví–A;¨:vŒ³º®Ì`¥ÓOÒj ¶†ÃÿŽéJì!³`|d\Ç*ì̲ªbå�EG™ê³:N•�YËÄR©ÿ)\ª+,.óª¼\�IF]êú,–ubCQN¯ðŠ ¶Ë¤ÿM_VåzœØtÅÔrPvŽ3I··_·¥D�-“þ›är¶)±À¼�Äm…Â8)=5¶89ÕýTGS(›Ëõ�ôÎéª{–äwãÉÊ*æÃL7žd¢Òà1-µmbªR8.¯k³©½dçñ©ÛKŽ£wW ¤KÛ=O�{".óñ}µÄÊi aVޱÔº2©´+Ý®c)§dª¼+†V-©N œË“ïu†Cåëâ¨Sº“Ôd¡›ä¤åRÔ3•';‚ê>—½«'‹ºŸœÙÎiåpøE5î_Î6°óŽy¨“D* ¦ŸôŒ·”©÷+”㙎[S@ÝÂòp�pU÷]¿AYq8þ^.—ßûCQU–év ÷µ¼©Sáú+·1N غÉçWqÒ‰ÎÙoìç\~¶ |aê r»%=Æûˆ]›ÈÁýÚ9ˆ“´»ÉŠj‹$›¯8ŒB²ÅJ^΃m•?•l|šÉqüÙÎþ 0Ê5±¿*†QºâxNÃÝSýMõ½GÃcJµ±±±±±±±±±ñá!O/éf뫌7çÓͺ”±G.ÙªnLri'ýQð0{º]åuP‡2¤cÅi rM7x¢sÆŽ±{yÒ-=*™QîÎØ¦{j tNÝ*:ÞuÐÕ’öÙA[¥Ã÷RøãÐûE“xF¶dÈÙqT{øT¾ìˆ`¸Îy�\%ïĘbšI×¹,,Ê:©~ÑÈõ¼NÇâ/ëç«êÕÕ —ƒÛnªki’�å«/Ú½¾þû‚eÕiWß\v'ƒ*wªW–¹+£û‚kšGvhU� �Ÿ¶‰JSÝsÛex+�s¬___ÿ˜©>’œÃÉÄAa:¶8¹§yrÿRöõ¶'SÚê™ 7™0ªtÔ³$›:>Ð}I¶þ×=·5�1 —ã3¾Å$½Gsº÷ö’����������;ãaŽ ¬ç*ÜÙÐÊRL—§c°j®f׉õ^™éb\üUr­°(g–'åqÿ™ÅqoÖw,C’ŸMÊ— ÷""·sz¡EéXwê2ŽQcFÙLfq]_Xaµùš�Ct/¾ªk¥Ó(NÏ}°‚ÙMuŸŸ9¬öž²±ê…K–�uK-';–Øl.«cò u²ŽÒI'O¥åXT.·JcÚæ�mpicZ.O7Ž©²M™· “‹qÕ–îsªÏ3Ó�õµ²š t-1ô+˜¬Êœ•Gåãô%É5Íw:.%;ÌáS{±Q×5uö�Ó^ñO˜Õï˜iuzЪ§Ò~$|ˆÓ=)t2d.�®1Tzî,ÍÊÒPÎ wË]IÙðz¢l\•¦qÆY®xXÖ[˜å:ã컳F±|É)Mi»ö›êŸJÀG/¡ð—û¨X'f 4J__ý—/ii×9îª\x÷»8<ˆ»#'ï¨pþ©ª.¦Ž §—¶¾ ò)<†í£rüœÞ©qoâÔ°N§¶Ä{Ê©)ý[q°ùrJ�­pc~Êk’§Ë«“gŠé¸<•‰Ótú}v wNwú‚¬z/@µ‰ó—&¶0Åá|Rº�_õhØÛK6666666666îŒO;½dÊ$w˜Îþ¦K"j––y\>Èö¤.—cÕ±Ó, ¿Œ©ä9‹ÕÕ…I“ðÜ•¯{á/¥1aq’ÌnéO�Ð4KO2'¹ù¬pd½˜åF6 ™\~‘†0ոŹTÈò»ò8…ÓÃSX\ýps}V1Žné“eR2²>òг‰¿ÒE[á®ÒÖüÅ:I+FÌ‚bL ?ÞÄõêØÞtj×ObH»0)mþŸ¾XYù¹1IõY–“ÿ³ž&9U~%çÔæ«�Zaû+¦{Âz¯Œ½»Ù�©je©“U±Ä¥›ïÉ‚rþ“´ÝŠÈ´LÓågJÔ™ÿiåÄé®[ â_wÍùLõ«³óu}«/ô^øÔÓK¦ àð^Ë<œýŸ.cb¥¬Éé>Ž?—'§–`Zîíõ3J› Ád²1Ejën‰tšçĨ¹�æ¬òÞ\eøÑ9›~: 4ÊÙ;Ž?÷Ã???Û“_ÐÉÂçÝ (\6Î7 ˜¼dï&ÆX&U•'Cé­ZÚW'Yà¤�ÛèõõõÍçÝ]ž(·Ó5N;íÝg8'®›´Ož)§›í¨¨®QnÐQ± J†‰3;±;É‘qúÉu� çŒÔ3W�In¶ùgÒP?œè¥c]yÒ½4©@tNWÁ}D+ÙïÔæïáp»òsÙ;�Hé%Y]yºúVcƒòuêo“œ”Å�õët8Ù×ÿSÿèÒý,ìí%wƇ¾HÙÍ8Ò é–|§axæ5™}º™7/©ñR¿z)åé Xî[Ù[‡n¡ê1±3® ÝÒçêêHÂt *±›x�Y&õRœzùo•©d.f‚Ù:d·\}ªgŽYÂ<Ï0*�T6•Þ*krúÃ.õ‹mTõÈuÆ[3œÍà“Z&ì?‚uFɫʦ˜M%Ÿëž;ýBå‹/_¥Sj�Es2LðÎV«úæ°N×1~ɬL•§ Ç,ÜdiåcR>¼J�Œ6懫5É R87~»pÞ±Â�ÝXÅ™±b26°ü¯•þt+I禲:äS…0µ-N¥�ý_Ùb•¶Òç)k�iMYô÷Ô¡[ðáÛK¦Ë%i�8%oRÙÜ€�í±SãÊäŽ{Béò­kuƒ’Áʤ-’£½b8]–�—âØ@©ÁÐóŠŸîSç„ï¡ÜîÃ)jBvÿ~%lE_ùÿóó³ÜßÍò`>lÕi*ÞçÓ+\� œ>²^àoÒ¹d7œ3å&@<ˆÇ¿N"ïãîòà´U«¶À<]{W\7Øp[º99;¦êã׳ëõúæyMXÔ6”U�¦Qu0ù²bªÿ®�ªgüje•ÁÙ1'ÓÄ1Ÿ¦Uò­œ$~§× IDATTõ«ôŽ÷Ö¿‡�Ÿ”Á=Sc|71�:Q]]ÝZ¾iÞ WÿiÜš”%Õ‹²ê˜b5p¸4™J~ŽwÎn¥qCåÙ•õ‘ðé_¤¼g‡èœ3^=Cc—Àç£R³¡uG )y“œÉX�A×i'†zÚÜdê8ÛÑ�<®ÝøY×�C°Z§ÕÎ�Rz’&]J&Ôo·WóæI¡›Èpy»Á/µ¥rÔ]ÚØ_ð9³­˜¯c­“Þ°Ó­êñ8üþü ¦6‡õeÀûÝ1s˜÷±t4˦pÕ^¬#8€òäE½TËò$½w{ÿWÆÖG§û.¢cþ'N·Ó[çÆG7 ãöGùåIžÔL&# <�uÏÒ€á;»“dK“®ÉX>Í'…í&Ê]ÚÉ7Hí¯þs8ÔAu~>æë¾=¡äpPz>�|ª1Ä¥ÑåóØ{º7666666666ÚÓ­â(Lf�ƒ¾.™dxx†é«í!2KulF‡Ä¾T:“4ϰénVÊi2ÛçòKLù”ÝÆ°îx´*¯bÜGó“òà•“‚Ò5–G1|˜¶bÞUXž¤ƒ®Ý¦K…‰mÅzÀýëÌ b[bZ\—vÇ*ù'åKá³Tep «»_õá˜n×nü?m/Q,êõz}SwØ&¼‡YÉ®tGõ� [­â8öžËÆqÔX�+ *�n)�YWÇÊ©¾æX=מx�cn¥ap'{œpvU‚å~�<™íN,êJ¾ªî][®Ú g'r¸0¨ƒ®O¨Õ¨•1Äé¨ ‡ÿWWRÚ�†Oß^R˜,5¬Vdj”ºž.U&™Ò>îúåó¸»/=9y1½NÖ3†ŠÓI¼Ë_Ýwmœ–�\tNÚŠ±dè¶€¬8�l41 u¿ò™´?ꀸ�ã­#¤.å¤ò¦Åí_OP†ßå¥^Òsל^šD8›¢ôÞ9á]|þÏõ›œ@§3ü ÃO¬èœMœl£_¿~ýþÚ©zEí+g‡|jù¹šh1&_¡ä´ÓÀÏåêœx¾¯œ½©l)œªC÷uQ—>Û­)*ìÊVv0'N÷ªcÅeYñ)\¿LýÃÉé&0�¢Æ —®û_¿Îáe™œÀùªÿê~ç€w2¸±*Ý$|o/ÙØØØØØØØØØ¸3>t{Éê³gØÖÄF¯À±‰jy›g’g^䘲ÄiFÎùpœ[sU×,Wгòñf:vL±‚c*OZ%(V™²§§Žû+–¡¶�ðÖŠž²�Œ%–éÛ·ood@F%½„¨î'ÆF1:øL½PœXs΃™îîTfûx û2®zà3þÀ‹oWêô‘ˇàúI/'¢sY»—*UzjK‘jsUǸu�_ªtÇ.ª¯Vv'™LmKz¦˜E ïŽDsÇ#:]MR« *\÷yÇÐ"X&W†„)CßµU²�I>—Ç™ñ+­‚q>i% ­"¸|ù¥iN«®•n¤U0~ÎvõFÅQ+%j|Ÿúe�NÒä{�†OÛ^✠ú휵IÚ.�‰rpzi™G ÀÊÉÆÿ«F!9Ý Ó´Ýý•�kÒf\†UcêÒæ6rŽÛ{wF§«jàÀk%O}îχv* ˆ2¸¯Î¥ÉM7¸`zn[§Ÿœ#î+ù¸´ªîÔ€…Î&Ÿ}í&W|7OD&Ç#ªÿ,Û¤Þ1?•†å£ ÝÙÕGTZ.Ÿ©†qÐé®öAÇÛÕ©“‰÷¶cã~˜tß9¢i2¤Ú’�ïT—ª¿ÕµsDÏØ|nW×÷Ý—''�¸²ñ5;¯)ËÒµ›’'ùI¾ºïƉäIÛŒ•|W&j¶¨fÉ.=çQ°2cMq³á˜ô…-·ÜVá0Î-KšYGL›™Ifk1mduy[–Y]Ö'µôݕѱºÌ ³ÞvìÖÕóóó–ˆÙ fQUIË¥ÜûËu\ÏÔÛR^¦äì¶«0 ‹u¤¶}”lÜžg˜SW¾Ž©¬ëÚÆÄ'Ì\.—7_E,”þ¸¶Pgø3ˈõ¥ê^Õ�O.,dŠÙn÷Áì¯W·Ôi1«‡uÃ[¤:{ÅaÜi&l'è˜hÕ'Ô=§äYÑå ãÚ=[ÜsÅt§¼qK ËO¥5]y™œ×îôiÂR»|ñ:� _ýïü¥GÀ§îéž’edSþ+†c¢.;®¬“Άi° ·–eU…ä'G4ÅIƒ¤È”¡9ãø+™º%M×?´ù~éM9œ•ÞOû¸•aæãñعg§fÒ/Ù¡Ä2ñ~h”Á9,jà­ýËÉPc>ÎЪ2°Ž±ÃÂH_W¬{O¥—&œN×XïYnµ¯¸³É)Uq¦6–Ó©ë:%‡·IÕ3,×õÔ)SùrØÉ�ÊÊúÍí¢NiA(½íƱÎ�p:¼â$¥I¡’mâütò¯nqrÏUÚN6¿ 7 “t+õéïã¶µ%y\8çðºqUéSÒUõÅœø8.m%Ã->Î{âaŽ DL {¶«dVH4*]'Pƒ©SÜãè� ìÊ d�`ªä*|b…Î䉨ºvõÅàýµ,ã Ò7Ñ™©‘ưìhóþU¼ÆÁw|qÌ———7N·zA­òW(çÃŽ„Ò‰ä¨qÚ(‹è'NrÁ±ÞìàcÝc8ž` ,ª ü›Ž#TeS×În`Ø4ˆ¤A—ËÐ9ôÓßÉÖ…g‡W1T�°�¨2(ÆY Ôi’ãîq{¸úWvIõ+·ÂpM�n¼ÆÕ-œäLœ3å(ºWÏ8¥Î¶s¹“< ©]&ŽžK㬤³âp§qd¥�:¹Ó$ï¡íì^¤Á±‚Ûß]OføÌ(pÔò´ªÓËåß.ÊÛ4�ѽ±Jîª+ÅóÊ—Ÿ«|Xvfº;öb\ÅvsùRß›l]`6e(ö‡óáãÚººrL�“™Ë79©#±‚ø¡¤Ô.+ìÊ‹rºã2™is,¸êSŠt}�åžØ�dÓÜŠ׫ʟ÷¯³nMÆ7µ¥¤î³|Ó>‡ t÷.’‚c0¹�œís÷T'˪?Ñ¥•Æ/•oj¿´ª“V'T=žµ£«c3Ý.½U9ðZõÅ.Ý4þ>"Æéf¬:SÇ‘—R¦Ë]¾IÑ•£]÷§gs;ÇÁ幂÷TÄd€±¾�36]ú)#”œN'9ðêw_¥? 7I»{q±œn• äèt»²sò±m¨·©<“>á&L©~Y7œÓîöm'}â=³…Î1žô?î¯<àvëïÔç>†NÒ¤o±áœ"WÖ)”œ¸ÊMþø³éè�»:eÙ&g’¯lŸPN–§î£LÕÏ8†Ç­‡¼Õ‹Ë§&übïäÈ@5VºpjB Ê‘Ve“º—�Ýýä,b˜[Æ;Ž?Õ}çœ;Û‘®WœMγsŒ•]ŸÖ«“!Ýëäïü§'§}E¦�ÀÞ^²±±±±±±±±±qg<ü)Wf+¶›¹�a6s X*wÍy§™âDî3³Ê)º÷*›¬X|UV÷"GA½(8-ßÊjÁ”¥pl{ª•6ßC O2)6 ™îU–ˆHf•|Î1Úœ³í“6s'ž¤~åXyÇ”2Ø}PIé'¦Ím™^Òä:âr«òpfí]8LÏé4ÛJÕÇÒµƒ²{XߥøòR+j êO:/Õ÷Ì1‰Ì8»ôxņ¯QßSžO½<‰Ì´ÒïÄ,;{Žñy«‰¿Rçþçò»Îtis»®ŒÅJ†ôÜ�Y»¶Ra¹½Òj^OOCRà2&_b…aÇ4;¶�ý‡~Ý‚‡Ù^r–þÇŠœ*)")Rr*U8t’P�º­%Nù]˜)nuè'éaÕùSGš ~]GOΫJ'åáâ*ãÙé+;˜ÎAíœ<Ô!vVÔÇS=ám˜7Á±;w˜÷àr™PNt08,Þc§[õ+5¸«¶LzÆeRñ»(ÜD„¬ät;Y“þ£>¨ûªnT]°ít}6õe•Ÿ’�BvîQ/Òé3ª¾UK}aºÝÏ•áòt_1UŽž]~½^�ãxëärwû¸1íÎÉU˜Ø­©.LÄÎwÏÜ$Óîá”Vç´u¯KßåÃõ–&9]Yœ]èÒq圤áÊÊiLÛ Ó`Îú”÷ÆÞ^²±±±±±±±±±qg< Ó}=S¢Ð1Ôü¿›AM—735eáRþ+³½é,•eMa““¡L.ߎiWi8ÖÊ1“ŠEžB19ޱVá«0)ÃqdFì8þa³®×ëxK�ºFÏK®pøËË×U† ÓÍl&¦…¬>¦Å+H*ŽÓþß½hèØm×F®û0 §—dp aÙMŽ[÷•ªëÄ:ªíJF‡¤w,¿Š[í^qT¿TéNVÆVÙ°Ž‘�ØA¬ÇççgÛføuJ–Ót[EÒö)wíòRåà“zœn¸±�ó�¬þ¼'¦ì)cêC¤±ÂÉàV™ø ”ɯÁ´ÒŠV*Oç­´Qg»* ûΞ£ž¸þ;¹~|øgà'÷>JµÜæœÂÉÒ;«K˜ÉMÎÏj· 9¢®c(C ~ÊóÀÁé¨eÃÉd…ã¯>K²táR8½{}}•N–‚’ƒ÷cÕW1¾úÈ {†i»ý¬jpwƒ€ê{5À¥>:é?ìЫ:®z©pi�³ûP‡Uà¯Iº¸jr§s8gÏÕqšHv}¶+g*?ê:‹ÕÖè|¸“?0ÿtœY‚ÓÛIü´�;}è&}r[}]´ê ú`·�¯§N·²íʹSHN·Ó[Ž3³Òøy«2`ÄtLrýUÅUÑ.§�Ϋ4;?îlšØo*Ç#`o/ÙØØØØØØØØØ¸3j{‰Cš½Ü2ÃCtŒgZšAFƱpÙx‰%ÉÅŒå„qXa[UÞi¶>e†ø™û(§Ý1ŠÝ[‰£žMX�ô,±°‰ÃgÈn#ËåØ�¤«øåQ§TîÜ`¬Ç1jé…ËJÓÃk|¦V���Ç{•¯Zªd¦O�ÁðŠA�°9Ž©N,£ëû¬i{ˆméäuårvŒå]a©¸n+nÍIö*õ#UgÉ>NítZM˜ÈÂÿùãJ�¬éÌq÷²s¥=y™×!ÙNg—Õ¦úâTžÉøv/Ü’ïdçç+ã£êol¿�<*^ ÛÉíâ¤q�ós}~ºš²âw|&îît¯TDç@OÌJC²éà§ÒÃç.må€OÑí„é2ØåëÚe¥§aØQ›ãœ©–Í-ߥÜíéÅgõ¿ÀÇ…¡~¢£íöSN ›’[9Ö•¾ûBžÚŸ]u¥NPàüxO5n%ÀûìdãщêX5U¶n@ç¶bç‡í„›äp¾X�ˆ‰-t“EçÄ8YU~///r¿p’1Ù4n³nRÉpuWýW9©¨[�£Ÿl¢»‡qÒ:•Ã…Uú¨¶}á–Œ«Úý8²#ëtƒÁ㘃’©â¸øh¦NØ R¾|ÿÌ8Õå=©SÏÅÁ0Ø÷x{Ÿ³É(¹Wêàl}­NòRrý²³�‚O?§[…™ïiÅv³õ.N§0j·:ëX¨$Ÿ’w%|vRÆÎ¨¤¸)ÎÊ1Š+éºÿ«�09V˜Vvž&áø%ÁÊïååE:„Ìþ:“Û79�˜§sÌØⲩô”‘T=× ÷)wd ÓtDxß¶ËëÛ·o¿�kÃ2¨ÿÎÉåvp΢KŸ§AÛ9S,£r¼Q®Ê/å£t•Û|2àu}eç/Rº "—AMŒVäHÎ;†qõíVœ=©‰':¥Ê6ò*§}«Ó�0�ü©ºS_}}/y’]Æç©uy¼'R=vùUßëÆ¥ ›ì_¯8ÄS;ÁÏRš˜¶J#�[),§õ(ŽøÞÓ½±±±±±±±±±qg|‰=݈4Û*$†je¶ã˜ÜÄð 9‘IÍî:91¨gÙu\2Té­®npÚ·.Ar½(6ò ¦,™Ú²¡Úìr¹üÁ,#ë…_åãôU¾Že`æ=éçËË‹d–1×ãDª]Ãâú‘;ˆÓbMµUÇ TÚÈx×3þÂ$æËyò›³,—ªc¥ÛJ§Ó=Ǩvò8öÈÙÁ$“êŸxíX+Þû�a\ŸŸØ#¬g?&iLØr–õF½CÁ+ h¹ýÏ2Én%fuÜàzSì¹Én¨û©<ÍÛrU?ê—mî­cø„éîlèä¾Ë£Ó³UòžþÍ=ñ0N÷™JzG��Á-K.|=]Va¬¦'\)¦s„ª ÎÁHiw÷ÙÃ4»x Õ9ïáÌ»ÎÎûÑ‘T×Ußøy÷©n)GDMôºzäA'OOOoþ£œ˜;“Á< :¸�—XÙ0óŽîË— ˜¿¼Við —®/ð3ÕFÜV¼L[÷Ñ[�z·€óÁûê™ê—ì,¦¾Ÿú^ê�ªÿrÿâIi7ð&{{Ö1šŽNO\=ª ÝÄ^²n:›íÊÊ:ˆ²òu²í� ·Úâédj%½ô1Û¹¬Î÷pi+y¦ßètÿl½�­ónÌú´’ÇWq¶ {{ÉÆÆÆÆÆÆÆÆÆÆ�ñ0L7‚™×3Œ•ÃJ|Ç´¸eœ‰vL·Š¿‚)ݱŒ¬Ój‚¡Âá}þh;Äœ^7qLÿU»¸/ r^® Éùa]àcêº>Ï×êc`JN÷|Ũ°uÂMç@wy8]@Ýrú�ÊÄéMÛ…O@êöõOõÑÉ5 £dSr¦>Í“s' —ƒõèVk¢3+“ω®NmÊYßã&ÝçüÎæ�é$G{Å×û Ž6âK9Ý…‰bŸ18l°&3<œÓìÕ9«ƒéj¹Ôµ{†uà˜¶./7;îVg¼&†çVéòUñ”sˆŽ5ÞcÝP2àW'ùyçð`;©zP_�Ti§�ã0ÛËŸj¯—kQáJ¦bä9^åãöµ¾¼¼üNÛɪ&à ÊUeÅ4ø] ÖãÔ^Ü.Ù{e�\ùUZÉQPñùìkOåÃ2$§«K;ÙN‡«:¸âÓéýd‚Àu¿jk’SÉår,1ç™Úžï«ÿg ìz];Ý/tÎ÷ÔI] 3Ic5�i½&Ûr&OnÛÕ~ŽaUzݵjó•±�û[çC¤°«Ï>{O÷ÆÆÆÆÆÆÆÆÆÆ�ñáL÷G.MY† �ÇrñWÝlï,²žÅÊ,óž°íÝìy"w'Û´ìïµ”8M³«WÕæŠÙÄ£ µGø8Þn)I,,Ÿ<Ñ1¬,·iÇøb¾Ì:«ðÈT???ÿ>ñWÓ�l²ªÓú@²úJVµú NêHåå>àÚ–u?­Ú¨Õw�ñtmÄm¬¶óteEyTÚuÊT;ÆÛ±úi…¥«S~†rÖªÎê‘­./®S Ã'ò¸´[Ǻ öçNÆ0NïÞ8³¢¢â«ç©/'Lêh•Q_W�<É7pé»>:�? ŸlÇq>ƒkË´ÂÃ}~ÚænŒægù>Ÿ¶½äÌ’ƒŠ7í@êZ9žnù.-{Lœn×§MJãž5Îg,¥•Ê—œ 'Ãjþ*ß.þÏåéY÷ÿ8þu¸Ý’ÎyM˘ÜFêhAÞ²�à½Ù“zN}�KûxÆ5;BüuIw�yâ$ë;‡÷\¿VeQ]…QÛ_Ò1š©¾0þtpHiLœFÒ­®/V¿îœJ—ßD®édé8þ¬G>{Üå‘lþçsÓ„®«w–ÕÕ·ÚÞ×ÕÍ=�o5qt(Dçx¯ÊàÒ]�ßa꣤±wÕÇ鯭‰ƒy¦Ÿ¥6b{r¦ýº1¶s ”=ü¨Éç-ØÛK66666666663Ý+ÌéÓ™^ZšÃ2¸½¤[Öé–\ÔÌñ£gaFö8z&P¥y†�NÌAÇŽ¸4o¿„8e®ÒÊÇq°Ü˜6ÿåбÞõYfֹͻÓ˜Áâ|‘]åxÈTÿþýw8f qË�;É„Ë]ÛUžžžÞ¼TÉ2tm©â¸¶`[ÐoÈõÄeW[cxn»ƒksî‹N·ÜuZeRÿ9~‡‰=ÀöV ý”¥LõP¿©_qxggù„'7ök~©vÂ6®Úè)ØÖájPǼŸY˜„›²è“4¦mº‚I|Ô‡nåÅéÛµýÄ6VÚ<ÖMÇðîžòO&¾Ô*�ÿÔÓKÎVædÙa’¶2"jðc§•|2Ð×3µÕ@98¨l�‚¯,ùL:Ì{ê$KçTrx—Î4}—rêK‘œnúü5žÅÍòá— UO� v(W=CÝ8ãäLœîµ÷ºþW=\.—7[Cp ~ªÝõ�rÑñUŸ/ï%»ú{A}u²Òî¶µTiå°j°L“@×wXŸØ1í ÚûŒMèÊ»š·3_‡ï¿�N¨þÒ9 ˜¶;ŸóEÇHM˜+t´“ÓíìÓª=é ê1M:`87&N0ž°Nì§Ãm>™Ì¸²¨ÿ·ÂõE7É­òLt>µ�Ÿ¦7×ï¤î8׿)ÎWÀÞ^²±±±±±±±±±qg|(Ó=�±Lg‹ÝÌ«›ól*½•–X&Ì;畘”nIêÌl:Í4§çqwL¾‚›A§´óŸòt¬�’!åë¶àµkÿççç?N½)Ô×&•Œ“~¡fþŠ©pl_…Q †b¹ÝŠþÇòàÇqp ^—lîËœ ªO:6’ÛE1“ü%·ÄsY1=üR Ê“Ùº¤ÓÜ~ŠYš2x,禛ÿ«:Qá&+"+«/N¾Ô×Õ5N¨>çúDýŸÚ¾•ÕN—uO9rŒ¿“g¥®SZéË®Ý`]w}t"[7n$»íÒä4\˜Õ1Òåé|‘NždCØfœéë jìSÏœ^¤p+m¾¶Kû³ñ¥>ŽÓU>Ã�^Õœ®‰<�Ñïdš¤æÙ´~ºA[•Í Œ©ÓNô÷îLÝ—»Fyð¨<.š*=¾—žaÚj›…›8ð@ÀqøÚ{%Oå©ê ·“ðqœø åF`ù~œåœL^ºÓ!Ô䦠NZQo41§‡jKBçøã„£dLñùª¯dß”ã]é!\ìlNÀ“!Ö“ÎñëL×W'öVÝWý퇪{g'¸¾§ö]ÝK_uN·’gÅnŸµñ«ù¼Wz«ýÙÉ�#YÏ“=I6¿“¿ó¿T?êÒž8õï1q|$ìí%wƇ3ÝÝ LauÆ3IÓÅð›[Ì&2¤Ùïj¹VÒŸ2P)nb0:f*¥½RS&âÌÊBbx±ýë…@f…~ýúõûåÉN¾ãøwkAW&®[–9�f‚y&æ•ﳬŽñd ›Í ÂUÎwÂÈb8õÉ{%÷ÓÓ“Ý^âØvÅF«^I,7Ëàâa>Åz*¶KAõÁÎ^u¶61›]_^e«U=0‹–V‡ª¾pëSê_N&vî8tÝNÇ.¥“|š–c:Ý‹½Še^e49Ì™³þ“ýu:q ÛÍñSÚ++7Ó~çäJ+)NV·j‘V°ýÜj�Ë#ÉS骶™ŽÓ¼'ã ‹÷èø§{ÕØ:p£§AóU ïdt‹óLÆ^ÅùHLòMu•ÒMvtWßïa\•Ѽ¥Ž§‘ú¹\ìQr///£Á¾Ë‹eä0¾SÉ“òqÎ?l2) IDAT‹�R|õL9Ú¸%M9Ý(ê·³Ã�==ýÞÃ­ŽºS'q$Ö Íérg:rŽOqË“ŽÁrìîÛærp»"‹v½^ß|8ÇíÏVyªrW\–Õéq•™EUÖŽB[�¶%–)}ð‡ãÔ}חݪo³Hû»Ó‰×êk£*>§ãòKìX§ Ëhry¸>1µ·ÌÞ»´k\×¼õH�ã¨>¯ôÄ•3Ù_ÖÑ ãØö·Œ‡ª�ÜïÁ€ª>–lÓ¤LJîÔ'éqZ¨ãNŸ\yS>µi+eàpª-SÿséMï>tO÷{„;SyjùEåé–\”!땉1ŸÊîÒDtõâ:œÊc²Ü¤Ò»u¹h*Ã-˜8�õë–¯ØáfGÄ¥=1Úiàp†ˆÛ�a0�ÞÞ2–,“—ôPn>NPÕ÷Êç¯ybƒeruÅKøøLɯž»—A1çã2~ V9ÝUž4i¼U¹x¢„ñ';Ýgú¬Óï©#ÍiMÀG ª>Ç`Ýv¶Ž'•¹ªN•ó¢&�êÞWN¿ê©Œ,¿³iéÊgÒ¾,ë½Æ'sWV‡•~ÐÕƒò!&v�Ÿ«þßÙ·é$ÓUåYõKœ<ÓôÎæõ‘ØÛK6666666666‘rºæSÉTáœ<Ž®p�Íef[•§Ð�¶“Ê ¶i¹zr ½[ º*Ÿ3mÞåqfÅ„óéXè¹§i;$8G'¶.­þ¤|“NŸ)ë„ÕŸ®,|¤?ÖáaœîÉ 2u°T·\Êy¸´¹“¹}{o5^�²ºdƒ÷»¸Î‘˜,‘�™¨¼GNi¦¥fls<­„>·äëòuúÈ÷ðYw ”j·¤›ÝùÝÝÒ®r¬°ŽÒ1Š*÷yö’§[epYÃbZ¼lÞ D ¼G:-û»ô°¾Qî4ð°œg&¶ÆÉçmud ÚÂtÆùYq¾ØnuyqÛói&J®7©Pm¤ÒæûJ'»8X–©óä œ,ÕÏÚÞÎiraÞÓ™b{rÓx™&üÉŽeK}Y…W÷øKÁ“üÓØçÒXѧäGLœóGÂÞ^²±±±±±±±±±qg|ê‹”g—soY†tÌKb ë�2¸8·Î¨ïÅè¾Gz+iß’÷GÌ^•>áu�/�aÓW 1ÝŽéR¬°jL+�'�q0\•ã¹'ºËrs}©¾Å/±Çq|ÿþý�ôø£ SÆG}´®‘�äs�ë“Ê_²œégie Ûë4É8YiâÿJ”LNFþ ÊÝ�d’Ê¢X6–myj3~¦VÜê�²ù†u¡“[±Ün A{“ú=§Wà$„[½KL7ÊÖÉ1 wf,Ÿ¤‡×jEdŠÉJÕ ¾N_µ© ì%?ŸÈæ˜e·â6±�³íü‘x˜í%Œ[+m¢ÔÊј83ÎéæÁ}EV–g‡¡Œ.?çø+ƒ×D†îÙ ÜòqÊ£3NiyJ]???ÿGÃÔéœsΓœJ7¸�\yÕçàÓ§ª1µ} õ›?=�Î;äèt#p_-§ç޹JûXy¿ºûò%¦­ •¯Ë˵’Ü'±.œ#Ìò$}Röˆ�EçTªø�®²ÓÍ“Bå ª2(Çewù'¹TùT~ÇqØýÝl x"©&˜ì@»¶T²w[ӦޔÃ&“”á̧Þ'áSG½ò�ÆÃðJoS^X�z¦:ç¾ÒueÇ{�Ý`¨:˜ô¼Ne]ÚN¾îz‚GqÄ÷ö’����������;ãa™î{a:íïÉŒ‹�÷ZBšÊ{vV˜¦)C»š/Ï€'ìb9R=N™nÜR‚qj©—óIKl‰Iàr¸­¼$îôJ1m///ãÓ&XÎJçùùYn(fÛ±#Ìt#K¬V‰�±æ¥quŠ ÇQi#›Wr`;*8ÝK/¡âµb�Yž*ʪôF¥íX8\¥pr¬YÅWŸ"G9XÇø¤•ôR¥ËWɈñ¸î©ï©ôñy}Ðêr¹X6›Û\­©íJª];fZë9=Oºã>¼¤Òp/5;¬Øyw?�£«cbjoüß…SiÞ“1uee¿£w:âÒ_}Ö¡äìdXñ_’<ŸÝ~|Ú)Óó.ÜÊò“ú?u‚]j ™¤wKcŸIû=m7X¤r'ÚÉÜÉ—ÒrKXݬœnt0ÙIHèêàÃ2ÕÝä~wž;u'9’ÿÏÞ·µ7®ó¼:ÓÌþÿ¿÷›v²/Þ‡³P)§YMg 7ql¨EB²ŒÎ‡ÚBR{ÞS}Ç?{º;åw¹\þ,ùó^V4PnÞì Y4´'{d±Êáæ0爨4œƒ«ŒZ6º9ïÕU}�·ó$ù’lªŽqü©ýÝ]•&ÙÔoœ®rñ¹V¿ÃúU[KÜž~—v2®Ý)C©]Ü)9©?»1ÎméÒ;cü&œ5žÎàŒ‘�pÆÉHyu6„n¹ù ÓéæÄNκîòQX5~ïís_md3¾œéžÚÇÑ$©á•N†YRìN¦io,=SŠÃM2<˜ÿ-¥yoz“þ�&ÖÉäÎu‚“)îãæ´ØX[=.‰ûqr^Ôet9c¡ŽÐc¨‰™_"å2”Á­ÒäUþE™ð\m~I÷@ã3Åš3n·›d·+ÎÔ¡Eþ3TùÖW7Æ;Ç¡dqÇ2¢¼l w²©¼œ|nbîê,Úgœø”¯*ö�ëõj_F=¡êj2�No©r¸´�^tr³>{´‘Ò9­gÚ>…ý Çá3æ:¶œ2¯Õ—L+¾ÓA+ÎH×?¦ú­ÃTÇNe[5ö…½§{cccccccccãÁøW� ì”UÈ1£Ê›�0‹Nf‚&×g¼©òW=2Çt'¯¹KOýv²¯bêõ¦p“¶Té¹k·�ÛõáÄ&;t{¨»giÛ€’ ï#›¬dår;F�QT§» ›ìö¢£¬¯¯¯ŽDF®XîJoü°‰úE&¯dàã±Ó*CÕ±º‡ÛyÜÊ æáXbÕÆõ_Õ?æß1§Ë]σÆ÷¸oòv •/÷;‡�¡ds²°¯ò{8þ\Z—Ë¥=NT1àNç»¶àôPn¬ûÚË^ò¬èûÏÂtlMÓZ�ܪÀJ«èú°*�–{¢9�i]%;«k«•¶œ°ÔÝý¯f±'øòí%¬V¤3˜ÔõdɆӯ_¼NÆÎt¯ɪã«ÁT2tʽSú�Ì“ÿ+i§üVÚÒ-Uá}·/yú¥I¾çœž•~ç”$S“O5óÄzzw¥­ŽdœUgœ6÷A6¢ñï³ÁÏù`ñ…QNÇI˯\ßÎðr}�5]¾g�µÍG½üêdæúYÑGJÖdлúîôi2Ô¦F©3lÐÁ¨0U§ÉØvp2pO�8„›ãðÞÔ™áv¿«ë=ïªážtä=i¶Áçæ�ºNóN:Zµ~“!ßÉ•Â'"ûè°*™ÝÿNÎgÃÞ^²±±±±±±±±±ñ`|ùé%Óe¿ÂÔsç8]~ŠarÏÓ²è=ŒqÂt‰Ç1KÊ[üÌ¥!ÎÃ1w«2pz]y'y³·¯^žÄôn�Ÿ« Ü2_’7±°î#/*>ÃñVé;¦[m)á1€[8˜Fù‘‘éXŽÊ÷z½þIÛ}`¦ÒÆ—'U{©ãðÔÖõ�©I}c›ó7]9ÓxéØRËäXt¾çV�kíÒP2óJ†“ß­hás§ßR™\>ÜþU¿///r+“’É­T9y¦löÙyÏÅs§Ÿ¨4&uÌqøzUö ÒŠáj:®ïUø,&åàñçìŽItº®ž©4*m×w§}ÕÍåSûO]wi|V_ù |ùgà]Õ°ÝÆ8n)Ÿ©Fï”!Ëð3 &‡ÉÐ¥ãäžLg—|>S‰¹ÈuØ�U¬öq¯*û+8œÐ“¡�ò°lØ]ùR[âþn¼Ç† Xr³Œ¸…£ Ë#�iN¿d¸^¯ïœ ·L¯N)ák”¹ÊçNPqorìxòqÇ5r]LõþW{‘ËaB§ Û ¯;gË”dcÑéRcëÞ‰P�ÎC9êÎÈwÞëö¶;L í3puÊåTÇeº¶®ggŒíG‡™„w΂ҥ«ùÝÛ†Ó4ÜüáÂÕµ²wXñ©R�ƒ¨òÂòl̰·—llllllllll<_ö"¥[ÚtϦL®[.é䙜kœ–Rºe•®cè9ÝG-w}FÚg–BïÉkòÌ1[¼M¢àØ~Ƙ¬@$yVê^•/1åNÖ)YËìu/±hJ†*Ÿcå°îŠÍ.ƹN6ÁU ~A�™nÇnc~øŒëŸ?¸Ãqëw• ä—*Ý [ZEsÌ–ú ^ó©0u=y!U�ŸÞA�£‰^Lã@=ã3ÉS\W'|ºÖ=Ÿ>ƒ«- 7¶Q'çŠÞìV[ù¥Ú4&R_SaV0Yí:“ötþWùuú[­T=jÎ�Ž#g+¤•*§ŸRÙxŒ*�ÊqVÊó™¶�Ó'�´‘îÅ¿¾§»›<&¸wpºå®[ýì�91âÓ’ÐDçˆL'5‰tusÏ`ë&·d°ºv® —'¦Ï”QÕ1n�PméÊêÚH-òµªgXÇûzèöq_.ÿ;~ �îtšF·µ†¿ùÿþßÿ{÷4^ñ>ç¡ê+�‰···å*V ”;�%¯Užjo|Õ¯r*»ô”‘v¯¦žÏ0ì:]À: ®�!ûúú*÷¢«:™”#9S�Þîî9Ú}ÔKõ9U†IyÜýdà­@Í3¨»î�ÏŒ‘¯0îÜ|§œ)çØ¸ín¨CÔ6=7?9=3)C×ç§ýpuì|¾Å‘�+�ë¼ÞäñN�O÷¢§7‘7ÜΣãxSƒ\)”)s³‚3“ÏÙôÜs5™ªä{0•»3jÓD‹¿‰¡©k6º'_fLŠZ• Ó¯ûÎ(¹ÝôQs©_ºÉW•Ï•�û···v¯µÊ×9³êˆ?…i8Nxéx/ì«îÅQî[©?uf¥…i$ƒie,¦¾—ƇS8KØ0»�öñãÊ@’Ç9Ji|Oû�2 ¸Ÿà}Ì÷Ì>n§Îè`—ï�¼õÛéØ$ƒ3¸SØÏ(ÏÔatiÜ;wV?él$ÖU÷8O«˜Ú4éÿ³`ïéÞØØØØØØØØØx0¾ôô|6ñDWá¼rµ¤ÙÉæ–hTú.�©¼«ñ0ìJ®Î;–CÁ1/)üªGïÒáëŽéÆ}ÉœþjßCFt*3>Ç­êx=%›b³;ŠÙ f6˜‘Sé¹´ÕÑ{F¬cA�ã[$øxC•Æôí~®»T&®«®L¼ï¹|¼:¦ê‚ÛË:auª¬&÷¯OêgÂ<¥xéþ=¬³¼œ×·û”’U­h¤U�•‚3¬%¦§V[Õ npó¿s�äžÊwæÙtsûê\ìæý{l”nì¤>äd¸‡É¯²9Ä'Þt«;º2Rq¦²OÓDYž_¾§›Ÿã/ßçᲄå–N:y»ôVŒGgø(Îï5àyBø cXÉro]­æ¥®ñeÀãøX¯÷L~+˜(L®/'dÓ½šu�_â, !‚ÖZÝMü*]Ã^¯×?apYS½<©þ;!Õ¯;R� woÿ©´&1ïÁLD@=g‡¥3®YÇvƽӃÉi›ÔÑc,¥Çýû*öuL‹Ûåæc1ÿ‰ìØ—ð\{Žÿs›«wªýqü&¢þ;Ç�óJiMÃ¥úsižuº±3)çj>]�»¸ø_é�dp»veÙܘÇ|x{‰Ò¿êþgƒóìÞgz6ìí%ÆÓèþ߯¬x°i)J1]Úì•&yc¯–.Ïxq•–[BJ¸×kíØü³i¥<8œ[Bî^.ryMâ$–hÂtwcBÕ+.—«Õ¬wTšû0 oÁ/>2{èê òKÀÕÅÖ©K*Ÿz–¾¸Çõ¦äÁºSGº2`©—Ú8\åÏé9ŽãÊ«ŽeB¸£»^+éC>.=wÄâ”scɵ]·Âàê„Ùmì·êƒJÇñq ¾TéÚØÉ¥dsòOæ?£˜÷ä^ÉYaê' }b_ƒ=� ›æË$óg1ÜJÎ ¯»•€*��nŒ¨ÿ|Ç;§u»}ü²¯c«öÍg¯fux$û¾‚§ü üÔtwey*ɆϒÒTKU+ÊÓåÅù¦¥ªU”BV²:p¾÷ÐSL ÷ 6$¥È\ó½ãX;–*9S.ýÉÙð*ÆAãG}rü8ÞŸx‚yñ}샿ÿ–g;³�ÉF$�§¨ëšóGÃÛKµÊà&wç�¹ñööööal»·øq즽è^«Xr¹Kx’T:±òg™*>–㿼¼Ø/ŠvFbŠÃPï0¬"9¬NGó>n_Õ§‡_OUÛÔÜ0­Ÿ;êÈH6Ä“ñédróê+†²Ësge.= e|Oœ¿ÏÊ�Áã­s VÀzÔõýÚ^ÒÍ;�DrŒ¦öÜWco/ÙØØØØØØØØØx0žêœî3Þ‰ò´“Wzfù(m/é–Ê0Ÿ ë‘dúŒåç þ[¬õg`ºü©XOÇÖGö”'}ˆY¡)û³š¯[M©_ÅÜò²¤ûúÞõzµ/”ÝnÿûHˆ“GÉÊ2º¾�_�ä6RKæ‡W!“Ë2®2VÅ«­+©}W˜\dI™•U²¹|¹<¬ øa"UO“�­®þuºŽõ·êŸ�,._,¾8œÚÇŽ:™e­kÅ>sù¸~8M%O;ÜÆnKÑj;*¹'ŒxÂtãºìæÖ•´UÜŠ&�Up[¦p<Ÿ(¦ÛÅåkÕïT^•>磘n5Ç&¹Üœ˜úèŠMâÊðLøÒÓK’±ñX=w \uâivÊae '%©&'SJ7¥½*ï#0uxâëN!t†±SPn’šFiÿ,Iiq¹Yyª}ܸ¥äz½~0ê?¿½Žqœ \~†Æ¾:Óåÿ¯¯¯ñ轺æí*,ÛdŸ$3nì©2«mJרÓbPv¬û4a+�æô“3Jù¿ûèQêßSgcªç;ƒ@±êºúº2Ž]{«÷TüÎpVPrOŒ) çœëNçO‘>Nåp�!ÜabÜ��{FÞÕ¹xšC9T*Oã;ér¹üÑU<®Ò)'ýÖå¯ìœkºº¼§|%öö’����������ãË^¤Tì•c0ÜR\ZnSyt2%YÝ[í–‡™¿ŽSžä+Kvx�Ye²ÒÝ;ƒgf¿ÿõ=ÝÅöè ›¼Ü Ór7¦«YWž‰Ñ5ÅŠâQeíäW†Ö¿9P’¬ø2ñ'E¿"›«³‰be‡ŽóJF’2x8?ž¤ÑˆCC$}¥�ŒRÛ ØØpJ_}€Gû\'\on;ÀËËË»râ>iÕøè½äl*£�ÃV=pZ¿ëKU'xd ¸ópcBMÔ*,Ê]Ž×Ç©:HÎ$†C¹’a¤>T¤â9ypûTÕ£s$Ý}–Õ�e>mfª#“AVàñãæ�Õ2¨¾šοîO ÷G"9ÿˆ¤çÿ #ñLÝ$'‹ûY7&U8 Ë:cº½Äõõ©·:ÿs–íY ï/?2P=_ñ*WŒLŽÃ†cêØèí¹Ž‡×ì©»Îâ<ÌLñÔÛOéO•êTùuùaž¥‚“ìÙü»I2åÏÏR}¡ÁÃý¾3^ë¹:ò�ÁF Ö§ÛÇ�áñ˜@.oooöv×3ÞG®Œ}„2^ð™2ÕW1Ñ�DYQ>4*¹]]Pgj³lìì(ç �y»½íêìt…¤S°ýñ‹¢h”r™Óí^Æuò(Ø9"θvŽ4;ììMêÎ9FÎÀV`¯qãäVz¦ëOgç.ÛÄPºLx——ËÃ9qœg§ë“C�¨T—«u<N¾‰<×ÍQÎVÏ•C§lŸ©Nê°wb¬?«Á}{O÷ÆÆÆÆÆÆÆÆÆÆÃñ¥ÛKðÿ™¥ÇTZ;š 'gÚ €iò‡-�Qs ûtß§ÊÏ�ëtrª×2 Ž™¸—Ýæ|ùþwLЄuãô“,‰ÅéX';ËÀìZØ·�QKÌ~ݯ­Ø–ÅL§•7.qËF±nÕßùH6fºqK‰b.ùKŒx­öd^__ÿ0¶œ¶J«Ê†ÛPëãXPÞ_¯Ú‹ëQmiQíçN]©¶T§ pY'Œ,¶]µQןÓ�â&V6­©ºÃ:a¦›?€ãV$0¯)Óíäf&™}L£;¥(ÍiJ'·K‚ŽEVs�j—Ïf»ôœÜéÿ=óÖtUàlž“úSöÍ$}ÕOë>³Û|óâuÆvÉ]ÏêË“(3†Uã” ?'›ÓiÉÈEÝÂÛmîíCX—Ëû­&X_ÜŸØÑSŽŸÓGÕ&j[Çq/ »=ølt³³‡²LëH�)þŸê~¢ÿ+-5–ñ…Žìqz”‘æçp*#*¥Í}fU—6’ \¶Éœ±b“LçÕ.ŸÕ>;ý�è¶+M�n%ÓÔYrýÓÅqcqÿ«°·—llllllllll<_úq÷lêIvËÎÛv™cœñ?›“˜d�iT[øL8ÆB…YIO¥£Â¤úMù®2ûÌlMä\ñ„«vó›ÈÑ­!«ëfû‹6•Ï…Qì¸bŒê´’bº™�tgàÿ“Õ÷B›ÚæÅ¬³+ëJŸ*P6Ç”s¾Š­E6ºäV_±d9',3XL·êCõï«Õ’):=ÜÕ·ê÷iKI••Ùè®~*m%Wê=¯t ®Ô¹16•A•%ÉÃaÒ}Ç ãít˜Kk2G'¸yyªË•ÞIy¥´øÙ4ÜJ»N�t�›{T`Xu„¥Êë¢'Vû¦Šÿl wáK??éS¯ÝÇÏV–ßðº›äê7ms˜ìßNt¥ó­bZß“ðÎHRƒRÕ£ ×Ý+Æ+Ópý$õ/N1Ù0é·•Võ/Þ�ûš¹?–Á‹é«þìÊÄ2Ç?[WTz8^^^Ž———w2 ±§ê‡¿‚Éõ‚²qÀ=æî”>ët Õ§«®º¾ÇÏÝ—!/—ËñëׯwqÐ0Æc�#21ªN”C§ú“ÚÂÑåádJ×ÎhIò¨±¬Œ)§¿§HóXÏ*.Ž_ìÃåt9chÕáI2p8üj:tõ8M¯Æ¥jçéXI²±Ãp¦]”>93‡¥gÊÆRùMÆJ]Ol1¥+�­�êåY mÄÞ^²±±±±±±±±±ñ`|Ùé%ê×yT ‰™˜¤Áž_ç])¦ÓÂÿ¼üë_u¦/§wfÉOy„‰­Påv`Ùΰ%X'®~:¯}…iKé°œ.Ì„IÁ´Û– žs]á¯:}¢òÆâpk÷a~ÁP�E·ì‹L{Óã3 U;óyåŽéNã€ë _T_â¬-(È«�ÛLÇ„b‚Ü×%yÕ åS«7ø�Åf#C¯ØÓ‰ì•6æËüqL¼;?ÿ+†Þm—p÷Ü fºYòµ;3}ªg§sÕ„Qw/‡vds_t:ÓQs‹Ò¹S}ÇHó¢“gÕ·VW';Þ­`®2Љõæ¼Ô<ÁéOYc%G’•™î©-æú÷-üï>ðäþ»²¨r}ü©öt»pÎXqÔ<Od¨°¸UMÔ8¡¼¼¼ÄcÐÎL’ª,`]žÉGåYiMŒüÔ–N q¸{Ú<Á9,(Om¥èYR|?…IŽnïp'BTØÚÖ�JOÅŸmi‚r†:ÆÏm¹QûÃSù”LÇ¢ûø‹;�ce‰ÔmsÎKr‚ùÈ9Ï̱©®§óQgܪëIxü¯d�Ø+.}7?uåñ0ãÇ IDATTóAÉææW¦‰Ü|Ô¥“�û÷™~;mç¤7žÉ¸vøÒ#Ï" ×Ý¥Óy{¥´Ó×Å’lŒd|N‡›Lr�\�¼g�„3´]>õŸ'þI^*�©¼êE·ÕÁ=U"+áÔ¤é ÞŸ?¾+tÌN&Cž¬ÐˆW“6§ƒû¸¹lhè9¦[M6®?%ÖÛM^iòì&cu¬#Êâ¾&êdÀv('óT횎¬K˜LÀUwNÇ­Ž¿Îà™LðN6~Ý™S£‰ePÀ±çÒCLÞš¬°ò<“äSåíŒ'ÖMݼsF/OÒíä[ÉkÓ<¸þWmÆÔ9â1¡ž©±’æf¾?±�8Oþßñ“gÏ„½§{cccccccccãÁxš/Râubº“w5a#'Þ™“eSÇ›q¸WÛåËñ¹>ΰ+Ì~ÊgšÆÊ’QZKrc;¹�º|VÙÇ$ÕuÚ³êòîÊTy:†ëÛ¡¦Ê‚i9F-ÅqÌ9£Ò~}}•ùàJ’b3˜ÚE1ÞÇñÏ †cåÓ�é)]Ur#­¶öÔ‰ +lbÉŒ:ËÄzôÌê”ÓÅNnN[mIqy`çXa<7GX§N×u˜èK—÷g õy7®U›Nì�3Ž›³qTœ®?¹0]žé8Ê•t9ÜÔàNõ�Úï™�k‡½½dcccccccccãÁøÒí%é:yAÇLuK$*�Ä”³lÌøÔ³´d§ØZ\æár88FGýWl‡ëXø‰79•gܾ\w޹qŒÁ”Y™¬ŒÇG6’™ÎŽ=8[7·›>uCÉXr96ç £NõIìïår‘_šd~ýú5úªž[!Hlæ—V êš?€Ãõƒ×///ïV·”܉µWåÀ_ÕPVD•Ç!èNˆÁ|\=ªvUŒq­Xàq�J†n¥bÂ<ó ›êXÀúï^ÌåöHŒ¤»¯¶Ì(¶ç†î(SW­,T>ªb:ÌLws’“¥Ó'ó;eE«º°c–'éNWb8�3åã|•Þ˜Æq²M™àdÓLëËÉÃóíÊü«tCW×NǪçÏ€§9§Û]O6wÎs2HÜT×õßÝ¥äSù0ÒÀþÌ¥¸i�¬`¢Ü'KE�‘‹áÏ,y1&ÿjº�"S÷“RUùº½Èjï0~�Qååúš3^9 ž#ÍF–÷qc8õåIWn'³“»ÒWò¸4¹ÑÉ9ýÅJgX§gX~•/§�À/}*Ýé¶§(°çÚŸ�n׿�³�ÀF»j>Gµ+§75ÏèW5>0,o1äk4°9ŸÛíý»C£;…qåèæ6ü¹¼&z>9f* ¼ŸÊëâ®Î}©ý§s»Ë{eîVu¦Œ\…4>Ò{4œwçè(Go*“»&þ³ÙŒ½½dcccccccccãÁø²)³\˜x¼õßyèÎKìαÄ7ú•÷Yà/áq™”w6aaT9\z¦Ãoq²t–ØŨ~6+ï Ú¯™ýtËe]»tu^l¨zYçãøÈ´a8쫸ÕËæÎ}Vy"[Š2àªÐ¯_¿ÞÝWÛº/ñ¥zéî[j‹I•¯]Ù“,ùÓí@§Pïpû©¾Ài)¶Ð1Õ¬÷Ô—P¹oa>® ,¦‡ý„ï'vÒwÒ|Âuï˜ÅÉjÊÇL7¯ ¸yð^¦[1�®î™œ\)~7gL˜Ü)º>Yù­Î}I.îßîMý¯Ò^e‚ñ÷ÁÎét��.”a:GºrLòúj|éö’ÉÒ@R¬Çá•�Ë7)7á)yÐ@˜ìQEÆ?ûëÞRŸ(—³�iꈜÅ=�\µI2Ò'é8¬Ö*Œ:ÉAå3éû˜NR:lt»£�±èNµà- \.忼¼¼3ºñš þ¨K·W�iר S2;GHå�ãU�F¤dqFN2dù?²˜®›\ÐÉá:År¨ºPå™|tªôÊZ{úSq&Æ«>쌷É8âwîÑu*ìg©/tFiµ¶Y:fô£›åqÏV ¸.NÒÛÉYqrr:©mS›ßãTtPý_9Z+NáTŽIÝ¢ xí¾Œåq[ßÜû'œn>ãô`zÏdd3öö’����������ãË·—8ÏFy,Ê«N×ÈÊ ¤òwK(,›úU²ª3Z•'ˆ Zç�±§Ü¥�îc~Ž�û ¤• ”ÁÅ›²TfdŨMóíòÆþ8 ÏíâØld3Õ¶ŽÊÓ�rÁL†{¡ÑmI)yÜi*¯¯¯~±=ë?Ê’ê€ÿOV" \ê>·9¯tlbǺ)¬ÒuºW ¸ý®ÊîV&c®y\ p[dXVLC±h?m)Á´ÒêËÐɷ”%‡ãEÉÍ«?nå´âóŠDÅQ÷+|7o¦{ˆT'iÞH«êþ*«ëþãýÉê]bÛSúø|¢ÿWæy¼×Í•.ÏÉ †ÛÖ„ñX¯Oä™Ô;^«:JõêôÁ3ãé·—`¾F¬LÀ jòÇ¥%7ž¡ŒžR„¸ë–�œrf…‹a’bíœ «ÊÍr¸¥3Žw¯á{ïÒ 3d&JCå£ ”Jc2è]ŸÖ¹XGµ½£Â¹vÁÉ�Ãñ¤­ SVº,�3üÑèæg•¯Ær»ñ‚aÕDåê› ^õŒÇÛÄÐVÆ­2†ø9ë%O×Õ’rüÓØf¸úåxUw|š‰*+§�2+'ŽË‡}O‹Rº­3èÔ¶•©!01†8mÕ.jluŒâÿ® j\óüÂX1V:eJÿWòî ú‰ÑÕA=KÆŸÃDŸ™‹Tßrq�S:ŽÃ”}£œ=ÞV—H‡‰#¢®§}c’žúÿUxª/Rºá+uŸÓ˜ƒî¸­J ŸáÄ“&Gg¸±Ât†íjÎv²ÏŽ71^V©þ¡äZ58Tº�óXÊ©;†©ƒ2ÚÊpÀ#úÜÙØœÐ‘uûÕÜhX³á©Œfdò”²v¤3x]�p[¹6Wº¥3ºX>å0*ÝÎØ¸Ýnr}’A1NøÌ½<Ér¦þèÆiªWõn³ÔI÷q8·j“œ)×fwÅPZÿN‡ 3ÄzÝ�ïÒe§ÐíÛçxêÅådÜ9LuYr*Q¶I_\E2ÆW熉ÝóIÚ©~&º)•'æÎèÆxLö8LÇ ÒÅÊY˜èPηÓ_‰½§{cccccccccãÁøòí%‰MæëÌ0¨´W˜Såe&†ÞygÌzñ5îÍ;Å )\ÿŒJ†”¶òð»8ŽýïX9w/ÉÅ×* ×Wãâ+°îበÕgëìÊÀ{Gñ9Ê�ìyÅÃtê9ÊSáUÃ�áÇÇ-.¼ÊÃù°¬n1¸»6bÆOÝÇ�*ƒc“ \7…ôæ?3â·²Á 1ç‡ï¶$v½ck¹½R�)Kû�1<ö'fá¦íªd˜¢ÓIo)6™¯qU ±Œ® ŽMLãí¨¬èÿŽÅìàæåÕ4\þ;ÊÏîeA§«)NÏœ•-ÍIØ¿\ü¯XfÌGõçzvO[:ÛOÁµëÔV|&¶ûË_¤tpÊŠ¡&‡nIc7™Ö nÙ°€FQ…qÊ�'¥‰Ü�ìDnI‹óŸ”˜Þ4Ì™  Kóå>Í[)¥¨ÉO½œÈF÷¤îø%Êd$¡ï¶¡à6îÏ·Û?û¸q)½Œ‹‰óéö‹;£òUËóN‡¨þ­ú¾ÚŸ­Æ,·§Ÿ^àt/׺ø®Í±Uû”^B¹YϤcKSŸV†$†»Ýnïú‰s°®ª�îsF7‡UFNšøÞY��zŸ�Èä´ñ‹“Ižº¯œÔdtã/Ý®½W05ÖWõ ÷9L£3X»¼*Lgðuí?qüSÚiKæáæýä¤OŒOe¬*C�Ç虣;�Ó¯ëI›3R�>‹á½·—llllllllll<_ú"¥ó,3å�<|÷ïÔkfÖEÉ^ù`|ÇÂ0«‡÷Ë5e–§ìË3©Ž£î”—zf9rSæÝÅS}ˆ¡˜‡É’–b-\Åþ¢lü1–ÿó ZØ]/—ˇm&u­Ž-ä­%ooo˜nu•êïÌü {¬^¬TåFLtKŠçtPåë^žÄ²¥g¹xü\éün ¯^œT+ż©ü9m–Ç1†Ø~|ú�ê·ÜS�8¤ðî…[%‡ŠÏ}Ím\Ñ•Nbþ\zX¯îXUßÜ'ëz¢·ÎÂ�Ñ {¼2‡�•͵ó4¾*_É­Vb\þxÓIywHíªÆhõA77¸í¯+mÔ�1žÜøTåIé=#¾üô§´»k†2<”Q¹¢hPQ;°ó²±ƒƒ��DsFÄt)æ3•’KwÅP<£(§F“{–ŒÆÏœ8ŽããÖ€ÎÀwgbsZ)_u¼YÝŸl/Á¾Yÿ'† ûj‰2ºñØ3<±$�µ§·3x•3œâ%}¢êŒ¯»ãÿÔ$;={ŸÁuä&w·M‡�[…ØÁ/p±<“qÊcÂ�TƒÇ[b|µ‡;É„i²¬ÌS‚¡ž©úvsoW\)ƒ‹ƒc´ò¨0|†w—ŸsèÓ:7_'’¬]ݬÈÓåŘØNVüfãy‡óMv•ëûì uŽ%—­3š�ì�ã¦Ò]×_…½½dcccccccccãÁxªí%ü\…C°5eŒ• ʃwé9vû8Þ/ç󋔘²„¸«dbYyÙø³Yo®SWÖ)©äs^,ËÐy¨ŠÑ¨<#¶"«ê§6ƒŸMØn·t‰Œ³:/UÉ=e Y÷1·¥„û#ç›ÎvËÝŽ=ÄgŠ­]aº9 „baÔ oÓp+"+c4é; ÃØá0uÿz½þ)ƒëwî4 Ç@*]àt¬ƒ“[…›¤çâMXIþ¿ÂˆòWÇi,:Ý®Æ!çýãÇ�§©´ÒVÆU$&Xõ§C™Eåk.SšKÜsFg{t˜ö'U|¦¶¨MëµË×ÅQºJÙ'ª©—(±ÍSÎrªq ¶?¦t”Ü®º¹ú߯—Ÿ^â*']w�ïqã¦#¾x)Ù-™så‰Ë-¿ð© îx,%g¥½:¹'…ÀpŠq'Ý›.UMK2¬ïU¬ÉhU÷•"SJMɪ¶�¤Æ8ç,Mî|ŸûªšÈœÑ͆šª¾Çuâ”,ד;šP•/ɰŠéøUrU¸ÉØqmÄia:i« ÊÇû€±NY§tΰz¦dä{¬/q_º;�…óI“;—ƒÓReHmbÙ“|%›ÚkͲ1&eWùUøŠÃ†ë ‡ënª/;1ÉœÒZq&a;]þYy±ÃÕ…WvÃêØ¯ë‰~㾩ô#ç£úÒ=Κ’eèÆoJË¥ýlx*¦ûÌ„©Œƒ®cœ1ÀÔÑ9œ×ïß¿ÿL"h„0ƒ�ŠŸ_4rž)_O½ûnºòNà”¤Sú*g@±r™´Y ãòÁgNž©ñšdàÉÞ½HËgn;#7µÑt?±3ÀùåS/RV_Ÿ:‹xWƒøÁ$Ë–ôɽÊ7)öãxï”°Q£V6r]ziï?ê w®.Ë€mÆç§ó¹ìî¬éT,?Ê€q°�'ãŸ9SÅqàþ‰åÃr»•S>÷öA~÷gЉ‘äú#;Ú¬«¦m„a’cÜ•¡ËgbŒÝ •¿Ë×9ÓÉIu:Ü92ÉÁQý¬3Εѭú ë4UnLß=C�æl;¶«\ZœßÄV|&|ïéÞØØØØØØØØØx0¾œéž°ÛÎ#C¤{è%²7†^\bnÔþ8õ ÓÀÓp鉽8Þ–RÿyŸžª«ÏdôWâ¥U‡ÉTÇV<Ò3u^ô*ÃÏÿ¹?§~W@&�÷j#3‰ñÒ2_òð'uª˜I%;2ïÅP(†ûýṪ�lÈqä%üÕ²Ÿ�K7ºqºÊnqšŠÁR2aÂcy<*f óa¹³¥>†ñÝr<³² ‰�L÷S�:F=¥çŽ^øTßIn¾¯˜ÉºßéÚ “t:ÿïÆÓ=ã¼cˆ'ù&Vvºáê$É7‘•ëpÚ7•õ;avq¼¥÷}¸Ïp\]aHåCÜÑ— “¶œ´õ¿‰/ÝÓ=Y.IGàǹí%*ÿH©#Ö//ƒ¨N…ÆFm!Á­'¸„îŒv7¡«2¸}ê.üÄØUŠ‹z’-Ý?vêL•b2^“R;#[2¼•<|,`š<;Y;Ù\ÚI©%cÓ�LÔÉÐgyœ¿jp«²*¹Õ/ê§{&ài_�DÛ·p`x|4íCe#n"÷ì4²±ªôWÕ¯ÓçjMõZ¥Íÿ'Põ˜ô„ë«I¯Çç,¯s0ø9U–'õA5~Wê�ã*Y&÷ùy’Û�åUÃËŸØoÝœèÒâÿ©-UyøÞtÞAbDÝn>çën¾LóËÃ÷ÕØž´1ßScñY°·—llllllllll<OóqÇL%“*Ï$�gÄSm/qÆâ¤R•š6Z†ÓžtŒ_Ë:jBÀ°l´»e1¥˜'Š…Ãu F…Oõ¢äî&€N™ªIgUér:n™o_ÝŸL¬lðsî4>Ôö•×ôÄ–©òKŸÉVŠúv»ýÙ\÷»zä¯O¦>3™\œ¾HÏ9ßåvºçvûÇùPmìÎfçþì>µìŒÜTN,~ª}¯×ë;ƒÑ��©!â¶”pû§öq:ÄÉVeKaÉTaÜùÙJÿOõAý&CÉ™.-ŽïŒ[ÌãÜ£§a¦íã®Ä_EG[%É£ä^MƒóOýLé·½DÉ—æíY»ù$9]^i¼9Ãü°·—llllllllll<_Ît;/¥c� ‰mÅkåM½JµTÉgp«2 —Ç_´Ã8Èbð NŠáUjçÉ©:HÌò &¬ö½iN¿•t•\&Ñ­LÒTá˜Ñãm$Øg\=v/cZªïð×%S{«‹ã2½HÉù«±à/C}̪cv:¦L3ïn5Á�×ãÐ %žJ¤òR÷•~œŒ7fâÕ‚?~üùjå¯_¿>èìé´µEérùçKªU�J_âÖ>ÅÇõ[LC}¥7é 7LÒNóÓ”éÆüSŸäyÂ��I^ ÕÆ*=UWÝêÚ‹ó?ÃOò<Ž÷+†®MœÞšÎ«NF%Ódl'LÛdKM^²u}!­Êðu “ÆÆïæ†IÙÕõWãË�nõªÔÓe€i0:ƒ×Úh pzooo>@Á2ð¤å&ž3F,Ë;Q ®}¦KM«ePFl§¬”2YUü˜÷9õ¿“Ÿ'6eŒÕ6.9HSƒ×ÉàŽ&Tùᖼ連Ð1žêëŒÉÖ•2ü;ã•ï±Ü<ÁàýÔJ®—ËÕ�\onlªrâÑ¥îT‘ú½^ÿ´q…s§ià笥/ˆâ®_Üv¥>:ĘÞ[Ñ?܇�¬É�™Àõ Õç\¸¤ë÷O¬ N[Íog 7—r9œÜ�žèœŠ‰|GÍ ÎéHåIŽÊ=†àŠ¡Þ}…R9¹®î]™0=×79œšCV ìd+>+öö’����������ãË™îäõÇûÍÿ‰IHL™Ê·â¬xŒõ›N,HÌ@-óv[RÃã®9�Äê%ÏePepŒƒZvÂ|'̆ór8­oÇ*9™ÜýUOeåÏ_³lêEJ–gâÕ'ñ„‰i�¸à$FH±É(ƒ– O¹pý¬Æ¥b^;ÝàÆPx?±G\N»cwóÆ,:†Sòøc[J†êêñJ6Åœßnúꪟ žwz±pªÜë9­7–Û½àêÚ?ɓƥ“¯Òžœ2”0-;æ{æãV.Õ�Uº©ý'8«Û“ƒá”Þtc„ﻃRžÓ´ŸOct×üMa Å‘òwy'ƒ.uBÜë̓—yÔ1jlóÑ‚EÖ n§ÐUZNuH¸’cš¦Š—Tgìs]q=*tý1Á}èÆ}�s5éŸq8P'�Sº¸ï–'c7Iª}Àø¬“ŸË­ŽX¬p|BÐê$ÂcoÒÿ•AV÷“²Ÿô%‡ 3ã<áÇ{ûۃ}Çã›�ˆt4`…SãåäÿÊïŒîθM:{2¹»£f§ïS8:]5I{jÐuó„2†Õ{ JN•Æé ·tÏÍ'gê�ÿwiœ)» Ãóª3®§òu÷±*Òóg�¯l 7‘‡ËÚÃJ‡vy©<'6äWãiŒnWIêºþOöúMdÀ_¥ð\gUùb' 'gé³½h`ðžpÌÝ$§ iç`¨0Ž©úMà<»gÝLé%L'5ÞåËŠ ‘ú_¿\6g ºãS½"3™ TüïØm6àÜÄɆ£bG1}î·“~ºaªº>­äãk¼§ÚI•CÕo‚r4ºñV:G=Om‡ÿßÞÞìJczé7éK”ÏÕ#­Ò9ˆ˜.·�2j*¾³ Ü·0M7‡¥ô:°cò¨´ï1*’Á›ÈžiþÎ)p}ƒçA~†÷\¾éˆG•NÝû ãÌÕ—OÍ]g~†c¶Û)À:ŸËÀ}ÁÙH$;󚌗îúÙ°÷tolllllllll<_Êt‡÷ä&LcÅKâ´§rª8*¿ô1œ···?,xçía8·ÕDÅ­{,CÇÐuLBÚ‡‹Hì æ™XLΕoÅ«ul§ãúã´¡Ü“£‹Vý&1[Ó²O˜n–ïr¹¼;&óÄS-x?uW|ø9æëú3÷YwŸ^Òõ+wO]«/ÄNØ? çØìj•Û‹?˜âØc^YPrqÔIxb ögŒ‡ùtLrÇ2'†ßEPeUì¡Ê«ÓwŽÙæë•í%ðŠ—ûÓݧú°:n¯Ý<Æq\»Näsc0=[Y­À8Æ8¥“ôÅÊêÆÊªA*«{ß ž©>�˜müßéTe›©:îh¥�VØî.Ì3á[l/áå5á¥F:3¹‡^ÆWñ�"p�Í_†rÎI8`xéºSÀÓŽ‰2¤¯VñÿnIMÝ?;î1~R¸‰2^‘ç8Û~ã÷Lý¤IÑ-Ós8|æ”6Ÿ«|»ýó ¾³€í\{Ô]y±OÆ¥*·ŠÇc”�7þVÇ’2~ÝV žÔÔ$Çá�A  V¼ï¾jˆõˆ†¬ëøB+ç�GüuõæÚ…ú}žè $=˜ê´3$Õ>õB¡jW÷åQ×§“>ã2tuÛéduÏ�þŸÈ.ë#°Ó‹ilWøUgÁååÒXA7OMótŽ<ÛJ±“<™¿;ý˜ú¦ÓËIL¨Õ|ž{{ÉÆÆÆÆÆÆÆÆÆÆƒñ”ÛK:�å^KZòP½QáÙ3s Óqüó"ÏUÞ§ò.ñK•Ì*®–k%<3FÈn2SÁ׉åê0eƒƒ™X‡nuC¥Waº—'™¹cY�,Q×ÎÌ`+™ÕÕoÃ8YåI/\ª<Ì€N˜L�ÛãuÌÍ”iVqÜv fÛ9%·?ççÊš¶¼qYT¿efÃñI4ª<›ÅýëÃc^IªñÁ:C×ï8m·ú£Ê ®;¸6Âk^MrùLLׯ•<®¾¹:&‚•ðÖm¥Jí¥úgW�jn9;Ÿ¥>¤æ^ŸÓr'–(Y•B¤9[¥­d�Øv˜W· òre}&–û8žÈè^m$†3dVäH�zbø§ „¿Ú^R×jpà^Æ×××vòtåpË‹˜·‰RÊI©N–‰”ÜIùŸQÓ‰¥3^&†½ —¾Ò§ÎâîdS†W'ßd ñvûx>ªS^ªß&£[M^ê89–'M6Ê�u'¢¤|¦Æ+—ƒëÞµÛ¤+Ý€ù¨ôx’œ~øŸ�ÿS_­Sájw}îÈ@5±NÆ#ʇ†?©ùãÇ�ç�s9ð™j¿t7ÿNNœYAgl¨>ª¾ªÆ›«cÕ+Ž2D1-u¨JkÅàquÐýÇ~5]þÞÕߟØ<Æ�|É™a({"ÝÇ‘çÕf\Î4ß9ÙÒ\šì9—.·±³ŸÍØ.ìí%ÆS2Ý챤)g—wœ\ŠQKấ•²ÖÇ‘ÏEU'™0[—˜;Ǩ)™1Žz6a³ùþ„‰Vñ§,E×)…{½„Ç ²ŒéÅ9Åf8‡åf™XÎ CïÂ'–q¼¨þÝmÝâ±ìä.=¡úU×1„Ø�ñ~}7 cÇT{uçЧ.ö-d_]Tÿ'ãÜÍ;I'âóÄö9Ù&Lâ*Íļ¦vÁí%‰qvò)&¾“9• ÛÙ}l+µÛ”yM2Ü6õ­¤[œþB=íCày'�‘©­�dsº ¯ÝÖZ—obºŸ™ñ~*¢c/ IDAT£»»æ·pÝä71b’�<) TJi`c™jY´–‰Ô2–÷w« ÊM„“7×OJÇA«i¨|»¶žN“vv`ç‰eRK{IÑtíÕ)¨N±ª¾U÷;%É÷�<Õ§]9ÔXUãÚ-—â8š8•©Ÿ¤qîŒ�GöÛt<§;ªN9(Ê(A9ØXa e,#· \¥«#SݸP¦çƦáŒMÕgWçƒÉóÂäë¬ngu?̓ª®ÝI;®/GÞKÏò¬Â9 .œsDY¶dä:ãQ9…*Ï8ïù$¢Nî"/܉%ÛÈà]ŸŸØüÌ�ù‰íö6ÛWàË�îÂd¢WF)Ù‰’Y‘Ç]«gÎÈaÓ(£» °îÓÏÌ>ñà0ü™‰°3\¸ ü¥ª©³£Ø–J{jˆrzª© Ï ÔN±:c“§,C2lëzÂL$%댕—ëûfMY®Ê§ŽœSËã”±36ÓdŠñ;§FÕ·Z±pép|7YNúºÊ[ÅIåâ \w¥C*?†ÊØW˜ŽÑT>eèÕþn%£ÊÓMÈJMÑ jü㳉 n¬p®îU_u}²sà:Ù&åH†µº¯ú~’'�Å$“ÓÙÉ N:v:?MPaËàîl’d#umïòWz£ú_²ŸÎä¥òíÞÉxì=ÝÆ—3ÝŽÉÃë´´¼âwáØ#sÇ™°ÄŠ}v,JåSû$'_À«eÞ´üÔyîê>—�?êâÊ̲Nömªü'˜°c“6ª835•�÷¸"³0ÙÇ­XÆÄØtì6ßwHù¦mR ˜/²bø�•Ëåý’6Þwý±[½™2§XÇT»þÊÇð¥<՘ǴQ_p>\w˜ç´¯»òq|Ç8á3\a«¯êªxxŠˆ*S'ûdU¢îñ~p¼¥²&ÝXq\�¤ÕþíX½Ä’®àžz¬û( ÷KŽË}såA%ãê3f¢óË}F6Þõ™”gškœÍàÒ«¾‰ñÔ„òuó»ƒc°Õ\ât,ç=™¯\ÚîúÙðTFw×0Ü¡iù'�-Ÿ™�²(¹YVL×�íí:CMdêH5>*«Â\¯×ãׯ_VÖ4P'÷�2Ni0’±­ -~žòIËŽ ©~xŸÂ-¹bP/­u²¹{ê™3âWëG½7ÑMJ+çíöϱsxÜœ3üÔ˜gdžÓÇ_–!M+ýlr^1˪Peè¥ôÜôJ¦nÜ'£ó)£V¥­ŽïÃkW'“pîºÚáz½þ‰ïަœêÈ3ÄÀÔIíôÇïô`‚/�lª?uºÅµùªQË}xª_\})6i#NÿŒ¾syNŒBÕ^]ÿ¯9L�ç³vQ’�óW²¹ûN¯wpõ8qž{{ÉÆÆÆÆÆÆÆÆÆÆƒñåLwaâ±0ë嘒‰·ÉPÞœûª“óRù>2-¸¬ž¼À××Wùáöz‘]}yyy÷2f·=ÅåÝ=S§àsô®ª=ÔR\bÀ ž°Â(óý6Ìõ;þŽ«Îcê¡wl†bêƒäÿÉx«kÅZ¨2cÚÌv«|#’úP*ÊâX½´*³:Æ\ÿæ{ÜgRÚ“ò�a¶jû[…OeRí0ÕËœ6Ö7‡å¶CÆ›õ/ÇUHý§Ó'Ì2º±³Â8NÀc�õÂtÎSp:çÎ7m¹Â¸*¯IœI¸®L“~0eÛ'p6� [y&½‡õí>nåæL›ë¬+«cºÓÊTw�ËxfÅ`¥Ž¿Oet«ÿÊ茒³J�;òê– ~†ˆ÷x«OÄ×}4 •AÀŸæOÉOʹ:Qs§N“ÒŸ=qÚ©.ºÏ@wi«}·e<­.í%#Wå­î)Å• nÎj8ªœ«“æ“¶š8¨ñ¡òåñÆi«/ëuŽã4\g,«zKN“KÓÁÉ7MÃtÇñqËÊ—¶S¹ô0¼3Ü�Üjváø?¦�äacö8ŽÎö5–gÕù8.OrŒ©ŸTœt¼)êÁn.HN³ —t'·Ë¤þR;Oîá}NgÒ×S�ÎÙø_¨êîÌüªÚ{b@»1î ã3ó2º•LÏ‚½½dcccccccccãÁx*¦Û±ÛèÑ%æm•U¬°./·d“˜8ÅlðKW—õÛퟥPd°ùm|dj‹ ç«äRè^ìê’?L’ÒIÌËt ÑÉ•â8Ö,õ»I9;S')t,Ã=Þx'ý«=ê¿Ê§®Ïäë¶šð©&³Äl;Ž·5�˷´MËê˜"÷µR¾×­8¨´î uÇ2±a}Ui:öOIza2^ùš¿:©ÂÔ3>EEå›t‚·íaù˜ÙVýmeNríœÚ(¥ãþ«t9\bz¹]¦ý©C·ztF¯¡,“~7m¯nÕ‚m—6ÝKzK­þOW 0ŽÓƒIÎîƒJÒ'ÎFãùÛ­Ð>žÒè®ÿ|?-'(`uа “}­®q•C &"N÷FÕi&%‹Ûëy¹¼?BPÕ£šüœó2…ëàgӛݓÉfº™¾6‘•û�Ú�¯dvyžQg&‡®/8E¦”¡ú]í[˜EÆõŠiº=ÆnŒ%ƒ É—ú¦› 8,;x¿ÛÇ�ô “¥þwΙJÛ?[ȆWÉ—ŒR‡Ôh ¨:*Yê?ܼÍË¥�05r¹�\œ‰�£Âœ³pÆØá¸¬#UXõ_�ÓÕÛT?tõØÁé·._•F'g7ŸtcÀÙAÜï§û¸Uß_™c°$�¤ê%ÙKNæ�^T²>öö’����������ã)™îäÉt£¨ß3KPè=òKZI&w™»ô eþÀ²LN.s¥Ïñ™!z„÷—˜·ŽÁr÷WdRì¦5=“[Éæ_<—;±B« ˆBZ‚Srr^+¬j—7æ•úº’£Pì$üÛ‰ÇæÉŒ¬Û†�V :aáÔøêúwÇÐ+$=˜Xw•¯z>aëŽã};9FíÇ�Îew/{%y�ü®Ç×í¤Ž¦ã�åMãeÚ.܇]}»—FݸQ6„ºNÀpüò$ëüÉ8ŸÈ ÊÆöؤ<Ó1’êÝ¥5Ù‘ðLxJ£»þóýêhêO6n#‚ã8c£;1eÒÀjÉœãò’íÛÛÛ»“LÔ$ÂåÇ}à.Ü%›Pß}ŒBÁÉßÉànJ»KC…OqÓ̸2ø�C°‚Iýpûc~ÉÀ˜Ê5s]ߪÿ8Æðh:~ârùg+U2üÑðà�EàµrŽ”œx�ÛTMÓró^tîƒîhÂä ¥±„zB�õ o/áþÃåP²âû&ÎùPi:ùÒ”Ãp¹±_Mô�ksÃmÒ9F.‡íú“Ó3N•�JÃ…Qí ô :-HÉŒive›ÎO®üÓyÁ¡«‡n;Uj�$«²…ê:ÝJîçÜ%yR8—¯j×® ”�¦l¶Gë߯ÓÝÇ¡‰òd&Êdepª´±£¨#y:T£;ã 'Vœ�‘áI-OõU6.OîNÉv†™ƒk¿É$Úɲ¿Ës:�CçdP†ÇdòZU]ßž´eªcc®üÆ®.ý.Üíöþ«•Ž9gÆÚMÖ¨Cð~�o®-'F»s†ªî”ÃçÚA�³©ñÚ}n>MdŒd¼¨q™>Q�ÒSé«|˜ý璿蹊d�¬ÖÕÙ<§óÎÔ°u÷Üs50m&™:çC¥¥úwšÃÎÐcý;Õ]˜¯{ÇdÅØëÂ)½Œ†¶#׸L«NJ׿Wt—£«—·›ç•}xóUì¯ÀÞÓ½±±±±±±±±±ñ`<Óí–e˜±ê–oÒKç¹¥<ë�÷Ñów½a/ óå%wޝ<òëõúᘫ3̆Ÿ°<+Þ~'³ŒŸÁ"œeÕUü¯X”{Zn••Ke똈ŽõPlÊdiÐ¥éê�Ï<Ž�Çß1sÛ�Åt| ˘ØE·jÕÕ›Šãdà1¥ÒqÏ8Ìqø�› ó;ÕoU†ô ó­|x;‡ºžŽ·BP׎íB&vºý�ǯk¿Ëåãžj•—%…qeèâU[vì!ÇOŒö™>w³ci;&�ÓVÏ� vaR�¤´JOÜÃr§Õ L;�X‚ò¤þéòPà1>™çY.§ÇÎÌo*ÿ©¾|<•Ñí†�_×èi‰±:áu†¾sP6õÂ&æ[áÐèÆ—%•bÅ´k ýׯ_£Ní ø \çw†ÈÄ@=Ž�/lM&å4‘r¹´U�ª_¬ï¤üTÚg&Ù•6á Á-‹NÓJyŸ1*& œΉ iÌrûŸ‘ÛÝ܇'†öwÔoîš ×–Ü�ÃÂqœRrwºï•Þª­CÉ)œul$£Ëíñæwe*m÷<Õ�KÏ}í8!ÕW‚Ó¿.m÷,õÛ©qžŒá%—kÅè]Í7êŸaèMú`·�¯�NriOd_1ºÓXp6›úåk•ÿw{‘ro/ÙØØØØØØØØØx0ž–évÌ”ólÌ2um·Tá^æTò;¹Ñ‹s’`– ÃÕRûÛÛ›õá�æLÞÚgÏ2± |Í2M=\N;1h�<ÉËMíæXÕ—�)›œ”3–ýìªCªÛéÿŽáa6Ó˜Œ5u=eÿù%-¼çX%S�‰®¬®nêÚ±3®ý�‘årp¾î%!÷©:.N½<é^%·ÂÊj ÆÁSSœžŸ¦­úp'wÕ©ÒÅgVF± ¾n‰i¨8g�ÚU=ÏqÓ©@Ö�jnHŒì=ºÝÉÞ�W7:–ûŒnîr¶Ïïß¿ÿØ�Ýãt¶Ó½ÎÉ›˜nW{eWr$» õâw`ºŸÞè^©d^RqoêO”;wÌ“e�”KÉW×î¨=d8Q¿¾¾Æ‰BuÜ———wƺSrJI;å�& 4†êÚS–ÒfåÇqÒ@Ÿ*k† 'ïdB»)Ÿn)î8f@ª§»<§“”GßjØþüÉo4X�Ül€©çœ�*¯Ë<Î�qŸö«sp+Ž::QSÙ˜S=ˆa» Xár¹×ëõOoooÖÙHuîô‘jo.C2°î”\N»p©N¸o¥tT¼îžÂÔ°�€Ûèv»Éù¶à¶Ó¤|ݘU²ð³i>�³Ñé1ž«Î"ÍcÇ¡�K.ð¸vF÷TçW:–ÇNÚ§ït˪¡¯Òeû�íÔÏ3`o/ÙØØØØØØØØØx0ž–év÷Ù›Qž¶b™ ¢®ùç];oÒ±OÈ®¨7é1ߊƒ ¸b¶”—Y/Uþßÿýß’ß1e®'-§=aò;ÏvÕóuý‡WQÒÖ×ïRy¦uÔåUi%¶pÂ2¯Èíîs|—/ƯguN7²Ý¼¥¤î¹�NqÚÌ2§/TVZÜ.êÇ"÷÷¡$¥Oœnq¬>S2p+·Ë´ºò%V—õ�«cÜr‘bÌ31[© Ž¡ÇzÄ¥|Ǽ;½žÐµëgbšöjûóÿ´úƒíÄoKi;¦Ûé±T6–3Í]$}7…êC®N˜éÆøÝ*‰›K'ã51Û“ºgvœóUsë$½ºžœf÷lx*£»àN(©ûÓ=Ý«{m“·Òw†O˜t8âv LOp`£Óc#ë?4‚áºcÔ\ýL; n¢/9/¥d’0Qj*=gŒ¹£×8]W?É©påè ce¨>�Ògyð~’!9M8ž]xRï›WûÙxÅ4°-”ܪ¸¾¨  ÞÊ3MŒ*ÍÔ.Îp(½QÏxü;çqbx¬%nÌXWá)Lüþ §«ê!Ý]ùÜüâ¶Hp[ªøÜæS£$é WªÌ.~×.I§üœnVcLµ-÷ó¤S�ÃÃõ�aœ.à¹y 69ˆ ÉfC»®Ù†À´Võ²²uºv¯pjÌusl§Cœæñïæ´gÅSÝ®‘¸ÑÓ'ì|îÅOÉÁò°·é&UžÎx©I[)m·¿�qLë¯ëAåµvu’¸Ážê‡�!%·º¯ wWï©êf|“ÜNרëúïŒÊB9)?uϽ§¢Â*=�gnTݱlÉ ›:•X†:Lœ'ÝÏåÅáÓŸ:¦ŠaWF¶3º'ù&£²389—/ÇWc?ÆSc{<îœá¨â¹¹}•ÙTsë –—ÁýN9gç§‹�­ÃùuFwýŸœ•^¿n\:ý�ñ± jsc&9 ÎèN¶Ù³bïéÞØØØØØØØØØx0žžé®ÿÇ‘·—(¯×±[Š5QÞ˜“!} gR¦Ûí&ÙŸËåò�-ôyKIÝKDZü•þõz=~ýúõ'Üö!1â‰EÃ0Šy™²G,O—§ƒJƒ½nÜÃÝ} Ó]a?¦a;†*±aŽÕM,¨cÔ§ò¦¼ð~¥÷òòòŽévŒ?.¿r¨'p[UÊ7õiWVî·<®ƒ¥ä`#—ƹc–�~ÄkÕg–>îÂeàS˜íæ|«]Ýïé ®|NVfèñz²2˜êŸ'¹\_ï0aÇñšuX’=�‰É¼Á«¯X·SÆÞ�Ñɘu,w §äs+"+é©8ÎÖP§û(›F�W”¯Û>šÚ01ËS»Gý*Ù§+<¼Õwïéþ¸†­ çJç85Ù8Ã6å«þ³<“†ž<ÉèvõÀû»ñÁãx?‘a>8øpi÷ׯ_rMx:øÔ ÅëÎpã‰zªÈ0콓¶ /ߟ]R\]Ê]YuáØHuñ“A=Gœ^«íY•^¥‰[º—‹ùe7åL TN;½\‰ý19@i,q8%c×ïUÝa|åh8Œãvåse*�J ÇnŸÃß©‘¥ò¨{ì8¨zpÆIɉÇRNuËÔxíÀOÊoj M�ñsÙD)]‚ý Y•.cºg7éÇi&sádãôSßa£’ú¹§·Nv•–ou½bû¤y‘挣l1¿ßÁèÞÛK6666666666ŒoÁt;Ï‹½zÔÊìØZ%Ãôˆ/üŸØÅÂwl�z©òõõõ8Žãøùó§dëTÝà×*ùã",gz¦Xk噫zÃÿÌFñ}•ÞgÂ1†ŽAey:¬°b*üj?Qù'ÆFýwŒ?/a¦rpþÓÁ/ß¡<Ì´0;©NçaYSûá8ŸÉiÕüU¥Çú€ë¥Ã¤ž§}“óŸ2Ú“ºs[ªÿ¸mX÷ܧ§Ì²+Cbo1•Ô˱}Õ®n\®è Ìkr?�9®ë'n•(å›t3¦çŽ­t}2Õ·ƒcüù~bxñ×õõ”^‚󼊎c%±Ü«Ìv7ŽÔ8Ps¶’‡Ó™Œ_¥—UÛ([lºÝìYð´F·2¢Ór6M5é”J):ÃÚå›$N<*-ÉÉGªá@G£ÿ»ÏC+Ù*ìÏŸ?¥l]gf¥S†Sã¢ÌiàªçN§4:C»3þ'Fð™°JvRV ;e¤&ƒubà¥zR†¶‚s´95‰W·ueê¡óÁ÷QM–;KNgœ­LRø«Òrý„Ç[2À“ñŠé¤}»îäÎÇ¥­� ÇNÿcÚÊÈá-ÓelÌWí Wr;C4Õ�3î'ú8=wyu÷“³áú#;¥ÜWݵÎÉIóüåâ÷?§1ê€eèæ ¬Ü^Âé¥ÿu/å5÷SÛ§C “ô‰K‡�îŽx}Fìí%ÆS2ÝÇá=-dÁÝ �ìÁß{®òïß¿ßmÅHùN½?Åæ‚ÿUzèió9ݯ¯¯²¬éË•õµÊН^ná|ÌÞsÙ0 ¬ç5'VÇ1¦+L±K¯Sÿ™0>Ó¼¸¿vL¿c5x[Ô®ÍWÆ‘kcdŒ™=Ƹ8æ;ÖË1"¸EÀ�Þ’‚§Ÿ¸²§“lÜ8çòL1Åu}±ëWª]˜eæ6Ré³®2NV ’|œï„ywº?¥ÑéÁ¤·îYMp÷Ô˜Çç8×`Ÿ™ŒyÎkZµÀ׊e^]Hù°œÎ¦aÜ®;U&–-É�ì¯.}5—«ôÜ|ËÏÛ~ÚûxZ£Û½!ËË .œkP70•q¡º&„Ô)•<Vàîx*œ|ÜõÇñ~ÿ(ï÷ÆûnÐÞn·w'žtRÝÃ:RËFN)¡”GRê]zXv‡4ðÝÑk)�U¸%½‰¬O…Ÿ*`NÏ9SçÕ�¼Æ-%|*Œëï+Žƒ¿˜�š\:î#/Θ¯2¨4Õמɀø©?¸IN…©úÅ-8©Í•¬iü³¾SuQ'…¨~Çåá²M [g¨¹¥s^îŸêvÎß�5i;–ÝéH¾¿%C×ñ~§¼¥KÍIèÜ©r8Ý8Õ®¿'ÉóËdN[u*žêƒIþ©#Yés>]\U'ltOË–ÂNÆ«ÓÿßuO÷Þ^²±±±±±±±±±ñ`<-Ó­<$ö´˜™à%[dNðTƒ”ßd9Ƚa<}ÉÀy‹¼½$1‹(/Ÿ>¢>¢“^RÃ{×ëõOÚîDU>n—Ž!à4:/µcÈ«Túã äK ß ËÐaÂXW¸ +€H¬DbÛT:N¦I8Ž£Æ¥ÛvÀ,c÷6¿ZÑÂ1ŠŒš’7­²(VŽW“ë♊¿Â,ÖuÇ’w˜¬qYYNÖ_,�bPWW*0mõ—!!1´?~üøs ”Òÿ¥Ó nS9ºù¡Ã„iVý7Å™°ègʆñÜù÷x?Í;«ys>ie�õ%¯tiW˜n¾ãß銽úאּÑNκfûfjãÔ¯›ç§óÛ¼½äž²~žÞèV'…¨ýOŽ'%œÜÓñxn©…'pÕ©\SƒËÇûZÕdSaS=U•îï®´\çfÃË:6®8Î=Å+I±r|w¯› T™ºe:—·2:$ÁÅQ†Œ’UÝKíªŒ¸Ú’�ãÓQNW�Ü(ïévýÔÈãfâ,ðvŒ�íÊ·'É¢ �θP2¤úVÂ9NÜg”¡ÍqÒ=ĤLÎi¯y¦Ú�ÛÑ9"œ“Bu=Ç.måŸbUO&G¾‹ÏϦecL T׿�®šêb–eêø9C2¥<–ÔØã2aši p¸tÝÕ‹ê]ßàò9G]9ßåÔ’ÂÓݪá3ü"]ê\j˜2ªã9c? î´n"SJ»Òà Á9ÎÇ|ðSñõÌ©äÊ„Oª“©IJ&YÔä“”ûív³ÆÔjŸ©ôTê ,ÕÎÜ/”Ret re²ç|±®8œSîed×Ü_Íõ¦V’’lî?¦Éé)c0¹nŸsÒ;•—‡�í˜ÁgÅqSiM€ú?/¸²Àã`bt»8gœN5¹wFrÜÅ‚»ÕÈË“ñ‹Ï¦úQùLâ²ÁØÍ ˜~WÎíáž–u¥ýY§ž1�ŸÂ©ô؆8Û�'XÕñ*~²¿&õÈqœ}Ó¥q™éþ.Ø{º7666666666Œ§eº g·—‡f[:�*É¡d`/Ì-Ë$OO+af(©ädWìZÅw2)vµŽ,†§îqYS™�1zyyù�?Ö�c8¦^½«õß];†‡Ë7‘‰?ˆáÒN²:¤º_¹¯žq_sõÕ1÷õ ™Kw ¦‡'Wà¯4\>ŽmÅkÅÚ¨m|ß1Ý©Ü%?ç›ú÷´ïŸeº˜Ev2tíÌuâhu_Õ1³fÓq™ú{jÿN÷áóß¿ÿ÷Å_Ôƒ¨#WØg–»ï©o¸Õ½T�÷°‚Ýäâ på3•gÒS<—vÍG[»Ò.ܧ&z11Æ}0Måéàl¼ž2Ë« »*ç[׸»�ç‡ï€§7ºÕ p�‘^F˜L˜ÉøaúÛ^‚{µ•QãʃÏ�ñ£¾n¦ŒnŒSû»Q1tÊár¹¼Û «ŒxeLO ¿nÙÉP“8êyWß,ç¤ÜØVÇ1ÿZ–3r“ñ2…28]¸‰rg¹�CÇï,¸2©­b¬äÝKl©?²"OýFÕí�?Ž———xޏ*Ozi›åž|Û•kÅ¡R÷U¿ïú~éet+C«îsÝ£NI: 3Î�áÄicZJ&.oÉÿöööî(VÕ^J¯OÚ¨ A•†+ÓªQs6¬k‡$ƒë;*œ»ïtô=NCÅwóq—öĘætTšl¼213­×I=wÿœþ­ûnþQõÃqXþU'bo/ÙØØØØØØØØØØhñôLwçi)ƹ®Õ×îœw5].S2$FÜ¥¡þó}<ÉÄ1 )=~y˽–ê�Ù=<Žp¸b%ÏÖ±°g˜ÖÕx¶4ÅŸ€O¥IÌœcõ\Ÿãg‰¹Ye&lDêÜçÜJ“[1RáX>–S=ÃþÄòâ˜U§œÓíävŒS×Þ,£z6IƒŸ¥§7°ïMÆ)orGlâs¹�“�eÇ•=d…8÷B*–‰YkÖ実§>¨ú]Ç(»ûgæ+ŒçúRš[R_p:Wµ‘ªW–-å;éû]ÜÍYNw²|8�NÝèÆçêü9I_é UO¼•c2O§•.�Òœ†bº¿žÞèV®ÛÓ�¶—ð¤’ò«8 ¬€Ýþ0u„agVÙ”³€†QÛLpád…_®d£Y œô¸~p2M[]ø>ÖOš&ŠÛ¼›`&ç ¯‚û§79‘ƒ'/Wî¤dÏ •½®;+>9ÍÇ‘—G;‡@MÚjBIÆ^ãXT_}å|¦}ˆ LUÞTéþÄXá2³ŽtuËewçyc»rzNa8g@wïK°¬œg]»¾ÁN *êXvÌRÝ;c³›#T.¯©þR�JGÕ£k£„ÎÉa}‘Ú™Û$�|ʸŸ”Åê(/öÕŸ’1ìÐ9S|¯Ó.“¹f§Ó��¡ý·–ÇÞ^²±±±±±±±±±ñp| ¦›OP,žx ¼+żuìË�y*/L±#•§c4ø¦�Ë·ÌZ;9̨zÀ<Û[§™¸ò9¨:)w•ív,ççX̧å IDATPU¾•eÉĨ:9T·Jàäé¶+¡|Ž¥Hq8ÿ®œj|`zÈzâ– Œ›V§0lÇvã/Êàêñ &̲*ÄÁÂúÂçS6›ÓNL^ú�÷\¿Ml¨ëj{Ëêtu=Sã¥Ó;NfÎW�0“ÚÒ1â¥Ï{ëdêXÍ)[=E;*O^õàñ¥Úy’‡Su­ö4¾Òʦ±Âš¦vsãûIb¹Ï”5éy•çïäS}}œ;ùÒj?S‡d¼½½íí%ÿxbV S-A¨/ß¹¥Sîxlt+¥Ë²M'㊣–y·JÇå…u‚�7}ÞYë‘?œÃ2(y¸®N¹;9T>,C7©TyV éî9×cç )…;qª:ÇCÝç8g&ô4É(‡N�·¤Ð9Ÿ©‚OŽV'¯·Ëí¦·”°Âøl¼¨ä8§¡“Ï…Uí:éCxÏì°ü®^± U½‡ÿ¼{…AY±&í¯äÃ{¨¿�‡á.O$¸ñ¶:UM +•_;(LuOéóiY*­Ôþît—NÇ­ 9Iœw𫔬ŒÕ•öãñ¨ôSúÏq¦eÀkõnƒJ;éu.CgËpÃö’oat;O +]1ÝÈΆî¼T7(V™nVÄ\&î°îÅC7"PAñÀÁ=Ý.=e„ªÁ‰¬wG¨&¯¤xÐÁàpÝd¥à·cĪ&éO¬(”-k©�º>”dr2r¿X1°OpTYÒD4�3ôÊ`ä|�A¯dUi—ƒê‰:¿Y¥…F¥3ºÜdÏã@=O×i»6Rù¸¯Nbx&9’\ʸâñ?ùÂ¥#(œ¬Jg ð|âÊ…qKÏ;Ñ•§Ë£î¯èBDÒ}xÝÝ*~—v×ݘW환ͤOÎgçÃåÃ}ƒçe—¶º~$Ø®Jr+#ºdå4Ug‹q:lç•£ÍL÷wÄÞÓ½±±±±±±±±±ñ`| ¦ÛmÓè–»•XoçÁ*&Ú±ÛnIÄy¬‰Ábù‹Ir¬ßCÊkVxà�Þ WêØãã8ÞÉãNFárqÙp5B¡X¯ #Zù3Ót¹ècÆ:O{ Ç2NtþˆÒ”UWeJý̱˜çŠÜ˜Vúè�c�UÿdyT™;Ú­&%FÎiWøýû_$Ä÷Tdù“~q¬³‹Sp}»þ�ÚÙ� ÄõËã¯SÚårì6×kú@‹ZéHp§’¤}·¥ç' Byy["§?AÇLs¸Ät§´YÇ«q ¶B:Ý6)Ÿ[QèÒ›²ëÕ‡Óü<É#�¨¦úWšo;6ÙÉÒµ«šܸîöÇ«ûN†4>’m§Vò¿¾…ÑÍ�ì ÛÉ‘<<ɦ¼œrGƒ¯yÛ .‰ñD†i¹NÌË2…n S)(eìºcÏÜÀùÕu#j¯¥›D”((=¨ÒK†,?Sz]•C•U9ÊÄl–*k1ÿŠévËÖ*ßäÑ+öfzDá”UêØ×NŽ‘ä+»t•<®¯%r€:&’™nWw8>U3‰Ï:Ö Ÿ©±Ìã™\N‹ÇǤ]˜ís}Z1³õ›Úã«zTò¸q0e½ÓØÁ¸3\rOÆÄä>?s×éC` µj™ÆÏÜטÑVpÛ¢TÞiŒ(T,O×îÑËÃ�ÆÄD‡î™«G§ãº4n+ëÕÎNžÉÊÁDNµRá~9Üô´NÛ�95&&¶ÝÞ^ò/B-o¤møLíQT�î7ÊpÇ;£[)"%§3ø’¡ï”¦å ÛÔ©±~øë’è8¸½Ö˜vÌxšI哵«/ÞB’ŒÅN6Ž£”ªRx÷h–ÁM*iò›%ÙÓdÜ�×9>/ONŒW”[ÕQ=ãø]=pZNp}±âOûœ+-vL0­dàLÚ/ éÚµ9ËÓù–ÚcbŒ¥4Ó3žÀÕ{.)­’Aõ�鄞ڨÒQqÜøÇ1‘ ÖU�”ŒX5^ÕÂñ¡tˆÊ/96Nÿwpý6¥¡êQ¼© «uÎvˆÚʺeeY¸¾’ьת+Y1-—N —ÒSåJã€ÓBûD]Wìí%Æ·bºÕ¶µQ^>SÊQÌ�J[±˜¶Z’TL7nÛpL‰óâñúÇ�ïÇR*V¯Ñ w[M˜QÞ)çs½^ßµ…Ê_=SL7/ýOØè³Ìí=á]¾“ô+7a£¹ßT}§¼”,®LI6×oy\®Ô•*«ªCÇ‚¨°µµÄÕ#ö¹ß¿ÿùÔõz}—Ÿzù²ôLw:#­©û®lx=e·ñ¾c²ñ:¥(µ‡ëO+ÿ•l‰aÇpœÊêÚß�óÄò²NS/¤rYÜí×Ô\Ÿ˜ö¡³ »“Sé(Õ^ø‹s•ë“ÛÉÆe˜¤‡i*»ãLú]ýuHz~î·|�cDé>ÇÚóµš[œ]¥¶—|W|K£» &ô çNIH_[Ã_¨|ßuJµ�»®š€�¡ÏÏÜ©éX¿Ô©1ŽëàUWüoFšÌñ4µ_­Zb­r»6sÌâŒvÜÔ˜P'¡¸vå#1ëÚ9Е†z¿B•=µ‡I“šê÷ªÍÜøPcÇ"ê‚Tîɸ“8õU–/=W2¨ÿõB²ÊS±}n•£Ëß�—¯ê»cXQnîG‰sãÏ1ÖŠQVçØ+vNÕ�bMÕ¸T vÚNÇqxË ³ÛŽÝt,œjŸÄZº8(Ÿº_ÏT[NôzÝ¿G(¹Õ*ëGŒ{³­ÒâöOsêÕï:¶xÂ|:(V¿C•ûjJåtz"õ—Û#Ó6só¼ÊªÇU»¸9–ãuzG•Mõ 5‡9ýËm®^BýÛ˜îogt§Á�¤žá~L^^NËjØið>oÍÀ-$¼ÕÃ)%ËåSyqœËåÛ?ÒžìT—ø_Õ#¦ÁG²"SyáþsµÕÛR)tnJ†,ORæI±¦ºë&Éé2 ‡y¦#(�ó’UW?j¼¤­ØÎ*o%‹“OíeÃÖ¥ÁãĥdždýâxÅgoooö� 7iÖ8­0œçd2�ö-ÿªì<^™ˆpãÜ-å'\•…ãp>\Õ–]½)ý�Œ’î~g¸«¾Ð2JW%§@!9/ª¿»8nîKpi»´R¸Ï©´UŸSóâ´_¬À¯Ÿir\¿Ur©4¦˜ØUlŸ¸øI^7–• h‡ðq³ßßÊè>Ž�/»8¦[u–‚cºÕoÁMVnÐ1ÆÙM6˜žÊ‹ó¬¯è)ãUÂjbãÁ�<2ßè¥r'+Æ©²Ü9ÝX¾ £ ,‡r6&F7>?«0�™Èà”N=S2)'NÅé&O×^.¶¥2xÕ^ÆÏ˜„X&·¿›Ã$£²À/vª>¨äè^�DC·Ò«{¼Ü9qÎiRÉt¸=ÝéÈGÌ—Ë�/¨«zäøNn†SI¶‰¡ÏaÏîãNž“#íNOLŒTއ}/õ‡dXa:S¶~nŽâ|ÎäUm?qr1}§c™t[qVVuã$|7n]ºÜ7�>ICÍcN?qêÝ2fº¿;öžî����������ãÛ1Ý“%;Åt»%dÞ_”Øαí¼Ç9É­òãp‰ã#1\b£9¯Ê‡·—ði&œ�Ú#«®ÝÞP.¦Ï¿¼·¹ �É1mÌ2&ÆWa²’ÐÅ›0 ×mõù 8f߇@T¿WL¨ ëÀ}ºòäxnõã¹2(¹8f ‰Ywr©ÿ˜o¹rõ’î;Æ(1Ý®]ÓÊ„»ÇzÈÕ7÷ÓNî “öo«ø�ŽUsƒ‹ŸÀuèt6¯öq»$vÓëßÔ•ÞRm™Vd&õŸê.•ç8z}Èý›Ç¢Ò�ªï�aœ»Ý­x¤¹Áõ»ÕUÖ—S}˿ξquìòäúîl·¥DéåïŠogtóä®:G5*9¼N/Rvƒ’ÃUš˜oÅá<;g�'%Þr�ל6¿X‰²ª´8”�·š¨8˜þ/8ÛÛ˧êú8ôž|÷›œ©d89¸p«ñ�³¡ž9£„ëè3“3Îð¹êÃŒéÄÁy'ƒÕ¥�uâŒÊŠw_lì 0tüÔ}Ž31 .ýyù®Ž8ÿdt£œ8‹ª¯ª­pÉÉ™kJÇ:yx¬;Ö!lTLÆoÒ}Îv:Ÿ�E÷2¨Ê[ÝS}ÎéHÔó)'‡3xñ¿Ò¯.½dà;$£;•I�Û%…s†è4¯³˜8d.ŽkWu¨Áê–™TwI¹4Üö’¿{{ÉÆÆÆÆÆÆÆÆÆÆƒñí˜nçe¢GVž‘c ‘U`fL±£Šéf™8Ÿô"¥bªë~beUžUÅ c™8n÷"„*+²Ûè}ÇñaKË„Áâ¸ê…4lãôáf˜�‰ÄzDVódæM}¼§+G 3a#CÐ1 (·k?Lk…�QŒ(—ÇÛ¤ÏV“r1«ïV-¼r…/ù¡l®¾qübüTw\'‰aKLЄm=#ƒb¾�ããV!ÇXv÷”sýdÊ>ªq“äSi¹±ÌºØ1â©MϬ”a«—òº4¸ü\GNçs9°�[›ú*æïV4Ôu*_'¥ãVº>³lg^9ç¼Ï¤�8»òÅrÇÇ·Ú‚¿é°ŠI?IL·;Ö·òÅí%uÔ0Þÿð-�î´LwùôÞ^2=c™ :·l¨ }µ|“:� Ìɲ  |J ¢jÀb9”‚ë–ÿÜÿ´ÇïcÙÙIéN‘Pùª Ì=ãçݤ6ÉÓY™ð\š| LÊï« Jpn’ä}vJñ¦Érj@±!ªâó¸tûÏÑqÄ>uï�:TTgØN�JµG‘ϯ¯ø«}/ÝC£ËM~�è&WÕ�Uüô,é“TÇñÑèD=¡t ¶y'wªw„Ò']=² Úÿ«¼§Ggâ˜àm˜®{–ô—‰áôj2ÖV :žß&s�ë×õ�"ñR^¬?\MïOÛÂ�Ç«3®Óžu¼Çu§t�“ów'–|†ãô,ØÛK6666666666ŒoÇtÇ1òÈÜö^â“7ÛÂ^–:™„óQ 8o7Ág•'çëuö€+�:·»®™5ënåù+öèv{ž·ûƒ3ï˜73?Ž‘IrOÞJÛ1˜Ž±q,qÇt¥{)U/îÃ9‹˜˜n„êëIfn¿ôlºr¢–t¹]ÔyÜ%'³Wn\MÙÅ´³ÈãoU¾®OãõtÕb¢ëÜø¨ò¨²;.1�|‚ʤ¬é×#�-<Á�;×ÏŒùÄâº9 éëÄr{M_ÒtúŽç'Ob¤1œ 3•'!m)âvPs�’UÙŽy]™[]øTf'k—NZaÁëôL¥ëìÌ“õ²«£ªS\�BÖûobº¿¥Ñí:ÙÊ@àÓ/&{º¨È¸¦í%¸bÒÁ1}Þ*âŒR4ŒÕG8ÜÞ?•§2ìÑЮò¼¾¾?þ´Æ^2”±þqyßM©MpââÉgjÜ)cjÄ»4IÑ'%‡y°aƒÏp{Ñê^84Z9mvÀ¸�œ�‘ò°˜'·—K›Ç¯’ÛÕ¿£àÆüJyÎôÞ¶å>`ãê¤ËW…Kã’ã:]ÃåÀ¾‘–Ü»:š#É©`�ÈÿÝÒµSNžNV•6Ërz{œj#Ÿ•ž“‡ßñqõ˜¶›¸þãÊ” ÃéXêêÿ;�íʲ¢{•}qÖtsb’)¥Õéè.¾#\ÖÉÜ9/Ý6ÞÊ í¿é+”ˆomt'ö÷9c˜Y7)q‡ÂxÜY�QÂ{ ݾdÎGMx+F`&À¥Y@OϾ\.Çõz•u‡åA8ÅãXÁ̳ʪ ÷­d;£ i’LÏ:#ŒÃðË£ŽqÀþ\ñ’b¬ô°~SÿIîÄHM“ –çååE:Zžu�“!µ3æ«V™”ãçâ»6絩1�Ïy’«|ÜÙÜCáêë˃PúN¥=-7"�uq·JÃc~ l§d„pe|«v�|{ À/”»y£+çt\*p¿�Îc˜f§oÝÑ©)Íî^Ýä¾bg_8°ž˜Ô¿Ó�ê:=Sy¸gÊŽêÆeÜeh¿¾¾Þíä<+öžî����������ã[3ÝÉ#sKˆx�KoêC+É“tKአ®<;Ÿ=ufM:†ŸeÀò]¯×?Gðp=t¬ÊÀlr=}}ýó Ù-—–*Ÿú]•¯óê1L±�ne�Ù1%[ªfè\xÇÜ9¶V1 ª|I^¾§Ž\dùÜ5ËàVu8_Çöq}s[(tm‚}ŽËªöNËÀ²;p.Ï= ŸÀÂû~Õ’-·Ÿê‡,;³�(?_»òN˜NżOØöÄ¢)�‘d¾Ýnïöˆ&†�W3»>êÞJù(ù” ©|, *«b)][LóM}À…Qs ËåâÔµcWeãûé]°nu@¥¿ºŠ”àÊÊr¹•Õ¦ì6ÇSáPN>ÊU¥Wu­N/ùÛ˜î¿ÊèæecõÑ´½Ä-ç&5}©ÿcÞñû÷ïwç+……eMÇE¡±©ŽPë ƒ�ƒªß’÷ׯ_ÂâÉ«†-Ö ó«Põ�i©mªÍÕÝT&5ù»IHµ·3¬�¡Æ¨0ÊøÆúNƯÚkÏïF$ãZÉ®îcl¨9cЛn9˜Ç%OJ«™ ×A•Áí[TÛ JΉå�#–Ÿ+C¨ëß<OûŒ÷Û4fñzú®Ã¤búgÊÀi þçùÉ•ãó±€ø ¯SZS§mR¾Vÿ+Ÿ3Ýä^7VUìúɤNR_˜ÄOΰª/—>ÛuûÚ�ÞçÊ1žÝîÓïöö’����������ã[2Ý·T¬–†Ô5¾x¥^¤,(¯R±„õ e@9;±î+\±­xíd@9q‹‰óÂ;WÉÍ/.¦­&ÌÎ:9˜ááöHàçoooï–\y«‰cú\>¶–1an˜évi+VC}DÕ3ý|ŸËà‡¶?•¥c«k‹åf¶ŠeVc�óplMW–nud5 –ù8>žVáâ«ënµ¥k××CŠ÷xÌ+¶Îé0•6³h n{ajWÖô‘¯@¤ñœàÊ—ú¤[YdùÔÖ÷ŸóÄ6r+*ÏÉxSñ¦P:�™[ ›˜w¶Ü89»¢áòuσœÒqú$ÙK.œ“‰¯Ýu}–m$ü %n/ùÛð­�n×qØxåÆÅû¼ýBí•N�nÜ“­”>nO¶Ú×­äÁ´ÒÒ'o¥Á­+“N�8^sÙkðð ›²x�öO¯6¼¶î9§)íMJÛ¡Sdx­äqËr(WÉ­¶ÒÔÿÉ>àã8¤ÁÂùN'!n¥o¨ÿê,n%‡36:C7M\÷Éi¨û?~üøð•L΋�EN[å£ÚÕõAï3&>gd�©_gds·Ûmé,îz–duÇÄb˜”Æl@²ÃÒÅIùò{<.�t�dpÎÆªþæù¡Œ»‰£;éÏiÎvõ¥ÂLçƒUpcZ®Í’‘Ì×î§åŒu•ÙTN²Ñ­Æì߆½½dcccccccccãÁø«˜nd™ÝÆgåM1KÁYÇ„a<Îçrùç娒Ž<É ¯Z²™z©•ËZ¬.2ÝX¦3[{TùÇÿ¶šÔùÝxß} ÃT¸)CÆaÔò"¾Xré9f Óî ^NqaJî »¢žs8~îNëÁ:¨üÝK5œßïà˜3ÌÇ�¸¢ÊÇr ÓÜ17ÌL&™' =æÏg$»8u¿Û€rvõ39˹côY'©pSvT}ăÃâ˜êÂ¥ô îEúªG¥#;¦4µ †›0´œv={yyy§£yŒº±ít±›\_L÷:8v”ì¤É餾áòQm§ôNZùjTÛ»ºe=“ì"¾ß1Ý“p•7_§~„ã²¶–ü­ÄAüµF·Sº|] .}Ç-×ð#1Îíãgî¨3eTà/¦å&=–»ò¯U¦í.*�•{ظ¿›ËíòTKšÎèâü;#WB®ýÙQy’!Mاb:  Ü¼Õ„Ÿ¥-NJnžÈX¾éd:™8ùHNe�;ƒ»äVŽÇIý'Éëºq�ú–:…ƒóæöO§€$ãeVºEåŸú:¦áÚ&å«?Õ.ªß*™PGÖ7Ö½ÉxUiqùÎ,}w=ÎC. ê&nœüIº9£sê0}wͲu}Ç9ÆV9�Óq Â¢Þ˜êb‡iŸ8£+•Á͆¶“×ÉGMí*žs´Õ a˜ø_1º÷ö’����������ã[3ÝÇ¡—ïÙÃÇ7a–^¤tŒ /w&æ}²|ÃesK©_m]Qu…Œ3Ï•˜nf Ñf†^åSuêØm,ObÊX®ãøçóõÈì¨úÆ<+ml[UÜ.©~ Û•cÊ$ò©-“ÏLĽé˜'÷d£[¦dFžÇ\ÝslØÈ0r<§'Ô ÑØW™¥RÛ¾ðÚfÅuŠáÜ H¬«°~n·›üÀ•cƱ•ç„ycÖ’e@8æŒëû±ë ˜Þ cíÆ©kg5o0Jwz¾êG…ë˜î3¬ªºß•¥cTù¿+k’mnEÕË“+i¯†_Åd5€û>WLµJ+µYbÄ�¬¨ T9Žã½]V,÷ʼó]ñí�îԹܖÜGÄF .!ª EMõìåååÏbxf”qÏ–Áô)œRj÷r6d¸®]Új`¹Ayï©3zqâQÊFÉ“”¾rTžxÓ{yy±†uR⮎©-ùž ǧ•°2L²ñurü&“J2ÄX6·ÄíÆ;9j\¹r8Y§‡ªûÒx�uñ‡F=n R2©|�!Z×]yUx•vê <^Ô5CmÁqé«Sw8-g@a¿``}»~’t¾+nÞPåa=ÌýåaÇË÷¦ëÇNÏ©p��¯î;¬qI7»ûÊàäôx¤üï5]Ýaÿéæ •&§Ý]OÃ)ÃØÍÑj¼âÜW$OݸE÷oÅ_ct³!‹J×1Ýüâ#NönâP^aáåååݧÖ�ÑÍ™_¾ÂøŠÁv ¶ò*¤ôp`àþn•'Ö‘S(‹2>”¼hl8…ÏOBÔTº—]S8ÞÿœÚI„\ΑI8;"|í4׃ƒ{–Œ;”[küŒ�átF¥ªcçà©><™Ô'PùT}(Ç =eHMårÆB‚g“öW¡j3Ô-ʹSmÁ«MœOÇÇñáÈ1 “Œf,ƒÓuÉ0JúÑ�ßê舩8(—WéDÕŽSãµs””®rBÒ£“yÌ9J':§û÷e¤üÓù匾LΔÓiiŽUF2;¥,›²”í£ÊÀ¤‰³A”Ñ}¯ó°÷tolllllllll< Ó­¼³n{ z{ÅÔ¨e^fØ“D6¢â×~a”-í?çk.ïVL)?s[døÙ�?þë‡Ë;Ý>ï {„é ÷ûúúú�tKR\ÿx_yÔSÖ¯äT«%¿ÿŽûZ1d«Ôq”˜_�™—ŠïVC¬žá}fÊ\â:qõíÊ“àdgÆOp`GÉͧ•86’evýÔ±k ^UôñÚ…«2²\|¿Ó X¥«R](=–ÊÌéU>ÝÊ bዚƿc̹~ð‹vNÇr=¸²r=ª~“Z.7®,N�QLá\™œ< Nßrúö_Ééê+•!ÕMÇ�óZõNóg*G‚Ò']x•®³5ÝܱÖx=�ãê]ÙAJ6ÜÞ‹§—œ9è;âÛÝ…Ô‰xk7ôq|œÜù¥ÊFø õ"�ÛoÈ×J ðþÇ4O^ªä‰ÚíñÅpêÖ‹ºve¨ � §dÝr'‡+”Ã4Uäµ<›^ s˘Iy°l<9¤g]Y¸¸ Øæ(+;ÏS¸þ€íІBõ‹4vÎ(m×wÝdÁ†•s^Rd#_¤Tí¯úŒrD¸Í\>ªÉáuÏÒxIÿ9¾úïŒìÇnÛ€2 U>¼õ�ÛyRwø û·jÕïRûÇ!÷¿òw}UÅSŽRš?V nõÌ힤¡æË$Çqè/MNô­"I�IÝ«8…*›²50MÕ~꙲UÔ|€ÿÓ|ɲÕ;pÿ•ýÜDZ·—llllllllll< Ó­ÞVÇÿ݇r˜…pÇ«Uz˜6³‹‡åYeºs†yà3W'i»„b 9 ¿‰qÝòë„Ù¨´+îËˢáIK­õÙûŽ1PËy¼5'11Ša–ÉÉÛ…Q[\’ x­XOdò0ņTxuÒÎ=@YùãT•/Oâ’䄹™0`ÝJ�k5f9ÏÔG™ÍÂÕ< ‡W]ød%Õ8–Õ ‘ª;Å*«þ©Ø¸`þ» IDATP§ûÒŠÁ¤aêE8†bøÜ©$©�Ò¸œ0ª‰ýKaP§·X?¹í�ØO0?Þ¢èt·�o®cWß 5vêÚ1ª.�Žçb„[©pLpwÏé G�¡ 7+Sý4mKU_uít¤›¿yÅ_žÄí`ÝvÖ¿�Ñ­:—RÀî$“ãðû’”²rãóþhב'Ë7\VÌn’ç%q¥`0Üõz}÷ÙvÄÊ pù°¼XGXßÊùá´Ó„É{ò9ŒJ�ÉÆF’2f8~ROõ™¤T»‰g¢üX‰+y¸ Óí3NF•ž;½†ÛÌM"gò�ÄIõ­ÆÕqhǶÂñ}l/ާNàpsɃáxÛ˜’»sJÔ˜IõÃý.Õ_×—+?ìø®ŒB•Mé4W�,·› ’ñ›ðãÇë4;º#±¯Îè�Î�RiOóédpF †wH:Ë¥ÍýÂåµ¢SY§º'9)|?9 ,;œ“yÇéXõn„ÇŽ°D$£û¿‚½½dcccccccccãÁøk˜îãøø¡zQŒ·yàiÊûWט³·õüååå�÷Æ2 ÎË÷Êsw^<3ïŽÃ 2ʦغëõú!Ý{˜2¼æ_l >Ç81lŽ�¸\.òå´Ž‘QióVÕ8 ^wy)Ù˜éëàú*¿ ìÚŽÁ´q5bÂ4;6þ8þ׿\Ûrý¨±|Ï*�‹¯äæ1ÆlrA±”®Ž±]p{Éív{÷2¶Ãd¥¢Æ{W~ׇÕÿŽ-eLÓRPÏy±€ýïá¯zæÎæNìvÇ‚»­zJòj#1±�ët]Ú†4ÉÇÁÍ[œ–Ó�§c¡;9ÝÍy¥4VÀõ˜Xr7ŽTØ”‡Q+>øÌÙÇqH‰m'÷''#3Ýx¨Å•ÑÍÊÚn« *I4XxRÄAÃ�Z<¼\œ–”AÍ×¼= L6UÚ÷Ù¦åÑ©ñŠÿݲ(¶~)”�…$ j®ýÒr³*ߊÑ�éº-.n2ìÚ1奔_gp¥ â§¢sÆjû’«Gå,:cÈÉ�®SüT5æy뙓…ï³a¤ŒîôµÓÉd\ò¹gªNÙàÁþÔååîqý¹ôxŒ)#Ã1y‘ú —ÙµY'WÅq†múÒ/^»1Šá°žªlÎQä6Ä_¾Ïù&cqêØªg.þÔiV2¨ü ŒI{rŸ)fƒ·š¤úÁSj¸ ªŸ1ÃçÆ5çé ˜².³Ñ˜�?Õçê¾Ê‡·ÂñJEA­Mú1¯Š©¾�i «Xé´Â“ØmǨâÕ&®ï+&_mwš0ùŽÕ�ê.žÇ�Æš:å Ÿ¯ÈÑ�k§óƒ?E±—“¸jRa\|ž¶ìñq/Ò&†þ ÎÖ£Ò}ÓzTºý8ôŠH²50ŒÛv«ÚA•ÁÙK•æqüo>¯³¹___—gø[ðWÝ…š¹#Öµ2ÀßÞÞ>ì1ÅÉ�'wg «øgœpK“±+ øbÊÍ+j¼–ÂVŒ2¬“aÇqTYS²‡X–äõ*6¡ÒFÆß½¡ÌeO¬‡«>±¤Âq;q:Jõ[áy‰W>\[byÜÞx>¹€·%©•ÅM>,»c1nǺÿŽ)Ml÷­ªfu97F]¿U2¸ÿª?:ÆÛ•ï+fŸÇ¢Ó Þ"¦ö`cŸ›Bm%Ã:VýG…O{5U=$v»cÕ•<(wÒaŽ]e=Ãpí¯ÂT8µÁL'–CíûÇ<ÏÜs׬›T=¸±§ÒC$½• V&Œz7Ÿ§±ÇL÷*Òxéâ¹ð“¶äðI_ªp˜ßsÛnÓJ�…JO,ù/~ñ×ݼ �\4²ðœÈÚ×]ÀAÂiá3·´S(ã ‰2šyòå Æ)^6ÓÄÒåËFÕÍq¼7*•œ)_¾¾\.Î2ç2U84^Q!¸¾T}aÞé|Ún¯g2è+M΃óâý«x}Æ`qŠR˜iræ{§3˜Ô$ÇGoâXb�1ÅÏ8_uíʧÆÑdÒTõÆé!~ÿþýaÿ:Æá6WÎY¥ƒáŽã£>qrveàíc•v2Ô°îxüuý3õ±Ò•–“uï7uÆ5ËÍãÂÍ\ìÓÎÈà±�ÂU8_g;8G´ž%�­â8`ŸÁ{+p†ÿdL1ªý•ÞètçT—¢LfÕhWsÍ*¸+{‚Á6?«øh ©1ÂrÔ/*ø¼ÒÂ}ÜÿÕ³¹{{ÉÆÆÆÆÆÆÆÆÆÆƒñW2ÝÇñÑÃS/Râÿº¯â+-5¥%)µ%… §d1mõ«Œ©40]>ª\%÷õzý³§© ç”Ý,O²�’콫·,îŽ3â½n·” ž×Ë2&£Ô…cçÀõ»ÎXTò¤ s–‡ÏƒfÃJ>ìMœœ$Cšð”~ÎPSFwA½;PÏñ+”Øïy >cç%ìä:Óâí%ªÍ•#Ši`¹Ý«ì'|„iÉÁõ°â´©z¬²ºw2œQ‚é9#�ï¹>Ü�ôàÒfÃÍ•ùì¸çtø×ýÔÈuNÏ�“mVª|®¾\]�ÕÎPw²âs5‡ñ¼xz̧yŸÃ°í“¶– ||r�BÝu6÷õ˜@ÄÞ^²±±±±±±±±±ñ`üÕL·zQ�ßÒåí%ø5Fd–øÌnõ‚SwB„òþÓR:_»râ/³cœ§c#ãê‘—Y#Ȩ́íÞêǼ/—NáúV×UnUw\ß,ƒn;Ri0‹Y÷™ívìvbÄcܱ%(‹Jã$&1�ŽygÖ“W‰ÔŠˆÛ’¤˜2N±z“xø,­Ž0:¶Ž™{n3ì'ŽÝd½Ãc\•É•Íýçû+ÌdZÑÀkn”�ÏpWr:†Ç¥b¼kÕélû)^Áé·êp»½?¦c1œ’›ÛÈéµ³Œ3ÆQדønå#Åqú›W‰»ñ{–Áîæ.uÿÌÊBj —nk•Ó{Žéæqä˜î´£V_9ÏÚZ‚'–Lúûߌ¿Öè>½Ä‚ŠKícRûÃŽãýäà¶—TúáÂuûW�!;)k·<åê‡ËŒ2£‘‹Íá¸Ê(U LMΜO^jÂâ�‡8# •M÷59öh¢ÈT<‘AÅQÛ-œñª”˃u¢”¹›üT;0Ü„U²©7Ùù¤'7–Ÿ¯R;«¼\9ð~Ê×�;¬ûT>„3ȹýpl)G¿“‘'øT–ºïtˆ:­„ÇqJ»Þ‡ÁpèT° \ŽJCÎuÏ8]×�7Œ‡ÏXr¥[U=+j2PvNG¥ÁFÒÄ�võ žMâ`׿llò<¡dàq™Ê3™Ÿ&à8Ó:�Ô!Û쀹:NuÊ tcIÍÕÇñÞQfg�ì_¿~½Û^ò_Ç_mt«}Ó¬´ñ¥Jü¯˜ÜãøÇR{qÂTŠZ då¹;ƒÕy¬üßÎÉÈQa”ÒÀ ¥êêçÏŸÇõz}Ç,aýð£êÂP///ïönòäŒÆ92^Õ+pÞ+›Î!¯8ãPµ‹Sî\îÎÐNÆ�cŒ±>êz2)©xJ6'²„ÜŸœq·b|§IjbL�{þ¯ÒÀ¶ãqèò-9»ñÂý{â8TÚ];«û˜öGt"�~seåq‰ã��ça=`Ú¬;Y®Ô§”^Bƒ‚ûRg�ã3^ÑàøI¶‰œü¬Ë*;Zê9ßSé(gAýWy¨²ª9Ç•K—Óœêþ?Õ+ãª�W¶ þ{çºÝF®+áV,9óþ/»'¶':?æÀ)}®)g<“ j-/·úB‚l^ÀˆvбÓVãuö«N¾ÕBYå,¦ûw¨ŸîÁ`0 ƒÁàƒñK3ݲGºZdø@Çt+ƒE¦›¬Egî,è}ßëÓí®¹çÉf¤c•­cÔô™ú¨�~XHÙcçÎô5}¦®¹²®ºÉŒÐêàÊZu¯2¹ôÎçó›:é|�úÁ�.üŸ+�ƒOYS;¹ÇôÙ1jd·ë˜¦Æô¡“Fexs·zNŸa[ë°S_Úîu¬¡EEïO}BŸat�N¶Îú’˜™oÝ WeÝQ$ÓdãL¾)7!×qÚ IYÝÃM;ò¹É5•õ‹ç:wžwJ}–]š.Oí;IéÖ6èòÖtÙ_WJúN»â½�O·>çÚ³sQYÉ�H ]¿TæÅJÛmJÇÝGå')ü©¬ÚftoJ§8î*¼.�îºË««»�Å1ûö’モ7�¿wÁÂúÕùåžçS½&82ê8Þú¯sC?ïWÙÝq¥so?õ®åìÞw"™‡*ݧ{0î%ƒÁ`0 ƒÁ‡ã·`º•)aè­:_Îþn%HÆš¦ÞÄ`¯BÑ•ld�;“”žKé¥ã”¶+ËQõ–ØH2ÝzŸºæhh&LL�šÁ”½s»×y\ùè;Wö›Ç޽'cÈè5ZWŸ]“-P¤kƒš¬#”c‡±ri¸ö­_-Æ2…sV&'ƒûÝÉÝ=¿‹ŽÕO,^bxÓæÌªú<û%û„¶ÁÄt³Ñâ“Úe¨ü:›eHåwm†LY²²-«|l?쇩:y ®¿9v6Õ‰«G^SV¿¿W¬ðª¾9~óšbg¡5"•OŸI}ªËGïa4 Z0î±Ì¤sš–+_é + Ij ÷ÈÀçS»OVBM¿+?-FN×qi³ï¬ôe¶+\à® ßï€ßBé>Žã�²WÇÚðœŸÓqܺÔ ”L¤nvƒ ÛÊÓ)áúl�ƒƒS8�%ùœr^i©|I™r>Ô>«Ò„ “•~~Þå[÷©2­¿“Oçw[¿]>Ú8 tŽ*i ×A­Ûîþ×}t¯Ñ<]ùô>78Ri:Ž·á¢ô']@¥÷¬uÂ÷@tJäîä¬é¬”^K‹E—¦¶Õ’RûHJ[ÇçÎÃÈ=, åKåîdpõ¹sŽõV{?ÒxÄßÚGÓøHÅLû,eá>½¦i³Ý»1¨S*w/]¾ºÅâêÞãèû9eHõØõµ¤øSçÁÕ¢ñ¤úÑq‹mæž:®ó¬—¤wî‚+%yõLw£µÕq׆õ¸#Œ4½ ¨1ºcÜKƒÁ`0 ƒÆoÃt'ö˜› ÓíVþúa˜?Wânºã*p/žòI s£¿;—2UÑ„Œ˜ï.3å˜eçj¢×”ý¥•AåÖ|Û¯ãèÊLV^ËëòuìIbQ[ãÌ¥;ŒšÞ£egý¤èŽ¥\±*dþ:æh‡Aã}ІÇÉ—�ú#Y*-_çÊ–Ú ³ìÔ1Ùc'7­7©]°=2íÔ_Rý�ÏçèΡ²%–/¹ƒ¹¶åú|õƒ´¹Û•»ê{—µÝ©¶é�¾¸Ê¯»Ç]ëØß”6ÙpÇœ»gVlµ²°»¬®c–»û�Ü”SYo–euÜÉãÆ^gY õƹ12ß”ŸKÏé7ÎJæää\E¨«®2ÝãZr‹ßNéVÅ‘�:}®ôëׯ¯ÊcuUºu2t¾Ã.lZ’-)×TDˆ•Y‘é%e¦K; n.­zæáááµîhfJƒ+ËÒ…[Ó´œ)¬îs #F"áNu7ÀTº•÷ù|¶Š¿S\Ü�´O'6Ñ!µ…493JFšhiZ¤˜”»3q7¹«¶*çNÚ»÷R)YMJú '¿T.üxÍMî5ætmÈÉëÔé™Ôt™I“³¶Ÿî“êìÏNé^�aÝ8V2h=°Oq‘©ÿW2×ó;‹3}ž ¾Sø\~)BнpŠèj±°3ßðw�sqèæ«ü˜7ï­rº>梕è»tew |š/u¼MʹŽ©Ý+bBÛ:IFÖ�+Ç×¾¯×ëëüþüü<Ÿ}o0î%ƒÁ`0 ƒÁã·aº 4OÔÇ_ê] ¦H&ŠŽ=TvW¬dtƒéXǾwé‘mwæd'»®†]üîT6‚¬Y±ÓÇ‘#8Yõ5‰j\\=ÖçɆ¨¼×ëÕFjqLw*¯cñK½g‡9Ûe]’,î9çR¢Çîƒ"‰áÝeeõ|Ú÷Voõ¼¶õd¡"›éÊíúQÚp{Ç͸£õéúTEŽÑo¸t‹5]1oŠö[ËçÒH®&dÊ’,´n踼b³Ó9~¬)¹«¹ö½Ê#µ™n\æøŸÚSÊ—Län_èênÅt»ü“kgÜI®}«²tÖš÷Œ :¦§z}ÏØ›®w ê$‰%^ååØrÕivÝ>ØSûÔ´õc8³‰ò-~;¥[µvªjœê¦>޳ ¸úØCç M’ùÔMâzÞ r�M?çdÚë&€EŽ Upy¿“Çur½OÓѲÑmÄ)Ó G¨×ÒàRçu ¦›…ÖÏjÐfÒÕÃÝ»šh:ÅÉ¥ÑÉ™m]L9y’/b§ $?[­ïäÍrvH‹Ò„ºïŨÚ`Z\³=j}é"NeÐÈ1ÚÖZ?®ÎîUºûYîXëà|>·é%‚€fñäj¢ù:ªþ»Et=Ó¹’89]$…µ««�Ðî{éäÝÁê�Öqê{ižâ¹•ÏòV‹°VeÕv’úï{òêæsW'iÜÖÿ —ž.^»0�Ú†9?²}W>)bɸ–¼Åo§tÇ-ËÁÀ­up¨M‘ª| þüülYïb2\cÕc*Ýé>§Œ¹ûÜÀ˜”ëîù•âß±T¦5\˜®‚“ŸóŠHu¢Š67bj}ë}šŸëÀS¿Ý5·É²S€¨¸kz®¬)½]6Ä=§uçü¸yÌt3¹’1)+z-M~]Ú\T¾÷Ö±{G:ž°Ü:ºÐ‚|'´¥¾“¬»Ê/Ïï*z_õy†íòï”î4†1ÿ¤XS·1Ú‘iì”c=—ëNQçóI±Ýé;´:QÞDt¤w¾êÛ»cƒÖWª»ÕB¥#)\™8®k¿ºgáÚ½gÍß½—Õ¢Ò�õÃçœÒ�ö˜ð7û‘«ËJ»”n�ÓýÞñöWÆøtƒÁ`0 ŒßšéÖ¡cº�w¹œN'ï³Ü1Û µ*uLŽ®Î;öyÅ€$3–š´¹"×gW¦,ÊAYëØ…Q$ã¯é¸•·²‚ºû]„ú¯Ï¨lún¹{]ìÄ.“ в&_òÄl±xœÎ‘êбVzOb7vX�Ĩuò𸞧Ï-˰Ãt®òwu·b‡w™ogR«ËðòòòÊ Óº¢löù|~e–’%§³tã‘ê'¹Ó1WžJ×µuŽÅiŽëZß�«ˆkÇt¹ã<±ªËÊ_Û®»¯ëßk¾Š‚•°s_W6÷ŽSº“�ŽÓ»ãDW_»V4½ß1ÚuÌúvלdG¦•æâdÉ¡ ©¯2=µ¢¥=U*+ëGçA–§òш%ª; Þâ·Tº ti Ò­ao’ùW•n5ŸRYPŶ“§3)¹ÁgeâKipÁ‘\v:ºÏ옺ÊDÞɪpiÇq£0'ÿ1útëÂHeRw�´ÕÕ™bÕé+–�ƒëU'~=·;ÁìN N«/®vþÄII¦ü]è8*ON‘|O9W a·àì¶]þ;‹ÊJ[Í´Õ/—‹Í÷z½Þì%¡ï§[üºã�…Új±™ÚtAÝ“œ Œ�®×k4…wãcRPÝ{v ê4†ÕïÔî´O¸¶ë�úrR✢öQP¹9Žílvt‹)UöVi°ïðw§”ºc}f5.w{rœÂËñ;�qnžæ"“÷¹ö½zïU¿ìKÇñ–Hdùõw7�i^&ðÞMš¿+ƽd0 ƒÁ`0ø`üöL7͉Êzº�¾d£•É9ŸÏ7‚ÑÕbb*¹‚ïV½‰…azÝÊ;1F)róå5-_2ç¹|ªî”ý×r§0Nõœ+Ÿš‰ •¤3�©ldx;¦Kóaä'+™­ÇÎb iP–ÔN«îîKeWÖÃ1IŽÁrìLb SÛê®ue]±Blß̇ò®°b½³Åv¡L·²ÙdqùÑ)gmqé;Y]ßeRÝÆqm'Ü<™êGë¤ÆÛ�0�|_«±�ò¹²Ç­Õ«Ú‰¾³dña}×1Ýé8»6M9Ýó®|zOê‹iì �'¥íd*pþtyî2çÝšÆ7͇¿Y'Ü8ùžq @ Ç07SOØí‡©=éxÒ}1™uçæ;Z[¾~½�ö¦ù 2~k¥›©þfc¥î¾Ä¶ ˜&Z•g5Àè½îºë®ê|RŒÜ"À)¶)Ÿ‚ó‡§â�ÿTF7‘©Œ|/š¶*<N~+eOŸY-´ØNº‰ŒåK 0eqçÜ„¬r»EA23º¨;i¢ÞQÀܵÕs©®Ý3L7)g ®_Ô³®MÕo·øtý×})Î)ÒêÖVíÖÝçLÉ© ]™ºóIYÜñ«.pìuäC—FÊË-XÒÂMÛ:£ä¤þÒ)t7^jÙRÚ ;‹ÊôÜÎ=®|÷(Ú…š/wä; ¸»¾[¦t¯?¾GžUù\t´”n'•v.`“›V×n]_vò»0�£t÷÷’Á`0 ƒÁàƒñ[3ÝÇqëÒ +D5�¨y¬VŽÅDY�IKöie"U9êø֛ǎt&-®”Él8–|Åà®ÊJóÝù|~½v>Ÿß¬ü]~d¶ô~4GËDF>­Ìëý f1ÌŽýqLgb½´ dÚÜ{quáÌÝz=mªc÷^+-·c�¬™['+óÙ‘Á•Õ•ƒlÍjóÏßË&Y“‹Åqx3uêoumg³“º­Ü˜RßqV‚]FЕWeè"–¤ã]¦;ÉÖYDR´˜Äø»:a~IžT‡«¶ÞÉàê YoV¬µæ»ê�ÝóÇqû…UçZq/º|Wõ™êÊ=¯ãÞ=§nó¤×Wsñ= %Á¹ÉÒ�¶PeK}Y¡ò¥`ï‘ÿwÂo¯tsòsî%.| NXn²Ñ�^Õˆi®t²èEßO'7ÿ'åÎM©Ó»ŽéÒë7¹RÁШ)Ée‡å£2¾ãcìä;ÿUÌäK®‹ý�Þ+£©¤‰¬›8Ó¢‹Ïh=êu•Ç)Ìi²qJ¸K{Çü¯ÏìLŽDê+uRè]:̃‹œ]pѤò¤>Ãrèâ^ÓÐcg´m2/ý$¼Ë3-€];Ñ=*;Ðw«~ÜnOÀjIsûê½t ‡Õ"ˆåaßqe¾÷Z�Ríº¸ð9—~ýïÆ7V¤1Èå«Ê÷@­°šOºçvÒN‹�4n8wµT�|.É�c¦uïxD·Ý¡ºK·XqJx•‡s�~î}ÂÞ�ß^é.Ôä§"…ÔköNÙ§Ëår<==½>Ÿ”M'Ç=+`wÞM<«Ó¥ÇyRÚ8!¤‰^ÓªÎì&Aeºkv ‹>× \n ­óŒË]÷=<<ÜȦ«\Aæ©Jw“ÀÎBÆ)ðiq¦eK“.•l†yset“±k'î÷ÎBµ%Þ×)Ú¬ãTß.ï{ Êp·HM}¹ÂYº÷Ö-º5¿´áRÃij^”� <ïnaØ¥A¹]{q~­Üðżv6K¦ûØžºóLñ€ IDAT¶ÅçÓxÉ~äÞ•>»b~Ý¿îKm5�ì#Ýxõ¥[ÓrŒ*Ç„{ ;瘆›ûº1#�!iÁåÀqÙ-´uÎrý`§Ž™v:V+=I¼”.ë«›«œÒí>+?ðŸîÁ`0 ƒÁàƒ1L÷ÿ£Vçêî Kè»”" ¨‰µXðçççvE®ÐkëݱjÝÊÝå³sÌ|³œØä•_k•µ n:tçqyWÚ‰9Iþáu¿¾Ë•i�ÑMûß™'ÉwfGWÖj§Êˆ¹rkž%[jlÃŽéÐô];Y±Bl;‰ßeôvêΜÒÞŪ½è;u¬óM}ÄëWdÕ‡“÷u¬j�Wfšaþœlîz²Žè3dùÓ½bûÒD‹M¡³t$«œ¦WÑNväsåuHyumºc†wÆüÎjÔY´ºÈ#ú.]”Œ®+æ¼ûíÊÇk»u¹»ûuÎX•+õË4Î'yë™´÷‹úJzls‰éV(‹®.%:î zŒÒ-àF§t—¿š0t19Ž¿êÚlùåË—h²«¼ê<'Ÿ�Ž™”ø]e5¹»I;»¼ Ý&ͤЗ+‡SŒ™˨.!+ÿîºßù•å«ý¦#*dI‘Õò¤zpõË ¡îÞ´hJ“J ¸«Ié{X'ëî¹Â*=§¬¤²Ü;i³ ²îS_æ~}FÝØèV¥J¡~�’‹7m_® œdwÞÿ* w•[Ž£ª€3m­“n\Ó>§åÝéÿ”9•ƒJejs;Š'Ëê6®ŽïYˆv æÎâšïD]‚î]”$tsÉnuJeº¯;^Õ9ó¡¬Ý\îÊÑ�ù¼Ï½£RŠ]¿bZŽ4§U­ùOõ¢q-ÙǸ— ƒÁ`0 ŒaºtçP¦›»�õšF´pî%çóùÍfÊÄÓl”VÊ 둘˜Ä,Tž)šÉNÞú|—7ͼÊÒ©%!AŸçÇCtï6´èoÇ;vTYFŽLYÖI·Ùñ8¾¹»tÖ„¶§k3.J‰ž_¹Mè³Üèªù%fm7í{ÑY>ŽãíWCwX —†c·ûX¿éBUç]û*(“H&JËZm�‘•’©ŸÌ–Ž[dïv"‘°h9ÓøÆÍ“ÝF/E*Ob‰¹q‘itì_ý×:®4™Nµ¹ëMÊKÑ1¼‰ñ%3›Æ Çä»ûº1$Y*:kRÇTïXKWØ[îa°]ºŽf_Nl4™îÕ{VtéÇ· .zLg HL7Ç¢&p˜î}ŒÒ ¨Â£#™¸OÄÓͤ&¡Šd¢ 9… ;Ž[óëŽÒÝ 4ìp«�–Ê MWêGšÒX�Ók.:ƒËSë¶›HꙤ4r`LSŠjR“¯º»èW5uNƒ—þv¡‹6áÊ¡Ç+å¶«Í“;ðS¼bU^;ÿõ”_WÞ«åÓãn'%E’ò­Â2Vš®\𶫝”·î!Ðo¨ 5IÓva+Ý¢’íTëȵ Í›ÏQ6–1¹f¨çÒX-2»ð�÷(Æ®}ºyÇ]{î¬陎%LÖ­tÎm¢TyÔ=ÄmΫô4ßÄf;æÛó¿«7ž¬Æ²™É’òñj�lÇÚ¶\xŽQ®’œ“©ï&õs—÷*½ŽyM÷ñ½¸ô )BÉêy7ï¤ò¬Æ‘®L÷œïбÜ]œxÎßz_ªm7�›Fg½¡>ÂMÉ%_WV[_ózyy9žŸŸo¬þãVr?FéÐOÓ‡›Jw«„š|ŽÇÇÇ×�åtJ‰v,v=Ÿ:­¦Ù .�âà&0ÊšžÕrt÷¸c—OM�ÎÇût:½Q  ÝÇ=R=¦2ªŸìétû¡5Ùk›q!Wƒ=ß¿„<9Q§ô\úUÎô^WëyU*“{ #ë8…Þíx�Ò�®í€ùPÁI ²î¹±‚J—kU÷FFayv®w ]Rë¹�}*;J7Cåî.zSz<Ïy+�;Ýow�ï±S>U–toO8~k_våÜYäèuŽù:�ÑÏú=î%®¨ÛWŽš×n¿|ø— ƒÁ`0 ŒaºÈ2«YM?šv ssÓù|~ý­‘L\ìÜÓ}/Ëà°b#5Ÿ#ºb‹�|÷°æ¬#·"gô]ɧºsìN*“n°=Žo±º/—‹�Æ Ñ\™v@VÑ¥Åòí¤Åç+�º¯Ût©é‘áqu·b¦RÛØ©£nCbW^>“>2D&èž~æär ?û˜FCÒr(ËÅè%zŸc°Ý†We¶\Ù4 =ÖëdȵL*w*+�É`;f¹«ã]ƹc:w¬¬c½'õîݧúÚ‘™2¸:H1àݱ»æÆ·Ý>êÒOèît÷ÎRÿH²9öW±Šw¿jß»pºA½—6£ˆè{bÙ»ãd©J‘ÛÆµä}¥»A5®OŸ>½*Ù—Ëå&@<ÑkçR÷’óùü}àùùÙš‰¨kÇJ»•WtJ[ïÓ|::'™si¾u“¬Ë‡÷¹kI1tJzšdvCW¢M+ýH‰NvZ^ú”¦¼*MýÏ´ºrhÝ» IÛ–ÊÖùM'…ú|>Û¯´:™vÌ»©\ÝDŸd£RÃÉ}¥2=¶9ï(m”¿®±�§múŒ+KZ�QžU™èîÂg\;£²¨y“pêÚsRÞ£ˆòÜÎ;[-˜w®i½vcbš³wQ NM�éÖouk¤O÷jÁªe«>®÷iÚŒV2J÷÷a”îŽé®F§ Qre•tóßóóó«Ò­!çC¤�Ö± TŠ’R¡`Ú«�HÓÞQÀv˜§(&…¼l’¡²q@ÐÉQ7¦Átw²ÐçÉ‘1N駉cG¯ßnC SàC§ 3Óv“;•ˆnq–°£@W’Ò¤÷ï0oÝQÓÞÉo…ÔXWýõ×M›LJÛÎB›ÊôqÜŽcî‹«É7›2èµR¸Ó¢Îµu7ž¤‰›þç.ÝN©IõÈ÷›ÆÁîýò~.À;¥9¥woŸI„ƒ;ïÚwg9¥B—ÆÇ$·›tÜØ-k×Îõ8õÙTW)7?º±Tórs“Ö×N;ÚiÃî¿ æ�Xn-“;¦Ò]ù8]gÂ~Ƨ{0 ƒÁ`0ø` Ó½]=vL7™ÎBùsÓ]Ì÷q¼eºë\ýN¬� THÌrŠqtÌMÇ,¾gåžž_1ÝZšºé‡}oÍÁ÷0gî÷ËËË £Xm¡BvŒ¶K—eJeíØ?ç«[ï+™±õ˜ìHb3“<%Ç=p¬|ɳò/w²í²ŒzïÊT½ËЭ õ]®=é](ÈX“•;Ž[ [Eè>ŠÄç;“½ö±b¹“õeUþ*GÇ”:7Œ㿲VUù’…,¥µº÷8úH&kªéu¬°ÊÝYÍÔ½ˆò¤ç8†8—’ïiÿïyÖÕñª�êïô1+ýßµ[ݳÀHi½gMj¿Ž)§•ˆÖw·÷‹ù¥~N–»Ò©´Sd”Áû0J÷ØðT¹z~~~U ÙøéÓ­n(>°óKî%ªXí(v+$åŽ&Ä•2¼J›URuà¹çë}œH©Øð>ú»ÇaMgÝä~½^_ß«Nº///7±ÙO§ÛÐ]š•§ô>ùnµ $Sªš“©„« š6]U4 §Ð«Ë�K{;“,ñ=“y½W'Î$½2ïBMêÈÖ5§€k¾5±:ÿlwjá—6ҥɘÿ�Ò­ IaµwŠCªK�7®÷ݳ0NíÉ•—ϬÆÕTV�ýÎ:vrî¸hZI>MOÛBÛ™ßK·°ás,KWŽUšŠÕ"§»Ç)’zÏjÁVõèîïÉß»Há{àyçòÊc-§[Dó¼óçææÉãø¦tÿSäÃïŠq/ ƒÁ`0 >Ãto‚¦] j$“r!Q¶ "—»}¹\^M€>Э�ÓÊ–«ë€K•ØÑÄ–&fÚ�w ™2û«|ÈÀiXGšh5<›¦AÆ›l=™�ÊGÃB*ƒ@6Ó¥MÆYáe*\=v,º2ï,Ÿ2*É\KöTïÓH&l«»lXb"»öö¬~'†{ånàžïîÕzØùèMj'�©[Û‚nØv2tfgw�–²h.|`W.öå®=ï°µ»èØ¿.m-»Ž5ìcdš]Úß;>óš¶ß’mÅŽ—¬�‹BŠÁ&‹~Oš©îÉú÷Þú¼'¯­0©NhíHój²~ë{I›'Ó­ùwÖ-ÍǹÏÎ&Ê£to‚»¹UÑRW“ÏŸ?ÇñÖ7ë|>¿*xúåJ5£Ö½ÎIÓR2Ù«Ág羕 q•ÿî Ôå�ɤlRùpù”RÜ™ �¬©®t°:�N7 *ä8³ì)¯4q;Så£n ©¬š¶*„ÇáÝmêþ¤ ºAœy¸|v”Ó½} úZš vÒaYRÛ<Žoe`ä.šÝ;Ò6úHåÓ�~…ôÙ{B`�†’”šäß½Zh;Y8¦%œclW–�²¾g u}7™íÓ3zŽí†ãü® l߬»¤,Þ£ weº÷–mwî*ì>“æ >¯ó,ëQ±³Xáó”!Íí”Å‘pƯòbÞ”AÇoŽ+ A¨Çïyσ[Œ{É`0 ƒÁ`ðÁ¦{µÂ+f[ÝŠÝ|zzz½â8¾mn*ד§§§¦[ÙQ2Ai3w8;“-å¿—9`ÙõØ1VÎTº2o¦´É*¬Z½§˜CÇþ*#Pl¸‹‘üæçz½Ý §ÿõ£%Êrp“g*[b/´,Z&æÃ´•5Y1D.†÷étº)+ò1ý[Ê ÷0ídzÝ}Wd£UÖ[êÚ÷n^nST'v‹Öe­;¶[�—;YŒ˜–cº�yºÛX[ù$ ¯±NVïšLdãœl�EÂÕI’›õÈ~Ðõ¿t¬¿iMrÖ·®ŸwVÎ-÷²˜ï/Wc~É}ï|µãÖEBJV'۪˫K›÷§þ¯ÇÚ'î‰Xâd ¥²Ò©´�{ɸ–ü3¥ûN0lNŠdòøøøÆô©!õC9úCvv×¹]‡ÛQ6ôÿ꾄NévJSzÞ ŠI!ÐßTR�ÜUWTª <4šÉŽÍ“i¢O&ñJÃÉÆwÒ)`�‚áž×{™•�TwzL…‰÷Ü£¼nA±«­”î4AvéêB¯î£ï'åvÿ;¥;õÍSˤ ‚ûÈ—Þ“ê$ÕiZ˜vJ7•d÷<Ñ)¸TüÒG§Üó.ÿ´¸Nr:…ÎÝÇ/ Þ«p;¤z¹÷žn bZ�r¾3é}®�;Û³žßQ~y/Çå´�¹^¯7ï,)ݬwÜE,Iî%;.~ƒ5Fé¾×ëõfCÁÃÃÃÍFJ=VeZCyé¦J�ÙÍ/ûU~•†'¦[ó¹; ïëX ÷Œ›<ÓCÏ;Ø:ŸØ¢c½�rÎ�,…Ñ[)¨ªl¯äéØŽÕäëêŸí -X’‚C* —�¾ýR!ów *摘BwN"-ÎÒÕÕ�¦·« t 7'\íÏ:¶¸´ê÷Jù¬~©ò;¥ÛMÒj9qu§t+Üx¡é¹°gn\XùÍV9]=¬qiaÃúqJÁ1‰1ÓSùÜ»tãh/ù¬¦ëävŠšbÕÆ»2쟾¢èÒîÎ¥ù©çWïá¸=Z<®þá”î47ñ·»E¼‡˜Í“‡ñé ƒÁ`0 >Ãt߉b¢Ôw[WˆÅ`3| ®‚5d`}­ò8nÝF*¯BbÃê¼[¯Lj+™•iÇLHÈqU¯ŒƒcgÎ[�æ_F©ëj–W¶Ú™4;Ó£cºµèƒÍ4:Ì1�¼Ÿlw—o]Oï‚÷9¦¥îS³lÕeµïdÉI'?áì„Ô&y¼›¯»ïÞvéêauÿŠévV7Ö8æ?±Ûü �s=!:Ë—–›uçÚT¯ŽåV¹ù\Oºzä½î>½×…L²;K�Êþ±ëÂ:vn ,G'[ºÖ1÷;`ÛZÝ«ÇïÉËýÞ?vË·jƒn®çûÒë)LàjŽÐ¶“Üe:÷’q+ùg1J÷;p½^o6¸M•ÏÏÏÇãããq+pL7U^.—7_y[ùw9®Îty÷MŠ]¹�‚Ù)ù» «É—ŠŸ;^Éí¾ÞwÞ£òÕÏ)³Ì»ŠQRL«mìNÆÎLØ)”››µNÒÂÊ]s÷¹Í£ªÜëù´°L‹˜zÿ }˜°Û–5m�twÌÚ«sIŽT¯I©\µíNiVÔ¯ßm¸¥¼L#… LÊy*3¯s³¤>Cwº„ÔnÒBØÉ‘dMýkõ^VJɽξãäáïN)>ŽÃ*S”)ɺêÿ®½vý¤ë/éý}ºyì8ÞŽ é>žß)C7÷Q™®4ªX•dæåæŠ:îBË:÷’ øÏcÜKƒÁ`0 ƒÆ0Ý8_^^n¾.©áëC9åB¢ †º—èóÊFéJ–+`F2qLwZ©‰5©çWl†;·Ãªw ýJfw­cõ•-S¶Ž›Õp>ŸoLõ»2�N>º†¾²*»¾s·qr‡‰ëXŽÄÚ'¶5±u%£²žn³kW!³¤å¦<;V”]v,•cõüŠñéÚǶ²¸ç\Ú+–�ï›cPŠ€BS¿c³ëXYðUYY–®¬‰ýO﫳ú¬,;àøDk Ëàduò²ï0=–+Y¾’[bZŽמÈÊwï²c³Ó<ä6ì®Þ•ʰúq"¥±3îZ:x̺Ji;K·cºS=wL·“§XneºÕ:2øg1J÷; �Aèׯ_m$“ËåòF�ÒH&¿[M¸T¦¿GéN %‘”ìTÝowšD:¥»[Hð¾ãø¦P$SZ� ƒúçT„“�iš0¨HjÄšzÿLCÓby:sl7«K‰Æ'W°­uñoõym“NQ«üÕ¯Ø)ˆT"ZÎ-$8!vJÄÎ9MËݧגòÚõ#­³äwïž[¥ácêÖæC,c2Ió¼F©Iõ­Ê=÷ŸhÜ|µ¨X�ß}ÿzm‡¤ÐtÜ¥¨iûv}=-&œÒËû´~©¨ñy.’Ý5¯J<ïÚÅJ!\½£E»{>½ãîÝwŠy—¾>ŸÚ7•k.šê?ß­“ÇåŸá:^ë>5UÀ¿§®ã^2 ƒÁ`0|0†é~'”½©âår¹1Ñ(ë­QJ”eÔM•Å´êÊTWœš§²ájB$+¨Øan³Ñ±›|æ^8&Ÿ æ=lûq|«e[ô~²¨‰ PæœïÄ1K+9•�¨ãççç×´4b åfú;Œ?Ó¢¹›Î)ÐT�,««"›uÏ>J6LjñS¦sÇ|Y¾$#Yª°|®muèòìy­¯‡‡‡›àÊ¢Ñ2¡¿“«‰^KåeT„T_‰ù{/:Vøž4ŽÃ³«ÎúÃ÷ÓY,©Ç»Œª2çZßβ Ïkùø;ÓõaÕܬ2tÑoV}¹Ë#¥åÞUŠšro»éÞW×¾uNâØÇw™h–/õ_—'™î‰Íý±¥û�Ф�µ™ççç7�Ø™ù¨t???ß(œ;‘LRD½/ z¼Ö™ïV¦×¤ävJ`�!ãvLqÌg7_­;M' š¬ÛÓét3(¥è nò2d¡ºt!VïVïÕÿšv�«è:Z·éòÔz¥y”3´í;Y™¿NŒ ­ÇnÂL“±›è»¶¿Ó/Vé¤gîY´2mU¬œ ’Ö·‹D¢éQ™æ‚“‘–œ2¤Ê™NæN)MǬ“näîÙYXñºkÇñ¶s!™úDr¥©4ôœ¦ÑùÇ'èØ¢uÏ:Imµ«k·xqeKJeês\»ó «�c]zT¬ø;M(ÎÇ»Ž]¾nòÔ‰'m˜ÔôÈ€hÚª,¤²rcŒøë¾ºVïQ™n7‘uÊ •ƒ]%ƒõ“|;¬d5q8_â*ËPÇ®í2Ü^bÿïY ì(©~Ùß(ORºw:'S¥OßøUº¹©²à|º;Ö[Û®¶yîP¹Wýwµ¸Ñ´îE§ ¥ñò½ïˆ2v ÌÝ:qÊY·™{§­º>æÆâÔ7ˆ®Ž¹À¡{¾ùlZ³ìZ–”–þîîl7¼¦÷¸zÕÀ ú^»ùÄɦõíÆ$—{îãÓ= ƒÁ`0|0†éþN8ÿêãðþÝÅ‚k´e¶n¾PI3­ú`’Ur¬G]¯ÿ;lwÇ‘µ¼‡A¬ë*Ob0É>Хñĉ½à3Ž]Oì–šßé[ݱ?uŸ†bs²TèJ¡þËIn¾‹Ää§÷êÞ_�l”cÑﱜ¸¼�ã­UF¯ÓZãêá|>ßøÃë}4Ûw,e*ǽ Ÿ{fe "3•Õ÷°¬îY­;µ,°ý0J e«ó.R™în rïè&”i½§žî}G#êÆ¸Ý[}ò^…z;í¡[ŒuuÇtÓ‰côJ!wõ«þÕÜx¬ÿ�<š'ë[A?nÝsÖÅÐü³÷’Á`0 ƒÁàƒ1L÷?·‚Õè%ÅrkAu!aDN01Ål¥0CdZ~”Õlb®2Æ,Sb6»ôº w‰ÕQמdº¤ ÊȪ« ™0²éý‘¡_½Ke=Õ¢Âk¬E Ñ×1Œ+¸ú×:&s»íááᡵˆ8&Ñ™lw˜e"Y#˜gþ^–o‡ÕÓ|¸YV-d&«ŸÏ盺ë6Oºó�5Šçwîå}�•®K«cõx'í$ŸKV/æÃ:í¢”¬òÔßsÊw¶káq훡%õZÇ>wù¥±GóYm.wy86› ²“;õ=Î[ɦ®´‚Óå#õ­oº:Ý`>†óßa”îÉ�£”îŠ\â>³ªJE§tkÇ r¨2¨i·•mgr.ì* �âÀA›÷¸ˆÉ [ÿS=8·Š$¯>“üßœ2UÊ ãZ³<΄ؙ_Ý3º Óó4c²NRÚ®Œu_7Á%e¡ƒ»�ùhÝSÙ`Û£Ä|tqêÊë™JË™ì»4xnG9àù´àÙ}ÆÉáäá3Zß%‡÷h,u�´Äö픊2Е‰òï )S]ú;‹ŸºèL]»pŠW—ÝïÊäêtgQÉsIn½/�U»Ï±®SÕ{9æïŒG+ÿí4/ÕwŸ¶ƒúŸ¹�¬î>öU´]Ä·@¨cN¹§Ò}O}¾ã^2 ƒÁ`0|0†éþ�V³µz}~~~ÍD#™0f·nSÆIY&ݨÄU³3ó2ºÃ{°ÃÕ}+–ȱ+‰‘P&#¹wÐcÅ,© nc%ëŠlw]ãfÅëT­ 2lCÅF\.—7Ìvb^sŸX}}¾ä Œ*_ºOÓÚaSZ¬½Îúfyœ;ަ£õæX:Ç$vV‚³œÌê+»{FÏQæŽÍs–�޹;�²KIbë´¾é±S>Ê�®ñ|‡Ä¦ûôz²¼­@+�Kãž²¬ÜI\þ.ŸºÖÉÓµó�üº¶îê5}/a•_²@î&ÿ IDATt°L�àŽõ…²º¹ÁYÇ8Nó™:ÖokìÄ\WùR�2f?7ߪ‹ë|�ò¿Á(Ýÿ ’.•n�dòòòò&R@òéÞñÕîv¸óÿŽ 1™1yì~§s)ÝμèÂ%ª_jú€åp2;Ž~kÞš¶ó+ïˆëõzóERçÿË ‘ŠLáC�]�0=æ—ê»3'Ey¥H¸K§ hhAÊF9WJ ¶™NÎN`¿Jét‹Ïîž{L¾“4i§P€,�.üë:á”n%vÑ)?®}³�ìŒAÝu-ÃÃÃUÔÜbsgÁÈ|“»ËTÏ3ÕÊÝ`iÝɶ»¨Ôs3Òx¢ù¤ÅðJAvŠmú�›÷ºÅÂŽ7ÑÍCu^Ý@w¾éät‹i¾Wm7Jö©¢Ï¢rðý¥û„[ÍÇß \CòkP—Ëå8Žo…*ÝîËp+_m÷ùRÚºÁB˱B7ÈïN;`ù’RÁ…GRD\ìkÇLðk{\L)âd«ÒÊ<¬X4§8ô]’5'£ë|Äùÿ=ï¯[p1ßôœÞ§ ·>ËÐí.Ý@T×Ò†Öz>)%%c=—«„®î:t‹Åt-Õ?Ç“ºïr¹Ü”M7ݦ± êÀí%IõãÒpr®®uçôš¶õnñŸ«”žÞK9»Åcº§[,¦þ«2ì¾ÿTÆÊ§[H°VuÕ)ˆé]î*šVÚh˜B]ÛTÙjüOû‡’2­÷9ËP�gá�½(Ún(k²h¿,òï8nýÁ¿‹ñé ƒÁ`0 >ÃtÿƒèV¶jÚa$ýªžþOL·sµJ¦$Eà±cøÌîGv®ï0&éþÄäÒ…À1<,+Ù—º(hÚ꟯(ÆÖ=“&FI! ŸØLj—‹ÆŠ�îÞëÊ�/ùÒûMˆŽéÒºKlOYˆ4=­ïêcνfö'_J³3]ï¤Ñ1ü»ìyCôº¶M¯cõôZv,Y¤Øîw™Î„T§¬og]â5×¾W mª§úï˜o–»ó‡Ol{×�,+Ù˜g¥ç,|nÑ1ºžß�7vÐYª\ùô¸kcŽ‘ïæÅ”^ºF«�º›ê5úe'ù\¿Ötê¿úqOÄ’ÿ£tÿÃpþ´ÕÉô PåR¢f¦óù|3™2d C ‡Ì�ÒMb0W¦87‘­:oš`vÍ•� n€s‹….Oý�&˜B�×wëüéêýë{®ôèâà6ü¹úÒ<Õ`Çsw‘ÓM’«É�Š·{žífWáÑIÅ-^êX _ëŽ ¦¤¯¦®~W<&˜gRV wrQ+<<<Ü,JÒ¢Ð�3΂ G}FÓëÚO§¦klO;cU ¸jß¼7�Omˆõ›ÄÔîÒ¸ßVHíÚ�«|º¾¨Ç;m•ãÂîÜ�ÞŸ;^•iåÃ�dpÿy�º»Ñ�;íµá±ó�w®%ºæ—'ëüà¿Á¸— ƒÁ`0 Œaºÿa¤AÊh???¿2 µáî8nðãÈ,CÖ¹°E% ¾´ïÌd÷0ÝC´b^;¹¸ÙQ¯34\:v+KfÇf×oÇT“iU6‘®9Êr8v�28–ÑɪP6£\/êÜ*t c WíAßËîæ4÷Ûåã\Šø^x¿“G­D®¾ï±¸tX1…ÌÓ±¼d…“ÉžisÌHì˜F2Q ]ç¤l]bºµ Š*�{σMì¶Çô.µ.ß“_²Öh»\Éç,÷ ½{Z…X¯Ë{*½{,8Çñv¬KÖ¦£õKù’åe§ï¬�ú”ócýºg­„L÷ŠÕg=²_SžX]Yïmoƒ£tÿÃp�¾”$vºã8Þøv©Û€ �Ò�húÒŒå”MÊ]rÜådØ©§n€q÷×5•ÏÕIM6NQc>©î8±Òmˆ>Þõ§N&RM›¾°�¹”íiGqдÕç9¹ÏhPn½Æ ',÷^˜¶+#óeþŒÜ£ï…pòœÏç×ç+ö½ËË)„NÑâsi!¡i²®R¾ú¼ÛO‘úbçOë"#Õsuþtº�Ú ²‘T¸GÁì˜Ý…û{u•Ànœ«ë+%^ïM å47(vˆˆnÑîÆöôŒÊ±s}µG¤S¸S?Z) �ìïY¼¸Eé{ê)-4�ã­Ò�bs§hL%Û®‹i¥ýôôt&° ;9øw0î%ƒÁ`0 ƒÁc˜îc;++Ô1ݺ{¹cºÉ¼&“VŠ^’"­ÔïVÌÏ=l…>ç@ÙV,˺bD]þdrÉӔ̴‹…×6�ØÍ]ð½¸*z_bàëǼ®òOlMŸ®¬ßÃêiÚÎ…‹Y&ÇöºvÂûõ÷{Ú´+å$ãŸòíÜÐt Ñ�Ù¬›ºçr¹ÜlôU¸1#±ºî¸òZ�/Ýu>Ÿ¬)M­>×Y0>}útãÆ•,gzÌzLu¾“,"ݘ¸k�HŒ±Ê@"Ê—,9Lתáäqù¬Ú`—G×w¬riL,¸9¿˜nuÍJ2èyn„NãªnždÄ’aºÿ{ŒÒýAàÀªæ%~‘R#\pÂs¦/�$©Ð+ô|Éãà¤tSÉè”ì]â÷¢S’Ô—1ù¯ïš »ëÜi®i2ÜÓªîô¿F…@Ë .I¹WÔ»w“Í=¾äN¶’Å}í�uÐ-ðº‰GÓSŸl¦“"®ÜåªBÅ�uàdJèó{«EDR´“Ò�”M]ˆ8w§`T{J{XR?KJé=ʹë«~æê€ù¤Å+ó[)�©îÎM�S»cù\>ÝB¤ÛVjï.>sOY)ꮜ«²¸ôÒ±+;ËêÚczI¶ëÕûV×<¿³¸®c×—Ýó"p"–ü¸÷’Á`0 ƒÁàƒ1L÷A™ n¾ãgà5N7ãqëJ×¹—Ôʸc7똬ž‹)^÷Ö=;ŒÓN]Üs¿c;’Lɽà1Ÿ£[DÇ¥ˆ%š®Êª_RYËT�˜|¦­¿�ûŒ«o'7Ys­“.¸‚¦¾‡éÕ{KNÇdªÜ¬o¦á¬G×ë­ �n²t –kƒ¼îÚ¦“»à¸t¬Ï§¨$døa21‹¼GY1'-l‰ÁÖçÈêvÏt÷éõvµcQWϹ|T&gyÓòºñÖ=ïúm׆œ,Ö£^c»ß�ë’…CïKÁ^^^Þ|/ å©r><<¼~{@eÐz,×Çt�kÉ��Qº?�Âë\MJW¿Ë¤Ò½$)t/é&‹BgÊKƒ®Êº3x}�RæÊ@bòݦ¯ýq|xÄMúUNç�çêW«?ž‚!¾’Éžù¸|éj¢yèoºÈP½¶R0¹ð£<;Š‘K_ÓV³ éÒ5‡¾öIy=�Þúxó˜ ÈŽò³Bª;M_ý6õŽÓâ\#”h{Jý‚mž¿]�—bž&òÔwÜ‚Ñ=»[—�Rê«îù*Snq­çõrçãù´hæ¥õš|ÉÓ¸ÎçwÆb7öQ6÷LZˆ¤|E*¹¶Õ-€Ò;âù®M»E°C×>UÖ0Á:çï.fد“¡*÷±D•îÁ��Qº?x”év)_^^ŽóùlýRÓæ4*%i0p~Î*—c9º2)œÒåžy¯¢Ý |;Œe Ã�Í?M>š¶Ö]åÃ<*·¡­©0»ØÇ]ÙUNʬòéûWE�!¬ÜÂA�� n±Àß*Cj·U'Ú\{ª…ìª}SfMOCìi‘š&Ow=)݃Á`0 ƒÁc˜î„2md=5”�š�tÕÚ™yÉü¹U8Yú&¶¦KC�“Z2ÑÜïd[±R.^så¦)V^WÇv¬X\ÇF’éÖ|•¥RæU-L�¦AZLœEDë„~ÖÇ‘#$wŒÄ’t¾ãÓ�ÚLjw´äð²°©kcZî]ýúõ5ªÐÊD›˜DÊã¢Í°Lu�çÝþýM—æM¹X§Z–TßšMäÌ£c·wYm>Çãdà5Å= h²Z8vû8¾�ë;~îi,L,ªkçi|£5+=CÅ$�k'š~*ëŒi»4y/åÞµ2uõxÏø´‚ÿk¬è|«Sÿgþ:Oè¢ÇÊ¢Ó=K~\ŒÒý/À¹ ¸M•Õyj³„nš8Ž·Êd��Ö p5Шª¸M>}z£ h�¨ ÉÓÓÓkžÎ•eðã`ÜKƒÁ`0 ƒÆ0ÝÿÈ€¨û™nþV¶[Ù'²Yn#¥2Võ;mòÑ{ˆÄ`v&ÜÄt%ómzf‡¡ªôT¶Ä”:†‡LÅq|ÛPèdàoÍKëW­”AïWƒLŽn–)ö¢Ê§ìOgÑtÓE뇋`R÷¹2Ô5×N¾~ýz¤3/§�Š Ž!vÌ™i²f)Ú‹Ûìz·.*©Ü<îäÖßšoçB¢_—d{JmAe"CGKB*»+Ë=H¬îêÜ*ÿïeeYL×=Gv[ÝÈ;WÇL»÷Âçºò¸èCŽÁv.�¥©«“Ä:wÖMS­ILëö¾ûM0Š× ]f~ÕÔ¥„a�£¯J VÍ 5^ë½êÆòåË—×ã‰Xòcc”î TrU9ã ­J·*"ÎÄî®í xÉDÚ)Óï™ “ëJg¾ï1Ië¥ÿKÞã¸U¬Žãx£8:?`¦}½^ob°»w¤m¡\UêýëDÈÅS2w§�eÖk|ÿU~–Iß%ýõY•Mc_s¢ê;°{Fßߪ¬u_j“ɯ_ßQ2ßvîÚÖùŸÊtr/Q·$¶“®/»²v‹€ÕÂzÕÿ\ÛJ&û{ú0�WÊWÊ“}1)ÛIVmg¼§k[»ãVw=E¹¢O·Sè]›I‹k§x»:I×R©ºE‰Ëouî8Þ.´Ý3;íÞ=£ 0~ R]@vó­ãóùü&|pýVו/_¾¼º—TžãVòãbÜKƒÁ`0 ƒÆ0Ýÿ¿Õ¹ k¢L·c:W&wÇê�õp Ôê™]ì˜o»gVH ËÖ1•Çñ�R¦Â¥G&IÁع)m�¥ëب’[MŠÊ¶»h3jF.\¯Wëž@ù´\Ýi�8–ŠQøþ´­wl)ë²Î;ó¶û­ÏÒµ"±º;¬>åL.ÕŒò¥6äÞƒc·y¬î%Œ0“êKËOÖÓÝCù’ËFÕIJ¯c³wúzºÏµ_•y—ýL +å§Lõß¹éñËÐ�[+f•éñÇLw ŽÝ—ØÿtÎ1º«4ºòïÔáJÖ$[Jg%—ž× Ü<©.�) Ž ÕÏ/—ËÍx¦VoucùòåËÖ†ÍÁ��Qºÿ%¤ÁØ…t®'ÚÉQ MîÝ·«tó÷{µÐÆV¦b=ß™U>'+ͪ¬o�„’¯¦©iQ)Ñ´;…‰J³¶uq9ŽoLN§·ü¡ÜNV‡N�æó:ÙT~”¡SW T§Å¢S*’âîÊݵדBžV;JE¥»R´+d˜¦•\JÒ»Uÿú•’—z²°»PZ=çäédK‹+—Ž{7+RÀ�Ù¬ï¥ä^e¯ž¡l®Ÿs¬Jãy’£ê*í r f'·»–4» }w·˜ÙIoG±NÏè8X®%¥ kè¾Ýäétº‰XRçëðêºR~ÜOOOÖw|ðcb”î:P;źX3Ufô*tš¦Â)Ýnðul$ÜfÊå‘ÑnpÏï*àÌ3±G̃“”óïV¹K‰tŒ•ûÄh3Ü•§ºO-•±ãÊ÷åå%²&+åJëm…´pxyy9®×ëëdÁ ‘lúž\hºN!J 4ï× ¬üžʵ³Ààú×ëb(ùÓ2*ÙNéV¿m=f=¸réçû«×‰´àÔ²Ó§ß�é¸S ùL'[·èN <íoîÞÔ¶h©tãnùív Zæãdwϸzs‹ÜÓé–Õ6¹ÇÝ8–�ËW êÔ>»ÇÒ•ÜÄn˜A׆ܨé6:&2\àŽXP庾 ï²Îi^þùçk>j-üØŸîÁ`0 ƒÁàƒ1L÷¿e°•ÁÔóê#Jv…;™ 4w%¤?Y…ó$YŠŽµP9¿‰ñwù$fI˪i�R:±Ñ¬;æíØÀëõjÝXÈ*›XL‡ƒcïºr3_²ûZvÖW+£B—º?i:» fbø ‡åVÈø¹:HÌ+­lk® ê×EËÕÄõ­2ÝeF®c­Û]s¹"½óÕ»ÐãA…ù$WÊíʱ*ӻݡóy_1ÓU¶Äïšó;ËLê§ÎZáäK{~\ý;¬¬&%ý–³•u…Ö/•ÙÉDR{ç˜4?&k`ÇtWúÇq¼a¶»ˆ%É©ãÁù|¾ ¨®&êFò矾‰X¢r ~\ŒÒý …¤{‰š®4ôÚqä¯SÝ„—cgÒw÷1Ÿ•rµ8p°KÃɺ:·3Ù&ùt ¯É×  n#Ÿ3Ij]q³$M—5;²œ7 µ¤Xí(¼L;=Ã6\e¬2u“8C$:y˜�Ê£õ�”Êä6”|n™6Ÿezn4T¥´›t“{ Cºw¹«l¦~]e*ðË·”UÛMöÚvwäJ Ö•Bš–nQYèÂ(v¤¸îZ—VªÊIÙ;EŸäH*wçïÏ:I ”2Qž´0êá¬GW7ZžäƒÎsXînó½¾u eˆ@‹]Y*-—ïår¹QÀ_Ÿûúõë«¢ýçŸÚЄƒã^2 ƒÁ`0|0†éþ�6å|ýúõÍJY¯%3/7Šuìfb™“èÒèX�&.1 Ì£cH\+F%ÉÂkŽéPv¶Ž•QUæ–,Œ¦á" (“TLb2«¦ Šõìq¼ý( ™²•u£ê$m(tuYÌ�¶IÇÐ% á´ÔS»Ñ>’ÚšcøS>ìcΜ¯ïÿtú{7ÍÇÛÍ’Ênë†É´Q‘é©ÿ+S™,"®9‹J•Õ¹Iuruìv²Zt dÇæwõ—,_*7±»kÎrâÆžÔN»ñvÅÖîXùè—ú%ë[ÛCŠ>åúO'›Ë×Y ˜FÇŽ« jYJïÛY²’E…²¨¬ŒXRǺy²sùã^VL .—Ë›�Ḉ%ÏÏÏãVòa”îÿT´´3w>ÝnbLqt5¯z>™�B×¥å~ï˜;õwÝŸ&–µ,S>ibåo=—|° ¥¬è@¯yÒU$™H�<Î-ÃMôŸ>}:oÂQ©²¯îJšvRÆ\»è|`‰’MCêD­ &ßqRî©pufö$çJ«r&_䕜,«ËÃ),ê·é>éÞ)d+¸½®_¥ˆE©Œ%«º¢èø´+grÇp‹_×vÚc=³£Ü§÷Ìw®÷v.%»²išLõG7ž¹:g›á‚Eåv.L»+Ç;·ˆ£ì‰ê|µU~×nÓ"¼C"q8߸¾C?îêÛ¥p»0�i¤¾Ûª€ÓµD#–0LààçÁ¸— ƒÁ`0 Œaºÿ#$÷e ¹©Ò­œ‹rìÙl2¶Ž!p±€WLBb©UÎ:&«°Jϱ;Ž™`^ú»3ió~­­;•�)]Ìô²`¬L¶*Óõz½‰¹­.EzßétºaG+N6ëît:Ý|�æWeÎÓ†82ÁÉâ é)D]Ó`�i›ÖsúžiñIl$áÞ×étºa Ý{Ö<µì.^ùõz½a™5 µh馨r'á\ÖSW&-7­+Z^öƒ¡F¡åÖ�”Ũ' D'cÇpkVuÒ1ôIžÎúÅñR¡ f··CWÇz¬÷¥ñͱ².=¾²ÆšÖªLi|=Ž·›lӳݻgÖ÷ïÞ{õÿ•kEW6Frãuå©›'•e.÷’²RwÖ„ú¯}þ|>߸—}þüùõ˜Ã)÷’‰Xòób”îÿª è×Ý:¥['ðÍï gÊwáñôÞî#Ä®ëAšlè6�&V÷åî”oÊšE}V¯Q‘¡Âêê±”·˜Ie¡[ˆ¦]Švå¯ ÞãããÍìÞeÉìD,+ëEÛÌŽ�NP///¯¦S·hKæå.Š@*ƒ“Ã=Ï´5ßî rî`\Xi^n’­û\û¥ rè‚#…‹«ßNaY¹—è¹ÔF»Åšß?sÏŠ«“ÝEs'ÿ'bC�ù¡2wßî"É‘+7�¤`»ò¥Eñ”ßýv¤‡ûŸÆ†n±ÔÍ zŽ}ˆïk—PqòP¹ç>M[Ç4÷©÷š£w/:žëGÐ.—Ë·’Êçÿûßkô�š2ø¹0î%ƒÁ`0 ƒÁc˜îÿt/QF…;¡¹›þ8Þ~¦9±=Ŧ(£¢ÇŽ=ti$–Øýî@#¹ P¶ÄþéïÎ\êØÖ†*™pÃWõ«ås:©2é3}_ŒB 2¨»‚¶eëܩ^iÒÞawÚ‰22µ‘reU¡%�yª5Aϧ6Çû´<é“Ù÷@ûMùZV�J�6ÓÒm ‹¦“,>´¸÷Ô1Ý­Ö6•¡“51§Ì#¹(Ò{fŸïÆ•i‡™¬1ygÃí=2ð9W¹´|Ý;ÓûÔÕ+õÿ‚s=Òô5-wOÇž§MÉz.�ó¬ßnLêÞC²&é±¶ u/ªÏ½ÇíFÊ®�0Oº˜•5ðóçϯÇOOO¯i—k‰F,™O¾ÿœ¥û?•iíÜ)Ð~Mèu¬aÆÒ`ɼN§Ó�ƒȺÈ(Î4˜þ{'7€»É†ƒä{MŸšóuט6#˜ÇÛðZZ>ú§úV4² hU~.—Ë�{’FQ¥’uÊ÷$¥½S’´.hUÜ×#µÜT$ i‚sr!Õ±ÖcÅ&•Uûn¥«¾š5ɪ9¹Þ‰SÒbº+›¢ÒJJG·(uï–õ£ �º”duùiz®ßêoW*Y+e‘åëŽ9.ïÔù=ŠvýïúNRºYÇNÙä;f¤,Y'É©²èï•íÒ[�å.½�´wÁ…RÀ�ãÖ½Ã}ŒFI†kå;¡Ò­‹jl(îÊ›_ ¬wUn&ƒŸ£tÿÇP¥­Ø#·!�Œ8}Bé‹VÇðœÒ­_»ìXÊ�”n>“Ò¾g�îØ-—VRš©,2ßnd:Yo*,ZOn“X)iI�“¿†Ÿª4ë¼2*Tܨ¬¸‰ˆ ¿TÖÔuSçqÜú6w›FL›>ÅI�ê”ÇÞu x·ÈP¥FÓÐzt{2Ë˶šúQR<\ˆÆ�…¨ëÛ*k¥ÍØì«¾C9©ä$ö?¥‘÷Zw­#&\û¡ï°Ë;ÉœÎq£¦ëÒ¦Ò­2t Ïã8ìX“ö"¬ Ï$K“ÊÉöäÒ*“’íú®æ“n^ªóÎBãöÀ¨Òí6Oº ¶©h>jí:ŸÏ¯Êöù|¾™ÿõ ”Ü´9ø91>݃Á`0 ƒÁc˜î\);¦;íž§™WCÎ9Ç™¿A¥‹`²câîVû‰Y"£Êë£ÍóëMFóc¹ÛçÒ($F41y޽Jl´Ê«,#åPßáB…tiwþ½*Âé½t…pìT…ÓZYDCëêË1jŠ• ¿úƒ2Ý£–Ú–“Iû›~ £ÊL´¿º¶�,9ÎJáÊàÐã迤G÷’ÓíÞË*ú�Kƒ÷SnÉÂõ�Ž�æøØ�u;L|ºæÆˆnürвw®ywîɃùèsïóÉp«¬zÝ¥Ý1æ©î••g�$+q±Üêê©î%:gëq‚–¯>Ž¥ãtE,ùôéÓ £^!¿|ùrÃ|ïZ&?Féþ J‰š—Ô§‹›*9èé¤Ý™žt௴/—‹�xÔ…Eÿ»4»A×)Vn"Se�ØÎà¾cžÖ· F¹y~5Á8…NSZgÞ<Ž[7ºvh(>}VóT?bšy©@§:a=èÆÌn�á&BmçLWÍ­º¤ é½Vý®Ìù]IJw•GëË=Ç:àÂÆõ·ãx§· ñ×]™ÒyöÛ®/èÿº7)¹ú»úº/ÄÝÇü¹™/)êéù”¶û¿Cè3T¸SÚi!ãd/¨rÆ4œÂéòI׺úR¥rå—îÊ—ÒvïDÛî~·(äb±[`j:iQ�ò¬ñ?É ÏrþuŸ]×½ ]ÝžN§%[‰²ÇÇÇ2DýRºŸŸŸ_ÿ?7ƽd0 ƒÁ`0ø` Óý�!‡t�"™ÇÛ Nµ"W�ÍÑUýËËË+#ªií0L+¬˜•ÄðÔon�ÛaŸ;¤ÂYܳÎí$±2¼O­ZVÇö+•˜@²ÿ‰aqì‘2)•—º%óyb×h1¨4yŸ^¯÷¨í[óÓZº¹˜ï?1[´�¸öªV¶eõz½;}—.ŸÎ=Eû¤Zôú»äJ,¬"õ�ó¶ãÐ1²É4¯i$¶±{f—áå{ ;ê\sÜ»w÷­Òvrw÷&ë#ÝXFžëØnžc{ÖûVc¤Ö�ÖIz^ÇÄd¥teIåÖ¾ÜYjØŽw¬:Ê:“馕9}y2E,Iùê÷²lÕïËårãªJþüóÏ×|ÔÚ=øy1J÷„2Aò •ÇñVé¦k€š§;÷ 7hºPg¼g+Ÿ»—fÌ41惡¨�ÃÇØ^ Ú]zɵ�yQuÙ8Ž[ŽºOýœé¿Ú¹â¨RÄ�ašÏÎnø�\/z IDAT4á»…‡«“’9ɭϪ«IŠlÐ)SL�‘_ê<ÛŠósvÊbª žs_U|.‚ù¹ø:¯ýŸ2ð]¤ö˜¢…¬”7‡RèÒ{á}«´wÞëÜAœíÜ?ô¾•÷Š8ØYt§2±»q†i»g®×ì^Ô•©{ß]ùºÅH¥Ë±ÝåÙ�'éùzÎ]Óg8²í»öO¥ûùùù&ú’ÎË«Åíqü­h+© aÕMP]Z¾|ùrãGþüü|÷œ<øñ0î%ƒÁ`0 ƒÁc˜î ºANè.’‰®ÔuSVÇ^* ®ù(#×m¼¹‡�NÏu,Q¡X�Ä%–£ËWÏ%ÓdÇ®0¯BAÆKÙ¿Ä>ÑÕ„+]ú‰1*6M7ó�Y/tï¨3sï0j¼æ,OOO¯,7™¦wB«…ºqã±æŸXkÖËÎ/}jz®ÞX?dk�â|>¿öye½ùÁ =æFÑFœr$ö�i¤û’lî~Ç~wÖ‹´ù¹êteE9Ž·nM)=¶áÎ’¥Øq‹ÐãôŽÒ3.o2ç*KbÿS=ï°©´Z¥q"•×]ã˜x¯åRe×gœ…'Y ê™rít›'•�^Yh´/ë˜Æ/Rj¾Ån?==ݸ´8·ÑÁχQº0¨¬¾ŸéC98ù¥+ NÉQ%žù¿×œµc¦N¦É�‰Ý¥½3É1ú&9ôùÝ …PßggÞ.EOëD¨¦Jõ÷W9´m0r�¦÷ððð¦ªvÈSN÷»S TW�N‰qŠèq|ûâZ…×rùÐ_•Qa˜Š>¢iU�ÇÛ/ûizêgÏ44ú‡»>:} y:½Ýà–U¸Ï¤œ¹…óxÏbVMù|ÿiQŸ">ÃEÛ*:‡>ß- ]>D:§ý/Õ#ËØ-LÒ8Êüµ_óžÝúvé“ðH^RÚiÂcö‘ݶç"7¥v\í1¹Vq•ºw¸¹˜P9S„’òïv}›J·ú”Ïq~ ŒÒýƒA;~bº]ø@�t«3???ß 6Ô8añ˜;ÝÆ…ä8øñþÄ*R `"MDTu"#›¬÷¹ºëX—’ÕÉ“XPú÷êÄ¡¬'ó%ëíÒ~yy¹il'uüøøxŠŠý�]]¥:pLPšäÝ‚°ü5æ¸Ûè«õÉsúŽ»öÈPb¬o¾§*‹æ�ˤ4•¢¦ýœå<Ž[¿Ïj›Ú6\;éúMRî(o·`åõ´Juº»˜æ¦F•‡ã`ê§\X;…:-]Ÿwù89“â·«twõ¯ïÙ½’;¤ïKã]ÝóžÍŽ+t vj§š—;Ÿäaýp¾Õ/O®ü¸9�¤Í’u^Ç1M»òT?ò•ïøàçÁøtƒÁ`0 Œaº@èj[ý³»ð�ºš×ðcµRN&~¦­æmFSÙaÃÜoÇ8î˜;<>·b:ëX‡ŽÉO2RÖ:N!ìÔLKzºý(kB†·Ø_ºšhYVPÿk˜É:þòåËM9T~ÖcWÉJ�ê˱ru�²<Êx³ Ñ%€&e–‡²R¦n�LÃò^÷ ÙHÇÔS.Ýë¡ò)£Æç\:®l©>øLúΙìÙ¿Ûê\ÜÞWwu¬ Ë�ê›m.EFqy¸g’%%µ3÷?Y‚È:ëûßi[,åIîj,óaÚŽ¹O}Û=Op áó._·'£Ðígà(�ÕYû»«}/ŒXRÇüꮦ]®u̘î_£tÿ€ {G�«ÈÎHÅH7o¨y,)©4oÓŒî|Yߣh§ÉÈÉ”&n† sf˜“I2Ýç6¡Q7w“©“•Ϩ¯nª×Óé6¶¬æÏ¯*T™SE›å®ãÏŸ?ßlJ¦*X¦¤”Ç[eRŸq‹ ne¾î½;w¢$7È–|¬o]±}¤bRX4]ti 3w¹\nòÔGiaEóûJ�OJ¼¶³NQwi•Li`Úƒ¡ÐkÎyÕ¦y=µ'>sï¸èê;=Ã…Ir)I.7*eÝ©GÞ·C@tåa>|Ö¥§cXýîÆ_¦¯sI�×1’J·Ö¥sÁcÛäü«˜ ë[i¯>7_ã÷àçǸ— ƒÁ`0 Œaº`$¦›áÉÔ*z>P™ ǜױ2o�Û�ßamî¹FÓàîêç¾Ä€(s«×Üý•öŠqÒ÷àž'ÛïL͉Yª´•­Õû4íÇÇÇ›ö¥ò)k˜ÜŽî"$YÉz–|ÚÞõ¾JKßa²t$†œõ‘¬ŽæóŽmÞiƒÉ½èz½ÞÈ­¦odLÑIìæ.CëÙÔד;�ÞǶ u@s:]&ôœÃêywMŸ¡Ü�e‚åreJ¬¾«Ã Er)¡lÝægÖ‰ëc¬o–wÙhÅܯÆO—6Ë©pnSšOõk÷Î"Pë�ÑC\�”õ�_ž<Ž·QŘFbºWU?Féþ�A׎.f·*SNéî"Ф­¾gú›¡î Ý$“&«:Ö+™.»A<)÷(;Χ›ŠŸK7ɪÇtQèî§)^'5UÀê]ºIRCÛ1­Õ$¬2W8A�lh夿©Ä)ÅZ~«Â_¿u‚ªô.—ËMûìòI&h¾/ž§<óqeqý€í¹3áô]–‹†#SÅ!ù•kû^)L©�séÚò*ÊQ!ùÖ&…™Ç,]=ô™]¥ÛùrÉÏ9µ+‡�ú昘¢”(ºEI7&vã¯[ˆp‘ËpWîÕ8˜žsrj:©]T!·0q!ÝXêò®´éF¢óoRºé^â¾Ç±ãÊ7ø90î%ƒÁ`0 ƒÁc˜î×ë·Èd0u5LÕ bv;Æ€«ýZ‘Ó½„n(d[Ñ�ß1¿—Åî˜S—Íã.íUYSÚú»³8‡ßXIf;É}·1�5--�se©g5_�òòòb?¼D¶¶cÓS§÷èX-e3ÕåB-;ÊꪎqîêRóMÖgæg~z]…R{fÙµ¾Õå¦Ê^×háÐ6àâÈ3ÿôθa;1¾tÍé,Aš¯ZvØ"Ex`ÛLõÚ¹¤ð¿++ËD¸¾¼;v‹êÚZ*ë.:kK²¨lÇÑ[–ô\êGI¦:îêØmWKŽ{Ö•O];Še®ßš6­ u¾˜m#]„(æK¦Û¹zÞûN?.FéþÁá”a5A•Ì)"ªtßã^BW8ôZ)dÝD]¿ë?ön€Öã4è¬Øîx¥ÃtÿàH ´Æìæ.ge¦4N¨‹ÈÀ|\ô’.²I¥Ý1]³‘Øe'É¢8³#Yô{àdØa©V÷íäÙ�'ÂkºaV-úŽR„…²=NžÊW?]¬–—ú­Ì²cÔ*­d¦wlXýN›4•yå†)·A–ï.™Å� Ùµo•Ám4V¦21Ý..9óa¹�ã»ÏH4t*™ôSÔ‰=îú(Û–¦ÁòiYh™)¤±¥~;TöÔ.êZמVîì{©Nºãîþ�1DÛI7¾u–2úÉ…¤«¯.Ÿô^ôžTÇ�¬Ú7YöÔÿ\NNZ@4b‰Z�5?ÓÖ>š>z£}Û�-n>×ãaºMŒÒý“ …,0×QUé.…É D:ÈÒ¥Aº±¨<�Bï�]ï*´©<…�Á8) �"’̬N†¤´ue*|ýúõuB¨´ëÝ2â £ŒÇ­«I¥¡P7 }·ä8nÛÓétŠn%i2^Aë§ó³uisrg´Í#½3=ÏEï_µË’Óùn«2Å÷µÓªOê» ï¹”€º®ïOI]ßåbƒuêÚrªïZX9"¡S0T±â¢-¡S²õŠXBE1-ºv‘”쮾ÝWh]Wо[˜$å{U†4^ß³€~|tüÑ:ÙY�éþ(õ§~zzj˪çÙ—ÝXœô%·*Ýiìü¥û'Y!í¤és±¦¨”'nàÑô�ã­wRº�ž6®9[ï)¨ÜzO7`%…8±5DJK=æ¬i¤òð'ž%�¬êï­“@áëׯÇåry}ÆùÐÖ}Ì«|÷µ”ÑÑ;•¶–E¶‡�ÅeÔúN÷iût!Ãôy÷.¿~ýzóþ G¹Èæºþ¦“1™îÔ.Ȩi½r� ì¨~ŠZó¹g!’úX§iùô[\¬ë¢í1)fl›[œ²çŽ];qÊù8n­”ÅU}§/Ϻt*÷¾:òÁ)ÃIž�tꇬïNq/Ô8ã®iKó ÏiZÕ¯ulP¥[7R&ù´¾ùy÷n¡ÝµA§t¿·=~lŒO÷`0 ƒÁ`ðÁ¦û'ÁõÚ‡L¡üÔï—æ.Ç�‰Ò0q4}ÑOÏ­ÆÉúÜëjÀcæãî#SFf¬cÑ\zZ�L£‹j°btˆŽ9tltg¢>Ž·Óøúõ«uq¦ý*W…š¤|Z'—Ëåx~~¾iwÊv§]û ´ÖtÌ'ˬù8w,•geEѺPÖ1½gÇôºú"Ö±Î.Múekù´ÜÅ´é{*臅“Ÿ,9l ‰É-ÏçóMI®pÉ€2t÷¥÷×1¡´Þue]�–ŽôLW�t7JeKcC›˜†cQ]útéÊļœÜ®\•O7ÞºcÝ_²“]×çµ�h´�ççç›�úl²:ñ˜¿S™9ž¯¬?ƒ_£tÿDH/ÒW¬ŽãmÌn§pppÐ åË 3™‡wL“DšÈWऑLšzºO•¡Î-‡ùò·®,œlV“¬›lÔÕ€Ÿ!VeX}Ýä¬ÇÕ¶šît:Ùð„*ãq¼õéU'‡>çdc¸½ä›L—}ß�ËŸ× ½[liYÓ‚E•š%Cë¸ÒÖ6æÊW÷Õ×EëÜqüýKõÁ§¢·«\¥²««ëme>wãÑJ)':3màLyì.øÒxêîë”8-C—§«³NQ£KCR¦)r¥bû¾×¢#9(ÇÎ9*ÝÌKåTR¡Æ·§§§e¿®ói“v÷.Ý‚ð8ò¼ª÷�òýë`ÜKƒÁ`0 ƒÆ0Ý?Ü®ÿr-á—´ŽãïÕ1?”£ì­‹6áX!ukéÌ`n…¾ÃPvͱ‰ÁN,\b0ù|2» „Ž-u,͈•^‡]¶Ko-ŸcÀËÕDhuêÞ“²B e·O§Ó«û™qº!©LŒ‘�>pÃwäÞsbò«¬JæÉM–Ž ,Æ+1s‰seªséƒ8,Ÿ¾cô 3ÉH/4Íwì¿æíÞ#éì²Û]ùxŸûÝ1¾�9g¼Zݳûœ+E²æìŒo‰e®ó®N:ë–câ™�“é^V6Y\9“•à8<¯¿Ý3j~zzz=—ê�Çš§¦Íw©²¤÷ꂸg¿Féþ Asw`»I¤L¾êãËPoUæ44YC4 (•—;æ=+÷ —†”Ü ìî£Ü:©¤onç|S éÙnqrwƒ¯šËUn*ãœ,tÀ¶�d¢ÏãqÜFË8Ž¿}‡Uñ¦xÏBLe/Y �’ë”8-_É£_Víüqù.�<œ|ÓäÌþÀò鯠_·Sÿí‚s)Ó~[ÿ�Yü�?þ¸I“íNÛ<þªØ¤àÎ-¡ƒ[Ä»ô’BÙ=S}TDZB·ÀÐs\œï¹¨%%Mer2è9ë9*ÚÉͪ˟ 2æ¡yñØÉ¼³ÈM}Þõÿ´(pé׸§á6Kéf{¦ïÊ_pm¸ÞYìôŽ%we×¶®cÇ Äf; DªÇaº=ŒÒýâzýQ¢”_ {”–rtOâ:p8¿Iš#ù)úä{ÆAÜMÆ�’ä&›åª3-&%ÙÝË|ÜñÊ„¸J[ŸMr§úêäW¥V' *Sê® ï™>ëI&mƒå éÜ4\TWN�\:÷ =^™b]„Šî·pÔ¼´îê<ýÓi¾kOÕO+=F,Q9(_*“–Ý-Èõ™ËåòÆ]IÛ�s/¢Ý¢’Š›>Kßÿ´˜ÝQd’"ÊèN»‹ú÷ �An¯rvc@�Q.’2îêu…¤„Óu­äèÒvJu:ÖüÓBÛ=“\fÜôõë×ãéééÍØÅr¯”î4†qìì%; ÉQº=ŒÒý“‚ì³~ž ùq|S²Té®ûºI\• õçž&äìî²+.��‰²»OÌŽyI, ¯u¾Ñ*O’SÃø¥EŪ®Üu]ŒÕ¤¡Ê¤N"Õ.ªNVïRËx½^_Yïã8n¾|IF�,ªóE®IWËæXB*p‰%J¾¬|ÿdŸœný®ûÈzq’&£™Òs“;¿&©ïrgñéÊW¿]Û¨{ÎçóͦX}—.-æëXðúOX·rå¹Wéf=èxIeu¥0&™V÷0-§´UZ«>O%oW�ëêun¬sy9Å¥0wå^)ìî}»=zßËËËñôôôºxLÄ{”nŽ®þW ÄN9üZŸîÁ`0 ƒÁàƒ1L÷OŠZAûì˜n5¥–¨š®;æEóQö6}TbgµNöAY�{XfgVu÷:0O¦•ê„HQ)è÷—Ê—êdŒ"Ð¥­l&]&{|¹\nØ@ú*ô÷_ýu|ùòåõ|1¥d½Îçó«LŪÖóZ>-›þO¦ygNví„e`ùÔ}ªêK™{æ«õèØqצ�éܱêj™b]Üðês®¬d³¯×oî3üñÇ�Cec;qcCÝ{ßBŽî°ÄÉÌÞkÚŸ:—’U]®¬ d{ݽêÎ¥÷¬ú<­ i\UF5�Ë «÷±²²Q6×ï\ÛíÆ°{Þ‘æ›\—êw}uÒ¹`:ð4ŠÖ¤.¢OjÇîžÁ¯ƒQºr8¥;ÅìV¥›1»»I@Íç»_¤,ð8)÷ŠÕ»3I2ýT¾•2´’�Çêpþ«‘)­ã¸UÜ:ðž¤tëqú­“C-ÆTnNâõ<ë´îûòåË—™’ùÓ§O¯ ¹*Ú§Óí§ã†0½#ÖAg*.Ðä«ò;÷ Z,¨¬õèò¯ßÎÆÅw“»öQ.î4=.0X'«Í˜Z÷¥jzüñÇqÇñ¿ÿýïÍÆÜº/…å"¢”u'çŽù]ót÷¸¶ÊͳŠN©IíLŸã;'ܦخmv„CZô² §ñ·CW9žtéudH§¤ò¶-¶ýn\Ó~¤í¬ŽËŸ[Ûª>òh¾úþ\=ÔXéÆ`·8K ¨Dr ~ Œ{É`0 ƒÁ`ðÁ¦û'G1Ljßeº•�MPŽÃG?д»’VéÊ 04Ý{ÌçjìØ�Äâ�é^¹—°nÓ­÷ðXŸseuóVÏèµ´yêz½¾¶�óùÜ–¡Î‘•T¦3½ã¯_¿¾ºšç²•Æ\ÞãÊÄöø= ¿“»ê¼6OÖ1Û‰Žùé}¦÷§e¨ûuü©Mweüü¥û'GE!ÐIÓ}�²LçêF B7¥�^㛦AD��²Ø ÔuœäIƒv'pR”wü…;e3M¸Ç‘MîîXë;…ÓsN‘rÐwôòòòÆFePѽK~:~Ç´ÿùóç›¶Æh/©~苞Þ安\'ßoÊ í]ëL'Y×u²^µ3>“Þ몯j>tkØQÀu®ï‹mFÍô®o§:Ѷ•ê.™ÙéJ‘\…H8P¦�@åïÚwW÷I6¾sWÞãxë³þO‚ï¡k‡; tº¶z'n âÂOëU냽tAv‡UºUq^ÉH¥[eum0¹•ìœüü÷’Á`0 ƒÁàƒ1L÷/e´•év»´•©R¦;1¼\¡;“f±J+fŠX­þUžÓ×�KæåbF«—˜)2¥‰]íbñ2íÄzjÝ9yûîä!–Þb¦kÓàétº‰0BFÔÉÊw^í‘yiÙéî’6-¹6éÊ—êžÌ½¦¡Ïi[?�Nvó_¥§.Zþwåæ»φ;æÃM±.jFªãÚTë,_¾|yyF?–ÃÈ=¬ßzZ_Ã�ås¬®Þ뢕¤g{Ù1�+V6½—†WßÇ�iç–;¹1t–�.ýÄh'ëFwœd;ŽÛ�eñ>µ,hž\@û/Ç>×nëØÉ×½?¶S½$̓ߣtÿ`ä€NéÖÉ]¿v—&„¥» MÅóœ€Ýà³;@¥‰¢Îëo'[):h¯&IÊ·RÀu‘³rc`«‰¨ÀøNùísº 餤ÑG´ êúRŠÙJÉ©°‚*kµ!F¡o¼Nº*7Ë×-Ž˜6/][åÂÍ¥]!ñ4ŸºO÷P¸6ç”nÊ­ç’Ë„¦]ié5*û,�ÖÅqÜîùßÿþ÷:¶<==×ëõÕ_ÿÏ?ÿ|M�þð\L©K‘ÊCW÷^xÌñ(ÝçʺBªcÞ£ç»z½wlÑßU67þºçvÊã”û:Ÿ"�c¼Ç)ª)jû²^w 7ž()@² µ}wŒBâòSYÝõTw;ïê=÷~Œ{É`0 ƒÁ`ðÁ¦û€2•zì> ¯l›ûP&²­)zÉŽi— J2Óݳºÿ'Ó ëáØ(Çfw ЊµLϹßU¿Î$ïØ62aÃWí¤Ú…ʪî j.-Ô1“)/�lro®ä3Œ'­m�ÌéŠuÒk•^Ý£} ®©œZVe¾èj¢ò軡ÕB]v´¿ñCU.R‚c)S=p#er#SÙ¸™L- Êt«;‰ÖëçÏŸ_ÙnÆ_ç;JV5¶[ןw­m«¾–Ú§s!Ø˵SÖ._-�c“ü‰Ñæ¹dÝèÆéd-ã8§}lçý»ßŽ&�ú‹ºYr¼^ýçâ]9ôy·¡\á¬Ý8Å|¿Féþp½^o|-»¯SºÉ�!МyLóÒôŽã›¢¿cBsjý¦ÒSçSè¼ô| ìn‚pfÞd"Ý€�\:é¸òuj’§Ž9ñì˜A;è$YïÑ•� U0Õ­…ïÂÉÇ�«‰*ú×ëõFÑg]éW6�?µÊìÊê”Í’Ë¥áŸt#©ç«ïÕ€´ìν¤Þ±ºz¹29e*)/Ú¯»~ž¢©PÙ+eúééé&©~¼çt:½ºšè¶ÍWe§LòÑWW:}T¶Ó·p\õÕ¤<¦¨P|&)¶\`tY\ŸH 5¾s¦Ã²9Ò$‘«‡ƒ¦—ö ¹Å>÷ñ™’[ßQ±*åëà\Rº1)õßÁ¯�Qº¨¢­ƒMú$üqì1ÝüMåŒÌö ㎻{9H&¦¤cdô^¸œôš{Þ¥ï&gNª”ê½Tô˜§�«®» ˜|þ¥”mÅ¥§ Ååry³Y2MÀ¼§”8ú×ó¥(Vûþôé“ýtüétÛ¹~³ì®m«âï|Fëù¤”¸±¯SÖý¶©k¾”Cÿk›æ"µÒM¡Aõ>Z´Œ///¯J·î)ÅZËWPßö§§§×kµY–_µ¤<Õ¶¹Q—Çn‘Ôõ%W—ì#z?‘î§p¯6fw`;s¾ñ”Õ¥Á´T¾”§{.-(\ùµ¿±Ü; fZ¤±‹uê6÷×}œOøÅ[ÊÀö—äÔr»väÞÓ{ƒƒ_ãÓ= ƒÁ`0|0†éþEàüÝ×)#¶20± ô7TØdv<ŽÞ„KÆ2™iw@¦EËêXî÷‚l»¦É¼ô=ÐBàX!gêì\ux\&û݈ußóóó ûZ`4ºSt¬ÄÊǽ—jKü€Oå«~›úœúZ®¬êÎQÌ-]H’ÜzÍàê ÁwB?ùn�ykβäúµ«×îKŸ*ëËËËÍ¢>ÝêNÃ~¤‘hÔ‡?ù•3_M“Ñ'´NvØß.�î¹”NgyëÆg‰«óÎ¥„m0•7Õ‰k3ßc1Ðç9_8v[ë �­‰QgùÜÝøôºOp¯&XݘIT¹ÔuAÝÔ�¸äq /åP%—ÊÙjAÈߪ$U_S÷.÷^ëÓêI1L3óUeˆ}YÛ†s5áÂH»½õ •·ˆ×vQn*êÖæLøT<¸¿€ãS�O~àØçW 5'ïsciçÇ̱Së{�K‰Ê–”û´xIcâqd<Ž9©/¥´K§h»¾—”îÝÎH"¸zÞ™WRyv‚Ýx8øu1î%ƒÁ`0 ƒÁc˜î_ÊL*Ó]L[±�ºòNî%däóVæsÍ31'Ç8:†Æ1陿œ2(#ãÊË´S:�¬|61wLcÇ„L6å÷…SÞ òIDAT8kÁ <×ëm¨,—?+Kô×_ݰDêj î&���v/,Ö‘º´ð;¶VŸ?ŸÏo¾<Çt®|+ÖRŸIæjw­?Êz_.—›6¨Q@qGµtèiÇtëÆÇÔθ!´à\ÊT6µ,¸oUXÁz.màî¬MÊ®ë3÷°ÂY~æ©VæKÙÈt;÷52¿¬ïkÚÎØ©yVÚzܹ®¸çY^çFØô|jßÉj‘ÞËqÜö—ä>çÆ½§ÒswW¨®½t«daáñà×Ã(Ý¿’2LåÇ)g:QïN~šMû�ɉ'MÝÀãžáD˜Òp“b2¦�7)Žn2^)tnPŦ[€t2óÖGç;ÌI/Mè…———7‹u5Q¿kºY¸‰‰.l“ªT*Ô�˜‹KçQeu æ_òësIye)øjƒº˜Ñ>êk.^ØFؾ]”"'3åweMÑ4˜Ž†NÔw÷øøøzßËËË�¬)ZD]¯ÿÎïv× Cê;îRº¹èYåUíÄùçS–´ð£²I¹œ�xòyvrîŒ;zCSv �Â΃Ϻ…­ëoZºr‘TP™»:Y�‰«48÷�¢ýû`ÜKƒÁ`0 ƒÆ0Ý¿Üj_7–Ô¦Ê�ˆŽÙåq¥_i“eXEÖp,§Êݱ�+¦»3“²¬¼æ�˜ú®L+æ"=ŸØíU™³”ÞÓé6Uí°ÑÅvÇ­Yýñññõøéé)–…쥚|5úÅüñzì˜[eŒÕâã\MÈ®6â¹/�&6‹l4ݾȼ'«“¦§ÇdGÙ¦ëø|>[W�G×±:v}œõ íI7»–lÅòëø¤ý²ƒZ:ÔjR øŠéNíYÓwyv+¾»UCS½*G²F¤û:ÀÝzHHï�ý`g¬êÆ:¦Í6éæ>Z½©kÌW�w,¬Óùû=sÈàçÄ(Ý¿Üd¨ÑKÊß5)Ý�{‰sQ ©’a½œ²×M^•ÎÎ}®ÜDrópÑJÒ ™ÊÍ|œ«ÈnœvZ¼¤�šå-з²S¼ œŒ»gøqý”¼æ«nê¯�” *t§ÓéUa?ŽoŸŽ¯¼ô¿>Su¢îOŒàB3/ÓX«Û‡+‡ÞçYu5©´�{‚>¯ç´,w)�ú.vËêÆ¾oM‡ïÌÉ]¾ëõìããã�Á-¸]Ó{JésåÛmÏL/�ƒ¼–Â0ò¾´(YõI•+)Ún|ª{îu)Qtm›mFÛYr—az; ¾³4~ÐU$¹!±ÿ®dãµÝËNýiÞzOZƒ£tÿbèØ5�@U!;ŽÛI�TbK5Ÿ———­ /¥�&Æn0V¹Ý}nb\)Ýi± Ç«úÚAz&1FTîv޵<‰�Ñ{vev²i{RÖûz½Þ„ûûôéÓ«M¦Ô½‡b]ëš*g×ë·¸Ú¥ðÔ}iAà§�³Ü©Ž]Ò´˨Çdl•ÉUv]¿úI%W?n¤L ²S*N§ÓÍ8ñüü|Sw¬×O³ùõëÛ˜ëuüùóç×|®×k £Èð�õ|å© ÷.wYTžKmŸc‹Þ›”&²³ ©N;YùŒÛÈìòM f­ï�M£îùÝ|Üoþ§eWÁ¹@ßKÚ »³8ãX¢cÈn=R>Î1ƒ_ ãÓ= ƒÁ`0|0†éþÅà˜ŽãxëÓí\ŽãíÎóÎKÏEH «c@4=eÇœK@¥¡PW 2Ð.„Õ{™ÇØ¿7=2+d&;¦ëž|;ÖÏ1“]4w¾{ÿzß§Oß¾^Ù±wt[P‹�ÞSç?þ|ó.Ô¥Eå¦ÙyÅ¢Õóc§m‹ïÎYbè'ý×_Ù¾¨íž ±‚lkr)êÚ ëÈE&b]‘Õsí‰l¼2öZF¼!kíäTyèoÏ('�õͱòš—û¯ïˆõ½bKݘèÚ -"ì/É2TÇŒX•úÛ=Œs²Ê¥òtã<�cOk‰Þ¯uD?îdÉa?JLwÓv}À=Ó�Ÿn,¦û×Ä(Ý¿Òä^púLîÎ$’\*-gÂw¾¶úU†ÕdÓ=Ÿ|-©„ìL:Iî•ÒÝ ´•wšÜéî@Þ¤ ¤ /…årÂJáqeY)Ý•nÝ_JV=›L¶šv÷î?þ|ãZQŠ7Ý7tbNŠ™SÆVõí>UŸÚ–* \°8úz½¾Ù`©ùj¹éÃ­Š¨ƒ–¡>õ®}¹SÚÜûHn úŽãoåZ•åºöùóç›:I¾ÚT~J*¸ð†*ëjí”M×è“];FùŒ Ý}J´Ô»ëú•îòéÊKK1w ·nãòÎb˜sû‘ëƒÜ/ m‹}ÇÉAt}")çD³9÷~ Œ{É`0 ƒÁ`ðÁ¦ûC2O:÷çBðž��Ŧ8€Îä¦ ËÁ¨;ŒË�¨ÎܹÃw÷iš)O²¨î|ýv.ŽùßeÙ�ùÕå[H#IéÇ-‹þððpÃVë—+Õ¥@ÙUWÞÔ¶È®»È&çóù¦ÝëFEæé˜²:NíÁ™§ë¼«/²}»®Yu|¹\Žÿýï¯å¸\.7_šdÚÉRå˜Å§§§›/{vLijƒlO‰­½^¯¯cÉf_.—™ê-�Ö½CŠXÓÕƒƒëû:¶Ð² ýJ^gmc}9+ŸÞïÆFíHVÂÕºb­õ|¹!¦ûÒïÝh-„«ªl È••!9™žZŒRË.òKbåw‘ÚS]üZ¥ûC´kbwᣒQH&M=fd”¤Ä­Òeú5¨º0b«ôÜÕ•C¯L~«´;å|ÇDÏk:qpÁ”dežÎ\íòë&ФXqÂÖ¶ .,»*ÆNžš—¶*`ª@?>>ÞD6©c×îSœÞ¤èhé¢lèçÝÓ;*ÅÓ) é]><<Ü„T¥[9UÖ”¶–U£•Ð¥DŸIŠ·*²Z?.¬›k{\üœN§÷# ©ãSR’¸pWWæ³3Ntï™ýÚõ±.Ÿä†ÐµAÖ}Z$u„E×R]¤�; ºô»îO M›åÞñY×÷ïÆ^§ðòþ4^ºÅgW¯zÎÕq7–~ Œ{É`0 ƒÁ`ðÁ¦ûƒcŽãí—Ï:3_·‘Ò=Sù¨‰Ó¹$t1²;6æ^ó]1ºñl‡yïÌå.ïJ†”þŠÙvåK1¤Wy;ÖŒ×ôW>e}›•Xbm ÅÆÖµËår³ÙU]$Êí ÒÒôéz¤ç\ùN§on:çó9¾ge[ÝFÓkíÚL•ér¹Ø�Þh”Ê­‘„ø>>þ|c%H_±ÔÍ‹dÎôqãd²Z±~\ÒͪzÞ1“*‹¾C-;]Mœ5Jë¦Ò«:Ѹñ[›ƒ�õ'Õ'ËÐ哬“®¿¹ûRDž4V»ò鵎åîÆëdÉá=îÚ®ÓÍo+×,ÊÝY ãživ²º±jdÛ‡éþµ1J÷/†4€SéÖÁ‡Qî ¡Ä]òTXœIrW�ä@×™´©ðì(×ü�Ì�:(*V t!íÔO“¹““s7ñ�iÓ•?)ä�¢žtü³¶u!P¼Ò|zzjC¿±]¨gZ4©2—”Ruqayéw©×õ¼F¹\.¯.!Úߨ€jQWú¥RÑva é^Ð-ÈKé^…™Û9.W÷t ø_ýõZ_§ÓéfÁV 2 µÈþÅ÷£.D»‹pö‘.4¤–ÉE±Ù…Ö·S¸õýé;ë×ߋ՘ÁkîújŒI÷\{¬6œæ—–«§t3t®SÖ)7ß‘^ëÞ‹¶§Qº}Œ{É`0 ƒÁ`ðÁø?õ_>@«tIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/slurm.svg0000644000175000017500000001602014757047403022133 0ustar00paynopayno slurm ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/slurm_active.png0000644000175000017500000000564514757047403023466 0ustar00paynopayno‰PNG  IHDR/0�§#âsBIT|dˆ pHYsÄÄ•+tEXtSoftwarewww.inkscape.org›î< "IDATh�½Zkl\ÅþÎܹû´w½~;Ž_ I  IȃV'$¡VQ´j¡ª*UýW©üBªD¡Š õG‹èT5¥DHSAÆ<’â??cÇïõ®w×^ïëî�Ó¶×k{½^;�ï×�3gÎùfï¹gÎÌ,á.à±ë?¬Hªd=�ªXp9).„€Lvb¬� ¢€qV4˜Ó @E¢ÌÝà�eä�^;êL‚�S®Ñ’¨ÝÎfáÖ"…AXúû f¦•DÊ6S,*±©Éòø˜qÒ‡þž›C@0jêmúìì–³‹È›ÂzPÙs5´ sé”4ŸOËÿàõL*/­ 2‘Ðð&0G~ÏW¿ÔIŒ>²V¾™À¦+Ÿ£»›Òyˆ™ á¸ôáݰOÀþ÷Nž>·ù­�€BëØNå­‰$%"‹­3ÓUÀl+\Ô¥´Ù�’‰E6 Rmf)‰¥,A©\KŽÄ÷øP€"Þ·R¬³±±Š�ÊúYç¬È~µ…`šýë‹.æ6Õ¹IX:[¡öηEÚÂ¥fý,t m²‡_.Ëë)NàYò�7J"Ô¯¨˜,¬`Ó³9åÐt~-Rñûv¨Ü�Ò¯æøüLVöfu-â›J5E<´0&-Ì=/‡´±ñêSR/Ë«c&=«ÓLPv7³f]hÏ…Š0“KUl›îbf‹k^NJ_S¨¦CÓÍ-R™¢6ku.ba"3>GÃd‘HdMrlLØ´3`=µª²˜®F†ôÛÁº Hó�¬ªO¨“(ͦ$ôÛ·XÌLÍŽP&8Ëšà”ÃÎÆ†-i)™f‡ôù³²a«Êâœuj­F RIÌ% •Ù¨ÄæûبڟâHü‹àŸ$9ܳHQLûfqYúâ¤òÊa½ÑFšwÊ^°Ð§¸%÷-ĺ�déíÊF�¥’‰ìÙWŠ%AÅó3e%ã j‰ÕK^™�Hm¶IDrÚîedEl—XÓ…Êt»ˆ-VˆX”Ät¼d#@ÌÀFMCÆò ²–dL¤cö91œ¨Û¬’Õ³"ç…÷ †‘FĶ<%Åv=®”­bzPs~~Öþn¡ÍÌÆ )Èüñ-ì¶–ízxN–­<ÖžÏÀ–ÙÅLýÀ¦Ó Ó^ˆu J'Hâéaé°˜3ll¨a£f.æÙ$91D¢'úÈ0™ù—ÓwRDAïŠúó~ãÛ�ñÜ©i�[$/}˜J»&Vjq¢à˜$æhú+¤ï+‡Zh  lyéù\(‹Z$ ŠÏ,òNFxÖ�a�­ãJF†ËÊ3¾ðœž5h®È» ˜IˆX|ÑX¦¨d¢ ¶¥„ÊîbØ\¤¢YÓ•°_»\»”MgwKg+Yn÷Ì¿Ýôò€À¼0�Ùï É�÷°Qù @¿}‹EkIeiÐ]^ð—×÷¾J‘€ßý¶ë�-¯ì²UÕUG òC‰hÜÖÛÑ[²«z� +¼ƒÑá1ËÍ®^gƒc{s;×Àä¤èîèrAl3PÝî»í—’4[g{§E×u¸KÝÊ­<²»£ËñH̘ h3áòŽ{Ý››LNLZ‰H C4:8Zò˜öè!/-"ïèsìì>Õi+:R†ê}5—0x]’”»îßS—‰@‘�ú´ý�èTN·ÀâLòBnÐz¨nÿ=ŸÐ0ï¾ÚÒZÛ×ÓçÜq`Çm’Ÿ'{â·¼úqy¿³o 3Ûˆ(–Š«ÚÚÚÖšdu0Ø7‰ëv|?ï†íéüÇN²ÁÑUYåx9V½­f|Ø=öé¨ï�ƒWÓûòÊó‡}Êï…©âÏVæð›“~«´zýŸz188èP¤�UVTTô¿ðüó8èüÁM7©»½» ýB[ÍÕ³Wö—ЬFJ™*eËL*m%=ͦͬØgÑ@B0H)Á’£Ì¬*º‹oª„3Ó<ï…#9f'€¿=÷Üs¯¾ÒóçgÚB¿ï¯èí/ûÂÅ+Ý÷ �fß»b\È÷Lú&\™µ¢¥Uñê æ·òCy?[æ{þabbbë‹/¾xãå—_~3¿Ù¶³´¯x$‹KФ–qÑi×g ¿«¿Ô3àz2úõÌãÀº’þZQeT¶Ÿ»ÿý挾ÓÍÍÍ.\H݆xöáÁ_ˆé•–÷“ÖrëMO‘§$àèíÛ6nÚºiº~ǽ¡k—¿vß)ñ©Ö Žl¼òò ý©�™µöööƒmmm�>ŸÏcš¦VZZêo{°«õªêx`½$Y\kMê#Ö±6“MŠ�ÂZ ÑFM*\ét™ùD’l¬ÁÖG;$IY/»Ÿ•BB7&½šo`Þo>ç¸ãùu¶D†ƒ"äõ(wéÎé†ÀžÐΛuuu§êëë¿iii9‡·kš&Ž=úe®N—âpçñj0½ú.®21-$¿ñÁ¶ÓYO€5^"OªØQô¾�kM+æ/lÿnnx+¼ú€uÜ;5v>Q.!Ÿñž»uά:LMži¾÷ÝþµŒ[÷ýêíM%ºE; ˆöT´Öñ̘Ñe6Ì çøŽþ8‘ ��O”K%êYˆ�¤PA“Ù&ˆì`ŽˆƒTÀ˜0Å�n׺ÎÞóöð�þeåÿVʧ§oÜ2IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/slurm_active.svg0000644000175000017500000002402414757047403023471 0ustar00paynopayno image/svg+xml slurm ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/slurm_deactive.png0000644000175000017500000000606614757047403023775 0ustar00paynopayno‰PNG  IHDR/0�§#âsBIT|dˆ pHYsÄÄ•+tEXtSoftwarewww.inkscape.org›î< ³IDATh�½Zkl\ÇuþfîÜݻ$Å·dJ”hK²^”[¸¦‰2­& Ä 'ôo€ú—�P hEÑ韠¨ê6 ’È2bÚ¦éØR"›ŠHQâCZ“\rIîûý¸{ïL�K.ÉÝ%—’óýÚsæÌ™oî=sæÌ�%x¸åJ gZ/8i§ÍÄE ‚ÀD€<‡P‰ 1P¬rˆE*‘éc¿ö@<θd¿g‡†<ªÐžøyâ¬Û�@ ·Ó?>òÛ÷–öánòS—/à„œÞOÿ*˜Ô)Þ:~}ØWO§=>ùòËžŠ\•@/ Z?¿Ý!€1&çþ«÷×¥öb¿'ò÷_ºØ N_��GoHË~~øúðƒÝLw%ÿàÅ/<Ç ù:öDÈí Düºï­wß®eT“ü½+_¸@)yY<¹Ø® BˆúÞ~÷Zµ¬T•ÔøÐå$ˆ¯ígиÙíÔ%iãMY ©”¢æòûñE †�¾5ü¿•Ú*’¿åâ)Aé«ÕÚk!èlk�j=ùÅr�QËÇú§†¯Õëkü;ï½·]»#kŒ =ïá”~û •¢$v M¤ºz ùÊÌÕK·ë·�¯¿N�Âø](�3Ø“!„9¾óþÀÀ^[2Èäí_ „tîÅaØÖä 9Z»KrC&j‹øjn2iÅÖ²h/ÉJ1›j‰.ø÷6¸›:àÿv�¿;8h�®}doÑp|:nq.ÉI³;ÞñùL…tŠ® B7|й,xžê Ûœ,é%®Z¢ ÿ±Gò„^œú}Ï�¡-ä)Ó/AM{u´Ãñúq¥Báç'ßúY%²ýÉ�º×S…zÀ/€uòŸ|ÿ´Lýä…ºW@Z±5Lvž*ò&5:áûø�'á„ô?ºté7‡†‡ Œ‹®€°Öãƒi…ìVYÍ@Jq8 ²â*oÓ%»”kêœoÈšÄ'L‰«E‰s^mè¬Aœð[wr®Z¬/»:ÚƒŽ¶^€ü˜ÿÓQYS‹Çüc·à»µ÷é=‹ãc-ѹْlRó×­ÞÁoqBepd"3Ç?»¹#¯o@¬“`€�Þjv ³»%av*ÉyƒùYS³ž>t´Ÿ*é5<ýpôz-òËž®.cÏs%YÖò‰RŸò0ãe¿+�‚¶Ýùò€ƒ5Ér· B®e\ ÙlשdÜ”M.�„¦í0B€´boT™ÁVR™\W¨–CÎK=L—yÕ½±˜KK\/\gºªV5И\^é Œ_×éæNkÎ%㻑iŽÎÝÒ˜AG:ØÍžPÒͨ€·–Qkdî‘IÍ$€r]7æsùZ ./›M!{k� DÚÔ)«®L(Rkœ¢¬XŠ’ÁªlJìF^&@<µ’í¼·çØ²«³¿$?£Ýúog&mŠùgÊí,ùdb6oSùæYcCóSË“ã®äª?o0;JzC±�.ýŽX½ÇJqωÄ:W§§js^Fˆ0¡FØpB·Ö?ëi‰!$¡JzYSw-yMj&cËD7ÛJ1»§ã^%ˆ±\™4ÙmEf4*Å\Î’O¥‰bk§59ÐØÝW©<¨5`­òÀ «)�Êf�µB ¸;O!øIßG¿•5µXæNÙ‘’tž}±À—%—ôŸ~4zý@Ä7mV3‰5âœÛ2ÑŠ‹¯TlŸìz›XZU˃̨߫€-‹@Ö`±çe³XÛĶ‘Da[éNʇm�wwÿ1®»R«+¦B6WiàI–RŠý6/;IÙÒ±`5û¦ÛN\ ìÙ裾�ß¡B×Ö Iß±ãæ™$WNÝ™ ?ÊÍNk.±ÙdÝÌç4É`²¹Ò«-AÖÕ4ÈšZ<²t÷ÓJ·—t=¯aó­”Ö•7¾¼×5ƒ–/”÷9F B9²1ƒÉV�›QÍÕLWGýc8êûC-›íèYk�~6Ã×É•—€¥ ”ÖÕŠ«ã©gÛ`-e3½ j’Ñ@À¹¬©Aö«¿ønßÜíg�éàRcr5˜U¬Mªd´ËÆbìÙÈrÁ`z´îŸ+jvKAV(šKVÌ0G>ùÕÚ[¬¹DÅ7{àø©UgûYÁÏ>|ÿvçÐ_ý�+„ÊŒ�ÉÕ YßÊÁ %ºà¯ã´³o4&Ww¬‹ÆÄÒº¾¶³T�µ5!@hDq/²°­úæÚÂéé‘_r‰I/î¨QcŒ°µ²•ç·ÆàçW:v¥Cá’lT³I¥˜ QÁõ»ûãDú†¥�¾Ú™—€ MƒV¡¸ö4]œ ÚÝný0¥×x¶zÖù<М™î ÎLÂßwãÝ ½JþóÌô»ÿ¸[íù\VŸ÷ûåÕ`ðsùкWNþ¬ú(´Eïب3¨Ùl’l¶"ê.•÷ j±˜©ÅbÞÙ@©d³5€n–%„1&Y­–uQËê¸ ¬ŸaÏüÛ§ÅûW.�¤=ž- OG K¡¨Ê6‹µÐ`µ¥»ã˜}V‰D¸³û««¡ ÔâtÅ\KþiëøÒJ4bmnôäÝ s¿¤‹yÞjûr2•DgSS$™N3_`¹¹»õ@´Ùîx0�Ÿ€ÃííaßRÀ± Û=Ngú�ÙôIQbv_<Þ›ŒÆ�­O¼Ùaÿ—³ÿú³Äypÿèo§Fÿþ'ç‹‹JwG{ÎÑàJä ªrovÖÓqêY[µW°´¼l˜zøÐbîë‹—®ÑXŒÞ›š¶Ñ#(ºBˆoaÁ¼²ºÊˆÄ”‰ÉIƒ,ËðÚíœ;ììÞÔ´ ²ù‚9‹IéL†¬ƒvõàÁó¡hÔH‘â‰ñ//{¤Á+¼¾…¼Ïl>qíÁ´rÙãÆ¹ŽŽÛX˜¿OcÏœz¶—©…Ø.Q°gÌÍÏK/žïŸ´p¾ ƒÁR~ð2Ër¢ÿP÷K §FÇîtÍø|–óÇ�Jä£U{þ§Œ6[|s=B…’߈«®®®1­³3î‹ÅñÎäý¿|`¶~mÞÚpYB¦±Øòn¤ÙÛåØ‘ÎŽU{`éC¶²<Ãæï”·57X—x84 lM&e^�D"Ìh ~ŠÀï÷;4eß*[ZZæ^}õ{g¸ð°À9™˜žvÜŸè¼1v§?Öè=¿)�ó _×¥jvŠ$eªµ¨¤¥Dc Lˆœ‚O7µþÃéàjïìܼ#œI7V»î“(Õ€ ¬- ›ÍGmUÌA@ê¾¾ o&¬ ßÞ®ßxZ¡Pèðk¯½öà�7ÞøÅˆ¹á„Ïë ä *F¥Š›˜d–€©¹9ï¼Ãù×Êæ^ŒÄbÆjöõ¢ØÚ>ñÌÛÃ#•Ú¶FFFFZnÞ¼¹qrÖåÄÎ�É·äªçÉfƒñ¡ÛéôDb1ùÖøDÛáƒSÇ{{·ïÞµ?.ñ±D. ~Š¿Q±}³†Bš˜˜¸0>>>‡�º®K^¯7rfr|Œß½óYkôti£“Rãr`\èºEwcW‚�6‰JÜ‘IOê6Û�PE‚(Ê�¥{„1Vhny†s¹¨F¥Pp~c܆G¡ÁÞ †Lz‰&âAnwzSÇOÄÏž~ØÝÝ}­··÷³ÑÑÑ«étúiI’èààà?BR{úJ;yéR‡`øùó\e¦§??ò»ßÕüzÔ{‰œ‰RA®às¸Ö$€‚ÿ üúÞIïÞc÷N“/ 4C°—ˆÀé'u.¸¸'ýúÑ·Gæêé·ïûÕ±¡ç=Èç h?w½ýD’·‹’¸yòÏõljJ˜|i ™sÖK!Ú8H q è !Ô$€<€ˆ|EtÑDå©§nÜXzÜ¿¬ü?ÉŸ’ÈÃÙÙIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/slurm_deactive.svg0000644000175000017500000002403014757047403023777 0ustar00paynopayno image/svg+xml slurm ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/stitching_modeRaw.png0000644000175000017500000000367314757047403024442 0ustar00paynopayno‰PNG  IHDRyuj8N2sBIT|dˆ pHYs)È)ÈyDÖtEXtSoftwarewww.inkscape.org›î<8IDATxœí�yŒÔtÇ?» ²°ˆ+ŠBˆ1¢ˆ¢j0j¢‰Š&ü!� !lD�‰GLÔhŒÆÄ �¤éº2Yi,�P‘+“õÆò ±y¡DŽ3°I#¹rqf]ªW‘+—™Ïî*råâŒiíæó€‘È� €O�\¯$›c3Ÿ[ü`ŽÔèO>ÉêµÌ¯`æ�âä3ÊX^­"W&WË_ø=ÈÜ×nÝÅ6õdGÛîz�d9ùL#;ò} Ü€\-8¥Øc½ÈíÆ! ¨úÁ‰ø(#ùJŒá*D2GÔÔ Cª�¹\fpÈÕÏÈÕñŸ]¿r𚛳þ>·ù#u³Æ9·G;‚–ÉZ³NUÀãÀ™ïíÈĵ[�’”®•à¼Ü`¬kÀ5ÒÖ¯ÈÉÉc(ò�›9íåƒÀóîUäò£¸™Q¸6³®yv|¦×š®Ë‡^HYûÙ››�9¾ Vð4’“ÏñÈäçt~C¢«hWBg"/.°½øø5�ë¸'Ë6é ì$û²e‡vàiä=61kî•D 6å4¥Ü/´º(N§»ÜE¾À{�÷)ÂPrnGÞä©T[Ézb¼î(Q0‡\‘ûÇëŽÈ ¼1^W”¨¨G¦ÍïŽÙ%BV!"�ŠÛ%8~‡Ò.¶_Fè‹~{˜š‘œs"ôE‰™jàÒ¸�PÂñ?¹ ºq8Ï�IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/stitching_modeRaw.svg0000644000175000017500000002270214757047403024447 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/stitching_modeRefine.png0000644000175000017500000002623114757047403025114 0ustar00paynopayno‰PNG  IHDR}z’…\�sBIT|dˆ pHYs)È)ÈyDÖtEXtSoftwarewww.inkscape.org›î< IDATxœí�wxTUúǿ継¹÷N „$$@ $t "‚" .¸*6¬èOwU¥ êâ.Ѝô*`WTTT”¢ô®@B¡$RHÏÌÜ)·ýþÀLK&É„°»|ž‡ç1sÎ=ç8ß9çžò¾ï!þ  3 À ²äáÿ�”x�ÐÀÀ* ñ�Óžk\!ŒÒØ­¸Æ¥9 S€D ÀOŽ^¹ö\£�è ÷ˆ~™tz€ €'¯lû®Ñüjú  ¸šÌ4€O<,±L�݈ÿd(¯¿]~ò ¼ØðÍ©‘þ,KeÖØ ùOÆCtÖL-�ÅO>`€±W¤U~ i 7èµIIaFa�ÕŽÿѾõ+L&Æ#QÐ4¹&z=¨VtˆèÆDtzKü˜Ð$Ð!ÌsÞ ¦¬ d0Ð{¦O»±ÉÂýŠòý-‰" Bˆ9uýÏP(Õ¦3G_•Ÿ\$u×�zrçw„Ï(ŽäÈþ €ª+¯Æ†PÔs&³zåŠÁü¨ç»,GYP”~mÉV˜@ ´@µP�‰TÅ„œ]Öž:%²5›Uš%_ÐU=ÚÏ#Oà ‡{û6XˆÁ@Íäyvä¯î1tïÞ¬ÚÌ‚ÀBÓ®ÍÞëCµ=SèAµK�ÔÊŠŸ¡·ljx鉻ukAÓäâ0ëóÈÖ`ƒ¬ßÀóÌwññæéû2Õ$8< MÓù Ë¿†ötˆ»Çpl혜ž%%ôè�=¢É+{pÅÅlÞrkÖdcõš3°ÛB`·+ð Ü=þ~ÎjŠo"ìºnÝ¢:®ù÷�|D„!¨‹" UÕ¯í½×ƒj{º1ž–ÂÛ°ç?ÿò¸^õó¨(#¸¿-–~6¥ÅǾ߆á_ÿ¼={Æ€a(„™¹;)Š0þ{}kžgÜ}WRç͇-8àž½+ŠvMôzPãÄ+¼9¸pÉAU×ç騱 ^y¹öî~e%Ç—_ÂÃS[GEW t¹ÙÌ­†{²×@/“�>0~\·ø/¿¸ÍȲµ›û‰"YÖ‚ÿ•\Çj‡wˆ½�;›±\RvìÈcúö�«±@Qdñ×;“ð×;“ ë ,æ×­ÏòÃÊS·ìO/ZLQD{ïýþÌðÇSë´¶¿8¼3p� r]Êø_§FÑA]L#GÞ}ïp·¾}ãjÎ_B€nݢЭ[yååbe¥ EEvºM›ºï­�4(Šhš¦ pú]£–5¶6¿ÇðÇ�?ž¦Êʪ›—ÕLX‡ú~ Ž£\;t©3A‰.$ÒÖ°¶`ÙW'º=Aa21×D¯AÏ¢Ì}ppÁ⌫âj2ѱ±Ûq¡ŒàoS¬Ö-zì`Cv^¾Mûý÷ ¡¨·^÷¿$úõ¢È&ó€€6µ"hÑ)ŽhaÝ裋ß?¤†¢âú Ьޫxïb21»< .KÌHA`?xfûõKåy¦µÛÞH­ÉÑwsG¾YžE,ö“WQd ®þžnµÛ•’“#Þçyæ‚ÑH½ yÏÃM&úÌ�Á �œÌn¸ýöV„eés¡jX­D7'Ó•æx¶è›åY¡ª¿ND73±=@d£6¤zNóªvÕZôæCŒY'OT"#£:‰†%&†ÇÊï¿]~Gxt´i©(²´l´ ²ÒµqëÖóöK7o.`ʽèÂü§ sçܔڮ]Ä“‰Éãy&§ßMqc�}Ì8å�^´Á@{”sâD™ÀÙPµ«V¢ëªæúcŠEPd�]òÞáPµ¡Î œˆ¬ÌÇMO<žz“Á@§(j BcÁ*vmß‘çsja21xú©È<ö˜°ö§¿F®\18jíÚ»L þ ‚NŸ±èp»�‡„ ¿ ]ÕíÇÛâ*ÿPŸ”e _.Ë„$…d2Y/ÂÂ8¼ûîÍܦ_ïáÌo û;€ö�Ý®‹ì+.vpçÏÛf¸ùæxÜ~[«€é�—g5âJ‹®ÚuéÀHk{ë)õ²;E¬Xy*Tí¨77ÞØ™Çå_›t}WŽ£38Žš €käf9Íf6sÏÞ‚:PRâ€Ó©ÑrCÕ¨E—-ºåÀˆÊöÆýÈóÌ�j¶À F#5">NpiZ5¦GÕ'àÀþa¦^=c\œ¤ÖlÉR>¢Uüá*Èc}LsêÉ ¶ÖÏgÇÿÕдh•rËGï`D1X£×Æç�ûÛ"ûô†‡†%ßn0ÐgàÞiPX–%ܸ-›‡š¼=ujCX‡ ëï6Žx®S[“‰> àºú´ËCtk¦JyU¡«Hªú9!(OÏÏ‹»Ó–³ÐuóàÛé;‡$Ö§ÞF!2Ò€�?`øaå`!&Æ4OÙMª_/ÕšÆ#F#=sÛ–{M‰‰õ÷Í i‚™3úpsçô‹0èmî©sYp;'´Í¥wФjBãB‡ñKšöæ"/lvÅ—mÔnXÿÓ]Œ üçôro  »]¡·nÍkMÓT¬®ë+B\Å@£‘Y¾~íÝÆ=Br~™ëzD“^½bÙ+O Õupš¦oâ±¾\üïÓÞcއi1Å‘³�§ Ÿ›Û3‘ªC§ —Éλ…®êEúŸ‚Ë¥bý†³øèã£ÒÚµ9ìÅÞò¾ªj+C\U/£‘þ÷ŠïÿbèÓ'˜CµÚ3h`KdxÈ0`Ъñ¥¥ÎÖ6›üü‡Žñ ƒ'U”�dv™.¬Û0‘�½ÈÑ«crSÓã�¥„¦åWˆÌÌ2|üÉ1õƒ�(ªŠ ’äZ¬iøD–µ†°éd4Ò¿~úÉ@ã_îHh€âÿ„a(Œ—Æ�iÇ#-:�jÐÃ=ø†ar°ë,~­©årÓòßÕ.Ÿ§¢ý¸2]u8*V¯9ƒ Úöì-ä8ŽZ+IÊBá«Õ$šLô–™Óûð Ké·$I öí»€Ý{ °uÛyÇ®]ù°ÛU„…qGhšlp:Õ5µ)�à±€äÂÉž®óÄ-†(Ú½û¯ê$ï#eà”É=©PX²6$û÷_À§Ÿs}ºô˜Î0Tve¥k€¯Eó<)”4ãyf{¿¾q‘½{7§Îœ©Dd¤µñÜñæçµ9X³&[Þ²õ¼óĉ2ÞlæòEÛfµÊ›ìp´¸Ø®Õ¥l�w:Aö§½¶� ÿÓÿûÌÇήт)bô‹Ý®Ê>^^îÄ·ß�Äœ¹éò™3À7.—ºÀÁ+ØŒD†!çvï)tÜÜe¸Ë¥ .—ÊÏ3ΰ0N 7¨MšÕÔH?ûl'~ÈàÄ€ßgn®CïýÙ¥(êtMÃn{ÊË�e¡j¬‡èB[æw6œ\Þõ±�QÍ%›ä^?n¾‹©­ûQC¢i:ví*ÀûÁ·ßžÇQ°ZeÀÛ^o„&ý^Y)÷öúŒˆ”$%R’”È‚)îùSÇmÛó^>›ý¤1,ÌÿyÐÂw)G­p¹Ô5Dc«Ý1È]ä0âÙNT¨—u¥¨ÈŽ÷Þ?¢/Z|‹‹8*4M‡Ëuù 5S¯•—Ñá¶^õ¶`ýNQ´¾oNÝ×wæŒ}Ö½’¤`ñ’ÊÍ&Oo¨†ì¾ç¾s$$&fêWÏVëËÿØ©Îþ4½Pï¤,“ìJY€­Í7påBžÕ ›My~Á deùze-ýü8†F¾žü ê*V�V)·|úÑ@æj:PÙ¸ùœÖü~fwì î,¡HuëÒ—4XO Çiš|4þ¥�Žªê:0}Æ[E…ë­†¬Ü¯èÙ ]ýî¾3‰4ðê1;+*²#ïœDë,É:<ÉúºªÇÔðÈD³q•Ƴ·ÛÕI~9«üºñOÛˆõ΢¸X²¨Õ¬¶øˆ~a£+ÞqZo=N?Úß�Ŷíy�f‹NL·=­«>öã�–.ã,ÆÕe7w‰2YÖ'½ðâ6IUݯ©Ó÷Kv»6 ^ËèPã1vë*˜‚eò %ïö¸ÕZQáBQ‘%%”–9PRòç¿ÂB …ŠŠírI™¥¥Nb©�©¸x^;ðÛCL}Ö­[¶žÓÊ \ºæé-BHnÒÿ¿>³Ôñ˜f×ý;>÷Ãsüãh4M[|îœuôgK�%õ½)ŽìÜ]@4Mû´¡ëõ]ÎÓ¯gešOO/†_ÎêŠ%­¸Ø®—”8QZê – ™RU�°Jå ChBt]‡Ã¡ÂéTuS½­Ù�¬‹ëJœÑ‘”#¾)ïÈûÂÕ{ØcëÖ­¾›©ëŽÞúõ¹”¦êÞ‚gu™.|'¶aÂÃ;S_|Iº_µë‰~ÿ;Ü–3O D®A!B±ZåQ&î\yÇí 4ÃPŸ¹\jECWJü‚‹÷˜›³ûùæT˜fÔ$J v6Œ8Øpâ`#(I\Ê!�Só2gHOèª×?΄G ï¶|ÐdôLe«Î+=4aTwqÒ«××z¨­¬t¡IÔ‡¸4 #�ã]çð«Lqìå�$)W–Ž—îSízëE}·oÙÕ$<�Ù$IÊ-ºŽd amú—&‡¿zôt&¿%¿n 8mu•ž˜#�Ô54­ú9!(o3’_{ç÷à˜‰œ8ΰú­7ö »þºªª÷F0ìÚ]žg`±¸mÙ0’ÑuޏÁC{Šó-Y>m¾ø}ÆXëÝŠM÷w2ôÜCý£¸ŠB—Ølʳ C S튘{ö:=Àa„ä~c—2gI/ùN£0õŸü¢@‚_ÂÜž)oþ»á�‡Ö©ÙÙþÂÉfëÖóp8Üs.œìé¾P\gŒ¡ý:›ÓB·¹â�Œ@Ž(î+Q7OÒ†"KQ´©Wª2Ñu?»ºíä{’-g™s,¼ÏÛ $»ËtáÓ¦×sA…⎻Ëx†ïLþúÀÏJ•]´Y·.²¬ÁÐŒlé¾HÜÆ6¡«� klN Ýæ‹«‘ü Ë�~€Û�ìïžî�¦@9þ–�*X뚯I#’Œîó„¯Ì)l­‚ó¶cÜ™[n)}q쎠Tw:Uüq´†hz{÷wÃö1áþ{¸7ÆZH[(®fD’ Ë_üˆú_ÔØµÆ{RuYvUÖí‡'ZÂKöÊÏÃkƒÃЄìì¾P\o¼xÞ^« 9¢%½ÌýôåòcòÒÏkvÄüí·BL´#m¡øÍ“Z dˆ¢ÍisÅõŒHÈr€uêU:�¢H €vu|¾Qð]s‹®ZTË�‘ÖK–ú¤÷Æô†´Åa{¸(ºÎAŒq´ÔòYî§‘/lQ�)©6ïÖmyÚR§žÔi(6ÄÒæ´¹âÆLöÈÒÀϨÃe@3NXÞlææÕ¥m�…‡è²�(r™V¶o¤µ§³@ý«wæ°TúëëG¡nT%ªWy ³wð]«•ŠŠÀÛè6ŸuRÆš C,mîü†¸@Q€,7ÁmUÓ$@º?̺®ÿ}Í¿ï¤t]ﱌÿy22Š@ˆ,´¡ëlî$W¨–Œ¬}œ¥úmAdïàWÔìC›LÌK¯¾ÚC€‘#:“°0¶5€{ëÚÎ+‰÷D.Êã/g«‡ sÚØÎ(e^´=¤IºG�!Tü_ ãìa±Æ¨@ÏòÅNOÎ$ ô7²´°�ãè·y$E�‰ <ÍII‰Äã�¥A`ß ¶íWï~H-KJö¹Ê޾n}VW=-Z� ^ç5ëãÿ &zw>ñIúæC¸ BSVWʾd{Tsêm<êÊG´äÜm¬qím¤(î�¶B^kýe€,±„àá ãÓjܘzû­Þœªê÷H ¦ýWš³+Úå*;þ¦4R×<×¼Gr;N?ŒL«~Îw�ñ4ߊ‹ë"(e‡_±=é3’�Näçý¥ô.›�¦ ÓS„¢�þØ;�‚zÅ’j..:Ú„ /¥1f3;7غ¯$ "zÞÏ®ÊÌiÒh]óÜÖ¤ $§ó4~YD'&$·"—¥+eG&YŸÖUÝciE Ç'ð‹4ájfÄHQÜ[ÉBeªHàñ¹‘ƤIÁ€˜8¡;Í0TOƒjÛ††&䢟[åª<½D ÝóäŠ2’Ýf ËÌÉ¡™3”îw}Ýú7oËXŠ àÕDþƒ›ë ø% ÅMm+Ø:ˆÌ‚KŸÅÆò8 ø¹™(²xçíÞF³™½ê¬qC× ÈùÂæÈþXz ^Æ Œ@¥ÍãWð µ?ŠõGÑNWù±)Òóº†ØªŸS¹¯%ñïõŽ ~H„�¢¸)myµ£È̯MºÎß�“ÕòôSHÓ¦¦8ŠÂ'FÃ}Aa¸×þ�f¹÷]ƒ~êÉQð“<Æ»L6œüÖmž¸ÉE‡äRÜ’]®²3¤‘Þ¯–�œÉm…/ºš™zEŽªTuö`…•)©Qyb*X:Æ@ˆöè#)µî Caå÷á¿þ&kxNNåƒÙ9¹ @"……’ÑéTY£‘¶ t EQ¹²¬ž³Zå,ÎÈ� !¶ƒ¯·èºíÄ|›Z´I¯‘ƒkJv§Íw°áÕ›7KÁ:WÅÉÅÒhïWGHÖ”dáëŽ"Ô Ù%²íªxÄ¢D�²«QE4›ïÔš[dS«xAIëC†ÞËtë…믋�wdæ`IKk†´´fn �ËF 6›ŒÜ\«¹ @2Ÿ;oMÌÏ·!7צ札tœ=kQóómti‰Ó¨¨:1™è €äH’<@õAP/ÑuZæ,[¼S~Á;ÍM6v[¶ŸHH"5®w•_Üc]o Hæ;ÉÂwÉB`Á]ºNµ*‘ǬjTŽSkv�¢bó­rYÓé”6áòub˜ûzÅÒ]»D¡K—¦¶Á£( ‹ÔÔH¤¦z,bhxE¶<{Ö‚[nýA(*’Ή�z�E×d(Gß´‰åéòÓÞi¦xú§®³Åã¡üüjGÅ™ãàeÏf È¡ÉÂ�­Æï;üëGêN‡Þ#¯Ò&rZçNMõ>7Ä0iÝ£I·®QHNŽM“«É*Ö§SÅð'µÙw[­ÊýÑ>J�DW�šë�ÚšUSóNÛÐÿî²®wssÚ>#õ˜ýê*´Ì™6¶x§üœwZœ�þi~jØalÝ�+ªBƒè¯µ2mî¤i;®ïõ�¶sg~(Š­Ÿ-=¦¿üÊ.›Ý®ö�ÙÐõÝ–-W¦�²Þ­X½ÌŽœ �&þ�çC²s/CýãMïOðzÅìñ˜™!!5Î,wéRF¹,[­.jàm«°æ§ìP_+V¬<¥?7b‹äp¨·äpRüÊfÉRʾ$ S$½ƒG�­Ísüì–šB²×(GÞ´‰åû}7xMôw³R…‘©�ÿZM˪õÅ㕽 �ê ]wÇ‘½ÿ�µxïý#¡¬&(þ½ú ytƒÓéTävr|ov8&[¿b{RszFs åmGó š�…¬®j®#¯Z¢ÊÓå§¼ÓÚ˜èofµr:tÞ4€[ðqÇ­}ÊO;x§SÕÆ�Ýîœ8qgC öaÓæsxpØ:§Ë¥Þ `Û•ªðZIÙ*säUÛÞgÔ„BQ‡×ø"ƒôC¯ Mч&Úâ¬YêÃÞi)ýéÔd¡Ü@…VðB—Z9î¸õæJE¿Ñ+Iéׄ™ö—(S«Ù¹¯¬Ìizï½þM7Ü&ŽË¥bð�Õp:Õ-p{Í^Q)©á{z�Ñp8|ÂÙ=·ÍÀœ U·Ç��ÉÙî‹Ä_B%¸«\µfŒò/ø ¦Üì†üˆE)ÿç Û£Þ‚ ì©8ãüêÏw¨&EÕ©-BêÕåžgྶ¿X�Œ|å!º˜ÊüÌ5¡C²ûå*½è’\¦{‡åpÝÞ”›6ªχZðý¥üµ“¶']ºg¨P\“ÈÏZ�kd;Ô°æ1&¥!—kU¹åæx=À”qÜ!ÏäRà™1:óUë�ç­·¹Êýº Ï™ÀG„\ð ¥ü͓֧TÝÇñ¡`\"¿èÖ&\�×Sœsha‰ áWlƒæ¦›šA`HÜ÷I[Ûéu&ä¢; Ukú8ë�ŠU÷öã’nnœùd<êJ·–¹Ê§œ¶>£ê>޹¯%ñKn Bp(pjamÛ…×zByѲµ¶�¡WÏXȲÆ[M„û†‡�†, é÷ïÈS*Ò_´Þ¥X}]…�3Îz¤¹1"Ô‚o*qUÌÉ–žÓt/Ÿ9‚³¯'ñõŒNp(#$"¹]dТë:ðÅ—™HH\ªµnû¹vÿ}?©ÅA·=%% EÀb(Ö @›éµ&dØÏÊ–clÃ?®ÂOÆç<[³çhmù¹ÈU1/G¥éž¡XBN¾“,~’V Á ‚�È`gîûö]Àu×/×FŽØìèÇè«§ ŸUìÌO¿©Ïwò =—+«×œ©± Š"è‘¥õŠ`²àÜx(@V€ïP»�g�ë E!ÖÓJyú8i˜f÷u~¶?ï¾cH[•Ÿ‹\•ïåJ/è^Aÿ8BN¼�,|ÙA¬½§K™K5·®Aôü|žü¿_ѧï ýèáâSóMsŸjaÊoÎÑöÑ-�{?H?�>oÙóÄÃë]:-S¾ûþ¤ßpi—è{K ö¤¬·� wÈ“@¤ÁùªÚÉh0Ô[ôŠ#²õÐÛšÓËUnWá!Q\½éÍ÷…ŽÊ%¹ÒÝ+¼§�"‡g¦_§ÖAp:)µ*¦@=ÝåR1gnÚ$�åßf•š4mÃÌ߯=íõÂh"?g<øa²ðYçrû–QßhIIþÜõùÇ¡(¾F™7Ü ¡Òàž±×tÈ”w䫨òUK½D/?¢”yM®¹ôU?'…cëæ*\€/óì¶¥ç>©M98+EXÕšgêô#Ë–4‘e(Ýß5&«×œAbëÏñ¯É{a·+ÇÃ4mË’öbz$C<„2ÐD}¸¹1óƒ¶ü·Êò/¯�ÙVšØòSyÞüƒ�¤?7ezõŒ�Í&à».tp¸Ã¡Üo¨‰:‹^v@)ÿã5ëÓºª{žÊäOHà—ôoÁ—åK•Ë œ£áõñIŸÓ^X“h ìøPÙ5¬U¼àá(xìXúݼÃZ�ü|l6ù÷Ž:8/E>þuòä½zY™Íš™å©·™![祚_ã 'Õ„<«‰:‰^¼ÇUqô 볺êë*<9‰¯oˆ /9+Ißæ»&Àk²gžÛÓ¥^G¿y-,éâž{q±ûû&¤õø»÷ÀnWà÷F:kA{sv°‚{Ó· —ÿN êòñ¬Ùéöø–ŸbÂÄ�h×îϦ 4Ù:¯½y[žîº´³¸ÓDS_(®€pGÀªµýÂWEæ;Òsºæ9¡  r^oÃÔ£–3æšÐtè‹ÎJöuÅ®±ð: cÈ®y©âææ†úŸ^�Õ°¤¶áôœ¹Hl½˾ʄө^zïja¤³fµÏó4©×íŽrùÜúRg?É®Ðv»‚wÆ®]0hð4Ù=¿ƒ°=š¥š€ÈЉŸu6 £©¯—wȳZ-çju”W´ÕiÍšcA×<'P,!YS“…eD&ä‚Ï>Jqåñΰ;‘§3§·Kxª~š{+䜧mOéîÞiðç¡‹¬žß^ø5†õ|Eñ‰û¤KXæ3G*?)•5Ó2¸#_m0@P�™‚îék�–ÌÙöç½çÉœš,|U—%Ru¨:´™96uG¹ü¢w;£²q~=ª¢éЗäJö‹ÜFQ4Á[óô±éÉb)OÕÏ@ó`¥|î­Ó¶§« ~ ž&{´VÅpÆ4DØ),¯¹�ò €t‘–pÛÙyoŠù%(Ñó×8í'—Øýù†š‘",ï ÖmÆE‡öÎi ·£T /»úfùi~{q_“ØÁk:ôYglʺb×xMÓ«~:€]©<}`F²PÎÓõóÀý½R>ÿÏS¶'tÝ7숑&{f¦ëãªñ¾Ž rQsQ‚‘þ$@–X›t®©=5Š~îG§åÔûöQÐ}|Ã3f¶Vµáký¡&dêÔSfo…êX7Î@¯žŸv4ŽªmVŽMÞî;’èö¦òtúÔdÁi¨§EnF¥|~ê)Ûp]÷íáFšìžŸ"¬ke ®Ó°„˜vKSyzQ€,Ñp¯ã« ƒU­è9_ÚÙÙÇÃ{‰D“½³S„5I¡\ƒ2ù´EÜ_©ŽðNki¤¿›Û^Ì …モC›vÚÂl/•ÇÀó;Ðìê 0;Þl'¸ê+xz¥+oò)Ûp-°à⌵{-ÓôÁY5ò•‘p_VÐ+PþE×€œÏl®ÜåNWa‘!»æ¦ L¡±�»„SÓ\¯fY¢[TŸÉJ¢‰þvfŠ�[ß÷*ðçH²§BÏW‡ `O×pfϛɂY?)‰çB!øäÓÒ£šŽx β{NЏ:©ž‚_.�=©�YëÁ̃ϭzÜ–7kൎ§ ÇÅxæÎ Z©å¸6 ^3æH†¬YÐÞ¼¯)G‡Äáá6UwL8am›k÷ tÐÅL4¥�¹’£H½íàšæz5Ó}¦>á•ä�Þ3‚Ùðj¢^ߺÒ+\¯»O„×ÙKÈž¹)âê]§­Ó@P¤wGò]ê®»Ö ¾^Ä,€NÀekãÓž×n*ð¹Ü&’!?.loΈd©�¾Ã+]sÜšœkWïöN»>œþèõ¶f‰¥êo.©ºcB¦-ö¤ÝçÕ!8Ô7‚ùå•$1²¾u]ü‘‹=ÜCp†�ÝóRÄøÐ ~ š€— °ƒš° á?•Ç�¹ÚÿÑ&,õõ‚â©p:´‚—»tiü k× .ÕûG¦÷‹dߟ((Tìà%Uw¼tÂÚ:×îãQcpÒHQÇ[š(Ǫ‡£>õXu�]UèzTÓÑ ^^B4ÁîÙ)âÊV<�XŸ:j‚" £š¢ls×ûÎǪM�Ÿ�ì¾)‚ÍŒ2Ôxõfs‰œR®øMêMÖöŒ`Jj²˜ä• ð�,š¦@ï.W[8Õ›½’í¾‚û6¦ºg^ŠþXî£No[¶ìT‘^ß^M@…`Ðl+‘ÍeŠ~'ü¯Î ÜÖ®T£®Ñèl¢à:{�ÿÎ3^à€ûºÉhà 7^˜à^O6X$¥‹0ë yL6?Pÿùø,5±p¯ÎöÂLøõÿ—ß®K4×IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/stitching_modeRefine.svg0000644000175000017500000003154414757047403025132 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/switch.png0000644000175000017500000000075314757047403022265 0ustar00paynopayno‰PNG  IHDR szzôsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<hIDATX…íÖ1KQàï‘ ,¨��€…©Å&µ`+¤Lai‘ÂTÖ‚¶)’4‚…½…¥ 䈅…$‚vb˜.¢n‰òRÌËà¬ãîÈ’0^ófî»çœwïáEJI?c ¯Õk5€@Õ""ú Uü4"v"b¶tbJ©²…÷Hø…cl`²SNä­8"žö Ä ìa¤mï¾aë)¥f¡xÖbðXëÚkæ4±Øƒ ,ç€+œa ›… TÐó¸n±½ÀÞa¼tôq‚?ø,“úðÞ¤.Xb´àÛ ž<ä¼Ò>/#bKÖÑo È즔nËžy¯xŽ�2I/ew{„¡ªú&?"b x+˱Ü/7˜ëÂuá{Jé £ØÇO�ã[¥¦ "¦°‚iL Ý÷ðºúøÝÑ ïPc¯ð _q‹ŒUæ¿–ð«U¨Ôˆº‰ÿëET¨ü“þ¯~• ´®IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/tomwer.png0000644000175000017500000006057314757047403022307 0ustar00paynopayno‰PNG  IHDR––<qâ=±zTXtRaw profile type exifxÚÕ½[–ä:’eùÏQäˆ  Àµz=üÞêqãFdVVWuýtx\7wu5% ˆ9G°kÿßÿ×wýÇüGÈ÷}_¹ÔöôçáÏwî¹ÇÁÚýûßïk¸óùýü¯?þ-üëë×_ÿy)ñ5ýþúì?ï¼^þù 5ÿy}þëëW}ÿ|NûóAþᘼräÞ×þ|PŠ¿×CþÇýù¾‘ÿö8þ›ëÏkå÷åßÿž+‹± Ÿ—âw éæ÷æUw�z¾v~/ÑW.çwïð¿\»ë¯?þÛâýõ§[»{üy=ýëR\÷?ûù·5úóz(ÿõÚ�úû…^ù_þ¡ó0÷ßÿ÷·µû¾Õ¾oÿžn䇕z®?õ�G9â�“¥LçÛ~Uþ+ü¹ž_�_�G|Ù±ÅnN~½Wè!²²_Èa…¾°Ï×7¼ÜbŽ;V¾ÆøÆt^k©Æß³)Ù_á‹•íYWjìÕË®%^ŽÝK8×íçzoh\yÞøŽÿôëú¯^üßùõ×}Ÿ¦ÂÝþZ+î+jÓ܆;ç+ ߟ5-g}ϯëovsÿmc;XÎ27pÜó÷³„ÚV:ûœx_¹óuÿ\#ÔõçX"®]¸,:‡ûÁ¼Ãîc �ulìÏàÎcÊq²¡”¸Âõ±7)=lN‹^›ï©á¼7–ø{ha#JzRekp 6+ç‚ýÔܰ¡QRÉW)å)µ´ÒËxÒ“Ÿò€�7ì6bƤÿí¯×ÿ×øÿó�õ°‡³~¡°1™ Yï;°¡¼Þ€maÙ}çNP½K`×b}2F”žý¶1a+ÕÝb«â;× 3·>¾æ.óý°üŠm‡p=/áBó¼ýÙ‹]/ï]žÐê[JÀdjí»-n- Loag¢’6βR~°6îóz‰oÆ™ú~æns…/ßß½Þoøå·g ,YJãÝ ÷Þ_\Ü1ëtq«°"on…ÞyÖþÔš�Žý¿üzý7o(,|»wƘ¾0ŸÞ¾4GÌ<Ó¬)Iõ¾æ`“VL׎ÏÚ˜\ª É FŸ¥ÇüAϰœg�ãþãK`dç=© Öçëñ{E¾ƒ«ÀDc`O)˜Ìz6ˆ5Jép•oŽE,Ò|gêíõ£v’Äx¶$[‹ÅÀE0:¦X2ž Ž{�„/ì¨_‘õ|ŸÌ'®î¾vsâ¯÷ÕÞ¦)asóÚ�ಾVg =K¶×ÄdwåÅ7ïý%–â©C_bã|±ÝÈþ®‡×¿öb#û?n ,ï@±Äê]g�öWöÍ·ÅZátÞÂ¿µ×. ›˜a¶:0ù dûp,ö}CÉ!r„&�¸Ö·Tö|ñb²#áy ÕCÐâÙnºÞ×ǃ~ºjZ=ܳ²ÜÙ�í]R÷,_Òóxï7ñ¬k>kùX@ýú˜|3‘ BýÜØÎu±Ê±ïѾ2wü½7è›7²™Ü.Ñì»ó"úÅwˆ°«NÜæ‚ò€}¾_Ç•€š¸°¥>ñF¢&kôEI8Áê~úÜ·1ê™>˜Ô;¦‚I×¼ñÖ'öÙSÄNì6-ÂMÙ}¼°¢öŒR Æ^õ˜UÇ(Xîo¦6'ëWmuTg- ÇJÜÁù�mÅÛÞQúj‡~ÝOjß ´­Õq ìp�þ.äÛÞ. D€åÈ÷þ¾<><¤Ûᛸ–š–+þ¤Xf¦1€À@aXi�kCÒËw¥ºö{Çõ|›ÅY¥ÍakóÇ»#Æ·0¢�Úó`±°õIR@0øä:©> *Õ¯Œ …0Ž(íÇùëä¦ÍÁ‡¦7L&�Ÿ]y`FcãH2ϱêm¿åš/ŒïÆ×HÖÜåáé;Û*8OëƒôZ ;¯pðlp…ç'¬cwÉßµÙ‹ñÄ Y»ñʃ3@œt£üáf ÃFgûØÑƒ{jóo¨X³¤Wˆß hA�Øgv¾•�» Uyœb7ªa°ñáe.ñÝϼŸFÜ›£â ‘݆}ÿÀCçùÇÊ ÂÈÀ’þ�ÿ‰:¤o�*3Åú& ñ†!}ü½¬9ó7^ôÎwñ~l6í»@Ý :;²¢Á·?ð?¿ò…ýÚÞ4 ×ǦïÀs~'$�n»rG<äkð#Œ¿|sí˜y|7ž«åÆÞ°¾ÌVsíŽm<81»oG áų£ŽòDR"»81_PdƒOmít÷T‰òŽr÷…Wt.EÔ…Ðá*àõ âÖ°?HÄó*`ôh”“àå>C=8cûŒg›µ~á ¼±rå\Û†ø ÿµòy€@±ó­ð ¬‘ÃB‰8ûÓ�ãÄÏ‰Š°i¾{Dwlr—4å¹VüõçP賌ÄH8å'^V�†Ë?Ì$@ì¨bºý© ÁçòH¢ô‡Ó€ÿ À ¼Ž˜~s}a¢«9Ð LŽ’¢$}ãCY@´ê••|×÷Å ÆŒÀ„‡äv‰HäfÌ·±Ø�wÜ{Á ŽþÂ&nœÙGo¡ßqw¾‹­à]0÷§t¹ÇoÍ€÷¯MI,,¯+¿ F¿Êõ<‡%Úùø Ä8€E˜"úläÅCÄÅDy>ŒmcZXìËevG(*S6ôeîx›láÃ}W+Bf$p÷¼°qe´“„tÀ)?8F4•ÄÚ-0×Eîq §ÍXÊËgOl|CÚ„†¶q =†Î§#ŸŸ0¤ó±ÎÕn4çH:5q½ÂäY•Ö Ùyn‰íñ�»,¶,ßàÆ—TƒÅz70^Ì÷.›‹Íã ¶y€…ÁÑ6pkäï5]8Ö=àà¬pyWÞ¸aÉÀ!ØEDÇ/1?v1® îºpÁØÑx¹ xpÝ�PÀE2p ®Á·?;b;É݆´vøâe°¼¼fXEÔé�TüùäçT‚ݽ€ŽÖŠ"М—�Bx \øR _°¶ kÅ-J½1ð÷ÙFˆ«�dæ …Ú ïþ‰ó œvDÀ%ƒi&póÿ]±cûaï ¡Ü�÷„žÿÖ•òÌ5ðưpl lPëé3ÝúÆ·@Oà`Š0##&* ECñ�wÇ÷‚)"æØKh°ï�^�‚‹4p'BUÀ o  Åõ2!ˆX†À+1A˜; ôb)lš‰+‚¸€Ö`S^XY�—/üëëD%—Ç<襤ÂFS†ëÜè“ m ç^ïÓŸ«‚}As ¨ ¹PG/Lp܈5>¯@†éVW˜Dr`S-kñQ®Ò·Y¡%¨ÎÙ4‹¼ð Öš„ðwôoc{ˆ�5‡Q ÃG®ÏAÜEÖáJÈší`»r»T“7ø9¬¿<þÞ¸91 œ-4Ê7‹œ 64GX'ÿ°!R¸b…šI*8åJ³!%�9„ÊÅ­,÷‚A`’d´õ{=È…ŠƒcB^™xpÃ_ÐR¸è=Ä'̑󹊄Àà ¬Â(YÓ'äG½… ¶sÇã•�ãßÑ=ö,­Ñx>¿šv‡$‚-¥¿ðÂfaÙxdþ…ݧŒýUâ2…öwä[7Åÿ™xˆ€%ˆŒŸ¡Õ‘àþ†ñ‚KG™O›¸,.ÉÝÌx0j±óc”ÝO´Í u~kÙTÃÓÑàò{�uç~¸ªèY4¿†m�¦J‘^$+…“MÙæ4‘†ŸÙ‹Rˆºd!ìD L «ßB=#Bv‚jífX~Ê¡z S~‰žXÈ”ˆ·²�7°ÿÌ«õãýÖ7.!ðà9°ùPLöAw ÕPÿ4¥¾x¡¡•�‡F³È£ÉØ �ósCVšâƒr¶ &G¸a+²PßïñXI®¸QF .—-Bαؼ�Jx�u|€-YD2ãŽ�C‚#°ÇíNL ã.BT½ÛV‹î4¯b¤ oB"Z$ó�<`€BOr²oè‰5rëßÀ²�͈V–P·€Ú+üº$ÔÚÔæ1PÑ<ÕlÈóÞÐ8ÜØæ� Ò'�Ÿ_Â5.2Ù’ˆ1ÇãQ#>`ùÅŠÂbeƒ·NÈ>èø"úÌ‚g“@¡*Fx›D'"cC~¢ÊñH˜¦wõº5ß!?å{+æyÁŸ—Õ•V‰/DÔ†c“«#r¢}Lš»ªñþØMnŇ £<î¯ïž ¼^ü’¾Søh ýmÑ}¢<_Pµü…µ^·>­á¡ ÿp­Ä7 ѹs½¬HÏĽiá)Ýü”º¥¾IÂñ±Öˆµ æÙºþµ&kaAM^�V,Õš^ Ý4»¬ŒÁ0¡?&·¹Éê„èGÈ(h“‚%KðKûÒcûÂmp»¿Òyÿã*F °ôàþ ݼ"f²¨èn¬óúÔÞôá)g¬ƒb×x¬µœÄðW‹â<Á„Íw7¬Yºú5 ,€T+¾].ÃÃ#bÀðx^c“4m òPiótP‰ÆÃ⢔q ¨�Õ`!duûÛÍœøA‘vT+³õ•¡¤­.ÔSá�ÐñC¶Ž-ê×ûΉ<õj¾Ž¬æ§ Þpc=(0cíˆ2ÌD�˜ëª¼™…xŽfvÈb [iqWB|Ùn1À¸ë l´{ ómˆgS]1NI|-ñjf=°38ÈFlãgù:ѼqÆŒËóÆ2÷<…c1Òcb ®op¿àêP~°o)á‘„p˜bí†È·7ÂÍõ(³ÿ2¤¬£˜çgb‰ø=ðˆ-‡Crq� $ÄX €ŸÐ’ ÍV$ÿìÑYìe_ªt¤ÅyÒDX\.’Ú…úCЭ £À`vĬ¿Ù‡¹X¢0Þý¨°/hZhš�FAò‘¦zW¹Yl‰ã4# ]>V—æ´ç2@ÞN�¤&²ÔÂdÆ„"! ýC'®¯õÂïqYž­IÔa­"Lù} %�ÿ:»ˆõÅ ˜ÒÕ¼°"–!FÔ¿‚i\"R$^Eøœ¢‡‡°þ›í¼áÕ8`[¡• ·Ò$NøËò+áµ\uæÝ€~d7¤/ðØ ŽHÂÞÕ~¸3ÿj[ XNœ–9=Kß ø¿ÕÜvfù aúEå°Àäø5Xî¹›ˆy™À1ÀåeÆšMy+¼—XÕý 㪠§‘N®‡ÿƧ0ùˆ=[¥5w9é`k¼”SJ šŠaª‹²“}Ú×â RöÚ –?Ø2¼º½0«…l¨@øFbô‚Œ!³Oß[÷!§û‹åõ (&²°«¨."l’q·(v¬³ÄŠ"ÛáÇ Éÿ€i¿  @i$bM˜Ü; Ç1%;="a§7HçÐW½J„»ÑÚ¬¸q‚Q™Ç„ÃûRˆaAŸS +‡ Õ†e6ö55ý"´±^ÐMuØ*ÚÖ|$/Ãü’û>–ú í÷Ë5Ë!ÑT^D,`©Ad` `Ä-–xa]jù1a�°¾‰�V Fó=õ2¯Œù=»b,!òý` ·±õIß%’N ,`0åŽ{Þn®fÚ^nëJ/QŠð‰ZÁŸ0LÙù)}3^°I‚l/'ÁÕ0�¤ a 逡Ôuû  CØsQ‡IŠ@Ç®ðŸ7,¸R³½¦Ns©–ãs\ò†î«q�£üeÎ0[”õ„…2,NÁQ¸¥jMÌ,”$�jjɇgèÉÕ«-9,!T—GhÖÓ°_Äåæí£E£á7ˆ¼0+12ŒÒÎr$��-Ìó«eÍã »Òc•\Nlžà€–Š èOÓð|pß•~B¢¶¿ f %�¼ÓWC3~cÞ˜(Õ§UtëbÛÕÁz¡JH7)ïÀVÍì¶y¡*,j€€½ï=Þ–zë¤èañÀMdÄ×5@à1í÷0ô3YW¸£ú+öÁ\2z„o}"!7rh£:P�@4œà³€UØ?ί8³±ãóŽ‘.ް·:w/K-ªY° ''¢¯ž…jâZ!7`ë‚<@ÿ’[A²éC"ÀCŸ D}«õ+8¾ÿÅ�ÃŽ¦VàW6(@Lßa [/ Sc3¸1öªÎ¨ÑZö­ò÷'ZfåNlaÈl´ÚB»!£\òê–úd®,v0š5L�ûôÖ|¿2 „Þû࢑"PöÂápü1ÿHÚeÓ¯Ð"øg(+pE˜„�‰xmpÈXÄó e ×á9Vïà*ª¿n74´å¤â`E*n|%E¬�‡a7C"PíøžÕ| ¸ “¥P�v¡�¸Þ²�‰UÅ9ç¬ö€ðÑlŒá‚Ê“Sø.–mo/¤aß|YÑ/`D2Ô4äÙ…`㛥ž eCŽ*ÄA=–@ä¦ãÃj@× 7»Ò Â'NEe�,dÁ³o6E˜ÍCšmSÖ1š!wÛÓ°ÅG"ožkÞ×J˜­§"�ÜÏéæmÑè@0œ¢»-5¸>Æ GÄo&lm hBZ ½‚qæ+¦»®¬å`Úv‹:„ÿ'Aátu… þ.߃h¯rÜÈ).á“ï­K_“€_aÝ•´ÙÈÌ¢±lƒÊÀï:‘ÑÖ‹*� ›´˜»AÐÔÁg«ù# ‘ƒ¶B9†“}|¡jˆÈŠÂi/Ú­S#÷ÉŒ©¡áÏè®çuÇÙÉ .Ö¿lm7vC® ÂJ@[KRõÈÒûyƬj³ˆ0Õ²Ú4ÿ޼—¥ª†Lå:`-zKâ9V k×îÕNuáKÐ0È{7 Ù€PÒÛÊs%ž¥ZÀÁ‚LÞªÀWí-cx|)æÕK„–ÚeÆjÚ=ù0ý‘‹�k…mMñûîóY…» ÑØðŠâÆ^scu¿]MÆ,Â/Ÿfý— ½E®#7Ñ*¶ ñˆÑìX /ʺ+æYàý€�¶ _‘˜ä Ýœš‹]az?QöwP:&úÙB+Ï„_Cªïfáï™ñE>Â+£-=ã{28õ 9åC ØØ¿~‡ ë‹'Ýn°¢ Í´*�t&v„ù@-2Nk«¥{ÆËÆÙÈO³1ñ$>Y 3i3è·3Ëyþàž« ùr­÷ÉbÈP?øÞéM¢[}Ö{µ°dÞ¥¢ˆnuÞ6ò¬2“ûcy"è–½?o ³«áGÒ«Ûª±c°¡‚¿w¤ÿ��XÝe[kïú;+Œj}•ÒHq‘ºÜ"PÛ1³´’ýI÷W”fEˆÀ²¿í§4~‡ ÛIÁ·ÚƒP!(h³„Ä£avíôÆbJ�¿ÁœŒ|ù–ÅÛ 0ŽŠÙÞ�ùò5`ü÷-à™„y u‹Ï˜Úñ¶Ü’"î¡J|y´qT)Dά›˜ö`;fÉCR…¾úií��¼ if"H¢Æ¹¦õɯmošÉë×÷@Aq¸MŒ·üxaÇ�+Œ\Ö“ú,|;žŒN‰êÐíøO‚&ëœý½º\Õüû˜8A8)Ÿ”ž· iØÐ¿Žäæ×s¯Ç>üOz‰´ïsbðv§^0èÞN9L";z£-·@ÃMÞ®Ù qC@쎃«ä3å�5ØÌùÙxÙ†Ã2ãÍép�]1ò�Û º† �ŸUÖ“Ú²×ãƒaØ÷ü`MÉç)£ÎJ,àšo„Nš‚FX¶\ã×Ú]�:z_s /%m±q�Ø@¸^bÒÙd,(Ô‡®MV1×Ó‚ŒŒÿSS2áª�¥¡òv¸ Ù3�á%ŽðYüµî:�½m7­õò’±¢g�ú÷^Ó˜f€� ôõ¤¹b„`óH|ÊgÎQ©»úÄá!Ù6TV»7’øû¢µó›ØŒÛ/xArQ¯j^äD by0=ŒëOà¾Ø3òÀ2hîÁ]ÁÒ^.Hf™y¼3 ¥2ô¸`òÑVï/ÀìmÃ]ª57tL·’†©ŒP6F~ðá À­wñäãB–!d :¥ô_-òοbáÉ4‘ļ»ÍU Ø fC1Ruž¡†[)ŠêÂÈj&ŽG®�Øf�’hVœð4àÄ,òm}‘~IŒ)æR!q×KBOò°�Žš­Ž}–Oµj•¾¾§ß@›_¥ˆ‚¼ QtÀ=ÓÐÄ8ŒÌ…»O_®M\ï,»”’2x Ë—„;¼ë° ã�ûêŸý™V۸ŭðǵb$º‡Ñe+¥Ÿ=¿CaÃôP柳 O´Ã”ЍlÈ7Ì8v(c3DàùÛ>S™E)Ö“ýÆ"qµM xà¾P40fÞÞÒiÌgn۔ӽł468KÎv¿³îO†Ù½0 t¶sCÊ '�¤ŽiÛaðÀ˜ö…,!‚í}Š}¾#&né�,¶Óý4DˆÖ__¿|tÓ€éA5Ñki&P09›�¾ßŽB¶ê€íiSÍ[~Åqø„Áò{5F·]…Ún{ù¹;Ø/ò Yc[1Ìhn6áÃÊF�&ÉÓ8YS\LÒOT’Pf[qð>¨<¹Ï»{GlÓp¸« =Vž[ÖFð¢Ä¶‰ ª¡ŠmÂðÁ „ $Âúâ–þXw$&Á†làÎðEaéJ d?lQ@l±¨ZTõÖnLæTkpÚ)·r^ƾžÂ¥°ìoN+’™ß;mpùïd®Š¦ wËPÔØ¾+ ?ååúpŒl‰Ó¯Y®ÐNZ2hºÓ¡vÁ:Ž`Fpêˆó¦ü&zñjaÖÇJÌkÞÒ̧ëL ˜ ¸bi±"‡ÿ•PAØ<–7žüÍó°—Éœü´!,å7ÕãfÇzü˜8•ïTb\g¢†A¾ Àµ9šb9æêÖÁ­ô|=6G­„£_ì{z&~î…›ÅBß°·ÔÕ-a{Ïž‹†=ü ('pg3RÙ&ÕÁ²n3lTø«þrýþÎhÈI÷ÓñBü JË ÉžÛdE2Þßh¡Å»á£ÑÖ‰…ÓN‹Uæe¡p n�Î`Ýîdzޛ¨‚ñv»u‹ij¶!AB!ª·ùò¡øý<»¸;ðÛ`ø÷mW >�0é—¶t¦åÞƒŠDàÆÓª V~ÛQÄöW ½ºÙ˜‡5UèÂI�ùȬé.p4þ¾ÇÇc+,ž›´Rö�+Æ6/·–eÃmÄ4‰z8ݧ W„Ú��VûÎ?ì¦K6«Ã›ß“Àg]"‹­æwÊÎ^’W_–I<öFmA ë�ra‹P€h‚œbu›=XöC²M¬Þs!ºw?µ)ЬþZŽ‘Wž³¿Ùnë°Å¦$>ÈÄp1×ÒL¯Úü`p³]\¬�•„ie�]°õQ~¼˜ƒí4pørO3^’Òåá0X�ÑíàÝ©hzŸ *óXتÉvããØÊÚ7a*(¿ß|OV9¶3‘%½ì�¿ÆÂo¸ (KVñ>�…D[³lcR%IK~ vÀ=K¿JW*¬ƒß]â8 ¼L6ñÕ>¸×+{Jm„ûÍ×ð)ìÊó7’ y3_„©]Íî|rÂ-*6O–cY¹²Sqœê]Ò‚ÆÆN$+ßñ¾ b·nKóUåÕ0ÒX,çµ 1÷âÅ?Ë ç­H¨�ëÇ ÀÍ Cݾ³üœÚªqzÿÊàý•Ƀµ¡ ¶s%(¢YÚÑjà�iÔ½/*!%«êÌ#Û6l E'âWwë$߯$bs 6²cB~yc Ò„ô^*­@’7„°ƒª}Ÿu4#�¿Ù†cñQ`\h•ÑÏHç’îpYl$v?Û9µ-ƒ4ñ h#€p4p^µLœLÛ0òÍ·ÁèâÍc} '4¬Xº!µÛCj§©Ó;Ž™=¶ø#·Lã¼¹±œ] ;í?�0©“ªåyçi úZ»và RŒ*Î^&bª“H¦ 'ÆV‰…²Þ@Ђ-k|�\C†Ö$Ç–z‡ÄÝ6c$[÷>Ž3Ãiäù€SBlüåñ¡U˜ä±ÛØ#Æî0C¿¯³ìÈÛÜ:9QAnxzºí£»f蹺«9ÍdûœsÎöš>±6Ò5ê{šçøÂ/hn°d0D+˰éi"±—Íγ <(á/�ÀoöÚØíêØù*�§ê2`¢m�¹¿5‡È]¡µðšhÛ*ZzV{®qZ –¸Â@ «*™Æï¦@¯xYd\«ÝÈB´zy <ÃF@³g\[ .‡aå™UÎX#‚õt`4@¯’u`Œ‡­Ž"Vñ÷œí�<{ö,t¿ÙŒm:[\¢*pY¶9Ž—ñK�TÀžmc ܶBPÇÑ!íú’CÚ[–“ó$¢`To²ù zzUÖk±p§‹½˜çÄklƒb#eIoùR>á ËêÌÌíÓËŠ}ñɆ"tG™è‡¦µèí0ê s0 ÷ÞHQV¥¿Ø oÅlËg¢šÅã>mZü’myŠŽ£OVf!þ-pÝŸ9Öt(C´Ã,�ÆÁÏ‘.ð†5f±RUu*3^ ÿ-*gsãv¿�3vSo`¬Ë~=SF…Á~àºé¶\•�ßj(tÉ<Ò&¶+µE†È>]gè @ý�Ogšùvýôè!µÅ !ÔÖî?ÓÐ6mÍäû }Vûb=ѨoHhAâ ž×PÉȘ&‡²�P ^Q´ø¡ 'Q|_Ïù\™8¹`–nù/ 3”PdXÀ^ ²�vK¿Ââ8=,Ýr–Z`¾Î�¢®á�o„ïëµ?†ÝÿGZQ´ö¨pÀ�Ûlb¾églí©Ök·:Êö3.R>SаÓh-ð† #>ñzODuAZЃØvH0Ñ*”Ãʾ™ž ÛµÀÕßz½ìƒš§äV†3&Z-JÖ/˜€ƒöãƒ&b±ÌdÒ€¢XýE"Uå*îÇb›Â�6n-óá|­_¬ïÚ¹�Q¨Iœ(2Q½î“·(�;;ÇðÄ1¾>vZðñ­lòxžÑÃiƒÛõ3�±•y¨Òˆô„¤@Ó ao51g®u@‡Ûuóã›”šz�‰È`Fî@.¡ úT ÏÁh5 ËøÎeßT»Ù?>Á‡kÝÎ…šÇPZÖØÖË3ĨWR€ž' Áh&Ô|ŽÚÅU-R6…+è[ª‡#vG�'Öwq ìtߥõÞíà%Û…é^Ø{p4l¼Áž‚aÏ`ÿ�&¤gX4mÄK¤¦�ƒCÎò¢¦M~²¼åš©cÀ��dÞH($‘íÃ’d>94‡„wÓa·˜uV¯¾ :¨ý‚B¼Ó•–þ.OÔ,NlY0ü†½{ŒvæDWìK˜CÇ@,sÝãœ�`«æÃö»µiŸIAK†nY{T¼¡kÛïÑ’¯Í›¨Â>!ä%¨N›ˆ-2Øê bÂW§}SÜ‹ Ux"ß"ñ‚0âÅ6á�ß à‚Aó-".p†nQƒUÌÄ�åÈej9¿÷ki›mÊ^»$§qÍ\­i“·% Eñ�w~EɽÝ}uÉ!ßÑŠ§Ð°ß4'+Á|첯Õ"ïA/NB9ná?œó$ƒ÷S .t@‡É,'o윰z2Áœnã±Sy÷i-­@m®ւŲ )¼ÄŠmi/*á·ÅÛd3�‰÷܉ŽD‡#Aí=Ï—^Oœ&³I†? ão¾ß²Yužx¤?Ù±êd&K<š5‘ß@.QëˆÃ–Ñ4NõB©`biàEìº>3ÿê �¨ÖcÞNb^✖¦æ1ˆ“¶=ÚêAŸ½¼¡ÿ:û—iÁŒˆe^Ãbûz“¹—M¿bÚ ÇIŠi˱7°kPm¾ïÝÎý]N.ÃR5¾( ¨5Ç#7Ÿt¹Ÿ}X+Ãê2K46ÍmQ–ˆÜNèmí‚ïZh "*!DûS0]O¼¬M¯ÇªÁŠcÇ—?érï ’Ùøp[LFË-”ȯaÄ–k¢TkÛ¬¾ÍÜ×t錎¦´&ËØæ©Ð—†šô"<=)ü„‹ßðÂ< î ÜÎl°Úà½æ  �À"”ôr¼é@C²tŠpТ5RXCµà4QN; ÀÈÓroÖÆ…ãÞs ˆLÞžÔ·žÁz¶ÚrÕgÏÀë «G,±ãÃACOXËνðA-…8.œÎƒM¾~&ß÷ã�ۉOdxPÊS´mù†Š±jDÒâØÆé()’îB|N—Ç©´ö›Þ«§¾a+ßW± fzÞƒK Q<`‡þ²¥ —„¼°sGüºfmÃÑO½1X»3! gµ; õDŒz�D³í&Ù�© u‡C§=TÃÃß`(è)ÖZýªFd{‚å1çÕäÆaˆƒDú5Ì Ù ÑÊêÖ}RjÍ !«þ%Û»¿<åùNAcdOOü³È mX×}�HÆ‚»�ÿZ!� ƒ¬9Ô{`‹ ðL¸Øé�¾dýÉS!e*„#ˆå™Zð€-ÖPi+ï˜ñÓœƒê=É =wéIw=ÏpU„];R™Ïý²¨S˯¢ò°ÄIóöÍáiu_ÚªC\}ØË�à='ʇ™úɰÛsþP`šh[¨¨ÞÝÕ3¦¨Òd=ñÕ 8O‹™])r·É,ì\æ ìl7B뺭POgÑB=ÞxkÃóË Z·Cnó…mnnËcÎðLJ�í¿y #{{tÌm¾ûËYáß dtŠ`­ ˆVgñSW³D1ç5gÀâ�îÙ6 ÏÄ�ƒî^朾}ôŸƒð¼þœ��ôàÀb؈ÃeH 6ŒÀ¼ÂQ ¯a½nßåZ&…k&@MÛËìñˆ`•. q„ßı©V8Î!æÀ…l—*ÝÖdÂÈŸXYaÊšLÿÓD`¤7Žôúë•�ÌÛÆ;•›sóJ1îÁ3L¾ ‹Ý$YæƒÒYVç×$nÁ�Þë¡'$qß D7nON*ž›e %ψÃ$†Ùèg¾¦ñ`^û@+“ý~ö¹ÞÅŽ”t5°¶¥yÉrûTç¬Á(¼fùÚä�~ò`,Ñ‚¡ �¦6=˜$šÖ í2cÁ:!S¾æT7ÃêºÃC¸‰i⇋ï¡ÕÙ[¯– Ó<:°�WsF�€´G¶âàç,�-õZ<Mð‚»þ†Z Ï 㙨†nvÌe.d1AœeÞÉöÚYèX öxÚZã) ý>=­°ZvÎã¸Àû {Kéïw¡²Ûd/0À({° ’óBgºší91îÃ~ìËÎÝÏÇBVhDêµî‰�ý@=g6É÷¹Ò4ï=ÀY4$[MȲ©pØÔÖ<ä…»z’‡k™r÷À‰—ãæÃÖ`Û¹Îh ÁÆw” ÒЉ}2‡”tÚ¾—x�ÑU±~›Öc—àmÅQÿ1ã�8‚GùýOÇðùw°Qø”edN{ñØX¬º£Q$mÕ³QAÆW¢ˆÝÝ»g¢äS@ DèmZ$ÛÉý80—ì³�O&Lsß@\ðx;�÷r^ÒN—HDt®'xF+^³ìåÇÜ{[!êÏ C[5öø™…`,ÔVùé…Ú&TLçýAg�„#!ûœÃ�b™ûæÆ˜Ç“('nÁ°²…A‚.ÐN;¬î¾…#y’x^aÁüîqSD·=àHÐJ$¹mÞÎÀ˜‡ƒö�œñË�™>èÂëµ�ay)xvÞŠ½5Ï p�ü]ÃÄÁ›`”øt�þsNygx¶³$`Ôs*…Å#ä:ÄÄÄ> [cŠ'þœÙx‡yz[4°Ü×Ó3d>�’+?tÎ@ç�Ú ÐEæÙ-ù‡@àæ§9uݯÓí£Â”°Ú»Ø yõäØWkžµ¡‰ÙÙ3¬=ŸðgD!•_‹·Ò..¡À¬kvç>²£5К.-1)ÿ4Ë#&ºª5§™NWÊ]<šæðP°‡kÀ¯1}v6gQçmñ`°4m§…bG-_ž\ãƒ7€@Em+ŸƒHÈ&�üýÓj̻ؓ˜çºnPÜk<�ûP¤•ê™é·—a"˜lÜx·§ŒyÑûZvgC=q¬xœ1´o„ ŒS Sô¶dÐwŒdÕ^Ú×Dm„T;õr� Ôl8ªó9k^Øþ#“<,ÁSNmÕ„‘Ýö¶@ìyd¸¯ýh¯Y'êmð]ðÒá?ë@Ó¯¾�ý TÓ³ÛC*¥ü øø°Ó„[o3­�å$¼äÉDä2eô €zy”(Vl�b¥,'�S×Bâ@v�1h¿¢b<£Âð$]÷ôS‹²iru_„bù¨ã O2ËÚ‰;*OÎnõ+×ÄàèÁ³"åd§ÁÈ1?Å«~ŒGÌAÌÓ9ðªûú~‡ÞxÔ�'izÝðXÁú)„ÊiÙà9§l±9¬÷´sLñxC¨üž÷}ÍÄàšáñƒ×±Øì¬b¶8î¡`6¿�¦ Ö„Xù ØÙU"4=H-^»”Nߣ3Iã“Ϙq´8îNž´U)Zf3žnq“Çj𳤆¸Š§ žyK³�ŽXÙÊ Œäßa¢ µ:Ùòýy �'8D*N÷×6‰ü<—£Qvî�#<�ý[·¤‚`MrýÌÑײîù6LqOPp/èšßüÚļMYvEJœ3©Œgf{hŽª mª^³¼¬J9¼lo¸O¼þ'g,wÛæ<›†è± �Ÿf­º£GÙ僸<â �Ò±=AË^à Ûiž¾Á³Ù� D8DpÀ œV2í JFèð:»…ù]À–Ÿ§Ø&oWþB†z}p$á*¥;¯“mCÈ�-pØdi\ͬžÅÆbê�X§Ba©–Ü‚©�èëò$ñb*ÅÓWï7{r�sæ·çZ>6ÿxüÕUmÑðŸ2ÌӜฆjâl÷ÉYÚÇžÏE˜+¸b[¼ÿYsðì^¢ˆ Æ'>%"Ný!BÞë‘©HËÛ±²ÑóÂWöM¨íHEŒöÃ75tù¾fx‚"¿˜ü‡{r¶Ìù*ûy=ŠGê°+� {†pw¶¶íõÀŸÞô¬ËC›ú—<ŽYï$6ï5‹êÌ�ÇVlϸ¨ÛqðÌ…ÿf„|#UopÀ öðœ5´A{žÁÚ·£ÀVÅÔDØy*Òö>[è8§aÀµSò´žmíXÙ•b°KïÙÎ|Ú BðG½ySΩ9h4=“+~¯£gàø�îߌÉk† 0Q·Gœ¿$EOJ*f­E<¿szÓ´¦�úgÍe¿¿“oÇô=)ÅÉâðçdÏa÷Ò ölÕíÞÕ ¢m«žzv; 9ì$µoö±›û÷¸b‹É,4!ãísK¸ÊÑ¿¯´Dãù ”FìäY=š{Â5ŸHTiû*—G¢8Ä¥Û¡1›â2–¯^ùRWÁ ¹±bûüAO$Þyý~RÄ�DO߀Sãü MgÖÆØœ2ÑmÙ³‡ä8=*×*`´·Æƒ>nˆS•hxl׉ …ö‡ð!™œ’ÇG€ãÉv<î°8;û EÖæ½@Gk´+dX�@x�öd2àrµÛL!¦±Ìnó°óñ'?XݼJ3Aàº=ãâ1"˜£› ZêÈÇZHU¢YºxˆÈö»{–Î ,Ãä#¼Ð]Â5ñtµ„k§P*®½<Çex"§}°8·g.)ZÑé4W^PX­°ƒ‚öŒks•¶*ß4aÃ@AZùC–º N`:Ó:¨é)OŽ‚z=„v©ÕÙµ……¢a-=ž£c§Ô¡ÈÎ €e£S |P?SuÍó€Ïa 9ùsAe‰�¶�‡SV‰v~äæKX¯?V&Ú_J@ÿ`/”Á´©¦®\ ©¯ÝIÝ93À¶ÚÔG.µ/žsàËÀh™ç^˜!1ØeÔæÎxMç Ï]µƒ²lI½-Ù¶›Æ/›®VzM®Â<­ÇóÝž˜Dºyíâ)Ý݉»3{~ð§¿÷W}<íà™·J!µYi¬ÐwödÏÓ.]î«ýøA.¿~ȼPŒ:·Ös ýœ‹náÏþm§÷¬D>fCd‡æ`Qè·ˆÕ/öŽ»Ws¿§¾Þq¥�=|ÉL§Ôe=·õîšÒ9 ëts=öƒHM™ö9/‹FÍ´•?Û)X“ø¡voÿ³Ÿ(âéã«_ÿ±5BðOçHbKGDÿÿÿ ½§“ pHYsÄÄ•+tIMEã  3Âj¥R IDATxÚí�y˜Õõ÷?§—YÙ÷Mv„hиG"ã5b`¦g@â®hÜM\pIBòs7ƃÈô ÆIŒúº/‘¸G Š(d_†�Y»ÏûGÕtwuWwW3Lƒõ}ž~fº»nWÕ½ß:÷œsÏ=\¸páÂ… .\¸páÂ… .\¸páÂ… .\¸páÂ… .\¸páÂ… .\¸páÂ… .\¸páÂ… ߈Û{ZÆõ×ïPÅÏe:õ.±\ì©æÑƒ›bú{²xb¾gŸ;ì$È$` Â?¤˜G3èå]„Øt0ç­- æ=(><Ü Å¬q%ÖþBª¹ôÇÃ×€€0‡I)‹2h?× |H€"h„~¸Ô|û‚8Í•Xû ³è!€‡n=Á¥¼¼@IÆgïsûBwy\Æ8$Æ£<„² (cï쵓‡™ ,CX‰p³;.\¸hã™T-c V’óm¸_w*ܤ*c å|аŠ:Ök§ì÷ªÃ·n�çÑ›0] q™”²´Dé…—QøùH&RãÀª›LŠùh è+ãhJ'å¨à{À.)æ‹\g!½(âåN)b¾+±Ú Müå\”ñxx$ãÁ R„°†0oPÏR­à@ÍŠ{߃¯c,=»óÌÇG9Ï£|ˆ²X˸»bc*p!Â8”¹SaÛÊho̻܌H5ðPŒÛ¡/aVšò^Ü'_óM'éZ&BÌ”)\£e|/CIìøz]bµ­Äš| ,®Ï¨í7t†I3*m»F~�ðO ,Î’„Ó�b˜ÍCqpF×ë%¼hº*.su¬lÖÑ‚| Œ‰!Ào¤Ä™oIç�'S©st¬á©-æ£Z<Œ”"V¹VáþiGÿ xåÀäq‡ã§Ø!© â©¿ øXü|_!•+±š¥Cæt”z”¿IirýGgÓÝÉ¡;a “‹1—|ÀCJ. ù(»MÉV Ô¡T[ñ±�6ËEæ÷­q�Ñ?Àƒ— Lf£K¬ö"Õl&‡ÿ€I a=ð¸I”ž@ »ùê­ìàT¶!¬V!|‰²åm)ᛌ~¦’nÔó04¢þ71Z¦²Ý%Vk�U%^êéôBéôBè‡Ð¥Ðèô§9”Åš`k lÙiü­k„�æäVS�!+ì°‘A] Àç…îŒW·лôè˜ôtÏI€õu¿K€?Å�n‘3¯=Æ`Ÿ‰nÐ2 ñÒ¥Ѓ0=ðÐ¥'B?ósƒDõôŽè�b‘ ØTm¼Öo‡ ;`ãXW%Ï“H›«£$jMäçÀÀî0¸6Žgát`”ÎáGRGñ؈ »N…d00rÆôé `7°åS„/¥8µ‡Ø1fá§ðÐ�0y@' %¥ B�È´¦‡ù¾—ùY Ïé¹v7À†íY6UÃÚ*ãïº*ØXmý®1”}QÑqP~I„0ÿ”Îq¨_}ô6?Ú‚—‘2™-íB, ÒxXáÈÚúåçàƒp 4Ë€-À&„Ë+~$f*Q$¢«s�B“D-vÐ5… ÉÑ< mÙi�¢Yªl0¥L3yÚB²ìm¼p-œr˜Ù«Ê0)ákîŒÁø¸ áá‘L­H-çV”�Oðræž�R´Œ³žj �ÏcЩIa[ lÚ ù~Ôü{à·­k„ÚØ¾Ûøw=T×ÿ×ÔÃÎZض˘n6ï´hóN¨Úõí3*N¯ß™W¦K1µ¹ª!TǨÓ¤˜ÇZ®c‰±lðÎRøà+8°¬Þu Ð!ÏP8wÕÄØX _¬Q‰!McôCaƒ4µ ÆwßFR´6î°¼íÚæ'<€zV³1#cÃlØSåý¸»áº 1�l¨!i0v¾Ï ÔîFwàÛ£XÞ.‰³z;PÏMÀw€(¿•6í‘N4Ž&-ãL”Ëñð.żԂj‹ŽµváJú�¹åÛ=�^t.0ÜͯÎÐ9ºB®r|Ph.[ä@®isuÎOÌÆö]Ö‡³¾Ñ0(ªk¡¾É˜úwÖÁ®zC-¨Úý¿¶î ³/€ƒúž  nvÚj%9ÔóðݘS¬"—Ãe"ÛêR“QÆ£¬ ÄÝ™¬d"±šBºÿ&×õ…}á€îЯ ôê }:Cß.QuÈËÊËo@ø…e% �Iq¤D=Ó�t©)(s">/G§·:±BaB~cŠÓý€`ò`ÂhâúÁÚË�F°a»j2ÐæûMÀ½ÀvÓR ÕæÕf7|(‰.OÍežN(¹¦Õ\"tDél¾÷#¬"ÌçxxÔ&Àï�$×�CÓyqïOÓyôhm·„¯¾ ïÂoÚžT9>è”�Zòü†Åé÷A‡\c*éœo(ük«àí%†§;\s Üvt´—>!„ßëQÖ!l¦‰ ([c�ZÎI¨¹MË:‹¤˜ß·û“£|•äs§®…x ¹‰0 m1ÊÊÍ0¬—1à�õ[am5tÎ5–r}à÷dÈõzFAŽI”‚¨nKœÎùQ¥S¾áaÎÔ**�¯|æìøIÇÂÝÑàßÏ€ÿ¢”"¦ù¬üFÜ–ö‡–1Ÿ¡ÌGg!e(=©tƒñ2¥Š|ËD¹_µŒ!(}ðRC_¤l'T¢Ü ²H[ø‹Ã®}ä›ïï“bSò¶²ƒôÍW?cì¨þqv7€×k(œÍë[÷\ÿhB©FØnvBµ©?ì0MÛíв~”ŸwÖA¯K )–¯Þ`L�@5¹ô‘‰Ôê\ÅÃ�ð° “xo�MGr¸ø>°á)æÕÊð!(³Ìã#Ïp;Åü9Ù®g-çx”‡�Ã,Š8\%žIAÄ�x¸ e4°/·Èdþçøþ*J˜³�O%`‰ùjUb�¿|³{t0,™|ÔÚ‰A”`¾ }ÄøLÌÏ”*<ì Ì|ì@¨¦‘RBFÞ,Ó|;À!7À—ëRß³#¬ÿcD—*—Rb Â�€jxI¦±³E3S9‡æíˆÿ'wK€ëlwa^Ä~©J� %À_[tMŠPÎxàÂ|(¥¼¿·gl¹<~ÞY±àkN| ˜%ÓÂÕ(!üì’‰­?ÿ:Ð#†šÄjô1ÃctI/™4ÈÀ“‘AÍa…>Î�d Ë[0€Á¤¸FËyFŠy7Òn„© ùú§j¯e¼,SIåü8Ã4Ð2ݫlj„�ÿ¾²®,ÏÓN‰ÀšmF8J:94æM˜ÓH˜N(Á¸AЇû36»ƒ�pxZ;L¹¢Ä¢�³Qú¦i—O˜iÀ­]S=FH½‚k4ȳàí½5„Yš¬3ð †Iý¹Ãd=GG·Ô�Ç—)1cQ<~øOTÍ0>M8Æá‘GÆ=8cZÔÎÙ5�Kò°þ -ÆëáRºýì(#<ç­›£ý—}ñX2˜°1±x­³&ßùwAZKÌKS’5«šLR ™ƒ•ç�Š-�:ÍÜl2 !;RÓÃuÙܨ·ì]Ñþ˾ÍaF7ÿëDbõïj¸ḐõSC¼lóZÍk�tpº‹:^Š.Ù#ŸUê9Èî>væÙVŸ]Ê9MËyOƒÜûùÅ?D²q—NFÄÑÏ2iMn™Håô�§ ˜K®ý.}�\­¤³í�5ð8ÈÎ'TÄIÍgÁ�¥,ü=‰¿,OçØK3)æ_¿Œùý�„)rÏÕ]øI”c�+µœÉÍÿù 4ûˆ¥ÆаÂÿÖ9 –UîHДð�ø> t"—B 0E&Rg9ž¨A^§+ÕÔ³]ƒ¬Ò ·Å¨Lc'Ê/ÓœîMrxÒrþÉlDùMšvÏÄû˜´Œs5È|ìÂG­Y A¦Ú�ë~r鉇Á `€”f&­4ÈEä9 rUÒcL{ögµòŽkÅ&cÅ?îk!åøŒN5��vî rð/à¤ýh 0oéìèz ”D˜¶¯áá,;½OJøp;غsž 7*Ìkº¡8"ÕFå1)aZÜôÔ“¡Ô ¼I¯¥3LGíy(ý€Mxù—Y]&Zƹ&©Rá p¯¿ÛbI4s‹Öˆ¾ÑØ{$!UÄ{ £´øiŠŸíéÐÈè¶Wú¤†|Ç3‹'‰õj\ï™¶d¬µ J1ÇO#¬AxNåôRÜ™½ÒÑ`ìõ[â`ÿ¯WCN’NN5P«‘KX¹—ˆUMWêq’Ë+Äêß6$!cB_H€³cß_*Þ?¼�>èˆ[²|*\ºÁY�ŸÅ"ôÚKx9 )R™ßÿr ­¶‘Û6á&6ÖW=šä>âFš ÏÛ|¶�Ý,Lõ£‹g’OªÝðly$µÍbéƒä‚‘lìóÕÎÚÄø°Ùi™PDÖ|!”_ÅFØL“÷AÚ,-wïÕ¨·$qg4# i‚ÃÜ€XÂg6£œ›.ÛÍåe‰’jÞ¥ä÷¸$µµ›=«;#›§f§k„#ûG$Èr¹(!äT\Œ@9‘\z™þ£äb2ñp$MÆ1‹{7DYŠù ¥{o}pe¼á’ð¥l¥ˆãŽB9‘†IIê"å—àŸÿ…õºõ, ÇÞ•~Õ kÜ ¤(8çøg[Äë�]³�°i /õY­z=s鎗ËP~‚âÁÄù›”ðJ»õÑã ÃË¥À÷Pòððà¯RÌgmq¾>�ñmØu_Œê�,^•TªHÆ ÷íàúKƒ¨ÑýPHýÞÛ8Vƒ¨–¥–B.2Çô% �÷os.ˆ²Ç*#­uSÈXÎÉÈ"ô8�÷NBê�' äf1>Ìú'1QâŽDñ!,’€ƒH�xðUëý_ùcäØÛ�÷I6¹X¹Å™E8¬—åí2K'—óÂü|ŠŸv^r�EùÜ�p>àEMå œ…:—ÒLÊÆµ¡Œ)û/(ga¤§l&Ú{x˜"E™‡Þ;ïûË¢Jûàä<ðJT×ÒˆÌØ”wsuX³«Á †ô´˜ÿ+,zˆòÂyG!\@ïÅ.ƒ¹.YÀ3�˜bé»xxKƒ¦¿ÞÛý6‡<<¼Œr¶�¾|aÞÑ Ë6±´^Œ?–T•XP:Re�UXMÙ¸t}ÆÄª§8&3Š¡Üv‰;|¹üÜòÉÎ&¤8EgœïÕkø¸Rè…&.Lë\Ò2žÑ ´œ—µ"ê]ÿÕß­™mjeìic¸Tƒ‰‹û ¿;?JÀì V8º=ü+‡y~‡öŠH«•qúÐû»Ž[GSktBŒÕ2Ff1µ.H/Ö8C+£ËO:—îxxáLàp”f¾ÎcÄçÐaõÖ¨“UË™Z˜Ç¿�ÿæk™}‚æHRÖD˲d‹+B,§kP�ˆÒ¿"î«d›)–X¦^áP‡×vXVNƒ†Cy¨#¹V“ïA(úÄSnâŠ[Ÿ²ÆÅ×5D¢BšÛ^Ÿ„¼ ‘¤ÙA,‰:r¢cõìhÙ�ýuÜo= Ÿ‘Ëß"‡ÎãðÚ²3³tGòqš~ÓJ# °½MÁbõèH×\_BÚÜ6’4;ˆ¥†Äªm0ö¦Õ¯¬¡…XRÌ|üxå„l–`>wxmŸe%±¦°eÝ б “Ü�`Ý2ãl‹‡§â›“Ð.I$©/K$ÖAÍúUØ�§dHÏäÄ�I¬®Hó3sH<÷‘”8$àÞî2AµŒÙ¿Nsèÿ³ä×ÊãIê¹ÊrïÂJr¸§ùíˆ~t»|.Ÿ\>—O4È:„ã�¤8zŒåZ<Ö}í.±LKbÀW-q5xZ¾2€?CÊ�Á»ðpIV[…yÌ$õV²Í4qµ…i07µÞŠðw„ßááÈØl€·þ4ª“I€¤˜‰ÉH•\±ko¬cHó¼¼Ä¡â>°»EÚµ¨p‘Œ£Igs*9”ABàß×@±± ›y%©Ñ ã0ÖX÷õÇ™šøà™i‹î´ûÍá½9pòŸR/N;Së²ÉÕàPbõëãÚä`__²�™ÆN pÆ \\„p:UŒŒ�ÏZrX/NB9¥¸ˆ0Èå¨tå~�–8þ7œÖ:šÛ_b)ƒ›í®›�5é ^g·¦§Aúbĺ–ÐĽ25¹¢+E,„ÔoYO°>>pÔås9áüb›n•">Ð�‘ÌN�Teß!–‡�ÍÔXå0 æ€(±¶\è>Ò GK'{}JÓržÂplÎC(j�w™—"‡Er‡ïr›c¯ Í’NlÆ™¬Y„ÖJ¼E)yÜúuM˜úüqïïvÄõ9‰^ãÛò`l’o‡æ¹dÙ]Ú¥ß2 —ÑÑc6îæ)ˆÛ”*¬ôäÙÆñÇ µ,éè||±ë„¬ebvH¬ú6û°œJ¬^�,OÔRüV?–”²–0c�`éþ �/í�™Ñ ?OsÚCð1)kÄU†á2±ñS}.fw¼ƒtGÇÚ–KžŽûÄúp~–°VéÏ+ÄÍÔ^íPbuï`¹ñ_Øfr1"?Ïuh¾œ‚³‘§@ ©·wá8\&–0U³�®¡©¤V½ƒ_³&º¤C°ôótê5ȵÀÕÀDZgÚ—Xž¨~´zk ˆ•\ŸÊØ*up\÷¬˜�h‚LÂe"^ôà;‘§Î H#ÁÈæËþ›uÂöŸ c,5§Sa÷Øã*¶µÂUlux­›³BVu¤�–„Ë�½•HªoÇÛ62£}}XʆΚt‹ª�52�zG§ 2\Ë9IçÒ߆0o8¼Ö¬ðÌ›®�ŒÃeÏÄ»pU"±Žº�ÐþG,¢ÓËV‡u!"ÎQqV­Jƒü ø åu<|­åÖ¼éævût‹®[ðñhöø˜íà(K¸Ì!}çn·wp!VW0ŠCîv˜ ¡sA¤sÓÊ83Lö‹Õ¢Ü®AŽ‹ÓF΃¤ ¶5x˜Ø^Õàm‘a¸L²8÷{mÏŸkkUlòü‰µÛÁáÉváœl‘Z“XG.G¿'êH­*ðp¸]�'}ŒžfÜyÛ §Yè\ºëŒèX™®“q`;�Œp¢%\&É2ŽGJZèioU£ŒmÆÄRGú•7‰"žÐÖ¬�õAríô7-§aîB]èJHË™O˜›Íè‚Ö#T�~‹r e›–ñ�üÞ ÷Yœ¤e „�O˜ä3?Þ£p€¤1žö/b™•ê[@,3­�Yx{¹|žàÓRž‡„|¢ ÉKÄ5ûg.õ úÑÄÛˆÅÔ÷¢ŒG8Q˘,%öyÙ3î–r.@™eñ¯… ~M'k¤ˆ*p.Óâs¿Ï¶ÿ¿‚Ää:�„©‘bÖ´ôÚÛÝ� FmDÇÄŠæè«Ó2N¡žµÀBêY¢ÑÝ>¦�¥áù£êQ®�âÄUü´h¢,…ÿȇ0'Ó]Ƕ¤*c4Ê#$Ït„Ý&ÔdXúäø y›er�pãfRi%9äEB|‰ò�–·<]S{»|`¤†tŠœèäÖ€ð(Ñ‚KÃG7LÆX}7à¥ަ‰>NWç-—YÁw1r¾§B!áVˆ‘nHë§RJÌ`Æ´xi¡ø8÷°23>ÎÝ|슀ŸD®D¹^Ë[P(ªÝ§B1xþ \tu�‘2Àù$Æ]ÙæZ�Él$}–¾T¡ãæb¿�­s肟aŽ1÷)¾�Pa[2Wø¾߸8Òæ~ç�ņ´Ž]Æ™r�ÛÖªNŒŠ3 2—ðímÖÅMoi£èÚèåÕyôÖÇ%²u–!Ù&“²™€�e("L&BY¬å6eé”ÞÏÕÑÉaoÚ$x;"I¤†òŸ¸O Y?Ó ë\ŽMW‚¯½‰Õ7½¥EŒ‡~ÊT”�Ý(ó¨rVETç1Bƒ,$ÄülÐ �ë, R ¢Ã¬¨ÖH ³ÊÅó`»Î8€0/ØÄz}ãP$Ø^S|Â�ªG§²¶—‰RÂs(·kVÆïòÑrN¾ÀÃ{”óÇl¶ ëÛÔI±l#jÉC8€¯dGgtÊxñDöÎy€Rò©¦'iö¢ù¤“­OÅÝß}HŠ6B7ÂܔƴyáÆ4çÙN81AoªxöØbä^›<èQJ¸ ¸+É×çÄ£sÀ>IH6X…uq.„´ˆ©ægµÕ t„a|'†T±×r^ŠÎÞÜ—æ—QÅÜë®â¨zÅÙ±ÎO|ܬMó@Þf»1$‰#”P4ÌæÈ¡{0æaÞŒ9×KÙ<îèRSa" >²æ–9ºç,Lòyê y7£I× ?ÇÃqþ¯ƒöo†G�™Ìœ’´@�2SJx0Ƀš,ž=âÕ¿åëƒRÂã„™€p.Û¸8›­Âµ¨aåu+„­ŠËþg™¥ý1ÀãjuŸ‘ÃH(òqÊK5b“.Ô ž Ä/Ì*_[^"—9 IG¼ÔF¼géÐh�n•RéÆàgšY*Ï,G˜#�;–tŸÙÒ&¦Rë!ý÷pÈJy=ûÝ 1ûûwuF¬ ;ŒTG|Æ3��æî“'h.#"¬$ÄåŽÚë†óÓ¸•ÏéÊNHk½-³Ûd~v�ùr ?F Ø;i™Úw* Gu‰”¦á$õã¾N,SDðƒÎÛÕ7Á¶è0õJrØ©qï 2©Ô1I¨ÑçE¹¡E÷x»%ÀÕäÒËÌjs(»é-îÌ´^³S—B>x¸zxoøî Xè ÛUώЧK¤£—'9,~mp'~IA$aý±yʸ‡Q-­‘ÑÆ�K!EÛ§Q‹”š³ÿ+Äcxù% 7Ÿ ?{0}“ Æ�G"ÀsI»ÝœÆº`„Í\稜‡Ol''IL©3ð0œS3á“ÖÈ©e–_9¨#—&D 8p)¤0Znp’ú±uÞÓ~Ìžz…•xiàN”«›—ë·Ãçk ºÖ(Ó;:ª]l!ÌRÊû& >ÁXÿ«ÆÇh3krÛ^o9/£üئGo’bfFŽ›E|Š5Ö©ž0ÇJ)ŸÄHÉÃ’è`Mì¦À®Ðg«ßS�w�ã0™ŽÙ“ bYSaU&’b~…2å!`Uß.0a4œsd„TÛþŒ2JJÍ2´� "º¨Ü‰¦ÌÝ-Du%¿&Îî:—ĺ\< ‘»’Ú©ëÛfS©å²�GÍñay1ÿïÛÄŠ¬„¯¥„é`0>"k.|J.½¥˜K,Eµý¬ˆyÒ«PþÝ‚'õZ ²Rƒ,6cŽ42ªÁÆ¡’î÷M2WXãã‹YŽýzå<§¾. 2Uƒ¬Ô2¾Ô²Ô‹Ä —c, 7/UÕ¢)êfïKSa+èh§š:ÖÚ Iu*Ö ïµønWßÐf:¼ åŒõÀUÀ X‰móûÍxD\j9¶‚A„ b„‡� œï$wªd�^a?IDATÎåP<|#,“Ét¦•äÓÀÉ4ò‰]ï}Í�ÕRnâ¿“îKe`X¦zçÈr›€ãUíö°Ûy¥•äSÏ‹kŠŠòG)I¢œ½÷¡åÁÌ-%�MGrXCs"^åd)áÇí�Eò“ #äñŠ])½lƒ�•ÉSh�)˜qÃŽø©�léIØ‘œú¼FèËKûR_¹SáÞ ¤á ½Ø·ŸÏ[¡ñÉ;ðÊx³ÀOü§_׿ûâå×_oô}šnwûk­¸®¨Msó*6$|Ö´œõ=¿®°›û66±ƒå,sãÇ=o1Kø»m¥³Ï‰×•;_÷Ï5³ÿ¼KÄg.&$và®!•PÃýÄø„À:6ögpå1å8Ù�PJÜáúØ›„'<±E?›ŸyÂym,ñ÷e …�(©â*�lVÎûyrÆFI%_¥”ZžÒJ/£¦šk©µ>UŒOzòSžútðÖƒŸ¼bŒgšy–Yç3Ûìs,ÌgåUV]Ïj«¯±ãN÷ßu?×n»ïñ†Szó[Þú>o{û;>líK_þÊW¿çk_ÿÆ_»ögWÿy׿ìÜÿzן]sÇòyÝó÷]ãËÏó··ÂIqÏØ±˜;þ¸ttÏîrŽîœ{v÷ˆS”È®…âæìàŽ±ƒù ±|᯽ûûÎý/÷í*ùÿhßâÿlç.·îÿÅÎ]nÝŸ�ûÏûöovm�QÒÙ ½Ð5½Ó°ñ‚·�؆1é¿üçõûÿ?¿[Ž=­Ôô…ôN`üý6¨î’Ó"¼÷ìñzÞ’ßIà~±ÑŒ 7þrׯWÞ€Ï1‹Ö…Ù±ÛcíÓœZeœûã3JúÚ“.‚Æ\;�gú+f^²÷óæþ¦Õc;ØŸÞ‘vJ«½“÷k�{hem-;_kÖ/ÎŒýä�h×ãý¦=Ûxóº1ðü„ù|XvÞO®u·NPúuw‚ ß^“hõ\aœÏÉqŒ�©âY®ÍDÉ–fü}µ|3óni}˜ëÚ_[ã}WM‰µJ}}“¿^%|-–±ù™:Gê3xâf=D†×ÝÞà{§^"küáëk?+ÁÂvË1 úÅ\@ùŽÍ„¿ñræ~%Ä“ÞÆ;Óbý#è¼b>ˆ#µ?;¬<áï7:Ö² pÇ�¡$�ÅÝÒº:WØ€ñ N•¬½�2DX˜‹ ÅÁ=î5;æŠ'<›Œ¡xsñí€G¿2¯Ã_¿@ÌùâÎ_ª-¿ü<~N8䊋û=aX@šš¸§�Ûåî¹bÌ„Àx_ßÛûZ Âý�rK´ÚO /öû¬‰­|�UÞß»>v7ÍÅB’( ¾OëIë‰Ï%ííƒEÛ2~Í¡cÖkíøå9ß/%¶�å »·oî¹ÿ`ÇúX–7ã5«æ+L” Ò챎ÆËØEœ­7èÏò¾8_xk÷¶âû¦Ò¿pïN {=»�«â[˜Ü^oMDѼĊò„Í?1�ýðõuð§X DÙ«§7²ZlêÔnÞâöXa~¶868º±ÒïÆ_#ì<­lÇ=V«¼<„€ò�<˜¨ü`Q¹]ïþžægr¿+§{‹—H ¦ ìáÄÜ/¤h{Ø-�ö{Þw‡/�¯í™Ùƒk³…Hâõ°&XDiƒ0,ˆ Ä%°í~ß{ï8!\×lDX)ˆ½Û%—BdWPÿ¨1âÈøþ«Þ�äcj 8\ël8¹&6¤—Ž,joƒý±¬Š¼ä^ºCÂdF7ÂÅö=©¾|ÒR£®Þðºo#Õr„‡á‘³ášo%B´z�WXÂ.p­1ÙÌ}³J•ĕƮ(b…TDäºØøß¿^+îþ”j˜Ãû[2wM¼Ñ�±—£Ü'Fû¬W­ü´7M œoýÞä›è†Oxa›%{á‹5Þ‹È÷À½°¹‰Î2 „�R|’ûYfü´¯û[üŒÞ¹Õ;ïÖʾªö�ù°®Hïà.ña5LæG#›]î)¿3=˜¼’ÅW)xC.ñˆš·�H<¯”0ß—-}ž•£p—‚EÌ:#ˆ·`3,s4,ßÕCî`™Hˆ¸ =Þy°æó7.¨=ß—¡àïÆ{+y…‰ù ® |• ¶µÝ=ˆóáÂ:±Û×&@®4Ñïxê@§!‹åÛhýSØp¸(ÿ€Ý…¨ñ>„ÂÚîÒ¹5}ˆˆŒ¡Dô;a–€Ìž½ÜÊ÷²Lr¢�Å/ì$HÕ7ÆÌr=ß’’´Iäkû"Ž·£ ÓŽÿû+˜ Ã?>sXŸ+¿¹ÿ…£Üð¿Œ)dÈÀwÏwb=×- $èÄ#Ä�·<hÑÊñV-ˆ?4�ÜŠµÏDæºtAÏ[’Ø븯ª©4öä#pÔ™<±Ö¡| ÓYN?ûLüy°’ìœhÁêC‹‹£FíèA_ !:þ8\nNB`ø‚+;Ïì^~0Ÿ9PMw!^~é&<-ªñÛL×¾(!:${ñ�[ ²´½÷·VU×"fÍnúŠåŠ7û…ˆ{YÖ�Ñ,‚îuC 'Ô�à„5ú'–úJÇBøòàÜ·aÊð� Åz5¼ŠM½O´…ä^¤ÿžn$âN|ó„XÃĹhnkc“+cë�ÏJý@GÜö+ %�e” 'skó‹xqç0‹ÀïllEìAm3Þ(Ÿu ;ì ß—$…k®ðÇ>wˆ‡÷F‰æ²rCÆb=ýÎm½rËJSK±Ø¢î«6>•P·pHéùâ2 DîÉ¡¹-h ‘ŽSpx÷ÃP®@(®¬<ÄÓ ÷ý›±^ìQHªˆêýªH *°Óg€µ£ °€böŠ·K|>ºñ[1„‘‡kúÊ5Ž¿ƒ]P,Ö æ¾á�÷*{Áë*&ÍÖI‘%Л½_fhÆšÀî¹föuD° Zbq�K LæX}w®-ñ]Ö7< X5þy]aÀæ- ¶DÃjoÇ�8à6^d¾vC"jœî .ö—]{Ðã`:«ƒÕ¿`Ìcp~ÿ"2 »ÈF¹ýƒþb0Q"@s|¨À¨`%°�ã&ø2UºxYÈ0OïïµPŠit߃“Þ®O×þ”Ž…Ð´%¸ïh“}›\(î2øbÜšv ð®¯rCO2 -3Û�¸¨»‘º�•±Þj¥GØËl ‘²0Α®z¿®ÐK…¬ù¥¯¿UþƒRz;´oKKßãÿpq¨íHP°¬U!‹¾Ï<±°²“ ¢?Ð"×ExŒh³Ÿ�Á"Ð`sb˜˜ðÔNçº@Rß+²IèGØö«‚š_ÓµœG<†ðÃ?ž0¡ÐÛh?Ä ÇvóÍú^\ùûꑵÅ}@ä��®‰ ¾Œöán{m˜ÕJØ÷Öp~„Ò'|V…¿Æ-AïªôÚˆ#v÷Ÿ.2¨ÍkÓ“oÉi+D«Îj@Z‡¥ætËPal½'ös?,NɯÕB�à)_¨ñ>]µ�š\Èä/�XÏ{ILö ê��äU‰�‚8J‡¾^�ÏÜ�tk4•†Sð$^쪀"W%`K¦©å�š;ÜŠ÷i N¤¼ pu&�Œõáþ8<¯oX@±'ŸC ˜}ÂßQ¡‰±ßÄvùQ¬¨yx3À;‚ wxn‘£å1Ñ6ÀkÆEÞFXÆ–Æ ëöÆN®lê�øi€Í~|„ûñ®E Á{À~ì¯Ù×Qƒï ÑåNB'½&"0%®$›SaS‰ÃQ«HàýãÿAvO�†AæZËÕy'6æÆ�AˆsS5mC:t˜Ñ|† J‚.€Ycu$pQW‰—Éüín˜°½±M– šû.]ÿÅÃÁ£Õ¡ÞVWùÑÁj% L1õ;%øÊõád�MP/à=†k€Œ(È/ŒŸbk!¤!@ÈŠÔòyÏx[Ï+°–¿ÚÌpXHŸÐœ„v �‰ø¹Â]‰#²�ñ%Ö:o+(4X—©\/’²çøò3iµ²0 ¸·H0èÜ!ÜBÏ«&¢õžè ý«ÐFЧ˜SáÖàˆš²_ö"ìpòðh¤«ƒcAZ0@Ÿ“‰™ÜšÉö ²\A!�Ø\-KΕ!³½þ. ĘdsK5`Æ:ÂDŽû†ý©…&˜ ´ž‰½fLøaøQÁ€”‹›ñ$ma¤Ü.ª¥„»W³ûkDTw**�ebþö XehÚ†þâޞإŽðaØ¿ cDëÍt/–͇£¨•…7Jôíð庉‰h7|æ¾:oˇáàÏ zCÁØœS�CŒG5rC<ä{ÕPHŒ7=æ{iªƒµ”^A|qC•èDC±5àÀÄâ‰'¨8õ÷ü8Òÿi�Jö� ‰.ºF†°È±ïcdCÈ�@¾Í0­E�_“˜«þlˆ€bzPÀ—Œ¾á»€�Æ—€"Â)ñõ+ù®ƒ¸×_€ò~ü.âø$×€ì ¾ØR=P•ÅN¦«IB¹cYS8À¹®~ëB`î`…oË N´Î]óu³m½ _»Á<Þ½vucẠKÐo¬»¯u—Šw¹Ái¨ W¯¤x—{`kWBϳ�áAÚm…ð \aJè´e-BúÆNà‚§‰fë 8LÄØA@2Qpm¼ÃTëc{WDè¿„|>¿�î¡+f‘žC²Í]ã?� ½"t‚Ÿ+\ËD[ƒ?³ â}&N]lú¸rXh¨ c„#(ºrê�¼3G>°..:ÿœüçD7â”ð5´O„l©!û®)G‚H�ôÀ‹½Ws>P|ÐWâ"¼ü 4€ÉÃù)\¢¾D%~dnF��PCNÀz@Óˆ^[ŸßêŸÓÓáo|8Abçv‰µ‹FPâm„ÿ+Mâ„Ńh&ÃIù®ì‹‰-Þ‹°4(ÍO�¹‹Z)äÚU£÷[2‹È¬ÂçÙ\mZñÅÂÿ2À`ïy¯Ç DêÝ`Ô"’óÆ›ñS£zþÀ%C>œˆmÏ@N?¯�šœÜAƒ—?õRŸ0—øÙ)ÏÞfº˜Á�5¢ò—ÕëCa˜xW/ðAø%05OÒ_gû‘�_›Í,=bñ�í°„ÝÌ>ô}â{ó}T Œ÷}>õ*&÷~E K˜7�-æÞ€:À–À²Ñƒ¡ÈPÞ%öqÄŠu’ÔäO…d¨7ê ›@o¶–¯¯,Ì>z¶ö¢âʇw„@hí@É,¢~o`ÆLO~”ÿ ŽX^~Ã.ð¹=ò¼å<0ñ%lÖ� d>í=iµçT8|˜’Onz$d£Îqe’àÂËSˆˆG$òH§œ ÐÀÀ�ïnï`yc.Sÿ/åôýîÏL¸Ô†‡ãíg#° ã¨€r2¸¡°X˜4Š�Mç´^ u’¾ Ûí \²E Æ©QϘG0VÁÉÜ_ç¿Èû<Ü­&ˆ¦ o6ý!ý¹{[Ëü«8Iµvˆ*8|ÊRƒÐkŽÏ93 Ê"øAÒd>$*@CxC¼àû„‰“…�†"m]/±;‚/œì3±¾—‰ç:*Z^ ÑC»?jWãºÍ§C@¾= }/|·}'c‡„û°yeØ8í½Áô äcë>›Â^ü0ñR"Þžg¦�È'˜ʺÀ�NÁap~`ª[”l�ÈÀ� BŽ�Qù}y|ü•ÛxHÅM šÕãO…MÙº=„>�­yÂ5ž.·g§`‰0¿@˜­xÍÅG„üê{˜¸Æ€©hé’œnzÑ=a~;·hâ!0kTp^Ik¼2îs¡á:S!ûx®—p�ºßÛSÖ�³‹µúP‹ÄŠNx¬‘�M@"á�¸ÙR£¿/’Æãt‚õø2+ÅѦ½x0 /}[Ä�CfœCvÙ[GøqÕ3þÄ…áª&ÚÇmVÃÇt±ELš ˆÐk/öQ-]á=M9óÃÊötö‹™±q\¤å=bç™ËC+ø$ÐSа÷‘y(›…™6¤,Ö¾w_yñ/j=¸äa X5dÖl6ï²~ÇSªùîã¨kØ;À^a<éÛÀ˺0͇8ç1=Êéy6Fe©+�-�ÁåXm¼6º!Êé1{0 Ùf8>¾E�L?ßøZ8eq{<ø@9„a  �/–Qv†sÜæÍ@pLþ Šõ.µ­DkÚêj>xwe‰2ü ·hŽU"x"ûV5¨0xÎu¬7\Óe†ì³˜ÌwäÙ¯�0× Ûž$ôc“Á Њ˴%lDh@ä�«#'„/ ó±º�€¥ntÞ`k°ç³äÊîL2­rN° shAénW6—7”tiïE\Á¹�’,À“~BJ3Ñè)xÔýŽH|4»‚ûl4—y�دxPfìË]QpPh".·ñðnV6Åe½á{rãÃ<äËqÞX?‚Ä‚�@éÚb[u„`Ú‚{ÀžLÐ\OuÜÉ@Ý«œÿ³�[Àý’Àrxºn ]× ?Þ'¾„Èák|A•ÂJTË�J� ŠrVjÄ:ê “¾ æò-¶DþYx…071~g!0ÄAS¹¸Æ•›)ž/HÞ [Çl.«W“ÚÜ(›h636ÙÅ«±2Ü�­h!‚‹ -qvõÝž÷í Íã{&ºßxís  ã´g+˜Î) 9Ö…â7€ÁT/¿%˜üƒ„Ä1w€âŠ&UÐ�Ý:Sð÷¶" JÑcÉЄ€Xþ` »Úê–û;<òV¾#‘/0b9…Ç$"ßCzL©ymùáî¬ßýÒçO¼÷IY ‰¶&@ú�müø¾âþ-ª¨lÂövEEfwK±¥@”Xy\„U˜Ž5wºÂg@ÕЋÅ0°ßDTZÐnAÙš`ÂAŠ€åæuÑ‹EÖòñäòúðΕŸ‡÷³&øƒëOãDVPAŒªg, �&�ƒ}C[•Ï¥#ü Ö×9'C2@¡=‚CÆÌSÖ3úç;爙â¡x´äU ˆ"Ù4ùº<ì2U1ÍKCOð=Þõ$I£%tk¡ñ ž‹;Z.˜Ÿ�FãÙqOC¾À†¼�‰ðš€ˆ}òYåÈHk¹ÊòNˆÍó©Ïœû.¼ù‘åó.¦ªÞu!²À@§¿3ßbg>bïSûõqP‘GLCA Ú!Ÿw¼£r_ࢆà°ÝÎGùþ€Ú°gBÄH0 > Q…*vìù†º*ùsÅ;ú¶{ÙVÍî˜ó�[bÞ–ð&þðÿ¢În)÷@_p‘×Âj6_š÷ÃXðÊE`DUzzöyÌX-Ô&°E`q®EoStÉÞ½‹=¢ÈV2¾¡•ÇâΫxÛÜ.Ó"­2`Y!é ‹ØÝ¬9Këæ*‰(fç» ˆâ“nüMȨ߆-zUÀõ�…ÔÆP7Êß·™d(;†›bçžH4 ëV´"lx£ÏÌ5,€8‡Ë}øf‡ÜãWt¶çÇ·Üo¾·™íÞ¬¶…@P�z[q�õ„W :�.ëÑheíQ&2aèêµ#òõ#¶QÆ÷�l-iЈ½\JUÕ’ÕlÀn´*gq;74±y@Ï]Kn‘úË¢eþý4EmkC<²ÄtÃ5ˆ ã>œ�ë!ˆXÍd�ízP\Õ\ܨA ÞQ³ÜüïiSö=Øþ®Aìý§>rws/qx”6áŸñÃO¾È·±§¨¿“5áB/׊iÁàsù2³½±Õ9œ|c/û§qÇôÌokÍ£‡ïÏ� t¿›­–Å‚Ýr!n�À'ýT9A ª7<=f°Ú-°!]KØ�7U8L{x!�T ǽÃFn9Ös·9OUa (æV“i=yôk%Ø�N* ºFž¤cAìü¾ÑsR3†o“NÏ(@Y>ô뎸¸ú×\Ü"ê³ý„n3Ãj�tjLÇsq׳qåÍ,õmØ �iC2¬†>�;�¸V˜,Á;ÁxOn Ö†Ýn8¤Dàï`›QUeb¹™nl±T‹�«Å¤>@ìˆ"8òß JOi¹> y^ÖÓ,0ìTÍRû’Ñ#‚UpÑ®÷qD;î+t·S!9€oVwX(�v¼Öâ Ó8·P-7yÙk'”ðqÇf�~DEž(‡P-ÏͺÂK­¿$f[ÅŠé¡gÀîh'óìÙ«VlÛ @€I¨/Á<„*6Öz?ƒÀM22[1ŠFkÃÁ7Wq›Ó�¦ZžaÞ°{Ön÷ —Ž=eøž©mdÏLuØ®ù挪µÈ‚�GD׳µò3"˜&|€O·10¥h±à¶@§ði|FI¤ÝÈ¥´ŠUC«ì Xe�Ë#µÊ¶[d�û;|–!#vÝSoÉˬ kE £vAC:àm²_Ž�šh¨;pÑg# xŠ›D®�éÞêÂ6` ÖV'³Ë�]›s,m»1-n8J'+[ß_«~Ñ·h€–/Œ Ba�˜3ö�y$1ù�´‘_®ËWlÖÍ-›ÀX) p~ä—²ÜS‘èYš\rîi$±«ªö-v—¢�¡†ÀD·øÇÎ 9"‚¯ý¢Y#bD}­pÉŸ«;’öÙ–i{Ä+ç´Û2ý÷Ù�aQS:ù¸SELt6ÝtÏÍûÐMáà(Ë’^ �p»-¹Ä9ve=62P˯UpÀH÷ Š ¨£Ý px³˜Õ²9X«‚¼1]ÎZ¿ ¨(Ýì§ÕÉ3\´ø9qØØÑ¸-c±Èb[#—\%Aþ;èæÚ¿".G�ÈâsdŽ’ê¦ð[ß½Çz!)›ÆJèŒp@€?D j"”{ó�¬>Ä9µx ±<ÓnÖBß‚(êÓˆßD÷Ã. Ë�È8�•ÍCü¥î}QûÈzh^‚¦�ýö˜¬’ õcé`¨'“9´ËB`Ë2!s`yƒ±jϲ»¥„"üšöÜ­!­öã�ªÏ~ßf5ÌA¬Ìf›(öœÂ’¬sÆ*ƒ# «ƒä"YMÞ>¯ÛÏà ἑ ]ˆ¶ A“¬AèÖl«øUù/‹á=[1du—uÙß<ç}%­ìa±û½Œß±­©¦Þ×ŸÛæÈbeÜ)Y ëÔ3{B:Öì> ŒÃ39»Ñ~U¥PÃeô|¶¹)›d±áÕžŽÞaá’ÀÔ’Õýø²üEøK† ô0ëæAâüÓwjˆ¬ùT] ¿`jóCµþŠàû�GúÍy°*AªÑN *½ÙKë/Ôâ,“1Ú¿0ê{—ž�¬DÄÿ~ k¸ô¸Ík|¥~-Jk~ÅI`Ñ÷Y5ðKd½ÒÈ w}ë1S:ÜïÌ6[¢È`w¢ bð"ß|}ç<••ÂeÝ2ˆ6ÖˆÐp þ.š�4Ä�ä@‘—÷z‰•°\\<Â`íê^Gê`‰[Ȱ¤5‰£Ý>4˜›TUžÆ_- 5s�·ÝkJ Œ÷O¸»ëcGžP‹³Þu$k¡Máìð=¾/X) Ž•q/¡8VO¶AÿÞ72ËP‡7A;Ñ[íWå‡)C$nÓ#|ø�U•MæÆ¼ {+c?Uw¡^¡Ã­‘ Yá`_ nï™`=ug°S“öTóæ¶Q{ÔÒ¼r[ÊûIˆê#]E0På² 6Àþ·=cr^8(WÎm8:Áó$‹=+A�pa7bÅ`}l®ŸT•Sÿåy‡ {ªCàÚPuÉ4 X‘iÖÙ)`BeÇvÞ bÅxæÛ7�–=¨pÄÖsJH¿_ʎûãqc=PÁ©�±Öøªg°Í ‡t_z'<ØÈv@²a„€À5˜%߇�åžáç®æxïw6¦øXú�{ kØïfŸÕš„Q”�te+VlŽeߪ-ï ’]m¯ß„ûcëòkͦº«-W”Ë º«M\:E÷˜Ë¶† “vå�ìmì\<§<*7›°?˜Ù]x/ˆ&lØÂŸ RLÁÙ-nj6VÙ¡‘°âÃxX¬~Úy†s",L¦ˆ.‹Ë<9„UB‘–UóL y>pÜ�³N­Fߎ#¯�Xψ0„ik0ûQ€­[½S±ÙÚb·õwÈŒá×Ö=:TÅüMC‡s˜ 4F$„ºìÔ`˜'K„ë6±Þ| ÃÄÑmõbmLJ°µÏˆ¨ÅZ``šPÁYáúÙ"ÿW¸‡ÍL*ÛLÄ£�z•€œ¿O8úmHžáC![û@ÈåÈ8òƒ^ög�Év,O­ rnð‘raSð%B™•*lïN`}“�ü°¶K톽öóA¬r…§Ù4�Å9´t8ŽÒq^�4ÂçÓ¿ ' c|ûn‹oн¥ŽN,žÌÞD{û Ÿ†�*€Ùæñ»!ᄙ☇kô€¨‡¿M‹å°vÔÍH&0Q*>WhŽöá5’ü”\ß^*E¹¯×¢�Ï®À–ÊÛeÔ)ì*x¼1T´Óc%nÀ·ÒgµÓî„9�¢vm›?>˜óÀÜÐ϶£[9ÖÌàœ&àWAbõ¾‡»;�çx¥E`‘�yDB(¤˜4H.bÙíQ«=V¯%ò7•= ðiX4 LHòè…oDK?­ä<6;÷ó�[ƒôUc.‘ImòZ'¢®†]"aO�aL¹`mŽEߘž-Ú—Žý�¨}"hâLìæ¶ó0í•UiD„0o6 ²üMX¾Û)vH, ZîÚÈ2q+¿/X“|s8Îm€<“@0ì…`ÇÐ�‡ @,‹ÉiϤÞtáXÛ¶’×’1ö¤ÈJA²lWç7?ψš]¸žهΫ 3¿ ³f{C„°?¯gÛèúø™7 Ûàá¶œn›[M&,ˆU¸‘vèV9Î`K¬µˆ–;ÿ dt"¯~S”¬Ä°{½Nk¡á ýk¹™ Dœö9Ø:›Gl›”s—zÛ¥uÃØ`´ëä–õv07–L »Â¡ãˆÈq[Öãˆ=dŸ}�w8-¹¬00…XF¯¥ =ÎóЄ±íÃaõÆ– ? ƒÇý —Ûº�v’ËŸ?ƒ­m÷­V[Д<Ü‹´Fo'%?ì wª…å[\xùžÆºòXê>µm¾ C–äá¨9Ëò-ßÀà¦ç,Jæz¾ìËjðfS ìÂÑÄK6të{í‡0+ƒoçe Oi‰ž Êœh–´Ÿàˆ–w9%)˜�·üI7¿¡Ë¢ˆ$µZœŽ1¿ßë1Ö¼³E›lŸÝ�¬œg.¸0ø‹ÝtÏ�­s'¼`2Xo”�¤nVÀÝ.ýºYm65 à˜z¸qxh§³,~EÝ9b�·Íb•^ok§,ƒ„£KlSÃ:»yùSÁz@¸Úe;s•D­~¨æç)tê£:­ô•Ñï*KÅ2±ô˜7[¥cOÈe¡HPLˆ³H&»$$æ¹¾a½ÓNy£ £U~Øwƒ^€Fõ{ÕÖ bßçovÅ:Å9J Ø€ï=óÔâÔÎÍ[,§2`€Á²TÀ¾­á{ ¦@ä,úާüº öÉêr9V»”È®v�>qsk=Ø$RM¨t{£=8¦,ƒ57!Áê ÞEÈõ¬Õ?î‹•B�ĺOÑÿË%Vôeí°|"[ŒQ± x(¸êOÈݦe'ˆÀ[]�èpÜe\s²…#/Þé¼ =•2l�ÌlA¹Á%,_Êjht·=üÙj{£(Lı=›hÃÒ›úܲ •#m',ðŠV˜‘Ã8Ñ3œ¦6ôò ÉFªß gÆE`IŸ“KÒéËF?Öd˜óô�0Nþn{uä‡J¶í¦t.Ýç$Š®uzÀí ã? 0xv0OÆÍëM[ Ö«Zd›ï¥’‹¦‘œmƒ„«Ï‡í"–‡üFBýÉB¶¶M„,‡T ÚÁgçXGULç{ûQ¸Ä5;¼oÓfDõë)°2$x·! „\ÒÜôš<ˆJ"¶Y¡èÑ`nV.áÕ6`è›åÜs{¯àyÕ¶¿jlT¸¸Û™oÃ%�¯¦f#€\àÌð0Ë©/ËÜ‹…#¶¹Z>rõî±ìBÃYDoIk3°Ú f*Ì9Gµê7ûÏ Âݪæf> 8ñÖ[ï/1ŽxgÐH>U讂Ãö¢buÇ|2ö�=`Ί€žrÙæd/Ç 9)Á¤©õ�(U€nO5„kÿEÿÅb™5œúEClÞÞÙç` ÃvJýàú@æø P'ã£�Cb>¢ÌH|e>· œr¯·:l¡‡˜ì0(Ù…‡ÿ^Îïªð¾GìIŽ*ø$nÏIÄÚÁpÃzÓ)� w6óųØ¿xˆ{Ä5YBƒ¼'I\ÊVÒ•v¼x&D°a×(dHýÕÛ“³&Ÿd‡sk< @Úv3gŽMÚŃÁ]Õ·#Г+NòYö3þéÊ>"žtÔûEe7vÀƒ¤�;F†>Ð׬Gîõ.Å„S„Mˆ÷€Ý>2b}·Æ®¼Ó À–ß�Q#ètlš†5ƒa…yuJÞ"XN Wá@Äèøh´Ì kƒs|ž³Ýˆ»Ú¡$[c³ÑÔXVó¼;{>²È˜e‚bNÏÀ- ³ì–è Ý•Çä÷BlDdˆnß"yõqëŽ-Z0i“g…—”ÐOÛÂŒ$‚HÑVqg’$�,¯æq]|óéΈ¬ÝqãALµ œØ 4¸X.7œµx±ó“NUR (ÙËiˆ^㵇sÁ½…Žm¸,1ÐlíôN' Ž£mÒ�ÚMÝ7‹nÛyv&¹ "§8ÀÙvsyddwîÉàÄt†” ˜os1áýñݸw³߯³c½DnPÊgƒYõTV‡œ¨6 $ ½­p Ó,¨m3¦ÜÁÉΚBPŸýZ{u�:’c´ø–¿÷fg•{üðâ3ïÇ40qÚÕK6ÚÐQ,dsœÆwú0.ó3gH ü�/ÛX=»%ùÞ`D�ÊÖ¬þ97Ïñ?�[C,\ B…W 6ð3 ä×ÎÄòÀOx›Œ}¯p‡dë]ü�»Ú–›ùHSÞo¸Ø:Vu™] nVQ®Œ tàÙ¢Ã|"Þ„ �ÀžYRV‰�«3âç‡ æN{¢¾<*$Ä“ˆá"¾`Ï “ÈIœá—C0°ë9ÝÕ°ór½|(ÈQJ‘ÒíyŒÜÃçdñsr�¶�H¯skL»òV€¢å­â�„¤¤R²5ùkºÀ›í,³µõy¨:‡èÊ�kÙþmT&wîP ¬¼MP]” Ÿ¤«·£�Š\?¨q0m«§éIQƒeææ¹ÿ,V-iƒ§ZEí>­:�f§oD1×°­­í½¯×[Pq„-0;NϘ¡cà\…Ô¼öˆ +6ËkyáÿÙÂç%`EZ‹�‰é¯óbŸÃ@œÊ€$ýpªæä¿w²)€m:G`özX ³ƒ“%ÃÌÐ@k-ºò>”·þÜΔÅ)¯% ·‹L¤‹[ÅÖ°Ó@EðJ§�Ê¡%8àÂÉIÚØaìI67s=§}ÑA çH‹X`áÁP.´j­6Ži$“㌓uÐ_Z¯!Çv{îÏ“¯ Ô/S+þX‰¹o3¬�ä´¡V„3 (Nu+®‘¬zÊܧNg~ç¤xƒÙ õH0E ªñõ9Ìç¿NbPýy,?n‡�Ùß&û†f�i½Ô²ZòÜöå|‚}„VðÆÍg;Øèùj+ÎECðsïŽsU‡·?ÆÖÇ�lžÃA÷º Fˆ-YqˆÈ‹å‹…ZP¶ç4»oGž¹óT�n˜ªÇD£3óÀ|äbaªÔ1Ô\Õ€IØ�贀⨶ݜ ˆ–s ë?–öq•Öoa´l[p:,ZÇQ¶™ïUmyD£#�±Üä`„Š’—«×“ƒ@AL6±))b¦3‰9NеDÀ37ÚøÒÌÆ8WÀZßséˆÁnM*ÐQãgJµ~v\Z3ù 0b_È:c�CV}Ûo€·|ÎaT:®àvjPïå0ŒngÜ”õf>è¸N7ÿÉ*›){‡~ÓÇ;éåÆ>Úü™¼¡D§nX/­<‘‘Q¬‘`gÒw‚¨~vh75yÕœ lšÉ6��ȼ/š…v;dÅ6 ¢&®‘<"]Y åíìÄ2`PlqÞÝ¡˜¸%DÇ ¢Ó¹Â{Ú+˜ÊÄVæÕØ‹ [œH ˜�Ǧ•õù·ÉIp­ �g:(Âų»é˜Ù!�-qEGÙð+MAÊØÈÅ`Ð�¯;õNåÞ6n�MÎfu½çm·åsâ>Ñ–ÿÆiNVÂj^Þ{ØVùO»  ûš‰G3\gN>æàØ+³G–¶.Xò´,e–ŽªÁYñOT°0)øM!—©Ò)z§o”„ÇØ¦K1ßœ¡ nÁ ™;Mž¿Øsî,3ÌÍ£g'‹°'»ÏHü1ø6`êìwUu<êŒå¸iO�Úpa=jÉB�pƒíƒà·óÀÏ‚³ƒ¶^BwúgFê²~ç_F�ZYr¯ýÍn+-R´* ®7êÙ°y[MŠ×¾úÙOVpE{]›É{¶¼¢:‹@ÆÖߊGï[3ÅwYeþÚƒHœûeGÏÇé‰!ŒÌª«õ–e�]ÔN[²&ÂÜòIÿ`+–—oq´÷ôÀœž|«Z‘/™�Vx0C0wFăÖY�O ¥(Ü iäl!+Áoûq m„¤qø×�=…&ž®Œ;»{}â™oËŠŸzyÞkÓmߕ겈`%ŠÆÞïÓ³Ö†ª-YO²=[zl›²sö“‚~ØÇûg¼#ûî.hÍÑËÅQvÖ×:¸xÀ2^6Æl0utP$[sgB¨~Ö2X‚¥µiÙŠY+ù¾Õaå–ólÎ>v§|Á‚qò1p/b9LÈÎÞµa;€'Gx"ühbbÛSJÈÖ° ×Òðà¸ÛÞ2‹7fµöBA€8ÅDg€W3>‚�û…+©V«uÆÅ 6³r p´éD!xž�¢ÝVØêˆ@ÓfV¶Ÿ6‹ÒU®bâìTpµ3ìJy”1�Ó}RŠù¯ã?�À)Pçiζ{`‚v÷w\ä;ív.>RšcQœ8í)dé” >6á붆9ùh­3ôÅ6žeñÕ›³#y<Ù®#èøbJ@=|À¬U:äTЮè†ß™t¨Ù²Í K$¿3µ¡Ž´‚ì‡ÌŠ@ü?�Éšz^nJÙtÁ' ½Ñšl+ÈÖô×Ûi#ÅQ§ÏÍ=üZ'ƒæyT§óÄT°¾{æ¼Q1–H5`©�nSg‘lG´*‹hÉ­Kçã™ëäøÂÄW±·a&b:›—O¿! {=›†@ AÎÎØæl\(ßÇŠñ¢?Âkw¶œò°+ A±ìRˆ„1 Ha•¦ý Ù¬NršFà¶<:üÌ‹Üz¾…´ç´´:—CÚlodzNºZùÚÞÇÏ~\^øzs8Åe‘Dê8KååJu8 Mô‹6}A�bYÖ U‡t‡ä�€ý'Ö—øHd|rBÜ/—s"ÁsÛûØ ½ -åQhI¦˜¬²¶;¾àù¯È}B`œÍ„ô¯Ê‹Póé¤6”º}»Ü;DA% §»ZM­a-{= ŽÂàL1Ûr9q©m30–‚Ts…»žŒª?†à¼’˜èÏNO2�j]ÆZwO&ÍØØ¯¯òýǹO©V¿K±Èb9‡Z– sýÍÿ¬G4 ÙN¥.Kªq>ÊóGc8Ü„øþÖÿ›¤Å!¦T²S}°Å¼Œ ݨp >4:~¯ž¦ªaGØRy{U{G,¶sâ߾صßS—x;�ºš˜’ÈñÑ·Å Ž>M¶O„ìeƒE­>[Ãä‹ÅÏ8èÅE’QÐ5ûeí‚�%˜j}(øá¬›¾/„Qq.• 1=&`ÿÑœ÷™I”?'*…ž"Ž–v�+8ýÛtšãîÀ´ÎR½ÐcøKr j} ë†éç”÷ÙJõ�*¶Ã$ò>ù':c N¡ ”“íc¦ø^æ �ŽÁ=Ç2phI�=½^fs 2=T‹>0¨ø²�øfmöíOKåÂyíd7cÍæ­5Ñ¢¡úš—3l Ö“� (¾ð´u`q$r;–lÌ«æ“Ò¼×jíä4ós×é™Yiež6ãb^¬CÐàH¶ÆY@øF$­” &¿óꎄ|x-w_NWrž/oZÙZö‹�…'v·³-ÁT;”=ðV®Ìuà´fŸ6,͘Œb^ñ™\k¿H÷âSùºn.{?ö°: Ï6ŽÇ2¼pëj=L·ª {úhíaf©ú®Æ´‘ƒ}ª†Áðn›ÇùÑsPAĺ@­âZ°Çu¼…�NYÛžH7'+ò¬YˆQ ‘Â>mƒ¿i-P¨€ý~¹»|D#DÉMø›|a  ·O\ˆgö§sÄàç7$çiÎ…¢´T¿Ç|²]©r#i\Öß½ʯç;8t¬›Œ| oÄgžV äœ+îÀ©r+ãöb  ΀î4«4ˆ«Ž¡YŽoe˜*˜’¾×D‹ü`˜�Ï2ØLnÕÚ?àlÚ·S¹¾Pªë¯Äwð‰BbÜs†rÚáH¨þ˜¹Œ¥§‚™{‹¡|ÓD”…:6ÁHÌku°¿“Ð<Ù³Îo/ Ø·Ê+{*rý§‘õ_Îüïrýí/ÜSrb?ÍÈ�gQäspCÌÇ<·'„œ‡ª€{=Ÿš£äe©®m´Ó]u&KAí­[ÏXy,u©µ€ vÖ-á“ ¡¼Y?󈳖Œ9\ùðÖƒ; í¡€8ž. óâE.R�^ Kº‰ýN÷élPÿ¸ÅäP‘1mTy®Sr;¥ ìy7"¯+g|˃@Éî’ƒá i>ƹ»O½T^'q=!‘ýÂbœ—1M>£Ôë®@-¿¼ÉS¾A?•?¯“ùÔäàQLdF�ö1·~y:5mmÔa…¸áe …‡¼\r¯Í±Þ¨�&‡›­ò²| ¤l+à²ß :˜/ÁÀ-nfy¢íØ>òÀ"mëAŒ+׿\â~†twV·N#80f9öòÆD£x`J¥íÀ©á³ 0÷qæ'HgSÓ–~ámÓ;8$ oœôrò% >ÑZdø~µ½Î¸°\z— )§äŠË'hcô&›_@Q0õ»|,`Jq˜í³P¾\_†vΓÔ¬ÄëIV}æ%^g¤ì,@Ë�v·<‹0Cgß ÜYÉ‹ sŠ’IšÚÎ±î„ææ!Ü£+ž2ÆdÓ �klî-Û¹×­«6\E;“1X¤ò²°DÅ€hqv`ë!võØœ7JFEg¶8&â>=‡…oØ]Ò-X=Ý>Á¼�sMªQŽÀÃ?G øá¸|æÄ)?.ž%%gªûŠÇõà sÃ�ž¶%f"áý÷¿&¿$¯?[ûœ§|FlôoSé‹+DSfAN ˆÙÙ…çCSzö$Öl7M;±‚•,³0–åï·çâ\ïkÁ€Æ,óy üx8GEgB¿JÀ*dÇí¥3º°±xì©’3n‹ˆ¡ÒMk ±jôÜiÿ?s´Ù×èœ�‡�°ëÃúY{_§†4@¬â”0�¶¿86œ ƺÏ©õ; 6Cáá†üë4w•óäWŒ5òÑ>é…fÉóIÉû¨‰ %I¦0ÍÖY$îaõm œe@ o„°b™ÓÎD$��V!VB¯MNÔ[‹´È±’‹Ž‹#Ë“òIY$ÏÉN:Ù)†z0-_ÛgÁr,‡WàYi‘Ϙ°a§¶bð3a½lñêÁÓYG‘Ž ŒÐ€,=¶Zìú|¾ÂkÑüëøËfmG \>p&ÂKgÑM)Þ¦C`Ùú4¬2qœzòÔù[4•\_ r™‚5ZŠ5Ù_áÀ\'–:IÂST@whÈ´Dá §1²^Ž˜ì‡ È]¶báDIìJrk¿= _6$Àg�A‚’§@ÓRYÃÌ®Ç稨S^ØÞ÷Â~a öáX¤ß}®;9`wœ'7Ÿ UÕ—�–åàk^Ãåƒ\m%/1¼>æ 9ßÏ(Áî!Ñ�Ç?.ºædQÐm“ZL�·–L/ÏÏÞ£mÜ�Ä9…Lñ·¡EìÅgN9]û¦éæ ®4¯¸ãA:lƒ�?ãøÎÔ2 {LÁLÇ×9Âýd4ž3ÓÜ"SÞ þ{f—)›}Àí²í�jG+üû`€+&ˈÙpö?GõÔüÏgõ×ÿþájøÜkAåBýá�ø²õ�£ ቘú¾ëÍ­uÙÇyX ôóu\ÒþšÃ9!Sìü²ÝŠ ~-äª'Ð5gèyòÈ Z‹_Åjy¿Ýk§¢1|Ù~€æ 9MíÔÀ?�Ð,›%+ŒE-«±JÅ }<ˆrÍq©ÖrCñ¦%äè)Ÿž4Mù°4¿‰C؆/ÙÛƒâúµ'Zÿ^Û&PÝããQøLiÚá-¾ÌÞ¾¨d„ŒØgþ…}�‚ÞçÙ>þ[ÚUÇsú9“3„#ŽxŸ¹«‡O¤ŸN-ø_ܧì÷>}s>@Ôôa—VÄq2›¶|~ A2�Tgã…þí°Û9Lœ;É7úà§àÅö¨œaíΡýŠs±ÕŠ+[ÅÍ.ú`©1NOh2k¶œ†åPo6ÜÚù»O öÉ#Ör5{:¯"´,¥ù`"þcoŸÏ<I_{6<Ùäõ‰ç 7·ÅçÄ>Îa_0Èy{ôÕ‹…�ŽTéfCîåcC­=9uæ7+–œyB˜Á>£õˆä鯳“ËS>O¦©Õ’�e´Øy‹éN÷²ì§n�Çá~ü¸³þì+rb6ž¾ËI×È#¡ñ":�†Jt?é=ÉÍèNyÝçÃDEP¦ÖÓæ1‘ m긙ƒÐ§‘<Æm‹p†$›!ê´ðõÛùËsàHÁ©ª¿C�.mXQ2°É°‘â4|¨ ö‡8…w9N«Æï˜Ndº�$â 1vrÿ}jrßhÊöšǰ ì1W7Óü¨eÆÁÑËñ“ÈÚ¶ÑqE|4Wó>EâTb½^kƒ ^ÅÁf0õò9~a€ßÎ5…ç‘M»M™¶¿2ÊNÁU³:ljn+¾nGZ°BÐοezkóqãŒ_°½A Eö´p†iÊwx"«è|WÞH¼ W·+àŒŠÛc€Êjt íã0ì®@ë5›ìó±ÝsØ–³òl†ÆY#GãƒÅÉ'5–S‹ÎŠï}jÞN#¤ɦ£÷Ð× ß„YeV“ù€±iÝê¼Î#2¶f›¸èô 3k,§m¾–WXr÷ɰöm‰‚©ÉQˆ™g ·�F—å‘>éî´ ý†r[¯�€§ÃÃ+Ï0"�Ðn‰yæq›oøã¢9 \µ]aùñ9«ðiÝs ³}$À}Ö ;å£x–?Ϋž�ÏNJ�VÙ.\çåq…Kgë¥}ÂL©¥TÄ„]o'”XÃù¿yÄàõð,BðÒ§9érŸ´\)âf8õĬEk¿jÇ=ëÔçOøÜÅñ¹ s1ëäÐ�”j•Ë>s&hÞ§¾ÖƹåÅí#ÆJ·ìÞÚ‹×FAŸUuññ¬«Ï4pšZš>$ëÏXŠü?Ýrâîî÷}ýßÜ.èø75bKGDÿÿÿ ½§“ pHYsÄÄ•+tIMEå,yýt IDATxÚì½kŒ$Yvß÷»q#õ®ê®ê×ôcž;»³3³ñaQä.É%A",Ú"lA" é“ýÉ€aS!Ú‚!Ø$Öó“}1%ƒ´!‚M‚)ÒÞ—"w—³³;»;»;3;Ýóèw×»ò×ι72³{ú9U;}~ƒ˜¬ÌÊÌ®ˆ›÷ÿsî9`†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a†a-œÃ0ŒÃe!‡Ÿÿ$üì‹ðò98s –çàø.OŸèïð&%®mníÂ¥kðÚEøÖ;pé&¼s ÞÛ†­1;ä†aË0 ã£Î/} þÉ߆'ŽA7‡ÌÉɹ Sëvçì@ à!TP0<€ím¸¶ß~~ÿÛð¯^�ͱsÃxÔäv Ã0—Ÿ}QÅU‰Ë�ãd9dÄÍãõ¢Ø%Ǩ€Šœ2/¨P¹’*»NÈ6�XìÁÊœ¼àOß„ÍvÌ ãQ“Ù!0 Ã8\^>'Î aÀP‹¨L/„;ºõ&¶®n}^V °ÎAžA?‡c ð‰ÓpvÍŽ·a|˜ƒe†ña_Ù:8¿ ÏŸ��Ÿ�󸼇S‰Õ<0—lQTeˆ{UCà€À>°ìCr ÷ •{�À/z9l,šÀ2 X†aQίÂý‹ð3Ÿ„Ók°Ôk%ÄFçÊ«˜š�…DdyX#`�Ü#c:8:@.`qž>aÇß0L`†a|yþŒˆ«§N@¯Ù<Îq”ê^•ÌkÀ1`Ï:pXF\-•N €màp¸B�ëÀ&}ö9ǘuJwƒ ô6Ïœ²ão&° Ã0>‚|üŒ8W½ø BS7AÜ+GNÛ½ZVu[HÖâvHhp[_—ãñähr;à;pvÃŽ¿a˜À2 㱤ïásƒÏ}>}έÃêœ]Ñ}Àêœ jàÊ&akÞ¹ _þø5ø£oÃAy¸û÷ôI˜ïŠ¸Êæ5)½CF §¢OÆ2p8œ. nÖš ¬<X·€ËÀO ôä8ú8J†@‘¯RUž°¾|øã;™ƒöÌ)¸°gVáØ",ô`c×çtÌ4žZèx¿w‹°} å(.Ý€7.ÃkïÀ7/Á÷¯Ci…¿ X†a"®þé¯H­ßïdEܽrfMœ¢��†¿ò<üµÏÀ¯þ&üÎ7wÿN¯Aî§ Æ•ƒ1ɽ‡„UX-éÏó‰ÀÊ�<¬š„xI„÷䀧hþ—ÁâÜá�ïdÚ|:¾©ÿå¸Ëb¨ú¤sǵ^E€²‚á®ïÀ—^‡ÿé_Ãë×ì;e˜À2 ÃàsŸq¥.OZû)&€Çm²&T §Ê›úPÁA•y‚s„ ðÓŸ<|�µº b¢œÇåqÐ!£OÅ’suq±N"áÁ5P™îßèë1xö‘ܬ1P2O‰“cQ¸^çð ¹Oæ ¹9-¨Zâ(�@檉qÎqµ5¤öW.õ¿â8‡Ìð°0 trøÉçáÅs&°ŒÃÁê`†qäøôq®27óœåuKëC¥[®¿o °ÌA/‡O]8üýëwg:r©€L]¬¾n ´k^Åßwi×Äš®‹¤.€÷‡¿ÿ“9h5¾>Y2Æw;Îu+¡ÌI]±õ%øäYû>‡ƒ9X†aþ•žƒg�Ëgá…³ðÜé:,'ÏTPLn±Ây Œ q w':9…ƒÊe„çO~ãWàÕ‹ð•7áëïBñ!{:µ¨ðµ´�ÐÃ1ēѥªEÕÓáAhB„óº-Дrè“Ý'Hv.«Ÿ>•ä õp™«‹£FaÙÕ}hö%ÔG«Ô1�ã{@,ME��!¡×±U“† ,Ã0cž=¿ö×á§ž×anÚቡ¢(²æ’É7WQ ùHq":ñ6xbþÞçaû^yþÁoÁWßùp÷7šl«ø—SOû �h6ã9éï�,O®KΕƒ4À;Y¹>Žó¼þ<9ÎM±Õ@ ”ú!²çŽÛ÷Ë0�eÆcÊ‹gE\�Y“ÐNáœ× ׷ʬ&Û²>ÖÓ‰wìS±CÆ&Ž[”l;H ƒ‘¯(˓ן¾?òô‡/°Æeªêܱ@I¥MA,*.Mtä<�sô±ø¼t^ò“jÑQ�ñ>½¦ í’WÕ„DKºæ�ü³Udå䪎s�£Ôq†-rn¸ l”쩨.=T•#œX¶ï—aË0ŒÇ”ΊsÕÍ5ù»íâ¤UÍûêh,!µ¡i’¼Gê|€„ cø(ÖŠrµÃdßò¼|þÃß߃±(ž|‡ÀZ¾‹BhRdMn$k¤ÏkoR¬Aš@‡F`… +í›c j\•É8‡VÞÕÍ Êe½ß›çŠÀHÇwT” ôØ” .èò¼}¿ X†a<¦G“ìíÕÁjþ‡BÚÚ')*ª<ºL¡v¯b÷¾ ¨®îk,Ï�«Àèï÷‰n�ˆª!q²B"—‡?Þ½|ª÷¢O„VÌ»Z¥IðOÇy˜Œ÷¾¯MÝÿMf›Éõ2 X†a<–¬.¨{uP‹*q6= Hý§SHEó§'ëMé—¸<·tBŽídšœ¤œŠ‚!rÍÑYêøû{mŠJÕÀUë8 #J*†*¯Ò„·UH­©øèÒô"Ü®!ŽÝ»À<·ðìÐc€§PáÂöGG`âñu� è`Í© Úž@œ«'·rCÅô¤S¹ª¯»¦Ç(KÆ{”ÞŠ&° Ãx\™ïÎ\úÖä_9:„–»KÄÆÇ±LCÌщUÍÓrOÖªlî¤Ó‡Í{·`0Ò"›NT�—5p�ƒU1€:T˜“Ñ¡é;˜ ¬m$d�¬žž‚.%]* BQJ%÷[‡?ÞÞÍçè`E§r>ǹD`Å*öC$¤¸¯ÏëÓv°DÁ9û~&° ÃxLé¥g¢Rë!å*<} ðu~Î’�µFST&±OßqvnÐ$L÷�=¼>·‚à !]º7wa¾‡$œ]ÓàeIEY‡¾P1µGÓop…¦VÌÁÚCBd×TdÝ$g—%£`�À.Á¿IgpñÖá�wR‚#†»º_Ë:ÆÇ‘¬Øq…¦¦W˜ÙÄ1ÚÔñï©(w8ç,Ë0�eÆãz"òÉt’É·À‘“ð8<¡®ì�VñNë^eÉïãsäy®^EØâ0 o¾}¾û,ÍÁÊ¡ ໄÂM9:“ísd«Ç&ÇDçjH( doÆ%ܼ o½ßø|ë[°³søû[Å`�Û÷oDÓÄ9ߨ¨Hö?>/nm/~�La‡„9X†a:»™ êYZlSª³Ã%ó:HM«=œ  ­úH[À%bM¨Œ›älãÙ×*à%ˆÈ ÛppúóýÉwáõ÷àù3R²Âw•çåGOOÖñoõLå•#Ⱥ„ÀÝ‚‘‡›ðåwàµ7D\}ó›ppÊ4T•üùšÔ_¨`Þ&£K;:R±´Œ8‘ègbY5y©ûõ.%Wh ŽJí/w4Z&° Ã0…kÛ2æ½:ÑÍ·J��°�cØ¡¨{Ó€#g¬aÄM�Œ÷5ñ{ˆgŒ§¤×ôç+�ºP[G@püé[ð÷ÿ%üÄÇàSàÉ X_„…>ô:„|(•î3§Iù*®b ¬ f`w—·á[—áKoÀŸ_„›[â\ˆ¸9lЦÙuã`ÆZdõ€Œ=šÒ k4M®IDwÞ2Öž0¦¬¬P)èj&° Ãx,yã üô ""Êr¯á±œ±æ_Åeøɳ¹�cXÔ¤#<û4õ¯®WñÜv™gÀc©ðÿ:¡Èàò™�*øÒ[ðÕ˰´+Ëpæ<».Û…U8±‹=)éàAu0†�ÜØ…«Ûðþ&¼wÞ½)·ïoÂÎèèåyǰ:O Hú/zö4oLň¬®e¶ƒ8X"¨c/ÂÀM*®©Èº‚äaíáàÔ¥<"­� X†a‡Â«—`{òEÈÁ�+ä­Þ|±²yŸ´š·´Ó‘¡ã€Àir{SÕ¼b‘Šq6²ŒÇðÖõÃßÿ,ƒgŸ…_„^€çž�ŽÃYK#èŒ!+ÁUàëšxj`XJ¸õê¼v þí+ðo¾Û££5Þ#qÞ\‘äšyu*û8öU8Åpáèâ“P°cÏ6eÐ,b¨pà3Â`dß/Öa�)_} ¾öøì“°<Ýœ'ø(®».Œ½Ûmpd9~•±ÄéÚCjC ñ¬Š5ȾL(»’Xþ½«‡¿ÿss"®¾ðxé%x⬡üø 8®"Ò!MS ôyŠº·ó=)^ºªkîþüû°}õh�÷–֩ל;)¬:$�ðõ¢…-Ä™Š+ ã|UÒ$¸ïáÙ§¬7Ä•¢� ùí;û~&° ÃxLùÆ{ðëÿ'ü¥§àåsðËÿœZ­M™€¥\A¬ZUÐT4O+¹§+ÑdÂuÄœÙW•ºW7ðƒ# >––Ĺzé%xê)X^€¹àý½Bõœ¾fc>yNB�¯1�ueKrÁ|“s'.VÁXGÓ%c?¢é1‹«)ea¨Ç¹Ô÷ e ÁI~Ÿa˜À2 㱤ðïÊðcÏÁ‰ YZXÒ1$°Ç¬ÊîNrnðuXqª`¥…PÎIâóÞÞ¹—o~øûë<·!bò“gá¹³ðÂsp¦ Cèz\¾¬{¸ŽãeRÙ¼]%�’�WT,áü�àKÈ*xz�ð?ÿ-x󊔂øÒëðå7¤6ÖaòÆøÜÇ%4ZR»Xi› !â@úzŸ›ú_“Ie¬CÝ,› ‚ËEo]µï—aË0 €o^’Õt]G(ø´’·£R'k²mÎdE÷ú5™Pu¥eÌÞÞ»¯¾W¡ùñsðëÿ‰¬<¾½ä¸·Á½å�×{å8ОŒ™Š Wﯨ“JW:Êv·ÅÕ|ê<¼x~þ%øë?¿ú/à�¿w¸ãûêEØ>€µLVŽ Ö%:íúX“c-…h›ÏC«Ò{ ¸@¨*YQùõ‹ö}2L`†aðß„Ÿ{ N®@ÇKÒ{5‚УÌ'åÔ(KÈ„lEû O]º&âê�¾×¡²ùËçD\�^…އ0–ÈÈòÿ@F®�ª rJrJ:x*¼qo†”” 2¬ ¤ Œ®�‡à3‚ïž;?ùüá ¬¯¼ ¯¼ Ÿ¾Ësr ²žŒ3*p¾¢š*…]LÌZe«4XAë©•"®^»ú=û>&° Ã0ø´òϽ/žƒS«°Ð#t+qz²¬n«Ój%tv®‚äøŒKØÃõ]xó:|í¢¬X|ÿ†8W×¶ä÷6Ÿ<+ÎUÇKm«RÅ%‡£$Ãá�% C¡ ýÔ+Ô¢ªdÌt3lhœ<2s]q›¯¿ ÿà·àGž†—ÏÃ3'áÔŠ$æÏ÷ Û!Äq®kEa­+cý¯¢‚qƒ‘$´_Ý’°à×/ЏúÊÛö}2g‡À0Ž>™ƒ§ŽÁ'ž�í™SÒ$øÔªLJ =X[ÂåwúVÇ«ý!\; ì àæ.¼wKrb¾q þâðÚeYòÔ�Ç“«r,>~F&è'ŽÁñ%qDt’&W�}²rpk®ïÀ{›pñº$º¿uE&æ«»�¾nÔ¿ø/àoü8äÎI¬GW+Õ÷�r�EJhVÓuh¬‚²ÎWÚCŠoîé})¼)ùLP•¾~þËÿýÑ Ì,“Õ‘KK°ºOmÀËgà…“pៗªõ]/õÏ¢B.Õ�Œaç@ÓW$¬øÕ7á›ïIÎÞQŸX7æå;úÔ†Ž}ö”|NO¯É*ÏS+¸�iæþíjuùæWW6 {CùܾuUrêþäuø³·¤ŽšaË0Œûà™ãð«ÿ1|þ ›õ»"|âà”àr7ó;&–ïi8EÝžQ›ûðçoÀ?ü¿àÕ÷�öñxz þÛ_”â¤'WÄ™‰bÊédí&½—¸\Q�)z¹½/“Öï½ÿüáÊî£ýûÿø×௡©ë5©jÓ*õãB*îíMøõß‚WÞ=ÚŸÏóðw>¿ð²ˆª•ù‰Ï¨ƒîN`E 2s’«ÔµÛÂwÞ…¿ÿ›R±ß8zXˆÐ0~øÄ"®Î­C/q¹4ˆ©Ý�|HFºêj2z–Så}*†TN–ÅãÁw ùüè3ð™'�¾ÀúÄ"®Îëñpç •QÝ8Ëë1è¶&¬à´Ñ³ï\�ë„~WÚÒüÑ7½ÀZ_’‰6 8<OW]ªE¤=ÌiJN'€ãH5óy¤öW¦óîX…T¬^ ©`ØÆ³¥ÏÒ!¸ªÅáåeX_‘¿åÕ7àí‡\lu²®×Ù“pbz7�'qùe`G©5ׇš&#TÕ!Ëà¸'|öiøKO}�ua]ÄÕËçai®k‹ö—Ïeæ\½6ÓªY"´bCò*ƒŠŒ Gp]Y% ,9ÂÇŸ€ŸxÞ– ,Ã0HPœ\1áui{"Ÿâò}?±Mæâ”ɵrºZ ç “Áê<¼tøòÑ>?Ó�,“«úÎ�«%h˜òôêÕv>“ý_èÃS'à©“ð§o>Ú¿y~¢¾UFFF®îT_EÖ¢Šª5à°’,OSªŸÜ�áÂ.M8Q> ’ÑEÇÁ’ƒ3ëðò3pbíá ¬©º^óЈãZN�S»ðÄ´‘%“•‡•9-G�§6ĹZškòìÂ�¿³iÙ‘ø}MËPÄÇêO³Ï$~rê X†ñCË3§$,˜eàæqy™\ýJ"t +Å-&DK®ŽkU8�U¯Çúx醄B·CxæäÑÛÿ¾‡Ï?Ÿÿ„L(ÏžA”uAdÊÊðõ1ñÉ­«—ò;™9%%U+8_Ø&¬-Àßû<|ö|ã"üÅ[Ò4ùaç¤Íu%DäÄÍÈU$-«�ÚÎçt;œTÁ5O"Ës Öuu»Võ¹ï¨;R’QУd™à6%�|¡OlÀ©cgŸæ;°±"‚í©óðc“¼ÁUýc¸¼œÀåïã‘Qâ)ñ*ý²‰‹�ô‚ ò^JQô<üò�~ôi)åñß„ßù:ìŽ�ÖçõÉ æZµLÕ¾SŸ.Žw ÷iÚ?Åbªiƒó¸�TP9”ô©òÂS'ìühË0ŒûæüºÖI¢¾žM×Uy :zž§�«ãTTŒhš%ÇÀLZ�³^ivfíèíÿ矇ú·ÅaêuÔu"ýËuõ]XA'îPOÞ1íJ:Õå*¸ÊÆÈ,äzü‰�ÁæüÙ÷áþ6|ã!‡L»í í±éÍä¦ÛR"žódŸ¢ˆ.t.‘VB‹µÛÈñ†r’ó”U�;X�ƒSa¼ç;ð…ÏÂÏ|V\±s'$™{îÈÞƒê }âŽ~ú*]%)âJö§ñ+¥è`igAyäôª¸—ŸyRj{üöWŽ˜ƒuú¹ JF9­çÕÕ­¯ã+ENƒ®^œ�M9Z®>68'áfÖa÷É©•:9V–ð£Sɰ€cQ��ãHHiYOÞ±Qî>›8n7ɹNÉ=<0 dœCU9±Å#(°>!“Ö\|–LT¾>=ŸIhÌéæÈáuÚ*(µ�NY·Ò�Òu¨„ B6 ¬/Á�= Ÿyêá ¬¤NüÛçÕy: œÎ'îÕíü«œÖÚzÉ6§¿‹Í°cü>%#F”îEB9ÿmÂ\&Ÿ­ecEÄÕÏ~VB� =è•à×pì’eÿ§Mp<#º”t)éQÒ£ÐqjŠ§ÆæÞM»#QRxmäì!„œpj•ðs/=�ua]Bš€Ë²V80:ÍË:Þ¤áߌ�Œ!²PaKó-`›Ûš¯Eå¨û;CšÀ2 ã>Y�OÒ7Š:·(^ýÇI::+ºÍ%«£mD†À]*†ux&¯ËJÕÉÞG‰O]ç*›ÎÔiÄf“wÔO‡ä •N I>Òduø$¿%s2A®.ÀKç�?y¸û3±“ÖœŠ©9½ßMdš«&ö¿Ÿ¼vž´6Új§DÖvÁ�¡[Á‰‡à€œXçêÌ:,ih,+ô¯ÇÊ1$#ׂ©¥ŽSA×*=‘ö“œl�&6:^ꤹ ¢U çÏιŠã¼@“g·ª÷;ÄE M^�„ ÅÇÛ× ¬:k­×±ó£ ,Ã0î›…„ª>Içz‚^Ôóº:§�Ó6€Uó‰ÀÚAV™Å«åEr®"y;µØ¡ß9WÄiNÏù�:,˜%M‡&l¶¨ârYo)k�!á´À8 g—;„º¤Á6°§^ר\Ÿ†„®49iÎÕ“®›Ï5u5¢ó©â¾xÒV9í÷ˆ¬BÝo+TÌ3¢G…组<§ #)—°>ÿàûsú8œÝм¸ øœ»Šã2Ž9#ú”ô9`X¦¬o¥¾—«“ñcâþ@œ`›’½¿­ŠÂÁ“„ÿíïJaÑ?û>üÅ;0>äºP« ‰ã܈ªþÄŸžÐïíqý]—Œ û¿­cx•ŠKPw¤Œ-„ʪNfçGX†aÜ7ݘ=u{Ç#^ /âXR‘‘ ,tbÚ×Ij~Ƥ-'4ÄUšÓsú„Š’PËŠ&Á_öc~½‹9KÝZt8X1IÜÕ“ùPÔËå'+{49inú®Kœ¨N²E‡rVé�ôµ³^_+ã[êÔN(®‚•ÞƒïÏ3'a£ÝBò»*ˆ]Ó|«œRËP¸zœq,0½2rŸv2 Ð4v8‰eø•Ÿ‚_H1Ò_û?àϹÿà|ojŒ²dlR—r!¹8XÔãôy:J¨ÐÞErê|í_•I‘VÖa÷ñEm ÆõœºT'È8 õvJ¯ŽWhç`í©»jcH&ºC`œe”Gá„=™Ó³ Pz IDAT˜�ëãØ$ÓÓœNJkêà�P/ÖŒJKDÁ4(ÙVçî"�[伃ämm1bO�E‘;ª YYøqŽ\ mÆ0çd{fܦ!ÃnòÝúõ9Ï…4Ë.sp9aþ!Ì/œ‘ƒM—­BöxèR2OÉ*C6�Ú^§ëq¡µ ¯OÆ)ÖöÇq…ÀUýìÞ¨¿�‚’*ä°2Oxù¼äͶÀêz]%Ú8X]ÝÏÔ½:‡äÚ�Ñã¿—i}³uýœ÷�dÿ!M¥þPfÎr°L`†qßdÙԤ݊8§%úÉ�ž’v~NÌïéL:XÙèï0•ÓS%Sp9vIÝ«UÚ5£ÚUÏebòê \Ãq0ãXÔõˆ!'ÍMlòÚf ‰»#WRõ>ãýÌ†Ž‘S¿ÅiÞUãÜHr·KrŽkµ‹5-°zɸÅÚ^»3?³ê¸ú ûð©#P'Ëg3¬ø™MsûÉg¸—¬èæ$Tç©ï«³~,&° Ãx€Ywö’þ92–QqL¯�W“I+Ó)5#�¬nN¸àܸ">uLj4-ô%déLÚ!Óš_ ”¬#9,ç7 ®Ä‹!ÂxŽ ‰[·£Ï›.RN…áâóC¡Ÿ(Ç#.Ã/’--¡ñACSÞ ©”TúqMÞNòI:A,^ñ@œ\’2ÙN"ª]J(X£ä$Žs< \ÀqFÝ™ešP®OÆé€&iM?ç=$ÔY‘è€"R'+ÏOŸ<ß×,´ÄU¼ŠÎërrA°š\ôÄaüÎæ4ùhÑík…õM_™À2 ãm�¥E5o·Íªòžææd÷é–Ä@k5C8Ùï«aË0~h “w�pGÇ£š8Yß�;rdNÜKЩÀ’ÖÛv•柵ë>M_éÏÊ…é'¯í%NÊ#ÍI ÓT©‚a¤£Ò"›Å„t¢1×í�ãÖXö AVBUÂõ�ߟNøþdä¥J*ù¿ŒQÁ’®\Ó-ŽQêÎM6&Ï¡} ½‰÷Ø$c�¦G_IIUU¸N~øâ£ 20yãJÅVFqœ6‘êì±BOŸÓ£Iô�uÀ®×ê±”ñ.£È2¥eË0ŒL^·›¼v8áb…ȆPU°¿ï\‹dŒòÄÅrSct·¹³ÆéNï£Ý”�F]¨²šp¯¦CÐÉmœˆú@Û…L?£I'+˜Â2�eƃ�°‹räuÖ“v#摹\Š`VÎo&nI¦ûœ'â¨ËÝå„écºd¾ËŒR �‚q"ÃV…ù _çS�’‰8:Çh’ùÓ{ê†\Õ1¾¨÷/éc;ú^ü?!”ò7ÜÚ„w‚ƒÕ:ÚåÌšÝdK�ñ¬ã<+TØIƺ;cÌ]TyG¡lA!@CRu=ÖöšLr�ãx nV—¦‡äâH^Öïë{êbí¥ßWX&° Ãx� ¹¨¯mâz”:1‹+U²‡¯[‰lÑÔÑq4á†Í’ïvxE'ß”å81¹ä¯>B+éÁêNÝ7ƒ¬ÍÕùt%E�èž:Q;º¥ESËd|ÏÛ¦q(ÅÁòRŒSW,RP à`$áÁ+Ûç Þƒ{Xcåîóoyä´WfF« é09ÎQ4§k'ÙRG²H,JX&° Ãx€öŽ/4º$0ªý‚œOEÉž$_c™v%÷]u5®ÓäsÜL„V©ò�ÑX!N#ÚYT9!IŽV½êOϧjÖ|;²‰ïÑ ¥ñÓ[¶öe¥¤+Ôá}CJzu-(Y˜q ¸LÕªoæk—&¿îZ²íЄ„ÇäTå’¸¡ƒnîÛ7äö�Ç+$²oúß®¶×ß’é$þ"¯"Õä ›��vtjÊpÉ:Á�|ºú½\£Ýì9 ¬›:®WÉØÖ‹§¤å{(Ë£qAd˜À2ŒZvds¥®FŠWÄžÃ$+ºW1a6m•›ï%.G:é„Áøð÷w0’ýõ]Úy-'Pµ–ºßi5V6c¾�¬UN€iqõˆì�+›ðÜIùW³q]—ª Ç'ïÐ'§«²2&Ã75íÛme6“ñ%B¤D¿Cv‚°®íÂ÷nÀ×߇[ƒ‡¡ˆk¹ßgÇñ™\¹ê&ÞéƒêƒÍ¬8!³›»¯ÏÁÇïk¬DVÕ㻣‚9–¡$+ ç-`§^UêÚ„‘ ,X†aÜ?×wàc•„vr4¤”ë‰Û×'äyu¨buö˜4'â–ا�_¤sÓÎÁáïïæ¾ºXi³¯¡ÑF€Ä è²Â.×ýˆùTé;ÄI8ºU±^Ô-uné{5«*�å|öÛ×à/?Ù!\Ã9™€‹ 11 Ëp•ª.E‘C�a§4Ok/q­Fêt@U©„¹QÀ âê?\‚­âÁ÷§ â¤x¯ ”uâý¾®ÍµK“´ÝÑçæR6 ©Ь¼K7yŸ¬q!+¥¶×aóÞ¦„î:£d9FEI`HF©.V ^¦YQ/ Òq•ãå¦Jo€½¡�M`†qß¼{KB;�[Äzä¹6lvu= ´ÍF\qV%ÂbRXÕ+«Jžxmûð÷÷ò¦&õg²ì-ë¨@Êfæ³ ’ýÒ^ ˜åL]�É×(§� �Èyã* Dzn�Þ—똆úïËTvýۢÑ'ãZÞæ8ŒU\Õûâ¡ ð½møÇÿ¯8W[ŒÂþUqDòºæS;¬W1R14š Y"„ë·›ã4á_~ÎZû× 9Ž�€£sñºäMú ²Šàz-w/†vãýRïO[�\qÉz5¨ pk×Î�&° øÿ ù ã {…à¶ê_­«}‡×k橾zÌn¡RéŒp„ª„gOÃå߀õ¥fù»‡´*µ¼ÈÁ� )î$,re.ÞñÝ÷àõ÷áÒö½¯L|ã*ì� “ƒ_ TC\æ[ŽÍnâÖE·ê€¦ÖÂmÜžè|ÝDVQ¾ ¼CÉ»HÞR“ã"¸¹Âo&G2âg/ž‘*îE!NÚ­=øþUø½oÂo~®Ýc^Ö¨€l‘À0£‚ßr×ö'Ž{/‘©ÓaÏܤZªk+âC]³¢”7x!³ +ðßüUøéd1Â|WšŽgÚxÜePÞå1ª¯r*B•Õ;œŠ¥Y«"Ck|]3žàKBdµâ×ß¶ó£ ,Ã0î›W/—¿ùY8¶(í@ü²œ°�#Tœ—ZÐ%М8ZVÎÉ¿sàæåFý8_âôç¬>[¨‹•‘„‚ ‚+DxÝ: „^~øÝWî]`½þ¾ˆ³ŸάÁò/ž…gOÂÙc°¾ Ks0×#tFªpUìñ’\ «ÃTéɹ(a¾Ý|Êëj*h‹hÈdºŽ/N•iÈQÜ–qâ¾ eö;"Ž>v~ÿ'�KÛâ|ýî+òúôŸK¸Ð¡•Ï—#º9NŠmGòD|e´WÜí2«RzÞš¬åSrÊÝæLê(oëRÝíZÄpG $=kÜß ÇÐAç¤ÍM×Árž=O®ÃWïQ`ÝØ…§OÔ6Ôd‰†´B}tçhZÅÅi鉘ØW¾Æ’"Mò~â4€¯ãïßzë´8Wý\ŽOÕ^‹êhWšŸ ï¥U»Ç 4Âe’ó8,%-cÚ¿Š«NÊ ß×Q ûCɹzûº8W_ü|é{v~<ª8;†ñÑÇ;xñ$|æIxé|þ“ðòSÐéâê+ðPWߎ[—a]�[|±²ž<ššD�…Nx�ŠœJëk?ìRN…ž'§Ã�¾ ª5¤î׺n“yX>™Ä÷u‚ßn’«óUjÍ(¯!ÂØÏnÐr&˜rˆb£á¼v°f??uºÒi´œ)®B-g‡ÉïÜ”(§&ò´DBtNbÈ.0¤b@`·)ËÁ˜À†fI�g¸i³dଽJcnW¨Ë–ãðú9ò,è8-HUúU§ù kL»gßMšÕž1/k cU•]B6��ÙþþÙïÀÿ¯î탕98»"bþcgà^„Ÿÿt œ—ts‡##'£§Ÿ?¯Õä}Ý`<Íy”ïGÆÇϘ¼Î­«€PŽ`<"üþ+ð¾w¾Þݱþ‚æ`†ñCË'áøð£OÁʼ8W>­@t ­Ö$“-IÚ9P¡¾j¯´iq ÆÐ”K<“»¸s“{A ¯’ý;£C"ÏKÊzâöõ¤󯤊}³ÊÎ©Ô 4«÷œþÔˆ¦P ½TðşܬØÎÅÕB©j…ú&ÅV#´ÜŒü9§Õ±Š©$èJ]¾*Iªv¸zÕi¥gþPϳrʶög§~Ì©ëâB�°_iûŸX 4.Pˆ�ìXÛkÒÍŠBx›¦’yt®ê¤v|#®Æ¥8i¯]º÷ïÇÙø¯~¾ð§Γ¿¥¨E`¥ÙnRn+׺^®v¤bþUOESŸfUá¤4ÙR&mN[Å”@%a\I¢þ�]øòw%_ñ^ùØWÏœÒEdË8z8FxzõEG_¿ 8ÈX¤½2ŠFù~Tì’±K`�QÒ|»¤ð¥ø¦ýB'“<8€ß{Õ– ,Ã0~hxéœ8Wy¦¹Y¡ö¤�rŽg¬"Ë3GɼNQd¥C,w�MädE!sž&ÖíoÝÄc¡õ»F ¸úÖ×N›££÷�È%{,.Ø—¥ðy-NB]Þ×?KÑËnkUW†Wå�å[͈Ó\œ{XÌXíÛjBXµK3ø)qÕÜfÉÏNo;*}+:µ«šì¹ ‡,Ü~õ)Ó+ászE\t±&ë< ÷'ý]Zk²Àf…¬~ ¡‚·®Àoÿ©8W¯^„ï^½?�õÄ1W>ùãcøÜ“áZÍ«çô»±HÓ€;Ÿpå²dß B- KuX%!Þ�ó0×…³Çá¹SðÇß·s– ,ÃxŒéy8>/‰æ+RÞà‰58sLd�/ÂR_–x÷:R^!Ïôê8ƒ“«w“¥ÓíÝÔ[º›€ÛP¥É&޹ÚêPÐ'°DÎ žã”#g�P¯ðšKœ áøºr¸4£•ˆ»H“´àéP1LÆóVRp#JŠ�¹ä~^?&÷%p'¢©‹§$W‘%nVžü,ùZ¾5�7kSÁ5Y¥Ê©ŒËè·’˜g ¦YëNâÊÝA\q[ASN‰­²¾ ‰Ð µ3URPÒÕÛx¿3!Ääqy}§U§IÄW1Ñ¢&¯…BAYÿÜôìQ0LròÆš—×´z9˜ñ9˜u\ª[}<\ ”|ëÒ½ç\Mòô)Yôá3ÈNèØ5‡¬K�‚y*Ž!Žé¶­ïȤÀ’«·hzÞÒÇvñŒðî&¡„àW ‹=Y,`˜À2ŒÇZ\ýäÇà§^€O=6`}{ò»<ÓÙÃÝ.æÅtðl–ˆ w!®ÚŽÏ�WÐäã(TH&Ï¢N«¸º¹p ¦Éâ1o&'h:3z…ŸÑ­Ý†&C)þ{Ó[v›ÇãæêUŒ™æI5"Ëib¾üÓªsu<¯îƒ¬Št8m“í4(5+¿DùTÑÖ; ,wG·îN‹YaJ`Uµ0jzÝ5‚+Ôu¢!êç•àk.§áD—0(ÉAêÖ;±’zÌ­Š=g훛؇j"Üëîp‰1µéªØºÔ+¡Ôùuèdú‡¸Öç Ãã)è$Žî2’ ·…۬΄ëCžû4aë:‹-Ëd¥ìùãv~5�e�1ÇçE\ýü§E\-͉°òòíF"1fMº%Í’ï&Y¸"Ë'^ã§ÞÃÍ“­Šåý{:]®�i†NW'†%rÖ�S8žNÓÔ’Jˤ!œy²ôÞkBrαÂv©�Fj!w¯[ó:—ÜV‰ÈªÈè«tªêÇ¢ªTáW¶å‰ì«ZG(=+ʱ¬êÛÛ‰¦&`™®*œ “ãîAV‹ Jñ™ÞVu#á {ž6—ÇÆzt1‚”ÕˆaÄ¢ ­Š^jáË,¤-kFxF” èÖ%-âZ0 ¯9SA_[$ µ]’,g$ößÖÐ�G  RÚà` ß¿ _zýÁ¿Ï§Wä»ëæqìÔ¢:§¤OÉŽu¤ÆÚIà)à”ºXË4="Ó¢©±÷çŽ:W—�Kúܬ>=xŠªb(ÍÍO­ÙùÕ–a<Ƭ/7ÎÕêt½,õÎn_ýÜÝÁ͸۰’Kªé¸;¾¯»Íã9™æ\å”tqškåX–q,×V³„¾[ç85kL¦ ÊyŽóä8ºH8(N Q(å‰xÊgªü¶b+:d©ÀÊT`uTL5+!]ë¿,ù9OŽ\¥÷™8š~âx£>�Ÿò¹få’q‹ð-›ÇB½Ò¯X%ÐQ!åõ6¨è *ºâý±þ쨨4A½ª]®RêfZú Xma#]Ì0zZH¢C £ïÞ8•ñçÐrãž•1k«”ïMˆ5Ÿ*õª"¤ªXª€½‘Ö�º&ÎÕ—^‡ÿò•Ž-HϺl†«]IOIG‹X¤%AVt[¢B�kL“·XêEÇb"Æ:ú}‘Eú È28¾dçWX†ñqÀƼTN~jC„ËÇàÄ2¬-ÀâÌ÷$ µ›KÛŠÜk΄“mcyÆô–¶³èßÅ´v§?ðNSc\~ßA'19¶hå™duÈ):0e+æZ“¯“¬›Í'!«Bß/ ½µó™<í<& «utÒÈè’3�c ©u’œSz•¾,�'ýü\êqÄê@#¾�ÊÕ«ð‰Ä*¹ÿú_!™ª ]Õ˜Õ¿kÒÎcð©S{V¡ÕÚ:úi•ʧ²Éikñüb|�§TIݦqk ‰{C †††Pq@Æ>ûö³§Ÿ )ìZÔÅBÅÝrT^B”T”á^…ó!×…Zì©ÀÕßÕŽŠ¡eýnœB:F^žÔŸU`ͪƒóÒô=zú¸8~"PKJ]} ‡²r„¥9›L`ÆCdcþÎçà^†gNÊŠ·^GW½©ˆÂ5ÕÉ�»«ëÿ{TÓ yÝ=ˆ1§¶�­ñã�DGC#(šçufâãqšÍ’fÎY«Q¬¿ícÌÈWêÐ!Ð%cÇNv=KÀ<Ž9 ¯î”¯“Î]-a|]x‘ºZTP—HdI5S`ùd`Æì�`6õX*°gÄÕÁ²bFÅ(W K�DdMz…U"j|"°&UN;ÓˆD¬µëÛß?1c'µ*ùôu Õ’Ç×’¼Y£×d„…ú9�úèÈm®®–KVf­Õni¨°YÑ´ÄE`D‡Q-²*†ÀæpÌQÑ'£«Õ·²:,ØÔ²ÊÔ]«›� ~æãð#O~¸u¡ú�ZÐFÿJ>wA ¥R7«žK«NË�j ¬ô~Ÿé²âúúÖópæz6˜À2Œ‡È…uW/Ÿ—|¦<ƒÚyâhE‰�ÇNÒÜ;¨w&Ϩ’zY¥&Ï‹àòºåZ{,Ô Þ]­xîÈ(TxuáÐQâhÅ;dZ«íì åã ÂÆ}LCÚ�ÄuêL\ÀÜi5dÞÏ“÷Jß#›|]žÙ|ð‘XóGáÅs2¹�^ƒÕyiëöœZ—‰h8†ëÛ°=„ƒBVL-ÍÃÊ",ä�Ç+ÛŒ©ª.pÃæþÕ]¸€ÁXº°ßڃ˛pñ:¼uM¬áË[pu ®íÂ~ñx Æb'¥žÒé8µ Ë’ô¸ºËó°Ð‡~Ÿ¼ÉCйHÎé7Ú%÷õÖ9ØX¹Mnù!‹ü¶!´öëí¼§h�PH¤ý~é ºÉ%ói$›r:â ­sÎH'ù]˜È‘Š9LÕTC×ö–O”HÃqùTùéH–Š$q³|-~ü„ë4í@Å69åŒçL»WÓ¯wäjó­ÛRW�1ÒœÕDè+æ9‰ ä5™:S/¤ª®;õ”ÜN�Þƒù:u IDATHž¬‚lRç]5©Iœü\‰¸qa EÀ•AÎCCŒ`0„=7»Cq¯†°?ÐÞ,û’@íÚ³n4€ÝØp·€JËk””^Î;{{ðî6Œ:ðæ–.ÁÎRÌi°hÿC89ôÄëé£.„™&Â;M‚—Åû-7'—`d–A·ó! ,W ÿô|å&.ÐÒ‹¯ÛÕïâ6bkÖ{E?xúo1>ëäŠ8U.ÃeÑÎïД”¥ à‚‡pa„ ýúÜä|¼ÂªfNµÁ‰‹QéUª\ɵR5àÀ� Ý\Vt[”¾i íÞÞühÄÉEWŸN.‹=ýåd�WœÂÓª+aBз�H´/“É1Ÿr²)Ü6<×4 ‰KÑûÀ¨z¬iµ›ºDQPä¹M“«ÍÊZ„ÜyëÎ1©‹T♟jk?¿-’ÊDL�ëDöL—cgú_ºÂÏë*7¯aËFúD¦bp–«–O¬Hœ51¸ú8fuæÍP³¥ #q«+u„v q‡ÆCm7!3. ÈEÏ\(`¯À�€á�. Á�®™Ú�.Ñ�8Cì�%Œ·3×i8„a—÷a-ƒ‹;"pº×a«×Pe“›ªwíf°õ_Žr®ì„ý¨¸«\Í‹ øì-8»"¡Õc@X†lûÉ+K½¯j7æ vê¤ùªî9$c—Š%¤›¬ÊËkW¶Œ}.ӈLJ ¯ —$%‡$0^jq�ízîÂËŸîß8û½Ln}Y�žãZ¡‘ “S�+ú°/fŠøªÂ‡@æ |hŸÐIN…鯑۷ÔÝÞK 8/y¡™'äAò¾ðüÙ‹??×hÉÕ‰»�÷‹¯¿�yØW«Ž]¤‰É± '(æ&•Úí�D aFŠÙMhËä½bAH7‘lìï�Ô~fÊDD—¤?ñ¼b¦³Òέr‰ph,_‡¶šö'Ó¾Ir�ª:�"íE—Ó^ú?+œ–×â­¼M.Ôtn“W'*×Þr]ù&!¶&É~HSN Hê7eõåêÚMcýÆÄbi 'ãhu¢w™ÜÊS�†’ã-eÀù€;P—jo_Bó{1—i[{°;‚�!ÜÀÖÜ:€‹{pm¾ý=;y>6\ƒ¯]ƒ¯Ýæ×çNÁö)xùIxî îéuÜÉ˺\¢G‡=­ë¿H¡7GI¹‚X ¡ÏM vUV�Ã�je�ð?þ§ðÍw$mä;W%ÜûPV,�‘ë7Ìik› õÝJvðÚk³IÐï%çŽtVH³Ó¦Õ±MNÜ´XË?~dÖB.«º¿ð"¼tάI_ÕcK¸üæ¿RçÙwnnjêÏ®Á—á;ïÁëïÁÅÍ£±Ï�F`µ?1qX&ŽÐL8™«¼ ø*�û€²¥•z]ýÁrɲ^—ÔU‘i¤˜¨ë_ãZ×á.ÌÔ˜è�„»xM¸íëg_«„{Zwóš¬ÝŸòˆÚõ©Ûn�ÓIúö+³&·0ãyÙ„Êf$‚ÏÊsÊ&zÊe3r£Ú=ç\vL øéˆpu~ô ‘�¼Ó«®Á®©/=͸u¬¥ÃG­xØBŠ;�´ç_cØh4ur—,J¸“,»À!93[¶&Tîý?§_xZÀU1ÕŽŽPYžN�»šÏeÂD$—Ž\€¨µkE“]ÌÑÜõ7þè>X=–£M)+º)AÜg}`£Ì2Ê*F>0 �"„æâÊšyyè°V¥1# q¹Â�v€ T ÌÒÄð´À)Éö»ìÔà:k–Ø*sN–ÉœóÃ)€ªŸ9—jŸhj¨™%ƨn³ƒÖÙ©@Ë,…ìì0²§€#³Äð g¯�ÌþäK+K2ñŠÆv!–F1 |ŠÇ¥Õ1™$¼–5þM¾§ë2I!_³ä½ÔÕ,YlCæ—iµÖ_:ú¦Ò%ê›"£”y5¼Ô ÝÚÉ,z^)sb3PÕp4Àux,Éj³#Ø]ˆ�æþLÚÑmyíY hœÜf¬Úª½«íKÏÀÏ| nÁC“;&oJåXµ-ÈšZ˜ë-,Tôžô‘™‘d¬‹ðô#À￳¿yQ%°(oò`kj*-k3§fŽ•|åoI(e²|ÒÄbØíÒ ¶Ã`Ô¾èýnŸ~T˜«Ðé²ú÷T"”Ê‚ºõ6l»9›‰­ÈµøøCð�ž¹Vœ9L¬c¸€8Ïn)u»Že:¶LËu&ë Æ“œqŒÖÆã\³®j-Òáš‹S‚¹Ò«±fÌ)X$i{ÁjjEÇUX¶…ñù {uv�.‚–¾3w¾”*kNUŽ~‘ס”Ýå÷Í Å{µÿÔBEó?³¤S2ÀÉt–X†~Ý;Ûh±„)ŠHS°”€®~¨Í�™µ—Ÿú^Z Ũ†Ê7Ú®VË™¡X%ê™úM©¦É¨†©èèšä õÉ™‰…]RmSž\3šSk'£™°ÆK5<¸Z<šæêÏtTÂ~ÇÇ’9·_ÂâXÀÐáB}åæ°;ƒWîÀ ÏËåj�^µwû¯þ/xóÜ�Â÷g˜IÀtJ†[�käMé'TÔÌ€#5#­bÁ"£Þ\£œðăïüï=œ«•MÙëË‚œL« ü2 í"yÝ[´¥sR€5WûÊ^½¼¼ÜFÒ Žuìs‘L¼?Ìr¿ì#Å% �…¿Ú²@Cž`é¾×ɾéõf%àr«Pú˜°6‚Ǽïƒ<Ñ\´Fhë´…,7¬õ­³9cjÆAnAë­“%2Þ6~-óÿJ“À%,h`X¡X^K3øžP¾å lÔy@–ix¶¶rš9Õ¾“~Þœ 0è�b:¬IÖûßô¬¬¬Ò »4C¬ÀÌÀ2½ ³|ÀŸÅöôJiøÏôjÇÅÿÝR­¹ŒÓ‹úÚ�0aFð�/S{æS&°›£c_¦x‹‡4·ÂñÔ»©½RÓBÀ^ÀXÈ›)Æw]¹�s­™³ëѤ2 µp¢mªÌ•±ZTPVêͤ.àÁª»¸…ñ’üÿU[µo«%¡Bä.¹W£GœKí\£%u#|�U;ý±Í$ãú�n»Gr×ò²re±%¹*kÈÙ#0MØ«:Æ9N�SÌ‘ÝS u˜€ªTË•&Èoy¯[¿ìÕ­¥èJÖYQ;AVÜ÷JÁT‘‹ªåð[½™AXÉë—îg€%`jl“s ÃÀU¤î’Ô[2¬g&ëŽi晜Q€ÂZìh¤ -’º±Š»S`dq”âkÒh§Œ–kØ«™,´ª»¨ZD—ðŒšr ¡—õwÓ·Ö÷i: þ¶Ëå ·á·32âTqùYYx]K×Ñ™&U òÊ{Â÷šå²$} F²N´ �qQ,ïz@,Íòs Ö 3Ze›NßïaFÍ5�¦)ä»hº!“Öš1ƒœ×RæµÖ‚«Åg)Pú³ˆõèfb>íê z¥Ê‹×Ó±íÒ¡�Ò¼†]G•Ô­³•¸ß�‰xñõ#˜æ0;„ò^_�©«¶jMûåß‚�L˜Û�?×/aÌ:cí¹FÚ—y<%s`Ÿ1w©¹§`$ªbƒæ¼‡��wþ·ÞÚqy¾Fà.ð̩ӖÕÊ©̨ÙÅrIõ¸ DD\qú6Cj-îÑê®ÞÄ6ìÕc´¶ Áê7÷ßûsÕ¯[XEL‘½œ°£¸`Ç5eð¶h´–ÄÊÚÝn(cwW5¾sœèêÌŸÍlßÏK|sS+ÿ5-öº‰aK×1L0LF#2©§d­úýÔ‰¤Úü(£³€€£Ð!²õB‰EA­Î.…bk]/X.©…zÏ°Ì è¼Ëtý°+ïÉ®½§Û˜Á :Óy§X]èDFåÉk~`�øÜ&ûE²ý6LÖhi(²Ü2ݦI4KCà³_k.õqj³!SSHnü„Îû"ù”ëôA²êœ“sV©Ó7ÄŽ•a:š Àš«€ü@ 1«C)Ÿ²?‡Ù1ÜÚ‡?Ž„÷ÞjÐ\µU{+­ªÅ;ë¸v7wM/“«rÕ厒¥[«¯­‹ˆ1°1yçç+w„½²™Ê°LGpY¬# S…[7=Æ*OXœ°vuÙS›) ºÚ«º–n­rò[Þë6X ¶mié ¨ËÞVÀµ£+Šþ#{å”­ÛWÖ«PèÎXkŒd‰Þ¿«æ"cÖ€K®a¸Žá ®âÙ!gÏ„œ1ž‘3¸(~–ƒ5êœ\o ¹4EEµP-•Ñb¡>IYµF,\É7D+­æWÝ¡½pzˆ¯ÍÊ MÙó—>Hü…N`§ºº*–,º€Ã,1Cm&š´_úøoÀ/üÔ‡O<ˆ±cõïó]¬“³EÅe….*8‰üucÊÀOŠwÞ�ó;·$;·°�íê{˜¼hª�HeÎ…ª³rö±Üű‰m´Ê“ƒ5WîØ'kÀÕLÉ…¸_¡v�•§Â/Üx¬+°½&×™Sb7Ù‚ceé®×�Çôñ�` À:@ý)mQ­¦’‹~e@uuï`þà¬hðf4¶j˜bÔ£ÖȘb˜™«œœ¢S¯ÍhöT;Ðìóñ06�’¢¬:6fZǽPk‡®ò`ùÀêk°Î§¡Jmh–á­Ô–r‰ý¤ð`8€�Äæd P–V–ˆ¶cžJœ÷DvúºIÞo�ÉÚL¶Ø$™mMñ]Ÿ|Æ'Ÿu 0 8K¾/Œéj—pV^‹=¡Þœ©œx,yÙ‹n!^M•“2*3µ4XxÕ3©g“2K®\¢iRß&Ÿ‰Pð²‡7Wcݪ­ÚûÒþä8ü´fêÑ™‚Æ>/-{U€ Ê»@Mß\äïüoüæpcO2Û&¹‚¬&7:r9jíG3MèJ“S`‘¬Qä�qŒYV® d W‹J¼¡¾ù>h ®]hëÔóè2X­F;.ëzÞÒLÊ(‚Ÿ*ƒ%ÉtN‹È'ß2Îïßk?`Á:.c¸FÁCx®QqËž©^ðÑ)k´2Qš ­‘b”³¥ÂÆ…æ]Ô0¯ ó’à3¼? x“áÖ&xj<9ž1ž\!E­rçÈ\yÚzyý¢,±�äÌî2øüæÎàú¥_†îCïŸ,†*q�ÐÓ'¡À:1¤¬“Û×'ó‚ä1ñt©½ª]è{‹ Z#*Y'"s#ëÕ^BfuÁcê YpN_›ëû³Rž‡cñd*U·œ„ÖÜL€Í¬–pÜA ¶½T9‡y7f°càåCY¸}¶¦°¿/D“Üj\ZµU»?Ú þÓ¿ÿÛ¿^„‡/EðªñqMrÕp�œ=lÂø8u<¯…eyÇÖëð»ÏÂO}Ü–reã5B} y¥«½°¥ÄqŒåÇ« °kU³é¢%ƒ€«q�©„,µdFãÍo½ëºԽ�™Ñ¬7^�X­)[uxxD­-Z�@ºð‚ÖžâH]ðÛLBÓ˜¬g0…½K‰=ƒê«´@ç¸1•úP…òÂÄŒÏ!“,Û2r¨c$Ö&~&N*¤—ž,ŒÅä¢/ÿëO¡5 E>™«ÚXN®ŠwÀª`Y1ŽÎò!9©î'F>)Ë�N£oÂl¦Ã õÝã]ÂX¥Ùs1c'¨§ª‘·k#(eºœ®3g¬/&d6ÅánGA /ç²n­k?@y(Û<ðâËäk¸­5êþxWÄåœa$wX­Æ¡U[µû¹9'µ›‰w˘Çþ1V)šz ±·O†àì]X/íÁûÿÀ¯>~ þÜgáÇŸ„b�Ðh/�jŠ 5u3Îè´uÉh´ïÜÞº¶a®lSÑ/~ þï?ì–Žy¯ÛÚXŽ«1,ûÒ“Tw‰¯–•Cƒ‚þ_6Ld»tÙHÓ:õ¿çóƒ°r"g�‚Kd\%ãpÏ&� fÑlaa ÓOa0Öèጠ&†œ*½ª‚Ìgµ^þ_Dæ):€—­±eÜþ‘‡*@u ìÓ�ú1-á÷ï!'lÕVmÕVíh/ïÂb–p…²X¥¦ð´– kÊfIx©n�VfÛ²-W7à£Wá£ÈããWá#WàÁ-Ñ]» £ÂyK×zýskŸ0×ìb›A¶M0{Í*q’ê$!ɼî¶6®`ºF¢µ%Ø9ÁëDö‹ß‚_ú­÷÷Üd©èg+™È7Åæ£EC<7ë´.öy–Eà5iÀ˜Óä© ’�þð¬È`�ÉaÆJ²5-?XLPF#¨µ5t£®©þ§å›0$(‚<:.—bé¹…qV]•2aa‚1ÀÆ4F -QVªæÆ¨dGAýfWC'û¼ö¥n{õë&¼WÕûÒ¼–›9fÃÕµè‹BPêÚ]êñ/Ke–D™ `k‘¼Ÿ{»µ¦Š ŽáÊ^•A@Vä:ËFð@€›œî ¾j«¶j«vÞVK_ÕQ/õµ´±¸{XJjW4®þêàg¾OÀÕÖšh§rÓ~è­Öô‹cÆÛ*¡ˆ,¶ n·IL«åzN¯Ç—.R’§pU9¸sϼòþŸŸòT#}ñxð�&{9i½î;õ[a9>ì ®Q0ŰMÆ–MœV:¯°d7ïb^Ù…[pï®hp6Gâò¦e›¼ �:W @=Á\ ø86©±'ÈC4Yä2Íœ‹*e®î—žƒ¯¾üþŸ›…£ã`Á= ùq¯ª ”Kš²¹Ž†3ZÒ"¬ˆÞ–C¥�ÚâÖ ÉÂý{ÍçKìUŽmj»yL–©u�0_]‹;µÉäˆ.L äÔð±ö­p:¢b[‚-`d 00ëv¢nÈ(˜R3ÉÄöN¾» px$žEû%ì–p{îÞ†ïTp0ƒ'Fbi³.ÈŠ·T=‡@v ï?cô»ß쑜ý[ó»@B¯ MoVàjÕVmÕþiÙùknœÙbXp}Òú69ذnåˆ!…Qd¡|2ð· •zí™L&øG%쉎x”¬UíRM'j� çÚK–ó¬ ÆÝxí<C˜«¯¾ Ï}*7UàcgLkÛS´Á¶¡Q§ÖJ­¾ÌôV_{—Ä Bd5ý} °rÄ3¢`�šmrÖ¨…½ÚßÅ|óeøÝoÂÿñ»ð''T0ÿÌ'ázG5üÓ—�äÔSÚÉÔ¸ºE ‹˜íÁ3 ÎCŸÕž}›Ÿ[ ñ­êÁ­Úª­Úª½cÍ8‰`tsz,m­†:a;–†àüØ^WæjcrL¾hlx"Tˆ øXе}ˆ ª¢_˜9£¢¦ÂãmÀc€Œ<á�_…ßü*<÷º,¯î½÷ abá'Ÿ‚Ï>ó\¿ ;k0ÁÅM�zö¤AN�` Ü; /$ÉÈgb³cŸ%ðSá¨(�# ÷¨¹ ¬©ŸÕ‘ú€ÅR9ÑÉ})øõâæ~Ø%p¤Ç·ÍƒWÉÊýÌ`É…g“º‚¹d•yuÄþ“Û'odËÊ�3µðä6<“5ÚEàј\‚�äÖÖh]ŸÀ+»C·Óª­Úª­Úª}˜[šhÓÀªö±Y¦)‹&v=uWÇd ü¥Ÿ€µB³¥#xh� Å·)4 k�¶(qÑX.WékñQØ,+` Ã¾~ôðÚ]ø�¯Áÿðkï}æßO>ÿÍÏ ‹7.$£5gâ•$+ýò&°©0f4’õzyNZ•%z{+…r€8dj-«ИªJ¡çÐz®ú ÙN Õîý{Íç.‘“S1¦`�ŠIôª}éMÌ—¿�ùÏÿÁéùg_;ÿÞîÞûU[µU[µUûð´ë…yim6j3�˜S3Ã2£Õî¸tÚms¸8†lc˜ü ±x(4[m lâÙFjJM]Z#&a¯f baæ]à€\½›$Vçk8Ö`r—PXa‹~ó�Þ{€õùO¸šŽÀæ]Q¹�•C|Os–C Vóx&æ"¿b!%{Âe‚ýp8 ¥ª[º­…£KÔ\ g] Øye¨öoçWµöâM,wôÏ€Š à9Ì$|z?¬Bø*r,Vm!\¹« IDAT=MðZÓ-[u «¶j«¶j«öÝ5§™ËD½RHü�„kjl+ÁM¯+Ë–âïÔN 4ÌÕb<°…X Œ{«¤UܦbîT?”Êòƒ1’õ>¾O>¿ýì{{,?ó˜0WÙ²ž-Õ�u…ý-S˜Öá ±‘PfË+D-ƨ½Z`8nØ+Ô¼¦&WµV °ö±ì6 –¥T Ú0X5¢m»w—1Ëñlàõ Œ©1'¿½Gö�[ð«Ï¬:†U[µU[µU{ûí?ø×áé�À•‹ g<�L�UÝdž‡öqì#Ÿ9uS‹�,öв©V;Â1%ºÀ;.—“åâ +†cý¼{ˆ^è’Cw ºì3Ö"ÍP›&¸IX›Àã¾ûÇojá§>Þj®¾÷1ȲÆ,‚©hþ}¨¢Ég\¡±�£Ù~c,(1øüPª×Ǫo;ÖŒrn2Ú@÷h™Á)5¹:ÝËû™²�–,wsÌ”¨8 Ø×u¦² û˜Á²dš+i­† WR,¯²j«¶j«¶j«ö6ÛöšÔ µ‚+§ÌUÖc¯¢à¼VÉ*ã‘x¹›@ZO˨_cj„¹©ƒ n+À ¦ VH~G¼#a­nMDC0@‘Ác—ßýã÷S‡¿ý—å»&EÏýnky~mO÷íÃ8ÓÏàWþ*|ßGá#Wa}‡À„@†£RýSàˆŠ}ÝèÐÝYt³Î¬äf,0 ¿F6€‹Ô\ÃðR'ï!¤VÞN®"«3$rŸë•´‹è‡n¯`Õ­¼éŒr>5€YÃÛÂC;ïþaüü'\MG`iê8J:šotgi8tSÿŸv¤¥Âé¾ö0Ê4M8¢æÑGÕùO­6 -prº­Èø‰K»!Wï²ôx–äê�5¦dDÍE!„?$ø+R�äÆ-øÃWîßî)oLÞ2-Þ\‰ã·[UÛ]µU[µz‹Frw“×îÈÃóÇ24ò \4P”PŒd1ZœœBJF�sšòrÅÊ)X­éYie¹hˆXU%À( Z™"Hu„£ZŒ�gµ+[BÍ�ioZ€f Tññ«*¨¬3?wæÇ|¸Íò<ŒGRÔ=ou>©°½&(k:Å‘…Á2IÖYHdW-{e›2;f dDæ*yr"£ÓÖþ<ñ\¿ªÄܶšs ‡Ô슚‰×ߤ[À= À15eÃ`Y=d¢»Ê‘0؆ò—(sõ].)Ȉ ¤-eÂxM‹W a�Û€š…"¿1~÷�…®_RCÓ¶„�%0Æ3&ã‚‚ªkÀUeî.Ñ ‹FŸªË1†}jîo¸�Q½Ù„}…ôÂÖø:'ä-¬�4£+¤O�§³š º¬XàÄ5~¯„WoÁ7¿»{÷7Àj¨ÜxhŒÖ0ùjüYµU»_[<<†Gv`},`ââXzâ�-©¶°¾©Õ¼€šÀ/X…5©äJUkRbà Åy[AÁÖd*u4'Êe ¸¬¸±;Rð¥ì ¤r (d kR~Œré³lÞÖ�³héïµ¹ÔAµ#}½† )ö±öi¾¬¬ l�QæÊ$@K‡h£�yY¹ÖBU SÄ>Ô {™¦V𣅌‹”…¦z;O™VÀð¥„}©ß© iª@Ê99Fñu·ð›-„m‹*,cd45s¨cÈr¦ÕÁTqddm¥#i€E)F‘W§‚PòŒ°VH µõ©ï<#µNX†Š’0£j¼•Ž©™+“U©îGØ«´MÝÑå´¢îioÒ! ¬~ùœI²�5bÑi)°KµXLŠwÿ^Ý^[2Àϸ?JÀfÔŸõug)ƒU¨n«õ ZþÆ0oŽ•Va±†P‡¦cD —’G§…�jWÙWÕ6ܹ ¯Ü†¯} ž}îg€‰?=TY¡Z…BËܬڪ­Ú»]�ïŸÀÅ-¸²¦°½c¸0‚õŒ×`§�pÍš.¹•eb!Éc‘ëÔ}Ü‚ Îd ³Ò“Ì"EjàÞϺà,ù?}>"ÍÁ—ÎÜtÒË¥ã6½°‘=ñûº[³�Wd˜Ézßí:Û�ßÝ/Qœ>VÉsÏ`�ºÁÖšdökôuË {}Ý ¬‡ÌîoŠëÊcTÊÐû¬ëüGçµþßþytÍpôØu¦òL€ *_ð”8Ž ì“qÇ�—¼¢ËMDƒuLÔýÌõ7¿Á*àYG„ì—•Áz ap.*ȘÒ¨ê‰×V nÓúc‰³»k,j½ jÀå ׉æ|ÀØ6$8Qµ£ûûRòöaàÁ{ïd v«¨eÃjnè6^TsV¹r\n õ²C)Pm ¸9†IÃju¯Û½$lIz$nß…/½Ï>/àêë_‡Ùì~X^;*�>¥ÇmŠ}º³ãÕ¶j«ö�m·áÆŽLˆÖÖa½–Éd"˜f"Ï-Âæä¹©\ÕÈŠ.il% ”Ç9±Ñî6×á¤'C`)WH”­‘víýÏ �5»Ý¢›tÌ(k�–Iêš…ˆZX®Ù~8蘤bÚ2Dë� °$ÐU÷� ×çmNŽ?VŸÇ0YÜÇ>üñɺñ¯Mþ³Éûé·KÊ4å ÃUC²ŸÑÓÊè;­Õ¥È± �Ãkv^É1†sÀ¡Š¬çDÇo‹�Ù†®{(ûYs‘ÁŠlUAWWeNWýmf´š¦¸Ýe&,�¢Ù{°ò¼÷[MÃÞ�¦-2XqÙÐ÷-Ëš3£�¸RöpŸV¯•70Ù¶÷¤÷0_À¼&3 Á·Å¯åÄkñf§u5ìÏáõ=xö øâ ðǯ½=a®f3Ùîý °Œf }r/´ût—×áû€/ýéj [µU{'ÛS—áÑm¸tYÂ9kÑÚLF ¬éêF™„ï¦#˜fò8žJXb”ÃZ.�##Z¦)`Æâ4]¨Î©°Â\�-dÑ%§l[N vâc(�”¦“N–àFºv¤B2 ‡�™î2 ê³VÂ×8<–Z‡ûE“Çeš4þnñØaÎ)$ ©]×õ ”]Ta`Û¦Åú<Òç¨U²¼úÛ¤I>êÿï{€Áô~C»nÖ¼f—Ø›,aËÌé/Ù)ûÝë %njœžeGI­– %�9�#ìc¸CÉ-7€n2æ°�ãÉÕs\™5­cyVk ‹³£lVô»š°\{ðtXÝÂÅQ²í ʆí'Ë!­/Ô{âÅm3)‡CÖÀÈ`]F´W×uyDY¼݇¢·ï>a±$À6ë9eíDÿ&æ .Ïðš­2 ïKð×þ÷U~~€ešN ¡È¤c�`gsu�VmÕÞév±€+›°³.59§Vf|“uÑѬgÂ:E»€õ±¼VXÂh"º–iëéxsu—Î…¥ #�YVGÚ8Óì—ÎõÉS5ÃW ª¼2µ>¶+'퀽 ¬–Y�~†r5ÀФÌUÐÐŒÑtz£eTŒf( ¡“€Ò0ÀB·´Ìœõ÷uh˜z;m¼ô·�¾–%\[ÝÔ)‚²ìÀt˜Êι~ `\Í4Ôxu�Ï1%‡ö¨Ø%°K`�À¶©]Wª‹»§&¸Š`ÖšδetuXyÂZeçd­N[ýmÐÓ_Řw¿¿è9¶›„i‹ú«I´�άÈfE õfãÎ~fÍõÕdLæ®í¬úïó¬Ô4_A–•%äl­¯Òª­ÚwÓ>v~úÓð1ͨzt.lÃö6×Ä‹©™k§ (kƒ†æ<¶<^Õ1ݱѰ´þ �a8å›Ï}Sè[.B´32`ÊwƬ :éèëN¨fÔO Æ�n“ hke>fšU¶‡Q�$Ö¹þŸ@Å!uXºÍ!à–€‰f»˜�A¸}‚Xùp”V¬ì�“%À*}-Cï-fð¹í­ç:@&ãä�[´]¨4ìK«,ðÌ0Q³ìQ²Kà.�{îiI•XbÓ årB¶FX,Ú7ýð iBxQÔ>:h½peP•n{ÜcÅÞ³fZN2î{Ô m+Ãv‰Vw¶®¿9ø­ñ>HÁ£Óc‡(ŒÏá›ÏÀ» dÇ„ +LðV윓NÏBtc›®ŽÑª­ÚwÕ¾ý&|¾Ô[L³ñŠ\XâqF«I‡­8¤ÛcŽ#ת¡!yß4œQ éÑ>YǵŒµ:Û¬Èæ*‚+O¦‹æ1$ËÒº8GÜ.�’žÔç:l’â-Ú�˜B/5`8ЂÀU¢É:`Õ�~«}­¯÷ = fð,ôýqOû`&ê°=¡¸=JæƒÛÌ·6X2'€+{ÀÊ:áÝáÏØ¾+´®X¥”fNÍ1�Cû s%ìUͶ£½ªcYÁxñbŸ�‘™U;/ÀªTÈó#Ža†¹7ƒ;Çðúk«ƒ´j«vZû·X‡K›’};UÍÔÖ\XƒKSØÙ€­ Ñ5ŽÓDòÓØ«vÀ�å-bùŽhÆ Ñú†sB�Qݤ pÉ'¼ThÀ“Ñ÷£¹lÞ pšï �hzÑÙF?¢8«6 ΟՃ¼ºÓÌ­¢{‰îÚ¯c¸Ü%O2͆Ä�6ôçO`±ºË&`µnDÖòÞB÷bœð® �v³ü0™þ¸M{fˆî$æ*²L'mÞ‹¹ Éÿ¹~®>˜ë¬¶ÜMÐ�n`FÍ‘ŠÙ¤‡Ô2Öp¯¬ïÔš!! bðü�Vªsƒ<á;ÑÂÀY3ïuc–™Î¾¹hŸa; \¥WhbL“Úmô®áÜ®úü·Â`uºïÅ×dá`îÄlÕVmÕNn[kpq.N _“¬¼�Æ#ÂúDõŒâ‘ÔúRÇa(ýcÚ@W´Cè^µ²5 ‹\¸�£î"ߤzàÿ‘B.×¼Xà)ôÿE²~k‘Y•‚ý(ÈŠù‚þmx�2°[ÈEÃ`Y€}¼jvºky`<`- y�ñZ^OŠ ·ƒO 6Rîª<R…¼>8 =œŒ¿!XáT€´ ¸lt'¬a V<_â^©IèBAVô¤?TpY+ñ¼ Ô¸–¹Ê‚ØÌKø“—àÏ…¬—«¡d¨dF´ÔAž<º^Èå3©Íf‘R%•®;NJŽXe]¢l/­o¼”N)2Ë9˜Á¬„½øÊ øçßþ🲟ÿ|áIxúaxâ*l\F,ý¦8Fx툥£wªâ‰^Ö%…–Ú(š �XÖ¶PÔÖj©J]$&åŒßÀp¸Í˜]ê&ëJ,·4í‚(p,’ç©_QÀQéwÛ{Õ‡°j Sj¶0¼©3}h5£„ié‹oOW2pVZºcÉlíUÍëÀ rÕ`Á‘î›?‘ Kÿ7'8]XÖuÇŠ,Ñ�®ÉjjÎøòæ˜rôãÄßq, '.‡yRçy3°­î~9Í 5KaÁ(Ú÷½¥JAµ|yÌúÞqIëÕANpµÔ¼,køõ?‚¿öw»'É-Åc:šÄ¨Ï»Gë‡u À;5Ùä µª"{z¨,é]w�=èèþx¯Vï·Æßx¬û»§¿sƒniŸ³j/Îô³÷tÙ£­CX6×®„»ƒ âI6[ɆÞÀJn“ºZöîþ \½«m ÕP\‚�`·¥N��ˆŸÑ†Ö�e°aåu§+y¤°¦@¥iûÓž¦ÉÍ_)¨šÈ¿“tJ¤À)$lŒÐô�åv´c:Q­8©1 Àª¸ ã oRÝ÷ °ÚðŸY ´KÕaÒY«k€U­va�ÔFr:Ÿ5M*û±úSõEøu‡Ÿ;;ìád¥!š�1TëÑ’×.à ™9�HÖÊH¸d~Zˆ–´I'é¢x¾ ßÌ{Ë.1Z'5sŽwºÏ‰°6 ¶¦ `ø`–Ø®ˆŒ;ŠB·Ä¹�LN“˜¾.dÀÎÁXaFöfðÕ——w-§îý†VPß^seÂèÆßdθö†€q�loÁrbIÀH�=ÿ^0Xað·Ö¿o)ìzâ=Ö=vóž²X��‹÷p8_ áçXÒ™™PfŽpï�ð�7V¦iWà© .]�­‰ÔwËG°=‚©‘µëƹd‡Ewí)�MÔ?ÃÇBK”L-dúÚ$—%¦îO�¥5©‚"#–²ƒ –æÝ±S?ù]ËÉÒÛô=–†fØçb7ì›�EÖÇðR:t^b^½¿ðü“oÀ/ý£ç¥ð?þ<|þðÉÁ^CŸò¦(L‰cNÆ1Žc<3jæš—¨°&T¬XÇ3Áj¶NÙ8Ÿh¥‚§]ejn6,NÅÀ›xv5‹®êPûi6aʘ¶ª}cWP7|[hÞ˵C�èã¸7dÏ5sÎ$Ê4å7bÉŽ8{öˆö”6;iˆI ¬¨t¿÷€[ÀëÀ«^Óãp·™e×Ôä¸Afª>Ž,Mz:¡²‹Å`É•±«›tö¸/ý’,ý�¿"×lºº3è‹Í†Å3V0»†g[÷–Ü�üû‡Â4ÎŽ—`”Ç:Ù?7hÔY(`Ž�ñõ(¢oÏ“ˆÒÉ Ÿî_Ý\Sñ˜äre{=/¦ DÐP{¨jWôüË–w­r�uÁE¼Gb¸:f²n"™¬ErTÆœ^ì9e®Ê漩×ßzïEÖô ™Ô„þÞíÖqqâu ¿sÜ»£Fl]ßK'8±9ÖýÜ^ÕåFr•É>§âv$ÒµjçXªù�à+Âq _yîÄøí¿zí6|ËÂàN�Ö¶¤È§�Ô5â¶4ÕÞäÚËlVËsa¦ -ª]äZìªÀ52ZsjœÈRcuAZSm8[ªz�, gSº­81´Ò,«Bß Ê#ׂ­‰#ä#Ln8¯Ò²�2Ãqˆõ:Ôdxœš,ºÄXQÒÓK=¹2F†ES©^^'X±ŒEhôF‡´aÂ}}~@Í¡®S5!(Ýj½ÐÕ¬„`E`’Á�æµ9ø _ê5�0‘Ù‚¶`‹|·mÊØ´‚àcõ6šõB†åòþŒu²I rM¹‘5eÖ±¬³\Vdt"iÃKé@}ÜŒ53s,%ŽÚÌpæÄ-»zî܃/ÿ>üâ߆g¿u6øÿá�Â�=Ÿy ~ø øè0£%kÙ7ÃD÷'îc|.žH¶ã‡4´Õ¨nê. ÖÛ|f ³’ðõWà+/Áï> ÿô0;¤ì·�RÖþX.“‘fÝʵ·™œ³œnirG?SW®³7ôÚ{xƒŒ7qìë~•iøm^ÁÇŸ‚§€Ï>Ÿº×wàâT¤lä˜êþ#ß|gAXÔ~{s^¸-Çç_<ørGXz –I@S\.ë{[É=VÔ®([u;aÈo(#v˜ô-!xakÕÕ¾xkœÎ°ŒÇ�‹75Þ/z ÖeøÙkðð:ln  Y[ƒãc):{X‰ Ú8[{xt ³ZÅÒ^2¿g ëÛ°ca¼!§|¤·ý¦>Ï,lL”ùñ-hªz3Ð`éË9Ò5Lô šXš‚óAY¤¼Fc°¥ÇͬˆÆ³L—˜JŒ"�‚®|�k™Iæ¹,#ú£"è]kµ(g¼‹û €Z»-Oê-N0¦éÎBÿ®“Zp1ŒÓÿ,®!¯Ÿö=j9‘.Àò§Ôfk‡ŽBÕ¡ Ex­g¥j3Cç˜Í5ØÙ†úüÁ‡DøîkÈÚy³œ«ŒQ‰c¡ªgNÅ�]`_�<ޢɰ«u€ ,ÈS'Õí[ú~_�†l§ÖR"uÓùÉÀe»)ã§T¤a?sZÚ5X ¢튳LÂâÿî�KÇ_Î…yͶ æ5À©_V®iø¹f9eÜ kdLAHÔ²äZMg⇠K'Ë!®3»nœ¾1¦„ÅîÙçïé‡àoüEøìã°=v'Ï–Ž\¦«o º™„žÖßÀФÏvEcÎ×h¡Bþ¬¬4rðð#9`ýðGáoý|üaX˾�R¿.êæÖ’}ÛHömçX³dýå†k_ IDAT>“×ÏNàÁ pu ~ü)ø7¾þ“¿ ¿ñõ3 2Ù¶¦éuÄ¿­û["ã{¼ª"™6¦çê$¶ø¨UmíË\`>‚ÿâ¯Ã]€k^ÆëÀx0¡ ï™Cpu»ßü5ø‘'Ä æ™Wà¯ÿ}XÔ�ÉSzß” 0ÜÖ}Ï“}™œO79 †âã¾'áÏf ñ ®Žðò›ðüÍp:?ÀÊØÇ�3f²U®ï`¿ðÃßÿIò‹ëpmK–­M)J;.´g {.µ»,]+ °Fï.'F@:뉲BcíÜb‘Z y̲ævMÊúiZ¡! R–üï >A[Äò#m¸Ìö8žr’)“v‡ª«õ÷åI”ºHJޤùFUâ…”5\F,¬’a'4a›¬W©+wd*R!¦g9=×�ÀpÉûö„zl®ÜN2íJ}N«»¯aØ gƒÀ:c<Ó¦«^#{ô"÷8 nûy¢SÚÂuê×Å%2=k,×ô;iÿRP¼§ŒÈ]eAî&ŸýzÊÄÝËg–` á±+ðSŸ<`½vWÂdYÖtÉA*½'âo\$`᪞¿‹zN×ÐE@"£s¯wíÝÖ}‘Z‰s\Ë^Õ¶5�Ã�=Ü�ñ]°�b¸«Õ3dÖuF¦x†&ïrB`.ý¿� +†í)áS×lÍ!l7!BßHÚi{[o¯éùÜNö9ÞoåÀõx¯ÙÇVUEéWYÃÝCWÿø«ð `½%+^06¦sç¿1"¬� [akŠÙ(df4.ä¢òA:[‚МÁ@‘ÂzÀerµ� �¬è�Æ£6ôF&z%“ú§k”€›t0°§è�âó¬÷^ÑP¢¤Ø&ŒŒk6¡!cS@f“Kû;cÑݘݶIx§Ð€0ù“€5ß †¤\ZÎ&À*uï6ƒ+õ1ê¦VÛ%pÕCŸ~ I*k £Ñ¾¯$'Pè`>Rïï¬)1ZÀd"ìçôn ¼cĦ¢02ÕLÀ¾íÕ‚Š’žc<‡Ôì+ƒµ§°#òD“DCb)…ïtH<ÒPXœ]&º¤ªé\�8sÌÕ£ÈTS$C‡HvÒ|2›Ÿ»yemØÐ4À¹¹•3£å1FPÝ“_‘�eX³µ¦4ˆ.GÌ$sµSŸèùO-ê`‘ ÔG´éæ{º$ƒó’™¢×‰Þ›çÝ~ï£Â\åýÄ×+Ü2Wë 8¶\]ì…:ǧ�¾¦gšh�B|ÉâT[V㢘<(|òÚÙû÷™Ç¤¶YGødH-%Ò‰�ìG’;ºlõVªÒ,Åáx0§:Ÿœ�¬¾L“ƒ>óØÙû÷Òm™¬ç2#ç> ÉD§e {:¹¼ÇX• (v=ÆX®¿Œ]LsßÍ´¶A×Û-¬%T9l>ë;0ÚW’`YÏ7T/qyâmc@I‰�±Ÿ;‡ðÑ«2Κ® dÁ²}ˆé�‹Ir~R¦/½ÏbÿR“š´Âí=ø/ÿ�0W/Ü„7WÀé­0Xoà“³¾¾Fu妓�sòË[Ø· ßJº ke�0ªa”^&)Säø¥,á;2Ú² F;÷"¸²D3t2#3 ìR)…áõÂÒÿ4ÛÍ:f�Qä;&�¶Wl7t’öÓ×Ú÷bvV¡µMjÁ•Zº¤LB�¡IC÷�ÛöÉÌÕµV´xª^èÏ ,ÎX?ÇÀ† ÀE —ȸŠc“\9”†BC†ë°QÀÇKxéÎ÷æøÂãðs??ò¤tn“ ÚeK^MÆœŠ#<»xÞTíÕk^!çu¢Ó¸ð\ihfªl_dBŠŠ�›õŒ±êY\CÝW�=‚fnû/Ü�,Ôǯ€õ‰[|ÛéZlóýyóZ;��">y¾´bã�M Ü%Ø‚ÀÁmÀb&á�â_Ó``�£¦dŒÃ° fFÎ!¡Ñ³ÜLX»N²À:NUºÈ8Às„UÖ.ÇQk9•1¡vðâ  YÓ)lnÂIX0dk”¹’ÉAôíŠ>J—”ùx Y.÷Hšµu’³¹ëé{R–ç͆�sÜ¢ä%wY$ƒ:Tjో„¿ó ð•áK߆?|IB6—'ðèEøÈexòA™´šcÓóÞ²mro:®$ûuUÙÅÈ`­÷trö„ýó=+”{�}“å–ž÷Ýd¢Pµ1ø,Ã?ñ ü⟗pØW_†çn‰ïUÚþô–èÆ…J6|’çì› u­çç°aB³@nâYïiû Ö–»Íõg›a‰£ÔD–@M#yn 6Ç0ÞÁä9ð0†›,Í~!ånÆ©M’cr…×A¬GrñŸ Ÿý áΡ2x¦“@šÉGÖ9w€u|£«'à¾Ð͵ýKŒýËkwA5Ù«ö6ÖL³Šl€i¨FnìñEÖ”ýhñ²KBZC'£­±v·T÷V–@“¢yæ{ßrú£Iþ÷çXŸ3¶_¬ç’×BÜ"LAQhÞO—M^£©—®ã™«Þ*$i÷écÙqIö§,C È+5í{ŒEd�°ÂÀ’<êjF¦©¾¨f¬û™5ìœ!#T}€]�C¶u=¯"ó˜5…‘¥s¬( ,”èF"è ^ ˜–]¦SýG¡˜^5ZiFÔœ\Y¯º�Y!çë'¯©~0½OÛaÊ^t3ßH®çª§³‘ëµn]²&à&àç2›öµêbªÆ:µR+ý¾¬§ÿH-7¨¿ÊTûbö  o»ZÀ• ’]ö•—†ÁÕOÀÓOÃ'? �?)zËžB-e®F=fg[—­Dµv {ÕXñígp¥Yo3eHŽ1ÌÕö õ[2•Mø‹Ÿƒó³ðÌ«ðŸý]xþ ø¹ÏÁÏ<-†·Ww”auÍ™5Éý™ZhlìßF²}öê$€å“ž¼¯gê‹ßÓºƒóTÓe \¿ ÿÑÏ Kó¥çà¿þ‡ð�^êù›¢Zw4f’àêÔ7-kb­õD[Ã1‚ÁT+–^“GKº«œE“9(2�à,!Ë\ù\’¥Ì3àÑ-–=VÔ4÷Á¨RN™Na—S�­iïä¶áÊ–€N/ZßLc[�¦aÙ(×'÷W*r_ÐͶ\òÏÒN&T5|í•Pzû+ð"– �íIÆ|mŠ·5Œr´ Î'┕tÞFãTŒÝ/-Ú¯¼51‹&Ì&ÀÌkÈ.¢u ^–—¼fÎÁæÄ°š;“õéj›Â ¯·žCN‹ë¡ö·›Æ8Ñ©Ïw8-ïW ½ Àqã€|žlÂTi&˸§«Jõm¥ú Åny;¸B’Ò�eœæ?&LØ®°àˆœ’’@†e¤©í�…n/Èç§#±=ø ¶Ÿþ!¡ç¿¦sàQD…±qS³Gà.w·çƒF+5¦âXÁ¨Ó&oÏÝYm®ÛŽsm”B¸c‚_4¶*8/!!›u4V}Ð0NÂBS–³©R‘¹ ŠcŽqÌÉY�«¸œ©ñ¦&d†à6ÁAv•àî�­ô:ãÉ—œ¶', §Mo(—BK†O‰¥ÆÊ\ß9#±e8.á[¯ÃŸ[>wÓ©€«/|>ýi¸’Cö*˜)†–EÜTöæ*ð0žG€ȸN7ò<à£?­Œû–‚› n¼Ü,ž«À+HæÚm"�3·r-rÂVFøÔ#ð¹�I¦öÏ< ß÷¨$"9dÖÉpäXƉžì�õ{>‚Ô‹|@Çvrmô…휲¡·ë ˜j×6õñÅ$TºÌÈ( PL ÙŒPäð¹'%œÛX/ÜýÀ£—a{MªWølœWTj)#¡YÛÞ'IØ0=w}&®�،տ,‚ޱô³f&æ¨!Ö8kÏoi&õL³Œq S�óQ/T¼H¾óӀђ;æo !‚óòý6#„ Œm"6K­VÂsGdšÕÝuiµ‡Š®Y:Îø ÞdoìÂï|}”Þ>À’,‡!'g-·ÌêÀ<³,2‹Õ0V–ÌoûlGëÐëõ±€$m¼Æ£Å~Õ�·´¬)Õá’Иë3vÎ~<ýs'¿_?y]×ûLhfÞ)`s žÒÏzè�¯~¸xìÎWé½¢ä½ê^1×õ*=‡!9OéºuR—ª5˜¨¨È€52Ž©˜c()¨(õØÛD“¦·¸g9ðA»9ò�p=í$#ZfÔ ƒÕu‘n¯«ºéÍ#èÀ¨ 2ºªw5GVÁ…!ÜÚƒ»Ê\ gŠ¥ŒÕ8àÓTü>Àê²Z¶òé$£ÑŽdF²s½‡ìÁ½.v(:E€e–ªb8+-=Òág”ÊüµÇÒœ–_yù6ü‹o sõÅçà˺|î67…¹úô§á£…µc$ Ý&Ì^h@hªKŠ)ý›À*W§©³D4Qœ Ïšé>ÞkÂ9f „6¬Üú>óxé†0W[jfœEöd¢¼IÔ”í$ Ö&݌Ȃ®§9`¥ûo•þ5¬©îã–þßͼŒ×FŒ—/mˆ}Ðý¢7áùmøí¯ÁÀ_ø|áSPäWuŒðÝÚ�­^Ì’kBƒéŽ”YìÞǹÆ „c‚×ë>Ë”1„¶(·Sp�»k®«>;˜¬nöeèÈ4–’�¬�o¾® í5)dÆ c•kÐÑ4=¿ãäìÎŽ€à=áÍ´_{EÀÕo|e”ÞþbxžÀ”Šíã9»ûsöç5»vöŽÙX³ŒÇ9¶Èɬ%äÞÔ£ g jFºd û"¡¯¼ Z5R¬Œš¼©T»$¬OÙo��jŸçÍç‡)7Àv ×Ú:;ƒ/J5žqoûu�áêbõ°:9ØN Ä.Ï:Ãàó–@~wy;mŠ¿Àéœ1­…tä.«”óò�À?‘ͺț|@ÛàÒv2ÌÆ Ò9OIÅ�}õ¼ŠìÕ5 u°ºè” q8œV!ìf¹ /ðêÈíuÔYE(=|ùyd² Œi÷EÌ1£hã€%¢m,ö¨Ùe¢a“óÆØ4à�”9 ¦óÈì!B}òºaAÓðK¿¤LÐîj}'ÛµñtË„ÊK­Ô¿ô˧Ÿ» ÛðÔ÷À#ÀÖræ‡0<§5!KÖ0ì¨épxT™«‡”uÙN4r¶< xô‹(GÀ;¢kÿ°®�7u½tð�û=J«!Û<>z»;ëJø ÆL€ÉÔrv¬Û½¤ûö°îßu}³ëúáÎìûF Äë¯æS[‹×èû1e‰_83%„a\žxp˜2{ýP–ÿï;âñõãO ƒ› ²‚Þk£Î5�5ç­nBæ'±qé$7Õå†ÚéͪÙîvGm5ŽT¹¤;½ïj¶1l%aØe€eU;eاVýaPñ¹éˆÏË\¬é¸´Iøã—àú•ÌfJ[,+öèý âîÜ÷ZlûwŸ…ç^�£wŽÁªq8²Ò3òžIWެ,qõ„‰-É�%�#ƒ›ÔÔ‹1Õ:TÖRSS©Ó�kPx„ u/Lºµ¨4S045Ðúå>BR(Õhù\:¡´Ó–.°ÊÖ¨ ÛõN~ƶNwý2%¢™¯7}›˜þ®¬ó»†Ø(öÈžzÎ!)z+ò£põCxõ’ÆÇ¨�S[Ï4:¶ nò,¥,èòA.P×bxÛÊÊi=°Œ2•UgæEâ®Ùÿ\¨}2±“V+='¦“±ÚÍÈæÒù-JøÑ'$D’™¥¯ÏZõAÖ&­èu`¥¯Ç’(F½¼Ä™¼nûõ›�j)³‹„z“·V:k6§°"á4ÍŸ2×j®þ䥳ÏÝWà/ÀÕ{0>‚¬VXa—Œ)§ ÐI‹åNÞ&ø8 �¤l�O¦ëɲÖa”BSp¹a��Ë›ð‘+0‹..~o¾ËcÉ–®ƒþþå, ¯y›û–²Y!ÑÞ­ Û¡0kK‰xxçì/}æUÑl�´ä˜‚,cÓ)½Ü¾#n¾öˆ„¬ì‚�½ˆ3Í^4 /ç¶&W÷ûvrcš‰ÍÉK¦˜ãÄñ¿e€C¾KÝòÕ-ø3ŸÉÚifåŒà²¦»Ž’„¡ûm©ÑtáS5�«öv–ãeæŒ^¼ÍúŸ|‡ÛϼÁ­çÞ`ç‹Ïpáù݆.—Ü©5ÂÏŠúÉÇ)Ÿz„Åc—˜_ßbqu‡’uJ‚’¤.)9”…撋بö'-›KS8W4C>ÿU§fµ…2ï~¾lžÇ²Ë. aÊÓ¶‡&íŽÏñýÑÓÊêïwœØÛý®—Rt»á¸Ø,`©>ÜyaUdªò�ÏÖÉk)«´8¡;•ß‘)E^4ƒhÞ0)Eã䎖Î1 $®ÀX|€mF„~1”h¡*g/õ“Ù£æ@õU¥Î% ƒzÈrÇšœàçÆ�MH7Àa%K—yë•P*¸¸¸©cfɇ,j|¶”…‰¾óWTo³ÙcdâÀ]%lӡ΢o“ó&5/¯3f—Es~ç@�¼7„CõÆ�Àn¼•Tr'¬A×áÍÓ€ÑØùSyéüŸ{¾ø­³·ñ}‹éãä؇0ì`¸‰á˜\ýȶT‡ô¨ê’MØ�‹: ŽßAÒwT�¬V Ï¥`7†FS7þ2†›£W ( `쓽Ûr½+c8ððð¸î߃ÊjõýȲw`ßèí_Þcíò^¸¸jú<¹®]θ¸qöõ ÿØ“V`s á5ׄ¼n¾óÜ“*,عkƒ°¯ê¦¸»1# d*«áXÃp�š+˜æžK³O#›5nýйØ&XÍÂtÜB\ä£'W†jòr�îK°5a^K¢ÐHL´ƒo7|L$ÚQ&“}ŒzΨiüçßbÕÞ1€•1£¤¾yÏÞ!ûÇ_ÆþÞ«MÇc邺�ñ¿òÔ?vÄ¢6,Ö3æ—&ÌËšÅ(ŠQ³fŽßæÆÕ/¦nþah´AapÑTax–›Ti§r&UÇ wy{õÏÒ['$uÜ8cýÔ²¡î½Ÿ5!Ó�D̃N+š4ÙÚzp@«e{»4U}Âúáô ¦or£ ²uui“<š$I¢Gë0…UyðýàpÕýcH8Î4K¥ü[OÏ墒ì¨Ë°9qÿ('X©›d^í5S¨öbðw´�âª7v…¹º¸©iêf‰IC„cºÙp; ƒ•èé}^õ˜ýx—À†�Bë×EsŒ�…ƒÿþ·à{®ÂcW$´º½“¡°í>“tö=[ëØÑ{íìk/¾GGs19|ñ¶0W_ü|é;gŸ»O>Ó²™¾ ö‰Ýc:ú¤¾iÈê�h}�\Ô€M“%MÈ;b©¡XÀµ‹Â^atm1�5dv®¯:Ë‚á�Ü¿~H4Õÿ�‡ö ½>6§gÉ·oÃßøUøÞëð©Gà‰áá‹Âîm­Át$¢ù\+tºµÓN-½ö¼f6/ôÞ»w 7þéëÚ·ðÈ�&”˜AÖ8eއÊDUÉë!a“'t-AúWdZeäŸ< ‡ xè‚„�×Õc°°k”é6í¾:/Kì_âýõ•—\}ù…0zçÖ.÷~õËäþâ�ÿŸ½7Ö$;Ë;'3¿í®uoÕ­}é]½HÝ�d´` $`–™�06ØL03{˜˜?Ø"˜�ÃcÿA1X^°Œ±YFVŒ±!$,$�„º[]Zº[Ý]ݵݭîþm™yæ�÷=™'óËï.U÷V}h¾£È¨ªÖ½ß—'ó,ÏyÞ÷}ž\ƒÆ§¬Ë•ýO\¦÷‰ËRñóK?DçÝOÑ{C�>5b$™µ‹K`÷µ;r¹ÿ<ŒT #Rª?,þ}Ð_ÍVüÄ`¨kðg­—E`‡~ZU˜Î¿×at3ÞÖTôÎTü^’q¶ÖMôkð¿¿ù™{?Xjf#˜k³¿Qâ‰èÉù9×y2LP£©f*a–u‘Yß��öˆÎŒã0Y‡¨NžÜn2È,À*ÎWÞ½EBWy @K-|óÏÞÙíüƒï‚o|£Ú»Œ­¹ÀcAfÈó‰Î#ù6÷é–LF ©…07­áªY �œ"W¡?¥ý;£?®ëz?7épûæ³Z>;æË!ì�faç‘ËBÚ¬í}NL,|qQ.îÂÚøÂÏk‡b„ˆÔ™Á0¥Œç)\Ÿ\gô”ä« <|±ÓyBNè{¼âí»^Pž^¤Q˜(ÄN7áÛ~~ föjÓ585#ÀÓ’fѪç {?�vOôÖÖvdÚl ØP¿ag±…ûÂüíta'–CyÁæµÓ!þÍOLæýXz\:ñú*Ä= ûÊÝv[Oï‰Î5¢R=ß[/±®Ìö„K5[öJ¶ÞÏ÷=×öû;ûùÿâ‚„Á�}–𹎹"MscÍ—nÂËK£®Þ¼o»O�¡ÉBž–-„@$!رn{ó¨IÎTŒdSP•èƒÇÆæÕo±æKă¥ïû0Çùã2¹�qÉ8… Í7ùÕpMoÓmV°W>ÀòõšzÞ!K’±-š ¢ s=‚þa¸|>ÿyxñÅ{²ŽOh•W·l5t.²}~ÿ�†:ÊÊŸMв÷ÂR˜À;Þ ~VÝë_ã.0WU@«J2¤1Àb•r±êáè-SÍÂË•ƒ,]UN]9שּׁ+0É„úùrCY,—“7n{ƒ«÷>��‡c’þá<ƒ]¤(N„Õk÷`³#×vWöñIñМ›÷ÈxuUÄp¿²×7ó�>zÿoÐÿا eÒNuØW ­*óŒ�øŸ|Œøí�“a’~‡íäŒ,6Á„afÑî˜�¹–ÓEàA=MŸ&¯kV°W”@–ï× _H¨¥ç¡Ç³öœøi4Mð¾÷Áµt¹z¶·ïíû›¬+ÀÚñž“¡©WÙ‹ÏéA9 êË%±0žÔw蔵;£µ£ö�ÄYÌXƒÑ<¼ÐûŒYíÓEz§¢_¿ Ë·†q…Óz/ äjõ¾$‚ô Ò(½õ Ab1‘ &YÎãq�gU•šŽ½*{V–7ÎÖÇýÎ:«ï=#ÿàÖÃ`�ÅN5Æj¯vjFÀÕÂŒ¤·?ò¯wÿÿý{°®ˆbn ÎÎôŒì׎õ:7/¹€ËÛ’3 }ìCe^!u•ˆÉX(_º OR�H#£Õp‘fX…Ÿ»¢1G˜éì@ì:Ö¦ÊÞx;¶ n†p@»åÙ sß/Ñ�ׇÅ­ü»µ¥D+›¦‹åg|7yl?µBm'‰¼˜~,`ªÝƒ­6¬oÃÒ\½%Þ[// ¸ZÚ¹÷t®)ÌÕÃÇaa LÏ[6ÊÊØÆ»V¡÷S°±"úþhNÈš½þˆw2 ƒ VLQ°/[�V"ÝñówUƒ¶r#+k•õ®ª˜‹ªÅ¥œœÜdP?«®38ãÐÂy¸ÿ¢|Àõëð‰OÜ{€Õp㲚é«y›Z½ôŒî¤ZðN™¬2ÓS¯bxŒzCšáã ^Ú´ËúVw»oجJ+A€C™Çr�φÖ*ž»)}ŽÿŒêºŽ û¼òƯ6P{¬cÂ\ÕB/'m?§ “{±6"Ét «E”ü Â@HƒÏ¿½^‘»±%àDÅd,TZ€ü+¤ÇDìNä‚!7ßÅ/A—YÖŠ~i'†®Ã�ý*üÑǃb”Úüû*üoÿ¾ÀPQ8ÿ ¬ìFî[ÀÎäö­6SãéTô2»ƒe«$g­a±¥ 1ü¼¶:£ÖÎÍÃ…Ó01«kˆ�üÅ :Ü—#` IDAT(°X®Š0ðx+¥Ð=f¬‰I©ÐrJóa¢KZ˜U}ú–HÂ`åéûyân‚µ!tzw~O­:UÔmÙk°ì7x;97ûc\©J‚ ¨×aj NŸ–?ïu ƒJYeÀÞCv§ê™»¿Bf0ä-Ë# ýýíß2¥fÌžs¤Ìô¹›]žS}·çŽ ã7jmv"ϹòÜ©YƒcÀ”~XWÊ=?ÞZõb ]ýÐ7`—6`cû±/aØgÅÿ{“­æÆU˜^ -–o„ÆL4t–¤²Énu`q]ÀÕïNü�Æm´Úý§aîÔZ\Ø[Àªò嚈Q¢jѤ‰¥®y<[˜Þ\[ƒ—^‡ËWà¿Ü­~¾ã"|×ðÄq8=õfQROTÃ7Luf¶Ž½rFÖª¤äVçÎï«îBB] �,D*§Ö È åÄÚƒ$mû |�Üf¤ã±=-êÔ i0%?†²ff”õ»×ŒƒÉv!Ÿ!([âL–žÓÝY†A%ôIïþü0oþMexÐ/r(W�ßK TôÏ·!ò¸3†ndVTO“¤™ÊtÅ3߯2>¥@¹`eš” •ÉžW4¢Œß¨µV½(‡S"ü'8à ð÷óë×SKR„d<�U ÅʪáÅ¢ßû )1tó�>¸2J¹5Æ�ƒ,?_/ú<~øã¶w;¿ šP&À˜TÔBB¥°#¯Ä<ÔÄLC�HKÀÐÃ,nÃ+ðìuøåOŒ^?¿ïiøš‡áá“R¹§ü†˜?ôU¿G˜+«ÌU¢ºEЧ!ìUjÀtÅ~âÚ­Ãad§â_\€ƒBˆ0doï¿ýnö~¸©˜dëTù�]íènˆåð`9‰Ü/¿g„ƒr .äV1!f÷ÍØ�Jˆ0òü�ºbóp{‘ìú¼“)ôC�r¬˜`í>ãVj�¾îAxç£ðô%©¼²ûW†®‡¾·f9=Êîù»b·Zg¦´eü*Æm?maVÙ«4[FÌ�“i�mÀ9Ã’ aÇ`uèÍ"Áµi§kÐ  V÷–¹DŒvIIé“x–åÕÌU„5Y½äptÌŒÙß±ú®çõ 8ý¶^oD*C}3’\§Í¯wÂð5ÓcîàþF±_‡Ù¿q•u`„Û×=?÷7Eá¿U—ê­;Œ$̶ò|7_‰ÀY uúREøài‰ø8‚ÜÆmÏ63¡V' åLÄàTòZXZª3ÔTÓÓ‘† '"GñÚüÞ‹�é„�Hû¶¯‡'.À#§`î8N9J4è¥r°‹EË4´rÐfìU&Ï`{XH‰ÏfWÄçî´YŸW*¶½ Ïmʼnl?_g=éd(œÝuOyÉ[«“DÀÕÆ†¨¹�T‹K|XY£´EU�ýæÎAu5Ô¨€˜rß‚Ûìë½kbjn½ùs£J¦åN¿ÍqÄñ!öW}{磮¦šNËA¡…±¿ŠYÝ!¸¶N¸¼M¸¹AØŒJ»ÎXÒ¨FÚl‘†!IÓ’l÷Iwv°óÇ M°íþ ¸ÚéIzÓÒ&LµòÁ<X㶯Öj�ýnüD ´’]rtL¾$XDIÐöáúæÙ™êV¶3Y@Ç`Rz 0b5x‚˜DGî‡)ý´ÂÒÝ܄ס*6µ•¨l2> \q› +¥*Ï,U»DÌ¬í¶€«­-‘gØÚ�—iw޹ý¨µaž¦ý=;ä³Fé�üå 6XT̹ræí>óaszXާýË÷ ïN{úRÎ\eZùHMûÌA›$ìÌ%†€XDo"H�D µ·°±Å¶;Øë›paNB�©®ºbiwuUrÑýªÎ1À·}µFTÐÝ)ÊÚLˆ2·uˆ´r°‰!èÑO`už_‚¥F¯�ž‘ÊÁ™cÚ›P¼Ä.¦F�žÇ`YÚ1TžAÍ.,¢ä»ÑÁØÅõ;¿·$Í®s´”ÓmšU4:åo§ÞUfÍÍñýæ…8æÊwuȽå¿õIHé+ò ››pí¼ô’°XUôÅl ÎÎÀù9¹Î̪'ØLMHõa­A(&àížx‚]SНÃK7àÚfQø€Œ@RbÒ`ìF¤OIS­�”_ù{”X[ê_+³ï{4À\ÎÍÁÅãp~Ψ•ÉTS*¹Êžq[ ]_“CÏ•u¾ÕÝû‹­ÿ” f`~ˆg®¸Ðgîƒ*gGçlsÜÜÛ!ðÖ›4ßèÇ­Ø.-¨É|C?+¾Šhш'›4Õœ»I’å*º1ꯧm¥¸?&Ž�å-ìvGÖämW¯­ÂFGÂ~Ê`�Û¾ZEÛÞU4©Ç`ÊÂH;£ÙÇX«f )·‰B§””8Ë½Š‡n1¤F€Á«KðÌ˰¼qç÷Ö� ”°eK@Z2®º·Üègw�U�§ó6Ã^iÓÎt¾èAº/¿ Ï='~„››ƒ<[ƒïyÞ÷žl¨†“SFrt¬ðÊÒ%¦�e«žqQI¹=Ʀ)üÙ‹®>~V!‘»›£ž0ÔE8¡¯ Z[O¹käêßÞ¢ÑbÐ–Ä Yà#¶¥ŸµÜÔkE¿§£ �%»þLnö\•ƒuvFÀÕÛ7€F(Lÿ Ã×@t qtk* £+j7°�Z.¶úáÏí`ÙJö¤G˜©ï;¦¯W�¥Þ)ðÀ[Ȼ޽mCµ3@ZJ³þ‘ùcúLf|Y,[xþT<ÿ¤Ð?»FæÜœ€«·>Ç&Åp<0À:ÆZˆJoÐÙÁ6f±­:L5$ià¿|V÷ÐãK-~x0)ÍÇàOáÌÑe$»ciHueù@ã³bëÀªÎ¹ýžMÒÌÃ1ƒ¢‡aÅõÕÖ&™LU®g™"fñ™Cœ.f ˜ÔõÑ’+nèß—°Ñm†ô±¤Í¶UînÁǾ(‡@¿ýÒGd ¬qÛW |3•jËÕú„² èY ²âAØQ�³X½$}ÏD…’s«–cˆÂ ¦!ÿÿo…¹ZÙ‘\¬;m«ÛroaªRƒ¢Ïå*tXÇÛ\»äåþ»1>»{@Ë7îV�¢Ó>|àÂ\µÛRMXnç焹šŸ„f¤ô½�¤fäÓ?#?3Ñ€‹'à¡3ð±/ï °2ŸøÈcöb óo¿› kkQ}¶ «~·þÝ;•ÇV~i–Çx[,ÛÅãÂ\›”ôg”ኌ·Ž5Ë>6)Ÿqñ8<·ÀJRH!WK oÕœëá…äk¥ÝcÞõô“¹©ûµ5ìúŽ„}ž}>z>úEÉã² !Â4ëÏ6ÕU.ÉÀ9 TyAúÀÊg®6•9¹ª×5�×·ðs =@Ú¹²(­Þû8¼ûqxê’äÀÍNÀéi ÑÞ¢fî vs »Ñ–ñg¯À=ð<ìÜhœ áÔ”ävÖB}çI¦º?…øDžÎg€“ÊbåKžïº>ïi]÷BBBrOÈ>Û;Ý"�lH„¡ª�Ö¸ `å'‚½•§ÝOyK»á|[ÎZ ²­Ég@\%a’1X¦TÕs}|eI4µ¢‚–Ö3àéoãÚ&W4<àU6p÷Y«Øc¬ØÚ"Y$)=Ý¿õ~ø™ï‡ÇÎ ÓyLáyäÕ<0«÷ÒTÛj•ó Ö�L2ÍRâ� [>Dm·.ž�þ�çeÑßî9­¾?yNá@ÎŒÏ4Ü+Rf{ÞåXžÂøJÒ¼R¼b Ë JïK·ßœ¥BÿÞõ0üÜ߀NB³.î Îê$I ãÉèNft×6e¥ó�U+,ŒÅ,]#¡Ç³sÂl½ó ð×Þ ?öKdàÜ?C�Á’¿ÀdgÌ, ªÇ ]•òÎ:Þ\Û¦&î“èJjò÷h‘ñ~·Û{—÷sñD‘AdŸî…S³ðàIxûCð­OÃ�ÿ|𙃃«o}¾ñQxÓÙ°©²’rì•»&=€Uóæ‰KµpI#îpšè³õŽMÀb)eáï¼ûK©8ŒÛ¸UNßÛMìÝÚ‚�¬H·P“Áøt�¬£Ú¢š\YJxœ-ûV7úâÑõòwÌþÔ~o·½¼(ùk�º†Ô:X“/ôe+½{WutFO]'õôælùŸáØ—ûqÅ;E/ËZÍd4åß ð{Ç„˜À�Ê8;Ÿ€€¦žîŠó)Fa\¾1'$R3ULâ6†Ô‘�Á†}lXÃÖC5é–�­)1<²Ð†Lk?×ô©«"�Ç6á-l°Ž Y–õYû¬E×!’°•ê†ïƀͰ)M=}»þÍë¿ë Ï:ªþÅ3êÆÖ+$¬éïùýK­0Wœ°:h$€ÛDnÌ„%qc7¶Ò}-KÁP9“ÔxÀÅ@„Ø–Á^:!,Ív'C¤~¿v0Ù;�·�Ï¥5eJŽ#Y…Uóέ'îP´¢ïþ:ð* ‹Êf-ë³ëḛ̀îp’l}·Û»pÕ¬Axî¢Æ\Pùô¬©{Þæ±ïyâàëÔ”€«oxNÍ@(ð×èªS×ù}8<\Pvßùu8¸®ŽÑy5hñð%Ï? ÁvBÌ öK7„<°^˜ðï¼;Xã¶o€UqÙÛ«Îäœp8, aT¬XOǶ°ØŠ“¸Š¨ð: ëõU¸¹Ó°Â [ìËÙŽ.äÆÁøºÍ5ÑÓ˜¿Ðw<Æj—TëÀZ aQã…ÒBl�`Û= N4Š0»2�áÀ˜)úæ%b§åËPΖS–# ”)uÐì2‹ÒÂö¥½Ì°Š1w?’Ï(sa¼>Òí—>ÏèçXúôTDcSWfSŽ’µªêŸ\¡PŒ‚«#àøéKÂ\Ãò>ÍÀºSå¿hv¹Ÿªñ„w¼²�ñä%Qè~ÀJšC”?oðó°Bv€-6Ðn’›Y; _X»y·AÊ–[%Öx _-0Ø~"²w»=uI™+3t®ÎéêJY›q×HîÔ“~?gf…¹:5#aäÀ}CPà-ýêAg†î¯�ŽÕ�ÖçÞòØßVËøüç™9/Ëú”è8D8nûXn)ÉF]a‹P,C‹ˆº:ú³ùòe¡»3º}Œê‚#о†YÈ¡¸ˆ˜],?ŽhK^\Ù‡“³BÇ7„¤Ê­¸Ú½¾fp•H7q3²¨4vX.hEYa`ƒˆí  (À´;¦|ýcP‹²¨`¹Ò´î±�r~€y^XšmFe©ˆÅÄû<¹X�Ÿé‘šXlŠl ›ttC´$4éÓ¥MƒMn²ä±z‘·ÁN{Ïè°�V9÷ÆåM­‘WlÞ à&°ŠaÓg°bT§§»�Ój³Ä$tH°ÔµOKúÎ}vÎmr�Ð: æ*.�Ã%eh••ËÒÃ�‘éȽía ÆØ� Ò�›¦·¶ c)ð7,‡`û¥±äÆ“ûw_Ò$ °_ûvyKž{Í`ã¢\\¸CÙù d‹„[ú.çõLWÌ»¤Äî­èsYÒ¿o�°Lžï)¹W‘ØÞ¥z1¼xãèׯ™|Ǜᛞ”Püý'! @UÓ1 �±óv僄û3Ž"Ixúö3? —¯Â‡Ÿ…~Öû{¬3³ˆ£ì¿Âðý¦u’õfJÙÄye�“‡oŒÞ:zL׈)`CçV¶V5#ItOROÄ;ŒÖ¸Ý9ƒe<·÷ª,ï¼^á>Ú’>ÅR[ÉÈì ¬Žc-oˆìÃÉYù÷±´‚�ÐD_�Ÿûºhû‹œ“`˜ªðÜ]Øl¿œ>$&ÊóeìŽÜÎÏy9Åçäüú'ÇIl¹M§VÚðËù)NŽ¢Í`xÓ?ÝgË›Aï<Ê*„µ²#šZOÝO]€‹Ç ‰5×Hú®²Y~Â슷 5K§JJ ¥KQ‹i' z„ô©“ÒÀÆ ;Š¢ª0¨\B鬲hÇôrÌÊ„·1F%€å¡�,„’WùȰNÊu §D$QLB[ªãMˆ"e±¦2Öhƒ„EÂLñ,)…Òæõ+o©œÌî3†KHž›»®¯Š04ØNO<ÏR ê`™Ô�>Î’®·õwÉóK (Ý0…sÛ,‡=î¬.§¬G^ ¹H^w]ÿ½J^å˜�¬Ô`BeˆCSbÊS¦€i‚l Íyciš¼ Ãg(…ãüP¸KkÞµî1À="bS' '°ö$ÖÞÀÆ}ÚX ¦Z¾ŸzêîÀ2!“Ī‘e ÷嬾‚·•Ñó«”;Þ;³¶)s¯ ¸úä‹RíxÔ훞pÖ1aÎâ»¹Þ aBßÁl‰õ™ð@eìõsÝ{ÞÄ9Kg �É…iìûžÜ`Í´ æ…5ÁWô›f‡n܃-Å+ÚÝrªU—*ÈɆ„M£0?pŽÖ¸í?D8ŒÁŠ ©i^„¤š*7µ0#ØÎ÷q¸íÏt Á€ªÓ�)�jÌÑ0XÝþäËð…×áÄ üÔwÂÙ¿õ›ô5©3ÔàZ¾™”OÊ�R8®Òd�õ0²ØÄ!Ë’ÙTÁZ•Á¨ZÓ8Ý™|cœ¦X¥ã³ eË�–ð6§A� §Yæ/ˆqV[–~7e‡ Ûpýª­Ø{Ïe£ƒ¾âa9We‹£�!l“ôÅ c¸ÞIŠ8‘³êJT1G,»Š´¯õRø&¸¶üÝ®;¥¾ùß?�W” Án¾ÕJ,hhŸ�!R1ƒc©Ì¬”Ç¿Úe_O‚:´Ÿ„ø:L¿HÑ@ÇfóÌ%$D¨«S”jÈ–õØÔ”!¼,¼ÿ¬IÅ<þ·>-ÌÕ³¯Â�~}|ãyvðý”ž“Þûq ·î|÷ ÒÒzSií…ðø¹½ï¯ °èù76¾C¼U‹9bÃü%ÓÌs¶ß0þì%a°jAÑM` °Æmh›¨ÁÂ,œœÓa˜W†‘—½æ“*¢EB�T½]ɽ.›[°´>š}}ÇãR—i`¹‚Ý^ÆØÕtaž$f˜Ví¯&±*×m¨vm��ûŽIåÝ£gáÁSpn^,?fZ’0^¯å§!PñÌTBq"F�húd +"ÑÅÄ×Ö Hõ´™*Õèû›£ñd(üDT“o21ÜÄÚLš½0ŸÛÝæw¢tÍ—N¸~h§*DØó€ÂÅ1—'¶¬yb«$!úJIäN Í¬Ÿ=Uâ¼e¸Wxæô>'*€é~^u•õ�ûü-ò\§3öš²<ËÖ•9ìº÷cÛº±&žŒ–ØÆ& LØÏD-º¤lzèDYMKôÏcëSÅdí·e©ç*°L^÷Šöñº²W[øŽ`Ãü;ýPÓ¤¾ƒ9æu -xcÉÏqrlh£"´¥wì�¥5ŠŠéî�øáº %ÄC^N—Èum¾.·¹Êm °Æm(¸úÆ7Ã{Þ O>H• ‡l¬QÆää –‹È—YÈÉ–$^HšMÎb“õKã-šæà‰Ð÷ƒývÉ185+4svòqzå �)Þ’»Wk!¨c“„±Â(O3«lA@]á”YA–´›ŸØS‘@ �FÛÅ;Né²’Í JLƒÏZ¹PŽ;Ùú–"�Ò²†�Vü¤å²úuO• µÂm‡„]—»Êúa�·ß³ã'~»ïÞ&Ýô€aQÿ*Ô�¬�~*Bª_¸ 7ׄ7":Ù‚o½<,É52™a°»ÚÞ�ÁÏW:htkæ?Ó-oSu¢®{¢¬MDëŠbâô0ÖÊ¿ü±Tëe€U5–ʬ›_}YVQû“ä]Ø–hÒÅ}Les'χËó‹bï~Ê+¥¡ïÚ’Ò eGgž‚«ØB8!…IÞò¸¦‚*mÁÒ*d]zF*k\¿;]X> ãT³ðùÆc®ž®x?3àI}þ|«\pÐU�•$ô¶WëÄÒGë}QdÞqŸbþ]›ÜÍ—i¨Ê¬¬ä9ôkc€5n•maVÀÕ{ß gO@à̼ºš¼in„ñªÅó)"&Ð)bèÃú-x}^¸6šý}ê LMBË_:¬Â'IïÎm ÓÊbɉÙ=þŒÙ{~ì\®%ÓˆÀ$˜0QˆÓÈxBÙlêÞ/†ž<ƒl66¬Šâ|jÁ¬M3œ–èV‘k o©Ë3²Šz>}éQ’B�ä˜Êh¸44lÄ.¨óˆîÖ9=ÍžNyLƒc­Êâ}U%Ý~8ͱb=!;EðU=‘^®r�„›4X6©Ñ¥“mæ©æS8&É–À™9.?ä´öaN7�V 1{€ãÞñØ�%½ç—•1qyW+ev'n`ƒ[ØÄª—çk°þø2|ƒô‰†l(¡¯Ñ”ï5.4·í�â��{/“ V} ëß0=—[ãë9¹œ²›Úg§žŸUFIv€1¤Ô2/7–Né»8­ÿ>á½?Á½¬¤¾Ÿ±äÀ_®Ñå*9Ý•°Ì!°M›Àԉúäb%›Xè¼›41‘€&“U!÷ô9ÆhÏŸrƒT³Ë,5,m=l@²�ÅqÒc%À%Lô:°©¤›åD•�Àâ™CcM QÛˆ´Ä‹±j…u|�®Ôià" ˆîÞEͽ:ŠݲcÁ’>çkÊÞÖ²Ÿµ$¤µ}Ê7Ú¢ÇgU‹ €Vtc½ªßã �6(*¹;¯ —¿èòo+Dl¨G_WIÂ.¶—ŒÖ¸°�œæêì Ñ^ ܤ¥Ô˜RN’)å`9îA—û,»vD}³µòIŠÅºÃ½ÃÛe¯@‚§fsd›+Âøß—ËBØŸVâ׌š¤íô$Û¬a'jbz�®IõMOüòôÓHÔá ÁÖrâíõacG¬ ÎωN�­Ö¾)‡Œç½í Ťתj¯*Àì3ôæ‹5NÀ›Í*ܰÚ÷¤¶ÛÑ{qàxnQË(ØdÙ]NÎEÍ£üï[ ‹UcÁºä'u¸¶&v@/¯ÂÏ}>ôë÷›áâñŒÅªbe|�³iýn˜^`¼l n$O«òävJß³‘±sA–V¨ŠKÒ<©*Œä‹L¨ÏŒT1 »�ê±T®s®*ªh‘Ð ÔÂ�žž3zy¥êK‹ò¥§�C3À¦¤sY•¡c 1–Ð] ? IDATËOu5j-Rf�y¬ý4ÖªCAÜ€v â‹ÐX€ÖMµÚ¡¸: ö× °¶`r†ü ^Œúv¹2ºÍñL‰¡ž ˜7éÏ�<7Ô°ƒe“Á gSñÝ•miKÖ¨é¦ô1üE,;¦0öæ Ÿ¾Àh]ï¯Cѽ"·D ½œ8 ÛZ†ÛäŒÖ¸ m§çáüL6%tÅû0|òz&Ô°4”µš b"ÓÁ ±´%ò}k^^†—¯Àüôèõõû¿.‡ùi7,ÔùØÌzï�«Q#.”ùî ²¦"ø–§à›Þo¼ ßw¬… d™qçO§N „Œnî ©†³<�HýC°MKëØoƒóp|Jó3Nc“k˜pGmv<ˆ’èR¬cwŸX¡Ý_¸ ?ö«ð“ß÷—ˆD8¨}ãÕ)D)ù‚2Xg=Æaª‚ vaJÜðŸ{Cû=é…]NW9Ÿ«Nƒ: ëD™zì-޲˜Úßå'¹Óõ2yNÉ1�Åò«ÃÒæ]%ÁàW®­‘çúÜÔK*C6(&·[ÛÁ&FNçm±LZ\—pûK+r}èYøö§Å.(íB*‡ìTàƒBXÎWŒ¿©lÃIâ5Š9CU¬\ßWîso•ú·DÀ"°­yI=B =l˜”t®,¤Ì° ã碎'7–œúöD㔀S9pVK©ÞšõBÙù»N¨R“ÚT¢ $†ô#Kš¦Ø0€ø»ð¿~œ?u£yŠ@r\CUV…(ügÁ3 ~kkb*[h‡�,@k˜è p½‚Q�½j�U“Iv¤ºº$D$¡!¥/¬VØöì<üÔ÷Àûxæ |òøóW%]>€’ôÈ&tî�îÓ÷tBÿ=M±� (…÷û¸¼:© �ôŽî;ÙÁCý÷¸¾.×± ¹×§°4²Pä¶ŽKw Zó�¾UŽËÕZUæÕUÁ®;Dôe I´¤au{ °Æí€íüq˜kAÍB�äá)"=sDJyçI�afLhr»fžÄHB¶M¡5k«£Õ×(ÕäÐÒXsü"ÞÝZ…ŠPÒú–§Ä«ïÌ1a�Œ¡\¿bÔç,Èv¦ Á"¿a2fÂé_AÑcŽK'àÂ<ôcè©.F€9+§ãW`„�´±zW¨×[·KðükpmUضÀè#± fUÑ´z&¬`4ì_À ð‰9�A7x÷½ŽÙ�êÄ0c¦Œ¿¯Ež]¬ Ä"rõˆ J G³„”ï+.1W[^xP’g- þÖõg 91ØÀJIþz[„fŸyY4ÑÊíÙ+ðµB£‰�;Y8Ǫ_fß �FTWmúšUÍ!r˜¾ÕŽZ-'‹Ü�¡G¤ÀQª]%g°È0EêJéWŸúïu e–ïïvÆ’ÿóî�MTŒ% i'Ô‘ü ±„Ñ � ð·ÿ+XÜ�™ )R©©Êy°Œµ’ 90DÞŽ®†¯bƒ«�F²þ¤ ˜®|yxÌMH¾Aïv‘ù¥p+ç‚Ú \‘�KêA<ƒ�"˜‰à­Á›ï‡o‹Ì÷Ÿü·ð§/—Ú myÞOP,4¨3(Ôë?ó4 ä jâæ«ÙÇ[½¾Ï]MªS3’üO¨Õµa�iu7ö�µ‘X¾mU‡b•cæ`Ø`[Š~®Ý¬q;`»t& }ÎcxC�KHDD’%8ÊäöªAJ==a¯®.‹×á“_‘J–Qj_ÿ5ð¶‡$éüD ¢ oÉŽ•j·Z‰â6MKW7ŒA/BÀVˆ}}Ó\5ê™OŸÑªÌÐ[¬\öW]3¯êjôÔXÆ%†&š„k=+CLLIŘx{©™ÃÊšä\ÔUÏäË06ž;M…µê%By/®ËbûûŸ+Ž™ ù�¨¸¸ú¹2§õ{?pI,Çü4ÉËÔ¢·´ QóÖ°°ôßëø%‘Bæk&°vC¢²!ª}n4KÞ³cš+BSÓ%¶ÌgäÊZPÝRØlƒ�u]¼× ³¤óüRõKZ©»¾ Ï_põñË¢‰Vny^@ü¹y¨5$!:°Ù&Öůp˵·¦+B;ÓT'ø—?Yx»ÌCƒNú¢NH˜ ¡�MÜ“‘÷ã�¥9‚,‡ï’²#Èóøœ¬‡ŸkÅÇ“?®ü*¿z%ƒ—è˜rY�¡Â¬kæ°­öMSps^\„“0?%lx¨Qõ–DÖÓ2hiCÈÜKôp§¹tsy0úc-(êé½ö¨“Ð ¦�¡A¬•Ûyßb]+ŠÖDa–­‘š@=S05ìl€}â¼ýá €5®œ2º_Ùy\ÿ[y^P²‘ vóe[ǤûýÐU­›}”•ÜÜ‚?ü¢üýMgáña¶¥þ“¶�séæårÅ»¦òö%Fz‰¡‡¤]°Q(¿ØK„U¬q;P»0µT�+„šBÞ�c¯­t„ÆÙã¤Vw›ú#èChû8W‹,ª(�‡ÕÃ3%êaßóÆ Ê\ ž¤Ë À·É'¢b˜’~>,4åd š*U‹à¥Uøý¿€wlR¼ºBÕ´é§ÐŽ%yzmGʹo¬‰pÞµUW›=ùß[(×nÀ¶ê/2W‡ÕÊJñEÍ0¥ò›yþ”Í ¥³ü—À¯¢Ì �z”ssRR‚BXÌŒrÅÚ° ÅmS<¬«p ª.WÉ·¹Êï}>ða®VvD­Ü>üyà×á½Oˆ—Ûãça~Zðs)dÙÁ¯b+æjù™Åü¬${N±æ¢ørå*E¬v”ïîã œŽÚÖ&YMš)…îÜ8rWËUå<«ÃO>#TfМˆr«ÂÂ6÷¯ˆ0­3qq þÑoñ&œ�æ÷øÌNÈjDrȱÊêïôa­ ;1¼ç1ù¹Ð×sJ”ÙNt¾%lÓTÓfÅ8Œõ–3HAa­È%u„˜jÀS÷ý¼üùW+1ºÃÒ&ÜØ‹<°U+½Ûçµn%ðŸ.Ãg¯ˆeÎþÌc ù‚}ïsýùà"Ê¢ËÝDçflœ`·8±ƒí¥°Õ…—ÇkÜØNO«®Ò4†×uBu‰èêf–x“;Ò�ÔPÓü«PÏðf} ¾²Ͻ ¿1‚ùWï9÷-½\�Á ”Ó°žg˜UÝ˪j9¥íÔ%´Z Â;‚w=*ƨ�† Èt£ÜBÒªIäa‰ÄËYrõ}Q¡bË—È“¤åÿOBC’¸ÿ$ö�3ðÌ«ð©áϯ æXìÕê$E…„öà8 §‘™óÊ<œÖS­ïTXž~>“eÈ•ËòE?(XsÓª—[ƒ4¬Ky¼Ý�äñOÇ(õL³cjXV i’2©¹"SÞÆ/Ä}_Z5åºZ¡'öYÏ”ñ; T$ôëFÐ9 ‹°ŠÛ¸ü<{u÷‡²Ãï|N.€�ÿ¼ãHL¦/Õ÷˜µ¶·©5Jãзž0)É$ôÕ¨9?åÙØ“ñ—jÎ[˜1¼:j!ú¶ä>ZÊv:öÊϽZ ×ìª0$¸_°îƒSñÿãmÒ²6ˆ9Fjß Ñc'›pnÖºðo>v°›ø§ZO ÛÌi FC¢¬UÂ=&H˜"Q¶1ѵÂ0�¡¡à«lÕ®À[Þ:Ñú�J´D!ö çà;¿^]†×–aµ]y0,"øc&Ú`%æ²UÑ�µß—¼•ÀÖ:¼´.:_ž`Í NY›¢õÀA5…4IHâ˜ty‹t±OúÏ>…}ç[á[�c×Ugìæš<£1À·µ¹˜T·ì†NŒ¤pÒ+^Æû_~6Á»ºÁhöÓ„Š´A^­’¦›¨‚ÛŒ=òu[ª´Q°VÀÕÏþ V­Z¡Æg_r釼tÜ…iÜ‚% ŽÉNWn�¨S¬Îñµ¡z~/ÎÌÀ_‡ø‰=ÿüäoÀŸ¾r°ç…‹dÙgp˜óüa›%WmŽU>h¾ÄàÉXù*“JŽŒ !vL3ïB nMõï9Û# ÐnSÎ?#·‹±Óc€„t¨Ó£N¬G‘”6Ž!Üæ*M¡Ý‡×WáË×þ`ž{ Þò4j.,ŽlÿT_V¦öb]7íÁaBOAkGËY|óížWq•dÀÑbƒ¶—Ç78žÊVTå‚‚ÃV»13Qøœ(0EÆë¼ù…¹œ;~ð/¾oATÀ3D‘(³—zL±¡I¢IùFCÖ¦P™[eà^µVøzl¾w&€Ç.ÁÏþ-øò5øðçà×?^ùÄM‰ù»�wcJ€«ú3nãm?sE-}°&wqðÙÛª„£R›ÎÀg°ÎyãiŠb>ØQ�'_pr’b!DØ"Êù¥` G½LŸƒà+؉@ LÚÎÍk®V ÃŽ® †&1Ó$Ì©ÖÔiN ˜‚˜ÿ|RŠFÒN9}Ñ»VÈEn�*ýÇA�t2Äž¯Á´êd}ü ûbÿ /\1Cþ~Çí£Ï÷=�ë �j‚™á¬˜K™èteî}è/à'þ]þÿÿæ�`?ýtúrê)ƒµ¼9XãvÀÖŒ4¹0¡ìh_Uœ3W^öJŠ }¬B”kýÄÛ�ýÚ"ÇTÄj¢lIéÓ)X©´5Ù½ï=%›hŸŸº$§§À ]Äku~œµÌ| `•=ÕÀò |»j»íýî]%>HšjȽ´Uô£Ì•+뎒¹Æ<ø¾u�`°D$*ƒa< ©@êv5ï0ÀÚ¶°š@šm[ƒ£GU›­ô3óM–cBRš¤ÇÚËX{vÞ›«ðÒsð©?‚^æê…puãàä÷ž•?¿ñ�ð¦ piNÏb�^ZPÅÕ¬²”F^ð1èÕ&}‹²~Z¤qWDoW¶`y ŽÍÀœÊ†<(0È`�Âx*�%?'2z¦&–¼ÕósÿÂãSÞzëî!g®ê$*‡b˜Ž)¸òíh|{ ŸEu‡4(æºü¹¢º}$l\ÝH>Ø#g¥àiH³»\±‘ªºî¨ýáeøñ_ƒw?!9eçæ¥?ͶæŠ}Ln R­»¼)B×n‰xïÏ|Ÿ©$�Ï¿F&~嬈V6å@4Xãv V‹À¦­à�ÍÔz1÷h@3' % ‘ éõ»°¾/¾6š}|èœ9 çÈÓ²%œ‘’ª[œé²¬Ðà&ÝL�Úy¬9í¢ŒÁŠS992‰ýÍßU)Í(kuÉ3ñu~œ²¶ïç/J.·ÂUº û•<óµÇÙR÷~¤ý ëØn“.J´ò1)Tó˜·9�½*ûö5¸rùX®R(·è]%)»NŠ"žªŠÏþ~â;äÔÎbã5Lä—<ôHhdlf°Ë©Ûl v 'DçDZÉtš"Ãðò|øøÀïÃ�wöP¶cø­ÏÊðÓß ÿË· £Q…s¥7?,è kÊ•ùŸ6û=* pclIA/�~Fªë~ü»5T~JוµÌ#³NšÍ W•æÔÚ§JàÁÜ…ñäæªÏ^ms$Ì2IB“vHˆéG iÜeïSÓÿÒé¤$ÙÁ¥‰aŠ˜cÕ—2œ'æ†Kú¬œ¾\ÙK²è‹˜[2¹g:[båwê26ƒ¤¬`k‘TC^\¨G¾Î›o)T÷æ}Õû* WY –°µøÐsrí§��†÷? '¦sË2LõÍ»X+?7Ý‚¹ž*ôÔºl °Æm×…Õ�¨•`3í«òfcr>Ç„²ƒm§£ÙG«VM@QÇ™vÄ$ÄZ�ÓÕœ“<‘·¢ú+°Ø^, S`veXªt~Šº;Åòa7µ}Eq·€&ˆ0^•P¤6#0pbæ6ž•_{3ØŸ;®:Ä�_ÝT¬P’â‹2ãD=„/\ƒÅ 'ÔkͰd'[$Sï{RŠZÙU« l�Õ\«¯`Ó–œ~—Wàõ›ðÜspù2lnþÃyþuXÙ’b…Z˜�,:˜jõoÞWѲ«Š§ä «ØÇ.–†œìƒ¾„^·:ðÌ+ððy Õ zPÆÏí,W¤ÕîÑxªK5|Ófdž&Àò—c¾]ާŸ»U ½ª/k€°ðŽ{À‚¬ZºŠÉ,ûôÙÒòÇŒÏòú ïÀïß�âó4•ÈCZž½åì~U©]˜†sÇ$©þ+‹ðâ ¸º™ƒ¬1À·ÊVJÊ.—PÚˆ8‰†4_šz1lnÃÿt4ûxjN5½Þˆ–°”å÷é‘ÒÆfÞjKt3åíE4jÈÐs ËY'L6(‹q6ô[\ž‰S©¾OÿöEøúGá䌘o‡-±>1›‚1*í�M�=¬ŸbJC;ÚLWʶº¸~þìKðÅ—\}þóÐnþzö5øÄ—áë‘pTC /lj²Äj›ªlÂ~ýØã8+ P¸iwdö\=wE*Wßñ˜æQ/㿆 Õú…¾Z;wq,¹ï”�HhÒ¤K�„™kR 0U¿½mä¼^åæÜÎb”åŽ9�ɘnÇ×JàÊ”ØÒ¦w¹>8Ö+ôº 1FJ1Ì$©íA-ÆžŸ÷è çž‚Iæ:M1­ªš°JÆÄ)ÿ¯BV•ÝÅ–Þ…ÖOD\Ù�,?thÔb( $²Óª‰ùõtSÖ‰$anwp]ÚÎ¥TÆkÜ*[`†n¬ƒ^|¦"”ˆpžóÉ–z¹ òoIm°¤*P×W=™=ÝÕ]BV·`n²òÙå6ÅEÛ¯xÛOÅ”ÿY“z?ƒŸeèDÅÏiÖn×rÂÌÉ»Çä$yþPT`JÏÕèaâ+·àg?$‰­��•ïóóbz>;¡B­š¿hÁ±z¦�ݱ;UÄ�è鸧ºG«;på\¾Ÿy ¾tÖÖ…¹j·å4}Øí…%øG¿O^€'ÎçáÜœ€­©–lõHl_œSÖ¿2ý`K¹(©\�>lvÄàåEa®>õ¢hÍ43£p?¯³ê}UÛ¿Ü»qTuo®rZ íKÇŸÆmìª^& SæL·`¬ª¢Uþ‹„M0(Çákí‰B½®j®ã§f¼°WTRóumL²µ±Å ‚»?„Šá/"PTL¿‹ V/‘A/–¡1*™aT5#ÉÉrÀj²‘RHSa†A´êžyu °Æm¯•%/í–ye9Xe+¯¨ryJþFÁî €÷ºÍ6¡æ§°ºåh›„T „­VàĬê)k�\}»£,ÅHx°ŸŠ¥É#g²U¥¬|<Z $×)óM†�«r¥Ž²w–¢<@`-ØZtGkVÑ;n0)¹Îh„ Ë`¶UÉ®¥¶²ðâª\|î«o>'¾¸(Ÿ¹ûßߪIØ) 1Ñš¾#[-þûj0!BØ]¸†!ÒƒXŠ‘JÔZx{ë­çõçë‚�RÖê<’³y‚seUÞn÷äó-O eÿj«’nW3ªJͼ¾ŸÏ 'Øb®…3g„Š{®ÖŽÎ 5·F(ñØ)»k©¿a4ØÐòxÚõÞÂàö¿¤”ƒUU¥[­ë¶÷Çû–\uÊ’¹-PÞ¯Dò�¦êVU$LL¦³µ­@ÉÙä”6ëh\e£;Š}”+""s6ÈÁU›m©¼¹W–áúÖწ؊=˜KŸ˜™æú䌀®é¦«¨Ä^ƒj¡0\ǧåO¬qÛëDzàÀ•‹�f‘ø$†®Ý>ÚDµÒ6ÜÖ”_èÓÁê"�ó¶ñ«]©Dë'®^¸ò%øÉ|ú„äÕm~5Ï~�‡�ÿ½8±Ò9œÙn –%†‰Øw¾e•™¢rnÂ:þ&%Wª›H¾©ßµÄžÿ¿·È•lx!çɨ¢»?vªBL£ÖCÊ"Ë^:·1·÷%påÂÿ®²rŽjù³�ûvLVCß‚oÈ.ªð)“ˆSEÏ?<‹mÖ$GIMÒS=l®+J”�ê*HZA˜ùãúÙ-Ý; "ÚÄlËnWMÁÀ†å¶z]zÛ éú\:-zn“ \–·¡wÈûJj¥È$Txv?+öbS­œ±¶v�üÌT³˜‚1Xã6` ž2«,Sb°ôO›Bm„VCâ~'€�Öç..+ª¨tI°ÝþßÏ sõ'_‚O¼Xé>_f›³ênXõ\|ý>|ñ„¿<$�ýË|ó‰×—vÝÕ?›dÉÿª€ÿÕƒvg@•sDZÌè×r[�š…rxœieN¾á÷ÓÒ1—ÛU×}#!Ê*Ÿc M”ùr®k’¼ ºý„¸—’ÞÚÀþÀ?‡ÿóo)h™€SÇ uz½Ãm›}Ø^…×nA?Ö�`C€Sè©ì‚; ]�J6ÔB¯ °ÆmËg*„) 3¬‘2X!‘nå™hl�pVkBÁF@Qµ(¯tqJÈ[ä^Í+4Ñ÷¿ùÅ]×XÇ4 ³r¹�Ue½S6Z–Ï×�ìEÙûPDé¾ü{+_9È‘þjoÖ=ù-�\ ª–„Cí{F©åcÈæþŠäš`CAüm€«²¤K9ì;–4P úáÂeU÷ 7á䬜›É+åÏ8sºpêðËXÍÊ B§.¬è”åÅ�"a©oXOºl/®Óû‹WI¾ëò$÷›ëÂÕ£¼àd½WꜲKÍ&´Êo²!À¬¦('N Óƒæ­¶˜ØwKÒ ©v,M‡>¬qÛÌ`E%Ëd A Z ŒpV?€´ï±WáÀ=¨Äm=ËäÖ8û<ÅËã8,ÌS�Ãb=à{x_f‡™{½9Ú]@–et7ï¯êÖ÷]ïÜœ‹\¡Ë ˆ²Dün�v;t<éú—nèÝ['†|¾1ðÅ«R¸SCܲ,­Ø µj'%ÅPN𷉫=t…8&K®ßÀ°…¡�º›=ú_¸^W ëÎ+¶Y“ŠWw_µ@µë"Tó“"zzVÂ{§g%/jº%@±Ó×*×%øÒ5øÂUxåVIÿ ©Ší'Zä1UXÑv,¯4VÁY?‘߬q»}Ëx9X††ˆTÉã�Le¨�$’�j›®iIu@I 2ƒ\Ek‰m"/G!ÎKñ÷± UÃÖ£é‘}¾&ÈM~å¿ù ®wscô½ãʥ୬”2ðëê¿ìjyëö”ÅÚЭ8Ò«Iª†×1±ú’]‰wdãŒ%[KyÁKJŸ€¾&{û&ÚÄÉ¡~¿¯k—âÚQ<ˆØ­ä½þó³ðÎG%á;R“‹Ín‘[vµ­À r›*÷I~dÀ­í�.Û×6èýãÿHü/?R|–ŽUr,Uæ’µ@ªúê5 Ë5t=w l²)Éê'¦å¾Õ–vî; §fås®¯‹ò»ß:}ÉÅê'ÐHEš%€¶b�( ÛêÈïŽÖ¸ÝΉ'g°Lvª�3Anð%2 F–œ‹¥²©ÀgØÊÅ5÷[‹N¯ûÙ mÅ¢yØlʾ{8ß³%ç{Í\Uy¦c¢ w:XGÞ¶;²DoÀò 5,³ê÷ÙÐp›-Ôó–ǰ¹‹€}74ëiiŽ)“Ñ‹m.W…¹ownÙ]¦ø‹¿õ)ùûûŸ„GÏÁÅã0ÝÄš\vÕéÃw™pùc9Àrî�"Îܱ)ÝåMúˤÿò#{÷Ë1Y†Üu! 2[²ì TÇ* rPÖ¬ËïL¨†HøñÏ^÷ÝéŠÏàNW~Ç}oæëûN\ù¿3Xã6€ fkpvFÌJÍ °’x}äUF´H©Ó$"Ö,�߆•\ëŽfßòÌ:×¼4c±ü…5öFE[*¢£Âz’e¦[wÕ]]¾Ap•ÝN·Í5•sÆœ‰ë6U9c·‰°J¿â¾Ï=›M½œB´«ˆ¼Ûá�´Ä¬ù¥à›øeàÞóNÒñü?ê¶¾ ©²ñeˆD£Üje™c‹Û¶±Âl ¹„¡·WÝÍãZZbhݼrs7×™KT®ÅJNg»w(ßí瀺çáÒ-ÊÎÆõ(²Ï¹Ã�)2ei*ºNø˜\ŸýßáÉ‹` 6ʵ±œ®tu5±3§2¤½v³Gzm…äù+¤ýßUnIv7 Õª3âÕ IDAT‹hh‚yŸüJñyüƒï†sóØÀ[Y¥NÏÂý R%¸XXÛ]±¿9ÜcÌBrÖ[x\mw%ôøÚŠü} °Æ­Ðfkð=OÃûƒÇÎ(³38à,TÓØdKƒNÏ´?º‰.VÃ{q®Ü–ëôO¬aédX6Ì>˱)zZ·},ÃCC?ÿ¶ð„ºXÇ»|ßÝd¯†1W»>� qØq;Ú¶º%²-Ö—�Gô}E•¾t»�_s—ÆR•WžÏ„æ÷esËkk$�ú�¾?Ïc¯g²?f7Â@k^Q¹]~?õ› H$éûÓæœO* ¬Û‡Õ[Ø^Áþæg°¬ìu¦Ë®I*éo8-!BÇ^E<­øó·¶‹ÕN¡½I"üÉY˜j ~ÏN,Þ‚Îþfa&¯(ÌFmÎ\-mˆDÏWåwÇkÜ í쌀«·? ‰‚¡Ó�T§"­”¬È«"ìkaC_"ë×Öàõ øòÕÑìï;ÎÃt¥Ä|¶Ý2PÅkdlPÎ`�5¡˜ÚA‹¦¡î³v0l 4¹MQÛÆ/¥Þ‹µJ³“¿05ëäÞ^·”¹ÙñîYVÐôöV}Š9!=ýl÷�΋°Ub±Žšuð7Ÿ¹ÚÔ{[Ã%ÔÂ!]B͛ђ…N<ÿ�º-nH¢{#„ðŸ`ãÿ}·¾·HË÷a“˜[„¬(êWÌùFÆG ²o^mzch]ÿÝöØ«Ü轆�S1Õ>ð .`Ü÷oéÜZÖ¹UöøtÐ`X²-1Ü}]ár™ŸÝMèhÒzâ �m]<úÊí÷Ÿ…w?.$ °Ö`ƒ‰òç§t¥·ª%°Ò†ÿî˜~*;´—è+Á•³fŠ Ážœ�7œÐc ü‡+?‡ûNa=‹¹ð(¼ô¼à{ãYàL7%tXn½TŒ›Aìo.—dù©¦€,Ès®V6‹fϽq’û¸•Ûù9a®æ'…v5î,&B‘ÁyÀ ‹Ø§ùTîYH’ÑMrc¡zmB9û`ðeÕƒ‰nò3Ú·8ÝeÁ ³œÿ4Ú%¡ë6ÿtº×ÉÔîrÊí–.ùÜ@O¥©,\·òt¡�r_ªX¹£Ü‹Ï"Éî«§E ù3޼{‹äýo¶Çóÿ¨Ûõu9é·"1ˆËN–ì^ ]%t‡Ž§»É„ÆÃi½aLR¢ IœÀµÕ;>ÀXŠ¡¼Ý+—$0ƒº2·³¨Øvùü$àâ÷}XUþYwàÄg*ü)¡¼¿¶±} WVÆóÿn¬/\ÓÜùIh5 hz9XÖ“E åÝ]X¬£K>{5¬(%.Œí@ÀU7–ª´/^»�ù•Ìñ<ñ¿X´â'؇z°1Cb~YÙP>/Ñ>ÅÄĤÄXÚ“°ýX<ú ,xê<¼é¢T.ÌÀúN5[äÚ»�w<"ÅG“ÊL5kù»Ý¡Ño|RB{•ÙABxÝŽx ö”µj"£q Iž>çPÀSj´õ“£÷c€5nÂ`�€zLæY ïP@Um:ÚÂÐÄÐ ¥F��>ÌÒ¼º$n~v4ûúo�K'a®�ºw>U]iÓ¡«á¦,ïÂeŒow¿£Ãqƒ%Ä`H é*7% Ÿ[“ìÄêr‡Ž!yY-ŠNôÖ;ݺŸ]×ö ðªžJ_×ê-R¶²ª9—ÆÀVçàÏÌÓö±„$Xe°Ò‚í†o6]óNÑ�Kw£�ÎreVÕßìuÄãì†UÝPºt‰™ÄÆØð¦È2uxiq<ÿ�º]Û€AþþØxx¢†Ž'KL¤Œ�È»r61î¿¥Þ¼8,ÏKÔĺ¨ã芎©HNÔy%ªMR 3ß\‡�^–µïvæWšB ÷"§€5�ÕîW\Óº4Kk…Ï^ùÌî*ð²öëue°n*S×Á({µŒ�ëŒãÛ yÎÔ\=~N@Q=‚Íüà/_ý²\®ýêÿ ¨Û‡ëkò9'f4ÊÂÿø/0?ÿ½01�¹0‡™�ÅÔRL¢+e_Fb7:0·%a½š‚«~,÷Ôéݸ¬qàÌ<„uµŽ™¥*÷*ßH�grê�:¦#–ÅbT�ž“H‹•Òñ ÉX+ëÕåÕ6F¯¤¤ECÀZ…Þ†sFB Z? 1]ú$™êñ6¹ Ϲ8_ä-¬a TÄ¥“¨K„ݤ(ÍÐ/Ÿ´eÕ–o#$Ö�uñu3r9e!= ª¶K'ý®·øö‡Ád•OèeQX¹L!9%”÷ìÀUlec|ei<ÿ�º­÷á·?ŸüФ#üÆ�ª/Kè1�¶â™£¾æ‡åÝ)så3¡eöh€Á²:7þñï sõ…«ðÊÚm̯>˜ ,}/üW÷ž‡Õµ"ÊæüIBµÞZaJ€±ãõa�<ô¹EÂvC÷ x›ªµÌí0¼s“Â\ÍNˆæT`$mb—wP~,mJÞÕõ[ðåkÂ\5T–Á½ðëð@ªk� ÍØ;Ž«¡¾þü9ìtSÀ^/–ƒæâºXçŒÖ¸i;> A¦‡á� LÕ©ÑPO)¹"ê"B�ÿ[Œí Øxe >yþüÅÑëçþUxË9¸xLû\W¯÷”””D>{X/Y<Ö0“Û¨;º LË"´X± ^]ƒG/‚éaÍYRZºxnbi+èé‘bé)ÐZNóäylùYb.,¸¥ æ ’G±HªŽôròÖ&`‘¨úr?�—oƒ±Ùî** {m¤ ;$$Á×ÅOua?^ÑŸÛe²ªB8Û“wMOæ¯)óp]Ÿë6Ð'!¥‡µ�,öݾ°WÇ!Â#oXëÃÚ \^‘ . <0Ò%È!òÀݸ?®` Ež—u'cÉŸWn,mé8z]™á+:–\– ç[�Ó?ýð�=Ÿ­Ž„ÑT]Bz]RÍtfó>PºIÈ1ÓšÛ(­~XÐyÿ¹ü«›:_62F®IŸ.)ÓØðmòì'"sp;ëØ¤\5ýÐ/WÚû …]7Ö„qZÜ�ܽf-ÿ¬ø;26~þS˜ïï`þê%xà4f¡'� ;Ú´2Ï]0ÖŠáZÄÿÇÞ»Y’Ýõ�Ÿs2ï«êÖ³«ß�陞Ñhž�è’@`;Øapƒ×ba7bÃìzmX°½^ïše—X³ìB@ØÄ¬À°Â’è óžé™iÍL¿»º»ºÞ÷•™gÿøýNæÉ¼·ª»§»§KÑ÷Lܨ[™yóœüþ¾çûû~ÙèÃâ&œí@{/ì«ÃÚšŽf7QÚ2Xã!”î¤t÷Px‚í óm…š/eÜy㵄²ÈŽVb Ú}â´vŽ”¹J´ŠMö* ‚]»8ÖqnÎ%0ÀÙ Ðóçà[×ܬ%œy�ºIª6}�•ØÐ…®<,<µ? `�²eX!S³OG—”†Ôw¦©€«, ôôë×Ù–7õ"‰ÊÈueiI;³©U±Æn(+çÁy¶üfìFédº•*ÝWø„íôÂvA7ïšçO½¹-�ñ¸±±ÙÏiLáŒ#2’RWjgÄç#Ûb^²0J§øfYPHüïß Ô* ëÁrÆû&8·syŽî–-¹«çÙ´ˆŽ=ÿ¦î$øíÄ.ŶüVkÅB»’4ßæ(-óC¯Ì �Õ.¼º¯_zÏ“–0W¦šßwmŸ ï[Eà>HåÚÌNê7¸RŒ³MèmÂF",Õjvers`!rP·¸�4 ½â)Øká#†û/À«'à…à¹çàÕWoȬñ ?%PUÃÑ"¥¥ÊV>‘ã@è^“àƒn*]ß8ðÕ�wŽxìn¸w�t¡L·ó:Ø‘‘’1¶):¤ô”ZÅ—­J�eÐíŠJu|õuø>+�£µì œyˆLß¹—/‚1Ò¼[h ñÿñGn†ú«Ñ€Âå ¢‡Æ&U®w~þ4|å•ë¿vVÔµ£‡C»Œ„ $$Ã/ì )kzÍvQ ‡Nïe­ÍV•mø ¬>8|e~…B&ÚÃ" K$ljSA¸¨�[ëÂ+\}æ)ÑwŒÇ[;–7áˆS›¤†ŠÜk8#Ù%¶öë¿Í"B†‰Ê½Tu77[ÜKU‚�‹z]AôJ^§´¤÷Û&�¥Š£ìÜýfÇÙ%xç]·p¬±ni£…Ÿt[ú¹tà SÄL’h&,%9\+¼÷Õ©,òíÁní€túØ¡î@¶ {>ùÜ«˜÷Þ�9×ì¯`>ý$fI›UÞ Y†;² 7Ó†ZŒ›˜•g“íÃäÛaá=`k"g94€{Öážc°¿î>œ���1À�›8ê¾ö‰JxDت”HåÚåE, ¾ËéS2ݹÙn®&õQ¤`ÒW)>ø×’ᔵJôj®ÔÆÜ-[ƒI «›pzÀzî,|e>ð 욇f ñ83¯ÕzQ1Û ­ïÅõ! ƒRû*\}H¦ÕµU@XÑSƒ;þäya®¾ò <ñÆõ_»S—å|#+o,þŽÄg‹DĤ¬ëñ¯P¶m0ÁÚã‚BøPÜ. n0d.SÄõìUBW#<|8·su¸t~ú7å¡vnÖúãùÿV� Ë�†Ø ù5…žn^g¸¦ §­÷S½Âø†÷ÒV2[ùÇõ+÷ÒZP¬³M7£ïYZ¿ñëñúEa�"+oÊb¡à*!¢›Ï£«VÂG—˜ Ì€•–Îm£Âì‚c—èE{iþõï sur .½‰¦˜ZTdô?ø>xðØ=!¤QÚ“0ÙÄýÛÏ—ÁÕGÂmôå9ÒíËÏ÷ñ›ªGR°îjJ×{ÇÀå)ä/váâ&nn·»�›ž„zרÃso঎ÁžG`r¶ÍšMhèÎ͹sðå/�ÖxÜäKëª÷†óÝ;â{iö`È`¬vÈådЃå>¼ð��yŽÿýpÿA¸{vÍêY5œöø ´;®£ÛwÃmÙmpÑtúò€>7¢�ùÊ ¼ø*¾âIéΔ¦AÍîòï›Ðð‰Ïz”ëúc•,Ë dÂ)Í? !R™€ Ò\CÜ…ä×nìÚ�8/‹]-‚h—40qÁÂÉñqX2öR8Q/sÎõÞ;«Æ°Cuèó>ûAE¾¼w¨-Y.“° tÔ×'\RÓÑìç_ÏùÛ9N\€?(€"ëAÔÐÎZèç÷{¦¬�¥¯À§‡h÷(;:SY—Â9cGÜOIå^ò@jÔ½´¨¿wß8’o¦™tMßðõX”mÓZ Ñ<.ÙÀÄN›cê h�ÑǰI�e|·nJƒ$ߌr€•åM}-¼úÁ+Í×41y%gbËpü<|òMv€û�e‡h³LÀÌ•,_ÂØ9˜ÚP3Ù‚ÇÃ�Oàþò5øÌ_Á÷¾ ·ÒÑf)ÙGVÀÚzWtXö4|ûB ˜Ø\�¿<k1î÷�Áý�‡àá{p|žx7uìyÚ êÅ¥ËjP4À�pìLOÃùóc€57`Ù!þ Ø*L‰ˆsÿ+«°ªW¶¨›\+;T•fºïSµãvj@†%e ¹ƒƒJö Ïò3RM]X…gO�ÞbZ[“=}O;ßµõâoà’‰œªVØY¥ŠE¼ò€0$j1Èb.‘ªåC®5²-\Ïœ¼ñk÷âÙ&¬×´“§‡Kº€DÚU˜æ­Ã:…éhUK2R ýUؼQ.õa÷dƒã#?ÖI´‹2a  ±ŒU²Ä€="×ãøéñ|¿Ý㙓"'˜“^çzªÇn&¥Øâ²¤¬ 7!�ŠòÙæ…n ØÃƈ*:ú^*:KI NÁUæ¤Èzú�¿/Ÿ…³WD·Ô¬A4©Íuˆ'pLèÐÃQWøå>} 1±v ïk‡$_/ÂÎb‰Ãñžp�Fó©7y>1,´aaJÖˆµ®dÆÀ¾&Äup8+æ�^;Ó€÷ÀÇ]Z“û"Ë Fo¢!ϧN¿Ò^öhG�M Ð}~½³¸g[pô,îð~ø³ã¸ý s5½j í”÷�;å9ëuh·aß>ùzÓž«ã©>¾òÀè²S0Xu}@† V½T!ƺqfdåZ럾¸3Ïñî9±£˜�S.%R`%µ^ª5t§ kC,yP;ž™ÓÄgOÃg_€ #¶:LzÚùá{áC“0ŸB¼ŒsdYTV¿PÊË*ÓV|o¦m–‹óS`E|SM†£)ä™%øÜó7`}áaöÎÈ¢Ww¹k‘@»=²`{Ç;aŸEº#ý•Ÿe8‡1|(†Q<½[8þ�x%x…Û„ò9vIy–̽g3H7Åìð/_Ï÷Û=ž8õ¼ónD×"ˆ ™_µ$(*<(ð)Ò='÷Ó,…«MÑPÑQœŒ2Û\­€«%Ê™ƒdyæ+sD\ª ö+çá‹Çoüz?'óô£À�9 nA” øLßG÷Pž&a…=z”îm~¶¨ª4QàÙUÃᎠ#j¸¤)]ÔÙÊÛèIúÆW_ysÏ�…¶h[wO ;µ²)ÀȘaÇ÷]BE:ÿ°ùáÃlC´[èÕ¬ÓFÊ2Yà7¾ ¤O¼ˆ{ô.8¸­æ§�+ò~çNã~í4…õFÏ1ÊŽRδ+Îå~<åìA—;N‹{»�ÿîw…¹º°ë#»,“n”3gdO~Þ7|è^x`š…Ým©RMqC=ŠÕSTuÈý¹¼6"£®W€YŠÿÜe8uQX‚Ï=Ÿ~îÆ¯ÝkKð øuxà üÀàGå±t=‘³Iîú5MŒ¯´ë#VèG´±ÅCÑ? ½¶¤Èià’‹`–!éKköËà™×Æóý¶3XgàŸþ6¼ûý’ÑaWéuá¯d2:|ñõ«ÿ¾,±äƆìé¿p~Cÿß/þ üÄw@K&³ Z�“�Ø`i&y­ê¥ M3XëÁÿúGð+rõñ¾ÝðèaxèÛ'•óü¤zÎÔeQZ˜PélþË‚ÃÑÇZ’B†`�îô»¤¬Õ´2ÓÖa+€je|ÇäZåk¨—+=í_Ç ¡Ó“vïWáÒÆx¾ßî‘8xò´¼þãœSƶ”£'¢ò$·"�­áˆËzïL¯ê½TMA´[VÖs�,V>ýÀ»µgè`öÍÀ÷¾[^0 –Ö¥k·;�í®ÅUøÆ)x¾vž>3Ÿ9xcE^Ÿ~I¶ªþáøø=p÷^aù&"ˆ>ƒKîR‰�Ë ³ÍÂ^Z/ :(ç’d’3øo>ÿÏ_ÞØçY³b¥ÐV#Ï(*"Ó~ó‹¥nÎQ…WuÒ§ÒaڪÞ9ïXmu0ð7ß ³±åL —õáÔÀÉð³ï•5º>³»DݦÊ °Æ£@òF—¡X¡“b°¶Ž§Ðe,ÙÁ+í+Õ¡ Èia¦q{• åé�^QßÄxö¤fsMåú7çLN¬92熖#GI]�Ò".Lš?³$zŽ«�ûvÃÏ||àm°«-Ú�ÈL¦|.þœ�«–ç|†cšw@…wŠ0¢6à=³üÁYÞ"”z<Œ ³ ¢,w×îiƒèwå¢\Úæêò:¼rž>Wºãù¾ÓÆÓoÀG‚ÉX#Ó4ö÷IBRº#-@RåH‹­Äe±»­ÜO…Ç–ÕûÈä }S;õzªÆLB €øùà·—F�ÝÓå‚$sð¡·KjÀSoÀ?ùmøú©í¯GUÃyh¯tÞ5ØpÉ|Þd"¥Ÿ±+Hb„µ²™æÅê6Üë—nNTT=‚I®tñ¯€ªjŸÁ¥µÂGqnR®á”°a^Çe€VS‹òá¦:›0=…{`?|Dצ̉ ½ÕVÑœ+¯kùÁ¸â•eÐï‹·á`�ÇMg°ò?&ªÁr¹k‚8÷Áò‹W¤A9¨ºL¦lçžãä4Ô&(÷‰_½c½Õᆢ1|œÎMõºT³ï9VPêÖà²àcV¯,K¸.˜žlUœ„jov\}öÙkX�pµV0g0±7£�a±`¢|©–ƒ{’€Ióf­1ÐÄ‘�²A†Ñ8£æ�†eýŽj·¤W[uz6Ë?$‹®(W< p‘Á™ Y(W;ðâxå‚€«¿8µs›0îäñg/Á÷¼ Žíö"28gp¦§¥ž š?ztiä�¤�TÕ‚Ùíï§ΗA»¿'ý«�5¦IóYgòԖĆt¨ìòv.‰”‚³‘°s�Ý%sþj«ªá¼ÿ<>2h%�SF-Óæ€,8 oÔÐPÆY»g“T¢^¢Q—àÓÏÂk7¡ 2¶º†Ù EÒÀÀ�~þè5X<9ºD½o/î²êX[u8¶GذzMþÞªËe-ü�û ]¦ìÂ|ée\»![‹Ý�tbnö ï ½OL¥³¬ÐZ…F¥t9íXì÷auU®ý`�ÇÍg°†1Wä;¬Á ‘™~wâvî9:µ.(y7äw$¥ªcpaââÍ8ÅçÎÁÏý.¼ó¨„¢Û+âñé Ù6¬Å…@4ß3ËLu©>—;B­Ÿ¾,[/Ÿ•×é•«ÿþ‡ sU‹Fæ„™Êk+Ö²ÈoÔ‡‰jÃüW�©rÑÁåóÛ?5Ê"Ýj[}øI%‚çâaèJ.ÔÎ �H'/ÁËgà+/Á×_…‹ëÂ\­$JÇcg�/¾ ?ý[Âô¼ã. >ºq gŠ^F@šrw`(ø.î§"tgÔ½4 Ü]W°Viišo5ªÆ¸ÕWÞ«¬¡ÃLµDsvµQÕpÎÎÀÝ»áÑðà^¸kvMÀd]€M²EÊš%iᵺ —WE7zêrÁ\½vÎß„-s«©’Ë«€µÐ‚�Þ¿=¢›ùÐn]m—ãH ¾ÙI‘(dzÖ ÃÞˆ¥Ãr¢!¯ãÇq 킱ê'²û¥—`ÅÂ; tº0Ù/¬Âçœg®<¸Z_)ÇúúÍ»¯Çk<Š•¢jÏSZÄÚnohSÃc‰u.é&šÜ$ôq‹F\Š=´• ŸC„„Dƒ‹aS£$ºÄôó­ÂXEîN´G"Ýc{aï¬t½L4`¡-ìÞuM0I K+¸Í\^“ÀÓS—ÅËêÅÓðÜ)8qéêf®Xh‘yyPݵ îÛ÷îƒó°k& &Òv…8üÜ V�ü«]JÅvDñÀ2$Ê"ɪNÊ,)u CÆ2ŽM2Íy ·™måáUE°£ZUÛŒ¼v�Œh_>ÿüÀ¯Œçô7Óè¥ðÙãòøŸ¿~ê;ÁÖÅn$Yù-A;â>VݸÒý”mñÕå¿Á —qå«× š@ ¸$d`�è,³V~ü;á{ß‹[ïŠIéÙ+â öìIé¬|á¼è•9ê·ë‰0OV·W;òçɆ^8pÖÊû¼x÷ú%ùÞz0ü4 Ì·á�ߦH|x.oÂà¨8¸×›å5Wë뮞}Vtokkc€5·_ÅúGWòÁj"Ý9Ò¡cT3“i”p£¨ÕúHÌÃNµ:˜ZÀ^‘æQ>9›8ºSˆ]#y¢¿û˜€«¹Iˆ"LÔÄ«7 `âXÁH:" ›‘ Md±x\IÌM„³‘¨•â%\-†o{;ü‡¯°ŽÌ ¸zìL7Õ\õ&Þ‹ô€Nbã2x0åšÐìÿ^ÓϽÚåW˜€¦téÓ%¥G/0C‡1ï‘%ÔZõ–F¶ìþ6c´hv¢ÁØìÃËçàKÇÇóù›}<õ†¸s¿÷˜Ì±z QS4ŠF!~ &N(ë+Õ–µÖ@‚€)DóÂÊËט4/.Âùê½dÙÜn9ìzõÞm¡ÆËk9“ÈJx¼‘-O¢g;¸…)xï½²®ìt€eŒ€«]S²�G2ÿX{†‰†lëy eL¡£Š£Ü÷ŒN_$Vãp®lÀgžÝó÷o~Xº­#«�A º"ý@¦ ̵¡Þ.Ö‰ÁEØø*¬¾  7åÿ{ÍÕùóÂ\ù°ç±kÇü­##™Ý3ðÀ!ø½'·?Õ£ Â\M7‹J/+>«²Ï™Ë�+ê°ò.ìþï¾ze£P0\“[¦úÑÏ�0ŒÆ'LCܰCýWé6Ì*(T·MÒ¬¬/¹¼.YnO¿!àê+ßOçoöñâ"üü'á±»àáÃpï^Ø?' ÅdS´8µÛ@Xm¶ïÆ7NÙ éa"—ÏÎp>x¦ª^)4üœð +d±ÂlÑ>úÂêðq;†XJ<«z¥ÙIÑdòå�ýùDF˜+®ü–Þf_Š�Î@>£VM€V=–ï‹-DµÂ™}�Ì¿ßÜj¬t‚“²Z5 -³VŒ›¦â.›A£µ×àõgà ‹ð…Um˜Z_ µ¶&Ïnb£Ö`ÝÁÃZq­�šÊW��— Î´-be°b"ºšEèå¡]¡wWwp |»“5ʬB¤]6¶ŒéhÛö@· %&§'xÿ}Z‘y7{Í¢¼ú•ÅÙÑÄäÞ<á¢ì†明jÀºÚÑ8Ò8Á1%>óÍ÷-÷À¿·,RuÀDMØž9xô˜TsµÜL´ vCLLS".g'Û@›ˆ6Òí¿NæOû `ý|ø´´½wóöwi�OéÓ'e€#m@F²î¥3ðÙçUƒòº4¤c!ú=RÏ]�o£És 8¨þZë}òŠk`61 ›ÏÛH7³S/s!ÍçAu.ŒòÙ –Ÿ>\9œ PéP6¤¦‰s=\=Æ}ÛÛ៞?%ÞY//îŒù[˜®Ã섬-­FP9øò«£ñí÷¼ת`Ë ÅÑÅUÙ"´^»TúY3ŠË^í”) ´ ÌF0¯@+¢¬±² þ¨Ãþ&Ìà�'àåµ·èš�§ò� ®î½~|P— WºÁË,‡ rmžç^¨ 2èg�E;›ÁJÃÙ™åº*ß W0XQÉɽÄbÕ-)V#·\½ã <|Ž,ÈöàzOòI—6$ˆy«±Úqz§&ÚªZ$6ÝL5¯ýüïð¾5wÕ`.Vpe* ÏhZùìÛ Ø7%_¬ñ¸•£Õpõ±�Á#�€¹¬wæ†ú`™@ƒetq1´È¨“©“{Š¡�¡+°¸~sLënÅxÏÝÐhAÜ–ðJrCÑ, œ’ŸzÍ‚ÝÐ ¸™ãžF^;¦0Ì(¬™¦q´u�U`~A–è§ùz}–©±J‰êÀú$QJÊLÔqõiÑ9€ä!žYpõÑÇáÀ‚´o×6À60¶†¥�%%Öcl3EÄ”^»(r'+àÊV(ÕxÿPñY�Kˆ{ûEýº¬Ò`�B“’KVÓÀÚ”x½óè`�Ç��ƒs®Þ{�z*Å@cb L^ìmÀRv±ØMÆ.$ïД}Ûª¶"¡È݃,Ï^ùœÃ‹ÀE2.qX£ÇºYƒj8ÛÄMtDsùþ·‰áv¬éº€«æŸ ¹®ÿÙ{0¿õÕ­v iÝA’6»Â„E>ý|©1aËæ„î@ˆ�Ì `›f§‹mÁü‡ývŒ+:#YÓ�<=c °ÆãÖ�©)a®yî¾[˜ÖðŽÜh;¾Á`‰· ø M>$`û;ô|3õÁò°¦ð® ÍC VÕ@&n¹OɳB¡(¶…+±B³úgXB€Õ LQ;úêtî«]Мµ2q'¢µ:¶5a®,ÀÔ„ØH˜PM’bI‰TõÑ ¶Ct­¢cö+dݶò© �ièÈîãI Àjòè!Á¿1R%ÏL|shPÆcg�#»„¹š�”kKS¿¶EØ`Î Û<Fsúç©-˜ÜQó!,8Á|ÏJì–4Ðø „4/ÍW´* ßÕ†‡_»½×svB™« ½ž Q§[xÞwþüExcD�í\¡‡êôáäEù|öÎ ç n7¼Î«;�÷iN„†@çú»ÊF£qÅW«:Öš}ë®Û`Ý¡cfî;÷Áô$˜]  iÎ`yý•÷Áªc‰pXú6`} N^sÇϽ²3Ï÷î£0Ñ–Å!ß�(6Ë@¡«nÑe+ÁYé ò!¢G�-¦ˆ˜ö»�=Àó9À*´XÀrêp.®Ôë“äÌÏe`…Œ Rú¤$æ²èÆâyÜT Žîc½C»tÅxÆœÅpKD�:MÕXÍó¤ì!b°/8æ]ú@i3œ8ª†;¨6ª/kžXÀr¸ ÀíŠ~O¨kÔ¹»ãŽíÏÏñ¸±qx—D­xwqÛUÆ9&ÒNè ,Ó ¢tì#ËçÂþ?Ï^5*L.[0-á|èRK/óá<ç�E".W0l¨þrCF纸F wï¾á_xhŸ¾sÒqÙnÂî–6†7*G�8âÊ¿¥ÀÒ*®Û/²_[`ã�‰ä×0¿÷ßHà»1˜»æ%3ñ³ÏÁÿöG¥õ�°ˆÚ=ÿÅ·ÁÁyxù<üô¿¯ZU�Ì*Ì÷ë_Àü‹ïÇ5jâ�µk¢Ø¼#Ô´î�‡…yV6”ë $˜úÒ \X‚Å+b¥³9¬;~쟇`ךWô&­“-Ê-¬&~E9{eƒˆˆLº1uIO›;ô„µ[%É(w?&Û2Xå,B¿0Ì^y0Ú¦¡� ^Fër†Ç OxÕ«[ ^(»‰�&ò† ñ²jÔ„ÅÚ¬Áî&ÔSˆ²ÒhxŒ¾RocrvÍ¿FiMjŒ¶—¨\Y2Š®)(»k�άz iª5ò �ñ¸‘qï^é6ôù]ÍÙ †ƒ£§nô¨n n°Âåpû°OY~°̉Mʦ©y[dáÐüð/zhü³¿)[ê³EÔVÞM™ö*ÇÛc‘ Z˜*þñþ Þw¼xFQº¸ôÙú›l@Z=Õámæîáyø‰�Hghdá±£ðÓÿ~ä·šQÇð¾]X3ç ×{Y<°œ+3Vþ§]À y·÷Á5t NÔÊšÖƒ»%e£^+X·4“®ôÕM8sž9Ÿ>ûd²ÆëÇà��Ö’¶Ù>†á8VÚ#’|’n8C‹˜:µ€Áb­+]l§á¥+páüe°öÃT¤ZŒ,€’S6,Rõ>6U –!4j1“Ê í‡õµO¡i¼‡Øö�x�€ù¹œNêõ@é“F)YšBã-€mäê3…‰_°IDŸš>(æ°ì!ã pË`¿VÔó 'pÇZ]øª‹²?ßÊ>¡©}ï]ÁïÙ€e=·.00�ƒ›k�ççxÜ ÀÚ/Cg1–\w%E†¥­÷ã~à ÎW?«ÌU8oí6ó¡jZÎß™;«¿w!g‹S&ˆ‚ã” }—4Ö=vÂñΣ®¦T:(A6n”¬bì–…R¬QàF ƒ–apƈ_\‡}¸çNÂ?ü y�øeÌ?þnÌ{îÃLNB¿�«ÇÀ edáC÷KÒzÓ“õà‰ŸÁž]Â<±ˆýê7°Ÿ~2Xsvã~ê[H?t÷ÐÒCó¸™Y2Ý�pÍU\?…ô²‚K½ðÆ  ©š¹®ö¶·‚ðc÷LYÓ:Ñ B§ƒ.Eç`¦-É ÒHÄ3'à�Kc€ug¬]05€h-Ð¥ù¢Qõròî2ImÁí¤FµM d;9D×é¬ 9)1)t ¶ôÁÖ`•SÅ–êºýç�ÅT…ÚªÎF_í®é¢\°IC†Ïý²°gFRããL²—žÒÕXî®v ¶ƒIh%±UæZµÒtÁ½â7j ëQ6*¿¯1êÁeÐ.Ÿñ�‡vþXf¢¡+{Áæ«©J‘Qc8ƒu»¹@˜z°¦xÂÆÈß—ä¿+9þ©Öð/{ä°0W5;”#k‚Ž"tû­þlÄúGΤE¿Zõá³ü?ÿþÙ,,$r¢Ë]- uüµGq+›ƒó¾{ÅÚamEÞ&q˜(´Øû÷agD�$rÌzv×pÇÃ]ód3“¸¸¡nø £â6t/«†Ø–uX¡ö«ŸJ×ãù5ùzµá­nrM«·{0zÍ.óägöÌ�Ö?úì,ÆLÏbYÃ’“F{†1 u 5bbåR =ÌÚ œ\�—/Âï¾´3ÏõÐVÁk@Â;ZYÐE(T~#p_n�å† �œ½jè⢯½Z±6¶©€«Ýx½`ÑõJ19&ËqyG Ò,ÃÍL„S#Åå’è¾�£MʰŸŒ#ÀQà.=Þ½Au]eØ ×&o¨vE”S&+®Vy•:�Áµê¸_ú!ñzò5ñÅJƾXãqc¾­¬†-Í¢vtžÞ­óဲ¹þ~­úÖ]«ÔÇŒ(Ì¥%LÌÀ`mL<Ó¦63Eín¨q”º‹‰cGÔˆÁF¤Ö’L7XKßF È�’™f͹i\b§'熙«µœ]ƒK°Ú‡F8ßúvÙ²¼k·Ü3 Ø5¸ytõLgõÓ;¬¥´Æ�±&fÉñó¸ÉÞ ûw¯ŒÖ=öµÅy(*ÎÍ_ÿüìïÀScÛ†ñ¸Ž1ÙÁ6—�8ÂùP«ÌÙ]z h§©é = MU(�ºöüüˆ˜Ú$°Ð–ó‹l)ô½X»ãœ±n¿#œk£ü»ºÚa,+¤É×ÁH Q¦YŒ(®rR'ï=?ð~é$ÒÝŒ+ ¢XoSoBƒ˜Zäˆê1D©u œô|:M�ôÇ•{‡Mí�l$è]·©©®`®Î®Á³çá…EXÀî…_ø»pï>Y?½VÏÛºêyú«»¬WÒçóèÙG¨;ØÓ€‡Â0Xwô˜m�ÉÀ,#-ü–”‰2Wiî@.wÏ^[;L’H5pv¾pØ�ú«ÃGá¡#â‹3=‘/³NÅêYì\äêõ‰éãÐ aŠ”)ÇëHc·¼K3¨†÷@©ûhVY¡kŠ»ààùµ."_Q¼©LVš3^™3˜zM]æ&Js`å�oA�ÍëÃQh¯¼&êjÑ×ó@©åZ=Ž|…[YpíS2\lÈŒƒ]mÜ»î�Çï¬ñ¸¾¡ñP!ƒÔÔû}�Þÿ~.Ðyë=¯Z\Û–àõ0»n‹í(Äìagb1b’¸A–ÌÁìYÜD]þOÝ‚`ll‘ŸXSPZMÌSh§ˆr©B‘&“2 ¢§kÍ*†+Àz,«ÔØÀ‰ÅÊz–žŒ(¾ý¹¦aÁøÁ‡0Gß ô0l`gc¢Éµn—zR€ÛÉ8f2‚–‹h4"â(ÆG¢ÇÖÁ©+¾|í�ˆ>ÖJ+Vfcœmã\ N¼ÝM´¯ê¶à‰%WÏ�‡ŽæêÞ}ÒqE%ÆÞÄR~˹¥6µcޯЎL÷qR$?6¥Ž£‡›p¸ÇŽ7Á`Ý©^Mý`AH¶`¯LÀ^ßèr�9èövæy®«�ªß£¸)MÃyÅÊ^É&›Ë°åj±Ê�b™ ×¾ÝVvÎ/g¢Õ·xo)�íÐ/·Eê[°kõ›¬®vNTü††µ.Å1è§[qŒ~ôð¥ñœ�kq4tVïÁp>l5ooÅ|°#Ž%dÑ 69æx$ߌ«´Êß3ÖQÀVû­ïÃç›mê#Š›®�¡èbCªû$Ø4S ÔuŒËëxÏzцY¬µD6¢f¥˜o9DŽɘLa"®Ñ´–8Ë0$ÎQ3xBŸ±Âßé1‰ ŸZ.6àŸÿéì „ÁZí sÕQfë±»„¹²fäçStΣþ�±vÎ=ŽTe#(v ?¶{ °îøá3¡è …þÊ�K‹OLŒ%ÅÒÄx›¾oræ |å…�yžû=ðö°oVÚ{™È—#ÙÍÏTˆ�äú«ÂÜ3&¥MÆ1œùœÒäÅbí[¼ýæM «úŠk/á‚^Õ/yˇi`U³þjÊ¥›©ŒÉK`ïaÖÂ0ƒe·Véæj.8Θ[°Âí‘ÆˆO­‡TÎ’c8Ð…t5p è;öÅ�k¹Ùfjp`Í•œ¡þjVïÿƒ{µ@¹»õz5W×Sh¸`>´ñ;Q)GBLÃŽUb6ˆèÑ�nBöçd²Œ5¹îʯÙSÀ,1ûqÌ)+·GÏož¢+²VX ©²åŽà21�E g€U.f «ÝÝÿòûü_ŸÌ Ó­ºŠóñŸ ~ƒ/&¢FF;jКˆ„as0ŸÀŽ™º×‚F'æHŒËdVÿ¼%ýºBá¹7ÀI²µdûçáOÏlÿ�ܵ[ S;²ù¡òm¨ÑWÖ/-yœmRØnôcH“ŒìÈîÿ‘„Ï�Ö�J¡GÁñýqžRw¥Î™¢¢Kƒ%++¢Òlçžg¦L›Íb\ê §ËZd {•ä¾WŽÜ×pnR�Û°Mñˆkv£•îVïoòóðœöèŠ=®,osµ3W¶þØšõ+žŽFôã1Û�™|â1øøðÀ~<—Ö¶2k4j>¼sa+V·,Ç€Xʧ¡h½êVß«©ŠU>ßÙÜ æšDIÎ ›üïÞªæ2Ð%¡ž9jiÆÀÔKÛ„U`å*/oƒct¿À*€j’0ámÓÌ:'² '盢“¤ —ï�„ìZ¦à«Ô…<Óºú‡0ßüÑÜÈ5ʸže�`ùc²”óXsuî|>þøðƒc€uçRè\†ÑŽ ¹±¼0²1DŸ”µï±ÐïIwÆ3‹;÷<ß~HböÌË~{®ÁÊÈÄ›½4a{9ƒ•¨Çú εÁõóeeT·\ãZÀ›V£¶‡À‘™Û@šz"bRš8¦5Sm6ׇùj½~‹ªõíX¬�½Ú@ôkžù[Õ.&¯1MbH3£Ú¹ñ�mÆ�iWï»æ'!JAç‚$”;÷@i>´ÞÂù൜ € .3ƒ¡MJè‘°)ÛRf ñ‚÷kDC™j˜Ö EÏÌíG:#C=h‹rؼ¡�DxÐ ŒPÊeýÙiRÞÀP@\³D<Ìæ¯húU#æ*¸ˆ±lÓÓõÈ1‡cÎD4‰zñEìq0‹£mʱL×ç ŠdˆËˆ?àý3úÿàR‡kÖ¹jÏñdœË�´Ã®ðjl،ƞÕŠõIXWí2EΪ%¢‹NÖY‹³7XwèÈ3 Ê –TÅþs”{_…S2�i: íàóÙÄ·Á´Oµ+Ðæö eß+£Ð+•éídƒá” †5V·bq¾ê{ÛY°Í|ñ-rSÒˆÕoCµ>êáê˪][e`ª]=oe8ëx|sŽCsÂ\ÍOB3V}iOK‰Ñ jX°ÜŽù0<L0D÷#"ë8(KFÏ'?Ç}Çà|ÀZùŽÝªMCÈ8UÅ÷Ôx7û¦sÔMF­Y+ûtm®À/üPΑMY¬‘Èv¦05•³m.—WÀr °äXâะ„aJïá–§¸É^Ãó¨3ªË4¼Ž…~ÍЦ°Íñù‘ E#R=Vºâ‰j͘Áºc‡ o.“o ÍÜe‚fàbl‚E( —S]øúñ�yŽŸxܽ Q»||qM·¤8úº$t(ƒ)‹Ò“úÄYiýeØHµjÐ72úFU€?\%Æ`ç”ÁrÀ"–A^‘MT*²é·�½ªDGyËÒ/bò Èhë¢Þ£±fiê1c¬ñ¸*ÀÚÝ£ÈBö“û¯1DD4”A�rMã,Eûí˜:sµÜ+š>¦Hiã˜$¦EBƒ„>½œ;Ï0š9 æ5 »”‘;HáÃw@Ïq’­­b\eK(Œ€k~™7�ZpS<¸ þÝOà~ôWó5¯ä{å¿þƒá~ìÛ1ô°$Ô’>&c.‹Ø—e‰àˆµ²Â¶-Y§DêJ6/ÈÌQ4È8 é&`ßúÀ JI· �nG°· ûgÄ•=’«ï¯e›ÂMôªŽ=ú{ÛƒÕŨÌq2¿w¤›sE;ì@b,Ù`�Ö¨Šh”«Ìx™d­.íÌst]0©žk•ÁŠpôɈ4B9"eh°b1=È®@Ö/�žQÞY7 \]ßû[0S`jÁ#åmÌ­Y¢·žÅªÞg¡¾ldW�çëxl?öψI¤�góŽ–[ßsñmœ áq•�Íï ¤[ê9«ìU¨k¬êËj ŒV–?Õyìh9GÓ:êq�xn¢€JßûïÅ�]†ûöéoÍ4®È¥†š�fjhEŽ #Tϰ‡E™_¹ &;”}ôJ fä³�víAøØÛá‘%f©šÕZ°W&Ϧ �Ÿk]ƒ—‘¶©fåZ玉c€u‡Ž ë,œ¬£ZúëÛ…Fë(™8FÖwê¸ûìÝ»ý4‰‚*+%ÕJ£—;7”ÁJ*^së(캠rò�Ì>´µK‘_Xþ©kg¬¼˜3 JöïÝ'Ô>ÔÀ´(܆/c´ã%Vß÷Q¶·ãÁR’ŽjS÷ ­ø'; M\´9ž¯ã±ýXhC-)@ú‹˜øƒÚùœ©«NÙ¢ávˆÜC+Ü& AR‹4?>¿ždAiv"Î"z)ß1¸‹Bwu=�‘ŽrwaØt°a Ópôì½Ý}zïØ;­½Dl#°Ôõz- ¶cˆOÚn}rønk¿E¸¤÷Ï€òî…Ó.èœÕ³ã©9f°¶©¦ F¡ˆbôîÙÁ›76•í;›ÜØ ÝËùƒÉpö KÀ¥C “ÿ9Ÿ·çíFm^í*�b­Âì²Â:¢,,- Š j¿häç¹uàëí¯ÞíVìn(km<ÆchÌNŠWÙÔ GrÕ„ vÈ|¸¶€æ*ƒe®ÚcÞļÌÙ1 ‡tÖ"¢F»0?öÁ‚ûùOà¦ZRp÷u­|X^Ãô—ÙŒZ–R7††I4~m8ž †µGÑ-Áñ¨õbÿŒ0W{§%Ñú–!ë�Ðý~‚ádoà<ÊWpè\Æ ÖÌ`å7p«çX­€‚-ÇFèƒÜ éïÜsœ™‚¹ðLŠ­B§Û‚¢p„+ѱ IDATpt•Åê ¦Œ\"y†iC«§É/í ÛoËUA•ïæ «³ËúuU-ßÓèR¿”&„¡;Û Êof$Λ­Ü«‹xM51éðƒa °ÆãjcjBìJŒ…ø}ÈN-Ÿ{Õ­Áå-Â�²MX=¾jla!ÒÑV¶jóŸØº26;ø.ܶSrŒ¯Æãj£ÕЧ™‡“[γ [òͶ‚Wue7“©Îßß9"‡¾Æf˜š�é&¼ÿØ? I §—D<^½î뛘$Ãfk ‘1[ë-¯ÂîUÏùšÏs·æ7Æš9ÈÅ œÞÚ×°zMGíðDÛ]÷1ƒu§ã«¨ää^Õ(4‰+¡�„ÏÕØÑ[„“Ðö¤rœå&P'¥§]„EмGCyŸI–D.`šÖ*2¤®ý{4¦vð„š«ue¬.çôµ¨ÿ&îÅ6×aa—qI‘WôF­o†.¼Â˜0ä Çc<®aÔk`ü÷ë&FãØM`4cwpÑ1ÊKªP¶«K×?SXãq•ÑMÁyK6µ¼¡ðvžr·s.\Íïn;_½kýwƒÇ–y�•ù÷vÊžSx­ŸY‚‹kpp~kVmYY"—’f†ÄF ÈH4Û/Ýf wl�*Èòcõ&ݤ¤£ {¥uh@a½ã_u=‡Ð¦Áï4ø—f”ÏÅ�¬1ÎC2«F C“”:™†�Ö0y­”À`ú��{rµ:ĵ6&jxk®GYƒ•OØKkò W³?)ûù{‰vH*¬”]ˆ†Êw¢øÀÕ0ó,d¯<¸Z¢È·ºŒOŽ·¬ê$D88»‚Ë tûðõ¿€·Z”¼O—¯ø6(wĄ悷«R÷Û¡¡‡X?¯S¹þÙ˜Ï�«ŒÕ>b›!ŽP ` Ç ))IþðìÏE§ï[ÉbUõ—á:Êú£Ö#Ê!Ã�Êç�'×Ó%™k“ïhÞ°eÉCª®òÐ…¿xV»ð¿ÿñÈ"Ýæ+/‘¼ë.:»¦YiÃ% uª&u½#¦£Õ(_„ú®ê‹»^×ÈU=çœ5…°V;báœ6�X¨Æù:¾¡ëíY=†�¾wèäî˜ü.Ã}ɱĬ±™fn¬Áºs‘ÕvNîiÀ^Ù`kÐßîÁOìä>ÔÔJ†àˆZn+etÕè¤C&ÍÀ˜Ü+|�A°à­±J„ß´[©U„J^­¼V‚ï )g¿`‚E͹5W‰“…ã Ÿ�×âÓõVj±ªÛáu ;)™º“)¸²—ŒÅîãq•±¸ i \Ü*ŽÝRˆãˆÈ°[ÜoÛ³'oUÁ[:òØ ®]æ†Ì“êüÞÊ‹®Oç4jí^?¬ÓSoÀ Ù²€pK� 2™¡—šCÔ Þ{Pù|’èypìM—CZZÓF1Þ×a£§ÍJ¢_Æ)…%çkKÆÑ~ 2|­ÿ¾Úͼ8�‚-]7Ö`Ýqc¢»g`�7â+ )C¿¤&âºÛ"V VFD-¯6 É\êÀ…,ªGÚéXvp#¬�êMª ®Nœ‡Þ@b[lŠK­^¾X«Ëˆe uÝ"L¹‚e‘¬ä“â¬0þAX¯Œ5`Ë2Åö`'gÕŒxϧ±ØO¤™Ï…e8y~[Ÿ®­Ì¦)üqB��[½=R¢ÕEl5_´26�>.Ða¹Â¸p<Æc«qz º ¨Oйpr/Ä]Ê_‘kl¼~fFçCµ«ðV3X.˜û} Ï»Õàá-íL™¨44~.I†ê&«Ø<Þe†ræhèŒn·aèªÛd�€1º„cÃ%à 1ëzD¤Ôá·þ~ñ�GÚ(„ÒˆÞ¿ÆÚàÃX—‘™´tÞ~ ˜¥ì<®c›ù±[t8©lÖ]çrkÀ:·"¯Ù‰"„9jã¨çëÒ†2b^뵌øaU£rü}´¤LÚ*°ˆÓïˆ>1)N Ã1ÀºƒÀÕLJ�<�S¾¡j#Þ¢‹ÐꟂ:sRµÄ;X“ôÀøi—P�º¹ƒ•W}ÎÁó§e›°K»Ép‰…8ÊÅ•½éÕJƒëW-­ ý[F§‹MÊQ¬Bªß¥)Ψîª7€‹«ðü)8»Tòè {”=ºÒÛÀ`mWÕ±+›sÈ6èxŒÇvãÔ ¬ÔabFr9£¯á˜ÒN`3Ò·nh~ñÖè±Fm•‡M(ÃLQªz²ú J´ìíU^ý€Ê('±nwL“æJ[ª]¢€¥±¤Þšà‰ãW=W9NÃÀdt3æ€Ò¤œ)kb„íe!󿦨S-ŠR|ŽXÏž…ùIqsŸT¡F„2œÅ½á·[½V6 ÖmW)\»ÁýT°W‘|^ÑÆ˜ÁºcÆîW},€Mtéa4T´ç,VGLO· 6àÌ8µOžÛÁ rjµ‘Ó>ì"ìU¬€¸bå}î|ñ8|ëý°0�:Ô .‰ Žó…ЖzmÄšV:Þ+ÌÕbËŬ˜´™N~8›âK›â˜üü)øÌSpn¹Ä`…`nM«2ï˜FjÄ•JÓÜ⇉¯D½ÖÌëͼC½l‡úd¥ú«�ñü�íÇÙe8›Âì,˜ ¨­J‡-}}íø]QÄçË�2‘¼•¢Wa®×ôþ_T6æ’‡ ÂŽfuXJÉAÈP‡1/­ ä¿/Ì” õXU°××Bï 1‹Êy�Ñ9b.cX£F—& )î—þ<_;B“ [aéSýıa «¦É2°„cIÏyÇ<…NÕ¯ÚI°Ž^Ñk´¨¯% )EÑI˜Š¥Nu\X‡Ï¾$~ä)Ɔ�Ý#³Ñr²¼›¯¼·x«T#ª wFYüíðF¢Rµ:ÛÇ9'ÍÕÿRùMR=ÆH¼i<­½BYsU£ ë�[‘ÉVÍWô3´">­ò%ŠŒÅ�¹iLC"8N\ÏßñØ~¬®Â«'àžcÐhBsMyQô%˜\ÇÓ¨Üïaö_ü{³çBÕ÷γËgu.œF4=K:Wzº>¹Ô�ihdW"‰ÈJIééªF¼@Ñu·D‘•7Q9wS*þœv3Ǭ—q\^.ÐàF»äZti1 EöÚSùvj9W´`éÃmÐôåUø.˦z`ù­8¯­’lÁ(\Pî„^%š€6u}õXÎïž_ý!¬§°¾'VàÔe8¶ŒÅSZƒ½m+V³ ’KöI v—e*¡OÍ;cÜ%ÁÇ5À¦ºrX ¡{„!­¸¹XùB“fÒ½–&ÐßÁìÕ„Öe™�å¬vº-|¢iIŸ±Tð>ÔÛëÃ"Ê^ý×óPÙÊG§0W¾R_Ç•±)uJ²9€ßüSa®¾þ{£Î�ÍPt¤íBtK¡o]m“e®X%›ì;h}7Ü9�'qš7Úc™"+\ÔÀm^�Ï>ßýn˜néCßBÖ‡(ÅaHp „Šd¿Í7Ìí Õ8…[„}ÊibŠ©�ÜХƀˆ””Ô|G^j‡yƒÑÏüGâ_ú;Øcûa:Æíš$kĤ“ï"»˜àžzQ.Ì“'à#ˆ@9õƒ\óT]o¶ x½“’Ï�„�ü«ëdè´]~B �¥¨¬ÚÖö(|–.ë\Ø0Y“”3D·ÓdUM~{#˜«óú:‡h½>qè’0 +Âí餽¼&Ú¢Ï<%¿ä¡ÃÂÎ-L@lpÊGI<‹%#+y5­ê\öL\h9PõôzÔ>”À•c÷¹?/­#–òVdôO~ü#$¼�lß<ét“d¦MòðQÒ¼÷å§øv�ãê1p¦¥E|˜Â _Ø\Ÿš©#�æ°ž^‚Ï=·sïÃ1ÀºCFS#V‚,A15%ï«�Á¢:�Œ²9i¦�Ï:z9× FeË;Òiô.ø –½ÙN/ŸƒÅ®ûë5°Ïã8”/¢¾[È‹J�F“•‡ˆ×Ÿ8ÊGÛ¬Ð%{Tå¼TìEvWèãp®+“ƾWãqƒã‹ÐMD"]Á%{µÃ7b–6ðæÊòš ŒÐÊ$£l|µÈ™�µ YÜp>t+lM‰)‹f¥+îÌ’xÝýÁðµWáÀ<|ß{àG? YguÅ%Ns ½+_yë>&Åé9ýîâz/£Ù§8Z8& ·Rê0®jw à¾~wl7éÌét‹tÂ’í™$ûŽ{`]Ù€Ï=ÇöÀô47�ª×<%•ÆÉöo¢ñ`«Êè=sRÀÕgž¬ñ¸Í£^¤;U}Kš¤*v6¹ã¯,$},“ÅôD€ýÆ÷%úðÿÏÞ›Y’ee~¿ë×ß{DFDFîYUY{WU]ÐÕ=Ð tj„†aX$fˆ1cf3’ƒ0$ën�ɘEi$C™¡‘�êÑ ›Ùˆ^èf z©¦ö¥kÍ=3öõÅ[Üýê�s®ûu/"3«²ª‚ÌwËžedå‹÷Üßó{ü;ßùÎwNÀü8ŒÇêänp• Ù"Ù›%Á’Ò�qpíÁåÐÈÀ]‡Ätô�ã"r?9 ‡'E,9Ú€ù©›…�*ø]Úĵ:°¾#&›çWÄ êÅKðÂEx}­ß:âò \X‚C“Yˆ ˜pÆ’Ñ"Qè˜bhii$Ê…­+Ê.¢ÐŸø5ÊŽ×7œAŽøáüÃ% ÷eÏZ­“康TýïÅœ ¢¯/÷ëp½½õÆ¢0¡ÍºÚ\ÅQˆÂ½h @ÿVpÝú<Ïè† HµÓ6ä_ªbvÿº~�ù½°¬ï#3G-]RºÄ$$bã¦%Ùè$ÒÜâ€Í.l.ÂË‹pz~äƒÐ¨‰+êâR¶iᾌ:™“€!)4N±tK»z˜pêPyê:dº �¯á~à÷Íô W/šOŸ¾Brø9’•-zÝIzÇÙôÜ1�ûÍŸãàßþׯÜ×á`Ý&+öe²B>Xd –¸t5¥%˜ç�®–ƒ¼²TŒ@�‚+þÅNÙ;Wé"”G¬�ºÿ1E°Ýé�»ÁñCð‘ûT5}w�Ð-xƒkaJ; çÄ=/ÑÎÂÅMø7/Á?þCxµìAÃâ<óÌM‰[ÿx]üÎÒÄ2|&Ón=�X ýL°z B{…2àîXU�«V°¼¾cƒ²ó²h*RR,)]ÿõÄëgkž>;ܯÃõ6ÖUYcMyÔ"ñªó*ËÓ©€!ßä <Õ�p�œ)ë׃ýPäžäñGŸ�UpÕK¥Ýÿ¹ ýç·´ ;05‘Ø 9\ê0Ö€/6È¥�%L[ÞÐÄ׌!NqÊî¹È(Ã_Wíš�ͯã¾5`$ÚÑQÌc÷`Ò ÓsÐjA/‚�.îênîîðnzVcÎ.ÝF÷ÝáV¼=–�À9ŒéÝN¬¢]¿`, 1…ÝZ$m·[mxõ̓{žï¿8 SS06ª¬87 )ñ$È6“ü1AʼΨz ç,¬˜…÷¾®N̪Ñh”³UUñç~Nîaæë¬%S®ÌtTIÑ‘çLLá1|ô~øÃ¿ìXKðåoÊÏ�œ�»æàxµ —¬Cœ’1‚£)¦x4òÏ`S3ë‰à1díá³ÐÆ¡Zjñmç^Ä[ò¶(t’e§dNM3º ®ž9 _{u¸_‡ëí3X¤š¥;ÃôŒ©é‚-�ÃòŒ�g_W�”ï¼› \6¬‚¬êØ«n%Ù›JüÌÍ"v‰ÄWJ{{3ÀEã¸^O€Èê6üÅ«ƒEÜ “0=5£fWb‹•»zD,ñÇlšÅ Qb0M‡i'˜`u`sœ ²(d°b=¦îëg1ŸüyDºû7?ˆ=<…�#"®—bº‰0þm‡Ûíâž»W7%†uzpaEä C€5\·ÔŠªd6ù„Á(¸y†þWÏ”„ê£u�G„Û–º·‡]„…Õf¡JlÅ�þÊjæ6©åÁ$=¸²Õÿ>檃5}£êËs÷ÇV»ŽB×±\f�h«OÂÇà÷+íÅ­|é›Âbž�{ þã�€­ƒ�Æ%Բ’QS&+£MT¹AØRד” Ó‹eèoCï”VƶÞX¶q´0êw•g¬¥ú®¯]fîiWO�î×áz{kqþÅ—àËÏÂ� ðc„O½ê1. ¸½Ã]ìÙpOö(wå5€XÂ^eÀŠ‚½à;#er½aD¬’„DöÄ3>wAÀÕËŸ�‹eC>MNcO‚!Êx1Ö&Bta0ÍX,Õš*ãvÄ ºf^X�Z cu)SF@'£å±T$-YŠ»´o. sõ­ËðæÚ` ×­°üPg[Ò`5(ôW;ìÌåÂÈÁ†ƒ¯¿~pÏóž»áè,ÌŽÊæ§‘C½’�€<’ÀûJXžà˸lD�Æù ùüNMÃ}Çàþcð±s}‡Q3ºA3¹|@®–ÚªYo8Ù—,zÄ$ĤqM!K#ã¸ï8?þ¼¡fvK-‰†­žüýì2Ü?›�‰Kq�=�KV \ÛœyÚRóÁFÀZ5óã÷Ëi©$ºµw)ÑÝ%¡MJ—„„˜«™qMnj)8?Úâ‰oÁßþÃ=:\7o9àê¶<žxNÏÀw? sX-¸Ìˆ•ý¥=oÔYÏ÷@FS”H ® 5å÷«%„´2|9eØ0ÄôT Yj¿I:òb½þüø/·?~Ÿœ„ûŽÂ½Çà;î’ä.ëab‘«›P…{yÄB“�Q¨¥`r�„”ÀºÚÄ•ÁÓŽ$*°�€øÂ&ñÿù ¢Ÿû(îô8ÉØ®ž’$i–‘%)…ù“ IDATn§o¬Èˆ¯ÛEs5X·é2Õ¿¸¾Ö` ô{œäó4Òq‚FO=v§MÌNÛ™3öòz2ྊ˦eÞâFo® ¸ú…„ï~��±†4dÅäÁ°V¡(/Ô¬Pãa´³§ªÆ<µÌY‹á“�Àcg„ùù£gà7þ ,V¬ ^[”VõцkA4‡KÛªI ¿M[™«U.¡vóŒÝi“Ä ¹jrm\®¤å¼|ÖV‡×Fâ�¿Ý‘¹`Ã5\ïäzñ¢hë5-é‹Ì1ÔK¦„†–Yi^iZÚ Ž˜T÷C°Ò¾dI\ÛS:šÌ$ywžþN D\Äþ³7ONÂö)øž÷‰EØÎ#̘+€b5�vywäX%É«Ú4xQ¾ï .’°Œ,q¥ùªù=â/_†+�àŽNã&R2[#³�¹×6PoJ‡àí¼†ëvX&P('9§SS×öf…þö– lˆEÀ˜p�¢ûàÔ Ì�ÀL8yË©_Ögd—h`Oã œƒôì¶àâ"œ[æê»ß'zŽF Ì&J!J5à¤Ø€­C´SÓìdž0Ê¿‰² vƒˆM26h°EJ‹˜]ÑvÄSrôc \£&Aà+/Àb%(¿±Ÿ×2âsRNhÔ!ÁeÒíŒd²N3Øž–ÛÊV fJ÷ª~,«Ü€=º$l“²HÆŽ–]§À�Ô‹F2õ페'>ñÊp×;»ž¿úÒ€¦�Aç&ŠPàÇê¬l8óHDS 6OF«IGBš³ãÂ�×U†¤¢]œÑAî=�½ùÍ×áÉ‚ûŽ ¸ºó04k`LÔ�È—cj8êÀ˜öKN!]Á‡ôç bF¬+%yþXC'wñÆë°N“M2ZgæiS¨qÃÏÀ}ú·Hî{I?véñ9’ɦX¤¦ŽlW™·¿ >‚C€5\o` µ9¹öx1ÒÑÖÍþ ÉLgIÙ€'Jµ+Æå VÁË%úo©€,ׄö8¬´eæàÒ:kô�)ö.†ŽÑÕ1Ò™'sû<èÍ|�"Éhï8|ãÕ3gÅ!ŽÀ¶•ajæAú Š›Æ~ÁÏU~vIö!\Ö“J'�Õxñ2\XnÇá:Xë™sðC��á’Û\—iJ׺ öD¢wÑd ÕÆ% ñbDgÕÉÄ�üì<ý,o^ûøN͉@ß”w\UóÙ”b<“süÃÛ¯Œ Xaü‘¦”.Ž6 ;ZÆÐ>6ž—: ~·ÄÞý÷_À�œÅ5î€s‹…ïÕùeWÿð'dÌÏxCXóÈ”_`¿ 37Q<ïîxì.øÔ£¢­û¥ÿ þíkC€5\ï%¾*_½a·[�r§[m/ Õ“¶Û»î}@Êx‡Ç`bа™Ú‘�ÒÕò[2`<…·pè€ëÂç¿)àê¹ç`wŽLk@h((Môó“îËId–ß1à¤>Žhö8E!2õG¶„,–Ÿá·„Ì*›$¢€¯|b—Í$;Œ-îôÜ�V_ ž: �ž–RcÍŠ&$“ çu"ÅU“h°0�õ£¬Èi“À(pº]ylïÀÒ¶€«Ï¿—6‡ûq¸Öúê+ðìyxø¤“Æ�|/¸´�¡¹G‹Ou”V¬>×!c»’ zlvàʦ00O¿ú¬\‡®õÈ”J:ARÜ VÐ4‰e^v'�yЧ5þøÉ #•øSˆÙ ©‚˜­vXÁ0G]ÊŠõ1ßu«ßû]ì~áßæåÂpåìõßû—ðk?�3FÁ•N¡øÑÇ\M�€�e"N(Î7eŸÀjÙß`Šö,7ap‡ß3XÃu�,w� VeeÙÁX½¨Ð_•ÎÔ÷ĸ ;Æ«¤Ô=—Ì_ÿua®vwå¼�õ�Ô°µÐ]yq»Ï 'ƒÌÑOdÓW*ß.>ün_éÖ}G¦oü³zêüÊçà;ÎÀ#§á®ÿNŽ+V‹%“·¦ýJT•+þLÕq¾Ý…­,oÀ…eqÔ~sIX« k®6zÃý8\k=y~ùsðø=ðÈ)¸ë0ÌOJ#I£5‹³­bÏú£¤sÁܼ-®ïva½—ÖeäÍ‹—¤eqC˜«•t®#¦ÎŒïB©‡ï<°V¡Ij5þø¸6±¸<þ8™•ÑlXê÷LÑûBÊJÀÊÔg~wyM¬bÎ/ ¸º¸)eÁñ†°îtVîAfÀý§úúáûb#é’~ôŽƒ{] Ö톰l TÕH¿£ –Ñ.B_üêÉ¥]«ìá]“03­ú+ÏÇyfªWx\h°ü¨Š H8W®”_{¼ ™ÁD"+Ô aô²WÇ�SÀ�úç tÕöè*x­úIùrb=È�½Ö¡`Ò#zd™ÃM�Þøg•dð�sòð«aÅ?lnOIçÒûOÁ=G$ƒž�ÃSçmâodŽ:‰Spe·¹+7œ‹«œ__„W®ÈMéâÖ�w®¾¬��cûÐ))3™†i�Úˆ¥7;®÷~WÍG‹0º²-þm힔ٷÄïé¥%xm¶hõz’ moÃæf9a»Ñ5ÞT€Õ :À8M³ÀBƒN!lú´¬ª1ª©œZÈd…lôÄ¿na~æq¢zÆÖÿ𯃆–²92�š|.ÿÏWáãÀßù~Ià<�†J*\8 g†I¤#œ²Qø&2"œÍp½÷Å¿/M3_~þøh"`°n·•”bŵ¬€´u\äî2çŽ=ƒ|[{_›Á>XÕϧ´qé3Ä^y¿«pìPµq`;Q®¸5è_Ô ¿!O¢Goÿ³kXø®{á#ʸ¡;æáø4Løvv�±ë I÷úŠú~rp|ŽMCvDÒ®Z8\X�/>¿ö¸°5ܺÃõÖ׃Gà3? ¼[ì[”¡ÍÙÙ0¹2H¬Û ÕÏOVЉö¼U‡åYØž”ßïvX]¹¯½VH^}õÆAV³¶/{Ê<šbF\‰?U€¦J†9:X«‰£A}¬N|òP.Wè%è}¯>þü“Ÿíj³¦Ì•ëc®låB3f(Ï®ŽèÊ¿¡c3’~èø�GáþðÙ!À®÷€Àb�fœÏØjS#ÎGæRFÍÊhÜsœž„CõšÄ%þG: »A§\2ÐltðF±ùfñÀª‰a Ñ9ÑŒñ(Ò¹3«LÔƒç–UA‡ ¾À:sý¶ %"ýÌ`êñÛ'xfG\}ï£pz^K…ØezÜ)‘õÁX- š³höUrž±Úb@7õ³o“ƒ‹HÚ¸‘)\=†½©üÑ3C€5\oo=zZÀÕü„º¹GÕMXL¥S0p«zÈhbYœ™ƒZ7r’c°²L5ˆÛpæ =*/pñ"ììÜØñ׬4rÇExCÙ¦i�A¾cp–BwåKƒ{%wÕ}ꟗS$´plci5cÚwÎÓù‘Çh�:„û±ÿ)gܽŽÕ�”O“>þ €«‘:Ø15©è)(LóÄt4xøÙ§�—x}ªƽƒ7”Š3~,j¸V…)+=\>��üO׬’½_Û–Ãî +ÌCMUt�Àf0ŠÕ¬nO —ûX½­57)ÌÕéyñªÛ܈=Žo�û´À*<‚ÊìaQ^ú³"#f#u¦}ÏøÊÐÖa¸ÞÆzè”0W±v¯ ¸®Í€kØìq‡Îæù•EP¯Cm„Ü*¾Ù”GCYæË—áÏÿüÆ–�J0¯'L'ªŒUtÀj¯{‚øú9êdÔ3CÍXìH st÷Ó�‘ýÆ“ƒ«;møÄCÊ\™üÕøQ§ìèµbM !~ÄÓ�Ñ*%™þ{0F* ï?up®»!Àº=‰¬êM¼‰Q –¡F†ÍUXAŽ²Ý‚õÌ$4k0â=—AxI‰ˆˆè¨o9êR^ DqÑzýé†ÎóçÄlÔø|Jžçßa,ð¾šfMDhèg¯#À™àyþµG(,¼`~?@YŸoé»a\ß…`àØœ9w•Ÿ�K—OÝBmD‡Æv%¾`2,G4(Sûñ€ó �ÞÃá¹Ò nòù‹ –$ŽÉØÆ™†Èý&Fp?þ�p×Qxî¼xß¼tU�×påÉUeVß™Ãâµtü�˜êN�ŠÈö'–6¸¾m_L0¹‰‹·tIÜäSÛ%ã\t‡‚©´ƒ‹ D50cpüÜ{¦&û5ž×ܯÄ®+Ä–Áæ1Â7ÔxÖêZÌù~÷†h850�c2Š˜lFÏS›�‚ûO�þðÇIþÆ—ƒþéOâ’ –·àä!œf„ˆ^κ ke#e’ÂiÞÇM¯ÿ –gò½Ëüªþ¹�ïzÔ¸bY‘?Ôr í |×ýÂfžž‡Cã"¯˜�m"ƒ• ø«…K+¸åxm ž:Ï]„Ë+°¸K2v°nGdµ7#áÙ«‚ÁòòÂZ,d™|’)˜0§Ê¨\Wפ­Áßû÷ÄÐîÏ^‚ÿæ·:áGA@®Ý„Ìq/¦ÈæàÅ ˜o`›€Ÿÿwà“ï��ñ&4c›½2ZÓ§9ÛO#åAºáŒ6ÿ9¹Š«~D\|[��>ºÖ¶á‰W᳿Ï_îéá*VuVßh]tVQ$àĘ”›±/ÜÇÕDÁcp<¸ê•bØ)GØè5y¥H§KÌwàáY89 /¿ÅÌx¦ÉîÁš¿µh­ÆÂÎa�Ë™,K&¯kë0ÕÄ=|¢Ø«ÿô' ß«‹«05Üs\…¹ryÇcè4?UX>¥íPH'Ò †tô;Ù¡¢I�é?¥¿vF4awѲe ¿K÷þȦq'gáø<¸çÙ`ÕûèéBÛ”è Ô†ƒD™§5,‰•›™u\#–Ì皤zùÏ› ‰í{ƒ·¹îZȳ9²Lcè`H•µêªû|–ÀÊš‰é€ÅÀ`@]°ÚÀQÎ^­#zŠ }ŰED‹”®¼ÎL�ŒW�qŸ„÷}pn.®ÁZgè“u;æ‹3 ±ø85 ß~gÁÄFmLÔÌ5•^îËRRš’Ù¡ãzíŽUXØêD WX!+ŒlÂ6ŽmRvèÐb›6«t±2ü<–Zj»¸ÇOÃý7áùóòX]‡ñšqŽÔdnˆóûnO,KÂW*[†žTÙÛŽ2•Á9§Cª]á-lzr0RŠý­o”ÝF ®Ò<öŽjÌX@&]œB\ç�!]Øþ;ˆé÷ÁjkÌñ ž#ÂWx�VèÙŒÔ7ŒÊŒCÏÀ yYГ 6¸'„@Ûÿ¶ò½ûï\☥CJj%câ¯âÆšpbŽÎ¯ Ö-®B_£ëžEå®QÅ^Ë ël,Ï`9ͬúÆï¥k*g.E¨~86êsJïn\h�ú;ßJhüúî&½~°¶6¨ ÓhŽfƒ 3ª jŠò|Åi aêhœâËß° oÃ!ÓþæfJJ‚-Úå­�Ÿ�;^¾ ŸþÕWaµ3Üó·ÓšiÀ�?ß÷°”¦¤9Ôͪ–4…öÇ•J܃V<`õ*7Ûâ¹ÞÖ&!Ã’ÐQÀcƒ>f6�GOÀ °² O¾"ÞX§'áÈL6„9ñƒÛìÀ•­¾ÝîSÇjWîuÛÎ\grÄ81Å‘eà"‡3=½KÔöHvû™¢ð; Àîý>X¦BøÁÒ“ú¹ïŘçï=ZƒO|¾ûÂ*�:¬3jûï}ÕI…U„)¼bV¬¡‡÷/lë{v¡žÁ|Î,?X·èªúU.®rùÇÐ$VKzäDߓʘáÕmX܆KKð•76¨ÌÏ3Íó S ”E&Ûa”FŸ~¨«A Ó$3»¸©Ñ¾P–¾|&ÛÒŸ; p‡¿¡ Vd¥¡ ³-“ó×~[¤ÖéY´70ñ®^‰‚ éðñŒÕˆ¿Î‚þé;~ü &ýú³Çùô‚óiQt­PÌ_\.Ëù¿wŽÌBšîÂDט+Ĭö-Xj²n«u|FÀÕïR[‘ØÅ˜X¹x=ʬÐq`Š”Y�Ù7OƬ^ßa÷]}¸ª\†Œ¬×®«¤,áX¢Ë2–5ºláhÓÆ‰®0ª‰_Óh[4ž�Ÿ�£X«ØHdº©2X)¤u° ®Ä ÇìâòãØÑã 'Tdܘt¡Ð›9:Ù§Ný§Œ£ë ‰sâÅjºšÔV³÷Ò[õ ,»ÎA´W‡�[+sc8úMR}\éŸýZþ�EcpóS®¾çRº›°`êv‰è“æ¥JŸ8Î`˜¡(UŠÀ$É»×�«úó]"Z´¹B/^!e²5má<6X·üªú™œª¨d¦ÔAè $MØ„œfÐÕ¹sc‘ÔpâÊ<ƒ•Ð_´+— C&ËÒ/r,¡ÑÑzˆ©Ü|„åÑ¡_Îõ‚«ðµCú¿êý’;{¹·€°æ'ÔU9¼SÍè\ÞJ²WaY0õÇ{°S®òYÛÏõìÕŽžç*0Š£­�®èÜóS±\×÷•ѳC€u[­S³òÝO�ɵàgÜUâšÕRRa{âr6vFSA²0hê‚©ì˰iÃ3XÅ Q£ìVJ;Çç¬wä#ÒÒÚô˜·ê=•7O3“îÞÜ2Àóë¾<˜èñØ<þìU*¼VªÆ9WGÏÅôâ„^ ‰3bìiŠQ¤×�Èž-êo&(âoõ×éA{0�9¸;<#ÌÕ±9˜U‹‹8G=…Bä1ÕŽÆq oGß;Ű®I®¼oª20tåîgpf~°nù5?%àjb$ Î½Î"l~�:,é"ŒeÊ“t¶ºBe_Y†×7`cí€3XU“€ò†­Ú*ÔsÖ¦¬–.‘g±@aV@¥°.¿­ÙÓxå1Pß×ÓÍã‚ fÇ›yv,n)K&ÎdNÓÔëX±�‡ŽÂî”a¶3£�e˜¨8ÓÎÐó¤A4'�„w¨²ý0»¼^ƒÆ˜z&Ëg±“À%À‘åBØe=÷2°hNÙ·÷¹ i›®Ûk�œ•ï¾®à*j«æJÀŒø-E9;—³&G*llÕ;*¼ÑÚ§aG¡ß§[ºG—tï\Áq¸JÌ Ö4VìÒ �!¥�sÑN4Ôn]Á•o8qNâYdÀu„ÁJ-.Ö÷w–°ia”” l©t?FY Æ>{ž×Vë¬àX"f‰„5Û:R£k`ü)[ ;®}“Ìx�¤í'Co.m §1ÿÆÊ„G‰•ÂXSDï&f1t±´¨ëïÏa8FRšÂ1Œc`Ú86€%&‰¹@‡‹%!¢CK«I¬³a&†ë–_G§…¥hØ`ú{ÿ¨ú`Éÿ ¬D§>9OÊà•k°,ûÕÍÊ7©Ž¶ÞY{‘e2ƒÁš ß¶Ý݃ɺöªÊŠ…%ÂNÀ’e�=éuhã: ÿàÇá±»ÔL´Vê Ý•›¸<£ ¾”ÎWŒ¹v“©dÑU¦Ð³ MÌ! ¢Õ_Î(#7Ö±&Üux¸ßo·u÷‚|÷ÞÏ((FUÙ’�� 9ý ~4`¯öÈ^ݧipCwAbÔÑhCKKw-ívóÉHB H´YQ4ÁÎ1º;Ó¤Âb¹X¬ÔÄÂ0¥úÞ¶'ŠXQrq�óª–ó…‘s´�¥c =©\åH¬kÜoöêØ»ž˜]ýý�qg~Zâ\>Gu›V4>L`úº¢=ƒUSýYYû•R'¦Fª¦Üz%“Í!Àº-2¼ñ†€ƒhc¬nuˆh÷µ+×5ë««`SÅîí.,mÃÅMxaå`Ÿóؘj°’ë3ƒ!@5tê¿'~ C†#Ê…�[‹ãK¾Å·�T2c³G`óͳb‹ÀD—tX&f ËŽ>/Åál×½ŽÉñ¸SÀÕì8ØÆ&9°ò�4“šÕ˜«ãAf7dœñ ǽ>ÿj»ü¢ÅòeÞ'üê4´&&šZŒ»ka¸ßo;€uT’‰�¨ê®äZ¿¶Czí×kù°^×Uæªìƒ7˜A�þ擌²u‰gág¦HÕnm‰inGšÆ2KÔE‘2,^ÈÍÚ×õLµÜvÓ±"´¶mZ1XÛ ¶ÐH £Öåçsú¤h¯~¨)ÝÖÇUà"p^ÿ¼ÃJêØÚ£3P{é5ÁÑ^@)âÆì%Ì>�ÒšSrÁ�IÁ|Ãó9›VÇ0Ì“pÃ]À�g*ñ»laÅ!�6&UuV†%#Õfƒ—9L#˜ ;X·è:q¨èË�ƒx‘þWáBWìÀT³sÀ{áSwÍrÙàn<«frîLA8uº=0£8U?”AQ”w…�6eWb¿aM…½dbè_£üÜ t%k÷:˜ÅGN�+ƒÊÜT�òˆž0ÃÔºþVývªB¡¾¢¼wXj-Ê‘6ÐÅd2‡qÐhŒáºÅãÛ¬º´{1µíÓêøkyœBcµ—¥ÈõsVÿìëzÀþøDi§ô~†ŽIþ^)¨Ë|à*^…#F#†I!K¡Ûƹ¦D!+]Š= �ØÑv »HÙ°0ÀU»‰A+[˜pïtMc¬öî‡0œÈ5®¤ÐZÇ9G2Ñ„é&Œµ1®AÜ›‚³O¼.Ìk²<ˆ¨ÚOT»"7”I¾\È$þ\¢Á2°‰•½CFŒK»ƒ}º*ˆg�á°O«ÍU1~ü~ع¹¥¯áK¢%¡ÄX Q"]Ži¿¬chÑÍ»Çôó™ÍYÇ¢<ïé{lQÌ…G4²u5Nο×Тb°nÑ5;°W ň…~ï+Sb¯ü347p‰ÜÛíƒÎ&Ss;°vÉžÝylÉÏ1™ú½¸œÒ�ÒI �H�˰èd.”*–qmÍú¶tã…Ÿ UL¿ya(–ÝÄ��‘@ÒÒ¡È=vž_sv—W7¯ýÙ,LëÆ7}YxX.npíÑ?7ß)zp—P³ò¨Î:4^£2Þî÷Ûm�5$¤®N¥ßo)´‰nµK üäÖÐëi¬Â—»-˜ ñ4I?ß“/Iî˜Â}ùÉô›XW8ÖÍ#{5îT;¡£JŒÜ¯ë¼Üy>X·þšhµûœ½r¥ùvõüg£VˆÝ#ÙÔÛXÛ€×/ìó½ÿŒ4drý –ï>i+hÙÈAŒÑL¨M‡¦nX5 £ì`§ ­–”mSÍ:*lmï"ú-ïR¾¤YÑ!Í’&(ë±Ü€cZEºæõ÷—�U26U{%!£ŽK,D›¢ ;wîúS£²ñ#0Ä%íÕ(…ö`^Y¬Â޹aYÞùQ@¡{r'ÈV ÝYp�T®ëµ¡‘ûí¶êqàÊ]”—§ôº=ª ¬w _ ð¼áídÁ• À•­°CYp“ŽŠÂ¶Œ˜„12w¢×qnKÿ[.^©­“Ká©Ë°ã>ÙDLo|ŒÝ µ)<›|ü™Àb…q±l§°a`5�UËIÊŠ±¬Í„,, 2ëÏeWÄ{úòÚ`Æ «ég±Ÿ·19C?ZI63Ê X*Iè¶ÆÃ5 ]ꊂÉ6¡9�S[m¾©w»qÄ”¡ÖÃ�ó!( .?ŠD¼tTÑ`Ý¢k´®WiZâl=[5�—­á2Õ4!éÑFï`Ÿ¯‹¥Ë¯—P­Ê”‘® KªåÁ8UEןv F;¸XÝ�å5I#“ÓP®Ä“ù¬*¥­Tz£’…«+³N–3Xb©«¹_ãìU\ê„Y{sé:¯SÊÍ .Ý¡ÇLíd®ö[{Í‹kT˜‡\²R‹†ûýv[•ysƒœÂ«,lí&«ëec÷r-/ºã apRƒÔ†‚¬àΟXè5 Ó¤÷çÃýì_`ZW—ŽZq·´µs1ddB«‡ ޝ« ´HÙ2ƒRX7°™Â¶IÙEüN ³žP»ª÷ Þ\L[i+Ë �W›´¤UõlTµDè†Í7ymª×…õ¨tlgú[¦G1¹0Ê£‡Ó‚Þ Š†S_Ù€ç rÍw%d<X·îjøo6Qa°jÄÔõæ_<1©Jþ´±7u°›ÀåøÆÙƒ}¾g&d˜g3t~¡äz¼›û™Ä\&å"p…„Ub¶€6 –Œ.í I3¸´ç®B»'�Ý6pIG7O‡DƒH¦º¬1`‹”U,‹æœãÁgÏ35› ®Äó* – &¤¢{°[D’ 6[¢�»fÆ_gÔéºÐ;ùa«¾ûÉg»þx½às?o › ® ðËñ]YsøRia‡‘;æÈ¢!Àº-Ö¸……q8:UÒ¹„ú«iea�ìÕ…²ñ% ¡.Ë�™§hšq8bv1láØ$VF¨A��q œÃ¹dùÍÌ(sÕ€¤)žXþÞýëÆ}éCK챘OØÖ•á 5C£ûÃah§ŽcØìÀf§Íf [í”–‘ ½V“¤“Ž5pæªTi­6¼>Àä7+øŸ"þŠ ªŽ–FIØ’I·léw~GìU+¨ \Ñ?ÏḬð©2X™–S�,÷U †Nem�‰º¦Ì˜Î…È».=Øëê{¯kÖñóR X²YÙ`Ýú«f‹” dÖ?{0 6ið,ÅæY"uö¿:�F¢ëË'\ßh›Ž¦4Ú&%U –�hW@L'•Ü `yKJõ¢d%úú6ŸüÖóÃ@šê…ú‡P»µ�£ERy‘’àhàÜ.‹$sÜi ¸zãêõ]np¦Ó_6¾ÞΪw l…,À c+•*#3Üï·¸úÔƒð‰ûááca5�Áªî½–¿Õ;ÅÄÇc*ÇcßAoËP7 íU™ýšÅ¬œ*9 •NîD5 Ï1™äÂ÷·%°"ÎòõJ\êmÓ"eÛÀvjh¥ íN;g®Òš!KÜHg¬T Ú=¸¸ ß I3HĦbáTojh³« +´EH+Ë' [8¶4NЬ"vMNF*áß¿,�ýpüzZÖKÉdù7ìþ®SŒ÷q„£Ê®ÃïР–>C€uk/[Îêå†eˆI¨“РÙ7ª@˜.È”Áj%ðæÎÁ?ßÃGe"}\ (Ú:Ð+é V‘úý9bΑr‰bæ�/Ã9·®wlµ`=wþôeøÈ}â ݬC­¡!˸Žz¤X )ëØ<°6* «ê?ÓQ–­�Óæ =߃s \Öƒ'�ƒo,Â=u} –�4jY ¾.èºÊú ÷óz7ÀU¨ócM|9Z¹I”D¥Ãuk®…qW»&¥]ŽKDDL¹ƒð0…[ûEiî�.w‡�!‹ÞvHX!f Ã8)M`KBKbAzLŠ[4°¾ �C0j5#KÕ+ËÀñ¿[ÿW> ½)Üј¬QÏ@÷‚drSy›Ð8Ê“OSHRè$ �í6½í„dm—´—V™š€ÉºèÀZW_zv0Àê¦0*úÔ,g°ä¨RÚ$lc˜VqÌéÀB§êô¹râ ³„×§ZV&iH´Q‰n k-‘‹44‚%/Aü)mõ¼Ü¸¢ïéçµI¡;­é±w” \DüÀ.*‹¶B̦66õÄr¢Š/á`Ý+̬1Xývpꊞ:ɦúr½Àɪ¬Ám–6¦4Õ‘àüywRXÚ‚‹kðê üêïÁœ€OÀ_ ¾í4˜:Îts*<#É- ¿S° Xªdû»c`¹Dƒl7�ÿïiøÝ¿æê�EÄ}­U*£¹t—GÅï!sµ °×ñ•ž<\·ö::%ÌÕ¤è #¿£m0¯SÖ¾›ìUR^¿¦d8j±*Ëøc`³ÿä ø[ßÇR¨÷Šýk€‡ßÏ>/¿÷îõULÃá¦q¨˜ßé¦Êƒ«b˜˜#ó +…®Ié% ½´F’¶IwSÜÆ®03:�ÛÞ…?{¾¨Àê[—à€á´;˜íâ´ðæ›Rz9c/Rù&1 jzLÂôÇ9@ Öbrºl+°)4X’ä:ëp;]¸º!þ€£5a¸í¯âXÃårŽr÷¤·}™4?šÇ7!ùfy_—û–,§ç>X·:À2àz¹æ& 2«:aë»É½Z¢œ4ÖÛ[ÚøÍ�ƒ¾ ³Â*ŵ ´¹¼Ó#t^÷3Ö�9[[: 5\–Sì·váì,mÈÿûÖ²<~ç)EôÐ |)›Üü³ZŽŒ(ÏêÛkN_Ö÷�Ñ­®æpY&™ã/ÃçþâÆKž³f%3Æp,ΠÑ4ï¸ Y¬°Ý}¤Ä FçC×-°ŽNÁHMÍrÿ¯ VLLŒ=)†“O `<ß�f�ðÞšRX5L�2ŽcŒ˜R¤tµ#™ÒÌ €\ìˆ=Ìvj‰€„üWýÇ~ìïbÎÿ3Ü›k˜…Y\-"«™€U—¸·§¥€îg4ù93�µ¥¡Ç¥uø�ÓÒT³Û…?yþç/îÿ!,mÉyp#7È0ôHÉHIè(°é°£ìÐRΞÇyü€å‚!¬cÙ f�º äô¼uMÒaûò6\X—co hµ˜éÜ^§GÄŽ2Xþ3Z§è4 Gåx¶ËW?6•ÍÚÐ$½›¿"îêÎ`ÝòËD}ßî~ –é Ê™tvÿ 0XIá8O1˜y‹µ¿�J"ú¦uWO¿Ë|¦ž9›»0A\WÑg'ï. 3Çê8‡ýÆo”Iv9Õ<$pe^ºü®‡�3+™A/�ªzÕ׫©øÎ ·û-¿&ep½µÛ²Eÿ˜íc<uѽW×pTÙgqn>š×´Fã´QÇA«+1&¶ûŸÀ• 81¥ù˜P ¦“dKq¨oã8p&…¸®t%:cpu9!À*už/m . V×ëKðȨmã˜Õ÷ê’±KBLD7—DøïÈ—Rúÿüñ‡,Ó1»XzúH!ó]ßv ×3ðÚ\Xƒ/ËôŠCcò™: V:Ã$Ø[ÁøãðV`ùçlPt ãu°Wqé·C¼CÆ2Žõ¼“¯«,Ð:)u,õpQIŠ;ÔéàôaI˜ c�,ÇÙ¯ ÓÖJå½/mÂç_”yà(Üq&&Ô¢Á嬕 Ó2ý#”¨Ü7 ‹ˆ†ZüÔÅ—Ð-K’ÝËʶ9C€u«2Xf_F`0ƒe`’ Oœü(¾L8° ²ª3I™!ÚË÷Dþ=ʶvàÓŸæj¥%Z¬êzú"üÊÿ ß~—Ìù;³ Sbè9Ú€zŒ‹­RÓi0k,üœ]á“é#I%PîìÂê6\Y&íµEa®^ºg7ÞzÄßãšØwpêb³†Àê6]‡Æ!ŽÁønØF‰6\Kcz°Ùâa*×µ“˜ÑK`�Æ�}Îbu[êWVá¹ópïQ˜…‘:®¦1(R­n í®¦n"ºÕTç­úx´¾®ž‚©”»^½¯]æê¥‹pvýÚ'ûüEXlC}B,b¢çqÉ#oæÀ)ÅÑÓó¥°”[hT]îþÞS[F“,™ÄEÏàҦ̋]\—÷Þ艔ã‰×áÄ ü�? ãÓ<)ëÒ»ž^q%M½¸Š®sõLL¬ú#*ë6 Ö­ °D®·—«l&iJ#s /‘^vðÏõƒ÷ÂÄ(4jƒÃd�aB�T�Ûcí1€ž¹F––8xò‚<Þʲ<" ØC§àî™99¢­'FáÔ<~Â’TºcÚ=ØÞ•xiMà ¤ÛñÕ•}‡^›k€¬ƒ¶nd(ìpÝ¢kz¢XʃñcH¡­Y+ƒ"â´ÂøÎ�õll‰‘u&2¸©Q¹YC¥AeÀÚÜÕ1^ίÀ?ú}øzÅ·ð±“ðŸþœœ�Ä(’7}ü3åÏ嫟¬•eÂf-oÂo|ž<c'}yÎ/Á̤°Žqök¸ä0Ä2¬¾rŸôiTËè]þgFJF]&m$àì×piC˜¶�޼çåŠ=X_�Väs9³ …SÝ£Ðʆ�½’ó’Éh’B´(úØ^"`÷Ü�ÁºM–»A«²²Lfdôe•Á"“cŽ|ï^ä¸U1¹ÌÌHtì8×7*ë�^�Ïü(|ðn˜•AÌa¦ºgÆdšÎÉ÷“ª'Íò–XIüêW¸€9@¦|\VÆ!Ⱥ=׸mæB·o’ðW—í4”~æãÂdo¶åÏdŸ8¼µ«�MAFg@×÷Ô¨ŒO‹•m1ìñ Ñ�EFž;є߽ѵ¸ϼsSplNfGÖ3ˆÎá’±xx ãÙªþ£rALJl% lÞ�²`·'ç}iYÞsqÀèž§ÏÁ‡ï•& dù÷ßO/[½ÕŽÎupÑ®¢ÄDʴߺg—‡ë¶XÈì¥ê0ÔNÉÉ=îCíšSEF]…øºcÆ&a¬ø`E9{Õa£míÏk“Ð&¥£{j ¸ó.ˆú=-àj~BÝ᣾�mò‚_iœqÚ_£ævãM\=Ÿ®?8Ѱ\ÿ_‹ ²üH[Ž×(†ÃZ¥æM ÕO†{ývX�º6îÄéÊ©o_¼gÂx�Ö5“cpÝNÏ PZÝ�µ¹yïË`«=`�Ö…á¾?þéþÏæñOc¾ú5[6ò;£õ?Ñ¥ øò7åçGÎHGáá&Œ:ˆ×ÄÄÙ€K…½ò†ÍeTâÊ¡�¢çÚ2N¨gDsµØ† K®¾üMyïêúÊóð�©¹œÁ“ÎI³7Ö´R J•åCʨ;]a®¾u >ÿœ¬Û`íý¿¯Í`¹’² ²ôàŸ«¯�Iöy€•î1¨³`±D¿…´,ˆMÃVë�?æ‡N så3Ê_Ý~ÙTßß##ósâÓõ;O]ƒ·>—³ŽXŸ ×­»l¨Ì‰¯ë‚ƒÃvºk,þY'fa¤)Iùà+Å�ŒˆHy,9‘:ÊÄòw«`Ñ6pcãð³ŸÄ}ߣðì9øÒsðGÏôÝiªF{¾«2”½Ç Ë3WíÊà º’Rc¸n镹éÆs@÷j`Él‘ònƒ«½lbŠF#%ÿ$ÍÒ£¿ÒgÿÜ·>r7¼ï$Ÿ…ÑQq.�l™q1Àò:neK®w+#iõtœ]^yo¯ŸÝþðYy¼›k°nuËÓ®)®ìM§÷­Ôˆ·Ô�>Ï^�N‚P傹惑âÿ9—pîŠxi% ¬lÞüãüÁoƒ_ý é4¬Ù�óóª¾T…]‚ës~/¾Ó¬ä»NÀÛñCÒáøýïnPý߃MøûfkQu{÷oJá1–Y67„V·ËÚíU€Ahóö3ë}ï¯áýŽ­�-Μ€¤Úu˜¤üõÇ —bü‹ –ïg`~R:1w:°²%º­ý޳ ™qT”T$«vì±EFSß{XCfrMè1zÿ´èYÕŒ¿£ç·©Ç´ŒÌ [ǰ£ý“¹û~– ·ù­¾ÞXqs]ÍF™ÑV{SÒú‘&ëúh0¸³ðÝVžµòû´Tìg:E"ÕÆ�6w0í¾¼ ÜÆ#ÄÖRkÊŒ¾kiF6OÀb¬F²²Ý€$M&×-z6¯k!™j�|øÙßþ$Ù?�ùÒ/†¤Fáž&›WÖ¥‹q¸†k¸® µBkÿ€“©ÕÃX]&VbJÜFè�Tdtꣂ×(èðÀöŽ´D¿xùæ¬�ÞÿíOÁ�‡¥#Ȫ“ràÜìK¶Mü XR;Iyðò €µ»Ç¿y'â4ü^&@VnFÝ” «3€ÍJ)&Ì¿ VÈD„eŸ‘Þ�2¹KOé�ºå×+WàŠø�ÔÕÕ� ‘ê/Åùk¹Êx¾›×qÈÀvƒŸËZÇ$oT£¡1É7ü9Kd±uÔ4�e ũ͎+%È¡ŒÀ;’› ›•90‘Väóôeö$æªÕ�Ëkð­Ë°>XC€5\ýhªòתާªÁ2ùÑ+~é ‹Ü�OÂ\ÆÇ´•Y¸oHW” ¬Þ˜c³�ÌI¼±,àêó/Ê«·»>ö€€«‘:Ø8³ uLÎÍóÀpXÿî'º‡+ì õ Ö¶fé+È4úEý³©,”!¡C‚Á9ÛW‚ë×EMßo˜V€W‚³Ó¿÷9OߤRFQÖÙ ˜«%à*pEÏo Ø&’1j ½¡I:Üï·úzõ*|ñyùùÄ,ÌNæÉŸï8ÝÕëfY¯ã&å!áƒ\ºßIöÊëׂ½¹¬{v‡êÈ=ØÉq"â¼ÒÐÄ1š'_13À!œîј\¾/åýSzX:k¶¦�u›vš°;?Nç£÷“þî/‘ýÚ“dã~øÀ1ÜV[Æáœ[põ—oÀfoxý Öpí‹°°X&�ÛKqE?à –Qñ¶ ÏÎsUh9mã΂LÖjY*Á/þ¶0W—6eŽÕÛ]ï?û9³4¾DXe¯fô1,[X>x{T°ZŽL0¬Ôô�?Lˆã¼$yáv‚¬;Ûï•Ýø É 8–°¼ÑÞƒ‘ 2¸ö°Ëé–_·à×¾ –#÷�ö3P#`¨�î�h �|�¦ðfG¶ª~ÐïÕ•2ƒºuÃ]e+ÆÐ´ÆpLIЄ‚¯z#Âæ/î5–ݺ)F͘l¢ ŸºGF¢ÍŒ‹YóŸ¼ÿü Â\m^ÃE~¸†kµ3X2+,ðFœr²ÑèáY˜�€é1˜jV¬G0#i_P#dì>ÿêÍ=¶“s2oÐDúÙ:b 5bÆ€iRæ�ãÀ)à$pLY¬e�F({”¹ [ïLÏ 0K–gíq?T¦g}W‘Á%ÅÆOT²£™õU Ý•×Buïì }õlÝ æÊß¼~lY�ãp¸,±ªYù.V;SœËd(ndàôÜ î? w†£Ój&Ëw‘fÚÕ†�q_^܄ˮC€=¬:Þü 4ׄS‡dò©Y86-Ƹ“£2J¥QSK|W[»b›ry.®À¥UxæÕÝÙƒÕ¢Ð]…Ó)Âx–ço¦è½:@سW+À%½–/—•™Ý:ª uÁÀꈦÊLMsaµãYn—k$G)ªÅÐä4g¸7n W3Xެ4c6j1íñ ºw&õC;Æê¸Ósðúêðš¬áz«`«ŸÉ2} �x«Øƒ{2‹©²WFÅ8sEÎ]%ya¦z�²ƒò;Ä~ÌŒõÍŒr�U°W£Ê`�SˆÛG\5ƒE°ªº+/î­Šã«åß¼K)Jq‰ e[„ªx>4mâ;ò�7t3ªÞ”¡«-}ßâýmΤ !«ÎëÊÖZ®þóOÁÇ„#S2ÞËvMðÎ.“k%K¥ —ˆÞdi»(ÿÎS2(v¸nÞškÂO}¾ÿ!¸û°$EÍXº�:–cÈ�w!˜µÙƒ^ZÛ°¾&`+K!­ƒ-º«×pk‹å£ÄÍ´mp†$8–ÁF¾¦0­¬HuU5ÝsSÊVMéÏS ®&‚$ÌÇ�‰™«ËŽ“GÃ:êILÏ&D KjtbÍÊÐùá¬áº>@Õ‰îqÞÔs· IDATžÕY )‘Nx3á­<É„:>¨ë;„Á…‘1 G‘†¨¤¯E:%%¥G¶gˆ¼‰«Yƒ4ˆ^5÷¸ϳQÇ §€ÓÊ`ÁSÿåO3 S­ü™×ô9iFÂ3ëúßOR°‘þ›ÍAÚVÎ\¥y™Åߤ¼Æeºò~!S°_ÓÄ^ão|÷—ד]ÔlûpËEDµ ì`éèþ ÌpkÆÀ&öGÒÖëºlâX…dì_@㳸‘X† O�ÈÓŸxÖW†Áãf®S‡\=z &›r#7¸1q-€ A1=Ʊfj÷àš£0á`¶®£¿‘aIpì’•,Kª¬}hu2’3ø×x�•‰NðÖö,p–” z-¯á;}�rX~5‰qŒ“ÄÊp;NG5NÌQh$G0s!Àó�¸žI›CÊ‹#Mˆ“˜(Øz8)XØ7=6¼^‡k¸® YíË`…¬�çèñÞO¤»ŽÕ#P©§žÇõÝÔ÷�v³We~× íUSƒäHÀ:…å·ýXúèíóZ!HË_g³%ìÕøxÞDY�cÙ¶Hó¶r¸ª¬ZC¢kdùý€·ßrØÂ²¥7†�¡ÌV½{´�üÜŠ”�L ¸Š"õEs{À»àçȃb ƒŽÂ‰xa°nêºcN˜«I-åû¹oé^‰Ne—FÊn QÒD3:¬×’©K�¬”´*lV/V¾TøV4…{±Váh§‚�ÍØÁ[3ȵœæ VÒ#lž�¹œá>°Vžån HÂü'Ve®»Ë=êd›Ôˆ�Œy48±<4FʵÃ5XÃuý¡ _ƒe4û1Xb"2 …,rv“wgðñ[]GFEH^o@c,€E3¶Ü“àÆnJ#VÞ1�e£|sùÏ],Ç4†ybHY@º!Ôÿ…*º&@–çÛ€¡òå½- ðak¸8Œ�¤[hJš½¥Œ ž9Ž„žj8ÚX¶Hsvé¢Åš Žu4`Òâà‹ cÚAøŸïtZF4*KÀëúÿV±lèóº^³’¤µqYS7ðŸ|¢ò)í`¢fÞµihêµ+ðÁŇ�‡p\À™£¸h j xäüë‡äˆ/®â¶vE§õú"/Ë®j^¶yf·ïçm€µ½]{ öküÓà�e©èSr ŸB¾…ƒ>»ªËm�§J‹õ[ÉZ¹ {µé,–iþQ\¦½"۵جd=VÌÑ-¥¹ ®Ì©+ÕhéŒL�•¼ŸÄq$äÅû6±naâ ?g�Éh1Zá�5‹c.„¬\¡,¯ÍP"�+^>ú®ø>,’I1IÇz°À²… )€N‚gš³âôÄ‘í᥾=u¯0WÎVtUÍ×)ÜS1#ê+LhHדkŸV²ûä:9ý^üÊ%kÔ©$Àj;K©= »AÓ4±X6ºÖÉ5ÀK¼`‹Y«å螎ƒÓƒæª uFÙ+m|vaDö‘þÊÐVëfî¦q'f¸‡�¦}#û¾½m¬ímCY pA: óH³’ÂjS¸°°ujz FÚÐ)¡J9L¥C%Á¦ðâÂë+ÿL˜°¶¶Œ{ ;]éK×ÙYÉC;qN]�‹ópy®¬H†á5VU¼ZÒôñz£¾ø¨˜ê¾ó 8‡1¦èœ-¯“¡MʉZ�8FÉ´ìekÏ€‰Ê]©*C;Åý›vÊ+¡KWËoËdŒàiº¨KÄy�|®ê=¼[ïá©‹Õb¸ì—c1ûJt/lj —õsdÁ e÷> i�-øxã1yùì¶li<Ø7-š» fë‡,“ÅúJOÌKÏÍÁ‰óð�ÓðÂ)xõòÝwµ °îbDµî„Üä➕܎IÅ%=ÙÂ%ž*s²aN*x>•ÿ%+r˼ ÝQv‚ÄË$a"Råèšyèg°ØÑó—à¹×á‹ÇáK¯4€¬�8éoNøló{×z¥^< —æ¥Û±�€�磘¢«0¬ãS NË:Ž„¬ÂPåÑJ~´ÐÕK„Á(Ö^Å:•.^;]t7¦ `Õ�è*?LJãKѤ³1 “dì^¿Ò°ß2Á{õNr²/Gv‰~íƒï„z~á·áÓ/½½Æ—ï|>ö_ÂÑ=²À±V&Ó5@ˆ‡Š}ßâëTv¼ú ƒ%ÐÚT<¥V(»½²WYq½ÒBô3MF?k1Zx4ùDÕ�L݃.ö¸Z�˜«Àij°±w›Ág=¼�Á{_›}«,VÉݻ™±"ÖK61‡¢™„�} ú}VçÏÉpü8¼ð¼ú*†âÕ×Ì—&²—áK/ïÿ¼|i`mow"ÊòC^ù’ D)†�¬K),tÅÄe«n»´ZбµugJ³MC¦e¦ðÔ«^ÄŽc+®L"ޏ}|Ò�dßiÃä왆½Óò6/ž†³‹Úå¦òä­Z»Õ­r‚î,Þ¬¼pJØ—¼CŽe¤É Þ[0;‘²K�#£W™T‚¦d¤ÆÄÅY…Q«D£È½ÎD”lQ§˜,ѰîziµŒa52$Ó|6WtbÆŒD§vgÐ0I®ìF®�‹2YÎcYÐûb²Ldÿ¼5xÛÁß¿WÎáÛ `}ðQW#­2kÓ†ë$ <ª ‚þ'c‡^§X¦É æs„ª#¹¤L&d¤ ðŽX¨häZu˜'+4{}Rµô°•nºLÑUD#´ƒu냵آ°…rw¼XXŒXØe,«XzZ(bºÌ8~ i­ÊeÑÐÚÞÐr)mÕÌÞhy0û«M6u†×kÃÁ$¸ixðAaªú}a°Žƒä Ïœæê™cÒ)jÇ0‰ZV†1TÀr¯:Þ�;|+�o{;¼ °¶·»t™¡ôÁ¸‹0‚Æ »³U·�j­òê~W¡•iÐ]™†2aVœ*ç%v@�QV�§�'ïƒÝS ˯ ¬Êr¥¹%ncÍïí*%ÑÊgxàÄeøçÿñ0móÙW¯­R¡Y&H¹Yîg«Ï¹ÃûTtW_?- 6+Òð¾#F¿7›2ú¯Ç ;¹vŒ�É>�ŒÈ«£ÞXçÎÁ—¿,eÁ™1éÍ›¹{ÓpÅd�0ç»'áÑCðñ¯n¬ííNTòðØ Mœ¨öʨ©ApqÏ¡ça%…®‡îöûiO ƒ5bM“hˆïëí-&ËÉ Qè¬G¶ÑYËÉÈqddä¦�7Â^`€™ÿ®£ðO^> ÏŸ”ôùã燓/&S1A¬–n h …–«ëà…•RŠýñ})ç|ó’¼þà«ðSï‡wƒv ZÜ…š.«š³f‡^™töt|2ºÈß&Qy¶ÔÂÕ_á¿…dX´Ih‘1®}WÂX‰†f–= w5ŽG“¥kXõ‰{‘œyÊN³KÊÒ]ÂrE™­y=§E`¯ñxgÉ>ÿäGà§Ä+ë•‹wŸ¦$1ðÄAxæ>ù?|ŒÅWU¢/´L�@J®z�òÂK­©û´^ÊÍÕ¹_�)òõä:yí>•ëUv  “ÔǪŽ//¬>z .­ òÂAÀ•¡…mŒ©J#ñ¼°jÒi[Ú0$ È##Q}e} MáÏOÀ;jÜO ù¼wä.%Ë™ƒ,7ÚÑjj�Ï7¾5?s¾°j�û0f ïœ,«‹Iãáð^ø¡‡à¿øoa÷´Æ°Ͼm`þÊ@ný¼Dºt½?Ö�Ÿý.üGž‚NÂg^€O>KwITÕ6Àº›·”z�¿iEÃ�–>~©‡¥-,Þ5™ÔóóÒÿªœ>­ ñZé+ºP†òÐà#KJ‹¶Êj�9™�O‡ç_¼ ¿ú»28éù¯—î„!I¨ýeVðüËMÌUÌ¥Äùk:ˆ¦ºZ®o¯_€×/J—Üøˆ¬LíUÑŠ˜ve€Ÿejç/4H”Ú¾¬ðú ‘MnúÃþd¦â§ïvĆL)˜ ¯éˆ¹ŠÛÙÛ�~ÙíO M,[(ev1…>,üŽì �{÷ÁÏ?\Y‚?}~íãðâ…»k(yâ üÓ‡§ï“H¡5“ |%gsR¯Ëô×)ávc/\Ä;¯Å†Æ¥çebÁ¼«xâÉ=œ÷\½é¡…W­¡«¬¬¢',ï�ŒN2F-$ôó2¶‡7HÓÌÜŠ”Vû©0Ä-Þ—¾}YFž%ä‰'÷‚Árwó�Ïà wZfz¯žq}ÞkZªNö_„C-°T²ë¡¡«×R�øJu¼ ³vwÂ�ð®{ở�ŸýÞ_n¬ím+op¤úœ”Ÿ¥…£­„-ýy¹›Zh¡I·î!¶GDÒ ›žÒž!Ó�µ?d.[#Õ…’FFKõ#ÕrQ®xŸ#Ö Bÿ;Îáí*~÷$|Ë2 Õ@L`¯Ä3'eVK[qüEÜ�ëë-êíâ¡;/Ö§ÌQŠmC‹¸$ 5¬‹ð©gåûûöÂÔ˜†ñqM7àse9]}MÜ–0œÑ£Œ§Ý6žƒˆ‡}›!+ÇLQŸ»IŒX*!{‡L³Ù„ýØ�d²Ýƒ8Ëï®±Vq¹)vÄ7k¬äÓ°í¤ÔÔgyñ3²œfÈÕ×Èï70\?¶*š’÷?$ Ïݰž¹Oîë�ãà'ðkµ;-g?pHY«ýˆïÔnÊεõôNq×^ ²‚žkš�çYvÿ©³úQOµ%AƒÀB«*ÃWJƒ±­‰«°²®Á6",^2ReØd!Ó.5�Yvozšéš ¸:{î€Õ¾,ÈvÏ@Û‰öÛ;ú>aÕuYîvXêÀŠIéjGm}þF; ëaê±ê2)+ 3:ú|îÒ3¢‹r°}0³`æÁŽbX0•¤XRRZ$´pÅsW–{3r-Û–€ØèWOš¨Ÿ™ïþÀ þÃ�m¬ííNÙ†ý°š£ "%ׯ>‡‹[Øk�Ê**W*»æåUO¢ƒa_ž–RÞð…z½Ã¨üeµ™ï›”zœÄÁÌ8<~Dö)5�dsÂ4Zýö¢rÓ Â6ÕÅ¢k¯Fëâña]S½ü˜Ê€_ß..Á¿ù,|îy¸oŸ€¬û÷I†Üþia-F[ø–“lkÀyp)ÒkÞÆg¿Qt!–‹×]à>Š÷¹Ÿr'Nž^¯[–‹"FžñÁtÈe�ÀÔt� ©‹Ú×rº&ÙáÉh5ÜZ�©­�œÆôkɶDÞA-»&àÑÃÀ¾Ë¬#r$ü ¸뺫6eGçŽÚµjb›ÜM×Ê՞㦮¾Ð¬0¶&+æ¤Tç\…���H½ôMÅ6¢ž§™ªejÈ4xß—FŸÃjWàoнËÑ=®:-a°z0•Ëû:Gž§dΑf†�+Ù¹&–› 0Ýžæ ÐTÁå@Ab¦zÍò}ã•Tž3¦OY¾GS cá|V€ævôüÅ%ùjnbYú,®m+�Çî"Ÿ¹m€õö[2p=VÐ`¹h`ëË:P€•^ݺ‡³cÆ[�t¨F—Eœ8w00WãÀ §�-�hRˆÅ¶yX„ÙÈÕ$Ó²¤Ù}aœ›Q¼ïâÛlŸ‡Ú0ÕוcH]«v†‰}¢¶ža/ž0`ÓΫ”ÎÑ瀋x®bŠLÂ"¾ÛYü m�/,ÉëÏ^»ö¹ÿžàc? ÷í¦ËYp¿)Ä]ö÷ä^r¿‰wˆ£b6€n ¯_†_ø8üñkðÔ!xÏ1xâ(üÄûÁ ý¡\¶�šÙrÙë÷{¨æ7ÆÂäk±€1¸*˜ªþ¤‚„ Nc‹ëbЉH&ÃŒQ¼ïá;-üûᄀã˜6=x�q�¢¤;�ïPæê ^£CÊ4îUöjªv_×A•YcîÿØG.ND˜bÆJo­vÄäv�”6yÖû¤xßeÉ×ÖöÁÔ‘VvU/hÈHà*ËÅÒen¾ò&ü꿃£»àþ »��ûÿæüaøÞ§aß ù˜eà:¬´{,XÇÆ1íËã«�v�X�áD ÷œêÖ‚Æp§aîž”vÔsÞ¥fÌ Ëf 0w‰N’UôH´P XØ3Ih¾dË–µôÞO MÜ·ÿ¿ÿ xîMøóWákwpöç6Àº›™+6XoÊ1%sVw bD¢k©z†Ù+«'L¨.¬CçY`u£Yéë$þ<^£‰jX ÷ìvÍ™Jy2Sz¼îé^ÁܲnÖ¹ö ºˆå.DíA8ß%/:«J÷h›Ý[ == /žVcç8tÔ Õö7ËR¤GÑ^W—åoNÏ ¸úg?%x“£bðÊÚñB¡ m"ÄGi6k½ÃVSc´â'%°V5öe„uÌa­–ânÛöÍ4ækÆ^WõŽÁØ€v¬Æ.šk„õ®S�iŒýµâW“A'ÞƒkáÓ“˜HóXë.>3èXÓbOªAñ]|:.Ç{#cR/‡…UxS½ò./ˆ¾h´¥çP�æù7$bhç(>o““‘bè‘ÐSÃÝ^mY_��9%ËíU7–ÐUë‹e÷®o´t ¦,(å&®KË”ìÆ)q% €¼¶²^DûÕÕ…¿ 9“{§á¯~ø=Ò8ôßýüÅMµ °îæÍW¸¾RŒ™,S$Ïç˜\q1ßÂ,ÚN4X•žüP™!£ L`ØI©Ø×ð®b#€µŠh=®€ äœÇrÏ¢v+ö€A"XÂïœ�s ×™þŽo(uÄÆ—¡Õ{Šj>{º¡–tuV£'�SÀÄMzÏ2&êRÔdç¥[€šÏ.À½(ß?röLÈ’cÀJ3XÀ¥%Wô¢üíO=!àjÇ8˜ Œ“Bˆà” SÊ~BtWG”Ù1"c ;o_ïÄÔž˜¸ë0”G†@¶-Ê*Fï�,‘Î/vNÞ}CÉ̘hr¬×ñ#'Á0ª j§^—ÃÀ}À½z­Bwg\¼Ùë{¢µj,°üÃ.Õâ}ÖÕhe–UÔÁ.8ý]�tØ¥^ÆÍ…œ¯_Y‘ŒFgõá×÷þøs7?øü;îe°Ï³jǰcà’rq–Rsß�v�EXÌšÏ⸨ ÷RcHÆÖzUƒA�ï²m¬] 0yA=þi´Æ 5•o?_×Rv"¶lϘÀ*#¬+ƈ~³×—‡³x·¢ ÒP>Ì1-¤Näy颰ԫ}¯ÏÁ«àų©U�Òê´t¨-ý~÷OðïÞ�ßÝ#Ÿ!›x/�®w¬Ú*Ë/( lXq…ç£CÙu#8ÆÉ˜AtV±öjo„G"ÖâVNÜñÒÃéçÅ€[J+y¥y ô;ò䣭k·Óàà$<°Ü÷ï…£»áž�°kR»8Û°kJõlD�»‰©®mA²ri¿Ú—’Õ¥8}UJW¯_@ðÚ8·tíþÿv |†1‹%Q=Ú¤>;A{tW1Ë8r‹V½¬Ûi`ç�²ò¥ö'Ò":…òVÄå|âkð3ÿfsÇ*ƒh³Ò žþªçá?ŽçÝd¿ÿ�ôž™Âïe¬ñ HD†´–35–¨n7Gÿ,Sæ$^¾ \ Ã9ÄGlÇ*NX#À»ÏâÓ÷Ê»$§!ù&†Uí”q/40Æò^}>è5Ÿ¬±ï¡Dš® ºÊÉâÚ¹ŠO@šh\W’ãïß· °¶·­ °Ö’�fµaÏ(ƒ• ;”oñTõ<–Úz¬­cWòX±¦'l#”^†{�ª|!ŸÊñÇ /â™Ç0‡çŠ.ÈJâD3?ÛÂ^e:ºô–Á.A2[Œ­MláH…1Î�›tbÝUh*µ”>ºF¦z�¬·÷m€µ½m½ÍPU©í_kÕ4YNÍ"&ôp•¦[ûðÐ �)<¢ƒhÐ*E™­™ˆÞ�b¡“0nï S˜,|4H»Úбp÷¶�9_x ~ða&FÚR‚P¼@”âÏyàŽ RÆ1'ò¦—Õ‚bÏ*1ñJ}@¦U^‹ïg®ž?)�9oõ65*g0éi˜4Ñlð¥Ú¥«â å 凸 |³Ã²ã}ÚU²e+}ðõÉÈ�½ö‡<°OÀÕƒûa´­úœ9L2�´ahg¯+'T[yVþºÊ’¢Ðà˜X�cŠo-$ßi øøÌó×XÖ‚i� IDATM ˆÕÒç'èp«] w nVìKÌß�RõÑê)0™¥,¡÷(ýàrcÈ�ÁïšØüû}¥Ë}±HùÜ/ã¿óׇÚ�ü/ýo˜‡~‰ÁÞc02Fpóëêøp1zvTX,S. ½.ÜLX€®W0\Æs…fñ,âX¢M¯Xޞǧμ û¯@g€qYQ²cäe–D×ý¢Å Ïgýºg”%Ü‘(ŠÜ!/òH3Í •ƒŸ¸ƒKîÛëíÊlµ›ÿS• Œ¹ÃŽ+[w0v04‘×;Âê-þÁ„´ž­^�¦IÄøâ+ð ¿ ßþѼ÷AØ3UÈÞEtk ¦ŠÐ%³3V�¡SJ V—¼¹bq²ˆn÷ÆàÏ\¦"n{~«·‘–ˆƒõº�±˜1 ¬QjÁ´ÃÝd›¹DiÊ×f°|uÕ}­íÁýÂ\�¶¥1 Pd04E­­;[+Šj1LÖ@Ë À:²[ÀÞ—N\`™Fv¯ÕÀêÝ.†±iÜ:÷MÒÊ�Q°¿ÉÛbWÊ´µüÆØ‚Åþå+øÜ+öpVÒ–1ê._eKEr`"–Û�èç«^ÀåœuÌ‘3G›ÒÂx8˜£†ÜOï/IjC>ýÛðÓOG�u}6·Óð|Öϳ­±ŒMLðš÷ÍHk`mowÃUÏ*¿øþÖ> C$ÄÏ(ÕSÕÉÑé o4 ¦¢Y}ph*¨†ßÍ"Æb…ÒI:μ3Öà»|úEyüÉ?m�÷�=�¯”@‘‰^!@Yâ>Ê€Úœž¾–ÓÂð02$ôŸçðæeérúð“ðcï—I½¥f¡h9¸ŸÂJf—áì,¼v^:/�…7ç›Ýßofk‰¸]VÈUVdœÒœ2èMbƒÊéD»Y†¤Uc<ムH÷£Y `µ-¼ï~ø+ à~ÇÑY9�±r71$�'³:X°5̸µn<[VZí~4Ÿd03ŽÿÛßßþNàß„¯œö2B3‡£,±Fc�²+“”¥m{›†�X�DÔáþ >Ró¸(4süh{ówraEž­‘ÖšÜüòo‘¿çWðï{ˆ|ÂV4 AK%v&z&”ÁòßÏäº,'0ïsæœcÞ XtmV ÿ>£é¡ïÏ«]+]xñ›`ßUPƒ¦áˆƒBhwì#X>-ÃAÝ+Ñ{Ãàerº”æÎyža‹w;Oß+FÎÇöÁ¾iÇ£mOœ)I�L»áWúÒhprŽ_€çΉK07‹‹°ºªÆÚÛk{»îÍýÛ7üW3?Å=lõ¼ÚÜ(Àбi€H~('«þZo®ëV,34n™‚÷í÷ƒˆú}æIsO¯Ÿ±Ò‡¥ŽcÙÀjâ5KÓ‘aÔïgKpÕÀ™«ðÊÙÆ‹g¶ÈHÆP³Áë“Ô^Õ÷1åÉqVÀÕGÿšO�©^1êö4¾ù¥6ßâ`µç,|e^>Ç�à /À«¯nÈÚXw;SåÖäj%j2â\œÄŸŒZõ˜Úâµïž®R0ì�aH° *š©° %ºv#ƒJ§öf¾†˜Ï¼ A¦f •ˆ)afU“Õ©°ÕrPG±3•Ir@Ž'#ÅÓ%�¥ñ#Š—Â¹±0Ñ&1I8/PªQš^|®‹@èé¢Óùà;៻õˆ& £çØj>dé¦UÆž?·{ònZÁOa™Ò<ɰÒ[ÆdÃk“¿ò°€« Ò.îT7‚%ÇÑÖÏ0•°äø\”ÖvH\@yv¼¬ [ÐèIk¾g€g€%s Ê-x“À”Å?vXÊÙC«œ-ÂóPê=Sä…›z|½n n*E…g<6= ŽîE¶Ÿ÷Â�lö.u…Á•ÜM~íGñ¿òñF;hþÖ¿Æ?u/fò|»M®¦Æ¡¹eAY«6††$7¸´‡�ëÃìþê<Ùr�¾�®÷¬NL²ºšÞž= Æ-9ää®r¤[|¹+àê³Ï+À2ë.0; —a×Yñõ©—råkNO‹$zŸ´üã§ïpµ{Rƒè£gSünõs-ÞX<“ÀüÄ%ü‘�0òN8z �_;s–—·Ööv#[iÕàu­Tº‹»ˆÓÒŽBãK¿·Å)¬AN³ê¤yX_+–ãFWÊæZ£}¼}ò9ùúáÇ$këð.Ø7ƒÏµ^˜TóѼ‚Þòh¼ÕÌÕz`ûºöïÉ£Ê\™5˜»*{JÅa<0­ÀŠÃ‹Ã~ÅÎÿ1ÃÛK|–³0¾–ï�Ù0a·ÐµZïz›» …Ì%-¿÷Ò2ñ`½í• øG÷A»Zþ ||Ža@KÚ!L;ȰË+˜+ pê2ùùy©¥?áéOO“zG6:J>>®©FÆøþ@ô™Ÿþº«WÎÂéù �·Êv£4³IkŸ¢_?"ÌU`á+ï×È×-.°,:��Nví‚–æžž;_þò6ÀÚÞndó «&c´I6´¥3ot Ú�-ŽsèéwJik—«VÄW&ìÐ=”Õþ¢.Æl:ƒõl¯¦ ÖuñËÒ@âCJü/|üÒ_…I ®‡OÇ*AÉ™nMÕz¯c >õà\… ´Éq¸÷�2V2À˜¤’³@yÏN1xo ät16ÁO�À?úaüÏ~œ½ß<ßÿ<ü¯ŸÙÐl’ÇïGsõµf£¦ŸòetáÆÀ<£eA[wu™‡­}ž|FFšôÉyŸìÂ�Ìãm"¾s�=;§áüùm€µ½Ý<ÔŠÁUýûBþ™[1µ9ñ[h³ˆs¥ª¾¶ªî=Ë/£ZvjJ¨_+0`üЧ\c{ñ \˜ÇNvEµíÚ˜ì*Æ?ADënïÆôÃ-¸–¸ˆOQa¬‚G).›¡K…ZRép4Ñ¿Ù; {&áÁ½ð­Ç`U˯^„O½ÿ÷ŸÂ¥ëŒß1×fì-^)ßÊÉ{ÝŽ>ƒ€«_ÿÉ2k±å*Ú›&ૺ+v(½M0ìíÔ°êZ(·Æ) _ÜÃ#bâGŠììüÙ«ðÑßZ¨]×ùØB׫z?ùuïÅÊöè~øè� `ž‰5@úÊz�Ï}ås¼)½ÈÖËõÀ³¿ŽoA/ÅŒº‚£Ó„69VKK9æ«g1?óo ��Úô»ŸÂÿ�÷ÁC¯ËõpnVYwB>ê#l}üÌ6Ü­ŸÖzÞF^y¯¬ö^©úÆë6> ÇÆÖìdµ4kióâ³3íÂîÊ{¶^€ÄC;ƒo‡÷ßÇ_ÞXÛÛÍA,�Ò,n^)CÅk¨–¹Œxa±ÆÆáÀA8wzkÒâ ,-‹‰_+%n`–n¬´(¿2„ÇVã”å˜ØÏÔV�q§ß,ÒÍsUÙ€J{„8jìšë?‡ïx§tÃŒh»¾í‰."¡Ê· ƪ-1HʼRú Lâ 0`“ž{ª]”«$¸BuçÈõlYDá Ö,Õ\²ÈCFJnzäv ÏEhÃ�¶dåð…—áÒÙ˜þ É’`­’Ó[9i7•Ääò~Ï$¾åŠÌDoÄá]Þ¹‹g`êçŠÏÈ£ñËÖ@u|ZüŠüãÜ,|îðró›{ÅW™ž¹ò¾ Ú¾}}_ð4µg6V±³~xŸðZ&c•”¾Žbò7 $í¢ (ï� Y¦´Õ¨9^tˆ&1§G�.Wè±Ä€×IMBn<Þöð;3ü·?ÿÇ&݈Ûëí²eK1Ìb¥ÕuFn…½Êr8×Ûº‡Ô2åRYa ;Sa°ò:;Lq™§^ŒèÁ£*$ч”û˜ÉÚÂzý*|ì?À'¾"ŒÁ±ý“²sBX¨Ñ¶48WîT– ˜ìöäÚ 'çšVÄÅ ~Š+:UûÑ8ˆ@>µû3o`O‡ß#-¼¹„ÅrÔc ê‹œª—2e¶:÷ådäôô½³2ß#Éá‘ý›wm¬·‡UVUZ×ê m¡Õ‚¤-¢Ü§:ðì=  s⎼² QYH)Ì„ŽD‡yà‚!g®“Oð\êj &°õ, _¹œÑ×)$ŸpXU}ĆVîáÄy}âë”Ó ì�ÿùçà‘£•,?S°Uieâ.ã€ò!sÔ`ÿÜåË Ø¨;|Ê †U‰ÖH¦ÉxÒ6´îÇ»nñýÙ †ýy~ò†²ÈÐv,d-šJÖ¢«1W»÷óH–_pÄÞ­@+öþª êÍ:ç/LtaA°±bÁ <¸rŸZª� )™ÅÓ÷ü±ý×uÍüïâ’VŽ%#W_y“5ï°5px >Ýï¹_ù zÞ¼NôIdBì ¶±Ó†=ŽÜªâubŒîºG Ý}ãt ôSGÒ ò~J>ÙŸ�…?|ž¾ú:|ã,ü‹Ÿ„û7r+?ëÀ•EøÍO_c=ž -Ïûᅩ6®b4‡8OP-a{ª_³Ê|�Ö{ï¢V€U2zˆýŒèAÇu„ŠØcšeûœ�céPÍ •˜¡œyz,�°H¿Œ J M=ì›Ü¼{v`½��V“3–“NB;�”Ý V–Afjƒ�'V\˜âÿ}%¬7�ÖFqÛq<ƺ–ðPJû»)hñàž.‡“m‚§JËÀ»öÀ{ÓàÓÝ{yœRå|°b³Î‘Æ.”AW‹ÁQ ¥1{—+òD™,£#ðÀþ¼ 7®6´2¿�ÏL¾�µoZ³ÍÓ‹¯ãë^Á’a-‘ÿzåR=®Æ „ˆ¥)�xF( †3õˆœ…ƒ;*‹¿Æ9ñ /ó\§õï'Ûp½î®ÃSðóßzTÄìã9yõy“g.Q6ÅWì5š®]ìWÖ%4Åy¼udFŠ9EÙnCÛÀ#‡ä›[�¯œ€_ù÷²?“kØè콞œ€‘I7°�ÁÂ,|é%ù›ñ 4/õ3ÉP�´ºñXÐ#£‹«°¡+µ*56©1ÿ¡Ô¸¢‹Óžš.—îò|ÛªÌoœ¨k'#°Ƴj®lÊ@›:úÅ{üø&6sm¬·¨Zk*�–¾F,$£â‡5¹¸´5êìe¸:s{azUè{u»’®´„DSà%²4a�”ËHÍßëºSW÷;t² « ð�.éªë—€7€³À92ætåµBhH`° ŽÓ‰€«�<î‚= p“ìÅÐÆ‘�0Vž=äìA²âB†Ù$ÃŽè>ð—)Ýé/ë•—¦g� –HH™"M cZãøÜ¾*=£¸‚I ƒq(=ø·ø¹‰u(݆ýËã?š“RR’bÔÛ§…aT]yv*Su8 Q:cÇlªãúÄþñs]K‘SÀ›Ô=Æ<Ëô…Epš§¾s¢ñ3²5ÎG‡Í˼æ*6^ ûÊYe””k¾±> àê¾½ë”bl¬SðšÐÒþëq½¦Óz]Cfæ$®â &û–1ÀãʂӬı¤Kd1çé©Ípî|+— ÉgŽÁ»î“} Ààïÿ<µöMÂÄ(Œ:pí²”i­Ø1ô4 q#Ñ3«=EÈ¥5Ì@÷­¼Ç2aä¢q20¯ãÑž›eJ-àCÏç°\!c £ìÕª>Kr'ÅÌo¨8ìÒçç€>;�•+Æú2ãõ*¢9<�è/D#Ož@ÞvÛk{»µ«:?ÄørÍ‘û¨Ûevk™ÏÕ…7o`±(¢=‚ÿW,²”I1SƒKW¬¼Ò`…òÊ"‹„„z£?Ku‚5¥Ë9üÊ&°~;F„¹zpì™�Ù2 žhÊñ “iQï$ˆ-Wš1ÀªRì^¥=ËÅdŸ¨—¼ô6zëD;vÝ—ÎWšÒJ¦!'ÚÙ숹ÍÏÏZ]¤Í�¤^Êëµ2�L’+׉˜ŽÐ!8Ms>æõ üë%�¥� L'¢×X�ÅreMÞ¬!lw­Vû¦köV°Xku¼5vý6Å@=t�0W#-e®|eÆŒ-`€�ØÈ™èY‹™ñyF>3~ýìRM{“uñ,‘³ˆ-:”ê!ÖoÅ%°!«:IÄ~R«+R,U:-ÈrL"�œ‰þáú܃ãp¯2X÷èª<¸µÇáãæŸüØv¤ž÷Ø&ç).J­ñúÌhkHHP×w…޲z:‚»Í×)S÷#Vv©2™Û²åóæ’þ±½Q¤QcKÝU`E”pÏ}ÆšØâz£AJVœ7yÖ<—H }çp‘„E£ Ý�f ZËøcû`iU€Òž€‡öžqüèy»%¬“^ðÈ3�÷©H?¾qnc'óÍK"ìo¹ Ãì1¬F^�î¿—(3B‰4XY¢±Eº°—�Y­,aéÒa@¦>;ñÆU´n��ö×q�Œ#:¾íÖs?¦ç:,¤ç)õ†IÄl‰GÍŽÝXÛÛõ7éÐÝ>Z%”"w-Ää^&@c¡›níÃLSè>�ÊèQÚ"<·Ô¢x†}xóÂc¦Ô à~o˜ÇhK±¡KJ�”�—9)ÞÁg)œÜ@zx79ãSjç�è!J)‹Š ŒUìØŠXäVù±^¢••BÉq”„Qeí\qN=ŒÞ€†!«z¬U»”Ö6s}+Y¬¬�m4±"ÆÈäœT™$Wc‘Æ¢ëô:›fÝä’X—Ñhê Åç·¡ô¡Q“Ÿ�ô-¸Vky5¥µû)Õ†Ž<ø,YðiÀ:²[ž3³ûUƒKaR¼†/—žeÁv²ö¬Å£rµÛÍ`ð b$Ú!eW€…‚Ųzo½tÞy}‰Þj9|âðÎJ�·~š÷ìM ï{ÒÕ:È®}BŸ{>ü¸LƒÏÊ©D O}¥üºH®AQ%¸é(ã–X†xæ0Q)Ô©†5Sw¾ïgÄ89:÷¦ö Åeï0F…ïmô õ¨š7F›mæÍ¹ °îö--¾_Ok ¡»ò6®%+𖇉-°ž=÷솩Lµaº…¡¥ÉvmÝ-WìIÑ]r‰Œ. –”fHó’k鯯ƒž9{ºòéÒ£KÆ 2úxÿ­ø¼/Z‡OÝúã|øìÜ ­øsÓÃpPgâ>¥«è#À}ˆ¾g¿­ÝÑDÚÄ.dTãYÂäA;vFu2i3R‰ÖΓ”¼uë¿4W�c†hT�§ªK «âÛÉR%/ê ü²¾fõ^ ÉŽ9cÄ€:šŒÛz^w)[uT_‡tåt+UWø[®`XÇUo^Èj IÀRNjsòvY\óEã{UŸx9šäÚ\;ãs3ÀU¬‘ þ_ ÔÝëQ�Oi?@¯Áôsÿ´:ï÷"n¿CRÜ›Ž=Hçç!eQŽRj�&"p•ÔÎ{̇ý¼BÆ.<“$œDìUlaœb€�1ÒY·Ô…¯Ÿo®cûð|ó}Oà; ¹1E"€7^^8xåª0[K0þâËðCï†÷K™4±x-Š| ”\Œêù½�2¥ßXdr̾èæîªîj€#%Ãû>í‹qr;�ZcÈ(¡œž„qÊÁ(e‰Ðê’ë³»°«¸©£È6Àº›·&öL,£Y„²DõQÒÞ Ã�[iÇßÊÛÊ d±*¬Hð¦¦`°JÏ §À)¥‹!'¡GVd¸¹ÊäšN¯x¥ô0Ê\ ðþ=xß—Ï_X†—ÏÜúã|ð£ÌÓ™l\Q×µ=ãkRŸôš´:I�ݯ½×ˆ {ËÁ)w…»3Ze°ì�OÎZLÖf �ëy¡Åü:‹F§«¬ÇpÔΰ¿Õfª®#3iÕÉ'7ЃkCä!TŠÜí�è?½Mשùþ)«ºOSJ™X*+´Ü ™Ü1Ñàw5|î³¶“áPî&¶$|n½³P}¦Ö雑„ñðÞKŠÂÙ9xî$sx“ÂWáÐî¡»¦É¹½ÉÁ½îÞ¿Þïn3XÛÛ-YMÂö¼ø¹�n»˜žÄ·Œ·àž‰­}xøçðÐ$ì…ÙqØ9©CJ K†“„5Õb tÀ“î—–0tÉÖÔö4•rDÃñþ\õR¸´§6¡1àÐnaó.&9\´‡·H*Ý5»)=•ê¿§£ÒOì´o®Ö v,wE9£�)4-+¤ôðk¯_ðÒ+jG±ËsOµs!?/t3Î(Ú˜Øì »®M»¨«õàß³¤û-w ˜Î0ð�vàŠî§ýˆk¦qU½9#A½#+¦Ÿ#a}r–Ȱ¬`l¦&'r¼2]-õ\®1W�Áˆu^n“Áp2‡NµÐýz‰Òci9b¯2´êé=Ì5ýNŒ(À)ìOBãÈeÛAeŒ�(3˜Èµšb€@JÌvIpŒ'%ѱ¦Wƒ®®bVñ«øÚ›°Ò‡/Ÿ‚÷}TÞÿ·þkxïp`: ~l\@՛𹗈ž7/_û¤örøÜ+òøÂ/Ãî)È{�Hn©äz½o|Ť büãh,h7x›I¶êËçàÐ.š¢™ê´A½�+~vë"ëúÖmÖfÙÞîî­îøâ æÊWœÝeÁ0Õ(–¼yu·Õ¶t ¥É%ï«MÑIX¾|- §j ÐUêºôl1 ,JK4WÞKës7•ΛÏÁéMX»¦ÄwÊ”Í †dhUOp±·×Frâê.ã­ã2¢\gKï RÃpÓæÜJÙIX €¦ÂBÔ¯I�1Ú,�¬&ÃÎúþHy#§GÆ@âdË�ÚäÚç´Bng´L�õ ×xx”£ ï4Ÿ}e¯V£W�õµs›q­b[†^´/MV²?¹”Îò.οqÍÊ`­ç,Ö…óת1ÅM¯8ªÝÁ.¹ùz¹«}yvÎÍÁ×OV÷ûçþOü§žÇŸº„_IáÄ9üð™‡~ —ൠ×¢¿~Rìgì>M‡Î{¬Å«Ž£ÍÏo%(:ï3€}xöÍèFIΧZÒ ®ìkûå g^£‹t3·mënÆU®ö#Wi·Íu]ê‹5iY#ÐYVÒÙúÇú¯^€C‡$ýp*ÚEa‚ÅU|¢dëé`˜ V=”åÃ]YÖ©Cé¨v¥¢¹ZXæêÅsðG/ÂÙ…[Œã#2Ì»ŽvI–ÚžPÊ – ±Ðv<*û\k7Ñ 4èbmË’28psº@»�á¥YY'¶ÒŽ�b#Çha ‚§Ž�óL�/ž€ì-zlâH�ÐZ{÷ˆZÎEÒf V¬-²k rú‘¸u|³AV=¦'o_�ó2uq¶ÃšN› IDAT¯à™ób_ë !óbt_Å&�±÷SÐ÷Ýlgd° ÷ê²TW�á3ÀI½VWt?¥ ¯l†tÕ¥œ¹:ü-'LdB‘qXÈÊ®µÝÊfÝU( :®]îõÑïeúÌ–ìpF�Ñ*Ù´G>HŲás/6¿–ã_8—W%zk$‘àåøóW%*çz·?þ|äI1�muÊ|Ä,Zó‘7<…)�½¤©þŸ³xë%¼¾Û‡×.Â^„¿ÿý„x7¨Ú[,E w0PÚÌЬ4nsÊd^Öû 0™qvì¦"­m€õvÃ]qØsµ“…\#ƒdý­PùUušŽ�–KR>f°ê5yK÷Ãá½Ç§Q|†÷å+CVq«+0»(Ý‚ÇOÁ‹§¥,xzVÀÕüàÖc'Q¦È7²#Žá�ä55×1Ça¾õ•ùM1X§¯¨ÐÝÍŸë±!v…Ò02‹TÃÍu«mDsU²4¹N~©®ÆÓhUœX›uX‹:Ëq;·�]ßðäÜ£E x nbO¤p�V"&+ÖäT“AoݵJ׸W–UWY7«õÚ—KÉìdCÉÌYšttÁ06”CÛk<æ¯E+zß¶z¦%É. ²0i­3sÿñq`£mØ5!¤gf…¹zõ<œ]ºþ“þ©ç�ßóÕ'ŽÀ�’EÚná'�&zU®p^ryíPOsKWú¢);uY˜«/¼_|EÇó|ˆ¥lÒqÅ/KÕh4,ä{[»Œ°b~Ö6Àz»À*”fM"ê4f°\ÄsäÒz?9;§î ºîø)xú ´ wÂ#™€†—mÕÁÆ e‚ Ë0Ê^|æê~ÿ³µ1‰•QkžÆ]<±¨ýzýëeßðvâ‚”:ZND¹™Ç8[±‰ŒJœ-Gmä”ú•›a²êÀ.öwºŒhxÎ#Ù“o*;r‰>ód,³H�U°Å©ÚRnŠX�Й9�ËÎÙÅÍb±™72Ⱦ‰»ZÂ$–{ñΓg!DÉÚ=dD±Tã—B·î^=¯á<ÔµIæ¯Õ b)–•a<§×égõº]©³ÖH9*Ía~Þh°U1¶8AÕñÃLd°@‰�{¯gAÇÉ„g-h¼¦ vÆTÎðGŸ¯²W�×§_À|äqé6œ]†ÿø8“Þ|Ë)üþ×äu;¶,cT—EQ^†%íl•!A—:Ͱ ~EŸáSÊhÎ"Y«ƒp¾òm€µ½Ý™^œ|¬bMV^‹€Öé&1wÆa®äâ:lbˬ»jðajlL f¶Ðf횃tÌ”˜›˜¼Ö›Œã×-¹#^: æ¥ ÝÑΧè>Íp¤xzäEäRôš¤Œeiss:ŸµB’{ÄNþDÎÓ>Z /’±"ŸŽJWáÝcYÓ�jânÐjfuã}sÚvàÁ'�9pNÇ�T=‘,}ò"!!>_�„ʲ¤¿‰Ñ¬®ý  {¥¸?²š±hÔÕ˜"ìü ƒÅUú¯_Zý¬1~¸òf®¥Ys|òµ.èÐ¥z�m¤¥5ÈÚŽ;n/öøÙô È ¦r>ÒÿÍëùéQ�€âr–t,éQír�M�·ÖövÝàª:�¤dÚ¡"ß·ÉdÉã­>Ò#]˜‡éö�q¨ÿÏŸÀ�½�(n!–xF½ÝK6&蕦ã»Õ7„ÐM�N¸™ÙðóZàêV ü¦ág7µ½x>>øN FžQwúNQ X!tJ:Y(Ñ…N·eD³ƒf‡úõ@f]—–õýguÕ´Wáû+æq¬²Ä€U<'ñþCxõ+"štlMÀ\îãí°f¸Öí—ëâû¶š×:Fe2J PjÍR…9qù/ø™…ó&ÁiJãÇ&Ÿ¬¦óà׸V½h½±WgÈ8­ßö1h˜RÀ;ð+}Ñž¸ŸúzsW]A•^Lõ(ªµÊææŸ±êµpµò£‘¦ƒ”¡®Ýú³éAʃ!^§}ÎòÝA6m(»yµOWM¡3úÀ.\¡g F£¡«tQÎY}?´e½�|ÎÆŒW·Ööv=«?yÞ*Õzt^û £]ywÊ–I÷ã0C€–hêZ¥Ð]¸áâ[GD®9Ñðý­ºgšó+ob{cþ§OÀ~ ÞqüüÀÁ� ôë:¬’‘ÌH‹²$—ÙÂ>_k‹¹Ú¸K°�ƒùèë%J£Ê.–‰&@¼ÿ�"I*S^�]¼•Ìâf0Yk½*›ëã³QŒs:nøÆhš‹”åÆÐl[Ä×`½0릮°ºÞj‰j^hy�ªwAĹYøïÿ½0Wo^†K+×ýà™Mº–k__þÂF€£ƒÕºgùùÉ‚4¦ÐǬå2eÙ¶E¦`¿Ú Œpç ö9¯è7sdzÛ”ìØm€õvW^)}1xëkä�ÜlŽª³PÆZ0:~çäJOëéáe#`%Ý\#äÈÚaJs°¤ËÎàH1ÖoM€UÐØ2˜4‰±ƒ©bøwV…Ê×­uÉ©¶^7™HÞøñxxmV^øüäwÀ�ÝàÇ éèggxz ´úx²‚Ùڧ줋+Î@ yx-†5hk�·¸¼X‘‹ˆ†çMåÎ8y~÷+74†Ö#xªÖ·à1gØ~ /8´0io ä,gïÌá©+ðð0ýÎE¯¸|Á6ÏcdŒàbqÁ¤®�³LF—^ñ÷)}rÚx?" KÛk{»~ÆÃ…´íD®q rãÚ¨›ÐG·h2ï�-©k°Êi¤, ‹Õª1XÒÝlÁaᥛv�7y½Ô=b6:¡7™nº�̉KðÄýfË.ýá*¹:é‡É5§s¨xŸGj «°²x �g¡ý{V¿Êê×FͮڑfïÅ`uFn{Fâí!N£1À[û¶«� Y ´VÉik|ÓbíZÕ¯AFÕ·°êK�µZl¼Nò5èl*÷kš‚íà»ÉÙ»NƸ‰I[ˇéf™byÏŒ7üÞ&Å·6 °€äe°ž{¾ía9kŠBJ^ŒcF³ã8žá{)KÇoŸ.©µsºxÏæeÇn¬·ÃV¶Œ—ƒUV™¬ZÓÎ `Ö¯#">¾S4XÝžt[KáGKB[3õ‚þ*x¨Äž?bQ±Ae ¸±WÄ HHè’³ª ŒCI-Pæm6&RoÒ¹Äyn‹ú³Š�Ì­Øž=yL´Á]ÄgßÉgÈéãéâó J›�G¶C_¡ûj’áè—ø9ˆÙ�PzŒÁU˜¸ç°, 1&2q; |Ú““¹Ð‡d:UÏr¯ö ÍîÕ�óø[Älƒù>WsGÝK), Ý‚ŽQ¡ FÏh“*Kòß‚7U¸FášÅŒãH SW1ÃîÇúµZ ,öÕ8èlzm‰A[õ8=ˤú¬%jd«a¤Æ;r ý;TƒõŸ^„x—xŽ´¤ &ïi¢/9rÎ:, V=èÊq,c@�”eRfÉyOï¿S8ú8~r`mo7:|¦CŽíå uŸv‹Uús5â»S6ãjš±ò¨c±ûZ¾?Åߘ-ÈA¬ô"èCÄ`%C«ü¦ü>¿&«i²­—+YDyn7»?{О’ÉÛ~Ÿ>Z”Cr½“û t6¢Ù ûÞ®±\ñ¤½ºÆ¤-¬ˆe X�&ëLmN| ÞüÀÀ—NÁûŠFT¯ÀÄêþä·”íØ p5,&Ï#k—ˆ ÷^;'`å=÷�éàM�û¢u~@N[‰OiºFi\Úk¬:s5±V1° º«Šƒ¼uIœÈŸ{SÀÕg7°²€—³È ÙV²‡\ÉkàÙlðüÇà6zï¬(úÌl 0�wä�[Y(ßiÛç_’,ÄïxD²;fðé èl/õ¦¸÷ltÆ«ìû€œe<¯ãý�ã½.Æ–á¥ÓÛk{»�ѳØJÿ«´˜€%à¸>a ìä±ÐîÜ9Ç|uA˜= „vy‹#¥�e”“ ÔíÜ1EÊ(¦’g¬ÁÿÆOÂó'ákoÀ ç {‹§Ã…-ÓÕ‡¶E®y`}ÚÏ—óÊ $Ñ$6Ű¼i°orÆ>�x?�Eô.¡ “ ‡ov;wN]‚ ”Xp‰gG1ÙÖ³U%NyÁ\f²îOT¬<*T™¿…‚´:a'Åj9€+RðnU¼”zxþ4¼ç�âY‹øá p"°V\æ6u³ÐµÃµSå¹ð-X\�NÃSGÄ>D ·åXzÅ}9Ð󻤠5xmÅRu«û’­ÔØÆ%,Käjlêè+;_–}Ü+çà»þÅõ� ,¯±LîWÈYÀª—ž0¦AW6VcKí53ñ"&ý9à2žKˆnmŽ��ÌZIí½‡>ãÒEø¯¾Þ¿ò£pißK%úìÊ¢x=ûüé7á/^‡~¾µÆòÕ >ù yü»¿?òhµñi_ï7£k ò˜u0ÀûŸ’†”ÍÎŽÝXo·­n2Zí&,ÿ—•·§÷•�fë3X&Ê>ˆg})ŽYÕ`U,3l˜8ø›–N–ÿ|~õ÷๳oí±]Y„<ƒd‡¿ôzf ¬Ì2¥ИNRIÁ¯¬=àç5`OlÁ¡{”ß ™‹³ðõ°{îÙ-+ðNö,>땬’bR‰³%M…½¥näütB 4>_¡¼´¬"í†�v'…œDŸ\ 2¸²ß8¥¾=áÝ7¦cË7È,n6sµÞþÌ )ÞMIÊÁâª0B «°ÃBÒ�mz4’{ÈQªfl$¤KyQªmÂ1‰�â«×©ì ¥4É·Ã" âùS70\fk0nv0Ç 9<ö eSÖ¥œ O—¤’ß7À�‘ààó vO^{ÿ/\‘xœA.Ô`ø<°ž¹¾ï)±KùG¿_:±µÇöçÞ„ï}Rí\J�…‚¬µ�¬²]©÷8>ï—àj3³c·ÖÛ‹Ìòµ‰³ÏZ]a‘ËZèÜA('NÃé{aÏL[]ÕÈì°´°Œ’3IÂ4f0Lá'«¬ Sg0£-|kÞs ž¾÷­Xçç ËÄ+*ëB’á!WÌö:sJ+‹À~]e�ÖVÙõÉ,€ªÀ^�N#Pg”ͺª�è[ò[Â/ÍÃç¾*ß?q ï�}Í!YÆû\sÏ’¢Ì�áЧ«Ïsäê㔯ÓE˜U˜:Ñh¸ÊD)_) ù›pËø`RÙ¸úÓWl¬ö4p|P ìÒ±›TDôËT#‚1b|Mnט@f]ST�—ÉéA¦ñY¹—ãþË×$Úä©£05ªŽü|¾ ‰)ÎsŽ!¥]© é+½¶†šXžz˜pOÍM´t?s)k†Ò­ñ2‰žŸƒÏ¾pý'¨—ªù­‰º#åü¥]È�óÃï…&‹agw-b|Ñ´±„+üÖÎèë‰æ(õñjá9|ßǪÞw?ýnÌ£aŽîÆÜ¿ŽLÁÌ$~¤]J?Œ.¤Méaæ' þ‘ƒðþ·>Àúò+ðòYxøkƒkásijòȘ(Ùi‰jœB/ß³èõai.-mnvì6ÀºÛQ•¯ ¨ImÅš–«ò¡Õ–þËÛÍ�¸Õ[Ž„†¦ñ°,S—t�dÊ`ZEÎ×°g’ lXbaz ?|ù­=¶SWdÐo9pñÙ9Œ3 6le¥_wÓžÔŸ…<¸¼6™ÕÁwœç¶Ta ¤¯¯Â`ù[¤Ó[Àg¿*,ÖÞp`<~ž>ÇvÃÁØ9)@'I”'©C œzÊ×:åKÖš¸ëš—²­ß‘ãDŸèW$�vÌ­ÀŸ‡N sõõ“ðÊE)›ù ²žæ*݃ÐáYjwR†Ûüo'‹å×/UÝ�U–‘IÚN*k—ÂÙYxîŒxI½û~ɦ{ò<}:£xoÀ̬3ÃçÄŸ—&ó-7´Ÿ†”\¯U‚Ïúxcñççàõ‹Â\}öøäs×’–ºEÝv-]b=q…²L3¦EŽ`4LeÊLõô^•ò£¯¼W§,ª% �Þ‰…¿ûmП„�`’6fÿvÿnìÞIĮ̀ˆÂ[é /Óf£ÞYëÀS÷ný±ýÏ^‡_üøÖ‡D“uïÉYëȘ˜8¼Y)«¹—ioK«pyN_†çåÞ8½ÉÙ±Ûëí°•iä¾ ía@ª¬ª¤ ´¼ðìÖÞ9‡û¯ÿ7àÀ ¸I muan1¢å£²“ÐQ#:`f€7ï ¾�à�íÛØçwìƒÝSâNþè!x×}ðà~Ø;%ôöî©ës�È…ÝñË}ÑI¤¹?{�Juþ—ÿ>÷RuŸ/ÏËó’´ñ¼¤<ÚR¦éÓ¦Kβv$Î*;8¡,G˜zÛ·a<ö{b€æt.ë¾-Äâ–Œ6Þ'¤³–zðÚEYÈ|å´¼~öÛàØ�ÁN«f¿3ø|Ü€!«L–‰®Ñµ÷cP<üÕ [–%`<~�‰�Ý·Æ|Ëaø›ª½›kø„ÚÏR`qIÖ¨™-¢�DÿWÍ] ×+0QW);$…Ù25\SÑ]-ã™Ãp™„Sx.�ršç0\!a�–ÛzòÕüdó·ë<®çiYG»íi�µiµ:¸©6v´­²o[dÎj5ur>Éñßþüg~ž; Ÿû†„E¯l±æ¦~_8!¯;iÛXw3ƒeˆE·uMÈpgS,· ,gwÚ…~OV.y.�ÅTtX†D¬°‚v «M¬�ý3Wßö|à�ðä}pß8´Cl«3ÈÚÜ„i˜TŠmït$šÉ…) Ì¢$çÊ�HÊ‹°äØé<Ęԭ âò`ébn˜Ã1¯îØ2ézz…­Gªw�6üü÷K·R|¬Ù°Áµºª*¿´O�ûÞ=2¹ç™”ªÜªæþÅx,/Àes¼�i<¿ÍNøŸe`W\¥¹ÜO—„µ:{uxçÏ]�¬.�|N'å±ba3X×¼o6‹U¸-Z©ù©í�GXÊÕ>œ¾"`·¾}ó¼ü·Ñ–x9 v>[Õ-) o(Öãœ6²ÏÃ×Ìà3õåòZF~Öm¼»6tÿÌŒG?£CJ^ż’¸€öÛhÌÕ®¢­£O(Q§9ô ¬X$aÏÀÒˆ²…úÚ,JPÖrw–À?ùüÝ>|`U@ȃ"c·E̬eà  ˜Ä3‰cŠŒqªÝq©ÍÈs‹Ÿ»öçîpõÝOÁÑ=ÂàŒ:0ã„#©»eÇù�M$Žr+à)7FF!noM¡G «è\Ô.R ÎÖ!«+8hÇÖõø‘erq…uÁBÄjôè3Ð{Iº´€ñ™P½Ã¸0‰¥Ø¤�hÁ©:©ÆlRŽxvÌ’Qèä >óøA ¹·Rj0r+•Ó_Ã,n¼Ø¢,2•ÿ[ð^WïÝ ºpaNÀÕ§Ÿ…ssÃoqê2ô»Ðê€} Ï'1Å«oV`gÿ®˜½ŠA•‰ööVƒ¬¸Ü�—ÿŸ½7¶$9¯û~™Uu—wßÚ¯ûõÞ=KφÌ$‚¸„IÓܵP”,Êa1¼H´MR¤e3B J”ý‡l‹![A[ “â*J¶lŠÀ °œ}0+¦÷õíËݪ*ýÇ÷eUVÝûº_ºÑ݃›3Óèwß­¼U™'Ïw¾s¼ö'ì-4vX›+Û >þ¼vyôÍ_»,ÿÀ±E˜nªÝF —[qäÖ¯ÇDÙ—w0^_“‚wycJ mãÖ®AåfÌ2˜y 9­ZéÖèqÌ�2 ‹Å(ÏÙÓ9»‚¸Õï05Ë`]FžÒ,£‡aÇZœ³l#®2àM®és·Šeûâ5ÿ÷«ä?úäšþÇ¿†ùÐãD‡:$Í„¶É™Ê,ÓÖ1݈˜²Ž¦µ4,X‘WtÝvµüX6¿¤²þÇÂrkp6Á_„o}|°&k2ö@çP–Màä>¾“©:¬t döÞ»ì�®´3”é±€Ðrå²L�Zoj®îÁ"l�:ÿ�ÆþYa®N�Óo#i%ò ~È–�3ÿ¬3�¼¢+‘M$ ZUu�H¿v-.øóë¬êùnòß^+RÑ EM K�­2VÕk­_o´ËF·[7[^åS…M´>ÿºü¾ÅÙÈ›1.ޤÀªc…1ŒîÒ â™Ú�°4ýTÊ`×6%§îå‹Î/ suq 6cÖ lw¡iÀwâL¯Ð0�ëÌܹkt‹AÖõ­½Ž¨ £Ym ëÀÿð[ÂR½vÎ�‰9¿ ÿôcžüС²\|t,jɸ%zkMø™ëÑJ®ÔÕ䪱Ì2a‡G<¡Ü˜{¯ä Æ±›õÚ,xîòâÉ+«õîÆm¨$Cx¶Jž+C CB†uç2ÒÔÑ5°úq¬áX§Á–m[dd§¯’ÿè?/x·‹M ‘sÄQDBFÓE´í�©ÜJù?�†+] E…ê*lu¨ÿËÖ×#,ôS'&[ç`MÆ ¬¼¤Gvë"kéÍ$�¸qï]ûÿñ ¡AN,HGÍÌL©2bbšêêî½læ�uRzêß“)Åï\ŽiÆ76…<8'eÁÙ¶‚«6ÆJ™!+ºŽH‰Î¿|·›ãJ7]Ê’RŠ#‹ Žä]œÍ NH>s®?ŸW46- ­ñ%�`Á¨_“l´}"úD +þBZHv¾5_6KCŒ‰³bc‹‘ÒdK�wUÛñí˜ ¿W{UÊhœ�p‡çqŸzþÍçàß¿|wøøœ[•Τé–dF˜éÂE,ËJñ}çÐÚL8ª~e_.Ȫ›zúH «ˆ¾î,pÑÙ]Öû¥`rs¤<ûÏ?yã_rnS^ôÚ­Ÿ_kàø¬äÓ=|þÂ{ÅÜ5ïcârþäГè½ÖÆUî½Ý²)ÅOÎ÷]·¸÷äÏËèS—.ã´l¦H˜Æ0…¡…%I!îí`º;¸�œ~¿Ç¶�µ¸År§Ãʾ”µxŠmšôvÖv~¨ÐÅúµ!i¸.m×aÚ:æâ)öÇb’°oè˜kÀ”s4‰°Æª\zìõ+ø¬ÆÒ¼u �#·–üè¾Éþ9X“qC€µËéu¼ËàJÿ™9ÑûÜ‹cËA–Öº ½2¢Ì%Œ5—pœ³{ÅëFãñc¢¹j‡Ì•À%¿˜ûßѤlï®·s‡fš1¡hݧ΂É2Æï€¸<-½äj¤YmY0Å&Û`Tƒµ›>¨îTí2pVÁ•³A0vª3l*à†npb(é ö,Ù‡€2uF¡`²N€#‹ð�ï†/ž‡Ÿøå;ßf~nUÚ¾çÚ°¯£j–2˜;ªØ"ì±MVØ"„q+)£–odí։ׯ1i¡uDE6àò»#Íáø,üÝï„o{\4C�¦”¥óq¬iL,á8´ô9ë0Þ:ÁÕØ¨ð™ósf +«_û‚gm†¨R—¹*}ж0làô™ëk OÄ&ÐUGÿTÁ²Xªžj>ÆiCCƒ„–8OI®®Ñ8¿Bòæ:ñ¹Kpe‡Áв=ßdcqž�Çö³óàqú›;¤�ýXIÜQznuNd¦Ùd¡aÙo�á°�8dKDÌã˜2Ð0em¨ÿ[SÖr9`,—õ÷¬ù{&sêŸ5€57`°B#.Âg«®Í®,ûè‚Slõi®+zûÞX~\¨ô)·ª:Ó²X# –ÝööС²ƒ®Æ\•lК)ýj÷‘X^]�Z�é÷&ŒénÛêÂý‹âcÒâ»Ïïöꩼ®�²;‘‘içRQ6΄¬r9�°ñXöÀ×éË3áµVÛ׫«Ì�£^ÊCƈš&Ëûøšg¾\ëúÃÞ'Îè|9}æ2�»8xfJëo/ê;�æ ä$ ±âÇ–;’­Œäê6ÍË«$o\ż´ÅpÓ?fMIç[dû6È_]é$-¬FFb,­Ü1•;¦#ÇŒsÌa±f�¿¾22Ư'þYób+jO³­ ~2Xq4Ù?'k2®;2W,Õ¬Í v"+J=­Ja©£�e,]„ÓSðƒ�¯_¹÷æ`uúY ` ¹ž c¦êÜb^Y¬ ›@D*rÕ½„?/Í+¡ÿDô¶.îû€cÀA}-*ðÇ`mSf ^®�s…ªWQ=y3Æý΋pä}``ÛbºçoJ!+\ßsÈ­ô€Ú¨¡hîD_d-äóÍ•¸Z§t0,âXD¼·–€ƒÄìDZoÌ&G:ü5¯×}¸B\\÷Ž1d4Éãîþ¥»ÌkCX[†—ÅíüÈd}œ£!p¡O‹ î.eöã’Þ Œv}Öµkã¬=ƉØ}ÓšÎíU�Wïovß=8`K³ÝRz¸´#¿õâÊ�Ÿß—ÔÁÛ‚í+K,år_vŸæ‰9¬ –u>=cìýî’ÀJ5Ín §Ï\ÌU —q\Ðïå ›Dì€Æ'y·zY_R=ô¤z$X¬x}õ6°_ææXš‰9G·–£Æq˜˜ýÆ1˨Ç]Ø5º ÷RGŸsŸh˜Œý0ÊÈ";Ù?'k2®;ÒLŠ#Â:”¡€”˜Tÿ=ôÁr¤åÒ“g0´²ºß“s`u¥ Ïô¦`°LÐIXÕ`¹¢HZ÷÷°¦[ æ™+ÿþM}í‡Àä´,¿×sØ|›u(Ôe¦ ßó^ÉKÔ‹ÊNᲈSÙ¨Åa´ û*ð2\&Z2gPWä\SŠ9ưWm\„;«rW„ûÖK¢~�O¨Šüòá¥Hy@­9ÓwÞmãÜ2¼ã¨�ŠÍ.#º å�³ª K¨É »ÒêÝ—ã¬�¹òìt¨µòóè­7¼ýÆ^Ð�‰™%)9«¸tì>Ü /:·;=Nìf¥vá!Kœ-\!2Ÿ ^3”åéPè*÷Ÿ©°§] +ˆÿ[“”.‘ºaùA–áÂ'#Ö#œ¸µÖǾtžì§ÿMeŠ‚ß]èÝ~õ•]Ksæà ¶Õ Nr¹£emçhGË9𯗔]q¿„ÇJ¿–Ìê÷½{ȶÙÛz7€õU=†a�H„#&SºÛ³W;„Ý2)ÓZ.T`6“Àá‰ÀøãCpæÒ½5ë=ØòMçU‹Cñ¨–´B)c¹‚1(�¸ˆ¥½áhJ+“‰.æó ªG€£úOÏ`MSæ˜ÙàÄé;èÏ/êâØªý½4²Â—-ÑÊlö KûzÔV¯¨ 9JÅî¬×gU¹átÈœ8vRØÀ´äÑ™6&`écIièb½ ×y 8!æ Žý”z³Pej§lotº¥ Ã3|ª`6`²È!ŸnÝ}š‘W.À·<‘@wgV�6}úªáqzðñLò5e––æea—¹guQ·éu|ž¹ºR¼,ˈ¾O´‡–))o�»ûq6‡tÖ¶áó¯Þùù<4'ì•éþVMõ0KÄ}¾Žé}xRçp>˜¿$¸÷B1{Z™³Œeeag‰9£Í0–L[c„¹¹ÍÉs'.ò&Ö¡®Wàð�¿Ëßãõ{¿”kœ1Áà7þ6æ=ÑXšgª™0[àXÂÊõ§×ç*åOÿõÎIöÌ3›«Å}e1ÆL4X€5×½¡Ö"…QMÌì?§ MªOþËec Øš÷à䩼Fœn<‹EE‡µ[&ÚžJ„5Z½zª.©ùé€Å™bÔ“ÊŸjC-’_øýÏ5k›¬üþH³~ðkŸ†ù)‰ šïˆN©™»Yœ÷ *¨¹v‹ Ry�õ®”¹.®‰‰æ·M«D¬±©>gÂñæäôpÑ×á¡«�¯]�kÛw~>‹|«È™L‚çcQYá£zÿ�Ðgn^ï§ä:Ì5&+d»DTáHU/—Ó/,mr Ï-&w¸·úyê»áƒ�þ$î;þQåwŒ )pïy >ÿRõÿ{ñáØÍ6Kƒœ6ÂXuŒSÆÝ�Ý!�ó:I/ê÷‡—ðZ#nÐø`MÆÛc¬í¨ 냕,–—k:r†ä$ºˆÈ™Ëĉ0 ÍäÞšƒAOJ\éâ!õ†wÿ¿VO7Û_XãO�á‰Ñ›‹z' N–vÌ‚›ëÏÆül4î³#:•Ãó·~.gZ•I1c„¬¶ðX÷3»¬°lÎY;`ûª ˜rXw£(÷̲¸ÀϵÕÙ?†h—®B,@!'#%Â`èÓ &'ÁVJ¨UMP`…Ì–ÿ{u€åÁø¥æj‡ˆ1} i+pà\G²w†pm ^]†g.ÂjïÎÏg+¹.{UÆZC3îÞ«¬0²* ž–BºV…ñ1¸MÇü×.Á{OIÓI²Â{=üo;Ÿ_®þÿ?ò~ܾ‰ÒÆ#8´…ÖÊíi½2ŒOWxËëÝdLÖWõ¸².âähÇ’.Ä&лd‹µ]¼ 1,†æ@q\®>O?wï86¼~67 7€Ö�2òØ[(¤‘{µLèÊ |OÃT²°‹Ð·‰ÏSÕÓø{\TŽ­�¯�n�^“ÔÒ. XýyrMÎÁÚJPí-Ýàò¼È,uf†,óÊ",*;z}µo®Æ-_:ñf§ ½ S­«ÿÿ])Ê=¿ Õ<·GÃ�Y˜oA4‡Kß„xÇ!Zr2Dt] @eXC|½ÌZ[tk,õŽ+ÿß®fÈ9Dž&¸èi\ÞiÁË«ðâ›®>sÖÓ;?ŸI™6±*¸hê³äuŽ^·¶H©»òLè^ï=ÿ÷2½w· PšiØyÕCÐF�GcÞõ…³p暈ó› üÞOHMªŒ‘ëj7D7ùÔW~ÿÙ·b–æpÆ u¿sÁ:ãÆFÿìh¸éŸŸŒ Àš �.¦a±®àÌA嬲Boå;šR- ¦ IIww=k¡©Ý„÷’ÖÒY—…Î_áŸíqi1oé¯ì¦ñ«óÚågoüóQõ§Œ‘ûvlp•ßdFX„$Øüë®ø–›ÛÆ1cMÝf|¶Ú]­YíÃo|þô8±ßöü'&ÐÃ¥ŸÅijz%ÞŸNÊuu檧öuVFæ  °<¨ÿ³4ŽÈi“§³8û,.ëˆ)ïÅMø…§áÓÏsµžJèõ�Q5سz�˜B¿Ö`|"ÃÍÜ!ãî¿Fpï�”¹íõå+ð¿} ?§Á¡yéöõåbc„Ýœm ¸²žÿ9Ü?U¾ïüœV"]¡C¿BWé½Ñ7Tÿ»yíŸQû`MÆÍŒ7.ÃNOrñ"µ“¶}Xi­kFrø6°Li™"Âb=O2—À)ø‘Â/~òÞ˜ƒC³0Õ�V˜øŽ&9ƒ]¢ƒü"vó›·Ù …:»¬6ÎuüÆ¡p#CWDì·zøM0ØJÞ {Qq) ¾¾îêz×_¸WsdìàX'Vß0SiGßU#—˜‹a¡‹xèªÝ€ƒs:]–ð2¥ؼ¼‰ëi öÊ6\Z“rê—¤óò• pn½q…D*ÄÕûCH¢"5À[�xÖ*ÙãafÜsçKûž�.óGSƾyæàÅËò7??öJXyb‹N_žÿ9¹õZ 8ºc¬®C®0@ #ŽºŒú¤ÕK�¡¾¬Þü°€î|²kNÖdìq¼rίȃÚ¢‹ÊH¥�+#ÕÓ§"÷!‰†šº¢�Ü] Ýν3™r¯`ÈŠ…+ ®Â�òQ_¢#óÛ°TŽ)ÃÕAd4†±z«å‡Q€jjಚ�8\}ÍøúãðÔax𠩘Gñƒˆ¦þYV”½¾ÒƒçìhV^GGS¶‰s=01Þé•58{UÀÕ~®®�~þ'� ¸:<_”‹å³ºÒ¶×˜ñºžÈßÓ±iš83%p%Špñ5\#R¦øÝ/ŒX&ر\åþHöpÿ½pUXÃh¬`Ò·†âVºðÙ×äß9ç”ÍÒªcûÄREÁUè�·Šxšym£¡Ú…[·¡ðZFïyuqï¿„t–nèÚ’RµžŒ ÀšŒÝƹu9 þî$Çëú+�Ä#ŽÏÕ¬»! )CršúXÇ%yl,˜{ˆHÎBÝFÙ£æ´o0/\í}7eT(µÊyJ÷¶à¸*ßUÏ‚ _7Ö>¸ë¼Gõ3Fz®Ööà6Læ�Ñ9™àeØ“ âBK˜«‡áÀt•!Þ9sa'Y°òÚ÷á»r±V6ŧNÜøó\ëÁ/ þäe¸o?œ\m΃‡áÈ>X˜�…Y6{•`@^> ÝÀ OÀ«v gêi·…ËÖÀ>(QGYÛ[Rº¼² ¯_…gÎÁKàâ²0WW×¥‹°>?&ÌU kU+á�›G³Ëý\Îc öö>nG÷Ézõñ¯ÿ ]˜›[|ÿÝAø ‡O½.,ÖâŒÌíBGÎF ÿôoâmB½Þª<f•ðòb~WX)¥þ®^^ôQi•5)Ÿ¬ ÀšŒë�ÜÉ)ðÌš,Vÿø/U–¨ðD´LkáŽitЦI®:hÃ�œ:‚ôê\»ûçàäL…ÎVq±Œ”!¯Žm`ƒ” œèâ1Å¢³÷]µ¨Xee¶¼K¼oßM#:Ko§Î«ú]mPvÐ ÐjHÉÇ[¼oܦpÞ=‚ÈœjÕͽÅMiÔVä:àÔ¦àä~¸ÿöüÎÓ°9½˜«=¸zþìÂèÅ~ï»áçÿ:[„†{E˜Ólbúþx` p˜�åzG¸læA\ž‰Æj§/]„ŸüMøä›×Ÿü¦…÷Ÿ‚o|D´ßqLƒ–µ{­è&5Åœ%5F©êÓeŠù“ÒT¦‡…ˆÜ,âÌ—÷¡“á~ð}ðà~xî üù›ðüÅëÞÙ˜ÃK~‹x˜qò�[õÞ r¸´-¯úø_þfÁÖùµª«ìUCµuÑQmë?}ÜR3¸‡={µ¬C—€ À]SVõ=Š£ä`MÖd¼ÀU”ä4,'¢”�–ÆzVS’¬”zgþìÞ×Üë«©ê—, –+Äþ¥&!ÛE“àö8¿£ µYž‡ìîà\gë§ÕAå3Êõ-KâM–‹Aä-W®ÂÖ;’ò1›Û[éN×í”ï²ÑU~èÀüõo‚�< „¹)˜ŠJ…}~Iÿ¥ c: «åS±ŠH©º|ûy/@äÁ9rOÝz§üÙ¯îæ.üô5)ëÏ´å³'±0EѪ²O­b±.­,Ò1ø7]“mãÌQI2H3q翼Ï�wþ�÷Ÿ‚üWá¡C ¬¼ÞÊUPí8—ðŒD¶”÷³)€`ÈÈïÚ2ð §ÄÜx}>÷:üÌoŽÜH{¹?¾œî¸Ñ{P¹«ï}�H¦ßc4*èbXÖ…MÊ�gxŽƒyï lC_› ¸|TZ±ž8]C&c°&ã&ØÜ€�ô!šyQ|4ˆ™"fš”Y,s8¦Ò Ñ‚ˆÁÌÎb>ÿä/Ã?û¼ôòÝ{½38uff È�ÏqªLâè)cå³ÚVSÆ�‚2o`¥ºx­×6ÿ‹_èXî7ußíãuþÄyAÿ{+d°2Êl�AW7n@wñË6À©—Z^ø©•ù–åb³¥•<§~s(»žâ¢ë©'÷ ¸zò„€”XÜÃ<ÓBô.ÕìÄÄD4°´(#‹ÂØ¢;Æ*¡ô“° PŽåˆY„;8�ûð;o`�½}Zþýá#¢óeÍÈ€ÙÑÈHWT‚«³åïSE”ÃL v{=*×\ýþ‹pyüpÕi*kUú.U�©¥Iië_aBAɘgt‰Ø.²PÓàÀ‘‘Æ�“ã¬ÅE .™�¯{Þ}_ð 0«çWúθí1‡�œ½w† Í­ïï�êÚ“©µÆÞî›ý:eP»�ŽrÁwˆx­PúÎ…�Öë�Ϥ ó(ýz·IÐIè4.k2&k2nb¤Þó)Ö5ÁÕDÔ©º;S°X)-µ1 ­ÑPSšlÀKwñõî›×csªÀJäŸÞOÆ»Øq�Í ÐMÉ’dÙÞºòÒ¬ ê –_¤·ƒWiýOšá¦ÞÓE½€‹íʉ3×ΰìUÑMd9lõàÒêm¸\Á�Tu|F}Ô¨¼êåšPÛt3›\É0Z†jµXop) >xPÀ•× e!×âËYQÁ´„.ñõxžzðvĨ˜xlçiÁÇo~~Wºð/?ŸxIÀâ‰R.<² ]f^ŸÓŠÅ­?ò!ÞNÀo–K7àÎ@"¢.¯Áùe8}έÀº¸&àjkèS'…¹ª±V%À2E90XÓ5°jk÷tT€¤Ø'ž QyoI*�6ï�'äKö n²BÔŸi·äõî½°¤}#£ÑºöÑk4«ï�Þ<Ã}³c«‹3•ÏîדmÊè›zºC ˆÆ,±â�MÍYô!ãM§±¸ÍÞd¿œ¬É¸¹ÑLG»Š\P›o®ã=fh1‡cGS›¿1M"âxŽè1ƒYhËðáwÀÿ»�¯ß]×ú_~;|øIxçq8²¨ËPDFFŠ¥Ï@ý¿«ˆ.á °LÆZlDáâ"0S HÿEùþW7pýTòÚÖvÄËg˜)l5*Ü”=«3Ðçâ­ãûË YYüÖ+Ÿ Îé¯èÿ/,Î笔úCqð?¿r{zäpÚW²;6°¬’là‚^—g¯rFu9õÍ ª¥ÑP7r%˜‡Mj]OÎÁ}d3Ž­�<ÆAÜ,�tÆZ¦)}�—¤– X4¿II¶_T„'o¬Ö †4�àäÜ/þ-xæMøÌkð…3£>YÖˆÎè‰ã“rê_057S X˜ÁÄál…š+s}úÏWq[]¸º©¾]o§vñí2ÀBS¼­N, X�¬fOVË€- SÁ\†)³”ÁÞ�Ú<ÊA#Ó;Ϫ~¿k¤Å¢§œÌ€Ë ®ãYPÖ2ײœ+©0µ“pݦÁ3QË”‚j_&l@$X~A\¡#,NŽË­üîÞPJƒ/œ… ·`õ†zÿxËSÜ?¡Ž­_{ùR¨åúa²õÐÝ0¸XÊs9]¢Ê{æ!Àzà 2.¶R®­ûù²àL°ß`ùï#üó¬Æš ‚ßåÌÁ_ù |Ï{D¨ýSÿ>ófõ‚Ü?õýð��Â�9ñ•ŠUçdtF²ñÞcÜ`‹qtÜ<äà½Âw ¼p~òWFm%šð¿¾ã�íst±Â^™€ôšµ¶Î[²¼ç¸a�j9¼|>Lqð¨Ì£Q zdAøqÏ—{ßùg$ T·öªÎZÉšXjTÃûÏys;4KÏŸ�¯¹—E… RRm,ðåÑX¹y?ÏÍ Ná×)sšb é3T j†™�q¸a&¿{œ¦±•{j•=-výòsïŸ)gÔQ®�ƒT£Ÿ{~æ·àÙ‹€5o£±¾-G”Ü€íéÃØ,ÏXÅ=:´iⰠɉ5 :aŠ˜&3Ø¥vist-ÁÇž�_üã;�í=ðý€¯}PNáL œ‚ª†.98Vp\.—é«&!eCµi©ÎŠ%‚(.=ob*L_½\Ô1²‘$Á<`XòH ,]6ö©à´ŸSwا–lìU 8“ãvúðÚUW{zo"æ››ÝÊ•ëRï™�„\»QK â·çUmHÝɾ^ì+SäýzÎg�ód\Å‹sÕ@Ãop÷ÐÒ 7‘ ¨·ï}ˆfå°¾êŸÍ×X—z9p0X¨e\!â<°ŒáІ…ô∔ˆÜµ`ÎâÞyBLIëë‰ã®Ž, À&îëó¨Y™q¿b¶jˆ±¤c2+¥-‹–� y¡×Šq³÷ø1ø†1¾]G\½÷q¸o&`zõÜò냰D–EÀ÷Òy 5@~C@êÁ²0Cò]ú޶Kú}'“5´�ç·0-š$k‹Jÿ~ÛT�ÿ}©²`|Xzø™Ì®‡!¯ËŒ¹\ÀqÇyà"1˸ƒê¤CóV��?/,üáyHÎ0®Ršô@oÇÐ$V ay?†eö~‘¥h´4(Z2çtEd²v|üù]4�˺Þ{¦¸ —ûØù{/B4uq ©›¬Éx[�Ë?·U–,ŠQ'‰ŽfPÐø©ŠPtЧ¥š,S˜6ˆI Á$‰‚Š»`4,4rÒÒ¢›,‘f/fÊ\I¡´«±¥�§üÿ"nïf3&­>ôñ)˜ƒB¡ž�%¸à-¬Â¯ê¦ãV”¤¶‚²TÈ^U¬ œƒKËðã¿$ÌÕÅ5ؼ >XW7äþ1=œiéâ��e›¼ÏÎvÀj5‚RM´ À 5k¡¨< w.�`½NšÉFTs›¯o7kìÕ|À`uÖ¥°Rª­ï.3ËbŠÕI‰mº%Ý…õñØ1a®±è©²Q¦ªê�ov5Ϭßk†ÑÕ·«ÓÿyN, s5ßѼ<3fMejìÕ¼Îínó8¬1XCýn7(…ñ;ud¯±õ�ŠÆÑíÊt–÷ÌNP& »@Ç,y§ X¬?ï*ïÕ+ÔÒ ÃE©DÿÜêñïž‘~è xâ<|öMK!X†�5h¦1l¨çþî?Ž‘2ìʼzQ˜«�?¿ó |דc4�•»©4ê YGF#ÆÊ`k óS"ÝàS€5o£ñúeø–wÈ¢ïÒ¢›0º²ãmˆ#bHNŸˆ†tH±8š$Ä4hkagg1€�<¯œ�?y~﹯ìµ}÷Sðæ_µ IDATÀüз‹ãtsâK“3$#§�c‹!«À†EWÞYú\VÉØ"¥O�œv!" #8 ± ŒI¥D–›TNl®!éçQ„ø†VñÍH¶c^åKXÛ>�Eb‰�Çî½Â?ûaxö |öuxú¼hköÏhN¢»ŠaºyMý/Ï\Ž+sõ@°B66Ñ~~ügÜ<ÇìŸ�æÑƒk&¸k[p È-—ùò—¼s¨ƒÒ¹|%(]Ö›ª�¢NÙµ˜uˈ®éUà2M.Ë86ˆé鳜ãÜn‡(|k¿ùyyüþ߃ozò!ıüî`]è2>9a·€çpiZ–#¿õ窿ÿ¾¥1šÆz‚ƒÓFSùÎ<3–à.7}Y îCï„_hÉý÷¹×á™ó·‡œ¬ÉøŠ�gÏÂÆÄÓ0ë ˜²›§Þñ¶EªÝ&†m,]úLÑ"%êÙ�Åàb ÍÓnÂL æ§¿ò×vúUhŸsDëÏP¹j¯2Õ]å 1ôÉÙÑ2@ØI3ÐÁqµ.ˆßpÅFZnn±ò¦_`À‚ËÄŒÑÏ/j´XžêœºÉç…•�­�ÈC=IØ=W‚+'¥“gNßþ9~æ4|_Wލ‡K-&Ï>y[…°ìVïÌ‹©z$…÷ÞFPݨ}OCõ(Ï}™ÖYÓζÇ2@×뜪mî ãubõOÏ’t æE§C£R¹" Þ>0+àꇾ>ò„Då,ÎBìûÚÒ€)2„&†v0—­1Ÿ3œ¿ºN,Ór‘Ÿ/,òûOî`ðÌiøé_—h–v#õ,S ÷öŸgZ�³‚á<Ú]X_ fð>õ€ðòúry®çbaP’Lò#)æ ÈTÌPj�ä¾é`/Ô|…ó—14;Älâ íã2°Šc[9ÿ�ÂßÌß{©Xf°ò¡>{Þw Z \:ÀÄq4ɵ¤Ê3Ž–�ë`Ë¥Zrí èÔÇ#‡Ëûá:šFX®b3“«�«±[Ä<~\¬H6»ðôiøé_ƒ?;;X“q�?û|áMNÎNÉIÕH—œ?oSf™õ‰èáè2¤G¢ÂÈ”nQR1´è�LuˆÞ�}ø8fëQÌw¬À�|PÄÉ©}F™«�<ï:Q†=sÅai`Þ˜9 ʘ ˜UJ™¶ú˾²‘§ãwuº‹rmz4Ј…Ç=šû^ZËĤòœ‰aÁâÞuRtY€5÷ôxîüýß„¯½_Êhé°¦l—Bl°XN;ßr¶°�¡MF“˜„ˆˆ‹Áê¹Ù6¤m×$1Ä dÃÛ{M³ ÐH ÕҜņ.æ99¹ß-˜ÓeÈ6Ž-Ò”P6Æ2tD˜ƒ¨8•OÕÊ2GfW0T”‰Œ•­ÈǺ gÔÑ3F�ÂC`UlÚÎI·Ï¹kðê%aþèEøƒ¯Àzú,üÔ¯Â{O‰GÒ÷½GïŸ(Ð*9Õ“åE§Y£¶yzŸžºGRŸ¬`Ö$¬ë½·£‹ö°VŠs‘Á¥¹´�?t˜º_St¼y«°$I­\D \Q\¸5 ÖÆŒDÅ€¡?ÝL¤,xjIÀU#ÖûÃßQ’)(˜)>¯·5cÓÁç;»”�¨! :С¶{lBd…u~ò„tÆÚ¨–Õ�‹ÖME[C™ÔÊSã:Ãe?�ãÍ^ƒ÷Š6%B¦E>»…33HVã(ƒšÔJÖ&Øüeý ïGÇŽ®ukÅ˱A¤à4%% ü×"œ»*@e˜Ã›_�ذ�¿?ñ+ð­�Ë!çè‚”[‰T<óh¤2Q¥¬œxù¥¹X¹ltE¯ùìW{aô÷ž—{4àÀª³®Â ·}¸J€íŸï!Tô¬rÿErX{òÄÛwß�¬¯’‘:øóóòøÐ“2jRqÁ<äÀ qÅ€³KÊ&1kô9H“¤ì#bž„i"¦04i“4D÷Ïbî_¼ã8æÃù51;|ó<œ^ƒµu¸Ð…—νµëX:á$¼çxçQxøÌ,ªsW¢ÂkÇÃC6鳊á¢z4½A�³HgÚeÝÄ·GG»(e3ó§Þ¹`S󥟶XŒ—�,«¶hH+†œyò¬/ÜQ—ÆZRsä…ÅÁ‘wN±~ ¿ýYøo~í+{ÿ søÜiy�t¢-ÎƪC-}®=uvßÐ9öÊÑ!®”¹J€±€¬ ríštêÞ^³gH{`Û"pý2|ó;Š­Ô Éw·O™—¥€ÑÙŒ:0Ø ªo¢ÉJY#fÃŽ>}-% ¸Ï3ƒI"ÜÉEñJ"pOc¢&pË€Cƒ¤¸÷õs.éë€þYØíZhL»®ó:v_RFkn÷�,†<íC’àX’ÍÚZ0™vú² ­4,sy@ç²S+ï¬ÂòÒ¸ò‘×M­*kÙºì`Ü1ñ£8—ÃP·oc!@$¦£©–ñ¹X î=±�pÚ ]-†Ý� ŠÖJJÓ)=½·}ÉÕ¹Ke¤ÌNÞ¸tûŸ¿�þŸgåu;†æ82 ÇD•çk‹ƒ…·åðö& DEcƒ¿'óà{ÜP6Ðû�yϸ"Ë33„?pp°&ãm6.®I†K!Š ó>aSRºÄlãØÄ1Å�6 -ú´hÐÄÑ 'Æk²¡ÕÞ.K±‘“ûlæ:˜#s0Œ`¾�.43xú-´ê¾ ŽÏJgÑT׌¨j®R/9Rz¶Éé‘ÒÕSjU{UjC"ÆwšÍŒ¬rsëå™h· &ËÁnë¢ÜÉ”«Ÿö+½:ú?Îi;øúŽx+Ýéqúk”5Ãûo.3”ÝŽq�¬— ÃŽÎiýg¨=*®ÛZa¯bÏ^Å7¸ÞqÙ�om.ëLV³öý”Ÿ3“Ï9ô㢙@²�ËL�zs AíÀ,Añ¯ñr«U2_[þ¾CDOÙïT R¢_/ÁUo(¦¾¯\¸÷÷ƒ¹~à]ð�Ác‡¡c+ßU¨Á«¯�¾y% ÖDh �z½gWJÐ!j œ�¬Éx›�×/Ãû†F—åA×[\” %:bÃ*Žk ¹BÂê}±ˆcÃ,–)´h�Ð$Úv_® «'ÿ̘n[]ÌVWŒç®nÀò\Ú�õžDDÄZXêÀ ,LÁ¡i˜Ÿ…}m\g âi…x r¬.®NKÃ)«d\%ç"C.0ä¼ê®Võd»®‹§#¢EÆ,â�äµ:‡•9ðúª|ÆàeÂÚ„š“´lœŽ5eg{ ÌE�íârSX[¸<0U,6[‚«Ð¨Ï‡ßþù›wþþyî|óìgæñÓyÐ]Ù×MkŠÒL´’S”A bjøÚWfaH¿åáZ¸,çüõ.üù—D_X”¶âÀÒfôû�fTx¿×œÄp£©ƒ!@†u-�ìø÷Ž‘÷“K�$�w1ñÃb 1M,Ó¤,sÑ6�@ºõ–¨vÁµÕ‹eT»07ô>Þ¯›`»„šõzCuãn¶­r¦r&ê%Q­Jq»Veóèÿï[å?/`‹ËNÓ¾@ìh#H¸ÂéËbq± bSÜMy ws 7@„eÃJÈ¢…ó'À´Q”VEÔ.™—ÎõÄí¼ŸÁvOÀÕï?÷öXGf\½ïØ×�†ƒx»Ðâ5pÌè}uL_‡ƒ{lŠj碡<¯kd½ñ¡�TÈóÜàfÚ€5o³ñÚ%è4LÖ «tx÷ššTrýIsH‹„6Z4”ˆtÑʵ›Î©E§%Âh¬n*bÉ©“å¸a†I¤åXÀ‡3¬o‘EÚ ´0ãÚSÇêmeƒ^Á!C ƒ‚­ÊØ&g“!¸"‡+]fE‡ŸÅ*Ûâ7ä0N¥°¼‰f�²û)ìB+Ù µ]Þ€�>+�Zûga®-1MÉ•sÞsȃ©4“R`w  ªˆš8#àêù»À¤ïÅs°ÖƒD‰íÎÌâ…ǹXŽX1xpU÷"îѨÖJþY×µ9×”ŽçÏÁŸ¾,ÌÕŸ} ž=_{7™À¨Ó�xI}¹•:S+cfëÞiÆÀá}Fz—Y>×ÏF™� hÍ÷«_CTc|¦•é ¬ØÄ�àˆˆ‚Ÿ7ÐnÊýf®_Ö÷2oq.ÇÍ_T»6y_Ï�hÇžuðÑÏ@³ã›`ª 6ÃåQ±f8»§ŒúpU5rõ.Ø0S3Õ{/Ö®»L~÷`(ÏòÇž`õÊ8·~ïïÇ„¹Úב¼KëöÌ`ÍQ ˜ö,´êZ½ ;i�µ}°&ãm5Þ¼*›w»!€µ¸,S�å5QÐÂlTcXòLÎì'aCˆ˜#V�M“6‘vãyÑsLBNdR¢Ù!v6Åë‹§ðζDùtû¢õqNDò-ANMé´­¬U¤PUŸ\5?C¶ÈØ c•œ« ¹„ã"=.#º”å t2D¢tšd´°Ì�³_™ƒzJ+ýà« Ö>]l¤k)g›ˆ†ÊÞúR®Ãßþ?ï®ï*†?ßö„ˆL�,ˆÕÁÒ|©mÝÓÐí)�…Œ§Š2mh²Z÷è×J^ñè¡Ìœ#àÊ)“÷ÏÃûc¨‘¨Rr5 ª„qЉÉvÙÄß@(½¿28½Ç…C³AùOrþ¦Å-š«°CÞ}�˜%¤ÃÑ{uÕûlšªýÁ8 „�¹™a4 S{[å!*Ï�äýÙ„õï)ª�Èx@t3sG� ôìRÙ(àŠôÃZy…Ɖë…Kð_'M.‰�¥¹}asˆ”ô]0on—{Ï÷_˜ ‹~›KçnÓb¾çÝð}ïsUéî<žÿ¿®¬áÖw¤{ïÙ3Òø/A7»ÃkLË�6²�ÿçû³êÍ&ßO‡ˆe®ü=z€ªË¬Mý3&±G5ÂÈ›�šFÄÛ6™p°¾JÇ—® +ÒijB6Æe"ßñæ !¶†Âh×TJƒŒ„„ˆ�òi!àΔUÊ å ú(åº`Êòe}áÇa²¢´,õ 1xëbWlÞ×JôCRueªÿRÊ:Ž5†¬â´ÈKS˜„ºÚI:Ôƒ´¨zû„][44©jG„ÁÊ‚ G¯=‰î¾ïÿÃ�ÃÏÿU8¦Q-ÖìºKÞ8ÿ.ø©J�ã~•Hã}zÊ÷J+^=ГLC4Ì¥¬üÜÍ´t»[ÀWÝ l¨ÿ·î¬�–ÞÛ¶Ð"ê�‰Õnǰw#'÷ðÏv{¿†ÀßÊê¯îü-i* Ý�¡�t­p™ÔÝ_»,%SMyÅÒEçrmÐÔŸÎVïz€ºÚX’áhˆ¾Ëp‘2h‘ž˜ÌÍ>Á8<‡æEÿúþ‡á»Þ?þ+ðÿ=g'iV*Ö”V®1¼W[cÖȰL¼ûú8æŽ,oÛ1X_¥ãô5ø=íHyð 8a·[R~säbæ—‘‘(©‚®mÄ€ï Cf0Ì’0‹e˜§Ç<–y2fqÌ`™&aŠœ6Ž&–D_–¦h³Z¦å`¾´Î+ -±‚´ˆL#§¥„”ÒÓϲÉ�u+ Õ3iÈ5uc^¡Wøg@N CDL_�•)6£ÐüÐkNâÚB�×þÞ YQÆéj§–%Æd&¶wß íÛžpÕŠ1¶ºé_¯–üBÆ)�ý¿÷ˬÆ4K7ò马é=ˆ8 c‘æÕ°Ø=hÐÂß&^·ÓørFÝNCÞ;Ó÷vÕF¦%G•ì¼)sä,*à=ÃÂÖ½t:úßå¿«)¤ÄèMQËD[q{F¸ÎÝØù ¯³nRgÍMÌ]}SÆÙ�x³Ê/?¬+…þÞ¸,¥:€ûå�ØŒ5¦J@�Ë ÆQ€ýrEã?QVRkÎ äÞÓI-bf·çÄiÉ7ËȖχ`´ÜZœMp'ö‹õÂ�XóíhgG3wô(›Õ4�eù:4tõÌdJU³·«Q®C@Ý`MÆÛj\Ý�_úñQºÿ<~þâáØ~¥‰3\ÖVIË^þdb‚Ó¯,�C2É·ª8ô$ 9lÁˆ5té”\>‹a¨Ô}Yà1™Ÿã´?Í/îÂvÎØ"g“�ê¬rÖH æ*VÝ‚žvd Úlíºp1î¿Gÿ¾ ºŸ¸+Ø�‘ñä‰ÒX2˜ƒ½ébªlJ5J¯ð‹ŒÒ{ƒÀ£Çûôš©PÌŸe"`ïoÃvV·áâªjÐÎ ¸záÒ®»vÝâ"ÙPp³À×í>² 1È”r#§ô0ß/,“�ëλ™íÇ\‡«{uU: óræªsh*ßu~�9¼Y�åjï7þûÊ ¥Ò’Äáâüï‡�?§ÂýKïr|QؘÙ6´¸DK^ž™1¾”g‚{O¿£,/õ�Y‡fõ{37|>ª]�®2oáýGpHsÆ(¼| š‰¢G<ÃàÔÝ`Í£VžÿwÇJÌÛxŸ�¬¯Òá€+;på |î à…-y}òõ[°xê(¼ç<ßõn0`Œ¬mFK¯uëߴѧ^îÿ}âjŽÅ=r÷ ?|fó%JpcÇp­ŒÉs=Æó®Z'k2n븶Ï| –æä¿gÛÐŽ à²HVý+ º´¸“<³eôä#a}úº$´q´Hi’ÓÀ’�“‘)“e öG:ðò•Ý2dÈ�œ†vÈՙݲ¡ì•¸/§ìhœM?(ɆïRÉÆž8ÃÅ�]NÝ×cH0*Ú¿Óãý§DsõÐ!ilˆme7ôHõ¼¹:µfòy€awaµŒgG< ?ñ½pu>ñEø¹ ¯^½µ×—»]��€ò”�Þ™#݉{8H»1¬KVyÿXVÞÛˆf(ŽÇ"»GÆðfÇ8«Rœ>*ô¦—Z©–ך¶õRÞ¸yt79�ãæ/Å�" .úy\Þv³×{Ž[=ž: ?ûƒð®“²ö%ñØïªîWVíðtÀ*¤U©†‰!£Å‘}ð7¾ùÎfóõ‡ò 9Ñ?Áñw´ç”JZÃnk^�ÉÌ÷ÀN2¼€5oë±¼ŸÐÈ•§î—²áñ}Ði@ìäpXÿ°ôuq4…Ûû¶:Z/«P‹! bš8š h`hbh¨¯JÂ�„DÓØ3mq[¨S-+Z�¼Ô>޾ª}zDô*ƒâŠÌD9%šÍ� 䘾P噘0Ëm™jL3`°ú„™oa¬‹ŽJ&�‰qY÷ο|DÀÕt "[¡êC¶Ã{.-Qj�f) .CƒU?_>»Í»6oé\u‰À4É-¸Î.‰á…{üÖ,ça_ùÝ”½Z%¥£¡Éã"YÕh–Ý:ôÊܺ2ÒÇ_û²^ûFpÈf26"® ‡U±¹tÏE$d#q;od…Ýe‰0+˜+Ãmö…ÁJ§ n(`1FÂÔe•ï{*øŒ¥•ÉnŸ»îQåïŸkˆÛüe}ß�‚ŒpL+{•BšÂÖŽhñnõxÏ®:`SL<ÐC£/áÚâùèPºëû㲓.RÓa¬ÄQÞ±ªó¶¢×· b±Êït6ßZWÊ£NY«ˆ§€(ˆQ«:äwôG‡ŒÚ4Tc‡ªëc?\“½4`°&ãm=ú|ò)ã쟅ƒóðÄqÉ.|è�d_-ÍàŒS¶#ç•Óª s¬‹¨Q¾ü”(¸2A[v_–oo–Ó9#e¨Ë© ¥U 5Ô?+bË“°+OXÒ%I ¦Y*ª>8ãË^~ö§Ð^íUý�~ñÈË»Azç¿ß§N seÍuOæ¾8MYZ 3ðB€Õ 6×A0ÿ½b£�ƒN!#š¯sðØ1ø×_¸õ Vj Þý;÷}epó s¯3Váõ†áÄ•LJ›àú[2÷#3¿ÛÝÚq={Œâj¯lAA¼�cI¯0V_*Œ #Øp.Óàþ±µù3ì.j¯»|‡%æ C^pmV6ÿÞP>çêmXOžæ*Ž O‹õÁaŠõ©ì4öBïyªAÒ~­ð@<)Þ©ê®_êàÜÝ‘ÍweºCñç³Dÿ+Ž®ê_�9W¿3_*30©=o£kr®æzx±V<Æ&k2¾*@Ö…Myq¾ú³?ÿÕ¶!@Å”E¦@K>‡ÕàZF4UЛ“0,bF¼‰iÌ@Æè£\fÜeÚÀ?$R3@ÿJÕ¢.2®•õ2ÀDâÂìW‚8©™ ?m®ë)º¡?»©§ÔÙ\x×iïäî�НèIm›¼Øtr”ùë îüw{ò€è€vÑ”ÌèµBü—NRfây€š­‚Óì5à2—pœ'Ö’ˆl«;q“ŒØu\3�S‡nýõ‹´«�¸=pÅÈa¤LÕ=¼jB†ÕzFâš²§�3À…Ê÷ïÙ­‚x¼ÍuÆB›pd»–\¾,b�ë Ó‹qz† D dÇ >ˆãEr2†lÒ%c�Œ«”žGFç£ •Lº£ÎÝym=x¸¨ÏÐ9�ËU`Ë�œœY\¾.%ÌÕøÒ ¬ÜFøÁƒb§’÷1±?x¸J¦åâd~DŸ‘ÃÊôúlËv°Ä?p'`r®gõ}ÊŽÐò[¸ãÙ|çÖàê–0ÜÆˆU�‘§>ÇŒã5] ]ðßó”¾kès·©×|�2÷uE³FûÁóîî8€NÖdÜÑñü9XÙ�V��äbª‹¹ÓÈŠê©9Â’*È’²¢7hŒÀKV¦\ª›C³QCr]¤‡ªq#µýÊ&’g`œÑ4ùÜÈ)1ê☫¸<ûÅ?݆ *doüÒÞR’Ì•ÁR›_ƒÜêÝùïoßt¥cFóàÂ8*÷íØªf«õ“yW�öÕVìŠðÙ Ú¯# ·þúiM'H`F[2ÛÁk‡ñ±9ãPxrï÷ÉvðgafbŽh²q6vàð¥¸^zÌ®ÓEwóN^ã:åwDc@V& ðå«°�@2 Ñ˸ô &n©þÆ‘1$£‡cGK¯½`^CÏ®Jù1X!£è�Ù¶þ{}.e⤱lþ¯.Ã3aõ6ôlo‡ªó|Èzýš×#½®,–ŸË•à'€· IDATÐ’‚˜}ö#øÄ›®>sÖoã1ÛVæF´Q¾³8–�t‡û�ûôyñY¥­àz¡Ú%é=Í| 1§*'@ÿÞÍæ»°}Iþý±Ãpjl lùy·åü9ªNîžÝ–ºÌÊ2p¡QM5“u£ûöÝ7'k2ö4¾xþÁ¿‚'OÂǤÌsd§…Vn%ЈqÞsÆŠFv‡)¥š]`� bP£9€¾û°e!ÅÁH7ÈTÃ�£¢|èh€Û@•98ØÞÖhuKrüÎ\ƒKðbõY "WÙ�ü -¢šëÖ¬¬²5?/¬¡nFÞd“Èà\X½óß_#ºuÌHpqèúí…à³c˜ ScT<˜š×9Ù=wLÒ³­[}+Ûb8™ˆ«ìÓ `�¶ƒïn£Æ&øï»°ÆýÜ:ã<Ö‚“¹G/i.±(y^0ˆÞ-¼®GÖ6Þ/·Ó1ô�+ßÛT50þÏ-ÃóË0÷(ìßííb2Âî7±G‰4’ª4Û� ž‘pîl �‡Œ•?œlsÛ¥¦c³·�Á?üca®ÖSÞQt«0¼¡ç“©<#í€å ¯CjlhÊî°v `…eãueª®RæZz3Û�€ur0Nb§z VÏüÙ^ÝPûçsÛê¢é°ã»Xwóš õb!˜Y«}féò4ôƒÃÎÁú¼ò:Ü÷ 4Ú÷¡ýgšÿYM(ƒ¤}©hUÙŒ…ãŒNxxÙÔŸ¹¦Ÿé ej•½Ëe.×wàÕÍÛÉ&jŽÉŠ´ÌŒîA}VßSÝÖþ°ágÛ8Ï;žÍ瀵!¬-ËËÒ©¹V´«øŽÎ¬(wʽ•1…Õõ1/J�Òt”Ýå"r�—À9íƒmJuáõË€5“qSãų°¼)z­F fgÓ©<Ó†4PlUOéÕE&Un ç”…Êr2W7à…³paeôóÔ}¾æÚ"úÖö@WÀ¸ÑÏà·FS0¹vǸJ瘫ƒ«aË[ð¹;ÿ}Œí,»£B'ñFít=ÎM<ÜèwÿùTËÀµWã6d3>}¾ý�ÐöÔ©Ü)×_¢*¸Ø 6>wõ`PX¡…G]{j¯œç´48H¥;ë¥ó0LÁv Fv\§c½Öw^ù¦ ÃîÂ÷qÑ=»uPŽt:æ9ln‹/ÂáÊèšÐІQŸÑÐkˆe›¼pˆµG½Àªû¦ùæˆP£Sýly©aË�8ùßö�0ª=¦¢¿Úíù¨²´ÕçËχ�úë®Íæ;¿ š)ò÷kLFZ[“EsëÝó :-îi9|Š“š<#MœWë]1X�¬É˜Œ›Ï��?ý"|àQXœ)rÂ0[´ÐS~¥Œ_˜úž·—«™©QÕø ¨Y8‰µØì ÍüÂYøØÓpqmôóÔ}¾= ìÆ#ÏÈ­'¼-¹RÙƒ€ú.K¹n4N—Œ´ ®l7Ô–òå-ø÷¯À³gïü÷a�>ìq¥<ØÄ2E®yŠeG]X拯Úêy£ùd†Ž6}ºDšÍ˜brÉã»å'ôO¾ÌÿßÞ›ÆX’]w~¿ï½Ü—Ú«º–ÞØÝ¬f³I‰¢(R"µr´3²� [€í±C_æË@4dÈ–y k Œ?Ø0üi Œ$�Gœ‘’8â&ÉÍ�ÙkõVÝÕµfUVfåžù–ˆ¸þpÎ�¸ñ2«ÉZ3[uþ�è|¹¼WqãFÄýÇÿœó?ü½�Hèz´%ù�¹4�[”„‚…5UPâpO¬6 ç`…\¦�r¥ú±ñxü —ÄÝùU1V}ålõ„}¹:¯0DZ¥u³¡Ð öè „8?l'µd¸P#Tè…*®KHµÞujŸ© ¶R”°µ/k?¼¹9˜zöe�oFaÂ=ú Ë�ujO¤ ÞÌùË� êVVuˆÕß/…£ê‡—nkþΑÐw4>WZ¼»_™£Ù 9îÏ7ìÇV=´ì‚õÚ|ì)èôñù .kSÒÇÓ¦ ¯Æ9mºô÷G™ëP[ßEµÊðɾ,åáse ¾wþæœ,ƒá–ðæuøÝÏÂ3'áô YøŽÎÂ̸˜—vZÐJ´O˜«º¨Vä ¾§ý领¿›}Iм¾&¹M%äò Q®æ–am‡ª”aŸ¯_ù(üÃOÄ(Y¾—8Í7pÛòŒŠÆb¬!ò:Ÿ &Wß<+=_¹$äên›jÞÜŽ?î­v;—Ž›÷i“Ï*%éÃjÚ]ÁWÏÂoü¾ª~è|ì 8<… }掓õ…””Úˆ¼Vµâäì�ZžÄyW•%Céáõ9øÃ¯ŠrõÊ%xû,oÀÉýPÔÕŽ%Ž‚69¥úº5ÛÑŸ¡áƒt‚UDûûJ5?+Ý®`¥…ä –%œ= —/Ã×¾ø�áý�V‰Ï;ÕBQVº…«TݸuÒVD<â°rñ.Ç2¶5)ñ•�Š/J!ªgïCˆ=ôÉܦòÖçtò.ׇ»Åkdø3›O-{ 9ßk—a£Y Ò5|~HŒ }Ý~þ9‚wa¡çvÈ›•êrŸNÈÃÇKáëgE¹ú›sðâe#XÃ-¡ð’ÿÚ<ð�½±O±Ï×S$Ï`¤ .Õ°’Ç¥NoIµ5o ~{“ÛH;êöá /Á?ùÓ½5Õrâ¶FIe�±}ù~ ‡»ÉÂávÜÞ-Àu—æö˯Ëð¥ß„ƒSBx²¬"½HåIÉÉðdêw”‘VÝ\Tž~³ö0qÿIéìñy)ýÿç?oîߥEøÀC�eÚ†¼GÁ„žMm•ED0$‚‡*Ç .Æ¡¥X ÊЪªJ×€w�ŠÇ9R®#a¹�t\-’¡L¾,acC¶7.CïYyJ{ø|DŠV"Rç§moÇI´ 7ÍZ“mýìB~\E®J}¨ZÙ„w®ßŸëÃ'ß÷ü~wÓÖïÿO _cwÚéžáüu±åëˆË|2/…Dnjh>› µ©l^Grðét�“úï_€ßúãc4‚ex qÆ;âžœIõ£÷N¤ˆ¤l,ÛóÂzJ¬Fð‰¶{èçR’æÒp\‡VlóJÚiã(Ñúy÷-{÷Åób)2ÒÂçE–,«±—útíÕ‰Ük¾˜×E¯Tò’¼kïµÊË/ŠËfžgûþ¼~ ~ú 1òdï® ¾Öíc‚¥Â*ue^œ,^Ò )ùÞ»m7H·yuÕcP#ܵ|¥^¹(!îV&y”iWC®®Ú�ØG®Îý*+uæfžb!Ì^êõUê|TaÁ¢rµ¶%×è¹ë÷éòðC�RwçÚøA?ï¾^ß—`-ÀWäÞ8=&çA °‚/FÄ!¾³4» äRÕÈÕ Òöò¥g�1‚ex q~þâEyýØa¹‰Œ´$Ù5Ið¥«sļDžp’ˆêàGÄÃ¥($‡¥;rõÜë{óâaØè2¶¦ˆ[_Ä­-:4ÛÈ /áŸ8~D‹EPN–T-‘­`™T­ :ôªÅhDÞ1¸ Í]�ïÓÛÓÇE…<6«7~5¾m…ÊU}O?×WÉa|~—mU^O®A!‹ZÑ(¼äè•^TªþçðÛrkû»¸o-À± H'`4ƒöDÅ!Ñl°�,^²IYyL]§v̧é[#ˆ/Uª>Káø§•êRU:æàÓn�³SyááÕk²ñíí¿ÿGŸ†ÿî—Å=I4±V©Ü¶@š’«ÂC2­ÆÀšÄÞˆ:òØaxäüôiY¤7{¢d]]Ù¾@w™„äeu–‡9®…Zt¤Ü `šºïâˆÎA¡ªb\|›Ôn"U�7T•\ÄWvÍÞ•šD~?@~�ûãâ,^„ç/ÚzaË`0¼ëâ“êŠ�ÃÕ]!„¡B(ƒÄ¡�á÷Çï͇•0�,¨wŠÇ÷Ãoþ=ø‰'áÀ¤*mf]UaíT�åUSð’c’s‡ƒb9º!:ÙóH39lwêk¶Ô•V/G´MÐ�¶’½à3”UIà ·…Ù áÙ¸«@‹¤á¤{L‰j•Ñ�|ÚêjW�O{C>m·±€¾v®­Hè°“iþ"Pæ8“T¢tVò½– §Lµaz¢IÆ|”�TjÑ8Äô;ÿÎÌßÝëcPhugªÛé|ä ´bòf×Hhš>lÄ[l»>¼¾7Ó÷úížd©“Jdƒ,ƒÁðA?‡t¼‘;Õ£YÍ›!†¦ÎaáVMBÞOp¼Ÿ§ö[ºÜ `�T›¼¦µçRâ%´z§øÀq!WÇfµ P§Unu¤Øê…¯'k»j >_S’¸ié«YF4Ò!jB¡JÏ�øš­äÒGàêQx6…§h'øb—Ÿ¡MJR %Ná/QÛ´ª®žM¬¾Ú0ܾæ[‰:æñy�O6dãùú·—óêe ¯ÿäi ©�¶¥Pĵå8V„©-_ýˆK—‚ÏpY'š«®ŽF©¢“מ®„s`lßš†{\–w›`m„ô¹±ª�Ñ@÷J®�>-RÚ•«~ P“:O±ájÑPá*ž+d\®�2�„rå‰H°ß�}1Á2 ïlôuñš`梑 >lš\‡E#¬¸IqPM‚ad]±æÕ+Ls°Ò®„ÛæWï|<§�‹rÕÎ$\8ôÐï*‚5\6ôÊy1°-ù|òýb$ú¾£¢š¤NŒL³ G®CÙMŒG(èR�R0B‘ (¹ŽK[xŸAgßÀË×áÕ+bˆø½wà•«w'çgàaa ÛëW#Ÿ!'>Cù,.s•Óû€¦ÃÎLqRvýµa%‘{HWÔ§m_| þñ¿½³±”Þ^’íÏÔ¾“Âþ11ò=<?ü0|ô1xü0™�V‚K$iÔ6ѳPÆÔ©:9!/-ƒ’-|ÚÁ�NÀñÓøŸ}Vüƾðüùó°v‡ªÏÅex6�lÏ£À%K Hñ¬áè�Ð'Q#âMUn 9Y¡º3ö1õѳD¦¾džkdªð¶YcŒ.äLS²ŽOßÁç‰ì‹Á–Á`x�àò2<‹¶= ÏÙ)¥ÖGI�¾ŒM`�œQ­H9£'È/S°LÜW®`€£ ¡¤Ä{ ÍQ|ñü­ïÿ'Ÿ€ßû5I‚Ë %••nàÈuáN«tå¸×[Ó�?(yYmÑ…£ðs³ð©ÓbDûí·à·ÿ^œ»»ó±£ÏÐ"Þ—¦L¥z1:Ýó›™RйcÖôWÊ�d¥î�¸¸&}Bï6:)üøð§¥Õ#‡àÔ,ŒGs¥ÉÛâìŸ6Íãñº–/‹ˆbZÓÉc³BØž}~öyÓ¿úö�íÿ+sð³™Þä*Þ}éŠØÛѧl§Ž‘mK”«e`¯U�)[¤•zU2MÉQ¼ÿ*¾…nWöÅ`Ë`0¼Gpn^JâÓ ŠQuïQP7¹-4\¸NÊu íMXT½×B"oÜWnS«¬Öˆ¬a Ï€‚¢@lJ®ž?/¤å– ÖûeÑkCšDJNZå�ethQ÷ [ܼ9תFI4Ñ�™‚RmÖ�¶ðÙ$üÈcðá‡ï>ÁÚÉghLÛG%‘yiÙ×þtíèÍùΟ™ëÿÒDò—‚è6Ð$ñÅ5éúÒ=¨šÝ?&äêç>$v'S£0š@ò˜r’Lê%S2ZôªùéòþR5öèPPèÜ8ú´´û]JžI>_™z¼Oñ‡gð?÷Ì�¬¿¹WxhÚ-H_Ç»ÓÀ*zlâñdl’³„cN•«ÐW°nî5Ç1SBæ«ëc _… {ŒRpïÏà‹ƒÐÀÕyÙƒ,ƒÁðÁÛó’<ÛjCºõC“ªeëòIr RºšØ›EKÒ‘‹m=ï†{ôùÄá¯.ß|W”«o¿ÏßFÞ‡N‰rµCà‚d8ÚbsÈHD´Z4«ðUïh(&yf󢸴˜ƒgN_¿»ó±“ÏÐc‡áÑCðÐ ÌjÏÎv†OHú:v·ÝÑÒ‡j;µ>è«Yçªzt]¾!V g. ¹º½1L‰ruê xȵSH›>厺¥N Âa®ÚÕZä4ß/«*ô\4_ÛÐ[)|àÄ�ïÿkWá[ËðñÓp`Œ�}ïf¶ù”%º—¡awOÕã>–uCl_å5nâÙj\ ÞŸº),Ü€o½¯]³û•,ƒÁðžÁ…z‹åÓ¸l”’DCz0 ÇŽ•ªbªÐůֺda)£¤êaFi4ã ]/,À¯ÿ‹[Û_L¶%qúØ>8u¨²a!¿°P�ê6AÂ’36©êÂÈÁêSÛ¬©>!¡›] ºäRÑåzø|»…ìðÝŸ�aŸ¡ÄÁñiQ³ž8�©MogÇ`¢£�Ø7­³Õƒ¥>>˜ßvµú¼úF½xQšé¾tò{l^yhZŒ(§F•\IE¡c³RG•PM‘«ßZZy{Õ!·¤Ñç°¶žH+(•AyžÂÇð¿ÿëðÂyøÚëbôÚ¿E/©åxí-8ù´Æ¤Ú1¦ä3õŸ” ±u2Z‘JLak,ß°1©mKB£x¯ â�^ +¸tMöayÅîWF° Ã{;æü¬àó#¸l²êÓ’ÞÅô0äŸäd¤Úþ$ô’óÛœ© ]öÅÉI¨«ŸK2ò­b² ÷#rzú?¸Í×*äð„¦cJª¦©�9G‡V�aË W-„%©f¤©¹CþÍc³÷~~ŽOÃ?üàgž�‡öÁ؈† �®Ú^¥u wRIôœàF^z±OX݄﾿õ¯á{—ïíþ?qT”·%&®lpå0WYE†eަ¢y ö�`mÑ4»�½×¡w€?0¿ò1ø…Ãk—á3ÿ¾r‹aèµ58sŽ•ïOí‡v­wðùXµPÊù½½ Ê÷ƒf—„@¬j÷w%Wé9ü`n,ÁùExé%Ù‡µ5»_Á2 ïlËù™„‰Ih­H]ñ)Ⱥ¼MÁº†D6IÈH)¢69^+Õ €n–’ÓÁ{�Ÿtø§‚�?yëkk ^Öótnžy>53d+Ú&Éá²R—›¡9x³Zµ&Yõ&š¯/ Hxׇ~Kkð�oÃKg…\½ü²ì‹Á–Á`x�`8ç籓ðóÿ<ý$LÏB{_^‡òƒ�ÍjFêðBŽ’Ó¾|P7Ãõ±òi_–pm .Ýåê‹/ß=ëû{lŸ(W§`D쪘 u>O¬^Mêb=ƒØKÌèϳ!‚Õ‰>)ôð› ä�¹Ê2À•h¼sÖCû”\¥Ûó¬"ÓËaß(QTâžáæžÂÔ|ðĽßÿ÷‘|(G4G^çÉ“!¡4Q¯\EŒÃ<íD°bãÎu¸pG«RŒ²Êy�4‘ø³§n}ÿËΞ…Ë—ák_ƒý3ð‰GàSŽÀ±i80)Úåº }#5‹Æ¼råå:ò9ÞàÚºTõ¾vþúMøê9¸±,ÊÕÖ–ì‹Á–Á`¸OpÀlGªœNî—üœ÷?¨û¥ íØ8ŽÈ›6?#¬ÁóËøõ.¬/ÃÒ5¡&c0šBúe|þ(.ó”t«ÐŒÛañ¨^ç@Ú+€­üŸ_„ò§w6Þ‡öI^OGÕ?ƒcSÃM mJ&T9œÐí”.؇UÝŠKçãÐÓª*^Á¿Hòh’*�¦Z8Ë?Òæ®g0µø¡“ð£�‹ÝÀ3§`bÜ8.S;ƒBm' ÒÊ›ž!£ÑÐg0«sಠJ2°¿ûüéðÂøËWàËg`ó.·c9:£;åIè‘�‘‘ÓÒc< &­æèpL•Ç)šUx¡¿b ¿KÀ5 &I«þa~œ¯<ƒ’eÖÅ?rèöÆP–°±!ÛÕ«ðÊkð}N~÷{ÿ üú§µÐ¢‹w#�˪`go²ê'^Ûõr¸²(¹j?óüêGå}ÙðÅN],º´‚ßHîâz]´ÅÞî‘F° Ãma¶ÿGáÓÏÀ“G%÷f|D»Ù§ê3ÔýÁˆÚ‘iðÓàK(ç _„ÁAŒKîLòÞ÷¡è(YëFîK=½kô´W_§îÕ×Ï¥jíÌ¥;ïÑYIìN5©¬µ§a™LUŽQU@BR{Gì‘H +¼JÖx´…< P VU¯eéÝŸÏ: ÿô?…gN ±ÊRH•A„Ö:ý/ö‹’Ä~WíŸ×‚‚<"\ÐôÐâÄ!¬{üâ‡à7~þô¥»;ž©Ñ!ž7 Ú:£CÇ|ŒºH¡5D°ˆTÇ ÝÆªyªU¬†®éì¿!Ý—.Àò†\wY*$«Ñt;¡Š¤=íÓèEå{öa=•ãîæÿö�©ÀÒT+›­Ž~ç³Ú”Û`Ë`0܆¢3+äê£�j|¦y:]Ž.‰г*D#H(S§ ìï$Y�t€O– ëãûlŽ@ÛCV‚Û�§nè ²Tz/TÄ©-@QŠCøÂ<÷:¼|Ö¡)©FK€²…K·pôIHÈÔ6bR¬cˆIý)U®f#e*�HUP{²hóÑñ íQ‚ÇWÈÓ‚"½ëGr5=n—å@†Kú:½ŠL¯¨ FÈÁUU�%‰¶r U�u#ây¦‰ÕI*–'öÃO=}÷ V'ƒ¢Äei¾m+‰šV¥êpTçë¨ÎUf4ÍF j‡@z� ôÈ";�¢ÆöüØ=é~ï|ë,|ôñÚ†"Ù—ng~N,ç…dy„@».-4§’¬®ŠÿúŒêœ,ïFðIy†Û·2ø±'¤7£,#Xƒá6qr¿(W3㲘%ɶª:§4!nÿEѤ2R@@œÃi÷`eþýYñ:¼˜RQ’¼—§ç\›oöä©þʲØœ¹$äêìâ��wÿ„æ]…@P�³¬¬X¥é©”°=_)‰ÈU‹Ú‡i´RF|C!’7¹»?ŸÏ>,ÊUT«ºobP­Òmc,Å5ԞД8ÓD^QaQ.«¹öÒ„¹“Á³'ïþxZitúF+œ `Åþd�hžv:_“!õ«S)’.ò`î6Î\…ßþáÃ�1~ì°XhLŽJŽ`–ÔçIð#KR˜׊д.‘$-‰+,‡Ï×á¼®RWlÎÉV*×ÉÓ'€oÛ=Ò–Á`¸-œØ57N é©B•5²Ø¸±Ý´¥Ä]<|z•Â!F¢e:‚gÇ�µàÊüêÿ³»ã�ÒçJHVuA¯ï”¤J˜žRÅj?°/RDÚ;,Ú�®…Ð☾_Z ”¬ËÀ"!>©"9w=Ãå‘Cº(g¸¤&UB* FÉW•nF“§əP‚Õn¬DÃÅÓkiͲ†«p€�s”IByb|úq¸´WVŃéN˜$Õbâ(Ô­Ý7,ft !±=�¬a"ìô÷AÑÚª>£`š”e`G—=Ô¶¡p¸4¹ûóUxxiN6¾öýÿþgOÃïýçppV“ÿgpI•BÙ$�A¥Ë†T¼~u½f•§V‘�gDòº:-üãGìþhË`0Ü6ÞwDr®Ò \ùHñð;�,¿ÍC¨‘Œ:1×iVS¦îå™Fî6&4Y¹WAÈЉŸüSš!¿ô&ÊÕ°Ò7üþÖÐg8UÊä ÷@Á:4¥ŠG­\Q‘Â\çÑE$KˆVðŒj,*'ñر~€g€«Üù^Žé‘1ø½_�Wçàó¯Â¿y–ï°YråQ�GÇÙUŠjv“yJnažÒ¡÷×sí¢ÚÖ{¤8Þ*ž<Öô+eŠç¹©P’•DG²ÎÌ)Éô£|M SÇ÷ÛýÑ–Á`¸}‚uTÔ«2ÇehÞd¤´È&ñL¨’3)9q^UY+º­‘°IÁ€Œ> …Ë%Wç¡}»?ÞN¦9^+:Þ@¬2 áeZõ׊¶„dÝ,|ÕúŒw#iwŒÉQ%n½J…UNTªYà 9G�£¸ÊÛk*R(C5] X+¤,ó8®‘s¸®!ÏÀÓûuüh ÿȘ•}ùÆÛ°|§a]GœfïÈ+$s“ns=7’åv˜«8´Û¢ÐïSrÍ9”3�=À¯xö$Lv$ï>iC²©¹i)y–EÏ1M]¤r¥/h}Í®Ñc�ºétž9ñi;8i÷G#Xƒá¶qb¿T –ÅQȶ… zLè÷ºìЊd ;$ô$Õ]'­FÜ¿nØUþUPDÛb›r¶'ÖûŽH8Ú™ªé5!Lí¦”t‚Õ£©>KoCqõÉ©à4Á2 ·‰}PöqY¦¹Hµqã$0…g?µKö�h1N¨Ì—€ëº]ÆÉXFÂa] ʉvÝU§,‡VVíSÜ|7䥄¼²>u¨,}—õ6$Ô­WB¿¸Ðw®Æ=8­\R)4µ3ý Ž"þ^§¯cª`ÒœFK»²�¨—@=£ ]¬=}z ÈÉYÅ—Ÿ¡Lÿ7|'…ƒB°î~É*ÙÞÞ¦ˆŽoy Ÿ·ž‰{ûÅóåïátÝ2ŽÌTm޽†­ÈŽ�«Ãä*�G’÷K%Skˆký‚^³×�«úþ%` ǰI^)#Þß} {U4¬àü¢ŽDêF!….vr�¿ë3)=`�‚e2ÖÈI#ÏþK\þuH>�oyiGtÇËoSœâ㼦ÇzU_oPç–ap;|ÆÖŸ>g“T*ëÂü¦>ßk¤E¢ùƒ5± ®ö‡È9†ã¢TEÊà VFÇn é¿8­sò³Båd‘&v4‚e0nC7Q§ÕYMÅÃWÆŽÁ){$"dP÷t .Ú#4�ËÝÿÖ®`nY¼„²T-Ø�ª"Ù¶aOU¹°U.¨X°½­L^túþ¼6mS¬Jʽ Xnû·±ïUì5ì7¤~åÄžQqâ¾h”®:c”ަÀì]ȹ+¶U·ëæ6ˆæ¨Ü�`ÅêäÎïOªe5Kƒb÷Ïß,èÅÙ�‚æ×U*åøÐV Ò�dÆÝb;‡{Råj0‚e0<0H’j I"¥bœŒ<�Þz‡Uõˆs°œ’�Iêü��D ¹ik¥žs»ŸÓñö^{âz5Á2Þ³ØÁµ]nܾáxÊàc_§ðœF¿«Ëå}£EÉžy"~m®®H>ØHÉ,žT�•êäôž.²ëºXoè{ ùJ%qUØJT�\ÿ¾6äìêçæú÷>/îM#ݬaK‚ØëéÝü¢vzÿNŸáÔñ¼¦çNŒ\ÇÆî|<ýÒÉ*ß-ä_‘úÔÕc¼14O±W[J3q+šßu}½Em”+ꕨš>/d ½=t½æ;ªXMˉúz�û1†ë¶=tm§Ãçƒ XF° ÃݼZ›æ¢­›�«°xu¨ÃõÍ<½‰çÓ±¼vþê üäiiN=9í–öRL*� QBÊJÑ:ªŠ\È[ª«îœ.Ú9›H^ËŽ9U±æÈ™§` ÉïÙBÌ<÷GInB�†ª�È•ÿ>-%!¡¥fêŽV€cßnßùÎoôª�ˆC¸›CTÄ LT5g’¦TP¿VT¥œ.ê×9$çn-R«aéáÆÆ XñKiŽ“¹m|­fÑï¥oïðð”þ„Û`Ë`0Ü2ü½³ÞÒmU\wúùwçWàýüÙ ðÔQøïÿ¾2†t[õ ëÀ*å¶Ü2p Ôô²¶3pUÂôš³ ¶@­*  £¤‹OGñ[k侀c§ ½zÕO‡îú‰ôÌ»S,®Ãcr �Å}ôrMDïFjÔ*ÍpaSë�>% Û }ï!WÎׄ¹ƒ´Ä<Ì-í±9qßw®~�«Ýï�«Ó`Ë`øÛK®|ƒ`H¸e8„22´x…pÚiE06¨Ãb¥~¾ß wñÒùeÙ>wþÑ/ÃL)=بí&<} ºÚMqÉQ¹JÈ?Ê«r÷RÚ7õï–TY ÇŽUr6ÈÕ/ÊIèÉ—ÒÐú>Ìlö ûÃÞ\þ&ï-‡Þ¿¥ï—ph¢ó‹zÔþþ¢dÝ… ç:üð#ÐJñ¹‡¬Þßn´�žºzs�º¢5Η“9…M VIYRrµH�ƒ´NI7Œ«ŸnáK/MÈÏ^Ý—jÓ|"Ìol·¶­h®C1Jx€èF„tmèz-ì†hË`0Ü­v‘ò4œãWgžNŽac΂žª ¡j.ö~Ú k+[ptVCP™.X¹6)TIèPVmd íÃ'ß»Fâ´´qJJ]%jzZòŸãýA|YÀ•÷Œ+›§¾›·×Í��<½šï/)I¢Ï�sˆtŸsw’Â_8?ÿ¬ø?¥IE² Ýf6¹!?°ˆ2ŠF‚÷+d¬*�^oœ³%žŸt…\ QÒ^¹¸7r “¸éͪ*Ñõæ:"ÜÃFºùÐù`²–,ƒÁp§7ìÔ«ðD—ó‡t —…*Âú$| ©œ»BÆ’ç²Eð*ö&Áº¾ Oƒ2…¬öÈÐf@Ÿžu=ÁpSL9]£Éµ,òN¨ûléë>]rº”¬âó$û`�Ã[÷@ò� ûµ¡óqªÆÎ!a?å ?ÅÖ±š¹Líür•¶”Xä¢TNe=wº¯½!ysOƒñŽ�,y¨* Ã8;ºO×£ñ [„ã”<™#ßPõrÀû?(E¹Z\‡¯¿/^Øýó5²­ð¤•zµIÁ µ•F0‘mGj_[Ç¿)}sHå¼ÎïV?÷ȧÍ`Ë`x`PP´ -ÔJ,*ã�ÐæÐÖÑ·ºè 8˜nàØ$o„JE£(÷Þø/.Ê~µ¶ðùŒÞ¸rJ2 ¯Z¨¸!:l4*dÄEýC™®ªÀ>@ò¨¨W[Ý{r"X±ïSP,¹èEêd[ÿ&Ù�`5 Ió½¹öœ,5sÉ'‹²0çåÝÉYúæ9øoÿ>þ<{ ~âýpl¶¡ÐÒ;Ї0XK‰pL°ŠhÜ2Ç@Œ3äa Ô†<ï\ƒõ Q®^¼oÌïþù:(Ô»-šß��VTó_³i¤dÅ¡ÿuêðà°Š…,#XƒáoØÕbå•@”¬NÃ?%!ô%Oº±Ö€º¯Ù<â%TŽ`qžˆ)ö`vÇÙ«ÐËÅÀ1]ŽH–¯ÈaX¬›ÖnÇ69eµ¥úµP[ yRÈÇ ‡¥ 8¿x÷dzƒ"*ëB+?¤äì×ExØÛ+ü>¸~/ 9h—(¹LÉëz¾ ð…ר\ ›]xûÚ��§_ÂsoÉð…ÏHõ§KðÎ5BZ!ü— m±*çÄSˆt³…xç%ùêeøþÍÞ:_£°kÝ�@ ) i«®Ù}4�F»ÔÉý¡’rNçx3"Y{ò�È`Ë`xÏ ;€Dú»Õá.¯mcjµ"„ˆR]È:Á ð*Í„ø `I«‡ïå{oüg.Ââš�¶3H–ñù(dUC›jñ�]Á·×o¹¡<úÞÏà“IÉšä°Ú…³óðÎÂÝO^ÊŽ&M+�¥ÍH½XC’ÀG£ûuì€>R;ÖÕ‘ ›jaQ«”Þ-Éêàò xãÊÝß àÇž€QIÛö®êtÙPÞêyª�W‰æEÞã›óUI)yWݾäí5¬Û -!£¤¨T»)[‘е¤ãÛ"Xëú»•HÉj(X^Ï%ƒ,ƒÁp»7ìnÃg((¥*8}B ϲÈ;¯‰Ãß„pÃFDÌj’åÅA}¯á¥ ðÕ×àOÁþIèd�nàu•ö¥“4ö†ã@λ»•Sñ~´&V[]Q®ÎÎÃ_¼ îA’{?oÌePߠ邾)ϨÚÛ«îY¼½uòš* d,éœËùRÊ‚¼Òrõ¥—î Áú«Wà?'È\% Þ ArÜlZòHßi’bòrSÒ’+¹zë<÷ÚÞ;_—Ö£Ø%Ð<½j¤R6(˜Ô9£©^“í šU¹^¯¾7°û£,ƒÁpÛXX…÷©Ì‚¼Þ²K:äxÍ?ÊTÉñU¾Nª)ÞaÑEì†= çºx-­ï½ñ¿y~÷³ðÌI8}?'öÃÁI˜…Ñ6¾�JÅÄ5›õQÉ"ò?�4’.JY¸·ú°¼.Õ‚g¯Â›s|gAÈÕB÷Þæ“à¶W˜‰º!÷æëÀE•T«‘!‚¬Vhú{Å‹q‰ä-±¾ÿãg…X½q.­Üýñ}é |æ÷á'Ÿ†gOÂCû`z FZø–Γs2W9ŸGå•ÞËVx™«~.äiÎ/ˆrõÜkðÜ›{ï|½¢½4[A‰ó•WV¦·�èA ØYD°B>^œ¯ÕT#UÁZÛ²û£,ƒÁpÛ8w~ä1heø¼„Lžö <žŽÞ Û•»yíâ-~G^Ë߃­�XD¡AÀ§ÈgŸ¿¾ûãuÀ¡ xä$jȱ!UÓc0Ö†v*ýôòúùÚÀFV6¤úðÒ xk^ÈÄëspqõÞô¼\[�S…<¤Ò°H‰¢a±ÐW¥c‘¢Ñ›°¬iåz¾Œäì„°Ò†VÞ…Ïó®Ä¯÷àÿøâ½ßVú’l?ÐBäàÙ‡à#�ÂOÂc‡àà4LŒH«¤42ÖIá𘀇_þ,¬IÙ à[gá{—`°Ëa³·®jû ’.Þ�è/:ô(H¨C»«C׬‹”Ì¢ºf{Uk U"ËBªj¯,ÙýÑ–Á`¸m<~éÃ0•H¸¥²½N)Iñ¤”t(µ$\‡‹Èæ0Õ63RI&ÉÝE­\¥HNËÖ@þ­ÝÆ¡ ø?çCB²¦Æ$Ô”%QFô°Ïu¤PáE¥*U¥ÚìËBôåWàŸNœâwU‘» ?ô¨f ËtQ-ªpî R§2mö«&ÁªC‰«CÊUݯÏKî’CŸ{ Ï>¿û«ð¡S¢H¶RQµ\P#wˆ)Vóì¥zñ—»REø›ßÚe«†—/ŠÒÖš–ÂŒ¤‹/FÞ`a%Û“ýãß ÑÊôº yh9¸~0ض#XÃ{ßxÎ\†Ó‰ÏPÖ—²ùb?.›R ŽhÚûºº;ú}_³µÀ3lâóž´qš—³¥.Ø_y}÷ÇûÈ!!W8 ã#B¬8ˆË$�&c*päJ!êÉõ)!éËœäÐÃwZðÓÀçžß}‚õÝwà—>S™�Û\ü½êDý%uùþ žXÁ¤3x,Åð[¤tÉèE–%à“ž$·Ï­ì½óû#� ¹š‡¤À©BGzëFÕ²jyÍa#)ñ.…é1üOÂGß}‚õü;ð�³ð±ÇavB 3Ò.Þ;(Æ ƒ‚±Šh5 2Äz$�¬úºõàK©põ™(¶—oÈCƒÁ–Á`¸M|û¼ø }ì}²=v ¦¦¡Õ×¹–ÞXÇx–�îz!ëJ<´È HVåõÚÎÍÁÛWE¹úÊëðÕ³{€`’5>"jFâ¢Þ .Z”2%XuuZ-pD?IiÁ±Y1,ýü.'FŸ¹—–àÑŒ$²øæÓ�õTÉ’ Ñ°ðŠ …§§™vJòÛ|°úxuéöâzïó\8è`�„€‡ñÁ“¢\e©„¾"Ô•†žá†ç(ɬæxbDr¾v¯]ƒü¯áCÃNÀÓ'àGŸ‚™qÈzJ´fªáx²!�®]?0ä@º†/±*¹º—E¹úò+ðù—ìþhË`0Ü6%|íœl?ò>ø§ÿ |p &�ä°$@úEéŸW|§é²>n°’Îá «ô ¸º ¿ýGð'ßÛý1NdpxŽÎÀ‡OJžU–€ŸÂ¹6.“'¡ ÑÑ¥‘AeQÙ8JÚô(³L«·:ø±üäSÐëK˜îì5¸¼vÿÛ�\[‘¼ºÓ’CÖÒ%|Þ®¬'øJÜÉ/*¦ž�@Í�_”׺‡/J­¼Û½úFRøä“ð©÷‹1é釠•AâpIGWNgâ|˜„ø(G òTÆïZmü/|ÿWǤòôK/Ã^†�ûl=Rxxåªl|~ê)ø½ƒ0Ò†'d0�×XG…,/ƹÎn:¯­€JXX‡ßú#øÃ¯Û=Ñ–Á`¸'˜_‚ß’úØ�:Œ–®„䫪aÍ%·Ôm�Ãʦ$~Ÿ_ØýñLdð OÃÏœ†gŽÃ‰ƒ0š@êU¹*"5£¨ÈFJÑpk/äÃáqUk’$ýó„O8< ?ò¸„™?ó/á�ŸßÝñ^¹!Nó3ãppJÇ*)çvî)XE½5„¿Ñ…sópîšÝÿÞ+Hí ïAEk°]Æ(µ²¨(´ÂhhË Yd7º²Ð¾|>ÿ¼øKmí²¹è‰)øµ�çž„‡Àô(¤+¸´M’xºdtiÓg„‚q ¦È™F¼¡f"?!éoçháuQ–Œ%ç� mK¸pjfÆàoÎÁ;7îïxûJ|óBÔ|�ÄŸÖ«­˜j:¼&8Ǫ�l%Eääïsu8uƒ…’éÍž$ùÿõø“ïÀÒ.—öÿƒOÂÏFÛ�µp.!q‰fX9Ú´%aœŒI2¦É˜¦!ò�Jéh�8%˃$—èWpã©&ýÜ‹»½¶QéÒ¤¾f½>ð  Öƒ\lDn¬ÉÃÐ_<ù2lôíh –Á`¸'ØÀ—¾+*Ö¡Y8²Έ çô8Lv`¬íDs³t‘]Z‡«Ëpñº(WàÆðÑ9:#ÊÕá)ëH.Ne‘Z¨š!aÁu³\Ù<­ð°O³ipP°rRÍjòøÄ�Keq?¾_üÅþê>ç�õ øÊðê%80‡§áôqø¡Gd«EA;ÃgÁÛKUçšÄš\EJU:ú9lô`ySæú‚„_½,Û¹»?ßÏž'iêq¡}LM´|5Ï�j½_·¸÷ä�N[ÅÛ™x§í6Öúðï¾ß> Çö‰/ØáYñB›S;Šv]=Y”z½nÀÜ xçº(Wçæa~ÝîF° Ã='YçöFˆïn¬£3ªh$À›¸ô!Ž„>mRF¨ ZM©š°jÃÆu`•DÝÍ‹Ê »än _8|:�ŸèÀ£‡vg̽®¬ÉÆeøÂ™çÜ=q@ÂiÞÍ€Œ„1JÆ�IU'e®Ã<;êÞ�ëˆß× ‰ú~Õ®õƒ,£( ü±}»?^¬öau^Ÿ·{—,ƒÁ`¸O8®NßY&!_×Ï92jåjL‰Õ°ñf-¼AÑ«U¸0n(ìE=iepbŸÿû�Ùñ¦G­\Åó<¡s<«ó÷Öܤö«MYågÁò ‡„‚ #Xƒá�ÄÉ0Ò�$…ä:ŽC b5ª„êp\·ÃºðND«Ð…w¸Šôã® ¥ð’Ù4AžA™w!íàÏØñ¿ßmAáq™p œÐy> s<œ"Êå¨r&qz×úy�ëЃ1CíK tßÉðvÄ F° Éãû!kIn”‹ ­§4Z„ÇUÕ˜¹ Á *Ç&âl.}ü)©6¿®àØ7aÇÿ~£•5,ɽòd:£Ñ׺�¡I°2�ï.\Óó£E³åŒäó F° ÈCÓ¢^]\6­ ®#£MGIÕŒ*Ç�‡õë~ý]‹¦‚µ-Æ]6�-Jt(Ô/+Ï2ÊÒá'ö@©“ÀLJRÀOâ7Þ�ƒr<ªÌý›¡(àÆ:~½ ×–áµËðÍ×á…·aa–º°’Ã`è9i¨–Ë�LÉÑ¢^N"êÕCúýÄÁZSò%¹YeUÑCÂÄ]´UPâìú2Á2 (¦Ç$'ªLªF³ªL”ªPA8J]IØ¢öÁ*tÑ •gq{1%� +’X¿Ûøøãð¿ügRA8Ú®=’n•˜’JÒ“ûàÃ'àŸ„×߀7çá…9øæEøîõÝ'Y7©ÜiŽGuþÂÏÃy1ú›ý›ØM>Ü–Á–Á`xP1ªõaY-¸©.¸ #ÔIÏ“ªtÄU„!$”ëâZêï‚gÒ0NÂ:¡ 2UdZ{à.øãO ¹š�4‰ÚÃÔä#vr�Ŭª)pª ¼�ÃÓÅûëøÙ}ø§Ñ182)oxk »;^×|™*9  ³ºÅ… q(8Óq‡ªÑ $ïj""d•ë½Ãr° F° Ãz#Ê¢¥¶¹ “ŒºuJ³uŒúùN»S«’d÷Çÿì)!™7Qvn6n¬`>ŠG¢„�w QŠqõ(|î�=@°ÜŽœ+V+ëL¼&±¼Ùù�ý­Û�Ì F° à )¼w••Ü’úà¿ÏïꮌIEEvevÀ‘qxä y|÷çÛ‡Èðš/V’UáÎ9]\5Çaî]D°BK¤.µ-C¿šçHÅ2 Ë`Ë`0<°XÚ”Õ0íã™ <= Úôé³I %óªb Dbu«œ@Q‚“ûF(™$á âXñýu IDAT:Hm®¬ ^] ¥MABG†#c 'ŠŽëQ&#øãûw¾ O(hð¤8ºä¬*ÅLÈHÈÙÀ±�¨SSÔ6 Áë†n—u®tî·ô\ð¥,ƒ,ƒÁð âúš°…ÄA‘B–â)ðä”8 <}]87¨ÚCˆp'‚µ¬“²IlÍ�Uv>×7­uïÿx�ÍB;ò�0iì zò»‚°�G+8š—J$CŽV‹”Œœ¯þõÚçqf|¬Rv:õxR�ã\ÃÁžM KÆ9+82_L°Bø†’­Uj+ï�¼°ëË`Ë`0< ˜[†A©uùËx#�Á\½Ž+$””ôT±™Cr“‚‚…’¨-š9I7€eÚê�åÉéÉJWðpcýþ�wßDm&šM‚f]¥êý5BÂ4¢\�¥V°¦/U…¦«Äj¬"‘) •u(q”äB*�Ã�vv¾{9L;¼¶á–ðæžœG—‚urfɸFÎ4®"• é0Ï+ùîR+X¾oË`Ë`0<¨¸´(¡ºN»N¦ÊšO›$lPVIí9¢N ¬u`•”uý¾¯¿«ò¯‚#i^•÷¼“£Úw1Ôþ…;qºMÁUr±â*ÂP{9©„#$„ÇîõR;Ýé[{ 7ßZ:pm<®šãœ”™ªož”Œ’œ®A°‘^ÕùÞd{‚»ÇÃF×®/ƒ,ƒÁð€âÂuQ’Æ:à2H®áóI\%mô+•“°JYµÃ‰îc�pm‘T‰Ï]RºDa£ÜCº‚/<ôpöÚýïHGÂu¸le©*þWIeË\Í jVÈ9‹[…PiÜŸo’”q`„‚6¢Ü W8\šì~uÝÜ AÉU<)YÑ\²RçÙW¤Qw®.öBø7¡$Ÿ\Hôzþæœ]_#XƒáÅ�-øƒçà¹WáÔø¯~ þγÐêâó‘Æ�*ö8’Ö)IÜøfggï|ÚEã›oÂ_¼(ÊÕËá­…û?^»]Å#K‹ŠOyÓñÄ-c~—û†sý^p-øÎxn >~öÍB'�Öwñî)$£Î+�òÑ<×K<Ò J k‚÷9Þi…b·€KKðò%»¾ F° à ,nÁâExþ"üð#ð“§¥Ò. $«¨ÈBÜØ8Vz†Ûæ@ŽÏSùŒRs®þú üOÿnwÇ›—J²DÉŠÛÄHø«_%q/!U‚ãz¿î#ÉîÁ`uƒ¦ÃýоoƒÚ¤³r5wì _¨¥8sŽ? éL�h¬ó+xwxYnÎsQ™“,7@r®@, ú¬nÁ¹ëpmÙ®/ƒ,ƒÁ`à•‹°¸­LªÞÒ.¾Hpé0�B©I“«U_óÒ��«A!ŸùÊÅÝßf_ßËxiæUÚ Yqç-ÝB[ AD@‚c}¼…ªÉàj^©YI‚/ö€mÁÚœ9G�Ê÷ÇÃátJHÎá‹qȼγÔJ֑ͼ9Ïe .Á“Cî §äêüuxá,X’»Á–Á`0^¼_~ì Ø?�$%¾t•œáñà=®J>*Á9I�÷EM³ª\-®Ëg¾xa÷Ç·´Q+I9 KŠœ~Õ_p©L•0­#•„±“û&bUpY·9¤Gß’~†³B iõ}ÜElmÁË/Ëë¹9xê1øè )a¤€dY‰“*UE.Ëu©Ú`' >´ÁÉ ñQ[ëK…â;J®ž;‹›v=Œ` oÌÃï|>xž>�÷óÙqéß7ÒÒJä.ÄóÔá¡î@ú.mÀ•%8{U”«/Ègï6ænH˜°å!�¯ŒU½&o‡*¹u“ë5$4<¿ZÔ!Âý› â¾|¥*X¾V°¼‡õ=à U–pö,\¾ _ûÌLÃSGà‡OÀÓGáÄ ÌŽÁh ZÉÐ<{({¢HnõaeKŒjß¼ g.ÃÛó0¿"ÊÕâ¦(Zƒ,ƒÁ`@zÕ½zM6¾ý·o|o_ƒÍ®’ÄT�U{xzä8ú¬�šaZ®±½ÙsW Ö"ÒqX dØ¢ �'÷pmX\ÛÇ ,acC¶«Wáµ×á�íÔ7Á2 Ãíâ�+pùŒ´µïÍU¼Þ�=9®2M]G”«’HUP°B81¨X[³(ȵ÷bŽOÇ¥Šr7œë #XƒÁ`¸/ëK/Éë‡öÁätxÍ9 ª•§öüºNÝ §MmÓP»×K8qC¿ö´¡'Çû1Éiêàܼƒá~ µC`0 ÷k=xõ|÷mxé|àÌŒ©�Ûf2ÚìÉØ¬.ܤÙ.FÜ뽪WJ®¼—�ÜÚüñwà;çm †{ S° ƒá>£ôpaY¶/ž�_ùœÚ/ލiFIZùW…Ö Íö7nˆ|Ö0-§äªŸÃÂ\\´ão0Ü$v ƒawñây!@®UùTŪUN­\Å~WA±jú^‰¼÷m¼Å¥X3,oÀëspÁ–Áp_`!BƒÁ`ØetøÑÇÅ‚"Íú”Ç©ç×ö6@yôº2õ^\á=¢Zõ°º)6/^„Ï¿ß8 [f]`0Üs8;ƒÁ°»ËàgOÃO= <ÍÂÔ˜ø}µRHHœÆ£»¶˜[ÉV”b¸¹ÕµêÒ"¼z^»,ªÕ…E¸¼K½½Ñ�Ð`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0 ƒÁ`0þvâÿ`ËÀ€BˆÌéIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/ud_mirroring.png0000644000175000017500000000067015143647637023467 0ustar00paynopayno‰PNG  IHDR00ˆð²“sBITÛáOà pHYsÃÃÇo¨dtEXtSoftwarewww.inkscape.org›î<6IDATh�í™Á! D­ñÿ\H ;”–eç]�Z_§¬•RJ)/Ñá½»v$ A H@‚øô^033»³”;ßýuE>”“¹–wGìé:Z"ÓÖ VÓCçm¼{‘~–¦xµC‚η¹_1ù7ÏŸ£¬ ‚~;À¯©™w‚øÇ-·m ;iæÅÛ9)ˆ3G+ZJó.)«…Ž£Ælšâç°ð ë@òuGÍãÞ÷z?çz†” €Ö €� @Â>ˆsïCºQÜ»¢Ñ5Ú‚Øû ÷Aü¬hRÂ�"[vr�ÐG%¨ÇÂÇ>×_Æ–�–¬ÚOP|Ü‚ž’�k¼šOPeùS�3²Ó2ž£¿HPe®µàºƒóœ• 0pÆÈ¬ã�Fl H@‚� ÀYäJR†óIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/ud_mirroring.svg0000644000175000017500000000451715143647637023506 0ustar00paynopayno ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/unlocked.png0000644000175000017500000000055514757047403022570 0ustar00paynopayno‰PNG  IHDR;mGúsBIT|dˆ pHYs × ×B(›xtEXtSoftwarewww.inkscape.org›î<êIDAT8�ÍÒAJAÐ×"ºsÉÆÄ3ä Þ+Üz‚€w0d©k/šL¹˜fÚ™�ˆ ?ÕTõÿ=URDèBJéSÜá ÏñÔy9"Z�!VˆUã¼Âð§Cd– Üã*çM®ÏŽŠ`œ_~Ç è r½Â¸Ù»(¦› aÛbì-–¹?iöJ‘›œ×� ä5çÛfñ²¸ôˆuD¼ôˆìºo‰DÄ}½(ÇùÛŸ«?÷óHìÕ6ï1oYŒ‘öOuJT5-¾V[wRæýÍNþŸÈ‡zYç 2¯eñ§9sÀâ›ûˆðÀó!áÚûIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/unlocked.svg0000644000175000017500000000413514757047403022601 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/unsharp_mask.png0000644000175000017500000030467414757047403023470 0ustar00paynopayno‰PNG  IHDR 6�㳆gAMA† 1è–_bKGDÿ‡�Ì¿ pHYs-ü-ü®Ãì˜tIMEà %"õòJ!€IDATxÚì} UûþÒÝÝÝÝ()%pwîÒ (�X ‚‚˜(**"Jǽséîîîîînö;ç¼ï‰™Ý+pfö‚~îÿÿåïƒÙ�™ç¼õ¼Ïã ò1zF:ÿ˜£;á®}ŒwFE†ôcšÃ?mþ߇}Z|>Ê4#CüÜÖÅ÷#Ühñ»ߨú¦õ[y‚]ë­?]¸ÖØÏº÷ó}]†…øq ûº�ï?dð7 aÇo‡‡"æo]ýÒÿtå Óè‘iú³ W2¿nèâóê>:¤OËõí›áÆÀPn¹ï­>£B��‘ï»ú•ßså �ëö(€ŸF¸p�›»öÂM¾Úõu›†ÿÁ#àTjûõȨÐ"dTO7ﻯË7Nöá–Ô/ F›¡¦ á³…{øhÚ;"¤OéÇŽ¾ÿàìÆ‡wü>´QÄ÷yS7ÒË�ƒÔüY=ÛÒôWð1´½{øxý§P>¢ˆ_:þ=¢O´Ú÷ÚDë‡f.Þý†_¹R¨ù·¤»óãÚý®{øxó3„ðèߥÉðø»ÛßøÝŸÇ†"ýÞtïÍÝ8LÍ‘ïF£ýpç·clOŸ{øÂÇóg�¦ÿÁã‘é:8"„ÏÀÐÆE„¼1Ð�2ä�–FtiâF‚õ�k ,£Ãï!{6æ¨ÏZþ�Ç:—?ú3„=_óÏ."¤ín äÛ†ÑÄ÷É8çýÏo¸öƒ;† æèï;üW›?nµþæ—ÃB‰�÷\ü®o�pcˆ÷qp€œw-ÔøäôÇv¢ÇbFü¯62ˆôÂXþ‘‹CÚ]ø¢æ°·Œ`iò“s| {ÛµŸÚ%TÇ–9¤[óÿàñdiôÎÏ!kh™c>iä^³·§S�_°»fHçuD7×Þ¼wGš!Ê®ú´4þÃÇ“WëŸþ2„ŒëåBšôqã+}£µ Mo·~¨ñQh†Tfä€ÿ²+ÍOË/BFù÷�kýv£Y?’,¨«iúƒó«Ÿ[©KÃCS˜Ãz¾þ<´‡�C—g}ãÚÈÐh3Ø„üʾ�ãcÞ¾vnýÈ.!© ͈Ÿßú�•è(Ïê>4Tùѵ¡”ÑÉ�ìãSk1Z9î ›£ßuëAtI~eþñßàÜñçͯCÕÏêë�Ï÷áç/ˈ·  �œ—6_ºÔ­køa(r]sLŸ·þƒ‡ yÖƒ"C“þöu-ûõ}åÂ×ùµ©ã]ÇLHóÇÆ.=‚CAÿ1‡¼ó_qîRÜ+D,ßþn͘�¦?:ÿ†=} F Ç$sˆKç³ïãôwÍ1_·ú®‘N?‡†Ÿõ‹[ÔE£¥ …ú¨N†ˆ _:þëF½í>ÞA~eéò±ÄMˆ4ù<$]FÓ½ò¶sÚ­ùsSˆÑÖù¡ÝË¥ÖÕýðmŽûú?^¢ÛŸ¶ýBR‰ôw-†|èœWñ-ÄùºùƒKMº÷†»��?>nô>ܯD>ŠR±Ÿ[gYão�CÆ@Œ�ÿ¬¡îßxÛõúÃŒøåÍgF�ϳ��ð¶C‘e t©Ûk¸±Ëb¼î´ 1G¹31:»>†2G|ò Î>ø6júzË·Ú´ëбûtìо]›7[4oÒ¨¡/ü™Æ‹Ñ¼GÚYf?—Ú)F[çä1�†Î›Æ_ºó‹ÚüáúýÔé™C†¯a“æ-Ûtx§K·ž_ôîÓ÷—þƒ† >jÌØ±ãà3vÌè‘Ãþü}à¯?ÿðÝןúÑûo·{«E³Æ ß9 ¾ÎƒB‘e¹T©ï�q F‡ÑNÑ/®ðhŒÖnïG‘êüáµ³(àkܼe»¾ø¡ßo 5v\¤©|ìß>Qôÿ1nÌÈaCþü]ÏwÛ´hÚ(üYŠ(Fó¯BÀÎúÕ%„ø¾t Mû:M°†¹²Vl´à6>þèÒØx°ákÚ¢Ý{Ý¿úqÀ�c"‚âQ¿þ̸QÃ~ÿµÏç¿Óæ�&¾g%F£Ü_û4ûº„Ç\£»ãRß•ãu·ñÙ¯µñԱѰi«Nõùm¸0‚#%rÜè¡¿îÒ¾å3�ãM÷§†æÏîp{�7–!žpã�!Nˆ+" Æë}]¾Ç£{53ž*6›uøèËŸ�iº.z@ÿÆ1Ãûñó®m›„?e”M>qjøƒK¹±Ã¶¨'¼áçŽóWš�¿s÷›Ã>|jÄv’S5iÕù“ï�‰4ÍP ‚п|Ô€ÞÝßnIQò1òö`×Û·MÜùjŸ;š†xœWè£ßqãÉ4úÒ]}Qs@ë§ŽðÆ-ßýnЈqfè-&‘ã†ìýn‹FO$Æë}ÜN³"¾u‡ûÚø{'_ÌÓè{§ –+wß§ã\}gÆ}ÝÂxà0š´éúõ€á1%–ŒÖÿë®mš<¥tËhÒÍí4+¢—+újÆ›Nfž�vŠÍ�®ôººJP4Göˆyn ©ÇßèÔã×Ñ‘1 µ,Ý¿ÇÛo4|*1:vùw�ýÄ•ý"ã=I’Ç!�Æå†LµËsÈÛ1:¾õéÏCÇ>%l¨(;ôçžm=…@b´p9Í2Ç|èR¢ÿµ#è7ôÛίÇ8FÞuWëÏîŠM›ÑZ;Qrs” ºÃFó~nÞÒQÝcpxnÍßÿö÷1Ï8”dëÏ>jÃ�­ÖýÜEÈPwtrº�{*‰pÃç Ñ—®ÞЮ1‡Žðf?ÿ-â™D‡hÿùÍ{oÄä.¥Ñâ{wû‘]YänÜÇ| 1uc–ó™‹7ÔÒΈ©ØÑð­^Ïhì°b$bhŸŽMb.Œ�>sUÈìïÆHÝh©I9q’ ºðÕßs±ÁkþüfL�·ºý<"òYGÇȘ�_Ä F¾ïîR�;~°ï�ŠùÒÃ…¤ƒ‹U]Ä�o1<švüê™éY=n=òs—1•jí]�ˆ˜_º20üÚŒa€˜�sÝl`™_ÆDyn„·ì9hÌ? üö ý¾s£˜ #FËÝüêãz¹1Kx£¿£1G8O°Œfî1xÍÑŸ††Ñ¤Ó7FþãÐÁS­_ºµŠ‘0b4ûÖEí?s´ã££Î�Æ@\زõõrq¦ÔÕzx4{¯ÿXóŸ ¸K‘ÿn,£a72²³ßù‹˜Œ ®hOtãÚ-üó�ÐçVoö<ȨŸ?l™VÃ\2‡¸±³ª#n¥ �1Î1íŠå4ÞÀ?:„ø‘�Ú~ñ§ùO‡V#>núLËx×E‘9À…þ‹ÑñÉ5Xtb~縳`¼åÚ 4û‡X¶ÝhøîO£þð€02¬wÛ�¯“o¹H!2¿wc;¤[D Äâœè†þ6~ú…VÎhú~ß1ÿt`Á>¼wÇP75ŒV?»ØÊúÂ…fo“'f-j$âCÇ÷Ö |Ø¿„TÚÇhò΀qÿ.x`Oë§!®×]ÕÛÅ…/ÔáI·ºôbökêø«¾ïZ�þ](M�¦]û�ý÷ÁÛ§?¿ß8ı÷×6©Ínìv?i’åÑûªŽ·¤ŒvnÑ"¾¡v‰Ñô½_"þ¥ð`OrÜ�ï„T˜Õhü¹kT;sp+&oO8.ÔÈÎ_¼_]zíÌÞ¡;IiþoL®¬÷olÿΡ4Þ2~2ƽ^Œ Ü�6OÖ:Õˆù›c�úF½]мã¾Yü0uî;ú_H´~z'”‰–›†a_5rþ}> y÷¾ãë—ânÄ·¡z´†¯õwcþàQäû¶¡Œ"¸&?®» �ƒ'J²4bþì´#í†,=|¾h"xo|3âÿ왎êÓ:„Óu×qÍ‘.Û� )@ÌáN‡ÖF3— �qß„¨À4^ïö{äÿ>ècúYèLN ÷ò»ó‘°ï3¤ùÜé7ô}æÒCý&4m|£ÑÛ¿ýŸÁƒÍEþü(djî­ý¸à5n´x‚u•'ˆù‡Ó ÝøÀ� HÄW!yžFxûÇüßÁƒ=Úˆ]BVŠttË#!â+ç$§÷Ɔ ãº:ýv-ÝY7‹è’üÊxãÓÿ—ð€jý»¶!b1\ª;Í1ÎÝþ÷ @Ì~N#\ãŸ\¹Qæw¡À‡ÑðÝß#ÿoñÁªà¯BÄÛ1Úq !à s­{Lý„1G9÷»Óáý>$ü’¶}Æü?Ã>áÈß> Qi×Á-„¸`ø÷iˆ"ˆù�õ=£½+ÕšK¦ˆöñþ‡ÃþÏáÁîí¸>­CC\£9.CŒæ�; y2€˜#²Ü�¦ý]ÁÇÏîË—ámûEü‡èäšþG—6€Æ~à8Éz\[œ'HÄçHÃÏ\¡˜ rÿÃhþéáCö³ú…„ etr'†˜¿;^Gjø]bvXÀo�qåö¸Ž#¼MÿÈÿð¡öоz=$qç2û9mÑ-¯"z²ò±C|¼1Ð…Ûcþéúþ¹Ñ¼×ðÿàaûüÖ5AÄxÇ�ñ™ã2䣷âX%µao7ð1âmן[›_ÿ A†"ß´ BÜáöŽyÏéw{¼�‹'ÈX‡o¦ÑÙ…ËÝÅíGÖ¨Çá#ø½þãÃŒ ßw!æïNe§Œv#݈ù‹³¡Ñê7îÌØî.ëí¿÷>¢­DBD>rgÖôƒSkß·¦«ó®³{õD$Êhsϯº ß»ü�¿;¨;¹D|ÝÆºñÕ">rBÞz öËãÄìíìÕtä5*¾Ä·î.€Í¿ó>þöŽ�úÒuîICW,aÌa³:"\ˆC;[ã 7蜿¸< lýËðxä§_[·“¬F_¹13u8Î4š?:él€˜}æ6Ÿ;Íß]͈ ßÿUç�Õ7ìærÃ×hâŠh`„S[£óh·bu¶Ée¼íœDÑì«Ñÿáãñ¾}\®Õ�×ûºÑñíT ºá÷¦[ùÊaÓy€ó2æWññfßÿ^ýÇ~vt7Ér§¥éx2gtå@ÌáÎÈ/FwçIç¸n®6xÿë^=Ñ«8²‡»ú1Æ[®�ß¿uøN<Ò¡æq#HO‡3(8ß6rññ4î6ò?|<B"¾u7Í2:»AËršd=ÒýöñbuvsþåøýìâˆÑôÛg�ÙnÚ>Ï D·u!ï�yú6F/7éPk´«cމù‡‹ ^£u¿ˆg‘ãÆŽ1ô�Á¿ @?ƒ~ûý�a#ÇŒ‹Pþ'ÏB†~ìêаaw†fogIÖ£´�sˆ#˜-§ûæÈ÷\|4�~3Ÿ62"#ÆŒ:¸ÿO}¾ú¬û‡ïwîØ®u«7š7mÒ˜~š6{½Å›mÚ¿ýn—�?ýü›ï8dø¨±ÏNÌ1Ÿ¹ºÈÙðk¾Ô¨NCH×çééì;¸0éîâƒyÿ©•ì%;òÏ�ßv{·ý[o4mÔ0Ü�å¡)ÿ¥¯aãf-Zwú gßÁÃF�‹4£ž*Nú¶pñAM¿w#Ér8"õ¥é§aÓmÞéöeß߆G<Å`ò[7ËW„æÿÆ;£�Fg-¬ÆŽéæ@×è@FÓ/bž»KÃÆðA?ôz·Å“"#N|MÞìòåO¿�÷tPbÿÀÅn»ÑιZ–9ÒáFÿZ>@Ì?œÅ°�2ÓÌ?Ú¹†�–}c>rŒôm·N­šø —ä¡Y4y³ó§}~û@bŽþÂEE2£³óxnþæìü4:�q�/��LŸc]› oö7c6rŒüý'�š…®K§Ó¿ñõÎ=~ü}td ƒÄŒøÆÅuuW¸ï=œµ¿Ût}4@Ì?�5X¿püø\[1Ú1cã†ÿÔµuS_èlhÂÕ¬ÍG?�átËìïâÌÐ�5!‡�,£uôm›ÇÈgŽ®ÝÁ)aÖü¹©[Ï¢sL±KÈû:ò×ÏßmÙȵ9EI£–ï|ÞoDŒbä·Ž®ý0£¹sf¯SË_o}€8ÔŠkô³S| s­y'†T©ÍÈ‘ý{µkdÄ:D$iÔæ³~#bŽ`þÙÙEÖ¨óB}\7‡Ä°hµV Gt0ã§æX×&„ÇÄøƒœã£êúVã‡HZ}ÐgdL$樮.êŽO.s¸ÃmŒ^ºqFã5^wÌrïíRÒè㘑#ú}Ú.æÑÁ1Ò°õÇ?�™8bŽúÔ=u€O3ÌÞ�œ…�蘓�HGäÇå KÜ_÷��?HUþû—o5zJèàñµè6`tL„sÜg®à÷qüuœ¶:{hFGZXÆë»Fæ(—vö µ6ƒiý¦só𧉎‘Æíz ŠˆŒDôvKâÚhî8Óp8 1Þˆ¦�ó€˜}�´|=�Ö^Ÿ¸3µmôIˆã‡9f@Ï·Â�§ÄHó.? ½XdD·¸‹FGÇË!‡!ŸkÄYiã°,6rgGÊ×k\hƒÇ¨:4yVÐ�÷Þתû�Гj\³¡0º8æ[ŒjçŒr\uçïbt4ƒøÚ!>†´qåö7îÊüʌܫM£g ðÄÃ_ÿû‘!δÌ_Ü6úÆi¡îPwÇè®A>u@Ú;ìÞ�ëâÊÍ÷}Âí(sìoŸ¼n<{ðÀнý·ÃB›i™\BˆÑÌ1 hÌûŽBHË ³�¿ˆ9ØImäЭÓüÑ•Ë×klè^�q?¿Óô…fZ-?Rˆ˜[»„�öŽ9íkz>yéá$€tt&5jþþ–w¾a·�åWæè¾ï7y†Ñ�a¤E÷¡,FÌ�o¹t>tz’Etwt§ÞÖsý;€˜#�üô&HDWWîûÇcC–\ýÒ©á³€H“…"æ`—bHC§û…æpGEkÐqúßä{U�ã¶„;2Õ…h~nŽý¡Sã<0ÁïçÐAÄäBŒ7œNCÌï�µß R4ÿ@ÉU7îçèÇš¸Rü½|˜c}¯Ñ?ìá7îÚlÈrM—LUC*÷_d¤£V¯ïË'Š æÏNÈÎR›q»pË�ÐðwÍÈßÞkü�‚@ä½A¡*×Í�o> G³Ÿñ£U`Ÿàoñ¡ƒÝÜ™²Žù� VûPìxtkþ�ƒ{þÍ?"&£9 •+·¤‰Óíg£� žSž¿é"9èñ]NÙËðZ‡#z57þ‘ø åz³OB41¹’mšàšš9j5�|‚â@ŠÊ)ùlìÇn”|!Ø?7Çönþ…»)á­z…f-ÆìçBœöv"z9ÊñÈžèqi¥ÑÍÙÍþÙy‚e4s_¿ÄŒðAÃ0<"íû†d2dþìJâÙØéxùO'@5:Œ~l€üè cÖt�£_éɽÑ×!È®º7û‡Ãƒ½�:ÿ’<ë7îŽÑÊ©°†£ÒÈ.â-@F¿ã €|à,NötNrwŸÀkŽëÓ.ü_€ú|^ÿôÏP ä[7z{FW‡On¤“é„ñöèLjÙÏÊY ËüÝÙ¥ÜN#Ì?>jôÖß Ežñ…ì¹Æß?Íia#Ûü.ÚÒí©µ°œ‘2qâär%jŽûºå¿�g½�0§KKðÕZ8ûf¦³òácEs„ƒ>«31^Çvº´Á벿�ù[×Fÿ*|°dÿk×iæènn|³�œ ™õxŒ7¬ïNtùNÿ-u6D7G:ö1raµÀ>~lñoƒ½M¾Nƒ]ïcŒrC/«á·ÎžßX'¾lÆG�AF;ˆR�5Ÿn”nò­ËÕÇ¿/|ðb½—ÛFØæðN.Œxßt6.4r@81ZXžh¸5úW0::ñ[sºôB?înŽû¥Í¿,ˆ¼3Èõ‘º¤‡ŠÖã­Jô~ €|¦�F}�'X®2xÍ1=ÿkñAïVó/\&ùš\6êë,„ pBZ«”Å 1‡éüÿÖláÑ¿ì§3t£µ›-~ó·Î ÿÍø ÷«á{n;6~ç\mÜéþíX'�Pßw�È·n¨'ýŒvªn4ûÉÅÇÑ·Õ¿�ñÿèò2Õ.4{�©‘:’‘3Þ÷€Œ{W?€´t¢æh‡ÐßÛÍ–Ì'Mþýø 3‘�‡»Š�19ÿRM�¹:JÕÕk{‚¶mÝ?uòFu\wã>†¼þÿòéäj­nŽìì|Ö묔4û;ÈóTJqP€ôv«Gö¤¿ª—Ó«�‹+„Þ4þob4ïãæ*•9Ø…{çLv0 ¤¹œåˆƒQ�mÊò¤ÄaÆo4ýÅ­§lF|ýúÿ>èB®«ö)fÇ­,‡Ãó7'›S_ý@Ì_õ;I�œ¼¡Îd�ȧánM@ÌQ½ÿ?áƒ~Þìf!ò¥ó•ž�ÑzÇ9hd)›…Á¢¯7j¼ç`ÀcrØttuÛ<ø½ðÿ»�Ñâ{ÑÃñã�Ó7ÈA —Óƒd´~†ÕÐI�Õ©�‰Ñúw—Ž@spÇðÿÃ�ÑäK÷˜'æǬ,ãG*@¹Ñéõ¸™a­G:¸£¿4qv?N_Õ;ÐÊÿ¿üøº¸Wˆ˜:¾‹¾¯…¥Bx3~Ø$Â�pJO?hì»ïgw·vû¼ñŠòJvto¬nöuº‚k´rT§�qbnÓ#"€˜Ã´7ƒŒ–tvÌþΩ«Üy´ã¾kú‹jzôë³4QÿÌI×ÅINb´@l¤¯ö0ÛøØ Éämg¯ew:¼fÄg�þ�ñA¹:?¸7Qwš„7u´Ù3ÎÁ¼’²S,ýRÙI�×ìël�Ù÷¹+^st�ÿo|ÐaÒçnQ³Ì?�2#Œ÷�äÍN,š�÷ƈƒa�Ñv”°¿ç̾�+ –9æ“ðÿû�Ñè3·šYæ�N§!Ž´HÍú{Ü¡ÙãÍÄÂŽÙ;i4weÉÖý�ï?€�'ÙÕ­•šˆ^o¨Ñv¤“ú½ƒË4‚D¼¯_¢;àñŽq¸¨ù™;­û�þà ä½aî Äå°´ ¦'ý$_}íãMÆëóØÿFýV×§Ô²¦­7èÚæ˜žbùaØ>O9ÍêäÒÚ™9Ð¡Þ…ÑÆÑþDOý+ÃÔÛ�Ÿ´{XN<;Ç8«@šþê>Fvñ=%T„û6yãͶí;¾Ý™|ÞîÔ¡]ë–Í5ô=E¬í\bf9Wqêáˆÿú¦Câ­ ã´Q£“>/ÀüÙQ ËøÈ�Öè�c¾ÆÍßlÿ·=¾üîÇ~‡ 5v~ÆŽñçàþ?ÿM¯ntjÓ¢iÃ𘇉kÚbc>pøEZ: fŸèä :M÷Øúrú/ôýG¹�Ñz¨éB~Õ%¡Þ°Y«Î½~øÇÈ1‘&~,_‡~¢È?"Æ�6¸ß·ÝÚµhâ‹Ùhb´rG]Ì¡³&ùt�p’â9~�t³ £¹>SÐähyÀ±9*ë_u÷Å8¶èøñ׿ü>bl¤Ñ}7Š“ÑÃýÐëƒvÍc0–­Üª;âp´}ë@¾Áè0& ÅÒž�õ©æÎl³Œ·]ز×#FÐÑè�ŽÝ¾úØÐ„Éï_wm×¼a aÄháN ÷©Ãïá„¡aöׇgS’eZ2J;: Òšƒ¹f½áB5ñY£�ƒ#¼I‡Ïaàpò¸ÍÈÑC~êÙ¶qŒ£e?WÆK#&YÍœ4aÆtp$°àq‡ïá„èîp½‡ó'Ñ;´ëƒ$t´zÿ›�£MÓ•÷Í4Göÿò½V�B�£åW¾qßfξƻNöð¾r�d3­D[+ÅèþT†9ŽÑð ¾ ¥º�aøZ|ÔoD„éæÊ7I·†÷ëÖ"äÉ–ÑòWW¾vOgß³±ƒ\Ï®¯‚èû1Ê�‘ÚU#}ÊŒù¹#¿ÖD ¡<ƒá{ó£†ºŠ’ˆ¡}»µ1FŒ7º1cæL²ßxÏA�i~îdâq¥%æ„+8ÊI‚êLè{h!ó60›vújx¤orV‘Œøî�×Cj g¼éÆÄÐìçLo ¡ƒmQó·¦ú?~¨Ç�lMâ`vîÆˆùg;#TðhõÙocC†þýÇýÑ»}(ÈÑÖ +ªg‚5Ð'îôêÛmú>S¢¿³ÔLêêˆebts:CwC0øWkòö7C#CŒŒ##û~Ø"taÄèàÆ Öájˆ““Ð�ã”ÑÚ£æÚVíDÇMÑhî8ü‡fbMßéòà¡ÜÅÈ¡½ZúB–)¾ã‚^¥ù£#N–£\zŒþZˆOÈ7Ú_¿—þ tz{:&a}Ñ(ðx½û ±1†„Ȱ>o‡Ì©Á Ï`‡Þ¬ND²”éá @´åLŒ×µi&æpÚ0Æ[ŽYîýš‡à�zããA‘1 È´Æôé¢~µ¯»s¶‚9Ä‘O°ÑUÿ04kî@FêÎ#Œwµ¿»ù¥“ï—_Ców×½�IrõÉOð{Æö'4+õ¾/\øv_8§;˜…8hxÒŠ6ïñë§Òã5Ú:\{3G¾ã:>š#ø ­¡». j¼ëœÖã¨N7z<…¥U �îºVGí7ÕÁ'Üç°×ÍÍB£Í�cžx°ÇÑÿ}·'‡¾^Žy ΘÛoê·õµÏ�Ѻ/«>®í ;”R4jì"<š|8ô™‚”"_¿év+«�ã/õ�“ºÏ÷•þ…‡jfwÇ”�†Ú#Έî*gvèæ:�7‰xæðÁ^Šnîö³Œ7+�ŒuÒY7ÞÒ¯òtÇà _è�ÖºqÏüS߇Ãh?ÚÙszßµ7ÇhüñŸÏ"Ë3â'W÷]~æ°P7wrï�hƒôrí­+}Éjóý¦¸¯·£C{Œ[ –Ñ´Ç(3òÙþ˜C»¸(Ia8–y�pÂ_0>Чý hâ ßé~cíU/³—ƒ™œ#–ù…K^ãõ"Ÿu|ÐJ¤Ïënv$.šÃ´z�×õ]þÆhõ ã´Í²´µNôŠ>säÝ2éì0(òŸñô¶‹eÈËóK'—ï¥]-¿)¢Z3ÝÑ_1ë¯Ò·t4upT&ªyÞÃÍ@Ì‘ÝÝkø6üÚYâÀÄÌQò`þ¡H ºúŒÆÛÚ–=¯nOoV¥pKz�þ§àƒ¦Y?¸æmm4uªHú�ƒí[>fZžžÝm[ý&ï(ý «q?G¾umÜxSŒæ_�ûçàƒM‚Û»–dur¶ˆcŽt ’e¼«½b~íÓH¤nÖÑPw mþª}Ž� #>såiþÓ? ôŽ×-ö™S1ÙCxx³1ºßíq2D!%ˆîdÕÔ£tÄ21û7uã i= ò÷1G÷r«iâðxÙÑAùP�]5bÕLPõ9çcµo‘�lr]W|Û4#ÿ�÷�KÆ[Î('Ž Ì”é—€h[ é.-9XÏr²i~ëB…ôÔ ò“K¥ºñ±³$K_ÚÉ¢ƒùÇ“�bén¾êo£kWÆë¥æˆÖÎ_£óÿP|�ÏÀ6î ¤Ig÷À�š�ÑY»Õà¨zœÌ쌷t³�ÑÚ!ðÕý|íÆxðÏ.>Hèîà BŒ7�u²F9hd5Òf»˜}êD¿y_3Ð:˜6üÙAì<Ã0: ÿãƒÎ„ßs§PÿÔÙ×ppTé«7h Ä@èŽ ¿Ð-A¾Õ/�(#tw~zvøý�šf~àJ»·i_G|¸?õ5ûŒ6Úz6ON©ò8y]õ©îú¶�ל1­±…öç?´ÝëŠ#¼ÑΑÙ#KŸôn~¥̓U_™j„¶Ê©6§ k„F›Áÿx|0Ïë†. Äçh5Äæ „h[*›ƒŸôŒ¤«i‘¡]/›?è> DÝ…õê-~ýàƒjøº!éb4s6 Ò 4ô•¦Æ½÷ä1‡è–®ÚkK]µï�ƒM©ˆ®ˆÑ¼ß¿!=Ü@ˆµ\ª"ç`jù�vŽõõ“§Xæ�š7«±.+F[)Õhñ‡¯7§¤é·‘ÿ–�9¦› YV£ÞN¾C„ƒ¢�H<±K”G_ßÐh©Ùð4Ó¶²r Ï:Ω”»U¦g!n(w;†hïX8R!}ÒÃÙ£¯dtÒ,•ÌÞÚGV?꬈¯Û˜ÈBF}èB–åÈâkŒ¾ø«ƒ“²ûD[T·ãª-òídâT¨Áè<ÊŒüw!ä]çS!'®6$·×_yh;Z;n5yB€h¯Û6Ö¼9z«�i&ŽÌBY6ñû¿ t=¹Á¯³:Ý�6síÚ¨'£ãy´rõKݦ€#/`g‹èF³~ÿ6|Ðiv[Çiâdžî@ìÝø\ûº]Ÿ šº×ÚªîÚf&F{}·i‡,¬†½"ÿ…s�c…b£­ƒíÔ£�n¶ý„°G› d|¬y[ƾã:òŽȇc#ÿ•é×Ì)B|Ž|Œ>Õ¾¼þ²÷“õP=‘ct™çšò¸Ú5Ox#m"¯ù§#7)ãÍ?ÌÈç§�SŸ£� &ú}¬'sNò˜Ã4“Ý–«ù‹fïB»èqÒX† áÏ!Ƈ 6>ƒÿ…ÿ1䟞N›½úÂ6‘NÔô±¾|2€ Ҭѵõt=«�îÚM÷Q޶„Œ¡…F䨡ú~ûeÏîuý€|º~Ô½çßöíÿç˜3ô0ãt`èHÆOK‰Ûº<Ž'Pz¢4{JÚŒJí”NJh~ï„Watf†‘£ÿìÿ]Ï.[6ö…–O¸¯qËôèÝoȨˆ�‚ÄîX/ËÁ´Ð�'›Ñ]ûšOÂ#ö¶ðñU‹Àƒ}Z÷v¯1kéäk:٠ѥ¯jo}?�¶‰&@t•»tÅÛôuäõ½ÛrãíÒÅ*|„ »üæ^âÈ¿\NiöÓÞ ÑeW<~oY š&æ(Mídó3ý·ó37^»ŸB>àÆ4ÿÊ­ b:q$§¹¾o¡öVˆþ¹ùyˆÒD�ÀiþÑéF!ò±€è—éÚ¦•Ú[� I�Þ�Ð læÏ�cöh£[‚80R…Oï˜Æùtê!æï4Zõ©Ú>²FGÍöÍã*7èäMMª¢æ2ˆñ‰fÕöq¤†F>}›Å<>ÈËâÆèÿ+ýÍ}B–þÒNSÍM”ÇíéDWEúã˜5C|rÓ_1àȼßëO”±6Øyî@H[0W_ª@[]ç1vzy7"¤aÍ­ŽR„vfûÁXGiÊ›OTå°¿óé¿“¢màb~£{I]ÚìcîÂëD³Ë;º­f�®¹µÍBþèÄõbhû§„z«ú9Ž!tZ�ºômkmm“Ç$€é䳘mbé.Ÿ<>ëß~;Y´Óå©áƒ8&ôqB´§éº�^í��Ç\þÖkóêÕæà¦1Eu­¬Œ.hX=}áOñc´rê…eŽÐÒߌÖv±±‚¡@|z1mNšf�®mÄÝÈA†eökj„?U„¼å”DföÖ&œ͵s,]å!ßw!"k¤‘^)höѬ4×mµ—OÚêAÌ!­ž.>(BœÚýŒvPD}­­©¹Ðh| É |<§)-€höžu…äu/7D·q°j;�Údt¸«îd�¿�îá¢+m¼9B³ŸýXˆÔˆñ†ÞÈÖì®)<\sn¯™)øô�[Ío…?ý�ñ¾³-Cs¨~Ÿº±®¨öÖ”î¨ðñ˜Þž<%Æê�AŒvš2ÀºÎ'oü©ï…ØÊxîë9ÎYùFœÚz ºÄRŸnÅøYÈ¢—õé®ÅèŽ%u�m�÷´ß®qŸ„?ŸFß: !ú¦§Ús‰Ç_ò³_±W(«t-€|£5�nI »,¥K^Ð'c† Ézá-ÖGú«üº”ɱïêVéšc²ÇªÒµ¢'1bÔ{}|zÌss„^º£ß©ŒÛÙVÒæOGl2ý½ß7Úši§¹ÿýXsk­.Ö71Z4kN‚tçèº%Ý!lþÌ|Œ�ɦjÓØôg…ºc2ãõ!!\ßÓˆf¢9ÑݪÔõÍÑ&Ü™#ZÏ@Â~î¨ é«;,Ôß‚ÕÕmÖÝo�x/DÑÜi†PãMÍM¹Ob–[ïˆÃ’2ÄÉvˆ´7Ôí’k+ÿw×Dä'!ˆîÂm�íòêrë›ê¾WÎB€�öNÄ€ô;½ÚBüÚmGÍ…ÓÇú‰:Ñ�Ìèý~ÝŸ?Z�rgtÔ’éÓ(üûôtÔéÕݽ5ÚkÓÍÞz!Øh­wÁÇ*Š5bhÊjjþ†°GärÝt[XoÏ>ŒæNˆ½úÞ��ûé*�hÊj¾��u=€hꎎÓ{ƒŒ1Ê­×^ïÔäY ”òà€–ü½¶d’®Òˆ®*T#Í�ÓÇÙ™ÒˆfÕ¬ùó5ýâÍ~ côfGö0ž9€„û¾tR¦ëê�êëcéî„h2Þg^ šÂ¼ºìóï¢b²©¬®ÿlù Ähî` ®í¡-n¢­zÓ3tÊ&:i¯5 zLzq`×PO)Cófk|߆?‹¼2ý5qmã§Ç7%°ýJMóžÇic餓Wq¨^ ¦»�õIŒöÌ´ekBüiÜW?ÉÕV÷7}rë@[U¬¹ñ€Ôˆ»V—«¨éÕ£)fi|“á1ô!¤µƒaH/í Œf«|¤æŠæÊã4Vt¢Çž|ÌG·ŠÍž™¦à�ùCÃðgó£ÍdtÍš@×ïhœfkYs%äqÄÿu¢9˜ÐH/|ê5•5óÍ!¨þÐÀökÝ!mõCˆ¶�¶æºæøÞÐ4ó|Œˆ¥�n!Kø‚>`­ªÙüCk¬ G]j½¼®a„û5mÖ¼YÓÆ ÙrïÓC¿Lï¥ÛÇÒô\ÕµèÓ|%#Çv @4÷¥¾Ó¹€ÊóÌÑŸ8á ëkµh’h´W44ÛXºRT�l¯h¤‰Þ“¦–´¦Y‡f.«Gæ}b‚„ñú_Ç×à BšjnÕ˜Ã5i˜ºol½®€®+à#m,ÿµy7æ¢ÁåýLã*cy+|¦A´KG]}Z][°Þ!²Íü .ä‰çÍZÌsôûr¬75×BÌš ÙèÎÍ"ëÑ;…ÿä)D—3<¢£þ!ÍL;ûˆt¢/¤[èŽît15�Átç.=ÝÈ¿šÍ«þ.1AH:÷ž.@t×Rh Rhnº Ò„h* =2`ybìL×µ‰Ù}­„î /æ ¡¶šjnºŠ¹ºN:º}¥á-b’ÔúH®™ÖF¡–ܺn±³…Zp4¿Ž‘$m sM�Å1š�×Nš}%=ã›Ðp¿bp'ýÃÂNz¯˜X¹Õ_Ï`9ˆ¦7šÑES¬ê“íójP£�ŒÒ%¥�/b²*ˆaU“î1!Ú ¯¢À>Ÿê®Ájl¿ŽQ)Ífަuè#É‘ž˜;Ó5u±ºÅ¨.Öz§Þf!Žr,ݽm]ó,³¯Þ­ÔU°ÖLÅ?Ò¼™MÜHÌ*+v‰QeE½�ì“îÁí”é‘c;Ǩ¼îJˆÞn�v¦¡w´™¿7u Ÿ„JÅ.xû^kÕGW›W/q6¿{Òë|8ÎA#ëgMþ`÷P‰G¹8Szôd"š§ç|ôȧ��͘<ÓÛŒÔûášêîZ‰ó“[Ü6úÄ�­®ô‡æ;¤)]¯»òeL6ÍÌao¸Ÿø„¡|Õ””ÿÃþM|Êç±/×rèã_M¹Þȶá:—kþ{d„ÆõF¼e¹Ú£/þÞï‘QQ¦i¹Ü#®)þ'Ÿ„?Áµäÿ¬ÍH­'7ª]¸ÎƒóõŽ|‚;)ÿ‡½µ^“ðö£u~[İV¹GÄ0 oXƒõë½V§vÍW_~ñ…jÕªUé8áÂ… æÏ�=sÆ´©“'ý5qÂxö¨U`šQQã'LükÒä©ÓfÌš=wþ‚…‹ÆÖ$¸Zõ/¾üj­Úu_«W¿AX˜×â„A¯F.W¿þkuÉå^y¹FuòjG.¢—›7gÖÌéS§½œI.7~½Üz¹9sɜ׶ \î¥WÈåê°Ëy­— ‡Ë‘_WWüºýèÕØ¯›õ7¿~ÞÄI“§L�N.8oÁ§ÕðSý…_~¥f­:ò¶ßH®F¯Þ¡Çƒ‡M\¼d!~èoœÁ~ãÄ ÊEé�³ÞËEÃ_ײü8ÃþÛȃ«[§VÍW^¢¿­j�(¼•³g^Æþà¦L›>“=8~+éÅjÖÆæ ò«È�īՠïIÕ/䃛F\tW#—£÷q&½� .þõv5òàÄmô¾'ö·²jãü­„«+áNÂS›K®¶pš¯ªý5±ü8E!Ã"ÿ7áJ䟌°õêÖ~õÅê•+”.Z W¦ÔIâÆ‰ã©ëþýû÷n\q¥Ì�-o¡eŸ«òý�õÈ%à ¿¨W½£ )ôÂçKoÂ%ïß¹zöØþ›×­X²`îÌiôý�â÷rÆlv/·Ã½|x¼ ûqñ’¤a÷²B%òãêÔ­× ÌþÛjT}¾\É"ùrdH™ˆÜÊKé­¼wýüñƒ»È­¤—™n»•ã'ü5yùeKW®ßºûЉ ×ï’?ÐÒÃ~XªŒ9ò)Uþùª5^©E.æ5ð½ gïIr'«=_ž>¸ ôÁÅñ|ô�=¸óÇЫ-]8gæ´)ä=‘722Š]m΂%+×mÙyàø¹käjþ)ôÇIHocaqµúôâ¯ãÏ­nì­,zòùª7/œ<´{ÛúUË’·’\ÍòšÀ�œ¿xÅšM;ö“×äöýûΗ£?.~²tYs,^š½&ìÇÁIÂ/«¢„ýƒý3û*¯’¯Âx,�ÇSã–ßïxçÊ™#ûvlZ³|ñ¼Ù ò>³7v|•£g¯Ü!âP6òg=±¦Ê˜=¹Ï•ª½ø yèË.FþAßž:5_®Qå¹r% çÉš.y|ò-òÓËÝ"oìží�ì—ÿeÿåärs(@ÈûzììÕ»äO¼O¯æ‰�(U¦ù‹–ª@.G~9Ã#ÿyFXÞhúërdL•0¶ÇÓ€þY¿ÿî5ò²îܼvÅâùsfN�<Ñö€L›5—>ØÍ;ɯܽP΃Ÿ¸IÒdÊI®HíË5É™Ä@ @È­^©kîÂe«6Гíò-r1ÿ;ìjñ“§'¯l‰rÏÁïjÆ”�¾²äd#p|®\Iúà’Å£ ½Úƒ›ä ݽ•=8�¿,ï dîÂ¥«6lÝ}ðäśȟX˜�þáxÉÒfÉ ç ¹{/ÙK+À_¾$}+S°·2×QúÛn_>}„lËà`³¾•ä±M›IBžÚ. Ç{äO\«D¯'IjúÐJ³·Â^I–bÉÔË'þ•?O �¢ùØã$[•�³G€L´ˆ  ûŽža9ž—?Ô`¡_ƒ>Õ:x쉧o{ª·Ù‘NŸê< >²“¨=‰R%")s^V±vm¦Ç,9ø&[Ÿ+„œ|‹W¬Ý§úÃ. ±IÉN^$òh«óâõòÃÂ@Ib2�Zq<žJk‚d ¿¥xî‘{¹‘ ŸÜKòã¦Æƒ#Ä׈œ5ôV¦ˆOŸ\[yÖlݰŠdÆ”I¶Ÿ6iò4 �Õ¶í9rêÒ-úÊ~Íî¤H%Ó¨ON6xpìdcyã¡È6rµ…óè�²…~�õ Kä5ˆOx+1^@²æÙ·}ãšåAWã9¹Y ’†�£*@à‰!@|€NŸ8ð_¼ð UG€°WÈSæäd>&!–²˜Bè«D^Üz´3BsIƒü3–³PÕáõ$ÇÒ: SxPÏÑÏ~܆þ‡-àÇ@xºŠï¬�Çþ€°£�duP€LTrˆ„¾²kÒò$M y–°X£C€lؾç0<Ö£¹D“§=÷ð$òÊ�ɺf5±’eÏ•\¯³#ÖˆX ÕKBSÈ9´�µiÇÞ#§.Þ|x¡!ñ’ÒR¸dÙŠ•«“$‹–!!4Ï"øà—$g@aÖö`ñÔ¹EçxÃÅï%-Òý þo $<’ò<>Ö0ÌC|�aÁ8ë�½ öS–§X[@egw2Yº¬�x],/"H6H‰“줹$k� W€�²ëà H±Žd‡›H"kùÅs#‡Ì«ü5A€$[)²qíòE¶×$š�"‚D€ÜodÏk°òðˆ†•ˆ‚zÆÖYz®Ì©“Є å:èóœƒ>/cƒ6Ch­wk½Ž¢ÖC€¼¢´'°„åKVÍ�8CF·3ºiö¶´]éåÈc…bïJ|[I.[�…ê—jBŸW&�ØV¶¼E/\ñËþ¼©äçMR¥Óª‡üÀC'Γ›=ÈB °FÖ /½R‹"¤> $ŒÆÈÚ4h=W¶¤|qI½ ²s3keÏd5ˆ/Â>+@xɹK‰ ¢»bÈTÈn �ûäOÍ©D�2JŠeIü’x ZG "›Q|À-Ò9@¾®¦X”ÊØ'‹tyiŸOídÁd‚gér’,�$ÑÙçÙ²Î�Hl†l¥G:K.?…76™z¤×÷ª¯úJF—) XÏ_“Ý& Xx¤ï+vCHÍ|ó>��ž¸�2ÙX#V[>,À”.Õr¿úóDK½ ëcÓ"d ÉgÏ’ëòKjÉž—<]’d‘«ÖdcQˆ" ê‘+ %Y-úG&“ s�µ+­˜€Ì§‘ähnK�¥‘ /É7Èø‰ €ì9„î\qkŠõ‚µÍ íbU5½ZšµAx®ª&t‘�5äd~ KK¤ÿbÂS,úš$ZÌ?t± „ãüÅ+”"ÝÿHbQ¤×PZGlâaç"¼_À²tö< äB€ÄŸAÿâû0oZ¿2ºÂÞXìßýêQÛyÎæh>q¤×m%°è/ÏÒþ»8‘P}þ:½Ñ{°?‘9í)Á¤°^X –žk6”@ðãÏm,–;«9Öx^„,\º’Í&O]$Ï62¾!ÉÓeÉ™Ÿ¼L !¯Ô$A„`„|ê>^ mbeN“4.þ™oÉýræ( ’Kæ«­e%‚H€\©ˆõœv °ÓbHvHü™<‚ìÙ¾‘TóíýŽHÙÅZ/rµ¢HV-Dœ©¢©l)Òi ²pntEº5‚œ)B¤ŒL±|b‰†-‚$\ȦsÑ„Ô ¬Í»VÎAüíØS¨A|¼¬S:X>¥¡F"HÍ—y Ï3Ö(xƒ.œ8(F¤ÁÞØY¢Á ÉåÈXÊ‘Qí@€ÐÛJ�ÑAÉsZ<4ÿz9:)D€àOŸš~z*6ª@ëe˜¿§v˜Aþßzˆ®“¢Jg·z‚ 4©›3É Öè=qîêÿÅWE#+qª ÙH’EÊ�JU«3îIí:uê’O‚RÌV®X–$u¤F‡&ù4¿G_\Z`²áä @+AI±îÔT"‚x ìωS¶ª%‚ÄŽE:¦ÄTÂb1}p7«*5H9[Š%àÐæe#^A𠉦H§ÍÀ ì`»PJ¤Æ–.–,Ô"]džˆ <Å móηéþ­#>(D@ø$LÔ%^6z™¦Ì¬ÏÞ@öÆÞ Ù*z.A $v®Äê‹þòÙ °")Fržê @àÛ¨«`®,¬ïêIÊrž�‡vãmºera¯«2Jß‘GébR(OYœ»(}^ÙÆ*wÉ�çì¥+`ɱ ÓØ$d5ù…û�ž¹D^¥Õ™ñm�?YšŒÙód©BYL¯¼Z³V­ÚµkתIðQ½ ÅH†•ZøôS÷öC¤·Àí„^‰E�K ¬� @ :ˆg)@«ËÉFª9VƒÜ¬®_Y$–Â'¼ž„óÙ}¼xêÈÞí�ˆA.——‰Fñ€‹G>¾�èx[ð;æCúe»Ú AŽ©QR,9�ã$<\­Ó­óC¤„xƒ<_¤àâÉC{¶Š¹ï„€ï2sŽ5çY• ë!šó¨d,Þ6óa�/—5m2 �8¿\.p¼¥’±�Ú™3¦‰A}‰¼¢©m@Ä‚ëbÝr«Ólàm3Ö„XÉ’Œ`7uƬy,ÇÚ¾÷ðÉ ×îúöòÈ$+m¦ !ž¯\µz�_"!ŸW^~‰â£B™â…óåÈ”&i<þ'Þ¸wŸýB³æC™%báµ1€ø;I€”`©YG €XkÏ Qƒl�¦Q²ÛþÛ/[ºX¯(9‹¤Tá¼<‚°W–F�#{!‚Ìž-ÕDÈÕç@ WS,ŸÙîP╨AØ++#Hð© o󲄕ª7ªÊ9ˆ¥ñY�È,{}ÅHß3yá)Vç@€ð—Ò‡t÷pÙ· ·v}1v¾\Ãz•:ƒµžz4L ÊæcE}Çï6–Eù.•â$ǣ *’�÷^Ê^?=šI!#GáÜ…¥ÎìNäìÚÌ’ðNS:ùq⇬ÒiN—nÌÒ•šÙžc@XŽÅÊôÝ��¹L^¦S„$I™.sö<ù +I Rñ¹ç+U®\¹JåJÏW,_¦dÑBysfI§�ô[ý·.�9 9ݹ0¼f8.W»XþŸÚ¼8IÇÿ‡�[ùê1"ˆRƒ`ë^¸:yÎ6Á±d�€.Vœ(¥H§³íè… a’Ž胲©a-ÒÃíE:Γã˜ÁR¬ �W›oábäEAx›7\]¤RŠuAôçì(JT²rÖì—G{1ÍyÃŽ>Õ.*îÖC,x"óÅèpÓËå8,j‚’ûEƒg”¼Ü_“§‹®Ö<󉔎F¬JÕ‘Ïkˆ0éåTš*Ë/HSHúdc=’œèÇöóÁ¶-Ç¢EͱÈéÇF!;ö>yþÚ݇þ{]b)I›)[®|‹/YºL¹ò*ÒO…reK•(Z0_®¬R'�ÇÿÇžJWܸ@jtöéœP6–ªÉvN5ñûû@€‹%ç xÌúx›gÛ _ZéîóØ0-`’NG®Šï7Væ 垯¢´yá`4ìç,‰P»XË[ �2*@x¶”j®†ƒB¥ Ææ]¡¦X�j…ÍK#ˆèó*cBŸLBÄ+Gi0JWŽt–„Ó÷ñcïNÌf©š KÀ‚7¥srdŠ58¹§sf6F›a' O�M–ÒÑtÇ¿/ ÒÏ¡�%Z=²Ñëmlº�’—3§›Üç}ìCbÄ5ÕB¢h2i*¹Ý¤Lg!äÀ±3—n’;~¾™GfY)ÒfÌ’#7�H±%K•.S¶lÙ2¥K•(V¸@ÞœÉÄæÿ[O/ÿÝ«´¡G-‹X�*Ý}gó*‰�TårÏ ²¢àž²ÐÏtw@öD“ôˆ ¯:I ˜ƒˆb…25Vý$RÈÖh¢ÐÝU€¼b+Ò9@”bùmQ¬™:ão¢�1­òø,‘»Sá’±PÛ¶SäI¸Žtœke+"@XQ€ôAÿ¸Ø²j.‰¹l=•6ÍV˜T:LÀFÈ=>YB èÁÊöyYĺÂéÃéy‹²#I¢�zX•Îè‘ô^g‚¹Dž=иĽôHŸ~2„L 9–éä´Ý¼cï¡ç®Ü&¯Ó±W$B%O�>s¶œyò(T¤h±â%J”(^¼há‚ùrçÈ’!Mò„"ÁòäÙä¿uù XëWAËAÄ>ȾcСóûû§»«tŒ:P¤Ã” ¬x JdE:gó_)0Å’¤Ö0K�@¬D�Ý¢¹ò×ßÎAXflO±d âSS,{ ‚¹b�ƒŒ:IW»X�Uº{ ìb•Ë«–ë>•ïþbµÊ*ù#ö8ÎV2›kÙèƒ&©d,Èe%â\ `ðôʤŽeÎ5Ù¤°8' {ڶ„+Œä-â›p½=¼ûÂF÷œ�É3, `„dˆ$L }ׯDŽk¾�c©!d< !SxÙ°u×þ£¤N§¸óû¿b„õ;¢H]�<¼Ý5ˆ\˜ VƒLš2M%ÑÑûxÏPyÑ–�BL±,Ä´,LECw—E:¶@éî>ù– ãDÚ+Õé´³¬ HÜ$m^|E<á5ˆº‹ì¨-;EOÿ KwlE¾LyGé;ÒÛØQ/¿ üZŸOéóR€ðÁ$´•ß¶öyñ¹ÚÉQS‘Ï+9'!\/@6©Ës,lcAÂ'!xÒV¿Š Lt0ÁÓ-!$ 5"fÌš3ŸT!ë6mßCêôK×ï‘jo-‘:ÅŽ—(Yª´é3e%É�;OÞ¼yrçÊ‘-s†´)“&Œ+ O‘þÛWÎ'-éèªøTÉþâã-uê÷¨4 }ŸXab¯,_¹eWûA¯­¢Û(d‹%\]¹­¥év6/oÏC‹Nv³«EAäF!t±ªX�Q+YѸ0…]¬‰"‚¨$ìǬA ¥Ë[ؼô÷‰•[Ÿ•ª(8oaõ$[‘“?<ŸðAÁ¾üŒü1]f—P5ŸÈ8)”: b”®Ì],}ÞKbejV`‹{¢BWäÙìþl�_¦²NIÃpG‹UéÊ$Dîg¤^ãÇF6¥†âBh™ÎBÈ’«I�N“¬Ë´ ñŸ¬/ÞýXqâ'N–2Mº ™2gÍš�|²fÉ”!mªä‰ãËúÓrœÿÞ�‹§�ìß¹e=m¾ò‹I€�Ç ûïü±²plöË`wxfœýÁgÛ/ @8)òWz#oB Â(ѦX Ø/g%LUKˆ�B\ÛE:Û18×`‚ã2Af/Ò%±…ç ÉÒYWnµ @xáhoóÎSÙ¼b2uæì Ý÷Apá[ÚÖu>ÛÆ�¢\HÆò´\±•”>¨èU( ò¬­D+œè@@Ç-^íÁÒ-îæÞƒ*ŒÉÌkë†y[!›åúôVWW·n%ÁÞ+TF¼Hèe|EÖè…ø¹“ÈãŒM³L†�ñJŽõù�,„,]¹vãÖ]ûŽœhÊ¥8“½D€Ž\Ù$Yfë«>@¦à@I,òÀ$zÊEl+·@R8¸Œ\ ?#µÞ¿ «™«TõÛ Â9­|’�€„nŠÎ Ÿ¤“StNË‚²yg36¯œƒtTD°‹…\,AÔÜJÙ QvŠl9OÝ;2x2‰•™A³ËÀŽÚɃûáʤPÕQ‡ƒÒ5cM`2ÇŸª¬0×Q˜€‰È‘© 9ŽXbÂEH½0¯—‡KJ6¡§kôÒg‹ížBûà¸ì( ôO¡i?h‹…�³é8�$YÛvï?rò< äÚW™ĉ— Q’¤É“§H™2EòdI%ˆ«„OÜÖgýwIr””èVÓ k‚Q&=ì%Z·EÄbxg)­Í‹ù´Ù�ÜYðL÷ü)·‰éÁ†BZ�¬XB3¬©ôJðp‘$€ óÃX6ûæ�»gJ?0\!í¼ÍhÂ}L0W¤Æ[Ö‹Å�ñA–—¹ ,ŸT�j¢”«f�_1A3:oÍÅáû 7Î#éB¯i‰ JÏŒälÑ :>‘;é,Å¢ÒØX�} Óe&Mi?�Åí<2«“t|CY~¸êpû*I°ìÚF+@x¬?AÈÒ‘+ŸNM̯…„Rªâ¡æW}µ¹›.žÄKq³FìJN ¼ÚÞ£ ×¼h&¡’WÙÀ©¤Oé/X’jµØŠ p”1mYdÙÌf…LdNÑàP3DIäáì�äMe¶Q(çöph?@ZóÎj.)ÕT�¿’ lYÚ�{¶J¡ÎÉr¶�2[Ý\$…¨®IÐ-XØJ}^úmNÄ”' ¨�Š-XEšSå׊ˆu\Ñr”d›Ž‚e\ Ì(Ön1Çb¿“NBê×eWdJUâ°­Ktz÷nß!_Ü j�йsI¡¾bÍúͤ9|òìÅk·Ù½¿8´Pœ¿…GœZkúïß¾váô1’`m^O*�…s §N5:nÖðbîV-7;“)xs¥.¬öRµ ÜÍô¤ÝÌÛó;™Âéœv€(p¤šª�σ±,Ö„IˆhåàÚPŽ�rÑ Zv€ † ®Û#@˜Ú' ¾T< ¡bÝuÁ]¢%|~ï6‘öcЀPîðIÈÃ7R«N=™¬z¼ì&JÖÕ)Ã+e@¿–Mà „L ¬š§À. n„Ð„ïÆ ’ð^´´L¨K~,ã©a;M±Z!›_Ÿ¿Ö&Ä$di2µG!³©nÃt6+$O—ŽBR°Æ@š•\ÜCÈ"!JB“,˜§ÏdY¹fý¦í»ö>~æÂ•›,ˆ<82 F¢èáQiÈ9ÿÃû·®^<}ìÐÞ[6¬Y±t!â�Gªñ&X"ãyh½°Ç*hŸâgym³4)Á›'ÛA!Göûƒ,/3eœù\3àx0›qU8m’¹ÇbMŒ‹ŸPÂBS®†¡ÑÇ’LÕ$Vüé³åSÄopê³­gIWX÷@ëbSò‘`Íõ¾H2âÙ¢,LyYÁ(âS¤¬¥�Xº+À—ü<­lkÛs‚’?ØÉì(hc�œ“ÚÆâ$T~]¯dc•.&[.ùª³ô EÒìx·çtç,)Êzab ûXtkŠ�B@ ™þ¡�PañÕf¯mSNL²˜VølCV¯ß´m×ÞCÇH!rýö}vÔ_gd� ÉŸûñ4¹#÷n]½pæØ¡};·n\»rÙâùsgñ2�/žL ¨­üW+Yûå¸8à•�Ð*])#ä�žB§)@®€6 Ä3íó$¡ïLYØÇaMÁ¿.�ºX�5¾;dxÙ|73yBÇt±î]©là[¤X²g¶�’dåS—| • òiråVÖÅ|XæáAœÛ“W$Z®¹ – LÝ 9�‡çUÓÚÀ�×°_�EAÅ2%äÒíË·Õ>ïÒ }Þñ²�µY2$¾TÅ9;JeHÈ*½‚:xivW™¥¯á,;›ŽÂ¤)b^ÀéXZ ¶ ©z0©£¿_õ1­CÊÇ¢lrþ‘ŽÃ—-¼ !a’í…±Ã�$!3!ë6mݹçÀ‘$ˆÜ¸¹³?òí¼‰,Åy¬¤¿ZFIü÷ïܸ|þ‰ëV-[¼`Þl@ÆsÖ0FV5câß—U4±Än&{‰„˜¨IóQbOåë|ž´JGeà©¨Ž }g`c˜ñam›©_ˆµ¥H·Šß …ÎóÂ-vœ£�T¢ˆ �åêÔ…­J+-�âµIJŗnì�ž²HmØ;«Ó%@ x§–š„Wà|¢ÝáQ3/üÃ+ªŸdGÙ–üXÂWâ¼�7á}þbKk ÒÓeƒÕÔ]õ*5�àת×+|ZìÅ£µhUEM�+(xÑß?3)ß aI�̱¼²-!„–éÌ*€‡�÷ù,„]tí.CÉšd)Y²|õº [H©~˜‘KWo"Dü÷ÏܵI� Eóå/ZáŦ݆.?Ëúr÷n]»tîÔу{wnÛ´nÕò% çQ b7þ~L X r”Sg'T7˜`LîfB+°”cj¹"®–WV\[ 11–¾–Ö W‡RI,^½v—˧1}1\´·Ë5MŸ=ÏúެO%¦»–,ÃÇ5ñäÜ^Hæ}Øé<(Ïì@€(s{È­‚ØRP, )·ÒCµhê‹âõJ›…f#%úöK]$¾pvTTð6Ö¥›ôÇ/ƒ÷5Y­* ×aªP¸¸jÕ]µiÕ)w›«ây2r¦¸È±DF[úX|=�õ± î¡ŒE*VÅ®™y§,§›°«—«uúxBÈu1ËZ°pÉò•k7lÞ¶s/ "§Ï+a–+gOœ8{b…Çíë—ÏŸ9qäÀž[7­[½|É"H° €Là�dÖ½fÚƒbŽîïc«Ñ-]^åXƒÉÏB<åøjãˬ×O’yªÿÉ*nÔé¸�œ ¯?´dj0Á?JT¦{ý(:î_–Ÿ´ª«Q´ä@ŠË¹=Sw ²;xR¸N¼�Ë jd:&SWÑ¢}ãC€0ˆ@&­,¤ìªœms­Ìd+¸è~Aþòã¥òR™fWØX<�…¹„OÙaRäG�Eˆê ®)|Eúû‘mUO[èc%·žJ§×ƒQ—;d!„¥oß�Õ[Êzß±yÍkgÏœ B¦Q‡¤ù /#iÖFDöÙ÷£ºÃ´jé‚hv˜è`_ec�Ü¡…>ˆK~ŠY‘Ü)£ÂWnI{”M’Ìl˱PTͱöåR\mJræ”é| äLÂÂî¹ï6.§ÓU&L²D' /ÍŽyȲ˜ƒà‚EK–­\³n#ƒÈÁ#ÇNž9wáÒ•k7nÞº}ç.ýܹ}óƵ+—.œ;sòØ‘ƒ$|lÝ´~ÍJ?¦">ð#ÒFhÍ!•·/îg°ÎPÌ@ä‘N›óŠI<4Öå•‹g ‚�j rk@ˆÔy°p,'öܼVÝ8K–Á*žï¬üóh|]`ÆCÃ]ÿØØü ÅQ@MˆŒ ¢©¬ôqJ_´A£Œ¶®Dœ)jNÊäñé©]§sJñX˜Š a!5åa_çm¿$¢Yhö¦ù|-¿ñq¥€µ…#!¢Hñ(ºä9w³ÃŠe2^�„`£—‰Èp)•]QÉMt|X?H™®„œ…¤0¡Ä¦u:&Yʘ‚#„Çé±I‚Èšõ·lÛ¹{ß�ÃG�Ÿ<}öü…‹—._¹J>W®\¾táüÙÓ'�%Ñc÷>V¯X¶x¡´ŸTð�ÙKÀÉ ¹þÛõðŒ½@¸‰BxTˆ_pÎ'äo:•ÏËö�· ­ª@%T¡)ËIDR« Çb–Žºy>щ­Á‹œ.Öœ¼œT»xUfÏxËëD!ÉîÀ¼Ä–¥cÅ9Ð+Îa ذP6²PÑ­Äq^§Ÿ8¸‡%Y YI–%†Ld!¥:I³HY±z-�";víÙwðБcÇOž:}æ,ûœ9}úä‰cGÜ¿w׎­›7¬#ácéb´ž�jňoA‰N‡IPÅúwgE &}…¸Z&ȵðég°ÎŠ'ì^`ÎóW4EÁF¦µÁ5à~°u¶Ú¯Œ¶ë5«,Ó9«’£”ýÞH Ófˆ,üt ~Q$•qËÍR_)=3uG©:k*_•³ëÀ'²‘¾�pbÃXw]Xþ(Âbˆ§å+µ˜nìk,ÏÂBDnÈ++èv ‘üTÛ§à.3èI ¶aØä®°( d•^/ ;øBQº¶]ŠÇóÆ(B( &!��Þ‰2ÇÚ*r¬³¥8‹�yBây]x˜!4')^0O¶ôpæÆê ý¦›"ÉÂ2d²!¬RGëä3gψ¬Z³nÃæ-Û)Fö8tøÈ‘£Çèçè‘Çîß·g÷Îí «V,[²]®i�>Ñ’`Ma+pÜé {X=c >8ö޲O‘T¶6BY!§î�Á0)*28[LðO¶•pIAq³âMeëò cF>¤£í½Âï-:iÞuJ‹®§èã QYä>ëìÚ2K†#û÷ä òÆö¶àE«Me¦ì 'q yêcE³T–a�)%2,ZU¡xÑåUøA(Ê�òCDk›õ#í ˜ÞŸ( V$Åëñ6Ç«ê䎱Ý@·žXÒ•’‚Í}™ÚJÈvG‹ÂûrIœŽ¶q/[ˆ/@°gÖìæ�ûDS9 äv¢úÏù·¤ Ú170ŸñyúPíñšµh%1D !>›ò�ÒÆòü&ÚX»”ÁD@KÝ™bÇÑûÎ�,¡ ã§Œ •ü™j½ cíâvé,ÇŠ²!¸•O}Ÿ0«[›‘cR–é¬ìã}ò€½J¡Œ,¡»^÷:&YçOÞ»}”!’ 2Þ†DæÌ›¿�D‘å+IY¿qÓæ-[·mß±“}vlß¾më–Í7¬_»zår=HõAÂù+iÿÊŠ*,ĈQLAþ–èSˆM{xaŠ2æŒÒÖ¡˜¬Ñ/”¢üJ«<ºÎãA¾1ñW\ûöbíº°Þ+Tø0YñðdÜ­^nÙ¹AéŠÎ)Lü­i^Xr«£Øº¨¢&($bm*ú$€FÉõ“ÐêóÇ•É$SúñŒa²Ê ÏO‚uˆ!¥±¼)žòu•l,à2CÑl½ÛJ•ÎCÚŸ±<�C`Ø‚•ŠÒ’¯(\;b m�=[…ÞéD»æºÌ±vó”äŽ!ö ›€•éLþG†/„§SRolõ&ô;Y ©ÀVbå¸Û²`8a"y¥i7k:@„$ZK—­XIâȺõ6˜°Ï¦�ëÖ®Y½rÅò¥$¹šO«�Óé|ÅŠ¡ÝÈÄM÷=}FŒw[ɲ²xYžaYÄÈãÉswœË„]kÑvÇ#}€¨,hß^;âÜëÌPÙ’ûo+펮­„B\„‹µ î¾æQW]PcÈëµi6Ø·N=ïs)ªèšÊQœˆ)Îéû¸8‘ÔN³D|=kê�8?9TY©N‰a’Ìg£+Ê®š÷ž*`½ta ÒˆXõY®®Ã¬LÍï¹-·[!öØõ@á‚í…¨bÌ”€<`Î�„{0$–Jé-'Ët‘”^BÈÏ,Q8oŽL©¡NϲÎ�Œ“ÓG)'k ê�Ïû½˜gÍžCj‘…‹/]¶œ‚dõš5k×®[·níÚ5kV¯Zµ’¤VK/\уÀcŠ-½âº[ÔR*�ó�ðø¦*ì‘b@ÍÇpC¥R-ž×ïâ�0'Vƒ~dÅŠXƒ|¬ŠIWGš¬Ê¦ sœWßÑô̤6Ô-9Úf"\JSÙËux„R¶ðAEøÅ­^év‚X 0 ÕFÖc·sVÕ#Ãâ ]¬³¯WeÚü¬�ñIB¸R‚Ùj‚ÀŠOÝÈ·N�ÀåZ åmä¨Rû‡%¬A*Ò±Š2oÝ;ФB#½lVÈÈ=¼Õ½/‡R¦[§éܼ‡W!`þD[½Ù¸ôzø5>.„2dµ•2eÝÁ•y‰" #$ÕZ¼x)E‰ø,_FÁ±ˆ cÞ\Œ6|Ð]¬é3™ËÛÚÂ:s…5åü÷[Â$=aJW¬ “ÏzJ âå¶'|=kô~–'¶Ø¢�­ðçì]Þ¯ þœ��C‘|•:l×Ãô¼xËjœ[¯xgÁå.–¶8ŸH>«�ME1Ššüˆ%WØ© h«šØ� MNÁ/÷GÄV&×J‹Ž=7ß©\ý†’eÑ‚eˆ”rð°ÎLiÄv»Anõ8x›»sw}øÒ¯Å” ˆÌÆ�L ÁgÙŒŸ&1×ô/?‡î½.èȦé\âþµú ÂDoÄà�,Jêåu:¼ ¾¾´Þ«çOÞ»c Ûj²Ä�ñ¦%ˆpˆÐ0Y°�¢dñø�GÀè€èA³+[zÅT·è&‰†h@‚-¬mYq‹˜÷%e†…Gz˜ÅYN�kÏ—6+˜£YËT©�Ìô�õò*5H΋WÍ–­Ó¶µlË~/ng¡B„ìâÓœºØu¹‡@¬^ Ö¹½Âû¢&|ê’)—Õ¢�€x~õ\Õj/ÔxQ ¤>»Ùìlõ©%© Ê�N; -°,FW¥ãˆnßœ¹ šA§Ëf­À>Ë”ªÌ�ßáþåôŒ@mÉ_êŒFí™Á:G!Òòiz6x©xñŠ“‚ùϾþh¬NÏ›=#&Yé–úErhÏöÍ”v»X!“­Á B«kR‹°0Bã A ù,`ŸùóçÍ£à è ¥9DËôc‚T¥Cÿ‘ƒÔ&Èó�à<§û ô‰² ü>Ÿ<`j½,K8Ñsáë»)ùa!FਠL!?°26¶¢r*œ|Vú9[�•GúGv¿{ÎR,ÑTæë‹[3J®Ei ᪔¼Ðf$S,²Ã ƒ{ÖÈ�[¾zÖO’Õ„FÈüxüT¬ÌB³¬×(/Ëëµt¹•Á„ì;ÿŽd“ãÁ\ÛÓd¹ËÀG—+’‹ Á´ô`ø$¸R³¦â%ÞYV°T%Ãfü4 ¤�–#Ý„¥u·ê{Ð’­� v›…púy­x«—¤)þ6åwú‘µx†nÆRbúâÞ”\/ÞïI˜j‘\‹F’Ùsägö¬Y3 8¦OCxüe‡àƒªAPÕFò²9} fXë�“(9`ÙT§:þ”0ˆûärcß O­[üöá‰6#ÈV¦ôBd÷È8ªÕ#.g… ­\Ÿê¦­¸¤ÇŸ(<ÙG]›½½X’xŒŒ/×KñõEeNè ÈT†·VÒÙ¾ÔV0eŸÍÔÅڢ륈oж¢~áñO«ø|å*ÕªóRç5àöz¹Ä‰ÏPRZ¥h~ßo–´)�Dâ“XòãüùŠ…i§HJc‘)‚(X£Ý»&û†8L� ê>KG¼Lÿ3r$•¼¤¶œ…€Æ¢Z§—%G!K²ØYðæM¤œ\:}ìÀîm!’eÚ!BÂŒ°\k: %ü3ƒ|¦p�Ê‚‡€Çø¨¨ ã|Ìæo‡Nœ‡ðë¿ÓŠgrq#vÉNöù‚MZ‘ÌçéŽb‘¼Éd!�×èÜz•aò»À&]—’[§¶•!,yR® ¦Ćl·e€üÂÕ0s*ë‹’‡©6•Ñ7š)[¥ä×i ¨ì‚ÙýÞ€ÊÿŽª†Ë…¡,YW¹Âs•(BHR«ꜩä‘>>—­È胨�UþœÝ÷)Pi—üø¨��Hàç+ðË«9­�â�^ª¹ž/'6z™n&¿åR070Ç¢—YŽÃ§àà½XÃ#“‚B»‚†k# “,JÉ¢IV¦ÔIÙO�ÿ”!w¯ÓVC]þ›Ë¶4‹ÀT`„Æ‘É$S¦N%8�ÏTö™à è˜(Сú“àÎsàøYlñúÇ%e¯›kÑ/ÿ!a\c„"]Þ=ÉÕñ¤^c 6&\…'z@Ñ8Uøé ný[ªe`E9—ðY¨\²A°k³²±õfF§íÎs8Ò?V™&–¦²�«oâ �—�iQ�qoP®¢ÂT˜ºÌ‚±¤8®´²þ:…ØÒã?øJY†�B^­Y‹’NX’%½=-âqâ@O½Q©Ò׊¶k Ü!óÝÝ$L ü}cy¤d�"ÅcX×ÄÁ/½ hU±C¢ÒE>L7qÞÇš`íc�¹&µµ¡ŽÐpòŽÍ²rä£V~ðŠu_/ŸÂ<½TÑ‚¹³eH•„i„¦šèÇVÖ‰�…€�)X^+�,ЇŠ‘¿%“)P(Vè¿›ÄÁ!ÐAÿt$Ç-`¦ÍœMròªn� *ô“ P•\ ¢D‡gfÙÉElå+ÒmWÁÀ‹ÍLhƒ –�‹ksŠu)»~s© VɆ¿ÙÏûÜÎzK ßX¶³„K‡7¨¢Ñ+·ÕŒip¶;·>‘=ìKÕÅÔ…íºØ6ø(@.†—*y‘"„$YB ¯´™RºJü|aL¥O}`m±]L¶7¥±!5¥æ:¦;Øèµ>㔫-[SË,¦‘rÂ\;–ð­væå­�¬¹Õ"¦…´ aýå:µ_åIVþ\Â%­Ø&@È�kT"t÷v¾ «Æ%ÍRR-††‚ ö/ 6XfeZi�S¦2|€ó3¯‚ËÿKlv¼ÒT±P ؃›'^XЊ¬…\>¹,åyW=Ïx ´F—5ë*åS»J°  .�†s¿P°ÈÈÁ'Û¯ÞV$†¢áÖ+¶`üH‡#ÀüÀ*|óZ á@Óòr¼g41WÑêcy47ïaç…Óš“yyËÌã¿Ûµx™r©Wñ ¼•ÅZ½Èò‰*õ@ñ+}¡ÎÒ%¿6@idö\Xgà“Ù‹eg4iz¥JñH¶ úöÀðsé£=Û;q{™Î Ì7lc+ì1¿ïÁÈMCHÉr²;*’,BHrR—Ch’U¦Dá|92§KsÚò‡ •År`÷öÍtp!®pL "X�ŒŸðˆ�ûòãÅ/ÄR oßÜy‹²²†RŠt"€¼ü*‚x½†h¹â©A\½•�g,?�nÎ…ûï ™n”¨ÑW§*D#$¸Â}ób �ó;r h:;~â$…~~Ê"]�ܦiø„ �·A}®{£L]:)òÍ ³gdÒ”p9ÉUÜ“Iq –ă+�€ø#Š•*SݼY’Eët&!#Tú$÷ \fXÖ×äAwæ@€�5à–?h!'!¢±þZ}¯’c…AŽÅëL^ˆÕ»--³BKŽ5A2ü˜œ dïÛB´G%g‘¶—ɽgIÖK´“Uº-CÒ@«é @Èíkç!ëW¯À%@5ˆØ B²-‚öa‰æSð‰²þ¯Å(ž©™²øÁlGHr:Xkã<'MËŠRå¸�VF£¯ÚဩDö½RÞ{*S­·N'Y´þü?Äââ΂‰… 1Vé†WQä—Û _J?›�k–/Fäž.kM¡«˜-���{�û[ó./„¨Üô Žk«éYPO§y‹—¯V\פ`¯…u�®¾"¡B²²4EHÅJ•i¡Îz½,„H¹yCµµ‘å.©Œ÷åAM @=Í_x§»¿¢¹^\RðåAøÚdÞ¬ŠX¯^ÊýÄI} ›LŽ8ëôbí×ÕBpÀÆ 'b/„êtV†Ð�zÆÔIÀj³ÍMDÓ ¥:ˆkV,å¥ú”ÀM¡hë;&wg�MWÑgõ΂A: XÊv*Ym3£,cIÛü„pXCb¡py�A²¿J‘â¥Ê–‡2„×éÖ¬ÏLD&#ôò ÊÉ6Ì@¹ÃÅÀ]À¼oY2KïY1~â­ÀÃt‘cu÷sýUÀ¤Õ;0RŽBf°)’ÄÙÉ´.}�R›'YœæE„¼D2Z†ÐiH*h“$xï:�!¤R?¸gÇ– kW‰MÀ©“£Ë³ï3Þ²¹KwÛÁQ�àã"³­¢,^ª‡›Tè™sæ/B0Î ÷a°OƒÄš�b>œhf@“×.�/t“–ãÜŽ½°g‹ñÛ¦¶T¼ØUòIQ,[‹©ÓJ¡Cž€· ßÌTÙ‹š&©2Z–O¼�ÁåÔ™n½ªhà’.D#—¯Q¦.léX%Ë o Aå§¹X¯@ÑÌí¾jõP§“&åM¼VÐbÚo¬Í[3X•®ÈйÝÙŠ|*�î³xJ—-æX`ƒ½|èc]¦�cqJ¯ÝÁœÎØX3F„�;°71[£(â8bãBþtZØ€•!¯PN-CòS;óÄ€�>·DrúØAÐzc»ä"ˆèBĺrEð~ ÛvàÆ‡ä³—m¾ÆKššVèTã¬j v² 뇄ÞúÜåÑÒÃ*t» tLÀ¦AJ�I“-žGì b-ÅNòaÑv…|ÙÞjW)Ón›¯d�¡½¹E8û'ĵŒ%…ù":,ÉåXB™w‘â�”i¥ì÷J+»ß•©K©òÒ>GˆÃ€Üë�§0AH9(Ch�^‡½7RˆÈ‹u¼®‚ñÞü�…ܳHnÁª �b�ÄoúWAØfô·êBC8·í5ïc±L:ù2áϼ›}³QÈÓf�†4qÜ3båXN�2c+ÍN Öê¬^Vá†5½^R†/œ/§he%èv×Ïç!gNÞ·kÛ&’fA™ðäð˜Ë$ó,Zºœª˜Òø!ðq¡&–L»Eµ{[Óö{7ÓA:´ ¾µˆEKáQ^^ÐÄÿm®…‹•¤eH•j"„ˆ¶+H +ŒwÑ9„"D%ôΠ‡ÊΡB›™�Og Ñû‚šcñr@äX¥˜Ú!Ì ¿ô‹KÂZ /Ó£¬æS8O|»ØT}ðŽO‹ J�´N]&碤ð¼ a¬ÅR¤PÏ‘9] plNÚû"䯥³'ïß½} öÀÆ,ƒþ"QʲÕ4!n#,~À„ðZwHR¤ËÂ¬Š•YŽX§L;‘¤ã… öe›™ƒ'ÑìÿA©úÙÌ:G>«HÔCïÑõw÷p…¡‚ŠªE‚˺qŠTÅ�ùþ’0Bž¨ 29pù¤«Ü†À±¤u.n1])·EšŽ·nKN±à‘ä=AàJÏ3Vƒø#rå-HÊ�2埣!ä%Bø’ŸÕ[³ k ì.! :pTˆÃÙ�²•w$·Úèâär£…F»ù…ËEFÞ[¶1ÇóN/—#¤Ù4½êæÜB€Ô[îy6 2Ánaƒz¬×K§!¬PÏ“=SZlöÆý”?ý÷n^ÉP*‰¸’„È_rö÷xèà`¶Ð>á’e«ÖlزcÄÀÇÃãá—Ï”ƒ%X¢B¯ÌR<Ì; ¶¯Œæ�/]&4ô°– £é¨GùGܬÄÄ®¾Á [/pŒìùk^4ϘKÐÁ_—bÞ‹l Bw°NŒ²õ\YPKÊí,>–<~а¢¶³XñØRî÷ ü«õ7‹ kŠäÊWˆ&YŸ‡:½VíºRiDÜÆ^(WJòCãM´oÁÂg@£Wê+"Û¤^@£¦A^©OlõµÉÆÍ°G ï@…̱ù3C¡L�¹"„àiñc,AêÍÃ’xµN7„GÈKl^Xª(EHšäCw¾¹ë*)DíÛµ�ª¾­Xºxá< A¯ú{ŒDÙøñl‘‰­Û¸uçÞCÇN_äøx0<+@’¤Î˜-OÁb¥Ê±‹·x½bÂ{¼ØÜàLwX¹Ív¥,ýñÀ)ˆd*²|rM:¡i`Wõy2¬è˜1²7´S¸¤I�./x�©Ë'W*sïiÉ.–ÏÕ�–O”±äì ë‹¨!B››€ÇÛ5ýc8@ø$�VéYóägIÔé4„¼¤Jç£B1½üÒ/ ± «�bÌøÉ¦¹™hõ‰]¡çÖhÜ×F^ò�û¼½�4Šÿ ,ÓÙ°�òMd#ë@~¾’)g>ÚR³x¯ô½ «�Ó�ªÒVVѹ³gL“ ïÝÓ~^ª_<{âÈ~.üÒ ,Ñb˳<ÕõtüEéZt{döª½ŒÚŒlÛµïÐñ3¯cýáŸÁÏã&N™!k®<Áâ„+ àR‹ô:á–¤žŒ[Ä”�ìþ8ÍÛú)þß<Òù T˘�Ç\ óƒ/œ²u¡søÉù€IDAT6Ï€…S«î(ý­›2á\"Ð=Çæ¿VImIÉe,ùW0Mº¾¸]¬/ÂXוÉ×!‚ø?Ș3o�ÂÅK•%u:´zkË%?¾bPW-BÔµÛ[,³åEHtšë`®‰l“íY5×ëͱø%)E’-5äíE;fZ@A9�KPî+²ß@äJ‘>+5õuz½¢ ¡?••!”×KR¡ AHžly ñxÏøy!rùÜ©cI¡ÒºTq‰"³•(ä“ÀL0Êdÿ? F‡‚©%÷©Ð­>˜´ïþ#'Î^º~ñ1�¾ÇM”2]–\ù —([¡$X @0ökó/9U�Èç ¿£&¦Ë¬ó#©Ac¥Ñk?|Ë⿤– Bƒ§A}Ëvœèe/)Ô(^Ð.o¤ sld÷Iq±Ëk[>ñq¥l®!‚¼'^ò|H ´Ïí'ÈKø÷¢äjâÙˆf¼Íë÷Ș�'Y• ‘U»Ž² ­ÎÎÇ.L ôÌ9ò.N�� ûáõÓ¦*ÜÂ,+DzRÍÇ!ˆàa!‰-*ˆ½ŠðYxÈiA±aΗA˜Ó+eÌTK¹!Þð¾ êý�èMÀòÉ/JuÊ–O^á²isûL.Ái��±Ãxi´ÂJ,öûöfVýjžãÚÿ†àµ@feÍ’ƒ&Y"„ÔTÅÂ}ª3šÀ­¢¹Î‹�% ‚k®³I¿pP|éáF�|­H”ªý,úÚà^!oX–9Ÿ€2]®Ã‹Nï\.xp"z,lØçø02y.Ræ…iÈ«V„`–å)½�ܾ~‰‘Cû©ƒ©Eè*-Û¤ ¡ÌÝIùù ¶©(8`¡jÓwX²t9õݲc7I¯N_¸z‹;'Ìbñ#NÂäi2eÏ‹H xFlù3\©Ð¹¥5öxaŠþÊu,ÑYs8l¶d‚,a�Þ×�iìªQµlÌë0‹O¸ˆè¸�EHþäy(šÕ®’jb®H©Ë'¸ –j–å“`é¨iræ ;}V'WÝåœP¶@vÊ�5gÞ‚EX¡7ÿU¼ bØkñ/Á{RŠG¥c,¦KÍu,$± ÓÙIQ_ÔÊL‰|m˜ô€y%œÛ}*ënZtUÎBöERïͶØê¥u:›§ ºŸ¥×&[Yˆ�‚¹i¥ž2–ôƒïð róê…³'�‚õšh-ea„`„®›³�Á©ÀqŸÄ?Œø>E€cöì¹L!hÙòUÛwí=xä$I¯°<÷?ŒÊ‰aò4³ç)X´T9^€ðÈÇÏ0f•…m6òo¬ßqM€ A8K½c‘à®"”¿Å.i²¶ëÔS¤”ŘPt]Q4n¦\�Þ × -’6IÐü©/T WD¡ÔÄjì€ÞGÄöÞ6Áóž8·ç?¨ÇÇWJ¬òÏsƒB±þ m^ÿÅji2gÏMëô²åI¡e:Ûª´6»•æÿ^5nX ‹¢3~š.î<’šOñØGüµ°�åî¡,„ˆQ'Mt|€‡}Ü!DÒ*Wº�Ÿƒ”acV��ïGe×p\(lÙ€”Å›½!%Š ÝÞ‰Øzˆ'Ù'Ðèãþ�ë—ÏŸ>~äà^‘4Œ€$Û:ŸÎ¶qOŠ}è¤;†\÷dÈ0rIøÃÇOŸ¿rƒ—·‡g`·*A²4³å)P”謩Égè·’³ª ¤4¬.QÖ³|_07 ‡5Çè  ˆQ·_ëDT«79'°ìcK·ŠÂ̋ঢmX£ã{Áíר/•±u•U²»�k›;°’§ƒ› Ø·³ BvW…²UƒB!ÞÎr¿E B Á*„vzySIŽKÕIFÒlûýÊž3’þí ÁÅ &VÙ¿åQ)>²�«Î> !x 2Éur8±hše½P7‘¤wßd‚%„l&‘ëÔE0ýí­^ªšC“,6 y…�@.Œ ¤½¬•eCHæ´)s1vÕÍ~Q‰PµãGìݵcÛæ�ë@/‘«úP”Ìb[¶êg& €Ž¥L�‘j]ïÞèØH#>n}‘Dâ#w�"%)Åä(@x÷ ×@„|*«@òfË€ žØƒá!�³:¾‹@%JEtb¼kvÀnË(ÈàªÊŸ\_R=�[›HÊå^K¡P´lÌHYAÆüš <ªâËÜ#�C"'uð>væµ�AçöÖ…ÛÍ@ ‘�1ˆ²pëÄ?4MÚLÙrç+DBH…ç«°Â×*ù+#óË+Jñ§Šž_S f®9–`ÕÔÂäÖeyî#ÄÓ?PwªÇ)½%•©p7˜¦óNïRæ>;Ér"ÊÂä¶R¡^˜ž©Áçéä<.Ä’,Ñ/*@ì8Æf/©CBJ-˜'G–ô©’šº'÷/·¸µÚÝ›W/Rˆ�Dkç6ª¸K0²¥¯¨†É\†Š*ÞÀäæ2l ®ÜÊU«×mØ´(œëKc{ÈyzªœŠ3Ï·p³èduܬè3¬ÅÌ+ôFyÿ´$ÂN3ÀÉJ6ãU�?ÔŸ)vÖ¦#Ïœ‚ 7ƒì(žèJÛNtÅ̌ˋ¢X‰sb‹…쥎%åÀZ¾„kSŠ.¶ü�‚ØÂNˆÿ›)ÒðB»$/âàc)nh`¢ŽøûûE‹�ë�YT£,¸yV§Ö#¼�¥ø3C»Õ{…œ»M‹ õ.Ñ ÞéEN/«BëÝZ…LbÚ9‹˜::©ÓQ¼sp".VdÊ‘·0_¬À¤Þë5„â*ŽÔaRµRÅr¥Š.�;{æt¤�4Ë“ûÏó¸öþÝ›×._8{úÄ1êµ{µÙ¼‰J¹3Åê5«W¯Y½†þ‚Œuë×oܸi ³Ù³ïàá£'N�½`�ÇíY%!ÔÅO’2]fŠ8»èW­ ª‚2(½è®°Õ#Ë“k†[Ê(]·’©Œ°×ÆO´ö° ¿™Çêdõ¢êd%hÞ²áæ1ž¶÷¥Å«¢çaˆ Rk*ý�/ìžÌʆ8ÌíêÖSí­ÃQ²¥:Ésb [>y`5 Fvg=&kÛY3ãÛ•«*ŸìbùýS“&I•.3 !eʳ«&_¬ WÛÁ´Ù¼ÿb*1}jpó¹ Ä#f¦Ÿ+~|—³®º6Ž_Åiº\,B©Éu"°‘%¦…T½êt\O¿ý¶‡� 3Kæ8ãõ2‡-0÷¤i B–õâ U+?W¾t RˆäÈ’!µH³âV�pWz;ß½}�„‘³§N;rèÀþ½{víÜAÍ@N6mÚÈ?äßoÞ Cvp8D] ÏPÃèÛ÷<ü‡[¥|$Hš*=0ÏAÿ¤6è<„¹ÍklÁ¤·©{²°âöÅ ä„ôz>6R;��aÎÃ?,OÈ+]íi†%$± a!`²TÝ´æo¡¸UÔèóÐ:nÒ©áh#©Št3 ^ˆ/«\Þ¥°h|ùÄb‡8˜fPòð@nBÉ"Ý¿# �Cec!¤\Åʨ×'Û:¢áÍœ`‘EŸ@±S|dJYbÑ›kŠKìr.J¦ò±³o¯ì±{E™Žâ Q³mœ^hÌ̇2q¼½‘Å'¼N?�ê9;ócé›’r²° �iˆ�%†Ä…A”Å�W!¤T/”/WÖŒiS&‰ ’ò­%w¤ÿùý;7¯]¹&�$ÔNjÁÉŽíò³cÇÎ]»wïÝ»ÿÀÁÃGŽ�8u†yEß¹'ÝÔ/ ) #¾¸ “¥Î�%GÞ‚EK–©ÀGT*> å Ö‹hÞ�=#§ñ>w‚­@fnÐ(1~»´=ø+¾ê,ÜÉä$<Ì«8õÈS3ÓN›¨b@ *§³x[™×èƒ,ªŠ¨rÊd€Ã}‚h"šX2�ù@ÒÊQ”6Ú¹½Eƒ«—æ-²Šµs9Ÿ šøý—+Å…Bž+ÓUÖ&·õªÇ9Ðt+¶q~¹9f5×´e¸s †-…°ô±�á9ásfød¥\+OëþO;àôR‘µµÿ×xk­^Z§«—ë¯ I"9Yy Ç2Go|Bß< öR„Pno5(Õ ç'iVúÔÉÁH„”¤vÝ—ypïÎÍëÌæù5ë{áâåk7Ið�𸽸¨éƦåd¾ðT8>`ðä1ChMpÅ»ü9³ ƒœ'Î4!=~Èpé�hßÁ¤CÎÃânì�D†•¿˜d”Jb””À´É3Uº*¡dÆ#Þ‰H6¹—stÐÄRÜ×p}I¨œ@Ø+ë»P¶�%_BÏ@ø•LÒd ÚóM´YY­8n¨"u(«È"˜˜JŠåÿŠR}2dÍ•¿pñÒåhªûŠb|¥Ò±”zŒÝŒ·Z–óM,ºËÁ?BÎ;ø3WþÌ^Á¥ö†‰i:í.Ó#*{+3m²…:€�ç>Þ¶ZHNF¬Ówä žwÞóxÄúQ>(C!t?O^ èe±™:AmfU,Wºx‘ysÒ B*€H¬ìíÝô[0r‹z¡_<îÌi“ãÔºS~Ž;vüÄÉSgΞ#à¸z� ã¾D‡ÿÆìF©=>’¦J‡R|°n®ër ’’�©·Iž¬¢Åk\Àû ?ò®o‰«¦ü8ßžGòåäNB}4\õÙE”•ø·Õ)WŸDÄQÎÑYÑsëY£+îkØØôYÆ.h Ò°3,]åh¨Š*±;š/[̬#0œïšsº;ùÌO�ƒ,˜36µÕzÛgg› šk^V½ÖeΠ]vúõÖd”ÌMɃýøÊ‚{¨J«·L½�W!,µžh§ƒ Í6O‡$ :YÊ`¯7yºÌ¹X"øãL¥ÍØÀ™z횯ÐR�¥YÅ åcA$yâøðz<ÉÛ,¾îW>îß½sëæõ«—/]¼pþÜÙ³gΜ>}úÔiú9sæìÙsç/\º|åÇ]5v�g¶ì-o¤:OLŽ,ÖZ,Ž4ë—`€^OÁ‡²FÏ,¶'zꥸ(E’sQ�[âÖŽr%ÁÿS ã½B¹¤".øÊW2àXÃm¯DÀú¢I ‰�¡G›J|MèX~µF—ïp;@�ùÅ›Xi6«¢ÍË‚I �·ZAŒÜŸÏBvç"uÒHÈáܱÂ4ªp F§Äé_”m’bUpsÍ 9–bJÀÜÝp�êá®ÐM¼’™ÆÇš0V†…y·!M’­¢ÈFÖÄ€V/Ú˜Á0„2NØé¸<“,Cr1‚“:_À^–ˆ! ê1ö;-Õ!ÍbA$[¦t©Hž% òâà‹*DüI$¡(¹qýÚÕ«W._¾|‰~._¾råÊÕk×oܺ}çî} 8Hôˆz jsO¬x‰’¥J—‰T…‹²ñGUÜÓy -À Þ;ñ*2$ûUü=ž÷�•Ã- ³˜�s`ÖD9 ‡ÈÍW¹ëP.ug'L„w6#(|òîUÝt—3•I–ýWæØmQPaO%*�â(©ƒJ—Wî%©5O¡ÓÈ™•¢x *¸�ÅI‰-ôzsJ+®ùS¯¾×QS¬[¯zâ'I™žÔƒ¬L}˜ÐQ-½jA½’Ñ ñ-ˆw ÅŸ™}¿Á±,Û8²L˾Ì~V!Ñù0„�î<„ðF– õNf™ôƒÇP¥ðÁ×ñ± aÓZ¨W®Î9'�àKÒ {_iV%’f•(Z(îYhž•(.‡H‚ŠŸ/¿â·~>xpÿ>ÁÉ�Û·oÁçöí;wîÞ»O°a‡ÿîÎ�¯$CxÄI�$ À ­ð\e\…¶äWì W,fGïd¿ž2ûÐøçØ@쬜(‹o�B3Ù˜^õ }®Še’Ë^YUYC­Xg—¥‚—¥²¡[BBAå#»ÄˆÜÎòù,V5\A~èË·˜_–®r$» Üv9v’ü?¢³$ÿ‡¸p@îe+TR<†ªroѪBøÖ¾Ê%ôD@ .˜ †ÆÌðÆB;3[‚8ráÀ,IݼE†Q9X’ƒRà°­ Y0—¯Öé̈f%êÜ^eÑõú›X†0™©‚(£#9Þ0ÅD�¶{ë „�4‹‘‚ùreÏœ!Mʤ ±åKÃÈ Ãößöù<¤Ÿ° ö¿¸¸}fŽ4š]¥NŸ™†�"(@Õf@Ñ�ãƒÞ/v„3–j?ê‰7 ‚ûyrvmÇ!ºýaav2³XµZ¡Dÿ‚w”˜ýk%9§âå+ŒÑ•ut®ñ«Ü,Dø­•`L¨Iƒn5ÔÌÂù ngHk%iOÈ·³ÚY™_Ñèd3ÅØJÂ*«‡•Ë[]DP¿D›×ï7ã�—%Uú,9óbÛ„ñ“ÏFy' טd9Ö üzÇAr‰ëêÛö�Uæ0²»ÛÞâÏ\EWT�,,Ó–¸fÍnJì¯ðþ ¤×‹Xz=É>-ótH²è¸Ô¬÷—Â9Cr¦R¬ty•åä•Í®2fÍ!„ª PHÂJ,uù‘j°”U½=ž¦l:pãÒé£l1€Ý¢h6àÙ ®;]™>˜rä‚8L©À«ˆA©M^±Ò–beàD Cøä@3Ä“…[h€9Ÿv¯‡!KUPéËG {U&–µ« ©ÁŠ?3…¤Îd5×ä9–O˜k‚�9}þä|!¤<„°q:=ád¢¢%…f0 !Iž¾ñ|n6Y¨çÌWXðdqÌà•Ò6§.Zƒ˳òäÌÊ!"ˆ'uÝ/gí¿ñð±°ñðòŽÈ®Ï%ô¨ðH™6C–ì¹iõQšîxVe²ûµmø`Èõ„Pxš(ÆqžÜ¸}îÄAºAvêd5€D !Jô‹ ¤‚ŒŽ#…g,ž\èêèS߇ò%•œ»øY%ç^µ,ˆL¶q„1!It}QÑè|€æRÒ›/ÕR´'Ÿá•t'EA¥þ]E#Z®FEÓÄÛY›Ó(Ö@¸q¡ŠÔYkª¹;A²Ô°·üóZÀ6%’·A°az¼á~éF­0ò_“e YçÆlRÆí°U"vV¼*ß„†^…xÚ#ëÚ¹ã¸Z¸€M ÿ R§³q!ídmPË�óµ°£š„Nö«ÅÀP4S%Ý?LI³H¡yÖóH)É–9CºÔ)’&JWÅÀ?S‰†�>ýqààa£FŽþû ŸzvnR"3’Ñ%:â&H”4Eêt)<òS‰Ü‰u¯hzøç†XêæAÿûØqã'J’"UÚô™²æ уÀ£TY&• ¦_àIÓ+é (’Z‘M@H‚Þ‘�`±5Ú''yÀ¤ÈT)…/z¼{sp¡oáX'‰rœYÑ€{w‚-VÌmâ\Œ7yY>1^^4E碤9/A&–cB”àáÒ!VÝj&ì.Tb U¬A¸YæÄ`L¬K-пØ-Ãú¢ > ÷šÀê3-Ó‹•’ìÞèõÉ‹‹¹¥âG–]ÜmëÀNˬ0Пy;©d™>31ÿ’|±O*”Óœ^ª€ú&prt¼‰ṁD:ÝZ…ÒªH²X¯<›.�gÓâًܲ‘²,œ‡È7Òn "µk½úÊKPа(R´P�|¹sdË’1}Š‘„ñI ‰åyœO¬Øqâ‘Ø‘ÎeëÉ%XéHÏrE07öH¿¥o‹·Ñ�B–3>6.”S¦é²Õ¦*d�IÀ$ —åàY$™áÇ·à(ŸÒ–{°aȤ©Œ“Åz½¤ 9qî ê3Ò!õrË¢!¯bO5LísC¿—V¬#Dh¢UªDѤ^Ï•#kæŒéÓ¦N™œ‚„D’؃NbÇ%àH’,E*ŠŽ¬ÙsåÉW°p±èI�ëyùÁfðE^£± ŒŠÌ›=#úÅy‚‘lY2eH—†€$Y’D Ä‹—âÄò‰;Nœ¸ñâ'H˜˜€#eê´é )Fka©ŠÕÛ®VqlAJŠÐÓoyjëN ôä¨(‘s=ؘÐ�ð Ý@&ž;3tcö> Š�­ÙpúÅWk©êâŒãÔ‰ØÓä–â’ÇZJ3‚Êd“’ÙZ�ÊmÂ<œ©X¢yEà ³6ðõÅ—®#Ÿü¦Ñù :`ZóÀ¾ÅÖt\';o¡ʾdx¸ òÒ.Ö]Ñ®¿]W$‹–’†¿Ò}ÖÀŽÒ‹6vÓÍà LlV8+(ÝôrW®Ý,‹Ç‹xD0·tz©û‚ØË#g6†ì`'e2Ó/Èx»·n 3¢À$+ ¼Í¦`¯—ê[wí?Ê õ{½ãK„dÏÃê�ça¦^›‹)ª3À<y…È‹FŠ)Ä0’=kf’´iR¥L‘,i’ĉ%L˜ A|öI� A„‰'Iš,9ÁFŽLY²eÏER«‚…‹/Yº�/<,áƒÓ ¼¼þuT0ú޼ž¿aƒ�'X¼< ÂUò(!€\}IΧXâûªàËp*h¤ÕøDõø“¤j™hòþ s#%†„Øæ†4\Ôªøoøøþ¢â}¬2[¾³ÌÑ£Y�í¬•ª ðÌ&“l‘ÄždynÉVýW|*�3áèU�TÁ\žcõ àc͘œnÂë†m»¹­ ¦Äâ�^4ÁbÃB/¯}Â8e‘œLò);g?îû@;y¯‡!Æ…l5dÙʵÑú�!äFÛØ!™²åaÊS€�šJkU]ŠæxEH¢E;Z$Ó"a¤dq‚‘‚ùóæÉ•3{¶,™3fHO`’:uª”)S¤Hž"9ù¤ Ÿ”©Rh¤Ë�1Sæ¬ÙräÌ�—ĆŽ2Ô±žÃü†¡Yà«k>®'¡j£–`FX)pB«'Dô+´¿G¬e8C$™LR+�£È:÷ON*Z'Ô&‚OÑV¸ê"ÉX8%ÌsDj 1ù„9ö7Áœ ¬£+»_ª:òåU2 t€WÉõœÉ‘pn�õEuù·³fÎá5ú9xóÀ,w#:Ù>éîó…}¿N"–�SX¸/Vã'oíæXunqU‰}Ñ?YÊt¨!Ð-IÅ;½ö‘­˜dÓwRT!Lu–/Åîë—ÍL1-ÆZÔ’dM÷عó¹¹ò±3—n°¾ mb ÒIÆì$Ë‚™ºu÷Â.t` /Ž Ey…6}i!;Á͵HòåÉMBI¶¬Y2gΔ1C†ôâ“!AF¦ÌY²fÏž3GA’Y!:ž¯\¥š=@›ïEÀŽ à£|™Eò³NëŸf7åÚyšyn^�#vWÆÛRÏÉÂÍ‘µ!í½ôò8�†e)ÑU �" +¦„ÍîY3¬y¹„(A`hÌõn¼àìʽÞ€À˜Ð¢î™uŸm}1À‰$ $ø¶ï ¾c3—B2&WP¶›Ïsåæ=�%ÀQå,×=B#ª{Q3ï 4~ ²ø<™áXLÓÙ÷¼ÝJ!daG±¦´g–²ÌLɺ:_)MÈÌ¿E©Ó©êÓbå¬oB õÍ;ö¢öãì§Ÿ¨ËR‡pu¾½W?LÑGàÃKÖd¥ac‘Wh¦U½*)ØIªU¶L©’%ŠQ�ÈŸ//�I®œ9²gÏž-[Ö¬Ùè‡üûœ9 4òäÍ—ŸDŽ"E‹—(EÐAR«JUªV{¡ÆK/Cô`ÙUVABâ2> |ÈV¹¼9º'I<±ƒ-^[aÒa‹lÈŒÄ@è¢ó¦VuLÕÏâN!Yb¨ëÌyÕ])+Õ]úV"³¨çû³ÙEG9�;@•„Æ ¬/Þ¸ àgª5z¤ÜÛu‡ïÔVd€¹wN=¬¸}"Œx„Éù|ܤ´™¹•¸4×”"ÖèƒÀÎ,²Æ,¹µB4¨k‡tF;†2< “YfR|XȬ)eRA…ýQ6�ê�få+Ínc¿ŸR²È#BÅÛË0¶ e¡¾yÇ^†v”œóp„¤f1Źö#ÐB ¥ øk ©W—#¤`'!q¤byIŠ-B`R°J>òÉK>äßç/@ÂFa†�’ 8:^¤�]Œ \â"ÈÿgJu¹^⃛U{<–³;rã"-@¶m\»bi°ËT˜Î@xÒ{»¡| …1€ðUOA;÷6V”˜C†Uæ¸Í,€Ú]“wR<‹›®uÈà³Úœ©ž¶Ê>:=“ƒ®/‚õ‰˜Kž.,¼sÔ‚B("`ÜòœÃLÃ�æšÜæKö\HUgÙܦp’׺¬t¿am^ !‘ª?3§Å¡âú•TsÈxe#KöE)[‚ÉÚ DÙ¨Ó™l&YŒ´¬×Ë uF[ܰe§ÒìÝÿšD_;ñ# ˜×Sš¬>Ex¢EÃ…-Ø FH®U‰€¤BùreÊ”&±¤xñb(EŠæòï‹+V¼xIŠ�²4³ªZ­:¼4Çч”08ãå5®øøæWR%Åø‘~”e—ÏÒ„Öe<Á ÂRç2>�»1- ¹ÐPþÚOâÊâ"Õ¶Ø!Ó½ŸLq/ÍYÑ-` ª;*D|b5±ZYÉ)ˆôNo!׳7Oõ¨±ÖèA¬zæ'Wˆ&å­ë‹ÂöƒD�Sç¯Þâ!äX>n¤š«€B³ÙA(wFTJ‰çûÕÜ“©(/Ó%±š·/~�gŠâýÕ0® LøÓοs•èûvnÙ°š U °JÆø£TÝ›½3D ‹·e�Wše×—«`eÅ®_ö- ;n^t–â,§äÜd’qµ…†2y¶O¤EMᣠ0£^£¯FEÖäk¦Hþ”®¨Ôè>uNî9zR !Œa@½ê…Ú5? ®4'ûßÖ-™ 9¥—VgÁLZ„3“Ëݸm·èšôÇÕÛÔÌ[S !^ºìÚšô¡à¾e¾�ê0DaU–!C±wíÆ­»öáCÿ�:±8s1ez¦]Q¢ŒÜtÅz9,L9ÑØ™Ž™}oYS‹Ä–l�¼ø %ÕªV­R¥råJäó<ÿÐÿ@�Q¥*Á� �Y:€Æks”0\êñ…ª•(>¨Jɯñ»Þ€-Ðw±  S‚⃱—0©†Ã§.?íbQ�ð}w%�ðª¤X/M΢ìIQ唯/^©(¬Oثι`ß¹õ:~FšE.ÀËtUj®>—À^›Ø+,.µ’LçkS|S·B¬!< .m“‡|y�¦ƒéYß½b�F«ÓÙC‘­^^§7¸Êyï�d±¤b:özíóBÖÊêû¦m»„œçIœ2]¦ìy³žfAM`HO{nSñwf#4Ù" y…¡¤F ‚“ê )üS�|HÔx¡‰/½Œà`èx Ðáåm3´äêW^L¯¤*•ÓÎBêsÄG¬N7 š^<}”èŒ}CGè–x©ÈY =„pòÿG´°X©ªÅmD“Aç”§9qþ´Ý?2 ‡MÞbûúVMkϵš²®çS½Þe•q#‘©8µ Xñ»b ®Û®/"�†zœ±H¹7‹X_¤!«Š:G—%:I±ö9u¬3„k<º§�Ïžcù¢Û#ƒƒ<ü6wíàF‘¸,„Xû&>‰�·‡ Éqºa«B€pRÄm 0M4ÆÏw¯Y’µÊ2³MC°•µ`ñr:ÙM="ädë¸(G•(™Ì¶¿,ÍR×ÁÕ²” #"ת‹‘„¢„„|(Rðó"ù¼D‘ñò+ ;X]ËŒ\nIì„ñ�-®ÐU¡lÉb`È�~ãv<Ç}n\:sìànr'Vc�ìVÀ´x™ÁœäªqI=0‡@§ìú-“`%zS6a鎜[— …Ì&½®ÔïØ—]š…Ã0UFš±,% Z)×Xö{ƒ-LRTGy�>/‘m}QP#E�Î~¯gïÁcg.Š2Xjr*Íáh;à(*)½w‘Ãd¬ƒ–éØéµ �ðHî­Bª)�,® ÕO-Ùê¥öú±0=v›jã¼âí)[Y –,ÇrêÂÕÛìݸÔX'ÔÐËW¨hIEpGYÉP+g4xòÊ\«‹$J(L(äó2ûôóê+äC°Q‡Eúwþ  #\q“Þ^U«LÇçT'8sº”|þçõK¼_qüàží´@_²€ <ÁŠ \Õ_²Ü"}ïÿ%žœ� ‡#fÙaáB.Nìa‰Ž­Ì8£¥ßxº#­ÒÖì¹bŒË„ãã�qŽ…gR�ûøøþ"%±°)ræq\2Qåt½¢r:€×èÜ}ñU ŸòMÄy»ÓïߘËtU0úX–E²ÚB” ñÄ`5×Óô‰Q�!„¹Ïng¨´Š£cTB¬³¯ ±ªÀ&Ýâ”,Ï·Õ$kƒèÜ-Ôy³wÉòÕ !Gi�=¥½z¤b4ºA€­)m#/J]Æ•qDɵH”0˜°O-ù©]‹þuê`VŰ£ŽŸú׋æ.È×½„åG‰"Tižz1`~Õþ2 @hƒwï’kÒj �I�lFˆ½,f‹¶û��Æïž<œ…ÅÈs–¢ì¢ ™fK‰~ÜB3 Χzä|ö;ö›ÞÀÕ Ô‘Ç�EG¾ˆ$b1»iR‚0Å7ZXÈM2Á‰¤µM–WŠQ‡«A$ܳcÏAªc€!äêË\-JuL¨g7±ŽBøjz�kêù±jiðóƒ‡؀歓uY¬!DV!’íŒ1µ_åu:“h�IÐɺÆh½›!ɽÞñö2„5{!Ûw8*:Ý7û¦öHÏ�LBô³r5.› ÚY¼Dà -e©Š½é$ &¯½Fs.û‡þ·õ(Þêã¼ÿRà  �RTE(s•*^8îlÒVԯ̀Ð/9& @;¯ ¨ýÖÃÏùs@Zƒ¨@xÏÇ%Åk½Ì§èœóáùIøñ±VFž)d€¹zdX»¡ H–.‹-q‘ÒÐ�D,g*ÂK'ªžàcÂyŒÊ+t#�Dî0³Ó­È­sÂdS€ÓÝ·îܧ†�HtN—ÕÚ�–ú¨^I鵺vLBÆâ d,òÅÂ`e:SË¥OCÈçh>›š0kÍWÑ{–O°Y‚uzÛ‹Q��dضåWÎÑä‚ï?”!ˆ�I B6oWcÈýñÙ±Ý715LÉ™—î¾Ò ÂTµqlè•U´t’SvhþB˜áŠøÔÇOƒüæ•/ Ò#CÑ o˜®c6 ¬ü(”/W¶ ºÝ»Í5ÀÇ•s'�ì£ zØ„0h‡w2×BÚ¨¶xeàÀ9�Õ3{»DêÌ0Úfº™w !� ÉÃú ‹#­nÓ\´ZïÇ(*\Ç\ñã³Ø,[ô2oÁ)Ș‚ &UGNåes—ý\TqqägS¹Ã@;ô)¢&ážÍ@Ü»ŽŒ¬ÝYùªŒä8rÁIÁv@5 [ã­–”é“ÿ 0íÀa!†PØž]]yø,¤¦½Õëu:ÌÓ%ïÝÓáŽJðVùGòåˆÄ$ë/‡Ì™ÏH'4†Ð)ióËr}‘„ÉR³4 jõÊU«¿ˆâ ¯-E”d‹ÖílŒ¨@¥�ú‘‚Q¹aÈ?ìÃ�×uÄþ.1²ð6%9GQO¢Øñ}“÷ïܺqíÊe”ûÝ„ ½0 ࣼB¿îÅ݃ôŒJQA™�ˆM)C¸é²"´ ß�üá¥�Éêå™6º‘"B»Xpœ?lç jÇ.)̪¤-P‚Ô¸.DG£/A”u[1&üÍÃUNó󶲜KÊÓ.ÜçÙH%kE³Ó»–éÌ­Ar,{ˆÍwÄ/¶‘eˆUïôy�ö;Ø3?èà+‚AªN Á9�Ò�ê0…réâ rR#üBäêœÁ:1H „ˆ,‹–a—oãfO�X<ÍJJÓ,Z«£º!+Ö½~}I±ÔÓ|}ƒ Á ›_Ø Ì*¬U0 Qæ«9Y|°Ñy=.ȅქWÙiyŽí]OòÏnr|œ<¼oàƒrn(>&YÒÌñÈý=Öµ›Ô hîñ“1c¡RêCS2]Z ¡2é_Ÿt¢b Η‚Äù%ÉÓ©uçÊuŠDÄ™’r&QÌFqúhAUN?à�¡Ìe9À©°n«’ë;‰¢‡ [r:¹4å‘Üo!?à ª”QÀr™û3Ûæ¨…E‘çO¿Ø¶ÜN™ù ÍŒ&ð2ŸòM”{´§ ß½ÍÊ)¤/S i}¥"ö V/³ª™4L²rïàÄwQ†($ë:a’!t¦~âÜeä¤�þ žÐ�Fyu8Äq"–rÝ'×Ðl¹RÐ�O(gØŠr¡!ã”a˜}Ô`j\´{E=|Ò¤HÌ%OS¹ø¸Ló«]lBñ ¬‰Ñê Y�·üŠ)Ùö¢öh¤Z2ɰ9ѽîMnÜIKôÒÊ*ˆúN Ñ­Ü?,ÎÁ`Œ^E¸™¦Üt…â¶NãD ½\³˜aWå•"ŽT×ý0Ƭ/Ryq}Qæ¥)–uÕïß�Õ¦v(Í5ÃÃ-ÆOèW(™8Ï�E3^ª¿"©–aa”Z…@}ˆá½§GöOŠ”,k=½”å[>OGÒ¢H²š�Gâ;¨oceÈ<(Ôƒ´²þ²#dÿágù¼ôÊ÷YDš•4•"e¹HÕ«Œ|‚åº Ÿ:»°¬ÝØþ�°”ð),<\m_!Ï«�Ü�!> PÃöÔÉ„$pž‰÷Øüƒác?Ã9�°Áx>ˆ‹é„IïÆ‡½¸3]º‰… Ñm4ÅÚb&z4±æÓ&ºM³Ó‘ ˆ)á½Æ<ÃÊa˰đãõZUNñ¢¶«nºË¹^į·Ù‚úçñÁœÂû¤°¢r ÍZËqå¡mŒÝJyÐBä¡yQªª&gøø$G!¶2=áte±TYƒ…$‘²N8UÛ‡q[V%„+­_Þ0© f|µ”$+Þ«X}`ÔyãÒiª”†”‘ƒ["²¬ù‹è<„ªû?s‘3ÿ§⺠ñ§�A„ë•Ù¾¬kÔ«§pBijŒ"¢–ˆ$>Á –>W\´�U\Ì™„õ®¨ñÈÊçË�-Sº”I…5I¹5~˜^>Kê�]Û6­cø˜#ãÇxœqFšbL·ç —óö¯È*l·ò‚�ü‹¯`-6�Ž-Tè’÷xóT+Ðè† ù²ízEåŸy!*¬Ø•ªïÅ–’°�•~ÇSÂ:zõ«h!‹ðsƒ– 0&\¥-LO¤ØÛ–—*§†|Œ¼H_A^S !Ðée^î(‰¤|]KŽi¨Øàša­àöã±}Ö4Ô¶� kyÐ'¶˜áÂó‘-x¡pbÿLÀAjÑâ¦i–ù~U©`ÃêåK@+-B,1„ò²vî=tü4ú÷4Žg "Ùrå-XÄxèÆîl 3Dlü…Û"ü}ªÚ«Ï"š¡ŠøáÿU,›ÔÕE.0T¾L©b,|dH#¦ž¸MöÀï¾Aû»4~¨ø°þtøå“… &XÀ7¿ø¢¥Å[žQâÈI.ZXD5l‰õÝC¤ssõÀÙ3‚yÑWjƒ²€2^ͰÊJ‘¯lu‡IQ^…ê³·»WÏYÖ³¹‘ÞkÛ[Íùº­7Üž%‡{–Á9r\„ècÅá9(2Zr,A7QöÉØ]ʵMtÂ÷l儬hù&‹XÙ$ªð…–4R kZþÔ“v®> !uD’Eµ ¸šy¹#\­VMW-·-þ!ä�Ø{ðØéóW°T¿Ü+­´"H‘šiIƒœS;QDH*«ªùj˜àIm¸ÏÒV_òŸ U9EêoQ‰:ª–Í,Ò¥J–�ë7&ï|~õõK$~�úcäWÈÀ FG›¾�ËV­W,ÿ�ø‚ÊMeŸ*Â^ŽRBÓX&¯…[~åÚË7Õè6š ÚØðéäÛ¶ ‹K€ +>9F§‚?…Êiªµ6ç�9�VVŠ×Û61¹ò|P]w–IŠÃ ýA–,§ÛC¬‘­Œ;aœ:˜ ó³—jʵ)žÔWœ¨=ÄÙ.œô.ö° ‘+ôžYòH± ùÎ# YŸ��ꆕ"É¢ãB\zçRNβiˆÜ²#d‚ub¸˜¶ì #Ãs—oB!roaq� ")Ñ�€B¤ƒÈ‹¨YUW„o˜×:`L·„÷]¸­„W�uQâ…êUhñAàQ8? •ðáÉ0~ó�ëÏ?´oçV?–°ø1�Ç�ñ�tMò£á`ߘ‹ŠÎmZ0Ýwæ±õ°^|Un!q‘:)…P„ þ@g¦ìEÉ®çVVV¦bÔë¹M»2Ùö{_RE•ò1ÜçY´Tˆà(`R�ãLË7ÊøÜ_4‰Y/ÜrŸ°(rŒó�•JmJ¹KBÔqú‰êžÜå´‰^¯!Lêä0¤Ês”Ö›;—+HüÓCeBjÕ•¶Y²¥—3Qô²„¬Ù@G†¬TÇBdG{îØ;^¢ä©ÓÓ<+aª[E!•GÄ~½F@OJI¥|JÏÊR²s1j¹¤ X�ç*”+ÍìHrfÍ”.UR>b¿´æ›·¯]8}ìÐ^:ÿàø˜JçÄàKcÂq‹Ü{<ůùP¸"«ÐËӛ϶rÔwk¡G9Íuäªm¦%b}W� *$�òT¦û/œf³¹Û lò즊qÎ=»Ê©�ˆe]–º+ö{mF ô—ÊÒCh�zX.ÊBÈp÷Ÿ+m.®ÁsBC¶ -Îh¢×w 'd�„£çC¤ 0Fã�,™‹FÄç3A8u:JÑC †!˜dY›3¯ôã>öie‚QßB&XÆ!P©“ã”äãKW¬^OÛ½¤T¿€Suÿ�¡y¤+A’iÒgfªë +ͤݠ¥Å1‚qÄB6TB‰R�ÈÃÓ0ò{Åô„j¾²tT¹‘À£HÁ¼¹²1ãPaÖ“èÝÓPžßºrþÔ±ƒ{vlÙ@ç´ò’‰e›YÚ í’ÆØMÀgèÀâ­¬ôHxfn $·N‹Á»óCé÷µq�BtŸ H'p"ÈSñ]Â[uÔ¶i "ŒÑëaòJ³P…ê>I]ó– ð0á‚&Ÿ+%ˆâ½æ ÒRņ̃C¬E ÿ!}_HŠ–Ö·Ôj^È‚ÅÂ\eä…³h¿u\¸ÏΘ�^ŽÓé–0ì…\ªá‰Žé EÒtì%àdΗƒozJïâ¤,:/„‰ú|µ�c‰!tBÞº²ˆ dÝFVˆœ"…2Ó¶¿•ˆC$n¤)ÒdP BUªq«ÚÀÉEökA’Ã%{]m|ŠØ€o”ÐÍD¡“òƒ¤8O™$�P�/<ê–(ÏO=°gÇæ kè|�áÞ_Yñ�ÞÃ'σ|že&xeÈÙÄ+tA2Ct/Èû×B&ƒ@R, 0 a‰Îܦ7€¶&Ãæ¶Œ Ó]Ÿ•’ŠÑ‰M>(È‘ÛT+«`ëYË97’ šÔS$†ø¬�+s‹qœ@'‹q²è‚:e-ÂIöÖ ®ápò𾢕%Æ!–f«Ô§L£Tó±™µcå�ˆ4ëæÀ"±dž•,eZjN�¯ÓÏE�7¡´Pyë $^‰nå.ðng¤ »1 À¯ÉÝv*‘B•¶Ê<¨c(É® ;Ä„u7ø±ü¸töä‘ý”ßø õ‡ˆQ‘Šl…(бÃ{œsð®4F³-:¡G“¤úHžª!¶:Ñs8?Ê=u¯Kï&î9T�™›ÍÿO±�ôÁè±lsIUú|ª¿r ›„Jë‡6„+«ñ–DLA6g‘%H€»z¬ÑI:cÖ®ÅÉÅéR´0c¾\3ˆº‰˜¦c§—}éFwáòÂyÑØ3«‚Gϲï¿é Òêµ$Y ]¾c/““Œçªiñ¿¼Ï õ‡èD}ut#3ŽÆ~gÄ,YˆÐ4 ¥^µJâQ ’ ü;¨{IÑ­BUt_d©%7Ÿ$‘âX%Œx‚ÿ@ò‰à3"7ž-ì:hnÅ$Y3Z<§=~[öû·¯²ò|×¶MëIF‰ñ# ¿R÷)Ñ�n7ëð²Ûõð³¸Pv2»Æ0CgD’v„qQ.Æô¤¸@Ò,ñ£©Ó¦â¥gpíY›¾ÿ©âò4·�Æ¢ñZ2,>vy4 eMÞYv+«ñrð¾´†x„Ä�Uå4Ü:­e\,¶4³õj�ôìÿ‘SAF!ŠÌHNÓYØ£Ù( ÿ3®«·¸âÈ7�¬9<„p)ë•Y=Br¦@ÑR"Ò³‰œ!-u°“Æ1”µ(Ê�TýAdoÔbŸR„@3kéÊ5´Ù{èØ©s—oð 2±F\‹½fZšhåÉ_°H1.†HãÈËl ª¶Xó`0±PÃÂ,D_„[B¬ƒ’/³Ô eA4žÂ#->¤Ç[bc5”÷n²òcï®­›Ö­&û©¢m7>*(>èó†;¼‹2¢ÓµÄ– –d)âJŸP–�"*�F·•ÊÓbZo“E›&l¥ÄªÔÔ„BÞ¿ %Ÿ·+é° Kµ¥É¸MÚÒ(˄ѭ£Sò0öKÛ©}eu "ÙtbÊë™É×.©Ö îÞ²´„x�ë(Ôï}XÇ`§÷¹5ƒ§IË{B!k'Û,çȉʛ©V! êGã-ûê½cñfcvH$YT«—Ú2×Eop¶’#SšdÀl-¼ uÚÊÚ³mÓ:¤íMã]±X'›YXˆìØKÒ¬³¯ÝºAäü'Ù…eAlðÌœ-'u*À0BR­*\¸‡ƒDnC½]Ryë7Pøï¸Ÿ[»6l±sa-*>G…~‹R#]�t©“+ÅG¬œ?ßé)?îÝí«Eó‘e¯¸òK©y]™ÃU¹›)$X­ æ…Ê yDIø—è]îÃáÙÁEU-`¢v„ØtØË�É–mU¢"§×W¿Î×+,æ±ã¬¬„Ê)R[P¯Ú´ 7RêËúä¼Êþ3„º˜ Úz ä(„I®ÛÊtÑñ³vÄÁ÷i3*d�<,:âx·l GrœÍe2ÐÈbëxq´|"õP²@F®>&YÂ=†íNñ�:”!(íñüqÙÊ:°gŒØj§öB°ÝK ‘Elf¸eûî}‡�Ÿ>…‘‡Û:$µºÐ¦IŸ¬ Š�j„`¤‚�~{ñ¥—تy­Zµa×·£ìö`aƒ-¯S± —PQ‹ÄŽòe©T|á‚ùó’Òœ$W*<<‰Ûîaßëáý[W/œ9qdÿî[>Ο3[ÎÏ'¥0£^ÅvržÃ%�»mQðˆ%Xx*‘”+tE2»^½:B Y™�Ô¹ Œ(6¯ã«¶ÈÁ‹²j>¡K¥´¿8RˆAØfŸm¦€4%Ã’vì±æct´mâ"6ûqÕM²:ð=H@ÄâÛ'–•)cÖ²FÖ^:5‚{6(bŒK®+\H‹Âµ1SÍÊ}Ÿ¾j¹(}‚Ûé›Ñ€_âÔé‚÷.¸–8.¬ îc@9¡îJÀš{ã¬he±f/U7'Ïl¦R¹A)DH©N'"ë7oÛ¹÷àÑ“g/]ã•È­ñµ©IJ BŠFFÊ0ŒPñÐj(äÃjÁÂmËGìà ]‡©øIµ*¤îàè F ¹sfËœ1mªä‰ˆÚÜ“ ú wo\&é-? <_HÇçÓè1<¿BÕ<”·ȃ!É=(öD,6áZ¯­B­¶jô…Cô”óávŸÇ"�Ä Â$Ðb ¤øû¿Ç=ð9VÔ¼ÒìAšb´ xÎYwc“÷ˆÕ,4:ž‰\G‡—Ø´„͇OeY£G!t“–ƒkÆi|M�”�vX8¼¡tàaÒ”—éØé¥kôðÅKŸTŒÑ6¬±Þ/[#‹mE%è,*ì5°×éb"äq1½^V†äÊ Âcõ¸Ç©ï§ŽBèrÝlxy&N°³‹y©3C–fmÙAju5ˆø¯ÿ^-v܉“±0’-u0( $•™*h_ P¬P�þa:@TˆiËU£Êr*yMc5s#ÁƒùæªöëYºï}€Õ §�¦éÕ’^ñòœÿÀ ø #ÑyÜ@Höô÷Wà´$©-Ì;XxÃüBPÓkî+˜[8E¦ža©@Ð/È�ˆ=ÞÕ•}qr)틤B'[Ø=x­F \cè[)ZÍM›‚1y§Î˜c³V>TÀBfõçFúTŠ)«DXuNÒ«ysÙô\”çQÁê*·ŠîsÇÏ ·–cQ,@ÒPÏ$Z€Te$^Ù W¬Ú¯ªÂÈ«óîæÄ9µ…¥ìYGZäИÅ1ÝYžRÕºÞ]UÒL¤dµòTyãé6ÛWA‚™…â2áJµÉ˶m=ž %b…y-Û b§Ç3‘»D,§ôƒƒbƒ¿‹Ç^>a§WŒV�܉� ä›@©vYidYf!Ö2i’\þ¤àDµ÷�YDc>g>µ“%¨s¼× ê€ꔑS´² ˜X8ÂnI-C¸rZîõÚä‚¥>H Ùg�!vª/Dþâ#ÞÎZ¿iëö]û¥¥ˆEn­ø´l FbÇ�Ÿ0qÒä)I$¡ÆÎY³eg0É“—ù­(È>… Á¿’ˆ‘?_¾¼Ô¿0'óùÌ”1Cº´ÌY=aü¸qb©ðH^õÇØ$xxÿÎ�Ë,»Ú·k;­>°:gÝÝ€òCÎ?„ ýÚMª¿¯ÿLËX\G“ZÄCÂ;X²€¹,*ö¡9 —Ê(µ—ï�`-,¬@&Mf¾‡Õ²�d¾^‡—è`¾‡šå\‘±)�Ç‹ƒ˰¾ b´Ì,”-®ÙÈlÀš0Lm?UPL¢ìÒ28IWöûè ÍA.¢p=\™¦W½yäôÂf¡B˜‘ T!Ln‚’z©;³½}¤xT¨uú¥Wq’ Z+,ò³$«¾’da‚ùÎh‹åKA+ ÝÂcw¼¢ˆìƒ²8„Dòx¡°�µtŪµ";h)râ …ˆˆ"þ k¥·œó’$ÉS¤"¡$=õx&8¡@É™3ùä¦xÉMþ™ü{ò_Q_ϬY³dΘ1=ÁF*9’$Š/NlË_;cØœ«~�Û×IñqòØ!–]­_ƒáƒu¯xP Ò{˜ŠröÜÿš2î`iòC\áLÉ& ¼©% ¡É5_©l8kñbœŽ?ÕÈH©Ìh¼ Áÿ.š 9›âªTè.7ó¸>ˆTô Ö8 èÀ –g¿¥‡ÅR”É�2ÀS„••T¡ô@…’a5P§ j3‹Dî4´xÙjXRF Û_ Ò»Òé Sñ­,РÔ;x¼QöYˆàwª‘w<†¨ÓYø‚à?'¥GH˜©û;,‚áæ07 …:ãœäÍž)M2@Hœ÷o!¡�fYtuÍJd.N ÒÌŠâA„ D’g±~Ö€M´îsGÇ[›û×Má±a$v\’n%NšŒÁ„à„%c&jú¬~2“ÿ†:CSõT)S�¬*�±­€ó$¯3pÛm¼Øƒ{gO=|`ÏNVœ¯Xº˜5w-é• I»j´�1R‘�u÷»¤ eŸ"Ÿ€ˆ¤�bn…¬:ã lñ¾xIn¢Sµ>6™4€L—vìØãõ¬�Æm�R˰�N£¹Zî¾q3¬Ã(ê�ãŸPuçLÞéÖ&¯Å¨Vl·)HñàgÖ<BΩ1XÊø.„I|0³ˆ‚ãS¢oiZFÁR [3Ä+Tª@…ž5]rxMÓNá¼;FÝFÕÉÁ�Ũ|4ÈÅ᫺#¿ªr ^oH‰Bh^)0¥zmÀ$yXLQq–}> äf lœõ”äÈ¢J“—Oî}á6ud�Ù~•óR¥ÜH0ℬh(ª7K!sÄØ?Â,Y$I”+ø��’8‡9_M*8ä)$Øœ×k ~TÒëÔd"Ë–,Z0O¶Œ©“B�>þçwd ¡CàôAStr@©.ƒ›‰Ì„b})ƒÈf‘#'NŸ»xõÆmQŒ�tp]¿šÉío7AI,ÀIü„ ¨$I’T~È"!ƒ#^\�À?�¨Ò÷+/>¹ÕÝ[×.“èÁᱞÀ©>¦‰ð¤qÍðAç$B>Î_C|LÎêá*&ÙóÄ Dià, ª:*aIQý<Ù¹ù�ç}V1Þ¼ Ö^ä!�7˜ý7=mvìŸX±RÃ3L¸wq·ébqÎßû%Ó}ka‰kµcWÆè—ª‰—º 6yk«nº>»Ò¥'ʪ2²�)‰±—tW~XO…2½U¬î³Š—Š5„°›Wî´_•¹Pw‚Öé0O§rH²¦fàÏ�5 ËÚáÒY†”!¢•E›½¹³ foÒÏoªÑAÊzecƒî"¼ØÎ"ïÖ¬9‘Uk"$Ñ:~êÜÅ+×o)aÄye¿¦E’{‚}(NbÇŽ'.ÿÄ‹Gÿ9Nòß#�ç®÷õü³â/'•ùM�3´wE²«Eмš¦Tç¶l‘³”ç@ÿŠáƒÐ«  #cjV Ó%Båe!\Ù߬#K…žk³2#´>ã€âŸ”ÝŸS%…”&ÚŠYÍB}8HÀ!HYEúÀÓô.¹Xk H†¥ìJ¡„ ŽÑ“ˆõ®gRû5^‚X„g0“SÏéCLìÞ‘�ÞBÞ„*˜†ÒzTT!t›EîÞÆâ‡F5³ ¡kÊbIÀ6aew†!¤†<Îe6¾Še]RÀפ¹¥½†Ä^Æ9¡¬,° çIôÝ-?· Äðm›Ö¯fJj©nI³Æ�çÅúTÊ΢¥mù®Z³žBd÷þƒGŽŸ:{á ##÷Ï,éZ%k|�ÃOœÔ%^ôŽDæVgN¥ðØðX¦dW"|Œ·¥Š')F("~ðüj#®$¡~­Š”,[±R5¾$%:¼Š2g¹Ó:'aÅûÝ/g„L ™êôM™ØÍç„z‹UÛ‘ñ‚ôxž¢Ô_ƒA›J3™�Ãön­\<ÃúKÌî ,yg¹›bj‘T䵇*°Ì"Bœ¹Ú,yës,H&6¯¸âºÍØçZÆ/ØBHþ}¢ÁÁŒ¡—(rU Š*ýMÇÕ) -B’u²’Gp²r Ûš"£;Ywˆ¦ÎÈä"B¸ñkBȲü÷oQãŒ»Ùæ6D¦é�òJë0�j£ÈbäÜ…+´Q0òðÚÞß½^"±682×ýxìÆs÷Ut°àqöÔñ£‡öïÙÉ¢Çj€Í®¦±ìjRÐð¡ˆ-D³¹ÔŒm`öT%Š$)Ó³èj"î®PC®TÑâZäyå2w>3BTA ¾^ ´mZâÂQ~¢ ¶[qSJ”èr×–›™±!jº3hVº,UÒ7¢ÑUT´®‚� èõª{5ë½'GbEÊg•Ùðð¿ ætÐ)æWjI¹ÜBÊ GhQJÊ"'é°að;¿h‘ïb©ó`ZxÿÄ0„Ư#œr¿0‹œbÁ@½j )Õ$<á¼`Š€Í^RF–aÖáé9é$é7l��ˆÐ6 ßÇ’fÉ<‹ E,Ù°yÛŽ]{÷ÓLëÌùK,ÕR0BžÚÉ9¿vªU$}ÂXO�¸ÉsTlüÙ¸-·•¿èáƒûwn]¿réü™“Ç�ÜÇáÁjóùsmÙU`%üL�bÝfn5ø8ô2rR¦Ë’3_a¥@7x”ñ¦l¦A‚…3ô4Sä $Yfš� — ËwGÇÆ“ƒhä2Á*a˜ÝSX5ñ×ÓÃjeÄÓ”SB QqkúèÍB¥o…*ÍäQ]m.eBU‡yŸaF"[š¨XKÇS.Sz€<„Úï·²tá$%KÕ2£ƒxް~;�¥×+ÊN[„VV=löR19:0¤Á…éø=qÁèÖÕ §¨:ÎTDZ”ꢢ‚ëÐòEˆÐZdæ-ÛwíÙGÃÈ©³ç/]%¹gÁˆßûÌöyCß®œ?c’x�ŒØ Rf+Q÷ë «_¹ï· ƒÄŠŽ³§N=t`ïîÛHiŽÉÕüy³9<ð«Ûãßxvè>èñúÍh4‡ùÕÉú€�D)Ò‘�6°`BX67QÿÌç —|7ZàI1§*|úã˜<›þ�>‡ )Ëäf])£Y¸¤Òãe%ºÐqT]„qgò¥r«{óZî��aAkÐëñÔ˶+%™¼Šz¸ÊÆòàÄN9Å¥cÄÅJë@"ßÄ'æÙj‡0„tº/k¸­‚³ìNrü›�Q̽>�ðÜÍ%½ô˜ƒ4@qžò"$‹ˆ! ÞƒYÛ¦?xp¯\P�]šÅƒ‡FÖÑZ»~ãF9vò4)G®\¿yûî}Hü÷¯ŸÜµlÊ�>]Úø^ªR¶pîìÙ2§'ŸŒY²çÈ[¬bµšÍÚwï7jço[ÿ wo:NŸ8FƒÇ®í[7oX·†Âƒ¶®È·†Éy`q. Œz_kðQ %O›9GÞB¬�G�`Ló%�0Eƒ”w…òÉ«È|º¬‘�)ôß*<ñ¾Ed2® Âɰê”M•=�f¡éSÀ‹Õ𺂠›Z»Ü“½Ÿ#§Qy­*·îÌY@ å}YŸÅ < ÕF,À2ë@~ë±´ªqu¼5aœ^�1²ä)óf œð"cp a+�¸ÜŸ’dmÉéTPÛ`Ë œ”Å—2�úÎÚÍ80d¤‰�x�/à–Ñ5*‘³wç¶�ëV/‡BD™ˆXÞ´¨ˆÌ™KËõ¥ËY¦µiëvZ�b9ñʵ$�€¡r›Z29¸{ㆠ¶ì=|äĹ+7ï<ò¿|HCÇ­×®\ºpöôÉcG xlÝÄáA¢ƒŽ>Ë'ë’=Ý�¤Ë_;öÐù9ÇljF¼ý‘¼<4c�ÎÓ Y€0�n, /iâßd~°“iÇD{ü¡åÞêõŠöÀõZX,ó!aõ—p#O8?«StJd;ðñÌhh&RŽCð°,E×�^“J% ³P¯´öð)± Q¢ÛªhâÃ\¾´4 )T‚ æ_©-]�}>UN¬šÖeåãÎv·‘’Ì—oƒ´zù!T0¶|›œ€Ð£a+ê^Ū,¬>ŽCjT«‚‘uHœ¦ äðð.Ó@§¬™µ`ÞìYÑ ÚD&ˆÌœ=gÞü…‹i1BÂȦÍ[wìÚ½�bäÄ©3çH ¹v"IP”<òC"Çõ«—/œ#™EǾÝ;IðØÈJÚØåµÇTQ›« Ž”ƒN!dªÜT·þ÷>9\iÀGž‚ElŸà5Éu³.p…>É1ñ¼u\SÏò5&è»Í¹°Œ�*+Æô‹¤héòÜM—{½q+¹�§èÅ<Ž\qé…9-ø†¯¢1Gn_‹ Ös2Ã’¶�kYËXïÈùèÍCÓ©[`î9$;½rÙ¬¬ºl–|šÂY„V/c"D[§/Z¶’í+œÀ}·ë0UOÎ\óJÐfd ®Øä•ýæå‡Í^:R‡,‹Å¨êbÕ?âç2�gi»—•êËØÌ0ªF�(Bj‘9sç“b„fZ¬Ùº}×n’k>zœ’«×oÞºCPò0!aƒ`ƒ¤U7®]½t‘$V'�=|hÿÞÝ;wlݲ‚›{Ì%µÇ �àÙ•L¯�³b‘[vî=tì´ð:Ú 6Vvi> ¥ ^l`YñÎWÒjY}·¡¬Ê¹Év¬Bgv^³Ù£�M k9¯@؃½ÓZ°LpHˆòg^ÉTlšO6P¤‰Bä ’aÍä¾RGÎ@†j=q“¤‘΄z¡/˜p�H©ÄÚÇPßd{f_FŽ; ì+’ÆJa�¡þMÔ»`TÞê †L´&YŒRÌBâÁbX†ÐF{š•ù.˜\5–3{%B¨Žïöz^ÞéGrï•óXª %)"ý ÑòU-òâ±L‹ì#ë F¶mß±{/ $$ç.\¼|åÚõ·nß¹{�áäaôÀ иOÂÆ�[7¯_»zù"‰§Yè8¸�[hjE‚©ÌÒ¹”æ²6ð ¸–‹–Rw9jŽtâ çïú�4ðp|dÌ&ð!X^å–†ÁXQ —V, ‡q7/ a•hÚä–¢`a­´,JÍL.æÙ"uWV1€5à<¿r*O1ýr!$�’3£±²ÂÖNò6C†µ5«X¡æèR˰¯q²¤bZex¨ªVAÎ7aÅ” K>EÙÐ9¸àEÒ‘\”‰¯VU[’ãB*йAÕ¤™ŸÅ£hÒ�{ùœèG*…:HZ $›‡ Sr™¥XܺŠV›ø¶*"žÊÖ(2…B©F–­ û’k‘š�’‡H$9qŠ äüÅK—¯\%8¹I€rçîÝ{äsŸ|H¨`òïÞ½sûÖÍ›74®\Bl?zäðÁý¤*ß¹ bÇꕬ0'Ác%%bçjb�è!éú\|‚ Ö3K‡ˆ�ƒ/s|¤Î˜� iÖŠX¥7hݶá>ÂÌ Êä‡`KÏgè¼B ~†™» ·}’æ'ç0‚¶¸é¢iNY�•púîàüa)Ý9ùïÍBI>$yXŠä¨ÕÊJõ=P…ª1šø-x5µ$ƒ�:”K¾{ëãí¸0‹â…"³Xê8h¸Q-k{¯×.._&È8îì™Ó§N?FÒª Û·mÙŒèX¾”�ù�[1xLfšWä �– ršå¬¹ŠÒ0u¸Fÿ^ÿ¶—”øAðQ¢ àƒõÎëqŠ"[†³�ÐK[F„ù™+â]:á3tØ# ˜#N]ÑÂZ•ÖÖû,“°p9ntŠg(/lmfãÁ¬¬–XzXתãÔ"³ÍŸÖ°lZÒ,Œ ¶F–òcî·|µW¿�ty·‡ökp¯å'?’N@«wÉü9�IÖxòÈYe9k.›UªÂüWZz¸÷j0R¶:± ’eåË•-£@Hº�÷­zè<Í¢CCX4 `ýÙËuF@™>cƬٴï»�–#ËW®Z³–$›IE²sçî={÷‘¢äÈ‘£'§N�>}†@åÜyú¹p‘ †@âý'OPh>DÇÖÍ›6¬'è …K­X𠥇=ì‰àøñ’¨/%"©0ËÁ£t|ŽC–�å°>ÇøAñ�+Rünb‘O‘æ«.ÁÁŠ?}ŠNÃ„ÍЃÎ3QZYðŸ<6Î%T!Û`¢Ã, ’*BøÎ2ü½† õ¢ÌbÞlœðYl'¿—œÕ+5€ìûé�dq"ÎZÜ_š—!|­Å‘ú®¨8°¤À^‡d˘&yBH Rö:�¥úÍËLò™:–­Y�A§†ÁòúNÆjd”#4ŽŒ�@²nÃFR¶“š„¢„”%:|øÈQ‚”ãÇOœ8qR|N�ÿâØ±£GŽPd�°±wÏî];w�´ŠDŽõëÖ®^µ’•å iÛ ƒ‡2÷ˆæËMüKʲ0õ»M[© ·4&}8·ï_¥ ÄG½P€(PQ€Ð¼¹€´)ò4»ŠTœíÙb^Tú ÈÎ}GQ5Á?-©�—å_1ä|Å_ƒ™æ@‰þ…âõ­Y(Eæ ʯ_Ãã.ªVV‰¬=,.ˆ%}‡}b%Dt±«Æz¿Ã:Šàº!JAåã�,pg~¾.õCÆØöž¨Ó÷låïÙÖyR¤Jë…>ùULYng&�¢LS´¤¥m/Ô•}Á¸½!±ÛŸâÊW/PÓ€ÝÛh7 ju¾¸ÐñEåñ,·™ÈÂÈ”©VŒ,¡ ©Ú×®_¿‘†’m&»vœ�x²ÿ�ƒäsèð!òO ° ¸ ŸÝÛ)66p¬]CÁA«Å,³tLŸ }Ýhàa­>X÷ ôS©‘ƒbmýp”sqŠüŠLjXðáã&EÞÿ5÷€q¦ÕÕðÈ–»-[î½÷²î½ïz½ë]7�4ÀGHB/ ¤òñ…R  @![r_÷Þ{ïM–lÙ*¶%¹wkþçÖç>Kù3!°xY[ÒÌyï=÷ž{Ž5?¦ ¯ŠÜ_)”4ah°+�4;BìÚá•òô¦€ dŠª©5¾�¡cN§S¯�}KjX¨‰²ÚsM¸hàD'™Í¢A Þ8Ï&s{’oKÈZ%‘䃿Ÿ-Y¶„Œ5%DW®¹¼r la¨_m½S¬zA’îÓS'Ôd‘¿ Þßâ{û/ D™ÝÍc!ÞÅ*³Õ]–‘F63Hv;ÚîPr`Â89í�â â^ç/\8ï^®ZÀëì™3§OŸ:u’¡qè�ÇÞ½»w!8¶(:Þ!æA½UAx˜#¯wŒ«´WàQç�&Ÿ~½ã#+>ă| ¾CÃ& 0x¡áO%œ��ØMgRiúrÞâ(IC`’?mÎKôÎE9MÏ(H%.i¡Þ¶ÓØp½ÿY E¯Ýæ–“Ða±pª±‰Í‰tXÞ‘7aÒºAŒ[œ¦„�OC÷ßÒETï~�Å¿­Æ»Š<‰�Ÿ çܶ<�걈S.CÈHŽg½¥|<}çSõõ¶ÇÞ¾ BL—E×=€<1Dmï€>Ý;·Õ`ØË_ÈFä®X?9 æRBÖÓöY\FàKÅ¡´Zˆ‘u,HJ\Ãå`rèð‘#”ãÇOœ8qÒ¼Üu°8vì¨CAcß^W8 µ²è˜G~zÌz¯ qc9†öÛe·ïpªuòöŸ5�‰¾¤SwÁ‡VbQ(ÊTÒÜi¢] …mÓ!ó>ïj°X垆¡«k'ňÑ甂ö`‰îÈ›œ³g¼—ªñ3ÍxéyÛägÁ}ùÅ¥yáOÞÀ¡ê“ý{±4:,N=H$‘p{‰Æ‹E/¿p�%D/[~ÒÈ_)zB<�ÏKrsL,n ÕÛ¸Þ7“)g5é8ÚdyB‚—Û¯ù}a�¾(>�†Ã^�`oC÷æÎ˜:iüh¸1ìѹ}«f ©�ÎþÊC�÷VUܸZö„‡÷+YmU€© Ê×,$TIJ&{öíÛõä ƒ ¼qÿ¯C ÷:°?!ÃA Wól­–ÔýµÈ¤8 ïgaôÞÖ8Òdy‚ž1™M[¶Åý ñ�҉ˉ�Xò� ÈÔ[l��aô‡hû»š�óó££{r\}‚uq#]¢ók–$ÀÈ:"7.†RÇÎ⌹÷½Ð]·èé:,8• ý°n�”î6,Ty^Š30î(–zúåI)>îåÊ.§ÆùP™ jÂ��ƒ¸ä¾´W¿ÖšÓãšg·ïÒ³ïÀa¸?×ù®é¯Ò_‰_%œ0S¾kÚ>÷ûe÷ÇÍ/6XëÖ¤i°j H*ÆWªô°5 „ ™Õ¨W¬ð{B"þñbŒŽX³†ü¨°Øý–ܢ㉳]ŸluqôâÑHbgEDlÁ‚ù±`^¸”èÿvø’²DY=ÄhöåU 9-ô£^v‡á¾uîM+�>¼ïÝš,ÖõR(õÇŸÍÐûÂn:ìÕ#QÊbÕ‰-¹\;› f)Uoõ;W“²¹[ FéЋm¯x±9*âE¾µ@0b»-\‘@¿…0qy('(ðÚˆ¯Mù¿´^X5 l0ç`pHcU�ÿ®ðx‡”WpùÁ–ôŽ�›öêÆoP6VýFÍ[wp ê a#ÇL0ûƇ]&Í7ŽÇÃ�ìÒŽ½øbÓnÐ'´ bèiEèŸu©fëTd"ÂŒçPO&>(ã5;�³a•‰øJ·Þ÷’•aixY°Ú]BÉÏŽûH !ó{õÔ+Œ²Êµvq¹q_<(G26µ÷‡�CË÷‚A–°� $Ã.¡šEõN™Èþb ü¿’ħ©›¥·^Mò¦ 0ö‘-Ÿ/�Aô‘Åa¯({½Š(Á¾�6Ú½Í8î…aV;%"±ûkÂ"bÜ<· 4 ´jŸùF>¬¤EAâΗë{°œ TÖùþ5 b c5ò ×SIáð•#u¢ŒÒD@¹F,îÐ'BM��K¦É±i2¾jÝ¡k¯~ƒ^qø˜ì÷ç:äP+>¾=£è.vg V÷mlw\N£GPƒ•ò¨[‚oä*º#DCÛk"s?Âñ°`šÝº_¢Çƒn]LÑÇ[;ÂØoÔ°°ëÕqÜ#I ùi}€š$’'y6ÙVri­ 0xÌ›;7®œäþË—d-jQdÌJc‚Qý ³9¼-ô<½×éè2Ä6Yùa“…f¤›Õ‰\ÂÛ ÇļN›îàtaˆ2"Î\¡½%õ XCp!2z8Pu$"ÜfuýÛ;'LäÆUãXhLCV¤¹¼¨­Ûò À …^«Í‹~E€¡ÐXjÀ‘_7 ¹zxH´·;}â\ùàÛ¨äÓíÓñUÇn½ú~eÔXÔïšM«ÔŽ%²™þH÷f?NÊ=è‚ VAjƒåzå½�H#^ü=ûtÌ[™ ów X™�È‹Äj> hf’|zï&Ïx·ŠcuX@–SXèN ÅìÆ–Ê3QVÞŠ-r�™/ÄäzL ŽEn–‰áú¾Ã'| ©š‹R+¿Ü‘4¹°þ ý_»'˾?ÛÆÌi~²øè¡°â ëe}o½ôéŒë]z„äùDVF® qÜë¨z¯®}›•ù6…ÓÛ;š(@ž·[év�‚‘Ú1‚íV�AÉ2­'„ËJûb`2 4êÂFê…Êõ¶áS0¼º^Qy×§Æ}©…§ç°þ<<ć^Õ$ >p€õêŒ)>>˜ÏÎ>ùˆißµÁ¢+j{Â�\ÞJM(Ã8÷äY—ƒ7Ue¢¡k¿úˆ.T݇è´�cL"lX(.AD`ÿyòò¶›´ÔŸBðAð˜� !ŽE'#xBñÌèD3² F‘eÊ Am¨êEìÓ~§Á“ÁóÞôµ9BCö‘´0ü—eÅ‚[jô0¢ñ�×ÏB\ªÏ˜:i˜‘DDÚµj&mVïÅš*ðèn•ï³Ä¸�®¿QÄHùÑÜö,Zœú^­%ð1!¨,‡-_˸d,5ÿ󺱑þ€‹­]w…i?eò€µWÉšÃÜ^ÕkÔ<Ç»°tuw&nY©5•BN\!…¢ °†q=ý6 *IbRózœðÂ#¼�‰ñ˼X\Ê ­;¯©¡,¤-ŒŸl§=ä’� ˆU™4Ótwá-za¡x ÂK�Šáª žîf B£l°âHÍçcF7¤Çü»õµ%ä–ÔÈz‡JÈB� 'È<½ÉØè A“u@>^µ¸È7YøôAËw›7ùì³¼n±'»qYͲT ªÂ,°"ªîˆH�.íaÞKoyËOž“»ñ§ïÞ.¿~Õ[ßzˆ{‘wûLL9a¨VôEÓ[Å…û=ëø]…d‡÷‚Ø\< ¤»+­¨º'»ódõ7zpzIã@Ïû ø˜Š³�#%rh'¡}èQ>’ª(á /ˆÜkk°4<}j8ñ{�Y¥‘#|>+19ÔŠs™áž²ÖdÖ]{jËqìé.¥ÞY£>ÀBÑW7 ]êT.%É☠›#£«y�7f¿þz,*|EÖŽÝ�@`mëˆDyº–‘Óûm!žIÊ>�ÊãGŸR“ÅY�ûRÛ×E! Ñ}!%#B¾PϬCÉeäD‚– àó@V†0Ì"2bè GD:¶Ñ6+6dåãhrQ‘ýÒh­ˆH§µä=@$@ ¿À}«€!/‹‹EuÿF2S^.“«uxý‹ÆÁh?�1?w<•òqùWp{Õ¤e›Ž@Ïq¼ë~^¸aåùU܆½x|Ѐ‰ÚÉ�T‡�²¹Qtñô±Cûv’ÏO¯i°XöJ ý|_ÙJ<+;j*SP@¦…i¡MþøaqIú¬7½�ERôgŸôbY‚P¬¹.hbÛAÝT�Ù�_ÏY´Èþ vBß�(²^|"f4Ê#ØLš|0Ôå�ÚGÒиþO§¤>®2M–_®Zžn‚΢¬mÆ?áêßÈ0ë�þ‘ƒ}ÃÅ6˜jRõY3§O�­ú°A®ÍêÜ®UóF¼4lñ«ÅI�øÞƒ>«èò…3"‡Ð)�n]"ËÞ•°¿;hþ ÿLAäfk�¯�΀³+Šãòñü‡ý¸½jÛÁî½=9f<Œ¯X�0_ø¹NéýYÿLñpí¢‘v�ÿ©F&‘�µbHZÙ)Ÿ‡F�5¿ç¯S± ‘ã»…f–×ÐÎé“'i¡sP©¸æþ|]†–ìºqzvòœ ˆ´Õ$’` â;,`¡õ–¬3għ/!Ì:�ò˳} À߇󈪗yz° ÏMVµ™d‘ Pm4„ö…:ÉG?¥s3¼§l¯þƒI’jO¼™„÷2Á�!¶YZgÉÒ0cÌÜ÷N�PsíJ"ä–ðΪº…ƒ¿¬—¹h" Î÷)­¨ºûPâ}j.|ª•´WÍ[·ï‚ôé9þ¬@àñ!|þÜŒ]ÀôîêoLÐÿ�í*aròˆ™ð¦i°VðíGZ0Cß×ÝDOMÁzo“³D7áâø,Ëü7�ZÀL&ÇžFèÎýªè¿"½›M"áåd"áω´|¼ñúë�iS#Yl¬ðð´P}HŸ~JÓ™{ö Èÿ6Í.X†Ä~û….™.±ÇÉÆµbµ¸$ø8ØXVÇ„p”E?äk¯ÆŒërÿÁ¾†¼e– Àb; ÷¶¿þ*‘q£†ØÏµYmU½kü¾³5>ÄéÎírÈ8ƒ�C„ývRÊÈÏ�‘Eö?ý<èP‰=®Ð}hç.¸ˆ‡„8 ®»zøD çŸ-ÀÞò šf¹öª'ªKˆžã³dþ¸wSÓ ×�B±Å‰è’ϽèüJî�˯žÇ)Ë6i°–¤ô8b¶,¡HÄÐï¾)nä]yG¨„ˆdvÊk´õ�|�. +4’I È¢`I¸ÊŽ E¿;EÝLøBK¶÷y*&Ä Hùpð˜>uò¬Xšó¸N_'¢^5‹<ßKG⦪3lŸ‡�³˜eH›õ~]x‘tÒHCÒKN\›GÁ÷h”u‹}ÏŽÓÙhFÃæXC†5dA`Ä¢³…x!νÔf�ӬΎ«K‰õþ³ÛIOEî܈7Žmþ0Ü+AÞeÿ¯—Ž|ÛZÉãoñèš+“1*ÝUòä¯qCýFÍqºÛ¶çã'Mz>OïkùÔ4Žo§H¼jsVØ浫|rÓtG@`â‡,©"^: ÅÃ71jHþ°¡<`{èŽ� ˆzo˜%z„�4ø†{‹ä†í'-°}EJXh˜&ˆÛå¸Ãl±|¸î à1iÜçci4pböN×é×ø:½æwÙç°µÈÞÍ%˜7SÒ¼®$ZôÇ…ã®ØIlBq¡žnÖueÑÏùÐ@A$[�p1à!qs!ç°èy¼�y/´Y°4„•HCN=Ë|cí#±Ÿ~öø^µƒÈU€È©ãG"Üi¹2²ÖŸ¿.ý¯’Ÿ þôD U¶¡ç¸;žqð(†Àäž¼ó½a\>2›dq{…ÛA¢ç4¾òøH~G¼ „H'IêŠ ÜÍïÜ-x¶?¼�ûãô,m°c`'óÇ‹cl‹NÏW3Møeó\\¢Oiˆêe2¦B­ä¡@¦ôQ$@(iá+ìÏ�¢¸™Ì ]ê$G >'„�WgNŸ6eÒ„qÓWÇ/®�…˜ëtül^î× †yÍüœxp:Åût”*¼2¸/6YøM~¡†Lk«ÊYÉêÅ)�!´$„ì"„\“aorC�„ÒmßZÓ¹|:nKòz)†¡î‡”®(‰\NSƒ~±X¬Ÿ6 �;tÕó©S?ŽUÞ þΤ…ºg«èÚÕ©.¶<ãÝÆ.C<�=Â=¸ñÓâ�ý•ÃÇlÇ>ù˜úöè,iÁ±öÿþ’7èŽ=ÂËžÑO6ï½±nS439¹©-1tɲ˜âw„2JÃD=‰ Õ%:�…¬s—8¦M©iºjÃå…îøàøK¥è}Ù°P/3ÉEûsÀÐ�×9‡ò1fÔ+ÿœŒ¥n¤ˆ%ã [¥˜ø]ÞœÀ¥áé >ø÷ËRœø&kX‘½&�sÍ”QH~›t Q‡ü0öºbýûìšwðéŠ5„7†oÚþZÚZ^ÿȼ—¦YŽ«ê×+,"#òï¹]Cß‹çΈA.º¸mÞ¸Q1Â…¤N�,ú/¡ƒïLÐcˆx¹cb |âÔY‚Çͪ»w~4\sšµl‹ìÛ«I¸zNwü ‰Qñ3�)+>ZòùLï%ýݵƉ€¬–èé” /Zãìbrn°nLòV?:�È$aMl£¤ÞwXª„iLö–.®Œf¼’ºFäùÆ8Ñ·DãšÕÓ�» Ü™A{åÊÇ„±£G¾2f_2–ögxÇ{Ïú²ªømþ )çøM�:~ÅåÜ„uï4É~=ôàÿ#wÃ÷�â6$@H>i‚1&À Bª!É·2¡iïDV¿ã„?ΆzŸ†;Cœfá�È”‰XDˆ‰´j.úÅX“™‹¨—ô³G÷ï܆h@ޝ�2²­ÜÀdݪV‹h€’‚üŸ»˜àFq‰è—qc…ïT;”½ÌüDø”»æÊÀãiþôFZ>²¨| †Ó«iP_ßô-hâdù9ñÂ/Ó‰òó‡U á…§Ú®íHЙ;¦¹šV“e8#ÄAòËÒåÀTÎ@|ó‘gF¼ÆÃV H)'‚”È):&¤MӅȹEÇOí72ê¤èx%Fù®¿rôñ1~̨þ¿: @Œa ÅfḠgHsü¶�F½3$ó)î=1â9)MVn²üKRzÉ«¡Þ-=QWU¬C`aHÚ÷gßj�‚�I!¢Q šf!¾ªß€IDAT-XÀm¨]=™H—mZ6kÈÚ“Xãíxä!òø 9G>ëÈØw µ‚¸òP%YÁ‚Ü@>’ÿn°XÌ«ö@1�Î[ÒXm@ŸSôËÞÄü„ë­.]»…ÇÁ�d 9oÜØGϾŽ�Óô Û+K?üOFâ‚þªgg] ×ÿ$áÃ=ÓP A– §L#YH4{ÜÙ]ãôh‰&ôua¸Ú5.è˜ÅÔšÖ”™MäµR<žYe’&M—l¸ zÉŒ÷Áì`‹>‘mŠN'¾o#ÿ|¸öj¤ûx üQ2@‚Ü,tÕƒâõ̓Qï8ùF˜‹b,Úó£M¯ ûœð u˜õîÛ%‚…Z²TY;÷ÈÂ��Ô_þcópÚ‹ÚÞé3™†j›m˜Òeâa†‘}{uë„}/EbY<¤iO5ÏC„f9Dhjad;Ú�‡>wZf`¢º’|BK¾ŠOD�âÅZ,þ]!”\| ¶:/×âÁ=ØþLóH^~ª�tW ›¶lÓ¡‹”3½š·€ºÏxn·Þqo%••ë‡ÃqãØG«ù’æ�7ºGšm‹-±A/GNžõ¬ªÆ[�’�0oaÁ‚8,Û7ØÖ`€/ Snë¡”Ú�Ö¢2A3¾”¢¶g� ݉¢›-ºŸa�É�âÃÑ�Ñ#^2¨ï¤+é£^|ËšÅGŸ‰y½²¿˜”&˯°zWŒÑ¸.”£ÍYe<1ä£fØøxQ–'|Þh3¯C.ÝpA¤>ý—!ý)B¬ì$W,$Eš…kuàêXDÜ�aØàþ}z„}V¬ÓÇw<3!ÌïAP`ÉUd#§N:²¬ÔÀj=“c-¡–KTì�^·@ÿMTñ^¿BovWÓÍ®wBoS‡Ž”ÙsíFÙÍÊ;{xÔœþR¿zZ>Zd·ëÃ+S>dz…ñ8:ûÇÞ3žŠ�ž]ÚqÁ�Åæ^ç|Ç›pc %ŸXï¬Xžnô¸Òk°Î\T�þ—OÁ7Íݧ¦ï`Ü¡3C_è=EòrÔL‘îô$ó_M챃{LÎLä’P–„|쇗R�DõذP’Ù€ðü¹¦~Œ…ÆÀ~Ý?ù4=@Ò˜‰žælO}X²E}¿ŸÖ™h;i²Xø^ï¯^êNÖÓ�4›GY²A' KÅ7nq yöÕ¬T„L†OÛ!y:;ÈQ®Ž“¼WaP1~,.Ö¹Ïj$}V¬íçŽ<ñ2R‰eòÐΜ:Açu*$›ÕŽd ß•¯ò猕e„~-]æåï+Š ëE·‡Ð¼œSß*n;fþä¹&TÕýc/IeÏlÔÊG� |`{5�Í}ÌM/æSB0îϹ¿RVlV1�HÉ€÷Jx×­Æž¸ Â�½7¦¬y‚µ³ƒDéuþƒu|2â7.´úÁB'ÛšÙ9¶TGXz(U™ð’m†öã~›%RGÚy·t¬ÃQvä#yr> ·èòÈ´±Ù‹;ñfRÇó·…ÄÓ½¤_¸r)x–e½dg­š¬ìŸ%ÅXÉÑV½‘(+¥§åa/†]B ëBjÈ‹o4óª“.=ñÆPn�Þ’a–¡ê2ÍZÀ\}r±q£GL}V묦 ëK¼fÛ÷oî£kŸ?Á2Rv]1âz-t˜6Vˆ€q&áKÚUæ8*|É ÕªUT5ðˆ�±aÁ±ÿà!è¬N�9wáÒ•b`•w ~Ú§Ž\ý#­õ6kÙÆ‘ó^ýNÃ]Ô&âôŠ•j¹&ƒLÄæŠþ ÷ƒÐ_µ‰Á„sŒ�Û¥Wa€EÚ@З˛µ(J@ÈÇ×kÒ`Ý}KìÇ1ñ~ÌDÍóæÏLž•‘Ì} Z™t�kÓe¶€�C©4I~$C§%¡8Éÿ©‰Ù$;…7¼áh‚"ü¤áá'Ô�}zv~µ¤6€@Ì·x[xuª.|XÓïy:'$ô»}ë ÕdõÔt»Q—å©t£è:cÔ1YFqbàD C_CžüK¶žËµï‚i”c¬�nõ$Î#¯#Ü—¾…[C�žÐÄ·?,EÚµ*"U¤ÝGVßIšNëñý»U˜É\Tˆ!bî–ˆèm…0YG.%rsŽçµï¬¢Ú²ŠþJÏpåfmP6‘©Öö»ÐÅ”MãOŸ9�èÀäé{¶·J>;óçÃõ6ÉrÝUמ} –ò1s³s¡ª1 ß@¾Ügo Áû´ÆÆRÈäÓ{ P&ìI½{CþµÝ¼à¿ïÜIÖ½ˆ „æT�:ƒ•£ðÊU ÏMAGòå•¿ÚH¾¾ŒMš7ïæàáÈǨ±HÎaxe†»ÌΪq&yš1}ã0Äý®ƒ÷‹ÀNÐOó€’:£øPÙiK! ì¢Zb&·´‘ qÖ˜g5",¶2ÃÇ©zŸ»Ï «õ 9;Óˆa¥D‰ÃŠr×¾C¼ÙÆv'.Ò�î}�0Ñq)…ô[ÂÃF g�EÖ�¢:´‡G½qÔ{‹F½—ÇK�/š³9AÇÚìaÉ!�<ë““دÞR‡¥+xà,÷éGY¶†0B˜©×l¤Îpy —¥x9žr¨;ñb"t[鳀Рš"MFýþ¶{Œv…¤ºòVE9Ep"J&€Œÿ GäíK @Īíœ?�…£Àáú*Žû?µ¼#™|rúŸ'6ÔâQ�ªG'‚�ꮀ„½5—†Wñ¸7eà £½Õ'7 ´f5I\±QÕׯ\p5x")¯#ôÅK¼-?KLÎù�âç¿-„ÕO°¤÷!—><ƒw„&/ôm„ß¡Úv È@Ö‘�۹˗_|8rj;Ã'ЪÀE¢zfÀ¡1�÷êÞPM'ëÈâÀ`‰—h—ÆM_9ø»�ç¨öŒš¬yäb)³^y0´[Ÿ n8ˆ‰LZ„Èý”CñÚÒ@çØÄXhά祳ƒók±&õ“ <�…´€‹téÐ.;«YãLåë±Ìž‰ŸUÖ9ç/$®Ýª(+½QâjIEž?稉{aZÎñã�–s sŽÅ¿€HÈÔ\@FB¦!Fº¶JÀñ"ÈY¯)ÿþÛJÌaïѤ…£æT=7Gò1m¦tW² ÒÑIÂl?ÐíÅš{wõi§±ñ'|8–¸‡&�J‡4qúŒnå˜ûkeL@’ÿÞ‚}LðQŠ> ^¤(�Ò\+;B dzчËDòÉ ”=/ OѽÊäX'ë†eg¼q£Óà ô-ÁÄyz§5o0¸äÝšdI‡XÂ3jûnœöZ„œŸÃö hàAJD¸ÍòCœ„Ž9I{2�nÈ^{•oD�®w騮uËæMøN+ÖtÌ﮼fëˆ+$/ž9�<¸w§ºò6Ô­½ Ñœ…˜Ax qkøÈœ¦¿ÄX¶óöIÈ ô貊›·*«î8p\wÅåCž þAî¢bd1~,>5»vh­¾Å3Ïp ÏÐZàÚI¢žîá ïÑÞ:Ï &XÔkȵRܪxà ؆ßgÛó2òÂÚY‘´PU™<û„÷©„óÖY"ÃòqìøgÏ!'04¨íÑ¥}v‹Æ™_©y7€DU½x?É“¡÷“F<ÀÜZâ‡p¡Iš'9OCâULÔÑIÿ7¹iÞé²VQç�!ìÔ«9£üCõb&@©·!"A›Å�,9슛yx 1DFéÕ£k§ömZ…�V¬QŸßÝRñ"¼\%yö„PRű瀓kW1±³Ða_ÚÉ©žìYXXTTtµøÚµ’’¥¥åå¬^}çÞý� r„àH¾(ßò»½ÆLoÕ¸YVv;†ÇÐWFŒfnŽäº+ÎŽ³c1O4ÕqÒÐs ‹×.(ÿ�¢ÇÇ;u Qˆ ³�2;lT%4ã¾O°fšlI9±“Nc¶ñrÜAlR%©£dIš°S@Øôd'J¢Á›Õ˜� ’$Ó&«I½N§ù'«U“½È†à>Y᳡t¦_†ô,.,?ËÉUtÆ5Ë �䈆Ðáþ§ñõ:eA¹#ýÊ‹N˜©c mo5ßÞþƒ¦z†Ý¦c75I‹¸ÈÃT1¾§KK½$ˆôëÝɈë´l‰5úkß9÷<ÉKDÉ£÷ïݽaèÊA‡Ìçk‘W FC—––••WÜdTUß¹{ïÁÃGO!8’/.~÷ÃCšù¯ žë­3o×±K÷^Ü\áb�G»Ú]ÅÉIOèh^ÜÈÑÈÂ]½{tnŸÝŒïÆ2rJ<>®À£‹&¬—[ZÛ�ã‰Ï¡!? á¿}@Qä>Œ£%y‚,?â}Åøq¶^ªwnÝXkYMÄ(k“_Žqâ�YVÞÅ9Î&æKT¬-¬‚òž @j½]äÏÓ×óøî²îÓ·µõË�þFÀN²2y¥AŠ—e³¼ôVziPÛsŠ…‹ØéÂ,ËuYE×+!Oþ¼ULBŽ�ª>7XÓý)nBrLiÜ)ó,ÜŠ`£Et䜎¯C§åÊH£Ìz#½~å›{Ê£ q(yùüÀä!⤺ºÚ!åö­[,‘—Å- ‡ Æ}‡ŒÇOž>Kƒ�äËÛ‡þõÃ}ëÅlñhÔ,«•cæ]{ôêÛðP€Çø‰Xÿ<¢ÝUäø˜³…&Ž•\ˆV‚�ú.•ý‡Ô¼ äaº ÊÊ0YR"]’«ÛjnžûŒ@¢‹¬Ás(l°¼‹L ¨Ëøè3ãòqx¿äM/«£€3ÐâáÖ)Û¤éÆ½]� 6ÇPœ¥ûY4ÌÈü÷¤H­FhùÞ¤‚hç …§¿ülÌžÀ€âdf0ž`‰Üæ ó6DDYmßÑ�:›-É(K²(�¬ÀY;Õ�#XC4üy~‡˜5·ï±ò�gjœýWFÐJ;ªH™8ʆ8¾ÞÛuZ®Œ86ÒÐ0v÷9Íüþÿ¼ô úyFòþò…+'OŸb`¤AâþÚÊ��ȶȬ—Ù¨)×[õî7pðÐáŽ{8xL�Õƒ¹9—�Mã'Õjz=zfêx·áÞanXUQÂø ú‘K#&>,y¼�®Ð©Ë˜<]ûà –ÞÙŠŠ—z»´#‘ Ú¹oÝ´.be²H—èªs×´Ð?ŠI(!¨LƃY.‡®y?kS‡^Ä])Ìrêí(@Òb„nÃCžÎº÷Ë“ä¸P.Ch’ÅüËH;ú õqâ§OD}Ô í\xΫ² BG¢]Ö�#'Î\¸RR^yŸî/Ö�S³4GDº‰[ÁÔéÊÕÙ(.åUæY|�ËU!‚–£G¼‚�”ÇF\«Õ°¾­#±†]¦ýæ÷ö\’L÷ªq¯—•箪<å×÷‚ÿ|öì™ûõ/_:`Ô¤ýÇŸß<ú“?x³wÓX€×Zee·uÅz«�C† 5†¨9V¿ôëoÛ�©äÄ ‘­³ø|0Öö+HŸxöç‚�-××6_T›ØíØb ‹Þ�›¹ Ö­øYƒ5×?BÕ«ÚD†^ÿŸÛôWØ•Á×±|ùÒt2^9”*–R40( tò¶) täKF ˜v » Žmð‡ñ÷úFÄ$¢>-F¬ïÓ˹Ã\Ö4¥Éâ ÞœàŸ"S]MŸNÊw0´dÙâ´R3Ê:Çl�Ï ÞB®•iÖñÙ™õ<�n³¦Q›¥†Fòíeð"äú2� â:­!û;ÂÞ­3¶ZÍ ŽXŒ¸JÒ7÷;;‹ï§ÿ˜Gƒ¨y×ÿaòIùáŸ}jXëúöω:°µêØŠÇ€AŽ™;xL$x@õÀÑU�„yrr³|êÒÞ�¯Úüè%-pïW‚¾„øùvªü–DXt°ƒãw›wôì·3Øh´C7Ð(úI§™`%¼ª èwÞY�cËññ #Þ §Žz™û²4VŽšÍìIß̰Y=¼$œ+ JÙDÈ~Ro)[�ÙjçÓ Abd">ΗO§ü2äчl“e'Y TeîêA¦WÙf|âŽ_BËWözí{”‡ÐÆpã–m;÷8|üôùÂk¥·ïò¸·üÓ ÕQдYbéá¾ÞPÏè³ Dx/B|ʈc#½ztu�:’‚‘X½f=§~ä/»÷>üïòzV¼ö›Ÿ}sPvŽŒúX;Zµ�Öª�ÁÆ#õ˜<'Waõ0Mï;+Óˆ ½"ú!ã«¡ë_ðÛQYv ÷çðÄ ëGŠNÎûûÙļäOZ"+t°ÀYà5&y^c"§uN×Äj&ÿÖŸ¾ra?^E×櫓#I¬‰b‚Ö;ü;ãÈz$Væk Ù½Ó2„t? „ÎÆY<¥ðëÂ…9áý-Úåi,‹%ê-þ3iMd²vMú’î7†Ž’ì¤ú!½-ÏWõŽ™y/N³ØÕüUR_èÖP/öiJŒ¶ŠÌv™¡e„0Ò0âøHvËŽ�Ã_)&�Û÷›œóÙÛy¶¤R“Ðêx¹§uYá¡wþì×_Ñ­EfÊo´£qÓ-³ÛtHñ€ÁÕ«³ò¥zà³™½¡É½µ_esIÌll“Õ˜ÿÔzs¯1>îÞ.½Vxžñ¡ýUjA7¶3»ÑAùªôÒ)Q¢+ô…ÆË]p¶÷ +fè�Ž/EÜúo~ÔIZ Èù"y|—�ÐH´~�L‘�–ò”¢ÏyÃýá4au­ NóÞzäŸ\1ö0R�¿8ÕŽxÓVLdô§0w~MÂ:L“5{ŽU-&Ôñ]‚‹|ð5š�t”uóú\‡¨*.µ†,‘§]áîÞˆd'7«$õx—‘ú�[P›5ØzÌ1㬸§°lé:Yì‘E«+#Øj  Á^«}[($M$õRQÔ°C¯‘Ó|ì·ÿôŸþõ§«·îØwôÌÅ+ÅWáUtùüÉÃ{¶oZöÃoýÝ~úƒ³'ìÚªQšß#£^}”޶í:\gåÐáZ«£]ñÀÞÊ1s\ jõ�A¶Ä~{efÄòˆÂ¶:ýàf®ñÊ9Œîέҫ—ÏŸ:Nú;¿ªýRMg|œdÕÿ©gT™ðâáoÜ„f’Oí,)Z«óúüBF¼pˆžNdb¬Ll¡;ø¿ÎŒŒÌY�“†(Gð½»³Ú¦Þ¿úس˜w­ÁN‹‹H~m‰A'Œ¡ý…þ1kØí�)¨ÔûL‘œÈmˆD§’'Øq>…Îáj,³2ÝÛÂ5²Ã!„"U÷8™ïÆù6 ì=ú ‚ä1."2ÎÒµaBº¬„˜DQ°é´Ðå{‚kµ#ý#ݺtêÐŽAÒ¨�hQqó¬Ö\ÀlVZ5oÒ8³ŽÆ�£�û§šeµÌnÛ®C§.Ýz`í ¼Š,õ€ïÇï=¤0ê ›¤%ìoïýŽ(д/Œkd÷öX›¿yDøxxçÖ ÀDZCŒ�µµÔŸâ²}÷>×ì^@S&š(~-“�bù©Lxsü!…eÈ™ÔÔ ŸŽ }«Ï �zaÁ%úv1¡�fñ@S@ØËl"rÄ«!at¼lÃ…qZ𕹒ô¡J±õÞþÌ‘üˆª—tïtޝ×bßn¨çøVkóö|ÖõúaÚB¢áÛ|ú<®È+«õrmcí5„n@(î=qæbQ Fƒã÷tÿ›­L›Õ�ÜÍÅžÖœ ÆÍ¾Fèl®_j§…AÓ°Õ‹”ÝõZýû:B �JÒ²…”’º`ò^_ˆ�FMšAåhãÀ�Uoꬓ§":^˜9iØNT&W‰<Õúèð�%™T>èä¡Cë,9>�õYNã«§ª+n_:øØ½gîiTù~qKøkXX¿%m¤PãŽN™ßÌ3&m°hÊ:“ã–tÒd)‹°Ê1™¢2Þ “2ò�ZŸÝ`q‡jØ×q„ÕÐ}0ÑgÝFu°Þ(HÓÅñ@7fè~Æëžwcä(~ÌË%<²Ê_¾Ê§–ú̇û�iêª5'ª˜€gy*q`QÖ¬Ôô»Œ\7ëXªy_T¸èµ½«XÜëÂã^f=[6*æ§Y?Ö�8½ŽH1rÔt&Ï7ߔ̕ÖkÔji2x ’î]$Ž“d5oÖ¤q£†™õëýWq’=`ÃuU-³][EàèÕ§oÿ�„Ž1cÇO˜„­0ß[ñðZ§×jRa]‰q:MóQ@\¢íUýéûkx¼ ëóKçN¥Nõ»)õ#º1I’ø±Ú×W$X¨q"FŠq»#“£SÔ˜ôQ#“Œ�߆îivïðVXÑ<]¾D?€yìÒÛ ÷—¶Vçoº9;6YVƒÑ®?‘]ϨÆçñÝÊØVï¢é ²B‹HAÔ«—˜]†H“u¶OL,Áº[9ÚÜá6(ÍO6'r~ðÉÇÞàò9²­ex"YA¡…ˆ«ï… ]|@ 1ynÏ p®îM8I�¥>v)¢d$G–ÎTFε eŸŽHÝ4Y?ke/Æt¡n%'~œ‡ õ6�›(š|Yr»ì*ˆ³F-á÷ÇD0Ì‚aÖ¥bÐ�0©þëÚfW‡"â˜HO̱�‡H«|"ÔœøVËÑرOrœ Ép‰«$}{c)éÜ©c{×re9œ4m‚Hià°â^õÜ+1¯zøª¨hа¡FSDF«l×Sµï€ØèáÚ*¨ƒ‡sàp¬;+˜Z½–R<<�2Õ#z69KÝVG2cÿù®dÅ߆õÇ™GkUŸ˜*®^)~exÁvMŽî$bzÒk€! ÞÖƒSDƒ¶õàHƒòçg™¡kI‰{S+Ý@öó „Œ¸¸€ÄåPÊ�×5ËŠóPÚo—ëé}×pÆÄh– Â}VÍæ ²­#G†¨Ézú‰˜1u.Lͼ~óÕÄa"M�;JFtÓïÔx‡²KðÛ»“¯ÔW¦}ƒ–ЏV†{�ª3¡ãÔše#ê)W7E„Ü>fEÜ>B #òǰŒÌ}ë-�=�|d"‰ã$}%Ý\ÇÕ±C{ÄIv+@ŠƒJ³¦M-Á«I“&M›6kÖ¼y  £-B£s×n®pôàxå•®tŒ7Á±ò:ßV±›'ç’|턱{ …>ÀÁœ¶W±‘KkøúÆW…ˆ÷|òõ£V|ˆã% xYaòð÷˜,{÷È?y:m@¤íÖ,)–XÌ¢ Œ¡²ÙQå}wÄÀùJ:†¾(ªR܆iVî±MäÅŸeH醯}ji\ Ø ìÓUü$ßÿT È�›7®ÆPîÅ6ŠsI$ë©ëJ-º¯åŒo².Žä¹¦C«ŸõòÑXÜ+ßýF�¢§h”%ÃÞ6?¢šö˜<.ÁÃ�¤½µQD•¿ã0kß! ê@DîðF$yíƒ Òô‹Ùë\vü0†ƒ‰„¿Æã²A˜o‚å1xúTGHm—„ý{Bàüé —qÕ=1b˜0FñIA$xmáפjöMÖºÖbáÐ w¦¡h3E¶uÒÐË{»®MÊJ�rpodÈÞèûa¼M»A™uúüå«HDè�ªþvÏXPDzxÇA9œ·Ï ßÂë}ª2öŒLc�ŒœP2d0“Þ½{õì¥k×.+îå@бCÇð‚¿èØÑýZg€à£—ë¨úõ‡žjÈPÀµUŽvຜС­•ß™',ûÈ3ð˜'e8'«å#»EcYqvúj5Ó ç8¾Âõô·¤MÏÏÉÂ> èºC]fþ£= °àÓ^—”°Ê=w\üÍQæÍצÞ7Mαýí £r?"iòñÔW�ÛÄ ëåïĬ kœ¨°Ì%!_ÚbÔûÔÉ�Ò¤ O@ÊK /Ævœ8ÊY®ÂGmYƒ¤³&6ÎyXÏž®^¨º™HÇS´Ö÷Q-<´˜+AÜT¯u-Öw§GÈU”e‘Œ´Ö1 ½Or©¾—ˆnD¸ÍJî›YÏ‘v�»‰g-ö¡‚ñíyóýåv ”C®+½pö7�L�¸Râj Ãp@éÛ§�+)®¨¸W�îæå á^½}ú0 Ðp„ƒ°1VÁ1c&—[;Ø&Q$%!þè\ÈwWê§ .ÝM…�g ]Oí<,Ë�ž›õ‡¹�Z”Ædfå¶œ€ˆx÷õÒV·>LÐ_õG„9ê+o…¦aƒån¹5�s—Dаñ }Õò´w„>lVo•v3a³Z@��è\_cÐpIˆ>u4hðc! p�ï~$±�=EéI»}YU{|)Ûd™xÆÊ¹fÖÐey£µ9Á`Zîó0þ•"#!_Gà³Ãß7fc%ñ(�Ž `2f e$T”W^6Ì¡ÅÁžÜ/ 6ÌýM‡ Æè1®j@Ù@l`Wà@ÖÁ�UÐY¥§i²€N 燾‘®»‚X_^™òëó/w¸—¸ïèÇÕÂót=¸}+¯ù&'\Óú“ƒ­p!E Â*ö(|S´Gí1Â~ nUždøŽn†¬u‚õµ—œcYwè¤r'†^PKÙwˆM©ð]ß–�zB$nÛ™rŠNNÙø'Ú`�bÓQ²XlòÉKçΞ¤@pWD!>y6�âDÖ…è†?˜ï5N½“çF\ýv4Ž£,Ô-Âz†Þ³×‰/>„s—Ey'õÝÒaéß]?L‘󗋯WÀZ�ŠHÙg²Ôa­)÷õb÷Z¢"~qè×mΛPÊŽºKm¶pCBí¡Äu\,'ãÇ!R\ëåÀp ^ðK£€‹qã ÂÆk¯#é@p`‘ctHg%R}?[ÐëH]ÁhWœ‡É3ʇf ÔŸ¹Ÿg5�\¯ÍôãÀÆÇ;¢M'cˆàCÓ‡¥• lÐÝ“{‰y$³ÁÃ6¤5X2ÁšQ)IÈEº‘ó‡¨o4Á•ïÓ¼ƒHñ}Ÿ:žúªSvÿsI½8¦‹GÛ¿XTI®ÇŽ@ÙáÚÔÚdy{7?úH,�ø_e‹¹‰(QG‡‰ì·¯yï_µ9'³,®!Q„襺C-Wò��: Ó¬[w¤ˆ<]õj}õÉiÖ û,˜gÁÈ— ©"‘{ª„~ñ�ãI;�ĵ[XJ L œ8nH™è°âÀâàâã_ð+ã]+5qÀ@d4 nç ¾ŠJ‡h­rE@fî¡|#¸Ð[Ppå8ì®0зuVSõåîñÕ[,Æs­DÙµ+°°gX@$úÚï@ðŠ‘}¸ZPùJ2ò�>¤m׋._<{ú„+"{w;жiY -MUœ�üfÎ�Á¡˜hÑ™á1¯Þ8läXþÑÌ¢nö…t"‰Ã(Âo#Že K|—Å5d—Ô�åikQFÝîsDäÌ…Ë ï½/\½â·ÛÆx2ËÀE“kr¹Á™i<­Ô;¶fÇ>Q)S6æ! íÕ;õèg6"¸3Ä6ëàÑãgÎ_*vEä®õÕ³QÌÆˆ;*Ò«„iDÐ];ý°HÕãþÆ"á83’ZB(�–kî\®' ½fó‹þýÍ9s‚ ÄÏÔr ß�ð䃻ÄÌ#Õƒ’Œ!¨sPÚá/î±äã{Upûq抷q/«ô#]ýP|À8Äã£æÛ-ø„¼îý§Ö¹/U±˜ªò$�oˆ¹"ÌüFÒO°Nq²&"Ú¢½ŒºQi@ {Å‘'.¹ñÎò1åÖH… êܵ€|ü%‡”CƒuŸÎÛ¨5úÊݪ›¥%PkÙ·‡Wti›¬åp­´É/ÔyGtjˆnCX”e®ô�MÜÎït[QÑIýV]´�»kUy""œf9®~î" |}¹óŸ£lZB☆� ïƒéäù<'4–ŠûPãíS )Áb²�`Bm±uk ü ÿò-ÅÛo Ÿ7Ÿ¡±�ÉxŽŸåúƒ.¡˜ZH„™«4ï„§ãd—C³ WÎF\7þÀ!)ïÀrÐý„¹½Ú\ý60q?áýR?øcùòÇí5O¼£uÀ;�ŽÐuNã5¼4¦Á#>|ˆ}ò®L°@Ä W ØÊÐ_~jt å¢Õ} ôT•bßAý™¢uÅ4D ³Â3x) -6ÓÃùA5e>àíKv?ª¾Uv½'‡ ËÚ¼±¶&‹f½š!F¬ï´õN÷}ô6‰ºG'–s�…·I¸RïÝU’ù†‡\%¢½M01mZž8_WD>ãÀä+¿ÙÑù5m‘ÝÔ'0óµáoõ?‘…œLŽŒWHžЕbB=v] (øšyñ/ϧfÊ !ô‡ô‡ÌÇMýJ£µÜHoõÖ›®zp2©�]¬×ÿŸHù vNËslc7®£tƒ|ý44˜þŠŠÉí%+²½ëpÀKo¾'èþFÊNç ïà ²"¤ ø4`vå²tçkÖm’¯ŒS ?gÌùDfq‰N¬ä飗wŸSklè5ÿè~í‘ãk8Ï€yß…óç1¥ù[­VÞà¤G4¤æËõx¢¬@¦¶@Ö!:qaqJǃû©^];d3B2>R-b1¸Ž†ë6\ï)HE_QáÒ¸º+"W¨ˆðNäùþÙjÿ\ŸØº@ ¦&O�9oÛ2¤ï$"’F#õ`˜hI¤Z2øÜF!0Â’!tC‹D"‘·2þö‘•”@訷’Á®Tàæa¶u³ÏÕøòQŽƒ°Î�ºLW£—Šðm³í¯îñ(}kO¶wøèÙo0 xí�­þ(¶¸é‹W¶øÆg$½‹E¼ØÇ,�æòùpVñ²“ÉÆFd2|ÌD_@|äZÜ89r _iµÞ›d'Gœ`±Ó§äŒ-zñ[R˜øaK MVmëB™õBêzáç^%Û˜ƒ+QGa¯&ëøa/¯CXt‚²,AHƒ_©ðþW 1:á俟f˜Å�¸e~š\Ý~#“Uÿ6±¾IpqU„­QcÆ‹Eáë¢{ò‚r¯öåìy;Ø ?ù¹RPˆE0Zrö�{`ä†�œÎyöâÑÌÑjoÊïvÜc€Ú·¶ä£Ñkònб�›Âε½òÇQ),o™Å‡é¯èǺ¹7§àá‚P „�¨IC„€À!8�Œ/½‘;š™KƒUCߦg–̓�&OÓ¡ú<åÆMÖf y�½ÁŽ4X×ÉÓå•k/Û™x­ ŸgŠ·2ç}œÐ…¡¼I%¥ 2ü �™¢}çuˆû2ÁVÛý¤ †°‡@ÆÇÊE¹T8nS ÝÊå©DDç½0Í"®¾{ßÁÃZDt±ž,ý½n1;Ðj�ò“~`Äæ�¦f‘m°í†N“ƒóÌ0ÉþR¯L)Š–t/þûXØú‘'y ¦¡SÝË‚¡·¹x�âæÊÁ¸¹’�ŒÞw7iʇk§ñQè~°0½¹ÂÒZ&éŒ�m;p ø¸}ŸæªÉ�Ãt�Þ¹|!ýô,ò¡ƒ>¢ŸÆfSDP±éxyýìA•$»n‡Gb- VÄ/š¨Ð?Õc7Üμ#œÁ™ìTÇ;œ†ÈV zæÛ|¹0tVËîÁ6JO?¿ìš¯Õ7E´¬øSg½kÒåAìèS¿{$êö˜,f6Æ!¯‰ñ¼AH,ï–.làNý4yðó–·¶÷Q–†‘"RúÅBÖ_žú\–B$ 6é½û @hö*„22WÙ^ ¨K«°øzÙ­ê{�"/.}uT=›Û¼%æÆR!õ ÖŽJ\°’,$kF-%?Ä[iJ‹Ý͇„C}seåHjÈy|ïÑÁ¼œŠ‡ë­R3y3zýÁÑçB>ÝãîêÌÉ£¸ûàòa¦Wi~Ž47§õe Wˆ•~ruOÁG›hý˜ë„r€A*n Þ-þI¢ú…ûL@ÊŠ/�e~¼nM´Ár½K�i°Ø~ŠÎ¤Y†.ÁäœØi‚d„Eyì ãòч²ƒ)&#ù –ÅÿÞgüäHÔøëS¿ÐpB4äZyí Ÿ|2޲ÆMœj�ÃrL¾•]‹1aõ{ï•|:û-ù/œ>NG¡H,ßI7— ¾¬_ÜA_×g^½�TDØz²äOgÆ‚‘–8«h®#޳k!y›O5xG’£‹¾€²'"^‡uÍz½nØ_Áp�šo|ñÂlPÇ�…¨Q,=1 rÍ›Ùõ§¥X>r¿Z»«#÷�r—ËGú猑ïðé_ÆìmÂGÍò†À%)±>ÆÍé#eÒwæáxÂG¶±ÉeJ@ Ïé"¥ÁÊ׊eaRr“½x×´�4§î‘¯Ä!ï5q¡˜öÆK˜Ö{tÄ{Ùï¬r¥5Ö¢‰’cm°ý=—ÎzS•ï.tÌ5ƒ*[,͉EFY4ì5‹UUæ„]–«¼ :m/ÿèÚ癸bÞ.ÃaÖQ±X“~³åÇYØàÛëÈúÞ‡"—®\sTÄ@¤¦äßGÖ�…�Vk.#Œ2ýœ" tëMäØ/G”"‰””!ìyv~%ã-ùÛ~Oú`¹[Dpˆ•Ê4è¬& ñp­d_uǘѬ¦�mòU×ÿwú¹%pò#ÝÕŽm›QZâÊðŠÔò±Ø—a¤rèÍwøØ*aXý®‹;„ø€úY çzy ت¿ÿØ <Ö%/!?v}ô^#|—Ë™TÍâÄgaèSõ Äßïçr{ƒ¬ÉÊ„ÜÓ>øÌΘÙ+›¾‚¸ˆi£ÑàŸEEÍàÞ`¡ž’�-ñ�‡�†È¾ðÌ+1cñBVºæ;Sî±YÚ‹±öUݦ;ÿeýÝ3î-âËÐÛ¢ÒÓ”6‹ÇY«Q�µuõY'aox­Ô±uSE®~kf ²ÜØ•Nì«‘ânƒ-é¶ô"ÖÈp¥š„«ÛR­JŠS,4̉‰^+âEï uu=“áúóðAÕ>ždà�¼Txù(â‹8&çÄ>ênSCÿãó…WËnÝ}DSŽçßéhù Ü'M#|…»¸½Â„/­)ÿ‹?¶Ķ7ákI˜TsÌ$Õ¼ü³LÊúDYaèaœÇ!N‡ÄµA}ô½Ç>?â={âˆoñÜó7ÖÑúPÆúž–“\9y´Šü”& ­äÈl‘®§ðmÙÕÛ/W!ãàgç¢âÃCæð´×Q§½»uj#ÆÖ�>y—©úýª›â-°wçvžß‹4+h³lí \¬ô¹¿Ù¯©Œ4kI­VÏ>}`‰Fnhr8ƒ+ –’9|㤇¶œxAI´­ 4(F/¿À__!6딩è/?n ÖEåï60Å#sà?—H�|ÁÜÜ‘�³'I˜H¾¼û¨…�/]®êh¸8xô„£pdíJ1£_i®o±âž‚"0aSMQðÒ‹e’ D�Kƒ/= çG»Ù–9½†ƒGCb^H�äÃ�ü™”ˆ° OÊ‹Lètf¡ÚŽ1Ì9ŒäÂÚeèî+ˆu#üÆŠ�¹•ä”T…Ù»GB¾=žZ!bP¶X*÷3?ÉÒQ{EÙk¦„À>„”‹�õÓ©­¸+7øÐEqoªVªÎD„DuZšynEJ"/"Û?7 ^˜FÞZ-À÷Z`"=–üܦMŸN~nŠ9œ§8Á’²0' ¯‹·¢_ŒyþÞ »*l«fN‡¾Ê•H(Þ�èèÙ½K§öm[GÜ›¿õÝk/ <ˆ›ùÀîÊ’ó¥é9\àÃã+¹�¬übSÑ'¶í,ó«©R?H¾&øÈU|Ø ¾Îzeý!¼yþ lÿÓ6-ËL�6X•´}«Ì“3©.=9 Ð'�åj\OÜËÜÉν}ËÆøë|Tòدú%¥¨Àbáz~AHæw’þh…ŒQkm²˜†àmÈÑ“ç½þ³¯6QU {�CR¤ËÊcñû<p¼ ˜Ñp…ëÒRލgŸO¦µß¼a½Õá£$=a÷E�gíÞ9}ö" ´Â*òòò�hhˈkµZ´jÓ®CgÁ%ØŒkA %z2kQÜ®`IóBPð�Aƒ®«°§zƒ SѾ‘Œ€‡I~�#Ž—ckå‹GF›ù‹$_�áQVR\H£]ð eÉo/!pKì™?]h:zÎ)^²¬þT=Ňί<>ä˜0Æþó�£¦Mq��;oæ«§å ]SßRw > PÏ¿U_TîÝû¢ëÔŒ�¡ÛÀ5™��{ÚÂÔûòKâ@duQ�ÅØ _ýöºm3¢ž×2RÀ–pµì AØ[Îõ'Ÿ�ÙL»a¥?!÷y“tY`Û;�ò‰y|0H<8ƒ]ª±¨Ù$ H©��³xm}�|‰­D\¹óàñó——R¾ba³X FZcZOJ:lx’i3%ÐqÁ)-’Rô0J!ãá0o¾?¤â³Ã9T5È­Q¼0ç-pJ"&ÀñZ«XFï/6ðxt· Žà‡½ëÙ«¼Z’òXYj¶Û9K]�e¼[´0“ï?@¿Û—ç»ÐCK¥-B•ù <þi'ÞîÅp$æ˜.¶YÛÿTŸ™`¶îÐz•û€¡£„¡ãˆ¤&Î âH¥8¼€Ig?캦½2%¡`qlH$í46§Ê‡3 vÓÝJºžp©�a/KßË?3.­„^‡fYœ/EÈÐ�˜é.é÷£g�em³B�v„‰è4f5ŠO6oƒÕºcë‘‚ȳ—RFînúÜІaÆlÅH�^½1ìi¨¯ J¦‹¡âD Êœ9ö´–pçú¿ä[\¹]g“.3f�¹V�³�¡3D›5nXß´V±ì×þþÜKÍ{‚ÕãúÕ+ –Hw%?°4Ïs5€ôãȉ3AÖvòÄÛ1¹tø�ý ©Þ+AªÔùd¢8s:™t@T ß¶ù7¹BìE±*iÉUÛ-+‰ÈÏ\TŸ†ûâO8a aw踖——C‡èd– *Å’7]ï/%�U.Öʾ‚z~wíØ&‹@c™÷R«pmÃ-Y­DNÔÑ)K|¾i³9^l’ÚtìnTžŒ�xÀCâ¡¶×!d˜ƒm—ö*ÌÊú‡‡JDÐ&ó4ˆwZ¢”ç¡hOdoÈ«õ"7DîˆÔ”ý`jËhs3ÇG0iBŸú!H†¡ËôXq Eã7ê¹ØÞêuqg`súÿ9úWâç@Þ'j¨å '²)¶€c@?l¬:wìàx¤P!Ô�ß·ã¾�Ö{ò›+0s: Ž€ûöùÐÕGjwN¯HÜŽôƒr%d|•<8”ñѬU».Z?f¾frÍFÇ\þL™0f$Ytð“¯Þ_ÔȆðêå³'A‚EûÕ(懇zz†äc“ù�e*÷Qã'‘5¤) ,2•â´r§%*×—ˆÌ>‘§„á!­×%õ�…z4dÉrŸ’"$IåÔ(EH§!ÊC44,ÎÆrâ4sßÓ¬ }ª4 ")mV:®®}–Ž|ÝÛl rô$BäZiÅíêû�T£åÊÈÞ?[?«Ù¨isÈ*ï€Éh�©‰áO¯Œ œ† UrHœI†Wìï“æ5Ký€Ø=kúôé\5ØâW²G(À�U›ì–Í›6ŠD´7yó[gŸ :^>{üàn%q‚ssž]¥'çÑËe÷(ÙµÝ/Àd¬RB„k~Ú‡[ƒfÙí»ôì;®~,>|äÕ�xÔJÓä&ÕûdµlKh1ÍÄ�ØOšÅ©[~Î Ç"űÐ`Íž£"¬Dž8§óˆ—w„z'Õèg¼#¯l»ús?¡<® !ÊÔgßJÖrTöŠ+W¤æê,]Æ4dëNüÂAsÂÈ^Ó]'åpI3Œ.if¥ Ê™‡P%„@«:v$J;èø cîu«��Ï{QQ„‚»i‹H>oÖ—y*BUdW‘ËE×n”ß®¾çøº–‘ä�ÿø@ïÌXÈG5iF‘å®ÛâøÀ�”æ!¶ì`&*N¢SÅŽâÐ"N_ôK3ÉQýÉ«t"Cc̨Q#9qd�£[ goEGã!ŸZuW‹Ç‹g�ïß¹]AÜüd‘Ÿ¬�Ó]å×Ú^­·ô£øFEÕ_=ún'v½hø€ûA[?ô2Oݨ3˜ˆÉ{Æ&pf©Þ¸Ò~.ý$êÈF+ÂÊØv?ý$“]¿a†¾�Ã…x•¿PÍ€!/§—ŠL¦ÞâBu¯±Œ!›¤Ñc½Ï=ÓÝ?IkÿÂ…:m¦QÖ98¦a±çÊìÈ­ÙØðÖÌ»µÊ´W2²îq©ÞFÃô†oÙ�#"t´r„ýœHŸ–‰(DDä몈B&Z.]¹#- #¾ŒoMÙKÓ[=¼W}»âƵbo·¼{ç6v$fWiGjãÊÓÝ#ä–ïó$îÿßFܺC×^x_;a ꯼C\®‘±`Û{€^ÛX1�:å úE¾7W¬©NœNƒWRÒ`y�‰¬@V<ªÑ¤ ƒÿNÿeÂrµ&ðœ—@È� ª>SÕ­kg×Va{3(tôxßwN=L½UÕíò%E—�š3< ÆnððXZ[™5ËA™îžƒ¼Í×N^û 㣱#–]{õŒÏ<À‡òsñæHpÊ.Ê$ã1îXôî¼ÙÈhC¸cË&Ú†­¼q…ÞºƒW„r^q~¬7úáˆW¹‹V2×�x펖¿þg¶2âõ;tù!ŦO�<[þ^!c/(¸SÄ)‘¯]î ý(«ä&{Y ý`^ âo!¥ËéâèáCôÁaSõÆZ퉵Y ^dÏå@¸|B¶Ž-(´"ÇO�9 øzùíª»v¦•L>9ñ¥íê…±ÍÀH$Ùm0˼ † :˜`5$y8ü!!c1ü¢ÿJ¹#1Fdø+Œ Épë n˜›ÛÚª¦©àˆÕo?ë/Î=K&ÍX÷þ�J\^8wš«Ç†Ó´t³+{Y‹?6ßc�cÝž'O¾SùUÇn½Ð5ký,/E]( 3§±»S—v¢ÀÊþ7CÐeýÀÆ�ùöÍc¼®@í8_I½ø7X­;õèËÁ –$1XnBúãd2G¼’FÒj›äMsšÕ¶MþN ÿøŒ�˜wñ¯ï{¨³^CCjGˆFF`ä� {ïÿ±"##@t2Õvª.¿¦^ÀëÂè�˜ÁgQVM¿õB“F¥þmô³Þ‚( ñ¡\'l¨cõ‡ø‡ªž”a—e$;yq½Zé"-Dzª›°æe$×Âsu)"éÆYBEx Å›Cj´öDNŸ»p©ðêõÒŠ[PFž¾Ð¾>™||ô»}%+òÍpœ¤�ë·JZJÀ9fÕb=é ÙƒPS@ÐD­bä…Él(@2[_LýìÕ£ÇãvhïzªìVY-°p8Îù“cYÃ>ü¯Gt<§âQ~ãZQáÅógNaÒ^ �¤êA- ù0çty®9+'9gEèǃït0ë’·cý˜Å»…Þ,5‘P¡¶àc:ÌvÕÐÖÌß½K4]>áÀ[zZ—Ñ(â¡×`]b,¹#“xžZÅ!CÇHtñöV/®—¨ŠÝæïŽ-¡“ „D\=@?Ã+œvÛ“‘ý¢\ѧ\ ‹°²§`”uöRñ ‰.y+qm5Y KW]æ`~ ³¤÷³T½ýw™iÖõâK¸Ù§@vÊŸ"¤a$.t}çq�Œ}¯—yh»ÃãÍ¿5®mýÈ'PRß¡¤IÓæL; 8¤t£¬Nˆêtx ^P*îÙ£[7ÈÂ팹ѰÞ2«¹«õS°«×zÌol»iÐ c+`¥°õ¸pöôÉã’ɺe³ ö^šög²Ä_~¨-%9Šq{Åô£ú·Ibp6¯Ý;)õcÕ�x<áݧâzÈ@åàÀÜ1›;ÿؼj¤¼©ô-¼Ž®E7¾^Ó/ëŠðéoû VßÁþ „Rir‘3)sGÈ#ÞØ_Ј·ºÜU�è=Ÿ¶0±9f} ¿œÑ¿zÝF™¤ˆdò£_%ÁòGOž»ìƒå‹gX„ H©!ºí”Ye$½‰Æ½“i˜Põƽ¬Ó,P/^¹à¸úáÀ�@w"i?ØN˜‰ÖÖí;�Œ:zü$δ€�ܬ„Áo€‘šêã?ú�)Íc±t(qŤQ“¦Í'®ëjHi‰Ï�öÜ^]áÕ­«¼à—:Sˆmb ¯h1ØŒ¬ï4Ó žÙªÆDUî &·ŒÀÐíá¬2^øÁG@ˆÉV9<À#¤[oé²!^ÛËÎ�*‡áù,÷2U7D¤ý·Ÿ‹zQ¹ú1ZˆIi-ß Ñ"ˆÈHËuZ®·6r–1Rq«òN´×ræí#?ùÈ ìt a ¸‚ÅA¥IӦ͚5oÞ^YüjA¯æÍš:T4nÔÈáÂ#=2à·lÑ'ï{û˞ٯ⥫ˆŽŠR[ó€±.öVœæMª©¦‘ÉnÚ£<ß#1BåéÕï·Š‰:±m'÷zE×ç¢ÏÇ-Æl€¶¾î4øè‹÷I5O@_~G@JÐ9˜�%&œK²Ê¬Ð}î_uÜL°äÌÖ®@„€p�kìˆÁýüÈü¼#Ä/ÐlïQ¢?­=­_õ&ÒDÐ{‡Ò1ó²'êQéû ²ßÃô:po÷$ühí"Û×Ö] l»¬yÄÔ5¼Aí€dÜ ¥MÅ0BD²>u%i¸º‘=�œ;ýs3 ëî´ Œ8Â~ôÄ)hµ€ŽFg·s-Щ•þÙ—£ÚÖò‰& T\UqhÉl¯†ôjÐÿ›ûÕú‹Œ:~›ƒÞþü÷w—<±:°rì¬\ító â�ÔƒÂGôA¡ëÓ¨ä\'vÌÎKoUËò ;�<Ý/É0‹†ÐxˆÛ©�¿ž¹Ó[ÍVVÜ(¦"rÀ‘­¤Î2sͺ!ÂddæÍLØÆVëcùȃG@H�$ŸWíÿ‡O¿> MÃØ/åU?«çä}e}ÙÓà­�Æê¢£‚ÑqŽbî]ñÀÞÊ1óõk#ð(¨«»zg ¯ |Àe-dsUj6×Ë]£còîe·wôœÇ»9„ööÒ…ác àƒÒ¾¹hùŸI¹ÉÄ¿l#ç~& ù�Àú`øÄá �L³÷öò,XN° ¬@¡‘ÉkÓ™¡‹×hì÷åŽT¼ä¿�j×¾8†\jŽ7ÞéÛSêò¡1f¨§eyÍÉêµÈ è8"¤šÁ¾¹›Šß#]EÅ�0ËSu°õ·D6"r«ëðç•IŸ´WÆéXÅïé½BÄ”‘ \F#‡#®×rœývÕ]($Ž‘„ ©y\z|õ7?‘Uï�Œ†=gò¯ó÷ß”×XUݾY~£:« g±µ‚©. cëfí­©ßý¢€‰­\)Ö/;‰}`ù¸Y­Á\÷ÿ¬k¼g9úѳÑs_™ó(¯OŒëyôWô#ÊþÖsðâ‹Mp£,¶‰Ï=�ž>ïWè7&X‘;¯ÅŠ7Ç'êÆ†>Ä0ô±…Ø Ü»uîž¼Mbˆ�űœÈwãú}­†Mþƒ3©ÒßCÊo²IrIq_º´;;�B+BÌ•x°Ñ3ˆ¯ !JDðnEÚ¬údʯüí�7-®z’ú×¼|•ã>•ŽÒë׊¯\¾xþ¬ clÌ™ypo¥f>ø-J·ôÊ’M[Õà Z}Âü‹�Ãb©ô¯_ŸmÆ»q›{W5„í¯ þä‘Çxù™+QÏéòЧNÿ° M�[‚çP³"ă•»�‘‰k�^›Î;ôN­™¡¿Í F¼'�È=Ú`@D‘ÌOœXwωÉ%�)<§î¬I«(ƒï‡'Ö;á:äÌÅ¢ë7Ù,ëåÒN†© Bü}|[ìÁ-?hCÕa×?Ö�f¹6K¦YYŸ¼�´LëBÖS�KSªˆ–é´€�à†ÝµZ#ûöD>rú칋—]!AF ¹ÿÐq’çiQ]muÉŃ[—ÿ›ñ»Ÿþõœ×§O3l@¯Ý»ãö£ hRú1~ÚÌ·Þÿñßüâ×¾ýÓõ»OWUÃ0±ÁbãNïwè#ÈJ‘¸Ã+EtV"¬Ó ÂÚÊi )?ºX^Ü\óñ°ÛF^ëtßÀûÂ*/Kf„ßSˆ�-ˆ’e1Bž}¿“ŸeuíÕOÔÒB÷Dv"A†ˆ¡mÍ{yš%ñbõ§­~nÒaʯ_-(×™£KÁ ‘Ô®>9fîKŒ} Qö-ÌGö!Ö~úìù —\»U|­äFi9¡„ŠÉSè¹Njþ븨y ÈxŠÐ¸w·º ±q£äTÇ™ST:`fEµC‰G´xä× Ú n¦îêy²ÚŒ¡š3n®íU6µWH?˜7ªº�Ï£R´¦Ê?zzy_,÷F€zØâfmEä³d� -¡ÅÚ;]$-¶KÏþÚ`Á@72¬ËÅQ�œBÜšW¹·(`±zùµËž¡¯Ô3B �#mþÛoS–ÍD&êBC�W§,öÜ¢£,Ý{Ê·µ ]­Q¸È5äû­ôž™2ïmf™{4ˆ$ØÃYòú«Üfá4«£1LÍþ’ˆqÝLY˜;ì]ë:²s8Þ,Ã'ˆvìÔkmƒÙ/‚Ä1’ã'OQ%)t¥PRV~ó–ã%&÷<|„@a¤Ô¼W\¸ŠÀxúøñ#¨wª+]OUQÆØ(¼tñü9•ŽÝ»vl·�•ûîêZz¤*5W¯]çgWÇÑøÓS¤|<[Ü/¦Ó+ß^1ýðøðã+“]Ìw¡|¼ZDÍð=ºa|°Qÿ’Z :Ù"alÑ+ì×FVèÓ^ 'XL@â y""EU¹¿ï13ôÀФQ¹› ’�Ä@Íy¢.Þ,¹éÒÛêBÈjœ<Ð î¥âR©!Ï·Wå"^P /þu!bò¢Sç½Ã÷ë Ú¬æâK_rÁ ëòïÈ:Ø4cÂ1\ФÜÓ¥ûÉx‡éˆ­#°Bܾ}ç®Ý{]·å@â*ÉÉSgΞ;ñ’c%ÅŽRL*nÞª¬ Rž<}úÌ�áâþ¼^8D¼xþü™CÅ“'P2\ͨ®rÕÍò²Rè©@9ΞqmÕñcG�8p8Nî+œY1:hjå[«tð�^æ=ö+.)»åwÉ‹n©¶l˜^õ§é.Цçóy|•0 ]ﲫPx|̾*QLÉ3þÁ“» ÍZ�>xr6 ø6W~H>CfÂKW„ •džW ¼éÒ–zÿCzË“'¬�Ľ)@|~µq¿#{zšÍe|ái$@.p‰ó§º¾3µZ�¦ÇŽ[�:@ÎC^~¯“EHßA)‘¥oÕu,¢ó^˜f a³;-"­ÿ¯Æ(Y/Ç>ù[ß¼aý{‚ˆgì²c7�Bâ ‚äÐWJ\¿ukÉåB„I‰àäÖmDÊ�»+÷ï?¸<|ä^�áõ_$<¸¨p£ªª€QQ^æª@£zª‹ÐT�>uÒqŽ#‡:pì…‰Õvj¬‚Ú±lùÒ¥K–Ôú}qsE{s%;vs(9ÞßÓÝÇãebªMäé•«õfûÁôÜT{Z]ÑÔñõôø˜u&ÄÇ!xÎn2l6UÜG7R{r¼�š¿©oÂÆaÂ;…ƒbñ‹Ê5ŽŽêÓY�ÔÿGËС€0C_šæ“Åޝç�*ûC¶eao3Ú¢?äÂ~pýª“—j*êö]à«t!Òeå·ög7„uÅÐC9û'<J%"Ó&O;zÄP\‰ ë6OZ†ýì™'ë°)¾|Ýši+b,oôX$íg)?ZGà�Éž}ûö„Rr j‰ë¸Î]€ž pâ¸Éõë7n”––—WTÜt`¹uûv¥Ã ½ª]� WåíÊÛ·Ýß½é`Ãá€Q U qαqª‡ÄÊÁ}ÕæMŽv¬_ëGº2ÓMËËC]�Tq;‚Àߨ#µ¢O6SvNËÁ�Cá6jò´¯¾Îá8ø £\š„÷§6®4ãÇŒ$ï?ÅǤ+*À*!|ìÙ±¥®oh',Ú€lê )˜]"+ô~¤F,¯1 W “nÑ—NX§�T«Ñ4 9ˆÁådвÅNä”õœï#Es²F Û §�x„@—Å5äù²žÖ—¯/䢎·Ku˜fÚ¬:ïum™L èíŠH›, 7iùñ#É MéšPql6¶7K—ÔQF´ŽgçBâ>Y$»©” JŽ�˜@ÏuÞá�â�rõÚµ’F‹{•™þ‚ÃÄu‡Š’«W¡`\qÀ¸|�qî – ��½ÜVmž K~#tÔòÍ,±'QÆ<F»0»¢îJ€ïÿpT†aç�qzÖíJ?tû‘y�Ìc¼�ŠàcÖ9É›,/Á˜q^ §—¾F ºOOž�¨FQ ˆ4Xsf£/ýt‘b‡w$-çêe4F„±ì;©;tßb‘„ß[M÷ÍiX4á"ãÿv øy¿“¦<˜äy.BºP B’=E;í�+Iºø&7·ñxN\s™rEÞ;Ï. ‘«ã^ÝG7ôý~µ(ÒŸRÚ±£"ÄÖ÷ˆ3Ttè›öSôZ˸ŽH·µa�Ä£Äu\WM'(çλŠâ rù²ë¾®^ðåêüþ{Qü ÷?¸|ÉŒ ç0\?…È@hxlìÚ¹�Á±QÀáѱdIÝ߇…‡õ–dòq©èÚ�›U÷Éj°æÌ§qùvÞ¡«L¯&M¥i£?þÐt’—ø�<‚Òñø�Óo7õ¤ŒBáÂöôqœôÀ(zb›oNT׃Sú€iH,ßpà w7r#ô+ôœ£Á�‰#Õà§‚a ¼ùüKqÂ*„3):&O·ñ M")Ɖz{!ê¯ßJª‰ê¥3¢9y7„ørÕwY;z³ü­)gK 7Ç›R¿é:-áû[z@½9–†Ž«�q\½¿0." ^[_ã½7™Š [gˆ õ暈Î5åC%o·&¾�H·í¢dÛŽ�;w9î¾—ˆÉáÃG()*+€Ëy÷ƒÿ¼ÿ¥Âaâ¬+®d; EÃ!¡Au±!•ƒX5V~á‘_7Ê‘Pqõ@9&Uq[ê*y÷ë½b¾|´ëŒÚ«Ü^éÛc†�8-ʉ«·òl>½£û(ïÏ?½HóŠ�B¾Á+2RX²A�¤—½øB=O@Ðñ™&¼D@rDó’ËŒW„ÑkÈe^�”â}ßNOIƒµ(]‹¥6õ折\Zx_Xÿ÷îÙ#I~¬÷G`)%úˆ©;ikHÍö‘1uÏïˆö£íB$ ê úviD"ú^ÐfÑ^]ŠC¤ã�—>‹¨Èu�\m§F wjþJ;z‡šº�f‹@‚kÄ5k¡ÝB�8”@ǵ`²ÇÁë Å••cÇX-ð:å_ô îo¹jáêÅQ¬‡"2ÐS9lå€Âa*­;Þ ^EÞNŠ¿=��«×ËmwõtK¼¡°(ÌÎuzEŠ¿Ôu x« >MUýUlÎYI+®@�âaÌ«²AßJÝok·Ò ÈxvD�¢S[n,ԘР$ˬ@ÎÊ}Í;é:�y™öçäˆn‘|ŒB¼Ì¿Kªæ¤›È]á°7Šé²v@•$¦~‡ �÷Oo°4+:ÌJxÍ@Øf9®N{ug™qVlðÏî[*rKÓ10{Ì^jã­î% `„g[ØnJ€•¸Z‚0œìܽÚ.BŠƒÊÁC‡-®´„/÷K€  €ãû©�;°lPOå°áÀ±‡¹«xœ»¬öÆjQšÞÊÀƒãptu¡°¸¤ÌuW�ŸÉ¶æÆŸ¶²å£”�¡ÃýrÐßFùãs{› ÷m|˜ HŒ�—¥¿*§ú�„´Y]6¨Ë(oÐÏšóí}]UãNd²l°b©’£,0äÂKz¡=¥VˆÒ=LH-cŽ˜&³Æý·ÊN‘0¨ë$Ëùö?KF-~Ø»B‰Ej}›ØGž:Kûz\��S‹>\šq¯¶¹>dǯi-WŸ E¤]vsY¬ÇÏ]ûBD°œ¯-”Ÿ^ä¡U×r-µ�Ðhk…'%ˆ’ ©š8œlßN@ÙåJÊn÷‘ß ¯}ðÚ¿o?½Üâ/àßT8X8\0 h`ÕÀžÊ5UkWSWE ]­¾t,ª»·2Õc§Œ­2 �rþ=IÄöåc0”�‰Z>æÎ·âDÉ��û].]HC+¦LФt^‰ï¯À ú+¬ii¡Íšø¡ã—Yüj°Éé°L@â�È{!Ó`‰“âðÓj5zQïÐW¯¬µ€I$L˜µz©òF½[ñªï¹?é­¾Î[ÝâŠZD'`k½B³,ÐeB.¼óG†]Å™©º”hªrœ'%´44E„˜H›–Í Yo÷‡çj|¾ëÝJh9ˆÐQ*»EÙ£»¥ïVF#†’J�”8”(L'TP¶mÛ½—Ê{íÀÀÿûþºÁ*†£ˆ …Ô îª�‘+é(¨½±J½(æ­¹ÀCSaq®äãùþ_oäwT>ÎìœEq~‚‹\ ˆzWÇ»ˆµT–˶z¹…ÊÏQà~D/ÐÅ 'í€WÂa/øD�{¿S¡LcUÃk¢@Ü&'. ÖkÜ`y�I£+˜5û´µ´?՘̋¤9 Ò€¨û´“1<Š€UÏåsz`˜¦“Ô.‹r¼pcxòìELÙ&„”~°~`£¯>2"" ¿4¤e­g"CöëÕú,gÝKÄ'œñŠUä"Øq"] -FÞy'˜Õ…»#¡ 0³ÂÉš5ŒAÊ&ËÀ ¾Û ð[ €T #c "ƒ éªl,Z\רJïI!’T=ŠJJ1 [Í( ?ÛVî|Áî£KOW>†aù˜6ã5Õ^‘v77Ïœ~‡mbÊoc+2?~Óòsïøþ*ÄÇ"��5ëÓd2½ø«âô̬É@_˜ uÄ2›5X±Á¢ÏÛû„a ;êØ¡ë¢�¾]o13gÑ®7êí[òï>·B–¡e1&U¨ôa¦ÊÅ"äuë3 } Œ{=U7IEbÕ—'vÄD"Ed@Ÿž];:²®}VæÔTÚ0™Ê †L´ÈЙ¦¾éÊÈ¢º0¢ýÍ€—QǵRÊ â‘ÂX´Ðk“¾6""°V(Üÿt‘�tCظíªê,étÉØ[�¨„½ìµzÜ6IñÉòo�”Ó­MZ´nß©»°,Ðõj{¥m /qýi4Jå8ÖÅeþFãs­ÓÖ�à`‚ü£p€ÅÞÿh%y3�I‚e%&DÐi¤£–Ù© Öгš÷œâåž¾€ð‹Nù8QN #e£ÞŽëSÆç¨³˜×!4­K+Çd·,*—TCŠ®W°õ{òáŸ4öלäešذ;«Í®NEw"ƒúõ¦>K—" gn{b r!RˆU(;wDì êÒ‰§i¸L-!öŽå€òìW#VX`Á¸þ@°Îü§ûE@¾ðï��SÜ€påÈׯj‰54ZåÝZÈ:£~t•|²~z}%çÍ[µíص'±x/Bv�ûéUBÒ�¡ ÏL “輆Ÿ½«õƒæWµL?½K$îüy9Ö[\~0±lÔ8ـ̣{Tþ”ärô–h°pE(“¦oG5&[ÒÞ¡§îA(ñ„nîu”e2{YsÒàË/tØËa }¯•‡,•4aFÜjXê£o´“ƒ£‡aÖH¾ç4#E¯>“"²�¾\D¦L?ÔYDÖ[4ÑyVöû¶>�@„BeN©7'tZÒ]å¿;Hॲ”¥ÌßÝG*Š–~­N÷’¿ °p<¶SÌ54ï¡n¤öE‹L½ÂãÈ1œ\qõðÁ¥/·%²¤»"rÞ½·¯p¬èÛ«ov:qKÏ)âž½9[ÉfªùŸ>d LÈ^uøàúAæ:aý°a3äаÎ�ç)J…ø Þ€,°Ä(nŒS¬OÜS;Ý Æègyúz*@ŒnQ5'šÅ£¬6?¤vðÑÝ›)ëFÈ¢°†,7û�#' †”WqÜvÍ¿w¶ã^f�™0)89 G2ÏDr´ïuo̾ˆàÄ·KÐgÅÚþáé"7ÉüÜ��Œ°!•‘H«•Š‘Eµð_N&PP¨ó¨È ‘°jeðZáëR ƒ „Æ{‡A‡µú±..Í¢7÷E­¢JL¾8óû�Lw…ä¼ïÀ!¯0ûx•ºÝy¢½âK½Ós5ø“<Z€¼„Þ�_J Çý*ÂÇaÁ‡ß/§5Æ!S<·ÛêÇÄÇ�l'pZ™âPƒ%6? Ћ®÷í¡FqýÎr.”¤­móg„µ>cLÐ’v÷ª,Ôœð�:WÍ6ë’&6ë̉ÃÑ•úûì²\S‰W¸&�¾f[_3ÌÂÄ;Ô�ÈÎP+;‘¤¦µ±°Á}…²�"2ê•!AO}V†$[~ñZ2¤ë�û FkLFÈgMÙÈÊ@¿±ø=¿Üy‰v],ðû-¯ãµŒQ±Ôþ³T4òßã­3hÙÒ¬Y³Ž¼'ØsÒÀ+²¤´x¸Ëooá4[MÓ홞�EÞem½Íø�ž3>*iÿ�ü\vgÒj5|0à=FÂ>ý\}OÐû Á ¡Z‰ }8脯»ˆæ¶éwÅæMòÐÙqY]ïvLH^ c¡5¤õ­çQÖ�mª[,¹r^}¹ý7]°8eÚ+c;DÈ@?’»gW2f×¥ù½d±îÞ$ë}{vë{C9È�Õü•‹É°Š DÈæ9 DÞûPËËR‚¾«kŠiÀäÅpˆ`¢€‡·ï­b¤Q[ñMýªˆQ$Îu±z—Ü€°R_=’W¿>,SÈGæYmÚwî³Ý |p£—;¤¼¼p;¨ê]ï:|ø°ä~/×"õcE´~ð‚Ð xÉzPXßi®�°,Q‚Ú½¸�òÓÏ®4X¢ÁúÌÖbXú4lX+¦ÅuDš|±¥ŠÇÕ�CøF�þ˜q…:Ê¢a¯K,3TPC¤ËJAÈ¥7ê+BØ6Ü>ó¸7'×c8¡1ã¬)4ñÕ>K]b±aߺQ£ËõÇj´ŒÕ3nFÖ­ñ†k?w I;ïÒc鶯üú9`‘íùËÅ–…wædÇ�Ü©ù�ò[�0§“Ý›?-Ç]wÕ±[Ï> Ü=.¥|ÒDšy{Ø×µ¿Âú¡òÝþÛ“!ÿ|°C\JeO¤p€uàh@З·Q‚Þ­Ï@ tR»H18¹õÏf±l” c"ê|£ÞJüUÿß#VDR€/þié쇣5„Ý€Ž»RRv[(6öéÂVÜ+¾¤9¬ÔÌÓÏY¬óÚPÉ:õY~žå~ó�¿:éÝO,1‘eÜfý·²è—ù?_T+>VÛ|k¿dò!¢ÄÒšÐ$vWŽœãlî>lù˜oMÅùÓA�q}ªçç=M¾å_q±ÅÇ®Úë‡ÉYc—QÊ‘¢ëÁG2øFÊ�ÞubŽl º#”ÒÒ:ñqÐfsRúÅè dI]oB,áµX‰àˆ’‰úk3‘†@µ’yY¬ñß¿ÐuöŠK* ‰0u�ö^¸bjHòð«4ÅËjÛ©[Ÿ §ííyÖ`&!7"y™‰˜µ!‘uè³²[˜>+ë÷ÅÃ�=©¾]}ÖÑŸì2‰É!¿€jðKm°–.gŸÄµ¬h3í^BI»é®j®~Šw¡wÝ�ó®=q¶ Ê-*½ÂánðÑ�xcOM¡²å>û >`Ò‰ûdÔµò�í²%é>"Ë)æ ÝHÑëÑ_5f‰"Øð²kæ,Ÿà§õ Ï@ŒÖHc„Uÿ 4r†Ol!e¼›H1z0•`9�‹ryá"ûÂ( iùÝ—)מ…¤I4Ä¡:ùꂵ²3БójY%¹»;Öª ÛŒ2>âyÆzHÓ:§kÜ31Ê e‘¢õi¨k‡œÜJ{Å�¦øœ0 ao{)ÇÚ°ääzÑE¡<:3[’æI‡ÌwYé7†ÉäÝ¿ìÀÊEµ"K9 â' �[™¬ ýÄwÂXuÂ>+Ó$8µÉùQ©œ>ÀyHáOáAÕEÈ;6+÷Ž_xÊœÅËÛ+f×ñäƒG»Oö|~��fpÝ�óÎDÎu5ˆÛ§·çé]m®…ɬE”¸�ã}-çãLÞÇpd}ûÙG1â9”[¤ =š„ÎGè5ÿ©>Q­#7 &ªSe¼bôó*ýhé¶;iÎ#q¶ïÒEÓÁ÷üïyæ8ä­9j•…F@�%{`-]O¥‡¤ÑEØ+\EÈÅ¢’rŸ£ZóÓÞ–”hˆ‰‹F©ÐÄ„ذŒÇY<ñ�:™Èú þ½{tíH}–IÈûý—4Ïzx¯Ê\åúÃõ5&o½àçFHþÿdƒµLëÇFëVr¬DMù¸¿í3Ù6q¡AKÎe5hWç4nÔ¬Q”“µá$jò­¿PýöVß¼ŠÖ£h࣠õ;1 Äeè»Å Vè½"^½‡à/�g¯oâ�í˜C(�Ð=›|·F �xw¼»H1"5I0L¯©I×z_ØÝùÆzíÓõ36F=ÝŸY2uÚžÕ‰AÈñéd¸ÚîÔ¡É‚Cv¶Î1¹×á›&ê, ÊÒ‰/÷Y½@|ú, ‘ú½cÿ kípå¸A„`‚[¾“ÿ¿ >ƒs¥àˆš]]..)½©'Q•ß�‘e¬�œ·'r>lähÖµ›ÝG1ó,xuþ•üë5XDðœ Û¬ãG¡…ÖæMš½³ìï2D °(E �¨�ŸF?†2^Aùxzä¯&4{˜œƒð g»)å#Ǩ›~� Ïñæ7`P=ÆQa xîÂô@n•ãëGÚ³º ÃB•;Ù`¹R†. …Ó¤ê7e—?áe’ð¼€·„¢ik“Î%“&] ȪwañWóm½ùüIƒ¿P÷’“ÕmQ𬨸‹di ¡‘Û“ôŒuYkP­‰W¸g/kJžˆüUr%ÅqÒ1*! |2¼Á³<Ür� ^Eà–Ê“uÐÁ‡Y² ‡þÃ…g®SƵáõb´„?ŠÁY�²–þ÷²è—C`R‚>¼—èÅ+WÑ,¦è÷v~´]€˜Ù8œíòjг�8'µ$A‡¥£Q•è�pÐo³jzàbèÚe”êíÞá ~Òž%i‡ÅQèZ@Jfi6ù¸sƒõæѸý$ŽljÞó×™½1) T¼z‡^›S\䋳Ra!jÿ«·'ÊQ<ÉÒ=Ó¸“8ê½Æ%dëÆ:g&AïÔ9á¹f�¯ž€Š48‰:RoŽÉ5/'/è†å e‡Rõβò,!ëÑ¥ýØ»½ïÇÅ †pmGÕ�hèZCC~Žël"œï àæ»»öˆ×îU²jO>?ò×ÓZFòÞ`sÞ®Îve5ȺöÀµÄÓrÿÄIªî@Œ{6XõßwJe¡(Ôß6ˆc“¥iŸ6Üa­Û>qP@®bzÙt�Ù¼uGñqŸ)G¶*SÛÛaaئI5ýÛçɤ?‘²ú½Œxá§3ûA³0Íó×½ø¸€&‹겚DÃîKIœœ™ÕK­uË 7Ûwïóž‹>͵ðíLÖ4CÃ9iêÌÀ6Oîºô  #-Ö½3�#ëXDÆŒ|EŒö˜JÙÈ+_=t×µËè1w�ãÛvaÖúš5¤[ü_Úc YA£AŠR;¸ª{OžWlüÍŽÑüÜú�›£ðŠu»²”ãüØÉä4aû ~tæúg&ïÇX¦—Ñü·n)>Øàç Ä‘mAô€Ð?KècA3Þ=0IêæÝ'É»–ç0t Êñ+t;áe;÷þSܘ¹ƒL¤xÈU å—¥€x× ŸB1ƒ‹àÉÌ? ¤*\-IDATÑù Š[ê£xfI 0ŸËg9gz]…ËćP.¸�/¼æ…‹¨„øjóú^´VT™ªX€$ò©_Ôž�<«Î"«‘™_¿øèaUÂ#BvïÜFQë«dj¿$ÿ—Ð#ý÷êŽ8Š ÏH9Ç µ›wÝßÿ…‘ÍRâB]ùȦò1XVƒ`ʬuófŽ„üæÉ dø ½iF�ÿðyîÏ%¡³Öô¨œLÑa‰^VùðŽßÊô„ºúT/°A jöãÂÖÄÑÃõéŽ}Ì9þªHæî H]wè¶JÇò‚á•ì ­Ã�„,óè呸#_PøünšÙYÁâºW•;öpœz¹!êÉ䓟�h�ÕŽ�óØ™˜3 5}*á…1 -€ñ6iâkÃY3gP¡›õ®é‹ˆ+#ƒ>ñÓÓ·o—BNB¨Òl²V,OÏ+1öEÿý"9ÎÛ˜S[VYqèÛñ.©ñë¢Û�”�7Þ4gƒñ¸ßÄZ|ˆ3ʰ|Óý 9§5ž²Í„˜:B,`­Is+.A`Æ{ò\aIÅ�'�¿¤�<Ûü C7Evi0ó®ùsŸÔ Ãе[¯_Õ]Z¢y;BVòĬ˜7/º8 ›,Ø«•Çj=ª$}$…®åÒUûÛJïªÜS®ÄÒëô‚æ­äðx*g?PøœC N¨¿0§¶!9_DZgyû¬€±÷ùüú‹¥× /œ9‰1Ò®ÉÚÀÂì_V�•ÿßï°˜�¬Gs¾½ Çù•¥g—ýZ§ÔÇ€{7i‘ÝÖ³� †}˜Õ ÙÆz‘ž®Ñ1`/«ÙrªCËæ.3‰YÏ�-'ä¬[“jàùV–á%úÆ-ÐaE¿ýàÑß6õo�xCW›¸ @ ™‚LãVëæ™ þDz8´-¾Kô�[¥€Ôùä+0IÅ?FØæ$<Ѳ%$Vï­¢ût¸o·Ì±¢ÏÜE)5d5}î‘CÛd¹6ëo{gwކ?à 7/áwº!°Í©tÊÄ7Ôøff¤K+Ïõ›?>[¾ÜØdùòË'!?%ÉF°z‚~òÜå¢SßûÈà¦iÓØÒê¼WßaùP]{Ü›2D"¿˜7žžÒr·êýÏÕæÍã`mIkpž 0ÃrÖ¡ãg/]-¯~øußÖs¤[o°1™�²MXöL>§S'â ËuX±�Ü×¹Á= Dßü^ˆž2Ç"åÃP`Š.‰=MÏ0*´­-!¼P…Q¡As—_;*m|zÁØÛ6YîÛY1µÇkI~é‚p6-uüz{9(¢E„ŒÆÈ7òj6í�í?v_»È«%zhÿ¿æ•/â~Ò8>ç~�§öüèwÆ7Nû­¹öªy+<‹êœEöá•% ?Ô^+¡A¶>Ö =\Ç=c¥}ë$©Oé@€U> Òa�/¼~ëÎ?µò_zƒæ­}™=ç-  …G¦ ¹¡Ãj0üŒ¯¿C*“½¾€Ôù¶ÊåçÏbÁø*‘ø|“ëB*!°-lb?có +èo´Ü‡ªv€„Çù[¶ï–Û˜êGahxɧºõè?Ü%­ûªY¦àÚ<ä¬�/½6ìÒÞºg¥|ŽšùðOv>¼o'Š#ð\`ù»“�üÿé"½*†à-ó¾C‡wþÇû7©íû¢«Ú®¬¼—Þ”A8Gœ=�¯ Þzƒ/Z‡ôëÞí£WƒHR¾:yTFSl£ã†e+l‡UVùïFS¯qKd P@Èæ¯ÐsöË„ ±˜‚ ЫsÛf]wùºö ’(:˜¹ È÷[ÿ‚ÏÄ,GOèM’5\h"E-˜>¥þÜ£7HCŒQ=µ³t©\K—±å¢¿®¼ÅוúºóÃI½9ÁÔõXä�¥„¹¢²“…¸Úø¹CÓX¥~–²†}à¯ï@ñå»uÿ¿©Oüc†n¸w,úÊû†6¯õ{âöª;¦©�J1e åUnÀ6:R7“uˆvXŽ¢÷ÿ�»ÁÛ†îÿxgJ éè‹‚OâRÒam…ëÌ¥«ß±«ÍÌ €¼)+}»Ô¹¦ ô!Ínùµ�Û{7¯+Eç‡xÁ{¸ÕüR¶Z�jO—$œ2É‘$–Õv-ïÆÇŠŠ0«gû– �6½¼Ž?\Vêïh„éÑSç K\ßù"�¼sv?¹˜·`A ~_˜g·#|ºŸÎ÷d$›”¶«!€øî¿úO«ñ~áçè±òÿqc)úÆ-kþéCÝê×ñí>ÄŽâÔc¥œÜȃ'ŠÜjæšMÚɺÆ\ Ó¾Ù«õi�¯d+l Ï^_ÑÃ>¯¶•âP÷A˜Æ#^f艔ùä OA²þ�§F/W—».çØÁ½Ž¬U°èݬEcÿV}q·> òQtEXtcommentFile source: https://commons.wikimedia.org/wiki/File:Usm-unsharp-mask.png™MÏ3%tEXtdate:create2016-12-11T00:37:33+00:00ôÌ,%tEXtdate:modify2016-12-11T00:37:33+00:00…‘º�MtEXtsoftwareImageMagick 6.8.9-9 Q16 x86_64 2016-12-02 http://www.imagemagick.org—&„tEXtThumb::Document::Pages1§ÿ»/tEXtThumb::Image::Height2480ótEXtThumb::Image::Width3508e- mtEXtThumb::Mimetypeimage/png?²VNtEXtThumb::MTime1481416653:ªÓtEXtThumb::Size1.71MBBzpGvIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/update_stitching_preview.svg0000644000175000017500000004136414757047403026101 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/url.png0000644000175000017500000000053214757047403021561 0ustar00paynopayno‰PNG  IHDR(»egsBITÛáOà pHYsÃÃÇo¨dtEXtSoftwarewww.inkscape.org›î<ØIDATX…í™Áà D‹Óÿÿez ‡d -êb€ö�Œ°aÅhˆ™™ùQ""¢~¼íOå^þ‚«SP°¶z…‚‚5¤=ÿ�`áÙi–ÝÀFç±<¿žÛ…àh|^“£œ,�š›"6®i £¾ÆFÍŒâ7�¥{V �F0Êe ¶%ìñæ-8f»²KµÇýRáJíJH`i,Aû]KìG‹Ù®ü⪮׮„p–ö¾T¾ËÌs, Î%U˜Aê\ª`:0&Z»L§¥=õÜó$\—ö¦­¼×Œÿ¥^2]œPç­(IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/url.svg0000644000175000017500000000356514757047403021605 0ustar00paynopayno url ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/vignettes.png0000644000175000017500000000144114757047403022767 0ustar00paynopayno‰PNG  IHDRUU8õ¨ZsBIT|dˆ pHYs??•ˆlÆtEXtSoftwarewww.inkscape.org›î<žIDATxœíÛ¿kqÆñçsWÁŸQ£"¤dR—Ž.."øt­pqq°þ \]¤‹Áä°‚‚»¿&Á±“ ŽYLAѨƒ$÷q°ÑkÂõ¢ä¹+õyM=.%oø’®€ˆˆˆü_,}Ñl6gÃ0IÔµ(ŠŽÐ�h·Û¯œÊº¯ãO ¨ŠJ ¨ŠJ ¨ŠJ ¨ŠJ ¨ŠJ ¨ŠJ ¨ŠJ ¨ŠJ ¨ŠJ ¨ŠJ ¨ŠJ ¨ŠJ�û„Š»/ÆqÜ+bLê=�ù~Ó6ɳT·Ü�>än·Û[nœŽ?�¢Œw_°»„-™ÌìMÙDDD¶�Ÿ³‰_Ü5¦&IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/vignettes.svg0000644000175000017500000000626414757047403023012 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/visible.png0000644000175000017500000000064314757047403022417 0ustar00paynopayno‰PNG  IHDR �Õ¶:sBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î< IDAT(‘uÒ=+†aÆñ߃ò^”ˆD’’H=ß@ù‹ R’—2(ŠÍ&F%Éb3( %y˂͠$ @”2Ü×ÃÝåqŒÿóå:Ϋ##¿Ê0„TãŸøÂ6ñöÏì� 1‹ Œ¡*ªWbg˜GÑ‹špˆVŠIl`%�g0�c´Æ‹:q…î+Áup¹ˆ;œFnÚCýg® 7h‰ÁCÊM^0õÕIÎÎÂ3zòœ½Šµˆí`)Oo/ž„EçhˆFÏ©÷�§Õ,9µ3r ÛRMå¸Å:ú±…GITrÊJþµ#¶Ú†I$2�5b{XF}à…˜Ã~ŠýQp$ lYT¯Á.1í7B¤ĪÅ0úÂ@±$s¯ØÅ6>â¡oœ 2ë¤Ü‡^IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/visible.svg0000644000175000017500000001761014757047403022434 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/warning.png0000644000175000017500000001342114757047403022425 0ustar00paynopayno‰PNG  IHDR2.j+JQÄzTXtRaw profile type exifxÚmP[!ü÷=‚0èâqÜG“Þ Ç/*nvÛN∠�p¼_Ïðh`’ iÑ\rŽ)R¸Z q v¦(�;À®Ñ=øp�-…V9žš½~æé4Wµ(]Œtsa½ EÜ_¿Œ¼#´ŽZ¼»QÙΖ»@nPÇX1]®#¬s‚ '4½·ýó^l{{²À|€�   ¨M0f¨Äb@�ÈÍl!ÿö4>(­YI°°$(„iCCPICC profilexœ}‘=HÃ@Å_SE)-í Ò!Hu²‹Š8Ö*¡B¨Zu0¹ô š´$).Ž‚kÁÁ�Ūƒ‹³®®‚ øâìà¤è"%þ/)´ˆñà¸ïî=îÞB«Ê4³/hºedRI1—_^@!Œ",3³>'Iixޝ{øøzçYÞçþ!µ`2À''Xݰˆ7ˆg6­:ç}â+Ë*ñ9ñ„A$~äºâòç’ÃÏŒÙÌüÏÀ•Þõ×ZÀì'éÍ®;†¶�‹ë®¦ì—;ÀðS]6dGòÓŠEàýŒ¾)„o�ÀšÛ[g§@–ºJ߇Àx‰²×=Þ=ØÛÛ¿g:ýý¡ãr¹]a'¯ xiTXtXML:com.adobe.xmp C#JÍbKGDÿÿÿ ½§“ pHYs  šœtIMEè  &5û �ºIDAThÞí˜{PÔ×€¿ +(J¡‚šVDä‘T$ø.„šJ3"iÊR‡(°0A1¢z\7mxû.¬xùŸ¸¸ˆ°°0àšE„"((è§z½^¢üͱ£1ÒêŽRL«ÕŠmÛ¶]�¦ãäØ|úôiUCCCý¿F™ s­ ýð‹6Ð÷‚ƒØÙô+–Âïôðá_ççZQQ¡t_e0$ ÚöövˆËÇ�ÿz_#Â׋û•ýëóø™±¿µÊ onn™™™7Û¯$¾££C„‡‡‹Èçÿi5:Zša„iG�ýŸ½�x-±yófÑÝÝ-€7§âÈTn£ö*•*ïÖ­[\¸p�ý±0GjìüÛßGøø“B)�ähjjB«ÕRYY™,�õPØØØ]¿~]¬[·Näk£#bÊ®t¿ñø“ÙŽÈʳgÏ&455ÑÑÑÁ+?4qŠ˜˜ÙÓe´n[0¬õ„ºº:RRR"ÿY‘ÉdE^^^ÒÝ»wS“KLÔgS:Spv H„¬¬,œœœˆ��=1[ /¦¦¦>W^^Îw×@h€i£ùs̓ô…ðgáØ±c$$$¬vÎ4ˆMzzúQ‰DBaa!‡aÞ\Ó†¦ôóǰ�#…Ì88wîwîÜA©T*»™I’ËåO( ’^?Ÿ± ~Í<¸Yódí€ììld2Ù" g¦@—””äôôôpñâE’#Lçüý‰3îsE)ÚÚÚhiiáüùóIÀ“Ó²aÆ·ìØ±ƒâ7ÀcÙ—Û;Ú›Xlœ Ñ7Á™C‡���uHHHÁtƒ¬ËÉɉmhhÀiþ?ˆ 1ãgÖÒñá¾(aÏ‚¿7TUU‘‘‘ñÏO \-]lülþ¸ï¬�ø0P*•DGG Hœ*ˆmvvvþ½{÷(--%kXÏ1ß¡eKŒ¿½ÜÌ'µ‚W£@­VÓÛÛËñãÇNSy!æétº;wîä G^�ØY=ø/¨z†?ƒ˜ïƒ“ÃÄÆ­†5¬àÒ¥Klݺõ”N§‹Ÿ ˆÛ™3g>BØÆÄÄðçw`Ùã³{1½s<~áêêŠL&[ h'”ZAAAGÖ¯_oCeÖìC8:@åAØ·onnnlß¾ýÄDŸºåååùjµšß6<_m¬'îÈ„²:¸ò>̳ç%ŸcÅRèÔÃ�>)»víZ^QQqè6'µ$IIIZ¹\îíëëË»' ÈoâèzaÕKŸ×iªÀ爫ÏÕ~ |_†ææf?R(^À'ã¥V|ll¬·J¥"úyøÞ†É¥Å»šÑºK¿™Ü\ßö†×# 33“¨¨¨å@Êx{Ä¡   ¯¯¯�ÚÚZR_©tr‹[™HÚ¹Ö“ß/É‘†ˆtvvRUU•8� ²`Á‚Ü���… /žò˜üÂ!›FWò±Þ.æÈòo@Y&DFFâççg˜?Öñª­­Õö÷÷[íÝ»‡¾Ë°dáÔN�ÿ—5ð駆ÇÓ“®S›ïîÇ¡Q¹øúú¼ hù"H¡^¯ß·råJÎ+ oiK”Æ÷`K2tuu_¯Ñh¶òàeL"‘Ø N-\û“e‚Œ|RÄÝÝÝ^£ÑŒJ­°+W®Ôß¼y“žž,YÜÝÝñööfãÆ�{�Su$³¬¬l¿½½½�%ƒ ¥¥¥ dŒw×’bÙ2üÿ�~�ÄbåéxÏFïJôIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/icons/warning.svg0000644000175000017500000000266614757047403022451 0ustar00paynopayno ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9811025 tomwer-1.6.17/src/tomwer/resources/gui/illustrations/0000755000175000017500000000000015153325403022040 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/resources/gui/illustrations/3D_coordinate_system.png0000644000175000017500000013756115143647637026663 0ustar00paynopayno‰PNG  IHDRùô>(T:ÇzTXtRaw profile type exifxÚmP[à ûç;yá8t¥Òn°ãÏ@*µÕ,›LHèßÏ^L4Ë5çhÕÊ ÂâB›‘¢Î8qTWtχC]2XÀ² –Ó™÷ 'SƒJ#{{a»ª.f{ùC2:bˆÝ�ª ¯¹A[ߊ¹Z¹~aëñ[+ŒðîÓ;’¿öÜkÁôö„¤0wAQDW2V Ò "‰á`ƒNà6Žx'È¿9�?ê±ZJðºOå„iCCPICC profilexœ}‘=HÃ@Å_[µ"A;ˆ8d¨ƒ]TıV¡B­ÐªƒÉ¥_Ф!Iqq\ ~,V\œuupÁwÁIÑEJü_RhãÁq?ÞÝ{ܽüõ2SÍŽ j–‘JÄ…LvU¾"ˆ~tac3õ9QLÂs|ÝÃÇ×»(Ïò>÷çèUr&|qŒé†E¼A<³iéœ÷‰Ã¬()ÄçÄ]�ø‘ë²Ëoœ ûyfØH§æ‰ÃÄB¡�å6fEC%ž&Ž(ªFùþŒË ç-Îj¹Êš÷ä/ å´•e®ÓF‹X‚2ª(¡ QZ5RL¤h?îárü"¹dr•Àȱ€ THŽü~wkæ§&ݤPè|±í� ¸ 4j¶ý}lÛ� ð \i-¥Ì~’^ki‘# o¸¸niòp¹ >é’!9R€¦?ŸÞÏ蛲ÀÀ-гæöÖÜÇé�¦®’7ÀÁ!0Z ìu�ww·÷öï™f?²ôrÀrÓÁt[iTXtXML:com.adobe.xmp |°ªÏbKGDÿÿÿ ½§“ pHYsÃÃÇo¨dtIMEé2Fˆ_P IDATxÚìÝy˜Wy÷ýï}ªº{vi¤ÑnÙ²¼�ð†Äb–hpX�`HXâÛÁ€y €�,SÖ H¿bb'„%!„é$$Ø`òÐC°08HÆ›ö}öÑlÝ]uîç�ª‘ÆÂ›vµúþ\W_3ÍÒ®îS¿sŸ:çcj�ü•ã·®%R)NQ±ÃbÌ™-´C`Ì™ïz—z^(xXÛ÷ƒî"*Šb1oÌÍÙ!0æ ¢QäTP¹µ—°´—”ñW±n�öl"ýcŒ…¼1¦zDDôd5zGéÖÆ½¬Š‘¶Y}/+š#"ËxcŒ1¦ª y�©àoË�Jo/�Òü |ük�Ü�+‘¦µô©uò�±JÞS-DP:¹Á£ÐÕ‰ÞÅç ò|àÀñg¯_€ÐŽ 6ùÎ ycLµ”ò"@oOöY±SƸëœèW<¢1úËçýð¶»îÖ2<ñöõgAýÕÂí[„záÝvx�±�7ÆœJÝ ‰ ž.ñoxµOHÔáQ<±«èú;oPV=ù j:àöFeÞ÷•ëx‚¡}cŒ…¼1æDÑnI7½ËêúƒÃñÅ¡àC:ÀÓÝ­Ùþ8�é%pÝ‹à5[`ä…Ž¿|«ã˯Š@£hcªƒÍ®7Æ<¦2ìùÿáÓcÙ­l¦!»±�1òƘªöm¸“ôaŒ©R6\oŒ1ÆXÈcŒ1ÆBÞcŒ1òÆcŒ±�7ÆcŒ…¼1Æc,ä�1Æ ycŒ1ÆXÈcŒ1ÆBÞcŒ1òÆcŒ±�7ÆcŒ…¼1Æc!oŒ1Æ ycŒ1ÆXÈcŒ1ÆBÞcŒ1òÆcŒ±�7Æc,ä�1Æc!oŒ1Æ ycŒ1ÆXÈcŽÊJ±c`Œ…¼1挴Yíc!oŒ1Æ ycŒ1ÆXÈcŒ1ÆBÞcŒ1òÆcŒ±�7Æc,ä�1Æc!oŒ1Æ ycŒ1ÆXÈcŒ1ÆBÞcŒ1òÆcŒ…¼1Æc,ä�1Æc!oŒ1Æ ycŒ1ÆXÈcŒ1ÆBÞcŒ±�7ÆcŒ…¼1Æc,ä�1Æc!oŒ1Æ ycŒ1ÆXÈcŒ1òÆcŒ±�7ÆcŒ…¼1Æc,ä�1Æc!oŒ1Æ ycL•‘YeÖc,ä�1gPШ½1òƘ3Gð§À¼,àÕ‰1òƘê­Ügó€n.°€7ÆBÞsfh>œ� Ñc!oŒ9c´\ü=P±CbŒ…¼1¦:>Dÿ)àY\Å—øŒ¬²Ãc̱ ícN‘™Yó­YÀ?“gòÞ#¯¦bU¼1VÉcª½’/\ÅÓù ï“WQ'—"vxŒ±�7Æ<©•§Û¶™!ú<ði`óO|@®¦N.˾ÃÎMÆXÈcžÜæÓq Z|x!ó%>,/¤Ažaç&cŽ/»&oŒ9YÕûìóÎ{€—³Œ/ò!YGƒ<ó°ï¶�7Æ*ycL• €wof)En‘_£Qž÷]»&oŒ…¼1¦ÊÎ7׿Ïîày&M²ÖÎMÆXÈcªÏáw‘»¸™F¾Á-rͲî ~ÒÎMÆXÈcªÄ�Àû©ç{ü�\H‹¼èIº6\oŒ…¼1¦ Î1on¦�õ|VÚ˜#/¶s“1òƘê#‡=^¼¸‡Û¤…¹ò’§ø[ìÜdŒ…¼1æ44³]ík�÷òEQæË+ŽàwØp½1òƘӴšqðÿË%¦M^yd¿AìÜdŒ…¼1æ4 õÙ³è¯"Ý�þ>¾ %ÚäÕvn2ÆBÞSý®>lá³2ÊyÍQvl¸Þ ycÌiä2àV`3+ûY"¿w cvn2ÆBÞsŠ>D%ðY`�¿•Ý,;†€·s“1òÆ˜ÓÆÀm€òiÙÂ2¹ö8t!ìÜdŒ…¼1æ»ø[@ù”üŒ•òû<úŽsGË®Éc!oŒ9Éf†è8ø; ä“òsΓ?8Noç&c¬!cN¡•À—��OÈÝœ/×Ç€·ázc,ä�1§Hð@ž�Ëi—ëNÀ’7®7ÆBÞs’Í>4ñQù.«äÍ'dM» ì`c!oŒ9Yæ‘΢oçÃò.—r'°;!vÈ�±�7GR¥Ç¡ë§rØç�÷ñðÏí\;ï€&Ò­jÛé‘ïpå x€F;øÆ«ÐAÍYü°Ølö{��À� ü&oá;¼Ôuâh:éÏ"g/„1òæ(øc¨”%Á²ô‘ÎŒæ"œ¬^è�´� @¼]™ú Ž(ûå‘@ùJ{çf=‡Ö¬rÔ¬Êß ‘^8|nÀî¬ðxUÞc ûÛ(ÁS|q³�=ÀosßáeîU8šOɳÉY%üOø?ï®ÉÚÒ51—ßoGÅBÞœy•ü :iNGrYr4e£k�k³Ñ€d }”~¡P<ìÄó}�ÿœœ¬&]Ÿ=7 ¡$;AÍÿðp6"0LºR`øqÂËþɽx5×òM^î:OYÀƒíyw|Ã=þ�tŽÍ^àUÀ/íÈXÈ«äOD'`Öh¤—æ",®Äq ð±‡:啉~›TöÊý¢ü§À#+Iç4�NË“^ëáÐ¥€ÍYõ¿'ûØŒeßg�|8à]À[yßæ•®“€ÖSúÌl¸þx|øÒQ3~B:b�ŽŠ yc•üIÏžf›!<7]KÕ ,F¸ø5à](ï…ò6e|RéŸR¶ÆðPƒòO‹€‹�9¤+˜ÎýÀƒÙHÀvà‘ìóaÒyã�wðøÕKU;BIDä€7oåwù]î·NyÀ§•¼ ×{õ>øSàú¬\!Ýšøì¬l!o!o¬’?�;¹‹ÓG#Bk6ðôìßß›]¨ìI;Ó£04¡ì@Ù%ÊÝgÁ�.%�$XÈjÇ©¬Ò$½$°#ë d�‚!Ò‰�¤—ªZD$À€?áU|�׸0ßÎNUðX ü9Ð9ëhN’^ÞÚgo!o,䫽0ë²@B °0›ð{³F*0}@= ì/+{ò°u‰rÇ XFºÉªd•Ð(éÐÿ¾ìãnÒ%‚ÛI— Že€dV•ø„@y‚;ѯöWE² þO¹†ûy“{! O›—Ï*ù£ ø8 øðÛÙy^³~ðmÒù,òòæÌ¤6íWG€„yÙ¾3ÞQ¿âa(�)c`hZéwÊîEÊ�Î…ïÏ'½$PÈN¤CÙÉt8ûø0‡. ̬ø•'òD/Øñü?v8zÒ ¿ø^Æ/¸Î­!dÑiõÒØÄ»# wÉÞƒç“.�|IvKYçsP¾ŒÇ\nç yc•|Íwr³— ¦s–ÍJä×þøA¨ìQÆÇ`¢¤ …°s±òÐ2eý `ÇÜl4 !îßÅ£w ÜJ:ëy_vB>a[{›EEv\~{VÿEà€,à�…¼±�?s©²÷cy}åÏ'×úˆ?�ó©'Ь>‹Ï;<±ˆ“£z¸¦ô‘[>s÷@&ð൤«*{Ó]+ƒÊäfý‘28¡l­(ÿšÀæôþÃé¥�eÙH@K\žt^@> ´ûI— îâÐM…fî$×BeŸUð—“Þ)ð•¤3<éíc?܇ÝYÑXÈ›” ן‘ ÏÀ§^t÷Ô3ƒ?ã-z M’Ÿù·Õ$@$V­àÕ©¸÷&pMP8?]ÝEÖXšužün ~ â¡ô‚•aez; );Æ•‡å+­0öª,Ì.–g�€BöGFI7%�°;ûïYg`7éT'`öæA<Îו“~?�' ø€t’Ý[€.ÍVØ |øEÌåÓÖŒ…¼™©äíœqoMxÁ�ÒÎGõ&ßN‹fÿk'ù8Á#„8 T‚S7®+!óÒGáüC‰»aUö=o­À„€»d;”~¦Lï„¡’²Ã)w—•¯¶�^X•õÚàà2¿éAÛ³Ðß<”}­ŸtKáÙÁ(‡}~º|8øàM³~ø*éŽvSöþ7òfvÈ[%Fþl̯9—÷ë{åbæIÃáßQFHE!’ˆ§÷ ·ä²¼¾ }ÌÌXŒÐ¼èÎn%ïNç”Q *ûÆ”-uÊÝ|§‰t³˜gg# Ùy¯Ì¡Û §»¦7pÙÏ¡û ½ëàSzÂÇ»c�Uðg‘N°{‡¶zI7¼ÙeÝ yc!ÆûJLÇ—XÀÍü±<‡…ò˜ÖLá“\öªW@å„ן´Ž@~ö̓ ¡álÒ�»Ho%œ ¤�ÒezÆJÊ®²ò€WÍçphN@óÁC–Žì"Ý:x?éðø¶l$`”t^ÀÔãŒÀ“_x*ççKH—Ê岯þ¸�t¢�-•3òæpvMþÌ0qgÌk>C+oçÃò\–ÊãîH7ØÀC A‹ÃÏ©àUkfÓXi†°ÂsÓû´ ÎÖ×g�xW:Q°´[RöOÁî¼²5T¾±v=�tÅ@! ÜÉ,èI‡þ·e‚½Y§`4ëLrl×ÇÞ—u>4ëhü ðY`“¼±�7òg¬É»b®ýKêwßÈåj–Kó}÷ýsõþ2n‰‡9Šj Êvgur§Ù�®ÎâÐ]ßZ…d0íLMÀø´²/V¶l^¦|ýB˜XBºDpæîCY0ï%�0óq é �Ét`…Ð dîܹ®P(à÷ïÖyFö{î¾þଂ7òæ‰Øp}u›únÌ;?ÜȇäEœ'-OZó“Ãã5qŸö×äO«N@¤ \ä.ÒÕ¹¤—ú>03?`J”`¬¢ô‡Ê¶åʆóaý¬*³NÀH6 0l‘=ÀRïýYÓS]U߸í2Mêú“¤þM•JóvpÃÊ–Ñ„WzûÀi3aÐXÈ›Sªb'‚ªUúqLÏáGoã£òÚŸ<àgB AQÍ:œÅÁqíf•âK ¸_îbj|{%_·Iƒp3ÎmRç&ÂðºK„¦…ðˆS~P[H7*‘ûo'�°�t>ÀÒ zýÀ�½_€±�7òæôQùE­ïQþñõ¼W®æYÒz$?í$ñŽzç™{œ^¼Ï19±27=µœ|¡Ÿ0? BÂÔÄEg4ž=ë;Ç¡<ÓªŒÏ�á‹”ÁË”þ<(ß Ò¼g&�ð]Ò[Ъ…½…¼±�7§•ø¡„/½KùÜ«¹I®a­´"G¶—{Ζ‰}ˆ“)‰ý™±„öñ>ÏôÔR˜Zzðk‡uÙš ® ê²ÝÏ:ì;nŽ!�’*NÙ‘óüÁ«³Àÿ';ÆòæÌ ;ÕóZmKøê;”[:¸žßä7¤9ò›°>«_ž_O¼Âã5§"ŠvlOï°?†Ÿ !×¹6¡ aî=>�ɉUñò¦6‚ÃzUHvz¾~£òáµ¼‘7q�›�;ºõísb�£N¼Wµáúšb/µ…¼©­o!_¿Ïóí·yþìJºx=¯v­w=;š†.x4ÀQA«ä-äMM°¶Vɛӎöüð&Ï{Vq oáwd!…cÿ½‚"Ôç5§ˆØq®�7” ySSl�üi|>ñüè­ž·�Ç y ×J+y©?.c¨z­à©™mm�òò¦æ”­ÕŸž'ãqϽÿÇó–<—?äe.u¿zG¹£+å!ˆñ*j﬒7òæŒ5i!úü´²é�<¿?—+¹�›¤•†Ç¿áÌ‘*èž)$VT³ÉùÖö­”7òæÌ4m�þô:—”_¾+áw \ÌM¼[æÐüÄ7œ9R÷ÏÓÿ á!BDœUòòÆBÞX%oN¸XÙüþ„×z–óN> -´ÉvµOÍ€Ô»„@gfÛ©Ø5ùÊx®·�7µeÄBþôà•íQÂ+÷2Ÿ›è‘Ú¤íÄü©’@Ò½ëU±¶o•¼±�7g¦1kø§Á‰WÙóç ×l¦ÀûùˆÌc±,:a ]4qàm�¼…¼±�7Öð͉ ø½OxñO�÷ð iãlY|b‡ DJ¨wÀ4‰kûÖÖ�…¼9£ÙuºSvÆøt‹~ ¼Ÿ¿”…œ/KNôßlÆ;¤Œb«ä­­ ysfG�5üSbèo^Ðü1”e\"ËNÆ_]5\Y€E*HN±¶o…¼±�7ÖòÍq5öå˜uÿ¼ŸÈBÖœØ!úÙNs6*ó4l3«ä�…¼±†oŽ›ŘçÿðÞ%Kx®,ãØî'zDr$3K4}é-ä­­ yc•¼9v_�yÓ€?æFðYt4÷„?bmß ySS;'ÃÔwbþð“ðÈû¸–³y©[Œœ·x¶áúêÏ[%o!oj°á[%ÂM/æ½�ûÞÊë8‹Wº6ùÓ¤Ggm¿†»‚ÚÚ!¨YÖ»?¡J?Iøð‡á{ÿ‡Wp¯só ¨?UÏ&ÊVÉ[È«ä�5|sÌÊ÷%|òýÊ×ò2.åZ7��¦SùŒ¾¶˜o*áCª¨°Àq'ý™SÞÔ­Co!o¬’7ÇGec­ïQ¾ôûü:Ïæ:™CŽæSý¬Êâb²Q{e¾¼uèM�°ázkøæ¸‰NøÂÍÊçÞÈU¬å­R /­§ß ß`!omÝXÈ«äÍS—lOø×?R>õZ.gï’€úuG¹c}á-ä-äM­°áúÚm÷òÇ/à÷z¾ù壿Åtð~�ÆwG¹c?ã×YÈ[[7òÆz÷æ)ÔÅû=ßz›ç/c)WÓ-žYzº=ËÞ%$*þÔ¬â3ÆXÈ›“™NvŽù{~øvÏ{_H3WóQ)3OÎ>Ÿéåc\˜C@ ÈÛò9këÆBÞXÃ7�Ox6¼ÃóÖK(ð"n‘IÊy§ë³]>´‡È �äm¸¾¶Þ«6jg!oj°á[Èý±›ðüì&Ï›wp‹Œ³T.9½Ÿs¢¥À ”m¸¾æÞ°v,ä�5|ó”MÿØó{›€—s“\Î ¹´ ºŠ(JÅÕÔëÐ[ÈkøæÌ wÏ¡pê7ºyj =ÀyTBrÖî­Co,ä�5|ó8üJÜŸæ¦ðI_t!´v_[MÝÚº…¼±JÞE%_5^Ôအ�ô­­ ys†÷î­á�vS%q?0_¿ç‘�B›]_c�Ý��¬Œ5|óÔ ùªk7› ŒL#céÖîk«©[[·�75È*ùãSÉWEU¬š#DÄ�8 yëЛšaki¬á›é{*êA›xgmÝØÉÊœñíÞ*ùšj7‰ ȉg×äk«­[ÈÛÉÊÔ ù£&‡B²Jâ2‡÷BN„À6ñ¶n,ä�5|óªî/m%æÅL;‡R«äk­”·CP»¬Ko ßE)_mOxõ`ðkõ$g%¢äÔ&ÞÕXS·¶n•¼©Á†o•üÑg|Õ­“‡„8P ¦Åî4kzc•¼9ÓYÈ×P縀8IPp¨Úp½uè��¬ŒõîÍ“·›*Y'£êQUDr�³Î½5tc!o¬’7gJ»qˆˆ Š×8 ì¼omÝØÉÊœáý{;ѵê»&_ÂyQ!ñ¶NÞÚº±�7Ö»7�ŸòÕö„÷ÍI6”Ð!�*ò5–òv,ä�5|óÔUÝôôŸ5²Cp{ÓûÉ;k÷µÕÔ­Co!oj°á'v ŽºÕ¸\ ΈTÉÄ»„ú0 xņë­Co,ä�5|óx¼¸ÊT‹†¤j¢LÅ9Bç©Â[åšcjêÖÖ-äM-F•‚£s•–OÈØo­ &—U2tïõˆ P±kòÖ¡75ÃÖËÖn»·�?Jsˆ[êÊòžy¢Úòûª£G'ST’ù@ÉúöÖ¡7VÉëÍöé2 IDATÝ›ÇVAp¨+h!Lªd¢ý¹^Ãzñ¡â­Ù×ZS·¶n!o¬wožªKÀ�R) Z)¿|oî%¢¬ô!¶y½uè�…¼±Þ½yL„Sý ÿw«øŸ–ÓÕðœ[´h@^qHž¤Õ^ÅšjëÖ¡·�75ÈBþèI$¬šÍBRO>Èy‡Z³¯¹”·C`!o,äÍS¯äe ¯‰TÏ�j† l©P™Lœ§"aÅ^ÅšÊxkëòƾ9‚ޑˆê¡Jr~w¿L�þУÍ�Ø«hŒ…¼9ÃSÞÁц¼ v­’R>„ˆ‘²5{ëЛša³ë­á›#Wáýäc D’xPÛñÎ:ôÆ*yc ßWÇw4ðÐ_X…¤çq×ÑA˜fƒJo/½�ëׇ¬_Ò«9´3ˆ§�Jäè%@;B)N=B"QäP$Í�™ïMsGIæ¸ ºE½€¢é©_“nÕDPFWo{eº;-‘"‘…†õîk¯’¯’SÒTÀDiÉ£¡ ××–µºåº­‰ ]‘ç5 Ç×䊲÷œ¢ný!° ØUÀoÝEn_3uýý+§‡»º{þ¢Þó1)u{¡¸I;¹•"Å´ü£[T´ËEQgÀ� ¼®Óz„¨éV�zÒ–¡‘$鳈Ð(--D#¡Ø.*�Ú“þÆô )6Oè„…¼¨(@o¥:Aˆ@¥‡…ˆNA» g•F]›´½W¤D¢H ;kT!kPÇòaU½å]› XæEÄÆqjG?šhú¸AÕ-L� FÑçI¶­Ó¸ uT*9��¿YF7¬{ͰÇm�íc¼vÇbüör#ÛV纰!šx¶�¦úöPŽE7zXèd=Ðß®lJ#»³Yµ ¡—ôkt#ÝY ‰¨lн!ˆ¸]µèÀ‹fw‚±wçñyèuЩ]]ÙŽ�Q$´ozÛé,BÇ‚¢tE�z{….¸�ÕJïF¡«›.°¯¾˜²�?•|•’ A"THl¸¾¦Ô!Ó±§R§H^¼$ 1”U\I�†“èñÔ¡Ô{¤¾Œ<’/áëÑ\,‰b$ˆÅ»ŠÂ´âTp  £ÊRä €fÆ}Ñ_îrúÛ·0Õy‹n+‹î|$dûT…‡êÙ½'ÇÞr�=ùg1¨ç3Ö÷·$ë:n¸>†A";_KÈóU¾>ÙÄyä¤IP'0™žT% åqб'Ä\�ßU¾¨ü»Ó[ii׎M›(Ò©]ë× SõãÛ” ×+wÞž¤ó."ÙÈFéYE�v)Šô ²±ˆ ÙØ�€¨ Ùä ºÓ€ šÎÆL§b¦¡°(Y'ÀÞ ò'¡’ªm �8D<ªÞ¦ÐÔ”BEU%AUEc—Ìî­*écâЙTQE‚@ÒVy…é@½×¼‡†ò1Rðêê<’�!¬¨JŒJueTbDb�2ê²Yõ9Ч¡<­µ1�L&‰>¨ø’g¢ò¦[|¾麺­?àÆÏüWÇ ÿÙÞש�ŠÍ$9¦�o`¿&áE„Þ‰W´(�\Zg‹@Yu>½pŸ  Õ»òÜàÓ|}×.’�Í}åp×÷|q+óy$7Ì~×ÈX)·}”×¶MÑ9PŠ6F ]oÜH´)"¥'ûxð…Up´#lB�}~%›õŸ~7¤ã�úhž´5ÇòU—9Å•('-é*% ù"GÙ¡AIHD‰*8&ò¸' Ϋ$š„êq‰£>|B.Qêb\c ùò+hè‘0œ*RÂ%@¤¬*!4/ô®y!å6/åK ÊUË÷pi±³¸¯Ë^Æc ùúöׄºéYþ�ÞÉÕäý2*xÅ 'Ip¤/lârB¹’È¡â—2¤‹KkpàC<{ð•< õ2åÆÇ÷éðø°†lå<·•ÑÏœ¾õ ì /+è# �¯�ÆV¯[�lˆ6øN:¥HÑK°6ÖöA__ЉïmÇ-èC¾‰/F½Ò)›4­ñ»U@‰zìäõÔcÊzÅÇò¡;x­õS,ÏáæJÙB¾æÞ­G«äÒvék‚$ýoãÓAU�@E� q¹Y5„àEPð�K Ÿx­‹•º RçÑúê+HÞ« Å%� Þ;O “’¸AuMñ°¯_UŒ´hK´�-ä;?»éÀ�ÅèÛë6¶¯gëõKšýÈoL ×'ŽKРž$IœÃyAP*• u’£¢ž  ’âôʺ–qš  !.˜ã�oÅNŸÍ¤W @'H¦�aœƒ4èÀ†ÿÝ0Œ/l)–ÿu'1ÛÂFvÄùhÛœ LåG¨D3¼:aA³²q�À&¥s£P\¥ DQz²µ:Þ*ù“sÚ¬®ëÚMeYœÃµ JEĶBª­Jþ¨_í‚d»¢&éPÿL§6—�B< nfëTŸÿ»ô{⬅ø$˜¦QBÒ ÿˆ„8Ÿ¯”8g»U‚w’è˜'$ÿ‰^ñÉíܾÇ^Äc ùÖ›qëzû´Wº:»v~ëf>ûÇøBîõ¬JH^çËò*ï‚eäâPBʼn$^µÄƒMuú©ñ8w^âXŒg1“œER™#�6h>κ<ˆCEHTµ¬ "šC¥Ž �r>¢ž\)'‚�ÄbBüèÅŒ¡²‡i·ÿ³íÔéÃÁÛý®ú÷ °¿áóÅÑ\‰‰ÞV¦6 {I­’?9!_]Ãõ¥ìbu>U«äk+äýQ·õ8&Á¥ó¤Ô=Öï&ÝÕƒ"Žtu ¨xÐ q x’ÍÀƒ„±ó•X Ã%.˜ñ 9þá«ÿ<ýÁÞ®VOç ÒU´×ñ˜Bþ¶5šÜžî,è:ßYTÿ JÐ×Çÿö®ë½ï}ÿÕõ‘ͽZvòF©ç9ª4© ’ÜWÞýÓ·oì{…ÞÌÍîc�k|ß_Sï< ÃÂâò× ùsâ –Æe–ãälò²t¡sÕ© 8œ€#q¨Wð8 G‚"´‘×ÅHr!B"$Îéø_™Ø@iHU'{it;yÐí§’l#‘=L$; Ùž/3xà¦V,ÅoÝM ñ½À­›�í¸Öaôu{Ðuàé†H Z¿ÞÑñ]�tëÁ9ý=ÀËo Øü-uµ;�@O„´w#�é’´¬1EÒAä:€vÐάj Ü*Ðî™%l§`2‰s¤Ó-æ�%ä«í¾húF¬ØìzëÐ Ÿå{V¡‹ÿÕÀWNQ—Ì^: àóõS�¯¨ëÌ/Lr¸Jœ[r€Ê•9|î1{ ü ðå§Íçí]›4¾ù Ö¬îõˆ]•?¦�Ä#Е¾&d+ß(º¢vñÆDQòo—þœ»öï✽ÓÁ‹ê&+ÏlmL¾õE>Š"ÖDÅ E È80ìî›N×À /_PÞ²s"Oœ«Óp´9l.-Öý\¨-¬ð°(ÀŸ¯ ­^™2— hBˆ}Ùû鈨ÓÄåÔKˆøFœ.c2YàǩÆ@BHRÞE©”£ÌõŒmE¶P–�$léj 7s¶ß‹+ óŒdäöÓ£4¯˜¢oE¼„Ò±n�vÓá:h×éL7ÚX¤3ºÁ¯�P�ˆDHøyeæ�-ôDÝQ§B'°)ÝíIz¤H·öÊÁ�Ÿ²ìÏVœ$Þ£uNµl! !_…A™ž^mv}ÍUòGòÎýêX•ºÇ}{ÍŒÛË¡$pe|Å%x¥œ÷.WAc�×mãÄÏP|a d/$ãhñŠóyçEÿtOI׈»ñÐi—�5äó�¡Å4Â"|7*ò€L·¯âὫ*<¤/Š|/íB'ÝT·*�PíÞSij€ ýŒ÷l¢?Šx$"úaDtJBQ}‘Â�ÅÌq9�W©�—Æ{XšTÜRT–Pr+p,Ö¼¶ê\DM§†Ä ¢âÕ e`’:TÁi! >Ý�?®(*nb*ØÁ˜Ä ú¡­{tÎÖmoùû< »ûšïÞÁ�ÿÙCþú!ÜÈEJÅ|q°JèÙ´é#¢¯7Rلᢺ4¢HQ# ›hæÀ(ÅÈ‘~1Û'0š•÷'OÉáŚαTòéB£ª‰KÁ¡xñĶNͽ[O¥ )�¸å¼w“„Š›–P·&$)¤Côèrgk“ÇE·­aõPèÌ®5Ø;ö„|º°úHÓmìˆ6]Ä)ÒlÚ#6­ŠâôÆ¿2H$Ep]�®Çëê£1˜â*kYë¾Ëw}{{$�½‘Ðurgº{•œÇ¦)SÈWÕÄ;šô$ç”¶’…|�…ü©�d[.x—/£yÄ•™ž;Ïp’&†TýnøÏ]4¼á�ÏûÇ÷¬ץЛN@#p‘­9†�Ÿ'ä‡ü·üjͯ°öÏ>­Q7i½�t÷€€�@£õDëAHè¹&‘hÃcVòÒ#tÏlg› eÛÙΪbµsÖh€|_%%(¼ƒ�h±ˆ+ÞŠ~wZìF;Á]¿w;«•ÍS|·oKýÉXë–ð ”(¹ïóýø^-†o�[O óÃ{F—Ä,¤>·Ô�UÎUÇr­—Rˆ/�„…� �éA„D„²OW�*h3.ž+!—¨Ãljø8@)ã#!f‚<»È³�ŸÊ¾æ¢=¶ÓŸßÆdÃN´nEŸ3‚OÚÞÿˆ•ÄÎôÇÒQª®ïö;*˜ pR±ÁÏZ{·žÚ€Lw¼¡jÛ�繟&UdÕÈ7‚v}Ó;7�ŒõÒ%kV¯WèðU¤‹§¢ÙÄe{ß]È/eJð‡ú|Hx.ëdoÔÏûß$мd+Ï#ÁG³~0ZG ë²ÿxì� ²Ê^#8lûLôèÉfrØó½·Yß“‹éï.fu8l8ôÓ?êû Œ”€‘ º9}üÁ­q+Ž;Ék@!?ÂYÉ+µ gQÏÙ¾Ž•”´ G›x!4iž�õÞ£‰’àU Zd’9 í8ŧ3TògNÙÃd½ÿz€{Ýž`Ò?,6K[+…`?ÓùÝÌ FñÉ(ÓS#×ÿˆòƒ_&èëCoãßÊjߥ]ÐWâ˜B;?†¿ùfÜ�«Ñn‰¼D}ލÃÓIÇä¿×å$®#|%ç}->ËZÀÑw•ªíŒ#B"ǤUò5VÉŸœ�/å�B‚HŒO‚t÷›Šƒ¤�P&iœˆÝU9|~aêwü`GcrÝ{¿¨ôN¡T¥Ã7è³p?æ�¿‡Ïr#¯çjºø/¾ì.ã÷t3wócÖŸùoþY�Œ¬C’v{#L£=°qfbàõ´ºÛ¯¿^GcÁ3'Hh�§ôl?¦ËX╳ñÁròn¾6ÇK‰µ™4è]Öm­àµLzqC4@ÈIàë$Âe„(ãÓ’ÒS:I"£„áÞÛŸ¡;xC„ºó†ÆgmG’}M¿`Ï8ìáeLŸ¿õ%ZdJ‹� |Çê¢D½‘°©ƒÏ­�òמõ�®¿àK‰þ"¸Ú�_þÜòÎK¿ÆÖŽÒ¬áúª8à‰ÉùRº”ÙÔLÈŸœáú¦L‡hà Q4 �HÝd¾aTÊÏRõuepý8ÀÿÀ­L^ÿ�Ï2­éñ(¡DÝØ½èŽ{ÈßË=úKúx�<Äz=ŸßÐoñg5Ý(ôà°ƒöq�@‘"·ƒïŠÑØûz¢±vD÷lìEîí$œ ölJêæÞGK¥LKÜÆ¢Òç¢n…6‹Èq•x¢ÍÍõ>AÒ­ƒEˆ‘txM´!{´‰óçÉdz{Ÿ.k‰¡<‘cBã_ß’¿ko³59nîûq°5¼4ÙÌí¸¦x肱çõ£,ÏéÂRxiqƒ½ý�ž¯²‰wÐzØ)´öÞ­'%ä+ cHpšÃCˆ#¡aŒÊ³*Ì)K↽>¼­NßøÎ›u·Šv¬�œyۻ㄄<ÀÏøWéä¯äþ\§á.>_ë&ºAèÄw,øgfDé7(’ö<ºP  ¢¨N�lìí¬/²ê¥ü êñ°ÑËêâj·ó‹òûVТÃ,VÇWÏYþ€žEEá9G– :×7Ë|9$ÝT �h’M\ôªZ@¤Ža™‡¨ú@/Ó'{Mð±â�&(L$Ûö;Þ¹¶¥rÁî«�ûêïñ¿¹½E¦ÆçO –ïžìo¨¯ZȵL§wˆ4OXÉWÝf8Ä$>¤É^¼Ú«äOÎh‘‡r¨'—Þ¹®~@Ãgä‰[cÆTtºyþ•ï¼kýN]' Š!�îC÷µIv' ä¿Í?ò|Þé_É«ùo>M­Ï»Õˆ™E�³Þrïoû¨q0!I×½§·ÄS•ŠÀ*²¹ÝíB6t=Å•ÓÐ9M±sôüüJv«�áÎÛý½½„�oP'~Ô¼œÁd¹Ê|y…(+´AÏ–�•ª,Á¹<‰@ âu*x/êE˜vž\RŸKJ�çîcÑGoáŒ!¿˜øS7ÜáêËwx“£óÈMh¨äi¬8¼¯ÇQ�Ðö-qíßJœ£xb_ ÉÇLç'GùåÙCŒÎÝÿÙr¥w//¸}­ÿ�½w°ìªë|?¿µöÞçÔyÔ³«ß�t: $Ý$’ÈC¸tÇ‹ƒ:TÍU¯â8™½Š�Q°v©3¢r…�Ç×­G® ʨiÐ �<èNHÒïw=Ïû±÷^ë7ìSÝ�HF t“óû'UuúT§÷Yk}ßßúý¾ßHÏU ®^Ë\a´MX=La"û:Ö°¸ÒïŠ]{­â¦2¢¡¶Èä¿20D�ÀCb p¨èH%1¾_ð¥n?x¡ S]- �Ÿä9ä/8Â‰á¦Øpª‚×óÚ?–£Í_Ï?þÅøâŸük1?v�;€w\üÁ¡�/ÞO¯ à0p &6{byçìËäÀÁ¥âŽìÐøé”Êkþ’oøÞßäm·œgºëEê®>ãÖÞ÷k<ôȦŽobWsŒ ]„Õ2neYǬŽá»%W ˜¦hê¨t„ÍfêÓÈá½UyùG5èÓÅÑQ¥f´K}–ÂG¯Y¾¡9zø–NéÁk³ÑûŠåQ›Òèå‰F&„£K„U½bG®,?yÜÀB,ž Ï<Úò”‚üF Ï™|ÆdCæ¶”õÖ—}n É&SŒÔ=§rÒnr¯ýŽ•…OÁŒrë¬�Q�½À’eÐáâ|º@þ¥|3×ób~�ï>’+3b�a>V½+9¸Ð=Íl÷î7°{ËRðÆ"º©+NÚ-XÎßø…håšÃÉzZâL»H©Q$l—)uÊTÁL69az4ÖÆˆ_Ãè©MÏL3rrš±Ú8Õ4´ .)Pp!%g�~„6Õ`»õ!§7?”Éw’bHKRèÓ-5X¯œçÁígY»éÌs;ÑÃ/ÎÌÚÎb·»iÄ5'ǵ^.÷Òb¹ÆÈä2…©5ìÈåø¼¯ÄÆ»¼ 7Ë�É¥$UÔÉÀ}N pà"_ì$æv‹Ngˆ¬Š×ÓÊÉö{ZïÌ>-3ïX4°0”ªýjƒ¼µL¹�óVþŽ¿>’+4WEDXFãC³ú­¿ÊUS5þ {^ŠÐTñë-Cš&$ž”0“,lШ6´±%Àú 'ˆ8Q2Í]õ"è¾è � ³jiŽf…‡·ñìÆÕ³+UìÚÁzm—h¶Êdõ…F‰¨^!lVñ!•ÔáûiVÙ}nåÙx þAÅþƒ7Ž^±C+êÒ(¶¨�49;ÒâÑ×hWNC7:v+…3×–ýÑé ¥2Ú¤2Ù 8Ú&ªž§°©†-~õŸø•U®× ÿ ‡›åO-È|b5ÀŠ€øÀ!…N­)~“ ²j¼œórÖ�èwªûæ¿�Ù+,΢³A’�sÇ0¾J ï°0|WvÌŠ^óûWòîÉV¿(Ém}ÖEÉ,µçdÁ§>ád¯�гŠqXIQ%óÎYãÔ[ Ld3£Æe8ÉÄ[¬é’8Û¦{óQ>Û9…ÅxCØ )¤–°Ú§v©µC|³B°:FÔ¨®U‰î.7×KD«ã˜¥qdm“„à-A¦ØN@¹U`+kÙ¥Šª†^>ÕùT¯ ô#G'Lè–שUÏò…M§Y{ÖšÓ÷c3í?¿Ükïï÷§'Ò¬Ríø‘j]K“M¢Ñ%�Æ›˜§”Âú+MÖvòC&ÿTý>Ö¤¨wÆX¢õ¾<_0Û2u£rΛZ ÿÚBwá“ñšÕ8V�Ï óFA.¸žãiùa\ù1'1qûoÙo*žÿ°Bú‚¾¢-ŒQ•úÞŒ{|�µÈ„ ñy¯Œ"dºái�ʼn3©Í(f�ZiJ†#¡o5�’ïÌbг‰$–È‚k¦d!b1&Ì¥ÙΜ‡ÀíòÙZ‰²†5 Ô )Ô*„«eú¾Ì™Ó„G¶S=¿Å•{A3$色�Ð:!Ò̧>„iÙŽÊ ðÆâ‰î΂ôî~¡I­²Æj±A}t‰Ë¼ªN÷+tì¹W“­Þ0’.m+ôÓéÉÔWªŠ£5J“k'— ÇûObtðJë®— ÉÉäŸy ÿÔ6¬«�§â‘P1µ¾Ùga{"NZ*œõ¦v÷š$¾‹{×m|Û�.VEc�b/³Ã.ú!Èã‰ÐŰˆè¬ú�6�yåû{ßIeò|ð{c¤ûû@舫_ðiçh8�w¨/ ¦èòqT'ùè‹ñŠªWb@™t¸™‰ IDATw8ç5V>p‘æZ“ª�'3žÄ;QœEº(F�³N¨ Ø\ôß8T¯9Ï øe'Jaú¢£BTjÑ­¸1DÖ� ž­m£ø™l}xš]ýq �qìÒ8Ò(!ëüZ…¬UDÓ|@�)…FÀxcŠÝf+Âs±à}ÚQò¡ÖˆÿP¿Ð§^êÒ­¬Q+.sxËIîß{žöU�ÒÖGÿ¥?>wJͦñU7VéøÑÉ>#c]-TÖ´8u†p<ŒÄDj® /¿f™‡•èÙŠ�n¢gÈ»/P�ä-ÄF.JÕø,¦î¸ÙÀµmùaøLÙf'EÝàÞÚÀÀ…vøŸ Ï«‚^!×�‰²8ñ”NËÉ÷ÿö!]yïʾ ºumäÔm�ÖwL:Yéu'Ç’ÞØhÛË …Ê Åɶ0üä¯T&Ÿý“‹T,âçG„Ò³N;.Ø’™ì¹ªØèyÔ-cí¯vgsïGe6÷ÛÎ ä†*vC�Æ—zǬÊÂÌ>�-2ÃO]üá ä-‚‹Z„Ò"ÍvŽz gðx !>·n>ŧ>\€ñYâ5¸Bî³Ç?úÑ-'‚®sozW¦[ÿf ~5Âû<Ü—�$¤¶Îj±I³Ø¢UYci´F{×*½Â¹Wxwú Ïl mmóh?«–”ÊuÊãuŠkD£BAøÜ@þK“µM,ƒâ"/¤lËÐÛÕ¶A넬�¾¿uk6÷þ{5„ùyTeÑ+Djòø\bQAöé#oŒÃÆ;xõ¤!F4jª°&i¶Û‡«6}ÄŠ£–Ô€�w`Ä_´�ÆSÞå–ÚÆ”À.ëŒoÿó‡‘Ï�šüÛûÛÏ}äwûI“êÒýÎÅ>hÉ2ÒV-ruk3¢Û Æx§Å›ì#]ã?Ò”~˜Òê4Ç–X«¬qêºÏ±4všÎÈñWi¿þ¼JªÓ•TFG[:6ÞvÕ±Ž*m¢Ê*…q?ì¸,™¼:ÔnœÖ‹÷L·Õ܆¸¨­†“â]_ÿØCú¦¿¸/îÅsçm°sš·Ë »è‡ ?Œ'Úa±Q‰u úHŒHŒêì{n3pÐ7ÞÁ«7 ¿­ÞŒ4Œ§®ê·ª<Ô39Q·a -=¼ƒÿªP#ñª—õ‰VðdÅ÷þÞ™Ö‰â.ÝÅô‡ùo­Wò%9˹¾r"u¸‚ “Ÿ•ú-€¢5_ h–[ÝζÕ2a£J±Y!l”1]KšF¬­”áÔ4ÅóÓ”ZeÂî8¡§T:ÙBQ}a3ÖY¼Jb“ÏuÅ®gÝ G'êÐ[buü8‡w?Êúö‡hM�üF¿Î-åe®Ú¾wTƒ]"SA�‘ÉvV¨®> Ž‚_ÿË5}Ì2U›;TmôÁ«š¯¡·¬‹‘QµÖ]FÿjÓtöýûÞÇ:ï˜!_úÂ…;x™uÃÍä‡ñ1'ªо'ˆEݽó¢r—˜ƒ/çÛB¼ÏI6ÑUѺxݪæð6ñ&B¦Î(x\€1:¬ƒ~�NÐ˯Òà­3z{³ó'ÏÝ¥dfœåìÇø�‡^ÊÝ£&LI2–EEƒÜqDòsÞŠ¢JæÜXƒµñ5V¯Š0"ØÀ$A/ Œ ëûô�H*Ð#:»“±C×°çÄNF–&Ô4FðÍ1ÔEØ®EÚBÐ £(›ˆJ¦œ®ìÂËóH4 C†ÞÝéÜÝ©,ÑÏ>�îÈXÝÒäôÖ“4Ë ú“}´_ûö ­ß8âš[Ê7=Ygl²Kq´E¡ºLqêáx:ì¸ä/'qhfsã™Ð[qN½8 ø- I_(u ²ìñç)þϱÖû·wüàÌ23 ¢":dëC�Æ“'†9£—ØÍÝ%FÞ¹ ŸyÇì¿(:Þ£’Mõ5 †ÓiÃñÍN?ß79À `1¢Þ«Êã‡Æ[/þ ýîû¾i lá Ù�óŸÚhج¨ý4ÕŒ€ÆXRãs­#"Î*x V‚ÄyòZojQÇJHÁzÀ‘¨“Ì;[ê¶{Õ’K÷=Jš)yC¨`›eŠÍ*…z@³±º2E±6¥¥µ*áú¸+ÖGYªRl :µc± �­¨ß&n%ÒW಑”^Уuÿ¤QèýI½œ76G—9ZjÒÛþ(�矡;~„N){M¹ÁÍ“«lŸlÚêX“RµFy²¦#“- G—4¬ŽËuÜD2�b†Ùõ3=¬âªý‰¥Ú»^³2F9Ì�¼çá—Ë_¯KfE¤'ª‚—ŒžZgµrÁ=ðq‚)’((VòdÉÄif;^j b#™x‡Ó g³Éž]¿š™8‹™¶ˆ·A‡´âÊ"8Rú®�j¿€éŒ>ºƒ«W·2Ý©®—ЕqÌÚviVJjdÎ@j |ÀX'd¼Ub»V¶\¯jU}¨¤(í’ÀÑ ’?jެüÑêè9jÓÇ8=}œæµ�Ð(¯‘bÀn+&ÝU»í]¥V6Yi11Ù¡²©F±Z'ª.QØÔø:é’ Ÿ­¸Ê)舳ҌœUe¬ž™ï‹©¨¬ªe•ìoÚS¼ö;W8§±"sù…`î:‹2dóC�Ɠۇó(÷}Ñ·p{„ùýˆd´CÀšdLŽoñ܇†J�Z<ÞõhæUÕäú°>ù ÞÈŠÛz÷–~}öÅ�˜2Gønþèô w�2ë2ë�zQ 5ÂK‚qèc� 6܇…TñðšÛ�[± ¹ ± ^A­ &¤£þBs—ˆÉD5#3„iêE¥eÛ8!¢`FÈÔ&™†Kôn]â Y…� YDØ/2’°Žk¬°ù:o?ßÜáz'·S>²ƒÒ±iÂ#;Ù¾>¥S݂҉Ð^„ôÂÌ2ÑÔ ^-†íX¹ Õ—âŒE­Å… ½¨ÎZ¡vïjiýÞµ±³¬Oœ¡Qi²2îypw�¬²L¿|Šž­ÿ¦Áó*ËfÏTW7Mv¨Œv´8Ú 4Ù$]"šla®!¡‹ ¢>oÌã, êK ãKŽðå–¨¬¨ø³dŸýôÍúÚ_~ö 3™W%VP…!n¹!Èã‹vbÉgNˆ%&&¾ï6ó*÷é;ª/ˆh-ñc�U2­ªߊ>€çmJâ1 *ȃü3àýôÇgî_ý¥7½(1¶XòG²ßœþ¿xÿCNÔ™¬`, ¨‡ �p8ß}-(Ä�>çb¹{(Xñ8UuŠ8 3XË€¸A;–‚N"Œ žÌ+)êúQ11"Sl‘Œ·H=‡YsdÚ‘$Z±lN#';ÖHw.³þÍŸ–µ�ÈÖËýõ³Ól_«P\cdµJ¡YDêcXWf¹Q$==Fxr‚âj…P«”ASÁt-Õv(láZ³]1· jÁf82º…>µ‚£&tŠõ�×Jµ�תk´GϲtíçyxäQš…®¬˜~½ÞwZé-“ ¦«‰ŒŽ¶etS�òdת-¢Ñ“„ã_ký€”Ä{‹˜ Ñ£AÐqݨUh$rkSmŽffô<…–nï~Ç/}zæìÑ7ϲ^TAb”éÝœ"C�‚ü0¾]ta!6,Ä2+êRì»J÷ÝZèÊèÖ°¦¢ôÔõ¢ŸÍ<.³“+º{.«Ãøš¨_ã¿^Qs×OÔοí»nUŠDþ¼ÿ>øÐëøÐWÑ h•ÈH@ɬÏÝs�ÏH¼ òDÿ˜Ç+›äl=V¾HûÕ%«2¯WwÉkvǨ€Ë×¾#Uš>îWYµdªÅÌûÂÀÈ CÉèg…vPÛݦ¶‹L³ëC¬3]CXêÒ 2É4R“”)8 }A¹šÑÏnçÙgwR^Ú¤¬W¡QF;E´ �i„Í�éN@ %¬«âu‡8ŒxÐ,Ô‹ÁG­R�Õò*ëcµ?nL.ýqcô õâ9–·Ö8tm�Ì,Ó­Wä–0åù•WWkl›\cb²N©Ú¡8Ú 8Ù$=G8út®K[Íà̰}œö�ëK«ÔOx1èDMœ¶œ†ÃÅMÝï~ý§9õzÝ'ÈB.è¸qÿ>Ð¥–ê‡ ?Œ'ŒÙCªÌ½ÇƱ¨Ì©Äó±þmÌuA'xOUúÛ:jXϘڳ»Ép�xÅ[gó“qx÷>ŒK¾p×�×zoû�qJœ—ïãýxR � ØŠ2�ÃI¢Î`çP�ðƒ:зž™ªE Þä‡lú™ŸÞ¡¥=QÁ�>¿¥é³ŽrÐG”’�( éŒ0²a’ˆNPfõüæü8…åQÂ3cTjã:Ú(ka½B˜x¯h&T;#l_Þ…²$|�Ñ/tiO§Ð§Uíøf¥~³¸zmd�æ¦,o>Αç±>qŒåMëœÚž¡¦KVè¡a‚j×Iþe¡Ë³ÇzvóX[§'×etªåGª-Tƒ±Áä ®|°™`P)X-7•op^§VZ*œFŽ—Âþ¿Zÿ/ܯ³(1ˆª‰çEcJÕA~O‚ymœ§1Ë‹è¡_f‹ï‡ÿ}œôæ¦Aj@Au}»Ê'¼!!ÁÆ C‰Úa\Âà÷Üwûßžø¹ù›<”²e} Þz¿ûÙ’EÄYG„ˆ-f!}²Œ$T«ëQQÖ‚Áˆ¿ÏpÅå让¹xk`-V½j‚‹çT3ñ. Ø)¶è•β)˜ô‡ñÌx`Ëý¯øÜ™Ÿý™›™ t™Î“?8Vj}—ª8PÁ�‘öŠi‰žé£àÄ«h΄AúÖ©¹uÊTtp§�qy7€:uB€ÅYêo2¬ÏÛƒ„N.ôX5‚8º&ñ4éK¾ÓÈð“m›©uÎ4¢^vžu‹—”Ì÷$A¦ôª‡éʃÒ‹³YpjŠÆú&ª+eFÖ«ÛU ëœi´ªYóÔ$ÅsS”–'(®Žu ˆ7H&”“€13É®ÕMøc׊Ã#ê´àpaF+„v!ËZA»ÞŠê4ÊËÔ&N=´¾ó Õv}ž3»Îs,�0¢ÖK–Šà¶Y¥ê@jŠ.!뮘Î|ïß½ûÜ6«¢ {UeQà�ŠêP�~òÃøßà¹U‰U˜S€™1÷‰y¯ãÞo‰·•Öùê苚*´U0èÚNÒO;C{ã0W¹xc:`ñb†Õ³gt„çê¹ÿôC7YŠé)÷>täÇø¯‡(AfmŠScÕDÎ’‚ =DRÉÝ B Lš7¬I�‰ú+ts=ö»K}²‹@ÛÆ=öêÐAŽ0˜JqŠ‚ul\‹=f<Áù¼õ/áÒ_å�€:øÙà-8’KÙ±~p�ã ¶]d$p¸RFOÅ£j1iˆœ�¦xÏ ì=z5SëÜé-I éÔ4ŠÎÕ|ÇB»Â„ ˜ÒõU¼Œ"\æÅà,N­øbª­B�z¥é“ˬNdç7ý6›!…û-Ž–šzƒ³Îëw?Ð{Å'ßxÛ.óŽ_£aþ�.ŽøÙ‚ž‡0À¡ØðûÝËŒ,Î,²oràepàŽ\\a>Fâ9Øftq>Væö ó‡Tã9= b÷ç­¹5¦ ó `| ÏÜ…0?ö†•ƒ§œ ãéˆXͽ¯ûK·âçU™Ã"dG�«úÂï•T^Ô•†IÐÕ½¢÷…†Fo£ž¨OÏXÜÝ^¾¡Š®ï†cÃéË 'PPk^'îê¿üu¹&½Vƾµ|Ï,·æß0i¨˜�5y5¿{âÇùÀÁ['p‘$¤^#56E�Z^Au±5Ñ›ÆUÆB¬tÉNd–cÞ‰¿\½rLñaô97â?? õ¯‡“Vm¾¥E¹P‰HA ‘X�v%i�2šzRlDê%¢VWá\Û §+ØÖ(#K›9¾…Êò£µ ÅVãBĈ À¥xŒÈh[³·/ÿ3Üÿ÷jÜ�Y¢¨E?)pþä |:ÑÂRXì/eœ¬7ÃSLWÎð©íþ¡µäØ1üëx·®3áfaß^ËÁ}phŸ×½±2ƒ h,±Ì±Wæ™Õ¹ˆU‰Efç�e�ýàcT™G˜›7pPaÑëÆâË;C†À>dòW׈Ee.v*{EâyXÜëÝ8»µþ }ÿÕ÷@ꢪµkáÓš=Ð 5±!_¦É—þ7|~Ï'NÍß³,e«tõv>Üx=x¤ uµ.2=XŸ^7kòwç}e¹L½¦ Šã<:h²ÆW§ø`2ñ�f(ZlàÒ\™ M·Ø£g3«àÔ "ã/N(‚8K§”™³Û˜::É5I‰B³Lxj³:ŽYª¢ë£Úþ¾?gò;>Ià2£/¸ßû?þvüú%DöpJ¯1¶OªÖ× ›öÄ­·tÚt�}0¬éÉ÷Ôï|kNQµGY=tº0}¨Ñåb[Æ^цGú,>šÇrßdï:ž8V@æ�ÅùXaNÌÍ瞘ù8ö3Ç‚<¹°ŽÌ)fÀ⇠rÈä¯�=­Uây‰ã9îÜ*SËçäãè·öi*ô„Ö>•OhÍm̱æ^ðâÉ•ì†Lþ2gòï�kÒ=O/“ÖÃÓw×~ä·¶-™g]#¾Æ ùpû-üÎ?ìäH-š£i”H!ÉÍÙü%®c&'I’"»Ù"ˆ/aNdèªCÕ æÞ‡Lþ«qعÕ% ¿€þù d¹iæ‚¶*y/EÞÁ«¢¹x�S?BØ)õ#Bo“ˆ²+PšµXXØLò­)˜óFU¼tw£w‡˜5¬—ÜOì`©;3,×_ ÿrMzÍÓòÓ‡^r¨ÿ¦ÿ8Ñæê­Ðæ&>¾ü~óáI{¤¸ˆ4Hòu“á#J¶#¨‡óäDp vã4¬‰âz‚ŠE‚ìòt6úzù':‚=‡ êù7h”TÐë^\ +ž¾ªE¬G#“€DM¢Üh…kµ¦‰ê2ª°EëWFÿ;cíÔÜBs­­úÝ8v;c'ð^5 #V¬7ªfÐè¨U£&µùa�sp# ’€¶(è:E]ÃR¹Èªô9¦žÃ¦À‘ ÀÙµUŒlq´CÏ©QÇâ>Çâ¢GãÁ™ÙüSÃrýW æ VeÆ ¢¾Îsò –ؽl?щ?åíÛék[�– }/í}÷¤5›‰gÅåm¨Í}áU†9í3=&>÷¯N×òGoH줱®®·ò7+¿ÄÛîcŧÍlb$³Jà ¥ut$Éú>t *ç5Í”,×£7Œ¨2÷øž´a<�ásŒ»øÌ$Äá bœW�Ádf /ì-ù IDAT/Ò[J8k3C�4S<$?¦bRQ¼AÄ…7Xüu‰:Öñþ¬¨ÿ€ÊúŸ7Gní6þ竎àâe¿·î&ìÎÓx‘ñE¶µV¹š1ÝA¤;4µ×ŠºíôÙ¬[)HY�‰°ÆçmÁ ŠÅ©Çj„ÕM¦Ã” ת@Ë"X”%ˆª4`陞·[8¥?qè¸+§ƒZ|Ö”X•• 4ÿ½ÄÝ9æì€ŒæjˆŠb`¿À`ÆÀbªç“õ¢ãÆcžrµ}™òüiÃNOQä1H^n‘$¾ðgó˜É94áò�B2ù§âjlu>öósÞð¢3ÌØ—o[,¼ôlñW‹ôþµ7 o´‹ö¯Aï©X–2‡·ƒ{Ñ¯Ö ü�É_L~ìÐ7î¼)Þ�1)JW_À�ÞÏñž»·Ë²Üd8‰»Ø? 0¢4g` ^#Œ¤¸ËÖmõ™ÃäŸD’�³{ 0Ö9ñèçü}Ç‹÷r ËéÞÕ¬Žúÿ[¥Ùœ£ 3Ùâü¢ßC<3C¼˜óÌAdâ'1÷²wÁ#3ª óäùä@~g"̀ݗ«ö»�¯¨ : 7* C�ÿº<áu6¿F›ŸbøØ]ð‰¿Œ S§Ì[BôGgÛ>DɲëUÎ$’ÏÈJ>)7´‰Æ…xÎÉàÞóoxר 7]c}C÷ñ‰ä?ð®‡öÚC+Y".ˆ4ðXéENlòŇ0ä/–@#‚W i3ø+ŒP L‚r÷IQ�¦šy#d{"uÏîYlÇ çTÓÃaåw,ýÃÍJi?Yx“ê ûýKŽ8™›ËSˆ¹KļÐP¯"} ÔçcdnŽ£"Ü=X†ûeÛ½¢B“Ñ•:“Ùf¶¥ ®Ò&[±~«fìÒžì¤(:"ÓN|IÀ`±¹#€Š8°JÁ *#Æû11~»·Ü ÂK’ü:Àcñ$íÕ´–œgMsVË<·Kñ¬œ§8{˜·°J•ÕÅqj¼ŽÎß(¯â�3+¢3Â�}û�°Œ2/JŒîCu/‹H<+Ä1Ä(ñ¥÷—oQ|X®ÿÊ·ž(ÂÅÞ1�d•°ñó–iÌO$dAK «&Û‚<0†;Êà^Î*È@ªö« òÃrýW�)×ÿ¦ìIwËSâ"6yøö£É¶Ôbï´Ðàz>VûE~ãÁë9ÝÚ^Œd%�ȤGâŸhû^Êäóîz#ŠW'J�+%�°âp—¥ ΰ\ÿ�ÓÓK»!�`"0Y&W{Ø+4AÏ€;l*øQÿ‘©„ê·>“çÞE)ºWÛýÿødî�U7Àæ�½ƒ¯g. šaâU¸ÔűaïA�Eî:„| ü\¬:r�EÙÇ!98ëâÂugۖ峎Nl¡›NQèNÒÕ=Dr %·‹.;±f+FŠ E !ª‚WO`Bï½ñyß‚Š1�1€ÔÕƒÜò!!b]#Ö4`�2çi‡M–�*V8aF9Öz”5šôIénÿ4þÀÇðDXDcbö2'‡ ¯häÿÃrý×sv px=FôÀûÍÏlÆüdO2ÓSCWqÛÿÙéÌOM>²â†©Õ0£‡_r²ùÆŸÙ™r�Eš\¯÷µÞÁ[ïÝR:C” >³’eâ™Z›ÖYy¢ñ7�׋*pÖ »G!UÁ¨’VÏ'Î -‹¯ ±ôp¾€ŠÉØ•Â�µ-ÐÓˆ?Ž~àGôÏ Yðƒ|ɺމ>9ù#Ù`ªy[Ô§/´þ‹\�œÐÆ<1ˆu~îEîØ;£ÚGœOþ©0«ûˆeq_L,s)±¤Û^Izö3ëkã]Œ)s±"¸Õ\Çfóèÿxp„¨7ÎR}#ÝŒ›g‘W‰O·h/Ø©}™vêG‰ˆ(h°Þ‰â4=N�P"éh e‚b"x#¾“â¨kF•cÁ ‰=…—ÓÈŽpGvÄþs–ݯ…çãR¼^íÄÍ&t^w†t;¸ø2n`îñ'…èŒ�AùwÄŽéƒæóYüÉ‘–ýÙgêy'}ºý̤å„Ë”ñ§’Â[o¿Âç‹mÈ䟑L~ë‰�‡ºÿîW¶×å¶1Ѷnç ÿOüê=/.ÜÓéfdâQQ!é¡>°XïìÀÀÀQ0ð—|mAz„·TpUÍÐÓŠ?Ú˾‡Šw—a¤9PÍ¥‡CT›®‘§¢º;AnòFMꑳˆýãŸàoÖ{L½î’C*Ëäy TïÉTßüdôèò%ûÇÔ/¿'Ÿ’K“�Ç¡ <7<ÈrØ¿P0xü[U˜sÌ}Ìø˜E�“�9dc©‹Þfà¾â8LÖe'ì6ên;®B¹ŠŠ½o·ˆI¦±„*û†�ô$ÀˆCŃzT1Šñy»C ‚UÄ"ŠÒÓŽ(=µ²BÉž¢`–©èy:飴Y*œ ŸÃñî;©óèNÇ‹N9¦ñ3ûÑ}óÈ™3È{n…ø,:ã%f£;PX˜}ÿmGþ}ÉË/ÎÖU´…úMð¹i8ÚW2Uƒ ®àûƒnzë!º¤�Ƶ›Ÿqqó¹‘Ï·è­õã½W¼$ i6q8ùI~ëðKåãÇD!o¬K¬ çÙŸi‡‹h§>Äi>‰ãœWPRÒéЙÛ3㣖¢5 ‡Uþú‡ ÿãá´³ý§‡Ïb™Sfc�ctï^zD0û(-`•˜‡XøËC’`)>`}##ÀcºÅ6ÙêjlÃÙ«Èt;ø]¦À65l"pUõ„ùô¼Ýèc# ñÑIþÀmQí˜�‘‘ÔqNG£#,³úÑÓü’;ñ %V²pñÄ[g¬c™iÎmûÿiŸ½äUèÌ^ÑÅ<óù?qÿËb3½ë>Q���y• ½ÿ2dò_Y¢=y>Løò þ ”ÞTGE×ÀOzp«òˆïoýFóƒë /ËÊ¢“e¨&–:â}æÄª)zßxW´„Œ[™æ‹¶~מ?ÿÄ¢ÆÄ1íP×nÖ7>Â?ýê©Ü´¯akj\ “4ìDnò jœ&*bî�biJˆñ +¹Í!Á–rzêžãh›@tTÑ{°¿ø{¾ô½[9úƒø9ùåkQýÏp³Ð°¹†=<ÍØªèšÕˆpp,¬n–ˆ_6,œ<Ìe z$Žá}ÙeÏb씟œ ÏÎ:ùRÖÞ$¼p§pü˜Ðu�å tSb!)K(›Ã¨™%4ä0¬Îg‚•XßG¢e_‘.DC¢ß«"„Þy¹Š�ŠB‰QúÄã½áqšH‚U¥„w5m¸I1»7»ÈÜfÚ.¿ËœqÙæÒ ØYî[»E:Øq^Æîj[ß(ÛžS‹"ÿéò,݃¶WQÉÕh›“¶]¸£J *˜pZGT±ÓZ4WP¿½™É[çp.L¢¡œÓ[uéñ%²¶qñºä5¿þ×ò?}ëÖúãÞ’þöSa±a5û«ôöï2Õÿ–ý+îkUX[,}‹ añ{xuñ(-¦ã©êð)Eækø2V¯‚s/@wÀe·ïXܵ›S.Ûq2Ã7�±EVòS9•6½æêkøüÒ�2�ñî6}í&–d%ú”:K³V`Ò”Ü�ϵ‚US¤wmhŽ ¡ÕN]LѰÚ`tã–ˆÕã´¦Þ[|Í µQ¥†è©ìÙBºvWL×?D¾?�?•¿Ÿ�¤uñj<" ´¨\V 'š ç‰B"¡Ø®Z;kjÉ+ž «2™Âx:î-Õ²§Ö¦T��9Åeu6L«£( _DmÁ7<pEÕ¾ÿþL9qž²÷po×M�}r:]°šmRÂÄ+”ªâ:)Ðìø8'ÃÃ{¥ëϗó¥Òõ»üOØ¥wÖÿêwߺåeÏV3!~£¼ƒÏmý}.¾±Œª· Œ˜ÏFæJº¾a¡äÂÒLf•ÔAf!/aJÕÄ{rß. Lª9A�o›s · ×}¹ýã_üYõYAÍo9ÿ´šó„Ÿ3g ïZ1÷€¬ZKº~/ócž0D�Y‰cøxJÎ †>JR&Ýo¯›v8 ò8ï±jEU|Œä"‹ûø÷±Q{ûÝÈŠŠõ‹Mn�¨!ËúÉ{sd‘Aºm³CbØCJNذìP k¦FŒ£¤øTÐCز uy ¹QÍÛ„Z»2‘f¦Ö†N–Ð „ªµ4 Ô äÞ‚ŠW C#Å6Lpб9ï´QrfZËü)çV¡¨ ÔæïäÉ´y9Z4OñÅRäwaùn{{ý¯Þ}Û[Î|®R3óý=ùÛù�m§qÉ-iR'ËÅY'Ñéžc”�HŠ‘Î;)"Æ©–«%_’†4 {L“¬É+u`Ü¡·K~ÝWËüìÏ'Ÿõ0¿‹ƒ/ÔPù›ÏÁ!l†í«X+7s®Þ²àjÊZ§[îfÒ,0#Õ%:Îb†p¬¤$‹Iµ�Ô’˜2ŠW/bê¾Eþ!rÜkttxxÍ%ÃÜ$œ³•ך‹ø±Ù¾üζͣ¾kž§oE�þ�µò%MVv2±¸�]fð‹-Òå¡«†¯$‚±vfxŒ8„¹*^€T„T”6‹ô†:�°iÕ*®â¬OqYel5ÅL‚Ž[t2µn Y¢dÖ“…&×H’”´Ÿ‡¸]p:eÂJ°):^‡ªLsáO1êüdypç‚ Ûßõ¡y�Où}�¥‡õù;ù̯žÇÿîjÇo0ž”2‰iP�Ÿé\2í¢ÔpÞH�ÅbÅ“ ªÐ�Ê“�䕺ö!Ü×~µë=ŸýñØÓ÷;+Hd†Ûi&æÃi�*Ãá ñð ÔVC^´¸[8öJ.X%œs.GÜIZ»›JuÝ£í¶×fÙ�«Ë¾RŒ"ÿPY- ¯>Gà-šc=¬ÎÏÐ5šÕÃŒ›AtXë—Þtn]Öžú9Co¯¼å­ç–ŽßÉ<¥·o>c '’üȆӅm¢KjÞ�Ã@»e~)§RÆ´%*ÆY!ðŠ§ŠCÍhb™ªÐnp½‰:-iØ™:ƒEœEë@½-W R‡$…j*:iŒ6—{È|h�½¿"´(Þ Ypªa,¹�¶ãw Wï†}õ¡®ÆŽ§õz )›õÕüËMgqÉ¢8•†õ¦ÒHkõF1a.2×(9++5^-")ÝZ³Ç·á»Æ€=X½ ný¶yÓ§8úÒ€]ô€ÂÄÈÌvöam±N˜6¸ý�D‡U‹�Ø0,ÇÊêsÏñÅ4¼:ª¿Z;Áà¹{ô”ì.”kÖ\æexg]£È?tO¼¸€ÖèÚ †Eô&f­¯^%¬>wßQ S›ôä5o”�7âw^@õµ739ÌÞm¯[uÁ-ì]y9@ÑüÀ¬³4§÷W%&½X!,Ÿt,™ô,í–‰Úe§äFEKÆzAÕ#Tƒ8#aîsbB@‡QtRè�ZE­Ã—‘,Ej%LÝ 5‹ÑZÉR³Êd™÷ê=ø0<5ÑtÜ/KFt}åý|ËøÖãOs*~;/ç?¶¼š¯o-ª€h ž:¾M­Éî£Umdö&‚¬ŠXD™j ÓžQÎjÉïå&ïõèµl$½û{å—Ÿ÷­ú¯†dé5Sñ“žéç�Â9k‹ßnV$ŒÖa ÂüµÍG £ÃÃì7#ÅCÂð V‹€>YD×Ä}ò™á첺èψ‹2¬ûç «ÊT:F…æãá©n�¡O!ðj•pÎ9>lûX#¬ºIx‹pòNeÍÍÊM«ääµçÊeçœcλtmù9»èýó�¬0zØÂ$[¬¹=R�Ã2X4 Ëä½m˜¤ 1¯$/ŠCJ¼J˜-F!õ! ` Ó ­¨— Õ?™ õ’PõÂx›£V†Z"Ô=¸ª…Ü ê¤=TÔ`„ÄkëPïÂp 'ˆOãPŽÝ«+€ ƒnj¯øôzo§ÎãƒMî•i¦Nƒç,RvÂ�®øßóee¶ä7 ïŽÑ •5/½|ýmvÖ( ;S¶é+ùÏ=oæK×¶“»œD]R—’"âÊjP©Ñpg›Ùæ¹eаO ñzƒÞ{‹ÝÌb6Þ5Qùð¥ˆñà X'áÄX*µ<9ÁHÞçÔÈžuØmÿ=ïœw}{ô/ß«¤�yy,縫ˆ…w3;`,&ÝL·PSý€E•éØ¿[@µ˜Cþ¯"Š›bad¶� kNÁ¾ ‹R¾ƒdðV~VgpÔ³¨½Á²k±oíÇèáh-Å/(£� ‰_ŒSR|( TÁƒbP1Í´}hÔ'aÂ#Íi¹.…F:ÙŽÔÊH=Á�‹¥f„,Ë˲:¹sâÔ*’"¥Ðæ7ȧšfo·¢Ò¯é!íïò¿?-ÞP´ùL¤Ù{²)Z¯Íþ1÷j#SìjCŠÿGX[a—`ÊyÂ$_öƒÏÉÙaÒ9ýþ¥#•�éšwß²í¶çŸ4Iw[Ê(/åß6¾‰¯ÞÚǨ÷X•Цöž*Åç傇)dô y¢˜½‚OUö„…7#£¼Y)òÅyÖyë‚£ÕH4+yZWž” 5TwYÌvgwýÔžü·ÿà>úF¥t܃üË£9Çý2ŠüÜ$¦ëgMºGtÿ ˆKaxÍšÚ«†å)èl`çZ¾ù\=�;£,îV£?È=mËû¤ºw¥ì©!÷ØeÜ™ ˜Ÿv–·Ì/! ¤+CçÑö²"%Œ1@ާ) ÅÄ\«Š$Hj°�Íé>qhÑ ŸBž 5£Œ[˜ð¢uIê5�ºQê©’%— š�NmÓ3dâBP_ ûhØ©ÂÀf$oUÄhRT8Ýï LÃýÑÿ•¹°ÁPÐä7Drá¾äž½«×P»ã÷OËŒ•6¿Óÿ_»ý­üËú¶rÝ$9R÷Nå�ù×RxôFˆɒŪÌk ¾¤n“A÷4Ƚ+ú)¬ÇÒªˆq‡#Ä*šIžf*Ç%¢ êŠß+È.ÏΟ¶ÿÞûþqòï|ð¿?©‰"iéH^)ìµ*à„Õœ««ÃèÕx8G†× cu�w*Né::NŸÐn6²ˆŸ°ªx¦·~̈ÛÒ£Ùæ…Ôodtß"vVØ\YÀúÊßíðº{qÉøîŠ7ehKÐÄ¢xœz Y&WΓ@ÆBj¡Í@o ”T0™bŸbr�\ðÕ²êDê´–†ÆAU+Zã2�LUýÌK rÒCNðD¢ÈGZ=’§˜I ¬»Š:¬"«›ë5«Q÷g�Äq? ²¦Ë«9z){hçí–'÷¿=+áwÎóùÞ �õ}2±gHv×ú�ÉafSy‰ùEgGþ³�zÚs(Y|bc° †×‰B¨-W6P¥C„~£¨%ÔX5”œfe$³h#A'­Pµ¢U#ÔÄÉh m(x#x5¨ó„ÁNöOp ßlPÄ÷{ ©CÌÔpî%cºyþÇž}ù 7�u†¡M,[y!޽…ÿÞÐͤ1ã@—1AÙ—hòZïÝ+âQƒ5®é Fãÿâ '„n%*©Å'¶�}b…|Ñè†Íž½WÓýþOë¿=m?5~r‘(ò‘fú|ÿLÄæ¸Áa”á¢hCCRD³Ec$m`wa¡Ì&íâz-vôxÀ¿ðc‚ßÕC¶u£+d¼ÑÏ^u“]Àí¥N.íÊe〢Ý•¤¢&MÁ( D8Ç„QêxU¡¤FËFÁzzIT5A(‡`ÝY´aU«%OM Z&Kª“ ®š@] ˯4=ÈÏ:ǃ1bœ 08n¶óÉÇ\xÕ5o?ÝÓ?/a§qÙøÛùܯ{¯eX5ÞiYË2.uW1uûHv¶ KÀ&4G #¿Å¥ßÈsbºþÁ–’JSÃy_ÂT2ì(æ8‹[TµÈˆC7‘ì»5m|à¼ìÛ' �/zØý½HùH«Fòû×ä ]t›Ug¢ªH³Åº$ˆ)býC{é›.Åtí%a/m\§ýÀr ¹´øõc’oé“êž~�¬/bŸëg›ôËú´ßÞÝÕŸÿ°'¥ÚŸ"%QŒ:ï‘P¸�fñ@n<‰b­Òf�6”ýC�ŠÄ[AËJfE'ÊJ£‚ÔSÑ1MhT­gÜ@î=.T1Šä¢ê-b¤…©ô€ë q⋵[l==ÿ•·üâÚ³Ï3+”üFžÇ¥ÞÃGïé$¯Ú\K`œ eƒ‡úD�Ö…’Y§¨Úà™%¬3+D§rîÅëš¶÷àà£(¢Í­xasBV$æ%lº ïƒûžhyØ®ËðÕY%·H[¤„msÈ>µ¿§Æ-4ÞPuª[1c?7�¿ýT~Ù¡ûå‡$©‰"ie‹rðq¤2mV}Ø:·¿�í£ݘ®íZêÚN èÇ“”ƒ°¦‘ˆÛÝOcç|­ÖŽaT³+_Ȧ´G6·Ï3×tx®íIíŠI5 £U0XѰ}ÌxU¨ˆjÅÕçVÑ$ƒ¢£|zL$Vk©“‰4·UÈ'jBV†j Ž É-©©ÕmÖX}”ÜÃëŸ C6õ»8‘«·ÿ9ÿpó|[5Þ © J.¹Š _F%OÅ�fxUT V¬<¹fxmžªÙ¿šËþÿNí²ÿͨ]MHU„ F<^Å/õx‡Í¼7Xñ±iá¡Í°#ëB®© h�4<©ŒlxÃNãÙáeòzÌšÏÈÿ®¾÷OA"!E>™iRJ™&‹·’,ÞJ;72X<)8*øñÒØÒ«õ‰ùL4†Ø› èV;O¶·õš ]ýîâö #� %)ÚCi±5¯F³“‘‚uÖ*ÖzRAºÄ©Z %'µ*^Ds+4R´V‘êäGr$cv?±›b ·�­æoìHö™‰¼”—’†%—PNí!Ñ)‹[³�ðüa» þ¸Í- IDAT†Âˆé¦~‡l„/ ç̽öÜ_Ž]œ{àE<^Fæáooàzðˆî«*¾ûdzG¶ø„ ˆÁ‰EwG•¼,n ìÏ>o&¯¬ø�~¬ö�ç¾#~j‘(ò‘HA Óy�V:ï¡Rd�c÷;Â_çíø±4¶/bb|#Ù|FÌvµõ±¾£›ëÊe®,ᤢˆ•fš?C™,Ö>,*V”²Åv%8ž+꟣|7—:%×ÅD9•±“Ü4’SWÑjêl|Ý£™¢¹Ô;Ù_ùæ››#(êõi6° µá1®èQJã­ Nž¹ �1Za«*ž S¿Ý‰J®¢)FJˆÉÁÇ0ïaN¨=ö ¼‚· “4ôH/©ŠŒcØ¥’]Ÿ¸<¯öíÌ3´†CãxÅt}ùHdÖf’ lï:Úz×ÑÆ•Ú�‹@³EdûSd_£ŸQ3Ÿ½f;çqW{?OÊl-— ±À“»MÞp�ªy>ÆdŒãÉÍ$&™P[²X²¾‘’ª N4�Ì ¦‰NZ¨Y´šõÔ…�¹Í2¼ËŠa–D‚wáÄ…7ä‹Íq÷i¸=¦È„uwOe U§Rô ¬ã| å-FÃgŸ8#Î%˕Ƒ¹b&QÖ¡�ͤÿúOòŸ;=Ë>ÊT±ÅÃ}D‘�"‰Ì]r$ÝD©¥~˜÷÷Ï'Ûz<¿þFI^;´žº^iß(^+þÆI—W-áŃZTÆiâÁ�Ž�&¡øJÊF©`EçQ¹ZLŽZ4+‰k””z9Œ®A>©HµU‹¯¹Ð1X³ýÂý»„m‡Sµ* bœ×+a‡A”ù‡ß±Tm <€ÅÈ^tI'�Uì„À6MüÒùÛÊo­óq�ô�¾¤HùH$r õ»<7Þ°�áÞïsÏ9(íÁj‡LøF‘ìïd‡<‹�ž†Y2©ãËF¥±r›‘Ã68í¹Q+öWtY˜×¦’¶�5EÑc¦x-ÄßÅ‚JN%M¡3IŠº%5N�O0™E&­ªøÉD©Z¤nÂÁ:hÖÀùLÐ<u‡e«4kJ&¹&E¿îϨšýŽƒ6·cË"*öz‡ñyÅ4BÈ‹…SüºÒìî7“{å?¦§ã泌í¤2™äšä"Óhèòñ«20“š°YÕ­Cþóï’¾n´vì§@J‡ÜïˆD‘�D"MÜFÏ­ç{þèÍÀ™ÅÁý!¯uAô²UÕ¤j}ûž6Ú÷´ ¿ž¬Pxjȼ&ŽÉþLvõUÙ·pL«{È{v¨?ünº{¬m]ã´•0½%ÕR¹èÊï2D…È+*xU ÆàËF( ô¦¡½¯H˜?ímè·’W„zE©µc&õÀt?R't¼¦£ÈG"‘)ߥlx64Ìý˜ÌݤªG1Uü�#ÂF«Ò“xP̼mkÛ†X«ª9ìŸó[ð!kŸ!¥Ý¢$^H½`𚄱€jTò�¡TË*µ’J]�j(ôõ ¼C½u‚!·N¬‡DúìO § .´ô Û››™J—{‹4G cB½Ÿ'´¾·‡%—æAñÓ?÷Û¿Ö¼�$­ŠƒoâL¯šüqÆK2² £ÛU.ú$¯ýÜ­Õ?ú$Ëã5‰"‰­¦Z›ÙÂ0Åq¦z‡9 5ãåàkï¥ 5”¤Žz“`R'ý ü ÖK©Šê5ºùñç^öÙÛv¾þc�ýè�ב(ò‘ÈœÇmôÜr�çïß1u\Txp$¼}ŠÝPzè¦VxWa®EÉÂÖ€\ºE»Ÿ½ƒnv°ˆÛüQÀ3Á¿ðãB¶ÝÒØV¡zC;£»:Ù¹÷pî1G›'ýþÝó‘]*‹èvøNE:S|©dHJ,BNR”è+5‚ŠG�‡Ä@{RÄzÔ’«_Rã“Üd²¥PépºÜ##W­‰RKÀYP Cƒµ!NëM@ŒGl1‚'d œÚbŸíÿ´h„Ñ¢“`ñýcÕÊ”´§À܇DfyâʨqICÒœy9<©,ZQãwвY͵ŸHžñ÷×ï~ûj¥ô¸G×y�D‘�Dætï¶(wüÈsþ¹pkGÐÆ’Âà•†wþÂðô?›=ÀóŠÿM‹Y13ûÍ 2�qÅø¼¢F‘û~á¦S)wæ”§‹q°ƒ#¸›§r‰ÿÀ�C¶ ÛUjëWêÈÈRvŒ.g“ôWÐÁÏûR|o%ɦ9ýó0]e¤+�R‚š;‹x Vì¡/vñÅ+>MŠI‚›a…!üœ>U2E2‹©µ©N$P/)µ.§U…IE3gÉ=š»)/LjçŠX’b`P®.Aö*ôAüU�¯.¤%îcs“[¤³!ÝUôxƒ–÷ªøÝxvhåÚ¯$G¾ïF÷áw«Vžò(Ÿ±sqùHd. |¾^¹ãÇ'΄_wAèQ8þËÛ.VüùÁ:’i‹´vÉA¶šÆ×«Ê‚.eÀ8Q1ȃ7ý¦ÊG@ùÑ.Ö1À:Žä'L9mycG™ê ]2º{ Ù6ÑÏ–ÆR½\{ó+z{` ´¡‹RèI š$5¢ 9ªõ¢›Ø•/F‘²Á—\— ¢hhá+ˆ¨/AVv’%h½˜8™c&´–¢�$ϽÁ™™Í­Š`Põâ &È¢ôþ„Þ8¼ótO"ÇWÐÎDGQÙ„ÜøÝžyúÑØgß‚¶Ÿ/±HùHäQøìÏÍ?öü¿sáú�Á œr›á w ýï¾ï–£Ú:Ÿ ò“NîzÕ¨ìT‹-ö´‚P¥|D•.Ft³#ŠûÎEðãH¶ÛDk¿JÛy”Ù“ Ê·J/n,öWô·aÛ†>})lV¡ËŠv¶«–ÚT’¢AF�4· ‚"*v"l~( ÒÙ¬ðOð A´”ãʘÌ@UÑjŠNZ´š$ÔÊB­’I Gž¡.ïŠM‚ÏxÛž\õ„ ¾stÊ�ÂM?JÞ÷õ±o¾ ×ù‚™sžG¢ÈG"sNàë×z®½Äó‰×Ãí}ì/¸zâ­–7ÝóÏ)tâ~lç}MvŸAÆuw$Éè$‚bAÜýeëùo:Ñr'”Wºh0À�~%7ó¢� 0õÝÊv)ûÒ]Ë”–éÞÉA6ûù\\ŸWºdþ™S߸Îó«‹<y3lh ¼Â’›-oúô½óþ¾ˆä[À| "ºs"³”ŒÒÀ€x�ÉÝçL'¾­SXNž<ÿŽæaž ?&¸Í%²-N·´•Ç/ëalßѵ­µÇp‘ òãþ^ÍçW�Ãd ÉmOíí(¡6A%ôÑY€:FŠ‚™3d·x®ÿžçR|ÁÒ øª°âï~·©`JKÞ¡bkV]1*&Ãy#Ú­iL—bŽ©“ƒ¶3Vëa ØÈcø!Ït É7c²-¸Æ�‹luô0?6ºR6L¬ô?ltrñ¼d�ÀaeèïDçWðóS¤Ý@¢@ŽW_dꨫPÃk6É­#qºõÖÄ}¹fYØ^/Ÿó�Îü¯ÿgËž.~þ›f¦S‰"‰Ì üNåî‹=ç½nd*×~§á_4üÞ~÷¡!-"“‚u˜êDææuQµ>T·ÏN¤ M�Á¥Ç@;Û\ÛXÌÕzpð‘1Ám¶d[Ú¥q{‡ÖF:Ù7ÞÅ–Ý'rIÖÍzzð‹úà°Ne±GúAÚ´½†/{5:n~WÛØ•'Õ8¢b'®þïê…lj[ôÎx}E¢ÈG"�^@3¦ìºÈñ…ÓàöæE9w oþ€áä?°¡!Ú³S È“®«](¢ÓÊÏIB& '=fTÛ`p4×r ÂÇÀm†|³Ò¸)‘ÚžÇÚ‘Ú±ùÆñ¥æ‡µEæ¢ö]yÕ”ìeé­�\p²pØß2Õ8/Fò‘(ò‘È#ÁïRvßó¹ãá—«˜*™Þ)¼zØòº5`‡ íÔV0  ØÅYûar…hÓR*¹E4]`Ž�ôh#×n®ËrGƒ?ü‡w!ùvöå'%âFjÚy¿µ~#Š|$Š|$rˆÈ×+ÛÖ:Î?~º F ÃW�s‡-ú^HŽCKl¡ó‚,d²$HvýeªH<-|& -õ£¥c[Äm‰"E>™­d·(¿æøÌpùB£ö™ïMø³·Aú˜ µÊªüïv,‰D‘�DZ…Æ ž¿àùÒÀõO†z‘¢ï~ÿã–·¿Ò‡�µFá�ÊŒ]+Žá%ç[^üJHW=dÛÙ[èµKŒäç±w}ùHdV ü:Ï5ñ|ô°þSÇWŽ^ÿÃÉ/»ôa�Om‘ɤ3kùÉGæ1�™e¸�ž«‡=~ ¬?yJÌO x¾áä³�/¤0Ÿ*ÈÃ5ŠŒ¢hT÷H$Š|$ÒŠ¿ÍóË÷yÖ¼ÖŸ>Å,Ì„W~ÊrúŸÀ·N$¯ TJ?»%tÚ7"#ùÉGæ1]™%ø}ÊMëùøÓaË©SLJjÂ+>oyéïCéqóß„V�ùƒÞE‘Ÿ;E>Š|$ÒÒäÊöóç=î|Í”€-sÂkþÃòÂSZý}Š|‹Œ”?X‘]ÔøÉG¢ÈG"-aÀ&.ö|mn| û— úœpö7,/xÊ¡øâO·Já]TùH$Š|$Òz_½Âñ�mÊů bVXæ…S/°¼lñߢ? ’�éúHŒä#Qä#‘Ca¸j?w|ë.å__{‹Ñ°ËU8û–³–BÛÓíKð-ÓñîèÎF9›D�Ô:1Џhú£ÈG¢ÈG"3“êO_ß \ð Ø›@X©Â™?°œÝ •§<¶³%ªëä±ÛíŸtÀaņ>1’�"‰"‰ÌD×8þó6å?^ {‹é_˼ðâZ^4*'>2¯£5 ïì"LŸ'›'¨Å‰¦?Š|d÷ÉGZŒìÇ÷~¡|íÕS?ä…üÀò¨<í‘‹R[$]/HƒÌ7Ä ¼�f?‰"‰Ì´þÇw/U¾ø'°³Ž†pö–—&Ðv�hÚ)­!—¦DbÊnª‰ygÍÆH>2'ˆéúH‹P»Üñ�‹”ÿükØ\�àX„ç^ey®@ûi<âëÌ­±…NAˆºâÕ–1Æ MÿœÑø8 &Š|$2“©þ0çß„~ê]áØáκÙpÊy´þ§9oý<üäc@_Ø&· á¬[,/½*OàQÝ Ö2£fåv«_wÈzxTm¼öc$™Ät}d†R¿6ç/¿WŸ,€…'`xÎ&ÃsöAÇé€}t_cN‹¤ëÍ]Ÿ�:gP "×ä£ÈG¢ÈG"�Ù-Ž�þ3\ñ!`(©c0¼`«áY”žÂŒhæÒ:‘<Î’ÐRJÆÏ´(ò‘ÙNLÙEfn‹ã_?®|óýÀ`ˆàŸ,Â)› 'm‡Ò fL·6®5¶ÐQÁxT`ÑÖÈ@D¢ÆGb$™Mø½Žï¼_ùÌû‚À'bxÖVÃI› ífP;V%×i†cìÄ„K¨O¡ ï¢ÊG¢ÈG"�œšô\ú~eø¯€åÁ0=N §�N¬ÛäìÌzÍ­3 Æ”0y M°2)yìxE>E>yÄpÊñ¼óÀ²`”†žºÃð¤ H—3#ªäÚ*ëÚ'§Š|ùHŒä#‘Ck|”íŸu¼îɰõÉáÐ2„S' /ºAè}ÆÌ>G=­Ék»âMT¨¢>*|$#ùHä üŽóo8¶>-BxƤáÌk„'‚´Íì·�µÊ:l*¢Š*†ŠÅz$ê|Œä#1’�D•ÕÙùÇiǧ„#ƒ§6 /¾Jx2Hyæ¿ ×2[Ñ|9´Ù÷(† ðÑòÏ™«-n˜Œ‘|$òH²ï›ŽS�¸·ÀŸV3œ{¥0t"HGk¼�†¶È>yH¬$AÜÅ;ñ>®ÉÇH>#ùHäágââœÓ»î-ðÏ�4œsµ0ô$�öÖy/­ÉïMÙÛ@¼ F0ÛÚF"1’�D^ª?Ëù£q˜85ü¾á”IÃK¯†Žo�¾Iël¡[7˜ÿ7°Þ½ëMC#ùHùHäá£qcÎÛwÀú³Ãï=OË /ù?aè‰ �-è´´L$]¥#‡´n &Š|ùHùHäá‰xïÌþ\uVSàáÄÜðÒK„�ÓÝšï+Sò1 ©·J¦EPœ—hø£ÈG¢ÈG"·ÉññËáÂ×L; ÃK¾+<æq`Z÷½�h«Dò©©æ)%Ó´ö"1’�‰"‰<$ü.Ç翯|íUìï;¿B /¸ÈðÄcÀ.mí÷7Ö2éú̦¦ŽzÔCE>ª|d«ë#‡Ê®Œ;Ö~Sùìk¦~È /û¾áù‡AºjVά5 hÅfI.¨QhD‘Ÿs"¿ïÉG"›M©y.Z«|øÕ@Ž ¨ð‚ZÎêƒòq³&:j‘êúÆìcÛ…$Q!j|Œä#Qä#‘Cî¹ì[ž¿þC 4uøÉZ^> •§ÍªwÛh�—¹xÂ>C½ ª@ k4FvQä#Qä#‘ˆ÷\õ?žw¼˜0N®’ß°¼õ˜w6³G\|+Eòí¶a¤0÷§ÑêG"Qä#‘.Üv¡çõgL‹à–Ýòñ«„Á¿™E5 Ú\“oÕ+=FòsçÊŒ>Ý&ÞÍ-™aWÖ]ì8÷T ŽôÇ]lyÇ Â²áÖ8óß2Àxk¤BÕøÝÇ)tsˆ8 &Š|$òPÔnç�g�8%ð(œp…å]· ß; ~Jäë-òbcÎnn_¢‘9K¼ôçæ?O™Ø Ù�àv€>©¹ÒqÎã€ySÇJ?6¼þBaág©Àh8g¼U }$#ùÈ\àNàlÇi5` Øl‡§î;!,©ÃPMè3ÐÑ&¤Ý�tC2/´ŸµÝ`zÂm⎜W{§w­»YxË¿Žüä,ø{ »¢Ìðr¿\ ß?�äL4[b0B\“�‘|$Š|dVògÀ'�!`Eñï \¹H¹r™BS•ñã…°Ø\ ìvŠë>Lø…×­¶¼â#`Í!Ã9ã�èmv'0¾¿­-ÄæõsGããWE>2‡È€;ŠÛeLuÃ2…p'À|àÈBÀ—‡·Ç½G »p Í ®�…Ç+므y¿: ´L˜¾Öœ47K¢#ûKs1’�‘|$Š|dŽ\ìJØñ]-~ÖDÚ�ÇÿC(²k>ß-ÀÝÀ1ʇžè #œ[2óFatèxòN᤺°R„ ôö m=�ö�í/n‹i�ZÀÏvF¿Ú8�&‰"‰ü_ú§ ü�À™…SP: Exƒ C°o1aY`)\u”rU�'À@ Ø\ŒÂwOŽL…Á>èì Ž@ihš#°hÆ‹êÌù§¸….:÷‘(ò‘ÈCÀ„4>üº"Ú¯·ÝűéF¦)*ÅsuÿNXX<®R®M «4 ì+žo p-°^7"œØ-ôõAGŸÐ>É$óÁG@Ú¡Ýô-eD�7p¯ÍòQä£ÈG¢ÈGætì7Å ðà Óûàl¦Òú¿Í�4ïn»Ÿ¿— Š¿Y²¢ø÷8`%С|Q•/V '`káÜF( Ü ìÞê…ÇÎæ÷C÷ P€´’"#�,éxȆSgþ¼—'Tu‰J&¢)9c2ÄEÓE>E>2§ ƒÒï_.¾)e€çÖáî¿—›‹Û/âXÂrÀÐ4ñ_, ™†ŠûSåŸ�ÂH!ú#À6àÿŠŸw»…s�pâ|aÉtöC¥_(M9¶Lÿo1œ3Þˆ®IžYR¿Ô¡ÐÀÅhsêRŽ"E>9hdÝ üðœiÇw§·â¨Cî㾜°†¿¸á çsh#,¬`j)`%pðTÂ�2ÐP.¨)ì,Þ×ÂöÀë G`^•'.@ç€Ð¶l[+‰|É8“/Æ ‹JŒï"‘(ò‘¹*î"ø%àŒi÷�¯"¤Å…D<ÐèøÀÇdÅm¬ì›x_¦p\:Íõ‡ `¨È<èj:@Uùʈò•æ2ÀNà×Àvà%­"òN´¨°WÍñ*÷ÉÏ¥P>~Qä#‘顸GàÅÓr/ð‡À%L¥Ö[Íxø":-û–ƒ<¦�РXHè°¼øùˆiN@…°t 8J3}Ó_b¬I]®Š�„Òú(òs‡¸:E>¹—ÈýðšiB>¼¸ø€h¿•£™�”æ{ª2Upã}\3Ý„€?ž‰àfúµ4fœs¼¤ØfV#ùHùÈ )xmÀg�WN³“Àk�oÎ2‹¡Òæ„z€Ý„”ý8†SÝÿfæ, ”ÅPeNœL‰¶Ç3?ª|d–½ùÈô­kçOx �5a|ä¾™ñéÐ{zäWàwåû(=uQá£ÈG¢ÈGf¹¸Oø�?=mýÇE¯Ón‘4¡7wé†:õ¨‘{KûæøÅÅ34E>2ûI€�ZœJèZ÷àëñ㙑ü¨Ö²¯Û“6Sî÷)þ6¨m·›X”‰Ìz™ÛÑü�wLóøëÀ__‰Ï, ®{’¯Èwò_æ'~—®ôâþ¯M�mÔNß%šMª0‚ž2*<¾!,ÎaAUèO…Ž ´UÂÁdqV@+ò1’�"™C¢>�7?í÷ x'¡ø.†V�ä»ùaòîüûî‰�],8vÌ”:ÁüAÕ}ùCNFÖ/õ —(—©¡_À"B¡ÞâYjÀõðœqቓÂ`úæW„®Jó ]‡Íl•�AùÈÜz^|ú€sà€/Ä�hV¸û’ËõïòöÇWгO3¥3IÛ-5éÇÎ×ìȆWï`xÿvù齄©fA‹€åð£åÊ�4L"\QÜßyÀ÷ð>ÂØH+QϤ¹Ê§Ÿ­Ê�žÙáõßžKrj…ëËRÛ øIDATÚñ ‹dŠò¾Õ°¾×ëŸ>-p¤¸ÝtÀqC(Ô´…°’ýMƒ.R.^ª¡™Ð¡©RN(â\G^%˜èo 7ͼ�ßœa`ýÚ )ÿ~àh`îX¤Üq8ЫaˆP³ÿµp(ÖÁ±{…Æ„£kÂÒ ô¶ íPY�(ò‘(ò‘ûzÎ>_`%¬%ÿ;¡’> |ë›òœ[õ£ú7Ò‹øs}É|ï°ú ï9÷ì+¹í“ªŠ!ÃS'óp“ ¯A‡E!tHœ Lú»¸ò€ÇT"ßÄŸå„e�%pÓ å¦ÇN@{ñ|ã„Ú€�ÀÿÁï� OŽÎ…¥�Ð5Ohë†òâ©É�ш‰"?·®ðs€™=)¡‚þ­„ŠúÈC¶G?›°N?Á»dRÐWáB÷¬�÷l¼øçùeÝb§#ŠªA‘áµÊ°ê#Ø¡xºÒT ÑÞAWüÓƒ<¾9; XJ$4 Áõ�W®ï×°l@áPŒæ+\ l‡ã÷OÉ„U¹0Ø}B¹ʃsЈ*E>2K£÷&§ êÚ˜JÛÿ[Á×âG5 Œø&ý oÓˆ¾IàB7È{ôâm5Q•ãYÇ5øý)�D”ÌòO;E>2#y,¡¨nÞ41ú6aàLLÑϑ߭ðÇz-!+s…÷¼m˜áêðÜùÌušó:ýgGXØ \=í¸v¯T8¾ ˜Z XVdŽN ×Í¥‰çÒ¬Èì(nÛ€_ϽN«žÛ–f¢#›áD‘�̶è�ÂP}·ˆfšù€WÏD>¹ytŒè>ý>¯ÔŸo*¢Ú·¡L¬–Õ #„ sÒѺ¿Ÿ•�Áj ú¶‚=ý:²…ÐFØØ\ *²�žI(,Á%uÏ%µ øl+n·™��Á¡>½n8µGX4ÿQp¢ÈG‘�Ì"#'EDraa˜š\Gh€~6Ñq½ŒwèÅ„®…ÛŠïv"~ ®ì‘ ¸é �éº Û›KË[WdJÅÍÁE£ž‹F¦9[ŠçÝ Œ5ál„§Ïõß�#ÐE>E~nEïz@$¿¼ˆà—N»ï:àE…a9ôåVQä-“zïÓÿa;¯'¬!¿ª#�øÝ¢ŒÀ�×ÝhqÛTûÑ×c™°L6½8pIq}<½p’©أ|kLùÖnÂVÁà6à'Àî� À /¶ÂI8�οG Š|ùH ¤¦aQB»Ñ﫦]Øwg›9xg³hZIäkzçé—¸•7ŠÅÞ¸_àó»�<²ŽÀôŸëE”¾“PÈÇA¾—ŽBôç‡G™€eÀS E‚Íy{�ÝÊ7w)ßlÖl-œŒ-ÀØ”òúvḅ‚…Ð1{6¶!E>ÒÂB8¡¨î1Óî» 8‹�:l «k’âGø�¿‚Gf¿yCïæ‹ú~É[‹HïÕ„µøHk]«ûs2|)@»š­ƒ› ƒú�# ‡à(B¶®½È4»nR¾°SÖÁ… Øm}ùHkÒ4K�o ð·Rô€�†â­„‹ÿIÀ‡Šã~ËsOÏp€¹�x$ ïr6s�~œïóšÂhÿ1¡‘Ldvd¦_KZw^|Çw?›öøæü€v¦š-)¢õ¡"°ª¸¯}Úsî‰ùHë üàB5}“;€w¿‘Ðí6¶ÜLh2"› ¡X¨½ˆF EFK )ÂÝ…šG(ôj6Ú˜W<>›ƒbh߯cßñçñ_¼¬ø¼_~Î�KÓ�{Âr@��Æ_üß�¯ªÿÛ…�Ý…£ Ä%º(ò‘–øà;EdÞdðÂBà›Qøí„¡4ïŽ/<ü÷FâÀ þ\B Üaô¬0Õ¯¸œ0Án ¡Øè€|øpU4Ì«ÀïãGú!¾øÿÛ»›»Ê:Žã¿ A4„� ÝèÂn\èÄ•†˜HBƒZјå¥I |¡ Qd 1’XL1  Q ¡˜P_@lRR#V EjLK±›¦©ÂЩLïãânævhµuZ:÷ÞÏ'™´s‡¹´çLú=Ï9ÏyN>ÙH}^à9 3™[ÍòE›cry€Ãèzs’{’¼èµÝI>ÑE}þ‘ÿ#©ÉwK“ü´ Åà à”îcpûÝ{»hÿ.õ±õI–wg >›¹[Œ>“:møžî€ã%£¯ã¨Ÿé<ÕnÉê¶4u¿ö¥Ý˜f4Æa~�ö‘g‘{Kjíù †Fõ/%ùX’-Gøž·u#øéÔ¤�ÁYœ�$¹?õ°š³º‚ßwaŸI-�ÛKr}ê1µƒû‚�šôÎî=þØdLâÌîvÞñ@¶´[sK;/5éê²ÌÍÒ>FK̶‘gDœžº¾~ÑÐk¯¤V=ûËa"Ûºï¹.µÎ÷ªî``i÷õg» ?š:Õ?%u=c’/'ٞɼ?ˆr;ŽïÕÏöv{VµsR÷Miè ÀH~L &Â]9´ßfR§qû/83Éy©Õü)u[ÎíIö¤É™?"ýGæVñÚ›äWÝhýŽÔmxÛR�®M’'»?Ë“ZŒÃH~ï³³Ý�kÚ»Rs!¾.ð€‘üd~uøÁh{’«’<ü?¾w_7jehô¿'ɇ T¯ÕϽvkjIΤÖÜ>cèkSø6d²WY;>ÞÝ~œíí©³.7¤&Hˆü˜ê¥®‹/µ|é (R§Þï;Ê÷Ùw˜×¦�«ýó^{-‡Þ‚óÏî×t›“ЯeGîl¿ÍS¹0uýýzûùñ·,u½ýŒ¡QÝÚÔŠr³6ÏŒäg³;÷ö×çñ\�ä—In´o‘oM­L÷øÐk¦n�ûwœÊýÈÌÞü¬ÿPÖgYø¯¦Ö$°o�Æ5ùÅaoê)pë’<‘äï©Õí¦mš1ˆ|?/gCÿ¾<�O¥Vüš} ˆüä, { µFü#yýÊsŒbä[dS»7wå£ÝÜWR ˆü„E¢ŸšŒe"Öhí½v„×gót[“ï´óSÏ‚_éà x#¹&¿øb/ðã0’oégk»'ßlJ=Þ÷r�DÆ!úÛÛYÕ>˜zJß©§¼¡œ®‡…ëòÙŽöp®ig§é{u’ÙD€ÈÃhŽÛçÖ›ßÕÍŠöîÔ#y/N²ÓN§ëáxd¾Ÿýy®Ý•+Û;RwI|1É‹6 `$£ìÕìÈÆö‹ÜÑ.JÝù…x / ò0.ië“\›º6I’m6 °8]Ç®7ôûÓ“¬è~ixKÕFò0â¡ï¥ž;0›ä²$µY#yÛ’lN²<É›0’‡Ñ׺Qü�Rrz0’‡1 }y@ä‘DDy@ä‘Dyy@ä�Ѱ¤g€ÈcéÑ‘Dy@ä‘DDy@ä‘Dyy@ä‘Dy@ä@ä‘Dy@ä‘‘Dy@ä‘DDy@ä‘Dyy@ä‘Dy@ä@ä‘Dy@ä‘‘Dy@ä‘DDy@ä‘Dy˜pOw¿¶´6üzKÏÆ‘FÏT/I¦’œ“%½$é¥7¿ê*"Œ’^z-™jókÞþ/¦Òn²©@ä�ÒZ/IZ’›’ÞÖué=7ôÅúÚÁÖ�õ› "Œ “¶.ÉÖ${u ¾ßKúI25åT=L€ÿò;{™î› IEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/resources/gui/illustrations/3D_coordinate_system.svg0000644000175000017500000004155115143647637026667 0ustar00paynopayno beam x y z ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/illustrations/ctf_z1.png0000644000175000017500000001711014757047403023746 0ustar00paynopayno‰PNG  IHDRc}Ž~\ pHYs¯¯£¦ÈtEXtSoftwarewww.inkscape.org›î<ÕIDATxœí�y˜TŹðuά0, (¢(‹ "j4îÀ ŒŠâ¿ÄKL4ñšåªÌ Š¿ä³¿,7zp æ¢11ÉuâonLÀhÐÀŒ âî\ƒ‚ÀÌ03Ý}êþñÖ¡Ïô¬=t÷LÏÔïy晳֩>§ê­ª·Þ÷-‹ÅÒÉ�÷{8/‹¥9x ÐÀ¹©Üèd$;‹¥'(k�Aæ˜î¹ìX,–žâL`#Є�±ˆ08»Çrd±X²NX‚Tþà0süsì¬Ê—ÅbÉ2ÿüØ\¨À¹Ñˆ@8³òe±X²È8`9Ráÿé $s 9?+‹ù²X,YÄAz»€ÍÀ7:¸ö D œ‘…|Y,–,sðà!:ƒÁ�\?§g8_‹%‹!³MÀ;@yï‹„™É•ÅbÉ:¥À›@3p P˜Â½c�pZú³e±X²ÉP Ä�5Àän¤1§¦1_‹%Ëœ | Ô×n7Ó�„SÒ”/‹Å’EF�"•ø d–`o8ؤÕU�ƒÅbé(d*q°ønšÒ�€„iJÏb±d˜ Àß‘Š[ ŒHcÚ±ÁbÉ òý@#« Sƒ‡ azÒ¶X,iä. Ü gè‡"¡,•›ò2“‹ÅÒðÒKȾ£SJñ¬@È!–,Y’ßÔÔ4K)‹Çãùm]ã8Ní°Äãñ|ÇqŠü}¥ÔŽŠŠŠ?d(»–öi"5#£î`B_äÁ,ª««;6�—ïÞ½{šRªHkí*¥Ú¼^k�RªÞó e”R*�÷¹ßÕϰ=„t�ŠÓP®èº�²–Š9�Õ!t‡l: å ZkëË�ëÄ�oh{�aœ†ŽÓZû3Ùr²X²I6¢&A. „ Ó�Öú$­uq8 åv–¡Ï�é¨I¹ÕC: )¥ŽA¢ÇlTJý‡çy=â4” 8Ž£<ϳ:„Ü'Ó�V{¿@HvBºM¯i­ïéNC¹‚U*ö 2=dè}aÉ’%ùÍÍÍ_1ADZ9 E£Ñ^ã4”+xžgM—ûÙ2¤DÚBÐi¨©©išÖº…ÓÐ_|ñB8Ž¥û¹ý¥vÈÐ'è»C†{î¹g¿h4zB²Ó�Ö:—œ†r1©oз”ŠUüpŸ�.?ˆE �ÒzÛ¸¼bŽ{=¿°þwC÷}÷ÅÑ_ùÜ¿ö¥Mwí·n㘔ÒÏsãŽnf@wó—**/V€v2½šÎ\(ví¦zß+kÞ<8ôɤ ŽJÍþ"îŒ+÷ƒ·VÑÔ8xÔkGŸ•j:C¡Š�éN·=´Vy.ª¨ó+Óƒ§)tÝæb»]åî;v+¬Žù× ªèìÚ¸Çíª7¾rÐGJáÙ#‡l›´ßA®v”Ž+·iGQñ®O ‹ê‡gš¿½#¦ëU^v p4N£ÒyYÆxžnvd±UtŠ©ž‡>òýaƒ‡n=VÇÝ!�^¯tLá4 Z*‡ Ýz`SccH¡ŽI-í =Ïq”Ñe!0´VYsPÓ:Þ �@è{EÝÞÌÏ¿ˆ7ÔÕ«è‡E뇆œÆ’' à)§QyºeYTàÆ¼OR|Dv›ëG­ÛòñáßÑZOUJ�q­u­ã8µóæÍ[o×H/ÕÕÕî§Ÿ~:U)õ늊Š'ö&­HäÚ¹J©gÌøÓOÓ•?KJÌvüviÝ€?û�Ë€wÓ�~vB8n–Ë««« >ûì³£Ìl©ZëoVUUíX´hÑóJ©Õ9d]x6p ²šÎ÷€^•ç7ÞxC…B!¬ íøÓŽ À¿«€Ÿ×�ÀZà×ÀÓ@wzC=§Tœ={v3°X‡ûþÀ)À®ë6E"‘—´Ö«=Ï[µ`Á‚Þê°™}’^& F�¥‰Årr’¦´ƒ�]ˆ!Ú`»ùŸì!…y'0؆|‹Ñˆ7k°/ð0ÌÜû0)üǘkw Npï Þ°ã€W€Qæo-ðU ¬G¾ý&à3`*ð²yÞQÀ³À!ÀAÀ_€Ró{Öçï™gŸƒTîà àaàpà0³}†yMÀDà8àMà1ó»'Ã�€Y&o�ÕÀkt­’wK 8�_’ápØ›?þÛTVV^ì8Î7µÖK€AJ©kÇY‰Dî­ªªº¨ªªjtºŸ¿ŒA>2Àoz2#í …@^^^Zz¯¿þúp¤ÂM.¶˜S÷ ½?€Zà6¤Bm.F*Ñnàh`. g«_!• ó‰Ùö€ïGš4Ž.2Ûy&ýZsí b¶ßDzl‡ï#•çëf»ø‘¹¤5ý‰Ù®1é„4TÇ!qPÌ~o®ýðÿÌöcÀ…ÀHàoÀ±À4¤�bÎÝg®ý!Ò€ø¿û¤"W›÷s”ùýC!q›¹ö óü&ó»Î5yº4Á¸Eˆ€ÜÏÜsp2]£÷&Ì›7o32Fúã½÷ÞŠF£'"+}_k=7‰lV'OOÖȘê«JZ”§J¥%é+á0váSEâw…KYüW×aö¨¯¯w }!Ô† ÖÜ�TÌuÀæÔHáxøi oEZÒaàS¤åœk®ý ðW³ý3à ³}9Ò’~ÌF*ôV³þ�Ä;ÿÒƒø¶yÞf`&ðº¹w&RqîC* ÀÕ$ÜŠËÌ=_"ÂÀï!‡|ß*à·æÚï�hÇš{ꀃÍïsÌö6¤KïWìÙ�Wyˆyv3Òk©C*¢_)Ãæàkæÿ¯‘(^7™ýs€GáÐŒ”÷]ˆ`ú½y©4Ý=¶N å(�—;Ž³Ç€ XuÔu×Íq›šŽdò¸Rx©«i׈„~É�æAW}"ÞDôm²ö`¨ oLÉò°âÎ;ï,v]÷I­õÍóçÏÿÛÞ¤‰Dæ*¥fTTT\˜®üYRb " ŽNEéN¤>ü7"x»ËÙÀŸ‘¡Çæ®ÞÔcÎM—^zi#°XTJj­g|vÆEMƽP¸eËû/_~aó°a…l˨Úa*"  �áB œ<‡€G ÁZ³ÆÎ�;U(Â&µ¦Üý`†‚ZtQï)x4…F!›ø†I CÕÓÝCºD½sÈ�L-üO”% fÏf$|:Âápx1§œ2Ñqœ©¡uë¾ ðáEÝ™0á™T•’ŠjàfD¹¹X\&]Üd¾kþoBÆŸ­pàÍ|MÃVWƶYgüøñjûöíD£Q+’ØO*ýÁæÅl”†�†›ja~)ÜÛ“ùkßtùÉL낆müO`ßjù áp8ì!Ûo×H=µàã�c„1F)yM$Ù ”Z ´£ÞƳR26þ½³ñxÜ�ôÍ2ôvªÁ%Jå6ɇøI2î¦NTI…¿–? ¿Pðÿã¢ÍïM¡où2¤ƒ±ÖšœY.ä¹úê«¿ÄC%)%Ï.ªªªÚRUUõâgO<ñùÈ+peî€rˆÕH�8()Y¸°x»TzËž…)ØgD �yHÁO4ܬÀ«…c5Öœ¢pñihhPÅÅÅýf¡–ýa‚'J¶6i†W‘©O’…Aßê¯$ÍÙÛ[²ÕCH‰52/|Ÿ‚+KÅ+%‚JÉ`ÜÏófì8ôб#W¬à�¹s/ŒLšTì[JjhR-]N÷E”9�¤L|f+¸0Ó&'âè§Düg ѳ.Qðøi‰é¸”(,,T@¿q.‚�vËc2§jéùµ;\ôQpšù¿¶³k³LßuN•±ÜzDÁ-¥2¾W˜EXöXJŽ]»ökÀc^qñxàfßR²ù¦›ö+lhh¤yOý¾™Ÿn$Ðj¯‚iÜêÂŒ2™—îS`w-<ªá’u°¦.ôdÑ- U4í7á81ë}*xìY˜¤Ä®á·ƒéa€Z™q¸TÃóe2�×›°C€•buõWàÉi ±´‡=£Œä°»îZøòâÅ»üµšGŒ8¸±°pLä²ËîUJ­^°`Á÷�ðŸ0†Oµ0Þƒ‡¸0£¦v‰ÃCü¥þ®ÁóÄê­[¨h4ŠëºýB $³F(ùVnÎ+ë`ž¾ÆkøP|Oõ¾Ðõ͈ù¶‹g¥›ÜyѰ¯‚ «à:ß^UÃeb±F-,ÐpÒ¥GÃ-5°]ÃÓÓæ°]"h)ùL^Þ¸ØÐ¡…À®�7VÄb±ÃfÍšµuÖ¬YGUVV®¯Uj>0ȃ»ýùG 7zð¡ ‹jÀƒ_Õ@½‚:2šš«jÅ6>¢à�ò½˜gnllô?ro+Üg%¹" ÆÐ‰Îi%ŒÖÒ³¢à¬²š&î„àêM H?7‚†U¾Ô°Ò©âÀv�–{;£§‹/Î�ÏãpcRw_ÅbÎÿüóÆÊÊÊ¥yyyà„‚‚‚ú™3gNTJÝSUUµEUU½¨”:/9ÔÛ7Ø2lêd«@? 7"Öh{5<Ú¹s§3pàÀ~×CРVÁR 'k˜;½�S�8-ýØ_Áù¥ðLÖ2šV teþ}oõ ÓàCdœÙ‚éâ´�‹Åf477ß_RRr}CCÃqŽã”Ó<Ï;/ íˆD"«�Z¥ÔÚ)Û�žF ªÁ­5Ö‹A ù é®2]ôÝšYRRR‚Öšh´O¬[Ûejàç ¾­á§õ�ÿË߀±.(K8hõF2½œ[n„^Âéˆ.à!£”|x.;¡Pèp¥T©Öº 8KkÝXUUõb<_ÕÔÔ´æ†nØá'4ö× § ŸâbIïgéÌ´‰¸Ü¯â!ÔŠRðzà�eèœVŠ1ÙÓˆ›ñÅÓexÑ›Éô ÐýC ¬‚C=©líñ`\ÓI2¾íÁëÈ\öŒ¥äëæï>�Y ÜqœißRÒuÝšéW^ù-=ß2F~~¾ŠÅbýÆR±NÔÒ#x¯‚±µ�ó1h.‡�585Ò38RIO,^+AGö‡�3z×Ôc¦W€î! ïçc”¶Ð ×Ùö‚X'‚x•uHP)™l)‹Å:´”L7yyy*‹õ›iGdz:q/Þ�ü£]c˜ô 8®)Z„s+툻ñ¥ÍmjdZ tk(’sÁhé?Ü‹$¾‰(0c$‚dt‰ö,%�ó•R{,%3µþD}}½ãºn¿24ÁŸ ÅE¸M´q?ŸñU\ë¦1XÉ”@( q%¶Ð2àJ§äœ@HeˆsÕ‚R&É}Ûݼyód¥T¹ÖzºÖú¼P(´3‰¼¬Ù¾}{�‰A¹WD£Qåºn¿™e0��Vdc¶Üåx½_‡�N¥b9p7Ò£ºѹ¤³£? „‹Ó� Y™ú5àµ`LI­u9P …®õcJ–””¬š3gN·‚;”””ô·!C_&�=„€Ÿ#ÑŸj€o!å1eú£@È(A÷mà_)©”*WJ]SWWwMP)y¥(%»D,S@¿é!ôqÒ!ò‘�?Atg— ¡áº]>¬@È0í)%µÖ)+%]×Uñxœx€ÖÚ�ÄìJ©"D àh­*¥öœóF\çȾç#ž¸‹¥Ÿñ¢XÜ�¬0VÜñåKöù:²ì¹¥5cE_º*îH‡ÃÒ”žÅ’v~Oï�6ÔSœ†ŒñGtva¿Nhãx‡.Û]dbµ˜ü9íɬKCÚg#li! wþ$Zm#Qh‰šK›é&dqÔ?#RÉ�jü 08+�ö8dúä$ऒ\‹cŒG´ªç «3ÿÊ«Gºdw MZã�ß™´Lî*ÉLLûL2¼ùˆéië 0ç1û¯!Qƒƒ¦Ê¥Èwz 6év¾ŠÚsÍý¯"ßÑgKòIàH`*òý¡óÅhâLs, »–ÞÚ<Ý„�èZ%t¼ºØ�Èû)^ž'aR|ªù?³Š²ì{£ÙÞß/A¾÷jZ›#BV:;™™xØŒ”£a&-?í À§f{_sß0ä{=E˲tß ½“i&O È-–"àq¤"¾JËÓ+·éÿBÞg#²â�¸f9R©ßEÁzdÎz&"`_B>|œ–AI�DÞÿïAýŸÈRä›h¹¢uò�a€yÎN¤!X‰XA^™ò¯Ï-&"e3òη ß/yÈp9ÒP¾‚¼÷:äûúF¾pøÌêb$ü~Q(®7÷î4Ï z@–!B` òÝÿ�,w e§9ï§}¶9wbÞü–¾äA»†ç€eHxÑið!â0Ñ®ÉðMIÇç!Î_59�psÒuäÅ·7 øºyÖȤã?¥wÍ쌡ˆt>=éø�Àö˜¤sG!…íÌÀ±åH…<Ùì;H‹QGbNà‡æ˜/è}�°–„Eãp¤§±4p_²@¸©A¡1BÒwyx™ÄêÓû!'(ŽA¾Epåò‰ˆÁÑ¿ŽyÀEIéOBÞáüÀ±1$zјgoE…`ý.Xü4­—-hÒyŒ„µêdD@ܸî9¤níY?ÓAÖ*¸i™~LOzp­£?gîmk\Ô/'í ¼Hû‹ULF^ÜbëT#«;Ïï)âæït=!�Âã³ é:ƒt÷EZñ¯$¥õ ‰oâ!­Kp[àš'‘‚‘\iï¬�˜ÅÞGÇQ£/@"¤YŠ4S;¸/—„ î c` w ÈlD þ*pì]¤÷us�IsQàØ&¤§ìß{ "|*iY?:‹)z2"ìL"¦âàa†}žFz€€tknE Ïù&#×"݈ HH—ä`¡þCòi·�ãõIûÍt2dîyª�s¹ä¼ ¸ ‘Еˆ^eRÈ|'¤+�PXuˆ ð¡°_RZŸ$í×!ÝÈÆ¤c�há|Þmc¿R[“Î!e¡És�d®/2Ñ›$/EŸ¬79y?ï'† :âä�'ß;”Äw˜ˆ”›ÎÒJf-ד|/x�?ÎyÙüÝ„(ªª‘–ùD‰ŒC|ü0è~bÛ‘.P� ]Ìü[ˆ2²½E/ßF^Ò2ZØ\c ¢¯™ŽtÓ~Œ(�ÎB†X‹‘PáAG–7ÚH§-AØU¿ø�Iû%æÞdA R)âÕV„ênņÌüÖ¸(éxò°6Ñ´5í×™�zRö¿ÑÆ9¿�¬GœŸR]Ö��QD¢aÉSRZ-òé côü¤c •¼Qp- 1¾…ŒOŸ!¡Ñ@û]Ûá´Ö;´ÇoMÚ?¡å4èd³ýRðþ�„Τå<•Üc7¢¸y�3‘î»6?¸ö º.X»JYÒ~)ÒJµ5dÛ�(›N@Z©ä¿Îf'r•‘Š”<$JÞ_‹”Ó´~7Á!V#­{ÓkI(Ô“ïõãl®GŒ3:Èk#­Ã°ù=›iIÇËh»�iAòa×!¿ ø¿�ó#͹s¾ézŒ \S€h0›Ì·#AÚR*&+Õ¾‡|€­ˆ–|ðPàü H¡­Cz2ï’ðËEB_}y€¿’>i~†Œ�FBÅï¢å8s9­˜™�¬0�ü<�jH(7#�ÀH¤7ÒHËu0“•Šç =’EˆÐÚù·ÒÒŽ¤¯ñsDÇ2iYg#å2¨TÜQˆ?ƒ|Wˆu1-õ2ÿ@f€NF¾GÒ¸mB¾ññæÞш•¨\!S” ÃùH#17�öˆñ§…‡›û^@z×Çšg]�|ÇK÷>G˲H—äd“‘siÛðÈAZ’o!Ó�méò�®ðl“é<¤ÀøþÞ®ÙoÏìs˜yþ·�ç$�ÏG$Ü·�©•ÑäcHM�´´ìÌA„©F´ÄW�Òröà׈ò7È¥ˆb6ÈxDˆaö}�ðm$ŸF„ü-´|×U´œuù.¯˜{4¢h{ }•bD8Ƒ߼10ÚFKùC\ŒÄûÙ@KåÝI$l¶‘(»ãA Üû-—¡†(›Íù8% ¢_ú#"4¶! �ôäÿÈÿvZ/qø$"ø,=Lˆö•®þùtG³ò‚/ “zÄßô?ÿü]³Î€ôš»ãçPŒ‡Ž,p‹ºpM[ &Ñ@[,{HK+’»å‹¥ó¿uÝm+áãIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/illustrations/ctf_z1.svg0000644000175000017500000010674014757047403023771 0ustar00paynopayno image/svg+xml 1 v / ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/illustrations/flow_down.png0000644000175000017500000000104714757047403024560 0ustar00paynopayno‰PNG  IHDRz�ûbsBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î<¤IDATX…핽JA…¿Ä€¢•ZYøÑÎF,¬DˆUË<��ï#Ÿ@\ ‚¤6ˆ/ `!XX)ŠnÆbïÀdvf6FY3†ý9÷ì½÷Ìì øÑŽ|d5 â +E„jœŒ%FsˆæÍ™„0º@4ÇEAs g,‘0šà¢9n¬­£$®þÍöÍ àwÍ)ÙùÍùia<\4'ÀMƒ9ÓpNƒ9“ë±^@·^�O€Ëœmà  \ Ð!S¸®–€øšFЉ �¦Ä¤À²~Ù%s1Zᾈ”ÄRâ Ø’žÚ ºÝ’wºßs³öº|M}·@ÏxÖüšÝøƒA*ëCúþQ›%%Ò£ ]b œ:xv=ͱçίÑ;0ï*õ¸¾M…{s !›–yÌW™+ ºhŽÕ�àFJ3§ãÎrý�‰õ¬ðLƒ� G™›£+À“!z!3gh©Šl!+ã>·¢|{NG2W°þ†aX�,}`ÑàšlÈ–^˜#ëqd!À±�ȹeทkßð€!Œ¾AOIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/illustrations/flow_down.svg0000644000175000017500000000762314757047403024601 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/illustrations/flow_right.png0000644000175000017500000000102314757047403024720 0ustar00paynopayno‰PNG  IHDRzàê3sBIT|dˆ pHYs 6 6+=tEXtSoftwarewww.inkscape.org›î<�IDATX…í×ÁKTQÇñ�:!H .‚vA›VŠ-Ú¶#¤MÿA¸ Â� þ ‚ ´©E‹ U´¨…â?àÐÂ)4³F�÷ 3R÷=lÞ(÷ —wáž{Ïy÷÷νï Iô “XÆ(¾á¨Üp½ä þ �,aƒe•è 38A³£}Ç,àvy¡%.›9A캶اٳŽm¼Æ””íWž§‚¸�b·Z]8Þ›ØÃžáV�&ºgÁyQc­3Û·ð h-4 {nâFÎø0FrƇ0Vàc,³û_í#Ù:1ÊŠó̉±�÷xWAU¾à×ù8¨ã Àf_ȨG¨åŒŸà°ÀÇ�HÆ ævÒÔÖò'>á-¾V°êo¡ æq lTŒßB©ã¢ð/³ubÔ\ízôæ lNQÉú»ø€�Ø„Oô9óâ÷sëN®á3^ân9a&ºaV³%rCûﻊõ̦è¾Oô1�qì|ïb¥ºùZð¿„lþ‚EÜ+3 Äåskx®•ΫýpeCçõIEND®B`‚././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/illustrations/flow_right.svg0000644000175000017500000001021314757047403024734 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/resources/gui/illustrations/no_rot.svg0000644000175000017500000010101214757047403024066 0ustar00paynopayno image/svg+xml ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9811025 tomwer-1.6.17/src/tomwer/synctools/0000755000175000017500000000000015153325403016363 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/synctools/__init__.py0000644000175000017500000000035314757047403020507 0ustar00paynopayno""" Contains tools used by the orange add-on and used to keep the orange-add-on and gui 'alive', avoid gui freeze during processing. With time it should be replace by the ewoksorange mechanism (inheritance to ewoksorange widgets) """ ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/synctools/axis.py0000644000175000017500000000120215153325210017670 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging from silx.gui import qt from tomwer.core.process.reconstruction.axis.params import AxisRP logger = logging.getLogger(__name__) class QAxisRP(AxisRP, qt.QObject): sigChanged = qt.Signal() """Signal emitted when at least one element of the dictionary change""" sigAxisUrlChanged = qt.Signal() """Signal emitted when the axis url change""" def __init__(self): qt.QObject.__init__(self) AxisRP.__init__(self) def changed(self): self.sigChanged.emit() def axis_urls_changed(self): self.sigAxisUrlChanged.emit() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9811025 tomwer-1.6.17/src/tomwer/synctools/bliss_sync/0000755000175000017500000000000015153325403020533 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/synctools/bliss_sync/_QThreadListenerBase.py0000644000175000017500000000216715115744275025115 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt class QThreadListenerBase(qt.QThread): """ This class defines the API for a QThread listening to blissdata. Interface is defined by signals emitted and the constructor signature. The goal is to be able to connect it with the DataListenerWidget """ sigAcquisitionStarted = qt.Signal(tuple) """Signal emitted when an acquisition is started. Tuple is: (master_file, master_entry)""" sigAcquisitionEnded = qt.Signal(tuple) """Signal emitted when an acquisition is ended. Tuple is (master_file, master_entry, succeed)""" sigScanAdded = qt.Signal(tuple) """Signal emitted when a scan is added to an acquisition. Tuple is (master_file, master_entry, scan_entry)""" sigServerStop = qt.Signal() """Signal if the rpc-server have been turn off""" def __init__(self, host, port, acquisitions): super().__init__() def join(self, timeout=None): if timeout is None: self.wait() else: self.wait(timeout) def stop(self): raise NotImplementedError("Base class") ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/synctools/bliss_sync/__init__.py0000644000175000017500000000000015115744275022644 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/synctools/bliss_sync/blissdata_listener.py0000644000175000017500000001035315143647637025001 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging import socket from ._QThreadListenerBase import QThreadListenerBase _logger = logging.getLogger(__name__) try: from blissdata.redis_engine.store import DataStore from blissdata.redis_engine.scan import ScanState from blissdata.beacon.data import BeaconData try: from blissdata.exceptions import NoScanAvailable except ImportError: from blissdata.redis_engine.exceptions import NoScanAvailable except ImportError: _logger.warning("blissdata not installed. Cannot run the Blissdata Listener.") has_blissdata = False else: has_blissdata = True _logger = logging.getLogger(__name__) class BlissDataListenerQThread(QThreadListenerBase): """Implementation of the _BaseDataListenerThread with a QThread. On this use case we use directly blissdata (requires Bliss version 2.0 or higher) # note: on bliss-tomo: # a sequence starts that triggers other scans. # then those scans starts and end... # and then only the parent sequence ends. # so the listener must be started before the sequence starts... which is already the case. ..warning:: this thread will never trigger 'sigScanAdded' or 'sigServerStop' as the first one is indeed never used at the moment and the second one is a specific feature for the json-rpc mechanism """ def __init__(self, host, port, acquisitions): super().__init__(host=host, port=port, acquisitions=acquisitions) self._host = host self._port = port self._stop = False if not has_blissdata: raise RuntimeError("'blissdata' not installed. Cannot create the listener") try: self.createDataStore() except socket.gaierror as e: _logger.error( f"Fail to connect to host: {self._host}:{self._port}", exc_info=e, stack_info=True, stacklevel=3, ) self._canConnect = False else: self._canConnect = True def createDataStore(self): self._beacon_client = BeaconData(host=self._host, port=self._port) self._redis_url = self._beacon_client.get_redis_data_db() self._data_store = DataStore(self._redis_url) def run(self): if not self._canConnect: return while not self._stop: try: _, key = self._data_store.get_next_scan(timeout=1) except (TimeoutError, NoScanAvailable): # not: Today the `NoScanAvailable` will be raised in case of a time out. continue except Exception as e: raise Exception("Failed to access next scan.") from e scan_sequence = self._data_store.load_scan(key) if not self.isBlissTomoScan(scan_sequence=scan_sequence): _logger.warning( f"Scan {scan_sequence} is not recognized as a bliss-tomo acquisition. It will be ignored." ) continue saving_file = scan_sequence.info["filename"] entry = scan_sequence.info["scan_nb"] proposal_file = scan_sequence.info["nexuswriter"]["masterfiles"]["proposal"] sample_file = scan_sequence.info["nexuswriter"]["masterfiles"][ "dataset_collection" ] self.sigAcquisitionStarted.emit( (saving_file, entry, proposal_file, sample_file) ) while scan_sequence.state < ScanState.CLOSED: if self._stop: return scan_sequence.update() succeeded = scan_sequence.info["end_reason"] == "SUCCESS" self.sigAcquisitionEnded.emit( (saving_file, entry, proposal_file, sample_file, succeeded) ) @staticmethod def isBlissTomoScan(scan_sequence) -> bool: """Check if the scan sequence is a bliss-tomo sequence""" tomo_config_group = scan_sequence.info.get("technique", {}).get( "tomoconfig", None ) return tomo_config_group is not None def stop(self): self._stop = True self._beacon_client = None self._redis_url = None self._data_store = None ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/synctools/bliss_sync/datalistener.py0000644000175000017500000001716515153325210023572 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging import time from collections import namedtuple from datetime import datetime from multiprocessing import Lock, Manager from silx.gui import qt from tomwer.core.process.control.datalistener.rpcserver import ( BlissAcquisition, TangoAcquisitionStatus, _BaseDataListenerThread, ) from tomwer.utils import docstring from ._QThreadListenerBase import QThreadListenerBase _logger = logging.getLogger(__name__) class DataListenerQThread(_BaseDataListenerThread, QThreadListenerBase): """Implementation of the _BaseDataListenerThread with a QThread. As jsonrpc is using gevent we want to limit the 'crossover' of gevent and qt. So the server is launch in another process and bot processes are sharing list of acquisitions (added, ended...). """ _WAIT_BTW_COLLECT = 0.5 def __init__(self, host, port, acquisitions): qt.QThread.__init__(self) _BaseDataListenerThread.__init__( self, host=host, port=port, acquisitions=acquisitions ) self._manager = Manager() self._lock = Lock() self._sequence_started = self._manager.list() self._sequence_ended = self._manager.list() self._scan_added = self._manager.list() self._stop = False @docstring(_BaseDataListenerThread.sequence_started) def sequence_started(self, acquisition: BlissAcquisition) -> None: assert isinstance(acquisition, BlissAcquisition) with self._lock: self._sequence_started.append( ( acquisition.master_file, acquisition.entry, acquisition.proposal_file, acquisition.sample_file, ) ) def _collect_sequence_started(self): with self._lock: for scan in self._sequence_started: master_file, entry, proposal_file, sample_file = scan self.sigAcquisitionStarted.emit( (master_file, entry, proposal_file, sample_file) ) self._sequence_started[:] = [] @docstring(_BaseDataListenerThread.scan_added) def scan_added(self, acquisition: BlissAcquisition, scan_number: int) -> None: assert isinstance(acquisition, BlissAcquisition) with self._lock: self._scan_added.append( ( acquisition.master_file, acquisition.entry, acquisition.proposal_file, acquisition.sample_file, scan_number, ) ) def _collect_scan_added(self): with self._lock: for scan in self._scan_added: master_file, entry, proposal_file, sample_file, scan_number = scan self.sigScanAdded.emit( (master_file, entry, proposal_file, sample_file, scan_number) ) self._scan_added[:] = [] @docstring(_BaseDataListenerThread.sequence_ended) def sequence_ended(self, acquisition: BlissAcquisition) -> None: assert isinstance(acquisition, BlissAcquisition) with self._lock: self._sequence_ended.append( ( acquisition.master_file, acquisition.entry, acquisition.proposal_file, acquisition.sample_file, not acquisition.has_error, ) ) def _collect_sequence_ended(self): with self._lock: for scan in self._sequence_ended: master_file, entry, proposal_file, sample_file, success = scan self.sigAcquisitionEnded.emit( (master_file, entry, proposal_file, sample_file, success) ) self._sequence_ended[:] = [] @docstring(_BaseDataListenerThread.sequence_failed) def sequence_failed(self, acquisition: BlissAcquisition): assert isinstance(acquisition, BlissAcquisition) with self._lock: self._sequence_ended.append( ( acquisition.master_file, acquisition.entry, acquisition.proposal_file, acquisition.sample_file, False, ) ) def start(self): _BaseDataListenerThread.start(self) qt.QThread.start(self) def stop(self): _BaseDataListenerThread.stop(self) self._stop = True self.join() def _make_sure_server_still_running(self): if not self._server.is_alive(): self.sigServerStop.emit() def run(self): while not self._stop: try: self._collect_sequence_started() self._collect_scan_added() self._collect_sequence_ended() self._make_sure_server_still_running() except Exception as e: _logger.error(e) break else: time.sleep(DataListenerQThread._WAIT_BTW_COLLECT) _mock_acquisition_info = namedtuple( "_mock_acquisition_info", ["master_file", "entry", "scan_numbers", "waiting_time"] ) class MockDataListenerQThread(DataListenerQThread): """ Overwrite run() function and mock an acquisition for CI avoiding to have a tango server and tango install. """ def __init__(self, host, port, acquisitions: list, mock_acquisitions: list): DataListenerQThread.__init__( self, host=host, port=port, acquisitions=acquisitions ) assert isinstance(mock_acquisitions, (list, tuple)) for acqui in mock_acquisitions: assert type(acqui) is _mock_acquisition_info self.mock_acquisitions = mock_acquisitions "waiting time between each scan / step of the acquisition" def get_device(self, device_name): return None def run(self) -> None: _logger.info("mock an acquisition using tango / tango") for mock_acqui in self.mock_acquisitions: if self._stop: return # first scan is the definition of the acquisition now = datetime.now() current_acquisition = BlissAcquisition( file_path=mock_acqui.master_file, entry_name=mock_acqui.entry, start_time=now.strftime("%H:%M:%S"), proposal_file=None, sample_file=None, ) self.acquisitions.append(current_acquisition) self.sequence_started(current_acquisition) time.sleep(mock_acqui.waiting_time) # add scan numbers if any for scan_number in mock_acqui.scan_numbers: current_acquisition.add_scan_number(scan_number) current_acquisition.set_status(TangoAcquisitionStatus.ON_GOING) self.scan_added( acquisition=current_acquisition, scan_number=scan_number ) if self._stop: return time.sleep(mock_acqui.waiting_time) # end acquisition now = datetime.now() current_acquisition.end( end_time=now.strftime("%H:%M:%S"), succeed=True, error=None ) self._rpc_sequence_ended( saving_file=current_acquisition.sample_file, sequence_scan_number=current_acquisition.entry, success=True, ) time.sleep(mock_acqui.waiting_time) # wait until stop the thread while not self._stop: time.sleep(0.1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/synctools/darkref.py0000644000175000017500000000076215153325210020354 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging from silx.gui import qt from tomwer.core.process.reconstruction.darkref import params as dkrf logger = logging.getLogger(__name__) class QDKRFRP(dkrf.DKRFRP, qt.QObject): sigChanged = qt.Signal() """Signal emitted when at least one element of the dictionary change""" def __init__(self): qt.QObject.__init__(self) dkrf.DKRFRP.__init__(self) def changed(self): self.sigChanged.emit() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/synctools/datatransfert.py0000644000175000017500000000102615153325210021572 0ustar00paynopayno# coding: utf-8 from __future__ import annotations from silx.gui import qt from tomwer.core.process.control.scantransfer import ( ScanTransferTask as FolderTransfertP, ) from tomwer.core.scan.scanbase import TomwerScanBase class ScanTransfer(qt.QObject, FolderTransfertP): scanready = qt.Signal(TomwerScanBase) """emit when scan ready""" def __init__(self, parent=None, inputs=None, varinfo=None): qt.QObject.__init__(self, parent) FolderTransfertP.__init__(self, varinfo=varinfo, inputs=inputs) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/synctools/imageloaderthread.py0000644000175000017500000000263014757047403022411 0ustar00paynopaynofrom __future__ import annotations import logging import os import numpy.lib.npyio from silx.gui import qt import tomwer.resources from tomwer.io.utils import get_slice_data logger = logging.getLogger(__name__) class ImageLoaderThread(qt.QThread): """Thread used to load an image""" IMG_NOT_FOUND = numpy.load( tomwer.resources._resource_filename( "%s.%s" % ("imageNotFound", "npy"), default_directory=os.path.join("gui", "icons"), ) ) def __init__(self, url, *args, **kwargs): """ :param index: index of the image on the stackplot :param filePath: filePath is the file to load on stackplot reference. It can be an .edf file or a .vol file. If this is a vol file then the name is given with the slice z index to be loaded. """ super().__init__(*args, **kwargs) self.data = None self.url = url def getData(self): if hasattr(self, "data"): return self.data else: return None def run(self): if os.path.exists(self.url.file_path()) and os.path.isfile( self.url.file_path() ): self.data = get_slice_data(self.url) else: logger.warning("file %s not longer exists or is empty" % self.url) self.data = self.IMG_NOT_FOUND ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/synctools/rsyncmanager.py0000644000175000017500000001146115153325210021425 0ustar00paynopayno# coding: utf-8 """ This module is used to manage the rsync between files for transfert. """ from __future__ import annotations import logging import time from rsyncmanager import RSyncManager from silx.gui import qt logger = logging.getLogger(__name__) class RSyncWorker(qt.QThread): """Thread which call for a synchronization on a folder each n seconds""" def __init__(self, src_dir, dst_dir, delta_time): qt.QThread.__init__(self) self._src_dir = src_dir self._dst_dir = dst_dir self._delta_tile = delta_time self._stop = False def stop(self): self._stop = True def _process_sync(self): RSyncManager().sync_file( source=self._src_dir, target=self._dst_dir, delete=False ) time.sleep(self._delta_tile) def run(self): while not self._stop: self._process_sync() class BlissSequenceRSyncWorker(RSyncWorker): """Thread to synchronize a bliss sequence""" def __init__( self, src_dir, dst_dir, src_proposal_file, dst_proposal_file, src_sample_file, dst_sample_file, delta_time, ): super(BlissSequenceRSyncWorker, self).__init__( src_dir=src_dir, dst_dir=dst_dir, delta_time=delta_time ) self._bliss_master_file = src_proposal_file self._dst_bliss_master_file = dst_proposal_file self._bliss_sample_file = src_sample_file self._dst_bliss_sample_file = dst_sample_file def _process_sync(self): super(BlissSequenceRSyncWorker, self)._process_sync() if self._bliss_master_file is not None: RSyncManager().sync_file( source=self._bliss_master_file, target=self._dst_bliss_master_file ) if self._bliss_sample_file is not None: RSyncManager().sync_file( source=self._bliss_sample_file, target=self._dst_bliss_sample_file ) class BlissSequenceRSyncWorkerFinalizer(qt.QThread): def __init__( self, source_scans, target_scans, proposal_file, target_proposal_file, sample_file, target_sample_file, nx_file, target_nx_file, block, callback, callback_parameters, parallel, delta_time=0.5, ): self._sources_scans = source_scans self._target_scans = target_scans self._proposal_file = proposal_file self._target_proposal_file = target_proposal_file self._sample_file = sample_file self._target_sample_file = target_sample_file self._nx_file = nx_file self._target_nx_file = target_nx_file self._block = block self._callback = callback self._callback_parameters = callback_parameters self._parparallel = parallel self._n_callback_scans = 0 self._n_callback_proposal = 0 self._n_callback_sample = 0 self._delta_time = delta_time def scan_transfert_completed(self): return self._n_callback_scans == len(self._sources_scans) def proposal_file_completed(self): if self._proposal_file is None: return True else: return self._n_callback_proposal == 1 def sample_file_completed(self): if self._sample_file is None: return True else: return self._n_callback_sample == 1 def transfert_completed(self): return ( self.proposal_file_completed() and self.sample_file_completed() and self.scan_transfert_completed() ) def _callback_scans(self, *args, **kwargs): self._n_callback_scans = self._n_callback_scans + 1 def _callaback_sample_file(self, *args, **kwargs): self._n_callback_sample = 1 def _callback_proposal_file(self, *args, **kwargs): self._n_callback_proposal = 1 def run(self): # no callback if self._sample_file is not None: RSyncManager().sync_file( source=self._sample_file, target=self._target_sample_file ) if self._proposal_file is not None: RSyncManager().sync_file( source=self._proposal_file, target=self._target_proposal_file ) for scan_in, scan_out in zip(self._sources_scans, self._target_scans): RSyncManager().sync_file( source=scan_in, target=scan_out, callback=self._callback_scans, delete=True, ) while not self.transfert_completed(): time.sleep(self._delta_time) if self._callback: if self._callback_parameters is not None: self._callback(*self._callback_parameters) else: self._callback() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/synctools/saaxis.py0000644000175000017500000000123515153325210020222 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging from silx.gui import qt from tomwer.core.process.reconstruction.saaxis.params import SAAxisParams logger = logging.getLogger(__name__) class QSAAxisParams(SAAxisParams, qt.QObject): sigChanged = qt.Signal() """Signal emitted when at least one element of the dictionary change""" sigAxisUrlChanged = qt.Signal() """Signal emitted when the axis url change""" def __init__(self): qt.QObject.__init__(self) SAAxisParams.__init__(self) def changed(self): self.sigChanged.emit() def axis_urls_changed(self): self.sigAxisUrlChanged.emit() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/synctools/sadeltabeta.py0000644000175000017500000000126615153325210021207 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging from silx.gui import qt from tomwer.core.process.reconstruction.sadeltabeta.params import SADeltaBetaParams logger = logging.getLogger(__name__) class QSADeltaBetaParams(SADeltaBetaParams, qt.QObject): sigChanged = qt.Signal() """Signal emitted when at least one element of the dictionary change""" sigAxisUrlChanged = qt.Signal() """Signal emitted when the axis url change""" def __init__(self): qt.QObject.__init__(self) SADeltaBetaParams.__init__(self) def changed(self): self.sigChanged.emit() def axis_urls_changed(self): self.sigAxisUrlChanged.emit() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9811025 tomwer-1.6.17/src/tomwer/synctools/stacks/0000755000175000017500000000000015153325403017653 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/synctools/stacks/__init__.py0000644000175000017500000000024514757047403021777 0ustar00paynopayno""" Contains the stack managed by qtSignals and used by the Orange add-on in order to insure 'parallel computation' of the different process and keep gui alive. """ ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9811025 tomwer-1.6.17/src/tomwer/synctools/stacks/control/0000755000175000017500000000000015153325403021333 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/synctools/stacks/control/__init__.py0000644000175000017500000000000014757047403023444 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/synctools/stacks/control/datalistener.py0000644000175000017500000000712115153325210024361 0ustar00paynopayno# coding: utf-8 from __future__ import annotations from silx.gui import qt from tomwer.core.process.control.datalistener import DataListener from tomwer.core.scan.blissscan import BlissScan from nxtomomill.models.h52nx import H52nxModel from ..processingstack import FIFO, ProcessingThread import logging _logger = logging.getLogger(__name__) class DataListenerProcessStack(FIFO, qt.QObject): """Stack of file conversion once received by the data-listener from a bliss file and a specific entry""" def __init__(self, parent=None): qt.QObject.__init__(self, parent=parent) FIFO.__init__(self, process_id=-1) self._results = {} def _process(self, data, configuration, callback=None): assert isinstance(data, BlissScan) assert isinstance(configuration, H52nxModel) _logger.info(f"DataListenerProcessStack is processing {data}") self._data_currently_computed = data self._computationThread.finished.connect(self._end_threaded_computation) self._computationThread.init(data=data, configuration=configuration) # need to manage connect before starting it because self._computationThread.start() def _end_threaded_computation(self, callback=None): self._computationThread.finished.disconnect(self._end_threaded_computation) super()._end_threaded_computation(callback=callback) def _create_processing_thread(self, process_id=None) -> qt.QThread: thread = _DataListenerConverterThread() thread.setParent(self) return thread def _end_computation(self, data, future_tomo_obj, callback): """ callback when the computation thread is finished :param scan: pass if no call to '_computationThread is made' """ if callback is not None: callback() if data in self._results: nx_scan = self._results[data] del self._results[data] else: nx_scan = None self.sigComputationEnded.emit(nx_scan, None) self._processing = False if self.can_process_next(): self._process_next() def register_result(self, bliss_scan, nx_scan): self._results[bliss_scan] = nx_scan class _DataListenerConverterThread(ProcessingThread): """ Thread use to execute the processing of nxtomomill """ def __init__(self): ProcessingThread.__init__(self) self._scan = None self._configuration = None def init(self, data, configuration): if not isinstance(data, BlissScan): raise TypeError(f"Only manage BlissScan. {type(data)} is not managed") assert isinstance(configuration, H52nxModel) self._scan = data self._configuration = configuration def run(self): self.sigComputationStarted.emit() _logger.processStarted(f"Start conversion of bliss scan {self._scan}") data_listener = DataListener() data_listener.set_configuration(self._configuration or {}) try: scans = data_listener.process_sample_file( sample_file=self._scan.master_file, entry=self._scan.entry, proposal_file=self._scan.proposal_file, master_sample_file=self._scan.saving_file, ) except Exception as e: _logger.processFailed( f"Conversion of bliss scan {self._scan}. Reason is {e}" ) scans = None else: _logger.processSucceed(f"Conversion of bliss scan {self._scan}.") self.parent().register_result(self._scan, scans) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/synctools/stacks/processingstack.py0000644000175000017500000001350715153325210023431 0ustar00paynopayno"""Define some processing stack""" from __future__ import annotations from collections import deque from tomwer.core.tomwer_object import TomwerObject from silx.gui.utils import blockSignals from processview.core.manager import DatasetState, ProcessManager from processview.core.superviseprocess import SuperviseProcess from silx.gui import qt class ProcessingThread(qt.QThread): """Class for running some processing""" sigComputationStarted = qt.Signal() """Signal emitted when a computation is started""" sigError = qt.Signal(str) """Error found during processing. Parameter is the error raised""" class FIFO(SuperviseProcess): """Processing Queue with a First In, First Out behavior""" sigComputationStarted = qt.Signal(object) """Signal emitted when a computation is started""" sigComputationEnded = qt.Signal(object, object) """Signal emitted when a computation is ended. First parameter is mandatory and is the scan computed. Second one is an optional FutureTomwerScan""" def __init__(self, process_id=None): SuperviseProcess.__init__(self, process_id=process_id) self._errors: list[qt.QErrorMessage] = [] self._deque = deque() self._computationThread = self._create_processing_thread(process_id=process_id) assert isinstance(self._computationThread, ProcessingThread) """scan process by the thread""" self._data_currently_computed = None """Scan computed currently""" self._processing = False # connect signal / slot self._computationThread.sigComputationStarted.connect( self._start_threaded_computation ) self._computationThread.sigError.connect(self._displayError) @property def data_currently_computed(self) -> TomwerObject | None: return self._data_currently_computed def add(self, data, configuration=None, callback=None): """ add a scan to process :param data: data to process :param configuration: configuration of the process :param callback: function to call once the processing is Done """ try: if self.process_id not in (None, -1): ProcessManager().notify_dataset_state( dataset=data, process=self, state=DatasetState.PENDING, ) except Exception: pass self.append((data, configuration, callback)) if self.can_process_next(): self._process_next() def _process(self, data, configuration, callback): raise NotImplementedError("Virtual class") def _process_next(self): if len(self) == 0: return self._processing = True data, configuration, callback = self.pop() self._process(data=data, configuration=configuration or {}, callback=callback) def can_process_next(self): """ :return: True if the computation thread is ready to compute a new axis position """ return not self._processing def _end_computation(self, data, future_tomo_obj, callback): """ callback when the computation thread is finished :param scan: pass if no call to '_computationThread is made' """ if callback is not None: callback() sender = self.sender() # pylint: disable=E1101 if hasattr(sender, "future_tomo_obj"): future_tomo_obj = sender.future_tomo_obj else: future_tomo_obj = None self.sigComputationEnded.emit(data, future_tomo_obj) self._processing = False if self.can_process_next(): self._process_next() def _create_processing_thread(self, process_id=None) -> ProcessingThread: raise NotImplementedError("Virtual class") def is_computing(self): """Return True if processing thread is running (mean that computation is on going)""" return self._processing def wait_computation_finished(self): """ Wait until the computation is finished """ if self._processing: self._computationThread.wait() def _start_threaded_computation(self, *args, **kwargs): self.sigComputationStarted.emit(self._data_currently_computed) def _end_threaded_computation(self, callback=None): sender = self.sender() # pylint: disable=E1101 if hasattr(sender, "future_tomo_obj"): future_tomo_obj = sender.future_tomo_obj else: future_tomo_obj = None self._end_computation( data=self._data_currently_computed, callback=callback, future_tomo_obj=future_tomo_obj, ) def cancel(self): if self._computationThread.isRunning(): with blockSignals(self._computationThread): self._computationThread.cancel() # stop stack self.stop() # emit next self.sigComputationEnded.emit(None, None) def stop(self): self._computationThread.wait() self._processing = False self._data_currently_computed = None def _displayError(self, error_msg: str): err = qt.QMessageBox() err.setText(error_msg) err.setIcon(qt.QMessageBox.Warning) self._errors.append(err) err.setModal(False) err.show() # expose deque API def append(self, value): self._deque.append(value) def clear(self): self._deque.clear() def pop(self): return self._deque.pop() def remove(self, value): return self._deque.remove(value) def __len__(self): return len(self._deque) def __contains__(self, value): return value.get_identifier().to_str() in [ scan.get_identifier().to_str() for scan in self._deque ] ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9811025 tomwer-1.6.17/src/tomwer/synctools/stacks/reconstruction/0000755000175000017500000000000015153325403022734 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/synctools/stacks/reconstruction/__init__.py0000644000175000017500000000000014757047403025045 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/synctools/stacks/reconstruction/axis.py0000644000175000017500000001371015153325210024250 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import functools import logging from processview.core.manager import DatasetState, ProcessManager from processview.core.superviseprocess import SuperviseProcess from silx.gui import qt from tomwer.core.process.reconstruction.axis import AxisTask from tomwer.core.process.reconstruction.axis.axis import NoAxisUrl from tomwer.core.process.reconstruction.axis.mode import AxisMode from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.settings import get_lbsram_path, isOnLbsram from tomwer.core.utils.lbsram import is_low_on_memory from tomwer.synctools.axis import QAxisRP from ..processingstack import FIFO, ProcessingThread _logger = logging.getLogger(__name__) class AxisProcessStack(FIFO, qt.QObject): """Implementation of the `.AxisTask` but having a stack for treating scans and making computation in threads""" def __init__(self, axis_params, process_id=None): qt.QObject.__init__(self) FIFO.__init__(self, process_id=process_id) assert axis_params is not None self._axis_params = axis_params def _process(self, data, configuration, callback=None): ProcessManager().notify_dataset_state( dataset=data, process=self, state=DatasetState.ON_GOING, ) assert isinstance(data, TomwerScanBase) if data.axis_params is None: data.axis_params = QAxisRP() self._data_currently_computed = data self._axis_params.frame_width = data.dim_1 mode = self._axis_params.mode if isOnLbsram(data) and is_low_on_memory(get_lbsram_path()) is True: # if computer is running into low memory on lbsram skip it mess = "low memory, skip axis calculation", data.path ProcessManager().notify_dataset_state( dataset=data, process=self._process_id, state=DatasetState.SKIPPED ) _logger.processSkipped(mess) data.axis_params.set_relative_value(None) if callback is not None: callback() self.scan_ready(scan=data) elif mode is (AxisMode.manual,): # if cor is not set then set it to 0 (can be the case if no) # interaction has been dne cor = self._axis_params.relative_cor_value if cor is None: cor = 0 data._axis_params.set_relative_value(cor) cor = data._axis_params.relative_cor_value # If mode is read or manual the position_value is not computed and # we will keep the actual one (should have been defined previously) self._end_computation(data=data, future_tomo_obj=None, callback=callback) else: _logger.processStarted( f"Start cor calculation on {data} ({self._axis_params.get_simple_str()})" ) data.axis_params.set_relative_value("...") self._axis_params.set_relative_value("...") assert self._axis_params.relative_cor_value == "..." self._data_currently_computed = data self._computationThread.init(data=data, axis_params=configuration) fct_callback = functools.partial(self._end_threaded_computation, callback) self._computationThread.finished.connect(fct_callback) self._computationThread.start() def _end_computation(self, data, future_tomo_obj, callback): """ callback when the computation thread is finished :param scan: pass if no call to '_computationThread is made' """ assert isinstance(data, TomwerScanBase) assert self._axis_params is not None # copy result computed on scan on the AxisTask reconsparams self._axis_params.set_relative_value( data.axis_params.relative_cor_value ) # noqa self._axis_params.frame_width = data.dim_1 FIFO._end_computation( self, data=data, future_tomo_obj=future_tomo_obj, callback=callback ) def _end_threaded_computation(self, callback=None): assert self._data_currently_computed is not None self._axis_params.set_relative_value(self._computationThread.center_of_rotation) self._computationThread.finished.disconnect() if callback: callback() FIFO._end_threaded_computation(self) def _create_processing_thread(self, process_id=None) -> qt.QThread: return _ProcessingThread(process_id=process_id) class _ProcessingThread(ProcessingThread, SuperviseProcess): """ Thread use to execute the processing of the axis position """ def __init__(self, process_id=None): SuperviseProcess.__init__(self, process_id=process_id) try: ProcessingThread.__init__(self, process_id=process_id) except TypeError: ProcessingThread.__init__(self) self.center_of_rotation = None self._scan = None self._axis_params = None """function pointer to know which function to call for the axis calculation""" self.__patch = {} """Used to patch some calculation method (for test purpose)""" def init(self, data, axis_params): self._scan = data self._axis_params = axis_params def run(self): self.sigComputationStarted.emit() axis = AxisTask( inputs={ "data": self._scan, "axis_params": self._axis_params, "serialize_output_data": False, }, process_id=self.process_id, ) try: axis.run() except NoAxisUrl as e: self.center_of_rotation = None _logger.error(f"CoR calculation failed. Issue with input ({e})") except Exception as e: _logger.error(f"CoR calculation failed ({e})", stack_info=True) self.center_of_rotation = None else: self.center_of_rotation = self._scan.axis_params.relative_cor_value ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/synctools/stacks/reconstruction/castvolume.py0000644000175000017500000001542115153325210025467 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import functools import logging from processview.core.manager import DatasetState, ProcessManager from processview.core.superviseprocess import SuperviseProcess from silx.gui import qt import traceback from tomwer.core.process.reconstruction.nabu.castvolume import CastVolumeTask from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.settings import get_lbsram_path, isOnLbsram from tomwer.core.tomwer_object import TomwerObject from tomwer.core.utils.lbsram import is_low_on_memory from tomwer.core.volume.volumebase import TomwerVolumeBase from tomwer.core.volume.volumefactory import VolumeFactory from ..processingstack import FIFO, ProcessingThread _logger = logging.getLogger(__name__) class CastVolumeProcessStack(FIFO, qt.QObject): def __init__(self, process_id=None): qt.QObject.__init__(self) FIFO.__init__(self, process_id=process_id) self._dry_run = False def set_dry_run(self, dry_run): self._dry_run = dry_run def _process(self, data, configuration, callback=None): ProcessManager().notify_dataset_state( dataset=data, process=self, state=DatasetState.ON_GOING, ) _logger.processStarted( f"start cast volume {str(data.get_identifier())} with parameters {configuration}" ) if isinstance(data, TomwerVolumeBase): if data.data_url is not None: path = data.data_url.file_path() else: path = None elif isinstance(data, TomwerScanBase): path = data.path else: raise ValueError( f"data is expected to be an instance of {TomwerScanBase} or {TomwerVolumeBase}. {type(data)} provided" ) if ( path is not None and isOnLbsram(path) and is_low_on_memory(get_lbsram_path()) is True ): # if computer is running into low memory on lbsram skip it mess = f"low memory, skip volume cast {data}" ProcessManager().notify_dataset_state( dataset=data, process=self, state=DatasetState.SKIPPED ) _logger.processSkipped(mess) if callback is not None: callback() self._end_computation(data=data, future_tomo_obj=None, callback=None) else: self._data_currently_computed = data try: self._computationThread.init(data=data, configuration=configuration) except ValueError as e: # initialization can fail (for example for cast volume is there is no volume or be case this will raise an error) # then we want to keep the thread active self._data_currently_computed = None ProcessManager().notify_dataset_state( dataset=data, process=self, state=DatasetState.FAILED ) _logger.processFailed(f"thread initialization failed. Error is {e}") if callback is not None: callback() self._end_computation(data=data, future_tomo_obj=None, callback=None) else: # need to manage connect before starting it because fct_callback = functools.partial( self._end_threaded_computation, callback ) self._computationThread.finished.connect(fct_callback) self._computationThread.start() def _end_computation(self, data, future_tomo_obj, callback): """ callback when the computation thread is finished :param scan: pass if no call to '_computationThread is made' """ assert isinstance(data, TomwerObject) FIFO._end_computation( self, data=data, future_tomo_obj=future_tomo_obj, callback=callback ) def _end_threaded_computation(self, callback=None): assert self._data_currently_computed is not None self._computationThread.finished.disconnect() if callback: callback() FIFO._end_threaded_computation(self) def _create_processing_thread(self, process_id=None) -> qt.QThread: return _ProcessingThread(process_id=process_id) class _ProcessingThread(ProcessingThread, SuperviseProcess): """ Thread use to execute the processing of the axis position """ def __init__(self, process_id=None): SuperviseProcess.__init__(self, process_id=process_id) try: ProcessingThread.__init__(self, process_id=process_id) except TypeError: ProcessingThread.__init__(self) self._dry_run = False self._scan = None self._future_tomo_obj = None self._volume = None self._configuration = None @property def future_tomo_obj(self): return self._future_tomo_obj def set_dry_run(self, dry_run): self._dry_run = dry_run def init(self, data, configuration): if isinstance(data, TomwerVolumeBase): self._scan = None self._volume = data else: self._scan = data if len(data.latest_vol_reconstructions) < 1: raise ValueError( "No reconstructed volume found. did you run the 'nabu volume reconstruction' process ?" ) volume_identifier = data.latest_vol_reconstructions[0] self._volume = VolumeFactory.create_tomo_object_from_identifier( volume_identifier ) self._data = data self._configuration = configuration def run(self): self.sigComputationStarted.emit() cast_volume_task = CastVolumeTask( process_id=self.process_id, varinfo=None, inputs={ "volume": self._volume, "configuration": self._configuration, "scan": self._scan, }, ) try: cast_volume_task.run() except Exception as e: _logger.info(traceback.format_exc()) _logger.error( f"Failed to cast volume. Error is {str(e)}", ) if self._scan is not None: # if scan is provided update status because otherwise only the volume state is updated ProcessManager().notify_dataset_state( dataset=self._scan, process=self, state=DatasetState.FAILED, ) else: if self._scan is not None: self._scan.cast_volume = cast_volume_task.outputs.volume if cast_volume_task.outputs.future_tomo_obj is not None: self._future_tomo_obj = cast_volume_task.outputs.future_tomo_obj ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/synctools/stacks/reconstruction/dkrefcopy.py0000644000175000017500000001403315153325210025271 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import functools import logging import shutil import tempfile import os from processview.core.manager import DatasetState, ProcessManager from processview.core.superviseprocess import SuperviseProcess from silx.gui import qt from tomwer.core.process.reconstruction.darkref.darkrefscopy import DarkRefsCopy from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.settings import get_lbsram_path, isOnLbsram from tomwer.core.utils.lbsram import is_low_on_memory from ..processingstack import FIFO, ProcessingThread _logger = logging.getLogger(__name__) class DarkRefCopyProcessStack(FIFO, qt.QObject): """Implementation of the `.AxisTask` but having a stack for treating scans and making computation in threads""" sigRefSetted = qt.Signal(str) """Signal emit when dark or flat are set by a scan. str is the scan identifier""" def __init__(self, process_id=None): try: self._save_dir = tempfile.mkdtemp() except Exception as e: _logger.warning( f"unable to create save dir. Error is {e}. Won't be able to copy any dark or flat" ) qt.QObject.__init__(self) FIFO.__init__(self, process_id=process_id) @property def save_dir(self): return self._save_dir def __del__(self): try: shutil.rmtree(self._save_dir) except Exception as e: _logger.error(e) def _process(self, data, configuration: dict, callback=None): if not isinstance(data, TomwerScanBase): raise TypeError(f"{data} is expected to be an instance of {TomwerScanBase}") if not isinstance(configuration, dict): raise TypeError(f"{configuration} is expected to be an instance of {dict}") ProcessManager().notify_dataset_state( dataset=data, process=self, state=DatasetState.ON_GOING, ) _logger.processStarted(f"dk-flat-copy {data}") assert isinstance(data, TomwerScanBase) self._data_currently_computed = data if isOnLbsram(data) and is_low_on_memory(get_lbsram_path()) is True: # if computer is running into low memory on lbsram skip it mess = "low memory, skip dk-flat-copy", data.path try: ProcessManager().notify_dataset_state( dataset=data, process=self, state=DatasetState.SKIPPED ) _logger.processSkipped(mess) if callback is not None: callback() except Exception as e: _logger.error(e) try: FIFO._end_threaded_computation(self) except Exception as e: _logger.error(e) else: self._data_currently_computed = data self._computationThread.init(data=data, inputs=configuration) # need to manage connect before starting it because fct_callback = functools.partial(self._end_threaded_computation, callback) self._computationThread.finished.connect(fct_callback) self._computationThread.sigRefSetted.connect(self.sigRefSetted) self._computationThread.start() def _end_computation(self, data, future_tomo_obj, callback): """ callback when the computation thread is finished :param scan: pass if no call to '_computationThread is made' """ if not isinstance(data, TomwerScanBase): raise TypeError(f"data is {type(data)} when {TomwerScanBase} expected.") super()._end_computation( data=data, future_tomo_obj=future_tomo_obj, callback=callback ) def _end_threaded_computation(self, callback=None): assert self._data_currently_computed is not None self._computationThread.finished.disconnect() if callback: callback() FIFO._end_threaded_computation(self) def _create_processing_thread(self, process_id=None) -> qt.QThread: return _ProcessingThread(process_id=process_id, save_dir=self._save_dir) def clear_cache(self): """ remove the file used to cache the reduced darks / flats. This can be used in the case it contain unrelevant data. Like frame with another shape... """ cache_file = DarkRefsCopy.get_save_file(self._save_dir) if os.path.exists(cache_file): os.remove(cache_file) class _ProcessingThread(ProcessingThread, SuperviseProcess): """ Thread use to execute the processing of the axis position """ sigRefSetted = qt.Signal(str) """Signal emit when dark or flat are set by a scan. str is the scan identifier""" def __init__(self, save_dir, process_id=None): SuperviseProcess.__init__(self, process_id=process_id) try: ProcessingThread.__init__(self, process_id=process_id) except TypeError: ProcessingThread.__init__(self) self._save_dir = save_dir self._data = None self._inputs = None def init(self, data, inputs): self._data = data self._inputs = inputs def run(self): self.sigComputationStarted.emit() inputs = self._inputs inputs["data"] = self._data inputs["save_dir"] = self._save_dir inputs["serialize_output_data"] = False process = DarkRefsCopyWithSig( parent=self.parent(), inputs=inputs, process_id=self.process_id ) process.sigRefSetted.connect(self.sigRefSetted) try: process.run() except Exception as e: _logger.warning(e) class DarkRefsCopyWithSig(qt.QObject, DarkRefsCopy): sigRefSetted = qt.Signal(str) """Signal emit when dark or flat are set by a scan. str is the scan identifier""" def __init__(self, parent=None, *args, **kwargs) -> None: qt.QObject.__init__(self, parent) DarkRefsCopy.__init__(self, *args, **kwargs) def _ref_has_been_set(self, scan): self.sigRefSetted.emit(scan.get_identifier().to_str()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/synctools/stacks/reconstruction/nabu.py0000644000175000017500000001500515153325210024230 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging from processview.core.manager import DatasetState, ProcessManager from processview.core.superviseprocess import SuperviseProcess from silx.gui import qt from silx.gui.utils import blockSignals from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.settings import get_lbsram_path, isOnLbsram from tomwer.core.utils.lbsram import is_low_on_memory from tomwer.core.process.reconstruction.nabu.nabuslices import NabuSlicesTask from tomwer.core.process.reconstruction.nabu.nabuvolume import NabuVolumeTask from ..processingstack import FIFO, ProcessingThread _logger = logging.getLogger(__name__) class NabuSliceProcessStack(FIFO, qt.QObject): """Implementation of the `.AxisTask` but having a stack for treating scans and making computation in threads""" def __init__(self, parent=None, process_id=None): qt.QObject.__init__(self, parent=parent) FIFO.__init__(self, process_id=process_id) self._dry_run = False def _process(self, data, configuration, callback=None): _logger.info(f"Nabu slice stack is processing {data}") ProcessManager().notify_dataset_state( dataset=data, process=self, state=DatasetState.ON_GOING, ) self._data_currently_computed = data assert isinstance(data, TomwerScanBase) self._computationThread.finished.connect(self._end_threaded_computation) if isOnLbsram(data) and is_low_on_memory(get_lbsram_path()) is True: # if computer is running into low memory on lbsram skip it mess = f"low memory, skip nabu reconstruction for {data.path}" _logger.processSkipped(mess) ProcessManager().notify_dataset_state( dataset=data, process=self, state=DatasetState.SKIPPED, ) self._end_threaded_computation() else: self._computationThread.init(data=data, configuration=configuration) self._computationThread.setDryRun(self._dry_run) # need to manage connect before starting it because self._computationThread.start() def _end_threaded_computation(self, callback=None): self._computationThread.finished.disconnect(self._end_threaded_computation) super()._end_threaded_computation(callback=callback) def _create_processing_thread(self, process_id=None) -> qt.QThread: return _SliceProcessingThread(process_id=process_id) def setDryRun(self, dry_run): self._dry_run = dry_run def cancel(self): if self._computationThread.isRunning(): with blockSignals(self._computationThread): self._computationThread.cancel() # stop stack super().stop() # emit next self.sigComputationEnded.emit(None, None) class NabuVolumeProcessStack(NabuSliceProcessStack): """Implementation of the `.AxisTask` but having a stack for treating scans and making computation in threads""" def _create_processing_thread(self, process_id=None) -> qt.QThread: return _VolumeProcessingThread(process_id=process_id) class _SliceProcessingThread(ProcessingThread, SuperviseProcess): """ Thread use to execute the processing of nabu reconstruction """ def __init__(self, process_id=None): SuperviseProcess.__init__(self, process_id=process_id) try: ProcessingThread.__init__(self, process_id=process_id) except TypeError: ProcessingThread.__init__(self) self._scan = None self._future_tomo_obj = None self._configuration = None self._dry_run = False self._current_processing = None # processing currently runned. As we want to be able to cancel processing we need to keep a pointer on the # 'activate' nabu processing to stop process if requested self._task = None # ewoks task for reconstruction @property def future_tomo_obj(self): return self._future_tomo_obj def setDryRun(self, dry_run): self._dry_run = dry_run def init(self, data, configuration): self._scan = data self._configuration = configuration self._task = None def run(self): # note: now rnu does a processing close to the 'run_slices_reconstruction' except that we keep a trace on the # current nabu subprocess runned. The goal is to be able to cancel / stop processing when asked self.sigComputationStarted.emit() mess = f"Start nabu slice(s) reconstruction of {self._scan}" _logger.processStarted(mess) ProcessManager().notify_dataset_state( dataset=self._scan, process=self, state=DatasetState.ON_GOING, details=mess, ) self._task = NabuSlicesTask( process_id=self.process_id, inputs={ "data": self._scan, "nabu_params": self._configuration, "dry_run": self._dry_run, "serialize_output_data": False, "invalid_slice_callback": self.showErrorSliceInvalid, }, ) self._task.run() self._future_tomo_obj = self._task.outputs.future_tomo_obj def cancel(self): if self._task is not None: self._task.cancel() self.quit() def showErrorSliceInvalid(self, error_message): self.sigError.emit(error_message) class _VolumeProcessingThread(_SliceProcessingThread): """ Thread use to execute the processing of nabu reconstruction """ def run(self): self.sigComputationStarted.emit() mess = f"Start nabu volume reconstruction of {self._scan}" _logger.processStarted(mess) ProcessManager().notify_dataset_state( dataset=self._scan, process=self, state=DatasetState.ON_GOING, details=mess, ) self._task = NabuVolumeTask( process_id=self.process_id, inputs={ "data": self._scan, "nabu_params": self._scan.nabu_recons_params, "nabu_extra_params": self._configuration, "process_id": self.process_id, "dry_run": self._dry_run, "serialize_output_data": False, # avoid spending time on serialization / deserialization }, ) self._task.run() self._future_tomo_obj = self._task.outputs.future_tomo_obj ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/synctools/stacks/reconstruction/normalization.py0000644000175000017500000000771415153325210026201 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import functools import logging from processview.core.manager import DatasetState, ProcessManager from processview.core.superviseprocess import SuperviseProcess from silx.gui import qt from tomwer.core.process.reconstruction.normalization import SinoNormalizationTask from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.settings import get_lbsram_path, isOnLbsram from tomwer.core.utils.lbsram import is_low_on_memory from ..processingstack import FIFO, ProcessingThread _logger = logging.getLogger(__name__) class INormalizationProcessStack(FIFO, qt.QObject): """Implementation of the `.AxisTask` but having a stack for treating scans and making computation in threads""" def __init__(self, process_id=None): qt.QObject.__init__(self) FIFO.__init__(self, process_id=process_id) def _process(self, data, configuration, callback=None): ProcessManager().notify_dataset_state( dataset=data, process=self, state=DatasetState.ON_GOING, ) _logger.processStarted(f"start intensity normalization {data}") assert isinstance(data, TomwerScanBase) if isOnLbsram(data) and is_low_on_memory(get_lbsram_path()) is True: # if computer is running into low memory on lbsram skip it mess = "low memory, skip intensity normalization", data.path ProcessManager().notify_dataset_state( dataset=data, process=self._process_id, state=DatasetState.SKIPPED ) _logger.processSkipped(mess) if callback is not None: callback() self.scan_ready(scan=data) else: self._data_currently_computed = data self._computationThread.init(data=data, i_norm_params=configuration) # need to manage connect before starting it because fct_callback = functools.partial(self._end_threaded_computation, callback) self._computationThread.finished.connect(fct_callback) self._computationThread.start() def _end_threaded_computation(self, callback=None): assert self._data_currently_computed is not None self._computationThread.finished.disconnect() if callback: callback() FIFO._end_threaded_computation(self) def _create_processing_thread(self, process_id=None) -> qt.QThread: return _ProcessingThread(process_id=process_id) class _ProcessingThread(ProcessingThread, SuperviseProcess): """ Thread use to execute the processing of intensity normalization (mostly load io and compute the mean / median on it) """ def __init__(self, process_id=None): SuperviseProcess.__init__(self, process_id=process_id) ProcessingThread.__init__(self, process_id=process_id) self.center_of_rotation = None self._dry_run = False self._scan = None self._i_norm_params = None def init(self, data, i_norm_params): self._scan = data self._i_norm_params = i_norm_params def run(self): self.sigComputationStarted.emit() norm_process = SinoNormalizationTask( process_id=self.process_id, varinfo=None, inputs={ "data": self._scan, "configuration": self._i_norm_params, "serialize_output_data": False, }, ) try: norm_process.run() except Exception as e: _logger.error(str(e)) mess = f"Intensity normalization computation for {self._scan} failed." state = DatasetState.FAILED else: mess = f"Intensity normalization computation for {self._scan} succeed." state = DatasetState.WAIT_USER_VALIDATION ProcessManager().notify_dataset_state( dataset=self._scan, process=self, state=state, details=mess, ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/synctools/stacks/reconstruction/saaxis.py0000644000175000017500000001326015153325210024574 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import functools import logging from processview.core.manager import DatasetState, ProcessManager from processview.core.superviseprocess import SuperviseProcess from silx.gui import qt from tomwer.core.process.reconstruction.saaxis import SAAxisTask from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.settings import get_lbsram_path, isOnLbsram from tomwer.core.utils.lbsram import is_low_on_memory from tomwer.synctools.axis import QAxisRP from tomwer.synctools.saaxis import QSAAxisParams from ..processingstack import FIFO, ProcessingThread _logger = logging.getLogger(__name__) class SAAxisProcessStack(FIFO, qt.QObject): """Implementation of the `.AxisTask` but having a stack for treating scans and making computation in threads""" def __init__(self, saaxis_params, process_id=None): qt.QObject.__init__(self) FIFO.__init__(self, process_id=process_id) assert saaxis_params is not None self._dry_run = False self._process_fct = None def patch_processing(self, process_fct): self._computationThread.patch_processing(process_fct) def set_dry_run(self, dry_run): self._dry_run = dry_run def _process(self, data, configuration, callback=None): ProcessManager().notify_dataset_state( dataset=data, process=self, state=DatasetState.ON_GOING, ) _logger.processStarted(f"start saaxis {data}") assert isinstance(data, TomwerScanBase) if data.axis_params is None: data.axis_params = QAxisRP() if data.saaxis_params is None: data.saaxis_params = QSAAxisParams() self._data_currently_computed = data saaxis_params = QSAAxisParams.from_dict(configuration) saaxis_params.frame_width = data.dim_1 if isOnLbsram(data) and is_low_on_memory(get_lbsram_path()) is True: # if computer is running into low memory on lbsram skip it mess = f"low memory, skip saaxis calculation {data.path}" ProcessManager().notify_dataset_state( dataset=data, process=self._process_id, state=DatasetState.SKIPPED ) _logger.processSkipped(mess) data.axis_params.set_relative_value(None) if callback is not None: callback() self.scan_ready(scan=data) else: self._data_currently_computed = data self._computationThread.init(data=data, saaxis_params=saaxis_params) # need to manage connect before starting it because fct_callback = functools.partial(self._end_threaded_computation, callback) self._computationThread.finished.connect(fct_callback) self._computationThread.start() def _end_computation(self, data, future_tomo_obj, callback): """ callback when the computation thread is finished :param scan: pass if no call to '_computationThread is made' """ assert isinstance(data, TomwerScanBase) FIFO._end_computation( self, data=data, future_tomo_obj=future_tomo_obj, callback=callback ) def _end_threaded_computation(self, callback=None): self._computationThread.finished.disconnect() if callback: callback() FIFO._end_threaded_computation(self) def _create_processing_thread(self, process_id=None) -> qt.QThread: return _ProcessingThread(process_id=process_id) class _ProcessingThread(ProcessingThread, SuperviseProcess): """ Thread use to execute the processing of the axis position """ def __init__(self, process_id=None): SuperviseProcess.__init__(self, process_id=process_id) try: ProcessingThread.__init__(self, process_id=process_id) except TypeError: ProcessingThread.__init__(self) self.center_of_rotation = None self._dry_run = False self._scan = None self._saaxis_params = None self._patch_process_fct = None """function pointer to know which function to call for the axis calculation""" self._current_processing = None # processing currently runned. As we want to be able to cancel processing we need to keep a pointer on the # 'activate' nabu processing to stop process if requested self._task = None # ewoks task for reconstruction def set_dry_run(self, dry_run): self._dry_run = dry_run def patch_processing(self, process_fct): self._patch_process_fct = process_fct def init(self, data, saaxis_params: dict): self._scan = data self._saaxis_params = saaxis_params def run(self): self.sigComputationStarted.emit() if self._patch_process_fct: scores = {} for cor in self._saaxis_params.cors: scores[cor] = self._patch_process_fct(cor) self._scan.saaxis_params.scores = scores SAAxisTask.autofocus(scan=self._scan) self.center_of_rotation = self._scan.saaxis_params.autofocus else: self._task = SAAxisTask( process_id=self.process_id, inputs={ "dump_process": False, "data": self._scan, "dry_run": self._dry_run, "sa_axis_params": self._saaxis_params.to_dict(), "serialize_output_data": False, }, ) self._task.run() self.center_of_rotation = self._task.outputs.best_cor def cancel(self): if self._task is not None: self._task.cancel() self.quit() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/synctools/stacks/reconstruction/sadeltabeta.py0000644000175000017500000001324415153325210025557 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import functools import logging from processview.core.manager import DatasetState, ProcessManager from processview.core.superviseprocess import SuperviseProcess from silx.gui import qt from tomwer.core.process.reconstruction.sadeltabeta.sadeltabeta import ( SADeltaBetaTask, ) from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.settings import get_lbsram_path, isOnLbsram from tomwer.core.utils.lbsram import is_low_on_memory from tomwer.synctools.axis import QAxisRP from tomwer.synctools.sadeltabeta import QSADeltaBetaParams from ..processingstack import FIFO, ProcessingThread _logger = logging.getLogger(__name__) class SADeltaBetaProcessStack(FIFO, qt.QObject): """Implementation of the `.AxisTask` but having a stack for treating scans and making computation in threads""" def __init__(self, sa_delta_beta_params, process_id=None): qt.QObject.__init__(self) FIFO.__init__(self, process_id=process_id) assert sa_delta_beta_params is not None self._dry_run = False self._process_fct = None def patch_processing(self, process_fct): self._computationThread.patch_processing(process_fct) def set_dry_run(self, dry_run): self._dry_run = dry_run def _process(self, data, configuration, callback=None): ProcessManager().notify_dataset_state( dataset=data, process=self, state=DatasetState.ON_GOING, ) _logger.processStarted(f"start sa-delta-beta {data}") assert isinstance(data, TomwerScanBase) if data.axis_params is None: data.axis_params = QAxisRP() if data.sa_delta_beta_params is None: data.sa_delta_beta_params = QSADeltaBetaParams() self._data_currently_computed = data sa_delta_beta_params = QSADeltaBetaParams.from_dict(configuration) if isOnLbsram(data) and is_low_on_memory(get_lbsram_path()) is True: # if computer is running into low memory on lbsram skip it mess = f"low memory, skip sa-delta-beta-axis calculation {data.path}" ProcessManager().notify_dataset_state( dataset=data, process=self._process_id, state=DatasetState.SKIPPED ) _logger.processSkipped(mess) data.sa_delta_beta_params.set_value(None) if callback is not None: callback() self.scan_ready(scan=data) else: self._data_currently_computed = data self._computationThread.init( data=data, sa_delta_beta_params=sa_delta_beta_params ) # need to manage connect before starting it because fct_callback = functools.partial(self._end_threaded_computation, callback) self._computationThread.finished.connect(fct_callback) self._computationThread.start() def _end_computation(self, data, future_tomo_obj, callback): """ callback when the computation thread is finished :param scan: pass if no call to '_computationThread is made' """ assert isinstance(data, TomwerScanBase) FIFO._end_computation( self, data=data, future_tomo_obj=future_tomo_obj, callback=callback ) def _end_threaded_computation(self, callback=None): assert self._data_currently_computed is not None self._computationThread.finished.disconnect() if callback: callback() FIFO._end_threaded_computation(self) def _create_processing_thread(self, process_id=None) -> qt.QThread: return _ProcessingThread(process_id=process_id) class _ProcessingThread(ProcessingThread, SuperviseProcess): """ Thread use to execute the processing of the axis position """ def __init__(self, process_id=None): SuperviseProcess.__init__(self, process_id=process_id) try: ProcessingThread.__init__(self, process_id=process_id) except TypeError: ProcessingThread.__init__(self) self.db_value = None self._dry_run = False self._scan = None self._sa_delta_beta_params = None self._patch_process_fct = None """function pointer to know which function to call for the axis calculation""" self._task = None # ewoks task for reconstruction def set_dry_run(self, dry_run): self._dry_run = dry_run def patch_processing(self, process_fct): self._patch_process_fct = process_fct def init(self, data, sa_delta_beta_params): self._scan = data self._sa_delta_beta_params = sa_delta_beta_params def run(self): self.sigComputationStarted.emit() if self._patch_process_fct: scores = {} for db in self._sa_delta_beta_params.delta_beta_values: scores[db] = self._patch_process_fct(db) self._scan.sa_delta_beta_params.scores = scores SADeltaBetaTask.autofocus(scan=self._scan) self.db_value = self._scan.sa_delta_beta_params.autofocus else: self._task = SADeltaBetaTask( inputs={ "dump_process": False, "data": self._scan, "dry_run": self._dry_run, "sa_delta_beta_params": self._sa_delta_beta_params.to_dict(), "serialize_output_data": False, }, process_id=self.process_id, ) self._task.run() self.db_value = self._task.outputs.best_db def cancel(self): if self._task is not None: self._task.cancel() self.quit() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9811025 tomwer-1.6.17/src/tomwer/synctools/tests/0000755000175000017500000000000015153325403017525 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/synctools/tests/__init__.py0000644000175000017500000000000014757047403021636 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/synctools/tests/test_darkRefs.py0000644000175000017500000003430615153325210022701 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import shutil import tempfile import fabio import numpy from silx.gui.utils.testutils import TestCaseQt from tomwer.core.process.reconstruction.darkref.darkrefs import DarkRefsTask from tomwer.core.process.reconstruction.darkref.params import DKRFRP, ReduceMethod from tomwer.core.utils.scanutils import MockEDF from tomwer.tests.datasets import TomwerCIDatasets class TestDarkRefsBehavior(TestCaseQt): """Test that the Darks and reference are correctly computed from the DarksRefs class """ def setUp(self): TestCaseQt.setUp(self) self.datasetsID = "test10" self.tmpDir = tempfile.mkdtemp() self.thRef = {} """number of theoretical ref file the algorithm should create""" self.thDark = {} """number of theoretical dark file the algorithm should create""" self.dataset_folder = os.path.join(self.tmpDir, self.datasetsID) dataDir = TomwerCIDatasets.get_dataset( f"edf_datasets/{self.datasetsID}", ) shutil.copytree(dataDir, self.dataset_folder) files = os.listdir(self.dataset_folder) for _f in files: if _f.startswith(("refHST", "darkHST", "dark.edf")): os.remove(os.path.join(self.dataset_folder, _f)) self.recons_params = DKRFRP() self.recons_params._set_remove_opt(False) def tearDown(self): self.qapp.processEvents() self.darkRef = None shutil.rmtree(self.tmpDir) def testDarkCreation(self): """Test that the dark is correctly computed""" self.recons_params.flat_calc_method = ReduceMethod.NONE self.recons_params.dark_calc_method = ReduceMethod.MEDIAN dar_ref_process = DarkRefsTask( inputs={ "dark_ref_params": self.recons_params, "force_sync": True, "darkhst_prefix": "darkHST", "data": self.dataset_folder, "serialize_output_data": False, } ) dar_ref_process.run() self.qapp.processEvents() if os.path.basename(self.dataset_folder) == "test10": self.assertTrue("darkend0000.edf" in os.listdir(self.dataset_folder)) self.assertTrue("dark.edf" in os.listdir(self.dataset_folder)) self.assertEqual( len( dar_ref_process.getDarkHSTFiles( self.dataset_folder, prefix=self.recons_params.dark_prefix ) ), 1, ) self.assertEqual( len( dar_ref_process.getRefHSTFiles( self.dataset_folder, prefix=self.recons_params.flat_prefix ) ), 0, ) def testRefCreation(self): """Test that the dark is correctly computed""" self.recons_params.flat_calc_method = ReduceMethod.MEDIAN self.recons_params.dark_calc_method = ReduceMethod.NONE dar_ref_process = DarkRefsTask( inputs={ "dark_ref_params": self.recons_params, "force_sync": True, "darkhst_prefix": "darkHST", "data": self.dataset_folder, "serialize_output_data": False, } ) dar_ref_process.run() self.qapp.processEvents() self.assertTrue("darkend0000.edf" in os.listdir(self.dataset_folder)) self.assertFalse("dark0000.edf" in os.listdir(self.dataset_folder)) self.assertTrue("refHST0000.edf" in os.listdir(self.dataset_folder)) self.assertTrue("refHST0020.edf" in os.listdir(self.dataset_folder)) self.assertTrue("ref0000_0000.edf" in os.listdir(self.dataset_folder)) self.assertTrue("ref0000_0020.edf" in os.listdir(self.dataset_folder)) self.assertTrue("ref0001_0000.edf" in os.listdir(self.dataset_folder)) self.assertTrue("ref0001_0020.edf" in os.listdir(self.dataset_folder)) class TestRefCalculationOneSerie(TestCaseQt): """ Make sure the calculation is correct for the dark and flat field according to the method used. """ def setUp(self): super().setUp() self.tmp_dir = tempfile.mkdtemp() n_scans = 5 n_info = 1 n_xml = 1 MockEDF.fastMockAcquisition(self.tmp_dir, n_radio=n_scans) reFiles = {} data1 = numpy.zeros((20, 10)) data2 = numpy.zeros((20, 10)) + 100 reFiles["ref0000_0000.edf"] = data1 reFiles["ref0001_0000.edf"] = data2 reFiles["ref0002_0000.edf"] = data2 reFiles["ref0003_0000.edf"] = data2 for refFile in reFiles: file_desc = fabio.edfimage.EdfImage(data=reFiles[refFile]) file_desc.write(os.path.join(self.tmp_dir, refFile)) assert len(os.listdir(self.tmp_dir)) is ( len(reFiles) + n_scans + n_xml + n_info ) self.recons_params = DKRFRP() self.darkRef = DarkRefsTask( inputs={ "dark_ref_params": self.recons_params, "data": self.tmp_dir, "serialize_output_data": False, } ) self.darkRef.setForceSync(True) self.recons_params.flat_pattern = "ref*.*[0-9]{3,4}_[0-9]{3,4}" def tearDown(self): shutil.rmtree(self.tmp_dir) super().tearDown() def testRefMedianCalculation(self): self.recons_params.flat_calc_method = ReduceMethod.MEDIAN self.recons_params.dark_calc_method = ReduceMethod.NONE self.darkRef.run() refHST = os.path.join(self.tmp_dir, "refHST0000.edf") self.assertTrue(os.path.isfile(refHST)) self.assertTrue( numpy.array_equal(fabio.open(refHST).data, numpy.zeros((20, 10)) + 100) ) def testRefMeanCalculation(self): self.recons_params.flat_calc_method = ReduceMethod.MEAN self.recons_params.dark_calc_method = ReduceMethod.NONE self.darkRef.run() refHST = os.path.join(self.tmp_dir, "refHST0000.edf") self.assertTrue(os.path.isfile(refHST)) self.assertTrue( numpy.array_equal(fabio.open(refHST).data, numpy.zeros((20, 10)) + 75) ) class TestRefCalculationThreeSerie(TestCaseQt): """ Make sure the calculation is correct for the dark and flat field according to the method used. """ def setUp(self): super().setUp() self.tmp_dir = tempfile.mkdtemp() MockEDF.fastMockAcquisition(folder=self.tmp_dir, n_radio=1) reFiles = {} self.seriesList = (0, 10, 200) for series in self.seriesList: data1 = numpy.zeros((20, 10)) + series data2 = numpy.zeros((20, 10)) + 100 + series reFiles["ref0000_" + str(series).zfill(4) + ".edf"] = data1 reFiles["ref0001_" + str(series).zfill(4) + ".edf"] = data2 reFiles["ref0002_" + str(series).zfill(4) + ".edf"] = data2 reFiles["ref0003_" + str(series).zfill(4) + ".edf"] = data2 for refFile in reFiles: file_desc = fabio.edfimage.EdfImage(data=reFiles[refFile]) file_desc.write(os.path.join(self.tmp_dir, refFile)) self.recons_params = DKRFRP() self.darkRef = DarkRefsTask( inputs={ "dark_ref_params": self.recons_params, "data": self.tmp_dir, "force_sync": True, "serialize_output_data": False, } ) self.recons_params.flat_pattern = "ref*.*[0-9]{3,4}_[0-9]{3,4}" def tearDown(self): shutil.rmtree(self.tmp_dir) super().tearDown() def testRefMedianCalculation(self): self.recons_params.flat_calc_method = ReduceMethod.MEDIAN self.recons_params.dark_calc_method = ReduceMethod.NONE self.darkRef.run() for serie in self.seriesList: refHST = os.path.join(self.tmp_dir, "refHST" + str(serie).zfill(4) + ".edf") self.assertTrue(os.path.isfile(refHST)) self.assertTrue( numpy.array_equal( fabio.open(refHST).data, numpy.zeros((20, 10)) + 100 + serie ) ) def testRefMeanCalculation(self): self.recons_params.flat_calc_method = ReduceMethod.MEAN self.recons_params.dark_calc_method = ReduceMethod.NONE self.darkRef.run() for series in self.seriesList: refHST = os.path.join( self.tmp_dir, "refHST" + str(series).zfill(4) + ".edf" ) self.assertTrue(os.path.isfile(refHST)) self.assertTrue( numpy.array_equal( fabio.open(refHST).data, numpy.zeros((20, 10)) + 75 + series ) ) class TestDarkCalculationOneFrame(TestCaseQt): """Make sure computation of the Dark is correct""" def setUp(self): super().setUp() self.tmp_dir = tempfile.mkdtemp() n_scan = 1 n_info = 1 n_xml = 1 MockEDF.fastMockAcquisition(self.tmp_dir, n_radio=n_scan) file_desc = fabio.edfimage.EdfImage(data=numpy.zeros((20, 10)) + 10) file_desc.write(os.path.join(self.tmp_dir, "darkend0000.edf")) assert len(os.listdir(self.tmp_dir)) is (1 + n_scan + n_info + n_xml) self.recons_params = DKRFRP() self.darkRef = DarkRefsTask( inputs={ "dark_ref_params": self.recons_params, "force_sync": True, "data": self.tmp_dir, "serialize_output_data": False, } ) def tearDown(self): shutil.rmtree(self.tmp_dir) super().tearDown() def testDarkMeanCalculation(self): self.recons_params.flat_calc_method = ReduceMethod.NONE self.recons_params.dark_calc_method = ReduceMethod.MEAN self.darkRef.run() refHST = os.path.join(self.tmp_dir, "dark.edf") self.assertTrue(os.path.isfile(refHST)) self.assertTrue( numpy.array_equal(fabio.open(refHST).data, numpy.zeros((20, 10)) + 10) ) def testDarkMedianCalculation(self): self.recons_params.flat_calc_method = ReduceMethod.NONE self.recons_params.dark_calc_method = ReduceMethod.MEDIAN self.darkRef.run() refHST = os.path.join(self.tmp_dir, "dark.edf") self.assertTrue(os.path.isfile(refHST)) self.assertTrue( numpy.array_equal(fabio.open(refHST).data, numpy.zeros((20, 10)) + 10) ) class TestDarkCalculation(TestCaseQt): """Make sure computation of the Dark is correct""" def setUp(self): super().setUp() self.tmp_dir = tempfile.mkdtemp() n_scan = 1 n_xml = 1 n_info = 1 MockEDF.fastMockAcquisition(os.path.join(self.tmp_dir), n_radio=n_scan) file_desc = fabio.edfimage.EdfImage(data=numpy.zeros((20, 10))) file_desc.append_frame(data=(numpy.zeros((20, 10)) + 100)) file_desc.append_frame(data=(numpy.zeros((20, 10)) + 100)) file_desc.append_frame(data=(numpy.zeros((20, 10)) + 100)) file_desc.write(os.path.join(self.tmp_dir, "darkend0000.edf")) assert len(os.listdir(self.tmp_dir)) is (1 + n_scan + n_xml + n_info) self.recons_params = DKRFRP() self.darkRef = DarkRefsTask( inputs={ "data": self.tmp_dir, "dark_ref_params": self.recons_params, "force_sync": True, "serialize_output_data": False, } ) def tearDown(self): shutil.rmtree(self.tmp_dir) super().tearDown() def testDarkMeanCalculation(self): self.recons_params.flat_calc_method = ReduceMethod.NONE self.recons_params.dark_calc_method = ReduceMethod.MEAN self.darkRef.run() refHST = os.path.join(self.tmp_dir, "dark.edf") self.assertTrue(os.path.isfile(refHST)) self.assertTrue( numpy.array_equal(fabio.open(refHST).data, numpy.zeros((20, 10)) + 75) ) def testDarkMedianCalculation(self): self.recons_params.flat_calc_method = ReduceMethod.NONE self.recons_params.dark_calc_method = ReduceMethod.MEDIAN self.darkRef.run() refHST = os.path.join(self.tmp_dir, "dark.edf") self.assertTrue(os.path.isfile(refHST)) self.assertTrue( numpy.array_equal(fabio.open(refHST).data, numpy.zeros((20, 10)) + 100) ) class TestDarkAccumulation(TestCaseQt): """ Make sure computation for dark in accumulation are correct """ def setUp(self): super().setUp() self.dataset = "bone8_1_" dataDir = TomwerCIDatasets.get_dataset( f"edf_datasets/{self.dataset}", ) self.outputdir = tempfile.mkdtemp() shutil.copytree(src=dataDir, dst=os.path.join(self.outputdir, self.dataset)) self.darkFile = os.path.join(self.outputdir, self.dataset, "dark.edf") # create a single 'bone8_1_' to be a valid acquisition directory MockEDF.fastMockAcquisition(os.path.join(self.outputdir, self.dataset)) assert os.path.isfile(self.darkFile) with fabio.open(self.darkFile) as dsc: self.dark_reference = dsc.data # remove dark file os.remove(self.darkFile) self.recons_params = DKRFRP() self.recons_params.flat_calc_method = ReduceMethod.NONE self.recons_params.dark_calc_method = ReduceMethod.MEDIAN self.recons_params.dark_pattern = "darkend*" self.recons_params.dark_prefix = "dark.edf" def tearDown(self): shutil.rmtree(self.outputdir) super().tearDown() def testComputation(self): """Test data `bone8_1_` from id16b containing dark.edf of reference and darkend""" dark_ref_process = DarkRefsTask( inputs={ "data": os.path.join(self.outputdir, self.dataset), "force_sync": True, "serialize_output_data": False, } ) dark_ref_process.run() self.assertTrue(os.path.isfile(self.darkFile)) with fabio.open(self.darkFile) as dsc: self.computed_dark = dsc.data self.assertTrue(numpy.array_equal(self.computed_dark, self.dark_reference)) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/synctools/tests/test_foldertransfer.py0000644000175000017500000002735015153325210024161 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging import os import shutil import tempfile import unittest from glob import glob import pytest from nxtomomill.converter import from_h5_to_nx from nxtomomill.models.h52nx import H52nxModel from silx.gui.utils.testutils import TestCaseQt from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils.spec import rebaseParFile from tomwer.core.utils.scanutils import MockEDF from tomwer.synctools.datatransfert import ScanTransfer from tomwer.tests.datasets import TomwerCIDatasets try: from tomwer.synctools.rsyncmanager import RSyncManager except ImportError: has_rsync = False else: has_rsync = True logging.disable(logging.INFO) class TestEDFDataTransfert(TestCaseQt): """ Test that the folder transfert process is valid """ def setUp(self): TestCaseQt.setUp(self) self.sourcedir = tempfile.mkdtemp() self.n_file = 10 MockEDF.fastMockAcquisition(self.sourcedir, n_radio=self.n_file) self.scan = ScanFactory.create_scan_object(self.sourcedir) assert os.path.isdir(self.sourcedir) assert os.path.exists(self.sourcedir) self.targettedir = tempfile.mkdtemp() assert os.path.isdir(self.targettedir) assert os.path.exists(self.targettedir) self.outputdir = os.path.join( self.targettedir, os.path.basename(self.sourcedir) ) def tearDown(self): if os.path.isdir(self.sourcedir): shutil.rmtree(self.sourcedir) if os.path.isdir(self.targettedir): shutil.rmtree(self.targettedir) def testMoveFiles(self): """ simple test that files are moved """ folder_trans_process = ScanTransfer( inputs={ "data": self.scan, "turn_off_print": True, "copying": False, "dest_dir": self.targettedir, "noRsync": True, } ) folder_trans_process.run() self.assertTrue(os.path.isdir(self.outputdir)) self.assertTrue(self.checkDataCopied()) def testCopyFiles(self): """ Simple test that file are copy and deleted """ folder_trans_process = ScanTransfer( inputs={ "data": self.scan, "turn_off_print": True, "copying": False, "dest_dir": self.targettedir, "noRsync": True, "move": False, } ) folder_trans_process.run() self.assertTrue(self.checkDataCopied()) def testMoveFilesForce(self): """ Test the force option of folderTransfert """ assert not os.path.isdir(self.outputdir) assert os.path.isdir(self.scan.path) folder_trans_process = ScanTransfer( inputs={ "data": self.scan, "turn_off_print": True, "copying": False, "dest_dir": self.targettedir, "noRsync": True, "move": True, "overwrite": False, } ) folder_trans_process.run() MockEDF.fastMockAcquisition(self.sourcedir, n_radio=self.n_file) folder_trans_process = ScanTransfer( inputs={ "data": self.scan, "turn_off_print": True, "copying": False, "dest_dir": self.targettedir, "noRsync": True, "move": True, "overwrite": False, } ) with self.assertRaises(shutil.Error): self.assertRaises(folder_trans_process.run()) folder_trans_process = ScanTransfer( inputs={ "data": self.scan, "turn_off_print": True, "copying": False, "dest_dir": self.targettedir, "noRsync": True, "move": True, "overwrite": True, } ) folder_trans_process.run() self.assertTrue(self.checkDataCopied()) def testCopyFilesForce(self): """ Test the force option for the copy files process """ assert not os.path.isdir(self.outputdir) os.makedirs(self.outputdir) assert os.path.isdir(self.outputdir) folder_trans_process = ScanTransfer( inputs={ "data": self.scan, "turn_off_print": True, "copying": False, "dest_dir": self.targettedir, "noRsync": True, "move": False, "overwrite": False, } ) folder_trans_process.run() self.assertTrue(self.checkDataCopied()) MockEDF.fastMockAcquisition(self.sourcedir, n_radio=self.n_file) self.assertTrue(self.scan.path == self.sourcedir) folder_trans_process = ScanTransfer( inputs={ "data": self.scan, "turn_off_print": True, "copying": False, "dest_dir": self.targettedir, "noRsync": True, "move": False, "overwrite": False, } ) with self.assertRaises(FileExistsError): self.assertRaises(folder_trans_process.run()) folder_trans_process = ScanTransfer( inputs={ "data": self.scan, "turn_off_print": True, "copying": False, "dest_dir": self.targettedir, "noRsync": True, "move": False, "overwrite": True, } ) folder_trans_process.run() self.assertTrue(self.checkDataCopied()) def checkDataCopied(self): outputFiles = os.listdir(self.outputdir) inputFile = glob(self.sourcedir) # + 3 because .info and .xml are count return ( (len(inputFile) == 0) and (len(outputFiles) == (self.n_file + 2)) and (not os.path.isdir(self.sourcedir)) ) @pytest.mark.skipif(RSyncManager().has_rsync() is False, reason="Rsync is missing") class TestHDFDataTransfert(TestCaseQt): """Make sure we can transfer data from bliss acquisition""" def setUp(self): super().setUp() self.input_dir = tempfile.mkdtemp() self.output_dir = tempfile.mkdtemp() shutil.copytree( TomwerCIDatasets.get_dataset("bliss/sample"), os.path.join(self.input_dir, "sample"), ) self._proposal_file = os.path.join( self.input_dir, "sample", "ihpayno_sample.h5" ) assert os.path.exists(self._proposal_file) self._sample_file = os.path.join( self.input_dir, "sample", "sample_29042021", "sample_29042021.h5" ) assert os.path.exists(self._sample_file) self._sample_file_entry = "/1.1" output_file_path = os.path.join( self.input_dir, "sample", "sample_29042021", "nx_file.nx" ) # convert it to nx configuration = H52nxModel() configuration.input_file = self._sample_file configuration.output_file = output_file_path files_entries = (self._sample_file_entry,) configuration.entries = files_entries configuration.single_file = False configuration.overwrite = False configuration.request_input = False configuration.file_extension = ".nx" results = from_h5_to_nx(configuration) assert len(results) == 1 output_file_path, entry = results[0] assert os.path.exists(output_file_path) assert os.path.isfile(output_file_path) self.scan = NXtomoScan(scan=output_file_path, entry=entry) def tearDown(self): for dir_ in (self.input_dir, self.output_dir): shutil.rmtree(dir_) def testDataTransfert(self): process = ScanTransfer( inputs={ "data": self.scan, "dest_dir": os.path.join(self.output_dir, "sample"), "block": True, } ) process.run() output_scan = os.path.join( self.output_dir, "sample", "sample_29042021", "scan0002" ) input_scan = os.path.join( self.input_dir, "sample", "sample_29042021", "scan0002" ) output_proposal_file = os.path.join( self.output_dir, "sample", "ihpayno_sample.h5" ) output_sample_file = os.path.join( self.output_dir, "sample", "sample_29042021", "sample_29042021.h5" ) self.assertTrue(os.path.exists(output_scan)) self.assertEqual(len(os.listdir(output_scan)), len(os.listdir(input_scan))) self.assertTrue(os.path.exists(output_proposal_file)) self.assertTrue(os.path.exists(output_sample_file)) other_scan_dir = os.path.join(self.output_dir, "sample", "scan0004") self.assertFalse(os.path.exists(other_scan_dir)) class TestPreTransfert(unittest.TestCase): """Test the pretransfert actions""" def setUp(self): unittest.TestCase.setUp(self) folderDataset = TomwerCIDatasets.get_dataset("edf_datasets/scan_3_") self.tmpdir = tempfile.mkdtemp() self.outputfolder = tempfile.mkdtemp() scan_path = os.path.join(self.tmpdir, "scan_3_") shutil.copytree(src=folderDataset, dst=scan_path) self.scan = ScanFactory.create_scan_object(scan_path=scan_path) def tearDown(self): unittest.TestCase.tearDown(self) for _dir in (self.tmpdir, self.outputfolder): if os.path.exists(_dir): shutil.rmtree(_dir) def testParFile(self): """Make sure the `scan_3_.par` is correctly updated when moved""" parDict = self.getParDict(os.path.join(self.scan.path, "scan_3_.par")) assert ( parDict["file_prefix"] == "/data/visitor/mi1226/id19/nemoz/henri/scan_3_/scan_3_" ) assert ( parDict["ff_prefix"] == "/data/visitor/mi1226/id19/nemoz/henri/scan_3_/refHST" ) rebaseParFile( os.path.join(self.scan.path, "scan_3_.par"), oldfolder="/data/visitor/mi1226/id19/nemoz/henri/scan_3_", newfolder=self.scan.path, ) parDict = self.getParDict(os.path.join(self.scan.path, "scan_3_.par")) self.assertTrue( parDict["file_prefix"] == os.path.join(self.scan.path, "scan_3_") ) self.assertTrue(parDict["ff_prefix"] == os.path.join(self.scan.path, "refHST")) folderTrans = ScanTransfer( inputs={ "turn_off_print": True, "copying": False, "dest_dir": self.outputfolder, "data": self.scan, "move": False, "overwrite": True, "noRsync": True, } ) folderTrans.run() parDict = self.getParDict( os.path.join(self.outputfolder, "scan_3_", "scan_3_.par") ) self.assertTrue( parDict["file_prefix"] == os.path.join(self.outputfolder, "scan_3_", "scan_3_") ) self.assertTrue( parDict["ff_prefix"] == os.path.join(self.outputfolder, "scan_3_", "refHST") ) @staticmethod def getParDict(_file): assert os.path.isfile(_file) ddict = {} f = open(_file, "r") lines = f.readlines() for line in lines: if "=" not in line: continue line_str = line.rstrip().replace(" ", "") line_str = line_str.split("#")[0] key, value = line_str.split("=") ddict[key.lower()] = value return ddict ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9811025 tomwer-1.6.17/src/tomwer/synctools/utils/0000755000175000017500000000000015153325403017523 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/synctools/utils/__init__.py0000644000175000017500000000000014757047403021634 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/synctools/utils/scanstages.py0000644000175000017500000001716515153325210022236 0ustar00paynopayno# coding: utf-8 """ Utils to mock scans """ from __future__ import annotations import glob import os import shutil from silx.io.url import DataUrl from enum import Enum as _Enum from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.synctools.rsyncmanager import RSyncManager class ScanStages: """ Util class to copy all the files of scan to a destination dir until a define advancement of the acquisition. :param scan: scan to copy. """ class AcquisitionStage(_Enum): ACQUI_NOT_STARTED = (0,) ACQUI_STARTED = (1,) ACQUI_ON_GOING = (2,) ACQUI_ENDED = (3,) RECONSTRUCTION_ADDED = (4,) COMPLETE = (99,) def get_command_name(self): """Return the name of the AcquisitionStage to give by a command option""" return self.name.lower().replace("_", "-") @staticmethod def get_command_names(): return [stage.get_command_name() for stage in ScanStages.AcquisitionStage] @staticmethod def from_command_name(name): """Return the AcquisitionStage fitting a command option""" name_ = name.replace("-", "_").upper() return getattr(ScanStages.AcquisitionStage, name_) def __init__(self, scan: TomwerScanBase): assert isinstance(scan, TomwerScanBase) self.scan = scan def rsync_until(self, stage: AcquisitionStage, dest_dir: str) -> None: """ :param stage: :param dest_dir: """ stage = ScanStages.AcquisitionStage(stage) if not dest_dir.endswith(os.path.basename(self.scan.path)): dest_dir = os.path.join(dest_dir, os.path.basename(self.scan.path)) for t_stage in ScanStages.AcquisitionStage: if t_stage.value <= stage.value: self._rsync_stage(t_stage, dest_dir=dest_dir) def _rsync_stage(self, stage: AcquisitionStage, dest_dir: str) -> None: """ Synchronize a specific stage of scan to the given destination directory :param stage: stage to copy :param dest_dir: """ if not dest_dir.endswith(os.path.basename(self.scan.path)): dest_dir = os.path.join(dest_dir, os.path.basename(self.scan.path)) stage = ScanStages.AcquisitionStage(stage) if stage is ScanStages.AcquisitionStage.ACQUI_NOT_STARTED: return elif stage is ScanStages.AcquisitionStage.ACQUI_STARTED: if isinstance(self.scan, EDFTomoScan): if not os.path.isdir(dest_dir): os.makedirs(dest_dir) info_file = self.scan.get_info_file(self.scan.path) if info_file is not None: file_info_dest = os.path.join(dest_dir, os.path.basename(info_file)) RSyncManager().sync_file( source=info_file, target=file_info_dest, wait=True ) elif isinstance(self.scan, NXtomoScan): raise NotImplementedError() elif stage is ScanStages.AcquisitionStage.ACQUI_ON_GOING: # copy half of the acquisition file if isinstance(self.scan, EDFTomoScan): urls = self.scan.projections n_url = len(urls) // 2 keys = list(urls.keys()) while n_url > 0: n_url -= 1 self._copy_url_file(url=urls[keys[n_url]], dest_dir=dest_dir) elif isinstance(self.scan, NXtomoScan): raise NotImplementedError() elif stage is ScanStages.AcquisitionStage.ACQUI_ENDED: if isinstance(self.scan, EDFTomoScan): for _, url in self.scan.projections.items(): file_target = url.file_path().replace(self.scan.path, dest_dir) if not os.path.exists(file_target): self._copy_url_file(url=url, dest_dir=dest_dir) xml_file = os.path.join( self.scan.path, os.path.basename(self.scan.path) + ".xml" ) xml_dest = os.path.join(dest_dir, os.path.basename(xml_file)) RSyncManager().sync_file(source=xml_file, target=xml_dest, wait=True) elif isinstance(self.scan, NXtomoScan): raise NotImplementedError() elif stage is ScanStages.AcquisitionStage.RECONSTRUCTION_ADDED: # copy reconstruction if isinstance(self.scan, EDFTomoScan): pyhst_files = EDFTomoScan.get_pyhst_recons_file(scanID=self.scan.path) if pyhst_files: for par_file in pyhst_files: par_file_dst = os.path.join( dest_dir, os.path.basename(par_file) ) RSyncManager().sync_file( source=par_file, target=par_file_dst, wait=True ) for reconstructed_file in EDFTomoScan.get_reconstructions_paths( scanID=self.scan.path ): assert os.path.isfile(reconstructed_file) recons_file_dest = os.path.join( dest_dir, os.path.basename(reconstructed_file) ) RSyncManager().sync_file( source=reconstructed_file, target=recons_file_dest, wait=True ) for par_file in glob.glob(os.path.join(self.scan.path, "*.par")): par_file_src = os.path.join(self.scan.path, par_file) par_file_dst = os.path.join(dest_dir, os.path.basename(par_file)) RSyncManager().sync_file( source=par_file_src, target=par_file_dst, wait=True ) # copy some info file that can came from .vol files for info_file in glob.glob(os.path.join(self.scan.path, "*.info")): info_file_src = os.path.join(self.scan.path, info_file) info_file_dst = os.path.join(dest_dir, os.path.basename(info_file)) RSyncManager().sync_file( source=info_file_src, target=info_file_dst, wait=True ) # copy some xml file that can came from pyhst xml_files = glob.glob(os.path.join(self.scan.path, "*.xml")) for xml_file in xml_files: _xml_file = os.path.join(self.scan.path, xml_file) xml_dest = os.path.join(dest_dir, os.path.basename(_xml_file)) RSyncManager().sync_file( source=_xml_file, target=xml_dest, wait=True ) elif isinstance(self.scan, NXtomoScan): raise NotImplementedError() elif stage is ScanStages.AcquisitionStage.COMPLETE: if isinstance(self.scan, EDFTomoScan): for file_ in os.listdir(self.scan.path): file_fp = os.path.join(self.scan.path, file_) RSyncManager().sync_file(source=file_fp, target=dest_dir, wait=True) elif isinstance(self.scan, NXtomoScan): raise NotImplementedError() else: raise ValueError("given stage is not recognized", stage) def _copy_url_file(self, url, dest_dir): assert isinstance(url, DataUrl) file_target = url.file_path().replace(self.scan.path, dest_dir) if not os.path.exists(file_target): shutil.copyfile(src=url.file_path(), dst=file_target) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9811025 tomwer-1.6.17/src/tomwer/tasks/0000755000175000017500000000000015153325403015453 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tasks/__init__.py0000644000175000017500000000000015153325210017546 0ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9811025 tomwer-1.6.17/src/tomwer/tasks/script/0000755000175000017500000000000015153325403016757 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/tasks/script/__init__.py0000644000175000017500000000000015143647637021075 0ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tasks/script/python.py0000644000175000017500000000323715153325210020653 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import code import logging from tomwer.core.process.task import Task from tomwer.core.scan.scanbase import TomwerScanBase from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils.scanutils import data_identifier_to_scan from tomwer.core.utils.volumeutils import volume_identifier_to_volume _logger = logging.getLogger(__name__) class PythonScript( Task, input_names=("scriptText",), optional_input_names=( "data", "volume", "serialize_output_data", "process_id", ), output_names=("data", "volume"), ): def run(self): # load data scan = data_identifier_to_scan(self.inputs.data) if isinstance(scan, dict): scan = ScanFactory.create_scan_object_frm_dict(scan) elif isinstance(scan, (TomwerScanBase, type(None))): scan = scan else: raise ValueError(f"input type of {scan}: {type(scan)} is not managed") # load volume volume = volume_identifier_to_volume(self.inputs.volume) interpreter = code.InteractiveConsole(locals={"in_data": scan}) interpreter = code.InteractiveConsole(locals={"in_volume": volume}) interpreter.runcode(self.inputs.scriptText) out_data = data_identifier_to_scan(interpreter.locals.get("out_data")) out_volume = data_identifier_to_scan(interpreter.locals.get("out_volume")) if out_data is not None and self.get_input_value("serialize_output_data", True): self.outputs.data = out_data.to_dict() else: self.outputs.data = out_data self.outputs.volume = out_volume ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9811025 tomwer-1.6.17/src/tomwer/tasks/tests/0000755000175000017500000000000015153325403016615 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tasks/tests/test_script.py0000644000175000017500000000111715153325210021526 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os from tomwer.core.utils.scanutils import MockNXtomo from tomwer.tasks.script.python import PythonScript def test_python_script(tmp_path): test_dir = tmp_path / "test_dir" test_dir.mkdir() dim = 10 scan = MockNXtomo( scan_path=os.path.join(test_dir, "scan1"), n_proj=10, n_ini_proj=10, scan_range=180, dim=dim, ).scan task = PythonScript( inputs={ "data": scan, "scriptText": "print('toto')", }, ) task.execute() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9811025 tomwer-1.6.17/src/tomwer/tasks/visualization/0000755000175000017500000000000015153325403020354 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tasks/visualization/volume_viewer.py0000644000175000017500000000435515153325210023621 0ustar00paynopaynoimport numpy from copy import deepcopy from ewokscore.task import Task as EwoksTask from tomwer.model.volume_viewer import VolumeViewerModel from tomwer.core.volume.volumebase import TomwerVolumeBase class VolumeViewerTask( EwoksTask, input_model=VolumeViewerModel, output_names=("slices", "volume_metadata", "volume_shape", "loaded_volume"), ): """Function loading a three slices into each direction and volume metadata and create a 'summary' of the reconstructed volume""" N_SLICES_PER_AXIS = 3 def run(self): volume = self.inputs.volume assert isinstance( volume, TomwerVolumeBase ), f"volume should be an instance of {TomwerVolumeBase}. got {type(volume)}" if self.inputs.load_volume: loaded_volume = deepcopy(volume) loaded_volume.load_data(store=True) self.outputs.loaded_volume = loaded_volume else: self.outputs.loaded_volume = None self.outputs.slices = volume.get_slices(slices=self.get_slices_to_extract()) self.outputs.volume_metadata = ( self.inputs.volume.metadata or self.inputs.volume.load_metadata() ) self.outputs.volume_shape = volume.get_volume_shape() def get_slices_to_extract(self) -> tuple[tuple[int, tuple[int]]]: """ Return the indices of the slices to extract on each axis (N_SLICES_PER_AXIS on each axis). return tuple (A) is a two elements tuple. First element if the axis (B). Second is the tuple of indices to extract along the axis (B) indices are equally spaced in each dimensions """ result: list[tuple[int, tuple[int]]] = [] volume = self.inputs.volume if not isinstance(volume, TomwerVolumeBase): raise TypeError( f"Volume is expected to be an instance of {TomwerVolumeBase}. Got {type(volume)}" ) volume_shape = volume.get_volume_shape() for axis, axis_len in enumerate(volume_shape): for slice_index in numpy.linspace( 0, axis_len, endpoint=False, num=self.N_SLICES_PER_AXIS + 1 )[1:]: result.append((axis, numpy.round(slice_index).astype(numpy.uint16))) return tuple(result) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9811025 tomwer-1.6.17/src/tomwer/tests/0000755000175000017500000000000015153325403015470 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/tests/__init__.py0000644000175000017500000000002314757047403017606 0ustar00paynopayno"""tomwer tests""" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9811025 tomwer-1.6.17/src/tomwer/tests/app/0000755000175000017500000000000015153325403016250 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1765263549.0 tomwer-1.6.17/src/tomwer/tests/app/test_stitching.py0000644000175000017500000001006215115744275021666 0ustar00paynopaynoimport pytest from nabu.stitching.config import StitchingType from nabu.stitching.tests import test_y_preprocessing_stitching from nabu.stitching.tests import test_z_preprocessing_stitching from nabu.stitching.tests import test_z_postprocessing_stitching from tomwer.app.stitching.common import MainWindow from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.volume.volumefactory import VolumeFactory from tomoscan.esrf.volume import HDF5Volume as _tomoscan_HDF5Volume from tomwer.tests.conftest import qtapp # noqa F401 def _create_objects_for_stitching(stitching_type: StitchingType, output_dir) -> tuple: """ create tomo object (scans or volumes) and return them with there position along the axis to stitch """ def cast_tomoscan_scans_to_tomwer_scans(scans: tuple) -> tuple: return tuple( [NXtomoScan(scan=scan.master_file, entry=scan.entry) for scan in scans] ) def cast_tomoscan_volumes_to_tomwer_volumes(volumes: tuple) -> tuple: return tuple( [ VolumeFactory.create_tomo_object_from_identifier( volume.get_identifier().to_str() ) for volume in volumes ] ) stitching_type = StitchingType(stitching_type) if stitching_type is StitchingType.Y_PREPROC: nxtomos, positions, _ = test_y_preprocessing_stitching.build_nxtomos( output_dir=output_dir, flip_lr=False, flip_ud=False ) return cast_tomoscan_scans_to_tomwer_scans(nxtomos), positions elif stitching_type is StitchingType.Z_PREPROC: nxtomos, positions, _ = test_z_preprocessing_stitching.build_nxtomos( output_dir=output_dir ) return cast_tomoscan_scans_to_tomwer_scans(nxtomos), positions elif stitching_type is StitchingType.Z_POSTPROC: volumes, positions, _ = test_z_postprocessing_stitching.build_volumes( output_dir=output_dir, volume_class=_tomoscan_HDF5Volume ) return cast_tomoscan_volumes_to_tomwer_volumes(volumes), positions else: raise NotImplementedError() @pytest.mark.parametrize("stitching_type", StitchingType) def test_stitching_on_projections(stitching_type, tmp_path, qtapp): # noqa F401 if stitching_type in (StitchingType.Z_PREPROC, StitchingType.Z_POSTPROC): axis = 0 elif stitching_type is StitchingType.Y_PREPROC: axis = 1 else: raise NotImplementedError widget = MainWindow(axis=axis) output_dir = tmp_path / "input_objs" output_dir.mkdir() tomo_objects, positions = _create_objects_for_stitching(stitching_type, output_dir) positions_dict = {} for tomo_object, position in zip(tomo_objects, positions): widget.addTomoObj(tomo_object) positions_dict[tomo_object.get_identifier().to_str()] = position pos_widget = ( widget._mainWindow._stitchingConfigWindow._editTomoObjFirstAxisPositionsWidget._tomoObjtoTomoObjPosWidget ) # make sure the position over the axis to stitch are valid for tomo_obj, w in pos_widget.items(): assert positions_dict[tomo_obj] == w.getOriginalValue() stitching_configuration = widget.getStitchingConfiguration() second_axis = widget._mainWindow._stitchingConfigWindow.second_axis # only the axis of the stitching is defined. When launching the widget we don't know if this is pre-processing or post-processing assert stitching_configuration["stitching"]["type"][0] == stitching_type.value[0] assert len(stitching_configuration["inputs"]["input_datasets"]) == len(tomo_objects) assert stitching_configuration["stitching"][f"axis_{axis}_pos_px"] == sorted( positions, reverse=True ) # at the moment the 'overlap' size is only handled and provided for the 'main axis (stitching axis) assert "overlap_size" in stitching_configuration["stitching"][f"axis_{axis}_params"] assert ( "overlap_size" not in stitching_configuration["stitching"][f"axis_{second_axis}_params"] ) assert "axis_2_params" not in stitching_configuration["stitching"] ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/conftest.py0000644000175000017500000000357015153325210017670 0ustar00paynopaynoimport gc import os import logging import pytest from ewoksorange.bindings.qtapp import get_all_qtwidgets, qtapp_context _logger = logging.getLogger(__name__) def global_cleanup_orange(): from orangecanvas.document.suggestions import Suggestions Suggestions.instance = None def global_cleanup_pytest(): for obj in gc.get_objects(): if isinstance(obj, logging.LogRecord): obj.exc_info = None # traceback keeps frames which keep locals def collect_garbage(app): if app is None: return app.processEvents() while gc.collect(): app.processEvents() @pytest.fixture(scope="session") def qtapp(): """ create a Qt application if doesn't exists """ with qtapp_context() as app: yield app collect_garbage(app) global_cleanup_orange() global_cleanup_pytest() collect_garbage(app) warn_qtwidgets_alive() def warn_qtwidgets_alive(): widgets = get_all_qtwidgets() if widgets: _logger.warning( "%d remaining widgets after tests:\n %s", len(widgets), "\n ".join(map(str, widgets)), ) @pytest.fixture(scope="function") def nxtomo_scan_180(tmp_path): test_path = tmp_path / "test" test_path.mkdir() yield create_default_scan( scan_path=os.path.join(test_path, "scan_180"), scan_range=180, ) @pytest.fixture(scope="function") def nxtomo_scan_360(tmp_path): test_path = tmp_path / "test" test_path.mkdir() yield create_default_scan( scan_path=os.path.join(test_path, "scan_360"), scan_range=360, ) def create_default_scan(scan_path: str, scan_range: int): from tomwer.core.utils.scanutils import MockNXtomo return MockNXtomo( scan_path=scan_path, n_proj=10, n_ini_proj=10, scan_range=scan_range, dim=20, energy=12.3, ).scan ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1771517244.0 tomwer-1.6.17/src/tomwer/tests/datasets.py0000644000175000017500000000052315145632474017664 0ustar00paynopaynofrom tomoscan.tests.datasets import GitlabProject from platformdirs import PlatformDirs _dirs = PlatformDirs("tomwer") TomwerCIDatasets = GitlabProject( branch_name="tomwer", host="https://gitlab.esrf.fr", cache_dir=_dirs.user_cache_dir, token=None, project_id=4299, # https://gitlab.esrf.fr/tomotools/ci_datasets ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8771002 tomwer-1.6.17/src/tomwer/tests/orangecontrib/0000755000175000017500000000000015153325403020324 5ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8771002 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/0000755000175000017500000000000015153325403021641 5ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9851027 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/0000755000175000017500000000000015153325403023307 5ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8771002 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/cluster/0000755000175000017500000000000015153325403024770 5ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9851027 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/cluster/tests/0000755000175000017500000000000015153325403026132 5ustar00paynopayno././@PaxHeader0000000000000000000000000000020500000000000010212 xustar00111 path=tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/cluster/tests/test_future_supervisorow.py 22 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/cluster/tests/test_future_supervisorow.p0000644000175000017500000000231515153325210033530 0ustar00paynopaynofrom tomwer.tests.conftest import qtapp # noqa F401 import asyncio import os import pytest from orangecontrib.tomwer.widgets.cluster.FutureSupervisorOW import FutureSupervisorOW from tomwer.core.futureobject import FutureTomwerObject from tomwer.core.utils.scanutils import MockNXtomo from tomwer.tests.utils import skip_gui_test @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") def test_FutureSupervisorOW( qtapp, # noqa F811 tmp_path, ): window = FutureSupervisorOW() test_dir = tmp_path / "scans_folder" test_dir.mkdir() # set up scans scans = [] future_tomo_objs = [] for i in range(5): # create scan scan = MockNXtomo( scan_path=os.path.join(test_dir, f"scan_test{i}"), n_proj=10, n_ini_proj=10, create_ini_dark=False, create_ini_flat=False, dim=10, ).scan scans.append(scan) # create future future = asyncio.Future() if i == 1: future.set_result(None) future_tomo_objs.append( FutureTomwerObject( tomo_obj=scan, futures=(future,), ) ) window.close() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/cluster/tests/test_slurm_clusterow.py0000644000175000017500000000227415153325210033015 0ustar00paynopaynofrom __future__ import annotations import gc import pickle import pytest from orangecanvas.scheme.readwrite import literal_dumps from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.cluster.SlurmClusterOW import SlurmClusterOW from tomwer.core.cluster.cluster import SlurmClusterConfiguration from tomwer.tests.utils import skip_gui_test @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestSlurmClusterOW(TestCaseQt): """Test that the axis widget work correctly""" def setUp(self): super().setUp() self._window = SlurmClusterOW() def tearDown(self): self._window.setAttribute(qt.Qt.WA_DeleteOnClose) self._window.close() self._window = None gc.collect() def test(self): self._window.show() self.qWaitForWindowExposed(self._window) configuration = self._window.getConfiguration() assert isinstance(configuration, SlurmClusterConfiguration) def test_serializing(self): pickle.dumps(self._window.getConfiguration().to_dict()) def test_literal_dumps(self): literal_dumps(self._window.getConfiguration().to_dict()) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8771002 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/control/0000755000175000017500000000000015153325403024767 5ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9851027 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/0000755000175000017500000000000015153325403026131 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_advancement.py0000644000175000017500000000031714757047403032042 0ustar00paynopayno# coding: utf-8 from tomwer.tests.conftest import qtapp # noqa F401 from orangecontrib.tomwer.widgets.control.AdvancementOW import AdvancementOW def test_totsaso(qtapp): # noqa F401 AdvancementOW() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_data_validator.py0000644000175000017500000000301314757047403032527 0ustar00paynopaynoimport gc import os import shutil import tempfile from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.control.DataValidatorOW import DataValidatorOW from tomwer.core.utils.scanutils import MockNXtomo class TestDataValidatorOW(TestCaseQt): """ simple test on the DataValidatorOW widget """ def setUp(self): super().setUp() self.window = DataValidatorOW() self.folder = tempfile.mkdtemp() self.scan_1 = MockNXtomo( scan_path=os.path.join(self.folder, "scan_1"), n_proj=20, n_ini_proj=20, dim=10, ).scan self.scan_2 = MockNXtomo( scan_path=os.path.join(self.folder, "scan_2"), n_proj=20, n_ini_proj=20, dim=10, ).scan def tearDown(self): self.window.setAttribute(qt.Qt.WA_DeleteOnClose) self.window.close() self.window = None shutil.rmtree(self.folder) gc.collect() def test(self): def wait_processing(): while self.qapp.hasPendingEvents(): self.qapp.processEvents() assert self.window.getNScanToValidate() == 0 self.window.addScan(self.scan_1) wait_processing() self.window.addScan(self.scan_2) wait_processing() assert self.window.getNScanToValidate() == 2 self.window._widget.validateCurrentScan() wait_processing() assert self.window.getNScanToValidate() == 1 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_datadiscovery.py0000644000175000017500000001125115153325210032377 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc import os import pickle import tempfile from orangecanvas.scheme.readwrite import literal_dumps from silx.gui import qt from silx.gui.utils.testutils import SignalListener, TestCaseQt from orangecontrib.tomwer.widgets.control.DataDiscoveryOW import DataDiscoveryOW from tomwer.core.scan.scantype import ScanType from tomwer.core.utils.scanutils import MockBlissAcquisition from tomoscan.esrf.scan.mock import MockNXtomo, MockEDF class TestDataDiscovery(TestCaseQt): WAIT_TIME = 5000 # thread processing wait time in ms def setUp(self): super().setUp() self.widget = DataDiscoveryOW() self.widget.setConfiguration(self.default_settings) self.signal_listener = SignalListener() self.widget.getProcessingThread().sigDataFound.connect(self.signal_listener) def tearDown(self): self.widget.getProcessingThread().sigDataFound.disconnect(self.signal_listener) self.signal_listener = None self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None gc.collect() @property def default_settings(self): return { "start_folder": "/my/folder", "file_filter": "*.h5", "scan_type_searched": ScanType.NX_TOMO, } def testSerialization(self): """make sure pickling works for the settings""" pickle.dumps(self.widget.getConfiguration()) def testLiteralDumps(self): """make sure literal dumps (from orangecanvas) works for the settings""" literal_dumps(self.widget.getConfiguration()) def testProcessingNXtomo(self): """Test the widget can find NXtomos""" n_scan = 3 with tempfile.TemporaryDirectory() as root_dir: for i_scan in range(n_scan): MockNXtomo( scan_path=os.path.join(root_dir, f"sub_folder_{i_scan}", "scan"), n_proj=10, n_ini_proj=10, dim=10, ) self.widget.setFolderObserved(root_dir) self.widget.start_discovery(wait=self.WAIT_TIME) while self.qapp.hasPendingEvents(): self.qapp.processEvents() assert self.signal_listener.callCount() == n_scan def testProcessingBlissRawScan(self): """Test the widget can find bliss raw scans""" with tempfile.TemporaryDirectory() as root_dir: n_scan = 2 for i_scan in range(n_scan): MockBlissAcquisition( n_sample=1, n_sequence=1, n_scan_per_sequence=1, n_darks=1, n_flats=1, with_nx=True, output_dir=os.path.join(root_dir, f"sub_folder_{i_scan}", "scan"), ) self.widget.setFilePattern("*.edf") self.widget.setSearchScanType(ScanType.BLISS) self.widget.setFolderObserved(root_dir) self.widget.start_discovery(wait=self.WAIT_TIME) while self.qapp.hasPendingEvents(): self.qapp.processEvents() assert ( self.signal_listener.callCount() == 0 ) # because of the filtering on files self.widget.setFilePattern(None) self.widget.start_discovery(wait=self.WAIT_TIME) while self.qapp.hasPendingEvents(): self.qapp.processEvents() assert self.signal_listener.callCount() == n_scan def testProcessingSpecScan(self): """Test the widget can find bliss raw scans""" with tempfile.TemporaryDirectory() as root_dir: n_scan = 4 for i_scan in range(n_scan): MockEDF( n_radio=4, n_ini_radio=4, scan_path=os.path.join(root_dir, f"sub_folder_{i_scan}", "scan"), ) self.widget.setSearchScanType(ScanType.BLISS) self.widget.setFilePattern(None) self.widget.setFolderObserved(root_dir) self.widget.start_discovery(wait=self.WAIT_TIME) while self.qapp.hasPendingEvents(): self.qapp.processEvents() assert ( self.signal_listener.callCount() == 0 ) # because of the scan type searched self.widget.setSearchScanType(ScanType.SPEC) self.widget.setFilePattern(None) self.widget.start_discovery(wait=self.WAIT_TIME) while self.qapp.hasPendingEvents(): self.qapp.processEvents() assert self.signal_listener.callCount() == n_scan ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_datalistener.py0000644000175000017500000000110215153325210032207 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc import pickle from silx.gui import qt from tomwer.tests.conftest import qtapp # noqa F401 from orangecontrib.tomwer.widgets.deprecated.DataListenerOW import DataListenerOW from orangecanvas.scheme.readwrite import literal_dumps def test_DataListenerOW( qtapp, # noqa F811 ): widget = DataListenerOW(host_discovery=False) pickle.dumps(widget.get_configuration()) literal_dumps(widget.get_configuration()) widget.setAttribute(qt.Qt.WA_DeleteOnClose) widget.close() gc.collect() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_dataselector.py0000644000175000017500000000405515153325210032214 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc import os import pickle import shutil import tempfile from orangecanvas.scheme.readwrite import literal_dumps from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.control.DataSelectorOW import DataSelectorOW from tomwer.core.utils.scanutils import MockNXtomo from tomwer.synctools.axis import QAxisRP class TestDataSelectorOw(TestCaseQt): def setUp(self): super().setUp() self.tempdir = tempfile.mkdtemp() dim = 10 mock = MockNXtomo( scan_path=os.path.join(self.tempdir, "scan1"), n_proj=10, n_ini_proj=10, scan_range=180, dim=dim, ) self.scan1 = mock.scan mock = MockNXtomo( scan_path=os.path.join(self.tempdir, "scan2"), n_proj=10, n_ini_proj=10, scan_range=180, dim=dim, ) self.scan2 = mock.scan self.widget = DataSelectorOW() def tearDown(self): self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None shutil.rmtree(self.tempdir) gc.collect() def test(self): for scan in (self.scan1, self.scan2): assert scan.axis_params is None scan.axis_params = QAxisRP() self.widget.add(scan) self.qapp.processEvents() scan_1_identifier = scan.get_identifier() assert scan_1_identifier.to_str() in self.widget.widget.dataList._myitems item = self.widget.widget.dataList._myitems[scan_1_identifier.to_str()] data_obj = item.data(qt.Qt.UserRole) assert id(scan) == id(data_obj) assert scan.axis_params is not None self.widget.selectAll() self.widget.send() self.qapp.processEvents() # test serialization assert len(self.widget._scanIDs) == 2 pickle.dumps(self.widget._scanIDs) literal_dumps(self.widget._scanIDs) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_datawatcher.py0000644000175000017500000003411315153325210032027 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc import logging import os import shutil import tempfile import time from time import sleep from silx.gui import qt from silx.gui.utils.testutils import SignalListener, TestCaseQt from orangecontrib.tomwer.tests.TestAcquisition import Simulation from orangecontrib.tomwer.widgets.control.DataWatcherOW import DataWatcherOW from tomwer.core.process.control.datawatcher import status as datawatcherstatus from tomwer.core.utils.scanutils import MockBlissAcquisition, MockNXtomo logging.disable(logging.INFO) class DataWatcherWaiter(TestCaseQt): """Define a simple objecy able to wait for some state of the DataWatcher arrive""" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.reset() self.lastStatus = [] def tearDown(self): pass def reset(self): self.lastStatus = [] def stateHasChanged(self, val): """Register all status""" if val not in self.lastStatus: self.lastStatus.append(val) def waitForState(self, state, maxWaiting): """simple function wich wait until the DataWatcherWidget reach the given state. If the widget doesn't reach this state after maxWaiting second. Then fail. :param state: the state we are waiting for :param maxWaiting: the maximal number of second to wait until failling. """ while state not in self.lastStatus: time.sleep(1.0) self.qapp.processEvents() maxWaiting -= 1 if maxWaiting <= 0: return False return state in self.lastStatus class TestDataWatcherAcquisition(DataWatcherWaiter): """Functions testing the classical behavior of data watcher - signal acquisition is over only when all files are copied """ def tearDown(self): while self.qapp.hasPendingEvents(): self.qapp.processEvents() self.dataWatcherWidget.setObservation(False) self.dataWatcherWidget.close() del self.dataWatcherWidget self.dataWatcherWidget = None self.s.wait() del self.s if os.path.isdir(self.inputdir): shutil.rmtree(self.inputdir) gc.collect() super().tearDown() def setUp(self): self.manipulationId = "test10" super().setUp() self.inputdir = tempfile.mkdtemp() DataWatcherWaiter.reset(self) self.dataWatcherWidget = DataWatcherOW(displayAdvancement=False) self.dataWatcherWidget.srcPattern = "" self.dataWatcherWidget.sigTMStatusChanged.connect(self.stateHasChanged) self.dataWatcherWidget.setAttribute(qt.Qt.WA_DeleteOnClose) self.s = Simulation( self.inputdir, self.manipulationId, finalState=Simulation.advancement["acquisitionRunning"], ) def testStartAcquisition(self): """Make sure the data watch detect the acquisition of started""" observeDir = os.path.join(self.inputdir, self.manipulationId) for folder in (self.inputdir, observeDir): if not os.path.exists(folder): os.makedirs(folder) self.assertTrue(os.path.isdir(observeDir)) self.s.createFinalXML(True) self.dataWatcherWidget.setFolderObserved(observeDir) self.assertTrue(self.dataWatcherWidget.currentStatus == "not processing") self.s.start() self.s.advanceTo("acquisitionDone") self.s.start() self.s.wait() self.dataWatcherWidget.startObservation() self.dataWatcherWidget._widget.observationThread.wait() self.dataWatcherWidget._widget.observationThread.observations.dict[ observeDir ].wait() self.qapp.processEvents() finishedAcqui = ( self.dataWatcherWidget._widget.observationThread.observations.ignoredFolders ) self.qapp.processEvents() self.assertTrue(observeDir in finishedAcqui) class TestDataWatcherInteraction(TestCaseQt): """Simple unit test to test the start/stop observation button action""" def setUp(self): super().setUp() self.inputdir = tempfile.mkdtemp() self.dataWatcherWidget = DataWatcherOW(displayAdvancement=False) self.dataWatcherWidget.setAttribute(qt.Qt.WA_DeleteOnClose) self.dataWatcherWidget.srcPattern = "" def tearDown(self): while self.qapp.hasPendingEvents(): self.qapp.processEvents() self.dataWatcherWidget.close() del self.dataWatcherWidget if os.path.isdir(self.inputdir): shutil.rmtree(self.inputdir) gc.collect() def testStartAndStopAcquisition(self): """test multiple start and stop action on the start observation to make sure no crash are appearing """ try: self.dataWatcherWidget.setFolderObserved(self.inputdir) self.dataWatcherWidget.show() self.dataWatcherWidget.setObservation(True) for _ in range(5): self.dataWatcherWidget._widget._qpbstartstop.pressed.emit() self.assertTrue(True) except Exception: self.assertTrue(False) class WaitForXMLOption(DataWatcherWaiter): """test the behavior of datawatcher when the option 'wait for xml copy' Basically in this case DataWatcherDirObserver will wait until an .xml arrived """ @classmethod def setUpClass(cls): cls.dataWatcherWidget = DataWatcherOW(displayAdvancement=False) cls.dataWatcherWidget.setAttribute(qt.Qt.WA_DeleteOnClose) cls.dataWatcherWidget.obsMethod = datawatcherstatus.DET_END_XML cls.dataWatcherWidget.srcPattern = "" cls.manipulationId = "test10" super().setUpClass() def setUp(self): self.inputdir = tempfile.mkdtemp() self.reset() self.dataWatcherWidget.setObservation(False) self.dataWatcherWidget.resetStatus() super().setUp() def tearDown(self): while self.qapp.hasPendingEvents(): self.qapp.processEvents() if os.path.isdir(self.inputdir): shutil.rmtree(self.inputdir) gc.collect() super().tearDown() @classmethod def tearDownClass(cls): cls.dataWatcherWidget.close() del cls.dataWatcherWidget if hasattr(cls, "s"): cls.s.quit() del cls.s super().tearDownClass() def testAcquistionNotEnding(self): """Check behavior if an acquisition never end""" observeDir = os.path.join(self.inputdir, self.manipulationId) for folder in (self.inputdir, observeDir): if not os.path.exists(folder): os.makedirs(folder) self.assertTrue(os.path.isdir(observeDir)) self.s = Simulation( self.inputdir, self.manipulationId, finalState=Simulation.advancement["acquisitionRunning"], ) self.dataWatcherWidget.setFolderObserved(observeDir) self.dataWatcherWidget.show() self.dataWatcherWidget.sigTMStatusChanged.connect(self.stateHasChanged) self.assertTrue(self.dataWatcherWidget.currentStatus == "not processing") self.s.start() self.s.wait() self.dataWatcherWidget.setObservation(True) self.dataWatcherWidget._widget.observationThread.wait() self.dataWatcherWidget._widget.observationThread.observations.dict[ observeDir ].wait() finishedAcqui = ( self.dataWatcherWidget._widget.observationThread.observations.ignoredFolders ) self.qapp.processEvents() self.assertFalse(observeDir in finishedAcqui) def testAcquistionEnded(self): """Check behavior if an acquisition is ending""" manipulationId = "test10" observeDir = os.path.join(self.inputdir, self.manipulationId) for folder in (self.inputdir, observeDir): if not os.path.exists(folder): os.makedirs(folder) self.assertTrue(os.path.isdir(observeDir)) self.s = Simulation( self.inputdir, manipulationId, finalState=Simulation.advancement["acquisitionDone"], ) self.s.createFinalXML(True) self.dataWatcherWidget.setFolderObserved(observeDir) self.dataWatcherWidget.show() self.dataWatcherWidget.sigTMStatusChanged.connect(self.stateHasChanged) self.assertTrue(self.dataWatcherWidget.currentStatus == "not processing") self.s.start() self.s.wait() self.dataWatcherWidget.setObservation(True) self.dataWatcherWidget._widget.observationThread.wait() self.dataWatcherWidget._widget.observationThread.observations.dict[ observeDir ].wait() finishedAcqui = ( self.dataWatcherWidget._widget.observationThread.observations.ignoredFolders ) self.qapp.processEvents() self.assertTrue(observeDir in finishedAcqui) class TestRSync(DataWatcherWaiter): """test that the synchronization using RSyncManager is working""" def setUp(self): super().setUp() self.inputdir = tempfile.mkdtemp() self.outputdir = tempfile.mkdtemp() DataWatcherWaiter.reset(self) self.dataWatcherWidget = DataWatcherOW(displayAdvancement=False) self.dataWatcherWidget.setAttribute(qt.Qt.WA_DeleteOnClose) self.dataWatcherWidget._widget.setSrcAndDestPattern( self.inputdir, self.outputdir ) def tearDown(self): while self.qapp.hasPendingEvents(): self.qapp.processEvents() self.dataWatcherWidget.close() del self.dataWatcherWidget if hasattr(self, "s"): self.s.quit() del self.s super(TestRSync, self).tearDown() for d in (self.inputdir, self.outputdir): if os.path.isdir(d): shutil.rmtree(d, ignore_errors=True) gc.collect() def testStartAcquisition(self): """Test that rsync is launched when an acquisition is discovered""" manipulationId = "test10" observeDir = os.path.join(self.inputdir, manipulationId) for folder in (self.inputdir, observeDir): if not os.path.exists(folder): os.makedirs(folder) self.assertTrue(os.path.isdir(observeDir)) self.s = Simulation( self.inputdir, manipulationId, finalState=Simulation.advancement["acquisitionRunning"], ) self.s.setSrcDestPatterns(self.inputdir, self.outputdir) self.s.createFinalXML(True) self.dataWatcherWidget.setFolderObserved(self.inputdir) self.dataWatcherWidget.show() self.dataWatcherWidget.sigTMStatusChanged.connect(self.stateHasChanged) self.assertTrue(self.dataWatcherWidget.currentStatus == "not processing") self.dataWatcherWidget.setObservation(True) self.s.start() # check state scanning time.sleep(0.5) self.dataWatcherWidget.stopObservation() # in this case the .info should be in the output dir also test10_output = os.path.join(self.outputdir, "test10") test10_input = os.path.join(self.inputdir, "test10") self.assertTrue(os.path.isfile(os.path.join(test10_output, "test10.info"))) # make sure file transfert have been started (using rsync) # all file in outputdir should be in input dir time.sleep(2) # check that some .edf file have already been copied self.assertTrue(len(test10_output) > 5) # xml shouldn't be there because we are righting it at the end self.assertFalse(os.path.isfile(os.path.join(test10_output, "test10.xml"))) self.assertFalse(os.path.isfile(os.path.join(test10_input, "test10.xml"))) class TestDataWatcherBlissScan(TestCaseQt): def setUp(self): self._widget = DataWatcherOW(self) self.tempdir = tempfile.mkdtemp() MockBlissAcquisition( n_sample=1, n_sequence=1, n_scan_per_sequence=3, n_darks=2, n_flats=2, output_dir=os.path.join(self.tempdir, "folder_1"), ) MockBlissAcquisition( n_sample=2, n_sequence=1, n_scan_per_sequence=3, n_darks=2, n_flats=2, output_dir=os.path.join(self.tempdir, "test", "with", "some", "depth"), ) self._listener = SignalListener() self._widget._widget.sigScanReady.connect(self._listener) def tearDown(self): self._widget._widget.sigScanReady.disconnect(self._listener) self._widget.stopObservation() self._listener = None shutil.rmtree(self.tempdir) self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None gc.collect() class TestDataWatcherNXtomo(TestCaseQt): def setUp(self): self._widget = DataWatcherOW(self) self.tempdir = tempfile.mkdtemp() MockNXtomo( scan_path=os.path.join(self.tempdir, "folder_1"), n_proj=10, ) MockNXtomo( scan_path=os.path.join(self.tempdir, "test", "with", "some", "depth"), n_proj=10, ) self._listener = SignalListener() self._widget._widget.sigScanReady.connect(self._listener) def tearDown(self): self._widget._widget.sigScanReady.disconnect(self._listener) self._widget.stopObservation() self._listener = None shutil.rmtree(self.tempdir) self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None gc.collect() def test(self): self._widget.setFolderObserved(self.tempdir) self._widget._widget.getConfigWindow().setMode((datawatcherstatus.NXtomo_END,)) self._widget.show() self._widget.startObservation() processing_time = 2 sleep_time = 0.005 while processing_time > 0: self.qapp.processEvents() sleep(sleep_time) processing_time -= sleep_time assert self._listener.callCount() == 2 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_emailow.py0000644000175000017500000000130615153325210031173 0ustar00paynopaynoimport gc import pickle from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.control.EmailOW import EmailOW from orangecanvas.scheme.readwrite import literal_dumps class TestEmailOW(TestCaseQt): def setUp(self): super().setUp() self.widget = EmailOW() def tearDown(self): self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None gc.collect() def test(self): self.widget.show() def test_serializing(self): pickle.dumps(self.widget.getConfiguration()) def test_literal_dumps(self): literal_dumps(self.widget.getConfiguration()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_notifier.py0000644000175000017500000000103215153325210031351 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.control.NotifierOW import NotifierWidgetOW class TestTimerOW(TestCaseQt): def setUp(self): super().setUp() self.widget = NotifierWidgetOW() def tearDown(self): self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None gc.collect() def test(self): self.widget.show() ././@PaxHeader0000000000000000000000000000020700000000000010214 xustar00113 path=tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_nxtomo_concatenate_ow.py 22 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_nxtomo_concatenate_ow0000644000175000017500000000322515153325210033506 0ustar00paynopaynoimport os from tomoscan.series import Series import pickle from ewoksorange.bindings.qtapp import QtEvent from orangecanvas.scheme.readwrite import literal_dumps from tomwer.tests.conftest import qtapp # noqa F401 from tomwer.core.utils.scanutils import MockNXtomo from orangecontrib.tomwer.widgets.control.NXtomoConcatenate import NXtomoConcatenateOW def test_NabuHelicalPrepareWeightsDoubleOW( qtapp, # noqa F811 tmp_path, ): """simple test of the _DeltaBetaSelectorDialog""" widget = NXtomoConcatenateOW() widget._loadSettings() # test settings serialization pickle.dumps(widget._ewoks_default_inputs) literal_dumps(widget._ewoks_default_inputs) scan_1 = MockNXtomo( scan_path=os.path.join(tmp_path, "scan1"), n_proj=10, n_ini_proj=10, scan_range=180, dim=20, energy=12.3, ).scan scan_2 = MockNXtomo( scan_path=os.path.join(tmp_path, "scan2"), n_proj=10, n_ini_proj=10, scan_range=180, dim=20, energy=12.3, ).scan output_scan_file = os.path.join(tmp_path, "concatenation.nx") assert not os.path.exists(output_scan_file) widget.widget.setConfiguration( { "output_file": output_scan_file, } ) # process task finished = QtEvent() def finished_callback(): finished.set() executor = widget.task_executor_queue executor.sigComputationEnded.connect(finished_callback) widget._process_series(series=Series(iterable=[scan_1, scan_2])) # wait until processing is finished assert finished.wait(timeout=10) assert os.path.exists(output_scan_file) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_nxtomomill.py0000644000175000017500000000775315153325210031754 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc import os import shutil import tempfile import time from orangecanvas.scheme.readwrite import literal_dumps from processview.core.manager.manager import DatasetState, ProcessManager from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from tomoscan.esrf.scan.mock import MockEDF from orangecontrib.tomwer.widgets.control.EDF2NXTomomillOW import EDF2NXOW from orangecontrib.tomwer.widgets.control.NXTomomillOW import NXTomomillOW from tomwer.core.scan.blissscan import BlissScan from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.utils.scanutils import MockBlissAcquisition class TestNXTomomillOw(TestCaseQt): """ Test the NXTomomillOW widget """ def setUp(self): super().setUp() self.tempdir = tempfile.mkdtemp() mock = MockBlissAcquisition( n_sample=1, n_sequence=1, n_scan_per_sequence=3, n_darks=2, n_flats=2, output_dir=self.tempdir, ) self.scan = BlissScan( master_file=mock.samples[0].sample_file, proposal_file=mock.proposal_file, entry="1.1", ) self.widget = NXTomomillOW() def tearDown(self): self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None shutil.rmtree(self.tempdir) gc.collect() def test(self): self.widget.add(self.scan.master_file) self.widget._sendAll() def test_literal_dumps(self): self.widget._saveNXTomoCfgFile(cfg_file="") literal_dumps(self.widget._ewoks_default_inputs) class TestEDF2NXOW(TestCaseQt): """ Test the EDF2NXOW widget """ def setUp(self): super().setUp() self.tempdir = tempfile.mkdtemp() self._edf_folder_1 = os.path.join(self.tempdir, "edf_scan_1") self._edf_folder_2 = os.path.join(self.tempdir, "edf_scan_2_") MockEDF( scan_path=self._edf_folder_1, n_radio=10, n_ini_radio=10, n_extra_radio=0, dim=128, dark_n=1, flat_n=1, ) MockEDF( scan_path=self._edf_folder_2, n_radio=10, n_ini_radio=10, n_extra_radio=0, dim=128, dark_n=1, flat_n=1, ) self.widget = EDF2NXOW() self._process_manager = ProcessManager() def tearDown(self): self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None shutil.rmtree(self.tempdir) gc.collect() def test(self): self.widget.add(self._edf_folder_1) self.widget.add(self._edf_folder_2) self.widget._sendAll() self.qapp.processEvents() timeout = 10 processing_queue = self.widget.task_executor_queue while not processing_queue.is_available and not processing_queue.empty(): self.qapp.processEvents() time.sleep(0.1) timeout -= 0.1 if timeout <= 0: raise TimeoutError # need to call one more time the processEvents tpo call callbacks and status notification for i in range(3): self.qapp.processEvents() time.sleep(0.1) # check the two output files exists and status of the processing is done... for folder in (self._edf_folder_1, self._edf_folder_2): scan = NXtomoScan(scan=folder + ".nx", entry="entry") self.assertTrue(os.path.exists(scan.master_file)) self.assertEqual( self._process_manager.get_dataset_state( dataset_id=scan.get_identifier(), process=self.widget, ), DatasetState.SUCCEED, ) def test_literal_dumps(self): self.widget._saveNXTomoCfgFile(cfg_file="") literal_dumps(self.widget._ewoks_default_inputs) ././@PaxHeader0000000000000000000000000000021300000000000010211 xustar00117 path=tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_reduce_dark_flat_selector.py 22 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_reduce_dark_flat_sele0000644000175000017500000000207615153325210033402 0ustar00paynopaynoimport gc import pickle import numpy from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.control.ReduceDarkFlatSelectorOW import ( ReduceDarkFlatSelectorOW, ) from orangecanvas.scheme.readwrite import literal_dumps class TestEmailOW(TestCaseQt): def setUp(self): super().setUp() self.widget = ReduceDarkFlatSelectorOW() self.widget._dialog.addReduceFrames( { "reduce_frames_name": "new dict", -1: numpy.random.random(100 * 100).reshape(100, 100), 2: numpy.random.random(100 * 100).reshape(100, 100), }, selected=(-1, 2), ) def tearDown(self): self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None gc.collect() def test(self): self.widget.show() def test_serializing(self): pickle.dumps(self.widget.getConfiguration()) def test_literal_dumps(self): literal_dumps(self.widget.getConfiguration()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_singletomoobj.py0000644000175000017500000000224715153325210032416 0ustar00paynopaynoimport gc import os import pickle import shutil import tempfile import numpy from orangecanvas.scheme.readwrite import literal_dumps from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.control.SingleTomoObjOW import SingleTomoObjOW from tomwer.core.volume.hdf5volume import HDF5Volume class TestSingleTomoObjOW(TestCaseQt): def setUp(self): super().setUp() self.window = SingleTomoObjOW() self.folder = tempfile.mkdtemp() self.volume_1 = HDF5Volume( file_path=os.path.join(self.folder, "vol_file.hdf5"), data_path="entry0000", data=numpy.linspace(0, 10, 100 * 100 * 3).reshape(3, 100, 100), ) self.volume_1.save() def tearDown(self): self.window.setAttribute(qt.Qt.WA_DeleteOnClose) self.window.close() self.window = None shutil.rmtree(self.folder) gc.collect() def test(self): self.window.show() self.window.widget.setTomoObject(self.volume_1) # test serialization pickle.dumps(self.window._tomo_obj_setting) literal_dumps(self.window._tomo_obj_setting) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_timerow.py0000644000175000017500000000100615153325210031221 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.control.TimerOW import TimerOW class TestTimerOW(TestCaseQt): def setUp(self): super().setUp() self.widget = TimerOW() def tearDown(self): self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None gc.collect() def test(self): self.widget.show() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_tomoobj_series.py0000644000175000017500000000701714757047403032604 0ustar00paynopaynoimport gc import os import shutil import tempfile import numpy from silx.gui import qt from silx.gui.utils.testutils import SignalListener, TestCaseQt from orangecontrib.tomwer.widgets.control.TomoObjSeriesOW import TomoObjSeriesOW from tomwer.core.utils.scanutils import HDF5MockContext from tomwer.core.volume.hdf5volume import HDF5Volume class TestTomoObjSeriesOW(TestCaseQt): """ Test the TomoObjSeriesOW orange widget """ def setUp(self): super().setUp() self.window = TomoObjSeriesOW() self.folder = tempfile.mkdtemp() # connect to the series created signal self._listener = SignalListener() self.window._widget.sigSeriesSelected.connect(self._listener) def tearDown(self): self.window.setAttribute(qt.Qt.WA_DeleteOnClose) self.window.close() self.window = None self._listener = None shutil.rmtree(self.folder) gc.collect() def test_with_volumes(self): """test the TomoObjSeriesOW with volumes""" volume_1 = HDF5Volume( file_path=os.path.join(self.folder, "vol_file.hdf5"), data_path="entry0000", data=numpy.linspace(0, 10, 100 * 100 * 3).reshape(3, 100, 100), ) volume_1.save() volume_2 = HDF5Volume( file_path=os.path.join(self.folder, "vol_file2.hdf5"), data_path="entry0001", data=numpy.linspace(60, 120, 100 * 100 * 5).reshape(5, 100, 100), ) volume_2.save() assert self._listener.callCount() == 0 assert len(self.window._widget._widget.getSelectedSeries()) == 0 # add the volume to the possible objects to be added self.window.addTomoObj(volume_1) self.window.addTomoObj(volume_2) assert len(self.window._widget._widget.getSelectedSeries()) == 0 # add volume to the series defined newSerieWidget = ( self.window._widget._widget._seriesDefinitionWidget._manualDefWidget._newSeriesWidget ) newSerieWidget.addTomoObjToCurrentSeries(volume_1) assert len(self.window._widget._widget.getSelectedSeries()) == 1 newSerieWidget.addTomoObjToCurrentSeries( volume_1 ) # try adding twice the same object assert len(self.window._widget._widget.getSelectedSeries()) == 1 newSerieWidget.addTomoObjToCurrentSeries(volume_2) assert len(self.window._widget._widget.getSelectedSeries()) == 2 assert self._listener.callCount() == 0 self.window._widget._selectButton.released.emit() self.qapp.processEvents() assert self._listener.callCount() == 1 def test_with_scans(self): """test the TomoObjSeriesOW with scans""" with HDF5MockContext( scan_path=os.path.join(self.folder, "test", "scan"), n_proj=100 ) as scan: assert self._listener.callCount() == 0 # add the scan to possible objects to be added self.window.addTomoObj(scan) assert len(self.window._widget._widget.getSelectedSeries()) == 0 # add scan to the series defined newSerieWidget = ( self.window._widget._widget._seriesDefinitionWidget._manualDefWidget._newSeriesWidget ) newSerieWidget.addTomoObjToCurrentSeries(scan) assert len(self.window._widget._widget.getSelectedSeries()) == 1 self.window._widget._selectButton.released.emit() self.qapp.processEvents() assert self._listener.callCount() == 1 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_volume_selector.py0000644000175000017500000000455615153325210032757 0ustar00paynopaynoimport gc import os import pickle import shutil import tempfile import numpy from orangecanvas.scheme.readwrite import literal_dumps from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.control.VolumeSelector import VolumeSelectorOW from tomwer.core.volume.hdf5volume import HDF5Volume class TestVolumeSelectorOW(TestCaseQt): def setUp(self): super().setUp() self.window = VolumeSelectorOW() self.folder = tempfile.mkdtemp() self.volume_1 = HDF5Volume( file_path=os.path.join(self.folder, "vol_file.hdf5"), data_path="entry0000", data=numpy.linspace(0, 10, 100 * 100 * 3).reshape(3, 100, 100), ) self.volume_1.save() self.volume_2 = HDF5Volume( file_path=os.path.join(self.folder, "vol_file2.hdf5"), data_path="entry0001", data=numpy.linspace(60, 120, 100 * 100 * 5).reshape(5, 100, 100), ) self.volume_2.save() def tearDown(self): self.window.setAttribute(qt.Qt.WA_DeleteOnClose) self.window.close() self.window = None shutil.rmtree(self.folder) gc.collect() def test(self): self.window.show() # check adding one volume self.window.addVolume(self.volume_1) assert self.window.widget.dataList.n_data() == 1 # check behavior adding the same volume self.window.addVolume(self.volume_1) assert self.window.widget.dataList.n_data() == 1 # check adding another volume self.window.addVolume(self.volume_2) assert self.window.widget.dataList.n_data() == 2 # check removing volume(s) self.window.removeVolume(self.volume_1) assert self.window.widget.dataList.n_data() == 1 self.window.removeVolume(self.volume_1) assert self.window.widget.dataList.n_data() == 1 self.window.removeVolume(self.volume_2) assert self.window.widget.dataList.n_data() == 0 # and adding them back self.window.addVolume(self.volume_1) self.window.addVolume(self.volume_2) assert self.window.widget.dataList.n_data() == 2 # test serialization self.window._updateSettings() assert len(self.window._scanIDs) == 2 pickle.dumps(self.window._scanIDs) literal_dumps(self.window._scanIDs) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8771002 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/debugtools/0000755000175000017500000000000015153325403025456 5ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9851027 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/debugtools/tests/0000755000175000017500000000000015153325403026620 5ustar00paynopayno././@PaxHeader0000000000000000000000000000020600000000000010213 xustar00112 path=tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/debugtools/tests/test_dataset_generator.py 22 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/debugtools/tests/test_dataset_generator.0000644000175000017500000000401614757047403033366 0ustar00paynopayno# coding: utf-8 # /*########################################################################## # # Copyright (c) 2017-2021 European Synchrotron Radiation Facility # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # # ###########################################################################*/ __authors__ = ["H. Payno"] __license__ = "MIT" __date__ = "21/06/2021" import gc import shutil import tempfile from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.debugtools.DatasetGeneratorOW import ( DatasetGeneratorOW, ) class TestDatasetGeneratorOW(TestCaseQt): def setUp(self): self.tmp_dir = tempfile.mkdtemp() self.widget = DatasetGeneratorOW() self.widget.generatorGUI.mainWidget.setRootDir(self.tmp_dir) def tearDown(self): shutil.rmtree(self.tmp_dir) self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None gc.collect() def test(self): self.widget._generate().join() ././@PaxHeader0000000000000000000000000000020500000000000010212 xustar00111 path=tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/debugtools/tests/test_object_inspector.py 22 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/debugtools/tests/test_object_inspector.p0000644000175000017500000000155214757047403033411 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc import os import shutil import tempfile from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.debugtools.ObjectInspectorOW import ObjectInspectorOW from tomwer.core.utils.scanutils import MockNXtomo class TestObjectInspectorOW(TestCaseQt): def setUp(self): super().setUp() self.tmp_dir = tempfile.mkdtemp() self.scan = MockNXtomo( scan_path=os.path.join(self.tmp_dir, "myscan"), n_proj=20, n_ini_proj=20, dim=10, ).scan def tearDown(self): shutil.rmtree(self.tmp_dir) gc.collect() def test(self): widget = ObjectInspectorOW() widget.setObject(self.scan) widget.setAttribute(qt.Qt.WA_DeleteOnClose) widget.close() ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8811002 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/edit/0000755000175000017500000000000015153325403024234 5ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9851027 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/edit/tests/0000755000175000017500000000000015153325403025376 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/edit/tests/test_dark_flat_patch.py0000644000175000017500000000274515153325210032121 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc import os import pickle import tempfile import h5py import numpy import pytest from orangecanvas.scheme.readwrite import literal_dumps from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from silx.io.url import DataUrl from orangecontrib.tomwer.widgets.edit.DarkFlatPatchOW import DarkFlatPatchOW from tomwer.tests.utils import skip_gui_test @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestDarkFlatPatch(TestCaseQt): """Test that the axis widget work correctly""" def setUp(self): super().setUp() self._window = DarkFlatPatchOW() def tearDown(self): self._window.setAttribute(qt.Qt.WA_DeleteOnClose) self._window.close() self._window = None gc.collect() def test(self): self._window.show() self.qWaitForWindowExposed(self._window) def test_serialiazation(self): with tempfile.TemporaryDirectory() as tmp_path: file_path = os.path.join(tmp_path, "darks.hdf5") with h5py.File(file_path, mode="w") as h5f: h5f.require_group("darks")["0"] = numpy.ones((10, 10)) dark_url = DataUrl(file_path=file_path, data_path="darks/0") self._window.widget.setStartDarkUrl(url=dark_url) config = self._window.getConfiguration() pickle.dumps(config) literal_dumps(config) self._window.setConfiguration(config) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/edit/tests/test_image_key_editor.py0000644000175000017500000000144614757047403032326 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc import pytest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.edit.ImageKeyEditorOW import ImageKeyEditorOW from tomwer.tests.utils import skip_gui_test @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestImageKeyEditor(TestCaseQt): """Test that the ImageKeyEditorOW widget work correctly (at least launched)""" def setUp(self): super().setUp() self._window = ImageKeyEditorOW() def tearDown(self): self._window.setAttribute(qt.Qt.WA_DeleteOnClose) self._window.close() self._window = None gc.collect() def test(self): self._window.show() self.qWaitForWindowExposed(self._window) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/edit/tests/test_image_key_upgrader.py0000644000175000017500000000424314757047403032647 0ustar00paynopayno# coding: utf-8 # /*########################################################################## # # Copyright (c) 2017-2019 European Synchrotron Radiation Facility # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # # ###########################################################################*/ __authors__ = ["H. Payno"] __license__ = "MIT" __date__ = "10/12/2021" import gc import pytest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.edit.ImageKeyUpgraderOW import ImageKeyUpgraderOW from tomwer.tests.utils import skip_gui_test @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestImageKeyEditor(TestCaseQt): """Test that the ImageKeyUpgraderOW widget work correctly. Processing test are done in the core module. gui test are done in the tomwer.gui.edit module""" def setUp(self): super().setUp() self._window = ImageKeyUpgraderOW() def tearDown(self): self._window.setAttribute(qt.Qt.WA_DeleteOnClose) self._window.close() self._window = None gc.collect() def test(self): self._window.show() self.qWaitForWindowExposed(self._window) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/edit/tests/test_nxtomo_editor.py0000644000175000017500000001374415153325210031706 0ustar00paynopaynoimport os import pickle import numpy import pytest import pint from nxtomomill.nexus.nxtomo import NXtomo from orangecanvas.scheme.readwrite import literal_dumps from silx.gui.utils.testutils import SignalListener from nxtomo.nxobject.nxdetector import ImageKey from orangecontrib.tomwer.widgets.edit.NXtomoEditorOW import NXtomoEditorOW from tomwer.core.process.edit.nxtomoeditor import NXtomoEditorKeys from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.tests.utils import skip_gui_test from tomwer.gui.utils.qt_utils import QSignalSpy from tomwer.tests.conftest import qtapp # noqa F401 from tomwer.tests.test_utils import is_lr_flip, is_ud_flip _ureg = pint.get_application_registry() def getDefaultConfig() -> dict: """return the configuration of the NXtomo editor. First value is the value of the field, second is: is the associated lock button locked or not""" return { NXtomoEditorKeys.ENERGY: (5.9, False), NXtomoEditorKeys.SAMPLE_SOURCE_DISTANCE: (-55.2, False), NXtomoEditorKeys.PROPAGATION_DISTANCE: (10.1, True), NXtomoEditorKeys.SAMPLE_DETECTOR_DISTANCE: (2.4, True), NXtomoEditorKeys.FIELD_OF_VIEW: ("Full", False), NXtomoEditorKeys.DETECTOR_X_PIXEL_SIZE: (0.023, True), NXtomoEditorKeys.DETECTOR_Y_PIXEL_SIZE: (0.025, True), NXtomoEditorKeys.SAMPLE_X_PIXEL_SIZE: (0.24, True), NXtomoEditorKeys.SAMPLE_Y_PIXEL_SIZE: (0.26, True), NXtomoEditorKeys.LR_FLIPPED: (True, True), NXtomoEditorKeys.UD_FLIPPED: (False, False), NXtomoEditorKeys.X_TRANSLATION: (0.0,), NXtomoEditorKeys.Z_TRANSLATION: (0.0,), } @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") def test_NXtomoEditorOW( qtapp, # noqa F811 tmp_path, ): window = NXtomoEditorOW() # test serialization window.setConfiguration(getDefaultConfig()) assert window.getConfiguration() == getDefaultConfig() pickle.dumps(window.getConfiguration()) # test literal dumps literal_dumps(window.getConfiguration()) # test widget automation signal_listener = SignalListener() window.sigScanReady.connect(signal_listener) # set up the widget to define and lock distance, energy and x pixel size distance_widget = window.widget.mainWidget._sampleDetectorDistanceMetricEntry distance_widget.setValue(value_m=0.6) distance_widget.setUnit(_ureg.millimeter) distance_locker = window.widget.mainWidget._sampleDetectorDistanceLB distance_locker.setLock(True) energy_widget = window.widget.mainWidget._energyEntry energy_widget.setValue(88.058) energy_locker = window.widget.mainWidget._energyLockerLB energy_locker.setLock(True) x_pixel_widget = window.widget.mainWidget._xDetectorPixelSizeMetricEntry x_pixel_widget.setValue(value_m=45) x_pixel_widget.setUnit(_ureg.nanometer) x_pixel_locker = window.widget.mainWidget._xDetectorPixelSizeLB x_pixel_locker.setLock(True) # 1.0 create nx tomos with raw data nx_tomo = NXtomo() nx_tomo.instrument.detector.x_pixel_size = ( 0.023 * _ureg.meter # should be overwrite by the configuration / lock buttons ) nx_tomo.instrument.detector.y_pixel_size = ( 0.025 * _ureg.meter # should be overwrite by the configuration / lock buttons ) nx_tomo.instrument.detector.field_of_view = "full" nx_tomo.instrument.detector.distance = ( 2.4 * _ureg.meter # should be overwrite by the configuration / lock buttons ) nx_tomo.instrument.detector.set_transformation_from_x_flipped( False # should be overwrite by the configuration / lock buttons ) nx_tomo.instrument.detector.set_transformation_from_y_flipped(True) nx_tomo.energy = 5.9 * _ureg.keV nx_tomo.instrument.detector.image_key_control = [ImageKey.PROJECTION.value] * 12 nx_tomo.instrument.detector.data = numpy.empty(shape=(12, 10, 10)) nx_tomo.sample.rotation_angle = numpy.linspace(0, 20, num=12) * _ureg.degree file_path = os.path.join(tmp_path, "nxtomo.nx") entry = "entry0000" nx_tomo.save( file_path=file_path, data_path=entry, ) # 2.0 set scan to the nxtomo-editor scan = NXtomoScan(file_path, entry) waiter = QSignalSpy(window.sigScanReady) window.setScan(scan=scan) # warning: avoid executing the ewoks task as this will be done # automatically (has some field lock). This would create concurrency task # and could bring some HDF5 concurrency error waiter.wait(5000) # 3.0 check results are as expected # make sure the scan has been re-emitted assert signal_listener.callCount() == 1 # make sure the edition of the parameters have been done and only those overwrite_nx_tomo = NXtomo().load( file_path=file_path, data_path=entry, detector_data_as="as_numpy_array", ) numpy.testing.assert_almost_equal( overwrite_nx_tomo.instrument.detector.x_pixel_size.to_base_units().magnitude, (45e-9 * _ureg.meter).to_base_units().magnitude, ) assert ( overwrite_nx_tomo.instrument.detector.y_pixel_size == nx_tomo.instrument.detector.y_pixel_size ) assert ( overwrite_nx_tomo.instrument.detector.field_of_view == nx_tomo.instrument.detector.field_of_view ) numpy.testing.assert_almost_equal( overwrite_nx_tomo.instrument.detector.distance.to_base_units().magnitude, (6.0e-4 * _ureg.meter).to_base_units().magnitude, ) assert ( is_lr_flip( overwrite_nx_tomo.instrument.detector.transformations.transformations ) is True ) assert ( is_ud_flip( overwrite_nx_tomo.instrument.detector.transformations.transformations ) is True ) numpy.testing.assert_almost_equal( overwrite_nx_tomo.energy.to_base_units().magnitude, (88.058 * _ureg.keV).to_base_units().magnitude, ) numpy.testing.assert_array_almost_equal( overwrite_nx_tomo.instrument.detector.data, nx_tomo.instrument.detector.data, ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8811002 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/other/0000755000175000017500000000000015153325403024430 5ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9851027 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/other/tests/0000755000175000017500000000000015153325403025572 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/other/tests/test_pythonscript.py0000644000175000017500000000165515153325210031754 0ustar00paynopaynoimport gc import logging from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.other.PythonScriptOW import OWPythonScript from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.volume.hdf5volume import HDF5Volume logging.disable(logging.INFO) class TestEDFDarkRefWidget(TestCaseQt): def setUp(self): TestCaseQt.setUp(self) self.widget = OWPythonScript() self._scan = NXtomoScan("my_file.hdf5", entry="entry0000") self._volume = HDF5Volume(file_path="my_volume.hdf5", data_path="volume") def tearDown(self): self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None gc.collect() def test_handle_data(self): self.widget.handle_input(self._scan, (1,), "data") def test_handle_volume(self): self.widget.handle_input(self._volume, (1,), "volume") ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8811002 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/0000755000175000017500000000000015153325403026370 5ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9851027 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/0000755000175000017500000000000015153325403027532 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_axis.py0000644000175000017500000001554715153325210032117 0ustar00paynopaynoimport gc import pickle import shutil import tempfile import time import os import pytest from orangecanvas.scheme.readwrite import literal_dumps from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.reconstruction.AxisOW import AxisOW from tomwer.core.utils.lbsram import mock_low_memory from tomwer.core.process.reconstruction.axis.mode import AxisMode from tomwer.core.settings import mock_lsbram from tomwer.core.utils.scanutils import MockNXtomo, MockEDF from tomwer.tests.utils import skip_gui_test @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestOWAxis(TestCaseQt): """Test that the axis widget work correctly""" def setUp(self): self._window = AxisOW() self.recons_params = self._window.recons_params self.tempdir = tempfile.mkdtemp() self.scan = MockNXtomo( scan_path=os.path.join(self.tempdir, "nx_tomo.nx"), n_proj=10, n_ini_proj=10, scan_range=180, dim=20, energy=12.3, ).scan self._window.getAxisParams().mode = AxisMode.centered self._window.show() self.qWaitForWindowExposed(self._window) def tearDown(self): shutil.rmtree(self.tempdir) self._window.setAttribute(qt.Qt.WA_DeleteOnClose) self._window.close() gc.collect() def testAxisLock(self): """Test behavior when locking the axis position. Could not be included in the tomwer/gui because the lock action is only available for the OW """ assert self._window.getAxisParams().mode in ( AxisMode.centered, AxisMode.global_, ) radio_axis = self._window._widget._axisWidget main_widget = self._window._widget self.assertFalse(main_widget._controlWidget._lockBut.isLocked()) self.assertTrue(radio_axis._settingsWidget._mainWidget.isEnabled()) self.mouseClick(main_widget._controlWidget._lockBut, qt.Qt.LeftButton) self.qapp.processEvents() self.assertTrue(main_widget._controlWidget._lockBut.isLocked()) # when the lock button is activated we should automatically switch to # the manual mode self.assertTrue(self._window.getAxisParams().mode is AxisMode.manual) self.assertFalse(radio_axis._settingsWidget._mainWidget.isEnabled()) def test_serializing(self): pickle.dumps(self._window.recons_params.to_dict()) def test_literal_dumps(self): literal_dumps(self._window.recons_params.to_dict()) class TestWindowAxisComputation(TestCaseQt): @staticmethod def _long_computation(scan): time.sleep(5) return -1 """Test that the axis widget work correctly""" def setUp(self): TestCaseQt.setUp(self) self.tempdir = tempfile.mkdtemp() self._mainWindow = AxisOW() self.recons_params = self._mainWindow.recons_params self._window = self._mainWindow._widget self.scan = MockNXtomo( scan_path=os.path.join(self.tempdir, "nx_tomo.nx"), n_proj=10, n_ini_proj=10, scan_range=180, dim=20, energy=12.3, ).scan self._mainWindow.show() self.qWaitForWindowExposed(self._mainWindow) self._mainWindow.setMode("manual") def tearDown(self): shutil.rmtree(self.tempdir) self._mainWindow.setAttribute(qt.Qt.WA_DeleteOnClose) self._mainWindow.close() self._mainWindow = None self._window = None gc.collect() def testComputationSucceed(self): """Test gui if the axis position is correctly computed""" self.recons_params.mode = AxisMode.manual radio_axis = self._window._axisWidget self.assertEqual(radio_axis.getMode(), AxisMode.manual) radio_axis.setXShift(2.345) self._mainWindow.process(self.scan) self.qapp.processEvents() self.assertEqual(radio_axis.getMode(), AxisMode.manual) self.assertEqual(self.recons_params.relative_cor_value, 2.345) position_info_widget = self._window._controlWidget._positionInfo self.assertEqual(position_info_widget._relativePositionQLE.text(), "2.345") global _computation_res _computation_res = 0 @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestAxisStack(TestCaseQt): """Test axis computation of a stack of scan""" @staticmethod def _test_computation(scan): global _computation_res _computation_res += 1 return _computation_res def setUp(self): # not working due to OW TestCaseQt.setUp(self) self._scan1 = MockEDF.mockScan(scanID=tempfile.mkdtemp()) self._scan2 = MockEDF.mockScan(scanID=tempfile.mkdtemp()) self._scan3 = MockEDF.mockScan(scanID=tempfile.mkdtemp()) self._mainWindow = AxisOW() self.recons_params = self._mainWindow._axis_params self._mainWindow._skip_exec(True) global _computation_res _computation_res = 0 self._mainWindow.patch_calc_method( AxisMode.centered, TestAxisStack._test_computation ) self.recons_params.mode = AxisMode.centered self._mainWindow.show() self.qWaitForWindowExposed(self._mainWindow) def tearDown(self): mock_low_memory(False) mock_lsbram(False) self._mainWindow.setAttribute(qt.Qt.WA_DeleteOnClose) self._mainWindow.close() self._mainWindow = None self._recons_params = None self.qapp.processEvents() for scan in (self._scan1, self._scan2, self._scan3): shutil.rmtree(scan.path) gc.collect() def testLowMemory(self): """Make sure the axis computation will be skip if we are in low memory""" mock_low_memory(True) mock_lsbram(True) for scan in (self._scan1, self._scan2, self._scan3): self.qapp.processEvents() self._mainWindow.new_data_in(scan) self.assertEqual(self._scan1.axis_params, None) self.assertEqual(self._scan2.axis_params, None) self.assertEqual(self._scan3.axis_params, None) def testLockStack(self): """Check that axis position will be simply copy if we are in a lock stack""" self.recons_params.mode = AxisMode.manual position_value = 0.36 self.recons_params.set_relative_value(position_value) for scan in (self._scan1, self._scan2, self._scan3): self._mainWindow.process(scan) for i in range(5): self.qapp.processEvents() time.sleep(0.2) self.qapp.processEvents() self.assertEqual(self._scan1.axis_params.relative_cor_value, position_value) self.assertEqual(self._scan2.axis_params.relative_cor_value, position_value) self.assertEqual(self._scan3.axis_params.relative_cor_value, position_value) ././@PaxHeader0000000000000000000000000000020600000000000010213 xustar00112 path=tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_cast_volumeow.py 22 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_cast_volumeow.0000644000175000017500000000311415153325210033454 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc import os import pickle import tempfile import time import numpy from orangecanvas.scheme.readwrite import literal_dumps from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.reconstruction.CastNabuVolumeOW import ( CastNabuVolumeOW, ) from tomwer.core.volume.rawvolume import RawVolume class TestCastVolumeOW(TestCaseQt): def setUp(self): super().setUp() self._window = CastNabuVolumeOW() def tearDown(self): self._window.setAttribute(qt.Qt.WA_DeleteOnClose) self._window.close() self._window = None gc.collect() def test(self): self._window.show() self.qWaitForWindowExposed(self._window) def test_serializing(self): pickle.dumps(self._window.getConfiguration()) def test_literal_dumps(self): literal_dumps(self._window.getConfiguration()) def test_cast_volume(self): with tempfile.TemporaryDirectory() as tmp_dir: input_dir = os.path.join(tmp_dir, "input") os.makedirs(input_dir) volume = RawVolume( file_path=os.path.join(input_dir, "vol_file.vol"), data=numpy.linspace(0, 10, 100 * 100 * 3, dtype=numpy.float32).reshape( 3, 100, 100 ), ) volume.save() self._window.process_volume(volume) while self._window._processingStack.is_computing(): time.sleep(0.1) self.qapp.processEvents() ././@PaxHeader0000000000000000000000000000021100000000000010207 xustar00115 path=tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_dark_refs_widget.py 22 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_dark_refs_widg0000644000175000017500000001147515153325210033472 0ustar00paynopaynoimport gc import logging import os import pickle import tempfile import numpy from orangecanvas.scheme.readwrite import literal_dumps from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.reconstruction.DarkRefAndCopyOW import ( DarkRefAndCopyOW, ) from tomwer.core.utils.scanutils import MockNXtomo logging.disable(logging.INFO) class TestDarkRefWidget(TestCaseQt): """class testing the DarkRefWidget""" def setUp(self): self._tmp_path = tempfile.mkdtemp() scan_folder_with_raw = os.path.join(self._tmp_path, "test_dir_1") scan_folder_without_raw = os.path.join(self._tmp_path, "test_dir_2") for my_dir in (scan_folder_with_raw, scan_folder_without_raw): os.makedirs(my_dir) self._scan_with_raw = MockNXtomo( scan_path=scan_folder_with_raw, create_ini_dark=True, create_ini_flat=True, create_final_flat=False, n_proj=10, n_ini_proj=10, dim=12, ).scan self._scan_without_raw = MockNXtomo( scan_path=scan_folder_without_raw, create_ini_dark=False, create_ini_flat=False, create_final_flat=False, n_proj=10, n_ini_proj=10, dim=12, ).scan self.widget = DarkRefAndCopyOW() return super().setUp() def tearDown(self): # shutil.rmtree(self._tmp_path) self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() gc.collect() def test_serializing(self): self.widget._updateSettingsVals() pickle.dumps(self.widget._ewoks_default_inputs) def test_literal_dumps(self): self.widget._updateSettingsVals() literal_dumps(self.widget._ewoks_default_inputs) def test_copy(self): self.widget.setCopyActive(True) while self.qapp.hasPendingEvents(): self.qapp.processEvents() assert len(os.listdir(self.widget._processing_stack._save_dir)) == 0 self.widget.process(self._scan_with_raw) self.widget._processing_stack.wait_computation_finished() while self.qapp.hasPendingEvents(): self.qapp.processEvents() assert self._scan_with_raw.load_reduced_darks() not in (None, {}) assert self._scan_with_raw.load_reduced_flats() not in (None, {}) assert len(os.listdir(self.widget._processing_stack._save_dir)) == 1 assert len(os.listdir(self.widget._processing_stack._save_dir)) == 1 self.widget.setCopyActive(False) while self.qapp.hasPendingEvents(): self.qapp.processEvents() self.widget.process(self._scan_without_raw) self.widget._processing_stack.wait_computation_finished() while self.qapp.hasPendingEvents(): self.qapp.processEvents() assert self._scan_without_raw.load_reduced_darks() in (None, {}) assert self._scan_without_raw.load_reduced_flats() in (None, {}) self.widget.setCopyActive(True) while self.qapp.hasPendingEvents(): self.qapp.processEvents() self.widget.process(self._scan_without_raw) self.widget._processing_stack.wait_computation_finished() while self.qapp.hasPendingEvents(): self.qapp.processEvents() assert self._scan_without_raw.load_reduced_darks() not in (None, {}) assert self._scan_without_raw.load_reduced_flats() not in (None, {}) def test_set_darks_and_flats(self): """ Test settings darks and flats. """ self.widget.setCopyActive(True) assert len(os.listdir(self.widget._processing_stack._save_dir)) == 0 self.widget.setReducedFlats( { "0.0r": numpy.linspace(12, 12 + 12 * 12, 12 * 12).reshape(12, 12), "1.0r": numpy.linspace(24, 24 + 12 * 12, 12 * 12).reshape(12, 12), } ) self.widget.setReducedDarks( { "0.0r": numpy.linspace(0, 12 * 12, 12 * 12).reshape(12, 12), } ) self.widget.process(self._scan_without_raw) self.widget._processing_stack.wait_computation_finished() while self.qapp.hasPendingEvents(): self.qapp.processEvents() loaded_reduced_darks = self._scan_without_raw.load_reduced_darks() assert tuple(loaded_reduced_darks.keys()) == (0,) numpy.testing.assert_allclose( loaded_reduced_darks[0], numpy.linspace(0, 12 * 12, 12 * 12).reshape(12, 12), ) loaded_reduced_flats = self._scan_without_raw.load_reduced_flats() assert tuple(loaded_reduced_flats.keys()) == (0, 9) numpy.testing.assert_allclose( loaded_reduced_flats[9], numpy.linspace(24, 24 + 12 * 12, 12 * 12).reshape(12, 12), ) ././@PaxHeader0000000000000000000000000000021400000000000010212 xustar00118 path=tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_delta_beta_selector.py 22 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_delta_beta_sel0000644000175000017500000000062715153325210033444 0ustar00paynopaynoimport numpy from orangecontrib.tomwer.widgets.reconstruction.NabuVolumeOW import ( _DeltaBetaSelectorDialog, ) from tomwer.tests.conftest import qtapp # noqa F401 def test_DeltaBetaSelector( qtapp, # noqa F811 ): """simple test of the _DeltaBetaSelectorDialog""" dialog = _DeltaBetaSelectorDialog(values=(12, 45)) dialog.show() assert numpy.isscalar(dialog.getSelectedValue()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_i_norm.py0000644000175000017500000001000515153325210032416 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import logging import os import pickle from orangecanvas.scheme.readwrite import literal_dumps from processview.core.manager import DatasetState, ProcessManager from silx.gui import qt from orangecontrib.tomwer.widgets.reconstruction.SinoNormOW import ( SinoNormOW as _SinoNormOW, ) from tomwer.core.utils.scanutils import MockNXtomo from tomwer.tests.conftest import qtapp # noqa F401 logger = logging.getLogger(__name__) class SinoNormOW(_SinoNormOW): def __init__(self, parent=None): self._scans_finished = [] super().__init__(parent) def processing_finished(self, scan): self._scans_finished.append(scan) def wait_processing(self, wait_time): self._window._processing_stack._computationThread.wait(wait_time) @property def scans_finished(self): return self._scans_finished def compute(self): self._window._processCurrentScan() def setROI(self, start_x, end_x, start_y, end_y): self._window.setROI(start_x=start_x, end_x=end_x, start_y=start_y, end_y=end_y) def close(self): self._scans_finished = {} super().close() FRAME_DIM = 100 def create_scan(folder_name): return MockNXtomo( scan_path=folder_name, n_ini_proj=20, n_proj=20, n_alignement_proj=2, create_final_flat=False, create_ini_dark=True, create_ini_flat=True, n_refs=1, dim=FRAME_DIM, ).scan def test_SinoNormOW( qtapp, # noqa F811 tmp_path, ): source_dir = tmp_path / "source" source_dir.mkdir() # create scans scan_1 = create_scan(os.path.join(source_dir, "scan_1")) scan_2 = create_scan(os.path.join(source_dir, "scan_2")) scan_3 = create_scan(os.path.join(source_dir, "scan_3")) process_manager = ProcessManager() widget = SinoNormOW() widget.show() # test serialization pickle.dumps(widget.getConfiguration()) # test literal dumps widget._updateSettings() literal_dumps(widget._ewoks_default_inputs) # test behavior when the widget is unlocked """Test result when used with some interaction""" widget.setLocked(False) def process_scalar_manually(): widget.setCurrentMethod("division") widget.setCurrentSource("manual ROI") qt.QApplication.processEvents() widget.setROI(start_x=0, end_x=10, start_y=0, end_y=10) qt.QApplication.processEvents() widget.compute() widget.wait_processing(5000) qt.QApplication.processEvents() widget.process(scan_1) process_scalar_manually() assert ( process_manager.get_dataset_state( dataset_id=scan_1.get_identifier(), process=widget, ) == DatasetState.WAIT_USER_VALIDATION ) widget.process(scan_2) process_scalar_manually() assert len(widget.scans_finished) == 0 assert ( process_manager.get_dataset_state( dataset_id=scan_1.get_identifier(), process=widget, ) == DatasetState.SKIPPED ) assert ( process_manager.get_dataset_state( dataset_id=scan_2.get_identifier(), process=widget, ) == DatasetState.WAIT_USER_VALIDATION ) widget.process(scan_3) process_scalar_manually() widget.validateCurrentScan() assert ( process_manager.get_dataset_state( dataset_id=scan_3.get_identifier(), process=widget, ) == DatasetState.SUCCEED ) # test behavior when the widget is locked widget.setLocked(True) for scan in (scan_1, scan_2, scan_3): widget.process(scan) widget.wait_processing(5000) qt.QApplication.processEvents() for scan in (scan_1, scan_2, scan_3): # test status is SUCCEED assert ( process_manager.get_dataset_state( dataset_id=scan.get_identifier(), process=widget, ) == DatasetState.SUCCEED ) ././@PaxHeader0000000000000000000000000000023400000000000010214 xustar00134 path=tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_nabu_helical_prepare_weights_double.py 22 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_nabu_helical_p0000644000175000017500000000115514757047403033455 0ustar00paynopayno# import pickle # from orangecanvas.scheme.readwrite import literal_dumps # from tomwer.tests.conftest import qtapp # noqa F401 # from orangecontrib.tomwer.widgets.reconstruction.NabuHelicalPrepareWeightsDoubleOW import ( # NabuHelicalPrepareWeightsDoubleOW, # ) # def test_NabuHelicalPrepareWeightsDoubleOW( # qtapp, # noqa F811 # ): # """simple test of the _DeltaBetaSelectorDialog""" # widget = NabuHelicalPrepareWeightsDoubleOW() # widget._loadSettings() # # test settings serialization # pickle.dumps(widget._ewoks_default_inputs) # literal_dumps(widget._ewoks_default_inputs) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_nabu_volume.py0000644000175000017500000000437215153325210033461 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc import os import pickle import shutil import tempfile from time import sleep from nabu.pipeline.config import get_default_nabu_config from nabu.pipeline.fullfield.nabu_config import ( nabu_config as nabu_fullfield_default_config, ) from orangecanvas.scheme.readwrite import literal_dumps from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.reconstruction.NabuVolumeOW import NabuVolumeOW from tomwer.core.utils.scanutils import MockNXtomo class TestNabuVolumeOW(TestCaseQt): def setUp(self): super().setUp() self.tmp_dir = tempfile.mkdtemp() self.scan = MockNXtomo( scan_path=os.path.join(self.tmp_dir, "myscan"), n_proj=20, n_ini_proj=20, dim=10, ).scan self.widget = NabuVolumeOW() self.widget._processingStack.setDryRun(True) def tearDown(self): self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None shutil.rmtree(self.tmp_dir) self.qapp.processEvents() gc.collect() def test_serializing(self): pickle.dumps(self.widget.getConfiguration()) def test_literal_dumps(self): literal_dumps(self.widget.getConfiguration()) def test_scan_as_None(self): "test if scan is None" self.widget.process(None) def test_scan_un_preprocessed(self): "test when scan is unconfigured (No nabu_recons_params defined)" assert self.scan.nabu_recons_params is None self.widget.process(self.scan) def test_scan_ready_to_be_processed(self): "test if scan has valid reconstruction parameters to be runned" self.scan.nabu_recons_params = get_default_nabu_config( nabu_fullfield_default_config ) self.widget.process(self.scan) timeout = 3 loop_sleep_time = 0.05 while not self.widget._processingStack.can_process_next(): self.qapp.processEvents() timeout -= loop_sleep_time if timeout <= 0.0: raise TimeoutError("volume not process within expected time") else: sleep(loop_sleep_time) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_nabu_widget.py0000644000175000017500000000730315153325210033432 0ustar00paynopaynoimport gc import logging import os import pickle import shutil import tempfile import time from glob import glob import h5py from orangecanvas.scheme.readwrite import literal_dumps from silx.gui import qt from silx.gui.utils.testutils import SignalListener, TestCaseQt from nxtomo.nxobject.nxdetector import FOV from orangecontrib.tomwer.widgets.reconstruction.NabuOW import NabuOW from tomwer.core.process.reconstruction.nabu.utils import _NabuMode from tomwer.core.scan.nxtomoscan import NXtomoScan from tomwer.core.settings import mock_lsbram from tomwer.core.utils.lbsram import mock_low_memory from tomwer.synctools.darkref import QDKRFRP from tomwer.tests.datasets import TomwerCIDatasets logging.disable(logging.INFO) class TestNabuWidget(TestCaseQt): """class testing the NabuOW""" def setUp(self): TestCaseQt.setUp(self) self._recons_params = QDKRFRP() self.widget = NabuOW(parent=None) self.scan_dir = tempfile.mkdtemp() # create dataset self.master_file = os.path.join(self.scan_dir, "frm_edftomomill_twoentries.nx") shutil.copyfile( TomwerCIDatasets.get_dataset( "h5_datasets/frm_edftomomill_twoentries.nx", ), self.master_file, ) self.scan = NXtomoScan(scan=self.master_file, entry="entry0000") # create listener for the nabu widget self.signal_listener = SignalListener() # connect signal / slot self.widget.sigScanReady.connect(self.signal_listener) # set up mock_low_memory(True) mock_lsbram(True) self.widget.setDryRun(dry_run=True) def tearDown(self): mock_low_memory(False) mock_lsbram(False) self.widget.sigScanReady.disconnect(self.signal_listener) self._recons_params = None self.scan = None self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None gc.collect() def test_serializing(self): pickle.dumps(self.widget.getConfiguration()) def test_literal_dumps(self): literal_dumps(self.widget.getConfiguration()) def testLowMemory(self): """Make sure no reconstruction is started if we are low in memory in lbsram""" self.assertEqual(len(glob(os.path.join(self.scan_dir, "*.cfg"))), 0) self.widget.process(self.scan) self.wait_processing() self.assertEqual(len(glob(os.path.join(self.scan_dir, "*.cfg"))), 0) def wait_processing(self): timeout = 10 while timeout >= 0 and self.signal_listener.callCount() == 0: timeout -= 0.1 time.sleep(0.1) if timeout <= 0.0: raise TimeoutError("nabu widget never end processing") def patch_fov(self, value: str): with h5py.File(self.scan.master_file, mode="a") as h5s: for entry in ("entry0000", "entry0001"): entry_node = h5s[entry] if "instrument/detector/field_of_view" in entry_node: del entry_node["instrument/detector/field_of_view"] entry_node["instrument/detector/field_of_view"] = value def testSetConfiguration(self): """Make sure the configuration evolve from scan information""" self.assertEqual(self.widget.getMode(), _NabuMode.FULL_FIELD) self.patch_fov(value=FOV.HALF.value) self.widget.process(self.scan) self.wait_processing() self.assertEqual(self.widget.getMode(), _NabuMode.HALF_ACQ) self.patch_fov(value=FOV.FULL.value) self.scan.clear_cache() self.widget.process(self.scan) self.wait_processing() self.assertEqual(self.widget.getMode(), _NabuMode.FULL_FIELD) ././@PaxHeader0000000000000000000000000000020600000000000010213 xustar00112 path=tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_sa_delta_beta.py 22 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_sa_delta_beta.0000644000175000017500000000723015153325210033337 0ustar00paynopaynoimport logging import os import pickle import numpy from orangecanvas.scheme.readwrite import literal_dumps from processview.core.manager import DatasetState, ProcessManager from silx.io.url import DataUrl from silx.gui import qt from orangecontrib.tomwer.widgets.reconstruction.SADeltaBetaOW import ( SADeltaBetaOW as _SADeltaBetaOW, ) from tomwer.core.process.reconstruction.scores import ComputedScore from tomwer.core.utils.scanutils import MockNXtomo from tomwer.tests.conftest import qtapp # noqa F401 logger = logging.getLogger(__name__) class SADeltaBetaOW(_SADeltaBetaOW): """class saving scan finished to keep a trace on those.""" def __init__(self, parent=None): self._scans_finished = [] super().__init__(parent) def processing_finished(self, scan): self._scans_finished.append(scan) @property def scans_finished(self): return self._scans_finished def close(self): self._scans_finished = {} super().close() FRAME_DIM = 100 def create_scan(output_dir): return MockNXtomo( scan_path=output_dir, n_ini_proj=20, n_proj=20, n_alignement_proj=2, create_final_flat=False, create_ini_dark=True, create_ini_flat=True, n_refs=1, dim=FRAME_DIM, ).scan def patch_score(*args, **kwargs): """Function to save some result""" return DataUrl( file_path="/no_existing/path.hdf5", data_path="/no_existing_data_path", scheme="silx", ), ComputedScore( tv=numpy.random.random(), std=numpy.random.random(), ) def test_SADeltaBetaOW( qtapp, # noqa F811 tmp_path, ): source_dir = tmp_path / "source" source_dir.mkdir() # create scans scan_1 = create_scan(os.path.join(source_dir, "scan_1")) scan_2 = create_scan(os.path.join(source_dir, "scan_2")) scan_3 = create_scan(os.path.join(source_dir, "scan_3")) process_manager = ProcessManager() widget = SADeltaBetaOW() widget.show() widget._widget._processing_stack.patch_processing(patch_score) # make sure the configuration is serializable pickle.dumps(widget.getConfiguration()) # make sure this is compatible with 'literal dumps' literal_dumps(widget.getConfiguration()) # test behavior when 'autofocus' is lock. (in this case we expect to take the dataset with the higher score) and continue widget.lockAutofocus(False) def manual_processing(): widget.compute() qt.QApplication.processEvents() widget.wait_processing(5000) qt.QApplication.processEvents() widget.process(scan_1) manual_processing() assert ( process_manager.get_dataset_state( dataset_id=scan_1.get_identifier(), process=widget, ) == DatasetState.WAIT_USER_VALIDATION ) widget.process(scan_2) manual_processing() assert len(widget.scans_finished) == 0 assert ( process_manager.get_dataset_state( dataset_id=scan_1.get_identifier(), process=widget, ) == DatasetState.SKIPPED ) assert ( process_manager.get_dataset_state( dataset_id=scan_2.get_identifier(), process=widget, ) == DatasetState.WAIT_USER_VALIDATION ) widget.process(scan_3) manual_processing() widget.validateCurrentScan() assert ( process_manager.get_dataset_state( dataset_id=scan_3.get_identifier(), process=widget, ) == DatasetState.SUCCEED ) # ensure a cor has been registered assert scan_3.sa_delta_beta_params.selected_delta_beta_value is not None ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_saaxis.py0000644000175000017500000001013715153325210032431 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import logging import pickle import time import numpy from orangecanvas.scheme.readwrite import literal_dumps from processview.core.manager import DatasetState, ProcessManager from silx.io.url import DataUrl from silx.gui import qt from orangecontrib.tomwer.widgets.reconstruction.SAAxisOW import SAAxisOW as _SAAxisOW from tomwer.core.process.reconstruction.scores import ComputedScore from tomwer.core.utils.scanutils import MockNXtomo from tomwer.tests.conftest import qtapp # noqa F401 logger = logging.getLogger(__name__) class SAAxisOW(_SAAxisOW): def __init__(self, parent=None): self._scans_finished = [] super().__init__(parent) def processing_finished(self, scan): self._scans_finished.append(scan) @property def scans_finished(self): return self._scans_finished def close(self): self._scans_finished = {} super().close() FRAME_DIM = 100 def create_scan(output_dir): return MockNXtomo( scan_path=output_dir, n_ini_proj=20, n_proj=20, n_alignement_proj=2, create_final_flat=False, create_ini_dark=True, create_ini_flat=True, n_refs=1, dim=FRAME_DIM, ).scan def patch_score(*args, **kwargs): """Function to save some result""" return DataUrl( file_path="/no_existing/path.hdf5", data_path="/no_existing_data_path", scheme="silx", ), ComputedScore( tv=numpy.random.random(), std=numpy.random.random(), ) def test_SAAxisOW( qtapp, # noqa F811 tmp_path, ): source_dir = tmp_path / "source" source_dir.mkdir() # create scans scan_1 = create_scan(os.path.join(source_dir, "scan_1")) scan_2 = create_scan(os.path.join(source_dir, "scan_2")) scan_3 = create_scan(os.path.join(source_dir, "scan_3")) process_manager = ProcessManager() widget = SAAxisOW() widget.show() widget._widget._processing_stack.patch_processing(patch_score) # test configuration serialization pickle.dumps(widget.getConfiguration()) # test configuration is compatible with 'litteral dumps' literal_dumps(widget.getConfiguration()) # test behavior when 'auto focus' is lock (so widget is automated, should take the value with the higher score) widget.lockAutofocus(False) def manual_processing(): widget.load_sinogram() widget.compute() qt.QApplication.processEvents() widget.wait_processing(5000) qt.QApplication.processEvents() widget.process(scan_1) manual_processing() assert ( process_manager.get_dataset_state( dataset_id=scan_1.get_identifier(), process=widget, ) == DatasetState.WAIT_USER_VALIDATION ) widget.process(scan_2) manual_processing() assert len(widget.scans_finished) == 0 assert ( process_manager.get_dataset_state( dataset_id=scan_1.get_identifier(), process=widget, ) == DatasetState.SKIPPED ) assert ( process_manager.get_dataset_state( dataset_id=scan_2.get_identifier(), process=widget, ) == DatasetState.WAIT_USER_VALIDATION ) widget.process(scan_3) manual_processing() widget.validateCurrentScan() assert ( process_manager.get_dataset_state( dataset_id=scan_3.get_identifier(), process=widget, ) == DatasetState.SUCCEED ) # insure a cor has been registered assert scan_3.axis_params.relative_cor_value is not None # test autofocus is unlocked widget.lockAutofocus(True) for scan in (scan_1, scan_2, scan_3): widget.process(scan) widget.wait_processing(10000) while qt.QApplication.hasPendingEvents(): time.sleep(0.1) qt.QApplication.processEvents() assert ( process_manager.get_dataset_state( dataset_id=scan.get_identifier(), process=widget, ) == DatasetState.SUCCEED ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8811002 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/stitching/0000755000175000017500000000000015153325403025303 5ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9851027 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/stitching/tests/0000755000175000017500000000000015153325403026445 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/stitching/tests/test_zstitching.py0000644000175000017500000002625715153325210032254 0ustar00paynopaynoimport os import pickle import shutil import tempfile import numpy from orangecanvas.scheme.readwrite import literal_dumps from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.stitching.ZStitchingConfigOW import ZStitchingConfigOW from tomwer.core.utils.scanutils import MockNXtomo from tomwer.core.volume.hdf5volume import HDF5Volume class TestScansZStitchingConfigOW(TestCaseQt): """ Test stitching with scans """ def setUp(self): super().setUp() self._widget = ZStitchingConfigOW() self._tmp_dir = tempfile.mkdtemp() self._scans = [] for i_scan in range(3): scan = MockNXtomo( scan_path=os.path.join(self._tmp_dir, f"scan_{i_scan}.nx"), n_ini_proj=20, n_proj=20, n_alignement_proj=2, dim=10, ).scan self._scans.append(scan) self._widget.setConfiguration( { "inputs": { "input_datasets": [ scan.get_identifier().to_str() for scan in self._scans ], }, "stitching": { "type": "z-preproc", "stitching_strategy": "closest", "alignment_axis_1": "center", "alignment_axis_2": "center", "pad_mode": "constant", }, "preproc": { "data_path": "myentry", "location": "/path/to/mynexusfile.nx", }, } ) self.qapp.processEvents() def test_get_configuration(self): """Make sure the set configuration will be the get configuration""" config = self._widget.getConfiguration() assert config == { "inputs": { "input_datasets": list( [scan.get_identifier().to_str() for scan in self._scans] ), "slices": "", }, "stitching": { "stitching_strategy": "cosinus weights", "type": "z-preproc", "axis_0_pos_px": [0] * len(self._scans), "axis_0_params": "overlap_size=;img_reg_method=None;window_size=400", "axis_1_pos_px": [0] * len(self._scans), "axis_1_params": "img_reg_method=None;window_size=400", "flipud": False, "fliplr": False, "avoid_data_duplication": False, "rescale_frames": False, "rescale_params": "rescale_min_percentile=0;rescale_max_percentile=100", "alignment_axis_1": "center", "alignment_axis_2": "center", "pad_mode": "constant", }, "preproc": { "data_path": "myentry", "location": "/path/to/mynexusfile.nx", }, "output": { "overwrite_results": True, }, "normalization_by_sample": { "active": False, "margin": 0, "method": "median", "side": "left", "width": 30, }, } # test setting some metadata for stitching for i_scan, scan in enumerate( self._widget.widget._widget._mainWidget.getTomoObjs() ): scan.stitching_metadata.setPxPos(-i_scan, axis=0) scan.stitching_metadata.setPxPos(-i_scan * 10, axis=1) self.qapp.processEvents() config = self._widget.getConfiguration() assert config == { "inputs": { "input_datasets": list( [scan.get_identifier().to_str() for scan in self._scans] ), "slices": "", }, "stitching": { "type": "z-preproc", "stitching_strategy": "cosinus weights", "axis_0_pos_px": [0, -1, -2], "axis_0_params": "overlap_size=;img_reg_method=None;window_size=400", "axis_1_pos_px": [0, -10, -20], "axis_1_params": "img_reg_method=None;window_size=400", "flipud": False, "fliplr": False, "avoid_data_duplication": False, "rescale_frames": False, "rescale_params": "rescale_min_percentile=0;rescale_max_percentile=100", "alignment_axis_1": "center", "alignment_axis_2": "center", "pad_mode": "constant", }, "preproc": { "data_path": "myentry", "location": "/path/to/mynexusfile.nx", }, "output": { "overwrite_results": True, }, "normalization_by_sample": { "active": False, "margin": 0, "method": "median", "side": "left", "width": 30, }, } config["stitching"]["axis_1_pos_px"] = [0, -1, -2] config["output"]["overwrite_results"] = False self._widget.setConfiguration(config) assert self._widget.getConfiguration() == config def tearDown(self): self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None shutil.rmtree(self._tmp_dir) def test_serializing(self): pickle.dumps(self._widget.getConfiguration()) def test_literal_dumps(self): literal_dumps(self._widget.getConfiguration()) class TestVolumesZStitchingConfigOW(TestCaseQt): """ Test ZStitchingConfigOW with volumes """ def setUp(self): super().setUp() self._widget = ZStitchingConfigOW() self._tmp_dir = tempfile.mkdtemp() self._volumes = [] for i_volumes in range(4): volume = HDF5Volume( file_path=os.path.join(self._tmp_dir, f"volume_{i_volumes}.hdf5"), data_path="entry0000", data=numpy.ones(shape=(10, 20, 30)), metadata={}, ) volume.save() self._volumes.append(volume) self.output_volume = HDF5Volume( file_path=os.path.join(self._tmp_dir, "result.hdf5"), data_path="stitched", ) self._widget.setConfiguration( { "inputs": { "input_datasets": [ volume.get_identifier().to_str() for volume in self._volumes ], }, "stitching": { "type": "z-postproc", "stitching_strategy": "closest", "alignment_axis_1": "center", "alignment_axis_2": "center", "pad_mode": "constant", }, "postproc": { "output_volume": self.output_volume.get_identifier().to_str(), }, } ) self.qapp.processEvents() def test_get_configuration(self): """Make sure the set configuration will be the get configuration""" config = self._widget.getConfiguration() assert config == { "inputs": { "input_datasets": list( [scan.get_identifier().to_str() for scan in self._volumes] ), "slices": "", }, "stitching": { "stitching_strategy": "cosinus weights", "type": "z-postproc", "axis_0_pos_px": [0] * len(self._volumes), "axis_0_params": "overlap_size=;img_reg_method=None;window_size=400", "axis_1_pos_px": [0] * len(self._volumes), "axis_1_params": "img_reg_method=None;window_size=400", "flipud": False, "fliplr": False, "avoid_data_duplication": False, "rescale_frames": False, "rescale_params": "rescale_min_percentile=0;rescale_max_percentile=100", "alignment_axis_1": "center", "alignment_axis_2": "center", "pad_mode": "constant", }, "postproc": { "output_volume": self.output_volume.get_identifier().to_str(), }, "output": { "overwrite_results": True, }, "normalization_by_sample": { "active": False, "margin": 0, "method": "median", "side": "left", "width": 30, }, } # test setting some metadata for stitching for i_scan, scan in enumerate( self._widget.widget._widget._mainWidget.getTomoObjs() ): scan.stitching_metadata.setPxPos(-i_scan, axis=0) scan.stitching_metadata.setPxPos(-i_scan * 10, axis=1) self.qapp.processEvents() config = self._widget.getConfiguration() assert config == { "inputs": { "input_datasets": list( [scan.get_identifier().to_str() for scan in self._volumes] ), "slices": "", }, "stitching": { "stitching_strategy": "cosinus weights", "type": "z-postproc", "axis_0_pos_px": [0, -1, -2, -3], "axis_0_params": "overlap_size=;img_reg_method=None;window_size=400", "axis_1_pos_px": [0, -10, -20, -30], "axis_1_params": "img_reg_method=None;window_size=400", "flipud": False, "fliplr": False, "avoid_data_duplication": False, "rescale_frames": False, "rescale_params": "rescale_min_percentile=0;rescale_max_percentile=100", "alignment_axis_1": "center", "alignment_axis_2": "center", "pad_mode": "constant", }, "postproc": { "output_volume": self.output_volume.get_identifier().to_str(), }, "output": { "overwrite_results": True, }, "normalization_by_sample": { "active": False, "margin": 0, "method": "median", "side": "left", "width": 30, }, } # update some field to enhance test config["stitching"]["axis_1_pos_px"] = [0, -100, -200, -300] config["stitching"]["rescale_frames"] = True config["stitching"][ "rescale_params" ] = "rescale_min_percentile=10;rescale_max_percentile=35" config["output"]["overwrite_results"] = False self._widget.setConfiguration(config) assert self._widget.getConfiguration() == config def tearDown(self): self._widget.setAttribute(qt.Qt.WA_DeleteOnClose) self._widget.close() self._widget = None shutil.rmtree(self._tmp_dir) def test_serializing(self): pickle.dumps(self._widget.getConfiguration()) def test_literal_dumps(self): literal_dumps(self._widget.getConfiguration()) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/test_conditions.py0000644000175000017500000000546214757047403027112 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc import logging import os import shutil import tempfile from silx.gui import qt from silx.gui.utils.testutils import SignalListener, TestCaseQt from orangecontrib.tomwer.widgets.control.FilterOW import NameFilterOW from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.utils.scanutils import MockEDF, MockNXtomo logging.disable(logging.INFO) class NameFilterOWCI(NameFilterOW): sigScanReady = qt.Signal(str) """signal emitted when a scan is ready; Parameter is folder path of the scan""" def _signalScanReady(self, scan): self.sigScanReady.emit(scan.path) class TestFilterWidget(TestCaseQt): """class testing the DarkRefWidget""" def setUp(self): TestCaseQt.setUp(self) self.widget = NameFilterOWCI(parent=None) self.tmpdir = tempfile.mkdtemp() # create hdf5 dataset self._hdf5with_mytotodir = MockNXtomo( scan_path=os.path.join(self.tmpdir, "mytotodir120"), n_proj=10 ).scan self._hdf5without_mytotodir = MockNXtomo( scan_path=os.path.join(self.tmpdir, "totodir120"), n_proj=10 ).scan # create edf dataset mockEDF1 = MockEDF( scan_path=os.path.join(self.tmpdir, "mytotodir20"), n_radio=10 ) self.edfwith_mytotodir = EDFTomoScan(scan=mockEDF1.scan_path) mockEDF2 = MockEDF(scan_path=os.path.join(self.tmpdir, "dir120"), n_radio=10) self.edfwithout_mytotodir = EDFTomoScan(scan=mockEDF2.scan_path) # add a signal listener self.signalListener = SignalListener() self.widget.sigScanReady.connect(self.signalListener) # define the unix file pattern self.widget.setPattern("*mytotodir*") def tearDown(self): shutil.rmtree(self.tmpdir) self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None gc.collect() def testEDF(self): """Make sure filtering works with EDF""" self.assertEqual(self.signalListener.callCount(), 0) self.widget.applyfilter(self.edfwith_mytotodir) self.qapp.processEvents() self.assertEqual(self.signalListener.callCount(), 1) self.widget.applyfilter(self.edfwithout_mytotodir) self.qapp.processEvents() self.assertEqual(self.signalListener.callCount(), 1) def testHDF5(self): """Make sure filtering works with HDF5""" self.assertEqual(self.signalListener.callCount(), 0) self.widget.applyfilter(self._hdf5without_mytotodir) self.qapp.processEvents() self.assertEqual(self.signalListener.callCount(), 0) self.widget.applyfilter(self._hdf5with_mytotodir) self.qapp.processEvents() self.assertEqual(self.signalListener.callCount(), 1) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/test_darkref.py0000644000175000017500000001702415153325210026336 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc import logging import os import shutil import tempfile import time import pytest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.reconstruction.DarkRefAndCopyOW import ( DarkRefAndCopyOW, ) from tomwer.core.process.reconstruction.darkref.darkrefs import DarkRefsTask from tomwer.core.process.reconstruction.darkref.params import ReduceMethod as DkrfMethod from tomwer.core.process.reconstruction.darkref.settings import ( DARKHST_PREFIX, REFHST_PREFIX, ) from tomwer.core.scan.edfscan import EDFTomoScan from tomwer.core.utils.scanutils import MockEDF, MockNXtomo from tomwer.synctools.darkref import QDKRFRP logging.disable(logging.INFO) class TestEDFDarkRefWidget(TestCaseQt): """class testing the DarkRefWidget""" def setUp(self): TestCaseQt.setUp(self) self._recons_params = QDKRFRP() self.widget = DarkRefAndCopyOW(parent=None, reconsparams=self._recons_params) def tearDown(self): self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None self.qapp.processEvents() gc.collect() def testSyncRead(self): """Make sure any modification on the self._reconsParams is applied on the GUI""" rp = self._recons_params self.assertTrue(rp["REFSRMV"] is False) self.assertFalse( self.widget.widget.mainWidget.tabGeneral._rmOptionCB.isChecked() ) rp["REFSRMV"] = True self.assertTrue( self.widget.widget.mainWidget.tabGeneral._rmOptionCB.isChecked() ) pattern = self.widget.widget.mainWidget.tabExpert._refLE.text() newText = "popo.*" assert pattern != newText rp["RFFILE"] = newText self.assertTrue( self.widget.widget.mainWidget.tabExpert._refLE.text() == newText ) def testSyncWrite(self): """Test that if we edit through the :class:`DarkRefWidget` then the modification are fall back into the self._reconsParams""" rp = self._recons_params # test patterns pattern = self.widget.widget.mainWidget.tabExpert._refLE.text() newText = "popo.*" assert pattern != newText self.widget.widget.mainWidget.tabExpert._refLE.setText(newText) self.widget.widget.mainWidget.tabExpert._refLE.editingFinished.emit() qt.QApplication.instance().processEvents() self.assertTrue(rp["RFFILE"] == newText) self.widget.widget.mainWidget.tabExpert._darkLE.setText(newText) self.widget.widget.mainWidget.tabExpert._darkLE.editingFinished.emit() qt.QApplication.instance().processEvents() self.assertTrue(rp["DKFILE"] == newText) # test calc mode self.widget.widget.mainWidget.tabGeneral._darkWCB.setMode(DkrfMethod.NONE) self.widget.widget.mainWidget.tabGeneral._refWCB.setMode(DkrfMethod.MEDIAN) self.assertTrue(rp["DARKCAL"] == DkrfMethod.NONE) self.assertTrue(rp["REFSCAL"] == DkrfMethod.MEDIAN) # test options cuRm = self.widget.widget.mainWidget.tabGeneral._rmOptionCB.isChecked() self.widget.widget.mainWidget.tabGeneral._rmOptionCB.setChecked(not cuRm) self.assertTrue(rp["REFSRMV"] == (not cuRm)) self.assertTrue(rp["DARKRMV"] == (not cuRm)) cuSkip = self.widget.widget.mainWidget.tabGeneral._skipOptionCB.isChecked() self.widget.widget.mainWidget.tabGeneral._skipOptionCB.setChecked(not cuSkip) # warning : here value of skip and overwrite are of course inverse self.assertTrue(rp["DARKOVE"] == cuSkip) self.assertTrue(rp["REFSOVE"] == cuSkip) @pytest.mark.skip("Fail on CI") class TestDarkRefCopyWithEDFAndHDF5(TestCaseQt): """Test the DarkRefCopy orange widget behaviour""" def setUp(self) -> None: TestCaseQt.setUp(self) self._folder = tempfile.mkdtemp() # define scans to be treated hdf5_mock_with_refs = MockNXtomo( scan_path=os.path.join(self._folder, "h5_with_refs"), n_proj=10, n_ini_proj=10, dim=20, create_ini_flat=True, create_ini_dark=True, create_final_flat=False, ) self.hdf5_acquisition_with_refs = hdf5_mock_with_refs.scan hdf5_mock_without_refs = MockNXtomo( scan_path=os.path.join(self._folder, "h5_without_refs"), n_proj=10, n_ini_proj=10, dim=20, create_ini_flat=False, create_ini_dark=False, ) self.hdf5_acquisition_without_refs = hdf5_mock_without_refs.scan hdf5_mock_without_refs_incoherent_dim = MockNXtomo( scan_path=os.path.join(self._folder, "h5_without_refs_different_dim"), n_proj=10, n_ini_proj=10, dim=21, create_ini_flat=False, create_ini_dark=False, ) self.hdf5_acquisition_without_refs_incoherent_dim = ( hdf5_mock_without_refs_incoherent_dim.scan ) edf_mock_without_ref = MockEDF( scan_path=os.path.join(self._folder, "edf_without_refs"), dim=20, n_radio=20 ) self.edf_acquisition_without_ref = EDFTomoScan( scan=edf_mock_without_ref.scan_path ) # processes set up self._recons_params = QDKRFRP() self.widget = DarkRefAndCopyOW(parent=None, reconsparams=self._recons_params) self.widget.setForceSync(True) self.widget.show() def tearDown(self) -> None: time.sleep(0.5) while self.qapp.hasPendingEvents(): self.qapp.processEvents() self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None shutil.rmtree(self._folder) gc.collect() def testCopyInactive(self): self.widget.setCopyActive(False) self.widget.process(self.hdf5_acquisition_with_refs) # make sure no dark or flats exists for the hdf5 without refs for scan in ( self.hdf5_acquisition_without_refs_incoherent_dim, self.hdf5_acquisition_without_refs, ): self.widget.process(scan) # make sure no dark or flats exists for the edf one self.widget.process(self.edf_acquisition_without_ref) def testCopyActive(self): self.widget.setCopyActive(True) self.widget.setModeAuto(True) self.widget.process(self.hdf5_acquisition_with_refs) # 1. make sure dark has been processed for the one with ref self.assertTrue(self.widget.hasDarkStored()) self.assertTrue(self.widget.hasFlatStored()) # 2. make sure copy has been processed for the the 'compatible hdf5' self.widget.process(self.hdf5_acquisition_without_refs) # 3. make sure copy has been processed for the the 'compatible edf' self.widget.process(self.edf_acquisition_without_ref) self.assertEqual( len( DarkRefsTask.getRefHSTFiles( self.edf_acquisition_without_ref.path, prefix=REFHST_PREFIX ) ), 2, ) self.assertEqual( len( DarkRefsTask.getDarkHSTFiles( self.edf_acquisition_without_ref.path, prefix=DARKHST_PREFIX ) ), 1, ) # 4. make sure process but no copy made if incompatible size self.widget.process(self.hdf5_acquisition_without_refs_incoherent_dim) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/test_foldertransfert.py0000644000175000017500000000645215153325210030127 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc import logging import os import shutil import tempfile import time from glob import glob from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.control.DataTransfertOW import DataTransfertOW from tomwer.core.scan.scanfactory import ScanFactory from tomwer.core.utils.scanutils import MockEDF logging.disable(logging.INFO) class TestEDFFolderTransfertWidget(TestCaseQt): """class testing the DataTransfertOW within an EDF acquisition""" def setUp(self): TestCaseQt.setUp(self) self.n_file = 10 self.sourcedir = tempfile.mkdtemp() os.makedirs(self.sourcedir, exist_ok=True) self.targettedir = tempfile.mkdtemp() os.makedirs(self.targettedir, exist_ok=True) MockEDF.fastMockAcquisition(self.sourcedir, n_radio=self.n_file) self.scan = ScanFactory.create_scan_object(self.sourcedir) self.folderTransWidget = DataTransfertOW() self.folderTransWidget.turn_off_print = True self.folderTransWidget.setDestDir(self.targettedir) self.folderTransWidget._copying = False self.folderTransWidget.setForceSync(True) def tearDown(self): self.folderTransWidget.settingsHandler.removeCallback( self.folderTransWidget._updateSettingsVals ) self.folderTransWidget.setAttribute(qt.Qt.WA_DeleteOnClose) self.folderTransWidget.close() self.folderTransWidget = None if os.path.isdir(self.sourcedir): shutil.rmtree(self.sourcedir) if os.path.isdir(self.targettedir): shutil.rmtree(self.targettedir) gc.collect() def testMoveFiles(self): """ simple test that files are correctly moved """ self.folderTransWidget._process(self.scan, move=True, noRsync=True) outputdir = os.path.join(self.targettedir, os.path.basename(self.sourcedir)) timeout = 1 while ( (os.path.isdir(self.sourcedir)) and timeout > 0 or self.folderTransWidget.isCopying() ): timeout = timeout - 0.1 time.sleep(0.1) self.qapp.processEvents() self.assertTrue(os.path.isdir(outputdir)) self.assertTrue(self.checkDataCopied()) def testCopyFiles(self): """ Simple test that file are copy and deleted """ self.folderTransWidget._process(self.scan, move=False, noRsync=True) timeout = 1 outputdir = os.path.join(self.targettedir, os.path.basename(self.sourcedir)) while ( os.path.isdir(self.sourcedir) and timeout > 0 ) or self.folderTransWidget.isCopying(): timeout = timeout - 0.1 time.sleep(0.1) self.qapp.processEvents() time.sleep(1) self.assertTrue(os.path.isdir(outputdir)) self.assertTrue(self.checkDataCopied()) def checkDataCopied(self): outputdir = os.path.join(self.targettedir, os.path.basename(self.sourcedir)) outputFiles = os.listdir(outputdir) inputFile = glob(self.sourcedir) return ( (len(inputFile) == 0) and (len(outputFiles) == (self.n_file + 2)) and (not os.path.isdir(self.sourcedir)) ) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8811002 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/0000755000175000017500000000000015153325403026210 5ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9851027 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/0000755000175000017500000000000015153325403027352 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_dataviewerow.py0000644000175000017500000000277214757047403033506 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc import os import shutil import tempfile from orangecanvas.scheme.readwrite import literal_dumps from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.visualization.DataViewerOW import DataViewerOW from tomwer.core.utils.scanutils import MockNXtomo class TestDataViewerOW(TestCaseQt): def setUp(self): self.tmp_dir = tempfile.mkdtemp() self.scan = MockNXtomo( scan_path=os.path.join(self.tmp_dir, "myscan"), n_proj=20, n_ini_proj=20, dim=10, ).scan self.widget = DataViewerOW() def tearDown(self): self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None shutil.rmtree(self.tmp_dir) self.qapp.processEvents() gc.collect() def test(self): self.widget.addScan(self.scan) for mode in ( "projections-radios", "slices", "raw darks", "raw flats", "reduced darks", "reduced flats", ): self.widget.viewer.setDisplayMode(mode) self.qapp.processEvents() def test_literal_dumps(self): """ test settings are correcly dump to literals (and load) """ self.widget._updateSettings() config = self.widget._viewer_config literal_dumps(config) self.widget._setSettings(config) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_diffviewerow.py0000644000175000017500000000173114757047403033477 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc import os import shutil import tempfile from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.visualization.DiffViewerOW import DiffViewerOW from tomwer.core.utils.scanutils import MockNXtomo class TestDiffViewerOW(TestCaseQt): def setUp(self): super().setUp() self.tmp_dir = tempfile.mkdtemp() os.makedirs(self.tmp_dir, exist_ok=True) self.scan = MockNXtomo( scan_path=os.path.join(self.tmp_dir, "myscan"), n_proj=20, n_ini_proj=20, dim=10, ).scan self.widget = DiffViewerOW() def tearDown(self): self.widget.setAttribute(qt.Qt.WA_DeleteOnClose) self.widget.close() self.widget = None self.qapp.processEvents() shutil.rmtree(self.tmp_dir) gc.collect() def test(self): self.widget.addScan(self.scan) ././@PaxHeader0000000000000000000000000000021600000000000010214 xustar00120 path=tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_nxtomo_metadata_viewer.py 22 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_nxtomo_metadata0000644000175000017500000000154614757047403033540 0ustar00paynopaynoimport gc import pytest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.visualization.NXtomoMetadataViewerOW import ( NXtomoMetadataViewerOW, ) from tomwer.tests.utils import skip_gui_test @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestNXtomoMetadataViewerOW(TestCaseQt): """Test that the NXtomoEditorOW widget work correctly. Processing test are done in the core module. gui test are done in the tomwer.gui.edit module""" def setUp(self): super().setUp() self._window = NXtomoMetadataViewerOW() def tearDown(self): self._window.setAttribute(qt.Qt.WA_DeleteOnClose) self._window.close() self._window = None gc.collect() def test(self): self._window.show() self.qWaitForWindowExposed(self._window) ././@PaxHeader0000000000000000000000000000020500000000000010212 xustar00111 path=tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_radio_stackow.py 22 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_radio_stackow.p0000644000175000017500000000140014757047403033430 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc import pytest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.visualization.RadioStackOW import RadioStackOW from tomwer.tests.utils import skip_gui_test @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestRadioStack(TestCaseQt): """Test that the axis widget work correctly""" def setUp(self): super().setUp() self._window = RadioStackOW() def tearDown(self): self._window.setAttribute(qt.Qt.WA_DeleteOnClose) self._window.close() self._window = None gc.collect() def test(self): self._window.show() self.qWaitForWindowExposed(self._window) ././@PaxHeader0000000000000000000000000000020600000000000010213 xustar00112 path=tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_sample_movedow.py 22 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_sample_movedow.0000644000175000017500000000230714757047403033447 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc import tempfile import pytest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.visualization.SampleMovedOW import SampleMovedOW from tomwer.core.utils.scanutils import MockNXtomo from tomwer.tests.utils import skip_gui_test @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestSampleMoved(TestCaseQt): """Test that the axis widget work correctly""" def setUp(self): super().setUp() self._window = SampleMovedOW() self._tmp_path = tempfile.mkdtemp() self._scan = MockNXtomo( scan_path=self._tmp_path, create_ini_dark=True, create_ini_flat=True, create_final_flat=False, n_proj=10, n_ini_proj=10, dim=12, ).scan def tearDown(self): self._window.setAttribute(qt.Qt.WA_DeleteOnClose) self._window.close() self._window = None gc.collect() def test(self): self._window.show() self.qWaitForWindowExposed(self._window) self._window.updateScan(self._scan) self.qapp.processEvents() ././@PaxHeader0000000000000000000000000000021100000000000010207 xustar00115 path=tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_sinogram_viewerow.py 22 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_sinogram_viewer0000644000175000017500000000142214757047403033545 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc import pytest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.visualization.SinogramViewerOW import SinogramViewerOW from tomwer.tests.utils import skip_gui_test @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestSinogramViewerOW(TestCaseQt): """Test that the axis widget work correctly""" def setUp(self): super().setUp() self._window = SinogramViewerOW() def tearDown(self): self._window.setAttribute(qt.Qt.WA_DeleteOnClose) self._window.close() self._window = None gc.collect() def test(self): self._window.show() self.qWaitForWindowExposed(self._window) ././@PaxHeader0000000000000000000000000000020500000000000010212 xustar00111 path=tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_slice_stackow.py 22 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_slice_stackow.p0000644000175000017500000000144314757047403033440 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import gc import pytest from silx.gui import qt from silx.gui.utils.testutils import TestCaseQt from orangecontrib.tomwer.widgets.visualization.SliceStackOW import SlicesStackOW from tomwer.tests.utils import skip_gui_test @pytest.mark.skip("Fail on CI") @pytest.mark.skipif(skip_gui_test(), reason="skip gui test") class TestSliceStackOW(TestCaseQt): """Test that the axis widget work correctly""" def setUp(self): super().setUp() self._window = SlicesStackOW() def tearDown(self): self._window.setAttribute(qt.Qt.WA_DeleteOnClose) self._window.close() self._window = None gc.collect() def test(self): self._window.show() self.qWaitForWindowExposed(self._window) ././@PaxHeader0000000000000000000000000000020700000000000010214 xustar00113 path=tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_volume_viewerow.py 22 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_volume_viewerow0000644000175000017500000000325215153325210033570 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import numpy from silx.gui import qt from tomwer.tests.conftest import qtapp # noqa F401 from tomwer.core.volume.hdf5volume import HDF5Volume from orangecontrib.tomwer.widgets.visualization.VolumeViewerOW import VolumeViewerOW def test_VolumeViewerOW(qtapp, tmp_path): # noqa F811 """Test VolumeViewerOW""" volume = HDF5Volume( file_path=os.path.join(tmp_path, "my_volume.hdf5"), data_path="my_vol", ) volume.data = numpy.random.random((100, 100, 100)) volume.save() volume.metadata = {} window = VolumeViewerOW() window.show() # test setting a volume (already loaded in memory) window.set_dynamic_input("volume", volume) window.handleNewSignals() qt.QApplication.instance().processEvents() volumeViewerWindow = window._window._window assert ( volumeViewerWindow._geometryOrMetadataWidget._metadataWidget._volumeIdentifierQLE.text() == volume.get_identifier().to_str() ) assert len(volumeViewerWindow._XYPlot2D.getPlot().getAllImages()) == 1 # note: according to underlying threads other plot might have 0 or 1 image # test setting a volume not existing not_existing_volume = HDF5Volume( file_path="/does/not/exists.h5", data_path="my_vol", ) window.set_dynamic_input("volume", not_existing_volume) window.handleNewSignals() assert ( volumeViewerWindow._geometryOrMetadataWidget._metadataWidget._volumeIdentifierQLE.text() == not_existing_volume.get_identifier().to_str() ) for plot in volumeViewerWindow.getPlots().values(): assert len(plot.getAllImages()) == 0 ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.8811002 tomwer-1.6.17/src/tomwer/tests/tasks/0000755000175000017500000000000015153325403016615 5ustar00paynopayno././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9851027 tomwer-1.6.17/src/tomwer/tests/tasks/visualization/0000755000175000017500000000000015153325403021516 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/tests/tasks/visualization/test_volume_viewer.py0000644000175000017500000000524315143647637026042 0ustar00paynopaynofrom __future__ import annotations import os import numpy import pytest from tomwer.core.volume.tiffvolume import TIFFVolume from tomoscan.esrf.volume.tiffvolume import has_tifffile from tomoscan.volumebase import VolumeBase, SliceTuple from tomwer.core.volume.hdf5volume import HDF5Volume from tomwer.core.volume.edfvolume import EDFVolume from tomwer.tasks.visualization.volume_viewer import VolumeViewerTask volume_constructors = [ EDFVolume, HDF5Volume, ] if has_tifffile: volume_constructors.append(TIFFVolume) @pytest.mark.parametrize("volume_input_as", (VolumeBase, str)) @pytest.mark.parametrize("volume_constructor", volume_constructors) def test_volume_viewer(tmp_path, volume_constructor, volume_input_as): volume_data = numpy.ones((10, 20, 30)) volume_metadata = { "nabu_config": { "reconstruction": { "method": "FBP", }, "phase": { "method": "paganin", "delta_beta": 110.0, }, }, "processing_options": { "reconstruction": { "voxel_size_cm": (0.2, 0.2, 0.2), "rotation_axis_position": 104, "enable_halftomo": True, "fbp_filter_type": "Hilbert", "sample_detector_dist": 0.4, }, "take_log": { "log_min_clip": 1.0, "log_max_clip": 10.0, }, }, } if volume_constructor is HDF5Volume: volume = HDF5Volume( data=volume_data, metadata=volume_metadata, file_path=os.path.join(tmp_path, "output_file.h5"), data_path="my_volume", ) else: vol_basename = "my_vol" volume = volume_constructor( data=volume_data, metadata=volume_metadata, folder=os.path.join(tmp_path, vol_basename), volume_basename=vol_basename, ) volume.save() if volume_input_as is VolumeBase: input_volume = volume elif volume_input_as is str: input_volume = volume.get_identifier().to_str() else: raise TypeError(f"'volume_input_as' should be [{str}, {VolumeBase}]") task = VolumeViewerTask( inputs={ "volume": input_volume, "load_volume": True, } ) task.execute() slices = task.get_output_value("slices") assert len(slices) == 9 for slice_ in slices: assert isinstance(slice_, SliceTuple) assert isinstance(task.get_output_value("volume_metadata"), dict) loaded_volume = task.get_output_value("loaded_volume") assert isinstance(loaded_volume.data, numpy.ndarray) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9851027 tomwer-1.6.17/src/tomwer/tests/test_ewoks/0000755000175000017500000000000015153325403017657 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/test_ewoks/test_conversion.py0000644000175000017500000000710715153325210023456 0ustar00paynopaynoimport pytest from ewoksorange.bindings import owsconvert from tomwer.tests.datasets import TomwerCIDatasets ows_files_to_convert = ("from_nxtomo_to_volume.ows",) @pytest.mark.parametrize("orange_file_name", ows_files_to_convert) def test_conversion(orange_file_name): """test orange file can be converted to ewoks Graph""" scheme_file = TomwerCIDatasets.get_dataset(f"workflows/{orange_file_name}") graph = owsconvert.ows_to_ewoks(scheme_file) # make sure settings where correctly saved assert len(graph.graph.nodes) == 7 assert len(graph.graph.edges) == 6 # make sure the settings are properly loaded for node in graph.graph.nodes.values(): assert node["task_type"] == "class" assert node["task_identifier"].startswith("tomwer") # check settings of some specific nodes # dark and flat dark_flat_node = graph.graph.nodes["1"] assert ( dark_flat_node["task_identifier"] == "tomwer.core.process.reconstruction.darkref.darkrefscopy.DarkRefsCopy" ) assert "default_inputs" in dark_flat_node def fileter_dark_ref_params(my_dict): return my_dict["name"] == "dark_ref_params" dark_ref_params_settings = tuple( filter(fileter_dark_ref_params, dark_flat_node["default_inputs"]) ) assert len(dark_ref_params_settings) == 1 dark_ref_params_as_dict = dark_ref_params_settings[0]["value"] assert "DOWHEN" in dark_ref_params_as_dict assert "DARKCAL" in dark_ref_params_as_dict assert "DKFILE" in dark_ref_params_as_dict # axis axis_node = graph.graph.nodes["2"] assert ( axis_node["task_identifier"] == "tomwer.core.process.reconstruction.axis.axis.AxisTask" ) assert "default_inputs" in axis_node assert len(axis_node["default_inputs"]) == 2 # axis_params + gui metadata def filter_axis_params(my_dict): return my_dict["name"] == "axis_params" axis_params_settings = tuple( filter(filter_axis_params, axis_node["default_inputs"]) ) assert len(axis_params_settings) == 1 axis_params_as_dict = axis_params_settings[0]["value"] assert "MODE" in axis_params_as_dict assert "POSITION_VALUE" in axis_params_as_dict assert "SINOGRAM_LINE" in axis_params_as_dict # nabu slice nabu_slice_node = graph.graph.nodes["3"] assert ( nabu_slice_node["task_identifier"] == "tomwer.core.process.reconstruction.nabu.nabuslices.NabuSlicesTask" ) assert "default_inputs" in axis_node def filter_nabu_params(my_dict): return my_dict["name"] == "nabu_params" nabu_params_settings = tuple( filter(filter_nabu_params, nabu_slice_node["default_inputs"]) ) assert len(nabu_params_settings) == 1 nabu_params_as_dict = nabu_params_settings[0]["value"] assert "preproc" in nabu_params_as_dict assert "phase" in nabu_params_as_dict assert "tomwer_slices" in nabu_params_as_dict # nabu volume nabu_volume_node = graph.graph.nodes["4"] assert ( nabu_volume_node["task_identifier"] == "tomwer.core.process.reconstruction.nabu.nabuvolume.NabuVolumeTask" ) assert "default_inputs" in axis_node def filter_nabu_volume_params(my_dict): return my_dict["name"] == "nabu_volume_params" nabu_volume_params_settings = tuple( filter(filter_nabu_volume_params, nabu_volume_node["default_inputs"]) ) assert len(nabu_volume_params_settings) == 1 nabu_volume_params_as_dict = nabu_volume_params_settings[0]["value"] assert "start_z" in nabu_volume_params_as_dict assert "end_z" in nabu_volume_params_as_dict ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/test_ewoks/test_single_node_execution.py0000644000175000017500000000537515153325210025647 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import tempfile from glob import glob import pytest from ewokscore.graph import analysis, load_graph from ewokscore.graph.validate import validate_graph from tomwer.core.utils.scanutils import HDF5MockContext from nabu.pipeline.config import get_default_nabu_config from nabu.pipeline.fullfield.nabu_config import ( nabu_config as nabu_fullfield_default_config, ) try: from nabu.pipeline.fullfield.reconstruction import ( # noqa F401 FullFieldReconstructor, ) except ImportError: try: from nabu.pipeline.fullfield.local_reconstruction import ( # noqa F401 ChunkedReconstructor, ) except ImportError: has_nabu = False else: has_nabu = True else: has_nabu = True pytest.mark.skipif(condition=not has_nabu, reason="nabu not installed") classes_to_test = { "darkref": "tomwer.core.process.reconstruction.darkref.darkrefs.DarkRefs", "axis": "tomwer.core.process.reconstruction.axis.axis.AxisTask", "nabu slices": "tomwer.core.process.reconstruction.nabu.nabuslices.NabuSlices", } @pytest.mark.parametrize("node_name, node_qual_name", classes_to_test.items()) def test_single_class_instanciation(node_name, node_qual_name): with HDF5MockContext( scan_path=os.path.join(tempfile.mkdtemp(), "scan_test"), n_proj=100 ) as scan: # insure no cfg yet assert len(glob(os.path.join(scan.path, "*.cfg"))) == 0 graph = load_graph( { "nodes": [ { "id": node_name, "task_type": "class", "task_identifier": node_qual_name, "default_inputs": [ { "name": "data", "value": scan, }, { "name": "nabu_params", "value": get_default_nabu_config( nabu_fullfield_default_config ), }, ], }, ] } ) assert graph.is_cyclic is False, "graph is expected to be acyclic" assert analysis.start_nodes(graph.graph) == { node_name }, "graph is expected to have only on start nodes" validate_graph(graph.graph) result = graph.execute(varinfo=None) assert analysis.end_nodes(graph.graph) == { node_name }, "graph is expected to have only one end node" assert "data" in result, "data is expected to be part of the output_values" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/test_ewoks/test_workflows.py0000644000175000017500000001140715153325210023324 0ustar00paynopayno# coding: utf-8 from __future__ import annotations import os import tempfile from glob import glob from ewoks import execute_graph from ewokscore.graph import analysis, load_graph from ewokscore.graph.validate import validate_graph from tomwer.core.utils.scanutils import HDF5MockContext from tomwer.core.process.reconstruction.output import ( PROCESS_FOLDER_RECONSTRUCTED_VOLUMES, ) try: from nabu.pipeline.fullfield.reconstruction import ( # noqa F401 FullFieldReconstructor, ) except ImportError: try: from nabu.pipeline.fullfield.local_reconstruction import ( # noqa F401 ChunkedReconstructor, ) except ImportError: has_nabu = False else: has_nabu = True else: has_nabu = True def test_simple_workflow_nabu(): """Test the workflow: darkref -> axis -> nabu slices -> nabu volume""" with HDF5MockContext( scan_path=os.path.join(tempfile.mkdtemp(), "scan_test"), n_proj=100 ) as scan: # insure no cfg yet assert len(glob(os.path.join(scan.path, "*.cfg"))) == 0 graph = load_graph( source={ "nodes": [ { "id": "darkref", "task_type": "class", "task_identifier": "tomwer.core.process.reconstruction.darkref.darkrefs.DarkRefs", }, { "id": "axis", "task_type": "class", "task_identifier": "tomwer.core.process.reconstruction.axis.axis.AxisTask", "default_inputs": [ { "name": "axis_params", "value": { "MODE": "manual", "POSITION_VALUE": 0.2, }, }, ], }, { "id": "nabu slices", "task_type": "class", "task_identifier": "tomwer.core.process.reconstruction.nabu.nabuslices.NabuSlices", "dry_run": True, # as this is a mock dataset avoid to reconstruct it and only check for the .cfg file created "default_inputs": [ { "name": "nabu_params", "value": {"tomwer_slices": 2}, } ], }, { "id": "nabu volume", "task_type": "class", "task_identifier": "tomwer.core.process.reconstruction.nabu.nabuvolume.NabuVolume", "dry_run": True, "default_inputs": [ { "name": "dry_run", "value": True, } ], }, ], "links": [ { "source": "darkref", "target": "axis", "map_all_data": True, }, { "source": "axis", "target": "nabu slices", "data_mapping": [ # same as all arguments but just here to test both { "source_output": "data", "target_input": "data", }, ], }, { "source": "nabu slices", "target": "nabu volume", "map_all_data": True, }, ], } ) assert graph.is_cyclic is False, "graph is expected to be acyclic" assert analysis.start_nodes(graph=graph.graph) == { "darkref" }, "start node should be a single task `darkref`" validate_graph(graph.graph) result = execute_graph( graph, inputs=[ {"id": "darkref", "name": "data", "value": scan}, ], ) assert analysis.end_nodes(graph=graph.graph) == { "nabu volume" }, "should only have one result nodes" assert "data" in result, f"cannot find `nabu volume` in {result}" assert os.path.exists( os.path.join( scan.path, PROCESS_FOLDER_RECONSTRUCTED_VOLUMES, "nabu_cfg_files" ) ), "nabu has not been executed (even in dry mode)" ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/test_scripts.py0000644000175000017500000001177515153325210020577 0ustar00paynopayno"""Test suite to scripts""" import logging import subprocess import sys import unittest import os _logger = logging.getLogger(__name__) class TestScriptsHelp(unittest.TestCase): def executeCommandLine(self, command_line, env): """Execute a command line. Log output as debug in case of bad return code. """ _logger.info("Execute: %s", " ".join(command_line)) p = subprocess.Popen( command_line, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env ) out, err = p.communicate() _logger.info("Return code: %d", p.returncode) try: out = out.decode("utf-8") except UnicodeError: pass try: err = err.decode("utf-8") except UnicodeError: pass if p.returncode != 0: _logger.info("stdout:") _logger.info("%s", out) _logger.info("stderr:") _logger.info("%s", err) else: _logger.debug("stdout:") _logger.debug("%s", out) _logger.debug("stderr:") _logger.debug("%s", err) self.assertEqual(p.returncode, 0) def executeAppHelp(self, script_name, module_name): test_script = ScriptTest() script = test_script.script_path(script_name, module_name) env = test_script.get_test_env() if script.endswith(".exe"): command_line = [script] else: command_line = [sys.executable, script] command_line.append("--help") self.executeCommandLine(command_line, env) def testAxis(self): self.executeAppHelp("axis", "tomwer.app.axis") def testCanvas(self): self.executeAppHelp("axis", "tomwer.app.canvas") def testDarkRef(self): self.executeAppHelp("darkref", "tomwer.app.darkref") def testDarkRefPath(self): self.executeAppHelp("darkrefpatch", "tomwer.app.darkrefpatch") def testDiffFrame(self): self.executeAppHelp("diffFrame", "tomwer.app.diffframe") def testImageKeyEditor(self): self.executeAppHelp("image-key-editor", "tomwer.app.imagekeyeditor") def testImageKeyUpgrader(self): self.executeAppHelp("image-key-upgrader", "tomwer.app.imagekeyupgrader") def testIntensityNormalization(self): self.executeAppHelp( "intensity-normalization", "tomwer.app.intensitynormalization" ) def testMulticor(self): self.executeAppHelp("multicor", "tomwer.app.multicor") def testMultiPag(self): self.executeAppHelp("multipag", "tomwer.app.multipag") def testNabu(self): self.executeAppHelp("nabu", "tomwer.app.nabuapp") def testNxTomoEditor(self): self.executeAppHelp("nxtomo-editor", "tomwer.app.nxtomoeditor") def testPatchRawDarkflat(self): self.executeAppHelp("patch-raw-dark-flat", "tomwer.app.patchrawdarkflat") def testRadioStack(self): self.executeAppHelp("radiostack", "tomwer.app.radiostack") def testReduceDarkFlat(self): self.executeAppHelp("reduce-dark-flat", "tomwer.app.reducedarkflat") def testRSync(self): self.executeAppHelp("rsync", "tomwer.app.rsync") def testSampleMoved(self): self.executeAppHelp("samplemoved", "tomwer.app.samplemoved") def testScanviewer(self): self.executeAppHelp("scanviewer", "tomwer.app.scanviewer") def testSinogramViewer(self): self.executeAppHelp("sinogramviewer", "tomwer.app.sinogramviewer") def testSliceStack(self): self.executeAppHelp("slicestack", "tomwer.app.slicestack") def testStopDataListener(self): self.executeAppHelp("stop-data-listener", "tomwer.app.stopdatalistener") def testZStitching(self): self.executeAppHelp("zstitching", "tomwer.app.zstitching") class ScriptTest: """ Class providing useful stuff for preparing script tests. """ def get_test_env(self): """ Returns an associated environment with a working project. """ env = dict((str(k), str(v)) for k, v in os.environ.items()) env["PYTHONPATH"] = os.pathsep.join(sys.path) return env def script_path(self, script_name, module_name): """Returns the script path according to it's location""" import importlib module = importlib.import_module(module_name) script = module.__file__ return script def get_installed_script_path(self, script): """ Returns the path of the executable and the associated environment In Windows, it checks availability of script using .py .bat, and .exe file extensions. """ paths = os.environ.get("PATH", "").split(os.pathsep) for base in paths: # clean up extra quotes from paths if base.startswith('"') and base.endswith('"'): base = base[1:-1] # script not found _logger.warning("Script '%s' not found in paths: %s", script, ":".join(paths)) script_path = script return script_path ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989064.0 tomwer-1.6.17/src/tomwer/tests/test_utils.py0000644000175000017500000000256715153325210020247 0ustar00paynopaynofrom __future__ import annotations import pint import numpy from tomwer.utils import Launcher from nxtomo.nxobject.nxtransformations import ( get_lr_flip, get_ud_flip, ) _ureg = pint.get_application_registry() def test_launcher(): launcher = Launcher(prog="tomwer", version="1.0") launcher.add_command( "canvas", module_name="tomwer.app.canvas", description="open the orange-canvas" ) launcher.print_help() launcher.execute_help(["tomwer", "canvas"]) def is_lr_flip(transformations) -> bool: """sum all rotation the detector 'y' axis and check that the sum is 180 (in this case we consider this is a detector left-right flip)""" lr_rot_sum = sum( [trans.transformation_values for trans in get_lr_flip(transformations)] ) assert isinstance(lr_rot_sum, pint.Quantity) return bool( numpy.isclose( lr_rot_sum, 180.0 * _ureg.degree, ) ) def is_ud_flip(transformations) -> bool: """sum all rotation the detector 'x' axis and check that the sum is 180 (in this case we consider this is a detector up-down flip)""" ud_rot_sum = sum( [trans.transformation_values for trans in get_ud_flip(transformations)] ) assert isinstance(ud_rot_sum, pint.Quantity) return bool( numpy.isclose( ud_rot_sum, 180.0 * _ureg.degree, ) ) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1740394243.0 tomwer-1.6.17/src/tomwer/tests/utils.py0000644000175000017500000000015314757047403017213 0ustar00paynopaynoimport os def skip_gui_test(): return os.environ.get("_TOMWER_NO_GUI_UNIT_TESTS", "False") == "True" ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9891026 tomwer-1.6.17/src/tomwer/third_part/0000755000175000017500000000000015153325403016466 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/third_part/FrameBrowser.py0000644000175000017500000000401715143647637021457 0ustar00paynopaynofrom silx.gui import qt class SliderPlayWidgetAction(qt.QWidgetAction): sigValueChanged = qt.Signal(int) def __init__( self, parent: qt.QWidget | None = None, label: str | None = None, tooltip: str | None = None, ): super().__init__(parent) self._build(label=label, tooltip=tooltip) def _build(self, label: str, tooltip: str): widget = qt.QWidget() layout = qt.QHBoxLayout() widget.setLayout(layout) self._spinbox = qt.QSpinBox() self._spinbox.setToolTip(tooltip) self._spinbox.setRange(1, 1000000) self._spinbox.valueChanged.connect(self.sigValueChanged) label = qt.QLabel(label) label.setToolTip(tooltip) layout.addWidget(label) layout.addWidget(self._spinbox) self.setDefaultWidget(widget) def value(self) -> int: return self._spinbox.value() def setValue(self, value: int): self._spinbox.setValue(value) class PlayButtonContextMenu(qt.QMenu): sigFrameRateChanged = qt.Signal(int) def __init__(self, parent: qt.QWidget | None = None): super().__init__(parent) self._build() def _build(self): self._framerateAction = SliderPlayWidgetAction( self, label="FPS:", tooltip="Display speed in frames per second" ) self._framerateAction.sigValueChanged.connect(self.sigFrameRateChanged) self._stepAction = SliderPlayWidgetAction( self, label="Step:", tooltip="Step between displayed frames" ) self.addAction(self._framerateAction) self._framerateAction.setValue(10) self.addAction(self._stepAction) self._stepAction.setValue(1) def getFrameRate(self) -> int: return self._framerateAction.value() def setFrameRate(self, rate: int): self._framerateAction.setValue(rate) def getStep(self) -> int: return self._stepAction.value() def setStep(self, interval: int): self._stepAction.setValue(interval) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/third_part/OverlayMixIn.py0000644000175000017500000001040615143647637021446 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from silx.gui.qt import inspect as qt_inspect from silx.gui.plot import PlotWidget class OverlayMixIn: """ MixIn class for overlay widget. For usage examples refer to :class:`WaitingOverlay`, :class:`LabelOverlay` and :class:`ButtonOverlay` .. warning:: Any class inheriting from this mixin must also inherit from a QWidget. """ def __init__( self, parent, ): self._alignment: qt.Qt.AlignmentFlag = qt.Qt.AlignCenter self._alignmentOffsets: tuple[int, int] = (0, 0) self._registerParent(parent=parent) def getAlignment(self) -> qt.Qt.AlignmentFlag: return self._alignment def setAlignment(self, alignment: qt.Qt.AlignmentFlag): self._alignment = alignment self.update() def getAlignmentOffsets(self) -> tuple[int, int]: return self._alignmentOffsets def setAlignmentOffsets(self, offsets: tuple[int, int]): self._alignmentOffsets = offsets def _listenedWidget(self, parent: qt.QWidget) -> qt.QWidget: """Returns widget to register event filter to according to parent""" if isinstance(parent, PlotWidget): return parent.getWidgetHandle() return parent def _backendChanged(self): self._listenedWidget(self.parent()).installEventFilter(self) self._resizeLater() def _registerParent(self, parent: qt.QWidget | None): if parent is None: return self._listenedWidget(parent).installEventFilter(self) if isinstance(parent, PlotWidget): parent.sigBackendChanged.connect(self._backendChanged) self._resize() def _unregisterParent(self, parent: qt.QWidget | None): if parent is None: return if isinstance(parent, PlotWidget): parent.sigBackendChanged.disconnect(self._backendChanged) self._listenedWidget(parent).removeEventFilter(self) def setParent(self, parent: qt.QWidget): self._unregisterParent(self.parent()) super().setParent(parent) self._registerParent(parent) def _getGeometry(self) -> qt.QRect | None: """Return the top left corner of the geometry to set up the geometry""" parent = self.parent() if parent is None: return None overlaySize = self.sizeHint() if isinstance(parent, PlotWidget): offset = parent.getWidgetHandle().mapTo(parent, qt.QPoint(0, 0)) canvasLeft, canvasTop, canvasWidth, canvasHeight = ( parent.getPlotBoundsInPixels() ) canvasLeft += offset.x() canvasTop += offset.y() else: canvasWidth = parent.size().width() canvasHeight = parent.size().height() canvasLeft = 0 canvasTop = 0 # calculate left position if self._alignment & qt.Qt.AlignTop: top = canvasTop elif self._alignment & qt.Qt.AlignBottom: top = canvasTop + canvasHeight - overlaySize.height() else: top = canvasTop + (canvasHeight - overlaySize.height()) / 2 # calculate top position if self._alignment & qt.Qt.AlignLeft: left = canvasLeft elif self._alignment & qt.Qt.AlignRight: left = canvasLeft + canvasWidth - overlaySize.width() else: left = canvasLeft + (canvasWidth - overlaySize.width()) / 2 topLeft = qt.QPoint( int(left + self._alignmentOffsets[0]), int(top + self._alignmentOffsets[1]), ) return qt.QRect( topLeft, overlaySize, ) def _resize(self): if not qt_inspect.isValid(self): return # For _resizeLater in case the widget has been deleted rect = self._getGeometry() if rect is None: return self.setGeometry(rect) self.raise_() def _resizeLater(self): qt.QTimer.singleShot(0, self._resize) def eventFilter(self, watched: qt.QWidget, event: qt.QEvent): if event.type() == qt.QEvent.Resize: self._resize() self._resizeLater() # Defer resize for the receiver to have handled it return super().eventFilter(watched, event) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1770999711.0 tomwer-1.6.17/src/tomwer/third_part/qitem_model_resetter.py0000644000175000017500000000065115143647637023275 0ustar00paynopaynofrom __future__ import annotations from silx.gui import qt from contextlib import contextmanager @contextmanager def qitem_model_resetter(model: qt.QAbstractItemModel): """Context manager for resetting a QAbstractItemModel. Make sure `beginResetModel()` is emit at the beginning and endResetModel() at the end. """ model.beginResetModel() try: yield finally: model.endResetModel() ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1760415684.0 tomwer-1.6.17/src/tomwer/utils.py0000644000175000017500000001554015073347704016056 0ustar00paynopayno# coding: utf-8 """ some project general utils functions """ from __future__ import annotations import argparse import functools import importlib import logging import sys from silx.utils.launcher import Launcher as _Launcher from silx.utils.launcher import LauncherCommand as _LauncherCommand _logger = logging.getLogger(__file__) def _docstring(dest, origin): """Implementation of docstring decorator. It patches dest.__doc__. """ if not isinstance(dest, type) and isinstance(origin, type): # func is not a class, but origin is, get the method with the same name try: origin = getattr(origin, dest.__name__) except AttributeError: raise ValueError("origin class has no %s method" % dest.__name__) dest.__doc__ = origin.__doc__ return dest def docstring(origin): """Decorator to initialize the docstring from another source. This is useful to duplicate a docstring for inheritance and composition. If origin is a method or a function, it copies its docstring. If origin is a class, the docstring is copied from the method of that class which has the same name as the method/function being decorated. :param origin: The method, function or class from which to get the docstring :raises ValueError: If the origin class has not method n case the """ return functools.partial(_docstring, origin=origin) class LauncherCommand(_LauncherCommand): """Description of a command""" def get_module(self): """Returns the python module to execute. If any.""" try: module = importlib.import_module(self.module_name) return module except ImportError: msg = "Error while reaching module '%s'" _logger.error(msg, self.module_name, exc_info=True) raise class Launcher(_Launcher): """ Manage launch of module. Provides an API to describe available commands and feature to display help and execute the commands. """ def __init__( self, prog=None, usage=None, description=None, epilog=None, version=None ): """ :param prog: Name of the program. If it is not defined it uses the first argument of `sys.argv` :param usage: Custom the string explaining the usage. Else it is autogenerated. :param description: Description of the application displayed after the usage. :param epilog: Custom the string displayed at the end of the help. :param version: Define the version of the application. """ if prog is None: prog = sys.argv[0] self.prog = prog self.usage = usage self.description = description self.epilog = epilog self.version = version self._commands = {} help_command = LauncherCommand( "help", description="Show help of the following command", function=self.execute_help, ) self.add_command(command=help_command) def add_command(self, name=None, module_name=None, description=None, command=None): """ Add a command to the launcher. See also `LauncherCommand`. :param name: Name of the command :param module_name: Module to execute :param description: Description of the command :param LauncherCommand command: A `LauncherCommand` """ if command is not None: assert name is None and module_name is None and description is None else: command = LauncherCommand( name=name, description=description, module_name=module_name ) self._commands[command.name] = command def print_help(self): """Print the help to stdout.""" usage = self.usage if usage is None: usage = "usage: {0.prog} [--version|--help] []" description = self.description epilog = self.epilog if epilog is None: epilog = "See '{0.prog} help ' to read about a specific subcommand" print(usage.format(self)) print("") if description is not None: print(description) print("") print("The {0.prog} commands are:".format(self)) commands = sorted(self._commands.keys()) for command in commands: command = self._commands[command] print(" {:18s} {:s}".format(command.name, command.description)) print("") print(epilog.format(self)) def execute_help(self, argv): """Execute the help command. :param argv: The list of arguments (the first one is the name of the application with the help command) :returns: The execution status """ description = "Display help information about %s" % self.prog parser = argparse.ArgumentParser(description=description) parser.add_argument( "command", default=None, nargs=argparse.OPTIONAL, help="Command in which aving help", ) try: options = parser.parse_args(argv[1:]) except SystemExit as e: # ArgumentParser likes to finish with a sys.exit return e.args[0] command_name = options.command if command_name is None: self.print_help() return 0 if command_name not in self._commands: print(f"Unknown command: {command_name}") self.print_help() return -1 command = self._commands[command_name] prog = f"{self.prog} {command.name}" return command.execute([prog, "--help"]) def execute(self, argv=None): """Execute the launcher. :param argv: The list of arguments (the first one is the name of the application) :returns: The execution status """ if argv is None: argv = sys.argv if len(argv) <= 1: self.print_help() return 0 command_name = argv[1] if command_name == "--version": print(f"{self.prog} version {str(self.version)}") return 0 if command_name in ["--help", "-h"]: # Special help command if len(argv) == 2: self.print_help() return 0 else: command_name = argv[2] command_argv = argv[2:] + ["--help"] command_argv[0] = f"{self.prog} {command_argv[0]}" else: command_argv = argv[1:] command_argv[0] = f"{self.prog} {command_argv[0]}" if command_name not in self._commands: print("Unknown command: %s" % command_name) self.print_help() return -1 command = self._commands[command_name] return command.execute(command_argv) ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989149.0 tomwer-1.6.17/src/tomwer/version.py0000644000175000017500000001044315153325335016373 0ustar00paynopayno#!/usr/bin/env python # coding: utf-8 # /*########################################################################## # # Copyright (c) 2015-2016 European Synchrotron Radiation Facility # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. # # ###########################################################################*/ """Unique place where the version number is defined. provides: * version = "1.2.3" or "1.2.3-beta4" * version_info = named tuple (1,2,3,"beta",4) * hexversion: 0x010203B4 * strictversion = "1.2.3b4 * debianversion = "1.2.3~beta4" * calc_hexversion: the function to transform a version_tuple into an integer This is called hexversion since it only really looks meaningful when viewed as the result of passing it to the built-in hex() function. The version_info value may be used for a more human-friendly encoding of the same information. The hexversion is a 32-bit number with the following layout: Bits (big endian order) Meaning 1-8 PY_MAJOR_VERSION (the 2 in 2.1.0a3) 9-16 PY_MINOR_VERSION (the 1 in 2.1.0a3) 17-24 PY_MICRO_VERSION (the 0 in 2.1.0a3) 25-28 PY_RELEASE_LEVEL (0xA for alpha, 0xB for beta, 0xC for release candidate and 0xF for final) 29-32 PY_RELEASE_SERIAL (the 3 in 2.1.0a3, zero for final releases) Thus 2.1.0a3 is hexversion 0x020100a3. """ from collections import namedtuple __authors__ = ["Jérôme Kieffer"] __license__ = "MIT" __copyright__ = "European Synchrotron Radiation Facility, Grenoble, France" __date__ = "17/06/2016" __status__ = "production" __docformat__ = "restructuredtext" __all__ = [ "date", "version_info", "strictversion", "hexversion", "debianversion", "calc_hexversion", ] RELEASE_LEVEL_VALUE = { "dev": 0, "alpha": 10, "beta": 11, "gamma": 11, "rc": 12, "final": 15, } MAJOR = 1 MINOR = 6 MICRO = 17 RELEV = "final" # <16 SERIAL = 0 # <16 date = __date__ _version_info = namedtuple( "version_info", ["major", "minor", "micro", "releaselevel", "serial"] ) version_info = _version_info(MAJOR, MINOR, MICRO, RELEV, SERIAL) strictversion = version = debianversion = "%d.%d.%d" % version_info[:3] latest_release_version_info = "0.9.0" if version_info.releaselevel != "final": version += "-%s%s" % version_info[-2:] debianversion += ( "~adev%i" % version_info[-1] if RELEV == "dev" else "~%s%i" % version_info[-2:] ) prerel = "a" if RELEASE_LEVEL_VALUE.get(version_info[3], 0) < 10 else "b" if prerel not in "ab": prerel = "a" strictversion += prerel + str(version_info[-1]) def calc_hexversion(major=0, minor=0, micro=0, releaselevel="dev", serial=0): """Calculate the hexadecimal version number from the tuple version_info: :param major: integer :param minor: integer :param micro: integer :param relev: integer or string :param serial: integer :return: integerm always increasing with revision numbers """ try: releaselevel = int(releaselevel) except ValueError: releaselevel = RELEASE_LEVEL_VALUE.get(releaselevel, 0) hex_version = int(serial) hex_version |= releaselevel * 1 << 4 hex_version |= int(micro) * 1 << 8 hex_version |= int(minor) * 1 << 16 hex_version |= int(major) * 1 << 24 return hex_version hexversion = calc_hexversion(*version_info) if __name__ == "__main__": print(version) ././@PaxHeader0000000000000000000000000000003400000000000010212 xustar0028 mtime=1772989186.9891026 tomwer-1.6.17/src/tomwer.egg-info/0000755000175000017500000000000015153325403016020 5ustar00paynopayno././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989186.0 tomwer-1.6.17/src/tomwer.egg-info/PKG-INFO0000644000175000017500000001621115153325402017115 0ustar00paynopaynoMetadata-Version: 2.4 Name: tomwer Version: 1.6.17 Summary: Tomography workflow tools Author-email: Henri Payno , Pierre Paleo , Pierre-Olivier Autran , Jérôme Lesaint , Alessandro Mirone License: MIT Project-URL: Homepage, https://gitlab.esrf.fr/tomotools/tomwer Project-URL: Documentation, https://tomotools.gitlab-pages.esrf.fr/tomwer/ Project-URL: Repository, https://gitlab.esrf.fr/tomotools/tomwer Project-URL: Issues, https://gitlab.esrf.fr/tomotools/tomwer/-/issues Project-URL: Changelog, https://gitlab.esrf.fr/tomotools/tomwer/-/blob/main/CHANGELOG.rst?ref_type=heads Keywords: orange3 add-on,ewoks Classifier: Intended Audience :: Education Classifier: Intended Audience :: Science/Research Classifier: License :: OSI Approved :: MIT License Classifier: Programming Language :: Python :: 3 Classifier: Environment :: Console Classifier: Environment :: X11 Applications :: Qt Classifier: Operating System :: POSIX Classifier: Natural Language :: English Classifier: Topic :: Scientific/Engineering :: Physics Classifier: Topic :: Software Development :: Libraries :: Python Modules Requires-Python: >=3.10 Description-Content-Type: text/x-rst License-File: LICENSE Requires-Dist: numpy Requires-Dist: setuptools<81 Requires-Dist: psutil Requires-Dist: silx[full]>=2.1.1 Requires-Dist: tomoscan>=2.2.0a6 Requires-Dist: nxtomo>2.0.0dev2 Requires-Dist: nxtomomill>=2.0.0dev0 Requires-Dist: processview>=1.5.0 Requires-Dist: ewoks>=0.1.1 Requires-Dist: ewokscore<2.0,>=1.5 Requires-Dist: sluurp>=0.4.1 Requires-Dist: packaging Requires-Dist: pint Requires-Dist: tqdm Requires-Dist: eval_type_backport; python_version < "3.10" Requires-Dist: platformdirs Provides-Extra: full-base Requires-Dist: orange-canvas-core; extra == "full-base" Requires-Dist: orange-widget-base; extra == "full-base" Requires-Dist: ewoks[orange]>=0.1.1; extra == "full-base" Requires-Dist: ewoksorange<2.0,>=0.7.0rc0; extra == "full-base" Requires-Dist: fabio; extra == "full-base" Requires-Dist: h5py>=3; extra == "full-base" Requires-Dist: lxml; extra == "full-base" Requires-Dist: werkzeug; extra == "full-base" Requires-Dist: json-rpc; extra == "full-base" Requires-Dist: scipy; extra == "full-base" Requires-Dist: Pillow; extra == "full-base" Requires-Dist: resource; extra == "full-base" Requires-Dist: tifffile; extra == "full-base" Requires-Dist: hdf5plugin; extra == "full-base" Requires-Dist: pyicat_plus; extra == "full-base" Requires-Dist: ewoksnotify[full]<0.2; extra == "full-base" Requires-Dist: pyicat_plus; extra == "full-base" Requires-Dist: rsyncmanager; extra == "full-base" Requires-Dist: blissdata; extra == "full-base" Provides-Extra: full-no-cuda Requires-Dist: tomwer[full_base]; extra == "full-no-cuda" Requires-Dist: nabu>=2024.2.0; extra == "full-no-cuda" Provides-Extra: full Requires-Dist: tomwer[full_base]; extra == "full" Requires-Dist: nabu[full]>=2024.2.0; extra == "full" Requires-Dist: pycuda<2024.1.1; extra == "full" Requires-Dist: scikit-cuda; extra == "full" Provides-Extra: doc Requires-Dist: tomwer[full_no_cuda]; extra == "doc" Requires-Dist: Sphinx>=4.0.0; extra == "doc" Requires-Dist: nbsphinx; extra == "doc" Requires-Dist: pandoc; extra == "doc" Requires-Dist: jupyterlab; extra == "doc" Requires-Dist: pydata_sphinx_theme; extra == "doc" Requires-Dist: sphinx-design; extra == "doc" Requires-Dist: sphinx-autodoc-typehints; extra == "doc" Requires-Dist: sphinxcontrib-programoutput; extra == "doc" Requires-Dist: sphinxcontrib-youtube; extra == "doc" Requires-Dist: myst-parser; extra == "doc" Requires-Dist: nb_extension_tagstyler; extra == "doc" Provides-Extra: dev-spec Requires-Dist: black; extra == "dev-spec" Requires-Dist: flake8; extra == "dev-spec" Requires-Dist: timeout-decorator; extra == "dev-spec" Requires-Dist: pyopencl; extra == "dev-spec" Provides-Extra: dev Requires-Dist: tomwer[full]; extra == "dev" Requires-Dist: tomwer[dev_spec]; extra == "dev" Provides-Extra: dev-no-cuda Requires-Dist: tomwer[full_no_cuda]; extra == "dev-no-cuda" Requires-Dist: tomwer[dev_spec]; extra == "dev-no-cuda" Provides-Extra: test Requires-Dist: tomwer[full_no_cuda]; extra == "test" Requires-Dist: pytest-asyncio; extra == "test" Requires-Dist: tomoscan[test]>=2.2.0a6; extra == "test" Dynamic: license-file .. image:: doc/img/tomwer.png :alt: Tomwer Logo :align: left :width: 400px Introduction ------------ **Tomwer** provides tools to automate acquisition and reconstruction processes for tomography. The package includes: - A library to individually access each acquisition process. - Graphical User Interface (GUI) applications to control key processes such as reconstruction and data transfer, which can be executed as standalone applications. - An Orange add-on to help users define custom workflows (`Orange3 `_). Tomwer relies on `Nabu `_ for tomographic reconstruction. **Note**: Currently, the software is only compatible with Linux. Documentation ------------- The latest version of the documentation is available `here `_. Installation ------------ Step 1: Installing Tomwer ''''''''''''''''''''''''' To install Tomwer with all features: .. code-block:: bash pip install tomwer[full] Alternatively, you can install the latest development branch from the repository: .. code-block:: bash pip install git+https://gitlab.esrf.fr/tomotools/tomwer/#egg=tomwer[full] Step 2: (Optional) Update Orange-CANVAS-CORE and Orange-WIDGET-BASE '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' If you need access to additional 'processing' wheels and 'reprocess action,' you may want to update these Orange forks. This is optional, as the project works with the native Orange libraries. .. code-block:: bash pip install git+https://github.com/payno/orange-canvas-core --no-deps --upgrade pip install git+https://github.com/payno/orange-widget-base --no-deps --upgrade Launching Applications ----------------------- After installation, Tomwer includes several applications. You can launch an application by running: .. code-block:: bash tomwer [options] - If you run `tomwer` without arguments, a manual page will be displayed. - For application-specific help, run: .. code-block:: bash tomwer --help Tomwer Canvas - Orange Canvas ----------------------------- You can launch the Orange canvas to create workflows using the available building blocks: .. code-block:: bash tomwer canvas - Alternatively, you can use `orange-canvas`. - If you're using a virtual environment, remember to activate it: .. code-block:: bash source myvirtualenv/bin/activate Building Documentation ----------------------- To build the documentation: .. code-block:: bash sphinx-build doc build/html The documentation will be generated in `doc/build/html`, and the entry point is `index.html`. To view the documentation in a browser: .. code-block:: bash firefox build/html/index.html **Note**: Building the documentation requires `sphinx` to be installed, which is not a hard dependency of Tomwer. If needed, install it separately. ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989186.0 tomwer-1.6.17/src/tomwer.egg-info/SOURCES.txt0000644000175000017500000014404715153325402017715 0ustar00paynopaynoLICENSE MANIFEST.in README.rst pyproject.toml src/orangecontrib/tomwer/__init__.py src/orangecontrib/tomwer/state_summary.py src/orangecontrib/tomwer/orange/__init__.py src/orangecontrib/tomwer/orange/managedprocess.py src/orangecontrib/tomwer/orange/settings.py src/orangecontrib/tomwer/tests/TestAcquisition.py src/orangecontrib/tomwer/tests/__init__.py src/orangecontrib/tomwer/tutorials/EBS_tomo_listener.ows src/orangecontrib/tomwer/tutorials/__init__.py src/orangecontrib/tomwer/tutorials/append_raw_darks_and_flats_frames_to_NXtomos.ows src/orangecontrib/tomwer/tutorials/cast_volume.ows src/orangecontrib/tomwer/tutorials/copy_reduced_darks_and_flats_meth1.ows src/orangecontrib/tomwer/tutorials/copy_reduced_darks_and_flats_meth2.ows src/orangecontrib/tomwer/tutorials/default_cor_search.ows src/orangecontrib/tomwer/tutorials/drac_publication.ows src/orangecontrib/tomwer/tutorials/hello_world_python_script.ows src/orangecontrib/tomwer/tutorials/simple_slice_reconstruction.ows src/orangecontrib/tomwer/tutorials/simple_slice_reconstruction_on_slurm.ows src/orangecontrib/tomwer/tutorials/simple_volume_local_reconstruction.ows src/orangecontrib/tomwer/tutorials/simple_volume_to_slurm_reconstruction.ows src/orangecontrib/tomwer/tutorials/using_saaxis_to_find_cor.ows src/orangecontrib/tomwer/tutorials/volume_casting_on_slurm.ows src/orangecontrib/tomwer/tutorials/id16b/ID16b_full_volume.ows src/orangecontrib/tomwer/tutorials/id16b/ID16b_insitu.ows src/orangecontrib/tomwer/tutorials/id16b/ID16b_normalization.ows src/orangecontrib/tomwer/tutorials/id16b/__init__.py src/orangecontrib/tomwer/widgets/__init__.py src/orangecontrib/tomwer/widgets/utils.py src/orangecontrib/tomwer/widgets/cluster/FutureSupervisorOW.py src/orangecontrib/tomwer/widgets/cluster/SlurmClusterOW.py src/orangecontrib/tomwer/widgets/cluster/__init__.py src/orangecontrib/tomwer/widgets/cluster/icons/slurm.png src/orangecontrib/tomwer/widgets/cluster/icons/slurm.svg src/orangecontrib/tomwer/widgets/cluster/icons/slurmobserver.png src/orangecontrib/tomwer/widgets/cluster/icons/slurmobserver.svg src/orangecontrib/tomwer/widgets/cluster/tests/__init__.py src/orangecontrib/tomwer/widgets/control/AdvancementOW.py src/orangecontrib/tomwer/widgets/control/BlissDataListenerOW.py src/orangecontrib/tomwer/widgets/control/DataDiscoveryOW.py src/orangecontrib/tomwer/widgets/control/DataSelectorOW.py src/orangecontrib/tomwer/widgets/control/DataTransfertOW.py src/orangecontrib/tomwer/widgets/control/DataValidatorOW.py src/orangecontrib/tomwer/widgets/control/DataWatcherOW.py src/orangecontrib/tomwer/widgets/control/EDF2NXTomomillOW.py src/orangecontrib/tomwer/widgets/control/EmailOW.py src/orangecontrib/tomwer/widgets/control/FilterOW.py src/orangecontrib/tomwer/widgets/control/NXTomomillMixIn.py src/orangecontrib/tomwer/widgets/control/NXTomomillOW.py src/orangecontrib/tomwer/widgets/control/NXtomoConcatenate.py src/orangecontrib/tomwer/widgets/control/NotifierOW.py src/orangecontrib/tomwer/widgets/control/ReduceDarkFlatSelectorOW.py src/orangecontrib/tomwer/widgets/control/SingleTomoObjOW.py src/orangecontrib/tomwer/widgets/control/TimerOW.py src/orangecontrib/tomwer/widgets/control/TomoObjSeriesOW.py src/orangecontrib/tomwer/widgets/control/VolumeSelector.py src/orangecontrib/tomwer/widgets/control/_DataListenerBaseClass.py src/orangecontrib/tomwer/widgets/control/__init__.py src/orangecontrib/tomwer/widgets/control/icons/advancement.png src/orangecontrib/tomwer/widgets/control/icons/advancement.svg src/orangecontrib/tomwer/widgets/control/icons/blissdata_listener.png src/orangecontrib/tomwer/widgets/control/icons/blissdata_listener.svg src/orangecontrib/tomwer/widgets/control/icons/concatenate_nxtomos.png src/orangecontrib/tomwer/widgets/control/icons/concatenate_nxtomos.svg src/orangecontrib/tomwer/widgets/control/icons/datadiscover.png src/orangecontrib/tomwer/widgets/control/icons/datadiscover.svg src/orangecontrib/tomwer/widgets/control/icons/datalistener.png src/orangecontrib/tomwer/widgets/control/icons/datawatcher.svg src/orangecontrib/tomwer/widgets/control/icons/edf2nx.png src/orangecontrib/tomwer/widgets/control/icons/edf2nx.svg src/orangecontrib/tomwer/widgets/control/icons/email.png src/orangecontrib/tomwer/widgets/control/icons/email.svg src/orangecontrib/tomwer/widgets/control/icons/esrf.png src/orangecontrib/tomwer/widgets/control/icons/folder-transfert.svg src/orangecontrib/tomwer/widgets/control/icons/image_key_upgrader.png src/orangecontrib/tomwer/widgets/control/icons/namefilter.png src/orangecontrib/tomwer/widgets/control/icons/namefilter.svg src/orangecontrib/tomwer/widgets/control/icons/notification.png src/orangecontrib/tomwer/widgets/control/icons/notification.svg src/orangecontrib/tomwer/widgets/control/icons/nxtomomill.png src/orangecontrib/tomwer/widgets/control/icons/nxtomomill.svg src/orangecontrib/tomwer/widgets/control/icons/progress.svg src/orangecontrib/tomwer/widgets/control/icons/reduced_darkflat_selector.png src/orangecontrib/tomwer/widgets/control/icons/reduced_darkflat_selector.svg src/orangecontrib/tomwer/widgets/control/icons/scanlist.svg src/orangecontrib/tomwer/widgets/control/icons/scanselector.png src/orangecontrib/tomwer/widgets/control/icons/scanselector.svg src/orangecontrib/tomwer/widgets/control/icons/single_tomo_obj.png src/orangecontrib/tomwer/widgets/control/icons/single_tomo_obj.svg src/orangecontrib/tomwer/widgets/control/icons/time.png src/orangecontrib/tomwer/widgets/control/icons/tomoobjseries.png src/orangecontrib/tomwer/widgets/control/icons/tomoobjseries.svg src/orangecontrib/tomwer/widgets/control/icons/tomwer.png src/orangecontrib/tomwer/widgets/control/icons/validator.png src/orangecontrib/tomwer/widgets/control/icons/validatorcrack.png src/orangecontrib/tomwer/widgets/control/icons/volumeselector.png src/orangecontrib/tomwer/widgets/control/icons/volumeselector.svg src/orangecontrib/tomwer/widgets/control/icons/volumesymlink.png src/orangecontrib/tomwer/widgets/control/icons/volumesymlink.svg src/orangecontrib/tomwer/widgets/control/tests/__init__.py src/orangecontrib/tomwer/widgets/dataportal/PublishProcessedDataOW.py src/orangecontrib/tomwer/widgets/dataportal/__init__.py src/orangecontrib/tomwer/widgets/dataportal/icons/publish_processed_data.png src/orangecontrib/tomwer/widgets/dataportal/icons/publish_processed_data.svg src/orangecontrib/tomwer/widgets/debugtools/DatasetGeneratorOW.py src/orangecontrib/tomwer/widgets/debugtools/ObjectInspectorOW.py src/orangecontrib/tomwer/widgets/debugtools/__init__.py src/orangecontrib/tomwer/widgets/debugtools/icons/hammer.png src/orangecontrib/tomwer/widgets/debugtools/icons/hammer.svg src/orangecontrib/tomwer/widgets/debugtools/icons/inspector.png src/orangecontrib/tomwer/widgets/debugtools/icons/inspector.svg src/orangecontrib/tomwer/widgets/debugtools/tests/__init__.py src/orangecontrib/tomwer/widgets/deprecated/DataListenerOW.py src/orangecontrib/tomwer/widgets/deprecated/VolumeViewerOW.py src/orangecontrib/tomwer/widgets/deprecated/__init__.py src/orangecontrib/tomwer/widgets/deprecated/_volume_viewer.py src/orangecontrib/tomwer/widgets/deprecated/icons/datalistener.svg src/orangecontrib/tomwer/widgets/deprecated/icons/deprecated_volume_viewer.png src/orangecontrib/tomwer/widgets/deprecated/icons/deprecated_volume_viewer.svg src/orangecontrib/tomwer/widgets/edit/DarkFlatPatchOW.py src/orangecontrib/tomwer/widgets/edit/ImageKeyEditorOW.py src/orangecontrib/tomwer/widgets/edit/ImageKeyUpgraderOW.py src/orangecontrib/tomwer/widgets/edit/NXtomoEditorOW.py src/orangecontrib/tomwer/widgets/edit/__init__.py src/orangecontrib/tomwer/widgets/edit/icons/image_key_editor.png src/orangecontrib/tomwer/widgets/edit/icons/image_key_editor.svg src/orangecontrib/tomwer/widgets/edit/icons/image_key_upgrader.png src/orangecontrib/tomwer/widgets/edit/icons/image_key_upgrader.svg src/orangecontrib/tomwer/widgets/edit/icons/nx_tomo_editor.png src/orangecontrib/tomwer/widgets/edit/icons/nx_tomo_editor.svg src/orangecontrib/tomwer/widgets/edit/icons/patch_dark_flat.png src/orangecontrib/tomwer/widgets/edit/icons/patch_dark_flat.svg src/orangecontrib/tomwer/widgets/edit/tests/__init__.py src/orangecontrib/tomwer/widgets/icons/deprecated.png src/orangecontrib/tomwer/widgets/icons/tomwer.png src/orangecontrib/tomwer/widgets/icons/tomwer_build.png src/orangecontrib/tomwer/widgets/icons/tomwer_build.svg src/orangecontrib/tomwer/widgets/icons/tomwer_cluster.png src/orangecontrib/tomwer/widgets/icons/tomwer_cluster.svg src/orangecontrib/tomwer/widgets/icons/tomwer_control.png src/orangecontrib/tomwer/widgets/icons/tomwer_control.svg src/orangecontrib/tomwer/widgets/icons/tomwer_data_portal.png src/orangecontrib/tomwer/widgets/icons/tomwer_data_portal.svg src/orangecontrib/tomwer/widgets/icons/tomwer_debug_tools.png src/orangecontrib/tomwer/widgets/icons/tomwer_debug_tools.svg src/orangecontrib/tomwer/widgets/icons/tomwer_edit.png src/orangecontrib/tomwer/widgets/icons/tomwer_edit.svg src/orangecontrib/tomwer/widgets/icons/tomwer_other.png src/orangecontrib/tomwer/widgets/icons/tomwer_other.svg src/orangecontrib/tomwer/widgets/icons/tomwer_stitching.png src/orangecontrib/tomwer/widgets/icons/tomwer_stitching.svg src/orangecontrib/tomwer/widgets/icons/tomwer_visu.png src/orangecontrib/tomwer/widgets/icons/tomwer_visu.svg src/orangecontrib/tomwer/widgets/other/PythonScriptOW.py src/orangecontrib/tomwer/widgets/other/TomoObjsHub.py src/orangecontrib/tomwer/widgets/other/__init__.py src/orangecontrib/tomwer/widgets/other/icons/PythonScript.svg src/orangecontrib/tomwer/widgets/other/icons/hub.png src/orangecontrib/tomwer/widgets/other/icons/hub.svg src/orangecontrib/tomwer/widgets/other/tests/__init__.py src/orangecontrib/tomwer/widgets/reconstruction/AxisOW.py src/orangecontrib/tomwer/widgets/reconstruction/CastNabuVolumeOW.py src/orangecontrib/tomwer/widgets/reconstruction/DarkRefAndCopyOW.py src/orangecontrib/tomwer/widgets/reconstruction/NabuHelicalPrepareWeightsDoubleOW.py src/orangecontrib/tomwer/widgets/reconstruction/NabuOW.py src/orangecontrib/tomwer/widgets/reconstruction/NabuVolumeOW.py src/orangecontrib/tomwer/widgets/reconstruction/SAAxisOW.py src/orangecontrib/tomwer/widgets/reconstruction/SADeltaBetaOW.py src/orangecontrib/tomwer/widgets/reconstruction/SinoNormOW.py src/orangecontrib/tomwer/widgets/reconstruction/__init__.py src/orangecontrib/tomwer/widgets/reconstruction/icons/axis.png src/orangecontrib/tomwer/widgets/reconstruction/icons/axis.svg src/orangecontrib/tomwer/widgets/reconstruction/icons/bricks.png src/orangecontrib/tomwer/widgets/reconstruction/icons/darkref.png src/orangecontrib/tomwer/widgets/reconstruction/icons/darkref.svg src/orangecontrib/tomwer/widgets/reconstruction/icons/delta_beta_range.png src/orangecontrib/tomwer/widgets/reconstruction/icons/delta_beta_range.svg src/orangecontrib/tomwer/widgets/reconstruction/icons/esrf.png src/orangecontrib/tomwer/widgets/reconstruction/icons/nabu_2d.png src/orangecontrib/tomwer/widgets/reconstruction/icons/nabu_2d.svg src/orangecontrib/tomwer/widgets/reconstruction/icons/nabu_3d.png src/orangecontrib/tomwer/widgets/reconstruction/icons/nabu_3d.svg src/orangecontrib/tomwer/widgets/reconstruction/icons/nabu_cast.png src/orangecontrib/tomwer/widgets/reconstruction/icons/nabu_cast.svg src/orangecontrib/tomwer/widgets/reconstruction/icons/nabu_prepare_weights_double.png src/orangecontrib/tomwer/widgets/reconstruction/icons/nabu_prepare_weights_double.svg src/orangecontrib/tomwer/widgets/reconstruction/icons/norm_I.png src/orangecontrib/tomwer/widgets/reconstruction/icons/norm_I.svg src/orangecontrib/tomwer/widgets/reconstruction/icons/refCopy.png src/orangecontrib/tomwer/widgets/reconstruction/icons/refCopy.svg src/orangecontrib/tomwer/widgets/reconstruction/icons/saaxis.png src/orangecontrib/tomwer/widgets/reconstruction/icons/saaxis.svg src/orangecontrib/tomwer/widgets/reconstruction/icons/sadeltabeta.png src/orangecontrib/tomwer/widgets/reconstruction/icons/sadeltabeta.svg src/orangecontrib/tomwer/widgets/reconstruction/icons/tomogui.png src/orangecontrib/tomwer/widgets/reconstruction/icons/tomwer.png src/orangecontrib/tomwer/widgets/reconstruction/tests/__init__.py src/orangecontrib/tomwer/widgets/stitching/StitcherOW.py src/orangecontrib/tomwer/widgets/stitching/ZStitchingConfigOW.py src/orangecontrib/tomwer/widgets/stitching/__init__.py src/orangecontrib/tomwer/widgets/stitching/tests/__init__.py src/orangecontrib/tomwer/widgets/tests/__init__.py src/orangecontrib/tomwer/widgets/visualization/DataViewerOW.py src/orangecontrib/tomwer/widgets/visualization/DiffViewerOW.py src/orangecontrib/tomwer/widgets/visualization/NXtomoMetadataViewerOW.py src/orangecontrib/tomwer/widgets/visualization/RadioStackOW.py src/orangecontrib/tomwer/widgets/visualization/SampleMovedOW.py src/orangecontrib/tomwer/widgets/visualization/SinogramViewerOW.py src/orangecontrib/tomwer/widgets/visualization/SliceStackOW.py src/orangecontrib/tomwer/widgets/visualization/VolumeViewerOW.py src/orangecontrib/tomwer/widgets/visualization/__init__.py src/orangecontrib/tomwer/widgets/visualization/icons/diff.png src/orangecontrib/tomwer/widgets/visualization/icons/diff.svg src/orangecontrib/tomwer/widgets/visualization/icons/esrf.png src/orangecontrib/tomwer/widgets/visualization/icons/eye.png src/orangecontrib/tomwer/widgets/visualization/icons/eyecrack.png src/orangecontrib/tomwer/widgets/visualization/icons/nx_tomo_metadata_viewer.png src/orangecontrib/tomwer/widgets/visualization/icons/nx_tomo_metadata_viewer.svg src/orangecontrib/tomwer/widgets/visualization/icons/radiosstack.png src/orangecontrib/tomwer/widgets/visualization/icons/radiosstack.svg src/orangecontrib/tomwer/widgets/visualization/icons/sampleMoved.png src/orangecontrib/tomwer/widgets/visualization/icons/sampleMoved.svg src/orangecontrib/tomwer/widgets/visualization/icons/sinogramviewer.png src/orangecontrib/tomwer/widgets/visualization/icons/slicesstack.png src/orangecontrib/tomwer/widgets/visualization/icons/slicesstack.svg src/orangecontrib/tomwer/widgets/visualization/icons/tomwer.png src/orangecontrib/tomwer/widgets/visualization/icons/volumeviewer.png src/orangecontrib/tomwer/widgets/visualization/icons/volumeviewer.svg src/orangecontrib/tomwer/widgets/visualization/tests/__init__.py src/tomwer/__init__.py src/tomwer/__main__.py src/tomwer/utils.py src/tomwer/version.py src/tomwer.egg-info/PKG-INFO src/tomwer.egg-info/SOURCES.txt src/tomwer.egg-info/dependency_links.txt src/tomwer.egg-info/entry_points.txt src/tomwer.egg-info/requires.txt src/tomwer.egg-info/top_level.txt src/tomwer/app/__init__.py src/tomwer/app/axis.py src/tomwer/app/canvas.py src/tomwer/app/darkref.py src/tomwer/app/darkrefpatch.py src/tomwer/app/diffframe.py src/tomwer/app/imagekeyeditor.py src/tomwer/app/imagekeyupgrader.py src/tomwer/app/intensitynormalization.py src/tomwer/app/multicor.py src/tomwer/app/multipag.py src/tomwer/app/nabuapp.py src/tomwer/app/nxtomoeditor.py src/tomwer/app/patchrawdarkflat.py src/tomwer/app/radiostack.py src/tomwer/app/reducedarkflat.py src/tomwer/app/rsync.py src/tomwer/app/samplemoved.py src/tomwer/app/scanviewer.py src/tomwer/app/sinogramviewer.py src/tomwer/app/slicestack.py src/tomwer/app/stopdatalistener.py src/tomwer/app/volume_viewer.py src/tomwer/app/ystitching.py src/tomwer/app/zstitching.py src/tomwer/app/canvas_launcher/__init__.py src/tomwer/app/canvas_launcher/config.py src/tomwer/app/canvas_launcher/environ.py src/tomwer/app/canvas_launcher/mainwindow.py src/tomwer/app/canvas_launcher/splash.py src/tomwer/app/canvas_launcher/utils.py src/tomwer/app/canvas_launcher/widgetsscheme.py src/tomwer/app/stitching/__init__.py src/tomwer/app/stitching/common.py src/tomwer/core/__init__.py src/tomwer/core/futureobject.py src/tomwer/core/resourcemanager.py src/tomwer/core/settings.py src/tomwer/core/signal.py src/tomwer/core/tomwer_object.py src/tomwer/core/cluster/__init__.py src/tomwer/core/cluster/cluster.py src/tomwer/core/log/__init__.py src/tomwer/core/log/processlog.py src/tomwer/core/process/__init__.py src/tomwer/core/process/output.py src/tomwer/core/process/task.py src/tomwer/core/process/utils.py src/tomwer/core/process/cluster/__init__.py src/tomwer/core/process/cluster/supervisor.py src/tomwer/core/process/conditions/__init__.py src/tomwer/core/process/conditions/filters.py src/tomwer/core/process/control/__init__.py src/tomwer/core/process/control/datadiscovery.py src/tomwer/core/process/control/emailnotifier.py src/tomwer/core/process/control/nxtomoconcatenate.py src/tomwer/core/process/control/nxtomomill.py src/tomwer/core/process/control/scanlist.py src/tomwer/core/process/control/scanselector.py src/tomwer/core/process/control/scantransfer.py src/tomwer/core/process/control/scanvalidator.py src/tomwer/core/process/control/singletomoobj.py src/tomwer/core/process/control/timer.py src/tomwer/core/process/control/tomoobjseries.py src/tomwer/core/process/control/volumeselector.py src/tomwer/core/process/control/datalistener/__init__.py src/tomwer/core/process/control/datalistener/datalistener.py src/tomwer/core/process/control/datalistener/rpcserver.py src/tomwer/core/process/control/datawatcher/__init__.py src/tomwer/core/process/control/datawatcher/datawatcher.py src/tomwer/core/process/control/datawatcher/datawatcherobserver.py src/tomwer/core/process/control/datawatcher/datawatcherprocess.py src/tomwer/core/process/control/datawatcher/edfdwprocess.py src/tomwer/core/process/control/datawatcher/hdf5dwprocess.py src/tomwer/core/process/control/datawatcher/status.py src/tomwer/core/process/control/tests/__init__.py src/tomwer/core/process/control/tests/test_concatenate_nxtomos.py src/tomwer/core/process/control/tests/test_email.py src/tomwer/core/process/control/tests/test_h52nx_process.py src/tomwer/core/process/drac/__init__.py src/tomwer/core/process/drac/binning.py src/tomwer/core/process/drac/dracbase.py src/tomwer/core/process/drac/gallery.py src/tomwer/core/process/drac/output.py src/tomwer/core/process/drac/processeddataset.py src/tomwer/core/process/drac/publish.py src/tomwer/core/process/drac/rawdataset.py src/tomwer/core/process/drac/tests/test_gallery.py src/tomwer/core/process/drac/tests/test_icat_processed_dataset.py src/tomwer/core/process/drac/tests/test_icat_raw_dataset.py src/tomwer/core/process/edit/__init__.py src/tomwer/core/process/edit/darkflatpatch.py src/tomwer/core/process/edit/imagekeyeditor.py src/tomwer/core/process/edit/nxtomoeditor.py src/tomwer/core/process/edit/tests/test_darkflatpatch.py src/tomwer/core/process/edit/tests/test_imagekey_editor.py src/tomwer/core/process/reconstruction/__init__.py src/tomwer/core/process/reconstruction/output.py src/tomwer/core/process/reconstruction/params_cache.py src/tomwer/core/process/reconstruction/paramsbase.py src/tomwer/core/process/reconstruction/axis/__init__.py src/tomwer/core/process/reconstruction/axis/anglemode.py src/tomwer/core/process/reconstruction/axis/axis.py src/tomwer/core/process/reconstruction/axis/mode.py src/tomwer/core/process/reconstruction/axis/params.py src/tomwer/core/process/reconstruction/axis/projectiontype.py src/tomwer/core/process/reconstruction/axis/side.py src/tomwer/core/process/reconstruction/darkref/__init__.py src/tomwer/core/process/reconstruction/darkref/darkrefs.py src/tomwer/core/process/reconstruction/darkref/darkrefscopy.py src/tomwer/core/process/reconstruction/darkref/params.py src/tomwer/core/process/reconstruction/darkref/settings.py src/tomwer/core/process/reconstruction/nabu/__init__.py src/tomwer/core/process/reconstruction/nabu/castvolume.py src/tomwer/core/process/reconstruction/nabu/helical.py src/tomwer/core/process/reconstruction/nabu/nabucommon.py src/tomwer/core/process/reconstruction/nabu/nabuscores.py src/tomwer/core/process/reconstruction/nabu/nabuslices.py src/tomwer/core/process/reconstruction/nabu/nabuvolume.py src/tomwer/core/process/reconstruction/nabu/plane.py src/tomwer/core/process/reconstruction/nabu/settings.py src/tomwer/core/process/reconstruction/nabu/target.py src/tomwer/core/process/reconstruction/nabu/utils.py src/tomwer/core/process/reconstruction/nabu/test/test_castvolume.py src/tomwer/core/process/reconstruction/nabu/test/test_nabu_utils.py src/tomwer/core/process/reconstruction/nabu/test/test_nabunormalization.py src/tomwer/core/process/reconstruction/normalization/__init__.py src/tomwer/core/process/reconstruction/normalization/normalization.py src/tomwer/core/process/reconstruction/normalization/params.py src/tomwer/core/process/reconstruction/saaxis/__init__.py src/tomwer/core/process/reconstruction/saaxis/params.py src/tomwer/core/process/reconstruction/saaxis/saaxis.py src/tomwer/core/process/reconstruction/sadeltabeta/__init__.py src/tomwer/core/process/reconstruction/sadeltabeta/params.py src/tomwer/core/process/reconstruction/sadeltabeta/sadeltabeta.py src/tomwer/core/process/reconstruction/scores/__init__.py src/tomwer/core/process/reconstruction/scores/params.py src/tomwer/core/process/reconstruction/scores/scores.py src/tomwer/core/process/reconstruction/tests/__init__.py src/tomwer/core/process/reconstruction/tests/test_axis.py src/tomwer/core/process/reconstruction/tests/test_axis_params.py src/tomwer/core/process/reconstruction/tests/test_darkref.py src/tomwer/core/process/reconstruction/tests/test_darkref_copy.py src/tomwer/core/process/reconstruction/tests/test_params_cache.py src/tomwer/core/process/reconstruction/tests/test_paramsbase.py src/tomwer/core/process/reconstruction/tests/test_saaxis.py src/tomwer/core/process/reconstruction/tests/test_sadeltabeta.py src/tomwer/core/process/reconstruction/tests/test_utils.py src/tomwer/core/process/reconstruction/utils/__init__.py src/tomwer/core/process/reconstruction/utils/cor.py src/tomwer/core/process/script/__init__.py src/tomwer/core/process/script/python.py src/tomwer/core/process/script/tests/test_script.py src/tomwer/core/process/stitching/__init__.py src/tomwer/core/process/stitching/metadataholder.py src/tomwer/core/process/stitching/nabustitcher.py src/tomwer/core/process/stitching/tests/test_metadataholder.py src/tomwer/core/process/tests/__init__.py src/tomwer/core/process/tests/test_conditions.py src/tomwer/core/process/tests/test_dark_and_flat.py src/tomwer/core/process/tests/test_data_listener.py src/tomwer/core/process/tests/test_data_transfer.py src/tomwer/core/process/tests/test_data_watcher.py src/tomwer/core/process/tests/test_nabu.py src/tomwer/core/process/tests/test_normalization.py src/tomwer/core/process/tests/test_timer.py src/tomwer/core/process/visualization/__init__.py src/tomwer/core/process/visualization/dataviewer.py src/tomwer/core/process/visualization/diffviewer.py src/tomwer/core/process/visualization/imagestackviewer.py src/tomwer/core/process/visualization/radiostack.py src/tomwer/core/process/visualization/samplemoved.py src/tomwer/core/process/visualization/sinogramviewer.py src/tomwer/core/process/visualization/slicestack.py src/tomwer/core/process/visualization/volumeviewer.py src/tomwer/core/process/visualization/tests/test_data_viewer.py src/tomwer/core/process/visualization/tests/test_diff_viewer.py src/tomwer/core/process/visualization/tests/test_image_stack_viewer.py src/tomwer/core/process/visualization/tests/test_radio_stack.py src/tomwer/core/process/visualization/tests/test_sample_moved.py src/tomwer/core/process/visualization/tests/test_sinogram_viewer.py src/tomwer/core/process/visualization/tests/test_slice_stack.py src/tomwer/core/scan/__init__.py src/tomwer/core/scan/blissscan.py src/tomwer/core/scan/edfscan.py src/tomwer/core/scan/futurescan.py src/tomwer/core/scan/hdf5scan.py src/tomwer/core/scan/helicalmetadata.py src/tomwer/core/scan/nxtomoscan.py src/tomwer/core/scan/scanbase.py src/tomwer/core/scan/scanfactory.py src/tomwer/core/scan/scantype.py src/tomwer/core/scan/tests/__init__.py src/tomwer/core/scan/tests/test_edf.py src/tomwer/core/scan/tests/test_future_scan.py src/tomwer/core/scan/tests/test_nxtomoscan.py src/tomwer/core/scan/tests/test_scan.py src/tomwer/core/tests/__init__.py src/tomwer/core/tests/test_scanutils.py src/tomwer/core/tests/test_utils.py src/tomwer/core/utils/__init__.py src/tomwer/core/utils/char.py src/tomwer/core/utils/deprecation.py src/tomwer/core/utils/dictutils.py src/tomwer/core/utils/ftseriesutils.py src/tomwer/core/utils/gpu.py src/tomwer/core/utils/image.py src/tomwer/core/utils/lbsram.py src/tomwer/core/utils/logconfig.py src/tomwer/core/utils/normalization.py src/tomwer/core/utils/nxtomoutils.py src/tomwer/core/utils/process.py src/tomwer/core/utils/resource.py src/tomwer/core/utils/scanutils.py src/tomwer/core/utils/slurm.py src/tomwer/core/utils/spec.py src/tomwer/core/utils/threads.py src/tomwer/core/utils/time.py src/tomwer/core/utils/volumeutils.py src/tomwer/core/utils/tests/__init__.py src/tomwer/core/utils/tests/test_image.py src/tomwer/core/utils/tests/test_nxtomo.py src/tomwer/core/utils/tests/test_scan_utils.py src/tomwer/core/utils/tests/test_time.py src/tomwer/core/volume/__init__.py src/tomwer/core/volume/edfvolume.py src/tomwer/core/volume/hdf5volume.py src/tomwer/core/volume/jp2kvolume.py src/tomwer/core/volume/rawvolume.py src/tomwer/core/volume/tiffvolume.py src/tomwer/core/volume/volumebase.py src/tomwer/core/volume/volumefactory.py src/tomwer/core/volume/tests/test_volumes.py src/tomwer/gui/__init__.py src/tomwer/gui/fonts.py src/tomwer/gui/icons.py src/tomwer/gui/illustrations.py src/tomwer/gui/imagefromfile.py src/tomwer/gui/metadataloader.py src/tomwer/gui/qconfigfile.py src/tomwer/gui/qlefilesystem.py src/tomwer/gui/settings.py src/tomwer/gui/stackplot.py src/tomwer/gui/stacks.py src/tomwer/gui/cluster/__init__.py src/tomwer/gui/cluster/slurm.py src/tomwer/gui/cluster/supervisor.py src/tomwer/gui/cluster/tests/__init__.py src/tomwer/gui/cluster/tests/test_cluster.py src/tomwer/gui/cluster/tests/test_supervisor.py src/tomwer/gui/conditions/__init__.py src/tomwer/gui/conditions/filter.py src/tomwer/gui/configuration/__init__.py src/tomwer/gui/configuration/action.py src/tomwer/gui/configuration/level.py src/tomwer/gui/control/__init__.py src/tomwer/gui/control/_host.py src/tomwer/gui/control/actions.py src/tomwer/gui/control/datadiscovery.py src/tomwer/gui/control/datalist.py src/tomwer/gui/control/datalistener.py src/tomwer/gui/control/datareacheractions.py src/tomwer/gui/control/datatransfert.py src/tomwer/gui/control/datavalidator.py src/tomwer/gui/control/history.py src/tomwer/gui/control/nxtomomill.py src/tomwer/gui/control/observations.py src/tomwer/gui/control/reducedarkflatselector.py src/tomwer/gui/control/scanselectorwidget.py src/tomwer/gui/control/selectorwidgetbase.py src/tomwer/gui/control/singletomoobj.py src/tomwer/gui/control/tomoobjdisplaymode.py src/tomwer/gui/control/volumeselectorwidget.py src/tomwer/gui/control/datawatcher/__init__.py src/tomwer/gui/control/datawatcher/configuration.py src/tomwer/gui/control/datawatcher/controlwidget.py src/tomwer/gui/control/datawatcher/datawatcher.py src/tomwer/gui/control/datawatcher/datawatcherobserver.py src/tomwer/gui/control/series/__init__.py src/tomwer/gui/control/series/nxtomoconcatenate.py src/tomwer/gui/control/series/seriescreator.py src/tomwer/gui/control/series/serieswaiter.py src/tomwer/gui/control/series/test/test_creator.py src/tomwer/gui/control/series/test/test_nxtomo_concatenate.py src/tomwer/gui/control/tests/__init__.py src/tomwer/gui/control/tests/test_datadiscovery.py src/tomwer/gui/control/tests/test_datalist.py src/tomwer/gui/control/tests/test_datalistener.py src/tomwer/gui/control/tests/test_datavalidator.py src/tomwer/gui/control/tests/test_inputwidget.py src/tomwer/gui/control/tests/test_reducedarkflat_selector.py src/tomwer/gui/control/tests/test_scan_observations.py src/tomwer/gui/control/tests/test_scanselector.py src/tomwer/gui/control/tests/test_scanvalidator.py src/tomwer/gui/control/tests/test_single_tomo_obj.py src/tomwer/gui/control/tests/test_volume_dialog.py src/tomwer/gui/control/tests/test_volumeselector.py src/tomwer/gui/dataportal/__init__.py src/tomwer/gui/dataportal/createscreenshots.py src/tomwer/gui/dataportal/gallery.py src/tomwer/gui/dataportal/outputformat.py src/tomwer/gui/dataportal/publish.py src/tomwer/gui/dataportal/tests/test_create_screenshots_gui.py src/tomwer/gui/dataportal/tests/test_gallery_gui.py src/tomwer/gui/debugtools/__init__.py src/tomwer/gui/debugtools/datasetgenerator.py src/tomwer/gui/debugtools/objectinspector.py src/tomwer/gui/dialog/QDataDialog.py src/tomwer/gui/dialog/QVolumeDialog.py src/tomwer/gui/dialog/_PortOccupyDialog.py src/tomwer/gui/dialog/__init__.py src/tomwer/gui/edit/__init__.py src/tomwer/gui/edit/dkrfpatch.py src/tomwer/gui/edit/imagekeyeditor.py src/tomwer/gui/edit/nxtomoeditor.py src/tomwer/gui/edit/nxtomowarmer.py src/tomwer/gui/edit/tests/__init__.py src/tomwer/gui/edit/tests/test_dkrf_patch.py src/tomwer/gui/edit/tests/test_image_key_editor.py src/tomwer/gui/edit/tests/test_nx_editor.py src/tomwer/gui/reconstruction/__init__.py src/tomwer/gui/reconstruction/sacommon.py src/tomwer/gui/reconstruction/axis/AxisMainWindow.py src/tomwer/gui/reconstruction/axis/AxisOptionsWidget.py src/tomwer/gui/reconstruction/axis/AxisSettingsWidget.py src/tomwer/gui/reconstruction/axis/AxisWidget.py src/tomwer/gui/reconstruction/axis/CalculationWidget.py src/tomwer/gui/reconstruction/axis/CompareImages.py src/tomwer/gui/reconstruction/axis/ControlWidget.py src/tomwer/gui/reconstruction/axis/EstimatedCORWidget.py src/tomwer/gui/reconstruction/axis/EstimatedCorComboBox.py src/tomwer/gui/reconstruction/axis/InputWidget.py src/tomwer/gui/reconstruction/axis/ManualFramesSelection.py src/tomwer/gui/reconstruction/axis/__init__.py src/tomwer/gui/reconstruction/darkref/__init__.py src/tomwer/gui/reconstruction/darkref/darkrefcopywidget.py src/tomwer/gui/reconstruction/darkref/darkrefwidget.py src/tomwer/gui/reconstruction/nabu/__init__.py src/tomwer/gui/reconstruction/nabu/castvolume.py src/tomwer/gui/reconstruction/nabu/check.py src/tomwer/gui/reconstruction/nabu/helical.py src/tomwer/gui/reconstruction/nabu/nabuflow.py src/tomwer/gui/reconstruction/nabu/platform.py src/tomwer/gui/reconstruction/nabu/slices.py src/tomwer/gui/reconstruction/nabu/slurm.py src/tomwer/gui/reconstruction/nabu/volume.py src/tomwer/gui/reconstruction/nabu/nabuconfig/__init__.py src/tomwer/gui/reconstruction/nabu/nabuconfig/base.py src/tomwer/gui/reconstruction/nabu/nabuconfig/ctf.py src/tomwer/gui/reconstruction/nabu/nabuconfig/nabuconfig.py src/tomwer/gui/reconstruction/nabu/nabuconfig/output.py src/tomwer/gui/reconstruction/nabu/nabuconfig/phase.py src/tomwer/gui/reconstruction/nabu/nabuconfig/preprocessing.py src/tomwer/gui/reconstruction/nabu/nabuconfig/reconstruction.py src/tomwer/gui/reconstruction/nabu/nabuconfig/tests/__init__.py src/tomwer/gui/reconstruction/nabu/nabuconfig/tests/test_NabuConfiguration.py src/tomwer/gui/reconstruction/nabu/test/test_cast_volume.py src/tomwer/gui/reconstruction/nabu/test/test_check.py src/tomwer/gui/reconstruction/nabu/test/test_ctf.py src/tomwer/gui/reconstruction/nabu/test/test_helical.py src/tomwer/gui/reconstruction/nabu/test/test_nabu_preprocessing.py src/tomwer/gui/reconstruction/normalization/__init__.py src/tomwer/gui/reconstruction/normalization/intensity.py src/tomwer/gui/reconstruction/normalization/test/test_intensity.py src/tomwer/gui/reconstruction/saaxis/__init__.py src/tomwer/gui/reconstruction/saaxis/corrangeselector.py src/tomwer/gui/reconstruction/saaxis/dimensionwidget.py src/tomwer/gui/reconstruction/saaxis/saaxis.py src/tomwer/gui/reconstruction/saaxis/sliceselector.py src/tomwer/gui/reconstruction/sadeltabeta/__init__.py src/tomwer/gui/reconstruction/sadeltabeta/saadeltabeta.py src/tomwer/gui/reconstruction/scores/__init__.py src/tomwer/gui/reconstruction/scores/control.py src/tomwer/gui/reconstruction/scores/scoreplot.py src/tomwer/gui/reconstruction/tests/__init__.py src/tomwer/gui/reconstruction/tests/test_axis.py src/tomwer/gui/reconstruction/tests/test_nabu.py src/tomwer/gui/reconstruction/tests/test_saaxis.py src/tomwer/gui/reconstruction/tests/test_sadeltabeta.py src/tomwer/gui/samplemoved/__init__.py src/tomwer/gui/samplemoved/selectiontable.py src/tomwer/gui/stitching/SingleAxisStitchingWidget.py src/tomwer/gui/stitching/StitchingOptionsWidget.py src/tomwer/gui/stitching/StitchingWindow.py src/tomwer/gui/stitching/__init__.py src/tomwer/gui/stitching/action.py src/tomwer/gui/stitching/alignment.py src/tomwer/gui/stitching/axisorderedlist.py src/tomwer/gui/stitching/metadataholder.py src/tomwer/gui/stitching/normalization.py src/tomwer/gui/stitching/preview.py src/tomwer/gui/stitching/singleaxis.py src/tomwer/gui/stitching/stitchandbackground.py src/tomwer/gui/stitching/stitching_preview.py src/tomwer/gui/stitching/stitching_raw.py src/tomwer/gui/stitching/utils.py src/tomwer/gui/stitching/config/_QSpinBox.py src/tomwer/gui/stitching/config/__init__.py src/tomwer/gui/stitching/config/_linkInfo.py src/tomwer/gui/stitching/config/axisparams.py src/tomwer/gui/stitching/config/output.py src/tomwer/gui/stitching/config/positionoveraxis.py src/tomwer/gui/stitching/config/stitchingstrategies.py src/tomwer/gui/stitching/config/tomoobjdetails.py src/tomwer/gui/stitching/config/tests/test_axisparams.py src/tomwer/gui/stitching/tests/test_ZStitchingWindow.py src/tomwer/gui/stitching/tests/test_axis_ordered_list.py src/tomwer/gui/stitching/tests/test_normalization.py src/tomwer/gui/stitching/tests/test_preview.py src/tomwer/gui/stitching/tests/test_stitching_raw.py src/tomwer/gui/stitching/tests/utils.py src/tomwer/gui/stitching/z_stitching/__init__.py src/tomwer/gui/stitching/z_stitching/fineestimation.py src/tomwer/gui/stitching/z_stitching/tests/test_fine_estimation.py src/tomwer/gui/stitching/z_stitching/tests/test_raw_estimation.py src/tomwer/gui/stitching/z_stitching/tests/test_stitching_window.py src/tomwer/gui/tests/__init__.py src/tomwer/gui/tests/test_axis_gui.py src/tomwer/gui/tests/test_qfolder_dialog.py src/tomwer/gui/utils/RangeWidget.py src/tomwer/gui/utils/__init__.py src/tomwer/gui/utils/buttons.py src/tomwer/gui/utils/completer.py src/tomwer/gui/utils/flow.py src/tomwer/gui/utils/gpu.py src/tomwer/gui/utils/host_editor.py src/tomwer/gui/utils/illustrations.py src/tomwer/gui/utils/inputwidget.py src/tomwer/gui/utils/loadingmode.py src/tomwer/gui/utils/qt_utils.py src/tomwer/gui/utils/sandboxes.py src/tomwer/gui/utils/scandescription.py src/tomwer/gui/utils/scrollarea.py src/tomwer/gui/utils/slider.py src/tomwer/gui/utils/splashscreen.py src/tomwer/gui/utils/step.py src/tomwer/gui/utils/unitsystem.py src/tomwer/gui/utils/utils.py src/tomwer/gui/utils/vignettes.py src/tomwer/gui/utils/waiterthread.py src/tomwer/gui/utils/lineselector/__init__.py src/tomwer/gui/utils/lineselector/lineselector.py src/tomwer/gui/utils/tests/test_completer.py src/tomwer/gui/utils/tests/test_host_editor.py src/tomwer/gui/utils/tests/test_line_selector.py src/tomwer/gui/utils/tests/test_splashscreen.py src/tomwer/gui/utils/tests/test_vignettes.py src/tomwer/gui/visualization/TomoPlot2D.py src/tomwer/gui/visualization/__init__.py src/tomwer/gui/visualization/dataviewer.py src/tomwer/gui/visualization/fullscreenplot.py src/tomwer/gui/visualization/imagestack.py src/tomwer/gui/visualization/nxtomometadata.py src/tomwer/gui/visualization/reconstructionparameters.py src/tomwer/gui/visualization/scanoverview.py src/tomwer/gui/visualization/sinogramviewer.py src/tomwer/gui/visualization/tomoobjoverview.py src/tomwer/gui/visualization/volumeoverview.py src/tomwer/gui/visualization/diffviewer/__init__.py src/tomwer/gui/visualization/diffviewer/diffviewer.py src/tomwer/gui/visualization/diffviewer/shiftwidget.py src/tomwer/gui/visualization/test/__init__.py src/tomwer/gui/visualization/test/test_dataviewer.py src/tomwer/gui/visualization/test/test_diffviewer.py src/tomwer/gui/visualization/test/test_nx_tomo_metadata_viewer.py src/tomwer/gui/visualization/test/test_reconstruction_parameters.py src/tomwer/gui/visualization/test/test_sinogramviewer.py src/tomwer/gui/visualization/test/test_stacks.py src/tomwer/gui/visualization/volume_viewer/CoordinateSystemOverlay.py src/tomwer/gui/visualization/volume_viewer/GeometryOrMetadataWidget.py src/tomwer/gui/visualization/volume_viewer/VolumeViewerWidget.py src/tomwer/gui/visualization/volume_viewer/VolumeViewerWindow.py src/tomwer/gui/visualization/volume_viewer/_CrossHairs.py src/tomwer/gui/visualization/volume_viewer/_HorizontalSliderWithBrowser.py src/tomwer/gui/visualization/volume_viewer/_ProcessingOverlay.py src/tomwer/gui/visualization/volume_viewer/_ReconstructionParameters.py src/tomwer/gui/visualization/volume_viewer/_SliceLoader.py src/tomwer/gui/visualization/volume_viewer/_TomoPlot2DSlices.py src/tomwer/gui/visualization/volume_viewer/__init__.py src/tomwer/gui/visualization/volume_viewer/toolbar.py src/tomwer/gui/visualization/volume_viewer/actions/_ColorBarAction.py src/tomwer/gui/visualization/volume_viewer/actions/_ShowAxesAction.py src/tomwer/gui/visualization/volume_viewer/actions/_ShowCoordinateSystemAction.py src/tomwer/gui/visualization/volume_viewer/actions/_ShowCoordinateSystemLabelAction.py src/tomwer/gui/visualization/volume_viewer/actions/_ShowCrosshairsAction.py src/tomwer/gui/visualization/volume_viewer/actions/_ShowPlotToolBarAction.py src/tomwer/gui/visualization/volume_viewer/actions/__init__.py src/tomwer/gui/visualization/volume_viewer/tests/__init__.py src/tomwer/gui/visualization/volume_viewer/tests/test_VolumeViewer.py src/tomwer/io/__init__.py src/tomwer/io/utils/__init__.py src/tomwer/io/utils/h5pyutils.py src/tomwer/io/utils/raw_and_processed_data.py src/tomwer/io/utils/tomoobj.py src/tomwer/io/utils/utils.py src/tomwer/io/utils/test/test_raw_and_processed_data.py src/tomwer/io/utils/test/test_utils.py src/tomwer/model/volume_viewer.py src/tomwer/resources/__init__.py src/tomwer/resources/gui/icons/3D_coordinate_system_XY.png src/tomwer/resources/gui/icons/3D_coordinate_system_XZ.png src/tomwer/resources/gui/icons/3D_coordinate_system_YZ.png src/tomwer/resources/gui/icons/Imagej_icon.png src/tomwer/resources/gui/icons/a.png src/tomwer/resources/gui/icons/a.svg src/tomwer/resources/gui/icons/add.png src/tomwer/resources/gui/icons/add.svg src/tomwer/resources/gui/icons/advanced_user.png src/tomwer/resources/gui/icons/advanced_user.svg src/tomwer/resources/gui/icons/axis.png src/tomwer/resources/gui/icons/axis.svg src/tomwer/resources/gui/icons/background.png src/tomwer/resources/gui/icons/background.svg src/tomwer/resources/gui/icons/basic_user.png src/tomwer/resources/gui/icons/basic_user.svg src/tomwer/resources/gui/icons/cfg_file_active.png src/tomwer/resources/gui/icons/cfg_file_active.svg src/tomwer/resources/gui/icons/cfg_file_inactive.png src/tomwer/resources/gui/icons/cfg_file_inactive.svg src/tomwer/resources/gui/icons/compare_mode_a_minus_b.png src/tomwer/resources/gui/icons/compare_mode_a_minus_b.svg src/tomwer/resources/gui/icons/compose.png src/tomwer/resources/gui/icons/compose.svg src/tomwer/resources/gui/icons/crosshairs.png src/tomwer/resources/gui/icons/crosshairs.svg src/tomwer/resources/gui/icons/datalistener_activate.png src/tomwer/resources/gui/icons/datalistener_activate.svg src/tomwer/resources/gui/icons/datalistener_deactivate.png src/tomwer/resources/gui/icons/datalistener_deactivate.svg src/tomwer/resources/gui/icons/delta_beta.png src/tomwer/resources/gui/icons/delta_beta.svg src/tomwer/resources/gui/icons/edit_downstream.svg src/tomwer/resources/gui/icons/edit_upstream.svg src/tomwer/resources/gui/icons/exit.png src/tomwer/resources/gui/icons/exit.svg src/tomwer/resources/gui/icons/extend_3D_coordinate_system_XY.png src/tomwer/resources/gui/icons/extend_3D_coordinate_system_XZ.png src/tomwer/resources/gui/icons/extend_3D_coordinate_system_YZ.png src/tomwer/resources/gui/icons/free_edition.svg src/tomwer/resources/gui/icons/full_screen.png src/tomwer/resources/gui/icons/full_screen.svg src/tomwer/resources/gui/icons/hammer.png src/tomwer/resources/gui/icons/hammer.svg src/tomwer/resources/gui/icons/health.png src/tomwer/resources/gui/icons/health.svg src/tomwer/resources/gui/icons/hide_3D_coordinate_system.png src/tomwer/resources/gui/icons/high_speed.png src/tomwer/resources/gui/icons/high_speed.svg src/tomwer/resources/gui/icons/history.png src/tomwer/resources/gui/icons/hourglass.npy src/tomwer/resources/gui/icons/icat_gallery_opts.png src/tomwer/resources/gui/icons/icat_gallery_opts.svg src/tomwer/resources/gui/icons/imageNotFound.npy src/tomwer/resources/gui/icons/information.png src/tomwer/resources/gui/icons/information.svg src/tomwer/resources/gui/icons/input.png src/tomwer/resources/gui/icons/input.svg src/tomwer/resources/gui/icons/invisible.png src/tomwer/resources/gui/icons/invisible.svg src/tomwer/resources/gui/icons/lineselection.png src/tomwer/resources/gui/icons/lineselection.svg src/tomwer/resources/gui/icons/link-slash.svg src/tomwer/resources/gui/icons/link.svg src/tomwer/resources/gui/icons/list_selection.png src/tomwer/resources/gui/icons/list_selection.svg src/tomwer/resources/gui/icons/locked.png src/tomwer/resources/gui/icons/locked.svg src/tomwer/resources/gui/icons/log.png src/tomwer/resources/gui/icons/log.svg src/tomwer/resources/gui/icons/loop.png src/tomwer/resources/gui/icons/low_speed.png src/tomwer/resources/gui/icons/low_speed.svg src/tomwer/resources/gui/icons/lr_mirroring.png src/tomwer/resources/gui/icons/lr_mirroring.svg src/tomwer/resources/gui/icons/medium_low_speed.png src/tomwer/resources/gui/icons/medium_low_speed.svg src/tomwer/resources/gui/icons/minimalistic_user.png src/tomwer/resources/gui/icons/minimalistic_user.svg src/tomwer/resources/gui/icons/multi-document-save.png src/tomwer/resources/gui/icons/multi-document-save.svg src/tomwer/resources/gui/icons/nabu.png src/tomwer/resources/gui/icons/nabu.svg src/tomwer/resources/gui/icons/output.png src/tomwer/resources/gui/icons/output.svg src/tomwer/resources/gui/icons/parameters.png src/tomwer/resources/gui/icons/parameters.svg src/tomwer/resources/gui/icons/plot-xleft.png src/tomwer/resources/gui/icons/plot-xleft.svg src/tomwer/resources/gui/icons/plot-xright.png src/tomwer/resources/gui/icons/plot-xright.svg src/tomwer/resources/gui/icons/range_selection.png src/tomwer/resources/gui/icons/range_selection.svg src/tomwer/resources/gui/icons/red_dot.svg src/tomwer/resources/gui/icons/reset_3D_coordinate_system.png src/tomwer/resources/gui/icons/results.png src/tomwer/resources/gui/icons/results.svg src/tomwer/resources/gui/icons/rm.png src/tomwer/resources/gui/icons/rm.svg src/tomwer/resources/gui/icons/roman_four.png src/tomwer/resources/gui/icons/roman_four.svg src/tomwer/resources/gui/icons/roman_one.png src/tomwer/resources/gui/icons/roman_one.svg src/tomwer/resources/gui/icons/roman_three.png src/tomwer/resources/gui/icons/roman_three.svg src/tomwer/resources/gui/icons/roman_two.png src/tomwer/resources/gui/icons/roman_two.svg src/tomwer/resources/gui/icons/ruler.png src/tomwer/resources/gui/icons/ruler.svg src/tomwer/resources/gui/icons/search.png src/tomwer/resources/gui/icons/search.svg src/tomwer/resources/gui/icons/short_description.png src/tomwer/resources/gui/icons/short_description.svg src/tomwer/resources/gui/icons/show_3D_coordinate_system.png src/tomwer/resources/gui/icons/show_coordinate_system_label.svg src/tomwer/resources/gui/icons/show_plot_toolbars.svg src/tomwer/resources/gui/icons/single_selection.png src/tomwer/resources/gui/icons/single_selection.svg src/tomwer/resources/gui/icons/sinogram.png src/tomwer/resources/gui/icons/slurm.svg src/tomwer/resources/gui/icons/slurm_active.png src/tomwer/resources/gui/icons/slurm_active.svg src/tomwer/resources/gui/icons/slurm_deactive.png src/tomwer/resources/gui/icons/slurm_deactive.svg src/tomwer/resources/gui/icons/stitching_modeRaw.png src/tomwer/resources/gui/icons/stitching_modeRaw.svg src/tomwer/resources/gui/icons/stitching_modeRefine.png src/tomwer/resources/gui/icons/stitching_modeRefine.svg src/tomwer/resources/gui/icons/switch.png src/tomwer/resources/gui/icons/tomwer.png src/tomwer/resources/gui/icons/tomwer_large.png src/tomwer/resources/gui/icons/ud_mirroring.png src/tomwer/resources/gui/icons/ud_mirroring.svg src/tomwer/resources/gui/icons/unlocked.png src/tomwer/resources/gui/icons/unlocked.svg src/tomwer/resources/gui/icons/unsharp_mask.png src/tomwer/resources/gui/icons/update_stitching_preview.svg src/tomwer/resources/gui/icons/url.png src/tomwer/resources/gui/icons/url.svg src/tomwer/resources/gui/icons/vignettes.png src/tomwer/resources/gui/icons/vignettes.svg src/tomwer/resources/gui/icons/visible.png src/tomwer/resources/gui/icons/visible.svg src/tomwer/resources/gui/icons/warning.png src/tomwer/resources/gui/icons/warning.svg src/tomwer/resources/gui/illustrations/3D_coordinate_system.png src/tomwer/resources/gui/illustrations/3D_coordinate_system.svg src/tomwer/resources/gui/illustrations/ctf_z1.png src/tomwer/resources/gui/illustrations/ctf_z1.svg src/tomwer/resources/gui/illustrations/flow_down.png src/tomwer/resources/gui/illustrations/flow_down.svg src/tomwer/resources/gui/illustrations/flow_right.png src/tomwer/resources/gui/illustrations/flow_right.svg src/tomwer/resources/gui/illustrations/no_rot.svg src/tomwer/synctools/__init__.py src/tomwer/synctools/axis.py src/tomwer/synctools/darkref.py src/tomwer/synctools/datatransfert.py src/tomwer/synctools/imageloaderthread.py src/tomwer/synctools/rsyncmanager.py src/tomwer/synctools/saaxis.py src/tomwer/synctools/sadeltabeta.py src/tomwer/synctools/bliss_sync/_QThreadListenerBase.py src/tomwer/synctools/bliss_sync/__init__.py src/tomwer/synctools/bliss_sync/blissdata_listener.py src/tomwer/synctools/bliss_sync/datalistener.py src/tomwer/synctools/stacks/__init__.py src/tomwer/synctools/stacks/processingstack.py src/tomwer/synctools/stacks/control/__init__.py src/tomwer/synctools/stacks/control/datalistener.py src/tomwer/synctools/stacks/reconstruction/__init__.py src/tomwer/synctools/stacks/reconstruction/axis.py src/tomwer/synctools/stacks/reconstruction/castvolume.py src/tomwer/synctools/stacks/reconstruction/dkrefcopy.py src/tomwer/synctools/stacks/reconstruction/nabu.py src/tomwer/synctools/stacks/reconstruction/normalization.py src/tomwer/synctools/stacks/reconstruction/saaxis.py src/tomwer/synctools/stacks/reconstruction/sadeltabeta.py src/tomwer/synctools/tests/__init__.py src/tomwer/synctools/tests/test_darkRefs.py src/tomwer/synctools/tests/test_foldertransfer.py src/tomwer/synctools/utils/__init__.py src/tomwer/synctools/utils/scanstages.py src/tomwer/tasks/__init__.py src/tomwer/tasks/script/__init__.py src/tomwer/tasks/script/python.py src/tomwer/tasks/tests/test_script.py src/tomwer/tasks/visualization/volume_viewer.py src/tomwer/tests/__init__.py src/tomwer/tests/conftest.py src/tomwer/tests/datasets.py src/tomwer/tests/test_scripts.py src/tomwer/tests/test_utils.py src/tomwer/tests/utils.py src/tomwer/tests/app/test_stitching.py src/tomwer/tests/orangecontrib/tomwer/widgets/test_conditions.py src/tomwer/tests/orangecontrib/tomwer/widgets/test_darkref.py src/tomwer/tests/orangecontrib/tomwer/widgets/test_foldertransfert.py src/tomwer/tests/orangecontrib/tomwer/widgets/cluster/tests/test_future_supervisorow.py src/tomwer/tests/orangecontrib/tomwer/widgets/cluster/tests/test_slurm_clusterow.py src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_advancement.py src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_data_validator.py src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_datadiscovery.py src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_datalistener.py src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_dataselector.py src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_datawatcher.py src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_emailow.py src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_notifier.py src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_nxtomo_concatenate_ow.py src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_nxtomomill.py src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_reduce_dark_flat_selector.py src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_singletomoobj.py src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_timerow.py src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_tomoobj_series.py src/tomwer/tests/orangecontrib/tomwer/widgets/control/tests/test_volume_selector.py src/tomwer/tests/orangecontrib/tomwer/widgets/debugtools/tests/test_dataset_generator.py src/tomwer/tests/orangecontrib/tomwer/widgets/debugtools/tests/test_object_inspector.py src/tomwer/tests/orangecontrib/tomwer/widgets/edit/tests/test_dark_flat_patch.py src/tomwer/tests/orangecontrib/tomwer/widgets/edit/tests/test_image_key_editor.py src/tomwer/tests/orangecontrib/tomwer/widgets/edit/tests/test_image_key_upgrader.py src/tomwer/tests/orangecontrib/tomwer/widgets/edit/tests/test_nxtomo_editor.py src/tomwer/tests/orangecontrib/tomwer/widgets/other/tests/test_pythonscript.py src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_axis.py src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_cast_volumeow.py src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_dark_refs_widget.py src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_delta_beta_selector.py src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_i_norm.py src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_nabu_helical_prepare_weights_double.py src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_nabu_volume.py src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_nabu_widget.py src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_sa_delta_beta.py src/tomwer/tests/orangecontrib/tomwer/widgets/reconstruction/tests/test_saaxis.py src/tomwer/tests/orangecontrib/tomwer/widgets/stitching/tests/test_zstitching.py src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_dataviewerow.py src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_diffviewerow.py src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_nxtomo_metadata_viewer.py src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_radio_stackow.py src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_sample_movedow.py src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_sinogram_viewerow.py src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_slice_stackow.py src/tomwer/tests/orangecontrib/tomwer/widgets/visualization/tests/test_volume_viewerow.py src/tomwer/tests/tasks/visualization/test_volume_viewer.py src/tomwer/tests/test_ewoks/test_conversion.py src/tomwer/tests/test_ewoks/test_single_node_execution.py src/tomwer/tests/test_ewoks/test_workflows.py src/tomwer/third_part/FrameBrowser.py src/tomwer/third_part/OverlayMixIn.py src/tomwer/third_part/qitem_model_resetter.py././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989186.0 tomwer-1.6.17/src/tomwer.egg-info/dependency_links.txt0000644000175000017500000000000115153325402022065 0ustar00paynopayno ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989186.0 tomwer-1.6.17/src/tomwer.egg-info/entry_points.txt0000644000175000017500000000076315153325402021323 0ustar00paynopayno[console_scripts] tomwer = tomwer.__main__:main [ewoks.tasks.class] tomwer.tasks.*.* = tomwer [orange.canvas.help] html-index = orangecontrib.tomwer.widgets:WIDGET_HELP_PATH [orange.widgets] tomwer = orangecontrib.tomwer.widgets [orange.widgets.tutorials] tomo_tutorials = orangecontrib.tomwer.tutorials tomo_tutorials_id16b = orangecontrib.tomwer.tutorials.id16b [orange3.addon] tomwer-add-on = orangecontrib.tomwer:addon [orangecanvas.examples] tomo_examples = orangecontrib.tomwer.examples ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989186.0 tomwer-1.6.17/src/tomwer.egg-info/requires.txt0000644000175000017500000000200615153325402020415 0ustar00paynopaynonumpy setuptools<81 psutil silx[full]>=2.1.1 tomoscan>=2.2.0a6 nxtomo>2.0.0dev2 nxtomomill>=2.0.0dev0 processview>=1.5.0 ewoks>=0.1.1 ewokscore<2.0,>=1.5 sluurp>=0.4.1 packaging pint tqdm platformdirs [:python_version < "3.10"] eval_type_backport [dev] tomwer[full] tomwer[dev_spec] [dev_no_cuda] tomwer[full_no_cuda] tomwer[dev_spec] [dev_spec] black flake8 timeout-decorator pyopencl [doc] tomwer[full_no_cuda] Sphinx>=4.0.0 nbsphinx pandoc jupyterlab pydata_sphinx_theme sphinx-design sphinx-autodoc-typehints sphinxcontrib-programoutput sphinxcontrib-youtube myst-parser nb_extension_tagstyler [full] tomwer[full_base] nabu[full]>=2024.2.0 pycuda<2024.1.1 scikit-cuda [full_base] orange-canvas-core orange-widget-base ewoks[orange]>=0.1.1 ewoksorange<2.0,>=0.7.0rc0 fabio h5py>=3 lxml werkzeug json-rpc scipy Pillow resource tifffile hdf5plugin pyicat_plus ewoksnotify[full]<0.2 rsyncmanager blissdata [full_no_cuda] tomwer[full_base] nabu>=2024.2.0 [test] tomwer[full_no_cuda] pytest-asyncio tomoscan[test]>=2.2.0a6 ././@PaxHeader0000000000000000000000000000002600000000000010213 xustar0022 mtime=1772989186.0 tomwer-1.6.17/src/tomwer.egg-info/top_level.txt0000644000175000017500000000002515153325402020546 0ustar00paynopaynoorangecontrib tomwer