pax_global_header00006660000000000000000000000064140377703040014517gustar00rootroot0000000000000052 comment=6657a9cc2014749c8e20572027f3ce64f8bcf582 organize-1.10.1/000077500000000000000000000000001403777030400134155ustar00rootroot00000000000000organize-1.10.1/.editorconfig000066400000000000000000000004461403777030400160760ustar00rootroot00000000000000# EditorConfig is awesome: http://EditorConfig.org # top-most EditorConfig file root = true [*] end_of_line = lf insert_final_newline = true charset = utf-8 indent_style = space indent_size = 4 [{*.bat,Makefile}] indent_style = tab [*.rst] indent_size = 2 [{*.yml,*.yaml}] indent_size = 2 organize-1.10.1/.github/000077500000000000000000000000001403777030400147555ustar00rootroot00000000000000organize-1.10.1/.github/FUNDING.yml000066400000000000000000000011271403777030400165730ustar00rootroot00000000000000# These are supported funding model platforms # github: tfeldmann patreon: # Replace with a single Patreon username open_collective: # Replace with a single Open Collective username ko_fi: # Replace with a single Ko-fi username tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry liberapay: # Replace with a single Liberapay username issuehunt: # Replace with a single IssueHunt username otechie: # Replace with a single Otechie username custom: ["paypal.me/tfeldmann42"] organize-1.10.1/.github/workflows/000077500000000000000000000000001403777030400170125ustar00rootroot00000000000000organize-1.10.1/.github/workflows/tests.yml000066400000000000000000000025611403777030400207030ustar00rootroot00000000000000name: tests on: push: branches: [master] pull_request: branches: [master] workflow_dispatch: jobs: build: runs-on: ubuntu-latest strategy: max-parallel: 4 matrix: python-version: [3.6, 3.7, 3.8, 3.9] steps: - name: Checkout sources uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} - name: Install dependencies run: | python -m pip install --upgrade pip python -m pip install poetry poetry install -E textract - name: General info run: | poetry run python main.py list poetry run python main.py config --path poetry run python main.py --version - name: Lint with flake8 run: | # stop the build if there are Python syntax errors or undefined names poetry run flake8 --count --select=E9,F63,F7,F82 --show-source --statistics organize # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide poetry run flake8 --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics organize - name: Test with pytest run: | poetry run pytest - name: Check with MyPy run: | poetry run mypy -porganize organize-1.10.1/.gitignore000066400000000000000000000026751403777030400154170ustar00rootroot00000000000000.configs .pytest_cache/ # Created by https://www.gitignore.io/api/python ### Python ### # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] *$py.class # C extensions *.so # Distribution / packaging .Python build/ develop-eggs/ dist/ downloads/ eggs/ .eggs/ lib/ lib64/ parts/ sdist/ var/ wheels/ *.egg-info/ .installed.cfg *.egg # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. *.manifest *.spec # Installer logs pip-log.txt pip-delete-this-directory.txt # Unit test / coverage reports htmlcov/ .tox/ .coverage .coverage.* .cache nosetests.xml coverage.xml *.cover .hypothesis/ # Translations *.mo *.pot # Django stuff: *.log local_settings.py # Flask stuff: instance/ .webassets-cache # Scrapy stuff: .scrapy # Sphinx documentation docs/_build/ # PyBuilder target/ # Jupyter Notebook .ipynb_checkpoints # pyenv .python-version # celery beat schedule file celerybeat-schedule # SageMath parsed files *.sage.py # Environments .env .venv env/ venv/ ENV/ env.bak/ venv.bak/ # Spyder project settings .spyderproject .spyproject # Rope project settings .ropeproject # mkdocs documentation /site # mypy .mypy_cache/ # End of https://www.gitignore.io/api/python # Created by https://www.gitignore.io/api/visualstudiocode ### VisualStudioCode ### .vscode .history # End of https://www.gitignore.io/api/visualstudiocode .idea organize-1.10.1/.readthedocs.yml000066400000000000000000000011071403777030400165020ustar00rootroot00000000000000# .readthedocs.yml # Read the Docs configuration file # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details # Required version: 2 # Build documentation in the docs/ directory with Sphinx sphinx: configuration: docs/conf.py # Build documentation with MkDocs #mkdocs: # configuration: mkdocs.yml # Optionally build your docs in additional formats such as PDF and ePub formats: all build: image: latest # Optionally set the version of Python and requirements required to build your docs python: version: 3.7 install: - method: pip path: . organize-1.10.1/CHANGELOG.md000066400000000000000000000104321403777030400152260ustar00rootroot00000000000000# Changelog ## v1.10.1 (2021-04-21) - Action `macos_tags` now supports colors and placeholders. - Show full expanded path if folder is not found. ## v1.10.0 (2021-04-20) - Add filter `mimetype` - Add action `macos_tags` - Support [`simplematch`](https://github.com/tfeldmann/simplematch) syntax in `filename`-filter. - Updated dependencies - Because installing `textract` is quite hard on some platforms it is now an optional dependency. Install it with `pip install organize-tool[textract]` - This version needs python 3.6 minimum. Some dependencies that were simply backports (pathlib2, typing) are removed. - Add timezones in created and last_modified filters (Thank you, @win0err!) ## v1.9.1 (2020-11-10) - Add {env} variable - Add {now} variable ## v1.9 (2020-06-12) - Add filter `Duplicate`. ## v1.8.2 (2020-04-03) - Fix a bug in the filename filter config parsing algorithm with digits-only filenames. ## v1.8.1 (2020-03-28) - Flatten filter and action lists to allow enhanced config file configuration (Thanks to @rawdamedia!) - Add support for multiline content filters (Thanks to @zor-el!) ## v1.8.0 (2020-03-04) - Added action `Delete`. - Added filter `FileContent`. - Python 3.4 is officially deprecated and no longer supported. - `--config-file` command line option now supports `~` for user folder and expansion of environment variables - Added `years`, `months`, `weeks` and `seconds` parameter to filter `created` and `lastmodified` ## v1.7.0 (2019-11-26) - Added filter `Exif` to filter by image exif data. - Placeholder variable properties are now case insensitve. ## v1.6.2 (2019-11-22) - Fix `Rename` action (`'PosixPath' object has no attribute 'items'`). - Use type hints everywhere. ## v1.6.1 (2019-10-25) - Shows a warning for missing folders instead of raising an exception. ## v1.6 (2019-08-19) - Added filter: `Python` - Added filter: `FileSize` - The organize module can now be run directly: `python3 -m organize` - Various code simplifications and speedups. - Fixes an issue with globstring file exclusion. - Remove `clint` dependency as it is no longer maintained. - Added various integration tests - The "~~ SIMULATION ~~"-banner now takes up the whole terminal width ## v1.5.3 (2019-08-01) - Filename filter now supports lists. ## v1.5.2 (2019-07-29) - Environment variables in folder pathes are now expanded (syntax `$name` or `${name}` and additionally `%name%` on windows). For example this allows the usage of e.g. `%public/Desktop%` in windows. ## v1.5.1 (2019-07-23) - New filter "Created" to filter by creation date. - Fixes issue #39 where globstrings don't work most of the time. - Integration test for issue #39 - Support indented config files ## v1.5 (2019-07-17) - Fixes issue #31 where the {path} variable always resolves to the source path - Updated dependencies - Exclude changelog and readme from published wheel ## v1.4.5 (2019-07-03) - Filter and Actions names are now case-insensitive ## v1.4.4 (2019-07-02) - Fixes issues #36 with umlauts in config file on windows ## v1.4.3 (2019-06-05) - Use safe YAML loader to fix a deprecation warning. (Thanks mope1!) - Better error message if a folder does not exist. (Again thanks mope1!) - Fix example code in documentation for LastModified filter. - Custom config file locations (given by cmd line argument or environment variable). - `config --debug` now shows the full path to the config file. ## v1.4.2 (2018-11-14) - Fixes a bug with command line arguments in the ``$EDITOR`` environment variable. - Fixes a bug where an empty config wouldn't show the correct error message. - Fix binary wheel creation in setup.py by using environment markers ## v1.4.1 (2018-10-05) - A custom separator ``counter_separator`` can now be set in the actions Move, Copy and Rename. ## v1.4 (2018-09-21) - Fixes a bug where glob wildcards are not detected correctly - Adds support for excluding folders and files via glob syntax. - Makes sure that files are only handled once per rule. ## v1.3 (2018-07-06) - Glob support in folder configuration. - New variable {relative_path} is now available in actions. ## v1.2 (2018-03-19) - Shows the relative path to files in subfolders. ## v1.1 (2018-03-13) - Removes the colon from extension filter output so `{extension.lower}` now returns `'png'` instead of `'.png'`. ## v1.0 (2018-03-13) - Initial release. organize-1.10.1/LICENSE.txt000066400000000000000000000020651403777030400152430ustar00rootroot00000000000000The MIT License (MIT) Copyright (c) Thomas Feldmann 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. organize-1.10.1/README.md000066400000000000000000000164311403777030400147010ustar00rootroot00000000000000

organize logo

[![tests](https://github.com/tfeldmann/organize/actions/workflows/tests.yml/badge.svg)](https://github.com/tfeldmann/organize/actions/workflows/tests.yml) [![Documentation Status](https://readthedocs.org/projects/organize/badge/?version=latest)](https://organize.readthedocs.io/en/latest/?badge=latest) [![License](https://img.shields.io/badge/license-MIT-blue.svg)](/LICENSE) [![PyPI Version](https://img.shields.io/pypi/v/organize-tool)](https://pypi.org/project/organize-tool/)
---

organize - The file management automation tool
Full documentation at Read the docs

- [About](#about) - [Getting started](#getting-started) - [Installation](#installation) - [Creating your first rule](#creating-your-first-rule) - [Example rules](#example-rules) - [Advanced usage](#advanced-usage) - [Command line interface](#command-line-interface) ## About Your desktop is a mess? You cannot find anything in your downloads and documents? Sorting and renaming all these files by hand is too tedious? Time to automate it once and benefit from it forever. **organize** is a command line, open-source alternative to apps like Hazel (macOS) or File Juggler (Windows). ## Getting started ### Installation Python 3.6+ is needed. Install it via your package manager or from [python.org](https://python.org). Installation is done via pip. Note that the package name is `organize-tool`: ```bash pip3 install -U organize-tool ``` If you want the text extraction capabilities, install with `textract` like this: ```bash pip3 install -U organize-tool[textract] ``` This command can also be used to update to the newest version. Now you can run `organize --help` to check if the installation was successful. ### Creating your first rule In your shell, **run `organize config`** to edit the configuration: ```yaml rules: - folders: ~/Downloads subfolders: true filters: - extension: pdf actions: - echo: "Found PDF!" ``` > If you have problems editing the configuration you can run `organize config --open-folder` to reveal the configuration folder in your file manager. You can then edit the `config.yaml` in your favourite editor. > > Alternatively you can run `organize config --path` to see the full path to > your `config.yaml`) **Save your config file and run `organize run`.** You will see a list of all `.pdf` files you have in your downloads folder (+ subfolders). For now we only show the text `Found PDF!` for each file, but this will change soon... (If it shows `Nothing to do` you simply don't have any pdfs in your downloads folder). Run `organize config` again and add a `copy`-action to your rule: ```yaml actions: - echo: "Found PDF!" - move: ~/Documents/PDFs/ ``` **Now run `organize sim` to see what would happen without touching your files**. You will see that your pdf-files would be moved over to your `Documents/PDFs` folder. Congratulations, you just automated your first task. You can now run `organize run` whenever you like and all your pdfs are a bit more organized. It's that easy. > There is so much more. You want to rename / copy files, run custom shell- or python scripts, match filenames with regular expressions or use placeholder variables? organize has you covered. Have a look at the advanced usage example below! ## Example rules Here are some examples of simple organization and cleanup rules. Modify to your needs! Move all invoices, orders or purchase documents into your documents folder: ```yaml rules: # sort my invoices and receipts - folders: ~/Downloads subfolders: true filters: - extension: pdf - filename: contains: - Invoice - Order - Purchase case_sensitive: false actions: - move: ~/Documents/Shopping/ ``` Move incomplete downloads older than 30 days into the trash: ```yaml rules: # move incomplete downloads older > 30 days into the trash - folders: ~/Downloads filters: - extension: - download - crdownload - part - lastmodified: days: 30 mode: older actions: - trash ``` Delete empty files from downloads and desktop: ```yaml rules: # delete empty files from downloads and desktop - folders: - ~/Downloads - ~/Desktop filters: - filesize: 0 actions: - trash ``` Move screenshots into a "Screenshots" folder on your desktop: ```yaml rules: # move screenshots into "Screenshots" folder - folders: ~/Desktop filters: - filename: startswith: "Screen Shot" actions: - move: ~/Desktop/Screenshots/ ``` Organize your font downloads: ```yaml rules: # organize your font files but keep the folder structure: # "~/Downloads/favourites/helvetica/helvetica-bold.ttf" # is moved to # "~/Documents/FONTS/favourites/helvetica/helvetica-bold.ttf" - folders: ~/Downloads/**/*.ttf actions: - Move: "~/Documents/FONTS/{relative_path}" ``` You'll find many more examples in the full documentation. ## Advanced usage This example shows some advanced features like placeholder variables, pluggable actions, recursion through subfolders and glob syntax: ```yaml rules: - folders: ~/Documents/**/* filters: - extension: - pdf - docx - created actions: - move: "~/Documents/{extension.upper}/{created.year}{created.month:02}/" - shell: 'open "{path}"' ``` Given we have two files in our `~/Documents` folder (or any of its subfolders) named `script.docx` from january 2018 and `demo.pdf` from december 2016 this will happen: - `script.docx` will be moved to `~/Documents/DOCX/2018-01/script.docx` - `demo.pdf` will be moved to `~/Documents/PDF/2016-12/demo.pdf` - The files will be opened (`open` command in macOS) _from their new location_. - Note the format syntax for `{created.month}` to make sure the month is prepended with a zero. ## Command line interface ``` The file management automation tool. Usage: organize sim [--config-file=] organize run [--config-file=] organize config [--open-folder | --path | --debug] [--config-file=] organize list organize --help organize --version Arguments: sim Simulate a run. Does not touch your files. run Organizes your files according to your rules. config Open the configuration file in $EDITOR. list List available filters and actions. --version Show program version and exit. -h, --help Show this screen and exit. Options: -o, --open-folder Open the folder containing the configuration files. -p, --path Show the path to the configuration file. -d, --debug Debug your configuration file. Full documentation: https://organize.readthedocs.io ``` organize-1.10.1/docs/000077500000000000000000000000001403777030400143455ustar00rootroot00000000000000organize-1.10.1/docs/Makefile000066400000000000000000000011421403777030400160030ustar00rootroot00000000000000# Minimal makefile for Sphinx documentation # # You can set these variables from the command line. SPHINXOPTS = SPHINXBUILD = python3 -msphinx SPHINXPROJ = organize SOURCEDIR = . BUILDDIR = _build # Put it first so that "make" without argument is like "make help". help: @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) .PHONY: help Makefile # Catch-all target: route all unknown targets to Sphinx using the new # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) organize-1.10.1/docs/_static/000077500000000000000000000000001403777030400157735ustar00rootroot00000000000000organize-1.10.1/docs/_static/organize.pdf000066400000000000000000011320251403777030400203100ustar00rootroot00000000000000%PDF-1.5 % 1 0 obj <>/OCGs[7 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream application/pdf organize 2017-10-06T16:23:53+02:00 2017-10-06T16:23:53+02:00 2017-10-06T16:23:53+02:00 Adobe Illustrator CS6 (Macintosh) 256 56 JPEG /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAOAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FUk87ebNP8 peVtR8wX5/cWMRdY60Mkp+GKJfd3IXFXln/ONXnfz/5xj8w6n5ivBc6ZHOiWSmNF4TOC8qIygHgi FNjXr88Ve3Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXyV/zkB55/NrS/zNksrW/1 DS9OQx/oOGyeSKK4UqhLUjIE7GQ0IatPs0xV9NeSLrXrvyho915gi9HWprSF9QjKhCJWQFuSDZWP Ur2O2Kp3irsVdirsVdirsVeK/k9+T/n/AMpefNZ1/wAw61Ff21/FIjGOSV3uZXkVlmmR1VVKqp7m laDbFXo/lLT/ADxaXmtP5m1S21G1nuy+ix28PpNDbU2Rz3Pam52ryNdlWR4qo3N5Z2qq11PHArEK rSuqAsegHIjfFXzH/wA5deaNdlvtO8upa3EGgwAXUt40brDc3LghVSQjiwhQ9j1Y16DFXtf5L+Tz 5T/LjR9LlTheyRfW78EUb17j94yt03QEJ/scVZviqF1TVNO0nTrjUtSuEtbG1Qy3FxKaKijuf898 VeCa9/zmJ5etbxotE0C41O2VmX6zcTrZ8gKUZEEdw1Dv9rifbwVZX+W3/OSHk3znqEWkXEMmi6xP RbeC4ZZIZnP+64phxq9egZFr232xV6B5z82ad5R8s3vmLUo5prKwCNNHbKrSkSSLEOIdo1+046ti rz3yp/zk35B8zeYrDQbKy1OC71CT0YJbmK3WIOQSORSeRt6U2U4ql35h/wDOUnlryvrc+jaVpr67 dWjmK8mWcW8COtQyI/CZnZW2Pwge+KvQ/wAtvPtt548oW/mSK0fT45mkR4JWDhWiPFyrgLyWo60H yxV5r5x/5yz8naPfS2WhafNrzwMUe5Eq21sxBofTkKys49+FD2NN8VYpc/8AOW/mzV2Sw8seUkXV J/ghRpZb92YkfYhhjt2JpXv/AEKr0r8gtf8AzM1bTtabz5Z3lvdfWllspLy2NrWN0o0UcZVKKhQE fD+11O+KoH8wv+cmfLfk/Xb3QRpF7e6pYnjMGMdvDyKh46OTI5VgwNeHTxxVimnf85l6ZJdKupeV pra1/altrtLiQbjpG8VuDtX9vFXu/lTzZoXmvQ4Nb0O5FzYXFQGoVZXXZkdTurKeo/hirDfzG/Pr yf5B12LRdYs9QuLqW3S6V7OOB4+Du6AEyTRNyrGe2Ksb83/85W+SdIgtv0NaTa3eXMEVw0QdYI4f WVX9KWWkv7xVb4lVWodia4qnH5S/85A6B+YGoSaQ1jJpGsrG00ds8gnjlRD8XpyhYyWUUJUoPatD irJ/zJ/M7Qfy+0q11PWbe6uILuf6tGtmkbuH4M9WEkkQpRPHFXnf/Q3/AOWn/Vs1n/kRa/8AZTir 17yt5isvMnl6w16xSWOz1GITwRzhVkCt2cKzrX5McVYz+Zv5xeWfy6fTk1u1vbg6mJTB9SSJ6ehw Dc/Vlhp/eClK4qwf/ob/APLT/q2az/yItf8AspxVkPkP/nIjyV518yQeX9KstShvbhJHSS6igSIC JC7VMc8jdBt8OKsj/MX80vKnkHTo7rW5ma4uKizsIAHnmK9eKkgBR3ZiB9OKvHV/5zMsPrnBvKso suRHrC9Uy8ex9L0Qtfb1PpxV7V5B/MXyt560g6loFwziIhLq1lASeB2FQsqAsN+xUlT2OxxViP8A zkrr3mbRfyyludAllt5JbuGC/uoCVkitZFfkwcbrykCJUfzYq8Z/5xY80eb5fzBbShd3F3o1xbTS 38MrvJHGyCqSjkTwYuQte9cVfV2savpujaXdarqc621hZxtNcTv0VFFfpJ6ADcnYYq+bvOn5dP8A nSZvO/krzE18FpA2i6kjQfVmRFJhidQUUnY0pQk1L4q82h8y/nD+V040nVIZ4dPbb9EapH9a0+VV 7Rhi0ZHvE4+eKvr38sfPEXnfyXYeYlg+qyXIdLi3rUJLE5Rwp7qStV9j44qynFXzv/zmH5ju7bRN B0CCQrBqMs1zdqNuQtggjU+I5SlqeIGKqX/OLv5aeUdS8mXmv63pVpqt3dXb28IvIUuEjhhVPspK GUMzs1SBWlMVeR/nx5V0/wAofmjfWmiL9Ts3WG9tIoyV9FpFDMEI+yBIpK06Dbtir650KLTfzB/K /Sx5gt/rdrrVhbS6hByeIPIAjtRo2RwPVSuxxV8UecYU8sfmZq8WghrJdG1WYaYEZnaL6vOfSozl mJXiOpOBXq2of84ta9D+Xltf2ccupedruWKSew9WGGG3gdWZ1rMY+cgPHkeXXoO5KvTH8s695U/5 xjvdFeI2+r2ul3LXcSsrsvrSvLOOcZdTSORuhxV4L/zjho/lHVvzKhtPM0UFxAbWVrC1uuLQy3fJ AiMj/C/7suQpruMVT7/nKbQvJmieaNIi8uWtrp941u7aja2KpEqUZfRZoo6KjEcuwJxV9DfkZq+t 6t+VWgX2tM8l/JFIhmlrzkjjmeOJ2J3JaNVPI9evfFWMfmV5p/5x80LzJc3vmiytdX8zFFS4thb/ AF2UCNPgV0k/cI3GgHIg9O2+KvDfze89/kz5n0S3j8o+WptE1qCdW9dbW1tIXgKsHRxbyvyPIqRV e3XFXpv/ADhvcyt5f8yWpY+lFdwSqtdg0kbKxA9xGMVYJ/zlz/5M6z/7ZMH/ACfnxV6V+VX5T+QZ vyVTUbzR7e91LVbGe4uL26jWWVHpIq+i7CsXEDbhQ13xV4Z/zj1JJH+cflsoxUmWdTTuGtpQR92K vszzj5E8qecrGGx8yWP1+1t5fXhj9WaHjJxK8qwvGx+Fj1OKvkD/AJyL8leWfJ/nu20vy7Z/UbGT Tobh4fUlmrK8sys3KZ5G6INq0xV9T/kl/wCSn8r/APMDH+s4qmHnP8tPJPnRrRvM2m/X2sRILU+t PDwEvHn/AHEkda8F64q+V/z8svyi8v348s+TNHRNWt3rqupC6u5lhI/490WSZ0L/AM5I+Hp1rxVe l/8AOM35M3OjJH5315Hh1C5iK6TZGqmOCVaGaUfzSKfhXsu53PwqvFfzv8xz+YvzZ1prqfha2V22 m27MCyxQ2rmIkBakgsGfbrXFXr2oa7/zibJ5Pm0G2ktFmFq0NvqI027F56oU8JTcfV/ULc992p26 bYq85/5xg8w3Ol/mtZWSOwtdYimtbmMfZJWNpo2I8Q8dK+5xV9ZfmD508ueUPLcuqeYUeXTZHW2e GOITGQyg/AUNFoQDXkaYq8SX/nJ3yBo8T2nkTyXIk9w20KxW9ijv2YpbCZn+7FUCfKX55fnLfQv5 q5eWfKiMHFqY2hBp3S2c+rI/g8p4jqvhir6I8p+VNF8qaBaaFo0Po2NotF5ULux3aSRgBydjuT/D FWD/AJ8fmZo3krQrCHUNIg146tO0baXclRG1vEtZXPJJBUFlUfD39sVZp5L0bTNI8s2Nrpumfoa2 kT6wdMDF/QkuP3skdST9l3I228NsVTvFXz5/zmB5Yu7zy/ovmG3jZ4tLmlt7wqK8Y7oJwdvYPFx+ bYqlP/OM/wCbnk7QvKd55e8w6jHps8F09zayz1EckUqqCoYAjkrqdj2O3Q4q8q/OrzZaeefzPvL3 Q1a5tHMNjpxVSHm9MBOSr9r45CePelMVfYGjyaX+Xn5Z6aNfuRbWeh2NtDf3IR5QslEjYhYhIxBl bsDir4m85a1pmo/mXq+tWc3q6ZdatNdQXHF15QvOXVuDAOPh3oRXFX3B5M/MvyT50a7XyzqX19rE Rm6Hozw8BLy4f38cda8G6YqyScxCCQyryi4t6ikcqrTcU77dsVfn7GPJfmTzvfS3l0nk3y9dSSy2 5itpr1YB1jj9JG5/F3oeIPQBaABXoXkvyH/zjqdUj/S/n5tVVW5i2a0uNLgcAgcZJZg23+q6nCr6 x5W8PlwnQRE0EVof0YttxaKiR/uRGFqpXYUpir4E8mS6BdeedOm84yu+jzXfqavKxcswYlmLlPjo z/bI3pXAr138/Nf/ACRbylaaT5JtdNbV2uI5GutOtY0ZLeNXUiS4CKxLGm3Ik9T2wqnX/OG2p2Kp 5l0xplF9Iba5jgP2miQOjuPZWdQfmMVYn/zlz/5M6z/7ZMH/ACfnxV7x+U//AJIfSf8Atlzf8zMV fLn/ADj9/wCTi8tf8Zpf+oeTFX2b5x8/eU/JtnBeeZL76hbXUhhgf0ppuThS1KQpIRsO+KvkH/nI vzr5Z84ee7bVPLt59esY9Oht3m9OWGkqSzMy8Zkjbo43pTFXuH5P/nV+Wdl5L8s+WrnWfT1tYYbN rT6tdn9+7cVT1FiMe5Yb8qYqiP8AnIn85pvJenR6BorFfMeqQ+oLmm1tbMzR+qp7yMyME8KE+FVX z5+TP/KsofMTa3+YGqrFDZMJLTTngubj6xNXl6kpiikXgp/ZJ+I9duqr6y8s/nX+WXmfWYNF0PWf rmpXAcwwfVbuOojQu3xyxIgoqnqcVfJX59eVrvy7+aetevCfqupXDalaOQQkiXLGR6Gv7MhZDTwx V6zoWn/84g6npEF9NBDp80iAz2VzeaiksT0+JCPW+Kh6Fag4qyn8o9F/5x41bzFPqPkawZNX0N+U c0s16CUlQp60cVxK3JPiK/ElQew2OKvWPMfl3R/Mei3Wi6xbi50+8ThNEdj4hlI3VlO4I6HFXzFd 6B+ZX5Ba5darosS635Ru6h5ZE5Ko/Y+scPjhdf5x8DfgFXof5Xfn55W1PR7vVfN/mS3s9Zdi0mll JILe2gQkRpbhufrO1SzMGZu1KAYqyvyF+Zc3nvWb280W2a38maYrQnUbleMl5dGhpEp/u4ok+Ji3 xHkvTcYq8ft5B+cn/OQSXMX77yn5YCsr9Ukit3qvsfrFwfpjHtir6hxV2KqF9Y2WoWU9jfQJc2dy jRXFvKoZHRhRlZTsQRirxTW/+cRvIF7eNcabf32lxOSTaKyTxLWlBGZF9QD/AFmbFWT/AJef84/e QfJN6mp28c2pavH/AHV9esrekSACYY0VEX2YgsP5sVZj5z8p6d5u8s3vl3UpJobK/CLNJbMqygRy LKOJdZF+0g6riryf/oUD8tP+rnrP/I+1/wCybFWcfll+Tvln8un1F9Eur24OpiIT/XXienocyvD0 ooaf3hrWuKpj+ZPn228i+WX8wXVlLfW8c0cMkUJVWX1SQGq21OVB9OKvnzSNG/5xv/Ma6vdTubqb yTeLKWlsnvbW2im5gH1IxcJIg+KvwoRTwpTFWMfm9+Xf5P8AlvQre78n+bP0vqck4R7H6za3tYiC S/K1RPT4n+br2xV6h/zh5qesT+W9esLhmfS7K5hNhyJIWSZXadFr0Hwo1PFj44qyLzt/zjB5D8y6 vNq1vPc6PdXLmS6jtfTMDud2cRuvwsx3NGp7YqjPKH/ONf5Z+XoZxcWsmt3NzE8Mk9+wbiki8XES RhFSo/a3cdmxVN/y3/Jjyt+X+qapf6LLcS/pJY4xHcsrmFEZmKRsqoSrFl+1U/CN8VQn5jfkL5P8 /a7FrWsXmoW91FbpaqlnJAkfBHdwSJIZW5VkPfFWXeXvKGm6F5St/K9pLNJp9tbtaxyyshmKPWpL KqrX4v5cVYD5O/5xq8i+VPMtj5h06+1SW9sGZ4Y7iW3aIlkZDyCQRt0bs2Ksp/Mr8rtA/MLTrTT9 auLu3hs5jPE1m8aMWKlKMZI5RSh8MVee/wDQoH5af9XPWf8Akfa/9k2KovSf+cUvy70vVbLU7fUd XaexniuYlkmtiheFw6hgLZTSq70OKsg/Mj8iPKH5ga5BrOs3moW91b2qWaJZyQpGY0kkkBIkhlPK sp74qxT/AKFA/LT/AKues/8AI+1/7JsVZH5A/wCce/JXkfzFHr+lXmo3F5HHJEiXckDxgSijGkcM TVp/lYqy3zt+X/lTzrpq6f5hsluY4yWt5lJSaFj1Mci/Ete46HuDiryOT/nDvyabgtHrmorb1FI2 EDPx7jmEUV9+OKvSvy+/KDyP5EV5NEtGa/kX05dSumEtyyGhK8gFVVJUEhFAOKs0xVp0SRGjkUOj gq6MKgg7EEHFXlHnL/nGf8tPMUklza28mh3r7mTTyqwlv8qBg0Y/2HHFXn9x/wA4y/mlpdpNpvlr zsP0VMrpJaSy3dlEySfbVoofrCHlXfxxV7B+UP5X2H5e+Vxpkci3OpXL+tqd6oKiSToqqDuEjXZf pPfFWcYq7FXYq7FXYq7FXYq7FUDruh6Vr2kXWkatbrdadep6dxA9aMtajcUIIIBBG4O+KvBtZ/5w 40Ge4L6P5iubCAsT6NzbpdkA0oFZXtum/Wv9VWtI/wCcONChn5av5kub2EEER2tulqaCtQWd7nrt 0GKvcvK/lXQfK2jQaNodotpYQVKxrUszH7TuxqzM3cnFWL3flL8wYGEmia96EinUvhu55rqNhczq 9nyWdJj+5iSnwkU3AqCcVT240rzRdeTJtNm1ER+YJoXjOowN6QDsxIKssYK/BtUJXw33xVL/APDf myK7dor9pbaG/tLizE17Pza2igWGeKULEF+Irz4nkGY1NDviqJ0/TvPyeU7i1vtUt5PMr1+r38SK sKbL+yYqdm6o2KpGmifnWQI5NfsVURSL6yKhkMvqK0b0NnwHwclYfSPZVD6xH+cUGsWKidJ9NuNQ jLmxEbNDbLIvITepFDVWTrv4/FsoZVUXQPzxDW7HzJYkLazJcqY46Ncsrei60tFNFYiu/b7LdCqj 30H80HR+evxMQ1k8SIIogfRMBuVLi1JAm4zdmG67AVAVTjzZaed7lrIeWry2skUv9ee4+IkHiECK YZa0+I9V7eOyqUpo35n7zvq9v9YkhkjeJHX0o2+uvLEyVtDVvqjLFyK7MKlXxVAw6L+d0cJ569p8 87FPtKqIoWpanG0qeWw3+Yp0xVHTaD+YyW0K22rRSXcFzqTrcTzEK0NykosucSW1GMDOhKE0+Hqa gKqj9B03z7BqyzaxqsNzpvpyq1qipy5F6xNyWCEsyp8LGqqevEYqoXej/mGuqXMlhq8QsJtQiuIk mKlks/RRZYOP1Z/92KxoHqwI+NCDyVd5f0Tz3BrNjf65qcV5HHbXNteQxSOiFpRaPDKsKxRxMySQ 3FCVDKkgXk1DVVl+KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2 KuxV2KuxV2KuxV2KuxV//9k= uuid:1e5d5c86-71a7-ba4b-a79c-97169be62009 xmp.did:0380117407206811822AF33CB0CB0D8F uuid:5D20892493BFDB11914A8590D31508C8 proof:pdf xmp.iid:0280117407206811822AF33CB0CB0D8F xmp.did:0280117407206811822AF33CB0CB0D8F uuid:5D20892493BFDB11914A8590D31508C8 proof:pdf saved xmp.iid:0180117407206811822AF33CB0CB0D8F 2017-10-06T16:19:14+02:00 Adobe Illustrator CS6 (Macintosh) / saved xmp.iid:0380117407206811822AF33CB0CB0D8F 2017-10-06T16:23:51+02:00 Adobe Illustrator CS6 (Macintosh) / Print False False 1 219.780556 59.266667 Millimeters FiraCode-Medium Fira Code Medium Open Type Version 1.204 False FiraCode-Medium.ttf FiraCode-Bold Fira Code Bold Open Type Version 1.204 False FiraCode-Bold.ttf Black Standard-Farbfeldgruppe 0 Weiß CMYK PROCESS 0.000000 0.000000 0.000000 0.000000 Schwarz CMYK PROCESS 0.000000 0.000000 0.000000 100.000000 CMYK Rot CMYK PROCESS 0.000000 100.000000 100.000000 0.000000 CMYK Gelb CMYK PROCESS 0.000000 0.000000 100.000000 0.000000 CMYK Grün CMYK PROCESS 100.000000 0.000000 100.000000 0.000000 CMYK Cyan CMYK PROCESS 100.000000 0.000000 0.000000 0.000000 CMYK Blau CMYK PROCESS 100.000000 100.000000 0.000000 0.000000 CMYK Magenta CMYK PROCESS 0.000000 100.000000 0.000000 0.000000 C=15 M=100 Y=90 K=10 CMYK PROCESS 14.999998 100.000000 90.000000 10.000002 C=0 M=90 Y=85 K=0 CMYK PROCESS 0.000000 90.000000 85.000000 0.000000 C=0 M=80 Y=95 K=0 CMYK PROCESS 0.000000 80.000000 95.000000 0.000000 C=0 M=50 Y=100 K=0 CMYK PROCESS 0.000000 50.000000 100.000000 0.000000 C=0 M=35 Y=85 K=0 CMYK PROCESS 0.000000 35.000004 85.000000 0.000000 C=5 M=0 Y=90 K=0 CMYK PROCESS 5.000001 0.000000 90.000000 0.000000 C=20 M=0 Y=100 K=0 CMYK PROCESS 19.999998 0.000000 100.000000 0.000000 C=50 M=0 Y=100 K=0 CMYK PROCESS 50.000000 0.000000 100.000000 0.000000 C=75 M=0 Y=100 K=0 CMYK PROCESS 75.000000 0.000000 100.000000 0.000000 C=85 M=10 Y=100 K=10 CMYK PROCESS 85.000000 10.000002 100.000000 10.000002 C=90 M=30 Y=95 K=30 CMYK PROCESS 90.000000 30.000002 95.000000 30.000002 C=75 M=0 Y=75 K=0 CMYK PROCESS 75.000000 0.000000 75.000000 0.000000 C=80 M=10 Y=45 K=0 CMYK PROCESS 80.000000 10.000002 45.000000 0.000000 C=70 M=15 Y=0 K=0 CMYK PROCESS 70.000000 14.999998 0.000000 0.000000 C=85 M=50 Y=0 K=0 CMYK PROCESS 85.000000 50.000000 0.000000 0.000000 C=100 M=95 Y=5 K=0 CMYK PROCESS 100.000000 95.000000 5.000001 0.000000 C=100 M=100 Y=25 K=25 CMYK PROCESS 100.000000 100.000000 25.000000 25.000000 C=75 M=100 Y=0 K=0 CMYK PROCESS 75.000000 100.000000 0.000000 0.000000 C=50 M=100 Y=0 K=0 CMYK PROCESS 50.000000 100.000000 0.000000 0.000000 C=35 M=100 Y=35 K=10 CMYK PROCESS 35.000004 100.000000 35.000004 10.000002 C=10 M=100 Y=50 K=0 CMYK PROCESS 10.000002 100.000000 50.000000 0.000000 C=0 M=95 Y=20 K=0 CMYK PROCESS 0.000000 95.000000 19.999998 0.000000 C=25 M=25 Y=40 K=0 CMYK PROCESS 25.000000 25.000000 39.999996 0.000000 C=40 M=45 Y=50 K=5 CMYK PROCESS 39.999996 45.000000 50.000000 5.000001 C=50 M=50 Y=60 K=25 CMYK PROCESS 50.000000 50.000000 60.000004 25.000000 C=55 M=60 Y=65 K=40 CMYK PROCESS 55.000000 60.000004 65.000000 39.999996 C=25 M=40 Y=65 K=0 CMYK PROCESS 25.000000 39.999996 65.000000 0.000000 C=30 M=50 Y=75 K=10 CMYK PROCESS 30.000002 50.000000 75.000000 10.000002 C=35 M=60 Y=80 K=25 CMYK PROCESS 35.000004 60.000004 80.000000 25.000000 C=40 M=65 Y=90 K=35 CMYK PROCESS 39.999996 65.000000 90.000000 35.000004 C=40 M=70 Y=100 K=50 CMYK PROCESS 39.999996 70.000000 100.000000 50.000000 C=50 M=70 Y=80 K=70 CMYK PROCESS 50.000000 70.000000 80.000000 70.000000 Graustufen 1 C=0 M=0 Y=0 K=100 CMYK PROCESS 0.000000 0.000000 0.000000 100.000000 C=0 M=0 Y=0 K=90 CMYK PROCESS 0.000000 0.000000 0.000000 89.999405 C=0 M=0 Y=0 K=80 CMYK PROCESS 0.000000 0.000000 0.000000 79.998795 C=0 M=0 Y=0 K=70 CMYK PROCESS 0.000000 0.000000 0.000000 69.999702 C=0 M=0 Y=0 K=60 CMYK PROCESS 0.000000 0.000000 0.000000 59.999104 C=0 M=0 Y=0 K=50 CMYK PROCESS 0.000000 0.000000 0.000000 50.000000 C=0 M=0 Y=0 K=40 CMYK PROCESS 0.000000 0.000000 0.000000 39.999401 C=0 M=0 Y=0 K=30 CMYK PROCESS 0.000000 0.000000 0.000000 29.998802 C=0 M=0 Y=0 K=20 CMYK PROCESS 0.000000 0.000000 0.000000 19.999701 C=0 M=0 Y=0 K=10 CMYK PROCESS 0.000000 0.000000 0.000000 9.999103 C=0 M=0 Y=0 K=5 CMYK PROCESS 0.000000 0.000000 0.000000 4.998803 Strahlende Farben 1 C=0 M=100 Y=100 K=0 CMYK PROCESS 0.000000 100.000000 100.000000 0.000000 C=0 M=75 Y=100 K=0 CMYK PROCESS 0.000000 75.000000 100.000000 0.000000 C=0 M=10 Y=95 K=0 CMYK PROCESS 0.000000 10.000002 95.000000 0.000000 C=85 M=10 Y=100 K=0 CMYK PROCESS 85.000000 10.000002 100.000000 0.000000 C=100 M=90 Y=0 K=0 CMYK PROCESS 100.000000 90.000000 0.000000 0.000000 C=60 M=90 Y=0 K=0 CMYK PROCESS 60.000004 90.000000 0.003099 0.003099 Adobe PDF library 10.01 endstream endobj 3 0 obj <> endobj 9 0 obj <>/Resources<>/Font<>/ProcSet[/PDF/Text]/Properties<>>>/Thumb 13 0 R/TrimBox[0.0 0.0 623.0 168.0]/Type/Page>> endobj 10 0 obj <>stream HlK\E +2 uzo"V!Zb= 03" n h{\/߽Njo^/>ˇO#Ogǯ\~gKqy*nxLץ9:JQ/i~XNwjEu6yגcfǵӪCknK>]yi.vBN9 kx͗pywy4u\xr7ΫMލfW \8;d ~"2i5ԫ.6 "2~#PN>S ^@ ӆLtZhwV$גS )X{+pOzl,t DONHB\–@!%rA4 {(%\/ו80P+0g7"ȵWH`!II5"ܤЯPunW*Qe;ks5ҊP" թTsXOׂOK־>-ED0ށWue|"j Uʑ:Ȭ=\mxjI@:DRJ.IyM Psjp+U=mWP ʾk.UQ`V6m! ,-v z?Z|t`&l61u;8Ὕ$u1UPh}'6 lP!% FhrLXM!JSpu`˰`SNAfraœ6BL2_S] ,,~Vߑ[ l.}q;sF͏1wszmA1tIRnLr}/2T^)'9ڼZ)@\uG-yobm7X?.W[4D+ (KHR&΢fID@ \m$su% pBAj {vv'ZI,(1TcGl DjRddXqQmW!NexiJfsXƗ %U6v|i*k!o4}v"N KT.hBBFw5/K4KHOAΤ, UT IFtVSUPDiStӠ{d5 u^VxrJM( جaUthjXk}ۥ/g>M:ϗgw~L%is}5W۾ZFΝߋj%EW'l]}{wypxqǧOOw[yͤ endstream endobj 13 0 obj <>stream 8;Z\r>n4ap%"iU=Sp^REpc9WaL)&4;e[DqVU'3lBo*OuEmfN9XQA?[$Z`fD "CkuFC4bfNCq;Li2JOSARUP9%F=Lq3\`2uTXe3BSB4TDZc9ONb"#jhHa_WXN3>%fF #JH7&eXT`G/b_r^E@VIP%F]I-7Bob8h&#k)TAqd/FM!iA~> endstream endobj 14 0 obj [/Indexed/DeviceRGB 255 15 0 R] endobj 15 0 obj <>stream 8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn 6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 7 0 obj <> endobj 16 0 obj [/View/Design] endobj 17 0 obj <>>> endobj 5 0 obj <> endobj 6 0 obj <> endobj 19 0 obj <> endobj 20 0 obj <>stream HԖ{|NGgfy߈H"97l ¶. AHh4B5"%ںVj,ooYԥZGw<3<3sΜy #WK?zMd)iY7&m\0'aY3 9qX=jGTC@T>̃͠22'%Q 4v䨴TB~ Yɾ')4^?53]i:y[5jlv 0(ݟ5&=%KoKn܅Jc X2Ez`pּܝf3vk:&vꀽŏX%u1?4}inݜ@ҏZ>4^Oi/ Brn5?.FӂsO|&g|>bdbX ^ϊ\1S$1]޼\> P)k S^$ 'LbL:A :]-4~v-Hki FZc-P µE UrEJ- gX  n/QO :W:D-EFǦ#MW&2JFV Y$9@-!r"gr\+Oe˛|uo=HoU1zIgS&}^X-V+D\rE+jV_kCk5a}՚jMd~Ȧ"izci>cq8j9;qӸcܷv[mmDԺf*^qǵ|Eޏ,Eꕒzg8z[z"&ӗ1 z.p#bE[Qq[B l*cdk^v K2OBLɍr,iY)myO7z I{kDl=ϣޮkg)zO>S/:ԣi1ژf,1O_P8`1yWc%Q6Rbri.?gLqR9Lrws&RGs㑳nss;:Rgk̙\ծBWk#nLGXH$Ku$9;^WxiObϤr}=>>=# $t{_{=mo^܋ҧ)nbwPS_ I."EqF8uE+_I_[\{vRqovuSL :`)fğ6rMy/yY.y֋2OwG<˫7g ͋/O D1H]ԂUJQ$WpuFlL`/f+xȿP1(6CA+PRk!!^$>7MFb2ph9xYH4[F,s1MUr)"i m77;CC X,E(V# kb4:X'hMg> ~h-h=*V'JGE5 c?@)Ŀw8.8c荳x '3n c x. '"Rq)7&qCqcFOSYxqEb /LW1M_}q F:hj\>RИXKf7V>PMbhUKtc 7Y?vueXwփYO֟%k:\2;ľevc VNR=vUs<*ׁ\1= `83 iΙ\7/⽢@MF \r^* ,wbu".||;}^z;N'c>7gtStRQ ]qtz]t&%_?R! I4Y0i MihAC6@d"=43i Z5,xi耎Ȁ ?:6d 'nGowaCEa0^*[5XuPx [6c'{VMqq =!C' ß1A#F8p1}SN˔_S&7p7g1'1_`"$|0NQuA1F)2&LLYJ0 0bc.`6.b2 *"]\b&$q1'K(KQC<@x5G()Rdƨxr;nq lq[nɜĉܘS97܈[snnũܞ}ܒ's9t3yQ< ͅVP*ּrGT/`8}b}~Cr2tYTL"NDǖWM(\qve3;*\܎JWʖvtǎƸmv+;پ+3YwWo>3;&Č3ėN00sw`!WHK)6]`.HVZmYVZJ>JǾR_Zuj~gl@ժR99e*տk1x^LZ,ް hM}a>#Gh>c8죱ј}4RzIi:kz]+PRNZiT `JAAYp'<` ?Vb <3/gSz^Ov ߷!ؐ?H=q9Eeu,i5mZvN3';_ל4cXNvT'g΃IP"=|~h(?7z49e~:V[Wk‡mnw[>it5pO)Ζ|mm>wv~@33H_$hu{}f.?gjAYߊE|1j,ds E2¬P)vk G4o{l8B al,pp"SΦ ȩpv2RQU1p"5k2j^ሜJO!<~_ t>78roRwگGG&өKڜX4v~l֓ѥ)E7sSR1X0l)9TE$E*O**k`EH@.;T6tcET-:Y#Wg.r>W.JGǃ=n3[aߟOS\ɸ|M7RԪb͐¹b:Wձ : 1*EkU #^ՙd5ӟcD9'Mfvn$>?p"_9]^+!r4ff@M|vkT-24͜:xMࢉo˥2M_PV ;^bUP7wƪ)& o,4BB[~_1V<(iv q;S-"=;x0bC-KCVdaLk Y0__|lM'Ŧa7#Pֳjpvwv;z|Y,Ƽ %f3Y> (*U}]6O3ע c4x]o\6З?ر˚]3-"s^Y SF2UxOG{+-8mrPޜ?Qs}}z$ѧv'&!>籅~eA&O6hBU~V>fC%-CVMiy.eQäTdt>*:Y_WO,@6R_d3%+(q =(MP^2;iUŪPbD7Ɓ 1.WSk)ÿ(^j G/ƙI߾bTjf'_ZD-Ʈ 31݂;MncQ;M"Vi,TzvkUWyH2YףH=>H.Tz3S{2 !̂,e)89 j9ndiK%i>AN [x#GJ+Dûw?:~qy20bs8Sl[i/ਯ*I6 $ RXyAC yZH @Yl V8 cǨZJh;Sꌭ-3v֪Ŷ:Tcf?w/nf>s=sν?*DTUlٙc3N"pN eR+x= 6q:;EfZ_Ұ's yo<w<| x*]1 EnIڈ;JgPjm@i&H̹/ș^59urSQMMy~ρ{3j<[2Q*ZRHK> "2ˣ{%=i [w PXyYC$KWsfĀQ#%B@.d0QƎE0H >8La!}f9q(&rbFA(*ra S|i9}Q< *mF2E -?sb6.˝wn',__W:n4*/:X{}c+ikl/ ly"/X,OWHM鱬|=Mt/927W ]kׂ)Ut$Zl?ae)zN8ll;Muhk 0Bt),P<3\}^ʞ,CwS #.x.wlL̓wk{J]bKOȜv}=<SqR93}A?_Ol<+csvs{E $kx-;ujɬ}: y{A/gld> #{-^:M{(8bM{b`π̛bqY1O}sĸ`& I>^~9"1!K]qWjdV BcVx;_K_J9w;e3UfF0zSzpgȺ^o9>{S|q)G?>pߓ}9Zה:uv]ogU'_.v o]՟'Yc]Oݏmuٺ\'zmpc5œO~/37\*jE,=.ߣX`;wmWL&>O)U+A 7٣=;쒔OBmJǛ 2^mqS8cd ~$|ʹ/ ?IRЗ)0gNNDׅq>|g]!zq-~Gt $-Ɲ徃̈́?zw{ Ui䁙IK< >Ww-5iIq'[>=m~"uQWe-[~' Aw=J37d}:a?h!=FoKᝏc7`@t;NWRs 18 A $H A $H A n"o4}>M,JVJ#VʿlI'#_&y/+$J%ʣ$@i1}U*7%hg䓨3Q)y/;%JmoT:uuOo_lv5:CО5 ;B-j[[Ў?lnim7ip۶fU# MUGF]hCnZQ|e=TK*rظ ڛ[ފ\vvj@~+r 97Jn6D;5뺬6Ҹu!ڂدV=Yk[tZ;=£ΆAX?Y.[v^lx> endobj 21 0 obj <>stream HԖ{|NGgfy_"7ytiڊK-Yu)%ْ RwvRڮƢAHě[=.u'}7X{>gfgfΙ9@Lp"?A~e_=*mtꤑ3tcz-75^ 3SGMh|t 6JJj̤!c%%"r:SM~)i,_Z'S֕?`i&|_C+i^`n46 h"lCkS\(wM /|rJz>r?}_[;'MG~ܥH9^&u%j~)x9Y>g|y._OJ1E/&j>u[ :3z` a0! )tL4q~]-N!r ˱[%`/ *Qq7p̯I7c1bb OJnF|؅PR):g7qQ]/j~B]ZuNׂ$%ib&ybJzc)x?#2D$f,QWxRыq ^#|EhxQOxW?%"@0A" -tDO!}A*kAZc-T5iZ@x/u'tLhGOD,UjXkŊng\p3}y o£yGޅO,υIRkH"I\uIn-=ꥑzX%|#ƫiE-~SBl(uTF2FvK)2S"N S7`u@\])إ*^@bt2yqFPЇ8h%Jb-2!q#q-&qMx\&Z'^.!bb"fYJ>BV"Zb"P WM93 _Uac+Z[Dx_ID"w'{`:ſ?w88C膣3x'n c ށq#ppɸ xqwq Tcj0CQ1Jd)^ԅ/(q Qi>耧#Zj5)C':̪{}6`7);=X,eXγn;zY/֛ d ʮ1!vaG1veORvaeeg«<" ^p$=NAL4L.;^JCKsAȍ 7偺. b8Nd||;}^z;E􉾁?%/MtTDt 4A&%LF J**h`aTF>@l܉AD'̤~![8X.^qIwpG;lD pCG ß0+F=}QS0tF%^ 2a>x| 8&KDwDq+J(9Lטo0 ut\ |٨\\U,5:Pź %ED='&{H^bG&RQ,%Aj(SVP2xRR5ŏ~Li 5OxZIg?6݂_R[,&⼸f)xFϊxIV9r8#aqDc8!N;b/Xɘ\+ QVz6r +rKəl9Z^&s;:?w[V'8G!q|:_ až2}+ikĸ(`#Ǟ:ܧHX  ZV :ȑH'Z}ױT}_ₙ!e/ӈQEEe ~g[ (TvqM"96+`(7 [څ;b*|Q7/xSey7EsHt^2< 퇓ٵU& ldx*юTI4ǯlmhYQp;]7|G%K=J4}UR0bUD,AvpL8Ubo_y#y֧1#9X%'Y}F#Q?t&Dz~8悧 Tfx}zڍnܝ_WHrZ[?U7I`0R}2WUy3FU/`T>|>}VDo)%,*"&fZiajcKfv L8laǤ+[1ve+;fc\ڎ5pe;Еm ܕ. bJJpwͲز6"Y-Nxg˖c+ǎ!;I0d,,c&eTQ2N8p9#3";N(\"HT?T#tUW aF 4:A//؇ᨂ}8v}8>`!HěiUobᡄҋ`"z4G /6bG|%ÃC$*@#CzEq≊%UhQylIc/îFr)p7 wLa=DhV"|@LG x 9`)]oI@5 QDiqT33g"(VLk8grs&BBt E/smr}|<\ M? ^F7 ޮ5Zi@9*,z_3 f@_}* 7 MW8Dm" ow߷ۀH~VV5  #;an]{8JDrcZۈ@ GU:,Hx8Lm>T*T K'.CVr,-O7ʿ57mj[#t"O;m϶gZ_AZ"5Dgt6Do $D~9ܔ .JJ,0HlN Z'(Qq0& r2$R!=9= v0Qm]ͿidIdneE; r0r+`H6]H%U7N@J;ZK™<ĥG8jWK>(Ξ,_n˳/bC i'h%ŪA}QXGmY ˁa6C{\d҆Ih}prD(wnw{`vh?f뗕DP}rerr,9rklˣB@R5+,o.Z46~cMdLk } !3 $D(r$m)bQJDQp"$S+NlZK~D^ 2<<<9 =5X:TVK5Lm+%g$@ŵQz21zQgq;{%=ϦBŅx$9<\s8;Z<1E֓V<~1Lxf#>??>3r8 PuϢ29B qsYp)x) C&.'dҘpb< .[sk#(\]gq٩H /)]L&{{SVyOMCD0WfslBgv=;EwnH 53g.s X6нES$0K C~aWjUgOy9m [vC\|h>Z̕oB!#1KnN(=m `pmjZ[I)Crn/'- "DdK&jMp8ll[QS2ܲf򈳆sIN6'kJ~/Rµ ~:~jdvb!oiupm"1e!}qIg&#]2ftɔ  f![MŗP^N9Z7?_L#.?@гgGҟ@|jc?}Zn /f~Z~ ? C>['ϲ9'x <<_Q_U?{,!$BI !$ic)`^D%4#K5!IB-8*80c;>ƎHjRlPԱ>XR6=~MB)ꌿ|r_=3<{I?GI’NR6cN^l;֓B^技5, _r"DRzqpl*}@`Cm4eUlwOAEF5sp+0Eֽ_`hKk&K6,y\lV궪H;I0!3zeŭ.T=]rCs{kט= ۼ\d[|܋RF"X }V̺t~2L:iw|@R7ySgn>T'깸FdK]u;WpֱLeozr9R#ɚbV.R8ُ?ԺYƸZΐg90K=n׍FXة#AtvDJ,)~MP\_#a/۰["s͖rP^u]a~׽Mhg/Du9#g/2ԝlfZg^$ʽ+/Q}'jxV%3Ѷ17ؖ2vD2>}bQDt6WKr/}.Kk|wוSVtRRw1S<wa3^jnVԙ3)g=ϬI25&wڸا=~6Y#>i `P@o3 K vٿS~Ԍi~%h:ܣR~Ҭ_??BgrFyy 8 ΂3w=9)da(sd۽ClZ3EMnZrŶK*=4z !wyɵ"˱6r'WM_!qoɉNahH%2[EhD/#Cd6ɶTyl=gƱ[=rM:= <*{r9c'C쿃_'!|=.oWC ]/'cB9}wNɸ2A1p/4hwRQ$)]n8uNiwމ:=|CܭIt.ΒxK%~_>N'%><S@%1gbXu~$8YL8ǸQs$۶fG~/ܾRo ҿ,e~~bsf;)6oB=޺rN;%uގλmmL^B3ۭަ;it7ʌux֠ߎ3=3Kԑ{˗B>NrdR:O_Z=e7> }9{?wL%OgM s)\f\GJ.θ9tɵW,S|e[9v -ߥZeuor;{YNq@o1wn{ԼuxYְPnH'x^>>4bqǾ,m%yA2uO$%.J\9c$CϚ|͂O,ȅH97k&8.f-2d@YeǭTDGtʿ `y4%G^!$_@N%JTE/I^Qq < H>zɇw)ޡخޑȱH]u#;Fb#֡x_|0~۷ԴƆMq!9>Ć#P{wt/tvi_?i Ƈ#Jj8 ^2G(B@uhqoʹ6Q#C*=nZAM# ]($͖sZ"A0s݈n*P~>&Zxԕ8z6)e}{[X pxh+a ]cTmABCQOx[x}:< UA]Ut% O(H3P75t]- jm892Vɥ}o8tWG'7n//(UlLQ`WZZ- endstream endobj 12 0 obj <> endobj 11 0 obj <> endobj 22 0 obj <> endobj 23 0 obj <>stream %!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 16.0 %%AI8_CreatorVersion: 16.0.0 %%For: (Thomas Feldmann) () %%Title: (organize.svg) %%CreationDate: 06.10.17 16:23 %%Canvassize: 16383 %%BoundingBox: -11 -158 519 -40 %%HiResBoundingBox: -10.1353 -157.6074 518.6563 -40.9722 %%DocumentProcessColors: Black %AI5_FileFormat 12.0 %AI12_BuildNumber: 682 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%CMYKProcessColor: 1 1 1 1 ([Passermarken]) %AI3_Cropmarks: -42 -174 581 -6 %AI3_TemplateBox: 298.5 -421.5 298.5 -421.5 %AI3_TileBox: -133.5 -369.5 649.5 189.5 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 1 %AI9_ColorModel: 2 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI9_OpenToView: -207.6665 164 1.5 1520 938 18 1 0 85 134 0 0 0 0 1 0 1 1 0 1 %AI5_OpenViewLayers: 7 %%PageOrigin:-8 -817 %AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 24 0 obj <>stream %%BoundingBox: -11 -158 519 -40 %%HiResBoundingBox: -10.1353 -157.6074 518.6563 -40.9722 %AI7_Thumbnail: 128 28 8 %%BeginData: 5056 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C45FD15FFA8FD4BFFA87D7DFD30FF2727A8FD49FFA827F82752FD2EFF %7D27F8FD4AFFA8F827F852FD2DFFA827F852FD4BFF7DF827A8FD1BFF7DF8 %A8FD0FFF7DF827A8FD2BFFA8FD3EFFF82752FF5227FD0CFFF82727FD0DFF %A8FD1BFFA87DF852FD06FFA8FD0FFFCFFD21FFA8FD05FFA852FFFFA87DFD %0BFF5227F87DFD0BFFA85227F82752FD05FFFD047DA8FF7D27F852A8FFFF %FF7D5226272727F82727FFFFFF7D52FD042752FD05FFA87D52FFA8522627 %52FD04FFA8527D7D7D52A8FD05FFFD087DA7FD04FF7D52272727A8FD11FF %FD04A82727A8FD0AFF7DF827F827F827F8A8FFFFCF27F827F8A87D27F827 %F8A8FFFF2727F827F827F8527DA8FFFFA827F827F827F827F8A8FFFFFF7D %F8272727F827F82752FFFFFF5227F827F82727FD05FFF827F827F827F827 %27FFFFFF2727F827F827F852FD05FF7D5252FD07FF5227F8517DFFA8FD0A %FFA8F827F87D7D52F82727FFFFFF2727F8275252F827F827FFFF7D27F827 %52A8272727FD05FF52527D7D5227F82752FFFFFF7D27F827277D5227F827 %A8FFFF7DF8272727F852FD05FFFD0527F827F852FFFF5227F8527D7D2727 %F8A8FFFFFF7D27F82752FD05FFA852F827F827F87DA8FD09FF2727F852FF %FFA827F8277DFFFFFF7D27F827F852522727FFFF52F82752FFFFA8F82727 %FD09FF7D27F852FFFFFF7DF82727FFFFA8F827F8A8FD05FF7DF82752FD07 %FFA8FF7D27F827A8FFA827F827A8FFFF7DF82727FFFFFF7DF827F827FD05 %FFA8FFA85227F827F852FD08FFA827F8277DFFFFFF2727F87DFFFFFF7DF8 %27F852FFA8F852FFFF2727F87DFFFFA827F827A8FD05FFFD047DF82727FF %FFFF5227F852FFFFA827F827A8FD05FF5227F852FD08FF7D27F8277DFFFF %7DF82727FFFFFFA827F827FFFFFFA827F82752FD04FF7DF87DFFFFA87DF8 %27F8A8FD07FFA8F827F8A8FFFFFF52F82752FFFFFF7D27F827A8FFA8FD04 %FF7DF82727CFFF7DF82727FFFFFFA852F827F827F827F827A8FFFF7DF827 %27FFFFA8F827F8A8FD05FF7DF82752FD07FFA827F82752FFFFFF5227F827 %F827F827F827F8A8FFFFFFA87D7DFD04FF7DF827A8FD05FF7D52A8FD07FF %A827F827A8FFFFFF5227F852FFFFFF7DF82727FD08FF52F827F827F827F8 %A8FFFFFF52F827277D7D52F82727FFFFFF5227F852FFFFA827F827A8FD05 %FF5227F852FD06FFA827F82752FD04FF7DF8272727F8FD0527A8FD08FF7D %27F827A8FD05FFA8FD0BFF2727F87DFFFFFF52F82752FFFFFF7D27F852FD %08FF7D27F827F82752A8FFFFFFA8F827F8A8FFFF7D27F827FFFFFF7DF827 %27FFFFA8F827F8FD06FF7DF82752FD05FFA827F82727FD05FF7D27F827A8 %FFA8FFFFFFA8FD04FF7D7D5252F827F852CFFD06FF7DF8A8FD09FF52F827 %27FFFFA8F827F8A8FFFFFF7DF82727FD08FF52F852A8FD07FFA827F827A8 %FFFF7DF82727FFFFFF7D27F852FFFFA827F827A8FD05FF5227F852FD05FF %52F82727FD07FF2627F87DFD04FFA8FD04FF7D27F827F82752A8FD08FFF8 %27A8FD09FFA827F8272752F827F852FFFFFF27F827F827F827A8FD04FFA8 %F827F827F82727527DFFFFFFF827F8275252F827F8277DFFFF7DF82727FF %FFA8F827F8A8FFFF5227F827F827F827F87DFF7DF827F8272727F82727FF %FF7DF827F8525252F827A8FD04FF272727A8FFFFA8FD07FF7D2752FD0BFF %7D27F827F827F852A8FFFFFFF827F827F827F8FD06FF7DF827F827F827F8 %27A8FFFFA8F827F827F8525227F8A8FFFF5227F852FFFFA827F827A8FFFF %52F827F827F827F82752FF7D27F827F827F827F852FFFFFF7DF827F827F8 %2727A8FD05FF272727A8527DFD04FF7DFFFF52F8A8FD0CFFA87D525252A8 %FD05FF7D527D7D7D527DCFFD06FFA87D7D767D2727F827FFFFFFA8525252 %A8FFFF7D52A8FFFFA8527D7DFFFFFF527D7DFFFFFF7D7D527D7D7D527D52 %A8FFA8527D527D7D7D527D7DFD04FFA8FD04527DFD08FF5227F827A8FFFF %A827A8FFA8F852FD23FFA852527DFD04FFA8F827F8FD44FF7D27F8275252 %F87DFFFF27277DFD23FF7D27F827527D7D7D2727F852FD46FF7D2727F827 %52A8522752FD25FF5227F827F827F827F827A8FFFFA8A8FD05FFA8A8A8FF %A8FD0BFFA8FD07FFA8FD05FFA8FD0FFFA8FFFFFFA8A8FD0BFF7D522727F8 %27F8FD27FF7D522627F827277DA8FFFFFF7D7D525252FFFFFD057D52A8FF %7D4B52527D7D52527D5252277D5252767DFFFF527D527D7D7D5252527D52 %A8767D52527DFFA8527D7D527D52FD0EFFA87D76FD35FFA8A87DA8FFFFA8 %FFA8FFA8A8A8FFA8A87DA8A8A87D527DA8A8A8A7A8A8FFA8FFFFA87DFD07 %A87DA8A8A87DA8A8A8FFFFFD06A8FD5BFFA8FDFCFFFDFCFFFD2CFFFF %%EndData endstream endobj 25 0 obj <>stream HWnH|H^~Y狑YĹ `$1H/EoЎe#Æ5ꮮ2&/2Y|E ][֟_vo|G߼>?FGe֕M0py oqض٬'Uݿ;aiE_uxnoLɡ`X8 =iXi=Y;߿ H(ںqrBLh.q[RPM-%M~*(?6}mz1+}^яPV]88*ыpԄ+$We͂z{͏pD4 ow7?Y7i:fţ!Q[gqc6x$m_f3Xge?.8ԪtE>0fiJ0;#Vii]-g:WJWuedK&!ϔ!:Xu]pc0-y_ApdWlMfau1Kç{ʳ-KsQiׄw;]1֝RY|]?vUW3ਘF/F_z8cOB9rU,&77u͊, |}㘚EMߤ8B o.\#w&F%-}oo1S~\ˏ7i?~~iA\4b? d`xAp? 5>9|ٿ@HKVNwxXzɅ?C _^ϛjtjEK?Rp"'Vr.NV;R6\1'6A(jƐ| jR!/.<9! 9 j iNRp .8HJG)mI>,N^*OZ A[ AF3B%L)aVxIFѓ3(JwO.aiؘLkRadi,(&hi7{ut巿Fon{ӦًR?X&`Ǣ1b$nLHF'4C|@Wf<$PIpd @}_~2 dQ9F5t f,J tUL PHҡBʁ_98` R K0,.An*9$nrABA |(("@Ep6bi *JhA)l)V / ) "LֳIFB2GHyH⡰`Ŵ؏^Mc!jaZ@}?2$|CI_! YX 2ePH"v zhWS04d&Y$+qSEVAUP~ _XT+"2 DGELA?쑎e#ԺuN_J 5TȞ  Ѵ=S\d JccIU@>@0R{HZHPX8N"@@!=(J* Z9d0w$*f(+G?@4gLa5V[O455$iWC%>dj)h* ռߴ'CFPrj{TvJz$>f$ڑN$Ah=wIKAX|C*qE<3R*ةF^ZRb%ESSS~@;"$lBo JC _<}ws}!<^pA'_аf^v\Dd-).%,d;Ruc>pQ3:2)9i`CMtzl:B-= >F|$ozQ$!^鍡']v;zW}ysdK1NlE$FP!c5Svsat]1$-mT@1҈τ5,Fyآ~e+ YqN84{<Sg,)|OIs]MBj_Ou~ LpEV):& 8;C:EVA*N)M^7Hz[MF*FEO6z7)Sk1[ ~nHR36C083YYXl:ZֶC]9+~UUJ-*pںw+0',em\(?#mb6D1u*VU:G[A"uCu"Q)<E61z1&'A4uۓ}KQo\F91fng9Du{ pcOmU9Fpe8'./!RTÏ}GuHT\l,2[ _rv6-jh'Uo11rMFŽwmXoH? nDUg)F|>9 =L@1B0FGX]Vkܲ#JCi)FXj%ƿ!V9Qк,leD MAF+Ѡ07A yȷڹ;h9ÍscKY>4pr^VQZmI^ ~'1Ex=m6ǻ*|ƆR-aF'ԟOkfLiBC}A BAV10PQ Dl["oK(؜FTG8Ha1Ю9MgRa7@9(\3illCݺH^X*n?Syd)g>BÉK_b(9N,tblRe;K=츔rFc}p;C}׷xv˧ԥ{̌:Oo_xqѣϞxɫۧz7>||}Oo}٫^>ܷwoqӟW瑎śt U??xt~?}sգo_Wׯ?]?}Ƨ忺Q.ݣe)˻D ç!QWsv9U@,&`s,>~O2$ 'v!,P}[_jU}4\ӽ3&WG݂`Sӄ}fP5o$f2 +!*[dVi@4+14!{uWzYe[izF1$[_ sl#>f 'x2z_lp]5H Kbcf*+?鸾)m!?KgR׎bMl#Vz|$<.$N PzU\:%Tn.֣r=ͯ/s]=nr$Ej5`acAtV94/%?pWg pB-qϐ|8:AH]p9Z'&BB$>#$fjңN,6Yr$""7*|2w2IOT$nncqjW}@_ήs:O:F-4'1SUǮzjE[|i}}4DznNdՇ=HѢEW`;Ϝx`-OҭSf)݆z( 2pW0iBY7!PnupX1+D%vY%0&R|<8#^lbWl*&,f{XG=U3ަ_[ٰKnJ^~ҺJ!)}ZӮ7)^+sM=#Af}}Kj H*B{#X9lgo-H#\qNtNMd$)DBPdLWdj/dqLjPV] kDiBOy(h.ߨ Gp:ӻ"}UiN]#w.E|@ɯ='rE{?\) PT'Jp%W* :`-G_ `Ny]cPUN;ɢ"){a,Mճ8t~Aǩ۽nT9K3:ԡ"0z3( ՟ٮz`QKY7 `r]4Msn!z-ipYuX&nķ5MX" ;L1%ԤaoqʦUKKA5Hvu[Z<ҺJ#Oܰ#fp].&Ke3P6`ߩVr<9XK41)+A 0q2Y,Un@+K SO/Y&%@Ns@4Ч)s1(of (=q-6CE#ljKwr*Q{pQP^ͧk2R1=өC=8"6't񱭏GTm( Z+8b0P̽4uh{ D%֜T"PH-@RJqjGv)nڡbKb_KØܷ_i#s/7a\TX ki D,9 iAM$k+NaSɊl$hO넞.q< \KDZ)>YHЪpR1/Fz {'F,H2~ɧ(VE1 y4 S2`VpI^Zq`/WY>5OztUGfqgO߼h@RUK w,Zz,EnDI6& iԾVXbTqzyXFO B:f0p[tEìu;5ss# o"*XDܞȦĤ#̝q$Q%~C<T!  gBE|vCh-*Qm~r4hw"D(O(F]T"md5Vy%V"h 5%f - 16H3#Rqs0(u96p4P;VwW>؞k F:T[NLLйVDb0Sޥ`ߛA8JT#vVK{6VCXdkٺ>>Uo,\Ro8ܐ=nne7V6xz3>EJFcLqvf{M81֝b+XL&,Z#sx(5u &)1SYgaM"g87v JkIzi*v95D,>ढ$+N ;Zj5{!yœ3O ??x%T+{'G$֢2|4Ǿ|˃ʜw36Ad=ϾcY!Zty~Ӭ7Jl{%[Iyh7ksH*< P5 !WYqHrR[.Jj.s8$y@}14dߣ,_kN آ9(h5Zh&nY0 k5oܱDKh.&ʲ #qt˰e? xzj[c0<}!hJ}K?`iQ?ɬ[eD%c4!aC0fDMDA_O32Vg}`*kJX1C stޓ߽+pN(m` *:oGURw04f=D% l^V;LağWmi5@4Ip}آgWn}WRpmYb-سxU 'jH,ۢrvƕ*McVRy BAE{qYO2BZ%+Sey[ BGQ2>@v*e'Bj$J/Е 4 7^(Z˰*b_rhᣌٜuk`ҿ4@Ix5~˚5TK锏%Q"U5o`eL$:IPC8:w\B}Vσ gRkn@CP ]Dų\^NjMk8]Ge>y*$Jix`C[37t༡y-*؉uP> VA@466x"%e#M՛>=֭&`ȱ} yys蜲c0P a ۂW5Jt\7Ma#S䚄UT0ދyrK4t-5}#τ-}D+Lŕ>#X\gĚC8c"[袼XL怢G(p;G 6A@l\)m<H^^agpiֵ~Ǹ:}*1{jD@ *iah%}Cj~~j3WWU܇F] eĮ.I3h̨U⇂:l1 xslz6 s1E'Gpe2Mt#{T7# ('G,sH%B2RHkO J)^!Bgb-_~%k푑PjO$-EZXff׹hY6i7;OWe܇[ @y}^e N05"TLk3,~s! >>9'YzeStʵ}3~JeU )?cqC`nx&IK QHKJ-B"8mAWV@y{շRYSuUW&kNH"mKS)}7I[/7߾5ϩuHBl^Cpc9 U d 4RoXo qug?ˋaVbg ؽ m^Uꚇ)Qך&IjմR87!mwlb'SA[2yjEϦЕP m( U}\ )yP:xdsuo.߽bSǍ{Ic&X ř)A|VYHbUVZkE 4o?I ,2eB) =\缚5 {b dk!R]MfkȲj}`gOL#^#E}KZˌc_WKgՆڔ)"'{;/__D'.-^u.jQ}:+1ƍXW\w}%k*dDnþoZ5G Z,ö@χM?=՘!ܾvƺx)ңe<fD8_7VKG^: [P=먇!,hdnGݵj# Qn OY]Պ3cbu54s 1/nKLW(- #r&r\K`}KoUΩj(ʩP3"4 &q,rq@bM2K;&[Gɔy2^t읚s!x!PA+0<≙5k]O⃵~ -w 0Bqp54j '/Eg2ΘӨR1j $wBQ`<1qٚg,o5&r9 5a==i@bCpPcP֑ erЗ&i_SBstoOyJ $_: i6MɃj-U-绉ݰO G6]*-z1RcţVe*z$szL`ǹn2kb'2a_KM9`/S(BRQ~vj`OiS>y -mH7G]m&,?^0F8X xe.&~'{ƧGF3J^ЮeW.lbS{<2]?c7ٯݸ#"@22t=y)'pr V &#P )(.3Pr $3+وp$:㨠db5|z1ѕBgOD] ; BH36΂>,UbFK:3=r?<ķJ%= !HqPJ+KHu,'AyESQ 9XT(C/|gZ#$(rs5ɤX@ MIC~+2\M{E]$ KB).1%Oe7vqRĮhH0uS9g3ƶ&nSA99os)kv=0t ɤc'v)-uiNB$ cYA%7PΚV3RD÷$Xcʋ!&0JZO"&R@Oq pL U>:'z z@LcezKs,8d&,Yb\.I=2īM@\#1}dch $V8F!M= ,$޳mgS*-f۳{D" MZAsᔉyvELbib,Mf"QxE^b e֒V$b,)-\̲lY^K.o;0I+W`β(レ'N%ֈ#Cj2'RӲr*Z{$:0PMEʖPDސ9P'4D_S& h"P@-%sQqQD%{)4/?Y>EiF%8yk̈́@ 6MC*YH_gR BGRKt&(XN f'VQENtŘǒӪ{W޿#% 0C(~PÎ_Evjش~Ϟ%^.~Σ_kuOWmOׯ/E_?s^oޜm_px-*G|Ca?[hUy9ʐjdO' r*stJVsծ*âPJ9@8طOf}|}svq-mDEv;Ɂe,TہK2&ڌ-C, r3|d<6=ub#6͏PIt|"&,F FDx|;3~SyRHf~'8~YsҭeݪjOcxxKl=IU}Vn>j),}؎Bb|HGj_A#$h4V`;\ofi _i@IRh=+ ZƜ,I?EUSW'zoAV;gdW$Ũ6jSQq=TjŤ[v9Nnr2/9Y X#V@@ 8eDVL#[~[w^=:wAzN??:<:ݲ?^o˯1=gwwWyw}sϏOZ~y|}}5ٞtKp׷7kR3f>:rRnnžGi"8/:sb"vei"u"x%ݲm^' J䚤IIĭu۱;cI5u}g( cQ*Ցki#ЄEt:fH1twTXeZ\ G&>9y"~<_ݯ0qU9L$L̼M?S7[izR3'?d\:'sONx1V{j+u-`Y-eymT| ǘQ82l>R;ЮfL}{=]yE-;g~bgK14Kgk^{>c;Ś]&l[r|/+UBd2KV8M >g19i.kr˗s=PD$"foJ6UGvxhl URowwi|Ó )恴F+tS場ޮo!d'|uT`"鼼*K Lw{űqzN;W7Q-;6ؚMhyرF7nc'xfx7Î}ΊWo7r&^6<[sƋ#v\͍aP8xd|2GFdUY"h ^w_np+`/вANљ;G M'2YwL*&hݎvJwᇘ3' :Q݊I1|11ҡ͸Jeh@&-״m3o}f!Wk?2w6H曼I&gf`nLѨGiGUv$[VGW0zwq 2T`]~ײYE:z)L6O"ikejP>h6%QF6%{5aDmO>`% :۠G 1U |uV1dq+WUhȕkCzuU>v m=GQ%3Tv lt I[t~%{QfV?dɛ.+wRO٧5O|-ugw%דi` =PI:G|G{71Ƅ#B?wD\o8dô34\tw %: ]z n+ShO ZWaYLFW9d4C:܂r{LR;,} 䓾$T~`}[zU0bo$PpѺd mV$/,i g HRm1MчV-P97'+f}}/'dsX oaMXU/H ဆJd?UA@8]?ߋ_?;fzL1&MhTkTbXtX%bѠZX~pY}9*WڨKGB@uPF + V,MX%]s_T9I\Xڛoʹ?QIli؟/6&Z`Tm'w^`K>0 ~ Э  +FB8逫cP9(4*Fz Lh/p5S)7a }2~V(mQwjFKK:|+(1b}HE? I*ryL*E)z!#JbWM S ?N(8U:k\Э7'99dD&7 ^SPn?4m|/l^OgX!֞nwp ~NĶ byF]j|4 8&{-:yVsɣۦ~{oiŢd;¿ J3$- Ʋ_4T"lVڊ,j{+ J1ScAV.Xv}4ɳB2, UXa٧$'D3de<:1d#[\ȩ73=3;\uYv"# ok5N_B'trrH676+>j[M>̙_"tNs-ɸ=F˪GI^? aP""i8K^gGj@.^y(]51+^-)bjN`v4h  P- \mK &?@]!aT1`U=?> endstream endobj 26 0 obj <>stream H˪`.l]l(Bș$ ?% |/xKya' S+552TAmJX d_Zl ;b,#ɱWQM@Q˾qc]az8?\h=}Y'diN;!AP6/*!bhk"[k'S{bS8F IL v JsDd73Xb#v!5|+UWZ uVy+^1'WxE)RU}6|P2H@l[7O X?Pg. nyԄ !3 ӏgTԊ[̡R i Bpb[!mͱ}15'YߘeN-Q1 ܘ|I}x_!{ۓJ iǡ!_> YjyƂkunmʼ{>C LZL_gT|O]OI_}?^O׷;~;kX}W,̯f@ZB k~С+Nt?PU2m1׹hzDy+o\E$pmF4LCMFNO_hg N/fBllw`%L& i*j=h:,/+.fgNfpf(`;WޜdϮ[ge#u*uO;gBfy:Ekt].c0u2P吞-%?͋/XEĄ~MQ~M!\Wi!ZFl?⹻jMT$կ)w)WyhtLY9&|k{u+֯)\/递_ 㭾ХnFYj03X[VhQn<xulB/:M`8_?9\ߊrr.Z#0Y *~ jkyEX\!d?;6El6+`Zo։ rFW"SXQ䲡ױ=hNt^\]/Z(d^SW,P;BN25,PQ>%GWՊWѳWhɵYG%>wz0P@7W&%—l~.fϯ>ӎn{sEkI8 <[Ka(2{N65ajKSWSk_9Nnfg,,t]1chEY"F'4;tJ2x˖aNu` W0sLG4/Vg mgL׽J@9OZ1cm8GeǨγZa6I J+C7C:#`WSK)PV+iǁQG/G+rF=zuvNb6UH*ee2E|W+5 'td(('u\kP۽bk)`3z-\/,n7uKH1 |²p/ھam砧f\Y!|lM ?hd3aeM"D%jn^#=Ϻ~ΣdWڔ}O1?xo?zo'??}J_4+vg#2RbGT}*Ⱦk2&`Ⱊ=hNƌEFy;IZ?؛&FέlTI;6p NĤidGmhS 2a#*Ơ1G>*cZKhMv+\˜1^Z-;*VU]ŕcHm@VюƠkrsޝ& (u +ħB"wh4G5Hsde;ڐ Ʌր#Ahv4TI[$Jݖ c5ީK\Iؖ)!;dG=zJn*9b`;(j4 wC,e"h.u-7W8 `o䅦֩!]ѵraݝ RݏL!cQ4Q2R [qa1㢖 t@LsjrgLNPBVw/UZ*>e}+9b $v!2"\ ߩBL U|RWVDڋ@0iNckb!cG\ȧ ZNS-~tAY1PKJ뱉;lZa2-c#R>ݺ.TZ/Q[v4afiʴ UJm 9-k9c6tC+{e6.7 0u*QkoŲTӂT)<97+ȝ/ rhȺRRJtxf7S )l :gŝ:ʓ\({i=R!gJ(ڶ,U鴷8y盵6 >w`upi=Akeᑪgc-ܢCi uoRJ'hc3l&xG%6TYzExY#%_C]\]EX#%I7M3%̚t.=|k<pk`tifcHxT +VSOfhyq0]HaGm3IJ% dB N6GIWF9u6:}GӒ6 z|#\pˁJ:I49uV |80G]W'ok[3Xz~ŹfÜ | J W27!/ Ɩs jSWECO*㺗`uVPYY>.9PrQ#9%z6l8o`2= U|¬ׁR(ˈ`l*2A ۣ)C aǽqg3"ud@`!LP7+٣Yプ^i' _M=\:9 ^|(/o?/ۧF-ߤM^nîdf#2&PP40lL?B:@eH wPVy>NT?Vj;PUMLl%%l7~n5,<c^b81:jrW<`rv:?;Ncrqm, ? 6#c}b/ظA⯢X XK)~"΢q`n+!X#j>}5ݱ06ư_-P6s[uWBeZr4Pv3{Ӈv# ZDphh`nl1-ٳ\cq+B 6/;]C}xU{co)6(ڮ4٣WVJRg>+CBw ,( gW|7T㗵DPgEqgq'_E(Q%~ 刞_h}ޢܻsޖ뿚',O_gjۑ㸡_0/ Ӫ >?2}ZB]l`'7oשW*ѡ"ڝPъLhB?P-|TK̴b>31Ӑ+}ng* ن~-3& *ِ>3>  >3hYb@^Rf e\ph)T( h %$B}-pk @TTuCk6@Dp 2PjAH.\UrћV3|ԶqxLQcKJb K~qV "Ъ ǁ(! eb)Pӈg03d=JHKmH?{H| ]nHG;(T`O6j h `$^`BA J!69r.!LCXxpšWRh#Cո(㺒4+gw"X%5jf;V]"`.E0AG/hb_'gG B(NmJ?qy.@RE9=E7*6% Dڷ$$M*sH ";{- ʀNG) (ڦrA @$p|4GD^ )UQ Z:S.|Z ␰ O* Q"iR2)^MkOu ç^&8:HӐyAƶdrf\ph邠͍qj ٵĩCC+ڨՙ`Bɣu9L$" ǁvHԭ*T1\˶QM/-KýjԄh3\3L' :-&6dN%Mg<6iro9(U n\.A,"l!.6@%V8FG~4|N1Qk4, T!mKb_@#Nt7/9XD[u(}7Do%erIb͞"p'o]s\K4FiaKRMM* V44lUAᚭ<`V+':i rk u#.;`w7^H#(x1~BBph;q@,FJ.|;HF鸙Wn5dMߜȞ `pю>۸("dBmiuD 3ij砪x6 f' `-qy927~KYSDNS D/:t"qV:3MS%,rV A E8J_US 5i*HdwYGtJRڳ2- ujT;P)JCL^9gYJPn-b3'e2+hquKVE ÂUN @WXUZL+Jhz3 K?RINyR6'\9:׌(;kБwGBVoTWCPVFlq"/ JT+G!?DVlR<~`9]i{|Ī*%QG-vaP:sgiuj6;ځPɀqD"HߖL(d[yZz|DKh(gc'?tel\KDH_9%*:UvfYC_;;Kx rǮS/%=U8HRޫmӒeJ7UZwcזR&m*vTu#̍fXrquO;Vf$/3ێ #w>Ҥ\Sg /J8}F@[jz/)jzn +o<ϱˊV j+ۍG/vkA,XY?9N?9rteZѡycgJzAu6#c:K5OA<4tU*2tP[jM32}XU\B! #yR-N(NFKYPN%@y@Y E_fa+I97 L`Y&cKÎ^'5jap,/:N'"H1 #Ph#F^AYaJSF1Ow`{DE]Ci zI<A f++EĈv\8ի- {aa$[(-R?Tj~vl*}>TJSכ| O??1`}+&gN͗c磻T.zIr+wiO!GXbY{r5C]V{,Q7j.(D(h4"HXnTNƎ RO;h<3Еk8Z(UP6]+:Fo57K_VlyĐ׎'7P2hQMV*Zl. H=SqqX=,nNUP3RE%;2UC T%rqOvh2N|ߔT ~(<__ 7aubDzEG% \Ia0a4Ș{] ,M!0B#ATk-VєQrϭ^][.+ߟb\r\CK`<Å(.`,l "E4Yhg(*:-iOn>kNI[!)':**ӷ.Q݇KWCZ HM/+dqFf3s?J]r~i<ٕ~ꅤ:Ht˕ULeŕ#i8[jvH }Mc>,en7.9 >APd`,2qyXG;J0=Jm0!MmVt%/p auAUF*kt2"S< f~:Fp[ni)tus킛ou3/4|:OW #2f@$OVb''Q-vfE80UC|c AZ0SnB,ACK+'l矰#32-T<¿g;k#Ǎ4|Y|$asS;ԽANg̙z]lʨ3vXZQ5*#bLAo0qr`oG imKoxu8WuH!0#{gouS?RDO⳯LD!m:vԋwE rحFc,0Yd&U s3'X)'ևG02މg2}lPh H_]Z!5f n W/n{]T4neZq~QH!ȈVCPo~Gׇ"&wLՉ@f}eJ( 95R: {Џ|-`)K>[ik˸ (uR u|PUi=џ~ WX{*owIM4F _A rۉPwNqE*VPKӳVvlSRh3ݲZӯf]y?u9q\ ??[621_!lL&[[[x12%$siI62$1dE.XnEk;rt 4*(USrJ 9ǘ `6iT*,V#q*ke|zM (>P4+G&d-`%&4$Db@[!ilaB:dԍ`BRjr]-a{9Pj,,PȎL% m9tn-nՔL;Ԙ QIU 5E,bI:# TW50IIfM@ Xº ԏd"V wwCB?VKԥ.=Y1$KA#^CL)6A\NȜY >oivJQK:71#CNd/պDYPp"^cCHPPPi& j}=9csK2*0u,I&pp\|scm_>囦~# X*6 )GR^y/{cNω%/!*L!uQ]RyaRqC|RnNW*qg0MRȟ 3Z/^rԎGJE,j^LD0.RB K (=K&9WІCJɜ"Hڃt1u a:02/uQyI'e|fIlplpR2M!`@c K32d|0uٌ+ \z&Øx>%NǐЫd,;pzU }A4I9<[FИfz z O ;/ҭLuD\MG*rJd2>PKXa=Cv?zR,;''+Ҟ@. @r= |3L9ᘆ-ٰ܅]RmAS7:e4\rQgeqa§Q&+h| D@z" l)T fܣa&r3>993j #:Toɫ&zӁ@X6DZy# wYpC? "Rتif<]c#Pz_+6eH^QTGqߡ N*s&&a-BI-Ch%jJٲ_߮],Q}bCE\N{q5P^oE,GǢ:w+֨1i~e6[vdc'B*gL<:tw<ѩH'f'ŵק,\un̜ƨ|sc1hWb znijZRݏ:0g%>f[?_!ܲV0U\:xu1ٯ/ 4,j~W&)$U$ӞV%Vi^],\u_ݼ).FܣcwE~c'ru%=ֿڽ~I5q G5t,zS1(DK8Š*hv} 3;`'GӣD:8cNiE ӫ q {xLS<%,̼7Ӡ+(f.SPm/b#::^kUb?P ٫7I4|P]@VLL%37ߦضg lz mOp>!W`A z&.n- ?vwNQ%tJenؽ}~5;Cg"'V{FW=ԁ ):' n+ʹ 137jc M_:2bG# 16+C㑒L]C%\ hZ0'NeUx L3?o~$:!W>XSLV\§EFx͛bW9Dc:3&h t awū &!d1(b9q= ac0-.X 4kVn91j_)ַ]pxwҧp7 uw@Pnr/ag4 @]"&yHWNF U 6 슮lD-Eh De_Nj=8RfiAxs3;:1Qi8cB\( "\)x >/-?\ìLn; yX؊FEIN*Hz3Wys{!9 $X3 N`5oz@p,`m.՝X ?E$Ho(P7,v,]I^cZOťT$GT ,M4  Y"(nwᏻ}ԃeUk'UQ>)t8IBP>WH Ul( _:/AОm^R4GjAqC9-27kҺ=,qw%CժP,mbgU(8DDSpbوI8WJf GlqTp*mQ!>stream HWYvH^AP9cm0L:aq!̅T@RJ^C?oKB$'O?ֽߝzvm|9D[&vP\r:K`y/*e&w05L8a!88xAJSC]DSNh4WƼ6_f%es4/c/"*J+Y\y9 hDaDH9\#M昺ο hx_Cu,Ek:Ӝ)1Er_ +m@ܑN/r(\$7ԦjPX[m1t-W.bҽ%=b`UvMj%W>z kjʾ @ya S'mmkV*e3oS9b_{J%MG1f93PL=b篙dKĽ,c{M`7:J 0!#;gq-W3ɪPlrl swq4pW#05ZHcS l?g_SzbRM],N-C+Cj\7p50GF:pO8 6jb\wLc\+'ŝ`/ Ho,Yd@+EǑNeTUWuQҟáM|q >\8Z4l\ke,7wԨd "S>h◾DI'qOC:,z M D͌ҷ&MHoXăiZVPN uzb6 k?jJEd; 5o?U94~ #5F0f/BZ V 5B@bE! s]%Cbϙ,2jpn>)ΪKAj@}" u9r+f9vJd'8Lv_le5N% 2y1|S##I;W;R&7|暫X\1G,^6Lly5d:>w6[Aɫ:wjx^PJBVzsюe?6<:nD-+M7G `7OS>ӘxUei7cن:, *[7o>|l\7F>Տ&O;?Vw6։>|?VFxw0lEk\}̅ USՏ^ozz<ӋԎyվ75γo[ڱV~56^l7/vn[o-lm|ix"?awYV Lo7s|?չmLdfۀ9Q@g=qUWp>>UXEjy0t)?zT$Mę\ihςDyr-A|R ,]t/YWG 0|rqtl{OF!0G]0$}C'N=5"A]%9ͺU'޻@-$G>޿E3إ21EU*x1Z {an'-W݋t^cPO?J00eޅ.4Ɂ cdݾq]ZEDH6V5sUWݥT9ދ\vt`_*r`N̵H:ߋC(4W_@NJX  "WFɺ'Gk+ *ܣڰUe 6<:B 6St]_z%D6œȬTdB7xPC4$ ,dXL̐A? ۰!(F~")@˸w?ʆP%:,S%bQ _OpD!>fj2 =e(xL20I]͕-4b~3CFH7 5G)ȞS%cɁTU ©"чrkFnn"Z17~ <ZRЗpBj܋v_lgfm̍ fӦ/}$ hI?X7r:#- bm0\C9 q(OLaϰqV|Ff@V|B%+M[?kM򥡅(gr {x`k *-7sZAiXXlCڔ(BZ @-7Jlk,#90EuR&U?"B$o֣1̶g1!m[JZdf$ 2FY|:xiudM;vB ]ړZpt$n'ѢnIa DsKyWrY1, \~ԣNςp>]Ap{vy⁛<}:75Ov?hk>]蒻ǠmkWAD3NwQ ˹spЗqDb6-6 N=Gi!9_`/r ۻbS4:_MݭbQ,`m.*rv-@yf[=}LOb}XR*4v<.`Jo9@&4/Xl\}^*ۺ&ǏCݐ&nK8nz 3 Lw"9T d~nF^>}głX`?wCo]LmU&zOi(BOeq;^#!UrYX,YdIM(:#m+'1'n"AZ?ΧG҂&;*Qȩ~_ @ꀳ)0?TWձϹFyv::N?f֝+E]ӌJ\P.\|1jT8Ӭ'a?%zD~N^] .̣.֔u%$tS"]hв]Z^+"^֜`r?7 6mXdYV}UкѓZy.L~YdYʹ :xr1q/8aq@l`r+1T# tgq5';uO Y*poàݧzu}^ J5IQe*1MR>e!ejv.pWulu_BB_] &fPƪb tX~ll]0^e۩I y3Ԩ1*j4Q"(ÿVE?{so j{Tɷp$|7{Q+yэu#@bQd7W%~]܁ ψޡDyI\?X=Z_¯fn)~$]i3(| +_WoAEd_V~P+4 c>qУ!ng# Y§t!{}\:g|elԨ_ Oh2vrCg"R/Pɱ,o gA^SBJU;m\G^;jKyΤ=r=e},u74KL18Y%ab2;)$Yک!x1ŕm/z7*Y} \T}E)/l\ֶ‰iX tMk{1;l̴XBh}^<xTmn~DV`>w1S[]1TRM4C6( Չ>L.7]E e%nxiwk]OxC!Y&$%\jG;h 42J,NOġWl?#h: ( Pc&0*{-mmL-tr/)Dꭊoj3/^}+Ģ;1dAbdp3j=i(nq61+ T0b#żN@5v澤,Όk{R=ܻxAtHiR(l}p/R@dwJio\JZ{9PzVi8hJt~ !Tcj;Ħ^͋}\4:bP H<⍳] k__`X|Ά;XS*؄Rf+ C啠]"s8,.8B Bn ^pX_'83*0VfJ{lׁUESiU2*&וMxFP~.wWssG"xdYMH}/eG&h"R)>0AF0鈎*n$"V?Ff "4xK`3*1- DnM/.ΐZ97ɇḪo߻xS5h]SK8'~}q %'w}tMY\fnl 4O*Eƛgthr= %rJؤ &wE{_r 32|oϛ+omjGF$oQA:&2 aw%H (" 'k8EfSXvhh_MyZѺT-:ζDFSdW:أuEv_K8ˮ$ 6 N2-5:Hɰ۩mVcWQc{[0^u vPN:&eEӲgӌᮄ{qAGDUu]2׋h y^_l;(;-dn,!ajy<15̕=o|ɲbE te6~(Ё֩y=wx"F˦ރ;TLDZ1AGBAw:p߈u6ر9R ο^$(It+7fskry/4SW\}h{h멁t)* ӡq,'g~]| $$M)ڥU7Ƣt>M,% TȸLW͐8-:0D%49P+VSMgJX34PY`~ 00SDY F[s]T {ے6 apr9I&Nen)hl5`&Y~uH~fz'W\0V&j,D,­sKpSLAe\;IF]j>sZWFW%ghxYsKbd8Ieƹw1TW:0f^!@뢾*h޿zn"cyNJˤkHeSFSF=uaBIck.q,ևbf>9`Zojhm۠UD֣L'ptwD-zL:\3o$"nL4Hz)c*"IYQ$Cf`\̡A2]ORhLW4\7:N6fLokqkl~4kG8S1SsJ$b{[T6f_m9tuU./y?rf*FLHqn C x#w9[3[BPƈ42cCygUWt+|牑0&vݿi6s "mLeCqڑPi'S"uPH^<di+|]p ;\M.z7N D7Q +o8Q{_b6v1 &ZUN:_r.˼f瑯}N-D7_>ֻZ+^7RQ&P7ͅ YdXY:n 1LhX;~- oi'4p7\鵽nE<<Խ')-y`mDܛ ]f|ˋjz5w4A\Fmz>|RK\ R} ql9ˀbWD>7>[Z]ijte$+okO}xE--W@~x ш˶@wmrna9u l|.&.Y\ǸbR=OZa*cZn8B3_1[6:ƣX/}ԢA5(SA=~m\>d'/"iӠxUϽ_4([cKq8;@lmP~ZzTS mAb`>jӡE[ 9OF\RNT Ǘ{z [ (TӸ Od-|i Ell?CϽABt[2w0MςeT߂J|eT'hӠl\d/[SO th⤅fTh!5('otfBߵ ӫFg;ϊTBs>ЧϑRnkz*5<9B Z5r̎}ϰW 0:|:B=~S[WUCkIb|Yq2qJP4ܑ^JHްށv.?@/Zen3UUvqJYj$_,;ow߼?q;m_Ķ'c/q坦էi:{8W4B֏8~֛Z!Th9;LqXOAbGO_g{%)t+P<-ū9b> 1}!j;76R-cg5\z0Ax!iv A-N1˭0TNS)dS<ȩLj\nN 5Őr t޺@&jGu|~>CCb*23Bo[_訄bXX]3eZEAd6uNj4qmE [pÃj&v$++ 0-^MګtZߠl>F=L1C;mq˃ `ZC/m t ݾc;PE 0BBPyߒXAY/Am)EeZAqᐯ+AG3pkId+k:v&?c1w1K%|>)@D=+ˮ+3TY<;UxD^e mQO?:'XsL1m`̄2A= J6vʭx]E 2+=t%mX]zcԌ)V_[`n>1>YYS̮۟Jrz=!A3"ɮJ=Hiu.,֬̐?U'aVVƆ4d4uͷEw~4{}õ^3jRS.ԹI}3Ԍ ? cB +V8I^Y*{%BR߰++,Vz@V=|~ѽhF~+4c ܮOqE(ӴV%$^OxҊGDMnHաOv遣ܟ7I'ܟ:v(Sll'c@-Ip/؛!nw2Cb4oIר4UZ\Bi:D_>2%h FB,}fjC]YCGs sI6Dڇa+%0.,psa/P@;  S &.mOooKP#j[Rm3|I1/L6L. JZq%5 >x 2t j؇6l ^1\R@jO"(cK+8U-[\B+0)DQ imIKA@=|{oa ,-Y{ T@{kq, YC n>sMrЏX<-Ї 5ϚÞT2ՃDuXAz8HMS԰޷%d{tbD}mmIT(oU$V<5;n[BLڐ pgښdt`!X@.`T0*t^"lA%vʹVN;&uRJOhc<"J\ yK CX:5cW:3m{. A˨tP;} nO;K] 5蘰AXj9\жŔ|+"-)w]*waEN;,:0cB @doƼ7Ui4!NvUxk@90`'h%ʵ⓽؉ DÚ{S;x </֝/:gVt%یZ0em(0n`\Bd):(?7fN1R+`u9 S~vd48_;?hhUр1AF.47AYN{>S>>g+p{44ylҫs.,Ԑ$>),t⣅5fQbPsH zE`Yz]А2uI'{.W;.(cZ'|1*yo م $Vь*׊OI'IN>2oC1}‘A౑񽷾EzG6>cq=k"/iy,S?)67d;"=Z4ŀS4cBUrrGN arMq&~>;SGiu ̱,gww\S5y9WkqzKC_MNFN/d|WR0h+}k[buop/6Q钻XG-)|_@ߪmcF)X\tlC5|\p^٫m,v (ipBZG.Ϋӓ4/ˎ6T}OAE8hRێ.prsC! ègwc">pĭmpcHsU\kR3oXs׋a^X_6Z̋(GkM2gԫBW1nj袵XiHmKwú:P2^U@YT\-jJJS'24? -0?CDz@Sʔ`ǹ%"bN6Ay!D&k\c?r's/9/q>Ɖ*M,q `ʹCzv51C`jmBL@u,'^fsc~Jx-P?m'М$ԭ8Xb(͕Ҡ&AM*Hi=u.Zо'ǹ w"UNyM mcuV7MrʝeXX~?l:DmpSҲ uۣ0 |c+>1eMwV:o cU ?et;ڙghU4&Ǥ_ݙ_\ITJo(W ] qXsp;\8D&TPHHUtd9Z]R:2z[NPE^t*}(/c+={P1q 0To*F'OV՟$$F7XLpUH U\ϧkKᶃ;^Jo:WuƯ7 N·Ѱ(ĎV [3#5n45rf2K(+N5'oNyV L)G`!9-I`\`8a'siX7Ig]|*bIea36LF-C#_q$Q-u hibiKGzjJ'd5Jm 5(m`XHL7It^SӋ%1VE##xI":һjؗh)Ҭcǝ#D'mJN1wv;(F)+-ķ>e'qLTF1.u1)1Glb~ч=93 >A̰p#V G.""&Š?[q&-}ΙlGVd$)kK v$3;o{ʀ޽'&\շM NN2OSV`vI7(X)C: ~%Nŕ<,xcXcXƐB 6cy,Ѷ} 1єcދ۩q ou1_cإbr;1'푱 7ʩ_ Z,`19෗Ȩ&W3le tM:} W,s4]A`v96m<]|{w]|;ml0,w+M`T # -&ߎYQKqU|Yv }5&zc p~==vCY/QO@5JRP+I)+qclH͕5xy+iLF{Ecr8OtWу'+`^2svmV yR6`V;fV.uj/[&ݛ~t6Cn?_H&},?T $E Ov:<\v$ t 83^}{Ý/Bl9=F]/\5Q(/ YN5?qs]o|:Nfw% #pƜߜu0/&Ja9tpo|J:-| iⱁ_y `}yNGL .Wo!G ttv#`2mؚ߫*$ e慪>ЄޗӀf8193Q_0BU}'`'Ъ8@3ᥪmcN aX='UB:[6(%짨]ÅUM'on+Kᆤlڑv`ҁGn =xL`[dq~*6kd㜔嗒͋2tETPymJA¶3CzN͠ީ}[36#SMp^xwcih:Ww>P2Zk$2zF*t㦖-N&6O úJxTS1e^,oiKZ:z&uS^`!g;O=(\2%2a!a7 928 PDAUNFaP^*tܸ edYfO"cFr$)%bĥj5Sd(MR!05~P^zE7Pq3=^[R j?mFӷYuZEKH Fju JHg)%'G{8t U?\ÀɃ5C7E^ qi1f~لj7I#4[pΨ&jvm|zԷ'a`or{f;12oM)} flJi]Na]6d׫ϕ`%f!VL>&'vRh1AjK5Qc0q/dz߰3sΙ5P2ۙ 5h?U'1"xGQ-d.) %)B$>A5/Q `ْ:U-ip$.=_ا=/J <>]jԘ.&VF8NU\ep\U*FeH0m%YaGYA۝5~鞴E ]q܂>stream HW^<}>K[ 8 XQaq`I'3?ss﹅پN @9zU&|+vFT2d6=go j?fCZ6:-߶Jb[o˩\??2ߧGj=VGO: MJUX ˝|WThi+*ji!gW#|Nme'^L]*_b͙rasfN}o kӉo#Blނ m065cboŕV@BXːoq<"+^h _QP*lw|icfMeW^H>Xξ P87 _ʉG?(Eٷix2^2Μ8!fNo(GMB393d!|lk]Aq7n*ɺ^-1Hx ceOZً>Vыx0 œc& v0] 'Ϛq'hNJjA+` 2]s1[N 4V_2fSgk{GEJ '^ tLamP/n ٮqB^x4Hho1> OiH6{Z*v\J1. ;4U0{KBK)å!>8ѐBQiq(R(~K{ sP%7:f 2'ƜaGJ#x r˜O/(4(eBLKede'tXveXpwR#EQ-p:A3Ϳ"'?NfA9OC}6elWno``5eKBa  gmӐ a bqSمԸ[ 7( {z[ȿTU_?FU6+T!7ͯ+xoKޕ-|+I6vac^WϠ0|ba.u_>yF](܍\N;!ScAR`.fyl o\q0ı* EֲG<,ch%Pɲփ+ G=W2Rs@mrsE KJ D*vQ/p#Zޖ+C] etgDruRMF͓=<~.A {=u``A h42& 2-j=f{\M]%z [H3xF_p0fg3i!_l*E݉GFAzfXsB{7h2DWYQ3>pi /t]pΟܚX'?;Q}~b_Govkb~ANȻ:-m ?E=ȓ1 Zxj ΂Tj7Wu{8J =n; ye\qSKPlawa=P AZtgjCHB)ٷ+vUhsPB.uOQJH'8On/[Mb C]|Py ".YT9%}` qǾPZqwVrZʏ*tQ OkOg,cէN0=-+*3ѸyC; I:U:Uy;ܨ4+*6U@)9'*lhTW"ЊUJr+%+- c^-Utr̄s803J/\n /qj+r2Ajp |׺$04g,x^K:;x MɈ撙{,Nn !$s@~F8L}1]mŮ|-5ӊ*1\8Y2bi.uJB.(0=vOBQ.mݭ;wMd(ؽ,(ƑB}y04 M߭MƌaX}MIgȉgϟـqafևj_r\u/\%508B4 Rnq籛!;co]TŃYB=X8My90Aկfg&ZhEi-Ro(>Hhά<~L1KW'K I]dR=#%WUSPTDeEb\JT\;2 ɥ`NsF`=yf<7O%$OsL6Oamɸ*@e+'.a:՛o!TE.ˮyKh R.l=m=[WnѨc'.$\oIMrc64k07C& xdj ȡ=j?N1 o\BST*8Qhو04>|Z#.+*] jN7by:z JkZbV;&K +v9f,`R'} 1'd߹7;eL 5#c]\IEu N(Dj6 nߡS[/ j>^Mb V8v!$!Wb';ģ_vx"u%:g> 躷uĮܞwS)P+?>[9m9uIN`{ يXQ8󛖒8q o C L`kKFJh{ѷK @1Rx/afm.dZ|InWB`}ןxukXA sji:IBԿΕ4^|%j< <2C=>tF ZNB0N>;R o电v EF=1>R-{T . ח$wll\+`7`0VXuAP2 PަEVV[n/D2$o[Cm;/_{16> 4z']P}8 ^DS d93HˠWu*ݸMǛӾ/"$oVe?Ƽn5LTBqP,[Iڀ٣ ӏOD9? La{6,d(͡OU1< vt>TZݦK O eJ|̃ /_X/^)y/w&e\ x9bADʜR&?HsU$(a2 kGJ| g Ш]VDv&LUi>k]OmE-X~}a0}fi';ȑz`DߞtD,0{byfͬq`%}Jc'AD/p3 #nYf{Ŝ rGw2jYCcW,soqJt!h,Цn롋2eԾ037}5n 녌7ia ZiƋ"-S7y¥PqenfN矟 UWr c'^zVf/EW^zah9yXKD,=Tٴ`5Ϩ RQLjPqtNcgk. gfy}y9"$ЈH|{/ { 1sccCA WK|xumif=Єcw, Q^*Ҩ(Y,3K"pd b QV9%b^E+~j /FФ"wP*@2/ ?`Qk4DŸ8#AJB|MR(2VR`S  :( M yNw7O@DMN;TAtyDVIs,,noL"Wx$5 cWmRCq% #Hy2e[X rp,M11bGo-؀l" R_%^ >!f t`tKeH40B 6 b_!h#2[/Rkm̱T bWJ&Ғ}ZVuS242esboqR~:ÿ{Smf )'<9KAྺil:Dvtԑe2ݞ; Y إmA08@5 g;83C"&UvM$ghgq/yBFe0#f3jWc&60(b,rK1#: aZ$&>]cC(0wl\BkDb@lf{ muNS`Qg?BR?]Fi7 m׎ ʄ;9 x0*[)`ۍ- 7?IB:'DL Ղ:._[3%I"A?V۟*fح,ͺvujE |SJO/EDLi+x&02YAxo=F'y7]b7 ͮv8U#8kaQxl9፝I}s$/nĹ <55;lpFvƐٳ;(JvK4bOqR,7uѯǼ̏LcѸh󜇹dkso؎_ x|=E)QnDxy5!bUnii?y!5298>t8bo/f,% o1ы .>-Dk%hy)XT2.W1,e逻Eڛ gt;wq?s#&85REB#^AZ3A M*8# l|l`49RjTb3To$To"IP= N,~0Z.v"aTkK xUSgOgSJ9|Նzq9X هXX <pT" rqV 1:n_(2(ᇚ6p|R~'@jȿ<N }8>TT ]~`HA`">}jDvC9GMO1/)C_gWvĢ$ɡGWWc^ tNvv@+ u\v^=gEfd:]g˞c[q#6!Z#za_sqzd=nDJC'S0+h.a誒9 6h %9@c ~X3#~a7j1F"4YBhRN/흳MER)%zz &>ݵ 9Iv?$%#š1\mz@HlL2*YE=+ҢH.y꼪3FC֣61Ө)a%m wl%|w+ R'>Po3HJ4y_HUnԝyRu @V[Br~vm&j4`1DGeQXP[&ZU9=4##]TӥO w FtѮRN^~V)A-nEHQ %z >cݒ¶볇L<]F{!GPD[;CUʹ=buYWmd qٵ͂yA&yUIM:yODdgFMT (9>J`9Sm YhG+D'Jpv&k9\G$2=޹y9UVxhy-;!=\'͓"lR'W t1'Q UJOZI >-MMrYۓYXFlmmYLan4,u9nYP7RA$<-%nh`^ A;,U .{; O <1Q!rl>X|K9"XO$Q(zk?ܡd+̷bYw(lg'G^+hm ?X:Mt@Y$ 8F\>fʮvrRW)|yć焙sh>`"ZP510pܱ(Ԫ ݨw ſEeB)go.a\BmGlKI.xpD]${ q`܅‰LWG4'eCsN\յC]>J NP 4hd^xsiAF2h}e$͇)b2ѧEz}Ep/ t!% +ToƊj%TψJ%VP(lm/Y!x#߱;ya`lb6*2*z)v%;f=P*?Z5j H\ ˮF4iRAH]:@] &RUtlBih>, M7ޔ`z_D[QxBeL6 bucE՟(`5m @UڴPO{* ?< 4ڢ`*V ]M'繎]Ы]%"84I<`3,糓}K?(Vz2S/3 P -ョf>m)3&|.ȵ䬕5h4H-ă͑djLBj@?pWG lj"(oMDet?Si".zp ’}BuXs(~,HF(Y>t?^[ -\fزd#H6EHӱGy;M G.L&%WLxDɊqYXȈu9?^e7~[Y枨FjQK$)Jȓal{ JT!M_`x628 >@o޷% 41{/|E/. w-Mu Y/gav7.%"0?.!0$bu_3əsbau vSZgh^ *{@:|T(nƹ|)r'c X 9;̺م!$ΟHpC1u&wЁd+*C 70ZJ`d&68x/=XۉPpG mꤛ5Ui,(˩R΢d8Ox[ݾR (+ C6eJ n$a}1 1ILI@ѬRK_MW3 m$+ tSJNHA>Avi|';f d +Xw8Pb\Jv"?М©1@|"w,%3ƕn㻪co0y^xfLhbW~:$QkqK^'R ;;rtpr.|i^ғf˜d%@~.ط.>~1uc' aC0"64qT>s;ՅQu\;\t}'s1 Sbp+`%@T1RjC gU _F9.hLG.`\Lzt)fG6obxѾջhbHBLJv*.1|dYfF]Y<,JXaEs7 ia+'F5ws) d '#ёpx4ȡ_4ach5uBѐ#q O:^yЛak>i<Hyt 'ES vJJEiYDX+ZFf~;L,2HaYX./ehw].> 2ǀTaQp#6Al[\hb}C̶D >NG#1] JyFhb$[v ? [t~IG0 әsy(9sky6geijvG?m@c_.%N?[դ1>4 &^ݏśySElLqhLxut|pO^HG,j*;,>H:2!(H\upMߞF\\Gծ]`~ m,toH.r?`懊+cKr|¶2t~bO7޽-XnD^lE||duPي}?A#8p.M?|[3{SrM-߱yg/2{wgL:uti֭wgNK^}RA7kcoOiY'}NjsEr@~/^n8}~oo~\{kZsp1W?=/]7/?)niP6߃I77o_u\Z<ݝ=k6^ ՞}k\oȃ]C%'ԛ]L< anR/(PoCqCOf3V|氺u/Ý׿bˇau''_>rA9s'0t QX Z k;G'g'cΆÍۧg>o|{㍱=ڛXW:[{m! ~r}<1qwJI>٪qhQKhT ^J_n ,}lUѕLX. w[ro㬆) ͵ ilpw!8˳4"aDIg`U[kq,4Kyb"ED'ো*2"QZ%EaAH@\CVRqZx[ .gOK!YK+,pطo\6 T0+byWHʴ':.$̆KrN6WCx`lr w 5;! 7GZMޜDn _2\n)K-4H_QLҳ[KNGRT9v2vԆ<3:C%,Bl0\Lߊ#Z2>vC%c \LbHI` V8"¡0E-@1]HDIYN⒄`Xjc0CHP X*<}mX)f,S7)A ҜO.IEbUW \I&⦁)cU |(Ie JKF( X'h(5 G)h7 tl4{HxͶPP!$JlxlI3'H NjKBBp7KPxm{$(3%Ĥ2܆5^,U" ؙ}=:)U{ +ԦUrȢI:YMpZkJE<&ZI쒃ݩM1!P vlxV?TuՁԏ-B@&PJ09`=Wňd'RdTUWNܼ2* ٤R= Dlk0ySt$ЈZ:YN`X7fXG6Nn b\Aئ!Ԫ?= CMuKh~"Ӿ{f-P;AbL& j96I|e -y*8LGъc #mjhS&LY55qXٳ|ŀƟL`=ul*gDC3JѨ8h8d8ô\8ʚӀz(D^U@ϑ{bV¼9hC0 dQ~ώ9sL,3AaQ)q:bC4SAT M6-?%1pC2-Q!e[*csG)1@k?/`P)Q a% *e5 %0 6 !+~3rQ9@UέtFtdU&%j`XQ-#04~mZ"0+.1LY:8_38EWMO1lF'L !!j#7d$,{-+Q.ʅevvN,'.n#29EPI'I`LbP`h)14*:)P^lT$eQ tL9*pF'ڝJ#H]θkEUž;ƀ>OWiGWX;ꈦ& O*c&2?IR~M .QfT&L&D׻*v@ɅxgQNW_D8zvJǵsUAk7J S> fiWK]V ho ~̙'g$- @Y (OE+/Z3TpkI"/& >stream HWnG494<b;nZcr$H,V$rs;Gor~1 칡ko-g}W@|8Mon)<-GveSI$fBYNxUY]]}Am>V;PdÛȲw Tf^E#}fTw@9b?x Jm3|t-doYL|X?ow]TMQ 9kv{@-NxQǸ)/~]de5u~Mk eUkxh{!pձ'_}ai/?O wo9"af#09+|J O/zS!V@3.86N-h9פo~W/GiSs唰/T8a_E0TKmSxFbbdHztg^y7peQqfH9Iiv@>M;誸xdղ;$,Jނґ9RIY>jNvl%baRay";J؞G3<)RR#\(EKT<儧yj^#mo3mFFmePbFނV%69o):#CUlX+Gnɩn4yc>޵Ͱ9vѽx] ܕOY~ojb##b\WDH}/q܋+Ol=? ԴU:ڊOnob5kujՏE7c}yL} 9[_w;'<Ä}C* n=jbE ^bg5^niQ &;^=nR@,?qK=gbЋ53@XYyK_YJǒB5h$0i,Zǵ=7E/oޗ-*M`^P| /x}}T6&^W騘^!;1p:ZP{hr[fA(((،؎؍؏iaIYb$fb%v$n%~B ($I,5R3R[KMO׃}&o5C37_Aȿpԡ.O) hH#ӄ4 AQIYhfhvn~H (0 0ȌȎȍȏhDa)?@{9'[,\!SIRcrMC- SSC9F)Z(Hei(4T36B"Q4uP VٔȾ@tMt/qE_PAF#|Y cig^ȯϹ%Q-ic@x-A*bխkzrә8(mfH9-*̢,JŢ,b[p pUnl(^P7JʷU]Ⱥ֬8%Yg%'%('BOAy*PJM*Mݪ~ՠID㙦]9Gm]8c1pkxx A}aor%=MA1l|Lo.v]+CQF#c< WQZo7cl>jpjsɷɵ9nׯm>foKՏkZ~B/%f~/??z}A Ddz{ gXRra3|p GC*ǔ >c%[Y__?}t0X1~H&O968EBBL%CBDE*PQ\d+QWmzz*7%*RR1OEzi!}E!J=2BN@yw<#NaDÆ'Ĕ! R]2L@qI~=! 7?9ȃ6p Ai,wN*"HgOYC_9 x DLiCnˠVҎ`0JmwdweNǎ "n^wžV|ٳt=gr}k۝N{E#QRG KL݉e(A!A%\U`Yf1\]=-U *Ƭb5i(S LU 6Vp 9S NxW'#ȽJgb(\`'U,[MV K=Fi\L0MeaHd$H,s[qV S+ݥ4ZijXj.9΢ &[3^Z"^nB9 uB0zLmT d&(YQ3J*3_`ԓFn˓S+bmcR,wLP J3ޛ,mP`s3X݁=rϬB;]B(M^BcKPQ!&$dIb@+`UZ Xq%&ނP1 )#G5]FdUI!!Zb6܁[7"P.;[cu(NIe%#꨾ihUZG5#h wfkj^mɖF6ph--![qc1٥3fUկ[*U}8ޖÝɟ)T\JyWeOj}i i/_m D%&P7j3\JrVwW^ODR8 A9>_$խ$ ~'A 蓆<aaB@ԣQ(4汌؏88ðd'7y/)y*S70T(W$ DŽq#qY)guPy㣶OO:׽G:m9:wPM獯ůd'aCm9b©}͞->_~M0?OSdMċK1K$&OGyz/>~~ywu诇חO߫OP",- 2;(Pr͢"Gͬ.ꥢPORMA*Iqo^RAR?R=u;+ɕȕ O EυXͪk&5d#DՅ LbR JJ-,I\b`RLjnԎI$(PHQQ5qJgX%J*3aY=52sU"/Ve\B( MqUjUFIn{ܥZ3oޗ{*y/W_mkH l[ՒX7S2 \D9S"v@tsq ZmP}Up8Zm-UZbY dk-m/Ǒ#~A67`Ok+/tc0 7"I*Q``EWWQ$sbʹ̝neU%"}n^7n_6F>i3$>(P4QXTeNb-h[,J{w AbSbKz%Wb^;wAjH4Wf祙]ȝSd?+߉I,/]|1/Y׮6_Pzl_37ӌ2̼fx17L=c6F2lcx#3[0#s]U€tgkY@߄`J' k;3A? H1Df $(T@ Hrg}8rJDd[:txDӉU#FPCt0euR:Gq (1V׫z^3dAbqG ٔ*v-RtwIbʏól>i-'?w/Dj3 1OӘ'6;|1<uAz* 1?X*?{X>PVoa`#|}[hw~6LTn ןy^6W[</S !M2R 30V2YSX&46qc'_l3{lxY^kc{ߩ)_w#g㪷2_pw>31N} Z@gJf;X2ijUfCN5A5h&?B>Fͤ5fjF8MdOG31ifM^U2AveogCʞ|*:E\;1ۏv)MGoqڛ].k ڣ:ֆPebd9coG[}.BLȨI%[)d1sJfRJ%̏NE؆DX]#@tAq/va-S͐ԮJmDj#쩧[DW" D&A#Zz/ IBci ~=A#Ų\~ As"x ` 7 ^DojEJm"mO5Ry4T8 D6`q#Еp۶y#vý3 JNFsM-fK_e5naͮ8VڣVN*6%V,V^B/E+RxclseK㢢z13 R" _Ef1x" 7D5|&nQ~bbbrKRA~d2 +:XA#tCx*4yÎ/PLJ\EYJ撩JM<O>iO[G=q 3Ys`)g,Bl{NP=j= A(١=rye^M!TdjJLJ#8@h2;EeS1E E{U82aV" 0I@%em6:k=f.CxN ,1 FlO/&3l#f 6cI[6[q !C q\[E8H>!I'KHP"$&jJU4lM6ޥe/?{[ǚ,O[~Ȯn=SfaԊWدخWT`YZR6RHUSqMŅkjQhPGn2T\ Zy.Pxkb%X&l6t_C= 1NرlBh*zyC"cVG!3.+7z)ГHZ'[`t۪U-;NӠŤ``!E 5!Mip=lg<$kSԁYRI|v쩳qݎƟ]VS\8tVF^ +r p6."""!U:vLZxm;2|r /(J+N <8G=6,06m!{>Z&2BOg*d-pzrB҃>w{uuU(!E29hdڝ])lld,>{vD?fWr Opޡ7b hH")l$L6,0& g{2yXDϽFt[:j ?-_A؀1 (SK)8l6hС2fղGٔAG1*!MAcۤ=H5q7qWcsΣt[8/ @dT4qa7Ό{F VTydj塌8l5 /LCS/;krL|1FErtF뮍hD;-*U8(_"~-Kv&8c{{*LԳֱT5'ku.ZH s =*H#\HdF:Ij%fIl'ĆB݂J+KK-ߢDd>M4 glܲ\u\֔gCv\nu+*1ȍiݙJk*4ҝ\tm)RUZҪfEj W]~haNPH4wN:cm 2bpUܖGd=ϨRO;CuE9'͛bi @BTh@ $-@Z)Ĉ c!h[d*d8:ܷuQ:87:&]/4uJ"`t93 { PBhi^d9>%0qK_7iq*X:rzӘ4Ǒ#kQ,ة=dk4z r:>{-#v[ ي,lC8eMY`I!  ,,h?&|Y.kY!i2|vY"Kf>`*\{1m.k*9$9FDimB*R8^@<xzkfj\Yf2#jo QU-EnrKK 3dpt)P֥NnJK+t*͑S\W-׎8A懰<Ϸ͝G-|Sq|=h]UQVtqrW}]>FC5 -Wj.I-_Q7շg?RsŽ>O{4UsQU˶O1| L=c'mTOE{1-x| \jǯ&n7`/A8WշӇ~˧7Ɨ>~*o?}[8t.~~hu2EWv4YG |/lQXj.Onjh{`^f0'tEO6>|$oS<!A[ Km2.wSl`I1sbv6. Bf]I؇uyFhCC$m&2PI;DUy~g|#p2!SpQo.ɲYC8͚)W aŦ7XIHߋuc[n6 Otp(:xC`/~ ]eNc ;.鸜27-\:C l* %rx{9kh4Lƛn5GvwKbW` q{0Bn ?!0 pERl"qe@8*n c`OTZ,_̱es0,K8>+Y!i sCYbIRJz#Epܱh7?%E_t'g/bkE?R4:0)%Ԩ=q ނK+.6XL}׶!Q\wx.]so:f}j8kG8 x_;40C``a*X1:<Fn A !Z<`q#ǀzЦuv`dy⟍۬mQF$|kE|g_>?>ɇoZ.ctO`]%#rAn|]xtg~_^>?|GoX~; !0!F  e -$xq[o=]%tv2L!G8$h4)bAzĊCb\i!B{dCx?_|) 0V@0DGZL}Ln\E@pyHؤ(C1A@PX&5\ A!QQ15chsҩ(ObyD/ 2>9E&ڌh H'G_d葞AgူHΊ-沔s9!1yv~稔e^9`K=06^oÙ \Ǔ]'f|5[},6$$C(@Iyկf\VTllo~sjo?..Y-y3nZ^GA/|uh5OOoί]\_~Y~ߨųWw7w?ᭋ>}xݓ6j'p'Y+hnK^I(o #AXfmZ``痳/}*'E"'Rc_YsR|;r_:Xǥ$XQKnnNr1VxA5 ~^qI`<#aak25Ӯl"ŝʮ@:FR7k6ı3X5cnYO2ø3.;ow-U'zi&n>4_hri=4e1ᬩ-]d⎄Ea~΄G{Idm48ޣb-H; `#''T ٴV xTLsE y3( 4l8)"TJh#=swcdžB%TTTM #aaL4vJug#lMgH%| Ց ha"|cMv뱂/>>Jd::N'6"BE r3ѐ,Pg:eĮ$I\k +\i r60Fr *%HڪYəJV/6[ #P@TBY 2m,'S Nhf&y EhU2g#g8OQ Ta`IlUGsfN,)- dAPG كrm\O_&]xpI* *Ռ?6N9TOn ᛭M>}ӷwWxy|vb?ܧo~8}Q/0w_돈P a!-,oʷ}n.BJ)D"X_ qjGjVl7х^FE"4UVTTֽQMO&w4\ØQQ2NIpt&DaQ2_jq$jSFA {6NLtSfGS`zҩ] \[h?G}c\Gm@7+eepvFGMOD6/Hlfcbmf#&^֪i}? fvn}+e߆#nAnآJ3^maXWc&f"xy*:OUHBi(Bm$-q|}Y^9Zg2A\#~D B%a{; D̫8O$SƗ՚0Z 9N{U/$ckzWTiJTהDch!(0AOچ(:ɓF@b=ed!9|_LnTKNTkR }_(W;z E~tن)H6$2ʆ&rs h?l~86f>icy `0u%|dGP\ =HXD-i]9q&PRt5F^ޏWpW+lIg@3W->1 $:1'ڨU A%~Zc׷?jcdGNi%?[yxLgVni%2Wst9͚0+M[f(gSg@l|`H~H^9Fe:c`:kFR\хȦ+@ gM>"PoI.;T@蔩X` ݇R/D̅3Je^C+wPtgRfQPUqk6i̘+չiv]']w)lLg 0þ?nuD3EPbPM̕qߍ)W]KT!5"xZb_g=9@RCIEQ[S@"tNMf .ȶm4:zi] m[|^~K|B~_Zql.@S׮ubvs56=e+ikPA(leO<{UуS]]EUlB$߀RATz1u'xn2މ1e` yߕsnG}+U XWuTS;1Xz(B:(TIMh̽W2yksD+SGUF(hfd*gPKG)- /(\^OZj Jbe5O)/f{$6O 2,QNF^}ؼ5ՖGS> q~Apsi{+ɱtaWZAч1TDt( F'HB͐Iޘ;|W) P]%x!9뀈B06^6QG N U~Nx&C{;AN#EǗ R,R4s& ͙FMFVMf银0ղq?*Xʰd Si-t 9_1Gt$e}X[LE#*wqmZ/A{:B<.!=&iŬ:}9 ̞FͧO2xoỻ>$g 0fBi_j+Qx(y]mI}9"&duw*T蒑fPL=WD?yf7Iith*I_¹EB4 <ɁQL2AV`} gSf"A-bL~W+!M4HB}kA-)yנx@_F*$7:D물bpuu/)`n!JО 8f@) Zu 3o*$cHp L = Kr3`}rO`pR^Hp8`ӌhJ$$#ո_yS^f 5SHUܫ/:'( u2}l@Ǭ`CNCDIyTHMucՌZXYYi$2P'Vd]ŴWBcgEyL}SuP/֍s#̈́$N[o!o$&O(&7jJbLWd]H 0U S%K"vԀJhOspZ-w6i<ɤ?Z[=oJѶnRmW#\xl1$xQVrs .V@,UˬڲH \#gݺg0Q C6h`~e />8X撲rMƚ]I&\LJ^Ӷ BSngc]*k'RD 0UXғs1>UJE2r690ί>MI ɗ}JчEԻUlS! GhrCK>a"<=yP!oLik]L,'(Iy ب"m@k/ Ҧ* 2$x#lW:dȀD#xpDS-eVLSKSq(H)Ȁiʮ57%)%~ltڜR6&-@qZRI$nBAջbtV^^f,HޠprfR!GC0JRBDl7 2"/̎Ь3SI{RsC 38UI @ֆKT 8Iv>V D!|J;qJHPa,+,)$ _ 5OB endstream endobj 30 0 obj <>stream Hl96 DW=(qCsܫA[ qP(k\BWwhX?ٮ4B~cl1kWek؝,他Pnss)]MqU~Rr; t bx6Xaiۋ xsvk:zZZG!q;6~:XbVm=qg_1ӵrxD4w=:KBz o]0O8BWwUxFJ6SNxAsVBשF~|eP0ʘUde"p!XWR=&#(y٫>aL8#_=l8|Ssu' To˔5\Ƥ9e e 06i|D~jT{N_sR 9|6{~Nz9o"q+I6.l[pU:oK 'd:+4z, ?0ߘE5$h!)HFk:ۙGz%UO% |=IChGBhd"SER}}aT:+Rz96Dbebӑn'HmNmM؋E͋LfE=Ǔ֖%"J}#!@QǣQ朡ᬐRadDȹ-ц]q]ZJ%JQ[ZI c$SUu?@tig}g:Ԥx{;q5궒Q7C9?}*8KFY=5n[Fj!x[s Hcdf)2Z>, o)ә@0.xM/N?6{kO2 t^Os*%VASRĨD#t9F3lK%t@M\:ase~J(r k=:[[u&Hs{t)VTx>:s'׀k?W$İLo'JJ{o'1H0geY݆^VhlcsiA;2-YRg3Akͳzlk9=5p4B}G%,u P=sd mMR'8Ni2>…2rጊa>sވG+A*n*l)>$2CSlj\Ԥ(E]lYݺ6U 1b>}Sc΅]twg\>4Q*A\vҩ&^߬+{,iY>*nD9(R۝b=s7 T/X}ߟW?I ܆ӷ^~bH==S0w}z+gM~Op.>|/Φ* $Y,68;gȤaD?\9}>"f#3-ÜIͨZ^\\gSlH5&wٱ[FOVenngzk;:fpGz u攂o9oF 3 95=B02,I:عsWH{qA2Bjw'9 D> 4E+BD2`( ycdٹĆ$j4;]]UP#05FG#Q i옰:krts1h@'ZAGǾ}a| [YS^LFM#ƼNUJtkI:J)ӝ54Z&(aϪ )..B(E4H]]fHr¢ QnaL0O酢k*чR~'%yq1o%*5[MPjD%^I,9k4|Q*r} EySofݓuK;^%L|g}digUǛ ) x"Bم?k]^;͵\ڛ׮uL9j/уuX0>ʫ}AXS`iymkO4~د+@#oGRrO{syFzx{H7=.w0al#wϙ+^Ɣm!ΈNl'i^:KeCߏzge MmϡŴ9inh)X9è+oI)M#ym38}u9/; ¡H\kqR}W~LA1m9ܲ >1vws\otIuI1 <$Ys.jzbp} qTwr`ŕʾ`]ٮyWj<>Z(hDI>G6ȣNX5FZzZ;vHE{8a-.@BV9܇QoQNH;tv :bLc+C!K;X% U4P?qrlUƓͦI=5 $(f' 9दYI_ 3L:1ЪPzL:h9݇ǥg} ۟HFe }%-XAK!rCyF؇II"۩v׏~^~ߗ|}s}8ga5o>ؼ}mgvyU}K =~}/z[޼b&osg˛/T2Ӫԗ?F bK 6RR\0XrmP Ѡwu]ڨ.mEbM`UEGMp&ˠ)G@yMc^O) _}S1oP͏Σ/O]F`Es#r {B=-!g"L\^o vyr/{J`.Гg^>[ {]^tJ{[W2ȗLLft̆D /7amT$wJc07@0_@:j]Fqʭ.n%uxBrL3 aNѿZP%v9@Y#"TqD5gHz ])**yy5ˁ{ NTok  2';(Eʔ\AEـ=qS;>}z7W)lZ̽/WM" 5T&"ydMi"sFsxo0=>u&/Ռٗ UDAUZUKU ,]Mg5pZ 񠁚r $6Q.UC$}Rzre<^< 5AK%dfBRؕ[-*A8R{[1!G $w!+ꡣjbXhg{Z7u P:"i*- 'g( XV0q$nR.µE8 hql҄־v\)]Uv c&׾Ury, i0X\} 7m'*ZOurS0I􇍅Wjwu9b&h+R矊w qǣhHaIPgShejU=Mlɯm s]U9g e^ߋitYˤDHQD>jƶu5)e>g^{!%bb*x]_gxꐐN:`#iӕ⌙HtmJRZ)ShV]uWwmR]D(t#fkۅ/W"w P${O\¶ZAFh} S؍B>[XPou9-<[H7K4egbmDb]4wWdms?P7 YQޮ sǻ,g1'.*,xcZ]B=cJ+X9Wd̈́19NL+0Ė-ՙHV^?MlhBҡiC@+ !iϞio#^U MźDC&'䶗D?"C WCI~uV;ꎍ:Ƽ(,wJɯIw +U!i|yՂ߶a'n2W-hzejUĘrZ6Dn&c8L5{Ȳ\34'=yF4PF>[ 0$"k$1dlC|ǐ F]6z1=hÑ)\,ڔkݹpf\ߤ9ɍ/ל!Y\($?ϩ6AsE&[g}rc~^,)mL|:b8 ^`9al3vۍMuYR]8|\9#3D*Q{.HN˞/!PocGIC*RHڭu_VqYZ޵=Еn:a`7rdXZ C* ˆ*҇ukΚqv6Dk`8=qڙ}gv8fuGMfv9S_8kıwv<-fVF<<Won.߽xt][=IY W0$?_<%)iTV5]i՗߽{oo__yG?WYmzqZ[Ƀc|!pC OkЁnQ􆂨`$gI}(za5xpvPN -:ehBzAx8=p5l[@yէ*S* JA?~><8=u[#hLJ63"qJFҨ~o+4tq}aF6e %j'U@H:_wͼŠw~7a+bɺДv,bAd D7΃*PH֝9buB,5]-gYHcJ{hIn!Y7̳J;@ Fh'\ხ0?<C3g:ab˞2ԏ׺=DaKU@vE*dVKT`nv,l6~lgFܣ {ʭllelCfY8Z{crOH*<y۫o^^]^M{YBuG_y(smF>}ފƿ6B׹,IʧxQ;j2 \X"W"r|&{kDgqgO>q;\N *\( jd_0suBZ' ރ NA_םQ+eCPVOܜ}mCKխ{8KYCGʗJ Nc]a؛RHwӖI /QJxVd&`/"?Byl/5+E oI - Iؓc>_~3kPv=!#vVE~.%?F^<9PTO_>~kp16T$4zÀNO#h9vT#G6@;;7 ;0Z;WI+MQNrtQ: AФuWgCϮe<{Ref_\ i\W3U.|3I |j$ 2'=WvʌU (З1aPBTt%1i$nbF[҄f6W.(G$T$1tZr;}^ UF& ҳ B4aNwXG bY*2?ҫBOTUrh {6DxTH%I3+]MYJr>u$줓3 6?}d$? 5M E@D8B)*p 4o{e_GAJ;#й-B+GDҸAҙRMr&5B;%N; J 0 v6& 8KG5rh>@ȉ<5 w^ +[| n=N}2ǿ4fp:"eКQB@Th'zJ@gATqҽ*<7 IVPJ@ЙꋝyF/dRw ĠD6T,+ɰ=ŝa.B:0H&b7 0'E;Æ,g (Z H#5G uѤXZsbCiNO=RlMQQ"(VcNW4&b5#ņL Ib Wi}Qw8#32L[UDx2MP~?dЖ_%Lǒ)K|ݢu+̭\$^ Bd6,_T`+e-6oR %<4.*Yc_[2`[HF0G`Kc>[ B[c=^ Pm-oXh[`eZ~ \) u<b.&O-&Yr-ْ>SduzG Ra1շZ5ţ*GW^ŷƪ )Ƣ_t5Vj`ziTPmp- r-)mgXӜƊ[rGXfɯof#(8[9gx[5Jk^ؼ]UxN-uH\1Aj:,)0benIi@^H9+AmZՋmws}àN4<<&gTNmfR_iHfWm+ PtHnqWlVɰ=a y؇-pa{THF;s3b26a>WU+Zˤ`4·$X]-z'X_MU4}bHXK,'2Y9<ُk(n cd\~}ĪҟĒs{PC͡xXKSHDU94At|J) cw Eel72_Rh,iW Ge'2'F3oQTb1 ]X~k;LBzИ$D5cچRИ)ZCamX^94%iÝCP ;31}<ΡQz#ʡQ%!G'Fbʧ6F ?dDa>,ECM$RUNh"M2Jv}> 4IDjG7n H+R}eZTp$3qve KTCg-/%2C %Ɏ@cҲ)$U(fQ2^"l "yN܂Aq_R9Q~Km]lpu/-1YCh @)Y Wo6a$IA`9¸e]-$m{<분JY5雙0P,uk\sY1T=徺|9g :gLu4 "Lta4\V]V-B*>I\O{r5coIX6OطTՁ4f>ҧ?xC4<} ńRRDԏSZK1/rzb˂lk { sAKlBPP0Y$LBW@`0Yʦ|L{,1öhC49KR)YxRހz8hL%ҁrċ_sy Q!hl MHd֓fi !OL"ع?XJPl\a"KQfYƯndFڲ b1#r!Bѭ.dnöQ]+,ΤGt+?TܻtO:-%`_A B-)PkHV^Wƙ  "ӾlF]4EAfTetg C!ItSͱ+w=ⱳJmq]ZZNŃwrѰA 2'cmYk#IyPՅvyC?n] +L섂SsA0ty<=b7qrݰ9:O% <^-/AVUԚ^mk-M5 ۷i,o4\#n0EC+,֫6׹(d#_Fk$9!%">H@0,bϡsX}x1߬wxo"HS4/V sJBrmqOk3rJV`yx,1D0v~]b@ Le/%^)zמO{ż\wfÝeCas[#\ *mP.j0r!O,uu")Gbb,Aҩo|n2ԑgW ~<5+d&zSRknr u6Ù {LYkTeۜcԳ¹W1՗'@P'>$Y#XtoIh"lO,^m7V:i7$-Tx)eRd21Oh=fG<}837=:;l7zhQuRQVշi'HiF,UFY\`diQйxru^9Vh F[mpkkZ̷<&})K|J>P-YnvSқ}YClg= M뺞g'BJSdl9$g-(nφf;Tf|MD{]7oI=dx{ŜL!'Gkq;[f|֥ #k(i$6# CI@rMCO1Lwk{[%{%#S&TAa)y&myۼ4&|X&f.:CNhBR9OefeͰәtֽĠ(42BlA/㒶sLc.ӡB: e'z$G8VQmz WO]b|tgu3z*M\I^ϦmxjR\ų\hy|vOLyOX4vcn>qWؼ4]۔|x)2HixB+0ۓYc~c) ˪z2󵋆)l[Q0xj?,yjadwA䛽}1Qν6Oz[*b^&}f*]66R"6s YqF6 E{^n3$FqH۳@Ol1T KFN2۰~AYxrZɹL5iJ4/<:'[RqKF _Z7tK%Gxrmk(q0: l]oM]bL;_`P;kUo(a{n{AGgMu]=WE[$E5Y47T r/ۊ _ :DlWΜd/_bD1Lܾ$,4}+Z 2w'[D)+D zh,Ir (Hc;c鶱8LNχr+J C+UmwNiÙ}+<TF})M5Iʫj_}ԩ*91f# 5N! !'Ĵ,8 ޱŸ6ʦ`mk?ј&"fp ID!x>)2zpf!@'4ر0Rhh/θG(-TD+0Q,]Yfl"V/2$aB0-2]N8h͞8ӟkdD)lcJAQgMw(1e={h~N9 A֜IZ0qE\1%c>9v٣6NC)p+I@q%*-1i6cumП/{Y."rCE[O2K]SLP~-qЇ xn""}J u pT́mܓ˾F'9,x($b{m>o5)Ew VvMIMu J,J '(y){Z2ޮ$fKf]P;shWtQHd`p&ꏌS-bhإvmh#`hʨr^OLu,\M9No#(#Hsm#Rzge&^I]̭/f% g bS4Coȟ._ٟWvڒ$Ϝ6 xZҤL+l&~-e*'DMsD!ˣ2}{,fl;JKFܶ^ϜQ\|4L޳oZTʁMvwɋh(1ô㦋. σJٶJ8l:8^#yݨR2ߛwZQOb9){9whׁf+)g^r[ď粈H԰J,lq.}eY֝[o{'?Q/" D;fIm.P3qî^Ace\xsl>Z"{Q<d3lFomE4z((?XbqKE5DS5MBp!PY[Ck*aШQn `1UJkr8iC(Ne"8yY6}m}6 3Tf&j9Aj|SL\};bz_^|?|p˾K"=: ,QС:_g^]>yUHk/bï&^]7ot?_/oۛ/x]o}ӟ?//~~r~Ҏ_~<?tⷽ_}x6Wriy9ȗ//%M_eih-4JOs^/Bug̽u/Dؾ)hjgU6__;|wү@a@2g)'ml[5<໡q w!wNL</AHK.:%Ȍ¿;Xվp_r,L{Ed]$S|+-Rȏ{/>Ul} NrsQ0G.&PR&~,&f"{v+"]P5 u 5#KIuШ  +"[&7&N'$l}CإfIkyB^Jd6Yb'0g.RTT@ ˷Vڙ;Z$LUh9Y9urs[[q@mN:y _RhI(uύSd%0F&A2mgPM;Z]"drێ*Җq޾r]"yVk:%ŸxctC˽J EҾqDѸ@ڸM;^ 0j-?Pqf]p=9+Аu &o( o9TC⎮<(:i+ (-IGCP/FTԟ)v/,Jݟ<iWIV_Q=~T)" e3nt[n'ěP_ ՙ/Dq/ůa4n* sEixT1I+pF 7IF+R:Q vO8 65G8 (f̂#^r \8‘^Q7ʎG{uG<Җ#07!i{Xx$}ZIB<җJGH!lG2-/͎"J/ R7u, ,,@̪:G[UȈ"q(A4]|9G>ڐ5k -zyNg/>j^uiZMn$BHHV^Gw -n6jnHF% l(ܤ?BwIb̔.*`# 9zsAzi"䐱Gtt zK.M]g7T S4Z*۪gjnڀv%$%\/,} , =gX)hźD,ۿ$nV6(=(i2 w%^?y-tVwOZiX=]J7qYxzd콙ڍ"啎Vzp7#2II(}'mAa4}k >1*@<0%ЮSYV"Jˋ[iOM{}Y`m_zpm[jЫ*[41fLZO1$I[/n޶>-H=n4.6:/k);ӐD]1+"Gu#LP=bXD.ѵ ,qnܤOc[)M|{r $Kald`g}#vf&QWfU<Dܪ=bRhY?*Q=`Q`l]MrKnv>4'D'3\,С$m )ADz۵8Ң佼,Cb6jlvC+lؗ$&@ѥvEó"וa[}9`w2R.}+"b(-)f&yuTٿhE$ d" /Rɢ&+7B.E\RHC+d'dU5E}^_.Y .Q#mh.q >c b6 C{â8>W~^QqۗF僚=q>l}_u}+p+?a^?~?ɗd~Н.LjC@*6h-z /H㷄2̧DIŋE)0HZ pCC;$E1)V97C:3E6u\0+:홃ʘH%`d"jơ=(N C .'/]5J!N2DP4QB̚՘`"ŌdΊ+̚ wǡFدi1Sq̕,0ZJM@gjph]`fQ$E6ޞJ$aF[J䣪X҂C-6뱠k&laY} {jJ,{C~CVΟ@3RmUsSK+mw!9MߜttIV>.G7xql鶂rFf645es CĦf6 Oc)ͣ!3kA qw*-vWw'l]sϳHPl+T\yt(T88WGz`^(ҟb6Fi(1-F3Czהz}z<52N{s4=IolP0#I~mn2/Iq=3 eZ0Ωj6jɌv&0C54`zM ˣ\dg [3_54[kU^M=b@?tt :M(3;y,ewFYyLzy4%xG<}i._9Qz0ߥPЕzH$Un1&*G~]1pWi PzxՎ⣠2T7Őn ʄF/*eqo] !cFcWr3Jb Pr8g!d0 3ve:ݓFHMlFצp+u6t;K…m9ktz&~Qp,~/\$Z5iFnwg$tYthr%Z~4.WpaTUj9R}Q\MY6?0@-*Np"yӵkMG2QR-dL4SΦEdB);VG)lH,YѐD}1'"aXWT?jF Ӛ"*Ƅ*iEC0hNUDڴ6Juha?f%mpT vӬ$Z܀FGPU`iP-_hULdRzi0dx(Lh9h 08ŶqO+}=fT$i<+Ae, d ONJnHzb+g˙T}/W9lVFrmqFp|=J:WaS#GD(N 4. B*kW ,A}چUY'u6|ۅ2jdq9RW&ޫ$ZG2H_E̱n0OZm%/l)I0ﻛBv6J =pR)pg+w^  JE400*W*%n:VO`TW@j(֙- cm`Hoy}O'ç(pIKdsÓ{c#\ٮ7?+nɣWxp܂߯+ABa7gO-Ubgȟxqws~=zw>}}7ݧ{{滇_r?|o<_>==_֣xz{wo=!=ûu܅?u<~b*Jy9ǫǏY7}-ǿTCX=/x7 cɞSh-3M'|zDhXmФ8i@h;:Z'Aa@ ?t|"17&,݇O`< ~@[>t/m[<AXqV tj*3bb6f+Bfg# HV҈O ,>ԓ''!_Fmm[@ A1*-wmάu~H[1Xsw |s)ݴ>sW)" Ia WpBU׀WV_ endstream endobj 31 0 obj <>stream HWko[%\}$M:8 hvX@Q{{)۪°$gg\Cte_僯޻! dC>% eRT|2OF`K&Ju\ `MiU < xmhřҐb"9 EFD9P TcB&PV@@K 3h[k|PQ9QC " R`|T/2HtMNԠvDŽ:'P&Q0C' mûϰ yxPْ q;0`K h񂇋 3DxS<4.I9!@B4Bd0$GfQ6gÙzez{CrX㒃; +/H v%"C1M [ 62 YrCX{ v$gK%!͊="#0Z8 CE9 =VX#ѶjPMM] WdvYTi@{u6Eզpv1sCq#Mt݈ДUxdfvHl ޛetk'׶$ &Q,c'1)fIc}ؤؔS1rSOدSMkm'59?}9l{vsby8zyXz:5{a뎅>[mar}G nmyASy:@yn)fd~f~헨%WhpX߮7o9N_n>Rað/^^`{tɋhɽkjË˙,|x]ufۑɋroXvr{qg'uμSyq_V? q|g/kV%42!K1:iX;Ȼϖb4Mܭvf+@VfNo*6Hr g1." c K\sOM&buCOžG_=bn~qbZY L H .h闙J, *`6mHvIrØH:Pql'TyFXEt}6A^毎t,hkm_(Ip#ŷAtvyp`K)tRӔhXיU0IbPDp*)>7$ӉxECͶD| =YW?T>|b-Np?~V.-#F^A#)|/Ht)3bEx@T;^<)Pe±Xcm%Fq7PuN-SNK3z)\ ?jm"W)҃r}z܉0C_J=7L`Z%raH+Lѱ嚁%pQ;PLVle*⧀-q"U鼕Dt"TA ,J/L|LVM]!Y /#4Z,~}۹VhVjkjj4u)м;6悺P ĠZy! (\ǂV(2$CUE rƏW$șǁ^DY< 3Ṟ8pEdMeIVm[B+Β{C'3bкLvbCӇ>AmlThR3'B #̯RS!X8͘u=gi'+?G^,dp5g_u3, X)_FWX E*Z=@Ҩ D\-\0yV Lo?Xb܁2G@0;7Sa(VKf5rI;R;ȇT"Ag)&@E 6p 쪮Q(P38dlr uH8j } (/= qľ*SH&tܷ DvX@oPEni25"@h[ˑ߹:9v0!g'!4W&9nH `^333 '*@WrY2\*!Vp~$AM& @R]6~o0ۡSvlن_^FTKYU|X5Z+?]lJ/^ sSi@)$ >eWOEѻ'X)y2"Q=)kSwag0^\ bI 8q"ԳUY;>!4KUm ~@) [O%j@44h>Mod[)Z_j]+ Vr&8ˊNȣKGK]f\uɾjN̘ujn j3ۑbr#Jpia7V .Mu0ڠdS էa\m,VXa4zzڐfXSLfU=nZ?A Ӆ4B2 aS"* dqe iHmM1\āy}%Lu|*ǒ}VlcpU `UwYG@Yn&??ҨIl lI NCo1q~_OJnW @PŜS@ؒfdV3 -kSD35L *up\}?@!E |W05@.(ʀ^䤯s8HewU1i|S=ӽLTo9yY8k>\L5HmKZYTY-'yƼGjZ*mO}&["` 5.Bv󆭾]c($oanbLߏ5YA;C*ɉ,_2wt犁]yQtvf*faTGDXhӫ79Y~ C;PGMH[GOا& V )Q) ._]\{EJzʻWaN0΃<0CҪD&x7)F]s OQZǗc1 /wAM*I9bXw/ Z̙&>uϓzl1(Ȯ8~B#nS&וeir`%vx)O0$( 1u䎮5Fp4}b'M@Ƹ0dpT?t5[O~K]mk'̸nVe(/`fEjQ~=v:sYFCߺi.I THIVFvF£/W)CiqY_2Tjm,~\.SzpKf^'UO㺣M3GTc?6$ވͺSg>e/eNS `H5(qg_V>r8v !5w YY#bWg"&a4GܶRvct ԝ?SxM6*)-S`ZxA!2 "1^ &iSebe{5H:.SAN9 ӈE"3tjNC]ED87R^e4gwsUQeT/9E^%F ϻrЬNGl.T7&!v^(IM ' Z`s-8DkŴ1 EeK(!tńJPgPHto!N9ㅬHLH{'!kJ7;2mQ>ȼMuQ4zP%!YaMnLxV-,C&;ɩuQE܃ fE F4n1?Xxy*ixSil6W$: 5kDs 8g 4ꎙb [Ssre)E62H|>Jiqh/ԣs;E'sH}aVeoF+*1N56Y[.ۨfN"GV9e!Vev'GCZɨ؋Vn/_D(>μ z,Zodۮ%8f%Ȯ!E/|uuOܒ.̗F4]LP 6_eW 󊳢+cFRY=y!糞SVi*Dd",qYꨕ:$O)q 'aAq mm6 n`kDo/ 7T+s)zl}{Y]KL>2 pQ*fz8[ Pr-2B5{Q,y2džS{d :$ e2NBG@ .m7{M_$v]9il]E} N#lt$9}54@Sv!9f90OcO[F^_; қ1$nA󄧄w%NJ253<T6co\pVgFe _{FOd5 U% iz7L'zŪ89YIF&]FDQOeWك#vHiI" GR]T$"QG:ѥ.e$hx*aT㉗Z ,5GDeȽ.CH[j4!%qRuS.OO?8ԭEezꮋ@$[9߻XoJoز{("@Xyg*b Yq8EѪQ{&RzoI^f K`p"5^UY65ĴI MѾW|Zק_~_|?O;ˏ0%h{Z4&!ޓlfD}ŵbnb`aa>`0F&-t[ ыF8w ȹ:@63Zki:2t@y)B]I3Й|x; *H0- ]r`5Nnƾ mW;oXWLOtP N43UhRohJA40T.֚wf/Ϡ]kCSU #߽wSIPV*~jnܘ)'-lzܑGOx^!ZBuE" ܭH>#A$-$Dν+~?'09|rhMn0T6㼈[:1?h8ϸcpsGrH%YeqH}$7 %EݵRx4pФ@ܳ h=' +G(xZ:g¿XɁ0PJgr9y݊6\+~"F,͐ݟC{)&sn\ a}c{!Έ x49t-n R("ѧ5}Zi^G@bGc3r` S6bɡ'˯nF4"|L\u95bO7Oron v+N,p ޫ9,8_=/ox`uhE5՞4ˢD`^4 ed?Se ՛삂QcOEnTJӹtZ,ՕVglkD{Pg |-:]_}~v$9gCZ]+$iqJ R i' `4щR'm\zV|AS3)wG5k#ͫ=bnÓ&Md5x,,ZMpÑmH<ՒQssXc d-U`kiE' Sq4Eru7M VuF% )p^]71PSuV6E.ǘXx@qV>4O9_&fg5r# r5]VLkKQzK)F%{T1}-- `TĮk|zc:mԲ[*;sz^zY1 }N$knˈ+Sԑ(朗_ R~n蚶@cOg}܅C{{ECP+ `ĥI!b 5WK+ RU#Li gYu$j"̆zCJy9Uӵx2,\F9S {йf J˙W4҇5Giغii(eڞl%d9zchR 1NmũЖ|-ǣeld[qWZ`e1S_}ƴY5QO-&yƚpe1X+ ߣ "F!o&=6!Nxe0DS(cVY I|ۭ_i(t1} Ƕ\Ngq^\9*U"4Б >|c [ 1_3 w{e5aҧQ˴}2/ ;.ezBjQÆ޷6 =,[Ι*I{DGcz}t]\fՏj{Uº3B.;3vjC'2/ #a,=}Z{Ϝ>q+T]dDM*^rR=B'@OP.mZV $ ;ZyG' F \2ݦ4S , 8!:BgGTrFQ \ mLtJԱ|E~Q] cM/~7dQ83P3\8?R!i^n(q*J#!Bhs?F0}sǯ^/";r<D6%tr+-kH/ {Nqԙ㬁i,8m^> ~ͨs{j >+ijhĞ[rSziqK$L{:ۛVy4% ,b »SF)3@ea.m>Q3 -@̼:Ȫ{҂D~P*YEJ=V*K)P Wkj}Ҹ 2b!a|6k$XgLZ8(W6j-/J$K#H69[Ɂ%UuUW{di:VQrC!J׸.-+v;nBǒV0Ӵ[L`4>|A' utvOyu*ϒ}-bm3WSP *+\@T-f@N euVwTG#Y+vƳ^eNJOg@B[l ptܶJJK >A.ͣ !Y('0 v*:!E1ļbИ[7IV dL""|cpq NWlms\U._:b$GHfj&:WtdZɍi  IqX7(_0 Gc+<3R`9 P6GD*-%yJĠ."M ƜML!kuuQ D~|!Db$ قml@!RC.܀VDZCx%;SNmc5TtvyvGd0-]BF[޾yRHT]@_!5 2g"a<.;C"%9Sl(՝P5/} z2u?|~x/?'A}IBwo??1Ǘ/^/ynxtz2F.Z*cB3H%Ŝ\t&lAiQu)uGՖ d+GE H2D6!%ɟfaי}/mFo^|>B;Ur.$Q7{ZS(FC}-!)/}?@f ɴ<H9%l&9;k[C魄6j1# Y#^T\YcwU˛%8dzOSdbf9 8q[*<ճҙpƠ%=fむ\Z \&4i?97ES7u*JǹԶ[jQ"FȞk@dt QXf-ի3=U{MYEжɉBBO=٦vȳQcyP{ ĬRẃ.];QgkTH_QJTi^@1IDK[+LƓ;a7t4"LE&/hr tn('Aޞ9#duR$*2L;`~"}FVϊ0#ʗ1,FbR=sVvFF&^@6ܱ=[3JT>BrĄKvbnLfu%o$,`U>,L A 5 {؞a,%>kK'I>r'\)R< mH.r|:=lOalل"2Z<;x3/TwTnCfFhP=A%cfBӕ>\1HŶƘoWBaldކx>O)"0!43qIH.V|Tš6PAn"`#Bl7=U* fEiWu$`420"mm؏.ht$xq=&fKnjk;")2D *L'R^x1PA]j{> %.]E.e{DfVДP [=-+\6JRQ7z" x1zu2Kٱ>/LP%9?m0\6Fڠm-*-oDǽ˼֍&GYl jAp!ׁN=.{9^!<u > T[cC iF֞|Mԧ*͵NJP55s paʴ0*6Г몷5Z*gF_Ã[J>f%̩~4.9Dz^ОDW^xv˩r9HZB(=N a7xgTdOWODqqJth>״) +J!Qco8&pqkN9fe r.b@3 uiyq^:bqCuM,f[4>Z .cblQtĤ:j]1[iQjUԹؔ|#,q :vޙ(B v&G sgTপq='{t">)|\jfwmr#Rk*2 EHcn-G@l^s۪ R5g}) e7Jٛʘ-sL$ucے [rZ4~/DHhaKeb:Ýs|ӍcqQH!|eͣRCU&C{$x_v:n]+5QL!ACvos!v*d`tUSRs[ڕ z.PeNAյ K lᗎu$@ a]9|UƘ8@̖D ]ݕb١BA;ێGA5ל(`Нgd2ڦ$ @6CCNH mP|Q]H~DC?6 u5KQ$w' y* * ؅D7˔ТOi+ZQYHC$ɭy>OP od]^Bs#mMi,ءD_5^53$gY?wTxV_55 <뙹.j1.Yǖ^'m;v56WZ'4$E"yŮ V ugvjDwǔ\>N,Vǔ g=R~ 7\jYn0T*.9]n25=e*Lu%mT.& ecyF (Vlݍ07)\Yo7&g`mG;2ˑO=7_d,kpiyA9i`zPF+@]P/T5*2ͼ2Y;Vht y-N ] !MSR6Ximb.}g<}o}|@~kpUߞxǿ=͛/~of~?,QQw^~ -Go/?oOy}W>{}+6ħ?~ՋO__oݗOn'{}Yx3Lh>l{QCk9`ԯX$`\3 ; &+F-8& 9stJ;0 tsHWia[xA(wrtDH#hIFJ4|\t%]N-2u-^Cd c1ԒEV(npE 2}YZJ]Ѥ#H-pz_P\r @aBzi2:B#qܝ8]:xKx]vKҙŹ칽Dygܨctͺ w#LWn؇1mPqf;x&Trɇ|o^J;APF Eu)H;Zs `ŒL{#'&i+`s]{ 7{!dDih]Qv.z@7qh83IݘNkv LɈUyH9n3BNJn)`G R9QL읒y%Sű5%^W=o5ROpjPϙ0L"V|)"7{ ^3C˪I@_eN7 3"VJ\YUg̎1MJZ^8fQ{N,TN,MH;gBl=nR݆ 7'MJFPxҬћr4J}R \JBY <%n^ mb7փv;BnTp3X3)CwL씛ݳ3-}L\ր?l%^T `_LI!X{fJFD֡nRMH|:E^Єi 2*,Ug@N\ 14F5H)JJn%0/2vWyT'd-{[+CjhADJvmEpC-65ދOCmE9BX6m=QҬܦ%W `%62hݮar5d0zzȸ`i AhU0"$aMnIXU P?6~єzvUsu3.U":ir* W6D54r3'C G(P\ѦR=2MuZzAUn@vԀpP9A95$.ݵ|*= ȬŽHzT=,܅cmW5*nd(ᖯ+RɊ;iSTʁ Tv [-F$".F*k1)1 [ B^7P|ӖSkɣPw5M=Mh+OP6Eh)Z/TwSej/aH́W[*7׫d_XM~G 6@jlڍ Ĵm,4.=s6S=' T=<'lIq[*Ͳ |>ke|TKgLv\Ɩ̀hrID$4sOPqM1SRWh>.v j\5tkvK^&Up -82pLIOY6 6[P1c>it2wF!aZ`}]iHY\F}ϣ9$ot3r\|hxZZpR040O7.Lqz똯N9V{jp6QsQ8 aNk9X%]j>I$=vy5jG|SzS==S\$2'qk̈T1x}mه7("B*,?e/]B[6`&Rb|}jZgbS샑#-0v!y]1;an5bLqTIM0q)Y*i|z>VFԳ?@IˆpT:9UY!+'MQ= HWnrY7YzքJ 'pW> !I0 O!as^ w T1^98y0T뇛t1۔#yqV.&K͟6/ԪW^_FroI%Id=V/K[_pHy%[<%__41S "n(7ueYjG\d@]r~eWKM0$(*~XMZcL@~&vfiua1yT:]q d3-k!~ i@U:wMR=nZ9wwYpA[~iCE*ŽtW1Mg `и?G"4nZ(Rk"%LVۉG-\̚a,@7 ]c$pX\)=0Q[6DsHRuvM3΁?dQh*:Y:ETӛgaҿp]~Aާ%}+<_F*Fw@6V;f2'^>컅OW' }[)שm;cte_Y_)IГve%ji"^ z]iSev.SAeI h82FfC]qX@`'EJk05rnƝJ6(,3.5f8_94|f3 mu6Qz  Q"AQmHq5vE-^)Oy7[.+G"#@ԫv 益Hq6v X缹V!PD~ *Byq~C!ҽ3i9^Z si$dS[܈Rzt+tpPB&4EgCfBd7Eˍ/êeaɔa-6;bC٬Hш&6r{Cjc_bAR^~s+SSq:Q2k BVρts#%1Xl!~kJ{|snR.`|XTi# /H}̋%9ŎBNq>tYxEJ,_c5 C6qEE/c~'CLNJ#>JOFžq#ԧX#[u$)_۠ǢOJYqldW͔b"t=[!_4K- ZbSvu9"Kt"?@.vjTW|ՒY/c EY:$ӸN)!_a8Aїy&Nֈ_P\QPc=Pv$vr:@>T"yoKS!A"\El).i p 8d[*)5{Q,q0,S{Zk uK!Ic%VP }aoJ:5;hSN9[&냈6%)o:|Җ#?R )Z,=?#?n_; қg'ySBѻ k!U|l䆁J2կ Evz<̏=*3 5,eV 4|3T+)y1 do'Ig",)#^Ud%M: ((0蛢 ك-V4Q֐}lHLTĞRz=7T庺*;Tè≇Z ,5ܽi7o&*(Eqa?BR )y)IG4~p+ YU&]OUK--mp*$OsSMA yW(%ks|+e6Z6z'R"_UlC઼Dj<æbLL8I7gDFis̤[RqBEcɏ[r'З ?eCqDѭPl4^`` h޽ϩIA;\QRGPyj9qt )^.Ũgs$E6`mm I! *}onxG8qBcmƓW[|gļvNZG a*br'3AD"|2F$}qa,zM@S4#s:!GhTBuB#$N{ΠĦ76][T&A*,~$w?ϟ;7hR}}ϟ>7??~ _??]ux${R 74TPj}>D;aa>` Aa҂: 3~/q>$jsedb_:CIUsn2t@+ jHfEVCnKKޑ`O '_ Fni&lk =0hUȣf;oXWLzOQ1 9d>@"mZz4pȈ W\!̰_kaFZ*sYz콛JNTBtL9ɦ2z#=! vf@¿5~ @Z;$Rsh~_!0sH[)^%q}aϑ{}7"{hI1f}S:1в޽znMr9~$:$z5)!^kxu0ذ~ˣDz)+pechw|=ՏIȤ' b%م3Y(A:Vِ7Ɯcj>Y-C. >#W NnxLj߀ /31gWx(nDSáCzg(Hi\{,hW - o'?1Rn uhFԕ_wMLD%ScM7Oro.Ӓe(S1vFdH"';X,ָ.g&:qjwz"D`*\1 9?)Pr]P0[q[lUjCmhbZT-fT`_7)ΒsVk2 X}+{4ˡ-M&NhxףQ1a;ݯㄛS[R?(D= 'v}4m*Za-•LN;3V ȸ@+0iJ+hx΃ gEG{BJGNE8 X5xYe`| od mQ Atz@ tH9qz'2j3Q0b X1T0@%0+WZC0ǎCu@ɭ~D&n)f-heTg8*ʜ54]炵cf[Te]K*u\9vڶe"D>uFR^߅e$~ ?ønj)N.b6Gݪ,X  Z ٧R?UXҝIHx+#Yz6+U\^֒aU Z`cfJSLK^X;JµH;BOW#]Ʈ2'n WދF$vK.=Q-pdh&| ]8D I)w$.^!{#!Bh=Yݏ\A0. ->V{<]!kسMJҷ*%9DpDa*Ʒ]iClMBjEzc$^, L ?o 9ʈa6>z'o~ w$TJ?/o~O?5k?}VA˯yg|~غ@L ể\\5!,]N 9Xsr)][Y8U3R aWՖ d+WEN$eJt" [6!ՖL]̎ȷ5z^>a!$3+ra%b!,D~XInrV. CqBKϻл4dZ~ @@.V:/P9fբ%1I& sY>rrPA)-g/{9()-, ;ޥvY!k3NwN{>t{ y)@7 XTFa=do _v`avl6(uUۻ)Yl: AT>QBM}jPd41sP˩ ^$Fro}d+ ?mItZրqUo4vU0^mAAt8h*_forKwsL -9# Y%i)`o8${-xMm N$H g,@Ŏ]sY[n" 4Mj|z*Bhh0%.iMTDۍѤ h Ķi -VAp2wU٥˞6q?e@}~pǍ}BZqb& [ hM U#ى d5[:*xqQ-sRatQbF4'3kd)X7]KԧBKW]E=OHFáJ1PN._L'1FÙzoNduRYfߤqP ۆ#>V%a{,FSs;C$ܜmS{fo(o9oJ#D*"=h%(xe'8$$b|DZ֙wK4Ar-l$=ckw&W `ƙjɩ\Svs>%y.;eF5٥fFjt/SkaFzEg 1cйȂ&iA2K i2x'vި}+ڸzM7 ٩#|g#VԿ;1W>HEO & p+-: +1ҍLPj|P:q!MH3BѾ;zsy8̿z5S鶤!biAbJ”~@^,-qq^+Dr@iO#3#k؏/nH4UXccF MN_IuxՔ%" )x1P`P `=߶ΠUv{4 ~Vq3:EM(TǦGB(\6J*s/= VDׅdri뵪HXNods+a1 Q 6qʨAdD'e^75u5qqAp[xq'ebz;P4P2XX"Ҍ=Xwd 4o 羅=j4V.,QYC F6LQq`{8_JYT"\mAz!ِ~^5Y jzxAYST7.r[\:%)5C|g(OM&HGi`=!U#%]itz4;'I0 kD.nYc] 4RHsքT)y@I5_gVUĔϥ)8Eij_zDsv> .ޓ7;-hN?fe,7q!\{mbF B&/x7Jl zi@r^Fue@v\T( ϝG]P Gclv 0uFpƤ$ns9CȳR <=7eMD\&U"T jUVQ¦R=3cEpl⳶3sẼ߳IγߐGdpPjy"jIfCBE OtHkEpU E VB2ҩAQqUz)/c/Kz5i!ERӢԬc (P)ICTy#}#<2" { B[wvVfun׸'Ou6MFs}5tJlZpڶժ2OF>Қ'u+kgIRmW`9]>k $Uy`YiIAy;0DZ֢3Ly/nQACモT>$wCsU߹$ls'W^H4˲C#Q36+m2D eAưIaJ61r:wO(ЍXmEFJ ~1ڇߜeRn`F*8]L lͶjd` ceiW P֬w^i,粮>E 6ڠDk~g[ ]*^YJ8;h+z3K 5mψd2K5kt%l%Z 4`AIAvI$kUi=}X'is$4ol}$iKVǔW0CӸh"3lI+؃ DD%oO5tʒTl(ɭX$ aRxBVe5(e #-p1KYϥf4q?xkԟ\Z6\[]n坳wG&lPqͲRp^ƥvV9dxT-@ s>k١TUUSZwJ'F[IExq?ÜY>zt>U]V-0jgpҪ/YT>ksIGnQL@ ]aNEڝUf2M/$T啀u$_V5x@;K_9Ȇk<*wb<6oH8ƸMBqVE&"S}Nz#|YSə0D'eymR&ޔH@?9WRbք,iI8,3ŵlF`>ըd S,+z ]v7YlgY+U}1Ʀ[(#"]A>PdיP[QSERǀ:f'Dyũ1.oA("Pk/HM5i=gQMV̄uQ:9*NMI#n沀y}TF rduIuم>$1Dor(Iڗ3KsЍL0N\JU$QgC 6U9T9Z7-^se'ɮCh1JjuK*bf6xk%"Q̗okf\yw^?ӗ@O~#u׳>ɋ_W53OY `` hד˿ً^OWo?}_w?7w,Oyzݷ|7GuvsƟ.~}Nזb&xw,6Ƙ"O#5@li&2h(v "JIIknGOR:#)} b;Ue3H7SukZ">zmI)) p x5TFS%&]#Z$wO-d8 EA*ΉM}4ڷUEʉf!&WJ3u.titgJ]Y"uM XIn@6xS7Dp Vds}a_oTuL\B?آRI@zp?@;{lYQR\R>+7 c5fDF kȣX$ZilƘ ^ȵ9V%-N`V RtfhsKڢ H[‡x$ȍxn]=HTUSjyx7)K1(ښqS1isBpj[`hZ$(iP,ayPiސx<2- GtzEH61\q&Dò`U,nI*_kPE,]GS[Aux9ۉ ɉLtaR vHM)=LG[fma^~K'8J^,1{UZI.B%u獒m/;RfMz$uoŖ+υ0Vcv䵯{f( Jg2Fa 9J9˘-Z`ؒ, -<1*VE.k T"9wzx .0WW: kPоV?Ŏem+f`ZW>6P!Nbo-6xY6uX== *&>m-1={KH]rʡwaE:m|û+G!E8r:$|1txp`GXgiHM2⚥B&i(Ȉ/QT孟I/L9/ bU.R (ზx8 rgI`_& 7K^-AeMu?|blSۼIm7B>_JPBQR]ǚ8?BdQIB.*.%AVEt -l!oeklg@ؤz?#?&UFFZ{L'*mR t4Ҍ ш )n>Z0XU8!'E!%w]׮ҋhؚŽuސhgb~T/zUQ<~V><>N&ޘ M*{׏v D3?j:A-հsdR+/!U*nwTϦ+{t ]YVR˦ Hx (Ou3J$H:`-9 ݲ?WC2C\<~X}ʈӛJOt_ {yU!i4~Gj[mO2OY5D{0e \oG~g_]Q~NoBڙ*$wN $z|w_Kx!c@t\bI]QÇo ';WBAr_Y(3t#bSmBzܟ S3.%,N%22~{Y8@#F>KM#b𰈭3ctN^nӾVK"'tUzo(\##N9PytY@Z#*UQO."G,_UBqM`I' tay ?@ƈ8ńPҴM2}tڲFw%B G. Vc瘝;~-[Q"2. l1 endstream endobj 32 0 obj <>stream HWe|D(9v'+`Y%V) @ xTuo [O]]]q{̱/1%![\?]&vɰK5#knqO+3kWƽo}^潰")ȾSڼ b=&# "S ٱsΈBsY^[9_j;V#  =.yM vek|CjNvV={$z'H"3.sC:/W d{>\nǹ.u>42GBrv)ɚZG1\5+Wgx-kc/o/=8l7*Fȸ]o$XbUl>+aؼV6:yޅEZuOmĊ52F{.)pM?#D6?p+'@q DU/- H 8Y7? EZ. :V%ݨoS" V$ Xְe`9ʠ-x H<q}ˁׯ7 \d#PKaMݽތ |g.tT"68H _? ި\9ITt^$xCZhP5A5|sdX[<+< Q;_(xJ@/udIuNf -ٲ9Msb1$vɞ섕>@ SDJ\Q#ds#"[R=*ـtaS?YԓdXfHAV[T!N\rB*]0 %vO+8Ɵ? ;\uTE#XuRVH݈y ٷɔBGB789Uӳw拿p_5hi^9]VrI{ #Be6>"{BS@j^lYfAAi }f8φ$7K[)C?pKAĘuڐBK?@f b1e6Bnkߢ>d%0 D|qBIID:KL ]l_SRAţLud&KT#b⃰T~R: GZ5E: ?Pa27ڵN DwƱDߔ(k?d5"VMB, mV5ew<#\)O{ ? ]B^͡Wn%5ǭ|:Yխ;Mz;H~-1QhFB-7|eQoYP:kv2cB[E-V72󣃨bQp % crC 4ĠKLC`R(G B+':QZlZ:)XR ~/?||÷~ ?SB|~}?g_}?}?~˵_ʿO)U1z;SmGd{{"qvr Y50IglоNBuAO:B vm/j(ӡqBce`cUś}ͪ?ZX,4MWW8 Au>J(@MDmCk,`հ}5SæU!5a)wA;˳VcQC"xr_wt }6koÓSh@uk[5V:>zo/w)O>HMo=닭h Uǃ5baw3`x\xCш#:g9zKbtG|U$=9cx 1#7B><[OD^ )3O'#ۻ4u%aDXk7cmkRw!AFq[1!PzG |m=L~}iu2lBY+$mMvk a1⤏DePiPS،^58jPלO ^gS ^^VhSjN,v*BP:qB b_H\9@MR錞DgO'6Ԭpo>(=syC\E-ӿV߲zvG3QQ1 Yn[!;n,?ۻ5)2\qeI/?ҩ *z%vέ3H"P{ 2NYBmhg#ßx02xYu7m9a Vtڿ#^{?{O5{Ta00UFQBsZ jp@t3a9t7-8ke|BB=f,DH|>QnID]{ /2"aj1>WT=~|ؑe;9rL > c\V((*gEM/:2Б"PJBoq :]յ^U(2qHq\LX2.=Ul֋55-8,Gcv%J-1 4V8`DiaڵEmgc_4k!j1NҔ15&>UKf0>jO H&8Z3BjH!Ol~R3y y$g%Xu]R=e>:k I!:Us)RPھD߮*.zx9 +LUU4"Ǘ`k;[y OqIL)Zdլ6.BV٨zSUoW{:)R&ƚ.kGdDV5\ EsE&QCyP{A[V08U D|Lh_d*UǫI-ي=';eFBB16"w "5bQ3ZiDRĵr0eÜkftqtˣw7B2ڵlxI}g,5 $U7 pӈ=?^k< cQæA10Y"al78 ViNEPnSt G8TQTUD"*n^Mhh`\X*]*o)U3R<Ҷ(UU1Ѕb3T4n&nlk D!Twђ N'bJ@XYh@][Y8kYgYȔA2 r=D+ 6MRe@/}RuBVi4X:"(ި;ס&9<$'͉5N ~EoDP>[=FGeࡐ_/y{ WFUfBNȲjqgd#XN>mplso2ju/@n_OW#X=/q-|w;[T6RLݬ4Ĵl[' @y1 Omk0m%DXI_l ]G2v7oܽp x=]p3ab^9^K| , VP )M[p9eM2k0ӇL@B~_xښ;z;AhQYjvz^hѵ^1RG`yHئ^ur*JC4BX %#ߌCh^UkռxhMm;Ghl$I `71kXβYݫ7߽޾Rг34!yw޾g/^|}ǻtW?zП<+ὙFRWV=+FFéɹ*PgWG>ī>D|Z"J$ ] ,g4M@8ߡ!C~Mr`* Nw+I46PS$ayo53+v!zC?'tp;|Ը?:U 8NJ̍%pẘϏя"T_,d@C҇*Ӌ7. "l^3{U]麖gNH 3,U,,+~8|DL,Ap%b֬*N[>öFզϗ~b l&]@Ml2il@$-(ׁI}zRU)fr´QLМ qL!\>́N*Ro)$ U*T16|u#WCcDm;YOcy1VNF+$kh#&:!>}ǽz͜]bŷar0$m?G9K7:B+6aĖD+=uk|S `Bh%ȁ;eE7v'gۂu5HHtACid,GLW7*);EHJ !J='cW6㐈6~,ˀxCdsW@z;YGۡJW{ H47fUHmM[3/ٞaڔdR5p;h*$߲ܲP˦5[i;ED+=eYrh wݭRF'ב!իT9I\BZ֡NH 2p-cy3eeQDp^ hM[\% X5PQ>X&gC%O)9M@{kTt=j(@s*{W"8 -uH-M]YuIf(7یNL)m9u)A셉+qpH(JsS laI }AG Bd;vTfp4X%u;G0ad!ĵ!vEtDl@߲F=kDk'} bfO#GEtcJ'DdNT5ݿY{Qmw@Xf$TjJ^ESK>#b;2N?hw{ dd,ު-~ 8_P'_0I8EO=7 Ѧ| _23io™t>n ngu4L1[`) Lr)VbS.W7HFDibcaouTrM!O~$LU''8AIYqjFL@ OlЈk ZgQ%`Ma X. hes~ iZ ~0c&-FRť8yA\Fk_bHҮM]U\GxBpg] xP5ֶ8ǎ_DtDX*UD_Mw `C7^{h y,;j N蛬Ta@aoAz@cc7 YPiN.MGfTwT볏=IװAdmRh q<T%R}B{iו]T45,^n۴e* F{GP^BtHP-2CIoi rV$6Yf=.tnvU8zAɴU`pU"8~cd:zپ?7SLGtl}` "N5+"YS 2Kj>pI5D7T`~_kܴS@eXZ]@tD1MllXhqw4sy2W}Sr ZF}E)dn 5u+XQ  ZG93K3$)ikw,zEM$[T43Hߢ3\Ԝ]4.P!צŏp>ydnX[Qjz6GU!+d]7:`abZf,괪S^z˜v#`D`J!fP GɅKguǷW;"? Fޚ0CX;@ F+C@p7JқLDWzdqW"鴵m` NPʪBKRaXsnR6Φ ա0۪$,Fdjw\.rQ D|iK<5ĉJW6[Z6S.VwZ37qBV[y4#t1^ēldP,Q$* !HkMNndrpq~]kKyH% ~ LR J]YI*җTR#Iaw{2w:BI(-e{(RF kpd!P42GO$S0?k/Rd:(F_1dGOiT kAv撸k6ԒTEO܋W/4[懕HO_h:nη R)d4gm.@9tP*(.̓18\ $`:n/@XUM4n]! F+j/yRɟu̺<2w}un/ʥƻd00K[vD%n_~`٤<H>#z{7Qc<Ҍr6BP+ibDS*ppRKނ^~'=4sm\vVn”N)Ù}ĺ8o0BEmuG ~Fw?G]"9 `@Y<L=MmlcѢ؟ ٫ĻQ7rDօ)G*l*Z():#wirFSҪѠ0Y=> [im5)/A^a#'ɒu67ByG*D!SdAᒖOfɒ_J^(۬hS$A4(:Yhf!xndos"h+֥.khQ5ǘ0 \mWiǡ#M/@X,: o#+y& P(ittFE' 鐢-y1ZQ Ft͇-kL[eU*FP沏:Dsy#\Nh\/d N8sQId]124k$YaYY-fe}(8Ḧ*|(A!ȎR_D2[>~q|c͸>4QNɫ. DRɖfL[<.ı MYR&DqOG61>IWlR`$1} GZi٥i$LoCnވSp9E:e ž=R<DQՃ'Xa|a3Q dF ̎"Lh) ׻gh(uA!$*\H%4|Puw$鍈aM ҫŌ#!6h.mRNuHYqlr# z]*kɕ8[5 YN۷~|22T\FJ0[ހpI#m!7r?;ĆI=tx蹘 A괞w Kk0z#;VbؓtGv#=w]Ҝ!9*j@F*Ə2Ͳ>CN7((CHs'gɰODciV֓@!AӑJ\9u!6/d?ĩU1c},ZnEeoڂ{BIi*RL:_؟u }Ӱ г <)4 b\. fFJoԹt ^*=:`Ϳjt")YwwL'||-¬C֋8}]'+ 4u3ӽVͬ/liҎ,$Пu[*hMVSp4pDgyN9_$NwUnȿ:bOG4ct!m.$ ZFk$|o;&uc1~xKV)VR( ^/ ~xYxFUI<ʢ̃¨ 8Ua}r" ɧlJFMp D52w5,3Hj؁&bf(H*2Jt^{QnU~LfjNgT5E h ufgNtv+:_ĕ.#WJ--^K/Z%d ٢v]"=4IˈchЬզEAjiMk0%5>$uz,/饻B1hTѦju>dj 8H;Ⱥ$syTɐB($O` ۉ\xm!#>FPRdDz3 Z9mQ"[~=ت*3"dҩi2!SF]mF[IȞ%Q pk`փW(õj?7>Ʀh2R*AM3u[41 D1f/`)|Hl)f@ڲojúҹj4W64[q`I=|^aJ~D2CazJ͐dpb@6r?" 1Zc<2Y{}Chw9a!~"mn+Ѽ^6bNur^Gothg_Ӓ KtE€1Kvx4GE )37KnBp/鑥PFI[8W|fMQk}ml),ynFAZ="3&$72RuICb Go }BWqezM)"Qyu!q||Q|).pZEbȭ0:&.dVS2lv=uHS" Q1PpVBWQEK ^4ԊХ3*} :=BcLv%- *ˆ{f-Kdj,/NfU!u7nf9CVC!Z3 :Y,Llߢ[K/=* *hҋMQi@߰s0>-S2&e;[l≈.m0aO n.QVy669r,͝D=MJW#@@59S~2Q:cA6 $ߜ&ǞE 2[)wD/}̋*ȥW2$z"q >NRRM@6ы>rdNU>Fb>~'X&N#}|4 aU]y*UiKZT^Z#gE&?s;ɶ])8wS * !ը/[IX.Ķ̧K{:.WuP/P r,D~c-m:Vi$d? Br~9;%zW ȳoL#FڈT Du;$v=+O{o 7:z!AB .du3=u|sAjk胬s-!*$f8ϡ$&=ǭIċ"{e)zqZWW8uc /$n#T]l*/$BhF#S휭TSq 783($飅2 {˻Rm<F6UJiEcɇt|_?N<#rIGRI:sedt 8DT!]oǂ~m%*LvE)d9p>-(9©F)HZcɆ]\3"Byx[##Gc5az M,KC[zҒbAE:* LOD:SsK:'6)LM d[X􈀹{3-;Ф2Z8@D" mo %툻GOZ g(oo e"#멻w9el\r*SdU^jRB1\C0jbl9Q nPYپ4K.XT(6- y~=qC {}xFI mΘ5qgyܾj̍ձ%Vߺ=*3,cI]>5"{D)'eƣ$Bf꼚)RL贰,5~u:"T%]mT*"w[$(z85.ڌS_%̋>q^^hKZ.IdDHx f o㶼Bq32F7>X2:LlB4EIR H'+ܨ:Sb4R4%6[4)`STC?M—>~ς_7[ʗo1wH2BHmLٜꘂ[$$!:MG<P{@,1NiF䒌$s&-Q $"Q;':܋n;ӎծjҤC .>RP-I ZQs }g&HY#%5#"S-YўiW})=1S_72s;77g&Cݤ>ҊQ}˿L[2J;4NWHB_7p)gfL`##)H R߿BZe䃖5lLP Rf1($mLo#M5ю@(rJw @Q! vrьW2H#]Z}N9Nth$;:ƹHBri$ܸS;Hx^w4q`GmQqL5NN ϺnUƛc{dd|ep:Zz\^XO!v "n(̄Y pz% =Z1o`X 5׆5\D-Cv|'ޜ;Aȥ&QWèɏbvy<"=䖆fv6Gw="޶ۙXp`AM7Egvl~piY)3`B`]QF1-TOHUbuXS* 9ܩ̯k#*5v0fuE\w`L:8 Hhl-DOޟ3"rYդȢCm{Q7@)D|^ڑRUZ'"32BiYu@*&L걤\aN t 2a.y;x|{9d!TрutȪIW 9xz'(޷?cIqAtW;96UNwzrQücs Q:8YY5\XGU;(*ueƄ"'~t-)CRr9v6<> lN+}َBWd~P?qV@0"?rotd=)mijZ9 enBVNu,FgW5Q0 XMQ T %ȇ@Yjk%XH錁9}fhfvV2u! ^vdOޑHj@D3I! $KGͩgVg}FSXڧ1RXKj& zȡq3ڂarXuAEՄx"s 4nWHU9@4 6Z='R`Dui`_Ltd9 /]d@\H^Ew:y¡S>{Q;x]0He+j@p3SBC(,$Y{tc0ȃa&UGm&WUZ8!Z0-}Ezy>gE1(IkedqG˙&ƞ5.DI#<°];>;-Z C2\v j;eSʀ64]^$ۏNg0no`1 5gdvC*FWXD1CMSu9MYpƱ]MqS= ob1Uw8Yk9~DMRZ;IO @gLa[X0m ع  $' w: ISט`KD>=;.ILh!Yp:$'AF">D'Hdt+NsW=r/(*jY*Ƭn^!(EքITTFo(V!ݶV.|\U2uY:]!6u| ޕUMiN-rWB6n2s'^'$`zo˾MhSIYBFC76gG~X)iq XX^ -M%l1|YW2,G0 C@0z+cvAеWtzkf.,;SdIJܡd \NT%9fzR&4Ým4W}TD&ŇC:~b(auuA6WSG'Ӑ5 #q"攸В&Lr&e[LtRZ8-OR{GFC +d;;U.4X*c {.#a=|soCUsG(UP{{w|_~ S|R>~|/͛_/cǏO??_yǗ;?o~Ԉn頞ECCu30Ƨu)3z3x9/T 7'T^W[ $[f#_pPS d9v}"42.FeNΖyH!fp83"e'ڹCl8i̖^+]Aɏ+IR~ lDWf€cd9BǵQ76+A*f%yivZƿ39fAZtx@sċRm5z ;S7nX9 E# /"^7}`2V1(2}2 .KJڌ23{ƻ"uymg R)FYw%)ajՕ tE@abߍP>*$KkKq1-j&ɍ;zu)YPDvK%-zʕnC`1'-肁=bD#YdUŢ6B B,I̢N` 1gz+mq:9p K<1=jʜޏbZfcMoQk80 g^}OV5*OCzl )= 9>(-%jG=6;=RZ$]dP;HwAY9t Z?[eҟ8k%D+ւRK@"%)bas'H&hb$W/b gq8v埋zf+&mR'y -cba'` y]Fc!/ɷx9ERqpTMmdj8ԮKHa x)}V_(&>$HK!cvFQs 1W_'b *=s2ȜJmYt//xzw Z`GlK]ӽ=ƢCh4.7+O!3r{&Mۧle6tj /%ka]+] x܍eE뷥x4^Tmm{T=3G[KhLsQKs4%+$z2y&GƺV5Ge_2S,}Yɲ,3A$5ahr?BE׉ww -p.X[PغL"ڑZIhѦAej.Vqtci2CL@O)mWͽ.S-C< ЗZ ܉B/0j1އ4 ;?3Ts7Vs"վv F e<)%UZ+m.6ָ9 "R5:G`9ݞ Y:kى!&Aq`^Y`sΌEXuLER"C ,vr"0x>9F˔ N4vPL B]̶R*BK88C|Q/_YF$h}ElxP CTL oʞcrBm:$Dܢ$mΦQSBg=Kf J >6eQ9ıڠQgbPv&:wf1![ ѻ!|9Uݢ5vT+l}r,b^fG%RF~PIZi,$wx'.4J9 cÃ7rJ.8xhm/yy\:P]䇩6Ԓ 5B_?-F3w=ڸ֍%9j!u1]mL/am<@qE*CDRJQW5mI9#40"D dJ̚tkB)d:΃orOKigE5 K;T)OUfҽ+ ϐ|YQҡp5Š5ŲwP !4O 3٭U7oYw`bV}Dd(xwmB`f b& SkB|fZ}Cw5cyob_vB UZL4iJi˰l.?*rIzD\c=d:%Y #k3Q!粐yGs6ՂU46I6į/q-*A=TbcJ(x&R{ܟ~曇_<?>ϟln2IFWcؗ3箇(#6v4’ߜo?пQΐ\eA*THrg TМ}"!2BV%H!;I'a 2Y~  dy&eT7:F/б; 2j w`ưZx2n3Y1}`E}Ht[ z`_R7,cE<} Aޙ1*:Oޠy{3MA H3h9f\Ll'bI|-xjA?[AP%.Zf-1Tt/i#DWvhu@+LU(yTӳʯ =?K1 O[۸=mlTOuA)}T[[Ü}ZUXTH?`fqb{کCUExJƢ"hXv• '֓$jLB \OZF@(옙╩I6Spǫs ˰Þm))`42%"?*XF{_1.uHCz8qϬ'auO+UH#ބG6H3'z`I)GhSZм4:: B0*(HOgBJsRK5/(&;܂c͎(R[d&M rFkmQ2@5 5T_fiEQΓgƼIBD~B^:;S?Yq@b/s<3@VGo-eM-TA)s>[Wck{\+x:)_:=oUC,ADRO|Se %-T4S]Z=..h($jqNϜ:C浓JĐǍv .j86iKdxvEv;gr91N2e 5{ g>׈  k|:L>gWK.1H^ 2.`&Yk3iq[.B`oqJwW[70Mz&W,@!XCʩMP-)S۰[q(>o0S7^vsܾUztow2R-7Bt"ҶBBr#Ґ3R{̡doi?s`-ډCj=G̶t]PIQ&x\ k_" SUGӮ 7GDYqD_QZP>=pU~͵VKs!rr -_$,F3g8 dj3/J4wܶ3u{~vJS%c%}NA RXܶQ4"]̺f 4@LW X+x(똩,TƩW nMK/Tҿ`V_DTf|8v.VBkAbhWۑ @?83=Ǽ +g[8¶.r V4hUKϯq{*[~82[Oo׃Nu8-ûò%|=Z2 qf!e3W$^Bve ͘17 򄩍CW, ":A[.w [%^6c% ,j8aY ->)gQpB&Q@!1Zp3ܰ'N1cۚb-q_;letI7T ?Y̛9.P }F+*aZ٨ƣ9'OAi'RAPcⷼdMEU{xPpr)t(X-WTtE-T7JFfu<,Z l/B V'K^tIBSm.YЖCYȨii wf]\yTq nH&OQ$lgF|voT_m0G ZTK4?P!32o3Y ]mLȞ%Q}[.&ۑZn_)(õ"ץoF82TV9{xbn']tbđQ![jU,MjUat(.8~ q6;xtH5lxf>Y/{J!EhA׫CC a)7 (l)Tɨ8[ ^26>y"}"3g.FD,n Ѽ^Ďup7^DU$ԋ{YO(ФOeP/L_VJT+!2vpzE% vY㴩t8_#VSx/֨mc5" r(gVQj |c 3(Yo/Q4|z<8@Z[bC2ˎ&_`&{f-K5 @ x{Df"43ʪȈsN)"qs y,s!(a?_\{<$ ;#ʐT 2"/ѐ* F,F PHhR*! Y Ej9yw DߕBGduZǀY)qo`Nl*f,8u}Ph3". >-sw ;/Ap^3R nd2/i;ms7S3ugw4WdB=@Vρtd:9ߜ&Ǟ"\.쥚VpGt#Wh #T׵Sد i$մx)T^4.)ʏw x1lIZ*GF#8l>! M.j*OؤEWΝ<}Jo4vpNDZ>))Bv3(DW.G.23 XXf3⿡/Ac~vV;I*Qc ~Q֫Ha!(1A~^'ƍ͛Sw*8<ԨBo*n܃\xpу\tQu&9S+8XCm QΫXHX׎=f6K$3,pS?LJ|_HFT$62ΡSq>b y+ R٫޽+U` ,7aQ5{"ɇt+}-r.IK'臃湊Q^Y1{BFnBpQ}ia`Py%UDY jW[2HPRe>++j )9.hG@O6,Y˄dvFGvᓃ/i4x.9fmxsv7? X9"c<|]Zs<2ޏwU,f@Y-h P7YV1a [ F^z#xA {:JbS '[^FOndH Y;{>VmmȊD'ڠپ4Ku083'@A!&D/䱌u'v4}oGfhUz9SτHy*3ڌdPrUXrX2&Gq).p 6iE!os^ܑЖx 2N os{ V om>4,fdn$}8pCz MX 2 `ǹST5+cAf8f h{j*5UX6&_}?|ӏ}/A-˷7|?oԓs$#5+^4&&ӈIkpj (.Rö(ߐ2]Xb$ uJ[7cÀcX#wD{Qˠkt=Z@;XK}U&WP#eՒ k5T4w5kjbѝ5RBDZ[[.gdoJg׍Neaz#Uo2D 9˿L[2N7F%9 psE 0nGeZA3'22RZA@E+16~t`M*HFķ'i.%\d [>Ӭ/pq!%J[1eLF@Y DDɡsҞffDd?{CJs74bߥDuH$6"rzR45:8ㅳ͒*)s`GhQJ )P7mvӮj^N<}]D{QaҌ*_!]̸6zrwVzr_GF ճEm[j z4XDX_3!aRI'[M.Prv:mO5RvSXEH;4V7oMK62Og+*O9HDɄs7=-Pz.<~^:4 WJB1)h/E\ъVc̱/=QE!9^ګOhK KwIa46i=#eRoGgu{0pܥ8Χk?Rhv6t63P&Y]Tl {'F6C.p >f4mZlm^9? 하,l&ڌ2?+)&g/uʞg$Rm?gzj;(25׍ɯMԫeX|DPFn;g"HWlA` #NdjP$-nS]&0 1}'Bdu{T H!0xӦX)nT 6ϴ^X^c&X 9c[I,foHv뵬6{uqoఉpOت@\ma]] ,^YMU,4 *EiS6΄bGj( *'ZAKz]!zNٴ6)~+3na  :\05Gش&I s韒xS_T5LqDŚu3=nPy>yu\K}>r{7(/fm q^Kok tc|P͈;Ǔ ᔁOupCYpx5\XGU(a}jNK!XUgK}vp@髺Q%rY̧4jY)"5|?C!$7]M.rƗl&̈dsbq>stream HWK^&`x1/geˬ*A0ATUw%NGuu"xD,j.qnxS!tXs[2}u!1 =mXN>Ed>.y{s˼f Ǜ]m. }\_0@Ⲇe9k-|վFzI~ud_oXu޲,_Íkuyp\&>sk;;~y_1:(,|N:ZU!ˮ{%nt:`Vxa7,gMsӹ5?x H4fPtk;r{iu쩤@^G.<~ F^}D1ȷfǂݮ=&8ܛAf!knxo`}ۺ,}<ޜ6G 8b ΢Tw,Q/hB o gM1V p?qg;E;`$N2W2o:Hv[gk3}[}u66)6 Q%ZvH|dDv`K`h%3t=k% !:}e߰6 ܝrZq!sC!l4&+.(0_MPګ*8ɮ&ɞhC K~! ‰'t~28E+`:UnZ#N[ ]tJxǑDt ѝ+8 =,k/ʊDlCxPF+Y3V9Zu4g>E9GqZ%J_7~e=ߏο#7c>%o?zF9C{QA>%$]d}Vm/ I7sj eImlfL1xA5\TF`!™WaD,G8:pMc$}G`2C8 tRYb0 ( >991?eDe=A`f!5"4\#< $ؐYbI%l{߆BU/@)@߲N߽-Dggst_!yȺ/(.İqf0/Gӿ"LgS?Oy]ףA0m.ڥ )DHbߖ!zv$H &ng8 c7p 4y Q}( :8*nBOLWͱfQ%6ix|Ï@Y@0QPTT xsar`%s@'yt3@l[lmA6cDD$ #䁊f;h'FE)WRB8_Pi IcӹŏҘ0ndÚ\yAfa9Rpq$0 *; P{׮9uir3j8hss RmM!}-QLV(6Gv,[_Elj[.?(UHȘb/v;uYKTPS@&B"bl̯DZO!6[V!F ]6-<ߋDPkW3*|"RL6o>ctyH)U'&Yc`\BH[HƷrZ?$c68.}Qhgi.Yq#%A,%Ρ2ЅT`fTL%Ω興`[!kXr@U*asՋH_u4$,CPzUS 6*" =hڜȑ7I/ (>`ABJҪDޞuwj{z9Z-@wJO1{xw>RaNA">k :GDBwq[.B{YJ ]N4JDٰ͞{&b%~SOSih*2ɮUmsK T>wVE&mk;Sޡ!7RV@7~n"䫠6]肖Z78;dAK1x,9gEq36PZrBl!CEIr.x\HK6M_aFK&2ҙƆͺ,D;uP_"DBWgZݞgrwBYmaa>99G1'Zˮظ,TYZp05䚩G,6A:RL.K_Dӟ7=SpN&87!$LcZJcOI#apLwK&޶28}Kb$JA2y pOTDQ24=Y;DPke _$义݈WX4Ť¦FG\Hx־:2yf7VX-w#F)aՇ p. -J,_=Ro9t@  Cߗw lN'4f1~V/kMEῲS^-S/U@)R"hNN*31w@!HzΈ|s\ O7hepXEHDXX x3N<C(}Pq>C9h@LKN400* Ã#a啴a9aQ`oF5.ɬ/u6xS Q3p } z AFZ7vA1=u5S,+>tva/3,sUt[}yGVH0`L,pKy]u! HLo)"|6bXĪMWis{"N Rf Շ8$ѶNyj#+Qj 5 jGAb*@Dӈc d8e&ݷ7˷\g80Xhv!v_W=}{;G#b-0]G=tӂ@bm}^߬)^u&W%%n}Oq ;MD&n On7Lxe O>w,ea3\mԅIب*ԂlLC%q%*z_ i$Rq? Bw|k79&22A89XTǵe:++pp,4H$;FlJy?d JbgYqPzg*Ʈ`GJ zp?C,.vK~?o>{W^m>~{_y?==fgkGٷҍHuKˏ^~gߋ_>=oo߽_~W_=~߾'8I?glMyM=< w8f٧&@LR,q6?ۿ!BR S5ZX$_~CGqeK-wyE&ƧGjd 6hm "P6I*x t-[GmtugUʖz)Q> MK`4p]R÷ ()fu+Ф4Lͱز}%~}Ie'c 'K<' Mc3 zR8ncnkޭ0WڑW]e*L`ΜAtv%'@z?H+ e[.F8۲ԃ/0DIϵc@CnP.q*DŽ@tz\҃o`gg''/Ty nRń+Y"/t2&rA=GEh}J1د6fΈ8@SȏnꨍJd`ZC`( $1R4[)L&솃O_,(osfn7.{1MgΘa]s#2vbL]iju&g4 v'P1)¡@M FPtd3:=y" Lɂ=#D`S(f, ƖUQ+ˊr#)KWJ+~vo ;]溲F~;/:5``8S s-Dǎe%\Y]!x^)O]wtib)uЖ솟@f#eгeh+eBx4]U}%'FPKњ1=(]=CǢp3irfJYfpp{ AMw=.& e4UR5|r՜[QrӖ^Z, `re=ۦW d@1gm Tb8x(S,ԖUhS2T&ӓLDJVՙ6ئ*rR4oY@QW`G)^pT*i2P1]{O=Jhq:-s$Vi9TK'zQT Ă5$v6~Y 7[oňg#ydũ}R|#jB+L IG3iL0YN/SfH7/yP{'ƙ,PK#!|5mho *+Z *kkfe!e9 w|9Y.hfwވZʵg"+h*_Fr;"u咹U^$zbmcQY@lGP ~"vS.d{bGjcfFe$@0Fo4 ~n~"Hg:Uyp7qʼQK=,_=‘qƮAEExZwƵ5‘-q?ė?h٤$|ޣA ׾,(y ,~hu?Dr'2>ߔX?㤬 nK2y$MzlE )yN"b 'mcw_KޠKp""D1ۂR-%{h?RS|[AMD6њ 3NZPCĖͰeaFKoB|* S5OTJN ƍ%uFu 4vv>~A%,m5Q;k *qd cpw;Ý".Fl=&Z~Ry]Y|Fu ˋW&f  L-4uࠢzc (&h$P[r$dj?dzc{87u fP0nǑFroj_m.hAum0"dLC/@X=\{7~w*Bc틸XIcؔ8EdQQ5=OЪ^Nv98VZ`n6Y8$ua<2\$NySia-5aB|?>M+YE˜$ DYMĞÅUCIIFqԈD|RډTdjjSNyDy.h*1n;/ qߙ)%YIxIڸ ޭ \cWcN_H ƹևJGUZl{u*]]I?CPm5yw/B[+VXFbʭ>fmx&8G@jdH Av!Xn8z=3S](-߈Wh Bڡk42.<0qTs-E7^ުPX; xVrG؊ ׂvk* dY2i-UclhQ>UHbH>RZ%m#i1MM|c^USǤl_5&#'{QЗi vLy"xP2*u ce1ǯHYY:T̓؍7ˑhX`Tċ_,KW)t5 uR"rhmqNHd;R_ꝔUM7EQZ8%.Oi=C͡5w4 9-YbM(mJ2KQKZuss(_,UtWB`@1;r%%U=6.EseDf f{E^jq7r/o),X ];O&j%TG䮰q٦Vu2[ (oOuҩKe廴7Bars4@UO-C ZYQT.sH}̽"Yd)_@a@qZY!]=7"DQEU*ʶ<7 ZVzC -W4tgzzn7ԀO~sŸ-qoO_>OI_}#Ѷ۷/y{O:8r[Q9>mdsX-U![Rp?J_N0S~Q0H ~fHe7y!Cb`t 1KPg!Τr 2Nj5đ[P/{Z(D=B5[G E2t:1lq힀5{sV XvIa/VnEȑ` XS5SmgwefY3( ZV Uf44/i>L[.(9LuiiQjP2"ӕ|𔦾!7ɭb@+@CѤUw7mQczO稛W}^=Vqųqn"E,tE#2Qopb׉1>44#\(1<@I7QC.Oܢ\ao4\c1ki>Nqikf+q0hKwk@j3CJazF(sDX\`i7#̡u/d7yZWl1\mp W3ߘxSE]tpB-Y^!i="dC;q˰-B@8}Џ"$@{1XѠ;}=T(o9`I)˫׶_C `%Ic#O E >p3^,]UpT+x 8?ĝlCqz|䔴>]ڐ)8U4x,p IϮ"TWΰj+Ori쨢_EG )C$ z֮:A$>uNE3þ p]k?Rb|XUiXH m%c"afwE9ueAC\ʼnG;?m@q,q?߳ЉϲP,jA2n8Ϙb5<2M__ac˦UV>J|o4~=J<݆[ ST57BŽx=kekt_̥xw}G3;-f[HR6 J׷ecnF#X٢Ԡ2bA%RIRsHcR0ѳ ^gJQVqNI a>V"WίSKщ"mcw 9MC9R yۦ2n&2&"<ڧ@F3GC28<x([ȹs ΢/T(xu^h C2Q챽fHC[F=ФksvFyzY@c])zA;%٦n`uFOi95He%FOQIыaF.IM0 x|>, 5-'704zjEB"ڳ'YҠÖh|soSѲ{Q؄=}/xgؤĸ"Dok{wJI ޔFn( =t4X[=)MG+> !iAZղ4.rW,L) 7Im=2BW.zClPh|9rT̶_Q*TR/w>~};{J;>/}W_~_9W>.UHTc:c&H.>@ӮEYqn4bg%$**jp]?.IqlVB(Rv=uPƟtօ}|d|r-MoX`Ay}kPM$A>)ǃG;L (<\_2ʎG;cGx9M ٖ()‹nn9N( ޞ8un%5nl Sw]ڋy|× 8mݍ`8S\Q=KTSr*>*MzΎ2gB f3K(ZKR4״jpb A,^> +()b D pPm,(s]۸?`P289cP0ur*bk ͊)]W; kZQ;Ԫ;ެTk&uB-A]ۏJ){'$ J7ٳ݂ũXI/5*Y3zL 3SUZXiooi!LR%iqMbЃ(M{]zDewNۨ/="mIPmnwR?O?pUSE(i{Vєxpʐy:1%;0_DT,݌vd;he:dQ*β+ ƌWl-6UG'-ΛL&D ufʁwS1 )a֧Lk궮jmа 4`'CBUWpBJ7Z5+i5" A?Z$bxG3T- (O]r 6*8QFH:d!,LՑ Hv˛ɶH#W0-Oz)0mێd Vҝ-7_&Dں@hϠ{2)o]6оsT?Ytc>O~о0&hzH%l Q{[ځ\,KӕMVzھG:g6:F;|_qD6h.k =6bR{].4+-RusM%%j%" Qm#% З V8JS=uFENV"o+  xzmj\"kY ૔` rJl3t/@^Vt $-;aFoR/g_e\_}  b Na7`u]VpoF&\bbgpŻY#Ndڐ3mZ> 5}@bSPkPyj0HP?m[`< s{M&6b:eS2m[:E2P%8;QnIW; "YvAgfXE5ʎqbŔ5]~/ZRmY@+cUf  ohvÌpb^}+(fr:{ybCmG ܛGwL JcQrI{7u%kR$ ^"o\JQU-<$ WJtr"wZ[MTRKZC(,ۖMNd u,8m)/ؾaԩ1堨Ч$GRxF봫'q"D:fKx [9IndSjnO1lAjN =O< P)n"?펻kuj=ڃ_[u S$=eqJV-'mЦdVT8>в%?GS4h&f]< \fp!EGEÒo)%&FRf vwjU.IO򞠤(㒄V9m8݋kH;_Cjj)u !@" nկtIMUԤat DGK ǸdA\B]3C!0`֛RkhX$5NtgQ˥So޽z@/~o0Tٟ߿}ۋ/?~Jc?_K7[~|ܾ,>Wo޿{?_~7| Wo߽駟_>߿}?}tuʿ߼1qx&j&50sQ*BFN!q":K-Q|ɸDvAPRn(hF0F(3Ɛ/BXSpFQMB&+ւ< p!+ 7{q"4Zj0eKizѓ,}BZlQ=RsNL c/1@TD^B#Px18g#k&3-vatZRElH0y77]iuo°DJ1ڗJ< g3̉;:S!o0^7HRdbwQМ@ cGycf4g #/@9К< rM-fV }?GG:ÐV[55O=܍*(jRi d˺#W5RJqzG>z %uEK"ɒL]RÝqcJ;v59LJ6FdAsoFBQP!Hٍ#cOL٩UEICߕ!5^߳fSbEnI[agcio 0DY<-;iTwzBl"!$9sDԅZF-y=0LiPYNZ:*Jm:T8Ʊ52͒YMUwXfU]%hSH47<9BF.}PD(H[P13ASfb= qQMUd4RԷ@PfȐg}g"1.uFU$̺ #K˩%|W QiRe#&a=rFA3K(IV`"wF0BLiq1Zu;W#k@jE$ӭjQɿ:[#BǪr9 5_RN)G+A/IG|. k6W1 @BbO2*׸̻H(/1o:YQWo$ː":K(?#Mct$*/] dOllN6 R|v0FLP}8|&LFG0%fZkAf.5DI"=-;ϦGDx:v(/}$*܊SwVfΈ;6rةzvV-7qwEs)-7 n{ۄ!yH))-C"l%b+"i;XaI[o:&$-ыt]7u j:(Vz<.2ْw׺܎)hFPDE_?Y1Fi}ֵzr6L_QOaSw\NI4sIS#3Lc}EZ-wE oZİi=_wR`4ɦ*| $@F]6P4RR ?k+tDDgļoֱS)uUCbGN*ƝIEDgDZ9XC[Ƃ6QghLȄtyQ+k ۞7[hG^t`}AG ]}΃JN߉BDn=N w_'Uep[wȿ>BĞis 7; /ݹ!9U:\m3OXdj;kynB1+g>/^ċ,=zhnGYr12OQ5 AT#sWZ~([aob2[Ǹ=T3]Y_D2ރV=@}󛣩9a!]%VA}ަEQ]QќLSڶvEh\+y|"t|T[0LuKߋP'DP5Ne 8 #]) idhZJ<ԏZ l/BV'1K2YTNmRT%Li}ڹgiN;U׹F\ELHNxKn5-őX`Oyo[@ # 32o;@Wӣg dHti7ۯ4dv^oFl VYM:0NHhۦ`at@lu8tmf8l-6j,4:.>8cEW>3\9l%bCqt{ /1| Ee/pA׫[e< ӒQٲSQ?hu +o2-އ0@+‹w9avrIwp~E0SƋMU,pWh'EHL_VJPK;/*i$M@mQFz@$kRx kT6q<*SD87nM*N 5;+˻D za$ ٶiW z3C7YD~52$QA\c__`l3H܊p*LJ1PǖslXj=c2 :\A""BQd!,lǭ.(D}z-A2s6v2GduͺY,Lٗ[%خb8*fl,ʸuPbh3". =[^er0NC<*SQ6NqNrFv:g9@٣JP,Yh\9S~2h̻&db2i*oKb˱g"{p|^犝]B=G~]$JuI5"BJ$բTJ-<0Sj܍%ѣ##z8Vէl>"w:UMZT=^D ʒ4mvpN)10 )E6b= K>ըխ$|%Ķ̷\KgU3EKg:y"YTagTѩD~˿JώOԧHat (1A?fnY< 0?5*nRˆt D8T"W3]'JMS;Gy$XMv5Vz- q >+81LFD['{0#1&qEN=Xmg 7EQ?a s-tMJ z!mWkSLsT *q|PHI}$ KT$‡ L@TE t1.7Cǿ/~~ӟG'y$"Nt?'t%TW"tV4a-v7c$pGM[Q~muK-Ө] Ca8 _TH1-sTP1 dOF%|}x=Bfl`=t.UZv.xā "c<]OU yexYl,fD=.m;Dw׽n4H:Rr؎üzzZ8C0#ͻn橧:<Pc%"ekG'2dHR*;{>VQǐ#ȍ*ڠپ4K.XT2βIl38MF^R@ڜ3jB8&t:cK*Yg{{ILI?9t[g69G3^&9v]GJ %nX#5+W p`p` (޽DEBS gFf.)tO:oJuqJmFPa^'$),mw=dK)n[= \S_jkҷ?Wj*Zl-HgmH6᭵ g1#kM#޼ƎbG;ޓM8ell7oH.5FY]Bѫrw8E{, "PaOҠ }f$w?|?//AS->m۷_͏?oo/?sIBjcVDŽZiöHUEԲ-U bAn$#E ;zG-mw(ÉN)w՛nmc7/}bWCd]#UՒ$Π@E@;ΌX"fcd2Z[O:0 #]GެCʵe$Sc%[ [~<ڄ FJ;#z1sӖ"`Ԁ㋤o|Akb<6ZREY_A1@p ym,W3.n/|]fvq36;uY1ݾRٚTl4wT g7 v;stC|2`'~QFAL NY6"yTB(s P}N&-BdGdZOGoYo*I2;?.BK&K;[381 iOH}@ Kcv{ oINjѲU9xgN>ݣPRߩE5J.\WOh4jh td %y~G q5bXD: 9f"мNT+L\HC2]RO.Qx0,f(u拤ݳCfl\LJ9mnu6ZkeAaIS*9@ ]y7NB.t1ot{fOFG~IߠKnyfxF# #g$SkTueDz+g>%{0 rT˅玑"SƓfm~j٪j[wmS!N7d>D؂Ìbcd¨'zqݱXen\VA<-˔FDefA-$*Z iO ɠ|κ՟I4Kjfi4 F'Wi-H~^kd9KQl:xqIșI{61~Kj^c܏wh(,”{7.~B P E)S.d9A^NJYQb d*62 ~!:K|pZZ'mޘ[hbo)J]d1IshKamN=Oպ!nɂ;=.ꮬfD'd\Q\ԵP &u_c7ɕuB~g!7նKCbi,/Xr88e`Hm"43R#-Z Dj<Ղw_6b KSS}t$``1 g;YW>.UHD[f9_J;?ediXQ+7LVriWC I=fpRXvlwI<rLauZqB8GW%( g0 @괹Bqt3{U%H(*Z~Yf5a1_ځIc$퐷@}s(+="4_ӅƋ5ktd{A-Pd=@#SxBB l40Lx ΨB.CgVqK"5o !GN#rD5'bEZ9^c",m8DLؼzLƠ"t !nQ5cv6BQ*GFmD F²a"s%}HS@ ₐnu2>s91tjo{Ҋ@Uy6QE/ц/~ŇC5X/U::)-cO*-*ڢ28YY3pä:?QVY}tY1.1}f^GiW,RC E;>sCAp :1\Y*ĄRmsUOz(# gh (JKYן矾۟}Ǧo_~|ן?~/~~a1s}?i_5 cDƏ^:(:݄#0G3]:|/dS+T%V@$knjlj1XhI i#kG,idUD-'XF[Ӝ,$<m8.5 NVH82zbi[6I U9\wc#e[;ЧݨnQd5T ߋʢ؋ܦP5tWL5-AJ3|djpblE )byk'zEB\AD$Dpu?mɘ>'qCaAo_gU׍^TuG4hf=# #fdA-9Rh!#-mhYpF82I_R9$$]/~P[O˹#ZaDcAvjq.:3m dg=Uซ{@ X] z$,Y!qZ]Նr ~H/G `,M}12C%9?^ZsO;yρ%XA؅i$JByÔ QEf#qIb9s 4f=Ho>ąA4p[p+&<7]AYJesP8E ϩHr9 h|3M|3orIk %ojonqt`إ7=p].6}< u'ԁ I|VFv| okbi Ft+Jgi&g@-(;U_dTUqnYH!BT9F74O+}^/Tq?UNxZJ}IX> V"mG/(*#d[FP:kyGX/z$_~I vs;eA'95ϸ.VPOF; Rg]vUMa֐bR]m +]t>7"$O328c c!_ V4+$v$ #5uKf7]Ї!׈&:gQ*MW%As%i|LJe>IPFz+'nܢuRv*Gmo~9$$<lP39QtwWI_qtx,2" ST\g?!sV Mi@G=AUÆx"Y|s/Q7z3 6;;' gg:Cȩh`u4KxMdΚe0x34s '-;ZV ZA'oῷRZ$,.,*MYɏK&>stream Hێ^Gw7H3\B@AAjd Ȍ|#C`gwuVZf~6k;i+uJO7C euT[j3j\ ca&Εy?Zk\1F|2dmezT'Ȭgˎٮmh/}/Qp<Zz)~n\1S@ZÑܬK g2\+:K.|qXƭZO]Z!+7DDhK 7JKT콒ވq_W`۹ϕ/K%]Oҳ]=GН+N@В735%O[ZA*IPCei4 ŴO}RJ[i1 T&[ =5;. ! ÑӸZF7JwI8j&lqWV\HiBWG,#/(%߲h(}F#g!lC72.K+=K^]`}fk톸ACߝ[sĵIU*_,A4gWK!滃R|,9i8>~eNa62gP#:f@ {k~UM4^]4t'ղn"!f;G3,#WыuuyK$swcFdsPn6)| +,s"ЎT,$tLٶdzk3(!*$>)므Bt;Ԑh!\+s*L7*Lysa )#mZ+2 3yJ<3]eC25t2a+}vKO;Dg:ֆIY a 4G֤EPKtTN!r i\*He"YN"ke-$AlZP#-mgA,P>|:X5.D>BR$Q79["v&F<|QYMӪ\@\RSAe}#@7Qp9\.;D`R?# 5 *GlM_o:ZBύϱރcjPC|s~(bXۆ/׆O*3gsṢLE_U&+tL;$Jv;''mYC 5(Iʥj^nѴT)kgT p.D5d,E+gw%伺{RNREIZ<[5&{■tUIHΈ/ѳJxHFEs$6E >WkDŅʐHX-ܟuq|J̱ҰZnE5NUWLSb)M`?c`ݤ5(z)4D!.,S3N#z"IN 4ހ2ZBjKegYҲzjHvkX~'J$Zy| G|EI`Wb+8Dk؋a1AM"0N5Y=o8փB~k E}"4.ZCJ"qRݾi-û}Ğe-ΗGP>HȐ7whh\}GD{40Ӯ;y'%.9Ijϥõ> x+l󲲆K%"Ama>9K.FSrVj S fc !1-ܰgZFl>V gmhpFjϲ2ރB:nU/?퐒,jd0-8aPLXZ𨭝N4PqEI roy1L%i<hK{skPqHW{$cj15>^-A(a0e=>Y^:ﶗ]5и >a74rT b8H;HDtf%CFDY45Oh.MȬQ|l{@h~=_첽$T4q״E( @=\[ C>UsLȔovVBWVg dTmo)7ۯ(õഹ7 6zPyi&O0Kۙ.dDLb8 /%/R,[|' X&UshgkOfJUh:aC Ȟg>e/6Q9bN< jj/ h=d%(l~D2Xg/d-DJ>*w9s1'v9;8N5"MotP/ZiD*oSY-&AE+v4>kNr(fSTGpĨ @s:Q5 ǥP7F1Cs k2kpʏ[*٨V!Pj lΘ\H <0YÃhq<:}DoZ7Y5c6v^/'&~SCٍss9w]ɹVF<^2ʻԢQ]$M@%ie8FϬ7y!\ ?nE ?Bu~K!O#MB$?"s}Jv+Y9Np}G'%Ō>g|_ǖ p0C8ċ$;>R)vTU( "Oq:M;\fNF!@R%?f°Blz|sn_R6a{"'Z-\j/xi|]"a(35CZ"Sﻎ6CU-hj*E}Xۉ 'RK"Ϻ">4D86^RKs^g+Ou lhQu{E zϛ(ݤ@CmR4P*f^9ŲR#()]:iD{@l|ˮ"Kl3f$-i4-pr{<6'NvřOƋ4DN#OSJI3zLzп`|z1>HGF*zCˆtTSZDv|PIgKF܋< SEX&aK+6D;hb }:3%B x< 1 cOcJaŒ@-H\wK!vX EIẕ ~!q[BEMEb|רi9[fv//*RxƋYI*WY{T^Pdâ&DPZctO׏##<HOȓпPdY22dTѲ;!Tڄ~tx40l,ԧCINPdf8 _9|"9U i^cɂ''PTŧǬ.O| ldJ٣))f.*[v"& hOi>JɢS}n䩊_:~g+xgЭJf/[yK=0wovi@u P@J'RJEDz/0 멻*ʡڞd֙E!#|NZQQq@In \ڊa)K1Z7gTپDӬȈb AҫKc"$"pC)4w}xF$6gD&eMHDŽN5'ƒ-%o`Tm$\;oP0>N_Xz9SûF"/bj-`IyC*zoQ:Sq$éqfˍ!kk}0/3R^w$Z,h'##!|Qb?1M#B<I{4!!)UKm:0'5 ϛ!XnTBuRC(5N{NSbE=]#(Ҡ G緟_zVAt+mPC `a {D} @wkΌï?>TϭVlϿ}/o/IfU[$zZmq?ERIԚ]U75-X )˺pA,1)'H?k$쀊mQ~6 H8M1|wNtJ#vmV4omc+kBt]^+"TKRDkP*zj"sgFM,zst31FZ #"[-RBG@]SzrV7jܛQ{?&Sb7c`le=ӑ̹R@4&<Q Gb]暴>Ys ! uF[b.ܥݥY}eD1WҬDNe%Pѓ :2?M/m>K@'jG4b)Iv;u-) NmĿK1OfQˍl#"-ѥmt8M~7w7'8Ɏ8SqHS$" sD h'^Duҫ mng_m uCDϞvdgC)9-wALqOl06č"FN rcDzmɗoWr}ۀXKNżl~u!Aiϒt&O&,$w6"zQ7D2koϲAkb<j7TiA3RW9Q‡XF$ZLW3.oO1LbƵetVI[M漂4o3 W%aPᠦηzJ$uuQAlu c2 Q8tZyQ]Y!?FN!fۗ0K=oknZZЈ+<&32aM̘abAZ/5l2d6Ojj ձKռ=sǛ̓MRH|ӫ 7dF딅3YxB9r6T ҄?N6)>#_Jtf@e5bhͤR kh蔺SorŊw*ZcU׾lvQwe;Un}serME]H\L4u_1tpu*]i3YA#jw;ZFhS g,@\Pm.^;(BY|*HXk:!XpGNAuJ$O{<1T攺 瓫 esmP7yh@^ͳB937"V͹J5rBl .#ѽ*l䠲/bag8<(R,Lj=CW5bK|W^Ѐq''2u! >v;I"Ue/{9ꍽuls=UivJ{e9o(ufu=* ]&ruYu1>C*~JwP[A{glBaE`3˲}wttĝc%bˑR/*K:zp9Lw=I2-ժ:; p"L؁Ş;w¨ Rw ܟqܙF\$)hv_愼}G)w˘fg.JytM1/_]LpnU֠X7iH'`Y.{wKj-ˌ5TBB^Wܢ+7FdY02M}-0EՄzk:|U/MAa-Niչ <;.EIƹ4E맴B'-4/'HeYB 43R#-Z S,ʵ7f)";VS: M>nN#W\佰8 >#4H(\a-L*u⣀r9Ea^ ?0'oPܗ)Y4NgTmyP_`>.4)d|wmsdvl=<# rw(#`=*ݚm$qDe 4 GN 7v#Xվ\ٲhdGQхvW!l=(^.-W+=Ԑ`/0@2!A gf2VWSg벪XDvѵgB۠mB&֪6ՇhC,LWZ>St&} ZEx('0 q<º'<ٟyٷ }xR%3Z?y8m3 aGWwX9z$m~v7>QT:"&l&@Qʰ!Qn~yl Ʌ~#TxZwyYϓ_01Q@ E>}8A+Fb}"2p( T vmtIMX&~[|8<>Uz}vAcLi}u,du>)$60#DԻܺ%Y(ƙ5n1}vN T49V{0z2ZpCEp *3(Za96#u+}u̲z*꓅M3XRpxR49?շ|J)~}/>曟f~FWxjw4f^e.JNVKћOfPX5my^3/c<%=T#c@s`Xdih!]`7o$NΖL@13 N8R2 (r]&ÓeTk9W`41YDy܍2W@YfI턣㧨1Uu斉7M6bG_)D|wu_+,ֲȨbr&FQP *LvMU֒Rje>tˠ~e N[wP! gm@i;x"Ywa6N*ਫwы}4GFpf: vsӁ@$9_;@]{]@g q蓓ܲd<휖Qd"$*4>jj&C$g^6A]=7p!PE9qw:=1С<.m}>'e76t*!w,FTsh%v݇HXD)Q{͖sRoJAuZ/(2Qr+A>ۺF')kfyB;~$R:gxI᫆7])肝^Wi"(U1%C;fgaཱི?(SѽlxNe|l9,m x8L'Mt&ȭ&0ȴ/Hgڄ {vA}/zMnEN9+]Π;k-u[}4fvr}A%\_a@䌳`ZFW"`#lg\7JH!AW<$.P 1UMI pz)dD39"bPRʖ ? ̖8sŰXR>"=L25Fl'7}킪{1~w@gc9wAD{!S N#~.~cQW MyAyl:'Qpbk"*x9̹Pۺ2#rp}klBR' =vt8 eCޠAbAT]u].*:HV.n988.r:u^"VOO`ݹı5MBǛEXwc͵j (&H\;is *]KH/I|!Qz6*bT/؞"SPm.A<Сlz!^Fy}K/_k$ep(>׳N "Us.;XFɓj21&b&v]^Y_(3Wۇ[?;[P $5"XYB{ͱb@ ΚP%ޝ j,u>Ssݰ8P+M)=.-SZ)/ZfxQZCK2tv>8 .aqqL|㑞dT]unYHo!BĉٹFʌ yJ V^aOKL~X 撬 rX ^-#ָt].QA;j<$7]qoN_1)ɷaΐ@'Z "~=ͻV8B~Eٔa]QCy5."̆+Nk=gĈNaQ!%V 2icW)jquI<|iLӳLs(&qKfJ N]CF1Fp X "*uٙPOQA昁(=;+@2ɱj (NQ Q=)fyD?)IW!QxOokA5\h2zuTAUKA҇'r"@"•eȌ|U !3SݽCT'H՜0c}l+<\ofe; j#rmشݡ̌  /#א\P8hі*PZ1YR9Ϩ*v19z:O21th:=ý8!G2!G8BZC/hMfN$flP~@Ρ@F[;*H:Y۵Zpt* Ei$l©޽LjU*`!+@}k}w0;p7e~_`C(s' Xv&T_tjd]#}8-"xSp0MOѪWUcJhTkzȴA:xYt-e"(U>|lJQ>^tq!tfB#ISxݑxfkhac؜hGIVV~ny JI kBwo+ۙkO(e.&&%P}HB_~BjZp;ԌG?Q_j1k{ 6-z:ל&1_|j7#zƮS/9!1svn]Ĕ;JeJB^\!Nk`<$ŃxGWD! DMݦUr۵ _Yx?W.Q9#5}t`Ƶ~Uh12ҎXҖ=SW;ATSk34g/l\*PJҲtLe5Xh9,kIӦ lԦLYcdeW݊ @k$l$gj+*%;Gk3(^V,wd#R<^kdO:4h[JmxOb;Ow׺գ'uiWJ>v! TBDk +v쎚Y*lŪ-Wܕ[="r68wTZt]-H4&rS$.ۂ#b:5nVuP8Beq6wfϾ=H%7,Q:Wr) =1]J.Q}&y! iH8Q*(?(dʅvnWv9"ɥlWeT=ono}SD [}@(X@-05epGP8)lk:zl*Sw#4c2٦4ᙩ1w!4}uBECAFCVہ'%5)H:t)er8<-p?~~oӹ?}۳/|w>w&=LMzL@c"D-){pʑ0|I_$lؿ/X׋dtS9qn2:- VᗩL5V]Z}#(3h%dus1Wݗhk35ṞnXj'+\-Ltk^dNZ-K bqY) {fj`WiƈhܵbWk)nkФAEEy ξ(G˩9lXha鯜!*h б3挍AҜ EJ%s*NmYq"5N W*SsLwY"wo-bcH&@.۪8Z]!UEA|e€95MJy~hJTlk;ֺ_2)%s8AfQITȂuFYslpIR걋0r>-.4kܖF<%ΨsnMQ\|g~-<;MF6.#]©Jui2b%v: $M/[E&%kZ(R$֡@TBtq4_5Mju;+/ ijaÎ Oiԃ wFD.Ѕ _#3/hz mT[,,j`wi?!\tiAes,ɢ`sΌZ ZmtTh v.8jcY}ݹn=:UҴРN.n+ wH(a0xȿz֖yC16'lS`%@|{4!u Vxc[Cdv77R=9' lVƦJ"M/"ebq!Ъ>,ZXzuG6eJ iK|R7QQR}Pn#ZQ)2cWkMq2Y6B@,eoTXq*m7`˞w@E>_e9-3uB\9;8T"a~(4NbDsnF̶ oߣUkVyr2S8h.2*{aT;Bu'oTUGVP-|M4爃fgXg/4zA2c^1x*1>00#T~ꖵw釃|2 H@l$2uhvgn0T)&L6 183sU#6=d>%TQ-RE w7ռa}?lӧ7dM%T Kaַ Z0PLL@6# 9P 4ؼs[@n7E;\#t3mt;,hnx!b6O[UPfë5.) 밁=7UQXtaOsQWBVJ,kJæg 77s6-PM?T)C_U0FU3\̲4Au6]x"9r[[f[W Z:JvU$UUd!lXE௑V\lH.o%=zsURy0+ꖼ?GI,s!D5En9Y@u/* 24|VZTFv{&C*ԇ:Z,)DIƧ qͿ8:hz2G~C|?(>`_=:'W4Ry0f-3nHQJRÅ釄[7qF|Ii;J>O2&]('}*ڠֶu%A;mEds93,FO$an@c2 h葍FWȫaTOJ FF=9! ȬF֊YVi"ˆArӳSFnpF޵*UH @:\ tLOr cyX_eWA'Ǝ/ 5P^ST>8vitbꭊ%H<+KiBCVTs;iT 'G0K̩|bjcCK4 "ܠbLiHiơؤ:X({riK?6¯`ЅB:5}I`*]9,IA&D,[ ʦznL( .9~E%0Y:T Ff9 -F-/TT&WyE<@W۰WiPm_a.DTbir8cqVG4"A W.[7_*Mr2%سә_:ú(L5RT.Xfo\"׿=n~*VAC8!S *=d"*c0O]JModYg(/R1muj$`|5*ZIcv!/?^9KJ#f7"Nҁ~hB%h%aȰkR!b#g5H' :Iv/ZMi5#Zp=j8 t^\DRG!m0з3){ .޲2zY{6?]`j=4 z]"gGRKҳͭd2RWD_%sgQQTeQ7y%N0ԸTaG0][i@˘Xä WX(Gdž~vKr}ԡ;FX}DnC=M-F;UϲCXoHS/zȼMi.Qz^8bkǁ"V,=*@l=slxSPil<D2f&H_.6ǥ +K"'P953`/K(O+f;˾:D7Utw'ɑye< ǹ[W[8|DT]?35ifwSAu47C]FT$EU~8B+FڅNZ#ӷzdՃb=x52HxNj 8(fQ2\FI:6S U%C"*Z:lxh` _h|o/{YW҃K-|}}w~G?nh)skf3ѩOꆒ[S#﫪\6`^fF$h#g9ћa\^Ffm`cH22O DKB&Iڞ`W?AH2p^k6Jɱe9DU 8:EP˴m">K39 D"$vUàc$YLod0+?]̣&[_ M˥'s(F ze*]:ƦN?q.) 6~44' 6~&i%cJ ad}а$cgpHi ~S!.X# _21[fIg7) E'1:ovY%MܝLH5Ki p-ŗHB[:{Yq˒_^ 28SeKGL3v I֓Q^#Y<- e-#:MU5߾KpZ"XNO'JpG^CFk`Szx-s!p=ږoY4?뱙΢7Wi4Hk(能<)?}&^r0պ +쌀FFPwM)]SQe{O O~Hwn:9pȧ>Rkn\},X}dt6_q^iXtBdUn)FuX ~~6d,rh\| yPF؏G?MFO_oR0grTDm.}(,Њ@OߙfLP!'f Zmrl͓݄z5i; NsjaÇK}43o+L!AVvΝgܜ+N4Mr{R.`e79#xa}Tw5Ӌy2]25Յu2`]ٺ: 0pš }#MjcTDi! wպ'jsQ'g=,f~jhCv?zi;QmER.U(Ǝv``t4Y]&{%}qvM~!@OEϙ*p1zB|i–2I.u:H"N)uZ.о1`si$hC;~RrUd h:Bʏ?X/oFC3=Ěqp_]=L !{S#9R+Eg4M=<ڔF iOw6,"`צ|OX²;խMº1K4duE "jd,`ueۀuikPL;<(CCRN*tZ5ƺj_:D1ŀܙJ8W]YPumZO}mIpwe/21w4:l}?;!g4H;VftH i\ZZJ7xS:UZ0(X>OzP_ڸI23`mk|Q1GKE=|Jomkiz r3+( ^ڃ=TaM4uV zqo"HMZee(d,ҟ*]2o`"g|nBkkV/EqI,k]>`$RY8m[Ų?8! 2{ѨL*fQf9#kUD0)_R ;‹9vd|v|JD3|q?YX¿?Ȁ%v5KNQ› ƒ1gP'>e% ;";r##`'-&PTD";PIr)!8A GU-uv]hȌ#WdD t)++hYCleXH.B-I+#8q U ^O |zՂ#%玺0LI/݁(JPz$2gR݋.1O8(>2K^8ub'a8ӧW:aGAP #GiniA`{%dQ{gfGsqL@Vϓ XVX9ͦZրjF YFM ꢐq6Xza]~Rc)*?P$tGj8_蟉ked n #` -C&j"0MIuB&4ZQo'x,OAnP6z^ns zN!4Wj(ҵk_.8a]0@g4Z@* >`K$ >ಬ5eHa#wRE9 J/4Sr_DQ,D>gЉ :@ݾxuWNY|[2f)xIC1j=(Iʘ4k3k<}ZB@Vvu F\H'5p8~DMmA{O)z !itW2f#'K^@mL 媸aW2*BWIГ7>_4rxNV}.V)xPZ%1?|>?/$>~x_|woo_>/oG_y;ODւdht E: ˴ x귮[^mIב ./nFYQo R׃A@l$b͘F,>Nk;k~\ }e*eHgs;C]<,QH96|PaKBj>h`+3%ӋLK_ ?Ԋ z%Q!ei,bH421RCȳsQ8w9R5W#m;*S\]'=_U*41̋ ވgNeU\ G:¼RAF#_FA }h/J<3mqqpN%v", @(Y ycǡ .:)*r,(z'*e%N@xA^F죪1dEԅ(Ch9;(;c= 7:q syMPts]7 CN(N( vR׹ou< cEv h#b>_1M"mݍ`8SʱaY?*>*M)r 3n#:g.Zh-aWMU581Lp Io 꽱b`Hbc's$H T=6*Qa9tQM9D۠`0>ON1<=F(_]WkP=:iHM휖v!*"(>nr G}F^aw_낔o&*;Eܿ kYDžXӌ`h< 7`6FEI_HJǜ#.$D]N+b6U`ZATz8;PMb: D2?!\;@mK]69Ew8r"C7Rvͧzl:8hbDg8$QwDTM#1/~1;0 dKs]AQ77enATq in>Ԩdͨ] _R@uFF!LRh(p#?J [O3xewN +&K/@l\\&dNnr3@F{x 聞e5o\sGv6M["mx=,zLCMD?$7w%VC|RG =+NY7je78RdcߘYE#"(ʛilEpR.6e*,+%QwFfc -Tr7($@9@ bհ\\gV_.* &{=;",ײ`zmj\Ba3Y@XR6H+6go ˊκA}A(rѰ{QҚj~:^\y *HBɭuŇPfi%zA|'Of,ʱu|i|jz;yV5A  G, 0)^Q~/N"df8癹xCK qP&%PEXu7HX37T~ݠHa0zRDqik(hS+@ 5 kĿtv]aj81oayGK B }\pZ'Oܘ 0עa5. *Hy$gۉLYE4oaE VJ{$.F^G} N95Js']vg#Sn*n|)iT4ڱ\YL?=<1Y%/arԎxE?XǙ@ƅұ6.*؊(kϱlᚓ#IJ D(M~:|Oj!:5O/_ GdL밞.vv-O7xagu.XFѸzJܱh/M}"cb}MΊS[`3pt7웖A1CmkA5G>!0QBLqEM)T'$:p/im@Ꚇx&Z'fRqAz=/Xё'S&@i(SNiXQPGgwpbB@3/f_?~ ;*hjy:L;|Ў&ٜ*NߤF#Q']^XNԌIG1w@Xxv/HBpL61iq' x/T|hzxʻ:$L17a=[N99WH1D\&s 0#Pgbx]E>z<Mgu\qCjۍ*;_8/`}$OƐIA$h 8ݖiva"0W]Uc0OA>!la(H (bYyfuBa(F=Gxz؀G) R-gB`*:aII4F%(Ovb4icn72"9>ljZ)XHxQFE^O |BmF`s#Y: ܟȋ\ӱQ:C*F0 )ːFik<<>"H$shx8G Dfƕ tAz1@f%xO! 1P)ImߓQ@g ]e@!#Ę ɔvHMexe$i>:Ƹ" JS>ru)}j0~vօbv`Dz-ҐP|e69uJa ps$ G#]+c-*U(l |~l]Eꍌa`79aY$&`H=!L䦎B,+. TnJ%4P+[ !ʚ4:'?)UxžhVq4*g)M3 ?~:!PeSCQh55/A͚ =#=X爴YK#lBz:7喅bv"^DmЖ̡<%pqI仗 G<ƭ;!`Ӏ/=9N8 cF}2!#"aoݸSAh}FE-c" aY):v A0fu^vd HԼf}~eGO:Tx<~? sb}dxwexxxfixtv]/_~^Yݬη%.~>Z/67_W?nnvߴs(oV; HvO/Wۏ"'_G]ju>}~j= Z}^y[%aݯOyo6x X3xG=0 `p u, n v\@lp"p^=pE,5 ,WhQѰ̐EȒW0U~sRea[uя/|qAmٍ5)RE}$4h1J)h=Vry *輔(Gʅ"GI;7V;g] "r5JEJDR+^b1S98̵xkW)gi .`Yu$X5'CS>N\{ B (5[9B4 th# miZ#|YJӎ]fLzfDDvxOɖ 3蚄+@K0 4]GF'%bIŊn<@V/5,8`?| YS0"!'([9քMzF]g zuq\2!&x.q;JdҚ,=wYɺbkl-Ү;=#E:ꤔ&sL:d ^T@ gȫ R#Xp{!WvmpEw4Fz,Tzi T:Gq^`L `H b(lѩcр+*e4/!^]WW!3*ܚ>".NЙ pYDogs3Ʒ(7f5 ,vv_kZ&æƦ.{Ȯ]rxm!~D9CLV:Uz6ƨiL!9c,5s:l48;\4!RaߛLX**U6S$@N=- z4١ER֨ʹ\\"Cg gdq9̘1ť`Ye0PsjE]DG-8VSOυ*8a\ &`c[=9'ݻ`" a }mVZ[ h[!Xa CU֐BYDLރ4OaGB]"H$#kaWŏb^S":Bnb&h/}֋ݷU/){loM7QKjojF6 &$^#+?7a`&ajs!amN/&쀧 V(]MZd'U.C)A_ ͛M`AbKw^Rbt2Qkil`V6 endstream endobj 35 0 obj <>stream HW;r,;\C$>a.nx2(&P:N($ަ?>?v!j>P}- /?-;LR0K]6 T.pn.0 {翭ylH=tЦ[.{O(Q&'*on`p]CE #{i-+~L7 ӹOmҽ86e+j T}BK#e_olQ83lHr2{PP#Q Nǝ;+|Ice>^+vqCJ9`HWqq䍫+2o˗%m|)5Ra?pU ݢH/Ϳ[Խ V_32ׂ_ rlam٘2*Y27R*B> 1ٸ3.p|R0-gI+(AEoF攘͎l@r#: l:B+xNVtR"6x['xa4\$at$mB0kPpZ>clHk>^!uQWdKwd8֡UX+iR0ӂ6jPشbq^cw5Y-aұo>OI{~[-$t@SIF?QL |Y,ۺG <ת9(H* b`t*3~WaJ]z[ha}{Υ`BixVx~=`[lwU$/}td嶒KO0+vkJZƒ+MSсhVix7s:fTZawC:ާ9xG8RG%o[XLT5VWq*zkU`|Vdi#Y^z1&$/QFۻasr7#'ztMƌG1\|`=GPq˴cP|nU2,K"0r }&H}T8Qq >uu^Z/6ű;,'`{CxK\c~:bDαFE,6.^hJ'A!:Sqx\P,n޵M}3WΑ)mO,&X5 V:8c2Z1@B<(g`N$HYXh^Tp%=xi)+ qA*ӻyUʎ꧃ ~a}`qf5 >%warmp ]z-3[a;^+o$occ$% y*ֵ3a*;Bz/3V֛V B£33X!qX̘jWRX?ߨ{#Xo ' c3!pJjCMaH_ Q\[W)t+4`R"~ `Rlc`X R1+\3oԌKD+I vJ^J Zf[;em5]߫>*Ni\_cM?e,Etם5( m@Fr(ڏM҈7B} ӏν^\_Z;Wͳ\k _Ԩ"%2IU.epFi=my\y\\0Y 6|}nhK;\ɢrjuƵ 8uPE{ulV#$x\93pMx`/Щ>~ôtn&>]AcmYˑ)LNЇշ42D~+tݪ}dN#%H_]g6 !0׮e 1xM's6!tZ5{Q/RLa8xʷɍu2+ 5*"O#25|C^F1K٩YIzmJ~|%s?A)gӊsZI\;|UJV rG8I V8P\LF 8.q/3(\_Œl%Scy+aI1Gb nk9 }XaG1١Q`PKVU\5@^قߒ1r auKXdA[QiqGkK8(f O{'|ֿ;rHWQ&W=-iYCڗ[cֳósW4 J1U3?)j{W{ +9Zz@c4iVs8ϥC7qkM1]f, xDk':{)ӀN:o? J(H{T5RWkR;#Vԗ-aըS}M쵾$>vI79s֨$ń-. dEAd<wplOS[ɊQ*{0F8 ٥rтkM..'ka6\l%'AOު-l?~zX`d*'x'̕SQsn}?m1)Jĵ&;b]5O5dݎ|Lpu]HA})X=-K/mم_z ]%Qugb!hfڔ[^V. IkY_$i1u`q } 2mu:\I >G$fa>F[?JFSH5B^sX Is,QqLFﵞ@N5Fm6y!_C N#V9 RO SH:(1!'x8K^-+A[0s,b]Ԍ+$RGu2`K96 7I2ۭ:?X~._ҋ}Y'h9SY˸wTgfCRV+|/SkcL9 t]unU.Ծ==oX+eZfp]kK2Q:p Yxx3Pb`*K f bb6ʖko/^ٸR'ؔAf=/Vs:^ -^Z:nK3fr*Yn*b`<`/w2;#>S-)~&)|Dx~U]i 9#Ցz4%$u IN5ȩH54LB9(Fs CG|T4 Z!Wtr 9КRȭq!fkvJG𸦕EC #{wt71H•s+5Va;x/!/ν=g5` k*m@YO?a1JȬ$i\FdV 9\:jI9{'ֵkUU.gwˮt΂q[@! Yt~epܞkz1tHldL߲uFP6k;HkgO}DE8)7٫k[_荣VK_]\RHIB`;OM'nȦ8<\ZW[=|#f¬|f8{@ f3~} }VOi߁sM*pvAc8O.pp~{H`!(K}fREq,"@Sc`awzA)k}tIkE7%P`B% Vf`y' {:"Elmu\{kt5wߡʦN~Kc%wytkxs3 P׎'6G]jbp1,0(i}g 2bWu )w%NH+6}Q lCYQU W2=6 c^kF,xڎ p&1X2i(P@·$Ѐڦׅn h3U뢷 ׸p[v5P֭ R0(= ny/ZTyMI{JZֱ,/U F  `7ɭRjZCǝ#]^37_dA;K NW+yˡ,ZQn'1k9cAʫÆhZ Mň5AdM.35 ltb4w>U8lJ"h^C5wCizAwD0?<84r Nl-^uf@j՞/Wˬ^R:,g °-]ŵ>+]40 0Du1h+S8G>K+6"XY k\մμWiW/ZNf%^-`η|K{5[y xyZ;h?sԼzl3b@ȵ8ie ~j7%p{gU =. rtʰ/p@ Wi2AX{aea pRr}&Y x~ q}*E {6l錀ɒIpĜnŅ'Zi;z iq7 ʲZvF{|~Mzu7KX&8  0мLLpqj^Z Ҙ0O%IW ];\[m Ae&b*A`dP˹1^w?I’x,‡w2OA*!Rxm_xkg$c(񗰱7 nGmƲ ^#TB*d@? Ɉ~O3qs >Fr">^ cKAymcFM9##Ou]Z1/G m|.p/ko|AViucZL#]Z !?6S< O|k^ a΢o4>iR3+/@"(>9XPbج9X^8 ]eLY$ `MQʷ +/&Bd*dꁚ #ƨ=9ゅ`ɳX1TaudNY}pb*l K ][%M4_}(=ˑ{v~_L"4@ug}>jhBe!P>6r!;9IQ #*p:k}`Pq븡OwE=r6ifYuQJZC+<}HWZ@S$rHyxCb[^R%FnSj&xk= 09" Z㐁a08cnB'hhJkHi|vꀵ{|C}C'ew ;3.&W)Yo^i**-Z;T;3,|ԨȠ߆ț =M]xV;y,GBM3@4smVڋ81&L1Y'&H{mYM@]/_hliƪQ~mțXRYkmْL%QV"jɋ"3tPW]-Ӡd0Z*5K 5HrcU 06SL}tŋNe~%p6>5o:)bl%K騬;i}yc3WHKo#,nSgmLwFt<9" S9WEwwO;'ߕan 2m~n蚒$ćR`#2@`0}\Rp^N4 +E:v>t~]I޴F.tjFQH J▖AKԙAW~W耆 :P}D"W7*-RQ,@My}BV,*S30ꌽEFWz\*2*2\\t4UU!-hbY~mh+PwП4 iӞPGz[mE:@ $3W (:xL9s6|R!X+S1%v{cvH,+}pN-M&.=+J!H0 dcԳ]A2(YY| qDX`<_@Iy Ơ;j͝my)F-^ZrkP"0:+A%K!#^A,Ns*BdALm\QwHR"n׌,kN-J|RPh8k1m25$LfGRL͐|fej1kXԼ֦N}`z@$L82WeثNCYJk%;"khSrQcKeo2Ͼ=ԁ}_H+ugtst›^(A[yN:!uY}|-rQ`(OM %&$4Q)'mA#麪h R5@ y:4CNZb&g8഍RF+8c۶mG/+eX,6@ayw%yOԜ}-a qW <] i)$v6% &'B:)Ոz>^% n` VuOnb{=L=_?ugIir $ΚJ]- ϼ alĝ w4Q-hꉗb?_} ٲxcgZ"{ .߇& Il E݄ăЭ]ޣew?GK0+ YCkrU4~7PQՙ)@cog(1 jJ,ól pvgu?af.֔pD@[Ӻڻtڹ] {v!ݼمGs`u߇;C$jG_LbvDKjodX5Y =?Lu { P(Z$k9{}PN]XET\[--ZMt;hd+P|0hߴgMW0l6C3g^%eߞ_'>{<ȩŧ8eie" :VM}`ꢲ ?RkP|wwtetQHVxRtCYI $$* !8eT&}j0cG'p ׫׋fzyrp?LE:7Z,afbٓ/ǯz5]߾?v\-Wn?o7Gbyw=vFܾo?{=zZoϾ^\l.} +rO9ftHztbft8o>HnGGr{<__,j3؜.4V(8#TXz/_]NGa5{xXr<o)94:Gc-1wpw<1fYLW_w%>'AOB:]xq3߼3vOC4i͘]/_\lv?NGj>.߼^WÏyzL w~ |6|7bZa(d,Q36!'B/C-yȏ׋x9_q\&?ٯݶq(t1tv'MZmp.Z2YӢGgcFc$'P|7"<=Mؿt4QN'p& 5iEq/1-?؊C1p.-śVڅk=+´Zq$rVYfVАɂa4*F5ˤRQү%7 {z𢅿Ihaoojj_8uY-Q%\4`|YcQhf}KTDJ,U}s(m]'D9SB͍e9~_<455& kvfCޥI1B8yNNg,v;ܴTx؆}31c4ٽX8џ dCu4Dp\+4Zb#>Ti뉮҅|S@$oʡE{<o޵u}>stream Hn:ƟZ$A+;FbS#-EPgۻ}e;ӜjSkmxO3曉\Zc!Ug˿$U-qh˷iv"Z :a_8IY7>L,z)xnߵ=p%A/7 `OZ}YDe5þH"\K*JPQ MpNz*THS+J XD\8Q)7E7o'#.ا[ky>BkNc1Zu&Lr_ @X1$kMu6\BSÝymj`ĭi鷰dbsl1T Li}h;9 u.pSHF%[e7A.ySM ;!#[="4Q }Tz<&}:럗^=&we)qqcQ8pRs.v7@n1 5䲐ͻQgdC7yKGPǦ$.swaq*v5yJUh^ Wv;,*A FW]$U,pV<,U yG!)OZDŚ翻ȞUG⿇o&3P})ƫ,|c^CY^7SsjӖ+٧5ۻNhѩo"nzn(ͽfy?QV3|\qFwq%Ǝp|E%(r pMpܫ&sN)Rna_J#ٯg+Ěz5/i<]s{. }^'G7yGvAܪhs{A'"$m3Wdf #pըYg<c pA&Y@o$pyJje8΂fv ~6΋peKʈEDd@+CxSH 5#K? InGic42I\pj5 pwƓr0E纇q*,dbU6KET4&m'9an>?,JFgY/xwY+>OS&)&k?HbYD-קB.>99y3twY&dI莆NgH]֘qD&j840FiƐ4o&Ő}1JK*u7>_/ߥ褏LVB1A>| \U!CsXw<.tj?KDAjG gCb:LܢF͠ -g~,LЕLd<9 }(m6?=YsR%BI9 g!miL0 +T)9TŘSRfgq6M9ȁ+??ɂ},{#[̦ytBwa"sC ̀U<%U2nXDeJ{.Đvro8:mm )hâdt~地ۡIem^r~U. \j!9,D;I):0@XS T1.`}z*?ŀS-xzAη^'G7yG}i]W [`!ùPӯ@YdG3 5UA9Q|(҄B\/ 1Vu)RcQCq 0Yg4&fHw |[¬\G; 2S`ЕU^B4qm6?:Ys4\u`cEwdb `d4nx`(V)9Tc6ʆC^DZݫ^ս?W߫:Ef'1%^ޫf"a̮S9j-ALU5e-lhLkJ|j;%n^.{d[d!C1Cܢ<,e:5sX:QƮOmZ ejϮ;…c~<[K94Wk^Fη1+*rqw&#d{0ԓJ/Rt!l(.{zTVI fʜ^_`U@?V &e7ܧnIa4m*k| 9!1*)4LIuXgFWLbmv4'xr㈱V$5]^Sٝ`&:0GedzغNqrqkU&kND]2NPfg# ʢjܟ j(oi|LEٓށdFJhLUmzXopc .~<#8Ap f /)N)+2<5tnw5Kp**ɸI(<P|`HJkCFchl=?Ka(: O\g6p@Ūn~SjNU#3KpТ?=jp>nO~\O!k7ϯ۔֔C|=u^>洠 endstream endobj 8 0 obj [7 0 R] endobj 37 0 obj <> endobj xref 0 38 0000000000 65535 f 0000000016 00000 n 0000000144 00000 n 0000048349 00000 n 0000000000 00000 f 0000051783 00000 n 0000052009 00000 n 0000051597 00000 n 0000307125 00000 n 0000048400 00000 n 0000048784 00000 n 0000071190 00000 n 0000071077 00000 n 0000050650 00000 n 0000051036 00000 n 0000051084 00000 n 0000051667 00000 n 0000051698 00000 n 0000061875 00000 n 0000052369 00000 n 0000052637 00000 n 0000062134 00000 n 0000071264 00000 n 0000071702 00000 n 0000072709 00000 n 0000077968 00000 n 0000095118 00000 n 0000110451 00000 n 0000126749 00000 n 0000140437 00000 n 0000159313 00000 n 0000183229 00000 n 0000210715 00000 n 0000237925 00000 n 0000264762 00000 n 0000291193 00000 n 0000303297 00000 n 0000307148 00000 n trailer <<4336D061D10542699B0CDE57451E0D75>]>> startxref 307335 %%EOF organize-1.10.1/docs/_static/organize.svg000066400000000000000000000641641403777030400203450ustar00rootroot00000000000000 organize-1.10.1/docs/conf.py000066400000000000000000000127301403777030400156470ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # # organize documentation build configuration file, created by # sphinx-quickstart on Fri Sep 29 15:43:41 2017. # # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. import os import sys sys.path.insert(0, os.path.abspath("../organize")) # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. # # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = ["sphinx.ext.autodoc", "sphinx.ext.todo", "sphinx.ext.autosectionlabel"] # If true, the current module name will be prepended to all description # unit titles (such as .. function::). add_module_names = False # Add any paths that contain templates here, relative to this directory. templates_path = ["_templates"] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] source_suffix = ".rst" # The master toctree document. master_doc = "index" # General information about the project. project = "organize" copyright = "Thomas Feldmann" author = "Thomas Feldmann" # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. src_dir = os.path.realpath(os.path.dirname(os.path.dirname(__file__))) sys.path.insert(0, src_dir) from organize.__version__ import __version__ version = __version__ # The full version, including alpha/beta/rc tags. release = __version__ # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = None # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] # The name of the Pygments (syntax highlighting) style to use. pygments_style = "sphinx" # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = True # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # # html_theme = 'alabaster' html_theme = "sphinx_rtd_theme" # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # # html_theme_options = {} # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = ["_static"] # Custom sidebar templates, must be a dictionary that maps document names # to template names. # # This is required for the alabaster theme # refs: http://alabaster.readthedocs.io/en/latest/installation.html#sidebars html_sidebars = { "**": [ "about.html", "navigation.html", "relations.html", # needs 'show_related': True theme option to display "searchbox.html", "donate.html", ] } # -- Options for HTMLHelp output ------------------------------------------ # Output file base name for HTML help builder. htmlhelp_basename = "organizedoc" # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # # 'preamble': '', # Latex figure (float) alignment # # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, "organize.tex", "organize Documentation", "Thomas Feldmann", "manual") ] # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [(master_doc, "organize", "organize Documentation", [author], 1)] # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ ( master_doc, "organize", "organize Documentation", author, "organize", "One line description of project.", "Miscellaneous", ) ] organize-1.10.1/docs/images/000077500000000000000000000000001403777030400156125ustar00rootroot00000000000000organize-1.10.1/docs/images/organize.pdf000066400000000000000000011320251403777030400201270ustar00rootroot00000000000000%PDF-1.5 % 1 0 obj <>/OCGs[7 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream application/pdf organize 2017-10-06T16:23:53+02:00 2017-10-06T16:23:53+02:00 2017-10-06T16:23:53+02:00 Adobe Illustrator CS6 (Macintosh) 256 56 JPEG /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgAOAEAAwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FUk87ebNP8 peVtR8wX5/cWMRdY60Mkp+GKJfd3IXFXln/ONXnfz/5xj8w6n5ivBc6ZHOiWSmNF4TOC8qIygHgi FNjXr88Ve3Yq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXYq7FXyV/zkB55/NrS/zNksrW/1 DS9OQx/oOGyeSKK4UqhLUjIE7GQ0IatPs0xV9NeSLrXrvyho915gi9HWprSF9QjKhCJWQFuSDZWP Ur2O2Kp3irsVdirsVdirsVeK/k9+T/n/AMpefNZ1/wAw61Ff21/FIjGOSV3uZXkVlmmR1VVKqp7m laDbFXo/lLT/ADxaXmtP5m1S21G1nuy+ix28PpNDbU2Rz3Pam52ryNdlWR4qo3N5Z2qq11PHArEK rSuqAsegHIjfFXzH/wA5deaNdlvtO8upa3EGgwAXUt40brDc3LghVSQjiwhQ9j1Y16DFXtf5L+Tz 5T/LjR9LlTheyRfW78EUb17j94yt03QEJ/scVZviqF1TVNO0nTrjUtSuEtbG1Qy3FxKaKijuf898 VeCa9/zmJ5etbxotE0C41O2VmX6zcTrZ8gKUZEEdw1Dv9rifbwVZX+W3/OSHk3znqEWkXEMmi6xP RbeC4ZZIZnP+64phxq9egZFr232xV6B5z82ad5R8s3vmLUo5prKwCNNHbKrSkSSLEOIdo1+046ti rz3yp/zk35B8zeYrDQbKy1OC71CT0YJbmK3WIOQSORSeRt6U2U4ql35h/wDOUnlryvrc+jaVpr67 dWjmK8mWcW8COtQyI/CZnZW2Pwge+KvQ/wAtvPtt548oW/mSK0fT45mkR4JWDhWiPFyrgLyWo60H yxV5r5x/5yz8naPfS2WhafNrzwMUe5Eq21sxBofTkKys49+FD2NN8VYpc/8AOW/mzV2Sw8seUkXV J/ghRpZb92YkfYhhjt2JpXv/AEKr0r8gtf8AzM1bTtabz5Z3lvdfWllspLy2NrWN0o0UcZVKKhQE fD+11O+KoH8wv+cmfLfk/Xb3QRpF7e6pYnjMGMdvDyKh46OTI5VgwNeHTxxVimnf85l6ZJdKupeV pra1/altrtLiQbjpG8VuDtX9vFXu/lTzZoXmvQ4Nb0O5FzYXFQGoVZXXZkdTurKeo/hirDfzG/Pr yf5B12LRdYs9QuLqW3S6V7OOB4+Du6AEyTRNyrGe2Ksb83/85W+SdIgtv0NaTa3eXMEVw0QdYI4f WVX9KWWkv7xVb4lVWodia4qnH5S/85A6B+YGoSaQ1jJpGsrG00ds8gnjlRD8XpyhYyWUUJUoPatD irJ/zJ/M7Qfy+0q11PWbe6uILuf6tGtmkbuH4M9WEkkQpRPHFXnf/Q3/AOWn/Vs1n/kRa/8AZTir 17yt5isvMnl6w16xSWOz1GITwRzhVkCt2cKzrX5McVYz+Zv5xeWfy6fTk1u1vbg6mJTB9SSJ6ehw Dc/Vlhp/eClK4qwf/ob/APLT/q2az/yItf8AspxVkPkP/nIjyV518yQeX9KstShvbhJHSS6igSIC JC7VMc8jdBt8OKsj/MX80vKnkHTo7rW5ma4uKizsIAHnmK9eKkgBR3ZiB9OKvHV/5zMsPrnBvKso suRHrC9Uy8ex9L0Qtfb1PpxV7V5B/MXyt560g6loFwziIhLq1lASeB2FQsqAsN+xUlT2OxxViP8A zkrr3mbRfyyludAllt5JbuGC/uoCVkitZFfkwcbrykCJUfzYq8Z/5xY80eb5fzBbShd3F3o1xbTS 38MrvJHGyCqSjkTwYuQte9cVfV2savpujaXdarqc621hZxtNcTv0VFFfpJ6ADcnYYq+bvOn5dP8A nSZvO/krzE18FpA2i6kjQfVmRFJhidQUUnY0pQk1L4q82h8y/nD+V040nVIZ4dPbb9EapH9a0+VV 7Rhi0ZHvE4+eKvr38sfPEXnfyXYeYlg+qyXIdLi3rUJLE5Rwp7qStV9j44qynFXzv/zmH5ju7bRN B0CCQrBqMs1zdqNuQtggjU+I5SlqeIGKqX/OLv5aeUdS8mXmv63pVpqt3dXb28IvIUuEjhhVPspK GUMzs1SBWlMVeR/nx5V0/wAofmjfWmiL9Ts3WG9tIoyV9FpFDMEI+yBIpK06Dbtir650KLTfzB/K /Sx5gt/rdrrVhbS6hByeIPIAjtRo2RwPVSuxxV8UecYU8sfmZq8WghrJdG1WYaYEZnaL6vOfSozl mJXiOpOBXq2of84ta9D+Xltf2ccupedruWKSew9WGGG3gdWZ1rMY+cgPHkeXXoO5KvTH8s695U/5 xjvdFeI2+r2ul3LXcSsrsvrSvLOOcZdTSORuhxV4L/zjho/lHVvzKhtPM0UFxAbWVrC1uuLQy3fJ AiMj/C/7suQpruMVT7/nKbQvJmieaNIi8uWtrp941u7aja2KpEqUZfRZoo6KjEcuwJxV9DfkZq+t 6t+VWgX2tM8l/JFIhmlrzkjjmeOJ2J3JaNVPI9evfFWMfmV5p/5x80LzJc3vmiytdX8zFFS4thb/ AF2UCNPgV0k/cI3GgHIg9O2+KvDfze89/kz5n0S3j8o+WptE1qCdW9dbW1tIXgKsHRxbyvyPIqRV e3XFXpv/ADhvcyt5f8yWpY+lFdwSqtdg0kbKxA9xGMVYJ/zlz/5M6z/7ZMH/ACfnxV6V+VX5T+QZ vyVTUbzR7e91LVbGe4uL26jWWVHpIq+i7CsXEDbhQ13xV4Z/zj1JJH+cflsoxUmWdTTuGtpQR92K vszzj5E8qecrGGx8yWP1+1t5fXhj9WaHjJxK8qwvGx+Fj1OKvkD/AJyL8leWfJ/nu20vy7Z/UbGT Tobh4fUlmrK8sys3KZ5G6INq0xV9T/kl/wCSn8r/APMDH+s4qmHnP8tPJPnRrRvM2m/X2sRILU+t PDwEvHn/AHEkda8F64q+V/z8svyi8v348s+TNHRNWt3rqupC6u5lhI/490WSZ0L/AM5I+Hp1rxVe l/8AOM35M3OjJH5315Hh1C5iK6TZGqmOCVaGaUfzSKfhXsu53PwqvFfzv8xz+YvzZ1prqfha2V22 m27MCyxQ2rmIkBakgsGfbrXFXr2oa7/zibJ5Pm0G2ktFmFq0NvqI027F56oU8JTcfV/ULc992p26 bYq85/5xg8w3Ol/mtZWSOwtdYimtbmMfZJWNpo2I8Q8dK+5xV9ZfmD508ueUPLcuqeYUeXTZHW2e GOITGQyg/AUNFoQDXkaYq8SX/nJ3yBo8T2nkTyXIk9w20KxW9ijv2YpbCZn+7FUCfKX55fnLfQv5 q5eWfKiMHFqY2hBp3S2c+rI/g8p4jqvhir6I8p+VNF8qaBaaFo0Po2NotF5ULux3aSRgBydjuT/D FWD/AJ8fmZo3krQrCHUNIg146tO0baXclRG1vEtZXPJJBUFlUfD39sVZp5L0bTNI8s2Nrpumfoa2 kT6wdMDF/QkuP3skdST9l3I228NsVTvFXz5/zmB5Yu7zy/ovmG3jZ4tLmlt7wqK8Y7oJwdvYPFx+ bYqlP/OM/wCbnk7QvKd55e8w6jHps8F09zayz1EckUqqCoYAjkrqdj2O3Q4q8q/OrzZaeefzPvL3 Q1a5tHMNjpxVSHm9MBOSr9r45CePelMVfYGjyaX+Xn5Z6aNfuRbWeh2NtDf3IR5QslEjYhYhIxBl bsDir4m85a1pmo/mXq+tWc3q6ZdatNdQXHF15QvOXVuDAOPh3oRXFX3B5M/MvyT50a7XyzqX19rE Rm6Hozw8BLy4f38cda8G6YqyScxCCQyryi4t6ikcqrTcU77dsVfn7GPJfmTzvfS3l0nk3y9dSSy2 5itpr1YB1jj9JG5/F3oeIPQBaABXoXkvyH/zjqdUj/S/n5tVVW5i2a0uNLgcAgcZJZg23+q6nCr6 x5W8PlwnQRE0EVof0YttxaKiR/uRGFqpXYUpir4E8mS6BdeedOm84yu+jzXfqavKxcswYlmLlPjo z/bI3pXAr138/Nf/ACRbylaaT5JtdNbV2uI5GutOtY0ZLeNXUiS4CKxLGm3Ik9T2wqnX/OG2p2Kp 5l0xplF9Iba5jgP2miQOjuPZWdQfmMVYn/zlz/5M6z/7ZMH/ACfnxV7x+U//AJIfSf8Atlzf8zMV fLn/ADj9/wCTi8tf8Zpf+oeTFX2b5x8/eU/JtnBeeZL76hbXUhhgf0ppuThS1KQpIRsO+KvkH/nI vzr5Z84ee7bVPLt59esY9Oht3m9OWGkqSzMy8Zkjbo43pTFXuH5P/nV+Wdl5L8s+WrnWfT1tYYbN rT6tdn9+7cVT1FiMe5Yb8qYqiP8AnIn85pvJenR6BorFfMeqQ+oLmm1tbMzR+qp7yMyME8KE+FVX z5+TP/KsofMTa3+YGqrFDZMJLTTngubj6xNXl6kpiikXgp/ZJ+I9duqr6y8s/nX+WXmfWYNF0PWf rmpXAcwwfVbuOojQu3xyxIgoqnqcVfJX59eVrvy7+aetevCfqupXDalaOQQkiXLGR6Gv7MhZDTwx V6zoWn/84g6npEF9NBDp80iAz2VzeaiksT0+JCPW+Kh6Fag4qyn8o9F/5x41bzFPqPkawZNX0N+U c0s16CUlQp60cVxK3JPiK/ElQew2OKvWPMfl3R/Mei3Wi6xbi50+8ThNEdj4hlI3VlO4I6HFXzFd 6B+ZX5Ba5darosS635Ru6h5ZE5Ko/Y+scPjhdf5x8DfgFXof5Xfn55W1PR7vVfN/mS3s9Zdi0mll JILe2gQkRpbhufrO1SzMGZu1KAYqyvyF+Zc3nvWb280W2a38maYrQnUbleMl5dGhpEp/u4ok+Ji3 xHkvTcYq8ft5B+cn/OQSXMX77yn5YCsr9Ukit3qvsfrFwfpjHtir6hxV2KqF9Y2WoWU9jfQJc2dy jRXFvKoZHRhRlZTsQRirxTW/+cRvIF7eNcabf32lxOSTaKyTxLWlBGZF9QD/AFmbFWT/AJef84/e QfJN6mp28c2pavH/AHV9esrekSACYY0VEX2YgsP5sVZj5z8p6d5u8s3vl3UpJobK/CLNJbMqygRy LKOJdZF+0g6riryf/oUD8tP+rnrP/I+1/wCybFWcfll+Tvln8un1F9Eur24OpiIT/XXienocyvD0 ooaf3hrWuKpj+ZPn228i+WX8wXVlLfW8c0cMkUJVWX1SQGq21OVB9OKvnzSNG/5xv/Ma6vdTubqb yTeLKWlsnvbW2im5gH1IxcJIg+KvwoRTwpTFWMfm9+Xf5P8AlvQre78n+bP0vqck4R7H6za3tYiC S/K1RPT4n+br2xV6h/zh5qesT+W9esLhmfS7K5hNhyJIWSZXadFr0Hwo1PFj44qyLzt/zjB5D8y6 vNq1vPc6PdXLmS6jtfTMDud2cRuvwsx3NGp7YqjPKH/ONf5Z+XoZxcWsmt3NzE8Mk9+wbiki8XES RhFSo/a3cdmxVN/y3/Jjyt+X+qapf6LLcS/pJY4xHcsrmFEZmKRsqoSrFl+1U/CN8VQn5jfkL5P8 /a7FrWsXmoW91FbpaqlnJAkfBHdwSJIZW5VkPfFWXeXvKGm6F5St/K9pLNJp9tbtaxyyshmKPWpL KqrX4v5cVYD5O/5xq8i+VPMtj5h06+1SW9sGZ4Y7iW3aIlkZDyCQRt0bs2Ksp/Mr8rtA/MLTrTT9 auLu3hs5jPE1m8aMWKlKMZI5RSh8MVee/wDQoH5af9XPWf8Akfa/9k2KovSf+cUvy70vVbLU7fUd XaexniuYlkmtiheFw6hgLZTSq70OKsg/Mj8iPKH5ga5BrOs3moW91b2qWaJZyQpGY0kkkBIkhlPK sp74qxT/AKFA/LT/AKues/8AI+1/7JsVZH5A/wCce/JXkfzFHr+lXmo3F5HHJEiXckDxgSijGkcM TVp/lYqy3zt+X/lTzrpq6f5hsluY4yWt5lJSaFj1Mci/Ete46HuDiryOT/nDvyabgtHrmorb1FI2 EDPx7jmEUV9+OKvSvy+/KDyP5EV5NEtGa/kX05dSumEtyyGhK8gFVVJUEhFAOKs0xVp0SRGjkUOj gq6MKgg7EEHFXlHnL/nGf8tPMUklza28mh3r7mTTyqwlv8qBg0Y/2HHFXn9x/wA4y/mlpdpNpvlr zsP0VMrpJaSy3dlEySfbVoofrCHlXfxxV7B+UP5X2H5e+Vxpkci3OpXL+tqd6oKiSToqqDuEjXZf pPfFWcYq7FXYq7FXYq7FXYq7FUDruh6Vr2kXWkatbrdadep6dxA9aMtajcUIIIBBG4O+KvBtZ/5w 40Ge4L6P5iubCAsT6NzbpdkA0oFZXtum/Wv9VWtI/wCcONChn5av5kub2EEER2tulqaCtQWd7nrt 0GKvcvK/lXQfK2jQaNodotpYQVKxrUszH7TuxqzM3cnFWL3flL8wYGEmia96EinUvhu55rqNhczq 9nyWdJj+5iSnwkU3AqCcVT240rzRdeTJtNm1ER+YJoXjOowN6QDsxIKssYK/BtUJXw33xVL/APDf myK7dor9pbaG/tLizE17Pza2igWGeKULEF+Irz4nkGY1NDviqJ0/TvPyeU7i1vtUt5PMr1+r38SK sKbL+yYqdm6o2KpGmifnWQI5NfsVURSL6yKhkMvqK0b0NnwHwclYfSPZVD6xH+cUGsWKidJ9NuNQ jLmxEbNDbLIvITepFDVWTrv4/FsoZVUXQPzxDW7HzJYkLazJcqY46Ncsrei60tFNFYiu/b7LdCqj 30H80HR+evxMQ1k8SIIogfRMBuVLi1JAm4zdmG67AVAVTjzZaed7lrIeWry2skUv9ee4+IkHiECK YZa0+I9V7eOyqUpo35n7zvq9v9YkhkjeJHX0o2+uvLEyVtDVvqjLFyK7MKlXxVAw6L+d0cJ569p8 87FPtKqIoWpanG0qeWw3+Yp0xVHTaD+YyW0K22rRSXcFzqTrcTzEK0NykosucSW1GMDOhKE0+Hqa gKqj9B03z7BqyzaxqsNzpvpyq1qipy5F6xNyWCEsyp8LGqqevEYqoXej/mGuqXMlhq8QsJtQiuIk mKlks/RRZYOP1Z/92KxoHqwI+NCDyVd5f0Tz3BrNjf65qcV5HHbXNteQxSOiFpRaPDKsKxRxMySQ 3FCVDKkgXk1DVVl+KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2KuxV2 KuxV2KuxV2KuxV2KuxV//9k= uuid:1e5d5c86-71a7-ba4b-a79c-97169be62009 xmp.did:0380117407206811822AF33CB0CB0D8F uuid:5D20892493BFDB11914A8590D31508C8 proof:pdf xmp.iid:0280117407206811822AF33CB0CB0D8F xmp.did:0280117407206811822AF33CB0CB0D8F uuid:5D20892493BFDB11914A8590D31508C8 proof:pdf saved xmp.iid:0180117407206811822AF33CB0CB0D8F 2017-10-06T16:19:14+02:00 Adobe Illustrator CS6 (Macintosh) / saved xmp.iid:0380117407206811822AF33CB0CB0D8F 2017-10-06T16:23:51+02:00 Adobe Illustrator CS6 (Macintosh) / Print False False 1 219.780556 59.266667 Millimeters FiraCode-Medium Fira Code Medium Open Type Version 1.204 False FiraCode-Medium.ttf FiraCode-Bold Fira Code Bold Open Type Version 1.204 False FiraCode-Bold.ttf Black Standard-Farbfeldgruppe 0 Weiß CMYK PROCESS 0.000000 0.000000 0.000000 0.000000 Schwarz CMYK PROCESS 0.000000 0.000000 0.000000 100.000000 CMYK Rot CMYK PROCESS 0.000000 100.000000 100.000000 0.000000 CMYK Gelb CMYK PROCESS 0.000000 0.000000 100.000000 0.000000 CMYK Grün CMYK PROCESS 100.000000 0.000000 100.000000 0.000000 CMYK Cyan CMYK PROCESS 100.000000 0.000000 0.000000 0.000000 CMYK Blau CMYK PROCESS 100.000000 100.000000 0.000000 0.000000 CMYK Magenta CMYK PROCESS 0.000000 100.000000 0.000000 0.000000 C=15 M=100 Y=90 K=10 CMYK PROCESS 14.999998 100.000000 90.000000 10.000002 C=0 M=90 Y=85 K=0 CMYK PROCESS 0.000000 90.000000 85.000000 0.000000 C=0 M=80 Y=95 K=0 CMYK PROCESS 0.000000 80.000000 95.000000 0.000000 C=0 M=50 Y=100 K=0 CMYK PROCESS 0.000000 50.000000 100.000000 0.000000 C=0 M=35 Y=85 K=0 CMYK PROCESS 0.000000 35.000004 85.000000 0.000000 C=5 M=0 Y=90 K=0 CMYK PROCESS 5.000001 0.000000 90.000000 0.000000 C=20 M=0 Y=100 K=0 CMYK PROCESS 19.999998 0.000000 100.000000 0.000000 C=50 M=0 Y=100 K=0 CMYK PROCESS 50.000000 0.000000 100.000000 0.000000 C=75 M=0 Y=100 K=0 CMYK PROCESS 75.000000 0.000000 100.000000 0.000000 C=85 M=10 Y=100 K=10 CMYK PROCESS 85.000000 10.000002 100.000000 10.000002 C=90 M=30 Y=95 K=30 CMYK PROCESS 90.000000 30.000002 95.000000 30.000002 C=75 M=0 Y=75 K=0 CMYK PROCESS 75.000000 0.000000 75.000000 0.000000 C=80 M=10 Y=45 K=0 CMYK PROCESS 80.000000 10.000002 45.000000 0.000000 C=70 M=15 Y=0 K=0 CMYK PROCESS 70.000000 14.999998 0.000000 0.000000 C=85 M=50 Y=0 K=0 CMYK PROCESS 85.000000 50.000000 0.000000 0.000000 C=100 M=95 Y=5 K=0 CMYK PROCESS 100.000000 95.000000 5.000001 0.000000 C=100 M=100 Y=25 K=25 CMYK PROCESS 100.000000 100.000000 25.000000 25.000000 C=75 M=100 Y=0 K=0 CMYK PROCESS 75.000000 100.000000 0.000000 0.000000 C=50 M=100 Y=0 K=0 CMYK PROCESS 50.000000 100.000000 0.000000 0.000000 C=35 M=100 Y=35 K=10 CMYK PROCESS 35.000004 100.000000 35.000004 10.000002 C=10 M=100 Y=50 K=0 CMYK PROCESS 10.000002 100.000000 50.000000 0.000000 C=0 M=95 Y=20 K=0 CMYK PROCESS 0.000000 95.000000 19.999998 0.000000 C=25 M=25 Y=40 K=0 CMYK PROCESS 25.000000 25.000000 39.999996 0.000000 C=40 M=45 Y=50 K=5 CMYK PROCESS 39.999996 45.000000 50.000000 5.000001 C=50 M=50 Y=60 K=25 CMYK PROCESS 50.000000 50.000000 60.000004 25.000000 C=55 M=60 Y=65 K=40 CMYK PROCESS 55.000000 60.000004 65.000000 39.999996 C=25 M=40 Y=65 K=0 CMYK PROCESS 25.000000 39.999996 65.000000 0.000000 C=30 M=50 Y=75 K=10 CMYK PROCESS 30.000002 50.000000 75.000000 10.000002 C=35 M=60 Y=80 K=25 CMYK PROCESS 35.000004 60.000004 80.000000 25.000000 C=40 M=65 Y=90 K=35 CMYK PROCESS 39.999996 65.000000 90.000000 35.000004 C=40 M=70 Y=100 K=50 CMYK PROCESS 39.999996 70.000000 100.000000 50.000000 C=50 M=70 Y=80 K=70 CMYK PROCESS 50.000000 70.000000 80.000000 70.000000 Graustufen 1 C=0 M=0 Y=0 K=100 CMYK PROCESS 0.000000 0.000000 0.000000 100.000000 C=0 M=0 Y=0 K=90 CMYK PROCESS 0.000000 0.000000 0.000000 89.999405 C=0 M=0 Y=0 K=80 CMYK PROCESS 0.000000 0.000000 0.000000 79.998795 C=0 M=0 Y=0 K=70 CMYK PROCESS 0.000000 0.000000 0.000000 69.999702 C=0 M=0 Y=0 K=60 CMYK PROCESS 0.000000 0.000000 0.000000 59.999104 C=0 M=0 Y=0 K=50 CMYK PROCESS 0.000000 0.000000 0.000000 50.000000 C=0 M=0 Y=0 K=40 CMYK PROCESS 0.000000 0.000000 0.000000 39.999401 C=0 M=0 Y=0 K=30 CMYK PROCESS 0.000000 0.000000 0.000000 29.998802 C=0 M=0 Y=0 K=20 CMYK PROCESS 0.000000 0.000000 0.000000 19.999701 C=0 M=0 Y=0 K=10 CMYK PROCESS 0.000000 0.000000 0.000000 9.999103 C=0 M=0 Y=0 K=5 CMYK PROCESS 0.000000 0.000000 0.000000 4.998803 Strahlende Farben 1 C=0 M=100 Y=100 K=0 CMYK PROCESS 0.000000 100.000000 100.000000 0.000000 C=0 M=75 Y=100 K=0 CMYK PROCESS 0.000000 75.000000 100.000000 0.000000 C=0 M=10 Y=95 K=0 CMYK PROCESS 0.000000 10.000002 95.000000 0.000000 C=85 M=10 Y=100 K=0 CMYK PROCESS 85.000000 10.000002 100.000000 0.000000 C=100 M=90 Y=0 K=0 CMYK PROCESS 100.000000 90.000000 0.000000 0.000000 C=60 M=90 Y=0 K=0 CMYK PROCESS 60.000004 90.000000 0.003099 0.003099 Adobe PDF library 10.01 endstream endobj 3 0 obj <> endobj 9 0 obj <>/Resources<>/Font<>/ProcSet[/PDF/Text]/Properties<>>>/Thumb 13 0 R/TrimBox[0.0 0.0 623.0 168.0]/Type/Page>> endobj 10 0 obj <>stream HlK\E +2 uzo"V!Zb= 03" n h{\/߽Njo^/>ˇO#Ogǯ\~gKqy*nxLץ9:JQ/i~XNwjEu6yגcfǵӪCknK>]yi.vBN9 kx͗pywy4u\xr7ΫMލfW \8;d ~"2i5ԫ.6 "2~#PN>S ^@ ӆLtZhwV$גS )X{+pOzl,t DONHB\–@!%rA4 {(%\/ו80P+0g7"ȵWH`!II5"ܤЯPunW*Qe;ks5ҊP" թTsXOׂOK־>-ED0ށWue|"j Uʑ:Ȭ=\mxjI@:DRJ.IyM Psjp+U=mWP ʾk.UQ`V6m! ,-v z?Z|t`&l61u;8Ὕ$u1UPh}'6 lP!% FhrLXM!JSpu`˰`SNAfraœ6BL2_S] ,,~Vߑ[ l.}q;sF͏1wszmA1tIRnLr}/2T^)'9ڼZ)@\uG-yobm7X?.W[4D+ (KHR&΢fID@ \m$su% pBAj {vv'ZI,(1TcGl DjRddXqQmW!NexiJfsXƗ %U6v|i*k!o4}v"N KT.hBBFw5/K4KHOAΤ, UT IFtVSUPDiStӠ{d5 u^VxrJM( جaUthjXk}ۥ/g>M:ϗgw~L%is}5W۾ZFΝߋj%EW'l]}{wypxqǧOOw[yͤ endstream endobj 13 0 obj <>stream 8;Z\r>n4ap%"iU=Sp^REpc9WaL)&4;e[DqVU'3lBo*OuEmfN9XQA?[$Z`fD "CkuFC4bfNCq;Li2JOSARUP9%F=Lq3\`2uTXe3BSB4TDZc9ONb"#jhHa_WXN3>%fF #JH7&eXT`G/b_r^E@VIP%F]I-7Bob8h&#k)TAqd/FM!iA~> endstream endobj 14 0 obj [/Indexed/DeviceRGB 255 15 0 R] endobj 15 0 obj <>stream 8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn 6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 7 0 obj <> endobj 16 0 obj [/View/Design] endobj 17 0 obj <>>> endobj 5 0 obj <> endobj 6 0 obj <> endobj 19 0 obj <> endobj 20 0 obj <>stream HԖ{|NGgfy߈H"97l ¶. AHh4B5"%ںVj,ooYԥZGw<3<3sΜy #WK?zMd)iY7&m\0'aY3 9qX=jGTC@T>̃͠22'%Q 4v䨴TB~ Yɾ')4^?53]i:y[5jlv 0(ݟ5&=%KoKn܅Jc X2Ez`pּܝf3vk:&vꀽŏX%u1?4}inݜ@ҏZ>4^Oi/ Brn5?.FӂsO|&g|>bdbX ^ϊ\1S$1]޼\> P)k S^$ 'LbL:A :]-4~v-Hki FZc-P µE UrEJ- gX  n/QO :W:D-EFǦ#MW&2JFV Y$9@-!r"gr\+Oe˛|uo=HoU1zIgS&}^X-V+D\rE+jV_kCk5a}՚jMd~Ȧ"izci>cq8j9;qӸcܷv[mmDԺf*^qǵ|Eޏ,Eꕒzg8z[z"&ӗ1 z.p#bE[Qq[B l*cdk^v K2OBLɍr,iY)myO7z I{kDl=ϣޮkg)zO>S/:ԣi1ژf,1O_P8`1yWc%Q6Rbri.?gLqR9Lrws&RGs㑳nss;:Rgk̙\ծBWk#nLGXH$Ku$9;^WxiObϤr}=>>=# $t{_{=mo^܋ҧ)nbwPS_ I."EqF8uE+_I_[\{vRqovuSL :`)fğ6rMy/yY.y֋2OwG<˫7g ͋/O D1H]ԂUJQ$WpuFlL`/f+xȿP1(6CA+PRk!!^$>7MFb2ph9xYH4[F,s1MUr)"i m77;CC X,E(V# kb4:X'hMg> ~h-h=*V'JGE5 c?@)Ŀw8.8c荳x '3n c x. '"Rq)7&qCqcFOSYxqEb /LW1M_}q F:hj\>RИXKf7V>PMbhUKtc 7Y?vueXwփYO֟%k:\2;ľevc VNR=vUs<*ׁ\1= `83 iΙ\7/⽢@MF \r^* ,wbu".||;}^z;N'c>7gtStRQ ]qtz]t&%_?R! I4Y0i MihAC6@d"=43i Z5,xi耎Ȁ ?:6d 'nGowaCEa0^*[5XuPx [6c'{VMqq =!C' ß1A#F8p1}SN˔_S&7p7g1'1_`"$|0NQuA1F)2&LLYJ0 0bc.`6.b2 *"]\b&$q1'K(KQC<@x5G()Rdƨxr;nq lq[nɜĉܘS97܈[snnũܞ}ܒ's9t3yQ< ͅVP*ּrGT/`8}b}~Cr2tYTL"NDǖWM(\qve3;*\܎JWʖvtǎƸmv+;پ+3YwWo>3;&Č3ėN00sw`!WHK)6]`.HVZmYVZJ>JǾR_Zuj~gl@ժR99e*տk1x^LZ,ް hM}a>#Gh>c8죱ј}4RzIi:kz]+PRNZiT `JAAYp'<` ?Vb <3/gSz^Ov ߷!ؐ?H=q9Eeu,i5mZvN3';_ל4cXNvT'g΃IP"=|~h(?7z49e~:V[Wk‡mnw[>it5pO)Ζ|mm>wv~@33H_$hu{}f.?gjAYߊE|1j,ds E2¬P)vk G4o{l8B al,pp"SΦ ȩpv2RQU1p"5k2j^ሜJO!<~_ t>78roRwگGG&өKڜX4v~l֓ѥ)E7sSR1X0l)9TE$E*O**k`EH@.;T6tcET-:Y#Wg.r>W.JGǃ=n3[aߟOS\ɸ|M7RԪb͐¹b:Wձ : 1*EkU #^ՙd5ӟcD9'Mfvn$>?p"_9]^+!r4ff@M|vkT-24͜:xMࢉo˥2M_PV ;^bUP7wƪ)& o,4BB[~_1V<(iv q;S-"=;x0bC-KCVdaLk Y0__|lM'Ŧa7#Pֳjpvwv;z|Y,Ƽ %f3Y> (*U}]6O3ע c4x]o\6З?ر˚]3-"s^Y SF2UxOG{+-8mrPޜ?Qs}}z$ѧv'&!>籅~eA&O6hBU~V>fC%-CVMiy.eQäTdt>*:Y_WO,@6R_d3%+(q =(MP^2;iUŪPbD7Ɓ 1.WSk)ÿ(^j G/ƙI߾bTjf'_ZD-Ʈ 31݂;MncQ;M"Vi,TzvkUWyH2YףH=>H.Tz3S{2 !̂,e)89 j9ndiK%i>AN [x#GJ+Dûw?:~qy20bs8Sl[i/ਯ*I6 $ RXyAC yZH @Yl V8 cǨZJh;Sꌭ-3v֪Ŷ:Tcf?w/nf>s=sν?*DTUlٙc3N"pN eR+x= 6q:;EfZ_Ұ's yo<w<| x*]1 EnIڈ;JgPjm@i&H̹/ș^59urSQMMy~ρ{3j<[2Q*ZRHK> "2ˣ{%=i [w PXyYC$KWsfĀQ#%B@.d0QƎE0H >8La!}f9q(&rbFA(*ra S|i9}Q< *mF2E -?sb6.˝wn',__W:n4*/:X{}c+ikl/ ly"/X,OWHM鱬|=Mt/927W ]kׂ)Ut$Zl?ae)zN8ll;Muhk 0Bt),P<3\}^ʞ,CwS #.x.wlL̓wk{J]bKOȜv}=<SqR93}A?_Ol<+csvs{E $kx-;ujɬ}: y{A/gld> #{-^:M{(8bM{b`π̛bqY1O}sĸ`& I>^~9"1!K]qWjdV BcVx;_K_J9w;e3UfF0zSzpgȺ^o9>{S|q)G?>pߓ}9Zה:uv]ogU'_.v o]՟'Yc]Oݏmuٺ\'zmpc5œO~/37\*jE,=.ߣX`;wmWL&>O)U+A 7٣=;쒔OBmJǛ 2^mqS8cd ~$|ʹ/ ?IRЗ)0gNNDׅq>|g]!zq-~Gt $-Ɲ徃̈́?zw{ Ui䁙IK< >Ww-5iIq'[>=m~"uQWe-[~' Aw=J37d}:a?h!=FoKᝏc7`@t;NWRs 18 A $H A $H A n"o4}>M,JVJ#VʿlI'#_&y/+$J%ʣ$@i1}U*7%hg䓨3Q)y/;%JmoT:uuOo_lv5:CО5 ;B-j[[Ў?lnim7ip۶fU# MUGF]hCnZQ|e=TK*rظ ڛ[ފ\vvj@~+r 97Jn6D;5뺬6Ҹu!ڂدV=Yk[tZ;=£ΆAX?Y.[v^lx> endobj 21 0 obj <>stream HԖ{|NGgfy_"7ytiڊK-Yu)%ْ RwvRڮƢAHě[=.u'}7X{>gfgfΙ9@Lp"?A~e_=*mtꤑ3tcz-75^ 3SGMh|t 6JJj̤!c%%"r:SM~)i,_Z'S֕?`i&|_C+i^`n46 h"lCkS\(wM /|rJz>r?}_[;'MG~ܥH9^&u%j~)x9Y>g|y._OJ1E/&j>u[ :3z` a0! )tL4q~]-N!r ˱[%`/ *Qq7p̯I7c1bb OJnF|؅PR):g7qQ]/j~B]ZuNׂ$%ib&ybJzc)x?#2D$f,QWxRыq ^#|EhxQOxW?%"@0A" -tDO!}A*kAZc-T5iZ@x/u'tLhGOD,UjXkŊng\p3}y o£yGޅO,υIRkH"I\uIn-=ꥑzX%|#ƫiE-~SBl(uTF2FvK)2S"N S7`u@\])إ*^@bt2yqFPЇ8h%Jb-2!q#q-&qMx\&Z'^.!bb"fYJ>BV"Zb"P WM93 _Uac+Z[Dx_ID"w'{`:ſ?w88C膣3x'n c ށq#ppɸ xqwq Tcj0CQ1Jd)^ԅ/(q Qi>耧#Zj5)C':̪{}6`7);=X,eXγn;zY/֛ d ʮ1!vaG1veORvaeeg«<" ^p$=NAL4L.;^JCKsAȍ 7偺. b8Nd||;}^z;E􉾁?%/MtTDt 4A&%LF J**h`aTF>@l܉AD'̤~![8X.^qIwpG;lD pCG ß0+F=}QS0tF%^ 2a>x| 8&KDwDq+J(9Lטo0 ut\ |٨\\U,5:Pź %ED='&{H^bG&RQ,%Aj(SVP2xRR5ŏ~Li 5OxZIg?6݂_R[,&⼸f)xFϊxIV9r8#aqDc8!N;b/Xɘ\+ QVz6r +rKəl9Z^&s;:?w[V'8G!q|:_ až2}+ikĸ(`#Ǟ:ܧHX  ZV :ȑH'Z}ױT}_ₙ!e/ӈQEEe ~g[ (TvqM"96+`(7 [څ;b*|Q7/xSey7EsHt^2< 퇓ٵU& ldx*юTI4ǯlmhYQp;]7|G%K=J4}UR0bUD,AvpL8Ubo_y#y֧1#9X%'Y}F#Q?t&Dz~8悧 Tfx}zڍnܝ_WHrZ[?U7I`0R}2WUy3FU/`T>|>}VDo)%,*"&fZiajcKfv L8laǤ+[1ve+;fc\ڎ5pe;Еm ܕ. bJJpwͲز6"Y-Nxg˖c+ǎ!;I0d,,c&eTQ2N8p9#3";N(\"HT?T#tUW aF 4:A//؇ᨂ}8v}8>`!HěiUobᡄҋ`"z4G /6bG|%ÃC$*@#CzEq≊%UhQylIc/îFr)p7 wLa=DhV"|@LG x 9`)]oI@5 QDiqT33g"(VLk8grs&BBt E/smr}|<\ M? ^F7 ޮ5Zi@9*,z_3 f@_}* 7 MW8Dm" ow߷ۀH~VV5  #;an]{8JDrcZۈ@ GU:,Hx8Lm>T*T K'.CVr,-O7ʿ57mj[#t"O;m϶gZ_AZ"5Dgt6Do $D~9ܔ .JJ,0HlN Z'(Qq0& r2$R!=9= v0Qm]ͿidIdneE; r0r+`H6]H%U7N@J;ZK™<ĥG8jWK>(Ξ,_n˳/bC i'h%ŪA}QXGmY ˁa6C{\d҆Ih}prD(wnw{`vh?f뗕DP}rerr,9rklˣB@R5+,o.Z46~cMdLk } !3 $D(r$m)bQJDQp"$S+NlZK~D^ 2<<<9 =5X:TVK5Lm+%g$@ŵQz21zQgq;{%=ϦBŅx$9<\s8;Z<1E֓V<~1Lxf#>??>3r8 PuϢ29B qsYp)x) C&.'dҘpb< .[sk#(\]gq٩H /)]L&{{SVyOMCD0WfslBgv=;EwnH 53g.s X6нES$0K C~aWjUgOy9m [vC\|h>Z̕oB!#1KnN(=m `pmjZ[I)Crn/'- "DdK&jMp8ll[QS2ܲf򈳆sIN6'kJ~/Rµ ~:~jdvb!oiupm"1e!}qIg&#]2ftɔ  f![MŗP^N9Z7?_L#.?@гgGҟ@|jc?}Zn /f~Z~ ? C>['ϲ9'x <<_Q_U?{,!$BI !$ic)`^D%4#K5!IB-8*80c;>ƎHjRlPԱ>XR6=~MB)ꌿ|r_=3<{I?GI’NR6cN^l;֓B^技5, _r"DRzqpl*}@`Cm4eUlwOAEF5sp+0Eֽ_`hKk&K6,y\lV궪H;I0!3zeŭ.T=]rCs{kט= ۼ\d[|܋RF"X }V̺t~2L:iw|@R7ySgn>T'깸FdK]u;WpֱLeozr9R#ɚbV.R8ُ?ԺYƸZΐg90K=n׍FXة#AtvDJ,)~MP\_#a/۰["s͖rP^u]a~׽Mhg/Du9#g/2ԝlfZg^$ʽ+/Q}'jxV%3Ѷ17ؖ2vD2>}bQDt6WKr/}.Kk|wוSVtRRw1S<wa3^jnVԙ3)g=ϬI25&wڸا=~6Y#>i `P@o3 K vٿS~Ԍi~%h:ܣR~Ҭ_??BgrFyy 8 ΂3w=9)da(sd۽ClZ3EMnZrŶK*=4z !wyɵ"˱6r'WM_!qoɉNahH%2[EhD/#Cd6ɶTyl=gƱ[=rM:= <*{r9c'C쿃_'!|=.oWC ]/'cB9}wNɸ2A1p/4hwRQ$)]n8uNiwމ:=|CܭIt.ΒxK%~_>N'%><S@%1gbXu~$8YL8ǸQs$۶fG~/ܾRo ҿ,e~~bsf;)6oB=޺rN;%uގλmmL^B3ۭަ;it7ʌux֠ߎ3=3Kԑ{˗B>NrdR:O_Z=e7> }9{?wL%OgM s)\f\GJ.θ9tɵW,S|e[9v -ߥZeuor;{YNq@o1wn{ԼuxYְPnH'x^>>4bqǾ,m%yA2uO$%.J\9c$CϚ|͂O,ȅH97k&8.f-2d@YeǭTDGtʿ `y4%G^!$_@N%JTE/I^Qq < H>zɇw)ޡخޑȱH]u#;Fb#֡x_|0~۷ԴƆMq!9>Ć#P{wt/tvi_?i Ƈ#Jj8 ^2G(B@uhqoʹ6Q#C*=nZAM# ]($͖sZ"A0s݈n*P~>&Zxԕ8z6)e}{[X pxh+a ]cTmABCQOx[x}:< UA]Ut% O(H3P75t]- jm892Vɥ}o8tWG'7n//(UlLQ`WZZ- endstream endobj 12 0 obj <> endobj 11 0 obj <> endobj 22 0 obj <> endobj 23 0 obj <>stream %!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 16.0 %%AI8_CreatorVersion: 16.0.0 %%For: (Thomas Feldmann) () %%Title: (organize.svg) %%CreationDate: 06.10.17 16:23 %%Canvassize: 16383 %%BoundingBox: -11 -158 519 -40 %%HiResBoundingBox: -10.1353 -157.6074 518.6563 -40.9722 %%DocumentProcessColors: Black %AI5_FileFormat 12.0 %AI12_BuildNumber: 682 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%CMYKProcessColor: 1 1 1 1 ([Passermarken]) %AI3_Cropmarks: -42 -174 581 -6 %AI3_TemplateBox: 298.5 -421.5 298.5 -421.5 %AI3_TileBox: -133.5 -369.5 649.5 189.5 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 1 %AI9_ColorModel: 2 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 1 %AI9_OpenToView: -207.6665 164 1.5 1520 938 18 1 0 85 134 0 0 0 0 1 0 1 1 0 1 %AI5_OpenViewLayers: 7 %%PageOrigin:-8 -817 %AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 24 0 obj <>stream %%BoundingBox: -11 -158 519 -40 %%HiResBoundingBox: -10.1353 -157.6074 518.6563 -40.9722 %AI7_Thumbnail: 128 28 8 %%BeginData: 5056 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C45FD15FFA8FD4BFFA87D7DFD30FF2727A8FD49FFA827F82752FD2EFF %7D27F8FD4AFFA8F827F852FD2DFFA827F852FD4BFF7DF827A8FD1BFF7DF8 %A8FD0FFF7DF827A8FD2BFFA8FD3EFFF82752FF5227FD0CFFF82727FD0DFF %A8FD1BFFA87DF852FD06FFA8FD0FFFCFFD21FFA8FD05FFA852FFFFA87DFD %0BFF5227F87DFD0BFFA85227F82752FD05FFFD047DA8FF7D27F852A8FFFF %FF7D5226272727F82727FFFFFF7D52FD042752FD05FFA87D52FFA8522627 %52FD04FFA8527D7D7D52A8FD05FFFD087DA7FD04FF7D52272727A8FD11FF %FD04A82727A8FD0AFF7DF827F827F827F8A8FFFFCF27F827F8A87D27F827 %F8A8FFFF2727F827F827F8527DA8FFFFA827F827F827F827F8A8FFFFFF7D %F8272727F827F82752FFFFFF5227F827F82727FD05FFF827F827F827F827 %27FFFFFF2727F827F827F852FD05FF7D5252FD07FF5227F8517DFFA8FD0A %FFA8F827F87D7D52F82727FFFFFF2727F8275252F827F827FFFF7D27F827 %52A8272727FD05FF52527D7D5227F82752FFFFFF7D27F827277D5227F827 %A8FFFF7DF8272727F852FD05FFFD0527F827F852FFFF5227F8527D7D2727 %F8A8FFFFFF7D27F82752FD05FFA852F827F827F87DA8FD09FF2727F852FF %FFA827F8277DFFFFFF7D27F827F852522727FFFF52F82752FFFFA8F82727 %FD09FF7D27F852FFFFFF7DF82727FFFFA8F827F8A8FD05FF7DF82752FD07 %FFA8FF7D27F827A8FFA827F827A8FFFF7DF82727FFFFFF7DF827F827FD05 %FFA8FFA85227F827F852FD08FFA827F8277DFFFFFF2727F87DFFFFFF7DF8 %27F852FFA8F852FFFF2727F87DFFFFA827F827A8FD05FFFD047DF82727FF %FFFF5227F852FFFFA827F827A8FD05FF5227F852FD08FF7D27F8277DFFFF %7DF82727FFFFFFA827F827FFFFFFA827F82752FD04FF7DF87DFFFFA87DF8 %27F8A8FD07FFA8F827F8A8FFFFFF52F82752FFFFFF7D27F827A8FFA8FD04 %FF7DF82727CFFF7DF82727FFFFFFA852F827F827F827F827A8FFFF7DF827 %27FFFFA8F827F8A8FD05FF7DF82752FD07FFA827F82752FFFFFF5227F827 %F827F827F827F8A8FFFFFFA87D7DFD04FF7DF827A8FD05FF7D52A8FD07FF %A827F827A8FFFFFF5227F852FFFFFF7DF82727FD08FF52F827F827F827F8 %A8FFFFFF52F827277D7D52F82727FFFFFF5227F852FFFFA827F827A8FD05 %FF5227F852FD06FFA827F82752FD04FF7DF8272727F8FD0527A8FD08FF7D %27F827A8FD05FFA8FD0BFF2727F87DFFFFFF52F82752FFFFFF7D27F852FD %08FF7D27F827F82752A8FFFFFFA8F827F8A8FFFF7D27F827FFFFFF7DF827 %27FFFFA8F827F8FD06FF7DF82752FD05FFA827F82727FD05FF7D27F827A8 %FFA8FFFFFFA8FD04FF7D7D5252F827F852CFFD06FF7DF8A8FD09FF52F827 %27FFFFA8F827F8A8FFFFFF7DF82727FD08FF52F852A8FD07FFA827F827A8 %FFFF7DF82727FFFFFF7D27F852FFFFA827F827A8FD05FF5227F852FD05FF %52F82727FD07FF2627F87DFD04FFA8FD04FF7D27F827F82752A8FD08FFF8 %27A8FD09FFA827F8272752F827F852FFFFFF27F827F827F827A8FD04FFA8 %F827F827F82727527DFFFFFFF827F8275252F827F8277DFFFF7DF82727FF %FFA8F827F8A8FFFF5227F827F827F827F87DFF7DF827F8272727F82727FF %FF7DF827F8525252F827A8FD04FF272727A8FFFFA8FD07FF7D2752FD0BFF %7D27F827F827F852A8FFFFFFF827F827F827F8FD06FF7DF827F827F827F8 %27A8FFFFA8F827F827F8525227F8A8FFFF5227F852FFFFA827F827A8FFFF %52F827F827F827F82752FF7D27F827F827F827F852FFFFFF7DF827F827F8 %2727A8FD05FF272727A8527DFD04FF7DFFFF52F8A8FD0CFFA87D525252A8 %FD05FF7D527D7D7D527DCFFD06FFA87D7D767D2727F827FFFFFFA8525252 %A8FFFF7D52A8FFFFA8527D7DFFFFFF527D7DFFFFFF7D7D527D7D7D527D52 %A8FFA8527D527D7D7D527D7DFD04FFA8FD04527DFD08FF5227F827A8FFFF %A827A8FFA8F852FD23FFA852527DFD04FFA8F827F8FD44FF7D27F8275252 %F87DFFFF27277DFD23FF7D27F827527D7D7D2727F852FD46FF7D2727F827 %52A8522752FD25FF5227F827F827F827F827A8FFFFA8A8FD05FFA8A8A8FF %A8FD0BFFA8FD07FFA8FD05FFA8FD0FFFA8FFFFFFA8A8FD0BFF7D522727F8 %27F8FD27FF7D522627F827277DA8FFFFFF7D7D525252FFFFFD057D52A8FF %7D4B52527D7D52527D5252277D5252767DFFFF527D527D7D7D5252527D52 %A8767D52527DFFA8527D7D527D52FD0EFFA87D76FD35FFA8A87DA8FFFFA8 %FFA8FFA8A8A8FFA8A87DA8A8A87D527DA8A8A8A7A8A8FFA8FFFFA87DFD07 %A87DA8A8A87DA8A8A8FFFFFD06A8FD5BFFA8FDFCFFFDFCFFFD2CFFFF %%EndData endstream endobj 25 0 obj <>stream HWnH|H^~Y狑YĹ `$1H/EoЎe#Æ5ꮮ2&/2Y|E ][֟_vo|G߼>?FGe֕M0py oqض٬'Uݿ;aiE_uxnoLɡ`X8 =iXi=Y;߿ H(ںqrBLh.q[RPM-%M~*(?6}mz1+}^яPV]88*ыpԄ+$We͂z{͏pD4 ow7?Y7i:fţ!Q[gqc6x$m_f3Xge?.8ԪtE>0fiJ0;#Vii]-g:WJWuedK&!ϔ!:Xu]pc0-y_ApdWlMfau1Kç{ʳ-KsQiׄw;]1֝RY|]?vUW3ਘF/F_z8cOB9rU,&77u͊, |}㘚EMߤ8B o.\#w&F%-}oo1S~\ˏ7i?~~iA\4b? d`xAp? 5>9|ٿ@HKVNwxXzɅ?C _^ϛjtjEK?Rp"'Vr.NV;R6\1'6A(jƐ| jR!/.<9! 9 j iNRp .8HJG)mI>,N^*OZ A[ AF3B%L)aVxIFѓ3(JwO.aiؘLkRadi,(&hi7{ut巿Fon{ӦًR?X&`Ǣ1b$nLHF'4C|@Wf<$PIpd @}_~2 dQ9F5t f,J tUL PHҡBʁ_98` R K0,.An*9$nrABA |(("@Ep6bi *JhA)l)V / ) "LֳIFB2GHyH⡰`Ŵ؏^Mc!jaZ@}?2$|CI_! YX 2ePH"v zhWS04d&Y$+qSEVAUP~ _XT+"2 DGELA?쑎e#ԺuN_J 5TȞ  Ѵ=S\d JccIU@>@0R{HZHPX8N"@@!=(J* Z9d0w$*f(+G?@4gLa5V[O455$iWC%>dj)h* ռߴ'CFPrj{TvJz$>f$ڑN$Ah=wIKAX|C*qE<3R*ةF^ZRb%ESSS~@;"$lBo JC _<}ws}!<^pA'_аf^v\Dd-).%,d;Ruc>pQ3:2)9i`CMtzl:B-= >F|$ozQ$!^鍡']v;zW}ysdK1NlE$FP!c5Svsat]1$-mT@1҈τ5,Fyآ~e+ YqN84{<Sg,)|OIs]MBj_Ou~ LpEV):& 8;C:EVA*N)M^7Hz[MF*FEO6z7)Sk1[ ~nHR36C083YYXl:ZֶC]9+~UUJ-*pںw+0',em\(?#mb6D1u*VU:G[A"uCu"Q)<E61z1&'A4uۓ}KQo\F91fng9Du{ pcOmU9Fpe8'./!RTÏ}GuHT\l,2[ _rv6-jh'Uo11rMFŽwmXoH? nDUg)F|>9 =L@1B0FGX]Vkܲ#JCi)FXj%ƿ!V9Qк,leD MAF+Ѡ07A yȷڹ;h9ÍscKY>4pr^VQZmI^ ~'1Ex=m6ǻ*|ƆR-aF'ԟOkfLiBC}A BAV10PQ Dl["oK(؜FTG8Ha1Ю9MgRa7@9(\3illCݺH^X*n?Syd)g>BÉK_b(9N,tblRe;K=츔rFc}p;C}׷xv˧ԥ{̌:Oo_xqѣϞxɫۧz7>||}Oo}٫^>ܷwoqӟW瑎śt U??xt~?}sգo_Wׯ?]?}Ƨ忺Q.ݣe)˻D ç!QWsv9U@,&`s,>~O2$ 'v!,P}[_jU}4\ӽ3&WG݂`Sӄ}fP5o$f2 +!*[dVi@4+14!{uWzYe[izF1$[_ sl#>f 'x2z_lp]5H Kbcf*+?鸾)m!?KgR׎bMl#Vz|$<.$N PzU\:%Tn.֣r=ͯ/s]=nr$Ej5`acAtV94/%?pWg pB-qϐ|8:AH]p9Z'&BB$>#$fjңN,6Yr$""7*|2w2IOT$nncqjW}@_ήs:O:F-4'1SUǮzjE[|i}}4DznNdՇ=HѢEW`;Ϝx`-OҭSf)݆z( 2pW0iBY7!PnupX1+D%vY%0&R|<8#^lbWl*&,f{XG=U3ަ_[ٰKnJ^~ҺJ!)}ZӮ7)^+sM=#Af}}Kj H*B{#X9lgo-H#\qNtNMd$)DBPdLWdj/dqLjPV] kDiBOy(h.ߨ Gp:ӻ"}UiN]#w.E|@ɯ='rE{?\) PT'Jp%W* :`-G_ `Ny]cPUN;ɢ"){a,Mճ8t~Aǩ۽nT9K3:ԡ"0z3( ՟ٮz`QKY7 `r]4Msn!z-ipYuX&nķ5MX" ;L1%ԤaoqʦUKKA5Hvu[Z<ҺJ#Oܰ#fp].&Ke3P6`ߩVr<9XK41)+A 0q2Y,Un@+K SO/Y&%@Ns@4Ч)s1(of (=q-6CE#ljKwr*Q{pQP^ͧk2R1=өC=8"6't񱭏GTm( Z+8b0P̽4uh{ D%֜T"PH-@RJqjGv)nڡbKb_KØܷ_i#s/7a\TX ki D,9 iAM$k+NaSɊl$hO넞.q< \KDZ)>YHЪpR1/Fz {'F,H2~ɧ(VE1 y4 S2`VpI^Zq`/WY>5OztUGfqgO߼h@RUK w,Zz,EnDI6& iԾVXbTqzyXFO B:f0p[tEìu;5ss# o"*XDܞȦĤ#̝q$Q%~C<T!  gBE|vCh-*Qm~r4hw"D(O(F]T"md5Vy%V"h 5%f - 16H3#Rqs0(u96p4P;VwW>؞k F:T[NLLйVDb0Sޥ`ߛA8JT#vVK{6VCXdkٺ>>Uo,\Ro8ܐ=nne7V6xz3>EJFcLqvf{M81֝b+XL&,Z#sx(5u &)1SYgaM"g87v JkIzi*v95D,>ढ$+N ;Zj5{!yœ3O ??x%T+{'G$֢2|4Ǿ|˃ʜw36Ad=ϾcY!Zty~Ӭ7Jl{%[Iyh7ksH*< P5 !WYqHrR[.Jj.s8$y@}14dߣ,_kN آ9(h5Zh&nY0 k5oܱDKh.&ʲ #qt˰e? xzj[c0<}!hJ}K?`iQ?ɬ[eD%c4!aC0fDMDA_O32Vg}`*kJX1C stޓ߽+pN(m` *:oGURw04f=D% l^V;LağWmi5@4Ip}آgWn}WRpmYb-سxU 'jH,ۢrvƕ*McVRy BAE{qYO2BZ%+Sey[ BGQ2>@v*e'Bj$J/Е 4 7^(Z˰*b_rhᣌٜuk`ҿ4@Ix5~˚5TK锏%Q"U5o`eL$:IPC8:w\B}Vσ gRkn@CP ]Dų\^NjMk8]Ge>y*$Jix`C[37t༡y-*؉uP> VA@466x"%e#M՛>=֭&`ȱ} yys蜲c0P a ۂW5Jt\7Ma#S䚄UT0ދyrK4t-5}#τ-}D+Lŕ>#X\gĚC8c"[袼XL怢G(p;G 6A@l\)m<H^^agpiֵ~Ǹ:}*1{jD@ *iah%}Cj~~j3WWU܇F] eĮ.I3h̨U⇂:l1 xslz6 s1E'Gpe2Mt#{T7# ('G,sH%B2RHkO J)^!Bgb-_~%k푑PjO$-EZXff׹hY6i7;OWe܇[ @y}^e N05"TLk3,~s! >>9'YzeStʵ}3~JeU )?cqC`nx&IK QHKJ-B"8mAWV@y{շRYSuUW&kNH"mKS)}7I[/7߾5ϩuHBl^Cpc9 U d 4RoXo qug?ˋaVbg ؽ m^Uꚇ)Qך&IjմR87!mwlb'SA[2yjEϦЕP m( U}\ )yP:xdsuo.߽bSǍ{Ic&X ř)A|VYHbUVZkE 4o?I ,2eB) =\缚5 {b dk!R]MfkȲj}`gOL#^#E}KZˌc_WKgՆڔ)"'{;/__D'.-^u.jQ}:+1ƍXW\w}%k*dDnþoZ5G Z,ö@χM?=՘!ܾvƺx)ңe<fD8_7VKG^: [P=먇!,hdnGݵj# Qn OY]Պ3cbu54s 1/nKLW(- #r&r\K`}KoUΩj(ʩP3"4 &q,rq@bM2K;&[Gɔy2^t읚s!x!PA+0<≙5k]O⃵~ -w 0Bqp54j '/Eg2ΘӨR1j $wBQ`<1qٚg,o5&r9 5a==i@bCpPcP֑ erЗ&i_SBstoOyJ $_: i6MɃj-U-绉ݰO G6]*-z1RcţVe*z$szL`ǹn2kb'2a_KM9`/S(BRQ~vj`OiS>y -mH7G]m&,?^0F8X xe.&~'{ƧGF3J^ЮeW.lbS{<2]?c7ٯݸ#"@22t=y)'pr V &#P )(.3Pr $3+وp$:㨠db5|z1ѕBgOD] ; BH36΂>,UbFK:3=r?<ķJ%= !HqPJ+KHu,'AyESQ 9XT(C/|gZ#$(rs5ɤX@ MIC~+2\M{E]$ KB).1%Oe7vqRĮhH0uS9g3ƶ&nSA99os)kv=0t ɤc'v)-uiNB$ cYA%7PΚV3RD÷$Xcʋ!&0JZO"&R@Oq pL U>:'z z@LcezKs,8d&,Yb\.I=2īM@\#1}dch $V8F!M= ,$޳mgS*-f۳{D" MZAsᔉyvELbib,Mf"QxE^b e֒V$b,)-\̲lY^K.o;0I+W`β(レ'N%ֈ#Cj2'RӲr*Z{$:0PMEʖPDސ9P'4D_S& h"P@-%sQqQD%{)4/?Y>EiF%8yk̈́@ 6MC*YH_gR BGRKt&(XN f'VQENtŘǒӪ{W޿#% 0C(~PÎ_Evjش~Ϟ%^.~Σ_kuOWmOׯ/E_?s^oޜm_px-*G|Ca?[hUy9ʐjdO' r*stJVsծ*âPJ9@8طOf}|}svq-mDEv;Ɂe,TہK2&ڌ-C, r3|d<6=ub#6͏PIt|"&,F FDx|;3~SyRHf~'8~YsҭeݪjOcxxKl=IU}Vn>j),}؎Bb|HGj_A#$h4V`;\ofi _i@IRh=+ ZƜ,I?EUSW'zoAV;gdW$Ũ6jSQq=TjŤ[v9Nnr2/9Y X#V@@ 8eDVL#[~[w^=:wAzN??:<:ݲ?^o˯1=gwwWyw}sϏOZ~y|}}5ٞtKp׷7kR3f>:rRnnžGi"8/:sb"vei"u"x%ݲm^' J䚤IIĭu۱;cI5u}g( cQ*Ցki#ЄEt:fH1twTXeZ\ G&>9y"~<_ݯ0qU9L$L̼M?S7[izR3'?d\:'sONx1V{j+u-`Y-eymT| ǘQ82l>R;ЮfL}{=]yE-;g~bgK14Kgk^{>c;Ś]&l[r|/+UBd2KV8M >g19i.kr˗s=PD$"foJ6UGvxhl URowwi|Ó )恴F+tS場ޮo!d'|uT`"鼼*K Lw{űqzN;W7Q-;6ؚMhyرF7nc'xfx7Î}ΊWo7r&^6<[sƋ#v\͍aP8xd|2GFdUY"h ^w_np+`/вANљ;G M'2YwL*&hݎvJwᇘ3' :Q݊I1|11ҡ͸Jeh@&-״m3o}f!Wk?2w6H曼I&gf`nLѨGiGUv$[VGW0zwq 2T`]~ײYE:z)L6O"ikejP>h6%QF6%{5aDmO>`% :۠G 1U |uV1dq+WUhȕkCzuU>v m=GQ%3Tv lt I[t~%{QfV?dɛ.+wRO٧5O|-ugw%דi` =PI:G|G{71Ƅ#B?wD\o8dô34\tw %: ]z n+ShO ZWaYLFW9d4C:܂r{LR;,} 䓾$T~`}[zU0bo$PpѺd mV$/,i g HRm1MчV-P97'+f}}/'dsX oaMXU/H ဆJd?UA@8]?ߋ_?;fzL1&MhTkTbXtX%bѠZX~pY}9*WڨKGB@uPF + V,MX%]s_T9I\Xڛoʹ?QIli؟/6&Z`Tm'w^`K>0 ~ Э  +FB8逫cP9(4*Fz Lh/p5S)7a }2~V(mQwjFKK:|+(1b}HE? I*ryL*E)z!#JbWM S ?N(8U:k\Э7'99dD&7 ^SPn?4m|/l^OgX!֞nwp ~NĶ byF]j|4 8&{-:yVsɣۦ~{oiŢd;¿ J3$- Ʋ_4T"lVڊ,j{+ J1ScAV.Xv}4ɳB2, UXa٧$'D3de<:1d#[\ȩ73=3;\uYv"# ok5N_B'trrH676+>j[M>̙_"tNs-ɸ=F˪GI^? aP""i8K^gGj@.^y(]51+^-)bjN`v4h  P- \mK &?@]!aT1`U=?> endstream endobj 26 0 obj <>stream H˪`.l]l(Bș$ ?% |/xKya' S+552TAmJX d_Zl ;b,#ɱWQM@Q˾qc]az8?\h=}Y'diN;!AP6/*!bhk"[k'S{bS8F IL v JsDd73Xb#v!5|+UWZ uVy+^1'WxE)RU}6|P2H@l[7O X?Pg. nyԄ !3 ӏgTԊ[̡R i Bpb[!mͱ}15'YߘeN-Q1 ܘ|I}x_!{ۓJ iǡ!_> YjyƂkunmʼ{>C LZL_gT|O]OI_}?^O׷;~;kX}W,̯f@ZB k~С+Nt?PU2m1׹hzDy+o\E$pmF4LCMFNO_hg N/fBllw`%L& i*j=h:,/+.fgNfpf(`;WޜdϮ[ge#u*uO;gBfy:Ekt].c0u2P吞-%?͋/XEĄ~MQ~M!\Wi!ZFl?⹻jMT$կ)w)WyhtLY9&|k{u+֯)\/递_ 㭾ХnFYj03X[VhQn<xulB/:M`8_?9\ߊrr.Z#0Y *~ jkyEX\!d?;6El6+`Zo։ rFW"SXQ䲡ױ=hNt^\]/Z(d^SW,P;BN25,PQ>%GWՊWѳWhɵYG%>wz0P@7W&%—l~.fϯ>ӎn{sEkI8 <[Ka(2{N65ajKSWSk_9Nnfg,,t]1chEY"F'4;tJ2x˖aNu` W0sLG4/Vg mgL׽J@9OZ1cm8GeǨγZa6I J+C7C:#`WSK)PV+iǁQG/G+rF=zuvNb6UH*ee2E|W+5 'td(('u\kP۽bk)`3z-\/,n7uKH1 |²p/ھam砧f\Y!|lM ?hd3aeM"D%jn^#=Ϻ~ΣdWڔ}O1?xo?zo'??}J_4+vg#2RbGT}*Ⱦk2&`Ⱊ=hNƌEFy;IZ?؛&FέlTI;6p NĤidGmhS 2a#*Ơ1G>*cZKhMv+\˜1^Z-;*VU]ŕcHm@VюƠkrsޝ& (u +ħB"wh4G5Hsde;ڐ Ʌր#Ahv4TI[$Jݖ c5ީK\Iؖ)!;dG=zJn*9b`;(j4 wC,e"h.u-7W8 `o䅦֩!]ѵraݝ RݏL!cQ4Q2R [qa1㢖 t@LsjrgLNPBVw/UZ*>e}+9b $v!2"\ ߩBL U|RWVDڋ@0iNckb!cG\ȧ ZNS-~tAY1PKJ뱉;lZa2-c#R>ݺ.TZ/Q[v4afiʴ UJm 9-k9c6tC+{e6.7 0u*QkoŲTӂT)<97+ȝ/ rhȺRRJtxf7S )l :gŝ:ʓ\({i=R!gJ(ڶ,U鴷8y盵6 >w`upi=Akeᑪgc-ܢCi uoRJ'hc3l&xG%6TYzExY#%_C]\]EX#%I7M3%̚t.=|k<pk`tifcHxT +VSOfhyq0]HaGm3IJ% dB N6GIWF9u6:}GӒ6 z|#\pˁJ:I49uV |80G]W'ok[3Xz~ŹfÜ | J W27!/ Ɩs jSWECO*㺗`uVPYY>.9PrQ#9%z6l8o`2= U|¬ׁR(ˈ`l*2A ۣ)C aǽqg3"ud@`!LP7+٣Yプ^i' _M=\:9 ^|(/o?/ۧF-ߤM^nîdf#2&PP40lL?B:@eH wPVy>NT?Vj;PUMLl%%l7~n5,<c^b81:jrW<`rv:?;Ncrqm, ? 6#c}b/ظA⯢X XK)~"΢q`n+!X#j>}5ݱ06ư_-P6s[uWBeZr4Pv3{Ӈv# ZDphh`nl1-ٳ\cq+B 6/;]C}xU{co)6(ڮ4٣WVJRg>+CBw ,( gW|7T㗵DPgEqgq'_E(Q%~ 刞_h}ޢܻsޖ뿚',O_gjۑ㸡_0/ Ӫ >?2}ZB]l`'7oשW*ѡ"ڝPъLhB?P-|TK̴b>31Ӑ+}ng* ن~-3& *ِ>3>  >3hYb@^Rf e\ph)T( h %$B}-pk @TTuCk6@Dp 2PjAH.\UrћV3|ԶqxLQcKJb K~qV "Ъ ǁ(! eb)Pӈg03d=JHKmH?{H| ]nHG;(T`O6j h `$^`BA J!69r.!LCXxpšWRh#Cո(㺒4+gw"X%5jf;V]"`.E0AG/hb_'gG B(NmJ?qy.@RE9=E7*6% Dڷ$$M*sH ";{- ʀNG) (ڦrA @$p|4GD^ )UQ Z:S.|Z ␰ O* Q"iR2)^MkOu ç^&8:HӐyAƶdrf\ph邠͍qj ٵĩCC+ڨՙ`Bɣu9L$" ǁvHԭ*T1\˶QM/-KýjԄh3\3L' :-&6dN%Mg<6iro9(U n\.A,"l!.6@%V8FG~4|N1Qk4, T!mKb_@#Nt7/9XD[u(}7Do%erIb͞"p'o]s\K4FiaKRMM* V44lUAᚭ<`V+':i rk u#.;`w7^H#(x1~BBph;q@,FJ.|;HF鸙Wn5dMߜȞ `pю>۸("dBmiuD 3ij砪x6 f' `-qy927~KYSDNS D/:t"qV:3MS%,rV A E8J_US 5i*HdwYGtJRڳ2- ujT;P)JCL^9gYJPn-b3'e2+hquKVE ÂUN @WXUZL+Jhz3 K?RINyR6'\9:׌(;kБwGBVoTWCPVFlq"/ JT+G!?DVlR<~`9]i{|Ī*%QG-vaP:sgiuj6;ځPɀqD"HߖL(d[yZz|DKh(gc'?tel\KDH_9%*:UvfYC_;;Kx rǮS/%=U8HRޫmӒeJ7UZwcזR&m*vTu#̍fXrquO;Vf$/3ێ #w>Ҥ\Sg /J8}F@[jz/)jzn +o<ϱˊV j+ۍG/vkA,XY?9N?9rteZѡycgJzAu6#c:K5OA<4tU*2tP[jM32}XU\B! #yR-N(NFKYPN%@y@Y E_fa+I97 L`Y&cKÎ^'5jap,/:N'"H1 #Ph#F^AYaJSF1Ow`{DE]Ci zI<A f++EĈv\8ի- {aa$[(-R?Tj~vl*}>TJSכ| O??1`}+&gN͗c磻T.zIr+wiO!GXbY{r5C]V{,Q7j.(D(h4"HXnTNƎ RO;h<3Еk8Z(UP6]+:Fo57K_VlyĐ׎'7P2hQMV*Zl. H=SqqX=,nNUP3RE%;2UC T%rqOvh2N|ߔT ~(<__ 7aubDzEG% \Ia0a4Ș{] ,M!0B#ATk-VєQrϭ^][.+ߟb\r\CK`<Å(.`,l "E4Yhg(*:-iOn>kNI[!)':**ӷ.Q݇KWCZ HM/+dqFf3s?J]r~i<ٕ~ꅤ:Ht˕ULeŕ#i8[jvH }Mc>,en7.9 >APd`,2qyXG;J0=Jm0!MmVt%/p auAUF*kt2"S< f~:Fp[ni)tus킛ou3/4|:OW #2f@$OVb''Q-vfE80UC|c AZ0SnB,ACK+'l矰#32-T<¿g;k#Ǎ4|Y|$asS;ԽANg̙z]lʨ3vXZQ5*#bLAo0qr`oG imKoxu8WuH!0#{gouS?RDO⳯LD!m:vԋwE rحFc,0Yd&U s3'X)'ևG02މg2}lPh H_]Z!5f n W/n{]T4neZq~QH!ȈVCPo~Gׇ"&wLՉ@f}eJ( 95R: {Џ|-`)K>[ik˸ (uR u|PUi=џ~ WX{*owIM4F _A rۉPwNqE*VPKӳVvlSRh3ݲZӯf]y?u9q\ ??[621_!lL&[[[x12%$siI62$1dE.XnEk;rt 4*(USrJ 9ǘ `6iT*,V#q*ke|zM (>P4+G&d-`%&4$Db@[!ilaB:dԍ`BRjr]-a{9Pj,,PȎL% m9tn-nՔL;Ԙ QIU 5E,bI:# TW50IIfM@ Xº ԏd"V wwCB?VKԥ.=Y1$KA#^CL)6A\NȜY >oivJQK:71#CNd/պDYPp"^cCHPPPi& j}=9csK2*0u,I&pp\|scm_>囦~# X*6 )GR^y/{cNω%/!*L!uQ]RyaRqC|RnNW*qg0MRȟ 3Z/^rԎGJE,j^LD0.RB K (=K&9WІCJɜ"Hڃt1u a:02/uQyI'e|fIlplpR2M!`@c K32d|0uٌ+ \z&Øx>%NǐЫd,;pzU }A4I9<[FИfz z O ;/ҭLuD\MG*rJd2>PKXa=Cv?zR,;''+Ҟ@. @r= |3L9ᘆ-ٰ܅]RmAS7:e4\rQgeqa§Q&+h| D@z" l)T fܣa&r3>993j #:Toɫ&zӁ@X6DZy# wYpC? "Rتif<]c#Pz_+6eH^QTGqߡ N*s&&a-BI-Ch%jJٲ_߮],Q}bCE\N{q5P^oE,GǢ:w+֨1i~e6[vdc'B*gL<:tw<ѩH'f'ŵק,\un̜ƨ|sc1hWb znijZRݏ:0g%>f[?_!ܲV0U\:xu1ٯ/ 4,j~W&)$U$ӞV%Vi^],\u_ݼ).FܣcwE~c'ru%=ֿڽ~I5q G5t,zS1(DK8Š*hv} 3;`'GӣD:8cNiE ӫ q {xLS<%,̼7Ӡ+(f.SPm/b#::^kUb?P ٫7I4|P]@VLL%37ߦضg lz mOp>!W`A z&.n- ?vwNQ%tJenؽ}~5;Cg"'V{FW=ԁ ):' n+ʹ 137jc M_:2bG# 16+C㑒L]C%\ hZ0'NeUx L3?o~$:!W>XSLV\§EFx͛bW9Dc:3&h t awū &!d1(b9q= ac0-.X 4kVn91j_)ַ]pxwҧp7 uw@Pnr/ag4 @]"&yHWNF U 6 슮lD-Eh De_Nj=8RfiAxs3;:1Qi8cB\( "\)x >/-?\ìLn; yX؊FEIN*Hz3Wys{!9 $X3 N`5oz@p,`m.՝X ?E$Ho(P7,v,]I^cZOťT$GT ,M4  Y"(nwᏻ}ԃeUk'UQ>)t8IBP>WH Ul( _:/AОm^R4GjAqC9-27kҺ=,qw%CժP,mbgU(8DDSpbوI8WJf GlqTp*mQ!>stream HWYvH^AP9cm0L:aq!̅T@RJ^C?oKB$'O?ֽߝzvm|9D[&vP\r:K`y/*e&w05L8a!88xAJSC]DSNh4WƼ6_f%es4/c/"*J+Y\y9 hDaDH9\#M昺ο hx_Cu,Ek:Ӝ)1Er_ +m@ܑN/r(\$7ԦjPX[m1t-W.bҽ%=b`UvMj%W>z kjʾ @ya S'mmkV*e3oS9b_{J%MG1f93PL=b篙dKĽ,c{M`7:J 0!#;gq-W3ɪPlrl swq4pW#05ZHcS l?g_SzbRM],N-C+Cj\7p50GF:pO8 6jb\wLc\+'ŝ`/ Ho,Yd@+EǑNeTUWuQҟáM|q >\8Z4l\ke,7wԨd "S>h◾DI'qOC:,z M D͌ҷ&MHoXăiZVPN uzb6 k?jJEd; 5o?U94~ #5F0f/BZ V 5B@bE! s]%Cbϙ,2jpn>)ΪKAj@}" u9r+f9vJd'8Lv_le5N% 2y1|S##I;W;R&7|暫X\1G,^6Lly5d:>w6[Aɫ:wjx^PJBVzsюe?6<:nD-+M7G `7OS>ӘxUei7cن:, *[7o>|l\7F>Տ&O;?Vw6։>|?VFxw0lEk\}̅ USՏ^ozz<ӋԎyվ75γo[ڱV~56^l7/vn[o-lm|ix"?awYV Lo7s|?չmLdfۀ9Q@g=qUWp>>UXEjy0t)?zT$Mę\ihςDyr-A|R ,]t/YWG 0|rqtl{OF!0G]0$}C'N=5"A]%9ͺU'޻@-$G>޿E3إ21EU*x1Z {an'-W݋t^cPO?J00eޅ.4Ɂ cdݾq]ZEDH6V5sUWݥT9ދ\vt`_*r`N̵H:ߋC(4W_@NJX  "WFɺ'Gk+ *ܣڰUe 6<:B 6St]_z%D6œȬTdB7xPC4$ ,dXL̐A? ۰!(F~")@˸w?ʆP%:,S%bQ _OpD!>fj2 =e(xL20I]͕-4b~3CFH7 5G)ȞS%cɁTU ©"чrkFnn"Z17~ <ZRЗpBj܋v_lgfm̍ fӦ/}$ hI?X7r:#- bm0\C9 q(OLaϰqV|Ff@V|B%+M[?kM򥡅(gr {x`k *-7sZAiXXlCڔ(BZ @-7Jlk,#90EuR&U?"B$o֣1̶g1!m[JZdf$ 2FY|:xiudM;vB ]ړZpt$n'ѢnIa DsKyWrY1, \~ԣNςp>]Ap{vy⁛<}:75Ov?hk>]蒻ǠmkWAD3NwQ ˹spЗqDb6-6 N=Gi!9_`/r ۻbS4:_MݭbQ,`m.*rv-@yf[=}LOb}XR*4v<.`Jo9@&4/Xl\}^*ۺ&ǏCݐ&nK8nz 3 Lw"9T d~nF^>}głX`?wCo]LmU&zOi(BOeq;^#!UrYX,YdIM(:#m+'1'n"AZ?ΧG҂&;*Qȩ~_ @ꀳ)0?TWձϹFyv::N?f֝+E]ӌJ\P.\|1jT8Ӭ'a?%zD~N^] .̣.֔u%$tS"]hв]Z^+"^֜`r?7 6mXdYV}UкѓZy.L~YdYʹ :xr1q/8aq@l`r+1T# tgq5';uO Y*poàݧzu}^ J5IQe*1MR>e!ejv.pWulu_BB_] &fPƪb tX~ll]0^e۩I y3Ԩ1*j4Q"(ÿVE?{so j{Tɷp$|7{Q+yэu#@bQd7W%~]܁ ψޡDyI\?X=Z_¯fn)~$]i3(| +_WoAEd_V~P+4 c>qУ!ng# Y§t!{}\:g|elԨ_ Oh2vrCg"R/Pɱ,o gA^SBJU;m\G^;jKyΤ=r=e},u74KL18Y%ab2;)$Yک!x1ŕm/z7*Y} \T}E)/l\ֶ‰iX tMk{1;l̴XBh}^<xTmn~DV`>w1S[]1TRM4C6( Չ>L.7]E e%nxiwk]OxC!Y&$%\jG;h 42J,NOġWl?#h: ( Pc&0*{-mmL-tr/)Dꭊoj3/^}+Ģ;1dAbdp3j=i(nq61+ T0b#żN@5v澤,Όk{R=ܻxAtHiR(l}p/R@dwJio\JZ{9PzVi8hJt~ !Tcj;Ħ^͋}\4:bP H<⍳] k__`X|Ά;XS*؄Rf+ C啠]"s8,.8B Bn ^pX_'83*0VfJ{lׁUESiU2*&וMxFP~.wWssG"xdYMH}/eG&h"R)>0AF0鈎*n$"V?Ff "4xK`3*1- DnM/.ΐZ97ɇḪo߻xS5h]SK8'~}q %'w}tMY\fnl 4O*Eƛgthr= %rJؤ &wE{_r 32|oϛ+omjGF$oQA:&2 aw%H (" 'k8EfSXvhh_MyZѺT-:ζDFSdW:أuEv_K8ˮ$ 6 N2-5:Hɰ۩mVcWQc{[0^u vPN:&eEӲgӌᮄ{qAGDUu]2׋h y^_l;(;-dn,!ajy<15̕=o|ɲbE te6~(Ё֩y=wx"F˦ރ;TLDZ1AGBAw:p߈u6ر9R ο^$(It+7fskry/4SW\}h{h멁t)* ӡq,'g~]| $$M)ڥU7Ƣt>M,% TȸLW͐8-:0D%49P+VSMgJX34PY`~ 00SDY F[s]T {ے6 apr9I&Nen)hl5`&Y~uH~fz'W\0V&j,D,­sKpSLAe\;IF]j>sZWFW%ghxYsKbd8Ieƹw1TW:0f^!@뢾*h޿zn"cyNJˤkHeSFSF=uaBIck.q,ևbf>9`Zojhm۠UD֣L'ptwD-zL:\3o$"nL4Hz)c*"IYQ$Cf`\̡A2]ORhLW4\7:N6fLokqkl~4kG8S1SsJ$b{[T6f_m9tuU./y?rf*FLHqn C x#w9[3[BPƈ42cCygUWt+|牑0&vݿi6s "mLeCqڑPi'S"uPH^<di+|]p ;\M.z7N D7Q +o8Q{_b6v1 &ZUN:_r.˼f瑯}N-D7_>ֻZ+^7RQ&P7ͅ YdXY:n 1LhX;~- oi'4p7\鵽nE<<Խ')-y`mDܛ ]f|ˋjz5w4A\Fmz>|RK\ R} ql9ˀbWD>7>[Z]ijte$+okO}xE--W@~x ш˶@wmrna9u l|.&.Y\ǸbR=OZa*cZn8B3_1[6:ƣX/}ԢA5(SA=~m\>d'/"iӠxUϽ_4([cKq8;@lmP~ZzTS mAb`>jӡE[ 9OF\RNT Ǘ{z [ (TӸ Od-|i Ell?CϽABt[2w0MςeT߂J|eT'hӠl\d/[SO th⤅fTh!5('otfBߵ ӫFg;ϊTBs>ЧϑRnkz*5<9B Z5r̎}ϰW 0:|:B=~S[WUCkIb|Yq2qJP4ܑ^JHްށv.?@/Zen3UUvqJYj$_,;ow߼?q;m_Ķ'c/q坦էi:{8W4B֏8~֛Z!Th9;LqXOAbGO_g{%)t+P<-ū9b> 1}!j;76R-cg5\z0Ax!iv A-N1˭0TNS)dS<ȩLj\nN 5Őr t޺@&jGu|~>CCb*23Bo[_訄bXX]3eZEAd6uNj4qmE [pÃj&v$++ 0-^MګtZߠl>F=L1C;mq˃ `ZC/m t ݾc;PE 0BBPyߒXAY/Am)EeZAqᐯ+AG3pkId+k:v&?c1w1K%|>)@D=+ˮ+3TY<;UxD^e mQO?:'XsL1m`̄2A= J6vʭx]E 2+=t%mX]zcԌ)V_[`n>1>YYS̮۟Jrz=!A3"ɮJ=Hiu.,֬̐?U'aVVƆ4d4uͷEw~4{}õ^3jRS.ԹI}3Ԍ ? cB +V8I^Y*{%BR߰++,Vz@V=|~ѽhF~+4c ܮOqE(ӴV%$^OxҊGDMnHաOv遣ܟ7I'ܟ:v(Sll'c@-Ip/؛!nw2Cb4oIר4UZ\Bi:D_>2%h FB,}fjC]YCGs sI6Dڇa+%0.,psa/P@;  S &.mOooKP#j[Rm3|I1/L6L. JZq%5 >x 2t j؇6l ^1\R@jO"(cK+8U-[\B+0)DQ imIKA@=|{oa ,-Y{ T@{kq, YC n>sMrЏX<-Ї 5ϚÞT2ՃDuXAz8HMS԰޷%d{tbD}mmIT(oU$V<5;n[BLڐ pgښdt`!X@.`T0*t^"lA%vʹVN;&uRJOhc<"J\ yK CX:5cW:3m{. A˨tP;} nO;K] 5蘰AXj9\жŔ|+"-)w]*waEN;,:0cB @doƼ7Ui4!NvUxk@90`'h%ʵ⓽؉ DÚ{S;x </֝/:gVt%یZ0em(0n`\Bd):(?7fN1R+`u9 S~vd48_;?hhUр1AF.47AYN{>S>>g+p{44ylҫs.,Ԑ$>),t⣅5fQbPsH zE`Yz]А2uI'{.W;.(cZ'|1*yo م $Vь*׊OI'IN>2oC1}‘A౑񽷾EzG6>cq=k"/iy,S?)67d;"=Z4ŀS4cBUrrGN arMq&~>;SGiu ̱,gww\S5y9WkqzKC_MNFN/d|WR0h+}k[buop/6Q钻XG-)|_@ߪmcF)X\tlC5|\p^٫m,v (ipBZG.Ϋӓ4/ˎ6T}OAE8hRێ.prsC! ègwc">pĭmpcHsU\kR3oXs׋a^X_6Z̋(GkM2gԫBW1nj袵XiHmKwú:P2^U@YT\-jJJS'24? -0?CDz@Sʔ`ǹ%"bN6Ay!D&k\c?r's/9/q>Ɖ*M,q `ʹCzv51C`jmBL@u,'^fsc~Jx-P?m'М$ԭ8Xb(͕Ҡ&AM*Hi=u.Zо'ǹ w"UNyM mcuV7MrʝeXX~?l:DmpSҲ uۣ0 |c+>1eMwV:o cU ?et;ڙghU4&Ǥ_ݙ_\ITJo(W ] qXsp;\8D&TPHHUtd9Z]R:2z[NPE^t*}(/c+={P1q 0To*F'OV՟$$F7XLpUH U\ϧkKᶃ;^Jo:WuƯ7 N·Ѱ(ĎV [3#5n45rf2K(+N5'oNyV L)G`!9-I`\`8a'siX7Ig]|*bIea36LF-C#_q$Q-u hibiKGzjJ'd5Jm 5(m`XHL7It^SӋ%1VE##xI":һjؗh)Ҭcǝ#D'mJN1wv;(F)+-ķ>e'qLTF1.u1)1Glb~ч=93 >A̰p#V G.""&Š?[q&-}ΙlGVd$)kK v$3;o{ʀ޽'&\շM NN2OSV`vI7(X)C: ~%Nŕ<,xcXcXƐB 6cy,Ѷ} 1єcދ۩q ou1_cإbr;1'푱 7ʩ_ Z,`19෗Ȩ&W3le tM:} W,s4]A`v96m<]|{w]|;ml0,w+M`T # -&ߎYQKqU|Yv }5&zc p~==vCY/QO@5JRP+I)+qclH͕5xy+iLF{Ecr8OtWу'+`^2svmV yR6`V;fV.uj/[&ݛ~t6Cn?_H&},?T $E Ov:<\v$ t 83^}{Ý/Bl9=F]/\5Q(/ YN5?qs]o|:Nfw% #pƜߜu0/&Ja9tpo|J:-| iⱁ_y `}yNGL .Wo!G ttv#`2mؚ߫*$ e慪>ЄޗӀf8193Q_0BU}'`'Ъ8@3ᥪmcN aX='UB:[6(%짨]ÅUM'on+Kᆤlڑv`ҁGn =xL`[dq~*6kd㜔嗒͋2tETPymJA¶3CzN͠ީ}[36#SMp^xwcih:Ww>P2Zk$2zF*t㦖-N&6O úJxTS1e^,oiKZ:z&uS^`!g;O=(\2%2a!a7 928 PDAUNFaP^*tܸ edYfO"cFr$)%bĥj5Sd(MR!05~P^zE7Pq3=^[R j?mFӷYuZEKH Fju JHg)%'G{8t U?\ÀɃ5C7E^ qi1f~لj7I#4[pΨ&jvm|zԷ'a`or{f;12oM)} flJi]Na]6d׫ϕ`%f!VL>&'vRh1AjK5Qc0q/dz߰3sΙ5P2ۙ 5h?U'1"xGQ-d.) %)B$>A5/Q `ْ:U-ip$.=_ا=/J <>]jԘ.&VF8NU\ep\U*FeH0m%YaGYA۝5~鞴E ]q܂>stream HW^<}>K[ 8 XQaq`I'3?ss﹅پN @9zU&|+vFT2d6=go j?fCZ6:-߶Jb[o˩\??2ߧGj=VGO: MJUX ˝|WThi+*ji!gW#|Nme'^L]*_b͙rasfN}o kӉo#Blނ m065cboŕV@BXːoq<"+^h _QP*lw|icfMeW^H>Xξ P87 _ʉG?(Eٷix2^2Μ8!fNo(GMB393d!|lk]Aq7n*ɺ^-1Hx ceOZً>Vыx0 œc& v0] 'Ϛq'hNJjA+` 2]s1[N 4V_2fSgk{GEJ '^ tLamP/n ٮqB^x4Hho1> OiH6{Z*v\J1. ;4U0{KBK)å!>8ѐBQiq(R(~K{ sP%7:f 2'ƜaGJ#x r˜O/(4(eBLKede'tXveXpwR#EQ-p:A3Ϳ"'?NfA9OC}6elWno``5eKBa  gmӐ a bqSمԸ[ 7( {z[ȿTU_?FU6+T!7ͯ+xoKޕ-|+I6vac^WϠ0|ba.u_>yF](܍\N;!ScAR`.fyl o\q0ı* EֲG<,ch%Pɲփ+ G=W2Rs@mrsE KJ D*vQ/p#Zޖ+C] etgDruRMF͓=<~.A {=u``A h42& 2-j=f{\M]%z [H3xF_p0fg3i!_l*E݉GFAzfXsB{7h2DWYQ3>pi /t]pΟܚX'?;Q}~b_Govkb~ANȻ:-m ?E=ȓ1 Zxj ΂Tj7Wu{8J =n; ye\qSKPlawa=P AZtgjCHB)ٷ+vUhsPB.uOQJH'8On/[Mb C]|Py ".YT9%}` qǾPZqwVrZʏ*tQ OkOg,cէN0=-+*3ѸyC; I:U:Uy;ܨ4+*6U@)9'*lhTW"ЊUJr+%+- c^-Utr̄s803J/\n /qj+r2Ajp |׺$04g,x^K:;x MɈ撙{,Nn !$s@~F8L}1]mŮ|-5ӊ*1\8Y2bi.uJB.(0=vOBQ.mݭ;wMd(ؽ,(ƑB}y04 M߭MƌaX}MIgȉgϟـqafևj_r\u/\%508B4 Rnq籛!;co]TŃYB=X8My90Aկfg&ZhEi-Ro(>Hhά<~L1KW'K I]dR=#%WUSPTDeEb\JT\;2 ɥ`NsF`=yf<7O%$OsL6Oamɸ*@e+'.a:՛o!TE.ˮyKh R.l=m=[WnѨc'.$\oIMrc64k07C& xdj ȡ=j?N1 o\BST*8Qhو04>|Z#.+*] jN7by:z JkZbV;&K +v9f,`R'} 1'd߹7;eL 5#c]\IEu N(Dj6 nߡS[/ j>^Mb V8v!$!Wb';ģ_vx"u%:g> 躷uĮܞwS)P+?>[9m9uIN`{ يXQ8󛖒8q o C L`kKFJh{ѷK @1Rx/afm.dZ|InWB`}ןxukXA sji:IBԿΕ4^|%j< <2C=>tF ZNB0N>;R o电v EF=1>R-{T . ח$wll\+`7`0VXuAP2 PަEVV[n/D2$o[Cm;/_{16> 4z']P}8 ^DS d93HˠWu*ݸMǛӾ/"$oVe?Ƽn5LTBqP,[Iڀ٣ ӏOD9? La{6,d(͡OU1< vt>TZݦK O eJ|̃ /_X/^)y/w&e\ x9bADʜR&?HsU$(a2 kGJ| g Ш]VDv&LUi>k]OmE-X~}a0}fi';ȑz`DߞtD,0{byfͬq`%}Jc'AD/p3 #nYf{Ŝ rGw2jYCcW,soqJt!h,Цn롋2eԾ037}5n 녌7ia ZiƋ"-S7y¥PqenfN矟 UWr c'^zVf/EW^zah9yXKD,=Tٴ`5Ϩ RQLjPqtNcgk. gfy}y9"$ЈH|{/ { 1sccCA WK|xumif=Єcw, Q^*Ҩ(Y,3K"pd b QV9%b^E+~j /FФ"wP*@2/ ?`Qk4DŸ8#AJB|MR(2VR`S  :( M yNw7O@DMN;TAtyDVIs,,noL"Wx$5 cWmRCq% #Hy2e[X rp,M11bGo-؀l" R_%^ >!f t`tKeH40B 6 b_!h#2[/Rkm̱T bWJ&Ғ}ZVuS242esboqR~:ÿ{Smf )'<9KAྺil:Dvtԑe2ݞ; Y إmA08@5 g;83C"&UvM$ghgq/yBFe0#f3jWc&60(b,rK1#: aZ$&>]cC(0wl\BkDb@lf{ muNS`Qg?BR?]Fi7 m׎ ʄ;9 x0*[)`ۍ- 7?IB:'DL Ղ:._[3%I"A?V۟*fح,ͺvujE |SJO/EDLi+x&02YAxo=F'y7]b7 ͮv8U#8kaQxl9፝I}s$/nĹ <55;lpFvƐٳ;(JvK4bOqR,7uѯǼ̏LcѸh󜇹dkso؎_ x|=E)QnDxy5!bUnii?y!5298>t8bo/f,% o1ы .>-Dk%hy)XT2.W1,e逻Eڛ gt;wq?s#&85REB#^AZ3A M*8# l|l`49RjTb3To$To"IP= N,~0Z.v"aTkK xUSgOgSJ9|Նzq9X هXX <pT" rqV 1:n_(2(ᇚ6p|R~'@jȿ<N }8>TT ]~`HA`">}jDvC9GMO1/)C_gWvĢ$ɡGWWc^ tNvv@+ u\v^=gEfd:]g˞c[q#6!Z#za_sqzd=nDJC'S0+h.a誒9 6h %9@c ~X3#~a7j1F"4YBhRN/흳MER)%zz &>ݵ 9Iv?$%#š1\mz@HlL2*YE=+ҢH.y꼪3FC֣61Ө)a%m wl%|w+ R'>Po3HJ4y_HUnԝyRu @V[Br~vm&j4`1DGeQXP[&ZU9=4##]TӥO w FtѮRN^~V)A-nEHQ %z >cݒ¶볇L<]F{!GPD[;CUʹ=buYWmd qٵ͂yA&yUIM:yODdgFMT (9>J`9Sm YhG+D'Jpv&k9\G$2=޹y9UVxhy-;!=\'͓"lR'W t1'Q UJOZI >-MMrYۓYXFlmmYLan4,u9nYP7RA$<-%nh`^ A;,U .{; O <1Q!rl>X|K9"XO$Q(zk?ܡd+̷bYw(lg'G^+hm ?X:Mt@Y$ 8F\>fʮvrRW)|yć焙sh>`"ZP510pܱ(Ԫ ݨw ſEeB)go.a\BmGlKI.xpD]${ q`܅‰LWG4'eCsN\յC]>J NP 4hd^xsiAF2h}e$͇)b2ѧEz}Ep/ t!% +ToƊj%TψJ%VP(lm/Y!x#߱;ya`lb6*2*z)v%;f=P*?Z5j H\ ˮF4iRAH]:@] &RUtlBih>, M7ޔ`z_D[QxBeL6 bucE՟(`5m @UڴPO{* ?< 4ڢ`*V ]M'繎]Ы]%"84I<`3,糓}K?(Vz2S/3 P -ョf>m)3&|.ȵ䬕5h4H-ă͑djLBj@?pWG lj"(oMDet?Si".zp ’}BuXs(~,HF(Y>t?^[ -\fزd#H6EHӱGy;M G.L&%WLxDɊqYXȈu9?^e7~[Y枨FjQK$)Jȓal{ JT!M_`x628 >@o޷% 41{/|E/. w-Mu Y/gav7.%"0?.!0$bu_3əsbau vSZgh^ *{@:|T(nƹ|)r'c X 9;̺م!$ΟHpC1u&wЁd+*C 70ZJ`d&68x/=XۉPpG mꤛ5Ui,(˩R΢d8Ox[ݾR (+ C6eJ n$a}1 1ILI@ѬRK_MW3 m$+ tSJNHA>Avi|';f d +Xw8Pb\Jv"?М©1@|"w,%3ƕn㻪co0y^xfLhbW~:$QkqK^'R ;;rtpr.|i^ғf˜d%@~.ط.>~1uc' aC0"64qT>s;ՅQu\;\t}'s1 Sbp+`%@T1RjC gU _F9.hLG.`\Lzt)fG6obxѾջhbHBLJv*.1|dYfF]Y<,JXaEs7 ia+'F5ws) d '#ёpx4ȡ_4ach5uBѐ#q O:^yЛak>i<Hyt 'ES vJJEiYDX+ZFf~;L,2HaYX./ehw].> 2ǀTaQp#6Al[\hb}C̶D >NG#1] JyFhb$[v ? [t~IG0 әsy(9sky6geijvG?m@c_.%N?[դ1>4 &^ݏśySElLqhLxut|pO^HG,j*;,>H:2!(H\upMߞF\\Gծ]`~ m,toH.r?`懊+cKr|¶2t~bO7޽-XnD^lE||duPي}?A#8p.M?|[3{SrM-߱yg/2{wgL:uti֭wgNK^}RA7kcoOiY'}NjsEr@~/^n8}~oo~\{kZsp1W?=/]7/?)niP6߃I77o_u\Z<ݝ=k6^ ՞}k\oȃ]C%'ԛ]L< anR/(PoCqCOf3V|氺u/Ý׿bˇau''_>rA9s'0t QX Z k;G'g'cΆÍۧg>o|{㍱=ڛXW:[{m! ~r}<1qwJI>٪qhQKhT ^J_n ,}lUѕLX. w[ro㬆) ͵ ilpw!8˳4"aDIg`U[kq,4Kyb"ED'ো*2"QZ%EaAH@\CVRqZx[ .gOK!YK+,pطo\6 T0+byWHʴ':.$̆KrN6WCx`lr w 5;! 7GZMޜDn _2\n)K-4H_QLҳ[KNGRT9v2vԆ<3:C%,Bl0\Lߊ#Z2>vC%c \LbHI` V8"¡0E-@1]HDIYN⒄`Xjc0CHP X*<}mX)f,S7)A ҜO.IEbUW \I&⦁)cU |(Ie JKF( X'h(5 G)h7 tl4{HxͶPP!$JlxlI3'H NjKBBp7KPxm{$(3%Ĥ2܆5^,U" ؙ}=:)U{ +ԦUrȢI:YMpZkJE<&ZI쒃ݩM1!P vlxV?TuՁԏ-B@&PJ09`=Wňd'RdTUWNܼ2* ٤R= Dlk0ySt$ЈZ:YN`X7fXG6Nn b\Aئ!Ԫ?= CMuKh~"Ӿ{f-P;AbL& j96I|e -y*8LGъc #mjhS&LY55qXٳ|ŀƟL`=ul*gDC3JѨ8h8d8ô\8ʚӀz(D^U@ϑ{bV¼9hC0 dQ~ώ9sL,3AaQ)q:bC4SAT M6-?%1pC2-Q!e[*csG)1@k?/`P)Q a% *e5 %0 6 !+~3rQ9@UέtFtdU&%j`XQ-#04~mZ"0+.1LY:8_38EWMO1lF'L !!j#7d$,{-+Q.ʅevvN,'.n#29EPI'I`LbP`h)14*:)P^lT$eQ tL9*pF'ڝJ#H]θkEUž;ƀ>OWiGWX;ꈦ& O*c&2?IR~M .QfT&L&D׻*v@ɅxgQNW_D8zvJǵsUAk7J S> fiWK]V ho ~̙'g$- @Y (OE+/Z3TpkI"/& >stream HWnG494<b;nZcr$H,V$rs;Gor~1 칡ko-g}W@|8Mon)<-GveSI$fBYNxUY]]}Am>V;PdÛȲw Tf^E#}fTw@9b?x Jm3|t-doYL|X?ow]TMQ 9kv{@-NxQǸ)/~]de5u~Mk eUkxh{!pձ'_}ai/?O wo9"af#09+|J O/zS!V@3.86N-h9פo~W/GiSs唰/T8a_E0TKmSxFbbdHztg^y7peQqfH9Iiv@>M;誸xdղ;$,Jނґ9RIY>jNvl%baRay";J؞G3<)RR#\(EKT<儧yj^#mo3mFFmePbFނV%69o):#CUlX+Gnɩn4yc>޵Ͱ9vѽx] ܕOY~ojb##b\WDH}/q܋+Ol=? ԴU:ڊOnob5kujՏE7c}yL} 9[_w;'<Ä}C* n=jbE ^bg5^niQ &;^=nR@,?qK=gbЋ53@XYyK_YJǒB5h$0i,Zǵ=7E/oޗ-*M`^P| /x}}T6&^W騘^!;1p:ZP{hr[fA(((،؎؍؏iaIYb$fb%v$n%~B ($I,5R3R[KMO׃}&o5C37_Aȿpԡ.O) hH#ӄ4 AQIYhfhvn~H (0 0ȌȎȍȏhDa)?@{9'[,\!SIRcrMC- SSC9F)Z(Hei(4T36B"Q4uP VٔȾ@tMt/qE_PAF#|Y cig^ȯϹ%Q-ic@x-A*bխkzrә8(mfH9-*̢,JŢ,b[p pUnl(^P7JʷU]Ⱥ֬8%Yg%'%('BOAy*PJM*Mݪ~ՠID㙦]9Gm]8c1pkxx A}aor%=MA1l|Lo.v]+CQF#c< WQZo7cl>jpjsɷɵ9nׯm>foKՏkZ~B/%f~/??z}A Ddz{ gXRra3|p GC*ǔ >c%[Y__?}t0X1~H&O968EBBL%CBDE*PQ\d+QWmzz*7%*RR1OEzi!}E!J=2BN@yw<#NaDÆ'Ĕ! R]2L@qI~=! 7?9ȃ6p Ai,wN*"HgOYC_9 x DLiCnˠVҎ`0JmwdweNǎ "n^wžV|ٳt=gr}k۝N{E#QRG KL݉e(A!A%\U`Yf1\]=-U *Ƭb5i(S LU 6Vp 9S NxW'#ȽJgb(\`'U,[MV K=Fi\L0MeaHd$H,s[qV S+ݥ4ZijXj.9΢ &[3^Z"^nB9 uB0zLmT d&(YQ3J*3_`ԓFn˓S+bmcR,wLP J3ޛ,mP`s3X݁=rϬB;]B(M^BcKPQ!&$dIb@+`UZ Xq%&ނP1 )#G5]FdUI!!Zb6܁[7"P.;[cu(NIe%#꨾ihUZG5#h wfkj^mɖF6ph--![qc1٥3fUկ[*U}8ޖÝɟ)T\JyWeOj}i i/_m D%&P7j3\JrVwW^ODR8 A9>_$խ$ ~'A 蓆<aaB@ԣQ(4汌؏88ðd'7y/)y*S70T(W$ DŽq#qY)guPy㣶OO:׽G:m9:wPM獯ůd'aCm9b©}͞->_~M0?OSdMċK1K$&OGyz/>~~ywu诇חO߫OP",- 2;(Pr͢"Gͬ.ꥢPORMA*Iqo^RAR?R=u;+ɕȕ O EυXͪk&5d#DՅ LbR JJ-,I\b`RLjnԎI$(PHQQ5qJgX%J*3aY=52sU"/Ve\B( MqUjUFIn{ܥZ3oޗ{*y/W_mkH l[ՒX7S2 \D9S"v@tsq ZmP}Up8Zm-UZbY dk-m/Ǒ#~A67`Ok+/tc0 7"I*Q``EWWQ$sbʹ̝neU%"}n^7n_6F>i3$>(P4QXTeNb-h[,J{w AbSbKz%Wb^;wAjH4Wf祙]ȝSd?+߉I,/]|1/Y׮6_Pzl_37ӌ2̼fx17L=c6F2lcx#3[0#s]U€tgkY@߄`J' k;3A? H1Df $(T@ Hrg}8rJDd[:txDӉU#FPCt0euR:Gq (1V׫z^3dAbqG ٔ*v-RtwIbʏól>i-'?w/Dj3 1OӘ'6;|1<uAz* 1?X*?{X>PVoa`#|}[hw~6LTn ןy^6W[</S !M2R 30V2YSX&46qc'_l3{lxY^kc{ߩ)_w#g㪷2_pw>31N} Z@gJf;X2ijUfCN5A5h&?B>Fͤ5fjF8MdOG31ifM^U2AveogCʞ|*:E\;1ۏv)MGoqڛ].k ڣ:ֆPebd9coG[}.BLȨI%[)d1sJfRJ%̏NE؆DX]#@tAq/va-S͐ԮJmDj#쩧[DW" D&A#Zz/ IBci ~=A#Ų\~ As"x ` 7 ^DojEJm"mO5Ry4T8 D6`q#Еp۶y#vý3 JNFsM-fK_e5naͮ8VڣVN*6%V,V^B/E+RxclseK㢢z13 R" _Ef1x" 7D5|&nQ~bbbrKRA~d2 +:XA#tCx*4yÎ/PLJ\EYJ撩JM<O>iO[G=q 3Ys`)g,Bl{NP=j= A(١=rye^M!TdjJLJ#8@h2;EeS1E E{U82aV" 0I@%em6:k=f.CxN ,1 FlO/&3l#f 6cI[6[q !C q\[E8H>!I'KHP"$&jJU4lM6ޥe/?{[ǚ,O[~Ȯn=SfaԊWدخWT`YZR6RHUSqMŅkjQhPGn2T\ Zy.Pxkb%X&l6t_C= 1NرlBh*zyC"cVG!3.+7z)ГHZ'[`t۪U-;NӠŤ``!E 5!Mip=lg<$kSԁYRI|v쩳qݎƟ]VS\8tVF^ +r p6."""!U:vLZxm;2|r /(J+N <8G=6,06m!{>Z&2BOg*d-pzrB҃>w{uuU(!E29hdڝ])lld,>{vD?fWr Opޡ7b hH")l$L6,0& g{2yXDϽFt[:j ?-_A؀1 (SK)8l6hС2fղGٔAG1*!MAcۤ=H5q7qWcsΣt[8/ @dT4qa7Ό{F VTydj塌8l5 /LCS/;krL|1FErtF뮍hD;-*U8(_"~-Kv&8c{{*LԳֱT5'ku.ZH s =*H#\HdF:Ij%fIl'ĆB݂J+KK-ߢDd>M4 glܲ\u\֔gCv\nu+*1ȍiݙJk*4ҝ\tm)RUZҪfEj W]~haNPH4wN:cm 2bpUܖGd=ϨRO;CuE9'͛bi @BTh@ $-@Z)Ĉ c!h[d*d8:ܷuQ:87:&]/4uJ"`t93 { PBhi^d9>%0qK_7iq*X:rzӘ4Ǒ#kQ,ة=dk4z r:>{-#v[ ي,lC8eMY`I!  ,,h?&|Y.kY!i2|vY"Kf>`*\{1m.k*9$9FDimB*R8^@<xzkfj\Yf2#jo QU-EnrKK 3dpt)P֥NnJK+t*͑S\W-׎8A懰<Ϸ͝G-|Sq|=h]UQVtqrW}]>FC5 -Wj.I-_Q7շg?RsŽ>O{4UsQU˶O1| L=c'mTOE{1-x| \jǯ&n7`/A8WշӇ~˧7Ɨ>~*o?}[8t.~~hu2EWv4YG |/lQXj.Onjh{`^f0'tEO6>|$oS<!A[ Km2.wSl`I1sbv6. Bf]I؇uyFhCC$m&2PI;DUy~g|#p2!SpQo.ɲYC8͚)W aŦ7XIHߋuc[n6 Otp(:xC`/~ ]eNc ;.鸜27-\:C l* %rx{9kh4Lƛn5GvwKbW` q{0Bn ?!0 pERl"qe@8*n c`OTZ,_̱es0,K8>+Y!i sCYbIRJz#Epܱh7?%E_t'g/bkE?R4:0)%Ԩ=q ނK+.6XL}׶!Q\wx.]so:f}j8kG8 x_;40C``a*X1:<Fn A !Z<`q#ǀzЦuv`dy⟍۬mQF$|kE|g_>?>ɇoZ.ctO`]%#rAn|]xtg~_^>?|GoX~; !0!F  e -$xq[o=]%tv2L!G8$h4)bAzĊCb\i!B{dCx?_|) 0V@0DGZL}Ln\E@pyHؤ(C1A@PX&5\ A!QQ15chsҩ(ObyD/ 2>9E&ڌh H'G_d葞AgူHΊ-沔s9!1yv~稔e^9`K=06^oÙ \Ǔ]'f|5[},6$$C(@Iyկf\VTllo~sjo?..Y-y3nZ^GA/|uh5OOoί]\_~Y~ߨųWw7w?ᭋ>}xݓ6j'p'Y+hnK^I(o #AXfmZ``痳/}*'E"'Rc_YsR|;r_:Xǥ$XQKnnNr1VxA5 ~^qI`<#aak25Ӯl"ŝʮ@:FR7k6ı3X5cnYO2ø3.;ow-U'zi&n>4_hri=4e1ᬩ-]d⎄Ea~΄G{Idm48ޣb-H; `#''T ٴV xTLsE y3( 4l8)"TJh#=swcdžB%TTTM #aaL4vJug#lMgH%| Ց ha"|cMv뱂/>>Jd::N'6"BE r3ѐ,Pg:eĮ$I\k +\i r60Fr *%HڪYəJV/6[ #P@TBY 2m,'S Nhf&y EhU2g#g8OQ Ta`IlUGsfN,)- dAPG كrm\O_&]xpI* *Ռ?6N9TOn ᛭M>}ӷwWxy|vb?ܧo~8}Q/0w_돈P a!-,oʷ}n.BJ)D"X_ qjGjVl7х^FE"4UVTTֽQMO&w4\ØQQ2NIpt&DaQ2_jq$jSFA {6NLtSfGS`zҩ] \[h?G}c\Gm@7+eepvFGMOD6/Hlfcbmf#&^֪i}? fvn}+e߆#nAnآJ3^maXWc&f"xy*:OUHBi(Bm$-q|}Y^9Zg2A\#~D B%a{; D̫8O$SƗ՚0Z 9N{U/$ckzWTiJTהDch!(0AOچ(:ɓF@b=ed!9|_LnTKNTkR }_(W;z E~tن)H6$2ʆ&rs h?l~86f>icy `0u%|dGP\ =HXD-i]9q&PRt5F^ޏWpW+lIg@3W->1 $:1'ڨU A%~Zc׷?jcdGNi%?[yxLgVni%2Wst9͚0+M[f(gSg@l|`H~H^9Fe:c`:kFR\хȦ+@ gM>"PoI.;T@蔩X` ݇R/D̅3Je^C+wPtgRfQPUqk6i̘+չiv]']w)lLg 0þ?nuD3EPbPM̕qߍ)W]KT!5"xZb_g=9@RCIEQ[S@"tNMf .ȶm4:zi] m[|^~K|B~_Zql.@S׮ubvs56=e+ikPA(leO<{UуS]]EUlB$߀RATz1u'xn2މ1e` yߕsnG}+U XWuTS;1Xz(B:(TIMh̽W2yksD+SGUF(hfd*gPKG)- /(\^OZj Jbe5O)/f{$6O 2,QNF^}ؼ5ՖGS> q~Apsi{+ɱtaWZAч1TDt( F'HB͐Iޘ;|W) P]%x!9뀈B06^6QG N U~Nx&C{;AN#EǗ R,R4s& ͙FMFVMf银0ղq?*Xʰd Si-t 9_1Gt$e}X[LE#*wqmZ/A{:B<.!=&iŬ:}9 ̞FͧO2xoỻ>$g 0fBi_j+Qx(y]mI}9"&duw*T蒑fPL=WD?yf7Iith*I_¹EB4 <ɁQL2AV`} gSf"A-bL~W+!M4HB}kA-)yנx@_F*$7:D물bpuu/)`n!JО 8f@) Zu 3o*$cHp L = Kr3`}rO`pR^Hp8`ӌhJ$$#ո_yS^f 5SHUܫ/:'( u2}l@Ǭ`CNCDIyTHMucՌZXYYi$2P'Vd]ŴWBcgEyL}SuP/֍s#̈́$N[o!o$&O(&7jJbLWd]H 0U S%K"vԀJhOspZ-w6i<ɤ?Z[=oJѶnRmW#\xl1$xQVrs .V@,UˬڲH \#gݺg0Q C6h`~e />8X撲rMƚ]I&\LJ^Ӷ BSngc]*k'RD 0UXғs1>UJE2r690ί>MI ɗ}JчEԻUlS! GhrCK>a"<=yP!oLik]L,'(Iy ب"m@k/ Ҧ* 2$x#lW:dȀD#xpDS-eVLSKSq(H)Ȁiʮ57%)%~ltڜR6&-@qZRI$nBAջbtV^^f,HޠprfR!GC0JRBDl7 2"/̎Ь3SI{RsC 38UI @ֆKT 8Iv>V D!|J;qJHPa,+,)$ _ 5OB endstream endobj 30 0 obj <>stream Hl96 DW=(qCsܫA[ qP(k\BWwhX?ٮ4B~cl1kWek؝,他Pnss)]MqU~Rr; t bx6Xaiۋ xsvk:zZZG!q;6~:XbVm=qg_1ӵrxD4w=:KBz o]0O8BWwUxFJ6SNxAsVBשF~|eP0ʘUde"p!XWR=&#(y٫>aL8#_=l8|Ssu' To˔5\Ƥ9e e 06i|D~jT{N_sR 9|6{~Nz9o"q+I6.l[pU:oK 'd:+4z, ?0ߘE5$h!)HFk:ۙGz%UO% |=IChGBhd"SER}}aT:+Rz96Dbebӑn'HmNmM؋E͋LfE=Ǔ֖%"J}#!@QǣQ朡ᬐRadDȹ-ц]q]ZJ%JQ[ZI c$SUu?@tig}g:Ԥx{;q5궒Q7C9?}*8KFY=5n[Fj!x[s Hcdf)2Z>, o)ә@0.xM/N?6{kO2 t^Os*%VASRĨD#t9F3lK%t@M\:ase~J(r k=:[[u&Hs{t)VTx>:s'׀k?W$İLo'JJ{o'1H0geY݆^VhlcsiA;2-YRg3Akͳzlk9=5p4B}G%,u P=sd mMR'8Ni2>…2rጊa>sވG+A*n*l)>$2CSlj\Ԥ(E]lYݺ6U 1b>}Sc΅]twg\>4Q*A\vҩ&^߬+{,iY>*nD9(R۝b=s7 T/X}ߟW?I ܆ӷ^~bH==S0w}z+gM~Op.>|/Φ* $Y,68;gȤaD?\9}>"f#3-ÜIͨZ^\\gSlH5&wٱ[FOVenngzk;:fpGz u攂o9oF 3 95=B02,I:عsWH{qA2Bjw'9 D> 4E+BD2`( ycdٹĆ$j4;]]UP#05FG#Q i옰:krts1h@'ZAGǾ}a| [YS^LFM#ƼNUJtkI:J)ӝ54Z&(aϪ )..B(E4H]]fHr¢ QnaL0O酢k*чR~'%yq1o%*5[MPjD%^I,9k4|Q*r} EySofݓuK;^%L|g}digUǛ ) x"Bم?k]^;͵\ڛ׮uL9j/уuX0>ʫ}AXS`iymkO4~د+@#oGRrO{syFzx{H7=.w0al#wϙ+^Ɣm!ΈNl'i^:KeCߏzge MmϡŴ9inh)X9è+oI)M#ym38}u9/; ¡H\kqR}W~LA1m9ܲ >1vws\otIuI1 <$Ys.jzbp} qTwr`ŕʾ`]ٮyWj<>Z(hDI>G6ȣNX5FZzZ;vHE{8a-.@BV9܇QoQNH;tv :bLc+C!K;X% U4P?qrlUƓͦI=5 $(f' 9दYI_ 3L:1ЪPzL:h9݇ǥg} ۟HFe }%-XAK!rCyF؇II"۩v׏~^~ߗ|}s}8ga5o>ؼ}mgvyU}K =~}/z[޼b&osg˛/T2Ӫԗ?F bK 6RR\0XrmP Ѡwu]ڨ.mEbM`UEGMp&ˠ)G@yMc^O) _}S1oP͏Σ/O]F`Es#r {B=-!g"L\^o vyr/{J`.Гg^>[ {]^tJ{[W2ȗLLft̆D /7amT$wJc07@0_@:j]Fqʭ.n%uxBrL3 aNѿZP%v9@Y#"TqD5gHz ])**yy5ˁ{ NTok  2';(Eʔ\AEـ=qS;>}z7W)lZ̽/WM" 5T&"ydMi"sFsxo0=>u&/Ռٗ UDAUZUKU ,]Mg5pZ 񠁚r $6Q.UC$}Rzre<^< 5AK%dfBRؕ[-*A8R{[1!G $w!+ꡣjbXhg{Z7u P:"i*- 'g( XV0q$nR.µE8 hql҄־v\)]Uv c&׾Ury, i0X\} 7m'*ZOurS0I􇍅Wjwu9b&h+R矊w qǣhHaIPgShejU=Mlɯm s]U9g e^ߋitYˤDHQD>jƶu5)e>g^{!%bb*x]_gxꐐN:`#iӕ⌙HtmJRZ)ShV]uWwmR]D(t#fkۅ/W"w P${O\¶ZAFh} S؍B>[XPou9-<[H7K4egbmDb]4wWdms?P7 YQޮ sǻ,g1'.*,xcZ]B=cJ+X9Wd̈́19NL+0Ė-ՙHV^?MlhBҡiC@+ !iϞio#^U MźDC&'䶗D?"C WCI~uV;ꎍ:Ƽ(,wJɯIw +U!i|yՂ߶a'n2W-hzejUĘrZ6Dn&c8L5{Ȳ\34'=yF4PF>[ 0$"k$1dlC|ǐ F]6z1=hÑ)\,ڔkݹpf\ߤ9ɍ/ל!Y\($?ϩ6AsE&[g}rc~^,)mL|:b8 ^`9al3vۍMuYR]8|\9#3D*Q{.HN˞/!PocGIC*RHڭu_VqYZ޵=Еn:a`7rdXZ C* ˆ*҇ukΚqv6Dk`8=qڙ}gv8fuGMfv9S_8kıwv<-fVF<<Won.߽xt][=IY W0$?_<%)iTV5]i՗߽{oo__yG?WYmzqZ[Ƀc|!pC OkЁnQ􆂨`$gI}(za5xpvPN -:ehBzAx8=p5l[@yէ*S* JA?~><8=u[#hLJ63"qJFҨ~o+4tq}aF6e %j'U@H:_wͼŠw~7a+bɺДv,bAd D7΃*PH֝9buB,5]-gYHcJ{hIn!Y7̳J;@ Fh'\ხ0?<C3g:ab˞2ԏ׺=DaKU@vE*dVKT`nv,l6~lgFܣ {ʭllelCfY8Z{crOH*<y۫o^^]^M{YBuG_y(smF>}ފƿ6B׹,IʧxQ;j2 \X"W"r|&{kDgqgO>q;\N *\( jd_0suBZ' ރ NA_םQ+eCPVOܜ}mCKխ{8KYCGʗJ Nc]a؛RHwӖI /QJxVd&`/"?Byl/5+E oI - Iؓc>_~3kPv=!#vVE~.%?F^<9PTO_>~kp16T$4zÀNO#h9vT#G6@;;7 ;0Z;WI+MQNrtQ: AФuWgCϮe<{Ref_\ i\W3U.|3I |j$ 2'=WvʌU (З1aPBTt%1i$nbF[҄f6W.(G$T$1tZr;}^ UF& ҳ B4aNwXG bY*2?ҫBOTUrh {6DxTH%I3+]MYJr>u$줓3 6?}d$? 5M E@D8B)*p 4o{e_GAJ;#й-B+GDҸAҙRMr&5B;%N; J 0 v6& 8KG5rh>@ȉ<5 w^ +[| n=N}2ǿ4fp:"eКQB@Th'zJ@gATqҽ*<7 IVPJ@ЙꋝyF/dRw ĠD6T,+ɰ=ŝa.B:0H&b7 0'E;Æ,g (Z H#5G uѤXZsbCiNO=RlMQQ"(VcNW4&b5#ņL Ib Wi}Qw8#32L[UDx2MP~?dЖ_%Lǒ)K|ݢu+̭\$^ Bd6,_T`+e-6oR %<4.*Yc_[2`[HF0G`Kc>[ B[c=^ Pm-oXh[`eZ~ \) u<b.&O-&Yr-ْ>SduzG Ra1շZ5ţ*GW^ŷƪ )Ƣ_t5Vj`ziTPmp- r-)mgXӜƊ[rGXfɯof#(8[9gx[5Jk^ؼ]UxN-uH\1Aj:,)0benIi@^H9+AmZՋmws}àN4<<&gTNmfR_iHfWm+ PtHnqWlVɰ=a y؇-pa{THF;s3b26a>WU+Zˤ`4·$X]-z'X_MU4}bHXK,'2Y9<ُk(n cd\~}ĪҟĒs{PC͡xXKSHDU94At|J) cw Eel72_Rh,iW Ge'2'F3oQTb1 ]X~k;LBzИ$D5cچRИ)ZCamX^94%iÝCP ;31}<ΡQz#ʡQ%!G'Fbʧ6F ?dDa>,ECM$RUNh"M2Jv}> 4IDjG7n H+R}eZTp$3qve KTCg-/%2C %Ɏ@cҲ)$U(fQ2^"l "yN܂Aq_R9Q~Km]lpu/-1YCh @)Y Wo6a$IA`9¸e]-$m{<분JY5雙0P,uk\sY1T=徺|9g :gLu4 "Lta4\V]V-B*>I\O{r5coIX6OطTՁ4f>ҧ?xC4<} ńRRDԏSZK1/rzb˂lk { sAKlBPP0Y$LBW@`0Yʦ|L{,1öhC49KR)YxRހz8hL%ҁrċ_sy Q!hl MHd֓fi !OL"ع?XJPl\a"KQfYƯndFڲ b1#r!Bѭ.dnöQ]+,ΤGt+?TܻtO:-%`_A B-)PkHV^Wƙ  "ӾlF]4EAfTetg C!ItSͱ+w=ⱳJmq]ZZNŃwrѰA 2'cmYk#IyPՅvyC?n] +L섂SsA0ty<=b7qrݰ9:O% <^-/AVUԚ^mk-M5 ۷i,o4\#n0EC+,֫6׹(d#_Fk$9!%">H@0,bϡsX}x1߬wxo"HS4/V sJBrmqOk3rJV`yx,1D0v~]b@ Le/%^)zמO{ż\wfÝeCas[#\ *mP.j0r!O,uu")Gbb,Aҩo|n2ԑgW ~<5+d&zSRknr u6Ù {LYkTeۜcԳ¹W1՗'@P'>$Y#XtoIh"lO,^m7V:i7$-Tx)eRd21Oh=fG<}837=:;l7zhQuRQVշi'HiF,UFY\`diQйxru^9Vh F[mpkkZ̷<&})K|J>P-YnvSқ}YClg= M뺞g'BJSdl9$g-(nφf;Tf|MD{]7oI=dx{ŜL!'Gkq;[f|֥ #k(i$6# CI@rMCO1Lwk{[%{%#S&TAa)y&myۼ4&|X&f.:CNhBR9OefeͰәtֽĠ(42BlA/㒶sLc.ӡB: e'z$G8VQmz WO]b|tgu3z*M\I^ϦmxjR\ų\hy|vOLyOX4vcn>qWؼ4]۔|x)2HixB+0ۓYc~c) ˪z2󵋆)l[Q0xj?,yjadwA䛽}1Qν6Oz[*b^&}f*]66R"6s YqF6 E{^n3$FqH۳@Ol1T KFN2۰~AYxrZɹL5iJ4/<:'[RqKF _Z7tK%Gxrmk(q0: l]oM]bL;_`P;kUo(a{n{AGgMu]=WE[$E5Y47T r/ۊ _ :DlWΜd/_bD1Lܾ$,4}+Z 2w'[D)+D zh,Ir (Hc;c鶱8LNχr+J C+UmwNiÙ}+<TF})M5Iʫj_}ԩ*91f# 5N! !'Ĵ,8 ޱŸ6ʦ`mk?ј&"fp ID!x>)2zpf!@'4ر0Rhh/θG(-TD+0Q,]Yfl"V/2$aB0-2]N8h͞8ӟkdD)lcJAQgMw(1e={h~N9 A֜IZ0qE\1%c>9v٣6NC)p+I@q%*-1i6cumП/{Y."rCE[O2K]SLP~-qЇ xn""}J u pT́mܓ˾F'9,x($b{m>o5)Ew VvMIMu J,J '(y){Z2ޮ$fKf]P;shWtQHd`p&ꏌS-bhإvmh#`hʨr^OLu,\M9No#(#Hsm#Rzge&^I]̭/f% g bS4Coȟ._ٟWvڒ$Ϝ6 xZҤL+l&~-e*'DMsD!ˣ2}{,fl;JKFܶ^ϜQ\|4L޳oZTʁMvwɋh(1ô㦋. σJٶJ8l:8^#yݨR2ߛwZQOb9){9whׁf+)g^r[ď粈H԰J,lq.}eY֝[o{'?Q/" D;fIm.P3qî^Ace\xsl>Z"{Q<d3lFomE4z((?XbqKE5DS5MBp!PY[Ck*aШQn `1UJkr8iC(Ne"8yY6}m}6 3Tf&j9Aj|SL\};bz_^|?|p˾K"=: ,QС:_g^]>yUHk/bï&^]7ot?_/oۛ/x]o}ӟ?//~~r~Ҏ_~<?tⷽ_}x6Wriy9ȗ//%M_eih-4JOs^/Bug̽u/Dؾ)hjgU6__;|wү@a@2g)'ml[5<໡q w!wNL</AHK.:%Ȍ¿;Xվp_r,L{Ed]$S|+-Rȏ{/>Ul} NrsQ0G.&PR&~,&f"{v+"]P5 u 5#KIuШ  +"[&7&N'$l}CإfIkyB^Jd6Yb'0g.RTT@ ˷Vڙ;Z$LUh9Y9urs[[q@mN:y _RhI(uύSd%0F&A2mgPM;Z]"drێ*Җq޾r]"yVk:%ŸxctC˽J EҾqDѸ@ڸM;^ 0j-?Pqf]p=9+Аu &o( o9TC⎮<(:i+ (-IGCP/FTԟ)v/,Jݟ<iWIV_Q=~T)" e3nt[n'ěP_ ՙ/Dq/ůa4n* sEixT1I+pF 7IF+R:Q vO8 65G8 (f̂#^r \8‘^Q7ʎG{uG<Җ#07!i{Xx$}ZIB<җJGH!lG2-/͎"J/ R7u, ,,@̪:G[UȈ"q(A4]|9G>ڐ5k -zyNg/>j^uiZMn$BHHV^Gw -n6jnHF% l(ܤ?BwIb̔.*`# 9zsAzi"䐱Gtt zK.M]g7T S4Z*۪gjnڀv%$%\/,} , =gX)hźD,ۿ$nV6(=(i2 w%^?y-tVwOZiX=]J7qYxzd콙ڍ"啎Vzp7#2II(}'mAa4}k >1*@<0%ЮSYV"Jˋ[iOM{}Y`m_zpm[jЫ*[41fLZO1$I[/n޶>-H=n4.6:/k);ӐD]1+"Gu#LP=bXD.ѵ ,qnܤOc[)M|{r $Kald`g}#vf&QWfU<Dܪ=bRhY?*Q=`Q`l]MrKnv>4'D'3\,С$m )ADz۵8Ң佼,Cb6jlvC+lؗ$&@ѥvEó"וa[}9`w2R.}+"b(-)f&yuTٿhE$ d" /Rɢ&+7B.E\RHC+d'dU5E}^_.Y .Q#mh.q >c b6 C{â8>W~^QqۗF僚=q>l}_u}+p+?a^?~?ɗd~Н.LjC@*6h-z /H㷄2̧DIŋE)0HZ pCC;$E1)V97C:3E6u\0+:홃ʘH%`d"jơ=(N C .'/]5J!N2DP4QB̚՘`"ŌdΊ+̚ wǡFدi1Sq̕,0ZJM@gjph]`fQ$E6ޞJ$aF[J䣪X҂C-6뱠k&laY} {jJ,{C~CVΟ@3RmUsSK+mw!9MߜttIV>.G7xql鶂rFf645es CĦf6 Oc)ͣ!3kA qw*-vWw'l]sϳHPl+T\yt(T88WGz`^(ҟb6Fi(1-F3Czהz}z<52N{s4=IolP0#I~mn2/Iq=3 eZ0Ωj6jɌv&0C54`zM ˣ\dg [3_54[kU^M=b@?tt :M(3;y,ewFYyLzy4%xG<}i._9Qz0ߥPЕzH$Un1&*G~]1pWi PzxՎ⣠2T7Őn ʄF/*eqo] !cFcWr3Jb Pr8g!d0 3ve:ݓFHMlFצp+u6t;K…m9ktz&~Qp,~/\$Z5iFnwg$tYthr%Z~4.WpaTUj9R}Q\MY6?0@-*Np"yӵkMG2QR-dL4SΦEdB);VG)lH,YѐD}1'"aXWT?jF Ӛ"*Ƅ*iEC0hNUDڴ6Juha?f%mpT vӬ$Z܀FGPU`iP-_hULdRzi0dx(Lh9h 08ŶqO+}=fT$i<+Ae, d ONJnHzb+g˙T}/W9lVFrmqFp|=J:WaS#GD(N 4. B*kW ,A}چUY'u6|ۅ2jdq9RW&ޫ$ZG2H_E̱n0OZm%/l)I0ﻛBv6J =pR)pg+w^  JE400*W*%n:VO`TW@j(֙- cm`Hoy}O'ç(pIKdsÓ{c#\ٮ7?+nɣWxp܂߯+ABa7gO-Ubgȟxqws~=zw>}}7ݧ{{滇_r?|o<_>==_֣xz{wo=!=ûu܅?u<~b*Jy9ǫǏY7}-ǿTCX=/x7 cɞSh-3M'|zDhXmФ8i@h;:Z'Aa@ ?t|"17&,݇O`< ~@[>t/m[<AXqV tj*3bb6f+Bfg# HV҈O ,>ԓ''!_Fmm[@ A1*-wmάu~H[1Xsw |s)ݴ>sW)" Ia WpBU׀WV_ endstream endobj 31 0 obj <>stream HWko[%\}$M:8 hvX@Q{{)۪°$gg\Cte_僯޻! dC>% eRT|2OF`K&Ju\ `MiU < xmhřҐb"9 EFD9P TcB&PV@@K 3h[k|PQ9QC " R`|T/2HtMNԠvDŽ:'P&Q0C' mûϰ yxPْ q;0`K h񂇋 3DxS<4.I9!@B4Bd0$GfQ6gÙzez{CrX㒃; +/H v%"C1M [ 62 YrCX{ v$gK%!͊="#0Z8 CE9 =VX#ѶjPMM] WdvYTi@{u6Eզpv1sCq#Mt݈ДUxdfvHl ޛetk'׶$ &Q,c'1)fIc}ؤؔS1rSOدSMkm'59?}9l{vsby8zyXz:5{a뎅>[mar}G nmyASy:@yn)fd~f~헨%WhpX߮7o9N_n>Rað/^^`{tɋhɽkjË˙,|x]ufۑɋroXvr{qg'uμSyq_V? q|g/kV%42!K1:iX;Ȼϖb4Mܭvf+@VfNo*6Hr g1." c K\sOM&buCOžG_=bn~qbZY L H .h闙J, *`6mHvIrØH:Pql'TyFXEt}6A^毎t,hkm_(Ip#ŷAtvyp`K)tRӔhXיU0IbPDp*)>7$ӉxECͶD| =YW?T>|b-Np?~V.-#F^A#)|/Ht)3bEx@T;^<)Pe±Xcm%Fq7PuN-SNK3z)\ ?jm"W)҃r}z܉0C_J=7L`Z%raH+Lѱ嚁%pQ;PLVle*⧀-q"U鼕Dt"TA ,J/L|LVM]!Y /#4Z,~}۹VhVjkjj4u)м;6悺P ĠZy! (\ǂV(2$CUE rƏW$șǁ^DY< 3Ṟ8pEdMeIVm[B+Β{C'3bкLvbCӇ>AmlThR3'B #̯RS!X8͘u=gi'+?G^,dp5g_u3, X)_FWX E*Z=@Ҩ D\-\0yV Lo?Xb܁2G@0;7Sa(VKf5rI;R;ȇT"Ag)&@E 6p 쪮Q(P38dlr uH8j } (/= qľ*SH&tܷ DvX@oPEni25"@h[ˑ߹:9v0!g'!4W&9nH `^333 '*@WrY2\*!Vp~$AM& @R]6~o0ۡSvlن_^FTKYU|X5Z+?]lJ/^ sSi@)$ >eWOEѻ'X)y2"Q=)kSwag0^\ bI 8q"ԳUY;>!4KUm ~@) [O%j@44h>Mod[)Z_j]+ Vr&8ˊNȣKGK]f\uɾjN̘ujn j3ۑbr#Jpia7V .Mu0ڠdS էa\m,VXa4zzڐfXSLfU=nZ?A Ӆ4B2 aS"* dqe iHmM1\āy}%Lu|*ǒ}VlcpU `UwYG@Yn&??ҨIl lI NCo1q~_OJnW @PŜS@ؒfdV3 -kSD35L *up\}?@!E |W05@.(ʀ^䤯s8HewU1i|S=ӽLTo9yY8k>\L5HmKZYTY-'yƼGjZ*mO}&["` 5.Bv󆭾]c($oanbLߏ5YA;C*ɉ,_2wt犁]yQtvf*faTGDXhӫ79Y~ C;PGMH[GOا& V )Q) ._]\{EJzʻWaN0΃<0CҪD&x7)F]s OQZǗc1 /wAM*I9bXw/ Z̙&>uϓzl1(Ȯ8~B#nS&וeir`%vx)O0$( 1u䎮5Fp4}b'M@Ƹ0dpT?t5[O~K]mk'̸nVe(/`fEjQ~=v:sYFCߺi.I THIVFvF£/W)CiqY_2Tjm,~\.SzpKf^'UO㺣M3GTc?6$ވͺSg>e/eNS `H5(qg_V>r8v !5w YY#bWg"&a4GܶRvct ԝ?SxM6*)-S`ZxA!2 "1^ &iSebe{5H:.SAN9 ӈE"3tjNC]ED87R^e4gwsUQeT/9E^%F ϻrЬNGl.T7&!v^(IM ' Z`s-8DkŴ1 EeK(!tńJPgPHto!N9ㅬHLH{'!kJ7;2mQ>ȼMuQ4zP%!YaMnLxV-,C&;ɩuQE܃ fE F4n1?Xxy*ixSil6W$: 5kDs 8g 4ꎙb [Ssre)E62H|>Jiqh/ԣs;E'sH}aVeoF+*1N56Y[.ۨfN"GV9e!Vev'GCZɨ؋Vn/_D(>μ z,Zodۮ%8f%Ȯ!E/|uuOܒ.̗F4]LP 6_eW 󊳢+cFRY=y!糞SVi*Dd",qYꨕ:$O)q 'aAq mm6 n`kDo/ 7T+s)zl}{Y]KL>2 pQ*fz8[ Pr-2B5{Q,y2džS{d :$ e2NBG@ .m7{M_$v]9il]E} N#lt$9}54@Sv!9f90OcO[F^_; қ1$nA󄧄w%NJ253<T6co\pVgFe _{FOd5 U% iz7L'zŪ89YIF&]FDQOeWك#vHiI" GR]T$"QG:ѥ.e$hx*aT㉗Z ,5GDeȽ.CH[j4!%qRuS.OO?8ԭEezꮋ@$[9߻XoJoز{("@Xyg*b Yq8EѪQ{&RzoI^f K`p"5^UY65ĴI MѾW|Zק_~_|?O;ˏ0%h{Z4&!ޓlfD}ŵbnb`aa>`0F&-t[ ыF8w ȹ:@63Zki:2t@y)B]I3Й|x; *H0- ]r`5Nnƾ mW;oXWLOtP N43UhRohJA40T.֚wf/Ϡ]kCSU #߽wSIPV*~jnܘ)'-lzܑGOx^!ZBuE" ܭH>#A$-$Dν+~?'09|rhMn0T6㼈[:1?h8ϸcpsGrH%YeqH}$7 %EݵRx4pФ@ܳ h=' +G(xZ:g¿XɁ0PJgr9y݊6\+~"F,͐ݟC{)&sn\ a}c{!Έ x49t-n R("ѧ5}Zi^G@bGc3r` S6bɡ'˯nF4"|L\u95bO7Oron v+N,p ޫ9,8_=/ox`uhE5՞4ˢD`^4 ed?Se ՛삂QcOEnTJӹtZ,ՕVglkD{Pg |-:]_}~v$9gCZ]+$iqJ R i' `4щR'm\zV|AS3)wG5k#ͫ=bnÓ&Md5x,,ZMpÑmH<ՒQssXc d-U`kiE' Sq4Eru7M VuF% )p^]71PSuV6E.ǘXx@qV>4O9_&fg5r# r5]VLkKQzK)F%{T1}-- `TĮk|zc:mԲ[*;sz^zY1 }N$knˈ+Sԑ(朗_ R~n蚶@cOg}܅C{{ECP+ `ĥI!b 5WK+ RU#Li gYu$j"̆zCJy9Uӵx2,\F9S {йf J˙W4҇5Giغii(eڞl%d9zchR 1NmũЖ|-ǣeld[qWZ`e1S_}ƴY5QO-&yƚpe1X+ ߣ "F!o&=6!Nxe0DS(cVY I|ۭ_i(t1} Ƕ\Ngq^\9*U"4Б >|c [ 1_3 w{e5aҧQ˴}2/ ;.ezBjQÆ޷6 =,[Ι*I{DGcz}t]\fՏj{Uº3B.;3vjC'2/ #a,=}Z{Ϝ>q+T]dDM*^rR=B'@OP.mZV $ ;ZyG' F \2ݦ4S , 8!:BgGTrFQ \ mLtJԱ|E~Q] cM/~7dQ83P3\8?R!i^n(q*J#!Bhs?F0}sǯ^/";r<D6%tr+-kH/ {Nqԙ㬁i,8m^> ~ͨs{j >+ijhĞ[rSziqK$L{:ۛVy4% ,b »SF)3@ea.m>Q3 -@̼:Ȫ{҂D~P*YEJ=V*K)P Wkj}Ҹ 2b!a|6k$XgLZ8(W6j-/J$K#H69[Ɂ%UuUW{di:VQrC!J׸.-+v;nBǒV0Ӵ[L`4>|A' utvOyu*ϒ}-bm3WSP *+\@T-f@N euVwTG#Y+vƳ^eNJOg@B[l ptܶJJK >A.ͣ !Y('0 v*:!E1ļbИ[7IV dL""|cpq NWlms\U._:b$GHfj&:WtdZɍi  IqX7(_0 Gc+<3R`9 P6GD*-%yJĠ."M ƜML!kuuQ D~|!Db$ قml@!RC.܀VDZCx%;SNmc5TtvyvGd0-]BF[޾yRHT]@_!5 2g"a<.;C"%9Sl(՝P5/} z2u?|~x/?'A}IBwo??1Ǘ/^/ynxtz2F.Z*cB3H%Ŝ\t&lAiQu)uGՖ d+GE H2D6!%ɟfaי}/mFo^|>B;Ur.$Q7{ZS(FC}-!)/}?@f ɴ<H9%l&9;k[C魄6j1# Y#^T\YcwU˛%8dzOSdbf9 8q[*<ճҙpƠ%=fむ\Z \&4i?97ES7u*JǹԶ[jQ"FȞk@dt QXf-ի3=U{MYEжɉBBO=٦vȳQcyP{ ĬRẃ.];QgkTH_QJTi^@1IDK[+LƓ;a7t4"LE&/hr tn('Aޞ9#duR$*2L;`~"}FVϊ0#ʗ1,FbR=sVvFF&^@6ܱ=[3JT>BrĄKvbnLfu%o$,`U>,L A 5 {؞a,%>kK'I>r'\)R< mH.r|:=lOalل"2Z<;x3/TwTnCfFhP=A%cfBӕ>\1HŶƘoWBaldކx>O)"0!43qIH.V|Tš6PAn"`#Bl7=U* fEiWu$`420"mm؏.ht$xq=&fKnjk;")2D *L'R^x1PA]j{> %.]E.e{DfVДP [=-+\6JRQ7z" x1zu2Kٱ>/LP%9?m0\6Fڠm-*-oDǽ˼֍&GYl jAp!ׁN=.{9^!<u > T[cC iF֞|Mԧ*͵NJP55s paʴ0*6Г몷5Z*gF_Ã[J>f%̩~4.9Dz^ОDW^xv˩r9HZB(=N a7xgTdOWODqqJth>״) +J!Qco8&pqkN9fe r.b@3 uiyq^:bqCuM,f[4>Z .cblQtĤ:j]1[iQjUԹؔ|#,q :vޙ(B v&G sgTপq='{t">)|\jfwmr#Rk*2 EHcn-G@l^s۪ R5g}) e7Jٛʘ-sL$ucے [rZ4~/DHhaKeb:Ýs|ӍcqQH!|eͣRCU&C{$x_v:n]+5QL!ACvos!v*d`tUSRs[ڕ z.PeNAյ K lᗎu$@ a]9|UƘ8@̖D ]ݕb١BA;ێGA5ל(`Нgd2ڦ$ @6CCNH mP|Q]H~DC?6 u5KQ$w' y* * ؅D7˔ТOi+ZQYHC$ɭy>OP od]^Bs#mMi,ءD_5^53$gY?wTxV_55 <뙹.j1.Yǖ^'m;v56WZ'4$E"yŮ V ugvjDwǔ\>N,Vǔ g=R~ 7\jYn0T*.9]n25=e*Lu%mT.& ecyF (Vlݍ07)\Yo7&g`mG;2ˑO=7_d,kpiyA9i`zPF+@]P/T5*2ͼ2Y;Vht y-N ] !MSR6Ximb.}g<}o}|@~kpUߞxǿ=͛/~of~?,QQw^~ -Go/?oOy}W>{}+6ħ?~ՋO__oݗOn'{}Yx3Lh>l{QCk9`ԯX$`\3 ; &+F-8& 9stJ;0 tsHWia[xA(wrtDH#hIFJ4|\t%]N-2u-^Cd c1ԒEV(npE 2}YZJ]Ѥ#H-pz_P\r @aBzi2:B#qܝ8]:xKx]vKҙŹ칽Dygܨctͺ w#LWn؇1mPqf;x&Trɇ|o^J;APF Eu)H;Zs `ŒL{#'&i+`s]{ 7{!dDih]Qv.z@7qh83IݘNkv LɈUyH9n3BNJn)`G R9QL읒y%Sű5%^W=o5ROpjPϙ0L"V|)"7{ ^3C˪I@_eN7 3"VJ\YUg̎1MJZ^8fQ{N,TN,MH;gBl=nR݆ 7'MJFPxҬћr4J}R \JBY <%n^ mb7փv;BnTp3X3)CwL씛ݳ3-}L\ր?l%^T `_LI!X{fJFD֡nRMH|:E^Єi 2*,Ug@N\ 14F5H)JJn%0/2vWyT'd-{[+CjhADJvmEpC-65ދOCmE9BX6m=QҬܦ%W `%62hݮar5d0zzȸ`i AhU0"$aMnIXU P?6~єzvUsu3.U":ir* W6D54r3'C G(P\ѦR=2MuZzAUn@vԀpP9A95$.ݵ|*= ȬŽHzT=,܅cmW5*nd(ᖯ+RɊ;iSTʁ Tv [-F$".F*k1)1 [ B^7P|ӖSkɣPw5M=Mh+OP6Eh)Z/TwSej/aH́W[*7׫d_XM~G 6@jlڍ Ĵm,4.=s6S=' T=<'lIq[*Ͳ |>ke|TKgLv\Ɩ̀hrID$4sOPqM1SRWh>.v j\5tkvK^&Up -82pLIOY6 6[P1c>it2wF!aZ`}]iHY\F}ϣ9$ot3r\|hxZZpR040O7.Lqz똯N9V{jp6QsQ8 aNk9X%]j>I$=vy5jG|SzS==S\$2'qk̈T1x}mه7("B*,?e/]B[6`&Rb|}jZgbS샑#-0v!y]1;an5bLqTIM0q)Y*i|z>VFԳ?@IˆpT:9UY!+'MQ= HWnrY7YzքJ 'pW> !I0 O!as^ w T1^98y0T뇛t1۔#yqV.&K͟6/ԪW^_FroI%Id=V/K[_pHy%[<%__41S "n(7ueYjG\d@]r~eWKM0$(*~XMZcL@~&vfiua1yT:]q d3-k!~ i@U:wMR=nZ9wwYpA[~iCE*ŽtW1Mg `и?G"4nZ(Rk"%LVۉG-\̚a,@7 ]c$pX\)=0Q[6DsHRuvM3΁?dQh*:Y:ETӛgaҿp]~Aާ%}+<_F*Fw@6V;f2'^>컅OW' }[)שm;cte_Y_)IГve%ji"^ z]iSev.SAeI h82FfC]qX@`'EJk05rnƝJ6(,3.5f8_94|f3 mu6Qz  Q"AQmHq5vE-^)Oy7[.+G"#@ԫv 益Hq6v X缹V!PD~ *Byq~C!ҽ3i9^Z si$dS[܈Rzt+tpPB&4EgCfBd7Eˍ/êeaɔa-6;bC٬Hш&6r{Cjc_bAR^~s+SSq:Q2k BVρts#%1Xl!~kJ{|snR.`|XTi# /H}̋%9ŎBNq>tYxEJ,_c5 C6qEE/c~'CLNJ#>JOFžq#ԧX#[u$)_۠ǢOJYqldW͔b"t=[!_4K- ZbSvu9"Kt"?@.vjTW|ՒY/c EY:$ӸN)!_a8Aїy&Nֈ_P\QPc=Pv$vr:@>T"yoKS!A"\El).i p 8d[*)5{Q,q0,S{Zk uK!Ic%VP }aoJ:5;hSN9[&냈6%)o:|Җ#?R )Z,=?#?n_; қg'ySBѻ k!U|l䆁J2կ Evz<̏=*3 5,eV 4|3T+)y1 do'Ig",)#^Ud%M: ((0蛢 ك-V4Q֐}lHLTĞRz=7T庺*;Tè≇Z ,5ܽi7o&*(Eqa?BR )y)IG4~p+ YU&]OUK--mp*$OsSMA yW(%ks|+e6Z6z'R"_UlC઼Dj<æbLL8I7gDFis̤[RqBEcɏ[r'З ?eCqDѭPl4^`` h޽ϩIA;\QRGPyj9qt )^.Ũgs$E6`mm I! *}onxG8qBcmƓW[|gļvNZG a*br'3AD"|2F$}qa,zM@S4#s:!GhTBuB#$N{ΠĦ76][T&A*,~$w?ϟ;7hR}}ϟ>7??~ _??]ux${R 74TPj}>D;aa>` Aa҂: 3~/q>$jsedb_:CIUsn2t@+ jHfEVCnKKޑ`O '_ Fni&lk =0hUȣf;oXWLzOQ1 9d>@"mZz4pȈ W\!̰_kaFZ*sYz콛JNTBtL9ɦ2z#=! vf@¿5~ @Z;$Rsh~_!0sH[)^%q}aϑ{}7"{hI1f}S:1в޽znMr9~$:$z5)!^kxu0ذ~ˣDz)+pechw|=ՏIȤ' b%م3Y(A:Vِ7Ɯcj>Y-C. >#W NnxLj߀ /31gWx(nDSáCzg(Hi\{,hW - o'?1Rn uhFԕ_wMLD%ScM7Oro.Ӓe(S1vFdH"';X,ָ.g&:qjwz"D`*\1 9?)Pr]P0[q[lUjCmhbZT-fT`_7)ΒsVk2 X}+{4ˡ-M&NhxףQ1a;ݯㄛS[R?(D= 'v}4m*Za-•LN;3V ȸ@+0iJ+hx΃ gEG{BJGNE8 X5xYe`| od mQ Atz@ tH9qz'2j3Q0b X1T0@%0+WZC0ǎCu@ɭ~D&n)f-heTg8*ʜ54]炵cf[Te]K*u\9vڶe"D>uFR^߅e$~ ?ønj)N.b6Gݪ,X  Z ٧R?UXҝIHx+#Yz6+U\^֒aU Z`cfJSLK^X;JµH;BOW#]Ʈ2'n WދF$vK.=Q-pdh&| ]8D I)w$.^!{#!Bh=Yݏ\A0. ->V{<]!kسMJҷ*%9DpDa*Ʒ]iClMBjEzc$^, L ?o 9ʈa6>z'o~ w$TJ?/o~O?5k?}VA˯yg|~غ@L ể\\5!,]N 9Xsr)][Y8U3R aWՖ d+WEN$eJt" [6!ՖL]̎ȷ5z^>a!$3+ra%b!,D~XInrV. CqBKϻл4dZ~ @@.V:/P9fբ%1I& sY>rrPA)-g/{9()-, ;ޥvY!k3NwN{>t{ y)@7 XTFa=do _v`avl6(uUۻ)Yl: AT>QBM}jPd41sP˩ ^$Fro}d+ ?mItZրqUo4vU0^mAAt8h*_forKwsL -9# Y%i)`o8${-xMm N$H g,@Ŏ]sY[n" 4Mj|z*Bhh0%.iMTDۍѤ h Ķi -VAp2wU٥˞6q?e@}~pǍ}BZqb& [ hM U#ى d5[:*xqQ-sRatQbF4'3kd)X7]KԧBKW]E=OHFáJ1PN._L'1FÙzoNduRYfߤqP ۆ#>V%a{,FSs;C$ܜmS{fo(o9oJ#D*"=h%(xe'8$$b|DZ֙wK4Ar-l$=ckw&W `ƙjɩ\Svs>%y.;eF5٥fFjt/SkaFzEg 1cйȂ&iA2K i2x'vި}+ڸzM7 ٩#|g#VԿ;1W>HEO & p+-: +1ҍLPj|P:q!MH3BѾ;zsy8̿z5S鶤!biAbJ”~@^,-qq^+Dr@iO#3#k؏/nH4UXccF MN_IuxՔ%" )x1P`P `=߶ΠUv{4 ~Vq3:EM(TǦGB(\6J*s/= VDׅdri뵪HXNods+a1 Q 6qʨAdD'e^75u5qqAp[xq'ebz;P4P2XX"Ҍ=Xwd 4o 羅=j4V.,QYC F6LQq`{8_JYT"\mAz!ِ~^5Y jzxAYST7.r[\:%)5C|g(OM&HGi`=!U#%]itz4;'I0 kD.nYc] 4RHsքT)y@I5_gVUĔϥ)8Eij_zDsv> .ޓ7;-hN?fe,7q!\{mbF B&/x7Jl zi@r^Fue@v\T( ϝG]P Gclv 0uFpƤ$ns9CȳR <=7eMD\&U"T jUVQ¦R=3cEpl⳶3sẼ߳IγߐGdpPjy"jIfCBE OtHkEpU E VB2ҩAQqUz)/c/Kz5i!ERӢԬc (P)ICTy#}#<2" { B[wvVfun׸'Ou6MFs}5tJlZpڶժ2OF>Қ'u+kgIRmW`9]>k $Uy`YiIAy;0DZ֢3Ly/nQACモT>$wCsU߹$ls'W^H4˲C#Q36+m2D eAưIaJ61r:wO(ЍXmEFJ ~1ڇߜeRn`F*8]L lͶjd` ceiW P֬w^i,粮>E 6ڠDk~g[ ]*^YJ8;h+z3K 5mψd2K5kt%l%Z 4`AIAvI$kUi=}X'is$4ol}$iKVǔW0CӸh"3lI+؃ DD%oO5tʒTl(ɭX$ aRxBVe5(e #-p1KYϥf4q?xkԟ\Z6\[]n坳wG&lPqͲRp^ƥvV9dxT-@ s>k١TUUSZwJ'F[IExq?ÜY>zt>U]V-0jgpҪ/YT>ksIGnQL@ ]aNEڝUf2M/$T啀u$_V5x@;K_9Ȇk<*wb<6oH8ƸMBqVE&"S}Nz#|YSə0D'eymR&ޔH@?9WRbք,iI8,3ŵlF`>ըd S,+z ]v7YlgY+U}1Ʀ[(#"]A>PdיP[QSERǀ:f'Dyũ1.oA("Pk/HM5i=gQMV̄uQ:9*NMI#n沀y}TF rduIuم>$1Dor(Iڗ3KsЍL0N\JU$QgC 6U9T9Z7-^se'ɮCh1JjuK*bf6xk%"Q̗okf\yw^?ӗ@O~#u׳>ɋ_W53OY `` hד˿ً^OWo?}_w?7w,Oyzݷ|7GuvsƟ.~}Nזb&xw,6Ƙ"O#5@li&2h(v "JIIknGOR:#)} b;Ue3H7SukZ">zmI)) p x5TFS%&]#Z$wO-d8 EA*ΉM}4ڷUEʉf!&WJ3u.titgJ]Y"uM XIn@6xS7Dp Vds}a_oTuL\B?آRI@zp?@;{lYQR\R>+7 c5fDF kȣX$ZilƘ ^ȵ9V%-N`V RtfhsKڢ H[‡x$ȍxn]=HTUSjyx7)K1(ښqS1isBpj[`hZ$(iP,ayPiސx<2- GtzEH61\q&Dò`U,nI*_kPE,]GS[Aux9ۉ ɉLtaR vHM)=LG[fma^~K'8J^,1{UZI.B%u獒m/;RfMz$uoŖ+υ0Vcv䵯{f( Jg2Fa 9J9˘-Z`ؒ, -<1*VE.k T"9wzx .0WW: kPоV?Ŏem+f`ZW>6P!Nbo-6xY6uX== *&>m-1={KH]rʡwaE:m|û+G!E8r:$|1txp`GXgiHM2⚥B&i(Ȉ/QT孟I/L9/ bU.R (ზx8 rgI`_& 7K^-AeMu?|blSۼIm7B>_JPBQR]ǚ8?BdQIB.*.%AVEt -l!oeklg@ؤz?#?&UFFZ{L'*mR t4Ҍ ш )n>Z0XU8!'E!%w]׮ҋhؚŽuސhgb~T/zUQ<~V><>N&ޘ M*{׏v D3?j:A-հsdR+/!U*nwTϦ+{t ]YVR˦ Hx (Ou3J$H:`-9 ݲ?WC2C\<~X}ʈӛJOt_ {yU!i4~Gj[mO2OY5D{0e \oG~g_]Q~NoBڙ*$wN $z|w_Kx!c@t\bI]QÇo ';WBAr_Y(3t#bSmBzܟ S3.%,N%22~{Y8@#F>KM#b𰈭3ctN^nӾVK"'tUzo(\##N9PytY@Z#*UQO."G,_UBqM`I' tay ?@ƈ8ńPҴM2}tڲFw%B G. Vc瘝;~-[Q"2. l1 endstream endobj 32 0 obj <>stream HWe|D(9v'+`Y%V) @ xTuo [O]]]q{̱/1%![\?]&vɰK5#knqO+3kWƽo}^潰")ȾSڼ b=&# "S ٱsΈBsY^[9_j;V#  =.yM vek|CjNvV={$z'H"3.sC:/W d{>\nǹ.u>42GBrv)ɚZG1\5+Wgx-kc/o/=8l7*Fȸ]o$XbUl>+aؼV6:yޅEZuOmĊ52F{.)pM?#D6?p+'@q DU/- H 8Y7? EZ. :V%ݨoS" V$ Xְe`9ʠ-x H<q}ˁׯ7 \d#PKaMݽތ |g.tT"68H _? ި\9ITt^$xCZhP5A5|sdX[<+< Q;_(xJ@/udIuNf -ٲ9Msb1$vɞ섕>@ SDJ\Q#ds#"[R=*ـtaS?YԓdXfHAV[T!N\rB*]0 %vO+8Ɵ? ;\uTE#XuRVH݈y ٷɔBGB789Uӳw拿p_5hi^9]VrI{ #Be6>"{BS@j^lYfAAi }f8φ$7K[)C?pKAĘuڐBK?@f b1e6Bnkߢ>d%0 D|qBIID:KL ]l_SRAţLud&KT#b⃰T~R: GZ5E: ?Pa27ڵN DwƱDߔ(k?d5"VMB, mV5ew<#\)O{ ? ]B^͡Wn%5ǭ|:Yխ;Mz;H~-1QhFB-7|eQoYP:kv2cB[E-V72󣃨bQp % crC 4ĠKLC`R(G B+':QZlZ:)XR ~/?||÷~ ?SB|~}?g_}?}?~˵_ʿO)U1z;SmGd{{"qvr Y50IglоNBuAO:B vm/j(ӡqBce`cUś}ͪ?ZX,4MWW8 Au>J(@MDmCk,`հ}5SæU!5a)wA;˳VcQC"xr_wt }6koÓSh@uk[5V:>zo/w)O>HMo=닭h Uǃ5baw3`x\xCш#:g9zKbtG|U$=9cx 1#7B><[OD^ )3O'#ۻ4u%aDXk7cmkRw!AFq[1!PzG |m=L~}iu2lBY+$mMvk a1⤏DePiPS،^58jPלO ^gS ^^VhSjN,v*BP:qB b_H\9@MR錞DgO'6Ԭpo>(=syC\E-ӿV߲zvG3QQ1 Yn[!;n,?ۻ5)2\qeI/?ҩ *z%vέ3H"P{ 2NYBmhg#ßx02xYu7m9a Vtڿ#^{?{O5{Ta00UFQBsZ jp@t3a9t7-8ke|BB=f,DH|>QnID]{ /2"aj1>WT=~|ؑe;9rL > c\V((*gEM/:2Б"PJBoq :]յ^U(2qHq\LX2.=Ul֋55-8,Gcv%J-1 4V8`DiaڵEmgc_4k!j1NҔ15&>UKf0>jO H&8Z3BjH!Ol~R3y y$g%Xu]R=e>:k I!:Us)RPھD߮*.zx9 +LUU4"Ǘ`k;[y OqIL)Zdլ6.BV٨zSUoW{:)R&ƚ.kGdDV5\ EsE&QCyP{A[V08U D|Lh_d*UǫI-ي=';eFBB16"w "5bQ3ZiDRĵr0eÜkftqtˣw7B2ڵlxI}g,5 $U7 pӈ=?^k< cQæA10Y"al78 ViNEPnSt G8TQTUD"*n^Mhh`\X*]*o)U3R<Ҷ(UU1Ѕb3T4n&nlk D!Twђ N'bJ@XYh@][Y8kYgYȔA2 r=D+ 6MRe@/}RuBVi4X:"(ި;ס&9<$'͉5N ~EoDP>[=FGeࡐ_/y{ WFUfBNȲjqgd#XN>mplso2ju/@n_OW#X=/q-|w;[T6RLݬ4Ĵl[' @y1 Omk0m%DXI_l ]G2v7oܽp x=]p3ab^9^K| , VP )M[p9eM2k0ӇL@B~_xښ;z;AhQYjvz^hѵ^1RG`yHئ^ur*JC4BX %#ߌCh^UkռxhMm;Ghl$I `71kXβYݫ7߽޾Rг34!yw޾g/^|}ǻtW?zП<+ὙFRWV=+FFéɹ*PgWG>ī>D|Z"J$ ] ,g4M@8ߡ!C~Mr`* Nw+I46PS$ayo53+v!zC?'tp;|Ը?:U 8NJ̍%pẘϏя"T_,d@C҇*Ӌ7. "l^3{U]麖gNH 3,U,,+~8|DL,Ap%b֬*N[>öFզϗ~b l&]@Ml2il@$-(ׁI}zRU)fr´QLМ qL!\>́N*Ro)$ U*T16|u#WCcDm;YOcy1VNF+$kh#&:!>}ǽz͜]bŷar0$m?G9K7:B+6aĖD+=uk|S `Bh%ȁ;eE7v'gۂu5HHtACid,GLW7*);EHJ !J='cW6㐈6~,ˀxCdsW@z;YGۡJW{ H47fUHmM[3/ٞaڔdR5p;h*$߲ܲP˦5[i;ED+=eYrh wݭRF'ב!իT9I\BZ֡NH 2p-cy3eeQDp^ hM[\% X5PQ>X&gC%O)9M@{kTt=j(@s*{W"8 -uH-M]YuIf(7یNL)m9u)A셉+qpH(JsS laI }AG Bd;vTfp4X%u;G0ad!ĵ!vEtDl@߲F=kDk'} bfO#GEtcJ'DdNT5ݿY{Qmw@Xf$TjJ^ESK>#b;2N?hw{ dd,ު-~ 8_P'_0I8EO=7 Ѧ| _23io™t>n ngu4L1[`) Lr)VbS.W7HFDibcaouTrM!O~$LU''8AIYqjFL@ OlЈk ZgQ%`Ma X. hes~ iZ ~0c&-FRť8yA\Fk_bHҮM]U\GxBpg] xP5ֶ8ǎ_DtDX*UD_Mw `C7^{h y,;j N蛬Ta@aoAz@cc7 YPiN.MGfTwT볏=IװAdmRh q<T%R}B{iו]T45,^n۴e* F{GP^BtHP-2CIoi rV$6Yf=.tnvU8zAɴU`pU"8~cd:zپ?7SLGtl}` "N5+"YS 2Kj>pI5D7T`~_kܴS@eXZ]@tD1MllXhqw4sy2W}Sr ZF}E)dn 5u+XQ  ZG93K3$)ikw,zEM$[T43Hߢ3\Ԝ]4.P!צŏp>ydnX[Qjz6GU!+d]7:`abZf,괪S^z˜v#`D`J!fP GɅKguǷW;"? Fޚ0CX;@ F+C@p7JқLDWzdqW"鴵m` NPʪBKRaXsnR6Φ ա0۪$,Fdjw\.rQ D|iK<5ĉJW6[Z6S.VwZ37qBV[y4#t1^ēldP,Q$* !HkMNndrpq~]kKyH% ~ LR J]YI*җTR#Iaw{2w:BI(-e{(RF kpd!P42GO$S0?k/Rd:(F_1dGOiT kAv撸k6ԒTEO܋W/4[懕HO_h:nη R)d4gm.@9tP*(.̓18\ $`:n/@XUM4n]! F+j/yRɟu̺<2w}un/ʥƻd00K[vD%n_~`٤<H>#z{7Qc<Ҍr6BP+ibDS*ppRKނ^~'=4sm\vVn”N)Ù}ĺ8o0BEmuG ~Fw?G]"9 `@Y<L=MmlcѢ؟ ٫ĻQ7rDօ)G*l*Z():#wirFSҪѠ0Y=> [im5)/A^a#'ɒu67ByG*D!SdAᒖOfɒ_J^(۬hS$A4(:Yhf!xndos"h+֥.khQ5ǘ0 \mWiǡ#M/@X,: o#+y& P(ittFE' 鐢-y1ZQ Ft͇-kL[eU*FP沏:Dsy#\Nh\/d N8sQId]124k$YaYY-fe}(8Ḧ*|(A!ȎR_D2[>~q|c͸>4QNɫ. DRɖfL[<.ı MYR&DqOG61>IWlR`$1} GZi٥i$LoCnވSp9E:e ž=R<DQՃ'Xa|a3Q dF ̎"Lh) ׻gh(uA!$*\H%4|Puw$鍈aM ҫŌ#!6h.mRNuHYqlr# z]*kɕ8[5 YN۷~|22T\FJ0[ހpI#m!7r?;ĆI=tx蹘 A괞w Kk0z#;VbؓtGv#=w]Ҝ!9*j@F*Ə2Ͳ>CN7((CHs'gɰODciV֓@!AӑJ\9u!6/d?ĩU1c},ZnEeoڂ{BIi*RL:_؟u }Ӱ г <)4 b\. fFJoԹt ^*=:`Ϳjt")YwwL'||-¬C֋8}]'+ 4u3ӽVͬ/liҎ,$Пu[*hMVSp4pDgyN9_$NwUnȿ:bOG4ct!m.$ ZFk$|o;&uc1~xKV)VR( ^/ ~xYxFUI<ʢ̃¨ 8Ua}r" ɧlJFMp D52w5,3Hj؁&bf(H*2Jt^{QnU~LfjNgT5E h ufgNtv+:_ĕ.#WJ--^K/Z%d ٢v]"=4IˈchЬզEAjiMk0%5>$uz,/饻B1hTѦju>dj 8H;Ⱥ$syTɐB($O` ۉ\xm!#>FPRdDz3 Z9mQ"[~=ت*3"dҩi2!SF]mF[IȞ%Q pk`փW(õj?7>Ʀh2R*AM3u[41 D1f/`)|Hl)f@ڲojúҹj4W64[q`I=|^aJ~D2CazJ͐dpb@6r?" 1Zc<2Y{}Chw9a!~"mn+Ѽ^6bNur^Gothg_Ӓ KtE€1Kvx4GE )37KnBp/鑥PFI[8W|fMQk}ml),ynFAZ="3&$72RuICb Go }BWqezM)"Qyu!q||Q|).pZEbȭ0:&.dVS2lv=uHS" Q1PpVBWQEK ^4ԊХ3*} :=BcLv%- *ˆ{f-Kdj,/NfU!u7nf9CVC!Z3 :Y,Llߢ[K/=* *hҋMQi@߰s0>-S2&e;[l≈.m0aO n.QVy669r,͝D=MJW#@@59S~2Q:cA6 $ߜ&ǞE 2[)wD/}̋*ȥW2$z"q >NRRM@6ы>rdNU>Fb>~'X&N#}|4 aU]y*UiKZT^Z#gE&?s;ɶ])8wS * !ը/[IX.Ķ̧K{:.WuP/P r,D~c-m:Vi$d? Br~9;%zW ȳoL#FڈT Du;$v=+O{o 7:z!AB .du3=u|sAjk胬s-!*$f8ϡ$&=ǭIċ"{e)zqZWW8uc /$n#T]l*/$BhF#S휭TSq 783($飅2 {˻Rm<F6UJiEcɇt|_?N<#rIGRI:sedt 8DT!]oǂ~m%*LvE)d9p>-(9©F)HZcɆ]\3"Byx[##Gc5az M,KC[zҒbAE:* LOD:SsK:'6)LM d[X􈀹{3-;Ф2Z8@D" mo %툻GOZ g(oo e"#멻w9el\r*SdU^jRB1\C0jbl9Q nPYپ4K.XT(6- y~=qC {}xFI mΘ5qgyܾj̍ձ%Vߺ=*3,cI]>5"{D)'eƣ$Bf꼚)RL贰,5~u:"T%]mT*"w[$(z85.ڌS_%̋>q^^hKZ.IdDHx f o㶼Bq32F7>X2:LlB4EIR H'+ܨ:Sb4R4%6[4)`STC?M—>~ς_7[ʗo1wH2BHmLٜꘂ[$$!:MG<P{@,1NiF䒌$s&-Q $"Q;':܋n;ӎծjҤC .>RP-I ZQs }g&HY#%5#"S-YўiW})=1S_72s;77g&Cݤ>ҊQ}˿L[2J;4NWHB_7p)gfL`##)H R߿BZe䃖5lLP Rf1($mLo#M5ю@(rJw @Q! vrьW2H#]Z}N9Nth$;:ƹHBri$ܸS;Hx^w4q`GmQqL5NN ϺnUƛc{dd|ep:Zz\^XO!v "n(̄Y pz% =Z1o`X 5׆5\D-Cv|'ޜ;Aȥ&QWèɏbvy<"=䖆fv6Gw="޶ۙXp`AM7Egvl~piY)3`B`]QF1-TOHUbuXS* 9ܩ̯k#*5v0fuE\w`L:8 Hhl-DOޟ3"rYդȢCm{Q7@)D|^ڑRUZ'"32BiYu@*&L걤\aN t 2a.y;x|{9d!TрutȪIW 9xz'(޷?cIqAtW;96UNwzrQücs Q:8YY5\XGU;(*ueƄ"'~t-)CRr9v6<> lN+}َBWd~P?qV@0"?rotd=)mijZ9 enBVNu,FgW5Q0 XMQ T %ȇ@Yjk%XH錁9}fhfvV2u! ^vdOޑHj@D3I! $KGͩgVg}FSXڧ1RXKj& zȡq3ڂarXuAEՄx"s 4nWHU9@4 6Z='R`Dui`_Ltd9 /]d@\H^Ew:y¡S>{Q;x]0He+j@p3SBC(,$Y{tc0ȃa&UGm&WUZ8!Z0-}Ezy>gE1(IkedqG˙&ƞ5.DI#<°];>;-Z C2\v j;eSʀ64]^$ۏNg0no`1 5gdvC*FWXD1CMSu9MYpƱ]MqS= ob1Uw8Yk9~DMRZ;IO @gLa[X0m ع  $' w: ISט`KD>=;.ILh!Yp:$'AF">D'Hdt+NsW=r/(*jY*Ƭn^!(EքITTFo(V!ݶV.|\U2uY:]!6u| ޕUMiN-rWB6n2s'^'$`zo˾MhSIYBFC76gG~X)iq XX^ -M%l1|YW2,G0 C@0z+cvAеWtzkf.,;SdIJܡd \NT%9fzR&4Ým4W}TD&ŇC:~b(auuA6WSG'Ӑ5 #q"攸В&Lr&e[LtRZ8-OR{GFC +d;;U.4X*c {.#a=|soCUsG(UP{{w|_~ S|R>~|/͛_/cǏO??_yǗ;?o~Ԉn頞ECCu30Ƨu)3z3x9/T 7'T^W[ $[f#_pPS d9v}"42.FeNΖyH!fp83"e'ڹCl8i̖^+]Aɏ+IR~ lDWf€cd9BǵQ76+A*f%yivZƿ39fAZtx@sċRm5z ;S7nX9 E# /"^7}`2V1(2}2 .KJڌ23{ƻ"uymg R)FYw%)ajՕ tE@abߍP>*$KkKq1-j&ɍ;zu)YPDvK%-zʕnC`1'-肁=bD#YdUŢ6B B,I̢N` 1gz+mq:9p K<1=jʜޏbZfcMoQk80 g^}OV5*OCzl )= 9>(-%jG=6;=RZ$]dP;HwAY9t Z?[eҟ8k%D+ւRK@"%)bas'H&hb$W/b gq8v埋zf+&mR'y -cba'` y]Fc!/ɷx9ERqpTMmdj8ԮKHa x)}V_(&>$HK!cvFQs 1W_'b *=s2ȜJmYt//xzw Z`GlK]ӽ=ƢCh4.7+O!3r{&Mۧle6tj /%ka]+] x܍eE뷥x4^Tmm{T=3G[KhLsQKs4%+$z2y&GƺV5Ge_2S,}Yɲ,3A$5ahr?BE׉ww -p.X[PغL"ڑZIhѦAej.Vqtci2CL@O)mWͽ.S-C< ЗZ ܉B/0j1އ4 ;?3Ts7Vs"վv F e<)%UZ+m.6ָ9 "R5:G`9ݞ Y:kى!&Aq`^Y`sΌEXuLER"C ,vr"0x>9F˔ N4vPL B]̶R*BK88C|Q/_YF$h}ElxP CTL oʞcrBm:$Dܢ$mΦQSBg=Kf J >6eQ9ıڠQgbPv&:wf1![ ѻ!|9Uݢ5vT+l}r,b^fG%RF~PIZi,$wx'.4J9 cÃ7rJ.8xhm/yy\:P]䇩6Ԓ 5B_?-F3w=ڸ֍%9j!u1]mL/am<@qE*CDRJQW5mI9#40"D dJ̚tkB)d:΃orOKigE5 K;T)OUfҽ+ ϐ|YQҡp5Š5ŲwP !4O 3٭U7oYw`bV}Dd(xwmB`f b& SkB|fZ}Cw5cyob_vB UZL4iJi˰l.?*rIzD\c=d:%Y #k3Q!粐yGs6ՂU46I6į/q-*A=TbcJ(x&R{ܟ~曇_<?>ϟln2IFWcؗ3箇(#6v4’ߜo?пQΐ\eA*THrg TМ}"!2BV%H!;I'a 2Y~  dy&eT7:F/б; 2j w`ưZx2n3Y1}`E}Ht[ z`_R7,cE<} Aޙ1*:Oޠy{3MA H3h9f\Ll'bI|-xjA?[AP%.Zf-1Tt/i#DWvhu@+LU(yTӳʯ =?K1 O[۸=mlTOuA)}T[[Ü}ZUXTH?`fqb{کCUExJƢ"hXv• '֓$jLB \OZF@(옙╩I6Spǫs ˰Þm))`42%"?*XF{_1.uHCz8qϬ'auO+UH#ބG6H3'z`I)GhSZм4:: B0*(HOgBJsRK5/(&;܂c͎(R[d&M rFkmQ2@5 5T_fiEQΓgƼIBD~B^:;S?Yq@b/s<3@VGo-eM-TA)s>[Wck{\+x:)_:=oUC,ADRO|Se %-T4S]Z=..h($jqNϜ:C浓JĐǍv .j86iKdxvEv;gr91N2e 5{ g>׈  k|:L>gWK.1H^ 2.`&Yk3iq[.B`oqJwW[70Mz&W,@!XCʩMP-)S۰[q(>o0S7^vsܾUztow2R-7Bt"ҶBBr#Ґ3R{̡doi?s`-ډCj=G̶t]PIQ&x\ k_" SUGӮ 7GDYqD_QZP>=pU~͵VKs!rr -_$,F3g8 dj3/J4wܶ3u{~vJS%c%}NA RXܶQ4"]̺f 4@LW X+x(똩,TƩW nMK/Tҿ`V_DTf|8v.VBkAbhWۑ @?83=Ǽ +g[8¶.r V4hUKϯq{*[~82[Oo׃Nu8-ûò%|=Z2 qf!e3W$^Bve ͘17 򄩍CW, ":A[.w [%^6c% ,j8aY ->)gQpB&Q@!1Zp3ܰ'N1cۚb-q_;letI7T ?Y̛9.P }F+*aZ٨ƣ9'OAi'RAPcⷼdMEU{xPpr)t(X-WTtE-T7JFfu<,Z l/B V'K^tIBSm.YЖCYȨii wf]\yTq nH&OQ$lgF|voT_m0G ZTK4?P!32o3Y ]mLȞ%Q}[.&ۑZn_)(õ"ץoF82TV9{xbn']tbđQ![jU,MjUat(.8~ q6;xtH5lxf>Y/{J!EhA׫CC a)7 (l)Tɨ8[ ^26>y"}"3g.FD,n Ѽ^Ďup7^DU$ԋ{YO(ФOeP/L_VJT+!2vpzE% vY㴩t8_#VSx/֨mc5" r(gVQj |c 3(Yo/Q4|z<8@Z[bC2ˎ&_`&{f-K5 @ x{Df"43ʪȈsN)"qs y,s!(a?_\{<$ ;#ʐT 2"/ѐ* F,F PHhR*! Y Ej9yw DߕBGduZǀY)qo`Nl*f,8u}Ph3". >-sw ;/Ap^3R nd2/i;ms7S3ugw4WdB=@Vρtd:9ߜ&Ǟ"\.쥚VpGt#Wh #T׵Sد i$մx)T^4.)ʏw x1lIZ*GF#8l>! M.j*OؤEWΝ<}Jo4vpNDZ>))Bv3(DW.G.23 XXf3⿡/Ac~vV;I*Qc ~Q֫Ha!(1A~^'ƍ͛Sw*8<ԨBo*n܃\xpу\tQu&9S+8XCm QΫXHX׎=f6K$3,pS?LJ|_HFT$62ΡSq>b y+ R٫޽+U` ,7aQ5{"ɇt+}-r.IK'臃湊Q^Y1{BFnBpQ}ia`Py%UDY jW[2HPRe>++j )9.hG@O6,Y˄dvFGvᓃ/i4x.9fmxsv7? X9"c<|]Zs<2ޏwU,f@Y-h P7YV1a [ F^z#xA {:JbS '[^FOndH Y;{>VmmȊD'ڠپ4Ku083'@A!&D/䱌u'v4}oGfhUz9SτHy*3ڌdPrUXrX2&Gq).p 6iE!os^ܑЖx 2N os{ V om>4,fdn$}8pCz MX 2 `ǹST5+cAf8f h{j*5UX6&_}?|ӏ}/A-˷7|?oԓs$#5+^4&&ӈIkpj (.Rö(ߐ2]Xb$ uJ[7cÀcX#wD{Qˠkt=Z@;XK}U&WP#eՒ k5T4w5kjbѝ5RBDZ[[.gdoJg׍Neaz#Uo2D 9˿L[2N7F%9 psE 0nGeZA3'22RZA@E+16~t`M*HFķ'i.%\d [>Ӭ/pq!%J[1eLF@Y DDɡsҞffDd?{CJs74bߥDuH$6"rzR45:8ㅳ͒*)s`GhQJ )P7mvӮj^N<}]D{QaҌ*_!]̸6zrwVzr_GF ճEm[j z4XDX_3!aRI'[M.Prv:mO5RvSXEH;4V7oMK62Og+*O9HDɄs7=-Pz.<~^:4 WJB1)h/E\ъVc̱/=QE!9^ګOhK KwIa46i=#eRoGgu{0pܥ8Χk?Rhv6t63P&Y]Tl {'F6C.p >f4mZlm^9? 하,l&ڌ2?+)&g/uʞg$Rm?gzj;(25׍ɯMԫeX|DPFn;g"HWlA` #NdjP$-nS]&0 1}'Bdu{T H!0xӦX)nT 6ϴ^X^c&X 9c[I,foHv뵬6{uqoఉpOت@\ma]] ,^YMU,4 *EiS6΄bGj( *'ZAKz]!zNٴ6)~+3na  :\05Gش&I s韒xS_T5LqDŚu3=nPy>yu\K}>r{7(/fm q^Kok tc|P͈;Ǔ ᔁOupCYpx5\XGU(a}jNK!XUgK}vp@髺Q%rY̧4jY)"5|?C!$7]M.rƗl&̈dsbq>stream HWK^&`x1/geˬ*A0ATUw%NGuu"xD,j.qnxS!tXs[2}u!1 =mXN>Ed>.y{s˼f Ǜ]m. }\_0@Ⲇe9k-|վFzI~ud_oXu޲,_Íkuyp\&>sk;;~y_1:(,|N:ZU!ˮ{%nt:`Vxa7,gMsӹ5?x H4fPtk;r{iu쩤@^G.<~ F^}D1ȷfǂݮ=&8ܛAf!knxo`}ۺ,}<ޜ6G 8b ΢Tw,Q/hB o gM1V p?qg;E;`$N2W2o:Hv[gk3}[}u66)6 Q%ZvH|dDv`K`h%3t=k% !:}e߰6 ܝrZq!sC!l4&+.(0_MPګ*8ɮ&ɞhC K~! ‰'t~28E+`:UnZ#N[ ]tJxǑDt ѝ+8 =,k/ʊDlCxPF+Y3V9Zu4g>E9GqZ%J_7~e=ߏο#7c>%o?zF9C{QA>%$]d}Vm/ I7sj eImlfL1xA5\TF`!™WaD,G8:pMc$}G`2C8 tRYb0 ( >991?eDe=A`f!5"4\#< $ؐYbI%l{߆BU/@)@߲N߽-Dggst_!yȺ/(.İqf0/Gӿ"LgS?Oy]ףA0m.ڥ )DHbߖ!zv$H &ng8 c7p 4y Q}( :8*nBOLWͱfQ%6ix|Ï@Y@0QPTT xsar`%s@'yt3@l[lmA6cDD$ #䁊f;h'FE)WRB8_Pi IcӹŏҘ0ndÚ\yAfa9Rpq$0 *; P{׮9uir3j8hss RmM!}-QLV(6Gv,[_Elj[.?(UHȘb/v;uYKTPS@&B"bl̯DZO!6[V!F ]6-<ߋDPkW3*|"RL6o>ctyH)U'&Yc`\BH[HƷrZ?$c68.}Qhgi.Yq#%A,%Ρ2ЅT`fTL%Ω興`[!kXr@U*asՋH_u4$,CPzUS 6*" =hڜȑ7I/ (>`ABJҪDޞuwj{z9Z-@wJO1{xw>RaNA">k :GDBwq[.B{YJ ]N4JDٰ͞{&b%~SOSih*2ɮUmsK T>wVE&mk;Sޡ!7RV@7~n"䫠6]肖Z78;dAK1x,9gEq36PZrBl!CEIr.x\HK6M_aFK&2ҙƆͺ,D;uP_"DBWgZݞgrwBYmaa>99G1'Zˮظ,TYZp05䚩G,6A:RL.K_Dӟ7=SpN&87!$LcZJcOI#apLwK&޶28}Kb$JA2y pOTDQ24=Y;DPke _$义݈WX4Ť¦FG\Hx־:2yf7VX-w#F)aՇ p. -J,_=Ro9t@  Cߗw lN'4f1~V/kMEῲS^-S/U@)R"hNN*31w@!HzΈ|s\ O7hepXEHDXX x3N<C(}Pq>C9h@LKN400* Ã#a啴a9aQ`oF5.ɬ/u6xS Q3p } z AFZ7vA1=u5S,+>tva/3,sUt[}yGVH0`L,pKy]u! HLo)"|6bXĪMWis{"N Rf Շ8$ѶNyj#+Qj 5 jGAb*@Dӈc d8e&ݷ7˷\g80Xhv!v_W=}{;G#b-0]G=tӂ@bm}^߬)^u&W%%n}Oq ;MD&n On7Lxe O>w,ea3\mԅIب*ԂlLC%q%*z_ i$Rq? Bw|k79&22A89XTǵe:++pp,4H$;FlJy?d JbgYqPzg*Ʈ`GJ zp?C,.vK~?o>{W^m>~{_y?==fgkGٷҍHuKˏ^~gߋ_>=oo߽_~W_=~߾'8I?glMyM=< w8f٧&@LR,q6?ۿ!BR S5ZX$_~CGqeK-wyE&ƧGjd 6hm "P6I*x t-[GmtugUʖz)Q> MK`4p]R÷ ()fu+Ф4Lͱز}%~}Ie'c 'K<' Mc3 zR8ncnkޭ0WڑW]e*L`ΜAtv%'@z?H+ e[.F8۲ԃ/0DIϵc@CnP.q*DŽ@tz\҃o`gg''/Ty nRń+Y"/t2&rA=GEh}J1د6fΈ8@SȏnꨍJd`ZC`( $1R4[)L&솃O_,(osfn7.{1MgΘa]s#2vbL]iju&g4 v'P1)¡@M FPtd3:=y" Lɂ=#D`S(f, ƖUQ+ˊr#)KWJ+~vo ;]溲F~;/:5``8S s-Dǎe%\Y]!x^)O]wtib)uЖ솟@f#eгeh+eBx4]U}%'FPKњ1=(]=CǢp3irfJYfpp{ AMw=.& e4UR5|r՜[QrӖ^Z, `re=ۦW d@1gm Tb8x(S,ԖUhS2T&ӓLDJVՙ6ئ*rR4oY@QW`G)^pT*i2P1]{O=Jhq:-s$Vi9TK'zQT Ă5$v6~Y 7[oňg#ydũ}R|#jB+L IG3iL0YN/SfH7/yP{'ƙ,PK#!|5mho *+Z *kkfe!e9 w|9Y.hfwވZʵg"+h*_Fr;"u咹U^$zbmcQY@lGP ~"vS.d{bGjcfFe$@0Fo4 ~n~"Hg:Uyp7qʼQK=,_=‘qƮAEExZwƵ5‘-q?ė?h٤$|ޣA ׾,(y ,~hu?Dr'2>ߔX?㤬 nK2y$MzlE )yN"b 'mcw_KޠKp""D1ۂR-%{h?RS|[AMD6њ 3NZPCĖͰeaFKoB|* S5OTJN ƍ%uFu 4vv>~A%,m5Q;k *qd cpw;Ý".Fl=&Z~Ry]Y|Fu ˋW&f  L-4uࠢzc (&h$P[r$dj?dzc{87u fP0nǑFroj_m.hAum0"dLC/@X=\{7~w*Bc틸XIcؔ8EdQQ5=OЪ^Nv98VZ`n6Y8$ua<2\$NySia-5aB|?>M+YE˜$ DYMĞÅUCIIFqԈD|RډTdjjSNyDy.h*1n;/ qߙ)%YIxIڸ ޭ \cWcN_H ƹևJGUZl{u*]]I?CPm5yw/B[+VXFbʭ>fmx&8G@jdH Av!Xn8z=3S](-߈Wh Bڡk42.<0qTs-E7^ުPX; xVrG؊ ׂvk* dY2i-UclhQ>UHbH>RZ%m#i1MM|c^USǤl_5&#'{QЗi vLy"xP2*u ce1ǯHYY:T̓؍7ˑhX`Tċ_,KW)t5 uR"rhmqNHd;R_ꝔUM7EQZ8%.Oi=C͡5w4 9-YbM(mJ2KQKZuss(_,UtWB`@1;r%%U=6.EseDf f{E^jq7r/o),X ];O&j%TG䮰q٦Vu2[ (oOuҩKe廴7Bars4@UO-C ZYQT.sH}̽"Yd)_@a@qZY!]=7"DQEU*ʶ<7 ZVzC -W4tgzzn7ԀO~sŸ-qoO_>OI_}#Ѷ۷/y{O:8r[Q9>mdsX-U![Rp?J_N0S~Q0H ~fHe7y!Cb`t 1KPg!Τr 2Nj5đ[P/{Z(D=B5[G E2t:1lq힀5{sV XvIa/VnEȑ` XS5SmgwefY3( ZV Uf44/i>L[.(9LuiiQjP2"ӕ|𔦾!7ɭb@+@CѤUw7mQczO稛W}^=Vqųqn"E,tE#2Qopb׉1>44#\(1<@I7QC.Oܢ\ao4\c1ki>Nqikf+q0hKwk@j3CJazF(sDX\`i7#̡u/d7yZWl1\mp W3ߘxSE]tpB-Y^!i="dC;q˰-B@8}Џ"$@{1XѠ;}=T(o9`I)˫׶_C `%Ic#O E >p3^,]UpT+x 8?ĝlCqz|䔴>]ڐ)8U4x,p IϮ"TWΰj+Ori쨢_EG )C$ z֮:A$>uNE3þ p]k?Rb|XUiXH m%c"afwE9ueAC\ʼnG;?m@q,q?߳ЉϲP,jA2n8Ϙb5<2M__ac˦UV>J|o4~=J<݆[ ST57BŽx=kekt_̥xw}G3;-f[HR6 J׷ecnF#X٢Ԡ2bA%RIRsHcR0ѳ ^gJQVqNI a>V"WίSKщ"mcw 9MC9R yۦ2n&2&"<ڧ@F3GC28<x([ȹs ΢/T(xu^h C2Q챽fHC[F=ФksvFyzY@c])zA;%٦n`uFOi95He%FOQIыaF.IM0 x|>, 5-'704zjEB"ڳ'YҠÖh|soSѲ{Q؄=}/xgؤĸ"Dok{wJI ޔFn( =t4X[=)MG+> !iAZղ4.rW,L) 7Im=2BW.zClPh|9rT̶_Q*TR/w>~};{J;>/}W_~_9W>.UHTc:c&H.>@ӮEYqn4bg%$**jp]?.IqlVB(Rv=uPƟtօ}|d|r-MoX`Ay}kPM$A>)ǃG;L (<\_2ʎG;cGx9M ٖ()‹nn9N( ޞ8un%5nl Sw]ڋy|× 8mݍ`8S\Q=KTSr*>*MzΎ2gB f3K(ZKR4״jpb A,^> +()b D pPm,(s]۸?`P289cP0ur*bk ͊)]W; kZQ;Ԫ;ެTk&uB-A]ۏJ){'$ J7ٳ݂ũXI/5*Y3zL 3SUZXiooi!LR%iqMbЃ(M{]zDewNۨ/="mIPmnwR?O?pUSE(i{Vєxpʐy:1%;0_DT,݌vd;he:dQ*β+ ƌWl-6UG'-ΛL&D ufʁwS1 )a֧Lk궮jmа 4`'CBUWpBJ7Z5+i5" A?Z$bxG3T- (O]r 6*8QFH:d!,LՑ Hv˛ɶH#W0-Oz)0mێd Vҝ-7_&Dں@hϠ{2)o]6оsT?Ytc>O~о0&hzH%l Q{[ځ\,KӕMVzھG:g6:F;|_qD6h.k =6bR{].4+-RusM%%j%" Qm#% З V8JS=uFENV"o+  xzmj\"kY ૔` rJl3t/@^Vt $-;aFoR/g_e\_}  b Na7`u]VpoF&\bbgpŻY#Ndڐ3mZ> 5}@bSPkPyj0HP?m[`< s{M&6b:eS2m[:E2P%8;QnIW; "YvAgfXE5ʎqbŔ5]~/ZRmY@+cUf  ohvÌpb^}+(fr:{ybCmG ܛGwL JcQrI{7u%kR$ ^"o\JQU-<$ WJtr"wZ[MTRKZC(,ۖMNd u,8m)/ؾaԩ1堨Ч$GRxF봫'q"D:fKx [9IndSjnO1lAjN =O< P)n"?펻kuj=ڃ_[u S$=eqJV-'mЦdVT8>в%?GS4h&f]< \fp!EGEÒo)%&FRf vwjU.IO򞠤(㒄V9m8݋kH;_Cjj)u !@" nկtIMUԤat DGK ǸdA\B]3C!0`֛RkhX$5NtgQ˥So޽z@/~o0Tٟ߿}ۋ/?~Jc?_K7[~|ܾ,>Wo޿{?_~7| Wo߽駟_>߿}?}tuʿ߼1qx&j&50sQ*BFN!q":K-Q|ɸDvAPRn(hF0F(3Ɛ/BXSpFQMB&+ւ< p!+ 7{q"4Zj0eKizѓ,}BZlQ=RsNL c/1@TD^B#Px18g#k&3-vatZRElH0y77]iuo°DJ1ڗJ< g3̉;:S!o0^7HRdbwQМ@ cGycf4g #/@9К< rM-fV }?GG:ÐV[55O=܍*(jRi d˺#W5RJqzG>z %uEK"ɒL]RÝqcJ;v59LJ6FdAsoFBQP!Hٍ#cOL٩UEICߕ!5^߳fSbEnI[agcio 0DY<-;iTwzBl"!$9sDԅZF-y=0LiPYNZ:*Jm:T8Ʊ52͒YMUwXfU]%hSH47<9BF.}PD(H[P13ASfb= qQMUd4RԷ@PfȐg}g"1.uFU$̺ #K˩%|W QiRe#&a=rFA3K(IV`"wF0BLiq1Zu;W#k@jE$ӭjQɿ:[#BǪr9 5_RN)G+A/IG|. k6W1 @BbO2*׸̻H(/1o:YQWo$ː":K(?#Mct$*/] dOllN6 R|v0FLP}8|&LFG0%fZkAf.5DI"=-;ϦGDx:v(/}$*܊SwVfΈ;6rةzvV-7qwEs)-7 n{ۄ!yH))-C"l%b+"i;XaI[o:&$-ыt]7u j:(Vz<.2ْw׺܎)hFPDE_?Y1Fi}ֵzr6L_QOaSw\NI4sIS#3Lc}EZ-wE oZİi=_wR`4ɦ*| $@F]6P4RR ?k+tDDgļoֱS)uUCbGN*ƝIEDgDZ9XC[Ƃ6QghLȄtyQ+k ۞7[hG^t`}AG ]}΃JN߉BDn=N w_'Uep[wȿ>BĞis 7; /ݹ!9U:\m3OXdj;kynB1+g>/^ċ,=zhnGYr12OQ5 AT#sWZ~([aob2[Ǹ=T3]Y_D2ރV=@}󛣩9a!]%VA}ަEQ]QќLSڶvEh\+y|"t|T[0LuKߋP'DP5Ne 8 #]) idhZJ<ԏZ l/BV'1K2YTNmRT%Li}ڹgiN;U׹F\ELHNxKn5-őX`Oyo[@ # 32o;@Wӣg dHti7ۯ4dv^oFl VYM:0NHhۦ`at@lu8tmf8l-6j,4:.>8cEW>3\9l%bCqt{ /1| Ee/pA׫[e< ӒQٲSQ?hu +o2-އ0@+‹w9avrIwp~E0SƋMU,pWh'EHL_VJPK;/*i$M@mQFz@$kRx kT6q<*SD87nM*N 5;+˻D za$ ٶiW z3C7YD~52$QA\c__`l3H܊p*LJ1PǖslXj=c2 :\A""BQd!,lǭ.(D}z-A2s6v2GduͺY,Lٗ[%خb8*fl,ʸuPbh3". =[^er0NC<*SQ6NqNrFv:g9@٣JP,Yh\9S~2h̻&db2i*oKb˱g"{p|^犝]B=G~]$JuI5"BJ$բTJ-<0Sj܍%ѣ##z8Vէl>"w:UMZT=^D ʒ4mvpN)10 )E6b= K>ըխ$|%Ķ̷\KgU3EKg:y"YTagTѩD~˿JώOԧHat (1A?fnY< 0?5*nRˆt D8T"W3]'JMS;Gy$XMv5Vz- q >+81LFD['{0#1&qEN=Xmg 7EQ?a s-tMJ z!mWkSLsT *q|PHI}$ KT$‡ L@TE t1.7Cǿ/~~ӟG'y$"Nt?'t%TW"tV4a-v7c$pGM[Q~muK-Ө] Ca8 _TH1-sTP1 dOF%|}x=Bfl`=t.UZv.xā "c<]OU yexYl,fD=.m;Dw׽n4H:Rr؎üzzZ8C0#ͻn橧:<Pc%"ekG'2dHR*;{>VQǐ#ȍ*ڠپ4K.XT2βIl38MF^R@ڜ3jB8&t:cK*Yg{{ILI?9t[g69G3^&9v]GJ %nX#5+W p`p` (޽DEBS gFf.)tO:oJuqJmFPa^'$),mw=dK)n[= \S_jkҷ?Wj*Zl-HgmH6᭵ g1#kM#޼ƎbG;ޓM8ell7oH.5FY]Bѫrw8E{, "PaOҠ }f$w?|?//AS->m۷_͏?oo/?sIBjcVDŽZiöHUEԲ-U bAn$#E ;zG-mw(ÉN)w՛nmc7/}bWCd]#UՒ$Π@E@;ΌX"fcd2Z[O:0 #]GެCʵe$Sc%[ [~<ڄ FJ;#z1sӖ"`Ԁ㋤o|Akb<6ZREY_A1@p ym,W3.n/|]fvq36;uY1ݾRٚTl4wT g7 v;stC|2`'~QFAL NY6"yTB(s P}N&-BdGdZOGoYo*I2;?.BK&K;[381 iOH}@ Kcv{ oINjѲU9xgN>ݣPRߩE5J.\WOh4jh td %y~G q5bXD: 9f"мNT+L\HC2]RO.Qx0,f(u拤ݳCfl\LJ9mnu6ZkeAaIS*9@ ]y7NB.t1ot{fOFG~IߠKnyfxF# #g$SkTueDz+g>%{0 rT˅玑"SƓfm~j٪j[wmS!N7d>D؂Ìbcd¨'zqݱXen\VA<-˔FDefA-$*Z iO ɠ|κ՟I4Kjfi4 F'Wi-H~^kd9KQl:xqIșI{61~Kj^c܏wh(,”{7.~B P E)S.d9A^NJYQb d*62 ~!:K|pZZ'mޘ[hbo)J]d1IshKamN=Oպ!nɂ;=.ꮬfD'd\Q\ԵP &u_c7ɕuB~g!7նKCbi,/Xr88e`Hm"43R#-Z Dj<Ղw_6b KSS}t$``1 g;YW>.UHD[f9_J;?ediXQ+7LVriWC I=fpRXvlwI<rLauZqB8GW%( g0 @괹Bqt3{U%H(*Z~Yf5a1_ځIc$퐷@}s(+="4_ӅƋ5ktd{A-Pd=@#SxBB l40Lx ΨB.CgVqK"5o !GN#rD5'bEZ9^c",m8DLؼzLƠ"t !nQ5cv6BQ*GFmD F²a"s%}HS@ ₐnu2>s91tjo{Ҋ@Uy6QE/ц/~ŇC5X/U::)-cO*-*ڢ28YY3pä:?QVY}tY1.1}f^GiW,RC E;>sCAp :1\Y*ĄRmsUOz(# gh (JKYן矾۟}Ǧo_~|ן?~/~~a1s}?i_5 cDƏ^:(:݄#0G3]:|/dS+T%V@$knjlj1XhI i#kG,idUD-'XF[Ӝ,$<m8.5 NVH82zbi[6I U9\wc#e[;ЧݨnQd5T ߋʢ؋ܦP5tWL5-AJ3|djpblE )byk'zEB\AD$Dpu?mɘ>'qCaAo_gU׍^TuG4hf=# #fdA-9Rh!#-mhYpF82I_R9$$]/~P[O˹#ZaDcAvjq.:3m dg=Uซ{@ X] z$,Y!qZ]Նr ~H/G `,M}12C%9?^ZsO;yρ%XA؅i$JByÔ QEf#qIb9s 4f=Ho>ąA4p[p+&<7]AYJesP8E ϩHr9 h|3M|3orIk %ojonqt`إ7=p].6}< u'ԁ I|VFv| okbi Ft+Jgi&g@-(;U_dTUqnYH!BT9F74O+}^/Tq?UNxZJ}IX> V"mG/(*#d[FP:kyGX/z$_~I vs;eA'95ϸ.VPOF; Rg]vUMa֐bR]m +]t>7"$O328c c!_ V4+$v$ #5uKf7]Ї!׈&:gQ*MW%As%i|LJe>IPFz+'nܢuRv*Gmo~9$$<lP39QtwWI_qtx,2" ST\g?!sV Mi@G=AUÆx"Y|s/Q7z3 6;;' gg:Cȩh`u4KxMdΚe0x34s '-;ZV ZA'oῷRZ$,.,*MYɏK&>stream Hێ^Gw7H3\B@AAjd Ȍ|#C`gwuVZf~6k;i+uJO7C euT[j3j\ ca&Εy?Zk\1F|2dmezT'Ȭgˎٮmh/}/Qp<Zz)~n\1S@ZÑܬK g2\+:K.|qXƭZO]Z!+7DDhK 7JKT콒ވq_W`۹ϕ/K%]Oҳ]=GН+N@В735%O[ZA*IPCei4 ŴO}RJ[i1 T&[ =5;. ! ÑӸZF7JwI8j&lqWV\HiBWG,#/(%߲h(}F#g!lC72.K+=K^]`}fk톸ACߝ[sĵIU*_,A4gWK!滃R|,9i8>~eNa62gP#:f@ {k~UM4^]4t'ղn"!f;G3,#WыuuyK$swcFdsPn6)| +,s"ЎT,$tLٶdzk3(!*$>)므Bt;Ԑh!\+s*L7*Lysa )#mZ+2 3yJ<3]eC25t2a+}vKO;Dg:ֆIY a 4G֤EPKtTN!r i\*He"YN"ke-$AlZP#-mgA,P>|:X5.D>BR$Q79["v&F<|QYMӪ\@\RSAe}#@7Qp9\.;D`R?# 5 *GlM_o:ZBύϱރcjPC|s~(bXۆ/׆O*3gsṢLE_U&+tL;$Jv;''mYC 5(Iʥj^nѴT)kgT p.D5d,E+gw%伺{RNREIZ<[5&{■tUIHΈ/ѳJxHFEs$6E >WkDŅʐHX-ܟuq|J̱ҰZnE5NUWLSb)M`?c`ݤ5(z)4D!.,S3N#z"IN 4ހ2ZBjKegYҲzjHvkX~'J$Zy| G|EI`Wb+8Dk؋a1AM"0N5Y=o8փB~k E}"4.ZCJ"qRݾi-û}Ğe-ΗGP>HȐ7whh\}GD{40Ӯ;y'%.9Ijϥõ> x+l󲲆K%"Ama>9K.FSrVj S fc !1-ܰgZFl>V gmhpFjϲ2ރB:nU/?퐒,jd0-8aPLXZ𨭝N4PqEI roy1L%i<hK{skPqHW{$cj15>^-A(a0e=>Y^:ﶗ]5и >a74rT b8H;HDtf%CFDY45Oh.MȬQ|l{@h~=_첽$T4q״E( @=\[ C>UsLȔovVBWVg dTmo)7ۯ(õഹ7 6zPyi&O0Kۙ.dDLb8 /%/R,[|' X&UshgkOfJUh:aC Ȟg>e/6Q9bN< jj/ h=d%(l~D2Xg/d-DJ>*w9s1'v9;8N5"MotP/ZiD*oSY-&AE+v4>kNr(fSTGpĨ @s:Q5 ǥP7F1Cs k2kpʏ[*٨V!Pj lΘ\H <0YÃhq<:}DoZ7Y5c6v^/'&~SCٍss9w]ɹVF<^2ʻԢQ]$M@%ie8FϬ7y!\ ?nE ?Bu~K!O#MB$?"s}Jv+Y9Np}G'%Ō>g|_ǖ p0C8ċ$;>R)vTU( "Oq:M;\fNF!@R%?f°Blz|sn_R6a{"'Z-\j/xi|]"a(35CZ"Sﻎ6CU-hj*E}Xۉ 'RK"Ϻ">4D86^RKs^g+Ou lhQu{E zϛ(ݤ@CmR4P*f^9ŲR#()]:iD{@l|ˮ"Kl3f$-i4-pr{<6'NvřOƋ4DN#OSJI3zLzп`|z1>HGF*zCˆtTSZDv|PIgKF܋< SEX&aK+6D;hb }:3%B x< 1 cOcJaŒ@-H\wK!vX EIẕ ~!q[BEMEb|רi9[fv//*RxƋYI*WY{T^Pdâ&DPZctO׏##<HOȓпPdY22dTѲ;!Tڄ~tx40l,ԧCINPdf8 _9|"9U i^cɂ''PTŧǬ.O| ldJ٣))f.*[v"& hOi>JɢS}n䩊_:~g+xgЭJf/[yK=0wovi@u P@J'RJEDz/0 멻*ʡڞd֙E!#|NZQQq@In \ڊa)K1Z7gTپDӬȈb AҫKc"$"pC)4w}xF$6gD&eMHDŽN5'ƒ-%o`Tm$\;oP0>N_Xz9SûF"/bj-`IyC*zoQ:Sq$éqfˍ!kk}0/3R^w$Z,h'##!|Qb?1M#B<I{4!!)UKm:0'5 ϛ!XnTBuRC(5N{NSbE=]#(Ҡ G緟_zVAt+mPC `a {D} @wkΌï?>TϭVlϿ}/o/IfU[$zZmq?ERIԚ]U75-X )˺pA,1)'H?k$쀊mQ~6 H8M1|wNtJ#vmV4omc+kBt]^+"TKRDkP*zj"sgFM,zst31FZ #"[-RBG@]SzrV7jܛQ{?&Sb7c`le=ӑ̹R@4&<Q Gb]暴>Ys ! uF[b.ܥݥY}eD1WҬDNe%Pѓ :2?M/m>K@'jG4b)Iv;u-) NmĿK1OfQˍl#"-ѥmt8M~7w7'8Ɏ8SqHS$" sD h'^Duҫ mng_m uCDϞvdgC)9-wALqOl06č"FN rcDzmɗoWr}ۀXKNżl~u!Aiϒt&O&,$w6"zQ7D2koϲAkb<j7TiA3RW9Q‡XF$ZLW3.oO1LbƵetVI[M漂4o3 W%aPᠦηzJ$uuQAlu c2 Q8tZyQ]Y!?FN!fۗ0K=oknZZЈ+<&32aM̘abAZ/5l2d6Ojj ձKռ=sǛ̓MRH|ӫ 7dF딅3YxB9r6T ҄?N6)>#_Jtf@e5bhͤR kh蔺SorŊw*ZcU׾lvQwe;Un}serME]H\L4u_1tpu*]i3YA#jw;ZFhS g,@\Pm.^;(BY|*HXk:!XpGNAuJ$O{<1T攺 瓫 esmP7yh@^ͳB937"V͹J5rBl .#ѽ*l䠲/bag8<(R,Lj=CW5bK|W^Ѐq''2u! >v;I"Ue/{9ꍽuls=UivJ{e9o(ufu=* ]&ruYu1>C*~JwP[A{glBaE`3˲}wttĝc%bˑR/*K:zp9Lw=I2-ժ:; p"L؁Ş;w¨ Rw ܟqܙF\$)hv_愼}G)w˘fg.JytM1/_]LpnU֠X7iH'`Y.{wKj-ˌ5TBB^Wܢ+7FdY02M}-0EՄzk:|U/MAa-Niչ <;.EIƹ4E맴B'-4/'HeYB 43R#-Z S,ʵ7f)";VS: M>nN#W\佰8 >#4H(\a-L*u⣀r9Ea^ ?0'oPܗ)Y4NgTmyP_`>.4)d|wmsdvl=<# rw(#`=*ݚm$qDe 4 GN 7v#Xվ\ٲhdGQхvW!l=(^.-W+=Ԑ`/0@2!A gf2VWSg벪XDvѵgB۠mB&֪6ՇhC,LWZ>St&} ZEx('0 q<º'<ٟyٷ }xR%3Z?y8m3 aGWwX9z$m~v7>QT:"&l&@Qʰ!Qn~yl Ʌ~#TxZwyYϓ_01Q@ E>}8A+Fb}"2p( T vmtIMX&~[|8<>Uz}vAcLi}u,du>)$60#DԻܺ%Y(ƙ5n1}vN T49V{0z2ZpCEp *3(Za96#u+}u̲z*꓅M3XRpxR49?շ|J)~}/>曟f~FWxjw4f^e.JNVKћOfPX5my^3/c<%=T#c@s`Xdih!]`7o$NΖL@13 N8R2 (r]&ÓeTk9W`41YDy܍2W@YfI턣㧨1Uu斉7M6bG_)D|wu_+,ֲȨbr&FQP *LvMU֒Rje>tˠ~e N[wP! gm@i;x"Ywa6N*ਫwы}4GFpf: vsӁ@$9_;@]{]@g q蓓ܲd<휖Qd"$*4>jj&C$g^6A]=7p!PE9qw:=1С<.m}>'e76t*!w,FTsh%v݇HXD)Q{͖sRoJAuZ/(2Qr+A>ۺF')kfyB;~$R:gxI᫆7])肝^Wi"(U1%C;fgaཱི?(SѽlxNe|l9,m x8L'Mt&ȭ&0ȴ/Hgڄ {vA}/zMnEN9+]Π;k-u[}4fvr}A%\_a@䌳`ZFW"`#lg\7JH!AW<$.P 1UMI pz)dD39"bPRʖ ? ̖8sŰXR>"=L25Fl'7}킪{1~w@gc9wAD{!S N#~.~cQW MyAyl:'Qpbk"*x9̹Pۺ2#rp}klBR' =vt8 eCޠAbAT]u].*:HV.n988.r:u^"VOO`ݹı5MBǛEXwc͵j (&H\;is *]KH/I|!Qz6*bT/؞"SPm.A<Сlz!^Fy}K/_k$ep(>׳N "Us.;XFɓj21&b&v]^Y_(3Wۇ[?;[P $5"XYB{ͱb@ ΚP%ޝ j,u>Ssݰ8P+M)=.-SZ)/ZfxQZCK2tv>8 .aqqL|㑞dT]unYHo!BĉٹFʌ yJ V^aOKL~X 撬 rX ^-#ָt].QA;j<$7]qoN_1)ɷaΐ@'Z "~=ͻV8B~Eٔa]QCy5."̆+Nk=gĈNaQ!%V 2icW)jquI<|iLӳLs(&qKfJ N]CF1Fp X "*uٙPOQA昁(=;+@2ɱj (NQ Q=)fyD?)IW!QxOokA5\h2zuTAUKA҇'r"@"•eȌ|U !3SݽCT'H՜0c}l+<\ofe; j#rmشݡ̌  /#א\P8hі*PZ1YR9Ϩ*v19z:O21th:=ý8!G2!G8BZC/hMfN$flP~@Ρ@F[;*H:Y۵Zpt* Ei$l©޽LjU*`!+@}k}w0;p7e~_`C(s' Xv&T_tjd]#}8-"xSp0MOѪWUcJhTkzȴA:xYt-e"(U>|lJQ>^tq!tfB#ISxݑxfkhac؜hGIVV~ny JI kBwo+ۙkO(e.&&%P}HB_~BjZp;ԌG?Q_j1k{ 6-z:ל&1_|j7#zƮS/9!1svn]Ĕ;JeJB^\!Nk`<$ŃxGWD! DMݦUr۵ _Yx?W.Q9#5}t`Ƶ~Uh12ҎXҖ=SW;ATSk34g/l\*PJҲtLe5Xh9,kIӦ lԦLYcdeW݊ @k$l$gj+*%;Gk3(^V,wd#R<^kdO:4h[JmxOb;Ow׺գ'uiWJ>v! TBDk +v쎚Y*lŪ-Wܕ[="r68wTZt]-H4&rS$.ۂ#b:5nVuP8Beq6wfϾ=H%7,Q:Wr) =1]J.Q}&y! iH8Q*(?(dʅvnWv9"ɥlWeT=ono}SD [}@(X@-05epGP8)lk:zl*Sw#4c2٦4ᙩ1w!4}uBECAFCVہ'%5)H:t)er8<-p?~~oӹ?}۳/|w>w&=LMzL@c"D-){pʑ0|I_$lؿ/X׋dtS9qn2:- VᗩL5V]Z}#(3h%dus1Wݗhk35ṞnXj'+\-Ltk^dNZ-K bqY) {fj`WiƈhܵbWk)nkФAEEy ξ(G˩9lXha鯜!*h б3挍AҜ EJ%s*NmYq"5N W*SsLwY"wo-bcH&@.۪8Z]!UEA|e€95MJy~hJTlk;ֺ_2)%s8AfQITȂuFYslpIR걋0r>-.4kܖF<%ΨsnMQ\|g~-<;MF6.#]©Jui2b%v: $M/[E&%kZ(R$֡@TBtq4_5Mju;+/ ijaÎ Oiԃ wFD.Ѕ _#3/hz mT[,,j`wi?!\tiAes,ɢ`sΌZ ZmtTh v.8jcY}ݹn=:UҴРN.n+ wH(a0xȿz֖yC16'lS`%@|{4!u Vxc[Cdv77R=9' lVƦJ"M/"ebq!Ъ>,ZXzuG6eJ iK|R7QQR}Pn#ZQ)2cWkMq2Y6B@,eoTXq*m7`˞w@E>_e9-3uB\9;8T"a~(4NbDsnF̶ oߣUkVyr2S8h.2*{aT;Bu'oTUGVP-|M4爃fgXg/4zA2c^1x*1>00#T~ꖵw釃|2 H@l$2uhvgn0T)&L6 183sU#6=d>%TQ-RE w7ռa}?lӧ7dM%T Kaַ Z0PLL@6# 9P 4ؼs[@n7E;\#t3mt;,hnx!b6O[UPfë5.) 밁=7UQXtaOsQWBVJ,kJæg 77s6-PM?T)C_U0FU3\̲4Au6]x"9r[[f[W Z:JvU$UUd!lXE௑V\lH.o%=zsURy0+ꖼ?GI,s!D5En9Y@u/* 24|VZTFv{&C*ԇ:Z,)DIƧ qͿ8:hz2G~C|?(>`_=:'W4Ry0f-3nHQJRÅ釄[7qF|Ii;J>O2&]('}*ڠֶu%A;mEds93,FO$an@c2 h葍FWȫaTOJ FF=9! ȬF֊YVi"ˆArӳSFnpF޵*UH @:\ tLOr cyX_eWA'Ǝ/ 5P^ST>8vitbꭊ%H<+KiBCVTs;iT 'G0K̩|bjcCK4 "ܠbLiHiơؤ:X({riK?6¯`ЅB:5}I`*]9,IA&D,[ ʦznL( .9~E%0Y:T Ff9 -F-/TT&WyE<@W۰WiPm_a.DTbir8cqVG4"A W.[7_*Mr2%سә_:ú(L5RT.Xfo\"׿=n~*VAC8!S *=d"*c0O]JModYg(/R1muj$`|5*ZIcv!/?^9KJ#f7"Nҁ~hB%h%aȰkR!b#g5H' :Iv/ZMi5#Zp=j8 t^\DRG!m0з3){ .޲2zY{6?]`j=4 z]"gGRKҳͭd2RWD_%sgQQTeQ7y%N0ԸTaG0][i@˘Xä WX(Gdž~vKr}ԡ;FX}DnC=M-F;UϲCXoHS/zȼMi.Qz^8bkǁ"V,=*@l=slxSPil<D2f&H_.6ǥ +K"'P953`/K(O+f;˾:D7Utw'ɑye< ǹ[W[8|DT]?35ifwSAu47C]FT$EU~8B+FڅNZ#ӷzdՃb=x52HxNj 8(fQ2\FI:6S U%C"*Z:lxh` _h|o/{YW҃K-|}}w~G?nh)skf3ѩOꆒ[S#﫪\6`^fF$h#g9ћa\^Ffm`cH22O DKB&Iڞ`W?AH2p^k6Jɱe9DU 8:EP˴m">K39 D"$vUàc$YLod0+?]̣&[_ M˥'s(F ze*]:ƦN?q.) 6~44' 6~&i%cJ ad}а$cgpHi ~S!.X# _21[fIg7) E'1:ovY%MܝLH5Ki p-ŗHB[:{Yq˒_^ 28SeKGL3v I֓Q^#Y<- e-#:MU5߾KpZ"XNO'JpG^CFk`Szx-s!p=ږoY4?뱙΢7Wi4Hk(能<)?}&^r0պ +쌀FFPwM)]SQe{O O~Hwn:9pȧ>Rkn\},X}dt6_q^iXtBdUn)FuX ~~6d,rh\| yPF؏G?MFO_oR0grTDm.}(,Њ@OߙfLP!'f Zmrl͓݄z5i; NsjaÇK}43o+L!AVvΝgܜ+N4Mr{R.`e79#xa}Tw5Ӌy2]25Յu2`]ٺ: 0pš }#MjcTDi! wպ'jsQ'g=,f~jhCv?zi;QmER.U(Ǝv``t4Y]&{%}qvM~!@OEϙ*p1zB|i–2I.u:H"N)uZ.о1`si$hC;~RrUd h:Bʏ?X/oFC3=Ěqp_]=L !{S#9R+Eg4M=<ڔF iOw6,"`צ|OX²;խMº1K4duE "jd,`ueۀuikPL;<(CCRN*tZ5ƺj_:D1ŀܙJ8W]YPumZO}mIpwe/21w4:l}?;!g4H;VftH i\ZZJ7xS:UZ0(X>OzP_ڸI23`mk|Q1GKE=|Jomkiz r3+( ^ڃ=TaM4uV zqo"HMZee(d,ҟ*]2o`"g|nBkkV/EqI,k]>`$RY8m[Ų?8! 2{ѨL*fQf9#kUD0)_R ;‹9vd|v|JD3|q?YX¿?Ȁ%v5KNQ› ƒ1gP'>e% ;";r##`'-&PTD";PIr)!8A GU-uv]hȌ#WdD t)++hYCleXH.B-I+#8q U ^O |zՂ#%玺0LI/݁(JPz$2gR݋.1O8(>2K^8ub'a8ӧW:aGAP #GiniA`{%dQ{gfGsqL@Vϓ XVX9ͦZրjF YFM ꢐq6Xza]~Rc)*?P$tGj8_蟉ked n #` -C&j"0MIuB&4ZQo'x,OAnP6z^ns zN!4Wj(ҵk_.8a]0@g4Z@* >`K$ >ಬ5eHa#wRE9 J/4Sr_DQ,D>gЉ :@ݾxuWNY|[2f)xIC1j=(Iʘ4k3k<}ZB@Vvu F\H'5p8~DMmA{O)z !itW2f#'K^@mL 媸aW2*BWIГ7>_4rxNV}.V)xPZ%1?|>?/$>~x_|woo_>/oG_y;ODւdht E: ˴ x귮[^mIב ./nFYQo R׃A@l$b͘F,>Nk;k~\ }e*eHgs;C]<,QH96|PaKBj>h`+3%ӋLK_ ?Ԋ z%Q!ei,bH421RCȳsQ8w9R5W#m;*S\]'=_U*41̋ ވgNeU\ G:¼RAF#_FA }h/J<3mqqpN%v", @(Y ycǡ .:)*r,(z'*e%N@xA^F죪1dEԅ(Ch9;(;c= 7:q syMPts]7 CN(N( vR׹ou< cEv h#b>_1M"mݍ`8SʱaY?*>*M)r 3n#:g.Zh-aWMU581Lp Io 꽱b`Hbc's$H T=6*Qa9tQM9D۠`0>ON1<=F(_]WkP=:iHM휖v!*"(>nr G}F^aw_낔o&*;Eܿ kYDžXӌ`h< 7`6FEI_HJǜ#.$D]N+b6U`ZATz8;PMb: D2?!\;@mK]69Ew8r"C7Rvͧzl:8hbDg8$QwDTM#1/~1;0 dKs]AQ77enATq in>Ԩdͨ] _R@uFF!LRh(p#?J [O3xewN +&K/@l\\&dNnr3@F{x 聞e5o\sGv6M["mx=,zLCMD?$7w%VC|RG =+NY7je78RdcߘYE#"(ʛilEpR.6e*,+%QwFfc -Tr7($@9@ bհ\\gV_.* &{=;",ײ`zmj\Ba3Y@XR6H+6go ˊκA}A(rѰ{QҚj~:^\y *HBɭuŇPfi%zA|'Of,ʱu|i|jz;yV5A  G, 0)^Q~/N"df8癹xCK qP&%PEXu7HX37T~ݠHa0zRDqik(hS+@ 5 kĿtv]aj81oayGK B }\pZ'Oܘ 0עa5. *Hy$gۉLYE4oaE VJ{$.F^G} N95Js']vg#Sn*n|)iT4ڱ\YL?=<1Y%/arԎxE?XǙ@ƅұ6.*؊(kϱlᚓ#IJ D(M~:|Oj!:5O/_ GdL밞.vv-O7xagu.XFѸzJܱh/M}"cb}MΊS[`3pt7웖A1CmkA5G>!0QBLqEM)T'$:p/im@Ꚇx&Z'fRqAz=/Xё'S&@i(SNiXQPGgwpbB@3/f_?~ ;*hjy:L;|Ў&ٜ*NߤF#Q']^XNԌIG1w@Xxv/HBpL61iq' x/T|hzxʻ:$L17a=[N99WH1D\&s 0#Pgbx]E>z<Mgu\qCjۍ*;_8/`}$OƐIA$h 8ݖiva"0W]Uc0OA>!la(H (bYyfuBa(F=Gxz؀G) R-gB`*:aII4F%(Ovb4icn72"9>ljZ)XHxQFE^O |BmF`s#Y: ܟȋ\ӱQ:C*F0 )ːFik<<>"H$shx8G Dfƕ tAz1@f%xO! 1P)ImߓQ@g ]e@!#Ę ɔvHMexe$i>:Ƹ" JS>ru)}j0~vօbv`Dz-ҐP|e69uJa ps$ G#]+c-*U(l |~l]Eꍌa`79aY$&`H=!L䦎B,+. TnJ%4P+[ !ʚ4:'?)UxžhVq4*g)M3 ?~:!PeSCQh55/A͚ =#=X爴YK#lBz:7喅bv"^DmЖ̡<%pqI仗 G<ƭ;!`Ӏ/=9N8 cF}2!#"aoݸSAh}FE-c" aY):v A0fu^vd HԼf}~eGO:Tx<~? sb}dxwexxxfixtv]/_~^Yݬη%.~>Z/67_W?nnvߴs(oV; HvO/Wۏ"'_G]ju>}~j= Z}^y[%aݯOyo6x X3xG=0 `p u, n v\@lp"p^=pE,5 ,WhQѰ̐EȒW0U~sRea[uя/|qAmٍ5)RE}$4h1J)h=Vry *輔(Gʅ"GI;7V;g] "r5JEJDR+^b1S98̵xkW)gi .`Yu$X5'CS>N\{ B (5[9B4 th# miZ#|YJӎ]fLzfDDvxOɖ 3蚄+@K0 4]GF'%bIŊn<@V/5,8`?| YS0"!'([9քMzF]g zuq\2!&x.q;JdҚ,=wYɺbkl-Ү;=#E:ꤔ&sL:d ^T@ gȫ R#Xp{!WvmpEw4Fz,Tzi T:Gq^`L `H b(lѩcр+*e4/!^]WW!3*ܚ>".NЙ pYDogs3Ʒ(7f5 ,vv_kZ&æƦ.{Ȯ]rxm!~D9CLV:Uz6ƨiL!9c,5s:l48;\4!RaߛLX**U6S$@N=- z4١ER֨ʹ\\"Cg gdq9̘1ť`Ye0PsjE]DG-8VSOυ*8a\ &`c[=9'ݻ`" a }mVZ[ h[!Xa CU֐BYDLރ4OaGB]"H$#kaWŏb^S":Bnb&h/}֋ݷU/){loM7QKjojF6 &$^#+?7a`&ajs!amN/&쀧 V(]MZd'U.C)A_ ͛M`AbKw^Rbt2Qkil`V6 endstream endobj 35 0 obj <>stream HW;r,;\C$>a.nx2(&P:N($ަ?>?v!j>P}- /?-;LR0K]6 T.pn.0 {翭ylH=tЦ[.{O(Q&'*on`p]CE #{i-+~L7 ӹOmҽ86e+j T}BK#e_olQ83lHr2{PP#Q Nǝ;+|Ice>^+vqCJ9`HWqq䍫+2o˗%m|)5Ra?pU ݢH/Ϳ[Խ V_32ׂ_ rlam٘2*Y27R*B> 1ٸ3.p|R0-gI+(AEoF攘͎l@r#: l:B+xNVtR"6x['xa4\$at$mB0kPpZ>clHk>^!uQWdKwd8֡UX+iR0ӂ6jPشbq^cw5Y-aұo>OI{~[-$t@SIF?QL |Y,ۺG <ת9(H* b`t*3~WaJ]z[ha}{Υ`BixVx~=`[lwU$/}td嶒KO0+vkJZƒ+MSсhVix7s:fTZawC:ާ9xG8RG%o[XLT5VWq*zkU`|Vdi#Y^z1&$/QFۻasr7#'ztMƌG1\|`=GPq˴cP|nU2,K"0r }&H}T8Qq >uu^Z/6ű;,'`{CxK\c~:bDαFE,6.^hJ'A!:Sqx\P,n޵M}3WΑ)mO,&X5 V:8c2Z1@B<(g`N$HYXh^Tp%=xi)+ qA*ӻyUʎ꧃ ~a}`qf5 >%warmp ]z-3[a;^+o$occ$% y*ֵ3a*;Bz/3V֛V B£33X!qX̘jWRX?ߨ{#Xo ' c3!pJjCMaH_ Q\[W)t+4`R"~ `Rlc`X R1+\3oԌKD+I vJ^J Zf[;em5]߫>*Ni\_cM?e,Etם5( m@Fr(ڏM҈7B} ӏν^\_Z;Wͳ\k _Ԩ"%2IU.epFi=my\y\\0Y 6|}nhK;\ɢrjuƵ 8uPE{ulV#$x\93pMx`/Щ>~ôtn&>]AcmYˑ)LNЇշ42D~+tݪ}dN#%H_]g6 !0׮e 1xM's6!tZ5{Q/RLa8xʷɍu2+ 5*"O#25|C^F1K٩YIzmJ~|%s?A)gӊsZI\;|UJV rG8I V8P\LF 8.q/3(\_Œl%Scy+aI1Gb nk9 }XaG1١Q`PKVU\5@^قߒ1r auKXdA[QiqGkK8(f O{'|ֿ;rHWQ&W=-iYCڗ[cֳósW4 J1U3?)j{W{ +9Zz@c4iVs8ϥC7qkM1]f, xDk':{)ӀN:o? J(H{T5RWkR;#Vԗ-aըS}M쵾$>vI79s֨$ń-. dEAd<wplOS[ɊQ*{0F8 ٥rтkM..'ka6\l%'AOު-l?~zX`d*'x'̕SQsn}?m1)Jĵ&;b]5O5dݎ|Lpu]HA})X=-K/mم_z ]%Qugb!hfڔ[^V. IkY_$i1u`q } 2mu:\I >G$fa>F[?JFSH5B^sX Is,QqLFﵞ@N5Fm6y!_C N#V9 RO SH:(1!'x8K^-+A[0s,b]Ԍ+$RGu2`K96 7I2ۭ:?X~._ҋ}Y'h9SY˸wTgfCRV+|/SkcL9 t]unU.Ծ==oX+eZfp]kK2Q:p Yxx3Pb`*K f bb6ʖko/^ٸR'ؔAf=/Vs:^ -^Z:nK3fr*Yn*b`<`/w2;#>S-)~&)|Dx~U]i 9#Ցz4%$u IN5ȩH54LB9(Fs CG|T4 Z!Wtr 9КRȭq!fkvJG𸦕EC #{wt71H•s+5Va;x/!/ν=g5` k*m@YO?a1JȬ$i\FdV 9\:jI9{'ֵkUU.gwˮt΂q[@! Yt~epܞkz1tHldL߲uFP6k;HkgO}DE8)7٫k[_荣VK_]\RHIB`;OM'nȦ8<\ZW[=|#f¬|f8{@ f3~} }VOi߁sM*pvAc8O.pp~{H`!(K}fREq,"@Sc`awzA)k}tIkE7%P`B% Vf`y' {:"Elmu\{kt5wߡʦN~Kc%wytkxs3 P׎'6G]jbp1,0(i}g 2bWu )w%NH+6}Q lCYQU W2=6 c^kF,xڎ p&1X2i(P@·$Ѐڦׅn h3U뢷 ׸p[v5P֭ R0(= ny/ZTyMI{JZֱ,/U F  `7ɭRjZCǝ#]^37_dA;K NW+yˡ,ZQn'1k9cAʫÆhZ Mň5AdM.35 ltb4w>U8lJ"h^C5wCizAwD0?<84r Nl-^uf@j՞/Wˬ^R:,g °-]ŵ>+]40 0Du1h+S8G>K+6"XY k\մμWiW/ZNf%^-`η|K{5[y xyZ;h?sԼzl3b@ȵ8ie ~j7%p{gU =. rtʰ/p@ Wi2AX{aea pRr}&Y x~ q}*E {6l錀ɒIpĜnŅ'Zi;z iq7 ʲZvF{|~Mzu7KX&8  0мLLpqj^Z Ҙ0O%IW ];\[m Ae&b*A`dP˹1^w?I’x,‡w2OA*!Rxm_xkg$c(񗰱7 nGmƲ ^#TB*d@? Ɉ~O3qs >Fr">^ cKAymcFM9##Ou]Z1/G m|.p/ko|AViucZL#]Z !?6S< O|k^ a΢o4>iR3+/@"(>9XPbج9X^8 ]eLY$ `MQʷ +/&Bd*dꁚ #ƨ=9ゅ`ɳX1TaudNY}pb*l K ][%M4_}(=ˑ{v~_L"4@ug}>jhBe!P>6r!;9IQ #*p:k}`Pq븡OwE=r6ifYuQJZC+<}HWZ@S$rHyxCb[^R%FnSj&xk= 09" Z㐁a08cnB'hhJkHi|vꀵ{|C}C'ew ;3.&W)Yo^i**-Z;T;3,|ԨȠ߆ț =M]xV;y,GBM3@4smVڋ81&L1Y'&H{mYM@]/_hliƪQ~mțXRYkmْL%QV"jɋ"3tPW]-Ӡd0Z*5K 5HrcU 06SL}tŋNe~%p6>5o:)bl%K騬;i}yc3WHKo#,nSgmLwFt<9" S9WEwwO;'ߕan 2m~n蚒$ćR`#2@`0}\Rp^N4 +E:v>t~]I޴F.tjFQH J▖AKԙAW~W耆 :P}D"W7*-RQ,@My}BV,*S30ꌽEFWz\*2*2\\t4UU!-hbY~mh+PwП4 iӞPGz[mE:@ $3W (:xL9s6|R!X+S1%v{cvH,+}pN-M&.=+J!H0 dcԳ]A2(YY| qDX`<_@Iy Ơ;j͝my)F-^ZrkP"0:+A%K!#^A,Ns*BdALm\QwHR"n׌,kN-J|RPh8k1m25$LfGRL͐|fej1kXԼ֦N}`z@$L82WeثNCYJk%;"khSrQcKeo2Ͼ=ԁ}_H+ugtst›^(A[yN:!uY}|-rQ`(OM %&$4Q)'mA#麪h R5@ y:4CNZb&g8഍RF+8c۶mG/+eX,6@ayw%yOԜ}-a qW <] i)$v6% &'B:)Ոz>^% n` VuOnb{=L=_?ugIir $ΚJ]- ϼ alĝ w4Q-hꉗb?_} ٲxcgZ"{ .߇& Il E݄ăЭ]ޣew?GK0+ YCkrU4~7PQՙ)@cog(1 jJ,ól pvgu?af.֔pD@[Ӻڻtڹ] {v!ݼمGs`u߇;C$jG_LbvDKjodX5Y =?Lu { P(Z$k9{}PN]XET\[--ZMt;hd+P|0hߴgMW0l6C3g^%eߞ_'>{<ȩŧ8eie" :VM}`ꢲ ?RkP|wwtetQHVxRtCYI $$* !8eT&}j0cG'p ׫׋fzyrp?LE:7Z,afbٓ/ǯz5]߾?v\-Wn?o7Gbyw=vFܾo?{=zZoϾ^\l.} +rO9ftHztbft8o>HnGGr{<__,j3؜.4V(8#TXz/_]NGa5{xXr<o)94:Gc-1wpw<1fYLW_w%>'AOB:]xq3߼3vOC4i͘]/_\lv?NGj>.߼^WÏyzL w~ |6|7bZa(d,Q36!'B/C-yȏ׋x9_q\&?ٯݶq(t1tv'MZmp.Z2YӢGgcFc$'P|7"<=Mؿt4QN'p& 5iEq/1-?؊C1p.-śVڅk=+´Zq$rVYfVАɂa4*F5ˤRQү%7 {z𢅿Ihaoojj_8uY-Q%\4`|YcQhf}KTDJ,U}s(m]'D9SB͍e9~_<455& kvfCޥI1B8yNNg,v;ܴTx؆}31c4ٽX8џ dCu4Dp\+4Zb#>Ti뉮҅|S@$oʡE{<o޵u}>stream Hn:ƟZ$A+;FbS#-EPgۻ}e;ӜjSkmxO3曉\Zc!Ug˿$U-qh˷iv"Z :a_8IY7>L,z)xnߵ=p%A/7 `OZ}YDe5þH"\K*JPQ MpNz*THS+J XD\8Q)7E7o'#.ا[ky>BkNc1Zu&Lr_ @X1$kMu6\BSÝymj`ĭi鷰dbsl1T Li}h;9 u.pSHF%[e7A.ySM ;!#[="4Q }Tz<&}:럗^=&we)qqcQ8pRs.v7@n1 5䲐ͻQgdC7yKGPǦ$.swaq*v5yJUh^ Wv;,*A FW]$U,pV<,U yG!)OZDŚ翻ȞUG⿇o&3P})ƫ,|c^CY^7SsjӖ+٧5ۻNhѩo"nzn(ͽfy?QV3|\qFwq%Ǝp|E%(r pMpܫ&sN)Rna_J#ٯg+Ěz5/i<]s{. }^'G7yGvAܪhs{A'"$m3Wdf #pըYg<c pA&Y@o$pyJje8΂fv ~6΋peKʈEDd@+CxSH 5#K? InGic42I\pj5 pwƓr0E纇q*,dbU6KET4&m'9an>?,JFgY/xwY+>OS&)&k?HbYD-קB.>99y3twY&dI莆NgH]֘qD&j840FiƐ4o&Ő}1JK*u7>_/ߥ褏LVB1A>| \U!CsXw<.tj?KDAjG gCb:LܢF͠ -g~,LЕLd<9 }(m6?=YsR%BI9 g!miL0 +T)9TŘSRfgq6M9ȁ+??ɂ},{#[̦ytBwa"sC ̀U<%U2nXDeJ{.Đvro8:mm )hâdt~地ۡIem^r~U. \j!9,D;I):0@XS T1.`}z*?ŀS-xzAη^'G7yG}i]W [`!ùPӯ@YdG3 5UA9Q|(҄B\/ 1Vu)RcQCq 0Yg4&fHw |[¬\G; 2S`ЕU^B4qm6?:Ys4\u`cEwdb `d4nx`(V)9Tc6ʆC^DZݫ^ս?W߫:Ef'1%^ޫf"a̮S9j-ALU5e-lhLkJ|j;%n^.{d[d!C1Cܢ<,e:5sX:QƮOmZ ejϮ;…c~<[K94Wk^Fη1+*rqw&#d{0ԓJ/Rt!l(.{zTVI fʜ^_`U@?V &e7ܧnIa4m*k| 9!1*)4LIuXgFWLbmv4'xr㈱V$5]^Sٝ`&:0GedzغNqrqkU&kND]2NPfg# ʢjܟ j(oi|LEٓށdFJhLUmzXopc .~<#8Ap f /)N)+2<5tnw5Kp**ɸI(<P|`HJkCFchl=?Ka(: O\g6p@Ūn~SjNU#3KpТ?=jp>nO~\O!k7ϯ۔֔C|=u^>洠 endstream endobj 8 0 obj [7 0 R] endobj 37 0 obj <> endobj xref 0 38 0000000000 65535 f 0000000016 00000 n 0000000144 00000 n 0000048349 00000 n 0000000000 00000 f 0000051783 00000 n 0000052009 00000 n 0000051597 00000 n 0000307125 00000 n 0000048400 00000 n 0000048784 00000 n 0000071190 00000 n 0000071077 00000 n 0000050650 00000 n 0000051036 00000 n 0000051084 00000 n 0000051667 00000 n 0000051698 00000 n 0000061875 00000 n 0000052369 00000 n 0000052637 00000 n 0000062134 00000 n 0000071264 00000 n 0000071702 00000 n 0000072709 00000 n 0000077968 00000 n 0000095118 00000 n 0000110451 00000 n 0000126749 00000 n 0000140437 00000 n 0000159313 00000 n 0000183229 00000 n 0000210715 00000 n 0000237925 00000 n 0000264762 00000 n 0000291193 00000 n 0000303297 00000 n 0000307148 00000 n trailer <<4336D061D10542699B0CDE57451E0D75>]>> startxref 307335 %%EOF organize-1.10.1/docs/images/organize.svg000066400000000000000000001743461403777030400201700ustar00rootroot00000000000000 organize-1.10.1/docs/index.rst000066400000000000000000000011201403777030400162000ustar00rootroot00000000000000.. image:: https://github.com/tfeldmann/organize/raw/master/docs/images/organize.svg?sanitize=true organize ======== organize is a command line utility to automate file organization tasks. http://github.com/tfeldmann/organize Contents: --------- .. toctree:: page/quickstart page/config page/filters page/actions If you find any bugs or have an idea for a new feature please don't hesitate to `open an issue `_ on GitHub. Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search` organize-1.10.1/docs/make.bat000066400000000000000000000014021403777030400157470ustar00rootroot00000000000000@ECHO OFF pushd %~dp0 REM Command file for Sphinx documentation if "%SPHINXBUILD%" == "" ( set SPHINXBUILD=python -msphinx ) set SOURCEDIR=. set BUILDDIR=_build set SPHINXPROJ=organize if "%1" == "" goto help %SPHINXBUILD% >NUL 2>NUL if errorlevel 9009 ( echo. echo.The Sphinx module was not found. Make sure you have Sphinx installed, echo.then set the SPHINXBUILD environment variable to point to the full echo.path of the 'sphinx-build' executable. Alternatively you may add the echo.Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from echo.http://sphinx-doc.org/ exit /b 1 ) %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% goto end :help %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% :end popd organize-1.10.1/docs/page/000077500000000000000000000000001403777030400152615ustar00rootroot00000000000000organize-1.10.1/docs/page/actions.rst000066400000000000000000000010231403777030400174470ustar00rootroot00000000000000.. _actions: .. py:module:: actions Actions ======= Copy ---- .. autoclass:: Copy(dest, [overwrite=False], [counter_separator=' ']) Delete ------ .. autoclass:: Delete Echo ---- .. autoclass:: Echo Move ---- .. autoclass:: Move(dest, [overwrite=False], [counter_separator=' ']) Python ------ .. autoclass:: actions.Python Rename ------ .. autoclass:: Rename(dest, [overwrite=False], [counter_separator=' ']) Shell ----- .. autoclass:: Shell Trash ----- .. autoclass:: Trash macOS Tags ---------- .. autoclass:: MacOSTags organize-1.10.1/docs/page/config.rst000066400000000000000000000222451403777030400172650ustar00rootroot00000000000000************* Configuration ************* Editing the configuration ========================= All configuration takes place in your `config.yaml` file. - To edit your configuration in ``$EDITOR`` run: .. code-block:: bash $ organize config # example: "EDITOR=vim organize config" - To show the full path to your configuration file:: $ organize config --path - To open the folder containing the configuration file:: $ organize config --open-folder - To debug your configuration run:: $ organize config --debug Environment variables ===================== - ``$EDITOR`` - The editor used to edit the config file. - ``$ORGANIZE_CONFIG`` - The config file path. Is overridden by ``--config-file`` cmd line argument. Rule syntax =========== The rule configuration is done in `YAML `_. You need a top-level element ``rules`` which contains a list of rules. Each rule defines ``folders``, ``filters`` (optional) and ``actions``. .. code-block:: yaml :caption: config.yaml :emphasize-lines: 1,2,5,10,14,16,18 rules: - folders: - ~/Desktop - /some/folder/ filters: - lastmodified: days: 40 mode: newer - extension: pdf actions: - move: ~/Desktop/Target/ - trash - folders: - ~/Inbox filters: - extension: pdf actions: - move: ~/otherinbox # optional settings: enabled: true subfolders: true system_files: false - ``folders`` is a list of folders you want to organize. - ``filters`` is a list of filters to apply to the files - you can filter by file extension, last modified date, regular expressions and many more. See :ref:`Filters`. - ``actions`` is a list of actions to apply to the filtered files. You can put them into the trash, move them into another folder and many more. See :ref:`Actions`. Other optional per rule settings: - ``enabled`` can be used to temporarily disable single rules. Default = true - ``subfolders`` specifies whether subfolders should be included in the search. Default = false. This setting only applies to folders without glob wildcards. - ``system_files`` specifies whether to include system files (desktop.ini, thumbs.db, .DS_Store) in the search. Default = false Folder syntax ============= Every rule in your configuration file needs to know the folders it applies to. The easiest way is to define the rules like this: .. code-block:: yaml :caption: config.yaml rules: - folders: - /path/one - /path/two filters: ... actions: ... - folders: - /path/one - /another/path filters: ... actions: ... .. note:: - You can use environment variables in your folder names. On windows this means you can use ``%public%/Desktop``, ``%APPDATA%``, ``%PROGRAMDATA%`` etc. Globstrings ----------- You can use globstrings in the folder lists. For example to get all files with filenames ending with ``_ui`` and any file extension you can use: .. code-block:: yaml :caption: config.yaml rules: - folders: - '~/Downloads/*_ui.*' actions: - echo: '{path}' You can use globstrings to recurse through subdirectories (alternatively you can use the ``subfolders: true`` setting as shown below) .. code-block:: yaml :caption: config.yaml rules: - folders: - '~/Downloads/**/*.*' actions: - echo: 'base {basedir}, path {path}, relative: {relative_path}' # alternative syntax - folders: - ~/Downloads subfolders: true actions: - echo: 'base {basedir}, path {path}, relative: {relative_path}' The following example recurses through all subdirectories in your downloads folder and finds files with ending in ``.c`` and ``.h``. .. code-block:: yaml :caption: config.yaml rules: - folders: - '~/Downloads/**/*.[c|h]' actions: - echo: '{path}' .. note:: - You have to target files with the globstring, not folders. So to scan through all folders starting with *log_* you would write ``yourpath/log_*/*`` Excluding files and folders --------------------------- Files and folders can be excluded by prepending an exclamation mark. The following example selects all files in ``~/Downloads`` and its subfolders - excluding the folder ``Software``: .. code-block:: yaml :caption: config.yaml rules: - folders: - '~/Downloads/**/*' - '! ~/Downloads/Software' actions: - echo: '{path}' Globstrings can be used to exclude only specific files / folders. This example: - adds all files in ``~/Downloads`` - exludes files from that list whose name contains the word ``system`` ending in ``.bak`` - adds all files from ``~/Documents`` - excludes the file ``~/Documents/important.txt``. .. code-block:: yaml :caption: config.yaml rules: - folders: - '~/Downloads/**/*' - '! ~/Downloads/**/*system*.bak' - '~/Documents' - '! ~/Documents/important.txt' actions: - echo: '{path}' .. note:: - Files and folders are included and excluded in the order you specify them! - Please make sure your are putting the exclamation mark within quotation marks. Aliases ------- Instead of repeating the same folders in each and every rule you can use an alias for multiple folders which you can then reference in each rule. Aliases are a standard feature of the YAML syntax. .. code-block:: yaml :caption: config.yaml all_my_messy_folders: &all - ~/Desktop - ~/Downloads - ~/Documents - ~/Dropbox rules: - folders: *all filters: ... actions: ... - folders: *all filters: ... actions: ... You can even use multiple folder lists: .. code-block:: yaml :caption: config.yaml private_folders: &private - '/path/private' - '~/path/private' work_folders: &work - '/path/work' - '~/My work folder' all_folders: &all - *private - *work rules: - folders: *private filters: ... actions: ... - folders: *work filters: ... actions: ... - folders: *all filters: ... actions: ... # same as *all - folders: - *work - *private filters: ... actions: ... Filter syntax ============= ``filters`` is a list of :ref:`Filters`. Filters are defined like this: .. code-block:: yaml :caption: config.yaml rules: - folders: ... actions: ... filters: # filter without parameters - FilterName # filter with a single parameter - FilterName: parameter # filter expecting a list as parameter - FilterName: - first - second - third # filter with multiple parameters - FilterName: parameter1: true option2: 10.51 third_argument: test string .. note:: Every filter comes with multiple usage examples which should be easy to adapt for your use case! Action syntax ============= ``actions`` is a list of :ref:`Actions`. Actions can be defined like this: .. code-block:: yaml :caption: config.yaml rules: - folders: ... actions: # action without parameters - ActionName # action with a single parameter - ActionName: parameter # filter with multiple parameters - ActionName: parameter1: true option2: 10.51 third_argument: test string .. note:: Every action comes with multiple usage examples which should be easy to adapt for your use case! Variable substitution (placeholders) ------------------------------------ **You can use placeholder variables in your actions.** Placeholder variables are used with curly braces ``{var}``. You always have access to the variables ``{path}``, ``{basedir}`` and ``{relative_path}``: - ``{path}`` -- is the full path to the current file - ``{basedir}`` -- the current base folder (the base folder is the folder you specify in your configuration). - ``{relative_path}`` -- the relative path from ``{basedir}`` to ``{path}`` Use the dot notation to access properties of ``{path}``, ``{basedir}`` and ``{relative_path}``: - ``{path}`` -- the full path to the current file - ``{path.name}`` -- the full filename including extension - ``{path.stem}`` -- just the file name without extension - ``{path.suffix}`` -- the file extension - ``{path.parent}`` -- the parent folder of the current file - ``{path.parent.parent}`` -- parent calls are chainable... - ``{basedir}`` -- the full path to the current base folder - ``{basedir.parent}`` -- the full path to the base folder's parent and any other property of the python ``pathlib.Path`` (`official documentation `_) object. Additionally :ref:`Filters` may emit placeholder variables when applied to a path. Check the documentation and examples of the filter to see available placeholder variables and usage examples. Some examples include: - ``{lastmodified.year}`` -- the year the file was last modified - ``{regex.yournamedgroup}`` -- anything you can extract via regular expressions - ``{extension.upper}`` -- the file extension in uppercase - ... and many more. organize-1.10.1/docs/page/filters.rst000066400000000000000000000010271403777030400174630ustar00rootroot00000000000000.. _filters: .. py:module:: filters Filters ======= Created ------- .. autoclass:: Created Duplicate --------- .. autoclass:: Duplicate Exif ---- .. autoclass:: Exif Extension --------- .. autoclass:: Extension FileContent ----------- .. autoclass:: FileContent Filename -------- .. autoclass:: Filename FileSize -------- .. autoclass:: FileSize LastModified ------------ .. autoclass:: LastModified MimeType ------------ .. autoclass:: MimeType Python ------ .. autoclass:: filters.Python Regex ----- .. autoclass:: Regex organize-1.10.1/docs/page/quickstart.rst000066400000000000000000000030751403777030400202120ustar00rootroot00000000000000Quickstart ========== Installation ------------ Requirements: Python 3.6+ `organize` is installed via pip: ``$ pip install organize-tool`` If you want all the text extraction capabilities, install with `textract` like this: ``$ sudo pip3 -U organize-tool[textract]`` Creating your first config file ------------------------------- To edit the configuration in your $EDITOR, run: ``$ organize config`` For example your configuration file could look like this: .. code-block:: yaml :caption: config.yaml rules: # move screenshots into "Screenshots" folder - folders: - ~/Desktop filters: - filename: startswith: Screen Shot actions: - move: ~/Desktop/Screenshots/ # move incomplete downloads older > 30 days into the trash - folders: - ~/Downloads filters: - extension: - crdownload - part - download - lastmodified: days: 30 actions: - trash .. note:: You can run ``$ organize config --path`` to show the full path to the configuration file. Simulate and run ---------------- After you saved the configuration file, run ``$ organize sim`` to show a simulation of how your files would be organized. If you like what you see, run ``$ organize run`` to organize your files. .. note:: Congrats! You just automated some tedious cleaning tasks! Continue to :ref:`Configuration` to see the full potential of organize or skip directly to the :ref:`Filters` and :ref:`Actions`. organize-1.10.1/main.py000066400000000000000000000001051403777030400147070ustar00rootroot00000000000000from organize.cli import main if __name__ == "__main__": main() organize-1.10.1/manage.py000066400000000000000000000122711403777030400152220ustar00rootroot00000000000000import argparse import getpass import re import subprocess from datetime import datetime from pathlib import Path import requests SRC_FOLDER = "organize" CURRENT_FOLDER = Path(__file__).resolve().parent GITHUB_API_ENDPOINT = "https://api.github.com/repos/tfeldmann/organize" def ask_confirm(text): while True: answer = input(f"{text} [y/n]: ").lower() if answer in ("j", "y", "ja", "yes"): return True if answer in ("n", "no", "nein"): return False def set_version(args): """ - reads and validates version number - updates __version__.py - updates pyproject.toml - Searches for 'WIP' in changelog and replaces it with current version and date """ from organize.__version__ import __version__ as current_version print(f"Current version is {current_version}.") # read version from input if not given version = args.version if not version: version = input("Version number: ") # validate and remove 'v' if present version = version.lower() if not re.match(r"v?\d+\.\d+.*", version): return if version.startswith("v"): version = version[1:] # safety check if not ask_confirm(f"Creating version v{version}. Continue?"): return # update library version versionfile = CURRENT_FOLDER / SRC_FOLDER / "__version__.py" with open(versionfile, "w") as f: print(f"Updating {versionfile}") f.write(f'__version__ = "{version}"\n') # update poetry version print("Updating pyproject.toml") subprocess.run(["poetry", "version", version], check=True) # read changelog print("Updating CHANGELOG.md") with open(CURRENT_FOLDER / "CHANGELOG.md", "r") as f: changelog = f.read() # check if WIP section is in changelog wip_regex = re.compile(r"## WIP\n(.*?)(?=\n##)", re.MULTILINE | re.DOTALL) match = wip_regex.search(changelog) if not match: print('No "## WIP" section found in changelog') return # change WIP to version number and date changes = match.group(1) today = datetime.now().strftime("%Y-%m-%d") changelog = wip_regex.sub(f"## v{version} ({today})\n{changes}", changelog, count=1) # write changelog with open(CURRENT_FOLDER / "CHANGELOG.md", "w") as f: f.write(changelog) if ask_confirm("Commit changes?"): subprocess.run( ["git", "add", "pyproject.toml", "*/__version__.py", "CHANGELOG.md"] ) subprocess.run(["git", "commit", "-m", f"bump version to v{version}"]) print("Please push to github and wait for CI to pass.") print("Success.") def publish(args): """ - reads version - reads changes from changelog - creates git tag - pushes to github - publishes on pypi - creates github release """ from organize.__version__ import __version__ as version if not ask_confirm(f"Publishing version {version}. Is this correct?"): return # extract changes from changelog with open(CURRENT_FOLDER / "CHANGELOG.md", "r") as f: changelog = f.read() wip_regex = re.compile( "## v{}".format(version.replace(".", r"\.")) + r".*?\n(.*?)(?=\n##)", re.MULTILINE | re.DOTALL, ) match = wip_regex.search(changelog) if not match: print("Failed to extract changes from changelog. Do the versions match?") return changes = match.group(1).strip() print(f"Changes:\n{changes}") # create git tag ('vXXX') if ask_confirm("Create tag?"): subprocess.run(["git", "tag", "-a", f"v{version}", "-m", f"v{version}"]) # push to github if ask_confirm("Push to github?"): print("Pushing to github") subprocess.run(["git", "push", "--follow-tags"], check=True) # upload to pypi if ask_confirm("Publish on Pypi?"): subprocess.run(["rm", "-rf", "dist"], check=True) subprocess.run(["poetry", "build"], check=True) subprocess.run(["poetry", "publish"], check=True) # create github release if ask_confirm("Create github release?"): response = requests.post( f"{GITHUB_API_ENDPOINT}/releases", auth=(input("Benutzer: "), getpass.getpass(prompt="API token: ")), json={ "tag_name": f"v{version}", "target_commitish": "master", "name": f"v{version}", "body": changes, "draft": False, "prerelease": False, }, ) response.raise_for_status() print("Success.") def main(): assert CURRENT_FOLDER == Path.cwd().resolve() parser = argparse.ArgumentParser() subparsers = parser.add_subparsers() parser_version = subparsers.add_parser("version", help="Set the version number") parser_version.add_argument( "version", type=str, help="The version number", nargs="?", default=None ) parser_version.set_defaults(func=set_version) parser_publish = subparsers.add_parser("publish", help="Publish the project") parser_publish.set_defaults(func=publish) args = parser.parse_args() if not vars(args): parser.print_help() else: args.func(args) if __name__ == "__main__": main() organize-1.10.1/organize/000077500000000000000000000000001403777030400152335ustar00rootroot00000000000000organize-1.10.1/organize/__init__.py000066400000000000000000000027431403777030400173520ustar00rootroot00000000000000import logging import logging.config import os import appdirs # type: ignore import colorama # type: ignore import yaml from pathlib import Path colorama.init(autoreset=True) # prepare config and log folders APP_DIRS = appdirs.AppDirs("organize") # setting the $ORGANIZE_CONFIG env variable overrides the default config path if os.getenv("ORGANIZE_CONFIG"): CONFIG_PATH = Path(os.getenv("ORGANIZE_CONFIG", "")).resolve() CONFIG_DIR = CONFIG_PATH.parent else: CONFIG_DIR = Path(APP_DIRS.user_config_dir) CONFIG_PATH = CONFIG_DIR / "config.yaml" LOG_DIR = Path(APP_DIRS.user_log_dir) LOG_PATH = LOG_DIR / "organize.log" for folder in (CONFIG_DIR, LOG_DIR): folder.mkdir(parents=True, exist_ok=True) # create empty config file if it does not exist if not CONFIG_PATH.exists(): CONFIG_PATH.touch() # configure logging LOGGING_CONFIG = """ version: 1 disable_existing_loggers: false formatters: simple: format: '%(asctime)s - %(name)s - %(levelname)s - %(message)s' handlers: console: class: logging.StreamHandler level: DEBUG formatter: simple stream: ext://sys.stdout file: class: logging.handlers.TimedRotatingFileHandler level: DEBUG filename: {filename} formatter: simple when: midnight backupCount: 30 root: level: DEBUG handlers: [file] exifread: level: INFO """.format( filename=str(LOG_PATH) ) logging.config.dictConfig(yaml.safe_load(LOGGING_CONFIG)) organize-1.10.1/organize/__main__.py000066400000000000000000000001271403777030400173250ustar00rootroot00000000000000import sys if __name__ == "__main__": from .cli import main sys.exit(main()) organize-1.10.1/organize/__version__.py000066400000000000000000000000271403777030400200650ustar00rootroot00000000000000__version__ = "1.10.1" organize-1.10.1/organize/actions/000077500000000000000000000000001403777030400166735ustar00rootroot00000000000000organize-1.10.1/organize/actions/__init__.py000066400000000000000000000003521403777030400210040ustar00rootroot00000000000000from .copy import Copy from .delete import Delete from .echo import Echo from .macos_tags import MacOSTags from .move import Move from .python import Python from .rename import Rename from .shell import Shell from .trash import Trash organize-1.10.1/organize/actions/action.py000066400000000000000000000024521403777030400205250ustar00rootroot00000000000000from textwrap import indent from typing import Any, Mapping, Optional, Callable from organize.utils import DotDict class Error(Exception): pass class TemplateAttributeError(Error): pass class Action: pre_print_hook = None # type: Optional[Callable] def run(self, **kwargs) -> Optional[Mapping[str, Any]]: return self.pipeline(DotDict(kwargs)) def pipeline(self, args: DotDict) -> Optional[Mapping[str, Any]]: raise NotImplementedError def print(self, msg) -> None: """ print a message for the user """ if callable(self.pre_print_hook): self.pre_print_hook() # pylint: disable=not-callable print(indent("- [%s] %s" % (self.__class__.__name__, msg), " " * 4)) @staticmethod def fill_template_tags(msg: str, args) -> str: try: return msg.format(**args) except AttributeError as exc: cause = exc.args[0] raise TemplateAttributeError( 'Missing template variable %s for "%s"' % (cause, msg) ) def __str__(self) -> str: return self.__class__.__name__ def __repr__(self) -> str: return "<%s>" % str(self) def __eq__(self, other) -> bool: return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ organize-1.10.1/organize/actions/copy.py000066400000000000000000000101021403777030400202110ustar00rootroot00000000000000import logging import os import shutil from organize.utils import Mapping, find_unused_filename, fullpath from .action import Action from .trash import Trash logger = logging.getLogger(__name__) class Copy(Action): """ Copy a file to a new location. If the specified path does not exist it will be created. :param str dest: The destination where the file should be copied to. If `dest` ends with a slash / backslash, the file will be copied into this folder and keep its original name. :param bool overwrite: specifies whether existing files should be overwritten. Otherwise it will start enumerating files (append a counter to the filename) to resolve naming conflicts. [Default: False] :param str counter_separator: specifies the separator between filename and the appended counter. Only relevant if **overwrite** is disabled. [Default: ``\' \'``] Examples: - Copy all pdfs into `~/Desktop/somefolder/` and keep filenames .. code-block:: yaml :caption: config.yaml rules: - folders: ~/Desktop filters: - extension: pdf actions: - copy: '~/Desktop/somefolder/' - Use a placeholder to copy all .pdf files into a "PDF" folder and all .jpg files into a "JPG" folder. Existing files will be overwritten. .. code-block:: yaml :caption: config.yaml rules: - folders: ~/Desktop filters: - extension: - pdf - jpg actions: - copy: dest: '~/Desktop/{extension.upper}/' overwrite: true - Copy into the folder `Invoices`. Keep the filename but do not overwrite existing files. To prevent overwriting files, an index is added to the filename, so `somefile.jpg` becomes `somefile 2.jpg`. The counter separator is `' '` by default, but can be changed using the `counter_separator` property. .. code-block:: yaml :caption: config.yaml rules: - folders: ~/Desktop/Invoices filters: - extension: - pdf actions: - copy: dest: '~/Documents/Invoices/' overwrite: false counter_separator: '_' """ def __init__(self, dest: str, overwrite=False, counter_separator=" ") -> None: self.dest = dest self.overwrite = overwrite self.counter_separator = counter_separator def pipeline(self, args: Mapping) -> None: path = args["path"] simulate = args["simulate"] expanded_dest = self.fill_template_tags(self.dest, args) # if only a folder path is given we append the filename to have the full # path. We use os.path for that because pathlib removes trailing slashes if expanded_dest.endswith(("\\", "/")): expanded_dest = os.path.join(expanded_dest, path.name) new_path = fullpath(expanded_dest) if new_path.exists() and not new_path.samefile(path): if self.overwrite: self.print("File already exists") Trash().run(path=new_path, simulate=simulate) else: new_path = find_unused_filename( path=new_path, separator=self.counter_separator ) self.print('Copy to "%s"' % new_path) if not simulate: logger.info("Creating folder if not exists: %s", new_path.parent) new_path.parent.mkdir(parents=True, exist_ok=True) logger.info('Copying "%s" to "%s"', path, new_path) shutil.copy2(src=str(path), dst=str(new_path)) # the next actions should handle the original file return None def __str__(self) -> str: return "Copy(dest=%s, overwrite=%s)" % (self.dest, self.overwrite) organize-1.10.1/organize/actions/delete.py000066400000000000000000000020431403777030400205060ustar00rootroot00000000000000import os import logging from typing import Mapping from pathlib import Path from .action import Action logger = logging.getLogger(__name__) class Delete(Action): """ Delete a file from disk. Deleted files have no recovery option! Using the `Trash` action is strongly advised for most use-cases! Example: - Delete all JPGs and PNGs on the desktop which are older than one year: .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Desktop' - filters: - lastmodified: - days: 365 - extension: - png - jpg - actions: - delete """ def pipeline(self, args: Mapping): path = args["path"] # type: Path simulate = args["simulate"] # type: bool self.print('Delete "%s"' % path) if not simulate: logger.info("Deleting file %s.", path) os.remove(str(path)) organize-1.10.1/organize/actions/echo.py000066400000000000000000000043601403777030400201660ustar00rootroot00000000000000import logging from .action import Action logger = logging.getLogger(__name__) class Echo(Action): """ Prints the given (formatted) message. This can be useful to test your rules, especially if you use formatted messages. :param str msg: The message to print (can be formatted) Example: - Prints "Found old file" for each file older than one year: .. code-block:: yaml :caption: config.yaml rules: - folders: ~/Desktop filters: - lastmodified: days: 365 actions: - echo: 'Found old file' - Prints "Hello World!" and filepath for each file on the desktop: .. code-block:: yaml :caption: config.yaml rules: - folders: - ~/Desktop actions: - echo: 'Hello World! {path}' - This will print something like ``Found a PNG: "test.png"`` for each file on your desktop: .. code-block:: yaml :caption: config.yaml rules: - folders: - ~/Desktop filters: - Extension actions: - echo: 'Found a {extension.upper}: "{path.name}"' - Show the ``{basedir}`` and ``{path}`` of all files in '~/Downloads', '~/Desktop' and their subfolders: .. code-block:: yaml :caption: config.yaml rules: - folders: - ~/Desktop - ~/Downloads subfolders: true actions: - echo: 'Basedir: {basedir}' - echo: 'Path: {path}' """ def __init__(self, msg) -> None: self.msg = msg self.log = logging.getLogger(__name__) def pipeline(self, args) -> None: path = args["path"] logger.debug('Echo msg "%s", path: "%s", args: "%s"', self.msg, path, args) full_msg = self.fill_template_tags(self.msg, args) logger.info("Console output: %s", full_msg) self.print("%s" % full_msg) def __str__(self) -> str: return 'Echo(msg="%s")' % self.msg organize-1.10.1/organize/actions/macos_tags.py000066400000000000000000000063631403777030400213750ustar00rootroot00000000000000import logging import sys from pathlib import Path from typing import Mapping import simplematch as sm # type: ignore from .action import Action logger = logging.getLogger(__name__) class MacOSTags(Action): """ Add macOS tags. Example: - Add a single tag: .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Documents/Invoices' - filters: - filename: startswith: "Invoice" - extension: pdf - actions: - macos_tags: Invoice - Adding multiple tags ("Invoice" and "Important"): .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Documents/Invoices' - filters: - filename: startswith: "Invoice" - extension: pdf - actions: - macos_tags: - Important - Invoice - Specify tag colors. Available colors are `none`, `gray`, `green`, `purple`, `blue`, `yellow`, `red`, `orange`. .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Documents/Invoices' - filters: - filename: startswith: "Invoice" - extension: pdf - actions: - macos_tags: - Important (green) - Invoice (purple) - Add a templated tag with color: .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Documents/Invoices' - filters: - created - actions: - macos_tags: - Year-{created.year} (red) """ def __init__(self, *tags): self.tags = tags def pipeline(self, args: Mapping): path = args["path"] # type: Path simulate = args["simulate"] # type: bool if sys.platform != "darwin": self.print("The macos_tags action is only available on macOS") return import macos_tags # type: ignore COLORS = [c.name.lower() for c in macos_tags.Color] for template in self.tags: tag = self.fill_template_tags(template, args) name, color = self._parse_tag(tag) if color not in COLORS: raise ValueError( "color %s is unknown. (Available: %s)" % (color, " / ".join(COLORS)) ) self.print('Adding tag: "%s" (color: %s)' % (name, color)) if not simulate: _tag = macos_tags.Tag( name=name, color=macos_tags.Color[color.upper()], ) macos_tags.add(_tag, file=str(path)) def _parse_tag(self, s): """ parse a tag definition and return a tuple (name, color) """ result = sm.match("{name} ({color})", s) if not result: return s, "none" return result["name"], result["color"].lower() def __str__(self) -> str: return "MacOSTags(tags=%s)" % self.tags organize-1.10.1/organize/actions/move.py000066400000000000000000000106221403777030400202140ustar00rootroot00000000000000import logging import os import shutil from typing import Mapping from pathlib import Path from organize.utils import DotDict, find_unused_filename, fullpath from .action import Action from .trash import Trash logger = logging.getLogger(__name__) class Move(Action): """ Move a file to a new location. The file can also be renamed. If the specified path does not exist it will be created. If you only want to rename the file and keep the folder, it is easier to use the Rename-Action. :param str dest: The destination folder or path. If `dest` ends with a slash / backslash, the file will be moved into this folder and not renamed. :param bool overwrite: specifies whether existing files should be overwritten. Otherwise it will start enumerating files (append a counter to the filename) to resolve naming conflicts. [Default: False] :param str counter_separator: specifies the separator between filename and the appended counter. Only relevant if **overwrite** is disabled. [Default: ``\' \'``] Examples: - Move all pdfs and jpgs from the desktop into the folder "~/Desktop/media/". Filenames are not changed. .. code-block:: yaml :caption: config.yaml rules: - folders: ~/Desktop filters: - extension: - pdf - jpg actions: - move: '~/Desktop/media/' - Use a placeholder to move all .pdf files into a "PDF" folder and all .jpg files into a "JPG" folder. Existing files will be overwritten. .. code-block:: yaml :caption: config.yaml rules: - folders: ~/Desktop filters: - extension: - pdf - jpg actions: - move: dest: '~/Desktop/{extension.upper}/' overwrite: true - Move pdfs into the folder `Invoices`. Keep the filename but do not overwrite existing files. To prevent overwriting files, an index is added to the filename, so ``somefile.jpg`` becomes ``somefile 2.jpg``. .. code-block:: yaml :caption: config.yaml rules: - folders: ~/Desktop/Invoices filters: - extension: - pdf actions: - move: dest: '~/Documents/Invoices/' overwrite: false counter_separator: '_' """ def __init__(self, dest: str, overwrite=False, counter_separator=" "): self.dest = dest self.overwrite = overwrite self.counter_separator = counter_separator def pipeline(self, args: DotDict) -> Mapping[str, Path]: path = args["path"] simulate = args["simulate"] expanded_dest = self.fill_template_tags(self.dest, args) # if only a folder path is given we append the filename to have the full # path. We use os.path for that because pathlib removes trailing slashes if expanded_dest.endswith(("\\", "/")): expanded_dest = os.path.join(expanded_dest, path.name) new_path = fullpath(expanded_dest) new_path_exists = new_path.exists() new_path_samefile = new_path_exists and new_path.samefile(path) if new_path_exists and not new_path_samefile: if self.overwrite: self.print("File already exists") Trash().run(path=new_path, simulate=simulate) else: new_path = find_unused_filename( path=new_path, separator=self.counter_separator ) if new_path_samefile and new_path == path: self.print("Keep location") else: self.print('Move to "%s"' % new_path) if not simulate: logger.info("Creating folder if not exists: %s", new_path.parent) new_path.parent.mkdir(parents=True, exist_ok=True) logger.info('Moving "%s" to "%s"', path, new_path) shutil.move(src=str(path), dst=str(new_path)) return {"path": new_path} def __str__(self) -> str: return "Move(dest=%s, overwrite=%s)" % (self.dest, self.overwrite) organize-1.10.1/organize/actions/python.py000066400000000000000000000056641403777030400206010ustar00rootroot00000000000000import logging import textwrap from typing import Any, Mapping, Optional, Iterable from organize.utils import DotDict from .action import Action logger = logging.getLogger(__name__) class Python(Action): r""" Execute python code in your config file. :param str code: The python code to execute Examples: - A basic example that shows how to get the current file path and do some printing in a for loop. The ``|`` is yaml syntax for defining a string literal spanning multiple lines. .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Desktop' actions: - python: | print('The path of the current file is %s' % path) for _ in range(5): print('Heyho, its me from the loop') - You can access filter data: .. code-block:: yaml :caption: config.yaml rules: - folders: ~/Desktop filters: - regex: '^(?P.*)\.(?P.*)$' actions: - python: | print('Name: %s' % regex.name) print('Extension: %s' % regex.extension) - You have access to all the python magic -- do a google search for each filename starting with an underscore: .. code-block:: yaml :caption: config.yaml rules: - folders: ~/Desktop filters: - filename: startswith: '_' actions: - python: | import webbrowser webbrowser.open('https://www.google.com/search?q=%s' % path.stem) """ def __init__(self, code) -> None: self.code = textwrap.dedent(code) def usercode(self, *args, **kwargs) -> Optional[Any]: pass # will be overwritten by `create_method` def create_method(self, name: str, argnames: Iterable[str], code: str) -> None: globals_ = globals().copy() globals_["print"] = self.print locals_ = locals().copy() funccode = "def {fnc}__({arg}):\n{cod}\n\nself.{fnc} = {fnc}__\n".format( fnc=name, arg=", ".join(argnames), cod=textwrap.indent(textwrap.dedent(code), " " * 4), ) exec(funccode, globals_, locals_) # pylint: disable=exec-used def pipeline(self, args: DotDict) -> Optional[Mapping[str, Any]]: simulate = args.simulate if simulate: self.print("Code not run in simulation. (Args: %s)" % args) return None logger.info('Executing python:\n"""\n%s\n""", args=%s', self.code, args) self.create_method(name="usercode", argnames=args.keys(), code=self.code) self.print("Running python script.") result = self.usercode(**args) # pylint: disable=assignment-from-no-return return result organize-1.10.1/organize/actions/rename.py000066400000000000000000000062401403777030400205160ustar00rootroot00000000000000import logging import os from typing import Mapping from pathlib import Path from organize.utils import find_unused_filename from .action import Action from .trash import Trash logger = logging.getLogger(__name__) class Rename(Action): """ Renames a file. :param str name: The new filename. Can be a format string which uses file attributes from a filter. :param bool overwrite: specifies whether existing files should be overwritten. Otherwise it will start enumerating files (append a counter to the filename) to resolve naming conflicts. [Default: False] :param str counter_separator: specifies the separator between filename and the appended counter. Only relevant if **overwrite** is disabled. [Default: ``\' \'``] Examples: - Convert all .PDF file extensions to lowercase (.pdf): .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Desktop' filters: - extension: PDF actions: - rename: "{path.stem}.pdf" - Convert **all** file extensions to lowercase: .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Desktop' filters: - Extension actions: - rename: "{path.stem}.{extension.lower}" """ def __init__(self, name: str, overwrite=False, counter_separator=" ") -> None: if os.path.sep in name: ValueError( "Rename only takes a filename as argument. To move files between " "folders use the Move action." ) self.name = name self.overwrite = overwrite self.counter_separator = counter_separator def pipeline(self, args: Mapping) -> Mapping[str, Path]: path = args["path"] # type: Path simulate = args["simulate"] expanded_name = self.fill_template_tags(self.name, args) new_path = path.parent / expanded_name # handle filename collisions new_path_exists = new_path.exists() new_path_samefile = new_path_exists and new_path.samefile(path) if new_path_exists and not new_path_samefile: if self.overwrite: self.print("File already exists") Trash().run(path=new_path, simulate=simulate) else: new_path = find_unused_filename( path=new_path, separator=self.counter_separator ) # do nothing if the new name is equal to the old name and the file is # the same if new_path_samefile and new_path == path: self.print("Keep name") else: self.print('New name: "%s"' % new_path.name) if not simulate: logger.info('Renaming "%s" to "%s".', path, new_path) path.rename(new_path) return {"path": new_path} def __str__(self) -> str: return "Rename(name=%s, overwrite=%s, sep=%s)" % ( self.name, self.overwrite, self.counter_separator, ) organize-1.10.1/organize/actions/shell.py000066400000000000000000000020331403777030400203520ustar00rootroot00000000000000import logging import subprocess from typing import Mapping from .action import Action logger = logging.getLogger(__name__) class Shell(Action): """ Executes a shell command :param str cmd: The command to execute. Example: - (macOS) Open all pdfs on your desktop: .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Desktop' filters: - extension: pdf actions: - shell: 'open "{path}"' """ def __init__(self, cmd: str) -> None: self.cmd = cmd def pipeline(self, args: Mapping) -> None: full_cmd = self.fill_template_tags(self.cmd, args) self.print("$ %s" % full_cmd) if not args["simulate"]: # we use call instead of run to be compatible with python < 3.5 logger.info('Executing command "%s" in shell.', full_cmd) subprocess.call(full_cmd, shell=True) def __str__(self) -> str: return 'Shell(cmd="%s")' % self.cmd organize-1.10.1/organize/actions/trash.py000066400000000000000000000020041403777030400203620ustar00rootroot00000000000000import logging from typing import Mapping from pathlib import Path from .action import Action logger = logging.getLogger(__name__) class Trash(Action): """ Move a file into the trash. Example: - Move all JPGs and PNGs on the desktop which are older than one year into the trash: .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Desktop' - filters: - lastmodified: - days: 365 - extension: - png - jpg - actions: - trash """ def pipeline(self, args: Mapping): path = args["path"] # type: Path simulate = args["simulate"] # type: bool from send2trash import send2trash # type: ignore self.print('Trash "%s"' % path) if not simulate: logger.info("Moving file %s into trash.", path) send2trash(str(path)) organize-1.10.1/organize/cli.py000066400000000000000000000117221403777030400163570ustar00rootroot00000000000000""" organize -- The file management automation tool. Usage: organize sim [--config-file=] organize run [--config-file=] organize config [--open-folder | --path | --debug] [--config-file=] organize list organize --help organize --version Arguments: sim Simulate a run. Does not touch your files. run Organizes your files according to your rules. config Open the configuration file in $EDITOR. list List available filters and actions. --version Show program version and exit. -h, --help Show this screen and exit. Options: -o, --open-folder Open the folder containing the configuration files. -p, --path Show the path to the configuration file. -d, --debug Debug your configuration file. Full documentation: https://organize.readthedocs.io """ import logging import os import sys from typing import Union from colorama import Fore, Style # type: ignore from docopt import docopt # type: ignore from . import CONFIG_DIR, CONFIG_PATH, LOG_PATH from .__version__ import __version__ from pathlib import Path from .config import Config from .core import execute_rules from .utils import flatten, fullpath logger = logging.getLogger("organize") def main(argv=None): """ entry point for the command line interface """ args = docopt(__doc__, argv=argv, version=__version__, help=True) # override default config file path if args["--config-file"]: expanded_path = os.path.expandvars(args["--config-file"]) config_path = Path(expanded_path).expanduser().resolve() config_dir = config_path.parent else: config_dir = CONFIG_DIR config_path = CONFIG_PATH # > organize config if args["config"]: if args["--open-folder"]: open_in_filemanager(config_dir) elif args["--path"]: print(str(config_path)) elif args["--debug"]: config_debug(config_path) else: config_edit(config_path) # > organize list elif args["list"]: list_actions_and_filters() # > organize sim / run else: try: config = Config.from_file(config_path) execute_rules(config.rules, simulate=args["sim"]) except Config.Error as e: logger.exception(e) print_error(e) print("Try 'organize config --debug' for easier debugging.") print("Full traceback at: %s" % LOG_PATH) sys.exit(1) except Exception as e: # pylint: disable=broad-except logger.exception(e) print_error(e) print("Full traceback at: %s" % LOG_PATH) sys.exit(1) def config_edit(config_path: Path) -> None: """ open the config file in $EDITOR or default text editor """ # attention: the env variable might contain command line arguments. # https://github.com/tfeldmann/organize/issues/24 editor = os.getenv("EDITOR") if editor: os.system('%s "%s"' % (editor, config_path)) else: open_in_filemanager(config_path) def open_in_filemanager(path: Path) -> None: """ opens the given path in file manager, using the default application """ import webbrowser # pylint: disable=import-outside-toplevel webbrowser.open(path.as_uri()) def config_debug(config_path: Path) -> None: """ prints the config with resolved yaml aliases, checks rules syntax and checks whether the given folders exist """ print(str(config_path)) haserr = False # check config syntax try: print(Style.BRIGHT + "Your configuration as seen by the parser:") config = Config.from_file(config_path) if not config.config: print_error("Config file is empty") return print(config.yaml()) rules = config.rules print("Config file syntax seems fine!") except Config.Error as e: haserr = True print_error(e) else: # check whether all folders exists: allfolders = set(flatten([rule.folders for rule in rules])) for f in allfolders: if not fullpath(f).exists(): haserr = True print(Fore.YELLOW + 'Warning: "%s" does not exist!' % f) if not haserr: print(Fore.GREEN + Style.BRIGHT + "No config problems found.") def list_actions_and_filters() -> None: """ Prints a list of available actions and filters """ import inspect # pylint: disable=import-outside-toplevel from organize import filters, actions # pylint: disable=import-outside-toplevel print(Style.BRIGHT + "Filters:") for name, _ in inspect.getmembers(filters, inspect.isclass): print(" " + name) print() print(Style.BRIGHT + "Actions:") for name, _ in inspect.getmembers(actions, inspect.isclass): print(" " + name) def print_error(e: Union[Exception, str]) -> None: print(Style.BRIGHT + Fore.RED + "ERROR:" + Style.RESET_ALL + " %s" % e) organize-1.10.1/organize/config.py000066400000000000000000000154741403777030400170650ustar00rootroot00000000000000import inspect import logging import textwrap from typing import Generator, List, Mapping, NamedTuple, Sequence import yaml from . import actions, filters from .actions.action import Action from pathlib import Path from .filters.filter import Filter from .utils import first_key, flatten logger = logging.getLogger(__name__) Rule = NamedTuple( "Rule", [ ("filters", Sequence[Filter]), ("actions", Sequence[Action]), ("folders", Sequence[str]), ("subfolders", bool), ("system_files", bool), ], ) # disable yaml constructors for strings starting with exclamation marks # https://stackoverflow.com/a/13281292/300783 def default_yaml_cnst(loader, tag_suffix, node): return str(node.tag) yaml.add_multi_constructor("", default_yaml_cnst, Loader=yaml.SafeLoader) class Config: def __init__(self, config: dict) -> None: self.config = config self.filter_by_name = { name.lower(): getattr(filters, name) for name, _ in inspect.getmembers(filters, inspect.isclass) } self.action_by_name = { name.lower(): getattr(actions, name) for name, _ in inspect.getmembers(actions, inspect.isclass) } @classmethod def from_string(cls, config: str) -> "Config": dedented_config = textwrap.dedent(config) try: return cls(yaml.load(dedented_config, Loader=yaml.SafeLoader)) except yaml.YAMLError as e: raise cls.ParsingError(e) @classmethod def from_file(cls, path: Path) -> "Config": with path.open(encoding="utf-8") as f: return cls.from_string(f.read()) def yaml(self) -> str: if not (self.config and "rules" in self.config): raise self.NoRulesFoundError() data = {"rules": self.config["rules"]} yaml.Dumper.ignore_aliases = lambda self, data: True # type: ignore return yaml.dump( data, allow_unicode=True, default_flow_style=False, default_style="'" ) @staticmethod def parse_folders(rule_item) -> Generator[str, None, None]: # the folder list is flattened so we can use encapsulated list # definitions in the config file. yield from flatten(rule_item["folders"]) @staticmethod def sanitize_key(key): return key.lower().replace("_", "") def _get_filter_class_by_name(self, name): try: return self.filter_by_name[self.sanitize_key(name)] except AttributeError as e: raise self.Error("%s is no valid filter" % name) from e def _get_action_class_by_name(self, name): try: return self.action_by_name[self.sanitize_key(name)] except AttributeError as e: raise self.Error("%s is no valid action" % name) from e @staticmethod def _class_instance_with_args(Cls, args): if args is None: return Cls() elif isinstance(args, list): return Cls(*args) elif isinstance(args, dict): return Cls(**args) return Cls(args) def instantiate_filters(self, rule_item: Mapping) -> Generator[Filter, None, None]: # filter list can be empty try: filter_list = rule_item["filters"] except KeyError: return if not filter_list: return if not isinstance(filter_list, list): raise self.FiltersNoListError() for filter_item in flatten(filter_list): if filter_item is None: # TODO: don't know what this should be continue # filter with arguments elif isinstance(filter_item, dict): name = first_key(filter_item) args = filter_item[name] filter_class = self._get_filter_class_by_name(name) yield self._class_instance_with_args(filter_class, args) # only given filter name without args elif isinstance(filter_item, str): name = filter_item filter_class = self._get_filter_class_by_name(name) yield filter_class() else: raise self.Error("Unknown filter: %s" % filter_item) def instantiate_actions(self, rule_item: Mapping) -> Generator[Action, None, None]: action_list = rule_item["actions"] if not isinstance(action_list, list): raise self.ActionsNoListError() for action_item in flatten(action_list): if isinstance(action_item, dict): name = first_key(action_item) args = action_item[name] action_class = self._get_action_class_by_name(name) yield self._class_instance_with_args(action_class, args) elif isinstance(action_item, str): name = action_item action_class = self._get_action_class_by_name(name) yield action_class() else: raise self.Error("Unknown action: %s" % action_item) @property def rules(self) -> List[Rule]: """ :returns: A list of instantiated Rules """ if not (self.config and "rules" in self.config): raise self.NoRulesFoundError() result = [] for i, rule_item in enumerate(self.config["rules"]): # skip disabled rules if not rule_item.get("enabled", True): continue rule_folders = list(self.parse_folders(rule_item)) rule_filters = list(self.instantiate_filters(rule_item)) rule_actions = list(self.instantiate_actions(rule_item)) if not rule_folders: logger.warning("No folders given for rule %s!", i + 1) if not rule_filters: logger.warning("No filters given for rule %s!", i + 1) if not rule_actions: logger.warning("No actions given for rule %s!", i + 1) rule = Rule( folders=rule_folders, filters=rule_filters, actions=rule_actions, subfolders=rule_item.get("subfolders", False), system_files=rule_item.get("system_files", False), ) result.append(rule) return result class Error(Exception): pass class NoRulesFoundError(Error): def __str__(self): return "No rules found in configuration file" class ParsingError(Error): pass class NoFoldersFoundError(Error): pass class NoFiltersFoundError(Error): pass class NoActionsFoundError(Error): pass class FiltersNoListError(Error): def __str__(self): return "Please specify your filters as a YAML list" class ActionsNoListError(Error): def __str__(self): return "Please specify your actions as a YAML list" organize-1.10.1/organize/core.py000066400000000000000000000155141403777030400165430ustar00rootroot00000000000000import logging import os import shutil from copy import deepcopy from datetime import datetime from textwrap import indent from typing import Generator, Iterable, List, NamedTuple, Optional, Sequence, Set, Tuple from colorama import Fore, Style # type: ignore from .actions.action import Action from pathlib import Path from .config import Rule from .filters.filter import Filter from .utils import DotDict, splitglob logger = logging.getLogger(__name__) SYSTEM_FILES = ("thumbs.db", "desktop.ini", ".DS_Store") Job = NamedTuple( "Job", [ ("folderstr", str), ("basedir", Path), ("path", Path), ("filters", Sequence[Filter]), ("actions", Sequence[Action]), ], ) Job.__doc__ = """ :param str folderstr: the original folder definition specified in the config :param Path basedir: the job's base folder :param Path path: the path of the file to handle :param list filters: the filters that apply to the path :param list actions: the actions which should be executed """ class OutputHelper: """ class to track the current folder / file and print only changes. This is needed because we only want to output the current folder and file if the filter or action prints something. """ def __init__(self) -> None: self.not_found = set() # type: Set[str] self.curr_folder = None # type: Optional[Path] self.curr_path = None # type: Optional[Path] self.prev_folder = None # type: Optional[Path] self.prev_path = None # type: Optional[Path] def set_location(self, folder: Path, path: Path) -> None: self.curr_folder = folder self.curr_path = path def pre_print(self) -> None: """ pre-print hook that is called everytime the moment before a filter or action is about to print something to the cli """ if self.curr_folder != self.prev_folder: if self.prev_folder is not None: print() # ensure newline between folders print("Folder %s%s:" % (Style.BRIGHT, self.curr_folder)) self.prev_folder = self.curr_folder if self.curr_path != self.prev_path: print(indent("File %s%s:" % (Style.BRIGHT, self.curr_path), " " * 2)) self.prev_path = self.curr_path def print_path_not_found(self, folderstr: str) -> None: if folderstr not in self.not_found: self.not_found.add(folderstr) msg = "Path not found: {}".format(folderstr) print(Fore.YELLOW + Style.BRIGHT + msg) logger.warning(msg) output_helper = OutputHelper() def execute_rules(rules: Iterable[Rule], simulate: bool) -> None: cols, _ = shutil.get_terminal_size(fallback=(79, 20)) simulation_msg = Fore.GREEN + Style.BRIGHT + " SIMULATION ".center(cols, "~") jobs = create_jobs(rules=rules) if simulate: print(simulation_msg) failed, succeded = run_jobs(jobs=jobs, simulate=simulate) if succeded == failed == 0: msg = "Nothing to do." logger.info(msg) print(msg) if simulate: print(simulation_msg) def create_jobs(rules: Iterable[Rule]) -> Generator[Job, None, None]: """ creates `Job` data structures for every path handled in each rule """ for rule in rules: for folderstr, basedir, path in all_files_for_rule(rule): yield Job( folderstr=folderstr, basedir=basedir, path=path, filters=rule.filters, actions=rule.actions, ) def all_files_for_rule(rule: Rule) -> Generator[Tuple[str, Path, Path], None, None]: files = dict() for folderstr in rule.folders: folderstr = folderstr.strip() # check whether the file / folder is prefixed with `!` to be excluded exclude_flag = folderstr.startswith("!") # assemble glob expression basedir, globstr = splitglob(folderstr.lstrip("!").strip()) if basedir.is_dir(): if not globstr: globstr = "**/*" if rule.subfolders else "*" elif basedir.is_file(): # this allows specifying single files globstr = basedir.name basedir = basedir.parent else: output_helper.print_path_not_found(str(basedir)) continue # iterate files in basedir and add to / remove from result dict for path in basedir.glob(globstr): if path.is_file() and (rule.system_files or path.name not in SYSTEM_FILES): if not exclude_flag: files[path] = (folderstr, basedir) elif path in files: del files[path] for path, (folderstr, basedir) in files.items(): yield (folderstr, basedir, path) def run_jobs(jobs: Iterable[Job], simulate: bool) -> List[int]: """ :returns: The number of successfully handled files """ count = [0, 0] Action.pre_print_hook = output_helper.pre_print Filter.pre_print_hook = output_helper.pre_print for job in sorted(jobs, key=lambda x: (x.folderstr, x.basedir, x.path)): args = DotDict( path=job.path, basedir=job.basedir, simulate=simulate, relative_path=job.path.relative_to(job.basedir), env=os.environ, now=datetime.now(), ) output_helper.set_location(job.basedir, args.relative_path) match = filter_pipeline(filters=job.filters, args=args) if match: success = action_pipeline(actions=job.actions, args=args) count[success] += 1 return count def filter_pipeline(filters: Iterable[Filter], args: DotDict) -> bool: """ run the filter pipeline. Returns True on a match, False otherwise and updates `args` in the process. """ for filter_ in filters: try: result = filter_.pipeline(deepcopy(args)) if isinstance(result, dict): args.update(result) elif not result: # filters might return a simple True / False. # Exit early if a filter does not match. return False except Exception as e: # pylint: disable=broad-except logger.exception(e) filter_.print(Fore.RED + Style.BRIGHT + "ERROR! %s" % e) return False return True def action_pipeline(actions: Iterable[Action], args: DotDict) -> bool: for action in actions: try: updates = action.pipeline(deepcopy(args)) # jobs may return a dict with updates that should be merged into args if updates is not None: args.update(updates) except Exception as e: # pylint: disable=broad-except logger.exception(e) action.print(Fore.RED + Style.BRIGHT + "ERROR! %s" % e) return False return True organize-1.10.1/organize/filters/000077500000000000000000000000001403777030400167035ustar00rootroot00000000000000organize-1.10.1/organize/filters/__init__.py000066400000000000000000000005251403777030400210160ustar00rootroot00000000000000from .created import Created from .duplicate import Duplicate from .exif import Exif from .extension import Extension from .file_content import FileContent from .filename import Filename from .filesize import FileSize from .last_modified import LastModified from .mimetype import MimeType from .python import Python from .regex import Regex organize-1.10.1/organize/filters/created.py000066400000000000000000000115521403777030400206700ustar00rootroot00000000000000import sys from typing import Dict, Optional, SupportsFloat import pendulum # type: ignore from pathlib import Path from organize.utils import DotDict from .filter import Filter class Created(Filter): """ Matches files by created date :param int years: specify number of years :param int months: specify number of months :param float weeks: specify number of weeks :param float days: specify number of days :param float hours: specify number of hours :param float minutes: specify number of minutes :param float seconds: specify number of seconds :param str mode: either 'older' or 'newer'. 'older' matches all files created before the given time, 'newer' matches all files created within the given time. (default = 'older') :param str timezone: specify timezone :returns: - ``{created.year}`` -- the year the file was created - ``{created.month}`` -- the month the file was created - ``{created.day}`` -- the day the file was created - ``{created.hour}`` -- the hour the file was created - ``{created.minute}`` -- the minute the file was created - ``{created.second}`` -- the second the file was created Examples: - Show all files on your desktop created at least 10 days ago: .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Desktop' filters: - created: days: 10 actions: - echo: 'Was created at least 10 days ago' - Show all files on your desktop which were created within the last 5 hours: .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Desktop' filters: - created: hours: 5 mode: newer actions: - echo: 'Was created within the last 5 hours' - Sort pdfs by year of creation: .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Documents' filters: - extension: pdf - created actions: - move: '~/Documents/PDF/{created.year}/' - Use specific timezone when processing files .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Documents' filters: - extension: pdf - created: timezone: "Europe/Moscow" actions: - move: '~/Documents/PDF/{created.day}/{created.hour}/' """ def __init__( self, years=0, months=0, weeks=0, days=0, hours=0, minutes=0, seconds=0, mode="older", timezone=pendulum.tz.local_timezone(), ) -> None: self._mode = mode.strip().lower() if self._mode not in ("older", "newer"): raise ValueError("Unknown option for 'mode': must be 'older' or 'newer'.") self.is_older = self._mode == "older" self.timezone = timezone self.timedelta = pendulum.duration( years=years, months=months, weeks=weeks, days=days, hours=hours, minutes=minutes, seconds=seconds, ) print(bool(self.timedelta)) def pipeline(self, args: DotDict) -> Optional[Dict[str, pendulum.DateTime]]: created_date = self._created(args.path) # Pendulum bug: https://github.com/sdispater/pendulum/issues/387 # in_words() is a workaround: total_seconds() returns 0 if years are given if self.timedelta.in_words(): is_past = (created_date + self.timedelta).is_past() match = self.is_older == is_past else: match = True if match: return {"created": created_date} return None def _created(self, path: Path) -> pendulum.DateTime: # see https://stackoverflow.com/a/39501288/300783 stat = path.stat() time = 0 # type: SupportsFloat if sys.platform.startswith("win"): time = stat.st_ctime else: try: time = stat.st_birthtime except AttributeError: # We're probably on Linux. No easy way to get creation dates here, # so we'll settle for when its content was last modified. time = stat.st_mtime return pendulum.from_timestamp(float(time), tz=self.timezone) def __str__(self): return "[Created] All files %s than %s" % ( self._mode, self.timedelta.in_words(), ) organize-1.10.1/organize/filters/duplicate.py000066400000000000000000000115651403777030400212370ustar00rootroot00000000000000""" Duplicate detection filter. Based on this stackoverflow answer: https://stackoverflow.com/a/36113168/300783 Which was updated for python3 in: https://gist.github.com/tfeldmann/fc875e6630d11f2256e746f67a09c1ae The script on stackoverflow has a bug which could lead to false positives. This is fixed here by using a tuple (file_size, hash) as key in the comparison dictionaries. """ import hashlib import os from collections import defaultdict from typing import DefaultDict as DDict from typing import Dict, List, Set, Tuple, Union from organize.utils import fullpath from .filter import Filter def chunk_reader(fobj, chunk_size=1024): """ Generator that reads a file in chunks of bytes """ while True: chunk = fobj.read(chunk_size) if not chunk: return yield chunk def get_hash(filename, first_chunk_only=False, hash_algo=hashlib.sha1): hashobj = hash_algo() with open(filename, "rb") as f: if first_chunk_only: hashobj.update(f.read(1024)) else: for chunk in chunk_reader(f): hashobj.update(chunk) return hashobj.digest() class Duplicate(Filter): """ Finds duplicate files. This filter compares files byte by byte and finds identical files with potentially different filenames. :returns: - ``{duplicate}`` -- path to the duplicate source Examples: - Show all duplicate files in your desktop and download folder (and their subfolders). .. code-block:: yaml :caption: config.yaml rules: - folders: - ~/Desktop - ~/Downloads subfolders: true filters: - duplicate actions: - echo: "{path} is a duplicate of {duplicate}" """ def __init__(self) -> None: self.files_for_size = defaultdict(list) # type: DDict[int, List[str]] # to prevent false positives the keys must be tuples of (file_size, hash). self.files_for_small_hash = defaultdict( list ) # type: DDict[Tuple[int, bytes], List[str]] self.file_for_full_hash = dict() # type: Dict[Tuple[int, bytes], str] # we keep track of which files we already computed the hashes for so we only do # that once. self.small_hash_known = set() # type: Set[str] self.full_hash_known = set() # type: Set[str] def matches(self, path: str) -> Union[bool, Dict[str, str]]: # the exact same path has already been handled. This might happen if path is a # symlink which resolves to file that is already known. We skip these. if path in self.small_hash_known: return False # check for files with equal size file_size = os.path.getsize(path) # type: int same_size = self.files_for_size[file_size] candidates_fsize = same_size[:] same_size.append(path) if not candidates_fsize: # the file is unique in size and cannot be a duplicate return False # for all other files with the same file size, get their hash of the first 1024 # bytes for c in candidates_fsize: if c not in self.small_hash_known: try: c_small_hash = get_hash(c, first_chunk_only=True) self.files_for_small_hash[(file_size, c_small_hash)].append(c) self.small_hash_known.add(c) except OSError: pass # check small hash collisions with the current file small_hash = get_hash(path, first_chunk_only=True) same_small_hash = self.files_for_small_hash[(file_size, small_hash)] candidates_shash = same_small_hash[:] same_small_hash.append(path) self.small_hash_known.add(path) if not candidates_shash: # the file has a unique small hash and cannot be a duplicate return False # For all other files with the same file size and small hash get the full hash for c in candidates_shash: if c not in self.full_hash_known: try: c_full_hash = get_hash(c, first_chunk_only=False) self.file_for_full_hash[(file_size, c_full_hash)] = c self.full_hash_known.add(c) except OSError: pass # check full hash collisions with the current file full_hash = get_hash(path, first_chunk_only=False) duplicate = self.file_for_full_hash.get((file_size, full_hash)) if duplicate: return {"duplicate": duplicate} self.file_for_full_hash[(file_size, full_hash)] = path return False def pipeline(self, args): return self.matches(str(fullpath(args["path"]))) def __str__(self) -> str: return "Duplicate()" organize-1.10.1/organize/filters/exif.py000066400000000000000000000104131403777030400202070ustar00rootroot00000000000000import collections from typing import Any, DefaultDict, Dict, Mapping, Optional, Union import exifread # type: ignore from pathlib import Path from .filter import Filter ExifDict = Mapping[str, Union[str, Mapping[str, str]]] class Exif(Filter): """ Filter by image EXIF data The `exif` filter can be used as a filter as well as a way to get exif information into your actions. :returns: ``{exif}`` -- a dict of all the collected exif inforamtion available in the file. Typically it consists of the following tags (if present in the file): - ``{exif.image}`` -- information related to the main image - ``{exif.exif}`` -- Exif information - ``{exif.gps}`` -- GPS information - ``{exif.interoperability}`` -- Interoperability information Examples: - Show available EXIF data of your pictures: .. code-block:: yaml :caption: config.yaml rules: - folders: ~/Pictures subfolders: true filters: - exif actions: - echo: "{exif}" - Copy all images which contain GPS information while keeping subfolder structure: .. code-block:: yaml :caption: config.yaml rules: - folders: ~/Pictures subfolders: true filters: - exif: gps.gpsdate actions: - copy: ~/Pictures/with_gps/{relative_path}/ - Filter by camera manufacturer: .. code-block:: yaml :caption: config.yaml rules: - folders: ~/Pictures subfolders: true filters: - exif: image.model: Nikon D3200 actions: - move: '~/Pictures/My old Nikon/' - Sort images by camera manufacturer. This will create folders for each camera model (for example "Nikon D3200", "iPhone 6s", "iPhone 5s", "DMC-GX80") and move the pictures accordingly: .. code-block:: yaml :caption: config.yaml rules: - folders: ~/Pictures subfolders: true filters: - extension: jpg - exif: image.model actions: - move: '~/Pictures/{exif.image.model}/' """ def __init__(self, *required_tags: str, **tag_filters: str) -> None: self.args = required_tags # expected exif keys self.kwargs = tag_filters # exif keys with expected values def category_dict(self, tags: Mapping[str, str]) -> ExifDict: result = collections.defaultdict(dict) # type: DefaultDict[str, Dict[str, str]] for key, value in tags.items(): if " " in key: category, field = key.split(" ", maxsplit=1) result[category][field] = value else: result[key] = value # type: ignore return result def matches(self, path: Path) -> Union[bool, ExifDict]: # NOTE: This should return Union[Literal[False], ExifDict] but Literal is only # available in Python>=3.8. with path.open("rb") as f: exiftags = exifread.process_file(f, details=False) # type: Dict if not exiftags: return False tags = {k.lower(): v.printable for k, v in exiftags.items()} # no match if expected tag is not found normkey = lambda k: k.replace(".", " ").lower() for key in self.args: if normkey(key) not in tags: return False # no match if tag has not expected value for key, value in self.kwargs.items(): key = normkey(key) if not (key in tags and tags[key].lower() == value.lower()): return False return self.category_dict(tags) def pipeline(self, args: Mapping[str, Any]) -> Optional[Dict[str, ExifDict]]: tags = self.matches(args["path"]) if isinstance(tags, dict): return {"exif": tags} return None def __str__(self) -> str: return "EXIF(%s)" % ", ".join("%s=%s" % (k, v) for k, v in self.kwargs.items()) organize-1.10.1/organize/filters/extension.py000066400000000000000000000062641403777030400213010ustar00rootroot00000000000000from typing import Dict, Optional, Union from pathlib import Path from organize.utils import DotDict, flatten from .filter import Filter class ExtensionResult: def __init__(self, ext): self.ext = ext[1:] if ext.startswith(".") else ext @property def lower(self): return self.ext.lower() @property def upper(self): return self.ext.upper() def __str__(self): return self.ext class Extension(Filter): """ Filter by file extension :param extensions: The file extensions to match (does not need to start with a colon). :returns: - ``{extension}`` -- the original file extension (without colon) - ``{extension.lower}`` -- the file extension in lowercase - ``{extension.upper}`` -- the file extension in UPPERCASE Examples: - Match a single file extension: .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Desktop' filters: - extension: png actions: - echo: 'Found PNG file: {path}' - Match multiple file extensions: .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Desktop' filters: - extension: - .jpg - jpeg actions: - echo: 'Found JPG file: {path}' - Make all file extensions lowercase: .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Desktop' filters: - Extension actions: - rename: '{path.stem}.{extension.lower}' - Using extension lists: .. code-block:: yaml :caption: config.yaml img_ext: &img - png - jpg - tiff audio_ext: &audio - mp3 - wav - ogg rules: - folders: '~/Desktop' filters: - extension: - *img - *audio actions: - echo: 'Found media file: {path}' """ def __init__(self, *extensions) -> None: self.extensions = list(map(self.normalize_extension, flatten(list(extensions)))) @staticmethod def normalize_extension(ext: str) -> str: """ strip colon and convert to lowercase """ if ext.startswith("."): return ext[1:].lower() else: return ext.lower() def matches(self, path: Path) -> Union[bool, str]: if not self.extensions: return True if not path.suffix: return False return self.normalize_extension(path.suffix) in self.extensions def pipeline(self, args: DotDict) -> Optional[Dict[str, ExtensionResult]]: if self.matches(args.path): result = ExtensionResult(args.path.suffix) return {"extension": result} return None def __str__(self): return "Extension(%s)" % ", ".join(self.extensions) organize-1.10.1/organize/filters/file_content.py000066400000000000000000000045011403777030400217260ustar00rootroot00000000000000import re from typing import Any, Dict, Mapping, Optional from pathlib import Path from .filter import Filter # not supported: .gif, .jpg, .mp3, .ogg, .png, .tiff, .wav SUPPORTED_EXTENSIONS = ( ".csv .doc .docx .eml .epub .json .html .msg .odt .pdf .pptx .ps .rtf .txt .xlsx .xls" ).split() class FileContent(Filter): r""" Matches file content with the given regular expression :param str expr: The regular expression to be matched. Any named groups in your regular expression will be returned like this: :returns: - ``{filecontent.yourgroupname}`` -- The text matched with the named group ``(?P)`` Examples: - Show the content of all your PDF files: .. code-block::yaml :caption: config.yaml rules: - folders: ~/Documents filters: - extension: pdf - filecontent: '(?P.*)' actions: - echo: "{filecontent.all}" - Match an invoice with a regular expression and sort by customer: .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Desktop' filters: - filecontent: 'Invoice.*Customer (?P\w+)' actions: - move: '~/Documents/Invoices/{filecontent.customer}/' """ def __init__(self, expr) -> None: self.expr = re.compile(expr, re.MULTILINE | re.DOTALL) def matches(self, path: Path) -> Any: if path.suffix.lower() not in SUPPORTED_EXTENSIONS: return try: import textract # type: ignore content = textract.process(str(path), errors="ignore") return self.expr.search(content.decode("utf-8", errors="ignore")) except ImportError as e: raise ImportError( "textract is not installed. " "Install with pip install organize-tool[textract]" ) from e except textract.exceptions.CommandLineError: pass def pipeline(self, args: Mapping) -> Optional[Dict[str, Dict]]: match = self.matches(args["path"]) if match: result = match.groupdict() return {"filecontent": result} return None organize-1.10.1/organize/filters/filename.py000066400000000000000000000071021403777030400210350ustar00rootroot00000000000000from typing import Any, List, Union, Optional, Dict import simplematch # type: ignore from pathlib import Path from .filter import Filter class Filename(Filter): """ Match files by filename :param str match: A matching string in `simplematch`-syntax (https://github.com/tfeldmann/simplematch) :param str startswith: The filename must begin with the given string :param str contains: The filename must contain the given string :param str endswith: The filename (without extension) must end with the given string :param bool case_sensitive = True: By default, the matching is case sensitive. Change this to False to use case insensitive matching. Examples: - Match all files starting with 'Invoice': .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Desktop' filters: - filename: startswith: Invoice actions: - echo: 'This is an invoice' - Match all files starting with 'A' end containing the string 'hole' (case insensitive) .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Desktop' filters: - filename: startswith: A contains: hole case_sensitive: false actions: - echo: 'Found a match.' - Match all files starting with 'A' or 'B' containing '5' or '6' and ending with '_end' .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Desktop' filters: - filename: startswith: - A - B contains: - 5 - 6 endswith: _end case_sensitive: false actions: - echo: 'Found a match.' """ def __init__( self, match="*", *, startswith="", contains="", endswith="", case_sensitive=True ) -> None: self.matcher = simplematch.Matcher(match, case_sensitive=case_sensitive) self.startswith = self.create_list(startswith, case_sensitive) self.contains = self.create_list(contains, case_sensitive) self.endswith = self.create_list(endswith, case_sensitive) self.case_sensitive = case_sensitive def matches(self, path: Path) -> bool: filename = path.stem if not self.case_sensitive: filename = filename.lower() is_match = ( self.matcher.test(filename) and any(x in filename for x in self.contains) and any(filename.startswith(x) for x in self.startswith) and any(filename.endswith(x) for x in self.endswith) ) return is_match def pipeline(self, args: Dict) -> Optional[Dict[str, Any]]: path = args["path"] result = self.matches(path) if result: return {"filename": self.matcher.match(path.stem)} return None @staticmethod def create_list(x: Union[int, str, List[Any]], case_sensitive: bool) -> List[str]: if isinstance(x, (int, float)): x = str(x) if isinstance(x, str): x = [x] x = [str(x) for x in x] if not case_sensitive: x = [x.lower() for x in x] return x organize-1.10.1/organize/filters/filesize.py000066400000000000000000000075641403777030400211030ustar00rootroot00000000000000import operator import re from typing import Callable, Dict, Optional, Sequence, Set, Tuple from organize.utils import DotDict, flattened_string_list, fullpath from .filter import Filter OPERATORS = { "<": operator.lt, "<=": operator.le, "==": operator.eq, "=": operator.eq, "": operator.eq, ">=": operator.ge, ">": operator.gt, } SIZE_REGEX = re.compile( r"^(?P[<>=]*)(?P(\d*\.)?\d+)(?P[kmgtpezy]?i?)b?$" ) def create_constrains(inp: str) -> Set[Tuple[Callable[[int, int], bool], int]]: """ Given an input string it returns a list of tuples (comparison operator, number of bytes). Accepted formats are: '30k', '>= 5 TiB, <10tb', '< 60 tb', ... Calculation is in bytes, even if the 'b' is lowercase. If an 'i' is present we calculate base 1024. """ result = set() # type: Set[Tuple[Callable[[int, int], bool], int]] parts = inp.replace(" ", "").lower().split(",") for part in parts: try: reg_match = SIZE_REGEX.match(part) if reg_match: match = reg_match.groupdict() op = OPERATORS[match["op"]] num = float(match["num"]) if "." in match["num"] else int(match["num"]) unit = match["unit"] base = 1024 if unit.endswith("i") else 1000 exp = "kmgtpezy".index(unit[0]) + 1 if unit else 0 numbytes = num * base ** exp result.add((op, numbytes)) except (AttributeError, KeyError, IndexError, ValueError, TypeError) as e: raise ValueError("Invalid size format: %s" % part) from e return result def satisfies_constrains(size, constrains): return all(op(size, p_size) for op, p_size in constrains) class FileSize(Filter): """ Matches files by file size :param str conditions: Accepts file size conditions, e.g: ``'>= 500 MB'``, ``'< 20k'``, ``'>0'``, ``'= 10 KiB'``. It is possible to define both lower and upper conditions like this: ``'>20k, < 1 TB'``, ``'>= 20 Mb, <25 Mb'``. The filter will match if all given conditions are satisfied. - Accepts all units from KB to YB. - If no unit is given, kilobytes are assumend. - If binary prefix is given (KiB, GiB) the size is calculated using base 1024. :returns: - ``{filesize.bytes}`` -- File size in bytes Examples: - Trash big downloads: .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Downloads' filters: - filesize: '> 0.5 GB' actions: - trash - Move all JPEGS bigger > 1MB and <10 MB. Search all subfolders and keep the´ original relative path. .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Pictures' subfolders: true filters: - extension: - jpg - jpeg - filesize: '>1mb, <10mb' actions: - move: '~/Pictures/sorted/{relative_path}/' """ def __init__(self, *conditions: Sequence[str]) -> None: self.conditions = ", ".join(flattened_string_list(list(conditions))) self.constrains = create_constrains(self.conditions) if not self.constrains: raise ValueError("No size(s) given!") def matches(self, filesize: int) -> bool: return all(op(filesize, c_size) for op, c_size in self.constrains) def pipeline(self, args: DotDict) -> Optional[Dict[str, Dict[str, int]]]: file_size = fullpath(args.path).stat().st_size if self.matches(file_size): return {"filesize": {"bytes": file_size}} return None def __str__(self) -> str: return "FileSize({})".format(" ".join(self.conditions)) organize-1.10.1/organize/filters/filter.py000066400000000000000000000017571403777030400205540ustar00rootroot00000000000000from textwrap import indent from typing import Any, Callable, Dict, Optional, Union from organize.utils import DotDict FilterResult = Union[Dict[str, Any], bool, None] class Filter: pre_print_hook = None # type: Optional[Callable] def run(self, **kwargs: Dict) -> FilterResult: return self.pipeline(DotDict(kwargs)) def pipeline(self, args: DotDict) -> FilterResult: raise NotImplementedError def print(self, msg: str) -> None: """ print a message for the user """ if callable(self.pre_print_hook): self.pre_print_hook() # pylint: disable=not-callable print(indent("- (%s) %s" % (self.__class__.__name__, msg), " " * 4)) def __str__(self) -> str: """ Return filter name and properties """ return self.__class__.__name__ def __repr__(self) -> str: return "<%s>" % str(self) def __eq__(self, other) -> bool: return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ organize-1.10.1/organize/filters/last_modified.py000066400000000000000000000110041403777030400220540ustar00rootroot00000000000000from typing import Dict, Optional import pendulum # type: ignore from pathlib import Path from organize.utils import DotDict from .filter import Filter class LastModified(Filter): """ Matches files by last modified date :param int years: specify number of years :param int months: specify number of months :param float weeks: specify number of weeks :param float days: specify number of days :param float hours: specify number of hours :param float minutes: specify number of minutes :param float seconds: specify number of seconds :param str mode: either 'older' or 'newer'. 'older' matches all files last modified before the given time, 'newer' matches all files last modified within the given time. (default = 'older') :param str timezone: specify timezone :returns: - ``{lastmodified.year}`` -- the year the file was last modified - ``{lastmodified.month}`` -- the month the file was last modified - ``{lastmodified.day}`` -- the day the file was last modified - ``{lastmodified.hour}`` -- the hour the file was last modified - ``{lastmodified.minute}`` -- the minute the file was last modified - ``{lastmodified.second}`` -- the second the file was last modified Examples: - Show all files on your desktop last modified at least 10 days ago: .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Desktop' filters: - lastmodified: days: 10 actions: - echo: 'Was modified at least 10 days ago' - Show all files on your desktop which were modified within the last 5 hours: .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Desktop' filters: - lastmodified: hours: 5 mode: newer actions: - echo: 'Was modified within the last 5 hours' - Sort pdfs by year of last modification .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Documents' filters: - extension: pdf - LastModified actions: - move: '~/Documents/PDF/{lastmodified.year}/' - Use specific timezone when processing files .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Documents' filters: - extension: pdf - lastmodified: timezone: "Europe/Moscow" actions: - move: '~/Documents/PDF/{lastmodified.day}/{lastmodified.hour}/' """ def __init__( self, years=0, months=0, weeks=0, days=0, hours=0, minutes=0, seconds=0, mode="older", timezone=pendulum.tz.local_timezone(), ) -> None: self._mode = mode.strip().lower() if self._mode not in ("older", "newer"): raise ValueError("Unknown option for 'mode': must be 'older' or 'newer'.") self.is_older = self._mode == "older" self.timezone = timezone self.timedelta = pendulum.duration( years=years, months=months, weeks=weeks, days=days, hours=hours, minutes=minutes, seconds=seconds, ) def pipeline(self, args: DotDict) -> Optional[Dict[str, pendulum.DateTime]]: file_modified = self._last_modified(args.path) # Pendulum bug: https://github.com/sdispater/pendulum/issues/387 # in_words() is a workaround: total_seconds() returns 0 if years are given if self.timedelta.in_words(): is_past = (file_modified + self.timedelta).is_past() match = self.is_older == is_past else: match = True if match: return {"lastmodified": file_modified} return None def _last_modified(self, path: Path) -> pendulum.DateTime: return pendulum.from_timestamp(float(path.stat().st_mtime), tz=self.timezone) def __str__(self): return "[LastModified] All files last modified %s than %s" % ( self._mode, self.timedelta.in_words(), ) organize-1.10.1/organize/filters/mimetype.py000066400000000000000000000051661403777030400211160ustar00rootroot00000000000000import mimetypes from pathlib import Path from organize.utils import DotDict, flatten from .filter import Filter class MimeType(Filter): """ Filter by MIME type associated with the file extension. Supports a single string or list of MIME type strings as argument. The types don't need to be fully specified, for example "audio" matches everything from "audio/midi" to "audio/quicktime". You can see a list of known MIME types on your system by running this oneliner: .. code-block:: yaml python3 -c "import mimetypes as m; print('\\n'.join(sorted(set(m.common_types.values()) | set(m.types_map.values()))))" Examples: - Show MIME types: .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Downloads' filters: - mimetype actions: - echo: '{mimetype}' - Filter by "image" mimetype: .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Downloads' filters: - mimetype: image actions: - echo: This file is an image: {mimetype} - Filter by specific MIME type: .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Desktop' filters: - mimetype: application/pdf actions: - echo: 'Found a PDF file' - Filter by multiple specific MIME types: .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Music' filters: - mimetype: - application/pdf - audio/midi actions: - echo: 'Found Midi or PDF.' """ def __init__(self, *mimetypes): self.mimetypes = list(map(str.lower, flatten(list(mimetypes)))) @staticmethod def mimetype(path): type_, _ = mimetypes.guess_type(path, strict=False) return type_ def matches(self, path: Path): mimetype = self.mimetype(path) if mimetype is None: return False if not self.mimetypes: return True return any(mimetype.startswith(x) for x in self.mimetypes) def pipeline(self, args: DotDict): if self.matches(args.path): result = self.mimetype(args.path) return {"mimetype": result} return None def __str__(self): return "MimeType(%s)" % ", ".join(self.mimetypes) organize-1.10.1/organize/filters/python.py000066400000000000000000000102261403777030400205770ustar00rootroot00000000000000import textwrap from typing import Any, Dict, Optional, Sequence from .filter import Filter class Python(Filter): r""" Use python code to filter files. :param str code: The python code to execute. The code must contain a ``return`` statement. :returns: - If your code returns ``False`` or ``None`` the file is filtered out, otherwise the file is passed on to the next filters. - ``{python}`` contains the returned value. If you return a dictionary (for example ``return {"some_key": some_value, "nested": {"k": 2}}``) it will be accessible via dot syntax in your actions: ``{python.some_key}``, ``{python.nested.k}``. Examples: - A file name reverser. .. code-block:: yaml :caption: config.yaml rules: - folders: ~/Documents filters: - extension - python: | return {"reversed_name": path.stem[::-1]} actions: - rename: '{python.reversed_name}.{extension}' - A filter for odd student numbers. Assuming the folder ``~/Students`` contains the files ``student-01.jpg``, ``student-01.txt``, ``student-02.txt`` and ``student-03.txt`` this rule will print ``"Odd student numbers: student-01.txt"`` and ``"Odd student numbers: student-03.txt"`` .. code-block:: yaml :caption: config.yaml rules: - folders: ~/Students/ filters: - python: | return int(path.stem.split('-')[1]) % 2 == 1 actions: - echo: 'Odd student numbers: {path.name}' - Advanced usecase. You can access data from previous filters in your python code. This can be used to match files and capturing names with a regular expression and then renaming the files with the output of your python script. .. code-block:: yaml :caption: config.yaml rules: - folders: files filters: - extension: txt - regex: (?P\w+)-(?P\w+)\..* - python: | emails = { "Betts": "dbetts@mail.de", "Cornish": "acornish@google.com", "Bean": "dbean@aol.com", "Frey": "l-frey@frey.org", } if regex.lastname in emails: # get emails from wherever return {"mail": emails[regex.lastname]} actions: - rename: '{python.mail}.txt' Result: - ``Devonte-Betts.txt`` becomes ``dbetts@mail.de.txt`` - ``Alaina-Cornish.txt`` becomes ``acornish@google.com.txt`` - ``Dimitri-Bean.txt`` becomes ``dbean@aol.com.txt`` - ``Lowri-Frey.txt`` becomes ``l-frey@frey.org.txt`` - ``Someunknown-User.txt`` remains unchanged because the email is not found """ def __init__(self, code) -> None: self.code = textwrap.dedent(code) if "return" not in self.code: raise ValueError("No return statement found in your code!") def usercode(self, *args, **kwargs) -> Optional[Any]: pass # will be overwritten by `create_method` def create_method(self, name: str, argnames: Sequence[str], code: str) -> None: globals_ = globals().copy() globals_["print"] = self.print locals_ = locals().copy() locals_["self"] = self funccode = "def {fnc}__({arg}):\n{cod}\n\nself.{fnc} = {fnc}__\n".format( fnc=name, arg=", ".join(argnames), cod=textwrap.indent(textwrap.dedent(code), " " * 4), ) exec(funccode, globals_, locals_) # pylint: disable=exec-used def pipeline(self, args) -> Optional[Dict[str, Any]]: self.create_method(name="usercode", argnames=args.keys(), code=self.code) result = self.usercode(**args) # pylint: disable=assignment-from-no-return if result not in (False, None): return {"python": result} return None organize-1.10.1/organize/filters/regex.py000066400000000000000000000034261403777030400203740ustar00rootroot00000000000000import re from typing import Any, Dict, Mapping, Optional from pathlib import Path from .filter import Filter class Regex(Filter): r""" Matches filenames with the given regular expression :param str expr: The regular expression to be matched. Any named groups in your regular expression will be returned like this: :returns: - ``{regex.yourgroupname}`` -- The text matched with the named group ``(?P)`` Examples: - Match an invoice with a regular expression: .. code-block:: yaml :caption: config.yaml rules: - folders: '~/Desktop' filters: - regex: '^RG(\d{12})-sig\.pdf$' actions: - move: '~/Documents/Invoices/1und1/' - Match and extract data from filenames with regex named groups: This is just like the previous example but we rename the invoice using the invoice number extracted via the regular expression and the named group ``the_number``. .. code-block:: yaml :caption: config.yaml rules: - folders: ~/Desktop filters: - regex: '^RG(?P\d{12})-sig\.pdf$' actions: - move: ~/Documents/Invoices/1und1/{regex.the_number}.pdf """ def __init__(self, expr) -> None: self.expr = re.compile(expr, flags=re.UNICODE) def matches(self, path: Path) -> Any: return self.expr.search(path.name) def pipeline(self, args: Mapping) -> Optional[Dict[str, Dict]]: match = self.matches(args["path"]) if match: result = match.groupdict() return {"regex": result} return None organize-1.10.1/organize/utils.py000066400000000000000000000125551403777030400167550ustar00rootroot00000000000000import os import re from collections.abc import Mapping from copy import deepcopy from typing import Any, Sequence, Tuple, Union, List, Hashable from pathlib import Path WILDCARD_REGEX = re.compile(r"(? Tuple[Path, str]: """ split a string with wildcards into a base folder and globstring """ path = fullpath(globstr.strip()) parts = path.parts for i, part in enumerate(parts): if WILDCARD_REGEX.search(part): return (Path(*parts[:i]), str(Path(*parts[i:]))) return (path, "") def fullpath(path: Union[str, Path]) -> Path: """ Expand '~' and resolve the given path. Path can be a string or a Path obj. """ return Path(os.path.expandvars(str(path))).expanduser().resolve(strict=False) def flatten(arr: List[Any]) -> List[Any]: if arr == []: return [] if not isinstance(arr, list): return [arr] return flatten(arr[0]) + flatten(arr[1:]) def flattened_string_list(x, case_sensitive=True) -> Sequence[str]: x = [str(x) for x in flatten(x)] if not case_sensitive: x = [x.lower() for x in x] return x def first_key(dic: Mapping) -> Hashable: return list(dic.keys())[0] class DotDict(dict): """ Quick and dirty implementation of a dot-able dict, which allows access and assignment via object properties rather than dict indexing. Keys are case insensitive. """ def __init__(self, *args, **kwargs): super().__init__() # we could just call super(DotDict, self).__init__(*args, **kwargs) # but that won't get us nested dotdict objects od = dict(*args, **kwargs) for key, val in od.items(): if isinstance(val, Mapping): value = DotDict(val) else: value = val self[self.normkey(key)] = value @staticmethod def normkey(key): if isinstance(key, str): return key.lower() else: return key def __delattr__(self, key): try: del self[self.normkey(key)] except KeyError as ex: raise AttributeError("No attribute called: %s" % key) from ex def __getattr__(self, key): try: return self[self.normkey(key)] except KeyError as ex: raise AttributeError("No attribute called: %s" % key) from ex def __setattr__(self, key, value) -> None: self[self.normkey(key)] = value def update(self, other): """ recursively update the dotdict instance with another dicts items """ for key, val in other.items(): normkey = self.normkey(key) if isinstance(val, Mapping): if isinstance(self.get(normkey), dict): self[normkey].update(val) else: self[normkey] = __class__(val) else: self[normkey] = val def merge(self, other) -> Mapping: """ recursively merge values from another dict and return a new instance """ new_dct = deepcopy(self) new_dct.update(other) return new_dct def increment_filename_version(path: Path, separator=" ") -> Path: stem = path.stem try: # try to find any existing counter splitstem = stem.split(separator) # raises ValueError on missing sep if len(splitstem) < 2: raise ValueError() counter = int(splitstem[-1]) stem = separator.join(splitstem[:-1]) except (ValueError, IndexError): # not found, we start with 1 counter = 1 return path.with_name( "{stem}{sep}{cnt}{suffix}".format( stem=stem, sep=separator, cnt=(counter + 1), suffix=path.suffix ) ) def find_unused_filename(path: Path, separator=" ") -> Path: """ We assume the given path already exists. This function adds a counter to the filename until we find a unused filename. """ # TODO: Check whether the assumption can be eliminated for cleaner code. # TODO: Optimization: The counter only needs to be parsed once. tmp = path while True: tmp = increment_filename_version(tmp, separator=separator) if not tmp.exists(): return tmp def dict_merge(dct, merge_dct, add_keys=True): """ Recursive dict merge. Inspired by :meth:``dict.update()``, instead of updating only top-level keys, dict_merge recurses down into dicts nested to an arbitrary depth, updating keys. The ``merge_dct`` is merged into ``dct``. This version will return a copy of the dictionary and leave the original arguments untouched. The optional argument ``add_keys``, determines whether keys which are present in ``merge_dict`` but not ``dct`` should be included in the new dict. Args: dct (dict) onto which the merge is executed merge_dct (dict): dct merged into dct add_keys (bool): whether to add new keys Returns: dict: updated dict Taken from comment thread: https://gist.github.com/angstwad/bf22d1822c38a92ec0a9 """ dct = deepcopy(dct) if not add_keys: merge_dct = {k: merge_dct[k] for k in set(dct).intersection(set(merge_dct))} for k, v in merge_dct.items(): if isinstance(dct.get(k), dict) and isinstance(v, Mapping): dct[k] = dict_merge(dct[k], v, add_keys=add_keys) else: dct[k] = v return dct organize-1.10.1/poetry.lock000066400000000000000000002576411403777030400156300ustar00rootroot00000000000000[[package]] name = "alabaster" version = "0.7.12" description = "A configurable sidebar-enabled Sphinx theme" category = "dev" optional = false python-versions = "*" [[package]] name = "appdirs" version = "1.4.4" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." category = "main" optional = false python-versions = "*" [[package]] name = "appnope" version = "0.1.2" description = "Disable App Nap on macOS >= 10.9" category = "dev" optional = false python-versions = "*" [[package]] name = "argcomplete" version = "1.10.0" description = "Bash tab completion for argparse" category = "main" optional = true python-versions = "*" [package.extras] test = ["coverage", "flake8", "pexpect", "wheel"] [[package]] name = "astroid" version = "2.5.3" description = "An abstract syntax tree for Python with inference support." category = "dev" optional = false python-versions = ">=3.6" [package.dependencies] lazy-object-proxy = ">=1.4.0" typed-ast = {version = ">=1.4.0,<1.5", markers = "implementation_name == \"cpython\" and python_version < \"3.8\""} wrapt = ">=1.11,<1.13" [[package]] name = "atomicwrites" version = "1.4.0" description = "Atomic file writes." category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "attrs" version = "20.3.0" description = "Classes Without Boilerplate" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.extras] dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface", "furo", "sphinx", "pre-commit"] docs = ["furo", "sphinx", "zope.interface"] tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "zope.interface"] tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six"] [[package]] name = "babel" version = "2.9.0" description = "Internationalization utilities" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.dependencies] pytz = ">=2015.7" [[package]] name = "backcall" version = "0.2.0" description = "Specifications for callback functions passed in to an API" category = "dev" optional = false python-versions = "*" [[package]] name = "beautifulsoup4" version = "4.8.0" description = "Screen-scraping library" category = "main" optional = true python-versions = "*" [package.dependencies] soupsieve = ">=1.2" [package.extras] html5lib = ["html5lib"] lxml = ["lxml"] [[package]] name = "certifi" version = "2020.12.5" description = "Python package for providing Mozilla's CA Bundle." category = "dev" optional = false python-versions = "*" [[package]] name = "cffi" version = "1.14.5" description = "Foreign Function Interface for Python calling C code." category = "main" optional = false python-versions = "*" [package.dependencies] pycparser = "*" [[package]] name = "chardet" version = "3.0.4" description = "Universal encoding detector for Python 2 and 3" category = "main" optional = false python-versions = "*" [[package]] name = "colorama" version = "0.4.4" description = "Cross-platform colored terminal text." category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "decorator" version = "5.0.7" description = "Decorators for Humans" category = "dev" optional = false python-versions = ">=3.5" [[package]] name = "docopt" version = "0.6.2" description = "Pythonic argument parser, that will make you smile" category = "main" optional = false python-versions = "*" [[package]] name = "docutils" version = "0.16" description = "Docutils -- Python Documentation Utilities" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "docx2txt" version = "0.8" description = "A pure python-based utility to extract text and images from docx files." category = "main" optional = true python-versions = "*" [[package]] name = "ebooklib" version = "0.17.1" description = "Ebook library which can handle EPUB2/EPUB3 and Kindle format" category = "main" optional = true python-versions = "*" [package.dependencies] lxml = "*" six = "*" [[package]] name = "exifread" version = "2.3.2" description = "Read Exif metadata from tiff and jpeg files." category = "main" optional = false python-versions = "*" [[package]] name = "extract-msg" version = "0.23.1" description = "Extracts emails and attachments saved in Microsoft Outlook's .msg files" category = "main" optional = true python-versions = "*" [package.dependencies] imapclient = "2.1.0" olefile = "0.46" tzlocal = "1.5.1" [[package]] name = "flake8" version = "3.9.1" description = "the modular source code checker: pep8 pyflakes and co" category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" [package.dependencies] importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} mccabe = ">=0.6.0,<0.7.0" pycodestyle = ">=2.7.0,<2.8.0" pyflakes = ">=2.3.0,<2.4.0" [[package]] name = "idna" version = "2.10" description = "Internationalized Domain Names in Applications (IDNA)" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "imagesize" version = "1.2.0" description = "Getting image size from png/jpeg/jpeg2000/gif file" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "imapclient" version = "2.1.0" description = "Easy-to-use, Pythonic and complete IMAP client library" category = "main" optional = true python-versions = "*" [package.dependencies] six = "*" [package.extras] doc = ["sphinx"] test = ["mock (>=1.3.0)"] [[package]] name = "importlib-metadata" version = "4.0.0" description = "Read metadata from Python packages" category = "dev" optional = false python-versions = ">=3.6" [package.dependencies] typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} zipp = ">=0.5" [package.extras] docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] testing = ["pytest (>=4.6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pep517", "pyfakefs", "flufl.flake8", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] [[package]] name = "ipdb" version = "0.12.3" description = "IPython-enabled pdb" category = "dev" optional = false python-versions = ">=2.7" [package.dependencies] ipython = {version = ">=5.1.0", markers = "python_version >= \"3.4\""} [[package]] name = "ipython" version = "7.16.1" description = "IPython: Productive Interactive Computing" category = "dev" optional = false python-versions = ">=3.6" [package.dependencies] appnope = {version = "*", markers = "sys_platform == \"darwin\""} backcall = "*" colorama = {version = "*", markers = "sys_platform == \"win32\""} decorator = "*" jedi = ">=0.10" pexpect = {version = "*", markers = "sys_platform != \"win32\""} pickleshare = "*" prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0" pygments = "*" traitlets = ">=4.2" [package.extras] all = ["Sphinx (>=1.3)", "ipykernel", "ipyparallel", "ipywidgets", "nbconvert", "nbformat", "nose (>=0.10.1)", "notebook", "numpy (>=1.14)", "pygments", "qtconsole", "requests", "testpath"] doc = ["Sphinx (>=1.3)"] kernel = ["ipykernel"] nbconvert = ["nbconvert"] nbformat = ["nbformat"] notebook = ["notebook", "ipywidgets"] parallel = ["ipyparallel"] qtconsole = ["qtconsole"] test = ["nose (>=0.10.1)", "requests", "testpath", "pygments", "nbformat", "ipykernel", "numpy (>=1.14)"] [[package]] name = "ipython-genutils" version = "0.2.0" description = "Vestigial utilities from IPython" category = "dev" optional = false python-versions = "*" [[package]] name = "isort" version = "5.8.0" description = "A Python utility / library to sort Python imports." category = "dev" optional = false python-versions = ">=3.6,<4.0" [package.extras] pipfile_deprecated_finder = ["pipreqs", "requirementslib"] requirements_deprecated_finder = ["pipreqs", "pip-api"] colors = ["colorama (>=0.4.3,<0.5.0)"] [[package]] name = "jedi" version = "0.18.0" description = "An autocompletion tool for Python that can be used for text editors." category = "dev" optional = false python-versions = ">=3.6" [package.dependencies] parso = ">=0.8.0,<0.9.0" [package.extras] qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<6.0.0)"] [[package]] name = "jinja2" version = "2.11.3" description = "A very fast and expressive template engine." category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.dependencies] MarkupSafe = ">=0.23" [package.extras] i18n = ["Babel (>=0.8)"] [[package]] name = "lazy-object-proxy" version = "1.6.0" description = "A fast and thorough lazy object proxy." category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" [[package]] name = "lxml" version = "4.6.3" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." category = "main" optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, != 3.4.*" [package.extras] cssselect = ["cssselect (>=0.7)"] html5 = ["html5lib"] htmlsoup = ["beautifulsoup4"] source = ["Cython (>=0.29.7)"] [[package]] name = "macos-tags" version = "1.5.1" description = "Use tags to organize files on Mac from Python" category = "main" optional = false python-versions = ">=3.6,<4.0" [package.dependencies] mdfind-wrapper = ">=0.1.3,<0.2.0" xattr = ">=0.9.7,<0.10.0" [[package]] name = "markupsafe" version = "1.1.1" description = "Safely add untrusted strings to HTML/XML markup." category = "dev" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*" [[package]] name = "mccabe" version = "0.6.1" description = "McCabe checker, plugin for flake8" category = "dev" optional = false python-versions = "*" [[package]] name = "mdfind-wrapper" version = "0.1.4" description = "A python library that wraps the mdfind." category = "main" optional = false python-versions = ">=3.6" [[package]] name = "more-itertools" version = "8.7.0" description = "More routines for operating on iterables, beyond itertools" category = "dev" optional = false python-versions = ">=3.5" [[package]] name = "mypy" version = "0.812" description = "Optional static typing for Python" category = "dev" optional = false python-versions = ">=3.5" [package.dependencies] mypy-extensions = ">=0.4.3,<0.5.0" typed-ast = ">=1.4.0,<1.5.0" typing-extensions = ">=3.7.4" [package.extras] dmypy = ["psutil (>=4.0)"] [[package]] name = "mypy-extensions" version = "0.4.3" description = "Experimental type system extensions for programs checked with the mypy typechecker." category = "dev" optional = false python-versions = "*" [[package]] name = "olefile" version = "0.46" description = "Python package to parse, read and write Microsoft OLE2 files (Structured Storage or Compound Document, Microsoft Office)" category = "main" optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "packaging" version = "20.9" description = "Core utilities for Python packages" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.dependencies] pyparsing = ">=2.0.2" [[package]] name = "parso" version = "0.8.2" description = "A Python Parser" category = "dev" optional = false python-versions = ">=3.6" [package.extras] qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] testing = ["docopt", "pytest (<6.0.0)"] [[package]] name = "pdfminer.six" version = "20181108" description = "PDF parser and analyzer" category = "main" optional = true python-versions = "*" [package.dependencies] pycryptodome = "*" six = "*" sortedcontainers = "*" [[package]] name = "pendulum" version = "2.1.2" description = "Python datetimes made easy" category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.dependencies] python-dateutil = ">=2.6,<3.0" pytzdata = ">=2020.1" [[package]] name = "pexpect" version = "4.8.0" description = "Pexpect allows easy control of interactive console applications." category = "dev" optional = false python-versions = "*" [package.dependencies] ptyprocess = ">=0.5" [[package]] name = "pickleshare" version = "0.7.5" description = "Tiny 'shelve'-like database with concurrency support" category = "dev" optional = false python-versions = "*" [[package]] name = "pillow" version = "8.2.0" description = "Python Imaging Library (Fork)" category = "main" optional = true python-versions = ">=3.6" [[package]] name = "pluggy" version = "0.13.1" description = "plugin and hook calling mechanisms for python" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [package.dependencies] importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} [package.extras] dev = ["pre-commit", "tox"] [[package]] name = "prompt-toolkit" version = "3.0.3" description = "Library for building powerful interactive command lines in Python" category = "dev" optional = false python-versions = ">=3.6" [package.dependencies] wcwidth = "*" [[package]] name = "ptyprocess" version = "0.7.0" description = "Run a subprocess in a pseudo terminal" category = "dev" optional = false python-versions = "*" [[package]] name = "py" version = "1.10.0" description = "library with cross-python path, ini-parsing, io, code, log facilities" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pycodestyle" version = "2.7.0" description = "Python style guide checker" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pycparser" version = "2.20" description = "C parser in Python" category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pycryptodome" version = "3.10.1" description = "Cryptographic library for Python" category = "main" optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [[package]] name = "pyflakes" version = "2.3.1" description = "passive checker of Python programs" category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pygments" version = "2.8.1" description = "Pygments is a syntax highlighting package written in Python." category = "dev" optional = false python-versions = ">=3.5" [[package]] name = "pylint" version = "2.7.4" description = "python code static checker" category = "dev" optional = false python-versions = "~=3.6" [package.dependencies] astroid = ">=2.5.2,<2.7" colorama = {version = "*", markers = "sys_platform == \"win32\""} isort = ">=4.2.5,<6" mccabe = ">=0.6,<0.7" toml = ">=0.7.1" [package.extras] docs = ["sphinx (==3.5.1)", "python-docs-theme (==2020.12)"] [[package]] name = "pyparsing" version = "2.4.7" description = "Python parsing module" category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "pytest" version = "4.6.11" description = "pytest: simple powerful testing with Python" category = "dev" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" [package.dependencies] atomicwrites = ">=1.0" attrs = ">=17.4.0" colorama = {version = "*", markers = "sys_platform == \"win32\" and python_version != \"3.4\""} importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} more-itertools = {version = ">=4.0.0", markers = "python_version > \"2.7\""} packaging = "*" pluggy = ">=0.12,<1.0" py = ">=1.5.0" six = ">=1.10.0" wcwidth = "*" [package.extras] testing = ["argcomplete", "hypothesis (>=3.56)", "nose", "requests", "mock"] [[package]] name = "python-dateutil" version = "2.8.1" description = "Extensions to the standard Python datetime module" category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" [package.dependencies] six = ">=1.5" [[package]] name = "python-pptx" version = "0.6.18" description = "Generate and manipulate Open XML PowerPoint (.pptx) files" category = "main" optional = true python-versions = "*" [package.dependencies] lxml = ">=3.1.0" Pillow = ">=3.3.2" XlsxWriter = ">=0.5.7" [[package]] name = "pytz" version = "2021.1" description = "World timezone definitions, modern and historical" category = "main" optional = false python-versions = "*" [[package]] name = "pytzdata" version = "2020.1" description = "The Olson timezone database for Python." category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "pyyaml" version = "5.4.1" description = "YAML parser and emitter for Python" category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" [[package]] name = "requests" version = "2.25.1" description = "Python HTTP for Humans." category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" [package.dependencies] certifi = ">=2017.4.17" chardet = ">=3.0.2,<5" idna = ">=2.5,<3" urllib3 = ">=1.21.1,<1.27" [package.extras] security = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)"] socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] [[package]] name = "send2trash" version = "1.5.0" description = "Send file to trash natively under Mac OS X, Windows and Linux." category = "main" optional = false python-versions = "*" [[package]] name = "simplematch" version = "1.3" description = "Minimal, super readable string pattern matching." category = "main" optional = false python-versions = ">=3.6,<4.0" [[package]] name = "six" version = "1.12.0" description = "Python 2 and 3 compatibility utilities" category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*" [[package]] name = "snowballstemmer" version = "2.1.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." category = "dev" optional = false python-versions = "*" [[package]] name = "sortedcontainers" version = "2.3.0" description = "Sorted Containers -- Sorted List, Sorted Dict, Sorted Set" category = "main" optional = true python-versions = "*" [[package]] name = "soupsieve" version = "2.2.1" description = "A modern CSS selector implementation for Beautiful Soup." category = "main" optional = true python-versions = ">=3.6" [[package]] name = "speechrecognition" version = "3.8.1" description = "Library for performing speech recognition, with support for several engines and APIs, online and offline." category = "main" optional = true python-versions = "*" [[package]] name = "sphinx" version = "3.5.4" description = "Python documentation generator" category = "dev" optional = false python-versions = ">=3.5" [package.dependencies] alabaster = ">=0.7,<0.8" babel = ">=1.3" colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} docutils = ">=0.12,<0.17" imagesize = "*" Jinja2 = ">=2.3" packaging = "*" Pygments = ">=2.0" requests = ">=2.5.0" snowballstemmer = ">=1.1" sphinxcontrib-applehelp = "*" sphinxcontrib-devhelp = "*" sphinxcontrib-htmlhelp = "*" sphinxcontrib-jsmath = "*" sphinxcontrib-qthelp = "*" sphinxcontrib-serializinghtml = "*" [package.extras] docs = ["sphinxcontrib-websupport"] lint = ["flake8 (>=3.5.0)", "isort", "mypy (>=0.800)", "docutils-stubs"] test = ["pytest", "pytest-cov", "html5lib", "cython", "typed-ast"] [[package]] name = "sphinx-rtd-theme" version = "0.5.2" description = "Read the Docs theme for Sphinx" category = "dev" optional = false python-versions = "*" [package.dependencies] docutils = "<0.17" sphinx = "*" [package.extras] dev = ["transifex-client", "sphinxcontrib-httpdomain", "bump2version"] [[package]] name = "sphinxcontrib-applehelp" version = "1.0.2" description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books" category = "dev" optional = false python-versions = ">=3.5" [package.extras] lint = ["flake8", "mypy", "docutils-stubs"] test = ["pytest"] [[package]] name = "sphinxcontrib-devhelp" version = "1.0.2" description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." category = "dev" optional = false python-versions = ">=3.5" [package.extras] lint = ["flake8", "mypy", "docutils-stubs"] test = ["pytest"] [[package]] name = "sphinxcontrib-htmlhelp" version = "1.0.3" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" category = "dev" optional = false python-versions = ">=3.5" [package.extras] lint = ["flake8", "mypy", "docutils-stubs"] test = ["pytest", "html5lib"] [[package]] name = "sphinxcontrib-jsmath" version = "1.0.1" description = "A sphinx extension which renders display math in HTML via JavaScript" category = "dev" optional = false python-versions = ">=3.5" [package.extras] test = ["pytest", "flake8", "mypy"] [[package]] name = "sphinxcontrib-qthelp" version = "1.0.3" description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." category = "dev" optional = false python-versions = ">=3.5" [package.extras] lint = ["flake8", "mypy", "docutils-stubs"] test = ["pytest"] [[package]] name = "sphinxcontrib-serializinghtml" version = "1.1.4" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." category = "dev" optional = false python-versions = ">=3.5" [package.extras] lint = ["flake8", "mypy", "docutils-stubs"] test = ["pytest"] [[package]] name = "textract" version = "1.6.3" description = "extract text from any document. no muss. no fuss." category = "main" optional = true python-versions = "*" [package.dependencies] argcomplete = "1.10.0" beautifulsoup4 = "4.8.0" chardet = "3.0.4" docx2txt = "0.8" EbookLib = "0.17.1" extract-msg = "0.23.1" "pdfminer.six" = "20181108" python-pptx = "0.6.18" six = "1.12.0" SpeechRecognition = "3.8.1" xlrd = "1.2.0" [package.extras] pocketsphinx = ["pocketsphinx (==0.1.15)"] [[package]] name = "toml" version = "0.10.2" description = "Python Library for Tom's Obvious, Minimal Language" category = "dev" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" [[package]] name = "traitlets" version = "4.3.3" description = "Traitlets Python config system" category = "dev" optional = false python-versions = "*" [package.dependencies] decorator = "*" ipython-genutils = "*" six = "*" [package.extras] test = ["pytest", "mock"] [[package]] name = "typed-ast" version = "1.4.3" description = "a fork of Python 2 and 3 ast modules with type comment support" category = "dev" optional = false python-versions = "*" [[package]] name = "typing-extensions" version = "3.7.4.3" description = "Backported and Experimental Type Hints for Python 3.5+" category = "dev" optional = false python-versions = "*" [[package]] name = "tzlocal" version = "1.5.1" description = "tzinfo object for the local timezone" category = "main" optional = true python-versions = "*" [package.dependencies] pytz = "*" [[package]] name = "urllib3" version = "1.26.4" description = "HTTP library with thread-safe connection pooling, file post, and more." category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" [package.extras] secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] brotli = ["brotlipy (>=0.6.0)"] [[package]] name = "wcwidth" version = "0.2.5" description = "Measures the displayed width of unicode strings in a terminal" category = "dev" optional = false python-versions = "*" [[package]] name = "wrapt" version = "1.12.1" description = "Module for decorators, wrappers and monkey patching." category = "dev" optional = false python-versions = "*" [[package]] name = "xattr" version = "0.9.7" description = "Python wrapper for extended filesystem attributes" category = "main" optional = false python-versions = "*" [package.dependencies] cffi = ">=1.0.0" [[package]] name = "xlrd" version = "1.2.0" description = "Library for developers to extract data from Microsoft Excel (tm) spreadsheet files" category = "main" optional = true python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" [[package]] name = "xlsxwriter" version = "1.3.9" description = "A Python module for creating Excel XLSX files." category = "main" optional = true python-versions = "*" [[package]] name = "zipp" version = "3.4.1" description = "Backport of pathlib-compatible object wrapper for zip files" category = "dev" optional = false python-versions = ">=3.6" [package.extras] docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] testing = ["pytest (>=4.6)", "pytest-checkdocs (>=1.2.3)", "pytest-flake8", "pytest-cov", "pytest-enabler", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] [extras] textract = ["textract"] [metadata] lock-version = "1.1" python-versions = "^3.6" content-hash = "d1e76e5a1ba4b03a7cb81610e1e3b8f4e28202d088a53295a0fe12d5c0ade8e5" [metadata.files] alabaster = [ {file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"}, {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"}, ] appdirs = [ {file = "appdirs-1.4.4-py2.py3-none-any.whl", hash = "sha256:a841dacd6b99318a741b166adb07e19ee71a274450e68237b4650ca1055ab128"}, {file = "appdirs-1.4.4.tar.gz", hash = "sha256:7d5d0167b2b1ba821647616af46a749d1c653740dd0d2415100fe26e27afdf41"}, ] appnope = [ {file = "appnope-0.1.2-py2.py3-none-any.whl", hash = "sha256:93aa393e9d6c54c5cd570ccadd8edad61ea0c4b9ea7a01409020c9aa019eb442"}, {file = "appnope-0.1.2.tar.gz", hash = "sha256:dd83cd4b5b460958838f6eb3000c660b1f9caf2a5b1de4264e941512f603258a"}, ] argcomplete = [ {file = "argcomplete-1.10.0-py2.py3-none-any.whl", hash = "sha256:2f2052ea5156eb5cc7edce9c0ddc937e30c49c1097d51b24f34350a08632a264"}, {file = "argcomplete-1.10.0.tar.gz", hash = "sha256:45836de8cc63d2f6e06b898cef1e4ce1e9907d246ec77ac8e64f23f153d6bec1"}, ] astroid = [ {file = "astroid-2.5.3-py3-none-any.whl", hash = "sha256:bea3f32799fbb8581f58431c12591bc20ce11cbc90ad82e2ea5717d94f2080d5"}, {file = "astroid-2.5.3.tar.gz", hash = "sha256:ad63b8552c70939568966811a088ef0bc880f99a24a00834abd0e3681b514f91"}, ] atomicwrites = [ {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, ] attrs = [ {file = "attrs-20.3.0-py2.py3-none-any.whl", hash = "sha256:31b2eced602aa8423c2aea9c76a724617ed67cf9513173fd3a4f03e3a929c7e6"}, {file = "attrs-20.3.0.tar.gz", hash = "sha256:832aa3cde19744e49938b91fea06d69ecb9e649c93ba974535d08ad92164f700"}, ] babel = [ {file = "Babel-2.9.0-py2.py3-none-any.whl", hash = "sha256:9d35c22fcc79893c3ecc85ac4a56cde1ecf3f19c540bba0922308a6c06ca6fa5"}, {file = "Babel-2.9.0.tar.gz", hash = "sha256:da031ab54472314f210b0adcff1588ee5d1d1d0ba4dbd07b94dba82bde791e05"}, ] backcall = [ {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, ] beautifulsoup4 = [ {file = "beautifulsoup4-4.8.0-py2-none-any.whl", hash = "sha256:05668158c7b85b791c5abde53e50265e16f98ad601c402ba44d70f96c4159612"}, {file = "beautifulsoup4-4.8.0-py3-none-any.whl", hash = "sha256:f040590be10520f2ea4c2ae8c3dae441c7cfff5308ec9d58a0ec0c1b8f81d469"}, {file = "beautifulsoup4-4.8.0.tar.gz", hash = "sha256:25288c9e176f354bf277c0a10aa96c782a6a18a17122dba2e8cec4a97e03343b"}, ] certifi = [ {file = "certifi-2020.12.5-py2.py3-none-any.whl", hash = "sha256:719a74fb9e33b9bd44cc7f3a8d94bc35e4049deebe19ba7d8e108280cfd59830"}, {file = "certifi-2020.12.5.tar.gz", hash = "sha256:1a4995114262bffbc2413b159f2a1a480c969de6e6eb13ee966d470af86af59c"}, ] cffi = [ {file = "cffi-1.14.5-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:bb89f306e5da99f4d922728ddcd6f7fcebb3241fc40edebcb7284d7514741991"}, {file = "cffi-1.14.5-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:34eff4b97f3d982fb93e2831e6750127d1355a923ebaeeb565407b3d2f8d41a1"}, {file = "cffi-1.14.5-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:99cd03ae7988a93dd00bcd9d0b75e1f6c426063d6f03d2f90b89e29b25b82dfa"}, {file = "cffi-1.14.5-cp27-cp27m-win32.whl", hash = "sha256:65fa59693c62cf06e45ddbb822165394a288edce9e276647f0046e1ec26920f3"}, {file = "cffi-1.14.5-cp27-cp27m-win_amd64.whl", hash = "sha256:51182f8927c5af975fece87b1b369f722c570fe169f9880764b1ee3bca8347b5"}, {file = "cffi-1.14.5-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:43e0b9d9e2c9e5d152946b9c5fe062c151614b262fda2e7b201204de0b99e482"}, {file = "cffi-1.14.5-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:cbde590d4faaa07c72bf979734738f328d239913ba3e043b1e98fe9a39f8b2b6"}, {file = "cffi-1.14.5-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:5de7970188bb46b7bf9858eb6890aad302577a5f6f75091fd7cdd3ef13ef3045"}, {file = "cffi-1.14.5-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:a465da611f6fa124963b91bf432d960a555563efe4ed1cc403ba5077b15370aa"}, {file = "cffi-1.14.5-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:d42b11d692e11b6634f7613ad8df5d6d5f8875f5d48939520d351007b3c13406"}, {file = "cffi-1.14.5-cp35-cp35m-win32.whl", hash = "sha256:72d8d3ef52c208ee1c7b2e341f7d71c6fd3157138abf1a95166e6165dd5d4369"}, {file = "cffi-1.14.5-cp35-cp35m-win_amd64.whl", hash = "sha256:29314480e958fd8aab22e4a58b355b629c59bf5f2ac2492b61e3dc06d8c7a315"}, {file = "cffi-1.14.5-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:3d3dd4c9e559eb172ecf00a2a7517e97d1e96de2a5e610bd9b68cea3925b4892"}, {file = "cffi-1.14.5-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:48e1c69bbacfc3d932221851b39d49e81567a4d4aac3b21258d9c24578280058"}, {file = "cffi-1.14.5-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:69e395c24fc60aad6bb4fa7e583698ea6cc684648e1ffb7fe85e3c1ca131a7d5"}, {file = "cffi-1.14.5-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:9e93e79c2551ff263400e1e4be085a1210e12073a31c2011dbbda14bda0c6132"}, {file = "cffi-1.14.5-cp36-cp36m-win32.whl", hash = "sha256:58e3f59d583d413809d60779492342801d6e82fefb89c86a38e040c16883be53"}, {file = "cffi-1.14.5-cp36-cp36m-win_amd64.whl", hash = "sha256:005a36f41773e148deac64b08f233873a4d0c18b053d37da83f6af4d9087b813"}, {file = "cffi-1.14.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2894f2df484ff56d717bead0a5c2abb6b9d2bf26d6960c4604d5c48bbc30ee73"}, {file = "cffi-1.14.5-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0857f0ae312d855239a55c81ef453ee8fd24136eaba8e87a2eceba644c0d4c06"}, {file = "cffi-1.14.5-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:cd2868886d547469123fadc46eac7ea5253ea7fcb139f12e1dfc2bbd406427d1"}, {file = "cffi-1.14.5-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:35f27e6eb43380fa080dccf676dece30bef72e4a67617ffda586641cd4508d49"}, {file = "cffi-1.14.5-cp37-cp37m-win32.whl", hash = "sha256:9ff227395193126d82e60319a673a037d5de84633f11279e336f9c0f189ecc62"}, {file = "cffi-1.14.5-cp37-cp37m-win_amd64.whl", hash = "sha256:9cf8022fb8d07a97c178b02327b284521c7708d7c71a9c9c355c178ac4bbd3d4"}, {file = "cffi-1.14.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:8b198cec6c72df5289c05b05b8b0969819783f9418e0409865dac47288d2a053"}, {file = "cffi-1.14.5-cp38-cp38-manylinux1_i686.whl", hash = "sha256:ad17025d226ee5beec591b52800c11680fca3df50b8b29fe51d882576e039ee0"}, {file = "cffi-1.14.5-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6c97d7350133666fbb5cf4abdc1178c812cb205dc6f41d174a7b0f18fb93337e"}, {file = "cffi-1.14.5-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8ae6299f6c68de06f136f1f9e69458eae58f1dacf10af5c17353eae03aa0d827"}, {file = "cffi-1.14.5-cp38-cp38-win32.whl", hash = "sha256:b85eb46a81787c50650f2392b9b4ef23e1f126313b9e0e9013b35c15e4288e2e"}, {file = "cffi-1.14.5-cp38-cp38-win_amd64.whl", hash = "sha256:1f436816fc868b098b0d63b8920de7d208c90a67212546d02f84fe78a9c26396"}, {file = "cffi-1.14.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1071534bbbf8cbb31b498d5d9db0f274f2f7a865adca4ae429e147ba40f73dea"}, {file = "cffi-1.14.5-cp39-cp39-manylinux1_i686.whl", hash = "sha256:9de2e279153a443c656f2defd67769e6d1e4163952b3c622dcea5b08a6405322"}, {file = "cffi-1.14.5-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:6e4714cc64f474e4d6e37cfff31a814b509a35cb17de4fb1999907575684479c"}, {file = "cffi-1.14.5-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:158d0d15119b4b7ff6b926536763dc0714313aa59e320ddf787502c70c4d4bee"}, {file = "cffi-1.14.5-cp39-cp39-win32.whl", hash = "sha256:afb29c1ba2e5a3736f1c301d9d0abe3ec8b86957d04ddfa9d7a6a42b9367e396"}, {file = "cffi-1.14.5-cp39-cp39-win_amd64.whl", hash = "sha256:f2d45f97ab6bb54753eab54fffe75aaf3de4ff2341c9daee1987ee1837636f1d"}, {file = "cffi-1.14.5.tar.gz", hash = "sha256:fd78e5fee591709f32ef6edb9a015b4aa1a5022598e36227500c8f4e02328d9c"}, ] chardet = [ {file = "chardet-3.0.4-py2.py3-none-any.whl", hash = "sha256:fc323ffcaeaed0e0a02bf4d117757b98aed530d9ed4531e3e15460124c106691"}, {file = "chardet-3.0.4.tar.gz", hash = "sha256:84ab92ed1c4d4f16916e05906b6b75a6c0fb5db821cc65e70cbd64a3e2a5eaae"}, ] colorama = [ {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, ] decorator = [ {file = "decorator-5.0.7-py3-none-any.whl", hash = "sha256:945d84890bb20cc4a2f4a31fc4311c0c473af65ea318617f13a7257c9a58bc98"}, {file = "decorator-5.0.7.tar.gz", hash = "sha256:6f201a6c4dac3d187352661f508b9364ec8091217442c9478f1f83c003a0f060"}, ] docopt = [ {file = "docopt-0.6.2.tar.gz", hash = "sha256:49b3a825280bd66b3aa83585ef59c4a8c82f2c8a522dbe754a8bc8d08c85c491"}, ] docutils = [ {file = "docutils-0.16-py2.py3-none-any.whl", hash = "sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af"}, {file = "docutils-0.16.tar.gz", hash = "sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc"}, ] docx2txt = [ {file = "docx2txt-0.8.tar.gz", hash = "sha256:2c06d98d7cfe2d3947e5760a57d924e3ff07745b379c8737723922e7009236e5"}, ] ebooklib = [ {file = "EbookLib-0.17.1.tar.gz", hash = "sha256:fe23e22c28050196c68db3e7b13b257bf39426d927cb395c6f2cc13ac11327f1"}, ] exifread = [ {file = "ExifRead-2.3.2-py3-none-any.whl", hash = "sha256:3ef8725efdb66530b4b3cd1c4ba5d3f3b35a7872137d2c707f711971f8ebf809"}, {file = "ExifRead-2.3.2.tar.gz", hash = "sha256:a0f74af5040168d3883bbc980efe26d06c89f026dc86ba28eb34107662d51766"}, ] extract-msg = [ {file = "extract_msg-0.23.1-py2.py3-none-any.whl", hash = "sha256:0e733743d4b5b7ca62265d1477d4b99f03e44f3202fa53ee97d54f5b2c75b1b3"}, {file = "extract_msg-0.23.1.tar.gz", hash = "sha256:3746d5f68266740575ef9097516f39c5f601fa031e188cea338a13b66de16ada"}, ] flake8 = [ {file = "flake8-3.9.1-py2.py3-none-any.whl", hash = "sha256:3b9f848952dddccf635be78098ca75010f073bfe14d2c6bda867154bea728d2a"}, {file = "flake8-3.9.1.tar.gz", hash = "sha256:1aa8990be1e689d96c745c5682b687ea49f2e05a443aff1f8251092b0014e378"}, ] idna = [ {file = "idna-2.10-py2.py3-none-any.whl", hash = "sha256:b97d804b1e9b523befed77c48dacec60e6dcb0b5391d57af6a65a312a90648c0"}, {file = "idna-2.10.tar.gz", hash = "sha256:b307872f855b18632ce0c21c5e45be78c0ea7ae4c15c828c20788b26921eb3f6"}, ] imagesize = [ {file = "imagesize-1.2.0-py2.py3-none-any.whl", hash = "sha256:6965f19a6a2039c7d48bca7dba2473069ff854c36ae6f19d2cde309d998228a1"}, {file = "imagesize-1.2.0.tar.gz", hash = "sha256:b1f6b5a4eab1f73479a50fb79fcf729514a900c341d8503d62a62dbc4127a2b1"}, ] imapclient = [ {file = "IMAPClient-2.1.0-py2.py3-none-any.whl", hash = "sha256:3eeb97b9aa8faab0caa5024d74bfde59408fbd542781246f6960873c7bf0dd01"}, {file = "IMAPClient-2.1.0.zip", hash = "sha256:60ba79758cc9f13ec910d7a3df9acaaf2bb6c458720d9a02ec33a41352fd1b99"}, ] importlib-metadata = [ {file = "importlib_metadata-4.0.0-py3-none-any.whl", hash = "sha256:19192b88d959336bfa6bdaaaef99aeafec179eca19c47c804e555703ee5f07ef"}, {file = "importlib_metadata-4.0.0.tar.gz", hash = "sha256:2e881981c9748d7282b374b68e759c87745c25427b67ecf0cc67fb6637a1bff9"}, ] ipdb = [ {file = "ipdb-0.12.3.tar.gz", hash = "sha256:5d9a4a0e3b7027a158fc6f2929934341045b9c3b0b86ed5d7e84e409653f72fd"}, ] ipython = [ {file = "ipython-7.16.1-py3-none-any.whl", hash = "sha256:2dbcc8c27ca7d3cfe4fcdff7f45b27f9a8d3edfa70ff8024a71c7a8eb5f09d64"}, {file = "ipython-7.16.1.tar.gz", hash = "sha256:9f4fcb31d3b2c533333893b9172264e4821c1ac91839500f31bd43f2c59b3ccf"}, ] ipython-genutils = [ {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, {file = "ipython_genutils-0.2.0.tar.gz", hash = "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8"}, ] isort = [ {file = "isort-5.8.0-py3-none-any.whl", hash = "sha256:2bb1680aad211e3c9944dbce1d4ba09a989f04e238296c87fe2139faa26d655d"}, {file = "isort-5.8.0.tar.gz", hash = "sha256:0a943902919f65c5684ac4e0154b1ad4fac6dcaa5d9f3426b732f1c8b5419be6"}, ] jedi = [ {file = "jedi-0.18.0-py2.py3-none-any.whl", hash = "sha256:18456d83f65f400ab0c2d3319e48520420ef43b23a086fdc05dff34132f0fb93"}, {file = "jedi-0.18.0.tar.gz", hash = "sha256:92550a404bad8afed881a137ec9a461fed49eca661414be45059329614ed0707"}, ] jinja2 = [ {file = "Jinja2-2.11.3-py2.py3-none-any.whl", hash = "sha256:03e47ad063331dd6a3f04a43eddca8a966a26ba0c5b7207a9a9e4e08f1b29419"}, {file = "Jinja2-2.11.3.tar.gz", hash = "sha256:a6d58433de0ae800347cab1fa3043cebbabe8baa9d29e668f1c768cb87a333c6"}, ] lazy-object-proxy = [ {file = "lazy-object-proxy-1.6.0.tar.gz", hash = "sha256:489000d368377571c6f982fba6497f2aa13c6d1facc40660963da62f5c379726"}, {file = "lazy_object_proxy-1.6.0-cp27-cp27m-macosx_10_14_x86_64.whl", hash = "sha256:c6938967f8528b3668622a9ed3b31d145fab161a32f5891ea7b84f6b790be05b"}, {file = "lazy_object_proxy-1.6.0-cp27-cp27m-win32.whl", hash = "sha256:ebfd274dcd5133e0afae738e6d9da4323c3eb021b3e13052d8cbd0e457b1256e"}, {file = "lazy_object_proxy-1.6.0-cp27-cp27m-win_amd64.whl", hash = "sha256:ed361bb83436f117f9917d282a456f9e5009ea12fd6de8742d1a4752c3017e93"}, {file = "lazy_object_proxy-1.6.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d900d949b707778696fdf01036f58c9876a0d8bfe116e8d220cfd4b15f14e741"}, {file = "lazy_object_proxy-1.6.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:5743a5ab42ae40caa8421b320ebf3a998f89c85cdc8376d6b2e00bd12bd1b587"}, {file = "lazy_object_proxy-1.6.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:bf34e368e8dd976423396555078def5cfc3039ebc6fc06d1ae2c5a65eebbcde4"}, {file = "lazy_object_proxy-1.6.0-cp36-cp36m-win32.whl", hash = "sha256:b579f8acbf2bdd9ea200b1d5dea36abd93cabf56cf626ab9c744a432e15c815f"}, {file = "lazy_object_proxy-1.6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:4f60460e9f1eb632584c9685bccea152f4ac2130e299784dbaf9fae9f49891b3"}, {file = "lazy_object_proxy-1.6.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:d7124f52f3bd259f510651450e18e0fd081ed82f3c08541dffc7b94b883aa981"}, {file = "lazy_object_proxy-1.6.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:22ddd618cefe54305df49e4c069fa65715be4ad0e78e8d252a33debf00f6ede2"}, {file = "lazy_object_proxy-1.6.0-cp37-cp37m-win32.whl", hash = "sha256:9d397bf41caad3f489e10774667310d73cb9c4258e9aed94b9ec734b34b495fd"}, {file = "lazy_object_proxy-1.6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:24a5045889cc2729033b3e604d496c2b6f588c754f7a62027ad4437a7ecc4837"}, {file = "lazy_object_proxy-1.6.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:17e0967ba374fc24141738c69736da90e94419338fd4c7c7bef01ee26b339653"}, {file = "lazy_object_proxy-1.6.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:410283732af311b51b837894fa2f24f2c0039aa7f220135192b38fcc42bd43d3"}, {file = "lazy_object_proxy-1.6.0-cp38-cp38-win32.whl", hash = "sha256:85fb7608121fd5621cc4377a8961d0b32ccf84a7285b4f1d21988b2eae2868e8"}, {file = "lazy_object_proxy-1.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:d1c2676e3d840852a2de7c7d5d76407c772927addff8d742b9808fe0afccebdf"}, {file = "lazy_object_proxy-1.6.0-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:b865b01a2e7f96db0c5d12cfea590f98d8c5ba64ad222300d93ce6ff9138bcad"}, {file = "lazy_object_proxy-1.6.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:4732c765372bd78a2d6b2150a6e99d00a78ec963375f236979c0626b97ed8e43"}, {file = "lazy_object_proxy-1.6.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:9698110e36e2df951c7c36b6729e96429c9c32b3331989ef19976592c5f3c77a"}, {file = "lazy_object_proxy-1.6.0-cp39-cp39-win32.whl", hash = "sha256:1fee665d2638491f4d6e55bd483e15ef21f6c8c2095f235fef72601021e64f61"}, {file = "lazy_object_proxy-1.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:f5144c75445ae3ca2057faac03fda5a902eff196702b0a24daf1d6ce0650514b"}, ] lxml = [ {file = "lxml-4.6.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:df7c53783a46febb0e70f6b05df2ba104610f2fb0d27023409734a3ecbb78fb2"}, {file = "lxml-4.6.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:1b7584d421d254ab86d4f0b13ec662a9014397678a7c4265a02a6d7c2b18a75f"}, {file = "lxml-4.6.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:079f3ae844f38982d156efce585bc540c16a926d4436712cf4baee0cce487a3d"}, {file = "lxml-4.6.3-cp27-cp27m-win32.whl", hash = "sha256:bc4313cbeb0e7a416a488d72f9680fffffc645f8a838bd2193809881c67dd106"}, {file = "lxml-4.6.3-cp27-cp27m-win_amd64.whl", hash = "sha256:8157dadbb09a34a6bd95a50690595e1fa0af1a99445e2744110e3dca7831c4ee"}, {file = "lxml-4.6.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:7728e05c35412ba36d3e9795ae8995e3c86958179c9770e65558ec3fdfd3724f"}, {file = "lxml-4.6.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:4bff24dfeea62f2e56f5bab929b4428ae6caba2d1eea0c2d6eb618e30a71e6d4"}, {file = "lxml-4.6.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:74f7d8d439b18fa4c385f3f5dfd11144bb87c1da034a466c5b5577d23a1d9b51"}, {file = "lxml-4.6.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:f90ba11136bfdd25cae3951af8da2e95121c9b9b93727b1b896e3fa105b2f586"}, {file = "lxml-4.6.3-cp35-cp35m-win32.whl", hash = "sha256:f2380a6376dfa090227b663f9678150ef27543483055cc327555fb592c5967e2"}, {file = "lxml-4.6.3-cp35-cp35m-win_amd64.whl", hash = "sha256:c4f05c5a7c49d2fb70223d0d5bcfbe474cf928310ac9fa6a7c6dddc831d0b1d4"}, {file = "lxml-4.6.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d2e35d7bf1c1ac8c538f88d26b396e73dd81440d59c1ef8522e1ea77b345ede4"}, {file = "lxml-4.6.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:289e9ca1a9287f08daaf796d96e06cb2bc2958891d7911ac7cae1c5f9e1e0ee3"}, {file = "lxml-4.6.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:bccbfc27563652de7dc9bdc595cb25e90b59c5f8e23e806ed0fd623755b6565d"}, {file = "lxml-4.6.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:820628b7b3135403540202e60551e741f9b6d3304371712521be939470b454ec"}, {file = "lxml-4.6.3-cp36-cp36m-win32.whl", hash = "sha256:5a0a14e264069c03e46f926be0d8919f4105c1623d620e7ec0e612a2e9bf1c04"}, {file = "lxml-4.6.3-cp36-cp36m-win_amd64.whl", hash = "sha256:92e821e43ad382332eade6812e298dc9701c75fe289f2a2d39c7960b43d1e92a"}, {file = "lxml-4.6.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:efd7a09678fd8b53117f6bae4fa3825e0a22b03ef0a932e070c0bdbb3a35e654"}, {file = "lxml-4.6.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:efac139c3f0bf4f0939f9375af4b02c5ad83a622de52d6dfa8e438e8e01d0eb0"}, {file = "lxml-4.6.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:0fbcf5565ac01dff87cbfc0ff323515c823081c5777a9fc7703ff58388c258c3"}, {file = "lxml-4.6.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:122fba10466c7bd4178b07dba427aa516286b846b2cbd6f6169141917283aae2"}, {file = "lxml-4.6.3-cp37-cp37m-win32.whl", hash = "sha256:3439c71103ef0e904ea0a1901611863e51f50b5cd5e8654a151740fde5e1cade"}, {file = "lxml-4.6.3-cp37-cp37m-win_amd64.whl", hash = "sha256:4289728b5e2000a4ad4ab8da6e1db2e093c63c08bdc0414799ee776a3f78da4b"}, {file = "lxml-4.6.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b007cbb845b28db4fb8b6a5cdcbf65bacb16a8bd328b53cbc0698688a68e1caa"}, {file = "lxml-4.6.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:76fa7b1362d19f8fbd3e75fe2fb7c79359b0af8747e6f7141c338f0bee2f871a"}, {file = "lxml-4.6.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:26e761ab5b07adf5f555ee82fb4bfc35bf93750499c6c7614bd64d12aaa67927"}, {file = "lxml-4.6.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:66e575c62792c3f9ca47cb8b6fab9e35bab91360c783d1606f758761810c9791"}, {file = "lxml-4.6.3-cp38-cp38-win32.whl", hash = "sha256:89b8b22a5ff72d89d48d0e62abb14340d9e99fd637d046c27b8b257a01ffbe28"}, {file = "lxml-4.6.3-cp38-cp38-win_amd64.whl", hash = "sha256:2a9d50e69aac3ebee695424f7dbd7b8c6d6eb7de2a2eb6b0f6c7db6aa41e02b7"}, {file = "lxml-4.6.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ce256aaa50f6cc9a649c51be3cd4ff142d67295bfc4f490c9134d0f9f6d58ef0"}, {file = "lxml-4.6.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:7610b8c31688f0b1be0ef882889817939490a36d0ee880ea562a4e1399c447a1"}, {file = "lxml-4.6.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f8380c03e45cf09f8557bdaa41e1fa7c81f3ae22828e1db470ab2a6c96d8bc23"}, {file = "lxml-4.6.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:884ab9b29feaca361f7f88d811b1eea9bfca36cf3da27768d28ad45c3ee6f969"}, {file = "lxml-4.6.3-cp39-cp39-win32.whl", hash = "sha256:33bb934a044cf32157c12bfcfbb6649807da20aa92c062ef51903415c704704f"}, {file = "lxml-4.6.3-cp39-cp39-win_amd64.whl", hash = "sha256:542d454665a3e277f76954418124d67516c5f88e51a900365ed54a9806122b83"}, {file = "lxml-4.6.3.tar.gz", hash = "sha256:39b78571b3b30645ac77b95f7c69d1bffc4cf8c3b157c435a34da72e78c82468"}, ] macos-tags = [ {file = "macos-tags-1.5.1.tar.gz", hash = "sha256:f144c5bc05d01573966d8aca2483cb345b20b76a5b32e9967786e086a38712e7"}, {file = "macos_tags-1.5.1-py3-none-any.whl", hash = "sha256:56419233af32242b703dd35bcf38c9f198abd969faddbe986eb8aaa6d95349cf"}, ] markupsafe = [ {file = "MarkupSafe-1.1.1-cp27-cp27m-macosx_10_6_intel.whl", hash = "sha256:09027a7803a62ca78792ad89403b1b7a73a01c8cb65909cd876f7fcebd79b161"}, {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:e249096428b3ae81b08327a63a485ad0878de3fb939049038579ac0ef61e17e7"}, {file = "MarkupSafe-1.1.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:500d4957e52ddc3351cabf489e79c91c17f6e0899158447047588650b5e69183"}, {file = "MarkupSafe-1.1.1-cp27-cp27m-win32.whl", hash = "sha256:b2051432115498d3562c084a49bba65d97cf251f5a331c64a12ee7e04dacc51b"}, {file = "MarkupSafe-1.1.1-cp27-cp27m-win_amd64.whl", hash = "sha256:98c7086708b163d425c67c7a91bad6e466bb99d797aa64f965e9d25c12111a5e"}, {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:cd5df75523866410809ca100dc9681e301e3c27567cf498077e8551b6d20e42f"}, {file = "MarkupSafe-1.1.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:43a55c2930bbc139570ac2452adf3d70cdbb3cfe5912c71cdce1c2c6bbd9c5d1"}, {file = "MarkupSafe-1.1.1-cp34-cp34m-macosx_10_6_intel.whl", hash = "sha256:1027c282dad077d0bae18be6794e6b6b8c91d58ed8a8d89a89d59693b9131db5"}, {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_i686.whl", hash = "sha256:62fe6c95e3ec8a7fad637b7f3d372c15ec1caa01ab47926cfdf7a75b40e0eac1"}, {file = "MarkupSafe-1.1.1-cp34-cp34m-manylinux1_x86_64.whl", hash = "sha256:88e5fcfb52ee7b911e8bb6d6aa2fd21fbecc674eadd44118a9cc3863f938e735"}, {file = "MarkupSafe-1.1.1-cp34-cp34m-win32.whl", hash = "sha256:ade5e387d2ad0d7ebf59146cc00c8044acbd863725f887353a10df825fc8ae21"}, {file = "MarkupSafe-1.1.1-cp34-cp34m-win_amd64.whl", hash = "sha256:09c4b7f37d6c648cb13f9230d847adf22f8171b1ccc4d5682398e77f40309235"}, {file = "MarkupSafe-1.1.1-cp35-cp35m-macosx_10_6_intel.whl", hash = "sha256:79855e1c5b8da654cf486b830bd42c06e8780cea587384cf6545b7d9ac013a0b"}, {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:c8716a48d94b06bb3b2524c2b77e055fb313aeb4ea620c8dd03a105574ba704f"}, {file = "MarkupSafe-1.1.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:7c1699dfe0cf8ff607dbdcc1e9b9af1755371f92a68f706051cc8c37d447c905"}, {file = "MarkupSafe-1.1.1-cp35-cp35m-win32.whl", hash = "sha256:6dd73240d2af64df90aa7c4e7481e23825ea70af4b4922f8ede5b9e35f78a3b1"}, {file = "MarkupSafe-1.1.1-cp35-cp35m-win_amd64.whl", hash = "sha256:9add70b36c5666a2ed02b43b335fe19002ee5235efd4b8a89bfcf9005bebac0d"}, {file = "MarkupSafe-1.1.1-cp36-cp36m-macosx_10_6_intel.whl", hash = "sha256:24982cc2533820871eba85ba648cd53d8623687ff11cbb805be4ff7b4c971aff"}, {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:00bc623926325b26bb9605ae9eae8a215691f33cae5df11ca5424f06f2d1f473"}, {file = "MarkupSafe-1.1.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:717ba8fe3ae9cc0006d7c451f0bb265ee07739daf76355d06366154ee68d221e"}, {file = "MarkupSafe-1.1.1-cp36-cp36m-win32.whl", hash = "sha256:535f6fc4d397c1563d08b88e485c3496cf5784e927af890fb3c3aac7f933ec66"}, {file = "MarkupSafe-1.1.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b1282f8c00509d99fef04d8ba936b156d419be841854fe901d8ae224c59f0be5"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-macosx_10_6_intel.whl", hash = "sha256:8defac2f2ccd6805ebf65f5eeb132adcf2ab57aa11fdf4c0dd5169a004710e7d"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:46c99d2de99945ec5cb54f23c8cd5689f6d7177305ebff350a58ce5f8de1669e"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:ba59edeaa2fc6114428f1637ffff42da1e311e29382d81b339c1817d37ec93c6"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-win32.whl", hash = "sha256:b00c1de48212e4cc9603895652c5c410df699856a2853135b3967591e4beebc2"}, {file = "MarkupSafe-1.1.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9bf40443012702a1d2070043cb6291650a0841ece432556f784f004937f0f32c"}, {file = "MarkupSafe-1.1.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:6788b695d50a51edb699cb55e35487e430fa21f1ed838122d722e0ff0ac5ba15"}, {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:cdb132fc825c38e1aeec2c8aa9338310d29d337bebbd7baa06889d09a60a1fa2"}, {file = "MarkupSafe-1.1.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:13d3144e1e340870b25e7b10b98d779608c02016d5184cfb9927a9f10c689f42"}, {file = "MarkupSafe-1.1.1-cp38-cp38-win32.whl", hash = "sha256:596510de112c685489095da617b5bcbbac7dd6384aeebeda4df6025d0256a81b"}, {file = "MarkupSafe-1.1.1-cp38-cp38-win_amd64.whl", hash = "sha256:e8313f01ba26fbbe36c7be1966a7b7424942f670f38e666995b88d012765b9be"}, {file = "MarkupSafe-1.1.1.tar.gz", hash = "sha256:29872e92839765e546828bb7754a68c418d927cd064fd4708fab9fe9c8bb116b"}, ] mccabe = [ {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, ] mdfind-wrapper = [ {file = "mdfind-wrapper-0.1.4.tar.gz", hash = "sha256:7b8f37e6e5037fea9722821f6d26c538abd1a08385a20820ab73158d70267653"}, {file = "mdfind_wrapper-0.1.4-py3-none-any.whl", hash = "sha256:8100c30333a7c82fd3af897cf84f6cecaa300fd6bb2ec762884d4ca6affe7a3c"}, ] more-itertools = [ {file = "more-itertools-8.7.0.tar.gz", hash = "sha256:c5d6da9ca3ff65220c3bfd2a8db06d698f05d4d2b9be57e1deb2be5a45019713"}, {file = "more_itertools-8.7.0-py3-none-any.whl", hash = "sha256:5652a9ac72209ed7df8d9c15daf4e1aa0e3d2ccd3c87f8265a0673cd9cbc9ced"}, ] mypy = [ {file = "mypy-0.812-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:a26f8ec704e5a7423c8824d425086705e381b4f1dfdef6e3a1edab7ba174ec49"}, {file = "mypy-0.812-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:28fb5479c494b1bab244620685e2eb3c3f988d71fd5d64cc753195e8ed53df7c"}, {file = "mypy-0.812-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:9743c91088d396c1a5a3c9978354b61b0382b4e3c440ce83cf77994a43e8c521"}, {file = "mypy-0.812-cp35-cp35m-win_amd64.whl", hash = "sha256:d7da2e1d5f558c37d6e8c1246f1aec1e7349e4913d8fb3cb289a35de573fe2eb"}, {file = "mypy-0.812-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4eec37370483331d13514c3f55f446fc5248d6373e7029a29ecb7b7494851e7a"}, {file = "mypy-0.812-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:d65cc1df038ef55a99e617431f0553cd77763869eebdf9042403e16089fe746c"}, {file = "mypy-0.812-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:61a3d5b97955422964be6b3baf05ff2ce7f26f52c85dd88db11d5e03e146a3a6"}, {file = "mypy-0.812-cp36-cp36m-win_amd64.whl", hash = "sha256:25adde9b862f8f9aac9d2d11971f226bd4c8fbaa89fb76bdadb267ef22d10064"}, {file = "mypy-0.812-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:552a815579aa1e995f39fd05dde6cd378e191b063f031f2acfe73ce9fb7f9e56"}, {file = "mypy-0.812-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:499c798053cdebcaa916eef8cd733e5584b5909f789de856b482cd7d069bdad8"}, {file = "mypy-0.812-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:5873888fff1c7cf5b71efbe80e0e73153fe9212fafdf8e44adfe4c20ec9f82d7"}, {file = "mypy-0.812-cp37-cp37m-win_amd64.whl", hash = "sha256:9f94aac67a2045ec719ffe6111df543bac7874cee01f41928f6969756e030564"}, {file = "mypy-0.812-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d23e0ea196702d918b60c8288561e722bf437d82cb7ef2edcd98cfa38905d506"}, {file = "mypy-0.812-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:674e822aa665b9fd75130c6c5f5ed9564a38c6cea6a6432ce47eafb68ee578c5"}, {file = "mypy-0.812-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:abf7e0c3cf117c44d9285cc6128856106183938c68fd4944763003decdcfeb66"}, {file = "mypy-0.812-cp38-cp38-win_amd64.whl", hash = "sha256:0d0a87c0e7e3a9becdfbe936c981d32e5ee0ccda3e0f07e1ef2c3d1a817cf73e"}, {file = "mypy-0.812-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7ce3175801d0ae5fdfa79b4f0cfed08807af4d075b402b7e294e6aa72af9aa2a"}, {file = "mypy-0.812-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:b09669bcda124e83708f34a94606e01b614fa71931d356c1f1a5297ba11f110a"}, {file = "mypy-0.812-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:33f159443db0829d16f0a8d83d94df3109bb6dd801975fe86bacb9bf71628e97"}, {file = "mypy-0.812-cp39-cp39-win_amd64.whl", hash = "sha256:3f2aca7f68580dc2508289c729bd49ee929a436208d2b2b6aab15745a70a57df"}, {file = "mypy-0.812-py3-none-any.whl", hash = "sha256:2f9b3407c58347a452fc0736861593e105139b905cca7d097e413453a1d650b4"}, {file = "mypy-0.812.tar.gz", hash = "sha256:cd07039aa5df222037005b08fbbfd69b3ab0b0bd7a07d7906de75ae52c4e3119"}, ] mypy-extensions = [ {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, ] olefile = [ {file = "olefile-0.46.zip", hash = "sha256:133b031eaf8fd2c9399b78b8bc5b8fcbe4c31e85295749bb17a87cba8f3c3964"}, ] packaging = [ {file = "packaging-20.9-py2.py3-none-any.whl", hash = "sha256:67714da7f7bc052e064859c05c595155bd1ee9f69f76557e21f051443c20947a"}, {file = "packaging-20.9.tar.gz", hash = "sha256:5b327ac1320dc863dca72f4514ecc086f31186744b84a230374cc1fd776feae5"}, ] parso = [ {file = "parso-0.8.2-py2.py3-none-any.whl", hash = "sha256:a8c4922db71e4fdb90e0d0bc6e50f9b273d3397925e5e60a717e719201778d22"}, {file = "parso-0.8.2.tar.gz", hash = "sha256:12b83492c6239ce32ff5eed6d3639d6a536170723c6f3f1506869f1ace413398"}, ] "pdfminer.six" = [ {file = "pdfminer.six-20181108-py2-none-any.whl", hash = "sha256:d12653375fcc00615d76dbd48fc551a2d5ffd6f572c11660d417ccf91a600f9b"}, {file = "pdfminer.six-20181108-py2.py3-none-any.whl", hash = "sha256:f04d029d1d3e58c87da51bdefef2e9a1dbf2d7b63f727dd2a3e36054f5ae96ea"}, {file = "pdfminer.six-20181108.tar.gz", hash = "sha256:9cc58857cf0a360213008061d903282462abee55cdcc7e0b6e08d6834e55050d"}, ] pendulum = [ {file = "pendulum-2.1.2-cp27-cp27m-macosx_10_15_x86_64.whl", hash = "sha256:b6c352f4bd32dff1ea7066bd31ad0f71f8d8100b9ff709fb343f3b86cee43efe"}, {file = "pendulum-2.1.2-cp27-cp27m-win_amd64.whl", hash = "sha256:318f72f62e8e23cd6660dbafe1e346950281a9aed144b5c596b2ddabc1d19739"}, {file = "pendulum-2.1.2-cp35-cp35m-macosx_10_15_x86_64.whl", hash = "sha256:0731f0c661a3cb779d398803655494893c9f581f6488048b3fb629c2342b5394"}, {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:3481fad1dc3f6f6738bd575a951d3c15d4b4ce7c82dce37cf8ac1483fde6e8b0"}, {file = "pendulum-2.1.2-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9702069c694306297ed362ce7e3c1ef8404ac8ede39f9b28b7c1a7ad8c3959e3"}, {file = "pendulum-2.1.2-cp35-cp35m-win_amd64.whl", hash = "sha256:fb53ffa0085002ddd43b6ca61a7b34f2d4d7c3ed66f931fe599e1a531b42af9b"}, {file = "pendulum-2.1.2-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:c501749fdd3d6f9e726086bf0cd4437281ed47e7bca132ddb522f86a1645d360"}, {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:c807a578a532eeb226150d5006f156632df2cc8c5693d778324b43ff8c515dd0"}, {file = "pendulum-2.1.2-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:2d1619a721df661e506eff8db8614016f0720ac171fe80dda1333ee44e684087"}, {file = "pendulum-2.1.2-cp36-cp36m-win_amd64.whl", hash = "sha256:f888f2d2909a414680a29ae74d0592758f2b9fcdee3549887779cd4055e975db"}, {file = "pendulum-2.1.2-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:e95d329384717c7bf627bf27e204bc3b15c8238fa8d9d9781d93712776c14002"}, {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:4c9c689747f39d0d02a9f94fcee737b34a5773803a64a5fdb046ee9cac7442c5"}, {file = "pendulum-2.1.2-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:1245cd0075a3c6d889f581f6325dd8404aca5884dea7223a5566c38aab94642b"}, {file = "pendulum-2.1.2-cp37-cp37m-win_amd64.whl", hash = "sha256:db0a40d8bcd27b4fb46676e8eb3c732c67a5a5e6bfab8927028224fbced0b40b"}, {file = "pendulum-2.1.2-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f5e236e7730cab1644e1b87aca3d2ff3e375a608542e90fe25685dae46310116"}, {file = "pendulum-2.1.2-cp38-cp38-manylinux1_i686.whl", hash = "sha256:de42ea3e2943171a9e95141f2eecf972480636e8e484ccffaf1e833929e9e052"}, {file = "pendulum-2.1.2-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7c5ec650cb4bec4c63a89a0242cc8c3cebcec92fcfe937c417ba18277d8560be"}, {file = "pendulum-2.1.2-cp38-cp38-win_amd64.whl", hash = "sha256:33fb61601083f3eb1d15edeb45274f73c63b3c44a8524703dc143f4212bf3269"}, {file = "pendulum-2.1.2-cp39-cp39-manylinux1_i686.whl", hash = "sha256:29c40a6f2942376185728c9a0347d7c0f07905638c83007e1d262781f1e6953a"}, {file = "pendulum-2.1.2-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:94b1fc947bfe38579b28e1cccb36f7e28a15e841f30384b5ad6c5e31055c85d7"}, {file = "pendulum-2.1.2.tar.gz", hash = "sha256:b06a0ca1bfe41c990bbf0c029f0b6501a7f2ec4e38bfec730712015e8860f207"}, ] pexpect = [ {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, ] pickleshare = [ {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, ] pillow = [ {file = "Pillow-8.2.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:dc38f57d8f20f06dd7c3161c59ca2c86893632623f33a42d592f097b00f720a9"}, {file = "Pillow-8.2.0-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:a013cbe25d20c2e0c4e85a9daf438f85121a4d0344ddc76e33fd7e3965d9af4b"}, {file = "Pillow-8.2.0-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:8bb1e155a74e1bfbacd84555ea62fa21c58e0b4e7e6b20e4447b8d07990ac78b"}, {file = "Pillow-8.2.0-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c5236606e8570542ed424849f7852a0ff0bce2c4c8d0ba05cc202a5a9c97dee9"}, {file = "Pillow-8.2.0-cp36-cp36m-win32.whl", hash = "sha256:12e5e7471f9b637762453da74e390e56cc43e486a88289995c1f4c1dc0bfe727"}, {file = "Pillow-8.2.0-cp36-cp36m-win_amd64.whl", hash = "sha256:5afe6b237a0b81bd54b53f835a153770802f164c5570bab5e005aad693dab87f"}, {file = "Pillow-8.2.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:cb7a09e173903541fa888ba010c345893cd9fc1b5891aaf060f6ca77b6a3722d"}, {file = "Pillow-8.2.0-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:0d19d70ee7c2ba97631bae1e7d4725cdb2ecf238178096e8c82ee481e189168a"}, {file = "Pillow-8.2.0-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:083781abd261bdabf090ad07bb69f8f5599943ddb539d64497ed021b2a67e5a9"}, {file = "Pillow-8.2.0-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:c6b39294464b03457f9064e98c124e09008b35a62e3189d3513e5148611c9388"}, {file = "Pillow-8.2.0-cp37-cp37m-win32.whl", hash = "sha256:01425106e4e8cee195a411f729cff2a7d61813b0b11737c12bd5991f5f14bcd5"}, {file = "Pillow-8.2.0-cp37-cp37m-win_amd64.whl", hash = "sha256:3b570f84a6161cf8865c4e08adf629441f56e32f180f7aa4ccbd2e0a5a02cba2"}, {file = "Pillow-8.2.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:031a6c88c77d08aab84fecc05c3cde8414cd6f8406f4d2b16fed1e97634cc8a4"}, {file = "Pillow-8.2.0-cp38-cp38-manylinux1_i686.whl", hash = "sha256:66cc56579fd91f517290ab02c51e3a80f581aba45fd924fcdee01fa06e635812"}, {file = "Pillow-8.2.0-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:6c32cc3145928c4305d142ebec682419a6c0a8ce9e33db900027ddca1ec39178"}, {file = "Pillow-8.2.0-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:624b977355cde8b065f6d51b98497d6cd5fbdd4f36405f7a8790e3376125e2bb"}, {file = "Pillow-8.2.0-cp38-cp38-win32.whl", hash = "sha256:5cbf3e3b1014dddc45496e8cf38b9f099c95a326275885199f427825c6522232"}, {file = "Pillow-8.2.0-cp38-cp38-win_amd64.whl", hash = "sha256:463822e2f0d81459e113372a168f2ff59723e78528f91f0bd25680ac185cf797"}, {file = "Pillow-8.2.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:95d5ef984eff897850f3a83883363da64aae1000e79cb3c321915468e8c6add5"}, {file = "Pillow-8.2.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b91c36492a4bbb1ee855b7d16fe51379e5f96b85692dc8210831fbb24c43e484"}, {file = "Pillow-8.2.0-cp39-cp39-manylinux1_i686.whl", hash = "sha256:d68cb92c408261f806b15923834203f024110a2e2872ecb0bd2a110f89d3c602"}, {file = "Pillow-8.2.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f217c3954ce5fd88303fc0c317af55d5e0204106d86dea17eb8205700d47dec2"}, {file = "Pillow-8.2.0-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:5b70110acb39f3aff6b74cf09bb4169b167e2660dabc304c1e25b6555fa781ef"}, {file = "Pillow-8.2.0-cp39-cp39-win32.whl", hash = "sha256:a7d5e9fad90eff8f6f6106d3b98b553a88b6f976e51fce287192a5d2d5363713"}, {file = "Pillow-8.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:238c197fc275b475e87c1453b05b467d2d02c2915fdfdd4af126145ff2e4610c"}, {file = "Pillow-8.2.0-pp36-pypy36_pp73-macosx_10_10_x86_64.whl", hash = "sha256:0e04d61f0064b545b989126197930807c86bcbd4534d39168f4aa5fda39bb8f9"}, {file = "Pillow-8.2.0-pp36-pypy36_pp73-manylinux2010_i686.whl", hash = "sha256:63728564c1410d99e6d1ae8e3b810fe012bc440952168af0a2877e8ff5ab96b9"}, {file = "Pillow-8.2.0-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:c03c07ed32c5324939b19e36ae5f75c660c81461e312a41aea30acdd46f93a7c"}, {file = "Pillow-8.2.0-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:4d98abdd6b1e3bf1a1cbb14c3895226816e666749ac040c4e2554231068c639b"}, {file = "Pillow-8.2.0-pp37-pypy37_pp73-manylinux2010_i686.whl", hash = "sha256:aac00e4bc94d1b7813fe882c28990c1bc2f9d0e1aa765a5f2b516e8a6a16a9e4"}, {file = "Pillow-8.2.0-pp37-pypy37_pp73-manylinux2010_x86_64.whl", hash = "sha256:22fd0f42ad15dfdde6c581347eaa4adb9a6fc4b865f90b23378aa7914895e120"}, {file = "Pillow-8.2.0-pp37-pypy37_pp73-win32.whl", hash = "sha256:e98eca29a05913e82177b3ba3d198b1728e164869c613d76d0de4bde6768a50e"}, {file = "Pillow-8.2.0.tar.gz", hash = "sha256:a787ab10d7bb5494e5f76536ac460741788f1fbce851068d73a87ca7c35fc3e1"}, ] pluggy = [ {file = "pluggy-0.13.1-py2.py3-none-any.whl", hash = "sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d"}, {file = "pluggy-0.13.1.tar.gz", hash = "sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0"}, ] prompt-toolkit = [ {file = "prompt_toolkit-3.0.3-py3-none-any.whl", hash = "sha256:c93e53af97f630f12f5f62a3274e79527936ed466f038953dfa379d4941f651a"}, {file = "prompt_toolkit-3.0.3.tar.gz", hash = "sha256:a402e9bf468b63314e37460b68ba68243d55b2f8c4d0192f85a019af3945050e"}, ] ptyprocess = [ {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, ] py = [ {file = "py-1.10.0-py2.py3-none-any.whl", hash = "sha256:3b80836aa6d1feeaa108e046da6423ab8f6ceda6468545ae8d02d9d58d18818a"}, {file = "py-1.10.0.tar.gz", hash = "sha256:21b81bda15b66ef5e1a777a21c4dcd9c20ad3efd0b3f817e7a809035269e1bd3"}, ] pycodestyle = [ {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, ] pycparser = [ {file = "pycparser-2.20-py2.py3-none-any.whl", hash = "sha256:7582ad22678f0fcd81102833f60ef8d0e57288b6b5fb00323d101be910e35705"}, {file = "pycparser-2.20.tar.gz", hash = "sha256:2d475327684562c3a96cc71adf7dc8c4f0565175cf86b6d7a404ff4c771f15f0"}, ] pycryptodome = [ {file = "pycryptodome-3.10.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:1c5e1ca507de2ad93474be5cfe2bfa76b7cf039a1a32fc196f40935944871a06"}, {file = "pycryptodome-3.10.1-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:6260e24d41149268122dd39d4ebd5941e9d107f49463f7e071fd397e29923b0c"}, {file = "pycryptodome-3.10.1-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:3f840c49d38986f6e17dbc0673d37947c88bc9d2d9dba1c01b979b36f8447db1"}, {file = "pycryptodome-3.10.1-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:2dea65df54349cdfa43d6b2e8edb83f5f8d6861e5cf7b1fbc3e34c5694c85e27"}, {file = "pycryptodome-3.10.1-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:e61e363d9a5d7916f3a4ce984a929514c0df3daf3b1b2eb5e6edbb131ee771cf"}, {file = "pycryptodome-3.10.1-cp27-cp27m-manylinux2014_aarch64.whl", hash = "sha256:2603c98ae04aac675fefcf71a6c87dc4bb74a75e9071ae3923bbc91a59f08d35"}, {file = "pycryptodome-3.10.1-cp27-cp27m-win32.whl", hash = "sha256:38661348ecb71476037f1e1f553159b80d256c00f6c0b00502acac891f7116d9"}, {file = "pycryptodome-3.10.1-cp27-cp27m-win_amd64.whl", hash = "sha256:1723ebee5561628ce96748501cdaa7afaa67329d753933296321f0be55358dce"}, {file = "pycryptodome-3.10.1-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:77997519d8eb8a4adcd9a47b9cec18f9b323e296986528186c0e9a7a15d6a07e"}, {file = "pycryptodome-3.10.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:99b2f3fc51d308286071d0953f92055504a6ffe829a832a9fc7a04318a7683dd"}, {file = "pycryptodome-3.10.1-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:e0a4d5933a88a2c98bbe19c0c722f5483dc628d7a38338ac2cb64a7dbd34064b"}, {file = "pycryptodome-3.10.1-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:d3d6958d53ad307df5e8469cc44474a75393a434addf20ecd451f38a72fe29b8"}, {file = "pycryptodome-3.10.1-cp27-cp27mu-manylinux2014_aarch64.whl", hash = "sha256:a8eb8b6ea09ec1c2535bf39914377bc8abcab2c7d30fa9225eb4fe412024e427"}, {file = "pycryptodome-3.10.1-cp35-abi3-macosx_10_9_x86_64.whl", hash = "sha256:31c1df17b3dc5f39600a4057d7db53ac372f492c955b9b75dd439f5d8b460129"}, {file = "pycryptodome-3.10.1-cp35-abi3-manylinux1_i686.whl", hash = "sha256:a3105a0eb63eacf98c2ecb0eb4aa03f77f40fbac2bdde22020bb8a536b226bb8"}, {file = "pycryptodome-3.10.1-cp35-abi3-manylinux1_x86_64.whl", hash = "sha256:a92d5c414e8ee1249e850789052608f582416e82422502dc0ac8c577808a9067"}, {file = "pycryptodome-3.10.1-cp35-abi3-manylinux2010_i686.whl", hash = "sha256:60386d1d4cfaad299803b45a5bc2089696eaf6cdd56f9fc17479a6f89595cfc8"}, {file = "pycryptodome-3.10.1-cp35-abi3-manylinux2010_x86_64.whl", hash = "sha256:501ab36aae360e31d0ec370cf5ce8ace6cb4112060d099b993bc02b36ac83fb6"}, {file = "pycryptodome-3.10.1-cp35-abi3-manylinux2014_aarch64.whl", hash = "sha256:fc7489a50323a0df02378bc2fff86eb69d94cc5639914346c736be981c6a02e7"}, {file = "pycryptodome-3.10.1-cp35-abi3-win32.whl", hash = "sha256:9b6f711b25e01931f1c61ce0115245a23cdc8b80bf8539ac0363bdcf27d649b6"}, {file = "pycryptodome-3.10.1-cp35-abi3-win_amd64.whl", hash = "sha256:7fd519b89585abf57bf47d90166903ec7b43af4fe23c92273ea09e6336af5c07"}, {file = "pycryptodome-3.10.1-pp27-pypy_73-macosx_10_9_x86_64.whl", hash = "sha256:09c1555a3fa450e7eaca41ea11cd00afe7c91fef52353488e65663777d8524e0"}, {file = "pycryptodome-3.10.1-pp27-pypy_73-manylinux1_x86_64.whl", hash = "sha256:758949ca62690b1540dfb24ad773c6da9cd0e425189e83e39c038bbd52b8e438"}, {file = "pycryptodome-3.10.1-pp27-pypy_73-manylinux2010_x86_64.whl", hash = "sha256:e3bf558c6aeb49afa9f0c06cee7fb5947ee5a1ff3bd794b653d39926b49077fa"}, {file = "pycryptodome-3.10.1-pp27-pypy_73-win32.whl", hash = "sha256:f977cdf725b20f6b8229b0c87acb98c7717e742ef9f46b113985303ae12a99da"}, {file = "pycryptodome-3.10.1-pp36-pypy36_pp73-macosx_10_9_x86_64.whl", hash = "sha256:6d2df5223b12437e644ce0a3be7809471ffa71de44ccd28b02180401982594a6"}, {file = "pycryptodome-3.10.1-pp36-pypy36_pp73-manylinux1_x86_64.whl", hash = "sha256:98213ac2b18dc1969a47bc65a79a8fca02a414249d0c8635abb081c7f38c91b6"}, {file = "pycryptodome-3.10.1-pp36-pypy36_pp73-manylinux2010_x86_64.whl", hash = "sha256:12222a5edc9ca4a29de15fbd5339099c4c26c56e13c2ceddf0b920794f26165d"}, {file = "pycryptodome-3.10.1-pp36-pypy36_pp73-win32.whl", hash = "sha256:6bbf7fee7b7948b29d7e71fcacf48bac0c57fb41332007061a933f2d996f9713"}, {file = "pycryptodome-3.10.1.tar.gz", hash = "sha256:3e2e3a06580c5f190df843cdb90ea28d61099cf4924334d5297a995de68e4673"}, ] pyflakes = [ {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, ] pygments = [ {file = "Pygments-2.8.1-py3-none-any.whl", hash = "sha256:534ef71d539ae97d4c3a4cf7d6f110f214b0e687e92f9cb9d2a3b0d3101289c8"}, {file = "Pygments-2.8.1.tar.gz", hash = "sha256:2656e1a6edcdabf4275f9a3640db59fd5de107d88e8663c5d4e9a0fa62f77f94"}, ] pylint = [ {file = "pylint-2.7.4-py3-none-any.whl", hash = "sha256:209d712ec870a0182df034ae19f347e725c1e615b2269519ab58a35b3fcbbe7a"}, {file = "pylint-2.7.4.tar.gz", hash = "sha256:bd38914c7731cdc518634a8d3c5585951302b6e2b6de60fbb3f7a0220e21eeee"}, ] pyparsing = [ {file = "pyparsing-2.4.7-py2.py3-none-any.whl", hash = "sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b"}, {file = "pyparsing-2.4.7.tar.gz", hash = "sha256:c203ec8783bf771a155b207279b9bccb8dea02d8f0c9e5f8ead507bc3246ecc1"}, ] pytest = [ {file = "pytest-4.6.11-py2.py3-none-any.whl", hash = "sha256:a00a7d79cbbdfa9d21e7d0298392a8dd4123316bfac545075e6f8f24c94d8c97"}, {file = "pytest-4.6.11.tar.gz", hash = "sha256:50fa82392f2120cc3ec2ca0a75ee615be4c479e66669789771f1758332be4353"}, ] python-dateutil = [ {file = "python-dateutil-2.8.1.tar.gz", hash = "sha256:73ebfe9dbf22e832286dafa60473e4cd239f8592f699aa5adaf10050e6e1823c"}, {file = "python_dateutil-2.8.1-py2.py3-none-any.whl", hash = "sha256:75bb3f31ea686f1197762692a9ee6a7550b59fc6ca3a1f4b5d7e32fb98e2da2a"}, ] python-pptx = [ {file = "python-pptx-0.6.18.tar.gz", hash = "sha256:a857d69e52d7e8a8fb32fca8182fdd4a3c68c689de8d4e4460e9b4a95efa7bc4"}, ] pytz = [ {file = "pytz-2021.1-py2.py3-none-any.whl", hash = "sha256:eb10ce3e7736052ed3623d49975ce333bcd712c7bb19a58b9e2089d4057d0798"}, {file = "pytz-2021.1.tar.gz", hash = "sha256:83a4a90894bf38e243cf052c8b58f381bfe9a7a483f6a9cab140bc7f702ac4da"}, ] pytzdata = [ {file = "pytzdata-2020.1-py2.py3-none-any.whl", hash = "sha256:e1e14750bcf95016381e4d472bad004eef710f2d6417240904070b3d6654485f"}, {file = "pytzdata-2020.1.tar.gz", hash = "sha256:3efa13b335a00a8de1d345ae41ec78dd11c9f8807f522d39850f2dd828681540"}, ] pyyaml = [ {file = "PyYAML-5.4.1-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:3b2b1824fe7112845700f815ff6a489360226a5609b96ec2190a45e62a9fc922"}, {file = "PyYAML-5.4.1-cp27-cp27m-win32.whl", hash = "sha256:129def1b7c1bf22faffd67b8f3724645203b79d8f4cc81f674654d9902cb4393"}, {file = "PyYAML-5.4.1-cp27-cp27m-win_amd64.whl", hash = "sha256:4465124ef1b18d9ace298060f4eccc64b0850899ac4ac53294547536533800c8"}, {file = "PyYAML-5.4.1-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:bb4191dfc9306777bc594117aee052446b3fa88737cd13b7188d0e7aa8162185"}, {file = "PyYAML-5.4.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6c78645d400265a062508ae399b60b8c167bf003db364ecb26dcab2bda048253"}, {file = "PyYAML-5.4.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:4e0583d24c881e14342eaf4ec5fbc97f934b999a6828693a99157fde912540cc"}, {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:72a01f726a9c7851ca9bfad6fd09ca4e090a023c00945ea05ba1638c09dc3347"}, {file = "PyYAML-5.4.1-cp36-cp36m-manylinux2014_s390x.whl", hash = "sha256:895f61ef02e8fed38159bb70f7e100e00f471eae2bc838cd0f4ebb21e28f8541"}, {file = "PyYAML-5.4.1-cp36-cp36m-win32.whl", hash = "sha256:3bd0e463264cf257d1ffd2e40223b197271046d09dadf73a0fe82b9c1fc385a5"}, {file = "PyYAML-5.4.1-cp36-cp36m-win_amd64.whl", hash = "sha256:e4fac90784481d221a8e4b1162afa7c47ed953be40d31ab4629ae917510051df"}, {file = "PyYAML-5.4.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:5accb17103e43963b80e6f837831f38d314a0495500067cb25afab2e8d7a4018"}, {file = "PyYAML-5.4.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:e1d4970ea66be07ae37a3c2e48b5ec63f7ba6804bdddfdbd3cfd954d25a82e63"}, {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:cb333c16912324fd5f769fff6bc5de372e9e7a202247b48870bc251ed40239aa"}, {file = "PyYAML-5.4.1-cp37-cp37m-manylinux2014_s390x.whl", hash = "sha256:fe69978f3f768926cfa37b867e3843918e012cf83f680806599ddce33c2c68b0"}, {file = "PyYAML-5.4.1-cp37-cp37m-win32.whl", hash = "sha256:dd5de0646207f053eb0d6c74ae45ba98c3395a571a2891858e87df7c9b9bd51b"}, {file = "PyYAML-5.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:08682f6b72c722394747bddaf0aa62277e02557c0fd1c42cb853016a38f8dedf"}, {file = "PyYAML-5.4.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2d9808ea7b4af864f35ea216be506ecec180628aced0704e34aca0b040ffe46"}, {file = "PyYAML-5.4.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:8c1be557ee92a20f184922c7b6424e8ab6691788e6d86137c5d93c1a6ec1b8fb"}, {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:fd7f6999a8070df521b6384004ef42833b9bd62cfee11a09bda1079b4b704247"}, {file = "PyYAML-5.4.1-cp38-cp38-manylinux2014_s390x.whl", hash = "sha256:bfb51918d4ff3d77c1c856a9699f8492c612cde32fd3bcd344af9be34999bfdc"}, {file = "PyYAML-5.4.1-cp38-cp38-win32.whl", hash = "sha256:fa5ae20527d8e831e8230cbffd9f8fe952815b2b7dae6ffec25318803a7528fc"}, {file = "PyYAML-5.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:0f5f5786c0e09baddcd8b4b45f20a7b5d61a7e7e99846e3c799b05c7c53fa696"}, {file = "PyYAML-5.4.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:294db365efa064d00b8d1ef65d8ea2c3426ac366c0c4368d930bf1c5fb497f77"}, {file = "PyYAML-5.4.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:74c1485f7707cf707a7aef42ef6322b8f97921bd89be2ab6317fd782c2d53183"}, {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:d483ad4e639292c90170eb6f7783ad19490e7a8defb3e46f97dfe4bacae89122"}, {file = "PyYAML-5.4.1-cp39-cp39-manylinux2014_s390x.whl", hash = "sha256:fdc842473cd33f45ff6bce46aea678a54e3d21f1b61a7750ce3c498eedfe25d6"}, {file = "PyYAML-5.4.1-cp39-cp39-win32.whl", hash = "sha256:49d4cdd9065b9b6e206d0595fee27a96b5dd22618e7520c33204a4a3239d5b10"}, {file = "PyYAML-5.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:c20cfa2d49991c8b4147af39859b167664f2ad4561704ee74c1de03318e898db"}, {file = "PyYAML-5.4.1.tar.gz", hash = "sha256:607774cbba28732bfa802b54baa7484215f530991055bb562efbed5b2f20a45e"}, ] requests = [ {file = "requests-2.25.1-py2.py3-none-any.whl", hash = "sha256:c210084e36a42ae6b9219e00e48287def368a26d03a048ddad7bfee44f75871e"}, {file = "requests-2.25.1.tar.gz", hash = "sha256:27973dd4a904a4f13b263a19c866c13b92a39ed1c964655f025f3f8d3d75b804"}, ] send2trash = [ {file = "Send2Trash-1.5.0-py3-none-any.whl", hash = "sha256:f1691922577b6fa12821234aeb57599d887c4900b9ca537948d2dac34aea888b"}, {file = "Send2Trash-1.5.0.tar.gz", hash = "sha256:60001cc07d707fe247c94f74ca6ac0d3255aabcb930529690897ca2a39db28b2"}, ] simplematch = [ {file = "simplematch-1.3-py3-none-any.whl", hash = "sha256:be1d9a7e5055aaf9b35d16f565d6fc198d03e2b5804e954557e1c972d2f868f9"}, {file = "simplematch-1.3.tar.gz", hash = "sha256:ed1d17d842799ee2222de1ea5f7fc3b4b1317464852214dc7dd197c1332a9f3c"}, ] six = [ {file = "six-1.12.0-py2.py3-none-any.whl", hash = "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c"}, {file = "six-1.12.0.tar.gz", hash = "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73"}, ] snowballstemmer = [ {file = "snowballstemmer-2.1.0-py2.py3-none-any.whl", hash = "sha256:b51b447bea85f9968c13b650126a888aabd4cb4463fca868ec596826325dedc2"}, {file = "snowballstemmer-2.1.0.tar.gz", hash = "sha256:e997baa4f2e9139951b6f4c631bad912dfd3c792467e2f03d7239464af90e914"}, ] sortedcontainers = [ {file = "sortedcontainers-2.3.0-py2.py3-none-any.whl", hash = "sha256:37257a32add0a3ee490bb170b599e93095eed89a55da91fa9f48753ea12fd73f"}, {file = "sortedcontainers-2.3.0.tar.gz", hash = "sha256:59cc937650cf60d677c16775597c89a960658a09cf7c1a668f86e1e4464b10a1"}, ] soupsieve = [ {file = "soupsieve-2.2.1-py3-none-any.whl", hash = "sha256:c2c1c2d44f158cdbddab7824a9af8c4f83c76b1e23e049479aa432feb6c4c23b"}, {file = "soupsieve-2.2.1.tar.gz", hash = "sha256:052774848f448cf19c7e959adf5566904d525f33a3f8b6ba6f6f8f26ec7de0cc"}, ] speechrecognition = [ {file = "SpeechRecognition-3.8.1-py2.py3-none-any.whl", hash = "sha256:4d8f73a0c05ec70331c3bacaa89ecc06dfa8d9aba0899276664cda06ab597e8e"}, ] sphinx = [ {file = "Sphinx-3.5.4-py3-none-any.whl", hash = "sha256:2320d4e994a191f4b4be27da514e46b3d6b420f2ff895d064f52415d342461e8"}, {file = "Sphinx-3.5.4.tar.gz", hash = "sha256:19010b7b9fa0dc7756a6e105b2aacd3a80f798af3c25c273be64d7beeb482cb1"}, ] sphinx-rtd-theme = [ {file = "sphinx_rtd_theme-0.5.2-py2.py3-none-any.whl", hash = "sha256:4a05bdbe8b1446d77a01e20a23ebc6777c74f43237035e76be89699308987d6f"}, {file = "sphinx_rtd_theme-0.5.2.tar.gz", hash = "sha256:32bd3b5d13dc8186d7a42fc816a23d32e83a4827d7d9882948e7b837c232da5a"}, ] sphinxcontrib-applehelp = [ {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"}, ] sphinxcontrib-devhelp = [ {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, ] sphinxcontrib-htmlhelp = [ {file = "sphinxcontrib-htmlhelp-1.0.3.tar.gz", hash = "sha256:e8f5bb7e31b2dbb25b9cc435c8ab7a79787ebf7f906155729338f3156d93659b"}, {file = "sphinxcontrib_htmlhelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:3c0bc24a2c41e340ac37c85ced6dafc879ab485c095b1d65d2461ac2f7cca86f"}, ] sphinxcontrib-jsmath = [ {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, ] sphinxcontrib-qthelp = [ {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, ] sphinxcontrib-serializinghtml = [ {file = "sphinxcontrib-serializinghtml-1.1.4.tar.gz", hash = "sha256:eaa0eccc86e982a9b939b2b82d12cc5d013385ba5eadcc7e4fed23f4405f77bc"}, {file = "sphinxcontrib_serializinghtml-1.1.4-py2.py3-none-any.whl", hash = "sha256:f242a81d423f59617a8e5cf16f5d4d74e28ee9a66f9e5b637a18082991db5a9a"}, ] textract = [ {file = "textract-1.6.3-py3-none-any.whl", hash = "sha256:ff2f4c61d720d3291e2deb870d3b24d0c63397cb4c094966e96c1bdb2f89df38"}, {file = "textract-1.6.3.tar.gz", hash = "sha256:6213b2f923b85af8e5e380241db9361e3f5dbd444a74108745fd4121ae151310"}, ] toml = [ {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, ] traitlets = [ {file = "traitlets-4.3.3-py2.py3-none-any.whl", hash = "sha256:70b4c6a1d9019d7b4f6846832288f86998aa3b9207c6821f3578a6a6a467fe44"}, {file = "traitlets-4.3.3.tar.gz", hash = "sha256:d023ee369ddd2763310e4c3eae1ff649689440d4ae59d7485eb4cfbbe3e359f7"}, ] typed-ast = [ {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:2068531575a125b87a41802130fa7e29f26c09a2833fea68d9a40cf33902eba6"}, {file = "typed_ast-1.4.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:c907f561b1e83e93fad565bac5ba9c22d96a54e7ea0267c708bffe863cbe4075"}, {file = "typed_ast-1.4.3-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:1b3ead4a96c9101bef08f9f7d1217c096f31667617b58de957f690c92378b528"}, {file = "typed_ast-1.4.3-cp35-cp35m-win32.whl", hash = "sha256:dde816ca9dac1d9c01dd504ea5967821606f02e510438120091b84e852367428"}, {file = "typed_ast-1.4.3-cp35-cp35m-win_amd64.whl", hash = "sha256:777a26c84bea6cd934422ac2e3b78863a37017618b6e5c08f92ef69853e765d3"}, {file = "typed_ast-1.4.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f8afcf15cc511ada719a88e013cec87c11aff7b91f019295eb4530f96fe5ef2f"}, {file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:52b1eb8c83f178ab787f3a4283f68258525f8d70f778a2f6dd54d3b5e5fb4341"}, {file = "typed_ast-1.4.3-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:01ae5f73431d21eead5015997ab41afa53aa1fbe252f9da060be5dad2c730ace"}, {file = "typed_ast-1.4.3-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:c190f0899e9f9f8b6b7863debfb739abcb21a5c054f911ca3596d12b8a4c4c7f"}, {file = "typed_ast-1.4.3-cp36-cp36m-win32.whl", hash = "sha256:398e44cd480f4d2b7ee8d98385ca104e35c81525dd98c519acff1b79bdaac363"}, {file = "typed_ast-1.4.3-cp36-cp36m-win_amd64.whl", hash = "sha256:bff6ad71c81b3bba8fa35f0f1921fb24ff4476235a6e94a26ada2e54370e6da7"}, {file = "typed_ast-1.4.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0fb71b8c643187d7492c1f8352f2c15b4c4af3f6338f21681d3681b3dc31a266"}, {file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:760ad187b1041a154f0e4d0f6aae3e40fdb51d6de16e5c99aedadd9246450e9e"}, {file = "typed_ast-1.4.3-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5feca99c17af94057417d744607b82dd0a664fd5e4ca98061480fd8b14b18d04"}, {file = "typed_ast-1.4.3-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:95431a26309a21874005845c21118c83991c63ea800dd44843e42a916aec5899"}, {file = "typed_ast-1.4.3-cp37-cp37m-win32.whl", hash = "sha256:aee0c1256be6c07bd3e1263ff920c325b59849dc95392a05f258bb9b259cf39c"}, {file = "typed_ast-1.4.3-cp37-cp37m-win_amd64.whl", hash = "sha256:9ad2c92ec681e02baf81fdfa056fe0d818645efa9af1f1cd5fd6f1bd2bdfd805"}, {file = "typed_ast-1.4.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b36b4f3920103a25e1d5d024d155c504080959582b928e91cb608a65c3a49e1a"}, {file = "typed_ast-1.4.3-cp38-cp38-manylinux1_i686.whl", hash = "sha256:067a74454df670dcaa4e59349a2e5c81e567d8d65458d480a5b3dfecec08c5ff"}, {file = "typed_ast-1.4.3-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7538e495704e2ccda9b234b82423a4038f324f3a10c43bc088a1636180f11a41"}, {file = "typed_ast-1.4.3-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:af3d4a73793725138d6b334d9d247ce7e5f084d96284ed23f22ee626a7b88e39"}, {file = "typed_ast-1.4.3-cp38-cp38-win32.whl", hash = "sha256:f2362f3cb0f3172c42938946dbc5b7843c2a28aec307c49100c8b38764eb6927"}, {file = "typed_ast-1.4.3-cp38-cp38-win_amd64.whl", hash = "sha256:dd4a21253f42b8d2b48410cb31fe501d32f8b9fbeb1f55063ad102fe9c425e40"}, {file = "typed_ast-1.4.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f328adcfebed9f11301eaedfa48e15bdece9b519fb27e6a8c01aa52a17ec31b3"}, {file = "typed_ast-1.4.3-cp39-cp39-manylinux1_i686.whl", hash = "sha256:2c726c276d09fc5c414693a2de063f521052d9ea7c240ce553316f70656c84d4"}, {file = "typed_ast-1.4.3-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:cae53c389825d3b46fb37538441f75d6aecc4174f615d048321b716df2757fb0"}, {file = "typed_ast-1.4.3-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:b9574c6f03f685070d859e75c7f9eeca02d6933273b5e69572e5ff9d5e3931c3"}, {file = "typed_ast-1.4.3-cp39-cp39-win32.whl", hash = "sha256:209596a4ec71d990d71d5e0d312ac935d86930e6eecff6ccc7007fe54d703808"}, {file = "typed_ast-1.4.3-cp39-cp39-win_amd64.whl", hash = "sha256:9c6d1a54552b5330bc657b7ef0eae25d00ba7ffe85d9ea8ae6540d2197a3788c"}, {file = "typed_ast-1.4.3.tar.gz", hash = "sha256:fb1bbeac803adea29cedd70781399c99138358c26d05fcbd23c13016b7f5ec65"}, ] typing-extensions = [ {file = "typing_extensions-3.7.4.3-py2-none-any.whl", hash = "sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f"}, {file = "typing_extensions-3.7.4.3-py3-none-any.whl", hash = "sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918"}, {file = "typing_extensions-3.7.4.3.tar.gz", hash = "sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c"}, ] tzlocal = [ {file = "tzlocal-1.5.1.tar.gz", hash = "sha256:4ebeb848845ac898da6519b9b31879cf13b6626f7184c496037b818e238f2c4e"}, ] urllib3 = [ {file = "urllib3-1.26.4-py2.py3-none-any.whl", hash = "sha256:2f4da4594db7e1e110a944bb1b551fdf4e6c136ad42e4234131391e21eb5b0df"}, {file = "urllib3-1.26.4.tar.gz", hash = "sha256:e7b021f7241115872f92f43c6508082facffbd1c048e3c6e2bb9c2a157e28937"}, ] wcwidth = [ {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, ] wrapt = [ {file = "wrapt-1.12.1.tar.gz", hash = "sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7"}, ] xattr = [ {file = "xattr-0.9.7-cp27-cp27m-macosx_10_13_x86_64.whl", hash = "sha256:1b2cd125150aa9bbfb02929627101b3303920a68487e9c865ddd170188ddd796"}, {file = "xattr-0.9.7-cp36-cp36m-macosx_10_13_x86_64.whl", hash = "sha256:e2c72a3a501bac715489180ca2b646e48a1ca3a794c1103dd6f0f987d43f570c"}, {file = "xattr-0.9.7-cp37-cp37m-macosx_10_13_x86_64.whl", hash = "sha256:1e11ba8ab86dfe74419704c53722ea9b5915833db07416e7c10db5dfb02218bb"}, {file = "xattr-0.9.7.tar.gz", hash = "sha256:b0bbca828e04ef2d484a6522ae7b3a7ccad5e43fa1c6f54d78e24bb870f49d44"}, ] xlrd = [ {file = "xlrd-1.2.0-py2.py3-none-any.whl", hash = "sha256:e551fb498759fa3a5384a94ccd4c3c02eb7c00ea424426e212ac0c57be9dfbde"}, {file = "xlrd-1.2.0.tar.gz", hash = "sha256:546eb36cee8db40c3eaa46c351e67ffee6eeb5fa2650b71bc4c758a29a1b29b2"}, ] xlsxwriter = [ {file = "XlsxWriter-1.3.9-py2.py3-none-any.whl", hash = "sha256:e74dca4f2e946a117a541ca3153c06466190a88bb67fcdbd1cba2c1ea7f1fd76"}, {file = "XlsxWriter-1.3.9.tar.gz", hash = "sha256:eca2e737d0b8df3cd72520fadcda9f48c3581282639965125a86ea8cd04620cf"}, ] zipp = [ {file = "zipp-3.4.1-py3-none-any.whl", hash = "sha256:51cb66cc54621609dd593d1787f286ee42a5c0adbb4b29abea5a63edc3e03098"}, {file = "zipp-3.4.1.tar.gz", hash = "sha256:3607921face881ba3e026887d8150cca609d517579abe052ac81fc5aeffdbd76"}, ] organize-1.10.1/pyproject.toml000066400000000000000000000027011403777030400163310ustar00rootroot00000000000000[tool.poetry] name = "organize-tool" version = "1.10.1" description = "The file management automation tool" packages = [ { include = "organize" }, ] authors = ["Thomas Feldmann "] license = "MIT" readme = "README.md" repository = "https://github.com/tfeldmann/organize" documentation = "https://organize.readthedocs.io" keywords = ["file", "management", "automation", "tool", "organization", "rules", "yaml"] classifiers = [ # Full list: https://pypi.python.org/pypi?%3Aaction=list_classifiers "Development Status :: 5 - Production/Stable", "Environment :: Console", "Intended Audience :: End Users/Desktop", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python :: 3", "Topic :: Utilities", ] [tool.poetry.scripts] organize = "organize.cli:main" [tool.poetry.dependencies] python = "^3.6" appdirs = "^1.4.4" docopt = "^0.6.2" PyYAML = "^5.4.1" Send2Trash = "^1.5.0" colorama = "^0.4.4" exifread = "^2.1" textract = { version = "^1.6.3", optional = true } pendulum = "^2.0.5" simplematch = "^1.3" macos-tags = { version = "^1.5.1", markers = "sys_platform == 'darwin'"} [tool.poetry.extras] textract = ["textract"] [tool.poetry.dev-dependencies] pytest = "^4.6" pylint = "^2.3" ipdb = "^0.12.0" sphinx = "^3.1.0" sphinx-rtd-theme = "^0.5.2" mypy = "^0.812" flake8 = "^3.9.1" [build-system] requires = ["poetry-core>=1.0.0"] build-backend = "poetry.core.masonry.api" organize-1.10.1/tests/000077500000000000000000000000001403777030400145575ustar00rootroot00000000000000organize-1.10.1/tests/actions/000077500000000000000000000000001403777030400162175ustar00rootroot00000000000000organize-1.10.1/tests/actions/__init__.py000066400000000000000000000000001403777030400203160ustar00rootroot00000000000000organize-1.10.1/tests/actions/test_copy.py000066400000000000000000000122761403777030400206120ustar00rootroot00000000000000import os from organize.actions import Copy from pathlib import Path USER_DIR = os.path.expanduser("~") DEFAULT_ARGS = { "basedir": Path.home(), "path": Path.home() / "test.py", "simulate": False, } def test_tilde_expansion(mock_exists, mock_samefile, mock_copy, mock_trash, mock_mkdir): mock_exists.return_value = False mock_samefile.return_value = False copy = Copy(dest="~/newname.py", overwrite=False) updates = copy.run(**DEFAULT_ARGS) mock_mkdir.assert_called_with(exist_ok=True, parents=True) mock_exists.assert_called_with() mock_trash.assert_not_called() mock_copy.assert_called_with( src=os.path.join(USER_DIR, "test.py"), dst=os.path.join(USER_DIR, "newname.py") ) # keep old file path assert updates is None def test_into_folder(mock_exists, mock_samefile, mock_copy, mock_trash, mock_mkdir): mock_exists.return_value = False mock_samefile.return_value = False copy = Copy(dest="~/somefolder/", overwrite=False) copy.run(**DEFAULT_ARGS) mock_mkdir.assert_called_with(exist_ok=True, parents=True) mock_exists.assert_called_with() mock_trash.assert_not_called() mock_copy.assert_called_with( src=os.path.join(USER_DIR, "test.py"), dst=os.path.join(USER_DIR, "somefolder", "test.py"), ) def test_overwrite(mock_exists, mock_samefile, mock_copy, mock_trash, mock_mkdir): mock_exists.return_value = True mock_samefile.return_value = False copy = Copy(dest="~/somefolder/", overwrite=True) copy.run(**DEFAULT_ARGS) mock_mkdir.assert_called_with(exist_ok=True, parents=True) mock_exists.assert_called_with() mock_trash.assert_called_with(os.path.join(USER_DIR, "somefolder", "test.py")) mock_copy.assert_called_with( src=os.path.join(USER_DIR, "test.py"), dst=os.path.join(USER_DIR, "somefolder", "test.py"), ) def test_already_exists(mock_exists, mock_samefile, mock_copy, mock_trash, mock_mkdir): mock_exists.side_effect = [True, False] mock_samefile.return_value = False copy = Copy(dest="~/folder/", overwrite=False) copy.run(**DEFAULT_ARGS) mock_mkdir.assert_called_with(exist_ok=True, parents=True) mock_exists.assert_called_with() mock_trash.assert_not_called() mock_copy.assert_called_with( src=os.path.join(USER_DIR, "test.py"), dst=os.path.join(USER_DIR, "folder", "test 2.py"), ) def test_already_exists_multiple( mock_exists, mock_samefile, mock_copy, mock_trash, mock_mkdir ): mock_exists.side_effect = [True, True, True, False] mock_samefile.return_value = False copy = Copy(dest="~/folder/", overwrite=False) copy.run(**DEFAULT_ARGS) mock_mkdir.assert_called_with(exist_ok=True, parents=True) mock_exists.assert_called_with() mock_trash.assert_not_called() mock_copy.assert_called_with( src=os.path.join(USER_DIR, "test.py"), dst=os.path.join(USER_DIR, "folder", "test 4.py"), ) def test_already_exists_multiple_with_separator( mock_exists, mock_samefile, mock_copy, mock_trash, mock_mkdir ): args = { "basedir": Path.home(), "path": Path.home() / "test_2.py", "simulate": False, } mock_exists.side_effect = [True, True, True, False] mock_samefile.return_value = False copy = Copy(dest="~/folder/", overwrite=False, counter_separator="_") copy.run(**args) mock_mkdir.assert_called_with(exist_ok=True, parents=True) mock_exists.assert_called_with() mock_trash.assert_not_called() mock_copy.assert_called_with( src=os.path.join(USER_DIR, "test_2.py"), dst=os.path.join(USER_DIR, "folder", "test_5.py"), ) def test_makedirs(mock_parent, mock_copy, mock_trash): copy = Copy(dest="~/some/new/folder/", overwrite=False) copy.run(**DEFAULT_ARGS) mock_parent.mkdir.assert_called_with(parents=True, exist_ok=True) mock_trash.assert_not_called() mock_copy.assert_called_with( src=os.path.join(USER_DIR, "test.py"), dst=os.path.join(USER_DIR, "some", "new", "folder", "test.py"), ) def test_args(mock_exists, mock_samefile, mock_copy, mock_trash, mock_mkdir): args = { "basedir": Path.home(), "path": Path.home() / "test.py", "simulate": False, "nr": {"upper": 1}, } mock_exists.return_value = False mock_samefile.return_value = False copy = Copy(dest="~/{nr.upper}-name.py", overwrite=False) copy.run(**args) mock_mkdir.assert_called_with(exist_ok=True, parents=True) mock_exists.assert_called_with() mock_trash.assert_not_called() mock_copy.assert_called_with( src=os.path.join(USER_DIR, "test.py"), dst=os.path.join(USER_DIR, "1-name.py") ) def test_path(mock_exists, mock_samefile, mock_copy, mock_trash, mock_mkdir): mock_exists.return_value = False mock_samefile.return_value = False copy = Copy(dest="~/{path.stem}/{path.suffix}/{path.name}", overwrite=False) copy.run(**DEFAULT_ARGS) mock_mkdir.assert_called_with(exist_ok=True, parents=True) mock_exists.assert_called_with() mock_trash.assert_not_called() mock_copy.assert_called_with( src=os.path.join(USER_DIR, "test.py"), dst=os.path.join(USER_DIR, "test", ".py", "test.py"), ) organize-1.10.1/tests/actions/test_echo.py000066400000000000000000000013461403777030400205520ustar00rootroot00000000000000from organize.actions import Echo from pathlib import Path from unittest.mock import patch def test_echo_basic(): echo = Echo("Hello World") with patch.object(echo, "print") as m: echo.run(path=Path("~"), simulate=False) m.assert_called_with("Hello World") def test_echo_args(): echo = Echo("This is the year {year}") with patch.object(echo, "print") as m: echo.run(path=Path("~"), simulate=False, year=2017) m.assert_called_with("This is the year 2017") def test_echo_path(): echo = Echo("{path.stem} for {year}") with patch.object(echo, "print") as m: echo.run(simulate=False, path=Path("/this/isafile.txt"), year=2017) m.assert_called_with("isafile for 2017") organize-1.10.1/tests/actions/test_move.py000066400000000000000000000141371403777030400206040ustar00rootroot00000000000000import os from organize.actions import Move from pathlib import Path from organize.utils import DotDict USER_DIR = os.path.expanduser("~") ARGS = DotDict(basedir=Path.home(), path=Path.home() / "test.py", simulate=False) def test_tilde_expansion(mock_exists, mock_samefile, mock_move, mock_trash, mock_mkdir): mock_exists.return_value = False mock_samefile.return_value = False move = Move(dest="~/newname.py", overwrite=False) updates = move.run(**ARGS) mock_mkdir.assert_called_with(exist_ok=True, parents=True) mock_exists.assert_called_with() mock_trash.assert_not_called() mock_move.assert_called_with( src=os.path.join(USER_DIR, "test.py"), dst=os.path.join(USER_DIR, "newname.py") ) assert updates == {"path": Path("~/newname.py").expanduser()} def test_into_folder(mock_exists, mock_samefile, mock_move, mock_trash, mock_mkdir): mock_exists.return_value = False mock_samefile.return_value = False move = Move(dest="~/somefolder/", overwrite=False) updates = move.run(**ARGS) mock_mkdir.assert_called_with(exist_ok=True, parents=True) mock_exists.assert_called_with() mock_trash.assert_not_called() mock_move.assert_called_with( src=os.path.join(USER_DIR, "test.py"), dst=os.path.join(USER_DIR, "somefolder", "test.py"), ) assert updates == {"path": Path(USER_DIR) / "somefolder" / "test.py"} def test_overwrite(mock_exists, mock_samefile, mock_move, mock_trash, mock_mkdir): mock_exists.return_value = True mock_samefile.return_value = False move = Move(dest="~/somefolder/", overwrite=True) updates = move.run(**ARGS) mock_mkdir.assert_called_with(exist_ok=True, parents=True) mock_exists.assert_called_with() mock_trash.assert_called_with(os.path.join(USER_DIR, "somefolder", "test.py")) mock_move.assert_called_with( src=os.path.join(USER_DIR, "test.py"), dst=os.path.join(USER_DIR, "somefolder", "test.py"), ) assert updates is not None def test_already_exists(mock_exists, mock_samefile, mock_move, mock_trash, mock_mkdir): mock_exists.side_effect = [True, False] mock_samefile.return_value = False move = Move(dest="~/folder/", overwrite=False) updates = move.run(**ARGS) mock_mkdir.assert_called_with(exist_ok=True, parents=True) mock_exists.assert_called_with() mock_trash.assert_not_called() mock_move.assert_called_with( src=os.path.join(USER_DIR, "test.py"), dst=os.path.join(USER_DIR, "folder", "test 2.py"), ) assert updates is not None def test_already_exists_multiple( mock_exists, mock_samefile, mock_move, mock_trash, mock_mkdir ): mock_exists.side_effect = [True, True, True, False] mock_samefile.return_value = False move = Move(dest="~/folder/", overwrite=False) updates = move.run(**ARGS) mock_mkdir.assert_called_with(exist_ok=True, parents=True) mock_exists.assert_called_with() mock_trash.assert_not_called() mock_move.assert_called_with( src=os.path.join(USER_DIR, "test.py"), dst=os.path.join(USER_DIR, "folder", "test 4.py"), ) assert updates is not None def test_already_exists_multiple_separator( mock_exists, mock_samefile, mock_move, mock_trash, mock_mkdir ): mock_exists.side_effect = [True, True, True, False] mock_samefile.return_value = False move = Move(dest="~/folder/", overwrite=False, counter_separator="_") updates = move.run(**ARGS) mock_mkdir.assert_called_with(exist_ok=True, parents=True) mock_exists.assert_called_with() mock_trash.assert_not_called() mock_move.assert_called_with( src=os.path.join(USER_DIR, "test.py"), dst=os.path.join(USER_DIR, "folder", "test_4.py"), ) assert updates is not None def test_makedirs(mock_parent, mock_move, mock_trash): move = Move(dest="~/some/new/folder/", overwrite=False) updates = move.run(**ARGS) mock_parent.mkdir.assert_called_with(parents=True, exist_ok=True) mock_trash.assert_not_called() mock_move.assert_called_with( src=os.path.join(USER_DIR, "test.py"), dst=os.path.join(USER_DIR, "some", "new", "folder", "test.py"), ) assert updates is not None def test_args(mock_exists, mock_samefile, mock_move, mock_trash, mock_mkdir): args = ARGS.merge({"nr": {"upper": 1}}) mock_exists.return_value = False mock_samefile.return_value = False move = Move(dest="~/{nr.upper}-name.py", overwrite=False) updates = move.run(**args) mock_mkdir.assert_called_with(exist_ok=True, parents=True) mock_exists.assert_called_with() mock_trash.assert_not_called() mock_move.assert_called_with( src=os.path.join(USER_DIR, "test.py"), dst=os.path.join(USER_DIR, "1-name.py") ) assert updates is not None def test_path(mock_exists, mock_samefile, mock_move, mock_trash, mock_mkdir): mock_exists.return_value = False mock_samefile.return_value = False move = Move(dest="~/{path.stem}/{path.suffix}/{path.name}", overwrite=False) updates = move.run(**ARGS) mock_mkdir.assert_called_with(exist_ok=True, parents=True) mock_exists.assert_called_with() mock_trash.assert_not_called() mock_move.assert_called_with( src=os.path.join(USER_DIR, "test.py"), dst=os.path.join(USER_DIR, "test", ".py", "test.py"), ) assert updates is not None def test_keep_location(mock_exists, mock_samefile, mock_move, mock_trash, mock_mkdir): mock_exists.return_value = True mock_samefile.return_value = True move = Move(dest="~/test.py") updates = move.run(**ARGS) mock_mkdir.assert_not_called() mock_exists.assert_called_with() mock_trash.assert_not_called() mock_move.assert_not_called() assert updates is not None def test_dont_keep_case_sensitive( mock_exists, mock_samefile, mock_move, mock_trash, mock_mkdir ): mock_exists.return_value = True mock_samefile.return_value = True move = Move(dest="~/TEST.PY") updates = move.run(**ARGS) assert mock_mkdir.call_count > 0 mock_exists.assert_called_with() mock_trash.assert_not_called() assert mock_move.call_count > 0 assert updates is not None organize-1.10.1/tests/actions/test_python.py000066400000000000000000000011731403777030400211530ustar00rootroot00000000000000from unittest.mock import patch from organize.actions import Python from pathlib import Path def test_print_substitution(): with patch.object(Python, "print") as mock_print: python = Python("print('Hello World')") python.run(path=Path.home(), simulate=False) mock_print.assert_called_with("Hello World") def test_code_execution(): with patch.object(Python, "print") as mock_print: path = Path("/some/folder") python = Python("print(x)\nprint(path)") python.run(path=path, x=42, simulate=False) mock_print.assert_any_call(42) mock_print.assert_any_call(path) organize-1.10.1/tests/actions/test_rename.py000066400000000000000000000077311403777030400211070ustar00rootroot00000000000000import os from organize.actions import Rename from pathlib import Path USER_DIR = os.path.expanduser("~") ARGS = {"basedir": Path.home(), "path": Path.home() / "test.py", "simulate": False} def test_tilde_expansion(mock_exists, mock_samefile, mock_rename, mock_trash): mock_exists.return_value = False mock_samefile.return_value = False rename = Rename(name="newname.py", overwrite=False) new_path = rename.run(**ARGS) assert mock_exists.call_count > 0 mock_trash.assert_not_called() expected_path = (Path.home() / "newname.py").expanduser() mock_rename.assert_called_with(expected_path) assert new_path == {'path': expected_path} def test_overwrite(mock_exists, mock_samefile, mock_rename, mock_trash): mock_exists.return_value = True mock_samefile.return_value = False rename = Rename(name="{path.stem} Kopie.py", overwrite=True) new_path = rename.run(**ARGS) assert mock_exists.call_count > 0 mock_trash.assert_called_with(os.path.join(USER_DIR, "test Kopie.py")) mock_rename.assert_called_with(Path("~/test Kopie.py").expanduser()) assert new_path is not None def test_already_exists(mock_exists, mock_samefile, mock_rename, mock_trash): mock_exists.side_effect = [True, False] mock_samefile.return_value = False rename = Rename(name="asd.txt", overwrite=False) new_path = rename.run(**ARGS) assert mock_exists.call_count > 0 mock_trash.assert_not_called() mock_rename.assert_called_with(Path("~/asd 2.txt").expanduser()) assert new_path is not None def test_overwrite_samefile(mock_exists, mock_samefile, mock_rename, mock_trash): args = {"basedir": Path.home(), "path": Path.home() / "test.PDF", "simulate": False} mock_exists.return_value = True mock_samefile.return_value = True rename = Rename(name="{path.stem}.pdf", overwrite=False) new_path = rename.run(**args) assert mock_exists.call_count > 0 mock_trash.assert_not_called() mock_rename.assert_called_with((Path.home() / "test.pdf").expanduser()) assert new_path is not None def test_keep_name(mock_exists, mock_samefile, mock_rename, mock_trash): args = {"basedir": Path.home(), "path": Path.home() / "test.pdf", "simulate": False} mock_exists.return_value = True mock_samefile.return_value = True rename = Rename(name="{path.stem}.pdf", overwrite=False) new_path = rename.run(**args) assert mock_exists.call_count > 0 mock_trash.assert_not_called() mock_rename.assert_not_called() assert new_path is not None def test_already_exists_multiple(mock_exists, mock_samefile, mock_rename, mock_trash): mock_exists.side_effect = [True, True, True, False] mock_samefile.return_value = False rename = Rename(name="asd.txt", overwrite=False) new_path = rename.run(**ARGS) assert mock_exists.call_count > 0 mock_trash.assert_not_called() mock_rename.assert_called_with(Path("~/asd 4.txt").expanduser()) assert new_path is not None def test_already_exists_multiple_separator( mock_exists, mock_samefile, mock_rename, mock_trash ): mock_exists.side_effect = [True, True, True, False] mock_samefile.return_value = False rename = Rename(name="asd.txt", overwrite=False, counter_separator="-") new_path = rename.run(**ARGS) assert mock_exists.call_count > 0 mock_trash.assert_not_called() mock_rename.assert_called_with(Path("~/asd-4.txt").expanduser()) assert new_path is not None def test_args(mock_exists, mock_samefile, mock_rename, mock_trash): args = { "basedir": Path.home(), "path": Path.home() / "test.py", "nr": {"upper": 1}, "simulate": False, } mock_exists.return_value = False mock_samefile.return_value = False rename = Rename(name="{nr.upper}-{path.stem} Kopie.py") new_path = rename.run(**args) assert mock_exists.call_count > 0 mock_trash.assert_not_called() mock_rename.assert_called_with(Path("~/1-test Kopie.py").expanduser()) assert new_path is not None organize-1.10.1/tests/actions/test_shell.py000066400000000000000000000014471403777030400207450ustar00rootroot00000000000000from unittest.mock import patch from organize.actions import Shell from pathlib import Path def test_shell_basic(): with patch("subprocess.call") as m: shell = Shell("echo 'Hello World'") shell.run(path=Path.home(), simulate=False) m.assert_called_with("echo 'Hello World'", shell=True) def test_shell_args(): with patch("subprocess.call") as m: shell = Shell("echo {year}") shell.run(path=Path.home(), year=2017, simulate=False) m.assert_called_with("echo 2017", shell=True) def test_shell_path(): with patch("subprocess.call") as m: shell = Shell("echo {path.stem} for {year}") shell.run(path=Path("/") / "this" / "isafile.txt", year=2017, simulate=False) m.assert_called_with("echo isafile for 2017", shell=True) organize-1.10.1/tests/actions/test_trash.py000066400000000000000000000004671403777030400207600ustar00rootroot00000000000000import os from organize.actions import Trash from pathlib import Path USER_DIR = os.path.expanduser("~") def test_trash(mock_trash): trash = Trash() trash.run(path=Path.home() / "this" / "file.tar.gz", simulate=False) mock_trash.assert_called_with(os.path.join(USER_DIR, "this", "file.tar.gz")) organize-1.10.1/tests/conftest.py000066400000000000000000000036201403777030400167570ustar00rootroot00000000000000import os from typing import Iterable, Tuple, Union from unittest.mock import patch import pytest from pathlib import Path from organize.utils import DotDict TESTS_FOLDER = os.path.dirname(os.path.abspath(__file__)) TESTS_FOLDER = os.path.dirname(os.path.abspath(__file__)) def create_filesystem(tmp_path, files, config): # create files for f in files: try: name, content = f except Exception: name = f content = "" p = tmp_path / "files" / Path(name) p.parent.mkdir(parents=True, exist_ok=True) with p.open("w") as ptr: ptr.write(content) # create config with (tmp_path / "config.yaml").open("w") as f: f.write(config) # change working directory os.chdir(str(tmp_path)) def assertdir(path, *files): os.chdir(str(path / "files")) assert set(files) == set(str(x) for x in Path(".").glob("**/*") if x.is_file()) @pytest.fixture def mock_exists(): with patch.object(Path, "exists") as mck: yield mck @pytest.fixture def mock_samefile(): with patch.object(Path, "samefile") as mck: yield mck @pytest.fixture def mock_rename(): with patch.object(Path, "rename") as mck: yield mck @pytest.fixture def mock_move(): with patch("shutil.move") as mck: yield mck @pytest.fixture def mock_copy(): with patch("shutil.copy2") as mck: yield mck @pytest.fixture def mock_remove(): with patch("os.remove") as mck: yield mck @pytest.fixture def mock_trash(): with patch("send2trash.send2trash") as mck: yield mck @pytest.fixture def mock_parent(): with patch.object(Path, "parent") as mck: yield mck @pytest.fixture def mock_mkdir(): with patch.object(Path, "mkdir") as mck: yield mck @pytest.fixture def mock_echo(): with patch("organize.actions.Echo.print") as mck: yield mck organize-1.10.1/tests/core/000077500000000000000000000000001403777030400155075ustar00rootroot00000000000000organize-1.10.1/tests/core/__init__.py000066400000000000000000000000001403777030400176060ustar00rootroot00000000000000organize-1.10.1/tests/core/test_config.py000066400000000000000000000231441403777030400203710ustar00rootroot00000000000000import pytest from organize.actions import Echo, Move, Shell, Trash, Rename from organize.config import Config, Rule from organize.filters import Extension, LastModified, FileContent, Filename def test_basic(): config = """ rules: - folders: '~/Desktop' filters: - extension: - jpg - png - extension: txt actions: - move: {dest: '~/Desktop/New Folder', overwrite: true} - echo: 'Moved {path}/{extension.upper}' - folders: - '~/test1' - '/test2' filters: actions: - shell: cmd: 'say {path.stem}' """ conf = Config.from_string(config) assert conf.rules == [ Rule( folders=["~/Desktop"], filters=[Extension(".JPG", "PNG"), Extension("txt")], actions=[ Move(dest="~/Desktop/New Folder", overwrite=True), Echo(msg="Moved {path}/{extension.upper}"), ], subfolders=False, system_files=False, ), Rule( folders=["~/test1", "/test2"], filters=[], actions=[Shell(cmd="say {path.stem}")], subfolders=False, system_files=False, ), ] def test_case_insensitive(): config = """ rules: - folders: '~/Desktop' filters: - extension: ['JPg', 'png'] - Extension: txt actions: - moVe: {dest: '~/Desktop/New Folder', overwrite: true} - EC_HO: 'Moved {path}/{extension.upper}' - folders: - '~/test1' - /test2 filters: actions: - SHELL: cmd: 'say {path.stem}' """ conf = Config.from_string(config) assert conf.rules == [ Rule( folders=["~/Desktop"], filters=[Extension(".JPG", "PNG"), Extension("txt")], actions=[ Move(dest="~/Desktop/New Folder", overwrite=True), Echo(msg="Moved {path}/{extension.upper}"), ], subfolders=False, system_files=False, ), Rule( folders=["~/test1", "/test2"], filters=[], actions=[Shell(cmd="say {path.stem}")], subfolders=False, system_files=False, ), ] def test_yaml_ref(): config = """ media: &media - wav - png all_folders: &all - ~/Desktop - ~/Documents rules: - folders: *all filters: - extension: *media - extension: - *media - jpg - lastmodified: days: 10 actions: - echo: msg: 'Hello World' - folders: - *all - /more/more filters: actions: - trash """ conf = Config.from_string(config) assert conf.rules == [ Rule( folders=["~/Desktop", "~/Documents"], filters=[ Extension(".wav", ".PNG"), Extension(".wav", ".PNG", "jpg"), LastModified(days=10), ], actions=[Echo(msg="Hello World")], subfolders=False, system_files=False, ), Rule( folders=["~/Desktop", "~/Documents", "/more/more"], filters=[], actions=[Trash()], subfolders=False, system_files=False, ), ] def test_error_filter_dict(): conf = Config.from_string( """ rules: - folders: '/' filters: Extension: 'jpg' actions: - trash """ ) with pytest.raises(Config.FiltersNoListError): _ = conf.rules def test_error_action_dict(): conf = Config.from_string( """ rules: - folders: '/' filters: - extension: 'jpg' actions: Trash """ ) with pytest.raises(Config.ActionsNoListError): _ = conf.rules def test_empty_filters(): conf = """ rules: - folders: '/' filters: actions: - trash - folders: '~/' actions: - trash """ assert Config.from_string(conf).rules == [ Rule( folders=["/"], filters=[], actions=[Trash()], subfolders=False, system_files=False, ), Rule( folders=["~/"], filters=[], actions=[Trash()], subfolders=False, system_files=False, ), ] @pytest.mark.skip def test_flatten_filters_and_actions(): config = """ folder_aliases: Downloads: &downloads ~/Downloads/ Payables_due: &payables_due ~/PayablesDue/ Payables_paid: &payables_paid ~/Accounting/Expenses/ Receivables_due: &receivables_due ~/Receivables/ Receivables_paid: &receivables_paid ~/Accounting/Income/ defaults: filters: &default_filters - extension: pdf - filecontent: '(?P...)' actions: &default_actions - echo: 'Dated: {filecontent.date}' - echo: 'Stem of filename: {filecontent.stem}' post_actions: &default_sorting - rename: '{python.timestamp}-{filecontent.stem}.{extension.lower}' - move: '{path.parent}/{python.quarter}/' rules: - folders: *downloads filters: - *default_filters - filecontent: 'Due Date' # regex to id as payable - filecontent: '(?P...)' # regex to extract supplier actions: - *default_actions - move: *payables_due - *default_sorting - folders: *downloads filters: - *default_filters - filecontent: 'Account: 000000000' # regex to id as receivables due - filecontent: '(?P...)' # regex to extract customer actions: - *default_actions - move: *receivables_due - *default_sorting - folders: *downloads filters: - *default_filters - filecontent: 'PAID' # regex to id as receivables paid - filecontent: '(?P...)' # regex to extract customer - filecontent: '(?P...)' # regex to extract date paid - filename: startswith: 2020 actions: - *default_actions - move: *receivables_paid - *default_sorting - rename: '{filecontent.paid}_{filecontent.stem}.{extension}' """ conf = Config.from_string(config) assert conf.rules == [ Rule( folders=["~/Downloads/"], filters=[ # default_filters Extension("pdf"), FileContent(expr="(?P...)"), # added filters FileContent(expr="Due Date"), FileContent(expr="(?P...)"), ], actions=[ # default_actions Echo(msg="Dated: {filecontent.date}"), Echo(msg="Stem of filename: {filecontent.stem}"), # added actions Move(dest="~/PayablesDue/", overwrite=False), # default_sorting Rename( name="{python.timestamp}-{filecontent.stem}.{extension.lower}", overwrite=False, ), Move(dest="{path.parent}/{python.quarter}/", overwrite=False), ], subfolders=False, system_files=False, ), Rule( folders=["~/Downloads/"], filters=[ # default_filters Extension("pdf"), FileContent(expr="(?P...)"), # added filters FileContent(expr="Account: 000000000"), FileContent(expr="(?P...)"), ], actions=[ # default_actions Echo(msg="Dated: {filecontent.date}"), Echo(msg="Stem of filename: {filecontent.stem}"), # added actions Move(dest="~/Receivables/", overwrite=False), # default_sorting Rename( name="{python.timestamp}-{filecontent.stem}.{extension.lower}", overwrite=False, ), Move(dest="{path.parent}/{python.quarter}/", overwrite=False), ], subfolders=False, system_files=False, ), Rule( folders=["~/Downloads/"], filters=[ # default_filters Extension("pdf"), FileContent(expr="(?P...)"), # added filters FileContent(expr="PAID"), FileContent(expr="(?P...)"), FileContent(expr="(?P...)"), Filename(startswith="2020"), ], actions=[ # default_actions Echo(msg="Dated: {filecontent.date}"), Echo(msg="Stem of filename: {filecontent.stem}"), # added actions Move(dest="~/Accounting/Income/", overwrite=False), # default_sorting Rename( name="{python.timestamp}-{filecontent.stem}.{extension.lower}", overwrite=False, ), Move(dest="{path.parent}/{python.quarter}/", overwrite=False), # added actions Rename( name="{filecontent.paid}_{filecontent.stem}.{extension}", overwrite=False, ), ], subfolders=False, system_files=False, ), ] organize-1.10.1/tests/core/test_utils.py000066400000000000000000000113701403777030400202620ustar00rootroot00000000000000from organize.utils import ( DotDict, Path, dict_merge, find_unused_filename, increment_filename_version, splitglob, ) def test_splitglob(): assert splitglob("~/Downloads") == (Path.home() / "Downloads", "") assert splitglob(r"/Test/\* tmp\*/*[!H]/**/*.*") == ( Path(r"/Test/\* tmp\*"), "*[!H]/**/*.*", ) assert splitglob("~/Downloads/Program 0.1*.exe") == ( Path.home() / "Downloads", "Program 0.1*.exe", ) assert splitglob("~/Downloads/Program[ms].exe") == ( Path.home() / "Downloads", "Program[ms].exe", ) assert splitglob("~/Downloads/Program.exe") == ( Path.home() / "Downloads" / "Program.exe", "", ) # https://github.com/tfeldmann/organize/issues/40 assert splitglob("~/Ältere/Erträgnisaufstellung_*.pdf") == ( Path.home() / "Ältere", "Erträgnisaufstellung_*.pdf", ) # https://github.com/tfeldmann/organize/issues/39 assert splitglob("~/Downloads/*.pdf") == (Path.home() / "Downloads", "*.pdf") def test_unused_filename_basic(mock_exists): mock_exists.return_value = False assert find_unused_filename(Path("somefile.jpg")) == Path("somefile 2.jpg") def test_unused_filename_separator(mock_exists): mock_exists.return_value = False assert find_unused_filename(Path("somefile.jpg"), separator="_") == Path( "somefile_2.jpg" ) def test_unused_filename_multiple(mock_exists): mock_exists.side_effect = [True, True, False] assert find_unused_filename(Path("somefile.jpg")) == Path("somefile 4.jpg") def test_unused_filename_increase(mock_exists): mock_exists.side_effect = [True, False] assert find_unused_filename(Path("somefile 7.jpg")) == Path("somefile 9.jpg") def test_unused_filename_increase_digit(mock_exists): mock_exists.side_effect = [True, False] assert find_unused_filename(Path("7.gif")) == Path("7 3.gif") def test_increment_filename_version(): assert ( increment_filename_version(Path.home() / "f3" / "test_123.7z") == Path.home() / "f3" / "test_123 2.7z" ) assert ( increment_filename_version(Path.home() / "f3" / "test_123_2 10.7z") == Path.home() / "f3" / "test_123_2 11.7z" ) def test_increment_filename_version_separator(): assert increment_filename_version(Path("test_123.7z"), separator="_") == Path( "test_124.7z" ) assert increment_filename_version(Path("test_123_2.7z"), separator="_") == Path( "test_123_3.7z" ) def test_increment_filename_version_no_separator(): assert increment_filename_version(Path("test.7z"), separator="") == Path("test2.7z") assert increment_filename_version(Path("test 10.7z"), separator="") == Path( "test 102.7z" ) def test_merges_dicts(): a = {"a": 1, "b": {"b1": 2, "b2": 3}} b = {"a": 1, "b": {"b1": 4}} assert dict_merge(a, b)["a"] == 1 assert dict_merge(a, b)["b"]["b2"] == 3 assert dict_merge(a, b)["b"]["b1"] == 4 def test_returns_copy(): a = {"regex": {"first": "A", "second": "B"}} b = {"regex": {"third": "C"}} x = dict_merge(a, b) a["regex"]["first"] = "X" assert x["regex"]["first"] == "A" assert x["regex"]["second"] == "B" assert x["regex"]["third"] == "C" def test_inserts_new_keys(): """Will it insert new keys by default?""" a = {"a": 1, "b": {"b1": 2, "b2": 3}} b = {"a": 1, "b": {"b1": 4, "b3": 5}, "c": 6} assert dict_merge(a, b)["a"] == 1 assert dict_merge(a, b)["b"]["b2"] == 3 assert dict_merge(a, b)["b"]["b1"] == 4 assert dict_merge(a, b)["b"]["b3"] == 5 assert dict_merge(a, b)["c"] == 6 def test_does_not_insert_new_keys(): """Will it avoid inserting new keys when required?""" a = {"a": 1, "b": {"b1": 2, "b2": 3}} b = {"a": 1, "b": {"b1": 4, "b3": 5}, "c": 6} assert dict_merge(a, b, add_keys=False)["a"] == 1 assert dict_merge(a, b, add_keys=False)["b"]["b2"] == 3 assert dict_merge(a, b, add_keys=False)["b"]["b1"] == 4 try: assert dict_merge(a, b, add_keys=False)["b"]["b3"] == 5 except KeyError: pass else: raise Exception("New keys added when they should not be") try: assert dict_merge(a, b, add_keys=False)["b"]["b3"] == 6 except KeyError: pass else: raise Exception("New keys added when they should not be") def test_dotdict_merge(): a = DotDict() b = {1: {2: 2, 3: 3, 4: {5: "fin."}}} a.update(b) assert a == b b[1][2] = 5 assert a != b a.update({1: {4: {5: "new.", 6: "fin."}, 2: "x"}}) assert a == {1: {2: "x", 3: 3, 4: {5: "new.", 6: "fin."}}} def test_dotdict_keeptype(): a = DotDict() a.update({"nr": {"upper": 1}}) assert a.nr.upper == 1 assert "{nr.upper}".format(**a) == "1" organize-1.10.1/tests/filters/000077500000000000000000000000001403777030400162275ustar00rootroot00000000000000organize-1.10.1/tests/filters/__init__.py000066400000000000000000000000001403777030400203260ustar00rootroot00000000000000organize-1.10.1/tests/filters/test_created.py000066400000000000000000000016041403777030400212500ustar00rootroot00000000000000from unittest.mock import patch import pendulum from pathlib import Path from organize.filters import Created def test_min(): now = pendulum.now() created = Created(days=10, hours=12, mode="older") with patch.object(created, "_created") as mock_cr: mock_cr.return_value = now - pendulum.duration(days=10, hours=0) assert created.run(path=Path("~")) is None mock_cr.return_value = now - pendulum.duration(days=10, hours=13) assert created.run(path=Path("~")) def test_max(): now = pendulum.now() created = Created(days=10, hours=12, mode="newer") with patch.object(created, "_created") as mock_cr: mock_cr.return_value = now - pendulum.duration(days=10, hours=0) assert created.run(path=Path("~")) mock_cr.return_value = now - pendulum.duration(days=10, hours=13) assert created.run(path=Path("~")) is None organize-1.10.1/tests/filters/test_extension.py000066400000000000000000000020721403777030400216550ustar00rootroot00000000000000from pathlib import Path from organize.filters import Extension def test_extension(): extension = Extension("JPG", ".gif", "pdf") testpathes = [ (Path("~/somefile.pdf"), True), (Path("/home/test/somefile.pdf.jpeg"), False), (Path("/home/test/gif.TXT"), False), (Path("/home/test/txt.GIF"), True), (Path("~/somefile.pdf"), True), ] for path, match in testpathes: assert bool(extension.matches(path)) == match def test_extension_empty(): extension = Extension() assert extension.matches(Path("~/test.txt")) def test_extension_result(): path = Path("~/somefile.TxT") extension = Extension("txt") assert extension.matches(path) result = extension.run(path=path)["extension"] assert str(result) == "TxT" assert result.lower == "txt" assert result.upper == "TXT" extension = Extension(".txt") assert extension.matches(path) result = extension.run(path=path)["extension"] assert str(result) == "TxT" assert result.lower == "txt" assert result.upper == "TXT" organize-1.10.1/tests/filters/test_filename.py000066400000000000000000000073501403777030400214250ustar00rootroot00000000000000from pathlib import Path from organize.filters import Filename def test_filename_startswith(): filename = Filename(startswith="begin") assert filename.matches(Path("~/here/beginhere.pdf")) assert not filename.matches(Path("~/here/.beginhere.pdf")) assert not filename.matches(Path("~/here/herebegin.begin")) def test_filename_contains(): filename = Filename(contains="begin") assert filename.matches(Path("~/here/beginhere.pdf")) assert filename.matches(Path("~/here/.beginhere.pdf")) assert filename.matches(Path("~/here/herebegin.begin")) assert not filename.matches(Path("~/here/other.begin")) def test_filename_endswith(): filename = Filename(endswith="end") assert filename.matches(Path("~/here/hereend.pdf")) assert not filename.matches(Path("~/here/end.tar.gz")) assert not filename.matches(Path("~/here/theendishere.txt")) def test_filename_multiple(): filename = Filename(startswith="begin", contains="con", endswith="end") assert filename.matches(Path("~/here/begin_somethgin_con_end.pdf")) assert not filename.matches(Path("~/here/beginend.pdf")) assert not filename.matches(Path("~/here/begincon.begin")) assert not filename.matches(Path("~/here/conend.begin")) assert filename.matches(Path("~/here/beginconend.begin")) def test_filename_case(): filename = Filename( startswith="star", contains="con", endswith="end", case_sensitive=False ) assert filename.matches(Path("~/STAR_conEnD.dpf")) assert not filename.matches(Path("~/here/STAREND.pdf")) assert not filename.matches(Path("~/here/STARCON.begin")) assert not filename.matches(Path("~/here/CONEND.begin")) assert filename.matches(Path("~/here/STARCONEND.begin")) def test_filename_list(): filename = Filename( startswith="_", contains=["1", "A", "3", "6"], endswith=["5", "6"], case_sensitive=False, ) assert filename.matches(Path("~/_15.dpf")) assert filename.matches(Path("~/_A5.dpf")) assert filename.matches(Path("~/_A6.dpf")) assert filename.matches(Path("~/_a6.dpf")) assert filename.matches(Path("~/_35.dpf")) assert filename.matches(Path("~/_36.dpf")) assert filename.matches(Path("~/_somethinga56")) assert filename.matches(Path("~/_6")) assert not filename.matches(Path("~/")) assert not filename.matches(Path("~/a_5")) def test_filename_list_case_sensitive(): filename = Filename( startswith="_", contains=["1", "A", "3", "7"], endswith=["5", "6"], case_sensitive=True, ) assert filename.matches(Path("~/_15.dpf")) assert filename.matches(Path("~/_A5.dpf")) assert filename.matches(Path("~/_A6.dpf")) assert not filename.matches(Path("~/_a6.dpf")) assert filename.matches(Path("~/_35.dpf")) assert filename.matches(Path("~/_36.dpf")) assert filename.matches(Path("~/_somethingA56")) assert not filename.matches(Path("~/_6")) assert not filename.matches(Path("~/_a5.dpf")) assert not filename.matches(Path("~/-A5.dpf")) assert not filename.matches(Path("~/")) assert not filename.matches(Path("~/_a5")) def test_filename_match(): fn = Filename("Invoice_*_{year:int}_{month}_{day}") p = "~/Documents/Invoice_RE1001_2021_01_31.pdf" assert fn.matches(Path(p)) assert fn.run(path=Path(p)) == { "filename": {"year": 2021, "month": "01", "day": "31"} } def test_filename_match_case_insensitive(): case = Filename("upper_{m1}_{m2}", case_sensitive=True) icase = Filename("upper_{m1}_{m2}", case_sensitive=False) p = "~/Documents/UPPER_MiXed_lower.pdf" assert icase.matches(Path(p)) assert icase.run(path=Path(p)) == {"filename": {"m1": "MiXed", "m2": "lower"}} assert not case.matches(Path(p)) organize-1.10.1/tests/filters/test_filesize.py000066400000000000000000000016641403777030400214610ustar00rootroot00000000000000from organize.filters import FileSize def test_constrains_mope1(): assert not FileSize("<1b,>2b").matches(1) assert FileSize(">=1b,<2b").matches(1) assert not FileSize(">1.000001b").matches(1) assert FileSize("<1.000001B").matches(1) assert FileSize("<1.000001").matches(1) assert FileSize("<=1,>=0.001kb").matches(1) assert FileSize("<1").matches(0) assert not FileSize(">1").matches(0) assert not FileSize("<1,>1b").matches(0) assert FileSize(">99.99999GB").matches(100000000000) assert FileSize("0").matches(0) def test_constrains_base(): assert FileSize(">1kb,<1kib").matches(1010) assert FileSize(">1k,<1ki").matches(1010) assert FileSize("1k").matches(1000) assert FileSize("1000").matches(1000) def test_other(): assert FileSize("<100 Mb").matches(20) assert FileSize("<100 Mb, <10 mb, <1 mb, > 0").matches(20) assert FileSize(["<100 Mb", ">= 0 Tb"]).matches(20) organize-1.10.1/tests/filters/test_last_modified.py000066400000000000000000000017071403777030400224500ustar00rootroot00000000000000from unittest.mock import patch import pendulum from pathlib import Path from organize.filters import LastModified def test_min(): now = pendulum.now() last_modified = LastModified(days=10, hours=12, mode="older") with patch.object(last_modified, "_last_modified") as mock_lm: mock_lm.return_value = now - pendulum.duration(days=10, hours=0) assert not last_modified.run(path=Path("~")) mock_lm.return_value = now - pendulum.duration(days=10, hours=13) assert last_modified.run(path=Path("~")) def test_max(): now = pendulum.now() last_modified = LastModified(days=10, hours=12, mode="newer") with patch.object(last_modified, "_last_modified") as mock_lm: mock_lm.return_value = now - pendulum.duration(days=10, hours=0) assert last_modified.run(path=Path("~")) mock_lm.return_value = now - pendulum.duration(days=10, hours=13) assert not last_modified.run(path=Path("~")) organize-1.10.1/tests/filters/test_python.py000066400000000000000000000003731403777030400211640ustar00rootroot00000000000000from organize.filters import Python from pathlib import Path def test_basic(): p = Python( """ print(path) return 1 """ ) assert p.run(path=Path.home()) assert p.run(path=Path.home()) == {"python": 1} organize-1.10.1/tests/filters/test_regex.py000066400000000000000000000022561403777030400207570ustar00rootroot00000000000000from pathlib import Path from organize.filters import Regex from organize.utils import DotDict TESTDATA = [ (Path("~/Invoices/RG123456123456-sig.pdf"), True, "123456123456"), (Path("~/Invoices/RG002312321542-sig.pdf"), True, "002312321542"), (Path("~/Invoices/RG002312321542.pdf"), False, None), ] def test_regex_backslash(): regex = Regex(r"^\.pdf$") assert regex.matches(Path(".pdf")) assert not regex.matches(Path("+pdf")) assert not regex.matches(Path("/pdf")) assert not regex.matches(Path("\\pdf")) def test_regex_basic(): regex = Regex(r"^RG(\d{12})-sig\.pdf$") for path, match, _ in TESTDATA: assert bool(regex.matches(path)) == match def test_regex_return(): regex = Regex(r"^RG(?P\d{12})-sig\.pdf$") for path, valid, result in TESTDATA: if valid: dct = regex.run(path=path) assert dct == {"regex": {"the_number": result}} def test_regex_umlaut(): regex = Regex(r"^Erträgnisaufstellung-(?P\d*)\.pdf") doc = Path("~/Documents/Erträgnisaufstellung-1998.pdf") assert regex.matches(doc) dct = regex.run(path=doc) assert dct == {"regex": {"year": "1998"}} organize-1.10.1/tests/integration/000077500000000000000000000000001403777030400171025ustar00rootroot00000000000000organize-1.10.1/tests/integration/__init__.py000066400000000000000000000000001403777030400212010ustar00rootroot00000000000000organize-1.10.1/tests/integration/test_codepost_usecase.py000066400000000000000000000023571403777030400240520ustar00rootroot00000000000000from conftest import assertdir, create_filesystem from organize.cli import main def test_codepost_usecase(tmp_path): create_filesystem( tmp_path, files=[ "Devonte-Betts.txt", "Alaina-Cornish.txt", "Dimitri-Bean.txt", "Lowri-Frey.txt", "Someunknown-User.txt", ], config=r""" rules: - folders: files filters: - extension: txt - regex: (?P\w+)-(?P\w+)\..* - python: | emails = { "Betts": "dbetts@mail.de", "Cornish": "acornish@google.com", "Bean": "dbean@aol.com", "Frey": "l-frey@frey.org", } if regex.lastname in emails: return {"mail": emails[regex.lastname]} actions: - rename: '{python.mail}.txt' """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir( tmp_path, "dbetts@mail.de.txt", "acornish@google.com.txt", "dbean@aol.com.txt", "l-frey@frey.org.txt", "Someunknown-User.txt", # no email found -> keep file ) organize-1.10.1/tests/integration/test_dict_merge.py000066400000000000000000000013751403777030400226230ustar00rootroot00000000000000from unittest.mock import call from conftest import create_filesystem from organize.cli import main def test_multiple_regex_placeholders(tmp_path, mock_echo): create_filesystem( tmp_path, files=["test-123.jpg", "other-456.pdf"], config=r""" rules: - folders: files filters: - regex: (?P\w+)-(?P\d+).* - regex: (?P.+?)\.\w{3} - extension actions: - echo: '{regex.word} {regex.number} {regex.all} {extension}' """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) mock_echo.assert_has_calls( (call("test 123 test-123 jpg"), call("other 456 other-456 pdf"),), any_order=True, ) organize-1.10.1/tests/integration/test_duplicate.py000066400000000000000000000032751403777030400224740ustar00rootroot00000000000000from conftest import create_filesystem, assertdir from organize.cli import main CONTENT_SMALL = "COPY CONTENT" CONTENT_LARGE = "XYZ" * 3000 def test_duplicate_smallfiles(tmp_path): create_filesystem( tmp_path, files=[ ("unique.txt", "I'm unique."), ("unique_too.txt", "I'm unique, too."), ("a.txt", CONTENT_SMALL), ("copy2.txt", CONTENT_SMALL), ("other/copy.txt", CONTENT_SMALL), ("other/copy.jpg", CONTENT_SMALL), ("large_unique.txt", CONTENT_LARGE), ("other/large.txt", CONTENT_LARGE), ], config=""" rules: - folders: files subfolders: true filters: - duplicate actions: - trash """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir( tmp_path, "unique.txt", "unique_too.txt", "a.txt", "large_unique.txt" ) def test_duplicate_largefiles(tmp_path): create_filesystem( tmp_path, files=[ ("unique.txt", CONTENT_LARGE + "1"), ("unique_too.txt", CONTENT_LARGE + "2"), ("a.txt", CONTENT_LARGE), ("copy2.txt", CONTENT_LARGE), ("other/copy.txt", CONTENT_LARGE), ("other/copy.jpg", CONTENT_LARGE), ("other/large.txt", CONTENT_LARGE), ], config=""" rules: - folders: files subfolders: true filters: - duplicate actions: - trash """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir(tmp_path, "unique.txt", "unique_too.txt", "a.txt") organize-1.10.1/tests/integration/test_exif.py000066400000000000000000000055721403777030400214570ustar00rootroot00000000000000import os import shutil from conftest import TESTS_FOLDER, create_filesystem, assertdir from organize.cli import main def copy_resources(tmp_path): src = os.path.join(TESTS_FOLDER, "resources") dst = os.path.join(str(tmp_path), "files") shutil.copytree(src=src, dst=dst) def test_exif(tmp_path): """ Sort photos by camera """ copy_resources(tmp_path) create_filesystem( tmp_path, files=["nothing.jpg"], config=""" rules: - folders: files filters: - extension: jpg - exif actions: - move: 'files/{exif.image.model}/' - echo: "{exif}" """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir( tmp_path, "nothing.jpg", "DMC-GX80/1.jpg", "NIKON D3200/2.jpg", "iPhone 6s/3.jpg", "iPhone 6s/4.jpg", "iPhone 5s/5.jpg", ) def test_exif_filter_single(tmp_path): """ Filter by camera """ copy_resources(tmp_path) create_filesystem( tmp_path, files=["nothing.jpg"], config=""" rules: - folders: files filters: - exif: image.model: Nikon D3200 actions: - move: 'files/{exif.image.model}/' """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir( tmp_path, "nothing.jpg", "1.jpg", "NIKON D3200/2.jpg", "3.jpg", "4.jpg", "5.jpg", ) def test_exif_filter_tag_exists(tmp_path): """ Filter by GPS """ copy_resources(tmp_path) create_filesystem( tmp_path, files=["nothing.jpg"], config=""" rules: - folders: files filters: - exif: gps.gpsdate actions: - echo: "{exif.gps.gpsdate}" - move: 'files/has_gps/' """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir( tmp_path, "nothing.jpg", "1.jpg", "2.jpg", "has_gps/3.jpg", "has_gps/4.jpg", "has_gps/5.jpg", ) def test_exif_filter_multiple(tmp_path): """ Filter by camera """ copy_resources(tmp_path) create_filesystem( tmp_path, files=["nothing.jpg"], config=""" rules: - folders: files filters: - exif: image.make: Apple exif.lensmodel: "iPhone 6s back camera 4.15mm f/2.2" actions: - echo: "{exif.image}" - move: 'files/chosen/' """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir( tmp_path, "nothing.jpg", "1.jpg", "2.jpg", "chosen/3.jpg", "chosen/4.jpg", "5.jpg", ) organize-1.10.1/tests/integration/test_extension.py000066400000000000000000000014171403777030400225320ustar00rootroot00000000000000from unittest.mock import call from conftest import create_filesystem from organize.cli import main def test_filename_move(tmp_path, mock_echo): create_filesystem( tmp_path, files=["test.jpg", "asd.JPG", "nomatch.jpg.zip", "camel.jPeG"], config=""" rules: - folders: files filters: - extension: - .jpg - jpeg actions: - echo: 'Found JPG file: {path.name}' """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) mock_echo.assert_has_calls( ( call("Found JPG file: test.jpg"), call("Found JPG file: asd.JPG"), call("Found JPG file: camel.jPeG"), ), any_order=True, ) organize-1.10.1/tests/integration/test_file_content.py000066400000000000000000000017371403777030400231740ustar00rootroot00000000000000import os from conftest import create_filesystem, assertdir from organize.cli import main def test_file_content(tmp_path): # inspired by https://github.com/tfeldmann/organize/issues/43 create_filesystem( tmp_path, files=[ ("Test1.txt", "Lorem MegaCorp Ltd. ipsum\nInvoice 12345\nMore text\nID: 98765"), ("Test2.txt", "Tests"), ("Test3.txt", "My Homework ...") ], config=r""" rules: - folders: files filters: - filecontent: 'MegaCorp Ltd.+^Invoice (?P\w+)$.+^ID: 98765$' actions: - rename: "MegaCorp_Invoice_{filecontent.number}.txt" - folders: files filters: - filecontent: '.*Homework.*' actions: - rename: "Homework.txt" """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir(tmp_path, "Homework.txt", "MegaCorp_Invoice_12345.txt", "Test2.txt") organize-1.10.1/tests/integration/test_filesize.py000066400000000000000000000040601403777030400223250ustar00rootroot00000000000000import pytest from unittest.mock import call from conftest import create_filesystem from organize.cli import main def test_size_zero(tmp_path, mock_echo): create_filesystem( tmp_path, files=["1", "2", "3"], config=""" rules: - folders: files filters: - filesize: 0 actions: - echo: '{path.name}' """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) mock_echo.assert_has_calls((call("1"), call("2"), call("3")), any_order=True) def test_basic(tmp_path, mock_echo): create_filesystem( tmp_path, files=[ "empty", ("full", "0" * 2000), ("halffull", "0" * 1010), ("two_thirds.txt", "0" * 666), ], config=""" rules: - folders: files filters: - filesize: '> 1kb, <= 1.0 KiB' actions: - echo: '{path.name} {filesize.bytes}' - folders: files filters: - filesize: - '> 0.5 kb' - '<1.0 KiB' actions: - echo: '2/3 {filesize.bytes}' """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) mock_echo.assert_has_calls( [call("halffull 1010"), call("2/3 666"),], any_order=True, ) @pytest.mark.skip(reason="TODO - template vars in filters not supported") def test_python_args(tmp_path, mock_echo): create_filesystem( tmp_path, files=[ "empty", ("full", "0" * 2000), ("halffull", "0" * 1010), ("two_thirds.txt", "0" * 666), ], config=""" rules: - folders: files filters: - python: | return 2000 - filesize: '= {python}b' actions: - echo: '{path.name} {filesize.bytes}' """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) mock_echo.assert_has_calls( [call("full 2000"),], any_order=True, ) organize-1.10.1/tests/integration/test_globstrings.py000066400000000000000000000072251403777030400230560ustar00rootroot00000000000000from conftest import create_filesystem, assertdir from organize.cli import main def test_globstr(tmp_path): # inspired by https://github.com/tfeldmann/organize/issues/39 create_filesystem( tmp_path, files=[ "Test.pdf", "Invoice.pdf", "Other.pdf", "Start.txt", "journal.md", "sub/test.pdf", "sub/other/marks.pdf", ], config=""" rules: - folders: files/*.pdf actions: - shell: "rm {path}" """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir( tmp_path, "Start.txt", "journal.md", "sub/test.pdf", "sub/other/marks.pdf" ) def test_globstr_subfolder(tmp_path): create_filesystem( tmp_path, files=[ "Test.pdf", "Invoice.pdf", "Other.pdf", "Start.txt", "sub/journal.md", "sub/test.pdf", "sub/other/marks.pdf", ], config=""" rules: - folders: files/**/*.pdf actions: - shell: "rm {path}" """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir(tmp_path, "Start.txt", "sub/journal.md") def test_globstr_subfolder_serious(tmp_path): create_filesystem( tmp_path, files=[ "Test.pdf", "Invoice.pdf", "Other.pdf", "Start.txt", "x/foo/test.pdf", "x/sub/journal.md", "x/sub/journal.pdf", "wub/best.pdf", "sub/other/marks.pdf", "x/sub/testjournal.pdf", "sub/test.pdf", "wub/test.pdf", "dub/test.pdf", ], config=""" rules: - folders: - files/**/*ub/**/test*.pdf - !files/dub/* actions: - shell: "rm {path}" """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir( tmp_path, "Test.pdf", "Invoice.pdf", "Other.pdf", "Start.txt", "x/foo/test.pdf", "x/sub/journal.md", "x/sub/journal.pdf", "wub/best.pdf", "sub/other/marks.pdf", "dub/test.pdf", ) def test_globstr_exclude(tmp_path): create_filesystem( tmp_path, files=[ "Test.pdf", "Invoice.pdf", "Start.txt", "other/a.txt", "other/next/b.txt", "exclude/test.pdf", "exclude/sub/journal.md", "exclude/sub/journal.pdf", ], config=""" rules: - folders: - files/**/* - !files/exclude/* - '! files/*' actions: - shell: "rm {path}" """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir( tmp_path, "Test.pdf", "Invoice.pdf", "Start.txt", "exclude/test.pdf", ) def test_globstr_subfolder_setting(tmp_path): create_filesystem( tmp_path, files=[ "Test.pdf", "Invoice.pdf", "Other.pdf", "Start.txt", "sub/journal.md", "sub/test.pdf", "sub/other/marks.pdf", ], config=""" rules: - folders: files subfolders: true filters: - extension: pdf actions: - shell: "rm {path}" """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir(tmp_path, "Start.txt", "sub/journal.md") organize-1.10.1/tests/integration/test_integration.py000066400000000000000000000042721403777030400230430ustar00rootroot00000000000000import pytest from conftest import assertdir, create_filesystem from organize.cli import main def test_filename_move(tmp_path): create_filesystem( tmp_path, files=["test.PY"], config=""" rules: - folders: files filters: - Extension actions: - rename: '{path.stem}{path.stem}.{extension.lower}' """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir(tmp_path, "testtest.py") def test_basic(tmp_path): create_filesystem( tmp_path, files=["asd.txt", "newname 2.pdf", "newname.pdf", "test.pdf"], config=""" rules: - folders: files filters: - filename: test actions: - copy: files/newname.pdf """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir( tmp_path, "newname.pdf", "newname 2.pdf", "newname 3.pdf", "test.pdf", "asd.txt" ) def test_globstr(tmp_path): create_filesystem( tmp_path, files=["asd.txt", "newname 2.pdf", "newname.pdf", "test.pdf"], config=""" rules: - folders: 'file[s]/*.pdf' actions: - delete """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir(tmp_path, "asd.txt") @pytest.mark.skip(reason="Todo") def test_dependent_rules(tmp_path): create_filesystem( tmp_path, files=["asd.txt", "newname 2.pdf", "newname.pdf", "test.pdf"], config=""" rules: - folders: files filters: - filename: test actions: - copy: files/newfolder/test.pdf - folders: files/newfolder/ filters: - filename: test actions: - rename: test-found.pdf """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir( tmp_path, "newname.pdf", "newname 2.pdf", "test.pdf", "asd.txt", "newfolder/test-found.pdf", ) organize-1.10.1/tests/integration/test_python_filter.py000066400000000000000000000132551403777030400234070ustar00rootroot00000000000000from unittest.mock import call from conftest import assertdir, create_filesystem from organize.cli import main def test_python(tmp_path, mock_echo): create_filesystem( tmp_path, files=["student-01.jpg", "student-01.txt", "student-02.txt", "student-03.txt"], config=""" rules: - folders: files filters: - extension: txt - python: | return int(path.name.split('.')[0][-2:]) * 100 actions: - echo: '{python}' """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) mock_echo.assert_has_calls( (call("100"), call("200"), call("300"),), any_order=True, ) def test_odd_detector(tmp_path, mock_echo): create_filesystem( tmp_path, files=["student-01.txt", "student-02.txt", "student-03.txt", "student-04.txt"], config=""" rules: - folders: files filters: - python: | return int(path.stem.split('-')[1]) % 2 == 1 actions: - echo: 'Odd student numbers: {path.name}' """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) mock_echo.assert_has_calls( ( call("Odd student numbers: student-01.txt"), call("Odd student numbers: student-03.txt"), ), any_order=True, ) def test_python_dict(tmp_path, mock_echo): create_filesystem( tmp_path, files=["foo-01.jpg", "foo-01.txt", "bar-02.txt", "baz-03.txt"], config=""" rules: - folders: files filters: - extension: txt - python: | return { "name": path.name[:3], "code": int(path.name.split('.')[0][-2:]) * 100, } actions: - echo: '{python.code} {python.name}' """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) mock_echo.assert_has_calls( (call("100 foo"), call("200 bar"), call("300 baz"),), any_order=True, ) def test_name_reverser(tmp_path): create_filesystem( tmp_path, files=["desrever.jpg", "emanelif.txt"], config=""" rules: - folders: files filters: - extension - python: | return { "reversed_name": path.stem[::-1], } actions: - rename: '{python.reversed_name}.{extension}' """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir(tmp_path, "reversed.jpg", "filename.txt") def test_folder_instructions(tmp_path): """ I would like to include path/folder-instructions into the filename because I have a lot of different files (and there are always new categories added) I don't want create rules for. For example my filename is '2019_Jobs_CategoryA_TagB_A-Media_content-name_V01_draft_eng.docx' which means: Move the file to the folder '2019/Jobs/CategoryA/TagB/Media/drafts/eng' whereby 'A-' is an additional instruction and should be removed from the filename afterwards ('2019_Jobs_CategoryA_TagB_content-name_V01_draft_eng.docx'). I have a rough idea to figure it out with python but I'm new to it (see below a sketch). Is there a possibility to use such variables, conditions etc. with organizer natively? If no, is it possible to do it with Python in Organizer at all? - Transform file-string into array - Search for 'A-...', 'V...' and 'content-name' and get index of values - remove value 'A-... and 'content-name' of array - build new filename string - remove value 'V...' and 'A-' of array - build folder-path string (convert _ to /) etc. """ # inspired by: https://github.com/tfeldmann/organize/issues/52 create_filesystem( tmp_path, files=[ "2019_Jobs_CategoryA_TagB_A-Media_content-name_V01_draft_eng.docx", "2019_Work_CategoryC_V-Test_A-Audio_V14_final.pdf", "other.pdf", ], config=r""" rules: - folders: files filters: - extension: - pdf - docx - filename: contains: "_" - python: | import os parts = [] instructions = dict() for part in path.stem.split("_"): if part.startswith("A-"): instructions["A"] = part[2:] elif part.startswith("V-"): instructions["V"] = part[2:] elif part.startswith("content-name"): instructions["content"] = part[12:] else: parts.append(part) return { "new_path": os.path.join(*parts), "instructions": instructions, } actions: - echo: "New path: {python.new_path}" - echo: "Instructions: {python.instructions}" - echo: "Value of A: {python.instructions.A}" - move: "files/{python.new_path}/{path.name}" """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir( tmp_path, "other.pdf", "2019/Jobs/CategoryA/TagB/V01/draft/eng/2019_Jobs_CategoryA_TagB_A-Media_content-name_V01_draft_eng.docx", "2019/Work/CategoryC/V14/final/2019_Work_CategoryC_V-Test_A-Audio_V14_final.pdf", "other.pdf", ) organize-1.10.1/tests/integration/test_regex.py000066400000000000000000000014421403777030400216260ustar00rootroot00000000000000from conftest import create_filesystem, assertdir from organize.cli import main def test_rename_files_date(tmp_path): # inspired by https://github.com/tfeldmann/organize/issues/43 create_filesystem( tmp_path, files=[ "File_abc_dat20190812_xyz.pdf", "File_xyz_bar19990101_a.pdf", "File_123456_foo20000101_xyz20190101.pdf", ], config=r""" rules: - folders: files filters: - regex: 'File_.*?(?P\d{4})(?P\d{2})(?P\d{2}).*?.pdf' actions: - rename: "File_{regex.d}{regex.m}{regex.y}.pdf" """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir(tmp_path, "File_12082019.pdf", "File_01011999.pdf", "File_01012000.pdf") organize-1.10.1/tests/integration/test_rename.py000066400000000000000000000017461403777030400217720ustar00rootroot00000000000000from conftest import create_filesystem, assertdir from organize.cli import main def test_rename_issue51(tmp_path): # test for issue https://github.com/tfeldmann/organize/issues/51 create_filesystem( tmp_path, files=["19asd_WF_test2.pdf", "other.pdf", "18asd_WFX_test2.pdf",], config=r""" rules: - folders: files filters: - filename: startswith: "19" contains: - "_WF_" actions: - rename: "{path.stem}_unread{path.suffix}" - copy: dest: "files/copy/" overwrite: false counter_separator: "_" """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir( tmp_path, "19asd_WF_test2_unread.pdf", "other.pdf", "copy/19asd_WF_test2_unread.pdf", "18asd_WFX_test2.pdf", ) organize-1.10.1/tests/integration/test_startswith.py000066400000000000000000000015761403777030400227400ustar00rootroot00000000000000from conftest import create_filesystem, assertdir from organize.cli import main def test_startswith_issue74(tmp_path): # test for issue https://github.com/tfeldmann/organize/issues/74 create_filesystem( tmp_path, files=["Cálculo_1.pdf", "Cálculo_2.pdf", "Calculo.pdf",], config=r""" # Cálculo PDF rules: - folders: files filters: - extension: - pdf - filename: startswith: Cálculo actions: - move: "files/Cálculo Integral/Periodo #6/PDF's/" """, ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir( tmp_path, "Cálculo Integral/Periodo #6/PDF's/Cálculo_1.pdf", "Cálculo Integral/Periodo #6/PDF's/Cálculo_2.pdf", "Calculo.pdf", ) organize-1.10.1/tests/integration/test_unicode.py000066400000000000000000000035161403777030400221460ustar00rootroot00000000000000import pytest from conftest import assertdir, create_filesystem from organize.cli import main @pytest.mark.skip(reason="Todo") def test_normalization_regex(tmp_path): create_filesystem( tmp_path, files=[b"Ertra\xcc\x88gnisaufstellung.txt".decode("utf-8")], config=""" rules: - folders: files filters: - regex: '^{}$' actions: - rename: "found-regex.txt" """.format( b"Ertr\xc3\xa4gnisaufstellung\\.txt".decode("utf-8") ), ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir(tmp_path, "found-regex.txt") @pytest.mark.skip(reason="Todo") def test_normalization_glob(tmp_path): create_filesystem( tmp_path, files=[b"Ertra\xcc\x88gnisaufstellung.txt".decode("utf-8")], config=""" rules: - folders: ./**/{}.* actions: - rename: "found-glob.txt" """.format( b"Ertr\xc3\xa4gnisaufstellung".decode("utf-8") ), ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir(tmp_path, "found-glob.txt") @pytest.mark.skip(reason="Todo") def test_normalization_filename(tmp_path): create_filesystem( tmp_path, files=[b"Ertra\xcc\x88gnisaufstellung.txt".decode("utf-8")], config=""" rules: - folders: files filters: - filename: contains: {} actions: - rename: "found-filename.txt" """.format( b"Ertr\xc3\xa4gnisaufstellung".decode("utf-8") ), ) main(["run", "--config-file=%s" % (tmp_path / "config.yaml")]) assertdir(tmp_path, "found-filename.txt") organize-1.10.1/tests/resources/000077500000000000000000000000001403777030400165715ustar00rootroot00000000000000organize-1.10.1/tests/resources/1.jpg000066400000000000000000000113111403777030400174300ustar00rootroot00000000000000JFIFExifMM*  z (1 2iPanasonicDMC-GX80Ver.1.2 2018:09:29 18:52:46$rz"'00230   ’0520520520100ʤ2  P 2018:09:29 18:52:462018:09:29 18:52:461   http://ns.adobe.com/xap/1.0/ xPhotoshop 3.08BIM?Z%G?185246>20180929720180929<1852468BIM%F0e^֔:0u0@ICC_PROFILE0ADBEmntrRGB XYZ  3;acspAPPLnone-ADBE cprt2desc0kwtptbkptrTRCgTRCbTRCrXYZgXYZbXYZtextCopyright 2000 Adobe Systems IncorporateddescAdobe RGB (1998)XYZ QXYZ curv3curv3curv3XYZ OXYZ 4,XYZ &1/! }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzCC ?(organize-1.10.1/tests/resources/2.jpg000077500000000000000000000104361403777030400174430ustar00rootroot00000000000000JFIFHH(ExifMM* z (1 2iNIKON CORPORATIONNIKON D3200HHVer.1.00 2018:04:29 16:24:21&"'d00230̒ Ԓܒ  䒆,쒐2020200100K    2018:04:29 16:24:212018:04:29 16:24:212ASCII  http://ns.adobe.com/xap/1.0/ xPhotoshop 3.08BIM?Z%G?162421>20180429720180429<1624218BIM%c60p9-nǬ5! }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzCC ?(organize-1.10.1/tests/resources/3.jpg000066400000000000000000000122051403777030400174350ustar00rootroot00000000000000JFIFHHrExifMM*  (12iˆ%4AppleiPhone 6sHH10.3.32017:08:12 12:23:36 HP"'0221Xl     |:6566560100  23 4# 2017:08:12 12:23:362017:08:12 12:23:36By e 0IS2Apple iOSMM  .h     "  bplist00Ok)E;V*}Yz&=>I{iD-^O,I]Luyr:JA{}~p=BQuQyzz|~{JG{9{pzz{|eER@~|{{}~T@L~}}~SPUlMgYXLtV[rF1 $f=,]O*+B0+qlWt  + C#-  -+ !D./  #3  3 bplist00UflagsUvalueUepochYtimescale4]pz;#-/8: ?Z?Xd}!2!2  AppleiPhone 6s back camera 4.15mm f/2.2NE& K >TFTN Vb-4d 5d_ $D9D92017:08:12 http://ns.adobe.com/xap/1.0/ xPhotoshop 3.08BIM?Z%G?122336>20170812720170812<1223368BIM%/ZVsD " }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzC C   ? (D>|organize-1.10.1/tests/resources/4.jpg000066400000000000000000000123451403777030400174430ustar00rootroot00000000000000JFIFHHExifMM*  (12iˆ%dAppleiPhone 6sHH11.2.62018:02:22 09:34:41 HP"' 0221Xl     |j843843010023:4#@! 2018:02:22 09:34:412018:02:22 09:34:41/ LcS2Apple iOSMM  .h     R      bplist00O      +!  [O>1! rm^QEPNBA4 &, 3:>)LRKOG3kXy||MQ[`?jN7Pahkpt bplist00UflagsUvalueYtimescaleUepoch$ج;'-/8= ?`25(=!2!2  AppleiPhone 6s back camera 4.15mm f/2.2NE6NV K nTvT~ 30d!Sd"(w2fUfU2018:02:22  http://ns.adobe.com/xap/1.0/ xPhotoshop 3.08BIM?Z%G?093441>20180222720180222<0934418BIM%R*M ]M Z" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzC C   ?IҬvw{xJI>>y=[ c^̻= #organize-1.10.1/tests/resources/5.jpg000066400000000000000000000137361403777030400174510ustar00rootroot00000000000000JFIFHHbExifMM*  (18.42i%8AppleiPhone 5sHH2015:07:08 14:43:52!LT"' 0221\p     |:1171170100234#x 2015:07:08 14:43:522015:07:08 14:43:52%]/ AS7:Apple iOSMM  .h     "  bplist00OP _GE ~+Z+Fl#$QG<sF8P0mA-JwhiK-$x`OB2%9vHE8Y}'"(p@<=PeEdQh$!$gH?m6-j|6JV5Uc"G pG!?l>%! 0vYi5&('. ! \!P0%A!!$mf6}*2/$\$!!. nmU&--(@K2"hjUV*",'-~V6-)<-( bplist00UflagsUvalueUepochYtimescaleb;#-/8: ?_,wi!2!2  AppleiPhone 5s back camera 4.15mm f/2.2NE K 6T>TF N&(od5mde +4+?;%j2015:07:08 9http://ns.adobe.com/xap/1.0/ xPhotoshop 3.08BIM?Z%G?144352>20150708720150708<1443528BIM%z%9?-\.m" }!1AQa"q2#BR$3br %&'()*456789:CDEFGHIJSTUVWXYZcdefghijstuvwxyz w!1AQaq"2B #3Rbr $4%&'()*56789:CDEFGHIJSTUVWXYZcdefghijstuvwxyzC C   ?kHoO iVRO-KˠD_U KJukk}MG_*?Ⱦ}3